REDROOM
PHP 8.2.30
Path:
Logout
Edit File
Size: 5.81 MB
Close
//usr/share/imunify360/wp-plugins/wp-cli
Text
Base64
IyEvdXNyL2Jpbi9lbnYgcGhwCjw/cGhwClBoYXI6Om1hcFBoYXIoKTsKaW5jbHVkZSAncGhhcjovL3dwLWNsaS5waGFyL3BocC9ib290LXBoYXIucGhwJzsKX19IQUxUX0NPTVBJTEVSKCk7ID8+DQrabQEARAQAABEAAAABAAsAAAB3cC1jbGkucGhhcgAAAAAjAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbXBhdC5waHBuEAAAkqKeYG4QAAAdunplpAEAAAAAAAAoAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbmZpZy1zcGVjLnBocF8NAACSop5gXw0AAN89jVekAQAAAAAAACYAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvYm9vdHN0cmFwLnBocHwIAACSop5gfAgAABNgrEakAQAAAAAAACoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY29tbWFuZHMvaGVscC5waHCUAAAAkqKeYJQAAABsRLMFpAEAAAAAAAApAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbW1hbmRzL2NsaS5waHDUAQAAkqKeYNQBAABqbpL8pAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbW1hbmRzL3NyYy9DTElfQ29tbWFuZC5waHD9TgAAkqKeYP1OAAC7CGdhpAEAAAAAAAA7AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbW1hbmRzL3NyYy9DTElfQ2FjaGVfQ29tbWFuZC5waHC3BAAAkqKeYLcEAAD9bj/tpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL2NvbW1hbmRzL3NyYy9IZWxwX0NvbW1hbmQucGhwVxwAAJKinmBXHAAAAe+8caQBAAAAAAAAOwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9jb21tYW5kcy9zcmMvQ0xJX0FsaWFzX0NvbW1hbmQucGhweTMAAJKinmB5MwAAvD7ZaaQBAAAAAAAAJAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9ib290LWZzLnBocJIBAACSop5gkgEAADz517KkAQAAAAAAACwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvd3Atc2V0dGluZ3MtY2xpLnBocG9DAACSop5gb0MAALURgmekAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvY2xhc3Mtd3AtY2xpLWNvbW1hbmQucGhwjQAAAJKinmCNAAAAySrD+qQBAAAAAAAAKQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9jbGFzcy13cC1jbGkucGhwS6IAAJKinmBLogAAEHpaTqQBAAAAAAAAJwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9kaXNwYXRjaGVyLnBocE0BAACSop5gTQEAAOHXOkqkAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1Byb2Nlc3MucGhwVAsAAJKinmBUCwAA6URrHqQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSW5mbGVjdG9yLnBocOY/AACSop5g5j8AAGLK5eikAQAAAAAAAD8AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvQ29tbWFuZE5hbWVzcGFjZS5waHCrBAAAkqKeYKsEAAByRnwRpAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9EaXNwYXRjaGVyL0NvbW1hbmRGYWN0b3J5LnBocAoiAACSop5gCiIAAMHebjakAQAAAAAAAD4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvQ29tbWFuZEFkZGl0aW9uLnBocCMEAACSop5gIwQAAM/oupukAQAAAAAAAD8AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvQ29tcG9zaXRlQ29tbWFuZC5waHBhGgAAkqKeYGEaAABtfDL/pAEAAAAAAAA6AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9EaXNwYXRjaGVyL1Jvb3RDb21tYW5kLnBocEsDAACSop5gSwMAAJ95FtWkAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Rpc3BhdGNoZXIvU3ViY29tbWFuZC5waHCKNQAAkqKeYIo1AABwcxfdpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Gb3JtYXR0ZXIucGhwFSUAAJKinmAVJQAAy1enq6QBAAAAAAAALAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvV3BPcmdBcGkucGhwrR8AAJKinmCtHwAA1DkP3KQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRG9jUGFyc2VyLnBocBAQAACSop5gEBAAAAoLeFCkAQAAAAAAADIAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1N5bm9wc2lzUGFyc2VyLnBocHASAACSop5gcBIAAJxXh12kAQAAAAAAACgAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL05vT3AucGhw3QAAAJKinmDdAAAARMoxBKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRmV0Y2hlcnMvQmFzZS5waHCVBAAAkqKeYJUEAACYisJVpAEAAAAAAAA0AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9GZXRjaGVycy9Db21tZW50LnBocH0CAACSop5gfQIAAOjh2gGkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0ZldGNoZXJzL1NpdGUucGhwmAMAAJKinmCYAwAAeBZrWKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRmV0Y2hlcnMvUG9zdC5waHA5AgAAkqKeYDkCAADI0fLrpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9GZXRjaGVycy9Vc2VyLnBocDADAACSop5gMAMAAP7mBvakAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0F1dG9sb2FkZXIucGhwLRIAAJKinmAtEgAACWzx0aQBAAAAAAAALgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQ29tcG9zZXJJTy5waHCCAwAAkqKeYIIDAACRyStRpAEAAAAAAAAwAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db25maWd1cmF0b3IucGhwliUAAJKinmCWJQAAkPEW4aQBAAAAAAAARgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0RlY2xhcmVGYWxsYmFja0Z1bmN0aW9ucy5waHBDAgAAkqKeYEMCAABAKkJnpAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5pdGlhbGl6ZUNvbG9yaXphdGlvbi5waHBMAgAAkqKeYEwCAACk2Cc9pAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvRGVjbGFyZU1haW5DbGFzcy5waHAUAgAAkqKeYBQCAAC3BVRqpAEAAAAAAABHAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5jbHVkZUZhbGxiYWNrQXV0b2xvYWRlci5waHC1AwAAkqKeYLUDAACw+M5TpAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5pdGlhbGl6ZUxvZ2dlci5waHAqBAAAkqKeYCoEAABcqbAzpAEAAAAAAAA9AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvQ29uZmlndXJlUnVubmVyLnBocDUCAACSop5gNQIAAInfti2kAQAAAAAAAEcAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9SZWdpc3RlckZyYW1ld29ya0NvbW1hbmRzLnBocGcEAACSop5gZwQAANY+61akAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Cb290c3RyYXBTdGF0ZS5waHCkBQAAkqKeYKQFAACiwILXpAEAAAAAAABGAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvUmVnaXN0ZXJEZWZlcnJlZENvbW1hbmRzLnBocJUHAACSop5glQcAAPgUawmkAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9SdW5uZXJJbnN0YW5jZS5waHCjAgAAkqKeYKMCAACyaxKPpAEAAAAAAABGAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvSW5jbHVkZVBhY2thZ2VBdXRvbG9hZGVyLnBocAEFAACSop5gAQUAAPDvH0akAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9BdXRvbG9hZGVyU3RlcC5waHApCQAAkqKeYCkJAACD68KspAEAAAAAAAA7AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvQm9vdHN0cmFwU3RlcC5waHDHAQAAkqKeYMcBAABBNy8MpAEAAAAAAABIAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Cb290c3RyYXAvRGVjbGFyZUFic3RyYWN0QmFzZUNvbW1hbmQucGhwQQIAAJKinmBBAgAAr0A8QKQBAAAAAAAASAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0luY2x1ZGVGcmFtZXdvcmtBdXRvbG9hZGVyLnBocMoFAACSop5gygUAAId0P9+kAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9MYXVuY2hSdW5uZXIucGhwKAIAAJKinmAoAgAAsHrcXKQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0xvYWRVdGlsaXR5RnVuY3Rpb25zLnBocCkCAACSop5gKQIAAFRZTd2kAQAAAAAAAEEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Mb2FkUmVxdWlyZWRDb21tYW5kLnBocKIGAACSop5gogYAAP7Y7tOkAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9Mb2FkRXhlY0NvbW1hbmQucGhwVwMAAJKinmBXAwAABXl+paQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvQm9vdHN0cmFwL0xvYWREaXNwYXRjaGVyLnBocDUCAACSop5gNQIAAFWg2zSkAQAAAAAAAEUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0Jvb3RzdHJhcC9EZWZpbmVQcm90ZWN0ZWRDb21tYW5kcy5waHDnBAAAkqKeYOcEAAA4xT4ypAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9QYWNrYWdlTWFuYWdlckV2ZW50U3Vic2NyaWJlci5waHB+BQAAkqKeYH4FAABuc1wUpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9FeGl0RXhjZXB0aW9uLnBocFMAAACSop5gUwAAAHt114SkAQAAAAAAACoAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL1J1bm5lci5waHCZ1gAAkqKeYJnWAAAgHTJKpAEAAAAAAAAwAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9VcGdyYWRlclNraW4ucGhwKwYAAJKinmArBgAA7jaKf6QBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvU3lub3BzaXNWYWxpZGF0b3IucGhw2Q4AAJKinmDZDgAAa+qVJaQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvRmlsZUNhY2hlLnBocLIhAACSop5gsiEAAGsgytOkAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0V4dHJhY3Rvci5waHBCJwAAkqKeYEInAAA801rPpAEAAAAAAABKAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db21wYXQvTWluX1BIUF81XzYvRmVlZGJhY2tNZXRob2RUcmFpdC5waHCzAQAAkqKeYLMBAAA8qk7TpAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db21wYXQvRmVlZGJhY2tNZXRob2RUcmFpdC5waHDOAQAAkqKeYM4BAADI+OmWpAEAAAAAAABKAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db21wYXQvTWluX1BIUF81XzQvRmVlZGJhY2tNZXRob2RUcmFpdC5waHAHAQAAkqKeYAcBAADcoJrTpAEAAAAAAAAuAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Qcm9jZXNzUnVuLnBocCgFAACSop5gKAUAAGPM7ZmkAQAAAAAAADAAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0xvZ2dlcnMvQmFzZS5waHDXCAAAkqKeYNcIAACrn0VlpAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Mb2dnZXJzL0V4ZWN1dGlvbi5waHBhBwAAkqKeYGEHAAB0hhRXpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Mb2dnZXJzL1F1aWV0LnBocKUEAACSop5gpQQAADU5XKKkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0xvZ2dlcnMvUmVndWxhci5waHAbCAAAkqKeYBsIAAA1msEhpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9Db21wbGV0aW9ucy5waHDHDgAAkqKeYMcOAACH48mqpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9XcEh0dHBDYWNoZU1hbmFnZXIucGhwawwAAJKinmBrDAAAFWqhGaQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSXRlcmF0b3JzL1RhYmxlLnBocGUKAACSop5gZQoAABFAFSukAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0l0ZXJhdG9ycy9RdWVyeS5waHAaDAAAkqKeYBoMAADp7da9pAEAAAAAAAA3AAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL1dQX0NMSS9JdGVyYXRvcnMvVHJhbnNmb3JtLnBocMcBAACSop5gxwEAANOAdFmkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvV1BfQ0xJL0l0ZXJhdG9ycy9DU1YucGhwoQYAAJKinmChBgAA+I9iT6QBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvd3AtY2xpL3BocC9XUF9DTEkvSXRlcmF0b3JzL0V4Y2VwdGlvbi5waHBoAAAAkqKeYGgAAAAwTDbSpAEAAAAAAAAjAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3dwLWNsaS5waHAfBAAAkqKeYB8EAADmrOHxpAEAAAAAAAAiAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvcGhwL3V0aWxzLnBocKnEAACSop5gqcQAAK6KRNGkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvZmFsbGJhY2stZnVuY3Rpb25zLnBocPQAAACSop5g9AAAAIZbBEakAQAAAAAAACUAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvdXRpbHMtd3AucGhwrTgAAJKinmCtOAAAzT93I6QBAAAAAAAAEQAAAHBocC9ib290LXBoYXIucGhwOQIAAJKinmA5AgAAWZC9c6QBAAAAAAAAMAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9iaW4vYnVpbGRfYm9vdHN0cmFwLnBocDsVAACSop5gOxUAAK3Az/qkAQAAAAAAAEEAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL1NvdXJjZS9GaWxlc3lzdGVtU291cmNlLnBocGoHAACSop5gagcAAMCF/UCkAQAAAAAAADAAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci5waHBCAgAAkqKeYEICAABRgMd5pAEAAAAAAAA5AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9DYWNoZS9Ob29wQ2FjaGUucGhwQQQAAJKinmBBBAAAlIiO2aQBAAAAAAAAPwAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQ2FjaGUvRmlsZXN5c3RlbUNhY2hlLnBocGgRAACSop5gaBEAACh9NBmkAQAAAAAAAD0AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0NhY2hlL0Fic3RyYWN0Q2FjaGUucGhw4QUAAJKinmDhBQAAVt+A26QBAAAAAAAAPwAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9nZ2VyL0Fic3RyYWN0TG9nZ2VyLnBocHYMAACSop5gdgwAAG7lWTakAQAAAAAAAD0AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvZ2dlci9TdHJlYW1Mb2dnZXIucGhwuRUAAJKinmC5FQAAtov9SqQBAAAAAAAAMgAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvVGVtcGxhdGUucGhwixMAAJKinmCLEwAAOAgEqaQBAAAAAAAAMAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9nZ2VyLnBocCQNAACSop5gJA0AAPdAWTmkAQAAAAAAADYAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xhbWJkYUhlbHBlci5waHDcBwAAkqKeYNwHAAAIinDVpAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Tb3VyY2UucGhwGgQAAJKinmAaBAAAYte2baQBAAAAAAAAMAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvRW5naW5lLnBocPhjAACSop5g+GMAAP9D1BKkAQAAAAAAADoAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0hlbHBlckNvbGxlY3Rpb24ucGhwnw4AAJKinmCfDgAAHYeO06QBAAAAAAAANAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvQXV0b2xvYWRlci5waHAZCAAAkqKeYBkIAAA9Y6vWpAEAAAAAAAAyAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Db21waWxlci5waHB8WAAAkqKeYHxYAABWc/6JpAEAAAAAAAAxAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Db250ZXh0LnBocPEaAACSop5g8RoAAI3+HESkAQAAAAAAADMAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi5waHBSAQAAkqKeYFIBAAAEXXW3pAEAAAAAAAAwAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9QYXJzZXIucGhwnCoAAJKinmCcKgAA21bKhKQBAAAAAAAASgAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvRXhjZXB0aW9uL1Vua25vd25GaWx0ZXJFeGNlcHRpb24ucGhwxQMAAJKinmDFAwAA6Wb93qQBAAAAAAAATAAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHCiAQAAkqKeYKIBAACsHthRpAEAAAAAAABDAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FeGNlcHRpb24vU3ludGF4RXhjZXB0aW9uLnBocJkDAACSop5gmQMAAP9Og5qkAQAAAAAAAEIAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9Mb2dpY0V4Y2VwdGlvbi5waHCDAQAAkqKeYIMBAADCfUGvpAEAAAAAAABMAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9FeGNlcHRpb24vVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uLnBocNsDAACSop5g2wMAAC24WwCkAQAAAAAAAEQAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9SdW50aW1lRXhjZXB0aW9uLnBocIkBAACSop5giQEAADFd0NOkAQAAAAAAAEoAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0V4Y2VwdGlvbi9Vbmtub3duSGVscGVyRXhjZXB0aW9uLnBocMUDAACSop5gxQMAAOtI3mqkAQAAAAAAADMAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL1Rva2VuaXplci5waHBfLAAAkqKeYF8sAABzhl5QpAEAAAAAAABBAAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2FkZXIvRmlsZXN5c3RlbUxvYWRlci5waHDTEAAAkqKeYNMQAABMJHmfpAEAAAAAAAA8AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2FkZXIvQXJyYXlMb2FkZXIucGhw4wcAAJKinmDjBwAA2yGTD6QBAAAAAAAAPQAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9hZGVyL0lubGluZUxvYWRlci5waHDuDgAAkqKeYO4OAABciQnhpAEAAAAAAAA9AAAAdmVuZG9yL211c3RhY2hlL211c3RhY2hlL3NyYy9NdXN0YWNoZS9Mb2FkZXIvU3RyaW5nTG9hZGVyLnBocNADAACSop5g0AMAADwloRGkAQAAAAAAAEAAAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci9DYXNjYWRpbmdMb2FkZXIucGhw+gYAAJKinmD6BgAAFeUcqaQBAAAAAAAASwAAAHZlbmRvci9tdXN0YWNoZS9tdXN0YWNoZS9zcmMvTXVzdGFjaGUvTG9hZGVyL1Byb2R1Y3Rpb25GaWxlc3lzdGVtTG9hZGVyLnBocGYLAACSop5gZgsAABSLsY+kAQAAAAAAAD4AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0xvYWRlci9NdXRhYmxlTG9hZGVyLnBocLACAACSop5gsAIAAOG4z2ekAQAAAAAAAC8AAAB2ZW5kb3IvbXVzdGFjaGUvbXVzdGFjaGUvc3JjL011c3RhY2hlL0NhY2hlLnBocP8CAACSop5g/wIAACUJSAqkAQAAAAAAACsAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMucGhw3XYAAJKinmDddgAA6nhSw6QBAAAAAAAAMgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9Ib29rZXIucGhwxQIAAJKinmDFAgAAPYJ1iaQBAAAAAAAAMwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9TZXNzaW9uLnBocAAcAACSop5gABwAALHzcBqkAQAAAAAAADcAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSUROQUVuY29kZXIucGhwGy0AAJKinmAbLQAA68yT8KQBAAAAAAAANgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9BdXRoL0Jhc2ljLnBocJMHAACSop5gkwcAAOdK1EGkAQAAAAAAADEAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvUHJveHkucGhwLQMAAJKinmAtAwAAy9/Jp6QBAAAAAAAAMAAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9JUHY2LnBocJITAACSop5gkhMAAPNqe22kAQAAAAAAADYAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvQ29va2llL0phci5waHAZDwAAkqKeYBkPAACpgfHxpAEAAAAAAAAyAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0Nvb2tpZS5waHDpMgAAkqKeYOkyAACfmoXhpAEAAAAAAABEAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1V0aWxpdHkvRmlsdGVyZWRJdGVyYXRvci5waHCcBAAAkqKeYJwEAAAJmfJepAEAAAAAAABNAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1V0aWxpdHkvQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeS5waHD7BwAAkqKeYPsHAACR9/FEpAEAAAAAAAAvAAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1NTTC5waHDmDgAAkqKeYOYOAACl/TbKpAEAAAAAAAA8AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL1Jlc3BvbnNlL0hlYWRlcnMucGhwVwgAAJKinmBXCAAA9j1RN6QBAAAAAAAANQAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24ucGhwAwQAAJKinmADBAAA7Bgl0KQBAAAAAAAALwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9JUkkucGhwiW8AAJKinmCJbwAADQZuDaQBAAAAAAAANQAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9UcmFuc3BvcnQucGhwxQQAAJKinmDFBAAA5P0q+aQBAAAAAAAAPwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9FeGNlcHRpb24vVHJhbnNwb3J0LnBocEoAAACSop5gSgAAAMU5W6GkAQAAAAAAAD4AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvNDE1LnBocKUBAACSop5gpQEAAFKtO9ekAQAAAAAAAD4AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvNDAyLnBocJMBAACSop5gkwEAAB1IYZ2kAQAAAAAAAD4AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvNDA1LnBocJkBAACSop5gmQEAAJB6XfCkAQAAAAAAAD4AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvNDAzLnBocH4BAACSop5gfgEAAAG6RDGkAQAAAAAAAD4AAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvMzA1LnBocH4BAACSop5gfgEAADQtT5OkAQAAAAAAAEIAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL0hUVFAvVW5rbm93bi5waHBkAwAAkqKeYGQDAAAB8bXnpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxOC5waHDfAQAAkqKeYN8BAAAfBN2EpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwMC5waHCiAQAAkqKeYKIBAACdZz8cpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxMS5waHCQAQAAkqKeYJABAADjee6IpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwMi5waHCEAQAAkqKeYIQBAADvLgT2pAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxNC5waHCiAQAAkqKeYKIBAADizrAbpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwNC5waHCQAQAAkqKeYJABAACP1lkBpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxMC5waHBvAQAAkqKeYG8BAAD8X403pAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwMy5waHCcAQAAkqKeYJwBAADYSdvppAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQzMS5waHAYAgAAkqKeYBgCAADPGNaNpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxNy5waHCZAQAAkqKeYJkBAAAJGkWDpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxMy5waHCrAQAAkqKeYKsBAACnzUj9pAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwMC5waHCEAQAAkqKeYIQBAABEaadRpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxMi5waHCcAQAAkqKeYJwBAAAe7/i3pAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzMwNi5waHCHAQAAkqKeYIcBAABNjG+WpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwOS5waHB7AQAAkqKeYHsBAACGd1pCpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQxNi5waHDAAQAAkqKeYMABAADE4ulypAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQyOS5waHAmAgAAkqKeYCYCAABtTWMnpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQyOC5waHD6AQAAkqKeYPoBAABKlPgypAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwOC5waHCQAQAAkqKeYJABAADvMYoipAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwNC5waHB+AQAAkqKeYH4BAAAeXx+6pAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwNS5waHCxAQAAkqKeYLEBAAC4jytmpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzMwNC5waHCHAQAAkqKeYIcBAAA59kFKpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUxMS5waHAYAgAAkqKeYBgCAACaFelmpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwNi5waHCNAQAAkqKeYI0BAAATVucipAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwNy5waHC6AQAAkqKeYLoBAABrb72RpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzQwMS5waHCHAQAAkqKeYIcBAABqiPlYpAEAAAAAAAA+AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLzUwMS5waHCQAQAAkqKeYJABAABhNI2ipAEAAAAAAAA6AAAAdmVuZG9yL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzL0V4Y2VwdGlvbi9IVFRQLnBocIwFAACSop5gjAUAAKbojnKkAQAAAAAAAEQAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvRXhjZXB0aW9uL1RyYW5zcG9ydC9jVVJMLnBocJcDAACSop5glwMAAF3xkJKkAQAAAAAAADEAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvSG9va3MucGhweAUAAJKinmB4BQAAS5ZsNaQBAAAAAAAAMAAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9BdXRoLnBocCoDAACSop5gKgMAAHUQkOmkAQAAAAAAADoAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVHJhbnNwb3J0L2NVUkwucGhwvkIAAJKinmC+QgAAKNl94aQBAAAAAAAAPwAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9UcmFuc3BvcnQvZnNvY2tvcGVuLnBocMwyAACSop5gzDIAAJ5tBeykAQAAAAAAADQAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvUmVzcG9uc2UucGhw0wkAAJKinmDTCQAAcbP5iaQBAAAAAAAANgAAAHZlbmRvci9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeS9SZXF1ZXN0cy9Qcm94eS9IVFRQLnBocKANAACSop5goA0AAEGwFySkAQAAAAAAAC4AAAB2ZW5kb3IvY29tcG9zZXIveGRlYnVnLWhhbmRsZXIvc3JjL1Byb2Nlc3MucGhwmhQAAJKinmCaFAAAcTuhhqQBAAAAAAAAMAAAAHZlbmRvci9jb21wb3Nlci94ZGVidWctaGFuZGxlci9zcmMvUGhwQ29uZmlnLnBocDUGAACSop5gNQYAAGok9aOkAQAAAAAAADQAAAB2ZW5kb3IvY29tcG9zZXIveGRlYnVnLWhhbmRsZXIvc3JjL1hkZWJ1Z0hhbmRsZXIucGhwdEkAAJKinmB0SQAAHqIfeKQBAAAAAAAALQAAAHZlbmRvci9jb21wb3Nlci94ZGVidWctaGFuZGxlci9zcmMvU3RhdHVzLnBocB0QAACSop5gHRAAAKuxZuukAQAAAAAAACUAAAB2ZW5kb3IvY29tcG9zZXIvSW5zdGFsbGVkVmVyc2lvbnMucGhwBEEAAJKinmAEQQAAj87AiKQBAAAAAAAAJQAAAHZlbmRvci9jb21wb3Nlci9hdXRvbG9hZF9jbGFzc21hcC5waHCAAQAAkqKeYIABAAAFO+u0pAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL3NwZHgtbGljZW5zZXMvc3JjL1NwZHhMaWNlbnNlcy5waHD9IwAAkqKeYP0jAACWpIKNpAEAAAAAAAAhAAAAdmVuZG9yL2NvbXBvc2VyL2F1dG9sb2FkX3BzcjQucGhwGAwAAJKinmAYDAAAHpbaYKQBAAAAAAAAIgAAAHZlbmRvci9jb21wb3Nlci9wbGF0Zm9ybV9jaGVjay5waHCdAwAAkqKeYJ0DAABUkZF0pAEAAAAAAAAnAAAAdmVuZG9yL2NvbXBvc2VyL2F1dG9sb2FkX25hbWVzcGFjZXMucGhwwwEAAJKinmDDAQAAJ2/ms6QBAAAAAAAAIwAAAHZlbmRvci9jb21wb3Nlci9hdXRvbG9hZF9zdGF0aWMucGhwBy4AAJKinmAHLgAAtjqBu6QBAAAAAAAAMQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRmFjdG9yeS5waHB/ZwAAkqKeYH9nAAAdfxwdpAEAAAAAAAAwAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25maWcucGhw2EQAAJKinmDYRAAAL06bYaQBAAAAAAAAMwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyLnBocKbBAACSop5gpsEAACX+B5CkAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsYXRmb3JtL0hodm1EZXRlY3Rvci5waHBOBwAAkqKeYE4HAAB2FSVZpAEAAAAAAAA6AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbGF0Zm9ybS9WZXJzaW9uLnBocP0KAACSop5g/QoAAFLvoQGkAQAAAAAAADoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsYXRmb3JtL1J1bnRpbWUucGhw7AgAAJKinmDsCAAASGrBUaQBAAAAAAAAOwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVkVmVyc2lvbnMucGhwqCYAAJKinmCoJgAAdycv5aQBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Db21wb3NpdGVSZXBvc2l0b3J5LnBocPMUAACSop5g8xQAAHoCBMmkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzUmVwb3NpdG9yeS5waHAkSAAAkqKeYCRIAAAuOm5opAEAAAAAAABNAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0luc3RhbGxlZEFycmF5UmVwb3NpdG9yeS5waHDFAwAAkqKeYMUDAADMjBOQpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1JlcG9zaXRvcnlTZXQucGhwpyoAAJKinmCnKgAAiVdCT6QBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9BcnRpZmFjdFJlcG9zaXRvcnkucGhwPhAAAJKinmA+EAAABl/IOqQBAAAAAAAAUQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9JbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlLnBocL8CAACSop5gvwIAAN/J2sCkAQAAAAAAAFAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUmVwb3NpdG9yeVNlY3VyaXR5RXhjZXB0aW9uLnBocOIBAACSop5g4gEAABA8Oe+kAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvRmlsdGVyUmVwb3NpdG9yeS5waHAfFQAAkqKeYB8VAAAiwl50pAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1JlcG9zaXRvcnlJbnRlcmZhY2UucGhwuhEAAJKinmC6EQAAGOCXpqQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9QYXRoUmVwb3NpdG9yeS5waHBxHQAAkqKeYHEdAAAB0csipAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1BlYXJSZXBvc2l0b3J5LnBocCoDAACSop5gKgMAAM8itO2kAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUGxhdGZvcm1SZXBvc2l0b3J5LnBocDBtAACSop5gMG0AACK4za2kAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL0dpdEh1YkRyaXZlci5waHDKTgAAkqKeYMpOAADJjH4fpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9IZ0RyaXZlci5waHArGwAAkqKeYCsbAAAeOxU6pAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9Tdm5Ecml2ZXIucGhwfi8AAJKinmB+LwAAssJiH6QBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvVmNzRHJpdmVySW50ZXJmYWNlLnBocJ8MAACSop5gnwwAAMnHp7ukAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL0JpdGJ1Y2tldERyaXZlci5waHAFNgAAkqKeYAU2AACdgkTrpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9HaXREcml2ZXIucGhwYB0AAJKinmBgHQAAVnCwFKQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvVmNzRHJpdmVyLnBocMMSAACSop5gwxIAALy9Az+kAQAAAAAAAEUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvVmNzL0dpdExhYkRyaXZlci5waHD0RgAAkqKeYPRGAAAReodepAEAAAAAAABHAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9QZXJmb3JjZURyaXZlci5waHAPDwAAkqKeYA8PAADsIwt/pAEAAAAAAABLAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1Zjcy9HaXRCaXRidWNrZXREcml2ZXIucGhwSgkAAJKinmBKCQAAcXIze6QBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvSGdCaXRidWNrZXREcml2ZXIucGhwRAkAAJKinmBECQAArNPqW6QBAAAAAAAARQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9WY3MvRm9zc2lsRHJpdmVyLnBocNocAACSop5g2hwAANlj3XmkAQAAAAAAAEQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvQXJyYXlSZXBvc2l0b3J5LnBocPwiAACSop5g/CIAAKz05WOkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvTG9ja0FycmF5UmVwb3NpdG9yeS5waHBtAgAAkqKeYG0CAADP/iGHpAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1JlcG9zaXRvcnlNYW5hZ2VyLnBocA8YAACSop5gDxgAADASwxSkAQAAAAAAAFAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlLnBocKkGAACSop5gqQYAADpxH/GkAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUm9vdFBhY2thZ2VSZXBvc2l0b3J5LnBocAoDAACSop5gCgMAAGJTwCKkAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvUmVwb3NpdG9yeUZhY3RvcnkucGhwmRwAAJKinmCZHAAAXzVn6aQBAAAAAAAATwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9JbnZhbGlkUmVwb3NpdG9yeUV4Y2VwdGlvbi5waHDfAQAAkqKeYN8BAADmnOckpAEAAAAAAABUAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0NvbmZpZ3VyYWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UucGhw3gEAAJKinmDeAQAANnujEqQBAAAAAAAASQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9GaWxlc3lzdGVtUmVwb3NpdG9yeS5waHAkIwAAkqKeYCQjAAClbtQjpAEAAAAAAABKAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1ZlcnNpb25DYWNoZUludGVyZmFjZS5waHCQAgAAkqKeYJACAABnAtQwpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L0luc3RhbGxlZFJlcG9zaXRvcnkucGhwWi8AAJKinmBaLwAAbqmwsKQBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9Db21wb3NlclJlcG9zaXRvcnkucGhwotUAAJKinmCi1QAARMLYbaQBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUmVwb3NpdG9yeS9QYWNrYWdlUmVwb3NpdG9yeS5waHDYBgAAkqKeYNgGAACK2UG/pAEAAAAAAABMAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9SZXBvc2l0b3J5L1dyaXRhYmxlQXJyYXlSZXBvc2l0b3J5LnBocMQHAACSop5gxAcAAJvS1x+kAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1JlcG9zaXRvcnkvSW5zdGFsbGVkRmlsZXN5c3RlbVJlcG9zaXRvcnkucGhw0AIAAJKinmDQAgAABcJ+i6QBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29uc29sZS9HaXRodWJBY3Rpb25FcnJvci5waHAiBQAAkqKeYCIFAACCXQ6zpAEAAAAAAABFAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25zb2xlL0h0bWxPdXRwdXRGb3JtYXR0ZXIucGhwAQoAAJKinmABCgAAplLE3KQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29uc29sZS9BcHBsaWNhdGlvbi5waHBiVwAAkqKeYGJXAACxC4Z5pAEAAAAAAABNAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9RdWVzdGlvbi9TdHJpY3RDb25maXJtYXRpb25RdWVzdGlvbi5waHBrCgAAkqKeYGsKAACX9nxGpAEAAAAAAAA2AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xpbmsucGhwMg4AAJKinmAyDgAA65iNxKQBAAAAAAAAOAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Mb2NrZXIucGhwOkAAAJKinmA6QAAACcyDc6QBAAAAAAAAPgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BbGlhc1BhY2thZ2UucGhwGCkAAJKinmAYKQAAcEFl7qQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Db21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UucGhwuAkAAJKinmC4CQAAxWSxMaQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Sb290UGFja2FnZS5waHCACgAAkqKeYIAKAAC/pihipAEAAAAAAABHAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1ZlcnNpb24vVmVyc2lvblBhcnNlci5waHCBCwAAkqKeYIELAADrlNDxpAEAAAAAAABJAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1ZlcnNpb24vVmVyc2lvblNlbGVjdG9yLnBocEMfAACSop5gQx8AAP4ZahKkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvVmVyc2lvbi9WZXJzaW9uR3Vlc3Nlci5waHCFOAAAkqKeYIU4AABzavk2pAEAAAAAAABJAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1ZlcnNpb24vU3RhYmlsaXR5RmlsdGVyLnBocB8HAACSop5gHwcAAEamct+kAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvUm9vdFBhY2thZ2VJbnRlcmZhY2UucGhwiAwAAJKinmCIDAAAJw3NZqQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9CYXNlUGFja2FnZS5waHAiGwAAkqKeYCIbAABcs1kPpAEAAAAAAABJAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL0FyY2hpdmVNYW5hZ2VyLnBocLUaAACSop5gtRoAAOh41G2kAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQXJjaGl2ZXIvUGhhckFyY2hpdmVyLnBocEYLAACSop5gRgsAAPVMCROkAQAAAAAAAFAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQXJjaGl2ZXIvQXJjaGl2YWJsZUZpbGVzRmluZGVyLnBocFMLAACSop5gUwsAANeCALKkAQAAAAAAAEsAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQXJjaGl2ZXIvR2l0RXhjbHVkZUZpbHRlci5waHA5CAAAkqKeYDkIAADiJJ6MpAEAAAAAAABMAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0FyY2hpdmVyL0Jhc2VFeGNsdWRlRmlsdGVyLnBocGwPAACSop5gbA8AAJB8pfekAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQXJjaGl2ZXIvQXJjaGl2ZXJJbnRlcmZhY2UucGhw9wQAAJKinmD3BAAAbNip46QBAAAAAAAAUAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9BcmNoaXZhYmxlRmlsZXNGaWx0ZXIucGhw3gMAAJKinmDeAwAA1LQePaQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9IZ0V4Y2x1ZGVGaWx0ZXIucGhw8goAAJKinmDyCgAAHtKxU6QBAAAAAAAAUAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9Db21wb3NlckV4Y2x1ZGVGaWx0ZXIucGhwWgMAAJKinmBaAwAASElud6QBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9BcmNoaXZlci9aaXBBcmNoaXZlci5waHBFCgAAkqKeYEUKAABYQw+kpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL1Jvb3RBbGlhc1BhY2thZ2UucGhwZg4AAJKinmBmDgAAEJDRHKQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Db21wbGV0ZVBhY2thZ2UucGhweQ8AAJKinmB5DwAASQf446QBAAAAAAAAOQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9QYWNrYWdlLnBocGI3AACSop5gYjcAAHAZrE2kAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvQ29tcGFyZXIvQ29tcGFyZXIucGhwZw4AAJKinmBnDgAATi/mpaQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Mb2FkZXIvQXJyYXlMb2FkZXIucGhwszoAAJKinmCzOgAAQuqy46QBAAAAAAAASAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGFja2FnZS9Mb2FkZXIvTG9hZGVySW50ZXJmYWNlLnBocEIDAACSop5gQgMAACr5SqSkAQAAAAAAAFAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvTG9hZGVyL0ludmFsaWRQYWNrYWdlRXhjZXB0aW9uLnBocOkDAACSop5g6QMAAElRqtikAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvTG9hZGVyL1Jvb3RQYWNrYWdlTG9hZGVyLnBocC8nAACSop5gLycAAKi501ukAQAAAAAAAE4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvTG9hZGVyL1ZhbGlkYXRpbmdBcnJheUxvYWRlci5waHC3XAAAkqKeYLdcAABIHoY6pAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QYWNrYWdlL0xvYWRlci9Kc29uTG9hZGVyLnBocFMFAACSop5gUwUAACZ1wkOkAQAAAAAAAEQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvRHVtcGVyL0FycmF5RHVtcGVyLnBocFATAACSop5gUBMAAIcwicukAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BhY2thZ2UvUGFja2FnZUludGVyZmFjZS5waHBdKgAAkqKeYF0qAAD9oaFfpAEAAAAAAAA4AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JTy9JT0ludGVyZmFjZS5waHC5HQAAkqKeYLkdAADezZW/pAEAAAAAAAA2AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JTy9Db25zb2xlSU8ucGhw3SoAAJKinmDdKgAAx/WhJqQBAAAAAAAAMwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSU8vQmFzZUlPLnBocMchAACSop5gxyEAAOxL7POkAQAAAAAAADUAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0lPL0J1ZmZlcklPLnBocCwKAACSop5gLAoAAN8ujj6kAQAAAAAAADMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0lPL051bGxJTy5waHAHCQAAkqKeYAcJAADNBf++pAEAAAAAAAA4AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0JpdGJ1Y2tldC5waHCqIQAAkqKeYKohAADuwOTupAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1N5bmNIZWxwZXIucGhwpQkAAJKinmClCQAAzNzK/KQBAAAAAAAAPgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9Qcm9jZXNzRXhlY3V0b3IucGhwbDUAAJKinmBsNQAAwS0go6QBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9IdHRwL0N1cmxEb3dubG9hZGVyLnBocOFZAACSop5g4VkAAFLOyqSkAQAAAAAAAD8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSHR0cC9Qcm94eUhlbHBlci5waHDPFAAAkqKeYM8UAACQMauWpAEAAAAAAABAAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0h0dHAvQ3VybFJlc3BvbnNlLnBocK8CAACSop5grwIAAKkbp4+kAQAAAAAAAEAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSHR0cC9SZXF1ZXN0UHJveHkucGhwbwcAAJKinmBvBwAAfCSQYaQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9IdHRwL1Byb3h5TWFuYWdlci5waHC3EgAAkqKeYLcSAABo5OJSpAEAAAAAAAA8AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0h0dHAvUmVzcG9uc2UucGhwHwkAAJKinmAfCQAAw+88y6QBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9Ob1Byb3h5UGF0dGVybi5waHAPKgAAkqKeYA8qAACGJnH5pAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0ZpbGVzeXN0ZW0ucGhw6V8AAJKinmDpXwAAonRHTqQBAAAAAAAANwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9QZXJmb3JjZS5waHD2QwAAkqKeYPZDAAByM45upAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1VybC5waHA6FAAAkqKeYDoUAAA/Xw+bpAEAAAAAAAA3AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1BsYXRmb3JtLnBocLoUAACSop5guhQAAAdhlSqkAQAAAAAAADIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvWmlwLnBocCwOAACSop5gLA4AACarboykAQAAAAAAADIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvVGFyLnBocFgHAACSop5gWAcAAKtXCVekAQAAAAAAADkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvQXV0aEhlbHBlci5waHAeMAAAkqKeYB4wAACYkiqhpAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL01ldGFkYXRhTWluaWZpZXIucGhwcQIAAJKinmBxAgAA8ZJ0WKQBAAAAAAAANQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9HaXRMYWIucGhwaRsAAJKinmBpGwAAw4Mgd6QBAAAAAAAAOAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9UbHNIZWxwZXIucGhw4RkAAJKinmDhGQAAWj8dVaQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9TdHJlYW1Db250ZXh0RmFjdG9yeS5waHBIJAAAkqKeYEgkAACXiW8qpAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1N2bi5waHA5JwAAkqKeYDknAAD63u6CpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0NvbXBvc2VyTWlycm9yLnBocPsGAACSop5g+wYAAP643lGkAQAAAAAAADwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvUGFja2FnZVNvcnRlci5waHC4CgAAkqKeYLgKAAAMUc7JpAEAAAAAAAA1AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0dpdEh1Yi5waHDpFwAAkqKeYOkXAABCavCnpAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL1JlbW90ZUZpbGVzeXN0ZW0ucGhwPoEAAJKinmA+gQAAoh1xa6QBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9IdHRwRG93bmxvYWRlci5waHBtPQAAkqKeYG09AABTRyUfpAEAAAAAAAAzAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0xvb3AucGhwcw0AAJKinmBzDQAAT29jQKQBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9HaXQucGhwfUcAAJKinmB9RwAAhOipTqQBAAAAAAAANwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvVXRpbC9TaWxlbmNlci5waHB2CAAAkqKeYHYIAACYR4kXpAEAAAAAAAAxAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9VdGlsL0hnLnBocP8LAACSop5g/wsAADZLNkCkAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvQ29uZmlnVmFsaWRhdG9yLnBocD8iAACSop5gPyIAAEItCHakAQAAAAAAADgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvSW5pSGVscGVyLnBocGAGAACSop5gYAYAAMrIyFikAQAAAAAAADsAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1V0aWwvRXJyb3JIYW5kbGVyLnBocEMJAACSop5gQwkAAMr3q7KkAQAAAAAAADYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1NjcmlwdC9FdmVudC5waHDGCwAAkqKeYMYLAAC1kWjApAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9TY3JpcHQvU2NyaXB0RXZlbnRzLnBocCcOAACSop5gJw4AAPkggcakAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9QcmVQb29sQ3JlYXRlRXZlbnQucGhwsQ0AAJKinmCxDQAAX1l3aqQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL1BsdWdpbkludGVyZmFjZS5waHCtBgAAkqKeYK0GAADatl33pAEAAAAAAABFAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vUHJlRmlsZURvd25sb2FkRXZlbnQucGhwMAsAAJKinmAwCwAAm+Y+i6QBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL1Bvc3RGaWxlRG93bmxvYWRFdmVudC5waHDwBwAAkqKeYPAHAAALUJtXpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vUGx1Z2luRXZlbnRzLnBocCcIAACSop5gJwgAAPXSPe2kAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL1BsdWdpbi9Db21tYW5kRXZlbnQucGhwrQcAAJKinmCtBwAAI60gEaQBAAAAAAAARgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL0NhcGFiaWxpdHkvQ2FwYWJpbGl0eS5waHDlAQAAkqKeYOUBAABZObEzpAEAAAAAAABLAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vQ2FwYWJpbGl0eS9Db21tYW5kUHJvdmlkZXIucGhwXwMAAJKinmBfAwAAgs686KQBAAAAAAAAOAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL0NhcGFibGUucGhwmwQAAJKinmCbBAAAJw/xfaQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvUGx1Z2luL1ByZUNvbW1hbmRSdW5FdmVudC5waHBNBQAAkqKeYE0FAADDkkAJpAEAAAAAAAA+AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9QbHVnaW4vUGx1Z2luTWFuYWdlci5waHDPUgAAkqKeYM9SAABNHgXIpAEAAAAAAABSAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9FdmVudERpc3BhdGNoZXIvRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlLnBocBEGAACSop5gEQYAAJ0cI2ekAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V2ZW50RGlzcGF0Y2hlci9TY3JpcHRFeGVjdXRpb25FeGNlcHRpb24ucGhwpgEAAJKinmCmAQAAXCEnxqQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRXZlbnREaXNwYXRjaGVyL0V2ZW50LnBocGYIAACSop5gZggAAEt4H9WkAQAAAAAAAEkAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V2ZW50RGlzcGF0Y2hlci9FdmVudERpc3BhdGNoZXIucGhwGVQAAJKinmAZVAAAmsW4vKQBAAAAAAAAMgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tcGlsZXIucGhwECoAAJKinmAQKgAAL9fRGaQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQXV0b2xvYWRHZW5lcmF0b3IucGhw77IAAJKinmDvsgAA7GsUwaQBAAAAAAAAPgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQ2xhc3NMb2FkZXIucGhwHzgAAJKinmAfOAAAbD36LaQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQXV0b2xvYWQvQ2xhc3NNYXBHZW5lcmF0b3IucGhwCjMAAJKinmAKMwAAUiaY6KQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9MaWNlbnNlc0NvbW1hbmQucGhwqxoAAJKinmCrGgAA2VhioqQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9TY3JpcHRBbGlhc0NvbW1hbmQucGhw0wcAAJKinmDTBwAAyWZPoqQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9BcmNoaXZlQ29tbWFuZC5waHB7GwAAkqKeYHsbAAAeyGiHpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL0luaXRDb21tYW5kLnBocD6IAACSop5gPogAAFsosKekAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvUnVuU2NyaXB0Q29tbWFuZC5waHC7EwAAkqKeYLsTAABZHd7ipAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1NlYXJjaENvbW1hbmQucGhw/QsAAJKinmD9CwAAS4A106QBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9EaWFnbm9zZUNvbW1hbmQucGhwcmYAAJKinmByZgAAJ1CQgKQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9Ib21lQ29tbWFuZC5waHB6FQAAkqKeYHoVAAAbHcKdpAEAAAAAAAA9AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1Nob3dDb21tYW5kLnBocMLNAACSop5gws0AALaAd5mkAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvT3V0ZGF0ZWRDb21tYW5kLnBocB8RAACSop5gHxEAAL5hUmqkAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvRnVuZENvbW1hbmQucGhwGRIAAJKinmAZEgAA7iqyV6QBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9TdWdnZXN0c0NvbW1hbmQucGhwzw8AAJKinmDPDwAA2rzzk6QBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9EZXBlbmRzQ29tbWFuZC5waHBtBQAAkqKeYG0FAACm4sUZpAEAAAAAAAA/AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1N0YXR1c0NvbW1hbmQucGhwjSEAAJKinmCNIQAAhxhzz6QBAAAAAAAARQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9EdW1wQXV0b2xvYWRDb21tYW5kLnBocBUSAACSop5gFRIAAFKAUcKkAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQWJvdXRDb21tYW5kLnBocJQEAACSop5glAQAACcY+3ykAQAAAAAAAEoAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQ2hlY2tQbGF0Zm9ybVJlcXNDb21tYW5kLnBocLIeAACSop5gsh4AABumejykAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQ3JlYXRlUHJvamVjdENvbW1hbmQucGhwElYAAJKinmASVgAAvKCELqQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9Db25maWdDb21tYW5kLnBocCd+AACSop5gJ34AAAQoDR2kAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQmFzZUNvbW1hbmQucGhwRhoAAJKinmBGGgAAsWvM5aQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9SZW1vdmVDb21tYW5kLnBocCA3AACSop5gIDcAAAkJVsekAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvQ2xlYXJDYWNoZUNvbW1hbmQucGhwsQgAAJKinmCxCAAAKcWpqaQBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9CYXNlRGVwZW5kZW5jeUNvbW1hbmQucGhwGiYAAJKinmAaJgAA5wOWqaQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9VcGRhdGVDb21tYW5kLnBocG0+AACSop5gbT4AAFNtzN6kAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvRXhlY0NvbW1hbmQucGhwjA0AAJKinmCMDQAAtsoljaQBAAAAAAAAQQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9WYWxpZGF0ZUNvbW1hbmQucGhwVR0AAJKinmBVHQAALkig2qQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9JbnN0YWxsQ29tbWFuZC5waHB9HQAAkqKeYH0dAAByi1RTpAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21tYW5kL1Byb2hpYml0c0NvbW1hbmQucGhwjgUAAJKinmCOBQAA+JDr2aQBAAAAAAAAPwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9HbG9iYWxDb21tYW5kLnBocEQOAACSop5gRA4AACW5rj2kAQAAAAAAAEAAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0NvbW1hbmQvUmVxdWlyZUNvbW1hbmQucGhwvEcAAJKinmC8RwAAyaW+BaQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ29tbWFuZC9TZWxmVXBkYXRlQ29tbWFuZC5waHCbYAAAkqKeYJtgAADOPEDMpAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9TZWxmVXBkYXRlL0tleXMucGhwagMAAJKinmBqAwAA3O+dQaQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvU2VsZlVwZGF0ZS9WZXJzaW9ucy5waHAaCgAAkqKeYBoKAACfYZvjpAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Kc29uL0pzb25WYWxpZGF0aW9uRXhjZXB0aW9uLnBocMACAACSop5gwAIAAJeUSsikAQAAAAAAAD4AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0pzb24vSnNvbk1hbmlwdWxhdG9yLnBocMFRAACSop5gwVEAADMn/v6kAQAAAAAAADwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0pzb24vSnNvbkZvcm1hdHRlci5waHChEQAAkqKeYKERAABT6QcapAEAAAAAAAA3AAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Kc29uL0pzb25GaWxlLnBocLMpAACSop5gsykAABXp8q2kAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0V4Y2VwdGlvbi9Ob1NzbEV4Y2VwdGlvbi5waHDaAQAAkqKeYNoBAAA4TTXtpAEAAAAAAABSAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9FeGNlcHRpb24vSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uLnBocKYBAACSop5gpgEAAIofiy2kAQAAAAAAAEcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsYXRpb25NYW5hZ2VyLnBocGBZAACSop5gYFkAALjg4XekAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9QbHVnaW5JbnN0YWxsZXIucGhwww8AAJKinmDDDwAA3H6lWKQBAAAAAAAAQAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL1BhY2thZ2VFdmVudC5waHBNCgAAkqKeYE0KAAA/ecclpAEAAAAAAABEAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvUHJvamVjdEluc3RhbGxlci5waHAaDQAAkqKeYBoNAADHxZumpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvQmluYXJ5SW5zdGFsbGVyLnBocGghAACSop5gaCEAALKstGekAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9QYWNrYWdlRXZlbnRzLnBocOQHAACSop5g5AcAAFq7VqykAQAAAAAAAEQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9MaWJyYXJ5SW5zdGFsbGVyLnBocNEnAACSop5g0ScAAPKTzJWkAQAAAAAAAE0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9TdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyLnBocPEgAACSop5g8SAAAJAvl76kAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9Ob29wSW5zdGFsbGVyLnBocCoKAACSop5gKgoAAKJgWNykAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsZXJJbnRlcmZhY2UucGhwthIAAJKinmC2EgAA/H2Se6QBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL0luc3RhbGxlckV2ZW50cy5waHB7AgAAkqKeYHsCAAD02TPjpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9JbnN0YWxsZXIvTWV0YXBhY2thZ2VJbnN0YWxsZXIucGhwkQsAAJKinmCRCwAANQzgQKQBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSW5zdGFsbGVyL0JpbmFyeVByZXNlbmNlSW50ZXJmYWNlLnBocNsCAACSop5g2wIAAKnHEfSkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0luc3RhbGxlci9JbnN0YWxsZXJFdmVudC5waHD4BwAAkqKeYPgHAAB+uCwIpAEAAAAAAAAyAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db21wb3Nlci5waHCfGgAAkqKeYJ8aAAAKoHg/pAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0Rvd25sb2FkZXJJbnRlcmZhY2UucGhwvw4AAJKinmC/DgAABOGwMaQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9SYXJEb3dubG9hZGVyLnBocGUJAACSop5gZQkAAEXT+RGkAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvVGFyRG93bmxvYWRlci5waHD8AgAAkqKeYPwCAADODbdmpAEAAAAAAABHAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1BlcmZvcmNlRG93bmxvYWRlci5waHCwCwAAkqKeYLALAABYw6jFpAEAAAAAAABEAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0Rvd25sb2FkTWFuYWdlci5waHDvPAAAkqKeYO88AAC/fnJspAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0FyY2hpdmVEb3dubG9hZGVyLnBocJMcAACSop5gkxwAAONgUeSkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvRmlsZXN5c3RlbUV4Y2VwdGlvbi5waHCgAgAAkqKeYKACAAC/7JQHpAEAAAAAAABMAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0R2Y3NEb3dubG9hZGVySW50ZXJmYWNlLnBocA4DAACSop5gDgMAAOp2oCikAQAAAAAAAEIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvR2l0RG93bmxvYWRlci5waHD+XAAAkqKeYP5cAABvUY+upAEAAAAAAABFAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0Zvc3NpbERvd25sb2FkZXIucGhwLBAAAJKinmAsEAAAxXoMraQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9QYXRoRG93bmxvYWRlci5waHAqJgAAkqKeYComAADWW2jypAEAAAAAAABKAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL0NoYW5nZVJlcG9ydEludGVyZmFjZS5waHD+AgAAkqKeYP4CAADZKcW4pAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1BoYXJEb3dubG9hZGVyLnBocOwDAACSop5g7AMAAEgkK+WkAQAAAAAAAFIAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvVmNzQ2FwYWJsZURvd25sb2FkZXJJbnRlcmZhY2UucGhwGwMAAJKinmAbAwAABgycmaQBAAAAAAAARwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9UcmFuc3BvcnRFeGNlcHRpb24ucGhwOQUAAJKinmA5BQAABf0EHqQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9Tdm5Eb3dubG9hZGVyLnBocPMgAACSop5g8yAAAD6d5oSkAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvSGdEb3dubG9hZGVyLnBocBUNAACSop5gFQ0AAIiScRakAQAAAAAAAEEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvWHpEb3dubG9hZGVyLnBocOkDAACSop5g6QMAABQVywakAQAAAAAAAFEAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbi5waHBvAQAAkqKeYG8BAAC/Oq6npAEAAAAAAABCAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Eb3dubG9hZGVyL1Zjc0Rvd25sb2FkZXIucGhwMDAAAJKinmAwMAAAG24H6KQBAAAAAAAAQgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9aaXBEb3dubG9hZGVyLnBocN4pAACSop5g3ikAAEC+FBGkAQAAAAAAAEMAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0Rvd25sb2FkZXIvR3ppcERvd25sb2FkZXIucGhwsQcAAJKinmCxBwAAdbLG7qQBAAAAAAAAQwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRG93bmxvYWRlci9GaWxlRG93bmxvYWRlci5waHCCRAAAkqKeYIJEAABtP0jbpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25maWcvSnNvbkNvbmZpZ1NvdXJjZS5waHBaKAAAkqKeYFooAAClQpF5pAEAAAAAAABGAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9Db25maWcvQ29uZmlnU291cmNlSW50ZXJmYWNlLnBocN8HAACSop5g3wcAAHSvrzqkAQAAAAAAAE8AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9Tb2x2ZXJCdWdFeGNlcHRpb24ucGhw/gIAAJKinmD+AgAAvjh8NKQBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL0RlZmF1bHRQb2xpY3kucGhwrRsAAJKinmCtGwAA8/Fcj6QBAAAAAAAASgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGUyTGl0ZXJhbHMucGhwUQoAAJKinmBRCgAA+7DRNqQBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVXYXRjaENoYWluLnBocHoFAACSop5gegUAAGRdX0OkAQAAAAAAAFcAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9PcGVyYXRpb24vSW5zdGFsbE9wZXJhdGlvbi5waHADBQAAkqKeYAMFAADji7Z0pAEAAAAAAABZAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvT3BlcmF0aW9uL1VuaW5zdGFsbE9wZXJhdGlvbi5waHDtBAAAkqKeYO0EAAAi12pipAEAAAAAAABZAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvT3BlcmF0aW9uL09wZXJhdGlvbkludGVyZmFjZS5waHCTAwAAkqKeYJMDAAAKWS96pAEAAAAAAABiAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvT3BlcmF0aW9uL01hcmtBbGlhc0luc3RhbGxlZE9wZXJhdGlvbi5waHAJBQAAkqKeYAkFAAD7ReGepAEAAAAAAABWAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvT3BlcmF0aW9uL1VwZGF0ZU9wZXJhdGlvbi5waHARCwAAkqKeYBELAAAEXxNepAEAAAAAAABkAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvT3BlcmF0aW9uL01hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9uLnBocA8FAACSop5gDwUAAHNbIKekAQAAAAAAAFYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9PcGVyYXRpb24vU29sdmVyT3BlcmF0aW9uLnBocBMDAACSop5gEwMAAGGRyFmkAQAAAAAAAEwAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9SdWxlU2V0SXRlcmF0b3IucGhwCAkAAJKinmAICQAAOThBC6QBAAAAAAAASwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1J1bGVXYXRjaEdyYXBoLnBocOwYAACSop5g7BgAABAGeaGkAQAAAAAAAFQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9Tb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbi5waHC4EQAAkqKeYLgRAAA0nkHlpAEAAAAAAABIAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUG9vbEJ1aWxkZXIucGhw4lkAAJKinmDiWQAAdy7M2qQBAAAAAAAARAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1JlcXVlc3QucGhwPBsAAJKinmA8GwAA9kpJcKQBAAAAAAAATAAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL1BvbGljeUludGVyZmFjZS5waHBwAgAAkqKeYHACAAAEdzrFpAEAAAAAAABDAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvU29sdmVyLnBocMVnAACSop5gxWcAACmUTKikAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9UcmFuc2FjdGlvbi5waHCsNAAAkqKeYKw0AABhbBizpAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUG9vbC5waHDAFwAAkqKeYMAXAAAFuyy9pAEAAAAAAABBAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUnVsZS5waHDdOwAAkqKeYN07AAC5L7YYpAEAAAAAAABOAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvTXVsdGlDb25mbGljdFJ1bGUucGhwYwoAAJKinmBjCgAAVXTP8aQBAAAAAAAAUQAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvRGVwZW5kZW5jeVJlc29sdmVyL0xvY2FsUmVwb1RyYW5zYWN0aW9uLnBocMICAACSop5gwgIAABQQbyqkAQAAAAAAAE0AAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9SdWxlU2V0R2VuZXJhdG9yLnBocKEvAACSop5goS8AAHKuAhikAQAAAAAAAEQAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9Qcm9ibGVtLnBocINPAACSop5gg08AAOXIg/SkAQAAAAAAAEgAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9HZW5lcmljUnVsZS5waHAwCAAAkqKeYDAIAABYtznApAEAAAAAAABEAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUnVsZVNldC5waHAGEQAAkqKeYAYRAABStVXgpAEAAAAAAABKAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvUnVsZVdhdGNoTm9kZS5waHAKCwAAkqKeYAoLAADLsDcLpAEAAAAAAABMAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3NyYy9Db21wb3Nlci9EZXBlbmRlbmN5UmVzb2x2ZXIvTG9ja1RyYW5zYWN0aW9uLnBocHkTAACSop5geRMAAHfokD2kAQAAAAAAAEYAAAB2ZW5kb3IvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyL0RlcGVuZGVuY3lSZXNvbHZlci9EZWNpc2lvbnMucGhwNBYAAJKinmA0FgAAE69VnqQBAAAAAAAALwAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvQ2FjaGUucGhwiSAAAJKinmCJIAAAX65fJ6QBAAAAAAAAKgAAAHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvYm9vdHN0cmFwLnBocMkCAACSop5gyQIAAGNBbOmkAQAAAAAAAB8AAAB2ZW5kb3IvY29tcG9zZXIvQ2xhc3NMb2FkZXIucGhwHzgAAJKinmAfOAAAbD36LaQBAAAAAAAAHQAAAHZlbmRvci9jb21wb3Nlci9pbnN0YWxsZWQucGhwEjEAAJKinmASMQAA7SB0rqQBAAAAAAAAOgAAAHZlbmRvci9jb21wb3Nlci9tZXRhZGF0YS1taW5pZmllci9zcmMvTWV0YWRhdGFNaW5pZmllci5waHCyCgAAkqKeYLIKAADWbO8zpAEAAAAAAAAsAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvVmVyc2lvblBhcnNlci5waHA7UgAAkqKeYDtSAACJ15T0pAEAAAAAAAAlAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvU2VtdmVyLnBocCMNAACSop5gIw0AAHRzDOCkAQAAAAAAAC8AAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9Db21waWxpbmdNYXRjaGVyLnBocNsHAACSop5g2wcAAJHukyikAQAAAAAAACkAAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9Db21wYXJhdG9yLnBocAcKAACSop5gBwoAAFN3DaikAQAAAAAAACcAAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9JbnRlcnZhbC5waHB+BwAAkqKeYH4HAABFfLxWpAEAAAAAAAA5AAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29uc3RyYWludC9NdWx0aUNvbnN0cmFpbnQucGhw9yAAAJKinmD3IAAAojf+JKQBAAAAAAAAPAAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0NvbnN0cmFpbnQvTWF0Y2hBbGxDb25zdHJhaW50LnBocK8FAACSop5grwUAAKVw1eekAQAAAAAAAD0AAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9Db25zdHJhaW50L01hdGNoTm9uZUNvbnN0cmFpbnQucGhwqQUAAJKinmCpBQAAtTKUCqQBAAAAAAAAPQAAAHZlbmRvci9jb21wb3Nlci9zZW12ZXIvc3JjL0NvbnN0cmFpbnQvQ29uc3RyYWludEludGVyZmFjZS5waHBUBwAAkqKeYFQHAAAkeGLQpAEAAAAAAAAvAAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29uc3RyYWludC9Cb3VuZC5waHAdCgAAkqKeYB0KAACUIUlPpAEAAAAAAAA0AAAAdmVuZG9yL2NvbXBvc2VyL3NlbXZlci9zcmMvQ29uc3RyYWludC9Db25zdHJhaW50LnBocG4vAACSop5gbi8AALs2YwakAQAAAAAAACgAAAB2ZW5kb3IvY29tcG9zZXIvc2VtdmVyL3NyYy9JbnRlcnZhbHMucGhwzk8AAJKinmDOTwAAuwh0VKQBAAAAAAAAIQAAAHZlbmRvci9jb21wb3Nlci9hdXRvbG9hZF9yZWFsLnBocPUJAACSop5g9QkAAIoHBIGkAQAAAAAAACIAAAB2ZW5kb3IvY29tcG9zZXIvYXV0b2xvYWRfZmlsZXMucGhw2gwAAJKinmDaDAAADRNPnaQBAAAAAAAAKgAAAHZlbmRvci9jb21wb3Nlci9jYS1idW5kbGUvc3JjL0NhQnVuZGxlLnBocBQ8AACSop5gFDwAAMCr6CakAQAAAAAAACIAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1Byb2Nlc3MucGhw09kAAJKinmDT2QAA9syeJ6QBAAAAAAAAJgAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvSW5wdXRTdHJlYW0ucGhwFAkAAJKinmAUCQAAdyeYyKQBAAAAAAAAJwAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvUHJvY2Vzc1V0aWxzLnBocK0PAACSop5grQ8AAGEeWGGkAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1BpcGVzL1BpcGVzSW50ZXJmYWNlLnBocPgFAACSop5g+AUAAOMrkrOkAQAAAAAAAC0AAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1BpcGVzL1dpbmRvd3NQaXBlcy5waHB1FgAAkqKeYHUWAAB1Ewe5pAEAAAAAAAAuAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9QaXBlcy9BYnN0cmFjdFBpcGVzLnBocK4TAACSop5grhMAAIbzAzykAQAAAAAAACoAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1BpcGVzL1VuaXhQaXBlcy5waHAsDgAAkqKeYCwOAAAEEnEbpAEAAAAAAAAuAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9QaHBFeGVjdXRhYmxlRmluZGVyLnBocEcJAACSop5gRwkAAB1fpCOkAQAAAAAAACsAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL0V4ZWN1dGFibGVGaW5kZXIucGhwIgoAAJKinmAiCgAAJSJ4tKQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHDwAQAAkqKeYPABAADLhY3rpAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9FeGNlcHRpb24vTG9naWNFeGNlcHRpb24ucGhw0gEAAJKinmDSAQAAHbCoV6QBAAAAAAAANQAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhjZXB0aW9uL1J1bnRpbWVFeGNlcHRpb24ucGhw4QEAAJKinmDhAQAAPkiWmaQBAAAAAAAANwAAAHZlbmRvci9zeW1mb255L3Byb2Nlc3MvRXhjZXB0aW9uL0V4Y2VwdGlvbkludGVyZmFjZS5waHCvAQAAkqKeYK8BAAAajTyepAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvcHJvY2Vzcy9FeGNlcHRpb24vUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uLnBocHsGAACSop5gewYAADSxEAKkAQAAAAAAADsAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL0V4Y2VwdGlvbi9Qcm9jZXNzRmFpbGVkRXhjZXB0aW9uLnBocI0FAACSop5gjQUAAFDBtDWkAQAAAAAAACkAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1Byb2Nlc3NCdWlsZGVyLnBocAoaAACSop5gChoAAGonVWikAQAAAAAAACUAAAB2ZW5kb3Ivc3ltZm9ueS9wcm9jZXNzL1BocFByb2Nlc3MucGhwwAkAAJKinmDACQAA+KG2A6QBAAAAAAAAKwAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLWN0eXBlL2Jvb3RzdHJhcC5waHAEBgAAkqKeYAQGAADAMDH2pAEAAAAAAAAnAAAAdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtY3R5cGUvQ3R5cGUucGhwfRgAAJKinmB9GAAAXIrosKQBAAAAAAAAKAAAAHZlbmRvci9zeW1mb255L2ZpbGVzeXN0ZW0vRmlsZXN5c3RlbS5waHBHdAAAkqKeYEd0AAAuV1iIpAEAAAAAAAApAAAAdmVuZG9yL3N5bWZvbnkvZmlsZXN5c3RlbS9Mb2NrSGFuZGxlci5waHA+DwAAkqKeYD4PAAA4AEgLpAEAAAAAAAA8AAAAdmVuZG9yL3N5bWZvbnkvZmlsZXN5c3RlbS9FeGNlcHRpb24vSU9FeGNlcHRpb25JbnRlcmZhY2UucGhwpgIAAJKinmCmAgAAqJlplKQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2ZpbGVzeXN0ZW0vRXhjZXB0aW9uL0ZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5waHC3AwAAkqKeYLcDAAD+MHrCpAEAAAAAAAA6AAAAdmVuZG9yL3N5bWZvbnkvZmlsZXN5c3RlbS9FeGNlcHRpb24vRXhjZXB0aW9uSW50ZXJmYWNlLnBocL0BAACSop5gvQEAABdoqqCkAQAAAAAAADMAAAB2ZW5kb3Ivc3ltZm9ueS9maWxlc3lzdGVtL0V4Y2VwdGlvbi9JT0V4Y2VwdGlvbi5waHCqAwAAkqKeYKoDAADRkYRBpAEAAAAAAAAuAAAAdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcvYm9vdHN0cmFwLnBocI0cAACSop5gjRwAAG2gfESkAQAAAAAAAEAAAAB2ZW5kb3Ivc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9SZXNvdXJjZXMvdW5pZGF0YS9sb3dlckNhc2UucGhw2V8AAJKinmDZXwAAWrafiqQBAAAAAAAARgAAAHZlbmRvci9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL1Jlc291cmNlcy91bmlkYXRhL3RpdGxlQ2FzZVJlZ2V4cC5waHA5GAAAkqKeYDkYAAA+fHpLpAEAAAAAAABAAAAAdmVuZG9yL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcvUmVzb3VyY2VzL3VuaWRhdGEvdXBwZXJDYXNlLnBocPJgAACSop5g8mAAAIpT6f2kAQAAAAAAAEQAAAB2ZW5kb3Ivc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9SZXNvdXJjZXMvbWJfY29udmVydF92YXJpYWJsZXMucGhwOD8DAACSop5gPwMAAPIW76CkAQAAAAAAAC0AAAB2ZW5kb3Ivc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9NYnN0cmluZy5waHADbgAAkqKeYANuAABwXudDpAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9UZXN0ZXIvQXBwbGljYXRpb25UZXN0ZXIucGhwChYAAJKinmAKFgAAWpnn6aQBAAAAAAAALwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvVGVzdGVyL0NvbW1hbmRUZXN0ZXIucGhw7REAAJKinmDtEQAAm0RknqQBAAAAAAAALAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvUXVlc3Rpb24vUXVlc3Rpb24ucGhw4RUAAJKinmDhFQAAj86KgaQBAAAAAAAAMgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvUXVlc3Rpb24vQ2hvaWNlUXVlc3Rpb24ucGhwXRMAAJKinmBdEwAAjzWIJ6QBAAAAAAAAOAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvUXVlc3Rpb24vQ29uZmlybWF0aW9uUXVlc3Rpb24ucGhwIwYAAJKinmAjBgAAz4H7G6QBAAAAAAAALwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvTG9nZ2VyL0NvbnNvbGVMb2dnZXIucGhw2hAAAJKinmDaEAAAB/eGVaQBAAAAAAAAPwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZExvYWRlci9Db21tYW5kTG9hZGVySW50ZXJmYWNlLnBocKADAACSop5goAMAALrH9hKkAQAAAAAAAD8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbW1hbmRMb2FkZXIvQ29udGFpbmVyQ29tbWFuZExvYWRlci5waHA+BgAAkqKeYD4GAAAjupMqpAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9Db21tYW5kTG9hZGVyL0ZhY3RvcnlDb21tYW5kTG9hZGVyLnBocDcFAACSop5gNwUAAIJtX/KkAQAAAAAAADAAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvRGVzY3JpcHRvci5waHBkDAAAkqKeYGQMAACh1uVUpAEAAAAAAAA4AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXNjcmlwdG9yL01hcmtkb3duRGVzY3JpcHRvci5waHC9FwAAkqKeYL0XAABmIDA+pAEAAAAAAAA0AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXNjcmlwdG9yL1RleHREZXNjcmlwdG9yLnBocGYwAACSop5gZjAAAKPHVxGkAQAAAAAAADkAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvRGVzY3JpcHRvckludGVyZmFjZS5waHCDAgAAkqKeYIMCAABQ2lr2pAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXNjcmlwdG9yL1htbERlc2NyaXB0b3IucGhw8SMAAJKinmDxIwAAx9BkS6QBAAAAAAAAPAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRGVzY3JpcHRvci9BcHBsaWNhdGlvbkRlc2NyaXB0aW9uLnBocIsPAACSop5giw8AANXRBqykAQAAAAAAADQAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Rlc2NyaXB0b3IvSnNvbkRlc2NyaXB0b3IucGhwEhQAAJKinmASFAAAbvQHFaQBAAAAAAAAPgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRm9ybWF0dGVyL091dHB1dEZvcm1hdHRlclN0eWxlU3RhY2sucGhwtQkAAJKinmC1CQAAl7+L0qQBAAAAAAAAOQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRm9ybWF0dGVyL091dHB1dEZvcm1hdHRlclN0eWxlLnBocDIWAACSop5gMhYAAB5Tu5ukAQAAAAAAAD0AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Zvcm1hdHRlci9PdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UucGhwpgYAAJKinmCmBgAAIzfqdaQBAAAAAAAAQgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRm9ybWF0dGVyL091dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlLnBocDwFAACSop5gPAUAAJ+90FqkAQAAAAAAADQAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0Zvcm1hdHRlci9PdXRwdXRGb3JtYXR0ZXIucGhwoRoAAJKinmChGgAAToiReKQBAAAAAAAAMQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvT3V0cHV0L091dHB1dEludGVyZmFjZS5waHAPDQAAkqKeYA8NAACSs+kmpAEAAAAAAAAoAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9PdXRwdXQvT3V0cHV0LnBocHsRAACSop5gexEAAO6e+DekAQAAAAAAADgAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9Db25zb2xlT3V0cHV0SW50ZXJmYWNlLnBocN4CAACSop5g3gIAAL8RoIOkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9OdWxsT3V0cHV0LnBocG4IAACSop5gbggAAHSPRLukAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9TdHJlYW1PdXRwdXQucGhwbw4AAJKinmBvDgAACxDDfqQBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvT3V0cHV0L0J1ZmZlcmVkT3V0cHV0LnBocEkDAACSop5gSQMAAAiFXPykAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL091dHB1dC9Db25zb2xlT3V0cHV0LnBocKcPAACSop5gpw8AALdKRGKkAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Qcm9jZXNzSGVscGVyLnBocM8TAACSop5gzxMAABP+dPukAQAAAAAAADcAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9TeW1mb255UXVlc3Rpb25IZWxwZXIucGhwhw8AAJKinmCHDwAAOYv08KQBAAAAAAAAKAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0hlbHBlci5waHCwDgAAkqKeYLAOAAB9S3W3pAEAAAAAAAAnAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvVGFibGUucGhwuE0AAJKinmC4TQAA6x4hPKQBAAAAAAAAMgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0lucHV0QXdhcmVIZWxwZXIucGhw6wIAAJKinmDrAgAAFLydF6QBAAAAAAAAMgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0Rlc2NyaXB0b3JIZWxwZXIucGhwkQkAAJKinmCRCQAAyxL7/qQBAAAAAAAANgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0RlYnVnRm9ybWF0dGVySGVscGVyLnBocEgQAACSop5gSBAAAF1SYEGkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9UYWJsZVN0eWxlLnBocHsUAACSop5gexQAALJwbhWkAQAAAAAAACsAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9UYWJsZUNlbGwucGhwUgYAAJKinmBSBgAA7Up7v6QBAAAAAAAAMQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0hlbHBlckludGVyZmFjZS5waHBwAwAAkqKeYHADAACR4PFupAEAAAAAAAAwAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvUXVlc3Rpb25IZWxwZXIucGhwAEIAAJKinmAAQgAAp92XXqQBAAAAAAAAMQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL0Zvcm1hdHRlckhlbHBlci5waHDhCgAAkqKeYOEKAAANVfr2pAEAAAAAAAArAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvSGVscGVyU2V0LnBocMEJAACSop5gwQkAAMMzQwykAQAAAAAAAC0AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0hlbHBlci9Qcm9ncmVzc0Jhci5waHA/QwAAkqKeYD9DAAA4mbAIpAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9IZWxwZXIvUHJvZ3Jlc3NJbmRpY2F0b3IucGhwph4AAJKinmCmHgAAitCUUKQBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSGVscGVyL1RhYmxlU2VwYXJhdG9yLnBocBMCAACSop5gEwIAACaKqg2kAQAAAAAAACMAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL1Rlcm1pbmFsLnBocNITAACSop5g0hMAABt1vu+kAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbW1hbmQvTGlzdENvbW1hbmQucGhw/wkAAJKinmD/CQAAHvGbI6QBAAAAAAAAKgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZC9Db21tYW5kLnBocIZMAACSop5ghkwAAEb65f2kAQAAAAAAAC4AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbW1hbmQvSGVscENvbW1hbmQucGhwPwkAAJKinmA/CQAA+I3kJ6QBAAAAAAAAMAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvQ29tbWFuZC9Mb2NrYWJsZVRyYWl0LnBocOQGAACSop5g5AYAAIruTwKkAQAAAAAAACgAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0NvbnNvbGVFdmVudHMucGhwIQcAAJKinmAhBwAAn5POqaQBAAAAAAAALQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvU3R5bGUvU3ltZm9ueVN0eWxlLnBocE8vAACSop5gTy8AABtBC3qkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL1N0eWxlL091dHB1dFN0eWxlLnBocP4LAACSop5g/gsAAJOxon6kAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL1N0eWxlL1N0eWxlSW50ZXJmYWNlLnBocCgMAACSop5gKAwAAK81IPGkAQAAAAAAAD0AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V4Y2VwdGlvbi9Db21tYW5kTm90Rm91bmRFeGNlcHRpb24ucGhwvQQAAJKinmC9BAAALpdvo6QBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHC+AQAAkqKeYL4BAADudSBppAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FeGNlcHRpb24vTG9naWNFeGNlcHRpb24ucGhwqgEAAJKinmCqAQAAU01Mj6QBAAAAAAAAOwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXhjZXB0aW9uL0ludmFsaWRPcHRpb25FeGNlcHRpb24ucGhw/AEAAJKinmD8AQAA7ZM7E6QBAAAAAAAANQAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXhjZXB0aW9uL1J1bnRpbWVFeGNlcHRpb24ucGhwrgEAAJKinmCuAQAAF7YqYqQBAAAAAAAANwAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXhjZXB0aW9uL0V4Y2VwdGlvbkludGVyZmFjZS5waHCWAQAAkqKeYJYBAADj69pVpAEAAAAAAAAmAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9BcHBsaWNhdGlvbi5waHA2rQAAkqKeYDatAAD3QadjpAEAAAAAAABEAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9EZXBlbmRlbmN5SW5qZWN0aW9uL0FkZENvbnNvbGVDb21tYW5kUGFzcy5waHCaDwAAkqKeYJoPAABBfFwHpAEAAAAAAAAyAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FdmVudC9Db25zb2xlRXJyb3JFdmVudC5waHDFCAAAkqKeYMUIAABsmxKdpAEAAAAAAAA2AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FdmVudC9Db25zb2xlRXhjZXB0aW9uRXZlbnQucGhwVAcAAJKinmBUBwAAw97jEKQBAAAAAAAANAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXZlbnQvQ29uc29sZUNvbW1hbmRFdmVudC5waHAlBQAAkqKeYCUFAAB7y77gpAEAAAAAAAAtAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9FdmVudC9Db25zb2xlRXZlbnQucGhwxAUAAJKinmDEBQAAeFMqD6QBAAAAAAAANgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvRXZlbnQvQ29uc29sZVRlcm1pbmF0ZUV2ZW50LnBocBoFAACSop5gGgUAAHtl8BOkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L1N0cmluZ0lucHV0LnBocEYJAACSop5gRgkAAP2lYzqkAQAAAAAAAC8AAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L0lucHV0SW50ZXJmYWNlLnBocLETAACSop5gsRMAAPXOiNqkAQAAAAAAADAAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L0lucHV0RGVmaW5pdGlvbi5waHDTKwAAkqKeYNMrAAC7A3wGpAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9TdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2UucGhwaQMAAJKinmBpAwAA9ReZ7aQBAAAAAAAAJgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvSW5wdXQucGhwchMAAJKinmByEwAAVYJqeKQBAAAAAAAANAAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvSW5wdXRBd2FyZUludGVyZmFjZS5waHA6AgAAkqKeYDoCAACxICe0pAEAAAAAAAAuAAAAdmVuZG9yL3N5bWZvbnkvY29uc29sZS9JbnB1dC9JbnB1dEFyZ3VtZW50LnBocE8NAACSop5gTw0AACjQwOKkAQAAAAAAACwAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L0lucHV0T3B0aW9uLnBocKIXAACSop5gohcAAJyrNl2kAQAAAAAAACsAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0lucHV0L0FycmF5SW5wdXQucGhwMBYAAJKinmAwFgAAbRpRaqQBAAAAAAAAKgAAAHZlbmRvci9zeW1mb255L2NvbnNvbGUvSW5wdXQvQXJndklucHV0LnBocCYvAACSop5gJi8AAIwT/IOkAQAAAAAAADYAAAB2ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL0V2ZW50TGlzdGVuZXIvRXJyb3JMaXN0ZW5lci5waHD0CgAAkqKeYPQKAABlP8PfpAEAAAAAAAAeAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0dsb2IucGhw7Q4AAJKinmDtDgAAmb6ye6QBAAAAAAAANgAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9FeGNlcHRpb24vRXhjZXB0aW9uSW50ZXJmYWNlLnBocCICAACSop5gIgIAANqAZlekAQAAAAAAADkAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvRXhjZXB0aW9uL0FjY2Vzc0RlbmllZEV4Y2VwdGlvbi5waHCrAQAAkqKeYKsBAADKY1fepAEAAAAAAAA1AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL1BhdGhGaWx0ZXJJdGVyYXRvci5waHCrBQAAkqKeYKsFAAB9o6wUpAEAAAAAAAA5AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0ZpbGVUeXBlRmlsdGVySXRlcmF0b3IucGhwPgUAAJKinmA+BQAAcMCfWaQBAAAAAAAAOgAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9EYXRlUmFuZ2VGaWx0ZXJJdGVyYXRvci5waHClBQAAkqKeYKUFAAARJDk5pAEAAAAAAAA9AAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL1JlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yLnBocC4SAACSop5gLhIAAPOPc9OkAQAAAAAAADsAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRGVwdGhSYW5nZUZpbHRlckl0ZXJhdG9yLnBocMwEAACSop5gzAQAANsqrB2kAQAAAAAAADcAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvQ3VzdG9tRmlsdGVySXRlcmF0b3IucGhw6QUAAJKinmDpBQAAtd8gDaQBAAAAAAAAPAAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9GaWxlY29udGVudEZpbHRlckl0ZXJhdG9yLnBocKYFAACSop5gpgUAAA5y3H6kAQAAAAAAAEEAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRXhjbHVkZURpcmVjdG9yeUZpbHRlckl0ZXJhdG9yLnBocJYJAACSop5glgkAAHTw6KSkAQAAAAAAADkAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvRmlsZW5hbWVGaWx0ZXJJdGVyYXRvci5waHCVBAAAkqKeYJUEAAAMy3DApAEAAAAAAAAzAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL1NvcnRhYmxlSXRlcmF0b3IucGhwQAoAAJKinmBACgAAzlsMAKQBAAAAAAAAPQAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9JdGVyYXRvci9NdWx0aXBsZVBjcmVGaWx0ZXJJdGVyYXRvci5waHB6DAAAkqKeYHoMAAA2qeympAEAAAAAAAAxAAAAdmVuZG9yL3N5bWZvbnkvZmluZGVyL0l0ZXJhdG9yL0ZpbHRlckl0ZXJhdG9yLnBocMkGAACSop5gyQYAAFZBU3OkAQAAAAAAADoAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvSXRlcmF0b3IvU2l6ZVJhbmdlRmlsdGVySXRlcmF0b3IucGhwggUAAJKinmCCBQAAHThLtaQBAAAAAAAALwAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9Db21wYXJhdG9yL0NvbXBhcmF0b3IucGhwAwgAAJKinmADCAAAfjSQ2KQBAAAAAAAANQAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9Db21wYXJhdG9yL051bWJlckNvbXBhcmF0b3IucGhwEwoAAJKinmATCgAA2NkHuqQBAAAAAAAAMwAAAHZlbmRvci9zeW1mb255L2ZpbmRlci9Db21wYXJhdG9yL0RhdGVDb21wYXJhdG9yLnBocJ4FAACSop5gngUAAIq8R8OkAQAAAAAAACAAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvRmluZGVyLnBocHtOAACSop5ge04AAJlJ7u2kAQAAAAAAACUAAAB2ZW5kb3Ivc3ltZm9ueS9maW5kZXIvU3BsRmlsZUluZm8ucGhwVwcAAJKinmBXBwAAIXRWYqQBAAAAAAAALQAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9Qcm9taXNlSW50ZXJmYWNlLnBocPgGAACSop5g+AYAAF6pDcekAQAAAAAAACwAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvUmVqZWN0ZWRQcm9taXNlLnBocKEIAACSop5goQgAAJ1NrjCkAQAAAAAAADgAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvVW5oYW5kbGVkUmVqZWN0aW9uRXhjZXB0aW9uLnBocGUCAACSop5gZQIAAGc0H9+kAQAAAAAAACgAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvTGF6eVByb21pc2UucGhwzwYAAJKinmDPBgAAlE2FSqQBAAAAAAAALgAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9mdW5jdGlvbnNfaW5jbHVkZS5waHBhAAAAkqKeYGEAAACFfAfipAEAAAAAAAAlAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0RlZmVycmVkLnBocLwFAACSop5gvAUAAAofBcykAQAAAAAAACYAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvZnVuY3Rpb25zLnBocIwvAACSop5gjC8AAApoeuykAQAAAAAAAC4AAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvUHJvbWlzb3JJbnRlcmZhY2UucGhwwwAAAJKinmDDAAAAd7U7AaQBAAAAAAAALQAAAHZlbmRvci9yZWFjdC9wcm9taXNlL3NyYy9GdWxmaWxsZWRQcm9taXNlLnBocF4HAACSop5gXgcAAB4GwXakAQAAAAAAACQAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvUHJvbWlzZS5waHCMIgAAkqKeYIwiAADJ4G0EpAEAAAAAAAA1AAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0V4dGVuZGVkUHJvbWlzZUludGVyZmFjZS5waHB2DQAAkqKeYHYNAACOyUkepAEAAAAAAAA4AAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0NhbmNlbGxhYmxlUHJvbWlzZUludGVyZmFjZS5waHC2AQAAkqKeYLYBAACyXGxipAEAAAAAAAAuAAAAdmVuZG9yL3JlYWN0L3Byb21pc2Uvc3JjL0NhbmNlbGxhdGlvblF1ZXVlLnBocHUEAACSop5gdQQAAJyNpG6kAQAAAAAAADYAAAB2ZW5kb3IvcmVhY3QvcHJvbWlzZS9zcmMvRXhjZXB0aW9uL0xlbmd0aEV4Y2VwdGlvbi5waHBeAAAAkqKeYF4AAAAEP3EEpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9lbnRpdHktY29tbWFuZC5waHDnCQAAkqKeYOcJAADpsyWupAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvVGVybV9NZXRhX0NvbW1hbmQucGhwkxEAAJKinmCTEQAAn0LRc6QBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1RheG9ub215X0NvbW1hbmQucGhwsxwAAJKinmCzHAAArzvsZqQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL05ldHdvcmtfTmFtZXNwYWNlLnBocCoBAACSop5gKgEAAHveZB+kAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Db21tZW50X0NvbW1hbmQucGhwBEIAAJKinmAEQgAAwFwdS6QBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL0NvbW1lbnRfTWV0YV9Db21tYW5kLnBocP0RAACSop5g/REAAENxqPCkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Vc2VyX0NvbW1hbmQucGhwb4kAAJKinmBviQAATyh7QaQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL09wdGlvbl9Db21tYW5kLnBocCw/AACSop5gLD8AAHUaB/qkAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Vc2VyX01ldGFfQ29tbWFuZC5waHC7JAAAkqKeYLskAABSSXxLpAEAAAAAAAA6AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvTWVudV9Mb2NhdGlvbl9Db21tYW5kLnBocLsPAACSop5guw8AAGT7AvGkAQAAAAAAADgAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9TaXRlX09wdGlvbl9Db21tYW5kLnBocIAnAACSop5ggCcAAFdXmfmkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9UZXJtX0NvbW1hbmQucGhwwEsAAJKinmDASwAAHq1HHKQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL01lbnVfSXRlbV9Db21tYW5kLnBocPAzAACSop5g8DMAAH5fq9ekAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Qb3N0X1R5cGVfQ29tbWFuZC5waHDnGAAAkqKeYOcYAADNeptfpAEAAAAAAAA5AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvVXNlcl9TZXNzaW9uX0NvbW1hbmQucGhw5BQAAJKinmDkFAAAzGn9jKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL01lbnVfQ29tbWFuZC5waHAJEgAAkqKeYAkSAAD1xM/NpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvUG9zdF9UZXJtX0NvbW1hbmQucGhwHgIAAJKinmAeAgAAKTeMv6QBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9FbnRpdHkvVXRpbHMucGhwgQEAAJKinmCBAQAAt3njpqQBAAAAAAAAUgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9FbnRpdHkvUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlci5waHAHEAAAkqKeYAcQAADDEUxtpAEAAAAAAABKAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvV1BfQ0xJL0VudGl0eS9Ob25FeGlzdGVudEtleUV4Y2VwdGlvbi5waHDLAQAAkqKeYMsBAADNzLFopAEAAAAAAAA7AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvV1BfQ0xJL0NvbW1hbmRXaXRoTWV0YS5waHA7OQAAkqKeYDs5AAB5gPwMpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvV1BfQ0xJL0NvbW1hbmRXaXRoVGVybXMucGhwZR4AAJKinmBlHgAAKFE+p6QBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1dQX0NMSS9Db21tYW5kV2l0aERCT2JqZWN0LnBocKMTAACSop5goxMAAIMalCOkAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9TaXRlX01ldGFfQ29tbWFuZC5waHCPEQAAkqKeYI8RAADadpStpAEAAAAAAAA5AAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvTmV0d29ya19NZXRhX0NvbW1hbmQucGhwXQEAAJKinmBdAQAA6WsCTqQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvZW50aXR5LWNvbW1hbmQvc3JjL1VzZXJfVGVybV9Db21tYW5kLnBocCYBAACSop5gJgEAABihe2KkAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9Qb3N0X01ldGFfQ29tbWFuZC5waHCTEQAAkqKeYJMRAADX/9T7pAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvUG9zdF9Db21tYW5kLnBocEptAACSop5gSm0AANVWyOOkAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9TaXRlX0NvbW1hbmQucGhwj1UAAJKinmCPVQAATayWuKQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvZXh0ZW5zaW9uLWNvbW1hbmQucGhwKQMAAJKinmApAwAAsAMYE6QBAAAAAAAAQQAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1RoZW1lX0F1dG9VcGRhdGVzX0NvbW1hbmQucGhwBhwAAJKinmAGHAAAKGMGeKQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1RoZW1lX0NvbW1hbmQucGhw1F8AAJKinmDUXwAAq7vqSaQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1BsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kLnBocIQbAACSop5ghBsAAA7HJY2kAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9UaGVtZV9Nb2RfQ29tbWFuZC5waHDOFgAAkqKeYM4WAADxe68opAEAAAAAAABIAAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvV1BfQ0xJL0Rlc3RydWN0aXZlUGx1Z2luVXBncmFkZXIucGhwqwEAAJKinmCrAQAAH0mNyaQBAAAAAAAAPgAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1dQX0NMSS9GZXRjaGVycy9QbHVnaW4ucGhwIgMAAJKinmAiAwAAC0bkIKQBAAAAAAAAPQAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjL1dQX0NMSS9GZXRjaGVycy9UaGVtZS5waHAMBwAAkqKeYAwHAADY+jOspAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvV1BfQ0xJL0NvbW1hbmRXaXRoVXBncmFkZS5waHB0WwAAkqKeYHRbAACyjuZQpAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvV1BfQ0xJL1BhcnNlUGx1Z2luTmFtZUlucHV0LnBocIgFAACSop5giAUAAEcwlC2kAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL3NyYy9XUF9DTEkvUGFyc2VUaGVtZU5hbWVJbnB1dC5waHBoEwAAkqKeYGgTAAD0R4AWpAEAAAAAAABHAAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvV1BfQ0xJL0Rlc3RydWN0aXZlVGhlbWVVcGdyYWRlci5waHCoAQAAkqKeYKgBAABTjP0PpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMvUGx1Z2luX0NvbW1hbmQucGhw4ZIAAJKinmDhkgAAorHSEqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvaW1wb3J0LWNvbW1hbmQvaW1wb3J0LWNvbW1hbmQucGhwDwEAAJKinmAPAQAAhxPkyqQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvaW1wb3J0LWNvbW1hbmQvc3JjL0ltcG9ydF9Db21tYW5kLnBocBA5AACSop5gEDkAAIURjAOkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kL3NlcnZlci1jb21tYW5kLnBocPYBAACSop5g9gEAAKorwR2kAQAAAAAAACcAAAB2ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kL3JvdXRlci5waHBODgAAkqKeYE4OAAA3ph39pAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9zZXJ2ZXItY29tbWFuZC9zcmMvU2VydmVyX0NvbW1hbmQucGhwLAwAAJKinmAsDAAAmp02XKQBAAAAAAAAJwAAAHZlbmRvci93cC1jbGkvZGItY29tbWFuZC9kYi1jb21tYW5kLnBocPsAAACSop5g+wAAAMz97WukAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL2RiLWNvbW1hbmQvc3JjL0RCX0NvbW1hbmQucGhwwvQAAJKinmDC9AAAhN/9NKQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyL3NyYy9XUENvbmZpZ1RyYW5zZm9ybWVyLnBocPQpAACSop5g9CkAAJavJdekAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL21lZGlhLWNvbW1hbmQvbWVkaWEtY29tbWFuZC5waHCSAgAAkqKeYJICAAA2iFiTpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9tZWRpYS1jb21tYW5kL3NyYy9NZWRpYV9Db21tYW5kLnBocOCdAACSop5g4J0AAH+nPC+kAQAAAAAAAEMAAAB2ZW5kb3Ivd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQucGhwTAEAAJKinmBMAQAAOcx2NKQBAAAAAAAARQAAAHZlbmRvci93cC1jbGkvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kL3NyYy9NYWludGVuYW5jZU1vZGVDb21tYW5kLnBocDcNAACSop5gNw0AADAyPUCkAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvZW1iZWQtY29tbWFuZC5waHB4AgAAkqKeYHgCAAAjvRjOpAEAAAAAAAA0AAAAdmVuZG9yL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYy9Qcm92aWRlcl9Db21tYW5kLnBocLkVAACSop5guRUAAH10NJSkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjL0hhbmRsZXJfQ29tbWFuZC5waHAXCAAAkqKeYBcIAABgxlfnpAEAAAAAAAAqAAAAdmVuZG9yL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYy9vRW1iZWQucGhw9wUAAJKinmD3BQAA6HD/PqQBAAAAAAAANAAAAHZlbmRvci93cC1jbGkvZW1iZWQtY29tbWFuZC9zcmMvRW1iZWRzX05hbWVzcGFjZS5waHDYAAAAkqKeYNgAAADw/HGlpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9lbWJlZC1jb21tYW5kL3NyYy9GZXRjaF9Db21tYW5kLnBocMkkAACSop5gySQAAJuJG/6kAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjL0NhY2hlX0NvbW1hbmQucGhwmhMAAJKinmCaEwAAbfNQ+KQBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAbBAAAkqKeYBsEAAC4ArE6pAEAAAAAAAApAAAAdmVuZG9yL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvU3B5Yy5waHDLAwAAkqKeYMsDAACWqtF4pAEAAAAAAAAuAAAAdmVuZG9yL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvcGhwNC81dG80LnBocNgCAACSop5g2AIAAHVTXSmkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9waHA0L3NweWMucGhwNEl1AACSop5gSXUAAP0tLgWkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9waHA0L3Rlc3QucGhwNIcRAACSop5ghxEAACBmM1CkAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9zcmMvU3B5Yy5waHDLhQAAkqKeYMuFAADoAH7jpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvaTE4bi1jb21tYW5kLnBocCQCAACSop5gJAIAABXwE1SkAQAAAAAAADgAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvSXRlcmFibGVDb2RlRXh0cmFjdG9yLnBocLghAACSop5guCEAAHRvvvGkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvSmVkR2VuZXJhdG9yLnBocG0IAACSop5gbQgAAKHKkwekAQAAAAAAADIAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvSnNDb2RlRXh0cmFjdG9yLnBocAAHAACSop5gAAcAAC2TS+ekAQAAAAAAADAAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvTWFrZU1vQ29tbWFuZC5waHBGCAAAkqKeYEYIAAC68b4mpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL0NvbW1hbmROYW1lc3BhY2UucGhwlgEAAJKinmCWAQAA9WxomqQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9NYWtlUG90Q29tbWFuZC5waHBcdQAAkqKeYFx1AABlctfTpAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjL1BocEZ1bmN0aW9uc1NjYW5uZXIucGhwywgAAJKinmDLCAAAwkkXlKQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9NYXBDb2RlRXh0cmFjdG9yLnBocIEGAACSop5ggQYAAKhjumSkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvSnNGdW5jdGlvbnNTY2FubmVyLnBocO4qAACSop5g7ioAAHoEnCOkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvUG90R2VuZXJhdG9yLnBocFEOAACSop5gUQ4AAIMOBuykAQAAAAAAADEAAAB2ZW5kb3Ivd3AtY2xpL2kxOG4tY29tbWFuZC9zcmMvQmxvY2tFeHRyYWN0b3IucGhwngYAAJKinmCeBgAAjB0Y0aQBAAAAAAAAMgAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9NYWtlSnNvbkNvbW1hbmQucGhwBBwAAJKinmAEHAAA+Kb7BqQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvaTE4bi1jb21tYW5kL3NyYy9QaHBDb2RlRXh0cmFjdG9yLnBocJ0HAACSop5gnQcAAGeuiJSkAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL3JvbGUtY29tbWFuZC9yb2xlLWNvbW1hbmQucGhwOwEAAJKinmA7AQAAYfB2B6QBAAAAAAAANwAAAHZlbmRvci93cC1jbGkvcm9sZS1jb21tYW5kL3NyYy9DYXBhYmlsaXRpZXNfQ29tbWFuZC5waHAzFQAAkqKeYDMVAAAP5RH3pAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9yb2xlLWNvbW1hbmQvc3JjL1JvbGVfQ29tbWFuZC5waHByKQAAkqKeYHIpAACAtS/UpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9yZXdyaXRlLWNvbW1hbmQvcmV3cml0ZS1jb21tYW5kLnBocBQBAACSop5gFAEAAB0XS6ukAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3Jld3JpdGUtY29tbWFuZC9zcmMvUmV3cml0ZV9Db21tYW5kLnBocB8wAACSop5gHzAAAOY7Fr+kAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvc2NhZmZvbGQtY29tbWFuZC5waHAZAQAAkqKeYBkBAADmtIMPpAEAAAAAAAA7AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9ibG9jay1waHAubXVzdGFjaGUuBwAAkqKeYC4HAABGHF6CpAEAAAAAAAA3AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3NyYy9TY2FmZm9sZF9Db21tYW5kLnBocKCWAACSop5goJYAAEUEkEGkAQAAAAAAACoAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL2Z1bmN0aW9ucy5waHBwBQAAkqKeYHAFAAAU6JEbpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9leHBvcnQtY29tbWFuZC5waHAPAQAAkqKeYA8BAADf/zJkpAEAAAAAAAA5AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfUG9zdF9JRHNfSXRlcmF0b3IucGhwSQYAAJKinmBJBgAAp9pDFqQBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9GaWxlX1dyaXRlci5waHA+AwAAkqKeYD4DAABSfVSbpAEAAAAAAAA4AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X0V4Y2VwdGlvbi5waHA+AAAAkqKeYD4AAABNHMsApAEAAAAAAAA0AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1F1ZXJ5LnBocDY0AACSop5gNjQAAN4HCZmkAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9XUF9FeHBvcnRfVGVybV9FeGNlcHRpb24ucGhwQwAAAJKinmBDAAAA6h8Cx6QBAAAAAAAANAAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX01hcF9JdGVyYXRvci5waHBAAQAAkqKeYEABAADRsRGQpAEAAAAAAAA3AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1JldHVybmVyLnBocEIEAACSop5gQgQAALPX102kAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYy9FeHBvcnRfQ29tbWFuZC5waHAPMwAAkqKeYA8zAAAQzCYzpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1dYUl9Gb3JtYXR0ZXIucGhwuCYAAJKinmC4JgAARoyYjaQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9PeHltZWwucGhwjgIAAJKinmCOAgAAaCitlaQBAAAAAAAAQQAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9TcGxpdF9GaWxlc19Xcml0ZXIucGhwLQsAAJKinmAtCwAADiVAaaQBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0l0ZXJhdG9yX0V4Y2VwdGlvbi5waHA5AAAAkqKeYDkAAACmfwd3pAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMvV1BfRXhwb3J0X1hNTF9PdmVyX0hUVFAucGhwYQUAAJKinmBhBQAAXYCev6QBAAAAAAAAOgAAAHZlbmRvci93cC1jbGkvZXhwb3J0LWNvbW1hbmQvc3JjL1dQX0V4cG9ydF9CYXNlX1dyaXRlci5waHCsAQAAkqKeYKwBAADHtGL3pAEAAAAAAAAkAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL3Rlc3QucGhwaQIAAJKinmBpAgAAM02ZFaQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvUmVuZGVyZXIucGhwTwIAAJKinmBPAgAAm2Mi06QBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvTWFya2Rvd24ucGhwqAUAAJKinmCoBQAAjFTpraQBAAAAAAAAMgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL3RyZWUvQXNjaWkucGhweAMAAJKinmB4AwAAOY/V9qQBAAAAAAAALQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL1RhYmxlLnBocKEZAACSop5goRkAAHThiCqkAQAAAAAAADAAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9Qcm9ncmVzcy5waHDJDQAAkqKeYMkNAAC0DmGqpAEAAAAAAAA0AAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvcHJvZ3Jlc3MvQmFyLnBocLYJAACSop5gtgkAAG6gKE+kAQAAAAAAADoAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9hcmd1bWVudHMvQXJndW1lbnQucGhwIAsAAJKinmAgCwAAPcbp6aQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2FyZ3VtZW50cy9IZWxwU2NyZWVuLnBocKAKAACSop5goAoAAP1PJHakAQAAAAAAADcAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9hcmd1bWVudHMvTGV4ZXIucGhwXgkAAJKinmBeCQAA/EfYB6QBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL2FyZ3VtZW50cy9JbnZhbGlkQXJndW1lbnRzLnBocBoEAACSop5gGgQAALX62COkAQAAAAAAACwAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9UcmVlLnBocLMFAACSop5gswUAAB7u/UCkAQAAAAAAAC4AAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9Db2xvcnMucGhwayEAAJKinmBrIQAAHXk2KaQBAAAAAAAALgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL05vdGlmeS5waHDNEQAAkqKeYM0RAAAsp6YUpAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvY2xpLnBocMdAAACSop5gx0AAAP1+etekAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS90YWJsZS9UYWJ1bGFyLnBocLICAACSop5gsgIAAPmIoWykAQAAAAAAADYAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS90YWJsZS9SZW5kZXJlci5waHBHBQAAkqKeYEcFAABZht+SpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvdGFibGUvQXNjaWkucGhwCxsAAJKinmALGwAAnUAlPaQBAAAAAAAANgAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL25vdGlmeS9TcGlubmVyLnBocAcFAACSop5gBwUAADj7dQekAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9ub3RpZnkvRG90cy5waHBkBwAAkqKeYGQHAADbd+F6pAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvU3RyZWFtcy5waHCjIgAAkqKeYKMiAAAryWYJpAEAAAAAAAAtAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvU2hlbGwucGhw5AwAAJKinmDkDAAAh23Fu6QBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL01lbW9pemUucGhw+wMAAJKinmD7AwAA3gH0DqQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpL0FyZ3VtZW50cy5waHAGLwAAkqKeYAYvAADgLDd7pAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYi9jbGkvdW5pY29kZS9yZWdleC5waHBiFgAAkqKeYGIWAADJtjnNpAEAAAAAAAAsAAAAdmVuZG9yL3dwLWNsaS9waHAtY2xpLXRvb2xzL2h0dHAtY29uc29sZS5waHAfBwAAkqKeYB8HAADnkcg+pAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS9jcm9uLWNvbW1hbmQvY3Jvbi1jb21tYW5kLnBocIEBAACSop5ggQEAAAGysi6kAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL2Nyb24tY29tbWFuZC9zcmMvQ3Jvbl9FdmVudF9Db21tYW5kLnBocN85AACSop5g3zkAAKvFu4mkAQAAAAAAAC8AAAB2ZW5kb3Ivd3AtY2xpL2Nyb24tY29tbWFuZC9zcmMvQ3Jvbl9Db21tYW5kLnBocAgMAACSop5gCAwAAIfjb42kAQAAAAAAADgAAAB2ZW5kb3Ivd3AtY2xpL2Nyb24tY29tbWFuZC9zcmMvQ3Jvbl9TY2hlZHVsZV9Db21tYW5kLnBocGkMAACSop5gaQwAAJ+/QH+kAQAAAAAAACsAAAB2ZW5kb3Ivd3AtY2xpL2NvcmUtY29tbWFuZC9jb3JlLWNvbW1hbmQucGhwBQEAAJKinmAFAQAAqTqIr6QBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvY29yZS1jb21tYW5kL3NyYy9Db3JlX0NvbW1hbmQucGhwnq8AAJKinmCerwAAOel0CKQBAAAAAAAAOwAAAHZlbmRvci93cC1jbGkvY29yZS1jb21tYW5kL3NyYy9XUF9DTEkvQ29yZS9Db3JlVXBncmFkZXIucGhwvBYAAJKinmC8FgAAMv9HKKQBAAAAAAAASQAAAHZlbmRvci93cC1jbGkvY29yZS1jb21tYW5kL3NyYy9XUF9DTEkvQ29yZS9Ob25EZXN0cnVjdGl2ZUNvcmVVcGdyYWRlci5waHCfAQAAkqKeYJ8BAACQIXp+pAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvdXRpbHMvY29udHJpYi1saXN0LnBocMMbAACSop5gwxsAAB1URTqkAQAAAAAAACMAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS91dGlscy9maW5kLXBocFwBAACSop5gXAEAAJZchimkAQAAAAAAAEAAAAB2ZW5kb3Ivd3AtY2xpL3dwLWNsaS91dGlscy9nZXQtcGFja2FnZS1yZXF1aXJlLWZyb20tY29tcG9zZXIucGhw5AEAAJKinmDkAQAAEOafDKQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZC9zdXBlci1hZG1pbi1jb21tYW5kLnBocL4BAACSop5gvgEAAJwY/4ikAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL3N1cGVyLWFkbWluLWNvbW1hbmQvc3JjL1N1cGVyX0FkbWluX0NvbW1hbmQucGhwOBcAAJKinmA4FwAAxSrTfKQBAAAAAAAAMQAAAHZlbmRvci93cC1jbGkvcGFja2FnZS1jb21tYW5kL3BhY2thZ2UtY29tbWFuZC5waHA6AQAAkqKeYDoBAABghvU3pAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQvc3JjL1dQX0NMSS9Kc29uTWFuaXB1bGF0b3IucGhwCFMAAJKinmAIUwAAz6KH6KQBAAAAAAAANQAAAHZlbmRvci93cC1jbGkvcGFja2FnZS1jb21tYW5kL3NyYy9QYWNrYWdlX0NvbW1hbmQucGhwqsIAAJKinmCqwgAATisG1KQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC9zZWFyY2gtcmVwbGFjZS1jb21tYW5kLnBocDcBAACSop5gNwEAAK7U5gGkAQAAAAAAAEMAAAB2ZW5kb3Ivd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc3JjL1NlYXJjaF9SZXBsYWNlX0NvbW1hbmQucGhwxpIAAJKinmDGkgAAHp3np6QBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC9zcmMvV1BfQ0xJL1NlYXJjaFJlcGxhY2VyLnBocFIXAACSop5gUhcAABMkZaykAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL2NhY2hlLWNvbW1hbmQvY2FjaGUtY29tbWFuZC5waHBDAQAAkqKeYEMBAAAmJ2UVpAEAAAAAAAA1AAAAdmVuZG9yL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYy9UcmFuc2llbnRfQ29tbWFuZC5waHD2RAAAkqKeYPZEAAAFSm+GpAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYy9DYWNoZV9Db21tYW5kLnBocDEfAACSop5gMR8AAMk1vsWkAQAAAAAAAC0AAAB2ZW5kb3Ivd3AtY2xpL3NoZWxsLWNvbW1hbmQvc2hlbGwtY29tbWFuZC5waHAKAQAAkqKeYAoBAAAB1dm3pAEAAAAAAAAxAAAAdmVuZG9yL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NyYy9TaGVsbF9Db21tYW5kLnBocFUFAACSop5gVQUAAMNuHiqkAQAAAAAAADUAAAB2ZW5kb3Ivd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjL1dQX0NMSS9TaGVsbC9SRVBMLnBocNoMAACSop5g2gwAABNEBGKkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvY2hlY2tzdW0tY29tbWFuZC5waHDwAQAAkqKeYPABAABbet9zpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYy9QbHVnaW5fQ29tbWFuZF9OYW1lc3BhY2UucGhwvQAAAJKinmC9AAAApjoFZqQBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvQ2hlY2tzdW1fQmFzZV9Db21tYW5kLnBocAUJAACSop5gBQkAAE4ZirqkAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvc3JjL0NvcmVfQ29tbWFuZF9OYW1lc3BhY2UucGhwwAAAAJKinmDAAAAAe9Lq8aQBAAAAAAAAPgAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvQ2hlY2tzdW1fUGx1Z2luX0NvbW1hbmQucGhwMSEAAJKinmAxIQAAM2cyMaQBAAAAAAAARwAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvV1BfQ0xJL0ZldGNoZXJzL1VuZmlsdGVyZWRQbHVnaW4ucGhwOgMAAJKinmA6AwAAPKcCZ6QBAAAAAAAAPAAAAHZlbmRvci93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMvQ2hlY2tzdW1fQ29yZV9Db21tYW5kLnBocNAXAACSop5g0BcAAMkhTROkAQAAAAAAADMAAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvbGFuZ3VhZ2UtY29tbWFuZC5waHAxBAAAkqKeYDEEAACeN8hnpAEAAAAAAAA+AAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9QbHVnaW5fTGFuZ3VhZ2VfQ29tbWFuZC5waHARMwAAkqKeYBEzAACFQk26pAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9TaXRlX1N3aXRjaF9MYW5ndWFnZV9Db21tYW5kLnBocIIDAACSop5gggMAAIcVMX+kAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjL1RoZW1lX0xhbmd1YWdlX0NvbW1hbmQucGhwXTEAAJKinmBdMQAA7dv2a6QBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvbGFuZ3VhZ2UtY29tbWFuZC9zcmMvTGFuZ3VhZ2VfTmFtZXNwYWNlLnBocOECAACSop5g4QIAAL8pfIOkAQAAAAAAADwAAAB2ZW5kb3Ivd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjL0NvcmVfTGFuZ3VhZ2VfQ29tbWFuZC5waHCbJgAAkqKeYJsmAAApywnKpAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9XUF9DTEkvQ29tbWFuZFdpdGhUcmFuc2xhdGlvbi5waHDdIAAAkqKeYN0gAAAskhbZpAEAAAAAAABCAAAAdmVuZG9yL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL3NyYy9XUF9DTEkvTGFuZ3VhZ2VQYWNrVXBncmFkZXIucGhw8Q0AAJKinmDxDQAAi26wFqQBAAAAAAAAKwAAAHZlbmRvci93cC1jbGkvZXZhbC1jb21tYW5kL2V2YWwtY29tbWFuZC5waHA9AQAAkqKeYD0BAAC2h0FrpAEAAAAAAAAvAAAAdmVuZG9yL3dwLWNsaS9ldmFsLWNvbW1hbmQvc3JjL0V2YWxfQ29tbWFuZC5waHBdAwAAkqKeYF0DAAAnpqyTpAEAAAAAAAAzAAAAdmVuZG9yL3dwLWNsaS9ldmFsLWNvbW1hbmQvc3JjL0V2YWxGaWxlX0NvbW1hbmQucGhwKwcAAJKinmArBwAAN6eJPqQBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvd2lkZ2V0LWNvbW1hbmQvd2lkZ2V0LWNvbW1hbmQucGhwRAEAAJKinmBEAQAA3e4Mr6QBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvd2lkZ2V0LWNvbW1hbmQvc3JjL1dpZGdldF9Db21tYW5kLnBocJVGAACSop5glUYAACpXBW6kAQAAAAAAADQAAAB2ZW5kb3Ivd3AtY2xpL3dpZGdldC1jb21tYW5kL3NyYy9TaWRlYmFyX0NvbW1hbmQucGhw0gYAAJKinmDSBgAAgWSzg6QBAAAAAAAALwAAAHZlbmRvci93cC1jbGkvY29uZmlnLWNvbW1hbmQvY29uZmlnLWNvbW1hbmQucGhwDwEAAJKinmAPAQAAN8zIUaQBAAAAAAAAMwAAAHZlbmRvci93cC1jbGkvY29uZmlnLWNvbW1hbmQvc3JjL0NvbmZpZ19Db21tYW5kLnBocKVqAACSop5gpWoAACxquPikAQAAAAAAABsAAAB2ZW5kb3IvbmIvb3h5bWVsL094eW1lbC5waHApFwAAkqKeYCkXAADoKHLVpAEAAAAAAAAfAAAAdmVuZG9yL25iL294eW1lbC9PeHltZWxUZXN0LnBocIITAACSop5gghMAAEJMqVakAQAAAAAAACkAAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0Fic3RyYWN0TG9nZ2VyLnBocCAMAACSop5gIAwAAEec6+KkAQAAAAAAAC8AAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0xvZ2dlckF3YXJlSW50ZXJmYWNlLnBocCkBAACSop5gKQEAAMhqDLGkAQAAAAAAACMAAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0xvZ0xldmVsLnBocFABAACSop5gUAEAAJ3yuhSkAQAAAAAAACsAAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0xvZ2dlckF3YXJlVHJhaXQucGhwkgEAAJKinmCSAQAAGVEnr6QBAAAAAAAAMwAAAHZlbmRvci9wc3IvbG9nL1Bzci9Mb2cvSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uLnBocGAAAACSop5gYAAAACCIWDGkAQAAAAAAACYAAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0xvZ2dlclRyYWl0LnBocFcNAACSop5gVw0AALlX5WqkAQAAAAAAACoAAAB2ZW5kb3IvcHNyL2xvZy9Qc3IvTG9nL0xvZ2dlckludGVyZmFjZS5waHAqDAAAkqKeYCoMAAAxYiFxpAEAAAAAAAAlAAAAdmVuZG9yL3Bzci9sb2cvUHNyL0xvZy9OdWxsTG9nZ2VyLnBocMMCAACSop5gwwIAANHi1UmkAQAAAAAAAEAAAAB2ZW5kb3Ivc2VsZC9qc29ubGludC9zcmMvU2VsZC9Kc29uTGludC9EdXBsaWNhdGVLZXlFeGNlcHRpb24ucGhwUgQAAJKinmBSBAAA66N5I6QBAAAAAAAAOwAAAHZlbmRvci9zZWxkL2pzb25saW50L3NyYy9TZWxkL0pzb25MaW50L1BhcnNpbmdFeGNlcHRpb24ucGhw1gMAAJKinmDWAwAA1DunFqQBAAAAAAAANQAAAHZlbmRvci9zZWxkL2pzb25saW50L3NyYy9TZWxkL0pzb25MaW50L0pzb25QYXJzZXIucGhwKFEAAJKinmAoUQAAGQjLe6QBAAAAAAAANAAAAHZlbmRvci9zZWxkL2pzb25saW50L3NyYy9TZWxkL0pzb25MaW50L1VuZGVmaW5lZC5waHAcAQAAkqKeYBwBAACCZ/AXpAEAAAAAAAAwAAAAdmVuZG9yL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQvTGV4ZXIucGhwBxkAAJKinmAHGQAAYH8Vn6QBAAAAAAAAKQAAAHZlbmRvci9zZWxkL3BoYXItdXRpbHMvc3JjL1RpbWVzdGFtcHMucGhw8RUAAJKinmDxFQAAj4GW4qQBAAAAAAAAJQAAAHZlbmRvci9zZWxkL3BoYXItdXRpbHMvc3JjL0xpbnRlci5waHCMDAAAkqKeYIwMAADUXWthpAEAAAAAAABGAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRW50aXR5L0pzb25Qb2ludGVyLnBocD4NAACSop5gPg0AAJAdVwSkAQAAAAAAAD0AAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9WYWxpZGF0b3IucGhw7goAAJKinmDuCgAAOJSb66QBAAAAAAAAOwAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1JmYzMzMzkucGhwdgMAAJKinmB2AwAAeMEkkKQBAAAAAAAASgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1NjaGVtYVN0b3JhZ2VJbnRlcmZhY2UucGhwIgMAAJKinmAiAwAAeAEmN6QBAAAAAAAARwAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL0ZhY3RvcnkucGhwRhYAAJKinmBGFgAAOjDAL6QBAAAAAAAAVAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL0NvbGxlY3Rpb25Db25zdHJhaW50LnBocMYTAACSop5gxhMAAE6I6OakAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9PYmplY3RDb25zdHJhaW50LnBocI8fAACSop5gjx8AAEZnY4SkAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9Gb3JtYXRDb25zdHJhaW50LnBocJUiAACSop5glSIAAM2lI0ukAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9OdW1iZXJDb25zdHJhaW50LnBocIcNAACSop5ghw0AALHpOXykAQAAAAAAAFAAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9TdHJpbmdDb25zdHJhaW50LnBocMYHAACSop5gxgcAAH66yEekAQAAAAAAAE4AAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9Db25zdHJhaW50cy9CYXNlQ29uc3RyYWludC5waHAlDwAAkqKeYCUPAACS3TKjpAEAAAAAAABTAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvQ29uc3RyYWludEludGVyZmFjZS5waHAdBgAAkqKeYB0GAAB0sWXkpAEAAAAAAABTAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvVW5kZWZpbmVkQ29uc3RyYWludC5waHCxPgAAkqKeYLE+AAAUfcjBpAEAAAAAAABOAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvVHlwZUNvbnN0cmFpbnQucGhwJh8AAJKinmAmHwAA2YwRXaQBAAAAAAAAXAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL1R5cGVDaGVjay9UeXBlQ2hlY2tJbnRlcmZhY2UucGhwoQEAAJKinmChAQAAYz6wz6QBAAAAAAAAWQAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL1R5cGVDaGVjay9TdHJpY3RUeXBlQ2hlY2sucGhwKwMAAJKinmArAwAA+7JR3KQBAAAAAAAAWAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL1R5cGVDaGVjay9Mb29zZVR5cGVDaGVjay5waHAWBgAAkqKeYBYGAAC5CvzApAEAAAAAAABOAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvQ29uc3RyYWludHMvRW51bUNvbnN0cmFpbnQucGhwcQYAAJKinmBxBgAAxWDIIKQBAAAAAAAAUAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL1NjaGVtYUNvbnN0cmFpbnQucGhwzw4AAJKinmDPDgAAwmZLC6QBAAAAAAAASgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0NvbnN0cmFpbnRzL0NvbnN0cmFpbnQucGhwWBkAAJKinmBYGQAAEQ8Dv6QBAAAAAAAAXgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9VbnJlc29sdmFibGVKc29uUG9pbnRlckV4Y2VwdGlvbi5waHCKAQAAkqKeYIoBAAAuum1ppAEAAAAAAABTAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0pzb25EZWNvZGluZ0V4Y2VwdGlvbi5waHDbBAAAkqKeYNsEAADZoxa9pAEAAAAAAABRAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL1ZhbGlkYXRpb25FeGNlcHRpb24ucGhwGQEAAJKinmAZAQAAReVCKqQBAAAAAAAAUgAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9VcmlSZXNvbHZlckV4Y2VwdGlvbi5waHBKAQAAkqKeYEoBAADv8AYtpAEAAAAAAABWAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbi5waHB5AQAAkqKeYHkBAACAV86WpAEAAAAAAABXAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24ucGhwVAEAAJKinmBUAQAA8NgdOqQBAAAAAAAAVAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9JbnZhbGlkQ29uZmlnRXhjZXB0aW9uLnBocFEBAACSop5gUQEAAADWSu+kAQAAAAAAAFQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vSW52YWxpZFNjaGVtYUV4Y2VwdGlvbi5waHBOAQAAkqKeYE4BAACPr92gpAEAAAAAAABOAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvRXhjZXB0aW9uL1J1bnRpbWVFeGNlcHRpb24ucGhwYQEAAJKinmBhAQAAYNoZl6QBAAAAAAAAUAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9FeGNlcHRpb25JbnRlcmZhY2UucGhwSQAAAJKinmBJAAAAJXwZsKQBAAAAAAAAXQAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL0V4Y2VwdGlvbi9JbnZhbGlkU2NoZW1hTWVkaWFUeXBlRXhjZXB0aW9uLnBocFcBAACSop5gVwEAACUqKdakAQAAAAAAAFcAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9FeGNlcHRpb24vSW52YWxpZFNvdXJjZVVyaUV4Y2VwdGlvbi5waHBcAQAAkqKeYFwBAACqGWlSpAEAAAAAAABLAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvSXRlcmF0b3IvT2JqZWN0SXRlcmF0b3IucGhw5woAAJKinmDnCgAASLipf6QBAAAAAAAASQAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1VyaVJldHJpZXZlckludGVyZmFjZS5waHAFAgAAkqKeYAUCAAA11HxbpAEAAAAAAABIAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpUmVzb2x2ZXJJbnRlcmZhY2UucGhwEgIAAJKinmASAgAAScvQ0aQBAAAAAAAAQQAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1NjaGVtYVN0b3JhZ2UucGhwKxUAAJKinmArFQAAoZ4YX6QBAAAAAAAAQwAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1VyaS9VcmlSZXNvbHZlci5waHA7EgAAkqKeYDsSAAAW88fkpAEAAAAAAABSAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpL1JldHJpZXZlcnMvUHJlZGVmaW5lZEFycmF5LnBocBQFAACSop5gFAUAAB8wFeGkAQAAAAAAAFQAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvUmV0cmlldmVycy9BYnN0cmFjdFJldHJpZXZlci5waHByAgAAkqKeYHICAACWivpNpAEAAAAAAABHAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpL1JldHJpZXZlcnMvQ3VybC5waHBvCAAAkqKeYG8IAACGbhMFpAEAAAAAAABYAAAAdmVuZG9yL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEvVXJpL1JldHJpZXZlcnMvVXJpUmV0cmlldmVySW50ZXJmYWNlLnBocOoCAACSop5g6gIAAD/JckCkAQAAAAAAAFIAAAB2ZW5kb3IvanVzdGlucmFpbmJvdy9qc29uLXNjaGVtYS9zcmMvSnNvblNjaGVtYS9VcmkvUmV0cmlldmVycy9GaWxlR2V0Q29udGVudHMucGhwagoAAJKinmBqCgAAW314I6QBAAAAAAAARAAAAHZlbmRvci9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hL1VyaS9VcmlSZXRyaWV2ZXIucGhwuiQAAJKinmC6JAAAWMtosaQBAAAAAAAAKQAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvTGFuZ3VhZ2UucGhwvT8AAJKinmC9PwAARulMmqQBAAAAAAAAKQAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvQ2xkckRhdGEucGhwJzYAAJKinmAnNgAA6zgMjaQBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvRXhwb3J0ZXIvSHRtbC5waHAQCgAAkqKeYBAKAABLkeUvpAEAAAAAAAAtAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9QaHAucGhwGggAAJKinmAaCAAA1K1F7KQBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvRXhwb3J0ZXIvRG9jcy5waHB5BwAAkqKeYHkHAACUWlXEpAEAAAAAAAAsAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9Qby5waHC6AwAAkqKeYLoDAABB//znpAEAAAAAAAAyAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9FeHBvcnRlci5waHDKEAAAkqKeYMoQAABotDMWpAEAAAAAAAA0AAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9QcmV0dHlqc29uLnBocEQDAACSop5gRAMAAFYmCoCkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0V4cG9ydGVyL1htbC5waHD9CAAAkqKeYP0IAABlJGW5pAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvbGFuZ3VhZ2VzL3NyYy9FeHBvcnRlci9Kc29uLnBocOAHAACSop5g4AcAAMZu9kekAQAAAAAAACkAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0NhdGVnb3J5LnBocGwQAACSop5gbBAAAJxnNC+kAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjL0Zvcm11bGFDb252ZXJ0ZXIucGhwehsAAJKinmB6GwAAIpj8G6QBAAAAAAAAKwAAAHZlbmRvci9nZXR0ZXh0L2xhbmd1YWdlcy9zcmMvYXV0b2xvYWRlci5waHBaAQAAkqKeYFoBAACOLvNypAEAAAAAAAAyAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVHJhbnNsYXRvckludGVyZmFjZS5waHAlCgAAkqKeYCUKAADN+J2kpAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Ud2lnLnBocDwEAACSop5gPAQAAP/zS/OkAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL1BocENvZGUucGhwPxMAAJKinmA/EwAAwoWQJ6QBAAAAAAAALwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvWGxpZmYucGhwmQsAAJKinmCZCwAAV30b9KQBAAAAAAAALwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvQmxhZGUucGhw+wMAAJKinmD7AwAANQt4F6QBAAAAAAAALAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvUG8ucGhwyRoAAJKinmDJGgAADI4B1KQBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvWWFtbC5waHBdAgAAkqKeYF0CAABq0Y8ipAEAAAAAAABBAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9FeHRyYWN0b3JNdWx0aUludGVyZmFjZS5waHCVAwAAkqKeYJUDAAC5pl2HpAEAAAAAAAA3AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Dc3ZEaWN0aW9uYXJ5LnBocFIEAACSop5gUgQAAFeCR4ekAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL0plZC5waHAeBgAAkqKeYB4GAAB7f2O+pAEAAAAAAAAvAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9WdWVKcy5waHBuNgAAkqKeYG42AACFB5g+pAEAAAAAAAAsAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Nby5waHBtDwAAkqKeYG0PAAAfZahwpAEAAAAAAAA4AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9ZYW1sRGljdGlvbmFyeS5waHBRAgAAkqKeYFECAACVdLdzpAEAAAAAAAAyAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9QaHBBcnJheS5waHBHAwAAkqKeYEcDAACHL0TRpAEAAAAAAAA4AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Kc29uRGljdGlvbmFyeS5waHAoAgAAkqKeYCgCAACyLdEqpAEAAAAAAAAwAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9Kc0NvZGUucGhwKAgAAJKinmAoCAAAOJF2VaQBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvSnNvbi5waHAuAgAAkqKeYC4CAADFdz11pAEAAAAAAAA8AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvRXh0cmFjdG9ycy9FeHRyYWN0b3JJbnRlcmZhY2UucGhwDQMAAJKinmANAwAAcH1Z0KQBAAAAAAAAMwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0V4dHJhY3RvcnMvRXh0cmFjdG9yLnBocIwHAACSop5gjAcAAAt76m6kAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9FeHRyYWN0b3JzL0Nzdi5waHAYBQAAkqKeYBgFAACYbTjCpAEAAAAAAAAwAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2V0dGV4dFRyYW5zbGF0b3IucGhwvg4AAJKinmC+DgAA3ryjfKQBAAAAAAAAKQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1RyYW5zbGF0b3IucGhwpB4AAJKinmCkHgAAA0r0PqQBAAAAAAAAJAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL01lcmdlLnBocEQYAACSop5gRBgAAIdtNlCkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9CYXNlVHJhbnNsYXRvci5waHCmAgAAkqKeYKYCAAAzdvTEpAEAAAAAAAArAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVHJhbnNsYXRpb25zLnBocOVAAACSop5g5UAAAP47mgGkAQAAAAAAACoAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9UcmFuc2xhdGlvbi5waHCUKwAAkqKeYJQrAADP2znipAEAAAAAAAAvAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9YbGlmZi5waHA2EQAAkqKeYDYRAADDvlGmpAEAAAAAAAAsAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Qby5waHAKEAAAkqKeYAoQAACauShTpAEAAAAAAAAuAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9ZYW1sLnBocNoCAACSop5g2gIAANX9tq+kAQAAAAAAADMAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL0dlbmVyYXRvci5waHC8AQAAkqKeYLwBAAAVszMDpAEAAAAAAAA3AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Dc3ZEaWN0aW9uYXJ5LnBocKYDAACSop5gpgMAAENUIBOkAQAAAAAAAC0AAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9HZW5lcmF0b3JzL0plZC5waHBwBwAAkqKeYHAHAACjLGsupAEAAAAAAAAsAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Nby5waHDrEgAAkqKeYOsSAAAwFKnQpAEAAAAAAAA4AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9ZYW1sRGljdGlvbmFyeS5waHDOAgAAkqKeYM4CAABMNaKspAEAAAAAAAAyAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9QaHBBcnJheS5waHCrAwAAkqKeYKsDAACuSNY7pAEAAAAAAAA8AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9HZW5lcmF0b3JJbnRlcmZhY2UucGhwpwIAAJKinmCnAgAAF6MLZ6QBAAAAAAAAOAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvSnNvbkRpY3Rpb25hcnkucGhwPQIAAJKinmA9AgAABdLpe6QBAAAAAAAALgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL0dlbmVyYXRvcnMvSnNvbi5waHBPAgAAkqKeYE8CAABmmCdOpAEAAAAAAAAtAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvR2VuZXJhdG9ycy9Dc3YucGhwhwUAAJKinmCHBQAAkeqLe6QBAAAAAAAAMgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL1BhcnNlZENvbW1lbnQucGhwXAwAAJKinmBcDAAAi9y6Q6QBAAAAAAAAOAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL1BocEZ1bmN0aW9uc1NjYW5uZXIucGhw/hYAAJKinmD+FgAAwqltLKQBAAAAAAAANwAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0pzRnVuY3Rpb25zU2Nhbm5lci5waHDqJAAAkqKeYOokAAAoje1kpAEAAAAAAAAzAAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvUGFyc2VkRnVuY3Rpb24ucGhwcQ4AAJKinmBxDgAAQolXY6QBAAAAAAAAOgAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0hlYWRlcnNHZW5lcmF0b3JUcmFpdC5waHA3AgAAkqKeYDcCAAA2w4lHpAEAAAAAAAA/AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQucGhwvAwAAJKinmC8DAAAxGkkYaQBAAAAAAAANAAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0RpY3Rpb25hcnlUcmFpdC5waHDuBQAAkqKeYO4FAADYfyePpAEAAAAAAAA6AAAAdmVuZG9yL2dldHRleHQvZ2V0dGV4dC9zcmMvVXRpbHMvSGVhZGVyc0V4dHJhY3RvclRyYWl0LnBocH4GAACSop5gfgYAAP29w9CkAQAAAAAAADEAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9VdGlscy9TdHJpbmdSZWFkZXIucGhwswMAAJKinmCzAwAAUI31jaQBAAAAAAAANQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0Z1bmN0aW9uc1NjYW5uZXIucGhwMhMAAJKinmAyEwAAPG0LeKQBAAAAAAAALQAAAHZlbmRvci9nZXR0ZXh0L2dldHRleHQvc3JjL1V0aWxzL0NzdlRyYWl0LnBocI8FAACSop5gjwUAAFPiGyqkAQAAAAAAACkAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy9hdXRvbG9hZGVyLnBocBwBAACSop5gHAEAAEGrcAKkAQAAAAAAADMAAAB2ZW5kb3IvZ2V0dGV4dC9nZXR0ZXh0L3NyYy90cmFuc2xhdG9yX2Z1bmN0aW9ucy5waHAwEAAAkqKeYDAQAAD0FOvIpAEAAAAAAAApAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9SZW5kZXJlci5waHCRngAAkqKeYJGeAACJutEYpAEAAAAAAAAvAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9Gb3JtYXR0ZXIvQmFzZS5waHCFCwAAkqKeYIULAAB8bsKbpAEAAAAAAAAyAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9Gb3JtYXR0ZXIvQ29tcGFjdC5waHC3AwAAkqKeYLcDAAD7Gup0pAEAAAAAAAA2AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9Gb3JtYXR0ZXIvUHJldHR5UHJpbnQucGhwcgEAAJKinmByAQAAjGrpz6QBAAAAAAAAMwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvRm9ybWF0dGVyL0V4cGFuZGVkLnBocOcCAACSop5g5wIAAL4TqHikAQAAAAAAACYAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1F1ZXJ5LnBocAYLAACSop5gBgsAAOwe28ykAQAAAAAAACYAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1BlYXN0LnBocLkYAACSop5guRgAAOX7K/qkAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMTUvRmVhdHVyZXMucGhwngEAAJKinmCeAQAAraa2QKQBAAAAAAAALQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1Rva2VuLnBocNUNAACSop5g1Q0AAMdL+amkAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMjAvRmVhdHVyZXMucGhwEwQAAJKinmATBAAAGLcXT6QBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1NvdXJjZUxvY2F0aW9uLnBocKQGAACSop5gpAYAAOjYrEGkAQAAAAAAADUAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FdmVudHNFbWl0dGVyLnBocBcGAACSop5gFwYAAIZ7EHWkAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMTkvRmVhdHVyZXMucGhwmgIAAJKinmCaAgAA6WZoDqQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VTMjAyMS9GZWF0dXJlcy5waHCWAgAAkqKeYJYCAABLWZhBpAEAAAAAAAAtAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvVXRpbHMucGhwQCEAAJKinmBAIQAAtwdN0qQBAAAAAAAAMAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0ZlYXR1cmVzLnBocDQJAACSop5gNAkAAPnmEgikAQAAAAAAADkAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FbmNvZGluZ0V4Y2VwdGlvbi5waHD3AQAAkqKeYPcBAABMEshwpAEAAAAAAAArAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTFNNLnBocNURAACSop5g1REAAA/67C+kAQAAAAAAADEAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FeGNlcHRpb24ucGhwRAQAAJKinmBEBAAAQgPNjKQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L0VTMjAxOC9GZWF0dXJlcy5waHAoAwAAkqKeYCgDAACGoXBmpAEAAAAAAAAuAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvUGFyc2VyLnBocO7qAQCSop5g7uoBAPvmiZ6kAQAAAAAAADgAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Db21tZW50c1JlZ2lzdHJ5LnBocAspAACSop5gCykAAPupEnykAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMTYvRmVhdHVyZXMucGhwFwIAAJKinmAXAgAAoXR+tqQBAAAAAAAAMAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1Bvc2l0aW9uLnBocN8GAACSop5g3wYAAPUjQy6kAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9FUzIwMTcvRmVhdHVyZXMucGhwAgMAAJKinmACAwAAlZJIQKQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L1BhcnNlckFic3RyYWN0LnBocMokAACSop5gyiQAAFBwLFWkAQAAAAAAAC8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9TY2FubmVyLnBocJjaAACSop5gmNoAACjZ53ykAQAAAAAAADQAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1Byb2dyYW0ucGhwjwkAAJKinmCPCQAAvNSAdqQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ2xhc3NCb2R5LnBocEgEAACSop5gSAQAAAafaFqkAQAAAAAAADcAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cHJlc3Npb24ucGhwhwEAAJKinmCHAQAAenf3IaQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ2F0Y2hDbGF1c2UucGhwwwYAAJKinmDDBgAA5QWksaQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRGVjbGFyYXRpb24ucGhwmwEAAJKinmCbAQAAOLM05aQBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvU3dpdGNoQ2FzZS5waHBYBwAAkqKeYFgHAAD7RQMLpAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnREZWNsYXJhdGlvbi5waHCCBwAAkqKeYIIHAAAAWJ85pAEAAAAAAAA/AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9WYXJpYWJsZURlY2xhcmF0b3IucGhwqwYAAJKinmCrBgAA0WL22aQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRnVuY3Rpb25fLnBocNkNAACSop5g2Q0AAHefdvGkAQAAAAAAAEAAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1ZhcmlhYmxlRGVjbGFyYXRpb24ucGhwYwgAAJKinmBjCAAAFLejSaQBAAAAAAAAOgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQmlnSW50TGl0ZXJhbC5waHD6BAAAkqKeYPoEAAAGFT48pAEAAAAAAAA8AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnRTcGVjaWZpZXIucGhwkAQAAJKinmCQBAAASL7qvaQBAAAAAAAANgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvU3RhdGVtZW50LnBocIUBAACSop5ghQEAAIWXkgakAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0Jvb2xlYW5MaXRlcmFsLnBocEkDAACSop5gSQMAAG3OznykAQAAAAAAAD4AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0Fzc2lnbm1lbnRQYXR0ZXJuLnBocLEGAACSop5gsQYAABXAUlmkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1VuYXJ5RXhwcmVzc2lvbi5waHBSCQAAkqKeYFIJAAB+dQTSpAEAAAAAAAA1AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Qcm9wZXJ0eS5waHACEwAAkqKeYAITAACZ/AqppAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DaGFpbkVsZW1lbnQucGhwxwQAAJKinmDHBAAAIswNK6QBAAAAAAAAPgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ29udGludWVTdGF0ZW1lbnQucGhwggQAAJKinmCCBAAA7MhaWaQBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ2hhaW5FeHByZXNzaW9uLnBocIkEAACSop5giQQAABr4gmWkAQAAAAAAAD4AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01vZHVsZURlY2xhcmF0aW9uLnBocJABAACSop5gkAEAANRudKukAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL09iamVjdEV4cHJlc3Npb24ucGhwzQQAAJKinmDNBAAAJyFFf6QBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQXdhaXRFeHByZXNzaW9uLnBocFUEAACSop5gVQQAAKEO3PikAQAAAAAAAD8AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0Fzc2lnbm1lbnRQcm9wZXJ0eS5waHCYBQAAkqKeYJgFAACMvbFZpAEAAAAAAAA8AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9SZXR1cm5TdGF0ZW1lbnQucGhw9QQAAJKinmD1BAAA1jpD66QBAAAAAAAAPQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTWV0aG9kRGVmaW5pdGlvbi5waHCFDwAAkqKeYIUPAACDdZfRpAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9OZXdFeHByZXNzaW9uLnBocK4BAACSop5grgEAAO+wPqykAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL01vZHVsZVNwZWNpZmllci5waHBPBAAAkqKeYE8EAAA5RQRNpAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9SZXN0RWxlbWVudC5waHCWBAAAkqKeYJYEAADEjZuMpAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9XaXRoU3RhdGVtZW50LnBocGQGAACSop5gZAYAAB+6fEqkAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL09iamVjdFBhdHRlcm4ucGhw1gQAAJKinmDWBAAAv/3n3KQBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvV2hpbGVTdGF0ZW1lbnQucGhwKgYAAJKinmAqBgAA6q6Th6QBAAAAAAAAPwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRnVuY3Rpb25FeHByZXNzaW9uLnBocNUBAACSop5g1QEAAMG9wVWkAQAAAAAAAEIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NvbmRpdGlvbmFsRXhwcmVzc2lvbi5waHARCQAAkqKeYBEJAACW+qiJpAEAAAAAAAA6AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9TcHJlYWRFbGVtZW50LnBocIUEAACSop5ghQQAAOKCJa+kAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0FycmF5RXhwcmVzc2lvbi5waHATBQAAkqKeYBMFAAB0OKzupAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9NZXRhUHJvcGVydHkucGhwBQYAAJKinmAFBgAAmfk6C6QBAAAAAAAAPgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRGVidWdnZXJTdGF0ZW1lbnQucGhwvgEAAJKinmC+AQAAZGnjH6QBAAAAAAAANAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvQ29tbWVudC5waHBYEAAAkqKeYFgQAAAe/FggpAEAAAAAAAA3AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JZGVudGlmaWVyLnBocBcEAACSop5gFwQAAJIPFrKkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1RlbXBsYXRlTGl0ZXJhbC5waHBODQAAkqKeYE4NAAAWtrhEpAEAAAAAAAA0AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9QYXR0ZXJuLnBocIEBAACSop5ggQEAAMXVAL6kAQAAAAAAADMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NsYXNzXy5waHB5CAAAkqKeYHkIAAAQbuCQpAEAAAAAAAA8AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9FeHBvcnRTcGVjaWZpZXIucGhwhAQAAJKinmCEBAAATNsOqKQBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRm9yT2ZTdGF0ZW1lbnQucGhwmgQAAJKinmCaBAAA/b8s6aQBAAAAAAAAPAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvWWllbGRFeHByZXNzaW9uLnBocDMHAACSop5gMwcAAKPbNZykAQAAAAAAAEAAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cHJlc3Npb25TdGF0ZW1lbnQucGhwjAQAAJKinmCMBAAAW7QCbaQBAAAAAAAAOQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvVHJ5U3RhdGVtZW50LnBocAUJAACSop5gBQkAAIo4tSKkAQAAAAAAADIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1N1cGVyLnBocIIBAACSop5gggEAAFJD3CikAQAAAAAAAEUAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1RhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbi5waHBcBgAAkqKeYFwGAADo198VpAEAAAAAAABEAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9BcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbi5waHD9BQAAkqKeYP0FAADRhc/3pAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnRFeHByZXNzaW9uLnBocE8EAACSop5gTwQAAKuETPKkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1N3aXRjaFN0YXRlbWVudC5waHDuBgAAkqKeYO4GAAClwRDopAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Gb3JTdGF0ZW1lbnQucGhwQwsAAJKinmBDCwAAMaEPqqQBAAAAAAAAPQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvVXBkYXRlRXhwcmVzc2lvbi5waHA7CQAAkqKeYDsJAAAzbcz/pAEAAAAAAAA/AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9TZXF1ZW5jZUV4cHJlc3Npb24ucGhwygQAAJKinmDKBAAA8tzTDqQBAAAAAAAAQAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRnVuY3Rpb25EZWNsYXJhdGlvbi5waHDVAgAAkqKeYNUCAABEGSrqpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9NZW1iZXJFeHByZXNzaW9uLnBocOUJAACSop5g5QkAAMsjRYSkAQAAAAAAAEMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0V4cG9ydE5hbWVkRGVjbGFyYXRpb24ucGhw0QkAAJKinmDRCQAAnvejgKQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTnVsbExpdGVyYWwucGhwAQMAAJKinmABAwAA3UvaD6QBAAAAAAAARAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvUGFyZW50aGVzaXplZEV4cHJlc3Npb24ucGhwiAQAAJKinmCIBAAAKILl06QBAAAAAAAAQQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRXhwb3J0QWxsRGVjbGFyYXRpb24ucGhwngYAAJKinmCeBgAAfWZ4DqQBAAAAAAAARQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uLnBocBAFAACSop5gEAUAADMiCRukAQAAAAAAADkAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0FycmF5UGF0dGVybi5waHCXBAAAkqKeYJcEAADeypEopAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9UaGlzRXhwcmVzc2lvbi5waHCgAQAAkqKeYKABAADiJWGCpAEAAAAAAAA8AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DbGFzc0V4cHJlc3Npb24ucGhwwgEAAJKinmDCAQAAcH6qw6QBAAAAAAAAPQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTGFiZWxlZFN0YXRlbWVudC5waHDmBQAAkqKeYOYFAAAoBo6SpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9CaW5hcnlFeHByZXNzaW9uLnBocFcIAACSop5gVwgAAMbww1ukAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0NsYXNzRGVjbGFyYXRpb24ucGhw0AIAAJKinmDQAgAAJV7paqQBAAAAAAAARQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyLnBocN0BAACSop5g3QEAAE3znmOkAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1RlbXBsYXRlRWxlbWVudC5waHD0CQAAkqKeYPQJAAA3hv/RpAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9FbXB0eVN0YXRlbWVudC5waHCjAQAAkqKeYKMBAABusr0PpAEAAAAAAABBAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Bc3NpZ25tZW50RXhwcmVzc2lvbi5waHAyCQAAkqKeYDIJAACd+lSOpAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9CcmVha1N0YXRlbWVudC5waHB5BAAAkqKeYHkEAACRDIsypAEAAAAAAAA+AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Mb2dpY2FsRXhwcmVzc2lvbi5waHBaCAAAkqKeYFoIAAC/0VOepAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9OdW1lcmljTGl0ZXJhbC5waHCiEwAAkqKeYKITAACp0PYNpAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9DYWxsRXhwcmVzc2lvbi5waHBXBwAAkqKeYFcHAAD7jpsNpAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9JbXBvcnREZWZhdWx0U3BlY2lmaWVyLnBocOcBAACSop5g5wEAAOEf5EqkAQAAAAAAADsAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0ZvckluU3RhdGVtZW50LnBocBQJAACSop5gFAkAAFAX45ukAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL1N0cmluZ0xpdGVyYWwucGhwvwkAAJKinmC/CQAANb924qQBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvVGhyb3dTdGF0ZW1lbnQucGhwbAQAAJKinmBsBAAAg6KxgKQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSWZTdGF0ZW1lbnQucGhwjwoAAJKinmCPCgAAe5WbEKQBAAAAAAAAOgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvUmVnRXhwTGl0ZXJhbC5waHBYCgAAkqKeYFgKAAD1RDQ5pAEAAAAAAAA7AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9CbG9ja1N0YXRlbWVudC5waHCeBAAAkqKeYJ4EAACf4ACGpAEAAAAAAAA9AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9Eb1doaWxlU3RhdGVtZW50LnBocDIGAACSop5gMgYAAKiloYGkAQAAAAAAAEMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hFbXB0eUV4cHJlc3Npb24ucGhwswEAAJKinmCzAQAAOrY4/6QBAAAAAAAARAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWE1lbWJlckV4cHJlc3Npb24ucGhwXAcAAJKinmBcBwAADQZ4TqQBAAAAAAAAQwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWFNwcmVhZEF0dHJpYnV0ZS5waHDFAQAAkqKeYMUBAABLJlGPpAEAAAAAAABCAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYQ2xvc2luZ0VsZW1lbnQucGhwpgEAAJKinmCmAQAA3WbzoaQBAAAAAAAAPgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWElkZW50aWZpZXIucGhwtAEAAJKinmC0AQAAg5ngTKQBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWFRleHQucGhw+AUAAJKinmD4BQAAmcaRuaQBAAAAAAAAOwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWEVsZW1lbnQucGhwogoAAJKinmCiCgAAfxAKjKQBAAAAAAAAQgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWE5hbWVzcGFjZWROYW1lLnBocHoGAACSop5gegYAAMLUhD2kAQAAAAAAADwAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hGcmFnbWVudC5waHCCCgAAkqKeYIIKAABOlE8vpAEAAAAAAAA/AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYU3ByZWFkQ2hpbGQucGhwowQAAJKinmCjBAAArH027qQBAAAAAAAAQwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWE9wZW5pbmdGcmFnbWVudC5waHC3AQAAkqKeYLcBAACV5LQIpAEAAAAAAABDAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9KU1gvSlNYQ2xvc2luZ0ZyYWdtZW50LnBocLcBAACSop5gtwEAAE7oh1ykAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hBdHRyaWJ1dGUucGhwdwcAAJKinmB3BwAAiZxrPqQBAAAAAAAAQgAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWE9wZW5pbmdFbGVtZW50LnBocBIIAACSop5gEggAAD5P0POkAQAAAAAAAEMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9Ob2RlL0pTWC9KU1hCb3VuZGFyeUVsZW1lbnQucGhweQUAAJKinmB5BQAAvPmiz6QBAAAAAAAARwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvSlNYL0pTWEV4cHJlc3Npb25Db250YWluZXIucGhwwgUAAJKinmDCBQAA+ncYxqQBAAAAAAAAMQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU3ludGF4L05vZGUvTm9kZS5waHBVIgAAkqKeYFUiAACn4k2RpAEAAAAAAAA0AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TeW50YXgvTm9kZS9MaXRlcmFsLnBocB4GAACSop5gHgYAABPENcqkAQAAAAAAADIAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9KU1gvUGFyc2VyLnBocHI2AACSop5gcjYAAHGGqamkAQAAAAAAADMAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1N5bnRheC9KU1gvU2Nhbm5lci5waHBlCwAAkqKeYGULAACWoMvRpAEAAAAAAAAqAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9UcmF2ZXJzZXIucGhwrhoAAJKinmCuGgAAvQHUI6QBAAAAAAAAMQAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTWF0Y2hlcy5waHDfDwAAkqKeYN8PAACZ3oZNpAEAAAAAAAAzAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9FeGNlcHRpb24ucGhw1wEAAJKinmDXAQAAQlE6jaQBAAAAAAAAMAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvUGFyc2VyLnBocJ9CAACSop5gn0IAAAKGbcqkAQAAAAAAADoAAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1NlbGVjdG9yL05vZGUvUGFydC9Qc2V1ZG8ucGhwtgIAAJKinmC2AgAAQC3tlaQBAAAAAAAAQAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9QYXJ0L1BzZXVkb1NpbXBsZS5waHBrBgAAkqKeYGsGAAB4mde3pAEAAAAAAAA4AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvVHlwZS5waHAGBAAAkqKeYAYEAACw4ikepAEAAAAAAABCAAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL1BhcnQvUHNldWRvU2VsZWN0b3IucGhwXwUAAJKinmBfBQAA+MuXC6QBAAAAAAAAPwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9QYXJ0L1BzZXVkb0luZGV4LnBocC0JAACSop5gLQkAALRGnqikAQAAAAAAAD0AAAB2ZW5kb3IvbWNrODkvcGVhc3QvbGliL1BlYXN0L1NlbGVjdG9yL05vZGUvUGFydC9BdHRyaWJ1dGUucGhwwRYAAJKinmDBFgAAE9cyv6QBAAAAAAAAOAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9QYXJ0L1BhcnQucGhwcgMAAJKinmByAwAAobxZJ6QBAAAAAAAANwAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9TZWxlY3Rvci5waHD3BAAAkqKeYPcEAACKOnLVpAEAAAAAAAA5AAAAdmVuZG9yL21jazg5L3BlYXN0L2xpYi9QZWFzdC9TZWxlY3Rvci9Ob2RlL0NvbWJpbmF0b3IucGhwUw8AAJKinmBTDwAAuK7dCKQBAAAAAAAANAAAAHZlbmRvci9tY2s4OS9wZWFzdC9saWIvUGVhc3QvU2VsZWN0b3IvTm9kZS9Hcm91cC5waHANBAAAkqKeYA0EAABIO/MdpAEAAAAAAAAyAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvdGVtcGxhdGVzL21hbi1wYXJhbXMubXVzdGFjaGU/AQAAkqKeYD8BAACTE81upAEAAAAAAAArAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvdGVtcGxhdGVzL21hbi5tdXN0YWNoZf4AAACSop5g/gAAAKlJHjykAQAAAAAAADkAAAB2ZW5kb3Ivd3AtY2xpL2NvbmZpZy1jb21tYW5kL3RlbXBsYXRlcy93cC1jb25maWcubXVzdGFjaGXLCQAAkqKeYMsJAADcCUb6pAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9jb3JlLWNvbW1hbmQvdGVtcGxhdGVzL3ZlcnNpb25zLm11c3RhY2hljAAAAJKinmCMAAAAU1UitKQBAAAAAAAAQAAAAHZlbmRvci93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1zdGF0dXMubXVzdGFjaGWaAAAAkqKeYJoAAABvW8Y1pAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC90ZW1wbGF0ZXMvdGhlbWUtc3RhdHVzLm11c3RhY2hleAAAAJKinmB4AAAAx4Fn0aQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLWJvb3RzdHJhcC5tdXN0YWNoZWsEAACSop5gawQAAB1b31ekAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1ncnVudGZpbGUubXVzdGFjaGWlBAAAkqKeYKUEAADRVIsEpAEAAAAAAABEAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wb3N0X3R5cGVfZXh0ZW5kZWQubXVzdGFjaGWNEAAAkqKeYI0QAACHO35lpAEAAAAAAAA8AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9pbnN0YWxsLXdwLXRlc3RzLnNodBcAAJKinmB0FwAApRimvaQBAAAAAAAAOAAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvLnBocGNzLnhtbC5kaXN0PQgAAJKinmA9CAAAWx66LaQBAAAAAAAAQQAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvdGhlbWUtYm9vdHN0cmFwLm11c3RhY2hlmQUAAJKinmCZBQAAPuv6yqQBAAAAAAAAOQAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGhwdW5pdC54bWwuZGlzdIUBAACSop5ghQEAACXV9UakAQAAAAAAAD8AAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1naXRsYWIubXVzdGFjaGVcBQAAkqKeYFwFAADi/KAMpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tcmVhZG1lLm11c3RhY2hlGhEAAJKinmAaEQAAA2IM+6QBAAAAAAAAQQAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvYmxvY2stc3R5bGUtY3NzLm11c3RhY2hlAQEAAJKinmABAQAAHq6X2KQBAAAAAAAAOwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcG9zdF90eXBlLm11c3RhY2hltAoAAJKinmC0CgAAoTMkp6QBAAAAAAAARAAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLXRlc3Qtc2FtcGxlLm11c3RhY2hlJwEAAJKinmAnAQAAFlx+p6QBAAAAAAAARwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvY2hpbGRfdGhlbWVfZnVuY3Rpb25zLm11c3RhY2hlTgIAAJKinmBOAgAALpHfD6QBAAAAAAAAQwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLWRpc3RpZ25vcmUubXVzdGFjaGVIAgAAkqKeYEgCAAAxRUGopAEAAAAAAAA4AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4ubXVzdGFjaGVxAQAAkqKeYHEBAABHiXHSpAEAAAAAAABBAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tcGFja2FnZXMubXVzdGFjaGVeAQAAkqKeYF4BAACjNYkrpAEAAAAAAABDAAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy90aGVtZS10ZXN0LXNhbXBsZS5tdXN0YWNoZSYBAACSop5gJgEAAH/9le6kAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1naXRpZ25vcmUubXVzdGFjaGVeAAAAkqKeYF4AAADHweaApAEAAAAAAAA2AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy8uZWRpdG9yY29uZmlnwAEAAJKinmDAAQAAEqZo0aQBAAAAAAAAPgAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvdGhlbWUtc3RhdHVzLm11c3RhY2hleAAAAJKinmB4AAAAx4Fn0aQBAAAAAAAAPwAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvcGx1Z2luLWNpcmNsZS5tdXN0YWNoZTwLAACSop5gPAsAAAV56TWkAQAAAAAAAEIAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3BsdWdpbi1iaXRidWNrZXQubXVzdGFjaGWRFQAAkqKeYJEVAABaQmdtpAEAAAAAAAA/AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy9wbHVnaW4tdHJhdmlzLm11c3RhY2hl+QYAAJKinmD5BgAAYUeVUqQBAAAAAAAAQAAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvYmxvY2staW5kZXgtanMubXVzdGFjaGXkCgAAkqKeYOQKAAAivbUwpAEAAAAAAAA6AAAAdmVuZG9yL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL3RlbXBsYXRlcy90YXhvbm9teS5tdXN0YWNoZWkKAACSop5gaQoAAPiuUnikAQAAAAAAAD0AAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL2NoaWxkX3RoZW1lLm11c3RhY2hl1AAAAJKinmDUAAAA6f32uaQBAAAAAAAAQgAAAHZlbmRvci93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC90ZW1wbGF0ZXMvYmxvY2stZWRpdG9yLWNzcy5tdXN0YWNoZcsAAACSop5gywAAAJMsVl2kAQAAAAAAAEMAAAB2ZW5kb3Ivd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvdGVtcGxhdGVzL3RheG9ub215X2V4dGVuZGVkLm11c3RhY2hl6AMAAJKinmDoAwAAm3vXLKQBAAAAAAAAEwAAAHZlbmRvci9hdXRvbG9hZC5waHCyAAAAkqKeYLIAAAA7nqqTpAEAAAAAAAAgAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL0xJQ0VOU0UsBAAAkqKeYCwEAABWhmeCpAEAAAAAAAAxAAAAdmVuZG9yL2NvbXBvc2VyL2NvbXBvc2VyL3Jlcy9jb21wb3Nlci1zY2hlbWEuanNvbv+qAACSop5g/6oAANtwhQWkAQAAAAAAADwAAAB2ZW5kb3Ivcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVHJhbnNwb3J0L2NhY2VydC5wZW1/PgMAkqKeYH8+AwC2EFVWpAEAAAAAAAAmAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvQ09NUE9TRVJfVkVSU0lPTlNfDgAAkqKeYF8OAADAdymepAEAAAAAAAAcAAAAdmVuZG9yL3dwLWNsaS93cC1jbGkvVkVSU0lPTgUAAACSop5gBQAAAA3aUFKkAQAAAAAAADw/cGhwCgovKioKICogQ29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3JhbXNleS9hcnJheV9jb2x1bW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqCiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSBCZW4gUmFtc2V5IChodHRwczovL2JlbnJhbXNleS5jb20pCiAqIEBsaWNlbnNlIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVAogKgogKiBAcGhwY3M6ZGlzYWJsZSAtLSBDb2RlIGZyb20gZXh0ZXJuYWwgc291cmNlLiBMZWZ0IGFzLWlzIGZvciBlYXNpZXIgY29tcGFyZS4KICovCmlmICghZnVuY3Rpb25fZXhpc3RzKCdhcnJheV9jb2x1bW4nKSkgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgZnJvbSBhIHNpbmdsZSBjb2x1bW4gb2YgdGhlIGlucHV0IGFycmF5LCBpZGVudGlmaWVkIGJ5CiAgICAgKiB0aGUgJGNvbHVtbktleS4KICAgICAqCiAgICAgKiBPcHRpb25hbGx5LCB5b3UgbWF5IHByb3ZpZGUgYW4gJGluZGV4S2V5IHRvIGluZGV4IHRoZSB2YWx1ZXMgaW4gdGhlIHJldHVybmVkCiAgICAgKiBhcnJheSBieSB0aGUgdmFsdWVzIGZyb20gdGhlICRpbmRleEtleSBjb2x1bW4gaW4gdGhlIGlucHV0IGFycmF5LgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5wdXQgQSBtdWx0aS1kaW1lbnNpb25hbCBhcnJheSAocmVjb3JkIHNldCkgZnJvbSB3aGljaCB0byBwdWxsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIGEgY29sdW1uIG9mIHZhbHVlcy4KICAgICAqIEBwYXJhbSBtaXhlZCAkY29sdW1uS2V5IFRoZSBjb2x1bW4gb2YgdmFsdWVzIHRvIHJldHVybi4gVGhpcyB2YWx1ZSBtYXkgYmUgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlZ2VyIGtleSBvZiB0aGUgY29sdW1uIHlvdSB3aXNoIHRvIHJldHJpZXZlLCBvciBpdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgbWF5IGJlIHRoZSBzdHJpbmcga2V5IG5hbWUgZm9yIGFuIGFzc29jaWF0aXZlIGFycmF5LgogICAgICogQHBhcmFtIG1peGVkICRpbmRleEtleSAoT3B0aW9uYWwuKSBUaGUgY29sdW1uIHRvIHVzZSBhcyB0aGUgaW5kZXgva2V5cyBmb3IKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHJldHVybmVkIGFycmF5LiBUaGlzIHZhbHVlIG1heSBiZSB0aGUgaW50ZWdlciBrZXkKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIGNvbHVtbiwgb3IgaXQgbWF5IGJlIHRoZSBzdHJpbmcga2V5IG5hbWUuCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIGZ1bmN0aW9uIGFycmF5X2NvbHVtbigkaW5wdXQgPSBudWxsLCAkY29sdW1uS2V5ID0gbnVsbCwgJGluZGV4S2V5ID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBVc2luZyBmdW5jX2dldF9hcmdzKCkgaW4gb3JkZXIgdG8gY2hlY2sgZm9yIHByb3BlciBudW1iZXIgb2YKICAgICAgICAvLyBwYXJhbWV0ZXJzIGFuZCB0cmlnZ2VyIGVycm9ycyBleGFjdGx5IGFzIHRoZSBidWlsdC1pbiBhcnJheV9jb2x1bW4oKQogICAgICAgIC8vIGRvZXMgaW4gUEhQIDUuNS4KICAgICAgICAkYXJnYyA9IGZ1bmNfbnVtX2FyZ3MoKTsKICAgICAgICAkcGFyYW1zID0gZnVuY19nZXRfYXJncygpOwoKICAgICAgICBpZiAoJGFyZ2MgPCAyKSB7CiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoImFycmF5X2NvbHVtbigpIGV4cGVjdHMgYXQgbGVhc3QgMiBwYXJhbWV0ZXJzLCB7JGFyZ2N9IGdpdmVuIiwgRV9VU0VSX1dBUk5JTkcpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfYXJyYXkoJHBhcmFtc1swXSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcigKICAgICAgICAgICAgICAgICdhcnJheV9jb2x1bW4oKSBleHBlY3RzIHBhcmFtZXRlciAxIHRvIGJlIGFycmF5LCAnIC4gZ2V0dHlwZSgkcGFyYW1zWzBdKSAuICcgZ2l2ZW4nLAogICAgICAgICAgICAgICAgRV9VU0VSX1dBUk5JTkcKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX2ludCgkcGFyYW1zWzFdKQogICAgICAgICAgICAmJiAhaXNfZmxvYXQoJHBhcmFtc1sxXSkKICAgICAgICAgICAgJiYgIWlzX3N0cmluZygkcGFyYW1zWzFdKQogICAgICAgICAgICAmJiAkcGFyYW1zWzFdICE9PSBudWxsCiAgICAgICAgICAgICYmICEoaXNfb2JqZWN0KCRwYXJhbXNbMV0pICYmIG1ldGhvZF9leGlzdHMoJHBhcmFtc1sxXSwgJ19fdG9TdHJpbmcnKSkKICAgICAgICApIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignYXJyYXlfY29sdW1uKCk6IFRoZSBjb2x1bW4ga2V5IHNob3VsZCBiZSBlaXRoZXIgYSBzdHJpbmcgb3IgYW4gaW50ZWdlcicsIEVfVVNFUl9XQVJOSU5HKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRwYXJhbXNbMl0pCiAgICAgICAgICAgICYmICFpc19pbnQoJHBhcmFtc1syXSkKICAgICAgICAgICAgJiYgIWlzX2Zsb2F0KCRwYXJhbXNbMl0pCiAgICAgICAgICAgICYmICFpc19zdHJpbmcoJHBhcmFtc1syXSkKICAgICAgICAgICAgJiYgIShpc19vYmplY3QoJHBhcmFtc1syXSkgJiYgbWV0aG9kX2V4aXN0cygkcGFyYW1zWzJdLCAnX190b1N0cmluZycpKQogICAgICAgICkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdhcnJheV9jb2x1bW4oKTogVGhlIGluZGV4IGtleSBzaG91bGQgYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIGludGVnZXInLCBFX1VTRVJfV0FSTklORyk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRwYXJhbXNJbnB1dCA9ICRwYXJhbXNbMF07CiAgICAgICAgJHBhcmFtc0NvbHVtbktleSA9ICgkcGFyYW1zWzFdICE9PSBudWxsKSA/IChzdHJpbmcpICRwYXJhbXNbMV0gOiBudWxsOwoKICAgICAgICAkcGFyYW1zSW5kZXhLZXkgPSBudWxsOwogICAgICAgIGlmIChpc3NldCgkcGFyYW1zWzJdKSkgewogICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHBhcmFtc1syXSkgfHwgaXNfaW50KCRwYXJhbXNbMl0pKSB7CiAgICAgICAgICAgICAgICAkcGFyYW1zSW5kZXhLZXkgPSAoaW50KSAkcGFyYW1zWzJdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBhcmFtc0luZGV4S2V5ID0gKHN0cmluZykgJHBhcmFtc1syXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdEFycmF5ID0gW107CgogICAgICAgIGZvcmVhY2ggKCRwYXJhbXNJbnB1dCBhcyAkcm93KSB7CiAgICAgICAgICAgICRrZXkgPSAkdmFsdWUgPSBudWxsOwogICAgICAgICAgICAka2V5U2V0ID0gJHZhbHVlU2V0ID0gZmFsc2U7CgogICAgICAgICAgICBpZiAoJHBhcmFtc0luZGV4S2V5ICE9PSBudWxsICYmIGFycmF5X2tleV9leGlzdHMoJHBhcmFtc0luZGV4S2V5LCAkcm93KSkgewogICAgICAgICAgICAgICAgJGtleVNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAka2V5ID0gKHN0cmluZykgJHJvd1skcGFyYW1zSW5kZXhLZXldOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHBhcmFtc0NvbHVtbktleSA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHZhbHVlU2V0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRyb3c7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc19hcnJheSgkcm93KSAmJiBhcnJheV9rZXlfZXhpc3RzKCRwYXJhbXNDb2x1bW5LZXksICRyb3cpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWVTZXQgPSB0cnVlOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJHJvd1skcGFyYW1zQ29sdW1uS2V5XTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR2YWx1ZVNldCkgewogICAgICAgICAgICAgICAgaWYgKCRrZXlTZXQpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0QXJyYXlbJGtleV0gPSAkdmFsdWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRyZXN1bHRBcnJheVtdID0gJHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRBcnJheTsKICAgIH0KCn0KLy8gcGhwY3M6ZW5hYmxlCjw/cGhwCgpyZXR1cm4gWwoJJ3BhdGgnICAgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICc9PHBhdGg+JywKCQknZmlsZScgICAgPT4gJzxwYXRoPicsCgkJJ2Rlc2MnICAgID0+ICdQYXRoIHRvIHRoZSBXb3JkUHJlc3MgZmlsZXMuJywKCV0sCgoJJ3VybCcgICAgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICc9PHVybD4nLAoJCSdmaWxlJyAgICA9PiAnPHVybD4nLAoJCSdkZXNjJyAgICA9PiAnUHJldGVuZCByZXF1ZXN0IGNhbWUgZnJvbSBnaXZlbiBVUkwuIEluIG11bHRpc2l0ZSwgdGhpcyBhcmd1bWVudCBpcyBob3cgdGhlIHRhcmdldCBzaXRlIGlzIHNwZWNpZmllZC4nLAoJXSwKCgknc3NoJyAgICAgICAgICAgICAgID0+IFsKCQkncnVudGltZScgPT4gJz1bPHNjaGVtZT46XVs8dXNlcj5AXTxob3N0fGNvbnRhaW5lcj5bOjxwb3J0Pl1bPHBhdGg+XScsCgkJJ2ZpbGUnICAgID0+ICdbPHNjaGVtZT46XVs8dXNlcj5AXTxob3N0fGNvbnRhaW5lcj5bOjxwb3J0Pl1bPHBhdGg+XScsCgkJJ2Rlc2MnICAgID0+ICdQZXJmb3JtIG9wZXJhdGlvbiBhZ2FpbnN0IGEgcmVtb3RlIHNlcnZlciBvdmVyIFNTSCAob3IgYSBjb250YWluZXIgdXNpbmcgc2NoZW1lIG9mICJkb2NrZXIiLCAiZG9ja2VyLWNvbXBvc2UiLCAidmFncmFudCIpLicsCgldLAoKCSdodHRwJyAgICAgICAgICAgICAgPT4gWwoJCSdydW50aW1lJyA9PiAnPTxodHRwPicsCgkJJ2ZpbGUnICAgID0+ICc8aHR0cD4nLAoJCSdkZXNjJyAgICA9PiAnUGVyZm9ybSBvcGVyYXRpb24gYWdhaW5zdCBhIHJlbW90ZSBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIG92ZXIgSFRUUC4nLAoJXSwKCgknYmxvZycgICAgICAgICAgICAgID0+IFsKCQknZGVwcmVjYXRlZCcgPT4gJ1VzZSAtLXVybCBpbnN0ZWFkLicsCgkJJ3J1bnRpbWUnICAgID0+ICc9PHVybD4nLAoJXSwKCgkndXNlcicgICAgICAgICAgICAgID0+IFsKCQkncnVudGltZScgPT4gJz08aWR8bG9naW58ZW1haWw+JywKCQknZmlsZScgICAgPT4gJzxpZHxsb2dpbnxlbWFpbD4nLAoJCSdkZXNjJyAgICA9PiAnU2V0IHRoZSBXb3JkUHJlc3MgdXNlci4nLAoJXSwKCgknc2tpcC1wbHVnaW5zJyAgICAgID0+IFsKCQkncnVudGltZScgPT4gJ1s9PHBsdWdpbnM+XScsCgkJJ2ZpbGUnICAgID0+ICc8bGlzdD4nLAoJCSdkZXNjJyAgICA9PiAnU2tpcCBsb2FkaW5nIGFsbCBwbHVnaW5zLCBvciBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIHBsdWdpbnMuIE5vdGU6IG11LXBsdWdpbnMgYXJlIHN0aWxsIGxvYWRlZC4nLAoJCSdkZWZhdWx0JyA9PiAnJywKCV0sCgoJJ3NraXAtdGhlbWVzJyAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICdbPTx0aGVtZXM+XScsCgkJJ2ZpbGUnICAgID0+ICc8bGlzdD4nLAoJCSdkZXNjJyAgICA9PiAnU2tpcCBsb2FkaW5nIGFsbCB0aGVtZXMsIG9yIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgdGhlbWVzLicsCgkJJ2RlZmF1bHQnID0+ICcnLAoJXSwKCgknc2tpcC1wYWNrYWdlcycgICAgID0+IFsKCQkncnVudGltZScgPT4gJycsCgkJJ2ZpbGUnICAgID0+ICc8Ym9vbD4nLAoJCSdkZXNjJyAgICA9PiAnU2tpcCBsb2FkaW5nIGFsbCBpbnN0YWxsZWQgcGFja2FnZXMuJywKCQknZGVmYXVsdCcgPT4gZmFsc2UsCgldLAoKCSdyZXF1aXJlJyAgICAgICAgICAgPT4gWwoJCSdydW50aW1lJyAgPT4gJz08cGF0aD4nLAoJCSdmaWxlJyAgICAgPT4gJzxwYXRoPicsCgkJJ2Rlc2MnICAgICA9PiAnTG9hZCBQSFAgZmlsZSBiZWZvcmUgcnVubmluZyB0aGUgY29tbWFuZCAobWF5IGJlIHVzZWQgbW9yZSB0aGFuIG9uY2UpLicsCgkJJ211bHRpcGxlJyA9PiB0cnVlLAoJCSdkZWZhdWx0JyAgPT4gW10sCgldLAoKCSdleGVjJyAgICAgICAgICAgICAgPT4gWwoJCSdydW50aW1lJyAgPT4gJz08cGhwLWNvZGU+JywKCQknZmlsZScgICAgID0+ICc8cGhwLWNvZGU+JywKCQknZGVzYycgICAgID0+ICdFeGVjdXRlIFBIUCBjb2RlIGJlZm9yZSBydW5uaW5nIHRoZSBjb21tYW5kIChtYXkgYmUgdXNlZCBtb3JlIHRoYW4gb25jZSkuJywKCQknbXVsdGlwbGUnID0+IHRydWUsCgkJJ2RlZmF1bHQnICA9PiBbXSwKCV0sCgoJJ2Rpc2FibGVkX2NvbW1hbmRzJyA9PiBbCgkJJ2ZpbGUnICAgID0+ICc8bGlzdD4nLAoJCSdkZWZhdWx0JyA9PiBbXSwKCQknZGVzYycgICAgPT4gJyhTdWIpY29tbWFuZHMgdG8gZGlzYWJsZS4nLAoJXSwKCgknY29sb3InICAgICAgICAgICAgID0+IFsKCQkncnVudGltZScgPT4gdHJ1ZSwKCQknZmlsZScgICAgPT4gJzxib29sPicsCgkJJ2RlZmF1bHQnID0+ICdhdXRvJywKCQknZGVzYycgICAgPT4gJ1doZXRoZXIgdG8gY29sb3JpemUgdGhlIG91dHB1dC4nLAoJXSwKCgknZGVidWcnICAgICAgICAgICAgID0+IFsKCQkncnVudGltZScgPT4gJ1s9PGdyb3VwPl0nLAoJCSdmaWxlJyAgICA9PiAnPGdyb3VwPicsCgkJJ2RlZmF1bHQnID0+IGZhbHNlLAoJCSdkZXNjJyAgICA9PiAnU2hvdyBhbGwgUEhQIGVycm9ycyBhbmQgYWRkIHZlcmJvc2l0eSB0byBXUC1DTEkgb3V0cHV0LiBCdWlsdC1pbiBncm91cHMgaW5jbHVkZTogYm9vdHN0cmFwLCBjb21tYW5kZmFjdG9yeSwgYW5kIGhlbHAuJywKCV0sCgoJJ3Byb21wdCcgICAgICAgICAgICA9PiBbCgkJJ3J1bnRpbWUnID0+ICdbPTxhc3NvYz5dJywKCQknZmlsZScgICAgPT4gZmFsc2UsCgkJJ2RlZmF1bHQnID0+IGZhbHNlLAoJCSdkZXNjJyAgICA9PiAnUHJvbXB0IHRoZSB1c2VyIHRvIGVudGVyIHZhbHVlcyBmb3IgYWxsIGNvbW1hbmQgYXJndW1lbnRzLCBvciBhIHN1YnNldCBzcGVjaWZpZWQgYXMgY29tbWEtc2VwYXJhdGVkIHZhbHVlcy4nLAoJXSwKCgkncXVpZXQnICAgICAgICAgICAgID0+IFsKCQkncnVudGltZScgPT4gJycsCgkJJ2ZpbGUnICAgID0+ICc8Ym9vbD4nLAoJCSdkZWZhdWx0JyA9PiBmYWxzZSwKCQknZGVzYycgICAgPT4gJ1N1cHByZXNzIGluZm9ybWF0aW9uYWwgbWVzc2FnZXMuJywKCV0sCgoJJ2FwYWNoZV9tb2R1bGVzJyAgICA9PiBbCgkJJ2ZpbGUnICAgICA9PiAnPGxpc3Q+JywKCQknZGVzYycgICAgID0+ICdMaXN0IG9mIEFwYWNoZSBNb2R1bGVzIHRoYXQgYXJlIHRvIGJlIHJlcG9ydGVkIGFzIGxvYWRlZC4nLAoJCSdtdWx0aXBsZScgPT4gdHJ1ZSwKCQknZGVmYXVsdCcgID0+IFtdLAoJXSwKCgkjIC0tYWxsb3ctcm9vdCA9PiAoTk9UIFJFQ09NTUVOREVEKSBBbGxvdyB3cC1jbGkgdG8gcnVuIGFzIHJvb3QuIFRoaXMgcG9zZXMKCSMgYSBzZWN1cml0eSByaXNrLCBzbyB5b3UgcHJvYmFibHkgZG8gbm90IHdhbnQgdG8gZG8gdGhpcy4KCSdhbGxvdy1yb290JyAgICAgICAgPT4gWwoJCSdmaWxlJyAgICA9PiBmYWxzZSwgIyBFeHBsaWNpdC4gSnVzdCBpbiBjYXNlIHRoZSBkZWZhdWx0IGNoYW5nZXMuCgkJJ3J1bnRpbWUnID0+ICcnLAoJCSdoaWRkZW4nICA9PiB0cnVlLAoJXSwKCl07Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSVxCb290c3RyYXBcQm9vdHN0cmFwU3RhdGU7CnVzZSBXUF9DTElcQm9vdHN0cmFwXEJvb3RzdHJhcFN0ZXA7CgovKioKICogR2V0IHRoZSBsaXN0IG9mIG9yZGVyZWQgc3RlcHMgdGhhdCBuZWVkIHRvIGJlIHByb2Nlc3NlZCB0byBib290c3RyYXAgV1AtQ0xJLgogKgogKiBFYWNoIGVudHJ5IGlzIGEgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgZm9yIGEgY2xhc3MgaW1wbGVtZW50aW5nIHRoZQogKiBgV1BfQ0xJXEJvb3RzdHJhcFxCb290c3RyYXBTdGVwYCBpbnRlcmZhY2UuCiAqCiAqIEByZXR1cm4gc3RyaW5nW10KICovCmZ1bmN0aW9uIGdldF9ib290c3RyYXBfc3RlcHMoKSB7CglyZXR1cm4gWwoJCSdXUF9DTElcQm9vdHN0cmFwXERlY2xhcmVGYWxsYmFja0Z1bmN0aW9ucycsCgkJJ1dQX0NMSVxCb290c3RyYXBcTG9hZFV0aWxpdHlGdW5jdGlvbnMnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExvYWREaXNwYXRjaGVyJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxEZWNsYXJlTWFpbkNsYXNzJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxEZWNsYXJlQWJzdHJhY3RCYXNlQ29tbWFuZCcsCgkJJ1dQX0NMSVxCb290c3RyYXBcSW5jbHVkZUZyYW1ld29ya0F1dG9sb2FkZXInLAoJCSdXUF9DTElcQm9vdHN0cmFwXENvbmZpZ3VyZVJ1bm5lcicsCgkJJ1dQX0NMSVxCb290c3RyYXBcSW5pdGlhbGl6ZUNvbG9yaXphdGlvbicsCgkJJ1dQX0NMSVxCb290c3RyYXBcSW5pdGlhbGl6ZUxvZ2dlcicsCgkJJ1dQX0NMSVxCb290c3RyYXBcRGVmaW5lUHJvdGVjdGVkQ29tbWFuZHMnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExvYWRFeGVjQ29tbWFuZCcsCgkJJ1dQX0NMSVxCb290c3RyYXBcTG9hZFJlcXVpcmVkQ29tbWFuZCcsCgkJJ1dQX0NMSVxCb290c3RyYXBcSW5jbHVkZVBhY2thZ2VBdXRvbG9hZGVyJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxJbmNsdWRlRmFsbGJhY2tBdXRvbG9hZGVyJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxSZWdpc3RlckZyYW1ld29ya0NvbW1hbmRzJywKCQknV1BfQ0xJXEJvb3RzdHJhcFxSZWdpc3RlckRlZmVycmVkQ29tbWFuZHMnLAoJCSdXUF9DTElcQm9vdHN0cmFwXExhdW5jaFJ1bm5lcicsCgldOwp9CgovKioKICogUmVnaXN0ZXIgdGhlIGNsYXNzZXMgbmVlZGVkIGZvciB0aGUgYm9vdHN0cmFwIHByb2Nlc3MuCiAqCiAqIFRoZSBDb21wb3NlciBhdXRvbG9hZGVyIGlzIG5vdCBhY3RpdmUgeWV0IGF0IHRoaXMgcG9pbnQsIHNvIHdlIG5lZWQgdG8gdXNlIGEKICogY3VzdG9tIGF1dG9sb2FkZXIgdG8gZmV0Y2ggdGhlIGJvb3RzdHJhcCBjbGFzc2VzIGluIGEgZmxleGlibGUgd2F5LgogKi8KZnVuY3Rpb24gcHJlcGFyZV9ib290c3RyYXAoKSB7CglyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQXV0b2xvYWRlci5waHAnOwoKCSRhdXRvbG9hZGVyID0gbmV3IEF1dG9sb2FkZXIoKTsKCgkkYXV0b2xvYWRlci0+YWRkX25hbWVzcGFjZSgKCQknV1BfQ0xJXEJvb3RzdHJhcCcsCgkJV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQm9vdHN0cmFwJwoJKS0+cmVnaXN0ZXIoKTsKfQoKLyoqCiAqIEluaXRpYWxpemUgYW5kIHJldHVybiB0aGUgYm9vdHN0cmFwIHN0YXRlIHRvIHBhc3MgZnJvbSBzdGVwIHRvIHN0ZXAuCiAqCiAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUKICovCmZ1bmN0aW9uIGluaXRpYWxpemVfYm9vdHN0cmFwX3N0YXRlKCkgewoJcmV0dXJuIG5ldyBCb290c3RyYXBTdGF0ZSgpOwp9CgovKioKICogUHJvY2VzcyB0aGUgYm9vdHN0cmFwcGluZyBzdGVwcy4KICoKICogTG9vcHMgb3ZlciBlYWNoIG9mIHRoZSBwcm92aWRlZCBzdGVwcywgaW5zdGFudGlhdGVzIGl0IGFuZCB0aGVuIGNhbGxzIGl0cwogKiBgcHJvY2VzcygpYCBtZXRob2QuCiAqLwpmdW5jdGlvbiBib290c3RyYXAoKSB7CglwcmVwYXJlX2Jvb3RzdHJhcCgpOwoJJHN0YXRlID0gaW5pdGlhbGl6ZV9ib290c3RyYXBfc3RhdGUoKTsKCglmb3JlYWNoICggZ2V0X2Jvb3RzdHJhcF9zdGVwcygpIGFzICRzdGVwICkgewoJCS8qKiBAdmFyIEJvb3RzdHJhcFN0ZXAgJHN0ZXBfaW5zdGFuY2UgKi8KCQkkc3RlcF9pbnN0YW5jZSA9IG5ldyAkc3RlcCgpOwoJCSRzdGF0ZSAgICAgICAgID0gJHN0ZXBfaW5zdGFuY2UtPnByb2Nlc3MoICRzdGF0ZSApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnSGVscF9Db21tYW5kJyApICkgewoJcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL3NyYy9IZWxwX0NvbW1hbmQucGhwJzsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2hlbHAnLCAnSGVscF9Db21tYW5kJyApOwo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ0NMSV9Db21tYW5kJyApICkgewoJcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL3NyYy9DTElfQ29tbWFuZC5waHAnOwp9CgppZiAoICEgY2xhc3NfZXhpc3RzKCAnQ0xJX0NhY2hlX0NvbW1hbmQnICkgKSB7CglyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvc3JjL0NMSV9DYWNoZV9Db21tYW5kLnBocCc7Cn0KCmlmICggISBjbGFzc19leGlzdHMoICdDTElfQWxpYXNfQ29tbWFuZCcgKSApIHsKCXJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy9zcmMvQ0xJX0FsaWFzX0NvbW1hbmQucGhwJzsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NsaScsICdDTElfQ29tbWFuZCcgKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjbGkgY2FjaGUnLCAnQ0xJX0NhY2hlX0NvbW1hbmQnICk7CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY2xpIGFsaWFzJywgJ0NMSV9BbGlhc19Db21tYW5kJyApOwo8P3BocAoKdXNlIENvbXBvc2VyXFNlbXZlclxDb21wYXJhdG9yOwp1c2UgV1BfQ0xJXENvbXBsZXRpb25zOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxQcm9jZXNzOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFJldmlld3MgY3VycmVudCBXUC1DTEkgaW5mbywgY2hlY2tzIGZvciB1cGRhdGVzLCBvciB2aWV3cyBkZWZpbmVkIGFsaWFzZXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIERpc3BsYXkgdGhlIHZlcnNpb24gY3VycmVudGx5IGluc3RhbGxlZC4KICogICAgICQgd3AgY2xpIHZlcnNpb24KICogICAgIFdQLUNMSSAwLjI0LjEKICoKICogICAgICMgQ2hlY2sgZm9yIHVwZGF0ZXMgdG8gV1AtQ0xJLgogKiAgICAgJCB3cCBjbGkgY2hlY2stdXBkYXRlCiAqICAgICBTdWNjZXNzOiBXUC1DTEkgaXMgYXQgdGhlIGxhdGVzdCB2ZXJzaW9uLgogKgogKiAgICAgIyBVcGRhdGUgV1AtQ0xJIHRvIHRoZSBsYXRlc3Qgc3RhYmxlIHJlbGVhc2UuCiAqICAgICAkIHdwIGNsaSB1cGRhdGUKICogICAgIFlvdSBoYXZlIHZlcnNpb24gMC4yNC4wLiBXb3VsZCB5b3UgbGlrZSB0byB1cGRhdGUgdG8gMC4yNC4xPyBbeS9uXSB5CiAqICAgICBEb3dubG9hZGluZyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS93cC1jbGkvd3AtY2xpL3JlbGVhc2VzL2Rvd25sb2FkL3YwLjI0LjEvd3AtY2xpLTAuMjQuMS5waGFyLi4uCiAqICAgICBOZXcgdmVyc2lvbiB3b3Jrcy4gUHJvY2VlZGluZyB0byByZXBsYWNlLgogKiAgICAgU3VjY2VzczogVXBkYXRlZCBXUC1DTEkgdG8gMC4yNC4xLgogKgogKiAgICAgIyBDbGVhciB0aGUgaW50ZXJuYWwgV1AtQ0xJIGNhY2hlLgogKiAgICAgJCB3cCBjbGkgY2FjaGUgY2xlYXIKICogICAgIFN1Y2Nlc3M6IENhY2hlIGNsZWFyZWQuCiAqCiAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCiAqLwpjbGFzcyBDTElfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlIGZ1bmN0aW9uIGNvbW1hbmRfdG9fYXJyYXkoICRjb21tYW5kICkgewoJCSRkdW1wID0gWwoJCQknbmFtZScgICAgICAgID0+ICRjb21tYW5kLT5nZXRfbmFtZSgpLAoJCQknZGVzY3JpcHRpb24nID0+ICRjb21tYW5kLT5nZXRfc2hvcnRkZXNjKCksCgkJCSdsb25nZGVzYycgICAgPT4gJGNvbW1hbmQtPmdldF9sb25nZGVzYygpLAoJCV07CgoJCWZvcmVhY2ggKCAkY29tbWFuZC0+Z2V0X3N1YmNvbW1hbmRzKCkgYXMgJHN1YmNvbW1hbmQgKSB7CgkJCSRkdW1wWydzdWJjb21tYW5kcyddW10gPSAkdGhpcy0+Y29tbWFuZF90b19hcnJheSggJHN1YmNvbW1hbmQgKTsKCQl9CgoJCWlmICggZW1wdHkoICRkdW1wWydzdWJjb21tYW5kcyddICkgKSB7CgkJCSRkdW1wWydzeW5vcHNpcyddID0gKHN0cmluZykgJGNvbW1hbmQtPmdldF9zeW5vcHNpcygpOwoJCX0KCgkJcmV0dXJuICRkdW1wOwoJfQoKCS8qKgoJICogUHJpbnRzIFdQLUNMSSB2ZXJzaW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzcGxheSBDTEkgdmVyc2lvbi4KCSAqICAgICAkIHdwIGNsaSB2ZXJzaW9uCgkgKiAgICAgV1AtQ0xJIDAuMjQuMQoJICovCglwdWJsaWMgZnVuY3Rpb24gdmVyc2lvbigpIHsKCQlXUF9DTEk6OmxpbmUoICdXUC1DTEkgJyAuIFdQX0NMSV9WRVJTSU9OICk7Cgl9CgoJLyoqCgkgKiBQcmludHMgdmFyaW91cyBkZXRhaWxzIGFib3V0IHRoZSBXUC1DTEkgZW52aXJvbm1lbnQuCgkgKgoJICogSGVscGZ1bCBmb3IgZGlhZ25vc3RpYyBwdXJwb3NlcywgdGhpcyBjb21tYW5kIHNoYXJlczoKCSAqCgkgKiAqIE9TIGluZm9ybWF0aW9uLgoJICogKiBTaGVsbCBpbmZvcm1hdGlvbi4KCSAqICogUEhQIGJpbmFyeSB1c2VkLgoJICogKiBQSFAgYmluYXJ5IHZlcnNpb24uCgkgKiAqIHBocC5pbmkgY29uZmlndXJhdGlvbiBmaWxlIHVzZWQgKHdoaWNoIGlzIHR5cGljYWxseSBkaWZmZXJlbnQgdGhhbiB3ZWIpLgoJICogKiBXUC1DTEkgcm9vdCBkaXI6IHdoZXJlIFdQLUNMSSBpcyBpbnN0YWxsZWQgKGlmIG5vbi1QaGFyIGluc3RhbGwpLgoJICogKiBXUC1DTEkgZ2xvYmFsIGNvbmZpZzogd2hlcmUgdGhlIGdsb2JhbCBjb25maWcgWUFNTCBmaWxlIGlzIGxvY2F0ZWQuCgkgKiAqIFdQLUNMSSBwcm9qZWN0IGNvbmZpZzogd2hlcmUgdGhlIHByb2plY3QgY29uZmlnIFlBTUwgZmlsZSBpcyBsb2NhdGVkLgoJICogKiBXUC1DTEkgdmVyc2lvbjogY3VycmVudGx5IGluc3RhbGxlZCB2ZXJzaW9uLgoJICoKCSAqIFNlZSBbY29uZmlnIGRvY3NdKGh0dHBzOi8vd3AtY2xpLm9yZy9jb25maWcvKSBmb3IgbW9yZSBkZXRhaWxzIG9uIGdsb2JhbAoJICogYW5kIHByb2plY3QgY29uZmlnIFlBTUwgZmlsZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBsaXN0CgkgKiBvcHRpb25zOgoJICogICAtIGxpc3QKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERpc3BsYXkgdmFyaW91cyBkYXRhIGFib3V0IHRoZSBDTEkgZW52aXJvbm1lbnQuCgkgKiAgICAgJCB3cCBjbGkgaW5mbwoJICogICAgIE9TOiAgTGludXggNC4xMC4wLTQyLWdlbmVyaWMgIzQ2fjE2LjA0LjEtVWJ1bnR1IFNNUCBNb24gRGVjIDQgMTU6NTc6NTkgVVRDIDIwMTcgeDg2XzY0CgkgKiAgICAgU2hlbGw6ICAgL3Vzci9iaW4venNoCgkgKiAgICAgUEhQIGJpbmFyeTogIC91c3IvYmluL3BocAoJICogICAgIFBIUCB2ZXJzaW9uOiA3LjEuMTItMSt1YnVudHUxNi4wNC4xK2RlYi5zdXJ5Lm9yZysxCgkgKiAgICAgcGhwLmluaSB1c2VkOiAgICAvZXRjL3BocC83LjEvY2xpL3BocC5pbmkKCSAqICAgICBXUC1DTEkgcm9vdCBkaXI6ICAgIHBoYXI6Ly93cC1jbGkucGhhcgoJICogICAgIFdQLUNMSSBwYWNrYWdlcyBkaXI6ICAgIC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzLwoJICogICAgIFdQLUNMSSBnbG9iYWwgY29uZmlnOgoJICogICAgIFdQLUNMSSBwcm9qZWN0IGNvbmZpZzoKCSAqICAgICBXUC1DTEkgdmVyc2lvbjogMS41LjAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluZm8oICRfLCAkYXNzb2NfYXJncyApIHsKCQkvLyBwaHBfdW5hbWUoKSAkbW9kZSBhcmd1bWVudCB3YXMgb25seSBhZGRlZCB3aXRoIFBIUCA3LjArLiBGYWxsIGJhY2sgdG8KCQkvLyBlbnRpcmUgc3RyaW5nIGZvciBvbGRlciB2ZXJzaW9ucy4KCQkkc3lzdGVtX29zID0gUEhQX01BSk9SX1ZFUlNJT04gPCA3CgkJCT8gcGhwX3VuYW1lKCkKCQkJOiBzcHJpbnRmKAoJCQkJJyVzICVzICVzICVzJywKCQkJCXBocF91bmFtZSggJ3MnICksCgkJCQlwaHBfdW5hbWUoICdyJyApLAoJCQkJcGhwX3VuYW1lKCAndicgKSwKCQkJCXBocF91bmFtZSggJ20nICkKCQkJKTsKCgkJJHNoZWxsID0gZ2V0ZW52KCAnU0hFTEwnICk7CgkJaWYgKCAhICRzaGVsbCAmJiBVdGlsc1xpc193aW5kb3dzKCkgKSB7CgkJCSRzaGVsbCA9IGdldGVudiggJ0NvbVNwZWMnICk7CgkJfQoKCQkkcGhwX2JpbiA9IFV0aWxzXGdldF9waHBfYmluYXJ5KCk7CgoJCSRydW5uZXIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKTsKCgkJJHBhY2thZ2VzX2RpciA9ICRydW5uZXItPmdldF9wYWNrYWdlc19kaXJfcGF0aCgpOwoJCWlmICggISBpc19kaXIoICRwYWNrYWdlc19kaXIgKSApIHsKCQkJJHBhY2thZ2VzX2RpciA9IG51bGw7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ2pzb24nICkgewoJCQkkaW5mbyA9IFsKCQkJCSdzeXN0ZW1fb3MnICAgICAgICAgICAgICAgID0+ICRzeXN0ZW1fb3MsCgkJCQknc2hlbGwnICAgICAgICAgICAgICAgICAgICA9PiAkc2hlbGwsCgkJCQkncGhwX2JpbmFyeV9wYXRoJyAgICAgICAgICA9PiAkcGhwX2JpbiwKCQkJCSdwaHBfdmVyc2lvbicgICAgICAgICAgICAgID0+IFBIUF9WRVJTSU9OLAoJCQkJJ3BocF9pbmlfdXNlZCcgICAgICAgICAgICAgPT4gZ2V0X2NmZ192YXIoICdjZmdfZmlsZV9wYXRoJyApLAoJCQkJJ215c3FsX2JpbmFyeV9wYXRoJyAgICAgICAgPT4gVXRpbHNcZ2V0X215c3FsX2JpbmFyeV9wYXRoKCksCgkJCQknbXlzcWxfdmVyc2lvbicgICAgICAgICAgICA9PiBVdGlsc1xnZXRfbXlzcWxfdmVyc2lvbigpLAoJCQkJJ3NxbF9tb2RlcycgICAgICAgICAgICAgICAgPT4gVXRpbHNcZ2V0X3NxbF9tb2RlcygpLAoJCQkJJ3dwX2NsaV9kaXJfcGF0aCcgICAgICAgICAgPT4gV1BfQ0xJX1JPT1QsCgkJCQknd3BfY2xpX3ZlbmRvcl9wYXRoJyAgICAgICA9PiBXUF9DTElfVkVORE9SX0RJUiwKCQkJCSd3cF9jbGlfcGhhcl9wYXRoJyAgICAgICAgID0+IGRlZmluZWQoICdXUF9DTElfUEhBUl9QQVRIJyApID8gV1BfQ0xJX1BIQVJfUEFUSCA6ICcnLAoJCQkJJ3dwX2NsaV9wYWNrYWdlc19kaXJfcGF0aCcgPT4gJHBhY2thZ2VzX2RpciwKCQkJCSdnbG9iYWxfY29uZmlnX3BhdGgnICAgICAgID0+ICRydW5uZXItPmdsb2JhbF9jb25maWdfcGF0aCwKCQkJCSdwcm9qZWN0X2NvbmZpZ19wYXRoJyAgICAgID0+ICRydW5uZXItPnByb2plY3RfY29uZmlnX3BhdGgsCgkJCQknd3BfY2xpX3ZlcnNpb24nICAgICAgICAgICA9PiBXUF9DTElfVkVSU0lPTiwKCQkJXTsKCgkJCVdQX0NMSTo6bGluZSgganNvbl9lbmNvZGUoICRpbmZvICkgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmxpbmUoICJPUzpcdCIgLiAkc3lzdGVtX29zICk7CgkJCVdQX0NMSTo6bGluZSggIlNoZWxsOlx0IiAuICRzaGVsbCApOwoJCQlXUF9DTEk6OmxpbmUoICJQSFAgYmluYXJ5Olx0IiAuICRwaHBfYmluICk7CgkJCVdQX0NMSTo6bGluZSggIlBIUCB2ZXJzaW9uOlx0IiAuIFBIUF9WRVJTSU9OICk7CgkJCVdQX0NMSTo6bGluZSggInBocC5pbmkgdXNlZDpcdCIgLiBnZXRfY2ZnX3ZhciggJ2NmZ19maWxlX3BhdGgnICkgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiTXlTUUwgYmluYXJ5Olx0IiAuIFV0aWxzXGdldF9teXNxbF9iaW5hcnlfcGF0aCgpICk7CgkJCVdQX0NMSTo6bGluZSggIk15U1FMIHZlcnNpb246XHQiIC4gVXRpbHNcZ2V0X215c3FsX3ZlcnNpb24oKSApOwoJCQlXUF9DTEk6OmxpbmUoICJTUUwgbW9kZXM6XHQiIC4gaW1wbG9kZSggJywnLCBVdGlsc1xnZXRfc3FsX21vZGVzKCkgKSApOwoJCQlXUF9DTEk6OmxpbmUoICJXUC1DTEkgcm9vdCBkaXI6XHQiIC4gV1BfQ0xJX1JPT1QgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiV1AtQ0xJIHZlbmRvciBkaXI6XHQiIC4gV1BfQ0xJX1ZFTkRPUl9ESVIgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiV1BfQ0xJIHBoYXIgcGF0aDpcdCIgLiAoIGRlZmluZWQoICdXUF9DTElfUEhBUl9QQVRIJyApID8gV1BfQ0xJX1BIQVJfUEFUSCA6ICcnICkgKTsKCQkJV1BfQ0xJOjpsaW5lKCAiV1AtQ0xJIHBhY2thZ2VzIGRpcjpcdCIgLiAkcGFja2FnZXNfZGlyICk7CgkJCVdQX0NMSTo6bGluZSggIldQLUNMSSBnbG9iYWwgY29uZmlnOlx0IiAuICRydW5uZXItPmdsb2JhbF9jb25maWdfcGF0aCApOwoJCQlXUF9DTEk6OmxpbmUoICJXUC1DTEkgcHJvamVjdCBjb25maWc6XHQiIC4gJHJ1bm5lci0+cHJvamVjdF9jb25maWdfcGF0aCApOwoJCQlXUF9DTEk6OmxpbmUoICJXUC1DTEkgdmVyc2lvbjpcdCIgLiBXUF9DTElfVkVSU0lPTiApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyB0byBzZWUgaWYgdGhlcmUgaXMgYSBuZXdlciB2ZXJzaW9uIG9mIFdQLUNMSSBhdmFpbGFibGUuCgkgKgoJICogUXVlcmllcyB0aGUgR2l0aHViIHJlbGVhc2VzIEFQSS4gUmV0dXJucyBhdmFpbGFibGUgdmVyc2lvbnMgaWYgdGhlcmUgYXJlCgkgKiB1cGRhdGVzIGF2YWlsYWJsZSwgb3Igc3VjY2VzcyBtZXNzYWdlIGlmIHVzaW5nIHRoZSBsYXRlc3QgcmVsZWFzZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tcGF0Y2hdCgkgKiA6IE9ubHkgbGlzdCBwYXRjaCB1cGRhdGVzLgoJICoKCSAqIFstLW1pbm9yXQoJICogOiBPbmx5IGxpc3QgbWlub3IgdXBkYXRlcy4KCSAqCgkgKiBbLS1tYWpvcl0KCSAqIDogT25seSBsaXN0IG1ham9yIHVwZGF0ZXMuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB1cGRhdGUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuIERlZmF1bHRzIHRvIHZlcnNpb24sdXBkYXRlX3R5cGUscGFja2FnZV91cmwuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayBmb3IgdXBkYXRlLgoJICogICAgICQgd3AgY2xpIGNoZWNrLXVwZGF0ZQoJICogICAgIFN1Y2Nlc3M6IFdQLUNMSSBpcyBhdCB0aGUgbGF0ZXN0IHZlcnNpb24uCgkgKgoJICogICAgICMgQ2hlY2sgZm9yIHVwZGF0ZSBhbmQgbmV3IHZlcnNpb24gaXMgYXZhaWxhYmxlLgoJICogICAgICQgd3AgY2xpIGNoZWNrLXVwZGF0ZQoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgdmVyc2lvbiB8IHVwZGF0ZV90eXBlIHwgcGFja2FnZV91cmwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMC4yNC4xICB8IHBhdGNoICAgICAgIHwgaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS93cC1jbGkvcmVsZWFzZXMvZG93bmxvYWQvdjAuMjQuMS93cC1jbGktMC4yNC4xLnBoYXIgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGNoZWNrLXVwZGF0ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY2hlY2tfdXBkYXRlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJHVwZGF0ZXMgPSAkdGhpcy0+Z2V0X3VwZGF0ZXMoICRhc3NvY19hcmdzICk7CgoJCWlmICggJHVwZGF0ZXMgKSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQlbICd2ZXJzaW9uJywgJ3VwZGF0ZV90eXBlJywgJ3BhY2thZ2VfdXJsJyBdCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICR1cGRhdGVzICk7CgkJfSBlbHNlaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgfHwgJ3RhYmxlJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkkdXBkYXRlX3R5cGUgPSAkdGhpcy0+Z2V0X3VwZGF0ZV90eXBlX3N0ciggJGFzc29jX2FyZ3MgKTsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiV1AtQ0xJIGlzIGF0IHRoZSBsYXRlc3R7JHVwZGF0ZV90eXBlfXZlcnNpb24uIiApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgV1AtQ0xJIHRvIHRoZSBsYXRlc3QgcmVsZWFzZS4KCSAqCgkgKiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIGNoZWNrIHRoZSByZWxlYXNlcyBBUEkgZm9yIHRoZSBuZXdlc3Qgc3RhYmxlCgkgKiB2ZXJzaW9uLCBhbmQgcHJvbXB0IGlmIG9uZSBpcyBhdmFpbGFibGUuCgkgKgoJICogVXNlIGAtLXN0YWJsZWAgdG8gaW5zdGFsbCBvciByZWluc3RhbGwgdGhlIGxhdGVzdCBzdGFibGUgdmVyc2lvbi4KCSAqCgkgKiBVc2UgYC0tbmlnaHRseWAgdG8gaW5zdGFsbCB0aGUgbGF0ZXN0IGJ1aWx0IHZlcnNpb24gb2YgdGhlIG1hc3RlciBicmFuY2guCgkgKiBXaGlsZSBub3QgcmVjb21tZW5kZWQgZm9yIHByb2R1Y3Rpb24sIG5pZ2h0bHkgY29udGFpbnMgdGhlIGxhdGVzdCBhbmQKCSAqIGdyZWF0ZXN0LCBhbmQgc2hvdWxkIGJlIHN0YWJsZSBlbm91Z2ggZm9yIGRldmVsb3BtZW50IGFuZCBzdGFnaW5nCgkgKiBlbnZpcm9ubWVudHMuCgkgKgoJICogT25seSB3b3JrcyBmb3IgdGhlIFBoYXIgaW5zdGFsbGF0aW9uIG1lY2hhbmlzbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tcGF0Y2hdCgkgKiA6IE9ubHkgcGVyZm9ybSBwYXRjaCB1cGRhdGVzLgoJICoKCSAqIFstLW1pbm9yXQoJICogOiBPbmx5IHBlcmZvcm0gbWlub3IgdXBkYXRlcy4KCSAqCgkgKiBbLS1tYWpvcl0KCSAqIDogT25seSBwZXJmb3JtIG1ham9yIHVwZGF0ZXMuCgkgKgoJICogWy0tc3RhYmxlXQoJICogOiBVcGRhdGUgdG8gdGhlIGxhdGVzdCBzdGFibGUgcmVsZWFzZS4gU2tpcHMgdXBkYXRlIGNoZWNrLgoJICoKCSAqIFstLW5pZ2h0bHldCgkgKiA6IFVwZGF0ZSB0byB0aGUgbGF0ZXN0IGJ1aWx0IHZlcnNpb24gb2YgdGhlIG1hc3RlciBicmFuY2guIFBvdGVudGlhbGx5IHVuc3RhYmxlLgoJICoKCSAqIFstLXllc10KCSAqIDogRG8gbm90IHByb21wdCBmb3IgY29uZmlybWF0aW9uLgoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgQ0xJLgoJICogICAgICQgd3AgY2xpIHVwZGF0ZQoJICogICAgIFlvdSBoYXZlIHZlcnNpb24gMC4yNC4wLiBXb3VsZCB5b3UgbGlrZSB0byB1cGRhdGUgdG8gMC4yNC4xPyBbeS9uXSB5CgkgKiAgICAgRG93bmxvYWRpbmcgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vd3AtY2xpL3dwLWNsaS9yZWxlYXNlcy9kb3dubG9hZC92MC4yNC4xL3dwLWNsaS0wLjI0LjEucGhhci4uLgoJICogICAgIE5ldyB2ZXJzaW9uIHdvcmtzLiBQcm9jZWVkaW5nIHRvIHJlcGxhY2UuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBXUC1DTEkgdG8gMC4yNC4xLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIFV0aWxzXGluc2lkZV9waGFyKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdZb3UgY2FuIG9ubHkgc2VsZi11cGRhdGUgUGhhciBmaWxlcy4nICk7CgkJfQoKCQkkb2xkX3BoYXIgPSByZWFscGF0aCggJF9TRVJWRVJbJ2FyZ3YnXVswXSApOwoKCQlpZiAoICEgaXNfd3JpdGFibGUoICRvbGRfcGhhciApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnJXMgaXMgbm90IHdyaXRhYmxlIGJ5IGN1cnJlbnQgdXNlci4nLCAkb2xkX3BoYXIgKSApOwoJCX0gZWxzZWlmICggISBpc193cml0YWJsZSggZGlybmFtZSggJG9sZF9waGFyICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJyVzIGlzIG5vdCB3cml0YWJsZSBieSBjdXJyZW50IHVzZXIuJywgZGlybmFtZSggJG9sZF9waGFyICkgKSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduaWdodGx5JyApICkgewoJCQlXUF9DTEk6OmNvbmZpcm0oIHNwcmludGYoICdZb3UgaGF2ZSB2ZXJzaW9uICVzLiBXb3VsZCB5b3UgbGlrZSB0byB1cGRhdGUgdG8gdGhlIGxhdGVzdCBuaWdodGx5PycsIFdQX0NMSV9WRVJTSU9OICksICRhc3NvY19hcmdzICk7CgkJCSRkb3dubG9hZF91cmwgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dwLWNsaS9idWlsZHMvZ2gtcGFnZXMvcGhhci93cC1jbGktbmlnaHRseS5waGFyJzsKCQkJJG1kNV91cmwgICAgICA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd3AtY2xpL2J1aWxkcy9naC1wYWdlcy9waGFyL3dwLWNsaS1uaWdodGx5LnBoYXIubWQ1JzsKCQl9IGVsc2VpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0YWJsZScgKSApIHsKCQkJV1BfQ0xJOjpjb25maXJtKCBzcHJpbnRmKCAnWW91IGhhdmUgdmVyc2lvbiAlcy4gV291bGQgeW91IGxpa2UgdG8gdXBkYXRlIHRvIHRoZSBsYXRlc3Qgc3RhYmxlIHJlbGVhc2U/JywgV1BfQ0xJX1ZFUlNJT04gKSwgJGFzc29jX2FyZ3MgKTsKCQkJJGRvd25sb2FkX3VybCA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd3AtY2xpL2J1aWxkcy9naC1wYWdlcy9waGFyL3dwLWNsaS5waGFyJzsKCQkJJG1kNV91cmwgICAgICA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd3AtY2xpL2J1aWxkcy9naC1wYWdlcy9waGFyL3dwLWNsaS5waGFyLm1kNSc7CgkJfSBlbHNlIHsKCgkJCSR1cGRhdGVzID0gJHRoaXMtPmdldF91cGRhdGVzKCAkYXNzb2NfYXJncyApOwoKCQkJaWYgKCBlbXB0eSggJHVwZGF0ZXMgKSApIHsKCQkJCSR1cGRhdGVfdHlwZSA9ICR0aGlzLT5nZXRfdXBkYXRlX3R5cGVfc3RyKCAkYXNzb2NfYXJncyApOwoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiV1AtQ0xJIGlzIGF0IHRoZSBsYXRlc3R7JHVwZGF0ZV90eXBlfXZlcnNpb24uIiApOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQkkbmV3ZXN0ID0gJHVwZGF0ZXNbMF07CgoJCQlXUF9DTEk6OmNvbmZpcm0oIHNwcmludGYoICdZb3UgaGF2ZSB2ZXJzaW9uICVzLiBXb3VsZCB5b3UgbGlrZSB0byB1cGRhdGUgdG8gJXM/JywgV1BfQ0xJX1ZFUlNJT04sICRuZXdlc3RbJ3ZlcnNpb24nXSApLCAkYXNzb2NfYXJncyApOwoKCQkJJGRvd25sb2FkX3VybCA9ICRuZXdlc3RbJ3BhY2thZ2VfdXJsJ107CgkJCSRtZDVfdXJsICAgICAgPSBzdHJfcmVwbGFjZSggJy5waGFyJywgJy5waGFyLm1kNScsICRkb3dubG9hZF91cmwgKTsKCQl9CgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnRG93bmxvYWRpbmcgZnJvbSAlcy4uLicsICRkb3dubG9hZF91cmwgKSApOwoKCQkkdGVtcCA9IFV0aWxzXGdldF90ZW1wX2RpcigpIC4gdW5pcWlkKCAnd3BfJywgdHJ1ZSApIC4gJy5waGFyJzsKCgkJJGhlYWRlcnMgPSBbXTsKCQkkb3B0aW9ucyA9IFsKCQkJJ3RpbWVvdXQnICA9PiA2MDAsICAvLyAxMCBtaW51dGVzIG91Z2h0IHRvIGJlIGVub3VnaCBmb3IgZXZlcnlib2R5LgoJCQknZmlsZW5hbWUnID0+ICR0ZW1wLAoJCQknaW5zZWN1cmUnID0+IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbnNlY3VyZScsIGZhbHNlICksCgkJXTsKCgkJVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJGRvd25sb2FkX3VybCwgbnVsbCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgoJCXVuc2V0KCAkb3B0aW9uc1snZmlsZW5hbWUnXSApOwoJCSRtZDVfcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkbWQ1X3VybCwgbnVsbCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgkJaWYgKCAnMjAnICE9PSBzdWJzdHIoICRtZDVfcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBhY2Nlc3MgbWQ1IGhhc2ggZm9yIHJlbGVhc2UgKEhUVFAgY29kZSB7JG1kNV9yZXNwb25zZS0+c3RhdHVzX2NvZGV9KS4iICk7CgkJfQoJCSRtZDVfZmlsZSAgICAgPSBtZDVfZmlsZSggJHRlbXAgKTsKCQkkcmVsZWFzZV9oYXNoID0gdHJpbSggJG1kNV9yZXNwb25zZS0+Ym9keSApOwoJCWlmICggJG1kNV9maWxlID09PSAkcmVsZWFzZV9oYXNoICkgewoJCQlXUF9DTEk6OmxvZyggJ21kNSBoYXNoIHZlcmlmaWVkOiAnIC4gJHJlbGVhc2VfaGFzaCApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJtZDUgaGFzaCBmb3IgZG93bmxvYWQgKHskbWQ1X2ZpbGV9KSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUgcmVsZWFzZSBoYXNoICh7JHJlbGVhc2VfaGFzaH0pLiIgKTsKCQl9CgoJCSRhbGxvd19yb290ID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1snYWxsb3ctcm9vdCddID8gJy0tYWxsb3ctcm9vdCcgOiAnJzsKCQkkcGhwX2JpbmFyeSA9IFV0aWxzXGdldF9waHBfYmluYXJ5KCk7CgkJJHByb2Nlc3MgICAgPSBQcm9jZXNzOjpjcmVhdGUoICJ7JHBocF9iaW5hcnl9ICR0ZW1wIC0taW5mbyB7JGFsbG93X3Jvb3R9IiApOwoJCSRyZXN1bHQgICAgID0gJHByb2Nlc3MtPnJ1bigpOwoJCWlmICggMCAhPT0gJHJlc3VsdC0+cmV0dXJuX2NvZGUgfHwgZmFsc2UgPT09IHN0cmlwb3MoICRyZXN1bHQtPnN0ZG91dCwgJ1dQLUNMSSB2ZXJzaW9uJyApICkgewoJCQkkbXVsdGlfbGluZSA9IGV4cGxvZGUoIFBIUF9FT0wsICRyZXN1bHQtPnN0ZGVyciApOwoJCQlXUF9DTEk6OmVycm9yX211bHRpX2xpbmUoICRtdWx0aV9saW5lICk7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgZG93bmxvYWRlZCBQSEFSIGlzIGJyb2tlbiwgdHJ5IHJ1bm5pbmcgd3AgY2xpIHVwZGF0ZSBhZ2Fpbi4nICk7CgkJfQoKCQlXUF9DTEk6OmxvZyggJ05ldyB2ZXJzaW9uIHdvcmtzLiBQcm9jZWVkaW5nIHRvIHJlcGxhY2UuJyApOwoKCQkkbW9kZSA9IGZpbGVwZXJtcyggJG9sZF9waGFyICkgJiA1MTE7CgoJCWlmICggZmFsc2UgPT09IGNobW9kKCAkdGVtcCwgJG1vZGUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0Nhbm5vdCBjaG1vZCAlcy4nLCAkdGVtcCApICk7CgkJfQoKCQljbGFzc19leGlzdHMoICdcY2xpXENvbG9ycycgKTsgLy8gVGhpcyBhdXRvbG9hZHMgXGNsaVxDb2xvcnMgLSBhZnRlciB3ZSBtb3ZlIHRoZSBmaWxlIHdlIG5vIGxvbmdlciBoYXZlIGFjY2VzcyB0byB0aGlzIGNsYXNzLgoKCQlpZiAoIGZhbHNlID09PSByZW5hbWUoICR0ZW1wLCAkb2xkX3BoYXIgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0Nhbm5vdCBtb3ZlICVzIHRvICVzJywgJHRlbXAsICRvbGRfcGhhciApICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25pZ2h0bHknLCBmYWxzZSApICkgewoJCQkkdXBkYXRlZF92ZXJzaW9uID0gJ3RoZSBsYXRlc3QgbmlnaHRseSByZWxlYXNlJzsKCQl9IGVsc2VpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0YWJsZScsIGZhbHNlICkgKSB7CgkJCSR1cGRhdGVkX3ZlcnNpb24gPSAndGhlIGxhdGVzdCBzdGFibGUgcmVsZWFzZSc7CgkJfSBlbHNlIHsKCQkJJHVwZGF0ZWRfdmVyc2lvbiA9IGlzc2V0KCAkbmV3ZXN0Wyd2ZXJzaW9uJ10gKSA/ICRuZXdlc3RbJ3ZlcnNpb24nXSA6ICc8bm90IHByb3ZpZGVkPic7CgkJfQoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggJ1VwZGF0ZWQgV1AtQ0xJIHRvICVzLicsICR1cGRhdGVkX3ZlcnNpb24gKSApOwoJfQoKCS8qKgoJICogUmV0dXJucyB1cGRhdGUgaW5mb3JtYXRpb24uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3VwZGF0ZXMoICRhc3NvY19hcmdzICkgewoJCSR1cmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy93cC1jbGkvd3AtY2xpL3JlbGVhc2VzP3Blcl9wYWdlPTEwMCc7CgoJCSRvcHRpb25zID0gWwoJCQkndGltZW91dCcgID0+IDMwLAoJCQknaW5zZWN1cmUnID0+IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbnNlY3VyZScsIGZhbHNlICksCgkJXTsKCgkJJGhlYWRlcnMgPSBbCgkJCSdBY2NlcHQnID0+ICdhcHBsaWNhdGlvbi9qc29uJywKCQldOwoKCQkkZ2l0aHViX3Rva2VuID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOwoJCWlmICggZmFsc2UgIT09ICRnaXRodWJfdG9rZW4gKSB7CgkJCSRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAndG9rZW4gJyAuICRnaXRodWJfdG9rZW47CgkJfQoKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkdXJsLCBudWxsLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCgkJaWYgKCAhICRyZXNwb25zZS0+c3VjY2VzcyB8fCAyMDAgIT09ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdGYWlsZWQgdG8gZ2V0IGxhdGVzdCB2ZXJzaW9uIChIVFRQIGNvZGUgJWQpLicsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSApOwoJCX0KCgkJJHJlbGVhc2VfZGF0YSA9IGpzb25fZGVjb2RlKCAkcmVzcG9uc2UtPmJvZHkgKTsKCgkJJHVwZGF0ZXMgPSBbCgkJCSdtYWpvcicgPT4gZmFsc2UsCgkJCSdtaW5vcicgPT4gZmFsc2UsCgkJCSdwYXRjaCcgPT4gZmFsc2UsCgkJXTsKCQlmb3JlYWNoICggJHJlbGVhc2VfZGF0YSBhcyAkcmVsZWFzZSApIHsKCgkJCS8vIEdldCByaWQgb2YgbGVhZGluZyAidiIgaWYgdGhlcmUgaXMgb25lIHNldC4KCQkJJHJlbGVhc2VfdmVyc2lvbiA9ICRyZWxlYXNlLT50YWdfbmFtZTsKCQkJaWYgKCAndicgPT09IHN1YnN0ciggJHJlbGVhc2VfdmVyc2lvbiwgMCwgMSApICkgewoJCQkJJHJlbGVhc2VfdmVyc2lvbiA9IGx0cmltKCAkcmVsZWFzZV92ZXJzaW9uLCAndicgKTsKCQkJfQoKCQkJJHVwZGF0ZV90eXBlID0gVXRpbHNcZ2V0X25hbWVkX3NlbV92ZXIoICRyZWxlYXNlX3ZlcnNpb24sIFdQX0NMSV9WRVJTSU9OICk7CgkJCWlmICggISAkdXBkYXRlX3R5cGUgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAhIGlzc2V0KCAkcmVsZWFzZS0+YXNzZXRzWzBdLT5icm93c2VyX2Rvd25sb2FkX3VybCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggISBlbXB0eSggJHVwZGF0ZXNbICR1cGRhdGVfdHlwZSBdICkgJiYgISBDb21wYXJhdG9yOjpncmVhdGVyVGhhbiggJHJlbGVhc2VfdmVyc2lvbiwgJHVwZGF0ZXNbICR1cGRhdGVfdHlwZSBdWyd2ZXJzaW9uJ10gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdXBkYXRlc1sgJHVwZGF0ZV90eXBlIF0gPSBbCgkJCQkndmVyc2lvbicgICAgID0+ICRyZWxlYXNlX3ZlcnNpb24sCgkJCQkndXBkYXRlX3R5cGUnID0+ICR1cGRhdGVfdHlwZSwKCQkJCSdwYWNrYWdlX3VybCcgPT4gJHJlbGVhc2UtPmFzc2V0c1swXS0+YnJvd3Nlcl9kb3dubG9hZF91cmwsCgkJCV07CgkJfQoKCQlmb3JlYWNoICggJHVwZGF0ZXMgYXMgJHR5cGUgPT4gJHZhbHVlICkgewoJCQlpZiAoIGVtcHR5KCAkdmFsdWUgKSApIHsKCQkJCXVuc2V0KCAkdXBkYXRlc1sgJHR5cGUgXSApOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggWyAnbWFqb3InLCAnbWlub3InLCAncGF0Y2gnIF0gYXMgJHR5cGUgKSB7CgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAkdHlwZSApICkgewoJCQkJcmV0dXJuICEgZW1wdHkoICR1cGRhdGVzWyAkdHlwZSBdICkgPyBbICR1cGRhdGVzWyAkdHlwZSBdIF0gOiBmYWxzZTsKCQkJfQoJCX0KCgkJaWYgKCBlbXB0eSggJHVwZGF0ZXMgKSAmJiBwcmVnX21hdGNoKCAnIy1hbHBoYS0oLispJCMnLCBXUF9DTElfVkVSU0lPTiwgJG1hdGNoZXMgKSApIHsKCQkJJHZlcnNpb25fdXJsID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvYnVpbGRzL2doLXBhZ2VzL3BoYXIvTklHSFRMWV9WRVJTSU9OJzsKCQkJJHJlc3BvbnNlICAgID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHZlcnNpb25fdXJsLCBudWxsLCBbXSwgJG9wdGlvbnMgKTsKCQkJaWYgKCAhICRyZXNwb25zZS0+c3VjY2VzcyB8fCAyMDAgIT09ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnRmFpbGVkIHRvIGdldCBjdXJyZW50IG5pZ2h0bHkgdmVyc2lvbiAoSFRUUCBjb2RlICVkKScsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSApOwoJCQl9CgkJCSRuaWdodGx5X3ZlcnNpb24gPSB0cmltKCAkcmVzcG9uc2UtPmJvZHkgKTsKCQkJaWYgKCBXUF9DTElfVkVSU0lPTiAhPT0gJG5pZ2h0bHlfdmVyc2lvbiApIHsKCQkJCSR1cGRhdGVzWyduaWdodGx5J10gPSBbCgkJCQkJJ3ZlcnNpb24nICAgICA9PiAkbmlnaHRseV92ZXJzaW9uLAoJCQkJCSd1cGRhdGVfdHlwZScgPT4gJ25pZ2h0bHknLAoJCQkJCSdwYWNrYWdlX3VybCcgPT4gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS93cC1jbGkvYnVpbGRzL2doLXBhZ2VzL3BoYXIvd3AtY2xpLW5pZ2h0bHkucGhhcicsCgkJCQldOwoJCQl9CgkJfQoKCQlyZXR1cm4gYXJyYXlfdmFsdWVzKCAkdXBkYXRlcyApOwoJfQoKCS8qKgoJICogRHVtcHMgdGhlIGxpc3Qgb2YgZ2xvYmFsIHBhcmFtZXRlcnMsIGFzIEpTT04gb3IgaW4gdmFyX2V4cG9ydCBmb3JtYXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXdpdGgtdmFsdWVzXQoJICogOiBEaXNwbGF5IGN1cnJlbnQgdmFsdWVzIGFsc28uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGpzb24KCSAqIG9wdGlvbnM6CgkgKiAgIC0gdmFyX2V4cG9ydAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRHVtcCB0aGUgbGlzdCBvZiBnbG9iYWwgcGFyYW1ldGVycy4KCSAqICAgICAkIHdwIGNsaSBwYXJhbS1kdW1wIC0tZm9ybWF0PXZhcl9leHBvcnQKCSAqICAgICBhcnJheSAoCgkgKiAgICAgICAncGF0aCcgPT4KCSAqICAgICAgIGFycmF5ICgKCSAqICAgICAgICAgJ3J1bnRpbWUnID0+ICc9PHBhdGg+JywKCSAqICAgICAgICAgJ2ZpbGUnID0+ICc8cGF0aD4nLAoJICogICAgICAgICAnc3lub3BzaXMnID0+ICcnLAoJICogICAgICAgICAnZGVmYXVsdCcgPT4gTlVMTCwKCSAqICAgICAgICAgJ211bHRpcGxlJyA9PiBmYWxzZSwKCSAqICAgICAgICAgJ2Rlc2MnID0+ICdQYXRoIHRvIHRoZSBXb3JkUHJlc3MgZmlsZXMuJywKCSAqICAgICAgICksCgkgKiAgICAgICAndXJsJyA9PgoJICogICAgICAgYXJyYXkgKAoJICoKCSAqIEBzdWJjb21tYW5kIHBhcmFtLWR1bXAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhcmFtX2R1bXAoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkc3BlYyA9IFdQX0NMSTo6Z2V0X2NvbmZpZ3VyYXRvcigpLT5nZXRfc3BlYygpOwoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3dpdGgtdmFsdWVzJyApICkgewoJCQkkY29uZmlnID0gV1BfQ0xJOjpnZXRfY29uZmlndXJhdG9yKCktPnRvX2FycmF5KCk7CgkJCS8vIENvcHkgY3VycmVudCBjb25maWcgdmFsdWVzIHRvICRzcGVjLgoJCQlmb3JlYWNoICggJHNwZWMgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCQkkY3VycmVudCA9IG51bGw7CgkJCQlpZiAoIGlzc2V0KCAkY29uZmlnWzBdWyAka2V5IF0gKSApIHsKCQkJCQkkY3VycmVudCA9ICRjb25maWdbMF1bICRrZXkgXTsKCQkJCX0KCQkJCSRzcGVjWyAka2V5IF1bJ2N1cnJlbnQnXSA9ICRjdXJyZW50OwoJCQl9CgkJfQoKCQlpZiAoICd2YXJfZXhwb3J0JyA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApICkgewoJCQl2YXJfZXhwb3J0KCAkc3BlYyApOwoJCX0gZWxzZSB7CgkJCWVjaG8ganNvbl9lbmNvZGUoICRzcGVjICk7CgkJfQoJfQoKCS8qKgoJICogRHVtcHMgdGhlIGxpc3Qgb2YgaW5zdGFsbGVkIGNvbW1hbmRzLCBhcyBKU09OLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRHVtcCB0aGUgbGlzdCBvZiBpbnN0YWxsZWQgY29tbWFuZHMuCgkgKiAgICAgJCB3cCBjbGkgY21kLWR1bXAKCSAqICAgICB7Im5hbWUiOiJ3cCIsImRlc2NyaXB0aW9uIjoiTWFuYWdlIFdvcmRQcmVzcyB0aHJvdWdoIHRoZSBjb21tYW5kLWxpbmUuIiwibG9uZ2Rlc2MiOiJcblxuIyMgR0xPQkFMIFBBUkFNRVRFUlNcblxuICAtLXBhdGg9PHBhdGg+XG4gICAgICBQYXRoIHRvIHRoZSBXb3JkUHJlc3MgZmlsZXMuXG5cbiAgLS1zc2g9PHNzaD5cbiAgICAgIFBlcmZvcm0gb3BlcmF0aW9uIGFnYWluc3QgYSByZW1vdGUgc2VydmVyIG92ZXIgU1NIIChvciBhIGNvbnRhaW5lciB1c2luZyBzY2hlbWUgb2YgImRvY2tlciIgb3IgImRvY2tlci1jb21wb3NlIikuXG5cbiAgLS11cmw9PHVybD5cbiAgICAgIFByZXRlbmQgcmVxdWVzdCBjYW1lIGZyb20gZ2l2ZW4gVVJMLiBJbiBtdWx0aXNpdGUsIHRoaXMgYXJndW1lbnQgaXMgaG93IHRoZSB0YXJnZXQgc2l0ZSBpcyBzcGVjaWZpZWQuIFxuXG4gIC0tdXNlcj08aWR8bG9naW58ZW1haWw+XG4KCSAqCgkgKiBAc3ViY29tbWFuZCBjbWQtZHVtcAoJICovCglwdWJsaWMgZnVuY3Rpb24gY21kX2R1bXAoKSB7CgkJZWNobyBqc29uX2VuY29kZSggJHRoaXMtPmNvbW1hbmRfdG9fYXJyYXkoIFdQX0NMSTo6Z2V0X3Jvb3RfY29tbWFuZCgpICkgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyB0YWIgY29tcGxldGlvbiBzdHJpbmdzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiAtLWxpbmU9PGxpbmU+CgkgKiA6IFRoZSBjdXJyZW50IGNvbW1hbmQgbGluZSB0byBiZSBleGVjdXRlZC4KCSAqCgkgKiAtLXBvaW50PTxwb2ludD4KCSAqIDogVGhlIGluZGV4IHRvIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjb21tYW5kLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgdGFiIGNvbXBsZXRpb24gc3RyaW5ncy4KCSAqICAgICAkIHdwIGNsaSBjb21wbGV0aW9ucyAtLWxpbmU9J3dwIGV2YScgLS1wb2ludD0xMDAKCSAqICAgICBldmFsCgkgKiAgICAgZXZhbC1maWxlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjb21wbGV0aW9ucyggJF8sICRhc3NvY19hcmdzICkgewoJCSRsaW5lICA9IHN1YnN0ciggJGFzc29jX2FyZ3NbJ2xpbmUnXSwgMCwgJGFzc29jX2FyZ3NbJ3BvaW50J10gKTsKCQkkY29tcGwgPSBuZXcgQ29tcGxldGlvbnMoICRsaW5lICk7CgkJJGNvbXBsLT5yZW5kZXIoKTsKCX0KCgkvKioKCSAqIEdldCBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgdXBkYXRlIGJlaW5nIGNoZWNrZWQgZm9yLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF91cGRhdGVfdHlwZV9zdHIoICRhc3NvY19hcmdzICkgewoJCSR1cGRhdGVfdHlwZSA9ICcgJzsKCQlmb3JlYWNoICggWyAnbWFqb3InLCAnbWlub3InLCAncGF0Y2gnIF0gYXMgJHR5cGUgKSB7CgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAkdHlwZSApICkgewoJCQkJJHVwZGF0ZV90eXBlID0gJyAnIC4gJHR5cGUgLiAnICc7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyZXR1cm4gJHVwZGF0ZV90eXBlOwoJfQoKCS8qKgoJICogRGV0ZWN0cyBpZiBhIGNvbW1hbmQgZXhpc3RzCgkgKgoJICogVGhpcyBjb21tYW5kcyBjaGVja3MgaWYgYSBjb21tYW5kIGlzIHJlZ2lzdGVyZWQgd2l0aCBXUC1DTEkuCgkgKiBJZiB0aGUgY29tbWFuZCBpcyBmb3VuZCB0aGVuIGl0IHJldHVybnMgd2l0aCBleGl0IHN0YXR1cyAwLgoJICogSWYgdGhlIGNvbW1hbmQgZG9lc24ndCBleGlzdCwgdGhlbiBpdCB3aWxsIGV4aXQgd2l0aCBzdGF0dXMgMS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKiA8Y29tbWFuZF9uYW1lPi4uLgoJICogOiBUaGUgY29tbWFuZAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVGhlICJzaXRlIGRlbGV0ZSIgY29tbWFuZCBpcyByZWdpc3RlcmVkLgoJICogICAgICQgd3AgY2xpIGhhcy1jb21tYW5kICJzaXRlIGRlbGV0ZSIKCSAqICAgICAkIGVjaG8gJD8KCSAqICAgICAwCgkgKgoJICogICAgICMgVGhlICJmb28gYmFyIiBjb21tYW5kIGlzIG5vdCByZWdpc3RlcmVkLgoJICogICAgICQgd3AgY2xpIGhhcy1jb21tYW5kICJmb28gYmFyIgoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBoYXMtY29tbWFuZAoJICoKCSAqIEB3aGVuIGFmdGVyX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhhc19jb21tYW5kKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCS8vIElmIGNvbW1hbmQgaXMgaW5wdXQgYXMgYSBzdHJpbmcsIHRoZW4gZXhwbG9kZSBpdCBpbnRvIGFycmF5LgoJCSRjb21tYW5kID0gZXhwbG9kZSggJyAnLCBpbXBsb2RlKCAnICcsICRfICkgKTsKCgkJV1BfQ0xJOjpoYWx0KCBpc19hcnJheSggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmZpbmRfY29tbWFuZF90b19ydW4oICRjb21tYW5kICkgKSA/IDAgOiAxICk7Cgl9Cn0KPD9waHAKCi8qKgogKiBNYW5hZ2VzIHRoZSBpbnRlcm5hbCBXUC1DTEkgY2FjaGUsLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBSZW1vdmUgYWxsIGNhY2hlZCBmaWxlcy4KICogICAgICQgd3AgY2xpIGNhY2hlIGNsZWFyCiAqICAgICBTdWNjZXNzOiBDYWNoZSBjbGVhcmVkLgogKgogKiAgICAgIyBSZW1vdmUgYWxsIGNhY2hlZCBmaWxlcyBleGNlcHQgZm9yIHRoZSBuZXdlc3QgdmVyc2lvbiBvZiBlYWNoIG9uZS4KICogICAgICQgd3AgY2xpIGNhY2hlIHBydW5lCiAqICAgICBTdWNjZXNzOiBDYWNoZSBwcnVuZWQuCiAqCiAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCiAqLwpjbGFzcyBDTElfQ2FjaGVfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIENsZWFycyB0aGUgaW50ZXJuYWwgY2FjaGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBjbGkgY2FjaGUgY2xlYXIKCSAqICAgICBTdWNjZXNzOiBDYWNoZSBjbGVhcmVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGNsZWFyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjYWNoZV9jbGVhcigpIHsKCQkkY2FjaGUgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoKCQlpZiAoICEgJGNhY2hlLT5pc19lbmFibGVkKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDYWNoZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QuJyApOwoJCX0KCgkJJGNhY2hlLT5jbGVhcigpOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdDYWNoZSBjbGVhcmVkLicgKTsKCX0KCgkvKioKCSAqIFBydW5lcyB0aGUgaW50ZXJuYWwgY2FjaGUuCgkgKgoJICogUmVtb3ZlcyBhbGwgY2FjaGVkIGZpbGVzIGV4Y2VwdCBmb3IgdGhlIG5ld2VzdCB2ZXJzaW9uIG9mIGVhY2ggb25lLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgY2xpIGNhY2hlIHBydW5lCgkgKiAgICAgU3VjY2VzczogQ2FjaGUgcHJ1bmVkLgoJICoKCSAqIEBzdWJjb21tYW5kIHBydW5lCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjYWNoZV9wcnVuZSgpIHsKCQkkY2FjaGUgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoKCQlpZiAoICEgJGNhY2hlLT5pc19lbmFibGVkKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDYWNoZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QuJyApOwoJCX0KCgkJJGNhY2hlLT5wcnVuZSgpOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdDYWNoZSBwcnVuZWQuJyApOwoJfQp9Cjw/cGhwCgp1c2UgY2xpXFNoZWxsOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXI7CnVzZSBXUF9DTElcVXRpbHM7CgpjbGFzcyBIZWxwX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBHZXRzIGhlbHAgb24gV1AtQ0xJLCBvciBvbiBhIHNwZWNpZmljIGNvbW1hbmQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8Y29tbWFuZD4uLi5dCgkgKiA6IEdldCBoZWxwIG9uIGEgc3BlY2lmaWMgY29tbWFuZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIGdldCBoZWxwIGZvciBgY29yZWAgY29tbWFuZAoJICogICAgIHdwIGhlbHAgY29yZQoJICoKCSAqICAgICAjIGdldCBoZWxwIGZvciBgY29yZSBkb3dubG9hZGAgc3ViY29tbWFuZAoJICogICAgIHdwIGhlbHAgY29yZSBkb3dubG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkciA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5maW5kX2NvbW1hbmRfdG9fcnVuKCAkYXJncyApOwoKCQlpZiAoIGlzX2FycmF5KCAkciApICkgewoJCQlsaXN0KCAkY29tbWFuZCApID0gJHI7CgoJCQlzZWxmOjpzaG93X2hlbHAoICRjb21tYW5kICk7CgkJCWV4aXQ7CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHNob3dfaGVscCggJGNvbW1hbmQgKSB7CgkJJG91dCA9IHNlbGY6OmdldF9pbml0aWFsX21hcmtkb3duKCAkY29tbWFuZCApOwoKCQkvLyBSZW1vdmUgc3ViY29tbWFuZHMgaWYgaW4gY29sdW1ucyAtIHdpbGwgd29yZHdyYXAgc2VwYXJhdGVseS4KCQkkc3ViY29tbWFuZHMgICAgICAgPSAnJzsKCQkkY29sdW1uX3N1YnBhdHRlcm4gPSAnWyBcdF0rW15cdF0rXHQrJzsKCQlpZiAoIHByZWdfbWF0Y2goICcvKF4jIyBTVUJDT01NQU5EU1teXG5dKlxuKycgLiAkY29sdW1uX3N1YnBhdHRlcm4gLiAnLis/KSg/Ol4jI3xceikvbXMnLCAkb3V0LCAkbWF0Y2hlcywgUFJFR19PRkZTRVRfQ0FQVFVSRSApICkgewoJCQkkc3ViY29tbWFuZHMgICAgICAgID0gJG1hdGNoZXNbMV1bMF07CgkJCSRzdWJjb21tYW5kc19oZWFkZXIgPSAiIyMgU1VCQ09NTUFORFNcbiI7CgkJCSRvdXQgICAgICAgICAgICAgICAgPSBzdWJzdHJfcmVwbGFjZSggJG91dCwgJHN1YmNvbW1hbmRzX2hlYWRlciwgJG1hdGNoZXNbMV1bMV0sIHN0cmxlbiggJHN1YmNvbW1hbmRzICkgKTsKCQl9CgoJCSRvdXQgLj0gc2VsZjo6cGFyc2VfcmVmZXJlbmNlX2xpbmtzKCAkY29tbWFuZC0+Z2V0X2xvbmdkZXNjKCkgKTsKCgkJLy8gRGVmaW5pdGlvbiBsaXN0cy4KCQkkb3V0ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCAnLyhbXlxuXSspXG46ICguKz8pKFxuXG58JCkvcycsIFsgX19DTEFTU19fLCAncmV3cmFwX3BhcmFtX2Rlc2MnIF0sICRvdXQgKTsKCgkJLy8gRW5zdXJlIGxpbmVzIHdpdGggbm8gbGVhZGluZyB3aGl0ZXNwYWNlIHRoYXQgYXJlbid0IHNlY3Rpb24gaGVhZGVycyBhcmUgaW5kZW50ZWQuCgkJJG91dCA9IHByZWdfcmVwbGFjZSggJy9eKCg/ISB8XHR8IyMpLikvbScsICJcdCQxIiwgJG91dCApOwoKCQkkdGFiID0gc3RyX3JlcGVhdCggJyAnLCAyICk7CgoJCS8vIE5lZWQgdG8gZGUtdGFiIGZvciB3b3Jkd3JhcHBpbmcgdG8gd29yayBwcm9wZXJseS4KCQkkb3V0ID0gc3RyX3JlcGxhY2UoICJcdCIsICR0YWIsICRvdXQgKTsKCgkJJHdvcmR3cmFwX3dpZHRoID0gU2hlbGw6OmNvbHVtbnMoKTsKCgkJLy8gV29yZHdyYXAgd2l0aCBpbmRlbnQuCgkJJG91dCA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygKCQkJJy9eKCAqKShbXlxuXSspXG4vbScsCgkJCWZ1bmN0aW9uICggJG1hdGNoZXMgKSB1c2UgKCAkd29yZHdyYXBfd2lkdGggKSB7CgkJCQlyZXR1cm4gJG1hdGNoZXNbMV0gLiBzdHJfcmVwbGFjZSggIlxuIiwgIlxueyRtYXRjaGVzWzFdfSIsIHdvcmR3cmFwKCAkbWF0Y2hlc1syXSwgJHdvcmR3cmFwX3dpZHRoIC0gc3RybGVuKCAkbWF0Y2hlc1sxXSApICkgKSAuICJcbiI7CgkJCX0sCgkJCSRvdXQKCQkpOwoKCQlpZiAoICRzdWJjb21tYW5kcyApIHsKCQkJLy8gV29yZHdyYXAgd2l0aCBjb2x1bW4gaW5kZW50LgoJCQkkc3ViY29tbWFuZHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCgkJCQknL14oJyAuICRjb2x1bW5fc3VicGF0dGVybiAuICcpKFteXG5dKylcbi9tJywKCQkJCWZ1bmN0aW9uICggJG1hdGNoZXMgKSB1c2UgKCAkd29yZHdyYXBfd2lkdGgsICR0YWIgKSB7CgkJCQkJLy8gTmVlZCB0byBkZS10YWIgZm9yIHdvcmR3cmFwcGluZyB0byB3b3JrIHByb3Blcmx5LgoJCQkJCSRtYXRjaGVzWzFdICA9IHN0cl9yZXBsYWNlKCAiXHQiLCAkdGFiLCAkbWF0Y2hlc1sxXSApOwoJCQkJCSRtYXRjaGVzWzJdICA9IHN0cl9yZXBsYWNlKCAiXHQiLCAkdGFiLCAkbWF0Y2hlc1syXSApOwoJCQkJCSRwYWRkaW5nX2xlbiA9IHN0cmxlbiggJG1hdGNoZXNbMV0gKTsKCQkJCQkkcGFkZGluZyAgICAgPSBzdHJfcmVwZWF0KCAnICcsICRwYWRkaW5nX2xlbiApOwoJCQkJCXJldHVybiAkbWF0Y2hlc1sxXSAuIHN0cl9yZXBsYWNlKCAiXG4iLCAiXG4kcGFkZGluZyIsIHdvcmR3cmFwKCAkbWF0Y2hlc1syXSwgJHdvcmR3cmFwX3dpZHRoIC0gJHBhZGRpbmdfbGVuICkgKSAuICJcbiI7CgkJCQl9LAoJCQkJJHN1YmNvbW1hbmRzCgkJCSk7CgoJCQkvLyBQdXQgc3ViY29tbWFuZHMgYmFjay4KCQkJJG91dCA9IHN0cl9yZXBsYWNlKCAkc3ViY29tbWFuZHNfaGVhZGVyLCAkc3ViY29tbWFuZHMsICRvdXQgKTsKCQl9CgoJCS8vIFNlY3Rpb24gaGVhZGVycy4KCQkkb3V0ID0gcHJlZ19yZXBsYWNlKCAnL14jIyAoW0EtWiBdKykvbScsIFdQX0NMSTo6Y29sb3JpemUoICclOVwxJW4nICksICRvdXQgKTsKCgkJc2VsZjo6cGFzc190aHJvdWdoX3BhZ2VyKCAkb3V0ICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcmV3cmFwX3BhcmFtX2Rlc2MoICRtYXRjaGVzICkgewoJCSRwYXJhbSA9ICRtYXRjaGVzWzFdOwoJCSRkZXNjICA9IHNlbGY6OmluZGVudCggIlx0XHQiLCAkbWF0Y2hlc1syXSApOwoJCXJldHVybiAiXHQkcGFyYW1cbiRkZXNjXG5cbiI7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5kZW50KCAkd2hpdGVzcGFjZSwgJHRleHQgKSB7CgkJJGxpbmVzID0gZXhwbG9kZSggIlxuIiwgJHRleHQgKTsKCQlmb3JlYWNoICggJGxpbmVzIGFzICYkbGluZSApIHsKCQkJJGxpbmUgPSAkd2hpdGVzcGFjZSAuICRsaW5lOwoJCX0KCQlyZXR1cm4gaW1wbG9kZSggIlxuIiwgJGxpbmVzICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcGFzc190aHJvdWdoX3BhZ2VyKCAkb3V0ICkgewoKCQlpZiAoICEgVXRpbHNcY2hlY2tfcHJvY19hdmFpbGFibGUoIG51bGwgLypjb250ZXh0Ki8sIHRydWUgLypyZXR1cm4qLyApICkgewoJCQlXUF9DTEk6OmxpbmUoICRvdXQgKTsKCQkJV1BfQ0xJOjpkZWJ1ZyggJ1dhcm5pbmc6IGNoZWNrX3Byb2NfYXZhaWxhYmxlKCkgZmFpbGVkIGluIHBhc3NfdGhyb3VnaF9wYWdlcigpLicsICdoZWxwJyApOwoJCQlyZXR1cm4gLTE7CgkJfQoKCQkkcGFnZXIgPSBnZXRlbnYoICdQQUdFUicgKTsKCQlpZiAoIGZhbHNlID09PSAkcGFnZXIgKSB7CgkJCSRwYWdlciA9IFV0aWxzXGlzX3dpbmRvd3MoKSA/ICdtb3JlJyA6ICdsZXNzIC1yJzsKCQl9CgoJCS8vIEZvciBXaW5kb3dzIDcgbmVlZCB0byBzZXQgY29kZSBwYWdlIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIFVuaWNvZGUgKDY1MDAxKSB0byBnZXQgYXJvdW5kICJOb3QgZW5vdWdoIG1lbW9yeS4iIGVycm9yIHdpdGggYG1vcmUuY29tYCBvbiBQSFAgNy4xKy4KCQlpZiAoICdtb3JlJyA9PT0gJHBhZ2VyICYmIGRlZmluZWQoICdQSFBfV0lORE9XU19WRVJTSU9OX01BSk9SJyApICYmIFBIUF9XSU5ET1dTX1ZFUlNJT05fTUFKT1IgPCAxMCAmJiBmdW5jdGlvbl9leGlzdHMoICdzYXBpX3dpbmRvd3NfY3Bfc2V0JyApICkgewoJCQkvLyBOb3RlIHdpbGwgYWxzbyBhcHBseSB0byBXaW5kb3dzIDggKHNlZSBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L3dpbmRvd3MvZGVza3RvcC9tczcyNDgzMi5hc3B4KSBidXQgcHJvYmFibHkgaGFybWxlc3MgYW55d2F5LgoJCQkkY3AgPSBnZXRlbnYoICdXUF9DTElfV0lORE9XU19DT0RFX1BBR0UnICkgPzogMTI1MjsgLy8gQ29kZSBwYWdlIDEyNTIgaXMgdGhlIG1vc3QgdXNlZCBzbyBwcm9iYWJseSB0aGUgbW9zdCBjb21wYXQuCgkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkZ1bmN0aW9uVXNlLk5ld0Z1bmN0aW9ucyAtLSBXcmFwcGVkIGluIGZ1bmN0aW9uX2V4aXN0cygpIGNhbGwuCgkJCXNhcGlfd2luZG93c19jcF9zZXQoICRjcCApOyAvLyBgc2FwaV93aW5kb3dzX2NwX3NldCgpYCBpbnRyb2R1Y2VkIFBIUCA3LjEuCgkJfQoKCQkvLyBDb252ZXJ0IHN0cmluZyB0byBmaWxlIGhhbmRsZS4KCQkkZmQgPSBmb3BlbiggJ3BocDovL3RlbXAnLCAncitiJyApOwoJCWZ3cml0ZSggJGZkLCAkb3V0ICk7CgkJcmV3aW5kKCAkZmQgKTsKCgkJJGRlc2NyaXB0b3JzcGVjID0gWwoJCQkwID0+ICRmZCwKCQkJMSA9PiBTVERPVVQsCgkJCTIgPT4gU1RERVJSLAoJCV07CgoJCXJldHVybiBwcm9jX2Nsb3NlKCBVdGlsc1xwcm9jX29wZW5fY29tcGF0KCAkcGFnZXIsICRkZXNjcmlwdG9yc3BlYywgJHBpcGVzICkgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfaW5pdGlhbF9tYXJrZG93biggJGNvbW1hbmQgKSB7CgkJJG5hbWUgPSBpbXBsb2RlKCAnICcsIERpc3BhdGNoZXJcZ2V0X3BhdGgoICRjb21tYW5kICkgKTsKCgkJJGJpbmRpbmcgPSBbCgkJCSduYW1lJyAgICAgID0+ICRuYW1lLAoJCQknc2hvcnRkZXNjJyA9PiAkY29tbWFuZC0+Z2V0X3Nob3J0ZGVzYygpLAoJCV07CgoJCSRiaW5kaW5nWydzeW5vcHNpcyddID0gIiRuYW1lICIgLiAkY29tbWFuZC0+Z2V0X3N5bm9wc2lzKCk7CgoJCSRhbGlhcyA9ICRjb21tYW5kLT5nZXRfYWxpYXMoKTsKCQlpZiAoICRhbGlhcyApIHsKCQkJJGJpbmRpbmdbJ2FsaWFzJ10gPSAkYWxpYXM7CgkJfQoKCQlpZiAoICRjb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcygpICkgewoJCQkkYmluZGluZ1snaGFzLXN1YmNvbW1hbmRzJ11bJ3N1YmNvbW1hbmRzJ10gPSBzZWxmOjpyZW5kZXJfc3ViY29tbWFuZHMoICRjb21tYW5kICk7CgkJfQoKCQlyZXR1cm4gVXRpbHNcbXVzdGFjaGVfcmVuZGVyKCAnbWFuLm11c3RhY2hlJywgJGJpbmRpbmcgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiByZW5kZXJfc3ViY29tbWFuZHMoICRjb21tYW5kICkgewoJCSRzdWJjb21tYW5kcyA9IFtdOwoJCWZvcmVhY2ggKCAkY29tbWFuZC0+Z2V0X3N1YmNvbW1hbmRzKCkgYXMgJHN1YmNvbW1hbmQgKSB7CgoJCQlpZiAoIFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5pc19jb21tYW5kX2Rpc2FibGVkKCAkc3ViY29tbWFuZCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRzdWJjb21tYW5kc1sgJHN1YmNvbW1hbmQtPmdldF9uYW1lKCkgXSA9ICRzdWJjb21tYW5kLT5nZXRfc2hvcnRkZXNjKCk7CgkJfQoKCQkkbWF4X2xlbiA9IHNlbGY6OmdldF9tYXhfbGVuKCBhcnJheV9rZXlzKCAkc3ViY29tbWFuZHMgKSApOwoKCQkkbGluZXMgPSBbXTsKCQlmb3JlYWNoICggJHN1YmNvbW1hbmRzIGFzICRuYW1lID0+ICRkZXNjICkgewoJCQkkbGluZXNbXSA9IHN0cl9wYWQoICRuYW1lLCAkbWF4X2xlbiApIC4gIlx0XHRcdCIgLiAkZGVzYzsKCQl9CgoJCXJldHVybiAkbGluZXM7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X21heF9sZW4oICRzdHJpbmdzICkgewoJCSRtYXhfbGVuID0gMDsKCQlmb3JlYWNoICggJHN0cmluZ3MgYXMgJHN0ciApIHsKCQkJJGxlbiA9IHN0cmxlbiggJHN0ciApOwoJCQlpZiAoICRsZW4gPiAkbWF4X2xlbiApIHsKCQkJCSRtYXhfbGVuID0gJGxlbjsKCQkJfQoJCX0KCgkJcmV0dXJuICRtYXhfbGVuOwoJfQoKCS8qKgoJICogUGFyc2UgcmVmZXJlbmNlIGxpbmtzIGZyb20gbG9uZ2Rlc2NyaXB0aW9uLgoJICoKCSAqIEBwYXJhbSAgc3RyaW5nICRsb25nZGVzYyBUaGUgbG9uZ2Rlc2NyaXB0aW9uIGZyb20gdGhlIGAkY29tbWFuZC0+Z2V0X2xvbmdkZXNjKClgLgoJICogQHJldHVybiBzdHJpbmcgVGhlIGxvbmdkZXNjcmlwdGlvbiB3aGljaCBoYXMgbGlua3MgYXMgZm9vdG5vdGUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBhcnNlX3JlZmVyZW5jZV9saW5rcyggJGxvbmdkZXNjICkgewoJCSRkZXNjcmlwdGlvbiA9ICcnOwoJCWZvcmVhY2ggKCBleHBsb2RlKCAiXG4iLCAkbG9uZ2Rlc2MgKSBhcyAkbGluZSApIHsKCQkJaWYgKCAwID09PSBzdHJwb3MoICRsaW5lLCAnIycgKSApIHsKCQkJCWJyZWFrOwoJCQl9CgkJCSRkZXNjcmlwdGlvbiAuPSAkbGluZSAuICJcbiI7CgkJfQoKCQkvLyBGaXJlcyBpZiBpdCBoYXMgZGVzY3JpcHRpb24gdGV4dCBhdCB0aGUgaGVhZCBvZiBgJGxvbmdkZXNjYC4KCQlpZiAoICRkZXNjcmlwdGlvbiApIHsKCQkJJGxpbmtzICAgPSBbXTsgLy8gQW4gYXJyYXkgb2YgVVJMcyBmcm9tIHRoZSBkZXNjcmlwdGlvbi4KCQkJJHBhdHRlcm4gPSAnL1xbLis/XF1cKChodHRwcz86XC9cLy4rPylcKS8nOwoJCQkkbmV3ZGVzYyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygKCQkJCSRwYXR0ZXJuLAoJCQkJZnVuY3Rpb24oICRtYXRjaGVzICkgdXNlICggJiRsaW5rcyApIHsKCQkJCQlzdGF0aWMgJGNvdW50ID0gMDsKCQkJCQkkY291bnQrKzsKCQkJCQkkbGlua3NbXSA9ICRtYXRjaGVzWzFdOwoJCQkJCXJldHVybiBzdHJfcmVwbGFjZSggJygnIC4gJG1hdGNoZXNbMV0gLiAnKScsICdbJyAuICRjb3VudCAuICddJywgJG1hdGNoZXNbMF0gKTsKCQkJCX0sCgkJCQkkZGVzY3JpcHRpb24KCQkJKTsKCgkJCSRmb290bm90ZSAgID0gJyc7CgkJCSRsaW5rX2NvdW50ID0gY291bnQoICRsaW5rcyApOwoJCQlmb3IgKCAkaSA9IDA7ICRpIDwgJGxpbmtfY291bnQ7ICRpKysgKSB7CgkJCQkkbiAgICAgICAgID0gJGkgKyAxOwoJCQkJJGZvb3Rub3RlIC49ICdbJyAuICRuIC4gJ10gJyAuICRsaW5rc1sgJGkgXSAuICJcbiI7CgkJCX0KCgkJCWlmICggJGZvb3Rub3RlICkgewoJCQkJJG5ld2Rlc2MgID0gdHJpbSggJG5ld2Rlc2MgKSAuICJcblxuLS0tXG4iIC4gJGZvb3Rub3RlOwoJCQkJJGxvbmdkZXNjID0gc3RyX3JlcGxhY2UoIHRyaW0oICRkZXNjcmlwdGlvbiApLCB0cmltKCAkbmV3ZGVzYyApLCAkbG9uZ2Rlc2MgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRsb25nZGVzYzsKCX0KfQo8P3BocAoKLyoqCiAqIFJldHJpZXZlcywgc2V0cyBhbmQgdXBkYXRlcyBhbGlhc2VzIGZvciBXb3JkUHJlc3MgSW5zdGFsbGF0aW9ucy4KICovCgp1c2UgTXVzdGFuZ29zdGFuZ1xTcHljOwp1c2UgV1BfQ0xJXEV4aXRFeGNlcHRpb247CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmV0cmlldmVzLCBzZXRzIGFuZCB1cGRhdGVzIGFsaWFzZXMgZm9yIFdvcmRQcmVzcyBJbnN0YWxsYXRpb25zLgogKgogKiBBbGlhc2VzIGFyZSBzaG9ydGhhbmQgcmVmZXJlbmNlcyB0byBXb3JkUHJlc3MgaW5zdGFsbHMuIEZvciBpbnN0YW5jZSwKICogYEBkZXZgIGNvdWxkIHJlZmVyIHRvIGEgZGV2ZWxvcG1lbnQgaW5zdGFsbCBhbmQgYEBwcm9kYCBjb3VsZCByZWZlciB0byBhIHByb2R1Y3Rpb24gaW5zdGFsbC4KICogVGhpcyBjb21tYW5kIGdpdmVzIHlvdSBhbmQgb3B0aW9uIHRvIGFkZCwgdXBkYXRlIGFuZCBkZWxldGUsIHRoZSByZWdpc3RlcmVkIGFsaWFzZXMgeW91IGhhdmUgYXZhaWxhYmxlLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGFsaWFzIGluZm9ybWF0aW9uLgogKiAgICAgJCB3cCBjbGkgYWxpYXMgbGlzdAogKiAgICAgbGlzdAogKiAgICAgLS0tCiAqICAgICBAYWxsOiBSdW4gY29tbWFuZCBhZ2FpbnN0IGV2ZXJ5IHJlZ2lzdGVyZWQgYWxpYXMuCiAqICAgICBAbG9jYWw6CiAqICAgICAgIHVzZXI6IHdwY2xpCiAqICAgICAgIHBhdGg6IC9Vc2Vycy93cGNsaS9zaXRlcy90ZXN0c2l0ZQogKgogKiAgICAgIyBHZXQgYWxpYXMgaW5mb3JtYXRpb24uCiAqICAgICAkIHdwIGNsaSBhbGlhcyBnZXQgQGRldgogKiAgICAgc3NoOiBkZXZAc29tZWRldmUuZW52OjEyMzQ1L2hvbWUvZGV2LwogKgogKiAgICAgIyBBZGQgYWxpYXMuCiAqICAgICAkIHdwIGNsaSBhbGlhcyBhZGQgQHByb2QgLS1zZXQtc3NoPWxvZ2luQGhvc3QgLS1zZXQtcGF0aD0vcGF0aC90by93b3JkcHJlc3MvaW5zdGFsbC8gLS1zZXQtdXNlcj13cGNsaQogKiAgICAgU3VjY2VzczogQWRkZWQgJ0Bwcm9kJyBhbGlhcy4KICoKICogICAgICMgVXBkYXRlIGFsaWFzLgogKiAgICAgJCB3cCBjbGkgYWxpYXMgdXBkYXRlIEBwcm9kIC0tc2V0LXVzZXI9bmV3dXNlciAtLXNldC1wYXRoPS9uZXcvcGF0aC90by93b3JkcHJlc3MvaW5zdGFsbC8KICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ3Byb2QnIGFsaWFzLgogKgogKiAgICAgIyBEZWxldGUgYWxpYXMuCiAqICAgICAkIHdwIGNsaSBhbGlhcyBkZWxldGUgQHByb2QKICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ0Bwcm9kJyBhbGlhcy4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqIEB3aGVuICAgIGJlZm9yZV93cF9sb2FkCiAqLwpjbGFzcyBDTElfQWxpYXNfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIExpc3RzIGF2YWlsYWJsZSBXUC1DTEkgYWxpYXNlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHlhbWwKCSAqIG9wdGlvbnM6CgkgKiAgIC0geWFtbAoJICogICAtIGpzb24KCSAqICAgLSB2YXJfZXhwb3J0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgYWxsIGF2YWlsYWJsZSBhbGlhc2VzLgoJICogICAgICQgd3AgY2xpIGFsaWFzIGxpc3QKCSAqICAgICAtLS0KCSAqICAgICBAYWxsOiBSdW4gY29tbWFuZCBhZ2FpbnN0IGV2ZXJ5IHJlZ2lzdGVyZWQgYWxpYXMuCgkgKiAgICAgQHByb2Q6CgkgKiAgICAgICBzc2g6IHJ1bmNvbW1hbmRAcnVuY29tbWFuZC5pb34vd2ViYXBwcy9wcm9kdWN0aW9uCgkgKiAgICAgQGRldjoKCSAqICAgICAgIHNzaDogdmFncmFudEAxOTIuMTY4LjUwLjEwL3Nydi93d3cvcnVuY29tbWFuZC5kZXYKCSAqICAgICBAYm90aDoKCSAqICAgICAgIC0gQHByb2QKCSAqICAgICAgIC0gQGRldgoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJV1BfQ0xJOjpwcmludF92YWx1ZSggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmFsaWFzZXMsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB2YWx1ZSBmb3IgYW4gYWxpYXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIGFsaWFzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGFsaWFzLgoJICogICAgICQgd3AgY2xpIGFsaWFzIGdldCBAcHJvZAoJICogICAgIHNzaDogZGV2QHNvbWVkZXZlLmVudjoxMjM0NS9ob21lL2Rldi8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRhbGlhcyApID0gJGFyZ3M7CgoJCSRhbGlhc2VzID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmFsaWFzZXM7CgoJCWlmICggZW1wdHkoICRhbGlhc2VzWyAkYWxpYXMgXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiTm8gYWxpYXMgZm91bmQgd2l0aCBrZXkgJ3skYWxpYXN9Jy4iICk7CgkJfQoKCQlmb3JlYWNoICggJGFsaWFzZXNbICRhbGlhcyBdIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQlXUF9DTEk6OmxvZyggInska2V5fTogeyR2YWx1ZX0iICk7CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlcyBhbiBhbGlhcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgYWxpYXMuCgkgKgoJICogWy0tc2V0LXVzZXI9PHVzZXI+XQoJICogOiBTZXQgdXNlciBmb3IgYWxpYXMuCgkgKgoJICogWy0tc2V0LXVybD08dXJsPl0KCSAqIDogU2V0IHVybCBmb3IgYWxpYXMuCgkgKgoJICogWy0tc2V0LXBhdGg9PHBhdGg+XQoJICogOiBTZXQgcGF0aCBmb3IgYWxpYXMuCgkgKgoJICogWy0tc2V0LXNzaD08c3NoPl0KCSAqIDogU2V0IHNzaCBmb3IgYWxpYXMuCgkgKgoJICogWy0tc2V0LWh0dHA9PGh0dHA+XQoJICogOiBTZXQgaHR0cCBmb3IgYWxpYXMuCgkgKgoJICogWy0tZ3JvdXBpbmc9PGdyb3VwaW5nPl0KCSAqIDogRm9yIGdyb3VwaW5nIG11bHRpcGxlIGFsaWFzZXMuCgkgKgoJICogWy0tY29uZmlnPTxjb25maWc+XQoJICogOiBDb25maWcgZmlsZSB0byBiZSBjb25zaWRlcmVkIGZvciBvcGVyYXRpb25zLgoJICogLS0tCgkgKiBkZWZhdWx0OiBnbG9iYWwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gZ2xvYmFsCgkgKiAgIC0gcHJvamVjdAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBZGQgYWxpYXMgdG8gZ2xvYmFsIGNvbmZpZy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBhZGQgQHByb2QgIC0tc2V0LXNzaD1sb2dpbkBob3N0IC0tc2V0LXBhdGg9L3BhdGgvdG8vd29yZHByZXNzL2luc3RhbGwvIC0tc2V0LXVzZXI9d3BjbGkKCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnQHByb2QnIGFsaWFzLgoJICoKCSAqICAgICAjIEFkZCBhbGlhcyB0byBwcm9qZWN0IGNvbmZpZy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBhZGQgQHByb2QgLS1zZXQtc3NoPWxvZ2luQGhvc3QgLS1zZXQtcGF0aD0vcGF0aC90by93b3JkcHJlc3MvaW5zdGFsbC8gLS1zZXQtdXNlcj13cGNsaSAtLWNvbmZpZz1wcm9qZWN0CgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ0Bwcm9kJyBhbGlhcy4KCSAqCgkgKiAgICAgIyBBZGQgZ3JvdXAgb2YgYWxpYXNlcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBhZGQgQG11bHRpc2VydmVycyAtLWdyb3VwaW5nPXNlcnZlcmEsc2VydmVyYgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkICdAbXVsdGlzZXJ2ZXJzJyBhbGlhcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkY29uZmlnID0gKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snY29uZmlnJ10gKSA/ICRhc3NvY19hcmdzWydjb25maWcnXSA6ICdnbG9iYWwnICk7CgoJCWxpc3QoICRjb25maWdfcGF0aCwgJGFsaWFzZXMgKSA9ICR0aGlzLT5nZXRfYWxpYXNlc19kYXRhKCAkY29uZmlnLCAnJywgdHJ1ZSApOwoKCQkkdGhpcy0+dmFsaWRhdGVfY29uZmlnX2ZpbGUoICRjb25maWdfcGF0aCApOwoKCQkkYWxpYXMgICAgPSAkYXJnc1swXTsKCQkkZ3JvdXBpbmcgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdncm91cGluZycgKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2lucHV0KCAkYXNzb2NfYXJncywgJGdyb3VwaW5nICk7CgoJCWlmICggaXNzZXQoICRhbGlhc2VzWyAkYWxpYXMgXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiS2V5ICd7JGFsaWFzfScgZXhpc3RzIGFscmVhZHkuIiApOwoJCX0KCgkJaWYgKCBudWxsID09PSAkZ3JvdXBpbmcgKSB7CgkJCSRhbGlhc2VzID0gJHRoaXMtPmJ1aWxkX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCBmYWxzZSApOwoJCX0gZWxzZSB7CgkJCSRhbGlhc2VzID0gJHRoaXMtPmJ1aWxkX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCB0cnVlLCAkZ3JvdXBpbmcgKTsKCQl9CgoJCSR0aGlzLT5wcm9jZXNzX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRjb25maWdfcGF0aCwgJ0FkZGVkJyApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBhbiBhbGlhcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgYWxpYXMuCgkgKgoJICogWy0tY29uZmlnPTxjb25maWc+XQoJICogOiBDb25maWcgZmlsZSB0byBiZSBjb25zaWRlcmVkIGZvciBvcGVyYXRpb25zLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIGdsb2JhbAoJICogICAtIHByb2plY3QKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFsaWFzLgoJICogICAgICQgd3AgY2xpIGFsaWFzIGRlbGV0ZSBAcHJvZAoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ0Bwcm9kJyBhbGlhcy4KCSAqCgkgKiAgICAgIyBEZWxldGUgcHJvamVjdCBhbGlhcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyBkZWxldGUgQHByb2QgLS1jb25maWc9cHJvamVjdAoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ0Bwcm9kJyBhbGlhcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkYWxpYXMgKSA9ICRhcmdzOwoKCQkkY29uZmlnID0gKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snY29uZmlnJ10gKSA/ICRhc3NvY19hcmdzWydjb25maWcnXSA6ICcnICk7CgoJCWxpc3QoICRjb25maWdfcGF0aCwgJGFsaWFzZXMgKSA9ICR0aGlzLT5nZXRfYWxpYXNlc19kYXRhKCAkY29uZmlnLCAkYWxpYXMgKTsKCgkJJHRoaXMtPnZhbGlkYXRlX2NvbmZpZ19maWxlKCAkY29uZmlnX3BhdGggKTsKCgkJaWYgKCBlbXB0eSggJGFsaWFzZXNbICRhbGlhcyBdICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyBhbGlhcyBmb3VuZCB3aXRoIGtleSAneyRhbGlhc30nLiIgKTsKCQl9CgoJCXVuc2V0KCAkYWxpYXNlc1sgJGFsaWFzIF0gKTsKCQkkdGhpcy0+cHJvY2Vzc19hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkY29uZmlnX3BhdGgsICdEZWxldGVkJyApOwoKCX0KCgkvKioKCSAqIFVwZGF0ZXMgYW4gYWxpYXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIGFsaWFzLgoJICoKCSAqIFstLXNldC11c2VyPTx1c2VyPl0KCSAqIDogU2V0IHVzZXIgZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC11cmw9PHVybD5dCgkgKiA6IFNldCB1cmwgZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1wYXRoPTxwYXRoPl0KCSAqIDogU2V0IHBhdGggZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1zc2g9PHNzaD5dCgkgKiA6IFNldCBzc2ggZm9yIGFsaWFzLgoJICoKCSAqIFstLXNldC1odHRwPTxodHRwPl0KCSAqIDogU2V0IGh0dHAgZm9yIGFsaWFzLgoJICoKCSAqIFstLWdyb3VwaW5nPTxncm91cGluZz5dCgkgKiA6IEZvciBncm91cGluZyBtdWx0aXBsZSBhbGlhc2VzLgoJICoKCSAqIFstLWNvbmZpZz08Y29uZmlnPl0KCSAqIDogQ29uZmlnIGZpbGUgdG8gYmUgY29uc2lkZXJlZCBmb3Igb3BlcmF0aW9ucy4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBnbG9iYWwKCSAqICAgLSBwcm9qZWN0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBhbGlhcy4KCSAqICAgICAkIHdwIGNsaSBhbGlhcyB1cGRhdGUgQHByb2QgLS1zZXQtdXNlcj1uZXd1c2VyIC0tc2V0LXBhdGg9L25ldy9wYXRoL3RvL3dvcmRwcmVzcy9pbnN0YWxsLwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ3Byb2QnIGFsaWFzLgoJICoKCSAqICAgICAjIFVwZGF0ZSBwcm9qZWN0IGFsaWFzLgoJICogICAgICQgd3AgY2xpIGFsaWFzIHVwZGF0ZSBAcHJvZCAtLXNldC11c2VyPW5ld3VzZXIgLS1zZXQtcGF0aD0vbmV3L3BhdGgvdG8vd29yZHByZXNzL2luc3RhbGwvIC0tY29uZmlnPXByb2plY3QKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdwcm9kJyBhbGlhcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkY29uZmlnICAgPSAoICEgZW1wdHkoICRhc3NvY19hcmdzWydjb25maWcnXSApID8gJGFzc29jX2FyZ3NbJ2NvbmZpZyddIDogJycgKTsKCQkkYWxpYXMgICAgPSAkYXJnc1swXTsKCQkkZ3JvdXBpbmcgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdncm91cGluZycgKTsKCgkJbGlzdCggJGNvbmZpZ19wYXRoLCAkYWxpYXNlcyApID0gJHRoaXMtPmdldF9hbGlhc2VzX2RhdGEoICRjb25maWcsICRhbGlhcywgdHJ1ZSApOwoKCQkkdGhpcy0+dmFsaWRhdGVfY29uZmlnX2ZpbGUoICRjb25maWdfcGF0aCApOwoKCQkkdGhpcy0+dmFsaWRhdGVfaW5wdXQoICRhc3NvY19hcmdzLCAkZ3JvdXBpbmcgKTsKCgkJaWYgKCBlbXB0eSggJGFsaWFzZXNbICRhbGlhcyBdICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyBhbGlhcyBmb3VuZCB3aXRoIGtleSAneyRhbGlhc30nLiIgKTsKCQl9CgoJCWlmICggbnVsbCA9PT0gJGdyb3VwaW5nICkgewoJCQkkYWxpYXNlcyA9ICR0aGlzLT5idWlsZF9hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkYXNzb2NfYXJncywgZmFsc2UsICcnLCB0cnVlICk7CgkJfSBlbHNlIHsKCQkJJGFsaWFzZXMgPSAkdGhpcy0+YnVpbGRfYWxpYXNlcyggJGFsaWFzZXMsICRhbGlhcywgJGFzc29jX2FyZ3MsIHRydWUsICRncm91cGluZywgdHJ1ZSApOwoJCX0KCgkJJHRoaXMtPnByb2Nlc3NfYWxpYXNlcyggJGFsaWFzZXMsICRhbGlhcywgJGNvbmZpZ19wYXRoLCAnVXBkYXRlZCcgKTsKCX0KCgkvKioKCSAqIEdldCBjb25maWcgcGF0aCBhbmQgYWxpYXNlcyBkYXRhIGJhc2VkIG9uIGNvbmZpZyB0eXBlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZyAgICAgICAgICAgICBUeXBlIG9mIGNvbmZpZyB0byBnZXQgZGF0YSBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAkYWxpYXMgICAgICAgICAgICAgIEFsaWFzIHRvIGJlIHVzZWQgZm9yIEFkZC9VcGRhdGUvRGVsZXRlLgoJICogQHBhcmFtIGJvb2wgICAkY3JlYXRlX2NvbmZpZ19maWxlIE9wdGlvbmFsLiBJZiBhIGNvbmZpZyBmaWxlIGRvZXNuJ3QgZXhpc3QsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGl0IGJlIGNyZWF0ZWQ/IERlZmF1bHRzIHRvIGZhbHNlLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgQ29uZmlnIFBhdGggYW5kIEFsaWFzZXMgaW4gaXQuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWxpYXNlc19kYXRhKCAkY29uZmlnLCAkYWxpYXMsICRjcmVhdGVfY29uZmlnX2ZpbGUgPSBmYWxzZSApIHsKCgkJJGdsb2JhbF9jb25maWdfcGF0aCA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5nZXRfZ2xvYmFsX2NvbmZpZ19wYXRoKCAkY3JlYXRlX2NvbmZpZ19maWxlICk7CgkJJGdsb2JhbF9hbGlhc2VzICAgICA9IFNweWM6OllBTUxMb2FkKCAkZ2xvYmFsX2NvbmZpZ19wYXRoICk7CgoJCSRwcm9qZWN0X2NvbmZpZ19wYXRoID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmdldF9wcm9qZWN0X2NvbmZpZ19wYXRoKCk7CgkJJHByb2plY3RfYWxpYXNlcyAgICAgPSBTcHljOjpZQU1MTG9hZCggJHByb2plY3RfY29uZmlnX3BhdGggKTsKCgkJaWYgKCAnZ2xvYmFsJyA9PT0gJGNvbmZpZyApIHsKCQkJJGNvbmZpZ19wYXRoID0gJGdsb2JhbF9jb25maWdfcGF0aDsKCQkJJGFsaWFzZXMgICAgID0gJGdsb2JhbF9hbGlhc2VzOwoJCX0gZWxzZWlmICggJ3Byb2plY3QnID09PSAkY29uZmlnICkgewoJCQkkY29uZmlnX3BhdGggPSAkcHJvamVjdF9jb25maWdfcGF0aDsKCQkJJGFsaWFzZXMgICAgID0gJHByb2plY3RfYWxpYXNlczsKCQl9IGVsc2UgewoKCQkJJGlzX2dsb2JhbF9hbGlhcyAgPSBhcnJheV9rZXlfZXhpc3RzKCAkYWxpYXMsICRnbG9iYWxfYWxpYXNlcyApOwoJCQkkaXNfcHJvamVjdF9hbGlhcyA9IGFycmF5X2tleV9leGlzdHMoICRhbGlhcywgJHByb2plY3RfYWxpYXNlcyApOwoKCQkJaWYgKCAkaXNfZ2xvYmFsX2FsaWFzICYmICRpc19wcm9qZWN0X2FsaWFzICkgewoJCQkJV1BfQ0xJOjplcnJvciggIktleSAneyRhbGlhc30nIGZvdW5kIGluIG1vcmUgdGhhbiBvbmUgcGF0aC4gUGxlYXNlIHBhc3MgLS1jb25maWcgcGFyYW0uIiApOwoJCQl9IGVsc2VpZiAoICRpc19nbG9iYWxfYWxpYXMgKSB7CgkJCQkkY29uZmlnX3BhdGggPSAkZ2xvYmFsX2NvbmZpZ19wYXRoOwoJCQkJJGFsaWFzZXMgICAgID0gJGdsb2JhbF9hbGlhc2VzOwoJCQl9IGVsc2UgewoJCQkJJGNvbmZpZ19wYXRoID0gJHByb2plY3RfY29uZmlnX3BhdGg7CgkJCQkkYWxpYXNlcyAgICAgPSAkcHJvamVjdF9hbGlhc2VzOwoJCQl9CgkJfQoKCQlyZXR1cm4gWyAkY29uZmlnX3BhdGgsICRhbGlhc2VzIF07CgoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIGNvbmZpZyBmaWxlIGV4aXN0cyBhbmQgaXMgd3JpdGFibGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29uZmlnX3BhdGggUGF0aCB0byBjb25maWcgZmlsZS4KCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZV9jb25maWdfZmlsZSggJGNvbmZpZ19wYXRoICkgewoJCWlmICggISBmaWxlX2V4aXN0cyggJGNvbmZpZ19wYXRoICkgfHwgISBpc193cml0YWJsZSggJGNvbmZpZ19wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb25maWcgZmlsZSBkb2VzIG5vdCBleGlzdDogeyRjb25maWdfcGF0aH0iICk7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJuIGFsaWFzZXMgYXJyYXkuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYWxpYXNlcyAgICAgQ3VycmVudCBhbGlhc2VzIGRhdGEuCgkgKiBAcGFyYW0gc3RyaW5nICRhbGlhcyAgICAgICBOYW1lIG9mIGFsaWFzLgoJICogQHBhcmFtIGFycmF5ICAkYXNzb2NfYXJncyAgQXNzb2NpYXRpdmUgYXJndW1lbnRzLgoJICogQHBhcmFtIGJvb2wgICAkaXNfZ3JvdXBpbmcgQ2hlY2sgaWYgaXRzIGEgZ3JvdXBpbmcgb3BlcmF0aW9uLgoJICogQHBhcmFtIHN0cmluZyAkZ3JvdXBpbmcgICAgR3JvdXBpbmcgdmFsdWUuCgkgKiBAcGFyYW0gYm9vbCAgICRpc191cGRhdGUgICBJcyB0aGlzIGFuIHVwZGF0ZSBvcGVyYXRpb24/CgkgKgoJICogQHJldHVybiBtaXhlZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGJ1aWxkX2FsaWFzZXMoICRhbGlhc2VzLCAkYWxpYXMsICRhc3NvY19hcmdzLCAkaXNfZ3JvdXBpbmcsICRncm91cGluZyA9ICcnLCAkaXNfdXBkYXRlID0gZmFsc2UgKSB7CgoJCWlmICggJGlzX2dyb3VwaW5nICkgewoJCQkkdmFsaWRfYXNzb2NfYXJncyA9IFsgJ2NvbmZpZycsICdncm91cGluZycgXTsKCQkJJGludmFsaWRfYXJncyAgICAgPSBhcnJheV9kaWZmKCBhcnJheV9rZXlzKCAkYXNzb2NfYXJncyApLCAkdmFsaWRfYXNzb2NfYXJncyApOwoKCQkJLy8gQ2hlY2sgZm9yIGludmFsaWQgYXJncy4KCQkJaWYgKCAhIGVtcHR5KCAkaW52YWxpZF9hcmdzICkgKSB7CgkJCQkkYXJnc19pbmZvID0gaW1wbG9kZSggJywnLCAkaW52YWxpZF9hcmdzICk7CgkJCQlXUF9DTEk6OmVycm9yKCAiLS1ncm91cGluZyBhcmd1bWVudCB3b3JrcyBhbG9uZS4gRm91bmQgaW52YWxpZCBhcmcocykgJyRhcmdzX2luZm8nLiIgKTsKCQkJfQoJCX0KCgkJaWYgKCAkaXNfdXBkYXRlICkgewoJCQkkdGhpcy0+dmFsaWRhdGVfYWxpYXNfdHlwZSggJGFsaWFzZXMsICRhbGlhcywgJGFzc29jX2FyZ3MsICRncm91cGluZyApOwoJCX0KCgkJaWYgKCAhICRpc19ncm91cGluZyApIHsKCQkJZm9yZWFjaCAoICRhc3NvY19hcmdzIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkJaWYgKCBzdHJwb3MoICRrZXksICdzZXQtJyApICE9PSBmYWxzZSApIHsKCQkJCQkkYWxpYXNfa2V5X2luZm8gPSBleHBsb2RlKCAnLScsICRrZXkgKTsKCQkJCQkkYWxpYXNfa2V5ICAgICAgPSBlbXB0eSggJGFsaWFzX2tleV9pbmZvWzFdICkgPyAnJyA6ICRhbGlhc19rZXlfaW5mb1sxXTsKCQkJCQlpZiAoICEgZW1wdHkoICRhbGlhc19rZXkgKSAmJiAhIGVtcHR5KCAkdmFsdWUgKSApIHsKCQkJCQkJJGFsaWFzZXNbICRhbGlhcyBdWyAkYWxpYXNfa2V5IF0gPSAkdmFsdWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCgkJCWlmICggISBlbXB0eSggJGdyb3VwaW5nICkgKSB7CgkJCQkkZ3JvdXBfYWxpYXNfbGlzdCAgPSBleHBsb2RlKCAnLCcsICRncm91cGluZyApOwoJCQkJJGdyb3VwX2FsaWFzICAgICAgID0gYXJyYXlfbWFwKAoJCQkJCWZ1bmN0aW9uICggJGN1cnJlbnRfYWxpYXMgKSB7CgkJCQkJCXJldHVybiAnQCcgLiBsdHJpbSggJGN1cnJlbnRfYWxpYXMsICdAJyApOwoJCQkJCX0sCgkJCQkJJGdyb3VwX2FsaWFzX2xpc3QKCQkJCSk7CgkJCQkkYWxpYXNlc1sgJGFsaWFzIF0gPSAkZ3JvdXBfYWxpYXM7CgkJCX0KCQl9CgoJCXJldHVybiAkYWxpYXNlczsKCX0KCgkvKioKCSAqIFZhbGlkYXRlIGlucHV0IG9mIHBhc3NlZCBhcmd1bWVudHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYXNzb2NfYXJncyBBcmd1bWVudHMgYXJyYXkuCgkgKiBAcGFyYW0gc3RyaW5nICRncm91cGluZyAgIEdyb3VwaW5nIGFyZ3VtZW50IHZhbHVlLgoJICoKCSAqIEB0aHJvd3MgRXhpdEV4Y2VwdGlvbgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlX2lucHV0KCAkYXNzb2NfYXJncywgJGdyb3VwaW5nICkgewoJCS8vIENoZWNrIGlmIHZhbGlkIGFyZ3VtZW50cyB3ZXJlIHBhc3NlZC4KCQkkYXJnX21hdGNoID0gcHJlZ19ncmVwKCAnL15zZXQtKFx3KykvaScsIGFycmF5X2tleXMoICRhc3NvY19hcmdzICkgKTsKCgkJLy8gVmVyaWZ5IHBhc3NlZC1hcmd1bWVudHMuCgkJaWYgKCBlbXB0eSggJGdyb3VwaW5nICkgJiYgZW1wdHkoICRhcmdfbWF0Y2ggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vIHZhbGlkIGFyZ3VtZW50cyBwYXNzZWQuJyApOwoJCX0KCgkJLy8gQ2hlY2sgd2hldGhlciBwYXNzZWQgYXJndW1lbnRzIGNvbnRhaW4gdmFsdWUgb3Igbm90LgoJCSRhc3NvY19hcmdfdmFsdWVzID0gYXJyYXlfZmlsdGVyKCBhcnJheV9pbnRlcnNlY3Rfa2V5KCAkYXNzb2NfYXJncywgYXJyYXlfZmxpcCggJGFyZ19tYXRjaCApICkgKTsKCgkJaWYgKCBlbXB0eSggJGdyb3VwaW5nICkgJiYgZW1wdHkoICRhc3NvY19hcmdfdmFsdWVzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyB2YWx1ZSBwYXNzZWQgdG8gYXJndW1lbnRzLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSBhbGlhcyB0eXBlIGJlZm9yZSB1cGRhdGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYWxpYXNlcyAgICBFeGlzdGluZyBhbGlhc2VzIGRhdGEuCgkgKiBAcGFyYW0gc3RyaW5nICRhbGlhcyAgICAgIEFsaWFzIE5hbWUuCgkgKiBAcGFyYW0gYXJyYXkgICRhc3NvY19hcmdzIEFyZ3VtZW50cyBhcnJheS4KCSAqIEBwYXJhbSBzdHJpbmcgJGdyb3VwaW5nICAgR3JvdXBpbmcgYXJndW1lbnQgdmFsdWUuCgkgKgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVfYWxpYXNfdHlwZSggJGFsaWFzZXMsICRhbGlhcywgJGFzc29jX2FyZ3MsICRncm91cGluZyApIHsKCgkJJGFsaWFzX2RhdGEgPSAkYWxpYXNlc1sgJGFsaWFzIF07CgoJCSRncm91cF9hbGlhc2VzX21hdGNoID0gcHJlZ19ncmVwKCAnL15AKFx3KykvaScsICRhbGlhc19kYXRhICk7CgkJJGFyZ19tYXRjaCAgICAgICAgICAgPSBwcmVnX2dyZXAoICcvXnNldC0oXHcrKS9pJywgYXJyYXlfa2V5cyggJGFzc29jX2FyZ3MgKSApOwoKCQlpZiAoICEgZW1wdHkoICRncm91cF9hbGlhc2VzX21hdGNoICkgJiYgISBlbXB0eSggJGFyZ19tYXRjaCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVHJ5aW5nIHRvIHVwZGF0ZSBncm91cCBhbGlhcyB3aXRoIGludmFsaWQgYXJndW1lbnRzLicgKTsKCQl9IGVsc2VpZiAoIGVtcHR5KCAkZ3JvdXBfYWxpYXNlc19tYXRjaCApICYmICEgZW1wdHkoICRncm91cGluZyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVHJ5aW5nIHRvIHVwZGF0ZSBzaW1wbGUgYWxpYXMgd2l0aCBpbnZhbGlkIC0tZ3JvdXBpbmcgYXJndW1lbnQuJyApOwoJCX0KCX0KCgkvKioKCSAqIFNhdmUgYWxpYXNlcyBkYXRhIHRvIGNvbmZpZyBmaWxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGFsaWFzZXMgICAgIEN1cnJlbnQgYWxpYXNlcyBkYXRhLgoJICogQHBhcmFtIHN0cmluZyAkYWxpYXMgICAgICAgTmFtZSBvZiBhbGlhcy4KCSAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZ19wYXRoIFBhdGggdG8gY29uZmlnIGZpbGUuCgkgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRpb24gICBDdXJyZW50IG9wZXJhdGlvbiBzdHJpbmcgZnJvIG1lc3NhZ2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcHJvY2Vzc19hbGlhc2VzKCAkYWxpYXNlcywgJGFsaWFzLCAkY29uZmlnX3BhdGgsICRvcGVyYXRpb24gPSAnJyApIHsKCQkvLyBDb252ZXJ0IGRhdGEgdG8gWUFNTCBzdHJpbmcuCgkJJHlhbWxfZGF0YSA9IFNweWM6OllBTUxEdW1wKCAkYWxpYXNlcyApOwoKCQkvLyBBZGQgZGF0YSBpbiBjb25maWcgZmlsZS4KCQlpZiAoIGZpbGVfcHV0X2NvbnRlbnRzKCAkY29uZmlnX3BhdGgsICR5YW1sX2RhdGEgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiJG9wZXJhdGlvbiAneyRhbGlhc30nIGFsaWFzLiIgKTsKCQl9Cgl9Cn0KPD9waHAKCi8vIFRoaXMgZmlsZSBuZWVkcyB0byBwYXJzZSB3aXRob3V0IGVycm9yIGluIFBIUCA8IDUuMwoKaWYgKCAnY2xpJyAhPT0gUEhQX1NBUEkgKSB7CgllY2hvICJPbmx5IENMSSBhY2Nlc3MuXG4iOwoJZGllKCAtMSApOwp9CgppZiAoIHZlcnNpb25fY29tcGFyZSggUEhQX1ZFUlNJT04sICc1LjYuMCcsICc8JyApICkgewoJcHJpbnRmKCAiRXJyb3I6IFdQLUNMSSByZXF1aXJlcyBQSFAgJXMgb3IgbmV3ZXIuIFlvdSBhcmUgcnVubmluZyB2ZXJzaW9uICVzLlxuIiwgJzUuNi4wJywgUEhQX1ZFUlNJT04gKTsKCWRpZSggLTEgKTsKfQoKZGVmaW5lKCAnV1BfQ0xJX1JPT1QnLCBkaXJuYW1lKCBfX0RJUl9fICkgKTsKCnJlcXVpcmVfb25jZSBXUF9DTElfUk9PVCAuICcvcGhwL3dwLWNsaS5waHAnOwoKPD9waHAKLyoqCiAqIEEgbW9kaWZpZWQgdmVyc2lvbiBvZiB3cC1zZXR0aW5ncy5waHAsIHRhaWxvcmVkIGZvciBDTEkgdXNlLgogKgogKiBOb3RlOiBUaGlzIGlzIG5vdCBiZWluZyB1c2VkIGFueW1vcmUgZnJvbSBXb3JkUHJlc3MgNC42LWFscGhhLTM3NTc1IG9ud2FyZHMuCiAqCiAqIEBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZSAtLSBTZXR0aW5nIHRoZSBnbG9iYWxzIGlzIHRoZSBwb2ludCBvZiB0aGlzIGZpbGUuCiAqIEBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkQ29uc3RhbnRGb3VuZCAtLSBUaGVzZSBhcmUgV1AgbmF0aXZlIGNvbnN0YW50cyB3aGljaCBhcmUgbmVlZGVkLgogKiBAcGhwY3M6ZGlzYWJsZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQWxsIGhvb2sgY2FsbHMgaW4gdGhpcyBmaWxlIGFyZSB0byBXUCBuYXRpdmUgaG9va3MuCiAqIEBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkVmFyaWFibGVGb3VuZCAtLSBFbnN1cmluZyBuYXRpdmUgV1AgdmFyaWFibGVzIGFyZSBhdmFpbGFibGUuCiAqLwoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBTdG9yZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBXb3JkUHJlc3MgZGlyZWN0b3J5IG9mIGZ1bmN0aW9ucywgY2xhc3NlcywgYW5kIGNvcmUgY29udGVudC4KICoKICogQHNpbmNlIDEuMC4wCiAqLwpkZWZpbmUoICdXUElOQycsICd3cC1pbmNsdWRlcycgKTsKCi8vIEluY2x1ZGUgZmlsZXMgcmVxdWlyZWQgZm9yIGluaXRpYWxpemF0aW9uLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbG9hZC5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvZGVmYXVsdC1jb25zdGFudHMucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3BsdWdpbi5waHAnOwoKLyoKICogVGhlc2UgY2FuJ3QgYmUgZGlyZWN0bHkgZ2xvYmFsaXplZCBpbiB2ZXJzaW9uLnBocC4gV2hlbiB1cGRhdGluZywKICogd2UncmUgaW5jbHVkaW5nIHZlcnNpb24ucGhwIGZyb20gYW5vdGhlciBpbnN0YWxsYXRpb24gYW5kIGRvbid0IHdhbnQKICogdGhlc2UgdmFsdWVzIHRvIGJlIG92ZXJyaWRkZW4gaWYgYWxyZWFkeSBzZXQuCiAqLwpnbG9iYWwgJHdwX3ZlcnNpb24sICR3cF9kYl92ZXJzaW9uLCAkdGlueW1jZV92ZXJzaW9uLCAkcmVxdWlyZWRfcGhwX3ZlcnNpb24sICRyZXF1aXJlZF9teXNxbF92ZXJzaW9uLCAkd3BfbG9jYWxfcGFja2FnZTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3ZlcnNpb24ucGhwJzsKCi8qKgogKiBJZiBub3QgYWxyZWFkeSBjb25maWd1cmVkLCBgJGJsb2dfaWRgIHdpbGwgZGVmYXVsdCB0byAxIGluIGEgc2luZ2xlIHNpdGUKICogY29uZmlndXJhdGlvbi4gSW4gbXVsdGlzaXRlLCBpdCB3aWxsIGJlIG92ZXJyaWRkZW4gYnkgZGVmYXVsdCBpbiBtcy1zZXR0aW5ncy5waHAuCiAqCiAqIEBnbG9iYWwgaW50ICRibG9nX2lkCiAqIEBzaW5jZSAyLjAuMAogKi8KZ2xvYmFsICRibG9nX2lkOwoKLy8gU2V0IGluaXRpYWwgZGVmYXVsdCBjb25zdGFudHMgaW5jbHVkaW5nIFdQX01FTU9SWV9MSU1JVCwgV1BfTUFYX01FTU9SWV9MSU1JVCwgV1BfREVCVUcsIFdQX0NPTlRFTlRfRElSIGFuZCBXUF9DQUNIRS4Kd3BfaW5pdGlhbF9jb25zdGFudHMoKTsKCi8vIENoZWNrIGZvciB0aGUgcmVxdWlyZWQgUEhQIHZlcnNpb24gYW5kIGZvciB0aGUgTXlTUUwgZXh0ZW5zaW9uIG9yIGEgZGF0YWJhc2UgZHJvcC1pbi4Kd3BfY2hlY2tfcGhwX215c3FsX3ZlcnNpb25zKCk7CgovLyBEaXNhYmxlIG1hZ2ljIHF1b3RlcyBhdCBydW50aW1lLiBNYWdpYyBxdW90ZXMgYXJlIGFkZGVkIHVzaW5nIHdwZGIgbGF0ZXIgaW4gd3Atc2V0dGluZ3MucGhwLgovLyBwaHBjczpkaXNhYmxlIFBIUENvbXBhdGliaWxpdHkuSW5pRGlyZWN0aXZlcy5SZW1vdmVkSW5pRGlyZWN0aXZlcyxXb3JkUHJlc3MuUEhQLkluaVNldC5SaXNreQppbmlfc2V0KCAnbWFnaWNfcXVvdGVzX3J1bnRpbWUnLCAwICk7CmluaV9zZXQoICdtYWdpY19xdW90ZXNfc3liYXNlJywgMCApOwovLyBwaHBjOmVuYWJsZSBQSFBDb21wYXRpYmlsaXR5LkluaURpcmVjdGl2ZXMuUmVtb3ZlZEluaURpcmVjdGl2ZXMsV29yZFByZXNzLlBIUC5JbmlTZXQKCi8vIFdvcmRQcmVzcyBjYWxjdWxhdGVzIG9mZnNldHMgZnJvbSBVVEMuCi8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy50aW1lem9uZV9jaGFuZ2VfZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldApkYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0KCAnVVRDJyApOwoKLy8gVHVybiByZWdpc3Rlcl9nbG9iYWxzIG9mZi4Kd3BfdW5yZWdpc3Rlcl9HTE9CQUxTKCk7CgovLyBTdGFuZGFyZGl6ZSAkX1NFUlZFUiB2YXJpYWJsZXMgYWNyb3NzIHNldHVwcy4Kd3BfZml4X3NlcnZlcl92YXJzKCk7CgovLyBDaGVjayBpZiB3ZSdyZSBpbiBtYWludGVuYW5jZSBtb2RlLgovLyBXUC1DTEk6IHJ1biBlbmFibGVfbWFpbnRlbmFuY2VfbW9kZSBmaWx0ZXIgZWFybHkgZm9yIGNvbXBhdCB3aXRoIDwgV1AgNC42Ci8qKgogKiBGaWx0ZXJzIHdoZXRoZXIgdG8gZW5hYmxlIG1haW50ZW5hbmNlIG1vZGUuCiAqCiAqIFRoaXMgZmlsdGVyIHJ1bnMgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGJ5IHBsdWdpbnMuIEl0IGlzIGRlc2lnbmVkIGZvcgogKiBub24td2ViIHJ1bnRpbWVzLiBJZiB0aGlzIGZpbHRlciByZXR1cm5zIHRydWUsIG1haW50ZW5hbmNlIG1vZGUgd2lsbCBiZQogKiBhY3RpdmUgYW5kIHRoZSByZXF1ZXN0IHdpbGwgZW5kLiBJZiBmYWxzZSwgdGhlIHJlcXVlc3Qgd2lsbCBiZSBhbGxvd2VkIHRvCiAqIGNvbnRpbnVlIHByb2Nlc3NpbmcgZXZlbiBpZiBtYWludGVuYW5jZSBtb2RlIHNob3VsZCBiZSBhY3RpdmUuCiAqCiAqIEBzaW5jZSA0LjYuMAogKgogKiBAcGFyYW0gYm9vbCAkZW5hYmxlX2NoZWNrcyBXaGV0aGVyIHRvIGVuYWJsZSBtYWludGVuYW5jZSBtb2RlLiBEZWZhdWx0IHRydWUuCiAqIEBwYXJhbSBpbnQgICR1cGdyYWRpbmcgICAgIFRoZSB0aW1lc3RhbXAgc2V0IGluIHRoZSAubWFpbnRlbmFuY2UgZmlsZS4KICovCmlmICggYXBwbHlfZmlsdGVycyggJ2VuYWJsZV9tYWludGVuYW5jZV9tb2RlJywgdHJ1ZSApICkgewoJd3BfbWFpbnRlbmFuY2UoKTsKfQoKLy8gU3RhcnQgbG9hZGluZyB0aW1lci4KdGltZXJfc3RhcnQoKTsKCi8vIFdQLUNMSTogcnVuIGVuYWJsZV93cF9kZWJ1Z19tb2RlX2NoZWNrcyBmaWx0ZXIgZWFybHkgZm9yIGNvbXBhdCB3aXRoIDwgV1AgNC42Ci8qKgogKiBGaWx0ZXJzIHdoZXRoZXIgdG8gYWxsb3cgdGhlIGRlYnVnIG1vZGUgY2hlY2sgdG8gb2NjdXIuCiAqCiAqIFRoaXMgZmlsdGVyIHJ1bnMgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGJ5IHBsdWdpbnMuIEl0IGlzIGRlc2lnbmVkIGZvcgogKiBub24td2ViIHJ1bi10aW1lcy4gUmV0dXJuaW5nIGZhbHNlIGNhdXNlcyB0aGUgYFdQX0RFQlVHYCBhbmQgcmVsYXRlZAogKiBjb25zdGFudHMgdG8gbm90IGJlIGNoZWNrZWQgYW5kIHRoZSBkZWZhdWx0IHBocCB2YWx1ZXMgZm9yIGVycm9ycwogKiB3aWxsIGJlIHVzZWQgdW5sZXNzIHlvdSB0YWtlIGNhcmUgdG8gdXBkYXRlIHRoZW0geW91cnNlbGYuCiAqCiAqIEBzaW5jZSA0LjYuMAogKgogKiBAcGFyYW0gYm9vbCAkZW5hYmxlX2RlYnVnX21vZGUgV2hldGhlciB0byBlbmFibGUgZGVidWcgbW9kZSBjaGVja3MgdG8gb2NjdXIuIERlZmF1bHQgdHJ1ZS4KICovCmlmICggYXBwbHlfZmlsdGVycyggJ2VuYWJsZV93cF9kZWJ1Z19tb2RlX2NoZWNrcycsIHRydWUgKSApIHsKCXdwX2RlYnVnX21vZGUoKTsKfQoKLyoqCiAqIEZpbHRlcnMgd2hldGhlciB0byBlbmFibGUgbG9hZGluZyBvZiB0aGUgYWR2YW5jZWQtY2FjaGUucGhwIGRyb3AtaW4uCiAqCiAqIFRoaXMgZmlsdGVyIHJ1bnMgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGJ5IHBsdWdpbnMuIEl0IGlzIGRlc2lnbmVkIGZvciBub24td2ViCiAqIHJ1bi10aW1lcy4gSWYgZmFsc2UgaXMgcmV0dXJuZWQsIGFkdmFuY2UtY2FjaGUucGhwIHdpbGwgbmV2ZXIgYmUgbG9hZGVkLgogKgogKiBAc2luY2UgNC42LjAKICoKICogQHBhcmFtIGJvb2wgJGVuYWJsZV9hZHZhbmNlZF9jYWNoZSBXaGV0aGVyIHRvIGVuYWJsZSBsb2FkaW5nIGFkdmFuY2VkLWNhY2hlLnBocCAoaWYgcHJlc2VudCkuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCB0cnVlLgogKi8KaWYgKCBXUF9DQUNIRSAmJiBhcHBseV9maWx0ZXJzKCAnZW5hYmxlX2xvYWRpbmdfYWR2YW5jZWRfY2FjaGVfZHJvcGluJywgdHJ1ZSApICkgewoJLy8gRm9yIGFuIGFkdmFuY2VkIGNhY2hpbmcgcGx1Z2luIHRvIHVzZS4gVXNlcyBhIHN0YXRpYyBkcm9wLWluIGJlY2F1c2UgeW91IHdvdWxkIG9ubHkgd2FudCBvbmUuCglpZiAoIGZpbGVfZXhpc3RzKCBXUF9DT05URU5UX0RJUiAuICcvYWR2YW5jZWQtY2FjaGUucGhwJyApICkgewoJCWluY2x1ZGUgV1BfQ09OVEVOVF9ESVIgLiAnL2FkdmFuY2VkLWNhY2hlLnBocCc7Cgl9Cn0KCi8vIERlZmluZSBXUF9MQU5HX0RJUiBpZiBub3Qgc2V0Lgp3cF9zZXRfbGFuZ19kaXIoKTsKCi8vIExvYWQgZWFybHkgV29yZFByZXNzIGZpbGVzLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY29tcGF0LnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9mdW5jdGlvbnMucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1lcnJvci5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcG9tby9tby5waHAnOwoKLy8gSW5jbHVkZSB0aGUgd3BkYiBjbGFzcyBhbmQsIGlmIHByZXNlbnQsIGEgZGIucGhwIGRhdGFiYXNlIGRyb3AtaW4uCnJlcXVpcmVfd3BfZGIoKTsKCi8vIFdQLUNMSTogSGFuZGxlIGRiIGVycm9yIG91cnNlbHZlcywgaW5zdGVhZCBvZiB3YWl0aW5nIGZvciBkZWFkX2RiKCkKZ2xvYmFsICR3cGRiOwppZiAoICEgZW1wdHkoICR3cGRiLT5lcnJvciApICkgewoJd3BfZGllKCAkd3BkYi0+ZXJyb3IgKTsKfQoKLy8gU2V0IHRoZSBkYXRhYmFzZSB0YWJsZSBwcmVmaXggYW5kIHRoZSBmb3JtYXQgc3BlY2lmaWVycyBmb3IgZGF0YWJhc2UgdGFibGUgY29sdW1ucy4KJEdMT0JBTFNbJ3RhYmxlX3ByZWZpeCddID0gJHRhYmxlX3ByZWZpeDsKd3Bfc2V0X3dwZGJfdmFycygpOwoKLy8gU3RhcnQgdGhlIFdvcmRQcmVzcyBvYmplY3QgY2FjaGUsIG9yIGFuIGV4dGVybmFsIG9iamVjdCBjYWNoZSBpZiB0aGUgZHJvcC1pbiBpcyBwcmVzZW50Lgp3cF9zdGFydF9vYmplY3RfY2FjaGUoKTsKCi8vIEF0dGFjaCB0aGUgZGVmYXVsdCBmaWx0ZXJzLgpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvZGVmYXVsdC1maWx0ZXJzLnBocCc7CgovLyBJbml0aWFsaXplIG11bHRpc2l0ZSBpZiBlbmFibGVkLgppZiAoIGlzX211bHRpc2l0ZSgpICkgewoJVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNi1hbHBoYS0zNzU3NScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atc2l0ZS1xdWVyeS5waHAnICk7CglVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC42LWFscGhhLTM3ODk2JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1uZXR3b3JrLXF1ZXJ5LnBocCcgKTsKCXJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9tcy1ibG9ncy5waHAnOwoJcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL21zLXNldHRpbmdzLnBocCc7Cn0gZWxzZWlmICggISBkZWZpbmVkKCAnTVVMVElTSVRFJyApICkgewoJZGVmaW5lKCAnTVVMVElTSVRFJywgZmFsc2UgKTsKfQoKcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oICdzaHV0ZG93bl9hY3Rpb25faG9vaycgKTsKCi8vIFN0b3AgbW9zdCBvZiBXb3JkUHJlc3MgZnJvbSBiZWluZyBsb2FkZWQgaWYgd2UganVzdCB3YW50IHRoZSBiYXNpY3MuCmlmICggU0hPUlRJTklUICkgewoJcmV0dXJuIGZhbHNlOwp9CgovLyBMb2FkIHRoZSBMMTBuIGxpYnJhcnkuCnJlcXVpcmVfb25jZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2wxMG4ucGhwJzsKCi8vIFdQLUNMSTogUGVybWl0IFV0aWxzXHdwX25vdF9pbnN0YWxsZWQoKSB0byBydW4gb24gPCBXUCA0LjAKYXBwbHlfZmlsdGVycyggJ25vY2FjaGVfaGVhZGVycycsIFtdICk7CgovLyBSdW4gdGhlIGluc3RhbGxlciBpZiBXb3JkUHJlc3MgaXMgbm90IGluc3RhbGxlZC4Kd3Bfbm90X2luc3RhbGxlZCgpOwoKLy8gTG9hZCBtb3N0IG9mIFdvcmRQcmVzcy4KcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXdhbGtlci5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtYWpheC1yZXNwb25zZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvZm9ybWF0dGluZy5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2FwYWJpbGl0aWVzLnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXJvbGVzLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atcm9sZS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXVzZXIucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcXVlcnkucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzMuNy1hbHBoYS0yNTEzOScsIEFCU1BBVEggLiBXUElOQyAuICcvZGF0ZS5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy90aGVtZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtdGhlbWUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3RlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy91c2VyLnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXVzZXItcXVlcnkucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC4wJywgQUJTUEFUSCAuIFdQSU5DIC4gJy9zZXNzaW9uLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL21ldGEucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtbWV0YS1xdWVyeS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjUtYWxwaGEtMzU3NzYnLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLW1ldGFkYXRhLWxhenlsb2FkZXIucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvZ2VuZXJhbC10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbGluay10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvYXV0aG9yLXRlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9wb3N0LnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdhbGtlci1wYWdlLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd2Fsa2VyLXBhZ2UtZHJvcGRvd24ucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC42LWFscGhhLTM3ODkwJywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1wb3N0LXR5cGUucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1wb3N0LnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3Bvc3QtdGVtcGxhdGUucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzMuNi1hbHBoYS0yMzQ1MScsIEFCU1BBVEggLiBXUElOQyAuICcvcmV2aXNpb24ucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnMy42LWFscGhhLTIzNDUxJywgQUJTUEFUSCAuIFdQSU5DIC4gJy9wb3N0LWZvcm1hdHMucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcG9zdC10aHVtYm5haWwtdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NhdGVnb3J5LnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdhbGtlci1jYXRlZ29yeS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdhbGtlci1jYXRlZ29yeS1kcm9wZG93bi5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9jYXRlZ29yeS10ZW1wbGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY29tbWVudC5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1jb21tZW50LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtY29tbWVudC1xdWVyeS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdhbGtlci1jb21tZW50LnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NvbW1lbnQtdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3Jld3JpdGUucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtcmV3cml0ZS5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9mZWVkLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9ib29rbWFyay5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvYm9va21hcmstdGVtcGxhdGUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2tzZXMucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2Nyb24ucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2RlcHJlY2F0ZWQucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3NjcmlwdC1sb2FkZXIucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3RheG9ub215LnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLXRlcm0ucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC42LWFscGhhLTM3NTc1JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC10ZXJtLXF1ZXJ5LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtdGF4LXF1ZXJ5LnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3VwZGF0ZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvY2Fub25pY2FsLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9zaG9ydGNvZGVzLnBocCc7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2VtYmVkLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWVtYmVkLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9tZWRpYS5waHAnOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWFscGhhLTM0OTAzJywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1vZW1iZWQtY29udHJvbGxlci5waHAnICk7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9odHRwLnBocCc7CnJlcXVpcmVfb25jZSBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLWh0dHAucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1zdHJlYW1zLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1jdXJsLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1wcm94eS5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWh0dHAtY29va2llLnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3AtaHR0cC1lbmNvZGluZy5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL2NsYXNzLXdwLWh0dHAtcmVzcG9uc2UucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC42LWFscGhhLTM3NDM4JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9jbGFzcy13cC1odHRwLXJlcXVlc3RzLXJlc3BvbnNlLnBocCcgKTsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3dpZGdldHMucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atd2lkZ2V0LnBocCcgKTsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1iZXRhNC0zNTcxOScsIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtd3Atd2lkZ2V0LWZhY3RvcnkucGhwJyApOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbmF2LW1lbnUucGhwJzsKcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL25hdi1tZW51LXRlbXBsYXRlLnBocCc7CnJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy9hZG1pbi1iYXIucGhwJzsKVXRpbHNcbWF5YmVfcmVxdWlyZSggJzQuNC1hbHBoYS0zNDkyOCcsIEFCU1BBVEggLiBXUElOQyAuICcvcmVzdC1hcGkucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9yZXN0LWFwaS9jbGFzcy13cC1yZXN0LXNlcnZlci5waHAnICk7ClV0aWxzXG1heWJlX3JlcXVpcmUoICc0LjQtYmV0YTQtMzU3MTknLCBBQlNQQVRIIC4gV1BJTkMgLiAnL3Jlc3QtYXBpL2NsYXNzLXdwLXJlc3QtcmVzcG9uc2UucGhwJyApOwpVdGlsc1xtYXliZV9yZXF1aXJlKCAnNC40LWJldGE0LTM1NzE5JywgQUJTUEFUSCAuIFdQSU5DIC4gJy9yZXN0LWFwaS9jbGFzcy13cC1yZXN0LXJlcXVlc3QucGhwJyApOwoKLy8gTG9hZCBtdWx0aXNpdGUtc3BlY2lmaWMgZmlsZXMuCmlmICggaXNfbXVsdGlzaXRlKCkgKSB7CglyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbXMtZnVuY3Rpb25zLnBocCc7CglyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbXMtZGVmYXVsdC1maWx0ZXJzLnBocCc7CglyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvbXMtZGVwcmVjYXRlZC5waHAnOwp9CgovLyBEZWZpbmUgY29uc3RhbnRzIHRoYXQgcmVseSBvbiB0aGUgQVBJIHRvIG9idGFpbiB0aGUgZGVmYXVsdCB2YWx1ZS4KLy8gRGVmaW5lIG11c3QtdXNlIHBsdWdpbiBkaXJlY3RvcnkgY29uc3RhbnRzLCB3aGljaCBtYXkgYmUgb3ZlcnJpZGRlbiBpbiB0aGUgc3VucmlzZS5waHAgZHJvcC1pbi4Kd3BfcGx1Z2luX2RpcmVjdG9yeV9jb25zdGFudHMoKTsKCiRzeW1saW5rZWRfcGx1Z2luc19zdXBwb3J0ZWQgPSBmdW5jdGlvbl9leGlzdHMoICd3cF9yZWdpc3Rlcl9wbHVnaW5fcmVhbHBhdGgnICk7CmlmICggJHN5bWxpbmtlZF9wbHVnaW5zX3N1cHBvcnRlZCApIHsKCSRHTE9CQUxTWyd3cF9wbHVnaW5fcGF0aHMnXSA9IFtdOwp9CgovLyBMb2FkIG11c3QtdXNlIHBsdWdpbnMuCmZvcmVhY2ggKCB3cF9nZXRfbXVfcGx1Z2lucygpIGFzICRtdV9wbHVnaW4gKSB7CglpbmNsdWRlX29uY2UgJG11X3BsdWdpbjsKfQp1bnNldCggJG11X3BsdWdpbiApOwoKLy8gTG9hZCBuZXR3b3JrIGFjdGl2YXRlZCBwbHVnaW5zLgppZiAoIGlzX211bHRpc2l0ZSgpICkgewoJZm9yZWFjaCAoIHdwX2dldF9hY3RpdmVfbmV0d29ya19wbHVnaW5zKCkgYXMgJG5ldHdvcmtfcGx1Z2luICkgewoJCWlmICggJHN5bWxpbmtlZF9wbHVnaW5zX3N1cHBvcnRlZCApIHsKCQkJd3BfcmVnaXN0ZXJfcGx1Z2luX3JlYWxwYXRoKCAkbmV0d29ya19wbHVnaW4gKTsKCQl9CgkJaW5jbHVkZV9vbmNlICRuZXR3b3JrX3BsdWdpbjsKCX0KCXVuc2V0KCAkbmV0d29ya19wbHVnaW4gKTsKfQoKZG9fYWN0aW9uKCAnbXVwbHVnaW5zX2xvYWRlZCcgKTsKCmlmICggaXNfbXVsdGlzaXRlKCkgKSB7Cgltc19jb29raWVfY29uc3RhbnRzKCk7Cn0KCi8vIERlZmluZSBjb25zdGFudHMgYWZ0ZXIgbXVsdGlzaXRlIGlzIGxvYWRlZC4gQ29va2llLXJlbGF0ZWQgY29uc3RhbnRzIG1heSBiZSBvdmVycmlkZGVuIGluIG1zX25ldHdvcmtfY29va2llcygpLgp3cF9jb29raWVfY29uc3RhbnRzKCk7CgovLyBEZWZpbmUgYW5kIGVuZm9yY2Ugb3VyIFNTTCBjb25zdGFudHMuCndwX3NzbF9jb25zdGFudHMoKTsKCi8vIENyZWF0ZSBjb21tb24gZ2xvYmFscy4KcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3ZhcnMucGhwJzsKCi8vIE1ha2UgdGF4b25vbWllcyBhbmQgcG9zdHMgYXZhaWxhYmxlIHRvIHBsdWdpbnMgYW5kIHRoZW1lcy4KLy8gQHBsdWdpbiBhdXRob3JzOiB3YXJuaW5nOiB0aGVzZSBnZXQgcmVnaXN0ZXJlZCBhZ2FpbiBvbiB0aGUgaW5pdCBob29rLgpjcmVhdGVfaW5pdGlhbF90YXhvbm9taWVzKCk7CmNyZWF0ZV9pbml0aWFsX3Bvc3RfdHlwZXMoKTsKCi8vIFJlZ2lzdGVyIHRoZSBkZWZhdWx0IHRoZW1lIGRpcmVjdG9yeSByb290CnJlZ2lzdGVyX3RoZW1lX2RpcmVjdG9yeSggZ2V0X3RoZW1lX3Jvb3QoKSApOwoKLy8gTG9hZCBhY3RpdmUgcGx1Z2lucy4KZm9yZWFjaCAoIHdwX2dldF9hY3RpdmVfYW5kX3ZhbGlkX3BsdWdpbnMoKSBhcyAkcGx1Z2luICkgewoJaWYgKCAkc3ltbGlua2VkX3BsdWdpbnNfc3VwcG9ydGVkICkgewoJCXdwX3JlZ2lzdGVyX3BsdWdpbl9yZWFscGF0aCggJHBsdWdpbiApOwoJfQoJaW5jbHVkZV9vbmNlICRwbHVnaW47Cn0KdW5zZXQoICRwbHVnaW4sICRzeW1saW5rZWRfcGx1Z2luc19zdXBwb3J0ZWQgKTsKCi8vIExvYWQgcGx1Z2dhYmxlIGZ1bmN0aW9ucy4KcmVxdWlyZSBBQlNQQVRIIC4gV1BJTkMgLiAnL3BsdWdnYWJsZS5waHAnOwpyZXF1aXJlIEFCU1BBVEggLiBXUElOQyAuICcvcGx1Z2dhYmxlLWRlcHJlY2F0ZWQucGhwJzsKCi8vIFNldCBpbnRlcm5hbCBlbmNvZGluZy4Kd3Bfc2V0X2ludGVybmFsX2VuY29kaW5nKCk7CgovLyBSdW4gd3BfY2FjaGVfcG9zdGxvYWQoKSBpZiBvYmplY3QgY2FjaGUgaXMgZW5hYmxlZCBhbmQgdGhlIGZ1bmN0aW9uIGV4aXN0cy4KaWYgKCBXUF9DQUNIRSAmJiBmdW5jdGlvbl9leGlzdHMoICd3cF9jYWNoZV9wb3N0bG9hZCcgKSApIHsKCXdwX2NhY2hlX3Bvc3Rsb2FkKCk7Cn0KCmRvX2FjdGlvbiggJ3BsdWdpbnNfbG9hZGVkJyApOwoKLy8gRGVmaW5lIGNvbnN0YW50cyB3aGljaCBhZmZlY3QgZnVuY3Rpb25hbGl0eSBpZiBub3QgYWxyZWFkeSBkZWZpbmVkLgp3cF9mdW5jdGlvbmFsaXR5X2NvbnN0YW50cygpOwoKaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ2dldF9tYWdpY19xdW90ZXNfZ3BjJyApICkgewoJLy8gUHJvdmlkZSBjb21wYXQgZmFsbGJhY2sgZm9yIG5ld2VyIFBIUCB2ZXJzaW9uICg3LjQrKSBvbiBvbGRlciBXb3JkUHJlc3MgY29yZSB2ZXJzaW9ucy4KCWZ1bmN0aW9uIGdldF9tYWdpY19xdW90ZXNfZ3BjKCkgewoJCXJldHVybiBmYWxzZTsKCX0KfQoKLy8gQWRkIG1hZ2ljIHF1b3RlcyBhbmQgc2V0IHVwICRfUkVRVUVTVCAoICRfR0VUICsgJF9QT1NUICkKd3BfbWFnaWNfcXVvdGVzKCk7Cgpkb19hY3Rpb24oICdzYW5pdGl6ZV9jb21tZW50X2Nvb2tpZXMnICk7CgovKioKICogV29yZFByZXNzIFF1ZXJ5IG9iamVjdAogKiBAZ2xvYmFsIG9iamVjdCAkd3BfdGhlX3F1ZXJ5CiAqIEBzaW5jZSAyLjAuMAogKi8KJEdMT0JBTFNbJ3dwX3RoZV9xdWVyeSddID0gbmV3IFdQX1F1ZXJ5KCk7CgovKioKICogSG9sZHMgdGhlIHJlZmVyZW5jZSB0byBAc2VlICR3cF90aGVfcXVlcnkKICogVXNlIHRoaXMgZ2xvYmFsIGZvciBXb3JkUHJlc3MgcXVlcmllcwogKiBAZ2xvYmFsIG9iamVjdCAkd3BfcXVlcnkKICogQHNpbmNlIDEuNS4wCiAqLwokR0xPQkFMU1snd3BfcXVlcnknXSA9ICRHTE9CQUxTWyd3cF90aGVfcXVlcnknXTsKCi8qKgogKiBIb2xkcyB0aGUgV29yZFByZXNzIFJld3JpdGUgb2JqZWN0IGZvciBjcmVhdGluZyBwcmV0dHkgVVJMcwogKiBAZ2xvYmFsIG9iamVjdCAkd3BfcmV3cml0ZQogKiBAc2luY2UgMS41LjAKICovCiRHTE9CQUxTWyd3cF9yZXdyaXRlJ10gPSBuZXcgV1BfUmV3cml0ZSgpOwoKLyoqCiAqIFdvcmRQcmVzcyBPYmplY3QKICogQGdsb2JhbCBvYmplY3QgJHdwCiAqIEBzaW5jZSAyLjAuMAogKi8KJEdMT0JBTFNbJ3dwJ10gPSBuZXcgV1AoKTsKCi8qKgogKiBXb3JkUHJlc3MgV2lkZ2V0IEZhY3RvcnkgT2JqZWN0CiAqIEBnbG9iYWwgb2JqZWN0ICR3cF93aWRnZXRfZmFjdG9yeQogKiBAc2luY2UgMi44LjAKICovCiRHTE9CQUxTWyd3cF93aWRnZXRfZmFjdG9yeSddID0gbmV3IFdQX1dpZGdldF9GYWN0b3J5KCk7CgovKioKICogV29yZFByZXNzIFVzZXIgUm9sZXMKICogQGdsb2JhbCBvYmplY3QgJHdwX3JvbGVzCiAqIEBzaW5jZSAyLjAuMAogKi8KJEdMT0JBTFNbJ3dwX3JvbGVzJ10gPSBuZXcgV1BfUm9sZXMoKTsKCmRvX2FjdGlvbiggJ3NldHVwX3RoZW1lJyApOwoKLy8gRGVmaW5lIHRoZSB0ZW1wbGF0ZSByZWxhdGVkIGNvbnN0YW50cy4Kd3BfdGVtcGxhdGluZ19jb25zdGFudHMoKTsKCi8vIExvYWQgdGhlIGRlZmF1bHQgdGV4dCBsb2NhbGl6YXRpb24gZG9tYWluLgpsb2FkX2RlZmF1bHRfdGV4dGRvbWFpbigpOwoKJGxvY2FsZSAgICAgID0gZ2V0X2xvY2FsZSgpOwokbG9jYWxlX2ZpbGUgPSBXUF9MQU5HX0RJUiAuICIvJGxvY2FsZS5waHAiOwppZiAoICggMCA9PT0gdmFsaWRhdGVfZmlsZSggJGxvY2FsZSApICkgJiYgaXNfcmVhZGFibGUoICRsb2NhbGVfZmlsZSApICkgewoJcmVxdWlyZSAkbG9jYWxlX2ZpbGU7Cn0KdW5zZXQoICRsb2NhbGVfZmlsZSApOwoKLy8gUHVsbCBpbiBsb2NhbGUgZGF0YSBhZnRlciBsb2FkaW5nIHRleHQgZG9tYWluLgpyZXF1aXJlX29uY2UgQUJTUEFUSCAuIFdQSU5DIC4gJy9sb2NhbGUucGhwJzsKCi8qKgogKiBXb3JkUHJlc3MgTG9jYWxlIG9iamVjdCBmb3IgbG9hZGluZyBsb2NhbGUgZG9tYWluIGRhdGUgYW5kIHZhcmlvdXMgc3RyaW5ncy4KICogQGdsb2JhbCBvYmplY3QgJHdwX2xvY2FsZQogKiBAc2luY2UgMi4xLjAKICovCiRHTE9CQUxTWyd3cF9sb2NhbGUnXSA9IG5ldyBXUF9Mb2NhbGUoKTsKCi8vIExvYWQgdGhlIGZ1bmN0aW9ucyBmb3IgdGhlIGFjdGl2ZSB0aGVtZSwgZm9yIGJvdGggcGFyZW50IGFuZCBjaGlsZCB0aGVtZSBpZiBhcHBsaWNhYmxlLgovLyBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5XUC5EaXNjb3VyYWdlZENvbnN0YW50cy5TVFlMRVNIRUVUUEFUSFVzYWdlRm91bmQsV29yZFByZXNzLldQLkRpc2NvdXJhZ2VkQ29uc3RhbnRzLlRFTVBMQVRFUEFUSFVzYWdlRm91bmQKZ2xvYmFsICRwYWdlbm93OwppZiAoICEgZGVmaW5lZCggJ1dQX0lOU1RBTExJTkcnICkgfHwgJ3dwLWFjdGl2YXRlLnBocCcgPT09ICRwYWdlbm93ICkgewoJaWYgKCBURU1QTEFURVBBVEggIT09IFNUWUxFU0hFRVRQQVRIICYmIGZpbGVfZXhpc3RzKCBTVFlMRVNIRUVUUEFUSCAuICcvZnVuY3Rpb25zLnBocCcgKSApIHsKCQlpbmNsdWRlIFNUWUxFU0hFRVRQQVRIIC4gJy9mdW5jdGlvbnMucGhwJzsKCX0KCWlmICggZmlsZV9leGlzdHMoIFRFTVBMQVRFUEFUSCAuICcvZnVuY3Rpb25zLnBocCcgKSApIHsKCQlpbmNsdWRlIFRFTVBMQVRFUEFUSCAuICcvZnVuY3Rpb25zLnBocCc7Cgl9Cn0KLy8gcGhwY3M6ZW5hYmxlIFdvcmRQcmVzcy5XUC5EaXNjb3VyYWdlZENvbnN0YW50cwoKZG9fYWN0aW9uKCAnYWZ0ZXJfc2V0dXBfdGhlbWUnICk7CgovLyBTZXQgdXAgY3VycmVudCB1c2VyLgokR0xPQkFMU1snd3AnXS0+aW5pdCgpOwoKLyoqCiAqIE1vc3Qgb2YgV1AgaXMgbG9hZGVkIGF0IHRoaXMgc3RhZ2UsIGFuZCB0aGUgdXNlciBpcyBhdXRoZW50aWNhdGVkLiBXUCBjb250aW51ZXMKICogdG8gbG9hZCBvbiB0aGUgaW5pdCBob29rIHRoYXQgZm9sbG93cyAoZS5nLiB3aWRnZXRzKSwgYW5kIG1hbnkgcGx1Z2lucyBpbnN0YW50aWF0ZQogKiB0aGVtc2VsdmVzIG9uIGl0IGZvciBhbGwgc29ydHMgb2YgcmVhc29ucyAoZS5nLiB0aGV5IG5lZWQgYSB1c2VyLCBhIHRheG9ub215LCBldGMuKS4KICoKICogSWYgeW91IHdpc2ggdG8gcGx1ZyBhbiBhY3Rpb24gb25jZSBXUCBpcyBsb2FkZWQsIHVzZSB0aGUgd3BfbG9hZGVkIGhvb2sgYmVsb3cuCiAqLwpkb19hY3Rpb24oICdpbml0JyApOwoKLy8gQ2hlY2sgc2l0ZSBzdGF0dXMKIyBpZiAoIGlzX211bHRpc2l0ZSgpICkgeyAgLy8gV1AtQ0xJCmlmICggaXNfbXVsdGlzaXRlKCkgJiYgISBkZWZpbmVkKCAnV1BfSU5TVEFMTElORycgKSApIHsKCSRmaWxlID0gbXNfc2l0ZV9jaGVjaygpOwoJaWYgKCB0cnVlICE9PSAkZmlsZSApIHsKCQlyZXF1aXJlICRmaWxlOwoJCWRpZSgpOwoJfQoJdW5zZXQoICRmaWxlICk7Cn0KCi8qKgogKiBUaGlzIGhvb2sgaXMgZmlyZWQgb25jZSBXUCwgYWxsIHBsdWdpbnMsIGFuZCB0aGUgdGhlbWUgYXJlIGZ1bGx5IGxvYWRlZCBhbmQgaW5zdGFudGlhdGVkLgogKgogKiBBSkFYIHJlcXVlc3RzIHNob3VsZCB1c2Ugd3AtYWRtaW4vYWRtaW4tYWpheC5waHAuIGFkbWluLWFqYXgucGhwIGNhbiBoYW5kbGUgcmVxdWVzdHMgZm9yCiAqIHVzZXJzIG5vdCBsb2dnZWQgaW4uCiAqCiAqIEBsaW5rIGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9BSkFYX2luX1BsdWdpbnMKICoKICogQHNpbmNlIDMuMC4wCiAqLwpkb19hY3Rpb24oICd3cF9sb2FkZWQnICk7Cjw/cGhwCgovKioKICogQmFzZSBjbGFzcyBmb3IgV1AtQ0xJIGNvbW1hbmRzCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KYWJzdHJhY3QgY2xhc3MgV1BfQ0xJX0NvbW1hbmQgewoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHt9Cn0KCjw/cGhwCgp1c2UgY2xpXENvbG9yczsKdXNlIE11c3Rhbmdvc3RhbmdcU3B5YzsKdXNlIFdQX0NMSVxDb25maWd1cmF0b3I7CnVzZSBXUF9DTElcRGlzcGF0Y2hlcjsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmRBZGRpdGlvbjsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmRGYWN0b3J5Owp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZTsKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXENvbXBvc2l0ZUNvbW1hbmQ7CnVzZSBXUF9DTElcRGlzcGF0Y2hlclxSb290Q29tbWFuZDsKdXNlIFdQX0NMSVxEb2NQYXJzZXI7CnVzZSBXUF9DTElcRXhpdEV4Y2VwdGlvbjsKdXNlIFdQX0NMSVxGaWxlQ2FjaGU7CnVzZSBXUF9DTElcTG9nZ2Vyc1xFeGVjdXRpb247CnVzZSBXUF9DTElcUHJvY2VzczsKdXNlIFdQX0NMSVxQcm9jZXNzUnVuOwp1c2UgV1BfQ0xJXFJ1bm5lcjsKdXNlIFdQX0NMSVxTeW5vcHNpc1BhcnNlcjsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxXcEh0dHBDYWNoZU1hbmFnZXI7CgovKioKICogVmFyaW91cyB1dGlsaXRpZXMgZm9yIFdQLUNMSSBjb21tYW5kcy4KICovCmNsYXNzIFdQX0NMSSB7CgoJcHJpdmF0ZSBzdGF0aWMgJGxvZ2dlcjsKCglwcml2YXRlIHN0YXRpYyAkaG9va3MgPSBbXTsKCglwcml2YXRlIHN0YXRpYyAkaG9va3NfcGFzc2VkID0gW107CgoJcHJpdmF0ZSBzdGF0aWMgJGNhcHR1cmVfZXhpdCA9IGZhbHNlOwoKCXByaXZhdGUgc3RhdGljICRkZWZlcnJlZF9hZGRpdGlvbnMgPSBbXTsKCgkvKioKCSAqIFNldCB0aGUgbG9nZ2VyIGluc3RhbmNlLgoJICoKCSAqIEBwYXJhbSBvYmplY3QgJGxvZ2dlcgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldF9sb2dnZXIoICRsb2dnZXIgKSB7CgkJc2VsZjo6JGxvZ2dlciA9ICRsb2dnZXI7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIENvbmZpZ3VyYXRvciBpbnN0YW5jZQoJICoKCSAqIEByZXR1cm4gQ29uZmlndXJhdG9yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NvbmZpZ3VyYXRvcigpIHsKCQlzdGF0aWMgJGNvbmZpZ3VyYXRvcjsKCgkJaWYgKCAhICRjb25maWd1cmF0b3IgKSB7CgkJCSRjb25maWd1cmF0b3IgPSBuZXcgQ29uZmlndXJhdG9yKCBXUF9DTElfUk9PVCAuICcvcGhwL2NvbmZpZy1zcGVjLnBocCcgKTsKCQl9CgoJCXJldHVybiAkY29uZmlndXJhdG9yOwoJfQoKCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X3Jvb3RfY29tbWFuZCgpIHsKCQlzdGF0aWMgJHJvb3Q7CgoJCWlmICggISAkcm9vdCApIHsKCQkJJHJvb3QgPSBuZXcgUm9vdENvbW1hbmQoKTsKCQl9CgoJCXJldHVybiAkcm9vdDsKCX0KCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9ydW5uZXIoKSB7CgkJc3RhdGljICRydW5uZXI7CgoJCWlmICggISAkcnVubmVyICkgewoJCQkkcnVubmVyID0gbmV3IFJ1bm5lcigpOwoJCX0KCgkJcmV0dXJuICRydW5uZXI7Cgl9CgoJLyoqCgkgKiBAcmV0dXJuIEZpbGVDYWNoZQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9jYWNoZSgpIHsKCQlzdGF0aWMgJGNhY2hlOwoKCQlpZiAoICEgJGNhY2hlICkgewoJCQkkaG9tZSA9IFV0aWxzXGdldF9ob21lX2RpcigpOwoJCQkkZGlyICA9IGdldGVudiggJ1dQX0NMSV9DQUNIRV9ESVInICkgPyA6ICIkaG9tZS8ud3AtY2xpL2NhY2hlIjsKCgkJCS8vIDYgbW9udGhzLCAzMDBtYgoJCQkkY2FjaGUgPSBuZXcgRmlsZUNhY2hlKCAkZGlyLCAxNTU1MjAwMCwgMzE0NTcyODAwICk7CgoJCQkvLyBDbGVhbiBvbGRlciBmaWxlcyBvbiBzaHV0ZG93biB3aXRoIDEvNTAgcHJvYmFiaWxpdHkuCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuQWx0ZXJuYXRpdmVGdW5jdGlvbnMucmFuZF9tdF9yYW5kIC0tIG5vIGNyeXB0byBhbmQgV1Agbm90IGxvYWRlZC4KCQkJaWYgKCAwID09PSBtdF9yYW5kKCAwLCA1MCApICkgewoJCQkJcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oCgkJCQkJZnVuY3Rpb24gKCkgdXNlICggJGNhY2hlICkgewoJCQkJCQkkY2FjaGUtPmNsZWFuKCk7CgkJCQkJfQoJCQkJKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRjYWNoZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgY29udGV4dCBpbiB3aGljaCBXUC1DTEkgc2hvdWxkIGJlIHJ1bgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldF91cmwoICR1cmwgKSB7CgkJc2VsZjo6ZGVidWcoICdTZXQgVVJMOiAnIC4gJHVybCwgJ2Jvb3RzdHJhcCcgKTsKCQkkdXJsX3BhcnRzID0gVXRpbHNccGFyc2VfdXJsKCAkdXJsICk7CgkJc2VsZjo6c2V0X3VybF9wYXJhbXMoICR1cmxfcGFydHMgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzZXRfdXJsX3BhcmFtcyggJHVybF9wYXJ0cyApIHsKCQkkZiA9IGZ1bmN0aW9uKCAka2V5ICkgdXNlICggJHVybF9wYXJ0cyApIHsKCQkJcmV0dXJuIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkdXJsX3BhcnRzLCAka2V5LCAnJyApOwoJCX07CgoJCWlmICggaXNzZXQoICR1cmxfcGFydHNbJ2hvc3QnXSApICkgewoJCQlpZiAoIGlzc2V0KCAkdXJsX3BhcnRzWydzY2hlbWUnXSApICYmICdodHRwcycgPT09IHN0cnRvbG93ZXIoICR1cmxfcGFydHNbJ3NjaGVtZSddICkgKSB7CgkJCQkkX1NFUlZFUlsnSFRUUFMnXSA9ICdvbic7CgkJCX0KCgkJCSRfU0VSVkVSWydIVFRQX0hPU1QnXSA9ICR1cmxfcGFydHNbJ2hvc3QnXTsKCQkJaWYgKCBpc3NldCggJHVybF9wYXJ0c1sncG9ydCddICkgKSB7CgkJCQkkX1NFUlZFUlsnSFRUUF9IT1NUJ10gLj0gJzonIC4gJHVybF9wYXJ0c1sncG9ydCddOwoJCQl9CgoJCQkkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSA9ICR1cmxfcGFydHNbJ2hvc3QnXTsKCQl9CgoJCSRfU0VSVkVSWydSRVFVRVNUX1VSSSddICA9ICRmKCAncGF0aCcgKSAuICggaXNzZXQoICR1cmxfcGFydHNbJ3F1ZXJ5J10gKSA/ICc/JyAuICR1cmxfcGFydHNbJ3F1ZXJ5J10gOiAnJyApOwoJCSRfU0VSVkVSWydTRVJWRVJfUE9SVCddICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkdXJsX3BhcnRzLCAncG9ydCcsICc4MCcgKTsKCQkkX1NFUlZFUlsnUVVFUllfU1RSSU5HJ10gPSAkZiggJ3F1ZXJ5JyApOwoJfQoKCS8qKgoJICogQHJldHVybiBXcEh0dHBDYWNoZU1hbmFnZXIKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRfaHR0cF9jYWNoZV9tYW5hZ2VyKCkgewoJCXN0YXRpYyAkaHR0cF9jYWNoZXI7CgoJCWlmICggISAkaHR0cF9jYWNoZXIgKSB7CgkJCSRodHRwX2NhY2hlciA9IG5ldyBXcEh0dHBDYWNoZU1hbmFnZXIoIHNlbGY6OmdldF9jYWNoZSgpICk7CgkJfQoKCQlyZXR1cm4gJGh0dHBfY2FjaGVyOwoJfQoKCS8qKgoJICogQ29sb3JpemUgYSBzdHJpbmcgZm9yIG91dHB1dC4KCSAqCgkgKiBZZXMsIHlvdSBjYW4gY2hhbmdlIHRoZSBjb2xvciBvZiBjb21tYW5kIGxpbmUgdGV4dCB0b28uIEZvciBpbnN0YW5jZSwKCSAqIGhlcmUncyBob3cgYFdQX0NMSTo6c3VjY2VzcygpYCBjb2xvcml6ZXMgIlN1Y2Nlc3M6ICIKCSAqCgkgKiBgYGAKCSAqIFdQX0NMSTo6Y29sb3JpemUoICIlR1N1Y2Nlc3M6JW4gIiApCgkgKiBgYGAKCSAqCgkgKiBVc2VzIGBcY2xpXENvbG9yczo6Y29sb3JpemUoKWAgdG8gdHJhbnNmb3JtIGNvbG9yIHRva2VucyB0byBkaXNwbGF5CgkgKiBzZXR0aW5ncy4gQ2hvb3NlIGZyb20gdGhlIGZvbGxvd2luZyB0b2tlbnMgKGFuZCBub3RlICdyZXNldCcpOgoJICoKCSAqICogJXkgPT4gWydjb2xvcicgPT4gJ3llbGxvdyddLAoJICogKiAlZyA9PiBbJ2NvbG9yJyA9PiAnZ3JlZW4nXSwKCSAqICogJWIgPT4gWydjb2xvcicgPT4gJ2JsdWUnXSwKCSAqICogJXIgPT4gWydjb2xvcicgPT4gJ3JlZCddLAoJICogKiAlcCA9PiBbJ2NvbG9yJyA9PiAnbWFnZW50YSddLAoJICogKiAlbSA9PiBbJ2NvbG9yJyA9PiAnbWFnZW50YSddLAoJICogKiAlYyA9PiBbJ2NvbG9yJyA9PiAnY3lhbiddLAoJICogKiAldyA9PiBbJ2NvbG9yJyA9PiAnZ3JleSddLAoJICogKiAlayA9PiBbJ2NvbG9yJyA9PiAnYmxhY2snXSwKCSAqICogJW4gPT4gWydjb2xvcicgPT4gJ3Jlc2V0J10sCgkgKiAqICVZID0+IFsnY29sb3InID0+ICd5ZWxsb3cnLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJUcgPT4gWydjb2xvcicgPT4gJ2dyZWVuJywgJ3N0eWxlJyA9PiAnYnJpZ2h0J10sCgkgKiAqICVCID0+IFsnY29sb3InID0+ICdibHVlJywgJ3N0eWxlJyA9PiAnYnJpZ2h0J10sCgkgKiAqICVSID0+IFsnY29sb3InID0+ICdyZWQnLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJVAgPT4gWydjb2xvcicgPT4gJ21hZ2VudGEnLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJU0gPT4gWydjb2xvcicgPT4gJ21hZ2VudGEnLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJUMgPT4gWydjb2xvcicgPT4gJ2N5YW4nLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJVcgPT4gWydjb2xvcicgPT4gJ2dyZXknLCAnc3R5bGUnID0+ICdicmlnaHQnXSwKCSAqICogJUsgPT4gWydjb2xvcicgPT4gJ2JsYWNrJywgJ3N0eWxlJyA9PiAnYnJpZ2h0J10sCgkgKiAqICVOID0+IFsnY29sb3InID0+ICdyZXNldCcsICdzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlMyA9PiBbJ2JhY2tncm91bmQnID0+ICd5ZWxsb3cnXSwKCSAqICogJTIgPT4gWydiYWNrZ3JvdW5kJyA9PiAnZ3JlZW4nXSwKCSAqICogJTQgPT4gWydiYWNrZ3JvdW5kJyA9PiAnYmx1ZSddLAoJICogKiAlMSA9PiBbJ2JhY2tncm91bmQnID0+ICdyZWQnXSwKCSAqICogJTUgPT4gWydiYWNrZ3JvdW5kJyA9PiAnbWFnZW50YSddLAoJICogKiAlNiA9PiBbJ2JhY2tncm91bmQnID0+ICdjeWFuJ10sCgkgKiAqICU3ID0+IFsnYmFja2dyb3VuZCcgPT4gJ2dyZXknXSwKCSAqICogJTAgPT4gWydiYWNrZ3JvdW5kJyA9PiAnYmxhY2snXSwKCSAqICogJUYgPT4gWydzdHlsZScgPT4gJ2JsaW5rJ10sCgkgKiAqICVVID0+IFsnc3R5bGUnID0+ICd1bmRlcmxpbmUnXSwKCSAqICogJTggPT4gWydzdHlsZScgPT4gJ2ludmVyc2UnXSwKCSAqICogJTkgPT4gWydzdHlsZScgPT4gJ2JyaWdodCddLAoJICogKiAlXyA9PiBbJ3N0eWxlJyA9PiAnYnJpZ2h0J10KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBTdHJpbmcgdG8gY29sb3JpemUgZm9yIG91dHB1dCwgd2l0aCBjb2xvciB0b2tlbnMuCgkgKiBAcmV0dXJuIHN0cmluZyBDb2xvcml6ZWQgc3RyaW5nLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbG9yaXplKCAkc3RyaW5nICkgewoJCXJldHVybiBDb2xvcnM6OmNvbG9yaXplKCAkc3RyaW5nLCBzZWxmOjpnZXRfcnVubmVyKCktPmluX2NvbG9yKCkgKTsKCX0KCgkvKioKCSAqIFNjaGVkdWxlIGEgY2FsbGJhY2sgdG8gYmUgZXhlY3V0ZWQgYXQgYSBjZXJ0YWluIHBvaW50LgoJICoKCSAqIEhvb2tzIGNvbmNlcHR1YWxseSBhcmUgdmVyeSBzaW1pbGFyIHRvIFdvcmRQcmVzcyBhY3Rpb25zLiBXUC1DTEkgaG9va3MKCSAqIGFyZSB0eXBpY2FsbHkgY2FsbGVkIGJlZm9yZSBXb3JkUHJlc3MgaXMgbG9hZGVkLgoJICoKCSAqIFdQLUNMSSBob29rcyBpbmNsdWRlOgoJICoKCSAqICogYGJlZm9yZV9hZGRfY29tbWFuZDo8Y29tbWFuZD5gIC0gQmVmb3JlIHRoZSBjb21tYW5kIGlzIGFkZGVkLgoJICogKiBgYWZ0ZXJfYWRkX2NvbW1hbmQ6PGNvbW1hbmQ+YCAtIEFmdGVyIHRoZSBjb21tYW5kIHdhcyBhZGRlZC4KCSAqICogYGJlZm9yZV9pbnZva2U6PGNvbW1hbmQ+YCAtIEp1c3QgYmVmb3JlIGEgY29tbWFuZCBpcyBpbnZva2VkLgoJICogKiBgYWZ0ZXJfaW52b2tlOjxjb21tYW5kPmAgLSBKdXN0IGFmdGVyIGEgY29tbWFuZCBpcyBpbnZva2VkLgoJICogKiBgZmluZF9jb21tYW5kX3RvX3J1bl9wcmVgIC0gSnVzdCBiZWZvcmUgV1AtQ0xJIGZpbmRzIHRoZSBjb21tYW5kIHRvIHJ1bi4KCSAqICogYGJlZm9yZV93cF9sb2FkYCAtIEp1c3QgYmVmb3JlIHRoZSBXUCBsb2FkIHByb2Nlc3MgYmVnaW5zLgoJICogKiBgYmVmb3JlX3dwX2NvbmZpZ19sb2FkYCAtIEFmdGVyIHdwLWNvbmZpZy5waHAgaGFzIGJlZW4gbG9jYXRlZC4KCSAqICogYGFmdGVyX3dwX2NvbmZpZ19sb2FkYCAtIEFmdGVyIHdwLWNvbmZpZy5waHAgaGFzIGJlZW4gbG9hZGVkIGludG8gc2NvcGUuCgkgKiAqIGBhZnRlcl93cF9sb2FkYCAtIEp1c3QgYWZ0ZXIgdGhlIFdQIGxvYWQgcHJvY2VzcyBoYXMgY29tcGxldGVkLgoJICogKiBgYmVmb3JlX3J1bl9jb21tYW5kYCAtIEp1c3QgYmVmb3JlIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkLgoJICoKCSAqIFdQLUNMSSBjb21tYW5kcyBjYW4gY3JlYXRlIHRoZWlyIG93biBob29rcyB3aXRoIGBXUF9DTEk6OmRvX2hvb2soKWAuCgkgKgoJICogSWYgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHBhc3NlZCB0aHJvdWdoIHRoZSBgV1BfQ0xJOjpkb19ob29rKClgIGNhbGwsCgkgKiB0aGVzZSB3aWxsIGJlIHBhc3NlZCBvbiB0byB0aGUgY2FsbGJhY2sgcHJvdmlkZWQgYnkgYFdQX0NMSTo6YWRkX2hvb2soKWAuCgkgKgoJICogYGBgCgkgKiAjIGB3cCBuZXR3b3JrIG1ldGFgIGNvbmZpcm1zIGNvbW1hbmQgaXMgZXhlY3V0aW5nIGluIG11bHRpc2l0ZSBjb250ZXh0LgoJICogV1BfQ0xJOjphZGRfY29tbWFuZCggJ25ldHdvcmsgbWV0YScsICdOZXR3b3JrX01ldGFfQ29tbWFuZCcsIGFycmF5KAoJICogICAgJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uICgpIHsKCSAqICAgICAgICBpZiAoICFpc19tdWx0aXNpdGUoKSApIHsKCSAqICAgICAgICAgICAgV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkgKiAgICAgICAgfQoJICogICAgfQoJICogKSApOwoJICogYGBgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBSZWdpc3RyYXRpb24KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3aGVuIElkZW50aWZpZXIgZm9yIHRoZSBob29rLgoJICogQHBhcmFtIG1peGVkICRjYWxsYmFjayBDYWxsYmFjayB0byBleGVjdXRlIHdoZW4gaG9vayBpcyBjYWxsZWQuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRfaG9vayggJHdoZW4sICRjYWxsYmFjayApIHsKCQlpZiAoIGFycmF5X2tleV9leGlzdHMoICR3aGVuLCBzZWxmOjokaG9va3NfcGFzc2VkICkgKSB7CgkJCXNlbGY6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknSW1tZWRpYXRlbHkgaW52b2tpbmcgb24gcGFzc2VkIGhvb2sgIiVzIjogJXMnLAoJCQkJCSR3aGVuLAoJCQkJCVV0aWxzXGRlc2NyaWJlX2NhbGxhYmxlKCAkY2FsbGJhY2sgKQoJCQkJKSwKCQkJCSdob29rcycKCQkJKTsKCQkJY2FsbF91c2VyX2Z1bmNfYXJyYXkoICRjYWxsYmFjaywgKGFycmF5KSBzZWxmOjokaG9va3NfcGFzc2VkWyAkd2hlbiBdICk7CgkJfQoKCQlzZWxmOjokaG9va3NbICR3aGVuIF1bXSA9ICRjYWxsYmFjazsKCX0KCgkvKioKCSAqIEV4ZWN1dGUgY2FsbGJhY2tzIHJlZ2lzdGVyZWQgdG8gYSBnaXZlbiBob29rLgoJICoKCSAqIFNlZSBgV1BfQ0xJOjphZGRfaG9vaygpYCBmb3IgZGV0YWlscyBvbiBXUC1DTEkncyBpbnRlcm5hbCBob29rIHN5c3RlbS4KCSAqIENvbW1hbmRzIGNhbiBwcm92aWRlIGFuZCBjYWxsIHRoZWlyIG93biBob29rcy4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IFJlZ2lzdHJhdGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdoZW4gSWRlbnRpZmllciBmb3IgdGhlIGhvb2suCgkgKiBAcGFyYW0gbWl4ZWQgLi4uIE9wdGlvbmFsLiBBcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCBvbnRvIHRoZQoJICogICAgICAgICAgICAgICAgICBjYWxsYmFjayBwcm92aWRlZCBieSBgV1BfQ0xJOjphZGRfaG9vaygpYC4KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGRvX2hvb2soICR3aGVuICkgewoKCQkkYXJncyA9IGZ1bmNfbnVtX2FyZ3MoKSA+IDEKCQkJPyBhcnJheV9zbGljZSggZnVuY19nZXRfYXJncygpLCAxICkKCQkJOiBbXTsKCgkJc2VsZjo6JGhvb2tzX3Bhc3NlZFsgJHdoZW4gXSA9ICRhcmdzOwoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OiRob29rc1sgJHdoZW4gXSApICkgewoJCQlyZXR1cm47CgkJfQoKCQlzZWxmOjpkZWJ1ZygKCQkJc3ByaW50ZigKCQkJCSdQcm9jZXNzaW5nIGhvb2sgIiVzIiB3aXRoICVkIGNhbGxiYWNrcycsCgkJCQkkd2hlbiwKCQkJCWNvdW50KCBzZWxmOjokaG9va3NbICR3aGVuIF0gKQoJCQkpLAoJCQknaG9va3MnCgkJKTsKCgkJZm9yZWFjaCAoIHNlbGY6OiRob29rc1sgJHdoZW4gXSBhcyAkY2FsbGJhY2sgKSB7CgkJCXNlbGY6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknT24gaG9vayAiJXMiOiAlcycsCgkJCQkJJHdoZW4sCgkJCQkJVXRpbHNcZGVzY3JpYmVfY2FsbGFibGUoICRjYWxsYmFjayApCgkJCQkpLAoJCQkJJ2hvb2tzJwoJCQkpOwoJCQljYWxsX3VzZXJfZnVuY19hcnJheSggJGNhbGxiYWNrLCAkYXJncyApOwoJCX0KCX0KCgkvKioKCSAqIEFkZCBhIGNhbGxiYWNrIHRvIGEgV29yZFByZXNzIGFjdGlvbiBvciBmaWx0ZXIuCgkgKgoJICogYGFkZF9hY3Rpb24oKWAgd2l0aG91dCBuZWVkaW5nIGFjY2VzcyB0byBgYWRkX2FjdGlvbigpYC4gSWYgV29yZFByZXNzIGlzCgkgKiBhbHJlYWR5IGxvYWRlZCB0aG91Z2gsIHlvdSBzaG91bGQgdXNlIGBhZGRfYWN0aW9uKClgIChhbmQgYGFkZF9maWx0ZXIoKWApCgkgKiBpbnN0ZWFkLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgUmVnaXN0cmF0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGFnIE5hbWVkIFdvcmRQcmVzcyBhY3Rpb24gb3IgZmlsdGVyLgoJICogQHBhcmFtIG1peGVkICRmdW5jdGlvbl90b19hZGQgQ2FsbGFibGUgdG8gZXhlY3V0ZSB3aGVuIHRoZSBhY3Rpb24gb3IgZmlsdGVyIGlzIGV2YWx1YXRlZC4KCSAqIEBwYXJhbSBpbnRlZ2VyICRwcmlvcml0eSBQcmlvcml0eSB0byBhZGQgdGhlIGNhbGxiYWNrIGFzLgoJICogQHBhcmFtIGludGVnZXIgJGFjY2VwdGVkX2FyZ3MgTnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwYXNzIHRvIGNhbGxiYWNrLgoJICogQHJldHVybiB0cnVlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWRkX3dwX2hvb2soICR0YWcsICRmdW5jdGlvbl90b19hZGQsICRwcmlvcml0eSA9IDEwLCAkYWNjZXB0ZWRfYXJncyA9IDEgKSB7CgkJZ2xvYmFsICR3cF9maWx0ZXIsICRtZXJnZWRfZmlsdGVyczsKCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdhZGRfZmlsdGVyJyApICkgewoJCQlhZGRfZmlsdGVyKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHksICRhY2NlcHRlZF9hcmdzICk7CgkJfSBlbHNlIHsKCQkJJGlkeCA9IHNlbGY6OndwX2hvb2tfYnVpbGRfdW5pcXVlX2lkKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHkgKTsKCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBUaGlzIGlzIGludGVudGlvbmFsICYgdGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbi4KCQkJJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXVsgJGlkeCBdID0gWwoJCQkJJ2Z1bmN0aW9uJyAgICAgID0+ICRmdW5jdGlvbl90b19hZGQsCgkJCQknYWNjZXB0ZWRfYXJncycgPT4gJGFjY2VwdGVkX2FyZ3MsCgkJCV07CgkJCXVuc2V0KCAkbWVyZ2VkX2ZpbHRlcnNbICR0YWcgXSApOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBCdWlsZCBVbmlxdWUgSUQgZm9yIHN0b3JhZ2UgYW5kIHJldHJpZXZhbC4KCSAqCgkgKiBFc3NlbnRpYWxseSBfd3BfZmlsdGVyX2J1aWxkX3VuaXF1ZV9pZCgpIHdpdGhvdXQgbmVlZGluZyBhY2Nlc3MgdG8gX3dwX2ZpbHRlcl9idWlsZF91bmlxdWVfaWQoKQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB3cF9ob29rX2J1aWxkX3VuaXF1ZV9pZCggJHRhZywgJGZ1bmN0aW9uLCAkcHJpb3JpdHkgKSB7CgkJZ2xvYmFsICR3cF9maWx0ZXI7CgkJc3RhdGljICRmaWx0ZXJfaWRfY291bnQgPSAwOwoKCQlpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uICkgKSB7CgkJCXJldHVybiAkZnVuY3Rpb247CgkJfQoKCQlpZiAoIGlzX29iamVjdCggJGZ1bmN0aW9uICkgKSB7CgkJCS8vIENsb3N1cmVzIGFyZSBjdXJyZW50bHkgaW1wbGVtZW50ZWQgYXMgb2JqZWN0cwoJCQkkZnVuY3Rpb24gPSBbICRmdW5jdGlvbiwgJycgXTsKCQl9IGVsc2UgewoJCQkkZnVuY3Rpb24gPSAoYXJyYXkpICRmdW5jdGlvbjsKCQl9CgoJCWlmICggaXNfb2JqZWN0KCAkZnVuY3Rpb25bMF0gKSApIHsKCQkJLy8gT2JqZWN0IENsYXNzIENhbGxpbmcKCQkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdzcGxfb2JqZWN0X2hhc2gnICkgKSB7CgkJCQlyZXR1cm4gc3BsX29iamVjdF9oYXNoKCAkZnVuY3Rpb25bMF0gKSAuICRmdW5jdGlvblsxXTsKCQkJfQoKCQkJJG9ial9pZHggPSBnZXRfY2xhc3MoICRmdW5jdGlvblswXSApIC4gJGZ1bmN0aW9uWzFdOwoJCQlpZiAoICEgaXNzZXQoICRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkICkgKSB7CgkJCQlpZiAoIGZhbHNlID09PSAkcHJpb3JpdHkgKSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQkJJG9ial9pZHggICAgICAgICAgICAgICAgICAuPSBpc3NldCggJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXSApID8gY291bnQoIChhcnJheSkgJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXSApIDogJGZpbHRlcl9pZF9jb3VudDsKCQkJCSRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkID0gJGZpbHRlcl9pZF9jb3VudDsKCQkJCSsrJGZpbHRlcl9pZF9jb3VudDsKCQkJfSBlbHNlIHsKCQkJCSRvYmpfaWR4IC49ICRmdW5jdGlvblswXS0+d3BfZmlsdGVyX2lkOwoJCQl9CgoJCQlyZXR1cm4gJG9ial9pZHg7CgkJfQoKCQlpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uWzBdICkgKSB7CgkJCS8vIFN0YXRpYyBDYWxsaW5nCgkJCXJldHVybiAkZnVuY3Rpb25bMF0gLiAnOjonIC4gJGZ1bmN0aW9uWzFdOwoJCX0KCX0KCgkvKioKCSAqIFJlZ2lzdGVyIGEgY29tbWFuZCB0byBXUC1DTEkuCgkgKgoJICogV1AtQ0xJIHN1cHBvcnRzIHVzaW5nIGFueSBjYWxsYWJsZSBjbGFzcywgZnVuY3Rpb24sIG9yIGNsb3N1cmUgYXMgYQoJICogY29tbWFuZC4gYFdQX0NMSTo6YWRkX2NvbW1hbmQoKWAgaXMgdXNlZCBmb3IgYm90aCBpbnRlcm5hbCBhbmQKCSAqIHRoaXJkLXBhcnR5IGNvbW1hbmQgcmVnaXN0cmF0aW9uLgoJICoKCSAqIENvbW1hbmQgYXJndW1lbnRzIGFyZSBwYXJzZWQgZnJvbSBQSFBEb2MgYnkgZGVmYXVsdCwgYnV0IGFsc28gY2FuIGJlCgkgKiBzdXBwbGllZCBhcyBhbiBvcHRpb25hbCB0aGlyZCBhcmd1bWVudCBkdXJpbmcgcmVnaXN0cmF0aW9uLgoJICoKCSAqIGBgYAoJICogIyBSZWdpc3RlciBhIGN1c3RvbSAnZm9vJyBjb21tYW5kIHRvIG91dHB1dCBhIHN1cHBsaWVkIHBvc2l0aW9uYWwgcGFyYW0uCgkgKiAjCgkgKiAjICQgd3AgZm9vIGJhciAtLWFwcGVuZD1xdXgKCSAqICMgU3VjY2VzczogYmFyIHF1eAoJICoKCSAqIC8qKgoJICogICogTXkgYXdlc29tZSBjbG9zdXJlIGNvbW1hbmQKCSAqICAqCgkgKiAgKiA8bWVzc2FnZT4KCSAqICAqIDogQW4gYXdlc29tZSBtZXNzYWdlIHRvIGRpc3BsYXkKCSAqICAqCgkgKiAgKiAtLWFwcGVuZD08bWVzc2FnZT4KCSAqICAqIDogQW4gYXdlc29tZSBtZXNzYWdlIHRvIGFwcGVuZCB0byB0aGUgb3JpZ2luYWwgbWVzc2FnZS4KCSAqICAqCgkgKiAgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICogICpcLwoJICogJGZvbyA9IGZ1bmN0aW9uKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkgKiAgICAgV1BfQ0xJOjpzdWNjZXNzKCAkYXJnc1swXSAuICcgJyAuICRhc3NvY19hcmdzWydhcHBlbmQnXSApOwoJICogfTsKCSAqIFdQX0NMSTo6YWRkX2NvbW1hbmQoICdmb28nLCAkZm9vICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IFJlZ2lzdHJhdGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICAkbmFtZSBOYW1lIGZvciB0aGUgY29tbWFuZCAoZS5nLiAicG9zdCBsaXN0IiBvciAic2l0ZSBlbXB0eSIpLgoJICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYWJsZSBDb21tYW5kIGltcGxlbWVudGF0aW9uIGFzIGEgY2xhc3MsIGZ1bmN0aW9uIG9yIGNsb3N1cmUuCgkgKiBAcGFyYW0gYXJyYXkgICAgJGFyZ3MgewoJICogICAgT3B0aW9uYWwuIEFuIGFzc29jaWF0aXZlIGFycmF5IHdpdGggYWRkaXRpb25hbCByZWdpc3RyYXRpb24gcGFyYW1ldGVycy4KCSAqCgkgKiAgICBAdHlwZSBjYWxsYWJsZSAkYmVmb3JlX2ludm9rZSBDYWxsYmFjayB0byBleGVjdXRlIGJlZm9yZSBpbnZva2luZyB0aGUgY29tbWFuZC4KCSAqICAgIEB0eXBlIGNhbGxhYmxlICRhZnRlcl9pbnZva2UgIENhbGxiYWNrIHRvIGV4ZWN1dGUgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbW1hbmQuCgkgKiAgICBAdHlwZSBzdHJpbmcgICAkc2hvcnRkZXNjICAgICBTaG9ydCBkZXNjcmlwdGlvbiAoODAgY2hhciBvciBsZXNzKSBmb3IgdGhlIGNvbW1hbmQuCgkgKiAgICBAdHlwZSBzdHJpbmcgICAkbG9uZ2Rlc2MgICAgICBEZXNjcmlwdGlvbiBvZiBhcmJpdHJhcnkgbGVuZ3RoIGZvciBleGFtcGxlcywgZXRjLgoJICogICAgQHR5cGUgc3RyaW5nICAgJHN5bm9wc2lzICAgICAgVGhlIHN5bm9wc2lzIGZvciB0aGUgY29tbWFuZCAoc3RyaW5nIG9yIGFycmF5KS4KCSAqICAgIEB0eXBlIHN0cmluZyAgICR3aGVuICAgICAgICAgIEV4ZWN1dGUgY2FsbGJhY2sgb24gYSBuYW1lZCBXUC1DTEkgaG9vayAoZS5nLiBiZWZvcmVfd3BfbG9hZCkuCgkgKiAgICBAdHlwZSBib29sICAgICAkaXNfZGVmZXJyZWQgICBXaGV0aGVyIHRoZSBjb21tYW5kIGFkZGl0aW9uIGhhZCBhbHJlYWR5IGJlZW4gZGVmZXJyZWQuCgkgKiB9CgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBpZiBkZWZlcnJlZCwgaGFyZCBlcnJvciBpZiByZWdpc3RyYXRpb24gZmFpbGVkLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFkZF9jb21tYW5kKCAkbmFtZSwgJGNhbGxhYmxlLCAkYXJncyA9IFtdICkgewoJCS8vIEJhaWwgaW1tZWRpYXRlbHkgaWYgdGhlIFdQLUNMSSBleGVjdXRhYmxlIGhhcyBub3QgYmVlbiBydW4uCgkJaWYgKCAhIGRlZmluZWQoICdXUF9DTEknICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR2YWxpZCA9IGZhbHNlOwoJCWlmICggaXNfY2FsbGFibGUoICRjYWxsYWJsZSApICkgewoJCQkkdmFsaWQgPSB0cnVlOwoJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkY2FsbGFibGUgKSAmJiBjbGFzc19leGlzdHMoIChzdHJpbmcpICRjYWxsYWJsZSApICkgewoJCQkkdmFsaWQgPSB0cnVlOwoJCX0gZWxzZWlmICggaXNfb2JqZWN0KCAkY2FsbGFibGUgKSApIHsKCQkJJHZhbGlkID0gdHJ1ZTsKCQl9IGVsc2VpZiAoIFV0aWxzXGlzX3ZhbGlkX2NsYXNzX2FuZF9tZXRob2RfcGFpciggJGNhbGxhYmxlICkgKSB7CgkJCSR2YWxpZCA9IHRydWU7CgkJfQoJCWlmICggISAkdmFsaWQgKSB7CgkJCWlmICggaXNfYXJyYXkoICRjYWxsYWJsZSApICkgewoJCQkJJGNhbGxhYmxlWzBdID0gaXNfb2JqZWN0KCAkY2FsbGFibGVbMF0gKSA/IGdldF9jbGFzcyggJGNhbGxhYmxlWzBdICkgOiAkY2FsbGFibGVbMF07CgkJCQkkY2FsbGFibGUgICAgPSBbICRjYWxsYWJsZVswXSwgJGNhbGxhYmxlWzFdIF07CgkJCX0KCQkJc2VsZjo6ZXJyb3IoIHNwcmludGYoICdDYWxsYWJsZSAlcyBkb2VzIG5vdCBleGlzdCwgYW5kIGNhbm5vdCBiZSByZWdpc3RlcmVkIGFzIGB3cCAlc2AuJywganNvbl9lbmNvZGUoICRjYWxsYWJsZSApLCAkbmFtZSApICk7CgkJfQoKCQkkYWRkaXRpb24gPSBuZXcgQ29tbWFuZEFkZGl0aW9uKCk7CgkJc2VsZjo6ZG9faG9vayggImJlZm9yZV9hZGRfY29tbWFuZDp7JG5hbWV9IiwgJGFkZGl0aW9uICk7CgoJCWlmICggJGFkZGl0aW9uLT53YXNfYWJvcnRlZCgpICkgewoJCQlzZWxmOjp3YXJuaW5nKCAiQWJvcnRpbmcgdGhlIGFkZGl0aW9uIG9mIHRoZSBjb21tYW5kICd7JG5hbWV9JyB3aXRoIHJlYXNvbjogeyRhZGRpdGlvbi0+Z2V0X3JlYXNvbigpfS4iICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWZvcmVhY2ggKCBbICdiZWZvcmVfaW52b2tlJywgJ2FmdGVyX2ludm9rZScgXSBhcyAkd2hlbiApIHsKCQkJaWYgKCBpc3NldCggJGFyZ3NbICR3aGVuIF0gKSApIHsKCQkJCXNlbGY6OmFkZF9ob29rKCAieyR3aGVufTp7JG5hbWV9IiwgJGFyZ3NbICR3aGVuIF0gKTsKCQkJfQoJCX0KCgkJJHBhdGggPSBwcmVnX3NwbGl0KCAnL1xzKy8nLCAkbmFtZSApOwoKCQkkbGVhZl9uYW1lID0gYXJyYXlfcG9wKCAkcGF0aCApOwoKCQkkY29tbWFuZCA9IHNlbGY6OmdldF9yb290X2NvbW1hbmQoKTsKCgkJd2hpbGUgKCAhIGVtcHR5KCAkcGF0aCApICkgewoJCQkkc3ViY29tbWFuZF9uYW1lID0gJHBhdGhbMF07CgkJCSRwYXJlbnQgICAgICAgICAgPSBpbXBsb2RlKCAnICcsICRwYXRoICk7CgkJCSRzdWJjb21tYW5kICAgICAgPSAkY29tbWFuZC0+ZmluZF9zdWJjb21tYW5kKCAkcGF0aCApOwoKCQkJLy8gUGFyZW50IG5vdCBmb3VuZC4gRGVmZXIgYWRkaXRpb24gb3IgY3JlYXRlIGFuIGVtcHR5IGNvbnRhaW5lciBhcwoJCQkvLyBuZWVkZWQuCgkJCWlmICggISAkc3ViY29tbWFuZCApIHsKCQkJCWlmICggaXNzZXQoICRhcmdzWydpc19kZWZlcnJlZCddICkgJiYgJGFyZ3NbJ2lzX2RlZmVycmVkJ10gKSB7CgkJCQkJJHN1YmNvbW1hbmQgPSBuZXcgQ29tcG9zaXRlQ29tbWFuZCgKCQkJCQkJJGNvbW1hbmQsCgkJCQkJCSRzdWJjb21tYW5kX25hbWUsCgkJCQkJCW5ldyBEb2NQYXJzZXIoICcnICkKCQkJCQkpOwoKCQkJCQlzZWxmOjpkZWJ1ZygKCQkJCQkJIkFkZGluZyBlbXB0eSBjb250YWluZXIgZm9yIGRlZmVycmVkIGNvbW1hbmQ6IHskbmFtZX0iLAoJCQkJCQknY29tbWFuZHMnCgkJCQkJKTsKCgkJCQkJJGNvbW1hbmQtPmFkZF9zdWJjb21tYW5kKCAkc3ViY29tbWFuZF9uYW1lLCAkc3ViY29tbWFuZCApOwoJCQkJfSBlbHNlIHsKCQkJCQlzZWxmOjpkZWJ1ZyggIkRlZmVycmluZyBjb21tYW5kOiB7JG5hbWV9IiwgJ2NvbW1hbmRzJyApOwoKCQkJCQlzZWxmOjpkZWZlcl9jb21tYW5kX2FkZGl0aW9uKAoJCQkJCQkkbmFtZSwKCQkJCQkJJHBhcmVudCwKCQkJCQkJJGNhbGxhYmxlLAoJCQkJCQkkYXJncwoJCQkJCSk7CgoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfQoKCQkJJGNvbW1hbmQgPSAkc3ViY29tbWFuZDsKCQl9CgoJCSRsZWFmX2NvbW1hbmQgPSBDb21tYW5kRmFjdG9yeTo6Y3JlYXRlKCAkbGVhZl9uYW1lLCAkY2FsbGFibGUsICRjb21tYW5kICk7CgoJCS8vIE9ubHkgYWRkIGEgY29tbWFuZCBuYW1lc3BhY2UgaWYgdGhlIGNvbW1hbmQgaXRzZWxmIGRvZXMgbm90IGV4aXN0IHlldC4KCQlpZiAoICRsZWFmX2NvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kTmFtZXNwYWNlCgkJCSYmIGFycmF5X2tleV9leGlzdHMoICRsZWFmX25hbWUsICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBSZWF0dGFjaCBjb21tYW5kcyBhdHRhY2hlZCB0byBuYW1lc3BhY2UgdG8gcmVhbCBjb21tYW5kLgoJCSRzdWJjb21tYW5kX25hbWUgID0gKGFycmF5KSAkbGVhZl9uYW1lOwoJCSRleGlzdGluZ19jb21tYW5kID0gJGNvbW1hbmQtPmZpbmRfc3ViY29tbWFuZCggJHN1YmNvbW1hbmRfbmFtZSApOwoJCWlmICggZmFsc2UgIT09ICRleGlzdGluZ19jb21tYW5kICkgewoJCQkkc3ViY29tbWFuZHMgPSAkZXhpc3RpbmdfY29tbWFuZC0+Z2V0X3N1YmNvbW1hbmRzKCk7CgkJCWlmICggISBlbXB0eSggJHN1YmNvbW1hbmRzICkKCQkJCSYmICggJGxlYWZfY29tbWFuZCBpbnN0YW5jZW9mIENvbXBvc2l0ZUNvbW1hbmQKCQkJCQl8fCAkbGVhZl9jb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcyApICkgewoJCQkJZm9yZWFjaCAoICRzdWJjb21tYW5kcyBhcyAkc3VibmFtZSA9PiAkc3ViY29tbWFuZCApIHsKCQkJCQkkbGVhZl9jb21tYW5kLT5hZGRfc3ViY29tbWFuZCggJHN1Ym5hbWUsICRzdWJjb21tYW5kICk7CgkJCQl9CgkJCX0KCQl9CgoJCS8qKiBAdmFyIERpc3BhdGNoZXJcU3ViY29tbWFuZHxEaXNwYXRjaGVyXENvbXBvc2l0ZUNvbW1hbmR8RGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlICRsZWFmX2NvbW1hbmQgKi8KCgkJaWYgKCAhICRjb21tYW5kLT5jYW5faGF2ZV9zdWJjb21tYW5kcygpICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKAoJCQkJc3ByaW50ZigKCQkJCQkiJyVzJyBjYW4ndCBoYXZlIHN1YmNvbW1hbmRzLiIsCgkJCQkJaW1wbG9kZSggJyAnLCBnZXRfcGF0aCggJGNvbW1hbmQgKSApCgkJCQkpCgkJCSk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXJnc1snc2hvcnRkZXNjJ10gKSApIHsKCQkJJGxlYWZfY29tbWFuZC0+c2V0X3Nob3J0ZGVzYyggJGFyZ3NbJ3Nob3J0ZGVzYyddICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXJnc1snbG9uZ2Rlc2MnXSApICkgewoJCQkkbGVhZl9jb21tYW5kLT5zZXRfbG9uZ2Rlc2MoICRhcmdzWydsb25nZGVzYyddICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXJnc1snc3lub3BzaXMnXSApICkgewoJCQlpZiAoIGlzX3N0cmluZyggJGFyZ3NbJ3N5bm9wc2lzJ10gKSApIHsKCQkJCSRsZWFmX2NvbW1hbmQtPnNldF9zeW5vcHNpcyggJGFyZ3NbJ3N5bm9wc2lzJ10gKTsKCQkJfSBlbHNlaWYgKCBpc19hcnJheSggJGFyZ3NbJ3N5bm9wc2lzJ10gKSApIHsKCQkJCSRzeW5vcHNpcyA9IFN5bm9wc2lzUGFyc2VyOjpyZW5kZXIoICRhcmdzWydzeW5vcHNpcyddICk7CgkJCQkkbGVhZl9jb21tYW5kLT5zZXRfc3lub3BzaXMoICRzeW5vcHNpcyApOwoJCQkJJGxvbmdfZGVzYyA9ICcnOwoJCQkJJGJpdHMgICAgICA9IGV4cGxvZGUoICcgJywgJHN5bm9wc2lzICk7CgkJCQlmb3JlYWNoICggJGFyZ3NbJ3N5bm9wc2lzJ10gYXMgJGtleSA9PiAkYXJnICkgewoJCQkJCSRsb25nX2Rlc2MgLj0gJGJpdHNbICRrZXkgXSAuICJcbiI7CgkJCQkJaWYgKCAhIGVtcHR5KCAkYXJnWydkZXNjcmlwdGlvbiddICkgKSB7CgkJCQkJCSRsb25nX2Rlc2MgLj0gJzogJyAuICRhcmdbJ2Rlc2NyaXB0aW9uJ10gLiAiXG4iOwoJCQkJCX0KCQkJCQkkeWFtbGlmeSA9IFtdOwoJCQkJCWZvcmVhY2ggKCBbICdkZWZhdWx0JywgJ29wdGlvbnMnIF0gYXMgJGtleSApIHsKCQkJCQkJaWYgKCBpc3NldCggJGFyZ1sgJGtleSBdICkgKSB7CgkJCQkJCQkkeWFtbGlmeVsgJGtleSBdID0gJGFyZ1sgJGtleSBdOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWlmICggISBlbXB0eSggJHlhbWxpZnkgKSApIHsKCQkJCQkJJGxvbmdfZGVzYyAuPSBTcHljOjpZQU1MRHVtcCggJHlhbWxpZnkgKTsKCQkJCQkJJGxvbmdfZGVzYyAuPSAnLS0tJyAuICJcbiI7CgkJCQkJfQoJCQkJCSRsb25nX2Rlc2MgLj0gIlxuIjsKCQkJCX0KCQkJCWlmICggISBlbXB0eSggJGxvbmdfZGVzYyApICkgewoJCQkJCSRsb25nX2Rlc2MgPSBydHJpbSggJGxvbmdfZGVzYywgIlxyXG4iICk7CgkJCQkJJGxvbmdfZGVzYyA9ICcjIyBPUFRJT05TJyAuICJcblxuIiAuICRsb25nX2Rlc2M7CgkJCQkJaWYgKCAhIGVtcHR5KCAkYXJnc1snbG9uZ2Rlc2MnXSApICkgewoJCQkJCQkkbG9uZ19kZXNjIC49ICJcblxuIiAuIGx0cmltKCAkYXJnc1snbG9uZ2Rlc2MnXSwgIlxyXG4iICk7CgkJCQkJfQoJCQkJCSRsZWFmX2NvbW1hbmQtPnNldF9sb25nZGVzYyggJGxvbmdfZGVzYyApOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXJnc1snd2hlbiddICkgKSB7CgkJCXNlbGY6OmdldF9ydW5uZXIoKS0+cmVnaXN0ZXJfZWFybHlfaW52b2tlKCAkYXJnc1snd2hlbiddLCAkbGVhZl9jb21tYW5kICk7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRwYXJlbnQgKSApIHsKCQkJJHN1Yl9jb21tYW5kID0gdHJpbSggc3RyX3JlcGxhY2UoICRwYXJlbnQsICcnLCAkbmFtZSApICk7CgkJCXNlbGY6OmRlYnVnKCAiQWRkaW5nIGNvbW1hbmQ6IHskc3ViX2NvbW1hbmR9IGluIHskcGFyZW50fSBOYW1lc3BhY2UiLCAnY29tbWFuZHMnICk7CgkJfSBlbHNlIHsKCQkJc2VsZjo6ZGVidWcoICJBZGRpbmcgY29tbWFuZDogeyRuYW1lfSIsICdjb21tYW5kcycgKTsKCQl9CgoJCSRjb21tYW5kLT5hZGRfc3ViY29tbWFuZCggJGxlYWZfbmFtZSwgJGxlYWZfY29tbWFuZCApOwoKCQlzZWxmOjpkb19ob29rKCAiYWZ0ZXJfYWRkX2NvbW1hbmQ6eyRuYW1lfSIgKTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIERlZmVyIGNvbW1hbmQgYWRkaXRpb24gZm9yIGEgc3ViLWNvbW1hbmQgaWYgdGhlIHBhcmVudCBjb21tYW5kIGlzIG5vdCB5ZXQKCSAqIHJlZ2lzdGVyZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSAgICAgTmFtZSBmb3IgdGhlIHN1Yi1jb21tYW5kLgoJICogQHBhcmFtIHN0cmluZyAkcGFyZW50ICAgTmFtZSBmb3IgdGhlIHBhcmVudCBjb21tYW5kLgoJICogQHBhcmFtIHN0cmluZyAkY2FsbGFibGUgQ29tbWFuZCBpbXBsZW1lbnRhdGlvbiBhcyBhIGNsYXNzLCBmdW5jdGlvbiBvciBjbG9zdXJlLgoJICogQHBhcmFtIGFycmF5ICAkYXJncyAgICAgT3B0aW9uYWwuIFNlZSBgV1BfQ0xJOjphZGRfY29tbWFuZCgpYCBmb3IgZGV0YWlscy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZGVmZXJfY29tbWFuZF9hZGRpdGlvbiggJG5hbWUsICRwYXJlbnQsICRjYWxsYWJsZSwgJGFyZ3MgPSBbXSApIHsKCQkkYXJnc1snaXNfZGVmZXJyZWQnXSAgICAgICAgICAgICAgID0gdHJ1ZTsKCQlzZWxmOjokZGVmZXJyZWRfYWRkaXRpb25zWyAkbmFtZSBdID0gWwoJCQkncGFyZW50JyAgID0+ICRwYXJlbnQsCgkJCSdjYWxsYWJsZScgPT4gJGNhbGxhYmxlLAoJCQknYXJncycgICAgID0+ICRhcmdzLAoJCV07CgkJc2VsZjo6YWRkX2hvb2soCgkJCSJhZnRlcl9hZGRfY29tbWFuZDokcGFyZW50IiwKCQkJZnVuY3Rpb24gKCkgdXNlICggJG5hbWUgKSB7CgkJCQkkZGVmZXJyZWRfYWRkaXRpb25zID0gV1BfQ0xJOjpnZXRfZGVmZXJyZWRfYWRkaXRpb25zKCk7CgoJCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRuYW1lLCAkZGVmZXJyZWRfYWRkaXRpb25zICkgKSB7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCSRjYWxsYWJsZSA9ICRkZWZlcnJlZF9hZGRpdGlvbnNbICRuYW1lIF1bJ2NhbGxhYmxlJ107CgkJCQkkYXJncyAgICAgPSAkZGVmZXJyZWRfYWRkaXRpb25zWyAkbmFtZSBdWydhcmdzJ107CgkJCQlXUF9DTEk6OnJlbW92ZV9kZWZlcnJlZF9hZGRpdGlvbiggJG5hbWUgKTsKCgkJCQlXUF9DTEk6OmFkZF9jb21tYW5kKCAkbmFtZSwgJGNhbGxhYmxlLCAkYXJncyApOwoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbGlzdCBvZiBvdXRzdGFuZGluZyBkZWZlcnJlZCBjb21tYW5kIGFkZGl0aW9ucy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIG91dHN0YW5kaW5nIGNvbW1hbmQgYWRkaXRpb25zLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9kZWZlcnJlZF9hZGRpdGlvbnMoKSB7CgkJcmV0dXJuIHNlbGY6OiRkZWZlcnJlZF9hZGRpdGlvbnM7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgYSBjb21tYW5kIGFkZGl0aW9uIGZyb20gdGhlIGxpc3Qgb2Ygb3V0c3RhbmRpbmcgZGVmZXJyZWQgYWRkaXRpb25zLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlbW92ZV9kZWZlcnJlZF9hZGRpdGlvbiggJG5hbWUgKSB7CgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRuYW1lLCBzZWxmOjokZGVmZXJyZWRfYWRkaXRpb25zICkgKSB7CgkJCXNlbGY6Ondhcm5pbmcoICJUcnlpbmcgdG8gcmVtb3ZlIGEgbm9uLWV4aXN0ZW50IGNvbW1hbmQgYWRkaXRpb24gJ3skbmFtZX0nLiIgKTsKCQl9CgoJCXVuc2V0KCBzZWxmOjokZGVmZXJyZWRfYWRkaXRpb25zWyAkbmFtZSBdICk7Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IGluZm9ybWF0aW9uYWwgbWVzc2FnZSB3aXRob3V0IHByZWZpeCwgYW5kIGlnbm9yZSBgLS1xdWlldGAuCgkgKgoJICogTWVzc2FnZSBpcyB3cml0dGVuIHRvIFNURE9VVC4gYFdQX0NMSTo6bG9nKClgIGlzIHR5cGljYWxseSByZWNvbW1lbmRlZDsKCSAqIGBXUF9DTEk6OmxpbmUoKWAgaXMgaW5jbHVkZWQgZm9yIGhpc3RvcmljYWwgY29tcGF0LgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIGRpc3BsYXkgdG8gdGhlIGVuZCB1c2VyLgoJICogQHJldHVybiBudWxsCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbGluZSggJG1lc3NhZ2UgPSAnJyApIHsKCQllY2hvICRtZXNzYWdlIC4gIlxuIjsKCX0KCgkvKioKCSAqIERpc3BsYXkgaW5mb3JtYXRpb25hbCBtZXNzYWdlIHdpdGhvdXQgcHJlZml4LgoJICoKCSAqIE1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERPVVQsIG9yIGRpc2NhcmRlZCB3aGVuIGAtLXF1aWV0YCBmbGFnIGlzIHN1cHBsaWVkLgoJICoKCSAqIGBgYAoJICogIyBgd3AgY2xpIHVwZGF0ZWAgbGV0cyB1c2VyIGtub3cgb2YgZWFjaCBzdGVwIGluIHRoZSB1cGRhdGUgcHJvY2Vzcy4KCSAqIFdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnRG93bmxvYWRpbmcgZnJvbSAlcy4uLicsICRkb3dubG9hZF91cmwgKSApOwoJICogYGBgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUgdG8gU1RET1VULgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvZyggJG1lc3NhZ2UgKSB7CgkJaWYgKCBudWxsID09PSBzZWxmOjokbG9nZ2VyICkgewoJCQlyZXR1cm47CgkJfQoKCQlzZWxmOjokbG9nZ2VyLT5pbmZvKCAkbWVzc2FnZSApOwoJfQoKCS8qKgoJICogRGlzcGxheSBzdWNjZXNzIG1lc3NhZ2UgcHJlZml4ZWQgd2l0aCAiU3VjY2VzczogIi4KCSAqCgkgKiBTdWNjZXNzIG1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERPVVQuCgkgKgoJICogVHlwaWNhbGx5IHJlY29tbWVuZGVkIHRvIGluZm9ybSB1c2VyIG9mIHN1Y2Nlc3NmdWwgc2NyaXB0IGNvbmNsdXNpb24uCgkgKgoJICogYGBgCgkgKiAjIHdwIHJld3JpdGUgZmx1c2ggZXhwZWN0cyAncmV3cml0ZV9ydWxlcycgb3B0aW9uIHRvIGJlIHNldCBhZnRlciBmbHVzaC4KCSAqIGZsdXNoX3Jld3JpdGVfcnVsZXMoIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaGFyZCcgKSApOwoJICogaWYgKCAhIGdldF9vcHRpb24oICdyZXdyaXRlX3J1bGVzJyApICkgewoJICogICAgIFdQX0NMSTo6d2FybmluZyggIlJld3JpdGUgcnVsZXMgYXJlIGVtcHR5LiIgKTsKCSAqIH0gZWxzZSB7CgkgKiAgICAgV1BfQ0xJOjpzdWNjZXNzKCAnUmV3cml0ZSBydWxlcyBmbHVzaGVkLicgKTsKCSAqIH0KCSAqIGBgYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlIHRvIFNURE9VVC4KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1Y2Nlc3MoICRtZXNzYWdlICkgewoJCWlmICggbnVsbCA9PT0gc2VsZjo6JGxvZ2dlciApIHsKCQkJcmV0dXJuOwoJCX0KCgkJc2VsZjo6JGxvZ2dlci0+c3VjY2VzcyggJG1lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIERpc3BsYXkgZGVidWcgbWVzc2FnZSBwcmVmaXhlZCB3aXRoICJEZWJ1ZzogIiB3aGVuIGAtLWRlYnVnYCBpcyB1c2VkLgoJICoKCSAqIERlYnVnIG1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERFUlIsIGFuZCBpbmNsdWRlcyBzY3JpcHQgZXhlY3V0aW9uIHRpbWUuCgkgKgoJICogSGVscGZ1bCBmb3Igb3B0aW9uYWxseSBzaG93aW5nIGdyZWF0ZXIgZGV0YWlsIHdoZW4gbmVlZGVkLiBVc2VkIHRocm91Z2hvdXQKCSAqIFdQLUNMSSBib290c3RyYXAgcHJvY2VzcyBmb3IgZWFzaWVyIGRlYnVnZ2luZyBhbmQgcHJvZmlsaW5nLgoJICoKCSAqIGBgYAoJICogIyBDYWxsZWQgaW4gYFdQX0NMSVxSdW5uZXI6OnNldF93cF9yb290KClgLgoJICogcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc2V0X3dwX3Jvb3QoICRwYXRoICkgewoJICogICAgIGRlZmluZSggJ0FCU1BBVEgnLCBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoICRwYXRoICkgKTsKCSAqICAgICBXUF9DTEk6OmRlYnVnKCAnQUJTUEFUSCBkZWZpbmVkOiAnIC4gQUJTUEFUSCApOwoJICogICAgICRfU0VSVkVSWydET0NVTUVOVF9ST09UJ10gPSByZWFscGF0aCggJHBhdGggKTsKCSAqIH0KCSAqCgkgKiAjIERlYnVnIGRldGFpbHMgb25seSBhcHBlYXIgd2hlbiBgLS1kZWJ1Z2AgaXMgdXNlZC4KCSAqICMgJCB3cCAtLWRlYnVnCgkgKiAjIFsuLi5dCgkgKiAjIERlYnVnOiBBQlNQQVRIIGRlZmluZWQ6IC9zcnYvd3d3L3dvcmRwcmVzcy1kZXZlbG9wLmRldi9zcmMvICgwLjIyNXMpCgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmd8V1BfRXJyb3J8RXhjZXB0aW9ufFRocm93YWJsZSAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlIHRvIFNUREVSUi4KCSAqIEBwYXJhbSBzdHJpbmd8Ym9vbCAkZ3JvdXAgT3JnYW5pemUgZGVidWcgbWVzc2FnZSB0byBhIHNwZWNpZmljIGdyb3VwLgoJICogVXNlIGBmYWxzZWAgdG8gbm90IGdyb3VwIHRoZSBtZXNzYWdlLgoJICogQHJldHVybiBudWxsCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZGVidWcoICRtZXNzYWdlLCAkZ3JvdXAgPSBmYWxzZSApIHsKCQlzdGF0aWMgJHN0b3JhZ2UgPSBbXTsKCgkJaWYgKCAhIHNlbGY6OiRsb2dnZXIgKSB7CgkJCSRzdG9yYWdlW10gPSBbICRtZXNzYWdlLCAkZ3JvdXAgXTsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkc3RvcmFnZSApICYmIHNlbGY6OiRsb2dnZXIgKSB7CgkJCWZvcmVhY2ggKCAkc3RvcmFnZSBhcyAkZW50cnkgKSB7CgkJCQlsaXN0KCAkc3RvcmVkX21lc3NhZ2UsICRzdG9yZWRfZ3JvdXAgKSA9ICRlbnRyeTsKCQkJCXNlbGY6OiRsb2dnZXItPmRlYnVnKCBzZWxmOjplcnJvcl90b19zdHJpbmcoICRzdG9yZWRfbWVzc2FnZSApLCAkc3RvcmVkX2dyb3VwICk7CgkJCX0KCQkJJHN0b3JhZ2UgPSBbXTsKCQl9CgoJCXNlbGY6OiRsb2dnZXItPmRlYnVnKCBzZWxmOjplcnJvcl90b19zdHJpbmcoICRtZXNzYWdlICksICRncm91cCApOwoJfQoKCS8qKgoJICogRGlzcGxheSB3YXJuaW5nIG1lc3NhZ2UgcHJlZml4ZWQgd2l0aCAiV2FybmluZzogIi4KCSAqCgkgKiBXYXJuaW5nIG1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERFUlIuCgkgKgoJICogVXNlIGluc3RlYWQgb2YgYFdQX0NMSTo6ZGVidWcoKWAgd2hlbiBzY3JpcHQgZXhlY3V0aW9uIHNob3VsZCBiZSBwZXJtaXR0ZWQKCSAqIHRvIGNvbnRpbnVlLgoJICoKCSAqIGBgYAoJICogIyBgd3AgcGx1Z2luIGFjdGl2YXRlYCBza2lwcyBhY3RpdmF0aW9uIHdoZW4gcGx1Z2luIGlzIG5ldHdvcmsgYWN0aXZlLgoJICogJHN0YXR1cyA9ICR0aGlzLT5nZXRfc3RhdHVzKCAkcGx1Z2luLT5maWxlICk7CgkgKiAvLyBOZXR3b3JrLWFjdGl2ZSBpcyB0aGUgaGlnaGVzdCBsZXZlbCBvZiBhY3RpdmF0aW9uIHN0YXR1cwoJICogaWYgKCAnYWN0aXZlLW5ldHdvcmsnID09PSAkc3RhdHVzICkgewoJICogICBXUF9DTEk6Ondhcm5pbmcoICJQbHVnaW4gJ3skcGx1Z2luLT5uYW1lfScgaXMgYWxyZWFkeSBuZXR3b3JrIGFjdGl2ZS4iICk7CgkgKiAgIGNvbnRpbnVlOwoJICogfQoJICogYGBgCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nfFdQX0Vycm9yfEV4Y2VwdGlvbnxUaHJvd2FibGUgJG1lc3NhZ2UgTWVzc2FnZSB0byB3cml0ZSB0byBTVERFUlIuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB3YXJuaW5nKCAkbWVzc2FnZSApIHsKCQlpZiAoIG51bGwgPT09IHNlbGY6OiRsb2dnZXIgKSB7CgkJCXJldHVybjsKCQl9CgoJCXNlbGY6OiRsb2dnZXItPndhcm5pbmcoIHNlbGY6OmVycm9yX3RvX3N0cmluZyggJG1lc3NhZ2UgKSApOwoJfQoKCS8qKgoJICogRGlzcGxheSBlcnJvciBtZXNzYWdlIHByZWZpeGVkIHdpdGggIkVycm9yOiAiIGFuZCBleGl0IHNjcmlwdC4KCSAqCgkgKiBFcnJvciBtZXNzYWdlIGlzIHdyaXR0ZW4gdG8gU1RERVJSLiBEZWZhdWx0cyB0byBoYWx0aW5nIHNjcmlwdCBleGVjdXRpb24KCSAqIHdpdGggcmV0dXJuIGNvZGUgMS4KCSAqCgkgKiBVc2UgYFdQX0NMSTo6d2FybmluZygpYCBpbnN0ZWFkIHdoZW4gc2NyaXB0IGV4ZWN1dGlvbiBzaG91bGQgYmUgcGVybWl0dGVkCgkgKiB0byBjb250aW51ZS4KCSAqCgkgKiBgYGAKCSAqICMgYHdwIGNhY2hlIGZsdXNoYCBjb25zaWRlcnMgZmx1c2ggZmFpbHVyZSB0byBiZSBhIGZhdGFsIGVycm9yLgoJICogaWYgKCBmYWxzZSA9PT0gd3BfY2FjaGVfZmx1c2goKSApIHsKCSAqICAgICBXUF9DTEk6OmVycm9yKCAnVGhlIG9iamVjdCBjYWNoZSBjb3VsZCBub3QgYmUgZmx1c2hlZC4nICk7CgkgKiB9CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IE91dHB1dAoJICoKCSAqIEBwYXJhbSBzdHJpbmd8V1BfRXJyb3J8RXhjZXB0aW9ufFRocm93YWJsZSAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlIHRvIFNUREVSUi4KCSAqIEBwYXJhbSBib29sZWFufGludGVnZXIgICAgICAgICAgICAkZXhpdCAgICBUcnVlIGRlZmF1bHRzIHRvIGV4aXQoMSkuCgkgKiBAcmV0dXJuIG51bGwKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnJvciggJG1lc3NhZ2UsICRleGl0ID0gdHJ1ZSApIHsKCQlpZiAoIG51bGwgIT09IHNlbGY6OiRsb2dnZXIgJiYgISBpc3NldCggc2VsZjo6Z2V0X3J1bm5lcigpLT5hc3NvY19hcmdzWydjb21wbGV0aW9ucyddICkgKSB7CgkJCXNlbGY6OiRsb2dnZXItPmVycm9yKCBzZWxmOjplcnJvcl90b19zdHJpbmcoICRtZXNzYWdlICkgKTsKCQl9CgoJCSRyZXR1cm5fY29kZSA9IGZhbHNlOwoJCWlmICggdHJ1ZSA9PT0gJGV4aXQgKSB7CgkJCSRyZXR1cm5fY29kZSA9IDE7CgkJfSBlbHNlaWYgKCBpc19pbnQoICRleGl0ICkgJiYgJGV4aXQgPj0gMSApIHsKCQkJJHJldHVybl9jb2RlID0gJGV4aXQ7CgkJfQoKCQlpZiAoICRyZXR1cm5fY29kZSApIHsKCQkJaWYgKCBzZWxmOjokY2FwdHVyZV9leGl0ICkgewoJCQkJdGhyb3cgbmV3IEV4aXRFeGNlcHRpb24oIG51bGwsICRyZXR1cm5fY29kZSApOwoJCQl9CgkJCWV4aXQoICRyZXR1cm5fY29kZSApOwoJCX0KCX0KCgkvKioKCSAqIEhhbHQgc2NyaXB0IGV4ZWN1dGlvbiB3aXRoIGEgc3BlY2lmaWMgcmV0dXJuIGNvZGUuCgkgKgoJICogUGVybWl0cyBzY3JpcHQgZXhlY3V0aW9uIHRvIGJlIG92ZXJsb2FkZWQgYnkgYFdQX0NMSTo6cnVuY29tbWFuZCgpYAoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgT3V0cHV0CgkgKgoJICogQHBhcmFtIGludGVnZXIgJHJldHVybl9jb2RlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGFsdCggJHJldHVybl9jb2RlICkgewoJCWlmICggc2VsZjo6JGNhcHR1cmVfZXhpdCApIHsKCQkJdGhyb3cgbmV3IEV4aXRFeGNlcHRpb24oIG51bGwsICRyZXR1cm5fY29kZSApOwoJCX0KCQlleGl0KCAkcmV0dXJuX2NvZGUgKTsKCX0KCgkvKioKCSAqIERpc3BsYXkgYSBtdWx0aS1saW5lIGVycm9yIG1lc3NhZ2UgaW4gYSByZWQgYm94LiBEb2Vzbid0IGV4aXQgc2NyaXB0LgoJICoKCSAqIEVycm9yIG1lc3NhZ2UgaXMgd3JpdHRlbiB0byBTVERFUlIuCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqIEBjYXRlZ29yeSBPdXRwdXQKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJG1lc3NhZ2VfbGluZXMgTXVsdGktbGluZSBlcnJvciBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnJvcl9tdWx0aV9saW5lKCAkbWVzc2FnZV9saW5lcyApIHsKCQlpZiAoIG51bGwgPT09IHNlbGY6OiRsb2dnZXIgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6Z2V0X3J1bm5lcigpLT5hc3NvY19hcmdzWydjb21wbGV0aW9ucyddICkgJiYgaXNfYXJyYXkoICRtZXNzYWdlX2xpbmVzICkgKSB7CgkJCXNlbGY6OiRsb2dnZXItPmVycm9yX211bHRpX2xpbmUoIGFycmF5X21hcCggWyBfX0NMQVNTX18sICdlcnJvcl90b19zdHJpbmcnIF0sICRtZXNzYWdlX2xpbmVzICkgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBc2sgZm9yIGNvbmZpcm1hdGlvbiBiZWZvcmUgcnVubmluZyBhIGRlc3RydWN0aXZlIG9wZXJhdGlvbi4KCSAqCgkgKiBJZiAneScgaXMgcHJvdmlkZWQgdG8gdGhlIHF1ZXN0aW9uLCB0aGUgc2NyaXB0IGV4ZWN1dGlvbiBjb250aW51ZXMuIElmCgkgKiAnbicgb3IgYW55IG90aGVyIHJlc3BvbnNlIGlzIHByb3ZpZGVkIHRvIHRoZSBxdWVzdGlvbiwgc2NyaXB0IGV4aXRzLgoJICoKCSAqIGBgYAoJICogIyBgd3AgZGIgZHJvcGAgYXNrcyBmb3IgY29uZmlybWF0aW9uIGJlZm9yZSBkcm9wcGluZyB0aGUgZGF0YWJhc2UuCgkgKgoJICogV1BfQ0xJOjpjb25maXJtKCAiQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRyb3AgdGhlIGRhdGFiYXNlPyIsICRhc3NvY19hcmdzICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IElucHV0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gUXVlc3Rpb24gdG8gZGlzcGxheSBiZWZvcmUgdGhlIHByb21wdC4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBTa2lwcyBwcm9tcHQgaWYgJ3llcycgaXMgcHJvdmlkZWQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29uZmlybSggJHF1ZXN0aW9uLCAkYXNzb2NfYXJncyA9IFtdICkgewoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd5ZXMnICkgKSB7CgkJCWZ3cml0ZSggU1RET1VULCAkcXVlc3Rpb24gLiAnIFt5L25dICcgKTsKCgkJCSRhbnN3ZXIgPSBzdHJ0b2xvd2VyKCB0cmltKCBmZ2V0cyggU1RESU4gKSApICk7CgoJCQlpZiAoICd5JyAhPT0gJGFuc3dlciApIHsKCQkJCWV4aXQ7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZWFkIHZhbHVlIGZyb20gYSBwb3NpdGlvbmFsIGFyZ3VtZW50IG9yIGZyb20gU1RESU4uCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFRoZSBsaXN0IG9mIHBvc2l0aW9uYWwgYXJndW1lbnRzLgoJICogQHBhcmFtIGludCAkaW5kZXggQXQgd2hpY2ggcG9zaXRpb24gdG8gY2hlY2sgZm9yIHRoZSB2YWx1ZS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF92YWx1ZV9mcm9tX2FyZ19vcl9zdGRpbiggJGFyZ3MsICRpbmRleCApIHsKCQlpZiAoIGlzc2V0KCAkYXJnc1sgJGluZGV4IF0gKSApIHsKCQkJJHJhd192YWx1ZSA9ICRhcmdzWyAkaW5kZXggXTsKCQl9IGVsc2UgewoJCQkvLyBXZSBkb24ndCB1c2UgZmlsZV9nZXRfY29udGVudHMoKSBoZXJlIGJlY2F1c2UgaXQgZG9lc24ndCBoYW5kbGUKCQkJLy8gQ3RybC1EIHByb3Blcmx5LCB3aGVuIHR5cGluZyBpbiB0aGUgdmFsdWUgaW50ZXJhY3RpdmVseS4KCQkJJHJhd192YWx1ZSA9ICcnOwoJCQl3aGlsZSAoIGZhbHNlICE9PSAoICRsaW5lID0gZmdldHMoIFNURElOICkgKSApIHsKCQkJCSRyYXdfdmFsdWUgLj0gJGxpbmU7CgkJCX0KCQl9CgoJCXJldHVybiAkcmF3X3ZhbHVlOwoJfQoKCS8qKgoJICogUmVhZCBhIHZhbHVlLCBmcm9tIHZhcmlvdXMgZm9ybWF0cy4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IElucHV0CgkgKgoJICogQHBhcmFtIG1peGVkICRyYXdfdmFsdWUKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlYWRfdmFsdWUoICRyYXdfdmFsdWUsICRhc3NvY19hcmdzID0gW10gKSB7CgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICdqc29uJyApIHsKCQkJJHZhbHVlID0ganNvbl9kZWNvZGUoICRyYXdfdmFsdWUsIHRydWUgKTsKCQkJaWYgKCBudWxsID09PSAkdmFsdWUgKSB7CgkJCQlzZWxmOjplcnJvciggc3ByaW50ZiggJ0ludmFsaWQgSlNPTjogJXMnLCAkcmF3X3ZhbHVlICkgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSR2YWx1ZSA9ICRyYXdfdmFsdWU7CgkJfQoKCQlyZXR1cm4gJHZhbHVlOwoJfQoKCS8qKgoJICogRGlzcGxheSBhIHZhbHVlLCBpbiB2YXJpb3VzIGZvcm1hdHMKCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlIHRvIGRpc3BsYXkuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgY29tbWFuZCwgZGV0ZXJtaW5pbmcgZm9ybWF0LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByaW50X3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzID0gW10gKSB7CgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICdqc29uJyApIHsKCQkJJHZhbHVlID0ganNvbl9lbmNvZGUoICR2YWx1ZSApOwoJCX0gZWxzZWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApID09PSAneWFtbCcgKSB7CgkJCSR2YWx1ZSA9IFNweWM6OllBTUxEdW1wKCAkdmFsdWUsIDIsIDAgKTsKCQl9IGVsc2VpZiAoIGlzX2FycmF5KCAkdmFsdWUgKSB8fCBpc19vYmplY3QoICR2YWx1ZSApICkgewoJCQkkdmFsdWUgPSB2YXJfZXhwb3J0KCAkdmFsdWUsIHRydWUgKTsKCQl9CgoJCWVjaG8gJHZhbHVlIC4gIlxuIjsKCX0KCgkvKioKCSAqIENvbnZlcnQgYSBXUF9FcnJvciBvciBFeGNlcHRpb24gaW50byBhIHN0cmluZwoJICoKCSAqIEBwYXJhbSBzdHJpbmd8V1BfRXJyb3J8RXhjZXB0aW9ufFRocm93YWJsZSAkZXJyb3JzCgkgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXJyb3JfdG9fc3RyaW5nKCAkZXJyb3JzICkgewoJCWlmICggaXNfc3RyaW5nKCAkZXJyb3JzICkgKSB7CgkJCXJldHVybiAkZXJyb3JzOwoJCX0KCgkJLy8gT25seSBqc29uX2VuY29kZSgpIHRoZSBkYXRhIHdoZW4gaXQgbmVlZHMgaXQKCQkkcmVuZGVyX2RhdGEgPSBmdW5jdGlvbiggJGRhdGEgKSB7CgkJCWlmICggaXNfYXJyYXkoICRkYXRhICkgfHwgaXNfb2JqZWN0KCAkZGF0YSApICkgewoJCQkJcmV0dXJuIGpzb25fZW5jb2RlKCAkZGF0YSApOwoJCQl9CgoJCQlyZXR1cm4gJyInIC4gJGRhdGEgLiAnIic7CgkJfTsKCgkJaWYgKCAkZXJyb3JzIGluc3RhbmNlb2YgV1BfRXJyb3IgKSB7CgkJCWZvcmVhY2ggKCAkZXJyb3JzLT5nZXRfZXJyb3JfbWVzc2FnZXMoKSBhcyAkbWVzc2FnZSApIHsKCQkJCWlmICggJGVycm9ycy0+Z2V0X2Vycm9yX2RhdGEoKSApIHsKCQkJCQlyZXR1cm4gJG1lc3NhZ2UgLiAnICcgLiAkcmVuZGVyX2RhdGEoICRlcnJvcnMtPmdldF9lcnJvcl9kYXRhKCkgKTsKCQkJCX0KCgkJCQlyZXR1cm4gJG1lc3NhZ2U7CgkJCX0KCQl9CgoJCS8vIFBIUCA3KzogaW50ZXJuYWwgYW5kIHVzZXIgZXhjZXB0aW9ucyBtdXN0IGltcGxlbWVudCBUaHJvd2FibGUgaW50ZXJmYWNlLgoJCS8vIFBIUCA1OiBpbnRlcm5hbCBhbmQgdXNlciBleGNlcHRpb25zIG11c3QgZXh0ZW5kIEV4Y2VwdGlvbiBjbGFzcy4KCQlpZiAoIGludGVyZmFjZV9leGlzdHMoICdUaHJvd2FibGUnICkgJiYgKCAkZXJyb3JzIGluc3RhbmNlb2YgVGhyb3dhYmxlICkgfHwgKCAkZXJyb3JzIGluc3RhbmNlb2YgRXhjZXB0aW9uICkgKSB7CgkJCXJldHVybiBnZXRfY2xhc3MoICRlcnJvcnMgKSAuICc6ICcgLiAkZXJyb3JzLT5nZXRNZXNzYWdlKCk7CgkJfQoKCQl0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAoJCQlzcHJpbnRmKAoJCQkJIlVuc3VwcG9ydGVkIGFyZ3VtZW50IHR5cGUgcGFzc2VkIHRvIFdQX0NMSTo6ZXJyb3JfdG9fc3RyaW5nKCk6ICclcyciLAoJCQkJZ2V0dHlwZSggJGVycm9ycyApCgkJCSkKCQkpOwoJfQoKCS8qKgoJICogTGF1bmNoIGFuIGFyYml0cmFyeSBleHRlcm5hbCBwcm9jZXNzIHRoYXQgdGFrZXMgb3ZlciBJL08uCgkgKgoJICogYGBgCgkgKiAjIGB3cCBjb3JlIGRvd25sb2FkYCBmYWxscyBiYWNrIHRvIHRoZSBgdGFyYCBiaW5hcnkgd2hlbiBQaGFyRGF0YSBpc24ndCBhdmFpbGFibGUKCSAqIGlmICggISBjbGFzc19leGlzdHMoICdQaGFyRGF0YScgKSApIHsKCSAqICAgICAkY21kID0gInRhciB4eiAtLXN0cmlwLWNvbXBvbmVudHM9MSAtLWRpcmVjdG9yeT0lcyAtZiAkdGFyYmFsbCI7CgkgKiAgICAgV1BfQ0xJOjpsYXVuY2goIFV0aWxzXGVzY19jbWQoICRjbWQsICRkZXN0ICkgKTsKCSAqICAgICByZXR1cm47CgkgKiB9CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IEV4ZWN1dGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgRXh0ZXJuYWwgcHJvY2VzcyB0byBsYXVuY2guCgkgKiBAcGFyYW0gYm9vbGVhbiAkZXhpdF9vbl9lcnJvciBXaGV0aGVyIHRvIGV4aXQgaWYgdGhlIGNvbW1hbmQgcmV0dXJucyBhbiBlbGV2YXRlZCByZXR1cm4gY29kZS4KCSAqIEBwYXJhbSBib29sZWFuICRyZXR1cm5fZGV0YWlsZWQgV2hldGhlciB0byByZXR1cm4gYW4gZXhpdCBzdGF0dXMgKGRlZmF1bHQpIG9yIGRldGFpbGVkIGV4ZWN1dGlvbiByZXN1bHRzLgoJICogQHJldHVybiBpbnR8UHJvY2Vzc1J1biBUaGUgY29tbWFuZCBleGl0IHN0YXR1cywgb3IgYSBQcm9jZXNzUnVuIG9iamVjdCBmb3IgZnVsbCBkZXRhaWxzLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxhdW5jaCggJGNvbW1hbmQsICRleGl0X29uX2Vycm9yID0gdHJ1ZSwgJHJldHVybl9kZXRhaWxlZCA9IGZhbHNlICkgewoJCVV0aWxzXGNoZWNrX3Byb2NfYXZhaWxhYmxlKCAnbGF1bmNoJyApOwoKCQkkcHJvYyAgICA9IFByb2Nlc3M6OmNyZWF0ZSggJGNvbW1hbmQgKTsKCQkkcmVzdWx0cyA9ICRwcm9jLT5ydW4oKTsKCgkJaWYgKCAtMSA9PT0gJHJlc3VsdHMtPnJldHVybl9jb2RlICkgewoJCQlzZWxmOjp3YXJuaW5nKCAiU3Bhd25lZCBwcm9jZXNzIHJldHVybmVkIGV4aXQgY29kZSB7JHJlc3VsdHMtPnJldHVybl9jb2RlfSwgd2hpY2ggY291bGQgYmUgY2F1c2VkIGJ5IGEgY3VzdG9tIGNvbXBpbGVkIHZlcnNpb24gb2YgUEhQIHRoYXQgdXNlcyB0aGUgLS1lbmFibGUtc2lnY2hpbGQgb3B0aW9uLiIgKTsKCQl9CgoJCWlmICggJHJlc3VsdHMtPnJldHVybl9jb2RlICYmICRleGl0X29uX2Vycm9yICkgewoJCQlleGl0KCAkcmVzdWx0cy0+cmV0dXJuX2NvZGUgKTsKCQl9CgoJCWlmICggJHJldHVybl9kZXRhaWxlZCApIHsKCQkJcmV0dXJuICRyZXN1bHRzOwoJCX0KCgkJcmV0dXJuICRyZXN1bHRzLT5yZXR1cm5fY29kZTsKCX0KCgkvKioKCSAqIFJ1biBhIFdQLUNMSSBjb21tYW5kIGluIGEgbmV3IHByb2Nlc3MgcmV1c2luZyB0aGUgY3VycmVudCBydW50aW1lIGFyZ3VtZW50cy4KCSAqCgkgKiBVc2UgYFdQX0NMSTo6cnVuY29tbWFuZCgpYCBpbnN0ZWFkLCB3aGljaCBpcyBlYXNpZXIgdG8gdXNlIGFuZCB3b3JrcyBiZXR0ZXIuCgkgKgoJICogTm90ZTogV2hpbGUgdGhpcyBjb21tYW5kIGRvZXMgcGVyc2lzdCBhIGxpbWl0ZWQgc2V0IG9mIHJ1bnRpbWUgYXJndW1lbnRzLAoJICogaXQgKmRvZXMgbm90KiBwZXJzaXN0IGVudmlyb25tZW50IHZhcmlhYmxlcy4gUHJhY3RpY2FsbHkgc3BlYWtpbmcsIFdQLUNMSQoJICogcGFja2FnZXMgd29uJ3QgYmUgbG9hZGVkIHdoZW4gdXNpbmcgV1BfQ0xJOjpsYXVuY2hfc2VsZigpIGJlY2F1c2UgdGhlCgkgKiBsYXVuY2hlZCBwcm9jZXNzIGRvZXNuJ3QgaGF2ZSBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgcHJvY2VzcyAkSE9NRS4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IEV4ZWN1dGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgV1AtQ0xJIGNvbW1hbmQgdG8gY2FsbC4KCSAqIEBwYXJhbSBhcnJheSAkYXJncyBQb3NpdGlvbmFsIGFyZ3VtZW50cyB0byBpbmNsdWRlIHdoZW4gY2FsbGluZyB0aGUgY29tbWFuZC4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcmd1bWVudHMgdG8gaW5jbHVkZSB3aGVuIGNhbGxpbmcgdGhlIGNvbW1hbmQuCgkgKiBAcGFyYW0gYm9vbCAkZXhpdF9vbl9lcnJvciBXaGV0aGVyIHRvIGV4aXQgaWYgdGhlIGNvbW1hbmQgcmV0dXJucyBhbiBlbGV2YXRlZCByZXR1cm4gY29kZS4KCSAqIEBwYXJhbSBib29sICRyZXR1cm5fZGV0YWlsZWQgV2hldGhlciB0byByZXR1cm4gYW4gZXhpdCBzdGF0dXMgKGRlZmF1bHQpIG9yIGRldGFpbGVkIGV4ZWN1dGlvbiByZXN1bHRzLgoJICogQHBhcmFtIGFycmF5ICRydW50aW1lX2FyZ3MgT3ZlcnJpZGUgb25lIG9yIG1vcmUgZ2xvYmFsIGFyZ3MgKHBhdGgsdXJsLHVzZXIsYWxsb3ctcm9vdCkKCSAqIEByZXR1cm4gaW50fFByb2Nlc3NSdW4gVGhlIGNvbW1hbmQgZXhpdCBzdGF0dXMsIG9yIGEgUHJvY2Vzc1J1biBpbnN0YW5jZQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxhdW5jaF9zZWxmKCAkY29tbWFuZCwgJGFyZ3MgPSBbXSwgJGFzc29jX2FyZ3MgPSBbXSwgJGV4aXRfb25fZXJyb3IgPSB0cnVlLCAkcmV0dXJuX2RldGFpbGVkID0gZmFsc2UsICRydW50aW1lX2FyZ3MgPSBbXSApIHsKCQkkcmV1c2VkX3J1bnRpbWVfYXJncyA9IFsKCQkJJ3BhdGgnLAoJCQkndXJsJywKCQkJJ3VzZXInLAoJCQknYWxsb3ctcm9vdCcsCgkJXTsKCgkJZm9yZWFjaCAoICRyZXVzZWRfcnVudGltZV9hcmdzIGFzICRrZXkgKSB7CgkJCWlmICggaXNzZXQoICRydW50aW1lX2FyZ3NbICRrZXkgXSApICkgewoJCQkJJGFzc29jX2FyZ3NbICRrZXkgXSA9ICRydW50aW1lX2FyZ3NbICRrZXkgXTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdmFsdWUgPSBzZWxmOjpnZXRfcnVubmVyKCktPmNvbmZpZ1sgJGtleSBdOwoJCQlpZiAoICR2YWx1ZSApIHsKCQkJCSRhc3NvY19hcmdzWyAka2V5IF0gPSAkdmFsdWU7CgkJCX0KCQl9CgoJCSRwaHBfYmluID0gZXNjYXBlc2hlbGxhcmcoIFV0aWxzXGdldF9waHBfYmluYXJ5KCkgKTsKCgkJJHNjcmlwdF9wYXRoID0gJEdMT0JBTFNbJ2FyZ3YnXVswXTsKCgkJaWYgKCBnZXRlbnYoICdXUF9DTElfQ09ORklHX1BBVEgnICkgKSB7CgkJCSRjb25maWdfcGF0aCA9IGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKTsKCQl9IGVsc2UgewoJCQkkY29uZmlnX3BhdGggPSBVdGlsc1xnZXRfaG9tZV9kaXIoKSAuICcvLndwLWNsaS9jb25maWcueW1sJzsKCQl9CgkJJGNvbmZpZ19wYXRoID0gZXNjYXBlc2hlbGxhcmcoICRjb25maWdfcGF0aCApOwoKCQkkYXJncyAgICAgICA9IGltcGxvZGUoICcgJywgYXJyYXlfbWFwKCAnZXNjYXBlc2hlbGxhcmcnLCAkYXJncyApICk7CgkJJGFzc29jX2FyZ3MgPSBVdGlsc1xhc3NvY19hcmdzX3RvX3N0ciggJGFzc29jX2FyZ3MgKTsKCgkJJGZ1bGxfY29tbWFuZCA9ICJXUF9DTElfQ09ORklHX1BBVEg9eyRjb25maWdfcGF0aH0geyRwaHBfYmlufSB7JHNjcmlwdF9wYXRofSB7JGNvbW1hbmR9IHskYXJnc30geyRhc3NvY19hcmdzfSI7CgoJCXJldHVybiBzZWxmOjpsYXVuY2goICRmdWxsX2NvbW1hbmQsICRleGl0X29uX2Vycm9yLCAkcmV0dXJuX2RldGFpbGVkICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHBhdGggdG8gdGhlIFBIUCBiaW5hcnkgdXNlZCB3aGVuIGV4ZWN1dGluZyBXUC1DTEkuCgkgKgoJICogRW52aXJvbm1lbnQgdmFsdWVzIHBlcm1pdCBzcGVjaWZpYyBiaW5hcmllcyB0byBiZSBpbmRpY2F0ZWQuCgkgKgoJICogTm90ZTogbW92ZWQgdG8gVXRpbHMsIGxlZnQgZm9yIEJDLgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgU3lzdGVtCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRfcGhwX2JpbmFyeSgpIHsKCQlyZXR1cm4gVXRpbHNcZ2V0X3BocF9iaW5hcnkoKTsKCX0KCgkvKioKCSAqIENvbmZpcm0gdGhhdCBhIGdsb2JhbCBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBkb2VzIGV4aXN0LgoJICoKCSAqIEBhY2Nlc3MgcHVibGljCgkgKiBAY2F0ZWdvcnkgSW5wdXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgQ29uZmlnIHBhcmFtZXRlciBrZXkgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGFzX2NvbmZpZyggJGtleSApIHsKCQlyZXR1cm4gYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgc2VsZjo6Z2V0X3J1bm5lcigpLT5jb25maWcgKTsKCX0KCgkvKioKCSAqIEdldCB2YWx1ZXMgb2YgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycy4KCSAqCgkgKiBQcm92aWRlcyBhY2Nlc3MgdG8gYC0tcGF0aD08cGF0aD5gLCBgLS11cmw9PHVybD5gLCBhbmQgb3RoZXIgdmFsdWVzIG9mCgkgKiB0aGUgW2dsb2JhbCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnNdKGh0dHBzOi8vd3AtY2xpLm9yZy9jb25maWcvKS4KCSAqCgkgKiBgYGAKCSAqIFdQX0NMSTo6bG9nKCAnVGhlIC0tdXJsPTx1cmw+IHZhbHVlIGlzOiAnIC4gV1BfQ0xJOjpnZXRfY29uZmlnKCAndXJsJyApICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IElucHV0CgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEdldCB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBnbG9iYWwgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIuCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NvbmZpZyggJGtleSA9IG51bGwgKSB7CgkJaWYgKCBudWxsID09PSAka2V5ICkgewoJCQlyZXR1cm4gc2VsZjo6Z2V0X3J1bm5lcigpLT5jb25maWc7CgkJfQoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OmdldF9ydW5uZXIoKS0+Y29uZmlnWyAka2V5IF0gKSApIHsKCQkJc2VsZjo6d2FybmluZyggIlVua25vd24gY29uZmlnIG9wdGlvbiAnJGtleScuIiApOwoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiBzZWxmOjpnZXRfcnVubmVyKCktPmNvbmZpZ1sgJGtleSBdOwoJfQoKCS8qKgoJICogUnVuIGEgV1AtQ0xJIGNvbW1hbmQuCgkgKgoJICogTGF1bmNoZXMgYSBuZXcgY2hpbGQgcHJvY2VzcyB0byBydW4gYSBzcGVjaWZpZWQgV1AtQ0xJIGNvbW1hbmQuCgkgKiBPcHRpb25hbGx5OgoJICoKCSAqICogUnVuIHRoZSBjb21tYW5kIGluIGFuIGV4aXN0aW5nIHByb2Nlc3MuCgkgKiAqIFByZXZlbnQgaGFsdGluZyBzY3JpcHQgZXhlY3V0aW9uIG9uIGVycm9yLgoJICogKiBDYXB0dXJlIGFuZCByZXR1cm4gU1RET1VULCBvciBmdWxsIGRldGFpbHMgYWJvdXQgY29tbWFuZCBleGVjdXRpb24uCgkgKiAqIFBhcnNlIEpTT04gb3V0cHV0IGlmIHRoZSBjb21tYW5kIHJlbmRlcmVkIGl0LgoJICoKCSAqIGBgYAoJICogJG9wdGlvbnMgPSBhcnJheSgKCSAqICAgJ3JldHVybicgICAgID0+IHRydWUsICAgLy8gUmV0dXJuICdTVERPVVQnOyB1c2UgJ2FsbCcgZm9yIGZ1bGwgb2JqZWN0LgoJICogICAncGFyc2UnICAgICAgPT4gJ2pzb24nLCAvLyBQYXJzZSBjYXB0dXJlZCBTVERPVVQgdG8gSlNPTiBhcnJheS4KCSAqICAgJ2xhdW5jaCcgICAgID0+IGZhbHNlLCAgLy8gUmV1c2UgdGhlIGN1cnJlbnQgcHJvY2Vzcy4KCSAqICAgJ2V4aXRfZXJyb3InID0+IHRydWUsICAgLy8gSGFsdCBzY3JpcHQgZXhlY3V0aW9uIG9uIGVycm9yLgoJICogKTsKCSAqICRwbHVnaW5zID0gV1BfQ0xJOjpydW5jb21tYW5kKCAncGx1Z2luIGxpc3QgLS1mb3JtYXQ9anNvbicsICRvcHRpb25zICk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IEV4ZWN1dGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgV1AtQ0xJIGNvbW1hbmQgdG8gcnVuLCBpbmNsdWRpbmcgYXJndW1lbnRzLgoJICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGNvbW1hbmQgZXhlY3V0aW9uLgoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJ1bmNvbW1hbmQoICRjb21tYW5kLCAkb3B0aW9ucyA9IFtdICkgewoJCSRkZWZhdWx0cyAgID0gWwoJCQknbGF1bmNoJyAgICAgPT4gdHJ1ZSwgLy8gTGF1bmNoIGEgbmV3IHByb2Nlc3MsIG9yIHJldXNlIHRoZSBleGlzdGluZy4KCQkJJ2V4aXRfZXJyb3InID0+IHRydWUsIC8vIEV4aXQgb24gZXJyb3IgYnkgZGVmYXVsdC4KCQkJJ3JldHVybicgICAgID0+IGZhbHNlLCAvLyBDYXB0dXJlIGFuZCByZXR1cm4gb3V0cHV0LCBvciByZW5kZXIgaW4gcmVhbHRpbWUuCgkJCSdwYXJzZScgICAgICA9PiBmYWxzZSwgLy8gUGFyc2UgcmV0dXJuZWQgb3V0cHV0IGFzIGEgcGFydGljdWxhciBmb3JtYXQuCgkJXTsKCQkkb3B0aW9ucyAgICA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRvcHRpb25zICk7CgkJJGxhdW5jaCAgICAgPSAkb3B0aW9uc1snbGF1bmNoJ107CgkJJGV4aXRfZXJyb3IgPSAkb3B0aW9uc1snZXhpdF9lcnJvciddOwoJCSRyZXR1cm4gICAgID0gJG9wdGlvbnNbJ3JldHVybiddOwoJCSRwYXJzZSAgICAgID0gJG9wdGlvbnNbJ3BhcnNlJ107CgkJJHJldHZhbCAgICAgPSBudWxsOwoJCWlmICggJGxhdW5jaCApIHsKCQkJVXRpbHNcY2hlY2tfcHJvY19hdmFpbGFibGUoICdsYXVuY2ggb3B0aW9uJyApOwoKCQkJJGRlc2NyaXB0b3JzID0gWwoJCQkJMCA9PiBTVERJTiwKCQkJCTEgPT4gU1RET1VULAoJCQkJMiA9PiBTVERFUlIsCgkJCV07CgoJCQlpZiAoICRyZXR1cm4gKSB7CgkJCQkkZGVzY3JpcHRvcnMgPSBbCgkJCQkJMCA9PiBTVERJTiwKCQkJCQkxID0+IFsgJ3BpcGUnLCAndycgXSwKCQkJCQkyID0+IFsgJ3BpcGUnLCAndycgXSwKCQkJCV07CgkJCX0KCgkJCSRwaHBfYmluICAgICA9IGVzY2FwZXNoZWxsYXJnKCBVdGlsc1xnZXRfcGhwX2JpbmFyeSgpICk7CgkJCSRzY3JpcHRfcGF0aCA9ICRHTE9CQUxTWydhcmd2J11bMF07CgoJCQkvLyBQZXJzaXN0IHJ1bnRpbWUgYXJndW1lbnRzIHVubGVzcyB0aGV5J3ZlIGJlZW4gc3BlY2lmaWVkIG90aGVyd2lzZS4KCQkJJGNvbmZpZ3VyYXRvciA9IHNlbGY6OmdldF9jb25maWd1cmF0b3IoKTsKCQkJJGFyZ3YgICAgICAgICA9IGFycmF5X3NsaWNlKCAkR0xPQkFMU1snYXJndiddLCAxICk7CgoJCQlsaXN0KCAkaWdub3JlMSwgJGlnbm9yZTIsICRydW50aW1lX2NvbmZpZyApID0gJGNvbmZpZ3VyYXRvci0+cGFyc2VfYXJncyggJGFyZ3YgKTsKCQkJZm9yZWFjaCAoICRydW50aW1lX2NvbmZpZyBhcyAkayA9PiAkdiApIHsKCQkJCWlmICggcHJlZ19tYXRjaCggInxeLS17JGt9PT8kfCIsICRjb21tYW5kICkgKSB7CgkJCQkJdW5zZXQoICRydW50aW1lX2NvbmZpZ1sgJGsgXSApOwoJCQkJfQoJCQl9CgkJCSRydW50aW1lX2NvbmZpZyA9IFV0aWxzXGFzc29jX2FyZ3NfdG9fc3RyKCAkcnVudGltZV9jb25maWcgKTsKCgkJCSRydW5jb21tYW5kID0gInskcGhwX2Jpbn0geyRzY3JpcHRfcGF0aH0geyRydW50aW1lX2NvbmZpZ30geyRjb21tYW5kfSI7CgoJCQkkcGlwZXMgPSBbXTsKCQkJJHByb2MgID0gVXRpbHNccHJvY19vcGVuX2NvbXBhdCggJHJ1bmNvbW1hbmQsICRkZXNjcmlwdG9ycywgJHBpcGVzLCBnZXRjd2QoKSApOwoKCQkJaWYgKCAkcmV0dXJuICkgewoJCQkJJHN0ZG91dCA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1sxXSApOwoJCQkJZmNsb3NlKCAkcGlwZXNbMV0gKTsKCQkJCSRzdGRlcnIgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCAkcGlwZXNbMl0gKTsKCQkJCWZjbG9zZSggJHBpcGVzWzJdICk7CgkJCX0KCQkJJHJldHVybl9jb2RlID0gcHJvY19jbG9zZSggJHByb2MgKTsKCQkJaWYgKCAtMSA9PT0gJHJldHVybl9jb2RlICkgewoJCQkJc2VsZjo6d2FybmluZyggJ1NwYXduZWQgcHJvY2VzcyByZXR1cm5lZCBleGl0IGNvZGUgLTEsIHdoaWNoIGNvdWxkIGJlIGNhdXNlZCBieSBhIGN1c3RvbSBjb21waWxlZCB2ZXJzaW9uIG9mIFBIUCB0aGF0IHVzZXMgdGhlIC0tZW5hYmxlLXNpZ2NoaWxkIG9wdGlvbi4nICk7CgkJCX0gZWxzZWlmICggJHJldHVybl9jb2RlICYmICRleGl0X2Vycm9yICkgewoJCQkJZXhpdCggJHJldHVybl9jb2RlICk7CgkJCX0KCQkJaWYgKCB0cnVlID09PSAkcmV0dXJuIHx8ICdzdGRvdXQnID09PSAkcmV0dXJuICkgewoJCQkJJHJldHZhbCA9IHRyaW0oICRzdGRvdXQgKTsKCQkJfSBlbHNlaWYgKCAnc3RkZXJyJyA9PT0gJHJldHVybiApIHsKCQkJCSRyZXR2YWwgPSB0cmltKCAkc3RkZXJyICk7CgkJCX0gZWxzZWlmICggJ3JldHVybl9jb2RlJyA9PT0gJHJldHVybiApIHsKCQkJCSRyZXR2YWwgPSAkcmV0dXJuX2NvZGU7CgkJCX0gZWxzZWlmICggJ2FsbCcgPT09ICRyZXR1cm4gKSB7CgkJCQkkcmV0dmFsID0gKG9iamVjdCkgWwoJCQkJCSdzdGRvdXQnICAgICAgPT4gdHJpbSggJHN0ZG91dCApLAoJCQkJCSdzdGRlcnInICAgICAgPT4gdHJpbSggJHN0ZGVyciApLAoJCQkJCSdyZXR1cm5fY29kZScgPT4gJHJldHVybl9jb2RlLAoJCQkJXTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRjb25maWd1cmF0b3IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBzZWxmOjpnZXRfY29uZmlndXJhdG9yKCk7CgkJCSRhcmd2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBVdGlsc1xwYXJzZV9zdHJfdG9fYXJndiggJGNvbW1hbmQgKTsKCQkJbGlzdCggJGFyZ3MsICRhc3NvY19hcmdzLCAkcnVudGltZV9jb25maWcgKSA9ICRjb25maWd1cmF0b3ItPnBhcnNlX2FyZ3MoICRhcmd2ICk7CgkJCWlmICggJHJldHVybiApIHsKCQkJCSRleGlzdGluZ19sb2dnZXIgPSBzZWxmOjokbG9nZ2VyOwoJCQkJc2VsZjo6JGxvZ2dlciAgICA9IG5ldyBFeGVjdXRpb24oKTsKCQkJCXNlbGY6OiRsb2dnZXItPm9iX3N0YXJ0KCk7CgkJCX0KCQkJaWYgKCAhICRleGl0X2Vycm9yICkgewoJCQkJc2VsZjo6JGNhcHR1cmVfZXhpdCA9IHRydWU7CgkJCX0KCQkJdHJ5IHsKCQkJCXNlbGY6OmdldF9ydW5uZXIoKS0+cnVuX2NvbW1hbmQoCgkJCQkJJGFyZ3MsCgkJCQkJJGFzc29jX2FyZ3MsCgkJCQkJWwoJCQkJCQknYmFja19jb21wYXRfY29udmVyc2lvbnMnID0+IHRydWUsCgkJCQkJXQoJCQkJKTsKCQkJCSRyZXR1cm5fY29kZSA9IDA7CgkJCX0gY2F0Y2ggKCBFeGl0RXhjZXB0aW9uICRlICkgewoJCQkJJHJldHVybl9jb2RlID0gJGUtPmdldENvZGUoKTsKCQkJfQoJCQlpZiAoICRyZXR1cm4gKSB7CgkJCQkkZXhlY3V0aW9uX2xvZ2dlciA9IHNlbGY6OiRsb2dnZXI7CgkJCQkkZXhlY3V0aW9uX2xvZ2dlci0+b2JfZW5kKCk7CgkJCQlzZWxmOjokbG9nZ2VyID0gJGV4aXN0aW5nX2xvZ2dlcjsKCQkJCSRzdGRvdXQgICAgICAgPSAkZXhlY3V0aW9uX2xvZ2dlci0+c3Rkb3V0OwoJCQkJJHN0ZGVyciAgICAgICA9ICRleGVjdXRpb25fbG9nZ2VyLT5zdGRlcnI7CgkJCQlpZiAoIHRydWUgPT09ICRyZXR1cm4gfHwgJ3N0ZG91dCcgPT09ICRyZXR1cm4gKSB7CgkJCQkJJHJldHZhbCA9IHRyaW0oICRzdGRvdXQgKTsKCQkJCX0gZWxzZWlmICggJ3N0ZGVycicgPT09ICRyZXR1cm4gKSB7CgkJCQkJJHJldHZhbCA9IHRyaW0oICRzdGRlcnIgKTsKCQkJCX0gZWxzZWlmICggJ3JldHVybl9jb2RlJyA9PT0gJHJldHVybiApIHsKCQkJCQkkcmV0dmFsID0gJHJldHVybl9jb2RlOwoJCQkJfSBlbHNlaWYgKCAnYWxsJyA9PT0gJHJldHVybiApIHsKCQkJCQkkcmV0dmFsID0gKG9iamVjdCkgWwoJCQkJCQknc3Rkb3V0JyAgICAgID0+IHRyaW0oICRzdGRvdXQgKSwKCQkJCQkJJ3N0ZGVycicgICAgICA9PiB0cmltKCAkc3RkZXJyICksCgkJCQkJCSdyZXR1cm5fY29kZScgPT4gJHJldHVybl9jb2RlLAoJCQkJCV07CgkJCQl9CgkJCX0KCQkJaWYgKCAhICRleGl0X2Vycm9yICkgewoJCQkJc2VsZjo6JGNhcHR1cmVfZXhpdCA9IGZhbHNlOwoJCQl9CgkJfQoJCWlmICggKCB0cnVlID09PSAkcmV0dXJuIHx8ICdzdGRvdXQnID09PSAkcmV0dXJuICkKCQkJJiYgJ2pzb24nID09PSAkcGFyc2UgKSB7CgkJCSRyZXR2YWwgPSBqc29uX2RlY29kZSggJHJldHZhbCwgdHJ1ZSApOwoJCX0KCQlyZXR1cm4gJHJldHZhbDsKCX0KCgkvKioKCSAqIFJ1biBhIGdpdmVuIGNvbW1hbmQgd2l0aGluIHRoZSBjdXJyZW50IHByb2Nlc3MgdXNpbmcgdGhlIHNhbWUgZ2xvYmFsCgkgKiBwYXJhbWV0ZXJzLgoJICoKCSAqIFVzZSBgV1BfQ0xJOjpydW5jb21tYW5kKClgIGluc3RlYWQsIHdoaWNoIGlzIGVhc2llciB0byB1c2UgYW5kIHdvcmtzIGJldHRlci4KCSAqCgkgKiBUbyBydW4gYSBjb21tYW5kIHVzaW5nIGEgbmV3IHByb2Nlc3Mgd2l0aCB0aGUgc2FtZSBnbG9iYWwgcGFyYW1ldGVycywKCSAqIHVzZSBXUF9DTEk6OmxhdW5jaF9zZWxmKCkuIFRvIHJ1biBhIGNvbW1hbmQgdXNpbmcgYSBuZXcgcHJvY2VzcyB3aXRoCgkgKiBkaWZmZXJlbnQgZ2xvYmFsIHBhcmFtZXRlcnMsIHVzZSBXUF9DTEk6OmxhdW5jaCgpLgoJICoKCSAqIGBgYAoJICogb2Jfc3RhcnQoKTsKCSAqIFdQX0NMSTo6cnVuX2NvbW1hbmQoIGFycmF5KCAnY2xpJywgJ2NtZC1kdW1wJyApICk7CgkgKiAkcmV0ID0gb2JfZ2V0X2NsZWFuKCk7CgkgKiBgYGAKCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICogQGNhdGVnb3J5IEV4ZWN1dGlvbgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBQb3NpdGlvbmFsIGFyZ3VtZW50cyBpbmNsdWRpbmcgY29tbWFuZCBuYW1lLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcnVuX2NvbW1hbmQoICRhcmdzLCAkYXNzb2NfYXJncyA9IFtdICkgewoJCXNlbGY6OmdldF9ydW5uZXIoKS0+cnVuX2NvbW1hbmQoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCgoJLy8gREVQUkVDQVRFRCBTVFVGRgoKCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWRkX21hbl9kaXIoKSB7CgkJdHJpZ2dlcl9lcnJvciggJ1dQX0NMSTo6YWRkX21hbl9kaXIoKSBpcyBkZXByZWNhdGVkLiBBZGQgZG9jcyBpbmxpbmUuJywgRV9VU0VSX1dBUk5JTkcgKTsKCX0KCgkvLyBiYWNrLWNvbXBhdAoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBvdXQoICRzdHIgKSB7CgkJZndyaXRlKCBTVERPVVQsICRzdHIgKTsKCX0KCgkvLyBiYWNrLWNvbXBhdAoJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZEZ1bmN0aW9uTmFtZS5NZXRob2ROYW1lSW52YWxpZCAtLSBEZXByZWNhdGVkIG1ldGhvZC4KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWRkQ29tbWFuZCggJG5hbWUsICRjbGFzcyApIHsKCQl0cmlnZ2VyX2Vycm9yKAoJCQlzcHJpbnRmKAoJCQkJJ3dwICVzOiAlcyBpcyBkZXByZWNhdGVkLiB1c2UgV1BfQ0xJOjphZGRfY29tbWFuZCgpIGluc3RlYWQuJywKCQkJCSRuYW1lLAoJCQkJX19GVU5DVElPTl9fCgkJCSksCgkJCUVfVVNFUl9XQVJOSU5HCgkJKTsKCQlzZWxmOjphZGRfY29tbWFuZCggJG5hbWUsICRjbGFzcyApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXERpc3BhdGNoZXI7CgovKioKICogR2V0IHRoZSBwYXRoIHRvIGEgY29tbWFuZCwgZS5nLiAiY29yZSBkb3dubG9hZCIKICoKICogQHBhcmFtIFN1YmNvbW1hbmR8Q29tcG9zaXRlQ29tbWFuZCAkY29tbWFuZAogKiBAcmV0dXJuIHN0cmluZ1tdCiAqLwpmdW5jdGlvbiBnZXRfcGF0aCggJGNvbW1hbmQgKSB7CgkkcGF0aCA9IFtdOwoKCWRvIHsKCQlhcnJheV91bnNoaWZ0KCAkcGF0aCwgJGNvbW1hbmQtPmdldF9uYW1lKCkgKTsKCX0gd2hpbGUgKCAkY29tbWFuZCA9ICRjb21tYW5kLT5nZXRfcGFyZW50KCkgKTsKCglyZXR1cm4gJHBhdGg7Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFJ1bnRpbWVFeGNlcHRpb247CgovKioKICogUnVuIGEgc3lzdGVtIHByb2Nlc3MsIGFuZCBsZWFybiB3aGF0IGhhcHBlbmVkLgogKi8KY2xhc3MgUHJvY2VzcyB7CgkvKioKCSAqIEB2YXIgc3RyaW5nIFRoZSBmdWxsIGNvbW1hbmQgdG8gZXhlY3V0ZSBieSB0aGUgc3lzdGVtLgoJICovCglwcml2YXRlICRjb21tYW5kOwoKCS8qKgoJICogQHZhciBzdHJpbmd8bnVsbCBUaGUgcGF0aCBvZiB0aGUgd29ya2luZyBkaXJlY3RvcnkgZm9yIHRoZSBwcm9jZXNzIG9yIE5VTEwgaWYgbm90IHNwZWNpZmllZCAoZGVmYXVsdHMgdG8gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSkuCgkgKi8KCXByaXZhdGUgJGN3ZDsKCgkvKioKCSAqIEB2YXIgYXJyYXkgRW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHNldCB3aGVuIHJ1bm5pbmcgdGhlIGNvbW1hbmQuCgkgKi8KCXByaXZhdGUgJGVudjsKCgkvKioKCSAqIEB2YXIgYXJyYXkgRGVzY3JpcHRvciBzcGVjIGZvciBgcHJvY19vcGVuKClgLgoJICovCglwcml2YXRlIHN0YXRpYyAkZGVzY3JpcHRvcnMgPSBbCgkJMCA9PiBTVERJTiwKCQkxID0+IFsgJ3BpcGUnLCAndycgXSwKCQkyID0+IFsgJ3BpcGUnLCAndycgXSwKCV07CgoJLyoqCgkgKiBAdmFyIGJvb2wgV2hldGhlciB0byBsb2cgcnVuIHRpbWUgaW5mbyBvciBub3QuCgkgKi8KCXB1YmxpYyBzdGF0aWMgJGxvZ19ydW5fdGltZXMgPSBmYWxzZTsKCgkvKioKCSAqIEB2YXIgYXJyYXkgQXJyYXkgb2YgcHJvY2VzcyBydW4gdGltZSBpbmZvLCBrZXllZCBieSBwcm9jZXNzIGNvbW1hbmQsIGVhY2ggYSAyLWVsZW1lbnQgYXJyYXkgY29udGFpbmluZyBydW4gdGltZSBhbmQgcnVuIGNvdW50LgoJICovCglwdWJsaWMgc3RhdGljICRydW5fdGltZXMgPSBbXTsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgQ29tbWFuZCB0byBleGVjdXRlLgoJICogQHBhcmFtIHN0cmluZyAkY3dkIERpcmVjdG9yeSB0byBleGVjdXRlIHRoZSBjb21tYW5kIGluLgoJICogQHBhcmFtIGFycmF5ICRlbnYgRW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHNldCB3aGVuIHJ1bm5pbmcgdGhlIGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBQcm9jZXNzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKCAkY29tbWFuZCwgJGN3ZCA9IG51bGwsICRlbnYgPSBbXSApIHsKCQkkcHJvYyA9IG5ldyBzZWxmKCk7CgoJCSRwcm9jLT5jb21tYW5kID0gJGNvbW1hbmQ7CgkJJHByb2MtPmN3ZCAgICAgPSAkY3dkOwoJCSRwcm9jLT5lbnYgICAgID0gJGVudjsKCgkJcmV0dXJuICRwcm9jOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7fQoKCS8qKgoJICogUnVuIHRoZSBjb21tYW5kLgoJICoKCSAqIEByZXR1cm4gUHJvY2Vzc1J1bgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuKCkgewoJCSRzdGFydF90aW1lID0gbWljcm90aW1lKCB0cnVlICk7CgoJCSRwaXBlcyA9IFtdOwoJCSRwcm9jICA9IFV0aWxzXHByb2Nfb3Blbl9jb21wYXQoICR0aGlzLT5jb21tYW5kLCBzZWxmOjokZGVzY3JpcHRvcnMsICRwaXBlcywgJHRoaXMtPmN3ZCwgJHRoaXMtPmVudiApOwoKCQkkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cyggJHBpcGVzWzFdICk7CgkJZmNsb3NlKCAkcGlwZXNbMV0gKTsKCgkJJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1syXSApOwoJCWZjbG9zZSggJHBpcGVzWzJdICk7CgoJCSRyZXR1cm5fY29kZSA9IHByb2NfY2xvc2UoICRwcm9jICk7CgoJCSRydW5fdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApIC0gJHN0YXJ0X3RpbWU7CgoJCWlmICggc2VsZjo6JGxvZ19ydW5fdGltZXMgKSB7CgkJCWlmICggISBpc3NldCggc2VsZjo6JHJ1bl90aW1lc1sgJHRoaXMtPmNvbW1hbmQgXSApICkgewoJCQkJc2VsZjo6JHJ1bl90aW1lc1sgJHRoaXMtPmNvbW1hbmQgXSA9IFsgMCwgMCBdOwoJCQl9CgkJCXNlbGY6OiRydW5fdGltZXNbICR0aGlzLT5jb21tYW5kIF1bMF0gKz0gJHJ1bl90aW1lOwoJCQlzZWxmOjokcnVuX3RpbWVzWyAkdGhpcy0+Y29tbWFuZCBdWzFdKys7CgkJfQoKCQlyZXR1cm4gbmV3IFByb2Nlc3NSdW4oCgkJCVsKCQkJCSdzdGRvdXQnICAgICAgPT4gJHN0ZG91dCwKCQkJCSdzdGRlcnInICAgICAgPT4gJHN0ZGVyciwKCQkJCSdyZXR1cm5fY29kZScgPT4gJHJldHVybl9jb2RlLAoJCQkJJ2NvbW1hbmQnICAgICA9PiAkdGhpcy0+Y29tbWFuZCwKCQkJCSdjd2QnICAgICAgICAgPT4gJHRoaXMtPmN3ZCwKCQkJCSdlbnYnICAgICAgICAgPT4gJHRoaXMtPmVudiwKCQkJCSdydW5fdGltZScgICAgPT4gJHJ1bl90aW1lLAoJCQldCgkJKTsKCX0KCgkvKioKCSAqIFJ1biB0aGUgY29tbWFuZCwgYnV0IHRocm93IGFuIEV4Y2VwdGlvbiBvbiBlcnJvci4KCSAqCgkgKiBAcmV0dXJuIFByb2Nlc3NSdW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1bl9jaGVjaygpIHsKCQkkciA9ICR0aGlzLT5ydW4oKTsKCgkJaWYgKCAkci0+cmV0dXJuX2NvZGUgKSB7CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCAkciApOwoJCX0KCgkJcmV0dXJuICRyOwoJfQoKCS8qKgoJICogUnVuIHRoZSBjb21tYW5kLCBidXQgdGhyb3cgYW4gRXhjZXB0aW9uIG9uIGVycm9yLgoJICogU2FtZSBhcyBgcnVuX2NoZWNrKClgIGFib3ZlLCBidXQgY2hlY2tzIHRoZSBjb3JyZWN0IHN0ZGVyci4KCSAqCgkgKiBAcmV0dXJuIFByb2Nlc3NSdW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1bl9jaGVja19zdGRlcnIoKSB7CgkJJHIgPSAkdGhpcy0+cnVuKCk7CgoJCWlmICggJHItPnJldHVybl9jb2RlIHx8ICEgZW1wdHkoICRyLT5zdGRlcnIgKSApIHsKCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oICRyICk7CgkJfQoKCQlyZXR1cm4gJHI7Cgl9Cn0KPD9waHAKLyoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAogKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQogKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueSBpbmRpdmlkdWFscwogKiBhbmQgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlCiAqIDxodHRwczovL3d3dy5kb2N0cmluZS1wcm9qZWN0Lm9yZz4uCiAqLwoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBEb2N0cmluZSBpbmZsZWN0b3IgaGFzIHN0YXRpYyBtZXRob2RzIGZvciBpbmZsZWN0aW5nIHRleHQuCiAqCiAqIFRoZSBtZXRob2RzIGluIHRoZXNlIGNsYXNzZXMgYXJlIGZyb20gc2V2ZXJhbCBkaWZmZXJlbnQgc291cmNlcyBjb2xsZWN0ZWQKICogYWNyb3NzIHNldmVyYWwgZGlmZmVyZW50IHBocCBwcm9qZWN0cyBhbmQgc2V2ZXJhbCBkaWZmZXJlbnQgYXV0aG9ycy4gVGhlCiAqIG9yaWdpbmFsIGF1dGhvciBuYW1lcyBhbmQgZW1haWxzIGFyZSBub3Qga25vd24uCiAqCiAqIFBsdXJhbGl6ZSAmIFNpbmd1bGFyaXplIGltcGxlbWVudGF0aW9uIGFyZSBib3Jyb3dlZCBmcm9tIENha2VQSFAgd2l0aCBzb21lIG1vZGlmaWNhdGlvbnMuCiAqCiAqIEBsaW5rICAgd3d3LmRvY3RyaW5lLXByb2plY3Qub3JnCiAqIEBzaW5jZSAgMS4wCiAqIEBhdXRob3IgS29uc3RhIFZlc3RlcmluZW4gPGt2ZXN0ZXJpQGNjLmh1dC5maT4KICogQGF1dGhvciBKb25hdGhhbiBILiBXYWdlIDxqb253YWdlQGdtYWlsLmNvbT4KICovCmNsYXNzIEluZmxlY3RvciB7CgoJLyoqCgkgKiBQbHVyYWwgaW5mbGVjdG9yIHJ1bGVzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgJHBsdXJhbCA9IFsKCQkncnVsZXMnICAgICAgID0+IFsKCQkJJy8ocyl0YXR1cyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxXDJ0YXR1c2VzJywKCQkJJy8ocXVpeikkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxemVzJywKCQkJJy9eKG94KSQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxXDJlbicsCgkJCScvKFttfGxdKW91c2UkL2knICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWljZScsCgkJCScvKG1hdHJ8dmVydHxpbmQpKGl4fGV4KSQvaScgICAgICAgICAgID0+ICdcMWljZXMnLAoJCQknLyh4fGNofHNzfHNoKSQvaScgICAgICAgICAgICAgICAgICAgICA9PiAnXDFlcycsCgkJCScvKFteYWVpb3V5XXxxdSl5JC9pJyAgICAgICAgICAgICAgICAgID0+ICdcMWllcycsCgkJCScvKGhpdmUpJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMXMnLAoJCQknLyg/OihbXmZdKWZlfChbbHJdKWYpJC9pJyAgICAgICAgICAgICA9PiAnXDFcMnZlcycsCgkJCScvc2lzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdzZXMnLAoJCQknLyhbdGldKXVtJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFhJywKCQkJJy8ocCllcnNvbiQvaScgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxZW9wbGUnLAoJCQknLyhtKWFuJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFlbicsCgkJCScvKGMpaGlsZCQvaScgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWhpbGRyZW4nLAoJCQknLyhmKW9vdCQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFlZXQnLAoJCQknLyhidWZmYWx8aGVyfHBvdGF0fHRvbWF0fHZvbGNhbilvJC9pJyA9PiAnXDFcMm9lcycsCgkJCScvKGFsdW1ufGJhY2lsbHxjYWN0fGZvY3xmdW5nfG51Y2xlfHJhZGl8c3RpbXVsfHN5bGxhYnx0ZXJtaW58dmlyKXVzJC9pJyA9PiAnXDFpJywKCQkJJy91cyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ3VzZXMnLAoJCQknLyhhbGlhcykkL2knICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFlcycsCgkJCScvKGFuYWx5c3xheHxjcmlzfHRlc3R8dGhlcylpcyQvaScgICAgID0+ICdcMWVzJywKCQkJJy9zJC8nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ3MnLAoJCQknL14kLycgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnJywKCQkJJy8kLycgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ3MnLAoJCV0sCgkJJ3VuaW5mbGVjdGVkJyA9PiBbCgkJCScuKltucmxtXWVzZScsCgkJCScuKmRlZXInLAoJCQknLipmaXNoJywKCQkJJy4qbWVhc2xlcycsCgkJCScuKm9pcycsCgkJCScuKnBveCcsCgkJCScuKnNoZWVwJywKCQkJJ3Blb3BsZScsCgkJCSdjb29raWUnLAoJCV0sCgkJJ2lycmVndWxhcicgICA9PiBbCgkJCSdhdGxhcycgICAgICAgID0+ICdhdGxhc2VzJywKCQkJJ2F4ZScgICAgICAgICAgPT4gJ2F4ZXMnLAoJCQknYmVlZicgICAgICAgICA9PiAnYmVlZnMnLAoJCQknYnJvdGhlcicgICAgICA9PiAnYnJvdGhlcnMnLAoJCQknY2FmZScgICAgICAgICA9PiAnY2FmZXMnLAoJCQknY2hhdGVhdScgICAgICA9PiAnY2hhdGVhdXgnLAoJCQknY2hpbGQnICAgICAgICA9PiAnY2hpbGRyZW4nLAoJCQknY29va2llJyAgICAgICA9PiAnY29va2llcycsCgkJCSdjb3JwdXMnICAgICAgID0+ICdjb3JwdXNlcycsCgkJCSdjb3cnICAgICAgICAgID0+ICdjb3dzJywKCQkJJ2NyaXRlcmlvbicgICAgPT4gJ2NyaXRlcmlhJywKCQkJJ2N1cnJpY3VsdW0nICAgPT4gJ2N1cnJpY3VsYScsCgkJCSdkZW1vJyAgICAgICAgID0+ICdkZW1vcycsCgkJCSdkb21pbm8nICAgICAgID0+ICdkb21pbm9lcycsCgkJCSdlY2hvJyAgICAgICAgID0+ICdlY2hvZXMnLAoJCQknZm9vdCcgICAgICAgICA9PiAnZmVldCcsCgkJCSdmdW5ndXMnICAgICAgID0+ICdmdW5naScsCgkJCSdnYW5nbGlvbicgICAgID0+ICdnYW5nbGlvbnMnLAoJCQknZ2VuaWUnICAgICAgICA9PiAnZ2VuaWVzJywKCQkJJ2dlbnVzJyAgICAgICAgPT4gJ2dlbmVyYScsCgkJCSdncmFmZml0bycgICAgID0+ICdncmFmZml0aScsCgkJCSdoaXBwb3BvdGFtdXMnID0+ICdoaXBwb3BvdGFtaScsCgkJCSdob29mJyAgICAgICAgID0+ICdob29mcycsCgkJCSdodW1hbicgICAgICAgID0+ICdodW1hbnMnLAoJCQknaXJpcycgICAgICAgICA9PiAnaXJpc2VzJywKCQkJJ2xlYWYnICAgICAgICAgPT4gJ2xlYXZlcycsCgkJCSdsb2FmJyAgICAgICAgID0+ICdsb2F2ZXMnLAoJCQknbWFuJyAgICAgICAgICA9PiAnbWVuJywKCQkJJ21lZGl1bScgICAgICAgPT4gJ21lZGlhJywKCQkJJ21lbW9yYW5kdW0nICAgPT4gJ21lbW9yYW5kYScsCgkJCSdtb25leScgICAgICAgID0+ICdtb25pZXMnLAoJCQknbW9uZ29vc2UnICAgICA9PiAnbW9uZ29vc2VzJywKCQkJJ21vdHRvJyAgICAgICAgPT4gJ21vdHRvZXMnLAoJCQknbW92ZScgICAgICAgICA9PiAnbW92ZXMnLAoJCQknbXl0aG9zJyAgICAgICA9PiAnbXl0aG9pJywKCQkJJ25pY2hlJyAgICAgICAgPT4gJ25pY2hlcycsCgkJCSdudWNsZXVzJyAgICAgID0+ICdudWNsZWknLAoJCQknbnVtZW4nICAgICAgICA9PiAnbnVtaW5hJywKCQkJJ29jY2lwdXQnICAgICAgPT4gJ29jY2lwdXRzJywKCQkJJ29jdG9wdXMnICAgICAgPT4gJ29jdG9wdXNlcycsCgkJCSdvcHVzJyAgICAgICAgID0+ICdvcHVzZXMnLAoJCQknb3gnICAgICAgICAgICA9PiAnb3hlbicsCgkJCSdwZW5pcycgICAgICAgID0+ICdwZW5pc2VzJywKCQkJJ3BlcnNvbicgICAgICAgPT4gJ3Blb3BsZScsCgkJCSdwbGF0ZWF1JyAgICAgID0+ICdwbGF0ZWF1eCcsCgkJCSdydW5uZXItdXAnICAgID0+ICdydW5uZXJzLXVwJywKCQkJJ3NleCcgICAgICAgICAgPT4gJ3NleGVzJywKCQkJJ3NvbGlsb3F1eScgICAgPT4gJ3NvbGlsb3F1aWVzJywKCQkJJ3Nvbi1pbi1sYXcnICAgPT4gJ3NvbnMtaW4tbGF3JywKCQkJJ3N5bGxhYnVzJyAgICAgPT4gJ3N5bGxhYmknLAoJCQkndGVzdGlzJyAgICAgICA9PiAndGVzdGVzJywKCQkJJ3RoaWVmJyAgICAgICAgPT4gJ3RoaWV2ZXMnLAoJCQkndG9vdGgnICAgICAgICA9PiAndGVldGgnLAoJCQkndG9ybmFkbycgICAgICA9PiAndG9ybmFkb2VzJywKCQkJJ3RyaWxieScgICAgICAgPT4gJ3RyaWxieXMnLAoJCQkndHVyZicgICAgICAgICA9PiAndHVyZnMnLAoJCQkndm9sY2FubycgICAgICA9PiAndm9sY2Fub2VzJywKCQldLAoJXTsKCgkvKioKCSAqIFNpbmd1bGFyIGluZmxlY3RvciBydWxlcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljICRzaW5ndWxhciA9IFsKCQkncnVsZXMnICAgICAgID0+IFsKCQkJJy8ocyl0YXR1c2VzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMnRhdHVzJywKCQkJJy9eKC4qKShtZW51KXMkL2knICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMicsCgkJCScvKHF1aXopemVzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1xcMScsCgkJCScvKG1hdHIpaWNlcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxaXgnLAoJCQknLyh2ZXJ0fGluZClpY2VzJC9pJyAgICAgICAgICAgICAgICAgICAgID0+ICdcMWV4JywKCQkJJy9eKG94KWVuL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDEnLAoJCQknLyhhbGlhcykoZXMpKiQvaScgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKGJ1ZmZhbHxoZXJ8cG90YXR8dG9tYXR8dm9sY2FuKW9lcyQvaScgPT4gJ1wxbycsCgkJCScvKGFsdW1ufGJhY2lsbHxjYWN0fGZvY3xmdW5nfG51Y2xlfHJhZGl8c3RpbXVsfHN5bGxhYnx0ZXJtaW58dmlyaT8paSQvaScgPT4gJ1wxdXMnLAoJCQknLyhbZnR3XWF4KWVzL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKGFuYWx5c3xheHxjcmlzfHRlc3R8dGhlcyllcyQvaScgICAgICAgPT4gJ1wxaXMnLAoJCQknLyhzaG9lfHNsYXZlKXMkL2knICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKG8pZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy9vdXNlcyQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnb3VzZScsCgkJCScvKFteYV0pdXNlcyQvJyAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxdXMnLAoJCQknLyhbbXxsXSlpY2UkL2knICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMW91c2UnLAoJCQknLyh4fGNofHNzfHNoKWVzJC9pJyAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKG0pb3ZpZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxXDJvdmllJywKCQkJJy8ocyllcmllcyQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMmVyaWVzJywKCQkJJy8oW15hZWlvdXldfHF1KWllcyQvaScgICAgICAgICAgICAgICAgICA9PiAnXDF5JywKCQkJJy8oW2xyXSl2ZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFmJywKCQkJJy8odGl2ZSlzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDEnLAoJCQknLyhoaXZlKXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMScsCgkJCScvKGRyaXZlKXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxJywKCQkJJy8oW15mb10pdmVzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFmZScsCgkJCScvKF5hbmFseSlzZXMkL2knICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxc2lzJywKCQkJJy8oYW5hbHl8ZGlhZ25vfF5iYXwocClhcmVudGhlfChwKXJvZ25vfChzKXlub3B8KHQpaGUpc2VzJC9pJyA9PiAnXDFcMnNpcycsCgkJCScvKFt0aV0pYSQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxdW0nLAoJCQknLyhwKWVvcGxlJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMVwyZXJzb24nLAoJCQknLyhtKWVuJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMWFuJywKCQkJJy8oYyloaWxkcmVuJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICA9PiAnXDFcMmhpbGQnLAoJCQknLyhmKWVldCQvaScgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcMW9vdCcsCgkJCScvKG4pZXdzJC9pJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gJ1wxXDJld3MnLAoJCQknL2VhdXMkLycgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdlYXUnLAoJCQknL14oLip1cykkLycgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICdcXDEnLAoJCQknL3MkL2knICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+ICcnLAoJCV0sCgkJJ3VuaW5mbGVjdGVkJyA9PiBbCgkJCScuKltucmxtXWVzZScsCgkJCScuKmRlZXInLAoJCQknLipmaXNoJywKCQkJJy4qbWVhc2xlcycsCgkJCScuKm9pcycsCgkJCScuKnBveCcsCgkJCScuKnNoZWVwJywKCQkJJy4qc3MnLAoJCV0sCgkJJ2lycmVndWxhcicgICA9PiBbCgkJCSdjcml0ZXJpYScgPT4gJ2NyaXRlcmlvbicsCgkJCSdjdXJ2ZXMnICAgPT4gJ2N1cnZlJywKCQkJJ2VtcGhhc2VzJyA9PiAnZW1waGFzaXMnLAoJCQknZm9lcycgICAgID0+ICdmb2UnLAoJCQknaG9heGVzJyAgID0+ICdob2F4JywKCQkJJ21lZGlhJyAgICA9PiAnbWVkaXVtJywKCQkJJ25ldXJvc2VzJyA9PiAnbmV1cm9zaXMnLAoJCQknd2F2ZXMnICAgID0+ICd3YXZlJywKCQkJJ29hc2VzJyAgICA9PiAnb2FzaXMnLAoJCV0sCgldOwoKCS8qKgoJICogV29yZHMgdGhhdCBzaG91bGQgbm90IGJlIGluZmxlY3RlZC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljICR1bmluZmxlY3RlZCA9IFsKCQknQW1veWVzZScsCgkJJ2Jpc29uJywKCQknQm9yZ2hlc2UnLAoJCSdicmVhbScsCgkJJ2JyZWVjaGVzJywKCQknYnJpdGNoZXMnLAoJCSdidWZmYWxvJywKCQknY2FudHVzJywKCQknY2FycCcsCgkJJ2NoYXNzaXMnLAoJCSdjbGlwcGVycycsCgkJJ2NvZCcsCgkJJ2NvaXR1cycsCgkJJ0NvbmdvZXNlJywKCQknY29udHJldGVtcHMnLAoJCSdjb3JwcycsCgkJJ2RlYnJpcycsCgkJJ2RpYWJldGVzJywKCQknZGppbm4nLAoJCSdlbGFuZCcsCgkJJ2VsaycsCgkJJ2VxdWlwbWVudCcsCgkJJ0Zhcm9lc2UnLAoJCSdmbG91bmRlcicsCgkJJ0Zvb2Nob3dlc2UnLAoJCSdnYWxsb3dzJywKCQknR2VuZXZlc2UnLAoJCSdHZW5vZXNlJywKCQknR2lsYmVydGVzZScsCgkJJ2dyYWZmaXRpJywKCQknaGVhZHF1YXJ0ZXJzJywKCQknaGVycGVzJywKCQknaGlqaW5rcycsCgkJJ0hvdHRlbnRvdGVzZScsCgkJJ2luZm9ybWF0aW9uJywKCQknaW5uaW5ncycsCgkJJ2phY2thbmFwZXMnLAoJCSdLaXBsaW5nZXNlJywKCQknS29uZ29lc2UnLAoJCSdMdWNjaGVzZScsCgkJJ21hY2tlcmVsJywKCQknTWFsdGVzZScsCgkJJy4qP21lZGlhJywKCQknbWV3cycsCgkJJ21vb3NlJywKCQknbXVtcHMnLAoJCSdOYW5raW5nZXNlJywKCQknbmV3cycsCgkJJ25leHVzJywKCQknTmlhc2VzZScsCgkJJ1Bla2luZ2VzZScsCgkJJ1BpZWRtb250ZXNlJywKCQkncGluY2VycycsCgkJJ1Bpc3RvaWVzZScsCgkJJ3BsaWVycycsCgkJJ1BvcnR1Z3Vlc2UnLAoJCSdwcm9jZWVkaW5ncycsCgkJJ3JhYmllcycsCgkJJ3JpY2UnLAoJCSdyaGlub2Nlcm9zJywKCQknc2FsbW9uJywKCQknU2FyYXdha2VzZScsCgkJJ3NjaXNzb3JzJywKCQknc2VhWy0gXWJhc3MnLAoJCSdzZXJpZXMnLAoJCSdTaGF2ZXNlJywKCQknc2hlYXJzJywKCQknc2llbWVucycsCgkJJ3NwZWNpZXMnLAoJCSdzdGFmZicsCgkJJ3N3aW5lJywKCQkndGVzdGVzJywKCQkndHJvdXNlcnMnLAoJCSd0cm91dCcsCgkJJ3R1bmEnLAoJCSdWZXJtb250ZXNlJywKCQknV2VuY2hvd2VzZScsCgkJJ3doaXRpbmcnLAoJCSd3aWxkZWJlZXN0JywKCQknWWVuZ2Vlc2UnLAoJXTsKCgkvKioKCSAqIE1ldGhvZCBjYWNoZSBhcnJheS4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljICRjYWNoZSA9IFtdOwoKCS8qKgoJICogVGhlIGluaXRpYWwgc3RhdGUgb2YgSW5mbGVjdG9yIHNvIHJlc2V0KCkgd29ya3MuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyAkaW5pdGlhbF9zdGF0ZSA9IFtdOwoKCS8qKgoJICogQ29udmVydHMgYSB3b3JkIGludG8gdGhlIGZvcm1hdCBmb3IgYSBEb2N0cmluZSB0YWJsZSBuYW1lLiBDb252ZXJ0cyAnTW9kZWxOYW1lJyB0byAnbW9kZWxfbmFtZScuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd29yZCBUaGUgd29yZCB0byB0YWJsZWl6ZS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgdGFibGVpemVkIHdvcmQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdGFibGVpemUoICR3b3JkICkgewoJCXJldHVybiBzdHJ0b2xvd2VyKCBwcmVnX3JlcGxhY2UoICd+KD88PVxcdykoW0EtWl0pficsICdfJDEnLCAkd29yZCApICk7Cgl9CgoJLyoqCgkgKiBDb252ZXJ0cyBhIHdvcmQgaW50byB0aGUgZm9ybWF0IGZvciBhIERvY3RyaW5lIGNsYXNzIG5hbWUuIENvbnZlcnRzICd0YWJsZV9uYW1lJyB0byAnVGFibGVOYW1lJy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3b3JkIFRoZSB3b3JkIHRvIGNsYXNzaWZ5LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFRoZSBjbGFzc2lmaWVkIHdvcmQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2xhc3NpZnkoICR3b3JkICkgewoJCXJldHVybiBzdHJfcmVwbGFjZSggJyAnLCAnJywgdWN3b3Jkcyggc3RydHIoICR3b3JkLCAnXy0nLCAnICAnICkgKSApOwoJfQoKCS8qKgoJICogQ2FtZWxpemVzIGEgd29yZC4gVGhpcyB1c2VzIHRoZSBjbGFzc2lmeSgpIG1ldGhvZCBhbmQgdHVybnMgdGhlIGZpcnN0IGNoYXJhY3RlciB0byBsb3dlcmNhc2UuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd29yZCBUaGUgd29yZCB0byBjYW1lbGl6ZS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgY2FtZWxpemVkIHdvcmQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2FtZWxpemUoICR3b3JkICkgewoJCXJldHVybiBsY2ZpcnN0KCBzZWxmOjpjbGFzc2lmeSggJHdvcmQgKSApOwoJfQoKCS8qKgoJICogVXBwZXJjYXNlcyB3b3JkcyB3aXRoIGNvbmZpZ3VyYWJsZSBkZWxpbWV0ZXJzIGJldHdlZW4gd29yZHMuCgkgKgoJICogVGFrZXMgYSBzdHJpbmcgYW5kIGNhcGl0YWxpemVzIGFsbCBvZiB0aGUgd29yZHMsIGxpa2UgUEhQJ3MgYnVpbHQtaW4KCSAqIHVjd29yZHMgZnVuY3Rpb24uICBUaGlzIGV4dGVuZHMgdGhhdCBiZWhhdmlvciwgaG93ZXZlciwgYnkgYWxsb3dpbmcgdGhlCgkgKiB3b3JkIGRlbGltZXRlcnMgdG8gYmUgY29uZmlndXJlZCwgcmF0aGVyIHRoYW4gb25seSBzZXBhcmF0aW5nIG9uCgkgKiB3aGl0ZXNwYWNlLgoJICoKCSAqIEhlcmUgaXMgYW4gZXhhbXBsZToKCSAqIDxjb2RlPgoJICogPD9waHAKCSAqICRzdHJpbmcgPSAndG9wLW8tdGhlLW1vcm5pbmcgdG8gYWxsX29mX3lvdSEnOwoJICogZWNobyBcRG9jdHJpbmVcQ29tbW9uXEluZmxlY3RvclxJbmZsZWN0b3I6OnVjd29yZHMoJHN0cmluZyk7CgkgKiAvLyBUb3AtTy1UaGUtTW9ybmluZyBUbyBBbGxfb2ZfeW91IQoJICoKCSAqIGVjaG8gXERvY3RyaW5lXENvbW1vblxJbmZsZWN0b3JcSW5mbGVjdG9yOjp1Y3dvcmRzKCRzdHJpbmcsICctXyAnKTsKCSAqIC8vIFRvcC1PLVRoZS1Nb3JuaW5nIFRvIEFsbF9PZl9Zb3UhCgkgKiA/PgoJICogPC9jb2RlPgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBUaGUgc3RyaW5nIHRvIG9wZXJhdGUgb24uCgkgKiBAcGFyYW0gc3RyaW5nICRkZWxpbWl0ZXJzIEEgbGlzdCBvZiB3b3JkIHNlcGFyYXRvcnMuCgkgKgoJICogQHJldHVybiBzdHJpbmcgVGhlIHN0cmluZyB3aXRoIGFsbCBkZWxpbWV0ZXItc2VwYXJhdGVkIHdvcmRzIGNhcGl0YWxpemVkLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHVjd29yZHMoICRzdHJpbmcsICRkZWxpbWl0ZXJzID0gIiBcblx0XHJcMFx4MEItIiApIHsKCQlyZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAoJCQknL1teJyAuIHByZWdfcXVvdGUoICRkZWxpbWl0ZXJzLCAnLycgKSAuICddKy8nLAoJCQlmdW5jdGlvbiggJG1hdGNoZXMgKSB7CgkJCQlyZXR1cm4gdWNmaXJzdCggJG1hdGNoZXNbMF0gKTsKCQkJfSwKCQkJJHN0cmluZwoJCSk7Cgl9CgoJLyoqCgkgKiBDbGVhcnMgSW5mbGVjdG9ycyBpbmZsZWN0ZWQgdmFsdWUgY2FjaGVzLCBhbmQgcmVzZXRzIHRoZSBpbmZsZWN0aW9uCgkgKiBydWxlcyB0byB0aGUgaW5pdGlhbCB2YWx1ZXMuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVzZXQoKSB7CgkJaWYgKCBlbXB0eSggc2VsZjo6JGluaXRpYWxfc3RhdGUgKSApIHsKCQkJc2VsZjo6JGluaXRpYWxfc3RhdGUgPSBnZXRfY2xhc3NfdmFycyggJ0luZmxlY3RvcicgKTsKCgkJCXJldHVybjsKCQl9CgoJCWZvcmVhY2ggKCBzZWxmOjokaW5pdGlhbF9zdGF0ZSBhcyAka2V5ID0+ICR2YWwgKSB7CgkJCWlmICggJ2luaXRpYWxfc3RhdGUnICE9PSAka2V5ICkgewoJCQkJc2VsZjo6JHska2V5fSA9ICR2YWw7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBBZGRzIGN1c3RvbSBpbmZsZWN0aW9uICRydWxlcywgb2YgZWl0aGVyICdwbHVyYWwnIG9yICdzaW5ndWxhcicgJHR5cGUuCgkgKgoJICogIyMjIFVzYWdlOgoJICoKCSAqIHt7ewoJICogSW5mbGVjdG9yOjpydWxlcygncGx1cmFsJywgYXJyYXkoJy9eKGluZmxlY3Qpb3IkL2knID0+ICdcMWFibGVzJykpOwoJICogSW5mbGVjdG9yOjpydWxlcygncGx1cmFsJywgYXJyYXkoCgkgKiAgICAgJ3J1bGVzJyA9PiBhcnJheSgnL14oaW5mbGVjdClvcnMkL2knID0+ICdcMWFibGVzJyksCgkgKiAgICAgJ3VuaW5mbGVjdGVkJyA9PiBhcnJheSgnZG9udGluZmxlY3RtZScpLAoJICogICAgICdpcnJlZ3VsYXInID0+IGFycmF5KCdyZWQnID0+ICdyZWRsaW5ncycpCgkgKiApKTsKCSAqIH19fQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICR0eXBlICBUaGUgdHlwZSBvZiBpbmZsZWN0aW9uLCBlaXRoZXIgJ3BsdXJhbCcgb3IgJ3Npbmd1bGFyJwoJICogQHBhcmFtIGFycmF5ICAgJHJ1bGVzIEFuIGFycmF5IG9mIHJ1bGVzIHRvIGJlIGFkZGVkLgoJICogQHBhcmFtIGJvb2xlYW4gJHJlc2V0IElmIHRydWUsIHdpbGwgdW5zZXQgZGVmYXVsdCBpbmZsZWN0aW9ucyBmb3IgYWxsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgbmV3IHJ1bGVzIHRoYXQgYXJlIGJlaW5nIGRlZmluZWQgaW4gJHJ1bGVzLgoJICoKCSAqIEByZXR1cm4gdm9pZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJ1bGVzKCAkdHlwZSwgJHJ1bGVzLCAkcmVzZXQgPSBmYWxzZSApIHsKCQlmb3JlYWNoICggJHJ1bGVzIGFzICRydWxlID0+ICRwYXR0ZXJuICkgewoJCQlpZiAoICEgaXNfYXJyYXkoICRwYXR0ZXJuICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAkcmVzZXQgKSB7CgkJCQlzZWxmOjokeyR0eXBlfVsgJHJ1bGUgXSA9ICRwYXR0ZXJuOwoJCQl9IGVsc2UgewoJCQkJc2VsZjo6JHskdHlwZX1bICRydWxlIF0gPSAoICd1bmluZmxlY3RlZCcgPT09ICRydWxlICkKCQkJCQk/IGFycmF5X21lcmdlKCAkcGF0dGVybiwgc2VsZjo6JHskdHlwZX1bICRydWxlIF0gKQoJCQkJCTogJHBhdHRlcm4gKyBzZWxmOjokeyR0eXBlfVsgJHJ1bGUgXTsKCQkJfQoKCQkJdW5zZXQoICRydWxlc1sgJHJ1bGUgXSwgc2VsZjo6JHskdHlwZX1bICdjYWNoZScgLiB1Y2ZpcnN0KCAkcnVsZSApIF0gKTsKCgkJCWlmICggaXNzZXQoIHNlbGY6OiR7JHR5cGV9WydtZXJnZWQnXVsgJHJ1bGUgXSApICkgewoJCQkJdW5zZXQoIHNlbGY6OiR7JHR5cGV9WydtZXJnZWQnXVsgJHJ1bGUgXSApOwoJCQl9CgoJCQlpZiAoICdwbHVyYWwnID09PSAkdHlwZSApIHsKCQkJCXNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ10gPSBbXTsKCQkJCXNlbGY6OiRjYWNoZVsndGFibGVpemUnXSAgPSBbXTsKCQkJfSBlbHNlaWYgKCAnc2luZ3VsYXInID09PSAkdHlwZSApIHsKCQkJCXNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXSA9IFtdOwoJCQl9CgkJfQoKCQlzZWxmOjokeyR0eXBlfVsncnVsZXMnXSA9ICRydWxlcyArIHNlbGY6OiR7JHR5cGV9WydydWxlcyddOwoJfQoKCS8qKgoJICogUmV0dXJucyBhIHdvcmQgaW4gcGx1cmFsIGZvcm0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd29yZCBUaGUgd29yZCBpbiBzaW5ndWxhciBmb3JtLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFRoZSB3b3JkIGluIHBsdXJhbCBmb3JtLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBsdXJhbGl6ZSggJHdvcmQgKSB7CgkJaWYgKCBpc3NldCggc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXSApICkgewoJCQlyZXR1cm4gc2VsZjo6JGNhY2hlWydwbHVyYWxpemUnXVsgJHdvcmQgXTsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6JHBsdXJhbFsnbWVyZ2VkJ11bJ2lycmVndWxhciddICkgKSB7CgkJCXNlbGY6OiRwbHVyYWxbJ21lcmdlZCddWydpcnJlZ3VsYXInXSA9IHNlbGY6OiRwbHVyYWxbJ2lycmVndWxhciddOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCBzZWxmOjokcGx1cmFsWydtZXJnZWQnXVsndW5pbmZsZWN0ZWQnXSApICkgewoJCQlzZWxmOjokcGx1cmFsWydtZXJnZWQnXVsndW5pbmZsZWN0ZWQnXSA9IGFycmF5X21lcmdlKCBzZWxmOjokcGx1cmFsWyd1bmluZmxlY3RlZCddLCBzZWxmOjokdW5pbmZsZWN0ZWQgKTsKCQl9CgoJCWlmICggISBpc3NldCggc2VsZjo6JHBsdXJhbFsnY2FjaGVVbmluZmxlY3RlZCddICkgfHwgISBpc3NldCggc2VsZjo6JHBsdXJhbFsnY2FjaGVJcnJlZ3VsYXInXSApICkgewoJCQlzZWxmOjokcGx1cmFsWydjYWNoZVVuaW5mbGVjdGVkJ10gPSAnKD86JyAuIGltcGxvZGUoICd8Jywgc2VsZjo6JHBsdXJhbFsnbWVyZ2VkJ11bJ3VuaW5mbGVjdGVkJ10gKSAuICcpJzsKCQkJc2VsZjo6JHBsdXJhbFsnY2FjaGVJcnJlZ3VsYXInXSAgID0gJyg/OicgLiBpbXBsb2RlKCAnfCcsIGFycmF5X2tleXMoIHNlbGY6OiRwbHVyYWxbJ21lcmdlZCddWydpcnJlZ3VsYXInXSApICkgLiAnKSc7CgkJfQoKCQlpZiAoIHByZWdfbWF0Y2goICcvKC4qKVxcYignIC4gc2VsZjo6JHBsdXJhbFsnY2FjaGVJcnJlZ3VsYXInXSAuICcpJC9pJywgJHdvcmQsICRyZWdzICkgKSB7CgkJCXNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ11bICR3b3JkIF0gPSAkcmVnc1sxXSAuIHN1YnN0ciggJHdvcmQsIDAsIDEgKSAuIHN1YnN0ciggc2VsZjo6JHBsdXJhbFsnbWVyZ2VkJ11bJ2lycmVndWxhciddWyBzdHJ0b2xvd2VyKCAkcmVnc1syXSApIF0sIDEgKTsKCgkJCXJldHVybiBzZWxmOjokY2FjaGVbJ3BsdXJhbGl6ZSddWyAkd29yZCBdOwoJCX0KCgkJaWYgKCBwcmVnX21hdGNoKCAnL14oJyAuIHNlbGY6OiRwbHVyYWxbJ2NhY2hlVW5pbmZsZWN0ZWQnXSAuICcpJC9pJywgJHdvcmQsICRyZWdzICkgKSB7CgkJCXNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ11bICR3b3JkIF0gPSAkd29yZDsKCgkJCXJldHVybiAkd29yZDsKCQl9CgoJCWZvcmVhY2ggKCBzZWxmOjokcGx1cmFsWydydWxlcyddIGFzICRydWxlID0+ICRyZXBsYWNlbWVudCApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAkcnVsZSwgJHdvcmQgKSApIHsKCQkJCXNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ11bICR3b3JkIF0gPSBwcmVnX3JlcGxhY2UoICRydWxlLCAkcmVwbGFjZW1lbnQsICR3b3JkICk7CgoJCQkJcmV0dXJuIHNlbGY6OiRjYWNoZVsncGx1cmFsaXplJ11bICR3b3JkIF07CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGEgd29yZCBpbiBzaW5ndWxhciBmb3JtLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdvcmQgVGhlIHdvcmQgaW4gcGx1cmFsIGZvcm0uCgkgKgoJICogQHJldHVybiBzdHJpbmcgVGhlIHdvcmQgaW4gc2luZ3VsYXIgZm9ybS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzaW5ndWxhcml6ZSggJHdvcmQgKSB7CgkJaWYgKCBpc3NldCggc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddWyAkd29yZCBdICkgKSB7CgkJCXJldHVybiBzZWxmOjokY2FjaGVbJ3Npbmd1bGFyaXplJ11bICR3b3JkIF07CgkJfQoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OiRzaW5ndWxhclsnbWVyZ2VkJ11bJ3VuaW5mbGVjdGVkJ10gKSApIHsKCQkJc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsndW5pbmZsZWN0ZWQnXSA9IGFycmF5X21lcmdlKAoJCQkJc2VsZjo6JHNpbmd1bGFyWyd1bmluZmxlY3RlZCddLAoJCQkJc2VsZjo6JHVuaW5mbGVjdGVkCgkJCSk7CgkJfQoKCQlpZiAoICEgaXNzZXQoIHNlbGY6OiRzaW5ndWxhclsnbWVyZ2VkJ11bJ2lycmVndWxhciddICkgKSB7CgkJCXNlbGY6OiRzaW5ndWxhclsnbWVyZ2VkJ11bJ2lycmVndWxhciddID0gYXJyYXlfbWVyZ2UoCgkJCQlzZWxmOjokc2luZ3VsYXJbJ2lycmVndWxhciddLAoJCQkJYXJyYXlfZmxpcCggc2VsZjo6JHBsdXJhbFsnaXJyZWd1bGFyJ10gKQoJCQkpOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCBzZWxmOjokc2luZ3VsYXJbJ2NhY2hlVW5pbmZsZWN0ZWQnXSApIHx8ICEgaXNzZXQoIHNlbGY6OiRzaW5ndWxhclsnY2FjaGVJcnJlZ3VsYXInXSApICkgewoJCQlzZWxmOjokc2luZ3VsYXJbJ2NhY2hlVW5pbmZsZWN0ZWQnXSA9ICcoPzonIC4gam9pbiggJ3wnLCBzZWxmOjokc2luZ3VsYXJbJ21lcmdlZCddWyd1bmluZmxlY3RlZCddICkgLiAnKSc7CgkJCXNlbGY6OiRzaW5ndWxhclsnY2FjaGVJcnJlZ3VsYXInXSAgID0gJyg/OicgLiBqb2luKCAnfCcsIGFycmF5X2tleXMoIHNlbGY6OiRzaW5ndWxhclsnbWVyZ2VkJ11bJ2lycmVndWxhciddICkgKSAuICcpJzsKCQl9CgoJCWlmICggcHJlZ19tYXRjaCggJy8oLiopXFxiKCcgLiBzZWxmOjokc2luZ3VsYXJbJ2NhY2hlSXJyZWd1bGFyJ10gLiAnKSQvaScsICR3b3JkLCAkcmVncyApICkgewoJCQlzZWxmOjokY2FjaGVbJ3Npbmd1bGFyaXplJ11bICR3b3JkIF0gPSAkcmVnc1sxXSAuIHN1YnN0ciggJHdvcmQsIDAsIDEgKSAuIHN1YnN0ciggc2VsZjo6JHNpbmd1bGFyWydtZXJnZWQnXVsnaXJyZWd1bGFyJ11bIHN0cnRvbG93ZXIoICRyZWdzWzJdICkgXSwgMSApOwoKCQkJcmV0dXJuIHNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXTsKCQl9CgoJCWlmICggcHJlZ19tYXRjaCggJy9eKCcgLiBzZWxmOjokc2luZ3VsYXJbJ2NhY2hlVW5pbmZsZWN0ZWQnXSAuICcpJC9pJywgJHdvcmQsICRyZWdzICkgKSB7CgkJCXNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXSA9ICR3b3JkOwoKCQkJcmV0dXJuICR3b3JkOwoJCX0KCgkJZm9yZWFjaCAoIHNlbGY6OiRzaW5ndWxhclsncnVsZXMnXSBhcyAkcnVsZSA9PiAkcmVwbGFjZW1lbnQgKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJHJ1bGUsICR3b3JkICkgKSB7CgkJCQlzZWxmOjokY2FjaGVbJ3Npbmd1bGFyaXplJ11bICR3b3JkIF0gPSBwcmVnX3JlcGxhY2UoICRydWxlLCAkcmVwbGFjZW1lbnQsICR3b3JkICk7CgoJCQkJcmV0dXJuIHNlbGY6OiRjYWNoZVsnc2luZ3VsYXJpemUnXVsgJHdvcmQgXTsKCQkJfQoJCX0KCgkJc2VsZjo6JGNhY2hlWydzaW5ndWxhcml6ZSddWyAkd29yZCBdID0gJHdvcmQ7CgoJCXJldHVybiAkd29yZDsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBBZGRzIGEgY29tbWFuZCBuYW1lc3BhY2Ugd2l0aG91dCBhY3R1YWwgZnVuY3Rpb25hbGl0eS4KICoKICogVGhpcyBpcyBtZWFudCB0byBwcm92aWRlIHRoZSBtZWFucyB0byBhdHRhY2ggbWV0YSBpbmZvcm1hdGlvbiB0byBhIG5hbWVzcGFjZQogKiB3aGVuIHRoZXJlJ3Mgbm8gYWN0dWFsIGNvbW1hbmQgbmVlZGVkLgogKgogKiBJbiBjYXNlIGEgcmVhbCBjb21tYW5kIGdldHMgcmVnaXN0ZXJlZCBmb3IgdGhlIHNhbWUgbmFtZSwgaXQgcmVwbGFjZXMgdGhlCiAqIGNvbW1hbmQgbmFtZXNwYWNlLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbW1hbmROYW1lc3BhY2UgZXh0ZW5kcyBDb21wb3NpdGVDb21tYW5kIHsKCgkvKioKCSAqIFNob3cgdGhlIHVzYWdlIGZvciBhbGwgc3ViY29tbWFuZHMgY29udGFpbmVkCgkgKiBieSB0aGUgY29tcG9zaXRlIGNvbW1hbmQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG93X3VzYWdlKCkgewoJCSRtZXRob2RzID0gJHRoaXMtPmdldF9zdWJjb21tYW5kcygpOwoKCQkkaSAgICAgPSAwOwoJCSRjb3VudCA9IDA7CgoJCWZvcmVhY2ggKCAkbWV0aG9kcyBhcyAkc3ViY29tbWFuZCApIHsKCQkJJHByZWZpeCA9ICggMCA9PT0gJGkgKSA/ICd1c2FnZTogJyA6ICcgICBvcjogJzsKCQkJJGkrKzsKCgkJCWlmICggXFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5pc19jb21tYW5kX2Rpc2FibGVkKCAkc3ViY29tbWFuZCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCVxXUF9DTEk6OmxpbmUoICRzdWJjb21tYW5kLT5nZXRfdXNhZ2UoICRwcmVmaXggKSApOwoJCQkkY291bnQrKzsKCQl9CgoJCSRjbWRfbmFtZSA9IGltcGxvZGUoICcgJywgYXJyYXlfc2xpY2UoIGdldF9wYXRoKCAkdGhpcyApLCAxICkgKTsKCQkkbWVzc2FnZSAgPSAkY291bnQgPiAwCgkJCT8gIlNlZSAnd3AgaGVscCAkY21kX25hbWUgPGNvbW1hbmQ+JyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBhIHNwZWNpZmljIGNvbW1hbmQuIgoJCQk6ICJUaGUgbmFtZXNwYWNlICRjbWRfbmFtZSBkb2VzIG5vdCBjb250YWluIGFueSB1c2FibGUgY29tbWFuZHMgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4iOwoKCQlcV1BfQ0xJOjpsaW5lKCk7CgkJXFdQX0NMSTo6bGluZSggJG1lc3NhZ2UgKTsKCgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRGlzcGF0Y2hlcjsKCnVzZSBDbG9zdXJlOwp1c2UgUmVmbGVjdGlvbkNsYXNzOwp1c2UgUmVmbGVjdGlvbkZ1bmN0aW9uOwp1c2UgUmVmbGVjdGlvbk1ldGhvZDsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxEb2NQYXJzZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQ3JlYXRlcyBDb21wb3NpdGVDb21tYW5kIG9yIFN1YmNvbW1hbmQgaW5zdGFuY2VzLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbW1hbmRGYWN0b3J5IHsKCgkvLyBDYWNoZSBvZiBmaWxlIGNvbnRlbnRzLCBpbmRleGVkIGJ5IGZpbGVuYW1lLiBPbmx5IHVzZWQgaWYgb3BjYWNoZS5zYXZlX2NvbW1lbnRzIGlzIGRpc2FibGVkLgoJcHJpdmF0ZSBzdGF0aWMgJGZpbGVfY29udGVudHMgPSBbXTsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBDb21wb3NpdGVDb21tYW5kIChvciBTdWJjb21tYW5kIGlmIGNsYXNzIGhhcyBfX2ludm9rZSgpKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgUmVwcmVzZW50cyBob3cgdGhlIGNvbW1hbmQgc2hvdWxkIGJlIGludm9rZWQKCSAqIEBwYXJhbSBzdHJpbmcgJGNhbGxhYmxlIEEgc3ViY2xhc3Mgb2YgV1BfQ0xJX0NvbW1hbmQsIGEgZnVuY3Rpb24sIG9yIGEgY2xvc3VyZQoJICogQHBhcmFtIG1peGVkICRwYXJlbnQgVGhlIG5ldyBjb21tYW5kJ3MgcGFyZW50IENvbXBvc2l0ZSAob3IgUm9vdCkgY29tbWFuZAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZSggJG5hbWUsICRjYWxsYWJsZSwgJHBhcmVudCApIHsKCgkJaWYgKCAoIGlzX29iamVjdCggJGNhbGxhYmxlICkgJiYgKCAkY2FsbGFibGUgaW5zdGFuY2VvZiBDbG9zdXJlICkgKQoJCQl8fCAoIGlzX3N0cmluZyggJGNhbGxhYmxlICkgJiYgZnVuY3Rpb25fZXhpc3RzKCAkY2FsbGFibGUgKSApICkgewoJCQkkcmVmbGVjdGlvbiA9IG5ldyBSZWZsZWN0aW9uRnVuY3Rpb24oICRjYWxsYWJsZSApOwoJCQkkY29tbWFuZCAgICA9IHNlbGY6OmNyZWF0ZV9zdWJjb21tYW5kKCAkcGFyZW50LCAkbmFtZSwgJGNhbGxhYmxlLCAkcmVmbGVjdGlvbiApOwoJCX0gZWxzZWlmICggaXNfYXJyYXkoICRjYWxsYWJsZSApICYmICggaXNfY2FsbGFibGUoICRjYWxsYWJsZSApIHx8IFV0aWxzXGlzX3ZhbGlkX2NsYXNzX2FuZF9tZXRob2RfcGFpciggJGNhbGxhYmxlICkgKSApIHsKCQkJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCAkY2FsbGFibGVbMF0gKTsKCQkJJGNvbW1hbmQgICAgPSBzZWxmOjpjcmVhdGVfc3ViY29tbWFuZCgKCQkJCSRwYXJlbnQsCgkJCQkkbmFtZSwKCQkJCVsgJGNhbGxhYmxlWzBdLCAkY2FsbGFibGVbMV0gXSwKCQkJCSRyZWZsZWN0aW9uLT5nZXRNZXRob2QoICRjYWxsYWJsZVsxXSApCgkJCSk7CgkJfSBlbHNlIHsKCQkJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCAkY2FsbGFibGUgKTsKCQkJaWYgKCAkcmVmbGVjdGlvbi0+aXNTdWJjbGFzc09mKCAnXFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2UnICkgKSB7CgkJCQkkY29tbWFuZCA9IHNlbGY6OmNyZWF0ZV9uYW1lc3BhY2UoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKTsKCQkJfSBlbHNlaWYgKCAkcmVmbGVjdGlvbi0+aGFzTWV0aG9kKCAnX19pbnZva2UnICkgKSB7CgkJCQkkY2xhc3MgICA9IGlzX29iamVjdCggJGNhbGxhYmxlICkgPyAkY2FsbGFibGUgOiAkcmVmbGVjdGlvbi0+bmFtZTsKCQkJCSRjb21tYW5kID0gc2VsZjo6Y3JlYXRlX3N1YmNvbW1hbmQoCgkJCQkJJHBhcmVudCwKCQkJCQkkbmFtZSwKCQkJCQlbICRjbGFzcywgJ19faW52b2tlJyBdLAoJCQkJCSRyZWZsZWN0aW9uLT5nZXRNZXRob2QoICdfX2ludm9rZScgKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCSRjb21tYW5kID0gc2VsZjo6Y3JlYXRlX2NvbXBvc2l0ZV9jb21tYW5kKCAkcGFyZW50LCAkbmFtZSwgJGNhbGxhYmxlICk7CgkJCX0KCQl9CgoJCXJldHVybiAkY29tbWFuZDsKCX0KCgkvKioKCSAqIENsZWFyIHRoZSBmaWxlIGNvbnRlbnRzIGNhY2hlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNsZWFyX2ZpbGVfY29udGVudHNfY2FjaGUoKSB7CgkJc2VsZjo6JGZpbGVfY29udGVudHMgPSBbXTsKCX0KCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBTdWJjb21tYW5kIGluc3RhbmNlLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkcGFyZW50IFRoZSBuZXcgY29tbWFuZCdzIHBhcmVudCBDb21wb3NpdGUgY29tbWFuZAoJICogQHBhcmFtIHN0cmluZ3xib29sICRuYW1lIFJlcHJlc2VudHMgaG93IHRoZSBjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkLgoJICogSWYgZmFsc2UsIHdpbGwgYmUgZGV0ZXJtaW5lZCBmcm9tIHRoZSBkb2N1bWVudGVkIHN1YmplY3QsIHJlcHJlc2VudGVkIGJ5IGAkcmVmbGVjdGlvbmAuCgkgKiBAcGFyYW0gbWl4ZWQgJGNhbGxhYmxlIEEgY2FsbGFibGUgZnVuY3Rpb24gb3IgY2xvc3VyZSwgb3IgY2xhc3MgbmFtZSBhbmQgbWV0aG9kCgkgKiBAcGFyYW0gb2JqZWN0ICRyZWZsZWN0aW9uIFJlZmxlY3Rpb24gaW5zdGFuY2UsIGZvciBkb2MgcGFyc2luZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVfc3ViY29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRjYWxsYWJsZSwgJHJlZmxlY3Rpb24gKSB7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCSRkb2NwYXJzZXIgICA9IG5ldyBEb2NQYXJzZXIoICRkb2NfY29tbWVudCApOwoKCQlpZiAoIGlzX2FycmF5KCAkY2FsbGFibGUgKSApIHsKCQkJaWYgKCAhICRuYW1lICkgewoJCQkJJG5hbWUgPSAkZG9jcGFyc2VyLT5nZXRfdGFnKCAnc3ViY29tbWFuZCcgKTsKCQkJfQoKCQkJaWYgKCAhICRuYW1lICkgewoJCQkJJG5hbWUgPSAkcmVmbGVjdGlvbi0+bmFtZTsKCQkJfQoJCX0KCQlpZiAoICEgJGRvY19jb21tZW50ICkgewoJCQlXUF9DTEk6OmRlYnVnKCBudWxsID09PSAkZG9jX2NvbW1lbnQgPyAiRmFpbGVkIHRvIGdldCBkb2MgY29tbWVudCBmb3IgeyRuYW1lfS4iIDogIk5vIGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIsICdjb21tYW5kZmFjdG9yeScgKTsKCQl9CgoJCSR3aGVuX2ludm9rZWQgPSBmdW5jdGlvbiAoICRhcmdzLCAkYXNzb2NfYXJncyApIHVzZSAoICRjYWxsYWJsZSApIHsKCQkJaWYgKCBpc19hcnJheSggJGNhbGxhYmxlICkgKSB7CgkJCQkkY2FsbGFibGVbMF0gPSBpc19vYmplY3QoICRjYWxsYWJsZVswXSApID8gJGNhbGxhYmxlWzBdIDogbmV3ICRjYWxsYWJsZVswXSgpOwoJCQkJY2FsbF91c2VyX2Z1bmMoIFsgJGNhbGxhYmxlWzBdLCAkY2FsbGFibGVbMV0gXSwgJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJCX0gZWxzZSB7CgkJCQljYWxsX3VzZXJfZnVuYyggJGNhbGxhYmxlLCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQkJfQoJCX07CgoJCXJldHVybiBuZXcgU3ViY29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIsICR3aGVuX2ludm9rZWQgKTsKCX0KCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBDb21wb3NpdGUgY29tbWFuZCBpbnN0YW5jZS4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgJHBhcmVudCBUaGUgbmV3IGNvbW1hbmQncyBwYXJlbnQgUm9vdCBvciBDb21wb3NpdGUgY29tbWFuZAoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBSZXByZXNlbnRzIGhvdyB0aGUgY29tbWFuZCBzaG91bGQgYmUgaW52b2tlZAoJICogQHBhcmFtIG1peGVkICRjYWxsYWJsZQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVfY29tcG9zaXRlX2NvbW1hbmQoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKSB7CgkJJHJlZmxlY3Rpb24gID0gbmV3IFJlZmxlY3Rpb25DbGFzcyggJGNhbGxhYmxlICk7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCWlmICggISAkZG9jX2NvbW1lbnQgKSB7CgkJCVdQX0NMSTo6ZGVidWcoIG51bGwgPT09ICRkb2NfY29tbWVudCA/ICJGYWlsZWQgdG8gZ2V0IGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIgOiAiTm8gZG9jIGNvbW1lbnQgZm9yIHskbmFtZX0uIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCX0KCQkkZG9jcGFyc2VyID0gbmV3IERvY1BhcnNlciggJGRvY19jb21tZW50ICk7CgoJCSRjb250YWluZXIgPSBuZXcgQ29tcG9zaXRlQ29tbWFuZCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIgKTsKCgkJZm9yZWFjaCAoICRyZWZsZWN0aW9uLT5nZXRNZXRob2RzKCkgYXMgJG1ldGhvZCApIHsKCQkJaWYgKCAhIHNlbGY6OmlzX2dvb2RfbWV0aG9kKCAkbWV0aG9kICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNsYXNzICAgICAgPSBpc19vYmplY3QoICRjYWxsYWJsZSApID8gJGNhbGxhYmxlIDogJHJlZmxlY3Rpb24tPm5hbWU7CgkJCSRzdWJjb21tYW5kID0gc2VsZjo6Y3JlYXRlX3N1YmNvbW1hbmQoICRjb250YWluZXIsIGZhbHNlLCBbICRjbGFzcywgJG1ldGhvZC0+bmFtZSBdLCAkbWV0aG9kICk7CgoJCQkkc3ViY29tbWFuZF9uYW1lID0gJHN1YmNvbW1hbmQtPmdldF9uYW1lKCk7CgoJCQkkY29udGFpbmVyLT5hZGRfc3ViY29tbWFuZCggJHN1YmNvbW1hbmRfbmFtZSwgJHN1YmNvbW1hbmQgKTsKCQl9CgoJCXJldHVybiAkY29udGFpbmVyOwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGNvbW1hbmQgbmFtZXNwYWNlIGluc3RhbmNlLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkcGFyZW50IFRoZSBuZXcgbmFtZXNwYWNlJ3MgcGFyZW50IFJvb3Qgb3IgQ29tcG9zaXRlIGNvbW1hbmQuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFJlcHJlc2VudHMgaG93IHRoZSBjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkCgkgKiBAcGFyYW0gbWl4ZWQgJGNhbGxhYmxlCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZV9uYW1lc3BhY2UoICRwYXJlbnQsICRuYW1lLCAkY2FsbGFibGUgKSB7CgkJJHJlZmxlY3Rpb24gID0gbmV3IFJlZmxlY3Rpb25DbGFzcyggJGNhbGxhYmxlICk7CgkJJGRvY19jb21tZW50ID0gc2VsZjo6Z2V0X2RvY19jb21tZW50KCAkcmVmbGVjdGlvbiApOwoJCWlmICggISAkZG9jX2NvbW1lbnQgKSB7CgkJCVdQX0NMSTo6ZGVidWcoIG51bGwgPT09ICRkb2NfY29tbWVudCA/ICJGYWlsZWQgdG8gZ2V0IGRvYyBjb21tZW50IGZvciB7JG5hbWV9LiIgOiAiTm8gZG9jIGNvbW1lbnQgZm9yIHskbmFtZX0uIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCX0KCQkkZG9jcGFyc2VyID0gbmV3IERvY1BhcnNlciggJGRvY19jb21tZW50ICk7CgoJCXJldHVybiBuZXcgQ29tbWFuZE5hbWVzcGFjZSggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIgKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYSBtZXRob2QgaXMgYWN0dWFsbHkgY2FsbGFibGUuCgkgKgoJICogQHBhcmFtIFJlZmxlY3Rpb25NZXRob2QgJG1ldGhvZAoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX2dvb2RfbWV0aG9kKCAkbWV0aG9kICkgewoJCXJldHVybiAkbWV0aG9kLT5pc1B1YmxpYygpICYmICEgJG1ldGhvZC0+aXNTdGF0aWMoKSAmJiAwICE9PSBzdHJwb3MoICRtZXRob2QtPmdldE5hbWUoKSwgJ19fJyApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgZG9jdW1lbnQgY29tbWVudC4gQ2F0ZXJzIGZvciBQSFAgZGlyZWN0aXZlIGBvcGNhY2hlLnNhdmUgY29tbWVudHNgIGJlaW5nIGRpc2FibGVkLgoJICoKCSAqIEBwYXJhbSBSZWZsZWN0aW9uTWV0aG9kfFJlZmxlY3Rpb25DbGFzc3xSZWZsZWN0aW9uRnVuY3Rpb24gJHJlZmxlY3Rpb24gUmVmbGVjdGlvbiBpbnN0YW5jZS4KCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlfG51bGwgRG9jIGNvbW1lbnQgc3RyaW5nIGlmIGFueSwgZmFsc2UgaWYgbm9uZSAoc2FtZSBhcyBgUmVmbGVjdGlvbio6OmdldERvY0NvbW1lbnQoKWApLCBudWxsIGlmIGVycm9yLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfZG9jX2NvbW1lbnQoICRyZWZsZWN0aW9uICkgewoJCSRjb250ZW50cyAgICA9IG51bGw7CgkJJGRvY19jb21tZW50ID0gJHJlZmxlY3Rpb24tPmdldERvY0NvbW1lbnQoKTsKCgkJaWYgKCBmYWxzZSAhPT0gJGRvY19jb21tZW50IHx8ICEgKCBpbmlfZ2V0KCAnb3BjYWNoZS5lbmFibGVfY2xpJyApICYmICEgaW5pX2dldCggJ29wY2FjaGUuc2F2ZV9jb21tZW50cycgKSApICkgeyAvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5JbmlEaXJlY3RpdmVzLk5ld0luaURpcmVjdGl2ZXMKCQkJLy8gRWl0aGVyIGhhdmUgZG9jIGNvbW1lbnQsIG9yIG5vIGRvYyBjb21tZW50IGFuZCBzYXZlIGNvbW1lbnRzIGVuYWJsZWQgLSBzdGFuZGFyZCBzaXR1YXRpb24uCgkJCWlmICggISBnZXRlbnYoICdXUF9DTElfVEVTVF9HRVRfRE9DX0NPTU1FTlQnICkgKSB7CgkJCQlyZXR1cm4gJGRvY19jb21tZW50OwoJCQl9CgkJfQoKCQkkZmlsZW5hbWUgPSAkcmVmbGVjdGlvbi0+Z2V0RmlsZU5hbWUoKTsKCgkJaWYgKCBpc3NldCggc2VsZjo6JGZpbGVfY29udGVudHNbICRmaWxlbmFtZSBdICkgKSB7CgkJCSRjb250ZW50cyA9IHNlbGY6OiRmaWxlX2NvbnRlbnRzWyAkZmlsZW5hbWUgXTsKCQl9IGVsc2VpZiAoIGlzX3JlYWRhYmxlKCAkZmlsZW5hbWUgKSApIHsKCQkJJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoICRmaWxlbmFtZSApOwoJCQlpZiAoIGlzX3N0cmluZyggJGNvbnRlbnRzICkgJiYgJycgIT09ICRjb250ZW50cyApIHsKCQkJCSRjb250ZW50cyAgICAgICAgICAgICAgICAgICAgICAgICA9IGV4cGxvZGUoICJcbiIsICRjb250ZW50cyApOwoJCQkJc2VsZjo6JGZpbGVfY29udGVudHNbICRmaWxlbmFtZSBdID0gJGNvbnRlbnRzOwoJCQl9CgkJfQoKCQlpZiAoICEgZW1wdHkoICRjb250ZW50cyApICkgewoJCQlyZXR1cm4gc2VsZjo6ZXh0cmFjdF9sYXN0X2RvY19jb21tZW50KCBpbXBsb2RlKCAiXG4iLCBhcnJheV9zbGljZSggJGNvbnRlbnRzLCAwLCAkcmVmbGVjdGlvbi0+Z2V0U3RhcnRMaW5lKCkgKSApICk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAiQ291bGQgbm90IHJlYWQgY29udGVudHMgZm9yIGZpbGVuYW1lICd7JGZpbGVuYW1lfScuIiwgJ2NvbW1hbmRmYWN0b3J5JyApOwoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgbGFzdCBkb2MgY29tbWVudCBpZiBhbnkgaW4gYCRjb250ZW50YC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50IFRoZSBjb250ZW50LCB3aGljaCBzaG91bGQgZW5kIGF0IHRoZSBjbGFzcyBvciBmdW5jdGlvbiBkZWNsYXJhdGlvbi4KCSAqIEByZXR1cm4gc3RyaW5nfGJvb2wgVGhlIGxhc3QgZG9jIGNvbW1lbnQgaWYgYW55LCBvciBmYWxzZSBpZiBub25lLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0X2xhc3RfZG9jX2NvbW1lbnQoICRjb250ZW50ICkgewoJCSRjb250ZW50ICAgICAgICAgPSB0cmltKCAkY29udGVudCApOwoJCSRjb21tZW50X2VuZF9wb3MgPSBzdHJycG9zKCAkY29udGVudCwgJyovJyApOwoJCWlmICggZmFsc2UgPT09ICRjb21tZW50X2VuZF9wb3MgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gTWFrZSBzdXJlIGNvbW1lbnQgZW5kIGJlbG9uZ3MgdG8gdGhpcyBjbGFzcy9mdW5jdGlvbi4KCQlpZiAoIHByZWdfbWF0Y2hfYWxsKCAnLyg/Ol58W1xzO31dKSg/OmNsYXNzfGZ1bmN0aW9uKVxzKy8nLCBzdWJzdHIoICRjb250ZW50LCAkY29tbWVudF9lbmRfcG9zICsgMiApLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApID4gMSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkY29udGVudCAgICAgICAgICAgPSBzdWJzdHIoICRjb250ZW50LCAwLCAkY29tbWVudF9lbmRfcG9zICsgMiApOwoJCSRjb21tZW50X3N0YXJ0X3BvcyA9IHN0cnJwb3MoICRjb250ZW50LCAnLyoqJyApOwoJCWlmICggZmFsc2UgPT09ICRjb21tZW50X3N0YXJ0X3BvcyB8fCAoICRjb21tZW50X3N0YXJ0X3BvcyArIDIgKSA9PT0gJGNvbW1lbnRfZW5kX3BvcyApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBNYWtlIHN1cmUgY29tbWVudCBzdGFydCBiZWxvbmdzIHRvIHRoaXMgY29tbWVudCBlbmQuCgkJJGNvbW1lbnRfZW5kMl9wb3MgPSBzdHJwb3MoIHN1YnN0ciggJGNvbnRlbnQsICRjb21tZW50X3N0YXJ0X3BvcyApLCAnKi8nICk7CgkJaWYgKCBmYWxzZSAhPT0gJGNvbW1lbnRfZW5kMl9wb3MgJiYgKCAkY29tbWVudF9zdGFydF9wb3MgKyAkY29tbWVudF9lbmQyX3BvcyApIDwgJGNvbW1lbnRfZW5kX3BvcyApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBBbGxvdyBmb3IgJy8qKicgd2l0aGluIGRvYyBjb21tZW50LgoJCSRzdWJjb250ZW50ID0gc3Vic3RyKCAkY29udGVudCwgMCwgJGNvbW1lbnRfc3RhcnRfcG9zICk7CgkJd2hpbGUgKCBmYWxzZSAhPT0gKCAkY29tbWVudF9zdGFydDJfcG9zID0gc3RycnBvcyggJHN1YmNvbnRlbnQsICcvKionICkgKSAmJiBmYWxzZSA9PT0gc3RycG9zKCAkc3ViY29udGVudCwgJyovJywgJGNvbW1lbnRfc3RhcnQyX3BvcyApICkgewoJCQkkY29tbWVudF9zdGFydF9wb3MgPSAkY29tbWVudF9zdGFydDJfcG9zOwoJCQkkc3ViY29udGVudCAgICAgICAgPSBzdWJzdHIoICRzdWJjb250ZW50LCAwLCAkY29tbWVudF9zdGFydF9wb3MgKTsKCQl9CgkJcmV0dXJuIHN1YnN0ciggJGNvbnRlbnQsICRjb21tZW50X3N0YXJ0X3BvcywgJGNvbW1lbnRfZW5kX3BvcyArIDIgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDb250cm9scyB3aGV0aGVyIGFkZGluZyBvZiBhIGNvbW1hbmQgc2hvdWxkIGJlIGNvbXBsZXRlZCBvciBub3QuCiAqCiAqIFRoaXMgaXMgbmVlZGVkIGJlY2F1c2Ugd2UgY2FuJ3QgcmVsaWFibHkgcGFzcyBzY2FsYXIgdmFsdWVzIGJ5IHJlZmVyZW5jZQogKiB0aHJvdWdoIHRoZSBob29rcyBtZWNoYW5pc20uIEFuIG9iamVjdCBpcyBhbHdheXMgcGFzc2VkIGJ5IHJlZmVyZW5jZS4KICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpmaW5hbCBjbGFzcyBDb21tYW5kQWRkaXRpb24gewoKCS8qKgoJICogV2hldGhlciB0aGUgY29tbWFuZCBhZGRpdGlvbiB3YXMgYWJvcnRlZCBvciBub3QuCgkgKgoJICogQHZhciBib29sCgkgKi8KCXByaXZhdGUgJGFib3J0ID0gZmFsc2U7CgoJLyoqCgkgKiBSZWFzb24gZm9yIHdoaWNoIHRoZSBhZGRpdGlvbiB3YXMgYWJvcnRlZC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcml2YXRlICRyZWFzb24gPSAnJzsKCgkvKioKCSAqIEFib3J0IHRoZSBjdXJyZW50IGNvbW1hbmQgYWRkaXRpb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcmVhc29uIFJlYXNvbiBhcyB0byB3aHkgdGhlIGFkZGl0aW9uIHdhcyBhYm9ydGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWJvcnQoICRyZWFzb24gPSAnJyApIHsKCQkkdGhpcy0+YWJvcnQgID0gdHJ1ZTsKCQkkdGhpcy0+cmVhc29uID0gKHN0cmluZykgJHJlYXNvbjsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgdGhlIGNvbW1hbmQgYWRkaXRpb24gd2FzIGFib3J0ZWQuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB3YXNfYWJvcnRlZCgpIHsKCQlyZXR1cm4gJHRoaXMtPmFib3J0OwoJfQoKCS8qKgoJICogR2V0IHRoZSByZWFzb24gYXMgdG8gd2h5IHRoZSBhZGRpdGlvbiB3YXMgYWJvcnRlZC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3JlYXNvbigpIHsKCQlyZXR1cm4gJHRoaXMtPnJlYXNvbjsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxEb2NQYXJzZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQSBub24tbGVhZiBub2RlIGluIHRoZSBjb21tYW5kIHRyZWUuCiAqIENvbnRhaW5zIG9uZSBvciBtb3JlIFN1YmNvbW1hbmRzLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbXBvc2l0ZUNvbW1hbmQgewoKCXByb3RlY3RlZCAkbmFtZTsKCXByb3RlY3RlZCAkc2hvcnRkZXNjOwoJcHJvdGVjdGVkICRzeW5vcHNpczsKCXByb3RlY3RlZCAkZG9jcGFyc2VyOwoKCXByb3RlY3RlZCAkcGFyZW50OwoJcHJvdGVjdGVkICRzdWJjb21tYW5kcyA9IFtdOwoKCS8qKgoJICogSW5zdGFudGlhdGUgYSBuZXcgQ29tcG9zaXRlQ29tbWFuZAoJICoKCSAqIEBwYXJhbSBtaXhlZCAkcGFyZW50IFBhcmVudCBjb21tYW5kIChlaXRoZXIgUm9vdCBvciBDb21wb3NpdGUpCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFJlcHJlc2VudHMgaG93IGNvbW1hbmQgc2hvdWxkIGJlIGludm9rZWQKCSAqIEBwYXJhbSBEb2NQYXJzZXIgJGRvY3BhcnNlcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRwYXJlbnQsICRuYW1lLCAkZG9jcGFyc2VyICkgewoJCSR0aGlzLT5wYXJlbnQgPSAkcGFyZW50OwoKCQkkdGhpcy0+bmFtZSA9ICRuYW1lOwoKCQkkdGhpcy0+c2hvcnRkZXNjID0gJGRvY3BhcnNlci0+Z2V0X3Nob3J0ZGVzYygpOwoJCSR0aGlzLT5sb25nZGVzYyAgPSAkZG9jcGFyc2VyLT5nZXRfbG9uZ2Rlc2MoKTsKCQkkdGhpcy0+ZG9jcGFyc2VyID0gJGRvY3BhcnNlcjsKCgkJJHdoZW5fdG9faW52b2tlID0gJGRvY3BhcnNlci0+Z2V0X3RhZyggJ3doZW4nICk7CgkJaWYgKCAkd2hlbl90b19pbnZva2UgKSB7CgkJCVdQX0NMSTo6Z2V0X3J1bm5lcigpLT5yZWdpc3Rlcl9lYXJseV9pbnZva2UoICR3aGVuX3RvX2ludm9rZSwgJHRoaXMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHBhcmVudCBjb21wb3NpdGUgKG9yIHJvb3QpIGNvbW1hbmQKCSAqCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcGFyZW50KCkgewoJCXJldHVybiAkdGhpcy0+cGFyZW50OwoJfQoKCS8qKgoJICogQWRkIGEgbmFtZWQgc3ViY29tbWFuZCB0byB0aGlzIGNvbXBvc2l0ZSBjb21tYW5kJ3MKCSAqIHNldCBvZiBjb250YWluZWQgc3ViY29tbWFuZHMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBSZXByZXNlbnRzIGhvdyBzdWJjb21tYW5kIHNob3VsZCBiZSBpbnZva2VkCgkgKiBAcGFyYW0gU3ViY29tbWFuZHxDb21wb3NpdGVDb21tYW5kICRjb21tYW5kCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfc3ViY29tbWFuZCggJG5hbWUsICRjb21tYW5kICkgewoJCSR0aGlzLT5zdWJjb21tYW5kc1sgJG5hbWUgXSA9ICRjb21tYW5kOwoJfQoKCS8qKgoJICogUmVtb3ZlIGEgbmFtZWQgc3ViY29tbWFuZCBmcm9tIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQncyBzZXQgb2YgY29udGFpbmVkCgkgKiBzdWJjb21tYW5kcwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgUmVwcmVzZW50cyBob3cgc3ViY29tbWFuZCBzaG91bGQgYmUgaW52b2tlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlX3N1YmNvbW1hbmQoICRuYW1lICkgewoJCWlmICggaXNzZXQoICR0aGlzLT5zdWJjb21tYW5kc1sgJG5hbWUgXSApICkgewoJCQl1bnNldCggJHRoaXMtPnN1YmNvbW1hbmRzWyAkbmFtZSBdICk7CgkJfQoJfQoKCgkvKioKCSAqIENvbXBvc2l0ZSBjb21tYW5kcyBhbHdheXMgY29udGFpbiBzdWJjb21tYW5kcy4KCSAqCgkgKiBAcmV0dXJuIHRydWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgewoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogR2V0IHRoZSBzdWJjb21tYW5kcyBjb250YWluZWQgYnkgdGhpcyBjb21wb3NpdGUKCSAqIGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3N1YmNvbW1hbmRzKCkgewoJCWtzb3J0KCAkdGhpcy0+c3ViY29tbWFuZHMgKTsKCgkJcmV0dXJuICR0aGlzLT5zdWJjb21tYW5kczsKCX0KCgkvKioKCSAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGNvbXBvc2l0ZSBjb21tYW5kLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfbmFtZSgpIHsKCQlyZXR1cm4gJHRoaXMtPm5hbWU7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHNob3J0IGRlc2NyaXB0aW9uIGZvciB0aGlzIGNvbXBvc2l0ZQoJICogY29tbWFuZC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3Nob3J0ZGVzYygpIHsKCQlyZXR1cm4gJHRoaXMtPnNob3J0ZGVzYzsKCX0KCgkvKioKCSAqIFNldCB0aGUgc2hvcnQgZGVzY3JpcHRpb24gZm9yIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2hvcnRkZXNjCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfc2hvcnRkZXNjKCAkc2hvcnRkZXNjICkgewoJCSR0aGlzLT5zaG9ydGRlc2MgPSBVdGlsc1xub3JtYWxpemVfZW9scyggJHNob3J0ZGVzYyApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBsb25nIGRlc2NyaXB0aW9uIGZvciB0aGlzIGNvbXBvc2l0ZQoJICogY29tbWFuZC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvbmdkZXNjKCkgewoJCXJldHVybiAkdGhpcy0+bG9uZ2Rlc2MgLiAkdGhpcy0+Z2V0X2dsb2JhbF9wYXJhbXMoKTsKCX0KCgkvKioKCSAqIFNldCB0aGUgbG9uZyBkZXNjcmlwdGlvbiBmb3IgdGhpcyBjb21wb3NpdGUgY29tbWFuZAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGxvbmdkZXNjCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfbG9uZ2Rlc2MoICRsb25nZGVzYyApIHsKCQkkdGhpcy0+bG9uZ2Rlc2MgPSBVdGlsc1xub3JtYWxpemVfZW9scyggJGxvbmdkZXNjICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHN5bm9wc2lzIGZvciB0aGlzIGNvbXBvc2l0ZSBjb21tYW5kLgoJICogQXMgYSBjb2xsZWN0aW9uIG9mIHN1YmNvbW1hbmRzLCB0aGUgY29tcG9zaXRlCgkgKiBjb21tYW5kIGlzIG9ubHkgaW50ZW5kZWQgdG8gaW52b2tlIHRob3NlCgkgKiBzdWJjb21tYW5kcy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3N5bm9wc2lzKCkgewoJCXJldHVybiAnPGNvbW1hbmQ+JzsKCX0KCgkvKioKCSAqIEdldCB0aGUgdXNhZ2UgZm9yIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF91c2FnZSggJHByZWZpeCApIHsKCQlyZXR1cm4gc3ByaW50ZigKCQkJJyVzJXMgJXMnLAoJCQkkcHJlZml4LAoJCQlpbXBsb2RlKCAnICcsIGdldF9wYXRoKCAkdGhpcyApICksCgkJCSR0aGlzLT5nZXRfc3lub3BzaXMoKQoJCSk7Cgl9CgoJLyoqCgkgKiBTaG93IHRoZSB1c2FnZSBmb3IgYWxsIHN1YmNvbW1hbmRzIGNvbnRhaW5lZAoJICogYnkgdGhlIGNvbXBvc2l0ZSBjb21tYW5kLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2hvd191c2FnZSgpIHsKCQkkbWV0aG9kcyA9ICR0aGlzLT5nZXRfc3ViY29tbWFuZHMoKTsKCgkJJGkgPSAwOwoKCQlmb3JlYWNoICggJG1ldGhvZHMgYXMgJHN1YmNvbW1hbmQgKSB7CgkJCSRwcmVmaXggPSAoIDAgPT09ICRpICkgPyAndXNhZ2U6ICcgOiAnICAgb3I6ICc7CgkJCSRpKys7CgoJCQlpZiAoIFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5pc19jb21tYW5kX2Rpc2FibGVkKCAkc3ViY29tbWFuZCApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCVdQX0NMSTo6bGluZSggJHN1YmNvbW1hbmQtPmdldF91c2FnZSggJHByZWZpeCApICk7CgkJfQoKCQkkY21kX25hbWUgPSBpbXBsb2RlKCAnICcsIGFycmF5X3NsaWNlKCBnZXRfcGF0aCggJHRoaXMgKSwgMSApICk7CgoJCVdQX0NMSTo6bGluZSgpOwoJCVdQX0NMSTo6bGluZSggIlNlZSAnd3AgaGVscCAkY21kX25hbWUgPGNvbW1hbmQ+JyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBhIHNwZWNpZmljIGNvbW1hbmQuIiApOwoJfQoKCS8qKgoJICogV2hlbiBhIGNvbXBvc2l0ZSBjb21tYW5kIGlzIGludm9rZWQsIGl0IHNob3dzIHVzYWdlCgkgKiBkb2NzIGZvciBpdHMgc3ViY29tbWFuZHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqIEBwYXJhbSBhcnJheSAkZXh0cmFfYXJncwoJICovCglwdWJsaWMgZnVuY3Rpb24gaW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzICkgewoJCSR0aGlzLT5zaG93X3VzYWdlKCk7Cgl9CgoJLyoqCgkgKiBHaXZlbiBzdXBwbGllZCBhcmd1bWVudHMsIGZpbmQgYSBjb250YWluZWQKCSAqIHN1YmNvbW1hbmQKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEByZXR1cm4gU3ViY29tbWFuZHxmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZmluZF9zdWJjb21tYW5kKCAmJGFyZ3MgKSB7CgkJJG5hbWUgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJJHN1YmNvbW1hbmRzID0gJHRoaXMtPmdldF9zdWJjb21tYW5kcygpOwoKCQlpZiAoICEgaXNzZXQoICRzdWJjb21tYW5kc1sgJG5hbWUgXSApICkgewoJCQkkYWxpYXNlcyA9IHNlbGY6OmdldF9hbGlhc2VzKCAkc3ViY29tbWFuZHMgKTsKCgkJCWlmICggaXNzZXQoICRhbGlhc2VzWyAkbmFtZSBdICkgKSB7CgkJCQkkbmFtZSA9ICRhbGlhc2VzWyAkbmFtZSBdOwoJCQl9CgkJfQoKCQlpZiAoICEgaXNzZXQoICRzdWJjb21tYW5kc1sgJG5hbWUgXSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHN1YmNvbW1hbmRzWyAkbmFtZSBdOwoJfQoKCS8qKgoJICogR2V0IGFueSByZWdpc3RlcmVkIGFsaWFzZXMgZm9yIHRoaXMgY29tcG9zaXRlIGNvbW1hbmQncwoJICogc3ViY29tbWFuZHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRzdWJjb21tYW5kcwoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfYWxpYXNlcyggJHN1YmNvbW1hbmRzICkgewoJCSRhbGlhc2VzID0gW107CgoJCWZvcmVhY2ggKCAkc3ViY29tbWFuZHMgYXMgJG5hbWUgPT4gJHN1YmNvbW1hbmQgKSB7CgkJCSRhbGlhcyA9ICRzdWJjb21tYW5kLT5nZXRfYWxpYXMoKTsKCQkJaWYgKCAkYWxpYXMgKSB7CgkJCQkkYWxpYXNlc1sgJGFsaWFzIF0gPSAkbmFtZTsKCQkJfQoJCX0KCgkJcmV0dXJuICRhbGlhc2VzOwoJfQoKCS8qKgoJICogQ29tcG9zaXRlIGNvbW1hbmRzIGNhbiBvbmx5IGJlIGtub3duIGJ5IG9uZSBuYW1lLgoJICoKCSAqIEByZXR1cm4gZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9hbGlhcygpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqKgoJICogR2V0IHRoZSBsaXN0IG9mIGdsb2JhbCBwYXJhbWV0ZXJzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcm9vdF9jb21tYW5kIHdoZXRoZXIgdG8gaW5jbHVkZSBvciBub3Qgcm9vdCBjb21tYW5kIHNwZWNpZmljIGRlc2NyaXB0aW9uCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2dsb2JhbF9wYXJhbXMoICRyb290X2NvbW1hbmQgPSBmYWxzZSApIHsKCQkkYmluZGluZyAgICAgICAgICAgICAgICAgPSBbXTsKCQkkYmluZGluZ1sncm9vdF9jb21tYW5kJ10gPSAkcm9vdF9jb21tYW5kOwoKCQlpZiAoICEgJHRoaXMtPmNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgfHwgKCBpc19vYmplY3QoICR0aGlzLT5wYXJlbnQgKSAmJiBnZXRfY2xhc3MoICR0aGlzLT5wYXJlbnQgKSA9PT0gJ1dQX0NMSVxEaXNwYXRjaGVyXENvbXBvc2l0ZUNvbW1hbmQnICkgKSB7CgkJCSRiaW5kaW5nWydpc19zdWJjb21tYW5kJ10gPSB0cnVlOwoJCX0KCgkJZm9yZWFjaCAoIFdQX0NMSTo6Z2V0X2NvbmZpZ3VyYXRvcigpLT5nZXRfc3BlYygpIGFzICRrZXkgPT4gJGRldGFpbHMgKSB7CgkJCWlmICggZmFsc2UgPT09ICRkZXRhaWxzWydydW50aW1lJ10gKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCBpc3NldCggJGRldGFpbHNbJ2RlcHJlY2F0ZWQnXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggaXNzZXQoICRkZXRhaWxzWydoaWRkZW4nXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggdHJ1ZSA9PT0gJGRldGFpbHNbJ3J1bnRpbWUnXSApIHsKCQkJCSRzeW5vcHNpcyA9ICItLVtuby1dJGtleSI7CgkJCX0gZWxzZSB7CgkJCQkkc3lub3BzaXMgPSAiLS0ka2V5IiAuICRkZXRhaWxzWydydW50aW1lJ107CgkJCX0KCgkJCS8vIENoZWNrIGlmIGdsb2JhbCBwYXJhbWV0ZXJzIHN5bm9wc2lzIHNob3VsZCBiZSBkaXNwbGF5ZWQgb3Igbm90LgoJCQlpZiAoICd0cnVlJyAhPT0gZ2V0ZW52KCAnV1BfQ0xJX1NVUFBSRVNTX0dMT0JBTF9QQVJBTVMnICkgKSB7CgkJCQkkYmluZGluZ1sncGFyYW1ldGVycyddW10gICA9IFsKCQkJCQknc3lub3BzaXMnID0+ICRzeW5vcHNpcywKCQkJCQknZGVzYycgICAgID0+ICRkZXRhaWxzWydkZXNjJ10sCgkJCQldOwoJCQkJJGJpbmRpbmdbJ2hhc19wYXJhbWV0ZXJzJ10gPSB0cnVlOwoJCQl9CgkJfQoKCQlpZiAoICR0aGlzLT5nZXRfc3ViY29tbWFuZHMoKSApIHsKCQkJJGJpbmRpbmdbJ2hhc19zdWJjb21tYW5kcyddID0gdHJ1ZTsKCQl9CgoJCXJldHVybiBVdGlsc1xtdXN0YWNoZV9yZW5kZXIoICdtYW4tcGFyYW1zLm11c3RhY2hlJywgJGJpbmRpbmcgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBUaGUgcm9vdCBub2RlIGluIHRoZSBjb21tYW5kIHRyZWUuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSQogKi8KY2xhc3MgUm9vdENvbW1hbmQgZXh0ZW5kcyBDb21wb3NpdGVDb21tYW5kIHsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPnBhcmVudCA9IGZhbHNlOwoKCQkkdGhpcy0+bmFtZSA9ICd3cCc7CgoJCSR0aGlzLT5zaG9ydGRlc2MgPSAnTWFuYWdlIFdvcmRQcmVzcyB0aHJvdWdoIHRoZSBjb21tYW5kLWxpbmUuJzsKCX0KCgkvKioKCSAqIEdldCB0aGUgaHVtYW4tcmVhZGFibGUgbG9uZyBkZXNjcmlwdGlvbi4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvbmdkZXNjKCkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2dsb2JhbF9wYXJhbXMoIHRydWUgKTsKCX0KCgkvKioKCSAqIEZpbmQgYSBzdWJjb21tYW5kIHJlZ2lzdGVyZWQgb24gdGhlIHJvb3QKCSAqIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcmV0dXJuIFN1YmNvbW1hbmR8ZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbmRfc3ViY29tbWFuZCggJiRhcmdzICkgewoJCSRjb21tYW5kID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJCVV0aWxzXGxvYWRfY29tbWFuZCggJGNvbW1hbmQgKTsKCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+c3ViY29tbWFuZHNbICRjb21tYW5kIF0gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5zdWJjb21tYW5kc1sgJGNvbW1hbmQgXTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxEaXNwYXRjaGVyOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxEb2NQYXJzZXI7CnVzZSBXUF9DTElcU3lub3BzaXNQYXJzZXI7CnVzZSBXUF9DTElcU3lub3BzaXNWYWxpZGF0b3I7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQSBsZWFmIG5vZGUgaW4gdGhlIGNvbW1hbmQgdHJlZS4KICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBTdWJjb21tYW5kIGV4dGVuZHMgQ29tcG9zaXRlQ29tbWFuZCB7CgoJcHJpdmF0ZSAkYWxpYXM7CgoJcHJpdmF0ZSAkd2hlbl9pbnZva2VkOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIsICR3aGVuX2ludm9rZWQgKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJHBhcmVudCwgJG5hbWUsICRkb2NwYXJzZXIgKTsKCgkJJHRoaXMtPndoZW5faW52b2tlZCA9ICR3aGVuX2ludm9rZWQ7CgoJCSR0aGlzLT5hbGlhcyA9ICRkb2NwYXJzZXItPmdldF90YWcoICdhbGlhcycgKTsKCgkJJHRoaXMtPnN5bm9wc2lzID0gJGRvY3BhcnNlci0+Z2V0X3N5bm9wc2lzKCk7CgkJaWYgKCAhICR0aGlzLT5zeW5vcHNpcyAmJiAkdGhpcy0+bG9uZ2Rlc2MgKSB7CgkJCSR0aGlzLT5zeW5vcHNpcyA9IHNlbGY6OmV4dHJhY3Rfc3lub3BzaXMoICR0aGlzLT5sb25nZGVzYyApOwoJCX0KCX0KCgkvKioKCSAqIEV4dHJhY3QgdGhlIHN5bm9wc2lzIGZyb20gUEhQZG9jIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRsb25nZGVzYyBDb21tYW5kIGRvY3MgdmlhIFBIUGRvYwoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdF9zeW5vcHNpcyggJGxvbmdkZXNjICkgewoJCXByZWdfbWF0Y2hfYWxsKCAnLyguKz8pW1xyXG5dKzovJywgJGxvbmdkZXNjLCAkbWF0Y2hlcyApOwoJCXJldHVybiBpbXBsb2RlKCAnICcsICRtYXRjaGVzWzFdICk7Cgl9CgoJLyoqCgkgKiBTdWJjb21tYW5kcyBjYW4ndCBoYXZlIHN1YmNvbW1hbmRzIGJlY2F1c2UgdGhleQoJICogcmVwcmVzZW50IGNvZGUgdG8gYmUgZXhlY3V0ZWQuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjYW5faGF2ZV9zdWJjb21tYW5kcygpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHN5bm9wc2lzIHN0cmluZyBmb3IgdGhpcyBzdWJjb21tYW5kLgoJICogQSBzeW5vcHNpcyBkZWZpbmVzIHdoYXQgcnVudGltZSBhcmd1bWVudHMgYXJlCgkgKiBleHBlY3RlZCwgdXNlZnVsIHRvIGh1bWFucyBhbmQgYXJndW1lbnQgdmFsaWRhdGlvbi4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3N5bm9wc2lzKCkgewoJCXJldHVybiAkdGhpcy0+c3lub3BzaXM7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHN5bm9wc2lzIHN0cmluZyBmb3IgdGhpcyBzdWJjb21tYW5kLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN5bm9wc2lzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfc3lub3BzaXMoICRzeW5vcHNpcyApIHsKCQkkdGhpcy0+c3lub3BzaXMgPSAkc3lub3BzaXM7Cgl9CgoJLyoqCgkgKiBJZiBhbiBhbGlhcyBpcyBzZXQsIGdyYW50IGFjY2VzcyB0byBpdC4KCSAqIEFsaWFzZXMgcGVybWl0IHN1YmNvbW1hbmRzIHRvIGJlIGluc3RhbnRpYXRlZAoJICogd2l0aCBhIHNlY29uZGFyeSBpZGVudGl0eS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FsaWFzKCkgewoJCXJldHVybiAkdGhpcy0+YWxpYXM7Cgl9CgoJLyoqCgkgKiBQcmludCB0aGUgdXNhZ2UgZGV0YWlscyB0byB0aGUgZW5kIHVzZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcHJlZml4CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaG93X3VzYWdlKCAkcHJlZml4ID0gJ3VzYWdlOiAnICkgewoJCVxXUF9DTEk6OmxpbmUoICR0aGlzLT5nZXRfdXNhZ2UoICRwcmVmaXggKSApOwoJfQoKCS8qKgoJICogR2V0IHRoZSB1c2FnZSBvZiB0aGUgc3ViY29tbWFuZCBhcyBhIGZvcm1hdHRlZCBzdHJpbmcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcHJlZml4CgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3VzYWdlKCAkcHJlZml4ICkgewoJCXJldHVybiBzcHJpbnRmKAoJCQknJXMlcyAlcycsCgkJCSRwcmVmaXgsCgkJCWltcGxvZGUoICcgJywgZ2V0X3BhdGgoICR0aGlzICkgKSwKCQkJJHRoaXMtPmdldF9zeW5vcHNpcygpCgkJKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgZm9yIENMSSBUb29scycgcHJvbXB0KCkgbWV0aG9kLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uCgkgKiBAcGFyYW0gc3RyaW5nICRkZWZhdWx0CgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByb21wdCggJHF1ZXN0aW9uLCAkZGVmYXVsdCApIHsKCgkJJHF1ZXN0aW9uIC49ICc6ICc7CgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdyZWFkbGluZScgKSApIHsKCQkJcmV0dXJuIHJlYWRsaW5lKCAkcXVlc3Rpb24gKTsKCQl9CgoJCWVjaG8gJHF1ZXN0aW9uOwoKCQkkcmV0ID0gc3RyZWFtX2dldF9saW5lKCBTVERJTiwgMTAyNCwgIlxuIiApOwoJCWlmICggVXRpbHNcaXNfd2luZG93cygpICYmICJcciIgPT09IHN1YnN0ciggJHJldCwgLTEgKSApIHsKCQkJJHJldCA9IHN1YnN0ciggJHJldCwgMCwgLTEgKTsKCQl9CgkJcmV0dXJuICRyZXQ7Cgl9CgoJLyoqCgkgKiBJbnRlcmFjdGl2ZWx5IHByb21wdCB0aGUgdXNlciBmb3IgaW5wdXQKCSAqIGJhc2VkIG9uIGRlZmluZWQgc3lub3BzaXMgYW5kIHBhc3NlZCBhcmd1bWVudHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwcm9tcHRfYXJncyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkc3lub3BzaXMgPSAkdGhpcy0+Z2V0X3N5bm9wc2lzKCk7CgoJCWlmICggISAkc3lub3BzaXMgKSB7CgkJCXJldHVybiBbICRhcmdzLCAkYXNzb2NfYXJncyBdOwoJCX0KCgkJLy8gVG8gc2tpcCB0aGUgYWxyZWFkeSBwcm92aWRlZCBwb3NpdGlvbmFsIGFyZ3VtZW50cywgd2UgbmVlZCB0byBjb3VudAoJCS8vIGhvdyBtYW55IHdlIGhhZCBhbHJlYWR5IHJlY2VpdmVkLgoJCSRhcmdfaW5kZXggPSAwOwoKCQkkc3BlYyA9IGFycmF5X2ZpbHRlcigKCQkJU3lub3BzaXNQYXJzZXI6OnBhcnNlKCAkc3lub3BzaXMgKSwKCQkJZnVuY3Rpb24oICRzcGVjX2FyZyApIHVzZSAoICRhcmdzLCAkYXNzb2NfYXJncywgJiRhcmdfaW5kZXggKSB7CgkJCQlzd2l0Y2ggKCAkc3BlY19hcmdbJ3R5cGUnXSApIHsKCQkJCQljYXNlICdwb3NpdGlvbmFsJzoKCQkJCQkJLy8gT25seSBwcm9tcHQgZm9yIHRoZSBwb3NpdGlvbmFsIGFyZ3VtZW50cyB0aGF0IGFyZSBub3QKCQkJCQkJLy8geWV0IHByb3ZpZGVkLCBiYXNlZCBwdXJlbHkgb24gbnVtYmVyLgoJCQkJCQlyZXR1cm4gJGFyZ19pbmRleCsrID49IGNvdW50KCAkYXJncyApOwoJCQkJCWNhc2UgJ2dlbmVyaWMnOgoJCQkJCQkvLyBBbHdheXMgcHJvbXB0IGZvciBnZW5lcmljIGFyZ3VtZW50cy4KCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJY2FzZSAnYXNzb2MnOgoJCQkJCWNhc2UgJ2ZsYWcnOgoJCQkJCWRlZmF1bHQ6CgkJCQkJCS8vIFByb21wdCBmb3IgdGhlIHNwZWNpZmljIGZsYWdzIHRoYXQgd2VyZSBub3QgcHJvdmlkZWQKCQkJCQkJLy8geWV0LCBiYXNlZCBvbiBuYW1lLgoJCQkJCQlyZXR1cm4gISBpc3NldCggJGFzc29jX2FyZ3NbICRzcGVjX2FyZ1snbmFtZSddIF0gKTsKCQkJCX0KCQkJfQoJCSk7CgoJCSRzcGVjID0gYXJyYXlfdmFsdWVzKCAkc3BlYyApOwoKCQkkcHJvbXB0X2FyZ3MgPSBXUF9DTEk6OmdldF9jb25maWcoICdwcm9tcHQnICk7CgkJaWYgKCB0cnVlICE9PSAkcHJvbXB0X2FyZ3MgKSB7CgkJCSRwcm9tcHRfYXJncyA9IGV4cGxvZGUoICcsJywgJHByb21wdF9hcmdzICk7CgkJfQoKCQkvLyAncG9zaXRpb25hbCcgYXJndW1lbnRzIGFyZSBwb3NpdGlvbmFsIChha2EgemVyby1pbmRleGVkKQoJCS8vIHNvICRhcmdzIG5lZWRzIHRvIGJlIHJlc2V0IGJlZm9yZSBwcm9tcHRpbmcgZm9yIG5ldyBhcmd1bWVudHMKCQkkYXJncyA9IFtdOwoKCQlmb3JlYWNoICggJHNwZWMgYXMgJGtleSA9PiAkc3BlY19hcmcgKSB7CgoJCQkvLyBXaGVuIHByb21wdGluZyBmb3Igc3BlY2lmaWMgYXJndW1lbnRzIChlLmcuIC0tcHJvbXB0PXVzZXJfcGFzcyksCgkJCS8vIGlnbm9yZSBhbGwgYXJndW1lbnRzIHRoYXQgZG9uJ3QgbWF0Y2guCgkJCWlmICggaXNfYXJyYXkoICRwcm9tcHRfYXJncyApICkgewoJCQkJaWYgKCAnYXNzb2MnICE9PSAkc3BlY19hcmdbJ3R5cGUnXSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWlmICggISBpbl9hcnJheSggJHNwZWNfYXJnWyduYW1lJ10sICRwcm9tcHRfYXJncywgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQl9CgoJCQkkY3VycmVudF9wcm9tcHQgPSAoICRrZXkgKyAxICkgLiAnLycgLiBjb3VudCggJHNwZWMgKSAuICcgJzsKCQkJJGRlZmF1bHQgICAgICAgID0gJHNwZWNfYXJnWydvcHRpb25hbCddID8gJycgOiBmYWxzZTsKCgkJCS8vICdnZW5lcmljJyBwZXJtaXRzIGFyYml0cmFyeSBrZXk9dmFsdWUgKGUuZy4gWy0tPGZpZWxkPj08dmFsdWU+XSApCgkJCWlmICggJ2dlbmVyaWMnID09PSAkc3BlY19hcmdbJ3R5cGUnXSApIHsKCgkJCQlsaXN0KCAka2V5X3Rva2VuLCAkdmFsdWVfdG9rZW4gKSA9IGV4cGxvZGUoICc9JywgJHNwZWNfYXJnWyd0b2tlbiddICk7CgoJCQkJJHJlcGVhdCA9IGZhbHNlOwoJCQkJZG8gewoJCQkJCWlmICggISAkcmVwZWF0ICkgewoJCQkJCQkka2V5X3Byb21wdCA9ICRjdXJyZW50X3Byb21wdCAuICRrZXlfdG9rZW47CgkJCQkJfSBlbHNlIHsKCQkJCQkJJGtleV9wcm9tcHQgPSBzdHJfcmVwZWF0KCAnICcsIHN0cmxlbiggJGN1cnJlbnRfcHJvbXB0ICkgKSAuICRrZXlfdG9rZW47CgkJCQkJfQoKCQkJCQkka2V5ID0gJHRoaXMtPnByb21wdCggJGtleV9wcm9tcHQsICRkZWZhdWx0ICk7CgkJCQkJaWYgKCBmYWxzZSA9PT0gJGtleSApIHsKCQkJCQkJcmV0dXJuIFsgJGFyZ3MsICRhc3NvY19hcmdzIF07CgkJCQkJfQoKCQkJCQlpZiAoICRrZXkgKSB7CgkJCQkJCSRrZXlfcHJvbXB0X2NvdW50ID0gc3RybGVuKCAka2V5X3Byb21wdCApIC0gc3RybGVuKCAkdmFsdWVfdG9rZW4gKSAtIDE7CgkJCQkJCSR2YWx1ZV9wcm9tcHQgICAgID0gc3RyX3JlcGVhdCggJyAnLCAka2V5X3Byb21wdF9jb3VudCApIC4gJz0nIC4gJHZhbHVlX3Rva2VuOwoKCQkJCQkJJHZhbHVlID0gJHRoaXMtPnByb21wdCggJHZhbHVlX3Byb21wdCwgJGRlZmF1bHQgKTsKCQkJCQkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQkJCQkJcmV0dXJuIFsgJGFyZ3MsICRhc3NvY19hcmdzIF07CgkJCQkJCX0KCgkJCQkJCSRhc3NvY19hcmdzWyAka2V5IF0gPSAkdmFsdWU7CgoJCQkJCQkkcmVwZWF0ID0gdHJ1ZTsKCQkJCQl9IGVsc2UgewoJCQkJCQkkcmVwZWF0ID0gZmFsc2U7CgkJCQkJfQoJCQkJfSB3aGlsZSAoICRyZXBlYXQgKTsKCgkJCX0gZWxzZSB7CgkJCQkkcHJvbXB0ID0gJGN1cnJlbnRfcHJvbXB0IC4gJHNwZWNfYXJnWyd0b2tlbiddOwoJCQkJaWYgKCAnZmxhZycgPT09ICRzcGVjX2FyZ1sndHlwZSddICkgewoJCQkJCSRwcm9tcHQgLj0gJyAoWS9uKSc7CgkJCQl9CgoJCQkJJHJlc3BvbnNlID0gJHRoaXMtPnByb21wdCggJHByb21wdCwgJGRlZmF1bHQgKTsKCQkJCWlmICggZmFsc2UgPT09ICRyZXNwb25zZSApIHsKCQkJCQlyZXR1cm4gWyAkYXJncywgJGFzc29jX2FyZ3MgXTsKCQkJCX0KCgkJCQlpZiAoICRyZXNwb25zZSApIHsKCQkJCQlzd2l0Y2ggKCAkc3BlY19hcmdbJ3R5cGUnXSApIHsKCQkJCQkJY2FzZSAncG9zaXRpb25hbCc6CgkJCQkJCQlpZiAoICRzcGVjX2FyZ1sncmVwZWF0aW5nJ10gKSB7CgkJCQkJCQkJJHJlc3BvbnNlID0gZXhwbG9kZSggJyAnLCAkcmVzcG9uc2UgKTsKCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJJHJlc3BvbnNlID0gWyAkcmVzcG9uc2UgXTsKCQkJCQkJCX0KCQkJCQkJCSRhcmdzID0gYXJyYXlfbWVyZ2UoICRhcmdzLCAkcmVzcG9uc2UgKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdhc3NvYyc6CgkJCQkJCQkkYXNzb2NfYXJnc1sgJHNwZWNfYXJnWyduYW1lJ10gXSA9ICRyZXNwb25zZTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdmbGFnJzoKCQkJCQkJCWlmICggJ1knID09PSBzdHJ0b3VwcGVyKCAkcmVzcG9uc2UgKSApIHsKCQkJCQkJCQkkYXNzb2NfYXJnc1sgJHNwZWNfYXJnWyduYW1lJ10gXSA9IHRydWU7CgkJCQkJCQl9CgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBbICRhcmdzLCAkYXNzb2NfYXJncyBdOwoJfQoKCS8qKgoJICogVmFsaWRhdGUgdGhlIHN1cHBsaWVkIGFyZ3VtZW50cyB0byB0aGUgY29tbWFuZC4KCSAqIFRocm93cyB3YXJuaW5ncyBvciBlcnJvcnMgaWYgYXJndW1lbnRzIGFyZSBtaXNzaW5nCgkgKiBvciBpbnZhbGlkLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncwoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGV4dHJhX2FyZ3MKCSAqIEByZXR1cm4gYXJyYXkgbGlzdCBvZiBpbnZhbGlkICRhc3NvY19hcmdzIGtleXMgdG8gdW5zZXQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZV9hcmdzKCAkYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzICkgewoJCSRzeW5vcHNpcyA9ICR0aGlzLT5nZXRfc3lub3BzaXMoKTsKCQlpZiAoICEgJHN5bm9wc2lzICkgewoJCQlyZXR1cm4gWyBbXSwgJGFyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyBdOwoJCX0KCgkJJHZhbGlkYXRvciA9IG5ldyBTeW5vcHNpc1ZhbGlkYXRvciggJHN5bm9wc2lzICk7CgoJCSRjbWRfcGF0aCA9IGltcGxvZGUoICcgJywgZ2V0X3BhdGgoICR0aGlzICkgKTsKCQlmb3JlYWNoICggJHZhbGlkYXRvci0+Z2V0X3Vua25vd24oKSBhcyAkdG9rZW4gKSB7CgkJCVxXUF9DTEk6Ondhcm5pbmcoCgkJCQlzcHJpbnRmKAoJCQkJCSdUaGUgYCVzYCBjb21tYW5kIGhhcyBhbiBpbnZhbGlkIHN5bm9wc2lzIHBhcnQ6ICVzJywKCQkJCQkkY21kX3BhdGgsCgkJCQkJJHRva2VuCgkJCQkpCgkJCSk7CgkJfQoKCQlpZiAoICEgJHZhbGlkYXRvci0+ZW5vdWdoX3Bvc2l0aW9uYWxzKCAkYXJncyApICkgewoJCQkkdGhpcy0+c2hvd191c2FnZSgpOwoJCQlleGl0KCAxICk7CgkJfQoKCQkkdW5rbm93bl9wb3NpdGlvbmFscyA9ICR2YWxpZGF0b3ItPnVua25vd25fcG9zaXRpb25hbHMoICRhcmdzICk7CgkJaWYgKCAhIGVtcHR5KCAkdW5rbm93bl9wb3NpdGlvbmFscyApICkgewoJCQlcV1BfQ0xJOjplcnJvcigKCQkJCSdUb28gbWFueSBwb3NpdGlvbmFsIGFyZ3VtZW50czogJyAuCgkJCQlpbXBsb2RlKCAnICcsICR1bmtub3duX3Bvc2l0aW9uYWxzICkKCQkJKTsKCQl9CgoJCSRzeW5vcHNpc19zcGVjID0gU3lub3BzaXNQYXJzZXI6OnBhcnNlKCAkc3lub3BzaXMgKTsKCQkkaSAgICAgICAgICAgICA9IDA7CgkJJGVycm9ycyAgICAgICAgPSBbCgkJCSdmYXRhbCcgICA9PiBbXSwKCQkJJ3dhcm5pbmcnID0+IFtdLAoJCV07CgkJJG1vY2tfZG9jICAgICAgPSBbICR0aGlzLT5nZXRfc2hvcnRkZXNjKCksICcnIF07CgkJJG1vY2tfZG9jICAgICAgPSBhcnJheV9tZXJnZSggJG1vY2tfZG9jLCBleHBsb2RlKCAiXG4iLCAkdGhpcy0+Z2V0X2xvbmdkZXNjKCkgKSApOwoJCSRtb2NrX2RvYyAgICAgID0gJy8qKicgLiBQSFBfRU9MIC4gJyogJyAuIGltcGxvZGUoIFBIUF9FT0wgLiAnKiAnLCAkbW9ja19kb2MgKSAuIFBIUF9FT0wgLiAnKi8nOwoJCSRkb2NwYXJzZXIgICAgID0gbmV3IERvY1BhcnNlciggJG1vY2tfZG9jICk7CgkJZm9yZWFjaCAoICRzeW5vcHNpc19zcGVjIGFzICRzcGVjICkgewoJCQlpZiAoICdwb3NpdGlvbmFsJyA9PT0gJHNwZWNbJ3R5cGUnXSApIHsKCQkJCSRzcGVjX2FyZ3MgPSAkZG9jcGFyc2VyLT5nZXRfYXJnX2FyZ3MoICRzcGVjWyduYW1lJ10gKTsKCQkJCWlmICggISBpc3NldCggJGFyZ3NbICRpIF0gKSApIHsKCQkJCQlpZiAoIGlzc2V0KCAkc3BlY19hcmdzWydkZWZhdWx0J10gKSApIHsKCQkJCQkJJGFyZ3NbICRpIF0gPSAkc3BlY19hcmdzWydkZWZhdWx0J107CgkJCQkJfQoJCQkJfQoJCQkJaWYgKCBpc3NldCggJHNwZWNfYXJnc1snb3B0aW9ucyddICkgKSB7CgkJCQkJaWYgKCAhIGVtcHR5KCAkc3BlY1sncmVwZWF0aW5nJ10gKSApIHsKCQkJCQkJZG8gewoJCQkJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuU3RyaWN0SW5BcnJheS5NaXNzaW5nVHJ1ZVN0cmljdCAtLSBUaGlzIGlzIGEgbG9vc2UgY29tcGFyaXNvbiBieSBkZXNpZ24uCgkJCQkJCQlpZiAoIGlzc2V0KCAkYXJnc1sgJGkgXSApICYmICEgaW5fYXJyYXkoICRhcmdzWyAkaSBdLCAkc3BlY19hcmdzWydvcHRpb25zJ10gKSApIHsKCQkJCQkJCQlcV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgdmFsdWUgc3BlY2lmaWVkIGZvciBwb3NpdGlvbmFsIGFyZy4nICk7CgkJCQkJCQl9CgkJCQkJCQkkaSsrOwoJCQkJCQl9IHdoaWxlICggaXNzZXQoICRhcmdzWyAkaSBdICkgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RJbkFycmF5Lk1pc3NpbmdUcnVlU3RyaWN0IC0tIFRoaXMgaXMgYSBsb29zZSBjb21wYXJpc29uIGJ5IGRlc2lnbi4KCQkJCQkJaWYgKCBpc3NldCggJGFyZ3NbICRpIF0gKSAmJiAhIGluX2FycmF5KCAkYXJnc1sgJGkgXSwgJHNwZWNfYXJnc1snb3B0aW9ucyddICkgKSB7CgkJCQkJCQlcV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgdmFsdWUgc3BlY2lmaWVkIGZvciBwb3NpdGlvbmFsIGFyZy4nICk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQkkaSsrOwoJCQl9IGVsc2VpZiAoICdhc3NvYycgPT09ICRzcGVjWyd0eXBlJ10gKSB7CgkJCQkkc3BlY19hcmdzID0gJGRvY3BhcnNlci0+Z2V0X3BhcmFtX2FyZ3MoICRzcGVjWyduYW1lJ10gKTsKCQkJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbICRzcGVjWyduYW1lJ10gXSApICYmICEgaXNzZXQoICRleHRyYV9hcmdzWyAkc3BlY1snbmFtZSddIF0gKSApIHsKCQkJCQlpZiAoIGlzc2V0KCAkc3BlY19hcmdzWydkZWZhdWx0J10gKSApIHsKCQkJCQkJJGFzc29jX2FyZ3NbICRzcGVjWyduYW1lJ10gXSA9ICRzcGVjX2FyZ3NbJ2RlZmF1bHQnXTsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJHNwZWNbJ25hbWUnXSBdICkgJiYgaXNzZXQoICRzcGVjX2FyZ3NbJ29wdGlvbnMnXSApICkgewoJCQkJCSR2YWx1ZSAgID0gJGFzc29jX2FyZ3NbICRzcGVjWyduYW1lJ10gXTsKCQkJCQkkb3B0aW9ucyA9ICRzcGVjX2FyZ3NbJ29wdGlvbnMnXTsKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RJbkFycmF5Lk1pc3NpbmdUcnVlU3RyaWN0IC0tIFRoaXMgaXMgYSBsb29zZSBjb21wYXJpc29uIGJ5IGRlc2lnbi4KCQkJCQlpZiAoICEgaW5fYXJyYXkoICR2YWx1ZSwgJG9wdGlvbnMgKSApIHsKCQkJCQkJLy8gVHJ5IHdoZXRoZXIgaXQgbWlnaHQgYmUgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBtdWx0aXBsZSB2YWx1ZXMuCgkJCQkJCSR2YWx1ZXMgPSBhcnJheV9tYXAoICd0cmltJywgZXhwbG9kZSggJywnLCAkdmFsdWUgKSApOwoJCQkJCQkkY291bnQgID0gY291bnQoICR2YWx1ZXMgKTsKCQkJCQkJaWYgKAoJCQkJCQkJJGNvdW50ID4gMQoJCQkJCQkJJiYKCQkJCQkJCWNvdW50KAoJCQkJCQkJCWFycmF5X2ZpbHRlcigKCQkJCQkJCQkJJHZhbHVlcywKCQkJCQkJCQkJc3RhdGljIGZ1bmN0aW9uICggJHZhbHVlICkgdXNlICggJG9wdGlvbnMgKSB7CgkJCQkJCQkJCQlyZXR1cm4gaW5fYXJyYXkoICR2YWx1ZSwgJG9wdGlvbnMsIHRydWUgKTsKCQkJCQkJCQkJfQoJCQkJCQkJCSkKCQkJCQkJCSkgPT09ICRjb3VudAoJCQkJCQkpIHsKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQl9CgkJCQkJCSRlcnJvcnNbJ2ZhdGFsJ11bICRzcGVjWyduYW1lJ10gXSA9ICJJbnZhbGlkIHZhbHVlIHNwZWNpZmllZCBmb3IgJ3skc3BlY1snbmFtZSddfSciOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJbGlzdCggJHJldHVybmVkX2Vycm9ycywgJHRvX3Vuc2V0ICkgPSAkdmFsaWRhdG9yLT52YWxpZGF0ZV9hc3NvYygKCQkJYXJyYXlfbWVyZ2UoIFxXUF9DTEk6OmdldF9jb25maWcoKSwgJGV4dHJhX2FyZ3MsICRhc3NvY19hcmdzICkKCQkpOwoJCWZvcmVhY2ggKCBbICdmYXRhbCcsICd3YXJuaW5nJyBdIGFzICRlcnJvcl90eXBlICkgewoJCQkkZXJyb3JzWyAkZXJyb3JfdHlwZSBdID0gYXJyYXlfbWVyZ2UoICRlcnJvcnNbICRlcnJvcl90eXBlIF0sICRyZXR1cm5lZF9lcnJvcnNbICRlcnJvcl90eXBlIF0gKTsKCQl9CgoJCWlmICggJ2hlbHAnICE9PSAkdGhpcy0+bmFtZSApIHsKCQkJZm9yZWFjaCAoICR2YWxpZGF0b3ItPnVua25vd25fYXNzb2MoICRhc3NvY19hcmdzICkgYXMgJGtleSApIHsKCQkJCSRzdWdnZXN0aW9uICAgID0gVXRpbHNcZ2V0X3N1Z2dlc3Rpb24oCgkJCQkJJGtleSwKCQkJCQkkdGhpcy0+Z2V0X3BhcmFtZXRlcnMoICRzeW5vcHNpc19zcGVjICksCgkJCQkJJHRocmVzaG9sZCA9IDIKCQkJCSk7CgoJCQkJJGVycm9yc1snZmF0YWwnXVtdID0gc3ByaW50ZigKCQkJCQkndW5rbm93biAtLSVzIHBhcmFtZXRlciVzJywKCQkJCQkka2V5LAoJCQkJCSEgZW1wdHkoICRzdWdnZXN0aW9uICkgPyBQSFBfRU9MIC4gIkRpZCB5b3UgbWVhbiAnLS17JHN1Z2dlc3Rpb259Jz8iIDogJycKCQkJCSk7CgkJCX0KCQl9CgoJCWlmICggISBlbXB0eSggJGVycm9yc1snZmF0YWwnXSApICkgewoJCQkkb3V0ID0gJ1BhcmFtZXRlciBlcnJvcnM6JzsKCQkJZm9yZWFjaCAoICRlcnJvcnNbJ2ZhdGFsJ10gYXMgJGtleSA9PiAkZXJyb3IgKSB7CgkJCQkkb3V0IC49ICJcbiB7JGVycm9yfSI7CgkJCQkkZGVzYyA9ICRkb2NwYXJzZXItPmdldF9wYXJhbV9kZXNjKCAka2V5ICk7CgkJCQlpZiAoICcnICE9PSAkZGVzYyApIHsKCQkJCQkkb3V0IC49ICIgKHskZGVzY30pIjsKCQkJCX0KCQkJfQoKCQkJXFdQX0NMSTo6ZXJyb3IoICRvdXQgKTsKCQl9CgoJCWFycmF5X21hcCggJ1xcV1BfQ0xJOjp3YXJuaW5nJywgJGVycm9yc1snd2FybmluZyddICk7CgoJCXJldHVybiBbICR0b191bnNldCwgJGFyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyBdOwoJfQoKCS8qKgoJICogSW52b2tlIHRoZSBzdWJjb21tYW5kIHdpdGggdGhlIHN1cHBsaWVkIGFyZ3VtZW50cy4KCSAqIEdpdmVuIGEgLS1wcm9tcHQgYXJndW1lbnQsIGludGVyYWN0aXZlbHkgcmVxdWVzdCBpbnB1dAoJICogZnJvbSB0aGUgZW5kIHVzZXIuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyApIHsKCQlzdGF0aWMgJHByb21wdGVkX29uY2UgPSBmYWxzZTsKCgkJaWYgKCAnaGVscCcgIT09ICR0aGlzLT5uYW1lICkgewoJCQlpZiAoIFxXUF9DTEk6OmdldF9jb25maWcoICdwcm9tcHQnICkgJiYgISAkcHJvbXB0ZWRfb25jZSApIHsKCQkJCWxpc3QoICRfYXJncywgJGFzc29jX2FyZ3MgKSA9ICR0aGlzLT5wcm9tcHRfYXJncyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJCQkkYXJncyAgICAgICAgICAgICAgICAgICAgICAgPSBhcnJheV9tZXJnZSggJGFyZ3MsICRfYXJncyApOwoJCQkJJHByb21wdGVkX29uY2UgICAgICAgICAgICAgID0gdHJ1ZTsKCQkJfQoJCX0KCgkJJGV4dHJhX3Bvc2l0aW9uYWxzID0gW107CgkJZm9yZWFjaCAoICRleHRyYV9hcmdzIGFzICRrID0+ICR2ICkgewoJCQlpZiAoIGlzX251bWVyaWMoICRrICkgKSB7CgkJCQlpZiAoICEgaXNzZXQoICRhcmdzWyAkayBdICkgKSB7CgkJCQkJJGV4dHJhX3Bvc2l0aW9uYWxzWyAkayBdID0gJHY7CgkJCQl9CgkJCQl1bnNldCggJGV4dHJhX2FyZ3NbICRrIF0gKTsKCQkJfQoJCX0KCQkkYXJncyArPSAkZXh0cmFfcG9zaXRpb25hbHM7CgoJCWxpc3QoICR0b191bnNldCwgJGFyZ3MsICRhc3NvY19hcmdzLCAkZXh0cmFfYXJncyApID0gJHRoaXMtPnZhbGlkYXRlX2FyZ3MoICRhcmdzLCAkYXNzb2NfYXJncywgJGV4dHJhX2FyZ3MgKTsKCgkJZm9yZWFjaCAoICR0b191bnNldCBhcyAka2V5ICkgewoJCQl1bnNldCggJGFzc29jX2FyZ3NbICRrZXkgXSApOwoJCX0KCgkJJHBhdGggICA9IGdldF9wYXRoKCAkdGhpcy0+Z2V0X3BhcmVudCgpICk7CgkJJHBhcmVudCA9IGltcGxvZGUoICcgJywgYXJyYXlfc2xpY2UoICRwYXRoLCAxICkgKTsKCQkkY21kICAgID0gJHRoaXMtPm5hbWU7CgkJaWYgKCAkcGFyZW50ICkgewoJCQlXUF9DTEk6OmRvX2hvb2soICJiZWZvcmVfaW52b2tlOnskcGFyZW50fSIgKTsKCQkJJGNtZCA9ICRwYXJlbnQgLiAnICcgLiAkY21kOwoJCX0KCQlXUF9DTEk6OmRvX2hvb2soICJiZWZvcmVfaW52b2tlOnskY21kfSIgKTsKCgkJLy8gQ2hlY2sgaWYgYC0tcHJvbXB0YCBhcmcgcGFzc2VkIG9yIG5vdC4KCQlpZiAoICRwcm9tcHRlZF9vbmNlICkgewoJCQkvLyBVbnNldCBlbXB0eSBhcmdzLgoJCQkkYWN0dWFsX2FyZ3MgPSAkYXNzb2NfYXJnczsKCQkJZm9yZWFjaCAoICRhY3R1YWxfYXJncyBhcyAka2V5ICkgewoJCQkJaWYgKCBlbXB0eSggJGFjdHVhbF9hcmdzWyAka2V5IF0gKSApIHsKCQkJCQl1bnNldCggJGFjdHVhbF9hcmdzWyAka2V5IF0gKTsKCQkJCX0KCQkJfQoKCQkJV1BfQ0xJOjpsb2coCgkJCQlzcHJpbnRmKAoJCQkJCSd3cCAlcyAlcycsCgkJCQkJJGNtZCwKCQkJCQlsdHJpbSggVXRpbHNcYXNzb2NfYXJnc190b19zdHIoICRhY3R1YWxfYXJncyApLCAnICcgKQoJCQkJKQoJCQkpOwoJCX0KCgkJY2FsbF91c2VyX2Z1bmMoICR0aGlzLT53aGVuX2ludm9rZWQsICRhcmdzLCBhcnJheV9tZXJnZSggJGV4dHJhX2FyZ3MsICRhc3NvY19hcmdzICkgKTsKCgkJaWYgKCAkcGFyZW50ICkgewoJCQlXUF9DTEk6OmRvX2hvb2soICJhZnRlcl9pbnZva2U6eyRwYXJlbnR9IiApOwoJCX0KCQlXUF9DTEk6OmRvX2hvb2soICJhZnRlcl9pbnZva2U6eyRjbWR9IiApOwoJfQoKCS8qKgoJICogR2V0IGFuIGFycmF5IG9mIHBhcmFtZXRlciBuYW1lcywgYnkgbWVyZ2luZyB0aGUgY29tbWFuZC1zcGVjaWZpYyBhbmQgdGhlCgkgKiBnbG9iYWwgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRzcGVjIE9wdGlvbmFsLiBTcGVjaWZpY2F0aW9uIG9mIHRoZSBjdXJyZW50IGNvbW1hbmQuCgkgKgoJICogQHJldHVybiBhcnJheSBBcnJheSBvZiBwYXJhbWV0ZXIgbmFtZXMKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcGFyYW1ldGVycyggJHNwZWMgPSBbXSApIHsKCQkkbG9jYWxfcGFyYW1ldGVycyAgPSBhcnJheV9jb2x1bW4oICRzcGVjLCAnbmFtZScgKTsKCQkkZ2xvYmFsX3BhcmFtZXRlcnMgPSBhcnJheV9jb2x1bW4oCgkJCVN5bm9wc2lzUGFyc2VyOjpwYXJzZSggJHRoaXMtPmdldF9nbG9iYWxfcGFyYW1zKCkgKSwKCQkJJ25hbWUnCgkJKTsKCgkJcmV0dXJuIGFycmF5X3VuaXF1ZSggYXJyYXlfbWVyZ2UoICRsb2NhbF9wYXJhbWV0ZXJzLCAkZ2xvYmFsX3BhcmFtZXRlcnMgKSApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIGNsaVxDb2xvcnM7CnVzZSBjbGlcVGFibGU7CnVzZSBJdGVyYXRvcjsKdXNlIE11c3Rhbmdvc3RhbmdcU3B5YzsKdXNlIFdQX0NMSTsKCi8qKgogKiBPdXRwdXQgb25lIG9yIG1vcmUgaXRlbXMgaW4gYSBnaXZlbiBmb3JtYXQgKGUuZy4gdGFibGUsIEpTT04pLgogKi8KY2xhc3MgRm9ybWF0dGVyIHsKCgkvKioKCSAqIEhvdyB0aGUgaXRlbXMgc2hvdWxkIGJlIG91dHB1dC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGFyZ3M7CgoJLyoqCgkgKiBTdGFuZGFyZCBwcmVmaXggZm9yIG9iamVjdCBmaWVsZHMuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJpdmF0ZSAkcHJlZml4OwoKCS8qKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIE91dHB1dCBmb3JtYXQgYXJndW1lbnRzLgoJICogQHBhcmFtIGFycmF5ICRmaWVsZHMgRmllbGRzIHRvIGRpc3BsYXkgb2YgZWFjaCBpdGVtLgoJICogQHBhcmFtIHN0cmluZ3xib29sICRwcmVmaXggQ2hlY2sgaWYgZmllbGRzIGhhdmUgYSBzdGFuZGFyZCBwcmVmaXguCgkgKiBGYWxzZSBpbmRpY2F0ZXMgZW1wdHkgcHJlZml4LgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICYkYXNzb2NfYXJncywgJGZpZWxkcyA9IG51bGwsICRwcmVmaXggPSBmYWxzZSApIHsKCQkkZm9ybWF0X2FyZ3MgPSBbCgkJCSdmb3JtYXQnID0+ICd0YWJsZScsCgkJCSdmaWVsZHMnID0+ICRmaWVsZHMsCgkJCSdmaWVsZCcgID0+IG51bGwsCgkJXTsKCgkJZm9yZWFjaCAoIFsgJ2Zvcm1hdCcsICdmaWVsZHMnLCAnZmllbGQnIF0gYXMgJGtleSApIHsKCQkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbICRrZXkgXSApICkgewoJCQkJJGZvcm1hdF9hcmdzWyAka2V5IF0gPSAkYXNzb2NfYXJnc1sgJGtleSBdOwoJCQkJdW5zZXQoICRhc3NvY19hcmdzWyAka2V5IF0gKTsKCQkJfQoJCX0KCgkJaWYgKCAhIGlzX2FycmF5KCAkZm9ybWF0X2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRmb3JtYXRfYXJnc1snZmllbGRzJ10gPSBleHBsb2RlKCAnLCcsICRmb3JtYXRfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCSRmb3JtYXRfYXJnc1snZmllbGRzJ10gPSBhcnJheV9tYXAoICd0cmltJywgJGZvcm1hdF9hcmdzWydmaWVsZHMnXSApOwoKCQkkdGhpcy0+YXJncyAgID0gJGZvcm1hdF9hcmdzOwoJCSR0aGlzLT5wcmVmaXggPSAkcHJlZml4OwoJfQoKCS8qKgoJICogTWFnaWMgZ2V0dGVyIGZvciBhcmd1bWVudHMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCggJGtleSApIHsKCQlyZXR1cm4gJHRoaXMtPmFyZ3NbICRrZXkgXTsKCX0KCgkvKioKCSAqIERpc3BsYXkgbXVsdGlwbGUgaXRlbXMgYWNjb3JkaW5nIHRvIHRoZSBvdXRwdXQgYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBhcnJheXxJdGVyYXRvciAkaXRlbXMgVGhlIGl0ZW1zIHRvIGRpc3BsYXkuCgkgKiBAcGFyYW0gYm9vbHxhcnJheSAgICAgICRhc2NpaV9wcmVfY29sb3JpemVkIE9wdGlvbmFsLiBBIGJvb2xlYW4gb3IgYW4gYXJyYXkgb2YgYm9vbGVhbnMgdG8gcGFzcyB0byBgZm9ybWF0KClgIGlmIGl0ZW1zIGluIHRoZSB0YWJsZSBhcmUgcHJlLWNvbG9yaXplZC4gRGVmYXVsdCBmYWxzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BsYXlfaXRlbXMoICRpdGVtcywgJGFzY2lpX3ByZV9jb2xvcml6ZWQgPSBmYWxzZSApIHsKCQlpZiAoICR0aGlzLT5hcmdzWydmaWVsZCddICkgewoJCQkkdGhpcy0+c2hvd19zaW5nbGVfZmllbGQoICRpdGVtcywgJHRoaXMtPmFyZ3NbJ2ZpZWxkJ10gKTsKCQl9IGVsc2UgewoJCQlpZiAoIGluX2FycmF5KCAkdGhpcy0+YXJnc1snZm9ybWF0J10sIFsgJ2NzdicsICdqc29uJywgJ3RhYmxlJyBdLCB0cnVlICkgKSB7CgkJCQkkaXRlbSA9IGlzX2FycmF5KCAkaXRlbXMgKSAmJiAhIGVtcHR5KCAkaXRlbXMgKSA/IGFycmF5X3NoaWZ0KCAkaXRlbXMgKSA6IGZhbHNlOwoJCQkJaWYgKCAkaXRlbSAmJiAhIGVtcHR5KCAkdGhpcy0+YXJnc1snZmllbGRzJ10gKSApIHsKCQkJCQlmb3JlYWNoICggJHRoaXMtPmFyZ3NbJ2ZpZWxkcyddIGFzICYkZmllbGQgKSB7CgkJCQkJCSRmaWVsZCA9ICR0aGlzLT5maW5kX2l0ZW1fa2V5KCAkaXRlbSwgJGZpZWxkICk7CgkJCQkJfQoJCQkJCWFycmF5X3Vuc2hpZnQoICRpdGVtcywgJGl0ZW0gKTsKCQkJCX0KCQkJfQoKCQkJaWYgKCBpbl9hcnJheSggJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLCBbICd0YWJsZScsICdjc3YnIF0sIHRydWUgKSApIHsKCQkJCWlmICggJGl0ZW1zIGluc3RhbmNlb2YgSXRlcmF0b3IgKSB7CgkJCQkJJGl0ZW1zID0gVXRpbHNcaXRlcmF0b3JfbWFwKCAkaXRlbXMsIFsgJHRoaXMsICd0cmFuc2Zvcm1faXRlbV92YWx1ZXNfdG9fanNvbicgXSApOwoJCQkJfSBlbHNlIHsKCQkJCQkkaXRlbXMgPSBhcnJheV9tYXAoIFsgJHRoaXMsICd0cmFuc2Zvcm1faXRlbV92YWx1ZXNfdG9fanNvbicgXSwgJGl0ZW1zICk7CgkJCQl9CgkJCX0KCgkJCSR0aGlzLT5mb3JtYXQoICRpdGVtcywgJGFzY2lpX3ByZV9jb2xvcml6ZWQgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEaXNwbGF5IGEgc2luZ2xlIGl0ZW0gYWNjb3JkaW5nIHRvIHRoZSBvdXRwdXQgYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAgICAgICRpdGVtCgkgKiBAcGFyYW0gYm9vbHxhcnJheSAkYXNjaWlfcHJlX2NvbG9yaXplZCBPcHRpb25hbC4gQSBib29sZWFuIG9yIGFuIGFycmF5IG9mIGJvb2xlYW5zIHRvIHBhc3MgdG8gYHNob3dfbXVsdGlwbGVfZmllbGRzKClgIGlmIHRoZSBpdGVtIGluIHRoZSB0YWJsZSBpcyBwcmUtY29sb3JpemVkLiBEZWZhdWx0IGZhbHNlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGlzcGxheV9pdGVtKCAkaXRlbSwgJGFzY2lpX3ByZV9jb2xvcml6ZWQgPSBmYWxzZSApIHsKCQlpZiAoIGlzc2V0KCAkdGhpcy0+YXJnc1snZmllbGQnXSApICkgewoJCQkkaXRlbSAgPSAob2JqZWN0KSAkaXRlbTsKCQkJJGtleSAgID0gJHRoaXMtPmZpbmRfaXRlbV9rZXkoICRpdGVtLCAkdGhpcy0+YXJnc1snZmllbGQnXSApOwoJCQkkdmFsdWUgPSAkaXRlbS0+JGtleTsKCQkJaWYgKCBpbl9hcnJheSggJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLCBbICd0YWJsZScsICdjc3YnIF0sIHRydWUgKSAmJiAoIGlzX29iamVjdCggJHZhbHVlICkgfHwgaXNfYXJyYXkoICR2YWx1ZSApICkgKSB7CgkJCQkkdmFsdWUgPSBqc29uX2VuY29kZSggJHZhbHVlICk7CgkJCX0KCQkJV1BfQ0xJOjpwcmludF92YWx1ZSgKCQkJCSR2YWx1ZSwKCQkJCVsKCQkJCQknZm9ybWF0JyA9PiAkdGhpcy0+YXJnc1snZm9ybWF0J10sCgkJCQldCgkJCSk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPnNob3dfbXVsdGlwbGVfZmllbGRzKCAkaXRlbSwgJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLCAkYXNjaWlfcHJlX2NvbG9yaXplZCApOwoJCX0KCX0KCgkvKioKCSAqIEZvcm1hdCBpdGVtcyBhY2NvcmRpbmcgdG8gYXJndW1lbnRzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgICAgICRpdGVtcwoJICogQHBhcmFtIGJvb2x8YXJyYXkgJGFzY2lpX3ByZV9jb2xvcml6ZWQgT3B0aW9uYWwuIEEgYm9vbGVhbiBvciBhbiBhcnJheSBvZiBib29sZWFucyB0byBwYXNzIHRvIGBzaG93X3RhYmxlKClgIGlmIGl0ZW1zIGluIHRoZSB0YWJsZSBhcmUgcHJlLWNvbG9yaXplZC4gRGVmYXVsdCBmYWxzZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBmb3JtYXQoICRpdGVtcywgJGFzY2lpX3ByZV9jb2xvcml6ZWQgPSBmYWxzZSApIHsKCQkkZmllbGRzID0gJHRoaXMtPmFyZ3NbJ2ZpZWxkcyddOwoKCQlzd2l0Y2ggKCAkdGhpcy0+YXJnc1snZm9ybWF0J10gKSB7CgkJCWNhc2UgJ2NvdW50JzoKCQkJCWlmICggISBpc19hcnJheSggJGl0ZW1zICkgKSB7CgkJCQkJJGl0ZW1zID0gaXRlcmF0b3JfdG9fYXJyYXkoICRpdGVtcyApOwoJCQkJfQoJCQkJZWNobyBjb3VudCggJGl0ZW1zICk7CgkJCQlicmVhazsKCgkJCWNhc2UgJ2lkcyc6CgkJCQlpZiAoICEgaXNfYXJyYXkoICRpdGVtcyApICkgewoJCQkJCSRpdGVtcyA9IGl0ZXJhdG9yX3RvX2FycmF5KCAkaXRlbXMgKTsKCQkJCX0KCQkJCWVjaG8gaW1wbG9kZSggJyAnLCAkaXRlbXMgKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSAndGFibGUnOgoJCQkJc2VsZjo6c2hvd190YWJsZSggJGl0ZW1zLCAkZmllbGRzLCAkYXNjaWlfcHJlX2NvbG9yaXplZCApOwoJCQkJYnJlYWs7CgoJCQljYXNlICdjc3YnOgoJCQkJVXRpbHNcd3JpdGVfY3N2KCBTVERPVVQsICRpdGVtcywgJGZpZWxkcyApOwoJCQkJYnJlYWs7CgoJCQljYXNlICdqc29uJzoKCQkJY2FzZSAneWFtbCc6CgkJCQkkb3V0ID0gW107CgkJCQlmb3JlYWNoICggJGl0ZW1zIGFzICRpdGVtICkgewoJCQkJCSRvdXRbXSA9IFV0aWxzXHBpY2tfZmllbGRzKCAkaXRlbSwgJGZpZWxkcyApOwoJCQkJfQoKCQkJCWlmICggJ2pzb24nID09PSAkdGhpcy0+YXJnc1snZm9ybWF0J10gKSB7CgkJCQkJaWYgKCBkZWZpbmVkKCAnSlNPTl9QQVJUSUFMX09VVFBVVF9PTl9FUlJPUicgKSApIHsKCQkJCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuQ29uc3RhbnRzLk5ld0NvbnN0YW50cy5qc29uX3BhcnRpYWxfb3V0cHV0X29uX2Vycm9yRm91bmQKCQkJCQkJZWNobyBqc29uX2VuY29kZSggJG91dCwgSlNPTl9QQVJUSUFMX09VVFBVVF9PTl9FUlJPUiApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWVjaG8ganNvbl9lbmNvZGUoICRvdXQgKTsKCQkJCQl9CgkJCQl9IGVsc2VpZiAoICd5YW1sJyA9PT0gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddICkgewoJCQkJCWVjaG8gU3B5Yzo6WUFNTER1bXAoICRvdXQsIDIsIDAgKTsKCQkJCX0KCQkJCWJyZWFrOwoKCQkJZGVmYXVsdDoKCQkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIGZvcm1hdDogJyAuICR0aGlzLT5hcmdzWydmb3JtYXQnXSApOwoJCX0KCX0KCgkvKioKCSAqIFNob3cgYSBzaW5nbGUgZmllbGQgZnJvbSBhIGxpc3Qgb2YgaXRlbXMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRpdGVtcyBBcnJheSBvZiBvYmplY3RzIHRvIHNob3cgZmllbGRzIGZyb20KCSAqIEBwYXJhbSBzdHJpbmcgJGZpZWxkIFRoZSBmaWVsZCB0byBzaG93CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2hvd19zaW5nbGVfZmllbGQoICRpdGVtcywgJGZpZWxkICkgewoJCSRrZXkgICAgPSBudWxsOwoJCSR2YWx1ZXMgPSBbXTsKCgkJZm9yZWFjaCAoICRpdGVtcyBhcyAkaXRlbSApIHsKCQkJJGl0ZW0gPSAob2JqZWN0KSAkaXRlbTsKCgkJCWlmICggbnVsbCA9PT0gJGtleSApIHsKCQkJCSRrZXkgPSAkdGhpcy0+ZmluZF9pdGVtX2tleSggJGl0ZW0sICRmaWVsZCApOwoJCQl9CgoJCQlpZiAoICdqc29uJyA9PT0gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddICkgewoJCQkJJHZhbHVlc1tdID0gJGl0ZW0tPiRrZXk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnByaW50X3ZhbHVlKAoJCQkJCSRpdGVtLT4ka2V5LAoJCQkJCVsKCQkJCQkJJ2Zvcm1hdCcgPT4gJHRoaXMtPmFyZ3NbJ2Zvcm1hdCddLAoJCQkJCV0KCQkJCSk7CgkJCX0KCQl9CgoJCWlmICggJ2pzb24nID09PSAkdGhpcy0+YXJnc1snZm9ybWF0J10gKSB7CgkJCWVjaG8ganNvbl9lbmNvZGUoICR2YWx1ZXMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBGaW5kIGFuIG9iamVjdCdzIGtleS4KCSAqIElmICRwcmVmaXggaXMgc2V0LCBhIGtleSB3aXRoIHRoYXQgcHJlZml4IHdpbGwgYmUgcHJpb3JpdGl6ZWQuCgkgKgoJICogQHBhcmFtIG9iamVjdCAkaXRlbQoJICogQHBhcmFtIHN0cmluZyAkZmllbGQKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZmluZF9pdGVtX2tleSggJGl0ZW0sICRmaWVsZCApIHsKCQlmb3JlYWNoICggWyAkZmllbGQsICR0aGlzLT5wcmVmaXggLiAnXycgLiAkZmllbGQgXSBhcyAkbWF5YmVfa2V5ICkgewoJCQlpZiAoICggaXNfb2JqZWN0KCAkaXRlbSApICYmICggcHJvcGVydHlfZXhpc3RzKCAkaXRlbSwgJG1heWJlX2tleSApIHx8IGlzc2V0KCAkaXRlbS0+JG1heWJlX2tleSApICkgKSB8fCAoIGlzX2FycmF5KCAkaXRlbSApICYmIGFycmF5X2tleV9leGlzdHMoICRtYXliZV9rZXksICRpdGVtICkgKSApIHsKCQkJCSRrZXkgPSAkbWF5YmVfa2V5OwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmICggISBpc3NldCggJGtleSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCBmaWVsZDogJGZpZWxkLiIgKTsKCQl9CgoJCXJldHVybiAka2V5OwoJfQoKCS8qKgoJICogU2hvdyBtdWx0aXBsZSBmaWVsZHMgb2YgYW4gb2JqZWN0LgoJICoKCSAqIEBwYXJhbSBvYmplY3R8YXJyYXkgJGRhdGEgICAgICAgICAgICAgICAgRGF0YSB0byBkaXNwbGF5CgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICRmb3JtYXQgICAgICAgICAgICAgIEZvcm1hdCB0byBkaXNwbGF5IHRoZSBkYXRhIGluCgkgKiBAcGFyYW0gYm9vbHxhcnJheSAgICRhc2NpaV9wcmVfY29sb3JpemVkIE9wdGlvbmFsLiBBIGJvb2xlYW4gb3IgYW4gYXJyYXkgb2YgYm9vbGVhbnMgdG8gcGFzcyB0byBgc2hvd190YWJsZSgpYCBpZiB0aGUgaXRlbSBpbiB0aGUgdGFibGUgaXMgcHJlLWNvbG9yaXplZC4gRGVmYXVsdCBmYWxzZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzaG93X211bHRpcGxlX2ZpZWxkcyggJGRhdGEsICRmb3JtYXQsICRhc2NpaV9wcmVfY29sb3JpemVkID0gZmFsc2UgKSB7CgoJCSR0cnVlX2ZpZWxkcyA9IFtdOwoJCWZvcmVhY2ggKCAkdGhpcy0+YXJnc1snZmllbGRzJ10gYXMgJGZpZWxkICkgewoJCQkkdHJ1ZV9maWVsZHNbXSA9ICR0aGlzLT5maW5kX2l0ZW1fa2V5KCAkZGF0YSwgJGZpZWxkICk7CgkJfQoKCQlmb3JlYWNoICggJGRhdGEgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCWlmICggISBpbl9hcnJheSggJGtleSwgJHRydWVfZmllbGRzLCB0cnVlICkgKSB7CgkJCQlpZiAoIGlzX2FycmF5KCAkZGF0YSApICkgewoJCQkJCXVuc2V0KCAkZGF0YVsgJGtleSBdICk7CgkJCQl9IGVsc2VpZiAoIGlzX29iamVjdCggJGRhdGEgKSApIHsKCQkJCQl1bnNldCggJGRhdGEtPiRrZXkgKTsKCQkJCX0KCQkJfQoJCX0KCgkJc3dpdGNoICggJGZvcm1hdCApIHsKCgkJCWNhc2UgJ3RhYmxlJzoKCQkJY2FzZSAnY3N2JzoKCQkJCSRyb3dzICAgPSAkdGhpcy0+YXNzb2NfYXJyYXlfdG9fcm93cyggJGRhdGEgKTsKCQkJCSRmaWVsZHMgPSBbICdGaWVsZCcsICdWYWx1ZScgXTsKCQkJCWlmICggJ3RhYmxlJyA9PT0gJGZvcm1hdCApIHsKCQkJCQlzZWxmOjpzaG93X3RhYmxlKCAkcm93cywgJGZpZWxkcywgJGFzY2lpX3ByZV9jb2xvcml6ZWQgKTsKCQkJCX0gZWxzZWlmICggJ2NzdicgPT09ICRmb3JtYXQgKSB7CgkJCQkJVXRpbHNcd3JpdGVfY3N2KCBTVERPVVQsICRyb3dzLCAkZmllbGRzICk7CgkJCQl9CgkJCQlicmVhazsKCgkJCWNhc2UgJ3lhbWwnOgoJCQljYXNlICdqc29uJzoKCQkJCVdQX0NMSTo6cHJpbnRfdmFsdWUoCgkJCQkJJGRhdGEsCgkJCQkJWwoJCQkJCQknZm9ybWF0JyA9PiAkZm9ybWF0LAoJCQkJCV0KCQkJCSk7CgkJCQlicmVhazsKCgkJCWRlZmF1bHQ6CgkJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBmb3JtYXQ6ICcgLiAkZm9ybWF0ICk7CgkJCQlicmVhazsKCgkJfQoKCX0KCgkvKioKCSAqIFNob3cgaXRlbXMgaW4gYSBcY2xpXFRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgICAgICRpdGVtcwoJICogQHBhcmFtIGFycmF5ICAgICAgJGZpZWxkcwoJICogQHBhcmFtIGJvb2x8YXJyYXkgJGFzY2lpX3ByZV9jb2xvcml6ZWQgT3B0aW9uYWwuIEEgYm9vbGVhbiBvciBhbiBhcnJheSBvZiBib29sZWFucyB0byBwYXNzIHRvIGBUYWJsZTo6c2V0QXNjaWlQcmVDb2xvcml6ZWQoKWAgaWYgaXRlbXMgaW4gdGhlIHRhYmxlIGFyZSBwcmUtY29sb3JpemVkLiBEZWZhdWx0IGZhbHNlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzaG93X3RhYmxlKCAkaXRlbXMsICRmaWVsZHMsICRhc2NpaV9wcmVfY29sb3JpemVkID0gZmFsc2UgKSB7CgkJJHRhYmxlID0gbmV3IFRhYmxlKCk7CgoJCSRlbmFibGVkID0gQ29sb3JzOjpzaG91bGRDb2xvcml6ZSgpOwoJCWlmICggJGVuYWJsZWQgKSB7CgkJCUNvbG9yczo6ZGlzYWJsZSggdHJ1ZSApOwoJCX0KCgkJJHRhYmxlLT5zZXRBc2NpaVByZUNvbG9yaXplZCggJGFzY2lpX3ByZV9jb2xvcml6ZWQgKTsKCQkkdGFibGUtPnNldEhlYWRlcnMoICRmaWVsZHMgKTsKCgkJZm9yZWFjaCAoICRpdGVtcyBhcyAkaXRlbSApIHsKCQkJJHRhYmxlLT5hZGRSb3coIGFycmF5X3ZhbHVlcyggVXRpbHNccGlja19maWVsZHMoICRpdGVtLCAkZmllbGRzICkgKSApOwoJCX0KCgkJZm9yZWFjaCAoICR0YWJsZS0+Z2V0RGlzcGxheUxpbmVzKCkgYXMgJGxpbmUgKSB7CgkJCVdQX0NMSTo6bGluZSggJGxpbmUgKTsKCQl9CgoJCWlmICggJGVuYWJsZWQgKSB7CgkJCUNvbG9yczo6ZW5hYmxlKCB0cnVlICk7CgkJfQoJfQoKCS8qKgoJICogRm9ybWF0IGFuIGFzc29jaWF0aXZlIGFycmF5IGFzIGEgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAgICAkZmllbGRzICAgIEZpZWxkcyBhbmQgdmFsdWVzIHRvIGZvcm1hdAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGFzc29jX2FycmF5X3RvX3Jvd3MoICRmaWVsZHMgKSB7CgkJJHJvd3MgPSBbXTsKCgkJZm9yZWFjaCAoICRmaWVsZHMgYXMgJGZpZWxkID0+ICR2YWx1ZSApIHsKCgkJCWlmICggISBpc19zdHJpbmcoICR2YWx1ZSApICkgewoJCQkJJHZhbHVlID0ganNvbl9lbmNvZGUoICR2YWx1ZSApOwoJCQl9CgoJCQkkcm93c1tdID0gKG9iamVjdCkgWwoJCQkJJ0ZpZWxkJyA9PiAkZmllbGQsCgkJCQknVmFsdWUnID0+ICR2YWx1ZSwKCQkJXTsKCQl9CgoJCXJldHVybiAkcm93czsKCX0KCgkvKioKCSAqIFRyYW5zZm9ybXMgb2JqZWN0cyBhbmQgYXJyYXlzIHRvIEpTT04gYXMgbmVjZXNzYXJ5CgkgKgoJICogQHBhcmFtIG1peGVkICRpdGVtCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0cmFuc2Zvcm1faXRlbV92YWx1ZXNfdG9fanNvbiggJGl0ZW0gKSB7CgkJZm9yZWFjaCAoICR0aGlzLT5hcmdzWydmaWVsZHMnXSBhcyAkZmllbGQgKSB7CgkJCSR0cnVlX2ZpZWxkID0gJHRoaXMtPmZpbmRfaXRlbV9rZXkoICRpdGVtLCAkZmllbGQgKTsKCQkJJHZhbHVlICAgICAgPSBpc19vYmplY3QoICRpdGVtICkgPyAkaXRlbS0+JHRydWVfZmllbGQgOiAkaXRlbVsgJHRydWVfZmllbGQgXTsKCQkJaWYgKCBpc19hcnJheSggJHZhbHVlICkgfHwgaXNfb2JqZWN0KCAkdmFsdWUgKSApIHsKCQkJCWlmICggaXNfb2JqZWN0KCAkaXRlbSApICkgewoJCQkJCSRpdGVtLT4kdHJ1ZV9maWVsZCA9IGpzb25fZW5jb2RlKCAkdmFsdWUgKTsKCQkJCX0gZWxzZWlmICggaXNfYXJyYXkoICRpdGVtICkgKSB7CgkJCQkJJGl0ZW1bICR0cnVlX2ZpZWxkIF0gPSBqc29uX2VuY29kZSggJHZhbHVlICk7CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuICRpdGVtOwoJfQoKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBSdW50aW1lRXhjZXB0aW9uOwoKLyoqCiAqIENsYXNzIFdwT3JnQXBpLgogKgogKiBUaGlzIGlzIGFuIGFic3RyYWN0aW9uIG9mIHRoZSBXb3JkUHJlc3Mub3JnIEFQSS4KICoKICogQHNlZSBodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvV29yZFByZXNzLm9yZ19BUEkKICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpmaW5hbCBjbGFzcyBXcE9yZ0FwaSB7CgoJLyoqCgkgKiBXb3JkUHJlc3Mub3JnIEFQSSByb290IFVSTC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBBUElfUk9PVCA9ICdodHRwczovL2FwaS53b3JkcHJlc3Mub3JnJzsKCgkvKioKCSAqIFdvcmRQcmVzcy5vcmcgQVBJIHJvb3QgVVJMLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IERPV05MT0FEU19ST09UID0gJ2h0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcnOwoKCS8qKgoJICogQ29yZSBjaGVja3N1bXMgZW5kcG9pbnQuCgkgKgoJICogQHNlZSBodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvV29yZFByZXNzLm9yZ19BUEkjQ2hlY2tzdW0KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBDT1JFX0NIRUNLU1VNU19FTkRQT0lOVCA9IHNlbGY6OkFQSV9ST09UIC4gJy9jb3JlL2NoZWNrc3Vtcy8xLjAvJzsKCgkvKioKCSAqIFBsdWdpbiBjaGVja3N1bXMgZW5kcG9pbnQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUExVR0lOX0NIRUNLU1VNU19FTkRQT0lOVCA9IHNlbGY6OkRPV05MT0FEU19ST09UIC4gJy9wbHVnaW4tY2hlY2tzdW1zLyc7CgoJLyoqCgkgKiBQbHVnaW4gaW5mbyBlbmRwb2ludC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBQTFVHSU5fSU5GT19FTkRQT0lOVCA9IHNlbGY6OkFQSV9ST09UIC4gJy9wbHVnaW5zL2luZm8vMS4yLyc7CgoJLyoqCgkgKiBUaGVtZSBpbmZvIGVuZHBvaW50LgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFRIRU1FX0lORk9fRU5EUE9JTlQgPSBzZWxmOjpBUElfUk9PVCAuICcvdGhlbWVzL2luZm8vMS4yLyc7CgoJLyoqCgkgKiBTYWx0IGVuZHBvaW50LgoJICoKCSAqIEBzZWUgaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1dvcmRQcmVzcy5vcmdfQVBJI1NlY3JldF9LZXkKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBTQUxUX0VORFBPSU5UID0gc2VsZjo6QVBJX1JPT1QgLiAnL3NlY3JldC1rZXkvMS4xL3NhbHQvJzsKCgkvKioKCSAqIFZlcnNpb24gY2hlY2sgZW5kcG9pbnQuCgkgKgoJICogQHNlZSBodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvV29yZFByZXNzLm9yZ19BUEkjVmVyc2lvbl9DaGVjawoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFZFUlNJT05fQ0hFQ0tfRU5EUE9JTlQgPSBzZWxmOjpBUElfUk9PVCAuICcvY29yZS92ZXJzaW9uLWNoZWNrLzEuNy8nOwoKCS8qKgoJICogT3B0aW9ucyB0byBwYXNzIG9udG8gdGhlIFJlcXVlc3RzIGxpYnJhcnkgZm9yIGV4ZWN1dGluZyB0aGUgcmVtb3RlIGNhbGxzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkb3B0aW9uczsKCgkvKioKCSAqIFdwT3JnQXBpIGNvbnN0cnVjdG9yLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBvcHRpb25zIHRvIHBhc3MgdG8gdGhlIEFQSSBhYnN0cmFjdGlvbi4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkb3B0aW9ucyA9IFtdICkgewoJCSR0aGlzLT5vcHRpb25zID0gJG9wdGlvbnM7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBjaGVja3N1bXMgZm9yIHRoZSBnaXZlbiB2ZXJzaW9uIG9mIFdvcmRQcmVzcyBjb3JlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gVmVyc2lvbiBzdHJpbmcgdG8gcXVlcnkuCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUgIE9wdGlvbmFsLiBMb2NhbGUgdG8gcXVlcnkuIERlZmF1bHRzIHRvICdlbl9VUycuCgkgKiBAcmV0dXJuIGJvb2x8YXJyYXkgRmFsc2Ugb24gZmFpbHVyZS4gQW4gYXJyYXkgb2YgY2hlY2tzdW1zIG9uIHN1Y2Nlc3MuCgkgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2NvcmVfY2hlY2tzdW1zKCAkdmVyc2lvbiwgJGxvY2FsZSA9ICdlbl9VUycgKSB7CgkJJHVybCA9IHNwcmludGYoCgkJCSclcz8lcycsCgkJCXNlbGY6OkNPUkVfQ0hFQ0tTVU1TX0VORFBPSU5ULAoJCQlodHRwX2J1aWxkX3F1ZXJ5KCBjb21wYWN0KCAndmVyc2lvbicsICdsb2NhbGUnICksIG51bGwsICcmJyApCgkJKTsKCgkJJHJlc3BvbnNlID0gJHRoaXMtPmpzb25fZ2V0X3JlcXVlc3QoICR1cmwgKTsKCgkJaWYgKAoJCQkhIGlzX2FycmF5KCAkcmVzcG9uc2UgKQoJCQl8fCAhIGlzc2V0KCAkcmVzcG9uc2VbJ2NoZWNrc3VtcyddICkKCQkJfHwgISBpc19hcnJheSggJHJlc3BvbnNlWydjaGVja3N1bXMnXSApCgkJKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkcmVzcG9uc2VbJ2NoZWNrc3VtcyddOwoJfQoKCS8qKgoJICogR2V0cyBhIGNvcmUgdmVyc2lvbiBjaGVjay4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUgT3B0aW9uYWwuIExvY2FsZSB0byByZXF1ZXN0IGEgdmVyc2lvbiBjaGVjayBmb3IuIERlZmF1bHRzIHRvICdlbl9VUycuCgkgKiBAcmV0dXJuIGFycmF5fGZhbHNlIEZhbHNlIG9uIGZhaWx1cmUuIEFzc29jaWF0aXZlIGFycmF5IG9mIHRoZSBvZmZlciBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlsZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfY29yZV92ZXJzaW9uX2NoZWNrKCAkbG9jYWxlID0gJ2VuX1VTJyApIHsKCQkkdXJsID0gc3ByaW50ZigKCQkJJyVzPyVzJywKCQkJc2VsZjo6VkVSU0lPTl9DSEVDS19FTkRQT0lOVCwKCQkJaHR0cF9idWlsZF9xdWVyeSggY29tcGFjdCggJ2xvY2FsZScgKSwgbnVsbCwgJyYnICkKCQkpOwoKCQkkcmVzcG9uc2UgPSAkdGhpcy0+anNvbl9nZXRfcmVxdWVzdCggJHVybCApOwoKCQlpZiAoICEgaXNfYXJyYXkoICRyZXNwb25zZSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJHJlc3BvbnNlOwoJfQoKCS8qKgoJICogR2V0cyBhIGRvd25sb2FkIG9mZmVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGxvY2FsZSBPcHRpb25hbC4gTG9jYWxlIHRvIHJlcXVlc3QgYW4gb2ZmZXIgZnJvbS4gRGVmYXVsdHMgdG8gJ2VuX1VTJy4KCSAqIEByZXR1cm4gYXJyYXl8ZmFsc2UgRmFsc2Ugb24gZmFpbHVyZS4gQXNzb2NpYXRpdmUgYXJyYXkgb2YgdGhlIG9mZmVyIG9uIHN1Y2Nlc3MuCgkgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9jb3JlX2Rvd25sb2FkX29mZmVyKCAkbG9jYWxlID0gJ2VuX1VTJyApIHsKCQkkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0X2NvcmVfdmVyc2lvbl9jaGVjayggJGxvY2FsZSApOwoKCQlpZiAoCgkJCSEgaXNfYXJyYXkoICRyZXNwb25zZSApCgkJCXx8ICEgaXNzZXQoICRyZXNwb25zZVsnb2ZmZXJzJ10gKQoJCQl8fCAhIGlzX2FycmF5KCAkcmVzcG9uc2VbJ29mZmVycyddICkKCQkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJG9mZmVyID0gJHJlc3BvbnNlWydvZmZlcnMnXVswXTsKCgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICdsb2NhbGUnLCAkb2ZmZXIgKSB8fCAkbG9jYWxlICE9PSAkb2ZmZXJbJ2xvY2FsZSddICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gJG9mZmVyOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgY2hlY2tzdW1zIGZvciB0aGUgZ2l2ZW4gdmVyc2lvbiBvZiBwbHVnaW4uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGx1Z2luICBQbHVnaW4gc2x1ZyB0byBxdWVyeS4KCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gVmVyc2lvbiBzdHJpbmcgdG8gcXVlcnkuCgkgKiBAcmV0dXJuIGJvb2x8YXJyYXkgRmFsc2Ugb24gZmFpbHVyZS4gQW4gYXJyYXkgb2YgY2hlY2tzdW1zIG9uIHN1Y2Nlc3MuCgkgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3BsdWdpbl9jaGVja3N1bXMoICRwbHVnaW4sICR2ZXJzaW9uICkgewoJCSR1cmwgPSBzcHJpbnRmKAoJCQknJXMlcy8lcy5qc29uJywKCQkJc2VsZjo6UExVR0lOX0NIRUNLU1VNU19FTkRQT0lOVCwKCQkJJHBsdWdpbiwKCQkJJHZlcnNpb24KCQkpOwoKCQkkcmVzcG9uc2UgPSAkdGhpcy0+anNvbl9nZXRfcmVxdWVzdCggJHVybCApOwoKCQlpZiAoCgkJCSEgaXNfYXJyYXkoICRyZXNwb25zZSApCgkJCXx8ICEgaXNzZXQoICRyZXNwb25zZVsnZmlsZXMnXSApCgkJCXx8ICEgaXNfYXJyYXkoICRyZXNwb25zZVsnZmlsZXMnXSApCgkJKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkcmVzcG9uc2VbJ2ZpbGVzJ107Cgl9CgoJLyoqCgkgKiBHZXRzIGEgcGx1Z2luJ3MgaW5mby4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwbHVnaW4gUGx1Z2luIHNsdWcgdG8gcXVlcnkuCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUgT3B0aW9uYWwuIExvY2FsZSB0byByZXF1ZXN0IGluZm8gZm9yLiBEZWZhdWx0cyB0byAnZW5fVVMnLgoJICogQHJldHVybiBhcnJheXxmYWxzZSBGYWxzZSBvbiBmYWlsdXJlLiBBc3NvY2lhdGl2ZSBhcnJheSBvZiB0aGUgb2ZmZXIgb24gc3VjY2Vzcy4KCSAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgcmVtb3RlIHJlcXVlc3QgZmFpbGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3BsdWdpbl9pbmZvKCAkcGx1Z2luLCAkbG9jYWxlID0gJ2VuX1VTJyApIHsKCQkkYWN0aW9uICA9ICdwbHVnaW5faW5mb3JtYXRpb24nOwoJCSRyZXF1ZXN0ID0gWwoJCQknbG9jYWxlJyA9PiAkbG9jYWxlLAoJCQknc2x1ZycgICA9PiAkcGx1Z2luLAoJCV07CgoJCSR1cmwgPSBzcHJpbnRmKAoJCQknJXM/JXMnLAoJCQlzZWxmOjpQTFVHSU5fSU5GT19FTkRQT0lOVCwKCQkJaHR0cF9idWlsZF9xdWVyeSggY29tcGFjdCggJ2FjdGlvbicsICdyZXF1ZXN0JyApLCBudWxsLCAnJicgKQoJCSk7CgoJCSRyZXNwb25zZSA9ICR0aGlzLT5qc29uX2dldF9yZXF1ZXN0KCAkdXJsICk7CgoJCWlmICggISBpc19hcnJheSggJHJlc3BvbnNlICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkcmVzcG9uc2U7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgdGhlbWUncyBpbmZvLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRoZW1lICBUaGVtZSBzbHVnIHRvIHF1ZXJ5LgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlIE9wdGlvbmFsLiBMb2NhbGUgdG8gcmVxdWVzdCBpbmZvIGZvci4gRGVmYXVsdHMgdG8gJ2VuX1VTJy4KCSAqIEByZXR1cm4gYXJyYXl8ZmFsc2UgRmFsc2Ugb24gZmFpbHVyZS4gQXNzb2NpYXRpdmUgYXJyYXkgb2YgdGhlIG9mZmVyIG9uIHN1Y2Nlc3MuCgkgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF90aGVtZV9pbmZvKCAkdGhlbWUsICRsb2NhbGUgPSAnZW5fVVMnICkgewoJCSRhY3Rpb24gID0gJ3RoZW1lX2luZm9ybWF0aW9uJzsKCQkkcmVxdWVzdCA9IFsKCQkJJ2xvY2FsZScgPT4gJGxvY2FsZSwKCQkJJ3NsdWcnICAgPT4gJHRoZW1lLAoJCV07CgoJCSR1cmwgPSBzcHJpbnRmKAoJCQknJXM/JXMnLAoJCQlzZWxmOjpUSEVNRV9JTkZPX0VORFBPSU5ULAoJCQlodHRwX2J1aWxkX3F1ZXJ5KCBjb21wYWN0KCAnYWN0aW9uJywgJ3JlcXVlc3QnICksIG51bGwsICcmJyApCgkJKTsKCgkJJHJlc3BvbnNlID0gJHRoaXMtPmpzb25fZ2V0X3JlcXVlc3QoICR1cmwgKTsKCgkJaWYgKCAhIGlzX2FycmF5KCAkcmVzcG9uc2UgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRyZXNwb25zZTsKCX0KCgkvKioKCSAqIEdldHMgYSBzZXQgb2Ygc2FsdHMgaW4gdGhlIGZvcm1hdCByZXF1aXJlZCBieSBgd3AtY29uZmlnLnBocGAuCgkgKgoJICogQHJldHVybiBib29sfHN0cmluZyBGYWxzZSBvbiBmYWlsdXJlLiBBIHN0cmluZyBvZiBQSFAgZGVmaW5lKCkgc3RhdGVtZW50cyBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlscy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9zYWx0cygpIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9yZXF1ZXN0KCBzZWxmOjpTQUxUX0VORFBPSU5UICk7Cgl9CgoJLyoqCgkgKiBFeGVjdXRlIGEgcmVtb3RlIEdFVCByZXF1ZXN0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCAgICAgVVJMIHRvIGV4ZWN1dGUgdGhlIEdFVCByZXF1ZXN0IG9uLgoJICogQHBhcmFtIGFycmF5ICAkaGVhZGVycyBPcHRpb25hbC4gQXNzb2NpYXRpdmUgYXJyYXkgb2YgaGVhZGVycy4KCSAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIG9wdGlvbnMuCgkgKiBAcmV0dXJuIG1peGVkfGZhbHNlIEZhbHNlIG9uIGZhaWx1cmUuIERlY29kZWQgSlNPTiBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSBKU09OIGNvdWxkIG5vdCBiZSBkZWNvZGVkLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGpzb25fZ2V0X3JlcXVlc3QoICR1cmwsICRoZWFkZXJzID0gW10sICRvcHRpb25zID0gW10gKSB7CgkJJGhlYWRlcnMgPSBhcnJheV9tZXJnZSgKCQkJWwoJCQkJJ0FjY2VwdCcgPT4gJ2FwcGxpY2F0aW9uL2pzb24nLAoJCQldLAoJCQkkaGVhZGVycwoJCSk7CgoJCSRyZXNwb25zZSA9ICR0aGlzLT5nZXRfcmVxdWVzdCggJHVybCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXNwb25zZSApIHsKCQkJcmV0dXJuICRyZXNwb25zZTsKCQl9CgoJCSRkYXRhID0ganNvbl9kZWNvZGUoICRyZXNwb25zZSwgdHJ1ZSApOwoKCQlpZiAoIEpTT05fRVJST1JfTk9ORSAhPT0ganNvbl9sYXN0X2Vycm9yKCkgKSB7CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCAnRmFpbGVkIHRvIGRlY29kZSBKU09OOiAnIC4ganNvbl9sYXN0X2Vycm9yX21zZygpICk7CgkJfQoKCQlyZXR1cm4gJGRhdGE7Cgl9CgoJLyoqCgkgKiBFeGVjdXRlIGEgcmVtb3RlIEdFVCByZXF1ZXN0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCAgICAgVVJMIHRvIGV4ZWN1dGUgdGhlIEdFVCByZXF1ZXN0IG9uLgoJICogQHBhcmFtIGFycmF5ICAkaGVhZGVycyBPcHRpb25hbC4gQXNzb2NpYXRpdmUgYXJyYXkgb2YgaGVhZGVycy4KCSAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIG9wdGlvbnMuCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBGYWxzZSBvbiBmYWlsdXJlLiBSZXNwb25zZSBib2R5IHN0cmluZyBvbiBzdWNjZXNzLgoJICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHRoZSByZW1vdGUgcmVxdWVzdCBmYWlscy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcmVxdWVzdCggJHVybCwgJGhlYWRlcnMgPSBbXSwgJG9wdGlvbnMgPSBbXSApIHsKCQkkb3B0aW9ucyA9IGFycmF5X21lcmdlKAoJCQkkdGhpcy0+b3B0aW9ucywKCQkJWwoJCQkJJ2hhbHRfb25fZXJyb3InID0+IGZhbHNlLAoJCQldLAoJCQkkb3B0aW9ucwoJCSk7CgoJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICR1cmwsIG51bGwsICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQlpZiAoCgkJCSEgJHJlc3BvbnNlLT5zdWNjZXNzCgkJCXx8IDIwMCA+IChpbnQpICRyZXNwb25zZS0+c3RhdHVzX2NvZGUKCQkJfHwgMzAwIDw9ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUKCQkpIHsKCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCgkJCQkiQ291bGRuJ3QgZmV0Y2ggcmVzcG9uc2UgZnJvbSB7JHVybH0gKEhUVFAgY29kZSB7JHJlc3BvbnNlLT5zdGF0dXNfY29kZX0pLiIKCQkJKTsKCQl9CgoJCXJldHVybiB0cmltKCAkcmVzcG9uc2UtPmJvZHkgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBNdXN0YW5nb3N0YW5nXFNweWM7CgovKioKICogUGFyc2UgY29tbWFuZCBhdHRyaWJ1dGVzIGZyb20gaXRzIFBIUGRvYy4KICogVXNlZCB0byBkZXRlcm1pbmUgZXhlY3V0aW9uIGNoYXJhY3RlcmlzdGljcyAoYXJndW1lbnRzLCBldGMuKS4KICovCmNsYXNzIERvY1BhcnNlciB7CgoJLyoqCgkgKiBQSFBkb2MgY29tbWFuZCBmb3IgdGhlIGNvbW1hbmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkb2NfY29tbWVudDsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJGRvY19jb21tZW50CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGRvY19jb21tZW50ICkgewoJCS8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGEga25vd24gbGluZSBlbmRpbmcgaW4gZG9jdW1lbnQgKi8KCQkkZG9jX2NvbW1lbnQgICAgICAgPSBzdHJfcmVwbGFjZSggIlxyXG4iLCAiXG4iLCAkZG9jX2NvbW1lbnQgKTsKCQkkdGhpcy0+ZG9jX2NvbW1lbnQgPSBzZWxmOjpyZW1vdmVfZGVjb3JhdGlvbnMoICRkb2NfY29tbWVudCApOwoJfQoKCS8qKgoJICogUmVtb3ZlIHVudXNlZCBjcnVmdCBmcm9tIFBIUGRvYyBjb21tZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbW1lbnQgUEhQZG9jIGNvbW1lbnQuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiByZW1vdmVfZGVjb3JhdGlvbnMoICRjb21tZW50ICkgewoJCSRjb21tZW50ID0gcHJlZ19yZXBsYWNlKCAnfF4vXCpcKltcclxuXSt8JywgJycsICRjb21tZW50ICk7CgkJJGNvbW1lbnQgPSBwcmVnX3JlcGxhY2UoICd8XG5bXHQgXSpcKi8kfCcsICcnLCAkY29tbWVudCApOwoJCSRjb21tZW50ID0gcHJlZ19yZXBsYWNlKCAnfF5bXHQgXSpcKiA/fG0nLCAnJywgJGNvbW1lbnQgKTsKCgkJcmV0dXJuICRjb21tZW50OwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21tYW5kJ3Mgc2hvcnQgZGVzY3JpcHRpb24gKGUuZy4gc3VtbWFyeSkuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9zaG9ydGRlc2MoKSB7CgkJaWYgKCAhIHByZWdfbWF0Y2goICd8XihbXkBdW15cbl0rKVxuKnwnLCAkdGhpcy0+ZG9jX2NvbW1lbnQsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiAnJzsKCQl9CgoJCXJldHVybiAkbWF0Y2hlc1sxXTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tbWFuZCdzIGZ1bGwgZGVzY3JpcHRpb24KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvbmdkZXNjKCkgewoJCSRzaG9ydGRlc2MgPSAkdGhpcy0+Z2V0X3Nob3J0ZGVzYygpOwoJCWlmICggISAkc2hvcnRkZXNjICkgewoJCQlyZXR1cm4gJyc7CgkJfQoKCQkkbG9uZ2Rlc2MgPSBzdWJzdHIoICR0aGlzLT5kb2NfY29tbWVudCwgc3RybGVuKCAkc2hvcnRkZXNjICkgKTsKCgkJJGxpbmVzID0gW107CgkJZm9yZWFjaCAoIGV4cGxvZGUoICJcbiIsICRsb25nZGVzYyApIGFzICRsaW5lICkgewoJCQlpZiAoIDAgPT09IHN0cnBvcyggJGxpbmUsICdAJyApICkgewoJCQkJYnJlYWs7CgkJCX0KCgkJCSRsaW5lc1tdID0gJGxpbmU7CgkJfQoKCQlyZXR1cm4gdHJpbSggaW1wbG9kZSggIlxuIiwgJGxpbmVzICkgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgZm9yIGEgZ2l2ZW4gdGFnIChlLmcuICJAYWxpYXMiIG9yICJAc3ViY29tbWFuZCIpCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBOYW1lIGZvciB0aGUgdGFnLCB3aXRob3V0ICdAJwoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF90YWcoICRuYW1lICkgewoJCWlmICggcHJlZ19tYXRjaCggJ3xeQCcgLiAkbmFtZSAuICdccysoW2Etei1fMC05XSspfG0nLCAkdGhpcy0+ZG9jX2NvbW1lbnQsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiAkbWF0Y2hlc1sxXTsKCQl9CgoJCXJldHVybiAnJzsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tbWFuZCdzIHN5bm9wc2lzLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfc3lub3BzaXMoKSB7CgkJaWYgKCAhIHByZWdfbWF0Y2goICd8XkBzeW5vcHNpc1xzKyguKyl8bScsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCgkJcmV0dXJuICRtYXRjaGVzWzFdOwoJfQoKCS8qKgoJICogR2V0IHRoZSBkZXNjcmlwdGlvbiBmb3IgYSBnaXZlbiBhcmd1bWVudC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIEFyZ3VtZW50J3MgZG9jIG5hbWUuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FyZ19kZXNjKCAkbmFtZSApIHsKCgkJaWYgKCBwcmVnX21hdGNoKCAiL1xbPzx7JG5hbWV9Pi4rXG46ICguKz8pKFxufCQpLyIsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICRtYXRjaGVzWzFdOwoJCX0KCgkJcmV0dXJuICcnOwoKCX0KCgkvKioKCSAqIEdldCB0aGUgYXJndW1lbnRzIGZvciBhIGdpdmVuIGFyZ3VtZW50LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgQXJndW1lbnQncyBkb2MgbmFtZS4KCSAqIEByZXR1cm4gbWl4ZWR8bnVsbAoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2FyZ19hcmdzKCAkbmFtZSApIHsKCQlyZXR1cm4gJHRoaXMtPmdldF9hcmdfb3JfcGFyYW1fYXJncyggIi9eXFs/PHskbmFtZX0+LiovIiApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBkZXNjcmlwdGlvbiBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IFBhcmFtZXRlcidzIGtleS4KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcGFyYW1fZGVzYyggJGtleSApIHsKCgkJaWYgKCBwcmVnX21hdGNoKCAiL1xbPy0teyRrZXl9PS4rXG46ICguKz8pKFxufCQpLyIsICR0aGlzLT5kb2NfY29tbWVudCwgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICRtYXRjaGVzWzFdOwoJCX0KCgkJcmV0dXJuICcnOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhcmd1bWVudHMgZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQYXJhbWV0ZXIncyBrZXkuCgkgKiBAcmV0dXJuIG1peGVkfG51bGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wYXJhbV9hcmdzKCAka2V5ICkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2FyZ19vcl9wYXJhbV9hcmdzKCAiL15cWz8tLXska2V5fT0uKi8iICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGFyZ3MgZm9yIGFuIGFyZyBvciBwYXJhbQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlZ2V4IFBhdHRlcm4gdG8gbWF0Y2ggYWdhaW5zdAoJICogQHJldHVybiBhcnJheXxudWxsIEludGVycHJldGVkIFlBTUwgZG9jdW1lbnQsIG9yIG51bGwuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2FyZ19vcl9wYXJhbV9hcmdzKCAkcmVnZXggKSB7CgkJJGJpdHMgICAgICAgPSBleHBsb2RlKCAiXG4iLCAkdGhpcy0+ZG9jX2NvbW1lbnQgKTsKCQkkd2l0aGluX2FyZyA9IGZhbHNlOwoJCSR3aXRoaW5fZG9jID0gZmFsc2U7CgkJJGRvY3VtZW50ICAgPSBbXTsKCQlmb3JlYWNoICggJGJpdHMgYXMgJGJpdCApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAkcmVnZXgsICRiaXQgKSApIHsKCQkJCSR3aXRoaW5fYXJnID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2FyZyAmJiAkd2l0aGluX2RvYyAmJiAnLS0tJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fZG9jID0gZmFsc2U7CgkJCX0KCgkJCWlmICggJHdpdGhpbl9hcmcgJiYgISAkd2l0aGluX2RvYyAmJiAnLS0tJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fZG9jID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2RvYyApIHsKCQkJCSRkb2N1bWVudFtdID0gJGJpdDsKCQkJfQoKCQkJaWYgKCAkd2l0aGluX2FyZyAmJiAnJyA9PT0gJGJpdCApIHsKCQkJCSR3aXRoaW5fYXJnID0gZmFsc2U7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCAkZG9jdW1lbnQgKSB7CgkJCXJldHVybiBTcHljOjpZQU1MTG9hZFN0cmluZyggaW1wbG9kZSggIlxuIiwgJGRvY3VtZW50ICkgKTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKLyoqCiAqIEdlbmVyYXRlIGEgc3lub3BzaXMgZnJvbSBhIGNvbW1hbmQncyBQSFBkb2MgYXJndW1lbnRzLgogKiBUdXJucyBzb21ldGhpbmcgbGlrZSAiPG9iamVjdC1pZD4uLi4iCiAqIGludG8gWyBvcHRpb25hbD0+ZmFsc2UsIHR5cGU9PnBvc2l0aW9uYWwsIHJlcGVhdGluZz0+dHJ1ZSwgbmFtZT0+b2JqZWN0LWlkIF0KICovCmNsYXNzIFN5bm9wc2lzUGFyc2VyIHsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJHN5bm9wc2lzIEEgc3lub3BzaXMKCSAqIEByZXR1cm4gYXJyYXkgTGlzdCBvZiBwYXJhbWV0ZXJzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFyc2UoICRzeW5vcHNpcyApIHsKCQkkdG9rZW5zID0gYXJyYXlfZmlsdGVyKCBwcmVnX3NwbGl0KCAnL1tcc1x0XSsvJywgJHN5bm9wc2lzICkgKTsKCgkJJHBhcmFtcyA9IFtdOwoJCWZvcmVhY2ggKCAkdG9rZW5zIGFzICR0b2tlbiApIHsKCQkJJHBhcmFtID0gc2VsZjo6Y2xhc3NpZnlfdG9rZW4oICR0b2tlbiApOwoKCQkJLy8gU29tZSB0eXBlcyBvZiBwYXJhbWV0ZXJzIHNob3VsZG4ndCBiZSBtYW5kYXRvcnkKCQkJaWYgKCBpc3NldCggJHBhcmFtWydvcHRpb25hbCddICkgJiYgISAkcGFyYW1bJ29wdGlvbmFsJ10gKSB7CgkJCQlpZiAoICdmbGFnJyA9PT0gJHBhcmFtWyd0eXBlJ10gfHwgKCAnYXNzb2MnID09PSAkcGFyYW1bJ3R5cGUnXSAmJiAkcGFyYW1bJ3ZhbHVlJ11bJ29wdGlvbmFsJ10gKSApIHsKCQkJCQkkcGFyYW1bJ3R5cGUnXSA9ICd1bmtub3duJzsKCQkJCX0KCQkJfQoKCQkJJHBhcmFtWyd0b2tlbiddID0gJHRva2VuOwoJCQkkcGFyYW1zW10gICAgICAgPSAkcGFyYW07CgkJfQoKCQlyZXR1cm4gJHBhcmFtczsKCX0KCgkvKioKCSAqIFJlbmRlciB0aGUgU3lub3BzaXMgaW50byBhIGZvcm1hdCBzdHJpbmcuCgkgKgoJICogQHBhcmFtIGFycmF5ICRzeW5vcHNpcyBBIHN0cnVjdHVyZWQgc3lub3BzaXMuIFRoaXMgbWlnaHQgZ2V0IHJlb3JkZXJlZAoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBtYXRjaCB0aGUgcGFyc2VkIG91dHB1dC4KCSAqIEByZXR1cm4gc3RyaW5nIFJlbmRlcmVkIHN5bm9wc2lzLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlbmRlciggJiRzeW5vcHNpcyApIHsKCQlpZiAoICEgaXNfYXJyYXkoICRzeW5vcHNpcyApICkgewoJCQlyZXR1cm4gJyc7CgkJfQoJCSRiaXRzICAgICAgICAgICAgICAgPSBbCgkJCSdwb3NpdGlvbmFsJyA9PiAnJywKCQkJJ2Fzc29jJyAgICAgID0+ICcnLAoJCQknZ2VuZXJpYycgICAgPT4gJycsCgkJCSdmbGFnJyAgICAgICA9PiAnJywKCQldOwoJCSRyZW9yZGVyZWRfc3lub3BzaXMgPSBbCgkJCSdwb3NpdGlvbmFsJyA9PiBbXSwKCQkJJ2Fzc29jJyAgICAgID0+IFtdLAoJCQknZ2VuZXJpYycgICAgPT4gW10sCgkJCSdmbGFnJyAgICAgICA9PiBbXSwKCQldOwoJCWZvcmVhY2ggKCAkYml0cyBhcyAka2V5ID0+ICYkdmFsdWUgKSB7CgkJCWZvcmVhY2ggKCAkc3lub3BzaXMgYXMgJGFyZyApIHsKCQkJCWlmICggZW1wdHkoICRhcmdbJ3R5cGUnXSApCgkJCQkJfHwgJGtleSAhPT0gJGFyZ1sndHlwZSddICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggZW1wdHkoICRhcmdbJ25hbWUnXSApICYmICdnZW5lcmljJyAhPT0gJGFyZ1sndHlwZSddICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggJ3Bvc2l0aW9uYWwnID09PSAka2V5ICkgewoJCQkJCSRyZW5kZXJlZF9hcmcgPSAiPHskYXJnWyduYW1lJ119PiI7CgoJCQkJCSRyZW9yZGVyZWRfc3lub3BzaXNbJ3Bvc2l0aW9uYWwnXSBbXSA9ICRhcmc7CgkJCQl9IGVsc2VpZiAoICdhc3NvYycgPT09ICRrZXkgKSB7CgkJCQkJJGFyZ192YWx1ZSAgICA9IGlzc2V0KCAkYXJnWyd2YWx1ZSddWyduYW1lJ10gKSA/ICRhcmdbJ3ZhbHVlJ11bJ25hbWUnXSA6ICRhcmdbJ25hbWUnXTsKCQkJCQkkcmVuZGVyZWRfYXJnID0gIi0teyRhcmdbJ25hbWUnXX09PHskYXJnX3ZhbHVlfT4iOwoKCQkJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydhc3NvYyddIFtdID0gJGFyZzsKCQkJCX0gZWxzZWlmICggJ2dlbmVyaWMnID09PSAka2V5ICkgewoJCQkJCSRyZW5kZXJlZF9hcmcgPSAnLS08ZmllbGQ+PTx2YWx1ZT4nOwoKCQkJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydnZW5lcmljJ10gW10gPSAkYXJnOwoJCQkJfSBlbHNlaWYgKCAnZmxhZycgPT09ICRrZXkgKSB7CgkJCQkJJHJlbmRlcmVkX2FyZyA9ICItLXskYXJnWyduYW1lJ119IjsKCgkJCQkJJHJlb3JkZXJlZF9zeW5vcHNpc1snZmxhZyddIFtdID0gJGFyZzsKCQkJCX0KCQkJCWlmICggISBlbXB0eSggJGFyZ1sncmVwZWF0aW5nJ10gKSApIHsKCQkJCQkkcmVuZGVyZWRfYXJnID0gInskcmVuZGVyZWRfYXJnfS4uLiI7CgkJCQl9CgkJCQlpZiAoICEgZW1wdHkoICRhcmdbJ29wdGlvbmFsJ10gKSApIHsKCQkJCQkkcmVuZGVyZWRfYXJnID0gIlt7JHJlbmRlcmVkX2FyZ31dIjsKCQkJCX0KCQkJCSR2YWx1ZSAuPSAieyRyZW5kZXJlZF9hcmd9ICI7CgkJCX0KCQl9CgkJJHJlbmRlcmVkID0gJyc7CgkJZm9yZWFjaCAoICRiaXRzIGFzICR2ICkgewoJCQlpZiAoICEgZW1wdHkoICR2ICkgKSB7CgkJCQkkcmVuZGVyZWQgLj0gJHY7CgkJCX0KCQl9CgoJCSRzeW5vcHNpcyA9IGFycmF5X21lcmdlKAoJCQkkcmVvcmRlcmVkX3N5bm9wc2lzWydwb3NpdGlvbmFsJ10sCgkJCSRyZW9yZGVyZWRfc3lub3BzaXNbJ2Fzc29jJ10sCgkJCSRyZW9yZGVyZWRfc3lub3BzaXNbJ2dlbmVyaWMnXSwKCQkJJHJlb3JkZXJlZF9zeW5vcHNpc1snZmxhZyddCgkJKTsKCgkJcmV0dXJuIHJ0cmltKCAkcmVuZGVyZWQsICcgJyApOwoJfQoKCS8qKgoJICogQ2xhc3NpZnkgYXJndW1lbnQgYXR0cmlidXRlcyBiYXNlZCBvbiBpdHMgc3ludGF4LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRva2VuCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNsYXNzaWZ5X3Rva2VuKCAkdG9rZW4gKSB7CgkJJHBhcmFtID0gW107CgoJCWxpc3QoICRwYXJhbVsnb3B0aW9uYWwnXSwgJHRva2VuICkgID0gc2VsZjo6aXNfb3B0aW9uYWwoICR0b2tlbiApOwoJCWxpc3QoICRwYXJhbVsncmVwZWF0aW5nJ10sICR0b2tlbiApID0gc2VsZjo6aXNfcmVwZWF0aW5nKCAkdG9rZW4gKTsKCgkJJHBfbmFtZSAgPSAnKFthLXotXzAtOV0rKSc7CgkJJHBfdmFsdWUgPSAnKFthLXpBLVotX3wsMC05XSspJzsKCgkJaWYgKCAnLS08ZmllbGQ+PTx2YWx1ZT4nID09PSAkdG9rZW4gKSB7CgkJCSRwYXJhbVsndHlwZSddID0gJ2dlbmVyaWMnOwoJCX0gZWxzZWlmICggcHJlZ19tYXRjaCggIi9ePCgkcF92YWx1ZSk+JC8iLCAkdG9rZW4sICRtYXRjaGVzICkgKSB7CgkJCSRwYXJhbVsndHlwZSddID0gJ3Bvc2l0aW9uYWwnOwoJCQkkcGFyYW1bJ25hbWUnXSA9ICRtYXRjaGVzWzFdOwoJCX0gZWxzZWlmICggcHJlZ19tYXRjaCggIi9eLS0oPzpcXFtuby1cXF0pPyRwX25hbWUvIiwgJHRva2VuLCAkbWF0Y2hlcyApICkgewoJCQkkcGFyYW1bJ25hbWUnXSA9ICRtYXRjaGVzWzFdOwoKCQkJJHZhbHVlID0gc3Vic3RyKCAkdG9rZW4sIHN0cmxlbiggJG1hdGNoZXNbMF0gKSApOwoKCQkJLy8gc3Vic3RyIHJldHVybnMgZmFsc2UgPD0gUEhQIDUuNiwgYW5kICcnIFBIUCA3KwoJCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgfHwgJycgPT09ICR2YWx1ZSApIHsKCQkJCSRwYXJhbVsndHlwZSddID0gJ2ZsYWcnOwoJCQl9IGVsc2UgewoJCQkJJHBhcmFtWyd0eXBlJ10gPSAnYXNzb2MnOwoKCQkJCWxpc3QoICRwYXJhbVsndmFsdWUnXVsnb3B0aW9uYWwnXSwgJHZhbHVlICkgPSBzZWxmOjppc19vcHRpb25hbCggJHZhbHVlICk7CgoJCQkJaWYgKCBwcmVnX21hdGNoKCAiL149PCRwX3ZhbHVlPiQvIiwgJHZhbHVlLCAkbWF0Y2hlcyApICkgewoJCQkJCSRwYXJhbVsndmFsdWUnXVsnbmFtZSddID0gJG1hdGNoZXNbMV07CgkJCQl9IGVsc2UgewoJCQkJCSRwYXJhbSA9IFsKCQkJCQkJJ3R5cGUnID0+ICd1bmtub3duJywKCQkJCQldOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJJHBhcmFtWyd0eXBlJ10gPSAndW5rbm93bic7CgkJfQoKCQlyZXR1cm4gJHBhcmFtOwoJfQoKCS8qKgoJICogQW4gb3B0aW9uYWwgcGFyYW1ldGVyIGlzIHN1cnJvdW5kZWQgYnkgc3F1YXJlIGJyYWNrZXRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRva2VuCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX29wdGlvbmFsKCAkdG9rZW4gKSB7CgkJaWYgKCAnWycgPT09IHN1YnN0ciggJHRva2VuLCAwLCAxICkgJiYgJ10nID09PSBzdWJzdHIoICR0b2tlbiwgLTEgKSApIHsKCQkJcmV0dXJuIFsgdHJ1ZSwgc3Vic3RyKCAkdG9rZW4sIDEsIC0xICkgXTsKCQl9CgoJCXJldHVybiBbIGZhbHNlLCAkdG9rZW4gXTsKCX0KCgkvKioKCSAqIEEgcmVwZWF0aW5nIHBhcmFtZXRlciBpcyBmb2xsb3dlZCBieSBhbiBlbGxpcHNpcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0b2tlbgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc19yZXBlYXRpbmcoICR0b2tlbiApIHsKCQlpZiAoICcuLi4nID09PSBzdWJzdHIoICR0b2tlbiwgLTMgKSApIHsKCQkJcmV0dXJuIFsgdHJ1ZSwgc3Vic3RyKCAkdG9rZW4sIDAsIC0zICkgXTsKCQl9CgoJCXJldHVybiBbIGZhbHNlLCAkdG9rZW4gXTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBFc2NhcGUgcm91dGUgZm9yIG5vdCBkb2luZyBhbnl0aGluZy4KICovCmZpbmFsIGNsYXNzIE5vT3AgewoKCXB1YmxpYyBmdW5jdGlvbiBfX3NldCggJGtleSwgJHZhbHVlICkgewoJCS8vIGRvIG5vdGhpbmcKCX0KCglwdWJsaWMgZnVuY3Rpb24gX19jYWxsKCAkbWV0aG9kLCAkYXJncyApIHsKCQkvLyBkbyBub3RoaW5nCgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEZldGNoZXJzOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxFeGl0RXhjZXB0aW9uOwoKLyoqCiAqIEZldGNoIGEgV29yZFByZXNzIGVudGl0eSBmb3IgdXNlIGluIGEgc3ViY29tbWFuZC4KICovCmFic3RyYWN0IGNsYXNzIEJhc2UgewoKCS8qKgoJICogVGhlIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIGFuIGl0ZW0gaXMgbm90IGZvdW5kLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkbXNnOwoKCS8qKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFRoZSByYXcgQ0xJIGFyZ3VtZW50LgoJICogQHJldHVybiBtaXhlZHxmYWxzZSBUaGUgaXRlbSBpZiBmb3VuZDsgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJnICk7CgoJLyoqCgkgKiBMaWtlIGdldCgpLCBidXQgY2FsbHMgV1BfQ0xJOjplcnJvcigpIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZyBUaGUgcmF3IENMSSBhcmd1bWVudC4KCSAqIEByZXR1cm4gbWl4ZWQgVGhlIGl0ZW0gaWYgZm91bmQuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIGl0ZW0gaXMgbm90IGZvdW5kLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2NoZWNrKCAkYXJnICkgewoJCSRpdGVtID0gJHRoaXMtPmdldCggJGFyZyApOwoKCQlpZiAoICEgJGl0ZW0gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICR0aGlzLT5tc2csICRhcmcgKSApOwoJCX0KCgkJcmV0dXJuICRpdGVtOwoJfQoKCS8qKgoJICogR2V0IG11bHRpcGxlIGl0ZW1zLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBUaGUgcmF3IENMSSBhcmd1bWVudHMuCgkgKiBAcmV0dXJuIGFycmF5IFRoZSBsaXN0IG9mIGZvdW5kIGl0ZW1zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X21hbnkoICRhcmdzICkgewoJCSRpdGVtcyA9IFtdOwoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGFyZyApIHsKCQkJJGl0ZW0gPSAkdGhpcy0+Z2V0KCAkYXJnICk7CgoJCQlpZiAoICRpdGVtICkgewoJCQkJJGl0ZW1zW10gPSAkaXRlbTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJHRoaXMtPm1zZywgJGFyZyApICk7CgkJCX0KCQl9CgoJCXJldHVybiAkaXRlbXM7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEZldGNoZXJzOwoKdXNlIFdQX0NvbW1lbnQ7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgY29tbWVudCBiYXNlZCBvbiBvbmUgb2YgaXRzIGF0dHJpYnV0ZXMuCiAqLwpjbGFzcyBDb21tZW50IGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBUaGUgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gYW4gaXRlbSBpcyBub3QgZm91bmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRtc2cgPSAnQ291bGQgbm90IGZpbmQgdGhlIGNvbW1lbnQgd2l0aCBJRCAlZC4nOwoKCS8qKgoJICogR2V0IGEgY29tbWVudCBvYmplY3QgYnkgSUQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRhcmcgVGhlIHJhdyBDTEkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIFdQX0NvbW1lbnR8YXJyYXl8ZmFsc2UgVGhlIGl0ZW0gaWYgZm91bmQ7IGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZyApIHsKCQkkY29tbWVudF9pZCA9IChpbnQpICRhcmc7CgkJJGNvbW1lbnQgICAgPSBnZXRfY29tbWVudCggJGNvbW1lbnRfaWQgKTsKCgkJaWYgKCBudWxsID09PSAkY29tbWVudCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRjb21tZW50OwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxGZXRjaGVyczsKCi8qKgogKiBGZXRjaCBhIFdvcmRQcmVzcyBzaXRlIGJhc2VkIG9uIG9uZSBvZiBpdHMgYXR0cmlidXRlcy4KICovCmNsYXNzIFNpdGUgZXh0ZW5kcyBCYXNlIHsKCgkvKioKCSAqIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiBhbiBpdGVtIGlzIG5vdCBmb3VuZC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICdDb3VsZCBub3QgZmluZCB0aGUgc2l0ZSB3aXRoIElEICVkLic7CgoJLyoqCgkgKiBHZXQgYSBzaXRlIG9iamVjdCBieSBJRAoJICoKCSAqIEBwYXJhbSBpbnQgJHNpdGVfaWQKCSAqIEByZXR1cm4gb2JqZWN0fGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRzaXRlX2lkICkgewoJCXJldHVybiAkdGhpcy0+Z2V0X3NpdGUoICRzaXRlX2lkICk7Cgl9CgoJLyoqCgkgKiBHZXQgc2l0ZSAoYmxvZykgZGF0YSBmb3IgYSBnaXZlbiBpZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRhcmcgVGhlIHJhdyBDTEkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIGFycmF5fGZhbHNlIFRoZSBpdGVtIGlmIGZvdW5kOyBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3NpdGUoICRhcmcgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBMb2FkIHNpdGUgZGF0YQoJCSRzaXRlID0gJHdwZGItPmdldF9yb3coCgkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJIlNFTEVDVCAqIEZST00geyR3cGRiLT5ibG9nc30gV0hFUkUgYmxvZ19pZCA9ICVkIiwKCQkJCSRhcmcKCQkJKQoJCSk7CgoJCWlmICggISBlbXB0eSggJHNpdGUgKSApIHsKCQkJLy8gT25seSBjYXJlIGFib3V0IGRvbWFpbiBhbmQgcGF0aCB3aGljaCBhcmUgc2V0IGhlcmUKCQkJcmV0dXJuICRzaXRlOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEZldGNoZXJzOwoKdXNlIFdQX1Bvc3Q7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgcG9zdCBiYXNlZCBvbiBvbmUgb2YgaXRzIGF0dHJpYnV0ZXMuCiAqLwpjbGFzcyBQb3N0IGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBUaGUgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gYW4gaXRlbSBpcyBub3QgZm91bmQuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRtc2cgPSAnQ291bGQgbm90IGZpbmQgdGhlIHBvc3Qgd2l0aCBJRCAlZC4nOwoKCS8qKgoJICogR2V0IGEgcG9zdCBvYmplY3QgYnkgSUQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRhcmcgVGhlIHJhdyBDTEkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIFdQX1Bvc3R8YXJyYXl8ZmFsc2UgVGhlIGl0ZW0gaWYgZm91bmQ7IGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZyApIHsKCQkkcG9zdCA9IGdldF9wb3N0KCAkYXJnICk7CgoJCWlmICggbnVsbCA9PT0gJHBvc3QgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkcG9zdDsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7Cgp1c2UgV1BfVXNlcjsKCi8qKgogKiBGZXRjaCBhIFdvcmRQcmVzcyB1c2VyIGJhc2VkIG9uIG9uZSBvZiBpdHMgYXR0cmlidXRlcy4KICovCmNsYXNzIFVzZXIgZXh0ZW5kcyBCYXNlIHsKCgkvKioKCSAqIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiBhbiBpdGVtIGlzIG5vdCBmb3VuZC4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICJJbnZhbGlkIHVzZXIgSUQsIGVtYWlsIG9yIGxvZ2luOiAnJXMnIjsKCgkvKioKCSAqIEdldCBhIHVzZXIgb2JqZWN0IGJ5IG9uZSBvZiBpdHMgaWRlbnRpZnlpbmcgYXR0cmlidXRlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRhcmcgVGhlIHJhdyBDTEkgYXJndW1lbnQuCgkgKiBAcmV0dXJuIFdQX1VzZXJ8ZmFsc2UgVGhlIGl0ZW0gaWYgZm91bmQ7IGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZyApIHsKCgkJaWYgKCBpc19udW1lcmljKCAkYXJnICkgKSB7CgkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdpZCcsICRhcmcgKTsKCQl9IGVsc2VpZiAoIGlzX2VtYWlsKCAkYXJnICkgKSB7CgkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdlbWFpbCcsICRhcmcgKTsKCQkJLy8gTG9naW5zIGNhbiBiZSBlbWFpbHMuCgkJCWlmICggISAkdXNlciApIHsKCQkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRhcmcgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRhcmcgKTsKCQl9CgoJCXJldHVybiAkdXNlcjsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogQ2xhc3MgQXV0b2xvYWRlci4KICoKICogVGhpcyBpcyBhIGN1c3RvbSBhdXRvbG9hZGVyIHRvIHJlcGxhY2UgdGhlIGZ1bmN0aW9uYWxpdHkgdGhhdCB3ZSB3b3VsZAogKiBub3JtYWxseSBnZXQgdGhyb3VnaCB0aGUgYXV0b2xvYWRlciBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIuCiAqCiAqIFdlIG5lZWQgdGhpcyBzZXBhcmF0ZSBhdXRvbG9hZGVyIGZvciB0aGUgYm9vdHN0cmFwcGluZyBwcm9jZXNzLCB3aGljaCBoYXBwZW5zCiAqIGJlZm9yZSB0aGUgQ29tcG9zZXIgYXV0b2xvYWRlcihzKSBjb3VsZCBiZSBsb2FkZWQuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSQogKi8KY2xhc3MgQXV0b2xvYWRlciB7CgoJLyoqCgkgKiBBcnJheSBjb250YWluaW5nIHRoZSByZWdpc3RlcmVkIG5hbWVzcGFjZSBzdHJ1Y3R1cmVzCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcm90ZWN0ZWQgJG5hbWVzcGFjZXMgPSBbXTsKCgkvKioKCSAqIERlc3RydWN0b3IgZm9yIHRoZSBBdXRvbG9hZGVyIGNsYXNzLgoJICoKCSAqIFRoZSBkZXN0cnVjdG9yIGF1dG9tYXRpY2FsbHkgdW5yZWdpc3RlcnMgdGhlIGF1dG9sb2FkIGNhbGxiYWNrIGZ1bmN0aW9uCgkgKiB3aXRoIHRoZSBTUEwgYXV0b2xvYWQgc3lzdGVtLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpIHsKCQkkdGhpcy0+dW5yZWdpc3RlcigpOwoJfQoKCS8qKgoJICogUmVnaXN0ZXJzIHRoZSBhdXRvbG9hZCBjYWxsYmFjayB3aXRoIHRoZSBTUEwgYXV0b2xvYWQgc3lzdGVtLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoKSB7CgkJc3BsX2F1dG9sb2FkX3JlZ2lzdGVyKCBbICR0aGlzLCAnYXV0b2xvYWQnIF0gKTsKCX0KCgkvKioKCSAqIFVucmVnaXN0ZXJzIHRoZSBhdXRvbG9hZCBjYWxsYmFjayB3aXRoIHRoZSBTUEwgYXV0b2xvYWQgc3lzdGVtLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5yZWdpc3RlcigpIHsKCQlzcGxfYXV0b2xvYWRfdW5yZWdpc3RlciggWyAkdGhpcywgJ2F1dG9sb2FkJyBdICk7Cgl9CgoJLyoqCgkgKiBBZGQgYSBzcGVjaWZpYyBuYW1lc3BhY2Ugc3RydWN0dXJlIHdpdGggb3VyIGN1c3RvbSBhdXRvbG9hZGVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRyb290ICAgICAgICBSb290IG5hbWVzcGFjZSBuYW1lLgoJICogQHBhcmFtIHN0cmluZyAgJGJhc2VfZGlyICAgIERpcmVjdG9yeSBjb250YWluaW5nIHRoZSBjbGFzcyBmaWxlcy4KCSAqIEBwYXJhbSBzdHJpbmcgICRwcmVmaXggICAgICBQcmVmaXggdG8gYmUgYWRkZWQgYmVmb3JlIHRoZSBjbGFzcy4KCSAqIEBwYXJhbSBzdHJpbmcgICRzdWZmaXggICAgICBTdWZmaXggdG8gYmUgYWRkZWQgYWZ0ZXIgdGhlIGNsYXNzLgoJICogQHBhcmFtIGJvb2xlYW4gJGxvd2VyY2FzZSAgIFdoZXRoZXIgdGhlIGNsYXNzIHNob3VsZCBiZSBjaGFuZ2VkIHRvCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJjYXNlLgoJICogQHBhcmFtIGJvb2xlYW4gJHVuZGVyc2NvcmVzIFdoZXRoZXIgdGhlIHVuZGVyc2NvcmVzIHNob3VsZCBiZSBjaGFuZ2VkIHRvCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlwaGVucy4KCSAqCgkgKiBAcmV0dXJuIHNlbGYKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZF9uYW1lc3BhY2UoCgkJJHJvb3QsCgkJJGJhc2VfZGlyLAoJCSRwcmVmaXggPSAnJywKCQkkc3VmZml4ID0gJy5waHAnLAoJCSRsb3dlcmNhc2UgPSBmYWxzZSwKCQkkdW5kZXJzY29yZXMgPSBmYWxzZQoJKSB7CgkJJHRoaXMtPm5hbWVzcGFjZXNbXSA9IFsKCQkJJ3Jvb3QnICAgICAgICA9PiAkdGhpcy0+bm9ybWFsaXplX3Jvb3QoIChzdHJpbmcpICRyb290ICksCgkJCSdiYXNlX2RpcicgICAgPT4gJHRoaXMtPmFkZF90cmFpbGluZ19zbGFzaCggKHN0cmluZykgJGJhc2VfZGlyICksCgkJCSdwcmVmaXgnICAgICAgPT4gKHN0cmluZykgJHByZWZpeCwKCQkJJ3N1ZmZpeCcgICAgICA9PiAoc3RyaW5nKSAkc3VmZml4LAoJCQknbG93ZXJjYXNlJyAgID0+IChib29sKSAkbG93ZXJjYXNlLAoJCQkndW5kZXJzY29yZXMnID0+IChib29sKSAkdW5kZXJzY29yZXMsCgkJXTsKCgkJcmV0dXJuICR0aGlzOwoJfQoKCS8qKgoJICogVGhlIGF1dG9sb2FkIGZ1bmN0aW9uIHRoYXQgZ2V0cyByZWdpc3RlcmVkIHdpdGggdGhlIFNQTCBBdXRvbG9hZGVyCgkgKiBzeXN0ZW0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY2xhc3MgVGhlIGNsYXNzIHRoYXQgZ290IHJlcXVlc3RlZCBieSB0aGUgc3BsX2F1dG9sb2FkZXIuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhdXRvbG9hZCggJGNsYXNzICkgewoKCQkvLyBJdGVyYXRlIG92ZXIgbmFtZXNwYWNlcyB0byBmaW5kIGEgbWF0Y2guCgkJZm9yZWFjaCAoICR0aGlzLT5uYW1lc3BhY2VzIGFzICRuYW1lc3BhY2UgKSB7CgoJCQkvLyBNb3ZlIG9uIGlmIHRoZSBvYmplY3QgZG9lcyBub3QgYmVsb25nIHRvIHRoZSBjdXJyZW50IG5hbWVzcGFjZS4KCQkJaWYgKCAwICE9PSBzdHJwb3MoICRjbGFzcywgJG5hbWVzcGFjZVsncm9vdCddICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gUmVtb3ZlIG5hbWVzcGFjZSByb290IGxldmVsIHRvIGNvcnJlc3BvbmQgd2l0aCByb290IGZpbGVzeXN0ZW0sIGFuZAoJCQkvLyByZXBsYWNlIHRoZSBuYW1lc3BhY2Ugc2VwYXJhdG9yICJcIiBieSB0aGUgc3lzdGVtLWRlcGVuZGVudCBkaXJlY3Rvcnkgc2VwYXJhdG9yLgoJCQkkZmlsZW5hbWUgPSBzdHJfcmVwbGFjZSgKCQkJCVsgJG5hbWVzcGFjZVsncm9vdCddLCAnXFwnIF0sCgkJCQlbICcnLCBESVJFQ1RPUllfU0VQQVJBVE9SIF0sCgkJCQkkY2xhc3MKCQkJKTsKCgkJCS8vIFJlbW92ZSBhIGxlYWRpbmcgYmFja3NsYXNoIGZyb20gdGhlIGNsYXNzIG5hbWUuCgkJCSRmaWxlbmFtZSA9ICR0aGlzLT5yZW1vdmVfbGVhZGluZ19iYWNrc2xhc2goICRmaWxlbmFtZSApOwoKCQkJLy8gQ2hhbmdlIHRvIGxvd2VyIGNhc2UgaWYgcmVxdWVzdGVkLgoJCQlpZiAoICRuYW1lc3BhY2VbJ2xvd2VyY2FzZSddICkgewoJCQkJJGZpbGVuYW1lID0gc3RydG9sb3dlciggJGZpbGVuYW1lICk7CgkJCX0KCgkJCS8vIENoYW5nZSB1bmRlcnNjb3JlcyBpbnRvIGh5cGhlbnMgaWYgcmVxdWVzdGVkLgoJCQlpZiAoICRuYW1lc3BhY2VbJ3VuZGVyc2NvcmVzJ10gKSB7CgkJCQkkZmlsZW5hbWUgPSBzdHJfcmVwbGFjZSggJ18nLCAnLScsICRmaWxlbmFtZSApOwoJCQl9CgoJCQkvLyBBZGQgYmFzZV9kaXIsIHByZWZpeCBhbmQgc3VmZml4LgoJCQkkZmlsZXBhdGggPSAkbmFtZXNwYWNlWydiYXNlX2RpciddCgkJCQkuICRuYW1lc3BhY2VbJ3ByZWZpeCddCgkJCQkuICRmaWxlbmFtZQoJCQkJLiAkbmFtZXNwYWNlWydzdWZmaXgnXTsKCgkJCS8vIFRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdCBvciBpcyBub3QgcmVhZGFibGUuCgkJCWlmICggaXNfcmVhZGFibGUoICRmaWxlcGF0aCApICkgewoJCQkJcmVxdWlyZV9vbmNlICRmaWxlcGF0aDsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIE5vcm1hbGl6ZSBhIG5hbWVzcGFjZSByb290LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJvb3QgTmFtZXNwYWNlIHJvb3QgdGhhdCBuZWVkcyB0byBiZSBub3JtYWxpemVkLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIE5vcm1hbGl6ZWQgbmFtZXNwYWNlIHJvb3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBub3JtYWxpemVfcm9vdCggJHJvb3QgKSB7CgkJJHJvb3QgPSAkdGhpcy0+cmVtb3ZlX2xlYWRpbmdfYmFja3NsYXNoKCAkcm9vdCApOwoKCQlyZXR1cm4gJHRoaXMtPmFkZF90cmFpbGluZ19iYWNrc2xhc2goICRyb290ICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgYSBsZWFkaW5nIGJhY2tzbGFzaCBmcm9tIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBTdHJpbmcgdG8gcmVtb3ZlIHRoZSBsZWFkaW5nIGJhY2tzbGFzaCBmcm9tLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIE1vZGlmaWVkIHN0cmluZy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbW92ZV9sZWFkaW5nX2JhY2tzbGFzaCggJHN0cmluZyApIHsKCQlyZXR1cm4gbHRyaW0oICRzdHJpbmcsICdcXCcgKTsKCX0KCgkvKioKCSAqIE1ha2Ugc3VyZSBhIHN0cmluZyBlbmRzIHdpdGggYSB0cmFpbGluZyBiYWNrc2xhc2guCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyB0byBjaGVjayB0aGUgdHJhaWxpbmcgYmFja3NsYXNoIG9mLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIE1vZGlmaWVkIHN0cmluZy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF90cmFpbGluZ19iYWNrc2xhc2goICRzdHJpbmcgKSB7CgkJcmV0dXJuIHJ0cmltKCAkc3RyaW5nLCAnXFwnICkgLiAnXFwnOwoJfQoKCS8qKgoJICogTWFrZSBzdXJlIGEgc3RyaW5nIGVuZHMgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBTdHJpbmcgdG8gY2hlY2sgdGhlIHRyYWlsaW5nIHNsYXNoIG9mLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIE1vZGlmaWVkIHN0cmluZy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF90cmFpbGluZ19zbGFzaCggJHN0cmluZyApIHsKCQlyZXR1cm4gcnRyaW0oICRzdHJpbmcsICcvXFwnICkgLiAnLyc7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgV1BfQ0xJOwoKLyoqCiAqIEEgQ29tcG9zZXIgSU8gY2xhc3Mgc28gd2UgY2FuIHByb3ZpZGUgc29tZSBsZXZlbCBvZiBpbnRlcmFjdGl2aXR5IGZyb20gV1AtQ0xJCiAqLwpjbGFzcyBDb21wb3NlcklPIGV4dGVuZHMgTnVsbElPIHsKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdyaXRlKCAkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCApIHsKCQlzZWxmOjpvdXRwdXRfY2xlYW5fbWVzc2FnZSggJG1lc3NhZ2VzICk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB3cml0ZUVycm9yKCAkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCApIHsKCQlzZWxmOjpvdXRwdXRfY2xlYW5fbWVzc2FnZSggJG1lc3NhZ2VzICk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gb3V0cHV0X2NsZWFuX21lc3NhZ2UoICRtZXNzYWdlcyApIHsKCQkkbWVzc2FnZXMgPSAoYXJyYXkpIHByZWdfcmVwbGFjZSggJyM8KGh0dHBzPykoW14+XSspPiMnLCAnJDEkMicsICRtZXNzYWdlcyApOwoJCWZvcmVhY2ggKCAkbWVzc2FnZXMgYXMgJG1lc3NhZ2UgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuQWx0ZXJuYXRpdmVGdW5jdGlvbnMuc3RyaXBfdGFnc19zdHJpcF90YWdzCgkJCVdQX0NMSTo6bG9nKCBzdHJpcF90YWdzKCB0cmltKCAkbWVzc2FnZSApICkgKTsKCQl9Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIE11c3Rhbmdvc3RhbmdcU3B5YzsKCi8qKgogKiBIYW5kbGVzIGZpbGUtIGFuZCBydW50aW1lLWJhc2VkIGNvbmZpZ3VyYXRpb24gdmFsdWVzLgogKgogKiBAcGFja2FnZSBXUF9DTEkKICovCmNsYXNzIENvbmZpZ3VyYXRvciB7CgoJLyoqCgkgKiBDb25maWd1cmF0b3IgYXJndW1lbnQgc3BlY2lmaWNhdGlvbi4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJHNwZWM7CgoJLyoqCgkgKiBWYWx1ZXMgZm9yIGtleXMgZGVmaW5lZCBpbiBDb25maWd1cmF0b3Igc3BlYy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGNvbmZpZyA9IFtdOwoKCS8qKgoJICogRXh0cmEgY29uZmlnIHZhbHVlcyBub3Qgc3BlY2lmaWVkIGluIHNwZWMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRleHRyYV9jb25maWcgPSBbXTsKCgkvKioKCSAqIEFueSBhbGlhc2VzIGRlZmluZWQgaW4gY29uZmlnIGZpbGVzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkYWxpYXNlcyA9IFtdOwoKCS8qKgoJICogUmVnZXggcGF0dGVybiB1c2VkIHRvIGRlZmluZSBhbiBhbGlhcy4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBBTElBU19SRUdFWCA9ICdeQFtBLVphLXowLTktX1wuXC1dKyQnOwoKCS8qKgoJICogQXJndW1lbnRzIHRoYXQgY2FuIGJlIHVzZWQgaW4gYW4gYWxpYXMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyAkYWxpYXNfc3BlYyA9IFsKCQkndXNlcicsCgkJJ3VybCcsCgkJJ3BhdGgnLAoJCSdzc2gnLAoJCSdodHRwJywKCV07CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gY29uZmlnIHNwZWMgZmlsZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcGF0aCApIHsKCQkkdGhpcy0+c3BlYyA9IGluY2x1ZGUgJHBhdGg7CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3J1bnRpbWUnICA9PiBmYWxzZSwKCQkJJ2ZpbGUnICAgICA9PiBmYWxzZSwKCQkJJ3N5bm9wc2lzJyA9PiAnJywKCQkJJ2RlZmF1bHQnICA9PiBudWxsLAoJCQknbXVsdGlwbGUnID0+IGZhbHNlLAoJCV07CgoJCWZvcmVhY2ggKCAkdGhpcy0+c3BlYyBhcyAka2V5ID0+ICYkZGV0YWlscyApIHsKCQkJJGRldGFpbHMgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkZGV0YWlscyApOwoKCQkJJHRoaXMtPmNvbmZpZ1sgJGtleSBdID0gJGRldGFpbHNbJ2RlZmF1bHQnXTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgZGVjbGFyZWQgY29uZmlndXJhdGlvbiB2YWx1ZXMgYXMgYW4gYXJyYXkuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gdG9fYXJyYXkoKSB7CgkJcmV0dXJuIFsgJHRoaXMtPmNvbmZpZywgJHRoaXMtPmV4dHJhX2NvbmZpZyBdOwoJfQoKCS8qKgoJICogR2V0IGNvbmZpZ3VyYXRpb24gc3BlY2lmaWNhdGlvbiwgaS5lLiBsaXN0IG9mIGFjY2VwdGVkIGtleXMuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3NwZWMoKSB7CgkJcmV0dXJuICR0aGlzLT5zcGVjOwoJfQoKCS8qKgoJICogR2V0IGFueSBhbGlhc2VzIGRlZmluZWQgaW4gY29uZmlnIGZpbGVzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9hbGlhc2VzKCkgewoJCSRydW50aW1lX2FsaWFzID0gZ2V0ZW52KCAnV1BfQ0xJX1JVTlRJTUVfQUxJQVMnICk7CgkJaWYgKCBmYWxzZSAhPT0gJHJ1bnRpbWVfYWxpYXMgKSB7CgkJCSRyZXR1cm5lZF9hbGlhc2VzID0gW107CgkJCWZvcmVhY2ggKCBqc29uX2RlY29kZSggJHJ1bnRpbWVfYWxpYXMsIHRydWUgKSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCWlmICggcHJlZ19tYXRjaCggJyMnIC4gc2VsZjo6QUxJQVNfUkVHRVggLiAnIycsICRrZXkgKSApIHsKCQkJCQkkcmV0dXJuZWRfYWxpYXNlc1sgJGtleSBdID0gW107CgkJCQkJZm9yZWFjaCAoIHNlbGY6OiRhbGlhc19zcGVjIGFzICRpICkgewoJCQkJCQlpZiAoIGlzc2V0KCAkdmFsdWVbICRpIF0gKSApIHsKCQkJCQkJCSRyZXR1cm5lZF9hbGlhc2VzWyAka2V5IF1bICRpIF0gPSAkdmFsdWVbICRpIF07CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJcmV0dXJuICRyZXR1cm5lZF9hbGlhc2VzOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5hbGlhc2VzOwoJfQoKCS8qKgoJICogU3BsaXRzIGEgbGlzdCBvZiBhcmd1bWVudHMgaW50byBwb3NpdGlvbmFsLCBhc3NvY2lhdGl2ZSBhbmQgY29uZmlnLgoJICoKCSAqIEBwYXJhbSBhcnJheShzdHJpbmcpICRhcmd1bWVudHMKCSAqIEByZXR1cm4gYXJyYXkoYXJyYXkpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXJzZV9hcmdzKCAkYXJndW1lbnRzICkgewoJCWxpc3QoICRwb3NpdGlvbmFsX2FyZ3MsICRtaXhlZF9hcmdzLCAkZ2xvYmFsX2Fzc29jLCAkbG9jYWxfYXNzb2MgKSA9IHNlbGY6OmV4dHJhY3RfYXNzb2MoICRhcmd1bWVudHMgKTsKCQlsaXN0KCAkYXNzb2NfYXJncywgJHJ1bnRpbWVfY29uZmlnICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAkdGhpcy0+dW5taXhfYXNzb2NfYXJncyggJG1peGVkX2FyZ3MsICRnbG9iYWxfYXNzb2MsICRsb2NhbF9hc3NvYyApOwoJCXJldHVybiBbICRwb3NpdGlvbmFsX2FyZ3MsICRhc3NvY19hcmdzLCAkcnVudGltZV9jb25maWcgXTsKCX0KCgkvKioKCSAqIFNwbGl0cyBwb3NpdGlvbmFsIGFyZ3MgZnJvbSBhc3NvY2lhdGl2ZSBhcmdzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJndW1lbnRzCgkgKiBAcmV0dXJuIGFycmF5KGFycmF5KQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3RfYXNzb2MoICRhcmd1bWVudHMgKSB7CgkJJHBvc2l0aW9uYWxfYXJncyA9IFtdOwoJCSRhc3NvY19hcmdzICAgICAgPSBbXTsKCQkkZ2xvYmFsX2Fzc29jICAgID0gW107CgkJJGxvY2FsX2Fzc29jICAgICA9IFtdOwoKCQlmb3JlYWNoICggJGFyZ3VtZW50cyBhcyAkYXJnICkgewoJCQkkcG9zaXRpb25hbF9hcmcgPSBudWxsOwoJCQkkYXNzb2NfYXJnICAgICAgPSBudWxsOwoKCQkJaWYgKCBwcmVnX21hdGNoKCAnfF4tLW5vLShbXj1dKykkfCcsICRhcmcsICRtYXRjaGVzICkgKSB7CgkJCQkkYXNzb2NfYXJnID0gWyAkbWF0Y2hlc1sxXSwgZmFsc2UgXTsKCQkJfSBlbHNlaWYgKCBwcmVnX21hdGNoKCAnfF4tLShbXj1dKykkfCcsICRhcmcsICRtYXRjaGVzICkgKSB7CgkJCQkkYXNzb2NfYXJnID0gWyAkbWF0Y2hlc1sxXSwgdHJ1ZSBdOwoJCQl9IGVsc2VpZiAoIHByZWdfbWF0Y2goICd8Xi0tKFtePV0rKT0oLiopfHMnLCAkYXJnLCAkbWF0Y2hlcyApICkgewoJCQkJJGFzc29jX2FyZyA9IFsgJG1hdGNoZXNbMV0sICRtYXRjaGVzWzJdIF07CgkJCX0gZWxzZSB7CgkJCQkkcG9zaXRpb25hbCA9ICRhcmc7CgkJCX0KCgkJCWlmICggISBpc19udWxsKCAkYXNzb2NfYXJnICkgKSB7CgkJCQkkYXNzb2NfYXJnc1tdID0gJGFzc29jX2FyZzsKCQkJCWlmICggY291bnQoICRwb3NpdGlvbmFsX2FyZ3MgKSApIHsKCQkJCQkkbG9jYWxfYXNzb2NbXSA9ICRhc3NvY19hcmc7CgkJCQl9IGVsc2UgewoJCQkJCSRnbG9iYWxfYXNzb2NbXSA9ICRhc3NvY19hcmc7CgkJCQl9CgkJCX0gZWxzZWlmICggISBpc19udWxsKCAkcG9zaXRpb25hbCApICkgewoJCQkJJHBvc2l0aW9uYWxfYXJnc1tdID0gJHBvc2l0aW9uYWw7CgkJCX0KCQl9CgoJCXJldHVybiBbICRwb3NpdGlvbmFsX2FyZ3MsICRhc3NvY19hcmdzLCAkZ2xvYmFsX2Fzc29jLCAkbG9jYWxfYXNzb2MgXTsKCX0KCgkvKioKCSAqIFNlcGFyYXRlIHJ1bnRpbWUgcGFyYW1ldGVycyBmcm9tIGNvbW1hbmQtc3BlY2lmaWMgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJG1peGVkX2FyZ3MKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiB1bm1peF9hc3NvY19hcmdzKCAkbWl4ZWRfYXJncywgJGdsb2JhbF9hc3NvYyA9IFtdLCAkbG9jYWxfYXNzb2MgPSBbXSApIHsKCQkkYXNzb2NfYXJncyAgICAgPSBbXTsKCQkkcnVudGltZV9jb25maWcgPSBbXTsKCgkJaWYgKCBnZXRlbnYoICdXUF9DTElfU1RSSUNUX0FSR1NfTU9ERScgKSApIHsKCQkJZm9yZWFjaCAoICRnbG9iYWxfYXNzb2MgYXMgJHRtcCApIHsKCQkJCWxpc3QoICRrZXksICR2YWx1ZSApID0gJHRtcDsKCQkJCWlmICggaXNzZXQoICR0aGlzLT5zcGVjWyAka2V5IF0gKSAmJiBmYWxzZSAhPT0gJHRoaXMtPnNwZWNbICRrZXkgXVsncnVudGltZSddICkgewoJCQkJCSR0aGlzLT5hc3NvY19hcmdfdG9fcnVudGltZV9jb25maWcoICRrZXksICR2YWx1ZSwgJHJ1bnRpbWVfY29uZmlnICk7CgkJCQl9CgkJCX0KCQkJZm9yZWFjaCAoICRsb2NhbF9hc3NvYyBhcyAkdG1wICkgewoJCQkJJGFzc29jX2FyZ3NbICR0bXBbMF0gXSA9ICR0bXBbMV07CgkJCX0KCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJG1peGVkX2FyZ3MgYXMgJHRtcCApIHsKCQkJCWxpc3QoICRrZXksICR2YWx1ZSApID0gJHRtcDsKCgkJCQlpZiAoIGlzc2V0KCAkdGhpcy0+c3BlY1sgJGtleSBdICkgJiYgZmFsc2UgIT09ICR0aGlzLT5zcGVjWyAka2V5IF1bJ3J1bnRpbWUnXSApIHsKCQkJCQkkdGhpcy0+YXNzb2NfYXJnX3RvX3J1bnRpbWVfY29uZmlnKCAka2V5LCAkdmFsdWUsICRydW50aW1lX2NvbmZpZyApOwoJCQkJfSBlbHNlIHsKCQkJCQkkYXNzb2NfYXJnc1sgJGtleSBdID0gJHZhbHVlOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gWyAkYXNzb2NfYXJncywgJHJ1bnRpbWVfY29uZmlnIF07Cgl9CgoJLyoqCgkgKiBIYW5kbGUgdHVybmluZyBhbiAkYXNzb2NfYXJnIGludG8gYSBydW50aW1lIGFyZy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhc3NvY19hcmdfdG9fcnVudGltZV9jb25maWcoICRrZXksICR2YWx1ZSwgJiRydW50aW1lX2NvbmZpZyApIHsKCQkkZGV0YWlscyA9ICR0aGlzLT5zcGVjWyAka2V5IF07CgkJaWYgKCBpc3NldCggJGRldGFpbHNbJ2RlcHJlY2F0ZWQnXSApICkgewoJCQlmd3JpdGUoIFNUREVSUiwgIldQLUNMSTogVGhlIC0teyRrZXl9IGdsb2JhbCBwYXJhbWV0ZXIgaXMgZGVwcmVjYXRlZC4geyRkZXRhaWxzWydkZXByZWNhdGVkJ119XG4iICk7CgkJfQoKCQlpZiAoICRkZXRhaWxzWydtdWx0aXBsZSddICkgewoJCQkkcnVudGltZV9jb25maWdbICRrZXkgXVtdID0gJHZhbHVlOwoJCX0gZWxzZSB7CgkJCSRydW50aW1lX2NvbmZpZ1sgJGtleSBdID0gJHZhbHVlOwoJCX0KCX0KCgkvKioKCSAqIExvYWQgYSBZQU1MIGZpbGUgb2YgcGFyYW1ldGVycyBpbnRvIHNjb3BlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBZQU1MIGZpbGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtZXJnZV95bWwoICRwYXRoLCAkY3VycmVudF9hbGlhcyA9IG51bGwgKSB7CgkJJHlhbWwgPSBzZWxmOjpsb2FkX3ltbCggJHBhdGggKTsKCQlpZiAoICEgZW1wdHkoICR5YW1sWydfJ11bJ2luaGVyaXQnXSApICkgewoJCQkkdGhpcy0+bWVyZ2VfeW1sKCAkeWFtbFsnXyddWydpbmhlcml0J10sICRjdXJyZW50X2FsaWFzICk7CgkJfQoJCS8vIFByZXBhcmUgdGhlIGJhc2UgcGF0aCBmb3IgYWJzb2x1dGl6ZWQgYWxpYXMgcGF0aHMuCgkJJHltbF9maWxlX2RpciA9ICRwYXRoID8gZGlybmFtZSggJHBhdGggKSA6IGZhbHNlOwoJCWZvcmVhY2ggKCAkeWFtbCBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAnIycgLiBzZWxmOjpBTElBU19SRUdFWCAuICcjJywgJGtleSApICkgewoJCQkJJHRoaXMtPmFsaWFzZXNbICRrZXkgXSA9IFtdOwoJCQkJJGlzX2FsaWFzICAgICAgICAgICAgICA9IGZhbHNlOwoJCQkJZm9yZWFjaCAoIHNlbGY6OiRhbGlhc19zcGVjIGFzICRpICkgewoJCQkJCWlmICggaXNzZXQoICR2YWx1ZVsgJGkgXSApICkgewoJCQkJCQlpZiAoICdwYXRoJyA9PT0gJGkgJiYgISBpc3NldCggJHZhbHVlWydzc2gnXSApICkgewoJCQkJCQkJc2VsZjo6YWJzb2x1dGl6ZSggJHZhbHVlWyAkaSBdLCAkeW1sX2ZpbGVfZGlyICk7CgkJCQkJCX0KCQkJCQkJJHRoaXMtPmFsaWFzZXNbICRrZXkgXVsgJGkgXSA9ICR2YWx1ZVsgJGkgXTsKCQkJCQkJJGlzX2FsaWFzICAgICAgICAgICAgICAgICAgICA9IHRydWU7CgkJCQkJfQoJCQkJfQoJCQkJLy8gSWYgaXQncyBub3QgYW4gYWxpYXMsIGl0IG1pZ2h0IGJlIGEgZ3JvdXAgb2YgYWxpYXNlcy4KCQkJCWlmICggISAkaXNfYWxpYXMgJiYgaXNfYXJyYXkoICR2YWx1ZSApICkgewoJCQkJCSRhbGlhc19ncm91cCA9IFtdOwoJCQkJCWZvcmVhY2ggKCAkdmFsdWUgYXMgJGsgKSB7CgkJCQkJCWlmICggcHJlZ19tYXRjaCggJyMnIC4gc2VsZjo6QUxJQVNfUkVHRVggLiAnIycsICRrICkgKSB7CgkJCQkJCQkkYWxpYXNfZ3JvdXBbXSA9ICRrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCSR0aGlzLT5hbGlhc2VzWyAka2V5IF0gPSAkYWxpYXNfZ3JvdXA7CgkJCQl9CgkJCX0gZWxzZWlmICggISBpc3NldCggJHRoaXMtPnNwZWNbICRrZXkgXSApIHx8IGZhbHNlID09PSAkdGhpcy0+c3BlY1sgJGtleSBdWydmaWxlJ10gKSB7CgkJCQlpZiAoIGlzc2V0KCAkdGhpcy0+ZXh0cmFfY29uZmlnWyAka2V5IF0gKQoJCQkJCSYmICEgZW1wdHkoICR5YW1sWydfJ11bJ21lcmdlJ10gKQoJCQkJCSYmIGlzX2FycmF5KCAkdGhpcy0+ZXh0cmFfY29uZmlnWyAka2V5IF0gKQoJCQkJCSYmIGlzX2FycmF5KCAkdmFsdWUgKSApIHsKCQkJCQkkdGhpcy0+ZXh0cmFfY29uZmlnWyAka2V5IF0gPSBhcnJheV9tZXJnZSggJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJGtleSBdLCAkdmFsdWUgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJGtleSBdID0gJHZhbHVlOwoJCQkJfQoJCQl9IGVsc2VpZiAoICR0aGlzLT5zcGVjWyAka2V5IF1bJ211bHRpcGxlJ10gKSB7CgkJCQlzZWxmOjphcnJheWlmeSggJHZhbHVlICk7CgkJCQkkdGhpcy0+Y29uZmlnWyAka2V5IF0gPSBhcnJheV9tZXJnZSggJHRoaXMtPmNvbmZpZ1sgJGtleSBdLCAkdmFsdWUgKTsKCQkJfSBlbHNlIHsKCQkJCWlmICggJGN1cnJlbnRfYWxpYXMgJiYgaW5fYXJyYXkoICRrZXksIHNlbGY6OiRhbGlhc19zcGVjLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkdGhpcy0+Y29uZmlnWyAka2V5IF0gPSAkdmFsdWU7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBNZXJnZSBhbiBhcnJheSBvZiB2YWx1ZXMgaW50byB0aGUgY29uZmlndXJhdG9yIGNvbmZpZy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZwoJICovCglwdWJsaWMgZnVuY3Rpb24gbWVyZ2VfYXJyYXkoICRjb25maWcgKSB7CgkJZm9yZWFjaCAoICR0aGlzLT5zcGVjIGFzICRrZXkgPT4gJGRldGFpbHMgKSB7CgkJCWlmICggZmFsc2UgIT09ICRkZXRhaWxzWydydW50aW1lJ10gJiYgaXNzZXQoICRjb25maWdbICRrZXkgXSApICkgewoJCQkJJHZhbHVlID0gJGNvbmZpZ1sgJGtleSBdOwoKCQkJCWlmICggJ3JlcXVpcmUnID09PSAka2V5ICkgewoJCQkJCSR2YWx1ZSA9IFV0aWxzXGV4cGFuZF9nbG9icyggJHZhbHVlICk7CgkJCQl9CgoJCQkJaWYgKCAkZGV0YWlsc1snbXVsdGlwbGUnXSApIHsKCQkJCQlzZWxmOjphcnJheWlmeSggJHZhbHVlICk7CgkJCQkJJHRoaXMtPmNvbmZpZ1sgJGtleSBdID0gYXJyYXlfbWVyZ2UoICR0aGlzLT5jb25maWdbICRrZXkgXSwgJHZhbHVlICk7CgkJCQl9IGVsc2UgewoJCQkJCSR0aGlzLT5jb25maWdbICRrZXkgXSA9ICR2YWx1ZTsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvKioKCSAqIExvYWQgdmFsdWVzIGZyb20gYSBZQU1MIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkeW1sX2ZpbGUgUGF0aCB0byB0aGUgWUFNTCBmaWxlCgkgKiBAcmV0dXJuIGFycmF5IERlY2xhcmVkIGNvbmZpZ3VyYXRpb24gdmFsdWVzCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGxvYWRfeW1sKCAkeW1sX2ZpbGUgKSB7CgkJaWYgKCAhICR5bWxfZmlsZSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJGNvbmZpZyA9IFNweWM6OllBTUxMb2FkKCAkeW1sX2ZpbGUgKTsKCgkJLy8gTWFrZSBzdXJlIGNvbmZpZy1maWxlLXJlbGF0aXZlIHBhdGhzIGFyZSBtYWRlIGFic29sdXRlLgoJCSR5bWxfZmlsZV9kaXIgPSBkaXJuYW1lKCAkeW1sX2ZpbGUgKTsKCgkJaWYgKCBpc3NldCggJGNvbmZpZ1sncGF0aCddICkgKSB7CgkJCXNlbGY6OmFic29sdXRpemUoICRjb25maWdbJ3BhdGgnXSwgJHltbF9maWxlX2RpciApOwoJCX0KCgkJaWYgKCBpc3NldCggJGNvbmZpZ1sncmVxdWlyZSddICkgKSB7CgkJCXNlbGY6OmFycmF5aWZ5KCAkY29uZmlnWydyZXF1aXJlJ10gKTsKCQkJJGNvbmZpZ1sncmVxdWlyZSddID0gVXRpbHNcZXhwYW5kX2dsb2JzKCAkY29uZmlnWydyZXF1aXJlJ10gKTsKCQkJZm9yZWFjaCAoICRjb25maWdbJ3JlcXVpcmUnXSBhcyAmJHBhdGggKSB7CgkJCQlzZWxmOjphYnNvbHV0aXplKCAkcGF0aCwgJHltbF9maWxlX2RpciApOwoJCQl9CgkJfQoKCQkvLyBCYWNrd2FyZHMgY29tcGF0CgkJLy8gQ29tbWFuZCAnY29yZSBjb25maWcnIHdhcyBtb3ZlZCB0byAnY29uZmlnIGNyZWF0ZScuCgkJaWYgKCBpc3NldCggJGNvbmZpZ1snY29yZSBjb25maWcnXSApICkgewoJCQkkY29uZmlnWydjb25maWcgY3JlYXRlJ10gPSAkY29uZmlnWydjb3JlIGNvbmZpZyddOwoJCQl1bnNldCggJGNvbmZpZ1snY29yZSBjb25maWcnXSApOwoJCX0KCQkvLyBDb21tYW5kICdjaGVja3N1bSBjb3JlJyB3YXMgbW92ZWQgdG8gJ2NvcmUgdmVyaWZ5LWNoZWNrc3VtcycuCgkJaWYgKCBpc3NldCggJGNvbmZpZ1snY2hlY2tzdW0gY29yZSddICkgKSB7CgkJCSRjb25maWdbJ2NvcmUgdmVyaWZ5LWNoZWNrc3VtcyddID0gJGNvbmZpZ1snY2hlY2tzdW0gY29yZSddOwoJCQl1bnNldCggJGNvbmZpZ1snY2hlY2tzdW0gY29yZSddICk7CgkJfQoJCS8vIENvbW1hbmQgJ2NoZWNrc3VtIHBsdWdpbicgd2FzIG1vdmVkIHRvICdwbHVnaW4gdmVyaWZ5LWNoZWNrc3VtcycuCgkJaWYgKCBpc3NldCggJGNvbmZpZ1snY2hlY2tzdW0gcGx1Z2luJ10gKSApIHsKCQkJJGNvbmZpZ1sncGx1Z2luIHZlcmlmeS1jaGVja3N1bXMnXSA9ICRjb25maWdbJ2NoZWNrc3VtIHBsdWdpbiddOwoJCQl1bnNldCggJGNvbmZpZ1snY2hlY2tzdW0gcGx1Z2luJ10gKTsKCQl9CgoJCXJldHVybiAkY29uZmlnOwoJfQoKCS8qKgoJICogQ29uZm9ybSBhIHZhcmlhYmxlIHRvIGFuIGFycmF5LgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkdmFsIEEgc3RyaW5nIG9yIGFuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGFycmF5aWZ5KCAmJHZhbCApIHsKCQkkdmFsID0gKGFycmF5KSAkdmFsOwoJfQoKCS8qKgoJICogTWFrZSBhIHBhdGggYWJzb2x1dGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIGZpbGUuCgkgKiBAcGFyYW0gc3RyaW5nICRiYXNlIEJhc2UgcGF0aCB0byBwcmVwZW5kLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBhYnNvbHV0aXplKCAmJHBhdGgsICRiYXNlICkgewoJCWlmICggISBlbXB0eSggJHBhdGggKSAmJiAhIFV0aWxzXGlzX3BhdGhfYWJzb2x1dGUoICRwYXRoICkgKSB7CgkJCSRwYXRoID0gJGJhc2UgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJHBhdGg7CgkJfQoJfQoKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgRGVjbGFyZUZhbGxiYWNrRnVuY3Rpb25zLgogKgogKiBEZWNsYXJlcyBmdW5jdGlvbnMgdGhhdCBtaWdodCBoYXZlIGJlZW4gZGlzYWJsZWQgYnV0IGFyZSByZXF1aXJlZC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgRGVjbGFyZUZhbGxiYWNrRnVuY3Rpb25zIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJaW5jbHVkZSBfX0RJUl9fIC4gJy8uLi8uLi9mYWxsYmFjay1mdW5jdGlvbnMucGhwJzsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgSW5pdGlhbGl6ZUNvbG9yaXphdGlvbi4KICoKICogSW5pdGlhbGl6ZSB0aGUgY29sb3JpemF0aW9uIHRocm91Z2ggdGhlIGBXUF9DTElcUnVubmVyYCBvYmplY3QuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIEluaXRpYWxpemVDb2xvcml6YXRpb24gaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoJCSRydW5uZXIoKS0+aW5pdF9jb2xvcml6YXRpb24oKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgRGVjbGFyZU1haW5DbGFzcy4KICoKICogRGVjbGFyZXMgdGhlIG1haW4gYFdQX0NMSWAgY2xhc3MuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIERlY2xhcmVNYWluQ2xhc3MgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvY2xhc3Mtd3AtY2xpLnBocCc7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBJbmNsdWRlRmFsbGJhY2tBdXRvbG9hZGVyLgogKgogKiBMb2FkcyB0aGUgZmFsbGJhY2sgYXV0b2xvYWRlciB0aGF0IGlzIHByb3ZpZGVkIHRocm91Z2ggdGhlIGBjb21wb3Nlci5qc29uYAogKiBmaWxlLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBJbmNsdWRlRmFsbGJhY2tBdXRvbG9hZGVyIGV4dGVuZHMgQXV0b2xvYWRlclN0ZXAgewoKCS8qKgoJICogR2V0IHRoZSBhdXRvbG9hZGVyIHBhdGhzIHRvIHNjYW4gZm9yIGFuIGF1dG9sb2FkZXIuCgkgKgoJICogQHJldHVybiBzdHJpbmdbXXxmYWxzZSBBcnJheSBvZiBzdHJpbmdzIHdpdGggYXV0b2xvYWRlciBwYXRocywgb3IgZmFsc2UKCSAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gc2tpcC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9hdXRvbG9hZGVyX3BhdGhzKCkgewoJCSRhdXRvbG9hZGVyX3BhdGhzID0gWwoJCQlXUF9DTElfVkVORE9SX0RJUiAuICcvYXV0b2xvYWQucGhwJywKCQldOwoKCQkkY3VzdG9tX3ZlbmRvciA9ICR0aGlzLT5nZXRfY3VzdG9tX3ZlbmRvcl9mb2xkZXIoKTsKCQlpZiAoIGZhbHNlICE9PSAkY3VzdG9tX3ZlbmRvciApIHsKCQkJYXJyYXlfdW5zaGlmdCgKCQkJCSRhdXRvbG9hZGVyX3BhdGhzLAoJCQkJV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uLycgLiAkY3VzdG9tX3ZlbmRvciAuICcvYXV0b2xvYWQucGhwJwoJCQkpOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZygKCQkJc3ByaW50ZigKCQkJCSdGYWxsYmFjayBhdXRvbG9hZGVyIHBhdGhzOiAlcycsCgkJCQlpbXBsb2RlKCAnLCAnLCAkYXV0b2xvYWRlcl9wYXRocyApCgkJCSksCgkJCSdib290c3RyYXAnCgkJKTsKCgkJcmV0dXJuICRhdXRvbG9hZGVyX3BhdGhzOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCnVzZSBEaXJlY3RvcnlJdGVyYXRvcjsKCi8qKgogKiBDbGFzcyBJbml0aWFsaXplTG9nZ2VyLgogKgogKiBJbml0aWFsaXplIHRoZSBsb2dnZXIgdGhyb3VnaCB0aGUgYFdQX0NMSVxSdW5uZXJgIG9iamVjdC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgSW5pdGlhbGl6ZUxvZ2dlciBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkdGhpcy0+ZGVjbGFyZV9sb2dnZXJzKCk7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoJCSRydW5uZXIoKS0+aW5pdF9sb2dnZXIoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIGNsYXNzIGRlY2xhcmF0aW9ucyBmb3IgdGhlIGxvZ2dlcnMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZGVjbGFyZV9sb2dnZXJzKCkgewoJCSRsb2dnZXJfZGlyID0gV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvTG9nZ2Vycyc7CgkJJGl0ZXJhdG9yICAgPSBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRsb2dnZXJfZGlyICk7CgoJCS8vIE1ha2Ugc3VyZSB0aGUgYmFzZSBjbGFzcyBpcyBkZWNsYXJlZCBmaXJzdC4KCQlpbmNsdWRlX29uY2UgIiRsb2dnZXJfZGlyL0Jhc2UucGhwIjsKCgkJZm9yZWFjaCAoICRpdGVyYXRvciBhcyAkZmlsZW5hbWUgKSB7CgkJCWlmICggJy5waHAnICE9PSBzdWJzdHIoICRmaWxlbmFtZSwgLSA0ICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaW5jbHVkZV9vbmNlICIkbG9nZ2VyX2Rpci8kZmlsZW5hbWUiOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgQ29uZmlndXJlUnVubmVyLgogKgogKiBJbml0aWFsaXplIHRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgYFdQX0NMSVxSdW5uZXJgIG9iamVjdC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgQ29uZmlndXJlUnVubmVyIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCSRydW5uZXIgPSBuZXcgUnVubmVySW5zdGFuY2UoKTsKCQkkcnVubmVyKCktPmluaXRfY29uZmlnKCk7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIERpcmVjdG9yeUl0ZXJhdG9yOwp1c2UgRXhjZXB0aW9uOwp1c2UgV1BfQ0xJOwoKLyoqCiAqIENsYXNzIFJlZ2lzdGVyRnJhbWV3b3JrQ29tbWFuZHMuCiAqCiAqIFJlZ2lzdGVyIHRoZSBjb21tYW5kcyB0aGF0IGFyZSBkaXJlY3RseSBpbmNsdWRlZCB3aXRoIHRoZSBmcmFtZXdvcmsuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIFJlZ2lzdGVyRnJhbWV3b3JrQ29tbWFuZHMgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJJGNtZF9kaXIgPSBXUF9DTElfUk9PVCAuICcvcGhwL2NvbW1hbmRzJzsKCgkJJGl0ZXJhdG9yID0gbmV3IERpcmVjdG9yeUl0ZXJhdG9yKCAkY21kX2RpciApOwoKCQlmb3JlYWNoICggJGl0ZXJhdG9yIGFzICRmaWxlbmFtZSApIHsKCQkJaWYgKCAnLnBocCcgIT09IHN1YnN0ciggJGZpbGVuYW1lLCAtIDQgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQl0cnkgewoJCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCQlzcHJpbnRmKAoJCQkJCQknQWRkaW5nIGZyYW1ld29yayBjb21tYW5kOiAlcycsCgkJCQkJCSIkY21kX2Rpci8kZmlsZW5hbWUiCgkJCQkJKSwKCQkJCQknYm9vdHN0cmFwJwoJCQkJKTsKCgkJCQlpbmNsdWRlX29uY2UgIiRjbWRfZGlyLyRmaWxlbmFtZSI7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkiQ291bGQgbm90IGFkZCBjb21tYW5kIHskY21kX2Rpcn0veyRmaWxlbmFtZX0uIFJlYXNvbjogIiAuICRleGNlcHRpb24tPmdldE1lc3NhZ2UoKQoJCQkJKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgQm9vdHN0cmFwU3RhdGUuCiAqCiAqIFJlcHJlc2VudHMgdGhlIHN0YXRlIHRoYXQgaXMgcGFzc2VkIGZyb20gb25lIGJvb3RzdHJhcCBzdGVwIHRvIHRoZSBuZXh0LgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqCiAqIE1haW50YWluIEJDOiBDaGFuZ2luZyB0aGUgbWV0aG9kIG5hbWVzIGluIHRoaXMgY2xhc3MgYnJlYWtzIGF1dG9sb2FkIGludGVyYWN0aW9ucyBiZXR3ZWVuIFBoYXIKICogJiBmcmFtZXdvcmsvY29tbWFuZHMgeW91IHVzZSBvdXRzaWRlIG9mIFBoYXIgKGxpa2Ugd2hlbiBydW5uaW5nIHRoZSBQaGFyIFdQIGluc2lkZSBvZiBhIGNvbW1hbmQgZm9sZGVyKS4KICogQHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkRnVuY3Rpb25OYW1lLk1ldGhvZE5hbWVJbnZhbGlkCiAqLwpjbGFzcyBCb290c3RyYXBTdGF0ZSB7CgoJLyoqCgkgKiBXaGV0aGVyIHRoZSBjb21tYW5kIGN1cnJlbnRseSBiZWluZyBydW4gaXMgInByb3RlY3RlZCIuCgkgKgoJICogVGhpcyBtZWFucyB0aGF0IHRoZSBjb21tYW5kIHNob3VsZCBub3QgYmUgYWxsb3dlZCB0byBicmVhayBkdWUgdG8KCSAqIGV4dGVuc2lvbiBjb2RlLgoJICovCgljb25zdCBJU19QUk9URUNURURfQ09NTUFORCA9ICdpc19wcm90ZWN0ZWRfY29tbWFuZCc7CgoJLyoqCgkgKiBJbnRlcm5hbCBzdG9yYWdlIG9mIHRoZSBzdGF0ZSB2YWx1ZXMuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRzdGF0ZSA9IFtdOwoKCS8qKgoJICogR2V0IHRoZSBzdGF0ZSB2YWx1ZSBmb3IgYSBnaXZlbiBrZXkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5ICAgICAgS2V5IHRvIGdldCB0aGUgc3RhdGUgZnJvbS4KCSAqIEBwYXJhbSBtaXhlZCAgJGZhbGxiYWNrIEZhbGxiYWNrIHZhbHVlIHRvIHVzZSBpZiB0aGUga2V5IGlzIG5vdCBkZWZpbmVkLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlKCAka2V5LCAkZmFsbGJhY2sgPSBudWxsICkgewoJCXJldHVybiBhcnJheV9rZXlfZXhpc3RzKCAka2V5LCAkdGhpcy0+c3RhdGUgKQoJCQk/ICR0aGlzLT5zdGF0ZVsgJGtleSBdCgkJCTogJGZhbGxiYWNrOwoJfQoKCS8qKgoJICogU2V0IHRoZSBzdGF0ZSB2YWx1ZSBmb3IgYSBnaXZlbiBrZXkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5ICAgS2V5IHRvIHNldCB0aGUgc3RhdGUgZm9yLgoJICogQHBhcmFtIG1peGVkICAkdmFsdWUgVmFsdWUgdG8gc2V0IHRoZSBzdGF0ZSBmb3IgdGhlIGdpdmVuIGtleSB0by4KCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCAka2V5LCAkdmFsdWUgKSB7CgkJJHRoaXMtPnN0YXRlWyAka2V5IF0gPSAkdmFsdWU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBDbGFzcyBSZWdpc3RlckRlZmVycmVkQ29tbWFuZHMuCiAqCiAqIFJlZ2lzdGVycyB0aGUgZGVmZXJyZWQgY29tbWFuZHMgdGhhdCBmb3Igd2hpY2ggbm8gcGFyZW50IHdhcyByZWdpc3RlcmVkIHlldC4KICogVGhpcyBpcyBuZWNlc3NhcnksIGJlY2F1c2Ugd2UgY2FuIGhhdmUgc3ViLWNvbW1hbmRzIHRoYXQgaGF2ZSBubyBkaXJlY3QKICogcGFyZW50LCBsaWtlIGB3cCBuZXR3b3JrIG1ldGFgLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBSZWdpc3RlckRlZmVycmVkQ29tbWFuZHMgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgoJCS8vIFByb2Nlc3MgZGVmZXJyZWQgY29tbWFuZCBhZGRpdGlvbnMgZm9yIGV4dGVybmFsIHBhY2thZ2VzLgoJCSR0aGlzLT5hZGRfZGVmZXJyZWRfY29tbWFuZHMoKTsKCgkJLy8gUHJvY2VzcyBkZWZlcnJlZCBjb21tYW5kIGFkZGl0aW9ucyBmb3IgY29tbWFuZHMgYWRkZWQgdGhyb3VnaAoJCS8vIHBsdWdpbnMuCgkJV1BfQ0xJOjphZGRfaG9vaygKCQkJJ2JlZm9yZV9ydW5fY29tbWFuZCcsCgkJCVsgJHRoaXMsICdhZGRfZGVmZXJyZWRfY29tbWFuZHMnIF0KCQkpOwoKCQlyZXR1cm4gJHN0YXRlOwoJfQoKCS8qKgoJICogQWRkIGRlZmVycmVkIGNvbW1hbmRzIHRoYXQgYXJlIHN0aWxsIHdhaXRpbmcgdG8gYmUgcHJvY2Vzc2VkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX2RlZmVycmVkX2NvbW1hbmRzKCkgewoJCSRkZWZlcnJlZF9hZGRpdGlvbnMgPSBXUF9DTEk6OmdldF9kZWZlcnJlZF9hZGRpdGlvbnMoKTsKCgkJZm9yZWFjaCAoICRkZWZlcnJlZF9hZGRpdGlvbnMgYXMgJG5hbWUgPT4gJGFkZGl0aW9uICkgewoJCQkkYWRkaXRpb25fZGF0YSA9IFtdOwoJCQlmb3JlYWNoICggJGFkZGl0aW9uIGFzICRhZGRpdGlvbl9rZXkgPT4gJGFkZGl0aW9uX3ZhbHVlICkgewoJCQkJLy8gRGVzY3JpYmUgdGhlIGNhbGxhYmxlIGFzIGEgc3RyaW5nIGluc3RlYWQgb2YgZGlyZWN0bHkgcHJpbnRpbmcgaXQKCQkJCS8vIGZvciBiZXR0ZXIgZGVidWcgaW5mby4KCQkJCWlmICggJ2NhbGxhYmxlJyA9PT0gJGFkZGl0aW9uX2tleSApIHsKCQkJCQkkYWRkaXRpb25fdmFsdWUgPSBVdGlsc1xkZXNjcmliZV9jYWxsYWJsZSggJGFkZGl0aW9uX3ZhbHVlICk7CgoJCQkJfSBlbHNlaWYgKCBpc19hcnJheSggJGFkZGl0aW9uX3ZhbHVlICkgKSB7CgkJCQkJJGFkZGl0aW9uX3ZhbHVlID0ganNvbl9lbmNvZGUoICRhZGRpdGlvbl92YWx1ZSApOwoJCQkJfQoKCQkJCSRhZGRpdGlvbl9kYXRhW10gPSBzcHJpbnRmKAoJCQkJCSclczogJXMnLAoJCQkJCSRhZGRpdGlvbl9rZXksCgkJCQkJJGFkZGl0aW9uX3ZhbHVlCgkJCQkpOwoJCQl9CgoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknQWRkaW5nIGRlZmVycmVkIGNvbW1hbmQ6ICVzICglcyknLAoJCQkJCSRuYW1lLAoJCQkJCWltcGxvZGUoICcsICcsICRhZGRpdGlvbl9kYXRhICkKCQkJCSksCgkJCQknYm9vdHN0cmFwJwoJCQkpOwoKCQkJV1BfQ0xJOjphZGRfY29tbWFuZCgKCQkJCSRuYW1lLAoJCQkJJGFkZGl0aW9uWydjYWxsYWJsZSddLAoJCQkJJGFkZGl0aW9uWydhcmdzJ10KCQkJKTsKCQl9Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxSdW5uZXI7CgovKioKICogQ2xhc3MgUnVubmVySW5zdGFuY2UuCiAqCiAqIENvbnZlbmllbmNlIGNsYXNzIGZvciBzdGVwcyB0aGF0IG1ha2UgdXNlIG9mIHRoZSBgV1BfQ0xJXFJ1bm5lcmAgb2JqZWN0LgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBSdW5uZXJJbnN0YW5jZSB7CgoJLyoqCgkgKiBSZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIGBXUF9DTElcUnVubmVyYCBvYmplY3QuCgkgKgoJICogSW5jbHVkZXMgbmVjZXNzYXJ5IGNsYXNzIGZpbGVzIGZpcnN0IGFzIG5lZWRlZC4KCSAqCgkgKiBAcmV0dXJuIFJ1bm5lcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoKSB7CgkJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSVxSdW5uZXInICkgKSB7CgkJCXJlcXVpcmVfb25jZSBXUF9DTElfUk9PVCAuICcvcGhwL1dQX0NMSS9SdW5uZXIucGhwJzsKCQl9CgoJCWlmICggISBjbGFzc19leGlzdHMoICdXUF9DTElcQ29uZmlndXJhdG9yJyApICkgewoJCQlyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9XUF9DTEkvQ29uZmlndXJhdG9yLnBocCc7CgkJfQoKCQlyZXR1cm4gV1BfQ0xJOjpnZXRfcnVubmVyKCk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBJbmNsdWRlUGFja2FnZUF1dG9sb2FkZXIuCiAqCiAqIExvYWRzIHRoZSBwYWNrYWdlIGF1dG9sb2FkZXIgdGhhdCBpbmNsdWRlcyBhbGwgdGhlIGV4dGVybmFsIHBhY2thZ2VzLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBJbmNsdWRlUGFja2FnZUF1dG9sb2FkZXIgZXh0ZW5kcyBBdXRvbG9hZGVyU3RlcCB7CgoJLyoqCgkgKiBHZXQgdGhlIGF1dG9sb2FkZXIgcGF0aHMgdG8gc2NhbiBmb3IgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdfGZhbHNlIEFycmF5IG9mIHN0cmluZ3Mgd2l0aCBhdXRvbG9hZGVyIHBhdGhzLCBvciBmYWxzZQoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBza2lwLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dG9sb2FkZXJfcGF0aHMoKSB7CgkJaWYgKCAkdGhpcy0+c3RhdGUtPmdldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIGZhbHNlICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRydW5uZXIgICAgICAgID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJJHNraXBfcGFja2FnZXMgPSAkcnVubmVyKCktPmNvbmZpZ1snc2tpcC1wYWNrYWdlcyddOwoJCWlmICggdHJ1ZSA9PT0gJHNraXBfcGFja2FnZXMgKSB7CgkJCVdQX0NMSTo6ZGVidWcoICdTa2lwcGVkIGxvYWRpbmcgcGFja2FnZXMuJywgJ2Jvb3RzdHJhcCcgKTsKCgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRhdXRvbG9hZGVyX3BhdGggPSAkcnVubmVyKCktPmdldF9wYWNrYWdlc19kaXJfcGF0aCgpIC4gJ3ZlbmRvci9hdXRvbG9hZC5waHAnOwoKCQlpZiAoIGlzX3JlYWRhYmxlKCAkYXV0b2xvYWRlcl9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQknTG9hZGluZyBwYWNrYWdlcyBmcm9tOiAnIC4gJGF1dG9sb2FkZXJfcGF0aCwKCQkJCSdib290c3RyYXAnCgkJCSk7CgoJCQlyZXR1cm4gWwoJCQkJJGF1dG9sb2FkZXJfcGF0aCwKCQkJXTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEhhbmRsZSB0aGUgZmFpbHVyZSB0byBmaW5kIGFuIGF1dG9sb2FkZXIuCgkgKgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVfZmFpbHVyZSgpIHsKCQlXUF9DTEk6OmRlYnVnKCAnTm8gcGFja2FnZSBhdXRvbG9hZCBmb3VuZCB0byBsb2FkLicsICdib290c3RyYXAnICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyBBdXRvbG9hZGVyU3RlcC4KICoKICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3Igc3RlcHMgdGhhdCBpbmNsdWRlIGFuIGF1dG9sb2FkZXIuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmFic3RyYWN0IGNsYXNzIEF1dG9sb2FkZXJTdGVwIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBTdG9yZSBzdGF0ZSBmb3Igc3ViY2xhc3NlcyB0byBoYXZlIGFjY2Vzcy4KCSAqCgkgKiBAdmFyIEJvb3RzdHJhcFN0YXRlCgkgKi8KCXByb3RlY3RlZCAkc3RhdGU7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCSR0aGlzLT5zdGF0ZSA9ICRzdGF0ZTsKCgkJJGZvdW5kX2F1dG9sb2FkZXIgPSBmYWxzZTsKCQkkYXV0b2xvYWRlcl9wYXRocyA9ICR0aGlzLT5nZXRfYXV0b2xvYWRlcl9wYXRocygpOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b2xvYWRlcl9wYXRocyApIHsKCQkJLy8gU2tpcCB0aGlzIGF1dG9sb2FkaW5nIHN0ZXAuCgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQlmb3JlYWNoICggJGF1dG9sb2FkZXJfcGF0aHMgYXMgJGF1dG9sb2FkZXJfcGF0aCApIHsKCQkJaWYgKCBpc19yZWFkYWJsZSggJGF1dG9sb2FkZXJfcGF0aCApICkgewoJCQkJdHJ5IHsKCQkJCQlXUF9DTEk6OmRlYnVnKAoJCQkJCQlzcHJpbnRmKAoJCQkJCQkJJ0xvYWRpbmcgZGV0ZWN0ZWQgYXV0b2xvYWRlcjogJXMnLAoJCQkJCQkJJGF1dG9sb2FkZXJfcGF0aAoJCQkJCQkpLAoJCQkJCQknYm9vdHN0cmFwJwoJCQkJCSk7CgkJCQkJcmVxdWlyZSAkYXV0b2xvYWRlcl9wYXRoOwoJCQkJCSRmb3VuZF9hdXRvbG9hZGVyID0gdHJ1ZTsKCQkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJCSJGYWlsZWQgdG8gbG9hZCBhdXRvbG9hZGVyICd7JGF1dG9sb2FkZXJfcGF0aH0nLiBSZWFzb246ICIKCQkJCQkJLiAkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCQkpOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICEgJGZvdW5kX2F1dG9sb2FkZXIgKSB7CgkJCSR0aGlzLT5oYW5kbGVfZmFpbHVyZSgpOwoJCX0KCgkJcmV0dXJuICR0aGlzLT5zdGF0ZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbmFtZSBvZiB0aGUgY3VzdG9tIHZlbmRvciBmb2xkZXIgYXMgc2V0IGluIGBjb21wb3Nlci5qc29uYC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBOYW1lIG9mIHRoZSBjdXN0b20gdmVuZG9yIGZvbGRlciBvciBmYWxzZSBpZiBub25lLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2N1c3RvbV92ZW5kb3JfZm9sZGVyKCkgewoJCSRtYXliZV9jb21wb3Nlcl9qc29uID0gV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uL2NvbXBvc2VyLmpzb24nOwoJCWlmICggISBpc19yZWFkYWJsZSggJG1heWJlX2NvbXBvc2VyX2pzb24gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJGNvbXBvc2VyID0ganNvbl9kZWNvZGUoIGZpbGVfZ2V0X2NvbnRlbnRzKCAkbWF5YmVfY29tcG9zZXJfanNvbiApICk7CgoJCWlmICggISBlbXB0eSggJGNvbXBvc2VyLT5jb25maWcgKQoJCQkmJiAhIGVtcHR5KCAkY29tcG9zZXItPmNvbmZpZy0+eyd2ZW5kb3ItZGlyJ30gKQoJCSkgewoJCQlyZXR1cm4gJGNvbXBvc2VyLT5jb25maWctPnsndmVuZG9yLWRpcid9OwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogSGFuZGxlIHRoZSBmYWlsdXJlIHRvIGZpbmQgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHZvaWQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGhhbmRsZV9mYWlsdXJlKCkgeyB9CgoJLyoqCgkgKiBHZXQgdGhlIGF1dG9sb2FkZXIgcGF0aHMgdG8gc2NhbiBmb3IgYW4gYXV0b2xvYWRlci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ1tdfGZhbHNlIEFycmF5IG9mIHN0cmluZ3Mgd2l0aCBhdXRvbG9hZGVyIHBhdGhzLCBvciBmYWxzZQoJICogICAgICAgICAgICAgICAgICAgICAgICB0byBza2lwLgoJICovCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dG9sb2FkZXJfcGF0aHMoKTsKfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogSW50ZXJmYWNlIEJvb3RzdHJhcFN0ZXAuCiAqCiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwIHRoYXQgY2FuIGJlIHByb2Nlc3NlZC4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KaW50ZXJmYWNlIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApOwp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCi8qKgogKiBDbGFzcyBEZWNsYXJlQWJzdHJhY3RCYXNlQ29tbWFuZC4KICoKICogRGVjbGFyZXMgdGhlIGFic3RyYWN0IGBXUF9DTElfQ29tbWFuZGAgYmFzZSBjbGFzcy4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgRGVjbGFyZUFic3RyYWN0QmFzZUNvbW1hbmQgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvY2xhc3Mtd3AtY2xpLWNvbW1hbmQucGhwJzsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7Cgp1c2UgV1BfQ0xJXEF1dG9sb2FkZXI7CgovKioKICogQ2xhc3MgSW5jbHVkZUZyYW1ld29ya0F1dG9sb2FkZXIuCiAqCiAqIExvYWRzIHRoZSBmcmFtZXdvcmsgYXV0b2xvYWRlciB0aHJvdWdoIGFuIGF1dG9sYW9kZXIgc2VwYXJhdGUgZnJvbSB0aGUKICogQ29tcG9zZXIgb25lLCB0byBhdm9pZCBjb3VwbGluZyB0aGUgbG9hZGluZyBvZiB0aGUgZnJhbWV3b3JrIHdpdGggYnVuZGxlZAogKiBjb21tYW5kcy4KICoKICogVGhpcyBvbmx5IGNvbnRhaW5zIGNsYXNzZXMgZm9yIHRoZSBmcmFtZXdvcmsuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIEluY2x1ZGVGcmFtZXdvcmtBdXRvbG9hZGVyIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCWlmICggISBjbGFzc19leGlzdHMoICdXUF9DTElcQXV0b2xvYWRlcicgKSApIHsKCQkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvV1BfQ0xJL0F1dG9sb2FkZXIucGhwJzsKCQl9CgoJCSRhdXRvbG9hZGVyID0gbmV3IEF1dG9sb2FkZXIoKTsKCgkJJG1hcHBpbmdzID0gWwoJCQknV1BfQ0xJJyAgICAgICAgICAgICAgICAgICA9PiBXUF9DTElfUk9PVCAuICcvcGhwL1dQX0NMSScsCgkJCSdjbGknICAgICAgICAgICAgICAgICAgICAgID0+IFdQX0NMSV9WRU5ET1JfRElSIC4gJy93cC1jbGkvcGhwLWNsaS10b29scy9saWIvY2xpJywKCQkJJ1JlcXVlc3RzJyAgICAgICAgICAgICAgICAgPT4gV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3JtY2N1ZS9yZXF1ZXN0cy9saWJyYXJ5L1JlcXVlc3RzJywKCQkJJ1N5bWZvbnlcQ29tcG9uZW50XEZpbmRlcicgPT4gV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3N5bWZvbnkvZmluZGVyLycsCgkJXTsKCgkJZm9yZWFjaCAoICRtYXBwaW5ncyBhcyAkbmFtZXNwYWNlID0+ICRmb2xkZXIgKSB7CgkJCSRhdXRvbG9hZGVyLT5hZGRfbmFtZXNwYWNlKAoJCQkJJG5hbWVzcGFjZSwKCQkJCSRmb2xkZXIKCQkJKTsKCQl9CgoJCWluY2x1ZGVfb25jZSBXUF9DTElfVkVORE9SX0RJUiAuICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMucGhwJzsKCQlpbmNsdWRlX29uY2UgV1BfQ0xJX1ZFTkRPUl9ESVIgLiAnL3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMvU3B5Yy5waHAnOwoKCQkkYXV0b2xvYWRlci0+cmVnaXN0ZXIoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgTGF1bmNoUnVubmVyLgogKgogKiBLaWNrIG9mZiB0aGUgUnVubmVyIG9iamVjdCB0aGF0IHN0YXJ0cyB0aGUgYWN0dWFsIGNvbW1hbmRzLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBMYXVuY2hSdW5uZXIgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJJHJ1bm5lciA9IG5ldyBSdW5uZXJJbnN0YW5jZSgpOwoJCSRydW5uZXIoKS0+c3RhcnQoKTsKCgkJcmV0dXJuICRzdGF0ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxCb290c3RyYXA7CgovKioKICogQ2xhc3MgTG9hZFV0aWxpdHlGdW5jdGlvbnMuCiAqCiAqIExvYWRzIHRoZSBmdW5jdGlvbnMgYXZhaWxhYmxlIHRocm91Z2ggYFdQX0NMSVxVdGlsc2AuCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIExvYWRVdGlsaXR5RnVuY3Rpb25zIGltcGxlbWVudHMgQm9vdHN0cmFwU3RlcCB7CgoJLyoqCgkgKiBQcm9jZXNzIHRoaXMgc2luZ2xlIGJvb3RzdHJhcHBpbmcgc3RlcC4KCSAqCgkgKiBAcGFyYW0gQm9vdHN0cmFwU3RhdGUgJHN0YXRlIENvbnRleHR1YWwgc3RhdGUgdG8gcGFzcyBpbnRvIHRoZSBzdGVwLgoJICoKCSAqIEByZXR1cm4gQm9vdHN0cmFwU3RhdGUgTW9kaWZpZWQgc3RhdGUgdG8gcGFzcyB0byB0aGUgbmV4dCBzdGVwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcHJvY2VzcyggQm9vdHN0cmFwU3RhdGUgJHN0YXRlICkgewoJCXJlcXVpcmVfb25jZSBXUF9DTElfUk9PVCAuICcvcGhwL3V0aWxzLnBocCc7CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBDbGFzcyBMb2FkUmVxdWlyZWRDb21tYW5kLgogKgogKiBMb2FkcyBhIGNvbW1hbmQgdGhhdCB3YXMgcGFzc2VkIHRocm91Z2ggdGhlIGAtLXJlcXVpcmU9PGNvbW1hbmQ+YCBvcHRpb24uCiAqCiAqIEBwYWNrYWdlIFdQX0NMSVxCb290c3RyYXAKICovCmZpbmFsIGNsYXNzIExvYWRSZXF1aXJlZENvbW1hbmQgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJaWYgKCAkc3RhdGUtPmdldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIGZhbHNlICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQkkcnVubmVyID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJaWYgKCAhIGlzc2V0KCAkcnVubmVyKCktPmNvbmZpZ1sncmVxdWlyZSddICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQlmb3JlYWNoICggJHJ1bm5lcigpLT5jb25maWdbJ3JlcXVpcmUnXSBhcyAkcGF0aCApIHsKCQkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkcGF0aCApICkgewoJCQkJJGNvbnRleHQgICAgICAgID0gJyc7CgkJCQkkcmVxdWlyZWRfZmlsZXMgPSAkcnVubmVyKCktPmdldF9yZXF1aXJlZF9maWxlcygpOwoJCQkJZm9yZWFjaCAoIFsgJ2dsb2JhbCcsICdwcm9qZWN0JywgJ3J1bnRpbWUnIF0gYXMgJHNjb3BlICkgewoJCQkJCWlmICggaW5fYXJyYXkoICRwYXRoLCAkcmVxdWlyZWRfZmlsZXNbICRzY29wZSBdLCB0cnVlICkgKSB7CgkJCQkJCXN3aXRjaCAoICRzY29wZSApIHsKCQkJCQkJCWNhc2UgJ2dsb2JhbCc6CgkJCQkJCQkJJGNvbnRleHQgPSAnIChmcm9tIGdsb2JhbCAnIC4gVXRpbHNcYmFzZW5hbWUoICRydW5uZXIoKS0+Z2V0X2dsb2JhbF9jb25maWdfcGF0aCgpICkgLiAnKSc7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdwcm9qZWN0JzoKCQkJCQkJCQkkY29udGV4dCA9ICcgKGZyb20gcHJvamVjdFwncyAnIC4gVXRpbHNcYmFzZW5hbWUoICRydW5uZXIoKS0+Z2V0X3Byb2plY3RfY29uZmlnX3BhdGgoKSApIC4gJyknOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAncnVudGltZSc6CgkJCQkJCQkJJGNvbnRleHQgPSAnIChmcm9tIHJ1bnRpbWUgYXJndW1lbnQpJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiUmVxdWlyZWQgZmlsZSAnJXMnIGRvZXNuJ3QgZXhpc3Qlcy4iLCBVdGlsc1xiYXNlbmFtZSggJHBhdGggKSwgJGNvbnRleHQgKSApOwoJCQl9CgkJCVV0aWxzXGxvYWRfZmlsZSggJHBhdGggKTsKCQkJV1BfQ0xJOjpkZWJ1ZyggJ1JlcXVpcmVkIGZpbGUgZnJvbSBjb25maWc6ICcgLiAkcGF0aCwgJ2Jvb3RzdHJhcCcgKTsKCQl9CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBDbGFzcyBMb2FkRXh0cmFDb21tYW5kLgogKgogKiBMb2FkcyBhIGNvbW1hbmQgdGhhdCB3YXMgcGFzc2VkIHRocm91Z2ggdGhlIGAtLWV4ZWM9PHBocC1jb2RlPmAgb3B0aW9uLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBMb2FkRXhlY0NvbW1hbmQgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJaWYgKCAkc3RhdGUtPmdldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIGZhbHNlICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQkkcnVubmVyID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgkJaWYgKCAhIGlzc2V0KCAkcnVubmVyKCktPmNvbmZpZ1snZXhlYyddICkgKSB7CgkJCXJldHVybiAkc3RhdGU7CgkJfQoKCQlmb3JlYWNoICggJHJ1bm5lcigpLT5jb25maWdbJ2V4ZWMnXSBhcyAkcGhwX2NvZGUgKSB7CgkJCWV2YWwoICRwaHBfY29kZSApOyAvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQKCQl9CgoJCXJldHVybiAkc3RhdGU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQm9vdHN0cmFwOwoKLyoqCiAqIENsYXNzIExvYWREaXNwYXRjaGVyLgogKgogKiBMb2FkcyB0aGUgZGlzcGF0Y2hlciB0aGF0IHdpbGwgZGlzcGF0Y2ggY29tbWFuZCBuYW1lcyB0byBmaWxlIGxvY2F0aW9ucy4KICoKICogQHBhY2thZ2UgV1BfQ0xJXEJvb3RzdHJhcAogKi8KZmluYWwgY2xhc3MgTG9hZERpc3BhdGNoZXIgaW1wbGVtZW50cyBCb290c3RyYXBTdGVwIHsKCgkvKioKCSAqIFByb2Nlc3MgdGhpcyBzaW5nbGUgYm9vdHN0cmFwcGluZyBzdGVwLgoJICoKCSAqIEBwYXJhbSBCb290c3RyYXBTdGF0ZSAkc3RhdGUgQ29udGV4dHVhbCBzdGF0ZSB0byBwYXNzIGludG8gdGhlIHN0ZXAuCgkgKgoJICogQHJldHVybiBCb290c3RyYXBTdGF0ZSBNb2RpZmllZCBzdGF0ZSB0byBwYXNzIHRvIHRoZSBuZXh0IHN0ZXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKCBCb290c3RyYXBTdGF0ZSAkc3RhdGUgKSB7CgkJcmVxdWlyZV9vbmNlIFdQX0NMSV9ST09UIC4gJy9waHAvZGlzcGF0Y2hlci5waHAnOwoKCQlyZXR1cm4gJHN0YXRlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEJvb3RzdHJhcDsKCi8qKgogKiBDbGFzcyBEZWZpbmVQcm90ZWN0ZWRDb21tYW5kcy4KICoKICogRGVmaW5lIHRoZSBjb21tYW5kcyB0aGF0IGFyZSAicHJvdGVjdGVkIiwgbWVhbmluZyB0aGF0IHRoZXkgc2hvdWxkbid0IGJlIGFibGUKICogdG8gYnJlYWsgZHVlIHRvIGV4dGVuc2lvbiBjb2RlLgogKgogKiBAcGFja2FnZSBXUF9DTElcQm9vdHN0cmFwCiAqLwpmaW5hbCBjbGFzcyBEZWZpbmVQcm90ZWN0ZWRDb21tYW5kcyBpbXBsZW1lbnRzIEJvb3RzdHJhcFN0ZXAgewoKCS8qKgoJICogUHJvY2VzcyB0aGlzIHNpbmdsZSBib290c3RyYXBwaW5nIHN0ZXAuCgkgKgoJICogQHBhcmFtIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSBDb250ZXh0dWFsIHN0YXRlIHRvIHBhc3MgaW50byB0aGUgc3RlcC4KCSAqCgkgKiBAcmV0dXJuIEJvb3RzdHJhcFN0YXRlIE1vZGlmaWVkIHN0YXRlIHRvIHBhc3MgdG8gdGhlIG5leHQgc3RlcC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3MoIEJvb3RzdHJhcFN0YXRlICRzdGF0ZSApIHsKCQkkY29tbWFuZHMgICAgICAgID0gJHRoaXMtPmdldF9wcm90ZWN0ZWRfY29tbWFuZHMoKTsKCQkkY3VycmVudF9jb21tYW5kID0gJHRoaXMtPmdldF9jdXJyZW50X2NvbW1hbmQoKTsKCgkJZm9yZWFjaCAoICRjb21tYW5kcyBhcyAkY29tbWFuZCApIHsKCQkJaWYgKCAwID09PSBzdHJwb3MoICRjdXJyZW50X2NvbW1hbmQsICRjb21tYW5kICkgKSB7CgkJCQkkc3RhdGUtPnNldFZhbHVlKCBCb290c3RyYXBTdGF0ZTo6SVNfUFJPVEVDVEVEX0NPTU1BTkQsIHRydWUgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRzdGF0ZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbGlzdCBvZiBwcm90ZWN0ZWQgY29tbWFuZHMuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wcm90ZWN0ZWRfY29tbWFuZHMoKSB7CgkJcmV0dXJuIFsKCQkJJ2NsaSBpbmZvJywKCQkJJ3BhY2thZ2UnLAoJCV07Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGN1cnJlbnQgY29tbWFuZCBhcyBhIHN0cmluZy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBDdXJyZW50IGNvbW1hbmQgdG8gYmUgZXhlY3V0ZWQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2N1cnJlbnRfY29tbWFuZCgpIHsKCQkkcnVubmVyID0gbmV3IFJ1bm5lckluc3RhbmNlKCk7CgoJCXJldHVybiBpbXBsb2RlKCAnICcsIChhcnJheSkgJHJ1bm5lcigpLT5hcmd1bWVudHMgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUnVsZTsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudFN1YnNjcmliZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudHM7CnVzZSBXUF9DTEk7CgovKioKICogQSBDb21wb3NlciBFdmVudCBzdWJzY3JpYmVyIHNvIHdlIGNhbiBrZWVwIHRyYWNrIG9mIHdoYXQncyBoYXBwZW5pbmcgaW5zaWRlIENvbXBvc2VyCiAqLwpjbGFzcyBQYWNrYWdlTWFuYWdlckV2ZW50U3Vic2NyaWJlciBpbXBsZW1lbnRzIEV2ZW50U3Vic2NyaWJlckludGVyZmFjZSB7CgoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTdWJzY3JpYmVkRXZlbnRzKCkgewoKCQlyZXR1cm4gWwoJCQlQYWNrYWdlRXZlbnRzOjpQUkVfUEFDS0FHRV9JTlNUQUxMICA9PiAncHJlX2luc3RhbGwnLAoJCQlQYWNrYWdlRXZlbnRzOjpQT1NUX1BBQ0tBR0VfSU5TVEFMTCA9PiAncG9zdF9pbnN0YWxsJywKCQldOwoJfQoKCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJlX2luc3RhbGwoIFBhY2thZ2VFdmVudCAkZXZlbnQgKSB7CgkJJG9wZXJhdGlvbl9tZXNzYWdlID0gJGV2ZW50LT5nZXRPcGVyYXRpb24oKS0+X190b1N0cmluZygpOwoJCVdQX0NMSTo6bG9nKCAnIC0gJyAuICRvcGVyYXRpb25fbWVzc2FnZSApOwoJfQoKCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcG9zdF9pbnN0YWxsKCBQYWNrYWdlRXZlbnQgJGV2ZW50ICkgewoKCQkkb3BlcmF0aW9uID0gJGV2ZW50LT5nZXRPcGVyYXRpb24oKTsKCgkJLy8gZ2V0UmVhc29uKCkgd2FzIHJlbW92ZWQgaW4gQ29tcG9zZXIgdjIgd2l0aG91dCByZXBsYWNlbWVudC4KCQlpZiAoICEgbWV0aG9kX2V4aXN0cyggJG9wZXJhdGlvbiwgJ2dldFJlYXNvbicgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHJlYXNvbiA9ICRvcGVyYXRpb24tPmdldFJlYXNvbigpOwoJCWlmICggJHJlYXNvbiBpbnN0YW5jZW9mIFJ1bGUgKSB7CgoJCQlzd2l0Y2ggKCAkcmVhc29uLT5nZXRSZWFzb24oKSApIHsKCgkJCQljYXNlIFJ1bGU6OlJVTEVfUEFDS0FHRV9DT05GTElDVDoKCQkJCWNhc2UgUnVsZTo6UlVMRV9QQUNLQUdFX1NBTUVfTkFNRToKCQkJCWNhc2UgUnVsZTo6UlVMRV9QQUNLQUdFX1JFUVVJUkVTOgoJCQkJCSRjb21wb3Nlcl9lcnJvciA9ICRyZWFzb24tPmdldFByZXR0eVN0cmluZyggJGV2ZW50LT5nZXRQb29sKCkgKTsKCQkJCQlicmVhazsKCgkJCX0KCgkJCWlmICggISBlbXB0eSggJGNvbXBvc2VyX2Vycm9yICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJyAtIFdhcm5pbmc6ICVzJywgJGNvbXBvc2VyX2Vycm9yICkgKTsKCQkJfQoJCX0KCgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIEV4Y2VwdGlvbjsKCmNsYXNzIEV4aXRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24ge30KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXI7CnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21wb3NpdGVDb21tYW5kOwp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcU3ViY29tbWFuZDsKdXNlIFdQX0NMSVxGZXRjaGVyczsKdXNlIFdQX0NMSVxJdGVyYXRvcnNcRXhjZXB0aW9uOwp1c2UgV1BfQ0xJXExvZ2dlcnM7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9FcnJvcjsKCi8qKgogKiBQZXJmb3JtcyB0aGUgZXhlY3V0aW9uIG9mIGEgY29tbWFuZC4KICoKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICRnbG9iYWxfY29uZmlnX3BhdGgKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICRwcm9qZWN0X2NvbmZpZ19wYXRoCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAkY29uZmlnCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAkZXh0cmFfY29uZmlnCiAqIEBwcm9wZXJ0eS1yZWFkIHN0cmluZyAkYWxpYXMKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICRhbGlhc2VzCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAkYXJndW1lbnRzCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAkYXNzb2NfYXJncwogKiBAcHJvcGVydHktcmVhZCBhcnJheSAgJHJ1bnRpbWVfY29uZmlnCiAqIEBwcm9wZXJ0eS1yZWFkIGJvb2wgICAkY29sb3JpemUKICogQHByb3BlcnR5LXJlYWQgYXJyYXkgICRlYXJseV9pbnZva2UKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICRnbG9iYWxfY29uZmlnX3BhdGhfZGVidWcKICogQHByb3BlcnR5LXJlYWQgc3RyaW5nICRwcm9qZWN0X2NvbmZpZ19wYXRoX2RlYnVnCiAqIEBwcm9wZXJ0eS1yZWFkIGFycmF5ICAkcmVxdWlyZWRfZmlsZXMKICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBSdW5uZXIgewoKCXByaXZhdGUgJGdsb2JhbF9jb25maWdfcGF0aDsKCXByaXZhdGUgJHByb2plY3RfY29uZmlnX3BhdGg7CgoJcHJpdmF0ZSAkY29uZmlnOwoJcHJpdmF0ZSAkZXh0cmFfY29uZmlnOwoKCXByaXZhdGUgJGFsaWFzOwoKCXByaXZhdGUgJGFsaWFzZXM7CgoJcHJpdmF0ZSAkYXJndW1lbnRzOwoJcHJpdmF0ZSAkYXNzb2NfYXJnczsKCXByaXZhdGUgJHJ1bnRpbWVfY29uZmlnOwoKCXByaXZhdGUgJGNvbG9yaXplID0gZmFsc2U7CgoJcHJpdmF0ZSAkZWFybHlfaW52b2tlID0gW107CgoJcHJpdmF0ZSAkZ2xvYmFsX2NvbmZpZ19wYXRoX2RlYnVnOwoKCXByaXZhdGUgJHByb2plY3RfY29uZmlnX3BhdGhfZGVidWc7CgoJcHJpdmF0ZSAkcmVxdWlyZWRfZmlsZXM7CgoJcHVibGljIGZ1bmN0aW9uIF9fZ2V0KCAka2V5ICkgewoJCWlmICggJ18nID09PSAka2V5WzBdICkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAkdGhpcy0+JGtleTsKCX0KCgkvKioKCSAqIFJlZ2lzdGVyIGEgY29tbWFuZCBmb3IgZWFybHkgaW52b2NhdGlvbiwgZ2VuZXJhbGx5IGJlZm9yZSBXb3JkUHJlc3MgbG9hZHMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd2hlbiBOYW1lZCBleGVjdXRpb24gaG9vawoJICogQHBhcmFtIFN1YmNvbW1hbmQgJGNvbW1hbmQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyX2Vhcmx5X2ludm9rZSggJHdoZW4sICRjb21tYW5kICkgewoJCSR0aGlzLT5lYXJseV9pbnZva2VbICR3aGVuIF1bXSA9IGFycmF5X3NsaWNlKCBEaXNwYXRjaGVyXGdldF9wYXRoKCAkY29tbWFuZCApLCAxICk7Cgl9CgoJLyoqCgkgKiBQZXJmb3JtIHRoZSBlYXJseSBpbnZvY2F0aW9uIG9mIGEgY29tbWFuZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR3aGVuIE5hbWVkIGV4ZWN1dGlvbiBob29rCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZG9fZWFybHlfaW52b2tlKCAkd2hlbiApIHsKCQlpZiAoICEgaXNzZXQoICR0aGlzLT5lYXJseV9pbnZva2VbICR3aGVuIF0gKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gU2VhcmNoIHRoZSB2YWx1ZSBvZiBAd2hlbiBmcm9tIHRoZSBjb21tYW5kIG1ldGhvZC4KCQkkcmVhbF93aGVuID0gJyc7CgkJJHIgICAgICAgICA9ICR0aGlzLT5maW5kX2NvbW1hbmRfdG9fcnVuKCAkdGhpcy0+YXJndW1lbnRzICk7CgkJaWYgKCBpc19hcnJheSggJHIgKSApIHsKCQkJbGlzdCggJGNvbW1hbmQsICRmaW5hbF9hcmdzLCAkY21kX3BhdGggKSA9ICRyOwoKCQkJZm9yZWFjaCAoICR0aGlzLT5lYXJseV9pbnZva2UgYXMgJF93aGVuID0+ICRfcGF0aCApIHsKCQkJCWZvcmVhY2ggKCAkX3BhdGggYXMgJGNtZCApIHsKCQkJCQlpZiAoICRjbWQgPT09ICRjbWRfcGF0aCApIHsKCQkJCQkJJHJlYWxfd2hlbiA9ICRfd2hlbjsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkdGhpcy0+ZWFybHlfaW52b2tlWyAkd2hlbiBdIGFzICRwYXRoICkgewoJCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoICRwYXRoICkgKSB7CgkJCQlpZiAoIGVtcHR5KCAkcmVhbF93aGVuICkgfHwgKCAkcmVhbF93aGVuICYmICRyZWFsX3doZW4gPT09ICR3aGVuICkgKSB7CgkJCQkJJHRoaXMtPnJ1bl9jb21tYW5kX2FuZF9leGl0KCk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHBhdGggdG8gdGhlIGdsb2JhbCBjb25maWd1cmF0aW9uIFlBTUwgZmlsZS4KCSAqCgkgKiBAcGFyYW0gYm9vbCAkY3JlYXRlX2NvbmZpZ19maWxlIE9wdGlvbmFsLiBJZiBhIGNvbmZpZyBmaWxlIGRvZXNuJ3QgZXhpc3QsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBpdCBiZSBjcmVhdGVkPyBEZWZhdWx0cyB0byBmYWxzZS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2dsb2JhbF9jb25maWdfcGF0aCggJGNyZWF0ZV9jb25maWdfZmlsZSA9IGZhbHNlICkgewoKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKSApIHsKCQkJJGNvbmZpZ19wYXRoICAgICAgICAgICAgICAgICAgICA9IGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKTsKCQkJJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aF9kZWJ1ZyA9ICdVc2luZyBnbG9iYWwgY29uZmlnIGZyb20gV1BfQ0xJX0NPTkZJR19QQVRIIGVudiB2YXI6ICcgLiAkY29uZmlnX3BhdGg7CgkJfSBlbHNlIHsKCQkJJGNvbmZpZ19wYXRoICAgICAgICAgICAgICAgICAgICA9IFV0aWxzXGdldF9ob21lX2RpcigpIC4gJy8ud3AtY2xpL2NvbmZpZy55bWwnOwoJCQkkdGhpcy0+Z2xvYmFsX2NvbmZpZ19wYXRoX2RlYnVnID0gJ1VzaW5nIGRlZmF1bHQgZ2xvYmFsIGNvbmZpZzogJyAuICRjb25maWdfcGF0aDsKCQl9CgoJCS8vIElmIGdsb2JhbCBjb25maWcgZG9lc24ndCBleGlzdCBjcmVhdGUgb25lLgoJCWlmICggdHJ1ZSA9PT0gJGNyZWF0ZV9jb25maWdfZmlsZSAmJiAhIGZpbGVfZXhpc3RzKCAkY29uZmlnX3BhdGggKSApIHsKCQkJJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aF9kZWJ1ZyA9ICJEZWZhdWx0IGdsb2JhbCBjb25maWcgZG9lc24ndCBleGlzdCwgY3JlYXRpbmcgb25lIGluIHskY29uZmlnX3BhdGh9IjsKCQkJUHJvY2Vzczo6Y3JlYXRlKCBVdGlsc1xlc2NfY21kKCAndG91Y2ggJXMnLCAkY29uZmlnX3BhdGggKSApLT5ydW4oKTsKCQl9CgoJCWlmICggaXNfcmVhZGFibGUoICRjb25maWdfcGF0aCApICkgewoJCQlyZXR1cm4gJGNvbmZpZ19wYXRoOwoJCX0KCgkJJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aF9kZWJ1ZyA9ICdObyByZWFkYWJsZSBnbG9iYWwgY29uZmlnIGZvdW5kJzsKCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogR2V0IHRoZSBwYXRoIHRvIHRoZSBwcm9qZWN0LXNwZWNpZmljIGNvbmZpZ3VyYXRpb24KCSAqIFlBTUwgZmlsZS4KCSAqIHdwLWNsaS5sb2NhbC55bWwgdGFrZXMgcHJpb3JpdHkgb3ZlciB3cC1jbGkueW1sLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcHJvamVjdF9jb25maWdfcGF0aCgpIHsKCQkkY29uZmlnX2ZpbGVzID0gWwoJCQknd3AtY2xpLmxvY2FsLnltbCcsCgkJCSd3cC1jbGkueW1sJywKCQldOwoKCQkvLyBTdG9wIGxvb2tpbmcgdXB3YXJkIHdoZW4gd2UgZmluZCB3ZSBoYXZlIGVtZXJnZWQgZnJvbSBhIHN1YmRpcmVjdG9yeQoJCS8vIGluc3RhbGxhdGlvbiBpbnRvIGEgcGFyZW50IGluc3RhbGxhdGlvbgoJCSRwcm9qZWN0X2NvbmZpZ19wYXRoID0gVXRpbHNcZmluZF9maWxlX3Vwd2FyZCgKCQkJJGNvbmZpZ19maWxlcywKCQkJZ2V0Y3dkKCksCgkJCXN0YXRpYyBmdW5jdGlvbiAoICRkaXIgKSB7CgkJCQlzdGF0aWMgJHdwX2xvYWRfY291bnQgPSAwOwoJCQkJJHdwX2xvYWRfcGF0aCAgICAgICAgID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAnd3AtbG9hZC5waHAnOwoJCQkJaWYgKCBmaWxlX2V4aXN0cyggJHdwX2xvYWRfcGF0aCApICkgewoJCQkJCSsrICR3cF9sb2FkX2NvdW50OwoJCQkJfQoJCQkJcmV0dXJuICR3cF9sb2FkX2NvdW50ID4gMTsKCQkJfQoJCSk7CgoJCSR0aGlzLT5wcm9qZWN0X2NvbmZpZ19wYXRoX2RlYnVnID0gJ05vIHByb2plY3QgY29uZmlnIGZvdW5kJzsKCgkJaWYgKCAhIGVtcHR5KCAkcHJvamVjdF9jb25maWdfcGF0aCApICkgewoJCQkkdGhpcy0+cHJvamVjdF9jb25maWdfcGF0aF9kZWJ1ZyA9ICdVc2luZyBwcm9qZWN0IGNvbmZpZzogJyAuICRwcm9qZWN0X2NvbmZpZ19wYXRoOwoJCX0KCgkJcmV0dXJuICRwcm9qZWN0X2NvbmZpZ19wYXRoOwoJfQoKCS8qKgoJICogR2V0IHRoZSBwYXRoIHRvIHRoZSBwYWNrYWdlcyBkaXJlY3RvcnkKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3BhY2thZ2VzX2Rpcl9wYXRoKCkgewoJCWlmICggZ2V0ZW52KCAnV1BfQ0xJX1BBQ0tBR0VTX0RJUicgKSApIHsKCQkJJHBhY2thZ2VzX2RpciA9IFV0aWxzXHRyYWlsaW5nc2xhc2hpdCggZ2V0ZW52KCAnV1BfQ0xJX1BBQ0tBR0VTX0RJUicgKSApOwoJCX0gZWxzZSB7CgkJCSRwYWNrYWdlc19kaXIgPSBVdGlsc1xnZXRfaG9tZV9kaXIoKSAuICcvLndwLWNsaS9wYWNrYWdlcy8nOwoJCX0KCQlyZXR1cm4gJHBhY2thZ2VzX2RpcjsKCX0KCgkvKioKCSAqIEF0dGVtcHRzIHRvIGZpbmQgdGhlIHBhdGggdG8gdGhlIFdQIGluc3RhbGxhdGlvbiBpbnNpZGUgaW5kZXgucGhwCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaW5kZXhfcGF0aAoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdF9zdWJkaXJfcGF0aCggJGluZGV4X3BhdGggKSB7CgkJJGluZGV4X2NvZGUgPSBmaWxlX2dldF9jb250ZW50cyggJGluZGV4X3BhdGggKTsKCgkJaWYgKCAhIHByZWdfbWF0Y2goICd8XlxzKnJlcXVpcmVccypcKD9ccyooLis/KS93cC1ibG9nLWhlYWRlclwucGhwKFtcJyJdKXxtJywgJGluZGV4X2NvZGUsICRtYXRjaGVzICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR3cF9wYXRoX3NyYyA9ICRtYXRjaGVzWzFdIC4gJG1hdGNoZXNbMl07CgkJJHdwX3BhdGhfc3JjID0gVXRpbHNccmVwbGFjZV9wYXRoX2NvbnN0cyggJHdwX3BhdGhfc3JjLCAkaW5kZXhfcGF0aCApOwoKCQkkd3BfcGF0aCA9IGV2YWwoICJyZXR1cm4gJHdwX3BhdGhfc3JjOyIgKTsgLy8gcGhwY3M6aWdub3JlIFNxdWl6LlBIUC5FdmFsLkRpc2NvdXJhZ2VkCgoJCWlmICggISBVdGlsc1xpc19wYXRoX2Fic29sdXRlKCAkd3BfcGF0aCApICkgewoJCQkkd3BfcGF0aCA9IGRpcm5hbWUoICRpbmRleF9wYXRoICkgLiAiLyR3cF9wYXRoIjsKCQl9CgoJCXJldHVybiAkd3BfcGF0aDsKCX0KCgkvKioKCSAqIEZpbmQgdGhlIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIHRoZSBXb3JkUHJlc3MgZmlsZXMuCgkgKiBEZWZhdWx0cyB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBBbiBhYnNvbHV0ZSBwYXRoCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZmluZF93cF9yb290KCkgewoJCWlmICggISBlbXB0eSggJHRoaXMtPmNvbmZpZ1sncGF0aCddICkgKSB7CgkJCSRwYXRoID0gJHRoaXMtPmNvbmZpZ1sncGF0aCddOwoJCQlpZiAoICEgVXRpbHNcaXNfcGF0aF9hYnNvbHV0ZSggJHBhdGggKSApIHsKCQkJCSRwYXRoID0gZ2V0Y3dkKCkgLiAnLycgLiAkcGF0aDsKCQkJfQoKCQkJcmV0dXJuICRwYXRoOwoJCX0KCgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjb3JlJywgJ2Rvd25sb2FkJyBdICkgKSB7CgkJCXJldHVybiBnZXRjd2QoKTsKCQl9CgoJCSRkaXIgPSBnZXRjd2QoKTsKCgkJd2hpbGUgKCBpc19yZWFkYWJsZSggJGRpciApICkgewoJCQlpZiAoIGZpbGVfZXhpc3RzKCAiJGRpci93cC1sb2FkLnBocCIgKSApIHsKCQkJCXJldHVybiAkZGlyOwoJCQl9CgoJCQlpZiAoIGZpbGVfZXhpc3RzKCAiJGRpci9pbmRleC5waHAiICkgKSB7CgkJCQkkcGF0aCA9IHNlbGY6OmV4dHJhY3Rfc3ViZGlyX3BhdGgoICIkZGlyL2luZGV4LnBocCIgKTsKCQkJCWlmICggISBlbXB0eSggJHBhdGggKSApIHsKCQkJCQlyZXR1cm4gJHBhdGg7CgkJCQl9CgkJCX0KCgkJCSRwYXJlbnRfZGlyID0gZGlybmFtZSggJGRpciApOwoJCQlpZiAoIGVtcHR5KCAkcGFyZW50X2RpciApIHx8ICRwYXJlbnRfZGlyID09PSAkZGlyICkgewoJCQkJYnJlYWs7CgkJCX0KCQkJJGRpciA9ICRwYXJlbnRfZGlyOwoJCX0KCX0KCgkvKioKCSAqIFNldCBXb3JkUHJlc3Mgcm9vdCBhcyBhIGdpdmVuIHBhdGguCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aAoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzZXRfd3Bfcm9vdCggJHBhdGggKSB7CgkJaWYgKCAhIGRlZmluZWQoICdBQlNQQVRIJyApICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIERlY2xhcmluZyBhIFdQIG5hdGl2ZSBjb25zdGFudC4KCQkJZGVmaW5lKCAnQUJTUEFUSCcsIFV0aWxzXG5vcm1hbGl6ZV9wYXRoKCBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoICRwYXRoICkgKSApOwoJCX0gZWxzZWlmICggISBpc19udWxsKCAkcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yX211bHRpX2xpbmUoCgkJCQlbCgkJCQkJJ1RoZSAtLXBhdGggcGFyYW1ldGVyIGNhbm5vdCBiZSB1c2VkIHdoZW4gQUJTUEFUSCBpcyBhbHJlYWR5IGRlZmluZWQgZWxzZXdoZXJlJywKCQkJCQknQUJTUEFUSCBpcyBkZWZpbmVkIGFzOiAiJyAuIEFCU1BBVEggLiAnIicsCgkJCQldCgkJCSk7CgkJfQoJCVdQX0NMSTo6ZGVidWcoICdBQlNQQVRIIGRlZmluZWQ6ICcgLiBBQlNQQVRILCAnYm9vdHN0cmFwJyApOwoKCQkkX1NFUlZFUlsnRE9DVU1FTlRfUk9PVCddID0gcmVhbHBhdGgoICRwYXRoICk7Cgl9CgoJLyoqCgkgKiBHdWVzcyB3aGljaCBVUkwgY29udGV4dCBXUC1DTEkgaGFzIGJlZW4gaW52b2tlZCB1bmRlci4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGd1ZXNzX3VybCggJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2Jsb2cnXSApICkgewoJCQkkYXNzb2NfYXJnc1sndXJsJ10gPSAkYXNzb2NfYXJnc1snYmxvZyddOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3VybCddICkgKSB7CgkJCSR1cmwgPSAkYXNzb2NfYXJnc1sndXJsJ107CgoJCQlpZiAoIHRydWUgPT09ICR1cmwgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdUaGUgLS11cmwgcGFyYW1ldGVyIGV4cGVjdHMgYSB2YWx1ZS4nICk7CgkJCX0KCgkJCXJldHVybiAkdXJsOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY21kX3N0YXJ0c193aXRoKCAkcHJlZml4ICkgewoJCXJldHVybiBhcnJheV9zbGljZSggJHRoaXMtPmFyZ3VtZW50cywgMCwgY291bnQoICRwcmVmaXggKSApID09PSAkcHJlZml4OwoJfQoKCS8qKgoJICogR2l2ZW4gcG9zaXRpb25hbCBhcmd1bWVudHMsIGZpbmQgdGhlIGNvbW1hbmQgdG8gZXhlY3V0ZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEByZXR1cm4gYXJyYXl8c3RyaW5nIENvbW1hbmQsIGFyZ3MsIGFuZCBwYXRoIG9uIHN1Y2Nlc3M7IGVycm9yIG1lc3NhZ2Ugb24gZmFpbHVyZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZmluZF9jb21tYW5kX3RvX3J1biggJGFyZ3MgKSB7CgkJJGNvbW1hbmQgPSBXUF9DTEk6OmdldF9yb290X2NvbW1hbmQoKTsKCgkJV1BfQ0xJOjpkb19ob29rKCAnZmluZF9jb21tYW5kX3RvX3J1bl9wcmUnICk7CgoJCSRjbWRfcGF0aCA9IFtdOwoKCQl3aGlsZSAoICEgZW1wdHkoICRhcmdzICkgJiYgJGNvbW1hbmQtPmNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgKSB7CgkJCSRjbWRfcGF0aFtdID0gJGFyZ3NbMF07CgkJCSRmdWxsX25hbWUgID0gaW1wbG9kZSggJyAnLCAkY21kX3BhdGggKTsKCgkJCSRzdWJjb21tYW5kID0gJGNvbW1hbmQtPmZpbmRfc3ViY29tbWFuZCggJGFyZ3MgKTsKCgkJCWlmICggISAkc3ViY29tbWFuZCApIHsKCQkJCWlmICggY291bnQoICRjbWRfcGF0aCApID4gMSApIHsKCQkJCQkkY2hpbGQgICAgICAgPSBhcnJheV9wb3AoICRjbWRfcGF0aCApOwoJCQkJCSRwYXJlbnRfbmFtZSA9IGltcGxvZGUoICcgJywgJGNtZF9wYXRoICk7CgkJCQkJJHN1Z2dlc3Rpb24gID0gJHRoaXMtPmdldF9zdWJjb21tYW5kX3N1Z2dlc3Rpb24oICRjaGlsZCwgJGNvbW1hbmQgKTsKCQkJCQlyZXR1cm4gc3ByaW50ZigKCQkJCQkJIiclcycgaXMgbm90IGEgcmVnaXN0ZXJlZCBzdWJjb21tYW5kIG9mICclcycuIFNlZSAnd3AgaGVscCAlcycgZm9yIGF2YWlsYWJsZSBzdWJjb21tYW5kcy4lcyIsCgkJCQkJCSRjaGlsZCwKCQkJCQkJJHBhcmVudF9uYW1lLAoJCQkJCQkkcGFyZW50X25hbWUsCgkJCQkJCSEgZW1wdHkoICRzdWdnZXN0aW9uICkgPyBQSFBfRU9MIC4gIkRpZCB5b3UgbWVhbiAneyRzdWdnZXN0aW9ufSc/IiA6ICcnCgkJCQkJKTsKCQkJCX0KCgkJCQkkc3VnZ2VzdGlvbiA9ICR0aGlzLT5nZXRfc3ViY29tbWFuZF9zdWdnZXN0aW9uKCAkZnVsbF9uYW1lLCAkY29tbWFuZCApOwoKCQkJCXJldHVybiBzcHJpbnRmKAoJCQkJCSInJXMnIGlzIG5vdCBhIHJlZ2lzdGVyZWQgd3AgY29tbWFuZC4gU2VlICd3cCBoZWxwJyBmb3IgYXZhaWxhYmxlIGNvbW1hbmRzLiVzIiwKCQkJCQkkZnVsbF9uYW1lLAoJCQkJCSEgZW1wdHkoICRzdWdnZXN0aW9uICkgPyBQSFBfRU9MIC4gIkRpZCB5b3UgbWVhbiAneyRzdWdnZXN0aW9ufSc/IiA6ICcnCgkJCQkpOwoJCQl9CgoJCQlpZiAoICR0aGlzLT5pc19jb21tYW5kX2Rpc2FibGVkKCAkc3ViY29tbWFuZCApICkgewoJCQkJcmV0dXJuIHNwcmludGYoCgkJCQkJIlRoZSAnJXMnIGNvbW1hbmQgaGFzIGJlZW4gZGlzYWJsZWQgZnJvbSB0aGUgY29uZmlnIGZpbGUuIiwKCQkJCQkkZnVsbF9uYW1lCgkJCQkpOwoJCQl9CgoJCQkkY29tbWFuZCA9ICRzdWJjb21tYW5kOwoJCX0KCgkJcmV0dXJuIFsgJGNvbW1hbmQsICRhcmdzLCAkY21kX3BhdGggXTsKCX0KCgkvKioKCSAqIEZpbmQgdGhlIFdQLUNMSSBjb21tYW5kIHRvIHJ1biBnaXZlbiBhcmd1bWVudHMsIGFuZCBpbnZva2UgaXQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgICBQb3NpdGlvbmFsIGFyZ3VtZW50cyBpbmNsdWRpbmcgY29tbWFuZCBuYW1lCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgIEFzc29jaWF0aXZlIGFyZ3VtZW50cyBmb3IgdGhlIGNvbW1hbmQuCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgICAgIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGZ1bmN0aW9uLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuX2NvbW1hbmQoICRhcmdzLCAkYXNzb2NfYXJncyA9IFtdLCAkb3B0aW9ucyA9IFtdICkgewoJCVdQX0NMSTo6ZG9faG9vayggJ2JlZm9yZV9ydW5fY29tbWFuZCcgKTsKCgkJaWYgKCAhIGVtcHR5KCAkb3B0aW9uc1snYmFja19jb21wYXRfY29udmVyc2lvbnMnXSApICkgewoJCQlsaXN0KCAkYXJncywgJGFzc29jX2FyZ3MgKSA9IHNlbGY6OmJhY2tfY29tcGF0X2NvbnZlcnNpb25zKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQl9CgkJJHIgPSAkdGhpcy0+ZmluZF9jb21tYW5kX3RvX3J1biggJGFyZ3MgKTsKCQlpZiAoIGlzX3N0cmluZyggJHIgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJHIgKTsKCQl9CgoJCWxpc3QoICRjb21tYW5kLCAkZmluYWxfYXJncywgJGNtZF9wYXRoICkgPSAkcjsKCgkJJG5hbWUgPSBpbXBsb2RlKCAnICcsICRjbWRfcGF0aCApOwoKCQkkZXh0cmFfYXJncyA9IFtdOwoKCQlpZiAoIGlzc2V0KCAkdGhpcy0+ZXh0cmFfY29uZmlnWyAkbmFtZSBdICkgKSB7CgkJCSRleHRyYV9hcmdzID0gJHRoaXMtPmV4dHJhX2NvbmZpZ1sgJG5hbWUgXTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoICdSdW5uaW5nIGNvbW1hbmQ6ICcgLiAkbmFtZSwgJ2Jvb3RzdHJhcCcgKTsKCQl0cnkgewoJCQkkY29tbWFuZC0+aW52b2tlKCAkZmluYWxfYXJncywgJGFzc29jX2FyZ3MsICRleHRyYV9hcmdzICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCX0KCgkvKioKCSAqIFNob3cgc3lub3BzaXMgaWYgdGhlIGNhbGxlZCBjb21tYW5kIGlzIGEgY29tcG9zaXRlIGNvbW1hbmQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNob3dfc3lub3BzaXNfaWZfY29tcG9zaXRlX2NvbW1hbmQoKSB7CgkJJHIgPSAkdGhpcy0+ZmluZF9jb21tYW5kX3RvX3J1biggJHRoaXMtPmFyZ3VtZW50cyApOwoJCWlmICggaXNfYXJyYXkoICRyICkgKSB7CgkJCWxpc3QoICRjb21tYW5kICkgPSAkcjsKCgkJCWlmICggJGNvbW1hbmQtPmNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgKSB7CgkJCQkkY29tbWFuZC0+c2hvd191c2FnZSgpOwoJCQkJZXhpdDsKCQkJfQoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIHJ1bl9jb21tYW5kX2FuZF9leGl0KCAkaGVscF9leGl0X3dhcm5pbmcgPSAnJyApIHsKCQkkdGhpcy0+c2hvd19zeW5vcHNpc19pZl9jb21wb3NpdGVfY29tbWFuZCgpOwoJCSR0aGlzLT5ydW5fY29tbWFuZCggJHRoaXMtPmFyZ3VtZW50cywgJHRoaXMtPmFzc29jX2FyZ3MgKTsKCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2hlbHAnIF0gKSApIHsKCQkJLy8gSGVscCBjb3VsZG4ndCBmaW5kIHRoZSBjb21tYW5kIHNvIGV4aXQgd2l0aCBzdWdnZXN0aW9uLgoJCQkkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCA9ICR0aGlzLT5maW5kX2NvbW1hbmRfdG9fcnVuKCBhcnJheV9zbGljZSggJHRoaXMtPmFyZ3VtZW50cywgMSApICk7CgkJCWlmICggaXNfc3RyaW5nKCAkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCApICkgewoJCQkJaWYgKCAkaGVscF9leGl0X3dhcm5pbmcgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkaGVscF9leGl0X3dhcm5pbmcgKTsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICRzdWdnZXN0aW9uX29yX2Rpc2FibGVkICk7CgkJCX0KCQkJLy8gU2hvdWxkIG5ldmVyIGdldCBoZXJlLgoJCX0KCQlleGl0OwoJfQoKCS8qKgoJICogUGVyZm9ybSBhIGNvbW1hbmQgYWdhaW5zdCBhIHJlbW90ZSBzZXJ2ZXIgb3ZlciBTU0ggKG9yIGEgY29udGFpbmVyIHVzaW5nCgkgKiBzY2hlbWUgb2YgImRvY2tlciIgb3IgImRvY2tlci1jb21wb3NlIikuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29ubmVjdGlvbl9zdHJpbmcgUGFzc2VkIGNvbm5lY3Rpb24gc3RyaW5nLgoJICogQHJldHVybiB2b2lkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcnVuX3NzaF9jb21tYW5kKCAkY29ubmVjdGlvbl9zdHJpbmcgKSB7CgoJCVdQX0NMSTo6ZG9faG9vayggJ2JlZm9yZV9zc2gnICk7CgoJCSRiaXRzID0gVXRpbHNccGFyc2Vfc3NoX3VybCggJGNvbm5lY3Rpb25fc3RyaW5nICk7CgoJCSRwcmVfY21kID0gZ2V0ZW52KCAnV1BfQ0xJX1NTSF9QUkVfQ01EJyApOwoJCWlmICggJHByZV9jbWQgKSB7CgkJCSRtZXNzYWdlID0gV1BfQ0xJOjp3YXJuaW5nKCAiV1BfQ0xJX1NTSF9QUkVfQ01EIGZvdW5kLCBleGVjdXRpbmcgdGhlIGZvbGxvd2luZyBjb21tYW5kKHMpIG9uIHRoZSByZW1vdGUgbWFjaGluZTpcbiAkcHJlX2NtZCIgKTsKCgkJCVdQX0NMSTo6bG9nKCAkbWVzc2FnZSApOwoKCQkJJHByZV9jbWQgPSBydHJpbSggJHByZV9jbWQsICc7JyApIC4gJzsgJzsKCQl9CgkJaWYgKCAhIGVtcHR5KCAkYml0c1sncGF0aCddICkgKSB7CgkJCSRwcmVfY21kIC49ICdjZCAnIC4gZXNjYXBlc2hlbGxhcmcoICRiaXRzWydwYXRoJ10gKSAuICc7ICc7CgkJfQoKCQkkZW52X3ZhcnMgPSAnJzsKCQlpZiAoIGdldGVudiggJ1dQX0NMSV9TVFJJQ1RfQVJHU19NT0RFJyApICkgewoJCQkkZW52X3ZhcnMgLj0gJ1dQX0NMSV9TVFJJQ1RfQVJHU19NT0RFPTEgJzsKCQl9CgoJCSR3cF9iaW5hcnkgPSAnd3AnOwoJCSR3cF9hcmdzICAgPSBhcnJheV9zbGljZSggJEdMT0JBTFNbJ2FyZ3YnXSwgMSApOwoKCQlpZiAoICR0aGlzLT5hbGlhcyAmJiAhIGVtcHR5KCAkd3BfYXJnc1swXSApICYmICR0aGlzLT5hbGlhcyA9PT0gJHdwX2FyZ3NbMF0gKSB7CgkJCWFycmF5X3NoaWZ0KCAkd3BfYXJncyApOwoJCQkkcnVudGltZV9hbGlhcyA9IFtdOwoJCQlmb3JlYWNoICggJHRoaXMtPmFsaWFzZXNbICR0aGlzLT5hbGlhcyBdIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkJaWYgKCAnc3NoJyA9PT0gJGtleSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCSRydW50aW1lX2FsaWFzWyAka2V5IF0gPSAkdmFsdWU7CgkJCX0KCQkJaWYgKCAhIGVtcHR5KCAkcnVudGltZV9hbGlhcyApICkgewoJCQkJJGVuY29kZWRfYWxpYXMgPSBqc29uX2VuY29kZSgKCQkJCQlbCgkJCQkJCSR0aGlzLT5hbGlhcyA9PiAkcnVudGltZV9hbGlhcywKCQkJCQldCgkJCQkpOwoJCQkJJHdwX2JpbmFyeSAgICAgPSAiV1BfQ0xJX1JVTlRJTUVfQUxJQVM9J3skZW5jb2RlZF9hbGlhc30nIHskd3BfYmluYXJ5fSB7JHRoaXMtPmFsaWFzfSI7CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkd3BfYXJncyBhcyAkayA9PiAkdiApIHsKCQkJaWYgKCBwcmVnX21hdGNoKCAnIy0tc3NoPSMnLCAkdiApICkgewoJCQkJdW5zZXQoICR3cF9hcmdzWyAkayBdICk7CgkJCX0KCQl9CgoJCSR3cF9jb21tYW5kICAgICAgPSAkcHJlX2NtZCAuICRlbnZfdmFycyAuICR3cF9iaW5hcnkgLiAnICcgLiBpbXBsb2RlKCAnICcsIGFycmF5X21hcCggJ2VzY2FwZXNoZWxsYXJnJywgJHdwX2FyZ3MgKSApOwoJCSRlc2NhcGVkX2NvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVfc3NoX2NvbW1hbmQoICRiaXRzLCAkd3BfY29tbWFuZCApOwoKCQlwYXNzdGhydSggJGVzY2FwZWRfY29tbWFuZCwgJGV4aXRfY29kZSApOwoJCWlmICggMjU1ID09PSAkZXhpdF9jb2RlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnQ2Fubm90IGNvbm5lY3Qgb3ZlciBTU0ggdXNpbmcgcHJvdmlkZWQgY29uZmlndXJhdGlvbi4nLCAyNTUgKTsKCQl9IGVsc2UgewoJCQlleGl0KCAkZXhpdF9jb2RlICk7CgkJfQoJfQoKCS8qKgoJICogR2VuZXJhdGUgYSBzaGVsbCBjb21tYW5kIGZyb20gdGhlIHBhcnNlZCBjb25uZWN0aW9uIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRiaXRzICAgICAgIFBhcnNlZCBjb25uZWN0aW9uIHN0cmluZy4KCSAqIEBwYXJhbSBzdHJpbmcgJHdwX2NvbW1hbmQgV1AtQ0xJIGNvbW1hbmQgdG8gcnVuLgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZW5lcmF0ZV9zc2hfY29tbWFuZCggJGJpdHMsICR3cF9jb21tYW5kICkgewoJCSRlc2NhcGVkX2NvbW1hbmQgPSAnJzsKCgkJLy8gU2V0IGRlZmF1bHQgdmFsdWVzLgoJCWZvcmVhY2ggKCBbICdzY2hlbWUnLCAndXNlcicsICdob3N0JywgJ3BvcnQnLCAncGF0aCcsICdrZXknIF0gYXMgJGJpdCApIHsKCQkJaWYgKCAhIGlzc2V0KCAkYml0c1sgJGJpdCBdICkgKSB7CgkJCQkkYml0c1sgJGJpdCBdID0gbnVsbDsKCQkJfQoKCQkJV1BfQ0xJOjpkZWJ1ZyggJ1NTSCAnIC4gJGJpdCAuICc6ICcgLiAkYml0c1sgJGJpdCBdLCAnYm9vdHN0cmFwJyApOwoJCX0KCgkJJGlzX3R0eSA9IGZ1bmN0aW9uX2V4aXN0cyggJ3Bvc2l4X2lzYXR0eScgKSAmJiBwb3NpeF9pc2F0dHkoIFNURE9VVCApOwoKCQlpZiAoICdkb2NrZXInID09PSAkYml0c1snc2NoZW1lJ10gKSB7CgkJCSRjb21tYW5kID0gJ2RvY2tlciBleGVjICVzJXMlcyBzaCAtYyAlcyc7CgoJCQkkZXNjYXBlZF9jb21tYW5kID0gc3ByaW50ZigKCQkJCSRjb21tYW5kLAoJCQkJJGJpdHNbJ3VzZXInXSA/ICctLXVzZXIgJyAuIGVzY2FwZXNoZWxsYXJnKCAkYml0c1sndXNlciddICkgLiAnICcgOiAnJywKCQkJCSRpc190dHkgPyAnLXQgJyA6ICcnLAoJCQkJZXNjYXBlc2hlbGxhcmcoICRiaXRzWydob3N0J10gKSwKCQkJCWVzY2FwZXNoZWxsYXJnKCAkd3BfY29tbWFuZCApCgkJCSk7CgkJfQoKCQlpZiAoICdkb2NrZXItY29tcG9zZScgPT09ICRiaXRzWydzY2hlbWUnXSApIHsKCQkJJGNvbW1hbmQgPSAnZG9ja2VyLWNvbXBvc2UgZXhlYyAlcyVzJXMgc2ggLWMgJXMnOwoKCQkJJGVzY2FwZWRfY29tbWFuZCA9IHNwcmludGYoCgkJCQkkY29tbWFuZCwKCQkJCSRiaXRzWyd1c2VyJ10gPyAnLS11c2VyICcgLiBlc2NhcGVzaGVsbGFyZyggJGJpdHNbJ3VzZXInXSApIC4gJyAnIDogJycsCgkJCQkkaXNfdHR5ID8gJycgOiAnLVQgJywKCQkJCWVzY2FwZXNoZWxsYXJnKCAkYml0c1snaG9zdCddICksCgkJCQllc2NhcGVzaGVsbGFyZyggJHdwX2NvbW1hbmQgKQoJCQkpOwoJCX0KCgkJLy8gVmFncmFudCBzc2gtY29uZmlnLgoJCWlmICggJ3ZhZ3JhbnQnID09PSAkYml0c1snc2NoZW1lJ10gKSB7CgkJCSRjYWNoZSAgICAgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoJCQkkY2FjaGVfa2V5ID0gJ3ZhZ3JhbnQ6JyAuICR0aGlzLT5wcm9qZWN0X2NvbmZpZ19wYXRoOwoJCQlpZiAoICRjYWNoZS0+aGFzKCAkY2FjaGVfa2V5ICkgKSB7CgkJCQkkY2FjaGVkID0gJGNhY2hlLT5yZWFkKCAkY2FjaGVfa2V5ICk7CgkJCQkkdmFsdWVzID0ganNvbl9kZWNvZGUoICRjYWNoZWQsIHRydWUgKTsKCQkJfSBlbHNlIHsKCQkJCSRzc2hfY29uZmlnID0gc2hlbGxfZXhlYyggJ3ZhZ3JhbnQgc3NoLWNvbmZpZyAyPi9kZXYvbnVsbCcgKTsKCQkJCWlmICggcHJlZ19tYXRjaF9hbGwoICcjXHMqKD88TkFNRT5bYS16QS1aXSspXHMoPzxWQUxVRT4uKylccyojJywgJHNzaF9jb25maWcsICRtYXRjaGVzICkgKSB7CgkJCQkJJHZhbHVlcyA9IGFycmF5X2NvbWJpbmUoICRtYXRjaGVzWydOQU1FJ10sICRtYXRjaGVzWydWQUxVRSddICk7CgkJCQkJJGNhY2hlLT53cml0ZSggJGNhY2hlX2tleSwganNvbl9lbmNvZGUoICR2YWx1ZXMgKSApOwoJCQkJfQoJCQl9CgoJCQlpZiAoIGVtcHR5KCAkYml0c1snaG9zdCddICkgfHwgKCBpc3NldCggJHZhbHVlc1snSG9zdCddICkgJiYgJGJpdHNbJ2hvc3QnXSA9PT0gJHZhbHVlc1snSG9zdCddICkgKSB7CgkJCQkkYml0c1snc2NoZW1lJ10gPSAnc3NoJzsKCQkJCSRiaXRzWydob3N0J10gICA9ICR2YWx1ZXNbJ0hvc3ROYW1lJ107CgkJCQkkYml0c1sncG9ydCddICAgPSAkdmFsdWVzWydQb3J0J107CgkJCQkkYml0c1sndXNlciddICAgPSAkdmFsdWVzWydVc2VyJ107CgkJCQkkYml0c1sna2V5J10gICAgPSAkdmFsdWVzWydJZGVudGl0eUZpbGUnXTsKCQkJfQoKCQkJLy8gSWYgd2UgY291bGQgbm90IHJlc29sdmUgdGhlIGJpdHMgc3RpbGwsIGZhbGxiYWNrIHRvIGp1c3QgYHZhZ3JhbnQgc3NoYAoJCQlpZiAoICd2YWdyYW50JyA9PT0gJGJpdHNbJ3NjaGVtZSddICkgewoJCQkJJGNvbW1hbmQgPSAndmFncmFudCBzc2ggLWMgJXMgJXMnOwoKCQkJCSRlc2NhcGVkX2NvbW1hbmQgPSBzcHJpbnRmKAoJCQkJCSRjb21tYW5kLAoJCQkJCWVzY2FwZXNoZWxsYXJnKCAkd3BfY29tbWFuZCApLAoJCQkJCWVzY2FwZXNoZWxsYXJnKCAkYml0c1snaG9zdCddICkKCQkJCSk7CgkJCX0KCQl9CgoJCS8vIERlZmF1bHQgc2NoZW1lIGlzIFNTSC4KCQlpZiAoICdzc2gnID09PSAkYml0c1snc2NoZW1lJ10gfHwgbnVsbCA9PT0gJGJpdHNbJ3NjaGVtZSddICkgewoJCQkkY29tbWFuZCA9ICdzc2ggLXEgJXMgJXMgJXMnOwoKCQkJaWYgKCAkYml0c1sndXNlciddICkgewoJCQkJJGJpdHNbJ2hvc3QnXSA9ICRiaXRzWyd1c2VyJ10gLiAnQCcgLiAkYml0c1snaG9zdCddOwoJCQl9CgoJCQkkY29tbWFuZF9hcmdzID0gWwoJCQkJJGJpdHNbJ3BvcnQnXSA/ICctcCAnIC4gKGludCkgJGJpdHNbJ3BvcnQnXSAuICcgJyA6ICcnLAoJCQkJJGJpdHNbJ2tleSddID8gc3ByaW50ZiggJy1pICVzJywgJGJpdHNbJ2tleSddICkgOiAnJywKCQkJCSRpc190dHkgPyAnLXQnIDogJy1UJywKCQkJXTsKCgkJCSRlc2NhcGVkX2NvbW1hbmQgPSBzcHJpbnRmKAoJCQkJJGNvbW1hbmQsCgkJCQlpbXBsb2RlKCAnICcsIGFycmF5X2ZpbHRlciggJGNvbW1hbmRfYXJncyApICksCgkJCQllc2NhcGVzaGVsbGFyZyggJGJpdHNbJ2hvc3QnXSApLAoJCQkJZXNjYXBlc2hlbGxhcmcoICR3cF9jb21tYW5kICkKCQkJKTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoICdSdW5uaW5nIFNTSCBjb21tYW5kOiAnIC4gJGVzY2FwZWRfY29tbWFuZCwgJ2Jvb3RzdHJhcCcgKTsKCgkJcmV0dXJuICRlc2NhcGVkX2NvbW1hbmQ7Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gY29tbWFuZCBpcyBkaXNhYmxlZCBieSB0aGUgY29uZmlnLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfY29tbWFuZF9kaXNhYmxlZCggJGNvbW1hbmQgKSB7CgkJJHBhdGggPSBpbXBsb2RlKCAnICcsIGFycmF5X3NsaWNlKCBEaXNwYXRjaGVyXGdldF9wYXRoKCAkY29tbWFuZCApLCAxICkgKTsKCQlyZXR1cm4gaW5fYXJyYXkoICRwYXRoLCAkdGhpcy0+Y29uZmlnWydkaXNhYmxlZF9jb21tYW5kcyddLCB0cnVlICk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHdwLWNvbmZpZy5waHAgY29kZSwgc2tpcHBpbmcgdGhlIGxvYWRpbmcgb2Ygd3Atc2V0dGluZ3MucGhwLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdwX2NvbmZpZ19wYXRoIE9wdGlvbmFsLiBDb25maWcgZmlsZSBwYXRoLiBJZiBsZWZ0IGVtcHR5LCBpdCB0cmllcyB0bwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRlIHRoZSB3cC1jb25maWcucGhwIGZpbGUgYXV0b21hdGljYWxseS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3dwX2NvbmZpZ19jb2RlKCAkd3BfY29uZmlnX3BhdGggPSAnJyApIHsKCQlpZiAoIGVtcHR5KCAkd3BfY29uZmlnX3BhdGggKSApIHsKCQkJJHdwX2NvbmZpZ19wYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoJCX0KCgkJJHdwX2NvbmZpZ19jb2RlID0gZXhwbG9kZSggIlxuIiwgZmlsZV9nZXRfY29udGVudHMoICR3cF9jb25maWdfcGF0aCApICk7CgoJCSRmb3VuZF93cF9zZXR0aW5ncyA9IGZhbHNlOwoKCQkkbGluZXNfdG9fcnVuID0gW107CgoJCWZvcmVhY2ggKCAkd3BfY29uZmlnX2NvZGUgYXMgJGxpbmUgKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJy9eXHMqcmVxdWlyZS4rd3Atc2V0dGluZ3NcLnBocC8nLCAkbGluZSApICkgewoJCQkJJGZvdW5kX3dwX3NldHRpbmdzID0gdHJ1ZTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbGluZXNfdG9fcnVuW10gPSAkbGluZTsKCQl9CgoJCWlmICggISAkZm91bmRfd3Bfc2V0dGluZ3MgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdTdHJhbmdlIHdwLWNvbmZpZy5waHAgZmlsZTogd3Atc2V0dGluZ3MucGhwIGlzIG5vdCBsb2FkZWQgZGlyZWN0bHkuJyApOwoJCX0KCgkJJHNvdXJjZSA9IGltcGxvZGUoICJcbiIsICRsaW5lc190b19ydW4gKTsKCQkkc291cmNlID0gVXRpbHNccmVwbGFjZV9wYXRoX2NvbnN0cyggJHNvdXJjZSwgJHdwX2NvbmZpZ19wYXRoICk7CgkJcmV0dXJuIHByZWdfcmVwbGFjZSggJ3xeXHMqXDxcP3BocFxzKnwnLCAnJywgJHNvdXJjZSApOwoJfQoKCS8qKgoJICogVHJhbnNwYXJlbnRseSBjb252ZXJ0IGRlcHJlY2F0ZWQgc3ludGF4ZXMKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncwoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBiYWNrX2NvbXBhdF9jb252ZXJzaW9ucyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0b3BfbGV2ZWxfYWxpYXNlcyA9IFsKCQkJJ3NxbCcgID0+ICdkYicsCgkJCSdibG9nJyA9PiAnc2l0ZScsCgkJXTsKCQlpZiAoIGNvdW50KCAkYXJncyApID4gMCApIHsKCQkJZm9yZWFjaCAoICR0b3BfbGV2ZWxfYWxpYXNlcyBhcyAkb2xkID0+ICRuZXcgKSB7CgkJCQlpZiAoICRvbGQgPT09ICRhcmdzWzBdICkgewoJCQkJCSRhcmdzWzBdID0gJG5ldzsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gKi1tZXRhICAtPiAgKiBtZXRhCgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICYmIHByZWdfbWF0Y2goICcvKHBvc3R8Y29tbWVudHx1c2VyfG5ldHdvcmspLW1ldGEvJywgJGFyZ3NbMF0sICRtYXRjaGVzICkgKSB7CgkJCWFycmF5X3NoaWZ0KCAkYXJncyApOwoJCQlhcnJheV91bnNoaWZ0KCAkYXJncywgJ21ldGEnICk7CgkJCWFycmF5X3Vuc2hpZnQoICRhcmdzLCAkbWF0Y2hlc1sxXSApOwoJCX0KCgkJLy8gY2xpIGFsaWFzZXMgIC0+ICBjbGkgYWxpYXMgbGlzdAoJCWlmICggWyAnY2xpJywgJ2FsaWFzZXMnIF0gPT09IGFycmF5X3NsaWNlKCAkYXJncywgMCwgMiApICkgewoJCQlsaXN0KCAkYXJnc1swXSwgJGFyZ3NbMV0sICRhcmdzWzJdICkgPSBbICdjbGknLCAnYWxpYXMnLCAnbGlzdCcgXTsKCQl9CgoJCS8vIGNvcmUgKG11bHRzaXRlLSlpbnN0YWxsIC0tYWRtaW5fbmFtZT0gIC0+ICAtLWFkbWluX3VzZXI9CgkJaWYgKCBjb3VudCggJGFyZ3MgKSA+IDAgJiYgJ2NvcmUnID09PSAkYXJnc1swXSAmJiBpc3NldCggJGFzc29jX2FyZ3NbJ2FkbWluX25hbWUnXSApICkgewoJCQkkYXNzb2NfYXJnc1snYWRtaW5fdXNlciddID0gJGFzc29jX2FyZ3NbJ2FkbWluX25hbWUnXTsKCQkJdW5zZXQoICRhc3NvY19hcmdzWydhZG1pbl9uYW1lJ10gKTsKCQl9CgoJCS8vIGNvcmUgY29uZmlnICAtPiAgY29uZmlnIGNyZWF0ZQoJCWlmICggWyAnY29yZScsICdjb25maWcnIF0gPT09IGFycmF5X3NsaWNlKCAkYXJncywgMCwgMiApICkgewoJCQlsaXN0KCAkYXJnc1swXSwgJGFyZ3NbMV0gKSA9IFsgJ2NvbmZpZycsICdjcmVhdGUnIF07CgkJfQoJCS8vIGNvcmUgbGFuZ3VhZ2UgIC0+ICBsYW5ndWFnZSBjb3JlCgkJaWYgKCBbICdjb3JlJywgJ2xhbmd1YWdlJyBdID09PSBhcnJheV9zbGljZSggJGFyZ3MsIDAsIDIgKSApIHsKCQkJbGlzdCggJGFyZ3NbMF0sICRhcmdzWzFdICkgPSBbICdsYW5ndWFnZScsICdjb3JlJyBdOwoJCX0KCgkJLy8gY2hlY2tzdW0gY29yZSAgLT4gIGNvcmUgdmVyaWZ5LWNoZWNrc3VtcwoJCWlmICggWyAnY2hlY2tzdW0nLCAnY29yZScgXSA9PT0gYXJyYXlfc2xpY2UoICRhcmdzLCAwLCAyICkgKSB7CgkJCWxpc3QoICRhcmdzWzBdLCAkYXJnc1sxXSApID0gWyAnY29yZScsICd2ZXJpZnktY2hlY2tzdW1zJyBdOwoJCX0KCgkJLy8gY2hlY2tzdW0gcGx1Z2luICAtPiAgcGx1Z2luIHZlcmlmeS1jaGVja3N1bXMKCQlpZiAoIFsgJ2NoZWNrc3VtJywgJ3BsdWdpbicgXSA9PT0gYXJyYXlfc2xpY2UoICRhcmdzLCAwLCAyICkgKSB7CgkJCWxpc3QoICRhcmdzWzBdLCAkYXJnc1sxXSApID0gWyAncGx1Z2luJywgJ3ZlcmlmeS1jaGVja3N1bXMnIF07CgkJfQoKCQkvLyBzaXRlIGNyZWF0ZSAtLXNpdGVfaWQ9ICAtPiAgc2l0ZSBjcmVhdGUgLS1uZXR3b3JrX2lkPQoJCWlmICggY291bnQoICRhcmdzICkgPj0gMiAmJiAnc2l0ZScgPT09ICRhcmdzWzBdICYmICdjcmVhdGUnID09PSAkYXJnc1sxXSAmJiBpc3NldCggJGFzc29jX2FyZ3NbJ3NpdGVfaWQnXSApICkgewoJCQkkYXNzb2NfYXJnc1snbmV0d29ya19pZCddID0gJGFzc29jX2FyZ3NbJ3NpdGVfaWQnXTsKCQkJdW5zZXQoICRhc3NvY19hcmdzWydzaXRlX2lkJ10gKTsKCQl9CgoJCS8vIHtwbHVnaW58dGhlbWV9IHVwZGF0ZS1hbGwgIC0+ICB7cGx1Z2lufHRoZW1lfSB1cGRhdGUgLS1hbGwKCQlpZiAoIGNvdW50KCAkYXJncyApID4gMSAmJiBpbl9hcnJheSggJGFyZ3NbMF0sIFsgJ3BsdWdpbicsICd0aGVtZScgXSwgdHJ1ZSApCgkJCSYmICd1cGRhdGUtYWxsJyA9PT0gJGFyZ3NbMV0KCQkpIHsKCQkJJGFyZ3NbMV0gICAgICAgICAgID0gJ3VwZGF0ZSc7CgkJCSRhc3NvY19hcmdzWydhbGwnXSA9IHRydWU7CgkJfQoKCQkvLyB0cmFuc2llbnQgZGVsZXRlLWV4cGlyZWQgIC0+ICB0cmFuc2llbnQgZGVsZXRlIC0tZXhwaXJlZAoJCWlmICggY291bnQoICRhcmdzICkgPiAxICYmICd0cmFuc2llbnQnID09PSAkYXJnc1swXSAmJiAnZGVsZXRlLWV4cGlyZWQnID09PSAkYXJnc1sxXSApIHsKCQkJJGFyZ3NbMV0gICAgICAgICAgICAgICA9ICdkZWxldGUnOwoJCQkkYXNzb2NfYXJnc1snZXhwaXJlZCddID0gdHJ1ZTsKCQl9CgoJCS8vIHRyYW5zaWVudCBkZWxldGUtYWxsICAtPiAgdHJhbnNpZW50IGRlbGV0ZSAtLWFsbAoJCWlmICggY291bnQoICRhcmdzICkgPiAxICYmICd0cmFuc2llbnQnID09PSAkYXJnc1swXSAmJiAnZGVsZXRlLWFsbCcgPT09ICRhcmdzWzFdICkgewoJCQkkYXJnc1sxXSAgICAgICAgICAgPSAnZGVsZXRlJzsKCQkJJGFzc29jX2FyZ3NbJ2FsbCddID0gdHJ1ZTsKCQl9CgoJCS8vIHBsdWdpbiBzY2FmZm9sZCAgLT4gIHNjYWZmb2xkIHBsdWdpbgoJCWlmICggWyAncGx1Z2luJywgJ3NjYWZmb2xkJyBdID09PSBhcnJheV9zbGljZSggJGFyZ3MsIDAsIDIgKSApIHsKCQkJbGlzdCggJGFyZ3NbMF0sICRhcmdzWzFdICkgPSBbICRhcmdzWzFdLCAkYXJnc1swXSBdOwoJCX0KCgkJLy8gZm9vIC0taGVscCAgLT4gIGhlbHAgZm9vCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2hlbHAnXSApICkgewoJCQlhcnJheV91bnNoaWZ0KCAkYXJncywgJ2hlbHAnICk7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snaGVscCddICk7CgkJfQoKCQkvLyB7cG9zdHx1c2VyfSBsaXN0IC0taWRzICAtPiAge3Bvc3R8dXNlcn0gbGlzdCAtLWZvcm1hdD1pZHMKCQlpZiAoIGNvdW50KCAkYXJncyApID4gMSAmJiBpbl9hcnJheSggJGFyZ3NbMF0sIFsgJ3Bvc3QnLCAndXNlcicgXSwgdHJ1ZSApCgkJCSYmICdsaXN0JyA9PT0gJGFyZ3NbMV0KCQkJJiYgaXNzZXQoICRhc3NvY19hcmdzWydpZHMnXSApCgkJKSB7CgkJCSRhc3NvY19hcmdzWydmb3JtYXQnXSA9ICdpZHMnOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2lkcyddICk7CgkJfQoKCQkvLyAtLWpzb24gIC0+ICAtLWZvcm1hdD1qc29uCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2pzb24nXSApICkgewoJCQkkYXNzb2NfYXJnc1snZm9ybWF0J10gPSAnanNvbic7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snanNvbiddICk7CgkJfQoKCQkvLyAtLXt2ZXJzaW9ufGluZm99ICAtPiAgY2xpIHt2ZXJzaW9ufGluZm99CgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJJHNwZWNpYWxfZmxhZ3MgPSBbICd2ZXJzaW9uJywgJ2luZm8nIF07CgkJCWZvcmVhY2ggKCAkc3BlY2lhbF9mbGFncyBhcyAka2V5ICkgewoJCQkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbICRrZXkgXSApICkgewoJCQkJCSRhcmdzID0gWyAnY2xpJywgJGtleSBdOwoJCQkJCXVuc2V0KCAkYXNzb2NfYXJnc1sgJGtleSBdICk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIChwb3N0fGNvbW1lbnR8c2l0ZXx0ZXJtKSB1cmwgIC0tPiAocG9zdHxjb21tZW50fHNpdGV8dGVybSkgbGlzdCAtLSpfX2luIC0tZmllbGQ9dXJsCgkJaWYgKCBjb3VudCggJGFyZ3MgKSA+PSAyICYmIGluX2FycmF5KCAkYXJnc1swXSwgWyAncG9zdCcsICdjb21tZW50JywgJ3NpdGUnLCAndGVybScgXSwgdHJ1ZSApICYmICd1cmwnID09PSAkYXJnc1sxXSApIHsKCQkJc3dpdGNoICggJGFyZ3NbMF0gKSB7CgkJCQljYXNlICdwb3N0JzoKCQkJCQkkcG9zdF9pZHMgICAgICAgICAgICAgICAgPSBhcnJheV9zbGljZSggJGFyZ3MsIDIgKTsKCQkJCQkkYXJncyAgICAgICAgICAgICAgICAgICAgPSBbICdwb3N0JywgJ2xpc3QnIF07CgkJCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfX2luJ10gID0gaW1wbG9kZSggJywnLCAkcG9zdF9pZHMgKTsKCQkJCQkkYXNzb2NfYXJnc1sncG9zdF90eXBlJ10gPSAnYW55JzsKCQkJCQkkYXNzb2NfYXJnc1snb3JkZXJieSddICAgPSAncG9zdF9faW4nOwoJCQkJCSRhc3NvY19hcmdzWydmaWVsZCddICAgICA9ICd1cmwnOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnY29tbWVudCc6CgkJCQkJJGNvbW1lbnRfaWRzICAgICAgICAgICAgICAgPSBhcnJheV9zbGljZSggJGFyZ3MsIDIgKTsKCQkJCQkkYXJncyAgICAgICAgICAgICAgICAgICAgICA9IFsgJ2NvbW1lbnQnLCAnbGlzdCcgXTsKCQkJCQkkYXNzb2NfYXJnc1snY29tbWVudF9faW4nXSA9IGltcGxvZGUoICcsJywgJGNvbW1lbnRfaWRzICk7CgkJCQkJJGFzc29jX2FyZ3NbJ29yZGVyYnknXSAgICAgPSAnY29tbWVudF9faW4nOwoJCQkJCSRhc3NvY19hcmdzWydmaWVsZCddICAgICAgID0gJ3VybCc7CgkJCQkJYnJlYWs7CgkJCQljYXNlICdzaXRlJzoKCQkJCQkkc2l0ZV9pZHMgICAgICAgICAgICAgICA9IGFycmF5X3NsaWNlKCAkYXJncywgMiApOwoJCQkJCSRhcmdzICAgICAgICAgICAgICAgICAgID0gWyAnc2l0ZScsICdsaXN0JyBdOwoJCQkJCSRhc3NvY19hcmdzWydzaXRlX19pbiddID0gaW1wbG9kZSggJywnLCAkc2l0ZV9pZHMgKTsKCQkJCQkkYXNzb2NfYXJnc1snZmllbGQnXSAgICA9ICd1cmwnOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAndGVybSc6CgkJCQkJJHRheG9ub215ID0gJyc7CgkJCQkJaWYgKCBpc3NldCggJGFyZ3NbMl0gKSApIHsKCQkJCQkJJHRheG9ub215ID0gJGFyZ3NbMl07CgkJCQkJfQoJCQkJCSR0ZXJtX2lkcyAgICAgICAgICAgICAgPSBhcnJheV9zbGljZSggJGFyZ3MsIDMgKTsKCQkJCQkkYXJncyAgICAgICAgICAgICAgICAgID0gWyAndGVybScsICdsaXN0JywgJHRheG9ub215IF07CgkJCQkJJGFzc29jX2FyZ3NbJ2luY2x1ZGUnXSA9IGltcGxvZGUoICcsJywgJHRlcm1faWRzICk7CgkJCQkJJGFzc29jX2FyZ3NbJ29yZGVyYnknXSA9ICdpbmNsdWRlJzsKCQkJCQkkYXNzb2NfYXJnc1snZmllbGQnXSAgID0gJ3VybCc7CgkJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCS8vIGNvbmZpZyBnZXQgLS1bZ2xvYmFsfGNvbnN0YW50XT08Z2xvYmFsfGNvbnN0YW50PiAtLT4gY29uZmlnIGdldCA8bmFtZT4gLS10eXBlPWNvbnN0YW50fHZhcmlhYmxlCgkJLy8gY29uZmlnIGdldCAtLT4gY29uZmlnIGxpc3QKCQlpZiAoIGNvdW50KCAkYXJncyApID09PSAyCgkJCSYmICdjb25maWcnID09PSAkYXJnc1swXQoJCQkmJiAnZ2V0JyA9PT0gJGFyZ3NbMV0gKSB7CgkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydnbG9iYWwnXSApICkgewoJCQkJJG5hbWUgPSAkYXNzb2NfYXJnc1snZ2xvYmFsJ107CgkJCQkkdHlwZSA9ICd2YXJpYWJsZSc7CgkJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2dsb2JhbCddICk7CgkJCX0gZWxzZWlmICggaXNzZXQoICRhc3NvY19hcmdzWydjb25zdGFudCddICkgKSB7CgkJCQkkbmFtZSA9ICRhc3NvY19hcmdzWydjb25zdGFudCddOwoJCQkJJHR5cGUgPSAnY29uc3RhbnQnOwoJCQkJdW5zZXQoICRhc3NvY19hcmdzWydjb25zdGFudCddICk7CgkJCX0KCQkJaWYgKCAhIGVtcHR5KCAkbmFtZSApICYmICEgZW1wdHkoICR0eXBlICkgKSB7CgkJCQkkYXJnc1tdICAgICAgICAgICAgID0gJG5hbWU7CgkJCQkkYXNzb2NfYXJnc1sndHlwZSddID0gJHR5cGU7CgkJCX0gZWxzZSB7CgkJCQkvLyBXZSBoYWQgYSAnY29uZmlnIGdldCcgd2l0aG91dCBhICc8bmFtZT4nLCBzbyBhc3N1bWUgJ2xpc3QnIHdhcyB3YW50ZWQuCgkJCQkkYXJnc1sxXSA9ICdsaXN0JzsKCQkJfQoJCX0KCgkJcmV0dXJuIFsgJGFyZ3MsICRhc3NvY19hcmdzIF07Cgl9CgoJLyoqCgkgKiBXaGV0aGVyIG9yIG5vdCB0aGUgb3V0cHV0IHNob3VsZCBiZSByZW5kZXJlZCBpbiBjb2xvcgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5fY29sb3IoKSB7CgkJcmV0dXJuICR0aGlzLT5jb2xvcml6ZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gaW5pdF9jb2xvcml6YXRpb24oKSB7CgkJaWYgKCAnYXV0bycgPT09ICR0aGlzLT5jb25maWdbJ2NvbG9yJ10gKSB7CgkJCSR0aGlzLT5jb2xvcml6ZSA9ICggISBVdGlsc1xpc1BpcGVkKCkgJiYgISBVdGlsc1xpc193aW5kb3dzKCkgKTsKCQl9IGVsc2UgewoJCQkkdGhpcy0+Y29sb3JpemUgPSAkdGhpcy0+Y29uZmlnWydjb2xvciddOwoJCX0KCX0KCglwdWJsaWMgZnVuY3Rpb24gaW5pdF9sb2dnZXIoKSB7CgkJaWYgKCAkdGhpcy0+Y29uZmlnWydxdWlldCddICkgewoJCQkkbG9nZ2VyID0gbmV3IExvZ2dlcnNcUXVpZXQoKTsKCQl9IGVsc2UgewoJCQkkbG9nZ2VyID0gbmV3IExvZ2dlcnNcUmVndWxhciggJHRoaXMtPmluX2NvbG9yKCkgKTsKCQl9CgoJCVdQX0NMSTo6c2V0X2xvZ2dlciggJGxvZ2dlciApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRfcmVxdWlyZWRfZmlsZXMoKSB7CgkJcmV0dXJuICR0aGlzLT5yZXF1aXJlZF9maWxlczsKCX0KCgkvKioKCSAqIERvIFdvcmRQcmVzcyBjb3JlIGZpbGVzIGV4aXN0PwoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHdwX2V4aXN0cygpIHsKCQlyZXR1cm4gZmlsZV9leGlzdHMoIEFCU1BBVEggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnICk7Cgl9CgoJLyoqCgkgKiBBcmUgV29yZFByZXNzIGNvcmUgZmlsZXMgcmVhZGFibGU/CgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gd3BfaXNfcmVhZGFibGUoKSB7CgkJcmV0dXJuIGlzX3JlYWRhYmxlKCBBQlNQQVRIIC4gJ3dwLWluY2x1ZGVzL3ZlcnNpb24ucGhwJyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfd3BfdmVyc2lvbigpIHsKCQkkd3BfZXhpc3RzICAgICAgPSAkdGhpcy0+d3BfZXhpc3RzKCk7CgkJJHdwX2lzX3JlYWRhYmxlID0gJHRoaXMtPndwX2lzX3JlYWRhYmxlKCk7CgkJaWYgKCAhICR3cF9leGlzdHMgfHwgISAkd3BfaXNfcmVhZGFibGUgKSB7CgkJCSR0aGlzLT5zaG93X3N5bm9wc2lzX2lmX2NvbXBvc2l0ZV9jb21tYW5kKCk7CgkJCS8vIElmIHRoZSBjb21tYW5kIGRvZXNuJ3QgZXhpc3QgdXNlIGFzIGVycm9yLgoJCQkkYXJncyAgICAgICAgICAgICAgICAgICA9ICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2hlbHAnIF0gKSA/IGFycmF5X3NsaWNlKCAkdGhpcy0+YXJndW1lbnRzLCAxICkgOiAkdGhpcy0+YXJndW1lbnRzOwoJCQkkc3VnZ2VzdGlvbl9vcl9kaXNhYmxlZCA9ICR0aGlzLT5maW5kX2NvbW1hbmRfdG9fcnVuKCAkYXJncyApOwoJCQlpZiAoIGlzX3N0cmluZyggJHN1Z2dlc3Rpb25fb3JfZGlzYWJsZWQgKSApIHsKCQkJCWlmICggISBwcmVnX21hdGNoKCAnL2Rpc2FibGVkIGZyb20gdGhlIGNvbmZpZyBmaWxlLiQvJywgJHN1Z2dlc3Rpb25fb3JfZGlzYWJsZWQgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJObyBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIGZvdW5kLiBJZiB0aGUgY29tbWFuZCAnIiAuIGltcGxvZGUoICcgJywgJGFyZ3MgKSAuICInIGlzIGluIGEgcGx1Z2luIG9yIHRoZW1lLCBwYXNzIC0tcGF0aD1gcGF0aC90by93b3JkcHJlc3NgLiIgKTsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICRzdWdnZXN0aW9uX29yX2Rpc2FibGVkICk7CgkJCX0KCgkJCWlmICggJHdwX2V4aXN0cyAmJiAhICR3cF9pc19yZWFkYWJsZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkJJ0l0IHNlZW1zLCB0aGUgV29yZFByZXNzIGNvcmUgZmlsZXMgZG8gbm90IGhhdmUgdGhlIHByb3BlciBmaWxlIHBlcm1pc3Npb25zLicKCQkJCSk7CgkJCX0KCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGlzIGRvZXMgbm90IHNlZW0gdG8gYmUgYSBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uLlxuIiAuCgkJCQknUGFzcyAtLXBhdGg9YHBhdGgvdG8vd29yZHByZXNzYCBvciBydW4gYHdwIGNvcmUgZG93bmxvYWRgLicKCQkJKTsKCQl9CgoJCWdsb2JhbCAkd3BfdmVyc2lvbjsKCQlpbmNsdWRlIEFCU1BBVEggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnOwoKCQkkbWluaW11bV92ZXJzaW9uID0gJzMuNyc7CgoJCWlmICggdmVyc2lvbl9jb21wYXJlKCAkd3BfdmVyc2lvbiwgJG1pbmltdW1fdmVyc2lvbiwgJzwnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiV1AtQ0xJIG5lZWRzIFdvcmRQcmVzcyAkbWluaW11bV92ZXJzaW9uIG9yIGxhdGVyIHRvIHdvcmsgcHJvcGVybHkuICIgLgoJCQkJIlRoZSB2ZXJzaW9uIGN1cnJlbnRseSBpbnN0YWxsZWQgaXMgJHdwX3ZlcnNpb24uXG4iIC4KCQkJCSdUcnkgcnVubmluZyBgd3AgY29yZSBkb3dubG9hZCAtLWZvcmNlYC4nCgkJCSk7CgkJfQoJfQoKCXB1YmxpYyBmdW5jdGlvbiBpbml0X2NvbmZpZygpIHsKCQkkY29uZmlndXJhdG9yID0gV1BfQ0xJOjpnZXRfY29uZmlndXJhdG9yKCk7CgoJCSRhcmd2ID0gYXJyYXlfc2xpY2UoICRHTE9CQUxTWydhcmd2J10sIDEgKTsKCgkJJHRoaXMtPmFsaWFzID0gbnVsbDsKCQlpZiAoICEgZW1wdHkoICRhcmd2WzBdICkgJiYgcHJlZ19tYXRjaCggJyMnIC4gQ29uZmlndXJhdG9yOjpBTElBU19SRUdFWCAuICcjJywgJGFyZ3ZbMF0sICRtYXRjaGVzICkgKSB7CgkJCSR0aGlzLT5hbGlhcyA9IGFycmF5X3NoaWZ0KCAkYXJndiApOwoJCX0KCgkJLy8gRmlsZSBjb25maWcKCQl7CgkJCSR0aGlzLT5nbG9iYWxfY29uZmlnX3BhdGggID0gJHRoaXMtPmdldF9nbG9iYWxfY29uZmlnX3BhdGgoKTsKCQkJJHRoaXMtPnByb2plY3RfY29uZmlnX3BhdGggPSAkdGhpcy0+Z2V0X3Byb2plY3RfY29uZmlnX3BhdGgoKTsKCgkJCSRjb25maWd1cmF0b3ItPm1lcmdlX3ltbCggJHRoaXMtPmdsb2JhbF9jb25maWdfcGF0aCwgJHRoaXMtPmFsaWFzICk7CgkJCSRjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgPSAkY29uZmlndXJhdG9yLT50b19hcnJheSgpOwoJCQkkdGhpcy0+cmVxdWlyZWRfZmlsZXNbJ2dsb2JhbCddID0gJGNvbmZpZ1swXVsncmVxdWlyZSddOwoJCQkkY29uZmlndXJhdG9yLT5tZXJnZV95bWwoICR0aGlzLT5wcm9qZWN0X2NvbmZpZ19wYXRoLCAkdGhpcy0+YWxpYXMgKTsKCQkJJGNvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgPSAkY29uZmlndXJhdG9yLT50b19hcnJheSgpOwoJCQkkdGhpcy0+cmVxdWlyZWRfZmlsZXNbJ3Byb2plY3QnXSA9ICRjb25maWdbMF1bJ3JlcXVpcmUnXTsKCQl9CgoJCS8vIFJ1bnRpbWUgY29uZmlnIGFuZCBhcmdzCgkJewoJCQlsaXN0KCAkYXJncywgJGFzc29jX2FyZ3MsICR0aGlzLT5ydW50aW1lX2NvbmZpZyApID0gJGNvbmZpZ3VyYXRvci0+cGFyc2VfYXJncyggJGFyZ3YgKTsKCgkJCWxpc3QoICR0aGlzLT5hcmd1bWVudHMsICR0aGlzLT5hc3NvY19hcmdzICkgPSBzZWxmOjpiYWNrX2NvbXBhdF9jb252ZXJzaW9ucygKCQkJCSRhcmdzLAoJCQkJJGFzc29jX2FyZ3MKCQkJKTsKCgkJCSRjb25maWd1cmF0b3ItPm1lcmdlX2FycmF5KCAkdGhpcy0+cnVudGltZV9jb25maWcgKTsKCQl9CgoJCWxpc3QoICR0aGlzLT5jb25maWcsICR0aGlzLT5leHRyYV9jb25maWcgKSA9ICRjb25maWd1cmF0b3ItPnRvX2FycmF5KCk7CgkJJHRoaXMtPmFsaWFzZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gJGNvbmZpZ3VyYXRvci0+Z2V0X2FsaWFzZXMoKTsKCQlpZiAoIGNvdW50KCAkdGhpcy0+YWxpYXNlcyApICYmICEgaXNzZXQoICR0aGlzLT5hbGlhc2VzWydAYWxsJ10gKSApIHsKCQkJJHRoaXMtPmFsaWFzZXMgICAgICAgICA9IGFycmF5X3JldmVyc2UoICR0aGlzLT5hbGlhc2VzICk7CgkJCSR0aGlzLT5hbGlhc2VzWydAYWxsJ10gPSAnUnVuIGNvbW1hbmQgYWdhaW5zdCBldmVyeSByZWdpc3RlcmVkIGFsaWFzLic7CgkJCSR0aGlzLT5hbGlhc2VzICAgICAgICAgPSBhcnJheV9yZXZlcnNlKCAkdGhpcy0+YWxpYXNlcyApOwoJCX0KCQkkdGhpcy0+cmVxdWlyZWRfZmlsZXNbJ3J1bnRpbWUnXSA9ICR0aGlzLT5jb25maWdbJ3JlcXVpcmUnXTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3Jvb3QoKSB7CgkJaWYgKCAkdGhpcy0+Y29uZmlnWydhbGxvdy1yb290J10gfHwgZ2V0ZW52KCAnV1BfQ0xJX0FMTE9XX1JPT1QnICkgKSB7CgkJCXJldHVybjsgIyB0aGV5J3JlIGF3YXJlIG9mIHRoZSByaXNrcyEKCQl9CgkJaWYgKCBjb3VudCggJHRoaXMtPmFyZ3VtZW50cyApID49IDIgJiYgJ2NsaScgPT09ICR0aGlzLT5hcmd1bWVudHNbMF0gJiYgaW5fYXJyYXkoICR0aGlzLT5hcmd1bWVudHNbMV0sIFsgJ3VwZGF0ZScsICdpbmZvJyBdLCB0cnVlICkgKSB7CgkJCXJldHVybjsgIyBtYWtlIGl0IGVhc2llciB0byB1cGRhdGUgcm9vdC1vd25lZCBjb3BpZXMKCQl9CgkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3Bvc2l4X2dldGV1aWQnICkgKSB7CgkJCXJldHVybjsgIyBwb3NpeCBmdW5jdGlvbnMgbm90IGF2YWlsYWJsZQoJCX0KCQlpZiAoIHBvc2l4X2dldGV1aWQoKSAhPT0gMCApIHsKCQkJcmV0dXJuOyAjIG5vdCByb290CgkJfQoKCQlXUF9DTEk6OmVycm9yKAoJCQkiWUlLRVMhIEl0IGxvb2tzIGxpa2UgeW91J3JlIHJ1bm5pbmcgdGhpcyBhcyByb290LiBZb3UgcHJvYmFibHkgbWVhbnQgdG8gIiAuCgkJCSJydW4gdGhpcyBhcyB0aGUgdXNlciB0aGF0IHlvdXIgV29yZFByZXNzIGluc3RhbGxhdGlvbiBleGlzdHMgdW5kZXIuXG4iIC4KCQkJIlxuIiAuCgkJCSJJZiB5b3UgUkVBTExZIG1lYW4gdG8gcnVuIHRoaXMgYXMgcm9vdCwgd2Ugd29uJ3Qgc3RvcCB5b3UsIGJ1dCBqdXN0ICIgLgoJCQknYmVhciBpbiBtaW5kIHRoYXQgYW55IGNvZGUgb24gdGhpcyBzaXRlIHdpbGwgdGhlbiBoYXZlIGZ1bGwgY29udHJvbCBvZiAnIC4KCQkJInlvdXIgc2VydmVyLCBtYWtpbmcgaXQgcXVpdGUgREFOR0VST1VTLlxuIiAuCgkJCSJcbiIgLgoJCQkiSWYgeW91J2QgbGlrZSB0byBjb250aW51ZSBhcyByb290LCBwbGVhc2UgcnVuIHRoaXMgYWdhaW4sIGFkZGluZyB0aGlzICIgLgoJCQkiZmxhZzogIC0tYWxsb3ctcm9vdFxuIiAuCgkJCSJcbiIgLgoJCQkiSWYgeW91J2QgbGlrZSB0byBydW4gaXQgYXMgdGhlIHVzZXIgdGhhdCB0aGlzIHNpdGUgaXMgdW5kZXIsIHlvdSBjYW4gIiAuCgkJCSJydW4gdGhlIGZvbGxvd2luZyB0byBiZWNvbWUgdGhlIHJlc3BlY3RpdmUgdXNlcjpcbiIgLgoJCQkiXG4iIC4KCQkJIiAgICBzdWRvIC11IFVTRVIgLWkgLS0gd3AgPGNvbW1hbmQ+XG4iIC4KCQkJIlxuIgoJCSk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBydW5fYWxpYXNfZ3JvdXAoICRhbGlhc2VzICkgewoJCVV0aWxzXGNoZWNrX3Byb2NfYXZhaWxhYmxlKCAnZ3JvdXAgYWxpYXMnICk7CgoJCSRwaHBfYmluID0gZXNjYXBlc2hlbGxhcmcoIFV0aWxzXGdldF9waHBfYmluYXJ5KCkgKTsKCgkJJHNjcmlwdF9wYXRoID0gJEdMT0JBTFNbJ2FyZ3YnXVswXTsKCgkJaWYgKCBnZXRlbnYoICdXUF9DTElfQ09ORklHX1BBVEgnICkgKSB7CgkJCSRjb25maWdfcGF0aCA9IGdldGVudiggJ1dQX0NMSV9DT05GSUdfUEFUSCcgKTsKCQl9IGVsc2UgewoJCQkkY29uZmlnX3BhdGggPSBVdGlsc1xnZXRfaG9tZV9kaXIoKSAuICcvLndwLWNsaS9jb25maWcueW1sJzsKCQl9CgkJJGNvbmZpZ19wYXRoID0gZXNjYXBlc2hlbGxhcmcoICRjb25maWdfcGF0aCApOwoKCQlmb3JlYWNoICggJGFsaWFzZXMgYXMgJGFsaWFzICkgewoJCQlXUF9DTEk6OmxvZyggJGFsaWFzICk7CgkJCSRhcmdzICAgICAgICAgICA9IGltcGxvZGUoICcgJywgYXJyYXlfbWFwKCAnZXNjYXBlc2hlbGxhcmcnLCAkdGhpcy0+YXJndW1lbnRzICkgKTsKCQkJJGFzc29jX2FyZ3MgICAgID0gVXRpbHNcYXNzb2NfYXJnc190b19zdHIoICR0aGlzLT5hc3NvY19hcmdzICk7CgkJCSRydW50aW1lX2NvbmZpZyA9IFV0aWxzXGFzc29jX2FyZ3NfdG9fc3RyKCAkdGhpcy0+cnVudGltZV9jb25maWcgKTsKCQkJJGZ1bGxfY29tbWFuZCAgID0gIldQX0NMSV9DT05GSUdfUEFUSD17JGNvbmZpZ19wYXRofSB7JHBocF9iaW59IHskc2NyaXB0X3BhdGh9IHskYWxpYXN9IHskYXJnc317JGFzc29jX2FyZ3N9eyRydW50aW1lX2NvbmZpZ30iOwoJCQkkcGlwZXMgICAgICAgICAgPSBbXTsKCQkJJHByb2MgICAgICAgICAgID0gVXRpbHNccHJvY19vcGVuX2NvbXBhdCggJGZ1bGxfY29tbWFuZCwgWyBTVERJTiwgU1RET1VULCBTVERFUlIgXSwgJHBpcGVzICk7CgkJCXByb2NfY2xvc2UoICRwcm9jICk7CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc2V0X2FsaWFzKCAkYWxpYXMgKSB7CgkJJG9yaWdfY29uZmlnICA9ICR0aGlzLT5jb25maWc7CgkJJGFsaWFzX2NvbmZpZyA9ICR0aGlzLT5hbGlhc2VzWyAkYWxpYXMgXTsKCQkkdGhpcy0+Y29uZmlnID0gYXJyYXlfbWVyZ2UoICRvcmlnX2NvbmZpZywgJGFsaWFzX2NvbmZpZyApOwoJCWZvcmVhY2ggKCAkYWxpYXNfY29uZmlnIGFzICRrZXkgPT4gJF8gKSB7CgkJCWlmICggaXNzZXQoICRvcmlnX2NvbmZpZ1sgJGtleSBdICkgJiYgISBpc19udWxsKCAkb3JpZ19jb25maWdbICRrZXkgXSApICkgewoJCQkJJHRoaXMtPmFzc29jX2FyZ3NbICRrZXkgXSA9ICRvcmlnX2NvbmZpZ1sgJGtleSBdOwoJCQl9CgkJfQoJfQoKCXB1YmxpYyBmdW5jdGlvbiBzdGFydCgpIHsKCQkvLyBFbmFibGUgUEhQIGVycm9yIHJlcG9ydGluZyB0byBzdGRlcnIgaWYgdGVzdGluZy4gV2lsbCBuZWVkIHRvIGJlIHJlLWVuYWJsZWQgYWZ0ZXIgV1AgbG9hZHMuCgkJaWYgKCBnZXRlbnYoICdCRUhBVF9SVU4nICkgKSB7CgkJCSR0aGlzLT5lbmFibGVfZXJyb3JfcmVwb3J0aW5nKCk7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAkdGhpcy0+Z2xvYmFsX2NvbmZpZ19wYXRoX2RlYnVnLCAnYm9vdHN0cmFwJyApOwoJCVdQX0NMSTo6ZGVidWcoICR0aGlzLT5wcm9qZWN0X2NvbmZpZ19wYXRoX2RlYnVnLCAnYm9vdHN0cmFwJyApOwoJCVdQX0NMSTo6ZGVidWcoICdhcmd2OiAnIC4gaW1wbG9kZSggJyAnLCAkR0xPQkFMU1snYXJndiddICksICdib290c3RyYXAnICk7CgoJCSR0aGlzLT5jaGVja19yb290KCk7CgkJaWYgKCAkdGhpcy0+YWxpYXMgKSB7CgkJCWlmICggJ0BhbGwnID09PSAkdGhpcy0+YWxpYXMgJiYgISBpc3NldCggJHRoaXMtPmFsaWFzZXNbJ0BhbGwnXSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkNhbm5vdCB1c2UgJ0BhbGwnIHdoZW4gbm8gYWxpYXNlcyBhcmUgcmVnaXN0ZXJlZC4iICk7CgkJCX0KCgkJCWlmICggJ0BhbGwnID09PSAkdGhpcy0+YWxpYXMgJiYgaXNfc3RyaW5nKCAkdGhpcy0+YWxpYXNlc1snQGFsbCddICkgKSB7CgkJCQkkYWxpYXNlcyA9IGFycmF5X2tleXMoICR0aGlzLT5hbGlhc2VzICk7CgkJCQkkayAgICAgICA9IGFycmF5X3NlYXJjaCggJ0BhbGwnLCAkYWxpYXNlcywgdHJ1ZSApOwoJCQkJdW5zZXQoICRhbGlhc2VzWyAkayBdICk7CgkJCQkkdGhpcy0+cnVuX2FsaWFzX2dyb3VwKCAkYWxpYXNlcyApOwoJCQkJZXhpdDsKCQkJfQoKCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICR0aGlzLT5hbGlhcywgJHRoaXMtPmFsaWFzZXMgKSApIHsKCQkJCSRlcnJvcl9tc2cgID0gIkFsaWFzICd7JHRoaXMtPmFsaWFzfScgbm90IGZvdW5kLiI7CgkJCQkkc3VnZ2VzdGlvbiA9IFV0aWxzXGdldF9zdWdnZXN0aW9uKCAkdGhpcy0+YWxpYXMsIGFycmF5X2tleXMoICR0aGlzLT5hbGlhc2VzICksICR0aHJlc2hvbGQgPSAyICk7CgkJCQlpZiAoICRzdWdnZXN0aW9uICkgewoJCQkJCSRlcnJvcl9tc2cgLj0gUEhQX0VPTCAuICJEaWQgeW91IG1lYW4gJ3skc3VnZ2VzdGlvbn0nPyI7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAkZXJyb3JfbXNnICk7CgkJCX0KCQkJLy8gTnVtZXJpY2FsbHkgaW5kZXhlZCBtZWFucyBhIGdyb3VwIG9mIGFsaWFzZXMKCQkJaWYgKCBpc3NldCggJHRoaXMtPmFsaWFzZXNbICR0aGlzLT5hbGlhcyBdWzBdICkgKSB7CgkJCQkkZ3JvdXBfYWxpYXNlcyA9ICR0aGlzLT5hbGlhc2VzWyAkdGhpcy0+YWxpYXMgXTsKCQkJCSRhbGxfYWxpYXNlcyAgID0gYXJyYXlfa2V5cyggJHRoaXMtPmFsaWFzZXMgKTsKCQkJCSRkaWZmICAgICAgICAgID0gYXJyYXlfZGlmZiggJGdyb3VwX2FsaWFzZXMsICRhbGxfYWxpYXNlcyApOwoJCQkJaWYgKCAhIGVtcHR5KCAkZGlmZiApICkgewoJCQkJCVdQX0NMSTo6ZXJyb3IoICJHcm91cCAneyR0aGlzLT5hbGlhc30nIGNvbnRhaW5zIG9uZSBvciBtb3JlIGludmFsaWQgYWxpYXNlczogIiAuIGltcGxvZGUoICcsICcsICRkaWZmICkgKTsKCQkJCX0KCQkJCSR0aGlzLT5ydW5fYWxpYXNfZ3JvdXAoICRncm91cF9hbGlhc2VzICk7CgkJCQlleGl0OwoJCQl9CgoJCQkkdGhpcy0+c2V0X2FsaWFzKCAkdGhpcy0+YWxpYXMgKTsKCQl9CgoJCWlmICggZW1wdHkoICR0aGlzLT5hcmd1bWVudHMgKSApIHsKCQkJJHRoaXMtPmFyZ3VtZW50c1tdID0gJ2hlbHAnOwoJCX0KCgkJLy8gUHJvdGVjdCAnY2xpIGluZm8nIGZyb20gbW9zdCBvZiB0aGUgcnVudGltZSwKCQkvLyBleGNlcHQgd2hlbiB0aGUgY29tbWFuZCB3aWxsIGJlIHJ1biBvdmVyIFNTSAoJCWlmICggJ2NsaScgPT09ICR0aGlzLT5hcmd1bWVudHNbMF0gJiYgISBlbXB0eSggJHRoaXMtPmFyZ3VtZW50c1sxXSApICYmICdpbmZvJyA9PT0gJHRoaXMtPmFyZ3VtZW50c1sxXSAmJiAhICR0aGlzLT5jb25maWdbJ3NzaCddICkgewoJCQkkdGhpcy0+cnVuX2NvbW1hbmRfYW5kX2V4aXQoKTsKCQl9CgoJCWlmICggaXNzZXQoICR0aGlzLT5jb25maWdbJ2h0dHAnXSApICYmICEgY2xhc3NfZXhpc3RzKCAnXFdQX1JFU1RfQ0xJXFJ1bm5lcicgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlJFU1RmdWwgV1AtQ0xJIG5lZWRzIHRvIGJlIGluc3RhbGxlZC4gVHJ5ICd3cCBwYWNrYWdlIGluc3RhbGwgd3AtY2xpL3Jlc3RmdWwnLiIgKTsKCQl9CgoJCWlmICggJHRoaXMtPmNvbmZpZ1snc3NoJ10gKSB7CgkJCSR0aGlzLT5ydW5fc3NoX2NvbW1hbmQoICR0aGlzLT5jb25maWdbJ3NzaCddICk7CgkJCXJldHVybjsKCQl9CgoJCS8vIEhhbmRsZSAtLXBhdGggcGFyYW1ldGVyCgkJc2VsZjo6c2V0X3dwX3Jvb3QoICR0aGlzLT5maW5kX3dwX3Jvb3QoKSApOwoKCQkvLyBGaXJzdCB0cnkgYXQgc2hvd2luZyBtYW4gcGFnZSAtIGlmIGhlbHAgY29tbWFuZCBhbmQgZWl0aGVyIGhhdmVuJ3QgZm91bmQgJ3ZlcnNpb24ucGhwJyBvciAnd3AtY29uZmlnLnBocCcgKHNvIHdvbid0IGJlIGxvYWRpbmcgV1AgJiBhZGRpbmcgY29tbWFuZHMpIG9yIGhlbHAgb24gc3ViY29tbWFuZC4KCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2hlbHAnIF0gKQoJCQkmJiAoICEgJHRoaXMtPndwX2V4aXN0cygpCgkJCQl8fCAhIFV0aWxzXGxvY2F0ZV93cF9jb25maWcoKQoJCQkJfHwgY291bnQoICR0aGlzLT5hcmd1bWVudHMgKSA+IDIKCQkJKSApIHsKCQkJJHRoaXMtPmF1dG9fY2hlY2tfdXBkYXRlKCk7CgkJCSR0aGlzLT5ydW5fY29tbWFuZCggJHRoaXMtPmFyZ3VtZW50cywgJHRoaXMtPmFzc29jX2FyZ3MgKTsKCQkJLy8gSGVscCBkaWRuJ3QgZXhpdCBzbyBmYWlsZWQgdG8gZmluZCB0aGUgY29tbWFuZCBhdCB0aGlzIHN0YWdlLgoJCX0KCgkJLy8gSGFuZGxlIC0tdXJsIHBhcmFtZXRlcgoJCSR1cmwgPSBzZWxmOjpndWVzc191cmwoICR0aGlzLT5jb25maWcgKTsKCQlpZiAoICR1cmwgKSB7CgkJCVdQX0NMSTo6c2V0X3VybCggJHVybCApOwoJCX0KCgkJJHRoaXMtPmRvX2Vhcmx5X2ludm9rZSggJ2JlZm9yZV93cF9sb2FkJyApOwoKCQkkdGhpcy0+Y2hlY2tfd3BfdmVyc2lvbigpOwoKCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2NvbmZpZycsICdjcmVhdGUnIF0gKSApIHsKCQkJJHRoaXMtPnJ1bl9jb21tYW5kX2FuZF9leGl0KCk7CgkJfQoKCQlpZiAoICEgVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpICkgewoJCQlXUF9DTEk6OmVycm9yKAoJCQkJIid3cC1jb25maWcucGhwJyBub3QgZm91bmQuXG4iIC4KCQkJCSdFaXRoZXIgY3JlYXRlIG9uZSBtYW51YWxseSBvciB1c2UgYHdwIGNvbmZpZyBjcmVhdGVgLicKCQkJKTsKCQl9CgoJCS8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIERlY2xhcmluZyBXUCBuYXRpdmUgY29uc3RhbnRzLgoKCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2NvcmUnLCAnaXMtaW5zdGFsbGVkJyBdICkKCQkJfHwgJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnY29yZScsICd1cGRhdGUtZGInIF0gKSApIHsKCQkJZGVmaW5lKCAnV1BfSU5TVEFMTElORycsIHRydWUgKTsKCQl9CgoJCWlmICgKCQkJY291bnQoICR0aGlzLT5hcmd1bWVudHMgKSA+PSAyICYmCgkJCSdjb3JlJyA9PT0gJHRoaXMtPmFyZ3VtZW50c1swXSAmJgoJCQlpbl9hcnJheSggJHRoaXMtPmFyZ3VtZW50c1sxXSwgWyAnaW5zdGFsbCcsICdtdWx0aXNpdGUtaW5zdGFsbCcgXSwgdHJ1ZSApCgkJKSB7CgkJCWRlZmluZSggJ1dQX0lOU1RBTExJTkcnLCB0cnVlICk7CgoJCQkvLyBXZSByZWFsbHkgbmVlZCBhIFVSTCBoZXJlCgkJCWlmICggISBpc3NldCggJF9TRVJWRVJbJ0hUVFBfSE9TVCddICkgKSB7CgkJCQkkdXJsID0gJ2h0dHA6Ly9leGFtcGxlLmNvbSc7CgkJCQlXUF9DTEk6OnNldF91cmwoICR1cmwgKTsKCQkJfQoKCQkJaWYgKCAnbXVsdGlzaXRlLWluc3RhbGwnID09PSAkdGhpcy0+YXJndW1lbnRzWzFdICkgewoJCQkJLy8gbmVlZCB0byBmYWtlIHNvbWUgZ2xvYmFscyB0byBza2lwIHRoZSBjaGVja3MgaW4gd3AtaW5jbHVkZXMvbXMtc2V0dGluZ3MucGhwCgkJCQkkdXJsX3BhcnRzID0gVXRpbHNccGFyc2VfdXJsKCAkdXJsICk7CgkJCQlzZWxmOjpmYWtlX2N1cnJlbnRfc2l0ZV9ibG9nKCAkdXJsX3BhcnRzICk7CgoJCQkJaWYgKCAhIGRlZmluZWQoICdDT09LSUVIQVNIJyApICkgewoJCQkJCWRlZmluZSggJ0NPT0tJRUhBU0gnLCBtZDUoICR1cmxfcGFydHNbJ2hvc3QnXSApICk7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaW1wb3J0JyBdICkgKSB7CgkJCWRlZmluZSggJ1dQX0xPQURfSU1QT1JURVJTJywgdHJ1ZSApOwoJCQlkZWZpbmUoICdXUF9JTVBPUlRJTkcnLCB0cnVlICk7CgkJfQoKCQlpZiAoICR0aGlzLT5jbWRfc3RhcnRzX3dpdGgoIFsgJ2Nyb24nLCAnZXZlbnQnLCAncnVuJyBdICkgKSB7CgkJCWRlZmluZSggJ0RPSU5HX0NST04nLCB0cnVlICk7CgkJfQoJCS8vIHBocGNzOmVuYWJsZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQKCgkJJHRoaXMtPmxvYWRfd29yZHByZXNzKCk7CgoJCSR0aGlzLT5ydW5fY29tbWFuZF9hbmRfZXhpdCgpOwoKCX0KCgkvKioKCSAqIExvYWQgV29yZFByZXNzLCBpZiBpdCBoYXNuJ3QgYWxyZWFkeSBiZWVuIGxvYWRlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gbG9hZF93b3JkcHJlc3MoKSB7CgkJc3RhdGljICR3cF9jbGlfaXNfbG9hZGVkOwoJCS8vIEdsb2JhbHMgbm90IGV4cGxpY2l0bHkgZ2xvYmFsaXplZCBpbiBXb3JkUHJlc3MKCQlnbG9iYWwgJHNpdGVfaWQsICR3cGRiLCAkcHVibGljLCAkY3VycmVudF9zaXRlLCAkY3VycmVudF9ibG9nLCAkcGF0aCwgJHNob3J0Y29kZV90YWdzOwoKCQlpZiAoICEgZW1wdHkoICR3cF9jbGlfaXNfbG9hZGVkICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSR3cF9jbGlfaXNfbG9hZGVkID0gdHJ1ZTsKCgkJV1BfQ0xJOjpkZWJ1ZyggJ0JlZ2luIFdvcmRQcmVzcyBsb2FkJywgJ2Jvb3RzdHJhcCcgKTsKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfd3BfbG9hZCcgKTsKCgkJJHRoaXMtPmNoZWNrX3dwX3ZlcnNpb24oKTsKCgkJJHdwX2NvbmZpZ19wYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoJCWlmICggISAkd3BfY29uZmlnX3BhdGggKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiJ3dwLWNvbmZpZy5waHAnIG5vdCBmb3VuZC5cbiIgLgoJCQkJJ0VpdGhlciBjcmVhdGUgb25lIG1hbnVhbGx5IG9yIHVzZSBgd3AgY29uZmlnIGNyZWF0ZWAuJwoJCQkpOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ3dwLWNvbmZpZy5waHAgcGF0aDogJyAuICR3cF9jb25maWdfcGF0aCwgJ2Jvb3RzdHJhcCcgKTsKCQlXUF9DTEk6OmRvX2hvb2soICdiZWZvcmVfd3BfY29uZmlnX2xvYWQnICk7CgoJCS8vIExvYWQgd3AtY29uZmlnLnBocCBjb2RlLCBpbiB0aGUgZ2xvYmFsIHNjb3BlCgkJJHdwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMgPSBnZXRfZGVmaW5lZF92YXJzKCk7CgoJCWV2YWwoICR0aGlzLT5nZXRfd3BfY29uZmlnX2NvZGUoKSApOyAvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQKCgkJZm9yZWFjaCAoIGdldF9kZWZpbmVkX3ZhcnMoKSBhcyAka2V5ID0+ICR2YXIgKSB7CgkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgJHdwX2NsaV9vcmlnaW5hbF9kZWZpbmVkX3ZhcnMgKSB8fCAnd3BfY2xpX29yaWdpbmFsX2RlZmluZWRfdmFycycgPT09ICRrZXkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuVmFyaWFibGVzLkZvcmJpZGRlbkdsb2JhbFZhcmlhYmxlVmFyaWFibGUuTm9uQmFyZVZhcmlhYmxlRm91bmQKCQkJZ2xvYmFsICR7JGtleX07CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZFZhcmlhYmxlRm91bmQKCQkJJHska2V5fSA9ICR2YXI7CgkJfQoKCQkkdGhpcy0+bWF5YmVfdXBkYXRlX3VybF9mcm9tX2RvbWFpbl9jb25zdGFudCgpOwoJCVdQX0NMSTo6ZG9faG9vayggJ2FmdGVyX3dwX2NvbmZpZ19sb2FkJyApOwoJCSR0aGlzLT5kb19lYXJseV9pbnZva2UoICdhZnRlcl93cF9jb25maWdfbG9hZCcgKTsKCgkJLy8gUHJldmVudCBlcnJvciBub3RpY2UgZnJvbSB3cF9ndWVzc191cmwoKSB3aGVuIGNvcmUgaXNuJ3QgaW5zdGFsbGVkCgkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjb3JlJywgJ2lzLWluc3RhbGxlZCcgXSApCgkJCSYmICEgZGVmaW5lZCggJ0NPT0tJRUhBU0gnICkgKSB7CgkJCWRlZmluZSggJ0NPT0tJRUhBU0gnLCBtZDUoICd3cC1jbGknICkgKTsKCQl9CgoJCS8vIExvYWQgV1AtQ0xJIHV0aWxpdGllcwoJCXJlcXVpcmUgV1BfQ0xJX1JPT1QgLiAnL3BocC91dGlscy13cC5waHAnOwoKCQkvLyBTZXQgdXAgV29yZFByZXNzIGJvb3RzdHJhcCBhY3Rpb25zIGFuZCBmaWx0ZXJzCgkJJHRoaXMtPnNldHVwX2Jvb3RzdHJhcF9ob29rcygpOwoKCQkvLyBMb2FkIENvcmUsIG11LXBsdWdpbnMsIHBsdWdpbnMsIHRoZW1lcyBldGMuCgkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjYtYWxwaGEtMzc1NzUnLCAnPj0nICkgKSB7CgkJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApICkgewoJCQkJLy8gSGFjazogZGVmaW5lIGBXUF9ERUJVR2AgYW5kIGBXUF9ERUJVR19ESVNQTEFZYCB0byBnZXQgYHdwZGI6OmJhaWwoKWAgdG8gYHdwX2RpZSgpYC4KCQkJCWlmICggISBkZWZpbmVkKCAnV1BfREVCVUcnICkgKSB7CgkJCQkJZGVmaW5lKCAnV1BfREVCVUcnLCB0cnVlICk7CgkJCQl9CgkJCQlpZiAoICEgZGVmaW5lZCggJ1dQX0RFQlVHX0RJU1BMQVknICkgKSB7CgkJCQkJZGVmaW5lKCAnV1BfREVCVUdfRElTUExBWScsIHRydWUgKTsKCQkJCX0KCQkJfQoJCQlyZXF1aXJlIEFCU1BBVEggLiAnd3Atc2V0dGluZ3MucGhwJzsKCQl9IGVsc2UgewoJCQlyZXF1aXJlIFdQX0NMSV9ST09UIC4gJy9waHAvd3Atc2V0dGluZ3MtY2xpLnBocCc7CgkJfQoKCQkvLyBGaXggbWVtb3J5IGxpbWl0LiBTZWUgaHR0cHM6Ly9jb3JlLnRyYWMud29yZHByZXNzLm9yZy90aWNrZXQvMTQ4ODkKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5JbmlTZXQubWVtb3J5X2xpbWl0X0JsYWNrbGlzdGVkIC0tIFRoaXMgaXMgcGVyZmVjdGx5IGZpbmUgZm9yIENMSSB1c2FnZS4KCQlpbmlfc2V0KCAnbWVtb3J5X2xpbWl0JywgLTEgKTsKCgkJLy8gTG9hZCBhbGwgdGhlIGFkbWluIEFQSXMsIGZvciBjb252ZW5pZW5jZQoJCXJlcXVpcmUgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9hZG1pbi5waHAnOwoKCQlhZGRfZmlsdGVyKAoJCQknZmlsZXN5c3RlbV9tZXRob2QnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJcmV0dXJuICdkaXJlY3QnOwoJCQl9LAoJCQk5OQoJCSk7CgoJCS8vIFJlLWVuYWJsZSBQSFAgZXJyb3IgcmVwb3J0aW5nIHRvIHN0ZGVyciBpZiB0ZXN0aW5nLgoJCWlmICggZ2V0ZW52KCAnQkVIQVRfUlVOJyApICkgewoJCQkkdGhpcy0+ZW5hYmxlX2Vycm9yX3JlcG9ydGluZygpOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ0xvYWRlZCBXb3JkUHJlc3MnLCAnYm9vdHN0cmFwJyApOwoJCVdQX0NMSTo6ZG9faG9vayggJ2FmdGVyX3dwX2xvYWQnICk7CgoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZha2VfY3VycmVudF9zaXRlX2Jsb2coICR1cmxfcGFydHMgKSB7CgkJZ2xvYmFsICRjdXJyZW50X3NpdGUsICRjdXJyZW50X2Jsb2c7CgoJCWlmICggISBpc3NldCggJHVybF9wYXJ0c1sncGF0aCddICkgKSB7CgkJCSR1cmxfcGFydHNbJ3BhdGgnXSA9ICcvJzsKCQl9CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBJbnRlbnRpb25hbCBvdmVycmlkZS4KCQkkY3VycmVudF9zaXRlID0gKG9iamVjdCkgWwoJCQknaWQnICAgICAgICAgICAgPT4gMSwKCQkJJ2Jsb2dfaWQnICAgICAgID0+IDEsCgkJCSdkb21haW4nICAgICAgICA9PiAkdXJsX3BhcnRzWydob3N0J10sCgkJCSdwYXRoJyAgICAgICAgICA9PiAkdXJsX3BhcnRzWydwYXRoJ10sCgkJCSdjb29raWVfZG9tYWluJyA9PiAkdXJsX3BhcnRzWydob3N0J10sCgkJCSdzaXRlX25hbWUnICAgICA9PiAnRmFrZSBTaXRlJywKCQldOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gSW50ZW50aW9uYWwgb3ZlcnJpZGUuCgkJJGN1cnJlbnRfYmxvZyA9IChvYmplY3QpIFsKCQkJJ2Jsb2dfaWQnICA9PiAxLAoJCQknc2l0ZV9pZCcgID0+IDEsCgkJCSdkb21haW4nICAgPT4gJHVybF9wYXJ0c1snaG9zdCddLAoJCQkncGF0aCcgICAgID0+ICR1cmxfcGFydHNbJ3BhdGgnXSwKCQkJJ3B1YmxpYycgICA9PiAnMScsCgkJCSdhcmNoaXZlZCcgPT4gJzAnLAoJCQknbWF0dXJlJyAgID0+ICcwJywKCQkJJ3NwYW0nICAgICA9PiAnMCcsCgkJCSdkZWxldGVkJyAgPT4gJzAnLAoJCQknbGFuZ19pZCcgID0+ICcwJywKCQldOwoJfQoKCS8qKgoJICogQ2FsbGVkIGFmdGVyIHdwLWNvbmZpZy5waHAgaXMgZXZhbCdkLCB0byBwb3RlbnRpYWxseSByZXNldCBgLS11cmxgCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbWF5YmVfdXBkYXRlX3VybF9mcm9tX2RvbWFpbl9jb25zdGFudCgpIHsKCQlpZiAoICEgZW1wdHkoICR0aGlzLT5jb25maWdbJ3VybCddICkgfHwgISBlbXB0eSggJHRoaXMtPmNvbmZpZ1snYmxvZyddICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggZGVmaW5lZCggJ0RPTUFJTl9DVVJSRU5UX1NJVEUnICkgKSB7CgkJCSR1cmwgPSBET01BSU5fQ1VSUkVOVF9TSVRFOwoJCQlpZiAoIGRlZmluZWQoICdQQVRIX0NVUlJFTlRfU0lURScgKSApIHsKCQkJCSR1cmwgLj0gUEFUSF9DVVJSRU5UX1NJVEU7CgkJCX0KCQkJV1BfQ0xJOjpzZXRfdXJsKCAkdXJsICk7CgkJfQoJfQoKCS8qKgoJICogU2V0IHVwIGhvb2tzIG1lYW50IHRvIHJ1biBkdXJpbmcgdGhlIFdvcmRQcmVzcyBib290c3RyYXAgcHJvY2VzcwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHNldHVwX2Jvb3RzdHJhcF9ob29rcygpIHsKCgkJaWYgKCAkdGhpcy0+Y29uZmlnWydza2lwLXBsdWdpbnMnXSApIHsKCQkJJHRoaXMtPnNldHVwX3NraXBfcGx1Z2luc19maWx0ZXJzKCk7CgkJfQoKCQlpZiAoICR0aGlzLT5jb25maWdbJ3NraXAtdGhlbWVzJ10gKSB7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soICdzZXR1cF90aGVtZScsIFsgJHRoaXMsICdhY3Rpb25fc2V0dXBfdGhlbWVfd3BfY2xpX3NraXBfdGhlbWVzJyBdLCA5OTkgKTsKCQl9CgoJCWlmICggJHRoaXMtPmNtZF9zdGFydHNfd2l0aCggWyAnaGVscCcgXSApICkgewoJCQkvLyBUcnkgdG8gdHJhcCBlcnJvcnMgb24gaGVscC4KCQkJJGhlbHBfaGFuZGxlciA9IFsgJHRoaXMsICdoZWxwX3dwX2RpZV9oYW5kbGVyJyBdOyAvLyBBdm9pZCBhbnkgY3Jvc3MgUEhQIHZlcnNpb24gaXNzdWVzIGJ5IG5vdCB1c2luZyAkdGhpcyBpbiBhbm9uIGZ1bmN0aW9uLgoJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJJ3dwX2RpZV9oYW5kbGVyJywKCQkJCWZ1bmN0aW9uICgpIHVzZSAoICRoZWxwX2hhbmRsZXIgKSB7CgkJCQkJcmV0dXJuICRoZWxwX2hhbmRsZXI7CgkJCQl9CgkJCSk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJCSd3cF9kaWVfaGFuZGxlcicsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJCXJldHVybiAnXFdQX0NMSVxVdGlsc1x3cF9kaWVfaGFuZGxlcic7CgkJCQl9CgkJCSk7CgkJfQoKCQkvLyBQcmV2ZW50IGNvZGUgZnJvbSBwZXJmb3JtaW5nIGEgcmVkaXJlY3QKCQlXUF9DTEk6OmFkZF93cF9ob29rKCAnd3BfcmVkaXJlY3QnLCAnV1BfQ0xJXFxVdGlsc1xcd3BfcmVkaXJlY3RfaGFuZGxlcicgKTsKCgkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJJ25vY2FjaGVfaGVhZGVycycsCgkJCXN0YXRpYyBmdW5jdGlvbiAoICRoZWFkZXJzICkgewoJCQkJLy8gV29yZFByZXNzIG1pZ2h0IGJlIGNhbGxpbmcgbm9jYWNoZV9oZWFkZXJzKCkgYmVjYXVzZSBvZiBhIGRlYWQgZGIKCQkJCWdsb2JhbCAkd3BkYjsKCQkJCWlmICggISBlbXB0eSggJHdwZGItPmVycm9yICkgKSB7CgkJCQkJVXRpbHNcd3BfZGllX2hhbmRsZXIoICR3cGRiLT5lcnJvciApOwoJCQkJfQoJCQkJLy8gT3RoZXJ3aXNlLCBXUCBtaWdodCBiZSBjYWxsaW5nIG5vY2FjaGVfaGVhZGVycygpIGJlY2F1c2UgV1AgaXNuJ3QgaW5zdGFsbGVkCgkJCQlVdGlsc1x3cF9ub3RfaW5zdGFsbGVkKCk7CgkJCQlyZXR1cm4gJGhlYWRlcnM7CgkJCX0KCQkpOwoKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknc2V0dXBfdGhlbWUnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJLy8gUG9seWZpbGwgaXNfY3VzdG9taXplX3ByZXZpZXcoKSwgYXMgaXQgaXMgbmVlZGVkIGJ5IFR3ZW50eVR3ZW50eSB0bwoJCQkJLy8gY2hlY2sgZm9yIHN0YXJ0ZXIgY29udGVudC4KCQkJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdpc19jdXN0b21pemVfcHJldmlldycgKSApIHsKCQkJCQlmdW5jdGlvbiBpc19jdXN0b21pemVfcHJldmlldygpIHsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfSwKCQkJMAoJCSk7CgoJCS8vIEFMVEVSTkFURV9XUF9DUk9OIG1pZ2h0IHRyaWdnZXIgYSByZWRpcmVjdCwgd2hpY2ggd2UgY2FuJ3QgaGFuZGxlCgkJaWYgKCBkZWZpbmVkKCAnQUxURVJOQVRFX1dQX0NST04nICkgJiYgQUxURVJOQVRFX1dQX0NST04gKSB7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQknbXVwbHVnaW5zX2xvYWRlZCcsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJCXJlbW92ZV9hY3Rpb24oICdpbml0JywgJ3dwX2Nyb24nICk7CgkJCQl9CgkJCSk7CgkJfQoKCQkvLyBHZXQgcmlkIG9mIHdhcm5pbmdzIHdoZW4gY29udmVydGluZyBzaW5nbGUgc2l0ZSB0byBtdWx0aXNpdGUKCQlpZiAoIGRlZmluZWQoICdXUF9JTlNUQUxMSU5HJyApICYmICR0aGlzLT5pc19tdWx0aXNpdGUoKSApIHsKCQkJJHZhbHVlcyA9IFsKCQkJCSdtc19maWxlc19yZXdyaXRpbmcnICAgICAgICAgICAgID0+IG51bGwsCgkJCQknYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnICAgICAgICA9PiBbXSwKCQkJCSdfc2l0ZV90cmFuc2llbnRfdXBkYXRlX2NvcmUnICAgID0+IG51bGwsCgkJCQknX3NpdGVfdHJhbnNpZW50X3VwZGF0ZV90aGVtZXMnICA9PiBudWxsLAoJCQkJJ19zaXRlX3RyYW5zaWVudF91cGRhdGVfcGx1Z2lucycgPT4gbnVsbCwKCQkJCSdXUExBTkcnICAgICAgICAgICAgICAgICAgICAgICAgID0+ICcnLAoJCQldOwoJCQlmb3JlYWNoICggJHZhbHVlcyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQkJInByZV9zaXRlX29wdGlvbl8ka2V5IiwKCQkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICggJHZhbHVlcywgJGtleSApIHsKCQkJCQkJcmV0dXJuICR2YWx1ZXNbICRrZXkgXTsKCQkJCQl9CgkJCQkpOwoJCQl9CgkJfQoKCQkvLyBBbHdheXMgcGVybWl0IG9wZXJhdGlvbnMgYWdhaW5zdCBzaXRlcywgcmVnYXJkbGVzcyBvZiBzdGF0dXMKCQlXUF9DTEk6OmFkZF93cF9ob29rKCAnbXNfc2l0ZV9jaGVjaycsICdfX3JldHVybl90cnVlJyApOwoKCQkvLyBBbHdheXMgcGVybWl0IG9wZXJhdGlvbnMgYWdhaW5zdCBXb3JkUHJlc3MsIHJlZ2FyZGxlc3Mgb2YgbWFpbnRlbmFuY2UgbW9kZQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdlbmFibGVfbWFpbnRlbmFuY2VfbW9kZScsCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkpOwoKCQkvLyBVc2Ugb3VyIG93biBkZWJ1ZyBtb2RlIGhhbmRsaW5nIGluc3RlYWQgb2YgV1AgY29yZQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdlbmFibGVfd3BfZGVidWdfbW9kZV9jaGVja3MnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkcmV0ICkgewoJCQkJVXRpbHNcd3BfZGVidWdfbW9kZSgpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJKTsKCgkJLy8gTmV2ZXIgbG9hZCBhZHZhbmNlZC1jYWNoZS5waHAgZHJvcC1pbiB3aGVuIFdQLUNMSSBpcyBvcGVyYXRpbmcKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknZW5hYmxlX2xvYWRpbmdfYWR2YW5jZWRfY2FjaGVfZHJvcGluJywKCQkJc3RhdGljIGZ1bmN0aW9uICgpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCSk7CgoJCS8vIEluIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbiwgZGllIGlmIHVuYWJsZSB0byBmaW5kIHNpdGUgZ2l2ZW4gaW4gLS11cmwgcGFyYW1ldGVyCgkJaWYgKCAkdGhpcy0+aXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRydW5fb25fc2l0ZV9ub3RfZm91bmQgPSBmYWxzZTsKCQkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdjYWNoZScsICdmbHVzaCcgXSApICkgewoJCQkJJHJ1bl9vbl9zaXRlX25vdF9mb3VuZCA9ICdjYWNoZSBmbHVzaCc7CgkJCX0KCQkJaWYgKCAkdGhpcy0+Y21kX3N0YXJ0c193aXRoKCBbICdzZWFyY2gtcmVwbGFjZScgXSApICkgewoJCQkJLy8gVGFibGUtc3BlY2lmaWVkCgkJCQkvLyBCaXRzOiBzZWFyY2gtcmVwbGFjZSA8c2VhcmNoPiA8cmVwbGFjZT4gWzx0YWJsZT4uLi5dCgkJCQkvLyBPciBub3QgYWdhaW5zdCBhIHNwZWNpZmljIGJsb2cKCQkJCWlmICggY291bnQoICR0aGlzLT5hcmd1bWVudHMgKSA+IDMKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snbmV0d29yayddICkKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snYWxsLXRhYmxlcyddICkKCQkJCQl8fCAhIGVtcHR5KCAkdGhpcy0+YXNzb2NfYXJnc1snYWxsLXRhYmxlcy13aXRoLXByZWZpeCddICkgKSB7CgkJCQkJJHJ1bl9vbl9zaXRlX25vdF9mb3VuZCA9ICdzZWFyY2gtcmVwbGFjZSc7CgkJCQl9CgkJCX0KCQkJaWYgKCAkcnVuX29uX3NpdGVfbm90X2ZvdW5kCgkJCQkmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjAnLCAnPj0nICkgKSB7CgkJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJCSdtc19zaXRlX25vdF9mb3VuZCcsCgkJCQkJc3RhdGljIGZ1bmN0aW9uICgpIHVzZSAoICRydW5fb25fc2l0ZV9ub3RfZm91bmQgKSB7CgkJCQkJCS8vIGVzY19zcWwoKSBpc24ndCB5ZXQgbG9hZGVkLCBidXQgbmVlZGVkLgoJCQkJCQlpZiAoICdzZWFyY2gtcmVwbGFjZScgPT09ICRydW5fb25fc2l0ZV9ub3RfZm91bmQgKSB7CgkJCQkJCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuIFdQSU5DIC4gJy9mb3JtYXR0aW5nLnBocCc7CgkJCQkJCX0KCQkJCQkJLy8gUEhQIDUuMyBjb21wYXRpYmxlIGltcGxlbWVudGF0aW9uIG9mIHJ1bl9jb21tYW5kX2FuZF9leGl0KCkuCgkJCQkJCSRydW5uZXIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKTsKCQkJCQkJJHJ1bm5lci0+cnVuX2NvbW1hbmQoICRydW5uZXItPmFyZ3VtZW50cywgJHJ1bm5lci0+YXNzb2NfYXJncyApOwoJCQkJCQlleGl0OwoJCQkJCX0sCgkJCQkJMQoJCQkJKTsKCQkJfQoJCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQkJJ21zX3NpdGVfbm90X2ZvdW5kJywKCQkJCXN0YXRpYyBmdW5jdGlvbiAoICRjdXJyZW50X3NpdGUsICRkb21haW4sICRwYXRoICkgewoJCQkJCSR1cmwgICAgICAgICA9ICRkb21haW4gLiAkcGF0aDsKCQkJCQkkbWVzc2FnZSAgICAgPSAkdXJsID8gIlNpdGUgJ3skdXJsfScgbm90IGZvdW5kLiIgOiAnU2l0ZSBub3QgZm91bmQuJzsKCQkJCQkkaGFzX3BhcmFtICAgPSBpc3NldCggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1sndXJsJ10gKTsKCQkJCQkkaGFzX2NvbnN0ICAgPSBkZWZpbmVkKCAnRE9NQUlOX0NVUlJFTlRfU0lURScgKTsKCQkJCQkkZXhwbGFuYXRpb24gPSAnJzsKCQkJCQlpZiAoICRoYXNfcGFyYW0gKSB7CgkJCQkJCSRleHBsYW5hdGlvbiA9ICdWZXJpZnkgYC0tdXJsPTx1cmw+YCBtYXRjaGVzIGFuIGV4aXN0aW5nIHNpdGUuJzsKCQkJCQl9IGVsc2UgewoJCQkJCQkkZXhwbGFuYXRpb24gPSAiRGVmaW5lIERPTUFJTl9DVVJSRU5UX1NJVEUgaW4gJ3dwLWNvbmZpZy5waHAnIG9yIHVzZSBgLS11cmw9PHVybD5gIHRvIG92ZXJyaWRlLiI7CgoJCQkJCQlpZiAoICRoYXNfY29uc3QgKSB7CgkJCQkJCQkkZXhwbGFuYXRpb24gPSAnVmVyaWZ5IERPTUFJTl9DVVJSRU5UX1NJVEUgbWF0Y2hlcyBhbiBleGlzdGluZyBzaXRlIG9yIHVzZSBgLS11cmw9PHVybD5gIHRvIG92ZXJyaWRlLic7CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYgKCAkZXhwbGFuYXRpb24gKSB7CgkJCQkJCSRtZXNzYWdlIC49ICcgJyAuICRleHBsYW5hdGlvbjsKCQkJCQl9CgkJCQkJV1BfQ0xJOjplcnJvciggJG1lc3NhZ2UgKTsKCQkJCX0sCgkJCQkxMCwKCQkJCTMKCQkJKTsKCQl9CgoJCS8vIFRoZSBBUEMgY2FjaGUgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgY29tbWFuZC1saW5lLCBzbyBiYWlsLCB0byBwcmV2ZW50IGNhY2hlIHBvaXNvbmluZwoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdtdXBsdWdpbnNfbG9hZGVkJywKCQkJc3RhdGljIGZ1bmN0aW9uICgpIHsKCQkJCWlmICggJEdMT0JBTFNbJ193cF91c2luZ19leHRfb2JqZWN0X2NhY2hlJ10gJiYgY2xhc3NfZXhpc3RzKCAnQVBDX09iamVjdF9DYWNoZScgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICdSdW5uaW5nIFdQLUNMSSB3aGlsZSB0aGUgQVBDIG9iamVjdCBjYWNoZSBpcyBhY3RpdmF0ZWQgY2FuIHJlc3VsdCBpbiBjYWNoZSBjb3JydXB0aW9uLicgKTsKCQkJCQlXUF9DTEk6OmNvbmZpcm0oICdHaXZlbiB0aGUgY29uc2VxdWVuY2VzLCBkbyB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7CgkJCQl9CgkJCX0sCgkJCTAKCQkpOwoKCQkvLyBIYW5kbGUgLS11c2VyIHBhcmFtZXRlcgoJCWlmICggISBkZWZpbmVkKCAnV1BfSU5TVEFMTElORycgKSApIHsKCQkJJGNvbmZpZyA9ICR0aGlzLT5jb25maWc7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCQknaW5pdCcsCgkJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICggJGNvbmZpZyApIHsKCQkJCQlpZiAoIGlzc2V0KCAkY29uZmlnWyd1c2VyJ10gKSApIHsKCQkJCQkJJGZldGNoZXIgPSBuZXcgRmV0Y2hlcnNcVXNlcigpOwoJCQkJCQkkdXNlciAgICA9ICRmZXRjaGVyLT5nZXRfY2hlY2soICRjb25maWdbJ3VzZXInXSApOwoJCQkJCQl3cF9zZXRfY3VycmVudF91c2VyKCAkdXNlci0+SUQgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlhZGRfYWN0aW9uKCAnaW5pdCcsICdrc2VzX3JlbW92ZV9maWx0ZXJzJywgMTEgKTsKCQkJCQl9CgkJCQl9LAoJCQkJMAoJCQkpOwoJCX0KCgkJLy8gQXZvaWQgdW5jYXVnaHQgZXhjZXB0aW9uIHdoZW4gdXNpbmcgd3BfbWFpbCgpIHdpdGhvdXQgZGVmaW5lZCAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSd3cF9tYWlsX2Zyb20nLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkZnJvbV9lbWFpbCApIHsKCQkJCWlmICggJ3dvcmRwcmVzc0AnID09PSAkZnJvbV9lbWFpbCApIHsKCQkJCQkkc2l0ZW5hbWUgPSBzdHJ0b2xvd2VyKCBVdGlsc1xwYXJzZV91cmwoIHNpdGVfdXJsKCksIFBIUF9VUkxfSE9TVCApICk7CgkJCQkJaWYgKCBzdWJzdHIoICRzaXRlbmFtZSwgMCwgNCApID09PSAnd3d3LicgKSB7CgkJCQkJCSRzaXRlbmFtZSA9IHN1YnN0ciggJHNpdGVuYW1lLCA0ICk7CgkJCQkJfQoJCQkJCSRmcm9tX2VtYWlsID0gJ3dvcmRwcmVzc0AnIC4gJHNpdGVuYW1lOwoJCQkJfQoJCQkJcmV0dXJuICRmcm9tX2VtYWlsOwoJCQl9CgkJKTsKCgkJLy8gRG9uJ3QgYXBwbHkgc2V0X3VybF9zY2hlbWUgaW4gZ2V0X3NpdGVfdXJsKCkKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknc2l0ZV91cmwnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCAkdXJsLCAkcGF0aCwgJHNjaGVtZSwgJGJsb2dfaWQgKSB7CgkJCQlpZiAoIGVtcHR5KCAkYmxvZ19pZCApIHx8ICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQkJJHVybCA9IGdldF9vcHRpb24oICdzaXRldXJsJyApOwoJCQkJfSBlbHNlIHsKCQkJCQlzd2l0Y2hfdG9fYmxvZyggJGJsb2dfaWQgKTsKCQkJCQkkdXJsID0gZ2V0X29wdGlvbiggJ3NpdGV1cmwnICk7CgkJCQkJcmVzdG9yZV9jdXJyZW50X2Jsb2coKTsKCQkJCX0KCQkJCWlmICggJHBhdGggJiYgaXNfc3RyaW5nKCAkcGF0aCApICkgewoJCQkJCSR1cmwgLj0gJy8nIC4gbHRyaW0oICRwYXRoLCAnLycgKTsKCQkJCX0KCQkJCXJldHVybiAkdXJsOwoJCQl9LAoJCQkwLAoJCQk0CgkJKTsKCgkJLy8gU2V0IHVwIGhvb2sgZm9yIHBsdWdpbnMgYW5kIHRoZW1lcyB0byBjb25kaXRpb25hbGx5IGFkZCBXUC1DTEkgY29tbWFuZHMuCgkJV1BfQ0xJOjphZGRfd3BfaG9vaygKCQkJJ2luaXQnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgewoJCQkJZG9fYWN0aW9uKCAnY2xpX2luaXQnICk7CgkJCX0KCQkpOwoJfQoKCS8qKgoJICogU2V0IHVwIHRoZSBmaWx0ZXJzIHRvIHNraXAgdGhlIGxvYWRlZCBwbHVnaW5zCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gc2V0dXBfc2tpcF9wbHVnaW5zX2ZpbHRlcnMoKSB7CgkJJHdwX2NsaV9maWx0ZXJfYWN0aXZlX3BsdWdpbnMgPSBzdGF0aWMgZnVuY3Rpb24gKCAkcGx1Z2lucyApIHsKCQkJJHNraXBwZWRfcGx1Z2lucyA9IFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5jb25maWdbJ3NraXAtcGx1Z2lucyddOwoJCQlpZiAoIHRydWUgPT09ICRza2lwcGVkX3BsdWdpbnMgKSB7CgkJCQlyZXR1cm4gW107CgkJCX0KCQkJaWYgKCAhIGlzX2FycmF5KCAkcGx1Z2lucyApICkgewoJCQkJcmV0dXJuICRwbHVnaW5zOwoJCQl9CgkJCWZvcmVhY2ggKCAkcGx1Z2lucyBhcyAkYSA9PiAkYiApIHsKCQkJCS8vIGFjdGl2ZV9zaXRld2lkZV9wbHVnaW5zIHN0b3JlcyBwbHVnaW4gbmFtZSBhcyB0aGUga2V5LgoJCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCBjdXJyZW50X2ZpbHRlcigpLCAnYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnICkgJiYgVXRpbHNcaXNfcGx1Z2luX3NraXBwZWQoICRhICkgKSB7CgkJCQkJdW5zZXQoICRwbHVnaW5zWyAkYSBdICk7CgkJCQkJLy8gYWN0aXZlX3BsdWdpbnMgc3RvcmVzIHBsdWdpbiBuYW1lIGFzIHRoZSB2YWx1ZS4KCQkJCX0gZWxzZWlmICggZmFsc2UgIT09IHN0cnBvcyggY3VycmVudF9maWx0ZXIoKSwgJ2FjdGl2ZV9wbHVnaW5zJyApICYmIFV0aWxzXGlzX3BsdWdpbl9za2lwcGVkKCAkYiApICkgewoJCQkJCXVuc2V0KCAkcGx1Z2luc1sgJGEgXSApOwoJCQkJfQoJCQl9CgkJCS8vIFJlaW5kZXggYmVjYXVzZSBhY3RpdmVfcGx1Z2lucyBleHBlY3RzIGEgbnVtZXJpYyBpbmRleC4KCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCBjdXJyZW50X2ZpbHRlcigpLCAnYWN0aXZlX3BsdWdpbnMnICkgKSB7CgkJCQkkcGx1Z2lucyA9IGFycmF5X3ZhbHVlcyggJHBsdWdpbnMgKTsKCQkJfQoJCQlyZXR1cm4gJHBsdWdpbnM7CgkJfTsKCgkJJGhvb2tzID0gWwoJCQkncHJlX3NpdGVfb3B0aW9uX2FjdGl2ZV9zaXRld2lkZV9wbHVnaW5zJywKCQkJJ3NpdGVfb3B0aW9uX2FjdGl2ZV9zaXRld2lkZV9wbHVnaW5zJywKCQkJJ3ByZV9vcHRpb25fYWN0aXZlX3BsdWdpbnMnLAoJCQknb3B0aW9uX2FjdGl2ZV9wbHVnaW5zJywKCQldOwoJCWZvcmVhY2ggKCAkaG9va3MgYXMgJGhvb2sgKSB7CgkJCVdQX0NMSTo6YWRkX3dwX2hvb2soICRob29rLCAkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfcGx1Z2lucywgOTk5ICk7CgkJfQoJCVdQX0NMSTo6YWRkX3dwX2hvb2soCgkJCSdwbHVnaW5zX2xvYWRlZCcsCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB1c2UgKCAkaG9va3MsICR3cF9jbGlfZmlsdGVyX2FjdGl2ZV9wbHVnaW5zICkgewoJCQkJZm9yZWFjaCAoICRob29rcyBhcyAkaG9vayApIHsKCQkJCQlyZW1vdmVfZmlsdGVyKCAkaG9vaywgJHdwX2NsaV9maWx0ZXJfYWN0aXZlX3BsdWdpbnMsIDk5OSApOwoJCQkJfQoJCQl9LAoJCQkwCgkJKTsKCX0KCgkvKioKCSAqIFNldCB1cCB0aGUgZmlsdGVycyB0byBza2lwIHRoZSBsb2FkZWQgdGhlbWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFjdGlvbl9zZXR1cF90aGVtZV93cF9jbGlfc2tpcF90aGVtZXMoKSB7CgkJJHdwX2NsaV9maWx0ZXJfYWN0aXZlX3RoZW1lID0gc3RhdGljIGZ1bmN0aW9uICggJHZhbHVlICkgewoJCQkkc2tpcHBlZF90aGVtZXMgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Y29uZmlnWydza2lwLXRoZW1lcyddOwoJCQlpZiAoIHRydWUgPT09ICRza2lwcGVkX3RoZW1lcyApIHsKCQkJCXJldHVybiAnJzsKCQkJfQoJCQlpZiAoICEgaXNfYXJyYXkoICRza2lwcGVkX3RoZW1lcyApICkgewoJCQkJJHNraXBwZWRfdGhlbWVzID0gZXhwbG9kZSggJywnLCAkc2tpcHBlZF90aGVtZXMgKTsKCQkJfQoKCQkJJGNoZWNrZWRfdmFsdWUgPSAkdmFsdWU7CgkJCS8vIEFsd2F5cyBjaGVjayBhZ2FpbnN0IHRoZSBzdHlsZXNoZWV0IHZhbHVlCgkJCS8vIFRoaXMgZW5zdXJlcyBhIGNoaWxkIHRoZW1lIGNhbiBiZSBza2lwcGVkIHdoZW4gdGVtcGxhdGUgZGlmZmVycwoJCQlpZiAoIGZhbHNlICE9PSBzdHJpcG9zKCBjdXJyZW50X2ZpbHRlcigpLCAnb3B0aW9uX3RlbXBsYXRlJyApICkgewoJCQkJJGNoZWNrZWRfdmFsdWUgPSBnZXRfb3B0aW9uKCAnc3R5bGVzaGVldCcgKTsKCQkJfQoKCQkJaWYgKCAnJyA9PT0gJGNoZWNrZWRfdmFsdWUgfHwgaW5fYXJyYXkoICRjaGVja2VkX3ZhbHVlLCAkc2tpcHBlZF90aGVtZXMsIHRydWUgKSApIHsKCQkJCXJldHVybiAnJzsKCQkJfQoJCQlyZXR1cm4gJHZhbHVlOwoJCX07CgkJJGhvb2tzICAgICAgICAgICAgICAgICAgICAgID0gWwoJCQkncHJlX29wdGlvbl90ZW1wbGF0ZScsCgkJCSdvcHRpb25fdGVtcGxhdGUnLAoJCQkncHJlX29wdGlvbl9zdHlsZXNoZWV0JywKCQkJJ29wdGlvbl9zdHlsZXNoZWV0JywKCQldOwoJCWZvcmVhY2ggKCAkaG9va3MgYXMgJGhvb2sgKSB7CgkJCWFkZF9maWx0ZXIoICRob29rLCAkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfdGhlbWUsIDk5OSApOwoJCX0KCQkvLyBDbGVhbiB1cCBhZnRlciB0aGUgVEVNUExBVEVQQVRIIGFuZCBTVFlMRVNIRUVUUEFUSCBjb25zdGFudHMgYXJlIGRlZmluZWQKCQlXUF9DTEk6OmFkZF93cF9ob29rKAoJCQknYWZ0ZXJfc2V0dXBfdGhlbWUnLAoJCQlzdGF0aWMgZnVuY3Rpb24gKCkgdXNlICggJGhvb2tzLCAkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfdGhlbWUgKSB7CgkJCQlmb3JlYWNoICggJGhvb2tzIGFzICRob29rICkgewoJCQkJCXJlbW92ZV9maWx0ZXIoICRob29rLCAkd3BfY2xpX2ZpbHRlcl9hY3RpdmVfdGhlbWUsIDk5OSApOwoJCQkJfQoJCQl9LAoJCQkwCgkJKTsKCX0KCgkvKioKCSAqIFdoZXRoZXIgb3Igbm90IHRoaXMgV29yZFByZXNzIGluc3RhbGxhdGlvbiBpcyBtdWx0aXNpdGUuCgkgKgoJICogRm9yIHVzZSBhZnRlciB3cC1jb25maWcucGhwIGhhcyBsb2FkZWQsIGJ1dCBiZWZvcmUgdGhlIHJlc3Qgb2YgV29yZFByZXNzCgkgKiBpcyBsb2FkZWQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaXNfbXVsdGlzaXRlKCkgewoJCWlmICggZGVmaW5lZCggJ01VTFRJU0lURScgKSApIHsKCQkJcmV0dXJuIE1VTFRJU0lURTsKCQl9CgoJCWlmICggZGVmaW5lZCggJ1NVQkRPTUFJTl9JTlNUQUxMJyApIHx8IGRlZmluZWQoICdWSE9TVCcgKSB8fCBkZWZpbmVkKCAnU1VOUklTRScgKSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBFcnJvciBoYW5kbGVyIGZvciBgd3BfZGllKClgIHdoZW4gdGhlIGNvbW1hbmQgaXMgaGVscCB0byB0cnkgdG8gdHJhcCBlcnJvcnMgKGRiIGNvbm5lY3Rpb24gZmFpbHVyZSBpbiBwYXJ0aWN1bGFyKSBkdXJpbmcgV29yZFByZXNzIGxvYWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBoZWxwX3dwX2RpZV9oYW5kbGVyKCAkbWVzc2FnZSApIHsKCQkkaGVscF9leGl0X3dhcm5pbmcgPSAnRXJyb3IgZHVyaW5nIFdvcmRQcmVzcyBsb2FkLic7CgkJaWYgKCAkbWVzc2FnZSBpbnN0YW5jZW9mIFdQX0Vycm9yICkgewoJCQkkaGVscF9leGl0X3dhcm5pbmcgPSBVdGlsc1x3cF9jbGVhbl9lcnJvcl9tZXNzYWdlKCAkbWVzc2FnZS0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkbWVzc2FnZSApICkgewoJCQkkaGVscF9leGl0X3dhcm5pbmcgPSBVdGlsc1x3cF9jbGVhbl9lcnJvcl9tZXNzYWdlKCAkbWVzc2FnZSApOwoJCX0KCQkkdGhpcy0+cnVuX2NvbW1hbmRfYW5kX2V4aXQoICRoZWxwX2V4aXRfd2FybmluZyApOwoJfQoKCS8qKgoJICogQ2hlY2sgd2hldGhlciB0aGVyZSdzIGEgV1AtQ0xJIHVwZGF0ZSBhdmFpbGFibGUsIGFuZCBzdWdnZXN0IHVwZGF0ZSBpZiBzby4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhdXRvX2NoZWNrX3VwZGF0ZSgpIHsKCgkJLy8gYHdwIGNsaSB1cGRhdGVgIG9ubHkgd29ya3Mgd2l0aCBQaGFycyBhdCB0aGlzIHRpbWUuCgkJaWYgKCAhIFV0aWxzXGluc2lkZV9waGFyKCkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRleGlzdGluZ19waGFyID0gcmVhbHBhdGgoICRfU0VSVkVSWydhcmd2J11bMF0gKTsKCQkvLyBQaGFyIG5lZWRzIHRvIGJlIHdyaXRhYmxlIHRvIGJlIGVhc2lseSB1cGRhdGVhYmxlLgoJCWlmICggISBpc193cml0YWJsZSggJGV4aXN0aW5nX3BoYXIgKSB8fCAhIGlzX3dyaXRhYmxlKCBkaXJuYW1lKCAkZXhpc3RpbmdfcGhhciApICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIE9ubHkgY2hlY2sgZm9yIHVwZGF0ZSB3aGVuIGEgaHVtYW4gaXMgb3BlcmF0aW5nLgoJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICdwb3NpeF9pc2F0dHknICkgfHwgISBwb3NpeF9pc2F0dHkoIFNURE9VVCApICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBBbGxvdyBob3N0cyBhbmQgb3RoZXIgcHJvdmlkZXJzIHRvIGRpc2FibGUgYXV0b21hdGljIGNoZWNrIHVwZGF0ZS4KCQlpZiAoIGdldGVudiggJ1dQX0NMSV9ESVNBQkxFX0FVVE9fQ0hFQ0tfVVBEQVRFJyApICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBQZXJtaXQgY29uZmlndXJhdGlvbiBvZiBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuIGNoZWNrcy4KCQkkZGF5c19iZXR3ZWVuX2NoZWNrcyA9IGdldGVudiggJ1dQX0NMSV9BVVRPX0NIRUNLX1VQREFURV9EQVlTJyApOwoJCWlmICggZmFsc2UgPT09ICRkYXlzX2JldHdlZW5fY2hlY2tzICkgewoJCQkkZGF5c19iZXR3ZWVuX2NoZWNrcyA9IDE7CgkJfQoKCQkkY2FjaGUgICAgID0gV1BfQ0xJOjpnZXRfY2FjaGUoKTsKCQkkY2FjaGVfa2V5ID0gJ3dwLWNsaS11cGRhdGUtY2hlY2snOwoJCS8vIEJhaWwgZWFybHkgb24gdGhlIGZpcnN0IGNoZWNrLCBzbyB3ZSBkb24ndCBhbHdheXMgY2hlY2sgb24gYW4gdW53cml0YWJsZSBjYWNoZS4KCQlpZiAoICEgJGNhY2hlLT5oYXMoICRjYWNoZV9rZXkgKSApIHsKCQkJJGNhY2hlLT53cml0ZSggJGNhY2hlX2tleSwgdGltZSgpICk7CgkJCXJldHVybjsKCQl9CgoJCS8vIEJhaWwgaWYgbGFzdCBjaGVjayBpcyBzdGlsbCB3aXRoaW4gb3VyIHVwZGF0ZSBjaGVjayB0aW1lIHBlcmlvZC4KCQkkbGFzdF9jaGVjayA9IChpbnQpICRjYWNoZS0+cmVhZCggJGNhY2hlX2tleSApOwoJCWlmICggKCB0aW1lKCkgLSAoIDI0ICogNjAgKiA2MCAqICRkYXlzX2JldHdlZW5fY2hlY2tzICkgKSA8ICRsYXN0X2NoZWNrICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBJbiBjYXNlIHRoZSBvcGVyYXRpb24gZmFpbHMsIGVuc3VyZSB0aGUgdGltZXN0YW1wIGhhcyBiZWVuIHVwZGF0ZWQuCgkJJGNhY2hlLT53cml0ZSggJGNhY2hlX2tleSwgdGltZSgpICk7CgoJCS8vIENoZWNrIHdoZXRoZXIgYW55IHVwZGF0ZXMgYXJlIGF2YWlsYWJsZS4KCQlvYl9zdGFydCgpOwoJCVdQX0NMSTo6cnVuX2NvbW1hbmQoCgkJCVsgJ2NsaScsICdjaGVjay11cGRhdGUnIF0sCgkJCVsKCQkJCSdmb3JtYXQnID0+ICdjb3VudCcsCgkJCV0KCQkpOwoJCSRjb3VudCA9IG9iX2dldF9jbGVhbigpOwoJCWlmICggISAkY291bnQgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIExvb2tzIGxpa2UgYW4gdXBkYXRlIGlzIGF2YWlsYWJsZSwgc28gbGV0J3MgcHJvbXB0IHRvIHVwZGF0ZS4KCQlXUF9DTEk6OnJ1bl9jb21tYW5kKCBbICdjbGknLCAndXBkYXRlJyBdICk7CgkJLy8gSWYgdGhlIFBoYXIgd2FzIHJlcGxhY2VkLCB3ZSBjYW4ndCBwcm9jZWVkIHdpdGggdGhlIG9yaWdpbmFsIHByb2Nlc3MuCgkJZXhpdDsKCX0KCgkvKioKCSAqIEdldCBhIHN1Z2dlc3Rpb24gb24gc2ltaWxhciAoc3ViKWNvbW1hbmRzIHdoZW4gdGhlIHVzZXIgZW50ZXJlZCBhbgoJICogdW5rbm93biAoc3ViKWNvbW1hbmQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGVudHJ5ICAgICAgICBVc2VyIGVudHJ5IHRoYXQgZGlkbid0IG1hdGNoIGFuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nIGNvbW1hbmQuCgkgKiBAcGFyYW0gQ29tcG9zaXRlQ29tbWFuZCAkcm9vdF9jb21tYW5kIFJvb3QgY29tbWFuZCB0byBzdGFydCBzZWFyY2ggZm9yCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Z2dlc3Rpb25zIGF0LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFN1Z2dlc3Rpb24gdGhhdCBmaXRzIHRoZSB1c2VyIGVudHJ5LCBvciBhbiBlbXB0eSBzdHJpbmcuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3N1YmNvbW1hbmRfc3VnZ2VzdGlvbiggJGVudHJ5LCBDb21wb3NpdGVDb21tYW5kICRyb290X2NvbW1hbmQgPSBudWxsICkgewoJCSRjb21tYW5kcyA9IFtdOwoJCSR0aGlzLT5lbnVtZXJhdGVfY29tbWFuZHMoICRyb290X2NvbW1hbmQgPzogV1BfQ0xJOjpnZXRfcm9vdF9jb21tYW5kKCksICRjb21tYW5kcyApOwoKCQlyZXR1cm4gVXRpbHNcZ2V0X3N1Z2dlc3Rpb24oICRlbnRyeSwgJGNvbW1hbmRzLCAkdGhyZXNob2xkID0gMiApOwoJfQoKCS8qKgoJICogUmVjdXJzaXZlIG1ldGhvZCB0byBlbnVtZXJhdGUgYWxsIGtub3duIGNvbW1hbmRzLgoJICoKCSAqIEBwYXJhbSBDb21wb3NpdGVDb21tYW5kICRjb21tYW5kIENvbXBvc2l0ZSBjb21tYW5kIHRvIHJlY3Vyc2Ugb3Zlci4KCSAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICRsaXN0ICAgIFJlZmVyZW5jZSB0byBsaXN0IGFjY3VtdWxhdGluZyByZXN1bHRzLgoJICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJHBhcmVudCAgUGFyZW50IGNvbW1hbmQgdG8gdXNlIGFzIHByZWZpeC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBlbnVtZXJhdGVfY29tbWFuZHMoIENvbXBvc2l0ZUNvbW1hbmQgJGNvbW1hbmQsIGFycmF5ICYkbGlzdCwgJHBhcmVudCA9ICcnICkgewoJCWZvcmVhY2ggKCAkY29tbWFuZC0+Z2V0X3N1YmNvbW1hbmRzKCkgYXMgJHN1YmNvbW1hbmQgKSB7CgkJCS8qKiBAdmFyIENvbXBvc2l0ZUNvbW1hbmQgJHN1YmNvbW1hbmQgKi8KCQkJJGNvbW1hbmRfc3RyaW5nID0gZW1wdHkoICRwYXJlbnQgKQoJCQkJPyAkc3ViY29tbWFuZC0+Z2V0X25hbWUoKQoJCQkJOiAieyRwYXJlbnR9IHskc3ViY29tbWFuZC0+Z2V0X25hbWUoKX0iOwoKCQkJJGxpc3RbXSA9ICRjb21tYW5kX3N0cmluZzsKCgkJCSR0aGlzLT5lbnVtZXJhdGVfY29tbWFuZHMoICRzdWJjb21tYW5kLCAkbGlzdCwgJGNvbW1hbmRfc3RyaW5nICk7CgkJfQoJfQoKCS8qKgoJICogRW5hYmxlcyAoYWxtb3N0KSBmdWxsIFBIUCBlcnJvciByZXBvcnRpbmcgdG8gc3RkZXJyLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGVuYWJsZV9lcnJvcl9yZXBvcnRpbmcoKSB7CgkJaWYgKCBFX0FMTCAhPT0gZXJyb3JfcmVwb3J0aW5nKCkgKSB7CgkJCS8vIERvbid0IGVuYWJsZSBFX0RFUFJFQ0FURUQgYXMgb2xkIHZlcnNpb25zIG9mIFdQIHVzZSBQSFAgNCBzdHlsZSBjb25zdHJ1Y3RvcnMgYW5kIHRoZSBteXNxbCBleHRlbnNpb24uCgkJCWVycm9yX3JlcG9ydGluZyggRV9BTEwgJiB+RV9ERVBSRUNBVEVEICk7CgkJfQoJCWluaV9zZXQoICdkaXNwbGF5X2Vycm9ycycsICdzdGRlcnInICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLkluaVNldC5kaXNwbGF5X2Vycm9yc19CbGFja2xpc3RlZAoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKdXNlIFdQX1VwZ3JhZGVyX1NraW47CgovKioKICogQSBVcGdyYWRlciBTa2luIGZvciBXb3JkUHJlc3MgdGhhdCBvbmx5IGdlbmVyYXRlcyBwbGFpbi10ZXh0CiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgVXBncmFkZXJTa2luIGV4dGVuZHMgV1BfVXBncmFkZXJfU2tpbiB7CgoJdXNlIFdQX0NMSVxDb21wYXRcRmVlZGJhY2tNZXRob2RUcmFpdDsKCglwdWJsaWMgJGFwaTsKCglwdWJsaWMgZnVuY3Rpb24gaGVhZGVyKCkge30KCXB1YmxpYyBmdW5jdGlvbiBmb290ZXIoKSB7fQoJcHVibGljIGZ1bmN0aW9uIGJ1bGtfaGVhZGVyKCkge30KCXB1YmxpYyBmdW5jdGlvbiBidWxrX2Zvb3RlcigpIHt9CgoJcHVibGljIGZ1bmN0aW9uIGVycm9yKCAkZXJyb3IgKSB7CgkJaWYgKCAhICRlcnJvciApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCBpc19zdHJpbmcoICRlcnJvciApICYmIGlzc2V0KCAkdGhpcy0+dXBncmFkZXItPnN0cmluZ3NbICRlcnJvciBdICkgKSB7CgkJCSRlcnJvciA9ICR0aGlzLT51cGdyYWRlci0+c3RyaW5nc1sgJGVycm9yIF07CgkJfQoKCQkvLyBUT0RPOiBzaG93IGFsbCBlcnJvcnMsIG5vdCBqdXN0IHRoZSBmaXJzdCBvbmUKCQlXUF9DTEk6Ondhcm5pbmcoICRlcnJvciApOwoJfQoKCS8qKgoJICogUHJvY2VzcyB0aGUgZmVlZGJhY2sgY29sbGVjdGVkIHRocm91Z2ggdGhlIGNvbXBhdCBpbmRpcmVjdGlvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgU3RyaW5nIHRvIHVzZSBhcyBmZWVkYmFjayBtZXNzYWdlLgoJICogQHBhcmFtIGFycmF5ICRhcmdzIEFycmF5IG9mIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHByb2Nlc3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzX2ZlZWRiYWNrKCAkc3RyaW5nLCAkYXJncyApIHsKCgkJaWYgKCAncGFyZW50X3RoZW1lX3ByZXBhcmVfaW5zdGFsbCcgPT09ICRzdHJpbmcgKSB7CgkJCVdQX0NMSTo6Z2V0X2h0dHBfY2FjaGVfbWFuYWdlcigpLT53aGl0ZWxpc3RfcGFja2FnZSggJHRoaXMtPmFwaS0+ZG93bmxvYWRfbGluaywgJ3RoZW1lJywgJHRoaXMtPmFwaS0+c2x1ZywgJHRoaXMtPmFwaS0+dmVyc2lvbiApOwoJCX0KCgkJaWYgKCBpc3NldCggJHRoaXMtPnVwZ3JhZGVyLT5zdHJpbmdzWyAkc3RyaW5nIF0gKSApIHsKCQkJJHN0cmluZyA9ICR0aGlzLT51cGdyYWRlci0+c3RyaW5nc1sgJHN0cmluZyBdOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICYmIHN0cnBvcyggJHN0cmluZywgJyUnICkgIT09IGZhbHNlICkgewoJCQkkc3RyaW5nID0gdnNwcmludGYoICRzdHJpbmcsICRhcmdzICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkc3RyaW5nICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSggJyYjODIzMDsnLCAnLi4uJywgVXRpbHNcc3RyaXBfdGFncyggJHN0cmluZyApICk7CgkJJHN0cmluZyA9IGh0bWxfZW50aXR5X2RlY29kZSggJHN0cmluZywgRU5UX1FVT1RFUywgZ2V0X2Jsb2dpbmZvKCAnY2hhcnNldCcgKSApOwoKCQlXUF9DTEk6OmxvZyggJHN0cmluZyApOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBDaGVja3MgaWYgdGhlIGxpc3Qgb2YgcGFyYW1ldGVycyBtYXRjaGVzIHRoZSBzcGVjaWZpY2F0aW9uIGRlZmluZWQgaW4gdGhlIHN5bm9wc2lzLgogKi8KY2xhc3MgU3lub3BzaXNWYWxpZGF0b3IgewoKCS8qKgoJICogU3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBjb21tYW5kIHN5bm9wc2lzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkc3BlYzsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgJHN5bm9wc2lzIENvbW1hbmQncyBzeW5vcHNpcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkc3lub3BzaXMgKSB7CgkJJHRoaXMtPnNwZWMgPSBTeW5vcHNpc1BhcnNlcjo6cGFyc2UoICRzeW5vcHNpcyApOwoJfQoKCS8qKgoJICogR2V0IGFueSB1bmtub3duIGFyZ3VtZW50cy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfdW5rbm93bigpIHsKCQlyZXR1cm4gYXJyYXlfY29sdW1uKAoJCQkkdGhpcy0+cXVlcnlfc3BlYygKCQkJCVsKCQkJCQkndHlwZScgPT4gJ3Vua25vd24nLAoJCQkJXQoJCQkpLAoJCQkndG9rZW4nCgkJKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgdGhlcmUgYXJlIGVub3VnaCBwb3NpdGlvbmFsIGFyZ3VtZW50cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgUG9zaXRpb25hbCBhcmd1bWVudHMuCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVub3VnaF9wb3NpdGlvbmFscyggJGFyZ3MgKSB7CgkJJHBvc2l0aW9uYWwgPSAkdGhpcy0+cXVlcnlfc3BlYygKCQkJWwoJCQkJJ3R5cGUnICAgICA9PiAncG9zaXRpb25hbCcsCgkJCQknb3B0aW9uYWwnID0+IGZhbHNlLAoJCQldCgkJKTsKCgkJcmV0dXJuIGNvdW50KCAkYXJncyApID49IGNvdW50KCAkcG9zaXRpb25hbCApOwoJfQoKCS8qKgoJICogQ2hlY2sgZm9yIGFueSB1bmtub3duIHBvc2l0aW9uYWxzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBQb3NpdGlvbmFsIGFyZ3VtZW50cy4KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVua25vd25fcG9zaXRpb25hbHMoICRhcmdzICkgewoJCSRwb3NpdGlvbmFsX3JlcGVhdGluZyA9ICR0aGlzLT5xdWVyeV9zcGVjKAoJCQlbCgkJCQkndHlwZScgICAgICA9PiAncG9zaXRpb25hbCcsCgkJCQkncmVwZWF0aW5nJyA9PiB0cnVlLAoJCQldCgkJKTsKCgkJLy8gQXQgbGVhc3Qgb25lIHBvc2l0aW9uYWwgc3VwcG9ydHMgYXMgbWFueSBhcyBwb3NzaWJsZS4KCQlpZiAoICEgZW1wdHkoICRwb3NpdGlvbmFsX3JlcGVhdGluZyApICkgewoJCQlyZXR1cm4gW107CgkJfQoKCQkkcG9zaXRpb25hbCA9ICR0aGlzLT5xdWVyeV9zcGVjKAoJCQlbCgkJCQkndHlwZScgICAgICA9PiAncG9zaXRpb25hbCcsCgkJCQkncmVwZWF0aW5nJyA9PiBmYWxzZSwKCQkJXQoJCSk7CgoJCXJldHVybiBhcnJheV9zbGljZSggJGFyZ3MsIGNvdW50KCAkcG9zaXRpb25hbCApICk7Cgl9CgoJLyoqCgkgKiBDaGVjayB0aGF0IGFsbCByZXF1aXJlZCBrZXlzIGFyZSBwcmVzZW50IGFuZCB0aGF0IHRoZXkgaGF2ZSB2YWx1ZXMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFBhcmFtZXRlcnMgcGFzc2VkIHRvIGNvbW1hbmQuCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZV9hc3NvYyggJGFzc29jX2FyZ3MgKSB7CgkJJGFzc29jX3NwZWMgPSAkdGhpcy0+cXVlcnlfc3BlYygKCQkJWwoJCQkJJ3R5cGUnID0+ICdhc3NvYycsCgkJCV0KCQkpOwoKCQkkZXJyb3JzID0gWwoJCQknZmF0YWwnICAgPT4gW10sCgkJCSd3YXJuaW5nJyA9PiBbXSwKCQldOwoKCQkkdG9fdW5zZXQgPSBbXTsKCgkJZm9yZWFjaCAoICRhc3NvY19zcGVjIGFzICRwYXJhbSApIHsKCQkJJGtleSA9ICRwYXJhbVsnbmFtZSddOwoKCQkJaWYgKCAhIGlzc2V0KCAkYXNzb2NfYXJnc1sgJGtleSBdICkgKSB7CgkJCQlpZiAoICEgJHBhcmFtWydvcHRpb25hbCddICkgewoJCQkJCSRlcnJvcnNbJ2ZhdGFsJ11bICRrZXkgXSA9ICJtaXNzaW5nIC0tJGtleSBwYXJhbWV0ZXIiOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJaWYgKCB0cnVlID09PSAkYXNzb2NfYXJnc1sgJGtleSBdICYmICEgJHBhcmFtWyd2YWx1ZSddWydvcHRpb25hbCddICkgewoJCQkJCSRlcnJvcl90eXBlICAgICAgICAgICAgICAgICAgICA9ICggISAkcGFyYW1bJ29wdGlvbmFsJ10gKSA/ICdmYXRhbCcgOiAnd2FybmluZyc7CgkJCQkJJGVycm9yc1sgJGVycm9yX3R5cGUgXVsgJGtleSBdID0gIi0tJGtleSBwYXJhbWV0ZXIgbmVlZHMgYSB2YWx1ZSI7CgoJCQkJCSR0b191bnNldFtdID0gJGtleTsKCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIFsgJGVycm9ycywgJHRvX3Vuc2V0IF07Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIHRoZXJlIGFyZSB1bmtub3duIHBhcmFtZXRlcnMgc3VwcGxpZWQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFBhcmFtZXRlcnMgcGFzc2VkIHRvIGNvbW1hbmQuCgkgKiBAcmV0dXJuIGFycmF5fGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmtub3duX2Fzc29jKCAkYXNzb2NfYXJncyApIHsKCQkkZ2VuZXJpYyA9ICR0aGlzLT5xdWVyeV9zcGVjKAoJCQlbCgkJCQkndHlwZScgPT4gJ2dlbmVyaWMnLAoJCQldCgkJKTsKCgkJaWYgKCBjb3VudCggJGdlbmVyaWMgKSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJGtub3duX2Fzc29jID0gW107CgoJCWZvcmVhY2ggKCAkdGhpcy0+c3BlYyBhcyAkcGFyYW0gKSB7CgkJCWlmICggaW5fYXJyYXkoICRwYXJhbVsndHlwZSddLCBbICdhc3NvYycsICdmbGFnJyBdLCB0cnVlICkgKSB7CgkJCQkka25vd25fYXNzb2NbXSA9ICRwYXJhbVsnbmFtZSddOwoJCQl9CgkJfQoKCQlyZXR1cm4gYXJyYXlfZGlmZiggYXJyYXlfa2V5cyggJGFzc29jX2FyZ3MgKSwgJGtub3duX2Fzc29jICk7Cgl9CgoJLyoqCgkgKiBGaWx0ZXJzIGEgbGlzdCBvZiBhc3NvY2lhdGl2ZSBhcnJheXMsIGJhc2VkIG9uIGEgc2V0IG9mIGtleSA9PiB2YWx1ZSBhcmd1bWVudHMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIEFuIGFycmF5IG9mIGtleSA9PiB2YWx1ZSBhcmd1bWVudHMgdG8gbWF0Y2ggYWdhaW5zdAoJICogQHBhcmFtIHN0cmluZyAkb3BlcmF0b3IKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBxdWVyeV9zcGVjKCAkYXJncywgJG9wZXJhdG9yID0gJ0FORCcgKSB7CgkJJG9wZXJhdG9yID0gc3RydG91cHBlciggJG9wZXJhdG9yICk7CgkJJGNvdW50ICAgID0gY291bnQoICRhcmdzICk7CgkJJGZpbHRlcmVkID0gW107CgoJCWZvcmVhY2ggKCAkdGhpcy0+c3BlYyBhcyAka2V5ID0+ICR0b19tYXRjaCApIHsKCQkJJG1hdGNoZWQgPSAwOwoJCQlmb3JlYWNoICggJGFyZ3MgYXMgJG1fa2V5ID0+ICRtX3ZhbHVlICkgewoJCQkJaWYgKCBhcnJheV9rZXlfZXhpc3RzKCAkbV9rZXksICR0b19tYXRjaCApICYmICRtX3ZhbHVlID09PSAkdG9fbWF0Y2hbICRtX2tleSBdICkgewoJCQkJCSRtYXRjaGVkKys7CgkJCQl9CgkJCX0KCgkJCWlmICggKCAnQU5EJyA9PT0gJG9wZXJhdG9yICYmICRtYXRjaGVkID09PSAkY291bnQgKQoJCQkJfHwgKCAnT1InID09PSAkb3BlcmF0b3IgJiYgJG1hdGNoZWQgPiAwICkKCQkJCXx8ICggJ05PVCcgPT09ICRvcGVyYXRvciAmJiAwID09PSAkbWF0Y2hlZCApICkgewoJCQkJCSRmaWx0ZXJlZFsgJGtleSBdID0gJHRvX21hdGNoOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGZpbHRlcmVkOwoJfQoKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIGhlYXZpbHkgaW5zcGlyZWQgYW5kIHVzZSBjb2RlIGZyb20gQ29tcG9zZXIoZ2V0Y29tcG9zZXIub3JnKSwKICogaW4gcGFydGljdWxhciBDb21wb3Nlci9DYWNoZSBhbmQgQ29tcG9zZXIvVXRpbC9GaWxlU3lzdGVtIGZyb20gMS4wLjAtYWxwaGE3CiAqCiAqIFRoZSBvcmlnaW5hbCBjb2RlIGFuZCB0aGlzIGZpbGUgYXJlIGJvdGggcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuCiAqCiAqIFRoZSBjb3B5cmlnaHQgaG9sZGVycyBvZiB0aGUgb3JpZ2luYWwgY29kZSBhcmU6CiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBEYXRlVGltZTsKdXNlIEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CnVzZSBXUF9DTEk7CgovKioKICogUmVhZHMvd3JpdGVzIHRvIGEgZmlsZXN5c3RlbSBjYWNoZQogKi8KY2xhc3MgRmlsZUNhY2hlIHsKCgkvKioKCSAqIEB2YXIgc3RyaW5nIGNhY2hlIHBhdGgKCSAqLwoJcHJvdGVjdGVkICRyb290OwoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRlbmFibGVkID0gdHJ1ZTsKCS8qKgoJICogQHZhciBpbnQgZmlsZXMgdGltZSB0byBsaXZlCgkgKi8KCXByb3RlY3RlZCAkdHRsOwoJLyoqCgkgKiBAdmFyIGludCBtYXggdG90YWwgc2l6ZQoJICovCglwcm90ZWN0ZWQgJG1heF9zaXplOwoJLyoqCgkgKiBAdmFyIHN0cmluZyBrZXkgYWxsb3dlZCBjaGFycyAocmVnZXggY2xhc3MpCgkgKi8KCXByb3RlY3RlZCAkd2hpdGVsaXN0OwoKCS8qKgoJICogQHBhcmFtIHN0cmluZyAkY2FjaGVfZGlyICBsb2NhdGlvbiBvZiB0aGUgY2FjaGUKCSAqIEBwYXJhbSBpbnQgICAgJHR0bCAgICAgICAgY2FjaGUgZmlsZXMgZGVmYXVsdCB0aW1lIHRvIGxpdmUgKGV4cGlyYXRpb24pCgkgKiBAcGFyYW0gaW50ICAgICRtYXhfc2l6ZSAgIG1heCB0b3RhbCBjYWNoZSBzaXplCgkgKiBAcGFyYW0gc3RyaW5nICR3aGl0ZWxpc3QgIExpc3Qgb2YgY2hhcmFjdGVycyB0aGF0IGFyZSBhbGxvd2VkIGluIHBhdGggbmFtZXMgKHVzZWQgaW4gYSByZWdleCBjaGFyYWN0ZXIgY2xhc3MpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGNhY2hlX2RpciwgJHR0bCwgJG1heF9zaXplLCAkd2hpdGVsaXN0ID0gJ2EtejAtOS5fLScgKSB7CgkJJHRoaXMtPnJvb3QgICAgICA9IFV0aWxzXHRyYWlsaW5nc2xhc2hpdCggJGNhY2hlX2RpciApOwoJCSR0aGlzLT50dGwgICAgICAgPSAoaW50KSAkdHRsOwoJCSR0aGlzLT5tYXhfc2l6ZSAgPSAoaW50KSAkbWF4X3NpemU7CgkJJHRoaXMtPndoaXRlbGlzdCA9ICR3aGl0ZWxpc3Q7CgoJCWlmICggISAkdGhpcy0+ZW5zdXJlX2Rpcl9leGlzdHMoICR0aGlzLT5yb290ICkgKSB7CgkJCSR0aGlzLT5lbmFibGVkID0gZmFsc2U7CgkJfQoKCX0KCgkvKioKCSAqIENhY2hlIGlzIGVuYWJsZWQKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2VuYWJsZWQoKSB7CgkJcmV0dXJuICR0aGlzLT5lbmFibGVkOwoJfQoKCS8qKgoJICogQ2FjaGUgcm9vdAoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfcm9vdCgpIHsKCQlyZXR1cm4gJHRoaXMtPnJvb3Q7Cgl9CgoKCS8qKgoJICogQ2hlY2sgaWYgYSBmaWxlIGlzIGluIGNhY2hlIGFuZCByZXR1cm4gaXRzIGZpbGVuYW1lCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IGNhY2hlIGtleQoJICogQHBhcmFtIGludCAgICAkdHRsIHRpbWUgdG8gbGl2ZQoJICogQHJldHVybiBib29sfHN0cmluZyBmaWxlbmFtZSBvciBmYWxzZQoJICovCglwdWJsaWMgZnVuY3Rpb24gaGFzKCAka2V5LCAkdHRsID0gbnVsbCApIHsKCQlpZiAoICEgJHRoaXMtPmVuYWJsZWQgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRmaWxlbmFtZSA9ICR0aGlzLT5maWxlbmFtZSggJGtleSApOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICRmaWxlbmFtZSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBVc2UgdHRsIHBhcmFtIG9yIGdsb2JhbCB0dGwuCgkJaWYgKCBudWxsID09PSAkdHRsICkgewoJCQkkdHRsID0gJHRoaXMtPnR0bDsKCQl9IGVsc2VpZiAoICR0aGlzLT50dGwgPiAwICkgewoJCQkkdHRsID0gbWluKCAoaW50KSAkdHRsLCAkdGhpcy0+dHRsICk7CgkJfSBlbHNlIHsKCQkJJHR0bCA9IChpbnQpICR0dGw7CgkJfQoKCQkvLwoJCWlmICggJHR0bCA+IDAgJiYgKCBmaWxlbXRpbWUoICRmaWxlbmFtZSApICsgJHR0bCApIDwgdGltZSgpICkgewoJCQlpZiAoICR0aGlzLT50dGwgPiAwICYmICR0dGwgPj0gJHRoaXMtPnR0bCApIHsKCQkJCXVubGluayggJGZpbGVuYW1lICk7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRmaWxlbmFtZTsKCX0KCgkvKioKCSAqIFdyaXRlIHRvIGNhY2hlIGZpbGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgICAgICBjYWNoZSBrZXkKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnRzIGZpbGUgY29udGVudHMKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gd3JpdGUoICRrZXksICRjb250ZW50cyApIHsKCQkkZmlsZW5hbWUgPSAkdGhpcy0+cHJlcGFyZV93cml0ZSggJGtleSApOwoKCQlpZiAoICRmaWxlbmFtZSApIHsKCQkJcmV0dXJuIGZpbGVfcHV0X2NvbnRlbnRzKCAkZmlsZW5hbWUsICRjb250ZW50cyApICYmIHRvdWNoKCAkZmlsZW5hbWUgKTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJlYWQgZnJvbSBjYWNoZSBmaWxlCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IGNhY2hlIGtleQoJICogQHBhcmFtIGludCAgICAkdHRsIHRpbWUgdG8gbGl2ZQoJICogQHJldHVybiBib29sfHN0cmluZyBmaWxlIGNvbnRlbnRzIG9yIGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWFkKCAka2V5LCAkdHRsID0gbnVsbCApIHsKCQkkZmlsZW5hbWUgPSAkdGhpcy0+aGFzKCAka2V5LCAkdHRsICk7CgoJCWlmICggJGZpbGVuYW1lICkgewoJCQlyZXR1cm4gZmlsZV9nZXRfY29udGVudHMoICRmaWxlbmFtZSApOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogQ29weSBhIGZpbGUgaW50byB0aGUgY2FjaGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgICAgY2FjaGUga2V5CgkgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2Ugc291cmNlIGZpbGVuYW1lCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGltcG9ydCggJGtleSwgJHNvdXJjZSApIHsKCQkkZmlsZW5hbWUgPSAkdGhpcy0+cHJlcGFyZV93cml0ZSggJGtleSApOwoKCQlpZiAoICRmaWxlbmFtZSApIHsKCQkJcmV0dXJuIGNvcHkoICRzb3VyY2UsICRmaWxlbmFtZSApICYmIHRvdWNoKCAkZmlsZW5hbWUgKTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIENvcHkgYSBmaWxlIG91dCBvZiB0aGUgY2FjaGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgICAgY2FjaGUga2V5CgkgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQgdGFyZ2V0IGZpbGVuYW1lCgkgKiBAcGFyYW0gaW50ICAgICR0dGwgICAgdGltZSB0byBsaXZlCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydCggJGtleSwgJHRhcmdldCwgJHR0bCA9IG51bGwgKSB7CgkJJGZpbGVuYW1lID0gJHRoaXMtPmhhcyggJGtleSwgJHR0bCApOwoKCQlpZiAoICRmaWxlbmFtZSAmJiAkdGhpcy0+ZW5zdXJlX2Rpcl9leGlzdHMoIGRpcm5hbWUoICR0YXJnZXQgKSApICkgewoJCQlyZXR1cm4gY29weSggJGZpbGVuYW1lLCAkdGFyZ2V0ICk7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgZmlsZSBmcm9tIGNhY2hlCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IGNhY2hlIGtleQoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmUoICRrZXkgKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkZmlsZW5hbWUgPSAkdGhpcy0+ZmlsZW5hbWUoICRrZXkgKTsKCgkJaWYgKCBmaWxlX2V4aXN0cyggJGZpbGVuYW1lICkgKSB7CgkJCXJldHVybiB1bmxpbmsoICRmaWxlbmFtZSApOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogQ2xlYW4gY2FjaGUgYmFzZWQgb24gdGltZSB0byBsaXZlIGFuZCBtYXggc2l6ZQoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gY2xlYW4oKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdHRsICAgICAgPSAkdGhpcy0+dHRsOwoJCSRtYXhfc2l6ZSA9ICR0aGlzLT5tYXhfc2l6ZTsKCgkJLy8gVW5saW5rIGV4cGlyZWQgZmlsZXMuCgkJaWYgKCAkdHRsID4gMCApIHsKCQkJdHJ5IHsKCQkJCSRleHBpcmUgPSBuZXcgRGF0ZVRpbWUoKTsKCQkJCSRleHBpcmUtPm1vZGlmeSggJy0nIC4gJHR0bCAuICcgc2Vjb25kcycgKTsKCgkJCQkkZmluZGVyID0gJHRoaXMtPmdldF9maW5kZXIoKS0+ZGF0ZSggJ3VudGlsICcgLiAkZXhwaXJlLT5mb3JtYXQoICdZLW0tZCBIOmk6cycgKSApOwoJCQkJZm9yZWFjaCAoICRmaW5kZXIgYXMgJGZpbGUgKSB7CgkJCQkJdW5saW5rKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSApOwoJCQkJfQoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCQl9CgkJfQoKCQkvLyBVbmxpbmsgb2xkZXIgZmlsZXMgaWYgbWF4IGNhY2hlIHNpemUgaXMgZXhjZWVkZWQuCgkJaWYgKCAkbWF4X3NpemUgPiAwICkgewoJCQkkZmlsZXMgPSBhcnJheV9yZXZlcnNlKCBpdGVyYXRvcl90b19hcnJheSggJHRoaXMtPmdldF9maW5kZXIoKS0+c29ydEJ5QWNjZXNzZWRUaW1lKCktPmdldEl0ZXJhdG9yKCkgKSApOwoJCQkkdG90YWwgPSAwOwoKCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJCWlmICggKCAkdG90YWwgKyAkZmlsZS0+Z2V0U2l6ZSgpICkgPD0gJG1heF9zaXplICkgewoJCQkJCSR0b3RhbCArPSAkZmlsZS0+Z2V0U2l6ZSgpOwoJCQkJfSBlbHNlIHsKCQkJCQl1bmxpbmsoICRmaWxlLT5nZXRSZWFsUGF0aCgpICk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUmVtb3ZlIGFsbCBjYWNoZWQgZmlsZXMuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbGVhcigpIHsKCQlpZiAoICEgJHRoaXMtPmVuYWJsZWQgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRmaW5kZXIgPSAkdGhpcy0+Z2V0X2ZpbmRlcigpOwoKCQlmb3JlYWNoICggJGZpbmRlciBhcyAkZmlsZSApIHsKCQkJdW5saW5rKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSApOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgYWxsIGNhY2hlZCBmaWxlcyBleGNlcHQgZm9yIHRoZSBuZXdlc3QgdmVyc2lvbiBvZiBvbmUuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwcnVuZSgpIHsKCQlpZiAoICEgJHRoaXMtPmVuYWJsZWQgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qKiBAdmFyIEZpbmRlciAkZmluZGVyICovCgkJJGZpbmRlciA9ICR0aGlzLT5nZXRfZmluZGVyKCktPnNvcnRCeU5hbWUoKTsKCgkJJGZpbGVzX3RvX2RlbGV0ZSA9IFtdOwoKCQlmb3JlYWNoICggJGZpbmRlciBhcyAkZmlsZSApIHsKCQkJJHBpZWNlcyAgICA9IGV4cGxvZGUoICctJywgJGZpbGUtPmdldEJhc2VuYW1lKCAkZmlsZS0+Z2V0RXh0ZW5zaW9uKCkgKSApOwoJCQkkdGltZXN0YW1wID0gZW5kKCAkcGllY2VzICk7CgoJCQkvLyBObyB3YXkgdG8gY29tcGFyZSB2ZXJzaW9ucywgZG8gbm90aGluZy4KCQkJaWYgKCAhIGlzX251bWVyaWMoICR0aW1lc3RhbXAgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkYmFzZW5hbWVfd2l0aG91dF90aW1lc3RhbXAgPSBzdHJfcmVwbGFjZSggJy0nIC4gJHRpbWVzdGFtcCwgJycsICRmaWxlLT5nZXRCYXNlbmFtZSgpICk7CgoJCQkvLyBUaGVyZSdzIGEgZmlsZSB3aXRoIGFuIG9sZGVyIHRpbWVzdGFtcCwgZGVsZXRlIGl0LgoJCQlpZiAoIGlzc2V0KCAkZmlsZXNfdG9fZGVsZXRlWyAkYmFzZW5hbWVfd2l0aG91dF90aW1lc3RhbXAgXSApICkgewoJCQkJdW5saW5rKCAkZmlsZXNfdG9fZGVsZXRlWyAkYmFzZW5hbWVfd2l0aG91dF90aW1lc3RhbXAgXSApOwoJCQl9CgoJCQkkZmlsZXNfdG9fZGVsZXRlWyAkYmFzZW5hbWVfd2l0aG91dF90aW1lc3RhbXAgXSA9ICRmaWxlLT5nZXRSZWFsUGF0aCgpOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0cwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRpciBkaXJlY3RvcnkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZW5zdXJlX2Rpcl9leGlzdHMoICRkaXIgKSB7CgkJaWYgKCAhIGlzX2RpciggJGRpciApICkgewoJCQkvLyBEaXNhYmxlIHRoZSBjYWNoZSBpZiBhIG51bGwgZGV2aWNlIGxpa2UgL2Rldi9udWxsIGlzIGJlaW5nIHVzZWQuCgkJCWlmICggcHJlZ19tYXRjaCggJ3soXnxbXFxcXC9dKShcJG51bGx8bnVsfE5VTHwvZGV2L251bGwpKFtcXFxcL118JCl9JywgJGRpciApICkgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQlpZiAoICEgQG1rZGlyKCAkZGlyLCAwNzc3LCB0cnVlICkgKSB7CgkJCQkkbWVzc2FnZSA9ICJGYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAneyRkaXJ9JyI7CgkJCQkkZXJyb3IgICA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQlpZiAoIGlzX2FycmF5KCAkZXJyb3IgKSAmJiBhcnJheV9rZXlfZXhpc3RzKCAnbWVzc2FnZScsICRlcnJvciApICkgewoJCQkJCSRtZXNzYWdlIC49ICI6IHskZXJyb3JbJ21lc3NhZ2UnXX0iOwoJCQkJfQoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRtZXNzYWdlfS4iICk7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUHJlcGFyZSBjYWNoZSB3cml0ZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBjYWNoZSBrZXkKCSAqIEByZXR1cm4gYm9vbHxzdHJpbmcgZmlsZW5hbWUgb3IgZmFsc2UKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHByZXBhcmVfd3JpdGUoICRrZXkgKSB7CgkJaWYgKCAhICR0aGlzLT5lbmFibGVkICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkZmlsZW5hbWUgPSAkdGhpcy0+ZmlsZW5hbWUoICRrZXkgKTsKCgkJaWYgKCAhICR0aGlzLT5lbnN1cmVfZGlyX2V4aXN0cyggZGlybmFtZSggJGZpbGVuYW1lICkgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuICRmaWxlbmFtZTsKCX0KCgkvKioKCSAqIFZhbGlkYXRlIGNhY2hlIGtleQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBjYWNoZSBrZXkKCSAqIEByZXR1cm4gc3RyaW5nIHJlbGF0aXZlIGZpbGVuYW1lCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZV9rZXkoICRrZXkgKSB7CgkJJHVybF9wYXJ0cyA9IFV0aWxzXHBhcnNlX3VybCggJGtleSwgLTEsIGZhbHNlICk7CgkJaWYgKCBhcnJheV9rZXlfZXhpc3RzKCAncGF0aCcsICR1cmxfcGFydHMgKSAmJiAhIGVtcHR5KCAkdXJsX3BhcnRzWydzY2hlbWUnXSApICkgeyAvLyBpcyB1cmwKCQkJJHBhcnRzICAgPSBbICdtaXNjJyBdOwoJCQkkcGFydHNbXSA9ICR1cmxfcGFydHNbJ3NjaGVtZSddIC4KCQkJCSggZW1wdHkoICR1cmxfcGFydHNbJ2hvc3QnXSApID8gJycgOiAnLScgLiAkdXJsX3BhcnRzWydob3N0J10gKSAuCgkJCQkoIGVtcHR5KCAkdXJsX3BhcnRzWydwb3J0J10gKSA/ICcnIDogJy0nIC4gJHVybF9wYXJ0c1sncG9ydCddICk7CgkJCSRwYXJ0c1tdID0gc3Vic3RyKCAkdXJsX3BhcnRzWydwYXRoJ10sIDEgKSAuCgkJCQkoIGVtcHR5KCAkdXJsX3BhcnRzWydxdWVyeSddICkgPyAnJyA6ICctJyAuICR1cmxfcGFydHNbJ3F1ZXJ5J10gKTsKCQl9IGVsc2UgewoJCQkka2V5ICAgPSBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCAka2V5ICk7CgkJCSRwYXJ0cyA9IGV4cGxvZGUoICcvJywgbHRyaW0oICRrZXkgKSApOwoJCX0KCgkJJHBhcnRzID0gcHJlZ19yZXBsYWNlKCAiI1teeyR0aGlzLT53aGl0ZWxpc3R9XSNpIiwgJy0nLCAkcGFydHMgKTsKCgkJcmV0dXJuIGltcGxvZGUoICcvJywgJHBhcnRzICk7Cgl9CgoJLyoqCgkgKiBGaWxlbmFtZSBmcm9tIGtleQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICogQHJldHVybiBzdHJpbmcgZmlsZW5hbWUKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbGVuYW1lKCAka2V5ICkgewoJCXJldHVybiAkdGhpcy0+cm9vdCAuICR0aGlzLT52YWxpZGF0ZV9rZXkoICRrZXkgKTsKCX0KCgkvKioKCSAqIEdldCBhIEZpbmRlciB0aGF0IGl0ZXJhdGVzIGluIGNhY2hlIHJvb3Qgb25seSB0aGUgZmlsZXMKCSAqCgkgKiBAcmV0dXJuIEZpbmRlcgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2ZpbmRlcigpIHsKCQlyZXR1cm4gRmluZGVyOjpjcmVhdGUoKS0+aW4oICR0aGlzLT5yb290ICktPmZpbGVzKCk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgRGlyZWN0b3J5SXRlcmF0b3I7CnVzZSBFeGNlcHRpb247CnVzZSBQaGFyRGF0YTsKdXNlIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOwp1c2UgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjsKdXNlIFdQX0NMSTsKdXNlIFppcEFyY2hpdmU7CgovKioKICogRXh0cmFjdCBhIHByb3ZpZGVkIGFyY2hpdmUgZmlsZS4KICovCmNsYXNzIEV4dHJhY3RvciB7CgoJLyoqCgkgKiBFeHRyYWN0IHRoZSBhcmNoaXZlIGZpbGUgdG8gYSBzcGVjaWZpYyBkZXN0aW5hdGlvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdCggJHRhcmJhbGxfb3JfemlwLCAkZGVzdCApIHsKCQlpZiAoIHByZWdfbWF0Y2goICcvXC56aXAkLycsICR0YXJiYWxsX29yX3ppcCApICkgewoJCQlyZXR1cm4gc2VsZjo6ZXh0cmFjdF96aXAoICR0YXJiYWxsX29yX3ppcCwgJGRlc3QgKTsKCQl9CgoJCWlmICggcHJlZ19tYXRjaCggJy9cLnRhclwuZ3okLycsICR0YXJiYWxsX29yX3ppcCApICkgewoJCQlyZXR1cm4gc2VsZjo6ZXh0cmFjdF90YXJiYWxsKCAkdGFyYmFsbF9vcl96aXAsICRkZXN0ICk7CgkJfQoKCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiRXh0cmFjdGlvbiBvbmx5IHN1cHBvcnRlZCBmb3IgJy56aXAnIGFuZCAnLnRhci5neicgZmlsZSB0eXBlcy4iICk7Cgl9CgoJLyoqCgkgKiBFeHRyYWN0IGEgWklQIGZpbGUgdG8gYSBzcGVjaWZpYyBkZXN0aW5hdGlvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR6aXBmaWxlCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3RfemlwKCAkemlwZmlsZSwgJGRlc3QgKSB7CgkJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1ppcEFyY2hpdmUnICkgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICdFeHRyYWN0aW5nIGEgemlwIGZpbGUgcmVxdWlyZXMgWmlwQXJjaGl2ZS4nICk7CgkJfQoKCQkvLyBFbnN1cmUgdGhlIGRlc3RpbmF0aW9uIGZvbGRlciBleGlzdHMgb3IgY2FuIGJlIGNyZWF0ZWQuCgkJaWYgKCAhIHNlbGY6OmVuc3VyZV9kaXJfZXhpc3RzKCAkZGVzdCApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiQ291bGQgbm90IGNyZWF0ZSBmb2xkZXIgJ3skZGVzdH0nLiIgKTsKCQl9CgoJCWlmICggISBmaWxlKCAkemlwZmlsZSApCgkJCXx8ICEgaXNfcmVhZGFibGUoICR6aXBmaWxlICkKCQkJfHwgZmlsZXNpemUoICR6aXBmaWxlICkgPD0gMCApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggIkludmFsaWQgemlwIGZpbGUgJ3skemlwZmlsZX0nLiIgKTsKCQl9CgoJCSR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOwoJCSRyZXMgPSAkemlwLT5vcGVuKCAkemlwZmlsZSApOwoKCQlpZiAoIHRydWUgPT09ICRyZXMgKSB7CgkJCSRuYW1lICAgID0gVXRpbHNcYmFzZW5hbWUoICR6aXBmaWxlICk7CgkJCSR0ZW1wZGlyID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkKCQkJCQkJLiB1bmlxaWQoICd3cC1jbGktZXh0cmFjdC16aXBmaWxlLScsIHRydWUgKQoJCQkJCQkuICIteyRuYW1lfSI7CgoJCQkkemlwLT5leHRyYWN0VG8oICR0ZW1wZGlyICk7CgkJCSR6aXAtPmNsb3NlKCk7CgoJCQlzZWxmOjpjb3B5X292ZXJ3cml0ZV9maWxlcygKCQkJCXNlbGY6OmdldF9maXJzdF9zdWJmb2xkZXIoICR0ZW1wZGlyICksCgkJCQkkZGVzdAoJCQkpOwoKCQkJc2VsZjo6cm1kaXIoICR0ZW1wZGlyICk7CgkJfSBlbHNlIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigKCQkJCXNwcmludGYoCgkJCQkJIlppcEFyY2hpdmUgZmFpbGVkIHRvIHVuemlwICclcyc6ICVzLiIsCgkJCQkJJHppcGZpbGUsCgkJCQkJc2VsZjo6emlwX2Vycm9yX21zZyggJHJlcyApCgkJCQkpCgkJCSk7CgkJfQoJfQoKCS8qKgoJICogRXh0cmFjdCBhIHRhcmJhbGwgdG8gYSBzcGVjaWZpYyBkZXN0aW5hdGlvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0YXJiYWxsCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3RfdGFyYmFsbCggJHRhcmJhbGwsICRkZXN0ICkgewoJCS8vIEVuc3VyZSB0aGUgZGVzdGluYXRpb24gZm9sZGVyIGV4aXN0cyBvciBjYW4gYmUgY3JlYXRlZC4KCQlpZiAoICEgc2VsZjo6ZW5zdXJlX2Rpcl9leGlzdHMoICRkZXN0ICkgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICJDb3VsZCBub3QgY3JlYXRlIGZvbGRlciAneyRkZXN0fScuIiApOwoJCX0KCgkJaWYgKCBjbGFzc19leGlzdHMoICdQaGFyRGF0YScgKSApIHsKCQkJdHJ5IHsKCQkJCSRwaGFyICAgID0gbmV3IFBoYXJEYXRhKCAkdGFyYmFsbCApOwoJCQkJJG5hbWUgICAgPSBVdGlsc1xiYXNlbmFtZSggJHRhcmJhbGwgKTsKCQkJCSR0ZW1wZGlyID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkKCQkJCQkJCS4gdW5pcWlkKCAnd3AtY2xpLWV4dHJhY3QtdGFyYmFsbC0nLCB0cnVlICkKCQkJCQkJCS4gIi17JG5hbWV9IjsKCgkJCQkkcGhhci0+ZXh0cmFjdFRvKCAkdGVtcGRpciApOwoKCQkJCXNlbGY6OmNvcHlfb3ZlcndyaXRlX2ZpbGVzKAoJCQkJCXNlbGY6OmdldF9maXJzdF9zdWJmb2xkZXIoICR0ZW1wZGlyICksCgkJCQkJJGRlc3QKCQkJCSk7CgoJCQkJc2VsZjo6cm1kaXIoICR0ZW1wZGlyICk7CgkJCQlyZXR1cm47CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIlBoYXJEYXRhIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvICd0YXIgeHonICgiCgkJCQkJLiAkZS0+Z2V0TWVzc2FnZSgpIC4gJyknCgkJCQkpOwoJCQkJLy8gRmFsbCB0aHJvdWdoIHRvIHRyeWluZyBgdGFyIHh6YCBiZWxvdy4KCQkJfQoJCX0KCgkJLy8gRW5zdXJlIHJlbGF0aXZlIHBhdGhzIGNhbm5vdCBiZSBtaXNpbnRlcnByZXRlZCBhcyBob3N0bmFtZXMuCgkJLy8gUHJlcGVuZGluZyBgLi9gIHdpbGwgZm9yY2UgdGFyIHRvIGludGVycHJldCBpdCBhcyBhIGZpbGVzeXN0ZW0gcGF0aC4KCQlpZiAoIHNlbGY6OnBhdGhfaXNfcmVsYXRpdmUoICR0YXJiYWxsICkgKSB7CgkJCSR0YXJiYWxsID0gIi4veyR0YXJiYWxsfSI7CgkJfQoKCQlpZiAoICEgZmlsZSggJHRhcmJhbGwgKQoJCQl8fCAhIGlzX3JlYWRhYmxlKCAkdGFyYmFsbCApCgkJCXx8IGZpbGVzaXplKCAkdGFyYmFsbCApIDw9IDAgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICJJbnZhbGlkIHppcCBmaWxlICd7JHRhcmJhbGx9Jy4iICk7CgkJfQoKCQkvLyBOb3RlOiBkaXJlY3RvcnkgbXVzdCBleGlzdCBmb3IgdGFyIC0tZGlyZWN0b3J5IHRvIHdvcmsuCgkJJGNtZCA9IFV0aWxzXGVzY19jbWQoCgkJCSd0YXIgeHogLS1zdHJpcC1jb21wb25lbnRzPTEgLS1kaXJlY3Rvcnk9JXMgLWYgJXMnLAoJCQkkZGVzdCwKCQkJJHRhcmJhbGwKCQkpOwoKCQkkcHJvY2Vzc19ydW4gPSBXUF9DTEk6OmxhdW5jaCgKCQkJJGNtZCwKCQkJZmFsc2UgLypleGl0X29uX2Vycm9yKi8sCgkJCXRydWUgLypyZXR1cm5fZGV0YWlsZWQqLwoJCSk7CgoJCWlmICggMCAhPT0gJHByb2Nlc3NfcnVuLT5yZXR1cm5fY29kZSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigKCQkJCXNwcmludGYoCgkJCQkJJ0ZhaWxlZCB0byBleGVjdXRlIGAlc2A6ICVzLicsCgkJCQkJJGNtZCwKCQkJCQlzZWxmOjp0YXJfZXJyb3JfbXNnKCAkcHJvY2Vzc19ydW4gKQoJCQkJKQoJCQkpOwoJCX0KCX0KCgkvKioKCSAqIENvcHkgZmlsZXMgZnJvbSBzb3VyY2UgZGlyZWN0b3J5IHRvIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4gU291cmNlCgkgKiBkaXJlY3RvcnkgbXVzdCBleGlzdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UKCSAqIEBwYXJhbSBzdHJpbmcgJGRlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb3B5X292ZXJ3cml0ZV9maWxlcyggJHNvdXJjZSwgJGRlc3QgKSB7CgkJJGl0ZXJhdG9yID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoCgkJCW5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigKCQkJCSRzb3VyY2UsCgkJCQlSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTCgkJCSksCgkJCVJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OlNFTEZfRklSU1QKCQkpOwoKCQkkZXJyb3IgPSAwOwoKCQlpZiAoICEgaXNfZGlyKCAkZGVzdCApICkgewoJCQlta2RpciggJGRlc3QsIDA3NzcsIHRydWUgKTsKCQl9CgoJCWZvcmVhY2ggKCAkaXRlcmF0b3IgYXMgJGl0ZW0gKSB7CgoJCQkkZGVzdF9wYXRoID0gJGRlc3QgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGl0ZXJhdG9yLT5nZXRTdWJQYXRoTmFtZSgpOwoKCQkJaWYgKCAkaXRlbS0+aXNEaXIoKSApIHsKCQkJCWlmICggISBpc19kaXIoICRkZXN0X3BhdGggKSApIHsKCQkJCQlta2RpciggJGRlc3RfcGF0aCApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJaWYgKCBmaWxlX2V4aXN0cyggJGRlc3RfcGF0aCApICYmIGlzX3dyaXRhYmxlKCAkZGVzdF9wYXRoICkgKSB7CgkJCQkJY29weSggJGl0ZW0sICRkZXN0X3BhdGggKTsKCQkJCX0gZWxzZWlmICggISBmaWxlX2V4aXN0cyggJGRlc3RfcGF0aCApICkgewoJCQkJCWNvcHkoICRpdGVtLCAkZGVzdF9wYXRoICk7CgkJCQl9IGVsc2UgewoJCQkJCSRlcnJvciA9IDE7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVW5hYmxlIHRvIGNvcHkgJyIgLiAkaXRlcmF0b3ItPmdldFN1YlBhdGhOYW1lKCkgLiAiJyB0byBjdXJyZW50IGRpcmVjdG9yeS4iICk7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJGVycm9yICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnVGhlcmUgd2FzIGFuIGVycm9yIG92ZXJ3cml0aW5nIGV4aXN0aW5nIGZpbGVzLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGUgYWxsIGZpbGVzIGFuZCBkaXJlY3RvcmllcyByZWN1cnNpdmVseSBmcm9tIGRpcmVjdG9yeS4gRGlyZWN0b3J5CgkgKiBtdXN0IGV4aXN0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRpcgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJtZGlyKCAkZGlyICkgewoJCSRmaWxlcyA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKAoJCQluZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoCgkJCQkkZGlyLAoJCQkJUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUwoJCQkpLAoJCQlSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpDSElMRF9GSVJTVAoJCSk7CgoJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGVpbmZvICkgewoJCQkkdG9kbyA9ICRmaWxlaW5mby0+aXNEaXIoKSA/ICdybWRpcicgOiAndW5saW5rJzsKCQkJJHBhdGggPSAkZmlsZWluZm8tPmdldFJlYWxQYXRoKCk7CgkJCWlmICggMCAhPT0gc3RycG9zKCAkcGF0aCwgJGZpbGVpbmZvLT5nZXRSZWFsUGF0aCgpICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIlRlbXBvcmFyeSBmaWxlIG9yIGZvbGRlciB0byBiZSByZW1vdmVkIHdhcyBmb3VuZCBvdXRzaWRlIG9mIHRlbXBvcmFyeSBmb2xkZXIsIGFib3J0aW5nIHJlbW92YWw6ICd7JHBhdGh9JyIKCQkJCSk7CgkJCX0KCQkJJHRvZG8oICRwYXRoICk7CgkJfQoJCXJtZGlyKCAkZGlyICk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gZm9ybWF0dGVkIFppcEFyY2hpdmUgZXJyb3IgbWVzc2FnZSBmcm9tIGVycm9yIGNvZGUuCgkgKgoJICogQHBhcmFtIGludCAkZXJyb3JfY29kZQoJICogQHJldHVybiBzdHJpbmd8aW50IFRoZSBlcnJvciBtZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZAoJICogICAgICAgICAgICAgICAgICAgIGNvZGUsIGlmIGZvdW5kOyBPdGhlciB3aXNlIHRoZSBzYW1lIGVycm9yIGNvZGUsCgkgKiAgICAgICAgICAgICAgICAgICAgdW5tb2RpZmllZC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB6aXBfZXJyb3JfbXNnKCAkZXJyb3JfY29kZSApIHsKCQkvLyBGcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAvcGhwLXNyYy9ibG9iL3BocC01LjMuMC9leHQvemlwL3BocF96aXAuYyNMMjYyMy1MMjY0Ni4KCQlzdGF0aWMgJHppcF9lcnJfbXNncyA9IFsKCQkJWmlwQXJjaGl2ZTo6RVJfT0sgICAgICAgICAgPT4gJ05vIGVycm9yJywKCQkJWmlwQXJjaGl2ZTo6RVJfTVVMVElESVNLICAgPT4gJ011bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQnLAoJCQlaaXBBcmNoaXZlOjpFUl9SRU5BTUUgICAgICA9PiAnUmVuYW1pbmcgdGVtcG9yYXJ5IGZpbGUgZmFpbGVkJywKCQkJWmlwQXJjaGl2ZTo6RVJfQ0xPU0UgICAgICAgPT4gJ0Nsb3NpbmcgemlwIGFyY2hpdmUgZmFpbGVkJywKCQkJWmlwQXJjaGl2ZTo6RVJfU0VFSyAgICAgICAgPT4gJ1NlZWsgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9SRUFEICAgICAgICA9PiAnUmVhZCBlcnJvcicsCgkJCVppcEFyY2hpdmU6OkVSX1dSSVRFICAgICAgID0+ICdXcml0ZSBlcnJvcicsCgkJCVppcEFyY2hpdmU6OkVSX0NSQyAgICAgICAgID0+ICdDUkMgZXJyb3InLAoJCQlaaXBBcmNoaXZlOjpFUl9aSVBDTE9TRUQgICA9PiAnQ29udGFpbmluZyB6aXAgYXJjaGl2ZSB3YXMgY2xvc2VkJywKCQkJWmlwQXJjaGl2ZTo6RVJfTk9FTlQgICAgICAgPT4gJ05vIHN1Y2ggZmlsZScsCgkJCVppcEFyY2hpdmU6OkVSX0VYSVNUUyAgICAgID0+ICdGaWxlIGFscmVhZHkgZXhpc3RzJywKCQkJWmlwQXJjaGl2ZTo6RVJfT1BFTiAgICAgICAgPT4gJ0NhblwndCBvcGVuIGZpbGUnLAoJCQlaaXBBcmNoaXZlOjpFUl9UTVBPUEVOICAgICA9PiAnRmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUnLAoJCQlaaXBBcmNoaXZlOjpFUl9aTElCICAgICAgICA9PiAnWmxpYiBlcnJvcicsCgkJCVppcEFyY2hpdmU6OkVSX01FTU9SWSAgICAgID0+ICdNYWxsb2MgZmFpbHVyZScsCgkJCVppcEFyY2hpdmU6OkVSX0NIQU5HRUQgICAgID0+ICdFbnRyeSBoYXMgYmVlbiBjaGFuZ2VkJywKCQkJWmlwQXJjaGl2ZTo6RVJfQ09NUE5PVFNVUFAgPT4gJ0NvbXByZXNzaW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkJywKCQkJWmlwQXJjaGl2ZTo6RVJfRU9GICAgICAgICAgPT4gJ1ByZW1hdHVyZSBFT0YnLAoJCQlaaXBBcmNoaXZlOjpFUl9JTlZBTCAgICAgICA9PiAnSW52YWxpZCBhcmd1bWVudCcsCgkJCVppcEFyY2hpdmU6OkVSX05PWklQICAgICAgID0+ICdOb3QgYSB6aXAgYXJjaGl2ZScsCgkJCVppcEFyY2hpdmU6OkVSX0lOVEVSTkFMICAgID0+ICdJbnRlcm5hbCBlcnJvcicsCgkJCVppcEFyY2hpdmU6OkVSX0lOQ09OUyAgICAgID0+ICdaaXAgYXJjaGl2ZSBpbmNvbnNpc3RlbnQnLAoJCQlaaXBBcmNoaXZlOjpFUl9SRU1PVkUgICAgICA9PiAnQ2FuXCd0IHJlbW92ZSBmaWxlJywKCQkJWmlwQXJjaGl2ZTo6RVJfREVMRVRFRCAgICAgPT4gJ0VudHJ5IGhhcyBiZWVuIGRlbGV0ZWQnLAoJCV07CgoJCWlmICggaXNzZXQoICR6aXBfZXJyX21zZ3NbICRlcnJvcl9jb2RlIF0gKSApIHsKCQkJcmV0dXJuIHNwcmludGYoCgkJCQknJXMgKCVkKScsCgkJCQkkemlwX2Vycl9tc2dzWyAkZXJyb3JfY29kZSBdLAoJCQkJJGVycm9yX2NvZGUKCQkJKTsKCQl9CgkJcmV0dXJuICRlcnJvcl9jb2RlOwoJfQoKCS8qKgoJICogUmV0dXJuIGZvcm1hdHRlZCBlcnJvciBtZXNzYWdlIGZyb20gUHJvY2Vzc1J1biBvZiB0YXIgY29tbWFuZC4KCSAqCgkgKiBAcGFyYW0gUHJvY2Vzc3J1biAkcHJvY2Vzc19ydW4KCSAqIEByZXR1cm4gc3RyaW5nfGludCBUaGUgZXJyb3IgbWVzc2FnZSBvZiB0aGUgcHJvY2VzcywgaWYgYXZhaWxhYmxlOwoJICogICAgICAgICAgICAgICAgICAgIG90aGVyd2lzZSB0aGUgcmV0dXJuIGNvZGUuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdGFyX2Vycm9yX21zZyggJHByb2Nlc3NfcnVuICkgewoJCSRzdGRlcnIgPSB0cmltKCAkcHJvY2Vzc19ydW4tPnN0ZGVyciApOwoJCSRubF9wb3MgPSBzdHJwb3MoICRzdGRlcnIsICJcbiIgKTsKCQlpZiAoIGZhbHNlICE9PSAkbmxfcG9zICkgewoJCQkkc3RkZXJyID0gdHJpbSggc3Vic3RyKCAkc3RkZXJyLCAwLCAkbmxfcG9zICkgKTsKCQl9CgkJaWYgKCAkc3RkZXJyICkgewoJCQlyZXR1cm4gc3ByaW50ZiggJyVzICglZCknLCAkc3RkZXJyLCAkcHJvY2Vzc19ydW4tPnJldHVybl9jb2RlICk7CgkJfQoJCXJldHVybiAkcHJvY2Vzc19ydW4tPnJldHVybl9jb2RlOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSBmaXJzdCBzdWJmb2xkZXIgd2l0aGluIGEgZ2l2ZW4gcGF0aC4KCSAqCgkgKiBGYWxscyBiYWNrIHRvIHRoZSBwcm92aWRlZCBwYXRoIGlmIG5vIHN1YmZvbGRlciB3YXMgZGV0ZWN0ZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIGZpbmQgdGhlIGZpcnN0IHN1YmZvbGRlciBpbi4KCSAqIEByZXR1cm4gc3RyaW5nIEZpcnN0IHN1YmZvbGRlciwgb3Igc2FtZSBhcyAkcGF0aCBpZiBub25lIGZvdW5kLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfZmlyc3Rfc3ViZm9sZGVyKCAkcGF0aCApIHsKCQkkaXRlcmF0b3IgPSBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRwYXRoICk7CgoJCWZvcmVhY2ggKCAkaXRlcmF0b3IgYXMgJGZpbGVpbmZvICkgewoJCQlpZiAoICRmaWxlaW5mby0+aXNEaXIoKSAmJiAhICRmaWxlaW5mby0+aXNEb3QoKSApIHsKCQkJCXJldHVybiAieyRwYXRofS97JGZpbGVpbmZvLT5nZXRGaWxlbmFtZSgpfSI7CgkJCX0KCQl9CgoJCXJldHVybiAkcGF0aDsKCX0KCgkvKioKCSAqIEVuc3VyZSBkaXJlY3RvcnkgZXhpc3RzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRpciBEaXJlY3RvcnkgdG8gZW5zdXJlIHRoZSBleGlzdGVuY2Ugb2YuCgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZXhpc3RlbmNlIGNvdWxkIGJlIGFzc2VydGVkLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBlbnN1cmVfZGlyX2V4aXN0cyggJGRpciApIHsKCQlpZiAoICEgaXNfZGlyKCAkZGlyICkgKSB7CgkJCWlmICggISBAbWtkaXIoICRkaXIsIDA3NzcsIHRydWUgKSApIHsKCQkJCSRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJc3ByaW50ZigKCQkJCQkJIkZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICclcyc6ICVzLiIsCgkJCQkJCSRkaXIsCgkJCQkJCSRlcnJvclsnbWVzc2FnZSddCgkJCQkJKQoJCQkJKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBDaGVjayB3aGV0aGVyIGEgcGF0aCBpcyByZWxhdGl2ZS0KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gY2hlY2suCgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgcGF0aCBpcyByZWxhdGl2ZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcGF0aF9pc19yZWxhdGl2ZSggJHBhdGggKSB7CgkJaWYgKCAnJyA9PT0gJHBhdGggKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gU3RyaXAgc2NoZW1lLgoJCSRzY2hlbWVfcG9zaXRpb24gPSBzdHJwb3MoICRwYXRoLCAnOi8vJyApOwoJCWlmICggZmFsc2UgIT09ICRzY2hlbWVfcG9zaXRpb24gKSB7CgkJCSRwYXRoID0gc3Vic3RyKCAkcGF0aCwgJHNjaGVtZV9wb3NpdGlvbiArIDMgKTsKCQl9CgoJCS8vIFVOSVggcm9vdCAiLyIgb3IgIlwiIChXaW5kb3dzIHN0eWxlKS4KCQlpZiAoICcvJyA9PT0gJHBhdGhbMF0gfHwgJ1xcJyA9PT0gJHBhdGhbMF0gKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIFdpbmRvd3Mgcm9vdC4KCQlpZiAoIHN0cmxlbiggJHBhdGggKSA+IDEgJiYgY3R5cGVfYWxwaGEoICRwYXRoWzBdICkgJiYgJzonID09PSAkcGF0aFsxXSApIHsKCgkJCS8vIFNwZWNpYWwgY2FzZTogb25seSBkcml2ZSBsZXR0ZXIsIGxpa2UgIkM6Ii4KCQkJaWYgKCAyID09PSBzdHJsZW4oICRwYXRoICkgKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIFJlZ3VsYXIgV2luZG93cyBwYXRoIHN0YXJ0aW5nIHdpdGggZHJpdmUgbGV0dGVyLCBsaWtlICJDOi8gb3IgIkM6XCIuCgkJCWlmICggJy8nID09PSAkcGF0aFsyXSB8fCAnXFwnID09PSAkcGF0aFsyXSApIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29tcGF0XE1pbl9QSFBfNV82OwoKdHJhaXQgRmVlZGJhY2tNZXRob2RUcmFpdCB7CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKCSAqIEBwYXJhbSBtaXhlZCAgLi4uJGFyZ3MgT3B0aW9uYWwgdGV4dCByZXBsYWNlbWVudHMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmZWVkYmFjayggJHN0cmluZywgLi4uJGFyZ3MgKSB7IC8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5Lkxhbmd1YWdlQ29uc3RydWN0cy5OZXdMYW5ndWFnZUNvbnN0cnVjdHMudF9lbGxpcHNpc0ZvdW5kCgkJJGFyZ3NfYXJyYXkgPSBbXTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGFyZyApIHsKCQkJJGFyZ3NfYXJyYXlbXSA9ICRhcmdzOwoJCX0KCgkJJHRoaXMtPnByb2Nlc3NfZmVlZGJhY2soICRzdHJpbmcsICRhcmdzICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29tcGF0OwoKLy8gcGhwY3M6ZGlzYWJsZSBHZW5lcmljLkZpbGVzLk9uZU9iamVjdFN0cnVjdHVyZVBlckZpbGUuTXVsdGlwbGVGb3VuZCxHZW5lcmljLkNsYXNzZXMuRHVwbGljYXRlQ2xhc3NOYW1lLkZvdW5kCgppZiAoIFBIUF9WRVJTSU9OX0lEID49IDUwNjAwICkgewoJcmVxdWlyZV9vbmNlIF9fRElSX18gLiAnL01pbl9QSFBfNV82L0ZlZWRiYWNrTWV0aG9kVHJhaXQucGhwJzsKCgl0cmFpdCBGZWVkYmFja01ldGhvZFRyYWl0IHsKCgkJdXNlIE1pbl9QSFBfNV82XEZlZWRiYWNrTWV0aG9kVHJhaXQ7Cgl9CgoJcmV0dXJuOwp9CgpyZXF1aXJlX29uY2UgX19ESVJfXyAuICcvTWluX1BIUF81XzQvRmVlZGJhY2tNZXRob2RUcmFpdC5waHAnOwoKdHJhaXQgRmVlZGJhY2tNZXRob2RUcmFpdCB7CgoJdXNlIE1pbl9QSFBfNV80XEZlZWRiYWNrTWV0aG9kVHJhaXQ7Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29tcGF0XE1pbl9QSFBfNV80OwoKdHJhaXQgRmVlZGJhY2tNZXRob2RUcmFpdCB7CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZlZWRiYWNrKCAkc3RyaW5nICkgewoJCSRhcmdzID0gZnVuY19nZXRfYXJncygpOwoJCSRhcmdzID0gYXJyYXlfc3BsaWNlKCAkYXJncywgMSApOwoKCQkkdGhpcy0+cHJvY2Vzc19mZWVkYmFjayggJHN0cmluZywgJGFyZ3MgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCi8qKgogKiBSZXN1bHRzIG9mIGFuIGV4ZWN1dGVkIGNvbW1hbmQuCiAqLwpjbGFzcyBQcm9jZXNzUnVuIHsKCgkvKioKCSAqIFRoZSBmdWxsIGNvbW1hbmQgZXhlY3V0ZWQgYnkgdGhlIHN5c3RlbS4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJGNvbW1hbmQ7CgoJLyoqCgkgKiBDYXB0dXJlZCBvdXRwdXQgZnJvbSB0aGUgcHJvY2VzcycgU1RET1VULgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXB1YmxpYyAkc3Rkb3V0OwoKCS8qKgoJICogQ2FwdHVyZWQgb3V0cHV0IGZyb20gdGhlIHByb2Nlc3MnIFNUREVSUi4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHN0ZGVycjsKCgkvKioKCSAqIFRoZSBwYXRoIG9mIHRoZSB3b3JraW5nIGRpcmVjdG9yeSBmb3IgdGhlIHByb2Nlc3Mgb3IgTlVMTCBpZiBub3Qgc3BlY2lmaWVkLgoJICoKCSAqIFRoaXMgZGVmYXVsdHMgdG8gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4KCSAqCgkgKiBAdmFyIHN0cmluZ3xudWxsCgkgKi8KCXB1YmxpYyAkY3dkOwoKCS8qKgoJICogRW52aXJvbm1lbnQgdmFyaWFibGVzIHNldCBmb3IgdGhpcyBwcm9jZXNzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHVibGljICRlbnY7CgoJLyoqCgkgKiBFeGl0IGNvZGUgb2YgdGhlIHByb2Nlc3MuCgkgKgoJICogQHZhciBpbnQKCSAqLwoJcHVibGljICRyZXR1cm5fY29kZTsKCgkvKioKCSAqIFRoZSBydW4gdGltZSBvZiB0aGUgcHJvY2Vzcy4KCSAqCgkgKiBAdmFyIGZsb2F0CgkgKi8KCXB1YmxpYyAkcnVuX3RpbWU7CgoJLyoqCgkgKiBAcGFyYW0gYXJyYXkgJHByb3BzIFByb3BlcnRpZXMgb2YgZXhlY3V0ZWQgY29tbWFuZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkcHJvcHMgKSB7CgkJZm9yZWFjaCAoICRwcm9wcyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJJHRoaXMtPiRrZXkgPSAkdmFsdWU7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJuIHByb3BlcnRpZXMgb2YgZXhlY3V0ZWQgY29tbWFuZCBhcyBhIHN0cmluZy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpIHsKCQkkb3V0ICA9ICIkICR0aGlzLT5jb21tYW5kXG4iOwoJCSRvdXQgLj0gIiR0aGlzLT5zdGRvdXRcbiR0aGlzLT5zdGRlcnIiOwoJCSRvdXQgLj0gImN3ZDogJHRoaXMtPmN3ZFxuIjsKCQkkb3V0IC49ICJydW4gdGltZTogJHRoaXMtPnJ1bl90aW1lXG4iOwoJCSRvdXQgLj0gImV4aXQgc3RhdHVzOiAkdGhpcy0+cmV0dXJuX2NvZGUiOwoKCQlyZXR1cm4gJG91dDsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxMb2dnZXJzOwoKdXNlIGNsaVxDb2xvcnM7CnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcUnVubmVyOwoKLyoqCiAqIEJhc2UgbG9nZ2VyIGNsYXNzCiAqLwphYnN0cmFjdCBjbGFzcyBCYXNlIHsKCglwcm90ZWN0ZWQgJGluX2NvbG9yID0gZmFsc2U7CgoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGluZm8oICRtZXNzYWdlICk7CgoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHN1Y2Nlc3MoICRtZXNzYWdlICk7CgoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoICRtZXNzYWdlICk7CgoJLyoqCgkgKiBSZXRyaWV2ZSB0aGUgcnVubmVyIGluc3RhbmNlIGZyb20gdGhlIGJhc2UgQ0xJIG9iamVjdC4gVGhpcyBmYWNpbGl0YXRlcwoJICogdW5pdCB0ZXN0aW5nLCB3aGVyZSB0aGUgV1BfQ0xJIGluc3RhbmNlIGlzbid0IGF2YWlsYWJsZQoJICoKCSAqIEByZXR1cm4gUnVubmVyIEluc3RhbmNlIG9mIHRoZSBydW5uZXIgY2xhc3MKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9ydW5uZXIoKSB7CgkJcmV0dXJuIFdQX0NMSTo6Z2V0X3J1bm5lcigpOwoJfQoKCS8qKgoJICogV3JpdGUgYSBtZXNzYWdlIHRvIFNUREVSUiwgcHJlZml4ZWQgd2l0aCAiRGVidWc6ICIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICogQHBhcmFtIHN0cmluZ3xib29sICRncm91cCBPcmdhbml6ZSBkZWJ1ZyBtZXNzYWdlIHRvIGEgc3BlY2lmaWMgZ3JvdXAuCgkgKiBVc2UgYGZhbHNlYCBmb3Igbm8gZ3JvdXAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWJ1ZyggJG1lc3NhZ2UsICRncm91cCA9IGZhbHNlICkgewoJCXN0YXRpYyAkc3RhcnRfdGltZSA9IG51bGw7CgkJaWYgKCBudWxsID09PSAkc3RhcnRfdGltZSApIHsKCQkJJHN0YXJ0X3RpbWUgPSBtaWNyb3RpbWUoIHRydWUgKTsKCQl9CgkJJGRlYnVnID0gJHRoaXMtPmdldF9ydW5uZXIoKS0+Y29uZmlnWydkZWJ1ZyddOwoJCWlmICggISAkZGVidWcgKSB7CgkJCXJldHVybjsKCQl9CgkJaWYgKCB0cnVlICE9PSAkZGVidWcgJiYgJGdyb3VwICE9PSAkZGVidWcgKSB7CgkJCXJldHVybjsKCQl9CgkJJHRpbWUgICA9IHJvdW5kKCBtaWNyb3RpbWUoIHRydWUgKSAtICggZGVmaW5lZCggJ1dQX0NMSV9TVEFSVF9NSUNST1RJTUUnICkgPyBXUF9DTElfU1RBUlRfTUlDUk9USU1FIDogJHN0YXJ0X3RpbWUgKSwgMyApOwoJCSRwcmVmaXggPSAnRGVidWcnOwoJCWlmICggJGdyb3VwICYmIHRydWUgPT09ICRkZWJ1ZyApIHsKCQkJJHByZWZpeCA9ICdEZWJ1ZyAoJyAuICRncm91cCAuICcpJzsKCQl9CgkJJHRoaXMtPl9saW5lKCAiJG1lc3NhZ2UgKHskdGltZX1zKSIsICRwcmVmaXgsICclQicsIFNUREVSUiApOwoJfQoKCS8qKgoJICogV3JpdGUgYSBzdHJpbmcgdG8gYSByZXNvdXJjZS4KCSAqCgkgKiBAcGFyYW0gcmVzb3VyY2UgJGhhbmRsZSBDb21tb25seSBTVERPVVQgb3IgU1RERVJSLgoJICogQHBhcmFtIHN0cmluZyAkc3RyIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSggJGhhbmRsZSwgJHN0ciApIHsKCQlmd3JpdGUoICRoYW5kbGUsICRzdHIgKTsKCX0KCgkvKioKCSAqIE91dHB1dCBvbmUgbGluZSBvZiBtZXNzYWdlIHRvIGEgcmVzb3VyY2UuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICogQHBhcmFtIHN0cmluZyAkbGFiZWwgUHJlZml4IG1lc3NhZ2Ugd2l0aCBhIGxhYmVsLgoJICogQHBhcmFtIHN0cmluZyAkY29sb3IgQ29sb3JpemUgbGFiZWwgd2l0aCBhIGdpdmVuIGNvbG9yLgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgUmVzb3VyY2UgdG8gd3JpdGUgdG8uIERlZmF1bHRzIHRvIFNURE9VVC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIF9saW5lKCAkbWVzc2FnZSwgJGxhYmVsLCAkY29sb3IsICRoYW5kbGUgPSBTVERPVVQgKSB7IC8vIHBocGNzOmlnbm9yZSBQU1IyLk1ldGhvZHMuTWV0aG9kRGVjbGFyYXRpb24uVW5kZXJzY29yZSAtLSBVc2VkIGluIHRoaXJkIHBhcnR5IGV4dGVuc2lvbnMuCgkJaWYgKCBjbGFzc19leGlzdHMoICdjbGlcQ29sb3JzJyApICkgewoJCQkkbGFiZWwgPSBDb2xvcnM6OmNvbG9yaXplKCAiJGNvbG9yJGxhYmVsOiVuIiwgJHRoaXMtPmluX2NvbG9yICk7CgkJfSBlbHNlIHsKCQkJJGxhYmVsID0gIiRsYWJlbDoiOwoJCX0KCQkkdGhpcy0+d3JpdGUoICRoYW5kbGUsICIkbGFiZWwgJG1lc3NhZ2VcbiIgKTsKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcTG9nZ2VyczsKCnVzZSBXUF9DTEk7CgovKioKICogRXhlY3V0aW9uIGxvZ2dlciBjYXB0dXJlcyBhbGwgU1RET1VUIGFuZCBTVERFUlIgd3JpdGVzCiAqLwpjbGFzcyBFeGVjdXRpb24gZXh0ZW5kcyBSZWd1bGFyIHsKCgkvKioKCSAqIENhcHR1cmVkIHdyaXRlcyB0byBTVERPVVQuCgkgKi8KCXB1YmxpYyAkc3Rkb3V0ID0gJyc7CgoJLyoqCgkgKiBDYXB0dXJlZCB3cml0ZXMgdG8gU1RERVJSLgoJICovCglwdWJsaWMgJHN0ZGVyciA9ICcnOwoKCS8qKgoJICogQHBhcmFtIGJvb2wgJGluX2NvbG9yIFdoZXRoZXIgb3Igbm90IHRvIENvbG9yaXplIHN0cmluZ3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGluX2NvbG9yID0gZmFsc2UgKSB7IC8vIHBocGNzOmlnbm9yZSBHZW5lcmljLkNvZGVBbmFseXNpcy5Vc2VsZXNzT3ZlcnJpZGluZ01ldGhvZC5Gb3VuZCAtLSBQcm92aWRlcyBhIGRlZmF1bHQgdmFsdWUuCgkJcGFyZW50OjpfX2NvbnN0cnVjdCggJGluX2NvbG9yICk7Cgl9CgoJLyoqCgkgKiBTaW1pbGFyIHRvIGVycm9yKCAkbWVzc2FnZSApLCBidXQgb3V0cHV0cyAkbWVzc2FnZSBpbiBhIHJlZCBib3guCgkgKgoJICogQHBhcmFtIGFycmF5ICRtZXNzYWdlX2xpbmVzIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlcnJvcl9tdWx0aV9saW5lKCAkbWVzc2FnZV9saW5lcyApIHsKCQkkbWVzc2FnZSA9IGltcGxvZGUoICJcbiIsICRtZXNzYWdlX2xpbmVzICk7CgoJCSR0aGlzLT53cml0ZSggU1RERVJSLCBXUF9DTEk6OmNvbG9yaXplKCAiJVJFcnJvcjolblxuJG1lc3NhZ2VcbiIgKSApOwoJCSR0aGlzLT53cml0ZSggU1RERVJSLCBXUF9DTEk6OmNvbG9yaXplKCAiJVItLS0tLS0tLS0lblxuXG4iICkgKTsKCX0KCgkvKioKCSAqIFdyaXRlIGEgc3RyaW5nIHRvIGEgcmVzb3VyY2UuCgkgKgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgQ29tbW9ubHkgU1RET1VUIG9yIFNUREVSUi4KCSAqIEBwYXJhbSBzdHJpbmcgJHN0ciBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICRoYW5kbGUsICRzdHIgKSB7CgkJc3dpdGNoICggJGhhbmRsZSApIHsKCQkJY2FzZSBTVERPVVQ6CgkJCQkkdGhpcy0+c3Rkb3V0IC49ICRzdHI7CgkJCQlicmVhazsKCQkJY2FzZSBTVERFUlI6CgkJCQkkdGhpcy0+c3RkZXJyIC49ICRzdHI7CgkJCQlicmVhazsKCQl9Cgl9CgoJLyoqCgkgKiBTdGFydHMgb3V0cHV0IGJ1ZmZlcmluZywgdXNpbmcgYSBjYWxsYmFjayB0byBjYXB0dXJlIG91dHB1dCBmcm9tIGBlY2hvYCwgYHByaW50YCwgYHByaW50ZmAgKHdoaWNoIHdyaXRlIHRvIHRoZSBvdXRwdXQgYnVmZmVyICdwaHA6Ly9vdXRwdXQnIHJhdGhlciB0aGFuIFNURE9VVCkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvYl9zdGFydCgpIHsKCQlvYl9zdGFydCggWyAkdGhpcywgJ29iX3N0YXJ0X2NhbGxiYWNrJyBdLCAxICk7Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmb3IgYG9iX3N0YXJ0KClgLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0ciBTdHJpbmcgdG8gd3JpdGUuCgkgKiBAcmV0dXJuIHN0cmluZyBSZXR1cm5zIHplcm8tbGVuZ3RoIHN0cmluZyBzbyBub3RoaW5nIGdldHMgd3JpdHRlbiB0byB0aGUgb3V0cHV0IGJ1ZmZlci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9iX3N0YXJ0X2NhbGxiYWNrKCAkc3RyICkgewoJCSR0aGlzLT53cml0ZSggU1RET1VULCAkc3RyICk7CgkJcmV0dXJuICcnOwoJfQoKCS8qKgoJICogVG8gbWF0Y2ggYG9iX3N0YXJ0KCkgYWJvdmUuIERvZXMgYW4gYG9iX2VuZF9mbHVzaCgpYC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9iX2VuZCgpIHsKCQlvYl9lbmRfZmx1c2goKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxMb2dnZXJzOwoKdXNlIFdQX0NMSTsKCi8qKgogKiBRdWlldCBsb2dnZXIgb25seSBsb2dzIGVycm9ycy4KICovCmNsYXNzIFF1aWV0IGV4dGVuZHMgQmFzZSB7CgoJLyoqCgkgKiBJbmZvcm1hdGlvbmFsIG1lc3NhZ2VzIGFyZW4ndCBsb2dnZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5mbyggJG1lc3NhZ2UgKSB7CgkJLy8gTm90aGluZy4KCX0KCgkvKioKCSAqIFN1Y2Nlc3MgbWVzc2FnZXMgYXJlbid0IGxvZ2dlZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdWNjZXNzKCAkbWVzc2FnZSApIHsKCQkvLyBOb3RoaW5nLgoJfQoKCS8qKgoJICogV2FybmluZyBtZXNzYWdlcyBhcmVuJ3QgbG9nZ2VkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgTWVzc2FnZSB0byB3cml0ZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoICRtZXNzYWdlICkgewoJCS8vIE5vdGhpbmcuCgl9CgoJLyoqCgkgKiBXcml0ZSBhbiBlcnJvciBtZXNzYWdlIHRvIFNUREVSUiwgcHJlZml4ZWQgd2l0aCAiRXJyb3I6ICIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXJyb3IoICRtZXNzYWdlICkgewoJCSR0aGlzLT53cml0ZSggU1RERVJSLCBXUF9DTEk6OmNvbG9yaXplKCAiJVJFcnJvcjolbiAkbWVzc2FnZVxuIiApICk7Cgl9CgoJLyoqCgkgKiBTaW1pbGFyIHRvIGVycm9yKCAkbWVzc2FnZSApLCBidXQgb3V0cHV0cyAkbWVzc2FnZSBpbiBhIHJlZCBib3guCgkgKgoJICogQHBhcmFtICBhcnJheSAkbWVzc2FnZV9saW5lcyBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXJyb3JfbXVsdGlfbGluZSggJG1lc3NhZ2VfbGluZXMgKSB7CgkJJG1lc3NhZ2UgPSBpbXBsb2RlKCAiXG4iLCAkbWVzc2FnZV9saW5lcyApOwoKCQkkdGhpcy0+d3JpdGUoIFNUREVSUiwgV1BfQ0xJOjpjb2xvcml6ZSggIiVSRXJyb3I6JW5cbiRtZXNzYWdlXG4iICkgKTsKCQkkdGhpcy0+d3JpdGUoIFNUREVSUiwgV1BfQ0xJOjpjb2xvcml6ZSggIiVSLS0tLS0tLS0tJW5cblxuIiApICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcTG9nZ2VyczsKCnVzZSBjbGlcQ29sb3JzOwoKLyoqCiAqIERlZmF1bHQgbG9nZ2VyIGZvciBzdWNjZXNzLCB3YXJuaW5nLCBlcnJvciwgYW5kIHN0YW5kYXJkIG1lc3NhZ2VzLgogKi8KY2xhc3MgUmVndWxhciBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogQHBhcmFtIGJvb2wgJGluX2NvbG9yIFdoZXRoZXIgb3Igbm90IHRvIENvbG9yaXplIHN0cmluZ3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGluX2NvbG9yICkgewoJCSR0aGlzLT5pbl9jb2xvciA9ICRpbl9jb2xvcjsKCX0KCgkvKioKCSAqIFdyaXRlIGFuIGluZm9ybWF0aW9uYWwgbWVzc2FnZSB0byBTVERPVVQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5mbyggJG1lc3NhZ2UgKSB7CgkJJHRoaXMtPndyaXRlKCBTVERPVVQsICRtZXNzYWdlIC4gIlxuIiApOwoJfQoKCS8qKgoJICogV3JpdGUgYSBzdWNjZXNzIG1lc3NhZ2UsIHByZWZpeGVkIHdpdGggIlN1Y2Nlc3M6ICIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc3VjY2VzcyggJG1lc3NhZ2UgKSB7CgkJJHRoaXMtPl9saW5lKCAkbWVzc2FnZSwgJ1N1Y2Nlc3MnLCAnJUcnICk7Cgl9CgoJLyoqCgkgKiBXcml0ZSBhIHdhcm5pbmcgbWVzc2FnZSB0byBTVERFUlIsIHByZWZpeGVkIHdpdGggIldhcm5pbmc6ICIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gd2FybmluZyggJG1lc3NhZ2UgKSB7CgkJJHRoaXMtPl9saW5lKCAkbWVzc2FnZSwgJ1dhcm5pbmcnLCAnJUMnLCBTVERFUlIgKTsKCX0KCgkvKioKCSAqIFdyaXRlIGFuIG1lc3NhZ2UgdG8gU1RERVJSLCBwcmVmaXhlZCB3aXRoICJFcnJvcjogIi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgdG8gd3JpdGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlcnJvciggJG1lc3NhZ2UgKSB7CgkJJHRoaXMtPl9saW5lKCAkbWVzc2FnZSwgJ0Vycm9yJywgJyVSJywgU1RERVJSICk7Cgl9CgoJLyoqCgkgKiBTaW1pbGFyIHRvIGVycm9yKCAkbWVzc2FnZSApLCBidXQgb3V0cHV0cyAkbWVzc2FnZSBpbiBhIHJlZCBib3guCgkgKgoJICogQHBhcmFtICBhcnJheSAkbWVzc2FnZV9saW5lcyBNZXNzYWdlIHRvIHdyaXRlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXJyb3JfbXVsdGlfbGluZSggJG1lc3NhZ2VfbGluZXMgKSB7CgkJLy8gQ29udmVydCB0YWJzIHRvIGZvdXIgc3BhY2VzLCBhcyBzb21lIHNoZWxscyB3aWxsIG91dHB1dCB0aGUgdGFicyBhcyB2YXJpYWJsZS1sZW5ndGguCgkJJG1lc3NhZ2VfbGluZXMgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAkbGluZSApIHsKCQkJCXJldHVybiBzdHJfcmVwbGFjZSggIlx0IiwgJyAgICAnLCAkbGluZSApOwoJCQl9LAoJCQkkbWVzc2FnZV9saW5lcwoJCSk7CgoJCSRsb25nZXN0ID0gbWF4KCBhcnJheV9tYXAoICdzdHJsZW4nLCAkbWVzc2FnZV9saW5lcyApICk7CgoJCS8vIFdyaXRlIGFuIGVtcHR5IGxpbmUgYmVmb3JlIHRoZSBtZXNzYWdlLgoJCSRlbXB0eV9saW5lID0gQ29sb3JzOjpjb2xvcml6ZSggJyV3JTEgJyAuIHN0cl9yZXBlYXQoICcgJywgJGxvbmdlc3QgKSAuICcgJW4nICk7CgkJJHRoaXMtPndyaXRlKCBTVERFUlIsICJcblx0JGVtcHR5X2xpbmVcbiIgKTsKCgkJZm9yZWFjaCAoICRtZXNzYWdlX2xpbmVzIGFzICRsaW5lICkgewoJCQkkcGFkZGluZyA9IHN0cl9yZXBlYXQoICcgJywgJGxvbmdlc3QgLSBzdHJsZW4oICRsaW5lICkgKTsKCQkJJGxpbmUgICAgPSBDb2xvcnM6OmNvbG9yaXplKCAiJXclMSAkbGluZSAkcGFkZGluZyVuIiApOwoJCQkkdGhpcy0+d3JpdGUoIFNUREVSUiwgIlx0JGxpbmVcbiIgKTsKCQl9CgoJCS8vIFdyaXRlIGFuIGVtcHR5IGxpbmUgYWZ0ZXIgdGhlIG1lc3NhZ2UuCgkJJHRoaXMtPndyaXRlKCBTVERFUlIsICJcdCRlbXB0eV9saW5lXG5cbiIgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CgpjbGFzcyBDb21wbGV0aW9ucyB7CgoJcHJpdmF0ZSAkd29yZHM7Cglwcml2YXRlICRvcHRzID0gW107CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkbGluZSApIHsKCQkvLyBUT0RPOiBwcm9wZXJseSBwYXJzZSBzaW5nbGUgYW5kIGRvdWJsZSBxdW90ZXMKCQkkdGhpcy0+d29yZHMgPSBleHBsb2RlKCAnICcsICRsaW5lICk7CgoJCS8vIEZpcnN0IHdvcmQgaXMgYWx3YXlzIGB3cGAuCgkJYXJyYXlfc2hpZnQoICR0aGlzLT53b3JkcyApOwoKCQkvLyBMYXN0IHdvcmQgaXMgZWl0aGVyIGVtcHR5IG9yIGFuIGluY29tcGxldGUgc3ViY29tbWFuZC4KCQkkdGhpcy0+Y3VyX3dvcmQgPSBlbmQoICR0aGlzLT53b3JkcyApOwoJCWlmICggJycgIT09ICR0aGlzLT5jdXJfd29yZCAmJiAhIHByZWdfbWF0Y2goICcvXlwtLycsICR0aGlzLT5jdXJfd29yZCApICkgewoJCQlhcnJheV9wb3AoICR0aGlzLT53b3JkcyApOwoJCX0KCgkJJGlzX2FsaWFzID0gZmFsc2U7CgkJJGlzX2hlbHAgID0gZmFsc2U7CgkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+d29yZHNbMF0gKSAmJiBwcmVnX21hdGNoKCAnL15ALycsICR0aGlzLT53b3Jkc1swXSApICkgewoJCQlhcnJheV9zaGlmdCggJHRoaXMtPndvcmRzICk7CgkJCS8vIGB3cCBAYWxgIGlzIGZhbHNlLCBidXQgYHdwIEBhbGwgYCBpcyB0cnVlLgoJCQlpZiAoIGNvdW50KCAkdGhpcy0+d29yZHMgKSApIHsKCQkJCSRpc19hbGlhcyA9IHRydWU7CgkJCX0KCQl9IGVsc2VpZiAoICEgZW1wdHkoICR0aGlzLT53b3Jkc1swXSApICYmICdoZWxwJyA9PT0gJHRoaXMtPndvcmRzWzBdICkgewoJCQlhcnJheV9zaGlmdCggJHRoaXMtPndvcmRzICk7CgkJCSRpc19oZWxwID0gdHJ1ZTsKCQl9CgoJCSRyID0gJHRoaXMtPmdldF9jb21tYW5kKCAkdGhpcy0+d29yZHMgKTsKCQlpZiAoICEgaXNfYXJyYXkoICRyICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWxpc3QoICRjb21tYW5kLCAkYXJncywgJGFzc29jX2FyZ3MgKSA9ICRyOwoKCQkkc3BlYyA9IFN5bm9wc2lzUGFyc2VyOjpwYXJzZSggJGNvbW1hbmQtPmdldF9zeW5vcHNpcygpICk7CgoJCWZvcmVhY2ggKCAkc3BlYyBhcyAkYXJnICkgewoJCQlpZiAoICdwb3NpdGlvbmFsJyA9PT0gJGFyZ1sndHlwZSddICYmICdmaWxlJyA9PT0gJGFyZ1snbmFtZSddICkgewoJCQkJJHRoaXMtPmFkZCggJzxmaWxlPiAnICk7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgoJCWlmICggJGNvbW1hbmQtPmNhbl9oYXZlX3N1YmNvbW1hbmRzKCkgKSB7CgkJCS8vIEFkZCBjb21wbGV0aW9uIHdoZW4gY29tbWFuZCBpcyBgd3BgIGFuZCBhbGlhcyBpc24ndCBzZXQuCgkJCWlmICggJ3dwJyA9PT0gJGNvbW1hbmQtPmdldF9uYW1lKCkgJiYgZmFsc2UgPT09ICRpc19hbGlhcyAmJiBmYWxzZSA9PT0gJGlzX2hlbHAgKSB7CgkJCQkkYWxpYXNlcyA9IFdQX0NMSTo6Z2V0X2NvbmZpZ3VyYXRvcigpLT5nZXRfYWxpYXNlcygpOwoJCQkJZm9yZWFjaCAoICRhbGlhc2VzIGFzICRuYW1lID0+ICRfICkgewoJCQkJCSR0aGlzLT5hZGQoICIkbmFtZSAiICk7CgkJCQl9CgkJCX0KCQkJZm9yZWFjaCAoICRjb21tYW5kLT5nZXRfc3ViY29tbWFuZHMoKSBhcyAkbmFtZSA9PiAkXyApIHsKCQkJCSR0aGlzLT5hZGQoICIkbmFtZSAiICk7CgkJCX0KCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJHNwZWMgYXMgJGFyZyApIHsKCQkJCWlmICggaW5fYXJyYXkoICRhcmdbJ3R5cGUnXSwgWyAnZmxhZycsICdhc3NvYycgXSwgdHJ1ZSApICkgewoJCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkYXJnWyduYW1lJ10gXSApICkgewoJCQkJCQljb250aW51ZTsKCQkJCQl9CgoJCQkJCSRvcHQgPSAiLS17JGFyZ1snbmFtZSddfSI7CgoJCQkJCWlmICggJ2ZsYWcnID09PSAkYXJnWyd0eXBlJ10gKSB7CgkJCQkJCSRvcHQgLj0gJyAnOwoJCQkJCX0gZWxzZWlmICggISAkYXJnWyd2YWx1ZSddWydvcHRpb25hbCddICkgewoJCQkJCQkkb3B0IC49ICc9JzsKCQkJCQl9CgoJCQkJCSR0aGlzLT5hZGQoICRvcHQgKTsKCQkJCX0KCQkJfQoKCQkJZm9yZWFjaCAoICR0aGlzLT5nZXRfZ2xvYmFsX3BhcmFtZXRlcnMoKSBhcyAkcGFyYW0gPT4gJHJ1bnRpbWUgKSB7CgkJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJHBhcmFtIF0gKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkb3B0ID0gIi0teyRwYXJhbX0iOwoKCQkJCWlmICggJycgPT09ICRydW50aW1lIHx8ICEgaXNfc3RyaW5nKCAkcnVudGltZSApICkgewoJCQkJCSRvcHQgLj0gJyAnOwoJCQkJfSBlbHNlIHsKCQkJCQkkb3B0IC49ICc9JzsKCQkJCX0KCgkJCQkkdGhpcy0+YWRkKCAkb3B0ICk7CgkJCX0KCQl9CgoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbW1hbmQoICR3b3JkcyApIHsKCQkkcG9zaXRpb25hbF9hcmdzID0gW107CgkJJGFzc29jX2FyZ3MgICAgICA9IFtdOwoKCQlmb3JlYWNoICggJHdvcmRzIGFzICRhcmcgKSB7CgkJCWlmICggcHJlZ19tYXRjaCggJ3xeLS0oW149XSspPT98JywgJGFyZywgJG1hdGNoZXMgKSApIHsKCQkJCSRhc3NvY19hcmdzWyAkbWF0Y2hlc1sxXSBdID0gdHJ1ZTsKCQkJfSBlbHNlIHsKCQkJCSRwb3NpdGlvbmFsX2FyZ3NbXSA9ICRhcmc7CgkJCX0KCQl9CgoJCSRyID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmZpbmRfY29tbWFuZF90b19ydW4oICRwb3NpdGlvbmFsX2FyZ3MgKTsKCQlpZiAoICEgaXNfYXJyYXkoICRyICkgJiYgYXJyYXlfcG9wKCAkcG9zaXRpb25hbF9hcmdzICkgPT09ICR0aGlzLT5jdXJfd29yZCApIHsKCQkJJHIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+ZmluZF9jb21tYW5kX3RvX3J1biggJHBvc2l0aW9uYWxfYXJncyApOwoJCX0KCgkJaWYgKCAhIGlzX2FycmF5KCAkciApICkgewoJCQlyZXR1cm4gJHI7CgkJfQoKCQlsaXN0KCAkY29tbWFuZCwgJGFyZ3MgKSA9ICRyOwoKCQlyZXR1cm4gWyAkY29tbWFuZCwgJGFyZ3MsICRhc3NvY19hcmdzIF07Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZ2xvYmFsX3BhcmFtZXRlcnMoKSB7CgkJJHBhcmFtcyA9IFtdOwoJCWZvcmVhY2ggKCBXUF9DTEk6OmdldF9jb25maWd1cmF0b3IoKS0+Z2V0X3NwZWMoKSBhcyAka2V5ID0+ICRkZXRhaWxzICkgewoJCQlpZiAoIGZhbHNlID09PSAkZGV0YWlsc1sncnVudGltZSddICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggaXNzZXQoICRkZXRhaWxzWydkZXByZWNhdGVkJ10gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoIGlzc2V0KCAkZGV0YWlsc1snaGlkZGVuJ10gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCSRwYXJhbXNbICRrZXkgXSA9ICRkZXRhaWxzWydydW50aW1lJ107CgoJCQkvLyBBZGQgYWRkaXRpb25hbCBvcHRpb24gbGlrZSBgLS1bbm8tXWNvbG9yYC4KCQkJaWYgKCB0cnVlID09PSAkZGV0YWlsc1sncnVudGltZSddICkgewoJCQkJJHBhcmFtc1sgJ25vLScgLiAka2V5IF0gPSAnJzsKCQkJfQoJCX0KCgkJcmV0dXJuICRwYXJhbXM7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhZGQoICRvcHQgKSB7CgkJaWYgKCAnJyAhPT0gJHRoaXMtPmN1cl93b3JkICkgewoJCQlpZiAoIDAgIT09IHN0cnBvcyggJG9wdCwgJHRoaXMtPmN1cl93b3JkICkgKSB7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgoJCSR0aGlzLT5vcHRzW10gPSAkb3B0OwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByZW5kZXIoKSB7CgkJZm9yZWFjaCAoICR0aGlzLT5vcHRzIGFzICRvcHQgKSB7CgkJCVdQX0NMSTo6bGluZSggJG9wdCApOwoJCX0KCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CgovKioKICogTWFuYWdlIGNhY2hpbmcgd2l0aCB3aGl0ZWxpc3RpbmcKICoKICogQHBhY2thZ2UgV1BfQ0xJCiAqLwpjbGFzcyBXcEh0dHBDYWNoZU1hbmFnZXIgewoKCS8qKgoJICogQHZhciBhcnJheSBtYXAgd2hpdGVsaXN0ZWQgdXJscyB0byBrZXlzIGFuZCB0dGxzCgkgKi8KCXByb3RlY3RlZCAkd2hpdGVsaXN0ID0gW107CgoJLyoqCgkgKiBAdmFyIEZpbGVDYWNoZQoJICovCglwcm90ZWN0ZWQgJGNhY2hlOwoKCS8qKgoJICogQHBhcmFtIEZpbGVDYWNoZSAkY2FjaGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCBGaWxlQ2FjaGUgJGNhY2hlICkgewoJCSR0aGlzLT5jYWNoZSA9ICRjYWNoZTsKCgkJLy8gaG9vayBpbnRvIHdwIGh0dHAgYXBpCgkJYWRkX2ZpbHRlciggJ3ByZV9odHRwX3JlcXVlc3QnLCBbICR0aGlzLCAnZmlsdGVyX3ByZV9odHRwX3JlcXVlc3QnIF0sIDEwLCAzICk7CgkJYWRkX2ZpbHRlciggJ2h0dHBfcmVzcG9uc2UnLCBbICR0aGlzLCAnZmlsdGVyX2h0dHBfcmVzcG9uc2UnIF0sIDEwLCAzICk7Cgl9CgoJLyoqCgkgKiBzaG9ydCBjaXJjdWl0IHdwIGh0dHAgYXBpIHdpdGggY2FjaGVkIGZpbGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbHRlcl9wcmVfaHR0cF9yZXF1ZXN0KCAkcmVzcG9uc2UsICRhcmdzLCAkdXJsICkgewoJCS8vIGNoZWNrIGlmIHdoaXRlbGlzdGVkCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF0gKSApIHsKCQkJcmV0dXJuICRyZXNwb25zZTsKCQl9CgkJLy8gY2hlY2sgaWYgZG93bmxvYWRpbmcKCQlpZiAoICdHRVQnICE9PSAkYXJnc1snbWV0aG9kJ10gfHwgZW1wdHkoICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNoZWNrIGNhY2hlIGFuZCBleHBvcnQgdG8gZGVzaWduYXRlZCBsb2NhdGlvbgoJCSRmaWxlbmFtZSA9ICR0aGlzLT5jYWNoZS0+aGFzKCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ2tleSddLCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ3R0bCddICk7CgkJaWYgKCAkZmlsZW5hbWUgKSB7CgkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnVXNpbmcgY2FjaGVkIGZpbGUgXCclc1wnLi4uJywgJGZpbGVuYW1lICkgKTsKCQkJaWYgKCBjb3B5KCAkZmlsZW5hbWUsICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCQkvLyBzaW11bGF0ZSBzdWNjZXNzZnVsIGRvd25sb2FkIHJlc3BvbnNlCgkJCQlyZXR1cm4gWwoJCQkJCSdyZXNwb25zZScgPT4gWwoJCQkJCQknY29kZScgICAgPT4gMjAwLAoJCQkJCQknbWVzc2FnZScgPT4gJ09LJywKCQkJCQldLAoJCQkJCSdmaWxlbmFtZScgPT4gJGFyZ3NbJ2ZpbGVuYW1lJ10sCgkJCQldOwoJCQl9CgoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnRXJyb3IgY29weWluZyBjYWNoZWQgZmlsZSAlcyB0byAlcycsICRmaWxlbmFtZSwgJHVybCApICk7CgkJfQoJCXJldHVybiAkcmVzcG9uc2U7Cgl9CgoKCS8qKgoJICogY2FjaGUgd3AgaHR0cCBhcGkgZG93bmxvYWRzCgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXNwb25zZQoJICogQHBhcmFtIGFycmF5ICRhcmdzCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbHRlcl9odHRwX3Jlc3BvbnNlKCAkcmVzcG9uc2UsICRhcmdzLCAkdXJsICkgewoJCS8vIGNoZWNrIGlmIHdoaXRlbGlzdGVkCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF0gKSApIHsKCQkJcmV0dXJuICRyZXNwb25zZTsKCQl9CgkJLy8gY2hlY2sgaWYgZG93bmxvYWRpbmcKCQlpZiAoICdHRVQnICE9PSAkYXJnc1snbWV0aG9kJ10gfHwgZW1wdHkoICRhcmdzWydmaWxlbmFtZSddICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNoZWNrIGlmIGRvd25sb2FkIHdhcyBzdWNjZXNzZnVsCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgfHwgMjAwICE9PSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHJlc3BvbnNlICkgKSB7CgkJCXJldHVybiAkcmVzcG9uc2U7CgkJfQoJCS8vIGNhY2hlIGRvd25sb2FkZWQgZmlsZQoJCSR0aGlzLT5jYWNoZS0+aW1wb3J0KCAkdGhpcy0+d2hpdGVsaXN0WyAkdXJsIF1bJ2tleSddLCAkcmVzcG9uc2VbJ2ZpbGVuYW1lJ10gKTsKCQlyZXR1cm4gJHJlc3BvbnNlOwoJfQoKCS8qKgoJICogd2hpdGVsaXN0IGEgcGFja2FnZSB1cmwKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBzdHJpbmcgJGdyb3VwICAgcGFja2FnZSBncm91cCAodGhlbWVzLCBwbHVnaW5zLCAuLi4pCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnICAgIHBhY2thZ2Ugc2x1ZwoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBwYWNrYWdlIHZlcnNpb24KCSAqIEBwYXJhbSBpbnQgICAgJHR0bAoJICovCglwdWJsaWMgZnVuY3Rpb24gd2hpdGVsaXN0X3BhY2thZ2UoICR1cmwsICRncm91cCwgJHNsdWcsICR2ZXJzaW9uLCAkdHRsID0gbnVsbCApIHsKCQkkZXh0ID0gcGF0aGluZm8oIFV0aWxzXHBhcnNlX3VybCggJHVybCwgUEhQX1VSTF9QQVRIICksIFBBVEhJTkZPX0VYVEVOU0lPTiApOwoJCSRrZXkgPSAiJGdyb3VwLyRzbHVnLSR2ZXJzaW9uLiRleHQiOwoJCSR0aGlzLT53aGl0ZWxpc3RfdXJsKCAkdXJsLCAka2V5LCAkdHRsICk7CgkJd3BfdXBkYXRlX3BsdWdpbnMoKTsKCX0KCgkvKioKCSAqIHdoaXRlbGlzdCBhIHVybAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKiBAcGFyYW0gaW50ICAgICR0dGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHdoaXRlbGlzdF91cmwoICR1cmwsICRrZXkgPSBudWxsLCAkdHRsID0gbnVsbCApIHsKCQkka2V5ICAgICAgICAgICAgICAgICAgICAgPSAka2V5ID8gOiAkdXJsOwoJCSR0aGlzLT53aGl0ZWxpc3RbICR1cmwgXSA9IGNvbXBhY3QoICdrZXknLCAndHRsJyApOwoJfQoKCS8qKgoJICogY2hlY2sgaWYgdXJsIGlzIHdoaXRlbGlzdGVkCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX3doaXRlbGlzdGVkKCAkdXJsICkgewoJCXJldHVybiBpc3NldCggJHRoaXMtPndoaXRlbGlzdFsgJHVybCBdICk7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEl0ZXJhdG9yczsKCi8qKgogKiBAc291cmNlIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tLzQwNjAwMDUKICovCmNsYXNzIFRhYmxlIGV4dGVuZHMgUXVlcnkgewoKCS8qKgoJICogQ3JlYXRlcyBhbiBpdGVyYXRvciBvdmVyIGEgZGF0YWJhc2UgdGFibGUuCgkgKgoJICogPGNvZGU+CgkgKiBmb3JlYWNoKCBuZXcgSXRlcmF0b3JzXFRhYmxlKCBhcnJheSggJ3RhYmxlJyA9PiAkd3BkYi0+cG9zdHMsICdmaWVsZHMnID0+IGFycmF5KCAnSUQnLCAncG9zdF9jb250ZW50JyApICkgKSBhcyAkcG9zdCApIHsKCSAqICAgICBjb3VudF93b3Jkc19mb3IoICRwb3N0LT5JRCwgJHBvc3QtPnBvc3RfY29udGVudCApOwoJICogfQoJICogPC9jb2RlPgoJICoKCSAqIDxjb2RlPgoJICogZm9yZWFjaCggbmV3IEl0ZXJhdG9yc1xUYWJsZSggYXJyYXkoICd0YWJsZScgPT4gJHdwZGItPnBvc3RzLCAnd2hlcmUnID0+ICdJRCA9IDggT1IgcG9zdF9zdGF0dXMgPSAicHVibGlzaCInICkgKSBhcyAkcG9zdCApIHsKCSAqICAgICDigKYKCSAqIH0KCSAqIDwvY29kZT4KCSAqCgkgKiA8Y29kZT4KCSAqIGZvcmVhY2goIG5ldyBQb3N0SXRlcmF0b3IoIGFycmF5KCAndGFibGUnID0+ICR3cGRiLT5wb3N0cywgJ3doZXJlJyA9PiBhcnJheSggJ3Bvc3Rfc3RhdHVzJyA9PiAncHVibGlzaCcsICdwb3N0X2RhdGVfZ210IEJFVFdFRU4geCBBTkQgeScgKSApICkgYXMgJHBvc3QgKSB7CgkgKiAgICAg4oCmCgkgKiB9CgkgKiA8L2NvZGU+CgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzIFN1cHBvcnRlZCBhcmd1bWVudHM6CgkgKiAgICAgIHRhYmxlIOKAkyB0aGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgdGFibGUKCSAqICAgICAgZmllbGRzIOKAkyBhbiBhcnJheSBvZiBjb2x1bW5zIHRvIGdldCBmcm9tIHRoZSB0YWJsZSwgJyonIGlzIGEgdmFsaWQgdmFsdWUgYW5kIHRoZSBkZWZhdWx0CgkgKiAgICAgIHdoZXJlIOKAkyBjb25kaXRpb25zIGZvciBmaWx0ZXJpbmcgcm93cy4gU3VwcG9ydHMgdHdvIGZvcm1hdHM6CgkgKiAgICAgICAgICAgICAgPSBzdHJpbmcg4oCTIHRoaXMgd2lsbCBiZSB0aGUgd2hlcmUgY2xhdXNlCgkgKiAgICAgICAgICAgICAgPSBhcnJheSDigJMgZWFjaCBlbGVtZW50IGlzIHRyZWF0ZWQgYXMgYSBjb25kaXRpb24gaWYgaXQncyBwb3NpdGlvbmFsLCBvciBhcyBjb2x1bW4gPT4gdmFsdWUgaWYKCSAqICAgICAgICAgICAgICAgIGl0J3MgYSBrZXkvdmFsdWUgcGFpci4gSW4gdGhlIGxhdHRlciBjYXNlIHRoZSB2YWx1ZSBpcyBhdXRvbWF0aWNhbGx5IHF1b3RlZCBhbmQgZXNjYXBlZAoJICogICAgICBhcHBlbmQgLSBhZGQgYXJiaXRyYXJ5IGV4dHJhIFNRTAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRhcmdzID0gW10gKSB7CgkJJGRlZmF1bHRzID0gWwoJCQknZmllbGRzJyAgICAgPT4gJyonLAoJCQknd2hlcmUnICAgICAgPT4gW10sCgkJCSdhcHBlbmQnICAgICA9PiAnJywKCQkJJ3RhYmxlJyAgICAgID0+IG51bGwsCgkJCSdjaHVua19zaXplJyA9PiA1MDAsCgkJXTsKCQkkdGFibGUgICAgPSAkYXJnc1sndGFibGUnXTsKCQkkYXJncyAgICAgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXJncyApOwoKCQkkZmllbGRzICAgICA9IHNlbGY6OmJ1aWxkX2ZpZWxkcyggJGFyZ3NbJ2ZpZWxkcyddICk7CgkJJGNvbmRpdGlvbnMgPSBzZWxmOjpidWlsZF93aGVyZV9jb25kaXRpb25zKCAkYXJnc1snd2hlcmUnXSApOwoJCSR3aGVyZV9zcWwgID0gJGNvbmRpdGlvbnMgPyAiIFdIRVJFICRjb25kaXRpb25zIiA6ICcnOwoJCSRxdWVyeSAgICAgID0gIlNFTEVDVCAkZmllbGRzIEZST00gYCR0YWJsZWAgJHdoZXJlX3NxbCB7JGFyZ3NbJ2FwcGVuZCddfSI7CgoJCXBhcmVudDo6X19jb25zdHJ1Y3QoICRxdWVyeSwgJGFyZ3NbJ2NodW5rX3NpemUnXSApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGJ1aWxkX2ZpZWxkcyggJGZpZWxkcyApIHsKCQlpZiAoICcqJyA9PT0gJGZpZWxkcyApIHsKCQkJcmV0dXJuICRmaWVsZHM7CgkJfQoKCQlyZXR1cm4gaW1wbG9kZSgKCQkJJywgJywKCQkJYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24gKCAkdiApIHsKCQkJCQlyZXR1cm4gImAkdmAiOwoJCQkJfSwKCQkJCSRmaWVsZHMKCQkJKQoJCSk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gYnVpbGRfd2hlcmVfY29uZGl0aW9ucyggJHdoZXJlICkgewoJCWdsb2JhbCAkd3BkYjsKCQlpZiAoIGlzX2FycmF5KCAkd2hlcmUgKSApIHsKCQkJJGNvbmRpdGlvbnMgPSBbXTsKCQkJZm9yZWFjaCAoICR3aGVyZSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCWlmICggaXNfYXJyYXkoICR2YWx1ZSApICkgewoJCQkJCSRjb25kaXRpb25zW10gPSAka2V5IC4gJyBJTiAoJyAuIGVzY19zcWwoIGltcGxvZGUoICcsJywgJHZhbHVlICkgKSAuICcpJzsKCQkJCX0gZWxzZWlmICggaXNfbnVtZXJpYyggJGtleSApICkgewoJCQkJCSRjb25kaXRpb25zW10gPSAkdmFsdWU7CgkJCQl9IGVsc2UgewoJCQkJCSRjb25kaXRpb25zW10gPSAka2V5IC4gJHdwZGItPnByZXBhcmUoICcgPSAlcycsICR2YWx1ZSApOwoJCQkJfQoJCQl9CgkJCSR3aGVyZSA9IGltcGxvZGUoICcgQU5EICcsICRjb25kaXRpb25zICk7CgkJfQoJCXJldHVybiAkd2hlcmU7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEl0ZXJhdG9yczsKCnVzZSBJdGVyYXRvcjsKCi8qKgogKiBJdGVyYXRlcyBvdmVyIHJlc3VsdHMgb2YgYSBxdWVyeSwgc3BsaXQgaW50byBtYW55IHF1ZXJpZXMgdmlhIExJTUlUIGFuZCBPRkZTRVQKICoKICogQHNvdXJjZSBodHRwczovL2dpc3QuZ2l0aHViLmNvbS80MDYwMDA1CiAqLwpjbGFzcyBRdWVyeSBpbXBsZW1lbnRzIEl0ZXJhdG9yIHsKCglwcml2YXRlICRjaHVua19zaXplOwoJcHJpdmF0ZSAkcXVlcnkgICAgICAgPSAnJzsKCXByaXZhdGUgJGNvdW50X3F1ZXJ5ID0gJyc7CgoJcHJpdmF0ZSAkZ2xvYmFsX2luZGV4ICAgICA9IDA7Cglwcml2YXRlICRpbmRleF9pbl9yZXN1bHRzID0gMDsKCXByaXZhdGUgJHJlc3VsdHMgICAgICAgICAgPSBbXTsKCXByaXZhdGUgJHJvd19jb3VudCAgICAgICAgPSAwOwoJcHJpdmF0ZSAkb2Zmc2V0ICAgICAgICAgICA9IDA7Cglwcml2YXRlICRkYiAgICAgICAgICAgICAgID0gbnVsbDsKCXByaXZhdGUgJGRlcGxldGVkICAgICAgICAgPSBmYWxzZTsKCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgcXVlcnkgaXRlcmF0b3IKCSAqCgkgKiBUaGlzIHdpbGwgbG9vcCBvdmVyIGFsbCB1c2VycywgYnV0IHdpbGwgcmV0cmlldmUgdGhlbSAxMDAgYnkgMTAwOgoJICogPGNvZGU+CgkgKiBmb3JlYWNoKCBuZXcgSXRlcmF0b3JzXFF1ZXJ5KCAnU0VMRUNUICogRlJPTSB1c2VycycsIDEwMCApIGFzICR1c2VyICkgewoJICogICAgIHRpY2tsZSggJHVzZXIgKTsKCSAqIH0KCSAqIDwvY29kZT4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRxdWVyeSBUaGUgcXVlcnkgYXMgYSBzdHJpbmcuIEl0IHNob3VsZG4ndCBpbmNsdWRlIGFueSBMSU1JVCBjbGF1c2VzCgkgKiBAcGFyYW0gaW50ICRjaHVua19zaXplIEhvdyBtYW55IHJvd3MgdG8gcmV0cmlldmUgYXQgb25jZTsgZGVmYXVsdCB2YWx1ZSBpcyA1MDAgKG9wdGlvbmFsKQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRxdWVyeSwgJGNodW5rX3NpemUgPSA1MDAgKSB7CgkJJHRoaXMtPnF1ZXJ5ID0gJHF1ZXJ5OwoKCQkkdGhpcy0+Y291bnRfcXVlcnkgPSBwcmVnX3JlcGxhY2UoICcvXi4qPyBGUk9NIC8nLCAnU0VMRUNUIENPVU5UKCopIEZST00gJywgJHF1ZXJ5LCAxLCAkcmVwbGFjZW1lbnRzICk7CgkJaWYgKCAxICE9PSAkcmVwbGFjZW1lbnRzICkgewoJCQkkdGhpcy0+Y291bnRfcXVlcnkgPSAnJzsKCQl9CgoJCSR0aGlzLT5jaHVua19zaXplID0gJGNodW5rX3NpemU7CgoJCSR0aGlzLT5kYiA9ICRHTE9CQUxTWyd3cGRiJ107Cgl9CgoJLyoqCgkgKiBSZWR1Y2VzIHRoZSBvZmZzZXQgd2hlbiB0aGUgcXVlcnkgcm93IGNvdW50IHNocmlua3MKCSAqCgkgKiBJbiBjYXNlcyB3aGVyZSB0aGUgaXRlcmF0ZWQgcm93cyBhcmUgYmVpbmcgdXBkYXRlZCBzdWNoIHRoYXQgdGhleSB3aWxsIG5vCgkgKiBsb25nZXIgYmUgcmV0dXJuZWQgYnkgdGhlIG9yaWdpbmFsIHF1ZXJ5LCB0aGUgb2Zmc2V0IG11c3QgYmUgcmVkdWNlZCB0bwoJICogaXRlcmF0ZSBvdmVyIGFsbCByZW1haW5pbmcgcm93cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhZGp1c3Rfb2Zmc2V0X2Zvcl9zaHJpbmtpbmdfcmVzdWx0X3NldCgpIHsKCQlpZiAoIGVtcHR5KCAkdGhpcy0+Y291bnRfcXVlcnkgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHJvd19jb3VudCA9ICR0aGlzLT5kYi0+Z2V0X3ZhciggJHRoaXMtPmNvdW50X3F1ZXJ5ICk7CgoJCWlmICggJHJvd19jb3VudCA8ICR0aGlzLT5yb3dfY291bnQgKSB7CgkJCSR0aGlzLT5vZmZzZXQgLT0gJHRoaXMtPnJvd19jb3VudCAtICRyb3dfY291bnQ7CgkJfQoKCQkkdGhpcy0+cm93X2NvdW50ID0gJHJvd19jb3VudDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGxvYWRfaXRlbXNfZnJvbV9kYigpIHsKCQkkdGhpcy0+YWRqdXN0X29mZnNldF9mb3Jfc2hyaW5raW5nX3Jlc3VsdF9zZXQoKTsKCgkJJHF1ZXJ5ICAgICAgICAgPSAkdGhpcy0+cXVlcnkgLiBzcHJpbnRmKCAnIExJTUlUICVkIE9GRlNFVCAlZCcsICR0aGlzLT5jaHVua19zaXplLCAkdGhpcy0+b2Zmc2V0ICk7CgkJJHRoaXMtPnJlc3VsdHMgPSAkdGhpcy0+ZGItPmdldF9yZXN1bHRzKCAkcXVlcnkgKTsKCgkJaWYgKCAhICR0aGlzLT5yZXN1bHRzICkgewoJCQlpZiAoICR0aGlzLT5kYi0+bGFzdF9lcnJvciApIHsKCQkJCXRocm93IG5ldyBFeGNlcHRpb24oICdEYXRhYmFzZSBlcnJvcjogJyAuICR0aGlzLT5kYi0+bGFzdF9lcnJvciApOwoJCQl9CgoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdGhpcy0+b2Zmc2V0ICs9ICR0aGlzLT5jaHVua19zaXplOwoJCXJldHVybiB0cnVlOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkgewoJCXJldHVybiAkdGhpcy0+cmVzdWx0c1sgJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgXTsKCX0KCglwdWJsaWMgZnVuY3Rpb24ga2V5KCkgewoJCXJldHVybiAkdGhpcy0+Z2xvYmFsX2luZGV4OwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBuZXh0KCkgewoJCSR0aGlzLT5pbmRleF9pbl9yZXN1bHRzKys7CgkJJHRoaXMtPmdsb2JhbF9pbmRleCsrOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKSB7CgkJJHRoaXMtPnJlc3VsdHMgICAgICAgICAgPSBbXTsKCQkkdGhpcy0+Z2xvYmFsX2luZGV4ICAgICA9IDA7CgkJJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgPSAwOwoJCSR0aGlzLT5vZmZzZXQgICAgICAgICAgID0gMDsKCQkkdGhpcy0+ZGVwbGV0ZWQgICAgICAgICA9IGZhbHNlOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiB2YWxpZCgpIHsKCQlpZiAoICR0aGlzLT5kZXBsZXRlZCApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+cmVzdWx0c1sgJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMgXSApICkgewoJCQkkaXRlbXNfbG9hZGVkID0gJHRoaXMtPmxvYWRfaXRlbXNfZnJvbV9kYigpOwoKCQkJaWYgKCAhICRpdGVtc19sb2FkZWQgKSB7CgkJCQkkdGhpcy0+cmV3aW5kKCk7CgkJCQkkdGhpcy0+ZGVwbGV0ZWQgPSB0cnVlOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cyA9IDA7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSXRlcmF0b3JzOwoKdXNlIEl0ZXJhdG9ySXRlcmF0b3I7CgovKioKICogQXBwbGllcyBvbmUgb3IgbW9yZSBjYWxsYmFja3MgdG8gYW4gaXRlbSBiZWZvcmUgcmV0dXJuaW5nIGl0LgogKi8KY2xhc3MgVHJhbnNmb3JtIGV4dGVuZHMgSXRlcmF0b3JJdGVyYXRvciB7CgoJcHJpdmF0ZSAkdHJhbnNmb3JtZXJzID0gW107CgoJcHVibGljIGZ1bmN0aW9uIGFkZF90cmFuc2Zvcm0oICRmbiApIHsKCQkkdGhpcy0+dHJhbnNmb3JtZXJzW10gPSAkZm47Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJJHZhbHVlID0gcGFyZW50OjpjdXJyZW50KCk7CgoJCWZvcmVhY2ggKCAkdGhpcy0+dHJhbnNmb3JtZXJzIGFzICRmbiApIHsKCQkJJHZhbHVlID0gY2FsbF91c2VyX2Z1bmMoICRmbiwgJHZhbHVlICk7CgkJfQoKCQlyZXR1cm4gJHZhbHVlOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJdGVyYXRvcnM7Cgp1c2UgQ291bnRhYmxlOwp1c2UgSXRlcmF0b3I7CnVzZSBTcGxGaWxlT2JqZWN0Owp1c2UgV1BfQ0xJOwoKLyoqCiAqIEFsbG93cyBpbmNyZW1lbnRhbGx5IHJlYWRpbmcgYW5kIHBhcnNpbmcgbGluZXMgZnJvbSBhIENTViBmaWxlLgogKi8KY2xhc3MgQ1NWIGltcGxlbWVudHMgQ291bnRhYmxlLCBJdGVyYXRvciB7CgoJY29uc3QgUk9XX1NJWkUgPSA0MDk2OwoKCXByaXZhdGUgJGZpbGVuYW1lOwoJcHJpdmF0ZSAkZmlsZV9wb2ludGVyOwoKCXByaXZhdGUgJGRlbGltaXRlcjsKCXByaXZhdGUgJGNvbHVtbnM7CgoJcHJpdmF0ZSAkY3VycmVudF9pbmRleDsKCXByaXZhdGUgJGN1cnJlbnRfZWxlbWVudDsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRmaWxlbmFtZSwgJGRlbGltaXRlciA9ICcsJyApIHsKCQkkdGhpcy0+ZmlsZW5hbWUgICAgID0gJGZpbGVuYW1lOwoJCSR0aGlzLT5maWxlX3BvaW50ZXIgPSBmb3BlbiggJGZpbGVuYW1lLCAncmInICk7CgkJaWYgKCAhICR0aGlzLT5maWxlX3BvaW50ZXIgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdDb3VsZCBub3Qgb3BlbiBmaWxlOiAlcycsICRmaWxlbmFtZSApICk7CgkJfQoKCQkkdGhpcy0+ZGVsaW1pdGVyID0gJGRlbGltaXRlcjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcmV3aW5kKCkgewoJCXJld2luZCggJHRoaXMtPmZpbGVfcG9pbnRlciApOwoKCQkkdGhpcy0+Y29sdW1ucyA9IGZnZXRjc3YoICR0aGlzLT5maWxlX3BvaW50ZXIsIHNlbGY6OlJPV19TSVpFLCAkdGhpcy0+ZGVsaW1pdGVyICk7CgoJCSR0aGlzLT5jdXJyZW50X2luZGV4ID0gLTE7CgkJJHRoaXMtPm5leHQoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpIHsKCQlyZXR1cm4gJHRoaXMtPmN1cnJlbnRfZWxlbWVudDsKCX0KCglwdWJsaWMgZnVuY3Rpb24ga2V5KCkgewoJCXJldHVybiAkdGhpcy0+Y3VycmVudF9pbmRleDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gbmV4dCgpIHsKCQkkdGhpcy0+Y3VycmVudF9lbGVtZW50ID0gZmFsc2U7CgoJCXdoaWxlICggdHJ1ZSApIHsKCQkJJHN0ciA9IGZnZXRzKCAkdGhpcy0+ZmlsZV9wb2ludGVyICk7CgoJCQlpZiAoIGZhbHNlID09PSAkc3RyICkgewoJCQkJYnJlYWs7CgkJCX0KCgkJCSRyb3cgPSBzdHJfZ2V0Y3N2KCAkc3RyLCAkdGhpcy0+ZGVsaW1pdGVyICk7CgoJCQkkZWxlbWVudCA9IFtdOwoJCQlmb3JlYWNoICggJHRoaXMtPmNvbHVtbnMgYXMgJGkgPT4gJGtleSApIHsKCQkJCWlmICggaXNzZXQoICRyb3dbICRpIF0gKSApIHsKCQkJCQkkZWxlbWVudFsgJGtleSBdID0gJHJvd1sgJGkgXTsKCQkJCX0KCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkZWxlbWVudCApICkgewoJCQkJJHRoaXMtPmN1cnJlbnRfZWxlbWVudCA9ICRlbGVtZW50OwoJCQkJJHRoaXMtPmN1cnJlbnRfaW5kZXgrKzsKCgkJCQlicmVhazsKCQkJfQoJCX0KCX0KCglwdWJsaWMgZnVuY3Rpb24gY291bnQoKSB7CgkJJGZpbGUgPSBuZXcgU3BsRmlsZU9iamVjdCggJHRoaXMtPmZpbGVuYW1lLCAncicgKTsKCQkkZmlsZS0+c2VlayggUEhQX0lOVF9NQVggKTsKCQlyZXR1cm4gJGZpbGUtPmtleSgpICsgMTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKSB7CgkJcmV0dXJuIGlzX2FycmF5KCAkdGhpcy0+Y3VycmVudF9lbGVtZW50ICk7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEl0ZXJhdG9yczsKCnVzZSBSdW50aW1lRXhjZXB0aW9uOwoKY2xhc3MgRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7fQoKPD9waHAKCi8vIENhbiBiZSB1c2VkIGJ5IHBsdWdpbnMvdGhlbWVzIHRvIGNoZWNrIGlmIFdQLUNMSSBpcyBydW5uaW5nIG9yIG5vdC4KZGVmaW5lKCAnV1BfQ0xJJywgdHJ1ZSApOwpkZWZpbmUoICdXUF9DTElfVkVSU0lPTicsIHRyaW0oIGZpbGVfZ2V0X2NvbnRlbnRzKCBXUF9DTElfUk9PVCAuICcvVkVSU0lPTicgKSApICk7CmRlZmluZSggJ1dQX0NMSV9TVEFSVF9NSUNST1RJTUUnLCBtaWNyb3RpbWUoIHRydWUgKSApOwoKaWYgKCBmaWxlX2V4aXN0cyggV1BfQ0xJX1JPT1QgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnICkgKSB7CglkZWZpbmUoICdXUF9DTElfVkVORE9SX0RJUicsIFdQX0NMSV9ST09UIC4gJy92ZW5kb3InICk7Cn0gZWxzZWlmICggZmlsZV9leGlzdHMoIGRpcm5hbWUoIGRpcm5hbWUoIFdQX0NMSV9ST09UICkgKSAuICcvYXV0b2xvYWQucGhwJyApICkgewoJZGVmaW5lKCAnV1BfQ0xJX1ZFTkRPUl9ESVInLCBkaXJuYW1lKCBkaXJuYW1lKCBXUF9DTElfUk9PVCApICkgKTsKfSBlbHNlaWYgKCBmaWxlX2V4aXN0cyggZGlybmFtZSggV1BfQ0xJX1JPT1QgKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCcgKSApIHsKCWRlZmluZSggJ1dQX0NMSV9WRU5ET1JfRElSJywgZGlybmFtZSggV1BfQ0xJX1JPT1QgKSAuICcvdmVuZG9yJyApOwp9IGVsc2UgewoJZGVmaW5lKCAnV1BfQ0xJX1ZFTkRPUl9ESVInLCBXUF9DTElfUk9PVCAuICcvdmVuZG9yJyApOwp9CgpyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9jb21wYXQucGhwJzsKCi8vIFNldCBjb21tb24gaGVhZGVycywgdG8gcHJldmVudCB3YXJuaW5ncyBmcm9tIHBsdWdpbnMuCiRfU0VSVkVSWydTRVJWRVJfUFJPVE9DT0wnXSA9ICdIVFRQLzEuMCc7CiRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSA9ICcnOwokX1NFUlZFUlsnUkVRVUVTVF9NRVRIT0QnXSAgPSAnR0VUJzsKJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10gICAgID0gJzEyNy4wLjAuMSc7CgpyZXF1aXJlX29uY2UgV1BfQ0xJX1JPT1QgLiAnL3BocC9ib290c3RyYXAucGhwJzsKV1BfQ0xJXGJvb3RzdHJhcCgpOwo8P3BocAoKLy8gVXRpbGl0aWVzIHRoYXQgZG8gTk9UIGRlcGVuZCBvbiBXb3JkUHJlc3MgY29kZS4KCm5hbWVzcGFjZSBXUF9DTElcVXRpbHM7Cgp1c2UgQXJyYXlJdGVyYXRvcjsKdXNlIGNsaTsKdXNlIGNsaVxwcm9ncmVzc1xCYXI7CnVzZSBjbGlcU2hlbGw7CnVzZSBDbG9zdXJlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBhcmF0b3I7CnVzZSBDb21wb3NlclxTZW12ZXJcU2VtdmVyOwp1c2UgRXhjZXB0aW9uOwp1c2UgTXVzdGFjaGVfRW5naW5lOwp1c2UgUmVmbGVjdGlvbkZ1bmN0aW9uOwp1c2UgUmVxdWVzdHM7CnVzZSBSZXF1ZXN0c19FeGNlcHRpb247CnVzZSBSdW50aW1lRXhjZXB0aW9uOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXEV4aXRFeGNlcHRpb247CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXEluZmxlY3RvcjsKdXNlIFdQX0NMSVxJdGVyYXRvcnNcVHJhbnNmb3JtOwp1c2UgV1BfQ0xJXE5vT3A7CnVzZSBXUF9DTElcUHJvY2VzczsKCmNvbnN0IFBIQVJfU1RSRUFNX1BSRUZJWCA9ICdwaGFyOi8vJzsKCi8qKgogKiBSZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybiB0byBtYXRjaCBfX0ZJTEVfXyBhbmQgX19ESVJfXyBjb25zdGFudHMuCiAqCiAqIFdlIHRyeSB0byBiZSBzbWFydCBhbmQgb25seSByZXBsYWNlIHRoZSBjb25zdGFudHMgd2hlbiB0aGV5IGFyZSBub3Qgd2l0aGluIHF1b3Rlcy4KICogUmVndWxhciBleHByZXNzaW9ucyBiZWluZyBzdGF0ZWxlc3MsIHRoaXMgaXMgcHJvYmFibHkgbm90IDEwMCUgY29ycmVjdCBmb3IgZWRnZSBjYXNlcy4KICoKICogQHNlZSBodHRwczovL3JlZ2V4MTAxLmNvbS9yLzloWHA1ZC8xMQogKiBAc2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNzE0OTkvOTMzMDY1CiAqCiAqIEB2YXIgc3RyaW5nCiAqLwpjb25zdCBGSUxFX0RJUl9QQVRURVJOID0gJyUoPz4jLio/JCl8KD8+Ly8uKj8kKXwoPz4vXCouKj9cKi8pfCg/PlwnKD86KD89KFxcXFw/KSlcMS4pKj9cJyl8KD8+Iig/Oig/PShcXFxcPykpXDIuKSo/Iil8KD88ZmlsZT5cYl9fRklMRV9fXGIpfCg/PGRpcj5cYl9fRElSX19cYiklbXMnOwoKZnVuY3Rpb24gaW5zaWRlX3BoYXIoKSB7CglyZXR1cm4gMCA9PT0gc3RycG9zKCBXUF9DTElfUk9PVCwgUEhBUl9TVFJFQU1fUFJFRklYICk7Cn0KCi8vIEZpbGVzIHRoYXQgbmVlZCB0byBiZSByZWFkIGJ5IGV4dGVybmFsIHByb2dyYW1zIGhhdmUgdG8gYmUgZXh0cmFjdGVkIGZyb20gdGhlIFBoYXIgYXJjaGl2ZS4KZnVuY3Rpb24gZXh0cmFjdF9mcm9tX3BoYXIoICRwYXRoICkgewoJaWYgKCAhIGluc2lkZV9waGFyKCkgKSB7CgkJcmV0dXJuICRwYXRoOwoJfQoKCSRmbmFtZSA9IGJhc2VuYW1lKCAkcGF0aCApOwoKCSR0bXBfcGF0aCA9IGdldF90ZW1wX2RpcigpIC4gdW5pcWlkKCAnd3AtY2xpLWV4dHJhY3QtZnJvbS1waGFyLScsIHRydWUgKSAuICItJGZuYW1lIjsKCgljb3B5KCAkcGF0aCwgJHRtcF9wYXRoICk7CgoJcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oCgkJZnVuY3Rpb24oKSB1c2UgKCAkdG1wX3BhdGggKSB7CgkJCWlmICggZmlsZV9leGlzdHMoICR0bXBfcGF0aCApICkgewoJCQkJdW5saW5rKCAkdG1wX3BhdGggKTsKCQkJfQoJCX0KCSk7CgoJcmV0dXJuICR0bXBfcGF0aDsKfQoKZnVuY3Rpb24gbG9hZF9kZXBlbmRlbmNpZXMoKSB7CglpZiAoIGluc2lkZV9waGFyKCkgKSB7CgkJaWYgKCBmaWxlX2V4aXN0cyggV1BfQ0xJX1JPT1QgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnICkgKSB7CgkJCXJlcXVpcmUgV1BfQ0xJX1JPT1QgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwoJCX0gZWxzZWlmICggZmlsZV9leGlzdHMoIGRpcm5hbWUoIGRpcm5hbWUoIFdQX0NMSV9ST09UICkgKSAuICcvYXV0b2xvYWQucGhwJyApICkgewoJCQlyZXF1aXJlIGRpcm5hbWUoIGRpcm5hbWUoIFdQX0NMSV9ST09UICkgKSAuICcvYXV0b2xvYWQucGhwJzsKCQl9CgkJcmV0dXJuOwoJfQoKCSRoYXNfYXV0b2xvYWQgPSBmYWxzZTsKCglmb3JlYWNoICggZ2V0X3ZlbmRvcl9wYXRocygpIGFzICR2ZW5kb3JfcGF0aCApIHsKCQlpZiAoIGZpbGVfZXhpc3RzKCAkdmVuZG9yX3BhdGggLiAnL2F1dG9sb2FkLnBocCcgKSApIHsKCQkJcmVxdWlyZSAkdmVuZG9yX3BhdGggLiAnL2F1dG9sb2FkLnBocCc7CgkJCSRoYXNfYXV0b2xvYWQgPSB0cnVlOwoJCQlicmVhazsKCQl9Cgl9CgoJaWYgKCAhICRoYXNfYXV0b2xvYWQgKSB7CgkJZndyaXRlKCBTVERFUlIsICJJbnRlcm5hbCBlcnJvcjogQ2FuJ3QgZmluZCBDb21wb3NlciBhdXRvbG9hZGVyLlxuVHJ5IHJ1bm5pbmc6IGNvbXBvc2VyIGluc3RhbGxcbiIgKTsKCQlleGl0KCAzICk7Cgl9Cn0KCmZ1bmN0aW9uIGdldF92ZW5kb3JfcGF0aHMoKSB7CgkkdmVuZG9yX3BhdGhzICAgICAgICA9IFsKCQlXUF9DTElfUk9PVCAuICcvLi4vLi4vLi4vdmVuZG9yJywgIC8vIFBhcnQgb2YgYSBsYXJnZXIgcHJvamVjdCAvIGluc3RhbGxlZCB2aWEgQ29tcG9zZXIgKHByZWZlcnJlZCkuCgkJV1BfQ0xJX1JPT1QgLiAnL3ZlbmRvcicsICAgICAgICAgICAvLyBUb3AtbGV2ZWwgcHJvamVjdCAvIGluc3RhbGxlZCBhcyBHaXQgY2xvbmUuCgldOwoJJG1heWJlX2NvbXBvc2VyX2pzb24gPSBXUF9DTElfUk9PVCAuICcvLi4vLi4vLi4vY29tcG9zZXIuanNvbic7CglpZiAoIGZpbGVfZXhpc3RzKCAkbWF5YmVfY29tcG9zZXJfanNvbiApICYmIGlzX3JlYWRhYmxlKCAkbWF5YmVfY29tcG9zZXJfanNvbiApICkgewoJCSRjb21wb3NlciA9IGpzb25fZGVjb2RlKCBmaWxlX2dldF9jb250ZW50cyggJG1heWJlX2NvbXBvc2VyX2pzb24gKSApOwoJCWlmICggISBlbXB0eSggJGNvbXBvc2VyLT5jb25maWcgKSAmJiAhIGVtcHR5KCAkY29tcG9zZXItPmNvbmZpZy0+eyd2ZW5kb3ItZGlyJ30gKSApIHsKCQkJYXJyYXlfdW5zaGlmdCggJHZlbmRvcl9wYXRocywgV1BfQ0xJX1JPT1QgLiAnLy4uLy4uLy4uLycgLiAkY29tcG9zZXItPmNvbmZpZy0+eyd2ZW5kb3ItZGlyJ30gKTsKCQl9Cgl9CglyZXR1cm4gJHZlbmRvcl9wYXRoczsKfQoKLy8gVXNpbmcgcmVxdWlyZSgpIGRpcmVjdGx5IGluc2lkZSBhIGNsYXNzIGdyYW50cyBhY2Nlc3MgdG8gcHJpdmF0ZSBtZXRob2RzIHRvIHRoZSBsb2FkZWQgY29kZS4KZnVuY3Rpb24gbG9hZF9maWxlKCAkcGF0aCApIHsKCXJlcXVpcmVfb25jZSAkcGF0aDsKfQoKZnVuY3Rpb24gbG9hZF9jb21tYW5kKCAkbmFtZSApIHsKCSRwYXRoID0gV1BfQ0xJX1JPT1QgLiAiL3BocC9jb21tYW5kcy8kbmFtZS5waHAiOwoKCWlmICggaXNfcmVhZGFibGUoICRwYXRoICkgKSB7CgkJaW5jbHVkZV9vbmNlICRwYXRoOwoJfQp9CgovKioKICogTGlrZSBhcnJheV9tYXAoKSwgZXhjZXB0IGl0IHJldHVybnMgYSBuZXcgaXRlcmF0b3IsIGluc3RlYWQgb2YgYSBtb2RpZmllZCBhcnJheS4KICoKICogRXhhbXBsZToKICoKICogICAgICRhcnIgPSBhcnJheSgnRm9vdGJhbGwnLCAnU29ja2VyJyk7CiAqCiAqICAgICAkaXQgPSBpdGVyYXRvcl9tYXAoJGFyciwgJ3N0cnRvbG93ZXInLCBmdW5jdGlvbigkdmFsKSB7CiAqICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnZm9vJywgJ2JhcicsICR2YWwpOwogKiAgICAgfSk7CiAqCiAqICAgICBmb3JlYWNoICggJGl0IGFzICR2YWwgKSB7CiAqICAgICAgIHZhcl9kdW1wKCR2YWwpOwogKiAgICAgfQogKgogKiBAcGFyYW0gYXJyYXl8b2JqZWN0ICRpdCBFaXRoZXIgYSBwbGFpbiBhcnJheSBvciBhbm90aGVyIGl0ZXJhdG9yLgogKiBAcGFyYW0gY2FsbGJhY2sgICAgICRmbiBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgdG8gYW4gZWxlbWVudC4KICogQHJldHVybiBvYmplY3QgQW4gaXRlcmF0b3IgdGhhdCBhcHBsaWVzIHRoZSBnaXZlbiBjYWxsYmFjayhzKS4KICovCmZ1bmN0aW9uIGl0ZXJhdG9yX21hcCggJGl0LCAkZm4gKSB7CglpZiAoIGlzX2FycmF5KCAkaXQgKSApIHsKCQkkaXQgPSBuZXcgQXJyYXlJdGVyYXRvciggJGl0ICk7Cgl9CgoJaWYgKCAhIG1ldGhvZF9leGlzdHMoICRpdCwgJ2FkZF90cmFuc2Zvcm0nICkgKSB7CgkJJGl0ID0gbmV3IFRyYW5zZm9ybSggJGl0ICk7Cgl9CgoJZm9yZWFjaCAoIGFycmF5X3NsaWNlKCBmdW5jX2dldF9hcmdzKCksIDEgKSBhcyAkZm4gKSB7CgkJJGl0LT5hZGRfdHJhbnNmb3JtKCAkZm4gKTsKCX0KCglyZXR1cm4gJGl0Owp9CgovKioKICogU2VhcmNoIGZvciBmaWxlIGJ5IHdhbGtpbmcgdXAgdGhlIGRpcmVjdG9yeSB0cmVlIHVudGlsIHRoZSBmaXJzdCBmaWxlIGlzIGZvdW5kIG9yIHVudGlsICRzdG9wX2NoZWNrKCRkaXIpIHJldHVybnMgdHJ1ZS4KICoKICogQHBhcmFtIHN0cmluZ3xhcnJheSAkZmlsZXMgICAgICBUaGUgZmlsZXMgKG9yIGZpbGUpIHRvIHNlYXJjaCBmb3IuCiAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgJGRpciAgICAgICAgVGhlIGRpcmVjdG9yeSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbTsgZGVmYXVsdHMgdG8gQ1dELgogKiBAcGFyYW0gY2FsbGFibGUgICAgICRzdG9wX2NoZWNrIEZ1bmN0aW9uIHdoaWNoIGlzIHBhc3NlZCB0aGUgY3VycmVudCBkaXIgZWFjaCB0aW1lIGEgZGlyZWN0b3J5IGxldmVsIGlzIHRyYXZlcnNlZC4KICogQHJldHVybiBudWxsfHN0cmluZyBOdWxsIGlmIHRoZSBmaWxlIHdhcyBub3QgZm91bmQuCiAqLwpmdW5jdGlvbiBmaW5kX2ZpbGVfdXB3YXJkKCAkZmlsZXMsICRkaXIgPSBudWxsLCAkc3RvcF9jaGVjayA9IG51bGwgKSB7CgkkZmlsZXMgPSAoYXJyYXkpICRmaWxlczsKCWlmICggaXNfbnVsbCggJGRpciApICkgewoJCSRkaXIgPSBnZXRjd2QoKTsKCX0KCXdoaWxlICggaXNfcmVhZGFibGUoICRkaXIgKSApIHsKCQkvLyBTdG9wIHdhbGtpbmcgdXAgd2hlbiB0aGUgc3VwcGxpZWQgY2FsbGFibGUgcmV0dXJucyB0cnVlIGJlaW5nIHBhc3NlZCB0aGUgJGRpcgoJCWlmICggaXNfY2FsbGFibGUoICRzdG9wX2NoZWNrICkgJiYgY2FsbF91c2VyX2Z1bmMoICRzdG9wX2NoZWNrLCAkZGlyICkgKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJJHBhdGggPSAkZGlyIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRmaWxlOwoJCQlpZiAoIGZpbGVfZXhpc3RzKCAkcGF0aCApICkgewoJCQkJcmV0dXJuICRwYXRoOwoJCQl9CgkJfQoKCQkkcGFyZW50X2RpciA9IGRpcm5hbWUoICRkaXIgKTsKCQlpZiAoIGVtcHR5KCAkcGFyZW50X2RpciApIHx8ICRwYXJlbnRfZGlyID09PSAkZGlyICkgewoJCQlicmVhazsKCQl9CgkJJGRpciA9ICRwYXJlbnRfZGlyOwoJfQoJcmV0dXJuIG51bGw7Cn0KCmZ1bmN0aW9uIGlzX3BhdGhfYWJzb2x1dGUoICRwYXRoICkgewoJLy8gV2luZG93cwoJaWYgKCBpc3NldCggJHBhdGhbMV0gKSAmJiAnOicgPT09ICRwYXRoWzFdICkgewoJCXJldHVybiB0cnVlOwoJfQoKCXJldHVybiAnLycgPT09ICRwYXRoWzBdOwp9CgovKioKICogQ29tcG9zZXMgcG9zaXRpb25hbCBhcmd1bWVudHMgaW50byBhIGNvbW1hbmQgc3RyaW5nLgogKgogKiBAcGFyYW0gYXJyYXkgJGFyZ3MgUG9zaXRpb25hbCBhcmd1bWVudHMgdG8gY29tcG9zZS4KICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGFyZ3NfdG9fc3RyKCAkYXJncyApIHsKCXJldHVybiAnICcgLiBpbXBsb2RlKCAnICcsIGFycmF5X21hcCggJ2VzY2FwZXNoZWxsYXJnJywgJGFyZ3MgKSApOwp9CgovKioKICogQ29tcG9zZXMgYXNzb2NpYXRpdmUgYXJndW1lbnRzIGludG8gYSBjb21tYW5kIHN0cmluZy4KICoKICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3VtZW50cyB0byBjb21wb3NlLgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gYXNzb2NfYXJnc190b19zdHIoICRhc3NvY19hcmdzICkgewoJJHN0ciA9ICcnOwoKCWZvcmVhY2ggKCAkYXNzb2NfYXJncyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQlpZiAoIHRydWUgPT09ICR2YWx1ZSApIHsKCQkJJHN0ciAuPSAiIC0tJGtleSI7CgkJfSBlbHNlaWYgKCBpc19hcnJheSggJHZhbHVlICkgKSB7CgkJCWZvcmVhY2ggKCAkdmFsdWUgYXMgJHYgKSB7CgkJCQkkc3RyIC49IGFzc29jX2FyZ3NfdG9fc3RyKAoJCQkJCVsKCQkJCQkJJGtleSA9PiAkdiwKCQkJCQldCgkJCQkpOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHN0ciAuPSAiIC0tJGtleT0iIC4gZXNjYXBlc2hlbGxhcmcoICR2YWx1ZSApOwoJCX0KCX0KCglyZXR1cm4gJHN0cjsKfQoKLyoqCiAqIEdpdmVuIGEgdGVtcGxhdGUgc3RyaW5nIGFuZCBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIGFyZ3VtZW50cywKICogcmV0dXJucyB0aGUgZmluYWwgY29tbWFuZCwgd2l0aCB0aGUgcGFyYW1ldGVycyBlc2NhcGVkLgogKi8KZnVuY3Rpb24gZXNjX2NtZCggJGNtZCApIHsKCWlmICggZnVuY19udW1fYXJncygpIDwgMiApIHsKCQl0cmlnZ2VyX2Vycm9yKCAnZXNjX2NtZCgpIHJlcXVpcmVzIGF0IGxlYXN0IHR3byBhcmd1bWVudHMuJywgRV9VU0VSX1dBUk5JTkcgKTsKCX0KCgkkYXJncyA9IGZ1bmNfZ2V0X2FyZ3MoKTsKCgkkY21kID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJcmV0dXJuIHZzcHJpbnRmKCAkY21kLCBhcnJheV9tYXAoICdlc2NhcGVzaGVsbGFyZycsICRhcmdzICkgKTsKfQoKLyoqCiAqIEdldHMgcGF0aCB0byBXb3JkUHJlc3MgY29uZmlndXJhdGlvbi4KICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGxvY2F0ZV93cF9jb25maWcoKSB7CglzdGF0aWMgJHBhdGg7CgoJaWYgKCBudWxsID09PSAkcGF0aCApIHsKCQkkcGF0aCA9IGZhbHNlOwoKCQlpZiAoIGdldGVudiggJ1dQX0NPTkZJR19QQVRIJyApICYmIGZpbGVfZXhpc3RzKCBnZXRlbnYoICdXUF9DT05GSUdfUEFUSCcgKSApICkgewoJCQkkcGF0aCA9IGdldGVudiggJ1dQX0NPTkZJR19QQVRIJyApOwoJCX0gZWxzZWlmICggZmlsZV9leGlzdHMoIEFCU1BBVEggLiAnd3AtY29uZmlnLnBocCcgKSApIHsKCQkJJHBhdGggPSBBQlNQQVRIIC4gJ3dwLWNvbmZpZy5waHAnOwoJCX0gZWxzZWlmICggZmlsZV9leGlzdHMoIGRpcm5hbWUoIEFCU1BBVEggKSAuICcvd3AtY29uZmlnLnBocCcgKSAmJiAhIGZpbGVfZXhpc3RzKCBkaXJuYW1lKCBBQlNQQVRIICkgLiAnL3dwLXNldHRpbmdzLnBocCcgKSApIHsKCQkJJHBhdGggPSBkaXJuYW1lKCBBQlNQQVRIICkgLiAnL3dwLWNvbmZpZy5waHAnOwoJCX0KCgkJaWYgKCAkcGF0aCApIHsKCQkJJHBhdGggPSByZWFscGF0aCggJHBhdGggKTsKCQl9Cgl9CgoJcmV0dXJuICRwYXRoOwp9CgpmdW5jdGlvbiB3cF92ZXJzaW9uX2NvbXBhcmUoICRzaW5jZSwgJG9wZXJhdG9yICkgewoJJHdwX3ZlcnNpb24gPSBzdHJfcmVwbGFjZSggJy1zcmMnLCAnJywgJEdMT0JBTFNbJ3dwX3ZlcnNpb24nXSApOwoJJHNpbmNlICAgICAgPSBzdHJfcmVwbGFjZSggJy1zcmMnLCAnJywgJHNpbmNlICk7CglyZXR1cm4gdmVyc2lvbl9jb21wYXJlKCAkd3BfdmVyc2lvbiwgJHNpbmNlLCAkb3BlcmF0b3IgKTsKfQoKLyoqCiAqIFJlbmRlciBhIGNvbGxlY3Rpb24gb2YgaXRlbXMgYXMgYW4gQVNDSUkgdGFibGUsIEpTT04sIENTViwgWUFNTCwgbGlzdCBvZiBpZHMsIG9yIGNvdW50LgogKgogKiBHaXZlbiBhIGNvbGxlY3Rpb24gb2YgaXRlbXMgd2l0aCBhIGNvbnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmU6CiAqCiAqIGBgYAogKiAkaXRlbXMgPSBhcnJheSgKICogICAgIGFycmF5KAogKiAgICAgICAgICdrZXknICAgPT4gJ2ZvbycsCiAqICAgICAgICAgJ3ZhbHVlJyAgPT4gJ2JhcicsCiAqICAgICApCiAqICk7CiAqIGBgYAogKgogKiBSZW5kZXIgYCRpdGVtc2AgYXMgYW4gQVNDSUkgdGFibGU6CiAqCiAqIGBgYAogKiBXUF9DTElcVXRpbHNcZm9ybWF0X2l0ZW1zKCAndGFibGUnLCAkaXRlbXMsIGFycmF5KCAna2V5JywgJ3ZhbHVlJyApICk7CiAqCiAqICMgKy0tLS0tKy0tLS0tLS0rCiAqICMgfCBrZXkgfCB2YWx1ZSB8CiAqICMgKy0tLS0tKy0tLS0tLS0rCiAqICMgfCBmb28gfCBiYXIgICB8CiAqICMgKy0tLS0tKy0tLS0tLS0rCiAqIGBgYAogKgogKiBPciByZW5kZXIgYCRpdGVtc2AgYXMgWUFNTDoKICoKICogYGBgCiAqIFdQX0NMSVxVdGlsc1xmb3JtYXRfaXRlbXMoICd5YW1sJywgJGl0ZW1zLCBhcnJheSggJ2tleScsICd2YWx1ZScgKSApOwogKgogKiAjIC0tLQogKiAjIC0KICogIyAgIGtleTogZm9vCiAqICMgICB2YWx1ZTogYmFyCiAqIGBgYAogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgT3V0cHV0CiAqCiAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGZvcm1hdCBGb3JtYXQgdG8gdXNlOiAndGFibGUnLCAnanNvbicsICdjc3YnLCAneWFtbCcsICdpZHMnLCAnY291bnQnLgogKiBAcGFyYW0gYXJyYXkgICAgICAgICRpdGVtcyAgQW4gYXJyYXkgb2YgaXRlbXMgdG8gb3V0cHV0LgogKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRmaWVsZHMgTmFtZWQgZmllbGRzIGZvciBlYWNoIGl0ZW0gb2YgZGF0YS4gQ2FuIGJlIGFycmF5IG9yIGNvbW1hLXNlcGFyYXRlZCBsaXN0LgogKi8KZnVuY3Rpb24gZm9ybWF0X2l0ZW1zKCAkZm9ybWF0LCAkaXRlbXMsICRmaWVsZHMgKSB7CgkkYXNzb2NfYXJncyA9IGNvbXBhY3QoICdmb3JtYXQnLCAnZmllbGRzJyApOwoJJGZvcm1hdHRlciAgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGl0ZW1zICk7Cn0KCi8qKgogKiBXcml0ZSBkYXRhIGFzIENTViB0byBhIGdpdmVuIGZpbGUuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqCiAqIEBwYXJhbSByZXNvdXJjZSAkZmQgICAgICBGaWxlIGRlc2NyaXB0b3IuCiAqIEBwYXJhbSBhcnJheSAgICAkcm93cyAgICBBcnJheSBvZiByb3dzIHRvIG91dHB1dC4KICogQHBhcmFtIGFycmF5ICAgICRoZWFkZXJzIExpc3Qgb2YgQ1NWIGNvbHVtbnMgKG9wdGlvbmFsKS4KICovCmZ1bmN0aW9uIHdyaXRlX2NzdiggJGZkLCAkcm93cywgJGhlYWRlcnMgPSBbXSApIHsKCWlmICggISBlbXB0eSggJGhlYWRlcnMgKSApIHsKCQlmcHV0Y3N2KCAkZmQsICRoZWFkZXJzICk7Cgl9CgoJZm9yZWFjaCAoICRyb3dzIGFzICRyb3cgKSB7CgkJaWYgKCAhIGVtcHR5KCAkaGVhZGVycyApICkgewoJCQkkcm93ID0gcGlja19maWVsZHMoICRyb3csICRoZWFkZXJzICk7CgkJfQoKCQlmcHV0Y3N2KCAkZmQsIGFycmF5X3ZhbHVlcyggJHJvdyApICk7Cgl9Cn0KCi8qKgogKiBQaWNrIGZpZWxkcyBmcm9tIGFuIGFzc29jaWF0aXZlIGFycmF5IG9yIG9iamVjdC4KICoKICogQHBhcmFtICBhcnJheXxvYmplY3QgJGl0ZW0gICAgQXNzb2NpYXRpdmUgYXJyYXkgb3Igb2JqZWN0IHRvIHBpY2sgZmllbGRzIGZyb20uCiAqIEBwYXJhbSAgYXJyYXkgICAgICAgICRmaWVsZHMgIExpc3Qgb2YgZmllbGRzIHRvIHBpY2suCiAqIEByZXR1cm4gYXJyYXkKICovCmZ1bmN0aW9uIHBpY2tfZmllbGRzKCAkaXRlbSwgJGZpZWxkcyApIHsKCSR2YWx1ZXMgPSBbXTsKCglpZiAoIGlzX29iamVjdCggJGl0ZW0gKSApIHsKCQlmb3JlYWNoICggJGZpZWxkcyBhcyAkZmllbGQgKSB7CgkJCSR2YWx1ZXNbICRmaWVsZCBdID0gaXNzZXQoICRpdGVtLT4kZmllbGQgKSA/ICRpdGVtLT4kZmllbGQgOiBudWxsOwoJCX0KCX0gZWxzZSB7CgkJZm9yZWFjaCAoICRmaWVsZHMgYXMgJGZpZWxkICkgewoJCQkkdmFsdWVzWyAkZmllbGQgXSA9IGlzc2V0KCAkaXRlbVsgJGZpZWxkIF0gKSA/ICRpdGVtWyAkZmllbGQgXSA6IG51bGw7CgkJfQoJfQoKCXJldHVybiAkdmFsdWVzOwp9CgovKioKICogTGF1bmNoIHN5c3RlbSdzICRFRElUT1IgZm9yIHRoZSB1c2VyIHRvIGVkaXQgc29tZSB0ZXh0LgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgSW5wdXQKICoKICogQHBhcmFtIHN0cmluZyAkaW5wdXQgU29tZSBmb3JtIG9mIHRleHQgdG8gZWRpdCAoZS5nLiBwb3N0IGNvbnRlbnQpLgogKiBAcGFyYW0gc3RyaW5nICR0aXRsZSBUaXRsZSB0byBkaXNwbGF5IGluIHRoZSBlZGl0b3IuCiAqIEBwYXJhbSBzdHJpbmcgJGV4dCAgIEV4dGVuc2lvbiB0byB1c2Ugd2l0aCB0aGUgdGVtcCBmaWxlLgogKiBAcmV0dXJuIHN0cmluZ3xib29sICBFZGl0ZWQgdGV4dCwgaWYgZmlsZSBpcyBzYXZlZCBmcm9tIGVkaXRvcjsgZmFsc2UsIGlmIG5vIGNoYW5nZSB0byBmaWxlLgogKi8KZnVuY3Rpb24gbGF1bmNoX2VkaXRvcl9mb3JfaW5wdXQoICRpbnB1dCwgJHRpdGxlID0gJ1dQLUNMSScsICRleHQgPSAndG1wJyApIHsKCgljaGVja19wcm9jX2F2YWlsYWJsZSggJ2xhdW5jaF9lZGl0b3JfZm9yX2lucHV0JyApOwoKCSR0bXBkaXIgPSBnZXRfdGVtcF9kaXIoKTsKCglkbyB7CgkJJHRtcGZpbGUgID0gYmFzZW5hbWUoICR0aXRsZSApOwoJCSR0bXBmaWxlICA9IHByZWdfcmVwbGFjZSggJ3xcLlteLl0qJHwnLCAnJywgJHRtcGZpbGUgKTsKCQkkdG1wZmlsZSAuPSAnLScgLiBzdWJzdHIoIG1kNSggbXRfcmFuZCgpICksIDAsIDYgKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5yYW5kX210X3JhbmQgLS0gbm8gY3J5cHRvIGFuZCBXUCBub3QgbG9hZGVkLgoJCSR0bXBmaWxlICA9ICR0bXBkaXIgLiAkdG1wZmlsZSAuICcuJyAuICRleHQ7CgkJJGZwICAgICAgID0gZm9wZW4oICR0bXBmaWxlLCAneGInICk7CgkJaWYgKCAhICRmcCAmJiBpc193cml0YWJsZSggJHRtcGRpciApICYmIGZpbGVfZXhpc3RzKCAkdG1wZmlsZSApICkgewoJCQkkdG1wZmlsZSA9ICcnOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCAkZnAgKSB7CgkJCWZjbG9zZSggJGZwICk7CgkJfQoJfSB3aGlsZSAoICEgJHRtcGZpbGUgKTsKCglpZiAoICEgJHRtcGZpbGUgKSB7CgkJV1BfQ0xJOjplcnJvciggJ0Vycm9yIGNyZWF0aW5nIHRlbXBvcmFyeSBmaWxlLicgKTsKCX0KCglmaWxlX3B1dF9jb250ZW50cyggJHRtcGZpbGUsICRpbnB1dCApOwoKCSRlZGl0b3IgPSBnZXRlbnYoICdFRElUT1InICk7CglpZiAoICEgJGVkaXRvciApIHsKCQkkZWRpdG9yID0gaXNfd2luZG93cygpID8gJ25vdGVwYWQnIDogJ3ZpJzsKCX0KCgkkZGVzY3JpcHRvcnNwZWMgPSBbIFNURElOLCBTVERPVVQsIFNUREVSUiBdOwoJJHByb2Nlc3MgICAgICAgID0gcHJvY19vcGVuX2NvbXBhdCggIiRlZGl0b3IgIiAuIGVzY2FwZXNoZWxsYXJnKCAkdG1wZmlsZSApLCAkZGVzY3JpcHRvcnNwZWMsICRwaXBlcyApOwoJJHIgICAgICAgICAgICAgID0gcHJvY19jbG9zZSggJHByb2Nlc3MgKTsKCWlmICggJHIgKSB7CgkJZXhpdCggJHIgKTsKCX0KCgkkb3V0cHV0ID0gZmlsZV9nZXRfY29udGVudHMoICR0bXBmaWxlICk7CgoJdW5saW5rKCAkdG1wZmlsZSApOwoKCWlmICggJG91dHB1dCA9PT0gJGlucHV0ICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglyZXR1cm4gJG91dHB1dDsKfQoKLyoqCiAqIEBwYXJhbSBzdHJpbmcgJHJhd19ob3N0IE15U1FMIGhvc3Qgc3RyaW5nLCBhcyBkZWZpbmVkIGluIHdwLWNvbmZpZy5waHAuCiAqCiAqIEByZXR1cm4gYXJyYXkKICovCmZ1bmN0aW9uIG15c3FsX2hvc3RfdG9fY2xpX2FyZ3MoICRyYXdfaG9zdCApIHsKCSRhc3NvY19hcmdzID0gW107CgoJLyoqCgkgKiBJZiB0aGUgaG9zdCBzdHJpbmcgYmVnaW5zIHdpdGggJ3A6JyBmb3IgYSBwZXJzaXN0ZW50IGRiIGNvbm5lY3Rpb24sCgkgKiByZXBsYWNlICdwOicgd2l0aCBub3RoaW5nLgoJICovCglpZiAoIHN1YnN0ciggJHJhd19ob3N0LCAwLCAyICkgPT09ICdwOicgKSB7CgkJJHJhd19ob3N0ID0gc3Vic3RyX3JlcGxhY2UoICRyYXdfaG9zdCwgJycsIDAsIDIgKTsKCX0KCgkkaG9zdF9wYXJ0cyA9IGV4cGxvZGUoICc6JywgJHJhd19ob3N0ICk7CglpZiAoIGNvdW50KCAkaG9zdF9wYXJ0cyApID09PSAyICkgewoJCWxpc3QoICRhc3NvY19hcmdzWydob3N0J10sICRleHRyYSApID0gJGhvc3RfcGFydHM7CgkJJGV4dHJhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSB0cmltKCAkZXh0cmEgKTsKCQlpZiAoIGlzX251bWVyaWMoICRleHRyYSApICkgewoJCQkkYXNzb2NfYXJnc1sncG9ydCddICAgICA9IChpbnQpICRleHRyYTsKCQkJJGFzc29jX2FyZ3NbJ3Byb3RvY29sJ10gPSAndGNwJzsKCQl9IGVsc2VpZiAoICcnICE9PSAkZXh0cmEgKSB7CgkJCSRhc3NvY19hcmdzWydzb2NrZXQnXSA9ICRleHRyYTsKCQl9Cgl9IGVsc2UgewoJCSRhc3NvY19hcmdzWydob3N0J10gPSAkcmF3X2hvc3Q7Cgl9CgoJcmV0dXJuICRhc3NvY19hcmdzOwp9CgovKioKICogUnVuIGEgTXlTUUwgY29tbWFuZCBhbmQgb3B0aW9uYWxseSByZXR1cm4gdGhlIG91dHB1dC4KICoKICogQHNpbmNlIHYyLjUuMCBEZXByZWNhdGVkICRkZXNjcmlwdG9ycyBhcmd1bWVudC4KICoKICogQHBhcmFtIHN0cmluZyAkY21kICAgICAgICAgICBDb21tYW5kIHRvIHJ1bi4KICogQHBhcmFtIGFycmF5ICAkYXNzb2NfYXJncyAgICBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gdXNlLgogKiBAcGFyYW0gbWl4ZWQgICRfICAgICAgICAgICAgIERlcHJlY2F0ZWQuIEZvcm1lciAkZGVzY3JpcHRvcnMgYXJndW1lbnQuCiAqIEBwYXJhbSBib29sICAgJHNlbmRfdG9fc2hlbGwgT3B0aW9uYWwuIFdoZXRoZXIgdG8gc2VuZCBTVERPVVQgYW5kIFNUREVSUgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZWx5IHRvIHRoZSBzaGVsbC4gRGVmYXVsdHMgdG8gdHJ1ZS4KICogQHBhcmFtIGJvb2wgICAkaW50ZXJhY3RpdmUgICBPcHRpb25hbC4gV2hldGhlciBNeVNRTCBpcyBtZWFudCB0byBiZQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGVkIGFzIGFuIGludGVyYWN0aXZlIHByb2Nlc3MuIERlZmF1bHRzCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZmFsc2UuCiAqCiAqIEByZXR1cm4gYXJyYXkgewogKiAgICAgQXNzb2NpYXRpdmUgYXJyYXkgY29udGFpbmluZyBTVERPVVQgYW5kIFNUREVSUiBvdXRwdXQuCiAqCiAqICAgICBAdHlwZSBzdHJpbmcgJHN0ZG91dCAgICBPdXRwdXQgdGhhdCB3YXMgc2VudCB0byBTVERPVVQuCiAqICAgICBAdHlwZSBzdHJpbmcgJHN0ZGVyciAgICBPdXRwdXQgdGhhdCB3YXMgc2VudCB0byBTVERFUlIuCiAqICAgICBAdHlwZSBpbnQgICAgJGV4aXRfY29kZSBFeGl0IGNvZGUgb2YgdGhlIHByb2Nlc3MuCiAqIH0KICovCmZ1bmN0aW9uIHJ1bl9teXNxbF9jb21tYW5kKCAkY21kLCAkYXNzb2NfYXJncywgJF8gPSBudWxsLCAkc2VuZF90b19zaGVsbCA9IHRydWUsICRpbnRlcmFjdGl2ZSA9IGZhbHNlICkgewoJY2hlY2tfcHJvY19hdmFpbGFibGUoICdydW5fbXlzcWxfY29tbWFuZCcgKTsKCgkkZGVzY3JpcHRvcnMgPSAkaW50ZXJhY3RpdmUgPwoJCVsKCQkJMCA9PiBTVERJTiwKCQkJMSA9PiBTVERPVVQsCgkJCTIgPT4gU1RERVJSLAoJCV0gOgoJCVsKCQkJMCA9PiBTVERJTiwKCQkJMSA9PiBbICdwaXBlJywgJ3cnIF0sCgkJCTIgPT4gWyAncGlwZScsICd3JyBdLAoJCV07CgoJJHN0ZG91dCA9ICcnOwoJJHN0ZGVyciA9ICcnOwoJJHBpcGVzICA9IFtdOwoKCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydob3N0J10gKSApIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlJlc3RyaWN0ZWRGdW5jdGlvbnMubXlzcWxfbXlzcWxfaG9zdF90b19jbGlfYXJncyAtLSBNaXNpZGVudGlmaWVkIGFzIFBIUCBuYXRpdmUgTXlTUUwgZnVuY3Rpb24uCgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSggJGFzc29jX2FyZ3MsIG15c3FsX2hvc3RfdG9fY2xpX2FyZ3MoICRhc3NvY19hcmdzWydob3N0J10gKSApOwoJfQoKCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydwYXNzJ10gKSApIHsKCQkkb2xkX3Bhc3N3b3JkID0gZ2V0ZW52KCAnTVlTUUxfUFdEJyApOwoJCXB1dGVudiggJ01ZU1FMX1BXRD0nIC4gJGFzc29jX2FyZ3NbJ3Bhc3MnXSApOwoJCXVuc2V0KCAkYXNzb2NfYXJnc1sncGFzcyddICk7Cgl9CgoJJGZpbmFsX2NtZCA9IGZvcmNlX2Vudl9vbl9uaXhfc3lzdGVtcyggJGNtZCApIC4gYXNzb2NfYXJnc190b19zdHIoICRhc3NvY19hcmdzICk7CgoJV1BfQ0xJOjpkZWJ1ZyggJ0ZpbmFsIE15U1FMIGNvbW1hbmQ6ICcgLiAkZmluYWxfY21kLCAnZGInICk7CgkkcHJvY2VzcyA9IHByb2Nfb3Blbl9jb21wYXQoICRmaW5hbF9jbWQsICRkZXNjcmlwdG9ycywgJHBpcGVzICk7CgoJaWYgKCBpc3NldCggJG9sZF9wYXNzd29yZCApICkgewoJCXB1dGVudiggJ01ZU1FMX1BXRD0nIC4gJG9sZF9wYXNzd29yZCApOwoJfQoKCWlmICggISAkcHJvY2VzcyApIHsKCQlleGl0KCAxICk7Cgl9CgoJaWYgKCAhICRpbnRlcmFjdGl2ZSAmJiBpc19yZXNvdXJjZSggJHByb2Nlc3MgKSApIHsKCQkkc3Rkb3V0ID0gc3RyZWFtX2dldF9jb250ZW50cyggJHBpcGVzWzFdICk7CgkJJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoICRwaXBlc1syXSApOwoKCQlmY2xvc2UoICRwaXBlc1sxXSApOwoJCWZjbG9zZSggJHBpcGVzWzJdICk7Cgl9CgoJJGV4aXRfY29kZSA9IHByb2NfY2xvc2UoICRwcm9jZXNzICk7CgoJaWYgKCAkaW50ZXJhY3RpdmUgJiYgJGV4aXRfY29kZSApIHsKCQlleGl0KCAkZXhpdF9jb2RlICk7Cgl9CgoJaWYgKCAkc2VuZF90b19zaGVsbCApIHsKCQlmd3JpdGUoIFNURE9VVCwgJHN0ZG91dCApOwoJCWZ3cml0ZSggU1RERVJSLCAkc3RkZXJyICk7CgoJCWlmICggJGV4aXRfY29kZSApIHsKCQkJZXhpdCggJGV4aXRfY29kZSApOwoJCX0KCX0KCglyZXR1cm4gWwoJCSRzdGRvdXQsCgkJJHN0ZGVyciwKCQkkZXhpdF9jb2RlLAoJXTsKfQoKLyoqCiAqIFJlbmRlciBQSFAgb3Igb3RoZXIgdHlwZXMgb2YgZmlsZXMgdXNpbmcgTXVzdGFjaGUgdGVtcGxhdGVzLgogKgogKiBJTVBPUlRBTlQ6IEF1dG9tYXRpYyBIVE1MIGVzY2FwaW5nIGlzIGRpc2FibGVkIQogKi8KZnVuY3Rpb24gbXVzdGFjaGVfcmVuZGVyKCAkdGVtcGxhdGVfbmFtZSwgJGRhdGEgPSBbXSApIHsKCWlmICggISBmaWxlX2V4aXN0cyggJHRlbXBsYXRlX25hbWUgKSApIHsKCQkkdGVtcGxhdGVfbmFtZSA9IFdQX0NMSV9ST09UIC4gIi90ZW1wbGF0ZXMvJHRlbXBsYXRlX25hbWUiOwoJfQoKCSR0ZW1wbGF0ZSA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkdGVtcGxhdGVfbmFtZSApOwoKCSRtID0gbmV3IE11c3RhY2hlX0VuZ2luZSgKCQlbCgkJCSdlc2NhcGUnID0+IGZ1bmN0aW9uICggJHZhbCApIHsKCQkJCXJldHVybiAkdmFsOyB9LAoJCV0KCSk7CgoJcmV0dXJuICRtLT5yZW5kZXIoICR0ZW1wbGF0ZSwgJGRhdGEgKTsKfQoKLyoqCiAqIENyZWF0ZSBhIHByb2dyZXNzIGJhciB0byBkaXNwbGF5IHBlcmNlbnQgY29tcGxldGlvbiBvZiBhIGdpdmVuIG9wZXJhdGlvbi4KICoKICogUHJvZ3Jlc3MgYmFyIGlzIHdyaXR0ZW4gdG8gU1RET1VULCBhbmQgZGlzYWJsZWQgd2hlbiBjb21tYW5kIGlzIHBpcGVkLiBQcm9ncmVzcwogKiBhZHZhbmNlcyB3aXRoIGAkcHJvZ3Jlc3MtPnRpY2soKWAsIGFuZCBjb21wbGV0ZXMgd2l0aCBgJHByb2dyZXNzLT5maW5pc2goKWAuCiAqIFByb2Nlc3MgYmFyIGFsc28gaW5kaWNhdGVzIGVsYXBzZWQgdGltZSBhbmQgZXhwZWN0ZWQgdG90YWwgdGltZS4KICoKICogYGBgCiAqICMgYHdwIHVzZXIgZ2VuZXJhdGVgIHRpY2tzIHByb2dyZXNzIGJhciBlYWNoIHRpbWUgYSBuZXcgdXNlciBpcyBjcmVhdGVkLgogKiAjCiAqICMgJCB3cCB1c2VyIGdlbmVyYXRlIC0tY291bnQ9NTAwCiAqICMgR2VuZXJhdGluZyB1c2VycyAgMjIgJSBbPT09PT09PT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gMDowNSAvIDA6MjMKICoKICogJHByb2dyZXNzID0gXFdQX0NMSVxVdGlsc1xtYWtlX3Byb2dyZXNzX2JhciggJ0dlbmVyYXRpbmcgdXNlcnMnLCAkY291bnQgKTsKICogZm9yICggJGkgPSAwOyAkaSA8ICRjb3VudDsgJGkrKyApIHsKICogICAgIC8vIHVzZXMgd3BfaW5zZXJ0X3VzZXIoKSB0byBpbnNlcnQgdGhlIHVzZXIKICogICAgICRwcm9ncmVzcy0+dGljaygpOwogKiB9CiAqICRwcm9ncmVzcy0+ZmluaXNoKCk7CiAqIGBgYAogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgT3V0cHV0CiAqCiAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlICBUZXh0IHRvIGRpc3BsYXkgYmVmb3JlIHRoZSBwcm9ncmVzcyBiYXIuCiAqIEBwYXJhbSBpbnRlZ2VyICRjb3VudCAgICBUb3RhbCBudW1iZXIgb2YgdGlja3MgdG8gYmUgcGVyZm9ybWVkLgogKiBAcGFyYW0gaW50ICAgICAkaW50ZXJ2YWwgT3B0aW9uYWwuIFRoZSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiB1cGRhdGVzLiBEZWZhdWx0IDEwMC4KICogQHJldHVybiBjbGlccHJvZ3Jlc3NcQmFyfE5vT3AKICovCmZ1bmN0aW9uIG1ha2VfcHJvZ3Jlc3NfYmFyKCAkbWVzc2FnZSwgJGNvdW50LCAkaW50ZXJ2YWwgPSAxMDAgKSB7CglpZiAoIFNoZWxsOjppc1BpcGVkKCkgKSB7CgkJcmV0dXJuIG5ldyBOb09wKCk7Cgl9CgoJcmV0dXJuIG5ldyBCYXIoICRtZXNzYWdlLCAkY291bnQsICRpbnRlcnZhbCApOwp9CgovKioKICogSGVscGVyIGZ1bmN0aW9uIHRvIHVzZSB3cF9wYXJzZV91cmwgd2hlbiBhdmFpbGFibGUgb3IgZmFsbCBiYWNrIHRvIFBIUCdzCiAqIHBhcnNlX3VybCBpZiBub3QuCiAqCiAqIEFkZGl0aW9uYWxseSwgdGhpcyBhZGRzICdodHRwOi8vJyB0byB0aGUgVVJMIGlmIG5vIHNjaGVtZSB3YXMgZm91bmQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHVybCAgICAgICAgICAgICBUaGUgVVJMIHRvIHBhcnNlLgogKiBAcGFyYW0gaW50ICAgICRjb21wb25lbnQgICAgICAgT3B0aW9uYWwuIFRoZSBzcGVjaWZpYyBjb21wb25lbnQgdG8gcmV0cmlldmUuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVc2Ugb25lIG9mIHRoZSBQSFAgcHJlZGVmaW5lZCBjb25zdGFudHMgdG8KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZnkgd2hpY2ggb25lLiBEZWZhdWx0cyB0byAtMSAoPSByZXR1cm4KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbCBwYXJ0cyBhcyBhbiBhcnJheSkuCiAqIEBwYXJhbSBib29sICAgJGF1dG9fYWRkX3NjaGVtZSBPcHRpb25hbC4gQXV0b21hdGljYWxseSBhZGQgYW4gaHR0cDovLyBzY2hlbWUgaWYKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbmUgd2FzIGZvdW5kLiBEZWZhdWx0cyB0byB0cnVlLgogKiBAcmV0dXJuIG1peGVkIEZhbHNlIG9uIHBhcnNlIGZhaWx1cmU7IEFycmF5IG9mIFVSTCBjb21wb25lbnRzIG9uIHN1Y2Nlc3M7CiAqICAgICAgICAgICAgICAgV2hlbiBhIHNwZWNpZmljIGNvbXBvbmVudCBoYXMgYmVlbiByZXF1ZXN0ZWQ6IG51bGwgaWYgdGhlCiAqICAgICAgICAgICAgICAgY29tcG9uZW50IGRvZXNuJ3QgZXhpc3QgaW4gdGhlIGdpdmVuIFVSTDsgYSBzdHJpbmcgb3IgLSBpbiB0aGUKICogICAgICAgICAgICAgICBjYXNlIG9mIFBIUF9VUkxfUE9SVCAtIGludGVnZXIgd2hlbiBpdCBkb2VzLiBTZWUgcGFyc2VfdXJsKCkncwogKiAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXMuCiAqLwpmdW5jdGlvbiBwYXJzZV91cmwoICR1cmwsICRjb21wb25lbnQgPSAtIDEsICRhdXRvX2FkZF9zY2hlbWUgPSB0cnVlICkgewoJaWYgKAoJCWZ1bmN0aW9uX2V4aXN0cyggJ3dwX3BhcnNlX3VybCcgKQoJCSYmICgKCQkJLTEgPT09ICRjb21wb25lbnQKCQkJfHwgd3BfdmVyc2lvbl9jb21wYXJlKCAnNC43JywgJz49JyApCgkJKQoJKSB7CgkJJHVybF9wYXJ0cyA9IHdwX3BhcnNlX3VybCggJHVybCwgJGNvbXBvbmVudCApOwoJfSBlbHNlIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwgLS0gRmFsbGJhY2suCgkJJHVybF9wYXJ0cyA9IFxwYXJzZV91cmwoICR1cmwsICRjb21wb25lbnQgKTsKCX0KCgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwgLS0gT3duIHZlcnNpb24gYmFzZWQgb24gV1Agb25lLgoJaWYgKCAkYXV0b19hZGRfc2NoZW1lICYmICEgcGFyc2VfdXJsKCAkdXJsLCBQSFBfVVJMX1NDSEVNRSwgZmFsc2UgKSApIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwgLS0gT3duIHZlcnNpb24gYmFzZWQgb24gV1Agb25lLgoJCSR1cmxfcGFydHMgPSBwYXJzZV91cmwoICdodHRwOi8vJyAuICR1cmwsICRjb21wb25lbnQsIGZhbHNlICk7Cgl9CgoJcmV0dXJuICR1cmxfcGFydHM7Cn0KCi8qKgogKiBDaGVjayBpZiB3ZSdyZSBydW5uaW5nIGluIGEgV2luZG93cyBlbnZpcm9ubWVudCAoY21kLmV4ZSkuCiAqCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gaXNfd2luZG93cygpIHsKCSR0ZXN0X2lzX3dpbmRvd3MgPSBnZXRlbnYoICdXUF9DTElfVEVTVF9JU19XSU5ET1dTJyApOwoJcmV0dXJuIGZhbHNlICE9PSAkdGVzdF9pc193aW5kb3dzID8gKGJvb2wpICR0ZXN0X2lzX3dpbmRvd3MgOiBzdHJ0b3VwcGVyKCBzdWJzdHIoIFBIUF9PUywgMCwgMyApICkgPT09ICdXSU4nOwp9CgovKioKICogUmVwbGFjZSBtYWdpYyBjb25zdGFudHMgaW4gc29tZSBQSFAgc291cmNlIGNvZGUuCiAqCiAqIFJlcGxhY2VzIHRoZSBfX0ZJTEVfXyBhbmQgX19ESVJfXyBtYWdpYyBjb25zdGFudHMgd2l0aCB0aGUgdmFsdWVzIHRoZXkgYXJlCiAqIHN1cHBvc2VkIHRvIHJlcHJlc2VudCBhdCBydW50aW1lLgogKgogKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UgVGhlIFBIUCBjb2RlIHRvIG1hbmlwdWxhdGUuCiAqIEBwYXJhbSBzdHJpbmcgJHBhdGggVGhlIHBhdGggdG8gdXNlIGluc3RlYWQgb2YgdGhlIG1hZ2ljIGNvbnN0YW50cy4KICogQHJldHVybiBzdHJpbmcgQWRhcHRlZCBQSFAgY29kZS4KICovCmZ1bmN0aW9uIHJlcGxhY2VfcGF0aF9jb25zdHMoICRzb3VyY2UsICRwYXRoICkgewoJLy8gU29sdmUgaXNzdWUgd2l0aCBXaW5kb3dzIGFsbG93aW5nIHNpbmdsZSBxdW90ZXMgaW4gYWNjb3VudCBuYW1lcy4KCSRmaWxlID0gYWRkc2xhc2hlcyggJHBhdGggKTsKCglpZiAoIGZpbGVfZXhpc3RzKCAkZmlsZSApICkgewoJCSRmaWxlID0gcmVhbHBhdGgoICRmaWxlICk7Cgl9CgoJJGRpciA9IGRpcm5hbWUoICRmaWxlICk7CgoJLy8gUmVwbGFjZSBfX0ZJTEVfXyBhbmQgX19ESVJfXyBjb25zdGFudHMgd2l0aCB2YWx1ZSBvZiAkZmlsZSBvciAkZGlyLgoJcmV0dXJuIHByZWdfcmVwbGFjZV9jYWxsYmFjaygKCQlGSUxFX0RJUl9QQVRURVJOLAoJCXN0YXRpYyBmdW5jdGlvbiAoICRtYXRjaGVzICkgdXNlICggJGZpbGUsICRkaXIgKSB7CgkJCWlmICggISBlbXB0eSggJG1hdGNoZXNbJ2ZpbGUnXSApICkgewoJCQkJcmV0dXJuICIneyRmaWxlfSciOwoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRtYXRjaGVzWydkaXInXSApICkgewoJCQkJcmV0dXJuICIneyRkaXJ9JyI7CgkJCX0KCgkJCXJldHVybiAkbWF0Y2hlc1swXTsKCQl9LAoJCSRzb3VyY2UKCSk7Cn0KCi8qKgogKiBNYWtlIGEgSFRUUCByZXF1ZXN0IHRvIGEgcmVtb3RlIFVSTC4KICoKICogV3JhcHMgdGhlIFJlcXVlc3RzIEhUVFAgbGlicmFyeSB0byBlbnN1cmUgZXZlcnkgcmVxdWVzdCBpbmNsdWRlcyBhIGNlcnQuCiAqCiAqIGBgYAogKiAjIGB3cCBjb3JlIGRvd25sb2FkYCB2ZXJpZmllcyB0aGUgaGFzaCBmb3IgYSBkb3dubG9hZGVkIFdvcmRQcmVzcyBhcmNoaXZlCiAqCiAqICRtZDVfcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkZG93bmxvYWRfdXJsIC4gJy5tZDUnICk7CiAqIGlmICggMjAgIT0gc3Vic3RyKCAkbWQ1X3Jlc3BvbnNlLT5zdGF0dXNfY29kZSwgMCwgMiApICkgewogKiAgICAgIFdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBhY2Nlc3MgbWQ1IGhhc2ggZm9yIHJlbGVhc2UgKEhUVFAgY29kZSB7JHJlc3BvbnNlLT5zdGF0dXNfY29kZX0pIiApOwogKiB9CiAqIGBgYAogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcGFyYW0gc3RyaW5nICRtZXRob2QgIEhUVFAgbWV0aG9kIChHRVQsIFBPU1QsIERFTEVURSwgZXRjLikuCiAqIEBwYXJhbSBzdHJpbmcgJHVybCAgICAgVVJMIHRvIG1ha2UgdGhlIEhUVFAgcmVxdWVzdCB0by4KICogQHBhcmFtIGFycmF5ICAkaGVhZGVycyBBZGQgc3BlY2lmaWMgaGVhZGVycyB0byB0aGUgcmVxdWVzdC4KICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyB7CiAqICAgICBPcHRpb25hbC4gQW4gYXNzb2NpYXRpdmUgYXJyYXkgb2YgYWRkaXRpb25hbCByZXF1ZXN0IG9wdGlvbnMuCiAqCiAqICAgICBAdHlwZSBib29sICRoYWx0X29uX2Vycm9yIFdoZXRoZXIgb3Igbm90IGNvbW1hbmQgZXhlY3V0aW9uIHNob3VsZCBiZSBoYWx0ZWQgb24gZXJyb3IuIERlZmF1bHQ6IHRydWUKICogICAgIEB0eXBlIGJvb2x8c3RyaW5nICR2ZXJpZnkgQSBib29sZWFuIHRvIHVzZSBlbmFibGUvZGlzYWJsZSBTU0wgdmVyaWZpY2F0aW9uCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIHN0cmluZyBhYnNvbHV0ZSBwYXRoIHRvIENBIGNlcnQgdG8gdXNlLgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byBkZXRlY3RlZCBDQSBjZXJ0IGJ1bmRsZWQgd2l0aCB0aGUgUmVxdWVzdHMgbGlicmFyeS4KICogICAgIEB0eXBlIGJvb2wgJGluc2VjdXJlICAgICAgV2hldGhlciB0byByZXRyeSBhdXRvbWF0aWNhbGx5IHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbi4KICogfQogKiBAcmV0dXJuIG9iamVjdAogKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHJlcXVlc3QgZmFpbGVkLgogKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIHJlcXVlc3QgZmFpbGVkIGFuZCAkaGFsdF9vbl9lcnJvciBpcyB0cnVlLgogKi8KZnVuY3Rpb24gaHR0cF9yZXF1ZXN0KCAkbWV0aG9kLCAkdXJsLCAkZGF0YSA9IG51bGwsICRoZWFkZXJzID0gW10sICRvcHRpb25zID0gW10gKSB7CgoJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1JlcXVlc3RzX0hvb2tzJyApICkgewoJCS8vIEF1dG9sb2FkZXIgZm9yIHRoZSBSZXF1ZXN0cyBsaWJyYXJ5IGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIHlldC4KCQlSZXF1ZXN0czo6cmVnaXN0ZXJfYXV0b2xvYWRlcigpOwoJfQoKCSRpbnNlY3VyZSAgICAgID0gaXNzZXQoICRvcHRpb25zWydpbnNlY3VyZSddICkgJiYgKGJvb2wpICRvcHRpb25zWydpbnNlY3VyZSddOwoJJGhhbHRfb25fZXJyb3IgPSAhIGlzc2V0KCAkb3B0aW9uc1snaGFsdF9vbl9lcnJvciddICkgfHwgKGJvb2wpICRvcHRpb25zWydoYWx0X29uX2Vycm9yJ107Cgl1bnNldCggJG9wdGlvbnNbJ2hhbHRfb25fZXJyb3InXSApOwoKCWlmICggISBpc3NldCggJG9wdGlvbnNbJ3ZlcmlmeSddICkgKSB7CgkJLy8gJ2N1cmwuY2FpbmZvJyBlbmZvcmNlcyB0aGUgQ0EgZmlsZSB0byB1c2UsIG90aGVyd2lzZSBmYWxsYmFjayB0byBzeXN0ZW0td2lkZSBkZWZhdWx0cyB0aGVuIHVzZSB0aGUgZW1iZWRkZWQgQ0EgZmlsZS4KCQkkb3B0aW9uc1sndmVyaWZ5J10gPSAhIGVtcHR5KCBpbmlfZ2V0KCAnY3VybC5jYWluZm8nICkgKSA/IGluaV9nZXQoICdjdXJsLmNhaW5mbycgKSA6IHRydWU7Cgl9CgoJdHJ5IHsKCQl0cnkgewoJCQlyZXR1cm4gUmVxdWVzdHM6OnJlcXVlc3QoICR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG1ldGhvZCwgJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggUmVxdWVzdHNfRXhjZXB0aW9uICRleCApIHsKCQkJaWYgKCB0cnVlICE9PSAkb3B0aW9uc1sndmVyaWZ5J10gfHwgJ2N1cmxlcnJvcicgIT09ICRleC0+Z2V0VHlwZSgpIHx8IGN1cmxfZXJybm8oICRleC0+Z2V0RGF0YSgpICkgIT09IENVUkxFX1NTTF9DQUNFUlQgKSB7CgkJCQl0aHJvdyAkZXg7CgkJCX0KCgkJCSRvcHRpb25zWyd2ZXJpZnknXSA9IGdldF9kZWZhdWx0X2NhY2VydCggJGhhbHRfb25fZXJyb3IgKTsKCgkJCXJldHVybiBSZXF1ZXN0czo6cmVxdWVzdCggJHVybCwgJGhlYWRlcnMsICRkYXRhLCAkbWV0aG9kLCAkb3B0aW9ucyApOwoJCX0KCX0gY2F0Y2ggKCBSZXF1ZXN0c19FeGNlcHRpb24gJGV4ICkgewoJCS8vIENVUkxFX1NTTF9DQUNFUlRfQkFERklMRSBvbmx5IGRlZmluZWQgZm9yIFBIUCA+PSA3LgoJCWlmICgKCQkJISAkaW5zZWN1cmUKCQkJfHwKCQkJJ2N1cmxlcnJvcicgIT09ICRleC0+Z2V0VHlwZSgpCgkJCXx8CgkJCSEgaW5fYXJyYXkoIGN1cmxfZXJybm8oICRleC0+Z2V0RGF0YSgpICksIFsgQ1VSTEVfU1NMX0NPTk5FQ1RfRVJST1IsIENVUkxFX1NTTF9DRVJUUFJPQkxFTSwgNzcgLypDVVJMRV9TU0xfQ0FDRVJUX0JBREZJTEUqLyBdLCB0cnVlICkKCQkpIHsKCQkJJGVycm9yX21zZyA9IHNwcmludGYoICJGYWlsZWQgdG8gZ2V0IHVybCAnJXMnOiAlcy4iLCAkdXJsLCAkZXgtPmdldE1lc3NhZ2UoKSApOwoJCQlpZiAoICRoYWx0X29uX2Vycm9yICkgewoJCQkJV1BfQ0xJOjplcnJvciggJGVycm9yX21zZyApOwoJCQl9CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCAkZXJyb3JfbXNnLCBudWxsLCAkZXggKTsKCQl9CgoJCSR3YXJuaW5nID0gc3ByaW50ZigKCQkJIlJlLXRyeWluZyB3aXRob3V0IHZlcmlmeSBhZnRlciBmYWlsaW5nIHRvIGdldCB2ZXJpZmllZCB1cmwgJyVzJyAlcy4iLAoJCQkkdXJsLAoJCQkkZXgtPmdldE1lc3NhZ2UoKQoJCSk7CgkJV1BfQ0xJOjp3YXJuaW5nKCAkd2FybmluZyApOwoKCQkvLyBEaXNhYmxlIGNlcnRpZmljYXRlIHZhbGlkYXRpb24gZm9yIHRoZSBuZXh0IHRyeS4KCQkkb3B0aW9uc1sndmVyaWZ5J10gPSBmYWxzZTsKCgkJdHJ5IHsKCQkJcmV0dXJuIFJlcXVlc3RzOjpyZXF1ZXN0KCAkdXJsLCAkaGVhZGVycywgJGRhdGEsICRtZXRob2QsICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIFJlcXVlc3RzX0V4Y2VwdGlvbiAkZXggKSB7CgkJCSRlcnJvcl9tc2cgPSBzcHJpbnRmKCAiRmFpbGVkIHRvIGdldCBub24tdmVyaWZpZWQgdXJsICclcycgJXMuIiwgJHVybCwgJGV4LT5nZXRNZXNzYWdlKCkgKTsKCQkJaWYgKCAkaGFsdF9vbl9lcnJvciApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRlcnJvcl9tc2cgKTsKCQkJfQoJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbiggJGVycm9yX21zZywgbnVsbCwgJGV4ICk7CgkJfQoJfQp9CgovKioKICogR2V0cyB0aGUgZnVsbCBwYXRoIHRvIHRoZSBkZWZhdWx0IENBIGNlcnQuCiAqCiAqIEBwYXJhbSBib29sICRoYWx0X29uX2Vycm9yIFdoZXRoZXIgb3Igbm90IGNvbW1hbmQgZXhlY3V0aW9uIHNob3VsZCBiZSBoYWx0ZWQgb24gZXJyb3IuIERlZmF1bHQ6IGZhbHNlCiAqIEByZXR1cm4gc3RyaW5nIEFic29sdXRlIHBhdGggdG8gdGhlIGRlZmF1bHQgQ0EgY2VydC4KICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIElmIHVuYWJsZSB0byBsb2NhdGUgdGhlIGNlcnQuCiAqIEB0aHJvd3MgRXhpdEV4Y2VwdGlvbiBJZiB1bmFibGUgdG8gbG9jYXRlIHRoZSBjZXJ0IGFuZCAkaGFsdF9vbl9lcnJvciBpcyB0cnVlLgogKi8KZnVuY3Rpb24gZ2V0X2RlZmF1bHRfY2FjZXJ0KCAkaGFsdF9vbl9lcnJvciA9IGZhbHNlICkgewoJJGNlcnRfcGF0aCA9ICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVHJhbnNwb3J0L2NhY2VydC5wZW0nOwoJJGVycm9yX21zZyA9ICdDYW5ub3QgZmluZCBTU0wgY2VydGlmaWNhdGUuJzsKCglpZiAoIGluc2lkZV9waGFyKCkgKSB7CgkJLy8gY1VSTCBjYW4ndCByZWFkIFBoYXIgYXJjaGl2ZXMKCQlyZXR1cm4gZXh0cmFjdF9mcm9tX3BoYXIoIFdQX0NMSV9WRU5ET1JfRElSIC4gJGNlcnRfcGF0aCApOwoJfQoKCWZvcmVhY2ggKCBnZXRfdmVuZG9yX3BhdGhzKCkgYXMgJHZlbmRvcl9wYXRoICkgewoJCWlmICggZmlsZV9leGlzdHMoICR2ZW5kb3JfcGF0aCAuICRjZXJ0X3BhdGggKSApIHsKCQkJcmV0dXJuICR2ZW5kb3JfcGF0aCAuICRjZXJ0X3BhdGg7CgkJfQoJfQoKCWlmICggJGhhbHRfb25fZXJyb3IgKSB7CgkJV1BfQ0xJOjplcnJvciggJGVycm9yX21zZyApOwoJfQoKCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCAkZXJyb3JfbXNnICk7Cn0KCi8qKgogKiBJbmNyZW1lbnRzIGEgdmVyc2lvbiBzdHJpbmcgdXNpbmcgdGhlICJ4Lnkuei1wcmUiIGZvcm1hdC4KICoKICogQ2FuIGluY3JlbWVudCB0aGUgbWFqb3IsIG1pbm9yIG9yIHBhdGNoIG51bWJlciBieSBvbmUuCiAqIElmICRuZXdfdmVyc2lvbiA9PSAic2FtZSIgdGhlIHZlcnNpb24gc3RyaW5nIGlzIG5vdCBjaGFuZ2VkLgogKiBJZiAkbmV3X3ZlcnNpb24gaXMgbm90IGEga25vd24ga2V5d29yZCwgaXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBuZXcgdmVyc2lvbiBzdHJpbmcgZGlyZWN0bHkuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGN1cnJlbnRfdmVyc2lvbgogKiBAcGFyYW0gc3RyaW5nICRuZXdfdmVyc2lvbgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gaW5jcmVtZW50X3ZlcnNpb24oICRjdXJyZW50X3ZlcnNpb24sICRuZXdfdmVyc2lvbiApIHsKCS8vIHNwbGl0IHZlcnNpb24gYXNzdW1pbmcgdGhlIGZvcm1hdCBpcyB4Lnkuei1wcmUKCSRjdXJyZW50X3ZlcnNpb24gICAgPSBleHBsb2RlKCAnLScsICRjdXJyZW50X3ZlcnNpb24sIDIgKTsKCSRjdXJyZW50X3ZlcnNpb25bMF0gPSBleHBsb2RlKCAnLicsICRjdXJyZW50X3ZlcnNpb25bMF0gKTsKCglzd2l0Y2ggKCAkbmV3X3ZlcnNpb24gKSB7CgkJY2FzZSAnc2FtZSc6CgkJCS8vIGRvIG5vdGhpbmcKCQkJYnJlYWs7CgoJCWNhc2UgJ3BhdGNoJzoKCQkJJGN1cnJlbnRfdmVyc2lvblswXVsyXSsrOwoKCQkJJGN1cnJlbnRfdmVyc2lvbiA9IFsgJGN1cnJlbnRfdmVyc2lvblswXSBdOyAvLyBEcm9wIHBvc3NpYmxlIHByZS1yZWxlYXNlIGluZm8uCgkJCWJyZWFrOwoKCQljYXNlICdtaW5vcic6CgkJCSRjdXJyZW50X3ZlcnNpb25bMF1bMV0rKzsKCQkJJGN1cnJlbnRfdmVyc2lvblswXVsyXSA9IDA7CgoJCQkkY3VycmVudF92ZXJzaW9uID0gWyAkY3VycmVudF92ZXJzaW9uWzBdIF07IC8vIERyb3AgcG9zc2libGUgcHJlLXJlbGVhc2UgaW5mby4KCQkJYnJlYWs7CgoJCWNhc2UgJ21ham9yJzoKCQkJJGN1cnJlbnRfdmVyc2lvblswXVswXSsrOwoJCQkkY3VycmVudF92ZXJzaW9uWzBdWzFdID0gMDsKCQkJJGN1cnJlbnRfdmVyc2lvblswXVsyXSA9IDA7CgoJCQkkY3VycmVudF92ZXJzaW9uID0gWyAkY3VycmVudF92ZXJzaW9uWzBdIF07IC8vIERyb3AgcG9zc2libGUgcHJlLXJlbGVhc2UgaW5mby4KCQkJYnJlYWs7CgoJCWRlZmF1bHQ6IC8vIG5vdCBhIGtleXdvcmQKCQkJJGN1cnJlbnRfdmVyc2lvbiA9IFsgWyAkbmV3X3ZlcnNpb24gXSBdOwoJCQlicmVhazsKCX0KCgkvLyBSZWNvbnN0cnVjdCB2ZXJzaW9uIHN0cmluZy4KCSRjdXJyZW50X3ZlcnNpb25bMF0gPSBpbXBsb2RlKCAnLicsICRjdXJyZW50X3ZlcnNpb25bMF0gKTsKCSRjdXJyZW50X3ZlcnNpb24gICAgPSBpbXBsb2RlKCAnLScsICRjdXJyZW50X3ZlcnNpb24gKTsKCglyZXR1cm4gJGN1cnJlbnRfdmVyc2lvbjsKfQoKLyoqCiAqIENvbXBhcmUgdHdvIHZlcnNpb24gc3RyaW5ncyB0byBnZXQgdGhlIG5hbWVkIHNlbWFudGljIHZlcnNpb24uCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5ld192ZXJzaW9uCiAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsX3ZlcnNpb24KICogQHJldHVybiBzdHJpbmcgJ21ham9yJywgJ21pbm9yJywgJ3BhdGNoJwogKi8KZnVuY3Rpb24gZ2V0X25hbWVkX3NlbV92ZXIoICRuZXdfdmVyc2lvbiwgJG9yaWdpbmFsX3ZlcnNpb24gKSB7CgoJaWYgKCAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkbmV3X3ZlcnNpb24sICRvcmlnaW5hbF92ZXJzaW9uICkgKSB7CgkJcmV0dXJuICcnOwoJfQoKCSRwYXJ0cyA9IGV4cGxvZGUoICctJywgJG9yaWdpbmFsX3ZlcnNpb24gKTsKCSRiaXRzICA9IGV4cGxvZGUoICcuJywgJHBhcnRzWzBdICk7CgkkbWFqb3IgPSAkYml0c1swXTsKCWlmICggaXNzZXQoICRiaXRzWzFdICkgKSB7CgkJJG1pbm9yID0gJGJpdHNbMV07Cgl9CglpZiAoIGlzc2V0KCAkYml0c1syXSApICkgewoJCSRwYXRjaCA9ICRiaXRzWzJdOwoJfQoKCWlmICggaXNzZXQoICRtaW5vciApICYmIFNlbXZlcjo6c2F0aXNmaWVzKCAkbmV3X3ZlcnNpb24sICJ7JG1ham9yfS57JG1pbm9yfS54IiApICkgewoJCXJldHVybiAncGF0Y2gnOwoJfQoKCWlmICggU2VtdmVyOjpzYXRpc2ZpZXMoICRuZXdfdmVyc2lvbiwgInskbWFqb3J9LngueCIgKSApIHsKCQlyZXR1cm4gJ21pbm9yJzsKCX0KCglyZXR1cm4gJ21ham9yJzsKfQoKLyoqCiAqIFJldHVybiB0aGUgZmxhZyB2YWx1ZSBvciwgaWYgaXQncyBub3Qgc2V0LCB0aGUgJGRlZmF1bHQgdmFsdWUuCiAqCiAqIEJlY2F1c2UgZmxhZ3MgY2FuIGJlIG5lZ2F0ZWQgKGUuZy4gLS1uby1xdWlldCB0byBuZWdhdGUgLS1xdWlldCksIHRoaXMKICogZnVuY3Rpb24gcHJvdmlkZXMgYSBzYWZlciBhbHRlcm5hdGl2ZSB0byB1c2luZwogKiBgaXNzZXQoICRhc3NvY19hcmdzWydxdWlldCddIClgIG9yIHNpbWlsYXIuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBJbnB1dAogKgogKiBAcGFyYW0gYXJyYXkgICRhc3NvY19hcmdzIEFyZ3VtZW50cyBhcnJheS4KICogQHBhcmFtIHN0cmluZyAkZmxhZyAgICAgICBGbGFnIHRvIGdldCB0aGUgdmFsdWUuCiAqIEBwYXJhbSBtaXhlZCAgJGRlZmF1bHQgICAgRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGZsYWcuIERlZmF1bHQ6IE5VTEwuCiAqIEByZXR1cm4gbWl4ZWQKICovCmZ1bmN0aW9uIGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJGZsYWcsICRkZWZhdWx0ID0gbnVsbCApIHsKCXJldHVybiBpc3NldCggJGFzc29jX2FyZ3NbICRmbGFnIF0gKSA/ICRhc3NvY19hcmdzWyAkZmxhZyBdIDogJGRlZmF1bHQ7Cn0KCi8qKgogKiBHZXQgdGhlIGhvbWUgZGlyZWN0b3J5LgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgU3lzdGVtCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBnZXRfaG9tZV9kaXIoKSB7CgkkaG9tZSA9IGdldGVudiggJ0hPTUUnICk7CglpZiAoICEgJGhvbWUgKSB7CgkJLy8gSW4gV2luZG93cyAkSE9NRSBtYXkgbm90IGJlIGRlZmluZWQKCQkkaG9tZSA9IGdldGVudiggJ0hPTUVEUklWRScgKSAuIGdldGVudiggJ0hPTUVQQVRIJyApOwoJfQoKCXJldHVybiBydHJpbSggJGhvbWUsICcvXFwnICk7Cn0KCi8qKgogKiBBcHBlbmRzIGEgdHJhaWxpbmcgc2xhc2guCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBTeXN0ZW0KICoKICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFdoYXQgdG8gYWRkIHRoZSB0cmFpbGluZyBzbGFzaCB0by4KICogQHJldHVybiBzdHJpbmcgU3RyaW5nIHdpdGggdHJhaWxpbmcgc2xhc2ggYWRkZWQuCiAqLwpmdW5jdGlvbiB0cmFpbGluZ3NsYXNoaXQoICRzdHJpbmcgKSB7CglyZXR1cm4gcnRyaW0oICRzdHJpbmcsICcvXFwnICkgLiAnLyc7Cn0KCi8qKgogKiBOb3JtYWxpemUgYSBmaWxlc3lzdGVtIHBhdGguCiAqCiAqIE9uIFdpbmRvd3Mgc3lzdGVtcywgcmVwbGFjZXMgYmFja3NsYXNoZXMgd2l0aCBmb3J3YXJkIHNsYXNoZXMKICogYW5kIGZvcmNlcyB1cHBlci1jYXNlIGRyaXZlIGxldHRlcnMuCiAqIEFsbG93cyBmb3IgdHdvIGxlYWRpbmcgc2xhc2hlcyBmb3IgV2luZG93cyBuZXR3b3JrIHNoYXJlcywgYnV0CiAqIGVuc3VyZXMgdGhhdCBhbGwgb3RoZXIgZHVwbGljYXRlIHNsYXNoZXMgYXJlIHJlZHVjZWQgdG8gYSBzaW5nbGUgb25lLgogKiBFbnN1cmVzIHVwcGVyLWNhc2UgZHJpdmUgbGV0dGVycyBvbiBXaW5kb3dzIHN5c3RlbXMuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBTeXN0ZW0KICoKICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIG5vcm1hbGl6ZS4KICogQHJldHVybiBzdHJpbmcgTm9ybWFsaXplZCBwYXRoLgogKi8KZnVuY3Rpb24gbm9ybWFsaXplX3BhdGgoICRwYXRoICkgewoJJHBhdGggPSBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCAkcGF0aCApOwoJJHBhdGggPSBwcmVnX3JlcGxhY2UoICd8KD88PS4pLyt8JywgJy8nLCAkcGF0aCApOwoJaWYgKCAnOicgPT09IHN1YnN0ciggJHBhdGgsIDEsIDEgKSApIHsKCQkkcGF0aCA9IHVjZmlyc3QoICRwYXRoICk7Cgl9CglyZXR1cm4gJHBhdGg7Cn0KCgovKioKICogQ29udmVydCBXaW5kb3dzIEVPTHMgdG8gKm5peC4KICoKICogQHBhcmFtIHN0cmluZyAkc3RyIFN0cmluZyB0byBjb252ZXJ0LgogKiBAcmV0dXJuIHN0cmluZyBTdHJpbmcgd2l0aCBjYXJyaWFnZSByZXR1cm4gLyBuZXdsaW5lIHBhaXJzIHJlZHVjZWQgdG8gbmV3bGluZXMuCiAqLwpmdW5jdGlvbiBub3JtYWxpemVfZW9scyggJHN0ciApIHsKCXJldHVybiBzdHJfcmVwbGFjZSggIlxyXG4iLCAiXG4iLCAkc3RyICk7Cn0KCi8qKgogKiBHZXQgdGhlIHN5c3RlbSdzIHRlbXAgZGlyZWN0b3J5LiBXYXJucyB1c2VyIGlmIGl0IGlzbid0IHdyaXRhYmxlLgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgU3lzdGVtCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBnZXRfdGVtcF9kaXIoKSB7CglzdGF0aWMgJHRlbXAgPSAnJzsKCglpZiAoICR0ZW1wICkgewoJCXJldHVybiAkdGVtcDsKCX0KCgkvLyBgc3lzX2dldF90ZW1wX2RpcigpYCBpbnRyb2R1Y2VkIFBIUCA1LjIuMS4gV2lsbCBhbHdheXMgcmV0dXJuIHNvbWV0aGluZy4KCSR0ZW1wID0gdHJhaWxpbmdzbGFzaGl0KCBzeXNfZ2V0X3RlbXBfZGlyKCkgKTsKCglpZiAoICEgaXNfd3JpdGFibGUoICR0ZW1wICkgKSB7CgkJV1BfQ0xJOjp3YXJuaW5nKCAiVGVtcCBkaXJlY3RvcnkgaXNuJ3Qgd3JpdGFibGU6IHskdGVtcH0iICk7Cgl9CgoJcmV0dXJuICR0ZW1wOwp9CgovKioKICogUGFyc2UgYSBTU0ggdXJsIGZvciBpdHMgaG9zdCwgcG9ydCwgYW5kIHBhdGguCiAqCiAqIFNpbWlsYXIgdG8gcGFyc2VfdXJsKCksIGJ1dCBhZGRzIHN1cHBvcnQgZm9yIGRlZmluZWQgU1NIIGFsaWFzZXMuCiAqCiAqIGBgYAogKiBob3N0IE9SIGhvc3QvcGF0aC90by93b3JkcHJlc3MgT1IgaG9zdDpwb3J0L3BhdGgvdG8vd29yZHByZXNzCiAqIGBgYAogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcmV0dXJuIG1peGVkCiAqLwpmdW5jdGlvbiBwYXJzZV9zc2hfdXJsKCAkdXJsLCAkY29tcG9uZW50ID0gLTEgKSB7CglwcmVnX21hdGNoKCAnI14oKGRvY2tlcnxkb2NrZXJcLWNvbXBvc2V8c3NofHZhZ3JhbnQpOik/KChbXkA6XSspQCk/KFteOi9+XSspKDooW1xkXSopKT8oKC98fikoLispKT8kIycsICR1cmwsICRtYXRjaGVzICk7CgkkYml0cyA9IFtdOwoJZm9yZWFjaCAoIFsKCQkyID0+ICdzY2hlbWUnLAoJCTQgPT4gJ3VzZXInLAoJCTUgPT4gJ2hvc3QnLAoJCTcgPT4gJ3BvcnQnLAoJCTggPT4gJ3BhdGgnLAoJXSBhcyAkaSA9PiAka2V5ICkgewoJCWlmICggISBlbXB0eSggJG1hdGNoZXNbICRpIF0gKSApIHsKCQkJJGJpdHNbICRrZXkgXSA9ICRtYXRjaGVzWyAkaSBdOwoJCX0KCX0KCgkvLyBGaW5kIHRoZSBob3N0bmFtZSBmcm9tIGB2YWdyYW50IHNzaC1jb25maWdgIGF1dG9tYXRpY2FsbHkuCglpZiAoIHByZWdfbWF0Y2goICcvXnZhZ3JhbnQ6Py8nLCAkdXJsICkgKSB7CgkJaWYgKCAndmFncmFudCcgPT09ICRiaXRzWydob3N0J10gJiYgZW1wdHkoICRiaXRzWydzY2hlbWUnXSApICkgewoJCQkkYml0c1snc2NoZW1lJ10gPSAndmFncmFudCc7CgkJCSRiaXRzWydob3N0J10gICA9ICcnOwoJCX0KCX0KCglzd2l0Y2ggKCAkY29tcG9uZW50ICkgewoJCWNhc2UgUEhQX1VSTF9TQ0hFTUU6CgkJCXJldHVybiBpc3NldCggJGJpdHNbJ3NjaGVtZSddICkgPyAkYml0c1snc2NoZW1lJ10gOiBudWxsOwoJCWNhc2UgUEhQX1VSTF9VU0VSOgoJCQlyZXR1cm4gaXNzZXQoICRiaXRzWyd1c2VyJ10gKSA/ICRiaXRzWyd1c2VyJ10gOiBudWxsOwoJCWNhc2UgUEhQX1VSTF9IT1NUOgoJCQlyZXR1cm4gaXNzZXQoICRiaXRzWydob3N0J10gKSA/ICRiaXRzWydob3N0J10gOiBudWxsOwoJCWNhc2UgUEhQX1VSTF9QQVRIOgoJCQlyZXR1cm4gaXNzZXQoICRiaXRzWydwYXRoJ10gKSA/ICRiaXRzWydwYXRoJ10gOiBudWxsOwoJCWNhc2UgUEhQX1VSTF9QT1JUOgoJCQlyZXR1cm4gaXNzZXQoICRiaXRzWydwb3J0J10gKSA/ICRiaXRzWydwb3J0J10gOiBudWxsOwoJCWRlZmF1bHQ6CgkJCXJldHVybiAkYml0czsKCX0KfQoKLyoqCiAqIFJlcG9ydCB0aGUgcmVzdWx0cyBvZiB0aGUgc2FtZSBvcGVyYXRpb24gYWdhaW5zdCBtdWx0aXBsZSByZXNvdXJjZXMuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBJbnB1dAogKgogKiBAcGFyYW0gc3RyaW5nICAgICAgICRub3VuICAgICAgUmVzb3VyY2UgYmVpbmcgYWZmZWN0ZWQgKGUuZy4gcGx1Z2luKS4KICogQHBhcmFtIHN0cmluZyAgICAgICAkdmVyYiAgICAgIFR5cGUgb2YgYWN0aW9uIGhhcHBlbmluZyB0byB0aGUgbm91biAoZS5nLiBhY3RpdmF0ZSkuCiAqIEBwYXJhbSBpbnRlZ2VyICAgICAgJHRvdGFsICAgICBUb3RhbCBudW1iZXIgb2YgcmVzb3VyY2UgYmVpbmcgYWZmZWN0ZWQuCiAqIEBwYXJhbSBpbnRlZ2VyICAgICAgJHN1Y2Nlc3NlcyBOdW1iZXIgb2Ygc3VjY2Vzc2Z1bCBvcGVyYXRpb25zLgogKiBAcGFyYW0gaW50ZWdlciAgICAgICRmYWlsdXJlcyAgTnVtYmVyIG9mIGZhaWx1cmVzLgogKiBAcGFyYW0gbnVsbHxpbnRlZ2VyICRza2lwcyAgICAgT3B0aW9uYWwuIE51bWJlciBvZiBza2lwcGVkIG9wZXJhdGlvbnMuIERlZmF1bHQgbnVsbCAoZG9uJ3Qgc2hvdyBza2lwcykuCiAqLwpmdW5jdGlvbiByZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICRub3VuLCAkdmVyYiwgJHRvdGFsLCAkc3VjY2Vzc2VzLCAkZmFpbHVyZXMsICRza2lwcyA9IG51bGwgKSB7CgkkcGx1cmFsX25vdW4gICAgICAgICAgID0gJG5vdW4gLiAncyc7CgkkcGFzdF90ZW5zZV92ZXJiICAgICAgID0gcGFzdF90ZW5zZV92ZXJiKCAkdmVyYiApOwoJJHBhc3RfdGVuc2VfdmVyYl91cHBlciA9IHVjZmlyc3QoICRwYXN0X3RlbnNlX3ZlcmIgKTsKCWlmICggJGZhaWx1cmVzICkgewoJCSRmYWlsZWRfc2tpcHBlZF9tZXNzYWdlID0gbnVsbCA9PT0gJHNraXBzID8gJycgOiAiICh7JGZhaWx1cmVzfSBmYWlsZWQiIC4gKCAkc2tpcHMgPyAiLCB7JHNraXBzfSBza2lwcGVkIiA6ICcnICkgLiAnKSc7CgkJaWYgKCAkc3VjY2Vzc2VzICkgewoJCQlXUF9DTEk6OmVycm9yKCAiT25seSB7JHBhc3RfdGVuc2VfdmVyYn0geyRzdWNjZXNzZXN9IG9mIHskdG90YWx9IHskcGx1cmFsX25vdW59eyRmYWlsZWRfc2tpcHBlZF9tZXNzYWdlfS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIk5vIHskcGx1cmFsX25vdW59IHskcGFzdF90ZW5zZV92ZXJifXskZmFpbGVkX3NraXBwZWRfbWVzc2FnZX0uIiApOwoJCX0KCX0gZWxzZSB7CgkJJHNraXBwZWRfbWVzc2FnZSA9ICRza2lwcyA/ICIgKHskc2tpcHN9IHNraXBwZWQpIiA6ICcnOwoJCWlmICggJHN1Y2Nlc3NlcyB8fCAkc2tpcHMgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggInskcGFzdF90ZW5zZV92ZXJiX3VwcGVyfSB7JHN1Y2Nlc3Nlc30gb2YgeyR0b3RhbH0geyRwbHVyYWxfbm91bn17JHNraXBwZWRfbWVzc2FnZX0uIiApOwoJCX0gZWxzZSB7CgkJCSRtZXNzYWdlID0gJHRvdGFsID4gMSA/IHVjZmlyc3QoICRwbHVyYWxfbm91biApIDogdWNmaXJzdCggJG5vdW4gKTsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAieyRtZXNzYWdlfSBhbHJlYWR5IHskcGFzdF90ZW5zZV92ZXJifS4iICk7CgkJfQoJfQp9CgovKioKICogUGFyc2UgYSBzdHJpbmcgb2YgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBpbnRvIGFuICRhcmd2LWVzcWUgdmFyaWFibGUuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqIEBjYXRlZ29yeSBJbnB1dAogKgogKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudHMKICogQHJldHVybiBhcnJheQogKi8KZnVuY3Rpb24gcGFyc2Vfc3RyX3RvX2FyZ3YoICRhcmd1bWVudHMgKSB7CglwcmVnX21hdGNoX2FsbCggJy8oPzotLVteXHM9XSs9KFsiXCddKSgoXFx7Mn0pKnwoPzpbXlwxXSs/W15cXFxcXShcXHsyfSkqKSlcMXwtLVteXHM9XSs9W15cc10rfC0tW15ccz1dK3woWyJcJ10pKChcXHsyfSkqfCg/OlteXDVdKz9bXlxcXFxdKFxcezJ9KSopKVw1fFteXHNdKykvJywgJGFyZ3VtZW50cywgJG1hdGNoZXMgKTsKCSRhcmd2ID0gaXNzZXQoICRtYXRjaGVzWzBdICkgPyAkbWF0Y2hlc1swXSA6IFtdOwoJcmV0dXJuIGFycmF5X21hcCgKCQlzdGF0aWMgZnVuY3Rpb24gKCAkYXJnICkgewoJCQlmb3JlYWNoICggWyAnIicsICInIiBdIGFzICRjaGFyICkgewoJCQkJaWYgKCBzdWJzdHIoICRhcmcsIDAsIDEgKSA9PT0gJGNoYXIgJiYgc3Vic3RyKCAkYXJnLCAtMSApID09PSAkY2hhciApIHsKCQkJCQkkYXJnID0gc3Vic3RyKCAkYXJnLCAxLCAtMSApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCQlyZXR1cm4gJGFyZzsKCQl9LAoJCSRhcmd2CgkpOwp9CgovKioKICogTG9jYWxlLWluZGVwZW5kZW50IHZlcnNpb24gb2YgYmFzZW5hbWUoKQogKgogKiBAYWNjZXNzIHB1YmxpYwogKgogKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAqIEBwYXJhbSBzdHJpbmcgJHN1ZmZpeAogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gYmFzZW5hbWUoICRwYXRoLCAkc3VmZml4ID0gJycgKSB7CgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5EaXNjb3VyYWdlZFBIUEZ1bmN0aW9ucy51cmxlbmNvZGVfdXJsZW5jb2RlIC0tIEZvcm1hdCByZXF1aXJlZCBieSB3b3JkcHJlc3Mub3JnIEFQSS4KCXJldHVybiB1cmxkZWNvZGUoIFxiYXNlbmFtZSggc3RyX3JlcGxhY2UoIFsgJyUyRicsICclNUMnIF0sICcvJywgdXJsZW5jb2RlKCAkcGF0aCApICksICRzdWZmaXggKSApOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgdGhlIG91dHB1dCBvZiB0aGUgY3VycmVudCBzY3JpcHQgaXMgYSBUVFkgb3IgYSBwaXBlIC8gcmVkaXJlY3QKICoKICogUmV0dXJucyB0cnVlIGlmIFNURE9VVCBvdXRwdXQgaXMgYmVpbmcgcmVkaXJlY3RlZCB0byBhIHBpcGUgb3IgYSBmaWxlOyBmYWxzZSBpcwogKiBvdXRwdXQgaXMgYmVpbmcgc2VudCBkaXJlY3RseSB0byB0aGUgdGVybWluYWwuCiAqCiAqIElmIGFuIGVudiB2YXJpYWJsZSBTSEVMTF9QSVBFIGV4aXN0cywgcmV0dXJuZWQgcmVzdWx0IGRlcGVuZHMgb24gaXRzCiAqIHZhbHVlLiBTdHJpbmdzIGxpa2UgMSwgMCwgeWVzLCBubywgdGhhdCB2YWxpZGF0ZSB0byBib29sZWFucyBhcmUgYWNjZXB0ZWQuCiAqCiAqIFRvIGVuYWJsZSBBU0NJSSBmb3JtYXR0aW5nIGV2ZW4gd2hlbiB0aGUgc2hlbGwgaXMgcGlwZWQsIHVzZSB0aGUKICogRU5WIHZhcmlhYmxlIFNIRUxMX1BJUEU9MC4KICoKICogQGFjY2VzcyBwdWJsaWMKICoKICogQHJldHVybiBib29sCiAqLwpmdW5jdGlvbiBpc1BpcGVkKCkgeyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlZhbGlkRnVuY3Rpb25OYW1lLkZ1bmN0aW9uTmFtZUludmFsaWQgLS0gUmVuYW1pbmcgd291bGQgYnJlYWsgQkMuCgkkc2hlbGxfcGlwZSA9IGdldGVudiggJ1NIRUxMX1BJUEUnICk7CgoJaWYgKCBmYWxzZSAhPT0gJHNoZWxsX3BpcGUgKSB7CgkJcmV0dXJuIGZpbHRlcl92YXIoICRzaGVsbF9waXBlLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTiApOwoJfQoKCXJldHVybiBmdW5jdGlvbl9leGlzdHMoICdwb3NpeF9pc2F0dHknICkgJiYgISBwb3NpeF9pc2F0dHkoIFNURE9VVCApOwp9CgovKioKICogRXhwYW5kIHdpdGhpbiBwYXRocyB0byB0aGVpciBtYXRjaGluZyBwYXRocy4KICoKICogSGFzIG5vIGVmZmVjdCBvbiBwYXRocyB3aGljaCBkbyBub3QgdXNlIGdsb2IgcGF0dGVybnMuCiAqCiAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJHBhdGhzIFNpbmdsZSBwYXRoIGFzIGEgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBwYXRocy4KICogQHBhcmFtIGludCAgICAgICAgICAkZmxhZ3MgT3B0aW9uYWwuIEZsYWdzIHRvIHBhc3MgdG8gZ2xvYi4gRGVmYXVsdHMgdG8gR0xPQl9CUkFDRS4KICogQHJldHVybiBhcnJheSBFeHBhbmRlZCBwYXRocy4KICovCmZ1bmN0aW9uIGV4cGFuZF9nbG9icyggJHBhdGhzLCAkZmxhZ3MgPSAnZGVmYXVsdCcgKSB7CgkvLyBDb21wYXRpYmlsaXR5IGZvciBzeXN0ZW1zIHdpdGhvdXQgR0xPQl9CUkFDRS4KCSRnbG9iX2Z1bmMgPSAnZ2xvYic7CglpZiAoICdkZWZhdWx0JyA9PT0gJGZsYWdzICkgewoJCWlmICggISBkZWZpbmVkKCAnR0xPQl9CUkFDRScgKSB8fCBnZXRlbnYoICdXUF9DTElfVEVTVF9FWFBBTkRfR0xPQlNfTk9fR0xPQl9CUkFDRScgKSApIHsKCQkJJGdsb2JfZnVuYyA9ICdXUF9DTElcVXRpbHNcZ2xvYl9icmFjZSc7CgkJfSBlbHNlIHsKCQkJJGZsYWdzID0gR0xPQl9CUkFDRTsKCQl9Cgl9CgoJJGV4cGFuZGVkID0gW107CgoJZm9yZWFjaCAoIChhcnJheSkgJHBhdGhzIGFzICRwYXRoICkgewoJCSRtYXRjaGluZyA9IFsgJHBhdGggXTsKCgkJaWYgKCBwcmVnX21hdGNoKCAnL1snIC4gcHJlZ19xdW90ZSggJyo/W117fSEnLCAnLycgKSAuICddLycsICRwYXRoICkgKSB7CgkJCSRtYXRjaGluZyA9ICRnbG9iX2Z1bmMoICRwYXRoLCAkZmxhZ3MgKSA/OiBbXTsKCQl9CgkJJGV4cGFuZGVkID0gYXJyYXlfbWVyZ2UoICRleHBhbmRlZCwgJG1hdGNoaW5nICk7Cgl9CgoJcmV0dXJuIGFycmF5X3ZhbHVlcyggYXJyYXlfdW5pcXVlKCAkZXhwYW5kZWQgKSApOwp9CgovKioKICogU2ltdWxhdGUgYSBgZ2xvYigpYCB3aXRoIHRoZSBgR0xPQl9CUkFDRWAgZmxhZyBzZXQuIEZvciBzeXN0ZW1zIChlZyBBbHBpbmUgTGludXgpIGJ1aWx0IGFnYWluc3QgYSBsaWJjIGxpYnJhcnkgKGVnIGh0dHBzOi8vd3d3Lm11c2wtbGliYy5vcmcvKSB0aGF0IGxhY2tzIGl0LgogKiBDb3BpZWQgYW5kIGFkYXB0ZWQgZnJvbSBaZW5kIEZyYW1ld29yaydzIGBHbG9iOjpmYWxsYmFja0dsb2IoKWAgYW5kIEdsb2I6Om5leHRCcmFjZVN1YigpYC4KICoKICogWmVuZCBGcmFtZXdvcmsgKGh0dHBzOi8vZnJhbWV3b3JrLnplbmQuY29tLykKICoKICogQGxpbmsgICAgICBodHRwczovL2dpdGh1Yi5jb20vemVuZGZyYW1ld29yay96ZjIgZm9yIHRoZSBjYW5vbmljYWwgc291cmNlIHJlcG9zaXRvcnkKICogQGNvcHlyaWdodCBDb3B5cmlnaHQgKGMpIDIwMDUtMjAxNSBaZW5kIFRlY2hub2xvZ2llcyBVU0EgSW5jLiAoaHR0cHM6Ly93d3cuemVuZC5jb20pCiAqIEBsaWNlbnNlICAgaHR0cHM6Ly9mcmFtZXdvcmsuemVuZC5jb20vbGljZW5zZS9uZXctYnNkIE5ldyBCU0QgTGljZW5zZQogKgogKiBAcGFyYW0gc3RyaW5nICRwYXR0ZXJuICAgICBGaWxlbmFtZSBwYXR0ZXJuLgogKiBAcGFyYW0gdm9pZCAgICRkdW1teV9mbGFncyBOb3QgdXNlZC4KICogQHJldHVybiBhcnJheSBBcnJheSBvZiBwYXRocy4KICovCmZ1bmN0aW9uIGdsb2JfYnJhY2UoICRwYXR0ZXJuLCAkZHVtbXlfZmxhZ3MgPSBudWxsICkgewoKCXN0YXRpYyAkbmV4dF9icmFjZV9zdWI7CglpZiAoICEgJG5leHRfYnJhY2Vfc3ViICkgewoJCS8vIEZpbmQgdGhlIGVuZCBvZiB0aGUgc3VicGF0dGVybiBpbiBhIGJyYWNlIGV4cHJlc3Npb24uCgkJJG5leHRfYnJhY2Vfc3ViID0gZnVuY3Rpb24gKCAkcGF0dGVybiwgJGN1cnJlbnQgKSB7CgkJCSRsZW5ndGggPSBzdHJsZW4oICRwYXR0ZXJuICk7CgkJCSRkZXB0aCAgPSAwOwoKCQkJd2hpbGUgKCAkY3VycmVudCA8ICRsZW5ndGggKSB7CgkJCQlpZiAoICdcXCcgPT09ICRwYXR0ZXJuWyAkY3VycmVudCBdICkgewoJCQkJCWlmICggKyskY3VycmVudCA9PT0gJGxlbmd0aCApIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCSRjdXJyZW50Kys7CgkJCQl9IGVsc2UgewoJCQkJCWlmICggKCAnfScgPT09ICRwYXR0ZXJuWyAkY3VycmVudCBdICYmIDAgPT09ICRkZXB0aC0tICkgfHwgKCAnLCcgPT09ICRwYXR0ZXJuWyAkY3VycmVudCBdICYmIDAgPT09ICRkZXB0aCApICkgewoJCQkJCQlicmVhazsKCQkJCQl9CgoJCQkJCWlmICggJ3snID09PSAkcGF0dGVyblsgJGN1cnJlbnQrKyBdICkgewoJCQkJCQkkZGVwdGgrKzsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCXJldHVybiAkY3VycmVudCA8ICRsZW5ndGggPyAkY3VycmVudCA6IG51bGw7CgkJfTsKCX0KCgkkbGVuZ3RoID0gc3RybGVuKCAkcGF0dGVybiApOwoKCS8vIEZpbmQgZmlyc3Qgb3BlbmluZyBicmFjZS4KCWZvciAoICRiZWdpbiA9IDA7ICRiZWdpbiA8ICRsZW5ndGg7ICRiZWdpbisrICkgewoJCWlmICggJ1xcJyA9PT0gJHBhdHRlcm5bICRiZWdpbiBdICkgewoJCQkkYmVnaW4rKzsKCQl9IGVsc2VpZiAoICd7JyA9PT0gJHBhdHRlcm5bICRiZWdpbiBdICkgewoJCQlicmVhazsKCQl9Cgl9CgoJLy8gRmluZCBjb21tYSBvciBtYXRjaGluZyBjbG9zaW5nIGJyYWNlLgoJJG5leHQgPSAkbmV4dF9icmFjZV9zdWIoICRwYXR0ZXJuLCAkYmVnaW4gKyAxICk7CglpZiAoIG51bGwgPT09ICRuZXh0ICkgewoJCXJldHVybiBnbG9iKCAkcGF0dGVybiApOwoJfQoKCSRyZXN0ID0gJG5leHQ7CgoJLy8gUG9pbnQgYCRyZXN0YCB0byBtYXRjaGluZyBjbG9zaW5nIGJyYWNlLgoJd2hpbGUgKCAnfScgIT09ICRwYXR0ZXJuWyAkcmVzdCBdICkgewoJCSRyZXN0ID0gJG5leHRfYnJhY2Vfc3ViKCAkcGF0dGVybiwgJHJlc3QgKyAxICk7CgkJaWYgKCBudWxsID09PSAkcmVzdCApIHsKCQkJcmV0dXJuIGdsb2IoICRwYXR0ZXJuICk7CgkJfQoJfQoKCSRwYXRocyA9IFtdOwoJJHAgICAgID0gJGJlZ2luICsgMTsKCgkvLyBGb3IgZWFjaCBjb21tYS1zZXBhcmF0ZWQgc3VicGF0dGVybi4KCWRvIHsKCQkkc3VicGF0dGVybiA9IHN1YnN0ciggJHBhdHRlcm4sIDAsICRiZWdpbiApCgkJCQkJLiBzdWJzdHIoICRwYXR0ZXJuLCAkcCwgJG5leHQgLSAkcCApCgkJCQkJLiBzdWJzdHIoICRwYXR0ZXJuLCAkcmVzdCArIDEgKTsKCgkJJHJlc3VsdCA9IGdsb2JfYnJhY2UoICRzdWJwYXR0ZXJuICk7CgkJaWYgKCAhIGVtcHR5KCAkcmVzdWx0ICkgKSB7CgkJCSRwYXRocyA9IGFycmF5X21lcmdlKCAkcGF0aHMsICRyZXN1bHQgKTsKCQl9CgoJCWlmICggJ30nID09PSAkcGF0dGVyblsgJG5leHQgXSApIHsKCQkJYnJlYWs7CgkJfQoKCQkkcCAgICA9ICRuZXh0ICsgMTsKCQkkbmV4dCA9ICRuZXh0X2JyYWNlX3N1YiggJHBhdHRlcm4sICRwICk7Cgl9IHdoaWxlICggbnVsbCAhPT0gJG5leHQgKTsKCglyZXR1cm4gYXJyYXlfdmFsdWVzKCBhcnJheV91bmlxdWUoICRwYXRocyApICk7Cn0KCi8qKgogKiBHZXQgdGhlIGNsb3Nlc3Qgc3VnZ2VzdGlvbiBmb3IgYSBtaXMtdHlwZWQgdGFyZ2V0IHRlcm0gYW1vbmdzdCBhIGxpc3Qgb2YKICogb3B0aW9ucy4KICoKICogVXNlcyB0aGUgTGV2ZW5zaHRlaW4gYWxnb3JpdGhtIHRvIGNhbGN1bGF0ZSB0aGUgcmVsYXRpdmUgImRpc3RhbmNlIiBiZXR3ZWVuCiAqIHRlcm1zLgogKgogKiBJZiB0aGUgImRpc3RhbmNlIiB0byB0aGUgY2xvc2VzdCB0ZXJtIGlzIGhpZ2hlciB0aGFuIHRoZSB0aHJlc2hvbGQsIGFuIGVtcHR5CiAqIHN0cmluZyBpcyByZXR1cm5lZC4KICoKICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0ICAgIFRhcmdldCB0ZXJtIHRvIGdldCBhIHN1Z2dlc3Rpb24gZm9yLgogKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zICAgQXJyYXkgd2l0aCBwb3NzaWJsZSBvcHRpb25zLgogKiBAcGFyYW0gaW50ICAgICR0aHJlc2hvbGQgVGhyZXNob2xkIGFib3ZlIHdoaWNoIHRvIHJldHVybiBhbiBlbXB0eSBzdHJpbmcuCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBnZXRfc3VnZ2VzdGlvbiggJHRhcmdldCwgYXJyYXkgJG9wdGlvbnMsICR0aHJlc2hvbGQgPSAyICkgewoKCSRzdWdnZXN0aW9uX21hcCA9IFsKCQknYWRkJyAgICAgICAgPT4gJ2NyZWF0ZScsCgkJJ2NoZWNrJyAgICAgID0+ICdjaGVjay11cGRhdGUnLAoJCSdjYXBhYmlsaXR5JyA9PiAnY2FwJywKCQknY2xlYXInICAgICAgPT4gJ2ZsdXNoJywKCQknZGVjcmVtZW50JyAgPT4gJ2RlY3InLAoJCSdkZWwnICAgICAgICA9PiAnZGVsZXRlJywKCQknZGlyZWN0b3J5JyAgPT4gJ2RpcicsCgkJJ2V4ZWMnICAgICAgID0+ICdldmFsJywKCQknZXhlYy1maWxlJyAgPT4gJ2V2YWwtZmlsZScsCgkJJ2luY3JlbWVudCcgID0+ICdpbmNyJywKCQknbGFuZ3VhZ2UnICAgPT4gJ2xvY2FsZScsCgkJJ2xhbmcnICAgICAgID0+ICdsb2NhbGUnLAoJCSduZXcnICAgICAgICA9PiAnY3JlYXRlJywKCQknbnVtYmVyJyAgICAgPT4gJ2NvdW50JywKCQkncmVtb3ZlJyAgICAgPT4gJ2RlbGV0ZScsCgkJJ3JlZ2VuJyAgICAgID0+ICdyZWdlbmVyYXRlJywKCQkncmVwJyAgICAgICAgPT4gJ3JlcGxhY2UnLAoJCSdyZXBsJyAgICAgICA9PiAncmVwbGFjZScsCgkJJ3RyYXNoJyAgICAgID0+ICdkZWxldGUnLAoJCSd2JyAgICAgICAgICA9PiAndmVyc2lvbicsCgldOwoKCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJHRhcmdldCwgJHN1Z2dlc3Rpb25fbWFwICkgJiYgaW5fYXJyYXkoICRzdWdnZXN0aW9uX21hcFsgJHRhcmdldCBdLCAkb3B0aW9ucywgdHJ1ZSApICkgewoJCXJldHVybiAkc3VnZ2VzdGlvbl9tYXBbICR0YXJnZXQgXTsKCX0KCglpZiAoIGVtcHR5KCAkb3B0aW9ucyApICkgewoJCXJldHVybiAnJzsKCX0KCWZvcmVhY2ggKCAkb3B0aW9ucyBhcyAkb3B0aW9uICkgewoJCSRkaXN0YW5jZSAgICAgICAgICAgICAgID0gbGV2ZW5zaHRlaW4oICRvcHRpb24sICR0YXJnZXQgKTsKCQkkbGV2ZW5zaHRlaW5bICRvcHRpb24gXSA9ICRkaXN0YW5jZTsKCX0KCgkvLyBTb3J0IGtub3duIGNvbW1hbmQgc3RyaW5ncyBieSBkaXN0YW5jZSB0byB1c2VyIGVudHJ5LgoJYXNvcnQoICRsZXZlbnNodGVpbiApOwoKCS8vIEZldGNoIHRoZSBjbG9zZXN0IGNvbW1hbmQgc3RyaW5nLgoJcmVzZXQoICRsZXZlbnNodGVpbiApOwoJJHN1Z2dlc3Rpb24gPSBrZXkoICRsZXZlbnNodGVpbiApOwoKCS8vIE9ubHkgcmV0dXJuIGEgc3VnZ2VzdGlvbiBpZiBiZWxvdyBhIGdpdmVuIHRocmVzaG9sZC4KCXJldHVybiAkbGV2ZW5zaHRlaW5bICRzdWdnZXN0aW9uIF0gPD0gJHRocmVzaG9sZCAmJiAkc3VnZ2VzdGlvbiAhPT0gJHRhcmdldAoJCT8gKHN0cmluZykgJHN1Z2dlc3Rpb24KCQk6ICcnOwp9CgovKioKICogR2V0IGEgUGhhci1zYWZlIHZlcnNpb24gb2YgYSBwYXRoLgogKgogKiBGb3IgcGF0aHMgaW5zaWRlIGEgUGhhciwgdGhpcyBzdHJpcHMgdGhlIG91dGVyIGZpbGVzeXN0ZW0ncyBsb2NhdGlvbiB0bwogKiByZWR1Y2UgdGhlIHBhdGggdG8gd2hhdCBpdCBuZWVkcyB0byBiZSB3aXRoaW4gdGhlIFBoYXIgYXJjaGl2ZS4KICoKICogVXNlIHRoZSBfX0ZJTEVfXyBvciBfX0RJUl9fIGNvbnN0YW50cyBhcyBhIHN0YXJ0aW5nIHBvaW50LgogKgogKiBAcGFyYW0gc3RyaW5nICRwYXRoIEFuIGFic29sdXRlIHBhdGggdGhhdCBtaWdodCBiZSB3aXRoaW4gYSBQaGFyLgogKiBAcmV0dXJuIHN0cmluZyBBIFBoYXItc2FmZSB2ZXJzaW9uIG9mIHRoZSBwYXRoLgogKi8KZnVuY3Rpb24gcGhhcl9zYWZlX3BhdGgoICRwYXRoICkgewoKCWlmICggISBpbnNpZGVfcGhhcigpICkgewoJCXJldHVybiAkcGF0aDsKCX0KCglyZXR1cm4gc3RyX3JlcGxhY2UoCgkJUEhBUl9TVFJFQU1fUFJFRklYIC4gV1BfQ0xJX1BIQVJfUEFUSCAuICcvJywKCQlQSEFSX1NUUkVBTV9QUkVGSVgsCgkJJHBhdGgKCSk7Cn0KCi8qKgogKiBNYXliZSBwcmVmaXggY29tbWFuZCBzdHJpbmcgd2l0aCAiL3Vzci9iaW4vZW52Ii4KICogUmVtb3ZlcyAoaWYgdGhlcmUpIGlmIFdpbmRvd3MsIGFkZHMgKGlmIG5vdCB0aGVyZSkgaWYgbm90LgogKgogKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBmb3JjZV9lbnZfb25fbml4X3N5c3RlbXMoICRjb21tYW5kICkgewoJJGVudl9wcmVmaXggICAgID0gJy91c3IvYmluL2VudiAnOwoJJGVudl9wcmVmaXhfbGVuID0gc3RybGVuKCAkZW52X3ByZWZpeCApOwoJaWYgKCBpc193aW5kb3dzKCkgKSB7CgkJaWYgKCAwID09PSBzdHJuY21wKCAkY29tbWFuZCwgJGVudl9wcmVmaXgsICRlbnZfcHJlZml4X2xlbiApICkgewoJCQkkY29tbWFuZCA9IHN1YnN0ciggJGNvbW1hbmQsICRlbnZfcHJlZml4X2xlbiApOwoJCX0KCX0gZWxzZWlmICggMCAhPT0gc3RybmNtcCggJGNvbW1hbmQsICRlbnZfcHJlZml4LCAkZW52X3ByZWZpeF9sZW4gKSApIHsKCQkkY29tbWFuZCA9ICRlbnZfcHJlZml4IC4gJGNvbW1hbmQ7Cgl9CglyZXR1cm4gJGNvbW1hbmQ7Cn0KCi8qKgogKiBDaGVjayB0aGF0IGBwcm9jX29wZW4oKWAgYW5kIGBwcm9jX2Nsb3NlKClgIGhhdmVuJ3QgYmVlbiBkaXNhYmxlZC4KICoKICogQHBhcmFtIHN0cmluZyAkY29udGV4dCBPcHRpb25hbC4gSWYgc2V0IHdpbGwgYXBwZWFyIGluIGVycm9yIG1lc3NhZ2UuIERlZmF1bHQgbnVsbC4KICogQHBhcmFtIGJvb2wgICAkcmV0dXJuICBPcHRpb25hbC4gSWYgc2V0IHdpbGwgcmV0dXJuIGZhbHNlIHJhdGhlciB0aGFuIGVycm9yIG91dC4gRGVmYXVsdCBmYWxzZS4KICogQHJldHVybiBib29sCiAqLwpmdW5jdGlvbiBjaGVja19wcm9jX2F2YWlsYWJsZSggJGNvbnRleHQgPSBudWxsLCAkcmV0dXJuID0gZmFsc2UgKSB7CglpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAncHJvY19vcGVuJyApIHx8ICEgZnVuY3Rpb25fZXhpc3RzKCAncHJvY19jbG9zZScgKSApIHsKCQlpZiAoICRyZXR1cm4gKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJG1zZyA9ICdUaGUgUEhQIGZ1bmN0aW9ucyBgcHJvY19vcGVuKClgIGFuZC9vciBgcHJvY19jbG9zZSgpYCBhcmUgZGlzYWJsZWQuIFBsZWFzZSBjaGVjayB5b3VyIFBIUCBpbmkgZGlyZWN0aXZlIGBkaXNhYmxlX2Z1bmN0aW9uc2Agb3Igc3Vob3NpbiBzZXR0aW5ncy4nOwoJCWlmICggJGNvbnRleHQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJDYW5ub3QgZG8gJyVzJzogJXMiLCAkY29udGV4dCwgJG1zZyApICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJG1zZyApOwoJCX0KCX0KCXJldHVybiB0cnVlOwp9CgovKioKICogUmV0dXJucyBwYXN0IHRlbnNlIG9mIHZlcmIsIHdpdGggbGltaXRlZCBhY2N1cmFjeS4gT25seSByZWd1bGFyIHZlcmJzIGNhdGVyZWQgZm9yLCBhcGFydCBmcm9tICJyZXNldCIuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHZlcmIgVmVyYiB0byByZXR1cm4gcGFzdCB0ZW5zZSBvZi4KICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIHBhc3RfdGVuc2VfdmVyYiggJHZlcmIgKSB7CglzdGF0aWMgJGlycmVndWxhciA9IFsKCQkncmVzZXQnID0+ICdyZXNldCcsCgldOwoJaWYgKCBpc3NldCggJGlycmVndWxhclsgJHZlcmIgXSApICkgewoJCXJldHVybiAkaXJyZWd1bGFyWyAkdmVyYiBdOwoJfQoJJGxhc3QgPSBzdWJzdHIoICR2ZXJiLCAtMSApOwoJaWYgKCAnZScgPT09ICRsYXN0ICkgewoJCSR2ZXJiID0gc3Vic3RyKCAkdmVyYiwgMCwgLTEgKTsKCX0gZWxzZWlmICggJ3knID09PSAkbGFzdCAmJiAhIHByZWdfbWF0Y2goICcvW2FlaW91XXkkLycsICR2ZXJiICkgKSB7CgkJJHZlcmIgPSBzdWJzdHIoICR2ZXJiLCAwLCAtMSApIC4gJ2knOwoJfSBlbHNlaWYgKCBwcmVnX21hdGNoKCAnL15bXmFlaW91XSpbYWVpb3VdW15hZWlvdWh3eHldJC8nLCAkdmVyYiApICkgewoJCS8vIFJ1bGUgb2YgdGh1bWIgdGhhdCBtb3N0IChhbGw/KSBvbmUtdm93ZWxlZCByZWd1bGFyIHZlcmJzIGVuZGluZyBpbiB2b3dlbCArIGNvbnNvbmFudCAoZXhjbHVkaW5nICJoIiwgInciLCAieCIsICJ5IikgZG91YmxlIHRoZWlyIGZpbmFsIGNvbnNvbmFudCAtIG1pc3NlcyBtYW55IGNhc2VzIChlZyAic3VibWl0IikuCgkJJHZlcmIgLj0gJGxhc3Q7Cgl9CglyZXR1cm4gJHZlcmIgLiAnZWQnOwp9CgovKioKICogR2V0IHRoZSBwYXRoIHRvIHRoZSBQSFAgYmluYXJ5IHVzZWQgd2hlbiBleGVjdXRpbmcgV1AtQ0xJLgogKgogKiBFbnZpcm9ubWVudCB2YWx1ZXMgcGVybWl0IHNwZWNpZmljIGJpbmFyaWVzIHRvIGJlIGluZGljYXRlZC4KICoKICogQGFjY2VzcyBwdWJsaWMKICogQGNhdGVnb3J5IFN5c3RlbQogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gZ2V0X3BocF9iaW5hcnkoKSB7Cgkkd3BfY2xpX3BocF91c2VkID0gZ2V0ZW52KCAnV1BfQ0xJX1BIUF9VU0VEJyApOwoJaWYgKCBmYWxzZSAhPT0gJHdwX2NsaV9waHBfdXNlZCApIHsKCQlyZXR1cm4gJHdwX2NsaV9waHBfdXNlZDsKCX0KCgkkd3BfY2xpX3BocCA9IGdldGVudiggJ1dQX0NMSV9QSFAnICk7CglpZiAoIGZhbHNlICE9PSAkd3BfY2xpX3BocCApIHsKCQlyZXR1cm4gJHdwX2NsaV9waHA7Cgl9CgoJcmV0dXJuIFBIUF9CSU5BUlk7Cn0KCi8qKgogKiBXaW5kb3dzIGNvbXBhdGlibGUgYHByb2Nfb3BlbigpYC4KICogV29ya3MgYXJvdW5kIGJ1ZyBpbiBQSFAsIGFuZCBhbHNvIGRlYWxzIHdpdGggKm5peC1saWtlIGBFTlZfVkFSPWJsYWggY21kYCBlbnZpcm9ubWVudCB2YXJpYWJsZSBwcmVmaXhlcy4KICoKICogQGFjY2VzcyBwdWJsaWMKICoKICogQHBhcmFtIHN0cmluZyAkY21kICAgICAgICAgICAgQ29tbWFuZCB0byBleGVjdXRlLgogKiBAcGFyYW0gYXJyYXkgICRkZXNjcmlwdG9yc3BlYyBJbmRleGVkIGFycmF5IG9mIGRlc2NyaXB0b3IgbnVtYmVycyBhbmQgdGhlaXIgdmFsdWVzLgogKiBAcGFyYW0gYXJyYXkgICYkcGlwZXMgICAgICAgICBJbmRleGVkIGFycmF5IG9mIGZpbGUgcG9pbnRlcnMgdGhhdCBjb3JyZXNwb25kIHRvIFBIUCdzIGVuZCBvZiBhbnkgcGlwZXMgdGhhdCBhcmUgY3JlYXRlZC4KICogQHBhcmFtIHN0cmluZyAkY3dkICAgICAgICAgICAgSW5pdGlhbCB3b3JraW5nIGRpcmVjdG9yeSBmb3IgdGhlIGNvbW1hbmQuCiAqIEBwYXJhbSBhcnJheSAgJGVudiAgICAgICAgICAgIEFycmF5IG9mIGVudmlyb25tZW50IHZhcmlhYmxlcy4KICogQHBhcmFtIGFycmF5ICAkb3RoZXJfb3B0aW9ucyAgQXJyYXkgb2YgYWRkaXRpb25hbCBvcHRpb25zIChXaW5kb3dzIG9ubHkpLgogKiBAcmV0dXJuIHJlc291cmNlIENvbW1hbmQgc3RyaXBwZWQgb2YgYW55IGVudmlyb25tZW50IHZhcmlhYmxlIHNldHRpbmdzLgogKi8KZnVuY3Rpb24gcHJvY19vcGVuX2NvbXBhdCggJGNtZCwgJGRlc2NyaXB0b3JzcGVjLCAmJHBpcGVzLCAkY3dkID0gbnVsbCwgJGVudiA9IG51bGwsICRvdGhlcl9vcHRpb25zID0gbnVsbCApIHsKCWlmICggaXNfd2luZG93cygpICkgewoJCS8vIE5lZWQgdG8gZW5jb21wYXNzIHRoZSB3aG9sZSBjb21tYW5kIGluIGRvdWJsZSBxdW90ZXMgLSBQSFAgYnVnIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NDkxMzkKCQkkY21kID0gJyInIC4gX3Byb2Nfb3Blbl9jb21wYXRfd2luX2VudiggJGNtZCwgJGVudiApIC4gJyInOwoJfQoJcmV0dXJuIHByb2Nfb3BlbiggJGNtZCwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMsICRjd2QsICRlbnYsICRvdGhlcl9vcHRpb25zICk7Cn0KCi8qKgogKiBGb3IgdXNlIGJ5IGBwcm9jX29wZW5fY29tcGF0KClgIG9ubHkuIFNlcGFyYXRlZCBvdXQgZm9yIGVhc2Ugb2YgdGVzdGluZy4gV2luZG93cyBvbmx5LgogKiBUdXJucyAqbml4LWxpa2UgYEVOVl9WQVI9YmxhaCBjb21tYW5kYCBlbnZpcm9ubWVudCB2YXJpYWJsZSBwcmVmaXhlcyBpbnRvIHN0cmlwcGVkIGBjbWRgIHdpdGggcHJlZml4ZWQgZW52aXJvbm1lbnQgdmFyaWFibGVzIGFkZGVkIHRvIHBhc3NlZCBpbiBlbnZpcm9ubWVudCBhcnJheS4KICoKICogQGFjY2VzcyBwcml2YXRlCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNtZCBDb21tYW5kIHRvIGV4ZWN1dGUuCiAqIEBwYXJhbSBhcnJheSAmJGVudiBBcnJheSBvZiBleGlzdGluZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMuIFdpbGwgYmUgbW9kaWZpZWQgaWYgYW55IHNldHRpbmdzIGluIGNvbW1hbmQuCiAqIEByZXR1cm4gc3RyaW5nIENvbW1hbmQgc3RyaXBwZWQgb2YgYW55IGVudmlyb25tZW50IHZhcmlhYmxlIHNldHRpbmdzLgogKi8KZnVuY3Rpb24gX3Byb2Nfb3Blbl9jb21wYXRfd2luX2VudiggJGNtZCwgJiRlbnYgKSB7CglpZiAoIGZhbHNlICE9PSBzdHJwb3MoICRjbWQsICc9JyApICkgewoJCXdoaWxlICggcHJlZ19tYXRjaCggJy9eKFtBLVphLXpfXVtBLVphLXowLTlfXSopPSgiW14iXSoifFteIF0qKSAvJywgJGNtZCwgJG1hdGNoZXMgKSApIHsKCQkJJGNtZCA9IHN1YnN0ciggJGNtZCwgc3RybGVuKCAkbWF0Y2hlc1swXSApICk7CgkJCWlmICggbnVsbCA9PT0gJGVudiApIHsKCQkJCSRlbnYgPSBbXTsKCQkJfQoJCQkkZW52WyAkbWF0Y2hlc1sxXSBdID0gaXNzZXQoICRtYXRjaGVzWzJdWzBdICkgJiYgJyInID09PSAkbWF0Y2hlc1syXVswXSA/IHN1YnN0ciggJG1hdGNoZXNbMl0sIDEsIC0xICkgOiAkbWF0Y2hlc1syXTsKCQl9Cgl9CglyZXR1cm4gJGNtZDsKfQoKLyoqCiAqIEZpcnN0IGhhbGYgb2YgZXNjYXBpbmcgZm9yIExJS0Ugc3BlY2lhbCBjaGFyYWN0ZXJzICUgYW5kIF8gYmVmb3JlIHByZXBhcmluZyBmb3IgTXlTUUwuCiAqCiAqIFVzZSB0aGlzIG9ubHkgYmVmb3JlIHdwZGI6OnByZXBhcmUoKSBvciBlc2Nfc3FsKCkuICBSZXZlcnNpbmcgdGhlIG9yZGVyIGlzIHZlcnkgYmFkIGZvciBzZWN1cml0eS4KICoKICogQ29waWVkIGZyb20gY29yZSAid3AtaW5jbHVkZXMvd3AtZGIucGhwIi4gQXZvaWRzIGRlcGVuZGVuY3kgb24gV1AgNC40IHdwZGIuCiAqCiAqIEBhY2Nlc3MgcHVibGljCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHRleHQgVGhlIHJhdyB0ZXh0IHRvIGJlIGVzY2FwZWQuIFRoZSBpbnB1dCB0eXBlZCBieSB0aGUgdXNlciBzaG91bGQgaGF2ZSBubwogKiAgICAgICAgICAgICAgICAgICAgIGV4dHJhIG9yIGRlbGV0ZWQgc2xhc2hlcy4KICogQHJldHVybiBzdHJpbmcgVGV4dCBpbiB0aGUgZm9ybSBvZiBhIExJS0UgcGhyYXNlLiBUaGUgb3V0cHV0IGlzIG5vdCBTUUwgc2FmZS4gQ2FsbCAkd3BkYjo6cHJlcGFyZSgpCiAqICAgICAgICAgICAgICAgIG9yIHJlYWxfZXNjYXBlIG5leHQuCiAqLwpmdW5jdGlvbiBlc2NfbGlrZSggJHRleHQgKSB7CglyZXR1cm4gYWRkY3NsYXNoZXMoICR0ZXh0LCAnXyVcXCcgKTsKfQoKLyoqCiAqIEVzY2FwZXMgKGJhY2t0aWNrcykgTXlTUUwgaWRlbnRpZmllcnMgKGFrYSBzY2hlbWEgb2JqZWN0IG5hbWVzKSAtIGkuZS4gY29sdW1uIG5hbWVzLCB0YWJsZSBuYW1lcywgYW5kIGRhdGFiYXNlL2luZGV4L2FsaWFzL3ZpZXcgZXRjIG5hbWVzLgogKiBTZWUgaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS41L2VuL2lkZW50aWZpZXJzLmh0bWwKICoKICogQHBhcmFtICBzdHJpbmd8YXJyYXkgJGlkZW50cyBBIHNpbmdsZSBpZGVudGlmaWVyIG9yIGFuIGFycmF5IG9mIGlkZW50aWZpZXJzLgogKiBAcmV0dXJuIHN0cmluZ3xhcnJheSBBbiBlc2NhcGVkIHN0cmluZyBpZiBnaXZlbiBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2YgZXNjYXBlZCBzdHJpbmdzIGlmIGdpdmVuIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqLwpmdW5jdGlvbiBlc2Nfc3FsX2lkZW50KCAkaWRlbnRzICkgewoJJGJhY2t0aWNrID0gc3RhdGljIGZ1bmN0aW9uICggJHYgKSB7CgkJLy8gRXNjYXBlIGFueSBiYWNrdGlja3MgaW4gdGhlIGlkZW50aWZpZXIgYnkgZG91YmxpbmcuCgkJcmV0dXJuICdgJyAuIHN0cl9yZXBsYWNlKCAnYCcsICdgYCcsICR2ICkgLiAnYCc7Cgl9OwoJaWYgKCBpc19zdHJpbmcoICRpZGVudHMgKSApIHsKCQlyZXR1cm4gJGJhY2t0aWNrKCAkaWRlbnRzICk7Cgl9CglyZXR1cm4gYXJyYXlfbWFwKCAkYmFja3RpY2ssICRpZGVudHMgKTsKfQoKLyoqCiAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBzdHJpbmcgaXMgYSB2YWxpZCBKU09OIHJlcHJlc2VudGF0aW9uLgogKgogKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudCAgICAgICBTdHJpbmcgdG8gZXZhbHVhdGUuCiAqIEBwYXJhbSBib29sICAgJGlnbm9yZV9zY2FsYXJzIE9wdGlvbmFsLiBXaGV0aGVyIHRvIGlnbm9yZSBzY2FsYXIgdmFsdWVzLgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB0cnVlLgogKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgcHJvdmlkZWQgc3RyaW5nIGlzIGEgdmFsaWQgSlNPTiByZXByZXNlbnRhdGlvbi4KICovCmZ1bmN0aW9uIGlzX2pzb24oICRhcmd1bWVudCwgJGlnbm9yZV9zY2FsYXJzID0gdHJ1ZSApIHsKCWlmICggISBpc19zdHJpbmcoICRhcmd1bWVudCApIHx8ICcnID09PSAkYXJndW1lbnQgKSB7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCWlmICggJGlnbm9yZV9zY2FsYXJzICYmICEgaW5fYXJyYXkoICRhcmd1bWVudFswXSwgWyAneycsICdbJyBdLCB0cnVlICkgKSB7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCWpzb25fZGVjb2RlKCAkYXJndW1lbnQsICRhc3NvYyA9IHRydWUgKTsKCglyZXR1cm4ganNvbl9sYXN0X2Vycm9yKCkgPT09IEpTT05fRVJST1JfTk9ORTsKfQoKLyoqCiAqIFBhcnNlIGtub3duIHNoZWxsIGFycmF5cyBpbmNsdWRlZCBpbiB0aGUgJGFzc29jX2FyZ3MgYXJyYXkuCiAqCiAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyAgICAgIEFzc29jaWF0aXZlIGFycmF5IG9mIGFyZ3VtZW50cy4KICogQHBhcmFtIGFycmF5ICRhcnJheV9hcmd1bWVudHMgQXJyYXkgb2YgYXJndW1lbnQga2V5cyB0aGF0IHNob3VsZCByZWNlaXZlIGFuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5IHRocm91Z2ggdGhlIHNoZWxsLgogKiBAcmV0dXJuIGFycmF5CiAqLwpmdW5jdGlvbiBwYXJzZV9zaGVsbF9hcnJheXMoICRhc3NvY19hcmdzLCAkYXJyYXlfYXJndW1lbnRzICkgewoJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3MgKSB8fCBlbXB0eSggJGFycmF5X2FyZ3VtZW50cyApICkgewoJCXJldHVybiAkYXNzb2NfYXJnczsKCX0KCglmb3JlYWNoICggJGFycmF5X2FyZ3VtZW50cyBhcyAka2V5ICkgewoJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgJGFzc29jX2FyZ3MgKSAmJiBpc19qc29uKCAkYXNzb2NfYXJnc1sgJGtleSBdICkgKSB7CgkJCSRhc3NvY19hcmdzWyAka2V5IF0gPSBqc29uX2RlY29kZSggJGFzc29jX2FyZ3NbICRrZXkgXSwgJGFzc29jID0gdHJ1ZSApOwoJCX0KCX0KCglyZXR1cm4gJGFzc29jX2FyZ3M7Cn0KCi8qKgogKiBEZXNjcmliZSBhIGNhbGxhYmxlIGFzIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gY2FsbGFibGUgJGNhbGxhYmxlIFRoZSBjYWxsYWJsZSB0byBkZXNjcmliZS4KICogQHJldHVybiBzdHJpbmcgU3RyaW5nIGRlc2NyaXB0aW9uIG9mIHRoZSBjYWxsYWJsZS4KICovCmZ1bmN0aW9uIGRlc2NyaWJlX2NhbGxhYmxlKCAkY2FsbGFibGUgKSB7Cgl0cnkgewoJCWlmICggJGNhbGxhYmxlIGluc3RhbmNlb2YgQ2xvc3VyZSApIHsKCQkJJHJlZmxlY3Rpb24gPSBuZXcgUmVmbGVjdGlvbkZ1bmN0aW9uKCAkY2FsbGFibGUgKTsKCgkJCXJldHVybiAiQ2xvc3VyZSBpbiBmaWxlIHskcmVmbGVjdGlvbi0+Z2V0RmlsZU5hbWUoKX0gYXQgbGluZSB7JHJlZmxlY3Rpb24tPmdldFN0YXJ0TGluZSgpfSI7CgkJfQoKCQlpZiAoIGlzX2FycmF5KCAkY2FsbGFibGUgKSApIHsKCQkJaWYgKCBpc19vYmplY3QoICRjYWxsYWJsZVswXSApICkgewoJCQkJcmV0dXJuIHNwcmludGYoCgkJCQkJJyVzLT4lcygpJywKCQkJCQlnZXRfY2xhc3MoICRjYWxsYWJsZVswXSApLAoJCQkJCSRjYWxsYWJsZVsxXQoJCQkJKTsKCQkJfQoKCQkJcmV0dXJuIHNwcmludGYoICclczo6JXMoKScsICRjYWxsYWJsZVswXSwgJGNhbGxhYmxlWzFdICk7CgkJfQoKCQlyZXR1cm4gZ2V0dHlwZSggJGNhbGxhYmxlICk7Cgl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJcmV0dXJuICdDYWxsYWJsZSBvZiB1bmtub3duIHR5cGUnOwoJfQp9CgovKioKICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBjbGFzcyBhbmQgbWV0aG9kIHBhaXIgaXMgYSB2YWxpZCBjYWxsYWJsZS4KICoKICogVGhpcyBhY2NvbW1vZGF0ZXMgY2hhbmdlcyB0byBgaXNfY2FsbGFibGUoKWAgaW4gUEhQIDggdGhhdCBtZWFuIGFuIGFycmF5IG9mIGEKICogY2xhc3NuYW1lIGFuZCBpbnN0YW5jZSBtZXRob2QgaXMgbm8gbG9uZ2VyIGNhbGxhYmxlLgogKgogKiBAcGFyYW0gYXJyYXkgJHBhaXIgVGhlIGNsYXNzIGFuZCBtZXRob2QgcGFpciB0byBjaGVjay4KICogQHJldHVybiBib29sCiAqLwpmdW5jdGlvbiBpc192YWxpZF9jbGFzc19hbmRfbWV0aG9kX3BhaXIoICRwYWlyICkgewoJaWYgKCAhIGlzX2FycmF5KCAkcGFpciApIHx8IDIgIT09IGNvdW50KCAkcGFpciApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglpZiAoICEgaXNfc3RyaW5nKCAkcGFpclswXSApIHx8ICEgaXNfc3RyaW5nKCAkcGFpclsxXSApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglpZiAoICEgY2xhc3NfZXhpc3RzKCAkcGFpclswXSApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglpZiAoICEgbWV0aG9kX2V4aXN0cyggJHBhaXJbMF0sICRwYWlyWzFdICkgKSB7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXJldHVybiB0cnVlOwp9CgovKioKICogUGx1cmFsaXplcyBhIG5vdW4gaW4gYSBncmFtbWF0aWNhbGx5IGNvcnJlY3Qgd2F5LgogKgogKiBAcGFyYW0gc3RyaW5nICAgJG5vdW4gIE5vdW4gdG8gYmUgcGx1cmFsaXplZC4gTmVlZHMgdG8gYmUgaW4gc2luZ3VsYXIgZm9ybS4KICogQHBhcmFtIGludHxudWxsICRjb3VudCBPcHRpb25hbC4gQ291bnQgb2YgdGhlIG5vdW5zLCB0byBkZWNpZGUgd2hldGhlciB0bwogKiAgICAgICAgICAgICAgICAgICAgICAgIHBsdXJhbGl6ZS4gV2lsbCBwbHVyYWxpemUgdW5jb25kaXRpb25hbGx5IGlmIG5vbmUKICogICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlZC4KICogQHJldHVybiBzdHJpbmcgUGx1cmFsaXplZCBub3VuLgogKi8KZnVuY3Rpb24gcGx1cmFsaXplKCAkbm91biwgJGNvdW50ID0gbnVsbCApIHsKCWlmICggMSA9PT0gJGNvdW50ICkgewoJCXJldHVybiAkbm91bjsKCX0KCglyZXR1cm4gSW5mbGVjdG9yOjpwbHVyYWxpemUoICRub3VuICk7Cn0KCi8qKgogKiBHZXQgdGhlIHBhdGggdG8gdGhlIG15c3FsIGJpbmFyeS4KICoKICogQHJldHVybiBzdHJpbmcgUGF0aCB0byB0aGUgbXlzcWwgYmluYXJ5LCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90IGZvdW5kLgogKi8KZnVuY3Rpb24gZ2V0X215c3FsX2JpbmFyeV9wYXRoKCkgewoJc3RhdGljICRwYXRoID0gbnVsbDsKCglpZiAoIG51bGwgPT09ICRwYXRoICkgewoJCSRyZXN1bHQgPSBQcm9jZXNzOjpjcmVhdGUoICcvdXNyL2Jpbi9lbnYgd2hpY2ggbXlzcWwnLCBudWxsLCBudWxsICktPnJ1bigpOwoKCQlpZiAoIDAgIT09ICRyZXN1bHQtPnJldHVybl9jb2RlICkgewoJCQkkcGF0aCA9ICcnOwoJCX0gZWxzZSB7CgkJCSRwYXRoID0gdHJpbSggJHJlc3VsdC0+c3Rkb3V0ICk7CgkJfQoJfQoKCXJldHVybiAkcGF0aDsKfQoKLyoqCiAqIEdldCB0aGUgdmVyc2lvbiBvZiB0aGUgTXlTUUwgZGF0YWJhc2UuCiAqCiAqIEByZXR1cm4gc3RyaW5nIFZlcnNpb24gb2YgdGhlIE15U1FMIGRhdGFiYXNlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90CiAqICAgICAgICAgICAgICAgIGZvdW5kLgogKi8KZnVuY3Rpb24gZ2V0X215c3FsX3ZlcnNpb24oKSB7CglzdGF0aWMgJHZlcnNpb24gPSBudWxsOwoKCWlmICggbnVsbCA9PT0gJHZlcnNpb24gKSB7CgkJJHJlc3VsdCA9IFByb2Nlc3M6OmNyZWF0ZSggJy91c3IvYmluL2VudiBteXNxbCAtLXZlcnNpb24nLCBudWxsLCBudWxsICktPnJ1bigpOwoKCQlpZiAoIDAgIT09ICRyZXN1bHQtPnJldHVybl9jb2RlICkgewoJCQkkdmVyc2lvbiA9ICcnOwoJCX0gZWxzZSB7CgkJCSR2ZXJzaW9uID0gdHJpbSggJHJlc3VsdC0+c3Rkb3V0ICk7CgkJfQoJfQoKCXJldHVybiAkdmVyc2lvbjsKfQoKLyoqCiAqIEdldCB0aGUgU1FMIG1vZGVzIG9mIHRoZSBNeVNRTCBzZXNzaW9uLgogKgogKiBAcmV0dXJuIHN0cmluZ1tdIEFycmF5IG9mIFNRTCBtb2Rlcywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdGhleSBjb3VsZG4ndCBiZQogKiAgICAgICAgICAgICAgICAgIHJlYWQuCiAqLwpmdW5jdGlvbiBnZXRfc3FsX21vZGVzKCkgewoJc3RhdGljICRzcWxfbW9kZXMgPSBudWxsOwoKCWlmICggbnVsbCA9PT0gJHNxbF9tb2RlcyApIHsKCQkkcmVzdWx0ID0gUHJvY2Vzczo6Y3JlYXRlKCAnL3Vzci9iaW4vZW52IG15c3FsIC0tbm8tYXV0by1yZWhhc2ggLS1iYXRjaCAtLXNraXAtY29sdW1uLW5hbWVzIC0tZXhlY3V0ZT0iU0VMRUNUIEBAU0VTU0lPTi5zcWxfbW9kZSInLCBudWxsLCBudWxsICktPnJ1bigpOwoKCQlpZiAoIDAgIT09ICRyZXN1bHQtPnJldHVybl9jb2RlICkgewoJCQkkc3FsX21vZGVzID0gW107CgkJfSBlbHNlIHsKCQkJJHNxbF9tb2RlcyA9IGFycmF5X2ZpbHRlcigKCQkJCWFycmF5X21hcCgKCQkJCQkndHJpbScsCgkJCQkJcHJlZ19zcGxpdCggIi9cclxufFxufFxyLyIsICRyZXN1bHQtPnN0ZG91dCApCgkJCQkpCgkJCSk7CgkJfQoJfQoKCXJldHVybiAkc3FsX21vZGVzOwp9Cjw/cGhwCgovKioKICogVGhpcyBmaWxlIGNvbnRhaW5zIGZhbGxiYWNrIGZ1bmN0aW9ucyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBkaXNhYmxlZCBidXQgYXJlIHJlcXVpcmVkIG5ldmVydGhlbGVzcy4KICovCgppZiAoIFBIUF9NQUpPUl9WRVJTSU9OID49IDggJiYgISBmdW5jdGlvbl9leGlzdHMoICdpbmlfc2V0JyApICkgewoJZnVuY3Rpb24gaW5pX3NldCggJG9wdGlvbiwgJHZhbHVlICkgewoJCXJldHVybiBmYWxzZTsKCX0KfQo8P3BocAoKLy8gVXRpbGl0aWVzIHRoYXQgZGVwZW5kIG9uIFdvcmRQcmVzcyBjb2RlLgoKbmFtZXNwYWNlIFdQX0NMSVxVdGlsczsKCnVzZSBSZWZsZWN0aW9uQ2xhc3M7CnVzZSBSZWZsZWN0aW9uUGFyYW1ldGVyOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFVwZ3JhZGVyU2tpbjsKCmZ1bmN0aW9uIHdwX25vdF9pbnN0YWxsZWQoKSB7CglnbG9iYWwgJHdwZGIsICR0YWJsZV9wcmVmaXg7CglpZiAoICEgaXNfYmxvZ19pbnN0YWxsZWQoKSAmJiAhIGRlZmluZWQoICdXUF9JTlNUQUxMSU5HJyApICkgewoJCSR0YWJsZXMgICAgICAgICA9ICR3cGRiLT5nZXRfY29sKCAiU0hPVyBUQUJMRVMgTElLRSAnJV9vcHRpb25zJyIgKTsKCQkkZm91bmRfcHJlZml4ZXMgPSBbXTsKCQlpZiAoIGNvdW50KCAkdGFibGVzICkgKSB7CgkJCWZvcmVhY2ggKCAkdGFibGVzIGFzICR0YWJsZSApIHsKCQkJCSRtYXliZV9wcmVmaXggPSBzdWJzdHIoICR0YWJsZSwgMCwgLSBzdHJsZW4oICdvcHRpb25zJyApICk7CgkJCQlpZiAoICRtYXliZV9wcmVmaXggIT09ICR0YWJsZV9wcmVmaXggKSB7CgkJCQkJJGZvdW5kX3ByZWZpeGVzW10gPSAkbWF5YmVfcHJlZml4OwoJCQkJfQoJCQl9CgkJfQoJCWlmICggY291bnQoICRmb3VuZF9wcmVmaXhlcyApICkgewoJCQkkcHJlZml4X2xpc3QgICA9IGltcGxvZGUoICcsICcsICRmb3VuZF9wcmVmaXhlcyApOwoJCQkkaW5zdGFsbF9sYWJlbCA9IGNvdW50KCAkZm91bmRfcHJlZml4ZXMgKSA+IDEgPyAnaW5zdGFsbGF0aW9ucycgOiAnaW5zdGFsbGF0aW9uJzsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGUgc2l0ZSB5b3UgaGF2ZSByZXF1ZXN0ZWQgaXMgbm90IGluc3RhbGxlZC5cbiIgLgoJCQkJIllvdXIgdGFibGUgcHJlZml4IGlzICd7JHRhYmxlX3ByZWZpeH0nLiBGb3VuZCB7JGluc3RhbGxfbGFiZWx9IHdpdGggdGFibGUgcHJlZml4OiB7JHByZWZpeF9saXN0fS5cbiIgLgoJCQkJJ09yLCBydW4gYHdwIGNvcmUgaW5zdGFsbGAgdG8gY3JlYXRlIGRhdGFiYXNlIHRhYmxlcy4nCgkJCSk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGUgc2l0ZSB5b3UgaGF2ZSByZXF1ZXN0ZWQgaXMgbm90IGluc3RhbGxlZC5cbiIgLgoJCQkJJ1J1biBgd3AgY29yZSBpbnN0YWxsYCB0byBjcmVhdGUgZGF0YWJhc2UgdGFibGVzLicKCQkJKTsKCQl9Cgl9Cn0KCi8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLlBIUC5JbmlTZXQgLS0gSW50ZW50aW9uYWwgJiBjb3JyZWN0IHVzYWdlLgpmdW5jdGlvbiB3cF9kZWJ1Z19tb2RlKCkgewoJaWYgKCBXUF9DTEk6OmdldF9jb25maWcoICdkZWJ1ZycgKSApIHsKCQlpZiAoICEgZGVmaW5lZCggJ1dQX0RFQlVHJyApICkgewoJCQlkZWZpbmUoICdXUF9ERUJVRycsIHRydWUgKTsKCQl9CgoJCWVycm9yX3JlcG9ydGluZyggRV9BTEwgJiB+RV9ERVBSRUNBVEVEICYgfkVfU1RSSUNUICk7Cgl9IGVsc2UgewoJCWlmICggV1BfREVCVUcgKSB7CgkJCWVycm9yX3JlcG9ydGluZyggRV9BTEwgKTsKCgkJCWlmICggV1BfREVCVUdfRElTUExBWSApIHsKCQkJCWluaV9zZXQoICdkaXNwbGF5X2Vycm9ycycsIDEgKTsKCQkJfSBlbHNlaWYgKCBudWxsICE9PSBXUF9ERUJVR19ESVNQTEFZICkgewoJCQkJaW5pX3NldCggJ2Rpc3BsYXlfZXJyb3JzJywgMCApOwoJCQl9CgoJCQlpZiAoIFdQX0RFQlVHX0xPRyApIHsKCQkJCWluaV9zZXQoICdsb2dfZXJyb3JzJywgMSApOwoJCQkJaW5pX3NldCggJ2Vycm9yX2xvZycsIFdQX0NPTlRFTlRfRElSIC4gJy9kZWJ1Zy5sb2cnICk7CgkJCX0KCQl9IGVsc2UgewoJCQllcnJvcl9yZXBvcnRpbmcoIEVfQ09SRV9FUlJPUiB8IEVfQ09SRV9XQVJOSU5HIHwgRV9DT01QSUxFX0VSUk9SIHwgRV9FUlJPUiB8IEVfV0FSTklORyB8IEVfUEFSU0UgfCBFX1VTRVJfRVJST1IgfCBFX1VTRVJfV0FSTklORyB8IEVfUkVDT1ZFUkFCTEVfRVJST1IgKTsKCQl9CgoJCWlmICggZGVmaW5lZCggJ1hNTFJQQ19SRVFVRVNUJyApIHx8IGRlZmluZWQoICdSRVNUX1JFUVVFU1QnICkgfHwgKCBkZWZpbmVkKCAnRE9JTkdfQUpBWCcgKSAmJiBET0lOR19BSkFYICkgKSB7CgkJCWluaV9zZXQoICdkaXNwbGF5X2Vycm9ycycsIDAgKTsKCQl9Cgl9CgoJLy8gWERlYnVnIGFscmVhZHkgc2VuZHMgZXJyb3JzIHRvIFNUREVSUi4KCWluaV9zZXQoICdkaXNwbGF5X2Vycm9ycycsIGZ1bmN0aW9uX2V4aXN0cyggJ3hkZWJ1Z19kZWJ1Z196dmFsJyApID8gZmFsc2UgOiAnU1RERVJSJyApOwp9Ci8vIHBocGNzOmVuYWJsZQoKZnVuY3Rpb24gcmVwbGFjZV93cF9kaWVfaGFuZGxlcigpIHsKCVxyZW1vdmVfZmlsdGVyKCAnd3BfZGllX2hhbmRsZXInLCAnX2RlZmF1bHRfd3BfZGllX2hhbmRsZXInICk7CglcYWRkX2ZpbHRlcigKCQknd3BfZGllX2hhbmRsZXInLAoJCWZ1bmN0aW9uKCkgewoJCQlyZXR1cm4gX19OQU1FU1BBQ0VfXyAuICdcXHdwX2RpZV9oYW5kbGVyJzsKCQl9CgkpOwp9CgpmdW5jdGlvbiB3cF9kaWVfaGFuZGxlciggJG1lc3NhZ2UgKSB7CglpZiAoICRtZXNzYWdlIGluc3RhbmNlb2YgXFdQX0Vycm9yICkgewoJCSRtZXNzYWdlID0gJG1lc3NhZ2UtPmdldF9lcnJvcl9tZXNzYWdlKCk7Cgl9CgoJJG1lc3NhZ2UgPSB3cF9jbGVhbl9lcnJvcl9tZXNzYWdlKCAkbWVzc2FnZSApOwoKCVdQX0NMSTo6ZXJyb3IoICRtZXNzYWdlICk7Cn0KCi8qKgogKiBDbGVhbiBIVE1MIGVycm9yIG1lc3NhZ2Ugc28gc3VpdGFibGUgZm9yIHRleHQgZGlzcGxheS4KICovCmZ1bmN0aW9uIHdwX2NsZWFuX2Vycm9yX21lc3NhZ2UoICRtZXNzYWdlICkgewoJJG9yaWdpbmFsX21lc3NhZ2UgPSB0cmltKCAkbWVzc2FnZSApOwoJJG1lc3NhZ2UgICAgICAgICAgPSAkb3JpZ2luYWxfbWVzc2FnZTsKCWlmICggcHJlZ19tYXRjaCggJ3xeXDxoMT4oLis/KTwvaDE+fCcsICRvcmlnaW5hbF9tZXNzYWdlLCAkbWF0Y2hlcyApICkgewoJCSRtZXNzYWdlID0gJG1hdGNoZXNbMV0gLiAnLic7Cgl9CglpZiAoIHByZWdfbWF0Y2goICd8XDxwPiguKz8pPC9wPnwnLCAkb3JpZ2luYWxfbWVzc2FnZSwgJG1hdGNoZXMgKSApIHsKCQkkbWVzc2FnZSAuPSAnICcgLiAkbWF0Y2hlc1sxXTsKCX0KCgkkc2VhcmNoX3JlcGxhY2UgPSBbCgkJJzxjb2RlPicgID0+ICdgJywKCQknPC9jb2RlPicgPT4gJ2AnLAoJXTsKCSRtZXNzYWdlICAgICAgICA9IHN0cl9yZXBsYWNlKCBhcnJheV9rZXlzKCAkc2VhcmNoX3JlcGxhY2UgKSwgYXJyYXlfdmFsdWVzKCAkc2VhcmNoX3JlcGxhY2UgKSwgJG1lc3NhZ2UgKTsKCSRtZXNzYWdlICAgICAgICA9IG5hbWVzcGFjZVxzdHJpcF90YWdzKCAkbWVzc2FnZSApOwoJJG1lc3NhZ2UgICAgICAgID0gaHRtbF9lbnRpdHlfZGVjb2RlKCAkbWVzc2FnZSwgRU5UX0NPTVBBVCwgJ1VURi04JyApOwoKCXJldHVybiAkbWVzc2FnZTsKfQoKZnVuY3Rpb24gd3BfcmVkaXJlY3RfaGFuZGxlciggJHVybCApIHsKCVdQX0NMSTo6d2FybmluZyggJ1NvbWUgY29kZSBpcyB0cnlpbmcgdG8gZG8gYSBVUkwgcmVkaXJlY3QuIEJhY2t0cmFjZTonICk7CgoJb2Jfc3RhcnQoKTsKCWRlYnVnX3ByaW50X2JhY2t0cmFjZSgpOwoJZndyaXRlKCBTVERFUlIsIG9iX2dldF9jbGVhbigpICk7CgoJcmV0dXJuICR1cmw7Cn0KCmZ1bmN0aW9uIG1heWJlX3JlcXVpcmUoICRzaW5jZSwgJHBhdGggKSB7CglpZiAoIHdwX3ZlcnNpb25fY29tcGFyZSggJHNpbmNlLCAnPj0nICkgKSB7CgkJcmVxdWlyZSAkcGF0aDsKCX0KfQoKZnVuY3Rpb24gZ2V0X3VwZ3JhZGVyKCAkY2xhc3MsICRpbnNlY3VyZSA9IGZhbHNlICkgewoJaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1xXUF9VcGdyYWRlcicgKSApIHsKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9jbGFzcy13cC11cGdyYWRlci5waHAnOwoJfQoKCSR1c2VzX2luc2VjdXJlX2ZsYWcgPSBmYWxzZTsKCgkkcmVmbGVjdGlvbiA9IG5ldyBSZWZsZWN0aW9uQ2xhc3MoICRjbGFzcyApOwoJaWYgKCAkcmVmbGVjdGlvbiApIHsKCQkkY29uc3RydWN0b3IgPSAkcmVmbGVjdGlvbi0+Z2V0Q29uc3RydWN0b3IoKTsKCQlpZiAoICRjb25zdHJ1Y3RvciApIHsKCQkJJGFyZ3VtZW50cyA9ICRjb25zdHJ1Y3Rvci0+Z2V0UGFyYW1ldGVycygpOwoJCQkvKiogQHZhciBSZWZsZWN0aW9uUGFyYW1ldGVyICRhcmd1bWVudCAqLwoJCQlmb3JlYWNoICggJGFyZ3VtZW50cyBhcyAkYXJndW1lbnQgKSB7CgkJCQlpZiAoICdpbnNlY3VyZScgPT09ICRhcmd1bWVudC0+bmFtZSApIHsKCQkJCQkkdXNlc19pbnNlY3VyZV9mbGFnID0gdHJ1ZTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KCglpZiAoICR1c2VzX2luc2VjdXJlX2ZsYWcgKSB7CgkJcmV0dXJuIG5ldyAkY2xhc3MoIG5ldyBVcGdyYWRlclNraW4oKSwgJGluc2VjdXJlICk7Cgl9IGVsc2UgewoJCXJldHVybiBuZXcgJGNsYXNzKCBuZXcgVXBncmFkZXJTa2luKCkgKTsKCX0KfQoKLyoqCiAqIENvbnZlcnRzIGEgcGx1Z2luIGJhc2VuYW1lIGJhY2sgaW50byBhIGZyaWVuZGx5IHNsdWcuCiAqLwpmdW5jdGlvbiBnZXRfcGx1Z2luX25hbWUoICRiYXNlbmFtZSApIHsKCWlmICggZmFsc2UgPT09IHN0cnBvcyggJGJhc2VuYW1lLCAnLycgKSApIHsKCQkkbmFtZSA9IGJhc2VuYW1lKCAkYmFzZW5hbWUsICcucGhwJyApOwoJfSBlbHNlIHsKCQkkbmFtZSA9IGRpcm5hbWUoICRiYXNlbmFtZSApOwoJfQoKCXJldHVybiAkbmFtZTsKfQoKZnVuY3Rpb24gaXNfcGx1Z2luX3NraXBwZWQoICRmaWxlICkgewoJJG5hbWUgPSBnZXRfcGx1Z2luX25hbWUoIHN0cl9yZXBsYWNlKCBXUF9QTFVHSU5fRElSIC4gJy8nLCAnJywgJGZpbGUgKSApOwoKCSRza2lwcGVkX3BsdWdpbnMgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Y29uZmlnWydza2lwLXBsdWdpbnMnXTsKCWlmICggdHJ1ZSA9PT0gJHNraXBwZWRfcGx1Z2lucyApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglpZiAoICEgaXNfYXJyYXkoICRza2lwcGVkX3BsdWdpbnMgKSApIHsKCQkkc2tpcHBlZF9wbHVnaW5zID0gZXhwbG9kZSggJywnLCAkc2tpcHBlZF9wbHVnaW5zICk7Cgl9CgoJcmV0dXJuIGluX2FycmF5KCAkbmFtZSwgYXJyYXlfZmlsdGVyKCAkc2tpcHBlZF9wbHVnaW5zICksIHRydWUgKTsKfQoKZnVuY3Rpb24gZ2V0X3RoZW1lX25hbWUoICRwYXRoICkgewoJcmV0dXJuIGJhc2VuYW1lKCAkcGF0aCApOwp9CgpmdW5jdGlvbiBpc190aGVtZV9za2lwcGVkKCAkcGF0aCApIHsKCSRuYW1lID0gZ2V0X3RoZW1lX25hbWUoICRwYXRoICk7CgoJJHNraXBwZWRfdGhlbWVzID0gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1snc2tpcC10aGVtZXMnXTsKCWlmICggdHJ1ZSA9PT0gJHNraXBwZWRfdGhlbWVzICkgewoJCXJldHVybiB0cnVlOwoJfQoKCWlmICggISBpc19hcnJheSggJHNraXBwZWRfdGhlbWVzICkgKSB7CgkJJHNraXBwZWRfdGhlbWVzID0gZXhwbG9kZSggJywnLCAkc2tpcHBlZF90aGVtZXMgKTsKCX0KCglyZXR1cm4gaW5fYXJyYXkoICRuYW1lLCBhcnJheV9maWx0ZXIoICRza2lwcGVkX3RoZW1lcyApLCB0cnVlICk7Cn0KCi8qKgogKiBSZWdpc3RlciB0aGUgc2lkZWJhciBmb3IgdW51c2VkIHdpZGdldHMuCiAqIENvcmUgZG9lcyB0aGlzIGluIC93cC1hZG1pbi93aWRnZXRzLnBocCwgd2hpY2ggaXNuJ3QgaGVscGZ1bC4KICovCmZ1bmN0aW9uIHdwX3JlZ2lzdGVyX3VudXNlZF9zaWRlYmFyKCkgewoKCXJlZ2lzdGVyX3NpZGViYXIoCgkJWwoJCQknbmFtZScgICAgICAgICAgPT4gX18oICdJbmFjdGl2ZSBXaWRnZXRzJyApLAoJCQknaWQnICAgICAgICAgICAgPT4gJ3dwX2luYWN0aXZlX3dpZGdldHMnLAoJCQknY2xhc3MnICAgICAgICAgPT4gJ2luYWN0aXZlLXNpZGViYXInLAoJCQknZGVzY3JpcHRpb24nICAgPT4gX18oICdEcmFnIHdpZGdldHMgaGVyZSB0byByZW1vdmUgdGhlbSBmcm9tIHRoZSBzaWRlYmFyIGJ1dCBrZWVwIHRoZWlyIHNldHRpbmdzLicgKSwKCQkJJ2JlZm9yZV93aWRnZXQnID0+ICcnLAoJCQknYWZ0ZXJfd2lkZ2V0JyAgPT4gJycsCgkJCSdiZWZvcmVfdGl0bGUnICA9PiAnJywKCQkJJ2FmdGVyX3RpdGxlJyAgID0+ICcnLAoJCV0KCSk7Cgp9CgovKioKICogQXR0ZW1wdHMgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdCBjYWNoZSBpcyBiZWluZyB1c2VkLgogKgogKiBOb3RlIHRoYXQgdGhlIGd1ZXNzZXMgbWFkZSBieSB0aGlzIGZ1bmN0aW9uIGFyZSBiYXNlZCBvbiB0aGUgV1BfT2JqZWN0X0NhY2hlIGNsYXNzZXMKICogdGhhdCBkZWZpbmUgdGhlIDNyZCBwYXJ0eSBvYmplY3QgY2FjaGUgZXh0ZW5zaW9uLiBDaGFuZ2VzIHRvIHRob3NlIGNsYXNzZXMgY291bGQgcmVuZGVyCiAqIHByb2JsZW1zIHdpdGggdGhpcyBmdW5jdGlvbidzIGFiaWxpdHkgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdCBjYWNoZSBpcyBiZWluZyB1c2VkLgogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gd3BfZ2V0X2NhY2hlX3R5cGUoKSB7CglnbG9iYWwgJF93cF91c2luZ19leHRfb2JqZWN0X2NhY2hlLCAkd3Bfb2JqZWN0X2NhY2hlOwoKCWlmICggISBlbXB0eSggJF93cF91c2luZ19leHRfb2JqZWN0X2NhY2hlICkgKSB7CgkJLy8gVGVzdCBmb3IgTWVtY2FjaGVkIFBFQ0wgZXh0ZW5zaW9uIG1lbWNhY2hlZCBvYmplY3QgY2FjaGUgKGh0dHBzOi8vZ2l0aHViLmNvbS90b2xsbWFuei93b3JkcHJlc3MtbWVtY2FjaGVkLWJhY2tlbmQpCgkJaWYgKCBpc3NldCggJHdwX29iamVjdF9jYWNoZS0+bSApICYmICR3cF9vYmplY3RfY2FjaGUtPm0gaW5zdGFuY2VvZiBcTWVtY2FjaGVkICkgewoJCQkkbWVzc2FnZSA9ICdNZW1jYWNoZWQnOwoKCQkJLy8gVGVzdCBmb3IgTWVtY2FjaGUgUEVDTCBleHRlbnNpb24gbWVtY2FjaGVkIG9iamVjdCBjYWNoZSAoaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2V4dGVuZC9wbHVnaW5zL21lbWNhY2hlZC8pCgkJfSBlbHNlaWYgKCBpc3NldCggJHdwX29iamVjdF9jYWNoZS0+bWMgKSApIHsKCQkJJGlzX21lbWNhY2hlID0gdHJ1ZTsKCQkJZm9yZWFjaCAoICR3cF9vYmplY3RfY2FjaGUtPm1jIGFzICRidWNrZXQgKSB7CgkJCQlpZiAoICEgJGJ1Y2tldCBpbnN0YW5jZW9mIFxNZW1jYWNoZSAmJiAhICRidWNrZXQgaW5zdGFuY2VvZiBcTWVtY2FjaGVkICkgewoJCQkJCSRpc19tZW1jYWNoZSA9IGZhbHNlOwoJCQkJfQoJCQl9CgoJCQlpZiAoICRpc19tZW1jYWNoZSApIHsKCQkJCSRtZXNzYWdlID0gJ01lbWNhY2hlJzsKCQkJfQoKCQkJLy8gVGVzdCBmb3IgWGNhY2hlIG9iamVjdCBjYWNoZSAoaHR0cHM6Ly9wbHVnaW5zLnN2bi53b3JkcHJlc3Mub3JnL3hjYWNoZS90cnVuay9vYmplY3QtY2FjaGUucGhwKQoJCX0gZWxzZWlmICggJHdwX29iamVjdF9jYWNoZSBpbnN0YW5jZW9mIFxYQ2FjaGVfT2JqZWN0X0NhY2hlICkgewoJCQkkbWVzc2FnZSA9ICdYY2FjaGUnOwoKCQkJLy8gVGVzdCBmb3IgV2luQ2FjaGUgb2JqZWN0IGNhY2hlIChodHRwczovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvd2luY2FjaGUtb2JqZWN0LWNhY2hlLWJhY2tlbmQvKQoJCX0gZWxzZWlmICggY2xhc3NfZXhpc3RzKCAnV2luQ2FjaGVfT2JqZWN0X0NhY2hlJyApICkgewoJCQkkbWVzc2FnZSA9ICdXaW5DYWNoZSc7CgoJCQkvLyBUZXN0IGZvciBBUEMgb2JqZWN0IGNhY2hlIChodHRwczovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvYXBjLykKCQl9IGVsc2VpZiAoIGNsYXNzX2V4aXN0cyggJ0FQQ19PYmplY3RfQ2FjaGUnICkgKSB7CgkJCSRtZXNzYWdlID0gJ0FQQyc7CgoJCQkvLyBUZXN0IGZvciBXUCBSZWRpcyAoaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3BsdWdpbnMvd3AtcmVkaXMvKQoJCX0gZWxzZWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPnJlZGlzICkgJiYgJHdwX29iamVjdF9jYWNoZS0+cmVkaXMgaW5zdGFuY2VvZiBcUmVkaXMgKSB7CgkJCSRtZXNzYWdlID0gJ1JlZGlzJzsKCgkJCS8vIFRlc3QgZm9yIFJlZGlzIE9iamVjdCBDYWNoZSAoaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3BsdWdpbnMvcmVkaXMtY2FjaGUvKQoJCX0gZWxzZWlmICggbWV0aG9kX2V4aXN0cyggJHdwX29iamVjdF9jYWNoZSwgJ3JlZGlzX2luc3RhbmNlJyApICYmIG1ldGhvZF9leGlzdHMoICR3cF9vYmplY3RfY2FjaGUsICdyZWRpc19zdGF0dXMnICkgKSB7CgkJCSRtZXNzYWdlID0gJ1JlZGlzJzsKCgkJCS8vIFRlc3QgZm9yIFdQIExDYWNoZSBPYmplY3QgY2FjaGUgKGh0dHBzOi8vZ2l0aHViLmNvbS9sY2FjaGUvd3AtbGNhY2hlKQoJCX0gZWxzZWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPmxjYWNoZSApICYmICR3cF9vYmplY3RfY2FjaGUtPmxjYWNoZSBpbnN0YW5jZW9mIFxMQ2FjaGVcSW50ZWdyYXRlZCApIHsKCQkJJG1lc3NhZ2UgPSAnV1AgTENhY2hlJzsKCgkJfSBlbHNlaWYgKCBmdW5jdGlvbl9leGlzdHMoICd3M19pbnN0YW5jZScgKSApIHsKCQkJJGNvbmZpZyAgPSB3M19pbnN0YW5jZSggJ1czX0NvbmZpZycgKTsKCQkJJG1lc3NhZ2UgPSAnVW5rbm93bic7CgoJCQlpZiAoICRjb25maWctPmdldF9ib29sZWFuKCAnb2JqZWN0Y2FjaGUuZW5hYmxlZCcgKSApIHsKCQkJCSRtZXNzYWdlID0gJ1czVEMgJyAuICRjb25maWctPmdldF9zdHJpbmcoICdvYmplY3RjYWNoZS5lbmdpbmUnICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkbWVzc2FnZSA9ICdVbmtub3duJzsKCQl9Cgl9IGVsc2UgewoJCSRtZXNzYWdlID0gJ0RlZmF1bHQnOwoJfQoJcmV0dXJuICRtZXNzYWdlOwp9CgovKioKICogQ2xlYXIgV29yZFByZXNzIGludGVybmFsIG9iamVjdCBjYWNoZXMuCiAqCiAqIEluIGxvbmctcnVubmluZyBzY3JpcHRzLCB0aGUgaW50ZXJuYWwgY2FjaGVzIG9uIGAkd3Bfb2JqZWN0X2NhY2hlYCBhbmQgYCR3cGRiYAogKiBjYW4gZ3JvdyB0byBjb25zdW1lIGdpZ2FieXRlcyBvZiBtZW1vcnkuIFBlcmlvZGljYWxseSBjYWxsaW5nIHRoaXMgdXRpbGl0eQogKiBjYW4gaGVscCB3aXRoIG1lbW9yeSBtYW5hZ2VtZW50LgogKgogKiBAYWNjZXNzIHB1YmxpYwogKiBAY2F0ZWdvcnkgU3lzdGVtCiAqIEBkZXByZWNhdGVkIDEuNS4wCiAqLwpmdW5jdGlvbiB3cF9jbGVhcl9vYmplY3RfY2FjaGUoKSB7CglnbG9iYWwgJHdwZGIsICR3cF9vYmplY3RfY2FjaGU7CgoJJHdwZGItPnF1ZXJpZXMgPSBbXTsKCglpZiAoICEgaXNfb2JqZWN0KCAkd3Bfb2JqZWN0X2NhY2hlICkgKSB7CgkJcmV0dXJuOwoJfQoKCS8vIFRoZSBmb2xsb3dpbmcgYXJlIE1lbWNhY2hlZCAoUmVkdXgpIHBsdWdpbiBzcGVjaWZpYyAoc2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzMxNDYzKS4KCWlmICggaXNzZXQoICR3cF9vYmplY3RfY2FjaGUtPmdyb3VwX29wcyApICkgewoJCSR3cF9vYmplY3RfY2FjaGUtPmdyb3VwX29wcyA9IFtdOwoJfQoJaWYgKCBpc3NldCggJHdwX29iamVjdF9jYWNoZS0+c3RhdHMgKSApIHsKCQkkd3Bfb2JqZWN0X2NhY2hlLT5zdGF0cyA9IFtdOwoJfQoJaWYgKCBpc3NldCggJHdwX29iamVjdF9jYWNoZS0+bWVtY2FjaGVfZGVidWcgKSApIHsKCQkkd3Bfb2JqZWN0X2NhY2hlLT5tZW1jYWNoZV9kZWJ1ZyA9IFtdOwoJfQoJLy8gVXNlZCBieSBgV1BfT2JqZWN0X0NhY2hlYCBhbHNvLgoJaWYgKCBpc3NldCggJHdwX29iamVjdF9jYWNoZS0+Y2FjaGUgKSApIHsKCQkkd3Bfb2JqZWN0X2NhY2hlLT5jYWNoZSA9IFtdOwoJfQp9CgovKioKICogR2V0IGEgc2V0IG9mIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UuCiAqCiAqIEludGVycHJldHMgY29tbW9uIGNvbW1hbmQtbGluZSBvcHRpb25zIGludG8gYSByZXNvbHZlZCBzZXQgb2YgdGFibGUgbmFtZXMuCiAqCiAqIEBwYXJhbSBhcnJheSAkYXJncyBQcm92aWRlZCB0YWJsZSBuYW1lcywgb3IgdGFibGVzIHdpdGggd2lsZGNhcmRzLgogKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgT3B0aW9uYWwgZmxhZ3MgZm9yIGdyb3VwcyBvZiB0YWJsZXMgKGUuZy4gLS1uZXR3b3JrKQogKiBAcmV0dXJuIGFycmF5CiAqLwpmdW5jdGlvbiB3cF9nZXRfdGFibGVfbmFtZXMoICRhcmdzLCAkYXNzb2NfYXJncyA9IFtdICkgewoJZ2xvYmFsICR3cGRiOwoKCSR0YWJsZXMgPSBbXTsKCgkvLyBBYm9ydCBpZiBpbmNvbXBhdGlibGUgYXJncyBzdXBwbGllZC4KCWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYmFzZS10YWJsZXMtb25seScgKSAmJiBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2aWV3cy1vbmx5JyApICkgewoJCVdQX0NMSTo6ZXJyb3IoICdZb3UgY2Fubm90IHN1cHBseSAtLWJhc2UtdGFibGVzLW9ubHkgYW5kIC0tdmlld3Mtb25seSBhdCB0aGUgc2FtZSB0aW1lLicgKTsKCX0KCgkvLyBQcmUtbG9hZCB0YWJsZXMgU1FMIHF1ZXJ5IHdpdGggVmlld3MgcmVzdHJpY3Rpb24gaWYgbmVlZGVkLgoJaWYgKCBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdiYXNlLXRhYmxlcy1vbmx5JyApICkgewoJCSR0YWJsZXNfc3FsID0gJ1NIT1cgRlVMTCBUQUJMRVMgV0hFUkUgVGFibGVfVHlwZSA9ICJCQVNFIFRBQkxFIic7CgoJfSBlbHNlaWYgKCBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2aWV3cy1vbmx5JyApICkgewoJCSR0YWJsZXNfc3FsID0gJ1NIT1cgRlVMTCBUQUJMRVMgV0hFUkUgVGFibGVfVHlwZSA9ICJWSUVXIic7CgoJfQoKCWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsLXRhYmxlcycgKSApIHsKCQlpZiAoIGVtcHR5KCAkdGFibGVzX3NxbCApICkgewoJCQkkdGFibGVzX3NxbCA9ICdTSE9XIFRBQkxFUyc7CgkJfQoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIFF1ZXJ5IGlzIHNhZmUsIHNlZSBhYm92ZS4KCQkkdGFibGVzID0gJHdwZGItPmdldF9jb2woICR0YWJsZXNfc3FsLCAwICk7CgoJfSBlbHNlaWYgKCBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwtdGFibGVzLXdpdGgtcHJlZml4JyApICkgewoJCWlmICggZW1wdHkoICR0YWJsZXNfc3FsICkgKSB7CgkJCSR0YWJsZXNfc3FsID0gJHdwZGItPnByZXBhcmUoICdTSE9XIFRBQkxFUyBMSUtFICVzJywgZXNjX2xpa2UoICR3cGRiLT5nZXRfYmxvZ19wcmVmaXgoKSApIC4gJyUnICk7CgkJfSBlbHNlIHsKCQkJJHRhYmxlc19zcWwgLj0gc3ByaW50ZiggIiBBTkQgJXMgTElLRSAnJXMnIiwgZXNjX3NxbF9pZGVudCggJ1RhYmxlc19pbl8nIC4gJHdwZGItPmRibmFtZSApLCBlc2NfbGlrZSggJHdwZGItPmdldF9ibG9nX3ByZWZpeCgpICkgLiAnJScgKTsKCQl9CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gUXVlcnkgaXMgcHJlcGFyZWQsIHNlZSBhYm92ZS4KCQkkdGFibGVzID0gJHdwZGItPmdldF9jb2woICR0YWJsZXNfc3FsLCAwICk7CgoJfSBlbHNlIHsKCQkkc2NvcGUgPSBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzY29wZScsICdhbGwnICk7CgoJCS8vIE5vdGU6IEJDIGNoYW5nZSAxLjUuMCwgdGFraW5nIHNjb3BlIGludG8gY29uc2lkZXJhdGlvbiBmb3IgbmV0d29yayBhbHNvLgoJCWlmICggZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKSAmJiBpc19tdWx0aXNpdGUoKSApIHsKCQkJJG5ldHdvcmtfZ2xvYmFsX3Njb3BlID0gaW5fYXJyYXkoICRzY29wZSwgWyAnYWxsJywgJ2dsb2JhbCcsICdtc19nbG9iYWwnIF0sIHRydWUgKSA/ICggJ2FsbCcgPT09ICRzY29wZSA/ICdnbG9iYWwnIDogJHNjb3BlICkgOiAnJzsKCQkJJHdwX3RhYmxlcyAgICAgICAgICAgID0gYXJyYXlfdmFsdWVzKCAkd3BkYi0+dGFibGVzKCAkbmV0d29ya19nbG9iYWxfc2NvcGUgKSApOwoJCQlpZiAoIGluX2FycmF5KCAkc2NvcGUsIFsgJ2FsbCcsICdibG9nJyBdLCB0cnVlICkgKSB7CgkJCQkvLyBEbyBkaXJlY3RseSBmb3IgY29tcGF0IHdpdGggb2xkIFdQIHZlcnNpb25zLiBOb3RlOiBwcml2YXRlLCBkZWxldGVkLCBhcmNoaXZlZCBzaXRlcyBhcmUgbm90IGV4Y2x1ZGVkLgoJCQkJJGJsb2dfaWRzID0gJHdwZGItPmdldF9jb2woICJTRUxFQ1QgYmxvZ19pZCBGUk9NICR3cGRiLT5ibG9ncyBXSEVSRSBzaXRlX2lkID0gJHdwZGItPnNpdGVpZCIgKTsKCQkJCWZvcmVhY2ggKCAkYmxvZ19pZHMgYXMgJGJsb2dfaWQgKSB7CgkJCQkJJHdwX3RhYmxlcyA9IGFycmF5X21lcmdlKCAkd3BfdGFibGVzLCBhcnJheV92YWx1ZXMoICR3cGRiLT50YWJsZXMoICdibG9nJywgdHJ1ZSAvKnByZWZpeCovLCAkYmxvZ19pZCApICkgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSR3cF90YWJsZXMgPSBhcnJheV92YWx1ZXMoICR3cGRiLT50YWJsZXMoICRzY29wZSApICk7CgkJfQoKCQlpZiAoICEgZ2xvYmFsX3Rlcm1zX2VuYWJsZWQoKSApIHsKCQkJLy8gT25seSBpbmNsdWRlIHNpdGVjYXRlZ29yaWVzIHdoZW4gaXQncyBhY3R1YWxseSBlbmFibGVkLgoJCQkkd3BfdGFibGVzID0gYXJyYXlfdmFsdWVzKCBhcnJheV9kaWZmKCAkd3BfdGFibGVzLCBbICR3cGRiLT5zaXRlY2F0ZWdvcmllcyBdICkgKTsKCQl9CgoJCS8vIE5vdGU6IEJDIGNoYW5nZSAxLjUuMCwgdGFibGVzIGFyZSBzb3J0ZWQgKHZpYSBUQUJMRVMgdmlldykuCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5Ob3RQcmVwYXJlZCAtLSB1c2VzIGVzY19zcWxfaWRlbnQoKSBhbmQgJHdwZGItPl9lc2NhcGUoKS4KCQkkdGFibGVzID0gJHdwZGItPmdldF9jb2woIHNwcmludGYoICJTSE9XIFRBQkxFUyBXSEVSRSAlcyBJTiAoJyVzJykiLCBlc2Nfc3FsX2lkZW50KCAnVGFibGVzX2luXycgLiAkd3BkYi0+ZGJuYW1lICksIGltcGxvZGUoICInLCAnIiwgJHdwZGItPl9lc2NhcGUoICR3cF90YWJsZXMgKSApICkgKTsKCgkJaWYgKCBnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdiYXNlLXRhYmxlcy1vbmx5JyApIHx8IGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ZpZXdzLW9ubHknICkgKSB7CgkJCS8vIEFwcGx5IFZpZXdzIHJlc3RyaWN0aW9uIGFyZ3MgaWYgbmVlZGVkLgoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIFF1ZXJ5IGlzIHByZXBhcmVkLCBzZWUgYWJvdmUuCgkJCSR2aWV3c19xdWVyeV90YWJsZXMgPSAkd3BkYi0+Z2V0X2NvbCggJHRhYmxlc19zcWwsIDAgKTsKCQkJJHRhYmxlcyAgICAgICAgICAgICA9IGFycmF5X2ludGVyc2VjdCggJHRhYmxlcywgJHZpZXdzX3F1ZXJ5X3RhYmxlcyApOwoJCX0KCX0KCgkvLyBGaWx0ZXIgYnkgYCRhcmdzYC4KCWlmICggJGFyZ3MgKSB7CgkJJGFyZ3NfdGFibGVzID0gW107CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCWlmICggZmFsc2UgIT09IHN0cnBvcyggJGFyZywgJyonICkgfHwgZmFsc2UgIT09IHN0cnBvcyggJGFyZywgJz8nICkgKSB7CgkJCQkkYXJnc190YWJsZXMgPSBhcnJheV9tZXJnZSgKCQkJCQkkYXJnc190YWJsZXMsCgkJCQkJYXJyYXlfZmlsdGVyKAoJCQkJCQkkdGFibGVzLAoJCQkJCQlmdW5jdGlvbiAoICR2ICkgdXNlICggJGFyZyApIHsKCQkJCQkJCXJldHVybiBmbm1hdGNoKCAkYXJnLCAkdiApOwoJCQkJCQl9CgkJCQkJKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCSRhcmdzX3RhYmxlc1tdID0gJGFyZzsKCQkJfQoJCX0KCQkkYXJnc190YWJsZXMgPSBhcnJheV92YWx1ZXMoIGFycmF5X3VuaXF1ZSggJGFyZ3NfdGFibGVzICkgKTsKCQkkdGFibGVzICAgICAgPSBhcnJheV92YWx1ZXMoIGFycmF5X2ludGVyc2VjdCggJHRhYmxlcywgJGFyZ3NfdGFibGVzICkgKTsKCQlpZiAoIGVtcHR5KCAkdGFibGVzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJDb3VsZG4ndCBmaW5kIGFueSB0YWJsZXMgbWF0Y2hpbmc6ICVzIiwgaW1wbG9kZSggJyAnLCAkYXJncyApICkgKTsKCQl9Cgl9CgoJcmV0dXJuICR0YWJsZXM7Cn0KCi8qKgogKiBGYWlsc2FmZSB1c2Ugb2YgdGhlIFdvcmRQcmVzcyB3cF9zdHJpcF9hbGxfdGFncygpIGZ1bmN0aW9uLgogKgogKiBBdXRvbWF0aWNhbGx5IGZhbGxzIGJhY2sgdG8gc3RyaXBfdGFncygpIGZ1bmN0aW9uIGlmIHRoZSBXUCBmdW5jdGlvbiBpcyBub3QKICogYXZhaWxhYmxlLgogKgogKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgU3RyaW5nIHRvIHN0cmlwIHRoZSB0YWdzIGZyb20uCiAqIEByZXR1cm4gc3RyaW5nIFN0cmluZyBkZXZvaWQgb2YgdGFncy4KICovCmZ1bmN0aW9uIHN0cmlwX3RhZ3MoICRzdHJpbmcgKSB7CglpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ3dwX3N0cmlwX2FsbF90YWdzJyApICkgewoJCXJldHVybiBcd3Bfc3RyaXBfYWxsX3RhZ3MoICRzdHJpbmcgKTsKCX0KCgkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKAoJCSdAPChzY3JpcHR8c3R5bGUpW14+XSo/Pi4qPzwvXFwxPkBzaScsCgkJJycsCgkJJHN0cmluZwoJKTsKCgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnN0cmlwX3RhZ3Nfc3RyaXBfdGFncyAtLSBGYWxsYmFjay4KCSRzdHJpbmcgPSBcc3RyaXBfdGFncyggJHN0cmluZyApOwoKCXJldHVybiB0cmltKCAkc3RyaW5nICk7Cn0KPD9waHAKCi8vIFN0b3JlIHRoZSBwYXRoIHRvIHRoZSBQaGFyIGVhcmx5IG9uIGZvciBgVXRpbHNccGhhci1zYWZlLXBhdGgoKWAgZnVuY3Rpb24uCmRlZmluZSggJ1dQX0NMSV9QSEFSX1BBVEgnLCBnZXRjd2QoKSApOwoKaWYgKCBmaWxlX2V4aXN0cyggJ3BoYXI6Ly93cC1jbGkucGhhci9waHAvd3AtY2xpLnBocCcgKSApIHsKCWRlZmluZSggJ1dQX0NMSV9ST09UJywgJ3BoYXI6Ly93cC1jbGkucGhhcicgKTsKCWluY2x1ZGUgV1BfQ0xJX1JPT1QgLiAnL3BocC93cC1jbGkucGhwJzsKfSBlbHNlaWYgKCBmaWxlX2V4aXN0cyggJ3BoYXI6Ly93cC1jbGkucGhhci92ZW5kb3Ivd3AtY2xpL3dwLWNsaS9waHAvd3AtY2xpLnBocCcgKSApIHsKCWRlZmluZSggJ1dQX0NMSV9ST09UJywgJ3BoYXI6Ly93cC1jbGkucGhhci92ZW5kb3Ivd3AtY2xpL3dwLWNsaScgKTsKCWluY2x1ZGUgV1BfQ0xJX1JPT1QgLiAnL3BocC93cC1jbGkucGhwJzsKfSBlbHNlIHsKCWVjaG8gIkNvdWxkbid0IGZpbmQgJ3BocC93cC1jbGkucGhwJy4gV2FzIHRoaXMgUGhhciBidWlsdCBjb3JyZWN0bHk/IjsKCWV4aXQoIDEgKTsKfQojIS91c3IvYmluL2VudiBwaHAKPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNSBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBzaGVsbCBzY3JpcHQgdG8gY3JlYXRlIGEgc2luZ2xlLWZpbGUgY2xhc3MgY2FjaGUgb2YgdGhlIGVudGlyZSBNdXN0YWNoZQogKiBsaWJyYXJ5LgogKgogKiAgICAgJCBiaW4vYnVpbGRfYm9vdHN0cmFwLnBocAogKgogKiAuLi4gd2lsbCBjcmVhdGUgYSBgbXVzdGFjaGUucGhwYCBib290c3RyYXAgZmlsZSBpbiB0aGUgcHJvamVjdCBkaXJlY3RvcnksCiAqIGNvbnRhaW5pbmcgYWxsIE11c3RhY2hlIGxpYnJhcnkgY2xhc3Nlcy4gVGhpcyBmaWxlIGNhbiB0aGVuIGJlIGluY2x1ZGVkIGluCiAqIHlvdXIgcHJvamVjdCwgcmF0aGVyIHRoYW4gcmVxdWlyaW5nIHRoZSBNdXN0YWNoZSBBdXRvbG9hZGVyLgogKi8KJGJhc2VEaXIgPSByZWFscGF0aChkaXJuYW1lKF9fRklMRV9fKSAuICcvLi4nKTsKCnJlcXVpcmUgJGJhc2VEaXIgLiAnL3NyYy9NdXN0YWNoZS9BdXRvbG9hZGVyLnBocCc7Ck11c3RhY2hlX0F1dG9sb2FkZXI6OnJlZ2lzdGVyKCk7CgovLyBkZWxldGUgdGhlIG9sZCBmaWxlCiRmaWxlID0gJGJhc2VEaXIgLiAnL211c3RhY2hlLnBocCc7CmlmIChmaWxlX2V4aXN0cygkZmlsZSkpIHsKICAgIHVubGluaygkZmlsZSk7Cn0KCi8vIGFuZCBsb2FkIHRoZSBuZXcgb25lClN5bWZvbnlDbGFzc0NvbGxlY3Rpb25Mb2FkZXI6OmxvYWQoYXJyYXkoCiAgICAnTXVzdGFjaGVfRW5naW5lJywKICAgICdNdXN0YWNoZV9DYWNoZScsCiAgICAnTXVzdGFjaGVfQ2FjaGVfQWJzdHJhY3RDYWNoZScsCiAgICAnTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlJywKICAgICdNdXN0YWNoZV9DYWNoZV9Ob29wQ2FjaGUnLAogICAgJ011c3RhY2hlX0NvbXBpbGVyJywKICAgICdNdXN0YWNoZV9Db250ZXh0JywKICAgICdNdXN0YWNoZV9FeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9Mb2dpY0V4Y2VwdGlvbicsCiAgICAnTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24nLAogICAgJ011c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duRmlsdGVyRXhjZXB0aW9uJywKICAgICdNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93bkhlbHBlckV4Y2VwdGlvbicsCiAgICAnTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbicsCiAgICAnTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbicsCiAgICAnTXVzdGFjaGVfTGFtYmRhSGVscGVyJywKICAgICdNdXN0YWNoZV9Mb2FkZXInLAogICAgJ011c3RhY2hlX0xvYWRlcl9BcnJheUxvYWRlcicsCiAgICAnTXVzdGFjaGVfTG9hZGVyX0Nhc2NhZGluZ0xvYWRlcicsCiAgICAnTXVzdGFjaGVfTG9hZGVyX0ZpbGVzeXN0ZW1Mb2FkZXInLAogICAgJ011c3RhY2hlX0xvYWRlcl9JbmxpbmVMb2FkZXInLAogICAgJ011c3RhY2hlX0xvYWRlcl9NdXRhYmxlTG9hZGVyJywKICAgICdNdXN0YWNoZV9Mb2FkZXJfU3RyaW5nTG9hZGVyJywKICAgICdNdXN0YWNoZV9Mb2dnZXInLAogICAgJ011c3RhY2hlX0xvZ2dlcl9BYnN0cmFjdExvZ2dlcicsCiAgICAnTXVzdGFjaGVfTG9nZ2VyX1N0cmVhbUxvZ2dlcicsCiAgICAnTXVzdGFjaGVfUGFyc2VyJywKICAgICdNdXN0YWNoZV9UZW1wbGF0ZScsCiAgICAnTXVzdGFjaGVfVG9rZW5pemVyJywKKSwgZGlybmFtZSgkZmlsZSksIGJhc2VuYW1lKCRmaWxlLCAnLnBocCcpKTsKCi8qKgogKiBTeW1mb255Q2xhc3NDb2xsZWN0aW9uTG9hZGVyLgogKgogKiBCYXNlZCBoZWF2aWx5IG9uIHRoZSBTeW1mb255IENsYXNzQ29sbGVjdGlvbkxvYWRlciBjb21wb25lbnQsIHdpdGggYWxsCiAqIHRoZSB1bm5lY2Vzc2FyeSBiaXRzIHJlbW92ZWQuCiAqCiAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgU3ltZm9ueUNsYXNzQ29sbGVjdGlvbkxvYWRlcgp7CiAgICBwcml2YXRlIHN0YXRpYyAkbG9hZGVkOwoKICAgIGNvbnN0IEhFQURFUiA9IDw8PCdFT1MnCjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLSVkIEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KRU9TOwoKICAgIC8qKgogICAgICogTG9hZHMgYSBsaXN0IG9mIGNsYXNzZXMgYW5kIGNhY2hlcyB0aGVtIGluIG9uZSBiaWcgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjbGFzc2VzICAgQW4gYXJyYXkgb2YgY2xhc3NlcyB0byBsb2FkCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjYWNoZURpciAgQSBjYWNoZSBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgICAgICBUaGUgY2FjaGUgbmFtZSBwcmVmaXgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGV4dGVuc2lvbiBGaWxlIGV4dGVuc2lvbiBvZiB0aGUgcmVzdWx0aW5nIGZpbGUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGNsYXNzIGNhbid0IGJlIGxvYWRlZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWQoYXJyYXkgJGNsYXNzZXMsICRjYWNoZURpciwgJG5hbWUsICRleHRlbnNpb24gPSAnLnBocCcpCiAgICB7CiAgICAgICAgLy8gZWFjaCAkbmFtZSBjYW4gb25seSBiZSBsb2FkZWQgb25jZSBwZXIgUEhQIHByb2Nlc3MKICAgICAgICBpZiAoaXNzZXQoc2VsZjo6JGxvYWRlZFskbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRsb2FkZWRbJG5hbWVdID0gdHJ1ZTsKCiAgICAgICAgJGNvbnRlbnQgPSAnJzsKICAgICAgICBmb3JlYWNoICgkY2xhc3NlcyBhcyAkY2xhc3MpIHsKICAgICAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJGNsYXNzKSAmJiAhaW50ZXJmYWNlX2V4aXN0cygkY2xhc3MpICYmICghZnVuY3Rpb25fZXhpc3RzKCd0cmFpdF9leGlzdHMnKSB8fCAhdHJhaXRfZXhpc3RzKCRjbGFzcykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBsb2FkIGNsYXNzICIlcyInLCAkY2xhc3MpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHIgPSBuZXcgUmVmbGVjdGlvbkNsYXNzKCRjbGFzcyk7CiAgICAgICAgICAgICRjb250ZW50IC49IHByZWdfcmVwbGFjZShhcnJheSgnL15ccyo8XD9waHAvJywgJy9cPz5ccyokLycpLCAnJywgZmlsZV9nZXRfY29udGVudHMoJHItPmdldEZpbGVOYW1lKCkpKTsKICAgICAgICB9CgogICAgICAgICRjYWNoZSAgPSAkY2FjaGVEaXIgLiAnLycgLiAkbmFtZSAuICRleHRlbnNpb247CiAgICAgICAgJGhlYWRlciA9IHNwcmludGYoc2VsZjo6SEVBREVSLCBzdHJmdGltZSgnJVknKSk7CiAgICAgICAgc2VsZjo6d3JpdGVDYWNoZUZpbGUoJGNhY2hlLCAkaGVhZGVyIC4gc3Vic3RyKHNlbGY6OnN0cmlwQ29tbWVudHMoJzw/cGhwICcgLiAkY29udGVudCksIDUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyBhIGNhY2hlIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSAgICBGaWxlbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudCBUZW1wb3JhcnkgZmlsZSBjb250ZW50CiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHdoZW4gYSBjYWNoZSBmaWxlIGNhbm5vdCBiZSB3cml0dGVuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHdyaXRlQ2FjaGVGaWxlKCRmaWxlLCAkY29udGVudCkKICAgIHsKICAgICAgICAkdG1wRmlsZSA9IHRlbXBuYW0oZGlybmFtZSgkZmlsZSksIGJhc2VuYW1lKCRmaWxlKSk7CiAgICAgICAgaWYgKGZhbHNlICE9PSBAZmlsZV9wdXRfY29udGVudHMoJHRtcEZpbGUsICRjb250ZW50KSAmJiBAcmVuYW1lKCR0bXBGaWxlLCAkZmlsZSkpIHsKICAgICAgICAgICAgY2htb2QoJGZpbGUsIDA2NjYgJiB+dW1hc2soKSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gd3JpdGUgY2FjaGUgZmlsZSAiJXMiLicsICRmaWxlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGNvbW1lbnRzIGZyb20gYSBQSFAgc291cmNlIHN0cmluZy4KICAgICAqCiAgICAgKiBXZSBkb24ndCB1c2UgdGhlIFBIUCBwaHBfc3RyaXBfd2hpdGVzcGFjZSgpIGZ1bmN0aW9uCiAgICAgKiBhcyB3ZSB3YW50IHRoZSBjb250ZW50IHRvIGJlIHJlYWRhYmxlIGFuZCB3ZWxsLWZvcm1hdHRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UgQSBQSFAgc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIFBIUCBzdHJpbmcgd2l0aCB0aGUgY29tbWVudHMgcmVtb3ZlZAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzdHJpcENvbW1lbnRzKCRzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3Rva2VuX2dldF9hbGwnKSkgewogICAgICAgICAgICByZXR1cm4gJHNvdXJjZTsKICAgICAgICB9CgogICAgICAgICRvdXRwdXQgPSAnJzsKICAgICAgICBmb3JlYWNoICh0b2tlbl9nZXRfYWxsKCRzb3VyY2UpIGFzICR0b2tlbikgewogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCR0b2tlbikpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgLj0gJHRva2VuOwogICAgICAgICAgICB9IGVsc2VpZiAoIWluX2FycmF5KCR0b2tlblswXSwgYXJyYXkoVF9DT01NRU5ULCBUX0RPQ19DT01NRU5UKSkpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgLj0gJHRva2VuWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZXBsYWNlIG11bHRpcGxlIG5ldyBsaW5lcyB3aXRoIGEgc2luZ2xlIG5ld2xpbmUKICAgICAgICAkb3V0cHV0ID0gcHJlZ19yZXBsYWNlKGFycmF5KCcvXHMrJC9TbScsICcvXG4rL1MnKSwgIlxuIiwgJG91dHB1dCk7CgogICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIHRlbXBsYXRlIEZpbGVzeXN0ZW0gU291cmNlLgogKgogKiBUaGlzIHRlbXBsYXRlIFNvdXJjZSB1c2VzIHN0YXQoKSB0byBnZW5lcmF0ZSB0aGUgU291cmNlIGtleSwgc28gdGhhdCB1c2luZwogKiBwcmUtY29tcGlsZWQgdGVtcGxhdGVzIGRvZXNuJ3QgcmVxdWlyZSBoaXR0aW5nIHRoZSBkaXNrIHRvIHJlYWQgdGhlIHNvdXJjZS4KICogSXQgaXMgbW9yZSBzdWl0YWJsZSBmb3IgcHJvZHVjdGlvbiB1c2UsIGFuZCBpcyB1c2VkIGJ5IGRlZmF1bHQgaW4gdGhlCiAqIFByb2R1Y3Rpb25GaWxlc3lzdGVtTG9hZGVyLgogKi8KY2xhc3MgTXVzdGFjaGVfU291cmNlX0ZpbGVzeXN0ZW1Tb3VyY2UgaW1wbGVtZW50cyBNdXN0YWNoZV9Tb3VyY2UKewogICAgcHJpdmF0ZSAkZmlsZU5hbWU7CiAgICBwcml2YXRlICRzdGF0UHJvcHM7CiAgICBwcml2YXRlICRzdGF0OwoKICAgIC8qKgogICAgICogRmlsZXN5c3RlbSBTb3VyY2UgY29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZU5hbWUKICAgICAqIEBwYXJhbSBhcnJheSAgJHN0YXRQcm9wcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGZpbGVOYW1lLCBhcnJheSAkc3RhdFByb3BzKQogICAgewogICAgICAgICR0aGlzLT5maWxlTmFtZSA9ICRmaWxlTmFtZTsKICAgICAgICAkdGhpcy0+c3RhdFByb3BzID0gJHN0YXRQcm9wczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgU291cmNlIGtleSAodXNlZCB0byBnZW5lcmF0ZSB0aGUgY29tcGlsZWQgY2xhc3MgbmFtZSkuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHdoZW4gYSBzb3VyY2UgZmlsZSBjYW5ub3QgYmUgcmVhZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXkoKQogICAgewogICAgICAgICRjaHVua3MgPSBhcnJheSgKICAgICAgICAgICAgJ2ZpbGVOYW1lJyA9PiAkdGhpcy0+ZmlsZU5hbWUsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+c3RhdFByb3BzKSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5zdGF0KSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnN0YXQgPSBAc3RhdCgkdGhpcy0+ZmlsZU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnN0YXQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gcmVhZCBzb3VyY2UgZmlsZSAiJXMiLicsICR0aGlzLT5maWxlTmFtZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+c3RhdFByb3BzIGFzICRwcm9wKSB7CiAgICAgICAgICAgICAgICAkY2h1bmtzWyRwcm9wXSA9ICR0aGlzLT5zdGF0WyRwcm9wXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGpzb25fZW5jb2RlKCRjaHVua3MpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB0ZW1wbGF0ZSBTb3VyY2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlTmFtZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgTG9hZGVyIGludGVyZmFjZS4KICovCmludGVyZmFjZSBNdXN0YWNoZV9Mb2FkZXIKewogICAgLyoqCiAgICAgKiBMb2FkIGEgVGVtcGxhdGUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gSWYgYSB0ZW1wbGF0ZSBmaWxlIGlzIG5vdCBmb3VuZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xNdXN0YWNoZV9Tb3VyY2UgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBDYWNoZSBpbi1tZW1vcnkgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoZSBpbi1tZW1vcnkgY2FjaGUgaXMgdXNlZCBmb3IgdW5jYWNoZWQgbGFtYmRhIHNlY3Rpb24gdGVtcGxhdGVzLiBJdCdzIGFsc28gdXNlZnVsIGR1cmluZyBkZXZlbG9wbWVudCwgYnV0IGlzIG5vdAogKiByZWNvbW1lbmRlZCBmb3IgcHJvZHVjdGlvbiB1c2UuCiAqLwpjbGFzcyBNdXN0YWNoZV9DYWNoZV9Ob29wQ2FjaGUgZXh0ZW5kcyBNdXN0YWNoZV9DYWNoZV9BYnN0cmFjdENhY2hlCnsKICAgIC8qKgogICAgICogTG9hZHMgbm90aGluZy4gTW92ZSBhbG9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRrZXkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJGtleSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkcyB0aGUgY29tcGlsZWQgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3Mgd2l0aG91dCBjYWNoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNhY2hlKCRrZXksICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKAogICAgICAgICAgICBNdXN0YWNoZV9Mb2dnZXI6OldBUk5JTkcsCiAgICAgICAgICAgICdUZW1wbGF0ZSBjYWNoZSBkaXNhYmxlZCwgZXZhbHVhdGluZyAie2NsYXNzTmFtZX0iIGNsYXNzIGF0IHJ1bnRpbWUnLAogICAgICAgICAgICBhcnJheSgnY2xhc3NOYW1lJyA9PiAka2V5KQogICAgICAgICk7CiAgICAgICAgZXZhbCgnPz4nIC4gJHZhbHVlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBDYWNoZSBmaWxlc3lzdGVtIGltcGxlbWVudGF0aW9uLgogKgogKiBBIEZpbGVzeXN0ZW1DYWNoZSBpbnN0YW5jZSBjYWNoZXMgTXVzdGFjaGUgVGVtcGxhdGUgY2xhc3NlcyBmcm9tIHRoZSBmaWxlc3lzdGVtIGJ5IG5hbWU6CiAqCiAqICAgICAkY2FjaGUgPSBuZXcgTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlKGRpcm5hbWUoX19GSUxFX18pLicvY2FjaGUnKTsKICogICAgICRjYWNoZS0+Y2FjaGUoJGNsYXNzTmFtZSwgJGNvbXBpbGVkU291cmNlKTsKICoKICogVGhlIEZpbGVzeXN0ZW1DYWNoZSBiZW5lZml0cyBmcm9tIGFueSBvcGNvZGUgY2FjaGluZyB0aGF0IG1heSBiZSBzZXR1cCBpbiB5b3VyIGVudmlyb25tZW50LiBTbyBkbyB0aGF0LCBrPwogKi8KY2xhc3MgTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlIGV4dGVuZHMgTXVzdGFjaGVfQ2FjaGVfQWJzdHJhY3RDYWNoZQp7CiAgICBwcml2YXRlICRiYXNlRGlyOwogICAgcHJpdmF0ZSAkZmlsZU1vZGU7CgogICAgLyoqCiAgICAgKiBGaWxlc3lzdGVtIGNhY2hlIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgIERpcmVjdG9yeSBmb3IgY29tcGlsZWQgdGVtcGxhdGVzCiAgICAgKiBAcGFyYW0gaW50ICAgICRmaWxlTW9kZSBPdmVycmlkZSBkZWZhdWx0IHBlcm1pc3Npb25zIGZvciBjYWNoZSBmaWxlcy4gRGVmYXVsdHMgdG8gdXNpbmcgdGhlIHN5c3RlbS1kZWZpbmVkIHVtYXNrCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgJGZpbGVNb2RlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YmFzZURpciA9ICRiYXNlRGlyOwogICAgICAgICR0aGlzLT5maWxlTW9kZSA9ICRmaWxlTW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgdGhlIGNsYXNzIGZyb20gY2FjaGUgdXNpbmcgYHJlcXVpcmVfb25jZWAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRrZXkpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmdldENhY2hlRmlsZW5hbWUoJGtleSk7CiAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmVxdWlyZV9vbmNlICRmaWxlTmFtZTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWNoZSBhbmQgbG9hZCB0aGUgY29tcGlsZWQgY2xhc3MuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAka2V5CiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FjaGUoJGtleSwgJHZhbHVlKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRDYWNoZUZpbGVuYW1lKCRrZXkpOwoKICAgICAgICAkdGhpcy0+bG9nKAogICAgICAgICAgICBNdXN0YWNoZV9Mb2dnZXI6OkRFQlVHLAogICAgICAgICAgICAnV3JpdGluZyB0byB0ZW1wbGF0ZSBjYWNoZTogIntmaWxlTmFtZX0iJywKICAgICAgICAgICAgYXJyYXkoJ2ZpbGVOYW1lJyA9PiAkZmlsZU5hbWUpCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPndyaXRlRmlsZSgkZmlsZU5hbWUsICR2YWx1ZSk7CiAgICAgICAgJHRoaXMtPmxvYWQoJGtleSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZCB0aGUgY2FjaGUgZmlsZW5hbWUuCiAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSBmb3IgY3VzdG9tIGNhY2hlIGRpcmVjdG9yeSBzdHJ1Y3R1cmVzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2FjaGVGaWxlbmFtZSgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gc3ByaW50ZignJXMvJXMucGhwJywgJHRoaXMtPmJhc2VEaXIsICRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBjYWNoZSBkaXJlY3RvcnkuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbiBJZiB1bmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVOYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZERpcmVjdG9yeUZvckZpbGVuYW1lKCRmaWxlTmFtZSkKICAgIHsKICAgICAgICAkZGlyTmFtZSA9IGRpcm5hbWUoJGZpbGVOYW1lKTsKICAgICAgICBpZiAoIWlzX2RpcigkZGlyTmFtZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6SU5GTywKICAgICAgICAgICAgICAgICdDcmVhdGluZyBNdXN0YWNoZSB0ZW1wbGF0ZSBjYWNoZSBkaXJlY3Rvcnk6ICJ7ZGlyTmFtZX0iJywKICAgICAgICAgICAgICAgIGFycmF5KCdkaXJOYW1lJyA9PiAkZGlyTmFtZSkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIEBta2RpcigkZGlyTmFtZSwgMDc3NywgdHJ1ZSk7CiAgICAgICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVTdGFydAogICAgICAgICAgICBpZiAoIWlzX2RpcigkZGlyTmFtZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY3JlYXRlIGNhY2hlIGRpcmVjdG9yeSAiJXMiLicsICRkaXJOYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZUVuZAogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkaXJOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogV3JpdGUgY2FjaGUgZmlsZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uIElmIHVuYWJsZSB0byB3cml0ZSBmaWxlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZU5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gd3JpdGVGaWxlKCRmaWxlTmFtZSwgJHZhbHVlKQogICAgewogICAgICAgICRkaXJOYW1lID0gJHRoaXMtPmJ1aWxkRGlyZWN0b3J5Rm9yRmlsZW5hbWUoJGZpbGVOYW1lKTsKCiAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgTXVzdGFjaGVfTG9nZ2VyOjpERUJVRywKICAgICAgICAgICAgJ0NhY2hpbmcgY29tcGlsZWQgdGVtcGxhdGUgdG8gIntmaWxlTmFtZX0iJywKICAgICAgICAgICAgYXJyYXkoJ2ZpbGVOYW1lJyA9PiAkZmlsZU5hbWUpCiAgICAgICAgKTsKCiAgICAgICAgJHRlbXBGaWxlID0gdGVtcG5hbSgkZGlyTmFtZSwgYmFzZW5hbWUoJGZpbGVOYW1lKSk7CiAgICAgICAgaWYgKGZhbHNlICE9PSBAZmlsZV9wdXRfY29udGVudHMoJHRlbXBGaWxlLCAkdmFsdWUpKSB7CiAgICAgICAgICAgIGlmIChAcmVuYW1lKCR0ZW1wRmlsZSwgJGZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgJG1vZGUgPSBpc3NldCgkdGhpcy0+ZmlsZU1vZGUpID8gJHRoaXMtPmZpbGVNb2RlIDogKDA2NjYgJiB+dW1hc2soKSk7CiAgICAgICAgICAgICAgICBAY2htb2QoJGZpbGVOYW1lLCAkbW9kZSk7CgogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6RVJST1IsCiAgICAgICAgICAgICAgICAnVW5hYmxlIHRvIHJlbmFtZSBNdXN0YWNoZSB0ZW1wIGNhY2hlIGZpbGU6ICJ7dGVtcE5hbWV9IiAtPiAie2ZpbGVOYW1lfSInLAogICAgICAgICAgICAgICAgYXJyYXkoJ3RlbXBOYW1lJyA9PiAkdGVtcEZpbGUsICdmaWxlTmFtZScgPT4gJGZpbGVOYW1lKQogICAgICAgICAgICApOwogICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICAgICAgfQoKICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHdyaXRlIGNhY2hlIGZpbGUgIiVzIi4nLCAkZmlsZU5hbWUpKTsKICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQWJzdHJhY3QgTXVzdGFjaGUgQ2FjaGUgY2xhc3MuCiAqCiAqIFByb3ZpZGVzIGxvZ2dpbmcgc3VwcG9ydCB0byBjaGlsZCBpbXBsZW1lbnRhdGlvbnMuCiAqCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgTXVzdGFjaGVfQ2FjaGVfQWJzdHJhY3RDYWNoZSBpbXBsZW1lbnRzIE11c3RhY2hlX0NhY2hlCnsKICAgIHByaXZhdGUgJGxvZ2dlciA9IG51bGw7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgbG9nZ2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfTG9nZ2VyfFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2dnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IGEgbG9nZ2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Mb2dnZXJ8UHNyXExvZ1xMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9nZ2VyKCRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgIGlmICgkbG9nZ2VyICE9PSBudWxsICYmICEoJGxvZ2dlciBpbnN0YW5jZW9mIE11c3RhY2hlX0xvZ2dlciB8fCBpc19hKCRsb2dnZXIsICdQc3JcXExvZ1xcTG9nZ2VySW50ZXJmYWNlJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdFeHBlY3RlZCBhbiBpbnN0YW5jZSBvZiBNdXN0YWNoZV9Mb2dnZXIgb3IgUHNyXFxMb2dcXExvZ2dlckludGVyZmFjZS4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2dnZXIgPSAkbG9nZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgbG9nIHJlY29yZCBpZiBsb2dnaW5nIGlzIGVuYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwgICBUaGUgbG9nZ2luZyBsZXZlbAogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQgVGhlIGxvZyBjb250ZXh0CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBsb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+bG9nZ2VyKSkgewogICAgICAgICAgICAkdGhpcy0+bG9nZ2VyLT5sb2coJGxldmVsLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBUaGlzIGlzIGEgc2ltcGxlIExvZ2dlciBpbXBsZW1lbnRhdGlvbiB0aGF0IG90aGVyIExvZ2dlcnMgY2FuIGluaGVyaXQgZnJvbS4KICoKICogVGhpcyBpcyBpZGVudGljYWwgdG8gdGhlIFBzclxMb2dcQWJzdHJhY3RMb2dnZXIuCiAqCiAqIEl0IHNpbXBseSBkZWxlZ2F0ZXMgYWxsIGxvZy1sZXZlbC1zcGVjaWZpYyBtZXRob2RzIHRvIHRoZSBgbG9nYCBtZXRob2QgdG8KICogcmVkdWNlIGJvaWxlcnBsYXRlIGNvZGUgdGhhdCBhIHNpbXBsZSBMb2dnZXIgdGhhdCBkb2VzIHRoZSBzYW1lIHRoaW5nIHdpdGgKICogbWVzc2FnZXMgcmVnYXJkbGVzcyBvZiB0aGUgZXJyb3IgbGV2ZWwgaGFzIHRvIGltcGxlbWVudC4KICovCmFic3RyYWN0IGNsYXNzIE11c3RhY2hlX0xvZ2dlcl9BYnN0cmFjdExvZ2dlciBpbXBsZW1lbnRzIE11c3RhY2hlX0xvZ2dlcgp7CiAgICAvKioKICAgICAqIFN5c3RlbSBpcyB1bnVzYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6RU1FUkdFTkNZLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFsZXJ0KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OkFMRVJULCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JpdGljYWwgY29uZGl0aW9ucy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBBcHBsaWNhdGlvbiBjb21wb25lbnQgdW5hdmFpbGFibGUsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OkNSSVRJQ0FMLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUnVudGltZSBlcnJvcnMgdGhhdCBkbyBub3QgcmVxdWlyZSBpbW1lZGlhdGUgYWN0aW9uIGJ1dCBzaG91bGQgdHlwaWNhbGx5CiAgICAgKiBiZSBsb2dnZWQgYW5kIG1vbml0b3JlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTXVzdGFjaGVfTG9nZ2VyOjpFUlJPUiwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YXJuaW5nKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhNdXN0YWNoZV9Mb2dnZXI6OldBUk5JTkcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6Tk9USUNFLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJlc3RpbmcgZXZlbnRzLgogICAgICoKICAgICAqIEV4YW1wbGU6IFVzZXIgbG9ncyBpbiwgU1FMIGxvZ3MuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTXVzdGFjaGVfTG9nZ2VyOjpJTkZPLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRGV0YWlsZWQgZGVidWcgaW5mb3JtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVidWcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKE11c3RhY2hlX0xvZ2dlcjo6REVCVUcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBNdXN0YWNoZSBTdHJlYW0gTG9nZ2VyLgogKgogKiBUaGUgU3RyZWFtIExvZ2dlciB3cmFwcyBhIGZpbGUgcmVzb3VyY2UgaW5zdGFuY2UgKHN1Y2ggYXMgYSBzdHJlYW0pIG9yIGEKICogc3RyZWFtIFVSTC4gQWxsIGxvZyBtZXNzYWdlcyBvdmVyIHRoZSB0aHJlc2hvbGQgbGV2ZWwgd2lsbCBiZSBhcHBlbmRlZCB0bwogKiB0aGlzIHN0cmVhbS4KICoKICogSGludDogVHJ5IGBwaHA6Ly9zdGRlcnJgIGZvciB5b3VyIHN0cmVhbSBVUkwuCiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2dnZXJfU3RyZWFtTG9nZ2VyIGV4dGVuZHMgTXVzdGFjaGVfTG9nZ2VyX0Fic3RyYWN0TG9nZ2VyCnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGxldmVscyA9IGFycmF5KAogICAgICAgIHNlbGY6OkRFQlVHICAgICA9PiAxMDAsCiAgICAgICAgc2VsZjo6SU5GTyAgICAgID0+IDIwMCwKICAgICAgICBzZWxmOjpOT1RJQ0UgICAgPT4gMjUwLAogICAgICAgIHNlbGY6OldBUk5JTkcgICA9PiAzMDAsCiAgICAgICAgc2VsZjo6RVJST1IgICAgID0+IDQwMCwKICAgICAgICBzZWxmOjpDUklUSUNBTCAgPT4gNTAwLAogICAgICAgIHNlbGY6OkFMRVJUICAgICA9PiA1NTAsCiAgICAgICAgc2VsZjo6RU1FUkdFTkNZID0+IDYwMCwKICAgICk7CgogICAgcHJvdGVjdGVkICRsZXZlbDsKICAgIHByb3RlY3RlZCAkc3RyZWFtID0gbnVsbDsKICAgIHByb3RlY3RlZCAkdXJsICAgID0gbnVsbDsKCiAgICAvKioKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2dnaW5nIGxldmVsIGlzIHVua25vd24KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nICRzdHJlYW0gUmVzb3VyY2UgaW5zdGFuY2Ugb3IgVVJMCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRsZXZlbCAgVGhlIG1pbmltdW0gbG9nZ2luZyBsZXZlbCBhdCB3aGljaCB0aGlzIGhhbmRsZXIgd2lsbCBiZSB0cmlnZ2VyZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzdHJlYW0sICRsZXZlbCA9IE11c3RhY2hlX0xvZ2dlcjo6RVJST1IpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldExldmVsKCRsZXZlbCk7CgogICAgICAgIGlmIChpc19yZXNvdXJjZSgkc3RyZWFtKSkgewogICAgICAgICAgICAkdGhpcy0+c3RyZWFtID0gJHN0cmVhbTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+dXJsID0gJHN0cmVhbTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbG9zZSBzdHJlYW0gcmVzb3VyY2VzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgaWYgKGlzX3Jlc291cmNlKCR0aGlzLT5zdHJlYW0pKSB7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+c3RyZWFtKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIG1pbmltdW0gbG9nZ2luZyBsZXZlbC4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvZ2dpbmcgbGV2ZWwgaXMgdW5rbm93bgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGxldmVsIFRoZSBtaW5pbXVtIGxvZ2dpbmcgbGV2ZWwgd2hpY2ggd2lsbCBiZSB3cml0dGVuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZXZlbCgkbGV2ZWwpCiAgICB7CiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRsZXZlbCwgc2VsZjo6JGxldmVscykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5leHBlY3RlZCBsb2dnaW5nIGxldmVsOiAlcycsICRsZXZlbCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxldmVsID0gJGxldmVsOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IG1pbmltdW0gbG9nZ2luZyBsZXZlbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGV2ZWwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGV2ZWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbG9nZ2luZyBsZXZlbCBpcyB1bmtub3duCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRsZXZlbCwgc2VsZjo6JGxldmVscykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5leHBlY3RlZCBsb2dnaW5nIGxldmVsOiAlcycsICRsZXZlbCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6OiRsZXZlbHNbJGxldmVsXSA+PSBzZWxmOjokbGV2ZWxzWyR0aGlzLT5sZXZlbF0pIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlTG9nKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZSBhIHJlY29yZCB0byB0aGUgbG9nLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0xvZ2ljRXhjZXB0aW9uICAgSWYgbmVpdGhlciBhIHN0cmVhbSByZXNvdXJjZSBub3IgdXJsIGlzIHByZXNlbnQKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHN0cmVhbSB1cmwgY2Fubm90IGJlIG9wZW5lZAogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsICAgVGhlIGxvZ2dpbmcgbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgVGhlIGxvZyBtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0IFRoZSBsb2cgY29udGV4dAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGVMb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmICghaXNfcmVzb3VyY2UoJHRoaXMtPnN0cmVhbSkpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Mb2dpY0V4Y2VwdGlvbignTWlzc2luZyBzdHJlYW0gdXJsLCB0aGUgc3RyZWFtIGNhbiBub3QgYmUgb3BlbmVkLiBUaGlzIG1heSBiZSBjYXVzZWQgYnkgYSBwcmVtYXR1cmUgY2FsbCB0byBjbG9zZSgpLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+c3RyZWFtID0gZm9wZW4oJHRoaXMtPnVybCwgJ2EnKTsKICAgICAgICAgICAgaWYgKCFpc19yZXNvdXJjZSgkdGhpcy0+c3RyZWFtKSkgewogICAgICAgICAgICAgICAgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlIHN0cmVhbSBvciBmaWxlICIlcyIgY291bGQgbm90IGJlIG9wZW5lZC4nLCAkdGhpcy0+dXJsKSk7CiAgICAgICAgICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ3cml0ZSgkdGhpcy0+c3RyZWFtLCBzZWxmOjpmb3JtYXRMaW5lKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBsb2dnaW5nIGxldmVsLgogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2dnaW5nIGxldmVsIGlzIHVua25vd24KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0TGV2ZWxOYW1lKCRsZXZlbCkKICAgIHsKICAgICAgICByZXR1cm4gc3RydG91cHBlcigkbGV2ZWwpOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0IGEgbG9nIGxpbmUgZm9yIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbCAgIFRoZSBsb2dnaW5nIGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dCBUaGUgbG9nIGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdExpbmUoJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAiJXM6ICVzXG4iLAogICAgICAgICAgICBzZWxmOjpnZXRMZXZlbE5hbWUoJGxldmVsKSwKICAgICAgICAgICAgc2VsZjo6aW50ZXJwb2xhdGVNZXNzYWdlKCRtZXNzYWdlLCAkY29udGV4dCkKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJwb2xhdGUgY29udGV4dCB2YWx1ZXMgaW50byB0aGUgbWVzc2FnZSBwbGFjZWhvbGRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gaW50ZXJwb2xhdGVNZXNzYWdlKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkbWVzc2FnZSwgJ3snKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgLy8gYnVpbGQgYSByZXBsYWNlbWVudCBhcnJheSB3aXRoIGJyYWNlcyBhcm91bmQgdGhlIGNvbnRleHQga2V5cwogICAgICAgICRyZXBsYWNlID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkY29udGV4dCBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgJHJlcGxhY2VbJ3snIC4gJGtleSAuICd9J10gPSAkdmFsOwogICAgICAgIH0KCiAgICAgICAgLy8gaW50ZXJwb2xhdGUgcmVwbGFjZW1lbnQgdmFsdWVzIGludG8gdGhlIHRoZSBtZXNzYWdlIGFuZCByZXR1cm4KICAgICAgICByZXR1cm4gc3RydHIoJG1lc3NhZ2UsICRyZXBsYWNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBBYnN0cmFjdCBNdXN0YWNoZSBUZW1wbGF0ZSBjbGFzcy4KICoKICogQGFic3RyYWN0CiAqLwphYnN0cmFjdCBjbGFzcyBNdXN0YWNoZV9UZW1wbGF0ZQp7CiAgICAvKioKICAgICAqIEB2YXIgTXVzdGFjaGVfRW5naW5lCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbXVzdGFjaGU7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRzdHJpY3RDYWxsYWJsZXMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIE11c3RhY2hlIFRlbXBsYXRlIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9FbmdpbmUgJG11c3RhY2hlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChNdXN0YWNoZV9FbmdpbmUgJG11c3RhY2hlKQogICAgewogICAgICAgICR0aGlzLT5tdXN0YWNoZSA9ICRtdXN0YWNoZTsKICAgIH0KCiAgICAvKioKICAgICAqIE11c3RhY2hlIFRlbXBsYXRlIGluc3RhbmNlcyBjYW4gYmUgdHJlYXRlZCBhcyBhIGZ1bmN0aW9uIGFuZCByZW5kZXJlZCBieSBzaW1wbHkgY2FsbGluZyB0aGVtLgogICAgICoKICAgICAqICAgICAkbSA9IG5ldyBNdXN0YWNoZV9FbmdpbmU7CiAgICAgKiAgICAgJHRwbCA9ICRtLT5sb2FkVGVtcGxhdGUoJ0hlbGxvLCB7eyBuYW1lIH19IScpOwogICAgICogICAgIGVjaG8gJHRwbChhcnJheSgnbmFtZScgPT4gJ1dvcmxkJykpOyAvLyAiSGVsbG8sIFdvcmxkISIKICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX1RlbXBsYXRlOjpyZW5kZXIKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGNvbnRleHQgQXJyYXkgb3Igb2JqZWN0IHJlbmRlcmluZyBjb250ZXh0IChkZWZhdWx0OiBhcnJheSgpKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFJlbmRlcmVkIHRlbXBsYXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSgkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW5kZXIoJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVyIHRoaXMgdGVtcGxhdGUgZ2l2ZW4gdGhlIHJlbmRlcmluZyBjb250ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkY29udGV4dCBBcnJheSBvciBvYmplY3QgcmVuZGVyaW5nIGNvbnRleHQgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcigkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW5kZXJJbnRlcm5hbCgKICAgICAgICAgICAgJHRoaXMtPnByZXBhcmVDb250ZXh0U3RhY2soJGNvbnRleHQpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEludGVybmFsIHJlbmRlcmluZyBtZXRob2QgaW1wbGVtZW50ZWQgYnkgTXVzdGFjaGUgVGVtcGxhdGUgY29uY3JldGUgc3ViY2xhc3Nlcy4KICAgICAqCiAgICAgKiBUaGlzIGlzIHdoZXJlIHRoZSBtYWdpYyBoYXBwZW5zIDopCiAgICAgKgogICAgICogTk9URTogVGhpcyBtZXRob2QgaXMgbm90IHBhcnQgb2YgdGhlIE11c3RhY2hlLnBocCBwdWJsaWMgQVBJLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkaW5kZW50ICAoZGVmYXVsdDogJycpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHJlbmRlckludGVybmFsKE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQsICRpbmRlbnQgPSAnJyk7CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIGEgdmFsdWUgc2hvdWxkIGJlIGl0ZXJhdGVkIG92ZXIgKGUuZy4gaW4gYSBzZWN0aW9uIGNvbnRleHQpLgogICAgICoKICAgICAqIEluIG1vc3QgbGFuZ3VhZ2VzIHRoZXJlIGFyZSB0d28gZGlzdGluY3QgYXJyYXkgdHlwZXM6IGxpc3QgYW5kIGhhc2ggKG9yIHdoYXRldmVyIHlvdSB3YW50IHRvIGNhbGwgdGhlbSkuIExpc3RzCiAgICAgKiBzaG91bGQgYmUgaXRlcmF0ZWQsIGhhc2hlcyBzaG91bGQgYmUgdHJlYXRlZCBhcyBvYmplY3RzLiBNdXN0YWNoZSBmb2xsb3dzIHRoaXMgcGFyYWRpZ20gZm9yIFJ1YnksIEphdmFzY3JpcHQsCiAgICAgKiBKYXZhLCBQeXRob24sIGV0Yy4KICAgICAqCiAgICAgKiBQSFAsIGhvd2V2ZXIsIHRyZWF0cyBsaXN0cyBhbmQgaGFzaGVzIGFzIG9uZSBwcmltaXRpdmUgdHlwZTogYXJyYXkuIFNvIE11c3RhY2hlLnBocCBuZWVkcyBhIHdheSB0byBkaXN0aW5ndWlzaAogICAgICogYmV0d2VlbiBiZXR3ZWVuIGEgbGlzdCBvZiB0aGluZ3MgKG51bWVyaWMsIG5vcm1hbGl6ZWQgYXJyYXkpIGFuZCBhIHNldCBvZiB2YXJpYWJsZXMgdG8gYmUgdXNlZCBhcyBzZWN0aW9uIGNvbnRleHQKICAgICAqIChhc3NvY2lhdGl2ZSBhcnJheSkuIEluIG90aGVyIHdvcmRzLCB0aGlzIHdpbGwgYmUgaXRlcmF0ZWQgb3ZlcjoKICAgICAqCiAgICAgKiAgICAgJGl0ZW1zID0gYXJyYXkoCiAgICAgKiAgICAgICAgIGFycmF5KCduYW1lJyA9PiAnZm9vJyksCiAgICAgKiAgICAgICAgIGFycmF5KCduYW1lJyA9PiAnYmFyJyksCiAgICAgKiAgICAgICAgIGFycmF5KCduYW1lJyA9PiAnYmF6JyksCiAgICAgKiAgICAgKTsKICAgICAqCiAgICAgKiAuLi4gYnV0IHRoaXMgd2lsbCBiZSB1c2VkIGFzIGEgc2VjdGlvbiBjb250ZXh0IGJsb2NrOgogICAgICoKICAgICAqICAgICAkaXRlbXMgPSBhcnJheSgKICAgICAqICAgICAgICAgMSAgICAgICAgPT4gYXJyYXkoJ25hbWUnID0+ICdmb28nKSwKICAgICAqICAgICAgICAgJ2JhbmFuYScgPT4gYXJyYXkoJ25hbWUnID0+ICdiYXInKSwKICAgICAqICAgICAgICAgNDIgICAgICAgPT4gYXJyYXkoJ25hbWUnID0+ICdiYXonKSwKICAgICAqICAgICApOwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgJ2l0ZXJhYmxlJwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNJdGVyYWJsZSgkdmFsdWUpCiAgICB7CiAgICAgICAgc3dpdGNoIChnZXR0eXBlKCR2YWx1ZSkpIHsKICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsdWUgaW5zdGFuY2VvZiBUcmF2ZXJzYWJsZTsKCiAgICAgICAgICAgIGNhc2UgJ2FycmF5JzoKICAgICAgICAgICAgICAgICRpID0gMDsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZSBhcyAkayA9PiAkdikgewogICAgICAgICAgICAgICAgICAgIGlmICgkayAhPT0gJGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgbWV0aG9kIHRvIHByZXBhcmUgdGhlIENvbnRleHQgc3RhY2suCiAgICAgKgogICAgICogQWRkcyB0aGUgTXVzdGFjaGUgSGVscGVyQ29sbGVjdGlvbiB0byB0aGUgc3RhY2sncyB0b3AgY29udGV4dCBmcmFtZSBpZiBoZWxwZXJzIGFyZSBwcmVzZW50LgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkY29udGV4dCBPcHRpb25hbCBmaXJzdCBjb250ZXh0IGZyYW1lIChkZWZhdWx0OiBudWxsKQogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfQ29udGV4dAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJlcGFyZUNvbnRleHRTdGFjaygkY29udGV4dCA9IG51bGwpCiAgICB7CiAgICAgICAgJHN0YWNrID0gbmV3IE11c3RhY2hlX0NvbnRleHQoKTsKCiAgICAgICAgJGhlbHBlcnMgPSAkdGhpcy0+bXVzdGFjaGUtPmdldEhlbHBlcnMoKTsKICAgICAgICBpZiAoISRoZWxwZXJzLT5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgJHN0YWNrLT5wdXNoKCRoZWxwZXJzKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGNvbnRleHQpKSB7CiAgICAgICAgICAgICRzdGFjay0+cHVzaCgkY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0YWNrOwogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZSBhIGNvbnRleHQgdmFsdWUuCiAgICAgKgogICAgICogSW52b2tlIHRoZSB2YWx1ZSBpZiBpdCBpcyBjYWxsYWJsZSwgb3RoZXJ3aXNlIHJldHVybiB0aGUgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfQ29udGV4dCAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZXNvbHZlVmFsdWUoJHZhbHVlLCBNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0KQogICAgewogICAgICAgIGlmICgoJHRoaXMtPnN0cmljdENhbGxhYmxlcyA/IGlzX29iamVjdCgkdmFsdWUpIDogIWlzX3N0cmluZygkdmFsdWUpKSAmJiBpc19jYWxsYWJsZSgkdmFsdWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bXVzdGFjaGUKICAgICAgICAgICAgICAgIC0+bG9hZExhbWJkYSgoc3RyaW5nKSBjYWxsX3VzZXJfZnVuYygkdmFsdWUpKQogICAgICAgICAgICAgICAgLT5yZW5kZXJJbnRlcm5hbCgkY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIERlc2NyaWJlcyBhIE11c3RhY2hlIGxvZ2dlciBpbnN0YW5jZS4KICoKICogVGhpcyBpcyBpZGVudGljYWwgdG8gdGhlIFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlLgogKgogKiBUaGUgbWVzc2FnZSBNVVNUIGJlIGEgc3RyaW5nIG9yIG9iamVjdCBpbXBsZW1lbnRpbmcgX190b1N0cmluZygpLgogKgogKiBUaGUgbWVzc2FnZSBNQVkgY29udGFpbiBwbGFjZWhvbGRlcnMgaW4gdGhlIGZvcm06IHtmb299IHdoZXJlIGZvbwogKiB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBjb250ZXh0IGRhdGEgaW4ga2V5ICJmb28iLgogKgogKiBUaGUgY29udGV4dCBhcnJheSBjYW4gY29udGFpbiBhcmJpdHJhcnkgZGF0YSwgdGhlIG9ubHkgYXNzdW1wdGlvbiB0aGF0CiAqIGNhbiBiZSBtYWRlIGJ5IGltcGxlbWVudG9ycyBpcyB0aGF0IGlmIGFuIEV4Y2VwdGlvbiBpbnN0YW5jZSBpcyBnaXZlbgogKiB0byBwcm9kdWNlIGEgc3RhY2sgdHJhY2UsIGl0IE1VU1QgYmUgaW4gYSBrZXkgbmFtZWQgImV4Y2VwdGlvbiIuCiAqCiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vcGhwLWZpZy9maWctc3RhbmRhcmRzL2Jsb2IvbWFzdGVyL2FjY2VwdGVkL1BTUi0zLWxvZ2dlci1pbnRlcmZhY2UubWQKICogZm9yIHRoZSBmdWxsIGludGVyZmFjZSBzcGVjaWZpY2F0aW9uLgogKi8KaW50ZXJmYWNlIE11c3RhY2hlX0xvZ2dlcgp7CiAgICAvKioKICAgICAqIFBzclxMb2cgY29tcGF0aWJsZSBsb2cgbGV2ZWxzLgogICAgICovCiAgICBjb25zdCBFTUVSR0VOQ1kgPSAnZW1lcmdlbmN5JzsKICAgIGNvbnN0IEFMRVJUICAgICA9ICdhbGVydCc7CiAgICBjb25zdCBDUklUSUNBTCAgPSAnY3JpdGljYWwnOwogICAgY29uc3QgRVJST1IgICAgID0gJ2Vycm9yJzsKICAgIGNvbnN0IFdBUk5JTkcgICA9ICd3YXJuaW5nJzsKICAgIGNvbnN0IE5PVElDRSAgICA9ICdub3RpY2UnOwogICAgY29uc3QgSU5GTyAgICAgID0gJ2luZm8nOwogICAgY29uc3QgREVCVUcgICAgID0gJ2RlYnVnJzsKCiAgICAvKioKICAgICAqIFN5c3RlbSBpcyB1bnVzYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBBY3Rpb24gbXVzdCBiZSB0YWtlbiBpbW1lZGlhdGVseS4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBFbnRpcmUgd2Vic2l0ZSBkb3duLCBkYXRhYmFzZSB1bmF2YWlsYWJsZSwgZXRjLiBUaGlzIHNob3VsZAogICAgICogdHJpZ2dlciB0aGUgU01TIGFsZXJ0cyBhbmQgd2FrZSB5b3UgdXAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWxlcnQoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBDcml0aWNhbCBjb25kaXRpb25zLgogICAgICoKICAgICAqIEV4YW1wbGU6IEFwcGxpY2F0aW9uIGNvbXBvbmVudCB1bmF2YWlsYWJsZSwgdW5leHBlY3RlZCBleGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JpdGljYWwoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBSdW50aW1lIGVycm9ycyB0aGF0IGRvIG5vdCByZXF1aXJlIGltbWVkaWF0ZSBhY3Rpb24gYnV0IHNob3VsZCB0eXBpY2FsbHkKICAgICAqIGJlIGxvZ2dlZCBhbmQgbW9uaXRvcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwoKICAgIC8qKgogICAgICogRXhjZXB0aW9uYWwgb2NjdXJyZW5jZXMgdGhhdCBhcmUgbm90IGVycm9ycy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2Ugb2YgZGVwcmVjYXRlZCBBUElzLCBwb29yIHVzZSBvZiBhbiBBUEksIHVuZGVzaXJhYmxlIHRoaW5ncwogICAgICogdGhhdCBhcmUgbm90IG5lY2Vzc2FyaWx5IHdyb25nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBJbnRlcmVzdGluZyBldmVudHMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlciBsb2dzIGluLCBTUUwgbG9ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmZvKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwoKICAgIC8qKgogICAgICogRGV0YWlsZWQgZGVidWcgaW5mb3JtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVidWcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgJGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBMYW1iZGEgSGVscGVyLgogKgogKiBQYXNzZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBzZWN0aW9uIGxhbWJkYXMgKGhpZ2hlciBvcmRlciBzZWN0aW9ucyksCiAqIGdpdmluZyB0aGVtIGFjY2VzcyB0byBhIGByZW5kZXJgIG1ldGhvZCBmb3IgcmVuZGVyaW5nIGEgc3RyaW5nIHdpdGggdGhlCiAqIGN1cnJlbnQgY29udGV4dC4KICovCmNsYXNzIE11c3RhY2hlX0xhbWJkYUhlbHBlcgp7CiAgICBwcml2YXRlICRtdXN0YWNoZTsKICAgIHByaXZhdGUgJGNvbnRleHQ7CiAgICBwcml2YXRlICRkZWxpbXM7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSBMYW1iZGEgSGVscGVyIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9FbmdpbmUgICRtdXN0YWNoZSBNdXN0YWNoZSBlbmdpbmUgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0ICBSZW5kZXJpbmcgY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGRlbGltcyAgIE9wdGlvbmFsIGN1c3RvbSBkZWxpbWl0ZXJzLCBpbiB0aGUgZm9ybWF0IGB7ez0gPCUgJT4gPX19YC4gKGRlZmF1bHQ6IG51bGwpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChNdXN0YWNoZV9FbmdpbmUgJG11c3RhY2hlLCBNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0LCAkZGVsaW1zID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+bXVzdGFjaGUgPSAkbXVzdGFjaGU7CiAgICAgICAgJHRoaXMtPmNvbnRleHQgID0gJGNvbnRleHQ7CiAgICAgICAgJHRoaXMtPmRlbGltcyAgID0gJGRlbGltczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlciBhIHN0cmluZyBhcyBhIE11c3RhY2hlIHRlbXBsYXRlIHdpdGggdGhlIGN1cnJlbnQgcmVuZGVyaW5nIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcigkc3RyaW5nKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bXVzdGFjaGUKICAgICAgICAgICAgLT5sb2FkTGFtYmRhKChzdHJpbmcpICRzdHJpbmcsICR0aGlzLT5kZWxpbXMpCiAgICAgICAgICAgIC0+cmVuZGVySW50ZXJuYWwoJHRoaXMtPmNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVyIGEgc3RyaW5nIGFzIGEgTXVzdGFjaGUgdGVtcGxhdGUgd2l0aCB0aGUgY3VycmVudCByZW5kZXJpbmcgY29udGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBSZW5kZXJlZCB0ZW1wbGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoJHN0cmluZykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbmRlcigkc3RyaW5nKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIExhbWJkYSBIZWxwZXIgd2l0aCBjdXN0b20gZGVsaW1pdGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbXMgQ3VzdG9tIGRlbGltaXRlcnMsIGluIHRoZSBmb3JtYXQgYHt7PSA8JSAlPiA9fX1gCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9MYW1iZGFIZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdpdGhEZWxpbWl0ZXJzKCRkZWxpbXMpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBzZWxmKCR0aGlzLT5tdXN0YWNoZSwgJHRoaXMtPmNvbnRleHQsICRkZWxpbXMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIHRlbXBsYXRlIFNvdXJjZSBpbnRlcmZhY2UuCiAqLwppbnRlcmZhY2UgTXVzdGFjaGVfU291cmNlCnsKICAgIC8qKgogICAgICogR2V0IHRoZSBTb3VyY2Uga2V5ICh1c2VkIHRvIGdlbmVyYXRlIHRoZSBjb21waWxlZCBjbGFzcyBuYW1lKS4KICAgICAqCiAgICAgKiBUaGlzIG11c3QgcmV0dXJuIGEgZGlzdGluY3Qga2V5IGZvciBlYWNoIHRlbXBsYXRlIHNvdXJjZS4gRm9yIGV4YW1wbGUsIGFuCiAgICAgKiBNRDUgaGFzaCBvZiB0aGUgdGVtcGxhdGUgY29udGVudHMgd291bGQgcHJvYmFibHkgZG8gdGhlIHRyaWNrLiBUaGUKICAgICAqIFByb2R1Y3Rpb25GaWxlc3lzdGVtTG9hZGVyIHVzZXMgbXRpbWUgYW5kIGZpbGUgcGF0aC4gSWYgeW91ciBwcm9kdWN0aW9uCiAgICAgKiBzb3VyY2UgZGlyZWN0b3J5IGlzIHVuZGVyIHZlcnNpb24gY29udHJvbCwgeW91IGNvdWxkIHVzZSB0aGUgY3VycmVudCBHaXQKICAgICAqIHJldiBhbmQgdGhlIGZpbGUgcGF0aC4uLgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB3aGVuIGEgc291cmNlIGZpbGUgY2Fubm90IGJlIHJlYWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2V5KCk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHRlbXBsYXRlIFNvdXJjZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gd2hlbiBhIHNvdXJjZSBmaWxlIGNhbm5vdCBiZSByZWFkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEEgTXVzdGFjaGUgaW1wbGVtZW50YXRpb24gaW4gUEhQLgogKgogKiB7QGxpbmsgaHR0cDovL2RlZnVua3QuZ2l0aHViLmNvbS9tdXN0YWNoZX0KICoKICogTXVzdGFjaGUgaXMgYSBmcmFtZXdvcmstYWdub3N0aWMgbG9naWMtbGVzcyB0ZW1wbGF0aW5nIGxhbmd1YWdlLiBJdCBlbmZvcmNlcyBzZXBhcmF0aW9uIG9mIHZpZXcKICogbG9naWMgZnJvbSB0ZW1wbGF0ZSBmaWxlcy4gSW4gZmFjdCwgaXQgaXMgbm90IGV2ZW4gcG9zc2libGUgdG8gZW1iZWQgbG9naWMgaW4gdGhlIHRlbXBsYXRlLgogKgogKiBUaGlzIGlzIHZlcnksIHZlcnkgcmFkLgogKgogKiBAYXV0aG9yIEp1c3RpbiBIaWxlbWFuIHtAbGluayBodHRwOi8vanVzdGluaGlsZW1hbi5jb219CiAqLwpjbGFzcyBNdXN0YWNoZV9FbmdpbmUKewogICAgY29uc3QgVkVSU0lPTiAgICAgICAgPSAnMi4xMy4wJzsKICAgIGNvbnN0IFNQRUNfVkVSU0lPTiAgID0gJzEuMS4yJzsKCiAgICBjb25zdCBQUkFHTUFfRklMVEVSUyAgICAgID0gJ0ZJTFRFUlMnOwogICAgY29uc3QgUFJBR01BX0JMT0NLUyAgICAgICA9ICdCTE9DS1MnOwogICAgY29uc3QgUFJBR01BX0FOQ0hPUkVEX0RPVCA9ICdBTkNIT1JFRC1ET1QnOwoKICAgIC8vIEtub3duIHByYWdtYXMKICAgIHByaXZhdGUgc3RhdGljICRrbm93blByYWdtYXMgPSBhcnJheSgKICAgICAgICBzZWxmOjpQUkFHTUFfRklMVEVSUyAgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6UFJBR01BX0JMT0NLUyAgICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlBSQUdNQV9BTkNIT1JFRF9ET1QgPT4gdHJ1ZSwKICAgICk7CgogICAgLy8gVGVtcGxhdGUgY2FjaGUKICAgIHByaXZhdGUgJHRlbXBsYXRlcyA9IGFycmF5KCk7CgogICAgLy8gRW52aXJvbm1lbnQKICAgIHByaXZhdGUgJHRlbXBsYXRlQ2xhc3NQcmVmaXggPSAnX19NdXN0YWNoZV8nOwogICAgcHJpdmF0ZSAkY2FjaGU7CiAgICBwcml2YXRlICRsYW1iZGFDYWNoZTsKICAgIHByaXZhdGUgJGNhY2hlTGFtYmRhVGVtcGxhdGVzID0gZmFsc2U7CiAgICBwcml2YXRlICRsb2FkZXI7CiAgICBwcml2YXRlICRwYXJ0aWFsc0xvYWRlcjsKICAgIHByaXZhdGUgJGhlbHBlcnM7CiAgICBwcml2YXRlICRlc2NhcGU7CiAgICBwcml2YXRlICRlbnRpdHlGbGFncyA9IEVOVF9DT01QQVQ7CiAgICBwcml2YXRlICRjaGFyc2V0ID0gJ1VURi04JzsKICAgIHByaXZhdGUgJGxvZ2dlcjsKICAgIHByaXZhdGUgJHN0cmljdENhbGxhYmxlcyA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcHJhZ21hcyA9IGFycmF5KCk7CiAgICBwcml2YXRlICRkZWxpbWl0ZXJzOwoKICAgIC8vIFNlcnZpY2VzCiAgICBwcml2YXRlICR0b2tlbml6ZXI7CiAgICBwcml2YXRlICRwYXJzZXI7CiAgICBwcml2YXRlICRjb21waWxlcjsKCiAgICAvKioKICAgICAqIE11c3RhY2hlIGNsYXNzIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIFBhc3NpbmcgYW4gJG9wdGlvbnMgYXJyYXkgYWxsb3dzIG92ZXJyaWRpbmcgY2VydGFpbiBNdXN0YWNoZSBvcHRpb25zIGR1cmluZyBpbnN0YW50aWF0aW9uOgogICAgICoKICAgICAqICAgICAkb3B0aW9ucyA9IGFycmF5KAogICAgICogICAgICAgICAvLyBUaGUgY2xhc3MgcHJlZml4IGZvciBjb21waWxlZCB0ZW1wbGF0ZXMuIERlZmF1bHRzIHRvICdfX011c3RhY2hlXycuCiAgICAgKiAgICAgICAgICd0ZW1wbGF0ZV9jbGFzc19wcmVmaXgnID0+ICdfX015VGVtcGxhdGVzXycsCiAgICAgKgogICAgICogICAgICAgICAvLyBBIE11c3RhY2hlIGNhY2hlIGluc3RhbmNlIG9yIGEgY2FjaGUgZGlyZWN0b3J5IHN0cmluZyBmb3IgY29tcGlsZWQgdGVtcGxhdGVzLgogICAgICogICAgICAgICAvLyBNdXN0YWNoZSB3aWxsIG5vdCBjYWNoZSB0ZW1wbGF0ZXMgdW5sZXNzIHRoaXMgaXMgc2V0LgogICAgICogICAgICAgICAnY2FjaGUnID0+IGRpcm5hbWUoX19GSUxFX18pLicvdG1wL2NhY2hlL211c3RhY2hlJywKICAgICAqCiAgICAgKiAgICAgICAgIC8vIE92ZXJyaWRlIGRlZmF1bHQgcGVybWlzc2lvbnMgZm9yIGNhY2hlIGZpbGVzLiBEZWZhdWx0cyB0byB1c2luZyB0aGUgc3lzdGVtLWRlZmluZWQgdW1hc2suIEl0IGlzCiAgICAgKiAgICAgICAgIC8vICpzdHJvbmdseSogcmVjb21tZW5kZWQgdGhhdCB5b3UgY29uZmlndXJlIHlvdXIgdW1hc2sgcHJvcGVybHkgcmF0aGVyIHRoYW4gb3ZlcnJpZGluZyBwZXJtaXNzaW9ucyBoZXJlLgogICAgICogICAgICAgICAnY2FjaGVfZmlsZV9tb2RlJyA9PiAwNjY2LAogICAgICoKICAgICAqICAgICAgICAgLy8gT3B0aW9uYWxseSwgZW5hYmxlIGNhY2hpbmcgZm9yIGxhbWJkYSBzZWN0aW9uIHRlbXBsYXRlcy4gVGhpcyBpcyBnZW5lcmFsbHkgbm90IHJlY29tbWVuZGVkLCBhcyBsYW1iZGEKICAgICAqICAgICAgICAgLy8gc2VjdGlvbnMgYXJlIG9mdGVuIHRvbyBkeW5hbWljIHRvIGJlbmVmaXQgZnJvbSBjYWNoaW5nLgogICAgICogICAgICAgICAnY2FjaGVfbGFtYmRhX3RlbXBsYXRlcycgPT4gdHJ1ZSwKICAgICAqCiAgICAgKiAgICAgICAgIC8vIEN1c3RvbWl6ZSB0aGUgdGFnIGRlbGltaXRlcnMgdXNlZCBieSB0aGlzIGVuZ2luZSBpbnN0YW5jZS4gTm90ZSB0aGF0IG92ZXJyaWRpbmcgaGVyZSBjaGFuZ2VzIHRoZQogICAgICogICAgICAgICAvLyBkZWxpbWl0ZXJzIHVzZWQgdG8gcGFyc2UgYWxsIHRlbXBsYXRlcyBhbmQgcGFydGlhbHMgbG9hZGVkIGJ5IHRoaXMgaW5zdGFuY2UuIFRvIG92ZXJyaWRlIGp1c3QgZm9yIGEKICAgICAqICAgICAgICAgLy8gc2luZ2xlIHRlbXBsYXRlLCB1c2UgYW4gaW5saW5lICJjaGFuZ2UgZGVsaW1pdGVycyIgdGFnIGF0IHRoZSBzdGFydCBvZiB0aGUgdGVtcGxhdGUgZmlsZToKICAgICAqICAgICAgICAgLy8KICAgICAqICAgICAgICAgLy8gICAgIHt7PTwlICU+PX19CiAgICAgKiAgICAgICAgIC8vCiAgICAgKiAgICAgICAgICdkZWxpbWl0ZXJzJyA9PiAnPCUgJT4nLAogICAgICoKICAgICAqICAgICAgICAgLy8gQSBNdXN0YWNoZSB0ZW1wbGF0ZSBsb2FkZXIgaW5zdGFuY2UuIFVzZXMgYSBTdHJpbmdMb2FkZXIgaWYgbm90IHNwZWNpZmllZC4KICAgICAqICAgICAgICAgJ2xvYWRlcicgPT4gbmV3IE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MnKSwKICAgICAqCiAgICAgKiAgICAgICAgIC8vIEEgTXVzdGFjaGUgbG9hZGVyIGluc3RhbmNlIGZvciBwYXJ0aWFscy4KICAgICAqICAgICAgICAgJ3BhcnRpYWxzX2xvYWRlcicgPT4gbmV3IE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MvcGFydGlhbHMnKSwKICAgICAqCiAgICAgKiAgICAgICAgIC8vIEFuIGFycmF5IG9mIE11c3RhY2hlIHBhcnRpYWxzLiBVc2VmdWwgZm9yIHF1aWNrLWFuZC1kaXJ0eSBzdHJpbmcgdGVtcGxhdGUgbG9hZGluZywgYnV0IG5vdCBhcwogICAgICogICAgICAgICAvLyBlZmZpY2llbnQgb3IgbGF6eSBhcyBhIEZpbGVzeXN0ZW0gKG9yIGRhdGFiYXNlKSBsb2FkZXIuCiAgICAgKiAgICAgICAgICdwYXJ0aWFscycgPT4gYXJyYXkoJ2ZvbycgPT4gZmlsZV9nZXRfY29udGVudHMoZGlybmFtZShfX0ZJTEVfXykuJy92aWV3cy9wYXJ0aWFscy9mb28ubXVzdGFjaGUnKSksCiAgICAgKgogICAgICogICAgICAgICAvLyBBbiBhcnJheSBvZiAnaGVscGVycycuIEhlbHBlcnMgY2FuIGJlIGdsb2JhbCB2YXJpYWJsZXMgb3Igb2JqZWN0cywgY2xvc3VyZXMgKGUuZy4gZm9yIGhpZ2hlciBvcmRlcgogICAgICogICAgICAgICAvLyBzZWN0aW9ucyksIG9yIGFueSBvdGhlciB2YWxpZCBNdXN0YWNoZSBjb250ZXh0IHZhbHVlLiBUaGV5IHdpbGwgYmUgcHJlcGVuZGVkIHRvIHRoZSBjb250ZXh0IHN0YWNrLAogICAgICogICAgICAgICAvLyBzbyB0aGV5IHdpbGwgYmUgYXZhaWxhYmxlIGluIGFueSB0ZW1wbGF0ZSBsb2FkZWQgYnkgdGhpcyBNdXN0YWNoZSBpbnN0YW5jZS4KICAgICAqICAgICAgICAgJ2hlbHBlcnMnID0+IGFycmF5KCdpMThuJyA9PiBmdW5jdGlvbiAoJHRleHQpIHsKICAgICAqICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyB0cmFuc2xhdGV5IGhlcmUuLi4KICAgICAqICAgICAgICAgfSksCiAgICAgKgogICAgICogICAgICAgICAvLyBBbiAnZXNjYXBlJyBjYWxsYmFjaywgcmVzcG9uc2libGUgZm9yIGVzY2FwaW5nIGRvdWJsZS1tdXN0YWNoZSB2YXJpYWJsZXMuCiAgICAgKiAgICAgICAgICdlc2NhcGUnID0+IGZ1bmN0aW9uICgkdmFsdWUpIHsKICAgICAqICAgICAgICAgICAgIHJldHVybiBodG1sc3BlY2lhbGNoYXJzKCRidWZmZXIsIEVOVF9DT01QQVQsICdVVEYtOCcpOwogICAgICogICAgICAgICB9LAogICAgICoKICAgICAqICAgICAgICAgLy8gVHlwZSBhcmd1bWVudCBmb3IgYGh0bWxzcGVjaWFsY2hhcnNgLiAgRGVmYXVsdHMgdG8gRU5UX0NPTVBBVC4gIFlvdSBtYXkgcHJlZmVyIEVOVF9RVU9URVMuCiAgICAgKiAgICAgICAgICdlbnRpdHlfZmxhZ3MnID0+IEVOVF9RVU9URVMsCiAgICAgKgogICAgICogICAgICAgICAvLyBDaGFyYWN0ZXIgc2V0IGZvciBgaHRtbHNwZWNpYWxjaGFyc2AuIERlZmF1bHRzIHRvICdVVEYtOCcuIFVzZSAnVVRGLTgnLgogICAgICogICAgICAgICAnY2hhcnNldCcgPT4gJ0lTTy04ODU5LTEnLAogICAgICoKICAgICAqICAgICAgICAgLy8gQSBNdXN0YWNoZSBMb2dnZXIgaW5zdGFuY2UuIE5vIGxvZ2dpbmcgd2lsbCBvY2N1ciB1bmxlc3MgdGhpcyBpcyBzZXQuIFVzaW5nIGEgUFNSLTMgY29tcGF0aWJsZQogICAgICogICAgICAgICAvLyBsb2dnaW5nIGxpYnJhcnkgLS0gc3VjaCBhcyBNb25vbG9nIC0tIGlzIGhpZ2hseSByZWNvbW1lbmRlZC4gQSBzaW1wbGUgc3RyZWFtIGxvZ2dlciBpbXBsZW1lbnRhdGlvbiBpcwogICAgICogICAgICAgICAvLyBhdmFpbGFibGUgYXMgd2VsbDoKICAgICAqICAgICAgICAgJ2xvZ2dlcicgPT4gbmV3IE11c3RhY2hlX0xvZ2dlcl9TdHJlYW1Mb2dnZXIoJ3BocDovL3N0ZGVycicpLAogICAgICoKICAgICAqICAgICAgICAgLy8gT25seSB0cmVhdCBDbG9zdXJlIGluc3RhbmNlcyBhbmQgaW52b2thYmxlIGNsYXNzZXMgYXMgY2FsbGFibGUuIElmIHRydWUsIHZhbHVlcyBsaWtlCiAgICAgKiAgICAgICAgIC8vIGBhcnJheSgnQ2xhc3NOYW1lJywgJ21ldGhvZE5hbWUnKWAgYW5kIGBhcnJheSgkY2xhc3NJbnN0YW5jZSwgJ21ldGhvZE5hbWUnKWAsIHdoaWNoIGFyZSB0cmFkaXRpb25hbGx5CiAgICAgKiAgICAgICAgIC8vICJjYWxsYWJsZSIgaW4gUEhQLCBhcmUgbm90IGNhbGxlZCB0byByZXNvbHZlIHZhcmlhYmxlcyBmb3IgaW50ZXJwb2xhdGlvbiBvciBzZWN0aW9uIGNvbnRleHRzLiBUaGlzCiAgICAgKiAgICAgICAgIC8vIGhlbHBzIHByb3RlY3QgYWdhaW5zdCBhcmJpdHJhcnkgY29kZSBleGVjdXRpb24gd2hlbiB1c2VyIGlucHV0IGlzIHBhc3NlZCBkaXJlY3RseSBpbnRvIHRoZSB0ZW1wbGF0ZS4KICAgICAqICAgICAgICAgLy8gVGhpcyBjdXJyZW50bHkgZGVmYXVsdHMgdG8gZmFsc2UsIGJ1dCB3aWxsIGRlZmF1bHQgdG8gdHJ1ZSBpbiB2My4wLgogICAgICogICAgICAgICAnc3RyaWN0X2NhbGxhYmxlcycgPT4gdHJ1ZSwKICAgICAqCiAgICAgKiAgICAgICAgIC8vIEVuYWJsZSBwcmFnbWFzIGFjcm9zcyBhbGwgdGVtcGxhdGVzLCByZWdhcmRsZXNzIG9mIHRoZSBwcmVzZW5jZSBvZiBwcmFnbWEgdGFncyBpbiB0aGUgaW5kaXZpZHVhbAogICAgICogICAgICAgICAvLyB0ZW1wbGF0ZXMuCiAgICAgKiAgICAgICAgICdwcmFnbWFzJyA9PiBbTXVzdGFjaGVfRW5naW5lOjpQUkFHTUFfRklMVEVSU10sCiAgICAgKiAgICAgKTsKICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgYGVzY2FwZWAgb3B0aW9uIGlzIG5vdCBjYWxsYWJsZQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyAoZGVmYXVsdDogYXJyYXkoKSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3RlbXBsYXRlX2NsYXNzX3ByZWZpeCddKSkgewogICAgICAgICAgICBpZiAoKHN0cmluZykgJG9wdGlvbnNbJ3RlbXBsYXRlX2NsYXNzX3ByZWZpeCddID09PSAnJykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ011c3RhY2hlIENvbnN0cnVjdG9yICJ0ZW1wbGF0ZV9jbGFzc19wcmVmaXgiIG11c3Qgbm90IGJlIGVtcHR5Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT50ZW1wbGF0ZUNsYXNzUHJlZml4ID0gJG9wdGlvbnNbJ3RlbXBsYXRlX2NsYXNzX3ByZWZpeCddOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydjYWNoZSddKSkgewogICAgICAgICAgICAkY2FjaGUgPSAkb3B0aW9uc1snY2FjaGUnXTsKCiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJGNhY2hlKSkgewogICAgICAgICAgICAgICAgJG1vZGUgID0gaXNzZXQoJG9wdGlvbnNbJ2NhY2hlX2ZpbGVfbW9kZSddKSA/ICRvcHRpb25zWydjYWNoZV9maWxlX21vZGUnXSA6IG51bGw7CiAgICAgICAgICAgICAgICAkY2FjaGUgPSBuZXcgTXVzdGFjaGVfQ2FjaGVfRmlsZXN5c3RlbUNhY2hlKCRjYWNoZSwgJG1vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+c2V0Q2FjaGUoJGNhY2hlKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snY2FjaGVfbGFtYmRhX3RlbXBsYXRlcyddKSkgewogICAgICAgICAgICAkdGhpcy0+Y2FjaGVMYW1iZGFUZW1wbGF0ZXMgPSAoYm9vbCkgJG9wdGlvbnNbJ2NhY2hlX2xhbWJkYV90ZW1wbGF0ZXMnXTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snbG9hZGVyJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRMb2FkZXIoJG9wdGlvbnNbJ2xvYWRlciddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1sncGFydGlhbHNfbG9hZGVyJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRQYXJ0aWFsc0xvYWRlcigkb3B0aW9uc1sncGFydGlhbHNfbG9hZGVyJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydwYXJ0aWFscyddKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0UGFydGlhbHMoJG9wdGlvbnNbJ3BhcnRpYWxzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydoZWxwZXJzJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRIZWxwZXJzKCRvcHRpb25zWydoZWxwZXJzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydlc2NhcGUnXSkpIHsKICAgICAgICAgICAgaWYgKCFpc19jYWxsYWJsZSgkb3B0aW9uc1snZXNjYXBlJ10pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignTXVzdGFjaGUgQ29uc3RydWN0b3IgImVzY2FwZSIgb3B0aW9uIG11c3QgYmUgY2FsbGFibGUnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmVzY2FwZSA9ICRvcHRpb25zWydlc2NhcGUnXTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snZW50aXR5X2ZsYWdzJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5lbnRpdHlGbGFncyA9ICRvcHRpb25zWydlbnRpdHlfZmxhZ3MnXTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snY2hhcnNldCddKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hhcnNldCA9ICRvcHRpb25zWydjaGFyc2V0J107CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2xvZ2dlciddKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0TG9nZ2VyKCRvcHRpb25zWydsb2dnZXInXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3N0cmljdF9jYWxsYWJsZXMnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnN0cmljdENhbGxhYmxlcyA9ICRvcHRpb25zWydzdHJpY3RfY2FsbGFibGVzJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2RlbGltaXRlcnMnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmRlbGltaXRlcnMgPSAkb3B0aW9uc1snZGVsaW1pdGVycyddOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydwcmFnbWFzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvcHRpb25zWydwcmFnbWFzJ10gYXMgJHByYWdtYSkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldChzZWxmOjoka25vd25QcmFnbWFzWyRwcmFnbWFdKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1Vua25vd24gcHJhZ21hOiAiJXMiLicsICRwcmFnbWEpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5wcmFnbWFzWyRwcmFnbWFdID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNob3J0Y3V0ICdyZW5kZXInIGludm9jYXRpb24uCiAgICAgKgogICAgICogRXF1aXZhbGVudCB0byBjYWxsaW5nIGAkbXVzdGFjaGUtPmxvYWRUZW1wbGF0ZSgkdGVtcGxhdGUpLT5yZW5kZXIoJGNvbnRleHQpO2AKICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0VuZ2luZTo6bG9hZFRlbXBsYXRlCiAgICAgKiBAc2VlIE11c3RhY2hlX1RlbXBsYXRlOjpyZW5kZXIKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZW1wbGF0ZQogICAgICogQHBhcmFtIG1peGVkICAkY29udGV4dCAgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgUmVuZGVyZWQgdGVtcGxhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcigkdGVtcGxhdGUsICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvYWRUZW1wbGF0ZSgkdGVtcGxhdGUpLT5yZW5kZXIoJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IE11c3RhY2hlIGVzY2FwZSBjYWxsYmFjay4KICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVzY2FwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lc2NhcGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTXVzdGFjaGUgZW50aXRpdHkgdHlwZSB0byBlc2NhcGUuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVudGl0eUZsYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVudGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IE11c3RhY2hlIGNoYXJhY3RlciBzZXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYXJzZXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hhcnNldDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBnbG9iYWxseSBlbmFibGVkIHByYWdtYXMuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJhZ21hcygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJHRoaXMtPnByYWdtYXMpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBNdXN0YWNoZSB0ZW1wbGF0ZSBMb2FkZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX0xvYWRlciAkbG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2FkZXIoTXVzdGFjaGVfTG9hZGVyICRsb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRlciA9ICRsb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTXVzdGFjaGUgdGVtcGxhdGUgTG9hZGVyIGluc3RhbmNlLgogICAgICoKICAgICAqIElmIG5vIExvYWRlciBpbnN0YW5jZSBoYXMgYmVlbiBleHBsaWNpdGx5IHNwZWNpZmllZCwgdGhpcyBtZXRob2Qgd2lsbCBpbnN0YW50aWF0ZSBhbmQgcmV0dXJuCiAgICAgKiBhIFN0cmluZ0xvYWRlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX0xvYWRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9hZGVyKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5sb2FkZXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgTXVzdGFjaGVfTG9hZGVyX1N0cmluZ0xvYWRlcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIE11c3RhY2hlIHBhcnRpYWxzIExvYWRlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfTG9hZGVyICRwYXJ0aWFsc0xvYWRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGFydGlhbHNMb2FkZXIoTXVzdGFjaGVfTG9hZGVyICRwYXJ0aWFsc0xvYWRlcikKICAgIHsKICAgICAgICAkdGhpcy0+cGFydGlhbHNMb2FkZXIgPSAkcGFydGlhbHNMb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTXVzdGFjaGUgcGFydGlhbHMgTG9hZGVyIGluc3RhbmNlLgogICAgICoKICAgICAqIElmIG5vIExvYWRlciBpbnN0YW5jZSBoYXMgYmVlbiBleHBsaWNpdGx5IHNwZWNpZmllZCwgdGhpcyBtZXRob2Qgd2lsbCBpbnN0YW50aWF0ZSBhbmQgcmV0dXJuCiAgICAgKiBhbiBBcnJheUxvYWRlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX0xvYWRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFydGlhbHNMb2FkZXIoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnBhcnRpYWxzTG9hZGVyKSkgewogICAgICAgICAgICAkdGhpcy0+cGFydGlhbHNMb2FkZXIgPSBuZXcgTXVzdGFjaGVfTG9hZGVyX0FycmF5TG9hZGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBhcnRpYWxzTG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHBhcnRpYWxzIGZvciB0aGUgY3VycmVudCBwYXJ0aWFscyBMb2FkZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbiBJZiB0aGUgY3VycmVudCBMb2FkZXIgaW5zdGFuY2UgaXMgaW1tdXRhYmxlCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRwYXJ0aWFscyAoZGVmYXVsdDogYXJyYXkoKSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcnRpYWxzKGFycmF5ICRwYXJ0aWFscyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cGFydGlhbHNMb2FkZXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5wYXJ0aWFsc0xvYWRlciA9IG5ldyBNdXN0YWNoZV9Mb2FkZXJfQXJyYXlMb2FkZXIoKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPnBhcnRpYWxzTG9hZGVyIGluc3RhbmNlb2YgTXVzdGFjaGVfTG9hZGVyX011dGFibGVMb2FkZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uKCdVbmFibGUgdG8gc2V0IHBhcnRpYWxzIG9uIGFuIGltbXV0YWJsZSBNdXN0YWNoZSBMb2FkZXIgaW5zdGFuY2UnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5wYXJ0aWFsc0xvYWRlci0+c2V0VGVtcGxhdGVzKCRwYXJ0aWFscyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYW4gYXJyYXkgb2YgTXVzdGFjaGUgaGVscGVycy4KICAgICAqCiAgICAgKiBBbiBhcnJheSBvZiAnaGVscGVycycuIEhlbHBlcnMgY2FuIGJlIGdsb2JhbCB2YXJpYWJsZXMgb3Igb2JqZWN0cywgY2xvc3VyZXMgKGUuZy4gZm9yIGhpZ2hlciBvcmRlciBzZWN0aW9ucyksIG9yCiAgICAgKiBhbnkgb3RoZXIgdmFsaWQgTXVzdGFjaGUgY29udGV4dCB2YWx1ZS4gVGhleSB3aWxsIGJlIHByZXBlbmRlZCB0byB0aGUgY29udGV4dCBzdGFjaywgc28gdGhleSB3aWxsIGJlIGF2YWlsYWJsZSBpbgogICAgICogYW55IHRlbXBsYXRlIGxvYWRlZCBieSB0aGlzIE11c3RhY2hlIGluc3RhbmNlLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiAkaGVscGVycyBpcyBub3QgYW4gYXJyYXkgb3IgVHJhdmVyc2FibGUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8VHJhdmVyc2FibGUgJGhlbHBlcnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhlbHBlcnMoJGhlbHBlcnMpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkaGVscGVycykgJiYgISRoZWxwZXJzIGluc3RhbmNlb2YgVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ3NldEhlbHBlcnMgZXhwZWN0cyBhbiBhcnJheSBvZiBoZWxwZXJzJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Z2V0SGVscGVycygpLT5jbGVhcigpOwoKICAgICAgICBmb3JlYWNoICgkaGVscGVycyBhcyAkbmFtZSA9PiAkaGVscGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRIZWxwZXIoJG5hbWUsICRoZWxwZXIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBzZXQgb2YgTXVzdGFjaGUgaGVscGVycy4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0VuZ2luZTo6c2V0SGVscGVycwogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVycygpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aGVscGVycykpIHsKICAgICAgICAgICAgJHRoaXMtPmhlbHBlcnMgPSBuZXcgTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5oZWxwZXJzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgbmV3IE11c3RhY2hlIGhlbHBlci4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0VuZ2luZTo6c2V0SGVscGVycwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBtaXhlZCAgJGhlbHBlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkSGVscGVyKCRuYW1lLCAkaGVscGVyKQogICAgewogICAgICAgICR0aGlzLT5nZXRIZWxwZXJzKCktPmFkZCgkbmFtZSwgJGhlbHBlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBNdXN0YWNoZSBoZWxwZXIgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0VuZ2luZTo6c2V0SGVscGVycwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIEhlbHBlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SGVscGVycygpLT5nZXQoJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciB0aGlzIE11c3RhY2hlIGluc3RhbmNlIGhhcyBhIGhlbHBlci4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0VuZ2luZTo6c2V0SGVscGVycwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0aGUgaGVscGVyIGlzIHByZXNlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0hlbHBlcigkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldEhlbHBlcnMoKS0+aGFzKCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZSBhIGhlbHBlciBieSBuYW1lLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfRW5naW5lOjpzZXRIZWxwZXJzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlSGVscGVyKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5nZXRIZWxwZXJzKCktPnJlbW92ZSgkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIE11c3RhY2hlIExvZ2dlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgbG9nZ2VyIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBNdXN0YWNoZV9Mb2dnZXIgb3IgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2UKICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfTG9nZ2VyfFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcigkbG9nZ2VyID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGxvZ2dlciAhPT0gbnVsbCAmJiAhKCRsb2dnZXIgaW5zdGFuY2VvZiBNdXN0YWNoZV9Mb2dnZXIgfHwgaXNfYSgkbG9nZ2VyLCAnUHNyXFxMb2dcXExvZ2dlckludGVyZmFjZScpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignRXhwZWN0ZWQgYW4gaW5zdGFuY2Ugb2YgTXVzdGFjaGVfTG9nZ2VyIG9yIFBzclxcTG9nXFxMb2dnZXJJbnRlcmZhY2UuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmdldENhY2hlKCktPmdldExvZ2dlcigpID09PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRDYWNoZSgpLT5zZXRMb2dnZXIoJGxvZ2dlcik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9nZ2VyID0gJGxvZ2dlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBNdXN0YWNoZSBMb2dnZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9Mb2dnZXJ8UHNyXExvZ1xMb2dnZXJJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvZ2dlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2dnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIE11c3RhY2hlIFRva2VuaXplciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfVG9rZW5pemVyICR0b2tlbml6ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRva2VuaXplcihNdXN0YWNoZV9Ub2tlbml6ZXIgJHRva2VuaXplcikKICAgIHsKICAgICAgICAkdGhpcy0+dG9rZW5pemVyID0gJHRva2VuaXplcjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBNdXN0YWNoZSBUb2tlbml6ZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogSWYgbm8gVG9rZW5pemVyIGluc3RhbmNlIGhhcyBiZWVuIGV4cGxpY2l0bHkgc3BlY2lmaWVkLCB0aGlzIG1ldGhvZCB3aWxsIGluc3RhbnRpYXRlIGFuZCByZXR1cm4gYSBuZXcgb25lLgogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfVG9rZW5pemVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb2tlbml6ZXIoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnRva2VuaXplcikpIHsKICAgICAgICAgICAgJHRoaXMtPnRva2VuaXplciA9IG5ldyBNdXN0YWNoZV9Ub2tlbml6ZXIoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW5pemVyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBNdXN0YWNoZSBQYXJzZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX1BhcnNlciAkcGFyc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQYXJzZXIoTXVzdGFjaGVfUGFyc2VyICRwYXJzZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhcnNlciA9ICRwYXJzZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTXVzdGFjaGUgUGFyc2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIElmIG5vIFBhcnNlciBpbnN0YW5jZSBoYXMgYmVlbiBleHBsaWNpdGx5IHNwZWNpZmllZCwgdGhpcyBtZXRob2Qgd2lsbCBpbnN0YW50aWF0ZSBhbmQgcmV0dXJuIGEgbmV3IG9uZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX1BhcnNlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFyc2VyKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5wYXJzZXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5wYXJzZXIgPSBuZXcgTXVzdGFjaGVfUGFyc2VyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBhcnNlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgTXVzdGFjaGUgQ29tcGlsZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX0NvbXBpbGVyICRjb21waWxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tcGlsZXIoTXVzdGFjaGVfQ29tcGlsZXIgJGNvbXBpbGVyKQogICAgewogICAgICAgICR0aGlzLT5jb21waWxlciA9ICRjb21waWxlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBNdXN0YWNoZSBDb21waWxlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBJZiBubyBDb21waWxlciBpbnN0YW5jZSBoYXMgYmVlbiBleHBsaWNpdGx5IHNwZWNpZmllZCwgdGhpcyBtZXRob2Qgd2lsbCBpbnN0YW50aWF0ZSBhbmQgcmV0dXJuIGEgbmV3IG9uZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX0NvbXBpbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21waWxlcigpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+Y29tcGlsZXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21waWxlciA9IG5ldyBNdXN0YWNoZV9Db21waWxlcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21waWxlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgTXVzdGFjaGUgQ2FjaGUgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIE11c3RhY2hlX0NhY2hlICRjYWNoZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2FjaGUoTXVzdGFjaGVfQ2FjaGUgJGNhY2hlKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+bG9nZ2VyKSAmJiAkY2FjaGUtPmdldExvZ2dlcigpID09PSBudWxsKSB7CiAgICAgICAgICAgICRjYWNoZS0+c2V0TG9nZ2VyKCR0aGlzLT5nZXRMb2dnZXIoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y2FjaGUgPSAkY2FjaGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTXVzdGFjaGUgQ2FjaGUgaW5zdGFuY2UuCiAgICAgKgogICAgICogSWYgbm8gQ2FjaGUgaW5zdGFuY2UgaGFzIGJlZW4gZXhwbGljaXRseSBzcGVjaWZpZWQsIHRoaXMgbWV0aG9kIHdpbGwgaW5zdGFudGlhdGUgYW5kIHJldHVybiBhIG5ldyBvbmUuCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9DYWNoZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2FjaGUoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNhY2hlKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0Q2FjaGUobmV3IE11c3RhY2hlX0NhY2hlX05vb3BDYWNoZSgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y2FjaGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgTGFtYmRhIENhY2hlIGluc3RhbmNlLgogICAgICoKICAgICAqIElmICdjYWNoZV9sYW1iZGFfdGVtcGxhdGVzJyBpcyBlbmFibGVkLCB0aGlzIGlzIHRoZSBkZWZhdWx0IGNhY2hlIGluc3RhbmNlLiBPdGhlcndpc2UsIGl0IGlzIGEgTm9vcENhY2hlLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfRW5naW5lOjpnZXRDYWNoZQogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfQ2FjaGUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldExhbWJkYUNhY2hlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNhY2hlTGFtYmRhVGVtcGxhdGVzKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0Q2FjaGUoKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmxhbWJkYUNhY2hlKSkgewogICAgICAgICAgICAkdGhpcy0+bGFtYmRhQ2FjaGUgPSBuZXcgTXVzdGFjaGVfQ2FjaGVfTm9vcENhY2hlKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmxhbWJkYUNhY2hlOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIG1ldGhvZCB0byBnZW5lcmF0ZSBhIE11c3RhY2hlIHRlbXBsYXRlIGNsYXNzLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIG11c3QgYmUgdXBkYXRlZCBhbnkgdGltZSBvcHRpb25zIGFyZSBhZGRlZCB3aGljaCBtYWtlIGl0IHNvCiAgICAgKiB0aGUgc2FtZSB0ZW1wbGF0ZSBjb3VsZCBiZSBwYXJzZWQgYW5kIGNvbXBpbGVkIG11bHRpcGxlIGRpZmZlcmVudCB3YXlzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8TXVzdGFjaGVfU291cmNlICRzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNdXN0YWNoZSBUZW1wbGF0ZSBjbGFzcyBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUZW1wbGF0ZUNsYXNzTmFtZSgkc291cmNlKQogICAgewogICAgICAgIC8vIEZvciB0aGUgbW9zdCBwYXJ0LCBhZGRpbmcgYSBuZXcgb3B0aW9uIGhlcmUgc2hvdWxkIGRvIHRoZSB0cmljay4KICAgICAgICAvLwogICAgICAgIC8vIFBpY2sgYSB2YWx1ZSBoZXJlIHdoaWNoIGlzIHVuaXF1ZSBmb3IgZWFjaCBwb3NzaWJsZSB3YXkgdGhlIHRlbXBsYXRlCiAgICAgICAgLy8gY291bGQgYmUgY29tcGlsZWQuLi4gYnV0IG5vdCBuZWNlc3NhcmlseSB1bmlxdWUgcGVyIG9wdGlvbiB2YWx1ZS4gU2VlCiAgICAgICAgLy8gZXNjYXBlIGJlbG93LCB3aGljaCBvbmx5IG5lZWRzIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiAnY3VzdG9tJyBhbmQKICAgICAgICAvLyAnZGVmYXVsdCcgZXNjYXBlcy4KICAgICAgICAvLwogICAgICAgIC8vIEtlZXAgdGhpcyBsaXN0IGluIGFscGhhYmV0aWNhbCBvcmRlciA6KQogICAgICAgICRjaHVua3MgPSBhcnJheSgKICAgICAgICAgICAgJ2NoYXJzZXQnICAgICAgICAgPT4gJHRoaXMtPmNoYXJzZXQsCiAgICAgICAgICAgICdkZWxpbWl0ZXJzJyAgICAgID0+ICR0aGlzLT5kZWxpbWl0ZXJzID8gJHRoaXMtPmRlbGltaXRlcnMgOiAne3sgfX0nLAogICAgICAgICAgICAnZW50aXR5RmxhZ3MnICAgICA9PiAkdGhpcy0+ZW50aXR5RmxhZ3MsCiAgICAgICAgICAgICdlc2NhcGUnICAgICAgICAgID0+IGlzc2V0KCR0aGlzLT5lc2NhcGUpID8gJ2N1c3RvbScgOiAnZGVmYXVsdCcsCiAgICAgICAgICAgICdrZXknICAgICAgICAgICAgID0+ICgkc291cmNlIGluc3RhbmNlb2YgTXVzdGFjaGVfU291cmNlKSA/ICRzb3VyY2UtPmdldEtleSgpIDogJ3NvdXJjZScsCiAgICAgICAgICAgICdwcmFnbWFzJyAgICAgICAgID0+ICR0aGlzLT5nZXRQcmFnbWFzKCksCiAgICAgICAgICAgICdzdHJpY3RDYWxsYWJsZXMnID0+ICR0aGlzLT5zdHJpY3RDYWxsYWJsZXMsCiAgICAgICAgICAgICd2ZXJzaW9uJyAgICAgICAgID0+IHNlbGY6OlZFUlNJT04sCiAgICAgICAgKTsKCiAgICAgICAgJGtleSA9IGpzb25fZW5jb2RlKCRjaHVua3MpOwoKICAgICAgICAvLyBUZW1wbGF0ZSBTb3VyY2UgaW5zdGFuY2VzIGhhdmUgYWxyZWFkeSBwcm92aWRlZCB0aGVpciBvd24gc291cmNlIGtleS4gRm9yIHN0cmluZ3MsIGp1c3QgaW5jbHVkZSB0aGUgd2hvbGUKICAgICAgICAvLyBzb3VyY2Ugc3RyaW5nIGluIHRoZSBtZDUgaGFzaC4KICAgICAgICBpZiAoISRzb3VyY2UgaW5zdGFuY2VvZiBNdXN0YWNoZV9Tb3VyY2UpIHsKICAgICAgICAgICAgJGtleSAuPSAiXG4iIC4gJHNvdXJjZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVDbGFzc1ByZWZpeCAuIG1kNSgka2V5KTsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBNdXN0YWNoZSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX1RlbXBsYXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkVGVtcGxhdGUoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkU291cmNlKCR0aGlzLT5nZXRMb2FkZXIoKS0+bG9hZCgkbmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogTG9hZCBhIE11c3RhY2hlIHBhcnRpYWwgVGVtcGxhdGUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIGEgaGVscGVyIG1ldGhvZCB1c2VkIGludGVybmFsbHkgYnkgVGVtcGxhdGUgaW5zdGFuY2VzIGZvciBsb2FkaW5nIHBhcnRpYWwgdGVtcGxhdGVzLiBZb3UgY2FuIG1vc3QgbGlrZWx5CiAgICAgKiBpZ25vcmUgaXQgY29tcGxldGVseS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9UZW1wbGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhcnRpYWwoJG5hbWUpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wYXJ0aWFsc0xvYWRlcikpIHsKICAgICAgICAgICAgICAgICRsb2FkZXIgPSAkdGhpcy0+cGFydGlhbHNMb2FkZXI7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkdGhpcy0+bG9hZGVyKSAmJiAhJHRoaXMtPmxvYWRlciBpbnN0YW5jZW9mIE11c3RhY2hlX0xvYWRlcl9TdHJpbmdMb2FkZXIpIHsKICAgICAgICAgICAgICAgICRsb2FkZXIgPSAkdGhpcy0+bG9hZGVyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmxvYWRTb3VyY2UoJGxvYWRlci0+bG9hZCgkbmFtZSkpOwogICAgICAgIH0gY2F0Y2ggKE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gSWYgdGhlIG5hbWVkIHBhcnRpYWwgY2Fubm90IGJlIGZvdW5kLCBsb2cgdGhlbiByZXR1cm4gbnVsbC4KICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6V0FSTklORywKICAgICAgICAgICAgICAgICdQYXJ0aWFsIG5vdCBmb3VuZDogIntuYW1lfSInLAogICAgICAgICAgICAgICAgYXJyYXkoJ25hbWUnID0+ICRlLT5nZXRUZW1wbGF0ZU5hbWUoKSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkIGEgTXVzdGFjaGUgbGFtYmRhIFRlbXBsYXRlIGJ5IHNvdXJjZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIGEgaGVscGVyIG1ldGhvZCB1c2VkIGJ5IFRlbXBsYXRlIGluc3RhbmNlcyB0byBnZW5lcmF0ZSBzdWJ0ZW1wbGF0ZXMgZm9yIExhbWJkYSBzZWN0aW9ucy4gWW91IGNhbiBtb3N0CiAgICAgKiBsaWtlbHkgaWdub3JlIGl0IGNvbXBsZXRlbHkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbXMgKGRlZmF1bHQ6IG51bGwpCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9UZW1wbGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZExhbWJkYSgkc291cmNlLCAkZGVsaW1zID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGRlbGltcyAhPT0gbnVsbCkgewogICAgICAgICAgICAkc291cmNlID0gJGRlbGltcyAuICJcbiIgLiAkc291cmNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkU291cmNlKCRzb3VyY2UsICR0aGlzLT5nZXRMYW1iZGFDYWNoZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluc3RhbnRpYXRlIGFuZCByZXR1cm4gYSBNdXN0YWNoZSBUZW1wbGF0ZSBpbnN0YW5jZSBieSBzb3VyY2UuCiAgICAgKgogICAgICogT3B0aW9uYWxseSBwcm92aWRlIGEgTXVzdGFjaGVfQ2FjaGUgaW5zdGFuY2UuIFRoaXMgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IE11c3RhY2hlX0VuZ2luZTo6bG9hZExhbWJkYSB0byByZXNwZWN0CiAgICAgKiB0aGUgJ2NhY2hlX2xhbWJkYV90ZW1wbGF0ZXMnIGNvbmZpZ3VyYXRpb24gb3B0aW9uLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfRW5naW5lOjpsb2FkVGVtcGxhdGUKICAgICAqIEBzZWUgTXVzdGFjaGVfRW5naW5lOjpsb2FkUGFydGlhbAogICAgICogQHNlZSBNdXN0YWNoZV9FbmdpbmU6OmxvYWRMYW1iZGEKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfE11c3RhY2hlX1NvdXJjZSAkc291cmNlCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfQ2FjaGUgICAgICAgICAkY2FjaGUgIChkZWZhdWx0OiBudWxsKQogICAgICoKICAgICAqIEByZXR1cm4gTXVzdGFjaGVfVGVtcGxhdGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkU291cmNlKCRzb3VyY2UsIE11c3RhY2hlX0NhY2hlICRjYWNoZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGNsYXNzTmFtZSA9ICR0aGlzLT5nZXRUZW1wbGF0ZUNsYXNzTmFtZSgkc291cmNlKTsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dGVtcGxhdGVzWyRjbGFzc05hbWVdKSkgewogICAgICAgICAgICBpZiAoJGNhY2hlID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkY2FjaGUgPSAkdGhpcy0+Z2V0Q2FjaGUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJGNsYXNzTmFtZSwgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICBpZiAoISRjYWNoZS0+bG9hZCgkY2xhc3NOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICRjb21waWxlZCA9ICR0aGlzLT5jb21waWxlKCRzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgICRjYWNoZS0+Y2FjaGUoJGNsYXNzTmFtZSwgJGNvbXBpbGVkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmxvZygKICAgICAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6REVCVUcsCiAgICAgICAgICAgICAgICAnSW5zdGFudGlhdGluZyB0ZW1wbGF0ZTogIntjbGFzc05hbWV9IicsCiAgICAgICAgICAgICAgICBhcnJheSgnY2xhc3NOYW1lJyA9PiAkY2xhc3NOYW1lKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgJHRoaXMtPnRlbXBsYXRlc1skY2xhc3NOYW1lXSA9IG5ldyAkY2xhc3NOYW1lKCR0aGlzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVzWyRjbGFzc05hbWVdOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIG1ldGhvZCB0byB0b2tlbml6ZSBhIE11c3RhY2hlIHRlbXBsYXRlLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfVG9rZW5pemVyOjpzY2FuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBUb2tlbnMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB0b2tlbml6ZSgkc291cmNlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VG9rZW5pemVyKCktPnNjYW4oJHNvdXJjZSwgJHRoaXMtPmRlbGltaXRlcnMpOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIG1ldGhvZCB0byBwYXJzZSBhIE11c3RhY2hlIHRlbXBsYXRlLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfUGFyc2VyOjpwYXJzZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVG9rZW4gdHJlZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlKCRzb3VyY2UpCiAgICB7CiAgICAgICAgJHBhcnNlciA9ICR0aGlzLT5nZXRQYXJzZXIoKTsKICAgICAgICAkcGFyc2VyLT5zZXRQcmFnbWFzKCR0aGlzLT5nZXRQcmFnbWFzKCkpOwoKICAgICAgICByZXR1cm4gJHBhcnNlci0+cGFyc2UoJHRoaXMtPnRva2VuaXplKCRzb3VyY2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgdG8gY29tcGlsZSBhIE11c3RhY2hlIHRlbXBsYXRlLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfQ29tcGlsZXI6OmNvbXBpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfE11c3RhY2hlX1NvdXJjZSAkc291cmNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgZ2VuZXJhdGVkIE11c3RhY2hlIHRlbXBsYXRlIGNsYXNzIGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb21waWxlKCRzb3VyY2UpCiAgICB7CiAgICAgICAgJG5hbWUgPSAkdGhpcy0+Z2V0VGVtcGxhdGVDbGFzc05hbWUoJHNvdXJjZSk7CgogICAgICAgICR0aGlzLT5sb2coCiAgICAgICAgICAgIE11c3RhY2hlX0xvZ2dlcjo6SU5GTywKICAgICAgICAgICAgJ0NvbXBpbGluZyB0ZW1wbGF0ZSB0byAie2NsYXNzTmFtZX0iIGNsYXNzJywKICAgICAgICAgICAgYXJyYXkoJ2NsYXNzTmFtZScgPT4gJG5hbWUpCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRzb3VyY2UgaW5zdGFuY2VvZiBNdXN0YWNoZV9Tb3VyY2UpIHsKICAgICAgICAgICAgJHNvdXJjZSA9ICRzb3VyY2UtPmdldFNvdXJjZSgpOwogICAgICAgIH0KICAgICAgICAkdHJlZSA9ICR0aGlzLT5wYXJzZSgkc291cmNlKTsKCiAgICAgICAgJGNvbXBpbGVyID0gJHRoaXMtPmdldENvbXBpbGVyKCk7CiAgICAgICAgJGNvbXBpbGVyLT5zZXRQcmFnbWFzKCR0aGlzLT5nZXRQcmFnbWFzKCkpOwoKICAgICAgICByZXR1cm4gJGNvbXBpbGVyLT5jb21waWxlKCRzb3VyY2UsICR0cmVlLCAkbmFtZSwgaXNzZXQoJHRoaXMtPmVzY2FwZSksICR0aGlzLT5jaGFyc2V0LCAkdGhpcy0+c3RyaWN0Q2FsbGFibGVzLCAkdGhpcy0+ZW50aXR5RmxhZ3MpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgbG9nIHJlY29yZCBpZiBsb2dnaW5nIGlzIGVuYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwgICBUaGUgbG9nZ2luZyBsZXZlbAogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQgVGhlIGxvZyBjb250ZXh0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbG9nKCRsZXZlbCwgJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxvZ2dlcikpIHsKICAgICAgICAgICAgJHRoaXMtPmxvZ2dlci0+bG9nKCRsZXZlbCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBjb2xsZWN0aW9uIG9mIGhlbHBlcnMgZm9yIGEgTXVzdGFjaGUgaW5zdGFuY2UuCiAqLwpjbGFzcyBNdXN0YWNoZV9IZWxwZXJDb2xsZWN0aW9uCnsKICAgIHByaXZhdGUgJGhlbHBlcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogSGVscGVyIENvbGxlY3Rpb24gY29uc3RydWN0b3IuCiAgICAgKgogICAgICogT3B0aW9uYWxseSBhY2NlcHRzIGFuIGFycmF5IChvciBUcmF2ZXJzYWJsZSkgb2YgYCRuYW1lID0+ICRoZWxwZXJgIHBhaXJzLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgJGhlbHBlcnMgYXJndW1lbnQgaXNuJ3QgYW4gYXJyYXkgb3IgVHJhdmVyc2FibGUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8VHJhdmVyc2FibGUgJGhlbHBlcnMgKGRlZmF1bHQ6IG51bGwpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaGVscGVycyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRoZWxwZXJzID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfYXJyYXkoJGhlbHBlcnMpICYmICEkaGVscGVycyBpbnN0YW5jZW9mIFRyYXZlcnNhYmxlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdIZWxwZXJDb2xsZWN0aW9uIGNvbnN0cnVjdG9yIGV4cGVjdHMgYW4gYXJyYXkgb2YgaGVscGVycycpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGhlbHBlcnMgYXMgJG5hbWUgPT4gJGhlbHBlcikgewogICAgICAgICAgICAkdGhpcy0+YWRkKCRuYW1lLCAkaGVscGVyKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWdpYyBtdXRhdG9yLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbjo6YWRkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIG1peGVkICAkaGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3NldCgkbmFtZSwgJGhlbHBlcikKICAgIHsKICAgICAgICAkdGhpcy0+YWRkKCRuYW1lLCAkaGVscGVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIGhlbHBlciB0byB0aGlzIGNvbGxlY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIG1peGVkICAkaGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGQoJG5hbWUsICRoZWxwZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmhlbHBlcnNbJG5hbWVdID0gJGhlbHBlcjsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIGFjY2Vzc29yLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbjo6Z2V0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgSGVscGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldCgkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBoZWxwZXIgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duSGVscGVyRXhjZXB0aW9uIElmIGhlbHBlciBkb2VzIG5vdCBleGlzdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIEhlbHBlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0KCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhcygkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duSGVscGVyRXhjZXB0aW9uKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aGVscGVyc1skbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWdpYyBpc3NldCgpLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfSGVscGVyQ29sbGVjdGlvbjo6aGFzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIGhlbHBlciBpcyBwcmVzZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2lzc2V0KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGFzKCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBoZWxwZXIgaXMgcHJlc2VudCBpbiB0aGUgY29sbGVjdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgaGVscGVyIGlzIHByZXNlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhcygkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJHRoaXMtPmhlbHBlcnMpOwogICAgfQoKICAgIC8qKgogICAgICogTWFnaWMgdW5zZXQoKS4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0hlbHBlckNvbGxlY3Rpb246OnJlbW92ZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdW5zZXQoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlbW92ZSgkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gaGVscGVyIGlzIHByZXNlbnQgaW4gdGhlIGNvbGxlY3Rpb24uCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93bkhlbHBlckV4Y2VwdGlvbiBpZiB0aGUgcmVxdWVzdGVkIGhlbHBlciBpcyBub3QgcHJlc2VudAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZSgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93bkhlbHBlckV4Y2VwdGlvbigkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICB1bnNldCgkdGhpcy0+aGVscGVyc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXIgdGhlIGhlbHBlciBjb2xsZWN0aW9uLgogICAgICoKICAgICAqIFJlbW92ZXMgYWxsIGhlbHBlcnMgZnJvbSB0aGlzIGNvbGxlY3Rpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyKCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVscGVycyA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBoZWxwZXIgY29sbGVjdGlvbiBpcyBlbXB0eS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0aGUgY29sbGVjdGlvbiBpcyBlbXB0eQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNFbXB0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGVtcHR5KCR0aGlzLT5oZWxwZXJzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBjbGFzcyBhdXRvbG9hZGVyLgogKi8KY2xhc3MgTXVzdGFjaGVfQXV0b2xvYWRlcgp7CiAgICBwcml2YXRlICRiYXNlRGlyOwoKICAgIC8qKgogICAgICogQW4gYXJyYXkgd2hlcmUgdGhlIGtleSBpcyB0aGUgYmFzZURpciBhbmQgdGhlIGtleSBpcyBhbiBpbnN0YW5jZSBvZiB0aGlzCiAgICAgKiBjbGFzcy4KICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRpbnN0YW5jZXM7CgogICAgLyoqCiAgICAgKiBBdXRvbG9hZGVyIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgTXVzdGFjaGUgbGlicmFyeSBiYXNlIGRpcmVjdG9yeSAoZGVmYXVsdDogZGlybmFtZShfX0ZJTEVfXykuJy8uLicpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRiYXNlRGlyID09PSBudWxsKSB7CiAgICAgICAgICAgICRiYXNlRGlyID0gZGlybmFtZShfX0ZJTEVfXykgLiAnLy4uJzsKICAgICAgICB9CgogICAgICAgIC8vIHJlYWxwYXRoIGRvZXNuJ3QgYWx3YXlzIHdvcmssIGZvciBleGFtcGxlLCB3aXRoIHN0cmVhbSBVUklzCiAgICAgICAgJHJlYWxEaXIgPSByZWFscGF0aCgkYmFzZURpcik7CiAgICAgICAgaWYgKGlzX2RpcigkcmVhbERpcikpIHsKICAgICAgICAgICAgJHRoaXMtPmJhc2VEaXIgPSAkcmVhbERpcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+YmFzZURpciA9ICRiYXNlRGlyOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVyIGEgbmV3IGluc3RhbmNlIGFzIGFuIFNQTCBhdXRvbG9hZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgTXVzdGFjaGUgbGlicmFyeSBiYXNlIGRpcmVjdG9yeSAoZGVmYXVsdDogZGlybmFtZShfX0ZJTEVfXykuJy8uLicpCiAgICAgKgogICAgICogQHJldHVybiBNdXN0YWNoZV9BdXRvbG9hZGVyIFJlZ2lzdGVyZWQgQXV0b2xvYWRlciBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRiYXNlRGlyID0gbnVsbCkKICAgIHsKICAgICAgICAka2V5ID0gJGJhc2VEaXIgPyAkYmFzZURpciA6IDA7CgogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGluc3RhbmNlc1ska2V5XSkpIHsKICAgICAgICAgICAgc2VsZjo6JGluc3RhbmNlc1ska2V5XSA9IG5ldyBzZWxmKCRiYXNlRGlyKTsKICAgICAgICB9CgogICAgICAgICRsb2FkZXIgPSBzZWxmOjokaW5zdGFuY2VzWyRrZXldOwogICAgICAgIHNwbF9hdXRvbG9hZF9yZWdpc3RlcihhcnJheSgkbG9hZGVyLCAnYXV0b2xvYWQnKSk7CgogICAgICAgIHJldHVybiAkbG9hZGVyOwogICAgfQoKICAgIC8qKgogICAgICogQXV0b2xvYWQgTXVzdGFjaGUgY2xhc3Nlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjbGFzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXV0b2xvYWQoJGNsYXNzKQogICAgewogICAgICAgIGlmICgkY2xhc3NbMF0gPT09ICdcXCcpIHsKICAgICAgICAgICAgJGNsYXNzID0gc3Vic3RyKCRjbGFzcywgMSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCRjbGFzcywgJ011c3RhY2hlJykgIT09IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSBzcHJpbnRmKCclcy8lcy5waHAnLCAkdGhpcy0+YmFzZURpciwgc3RyX3JlcGxhY2UoJ18nLCAnLycsICRjbGFzcykpOwogICAgICAgIGlmIChpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICByZXF1aXJlICRmaWxlOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBDb21waWxlciBjbGFzcy4KICoKICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgdHVybmluZyBhIE11c3RhY2hlIHRva2VuIHBhcnNlIHRyZWUgaW50byBub3JtYWwgUEhQIHNvdXJjZSBjb2RlLgogKi8KY2xhc3MgTXVzdGFjaGVfQ29tcGlsZXIKewogICAgcHJpdmF0ZSAkcHJhZ21hczsKICAgIHByaXZhdGUgJGRlZmF1bHRQcmFnbWFzID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJHNlY3Rpb25zOwogICAgcHJpdmF0ZSAkYmxvY2tzOwogICAgcHJpdmF0ZSAkc291cmNlOwogICAgcHJpdmF0ZSAkaW5kZW50TmV4dExpbmU7CiAgICBwcml2YXRlICRjdXN0b21Fc2NhcGU7CiAgICBwcml2YXRlICRlbnRpdHlGbGFnczsKICAgIHByaXZhdGUgJGNoYXJzZXQ7CiAgICBwcml2YXRlICRzdHJpY3RDYWxsYWJsZXM7CgogICAgLyoqCiAgICAgKiBDb21waWxlIGEgTXVzdGFjaGUgdG9rZW4gcGFyc2UgdHJlZSBpbnRvIFBIUCBzb3VyY2UgY29kZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UgICAgICAgICAgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlIGNvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRyZWUgICAgICAgICAgICBQYXJzZSB0cmVlIG9mIE11c3RhY2hlIHRva2VucwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSAgICAgICAgICAgIE11c3RhY2hlIFRlbXBsYXRlIGNsYXNzIG5hbWUKICAgICAqIEBwYXJhbSBib29sICAgJGN1c3RvbUVzY2FwZSAgICAoZGVmYXVsdDogZmFsc2UpCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyc2V0ICAgICAgICAgKGRlZmF1bHQ6ICdVVEYtOCcpCiAgICAgKiBAcGFyYW0gYm9vbCAgICRzdHJpY3RDYWxsYWJsZXMgKGRlZmF1bHQ6IGZhbHNlKQogICAgICogQHBhcmFtIGludCAgICAkZW50aXR5RmxhZ3MgICAgIChkZWZhdWx0OiBFTlRfQ09NUEFUKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBQSFAgc291cmNlIGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBpbGUoJHNvdXJjZSwgYXJyYXkgJHRyZWUsICRuYW1lLCAkY3VzdG9tRXNjYXBlID0gZmFsc2UsICRjaGFyc2V0ID0gJ1VURi04JywgJHN0cmljdENhbGxhYmxlcyA9IGZhbHNlLCAkZW50aXR5RmxhZ3MgPSBFTlRfQ09NUEFUKQogICAgewogICAgICAgICR0aGlzLT5wcmFnbWFzICAgICAgICAgPSAkdGhpcy0+ZGVmYXVsdFByYWdtYXM7CiAgICAgICAgJHRoaXMtPnNlY3Rpb25zICAgICAgICA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmJsb2NrcyAgICAgICAgICA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnNvdXJjZSAgICAgICAgICA9ICRzb3VyY2U7CiAgICAgICAgJHRoaXMtPmluZGVudE5leHRMaW5lICA9IHRydWU7CiAgICAgICAgJHRoaXMtPmN1c3RvbUVzY2FwZSAgICA9ICRjdXN0b21Fc2NhcGU7CiAgICAgICAgJHRoaXMtPmVudGl0eUZsYWdzICAgICA9ICRlbnRpdHlGbGFnczsKICAgICAgICAkdGhpcy0+Y2hhcnNldCAgICAgICAgID0gJGNoYXJzZXQ7CiAgICAgICAgJHRoaXMtPnN0cmljdENhbGxhYmxlcyA9ICRzdHJpY3RDYWxsYWJsZXM7CgogICAgICAgIHJldHVybiAkdGhpcy0+d3JpdGVDb2RlKCR0cmVlLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmFibGUgcHJhZ21hcyBhY3Jvc3MgYWxsIHRlbXBsYXRlcywgcmVnYXJkbGVzcyBvZiB0aGUgcHJlc2VuY2Ugb2YgcHJhZ21hCiAgICAgKiB0YWdzIGluIHRoZSBpbmRpdmlkdWFsIHRlbXBsYXRlcy4KICAgICAqCiAgICAgKiBAaW50ZXJuYWwgVXNlcnMgc2hvdWxkIHNldCBnbG9iYWwgcHJhZ21hcyBpbiBNdXN0YWNoZV9FbmdpbmUsIG5vdCBoZXJlIDopCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRwcmFnbWFzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmFnbWFzKGFycmF5ICRwcmFnbWFzKQogICAgewogICAgICAgICR0aGlzLT5wcmFnbWFzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcHJhZ21hcyBhcyAkcHJhZ21hKSB7CiAgICAgICAgICAgICR0aGlzLT5wcmFnbWFzWyRwcmFnbWFdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmRlZmF1bHRQcmFnbWFzID0gJHRoaXMtPnByYWdtYXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIHdhbGtpbmcgdGhlIE11c3RhY2hlIHRva2VuIHBhcnNlIHRyZWUuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uIHVwb24gZW5jb3VudGVyaW5nIHVua25vd24gdG9rZW4gdHlwZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRyZWUgIFBhcnNlIHRyZWUgb2YgTXVzdGFjaGUgdG9rZW5zCiAgICAgKiBAcGFyYW0gaW50ICAgJGxldmVsIChkZWZhdWx0OiAwKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBQSFAgc291cmNlIGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3YWxrKGFycmF5ICR0cmVlLCAkbGV2ZWwgPSAwKQogICAgewogICAgICAgICRjb2RlID0gJyc7CiAgICAgICAgJGxldmVsKys7CiAgICAgICAgZm9yZWFjaCAoJHRyZWUgYXMgJG5vZGUpIHsKICAgICAgICAgICAgc3dpdGNoICgkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdKSB7CiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9QUkFHTUE6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnByYWdtYXNbJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1NFQ1RJT046CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnNlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICBpc3NldCgkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkZJTFRFUlNdKSA/ICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10gOiBhcnJheSgpLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVYXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpFTkRdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok9UQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkNUQUddLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0lOVkVSVEVEOgogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5pbnZlcnRlZFNlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICBpc3NldCgkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OkZJTFRFUlNdKSA/ICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10gOiBhcnJheSgpLAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BBUlRJQUw6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnBhcnRpYWwoCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlzc2V0KCRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6SU5ERU5UXSkgPyAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVOVF0gOiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgJGxldmVsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9QQVJFTlQ6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnBhcmVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNzZXQoJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFTlRdKSA/ICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6SU5ERU5UXSA6ICcnLAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5PREVTXSwKICAgICAgICAgICAgICAgICAgICAgICAgJGxldmVsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9CTE9DS19BUkc6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPmJsb2NrQXJnKAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5PREVTXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFWF0sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RU5EXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpPVEFHXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpDVEFHXSwKICAgICAgICAgICAgICAgICAgICAgICAgJGxldmVsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9CTE9DS19WQVI6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPmJsb2NrVmFyKAogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZVtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5PREVTXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFWF0sCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RU5EXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpPVEFHXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpDVEFHXSwKICAgICAgICAgICAgICAgICAgICAgICAgJGxldmVsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9DT01NRU5UOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0VTQ0FQRUQ6CiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9VTkVTQ0FQRUQ6CiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9VTkVTQ0FQRURfMjoKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+dmFyaWFibGUoCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlzc2V0KCRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6RklMVEVSU10pID8gJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpGSUxURVJTXSA6IGFycmF5KCksCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0gPT09IE11c3RhY2hlX1Rva2VuaXplcjo6VF9FU0NBUEVELAogICAgICAgICAgICAgICAgICAgICAgICAkbGV2ZWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX1RFWFQ6CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnRleHQoJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpWQUxVRV0sICRsZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbihzcHJpbnRmKCdVbmtub3duIHRva2VuIHR5cGU6ICVzJywgJG5vZGVbTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSksICRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb2RlOwogICAgfQoKICAgIGNvbnN0IEtMQVNTID0gJzw/cGhwCgogICAgICAgIGNsYXNzICVzIGV4dGVuZHMgTXVzdGFjaGVfVGVtcGxhdGUKICAgICAgICB7CiAgICAgICAgICAgIHByaXZhdGUgJGxhbWJkYUhlbHBlcjslcwoKICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlckludGVybmFsKE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQsICRpbmRlbnQgPSBcJ1wnKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bGFtYmRhSGVscGVyID0gbmV3IE11c3RhY2hlX0xhbWJkYUhlbHBlcigkdGhpcy0+bXVzdGFjaGUsICRjb250ZXh0KTsKICAgICAgICAgICAgICAgICRidWZmZXIgPSBcJ1wnOwogICAgICAgICVzCgogICAgICAgICAgICAgICAgcmV0dXJuICRidWZmZXI7CiAgICAgICAgICAgIH0KICAgICAgICAlcwogICAgICAgICVzCiAgICAgICAgfSc7CgogICAgY29uc3QgS0xBU1NfTk9fTEFNQkRBUyA9ICc8P3BocAoKICAgICAgICBjbGFzcyAlcyBleHRlbmRzIE11c3RhY2hlX1RlbXBsYXRlCiAgICAgICAgeyVzCiAgICAgICAgICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXJJbnRlcm5hbChNdXN0YWNoZV9Db250ZXh0ICRjb250ZXh0LCAkaW5kZW50ID0gXCdcJykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgJGJ1ZmZlciA9IFwnXCc7CiAgICAgICAgJXMKCiAgICAgICAgICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgICAgICAgICAgfQogICAgICAgIH0nOwoKICAgIGNvbnN0IFNUUklDVF9DQUxMQUJMRSA9ICdwcm90ZWN0ZWQgJHN0cmljdENhbGxhYmxlcyA9IHRydWU7JzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIGNsYXNzIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkdHJlZSBQYXJzZSB0cmVlIG9mIE11c3RhY2hlIHRva2VucwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBNdXN0YWNoZSBUZW1wbGF0ZSBjbGFzcyBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlQ29kZSgkdHJlZSwgJG5hbWUpCiAgICB7CiAgICAgICAgJGNvZGUgICAgID0gJHRoaXMtPndhbGsoJHRyZWUpOwogICAgICAgICRzZWN0aW9ucyA9IGltcGxvZGUoIlxuIiwgJHRoaXMtPnNlY3Rpb25zKTsKICAgICAgICAkYmxvY2tzICAgPSBpbXBsb2RlKCJcbiIsICR0aGlzLT5ibG9ja3MpOwogICAgICAgICRrbGFzcyAgICA9IGVtcHR5KCR0aGlzLT5zZWN0aW9ucykgJiYgZW1wdHkoJHRoaXMtPmJsb2NrcykgPyBzZWxmOjpLTEFTU19OT19MQU1CREFTIDogc2VsZjo6S0xBU1M7CgogICAgICAgICRjYWxsYWJsZSA9ICR0aGlzLT5zdHJpY3RDYWxsYWJsZXMgPyAkdGhpcy0+cHJlcGFyZShzZWxmOjpTVFJJQ1RfQ0FMTEFCTEUpIDogJyc7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKCRrbGFzcywgMCwgZmFsc2UsIHRydWUpLCAkbmFtZSwgJGNhbGxhYmxlLCAkY29kZSwgJHNlY3Rpb25zLCAkYmxvY2tzKTsKICAgIH0KCiAgICBjb25zdCBCTE9DS19WQVIgPSAnCiAgICAgICAgJGJsb2NrRnVuY3Rpb24gPSAkY29udGV4dC0+ZmluZEluQmxvY2soJXMpOwogICAgICAgIGlmIChpc19jYWxsYWJsZSgkYmxvY2tGdW5jdGlvbikpIHsKICAgICAgICAgICAgJGJ1ZmZlciAuPSBjYWxsX3VzZXJfZnVuYygkYmxvY2tGdW5jdGlvbiwgJGNvbnRleHQpOwogICAgICAgICVzfQogICAgJzsKCiAgICBjb25zdCBCTE9DS19WQVJfRUxTRSA9ICd9IGVsc2UgeyVzJzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIGluaGVyaXRhbmNlIGJsb2NrIHZhcmlhYmxlIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkbm9kZXMgQXJyYXkgb2YgY2hpbGQgdG9rZW5zCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCAgICBTZWN0aW9uIG5hbWUKICAgICAqIEBwYXJhbSBpbnQgICAgJHN0YXJ0IFNlY3Rpb24gc3RhcnQgb2Zmc2V0CiAgICAgKiBAcGFyYW0gaW50ICAgICRlbmQgICBTZWN0aW9uIGVuZCBvZmZzZXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJG90YWcgIEN1cnJlbnQgTXVzdGFjaGUgb3BlbmluZyB0YWcKICAgICAqIEBwYXJhbSBzdHJpbmcgJGN0YWcgIEN1cnJlbnQgTXVzdGFjaGUgY2xvc2luZyB0YWcKICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGJsb2NrVmFyKCRub2RlcywgJGlkLCAkc3RhcnQsICRlbmQsICRvdGFnLCAkY3RhZywgJGxldmVsKQogICAgewogICAgICAgICRpZCA9IHZhcl9leHBvcnQoJGlkLCB0cnVlKTsKCiAgICAgICAgJGVsc2UgPSAkdGhpcy0+d2Fsaygkbm9kZXMsICRsZXZlbCk7CiAgICAgICAgaWYgKCRlbHNlICE9PSAnJykgewogICAgICAgICAgICAkZWxzZSA9IHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6QkxPQ0tfVkFSX0VMU0UsICRsZXZlbCArIDEsIGZhbHNlLCB0cnVlKSwgJGVsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6QkxPQ0tfVkFSLCAkbGV2ZWwpLCAkaWQsICRlbHNlKTsKICAgIH0KCiAgICBjb25zdCBCTE9DS19BUkcgPSAnJXMgPT4gYXJyYXkoJHRoaXMsIFwnYmxvY2slc1wnKSwnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgaW5oZXJpdGFuY2UgYmxvY2sgYXJndW1lbnQgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRub2RlcyBBcnJheSBvZiBjaGlsZCB0b2tlbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkICAgIFNlY3Rpb24gbmFtZQogICAgICogQHBhcmFtIGludCAgICAkc3RhcnQgU2VjdGlvbiBzdGFydCBvZmZzZXQKICAgICAqIEBwYXJhbSBpbnQgICAgJGVuZCAgIFNlY3Rpb24gZW5kIG9mZnNldAogICAgICogQHBhcmFtIHN0cmluZyAkb3RhZyAgQ3VycmVudCBNdXN0YWNoZSBvcGVuaW5nIHRhZwogICAgICogQHBhcmFtIHN0cmluZyAkY3RhZyAgQ3VycmVudCBNdXN0YWNoZSBjbG9zaW5nIHRhZwogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYmxvY2tBcmcoJG5vZGVzLCAkaWQsICRzdGFydCwgJGVuZCwgJG90YWcsICRjdGFnLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgJGtleSA9ICR0aGlzLT5ibG9jaygkbm9kZXMpOwogICAgICAgICRrZXlzdHIgPSB2YXJfZXhwb3J0KCRrZXksIHRydWUpOwogICAgICAgICRpZCA9IHZhcl9leHBvcnQoJGlkLCB0cnVlKTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6QkxPQ0tfQVJHLCAkbGV2ZWwpLCAkaWQsICRrZXkpOwogICAgfQoKICAgIGNvbnN0IEJMT0NLX0ZVTkNUSU9OID0gJwogICAgICAgIHB1YmxpYyBmdW5jdGlvbiBibG9jayVzKCRjb250ZXh0KQogICAgICAgIHsKICAgICAgICAgICAgJGluZGVudCA9ICRidWZmZXIgPSBcJ1wnOyVzCgogICAgICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgICAgICB9CiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgaW5oZXJpdGFuY2UgYmxvY2sgZnVuY3Rpb24gUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJG5vZGVzIEFycmF5IG9mIGNoaWxkIHRva2VucwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIGtleSBvZiBuZXcgYmxvY2sgZnVuY3Rpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBibG9jaygkbm9kZXMpCiAgICB7CiAgICAgICAgJGNvZGUgPSAkdGhpcy0+d2Fsaygkbm9kZXMsIDApOwogICAgICAgICRrZXkgPSB1Y2ZpcnN0KG1kNSgkY29kZSkpOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5ibG9ja3NbJGtleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5ibG9ja3NbJGtleV0gPSBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OkJMT0NLX0ZVTkNUSU9OLCAwKSwgJGtleSwgJGNvZGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRrZXk7CiAgICB9CgogICAgY29uc3QgU0VDVElPTl9DQUxMID0gJwogICAgICAgIC8vICVzIHNlY3Rpb24KICAgICAgICAkdmFsdWUgPSAkY29udGV4dC0+JXMoJXMpOyVzCiAgICAgICAgJGJ1ZmZlciAuPSAkdGhpcy0+c2VjdGlvbiVzKCRjb250ZXh0LCAkaW5kZW50LCAkdmFsdWUpOwogICAgJzsKCiAgICBjb25zdCBTRUNUSU9OID0gJwogICAgICAgIHByaXZhdGUgZnVuY3Rpb24gc2VjdGlvbiVzKE11c3RhY2hlX0NvbnRleHQgJGNvbnRleHQsICRpbmRlbnQsICR2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgICRidWZmZXIgPSBcJ1wnOwoKICAgICAgICAgICAgaWYgKCVzKSB7CiAgICAgICAgICAgICAgICAkc291cmNlID0gJXM7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gY2FsbF91c2VyX2Z1bmMoJHZhbHVlLCAkc291cmNlLCAlcyk7CiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRyZXN1bHQsIFwne3tcJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkcmVzdWx0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICR0aGlzLT5tdXN0YWNoZQogICAgICAgICAgICAgICAgICAgICAgICAtPmxvYWRMYW1iZGEoKHN0cmluZykgJHJlc3VsdCVzKQogICAgICAgICAgICAgICAgICAgICAgICAtPnJlbmRlckludGVybmFsKCRjb250ZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCFlbXB0eSgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWVzID0gJHRoaXMtPmlzSXRlcmFibGUoJHZhbHVlKSA/ICR2YWx1ZSA6IGFycmF5KCR2YWx1ZSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdmFsdWVzIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICRjb250ZXh0LT5wdXNoKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgJXMKICAgICAgICAgICAgICAgICAgICAkY29udGV4dC0+cG9wKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgICAgIH0KICAgICc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBzZWN0aW9uIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICRub2RlcyAgIEFycmF5IG9mIGNoaWxkIHRva2VucwogICAgICogQHBhcmFtIHN0cmluZyAgICRpZCAgICAgIFNlY3Rpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZ1tdICRmaWx0ZXJzIEFycmF5IG9mIGZpbHRlcnMKICAgICAqIEBwYXJhbSBpbnQgICAgICAkc3RhcnQgICBTZWN0aW9uIHN0YXJ0IG9mZnNldAogICAgICogQHBhcmFtIGludCAgICAgICRlbmQgICAgIFNlY3Rpb24gZW5kIG9mZnNldAogICAgICogQHBhcmFtIHN0cmluZyAgICRvdGFnICAgIEN1cnJlbnQgTXVzdGFjaGUgb3BlbmluZyB0YWcKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkY3RhZyAgICBDdXJyZW50IE11c3RhY2hlIGNsb3NpbmcgdGFnCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIHNlY3Rpb24gUEhQIHNvdXJjZSBjb2RlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2VjdGlvbigkbm9kZXMsICRpZCwgJGZpbHRlcnMsICRzdGFydCwgJGVuZCwgJG90YWcsICRjdGFnLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgJHNvdXJjZSAgID0gdmFyX2V4cG9ydChzdWJzdHIoJHRoaXMtPnNvdXJjZSwgJHN0YXJ0LCAkZW5kIC0gJHN0YXJ0KSwgdHJ1ZSk7CiAgICAgICAgJGNhbGxhYmxlID0gJHRoaXMtPmdldENhbGxhYmxlKCk7CgogICAgICAgIGlmICgkb3RhZyAhPT0gJ3t7JyB8fCAkY3RhZyAhPT0gJ319JykgewogICAgICAgICAgICAkZGVsaW1UYWcgPSB2YXJfZXhwb3J0KHNwcmludGYoJ3t7PSAlcyAlcyA9fX0nLCAkb3RhZywgJGN0YWcpLCB0cnVlKTsKICAgICAgICAgICAgJGhlbHBlciA9IHNwcmludGYoJyR0aGlzLT5sYW1iZGFIZWxwZXItPndpdGhEZWxpbWl0ZXJzKCVzKScsICRkZWxpbVRhZyk7CiAgICAgICAgICAgICRkZWxpbXMgPSAnLCAnIC4gJGRlbGltVGFnOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRoZWxwZXIgPSAnJHRoaXMtPmxhbWJkYUhlbHBlcic7CiAgICAgICAgICAgICRkZWxpbXMgPSAnJzsKICAgICAgICB9CgogICAgICAgICRrZXkgPSB1Y2ZpcnN0KG1kNSgkZGVsaW1zIC4gIlxuIiAuICRzb3VyY2UpKTsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+c2VjdGlvbnNbJGtleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZWN0aW9uc1ska2V5XSA9IHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6U0VDVElPTiksICRrZXksICRjYWxsYWJsZSwgJHNvdXJjZSwgJGhlbHBlciwgJGRlbGltcywgJHRoaXMtPndhbGsoJG5vZGVzLCAyKSk7CiAgICAgICAgfQoKICAgICAgICAkbWV0aG9kICA9ICR0aGlzLT5nZXRGaW5kTWV0aG9kKCRpZCk7CiAgICAgICAgJGlkICAgICAgPSB2YXJfZXhwb3J0KCRpZCwgdHJ1ZSk7CiAgICAgICAgJGZpbHRlcnMgPSAkdGhpcy0+Z2V0RmlsdGVycygkZmlsdGVycywgJGxldmVsKTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6U0VDVElPTl9DQUxMLCAkbGV2ZWwpLCAkaWQsICRtZXRob2QsICRpZCwgJGZpbHRlcnMsICRrZXkpOwogICAgfQoKICAgIGNvbnN0IElOVkVSVEVEX1NFQ1RJT04gPSAnCiAgICAgICAgLy8gJXMgaW52ZXJ0ZWQgc2VjdGlvbgogICAgICAgICR2YWx1ZSA9ICRjb250ZXh0LT4lcyglcyk7JXMKICAgICAgICBpZiAoZW1wdHkoJHZhbHVlKSkgewogICAgICAgICAgICAlcwogICAgICAgIH0KICAgICc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBpbnZlcnRlZCBzZWN0aW9uIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICRub2RlcyAgIEFycmF5IG9mIGNoaWxkIHRva2VucwogICAgICogQHBhcmFtIHN0cmluZyAgICRpZCAgICAgIFNlY3Rpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZ1tdICRmaWx0ZXJzIEFycmF5IG9mIGZpbHRlcnMKICAgICAqIEBwYXJhbSBpbnQgICAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgaW52ZXJ0ZWQgc2VjdGlvbiBQSFAgc291cmNlIGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbnZlcnRlZFNlY3Rpb24oJG5vZGVzLCAkaWQsICRmaWx0ZXJzLCAkbGV2ZWwpCiAgICB7CiAgICAgICAgJG1ldGhvZCAgPSAkdGhpcy0+Z2V0RmluZE1ldGhvZCgkaWQpOwogICAgICAgICRpZCAgICAgID0gdmFyX2V4cG9ydCgkaWQsIHRydWUpOwogICAgICAgICRmaWx0ZXJzID0gJHRoaXMtPmdldEZpbHRlcnMoJGZpbHRlcnMsICRsZXZlbCk7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OklOVkVSVEVEX1NFQ1RJT04sICRsZXZlbCksICRpZCwgJG1ldGhvZCwgJGlkLCAkZmlsdGVycywgJHRoaXMtPndhbGsoJG5vZGVzLCAkbGV2ZWwpKTsKICAgIH0KCiAgICBjb25zdCBQQVJUSUFMX0lOREVOVCA9ICcsICRpbmRlbnQgLiAlcyc7CiAgICBjb25zdCBQQVJUSUFMID0gJwogICAgICAgIGlmICgkcGFydGlhbCA9ICR0aGlzLT5tdXN0YWNoZS0+bG9hZFBhcnRpYWwoJXMpKSB7CiAgICAgICAgICAgICRidWZmZXIgLj0gJHBhcnRpYWwtPnJlbmRlckludGVybmFsKCRjb250ZXh0JXMpOwogICAgICAgIH0KICAgICc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBwYXJ0aWFsIGNhbGwgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCAgICAgUGFydGlhbCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbmRlbnQgV2hpdGVzcGFjZSBpbmRlbnQgdG8gYXBwbHkgdG8gcGFydGlhbAogICAgICogQHBhcmFtIGludCAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgcGFydGlhbCBjYWxsIFBIUCBzb3VyY2UgY29kZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnRpYWwoJGlkLCAkaW5kZW50LCAkbGV2ZWwpCiAgICB7CiAgICAgICAgaWYgKCRpbmRlbnQgIT09ICcnKSB7CiAgICAgICAgICAgICRpbmRlbnRQYXJhbSA9IHNwcmludGYoc2VsZjo6UEFSVElBTF9JTkRFTlQsIHZhcl9leHBvcnQoJGluZGVudCwgdHJ1ZSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpbmRlbnRQYXJhbSA9ICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoCiAgICAgICAgICAgICR0aGlzLT5wcmVwYXJlKHNlbGY6OlBBUlRJQUwsICRsZXZlbCksCiAgICAgICAgICAgIHZhcl9leHBvcnQoJGlkLCB0cnVlKSwKICAgICAgICAgICAgJGluZGVudFBhcmFtCiAgICAgICAgKTsKICAgIH0KCiAgICBjb25zdCBQQVJFTlQgPSAnCiAgICAgICAgaWYgKCRwYXJlbnQgPSAkdGhpcy0+bXVzdGFjaGUtPmxvYWRQYXJ0aWFsKCVzKSkgewogICAgICAgICAgICAkY29udGV4dC0+cHVzaEJsb2NrQ29udGV4dChhcnJheSglcwogICAgICAgICAgICApKTsKICAgICAgICAgICAgJGJ1ZmZlciAuPSAkcGFyZW50LT5yZW5kZXJJbnRlcm5hbCgkY29udGV4dCwgJGluZGVudCk7CiAgICAgICAgICAgICRjb250ZXh0LT5wb3BCbG9ja0NvbnRleHQoKTsKICAgICAgICB9CiAgICAnOwoKICAgIGNvbnN0IFBBUkVOVF9OT19DT05URVhUID0gJwogICAgICAgIGlmICgkcGFyZW50ID0gJHRoaXMtPm11c3RhY2hlLT5sb2FkUGFydGlhbCglcykpIHsKICAgICAgICAgICAgJGJ1ZmZlciAuPSAkcGFyZW50LT5yZW5kZXJJbnRlcm5hbCgkY29udGV4dCwgJGluZGVudCk7CiAgICAgICAgfQogICAgJzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIGluaGVyaXRhbmNlIHBhcmVudCBjYWxsIFBIUCBzb3VyY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgICAgUGFyZW50IHRhZyBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbmRlbnQgICBXaGl0ZXNwYWNlIGluZGVudCB0byBhcHBseSB0byBwYXJlbnQKICAgICAqIEBwYXJhbSBhcnJheSAgJGNoaWxkcmVuIENoaWxkIG5vZGVzCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBQSFAgc291cmNlIGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwYXJlbnQoJGlkLCAkaW5kZW50LCBhcnJheSAkY2hpbGRyZW4sICRsZXZlbCkKICAgIHsKICAgICAgICAkcmVhbENoaWxkcmVuID0gYXJyYXlfZmlsdGVyKCRjaGlsZHJlbiwgYXJyYXkoX19DTEFTU19fLCAnb25seUJsb2NrQXJncycpKTsKCiAgICAgICAgaWYgKGVtcHR5KCRyZWFsQ2hpbGRyZW4pKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OlBBUkVOVF9OT19DT05URVhULCAkbGV2ZWwpLCB2YXJfZXhwb3J0KCRpZCwgdHJ1ZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoCiAgICAgICAgICAgICR0aGlzLT5wcmVwYXJlKHNlbGY6OlBBUkVOVCwgJGxldmVsKSwKICAgICAgICAgICAgdmFyX2V4cG9ydCgkaWQsIHRydWUpLAogICAgICAgICAgICAkdGhpcy0+d2FsaygkcmVhbENoaWxkcmVuLCAkbGV2ZWwgKyAxKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciBmaWx0ZXJpbmcgb3V0IG5vbi1ibG9jay1hcmcgdG9rZW5zLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIGlmICRub2RlIGlzIGEgYmxvY2sgYXJnIHRva2VuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIG9ubHlCbG9ja0FyZ3MoYXJyYXkgJG5vZGUpCiAgICB7CiAgICAgICAgcmV0dXJuICRub2RlW011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0gPT09IE11c3RhY2hlX1Rva2VuaXplcjo6VF9CTE9DS19BUkc7CiAgICB9CgogICAgY29uc3QgVkFSSUFCTEUgPSAnCiAgICAgICAgJHZhbHVlID0gJHRoaXMtPnJlc29sdmVWYWx1ZSgkY29udGV4dC0+JXMoJXMpLCAkY29udGV4dCk7JXMKICAgICAgICAkYnVmZmVyIC49ICVzJXM7CiAgICAnOwoKICAgIC8qKgogICAgICogR2VuZXJhdGUgTXVzdGFjaGUgVGVtcGxhdGUgdmFyaWFibGUgaW50ZXJwb2xhdGlvbiBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkaWQgICAgICBWYXJpYWJsZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGZpbHRlcnMgQXJyYXkgb2YgZmlsdGVycwogICAgICogQHBhcmFtIGJvb2wgICAgICRlc2NhcGUgIEVzY2FwZSB0aGUgdmFyaWFibGUgdmFsdWUgZm9yIG91dHB1dD8KICAgICAqIEBwYXJhbSBpbnQgICAgICAkbGV2ZWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBHZW5lcmF0ZWQgdmFyaWFibGUgaW50ZXJwb2xhdGlvbiBQSFAgc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFyaWFibGUoJGlkLCAkZmlsdGVycywgJGVzY2FwZSwgJGxldmVsKQogICAgewogICAgICAgICRtZXRob2QgID0gJHRoaXMtPmdldEZpbmRNZXRob2QoJGlkKTsKICAgICAgICAkaWQgICAgICA9ICgkbWV0aG9kICE9PSAnbGFzdCcpID8gdmFyX2V4cG9ydCgkaWQsIHRydWUpIDogJyc7CiAgICAgICAgJGZpbHRlcnMgPSAkdGhpcy0+Z2V0RmlsdGVycygkZmlsdGVycywgJGxldmVsKTsKICAgICAgICAkdmFsdWUgICA9ICRlc2NhcGUgPyAkdGhpcy0+Z2V0RXNjYXBlKCkgOiAnJHZhbHVlJzsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHRoaXMtPnByZXBhcmUoc2VsZjo6VkFSSUFCTEUsICRsZXZlbCksICRtZXRob2QsICRpZCwgJGZpbHRlcnMsICR0aGlzLT5mbHVzaEluZGVudCgpLCAkdmFsdWUpOwogICAgfQoKICAgIGNvbnN0IEZJTFRFUiA9ICcKICAgICAgICAkZmlsdGVyID0gJGNvbnRleHQtPiVzKCVzKTsKICAgICAgICBpZiAoISglcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duRmlsdGVyRXhjZXB0aW9uKCVzKTsKICAgICAgICB9CiAgICAgICAgJHZhbHVlID0gY2FsbF91c2VyX2Z1bmMoJGZpbHRlciwgJHZhbHVlKTslcwogICAgJzsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlIE11c3RhY2hlIFRlbXBsYXRlIHZhcmlhYmxlIGZpbHRlcmluZyBQSFAgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZmlsdGVycyBBcnJheSBvZiBmaWx0ZXJzCiAgICAgKiBAcGFyYW0gaW50ICAgICAgJGxldmVsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgR2VuZXJhdGVkIGZpbHRlciBQSFAgc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RmlsdGVycyhhcnJheSAkZmlsdGVycywgJGxldmVsKQogICAgewogICAgICAgIGlmIChlbXB0eSgkZmlsdGVycykpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgJG5hbWUgICAgID0gYXJyYXlfc2hpZnQoJGZpbHRlcnMpOwogICAgICAgICRtZXRob2QgICA9ICR0aGlzLT5nZXRGaW5kTWV0aG9kKCRuYW1lKTsKICAgICAgICAkZmlsdGVyICAgPSAoJG1ldGhvZCAhPT0gJ2xhc3QnKSA/IHZhcl9leHBvcnQoJG5hbWUsIHRydWUpIDogJyc7CiAgICAgICAgJGNhbGxhYmxlID0gJHRoaXMtPmdldENhbGxhYmxlKCckZmlsdGVyJyk7CiAgICAgICAgJG1zZyAgICAgID0gdmFyX2V4cG9ydCgkbmFtZSwgdHJ1ZSk7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5wcmVwYXJlKHNlbGY6OkZJTFRFUiwgJGxldmVsKSwgJG1ldGhvZCwgJGZpbHRlciwgJGNhbGxhYmxlLCAkbXNnLCAkdGhpcy0+Z2V0RmlsdGVycygkZmlsdGVycywgJGxldmVsKSk7CiAgICB9CgogICAgY29uc3QgTElORSA9ICckYnVmZmVyIC49ICJcbiI7JzsKICAgIGNvbnN0IFRFWFQgPSAnJGJ1ZmZlciAuPSAlcyVzOyc7CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBvdXRwdXQgQnVmZmVyIGNhbGwgUEhQIHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0CiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEdlbmVyYXRlZCBvdXRwdXQgQnVmZmVyIGNhbGwgUEhQIHNvdXJjZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRleHQoJHRleHQsICRsZXZlbCkKICAgIHsKICAgICAgICAkaW5kZW50TmV4dExpbmUgPSAoc3Vic3RyKCR0ZXh0LCAtMSkgPT09ICJcbiIpOwogICAgICAgICRjb2RlID0gc3ByaW50ZigkdGhpcy0+cHJlcGFyZShzZWxmOjpURVhULCAkbGV2ZWwpLCAkdGhpcy0+Zmx1c2hJbmRlbnQoKSwgdmFyX2V4cG9ydCgkdGV4dCwgdHJ1ZSkpOwogICAgICAgICR0aGlzLT5pbmRlbnROZXh0TGluZSA9ICRpbmRlbnROZXh0TGluZTsKCiAgICAgICAgcmV0dXJuICRjb2RlOwogICAgfQoKICAgIC8qKgogICAgICogUHJlcGFyZSBQSFAgc291cmNlIGNvZGUgc25pcHBldCBmb3Igb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQKICAgICAqIEBwYXJhbSBpbnQgICAgJGJvbnVzICAgICAgICAgIEFkZGl0aW9uYWwgaW5kZW50IGxldmVsIChkZWZhdWx0OiAwKQogICAgICogQHBhcmFtIGJvb2wgICAkcHJlcGVuZE5ld2xpbmUgUHJlcGVuZCBhIG5ld2xpbmUgdG8gdGhlIHNuaXBwZXQ/IChkZWZhdWx0OiB0cnVlKQogICAgICogQHBhcmFtIGJvb2wgICAkYXBwZW5kTmV3bGluZSAgQXBwZW5kIGEgbmV3bGluZSB0byB0aGUgc25pcHBldD8gKGRlZmF1bHQ6IGZhbHNlKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFBIUCBzb3VyY2UgY29kZSBzbmlwcGV0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcHJlcGFyZSgkdGV4dCwgJGJvbnVzID0gMCwgJHByZXBlbmROZXdsaW5lID0gdHJ1ZSwgJGFwcGVuZE5ld2xpbmUgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGV4dCA9ICgkcHJlcGVuZE5ld2xpbmUgPyAiXG4iIDogJycpIC4gdHJpbSgkdGV4dCk7CiAgICAgICAgaWYgKCRwcmVwZW5kTmV3bGluZSkgewogICAgICAgICAgICAkYm9udXMrKzsKICAgICAgICB9CiAgICAgICAgaWYgKCRhcHBlbmROZXdsaW5lKSB7CiAgICAgICAgICAgICR0ZXh0IC49ICJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlKCIvXG4oIHs4fSk/LyIsICJcbiIgLiBzdHJfcmVwZWF0KCcgJywgJGJvbnVzICogNCksICR0ZXh0KTsKICAgIH0KCiAgICBjb25zdCBERUZBVUxUX0VTQ0FQRSA9ICdodG1sc3BlY2lhbGNoYXJzKCVzLCAlcywgJXMpJzsKICAgIGNvbnN0IENVU1RPTV9FU0NBUEUgID0gJ2NhbGxfdXNlcl9mdW5jKCR0aGlzLT5tdXN0YWNoZS0+Z2V0RXNjYXBlKCksICVzKSc7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgZXNjYXBlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSAoZGVmYXVsdDogJyR2YWx1ZScpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgRWl0aGVyIGEgY3VzdG9tIGNhbGxiYWNrLCBvciBhbiBpbmxpbmUgY2FsbCB0byBgaHRtbHNwZWNpYWxjaGFyc2AKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRFc2NhcGUoJHZhbHVlID0gJyR2YWx1ZScpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jdXN0b21Fc2NhcGUpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoc2VsZjo6Q1VTVE9NX0VTQ0FQRSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzcHJpbnRmKHNlbGY6OkRFRkFVTFRfRVNDQVBFLCAkdmFsdWUsIHZhcl9leHBvcnQoJHRoaXMtPmVudGl0eUZsYWdzLCB0cnVlKSwgdmFyX2V4cG9ydCgkdGhpcy0+Y2hhcnNldCwgdHJ1ZSkpOwogICAgfQoKICAgIC8qKgogICAgICogU2VsZWN0IHRoZSBhcHByb3ByaWF0ZSBDb250ZXh0IGBmaW5kYCBtZXRob2QgZm9yIGEgZ2l2ZW4gJGlkLgogICAgICoKICAgICAqIFRoZSByZXR1cm4gdmFsdWUgd2lsbCBiZSBvbmUgb2YgYGZpbmRgLCBgZmluZERvdGAsIGBmaW5kQW5jaG9yZWREb3RgIG9yIGBsYXN0YC4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0NvbnRleHQ6OmZpbmQKICAgICAqIEBzZWUgTXVzdGFjaGVfQ29udGV4dDo6ZmluZERvdAogICAgICogQHNlZSBNdXN0YWNoZV9Db250ZXh0OjpsYXN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgVmFyaWFibGUgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIGBmaW5kYCBtZXRob2QgbmFtZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEZpbmRNZXRob2QoJGlkKQogICAgewogICAgICAgIGlmICgkaWQgPT09ICcuJykgewogICAgICAgICAgICByZXR1cm4gJ2xhc3QnOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcmFnbWFzW011c3RhY2hlX0VuZ2luZTo6UFJBR01BX0FOQ0hPUkVEX0RPVF0pICYmICR0aGlzLT5wcmFnbWFzW011c3RhY2hlX0VuZ2luZTo6UFJBR01BX0FOQ0hPUkVEX0RPVF0pIHsKICAgICAgICAgICAgaWYgKHN1YnN0cigkaWQsIDAsIDEpID09PSAnLicpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnZmluZEFuY2hvcmVkRG90JzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkaWQsICcuJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAnZmluZCc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ2ZpbmREb3QnOwogICAgfQoKICAgIGNvbnN0IElTX0NBTExBQkxFICAgICAgICA9ICchaXNfc3RyaW5nKCVzKSAmJiBpc19jYWxsYWJsZSglcyknOwogICAgY29uc3QgU1RSSUNUX0lTX0NBTExBQkxFID0gJ2lzX29iamVjdCglcykgJiYgaXNfY2FsbGFibGUoJXMpJzsKCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBjb21waWxlIHN0cmljdCB2cyBsYXggImlzIGNhbGxhYmxlIiBsb2dpYy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YXJpYWJsZSAoZGVmYXVsdDogJyR2YWx1ZScpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgImlzIGNhbGxhYmxlIiBsb2dpYwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENhbGxhYmxlKCR2YXJpYWJsZSA9ICckdmFsdWUnKQogICAgewogICAgICAgICR0cGwgPSAkdGhpcy0+c3RyaWN0Q2FsbGFibGVzID8gc2VsZjo6U1RSSUNUX0lTX0NBTExBQkxFIDogc2VsZjo6SVNfQ0FMTEFCTEU7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCR0cGwsICR2YXJpYWJsZSwgJHZhcmlhYmxlKTsKICAgIH0KCiAgICBjb25zdCBMSU5FX0lOREVOVCA9ICckaW5kZW50IC4gJzsKCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCAkaW5kZW50IHByZWZpeCB0byB3cml0ZSB0byB0aGUgYnVmZmVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nICIkaW5kZW50IC4gIiBvciAiIgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZsdXNoSW5kZW50KCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pbmRlbnROZXh0TGluZSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5kZW50TmV4dExpbmUgPSBmYWxzZTsKCiAgICAgICAgcmV0dXJuIHNlbGY6OkxJTkVfSU5ERU5UOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIFRlbXBsYXRlIHJlbmRlcmluZyBDb250ZXh0LgogKi8KY2xhc3MgTXVzdGFjaGVfQ29udGV4dAp7CiAgICBwcml2YXRlICRzdGFjayAgICAgID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJGJsb2NrU3RhY2sgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogTXVzdGFjaGUgcmVuZGVyaW5nIENvbnRleHQgY29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICRjb250ZXh0IERlZmF1bHQgcmVuZGVyaW5nIGNvbnRleHQgKGRlZmF1bHQ6IG51bGwpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29udGV4dCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRjb250ZXh0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5zdGFjayA9IGFycmF5KCRjb250ZXh0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQdXNoIGEgbmV3IENvbnRleHQgZnJhbWUgb250byB0aGUgc3RhY2suCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBPYmplY3Qgb3IgYXJyYXkgdG8gdXNlIGZvciBjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwdXNoKCR2YWx1ZSkKICAgIHsKICAgICAgICBhcnJheV9wdXNoKCR0aGlzLT5zdGFjaywgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFB1c2ggYSBuZXcgQ29udGV4dCBmcmFtZSBvbnRvIHRoZSBibG9jayBjb250ZXh0IHN0YWNrLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgT2JqZWN0IG9yIGFycmF5IHRvIHVzZSBmb3IgYmxvY2sgY29udGV4dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHVzaEJsb2NrQ29udGV4dCgkdmFsdWUpCiAgICB7CiAgICAgICAgYXJyYXlfcHVzaCgkdGhpcy0+YmxvY2tTdGFjaywgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFBvcCB0aGUgbGFzdCBDb250ZXh0IGZyYW1lIGZyb20gdGhlIHN0YWNrLgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgTGFzdCBDb250ZXh0IGZyYW1lIChvYmplY3Qgb3IgYXJyYXkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwb3AoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9wb3AoJHRoaXMtPnN0YWNrKTsKICAgIH0KCiAgICAvKioKICAgICAqIFBvcCB0aGUgbGFzdCBibG9jayBDb250ZXh0IGZyYW1lIGZyb20gdGhlIHN0YWNrLgogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgTGFzdCBibG9jayBDb250ZXh0IGZyYW1lIChvYmplY3Qgb3IgYXJyYXkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwb3BCbG9ja0NvbnRleHQoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9wb3AoJHRoaXMtPmJsb2NrU3RhY2spOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBsYXN0IENvbnRleHQgZnJhbWUuCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBMYXN0IENvbnRleHQgZnJhbWUgKG9iamVjdCBvciBhcnJheSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxhc3QoKQogICAgewogICAgICAgIHJldHVybiBlbmQoJHRoaXMtPnN0YWNrKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgYSB2YXJpYWJsZSBpbiB0aGUgQ29udGV4dCBzdGFjay4KICAgICAqCiAgICAgKiBTdGFydGluZyB3aXRoIHRoZSBsYXN0IENvbnRleHQgZnJhbWUgKHRoZSBjb250ZXh0IG9mIHRoZSBpbm5lcm1vc3Qgc2VjdGlvbiksIGFuZCB3b3JraW5nIGJhY2sgdG8gdGhlIHRvcC1sZXZlbAogICAgICogcmVuZGVyaW5nIGNvbnRleHQsIGxvb2sgZm9yIGEgdmFyaWFibGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZToKICAgICAqCiAgICAgKiAgKiBJZiB0aGUgQ29udGV4dCBmcmFtZSBpcyBhbiBhc3NvY2lhdGl2ZSBhcnJheSB3aGljaCBjb250YWlucyB0aGUga2V5ICRpZCwgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhhdCBlbGVtZW50LgogICAgICogICogSWYgdGhlIENvbnRleHQgZnJhbWUgaXMgYW4gb2JqZWN0LCB0aGlzIHdpbGwgY2hlY2sgZmlyc3QgZm9yIGEgcHVibGljIG1ldGhvZCwgdGhlbiBhIHB1YmxpYyBwcm9wZXJ0eSBuYW1lZAogICAgICogICAgJGlkLiBGYWlsaW5nIGJvdGggb2YgdGhlc2UsIGl0IHdpbGwgdHJ5IGBfX2lzc2V0YCBhbmQgYF9fZ2V0YCBtYWdpYyBtZXRob2RzLgogICAgICogICogSWYgYSB2YWx1ZSBuYW1lZCAkaWQgaXMgbm90IGZvdW5kIGluIGFueSBDb250ZXh0IGZyYW1lLCByZXR1cm5zIGFuIGVtcHR5IHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCBWYXJpYWJsZSBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBWYXJpYWJsZSB2YWx1ZSwgb3IgJycgaWYgbm90IGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kKCRpZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZpbmRWYXJpYWJsZUluU3RhY2soJGlkLCAkdGhpcy0+c3RhY2spOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBhICdkb3Qgbm90YXRpb24nIHZhcmlhYmxlIGluIHRoZSBDb250ZXh0IHN0YWNrLgogICAgICoKICAgICAqIE5vdGUgdGhhdCBkb3Qgbm90YXRpb24gdHJhdmVyc2FsIGJ1YmJsZXMgdGhyb3VnaCBzY29wZSBkaWZmZXJlbnRseSB0aGFuIHRoZSByZWd1bGFyIGZpbmQgbWV0aG9kLiBBZnRlciBmaW5kaW5nCiAgICAgKiB0aGUgaW5pdGlhbCBjaHVuayBvZiB0aGUgZG90dGVkIG5hbWUsIGVhY2ggc3Vic2VxdWVudCBjaHVuayBpcyBzZWFyY2hlZCBmb3Igb25seSB3aXRoaW4gdGhlIHZhbHVlIG9mIHRoZSBwcmV2aW91cwogICAgICogcmVzdWx0LiBGb3IgZXhhbXBsZSwgZ2l2ZW4gdGhlIGZvbGxvd2luZyBjb250ZXh0IHN0YWNrOgogICAgICoKICAgICAqICAgICAkZGF0YSA9IGFycmF5KAogICAgICogICAgICAgICAnbmFtZScgPT4gJ0ZyZWQnLAogICAgICogICAgICAgICAnY2hpbGQnID0+IGFycmF5KAogICAgICogICAgICAgICAgICAgJ25hbWUnID0+ICdCb2InCiAgICAgKiAgICAgICAgICksCiAgICAgKiAgICAgKTsKICAgICAqCiAgICAgKiAuLi4gYW5kIHRoZSBNdXN0YWNoZSBmb2xsb3dpbmcgdGVtcGxhdGU6CiAgICAgKgogICAgICogICAgIHt7IGNoaWxkLm5hbWUgfX0KICAgICAqCiAgICAgKiAuLi4gdGhlIGBuYW1lYCB2YWx1ZSBpcyBvbmx5IHNlYXJjaGVkIGZvciB3aXRoaW4gdGhlIGBjaGlsZGAgdmFsdWUgb2YgdGhlIGdsb2JhbCBDb250ZXh0LCBub3Qgd2l0aGluIHBhcmVudAogICAgICogQ29udGV4dCBmcmFtZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgRG90dGVkIHZhcmlhYmxlIHNlbGVjdG9yCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBWYXJpYWJsZSB2YWx1ZSwgb3IgJycgaWYgbm90IGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kRG90KCRpZCkKICAgIHsKICAgICAgICAkY2h1bmtzID0gZXhwbG9kZSgnLicsICRpZCk7CiAgICAgICAgJGZpcnN0ICA9IGFycmF5X3NoaWZ0KCRjaHVua3MpOwogICAgICAgICR2YWx1ZSAgPSAkdGhpcy0+ZmluZFZhcmlhYmxlSW5TdGFjaygkZmlyc3QsICR0aGlzLT5zdGFjayk7CgogICAgICAgIGZvcmVhY2ggKCRjaHVua3MgYXMgJGNodW5rKSB7CiAgICAgICAgICAgIGlmICgkdmFsdWUgPT09ICcnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+ZmluZFZhcmlhYmxlSW5TdGFjaygkY2h1bmssIGFycmF5KCR2YWx1ZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgYW4gJ2FuY2hvcmVkIGRvdCBub3RhdGlvbicgdmFyaWFibGUgaW4gdGhlIENvbnRleHQgc3RhY2suCiAgICAgKgogICAgICogVGhpcyBpcyB0aGUgc2FtZSBhcyBmaW5kRG90KCksIGV4Y2VwdCBpdCBsb29rcyBpbiB0aGUgdG9wIG9mIHRoZSBjb250ZXh0CiAgICAgKiBzdGFjayBmb3IgdGhlIGZpcnN0IHZhbHVlLCByYXRoZXIgdGhhbiBzZWFyY2hpbmcgdGhlIHdob2xlIGNvbnRleHQgc3RhY2sKICAgICAqIGFuZCBzdGFydGluZyBmcm9tIHRoZXJlLgogICAgICoKICAgICAqIEBzZWUgTXVzdGFjaGVfQ29udGV4dDo6ZmluZERvdAogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiBnaXZlbiBhbiBpbnZhbGlkIGFuY2hvcmVkIGRvdCAkaWQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCBEb3R0ZWQgdmFyaWFibGUgc2VsZWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFZhcmlhYmxlIHZhbHVlLCBvciAnJyBpZiBub3QgZm91bmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRBbmNob3JlZERvdCgkaWQpCiAgICB7CiAgICAgICAgJGNodW5rcyA9IGV4cGxvZGUoJy4nLCAkaWQpOwogICAgICAgICRmaXJzdCAgPSBhcnJheV9zaGlmdCgkY2h1bmtzKTsKICAgICAgICBpZiAoJGZpcnN0ICE9PSAnJykgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdVbmV4cGVjdGVkIGlkIGZvciBmaW5kQW5jaG9yZWREb3Q6ICVzJywgJGlkKSk7CiAgICAgICAgfQoKICAgICAgICAkdmFsdWUgID0gJHRoaXMtPmxhc3QoKTsKCiAgICAgICAgZm9yZWFjaCAoJGNodW5rcyBhcyAkY2h1bmspIHsKICAgICAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJycpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5maW5kVmFyaWFibGVJblN0YWNrKCRjaHVuaywgYXJyYXkoJHZhbHVlKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBhbiBhcmd1bWVudCBpbiB0aGUgYmxvY2sgY29udGV4dCBzdGFjay4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZAogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgVmFyaWFibGUgdmFsdWUsIG9yICcnIGlmIG5vdCBmb3VuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZEluQmxvY2soJGlkKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ibG9ja1N0YWNrIGFzICRjb250ZXh0KSB7CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRpZCwgJGNvbnRleHQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGNvbnRleHRbJGlkXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICcnOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGZpbmQgYSB2YXJpYWJsZSBpbiB0aGUgQ29udGV4dCBzdGFjay4KICAgICAqCiAgICAgKiBAc2VlIE11c3RhY2hlX0NvbnRleHQ6OmZpbmQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCAgICBWYXJpYWJsZSBuYW1lCiAgICAgKiBAcGFyYW0gYXJyYXkgICRzdGFjayBDb250ZXh0IHN0YWNrCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBWYXJpYWJsZSB2YWx1ZSwgb3IgJycgaWYgbm90IGZvdW5kCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZFZhcmlhYmxlSW5TdGFjaygkaWQsIGFycmF5ICRzdGFjaykKICAgIHsKICAgICAgICBmb3IgKCRpID0gY291bnQoJHN0YWNrKSAtIDE7ICRpID49IDA7ICRpLS0pIHsKICAgICAgICAgICAgJGZyYW1lID0gJiRzdGFja1skaV07CgogICAgICAgICAgICBzd2l0Y2ggKGdldHR5cGUoJGZyYW1lKSkgewogICAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzoKICAgICAgICAgICAgICAgICAgICBpZiAoISgkZnJhbWUgaW5zdGFuY2VvZiBDbG9zdXJlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgaXNfY2FsbGFibGUoKSAqd2lsbCBub3Qgd29yayBoZXJlKgogICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2JvYnRoZWNvdy9tdXN0YWNoZS5waHAvd2lraS9NYWdpYy1NZXRob2RzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZXRob2RfZXhpc3RzKCRmcmFtZSwgJGlkKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmcmFtZS0+JGlkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZnJhbWUtPiRpZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZnJhbWUtPiRpZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRmcmFtZSBpbnN0YW5jZW9mIEFycmF5QWNjZXNzICYmIGlzc2V0KCRmcmFtZVskaWRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmcmFtZVskaWRdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2FycmF5JzoKICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkaWQsICRmcmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmcmFtZVskaWRdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICcnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIEEgTXVzdGFjaGUgRXhjZXB0aW9uIGludGVyZmFjZS4KICovCmludGVyZmFjZSBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgUGFyc2VyIGNsYXNzLgogKgogKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciB0dXJuaW5nIGEgc2V0IG9mIE11c3RhY2hlIHRva2VucyBpbnRvIGEgcGFyc2UgdHJlZS4KICovCmNsYXNzIE11c3RhY2hlX1BhcnNlcgp7CiAgICBwcml2YXRlICRsaW5lTnVtOwogICAgcHJpdmF0ZSAkbGluZVRva2VuczsKICAgIHByaXZhdGUgJHByYWdtYXM7CiAgICBwcml2YXRlICRkZWZhdWx0UHJhZ21hcyA9IGFycmF5KCk7CgogICAgcHJpdmF0ZSAkcHJhZ21hRmlsdGVyczsKICAgIHByaXZhdGUgJHByYWdtYUJsb2NrczsKCiAgICAvKioKICAgICAqIFByb2Nlc3MgYW4gYXJyYXkgb2YgTXVzdGFjaGUgdG9rZW5zIGFuZCBjb252ZXJ0IHRoZW0gaW50byBhIHBhcnNlIHRyZWUuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICR0b2tlbnMgU2V0IG9mIE11c3RhY2hlIHRva2VucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgTXVzdGFjaGUgdG9rZW4gcGFyc2UgdHJlZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2UoYXJyYXkgJHRva2VucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxpbmVOdW0gICAgPSAtMTsKICAgICAgICAkdGhpcy0+bGluZVRva2VucyA9IDA7CiAgICAgICAgJHRoaXMtPnByYWdtYXMgICAgPSAkdGhpcy0+ZGVmYXVsdFByYWdtYXM7CgogICAgICAgICR0aGlzLT5wcmFnbWFGaWx0ZXJzID0gaXNzZXQoJHRoaXMtPnByYWdtYXNbTXVzdGFjaGVfRW5naW5lOjpQUkFHTUFfRklMVEVSU10pOwogICAgICAgICR0aGlzLT5wcmFnbWFCbG9ja3MgID0gaXNzZXQoJHRoaXMtPnByYWdtYXNbTXVzdGFjaGVfRW5naW5lOjpQUkFHTUFfQkxPQ0tTXSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+YnVpbGRUcmVlKCR0b2tlbnMpOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlIHByYWdtYXMgYWNyb3NzIGFsbCB0ZW1wbGF0ZXMsIHJlZ2FyZGxlc3Mgb2YgdGhlIHByZXNlbmNlIG9mIHByYWdtYQogICAgICogdGFncyBpbiB0aGUgaW5kaXZpZHVhbCB0ZW1wbGF0ZXMuCiAgICAgKgogICAgICogQGludGVybmFsIFVzZXJzIHNob3VsZCBzZXQgZ2xvYmFsIHByYWdtYXMgaW4gTXVzdGFjaGVfRW5naW5lLCBub3QgaGVyZSA6KQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkcHJhZ21hcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJhZ21hcyhhcnJheSAkcHJhZ21hcykKICAgIHsKICAgICAgICAkdGhpcy0+cHJhZ21hcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHByYWdtYXMgYXMgJHByYWdtYSkgewogICAgICAgICAgICAkdGhpcy0+ZW5hYmxlUHJhZ21hKCRwcmFnbWEpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZGVmYXVsdFByYWdtYXMgPSAkdGhpcy0+cHJhZ21hczsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgZm9yIHJlY3Vyc2l2ZWx5IGJ1aWxkaW5nIGEgcGFyc2UgdHJlZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24gd2hlbiBuZXN0aW5nIGVycm9ycyBvciBtaXNtYXRjaGVkIHNlY3Rpb24gdGFncyBhcmUgZW5jb3VudGVyZWQKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJiR0b2tlbnMgU2V0IG9mIE11c3RhY2hlIHRva2VucwogICAgICogQHBhcmFtIGFycmF5ICRwYXJlbnQgIFBhcmVudCB0b2tlbiAoZGVmYXVsdDogbnVsbCkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IE11c3RhY2hlIFRva2VuIHBhcnNlIHRyZWUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZFRyZWUoYXJyYXkgJiR0b2tlbnMsIGFycmF5ICRwYXJlbnQgPSBudWxsKQogICAgewogICAgICAgICRub2RlcyA9IGFycmF5KCk7CgogICAgICAgIHdoaWxlICghZW1wdHkoJHRva2VucykpIHsKICAgICAgICAgICAgJHRva2VuID0gYXJyYXlfc2hpZnQoJHRva2Vucyk7CgogICAgICAgICAgICBpZiAoJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TElORV0gPT09ICR0aGlzLT5saW5lTnVtKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bGluZVRva2VucysrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmxpbmVOdW0gICAgPSAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpMSU5FXTsKICAgICAgICAgICAgICAgICR0aGlzLT5saW5lVG9rZW5zID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5wcmFnbWFGaWx0ZXJzICYmIGlzc2V0KCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdKSkgewogICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJGZpbHRlcnMpID0gJHRoaXMtPmdldE5hbWVBbmRGaWx0ZXJzKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdKTsKICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJGZpbHRlcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0gICAgPSAkbmFtZTsKICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpGSUxURVJTXSA9ICRmaWx0ZXJzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdKSB7CiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9ERUxJTV9DSEFOR0U6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrSWZUb2tlbklzQWxsb3dlZEluUGFyZW50KCRwYXJlbnQsICR0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNsZWFyU3RhbmRhbG9uZUxpbmVzKCRub2RlcywgJHRva2Vucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfU0VDVElPTjoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0lOVkVSVEVEOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja0lmVG9rZW5Jc0FsbG93ZWRJblBhcmVudCgkcGFyZW50LCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jbGVhclN0YW5kYWxvbmVMaW5lcygkbm9kZXMsICR0b2tlbnMpOwogICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRoaXMtPmJ1aWxkVHJlZSgkdG9rZW5zLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0VORF9TRUNUSU9OOgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHBhcmVudCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVW5leHBlY3RlZCBjbG9zaW5nIHRhZzogLyVzIG9uIGxpbmUgJWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpMSU5FXQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbigkbXNnLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdICE9PSAkcGFyZW50W011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTmVzdGluZyBlcnJvcjogJXMgKG9uIGxpbmUgJWQpIHZzLiAlcyAob24gbGluZSAlZCknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6OkxJTkVdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpMSU5FXQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbigkbXNnLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNsZWFyU3RhbmRhbG9uZUxpbmVzKCRub2RlcywgJHRva2Vucyk7CiAgICAgICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6OkVORF0gICA9ICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OklOREVYXTsKICAgICAgICAgICAgICAgICAgICAkcGFyZW50W011c3RhY2hlX1Rva2VuaXplcjo6Tk9ERVNdID0gJG5vZGVzOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHBhcmVudDsKCiAgICAgICAgICAgICAgICBjYXNlIE11c3RhY2hlX1Rva2VuaXplcjo6VF9QQVJUSUFMOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja0lmVG9rZW5Jc0FsbG93ZWRJblBhcmVudCgkcGFyZW50LCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIC8vc3RvcmUgdGhlIHdoaXRlc3BhY2UgcHJlZml4IGZvciBsYXRlcnMhCiAgICAgICAgICAgICAgICAgICAgaWYgKCRpbmRlbnQgPSAkdGhpcy0+Y2xlYXJTdGFuZGFsb25lTGluZXMoJG5vZGVzLCAkdG9rZW5zKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpJTkRFTlRdID0gJGluZGVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6OlZBTFVFXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfUEFSRU5UOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja0lmVG9rZW5Jc0FsbG93ZWRJblBhcmVudCgkcGFyZW50LCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRoaXMtPmJ1aWxkVHJlZSgkdG9rZW5zLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgTXVzdGFjaGVfVG9rZW5pemVyOjpUX0JMT0NLX1ZBUjoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnByYWdtYUJsb2NrcykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBCTE9DS1MgcHJhZ21hIGlzIGVuYWJsZWQsIGxldCdzIGRvIHRoaXMhCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFyZW50KSAmJiAkcGFyZW50W011c3RhY2hlX1Rva2VuaXplcjo6VFlQRV0gPT09IE11c3RhY2hlX1Rva2VuaXplcjo6VF9QQVJFTlQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdID0gTXVzdGFjaGVfVG9rZW5pemVyOjpUX0JMT0NLX0FSRzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYXJTdGFuZGFsb25lTGluZXMoJG5vZGVzLCAkdG9rZW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGVzW10gPSAkdGhpcy0+YnVpbGRUcmVlKCR0b2tlbnMsICR0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJldGVuZCB0aGlzIHdhcyBqdXN0IGEgbm9ybWFsICJlc2NhcGVkIiB0b2tlbi4uLgogICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9IE11c3RhY2hlX1Rva2VuaXplcjo6VF9FU0NBUEVEOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaWd1cmUgb3V0IGhvdyB0byBmaWd1cmUgb3V0IGlmIHRoZXJlIHdhcyBhIHNwYWNlIGFmdGVyIHRoaXMgZG9sbGFyOgogICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bTXVzdGFjaGVfVG9rZW5pemVyOjpOQU1FXSA9ICckJyAuICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZXNbXSA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfUFJBR01BOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lbmFibGVQcmFnbWEoJHRva2VuW011c3RhY2hlX1Rva2VuaXplcjo6TkFNRV0pOwogICAgICAgICAgICAgICAgICAgIC8vIG5vIGJyZWFrCgogICAgICAgICAgICAgICAgY2FzZSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfQ09NTUVOVDoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYXJTdGFuZGFsb25lTGluZXMoJG5vZGVzLCAkdG9rZW5zKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZXNbXSA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHBhcmVudCkpIHsKICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAnTWlzc2luZyBjbG9zaW5nIHRhZzogJXMgb3BlbmVkIG9uIGxpbmUgJWQnLAogICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6Ok5BTUVdLAogICAgICAgICAgICAgICAgJHBhcmVudFtNdXN0YWNoZV9Ub2tlbml6ZXI6OkxJTkVdCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uKCRtc2csICRwYXJlbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRub2RlczsKICAgIH0KCiAgICAvKioKICAgICAqIENsZWFyIHN0YW5kYWxvbmUgbGluZSB0b2tlbnMuCiAgICAgKgogICAgICogUmV0dXJucyBhIHdoaXRlc3BhY2UgdG9rZW4gZm9yIGluZGVudGluZyBwYXJ0aWFscywgaWYgYXBwbGljYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJG5vZGVzICBQYXJzZWQgbm9kZXMKICAgICAqIEBwYXJhbSBhcnJheSAkdG9rZW5zIFRva2VucyB0byBiZSBwYXJzZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwgUmVzdWx0aW5nIGluZGVudCB0b2tlbiwgaWYgYW55CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2xlYXJTdGFuZGFsb25lTGluZXMoYXJyYXkgJiRub2RlcywgYXJyYXkgJiR0b2tlbnMpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5saW5lVG9rZW5zID4gMSkgewogICAgICAgICAgICAvLyB0aGlzIGlzIHRoZSB0aGlyZCBvciBsYXRlciBub2RlIG9uIHRoaXMgbGluZSwgc28gaXQgY2FuJ3QgYmUgc3RhbmRhbG9uZQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkcHJldiA9IG51bGw7CiAgICAgICAgaWYgKCR0aGlzLT5saW5lVG9rZW5zID09PSAxKSB7CiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNlY29uZCBub2RlIG9uIHRoaXMgbGluZSwgc28gaXQgY2FuJ3QgYmUgc3RhbmRhbG9uZQogICAgICAgICAgICAvLyB1bmxlc3MgdGhlIHByZXZpb3VzIG5vZGUgaXMgd2hpdGVzcGFjZS4KICAgICAgICAgICAgaWYgKCRwcmV2ID0gZW5kKCRub2RlcykpIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnRva2VuSXNXaGl0ZXNwYWNlKCRwcmV2KSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRuZXh0ID0gcmVzZXQoJHRva2VucykpIHsKICAgICAgICAgICAgLy8gSWYgd2UncmUgb24gYSBuZXcgbGluZSwgYmFpbC4KICAgICAgICAgICAgaWYgKCRuZXh0W011c3RhY2hlX1Rva2VuaXplcjo6TElORV0gIT09ICR0aGlzLT5saW5lTnVtKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIHRoZSBuZXh0IHRva2VuIGlzbid0IHdoaXRlc3BhY2UsIGJhaWwuCiAgICAgICAgICAgIGlmICghJHRoaXMtPnRva2VuSXNXaGl0ZXNwYWNlKCRuZXh0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY291bnQoJHRva2VucykgIT09IDEpIHsKICAgICAgICAgICAgICAgIC8vIFVubGVzcyBpdCdzIHRoZSBsYXN0IHRva2VuIGluIHRoZSB0ZW1wbGF0ZSwgdGhlIG5leHQgdG9rZW4KICAgICAgICAgICAgICAgIC8vIG11c3QgZW5kIGluIG5ld2xpbmUgZm9yIHRoaXMgdG8gYmUgc3RhbmRhbG9uZS4KICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJG5leHRbTXVzdGFjaGVfVG9rZW5pemVyOjpWQUxVRV0sIC0xKSAhPT0gIlxuIikgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRGlzY2FyZCB0aGUgd2hpdGVzcGFjZSBzdWZmaXgKICAgICAgICAgICAgYXJyYXlfc2hpZnQoJHRva2Vucyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByZXYpIHsKICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSB3aGl0ZXNwYWNlIHByZWZpeCwgaWYgYW55CiAgICAgICAgICAgIHJldHVybiBhcnJheV9wb3AoJG5vZGVzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIHRva2VuIGlzIGEgd2hpdGVzcGFjZSB0b2tlbi4KICAgICAqCiAgICAgKiBUcnVlIGlmIHRva2VuIHR5cGUgaXMgVF9URVhUIGFuZCB2YWx1ZSBpcyBhbGwgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdG9rZW4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0b2tlbiBpcyBhIHdoaXRlc3BhY2UgdG9rZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB0b2tlbklzV2hpdGVzcGFjZShhcnJheSAkdG9rZW4pCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OlRZUEVdID09PSBNdXN0YWNoZV9Ub2tlbml6ZXI6OlRfVEVYVCkgewogICAgICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgnL15ccyokLycsICR0b2tlbltNdXN0YWNoZV9Ub2tlbml6ZXI6OlZBTFVFXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIGEgdG9rZW4gaXMgYWxsb3dlZCBpbnNpZGUgYSBwYXJlbnQgdGFnLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbiBpZiBhbiBpbnZhbGlkIHRva2VuIGlzIGZvdW5kIGluc2lkZSBhIHBhcmVudCB0YWcKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAkcGFyZW50CiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAkdG9rZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0lmVG9rZW5Jc0FsbG93ZWRJblBhcmVudCgkcGFyZW50LCBhcnJheSAkdG9rZW4pCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRwYXJlbnQpICYmICRwYXJlbnRbTXVzdGFjaGVfVG9rZW5pemVyOjpUWVBFXSA9PT0gTXVzdGFjaGVfVG9rZW5pemVyOjpUX1BBUkVOVCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1N5bnRheEV4Y2VwdGlvbignSWxsZWdhbCBjb250ZW50IGluIDwgcGFyZW50IHRhZycsICR0b2tlbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU3BsaXQgYSB0YWcgbmFtZSBpbnRvIG5hbWUgYW5kIGZpbHRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgW1RhZyBuYW1lLCBBcnJheSBvZiBmaWx0ZXJzXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldE5hbWVBbmRGaWx0ZXJzKCRuYW1lKQogICAgewogICAgICAgICRmaWx0ZXJzID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnfCcsICRuYW1lKSk7CiAgICAgICAgJG5hbWUgICAgPSBhcnJheV9zaGlmdCgkZmlsdGVycyk7CgogICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgJGZpbHRlcnMpOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlIGEgcHJhZ21hLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbmFibGVQcmFnbWEoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByYWdtYXNbJG5hbWVdID0gdHJ1ZTsKCiAgICAgICAgc3dpdGNoICgkbmFtZSkgewogICAgICAgICAgICBjYXNlIE11c3RhY2hlX0VuZ2luZTo6UFJBR01BX0JMT0NLUzoKICAgICAgICAgICAgICAgICR0aGlzLT5wcmFnbWFCbG9ja3MgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIE11c3RhY2hlX0VuZ2luZTo6UFJBR01BX0ZJTFRFUlM6CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJhZ21hRmlsdGVycyA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogVW5rbm93biBmaWx0ZXIgZXhjZXB0aW9uLgogKi8KY2xhc3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25GaWx0ZXJFeGNlcHRpb24gZXh0ZW5kcyBVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgcHJvdGVjdGVkICRmaWx0ZXJOYW1lOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAkZmlsdGVyTmFtZQogICAgICogQHBhcmFtIEV4Y2VwdGlvbiAkcHJldmlvdXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRmaWx0ZXJOYW1lLCBFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsdGVyTmFtZSA9ICRmaWx0ZXJOYW1lOwogICAgICAgICRtZXNzYWdlID0gc3ByaW50ZignVW5rbm93biBmaWx0ZXI6ICVzJywgJGZpbHRlck5hbWUpOwogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjMuMCcsICc+PScpKSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsIDAsICRwcmV2aW91cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbHRlck5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmlsdGVyTmFtZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBJbnZhbGlkIGFyZ3VtZW50IGV4Y2VwdGlvbi4KICovCmNsYXNzIE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgc3ludGF4IGV4Y2VwdGlvbi4KICovCmNsYXNzIE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24gZXh0ZW5kcyBMb2dpY0V4Y2VwdGlvbiBpbXBsZW1lbnRzIE11c3RhY2hlX0V4Y2VwdGlvbgp7CiAgICBwcm90ZWN0ZWQgJHRva2VuOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAkbXNnCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICR0b2tlbgogICAgICogQHBhcmFtIEV4Y2VwdGlvbiAkcHJldmlvdXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtc2csIGFycmF5ICR0b2tlbiwgRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnRva2VuID0gJHRva2VuOwogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjMuMCcsICc+PScpKSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1zZywgMCwgJHByZXZpb3VzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtc2cpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VG9rZW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW47CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTG9naWMgZXhjZXB0aW9uLgogKi8KY2xhc3MgTXVzdGFjaGVfRXhjZXB0aW9uX0xvZ2ljRXhjZXB0aW9uIGV4dGVuZHMgTG9naWNFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogVW5rbm93biB0ZW1wbGF0ZSBleGNlcHRpb24uCiAqLwpjbGFzcyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uIGV4dGVuZHMgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgTXVzdGFjaGVfRXhjZXB0aW9uCnsKICAgIHByb3RlY3RlZCAkdGVtcGxhdGVOYW1lOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAkdGVtcGxhdGVOYW1lCiAgICAgKiBAcGFyYW0gRXhjZXB0aW9uICRwcmV2aW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHRlbXBsYXRlTmFtZSwgRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnRlbXBsYXRlTmFtZSA9ICR0ZW1wbGF0ZU5hbWU7CiAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKCdVbmtub3duIHRlbXBsYXRlOiAlcycsICR0ZW1wbGF0ZU5hbWUpOwogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjMuMCcsICc+PScpKSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsIDAsICRwcmV2aW91cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlbXBsYXRlTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZW1wbGF0ZU5hbWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogUnVudGltZSBleGNlcHRpb24uCiAqLwpjbGFzcyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogVW5rbm93biBoZWxwZXIgZXhjZXB0aW9uLgogKi8KY2xhc3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25IZWxwZXJFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBNdXN0YWNoZV9FeGNlcHRpb24KewogICAgcHJvdGVjdGVkICRoZWxwZXJOYW1lOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAkaGVscGVyTmFtZQogICAgICogQHBhcmFtIEV4Y2VwdGlvbiAkcHJldmlvdXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRoZWxwZXJOYW1lLCBFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVscGVyTmFtZSA9ICRoZWxwZXJOYW1lOwogICAgICAgICRtZXNzYWdlID0gc3ByaW50ZignVW5rbm93biBoZWxwZXI6ICVzJywgJGhlbHBlck5hbWUpOwogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjMuMCcsICc+PScpKSB7CiAgICAgICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsIDAsICRwcmV2aW91cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlbHBlck5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGVscGVyTmFtZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBUb2tlbml6ZXIgY2xhc3MuCiAqCiAqIFRoaXMgY2xhc3MgaXMgcmVzcG9uc2libGUgZm9yIHR1cm5pbmcgcmF3IHRlbXBsYXRlIHNvdXJjZSBpbnRvIGEgc2V0IG9mIE11c3RhY2hlIHRva2Vucy4KICovCmNsYXNzIE11c3RhY2hlX1Rva2VuaXplcgp7CiAgICAvLyBGaW5pdGUgc3RhdGUgbWFjaGluZSBzdGF0ZXMKICAgIGNvbnN0IElOX1RFWFQgICAgID0gMDsKICAgIGNvbnN0IElOX1RBR19UWVBFID0gMTsKICAgIGNvbnN0IElOX1RBRyAgICAgID0gMjsKCiAgICAvLyBUb2tlbiB0eXBlcwogICAgY29uc3QgVF9TRUNUSU9OICAgICAgPSAnIyc7CiAgICBjb25zdCBUX0lOVkVSVEVEICAgICA9ICdeJzsKICAgIGNvbnN0IFRfRU5EX1NFQ1RJT04gID0gJy8nOwogICAgY29uc3QgVF9DT01NRU5UICAgICAgPSAnISc7CiAgICBjb25zdCBUX1BBUlRJQUwgICAgICA9ICc+JzsKICAgIGNvbnN0IFRfUEFSRU5UICAgICAgID0gJzwnOwogICAgY29uc3QgVF9ERUxJTV9DSEFOR0UgPSAnPSc7CiAgICBjb25zdCBUX0VTQ0FQRUQgICAgICA9ICdfdic7CiAgICBjb25zdCBUX1VORVNDQVBFRCAgICA9ICd7JzsKICAgIGNvbnN0IFRfVU5FU0NBUEVEXzIgID0gJyYnOwogICAgY29uc3QgVF9URVhUICAgICAgICAgPSAnX3QnOwogICAgY29uc3QgVF9QUkFHTUEgICAgICAgPSAnJSc7CiAgICBjb25zdCBUX0JMT0NLX1ZBUiAgICA9ICckJzsKICAgIGNvbnN0IFRfQkxPQ0tfQVJHICAgID0gJyRhcmcnOwoKICAgIC8vIFZhbGlkIHRva2VuIHR5cGVzCiAgICBwcml2YXRlIHN0YXRpYyAkdGFnVHlwZXMgPSBhcnJheSgKICAgICAgICBzZWxmOjpUX1NFQ1RJT04gICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfSU5WRVJURUQgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9FTkRfU0VDVElPTiAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX0NPTU1FTlQgICAgICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfUEFSVElBTCAgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9QQVJFTlQgICAgICAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX0RFTElNX0NIQU5HRSA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfRVNDQVBFRCAgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9VTkVTQ0FQRUQgICAgPT4gdHJ1ZSwKICAgICAgICBzZWxmOjpUX1VORVNDQVBFRF8yICA9PiB0cnVlLAogICAgICAgIHNlbGY6OlRfUFJBR01BICAgICAgID0+IHRydWUsCiAgICAgICAgc2VsZjo6VF9CTE9DS19WQVIgICAgPT4gdHJ1ZSwKICAgICk7CgogICAgLy8gVG9rZW4gcHJvcGVydGllcwogICAgY29uc3QgVFlQRSAgICA9ICd0eXBlJzsKICAgIGNvbnN0IE5BTUUgICAgPSAnbmFtZSc7CiAgICBjb25zdCBPVEFHICAgID0gJ290YWcnOwogICAgY29uc3QgQ1RBRyAgICA9ICdjdGFnJzsKICAgIGNvbnN0IExJTkUgICAgPSAnbGluZSc7CiAgICBjb25zdCBJTkRFWCAgID0gJ2luZGV4JzsKICAgIGNvbnN0IEVORCAgICAgPSAnZW5kJzsKICAgIGNvbnN0IElOREVOVCAgPSAnaW5kZW50JzsKICAgIGNvbnN0IE5PREVTICAgPSAnbm9kZXMnOwogICAgY29uc3QgVkFMVUUgICA9ICd2YWx1ZSc7CiAgICBjb25zdCBGSUxURVJTID0gJ2ZpbHRlcnMnOwoKICAgIHByaXZhdGUgJHN0YXRlOwogICAgcHJpdmF0ZSAkdGFnVHlwZTsKICAgIHByaXZhdGUgJGJ1ZmZlcjsKICAgIHByaXZhdGUgJHRva2VuczsKICAgIHByaXZhdGUgJHNlZW5UYWc7CiAgICBwcml2YXRlICRsaW5lOwoKICAgIHByaXZhdGUgJG90YWc7CiAgICBwcml2YXRlICRvdGFnQ2hhcjsKICAgIHByaXZhdGUgJG90YWdMZW47CgogICAgcHJpdmF0ZSAkY3RhZzsKICAgIHByaXZhdGUgJGN0YWdDaGFyOwogICAgcHJpdmF0ZSAkY3RhZ0xlbjsKCiAgICAvKioKICAgICAqIFNjYW4gYW5kIHRva2VuaXplIHRlbXBsYXRlIHNvdXJjZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24gd2hlbiBtaXNtYXRjaGVkIHNlY3Rpb24gdGFncyBhcmUgZW5jb3VudGVyZWQKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiB3aGVuICRkZWxpbWl0ZXJzIHN0cmluZyBpcyBpbnZhbGlkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dCAgICAgICBNdXN0YWNoZSB0ZW1wbGF0ZSBzb3VyY2UgdG8gdG9rZW5pemUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlbGltaXRlcnMgT3B0aW9uYWxseSwgcGFzcyBpbml0aWFsIG9wZW5pbmcgYW5kIGNsb3NpbmcgZGVsaW1pdGVycyAoZGVmYXVsdDogbnVsbCkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFNldCBvZiBNdXN0YWNoZSB0b2tlbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW4oJHRleHQsICRkZWxpbWl0ZXJzID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBTZXR0aW5nIG1ic3RyaW5nLmZ1bmNfb3ZlcmxvYWQgbWFrZXMgdGhpbmdzICpyZWFsbHkqIHNsb3cuCiAgICAgICAgLy8gTGV0J3MgZG8gZXZlcnlvbmUgYSBmYXZvciBhbmQgc2NhbiB0aGlzIHN0cmluZyBhcyBBU0NJSSBpbnN0ZWFkLgogICAgICAgIC8vCiAgICAgICAgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0CiAgICAgICAgJGVuY29kaW5nID0gbnVsbDsKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdtYl9pbnRlcm5hbF9lbmNvZGluZycpICYmIGluaV9nZXQoJ21ic3RyaW5nLmZ1bmNfb3ZlcmxvYWQnKSAmIDIpIHsKICAgICAgICAgICAgJGVuY29kaW5nID0gbWJfaW50ZXJuYWxfZW5jb2RpbmcoKTsKICAgICAgICAgICAgbWJfaW50ZXJuYWxfZW5jb2RpbmcoJ0FTQ0lJJyk7CiAgICAgICAgfQogICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCiAgICAgICAgJHRoaXMtPnJlc2V0KCk7CgogICAgICAgIGlmICgkZGVsaW1pdGVycyA9IHRyaW0oJGRlbGltaXRlcnMpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREZWxpbWl0ZXJzKCRkZWxpbWl0ZXJzKTsKICAgICAgICB9CgogICAgICAgICRsZW4gPSBzdHJsZW4oJHRleHQpOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsZW47ICRpKyspIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdGUpIHsKICAgICAgICAgICAgICAgIGNhc2Ugc2VsZjo6SU5fVEVYVDoKICAgICAgICAgICAgICAgICAgICAkY2hhciA9ICR0ZXh0WyRpXTsKICAgICAgICAgICAgICAgICAgICAvLyBUZXN0IHdoZXRoZXIgaXQncyB0aW1lIHRvIGNoYW5nZSB0YWdzLgogICAgICAgICAgICAgICAgICAgIGlmICgkY2hhciA9PT0gJHRoaXMtPm90YWdDaGFyICYmIHN1YnN0cigkdGV4dCwgJGksICR0aGlzLT5vdGFnTGVuKSA9PT0gJHRoaXMtPm90YWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGktLTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZsdXNoQnVmZmVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGF0ZSA9IHNlbGY6OklOX1RBR19UWVBFOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY2hhciA9PT0gIlxuIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZsdXNoQnVmZmVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bGluZSsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2Ugc2VsZjo6SU5fVEFHX1RZUEU6CiAgICAgICAgICAgICAgICAgICAgJGkgKz0gJHRoaXMtPm90YWdMZW4gLSAxOwogICAgICAgICAgICAgICAgICAgICRjaGFyID0gJHRleHRbJGkgKyAxXTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoc2VsZjo6JHRhZ1R5cGVzWyRjaGFyXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRhZyA9ICRjaGFyOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dGFnVHlwZSA9ICR0YWc7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRhZyA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT50YWdUeXBlID0gc2VsZjo6VF9FU0NBUEVEOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT50YWdUeXBlID09PSBzZWxmOjpUX0RFTElNX0NIQU5HRSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaSA9ICR0aGlzLT5jaGFuZ2VEZWxpbWl0ZXJzKCR0ZXh0LCAkaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGF0ZSA9IHNlbGY6OklOX1RFWFQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT50YWdUeXBlID09PSBzZWxmOjpUX1BSQUdNQSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaSA9ICR0aGlzLT5hZGRQcmFnbWEoJHRleHQsICRpKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnN0YXRlID0gc2VsZjo6SU5fVEVYVDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRhZyAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3RhdGUgPSBzZWxmOjpJTl9UQUc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zZWVuVGFnID0gJGk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAkY2hhciA9ICR0ZXh0WyRpXTsKICAgICAgICAgICAgICAgICAgICAvLyBUZXN0IHdoZXRoZXIgaXQncyB0aW1lIHRvIGNoYW5nZSB0YWdzLgogICAgICAgICAgICAgICAgICAgIGlmICgkY2hhciA9PT0gJHRoaXMtPmN0YWdDaGFyICYmIHN1YnN0cigkdGV4dCwgJGksICR0aGlzLT5jdGFnTGVuKSA9PT0gJHRoaXMtPmN0YWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjpUWVBFICA9PiAkdGhpcy0+dGFnVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGY6Ok5BTUUgID0+IHRyaW0oJHRoaXMtPmJ1ZmZlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjpPVEFHICA9PiAkdGhpcy0+b3RhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGY6OkNUQUcgID0+ICR0aGlzLT5jdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZjo6TElORSAgPT4gJHRoaXMtPmxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjpJTkRFWCA9PiAoJHRoaXMtPnRhZ1R5cGUgPT09IHNlbGY6OlRfRU5EX1NFQ1RJT04pID8gJHRoaXMtPnNlZW5UYWcgLSAkdGhpcy0+b3RhZ0xlbiA6ICRpICsgJHRoaXMtPmN0YWdMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnRhZ1R5cGUgPT09IHNlbGY6OlRfVU5FU0NBUEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBge3t7IHRyaXBsZVN0YWNoZSB9fX1gIHN0eWxlIHRva2Vucy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y3RhZyA9PT0gJ319JykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoJGkgKyAyIDwgJGxlbikgJiYgJHRleHRbJGkgKyAyXSA9PT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWlzbWF0Y2hlZCB0YWcgZGVsaW1pdGVyczogJXMgb24gbGluZSAlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bc2VsZjo6TkFNRV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW5bc2VsZjo6TElORV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uKCRtc2csICR0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGFzdE5hbWUgPSAkdG9rZW5bc2VsZjo6TkFNRV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YnN0cigkbGFzdE5hbWUsIC0xKSA9PT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltzZWxmOjpOQU1FXSA9IHRyaW0oc3Vic3RyKCRsYXN0TmFtZSwgMCwgLTEpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbXNnID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdNaXNtYXRjaGVkIHRhZyBkZWxpbWl0ZXJzOiAlcyBvbiBsaW5lICVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltzZWxmOjpOQU1FXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbltzZWxmOjpMSU5FXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9TeW50YXhFeGNlcHRpb24oJG1zZywgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXIgPSAnJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGkgKz0gJHRoaXMtPmN0YWdMZW4gLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c3RhdGUgPSBzZWxmOjpJTl9URVhUOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dG9rZW5zW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5mbHVzaEJ1ZmZlcigpOwoKICAgICAgICAvLyBSZXN0b3JlIHRoZSB1c2VyJ3MgZW5jb2RpbmcuLi4KICAgICAgICAvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKICAgICAgICBpZiAoJGVuY29kaW5nKSB7CiAgICAgICAgICAgIG1iX2ludGVybmFsX2VuY29kaW5nKCRlbmNvZGluZyk7CiAgICAgICAgfQogICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCiAgICAgICAgcmV0dXJuICR0aGlzLT50b2tlbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcmVzZXQgdG9rZW5pemVyIGludGVybmFsIHN0YXRlLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdGUgICAgPSBzZWxmOjpJTl9URVhUOwogICAgICAgICR0aGlzLT50YWdUeXBlICA9IG51bGw7CiAgICAgICAgJHRoaXMtPmJ1ZmZlciAgID0gJyc7CiAgICAgICAgJHRoaXMtPnRva2VucyAgID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+c2VlblRhZyAgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+bGluZSAgICAgPSAwOwoKICAgICAgICAkdGhpcy0+b3RhZyAgICAgPSAne3snOwogICAgICAgICR0aGlzLT5vdGFnQ2hhciA9ICd7JzsKICAgICAgICAkdGhpcy0+b3RhZ0xlbiAgPSAyOwoKICAgICAgICAkdGhpcy0+Y3RhZyAgICAgPSAnfX0nOwogICAgICAgICR0aGlzLT5jdGFnQ2hhciA9ICd9JzsKICAgICAgICAkdGhpcy0+Y3RhZ0xlbiAgPSAyOwogICAgfQoKICAgIC8qKgogICAgICogRmx1c2ggdGhlIGN1cnJlbnQgYnVmZmVyIHRvIGEgdG9rZW4uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmx1c2hCdWZmZXIoKQogICAgewogICAgICAgIGlmIChzdHJsZW4oJHRoaXMtPmJ1ZmZlcikgPiAwKSB7CiAgICAgICAgICAgICR0aGlzLT50b2tlbnNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgc2VsZjo6VFlQRSAgPT4gc2VsZjo6VF9URVhULAogICAgICAgICAgICAgICAgc2VsZjo6TElORSAgPT4gJHRoaXMtPmxpbmUsCiAgICAgICAgICAgICAgICBzZWxmOjpWQUxVRSA9PiAkdGhpcy0+YnVmZmVyLAogICAgICAgICAgICApOwogICAgICAgICAgICAkdGhpcy0+YnVmZmVyICAgPSAnJzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGFuZ2UgdGhlIGN1cnJlbnQgTXVzdGFjaGUgZGVsaW1pdGVycy4gU2V0IG5ldyBgb3RhZ2AgYW5kIGBjdGFnYCB2YWx1ZXMuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uIHdoZW4gZGVsaW1pdGVyIHN0cmluZyBpcyBpbnZhbGlkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dCAgTXVzdGFjaGUgdGVtcGxhdGUgc291cmNlCiAgICAgKiBAcGFyYW0gaW50ICAgICRpbmRleCBDdXJyZW50IHRva2VuaXplciBpbmRleAogICAgICoKICAgICAqIEByZXR1cm4gaW50IE5ldyBpbmRleCB2YWx1ZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoYW5nZURlbGltaXRlcnMoJHRleHQsICRpbmRleCkKICAgIHsKICAgICAgICAkc3RhcnRJbmRleCA9IHN0cnBvcygkdGV4dCwgJz0nLCAkaW5kZXgpICsgMTsKICAgICAgICAkY2xvc2UgICAgICA9ICc9JyAuICR0aGlzLT5jdGFnOwogICAgICAgICRjbG9zZUluZGV4ID0gc3RycG9zKCR0ZXh0LCAkY2xvc2UsICRpbmRleCk7CgogICAgICAgICR0b2tlbiA9IGFycmF5KAogICAgICAgICAgICBzZWxmOjpUWVBFID0+IHNlbGY6OlRfREVMSU1fQ0hBTkdFLAogICAgICAgICAgICBzZWxmOjpMSU5FID0+ICR0aGlzLT5saW5lLAogICAgICAgICk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREZWxpbWl0ZXJzKHRyaW0oc3Vic3RyKCR0ZXh0LCAkc3RhcnRJbmRleCwgJGNsb3NlSW5kZXggLSAkc3RhcnRJbmRleCkpKTsKICAgICAgICB9IGNhdGNoIChNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fU3ludGF4RXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksICR0b2tlbik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dG9rZW5zW10gPSAkdG9rZW47CgogICAgICAgIHJldHVybiAkY2xvc2VJbmRleCArIHN0cmxlbigkY2xvc2UpIC0gMTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgY3VycmVudCBNdXN0YWNoZSBgb3RhZ2AgYW5kIGBjdGFnYCBkZWxpbWl0ZXJzLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIGRlbGltaXRlciBzdHJpbmcgaXMgaW52YWxpZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlbGltaXRlcnMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXREZWxpbWl0ZXJzKCRkZWxpbWl0ZXJzKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL15ccyooXFMrKVxzKyhcUyspXHMqJC8nLCAkZGVsaW1pdGVycywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0ludmFsaWQgZGVsaW1pdGVyczogJXMnLCAkZGVsaW1pdGVycykpOwogICAgICAgIH0KCiAgICAgICAgbGlzdCgkXywgJG90YWcsICRjdGFnKSA9ICRtYXRjaGVzOwoKICAgICAgICAkdGhpcy0+b3RhZyAgICAgPSAkb3RhZzsKICAgICAgICAkdGhpcy0+b3RhZ0NoYXIgPSAkb3RhZ1swXTsKICAgICAgICAkdGhpcy0+b3RhZ0xlbiAgPSBzdHJsZW4oJG90YWcpOwoKICAgICAgICAkdGhpcy0+Y3RhZyAgICAgPSAkY3RhZzsKICAgICAgICAkdGhpcy0+Y3RhZ0NoYXIgPSAkY3RhZ1swXTsKICAgICAgICAkdGhpcy0+Y3RhZ0xlbiAgPSBzdHJsZW4oJGN0YWcpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIHByYWdtYSB0b2tlbi4KICAgICAqCiAgICAgKiBQcmFnbWFzIGFyZSBob2lzdGVkIHRvIHRoZSBmcm9udCBvZiB0aGUgdGVtcGxhdGUsIHNvIGFsbCBwcmFnbWEgdG9rZW5zCiAgICAgKiB3aWxsIGFwcGVhciBhdCB0aGUgZnJvbnQgb2YgdGhlIHRva2VuIGxpc3QuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dAogICAgICogQHBhcmFtIGludCAgICAkaW5kZXgKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBOZXcgaW5kZXggdmFsdWUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRQcmFnbWEoJHRleHQsICRpbmRleCkKICAgIHsKICAgICAgICAkZW5kICAgID0gc3RycG9zKCR0ZXh0LCAkdGhpcy0+Y3RhZywgJGluZGV4KTsKICAgICAgICAkcHJhZ21hID0gdHJpbShzdWJzdHIoJHRleHQsICRpbmRleCArIDIsICRlbmQgLSAkaW5kZXggLSAyKSk7CgogICAgICAgIC8vIFByYWdtYXMgYXJlIGhvaXN0ZWQgdG8gdGhlIGZyb250IG9mIHRoZSB0ZW1wbGF0ZS4KICAgICAgICBhcnJheV91bnNoaWZ0KCR0aGlzLT50b2tlbnMsIGFycmF5KAogICAgICAgICAgICBzZWxmOjpUWVBFID0+IHNlbGY6OlRfUFJBR01BLAogICAgICAgICAgICBzZWxmOjpOQU1FID0+ICRwcmFnbWEsCiAgICAgICAgICAgIHNlbGY6OkxJTkUgPT4gMCwKICAgICAgICApKTsKCiAgICAgICAgcmV0dXJuICRlbmQgKyAkdGhpcy0+Y3RhZ0xlbiAtIDE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgZmlsZXN5c3RlbSBMb2FkZXIgaW1wbGVtZW50YXRpb24uCiAqCiAqIEEgRmlsZXN5c3RlbUxvYWRlciBpbnN0YW5jZSBsb2FkcyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UgZnJvbSB0aGUgZmlsZXN5c3RlbSBieSBuYW1lOgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzJyk7CiAqICAgICAkdHBsID0gJGxvYWRlci0+bG9hZCgnZm9vJyk7IC8vIGVxdWl2YWxlbnQgdG8gYGZpbGVfZ2V0X2NvbnRlbnRzKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MvZm9vLm11c3RhY2hlJyk7CiAqCiAqIFRoaXMgaXMgcHJvYmFibHkgdGhlIG1vc3QgdXNlZnVsIE11c3RhY2hlIExvYWRlciBpbXBsZW1lbnRhdGlvbi4gSXQgY2FuIGJlIHVzZWQgZm9yIHBhcnRpYWxzIGFuZCBub3JtYWwgVGVtcGxhdGVzOgogKgogKiAgICAgJG0gPSBuZXcgTXVzdGFjaGUoYXJyYXkoCiAqICAgICAgICAgICdsb2FkZXInICAgICAgICAgID0+IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzJyksCiAqICAgICAgICAgICdwYXJ0aWFsc19sb2FkZXInID0+IG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihkaXJuYW1lKF9fRklMRV9fKS4nL3ZpZXdzL3BhcnRpYWxzJyksCiAqICAgICApKTsKICovCmNsYXNzIE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyIGltcGxlbWVudHMgTXVzdGFjaGVfTG9hZGVyCnsKICAgIHByaXZhdGUgJGJhc2VEaXI7CiAgICBwcml2YXRlICRleHRlbnNpb24gPSAnLm11c3RhY2hlJzsKICAgIHByaXZhdGUgJHRlbXBsYXRlcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSBmaWxlc3lzdGVtIExvYWRlciBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBQYXNzaW5nIGFuICRvcHRpb25zIGFycmF5IGFsbG93cyBvdmVycmlkaW5nIGNlcnRhaW4gTG9hZGVyIG9wdGlvbnMgZHVyaW5nIGluc3RhbnRpYXRpb246CiAgICAgKgogICAgICogICAgICRvcHRpb25zID0gYXJyYXkoCiAgICAgKiAgICAgICAgIC8vIFRoZSBmaWxlbmFtZSBleHRlbnNpb24gdXNlZCBmb3IgTXVzdGFjaGUgdGVtcGxhdGVzLiBEZWZhdWx0cyB0byAnLm11c3RhY2hlJwogICAgICogICAgICAgICAnZXh0ZW5zaW9uJyA9PiAnLm1zJywKICAgICAqICAgICApOwogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1J1bnRpbWVFeGNlcHRpb24gaWYgJGJhc2VEaXIgZG9lcyBub3QgZXhpc3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyIEJhc2UgZGlyZWN0b3J5IGNvbnRhaW5pbmcgTXVzdGFjaGUgdGVtcGxhdGUgZmlsZXMKICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgQXJyYXkgb2YgTG9hZGVyIG9wdGlvbnMgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5iYXNlRGlyID0gJGJhc2VEaXI7CgogICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPmJhc2VEaXIsICc6Ly8nKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJHRoaXMtPmJhc2VEaXIgPSByZWFscGF0aCgkdGhpcy0+YmFzZURpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENoZWNrUGF0aCgpICYmICFpc19kaXIoJHRoaXMtPmJhc2VEaXIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNdXN0YWNoZV9FeGNlcHRpb25fUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdGaWxlc3lzdGVtTG9hZGVyIGJhc2VEaXIgbXVzdCBiZSBhIGRpcmVjdG9yeTogJXMnLCAkYmFzZURpcikpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ2V4dGVuc2lvbicsICRvcHRpb25zKSkgewogICAgICAgICAgICBpZiAoZW1wdHkoJG9wdGlvbnNbJ2V4dGVuc2lvbiddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmV4dGVuc2lvbiA9ICcnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmV4dGVuc2lvbiA9ICcuJyAuIGx0cmltKCRvcHRpb25zWydleHRlbnNpb24nXSwgJy4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqICAgICAkbG9hZGVyID0gbmV3IE11c3RhY2hlX0xvYWRlcl9GaWxlc3lzdGVtTG9hZGVyKGRpcm5hbWUoX19GSUxFX18pLicvdmlld3MnKTsKICAgICAqICAgICAkbG9hZGVyLT5sb2FkKCdhZG1pbi9kYXNoYm9hcmQnKTsgLy8gbG9hZHMgIi4vdmlld3MvYWRtaW4vZGFzaGJvYXJkLm11c3RhY2hlIjsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnRlbXBsYXRlc1skbmFtZV0pKSB7CiAgICAgICAgICAgICR0aGlzLT50ZW1wbGF0ZXNbJG5hbWVdID0gJHRoaXMtPmxvYWRGaWxlKCRuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiBmb3IgbG9hZGluZyBhIE11c3RhY2hlIGZpbGUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gSWYgYSB0ZW1wbGF0ZSBmaWxlIGlzIG5vdCBmb3VuZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRGaWxlKCRuYW1lKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRGaWxlTmFtZSgkbmFtZSk7CgogICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2hlY2tQYXRoKCkgJiYgIWZpbGVfZXhpc3RzKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGdldHRpbmcgYSBNdXN0YWNoZSB0ZW1wbGF0ZSBmaWxlIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRlbXBsYXRlIGZpbGUgbmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RmlsZU5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmJhc2VEaXIgLiAnLycgLiAkbmFtZTsKICAgICAgICBpZiAoc3Vic3RyKCRmaWxlTmFtZSwgMCAtIHN0cmxlbigkdGhpcy0+ZXh0ZW5zaW9uKSkgIT09ICR0aGlzLT5leHRlbnNpb24pIHsKICAgICAgICAgICAgJGZpbGVOYW1lIC49ICR0aGlzLT5leHRlbnNpb247CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGVOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogT25seSBjaGVjayBpZiBiYXNlRGlyIGlzIGEgZGlyZWN0b3J5IGFuZCByZXF1ZXN0ZWQgdGVtcGxhdGVzIGFyZSBmaWxlcyBpZgogICAgICogYmFzZURpciBpcyB1c2luZyB0aGUgZmlsZXN5c3RlbSBzdHJlYW0gd3JhcHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0byBjaGVjayBgaXNfZGlyYCBhbmQgYGZpbGVfZXhpc3RzYAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2hvdWxkQ2hlY2tQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gc3RycG9zKCR0aGlzLT5iYXNlRGlyLCAnOi8vJykgPT09IGZhbHNlIHx8IHN0cnBvcygkdGhpcy0+YmFzZURpciwgJ2ZpbGU6Ly8nKSA9PT0gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBUZW1wbGF0ZSBhcnJheSBMb2FkZXIgaW1wbGVtZW50YXRpb24uCiAqCiAqIEFuIEFycmF5TG9hZGVyIGluc3RhbmNlIGxvYWRzIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZSBieSBuYW1lIGZyb20gYW4gaW5pdGlhbCBhcnJheToKICoKICogICAgICRsb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoCiAqICAgICAgICAgJ2ZvbycgPT4gJ3t7IGJhciB9fScsCiAqICAgICAgICAgJ2JheicgPT4gJ0hleSB7eyBxdXggfX0hJwogKiAgICAgKTsKICoKICogICAgICR0cGwgPSAkbG9hZGVyLT5sb2FkKCdmb28nKTsgLy8gJ3t7IGJhciB9fScKICoKICogVGhlIEFycmF5TG9hZGVyIGlzIHVzZWQgaW50ZXJuYWxseSBhcyBhIHBhcnRpYWxzIGxvYWRlciBieSBNdXN0YWNoZV9FbmdpbmUgaW5zdGFuY2Ugd2hlbiBhbiBhcnJheSBvZiBwYXJ0aWFscwogKiBpcyBzZXQuIEl0IGNhbiBhbHNvIGJlIHVzZWQgYXMgYSBxdWljay1hbmQtZGlydHkgVGVtcGxhdGUgbG9hZGVyLgogKi8KY2xhc3MgTXVzdGFjaGVfTG9hZGVyX0FycmF5TG9hZGVyIGltcGxlbWVudHMgTXVzdGFjaGVfTG9hZGVyLCBNdXN0YWNoZV9Mb2FkZXJfTXV0YWJsZUxvYWRlcgp7CiAgICBwcml2YXRlICR0ZW1wbGF0ZXM7CgogICAgLyoqCiAgICAgKiBBcnJheUxvYWRlciBjb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRlbXBsYXRlcyBBc3NvY2lhdGl2ZSBhcnJheSBvZiBUZW1wbGF0ZSBzb3VyY2UgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkdGVtcGxhdGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+dGVtcGxhdGVzID0gJHRlbXBsYXRlczsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gSWYgYSB0ZW1wbGF0ZSBmaWxlIGlzIG5vdCBmb3VuZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50ZW1wbGF0ZXNbJG5hbWVdOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IGFuIGFzc29jaWF0aXZlIGFycmF5IG9mIFRlbXBsYXRlIHNvdXJjZXMgZm9yIHRoaXMgbG9hZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdGVtcGxhdGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZW1wbGF0ZXMoYXJyYXkgJHRlbXBsYXRlcykKICAgIHsKICAgICAgICAkdGhpcy0+dGVtcGxhdGVzID0gJHRlbXBsYXRlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIFRlbXBsYXRlIHNvdXJjZSBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRlbXBsYXRlIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVtcGxhdGUoJG5hbWUsICR0ZW1wbGF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dGVtcGxhdGVzWyRuYW1lXSA9ICR0ZW1wbGF0ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBBIE11c3RhY2hlIFRlbXBsYXRlIGxvYWRlciBmb3IgaW5saW5lIHRlbXBsYXRlcy4KICoKICogV2l0aCB0aGUgSW5saW5lTG9hZGVyLCB0ZW1wbGF0ZXMgY2FuIGJlIGRlZmluZWQgYXQgdGhlIGVuZCBvZiBhbnkgUEhQIHNvdXJjZQogKiBmaWxlOgogKgogKiAgICAgJGxvYWRlciAgPSBuZXcgTXVzdGFjaGVfTG9hZGVyX0lubGluZUxvYWRlcihfX0ZJTEVfXywgX19DT01QSUxFUl9IQUxUX09GRlNFVF9fKTsKICogICAgICRoZWxsbyAgID0gJGxvYWRlci0+bG9hZCgnaGVsbG8nKTsKICogICAgICRnb29kYnllID0gJGxvYWRlci0+bG9hZCgnZ29vZGJ5ZScpOwogKgogKiAgICAgX19oYWx0X2NvbXBpbGVyKCk7CiAqCiAqICAgICBAQCBoZWxsbwogKiAgICAgSGVsbG8sIHt7IHBsYW5ldCB9fSEKICoKICogICAgIEBAIGdvb2RieWUKICogICAgIEdvb2RieWUsIGNydWVsIHt7IHBsYW5ldCB9fQogKgogKiBUZW1wbGF0ZXMgYXJlIGRlbGluaWF0ZWQgYnkgbGluZXMgY29udGFpbmluZyBvbmx5IGBAQCBuYW1lYC4KICoKICogVGhlIElubGluZUxvYWRlciBpcyB3ZWxsLXN1aXRlZCB0byBtaWNyby1mcmFtZXdvcmtzIHN1Y2ggYXMgU2lsZXg6CiAqCiAqICAgICAkYXBwLT5yZWdpc3RlcihuZXcgTXVzdGFjaGVTZXJ2aWNlUHJvdmlkZXIsIGFycmF5KAogKiAgICAgICAgICdtdXN0YWNoZS5sb2FkZXInID0+IG5ldyBNdXN0YWNoZV9Mb2FkZXJfSW5saW5lTG9hZGVyKF9fRklMRV9fLCBfX0NPTVBJTEVSX0hBTFRfT0ZGU0VUX18pCiAqICAgICApKTsKICoKICogICAgICRhcHAtPmdldCgnL3tuYW1lfScsIGZ1bmN0aW9uICgkbmFtZSkgdXNlICgkYXBwKSB7CiAqICAgICAgICAgcmV0dXJuICRhcHBbJ211c3RhY2hlJ10tPnJlbmRlcignaGVsbG8nLCBjb21wYWN0KCduYW1lJykpOwogKiAgICAgfSkKICogICAgIC0+dmFsdWUoJ25hbWUnLCAnd29ybGQnKTsKICoKICogICAgIC8vIC4uLgogKgogKiAgICAgX19oYWx0X2NvbXBpbGVyKCk7CiAqCiAqICAgICBAQCBoZWxsbwogKiAgICAgSGVsbG8sIHt7IG5hbWUgfX0hCiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2FkZXJfSW5saW5lTG9hZGVyIGltcGxlbWVudHMgTXVzdGFjaGVfTG9hZGVyCnsKICAgIHByb3RlY3RlZCAkZmlsZU5hbWU7CiAgICBwcm90ZWN0ZWQgJG9mZnNldDsKICAgIHByb3RlY3RlZCAkdGVtcGxhdGVzOwoKICAgIC8qKgogICAgICogVGhlIElubGluZUxvYWRlciByZXF1aXJlcyBhIGZpbGVuYW1lIGFuZCBvZmZzZXQgdG8gcHJvY2VzcyB0ZW1wbGF0ZXMuCiAgICAgKgogICAgICogVGhlIG1hZ2ljIGNvbnN0YW50cyBgX19GSUxFX19gIGFuZCBgX19DT01QSUxFUl9IQUxUX09GRlNFVF9fYCBhcmUgdXN1YWxseQogICAgICogcGVyZmVjdGx5IHN1aXRlZCB0byB0aGUgam9iOgogICAgICoKICAgICAqICAgICAkbG9hZGVyID0gbmV3IE11c3RhY2hlX0xvYWRlcl9JbmxpbmVMb2FkZXIoX19GSUxFX18sIF9fQ09NUElMRVJfSEFMVF9PRkZTRVRfXyk7CiAgICAgKgogICAgICogTm90ZSB0aGF0IHRoaXMgb25seSB3b3JrcyBpZiB0aGUgbG9hZGVyIGlzIGluc3RhbnRpYXRlZCBpbnNpZGUgdGhlIHNhbWUKICAgICAqIGZpbGUgYXMgdGhlIGlubGluZSB0ZW1wbGF0ZXMuIElmIHRoZSB0ZW1wbGF0ZXMgYXJlIGxvY2F0ZWQgaW4gYW5vdGhlcgogICAgICogZmlsZSwgaXQgd291bGQgYmUgbmVjZXNzYXJ5IHRvIG1hbnVhbGx5IHNwZWNpZnkgdGhlIGZpbGVuYW1lIGFuZCBvZmZzZXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZU5hbWUgVGhlIGZpbGUgdG8gcGFyc2UgZm9yIGlubGluZSB0ZW1wbGF0ZXMKICAgICAqIEBwYXJhbSBpbnQgICAgJG9mZnNldCAgIEEgc3RyaW5nIG9mZnNldCBmb3IgdGhlIHN0YXJ0IG9mIHRoZSB0ZW1wbGF0ZXMuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIHVzdWFsbHkgY29pbmNpZGVzIHdpdGggdGhlIGBfX2hhbHRfY29tcGlsZXJgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsLCBhbmQgdGhlIGBfX0NPTVBJTEVSX0hBTFRfT0ZGU0VUX19gCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZmlsZU5hbWUsICRvZmZzZXQpCiAgICB7CiAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9JbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0lubGluZUxvYWRlciBleHBlY3RzIGEgdmFsaWQgZmlsZW5hbWUuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX2ludCgkb2Zmc2V0KSB8fCAkb2Zmc2V0IDwgMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX0ludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW5saW5lTG9hZGVyIGV4cGVjdHMgYSB2YWxpZCBmaWxlIG9mZnNldC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maWxlTmFtZSA9ICRmaWxlTmFtZTsKICAgICAgICAkdGhpcy0+b2Zmc2V0ICAgPSAkb2Zmc2V0OwogICAgfQoKICAgIC8qKgogICAgICogTG9hZCBhIFRlbXBsYXRlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHRocm93cyBNdXN0YWNoZV9FeGNlcHRpb25fVW5rbm93blRlbXBsYXRlRXhjZXB0aW9uIElmIGEgdGVtcGxhdGUgZmlsZSBpcyBub3QgZm91bmQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgTXVzdGFjaGUgVGVtcGxhdGUgc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5sb2FkVGVtcGxhdGVzKCk7CgogICAgICAgIGlmICghYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJHRoaXMtPnRlbXBsYXRlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50ZW1wbGF0ZXNbJG5hbWVdOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2UgYW5kIGxvYWQgdGVtcGxhdGVzIGZyb20gdGhlIGVuZCBvZiBhIHNvdXJjZSBmaWxlLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbG9hZFRlbXBsYXRlcygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT50ZW1wbGF0ZXMgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnRlbXBsYXRlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRkYXRhID0gZmlsZV9nZXRfY29udGVudHMoJHRoaXMtPmZpbGVOYW1lLCBmYWxzZSwgbnVsbCwgJHRoaXMtPm9mZnNldCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHByZWdfc3BsaXQoIi9eQEAoPz0gW1x3XGRcLl0rJCkvbSIsICRkYXRhLCAtMSkgYXMgJGNodW5rKSB7CiAgICAgICAgICAgICAgICBpZiAodHJpbSgkY2h1bmspKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJGNvbnRlbnQpICAgICAgICAgPSBleHBsb2RlKCJcbiIsICRjaHVuaywgMik7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnRlbXBsYXRlc1t0cmltKCRuYW1lKV0gPSB0cmltKCRjb250ZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgTXVzdGFjaGUucGhwLgogKgogKiAoYykgMjAxMC0yMDE3IEp1c3RpbiBIaWxlbWFuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCi8qKgogKiBNdXN0YWNoZSBUZW1wbGF0ZSBzdHJpbmcgTG9hZGVyIGltcGxlbWVudGF0aW9uLgogKgogKiBBIFN0cmluZ0xvYWRlciBpbnN0YW5jZSBpcyBlc3NlbnRpYWxseSBhIG5vb3AuIEl0IHNpbXBseSBwYXNzZXMgdGhlICduYW1lJyBhcmd1bWVudCBzdHJhaWdodCB0aHJvdWdoOgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBTdHJpbmdMb2FkZXI7CiAqICAgICAkdHBsID0gJGxvYWRlci0+bG9hZCgne3sgZm9vIH19Jyk7IC8vICd7eyBmb28gfX0nCiAqCiAqIFRoaXMgaXMgdGhlIGRlZmF1bHQgVGVtcGxhdGUgTG9hZGVyIGluc3RhbmNlIHVzZWQgYnkgTXVzdGFjaGU6CiAqCiAqICAgICAkbSA9IG5ldyBNdXN0YWNoZTsKICogICAgICR0cGwgPSAkbS0+bG9hZFRlbXBsYXRlKCd7eyBmb28gfX0nKTsKICogICAgIGVjaG8gJHRwbC0+cmVuZGVyKGFycmF5KCdmb28nID0+ICdiYXInKSk7IC8vICJiYXIiCiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2FkZXJfU3RyaW5nTG9hZGVyIGltcGxlbWVudHMgTXVzdGFjaGVfTG9hZGVyCnsKICAgIC8qKgogICAgICogTG9hZCBhIFRlbXBsYXRlIGJ5IHNvdXJjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZCgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJG5hbWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogQSBNdXN0YWNoZSBUZW1wbGF0ZSBjYXNjYWRpbmcgbG9hZGVyIGltcGxlbWVudGF0aW9uLCB3aGljaCBkZWxlZ2F0ZXMgdG8gb3RoZXIKICogTG9hZGVyIGluc3RhbmNlcy4KICovCmNsYXNzIE11c3RhY2hlX0xvYWRlcl9DYXNjYWRpbmdMb2FkZXIgaW1wbGVtZW50cyBNdXN0YWNoZV9Mb2FkZXIKewogICAgcHJpdmF0ZSAkbG9hZGVyczsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIENhc2NhZGluZ0xvYWRlciB3aXRoIGFuIGFycmF5IG9mIGxvYWRlcnMuCiAgICAgKgogICAgICogICAgICRsb2FkZXIgPSBuZXcgTXVzdGFjaGVfTG9hZGVyX0Nhc2NhZGluZ0xvYWRlcihhcnJheSgKICAgICAqICAgICAgICAgbmV3IE11c3RhY2hlX0xvYWRlcl9JbmxpbmVMb2FkZXIoX19GSUxFX18sIF9fQ09NUElMRVJfSEFMVF9PRkZTRVRfXyksCiAgICAgKiAgICAgICAgIG5ldyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcihfX0RJUl9fLicvdGVtcGxhdGVzJykKICAgICAqICAgICApKTsKICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfTG9hZGVyW10gJGxvYWRlcnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRsb2FkZXJzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZGVycyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGxvYWRlcnMgYXMgJGxvYWRlcikgewogICAgICAgICAgICAkdGhpcy0+YWRkTG9hZGVyKCRsb2FkZXIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIExvYWRlciBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gTXVzdGFjaGVfTG9hZGVyICRsb2FkZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZExvYWRlcihNdXN0YWNoZV9Mb2FkZXIgJGxvYWRlcikKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZGVyc1tdID0gJGxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBUZW1wbGF0ZSBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiBJZiBhIHRlbXBsYXRlIGZpbGUgaXMgbm90IGZvdW5kCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIE11c3RhY2hlIFRlbXBsYXRlIHNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZCgkbmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bG9hZGVycyBhcyAkbG9hZGVyKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxvYWRlci0+bG9hZCgkbmFtZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcsIGNoZWNrIHRoZSBuZXh0IGxvYWRlci4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IE11c3RhY2hlX0V4Y2VwdGlvbl9Vbmtub3duVGVtcGxhdGVFeGNlcHRpb24oJG5hbWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIFRlbXBsYXRlIHByb2R1Y3Rpb24gZmlsZXN5c3RlbSBMb2FkZXIgaW1wbGVtZW50YXRpb24uCiAqCiAqIEEgcHJvZHVjdGlvbi1yZWFkeSBGaWxlc3lzdGVtTG9hZGVyLCB3aGljaCBkb2Vzbid0IHJlcXVpcmUgcmVhZGluZyBhIGZpbGUgaWYgaXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHRlbXBsYXRlIGNhY2hlLgogKgogKiB7QGluaGVyaXRkb2N9CiAqLwpjbGFzcyBNdXN0YWNoZV9Mb2FkZXJfUHJvZHVjdGlvbkZpbGVzeXN0ZW1Mb2FkZXIgZXh0ZW5kcyBNdXN0YWNoZV9Mb2FkZXJfRmlsZXN5c3RlbUxvYWRlcgp7CiAgICBwcml2YXRlICRzdGF0UHJvcHM7CgogICAgLyoqCiAgICAgKiBNdXN0YWNoZSBwcm9kdWN0aW9uIGZpbGVzeXN0ZW0gTG9hZGVyIGNvbnN0cnVjdG9yLgogICAgICoKICAgICAqIFBhc3NpbmcgYW4gJG9wdGlvbnMgYXJyYXkgYWxsb3dzIG92ZXJyaWRpbmcgY2VydGFpbiBMb2FkZXIgb3B0aW9ucyBkdXJpbmcgaW5zdGFudGlhdGlvbjoKICAgICAqCiAgICAgKiAgICAgJG9wdGlvbnMgPSBhcnJheSgKICAgICAqICAgICAgICAgLy8gVGhlIGZpbGVuYW1lIGV4dGVuc2lvbiB1c2VkIGZvciBNdXN0YWNoZSB0ZW1wbGF0ZXMuIERlZmF1bHRzIHRvICcubXVzdGFjaGUnCiAgICAgKiAgICAgICAgICdleHRlbnNpb24nID0+ICcubXMnLAogICAgICogICAgICAgICAnc3RhdF9wcm9wcycgPT4gYXJyYXkoJ3NpemUnLCAnbXRpbWUnKSwKICAgICAqICAgICApOwogICAgICoKICAgICAqIFNwZWNpZnlpbmcgJ3N0YXRfcHJvcHMnIG92ZXJyaWRlcyB0aGUgc3RhdCBwcm9wZXJ0aWVzIHVzZWQgdG8gaW52YWxpZGF0ZSB0aGUgdGVtcGxhdGUgY2FjaGUuIEJ5IGRlZmF1bHQsIHRoaXMKICAgICAqIHVzZXMgJ210aW1lJyBhbmQgJ3NpemUnLCBidXQgdGhpcyBjYW4gYmUgc2V0IHRvIGFueSBvZiB0aGUgcHJvcGVydGllcyBzdXBwb3J0ZWQgYnkgc3RhdCgpOgogICAgICoKICAgICAqICAgICBodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RhdC5waHAKICAgICAqCiAgICAgKiBZb3UgY2FuIGFsc28gZGlzYWJsZSBmaWxlc3lzdGVtIHN0YXQgZW50aXJlbHk6CiAgICAgKgogICAgICogICAgICRvcHRpb25zID0gYXJyYXkoJ3N0YXRfcHJvcHMnID0+IG51bGwpOwogICAgICoKICAgICAqIEJ1dCB3aXRoIGdyZWF0IHBvd2VyIGNvbWVzIGdyZWF0IHJlc3BvbnNpYmlsaXR5LiBOYW1lbHksIGlmIHlvdSBkaXNhYmxlIHN0YXQtYmFzZWQgY2FjaGUgaW52YWxpZGF0aW9uLAogICAgICogWU9VIE1VU1QgQ0xFQVIgVEhFIFRFTVBMQVRFIENBQ0hFIFlPVVJTRUxGIHdoZW4geW91ciB0ZW1wbGF0ZXMgY2hhbmdlLiBNYWtlIGl0IHBhcnQgb2YgeW91ciBidWlsZCBvciBkZXBsb3kKICAgICAqIHByb2Nlc3Mgc28geW91IGRvbid0IGZvcmdldCEKICAgICAqCiAgICAgKiBAdGhyb3dzIE11c3RhY2hlX0V4Y2VwdGlvbl9SdW50aW1lRXhjZXB0aW9uIGlmICRiYXNlRGlyIGRvZXMgbm90IGV4aXN0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VEaXIgQmFzZSBkaXJlY3RvcnkgY29udGFpbmluZyBNdXN0YWNoZSB0ZW1wbGF0ZSBmaWxlcy4KICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMgQXJyYXkgb2YgTG9hZGVyIG9wdGlvbnMgKGRlZmF1bHQ6IGFycmF5KCkpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYmFzZURpciwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGJhc2VEaXIsICRvcHRpb25zKTsKCiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3N0YXRfcHJvcHMnLCAkb3B0aW9ucykpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRvcHRpb25zWydzdGF0X3Byb3BzJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3RhdFByb3BzID0gYXJyYXkoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdGF0UHJvcHMgPSAkb3B0aW9uc1snc3RhdF9wcm9wcyddOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnN0YXRQcm9wcyA9IGFycmF5KCdzaXplJywgJ210aW1lJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciBsb2FkaW5nIGEgTXVzdGFjaGUgZmlsZSBieSBuYW1lLgogICAgICoKICAgICAqIEB0aHJvd3MgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbiBJZiBhIHRlbXBsYXRlIGZpbGUgaXMgbm90IGZvdW5kLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIE11c3RhY2hlX1NvdXJjZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRGaWxlKCRuYW1lKQogICAgewogICAgICAgICRmaWxlTmFtZSA9ICR0aGlzLT5nZXRGaWxlTmFtZSgkbmFtZSk7CgogICAgICAgIGlmICghZmlsZV9leGlzdHMoJGZpbGVOYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTXVzdGFjaGVfRXhjZXB0aW9uX1Vua25vd25UZW1wbGF0ZUV4Y2VwdGlvbigkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IE11c3RhY2hlX1NvdXJjZV9GaWxlc3lzdGVtU291cmNlKCRmaWxlTmFtZSwgJHRoaXMtPnN0YXRQcm9wcyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIE11c3RhY2hlLnBocC4KICoKICogKGMpIDIwMTAtMjAxNyBKdXN0aW4gSGlsZW1hbgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKioKICogTXVzdGFjaGUgVGVtcGxhdGUgbXV0YWJsZSBMb2FkZXIgaW50ZXJmYWNlLgogKi8KaW50ZXJmYWNlIE11c3RhY2hlX0xvYWRlcl9NdXRhYmxlTG9hZGVyCnsKICAgIC8qKgogICAgICogU2V0IGFuIGFzc29jaWF0aXZlIGFycmF5IG9mIFRlbXBsYXRlIHNvdXJjZXMgZm9yIHRoaXMgbG9hZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdGVtcGxhdGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZW1wbGF0ZXMoYXJyYXkgJHRlbXBsYXRlcyk7CgogICAgLyoqCiAgICAgKiBTZXQgYSBUZW1wbGF0ZSBzb3VyY2UgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZW1wbGF0ZSBNdXN0YWNoZSBUZW1wbGF0ZSBzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlbXBsYXRlKCRuYW1lLCAkdGVtcGxhdGUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBNdXN0YWNoZS5waHAuCiAqCiAqIChjKSAyMDEwLTIwMTcgSnVzdGluIEhpbGVtYW4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKLyoqCiAqIE11c3RhY2hlIENhY2hlIGludGVyZmFjZS4KICoKICogSW50ZXJmYWNlIGZvciBjYWNoaW5nIGFuZCBsb2FkaW5nIE11c3RhY2hlX1RlbXBsYXRlIGNsYXNzZXMKICogZ2VuZXJhdGVkIGJ5IHRoZSBNdXN0YWNoZV9Db21waWxlci4KICovCmludGVyZmFjZSBNdXN0YWNoZV9DYWNoZQp7CiAgICAvKioKICAgICAqIExvYWQgYSBjb21waWxlZCBNdXN0YWNoZV9UZW1wbGF0ZSBjbGFzcyBmcm9tIGNhY2hlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBpbmRpY2F0ZXMgc3VjY2Vzc2Z1bGx5IGNsYXNzIGxvYWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJGtleSk7CgogICAgLyoqCiAgICAgKiBDYWNoZSBhbmQgbG9hZCBhIGNvbXBpbGVkIE11c3RhY2hlX1RlbXBsYXRlIGNsYXNzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNhY2hlKCRrZXksICR2YWx1ZSk7Cn0KPD9waHAKLyoqCiAqIFJlcXVlc3RzIGZvciBQSFAKICoKICogSW5zcGlyZWQgYnkgUmVxdWVzdHMgZm9yIFB5dGhvbi4KICoKICogQmFzZWQgb24gY29uY2VwdHMgZnJvbSBTaW1wbGVQaWVfRmlsZSwgUmVxdWVzdENvcmUgYW5kIFdQX0h0dHAuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIFJlcXVlc3RzIGZvciBQSFAKICoKICogSW5zcGlyZWQgYnkgUmVxdWVzdHMgZm9yIFB5dGhvbi4KICoKICogQmFzZWQgb24gY29uY2VwdHMgZnJvbSBTaW1wbGVQaWVfRmlsZSwgUmVxdWVzdENvcmUgYW5kIFdQX0h0dHAuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0cyB7CgkvKioKCSAqIFBPU1QgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUE9TVCA9ICdQT1NUJzsKCgkvKioKCSAqIFBVVCBtZXRob2QKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBQVVQgPSAnUFVUJzsKCgkvKioKCSAqIEdFVCBtZXRob2QKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBHRVQgPSAnR0VUJzsKCgkvKioKCSAqIEhFQUQgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgSEVBRCA9ICdIRUFEJzsKCgkvKioKCSAqIERFTEVURSBtZXRob2QKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBERUxFVEUgPSAnREVMRVRFJzsKCgkvKioKCSAqIE9QVElPTlMgbWV0aG9kCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgT1BUSU9OUyA9ICdPUFRJT05TJzsKCgkvKioKCSAqIFRSQUNFIG1ldGhvZAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFRSQUNFID0gJ1RSQUNFJzsKCgkvKioKCSAqIFBBVENIIG1ldGhvZAoJICoKCSAqIEBsaW5rIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM1Nzg5CgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBQQVRDSCA9ICdQQVRDSCc7CgoJLyoqCgkgKiBEZWZhdWx0IHNpemUgb2YgYnVmZmVyIHNpemUgdG8gcmVhZCBzdHJlYW1zCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCWNvbnN0IEJVRkZFUl9TSVpFID0gMTE2MDsKCgkvKioKCSAqIEN1cnJlbnQgdmVyc2lvbiBvZiBSZXF1ZXN0cwoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFZFUlNJT04gPSAnMS43JzsKCgkvKioKCSAqIFJlZ2lzdGVyZWQgdHJhbnNwb3J0IGNsYXNzZXMKCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgJHRyYW5zcG9ydHMgPSBhcnJheSgpOwoKCS8qKgoJICogU2VsZWN0ZWQgdHJhbnNwb3J0IG5hbWUKCSAqCgkgKiBVc2Uge0BzZWUgZ2V0X3RyYW5zcG9ydCgpfSBpbnN0ZWFkCgkgKgoJICogQHZhciBhcnJheQoJICovCglwdWJsaWMgc3RhdGljICR0cmFuc3BvcnQgPSBhcnJheSgpOwoKCS8qKgoJICogRGVmYXVsdCBjZXJ0aWZpY2F0ZSBwYXRoLgoJICoKCSAqIEBzZWUgUmVxdWVzdHM6OmdldF9jZXJ0aWZpY2F0ZV9wYXRoKCkKCSAqIEBzZWUgUmVxdWVzdHM6OnNldF9jZXJ0aWZpY2F0ZV9wYXRoKCkKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgc3RhdGljICRjZXJ0aWZpY2F0ZV9wYXRoOwoKCS8qKgoJICogVGhpcyBpcyBhIHN0YXRpYyBjbGFzcywgZG8gbm90IGluc3RhbnRpYXRlIGl0CgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkge30KCgkvKioKCSAqIEF1dG9sb2FkZXIgZm9yIFJlcXVlc3RzCgkgKgoJICogUmVnaXN0ZXIgdGhpcyB3aXRoIHtAc2VlIHJlZ2lzdGVyX2F1dG9sb2FkZXIoKX0gaWYgeW91J2QgbGlrZSB0byBhdm9pZAoJICogaGF2aW5nIHRvIGNyZWF0ZSB5b3VyIG93bi4KCSAqCgkgKiAoWW91IGNhbiBhbHNvIHVzZSBgc3BsX2F1dG9sb2FkX3JlZ2lzdGVyYCBkaXJlY3RseSBpZiB5b3UnZCBwcmVmZXIuKQoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjbGFzcyBDbGFzcyBuYW1lIHRvIGxvYWQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhdXRvbG9hZGVyKCRjbGFzcykgewoJCS8vIENoZWNrIHRoYXQgdGhlIGNsYXNzIHN0YXJ0cyB3aXRoICJSZXF1ZXN0cyIKCQlpZiAoc3RycG9zKCRjbGFzcywgJ1JlcXVlc3RzJykgIT09IDApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJGZpbGUgPSBzdHJfcmVwbGFjZSgnXycsICcvJywgJGNsYXNzKTsKCQlpZiAoZmlsZV9leGlzdHMoZGlybmFtZShfX0ZJTEVfXykgLiAnLycgLiAkZmlsZSAuICcucGhwJykpIHsKCQkJcmVxdWlyZV9vbmNlIGRpcm5hbWUoX19GSUxFX18pIC4gJy8nIC4gJGZpbGUgLiAnLnBocCc7CgkJfQoJfQoKCS8qKgoJICogUmVnaXN0ZXIgdGhlIGJ1aWx0LWluIGF1dG9sb2FkZXIKCSAqCgkgKiBAY29kZUNvdmVyYWdlSWdub3JlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVnaXN0ZXJfYXV0b2xvYWRlcigpIHsKCQlzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJ1JlcXVlc3RzJywgJ2F1dG9sb2FkZXInKSk7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciBhIHRyYW5zcG9ydAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRyYW5zcG9ydCBUcmFuc3BvcnQgY2xhc3MgdG8gYWRkLCBtdXN0IHN1cHBvcnQgdGhlIFJlcXVlc3RzX1RyYW5zcG9ydCBpbnRlcmZhY2UKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRfdHJhbnNwb3J0KCR0cmFuc3BvcnQpIHsKCQlpZiAoZW1wdHkoc2VsZjo6JHRyYW5zcG9ydHMpKSB7CgkJCXNlbGY6OiR0cmFuc3BvcnRzID0gYXJyYXkoCgkJCQknUmVxdWVzdHNfVHJhbnNwb3J0X2NVUkwnLAoJCQkJJ1JlcXVlc3RzX1RyYW5zcG9ydF9mc29ja29wZW4nLAoJCQkpOwoJCX0KCgkJc2VsZjo6JHRyYW5zcG9ydHMgPSBhcnJheV9tZXJnZShzZWxmOjokdHJhbnNwb3J0cywgYXJyYXkoJHRyYW5zcG9ydCkpOwoJfQoKCS8qKgoJICogR2V0IGEgd29ya2luZyB0cmFuc3BvcnQKCSAqCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBJZiBubyB2YWxpZCB0cmFuc3BvcnQgaXMgZm91bmQgKGBub3RyYW5zcG9ydGApCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1RyYW5zcG9ydAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF90cmFuc3BvcnQoJGNhcGFiaWxpdGllcyA9IGFycmF5KCkpIHsKCQkvLyBDYWNoaW5nIGNvZGUsIGRvbid0IGJvdGhlciB0ZXN0aW5nIGNvdmVyYWdlCgkJLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0CgkJLy8gYXJyYXkgb2YgY2FwYWJpbGl0aWVzIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYW4gYXJyYXkga2V5CgkJa3NvcnQoJGNhcGFiaWxpdGllcyk7CgkJJGNhcF9zdHJpbmcgPSBzZXJpYWxpemUoJGNhcGFiaWxpdGllcyk7CgoJCS8vIERvbid0IHNlYXJjaCBmb3IgYSB0cmFuc3BvcnQgaWYgaXQncyBhbHJlYWR5IGJlZW4gZG9uZSBmb3IgdGhlc2UgJGNhcGFiaWxpdGllcwoJCWlmIChpc3NldChzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSkgJiYgc2VsZjo6JHRyYW5zcG9ydFskY2FwX3N0cmluZ10gIT09IG51bGwpIHsKCQkJJGNsYXNzID0gc2VsZjo6JHRyYW5zcG9ydFskY2FwX3N0cmluZ107CgkJCXJldHVybiBuZXcgJGNsYXNzKCk7CgkJfQoJCS8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCgkJaWYgKGVtcHR5KHNlbGY6OiR0cmFuc3BvcnRzKSkgewoJCQlzZWxmOjokdHJhbnNwb3J0cyA9IGFycmF5KAoJCQkJJ1JlcXVlc3RzX1RyYW5zcG9ydF9jVVJMJywKCQkJCSdSZXF1ZXN0c19UcmFuc3BvcnRfZnNvY2tvcGVuJywKCQkJKTsKCQl9CgoJCS8vIEZpbmQgdXMgYSB3b3JraW5nIHRyYW5zcG9ydAoJCWZvcmVhY2ggKHNlbGY6OiR0cmFuc3BvcnRzIGFzICRjbGFzcykgewoJCQlpZiAoIWNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdCA9IGNhbGxfdXNlcl9mdW5jKGFycmF5KCRjbGFzcywgJ3Rlc3QnKSwgJGNhcGFiaWxpdGllcyk7CgkJCWlmICgkcmVzdWx0KSB7CgkJCQlzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSA9ICRjbGFzczsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCWlmIChzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXSA9PT0gbnVsbCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdObyB3b3JraW5nIHRyYW5zcG9ydHMgZm91bmQnLCAnbm90cmFuc3BvcnQnLCBzZWxmOjokdHJhbnNwb3J0cyk7CgkJfQoKCQkkY2xhc3MgPSBzZWxmOjokdHJhbnNwb3J0WyRjYXBfc3RyaW5nXTsKCQlyZXR1cm4gbmV3ICRjbGFzcygpOwoJfQoKCS8qKiNAKwoJICogQHNlZSByZXF1ZXN0KCkKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKCSAqIEByZXR1cm4gUmVxdWVzdHNfUmVzcG9uc2UKCSAqLwoJLyoqCgkgKiBTZW5kIGEgR0VUIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgc2VsZjo6R0VULCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgSEVBRCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGVhZCgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiBzZWxmOjpyZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCBudWxsLCBzZWxmOjpIRUFELCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgREVMRVRFIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZWxldGUoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgc2VsZjo6REVMRVRFLCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgVFJBQ0UgcmVxdWVzdAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRyYWNlKCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJcmV0dXJuIHNlbGY6OnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIHNlbGY6OlRSQUNFLCAkb3B0aW9ucyk7Cgl9CgkvKiojQC0qLwoKCS8qKiNAKwoJICogQHNlZSByZXF1ZXN0KCkKCSAqIEBwYXJhbSBzdHJpbmcgJHVybAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzCgkgKiBAcGFyYW0gYXJyYXkgJGRhdGEKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwoJICogQHJldHVybiBSZXF1ZXN0c19SZXNwb25zZQoJICovCgkvKioKCSAqIFNlbmQgYSBQT1NUIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwb3N0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6OlBPU1QsICRvcHRpb25zKTsKCX0KCS8qKgoJICogU2VuZCBhIFBVVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHV0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6OlBVVCwgJG9wdGlvbnMpOwoJfQoKCS8qKgoJICogU2VuZCBhbiBPUFRJT05TIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBvcHRpb25zKCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gc2VsZjo6cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIHNlbGY6Ok9QVElPTlMsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBQQVRDSCByZXF1ZXN0CgkgKgoJICogTm90ZTogVW5saWtlIHtAc2VlIHBvc3R9IGFuZCB7QHNlZSBwdXR9LCBgJGhlYWRlcnNgIGlzIHJlcXVpcmVkLCBhcyB0aGUKCSAqIHNwZWNpZmljYXRpb24gcmVjb21tZW5kcyB0aGF0IHNob3VsZCBzZW5kIGFuIEVUYWcKCSAqCgkgKiBAbGluayBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTc4OQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhdGNoKCR1cmwsICRoZWFkZXJzLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiBzZWxmOjpyZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgc2VsZjo6UEFUQ0gsICRvcHRpb25zKTsKCX0KCS8qKiNALSovCgoJLyoqCgkgKiBNYWluIGludGVyZmFjZSBmb3IgSFRUUCByZXF1ZXN0cwoJICoKCSAqIFRoaXMgbWV0aG9kIGluaXRpYXRlcyBhIHJlcXVlc3QgYW5kIHNlbmRzIGl0IHZpYSBhIHRyYW5zcG9ydCBiZWZvcmUKCSAqIHBhcnNpbmcuCgkgKgoJICogVGhlIGAkb3B0aW9uc2AgcGFyYW1ldGVyIHRha2VzIGFuIGFzc29jaWF0aXZlIGFycmF5IHdpdGggdGhlIGZvbGxvd2luZwoJICogb3B0aW9uczoKCSAqCgkgKiAtIGB0aW1lb3V0YDogSG93IGxvbmcgc2hvdWxkIHdlIHdhaXQgZm9yIGEgcmVzcG9uc2U/CgkgKiAgICBOb3RlOiBmb3IgY1VSTCwgYSBtaW5pbXVtIG9mIDEgc2Vjb25kIGFwcGxpZXMsIGFzIEROUyByZXNvbHV0aW9uCgkgKiAgICBvcGVyYXRlcyBhdCBzZWNvbmQtcmVzb2x1dGlvbiBvbmx5LgoJICogICAgKGZsb2F0LCBzZWNvbmRzIHdpdGggYSBtaWxsaXNlY29uZCBwcmVjaXNpb24sIGRlZmF1bHQ6IDEwLCBleGFtcGxlOiAwLjAxKQoJICogLSBgY29ubmVjdF90aW1lb3V0YDogSG93IGxvbmcgc2hvdWxkIHdlIHdhaXQgd2hpbGUgdHJ5aW5nIHRvIGNvbm5lY3Q/CgkgKiAgICAoZmxvYXQsIHNlY29uZHMgd2l0aCBhIG1pbGxpc2Vjb25kIHByZWNpc2lvbiwgZGVmYXVsdDogMTAsIGV4YW1wbGU6IDAuMDEpCgkgKiAtIGB1c2VyYWdlbnRgOiBVc2VyYWdlbnQgdG8gc2VuZCB0byB0aGUgc2VydmVyCgkgKiAgICAoc3RyaW5nLCBkZWZhdWx0OiBwaHAtcmVxdWVzdHMvJHZlcnNpb24pCgkgKiAtIGBmb2xsb3dfcmVkaXJlY3RzYDogU2hvdWxkIHdlIGZvbGxvdyAzeHggcmVkaXJlY3RzPwoJICogICAgKGJvb2xlYW4sIGRlZmF1bHQ6IHRydWUpCgkgKiAtIGByZWRpcmVjdHNgOiBIb3cgbWFueSB0aW1lcyBzaG91bGQgd2UgcmVkaXJlY3QgYmVmb3JlIGVycm9yaW5nPwoJICogICAgKGludGVnZXIsIGRlZmF1bHQ6IDEwKQoJICogLSBgYmxvY2tpbmdgOiBTaG91bGQgd2UgYmxvY2sgcHJvY2Vzc2luZyBvbiB0aGlzIHJlcXVlc3Q/CgkgKiAgICAoYm9vbGVhbiwgZGVmYXVsdDogdHJ1ZSkKCSAqIC0gYGZpbGVuYW1lYDogRmlsZSB0byBzdHJlYW0gdGhlIGJvZHkgdG8gaW5zdGVhZC4KCSAqICAgIChzdHJpbmd8Ym9vbGVhbiwgZGVmYXVsdDogZmFsc2UpCgkgKiAtIGBhdXRoYDogQXV0aGVudGljYXRpb24gaGFuZGxlciBvciBhcnJheSBvZiB1c2VyL3Bhc3N3b3JkIGRldGFpbHMgdG8gdXNlCgkgKiAgICBmb3IgQmFzaWMgYXV0aGVudGljYXRpb24KCSAqICAgIChSZXF1ZXN0c19BdXRofGFycmF5fGJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlKQoJICogLSBgcHJveHlgOiBQcm94eSBkZXRhaWxzIHRvIHVzZSBmb3IgcHJveHkgYnktcGFzc2luZyBhbmQgYXV0aGVudGljYXRpb24KCSAqICAgIChSZXF1ZXN0c19Qcm94eXxhcnJheXxzdHJpbmd8Ym9vbGVhbiwgZGVmYXVsdDogZmFsc2UpCgkgKiAtIGBtYXhfYnl0ZXNgOiBMaW1pdCBmb3IgdGhlIHJlc3BvbnNlIGJvZHkgc2l6ZS4KCSAqICAgIChpbnRlZ2VyfGJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlKQoJICogLSBgaWRuYDogRW5hYmxlIElETiBwYXJzaW5nCgkgKiAgICAoYm9vbGVhbiwgZGVmYXVsdDogdHJ1ZSkKCSAqIC0gYHRyYW5zcG9ydGA6IEN1c3RvbSB0cmFuc3BvcnQuIEVpdGhlciBhIGNsYXNzIG5hbWUsIG9yIGEKCSAqICAgIHRyYW5zcG9ydCBvYmplY3QuIERlZmF1bHRzIHRvIHRoZSBmaXJzdCB3b3JraW5nIHRyYW5zcG9ydCBmcm9tCgkgKiAgICB7QHNlZSBnZXRUcmFuc3BvcnQoKX0KCSAqICAgIChzdHJpbmd8UmVxdWVzdHNfVHJhbnNwb3J0LCBkZWZhdWx0OiB7QHNlZSBnZXRUcmFuc3BvcnQoKX0pCgkgKiAtIGBob29rc2A6IEhvb2tzIGhhbmRsZXIuCgkgKiAgICAoUmVxdWVzdHNfSG9va2VyLCBkZWZhdWx0OiBuZXcgUmVxdWVzdHNfSG9va3MoKSkKCSAqIC0gYHZlcmlmeWA6IFNob3VsZCB3ZSB2ZXJpZnkgU1NMIGNlcnRpZmljYXRlcz8gQWxsb3dzIHBhc3NpbmcgaW4gYSBjdXN0b20KCSAqICAgIGNlcnRpZmljYXRlIGZpbGUgYXMgYSBzdHJpbmcuIChVc2luZyB0cnVlIHVzZXMgdGhlIHN5c3RlbS13aWRlIHJvb3QKCSAqICAgIGNlcnRpZmljYXRlIHN0b3JlIGluc3RlYWQsIGJ1dCB0aGlzIG1heSBoYXZlIGRpZmZlcmVudCBiZWhhdmlvdXIKCSAqICAgIGFjcm9zcyB0cmFuc3BvcnRzLikKCSAqICAgIChzdHJpbmd8Ym9vbGVhbiwgZGVmYXVsdDogbGlicmFyeS9SZXF1ZXN0cy9UcmFuc3BvcnQvY2FjZXJ0LnBlbSkKCSAqIC0gYHZlcmlmeW5hbWVgOiBTaG91bGQgd2UgdmVyaWZ5IHRoZSBjb21tb24gbmFtZSBpbiB0aGUgU1NMIGNlcnRpZmljYXRlPwoJICogICAgKGJvb2xlYW4sIGRlZmF1bHQ6IHRydWUpCgkgKiAtIGBkYXRhX2Zvcm1hdGA6IEhvdyBzaG91bGQgd2Ugc2VuZCB0aGUgYCRkYXRhYCBwYXJhbWV0ZXI/CgkgKiAgICAoc3RyaW5nLCBvbmUgb2YgJ3F1ZXJ5JyBvciAnYm9keScsIGRlZmF1bHQ6ICdxdWVyeScgZm9yCgkgKiAgICBIRUFEL0dFVC9ERUxFVEUsICdib2R5JyBmb3IgUE9TVC9QVVQvT1BUSU9OUy9QQVRDSCkKCSAqCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBpbnZhbGlkIFVSTHMgKGBub25odHRwYCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBFeHRyYSBoZWFkZXJzIHRvIHNlbmQgd2l0aCB0aGUgcmVxdWVzdAoJICogQHBhcmFtIGFycmF5fG51bGwgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyBhIHF1ZXJ5IHN0cmluZyBmb3IgR0VUL0hFQUQgcmVxdWVzdHMsIG9yIGluIHRoZSBib2R5IGZvciBQT1NUIHJlcXVlc3RzCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlIEhUVFAgcmVxdWVzdCB0eXBlICh1c2UgUmVxdWVzdHMgY29uc3RhbnRzKQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0IChzZWUgZGVzY3JpcHRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24pCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVxdWVzdCgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRkYXRhID0gYXJyYXkoKSwgJHR5cGUgPSBzZWxmOjpHRVQsICRvcHRpb25zID0gYXJyYXkoKSkgewoJCWlmIChlbXB0eSgkb3B0aW9uc1sndHlwZSddKSkgewoJCQkkb3B0aW9uc1sndHlwZSddID0gJHR5cGU7CgkJfQoJCSRvcHRpb25zID0gYXJyYXlfbWVyZ2Uoc2VsZjo6Z2V0X2RlZmF1bHRfb3B0aW9ucygpLCAkb3B0aW9ucyk7CgoJCXNlbGY6OnNldF9kZWZhdWx0cygkdXJsLCAkaGVhZGVycywgJGRhdGEsICR0eXBlLCAkb3B0aW9ucyk7CgoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgncmVxdWVzdHMuYmVmb3JlX3JlcXVlc3QnLCBhcnJheSgmJHVybCwgJiRoZWFkZXJzLCAmJGRhdGEsICYkdHlwZSwgJiRvcHRpb25zKSk7CgoJCWlmICghZW1wdHkoJG9wdGlvbnNbJ3RyYW5zcG9ydCddKSkgewoJCQkkdHJhbnNwb3J0ID0gJG9wdGlvbnNbJ3RyYW5zcG9ydCddOwoKCQkJaWYgKGlzX3N0cmluZygkb3B0aW9uc1sndHJhbnNwb3J0J10pKSB7CgkJCQkkdHJhbnNwb3J0ID0gbmV3ICR0cmFuc3BvcnQoKTsKCQkJfQoJCX0KCQllbHNlIHsKCQkJJG5lZWRfc3NsICAgICA9IChzdHJpcG9zKCR1cmwsICdodHRwczovLycpID09PSAwKTsKCQkJJGNhcGFiaWxpdGllcyA9IGFycmF5KCdzc2wnID0+ICRuZWVkX3NzbCk7CgkJCSR0cmFuc3BvcnQgICAgPSBzZWxmOjpnZXRfdHJhbnNwb3J0KCRjYXBhYmlsaXRpZXMpOwoJCX0KCQkkcmVzcG9uc2UgPSAkdHJhbnNwb3J0LT5yZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpOwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ3JlcXVlc3RzLmJlZm9yZV9wYXJzZScsIGFycmF5KCYkcmVzcG9uc2UsICR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJHR5cGUsICRvcHRpb25zKSk7CgoJCXJldHVybiBzZWxmOjpwYXJzZV9yZXNwb25zZSgkcmVzcG9uc2UsICR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpOwoJfQoKCS8qKgoJICogU2VuZCBtdWx0aXBsZSBIVFRQIHJlcXVlc3RzIHNpbXVsdGFuZW91c2x5CgkgKgoJICogVGhlIGAkcmVxdWVzdHNgIHBhcmFtZXRlciB0YWtlcyBhbiBhc3NvY2lhdGl2ZSBvciBpbmRleGVkIGFycmF5IG9mCgkgKiByZXF1ZXN0IGZpZWxkcy4gVGhlIGtleSBvZiBlYWNoIHJlcXVlc3QgY2FuIGJlIHVzZWQgdG8gbWF0Y2ggdXAgdGhlCgkgKiByZXF1ZXN0IHdpdGggdGhlIHJldHVybmVkIGRhdGEsIG9yIHdpdGggdGhlIHJlcXVlc3QgcGFzc2VkIGludG8geW91cgoJICogYG11bHRpcGxlLnJlcXVlc3QuY29tcGxldGVgIGNhbGxiYWNrLgoJICoKCSAqIFRoZSByZXF1ZXN0IGZpZWxkcyB2YWx1ZSBpcyBhbiBhc3NvY2lhdGl2ZSBhcnJheSB3aXRoIHRoZSBmb2xsb3dpbmcga2V5czoKCSAqCgkgKiAtIGB1cmxgOiBSZXF1ZXN0IFVSTCBTYW1lIGFzIHRoZSBgJHVybGAgcGFyYW1ldGVyIHRvCgkgKiAgICB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0KCSAqICAgIChzdHJpbmcsIHJlcXVpcmVkKQoJICogLSBgaGVhZGVyc2A6IEFzc29jaWF0aXZlIGFycmF5IG9mIGhlYWRlciBmaWVsZHMuIFNhbWUgYXMgdGhlIGAkaGVhZGVyc2AKCSAqICAgIHBhcmFtZXRlciB0byB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0KCSAqICAgIChhcnJheSwgZGVmYXVsdDogYGFycmF5KClgKQoJICogLSBgZGF0YWA6IEFzc29jaWF0aXZlIGFycmF5IG9mIGRhdGEgZmllbGRzIG9yIGEgc3RyaW5nLiBTYW1lIGFzIHRoZQoJICogICAgYCRkYXRhYCBwYXJhbWV0ZXIgdG8ge0BzZWUgUmVxdWVzdHM6OnJlcXVlc3R9CgkgKiAgICAoYXJyYXl8c3RyaW5nLCBkZWZhdWx0OiBgYXJyYXkoKWApCgkgKiAtIGB0eXBlYDogSFRUUCByZXF1ZXN0IHR5cGUgKHVzZSBSZXF1ZXN0cyBjb25zdGFudHMpLiBTYW1lIGFzIHRoZSBgJHR5cGVgCgkgKiAgICBwYXJhbWV0ZXIgdG8ge0BzZWUgUmVxdWVzdHM6OnJlcXVlc3R9CgkgKiAgICAoc3RyaW5nLCBkZWZhdWx0OiBgUmVxdWVzdHM6OkdFVGApCgkgKiAtIGBjb29raWVzYDogQXNzb2NpYXRpdmUgYXJyYXkgb2YgY29va2llIG5hbWUgdG8gdmFsdWUsIG9yIGNvb2tpZSBqYXIuCgkgKiAgICAoYXJyYXl8UmVxdWVzdHNfQ29va2llX0phcikKCSAqCgkgKiBJZiB0aGUgYCRvcHRpb25zYCBwYXJhbWV0ZXIgaXMgc3BlY2lmaWVkLCBpbmRpdmlkdWFsIHJlcXVlc3RzIHdpbGwKCSAqIGluaGVyaXQgb3B0aW9ucyBmcm9tIGl0LiBUaGlzIGNhbiBiZSB1c2VkIHRvIHVzZSBhIHNpbmdsZSBob29raW5nIHN5c3RlbSwKCSAqIG9yIHNldCBhbGwgdGhlIHR5cGVzIHRvIGBSZXF1ZXN0czo6UE9TVGAsIGZvciBleGFtcGxlLgoJICoKCSAqIEluIGFkZGl0aW9uLCB0aGUgYCRvcHRpb25zYCBwYXJhbWV0ZXIgdGFrZXMgdGhlIGZvbGxvd2luZyBnbG9iYWwgb3B0aW9uczoKCSAqCgkgKiAtIGBjb21wbGV0ZWA6IEEgY2FsbGJhY2sgZm9yIHdoZW4gYSByZXF1ZXN0IGlzIGNvbXBsZXRlLiBUYWtlcyB0d28KCSAqICAgIHBhcmFtZXRlcnMsIGEgUmVxdWVzdHNfUmVzcG9uc2UvUmVxdWVzdHNfRXhjZXB0aW9uIHJlZmVyZW5jZSwgYW5kIHRoZQoJICogICAgSUQgZnJvbSB0aGUgcmVxdWVzdCBhcnJheSAoTm90ZTogdGhpcyBjYW4gYWxzbyBiZSBvdmVycmlkZGVuIG9uIGEKCSAqICAgIHBlci1yZXF1ZXN0IGJhc2lzLCBhbHRob3VnaCB0aGF0J3MgYSBsaXR0bGUgc2lsbHkpCgkgKiAgICAoY2FsbGJhY2spCgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXF1ZXN0cyBSZXF1ZXN0cyBkYXRhIChzZWUgZGVzY3JpcHRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24pCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIGFuZCBkZWZhdWx0IG9wdGlvbnMgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0pCgkgKiBAcmV0dXJuIGFycmF5IFJlc3BvbnNlcyAoZWl0aGVyIFJlcXVlc3RzX1Jlc3BvbnNlIG9yIGEgUmVxdWVzdHNfRXhjZXB0aW9uIG9iamVjdCkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXF1ZXN0X211bHRpcGxlKCRyZXF1ZXN0cywgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJJG9wdGlvbnMgPSBhcnJheV9tZXJnZShzZWxmOjpnZXRfZGVmYXVsdF9vcHRpb25zKHRydWUpLCAkb3B0aW9ucyk7CgoJCWlmICghZW1wdHkoJG9wdGlvbnNbJ2hvb2tzJ10pKSB7CgkJCSRvcHRpb25zWydob29rcyddLT5yZWdpc3RlcigndHJhbnNwb3J0LmludGVybmFsLnBhcnNlX3Jlc3BvbnNlJywgYXJyYXkoJ1JlcXVlc3RzJywgJ3BhcnNlX211bHRpcGxlJykpOwoJCQlpZiAoIWVtcHR5KCRvcHRpb25zWydjb21wbGV0ZSddKSkgewoJCQkJJG9wdGlvbnNbJ2hvb2tzJ10tPnJlZ2lzdGVyKCdtdWx0aXBsZS5yZXF1ZXN0LmNvbXBsZXRlJywgJG9wdGlvbnNbJ2NvbXBsZXRlJ10pOwoJCQl9CgkJfQoKCQlmb3JlYWNoICgkcmVxdWVzdHMgYXMgJGlkID0+ICYkcmVxdWVzdCkgewoJCQlpZiAoIWlzc2V0KCRyZXF1ZXN0WydoZWFkZXJzJ10pKSB7CgkJCQkkcmVxdWVzdFsnaGVhZGVycyddID0gYXJyYXkoKTsKCQkJfQoJCQlpZiAoIWlzc2V0KCRyZXF1ZXN0WydkYXRhJ10pKSB7CgkJCQkkcmVxdWVzdFsnZGF0YSddID0gYXJyYXkoKTsKCQkJfQoJCQlpZiAoIWlzc2V0KCRyZXF1ZXN0Wyd0eXBlJ10pKSB7CgkJCQkkcmVxdWVzdFsndHlwZSddID0gc2VsZjo6R0VUOwoJCQl9CgkJCWlmICghaXNzZXQoJHJlcXVlc3RbJ29wdGlvbnMnXSkpIHsKCQkJCSRyZXF1ZXN0WydvcHRpb25zJ10gICAgICAgICA9ICRvcHRpb25zOwoJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsndHlwZSddID0gJHJlcXVlc3RbJ3R5cGUnXTsKCQkJfQoJCQllbHNlIHsKCQkJCWlmIChlbXB0eSgkcmVxdWVzdFsnb3B0aW9ucyddWyd0eXBlJ10pKSB7CgkJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsndHlwZSddID0gJHJlcXVlc3RbJ3R5cGUnXTsKCQkJCX0KCQkJCSRyZXF1ZXN0WydvcHRpb25zJ10gPSBhcnJheV9tZXJnZSgkb3B0aW9ucywgJHJlcXVlc3RbJ29wdGlvbnMnXSk7CgkJCX0KCgkJCXNlbGY6OnNldF9kZWZhdWx0cygkcmVxdWVzdFsndXJsJ10sICRyZXF1ZXN0WydoZWFkZXJzJ10sICRyZXF1ZXN0WydkYXRhJ10sICRyZXF1ZXN0Wyd0eXBlJ10sICRyZXF1ZXN0WydvcHRpb25zJ10pOwoKCQkJLy8gRW5zdXJlIHdlIG9ubHkgaG9vayBpbiBvbmNlCgkJCWlmICgkcmVxdWVzdFsnb3B0aW9ucyddWydob29rcyddICE9PSAkb3B0aW9uc1snaG9va3MnXSkgewoJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+cmVnaXN0ZXIoJ3RyYW5zcG9ydC5pbnRlcm5hbC5wYXJzZV9yZXNwb25zZScsIGFycmF5KCdSZXF1ZXN0cycsICdwYXJzZV9tdWx0aXBsZScpKTsKCQkJCWlmICghZW1wdHkoJHJlcXVlc3RbJ29wdGlvbnMnXVsnY29tcGxldGUnXSkpIHsKCQkJCQkkcmVxdWVzdFsnb3B0aW9ucyddWydob29rcyddLT5yZWdpc3RlcignbXVsdGlwbGUucmVxdWVzdC5jb21wbGV0ZScsICRyZXF1ZXN0WydvcHRpb25zJ11bJ2NvbXBsZXRlJ10pOwoJCQkJfQoJCQl9CgkJfQoJCXVuc2V0KCRyZXF1ZXN0KTsKCgkJaWYgKCFlbXB0eSgkb3B0aW9uc1sndHJhbnNwb3J0J10pKSB7CgkJCSR0cmFuc3BvcnQgPSAkb3B0aW9uc1sndHJhbnNwb3J0J107CgoJCQlpZiAoaXNfc3RyaW5nKCRvcHRpb25zWyd0cmFuc3BvcnQnXSkpIHsKCQkJCSR0cmFuc3BvcnQgPSBuZXcgJHRyYW5zcG9ydCgpOwoJCQl9CgkJfQoJCWVsc2UgewoJCQkkdHJhbnNwb3J0ID0gc2VsZjo6Z2V0X3RyYW5zcG9ydCgpOwoJCX0KCQkkcmVzcG9uc2VzID0gJHRyYW5zcG9ydC0+cmVxdWVzdF9tdWx0aXBsZSgkcmVxdWVzdHMsICRvcHRpb25zKTsKCgkJZm9yZWFjaCAoJHJlc3BvbnNlcyBhcyAkaWQgPT4gJiRyZXNwb25zZSkgewoJCQkvLyBJZiBvdXIgaG9vayBnb3QgbWVzc2VkIHdpdGggc29tZWhvdywgZW5zdXJlIHdlIGVuZCB1cCB3aXRoIHRoZQoJCQkvLyBjb3JyZWN0IHJlc3BvbnNlCgkJCWlmIChpc19zdHJpbmcoJHJlc3BvbnNlKSkgewoJCQkJJHJlcXVlc3QgPSAkcmVxdWVzdHNbJGlkXTsKCQkJCXNlbGY6OnBhcnNlX211bHRpcGxlKCRyZXNwb25zZSwgJHJlcXVlc3QpOwoJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ211bHRpcGxlLnJlcXVlc3QuY29tcGxldGUnLCBhcnJheSgmJHJlc3BvbnNlLCAkaWQpKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRyZXNwb25zZXM7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGRlZmF1bHQgb3B0aW9ucwoJICoKCSAqIEBzZWUgUmVxdWVzdHM6OnJlcXVlc3QoKSBmb3IgdmFsdWVzIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kCgkgKiBAcGFyYW0gYm9vbGVhbiAkbXVsdGlyZXF1ZXN0IElzIHRoaXMgYSBtdWx0aXJlcXVlc3Q/CgkgKiBAcmV0dXJuIGFycmF5IERlZmF1bHQgb3B0aW9uIHZhbHVlcwoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9kZWZhdWx0X29wdGlvbnMoJG11bHRpcmVxdWVzdCA9IGZhbHNlKSB7CgkJJGRlZmF1bHRzID0gYXJyYXkoCgkJCSd0aW1lb3V0JyAgICAgICAgICA9PiAxMCwKCQkJJ2Nvbm5lY3RfdGltZW91dCcgID0+IDEwLAoJCQkndXNlcmFnZW50JyAgICAgICAgPT4gJ3BocC1yZXF1ZXN0cy8nIC4gc2VsZjo6VkVSU0lPTiwKCQkJJ3Byb3RvY29sX3ZlcnNpb24nID0+IDEuMSwKCQkJJ3JlZGlyZWN0ZWQnICAgICAgID0+IDAsCgkJCSdyZWRpcmVjdHMnICAgICAgICA9PiAxMCwKCQkJJ2ZvbGxvd19yZWRpcmVjdHMnID0+IHRydWUsCgkJCSdibG9ja2luZycgICAgICAgICA9PiB0cnVlLAoJCQkndHlwZScgICAgICAgICAgICAgPT4gc2VsZjo6R0VULAoJCQknZmlsZW5hbWUnICAgICAgICAgPT4gZmFsc2UsCgkJCSdhdXRoJyAgICAgICAgICAgICA9PiBmYWxzZSwKCQkJJ3Byb3h5JyAgICAgICAgICAgID0+IGZhbHNlLAoJCQknY29va2llcycgICAgICAgICAgPT4gZmFsc2UsCgkJCSdtYXhfYnl0ZXMnICAgICAgICA9PiBmYWxzZSwKCQkJJ2lkbicgICAgICAgICAgICAgID0+IHRydWUsCgkJCSdob29rcycgICAgICAgICAgICA9PiBudWxsLAoJCQkndHJhbnNwb3J0JyAgICAgICAgPT4gbnVsbCwKCQkJJ3ZlcmlmeScgICAgICAgICAgID0+IHNlbGY6OmdldF9jZXJ0aWZpY2F0ZV9wYXRoKCksCgkJCSd2ZXJpZnluYW1lJyAgICAgICA9PiB0cnVlLAoJCSk7CgkJaWYgKCRtdWx0aXJlcXVlc3QgIT09IGZhbHNlKSB7CgkJCSRkZWZhdWx0c1snY29tcGxldGUnXSA9IG51bGw7CgkJfQoJCXJldHVybiAkZGVmYXVsdHM7Cgl9CgoJLyoqCgkgKiBHZXQgZGVmYXVsdCBjZXJ0aWZpY2F0ZSBwYXRoLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIERlZmF1bHQgY2VydGlmaWNhdGUgcGF0aC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRfY2VydGlmaWNhdGVfcGF0aCgpIHsKCQlpZiAoIWVtcHR5KHNlbGY6OiRjZXJ0aWZpY2F0ZV9wYXRoKSkgewoJCQlyZXR1cm4gc2VsZjo6JGNlcnRpZmljYXRlX3BhdGg7CgkJfQoKCQlyZXR1cm4gZGlybmFtZShfX0ZJTEVfXykgLiAnL1JlcXVlc3RzL1RyYW5zcG9ydC9jYWNlcnQucGVtJzsKCX0KCgkvKioKCSAqIFNldCBkZWZhdWx0IGNlcnRpZmljYXRlIHBhdGguCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBDZXJ0aWZpY2F0ZSBwYXRoLCBwb2ludGluZyB0byBhIFBFTSBmaWxlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldF9jZXJ0aWZpY2F0ZV9wYXRoKCRwYXRoKSB7CgkJc2VsZjo6JGNlcnRpZmljYXRlX3BhdGggPSAkcGF0aDsKCX0KCgkvKioKCSAqIFNldCB0aGUgZGVmYXVsdCB2YWx1ZXMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBFeHRyYSBoZWFkZXJzIHRvIHNlbmQgd2l0aCB0aGUgcmVxdWVzdAoJICogQHBhcmFtIGFycmF5fG51bGwgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyBhIHF1ZXJ5IHN0cmluZyBmb3IgR0VUL0hFQUQgcmVxdWVzdHMsIG9yIGluIHRoZSBib2R5IGZvciBQT1NUIHJlcXVlc3RzCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlIEhUVFAgcmVxdWVzdCB0eXBlCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3QKCSAqIEByZXR1cm4gYXJyYXkgJG9wdGlvbnMKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzZXRfZGVmYXVsdHMoJiR1cmwsICYkaGVhZGVycywgJiRkYXRhLCAmJHR5cGUsICYkb3B0aW9ucykgewoJCWlmICghcHJlZ19tYXRjaCgnL15odHRwKHMpPzpcL1wvL2knLCAkdXJsLCAkbWF0Y2hlcykpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignT25seSBIVFRQKFMpIHJlcXVlc3RzIGFyZSBoYW5kbGVkLicsICdub25odHRwJywgJHVybCk7CgkJfQoKCQlpZiAoZW1wdHkoJG9wdGlvbnNbJ2hvb2tzJ10pKSB7CgkJCSRvcHRpb25zWydob29rcyddID0gbmV3IFJlcXVlc3RzX0hvb2tzKCk7CgkJfQoKCQlpZiAoaXNfYXJyYXkoJG9wdGlvbnNbJ2F1dGgnXSkpIHsKCQkJJG9wdGlvbnNbJ2F1dGgnXSA9IG5ldyBSZXF1ZXN0c19BdXRoX0Jhc2ljKCRvcHRpb25zWydhdXRoJ10pOwoJCX0KCQlpZiAoJG9wdGlvbnNbJ2F1dGgnXSAhPT0gZmFsc2UpIHsKCQkJJG9wdGlvbnNbJ2F1dGgnXS0+cmVnaXN0ZXIoJG9wdGlvbnNbJ2hvb2tzJ10pOwoJCX0KCgkJaWYgKGlzX3N0cmluZygkb3B0aW9uc1sncHJveHknXSkgfHwgaXNfYXJyYXkoJG9wdGlvbnNbJ3Byb3h5J10pKSB7CgkJCSRvcHRpb25zWydwcm94eSddID0gbmV3IFJlcXVlc3RzX1Byb3h5X0hUVFAoJG9wdGlvbnNbJ3Byb3h5J10pOwoJCX0KCQlpZiAoJG9wdGlvbnNbJ3Byb3h5J10gIT09IGZhbHNlKSB7CgkJCSRvcHRpb25zWydwcm94eSddLT5yZWdpc3Rlcigkb3B0aW9uc1snaG9va3MnXSk7CgkJfQoKCQlpZiAoaXNfYXJyYXkoJG9wdGlvbnNbJ2Nvb2tpZXMnXSkpIHsKCQkJJG9wdGlvbnNbJ2Nvb2tpZXMnXSA9IG5ldyBSZXF1ZXN0c19Db29raWVfSmFyKCRvcHRpb25zWydjb29raWVzJ10pOwoJCX0KCQllbHNlaWYgKGVtcHR5KCRvcHRpb25zWydjb29raWVzJ10pKSB7CgkJCSRvcHRpb25zWydjb29raWVzJ10gPSBuZXcgUmVxdWVzdHNfQ29va2llX0phcigpOwoJCX0KCQlpZiAoJG9wdGlvbnNbJ2Nvb2tpZXMnXSAhPT0gZmFsc2UpIHsKCQkJJG9wdGlvbnNbJ2Nvb2tpZXMnXS0+cmVnaXN0ZXIoJG9wdGlvbnNbJ2hvb2tzJ10pOwoJCX0KCgkJaWYgKCRvcHRpb25zWydpZG4nXSAhPT0gZmFsc2UpIHsKCQkJJGlyaSAgICAgICA9IG5ldyBSZXF1ZXN0c19JUkkoJHVybCk7CgkJCSRpcmktPmhvc3QgPSBSZXF1ZXN0c19JRE5BRW5jb2Rlcjo6ZW5jb2RlKCRpcmktPmlob3N0KTsKCQkJJHVybCAgICAgICA9ICRpcmktPnVyaTsKCQl9CgoJCS8vIE1hc3NhZ2UgdGhlIHR5cGUgdG8gZW5zdXJlIHdlIHN1cHBvcnQgaXQuCgkJJHR5cGUgPSBzdHJ0b3VwcGVyKCR0eXBlKTsKCgkJaWYgKCFpc3NldCgkb3B0aW9uc1snZGF0YV9mb3JtYXQnXSkpIHsKCQkJaWYgKGluX2FycmF5KCR0eXBlLCBhcnJheShzZWxmOjpIRUFELCBzZWxmOjpHRVQsIHNlbGY6OkRFTEVURSksIHRydWUpKSB7CgkJCQkkb3B0aW9uc1snZGF0YV9mb3JtYXQnXSA9ICdxdWVyeSc7CgkJCX0KCQkJZWxzZSB7CgkJCQkkb3B0aW9uc1snZGF0YV9mb3JtYXQnXSA9ICdib2R5JzsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEhUVFAgcmVzcG9uc2UgcGFyc2VyCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gbWlzc2luZyBoZWFkL2JvZHkgc2VwYXJhdG9yIChgcmVxdWVzdHMubm9fY3JsZl9zZXBhcmF0b3JgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gbWlzc2luZyBoZWFkL2JvZHkgc2VwYXJhdG9yIChgbm92ZXJzaW9uYCkKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIG1pc3NpbmcgaGVhZC9ib2R5IHNlcGFyYXRvciAoYHRvb21hbnlyZWRpcmVjdHNgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGhlYWRlcnMgRnVsbCByZXNwb25zZSB0ZXh0IGluY2x1ZGluZyBoZWFkZXJzIGFuZCBib2R5CgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgT3JpZ2luYWwgcmVxdWVzdCBVUkwKCSAqIEBwYXJhbSBhcnJheSAkcmVxX2hlYWRlcnMgT3JpZ2luYWwgJGhlYWRlcnMgYXJyYXkgcGFzc2VkIHRvIHtAbGluayByZXF1ZXN0KCl9LCBpbiBjYXNlIHdlIG5lZWQgdG8gZm9sbG93IHJlZGlyZWN0cwoJICogQHBhcmFtIGFycmF5ICRyZXFfZGF0YSBPcmlnaW5hbCAkZGF0YSBhcnJheSBwYXNzZWQgdG8ge0BsaW5rIHJlcXVlc3QoKX0sIGluIGNhc2Ugd2UgbmVlZCB0byBmb2xsb3cgcmVkaXJlY3RzCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgT3JpZ2luYWwgJG9wdGlvbnMgYXJyYXkgcGFzc2VkIHRvIHtAbGluayByZXF1ZXN0KCl9LCBpbiBjYXNlIHdlIG5lZWQgdG8gZm9sbG93IHJlZGlyZWN0cwoJICogQHJldHVybiBSZXF1ZXN0c19SZXNwb25zZQoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHBhcnNlX3Jlc3BvbnNlKCRoZWFkZXJzLCAkdXJsLCAkcmVxX2hlYWRlcnMsICRyZXFfZGF0YSwgJG9wdGlvbnMpIHsKCQkkcmV0dXJuID0gbmV3IFJlcXVlc3RzX1Jlc3BvbnNlKCk7CgkJaWYgKCEkb3B0aW9uc1snYmxvY2tpbmcnXSkgewoJCQlyZXR1cm4gJHJldHVybjsKCQl9CgoJCSRyZXR1cm4tPnJhdyAgPSAkaGVhZGVyczsKCQkkcmV0dXJuLT51cmwgID0gKHN0cmluZykgJHVybDsKCQkkcmV0dXJuLT5ib2R5ID0gJyc7CgoJCWlmICghJG9wdGlvbnNbJ2ZpbGVuYW1lJ10pIHsKCQkJJHBvcyA9IHN0cnBvcygkaGVhZGVycywgIlxyXG5cclxuIik7CgkJCWlmICgkcG9zID09PSBmYWxzZSkgewoJCQkJLy8gQ3JhcCEKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ01pc3NpbmcgaGVhZGVyL2JvZHkgc2VwYXJhdG9yJywgJ3JlcXVlc3RzLm5vX2NybGZfc2VwYXJhdG9yJyk7CgkJCX0KCgkJCSRoZWFkZXJzID0gc3Vic3RyKCRyZXR1cm4tPnJhdywgMCwgJHBvcyk7CgkJCS8vIEhlYWRlcnMgd2lsbCBhbHdheXMgYmUgc2VwYXJhdGVkIGZyb20gdGhlIGJvZHkgYnkgdHdvIG5ldyBsaW5lcyAtIGBcblxyXG5ccmAuCgkJCSRib2R5ID0gc3Vic3RyKCRyZXR1cm4tPnJhdywgJHBvcyArIDQpOwoJCQlpZiAoIWVtcHR5KCRib2R5KSkgewoJCQkJJHJldHVybi0+Ym9keSA9ICRib2R5OwoJCQl9CgkJfQoJCS8vIFByZXRlbmQgQ1JMRiA9IExGIGZvciBjb21wYXRpYmlsaXR5IChSRkMgMjYxNiwgc2VjdGlvbiAxOS4zKQoJCSRoZWFkZXJzID0gc3RyX3JlcGxhY2UoIlxyXG4iLCAiXG4iLCAkaGVhZGVycyk7CgkJLy8gVW5mb2xkIGhlYWRlcnMgKHJlcGxhY2UgW0NSTEZdIDEqKCBTUCB8IEhUICkgd2l0aCBTUCkgYXMgcGVyIFJGQyAyNjE2IChzZWN0aW9uIDIuMikKCQkkaGVhZGVycyA9IHByZWdfcmVwbGFjZSgnL1xuWyBcdF0vJywgJyAnLCAkaGVhZGVycyk7CgkJJGhlYWRlcnMgPSBleHBsb2RlKCJcbiIsICRoZWFkZXJzKTsKCQlwcmVnX21hdGNoKCcjXkhUVFAvKDFcLlxkKVsgXHRdKyhcZCspI2knLCBhcnJheV9zaGlmdCgkaGVhZGVycyksICRtYXRjaGVzKTsKCQlpZiAoZW1wdHkoJG1hdGNoZXMpKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ1Jlc3BvbnNlIGNvdWxkIG5vdCBiZSBwYXJzZWQnLCAnbm92ZXJzaW9uJywgJGhlYWRlcnMpOwoJCX0KCQkkcmV0dXJuLT5wcm90b2NvbF92ZXJzaW9uID0gKGZsb2F0KSAkbWF0Y2hlc1sxXTsKCQkkcmV0dXJuLT5zdGF0dXNfY29kZSAgICAgID0gKGludCkgJG1hdGNoZXNbMl07CgkJaWYgKCRyZXR1cm4tPnN0YXR1c19jb2RlID49IDIwMCAmJiAkcmV0dXJuLT5zdGF0dXNfY29kZSA8IDMwMCkgewoJCQkkcmV0dXJuLT5zdWNjZXNzID0gdHJ1ZTsKCQl9CgoJCWZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKCQkJbGlzdCgka2V5LCAkdmFsdWUpID0gZXhwbG9kZSgnOicsICRoZWFkZXIsIDIpOwoJCQkkdmFsdWUgICAgICAgICAgICAgPSB0cmltKCR2YWx1ZSk7CgkJCXByZWdfcmVwbGFjZSgnIyhccyspI2knLCAnICcsICR2YWx1ZSk7CgkJCSRyZXR1cm4tPmhlYWRlcnNbJGtleV0gPSAkdmFsdWU7CgkJfQoJCWlmIChpc3NldCgkcmV0dXJuLT5oZWFkZXJzWyd0cmFuc2Zlci1lbmNvZGluZyddKSkgewoJCQkkcmV0dXJuLT5ib2R5ID0gc2VsZjo6ZGVjb2RlX2NodW5rZWQoJHJldHVybi0+Ym9keSk7CgkJCXVuc2V0KCRyZXR1cm4tPmhlYWRlcnNbJ3RyYW5zZmVyLWVuY29kaW5nJ10pOwoJCX0KCQlpZiAoaXNzZXQoJHJldHVybi0+aGVhZGVyc1snY29udGVudC1lbmNvZGluZyddKSkgewoJCQkkcmV0dXJuLT5ib2R5ID0gc2VsZjo6ZGVjb21wcmVzcygkcmV0dXJuLT5ib2R5KTsKCQl9CgoJCS8vZnNvY2tvcGVuIGFuZCBjVVJMIGNvbXBhdGliaWxpdHkKCQlpZiAoaXNzZXQoJHJldHVybi0+aGVhZGVyc1snY29ubmVjdGlvbiddKSkgewoJCQl1bnNldCgkcmV0dXJuLT5oZWFkZXJzWydjb25uZWN0aW9uJ10pOwoJCX0KCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdyZXF1ZXN0cy5iZWZvcmVfcmVkaXJlY3RfY2hlY2snLCBhcnJheSgmJHJldHVybiwgJHJlcV9oZWFkZXJzLCAkcmVxX2RhdGEsICRvcHRpb25zKSk7CgoJCWlmICgkcmV0dXJuLT5pc19yZWRpcmVjdCgpICYmICRvcHRpb25zWydmb2xsb3dfcmVkaXJlY3RzJ10gPT09IHRydWUpIHsKCQkJaWYgKGlzc2V0KCRyZXR1cm4tPmhlYWRlcnNbJ2xvY2F0aW9uJ10pICYmICRvcHRpb25zWydyZWRpcmVjdGVkJ10gPCAkb3B0aW9uc1sncmVkaXJlY3RzJ10pIHsKCQkJCWlmICgkcmV0dXJuLT5zdGF0dXNfY29kZSA9PT0gMzAzKSB7CgkJCQkJJG9wdGlvbnNbJ3R5cGUnXSA9IHNlbGY6OkdFVDsKCQkJCX0KCQkJCSRvcHRpb25zWydyZWRpcmVjdGVkJ10rKzsKCQkJCSRsb2NhdGlvbiA9ICRyZXR1cm4tPmhlYWRlcnNbJ2xvY2F0aW9uJ107CgkJCQlpZiAoc3RycG9zKCRsb2NhdGlvbiwgJ2h0dHA6Ly8nKSAhPT0gMCAmJiBzdHJwb3MoJGxvY2F0aW9uLCAnaHR0cHM6Ly8nKSAhPT0gMCkgewoJCQkJCS8vIHJlbGF0aXZlIHJlZGlyZWN0LCBmb3IgY29tcGF0aWJpbGl0eSBtYWtlIGl0IGFic29sdXRlCgkJCQkJJGxvY2F0aW9uID0gUmVxdWVzdHNfSVJJOjphYnNvbHV0aXplKCR1cmwsICRsb2NhdGlvbik7CgkJCQkJJGxvY2F0aW9uID0gJGxvY2F0aW9uLT51cmk7CgkJCQl9CgoJCQkJJGhvb2tfYXJncyA9IGFycmF5KAoJCQkJCSYkbG9jYXRpb24sCgkJCQkJJiRyZXFfaGVhZGVycywKCQkJCQkmJHJlcV9kYXRhLAoJCQkJCSYkb3B0aW9ucywKCQkJCQkkcmV0dXJuLAoJCQkJKTsKCQkJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgncmVxdWVzdHMuYmVmb3JlX3JlZGlyZWN0JywgJGhvb2tfYXJncyk7CgkJCQkkcmVkaXJlY3RlZCAgICAgICAgICAgID0gc2VsZjo6cmVxdWVzdCgkbG9jYXRpb24sICRyZXFfaGVhZGVycywgJHJlcV9kYXRhLCAkb3B0aW9uc1sndHlwZSddLCAkb3B0aW9ucyk7CgkJCQkkcmVkaXJlY3RlZC0+aGlzdG9yeVtdID0gJHJldHVybjsKCQkJCXJldHVybiAkcmVkaXJlY3RlZDsKCQkJfQoJCQllbHNlaWYgKCRvcHRpb25zWydyZWRpcmVjdGVkJ10gPj0gJG9wdGlvbnNbJ3JlZGlyZWN0cyddKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdUb28gbWFueSByZWRpcmVjdHMnLCAndG9vbWFueXJlZGlyZWN0cycsICRyZXR1cm4pOwoJCQl9CgkJfQoKCQkkcmV0dXJuLT5yZWRpcmVjdHMgPSAkb3B0aW9uc1sncmVkaXJlY3RlZCddOwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ3JlcXVlc3RzLmFmdGVyX3JlcXVlc3QnLCBhcnJheSgmJHJldHVybiwgJHJlcV9oZWFkZXJzLCAkcmVxX2RhdGEsICRvcHRpb25zKSk7CgkJcmV0dXJuICRyZXR1cm47Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmb3IgYHRyYW5zcG9ydC5pbnRlcm5hbC5wYXJzZV9yZXNwb25zZWAKCSAqCgkgKiBJbnRlcm5hbCB1c2Ugb25seS4gQ29udmVydHMgYSByYXcgSFRUUCByZXNwb25zZSB0byBhIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKiB3aGlsZSBzdGlsbCBleGVjdXRpbmcgYSBtdWx0aXBsZSByZXF1ZXN0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHJlc3BvbnNlIEZ1bGwgcmVzcG9uc2UgdGV4dCBpbmNsdWRpbmcgaGVhZGVycyBhbmQgYm9keSAod2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIFJlc3BvbnNlIGluc3RhbmNlKQoJICogQHBhcmFtIGFycmF5ICRyZXF1ZXN0IFJlcXVlc3QgZGF0YSBhcyBwYXNzZWQgaW50byB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdF9tdWx0aXBsZSgpfQoJICogQHJldHVybiBudWxsIGAkcmVzcG9uc2VgIGlzIGVpdGhlciBzZXQgdG8gYSBSZXF1ZXN0c19SZXNwb25zZSBpbnN0YW5jZSwgb3IgYSBSZXF1ZXN0c19FeGNlcHRpb24gb2JqZWN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFyc2VfbXVsdGlwbGUoJiRyZXNwb25zZSwgJHJlcXVlc3QpIHsKCQl0cnkgewoJCQkkdXJsICAgICAgPSAkcmVxdWVzdFsndXJsJ107CgkJCSRoZWFkZXJzICA9ICRyZXF1ZXN0WydoZWFkZXJzJ107CgkJCSRkYXRhICAgICA9ICRyZXF1ZXN0WydkYXRhJ107CgkJCSRvcHRpb25zICA9ICRyZXF1ZXN0WydvcHRpb25zJ107CgkJCSRyZXNwb25zZSA9IHNlbGY6OnBhcnNlX3Jlc3BvbnNlKCRyZXNwb25zZSwgJHVybCwgJGhlYWRlcnMsICRkYXRhLCAkb3B0aW9ucyk7CgkJfQoJCWNhdGNoIChSZXF1ZXN0c19FeGNlcHRpb24gJGUpIHsKCQkJJHJlc3BvbnNlID0gJGU7CgkJfQoJfQoKCS8qKgoJICogRGVjb2RlZCBhIGNodW5rZWQgYm9keSBhcyBwZXIgUkZDIDI2MTYKCSAqCgkgKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyNjE2I3NlY3Rpb24tMy42LjEKCSAqIEBwYXJhbSBzdHJpbmcgJGRhdGEgQ2h1bmtlZCBib2R5CgkgKiBAcmV0dXJuIHN0cmluZyBEZWNvZGVkIGJvZHkKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBkZWNvZGVfY2h1bmtlZCgkZGF0YSkgewoJCWlmICghcHJlZ19tYXRjaCgnL14oWzAtOWEtZl0rKSg/OjsoPzpbXHctXSopKD86PSg/Oig/Oltcdy1dKikqfCIoPzpbXlxyXG5dKSoiKSk/KSpcclxuL2knLCB0cmltKCRkYXRhKSkpIHsKCQkJcmV0dXJuICRkYXRhOwoJCX0KCgkJJGRlY29kZWQgPSAnJzsKCQkkZW5jb2RlZCA9ICRkYXRhOwoKCQl3aGlsZSAodHJ1ZSkgewoJCQkkaXNfY2h1bmtlZCA9IChib29sKSBwcmVnX21hdGNoKCcvXihbMC05YS1mXSspKD86Oyg/Oltcdy1dKikoPzo9KD86KD86W1x3LV0qKSp8Iig/OlteXHJcbl0pKiIpKT8pKlxyXG4vaScsICRlbmNvZGVkLCAkbWF0Y2hlcyk7CgkJCWlmICghJGlzX2NodW5rZWQpIHsKCQkJCS8vIExvb2tzIGxpa2UgaXQncyBub3QgY2h1bmtlZCBhZnRlciBhbGwKCQkJCXJldHVybiAkZGF0YTsKCQkJfQoKCQkJJGxlbmd0aCA9IGhleGRlYyh0cmltKCRtYXRjaGVzWzFdKSk7CgkJCWlmICgkbGVuZ3RoID09PSAwKSB7CgkJCQkvLyBJZ25vcmUgdHJhaWxlciBoZWFkZXJzCgkJCQlyZXR1cm4gJGRlY29kZWQ7CgkJCX0KCgkJCSRjaHVua19sZW5ndGggPSBzdHJsZW4oJG1hdGNoZXNbMF0pOwoJCQkkZGVjb2RlZCAgICAgLj0gc3Vic3RyKCRlbmNvZGVkLCAkY2h1bmtfbGVuZ3RoLCAkbGVuZ3RoKTsKCQkJJGVuY29kZWQgICAgICA9IHN1YnN0cigkZW5jb2RlZCwgJGNodW5rX2xlbmd0aCArICRsZW5ndGggKyAyKTsKCgkJCWlmICh0cmltKCRlbmNvZGVkKSA9PT0gJzAnIHx8IGVtcHR5KCRlbmNvZGVkKSkgewoJCQkJcmV0dXJuICRkZWNvZGVkOwoJCQl9CgkJfQoKCQkvLyBXZSdsbCBuZXZlciBhY3R1YWxseSBnZXQgZG93biBoZXJlCgkJLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZVN0YXJ0Cgl9CgkvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCgoJLyoqCgkgKiBDb252ZXJ0IGEga2V5ID0+IHZhbHVlIGFycmF5IHRvIGEgJ2tleTogdmFsdWUnIGFycmF5IGZvciBoZWFkZXJzCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcnJheSBEaWN0aW9uYXJ5IG9mIGhlYWRlciB2YWx1ZXMKCSAqIEByZXR1cm4gYXJyYXkgTGlzdCBvZiBoZWFkZXJzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZmxhdHRlbigkYXJyYXkpIHsKCQkkcmV0dXJuID0gYXJyYXkoKTsKCQlmb3JlYWNoICgkYXJyYXkgYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJJHJldHVybltdID0gc3ByaW50ZignJXM6ICVzJywgJGtleSwgJHZhbHVlKTsKCQl9CgkJcmV0dXJuICRyZXR1cm47Cgl9CgoJLyoqCgkgKiBDb252ZXJ0IGEga2V5ID0+IHZhbHVlIGFycmF5IHRvIGEgJ2tleTogdmFsdWUnIGFycmF5IGZvciBoZWFkZXJzCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgTWlzc3BlbGxpbmcgb2Yge0BzZWUgUmVxdWVzdHM6OmZsYXR0ZW59CgkgKiBAcGFyYW0gYXJyYXkgJGFycmF5IERpY3Rpb25hcnkgb2YgaGVhZGVyIHZhbHVlcwoJICogQHJldHVybiBhcnJheSBMaXN0IG9mIGhlYWRlcnMKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmbGF0dGVybigkYXJyYXkpIHsKCQlyZXR1cm4gc2VsZjo6ZmxhdHRlbigkYXJyYXkpOwoJfQoKCS8qKgoJICogRGVjb21wcmVzcyBhbiBlbmNvZGVkIGJvZHkKCSAqCgkgKiBJbXBsZW1lbnRzIGd6aXAsIGNvbXByZXNzIGFuZCBkZWZsYXRlLiBHdWVzc2VzIHdoaWNoIGl0IGlzIGJ5IGF0dGVtcHRpbmcKCSAqIHRvIGRlY29kZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkYXRhIENvbXByZXNzZWQgZGF0YSBpbiBvbmUgb2YgdGhlIGFib3ZlIGZvcm1hdHMKCSAqIEByZXR1cm4gc3RyaW5nIERlY29tcHJlc3NlZCBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZWNvbXByZXNzKCRkYXRhKSB7CgkJaWYgKHN1YnN0cigkZGF0YSwgMCwgMikgIT09ICJceDFmXHg4YiIgJiYgc3Vic3RyKCRkYXRhLCAwLCAyKSAhPT0gIlx4NzhceDljIikgewoJCQkvLyBOb3QgYWN0dWFsbHkgY29tcHJlc3NlZC4gUHJvYmFibHkgY1VSTCBydWluaW5nIHRoaXMgZm9yIHVzLgoJCQlyZXR1cm4gJGRhdGE7CgkJfQoKCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCdnemRlY29kZScpKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkZ1bmN0aW9uVXNlLk5ld0Z1bmN0aW9ucy5nemRlY29kZUZvdW5kIC0tIFdyYXBwZWQgaW4gZnVuY3Rpb25fZXhpc3RzKCkgZm9yIFBIUCA1LjIuCgkJCSRkZWNvZGVkID0gQGd6ZGVjb2RlKCRkYXRhKTsKCQkJaWYgKCRkZWNvZGVkICE9PSBmYWxzZSkgewoJCQkJcmV0dXJuICRkZWNvZGVkOwoJCQl9CgkJfQoKCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCdnemluZmxhdGUnKSkgewoJCQkkZGVjb2RlZCA9IEBnemluZmxhdGUoJGRhdGEpOwoJCQlpZiAoJGRlY29kZWQgIT09IGZhbHNlKSB7CgkJCQlyZXR1cm4gJGRlY29kZWQ7CgkJCX0KCQl9CgoJCSRkZWNvZGVkID0gc2VsZjo6Y29tcGF0aWJsZV9nemluZmxhdGUoJGRhdGEpOwoJCWlmICgkZGVjb2RlZCAhPT0gZmFsc2UpIHsKCQkJcmV0dXJuICRkZWNvZGVkOwoJCX0KCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnZ3p1bmNvbXByZXNzJykpIHsKCQkJJGRlY29kZWQgPSBAZ3p1bmNvbXByZXNzKCRkYXRhKTsKCQkJaWYgKCRkZWNvZGVkICE9PSBmYWxzZSkgewoJCQkJcmV0dXJuICRkZWNvZGVkOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGRhdGE7Cgl9CgoJLyoqCgkgKiBEZWNvbXByZXNzaW9uIG9mIGRlZmxhdGVkIHN0cmluZyB3aGlsZSBzdGF5aW5nIGNvbXBhdGlibGUgd2l0aCB0aGUgbWFqb3JpdHkgb2Ygc2VydmVycy4KCSAqCgkgKiBDZXJ0YWluIFNlcnZlcnMgd2lsbCByZXR1cm4gZGVmbGF0ZWQgZGF0YSB3aXRoIGhlYWRlcnMgd2hpY2ggUEhQJ3MgZ3ppbmZsYXRlKCkKCSAqIGZ1bmN0aW9uIGNhbm5vdCBoYW5kbGUgb3V0IG9mIHRoZSBib3guIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gaGFzIGJlZW4gY3JlYXRlZCBmcm9tCgkgKiB2YXJpb3VzIHNuaXBwZXRzIG9uIHRoZSBnemluZmxhdGUoKSBQSFAgZG9jdW1lbnRhdGlvbi4KCSAqCgkgKiBXYXJuaW5nOiBNYWdpYyBudW1iZXJzIHdpdGhpbi4gRHVlIHRvIHRoZSBwb3RlbnRpYWwgZGlmZmVyZW50IGZvcm1hdHMgdGhhdCB0aGUgY29tcHJlc3NlZAoJICogZGF0YSBtYXkgYmUgcmV0dXJuZWQgaW4sIHNvbWUgIm1hZ2ljIG9mZnNldHMiIGFyZSBuZWVkZWQgdG8gZW5zdXJlIHByb3BlciBkZWNvbXByZXNzaW9uCgkgKiB0YWtlcyBwbGFjZS4gRm9yIGEgc2ltcGxlIHByb2dtYXRpYyB3YXkgdG8gZGV0ZXJtaW5lIHRoZSBtYWdpYyBvZmZzZXQgaW4gdXNlLCBzZWU6CgkgKiBodHRwczovL2NvcmUudHJhYy53b3JkcHJlc3Mub3JnL3RpY2tldC8xODI3MwoJICoKCSAqIEBzaW5jZSAyLjguMQoJICogQGxpbmsgaHR0cHM6Ly9jb3JlLnRyYWMud29yZHByZXNzLm9yZy90aWNrZXQvMTgyNzMKCSAqIEBsaW5rIGh0dHBzOi8vc2VjdXJlLnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmd6aW5mbGF0ZS5waHAjNzA4NzUKCSAqIEBsaW5rIGh0dHBzOi8vc2VjdXJlLnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmd6aW5mbGF0ZS5waHAjNzczMzYKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRnel9kYXRhIFN0cmluZyB0byBkZWNvbXByZXNzLgoJICogQHJldHVybiBzdHJpbmd8Ym9vbCBGYWxzZSBvbiBmYWlsdXJlLgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbXBhdGlibGVfZ3ppbmZsYXRlKCRnel9kYXRhKSB7CgkJLy8gQ29tcHJlc3NlZCBkYXRhIG1pZ2h0IGNvbnRhaW4gYSBmdWxsIHpsaWIgaGVhZGVyLCBpZiBzbyBzdHJpcCBpdCBmb3IKCQkvLyBnemluZmxhdGUoKQoJCWlmIChzdWJzdHIoJGd6X2RhdGEsIDAsIDMpID09PSAiXHgxZlx4OGJceDA4IikgewoJCQkkaSAgID0gMTA7CgkJCSRmbGcgPSBvcmQoc3Vic3RyKCRnel9kYXRhLCAzLCAxKSk7CgkJCWlmICgkZmxnID4gMCkgewoJCQkJaWYgKCRmbGcgJiA0KSB7CgkJCQkJbGlzdCgkeGxlbikgPSB1bnBhY2soJ3YnLCBzdWJzdHIoJGd6X2RhdGEsICRpLCAyKSk7CgkJCQkJJGkgICAgICAgICArPSAyICsgJHhsZW47CgkJCQl9CgkJCQlpZiAoJGZsZyAmIDgpIHsKCQkJCQkkaSA9IHN0cnBvcygkZ3pfZGF0YSwgIlwwIiwgJGkpICsgMTsKCQkJCX0KCQkJCWlmICgkZmxnICYgMTYpIHsKCQkJCQkkaSA9IHN0cnBvcygkZ3pfZGF0YSwgIlwwIiwgJGkpICsgMTsKCQkJCX0KCQkJCWlmICgkZmxnICYgMikgewoJCQkJCSRpICs9IDI7CgkJCQl9CgkJCX0KCQkJJGRlY29tcHJlc3NlZCA9IHNlbGY6OmNvbXBhdGlibGVfZ3ppbmZsYXRlKHN1YnN0cigkZ3pfZGF0YSwgJGkpKTsKCQkJaWYgKCRkZWNvbXByZXNzZWQgIT09IGZhbHNlKSB7CgkJCQlyZXR1cm4gJGRlY29tcHJlc3NlZDsKCQkJfQoJCX0KCgkJLy8gSWYgdGhlIGRhdGEgaXMgSHVmZm1hbiBFbmNvZGVkLCB3ZSBtdXN0IGZpcnN0IHN0cmlwIHRoZSBsZWFkaW5nIDIKCQkvLyBieXRlIEh1ZmZtYW4gbWFya2VyIGZvciBnemluZmxhdGUoKQoJCS8vIFRoZSByZXNwb25zZSBpcyBIdWZmbWFuIGNvZGVkIGJ5IG1hbnkgY29tcHJlc3NvcnMgc3VjaCBhcwoJCS8vIGphdmEudXRpbC56aXAuRGVmbGF0ZXIsIFJ1YnnigJlzIFpsaWI6OkRlZmxhdGUsIGFuZCAuTkVUJ3MKCQkvLyBTeXN0ZW0uSU8uQ29tcHJlc3Npb24uRGVmbGF0ZVN0cmVhbS4KCQkvLwoJCS8vIFNlZSBodHRwczovL2RlY29tcHJlcy5ibG9nc3BvdC5jb20vIGZvciBhIHF1aWNrIGV4cGxhbmF0aW9uIG9mIHRoaXMKCQkvLyBkYXRhIHR5cGUKCQkkaHVmZm1hbl9lbmNvZGVkID0gZmFsc2U7CgoJCS8vIGxvdyBuaWJibGUgb2YgZmlyc3QgYnl0ZSBzaG91bGQgYmUgMHgwOAoJCWxpc3QoLCAkZmlyc3RfbmliYmxlKSA9IHVucGFjaygnaCcsICRnel9kYXRhKTsKCgkJLy8gRmlyc3QgMiBieXRlcyBzaG91bGQgYmUgZGl2aXNpYmxlIGJ5IDB4MUYKCQlsaXN0KCwgJGZpcnN0X3R3b19ieXRlcykgPSB1bnBhY2soJ24nLCAkZ3pfZGF0YSk7CgoJCWlmICgkZmlyc3RfbmliYmxlID09PSAweDA4ICYmICgkZmlyc3RfdHdvX2J5dGVzICUgMHgxRikgPT09IDApIHsKCQkJJGh1ZmZtYW5fZW5jb2RlZCA9IHRydWU7CgkJfQoKCQlpZiAoJGh1ZmZtYW5fZW5jb2RlZCkgewoJCQkkZGVjb21wcmVzc2VkID0gQGd6aW5mbGF0ZShzdWJzdHIoJGd6X2RhdGEsIDIpKTsKCQkJaWYgKCRkZWNvbXByZXNzZWQgIT09IGZhbHNlKSB7CgkJCQlyZXR1cm4gJGRlY29tcHJlc3NlZDsKCQkJfQoJCX0KCgkJaWYgKHN1YnN0cigkZ3pfZGF0YSwgMCwgNCkgPT09ICJceDUwXHg0Ylx4MDNceDA0IikgewoJCQkvLyBaSVAgZmlsZSBmb3JtYXQgaGVhZGVyCgkJCS8vIE9mZnNldCA2OiAyIGJ5dGVzLCBHZW5lcmFsLXB1cnBvc2UgZmllbGQKCQkJLy8gT2Zmc2V0IDI2OiAyIGJ5dGVzLCBmaWxlbmFtZSBsZW5ndGgKCQkJLy8gT2Zmc2V0IDI4OiAyIGJ5dGVzLCBvcHRpb25hbCBmaWVsZCBsZW5ndGgKCQkJLy8gT2Zmc2V0IDMwOiBGaWxlbmFtZSBmaWVsZCwgZm9sbG93ZWQgYnkgb3B0aW9uYWwgZmllbGQsIGZvbGxvd2VkCgkJCS8vIGltbWVkaWF0ZWx5IGJ5IGRhdGEKCQkJbGlzdCgsICRnZW5lcmFsX3B1cnBvc2VfZmxhZykgPSB1bnBhY2soJ3YnLCBzdWJzdHIoJGd6X2RhdGEsIDYsIDIpKTsKCgkJCS8vIElmIHRoZSBmaWxlIGhhcyBiZWVuIGNvbXByZXNzZWQgb24gdGhlIGZseSwgMHgwOCBiaXQgaXMgc2V0IG9mCgkJCS8vIHRoZSBnZW5lcmFsIHB1cnBvc2UgZmllbGQuIFdlIGNhbiB1c2UgdGhpcyB0byBkaWZmZXJlbnRpYXRlCgkJCS8vIGJldHdlZW4gYSBjb21wcmVzc2VkIGRvY3VtZW50LCBhbmQgYSBaSVAgZmlsZQoJCQkkemlwX2NvbXByZXNzZWRfb25fdGhlX2ZseSA9ICgoMHgwOCAmICRnZW5lcmFsX3B1cnBvc2VfZmxhZykgPT09IDB4MDgpOwoKCQkJaWYgKCEkemlwX2NvbXByZXNzZWRfb25fdGhlX2ZseSkgewoJCQkJLy8gRG9uJ3QgYXR0ZW1wdCB0byBkZWNvZGUgYSBjb21wcmVzc2VkIHppcCBmaWxlCgkJCQlyZXR1cm4gJGd6X2RhdGE7CgkJCX0KCgkJCS8vIERldGVybWluZSB0aGUgZmlyc3QgYnl0ZSBvZiBkYXRhLCBiYXNlZCBvbiB0aGUgYWJvdmUgWklQIGhlYWRlcgoJCQkvLyBvZmZzZXRzOgoJCQkkZmlyc3RfZmlsZV9zdGFydCA9IGFycmF5X3N1bSh1bnBhY2soJ3YyJywgc3Vic3RyKCRnel9kYXRhLCAyNiwgNCkpKTsKCQkJJGRlY29tcHJlc3NlZCAgICAgPSBAZ3ppbmZsYXRlKHN1YnN0cigkZ3pfZGF0YSwgMzAgKyAkZmlyc3RfZmlsZV9zdGFydCkpOwoJCQlpZiAoJGRlY29tcHJlc3NlZCAhPT0gZmFsc2UpIHsKCQkJCXJldHVybiAkZGVjb21wcmVzc2VkOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIEZpbmFsbHkgZmFsbCBiYWNrIHRvIHN0cmFpZ2h0IGd6aW5mbGF0ZQoJCSRkZWNvbXByZXNzZWQgPSBAZ3ppbmZsYXRlKCRnel9kYXRhKTsKCQlpZiAoJGRlY29tcHJlc3NlZCAhPT0gZmFsc2UpIHsKCQkJcmV0dXJuICRkZWNvbXByZXNzZWQ7CgkJfQoKCQkvLyBGYWxsYmFjayBmb3IgYWxsIGFib3ZlIGZhaWxpbmcsIG5vdCBleHBlY3RlZCwgYnV0IGluY2x1ZGVkIGZvcgoJCS8vIGRlYnVnZ2luZyBhbmQgcHJldmVudGluZyByZWdyZXNzaW9ucyBhbmQgdG8gdHJhY2sgc3RhdHMKCQkkZGVjb21wcmVzc2VkID0gQGd6aW5mbGF0ZShzdWJzdHIoJGd6X2RhdGEsIDIpKTsKCQlpZiAoJGRlY29tcHJlc3NlZCAhPT0gZmFsc2UpIHsKCQkJcmV0dXJuICRkZWNvbXByZXNzZWQ7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYXRjaF9kb21haW4oJGhvc3QsICRyZWZlcmVuY2UpIHsKCQkvLyBDaGVjayBmb3IgYSBkaXJlY3QgbWF0Y2gKCQlpZiAoJGhvc3QgPT09ICRyZWZlcmVuY2UpIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBDYWxjdWxhdGUgdGhlIHZhbGlkIHdpbGRjYXJkIG1hdGNoIGlmIHRoZSBob3N0IGlzIG5vdCBhbiBJUCBhZGRyZXNzCgkJLy8gQWxzbyB2YWxpZGF0ZXMgdGhhdCB0aGUgaG9zdCBoYXMgMyBwYXJ0cyBvciBtb3JlLCBhcyBwZXIgRmlyZWZveCdzCgkJLy8gcnVsZXNldC4KCQkkcGFydHMgPSBleHBsb2RlKCcuJywgJGhvc3QpOwoJCWlmIChpcDJsb25nKCRob3N0KSA9PT0gZmFsc2UgJiYgY291bnQoJHBhcnRzKSA+PSAzKSB7CgkJCSRwYXJ0c1swXSA9ICcqJzsKCQkJJHdpbGRjYXJkID0gaW1wbG9kZSgnLicsICRwYXJ0cyk7CgkJCWlmICgkd2lsZGNhcmQgPT09ICRyZWZlcmVuY2UpIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9Cn0KPD9waHAKLyoqCiAqIEV2ZW50IGRpc3BhdGNoZXIKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwoKLyoqCiAqIEV2ZW50IGRpc3BhdGNoZXIKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwppbnRlcmZhY2UgUmVxdWVzdHNfSG9va2VyIHsKCS8qKgoJICogUmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSBob29rCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBjYWxsYmFjayAkY2FsbGJhY2sgRnVuY3Rpb24vbWV0aG9kIHRvIGNhbGwgb24gZXZlbnQKCSAqIEBwYXJhbSBpbnQgJHByaW9yaXR5IFByaW9yaXR5IG51bWJlci4gPDAgaXMgZXhlY3V0ZWQgZWFybGllciwgPjAgaXMgZXhlY3V0ZWQgbGF0ZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRob29rLCAkY2FsbGJhY2ssICRwcmlvcml0eSA9IDApOwoKCS8qKgoJICogRGlzcGF0Y2ggYSBtZXNzYWdlCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBhcnJheSAkcGFyYW1ldGVycyBQYXJhbWV0ZXJzIHRvIHBhc3MgdG8gY2FsbGJhY2tzCgkgKiBAcmV0dXJuIGJvb2xlYW4gU3VjY2Vzc2Z1bG5lc3MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoKCRob29rLCAkcGFyYW1ldGVycyA9IGFycmF5KCkpOwp9Cjw/cGhwCi8qKgogKiBTZXNzaW9uIGhhbmRsZXIgZm9yIHBlcnNpc3RlbnQgcmVxdWVzdHMgYW5kIGRlZmF1bHQgcGFyYW1ldGVycwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBTZXNzaW9uIEhhbmRsZXIKICovCgovKioKICogU2Vzc2lvbiBoYW5kbGVyIGZvciBwZXJzaXN0ZW50IHJlcXVlc3RzIGFuZCBkZWZhdWx0IHBhcmFtZXRlcnMKICoKICogQWxsb3dzIHZhcmlvdXMgb3B0aW9ucyB0byBiZSBzZXQgYXMgZGVmYXVsdCB2YWx1ZXMsIGFuZCBtZXJnZXMgYm90aCB0aGUKICogb3B0aW9ucyBhbmQgVVJMIHByb3BlcnRpZXMgdG9nZXRoZXIuIEEgYmFzZSBVUkwgY2FuIGJlIHNldCBmb3IgYWxsIHJlcXVlc3RzLAogKiB3aXRoIGFsbCBzdWJyZXF1ZXN0cyByZXNvbHZlZCBmcm9tIHRoaXMuIEJhc2Ugb3B0aW9ucyBjYW4gYmUgc2V0IChpbmNsdWRpbmcKICogYSBzaGFyZWQgY29va2llIGphciksIHRoZW4gb3ZlcnJpZGRlbiBmb3IgaW5kaXZpZHVhbCByZXF1ZXN0cy4KICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgU2Vzc2lvbiBIYW5kbGVyCiAqLwpjbGFzcyBSZXF1ZXN0c19TZXNzaW9uIHsKCS8qKgoJICogQmFzZSBVUkwgZm9yIHJlcXVlc3RzCgkgKgoJICogVVJMcyB3aWxsIGJlIG1hZGUgYWJzb2x1dGUgdXNpbmcgdGhpcyBhcyB0aGUgYmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHVibGljICR1cmwgPSBudWxsOwoKCS8qKgoJICogQmFzZSBoZWFkZXJzIGZvciByZXF1ZXN0cwoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHVibGljICRoZWFkZXJzID0gYXJyYXkoKTsKCgkvKioKCSAqIEJhc2UgZGF0YSBmb3IgcmVxdWVzdHMKCSAqCgkgKiBJZiBib3RoIHRoZSBiYXNlIGRhdGEgYW5kIHRoZSBwZXItcmVxdWVzdCBkYXRhIGFyZSBhcnJheXMsIHRoZSBkYXRhIHdpbGwKCSAqIGJlIG1lcmdlZCBiZWZvcmUgc2VuZGluZyB0aGUgcmVxdWVzdC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXB1YmxpYyAkZGF0YSA9IGFycmF5KCk7CgoJLyoqCgkgKiBCYXNlIG9wdGlvbnMgZm9yIHJlcXVlc3RzCgkgKgoJICogVGhlIGJhc2Ugb3B0aW9ucyBhcmUgbWVyZ2VkIHdpdGggdGhlIHBlci1yZXF1ZXN0IGRhdGEgZm9yIGVhY2ggcmVxdWVzdC4KCSAqIFRoZSBvbmx5IGRlZmF1bHQgb3B0aW9uIGlzIGEgc2hhcmVkIGNvb2tpZSBqYXIgYmV0d2VlbiByZXF1ZXN0cy4KCSAqCgkgKiBWYWx1ZXMgaGVyZSBjYW4gYWxzbyBiZSBzZXQgZGlyZWN0bHkgdmlhIHByb3BlcnRpZXMgb24gdGhlIFNlc3Npb24KCSAqIG9iamVjdCwgZS5nLiBgJHNlc3Npb24tPnVzZXJhZ2VudCA9ICdYJztgCgkgKgoJICogQHZhciBhcnJheQoJICovCglwdWJsaWMgJG9wdGlvbnMgPSBhcnJheSgpOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IHNlc3Npb24KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHVybCBCYXNlIFVSTCBmb3IgcmVxdWVzdHMKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBEZWZhdWx0IGhlYWRlcnMgZm9yIHJlcXVlc3RzCgkgKiBAcGFyYW0gYXJyYXkgJGRhdGEgRGVmYXVsdCBkYXRhIGZvciByZXF1ZXN0cwoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIERlZmF1bHQgb3B0aW9ucyBmb3IgcmVxdWVzdHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwgPSBudWxsLCAkaGVhZGVycyA9IGFycmF5KCksICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJJHRoaXMtPnVybCAgICAgPSAkdXJsOwoJCSR0aGlzLT5oZWFkZXJzID0gJGhlYWRlcnM7CgkJJHRoaXMtPmRhdGEgICAgPSAkZGF0YTsKCQkkdGhpcy0+b3B0aW9ucyA9ICRvcHRpb25zOwoKCQlpZiAoZW1wdHkoJHRoaXMtPm9wdGlvbnNbJ2Nvb2tpZXMnXSkpIHsKCQkJJHRoaXMtPm9wdGlvbnNbJ2Nvb2tpZXMnXSA9IG5ldyBSZXF1ZXN0c19Db29raWVfSmFyKCk7CgkJfQoJfQoKCS8qKgoJICogR2V0IGEgcHJvcGVydHkncyB2YWx1ZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQcm9wZXJ0eSBrZXkKCSAqIEByZXR1cm4gbWl4ZWR8bnVsbCBQcm9wZXJ0eSB2YWx1ZSwgbnVsbCBpZiBub25lIGZvdW5kCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgka2V5KSB7CgkJaWYgKGlzc2V0KCR0aGlzLT5vcHRpb25zWyRrZXldKSkgewoJCQlyZXR1cm4gJHRoaXMtPm9wdGlvbnNbJGtleV07CgkJfQoKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFNldCBhIHByb3BlcnR5J3MgdmFsdWUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgUHJvcGVydHkga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFByb3BlcnR5IHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX3NldCgka2V5LCAkdmFsdWUpIHsKCQkkdGhpcy0+b3B0aW9uc1ska2V5XSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIFJlbW92ZSBhIHByb3BlcnR5J3MgdmFsdWUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgUHJvcGVydHkga2V5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2lzc2V0KCRrZXkpIHsKCQlyZXR1cm4gaXNzZXQoJHRoaXMtPm9wdGlvbnNbJGtleV0pOwoJfQoKCS8qKgoJICogUmVtb3ZlIGEgcHJvcGVydHkncyB2YWx1ZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBQcm9wZXJ0eSBrZXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdW5zZXQoJGtleSkgewoJCWlmIChpc3NldCgkdGhpcy0+b3B0aW9uc1ska2V5XSkpIHsKCQkJdW5zZXQoJHRoaXMtPm9wdGlvbnNbJGtleV0pOwoJCX0KCX0KCgkvKiojQCsKCSAqIEBzZWUgcmVxdWVzdCgpCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycwoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKi8KCS8qKgoJICogU2VuZCBhIEdFVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIFJlcXVlc3RzOjpHRVQsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBIRUFEIHJlcXVlc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhlYWQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsIG51bGwsIFJlcXVlc3RzOjpIRUFELCAkb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBTZW5kIGEgREVMRVRFIHJlcXVlc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiAkdGhpcy0+cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgbnVsbCwgUmVxdWVzdHM6OkRFTEVURSwgJG9wdGlvbnMpOwoJfQoJLyoqI0AtKi8KCgkvKiojQCsKCSAqIEBzZWUgcmVxdWVzdCgpCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycwoJICogQHBhcmFtIGFycmF5ICRkYXRhCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKCSAqIEByZXR1cm4gUmVxdWVzdHNfUmVzcG9uc2UKCSAqLwoJLyoqCgkgKiBTZW5kIGEgUE9TVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwb3N0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlyZXR1cm4gJHRoaXMtPnJlcXVlc3QoJHVybCwgJGhlYWRlcnMsICRkYXRhLCBSZXF1ZXN0czo6UE9TVCwgJG9wdGlvbnMpOwoJfQoKCS8qKgoJICogU2VuZCBhIFBVVCByZXF1ZXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwdXQoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCXJldHVybiAkdGhpcy0+cmVxdWVzdCgkdXJsLCAkaGVhZGVycywgJGRhdGEsIFJlcXVlc3RzOjpQVVQsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIFNlbmQgYSBQQVRDSCByZXF1ZXN0CgkgKgoJICogTm90ZTogVW5saWtlIHtAc2VlIHBvc3R9IGFuZCB7QHNlZSBwdXR9LCBgJGhlYWRlcnNgIGlzIHJlcXVpcmVkLCBhcyB0aGUKCSAqIHNwZWNpZmljYXRpb24gcmVjb21tZW5kcyB0aGF0IHNob3VsZCBzZW5kIGFuIEVUYWcKCSAqCgkgKiBAbGluayBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTc4OQoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0Y2goJHVybCwgJGhlYWRlcnMsICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKSB7CgkJcmV0dXJuICR0aGlzLT5yZXF1ZXN0KCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgUmVxdWVzdHM6OlBBVENILCAkb3B0aW9ucyk7Cgl9CgkvKiojQC0qLwoKCS8qKgoJICogTWFpbiBpbnRlcmZhY2UgZm9yIEhUVFAgcmVxdWVzdHMKCSAqCgkgKiBUaGlzIG1ldGhvZCBpbml0aWF0ZXMgYSByZXF1ZXN0IGFuZCBzZW5kcyBpdCB2aWEgYSB0cmFuc3BvcnQgYmVmb3JlCgkgKiBwYXJzaW5nLgoJICoKCSAqIEBzZWUgUmVxdWVzdHM6OnJlcXVlc3QoKQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGludmFsaWQgVVJMcyAoYG5vbmh0dHBgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgdG8gcmVxdWVzdAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIEV4dHJhIGhlYWRlcnMgdG8gc2VuZCB3aXRoIHRoZSByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXl8bnVsbCAkZGF0YSBEYXRhIHRvIHNlbmQgZWl0aGVyIGFzIGEgcXVlcnkgc3RyaW5nIGZvciBHRVQvSEVBRCByZXF1ZXN0cywgb3IgaW4gdGhlIGJvZHkgZm9yIFBPU1QgcmVxdWVzdHMKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgSFRUUCByZXF1ZXN0IHR5cGUgKHVzZSBSZXF1ZXN0cyBjb25zdGFudHMpCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3QgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0pCgkgKiBAcmV0dXJuIFJlcXVlc3RzX1Jlc3BvbnNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkdHlwZSA9IFJlcXVlc3RzOjpHRVQsICRvcHRpb25zID0gYXJyYXkoKSkgewoJCSRyZXF1ZXN0ID0gJHRoaXMtPm1lcmdlX3JlcXVlc3QoY29tcGFjdCgndXJsJywgJ2hlYWRlcnMnLCAnZGF0YScsICdvcHRpb25zJykpOwoKCQlyZXR1cm4gUmVxdWVzdHM6OnJlcXVlc3QoJHJlcXVlc3RbJ3VybCddLCAkcmVxdWVzdFsnaGVhZGVycyddLCAkcmVxdWVzdFsnZGF0YSddLCAkdHlwZSwgJHJlcXVlc3RbJ29wdGlvbnMnXSk7Cgl9CgoJLyoqCgkgKiBTZW5kIG11bHRpcGxlIEhUVFAgcmVxdWVzdHMgc2ltdWx0YW5lb3VzbHkKCSAqCgkgKiBAc2VlIFJlcXVlc3RzOjpyZXF1ZXN0X211bHRpcGxlKCkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlcXVlc3RzIFJlcXVlc3RzIGRhdGEgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdF9tdWx0aXBsZX0pCgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIGFuZCBkZWZhdWx0IG9wdGlvbnMgKHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0pCgkgKiBAcmV0dXJuIGFycmF5IFJlc3BvbnNlcyAoZWl0aGVyIFJlcXVlc3RzX1Jlc3BvbnNlIG9yIGEgUmVxdWVzdHNfRXhjZXB0aW9uIG9iamVjdCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3RfbXVsdGlwbGUoJHJlcXVlc3RzLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQlmb3JlYWNoICgkcmVxdWVzdHMgYXMgJGtleSA9PiAkcmVxdWVzdCkgewoJCQkkcmVxdWVzdHNbJGtleV0gPSAkdGhpcy0+bWVyZ2VfcmVxdWVzdCgkcmVxdWVzdCwgZmFsc2UpOwoJCX0KCgkJJG9wdGlvbnMgPSBhcnJheV9tZXJnZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwoKCQkvLyBEaXNhbGxvdyBmb3JjaW5nIHRoZSB0eXBlLCBhcyB0aGF0J3MgYSBwZXIgcmVxdWVzdCBzZXR0aW5nCgkJdW5zZXQoJG9wdGlvbnNbJ3R5cGUnXSk7CgoJCXJldHVybiBSZXF1ZXN0czo6cmVxdWVzdF9tdWx0aXBsZSgkcmVxdWVzdHMsICRvcHRpb25zKTsKCX0KCgkvKioKCSAqIE1lcmdlIGEgcmVxdWVzdCdzIGRhdGEgd2l0aCB0aGUgZGVmYXVsdCBkYXRhCgkgKgoJICogQHBhcmFtIGFycmF5ICRyZXF1ZXN0IFJlcXVlc3QgZGF0YSAoc2FtZSBmb3JtIGFzIHtAc2VlIHJlcXVlc3RfbXVsdGlwbGV9KQoJICogQHBhcmFtIGJvb2xlYW4gJG1lcmdlX29wdGlvbnMgU2hvdWxkIHdlIG1lcmdlIG9wdGlvbnMgYXMgd2VsbD8KCSAqIEByZXR1cm4gYXJyYXkgUmVxdWVzdCBkYXRhCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBtZXJnZV9yZXF1ZXN0KCRyZXF1ZXN0LCAkbWVyZ2Vfb3B0aW9ucyA9IHRydWUpIHsKCQlpZiAoJHRoaXMtPnVybCAhPT0gbnVsbCkgewoJCQkkcmVxdWVzdFsndXJsJ10gPSBSZXF1ZXN0c19JUkk6OmFic29sdXRpemUoJHRoaXMtPnVybCwgJHJlcXVlc3RbJ3VybCddKTsKCQkJJHJlcXVlc3RbJ3VybCddID0gJHJlcXVlc3RbJ3VybCddLT51cmk7CgkJfQoKCQlpZiAoZW1wdHkoJHJlcXVlc3RbJ2hlYWRlcnMnXSkpIHsKCQkJJHJlcXVlc3RbJ2hlYWRlcnMnXSA9IGFycmF5KCk7CgkJfQoJCSRyZXF1ZXN0WydoZWFkZXJzJ10gPSBhcnJheV9tZXJnZSgkdGhpcy0+aGVhZGVycywgJHJlcXVlc3RbJ2hlYWRlcnMnXSk7CgoJCWlmIChlbXB0eSgkcmVxdWVzdFsnZGF0YSddKSkgewoJCQlpZiAoaXNfYXJyYXkoJHRoaXMtPmRhdGEpKSB7CgkJCQkkcmVxdWVzdFsnZGF0YSddID0gJHRoaXMtPmRhdGE7CgkJCX0KCQl9CgkJZWxzZWlmIChpc19hcnJheSgkcmVxdWVzdFsnZGF0YSddKSAmJiBpc19hcnJheSgkdGhpcy0+ZGF0YSkpIHsKCQkJJHJlcXVlc3RbJ2RhdGEnXSA9IGFycmF5X21lcmdlKCR0aGlzLT5kYXRhLCAkcmVxdWVzdFsnZGF0YSddKTsKCQl9CgoJCWlmICgkbWVyZ2Vfb3B0aW9ucyAhPT0gZmFsc2UpIHsKCQkJJHJlcXVlc3RbJ29wdGlvbnMnXSA9IGFycmF5X21lcmdlKCR0aGlzLT5vcHRpb25zLCAkcmVxdWVzdFsnb3B0aW9ucyddKTsKCgkJCS8vIERpc2FsbG93IGZvcmNpbmcgdGhlIHR5cGUsIGFzIHRoYXQncyBhIHBlciByZXF1ZXN0IHNldHRpbmcKCQkJdW5zZXQoJHJlcXVlc3RbJ29wdGlvbnMnXVsndHlwZSddKTsKCQl9CgoJCXJldHVybiAkcmVxdWVzdDsKCX0KfQo8P3BocAoKLyoqCiAqIElETkEgVVJMIGVuY29kZXIKICoKICogTm90ZTogTm90IGZ1bGx5IGNvbXBsaWFudCwgYXMgbmFtZXByZXAgZG9lcyBub3RoaW5nIHlldC4KICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTAgSUROQSBzcGVjaWZpY2F0aW9uCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTIgUHVueWNvZGUvQm9vdHN0cmFwIHNwZWNpZmljYXRpb24KICovCmNsYXNzIFJlcXVlc3RzX0lETkFFbmNvZGVyIHsKCS8qKgoJICogQUNFIHByZWZpeCB1c2VkIGZvciBJRE5BCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MCNzZWN0aW9uLTUKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IEFDRV9QUkVGSVggPSAneG4tLSc7CgoJLyoqI0ArCgkgKiBCb290c3RyYXAgY29uc3RhbnQgZm9yIFB1bnljb2RlCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MiNzZWN0aW9uLTUKCSAqIEB2YXIgaW50CgkgKi8KCWNvbnN0IEJPT1RTVFJBUF9CQVNFICAgICAgICAgPSAzNjsKCWNvbnN0IEJPT1RTVFJBUF9UTUlOICAgICAgICAgPSAxOwoJY29uc3QgQk9PVFNUUkFQX1RNQVggICAgICAgICA9IDI2OwoJY29uc3QgQk9PVFNUUkFQX1NLRVcgICAgICAgICA9IDM4OwoJY29uc3QgQk9PVFNUUkFQX0RBTVAgICAgICAgICA9IDcwMDsKCWNvbnN0IEJPT1RTVFJBUF9JTklUSUFMX0JJQVMgPSA3MjsKCWNvbnN0IEJPT1RTVFJBUF9JTklUSUFMX04gICAgPSAxMjg7CgkvKiojQC0qLwoKCS8qKgoJICogRW5jb2RlIGEgaG9zdG5hbWUgdXNpbmcgUHVueWNvZGUKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgSG9zdG5hbWUKCSAqIEByZXR1cm4gc3RyaW5nIFB1bnljb2RlLWVuY29kZWQgaG9zdG5hbWUKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlbmNvZGUoJHN0cmluZykgewoJCSRwYXJ0cyA9IGV4cGxvZGUoJy4nLCAkc3RyaW5nKTsKCQlmb3JlYWNoICgkcGFydHMgYXMgJiRwYXJ0KSB7CgkJCSRwYXJ0ID0gc2VsZjo6dG9fYXNjaWkoJHBhcnQpOwoJCX0KCQlyZXR1cm4gaW1wbG9kZSgnLicsICRwYXJ0cyk7Cgl9CgoJLyoqCgkgKiBDb252ZXJ0IGEgVVRGLTggc3RyaW5nIHRvIGFuIEFTQ0lJIHN0cmluZyB1c2luZyBQdW55Y29kZQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIFByb3ZpZGVkIHN0cmluZyBsb25nZXIgdGhhbiA2NCBBU0NJSSBjaGFyYWN0ZXJzIChgaWRuYS5wcm92aWRlZF90b29fbG9uZ2ApCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBQcmVwYXJlZCBzdHJpbmcgbG9uZ2VyIHRoYW4gNjQgQVNDSUkgY2hhcmFjdGVycyAoYGlkbmEucHJlcGFyZWRfdG9vX2xvbmdgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gUHJvdmlkZWQgc3RyaW5nIGFscmVhZHkgYmVnaW5zIHdpdGggeG4tLSAoYGlkbmEucHJvdmlkZWRfaXNfcHJlZml4ZWRgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gRW5jb2RlZCBzdHJpbmcgbG9uZ2VyIHRoYW4gNjQgQVNDSUkgY2hhcmFjdGVycyAoYGlkbmEuZW5jb2RlZF90b29fbG9uZ2ApCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIEFTQ0lJIG9yIFVURi04IHN0cmluZyAobWF4IGxlbmd0aCA2NCBjaGFyYWN0ZXJzKQoJICogQHJldHVybiBzdHJpbmcgQVNDSUkgc3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9fYXNjaWkoJHN0cmluZykgewoJCS8vIFN0ZXAgMTogQ2hlY2sgaWYgdGhlIHN0cmluZyBpcyBhbHJlYWR5IEFTQ0lJCgkJaWYgKHNlbGY6OmlzX2FzY2lpKCRzdHJpbmcpKSB7CgkJCS8vIFNraXAgdG8gc3RlcCA3CgkJCWlmIChzdHJsZW4oJHN0cmluZykgPCA2NCkgewoJCQkJcmV0dXJuICRzdHJpbmc7CgkJCX0KCgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ1Byb3ZpZGVkIHN0cmluZyBpcyB0b28gbG9uZycsICdpZG5hLnByb3ZpZGVkX3Rvb19sb25nJywgJHN0cmluZyk7CgkJfQoKCQkvLyBTdGVwIDI6IG5hbWVwcmVwCgkJJHN0cmluZyA9IHNlbGY6Om5hbWVwcmVwKCRzdHJpbmcpOwoKCQkvLyBTdGVwIDM6IFVzZVNURDNBU0NJSVJ1bGVzIGlzIGZhbHNlLCBjb250aW51ZQoJCS8vIFN0ZXAgNDogQ2hlY2sgaWYgaXQncyBBU0NJSSBub3cKCQlpZiAoc2VsZjo6aXNfYXNjaWkoJHN0cmluZykpIHsKCQkJLy8gU2tpcCB0byBzdGVwIDcKCQkJaWYgKHN0cmxlbigkc3RyaW5nKSA8IDY0KSB7CgkJCQlyZXR1cm4gJHN0cmluZzsKCQkJfQoKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignUHJlcGFyZWQgc3RyaW5nIGlzIHRvbyBsb25nJywgJ2lkbmEucHJlcGFyZWRfdG9vX2xvbmcnLCAkc3RyaW5nKTsKCQl9CgoJCS8vIFN0ZXAgNTogQ2hlY2sgQUNFIHByZWZpeAoJCWlmIChzdHJwb3MoJHN0cmluZywgc2VsZjo6QUNFX1BSRUZJWCkgPT09IDApIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignUHJvdmlkZWQgc3RyaW5nIGJlZ2lucyB3aXRoIEFDRSBwcmVmaXgnLCAnaWRuYS5wcm92aWRlZF9pc19wcmVmaXhlZCcsICRzdHJpbmcpOwoJCX0KCgkJLy8gU3RlcCA2OiBFbmNvZGUgd2l0aCBQdW55Y29kZQoJCSRzdHJpbmcgPSBzZWxmOjpwdW55Y29kZV9lbmNvZGUoJHN0cmluZyk7CgoJCS8vIFN0ZXAgNzogUHJlcGVuZCBBQ0UgcHJlZml4CgkJJHN0cmluZyA9IHNlbGY6OkFDRV9QUkVGSVggLiAkc3RyaW5nOwoKCQkvLyBTdGVwIDg6IENoZWNrIHNpemUKCQlpZiAoc3RybGVuKCRzdHJpbmcpIDwgNjQpIHsKCQkJcmV0dXJuICRzdHJpbmc7CgkJfQoKCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdFbmNvZGVkIHN0cmluZyBpcyB0b28gbG9uZycsICdpZG5hLmVuY29kZWRfdG9vX2xvbmcnLCAkc3RyaW5nKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBzdHJpbmcgY29udGFpbnMgb25seSBBU0NJSSBjaGFyYWN0ZXJzCgkgKgoJICogQGludGVybmFsIChUZXN0aW5nIGZvdW5kIHJlZ2V4IHdhcyB0aGUgZmFzdGVzdCBpbXBsZW1lbnRhdGlvbikKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKCSAqIEByZXR1cm4gYm9vbCBJcyB0aGUgc3RyaW5nIEFTQ0lJLW9ubHk/CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gaXNfYXNjaWkoJHN0cmluZykgewoJCXJldHVybiAocHJlZ19tYXRjaCgnLyg/OlteXHgwMC1ceDdGXSkvJywgJHN0cmluZykgIT09IDEpOwoJfQoKCS8qKgoJICogUHJlcGFyZSBhIHN0cmluZyBmb3IgdXNlIGFzIGFuIElETkEgbmFtZQoJICoKCSAqIEB0b2RvIEltcGxlbWVudCB0aGlzIGJhc2VkIG9uIFJGQyAzNDkxIGFuZCB0aGUgbmV3ZXIgNTg5MQoJICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCgkgKiBAcmV0dXJuIHN0cmluZyBQcmVwYXJlZCBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBuYW1lcHJlcCgkc3RyaW5nKSB7CgkJcmV0dXJuICRzdHJpbmc7Cgl9CgoJLyoqCgkgKiBDb252ZXJ0IGEgVVRGLTggc3RyaW5nIHRvIGEgVUNTLTQgY29kZXBvaW50IGFycmF5CgkgKgoJICogQmFzZWQgb24gUmVxdWVzdHNfSVJJOjpyZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoKQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIEludmFsaWQgVVRGLTggY29kZXBvaW50IChgaWRuYS5pbnZhbGlkY29kZXBvaW50YCkKCSAqIEBwYXJhbSBzdHJpbmcgJGlucHV0CgkgKiBAcmV0dXJuIGFycmF5IFVuaWNvZGUgY29kZSBwb2ludHMKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB1dGY4X3RvX2NvZGVwb2ludHMoJGlucHV0KSB7CgkJJGNvZGVwb2ludHMgPSBhcnJheSgpOwoKCQkvLyBHZXQgbnVtYmVyIG9mIGJ5dGVzCgkJJHN0cmxlbiA9IHN0cmxlbigkaW5wdXQpOwoKCQkvLyBwaHBjczppZ25vcmUgR2VuZXJpYy5Db2RlQW5hbHlzaXMuSnVtYmxlZEluY3JlbWVudGVyIC0tIFRoaXMgaXMgYSBkZWxpYmVyYXRlIGNob2ljZS4KCQlmb3IgKCRwb3NpdGlvbiA9IDA7ICRwb3NpdGlvbiA8ICRzdHJsZW47ICRwb3NpdGlvbisrKSB7CgkJCSR2YWx1ZSA9IG9yZCgkaW5wdXRbJHBvc2l0aW9uXSk7CgoJCQkvLyBPbmUgYnl0ZSBzZXF1ZW5jZToKCQkJaWYgKCh+JHZhbHVlICYgMHg4MCkgPT09IDB4ODApIHsKCQkJCSRjaGFyYWN0ZXIgPSAkdmFsdWU7CgkJCQkkbGVuZ3RoICAgID0gMTsKCQkJCSRyZW1haW5pbmcgPSAwOwoJCQl9CgkJCS8vIFR3byBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEUwKSA9PT0gMHhDMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDFGKSA8PCA2OwoJCQkJJGxlbmd0aCAgICA9IDI7CgkJCQkkcmVtYWluaW5nID0gMTsKCQkJfQoJCQkvLyBUaHJlZSBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEYwKSA9PT0gMHhFMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDBGKSA8PCAxMjsKCQkJCSRsZW5ndGggICAgPSAzOwoJCQkJJHJlbWFpbmluZyA9IDI7CgkJCX0KCQkJLy8gRm91ciBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEY4KSA9PT0gMHhGMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDA3KSA8PCAxODsKCQkJCSRsZW5ndGggICAgPSA0OwoJCQkJJHJlbWFpbmluZyA9IDM7CgkJCX0KCQkJLy8gSW52YWxpZCBieXRlOgoJCQllbHNlIHsKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgVW5pY29kZSBjb2RlcG9pbnQnLCAnaWRuYS5pbnZhbGlkY29kZXBvaW50JywgJHZhbHVlKTsKCQkJfQoKCQkJaWYgKCRyZW1haW5pbmcgPiAwKSB7CgkJCQlpZiAoJHBvc2l0aW9uICsgJGxlbmd0aCA+ICRzdHJsZW4pIHsKCQkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIFVuaWNvZGUgY29kZXBvaW50JywgJ2lkbmEuaW52YWxpZGNvZGVwb2ludCcsICRjaGFyYWN0ZXIpOwoJCQkJfQoJCQkJZm9yICgkcG9zaXRpb24rKzsgJHJlbWFpbmluZyA+IDA7ICRwb3NpdGlvbisrKSB7CgkJCQkJJHZhbHVlID0gb3JkKCRpbnB1dFskcG9zaXRpb25dKTsKCgkJCQkJLy8gSWYgaXQgaXMgaW52YWxpZCwgY291bnQgdGhlIHNlcXVlbmNlIGFzIGludmFsaWQgYW5kIHJlcHJvY2VzcyB0aGUgY3VycmVudCBieXRlOgoJCQkJCWlmICgoJHZhbHVlICYgMHhDMCkgIT09IDB4ODApIHsKCQkJCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignSW52YWxpZCBVbmljb2RlIGNvZGVwb2ludCcsICdpZG5hLmludmFsaWRjb2RlcG9pbnQnLCAkY2hhcmFjdGVyKTsKCQkJCQl9CgoJCQkJCS0tJHJlbWFpbmluZzsKCQkJCQkkY2hhcmFjdGVyIHw9ICgkdmFsdWUgJiAweDNGKSA8PCAoJHJlbWFpbmluZyAqIDYpOwoJCQkJfQoJCQkJJHBvc2l0aW9uLS07CgkJCX0KCgkJCWlmICgvLyBOb24tc2hvcnRlc3QgZm9ybSBzZXF1ZW5jZXMgYXJlIGludmFsaWQKCQkJCSRsZW5ndGggPiAxICYmICRjaGFyYWN0ZXIgPD0gMHg3RgoJCQkJfHwgJGxlbmd0aCA+IDIgJiYgJGNoYXJhY3RlciA8PSAweDdGRgoJCQkJfHwgJGxlbmd0aCA+IDMgJiYgJGNoYXJhY3RlciA8PSAweEZGRkYKCQkJCS8vIE91dHNpZGUgb2YgcmFuZ2Ugb2YgdWNzY2hhciBjb2RlcG9pbnRzCgkJCQkvLyBOb25jaGFyYWN0ZXJzCgkJCQl8fCAoJGNoYXJhY3RlciAmIDB4RkZGRSkgPT09IDB4RkZGRQoJCQkJfHwgJGNoYXJhY3RlciA+PSAweEZERDAgJiYgJGNoYXJhY3RlciA8PSAweEZERUYKCQkJCXx8ICgKCQkJCQkvLyBFdmVyeXRoaW5nIGVsc2Ugbm90IGluIHVjc2NoYXIKCQkJCQkkY2hhcmFjdGVyID4gMHhEN0ZGICYmICRjaGFyYWN0ZXIgPCAweEY5MDAKCQkJCQl8fCAkY2hhcmFjdGVyIDwgMHgyMAoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweDdFICYmICRjaGFyYWN0ZXIgPCAweEEwCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4RUZGRkQKCQkJCSkKCQkJKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIFVuaWNvZGUgY29kZXBvaW50JywgJ2lkbmEuaW52YWxpZGNvZGVwb2ludCcsICRjaGFyYWN0ZXIpOwoJCQl9CgoJCQkkY29kZXBvaW50c1tdID0gJGNoYXJhY3RlcjsKCQl9CgoJCXJldHVybiAkY29kZXBvaW50czsKCX0KCgkvKioKCSAqIFJGQzM0OTItY29tcGxpYW50IGVuY29kZXIKCSAqCgkgKiBAaW50ZXJuYWwgUHNldWRvLWNvZGUgZnJvbSBTZWN0aW9uIDYuMyBpcyBjb21tZW50ZWQgd2l0aCAiIyIgbmV4dCB0byByZWxldmFudCBjb2RlCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBjaGFyYWN0ZXIgb3V0c2lkZSBvZiB0aGUgZG9tYWluIChuZXZlciBoYXBwZW5zIHdpdGggUHVueWNvZGUpIChgaWRuYS5jaGFyYWN0ZXJfb3V0c2lkZV9kb21haW5gKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFVURi04IGVuY29kZWQgc3RyaW5nIHRvIGVuY29kZQoJICogQHJldHVybiBzdHJpbmcgUHVueWNvZGUtZW5jb2RlZCBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwdW55Y29kZV9lbmNvZGUoJGlucHV0KSB7CgkJJG91dHB1dCA9ICcnOwoJCS8vIGxldCBuID0gaW5pdGlhbF9uCgkJJG4gPSBzZWxmOjpCT09UU1RSQVBfSU5JVElBTF9OOwoJCS8vIGxldCBkZWx0YSA9IDAKCQkkZGVsdGEgPSAwOwoJCS8vIGxldCBiaWFzID0gaW5pdGlhbF9iaWFzCgkJJGJpYXMgPSBzZWxmOjpCT09UU1RSQVBfSU5JVElBTF9CSUFTOwoJCS8vIGxldCBoID0gYiA9IHRoZSBudW1iZXIgb2YgYmFzaWMgY29kZSBwb2ludHMgaW4gdGhlIGlucHV0CgkJJGggPSAwOwoJCSRiID0gMDsgLy8gc2VlIGxvb3AKCQkvLyBjb3B5IHRoZW0gdG8gdGhlIG91dHB1dCBpbiBvcmRlcgoJCSRjb2RlcG9pbnRzID0gc2VsZjo6dXRmOF90b19jb2RlcG9pbnRzKCRpbnB1dCk7CgkJJGV4dGVuZGVkICAgPSBhcnJheSgpOwoKCQlmb3JlYWNoICgkY29kZXBvaW50cyBhcyAkY2hhcikgewoJCQlpZiAoJGNoYXIgPCAxMjgpIHsKCQkJCS8vIENoYXJhY3RlciBpcyB2YWxpZCBBU0NJSQoJCQkJLy8gVE9ETzogdGhpcyBzaG91bGQgYWxzbyBjaGVjayBpZiBpdCdzIHZhbGlkIGZvciBhIFVSTAoJCQkJJG91dHB1dCAuPSBjaHIoJGNoYXIpOwoJCQkJJGgrKzsKCQkJfQoJCQkvLyBDaGVjayBpZiB0aGUgY2hhcmFjdGVyIGlzIG5vbi1BU0NJSSwgYnV0IGJlbG93IGluaXRpYWwgbgoJCQkvLyBUaGlzIG5ldmVyIG9jY3VycyBmb3IgUHVueWNvZGUsIHNvIGlnbm9yZSBpbiBjb3ZlcmFnZQoJCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKCQkJZWxzZWlmICgkY2hhciA8ICRuKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIGNoYXJhY3RlcicsICdpZG5hLmNoYXJhY3Rlcl9vdXRzaWRlX2RvbWFpbicsICRjaGFyKTsKCQkJfQoJCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlRW5kCgkJCWVsc2UgewoJCQkJJGV4dGVuZGVkWyRjaGFyXSA9IHRydWU7CgkJCX0KCQl9CgkJJGV4dGVuZGVkID0gYXJyYXlfa2V5cygkZXh0ZW5kZWQpOwoJCXNvcnQoJGV4dGVuZGVkKTsKCQkkYiA9ICRoOwoJCS8vIFtjb3B5IHRoZW1dIGZvbGxvd2VkIGJ5IGEgZGVsaW1pdGVyIGlmIGIgPiAwCgkJaWYgKHN0cmxlbigkb3V0cHV0KSA+IDApIHsKCQkJJG91dHB1dCAuPSAnLSc7CgkJfQoJCS8vIHtpZiB0aGUgaW5wdXQgY29udGFpbnMgYSBub24tYmFzaWMgY29kZSBwb2ludCA8IG4gdGhlbiBmYWlsfQoJCS8vIHdoaWxlIGggPCBsZW5ndGgoaW5wdXQpIGRvIGJlZ2luCgkJJGNvZGVwb2ludGNvdW50ID0gY291bnQoJGNvZGVwb2ludHMpOwoJCXdoaWxlICgkaCA8ICRjb2RlcG9pbnRjb3VudCkgewoJCQkvLyBsZXQgbSA9IHRoZSBtaW5pbXVtIGNvZGUgcG9pbnQgPj0gbiBpbiB0aGUgaW5wdXQKCQkJJG0gPSBhcnJheV9zaGlmdCgkZXh0ZW5kZWQpOwoJCQkvL3ByaW50ZignbmV4dCBjb2RlIHBvaW50IHRvIGluc2VydCBpcyAlcycgLiBQSFBfRU9MLCBkZWNoZXgoJG0pKTsKCQkJLy8gbGV0IGRlbHRhID0gZGVsdGEgKyAobSAtIG4pICogKGggKyAxKSwgZmFpbCBvbiBvdmVyZmxvdwoJCQkkZGVsdGEgKz0gKCRtIC0gJG4pICogKCRoICsgMSk7CgkJCS8vIGxldCBuID0gbQoJCQkkbiA9ICRtOwoJCQkvLyBmb3IgZWFjaCBjb2RlIHBvaW50IGMgaW4gdGhlIGlucHV0IChpbiBvcmRlcikgZG8gYmVnaW4KCQkJZm9yICgkbnVtID0gMDsgJG51bSA8ICRjb2RlcG9pbnRjb3VudDsgJG51bSsrKSB7CgkJCQkkYyA9ICRjb2RlcG9pbnRzWyRudW1dOwoJCQkJLy8gaWYgYyA8IG4gdGhlbiBpbmNyZW1lbnQgZGVsdGEsIGZhaWwgb24gb3ZlcmZsb3cKCQkJCWlmICgkYyA8ICRuKSB7CgkJCQkJJGRlbHRhKys7CgkJCQl9CgkJCQkvLyBpZiBjID09IG4gdGhlbiBiZWdpbgoJCQkJZWxzZWlmICgkYyA9PT0gJG4pIHsKCQkJCQkvLyBsZXQgcSA9IGRlbHRhCgkJCQkJJHEgPSAkZGVsdGE7CgkJCQkJLy8gZm9yIGsgPSBiYXNlIHRvIGluZmluaXR5IGluIHN0ZXBzIG9mIGJhc2UgZG8gYmVnaW4KCQkJCQlmb3IgKCRrID0gc2VsZjo6Qk9PVFNUUkFQX0JBU0U7IDsgJGsgKz0gc2VsZjo6Qk9PVFNUUkFQX0JBU0UpIHsKCQkJCQkJLy8gbGV0IHQgPSB0bWluIGlmIGsgPD0gYmlhcyB7KyB0bWlufSwgb3IKCQkJCQkJLy8gICAgIHRtYXggaWYgayA+PSBiaWFzICsgdG1heCwgb3IgayAtIGJpYXMgb3RoZXJ3aXNlCgkJCQkJCWlmICgkayA8PSAoJGJpYXMgKyBzZWxmOjpCT09UU1RSQVBfVE1JTikpIHsKCQkJCQkJCSR0ID0gc2VsZjo6Qk9PVFNUUkFQX1RNSU47CgkJCQkJCX0KCQkJCQkJZWxzZWlmICgkayA+PSAoJGJpYXMgKyBzZWxmOjpCT09UU1RSQVBfVE1BWCkpIHsKCQkJCQkJCSR0ID0gc2VsZjo6Qk9PVFNUUkFQX1RNQVg7CgkJCQkJCX0KCQkJCQkJZWxzZSB7CgkJCQkJCQkkdCA9ICRrIC0gJGJpYXM7CgkJCQkJCX0KCQkJCQkJLy8gaWYgcSA8IHQgdGhlbiBicmVhawoJCQkJCQlpZiAoJHEgPCAkdCkgewoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQkJLy8gb3V0cHV0IHRoZSBjb2RlIHBvaW50IGZvciBkaWdpdCB0ICsgKChxIC0gdCkgbW9kIChiYXNlIC0gdCkpCgkJCQkJCSRkaWdpdCAgID0gJHQgKyAoKCRxIC0gJHQpICUgKHNlbGY6OkJPT1RTVFJBUF9CQVNFIC0gJHQpKTsKCQkJCQkJJG91dHB1dCAuPSBzZWxmOjpkaWdpdF90b19jaGFyKCRkaWdpdCk7CgkJCQkJCS8vIGxldCBxID0gKHEgLSB0KSBkaXYgKGJhc2UgLSB0KQoJCQkJCQkkcSA9IGZsb29yKCgkcSAtICR0KSAvIChzZWxmOjpCT09UU1RSQVBfQkFTRSAtICR0KSk7CgkJCQkJfSAvLyBlbmQKCQkJCQkvLyBvdXRwdXQgdGhlIGNvZGUgcG9pbnQgZm9yIGRpZ2l0IHEKCQkJCQkkb3V0cHV0IC49IHNlbGY6OmRpZ2l0X3RvX2NoYXIoJHEpOwoJCQkJCS8vIGxldCBiaWFzID0gYWRhcHQoZGVsdGEsIGggKyAxLCB0ZXN0IGggZXF1YWxzIGI/KQoJCQkJCSRiaWFzID0gc2VsZjo6YWRhcHQoJGRlbHRhLCAkaCArIDEsICRoID09PSAkYik7CgkJCQkJLy8gbGV0IGRlbHRhID0gMAoJCQkJCSRkZWx0YSA9IDA7CgkJCQkJLy8gaW5jcmVtZW50IGgKCQkJCQkkaCsrOwoJCQkJfSAvLyBlbmQKCQkJfSAvLyBlbmQKCQkJLy8gaW5jcmVtZW50IGRlbHRhIGFuZCBuCgkJCSRkZWx0YSsrOwoJCQkkbisrOwoJCX0gLy8gZW5kCgoJCXJldHVybiAkb3V0cHV0OwoJfQoKCS8qKgoJICogQ29udmVydCBhIGRpZ2l0IHRvIGl0cyByZXNwZWN0aXZlIGNoYXJhY3RlcgoJICoKCSAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTIjc2VjdGlvbi01CgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBpbnZhbGlkIGRpZ2l0IChgaWRuYS5pbnZhbGlkX2RpZ2l0YCkKCSAqCgkgKiBAcGFyYW0gaW50ICRkaWdpdCBEaWdpdCBpbiB0aGUgcmFuZ2UgMC0zNQoJICogQHJldHVybiBzdHJpbmcgU2luZ2xlIGNoYXJhY3RlciBjb3JyZXNwb25kaW5nIHRvIGRpZ2l0CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZGlnaXRfdG9fY2hhcigkZGlnaXQpIHsKCQkvLyBAY29kZUNvdmVyYWdlSWdub3JlU3RhcnQKCQkvLyBBcyBmYXIgYXMgSSBrbm93LCB0aGlzIG5ldmVyIGhhcHBlbnMsIGJ1dCBzdGlsbCBnb29kIHRvIGJlIHN1cmUuCgkJaWYgKCRkaWdpdCA8IDAgfHwgJGRpZ2l0ID4gMzUpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbihzcHJpbnRmKCdJbnZhbGlkIGRpZ2l0ICVkJywgJGRpZ2l0KSwgJ2lkbmEuaW52YWxpZF9kaWdpdCcsICRkaWdpdCk7CgkJfQoJCS8vIEBjb2RlQ292ZXJhZ2VJZ25vcmVFbmQKCQkkZGlnaXRzID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7CgkJcmV0dXJuIHN1YnN0cigkZGlnaXRzLCAkZGlnaXQsIDEpOwoJfQoKCS8qKgoJICogQWRhcHQgdGhlIGJpYXMKCSAqCgkgKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNDkyI3NlY3Rpb24tNi4xCgkgKiBAcGFyYW0gaW50ICRkZWx0YQoJICogQHBhcmFtIGludCAkbnVtcG9pbnRzCgkgKiBAcGFyYW0gYm9vbCAkZmlyc3R0aW1lCgkgKiBAcmV0dXJuIGludCBOZXcgYmlhcwoJICoKCSAqIGZ1bmN0aW9uIGFkYXB0KGRlbHRhLG51bXBvaW50cyxmaXJzdHRpbWUpOgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGFkYXB0KCRkZWx0YSwgJG51bXBvaW50cywgJGZpcnN0dGltZSkgewoJCS8vIGlmIGZpcnN0dGltZSB0aGVuIGxldCBkZWx0YSA9IGRlbHRhIGRpdiBkYW1wCgkJaWYgKCRmaXJzdHRpbWUpIHsKCQkJJGRlbHRhID0gZmxvb3IoJGRlbHRhIC8gc2VsZjo6Qk9PVFNUUkFQX0RBTVApOwoJCX0KCQkvLyBlbHNlIGxldCBkZWx0YSA9IGRlbHRhIGRpdiAyCgkJZWxzZSB7CgkJCSRkZWx0YSA9IGZsb29yKCRkZWx0YSAvIDIpOwoJCX0KCQkvLyBsZXQgZGVsdGEgPSBkZWx0YSArIChkZWx0YSBkaXYgbnVtcG9pbnRzKQoJCSRkZWx0YSArPSBmbG9vcigkZGVsdGEgLyAkbnVtcG9pbnRzKTsKCQkvLyBsZXQgayA9IDAKCQkkayA9IDA7CgkJLy8gd2hpbGUgZGVsdGEgPiAoKGJhc2UgLSB0bWluKSAqIHRtYXgpIGRpdiAyIGRvIGJlZ2luCgkJJG1heCA9IGZsb29yKCgoc2VsZjo6Qk9PVFNUUkFQX0JBU0UgLSBzZWxmOjpCT09UU1RSQVBfVE1JTikgKiBzZWxmOjpCT09UU1RSQVBfVE1BWCkgLyAyKTsKCQl3aGlsZSAoJGRlbHRhID4gJG1heCkgewoJCQkvLyBsZXQgZGVsdGEgPSBkZWx0YSBkaXYgKGJhc2UgLSB0bWluKQoJCQkkZGVsdGEgPSBmbG9vcigkZGVsdGEgLyAoc2VsZjo6Qk9PVFNUUkFQX0JBU0UgLSBzZWxmOjpCT09UU1RSQVBfVE1JTikpOwoJCQkvLyBsZXQgayA9IGsgKyBiYXNlCgkJCSRrICs9IHNlbGY6OkJPT1RTVFJBUF9CQVNFOwoJCX0gLy8gZW5kCgkJLy8gcmV0dXJuIGsgKyAoKChiYXNlIC0gdG1pbiArIDEpICogZGVsdGEpIGRpdiAoZGVsdGEgKyBza2V3KSkKCQlyZXR1cm4gJGsgKyBmbG9vcigoKHNlbGY6OkJPT1RTVFJBUF9CQVNFIC0gc2VsZjo6Qk9PVFNUUkFQX1RNSU4gKyAxKSAqICRkZWx0YSkgLyAoJGRlbHRhICsgc2VsZjo6Qk9PVFNUUkFQX1NLRVcpKTsKCX0KfQo8P3BocAovKioKICogQmFzaWMgQXV0aGVudGljYXRpb24gcHJvdmlkZXIKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQXV0aGVudGljYXRpb24KICovCgovKioKICogQmFzaWMgQXV0aGVudGljYXRpb24gcHJvdmlkZXIKICoKICogUHJvdmlkZXMgYSBoYW5kbGVyIGZvciBCYXNpYyBIVFRQIGF1dGhlbnRpY2F0aW9uIHZpYSB0aGUgQXV0aG9yaXphdGlvbgogKiBoZWFkZXIuCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIEF1dGhlbnRpY2F0aW9uCiAqLwpjbGFzcyBSZXF1ZXN0c19BdXRoX0Jhc2ljIGltcGxlbWVudHMgUmVxdWVzdHNfQXV0aCB7CgkvKioKCSAqIFVzZXJuYW1lCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR1c2VyOwoKCS8qKgoJICogUGFzc3dvcmQKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHBhc3M7CgoJLyoqCgkgKiBDb25zdHJ1Y3RvcgoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGluY29ycmVjdCBudW1iZXIgb2YgYXJndW1lbnRzIChgYXV0aGJhc2ljYmFkYXJnc2ApCgkgKiBAcGFyYW0gYXJyYXl8bnVsbCAkYXJncyBBcnJheSBvZiB1c2VyIGFuZCBwYXNzd29yZC4gTXVzdCBoYXZlIGV4YWN0bHkgdHdvIGVsZW1lbnRzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYXJncyA9IG51bGwpIHsKCQlpZiAoaXNfYXJyYXkoJGFyZ3MpKSB7CgkJCWlmIChjb3VudCgkYXJncykgIT09IDIpIHsKCQkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ0ludmFsaWQgbnVtYmVyIG9mIGFyZ3VtZW50cycsICdhdXRoYmFzaWNiYWRhcmdzJyk7CgkJCX0KCgkJCWxpc3QoJHRoaXMtPnVzZXIsICR0aGlzLT5wYXNzKSA9ICRhcmdzOwoJCX0KCX0KCgkvKioKCSAqIFJlZ2lzdGVyIHRoZSBuZWNlc3NhcnkgY2FsbGJhY2tzCgkgKgoJICogQHNlZSBjdXJsX2JlZm9yZV9zZW5kCgkgKiBAc2VlIGZzb2Nrb3Blbl9oZWFkZXIKCSAqIEBwYXJhbSBSZXF1ZXN0c19Ib29rcyAkaG9va3MgSG9vayBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tzICRob29rcykgewoJCSRob29rcy0+cmVnaXN0ZXIoJ2N1cmwuYmVmb3JlX3NlbmQnLCBhcnJheSgkdGhpcywgJ2N1cmxfYmVmb3JlX3NlbmQnKSk7CgkJJGhvb2tzLT5yZWdpc3RlcignZnNvY2tvcGVuLmFmdGVyX2hlYWRlcnMnLCBhcnJheSgkdGhpcywgJ2Zzb2Nrb3Blbl9oZWFkZXInKSk7Cgl9CgoJLyoqCgkgKiBTZXQgY1VSTCBwYXJhbWV0ZXJzIGJlZm9yZSB0aGUgZGF0YSBpcyBzZW50CgkgKgoJICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUgY1VSTCByZXNvdXJjZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY3VybF9iZWZvcmVfc2VuZCgmJGhhbmRsZSkgewoJCWN1cmxfc2V0b3B0KCRoYW5kbGUsIENVUkxPUFRfSFRUUEFVVEgsIENVUkxBVVRIX0JBU0lDKTsKCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1VTRVJQV0QsICR0aGlzLT5nZXRBdXRoU3RyaW5nKCkpOwoJfQoKCS8qKgoJICogQWRkIGV4dHJhIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3QgYmVmb3JlIHNlbmRpbmcKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRvdXQgSFRUUCBoZWFkZXIgc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmc29ja29wZW5faGVhZGVyKCYkb3V0KSB7CgkJJG91dCAuPSBzcHJpbnRmKCJBdXRob3JpemF0aW9uOiBCYXNpYyAlc1xyXG4iLCBiYXNlNjRfZW5jb2RlKCR0aGlzLT5nZXRBdXRoU3RyaW5nKCkpKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgYXV0aGVudGljYXRpb24gc3RyaW5nICh1c2VyOnBhc3MpCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEF1dGhTdHJpbmcoKSB7CgkJcmV0dXJuICR0aGlzLT51c2VyIC4gJzonIC4gJHRoaXMtPnBhc3M7Cgl9Cn0KPD9waHAKLyoqCiAqIFByb3h5IGNvbm5lY3Rpb24gaW50ZXJmYWNlCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFByb3h5CiAqIEBzaW5jZSAxLjYKICovCgovKioKICogUHJveHkgY29ubmVjdGlvbiBpbnRlcmZhY2UKICoKICogSW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIHRvIGhhbmRsZSBwcm94eSBzZXR0aW5ncyBhbmQgYXV0aGVudGljYXRpb24KICoKICogUGFyYW1ldGVycyBzaG91bGQgYmUgcGFzc2VkIHZpYSB0aGUgY29uc3RydWN0b3Igd2hlcmUgcG9zc2libGUsIGFzIHRoaXMKICogbWFrZXMgaXQgbXVjaCBlYXNpZXIgZm9yIHVzZXJzIHRvIHVzZSB5b3VyIHByb3ZpZGVyLgogKgogKiBAc2VlIFJlcXVlc3RzX0hvb2tzCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFByb3h5CiAqIEBzaW5jZSAxLjYKICovCmludGVyZmFjZSBSZXF1ZXN0c19Qcm94eSB7CgkvKioKCSAqIFJlZ2lzdGVyIGhvb2tzIGFzIG5lZWRlZAoJICoKCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBpbiB7QHNlZSBSZXF1ZXN0czo6cmVxdWVzdH0gd2hlbiB0aGUgdXNlciBoYXMgc2V0CgkgKiBhbiBpbnN0YW5jZSBhcyB0aGUgJ2F1dGgnIG9wdGlvbi4gVXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVnaXN0ZXIgYWxsIHRoZQoJICogaG9va3MgeW91J2xsIG5lZWQuCgkgKgoJICogQHNlZSBSZXF1ZXN0c19Ib29rczo6cmVnaXN0ZXIKCSAqIEBwYXJhbSBSZXF1ZXN0c19Ib29rcyAkaG9va3MgSG9vayBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tzICRob29rcyk7Cn0KPD9waHAKLyoqCiAqIENsYXNzIHRvIHZhbGlkYXRlIGFuZCB0byB3b3JrIHdpdGggSVB2NiBhZGRyZXNzZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwoKLyoqCiAqIENsYXNzIHRvIHZhbGlkYXRlIGFuZCB0byB3b3JrIHdpdGggSVB2NiBhZGRyZXNzZXMKICoKICogVGhpcyB3YXMgb3JpZ2luYWxseSBiYXNlZCBvbiB0aGUgUEVBUiBjbGFzcyBvZiB0aGUgc2FtZSBuYW1lLCBidXQgaGFzIGJlZW4KICogZW50aXJlbHkgcmV3cml0dGVuLgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCmNsYXNzIFJlcXVlc3RzX0lQdjYgewoJLyoqCgkgKiBVbmNvbXByZXNzZXMgYW4gSVB2NiBhZGRyZXNzCgkgKgoJICogUkZDIDQyOTEgYWxsb3dzIHlvdSB0byBjb21wcmVzcyBjb25zZWN1dGl2ZSB6ZXJvIHBpZWNlcyBpbiBhbiBhZGRyZXNzIHRvCgkgKiAnOjonLiBUaGlzIG1ldGhvZCBleHBlY3RzIGEgdmFsaWQgSVB2NiBhZGRyZXNzIGFuZCBleHBhbmRzIHRoZSAnOjonIHRvCgkgKiB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIHplcm8gcGllY2VzLgoJICoKCSAqIEV4YW1wbGU6ICBGRjAxOjoxMDEgICAtPiAgRkYwMTowOjA6MDowOjA6MDoxMDEKCSAqICAgICAgICAgICA6OjEgICAgICAgICAtPiAgMDowOjA6MDowOjA6MDoxCgkgKgoJICogQGF1dGhvciBBbGV4YW5kZXIgTWVyeiA8YWxleGFuZGVyLm1lcnpAd2ViLmRlPgoJICogQGF1dGhvciBlbGZyaW5rIGF0IGludHJvd2ViIGRvdCBubAoJICogQGF1dGhvciBKb3NoIFBlY2sgPGptcCBhdCBqb3NocGVjayBkb3Qgb3JnPgoJICogQGNvcHlyaWdodCAyMDAzLTIwMDUgVGhlIFBIUCBHcm91cAoJICogQGxpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9ic2QtbGljZW5zZS5waHAKCSAqIEBwYXJhbSBzdHJpbmcgJGlwIEFuIElQdjYgYWRkcmVzcwoJICogQHJldHVybiBzdHJpbmcgVGhlIHVuY29tcHJlc3NlZCBJUHY2IGFkZHJlc3MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1bmNvbXByZXNzKCRpcCkgewoJCWlmIChzdWJzdHJfY291bnQoJGlwLCAnOjonKSAhPT0gMSkgewoJCQlyZXR1cm4gJGlwOwoJCX0KCgkJbGlzdCgkaXAxLCAkaXAyKSA9IGV4cGxvZGUoJzo6JywgJGlwKTsKCQkkYzEgICAgICAgICAgICAgID0gKCRpcDEgPT09ICcnKSA/IC0xIDogc3Vic3RyX2NvdW50KCRpcDEsICc6Jyk7CgkJJGMyICAgICAgICAgICAgICA9ICgkaXAyID09PSAnJykgPyAtMSA6IHN1YnN0cl9jb3VudCgkaXAyLCAnOicpOwoKCQlpZiAoc3RycG9zKCRpcDIsICcuJykgIT09IGZhbHNlKSB7CgkJCSRjMisrOwoJCX0KCQkvLyA6OgoJCWlmICgkYzEgPT09IC0xICYmICRjMiA9PT0gLTEpIHsKCQkJJGlwID0gJzA6MDowOjA6MDowOjA6MCc7CgkJfQoJCS8vIDo6eHh4CgkJZWxzZWlmICgkYzEgPT09IC0xKSB7CgkJCSRmaWxsID0gc3RyX3JlcGVhdCgnMDonLCA3IC0gJGMyKTsKCQkJJGlwICAgPSBzdHJfcmVwbGFjZSgnOjonLCAkZmlsbCwgJGlwKTsKCQl9CgkJLy8geHh4OjoKCQllbHNlaWYgKCRjMiA9PT0gLTEpIHsKCQkJJGZpbGwgPSBzdHJfcmVwZWF0KCc6MCcsIDcgLSAkYzEpOwoJCQkkaXAgICA9IHN0cl9yZXBsYWNlKCc6OicsICRmaWxsLCAkaXApOwoJCX0KCQkvLyB4eHg6Onh4eAoJCWVsc2UgewoJCQkkZmlsbCA9ICc6JyAuIHN0cl9yZXBlYXQoJzA6JywgNiAtICRjMiAtICRjMSk7CgkJCSRpcCAgID0gc3RyX3JlcGxhY2UoJzo6JywgJGZpbGwsICRpcCk7CgkJfQoJCXJldHVybiAkaXA7Cgl9CgoJLyoqCgkgKiBDb21wcmVzc2VzIGFuIElQdjYgYWRkcmVzcwoJICoKCSAqIFJGQyA0MjkxIGFsbG93cyB5b3UgdG8gY29tcHJlc3MgY29uc2VjdXRpdmUgemVybyBwaWVjZXMgaW4gYW4gYWRkcmVzcyB0bwoJICogJzo6Jy4gVGhpcyBtZXRob2QgZXhwZWN0cyBhIHZhbGlkIElQdjYgYWRkcmVzcyBhbmQgY29tcHJlc3NlcyBjb25zZWN1dGl2ZQoJICogemVybyBwaWVjZXMgdG8gJzo6Jy4KCSAqCgkgKiBFeGFtcGxlOiAgRkYwMTowOjA6MDowOjA6MDoxMDEgICAtPiAgRkYwMTo6MTAxCgkgKiAgICAgICAgICAgMDowOjA6MDowOjA6MDoxICAgICAgICAtPiAgOjoxCgkgKgoJICogQHNlZSB1bmNvbXByZXNzKCkKCSAqIEBwYXJhbSBzdHJpbmcgJGlwIEFuIElQdjYgYWRkcmVzcwoJICogQHJldHVybiBzdHJpbmcgVGhlIGNvbXByZXNzZWQgSVB2NiBhZGRyZXNzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29tcHJlc3MoJGlwKSB7CgkJLy8gUHJlcGFyZSB0aGUgSVAgdG8gYmUgY29tcHJlc3NlZAoJCSRpcCAgICAgICA9IHNlbGY6OnVuY29tcHJlc3MoJGlwKTsKCQkkaXBfcGFydHMgPSBzZWxmOjpzcGxpdF92Nl92NCgkaXApOwoKCQkvLyBSZXBsYWNlIGFsbCBsZWFkaW5nIHplcm9zCgkJJGlwX3BhcnRzWzBdID0gcHJlZ19yZXBsYWNlKCcvKF58OikwKyhbMC05XSkvJywgJ1wxXDInLCAkaXBfcGFydHNbMF0pOwoKCQkvLyBGaW5kIGJ1bmNoZXMgb2YgemVyb3MKCQlpZiAocHJlZ19tYXRjaF9hbGwoJy8oPzpefDopKD86MCg/Ojp8JCkpKy8nLCAkaXBfcGFydHNbMF0sICRtYXRjaGVzLCBQUkVHX09GRlNFVF9DQVBUVVJFKSkgewoJCQkkbWF4ID0gMDsKCQkJJHBvcyA9IG51bGw7CgkJCWZvcmVhY2ggKCRtYXRjaGVzWzBdIGFzICRtYXRjaCkgewoJCQkJaWYgKHN0cmxlbigkbWF0Y2hbMF0pID4gJG1heCkgewoJCQkJCSRtYXggPSBzdHJsZW4oJG1hdGNoWzBdKTsKCQkJCQkkcG9zID0gJG1hdGNoWzFdOwoJCQkJfQoJCQl9CgoJCQkkaXBfcGFydHNbMF0gPSBzdWJzdHJfcmVwbGFjZSgkaXBfcGFydHNbMF0sICc6OicsICRwb3MsICRtYXgpOwoJCX0KCgkJaWYgKCRpcF9wYXJ0c1sxXSAhPT0gJycpIHsKCQkJcmV0dXJuIGltcGxvZGUoJzonLCAkaXBfcGFydHMpOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuICRpcF9wYXJ0c1swXTsKCQl9Cgl9CgoJLyoqCgkgKiBTcGxpdHMgYW4gSVB2NiBhZGRyZXNzIGludG8gdGhlIElQdjYgYW5kIElQdjQgcmVwcmVzZW50YXRpb24gcGFydHMKCSAqCgkgKiBSRkMgNDI5MSBhbGxvd3MgeW91IHRvIHJlcHJlc2VudCB0aGUgbGFzdCB0d28gcGFydHMgb2YgYW4gSVB2NiBhZGRyZXNzCgkgKiB1c2luZyB0aGUgc3RhbmRhcmQgSVB2NCByZXByZXNlbnRhdGlvbgoJICoKCSAqIEV4YW1wbGU6ICAwOjA6MDowOjA6MDoxMy4xLjY4LjMKCSAqICAgICAgICAgICAwOjA6MDowOjA6RkZGRjoxMjkuMTQ0LjUyLjM4CgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXAgQW4gSVB2NiBhZGRyZXNzCgkgKiBAcmV0dXJuIHN0cmluZ1tdIFswXSBjb250YWlucyB0aGUgSVB2NiByZXByZXNlbnRlZCBwYXJ0LCBhbmQgWzFdIHRoZSBJUHY0IHJlcHJlc2VudGVkIHBhcnQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzcGxpdF92Nl92NCgkaXApIHsKCQlpZiAoc3RycG9zKCRpcCwgJy4nKSAhPT0gZmFsc2UpIHsKCQkJJHBvcyAgICAgICA9IHN0cnJwb3MoJGlwLCAnOicpOwoJCQkkaXB2Nl9wYXJ0ID0gc3Vic3RyKCRpcCwgMCwgJHBvcyk7CgkJCSRpcHY0X3BhcnQgPSBzdWJzdHIoJGlwLCAkcG9zICsgMSk7CgkJCXJldHVybiBhcnJheSgkaXB2Nl9wYXJ0LCAkaXB2NF9wYXJ0KTsKCQl9CgkJZWxzZSB7CgkJCXJldHVybiBhcnJheSgkaXAsICcnKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3MgYW4gSVB2NiBhZGRyZXNzCgkgKgoJICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBJUCBpcyBhIHZhbGlkIElQdjYgYWRkcmVzcwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlwIEFuIElQdjYgYWRkcmVzcwoJICogQHJldHVybiBib29sIHRydWUgaWYgJGlwIGlzIGEgdmFsaWQgSVB2NiBhZGRyZXNzCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2hlY2tfaXB2NigkaXApIHsKCQkkaXAgICAgICAgICAgICAgICAgPSBzZWxmOjp1bmNvbXByZXNzKCRpcCk7CgkJbGlzdCgkaXB2NiwgJGlwdjQpID0gc2VsZjo6c3BsaXRfdjZfdjQoJGlwKTsKCQkkaXB2NiAgICAgICAgICAgICAgPSBleHBsb2RlKCc6JywgJGlwdjYpOwoJCSRpcHY0ICAgICAgICAgICAgICA9IGV4cGxvZGUoJy4nLCAkaXB2NCk7CgkJaWYgKGNvdW50KCRpcHY2KSA9PT0gOCAmJiBjb3VudCgkaXB2NCkgPT09IDEgfHwgY291bnQoJGlwdjYpID09PSA2ICYmIGNvdW50KCRpcHY0KSA9PT0gNCkgewoJCQlmb3JlYWNoICgkaXB2NiBhcyAkaXB2Nl9wYXJ0KSB7CgkJCQkvLyBUaGUgc2VjdGlvbiBjYW4ndCBiZSBlbXB0eQoJCQkJaWYgKCRpcHY2X3BhcnQgPT09ICcnKSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoKCQkJCS8vIE5vciBjYW4gaXQgYmUgb3ZlciBmb3VyIGNoYXJhY3RlcnMKCQkJCWlmIChzdHJsZW4oJGlwdjZfcGFydCkgPiA0KSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoKCQkJCS8vIFJlbW92ZSBsZWFkaW5nIHplcm9zICh0aGlzIGlzIHNhZmUgYmVjYXVzZSBvZiB0aGUgYWJvdmUpCgkJCQkkaXB2Nl9wYXJ0ID0gbHRyaW0oJGlwdjZfcGFydCwgJzAnKTsKCQkJCWlmICgkaXB2Nl9wYXJ0ID09PSAnJykgewoJCQkJCSRpcHY2X3BhcnQgPSAnMCc7CgkJCQl9CgoJCQkJLy8gQ2hlY2sgdGhlIHZhbHVlIGlzIHZhbGlkCgkJCQkkdmFsdWUgPSBoZXhkZWMoJGlwdjZfcGFydCk7CgkJCQlpZiAoZGVjaGV4KCR2YWx1ZSkgIT09IHN0cnRvbG93ZXIoJGlwdjZfcGFydCkgfHwgJHZhbHVlIDwgMCB8fCAkdmFsdWUgPiAweEZGRkYpIHsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0KCQkJaWYgKGNvdW50KCRpcHY0KSA9PT0gNCkgewoJCQkJZm9yZWFjaCAoJGlwdjQgYXMgJGlwdjRfcGFydCkgewoJCQkJCSR2YWx1ZSA9IChpbnQpICRpcHY0X3BhcnQ7CgkJCQkJaWYgKChzdHJpbmcpICR2YWx1ZSAhPT0gJGlwdjRfcGFydCB8fCAkdmFsdWUgPCAwIHx8ICR2YWx1ZSA+IDB4RkYpIHsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJZWxzZSB7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9Cn0KPD9waHAKLyoqCiAqIENvb2tpZSBob2xkZXIgb2JqZWN0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIENvb2tpZXMKICovCgovKioKICogQ29va2llIGhvbGRlciBvYmplY3QKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQ29va2llcwogKi8KY2xhc3MgUmVxdWVzdHNfQ29va2llX0phciBpbXBsZW1lbnRzIEFycmF5QWNjZXNzLCBJdGVyYXRvckFnZ3JlZ2F0ZSB7CgkvKioKCSAqIEFjdHVhbCBpdGVtIGRhdGEKCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkY29va2llcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgamFyCgkgKgoJICogQHBhcmFtIGFycmF5ICRjb29raWVzIEV4aXN0aW5nIGNvb2tpZSB2YWx1ZXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb29raWVzID0gYXJyYXkoKSkgewoJCSR0aGlzLT5jb29raWVzID0gJGNvb2tpZXM7Cgl9CgoJLyoqCgkgKiBOb3JtYWxpc2UgY29va2llIGRhdGEgaW50byBhIFJlcXVlc3RzX0Nvb2tpZQoJICoKCSAqIEBwYXJhbSBzdHJpbmd8UmVxdWVzdHNfQ29va2llICRjb29raWUKCSAqIEByZXR1cm4gUmVxdWVzdHNfQ29va2llCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkgPSBudWxsKSB7CgkJaWYgKCRjb29raWUgaW5zdGFuY2VvZiBSZXF1ZXN0c19Db29raWUpIHsKCQkJcmV0dXJuICRjb29raWU7CgkJfQoKCQlyZXR1cm4gUmVxdWVzdHNfQ29va2llOjpwYXJzZSgkY29va2llLCAka2V5KTsKCX0KCgkvKioKCSAqIE5vcm1hbGlzZSBjb29raWUgZGF0YSBpbnRvIGEgUmVxdWVzdHNfQ29va2llCgkgKgoJICogQGNvZGVDb3ZlcmFnZUlnbm9yZQoJICogQGRlcHJlY2F0ZWQgVXNlIHtAc2VlIFJlcXVlc3RzX0Nvb2tpZV9KYXI6Om5vcm1hbGl6ZV9jb29raWV9CgkgKiBAcmV0dXJuIFJlcXVlc3RzX0Nvb2tpZQoJICovCglwdWJsaWMgZnVuY3Rpb24gbm9ybWFsaXplQ29va2llKCRjb29raWUsICRrZXkgPSBudWxsKSB7CgkJcmV0dXJuICR0aGlzLT5ub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkpOwoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIGdpdmVuIGl0ZW0gZXhpc3RzCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIGJvb2xlYW4gRG9lcyB0aGUgaXRlbSBleGlzdD8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldEV4aXN0cygka2V5KSB7CgkJcmV0dXJuIGlzc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBpdGVtCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5IEl0ZW0ga2V5CgkgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEl0ZW0gdmFsdWUgKG51bGwgaWYgb2Zmc2V0RXhpc3RzIGlzIGZhbHNlKQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0R2V0KCRrZXkpIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAkdGhpcy0+Y29va2llc1ska2V5XTsKCX0KCgkvKioKCSAqIFNldCB0aGUgZ2l2ZW4gaXRlbQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGF0dGVtcHRpbmcgdG8gdXNlIGRpY3Rpb25hcnkgYXMgbGlzdCAoYGludmFsaWRzZXRgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBJdGVtIG5hbWUKCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIEl0ZW0gdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgka2V5LCAkdmFsdWUpIHsKCQlpZiAoJGtleSA9PT0gbnVsbCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdPYmplY3QgaXMgYSBkaWN0aW9uYXJ5LCBub3QgYSBsaXN0JywgJ2ludmFsaWRzZXQnKTsKCQl9CgoJCSR0aGlzLT5jb29raWVzWyRrZXldID0gJHZhbHVlOwoJfQoKCS8qKgoJICogVW5zZXQgdGhlIGdpdmVuIGhlYWRlcgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0VW5zZXQoJGtleSkgewoJCXVuc2V0KCR0aGlzLT5jb29raWVzWyRrZXldKTsKCX0KCgkvKioKCSAqIEdldCBhbiBpdGVyYXRvciBmb3IgdGhlIGRhdGEKCSAqCgkgKiBAcmV0dXJuIEFycmF5SXRlcmF0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkgewoJCXJldHVybiBuZXcgQXJyYXlJdGVyYXRvcigkdGhpcy0+Y29va2llcyk7Cgl9CgoJLyoqCgkgKiBSZWdpc3RlciB0aGUgY29va2llIGhhbmRsZXIgd2l0aCB0aGUgcmVxdWVzdCdzIGhvb2tpbmcgc3lzdGVtCgkgKgoJICogQHBhcmFtIFJlcXVlc3RzX0hvb2tlciAkaG9va3MgSG9va2luZyBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tlciAkaG9va3MpIHsKCQkkaG9va3MtPnJlZ2lzdGVyKCdyZXF1ZXN0cy5iZWZvcmVfcmVxdWVzdCcsIGFycmF5KCR0aGlzLCAnYmVmb3JlX3JlcXVlc3QnKSk7CgkJJGhvb2tzLT5yZWdpc3RlcigncmVxdWVzdHMuYmVmb3JlX3JlZGlyZWN0X2NoZWNrJywgYXJyYXkoJHRoaXMsICdiZWZvcmVfcmVkaXJlY3RfY2hlY2snKSk7Cgl9CgoJLyoqCgkgKiBBZGQgQ29va2llIGhlYWRlciB0byBhIHJlcXVlc3QgaWYgd2UgaGF2ZSBhbnkKCSAqCgkgKiBBcyBwZXIgUkZDIDYyNjUsIGNvb2tpZXMgYXJlIHNlcGFyYXRlZCBieSAnOyAnCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMKCSAqIEBwYXJhbSBhcnJheSAkZGF0YQoJICogQHBhcmFtIHN0cmluZyAkdHlwZQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBiZWZvcmVfcmVxdWVzdCgkdXJsLCAmJGhlYWRlcnMsICYkZGF0YSwgJiR0eXBlLCAmJG9wdGlvbnMpIHsKCQlpZiAoISR1cmwgaW5zdGFuY2VvZiBSZXF1ZXN0c19JUkkpIHsKCQkJJHVybCA9IG5ldyBSZXF1ZXN0c19JUkkoJHVybCk7CgkJfQoKCQlpZiAoIWVtcHR5KCR0aGlzLT5jb29raWVzKSkgewoJCQkkY29va2llcyA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCR0aGlzLT5jb29raWVzIGFzICRrZXkgPT4gJGNvb2tpZSkgewoJCQkJJGNvb2tpZSA9ICR0aGlzLT5ub3JtYWxpemVfY29va2llKCRjb29raWUsICRrZXkpOwoKCQkJCS8vIFNraXAgZXhwaXJlZCBjb29raWVzCgkJCQlpZiAoJGNvb2tpZS0+aXNfZXhwaXJlZCgpKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCRjb29raWUtPmRvbWFpbl9tYXRjaGVzKCR1cmwtPmhvc3QpKSB7CgkJCQkJJGNvb2tpZXNbXSA9ICRjb29raWUtPmZvcm1hdF9mb3JfaGVhZGVyKCk7CgkJCQl9CgkJCX0KCgkJCSRoZWFkZXJzWydDb29raWUnXSA9IGltcGxvZGUoJzsgJywgJGNvb2tpZXMpOwoJCX0KCX0KCgkvKioKCSAqIFBhcnNlIGFsbCBjb29raWVzIGZyb20gYSByZXNwb25zZSBhbmQgYXR0YWNoIHRoZW0gdG8gdGhlIHJlc3BvbnNlCgkgKgoJICogQHZhciBSZXF1ZXN0c19SZXNwb25zZSAkcmVzcG9uc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGJlZm9yZV9yZWRpcmVjdF9jaGVjayhSZXF1ZXN0c19SZXNwb25zZSAkcmV0dXJuKSB7CgkJJHVybCA9ICRyZXR1cm4tPnVybDsKCQlpZiAoISR1cmwgaW5zdGFuY2VvZiBSZXF1ZXN0c19JUkkpIHsKCQkJJHVybCA9IG5ldyBSZXF1ZXN0c19JUkkoJHVybCk7CgkJfQoKCQkkY29va2llcyAgICAgICAgID0gUmVxdWVzdHNfQ29va2llOjpwYXJzZV9mcm9tX2hlYWRlcnMoJHJldHVybi0+aGVhZGVycywgJHVybCk7CgkJJHRoaXMtPmNvb2tpZXMgICA9IGFycmF5X21lcmdlKCR0aGlzLT5jb29raWVzLCAkY29va2llcyk7CgkJJHJldHVybi0+Y29va2llcyA9ICR0aGlzOwoJfQp9Cjw/cGhwCi8qKgogKiBDb29raWUgc3RvcmFnZSBvYmplY3QKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQ29va2llcwogKi8KCi8qKgogKiBDb29raWUgc3RvcmFnZSBvYmplY3QKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQ29va2llcwogKi8KY2xhc3MgUmVxdWVzdHNfQ29va2llIHsKCS8qKgoJICogQ29va2llIG5hbWUuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRuYW1lOwoKCS8qKgoJICogQ29va2llIHZhbHVlLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXB1YmxpYyAkdmFsdWU7CgoJLyoqCgkgKiBDb29raWUgYXR0cmlidXRlcwoJICoKCSAqIFZhbGlkIGtleXMgYXJlIChjdXJyZW50bHkpIHBhdGgsIGRvbWFpbiwgZXhwaXJlcywgbWF4LWFnZSwgc2VjdXJlIGFuZAoJICogaHR0cG9ubHkuCgkgKgoJICogQHZhciBSZXF1ZXN0c19VdGlsaXR5X0Nhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnl8YXJyYXkgQXJyYXktbGlrZSBvYmplY3QKCSAqLwoJcHVibGljICRhdHRyaWJ1dGVzID0gYXJyYXkoKTsKCgkvKioKCSAqIENvb2tpZSBmbGFncwoJICoKCSAqIFZhbGlkIGtleXMgYXJlIChjdXJyZW50bHkpIGNyZWF0aW9uLCBsYXN0LWFjY2VzcywgcGVyc2lzdGVudCBhbmQKCSAqIGhvc3Qtb25seS4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXB1YmxpYyAkZmxhZ3MgPSBhcnJheSgpOwoKCS8qKgoJICogUmVmZXJlbmNlIHRpbWUgZm9yIHJlbGF0aXZlIGNhbGN1bGF0aW9ucwoJICoKCSAqIFRoaXMgaXMgdXNlZCBpbiBwbGFjZSBvZiBgdGltZSgpYCB3aGVuIGNhbGN1bGF0aW5nIE1heC1BZ2UgZXhwaXJhdGlvbiBhbmQKCSAqIGNoZWNraW5nIHRpbWUgdmFsaWRpdHkuCgkgKgoJICogQHZhciBpbnQKCSAqLwoJcHVibGljICRyZWZlcmVuY2VfdGltZSA9IDA7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgY29va2llIG9iamVjdAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCgkgKiBAcGFyYW0gYXJyYXl8UmVxdWVzdHNfVXRpbGl0eV9DYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5ICRhdHRyaWJ1dGVzIEFzc29jaWF0aXZlIGFycmF5IG9mIGF0dHJpYnV0ZSBkYXRhCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJHZhbHVlLCAkYXR0cmlidXRlcyA9IGFycmF5KCksICRmbGFncyA9IGFycmF5KCksICRyZWZlcmVuY2VfdGltZSA9IG51bGwpIHsKCQkkdGhpcy0+bmFtZSAgICAgICA9ICRuYW1lOwoJCSR0aGlzLT52YWx1ZSAgICAgID0gJHZhbHVlOwoJCSR0aGlzLT5hdHRyaWJ1dGVzID0gJGF0dHJpYnV0ZXM7CgkJJGRlZmF1bHRfZmxhZ3MgICAgPSBhcnJheSgKCQkJJ2NyZWF0aW9uJyAgICA9PiB0aW1lKCksCgkJCSdsYXN0LWFjY2VzcycgPT4gdGltZSgpLAoJCQkncGVyc2lzdGVudCcgID0+IGZhbHNlLAoJCQknaG9zdC1vbmx5JyAgID0+IHRydWUsCgkJKTsKCQkkdGhpcy0+ZmxhZ3MgICAgICA9IGFycmF5X21lcmdlKCRkZWZhdWx0X2ZsYWdzLCAkZmxhZ3MpOwoKCQkkdGhpcy0+cmVmZXJlbmNlX3RpbWUgPSB0aW1lKCk7CgkJaWYgKCRyZWZlcmVuY2VfdGltZSAhPT0gbnVsbCkgewoJCQkkdGhpcy0+cmVmZXJlbmNlX3RpbWUgPSAkcmVmZXJlbmNlX3RpbWU7CgkJfQoKCQkkdGhpcy0+bm9ybWFsaXplKCk7Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiBhIGNvb2tpZSBpcyBleHBpcmVkLgoJICoKCSAqIENoZWNrcyB0aGUgYWdlIGFnYWluc3QgJHRoaXMtPnJlZmVyZW5jZV90aW1lIHRvIGRldGVybWluZSBpZiB0aGUgY29va2llCgkgKiBpcyBleHBpcmVkLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIGV4cGlyZWQsIGZhbHNlIGlmIHRpbWUgaXMgdmFsaWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc19leHBpcmVkKCkgewoJCS8vIFJGQzYyNjUsIHMuIDQuMS4yLjI6CgkJLy8gSWYgYSBjb29raWUgaGFzIGJvdGggdGhlIE1heC1BZ2UgYW5kIHRoZSBFeHBpcmVzIGF0dHJpYnV0ZSwgdGhlIE1heC0KCQkvLyBBZ2UgYXR0cmlidXRlIGhhcyBwcmVjZWRlbmNlIGFuZCBjb250cm9scyB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoZQoJCS8vIGNvb2tpZS4KCQlpZiAoaXNzZXQoJHRoaXMtPmF0dHJpYnV0ZXNbJ21heC1hZ2UnXSkpIHsKCQkJJG1heF9hZ2UgPSAkdGhpcy0+YXR0cmlidXRlc1snbWF4LWFnZSddOwoJCQlyZXR1cm4gJG1heF9hZ2UgPCAkdGhpcy0+cmVmZXJlbmNlX3RpbWU7CgkJfQoKCQlpZiAoaXNzZXQoJHRoaXMtPmF0dHJpYnV0ZXNbJ2V4cGlyZXMnXSkpIHsKCQkJJGV4cGlyZXMgPSAkdGhpcy0+YXR0cmlidXRlc1snZXhwaXJlcyddOwoJCQlyZXR1cm4gJGV4cGlyZXMgPCAkdGhpcy0+cmVmZXJlbmNlX3RpbWU7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiBhIGNvb2tpZSBpcyB2YWxpZCBmb3IgYSBnaXZlbiBVUkkKCSAqCgkgKiBAcGFyYW0gUmVxdWVzdHNfSVJJICR1cmkgVVJJIHRvIGNoZWNrCgkgKiBAcmV0dXJuIGJvb2xlYW4gV2hldGhlciB0aGUgY29va2llIGlzIHZhbGlkIGZvciB0aGUgZ2l2ZW4gVVJJCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cmlfbWF0Y2hlcyhSZXF1ZXN0c19JUkkgJHVyaSkgewoJCWlmICghJHRoaXMtPmRvbWFpbl9tYXRjaGVzKCR1cmktPmhvc3QpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlmICghJHRoaXMtPnBhdGhfbWF0Y2hlcygkdXJpLT5wYXRoKSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gZW1wdHkoJHRoaXMtPmF0dHJpYnV0ZXNbJ3NlY3VyZSddKSB8fCAkdXJpLT5zY2hlbWUgPT09ICdodHRwcyc7Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiBhIGNvb2tpZSBpcyB2YWxpZCBmb3IgYSBnaXZlbiBkb21haW4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgRG9tYWluIHRvIGNoZWNrCgkgKiBAcmV0dXJuIGJvb2xlYW4gV2hldGhlciB0aGUgY29va2llIGlzIHZhbGlkIGZvciB0aGUgZ2l2ZW4gZG9tYWluCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkb21haW5fbWF0Y2hlcygkc3RyaW5nKSB7CgkJaWYgKCFpc3NldCgkdGhpcy0+YXR0cmlidXRlc1snZG9tYWluJ10pKSB7CgkJCS8vIENvb2tpZXMgY3JlYXRlZCBtYW51YWxseTsgY29va2llcyBjcmVhdGVkIGJ5IFJlcXVlc3RzIHdpbGwgc2V0CgkJCS8vIHRoZSBkb21haW4gdG8gdGhlIHJlcXVlc3RlZCBkb21haW4KCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkZG9tYWluX3N0cmluZyA9ICR0aGlzLT5hdHRyaWJ1dGVzWydkb21haW4nXTsKCQlpZiAoJGRvbWFpbl9zdHJpbmcgPT09ICRzdHJpbmcpIHsKCQkJLy8gVGhlIGRvbWFpbiBzdHJpbmcgYW5kIHRoZSBzdHJpbmcgYXJlIGlkZW50aWNhbC4KCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBJZiB0aGUgY29va2llIGlzIG1hcmtlZCBhcyBob3N0LW9ubHkgYW5kIHdlIGRvbid0IGhhdmUgYW4gZXhhY3QKCQkvLyBtYXRjaCwgcmVqZWN0IHRoZSBjb29raWUKCQlpZiAoJHRoaXMtPmZsYWdzWydob3N0LW9ubHknXSA9PT0gdHJ1ZSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoc3RybGVuKCRzdHJpbmcpIDw9IHN0cmxlbigkZG9tYWluX3N0cmluZykpIHsKCQkJLy8gRm9yIG9idmlvdXMgcmVhc29ucywgdGhlIHN0cmluZyBjYW5ub3QgYmUgYSBzdWZmaXggaWYgdGhlIGRvbWFpbgoJCQkvLyBpcyBzaG9ydGVyIHRoYW4gdGhlIGRvbWFpbiBzdHJpbmcKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKHN1YnN0cigkc3RyaW5nLCAtMSAqIHN0cmxlbigkZG9tYWluX3N0cmluZykpICE9PSAkZG9tYWluX3N0cmluZykgewoJCQkvLyBUaGUgZG9tYWluIHN0cmluZyBzaG91bGQgYmUgYSBzdWZmaXggb2YgdGhlIHN0cmluZy4KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHByZWZpeCA9IHN1YnN0cigkc3RyaW5nLCAwLCBzdHJsZW4oJHN0cmluZykgLSBzdHJsZW4oJGRvbWFpbl9zdHJpbmcpKTsKCQlpZiAoc3Vic3RyKCRwcmVmaXgsIC0xKSAhPT0gJy4nKSB7CgkJCS8vIFRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIHRoZQoJCQkvLyBkb21haW4gc3RyaW5nIHNob3VsZCBiZSBhICV4MkUgKCIuIikgY2hhcmFjdGVyLgoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBUaGUgc3RyaW5nIHNob3VsZCBiZSBhIGhvc3QgbmFtZSAoaS5lLiwgbm90IGFuIElQIGFkZHJlc3MpLgoJCXJldHVybiAhcHJlZ19tYXRjaCgnI14oLitcLilcZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9JCMnLCAkc3RyaW5nKTsKCX0KCgkvKioKCSAqIENoZWNrIGlmIGEgY29va2llIGlzIHZhbGlkIGZvciBhIGdpdmVuIHBhdGgKCSAqCgkgKiBGcm9tIHRoZSBwYXRoLW1hdGNoIGNoZWNrIGluIFJGQyA2MjY1IHNlY3Rpb24gNS4xLjQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRyZXF1ZXN0X3BhdGggUGF0aCB0byBjaGVjawoJICogQHJldHVybiBib29sZWFuIFdoZXRoZXIgdGhlIGNvb2tpZSBpcyB2YWxpZCBmb3IgdGhlIGdpdmVuIHBhdGgKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGhfbWF0Y2hlcygkcmVxdWVzdF9wYXRoKSB7CgkJaWYgKGVtcHR5KCRyZXF1ZXN0X3BhdGgpKSB7CgkJCS8vIE5vcm1hbGl6ZSBlbXB0eSBwYXRoIHRvIHJvb3QKCQkJJHJlcXVlc3RfcGF0aCA9ICcvJzsKCQl9CgoJCWlmICghaXNzZXQoJHRoaXMtPmF0dHJpYnV0ZXNbJ3BhdGgnXSkpIHsKCQkJLy8gQ29va2llcyBjcmVhdGVkIG1hbnVhbGx5OyBjb29raWVzIGNyZWF0ZWQgYnkgUmVxdWVzdHMgd2lsbCBzZXQKCQkJLy8gdGhlIHBhdGggdG8gdGhlIHJlcXVlc3RlZCBwYXRoCgkJCXJldHVybiB0cnVlOwoJCX0KCgkJJGNvb2tpZV9wYXRoID0gJHRoaXMtPmF0dHJpYnV0ZXNbJ3BhdGgnXTsKCgkJaWYgKCRjb29raWVfcGF0aCA9PT0gJHJlcXVlc3RfcGF0aCkgewoJCQkvLyBUaGUgY29va2llLXBhdGggYW5kIHRoZSByZXF1ZXN0LXBhdGggYXJlIGlkZW50aWNhbC4KCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlpZiAoc3RybGVuKCRyZXF1ZXN0X3BhdGgpID4gc3RybGVuKCRjb29raWVfcGF0aCkgJiYgc3Vic3RyKCRyZXF1ZXN0X3BhdGgsIDAsIHN0cmxlbigkY29va2llX3BhdGgpKSA9PT0gJGNvb2tpZV9wYXRoKSB7CgkJCWlmIChzdWJzdHIoJGNvb2tpZV9wYXRoLCAtMSkgPT09ICcvJykgewoJCQkJLy8gVGhlIGNvb2tpZS1wYXRoIGlzIGEgcHJlZml4IG9mIHRoZSByZXF1ZXN0LXBhdGgsIGFuZCB0aGUgbGFzdAoJCQkJLy8gY2hhcmFjdGVyIG9mIHRoZSBjb29raWUtcGF0aCBpcyAleDJGICgiLyIpLgoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCgkJCWlmIChzdWJzdHIoJHJlcXVlc3RfcGF0aCwgc3RybGVuKCRjb29raWVfcGF0aCksIDEpID09PSAnLycpIHsKCQkJCS8vIFRoZSBjb29raWUtcGF0aCBpcyBhIHByZWZpeCBvZiB0aGUgcmVxdWVzdC1wYXRoLCBhbmQgdGhlCgkJCQkvLyBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIHJlcXVlc3QtcGF0aCB0aGF0IGlzIG5vdCBpbmNsdWRlZCBpbgoJCQkJLy8gdGhlIGNvb2tpZS1wYXRoIGlzIGEgJXgyRiAoIi8iKSBjaGFyYWN0ZXIuCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogTm9ybWFsaXplIGNvb2tpZSBhbmQgYXR0cmlidXRlcwoJICoKCSAqIEByZXR1cm4gYm9vbGVhbiBXaGV0aGVyIHRoZSBjb29raWUgd2FzIHN1Y2Nlc3NmdWxseSBub3JtYWxpemVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemUoKSB7CgkJZm9yZWFjaCAoJHRoaXMtPmF0dHJpYnV0ZXMgYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJJG9yaWdfdmFsdWUgPSAkdmFsdWU7CgkJCSR2YWx1ZSAgICAgID0gJHRoaXMtPm5vcm1hbGl6ZV9hdHRyaWJ1dGUoJGtleSwgJHZhbHVlKTsKCQkJaWYgKCR2YWx1ZSA9PT0gbnVsbCkgewoJCQkJdW5zZXQoJHRoaXMtPmF0dHJpYnV0ZXNbJGtleV0pOwoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICgkdmFsdWUgIT09ICRvcmlnX3ZhbHVlKSB7CgkJCQkkdGhpcy0+YXR0cmlidXRlc1ska2V5XSA9ICR2YWx1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBQYXJzZSBhbiBpbmRpdmlkdWFsIGNvb2tpZSBhdHRyaWJ1dGUKCSAqCgkgKiBIYW5kbGVzIHBhcnNpbmcgaW5kaXZpZHVhbCBhdHRyaWJ1dGVzIGZyb20gdGhlIGNvb2tpZSB2YWx1ZXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBBdHRyaWJ1dGUgbmFtZQoJICogQHBhcmFtIHN0cmluZ3xib29sZWFuICR2YWx1ZSBBdHRyaWJ1dGUgdmFsdWUgKHN0cmluZyB2YWx1ZSwgb3IgdHJ1ZSBpZiBlbXB0eS9mbGFnKQoJICogQHJldHVybiBtaXhlZCBWYWx1ZSBpZiBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBpbnZhbGlkIChhbmQgc2hvdWxkIGJlIHNraXBwZWQpCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBub3JtYWxpemVfYXR0cmlidXRlKCRuYW1lLCAkdmFsdWUpIHsKCQlzd2l0Y2ggKHN0cnRvbG93ZXIoJG5hbWUpKSB7CgkJCWNhc2UgJ2V4cGlyZXMnOgoJCQkJLy8gRXhwaXJhdGlvbiBwYXJzaW5nLCBhcyBwZXIgUkZDIDYyNjUgc2VjdGlvbiA1LjIuMQoJCQkJaWYgKGlzX2ludCgkdmFsdWUpKSB7CgkJCQkJcmV0dXJuICR2YWx1ZTsKCQkJCX0KCgkJCQkkZXhwaXJ5X3RpbWUgPSBzdHJ0b3RpbWUoJHZhbHVlKTsKCQkJCWlmICgkZXhwaXJ5X3RpbWUgPT09IGZhbHNlKSB7CgkJCQkJcmV0dXJuIG51bGw7CgkJCQl9CgoJCQkJcmV0dXJuICRleHBpcnlfdGltZTsKCgkJCWNhc2UgJ21heC1hZ2UnOgoJCQkJLy8gRXhwaXJhdGlvbiBwYXJzaW5nLCBhcyBwZXIgUkZDIDYyNjUgc2VjdGlvbiA1LjIuMgoJCQkJaWYgKGlzX2ludCgkdmFsdWUpKSB7CgkJCQkJcmV0dXJuICR2YWx1ZTsKCQkJCX0KCgkJCQkvLyBDaGVjayB0aGF0IHdlIGhhdmUgYSB2YWxpZCBhZ2UKCQkJCWlmICghcHJlZ19tYXRjaCgnL14tP1xkKyQvJywgJHZhbHVlKSkgewoJCQkJCXJldHVybiBudWxsOwoJCQkJfQoKCQkJCSRkZWx0YV9zZWNvbmRzID0gKGludCkgJHZhbHVlOwoJCQkJaWYgKCRkZWx0YV9zZWNvbmRzIDw9IDApIHsKCQkJCQkkZXhwaXJ5X3RpbWUgPSAwOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJJGV4cGlyeV90aW1lID0gJHRoaXMtPnJlZmVyZW5jZV90aW1lICsgJGRlbHRhX3NlY29uZHM7CgkJCQl9CgoJCQkJcmV0dXJuICRleHBpcnlfdGltZTsKCgkJCWNhc2UgJ2RvbWFpbic6CgkJCQkvLyBEb21haW5zIGFyZSBub3QgcmVxdWlyZWQgYXMgcGVyIFJGQyA2MjY1IHNlY3Rpb24gNS4yLjMKCQkJCWlmIChlbXB0eSgkdmFsdWUpKSB7CgkJCQkJcmV0dXJuIG51bGw7CgkJCQl9CgoJCQkJLy8gRG9tYWluIG5vcm1hbGl6YXRpb24sIGFzIHBlciBSRkMgNjI2NSBzZWN0aW9uIDUuMi4zCgkJCQlpZiAoJHZhbHVlWzBdID09PSAnLicpIHsKCQkJCQkkdmFsdWUgPSBzdWJzdHIoJHZhbHVlLCAxKTsKCQkJCX0KCgkJCQlyZXR1cm4gJHZhbHVlOwoKCQkJZGVmYXVsdDoKCQkJCXJldHVybiAkdmFsdWU7CgkJfQoJfQoKCS8qKgoJICogRm9ybWF0IGEgY29va2llIGZvciBhIENvb2tpZSBoZWFkZXIKCSAqCgkgKiBUaGlzIGlzIHVzZWQgd2hlbiBzZW5kaW5nIGNvb2tpZXMgdG8gYSBzZXJ2ZXIuCgkgKgoJICogQHJldHVybiBzdHJpbmcgQ29va2llIGZvcm1hdHRlZCBmb3IgQ29va2llIGhlYWRlcgoJICovCglwdWJsaWMgZnVuY3Rpb24gZm9ybWF0X2Zvcl9oZWFkZXIoKSB7CgkJcmV0dXJuIHNwcmludGYoJyVzPSVzJywgJHRoaXMtPm5hbWUsICR0aGlzLT52YWx1ZSk7Cgl9CgoJLyoqCgkgKiBGb3JtYXQgYSBjb29raWUgZm9yIGEgQ29va2llIGhlYWRlcgoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEBkZXByZWNhdGVkIFVzZSB7QHNlZSBSZXF1ZXN0c19Db29raWU6OmZvcm1hdF9mb3JfaGVhZGVyfQoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZvcm1hdEZvckhlYWRlcigpIHsKCQlyZXR1cm4gJHRoaXMtPmZvcm1hdF9mb3JfaGVhZGVyKCk7Cgl9CgoJLyoqCgkgKiBGb3JtYXQgYSBjb29raWUgZm9yIGEgU2V0LUNvb2tpZSBoZWFkZXIKCSAqCgkgKiBUaGlzIGlzIHVzZWQgd2hlbiBzZW5kaW5nIGNvb2tpZXMgdG8gY2xpZW50cy4gVGhpcyBpc24ndCByZWFsbHkKCSAqIGFwcGxpY2FibGUgdG8gY2xpZW50LXNpZGUgdXNhZ2UsIGJ1dCBtaWdodCBiZSBoYW5keSBmb3IgZGVidWdnaW5nLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIENvb2tpZSBmb3JtYXR0ZWQgZm9yIFNldC1Db29raWUgaGVhZGVyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmb3JtYXRfZm9yX3NldF9jb29raWUoKSB7CgkJJGhlYWRlcl92YWx1ZSA9ICR0aGlzLT5mb3JtYXRfZm9yX2hlYWRlcigpOwoJCWlmICghZW1wdHkoJHRoaXMtPmF0dHJpYnV0ZXMpKSB7CgkJCSRwYXJ0cyA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCR0aGlzLT5hdHRyaWJ1dGVzIGFzICRrZXkgPT4gJHZhbHVlKSB7CgkJCQkvLyBJZ25vcmUgbm9uLWFzc29jaWF0aXZlIGF0dHJpYnV0ZXMKCQkJCWlmIChpc19udW1lcmljKCRrZXkpKSB7CgkJCQkJJHBhcnRzW10gPSAkdmFsdWU7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkkcGFydHNbXSA9IHNwcmludGYoJyVzPSVzJywgJGtleSwgJHZhbHVlKTsKCQkJCX0KCQkJfQoKCQkJJGhlYWRlcl92YWx1ZSAuPSAnOyAnIC4gaW1wbG9kZSgnOyAnLCAkcGFydHMpOwoJCX0KCQlyZXR1cm4gJGhlYWRlcl92YWx1ZTsKCX0KCgkvKioKCSAqIEZvcm1hdCBhIGNvb2tpZSBmb3IgYSBTZXQtQ29va2llIGhlYWRlcgoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEBkZXByZWNhdGVkIFVzZSB7QHNlZSBSZXF1ZXN0c19Db29raWU6OmZvcm1hdF9mb3Jfc2V0X2Nvb2tpZX0KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmb3JtYXRGb3JTZXRDb29raWUoKSB7CgkJcmV0dXJuICR0aGlzLT5mb3JtYXRfZm9yX3NldF9jb29raWUoKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29va2llIHZhbHVlCgkgKgoJICogQXR0cmlidXRlcyBhbmQgb3RoZXIgZGF0YSBjYW4gYmUgYWNjZXNzZWQgdmlhIG1ldGhvZHMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkgewoJCXJldHVybiAkdGhpcy0+dmFsdWU7Cgl9CgoJLyoqCgkgKiBQYXJzZSBhIGNvb2tpZSBzdHJpbmcgaW50byBhIGNvb2tpZSBvYmplY3QKCSAqCgkgKiBCYXNlZCBvbiBNb3ppbGxhJ3MgcGFyc2luZyBjb2RlIGluIEZpcmVmb3ggYW5kIHJlbGF0ZWQgcHJvamVjdHMsIHdoaWNoCgkgKiBpcyBhbiBpbnRlbnRpb25hbCBkZXZpYXRpb24gZnJvbSBSRkMgMjEwOSBhbmQgUkZDIDI2MTYuIFJGQyA2MjY1CgkgKiBzcGVjaWZpZXMgc29tZSBvZiB0aGlzIGhhbmRsaW5nLCBidXQgbm90IGluIGEgdGhvcm91Z2ggbWFubmVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgQ29va2llIGhlYWRlciB2YWx1ZSAoZnJvbSBhIFNldC1Db29raWUgaGVhZGVyKQoJICogQHJldHVybiBSZXF1ZXN0c19Db29raWUgUGFyc2VkIGNvb2tpZSBvYmplY3QKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZSgkc3RyaW5nLCAkbmFtZSA9ICcnLCAkcmVmZXJlbmNlX3RpbWUgPSBudWxsKSB7CgkJJHBhcnRzICAgPSBleHBsb2RlKCc7JywgJHN0cmluZyk7CgkJJGt2cGFydHMgPSBhcnJheV9zaGlmdCgkcGFydHMpOwoKCQlpZiAoIWVtcHR5KCRuYW1lKSkgewoJCQkkdmFsdWUgPSAkc3RyaW5nOwoJCX0KCQllbHNlaWYgKHN0cnBvcygka3ZwYXJ0cywgJz0nKSA9PT0gZmFsc2UpIHsKCQkJLy8gU29tZSBzaXRlcyBtaWdodCBvbmx5IGhhdmUgYSB2YWx1ZSB3aXRob3V0IHRoZSBlcXVhbHMgc2VwYXJhdG9yLgoJCQkvLyBEZXZpYXRlIGZyb20gUkZDIDYyNjUgYW5kIHByZXRlbmQgaXQgd2FzIGFjdHVhbGx5IGEgYmxhbmsgbmFtZQoJCQkvLyAoYD1mb29gKQoJCQkvLwoJCQkvLyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xNjkwOTEKCQkJJG5hbWUgID0gJyc7CgkJCSR2YWx1ZSA9ICRrdnBhcnRzOwoJCX0KCQllbHNlIHsKCQkJbGlzdCgkbmFtZSwgJHZhbHVlKSA9IGV4cGxvZGUoJz0nLCAka3ZwYXJ0cywgMik7CgkJfQoJCSRuYW1lICA9IHRyaW0oJG5hbWUpOwoJCSR2YWx1ZSA9IHRyaW0oJHZhbHVlKTsKCgkJLy8gQXR0cmlidXRlIGtleSBhcmUgaGFuZGxlZCBjYXNlLWluc2Vuc2l0aXZlbHkKCQkkYXR0cmlidXRlcyA9IG5ldyBSZXF1ZXN0c19VdGlsaXR5X0Nhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkoKTsKCgkJaWYgKCFlbXB0eSgkcGFydHMpKSB7CgkJCWZvcmVhY2ggKCRwYXJ0cyBhcyAkcGFydCkgewoJCQkJaWYgKHN0cnBvcygkcGFydCwgJz0nKSA9PT0gZmFsc2UpIHsKCQkJCQkkcGFydF9rZXkgICA9ICRwYXJ0OwoJCQkJCSRwYXJ0X3ZhbHVlID0gdHJ1ZTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCWxpc3QoJHBhcnRfa2V5LCAkcGFydF92YWx1ZSkgPSBleHBsb2RlKCc9JywgJHBhcnQsIDIpOwoJCQkJCSRwYXJ0X3ZhbHVlICAgICAgICAgICAgICAgICAgPSB0cmltKCRwYXJ0X3ZhbHVlKTsKCQkJCX0KCgkJCQkkcGFydF9rZXkgICAgICAgICAgICAgID0gdHJpbSgkcGFydF9rZXkpOwoJCQkJJGF0dHJpYnV0ZXNbJHBhcnRfa2V5XSA9ICRwYXJ0X3ZhbHVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gbmV3IFJlcXVlc3RzX0Nvb2tpZSgkbmFtZSwgJHZhbHVlLCAkYXR0cmlidXRlcywgYXJyYXkoKSwgJHJlZmVyZW5jZV90aW1lKTsKCX0KCgkvKioKCSAqIFBhcnNlIGFsbCBTZXQtQ29va2llIGhlYWRlcnMgZnJvbSByZXF1ZXN0IGhlYWRlcnMKCSAqCgkgKiBAcGFyYW0gUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyAkaGVhZGVycyBIZWFkZXJzIHRvIHBhcnNlIGZyb20KCSAqIEBwYXJhbSBSZXF1ZXN0c19JUkl8bnVsbCAkb3JpZ2luIFVSSSBmb3IgY29tcGFyaW5nIGNvb2tpZSBvcmlnaW5zCgkgKiBAcGFyYW0gaW50fG51bGwgJHRpbWUgUmVmZXJlbmNlIHRpbWUgZm9yIGV4cGlyYXRpb24gY2FsY3VsYXRpb24KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZV9mcm9tX2hlYWRlcnMoUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyAkaGVhZGVycywgUmVxdWVzdHNfSVJJICRvcmlnaW4gPSBudWxsLCAkdGltZSA9IG51bGwpIHsKCQkkY29va2llX2hlYWRlcnMgPSAkaGVhZGVycy0+Z2V0VmFsdWVzKCdTZXQtQ29va2llJyk7CgkJaWYgKGVtcHR5KCRjb29raWVfaGVhZGVycykpIHsKCQkJcmV0dXJuIGFycmF5KCk7CgkJfQoKCQkkY29va2llcyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoJGNvb2tpZV9oZWFkZXJzIGFzICRoZWFkZXIpIHsKCQkJJHBhcnNlZCA9IHNlbGY6OnBhcnNlKCRoZWFkZXIsICcnLCAkdGltZSk7CgoJCQkvLyBEZWZhdWx0IGRvbWFpbi9wYXRoIGF0dHJpYnV0ZXMKCQkJaWYgKGVtcHR5KCRwYXJzZWQtPmF0dHJpYnV0ZXNbJ2RvbWFpbiddKSAmJiAhZW1wdHkoJG9yaWdpbikpIHsKCQkJCSRwYXJzZWQtPmF0dHJpYnV0ZXNbJ2RvbWFpbiddID0gJG9yaWdpbi0+aG9zdDsKCQkJCSRwYXJzZWQtPmZsYWdzWydob3N0LW9ubHknXSAgID0gdHJ1ZTsKCQkJfQoJCQllbHNlIHsKCQkJCSRwYXJzZWQtPmZsYWdzWydob3N0LW9ubHknXSA9IGZhbHNlOwoJCQl9CgoJCQkkcGF0aF9pc192YWxpZCA9ICghZW1wdHkoJHBhcnNlZC0+YXR0cmlidXRlc1sncGF0aCddKSAmJiAkcGFyc2VkLT5hdHRyaWJ1dGVzWydwYXRoJ11bMF0gPT09ICcvJyk7CgkJCWlmICghJHBhdGhfaXNfdmFsaWQgJiYgIWVtcHR5KCRvcmlnaW4pKSB7CgkJCQkkcGF0aCA9ICRvcmlnaW4tPnBhdGg7CgoJCQkJLy8gRGVmYXVsdCBwYXRoIG5vcm1hbGl6YXRpb24gYXMgcGVyIFJGQyA2MjY1IHNlY3Rpb24gNS4xLjQKCQkJCWlmIChzdWJzdHIoJHBhdGgsIDAsIDEpICE9PSAnLycpIHsKCQkJCQkvLyBJZiB0aGUgdXJpLXBhdGggaXMgZW1wdHkgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgoJCQkJCS8vIHRoZSB1cmktcGF0aCBpcyBub3QgYSAleDJGICgiLyIpIGNoYXJhY3Rlciwgb3V0cHV0CgkJCQkJLy8gJXgyRiAoIi8iKSBhbmQgc2tpcCB0aGUgcmVtYWluaW5nIHN0ZXBzLgoJCQkJCSRwYXRoID0gJy8nOwoJCQkJfQoJCQkJZWxzZWlmIChzdWJzdHJfY291bnQoJHBhdGgsICcvJykgPT09IDEpIHsKCQkJCQkvLyBJZiB0aGUgdXJpLXBhdGggY29udGFpbnMgbm8gbW9yZSB0aGFuIG9uZSAleDJGICgiLyIpCgkJCQkJLy8gY2hhcmFjdGVyLCBvdXRwdXQgJXgyRiAoIi8iKSBhbmQgc2tpcCB0aGUgcmVtYWluaW5nCgkJCQkJLy8gc3RlcC4KCQkJCQkkcGF0aCA9ICcvJzsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCS8vIE91dHB1dCB0aGUgY2hhcmFjdGVycyBvZiB0aGUgdXJpLXBhdGggZnJvbSB0aGUgZmlyc3QKCQkJCQkvLyBjaGFyYWN0ZXIgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCB0aGUgcmlnaHQtbW9zdAoJCQkJCS8vICV4MkYgKCIvIikuCgkJCQkJJHBhdGggPSBzdWJzdHIoJHBhdGgsIDAsIHN0cnJwb3MoJHBhdGgsICcvJykpOwoJCQkJfQoJCQkJJHBhcnNlZC0+YXR0cmlidXRlc1sncGF0aCddID0gJHBhdGg7CgkJCX0KCgkJCS8vIFJlamVjdCBpbnZhbGlkIGNvb2tpZSBkb21haW5zCgkJCWlmICghZW1wdHkoJG9yaWdpbikgJiYgISRwYXJzZWQtPmRvbWFpbl9tYXRjaGVzKCRvcmlnaW4tPmhvc3QpKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvb2tpZXNbJHBhcnNlZC0+bmFtZV0gPSAkcGFyc2VkOwoJCX0KCgkJcmV0dXJuICRjb29raWVzOwoJfQoKCS8qKgoJICogUGFyc2UgYWxsIFNldC1Db29raWUgaGVhZGVycyBmcm9tIHJlcXVlc3QgaGVhZGVycwoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEBkZXByZWNhdGVkIFVzZSB7QHNlZSBSZXF1ZXN0c19Db29raWU6OnBhcnNlX2Zyb21faGVhZGVyc30KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZUZyb21IZWFkZXJzKFJlcXVlc3RzX1Jlc3BvbnNlX0hlYWRlcnMgJGhlYWRlcnMpIHsKCQlyZXR1cm4gc2VsZjo6cGFyc2VfZnJvbV9oZWFkZXJzKCRoZWFkZXJzKTsKCX0KfQo8P3BocAovKioKICogSXRlcmF0b3IgZm9yIGFycmF5cyByZXF1aXJpbmcgZmlsdGVyZWQgdmFsdWVzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KCi8qKgogKiBJdGVyYXRvciBmb3IgYXJyYXlzIHJlcXVpcmluZyBmaWx0ZXJlZCB2YWx1ZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwpjbGFzcyBSZXF1ZXN0c19VdGlsaXR5X0ZpbHRlcmVkSXRlcmF0b3IgZXh0ZW5kcyBBcnJheUl0ZXJhdG9yIHsKCS8qKgoJICogQ2FsbGJhY2sgdG8gcnVuIGFzIGEgZmlsdGVyCgkgKgoJICogQHZhciBjYWxsYWJsZQoJICovCglwcm90ZWN0ZWQgJGNhbGxiYWNrOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGl0ZXJhdG9yCgkgKgoJICogQHBhcmFtIGFycmF5ICRkYXRhCgkgKiBAcGFyYW0gY2FsbGFibGUgJGNhbGxiYWNrIENhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBlYWNoIHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZGF0YSwgJGNhbGxiYWNrKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkZGF0YSk7CgoJCSR0aGlzLT5jYWxsYmFjayA9ICRjYWxsYmFjazsKCX0KCgkvKioKCSAqIEdldCB0aGUgY3VycmVudCBpdGVtJ3MgdmFsdWUgYWZ0ZXIgZmlsdGVyaW5nCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJJHZhbHVlID0gcGFyZW50OjpjdXJyZW50KCk7CgoJCWlmIChpc19jYWxsYWJsZSgkdGhpcy0+Y2FsbGJhY2spKSB7CgkJCSR2YWx1ZSA9IGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5jYWxsYmFjaywgJHZhbHVlKTsKCQl9CgoJCXJldHVybiAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zZXJpYWxpemUoJHNlcmlhbGl6ZWQpIHt9CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICoKCSAqIEBwaHBjczpkaXNhYmxlIFBIUENvbXBhdGliaWxpdHkuRnVuY3Rpb25OYW1lUmVzdHJpY3Rpb25zLk5ld01hZ2ljTWV0aG9kcy5fX3Vuc2VyaWFsaXplRm91bmQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdW5zZXJpYWxpemUoJHNlcmlhbGl6ZWQpIHt9CgoJcHVibGljIGZ1bmN0aW9uIF9fd2FrZXVwKCkgewoJCXVuc2V0KCR0aGlzLT5jYWxsYmFjayk7Cgl9Cn0KPD9waHAKLyoqCiAqIENhc2UtaW5zZW5zaXRpdmUgZGljdGlvbmFyeSwgc3VpdGFibGUgZm9yIEhUVFAgaGVhZGVycwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogQ2FzZS1pbnNlbnNpdGl2ZSBkaWN0aW9uYXJ5LCBzdWl0YWJsZSBmb3IgSFRUUCBoZWFkZXJzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KY2xhc3MgUmVxdWVzdHNfVXRpbGl0eV9DYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5IGltcGxlbWVudHMgQXJyYXlBY2Nlc3MsIEl0ZXJhdG9yQWdncmVnYXRlIHsKCS8qKgoJICogQWN0dWFsIGl0ZW0gZGF0YQoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRkYXRhID0gYXJyYXkoKTsKCgkvKioKCSAqIENyZWF0ZXMgYSBjYXNlIGluc2Vuc2l0aXZlIGRpY3Rpb25hcnkuCgkgKgoJICogQHBhcmFtIGFycmF5ICRkYXRhIERpY3Rpb25hcnkvbWFwIHRvIGNvbnZlcnQgdG8gY2FzZS1pbnNlbnNpdGl2ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGRhdGEgPSBhcnJheSgpKSB7CgkJZm9yZWFjaCAoJGRhdGEgYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJJHRoaXMtPm9mZnNldFNldCgka2V5LCAkdmFsdWUpOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrIGlmIHRoZSBnaXZlbiBpdGVtIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBJdGVtIGtleQoJICogQHJldHVybiBib29sZWFuIERvZXMgdGhlIGl0ZW0gZXhpc3Q/CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvZmZzZXRFeGlzdHMoJGtleSkgewoJCSRrZXkgPSBzdHJ0b2xvd2VyKCRrZXkpOwoJCXJldHVybiBpc3NldCgkdGhpcy0+ZGF0YVska2V5XSk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgaXRlbQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleSBJdGVtIGtleQoJICogQHJldHVybiBzdHJpbmd8bnVsbCBJdGVtIHZhbHVlIChudWxsIGlmIG9mZnNldEV4aXN0cyBpcyBmYWxzZSkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldEdldCgka2V5KSB7CgkJJGtleSA9IHN0cnRvbG93ZXIoJGtleSk7CgkJaWYgKCFpc3NldCgkdGhpcy0+ZGF0YVska2V5XSkpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmRhdGFbJGtleV07Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGdpdmVuIGl0ZW0KCSAqCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBhdHRlbXB0aW5nIHRvIHVzZSBkaWN0aW9uYXJ5IGFzIGxpc3QgKGBpbnZhbGlkc2V0YCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgSXRlbSBuYW1lCgkgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBJdGVtIHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvZmZzZXRTZXQoJGtleSwgJHZhbHVlKSB7CgkJaWYgKCRrZXkgPT09IG51bGwpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignT2JqZWN0IGlzIGEgZGljdGlvbmFyeSwgbm90IGEgbGlzdCcsICdpbnZhbGlkc2V0Jyk7CgkJfQoKCQkka2V5ICAgICAgICAgICAgICA9IHN0cnRvbG93ZXIoJGtleSk7CgkJJHRoaXMtPmRhdGFbJGtleV0gPSAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBVbnNldCB0aGUgZ2l2ZW4gaGVhZGVyCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvZmZzZXRVbnNldCgka2V5KSB7CgkJdW5zZXQoJHRoaXMtPmRhdGFbc3RydG9sb3dlcigka2V5KV0pOwoJfQoKCS8qKgoJICogR2V0IGFuIGl0ZXJhdG9yIGZvciB0aGUgZGF0YQoJICoKCSAqIEByZXR1cm4gQXJyYXlJdGVyYXRvcgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKSB7CgkJcmV0dXJuIG5ldyBBcnJheUl0ZXJhdG9yKCR0aGlzLT5kYXRhKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgaGVhZGVycyBhcyBhbiBhcnJheQoJICoKCSAqIEByZXR1cm4gYXJyYXkgSGVhZGVyIGRhdGEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEFsbCgpIHsKCQlyZXR1cm4gJHRoaXMtPmRhdGE7Cgl9Cn0KPD9waHAKLyoqCiAqIFNTTCB1dGlsaXRpZXMgZm9yIFJlcXVlc3RzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFV0aWxpdGllcwogKi8KCi8qKgogKiBTU0wgdXRpbGl0aWVzIGZvciBSZXF1ZXN0cwogKgogKiBDb2xsZWN0aW9uIG9mIHV0aWxpdGllcyBmb3Igd29ya2luZyB3aXRoIGFuZCB2ZXJpZnlpbmcgU1NMIGNlcnRpZmljYXRlcy4KICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVXRpbGl0aWVzCiAqLwpjbGFzcyBSZXF1ZXN0c19TU0wgewoJLyoqCgkgKiBWZXJpZnkgdGhlIGNlcnRpZmljYXRlIGFnYWluc3QgY29tbW9uIG5hbWUgYW5kIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMKCSAqCgkgKiBVbmZvcnR1bmF0ZWx5LCBQSFAgZG9lc24ndCBjaGVjayB0aGUgY2VydGlmaWNhdGUgYWdhaW5zdCB0aGUgYWx0ZXJuYXRpdmUKCSAqIG5hbWVzLCBsZWFkaW5nIHRoaW5ncyBsaWtlICdodHRwczovL3d3dy5naXRodWIuY29tLycgdG8gYmUgaW52YWxpZC4KCSAqCgkgKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyODE4I3NlY3Rpb24tMy4xIFJGQzI4MTgsIFNlY3Rpb24gMy4xCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gT24gbm90IG9idGFpbmluZyBhIG1hdGNoIGZvciB0aGUgaG9zdCAoYGZzb2Nrb3Blbi5zc2wubm9fbWF0Y2hgKQoJICogQHBhcmFtIHN0cmluZyAkaG9zdCBIb3N0IG5hbWUgdG8gdmVyaWZ5IGFnYWluc3QKCSAqIEBwYXJhbSBhcnJheSAkY2VydCBDZXJ0aWZpY2F0ZSBkYXRhIGZyb20gb3BlbnNzbF94NTA5X3BhcnNlKCkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZlcmlmeV9jZXJ0aWZpY2F0ZSgkaG9zdCwgJGNlcnQpIHsKCQkkaGFzX2Ruc19hbHQgPSBmYWxzZTsKCgkJLy8gQ2hlY2sgdGhlIHN1YmplY3RBbHROYW1lCgkJaWYgKCFlbXB0eSgkY2VydFsnZXh0ZW5zaW9ucyddKSAmJiAhZW1wdHkoJGNlcnRbJ2V4dGVuc2lvbnMnXVsnc3ViamVjdEFsdE5hbWUnXSkpIHsKCQkJJGFsdG5hbWVzID0gZXhwbG9kZSgnLCcsICRjZXJ0WydleHRlbnNpb25zJ11bJ3N1YmplY3RBbHROYW1lJ10pOwoJCQlmb3JlYWNoICgkYWx0bmFtZXMgYXMgJGFsdG5hbWUpIHsKCQkJCSRhbHRuYW1lID0gdHJpbSgkYWx0bmFtZSk7CgkJCQlpZiAoc3RycG9zKCRhbHRuYW1lLCAnRE5TOicpICE9PSAwKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJJGhhc19kbnNfYWx0ID0gdHJ1ZTsKCgkJCQkvLyBTdHJpcCB0aGUgJ0ROUzonIHByZWZpeCBhbmQgdHJpbSB3aGl0ZXNwYWNlCgkJCQkkYWx0bmFtZSA9IHRyaW0oc3Vic3RyKCRhbHRuYW1lLCA0KSk7CgoJCQkJLy8gQ2hlY2sgZm9yIGEgbWF0Y2gKCQkJCWlmIChzZWxmOjptYXRjaF9kb21haW4oJGhvc3QsICRhbHRuYW1lKSA9PT0gdHJ1ZSkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBGYWxsIGJhY2sgdG8gY2hlY2tpbmcgdGhlIGNvbW1vbiBuYW1lIGlmIHdlIGRpZG4ndCBnZXQgYW55IGROU05hbWUKCQkvLyBhbHQgbmFtZXMsIGFzIHBlciBSRkMyODE4CgkJaWYgKCEkaGFzX2Ruc19hbHQgJiYgIWVtcHR5KCRjZXJ0WydzdWJqZWN0J11bJ0NOJ10pKSB7CgkJCS8vIENoZWNrIGZvciBhIG1hdGNoCgkJCWlmIChzZWxmOjptYXRjaF9kb21haW4oJGhvc3QsICRjZXJ0WydzdWJqZWN0J11bJ0NOJ10pID09PSB0cnVlKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogVmVyaWZ5IHRoYXQgYSByZWZlcmVuY2UgbmFtZSBpcyB2YWxpZAoJICoKCSAqIFZlcmlmaWVzIGEgZE5TTmFtZSBmb3IgSFRUUFMgdXNhZ2UsIChhbG1vc3QpIGFzIHBlciBGaXJlZm94J3MgcnVsZXM6CgkgKiAtIFdpbGRjYXJkcyBjYW4gb25seSBvY2N1ciBpbiBhIG5hbWUgd2l0aCBtb3JlIHRoYW4gMyBjb21wb25lbnRzCgkgKiAtIFdpbGRjYXJkcyBjYW4gb25seSBvY2N1ciBhcyB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIGZpcnN0CgkgKiAgIGNvbXBvbmVudAoJICogLSBXaWxkY2FyZHMgbWF5IGJlIHByZWNlZGVkIGJ5IGFkZGl0aW9uYWwgY2hhcmFjdGVycwoJICoKCSAqIFdlIG1vZGlmeSB0aGVzZSBydWxlcyB0byBiZSBhIGJpdCBzdHJpY3RlciBhbmQgb25seSBhbGxvdyB0aGUgd2lsZGNhcmQKCSAqIGNoYXJhY3RlciB0byBiZSB0aGUgZnVsbCBmaXJzdCBjb21wb25lbnQ7IHRoYXQgaXMsIHdpdGggdGhlIGV4Y2x1c2lvbiBvZgoJICogdGhlIHRoaXJkIHJ1bGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcmVmZXJlbmNlIFJlZmVyZW5jZSBkTlNOYW1lCgkgKiBAcmV0dXJuIGJvb2xlYW4gSXMgdGhlIG5hbWUgdmFsaWQ/CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmVyaWZ5X3JlZmVyZW5jZV9uYW1lKCRyZWZlcmVuY2UpIHsKCQkkcGFydHMgPSBleHBsb2RlKCcuJywgJHJlZmVyZW5jZSk7CgoJCS8vIENoZWNrIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBuYW1lCgkJJGZpcnN0ID0gYXJyYXlfc2hpZnQoJHBhcnRzKTsKCgkJaWYgKHN0cnBvcygkZmlyc3QsICcqJykgIT09IGZhbHNlKSB7CgkJCS8vIENoZWNrIHRoYXQgdGhlIHdpbGRjYXJkIGlzIHRoZSBmdWxsIHBhcnQKCQkJaWYgKCRmaXJzdCAhPT0gJyonKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIENoZWNrIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCAzIGNvbXBvbmVudHMgKGluY2x1ZGluZyBmaXJzdCkKCQkJaWYgKGNvdW50KCRwYXJ0cykgPCAyKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCS8vIENoZWNrIHRoZSByZW1haW5pbmcgcGFydHMKCQlmb3JlYWNoICgkcGFydHMgYXMgJHBhcnQpIHsKCQkJaWYgKHN0cnBvcygkcGFydCwgJyonKSAhPT0gZmFsc2UpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCgkJLy8gTm90aGluZyBmb3VuZCwgdmVyaWZpZWQhCgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBNYXRjaCBhIGhvc3RuYW1lIGFnYWluc3QgYSBkTlNOYW1lIHJlZmVyZW5jZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGhvc3QgUmVxdWVzdGVkIGhvc3QKCSAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZSBkTlNOYW1lIHRvIG1hdGNoIGFnYWluc3QKCSAqIEByZXR1cm4gYm9vbGVhbiBEb2VzIHRoZSBkb21haW4gbWF0Y2g/CgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWF0Y2hfZG9tYWluKCRob3N0LCAkcmVmZXJlbmNlKSB7CgkJLy8gQ2hlY2sgaWYgdGhlIHJlZmVyZW5jZSBpcyBibG9ja2xpc3RlZCBmaXJzdAoJCWlmIChzZWxmOjp2ZXJpZnlfcmVmZXJlbmNlX25hbWUoJHJlZmVyZW5jZSkgIT09IHRydWUpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gQ2hlY2sgZm9yIGEgZGlyZWN0IG1hdGNoCgkJaWYgKCRob3N0ID09PSAkcmVmZXJlbmNlKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gQ2FsY3VsYXRlIHRoZSB2YWxpZCB3aWxkY2FyZCBtYXRjaCBpZiB0aGUgaG9zdCBpcyBub3QgYW4gSVAgYWRkcmVzcwoJCS8vIEFsc28gdmFsaWRhdGVzIHRoYXQgdGhlIGhvc3QgaGFzIDMgcGFydHMgb3IgbW9yZSwgYXMgcGVyIEZpcmVmb3gncwoJCS8vIHJ1bGVzZXQuCgkJaWYgKGlwMmxvbmcoJGhvc3QpID09PSBmYWxzZSkgewoJCQkkcGFydHMgICAgPSBleHBsb2RlKCcuJywgJGhvc3QpOwoJCQkkcGFydHNbMF0gPSAnKic7CgkJCSR3aWxkY2FyZCA9IGltcGxvZGUoJy4nLCAkcGFydHMpOwoJCQlpZiAoJHdpbGRjYXJkID09PSAkcmVmZXJlbmNlKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQp9Cjw/cGhwCi8qKgogKiBDYXNlLWluc2Vuc2l0aXZlIGRpY3Rpb25hcnksIHN1aXRhYmxlIGZvciBIVFRQIGhlYWRlcnMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogQ2FzZS1pbnNlbnNpdGl2ZSBkaWN0aW9uYXJ5LCBzdWl0YWJsZSBmb3IgSFRUUCBoZWFkZXJzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19SZXNwb25zZV9IZWFkZXJzIGV4dGVuZHMgUmVxdWVzdHNfVXRpbGl0eV9DYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5IHsKCS8qKgoJICogR2V0IHRoZSBnaXZlbiBoZWFkZXIKCSAqCgkgKiBVbmxpa2Uge0BzZWUgc2VsZjo6Z2V0VmFsdWVzKCl9LCB0aGlzIHJldHVybnMgYSBzdHJpbmcuIElmIHRoZXJlIGFyZQoJICogbXVsdGlwbGUgdmFsdWVzLCBpdCBjb25jYXRlbmF0ZXMgdGhlbSB3aXRoIGEgY29tbWEgYXMgcGVyIFJGQzI2MTYuCgkgKgoJICogQXZvaWQgdXNpbmcgdGhpcyB3aGVyZSBjb21tYXMgbWF5IGJlIHVzZWQgdW5xdW90ZWQgaW4gdmFsdWVzLCBzdWNoIGFzCgkgKiBTZXQtQ29va2llIGhlYWRlcnMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKiBAcmV0dXJuIHN0cmluZ3xudWxsIEhlYWRlciB2YWx1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0R2V0KCRrZXkpIHsKCQkka2V5ID0gc3RydG9sb3dlcigka2V5KTsKCQlpZiAoIWlzc2V0KCR0aGlzLT5kYXRhWyRrZXldKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAkdGhpcy0+ZmxhdHRlbigkdGhpcy0+ZGF0YVska2V5XSk7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGdpdmVuIGl0ZW0KCSAqCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBhdHRlbXB0aW5nIHRvIHVzZSBkaWN0aW9uYXJ5IGFzIGxpc3QgKGBpbnZhbGlkc2V0YCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRrZXkgSXRlbSBuYW1lCgkgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBJdGVtIHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvZmZzZXRTZXQoJGtleSwgJHZhbHVlKSB7CgkJaWYgKCRrZXkgPT09IG51bGwpIHsKCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignT2JqZWN0IGlzIGEgZGljdGlvbmFyeSwgbm90IGEgbGlzdCcsICdpbnZhbGlkc2V0Jyk7CgkJfQoKCQkka2V5ID0gc3RydG9sb3dlcigka2V5KTsKCgkJaWYgKCFpc3NldCgkdGhpcy0+ZGF0YVska2V5XSkpIHsKCQkJJHRoaXMtPmRhdGFbJGtleV0gPSBhcnJheSgpOwoJCX0KCgkJJHRoaXMtPmRhdGFbJGtleV1bXSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIEdldCBhbGwgdmFsdWVzIGZvciBhIGdpdmVuIGhlYWRlcgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGtleQoJICogQHJldHVybiBhcnJheXxudWxsIEhlYWRlciB2YWx1ZXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldFZhbHVlcygka2V5KSB7CgkJJGtleSA9IHN0cnRvbG93ZXIoJGtleSk7CgkJaWYgKCFpc3NldCgkdGhpcy0+ZGF0YVska2V5XSkpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmRhdGFbJGtleV07Cgl9CgoJLyoqCgkgKiBGbGF0dGVucyBhIHZhbHVlIGludG8gYSBzdHJpbmcKCSAqCgkgKiBDb252ZXJ0cyBhbiBhcnJheSBpbnRvIGEgc3RyaW5nIGJ5IGltcGxvZGluZyB2YWx1ZXMgd2l0aCBhIGNvbW1hLCBhcyBwZXIKCSAqIFJGQzI2MTYncyBydWxlcyBmb3IgZm9sZGluZyBoZWFkZXJzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJHZhbHVlIFZhbHVlIHRvIGZsYXR0ZW4KCSAqIEByZXR1cm4gc3RyaW5nIEZsYXR0ZW5lZCB2YWx1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZmxhdHRlbigkdmFsdWUpIHsKCQlpZiAoaXNfYXJyYXkoJHZhbHVlKSkgewoJCQkkdmFsdWUgPSBpbXBsb2RlKCcsJywgJHZhbHVlKTsKCQl9CgoJCXJldHVybiAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBHZXQgYW4gaXRlcmF0b3IgZm9yIHRoZSBkYXRhCgkgKgoJICogQ29udmVydHMgdGhlIGludGVybmFsCgkgKiBAcmV0dXJuIEFycmF5SXRlcmF0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCkgewoJCXJldHVybiBuZXcgUmVxdWVzdHNfVXRpbGl0eV9GaWx0ZXJlZEl0ZXJhdG9yKCR0aGlzLT5kYXRhLCBhcnJheSgkdGhpcywgJ2ZsYXR0ZW4nKSk7Cgl9Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgSFRUUCByZXF1ZXN0cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIEhUVFAgcmVxdWVzdHMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CgkvKioKCSAqIFR5cGUgb2YgZXhjZXB0aW9uCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICR0eXBlOwoKCS8qKgoJICogRGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbgoJICoKCSAqIEB2YXIgbWl4ZWQKCSAqLwoJcHJvdGVjdGVkICRkYXRhOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGV4Y2VwdGlvbgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgRXhjZXB0aW9uIG1lc3NhZ2UKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgRXhjZXB0aW9uIHR5cGUKCSAqIEBwYXJhbSBtaXhlZCAkZGF0YSBBc3NvY2lhdGVkIGRhdGEKCSAqIEBwYXJhbSBpbnRlZ2VyICRjb2RlIEV4Y2VwdGlvbiBudW1lcmljYWwgY29kZSwgaWYgYXBwbGljYWJsZQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsICR0eXBlLCAkZGF0YSA9IG51bGwsICRjb2RlID0gMCkgewoJCXBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRjb2RlKTsKCgkJJHRoaXMtPnR5cGUgPSAkdHlwZTsKCQkkdGhpcy0+ZGF0YSA9ICRkYXRhOwoJfQoKCS8qKgoJICogTGlrZSB7QHNlZSBnZXRDb2RlKCl9LCBidXQgYSBzdHJpbmcgY29kZS4KCSAqCgkgKiBAY29kZUNvdmVyYWdlSWdub3JlCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpIHsKCQlyZXR1cm4gJHRoaXMtPnR5cGU7Cgl9CgoJLyoqCgkgKiBHaXZlcyBhbnkgcmVsZXZhbnQgZGF0YQoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldERhdGEoKSB7CgkJcmV0dXJuICR0aGlzLT5kYXRhOwoJfQp9Cjw/cGhwCi8qKgogKiBJUkkgcGFyc2VyL3NlcmlhbGlzZXIvbm9ybWFsaXNlcgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogSVJJIHBhcnNlci9zZXJpYWxpc2VyL25vcm1hbGlzZXIKICoKICogQ29weXJpZ2h0IChjKSAyMDA3LTIwMTAsIEdlb2ZmcmV5IFNuZWRkb24gYW5kIFN0ZXZlIE1pbnV0aWxsby4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgogKgogKiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCiAqICAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAqCiAqICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogKiAgICAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICoKICogICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU2ltcGxlUGllIFRlYW0gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyAiQVMgSVMiCiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIEJFCiAqIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YKICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTCiAqIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOCiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpCiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFCiAqIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICogQGF1dGhvciBHZW9mZnJleSBTbmVkZG9uCiAqIEBhdXRob3IgU3RldmUgTWludXRpbGxvCiAqIEBjb3B5cmlnaHQgMjAwNy0yMDA5IEdlb2ZmcmV5IFNuZWRkb24gYW5kIFN0ZXZlIE1pbnV0aWxsbwogKiBAbGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2JzZC1saWNlbnNlLnBocAogKiBAbGluayBodHRwOi8vaGcuZ3NuZWRkZXJzLmNvbS9pcmkvCiAqCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGlyaSBJUkkgd2UncmUgd29ya2luZyB3aXRoCiAqIEBwcm9wZXJ0eS1yZWFkIHN0cmluZyAkdXJpIElSSSBpbiBVUkkgZm9ybSwge0BzZWUgdG9fdXJpfQogKiBAcHJvcGVydHkgc3RyaW5nICRzY2hlbWUgU2NoZW1lIHBhcnQgb2YgdGhlIElSSQogKiBAcHJvcGVydHkgc3RyaW5nICRhdXRob3JpdHkgQXV0aG9yaXR5IHBhcnQsIGZvcm1hdHRlZCBmb3IgYSBVUkkgKHVzZXJpbmZvICsgaG9zdCArIHBvcnQpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGlhdXRob3JpdHkgQXV0aG9yaXR5IHBhcnQgb2YgdGhlIElSSSAodXNlcmluZm8gKyBob3N0ICsgcG9ydCkKICogQHByb3BlcnR5IHN0cmluZyAkdXNlcmluZm8gVXNlcmluZm8gcGFydCwgZm9ybWF0dGVkIGZvciBhIFVSSSAoYWZ0ZXIgJzovLycgYW5kIGJlZm9yZSAnQCcpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGl1c2VyaW5mbyBVc2VyaW5mbyBwYXJ0IG9mIHRoZSBJUkkgKGFmdGVyICc6Ly8nIGFuZCBiZWZvcmUgJ0AnKQogKiBAcHJvcGVydHkgc3RyaW5nICRob3N0IEhvc3QgcGFydCwgZm9ybWF0dGVkIGZvciBhIFVSSQogKiBAcHJvcGVydHkgc3RyaW5nICRpaG9zdCBIb3N0IHBhcnQgb2YgdGhlIElSSQogKiBAcHJvcGVydHkgc3RyaW5nICRwb3J0IFBvcnQgcGFydCBvZiB0aGUgSVJJIChhZnRlciAnOicpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJHBhdGggUGF0aCBwYXJ0LCBmb3JtYXR0ZWQgZm9yIGEgVVJJIChhZnRlciBmaXJzdCAnLycpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJGlwYXRoIFBhdGggcGFydCBvZiB0aGUgSVJJIChhZnRlciBmaXJzdCAnLycpCiAqIEBwcm9wZXJ0eSBzdHJpbmcgJHF1ZXJ5IFF1ZXJ5IHBhcnQsIGZvcm1hdHRlZCBmb3IgYSBVUkkgKGFmdGVyICc/JykKICogQHByb3BlcnR5IHN0cmluZyAkaXF1ZXJ5IFF1ZXJ5IHBhcnQgb2YgdGhlIElSSSAoYWZ0ZXIgJz8nKQogKiBAcHJvcGVydHkgc3RyaW5nICRmcmFnbWVudCBGcmFnbWVudCwgZm9ybWF0dGVkIGZvciBhIFVSSSAoYWZ0ZXIgJyMnKQogKiBAcHJvcGVydHkgc3RyaW5nICRpZnJhZ21lbnQgRnJhZ21lbnQgcGFydCBvZiB0aGUgSVJJIChhZnRlciAnIycpCiAqLwpjbGFzcyBSZXF1ZXN0c19JUkkgewoJLyoqCgkgKiBTY2hlbWUKCSAqCgkgKiBAdmFyIHN0cmluZ3xudWxsCgkgKi8KCXByb3RlY3RlZCAkc2NoZW1lID0gbnVsbDsKCgkvKioKCSAqIFVzZXIgSW5mb3JtYXRpb24KCSAqCgkgKiBAdmFyIHN0cmluZ3xudWxsCgkgKi8KCXByb3RlY3RlZCAkaXVzZXJpbmZvID0gbnVsbDsKCgkvKioKCSAqIGlob3N0CgkgKgoJICogQHZhciBzdHJpbmd8bnVsbAoJICovCglwcm90ZWN0ZWQgJGlob3N0ID0gbnVsbDsKCgkvKioKCSAqIFBvcnQKCSAqCgkgKiBAdmFyIHN0cmluZ3xudWxsCgkgKi8KCXByb3RlY3RlZCAkcG9ydCA9IG51bGw7CgoJLyoqCgkgKiBpcGF0aAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkaXBhdGggPSAnJzsKCgkvKioKCSAqIGlxdWVyeQoJICoKCSAqIEB2YXIgc3RyaW5nfG51bGwKCSAqLwoJcHJvdGVjdGVkICRpcXVlcnkgPSBudWxsOwoKCS8qKgoJICogaWZyYWdtZW50fG51bGwKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJGlmcmFnbWVudCA9IG51bGw7CgoJLyoqCgkgKiBOb3JtYWxpemF0aW9uIGRhdGFiYXNlCgkgKgoJICogRWFjaCBrZXkgaXMgdGhlIHNjaGVtZSwgZWFjaCB2YWx1ZSBpcyBhbiBhcnJheSB3aXRoIGVhY2gga2V5IGFzIHRoZSBJUkkKCSAqIHBhcnQgYW5kIHZhbHVlIGFzIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGF0IHBhcnQuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcm90ZWN0ZWQgJG5vcm1hbGl6YXRpb24gPSBhcnJheSgKCQknYWNhcCcgPT4gYXJyYXkoCgkJCSdwb3J0JyA9PiA2NzQKCQkpLAoJCSdkaWN0JyA9PiBhcnJheSgKCQkJJ3BvcnQnID0+IDI2MjgKCQkpLAoJCSdmaWxlJyA9PiBhcnJheSgKCQkJJ2lob3N0JyA9PiAnbG9jYWxob3N0JwoJCSksCgkJJ2h0dHAnID0+IGFycmF5KAoJCQkncG9ydCcgPT4gODAsCgkJKSwKCQknaHR0cHMnID0+IGFycmF5KAoJCQkncG9ydCcgPT4gNDQzLAoJCSksCgkpOwoKCS8qKgoJICogUmV0dXJuIHRoZSBlbnRpcmUgSVJJIHdoZW4geW91IHRyeSBhbmQgcmVhZCB0aGUgb2JqZWN0IGFzIGEgc3RyaW5nCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKSB7CgkJcmV0dXJuICR0aGlzLT5nZXRfaXJpKCk7Cgl9CgoJLyoqCgkgKiBPdmVybG9hZCBfX3NldCgpIHRvIHByb3ZpZGUgYWNjZXNzIHZpYSBwcm9wZXJ0aWVzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBQcm9wZXJ0eSBuYW1lCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFByb3BlcnR5IHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX3NldCgkbmFtZSwgJHZhbHVlKSB7CgkJaWYgKG1ldGhvZF9leGlzdHMoJHRoaXMsICdzZXRfJyAuICRuYW1lKSkgewoJCQljYWxsX3VzZXJfZnVuYyhhcnJheSgkdGhpcywgJ3NldF8nIC4gJG5hbWUpLCAkdmFsdWUpOwoJCX0KCQllbHNlaWYgKAoJCQkgICAkbmFtZSA9PT0gJ2lhdXRob3JpdHknCgkJCXx8ICRuYW1lID09PSAnaXVzZXJpbmZvJwoJCQl8fCAkbmFtZSA9PT0gJ2lob3N0JwoJCQl8fCAkbmFtZSA9PT0gJ2lwYXRoJwoJCQl8fCAkbmFtZSA9PT0gJ2lxdWVyeScKCQkJfHwgJG5hbWUgPT09ICdpZnJhZ21lbnQnCgkJKSB7CgkJCWNhbGxfdXNlcl9mdW5jKGFycmF5KCR0aGlzLCAnc2V0XycgLiBzdWJzdHIoJG5hbWUsIDEpKSwgJHZhbHVlKTsKCQl9Cgl9CgoJLyoqCgkgKiBPdmVybG9hZCBfX2dldCgpIHRvIHByb3ZpZGUgYWNjZXNzIHZpYSBwcm9wZXJ0aWVzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBQcm9wZXJ0eSBuYW1lCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkgewoJCS8vIGlzc2V0KCkgcmV0dXJucyBmYWxzZSBmb3IgbnVsbCwgd2UgZG9uJ3Qgd2FudCB0byBkbyB0aGF0CgkJLy8gQWxzbyB3aHkgd2UgdXNlIGFycmF5X2tleV9leGlzdHMgYmVsb3cgaW5zdGVhZCBvZiBpc3NldCgpCgkJJHByb3BzID0gZ2V0X29iamVjdF92YXJzKCR0aGlzKTsKCgkJaWYgKAoJCQkkbmFtZSA9PT0gJ2lyaScgfHwKCQkJJG5hbWUgPT09ICd1cmknIHx8CgkJCSRuYW1lID09PSAnaWF1dGhvcml0eScgfHwKCQkJJG5hbWUgPT09ICdhdXRob3JpdHknCgkJKSB7CgkJCSRtZXRob2QgPSAnZ2V0XycgLiAkbmFtZTsKCQkJJHJldHVybiA9ICR0aGlzLT4kbWV0aG9kKCk7CgkJfQoJCWVsc2VpZiAoYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJHByb3BzKSkgewoJCQkkcmV0dXJuID0gJHRoaXMtPiRuYW1lOwoJCX0KCQkvLyBob3N0IC0+IGlob3N0CgkJZWxzZWlmICgoJHByb3AgPSAnaScgLiAkbmFtZSkgJiYgYXJyYXlfa2V5X2V4aXN0cygkcHJvcCwgJHByb3BzKSkgewoJCQkkbmFtZSA9ICRwcm9wOwoJCQkkcmV0dXJuID0gJHRoaXMtPiRwcm9wOwoJCX0KCQkvLyBpc2NoZW1lIC0+IHNjaGVtZQoJCWVsc2VpZiAoKCRwcm9wID0gc3Vic3RyKCRuYW1lLCAxKSkgJiYgYXJyYXlfa2V5X2V4aXN0cygkcHJvcCwgJHByb3BzKSkgewoJCQkkbmFtZSA9ICRwcm9wOwoJCQkkcmV0dXJuID0gJHRoaXMtPiRwcm9wOwoJCX0KCQllbHNlIHsKCQkJdHJpZ2dlcl9lcnJvcignVW5kZWZpbmVkIHByb3BlcnR5OiAnIC4gZ2V0X2NsYXNzKCR0aGlzKSAuICc6OicgLiAkbmFtZSwgRV9VU0VSX05PVElDRSk7CgkJCSRyZXR1cm4gPSBudWxsOwoJCX0KCgkJaWYgKCRyZXR1cm4gPT09IG51bGwgJiYgaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJG5hbWVdKSkgewoJCQlyZXR1cm4gJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJG5hbWVdOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuICRyZXR1cm47CgkJfQoJfQoKCS8qKgoJICogT3ZlcmxvYWQgX19pc3NldCgpIHRvIHByb3ZpZGUgYWNjZXNzIHZpYSBwcm9wZXJ0aWVzCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSBQcm9wZXJ0eSBuYW1lCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faXNzZXQoJG5hbWUpIHsKCQlyZXR1cm4gKG1ldGhvZF9leGlzdHMoJHRoaXMsICdnZXRfJyAuICRuYW1lKSB8fCBpc3NldCgkdGhpcy0+JG5hbWUpKTsKCX0KCgkvKioKCSAqIE92ZXJsb2FkIF9fdW5zZXQoKSB0byBwcm92aWRlIGFjY2VzcyB2aWEgcHJvcGVydGllcwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgUHJvcGVydHkgbmFtZQoJICovCglwdWJsaWMgZnVuY3Rpb24gX191bnNldCgkbmFtZSkgewoJCWlmIChtZXRob2RfZXhpc3RzKCR0aGlzLCAnc2V0XycgLiAkbmFtZSkpIHsKCQkJY2FsbF91c2VyX2Z1bmMoYXJyYXkoJHRoaXMsICdzZXRfJyAuICRuYW1lKSwgJycpOwoJCX0KCX0KCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBJUkkgb2JqZWN0LCBmcm9tIGEgc3BlY2lmaWVkIHN0cmluZwoJICoKCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkaXJpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaXJpID0gbnVsbCkgewoJCSR0aGlzLT5zZXRfaXJpKCRpcmkpOwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IElSSSBvYmplY3QgYnkgcmVzb2x2aW5nIGEgcmVsYXRpdmUgSVJJCgkgKgoJICogUmV0dXJucyBmYWxzZSBpZiAkYmFzZSBpcyBub3QgYWJzb2x1dGUsIG90aGVyd2lzZSBhbiBJUkkuCgkgKgoJICogQHBhcmFtIFJlcXVlc3RzX0lSSXxzdHJpbmcgJGJhc2UgKEFic29sdXRlKSBCYXNlIElSSQoJICogQHBhcmFtIFJlcXVlc3RzX0lSSXxzdHJpbmcgJHJlbGF0aXZlIFJlbGF0aXZlIElSSQoJICogQHJldHVybiBSZXF1ZXN0c19JUkl8ZmFsc2UKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhYnNvbHV0aXplKCRiYXNlLCAkcmVsYXRpdmUpIHsKCQlpZiAoISgkcmVsYXRpdmUgaW5zdGFuY2VvZiBSZXF1ZXN0c19JUkkpKSB7CgkJCSRyZWxhdGl2ZSA9IG5ldyBSZXF1ZXN0c19JUkkoJHJlbGF0aXZlKTsKCQl9CgkJaWYgKCEkcmVsYXRpdmUtPmlzX3ZhbGlkKCkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQllbHNlaWYgKCRyZWxhdGl2ZS0+c2NoZW1lICE9PSBudWxsKSB7CgkJCXJldHVybiBjbG9uZSAkcmVsYXRpdmU7CgkJfQoKCQlpZiAoISgkYmFzZSBpbnN0YW5jZW9mIFJlcXVlc3RzX0lSSSkpIHsKCQkJJGJhc2UgPSBuZXcgUmVxdWVzdHNfSVJJKCRiYXNlKTsKCQl9CgkJaWYgKCRiYXNlLT5zY2hlbWUgPT09IG51bGwgfHwgISRiYXNlLT5pc192YWxpZCgpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlmICgkcmVsYXRpdmUtPmdldF9pcmkoKSAhPT0gJycpIHsKCQkJaWYgKCRyZWxhdGl2ZS0+aXVzZXJpbmZvICE9PSBudWxsIHx8ICRyZWxhdGl2ZS0+aWhvc3QgIT09IG51bGwgfHwgJHJlbGF0aXZlLT5wb3J0ICE9PSBudWxsKSB7CgkJCQkkdGFyZ2V0ID0gY2xvbmUgJHJlbGF0aXZlOwoJCQkJJHRhcmdldC0+c2NoZW1lID0gJGJhc2UtPnNjaGVtZTsKCQkJfQoJCQllbHNlIHsKCQkJCSR0YXJnZXQgPSBuZXcgUmVxdWVzdHNfSVJJOwoJCQkJJHRhcmdldC0+c2NoZW1lID0gJGJhc2UtPnNjaGVtZTsKCQkJCSR0YXJnZXQtPml1c2VyaW5mbyA9ICRiYXNlLT5pdXNlcmluZm87CgkJCQkkdGFyZ2V0LT5paG9zdCA9ICRiYXNlLT5paG9zdDsKCQkJCSR0YXJnZXQtPnBvcnQgPSAkYmFzZS0+cG9ydDsKCQkJCWlmICgkcmVsYXRpdmUtPmlwYXRoICE9PSAnJykgewoJCQkJCWlmICgkcmVsYXRpdmUtPmlwYXRoWzBdID09PSAnLycpIHsKCQkJCQkJJHRhcmdldC0+aXBhdGggPSAkcmVsYXRpdmUtPmlwYXRoOwoJCQkJCX0KCQkJCQllbHNlaWYgKCgkYmFzZS0+aXVzZXJpbmZvICE9PSBudWxsIHx8ICRiYXNlLT5paG9zdCAhPT0gbnVsbCB8fCAkYmFzZS0+cG9ydCAhPT0gbnVsbCkgJiYgJGJhc2UtPmlwYXRoID09PSAnJykgewoJCQkJCQkkdGFyZ2V0LT5pcGF0aCA9ICcvJyAuICRyZWxhdGl2ZS0+aXBhdGg7CgkJCQkJfQoJCQkJCWVsc2VpZiAoKCRsYXN0X3NlZ21lbnQgPSBzdHJycG9zKCRiYXNlLT5pcGF0aCwgJy8nKSkgIT09IGZhbHNlKSB7CgkJCQkJCSR0YXJnZXQtPmlwYXRoID0gc3Vic3RyKCRiYXNlLT5pcGF0aCwgMCwgJGxhc3Rfc2VnbWVudCArIDEpIC4gJHJlbGF0aXZlLT5pcGF0aDsKCQkJCQl9CgkJCQkJZWxzZSB7CgkJCQkJCSR0YXJnZXQtPmlwYXRoID0gJHJlbGF0aXZlLT5pcGF0aDsKCQkJCQl9CgkJCQkJJHRhcmdldC0+aXBhdGggPSAkdGFyZ2V0LT5yZW1vdmVfZG90X3NlZ21lbnRzKCR0YXJnZXQtPmlwYXRoKTsKCQkJCQkkdGFyZ2V0LT5pcXVlcnkgPSAkcmVsYXRpdmUtPmlxdWVyeTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCSR0YXJnZXQtPmlwYXRoID0gJGJhc2UtPmlwYXRoOwoJCQkJCWlmICgkcmVsYXRpdmUtPmlxdWVyeSAhPT0gbnVsbCkgewoJCQkJCQkkdGFyZ2V0LT5pcXVlcnkgPSAkcmVsYXRpdmUtPmlxdWVyeTsKCQkJCQl9CgkJCQkJZWxzZWlmICgkYmFzZS0+aXF1ZXJ5ICE9PSBudWxsKSB7CgkJCQkJCSR0YXJnZXQtPmlxdWVyeSA9ICRiYXNlLT5pcXVlcnk7CgkJCQkJfQoJCQkJfQoJCQkJJHRhcmdldC0+aWZyYWdtZW50ID0gJHJlbGF0aXZlLT5pZnJhZ21lbnQ7CgkJCX0KCQl9CgkJZWxzZSB7CgkJCSR0YXJnZXQgPSBjbG9uZSAkYmFzZTsKCQkJJHRhcmdldC0+aWZyYWdtZW50ID0gbnVsbDsKCQl9CgkJJHRhcmdldC0+c2NoZW1lX25vcm1hbGl6YXRpb24oKTsKCQlyZXR1cm4gJHRhcmdldDsKCX0KCgkvKioKCSAqIFBhcnNlIGFuIElSSSBpbnRvIHNjaGVtZS9hdXRob3JpdHkvcGF0aC9xdWVyeS9mcmFnbWVudCBzZWdtZW50cwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlyaQoJICogQHJldHVybiBhcnJheQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VfaXJpKCRpcmkpIHsKCQkkaXJpID0gdHJpbSgkaXJpLCAiXHgyMFx4MDlceDBBXHgwQ1x4MEQiKTsKCQkkaGFzX21hdGNoID0gcHJlZ19tYXRjaCgnL14oKD9QPHNjaGVtZT5bXjpcLz8jXSspOik/KFwvXC8oP1A8YXV0aG9yaXR5PlteXC8/I10qKSk/KD9QPHBhdGg+W14/I10qKShcPyg/UDxxdWVyeT5bXiNdKikpPygjKD9QPGZyYWdtZW50Pi4qKSk/JC8nLCAkaXJpLCAkbWF0Y2gpOwoJCWlmICghJGhhc19tYXRjaCkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdDYW5ub3QgcGFyc2Ugc3VwcGxpZWQgSVJJJywgJ2lyaS5jYW5ub3RfcGFyc2UnLCAkaXJpKTsKCQl9CgoJCWlmICgkbWF0Y2hbMV0gPT09ICcnKSB7CgkJCSRtYXRjaFsnc2NoZW1lJ10gPSBudWxsOwoJCX0KCQlpZiAoIWlzc2V0KCRtYXRjaFszXSkgfHwgJG1hdGNoWzNdID09PSAnJykgewoJCQkkbWF0Y2hbJ2F1dGhvcml0eSddID0gbnVsbDsKCQl9CgkJaWYgKCFpc3NldCgkbWF0Y2hbNV0pKSB7CgkJCSRtYXRjaFsncGF0aCddID0gJyc7CgkJfQoJCWlmICghaXNzZXQoJG1hdGNoWzZdKSB8fCAkbWF0Y2hbNl0gPT09ICcnKSB7CgkJCSRtYXRjaFsncXVlcnknXSA9IG51bGw7CgkJfQoJCWlmICghaXNzZXQoJG1hdGNoWzhdKSB8fCAkbWF0Y2hbOF0gPT09ICcnKSB7CgkJCSRtYXRjaFsnZnJhZ21lbnQnXSA9IG51bGw7CgkJfQoJCXJldHVybiAkbWF0Y2g7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgZG90IHNlZ21lbnRzIGZyb20gYSBwYXRoCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaW5wdXQKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiByZW1vdmVfZG90X3NlZ21lbnRzKCRpbnB1dCkgewoJCSRvdXRwdXQgPSAnJzsKCQl3aGlsZSAoc3RycG9zKCRpbnB1dCwgJy4vJykgIT09IGZhbHNlIHx8IHN0cnBvcygkaW5wdXQsICcvLicpICE9PSBmYWxzZSB8fCAkaW5wdXQgPT09ICcuJyB8fCAkaW5wdXQgPT09ICcuLicpIHsKCQkJLy8gQTogSWYgdGhlIGlucHV0IGJ1ZmZlciBiZWdpbnMgd2l0aCBhIHByZWZpeCBvZiAiLi4vIiBvciAiLi8iLAoJCQkvLyB0aGVuIHJlbW92ZSB0aGF0IHByZWZpeCBmcm9tIHRoZSBpbnB1dCBidWZmZXI7IG90aGVyd2lzZSwKCQkJaWYgKHN0cnBvcygkaW5wdXQsICcuLi8nKSA9PT0gMCkgewoJCQkJJGlucHV0ID0gc3Vic3RyKCRpbnB1dCwgMyk7CgkJCX0KCQkJZWxzZWlmIChzdHJwb3MoJGlucHV0LCAnLi8nKSA9PT0gMCkgewoJCQkJJGlucHV0ID0gc3Vic3RyKCRpbnB1dCwgMik7CgkJCX0KCQkJLy8gQjogaWYgdGhlIGlucHV0IGJ1ZmZlciBiZWdpbnMgd2l0aCBhIHByZWZpeCBvZiAiLy4vIiBvciAiLy4iLAoJCQkvLyB3aGVyZSAiLiIgaXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQsIHRoZW4gcmVwbGFjZSB0aGF0IHByZWZpeAoJCQkvLyB3aXRoICIvIiBpbiB0aGUgaW5wdXQgYnVmZmVyOyBvdGhlcndpc2UsCgkJCWVsc2VpZiAoc3RycG9zKCRpbnB1dCwgJy8uLycpID09PSAwKSB7CgkJCQkkaW5wdXQgPSBzdWJzdHIoJGlucHV0LCAyKTsKCQkJfQoJCQllbHNlaWYgKCRpbnB1dCA9PT0gJy8uJykgewoJCQkJJGlucHV0ID0gJy8nOwoJCQl9CgkJCS8vIEM6IGlmIHRoZSBpbnB1dCBidWZmZXIgYmVnaW5zIHdpdGggYSBwcmVmaXggb2YgIi8uLi8iIG9yICIvLi4iLAoJCQkvLyB3aGVyZSAiLi4iIGlzIGEgY29tcGxldGUgcGF0aCBzZWdtZW50LCB0aGVuIHJlcGxhY2UgdGhhdCBwcmVmaXgKCQkJLy8gd2l0aCAiLyIgaW4gdGhlIGlucHV0IGJ1ZmZlciBhbmQgcmVtb3ZlIHRoZSBsYXN0IHNlZ21lbnQgYW5kIGl0cwoJCQkvLyBwcmVjZWRpbmcgIi8iIChpZiBhbnkpIGZyb20gdGhlIG91dHB1dCBidWZmZXI7IG90aGVyd2lzZSwKCQkJZWxzZWlmIChzdHJwb3MoJGlucHV0LCAnLy4uLycpID09PSAwKSB7CgkJCQkkaW5wdXQgPSBzdWJzdHIoJGlucHV0LCAzKTsKCQkJCSRvdXRwdXQgPSBzdWJzdHJfcmVwbGFjZSgkb3V0cHV0LCAnJywgc3RycnBvcygkb3V0cHV0LCAnLycpKTsKCQkJfQoJCQllbHNlaWYgKCRpbnB1dCA9PT0gJy8uLicpIHsKCQkJCSRpbnB1dCA9ICcvJzsKCQkJCSRvdXRwdXQgPSBzdWJzdHJfcmVwbGFjZSgkb3V0cHV0LCAnJywgc3RycnBvcygkb3V0cHV0LCAnLycpKTsKCQkJfQoJCQkvLyBEOiBpZiB0aGUgaW5wdXQgYnVmZmVyIGNvbnNpc3RzIG9ubHkgb2YgIi4iIG9yICIuLiIsIHRoZW4gcmVtb3ZlCgkJCS8vIHRoYXQgZnJvbSB0aGUgaW5wdXQgYnVmZmVyOyBvdGhlcndpc2UsCgkJCWVsc2VpZiAoJGlucHV0ID09PSAnLicgfHwgJGlucHV0ID09PSAnLi4nKSB7CgkJCQkkaW5wdXQgPSAnJzsKCQkJfQoJCQkvLyBFOiBtb3ZlIHRoZSBmaXJzdCBwYXRoIHNlZ21lbnQgaW4gdGhlIGlucHV0IGJ1ZmZlciB0byB0aGUgZW5kIG9mCgkJCS8vIHRoZSBvdXRwdXQgYnVmZmVyLCBpbmNsdWRpbmcgdGhlIGluaXRpYWwgIi8iIGNoYXJhY3RlciAoaWYgYW55KQoJCQkvLyBhbmQgYW55IHN1YnNlcXVlbnQgY2hhcmFjdGVycyB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIHRoZSBuZXh0CgkJCS8vICIvIiBjaGFyYWN0ZXIgb3IgdGhlIGVuZCBvZiB0aGUgaW5wdXQgYnVmZmVyCgkJCWVsc2VpZiAoKCRwb3MgPSBzdHJwb3MoJGlucHV0LCAnLycsIDEpKSAhPT0gZmFsc2UpIHsKCQkJCSRvdXRwdXQgLj0gc3Vic3RyKCRpbnB1dCwgMCwgJHBvcyk7CgkJCQkkaW5wdXQgPSBzdWJzdHJfcmVwbGFjZSgkaW5wdXQsICcnLCAwLCAkcG9zKTsKCQkJfQoJCQllbHNlIHsKCQkJCSRvdXRwdXQgLj0gJGlucHV0OwoJCQkJJGlucHV0ID0gJyc7CgkJCX0KCQl9CgkJcmV0dXJuICRvdXRwdXQgLiAkaW5wdXQ7Cgl9CgoJLyoqCgkgKiBSZXBsYWNlIGludmFsaWQgY2hhcmFjdGVyIHdpdGggcGVyY2VudCBlbmNvZGluZwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBJbnB1dCBzdHJpbmcKCSAqIEBwYXJhbSBzdHJpbmcgJGV4dHJhX2NoYXJzIFZhbGlkIGNoYXJhY3RlcnMgbm90IGluIGl1bnJlc2VydmVkIG9yCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcHJpdmF0ZSAodGhpcyBpcyBBU0NJSS1vbmx5KQoJICogQHBhcmFtIGJvb2wgJGlwcml2YXRlIEFsbG93IGlwcml2YXRlCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gcmVwbGFjZV9pbnZhbGlkX3dpdGhfcGN0X2VuY29kaW5nKCRzdHJpbmcsICRleHRyYV9jaGFycywgJGlwcml2YXRlID0gZmFsc2UpIHsKCQkvLyBOb3JtYWxpemUgYXMgbWFueSBwY3QtZW5jb2RlZCBzZWN0aW9ucyBhcyBwb3NzaWJsZQoJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJy8oPzolW0EtRmEtZjAtOV17Mn0pKy8nLCBhcnJheSgkdGhpcywgJ3JlbW92ZV9pdW5yZXNlcnZlZF9wZXJjZW50X2VuY29kZWQnKSwgJHN0cmluZyk7CgoJCS8vIFJlcGxhY2UgaW52YWxpZCBwZXJjZW50IGNoYXJhY3RlcnMKCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvJSg/IVtBLUZhLWYwLTldezJ9KS8nLCAnJTI1JywgJHN0cmluZyk7CgoJCS8vIEFkZCB1bnJlc2VydmVkIGFuZCAlIHRvICRleHRyYV9jaGFycyAodGhlIGxhdHRlciBpcyBzYWZlIGJlY2F1c2UgYWxsCgkJLy8gcGN0LWVuY29kZWQgc2VjdGlvbnMgYXJlIG5vdyB2YWxpZCkuCgkJJGV4dHJhX2NoYXJzIC49ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OS0uX34lJzsKCgkJLy8gTm93IHJlcGxhY2UgYW55IGJ5dGVzIHRoYXQgYXJlbid0IGFsbG93ZWQgd2l0aCB0aGVpciBwY3QtZW5jb2RlZCB2ZXJzaW9ucwoJCSRwb3NpdGlvbiA9IDA7CgkJJHN0cmxlbiA9IHN0cmxlbigkc3RyaW5nKTsKCQl3aGlsZSAoKCRwb3NpdGlvbiArPSBzdHJzcG4oJHN0cmluZywgJGV4dHJhX2NoYXJzLCAkcG9zaXRpb24pKSA8ICRzdHJsZW4pIHsKCQkJJHZhbHVlID0gb3JkKCRzdHJpbmdbJHBvc2l0aW9uXSk7CgoJCQkvLyBTdGFydCBwb3NpdGlvbgoJCQkkc3RhcnQgPSAkcG9zaXRpb247CgoJCQkvLyBCeSBkZWZhdWx0IHdlIGFyZSB2YWxpZAoJCQkkdmFsaWQgPSB0cnVlOwoKCQkJLy8gTm8gb25lIGJ5dGUgc2VxdWVuY2VzIGFyZSB2YWxpZCBkdWUgdG8gdGhlIHdoaWxlLgoJCQkvLyBUd28gYnl0ZSBzZXF1ZW5jZToKCQkJaWYgKCgkdmFsdWUgJiAweEUwKSA9PT0gMHhDMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDFGKSA8PCA2OwoJCQkJJGxlbmd0aCA9IDI7CgkJCQkkcmVtYWluaW5nID0gMTsKCQkJfQoJCQkvLyBUaHJlZSBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEYwKSA9PT0gMHhFMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDBGKSA8PCAxMjsKCQkJCSRsZW5ndGggPSAzOwoJCQkJJHJlbWFpbmluZyA9IDI7CgkJCX0KCQkJLy8gRm91ciBieXRlIHNlcXVlbmNlOgoJCQllbHNlaWYgKCgkdmFsdWUgJiAweEY4KSA9PT0gMHhGMCkgewoJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDA3KSA8PCAxODsKCQkJCSRsZW5ndGggPSA0OwoJCQkJJHJlbWFpbmluZyA9IDM7CgkJCX0KCQkJLy8gSW52YWxpZCBieXRlOgoJCQllbHNlIHsKCQkJCSR2YWxpZCA9IGZhbHNlOwoJCQkJJGxlbmd0aCA9IDE7CgkJCQkkcmVtYWluaW5nID0gMDsKCQkJfQoKCQkJaWYgKCRyZW1haW5pbmcpIHsKCQkJCWlmICgkcG9zaXRpb24gKyAkbGVuZ3RoIDw9ICRzdHJsZW4pIHsKCQkJCQlmb3IgKCRwb3NpdGlvbisrOyAkcmVtYWluaW5nOyAkcG9zaXRpb24rKykgewoJCQkJCQkkdmFsdWUgPSBvcmQoJHN0cmluZ1skcG9zaXRpb25dKTsKCgkJCQkJCS8vIENoZWNrIHRoYXQgdGhlIGJ5dGUgaXMgdmFsaWQsIHRoZW4gYWRkIGl0IHRvIHRoZSBjaGFyYWN0ZXI6CgkJCQkJCWlmICgoJHZhbHVlICYgMHhDMCkgPT09IDB4ODApIHsKCQkJCQkJCSRjaGFyYWN0ZXIgfD0gKCR2YWx1ZSAmIDB4M0YpIDw8ICgtLSRyZW1haW5pbmcgKiA2KTsKCQkJCQkJfQoJCQkJCQkvLyBJZiBpdCBpcyBpbnZhbGlkLCBjb3VudCB0aGUgc2VxdWVuY2UgYXMgaW52YWxpZCBhbmQgcmVwcm9jZXNzIHRoZSBjdXJyZW50IGJ5dGU6CgkJCQkJCWVsc2UgewoJCQkJCQkJJHZhbGlkID0gZmFsc2U7CgkJCQkJCQkkcG9zaXRpb24tLTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJJHBvc2l0aW9uID0gJHN0cmxlbiAtIDE7CgkJCQkJJHZhbGlkID0gZmFsc2U7CgkJCQl9CgkJCX0KCgkJCS8vIFBlcmNlbnQgZW5jb2RlIGFueXRoaW5nIGludmFsaWQgb3Igbm90IGluIHVjc2NoYXIKCQkJaWYgKAoJCQkJLy8gSW52YWxpZCBzZXF1ZW5jZXMKCQkJCSEkdmFsaWQKCQkJCS8vIE5vbi1zaG9ydGVzdCBmb3JtIHNlcXVlbmNlcyBhcmUgaW52YWxpZAoJCQkJfHwgJGxlbmd0aCA+IDEgJiYgJGNoYXJhY3RlciA8PSAweDdGCgkJCQl8fCAkbGVuZ3RoID4gMiAmJiAkY2hhcmFjdGVyIDw9IDB4N0ZGCgkJCQl8fCAkbGVuZ3RoID4gMyAmJiAkY2hhcmFjdGVyIDw9IDB4RkZGRgoJCQkJLy8gT3V0c2lkZSBvZiByYW5nZSBvZiB1Y3NjaGFyIGNvZGVwb2ludHMKCQkJCS8vIE5vbmNoYXJhY3RlcnMKCQkJCXx8ICgkY2hhcmFjdGVyICYgMHhGRkZFKSA9PT0gMHhGRkZFCgkJCQl8fCAkY2hhcmFjdGVyID49IDB4RkREMCAmJiAkY2hhcmFjdGVyIDw9IDB4RkRFRgoJCQkJfHwgKAoJCQkJCS8vIEV2ZXJ5dGhpbmcgZWxzZSBub3QgaW4gdWNzY2hhcgoJCQkJCSAgICRjaGFyYWN0ZXIgPiAweEQ3RkYgJiYgJGNoYXJhY3RlciA8IDB4RjkwMAoJCQkJCXx8ICRjaGFyYWN0ZXIgPCAweEEwCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4RUZGRkQKCQkJCSkKCQkJCSYmICgKCQkJCQkvLyBFdmVyeXRoaW5nIG5vdCBpbiBpcHJpdmF0ZSwgaWYgaXQgYXBwbGllcwoJCQkJCSAgICEkaXByaXZhdGUKCQkJCQl8fCAkY2hhcmFjdGVyIDwgMHhFMDAwCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4MTBGRkZECgkJCQkpCgkJCSkgewoJCQkJLy8gSWYgd2Ugd2VyZSBhIGNoYXJhY3RlciwgcHJldGVuZCB3ZSB3ZXJlbid0LCBidXQgcmF0aGVyIGFuIGVycm9yLgoJCQkJaWYgKCR2YWxpZCkgewoJCQkJCSRwb3NpdGlvbi0tOwoJCQkJfQoKCQkJCWZvciAoJGogPSAkc3RhcnQ7ICRqIDw9ICRwb3NpdGlvbjsgJGorKykgewoJCQkJCSRzdHJpbmcgPSBzdWJzdHJfcmVwbGFjZSgkc3RyaW5nLCBzcHJpbnRmKCclJSUwMlgnLCBvcmQoJHN0cmluZ1skal0pKSwgJGosIDEpOwoJCQkJCSRqICs9IDI7CgkJCQkJJHBvc2l0aW9uICs9IDI7CgkJCQkJJHN0cmxlbiArPSAyOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCgkvKioKCSAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciBwcmVnX3JlcGxhY2VfY2FsbGJhY2suCgkgKgoJICogUmVtb3ZlcyBzZXF1ZW5jZXMgb2YgcGVyY2VudCBlbmNvZGVkIGJ5dGVzIHRoYXQgcmVwcmVzZW50IFVURi04CgkgKiBlbmNvZGVkIGNoYXJhY3RlcnMgaW4gaXVucmVzZXJ2ZWQKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJG1hdGNoIFBDUkUgbWF0Y2gKCSAqIEByZXR1cm4gc3RyaW5nIFJlcGxhY2VtZW50CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiByZW1vdmVfaXVucmVzZXJ2ZWRfcGVyY2VudF9lbmNvZGVkKCRtYXRjaCkgewoJCS8vIEFzIHdlIGp1c3QgaGF2ZSB2YWxpZCBwZXJjZW50IGVuY29kZWQgc2VxdWVuY2VzIHdlIGNhbiBqdXN0IGV4cGxvZGUKCQkvLyBhbmQgaWdub3JlIHRoZSBmaXJzdCBtZW1iZXIgb2YgdGhlIHJldHVybmVkIGFycmF5IChhbiBlbXB0eSBzdHJpbmcpLgoJCSRieXRlcyA9IGV4cGxvZGUoJyUnLCAkbWF0Y2hbMF0pOwoKCQkvLyBJbml0aWFsaXplIHRoZSBuZXcgc3RyaW5nICh0aGlzIGlzIHdoYXQgd2lsbCBiZSByZXR1cm5lZCkgYW5kIHRoYXQKCQkvLyB0aGVyZSBhcmUgbm8gYnl0ZXMgcmVtYWluaW5nIGluIHRoZSBjdXJyZW50IHNlcXVlbmNlICh1bnN1cnByaXNpbmcKCQkvLyBhdCB0aGUgZmlyc3QgYnl0ZSEpLgoJCSRzdHJpbmcgPSAnJzsKCQkkcmVtYWluaW5nID0gMDsKCgkJLy8gTG9vcCBvdmVyIGVhY2ggYW5kIGV2ZXJ5IGJ5dGUsIGFuZCBzZXQgJHZhbHVlIHRvIGl0cyB2YWx1ZQoJCWZvciAoJGkgPSAxLCAkbGVuID0gY291bnQoJGJ5dGVzKTsgJGkgPCAkbGVuOyAkaSsrKSB7CgkJCSR2YWx1ZSA9IGhleGRlYygkYnl0ZXNbJGldKTsKCgkJCS8vIElmIHdlJ3JlIHRoZSBmaXJzdCBieXRlIG9mIHNlcXVlbmNlOgoJCQlpZiAoISRyZW1haW5pbmcpIHsKCQkJCS8vIFN0YXJ0IHBvc2l0aW9uCgkJCQkkc3RhcnQgPSAkaTsKCgkJCQkvLyBCeSBkZWZhdWx0IHdlIGFyZSB2YWxpZAoJCQkJJHZhbGlkID0gdHJ1ZTsKCgkJCQkvLyBPbmUgYnl0ZSBzZXF1ZW5jZToKCQkJCWlmICgkdmFsdWUgPD0gMHg3RikgewoJCQkJCSRjaGFyYWN0ZXIgPSAkdmFsdWU7CgkJCQkJJGxlbmd0aCA9IDE7CgkJCQl9CgkJCQkvLyBUd28gYnl0ZSBzZXF1ZW5jZToKCQkJCWVsc2VpZiAoKCR2YWx1ZSAmIDB4RTApID09PSAweEMwKSB7CgkJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDFGKSA8PCA2OwoJCQkJCSRsZW5ndGggPSAyOwoJCQkJCSRyZW1haW5pbmcgPSAxOwoJCQkJfQoJCQkJLy8gVGhyZWUgYnl0ZSBzZXF1ZW5jZToKCQkJCWVsc2VpZiAoKCR2YWx1ZSAmIDB4RjApID09PSAweEUwKSB7CgkJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDBGKSA8PCAxMjsKCQkJCQkkbGVuZ3RoID0gMzsKCQkJCQkkcmVtYWluaW5nID0gMjsKCQkJCX0KCQkJCS8vIEZvdXIgYnl0ZSBzZXF1ZW5jZToKCQkJCWVsc2VpZiAoKCR2YWx1ZSAmIDB4RjgpID09PSAweEYwKSB7CgkJCQkJJGNoYXJhY3RlciA9ICgkdmFsdWUgJiAweDA3KSA8PCAxODsKCQkJCQkkbGVuZ3RoID0gNDsKCQkJCQkkcmVtYWluaW5nID0gMzsKCQkJCX0KCQkJCS8vIEludmFsaWQgYnl0ZToKCQkJCWVsc2UgewoJCQkJCSR2YWxpZCA9IGZhbHNlOwoJCQkJCSRyZW1haW5pbmcgPSAwOwoJCQkJfQoJCQl9CgkJCS8vIENvbnRpbnVhdGlvbiBieXRlOgoJCQllbHNlIHsKCQkJCS8vIENoZWNrIHRoYXQgdGhlIGJ5dGUgaXMgdmFsaWQsIHRoZW4gYWRkIGl0IHRvIHRoZSBjaGFyYWN0ZXI6CgkJCQlpZiAoKCR2YWx1ZSAmIDB4QzApID09PSAweDgwKSB7CgkJCQkJJHJlbWFpbmluZy0tOwoJCQkJCSRjaGFyYWN0ZXIgfD0gKCR2YWx1ZSAmIDB4M0YpIDw8ICgkcmVtYWluaW5nICogNik7CgkJCQl9CgkJCQkvLyBJZiBpdCBpcyBpbnZhbGlkLCBjb3VudCB0aGUgc2VxdWVuY2UgYXMgaW52YWxpZCBhbmQgcmVwcm9jZXNzIHRoZSBjdXJyZW50IGJ5dGUgYXMgdGhlIHN0YXJ0IG9mIGEgc2VxdWVuY2U6CgkJCQllbHNlIHsKCQkJCQkkdmFsaWQgPSBmYWxzZTsKCQkJCQkkcmVtYWluaW5nID0gMDsKCQkJCQkkaS0tOwoJCQkJfQoJCQl9CgoJCQkvLyBJZiB3ZSd2ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgYnl0ZSBzZXF1ZW5jZSwgYXBwZW5kIGl0IHRvIFVuaWNvZGU6OiRkYXRhCgkJCWlmICghJHJlbWFpbmluZykgewoJCQkJLy8gUGVyY2VudCBlbmNvZGUgYW55dGhpbmcgaW52YWxpZCBvciBub3QgaW4gaXVucmVzZXJ2ZWQKCQkJCWlmICgKCQkJCQkvLyBJbnZhbGlkIHNlcXVlbmNlcwoJCQkJCSEkdmFsaWQKCQkJCQkvLyBOb24tc2hvcnRlc3QgZm9ybSBzZXF1ZW5jZXMgYXJlIGludmFsaWQKCQkJCQl8fCAkbGVuZ3RoID4gMSAmJiAkY2hhcmFjdGVyIDw9IDB4N0YKCQkJCQl8fCAkbGVuZ3RoID4gMiAmJiAkY2hhcmFjdGVyIDw9IDB4N0ZGCgkJCQkJfHwgJGxlbmd0aCA+IDMgJiYgJGNoYXJhY3RlciA8PSAweEZGRkYKCQkJCQkvLyBPdXRzaWRlIG9mIHJhbmdlIG9mIGl1bnJlc2VydmVkIGNvZGVwb2ludHMKCQkJCQl8fCAkY2hhcmFjdGVyIDwgMHgyRAoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweEVGRkZECgkJCQkJLy8gTm9uY2hhcmFjdGVycwoJCQkJCXx8ICgkY2hhcmFjdGVyICYgMHhGRkZFKSA9PT0gMHhGRkZFCgkJCQkJfHwgJGNoYXJhY3RlciA+PSAweEZERDAgJiYgJGNoYXJhY3RlciA8PSAweEZERUYKCQkJCQkvLyBFdmVyeXRoaW5nIGVsc2Ugbm90IGluIGl1bnJlc2VydmVkICh0aGlzIGlzIGFsbCBCTVApCgkJCQkJfHwgJGNoYXJhY3RlciA9PT0gMHgyRgoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweDM5ICYmICRjaGFyYWN0ZXIgPCAweDQxCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4NUEgJiYgJGNoYXJhY3RlciA8IDB4NjEKCQkJCQl8fCAkY2hhcmFjdGVyID4gMHg3QSAmJiAkY2hhcmFjdGVyIDwgMHg3RQoJCQkJCXx8ICRjaGFyYWN0ZXIgPiAweDdFICYmICRjaGFyYWN0ZXIgPCAweEEwCgkJCQkJfHwgJGNoYXJhY3RlciA+IDB4RDdGRiAmJiAkY2hhcmFjdGVyIDwgMHhGOTAwCgkJCQkpIHsKCQkJCQlmb3IgKCRqID0gJHN0YXJ0OyAkaiA8PSAkaTsgJGorKykgewoJCQkJCQkkc3RyaW5nIC49ICclJyAuIHN0cnRvdXBwZXIoJGJ5dGVzWyRqXSk7CgkJCQkJfQoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJZm9yICgkaiA9ICRzdGFydDsgJGogPD0gJGk7ICRqKyspIHsKCQkJCQkJJHN0cmluZyAuPSBjaHIoaGV4ZGVjKCRieXRlc1skal0pKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCS8vIElmIHdlIGhhdmUgYW55IGJ5dGVzIGxlZnQgb3ZlciB0aGV5IGFyZSBpbnZhbGlkIChpLmUuLCB3ZSBhcmUKCQkvLyBtaWQtd2F5IHRocm91Z2ggYSBtdWx0aS1ieXRlIHNlcXVlbmNlKQoJCWlmICgkcmVtYWluaW5nKSB7CgkJCWZvciAoJGogPSAkc3RhcnQ7ICRqIDwgJGxlbjsgJGorKykgewoJCQkJJHN0cmluZyAuPSAnJScgLiBzdHJ0b3VwcGVyKCRieXRlc1skal0pOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2NoZW1lX25vcm1hbGl6YXRpb24oKSB7CgkJaWYgKGlzc2V0KCR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydpdXNlcmluZm8nXSkgJiYgJHRoaXMtPml1c2VyaW5mbyA9PT0gJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2l1c2VyaW5mbyddKSB7CgkJCSR0aGlzLT5pdXNlcmluZm8gPSBudWxsOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lob3N0J10pICYmICR0aGlzLT5paG9zdCA9PT0gJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lob3N0J10pIHsKCQkJJHRoaXMtPmlob3N0ID0gbnVsbDsKCQl9CgkJaWYgKGlzc2V0KCR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydwb3J0J10pICYmICR0aGlzLT5wb3J0ID09PSAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsncG9ydCddKSB7CgkJCSR0aGlzLT5wb3J0ID0gbnVsbDsKCQl9CgkJaWYgKGlzc2V0KCR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydpcGF0aCddKSAmJiAkdGhpcy0+aXBhdGggPT09ICR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydpcGF0aCddKSB7CgkJCSR0aGlzLT5pcGF0aCA9ICcnOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPmlob3N0KSAmJiBlbXB0eSgkdGhpcy0+aXBhdGgpKSB7CgkJCSR0aGlzLT5pcGF0aCA9ICcvJzsKCQl9CgkJaWYgKGlzc2V0KCR0aGlzLT5ub3JtYWxpemF0aW9uWyR0aGlzLT5zY2hlbWVdWydpcXVlcnknXSkgJiYgJHRoaXMtPmlxdWVyeSA9PT0gJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lxdWVyeSddKSB7CgkJCSR0aGlzLT5pcXVlcnkgPSBudWxsOwoJCX0KCQlpZiAoaXNzZXQoJHRoaXMtPm5vcm1hbGl6YXRpb25bJHRoaXMtPnNjaGVtZV1bJ2lmcmFnbWVudCddKSAmJiAkdGhpcy0+aWZyYWdtZW50ID09PSAkdGhpcy0+bm9ybWFsaXphdGlvblskdGhpcy0+c2NoZW1lXVsnaWZyYWdtZW50J10pIHsKCQkJJHRoaXMtPmlmcmFnbWVudCA9IG51bGw7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIG9iamVjdCByZXByZXNlbnRzIGEgdmFsaWQgSVJJLiBUaGlzIG5lZWRzIHRvIGJlIGRvbmUgb24gZWFjaAoJICogY2FsbCBhcyBzb21lIHRoaW5ncyBjaGFuZ2UgZGVwZW5kaW5nIG9uIGFub3RoZXIgcGFydCBvZiB0aGUgSVJJLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfdmFsaWQoKSB7CgkJJGlzYXV0aG9yaXR5ID0gJHRoaXMtPml1c2VyaW5mbyAhPT0gbnVsbCB8fCAkdGhpcy0+aWhvc3QgIT09IG51bGwgfHwgJHRoaXMtPnBvcnQgIT09IG51bGw7CgkJaWYgKCR0aGlzLT5pcGF0aCAhPT0gJycgJiYKCQkJKAoJCQkJJGlzYXV0aG9yaXR5ICYmICR0aGlzLT5pcGF0aFswXSAhPT0gJy8nIHx8CgkJCQkoCgkJCQkJJHRoaXMtPnNjaGVtZSA9PT0gbnVsbCAmJgoJCQkJCSEkaXNhdXRob3JpdHkgJiYKCQkJCQlzdHJwb3MoJHRoaXMtPmlwYXRoLCAnOicpICE9PSBmYWxzZSAmJgoJCQkJCShzdHJwb3MoJHRoaXMtPmlwYXRoLCAnLycpID09PSBmYWxzZSA/IHRydWUgOiBzdHJwb3MoJHRoaXMtPmlwYXRoLCAnOicpIDwgc3RycG9zKCR0aGlzLT5pcGF0aCwgJy8nKSkKCQkJCSkKCQkJKQoJCSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgZW50aXJlIElSSS4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUgKGlmIHRoZXJlCgkgKiBhcmUgYW55IGludmFsaWQgY2hhcmFjdGVycykuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXJpCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9pcmkoJGlyaSkgewoJCXN0YXRpYyAkY2FjaGU7CgkJaWYgKCEkY2FjaGUpIHsKCQkJJGNhY2hlID0gYXJyYXkoKTsKCQl9CgoJCWlmICgkaXJpID09PSBudWxsKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCQlpZiAoaXNzZXQoJGNhY2hlWyRpcmldKSkgewoJCQlsaXN0KCR0aGlzLT5zY2hlbWUsCgkJCQkgJHRoaXMtPml1c2VyaW5mbywKCQkJCSAkdGhpcy0+aWhvc3QsCgkJCQkgJHRoaXMtPnBvcnQsCgkJCQkgJHRoaXMtPmlwYXRoLAoJCQkJICR0aGlzLT5pcXVlcnksCgkJCQkgJHRoaXMtPmlmcmFnbWVudCwKCQkJCSAkcmV0dXJuKSA9ICRjYWNoZVskaXJpXTsKCQkJcmV0dXJuICRyZXR1cm47CgkJfQoKCQkkcGFyc2VkID0gJHRoaXMtPnBhcnNlX2lyaSgoc3RyaW5nKSAkaXJpKTsKCgkJJHJldHVybiA9ICR0aGlzLT5zZXRfc2NoZW1lKCRwYXJzZWRbJ3NjaGVtZSddKQoJCQkmJiAkdGhpcy0+c2V0X2F1dGhvcml0eSgkcGFyc2VkWydhdXRob3JpdHknXSkKCQkJJiYgJHRoaXMtPnNldF9wYXRoKCRwYXJzZWRbJ3BhdGgnXSkKCQkJJiYgJHRoaXMtPnNldF9xdWVyeSgkcGFyc2VkWydxdWVyeSddKQoJCQkmJiAkdGhpcy0+c2V0X2ZyYWdtZW50KCRwYXJzZWRbJ2ZyYWdtZW50J10pOwoKCQkkY2FjaGVbJGlyaV0gPSBhcnJheSgkdGhpcy0+c2NoZW1lLAoJCQkJCQkJICR0aGlzLT5pdXNlcmluZm8sCgkJCQkJCQkgJHRoaXMtPmlob3N0LAoJCQkJCQkJICR0aGlzLT5wb3J0LAoJCQkJCQkJICR0aGlzLT5pcGF0aCwKCQkJCQkJCSAkdGhpcy0+aXF1ZXJ5LAoJCQkJCQkJICR0aGlzLT5pZnJhZ21lbnQsCgkJCQkJCQkgJHJldHVybik7CgkJcmV0dXJuICRyZXR1cm47Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHNjaGVtZS4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUgKGlmIHRoZXJlIGFyZQoJICogYW55IGludmFsaWQgY2hhcmFjdGVycykuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2NoZW1lCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9zY2hlbWUoJHNjaGVtZSkgewoJCWlmICgkc2NoZW1lID09PSBudWxsKSB7CgkJCSR0aGlzLT5zY2hlbWUgPSBudWxsOwoJCX0KCQllbHNlaWYgKCFwcmVnX21hdGNoKCcvXltBLVphLXpdWzAtOUEtWmEteitcLS5dKiQvJywgJHNjaGVtZSkpIHsKCQkJJHRoaXMtPnNjaGVtZSA9IG51bGw7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJZWxzZSB7CgkJCSR0aGlzLT5zY2hlbWUgPSBzdHJ0b2xvd2VyKCRzY2hlbWUpOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgYXV0aG9yaXR5LiBSZXR1cm5zIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZSAoaWYgdGhlcmUgYXJlCgkgKiBhbnkgaW52YWxpZCBjaGFyYWN0ZXJzKS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRhdXRob3JpdHkKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X2F1dGhvcml0eSgkYXV0aG9yaXR5KSB7CgkJc3RhdGljICRjYWNoZTsKCQlpZiAoISRjYWNoZSkgewoJCQkkY2FjaGUgPSBhcnJheSgpOwoJCX0KCgkJaWYgKCRhdXRob3JpdHkgPT09IG51bGwpIHsKCQkJJHRoaXMtPml1c2VyaW5mbyA9IG51bGw7CgkJCSR0aGlzLT5paG9zdCA9IG51bGw7CgkJCSR0aGlzLT5wb3J0ID0gbnVsbDsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCWlmIChpc3NldCgkY2FjaGVbJGF1dGhvcml0eV0pKSB7CgkJCWxpc3QoJHRoaXMtPml1c2VyaW5mbywKCQkJCSAkdGhpcy0+aWhvc3QsCgkJCQkgJHRoaXMtPnBvcnQsCgkJCQkgJHJldHVybikgPSAkY2FjaGVbJGF1dGhvcml0eV07CgoJCQlyZXR1cm4gJHJldHVybjsKCQl9CgoJCSRyZW1haW5pbmcgPSAkYXV0aG9yaXR5OwoJCWlmICgoJGl1c2VyaW5mb19lbmQgPSBzdHJycG9zKCRyZW1haW5pbmcsICdAJykpICE9PSBmYWxzZSkgewoJCQkkaXVzZXJpbmZvID0gc3Vic3RyKCRyZW1haW5pbmcsIDAsICRpdXNlcmluZm9fZW5kKTsKCQkJJHJlbWFpbmluZyA9IHN1YnN0cigkcmVtYWluaW5nLCAkaXVzZXJpbmZvX2VuZCArIDEpOwoJCX0KCQllbHNlIHsKCQkJJGl1c2VyaW5mbyA9IG51bGw7CgkJfQoJCWlmICgoJHBvcnRfc3RhcnQgPSBzdHJwb3MoJHJlbWFpbmluZywgJzonLCBzdHJwb3MoJHJlbWFpbmluZywgJ10nKSkpICE9PSBmYWxzZSkgewoJCQkkcG9ydCA9IHN1YnN0cigkcmVtYWluaW5nLCAkcG9ydF9zdGFydCArIDEpOwoJCQlpZiAoJHBvcnQgPT09IGZhbHNlIHx8ICRwb3J0ID09PSAnJykgewoJCQkJJHBvcnQgPSBudWxsOwoJCQl9CgkJCSRyZW1haW5pbmcgPSBzdWJzdHIoJHJlbWFpbmluZywgMCwgJHBvcnRfc3RhcnQpOwoJCX0KCQllbHNlIHsKCQkJJHBvcnQgPSBudWxsOwoJCX0KCgkJJHJldHVybiA9ICR0aGlzLT5zZXRfdXNlcmluZm8oJGl1c2VyaW5mbykgJiYKCQkJCSAgJHRoaXMtPnNldF9ob3N0KCRyZW1haW5pbmcpICYmCgkJCQkgICR0aGlzLT5zZXRfcG9ydCgkcG9ydCk7CgoJCSRjYWNoZVskYXV0aG9yaXR5XSA9IGFycmF5KCR0aGlzLT5pdXNlcmluZm8sCgkJCQkJCQkJICAgJHRoaXMtPmlob3N0LAoJCQkJCQkJCSAgICR0aGlzLT5wb3J0LAoJCQkJCQkJCSAgICRyZXR1cm4pOwoKCQlyZXR1cm4gJHJldHVybjsKCX0KCgkvKioKCSAqIFNldCB0aGUgaXVzZXJpbmZvLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGl1c2VyaW5mbwoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRfdXNlcmluZm8oJGl1c2VyaW5mbykgewoJCWlmICgkaXVzZXJpbmZvID09PSBudWxsKSB7CgkJCSR0aGlzLT5pdXNlcmluZm8gPSBudWxsOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPml1c2VyaW5mbyA9ICR0aGlzLT5yZXBsYWNlX2ludmFsaWRfd2l0aF9wY3RfZW5jb2RpbmcoJGl1c2VyaW5mbywgJyEkJlwnKCkqKyw7PTonKTsKCQkJJHRoaXMtPnNjaGVtZV9ub3JtYWxpemF0aW9uKCk7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgaWhvc3QuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlIChpZiB0aGVyZSBhcmUKCSAqIGFueSBpbnZhbGlkIGNoYXJhY3RlcnMpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlob3N0CgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9ob3N0KCRpaG9zdCkgewoJCWlmICgkaWhvc3QgPT09IG51bGwpIHsKCQkJJHRoaXMtPmlob3N0ID0gbnVsbDsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCWlmIChzdWJzdHIoJGlob3N0LCAwLCAxKSA9PT0gJ1snICYmIHN1YnN0cigkaWhvc3QsIC0xKSA9PT0gJ10nKSB7CgkJCWlmIChSZXF1ZXN0c19JUHY2OjpjaGVja19pcHY2KHN1YnN0cigkaWhvc3QsIDEsIC0xKSkpIHsKCQkJCSR0aGlzLT5paG9zdCA9ICdbJyAuIFJlcXVlc3RzX0lQdjY6OmNvbXByZXNzKHN1YnN0cigkaWhvc3QsIDEsIC0xKSkgLiAnXSc7CgkJCX0KCQkJZWxzZSB7CgkJCQkkdGhpcy0+aWhvc3QgPSBudWxsOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJCWVsc2UgewoJCQkkaWhvc3QgPSAkdGhpcy0+cmVwbGFjZV9pbnZhbGlkX3dpdGhfcGN0X2VuY29kaW5nKCRpaG9zdCwgJyEkJlwnKCkqKyw7PScpOwoKCQkJLy8gTG93ZXJjYXNlLCBidXQgaWdub3JlIHBjdC1lbmNvZGVkIHNlY3Rpb25zIChhcyB0aGV5IHNob3VsZAoJCQkvLyByZW1haW4gdXBwZXJjYXNlKS4gVGhpcyBtdXN0IGJlIGRvbmUgYWZ0ZXIgdGhlIHByZXZpb3VzIHN0ZXAKCQkJLy8gYXMgdGhhdCBjYW4gYWRkIHVuZXNjYXBlZCBjaGFyYWN0ZXJzLgoJCQkkcG9zaXRpb24gPSAwOwoJCQkkc3RybGVuID0gc3RybGVuKCRpaG9zdCk7CgkJCXdoaWxlICgoJHBvc2l0aW9uICs9IHN0cmNzcG4oJGlob3N0LCAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVolJywgJHBvc2l0aW9uKSkgPCAkc3RybGVuKSB7CgkJCQlpZiAoJGlob3N0WyRwb3NpdGlvbl0gPT09ICclJykgewoJCQkJCSRwb3NpdGlvbiArPSAzOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJJGlob3N0WyRwb3NpdGlvbl0gPSBzdHJ0b2xvd2VyKCRpaG9zdFskcG9zaXRpb25dKTsKCQkJCQkkcG9zaXRpb24rKzsKCQkJCX0KCQkJfQoKCQkJJHRoaXMtPmlob3N0ID0gJGlob3N0OwoJCX0KCgkJJHRoaXMtPnNjaGVtZV9ub3JtYWxpemF0aW9uKCk7CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBwb3J0LiBSZXR1cm5zIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZSAoaWYgdGhlcmUgYXJlCgkgKiBhbnkgaW52YWxpZCBjaGFyYWN0ZXJzKS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwb3J0CgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9wb3J0KCRwb3J0KSB7CgkJaWYgKCRwb3J0ID09PSBudWxsKSB7CgkJCSR0aGlzLT5wb3J0ID0gbnVsbDsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlpZiAoc3Ryc3BuKCRwb3J0LCAnMDEyMzQ1Njc4OScpID09PSBzdHJsZW4oJHBvcnQpKSB7CgkJCSR0aGlzLT5wb3J0ID0gKGludCkgJHBvcnQ7CgkJCSR0aGlzLT5zY2hlbWVfbm9ybWFsaXphdGlvbigpOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSR0aGlzLT5wb3J0ID0gbnVsbDsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGlwYXRoLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlwYXRoCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9wYXRoKCRpcGF0aCkgewoJCXN0YXRpYyAkY2FjaGU7CgkJaWYgKCEkY2FjaGUpIHsKCQkJJGNhY2hlID0gYXJyYXkoKTsKCQl9CgoJCSRpcGF0aCA9IChzdHJpbmcpICRpcGF0aDsKCgkJaWYgKGlzc2V0KCRjYWNoZVskaXBhdGhdKSkgewoJCQkkdGhpcy0+aXBhdGggPSAkY2FjaGVbJGlwYXRoXVsoaW50KSAoJHRoaXMtPnNjaGVtZSAhPT0gbnVsbCldOwoJCX0KCQllbHNlIHsKCQkJJHZhbGlkID0gJHRoaXMtPnJlcGxhY2VfaW52YWxpZF93aXRoX3BjdF9lbmNvZGluZygkaXBhdGgsICchJCZcJygpKissOz1AOi8nKTsKCQkJJHJlbW92ZWQgPSAkdGhpcy0+cmVtb3ZlX2RvdF9zZWdtZW50cygkdmFsaWQpOwoKCQkJJGNhY2hlWyRpcGF0aF0gPSBhcnJheSgkdmFsaWQsICRyZW1vdmVkKTsKCQkJJHRoaXMtPmlwYXRoID0gKCR0aGlzLT5zY2hlbWUgIT09IG51bGwpID8gJHJlbW92ZWQgOiAkdmFsaWQ7CgkJfQoJCSR0aGlzLT5zY2hlbWVfbm9ybWFsaXphdGlvbigpOwoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogU2V0IHRoZSBpcXVlcnkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaXF1ZXJ5CgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldF9xdWVyeSgkaXF1ZXJ5KSB7CgkJaWYgKCRpcXVlcnkgPT09IG51bGwpIHsKCQkJJHRoaXMtPmlxdWVyeSA9IG51bGw7CgkJfQoJCWVsc2UgewoJCQkkdGhpcy0+aXF1ZXJ5ID0gJHRoaXMtPnJlcGxhY2VfaW52YWxpZF93aXRoX3BjdF9lbmNvZGluZygkaXF1ZXJ5LCAnISQmXCcoKSorLDs9OkAvPycsIHRydWUpOwoJCQkkdGhpcy0+c2NoZW1lX25vcm1hbGl6YXRpb24oKTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGlmcmFnbWVudC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRpZnJhZ21lbnQKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X2ZyYWdtZW50KCRpZnJhZ21lbnQpIHsKCQlpZiAoJGlmcmFnbWVudCA9PT0gbnVsbCkgewoJCQkkdGhpcy0+aWZyYWdtZW50ID0gbnVsbDsKCQl9CgkJZWxzZSB7CgkJCSR0aGlzLT5pZnJhZ21lbnQgPSAkdGhpcy0+cmVwbGFjZV9pbnZhbGlkX3dpdGhfcGN0X2VuY29kaW5nKCRpZnJhZ21lbnQsICchJCZcJygpKissOz06QC8/Jyk7CgkJCSR0aGlzLT5zY2hlbWVfbm9ybWFsaXphdGlvbigpOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIENvbnZlcnQgYW4gSVJJIHRvIGEgVVJJIChvciBwYXJ0cyB0aGVyZW9mKQoJICoKCSAqIEBwYXJhbSBzdHJpbmd8Ym9vbCBJUkkgdG8gY29udmVydCAob3IgZmFsc2UgZnJvbSB7QHNlZSBnZXRfaXJpfSkKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFVSSSBpZiBJUkkgaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHRvX3VyaSgkc3RyaW5nKSB7CgkJaWYgKCFpc19zdHJpbmcoJHN0cmluZykpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJc3RhdGljICRub25fYXNjaWk7CgkJaWYgKCEkbm9uX2FzY2lpKSB7CgkJCSRub25fYXNjaWkgPSBpbXBsb2RlKCcnLCByYW5nZSgiXHg4MCIsICJceEZGIikpOwoJCX0KCgkJJHBvc2l0aW9uID0gMDsKCQkkc3RybGVuID0gc3RybGVuKCRzdHJpbmcpOwoJCXdoaWxlICgoJHBvc2l0aW9uICs9IHN0cmNzcG4oJHN0cmluZywgJG5vbl9hc2NpaSwgJHBvc2l0aW9uKSkgPCAkc3RybGVuKSB7CgkJCSRzdHJpbmcgPSBzdWJzdHJfcmVwbGFjZSgkc3RyaW5nLCBzcHJpbnRmKCclJSUwMlgnLCBvcmQoJHN0cmluZ1skcG9zaXRpb25dKSksICRwb3NpdGlvbiwgMSk7CgkJCSRwb3NpdGlvbiArPSAzOwoJCQkkc3RybGVuICs9IDI7CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tcGxldGUgSVJJCgkgKgoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9pcmkoKSB7CgkJaWYgKCEkdGhpcy0+aXNfdmFsaWQoKSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkaXJpID0gJyc7CgkJaWYgKCR0aGlzLT5zY2hlbWUgIT09IG51bGwpIHsKCQkJJGlyaSAuPSAkdGhpcy0+c2NoZW1lIC4gJzonOwoJCX0KCQlpZiAoKCRpYXV0aG9yaXR5ID0gJHRoaXMtPmdldF9pYXV0aG9yaXR5KCkpICE9PSBudWxsKSB7CgkJCSRpcmkgLj0gJy8vJyAuICRpYXV0aG9yaXR5OwoJCX0KCQkkaXJpIC49ICR0aGlzLT5pcGF0aDsKCQlpZiAoJHRoaXMtPmlxdWVyeSAhPT0gbnVsbCkgewoJCQkkaXJpIC49ICc/JyAuICR0aGlzLT5pcXVlcnk7CgkJfQoJCWlmICgkdGhpcy0+aWZyYWdtZW50ICE9PSBudWxsKSB7CgkJCSRpcmkgLj0gJyMnIC4gJHRoaXMtPmlmcmFnbWVudDsKCQl9CgoJCXJldHVybiAkaXJpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21wbGV0ZSBVUkkKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3VyaSgpIHsKCQlyZXR1cm4gJHRoaXMtPnRvX3VyaSgkdGhpcy0+Z2V0X2lyaSgpKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29tcGxldGUgaWF1dGhvcml0eQoJICoKCSAqIEByZXR1cm4gc3RyaW5nfG51bGwKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9pYXV0aG9yaXR5KCkgewoJCWlmICgkdGhpcy0+aXVzZXJpbmZvID09PSBudWxsICYmICR0aGlzLT5paG9zdCA9PT0gbnVsbCAmJiAkdGhpcy0+cG9ydCA9PT0gbnVsbCkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCSRpYXV0aG9yaXR5ID0gJyc7CgkJaWYgKCR0aGlzLT5pdXNlcmluZm8gIT09IG51bGwpIHsKCQkJJGlhdXRob3JpdHkgLj0gJHRoaXMtPml1c2VyaW5mbyAuICdAJzsKCQl9CgkJaWYgKCR0aGlzLT5paG9zdCAhPT0gbnVsbCkgewoJCQkkaWF1dGhvcml0eSAuPSAkdGhpcy0+aWhvc3Q7CgkJfQoJCWlmICgkdGhpcy0+cG9ydCAhPT0gbnVsbCkgewoJCQkkaWF1dGhvcml0eSAuPSAnOicgLiAkdGhpcy0+cG9ydDsKCQl9CgkJcmV0dXJuICRpYXV0aG9yaXR5OwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb21wbGV0ZSBhdXRob3JpdHkKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2F1dGhvcml0eSgpIHsKCQkkaWF1dGhvcml0eSA9ICR0aGlzLT5nZXRfaWF1dGhvcml0eSgpOwoJCWlmIChpc19zdHJpbmcoJGlhdXRob3JpdHkpKSB7CgkJCXJldHVybiAkdGhpcy0+dG9fdXJpKCRpYXV0aG9yaXR5KTsKCQl9CgkJZWxzZSB7CgkJCXJldHVybiAkaWF1dGhvcml0eTsKCQl9Cgl9Cn0KPD9waHAKLyoqCiAqIEJhc2UgSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwoKLyoqCiAqIEJhc2UgSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwppbnRlcmZhY2UgUmVxdWVzdHNfVHJhbnNwb3J0IHsKCS8qKgoJICogUGVyZm9ybSBhIHJlcXVlc3QKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBBc3NvY2lhdGl2ZSBhcnJheSBvZiByZXF1ZXN0IGhlYWRlcnMKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyB0aGUgUE9TVCBib2R5LCBvciBhcyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwgZm9yIGEgR0VUL0hFQUQKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBSZXF1ZXN0IG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqIEByZXR1cm4gc3RyaW5nIFJhdyBIVFRQIHJlc3VsdAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVxdWVzdCgkdXJsLCAkaGVhZGVycyA9IGFycmF5KCksICRkYXRhID0gYXJyYXkoKSwgJG9wdGlvbnMgPSBhcnJheSgpKTsKCgkvKioKCSAqIFNlbmQgbXVsdGlwbGUgcmVxdWVzdHMgc2ltdWx0YW5lb3VzbHkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlcXVlc3RzIFJlcXVlc3QgZGF0YSAoYXJyYXkgb2YgJ3VybCcsICdoZWFkZXJzJywgJ2RhdGEnLCAnb3B0aW9ucycpIGFzIHBlciB7QHNlZSBSZXF1ZXN0c19UcmFuc3BvcnQ6OnJlcXVlc3R9CgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2YgUmVxdWVzdHNfUmVzcG9uc2Ugb2JqZWN0cyAobWF5IGNvbnRhaW4gUmVxdWVzdHNfRXhjZXB0aW9uIG9yIHN0cmluZyByZXNwb25zZXMgYXMgd2VsbCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3RfbXVsdGlwbGUoJHJlcXVlc3RzLCAkb3B0aW9ucyk7CgoJLyoqCgkgKiBTZWxmLXRlc3Qgd2hldGhlciB0aGUgdHJhbnNwb3J0IGNhbiBiZSB1c2VkCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0ZXN0KCk7Cn0KPD9waHAKCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9UcmFuc3BvcnQgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb24gewoKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTUgVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MTUgVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxNSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTU7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAyIFBheW1lbnQgUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAyIFBheW1lbnQgUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDIgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDAyOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1BheW1lbnQgUmVxdWlyZWQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwNSBNZXRob2QgTm90IEFsbG93ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA1IE1ldGhvZCBOb3QgQWxsb3dlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwNSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDU7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnTWV0aG9kIE5vdCBBbGxvd2VkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MDMgRm9yYmlkZGVuIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwMyBGb3JiaWRkZW4gcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDMgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDAzOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0ZvcmJpZGRlbic7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgMzA1IFVzZSBQcm94eSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciAzMDUgVXNlIFByb3h5IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfMzA1IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDMwNTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVc2UgUHJveHknOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIHVua25vd24gc3RhdHVzIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIHVua25vd24gc3RhdHVzIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfVW5rbm93biBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcnxib29sIENvZGUgaWYgYXZhaWxhYmxlLCBmYWxzZSBpZiBhbiBlcnJvciBvY2N1cnJlZAoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSAwOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1Vua25vd24nOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IGV4Y2VwdGlvbgoJICoKCSAqIElmIGAkZGF0YWAgaXMgYW4gaW5zdGFuY2Ugb2Yge0BzZWUgUmVxdWVzdHNfUmVzcG9uc2V9LCB1c2VzIHRoZSBzdGF0dXMKCSAqIGNvZGUgZnJvbSBpdC4gT3RoZXJ3aXNlLCBzZXRzIGFzIDAKCSAqCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHJlYXNvbiBSZWFzb24gcGhyYXNlCgkgKiBAcGFyYW0gbWl4ZWQgJGRhdGEgQXNzb2NpYXRlZCBkYXRhCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcmVhc29uID0gbnVsbCwgJGRhdGEgPSBudWxsKSB7CgkJaWYgKCRkYXRhIGluc3RhbmNlb2YgUmVxdWVzdHNfUmVzcG9uc2UpIHsKCQkJJHRoaXMtPmNvZGUgPSAkZGF0YS0+c3RhdHVzX2NvZGU7CgkJfQoKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCRyZWFzb24sICRkYXRhKTsKCX0KfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTggSSdtIEEgVGVhcG90IHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyMzI0CiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDE4IEknbSBBIFRlYXBvdCByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjMyNAogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDE4IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQxODsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICJJJ20gQSBUZWFwb3QiOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3IgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTAwIEludGVybmFsIFNlcnZlciBFcnJvciByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwMCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDA7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnSW50ZXJuYWwgU2VydmVyIEVycm9yJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTEgTGVuZ3RoIFJlcXVpcmVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMSBMZW5ndGggUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTEgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDExOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0xlbmd0aCBSZXF1aXJlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTAyIEJhZCBHYXRld2F5IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMiBCYWQgR2F0ZXdheSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzUwMiBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA1MDI7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnQmFkIEdhdGV3YXknOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNCBSZXF1ZXN0LVVSSSBUb28gTGFyZ2UgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDE0IFJlcXVlc3QtVVJJIFRvbyBMYXJnZSByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxNCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTQ7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUmVxdWVzdC1VUkkgVG9vIExhcmdlJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA1MDQgR2F0ZXdheSBUaW1lb3V0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwNCBHYXRld2F5IFRpbWVvdXQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF81MDQgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNTA0OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0dhdGV3YXkgVGltZW91dCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDEwIEdvbmUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDEwIEdvbmUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTAgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDEwOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0dvbmUnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMyBTZXJ2aWNlIFVuYXZhaWxhYmxlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMyBTZXJ2aWNlIFVuYXZhaWxhYmxlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNTAzIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDUwMzsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdTZXJ2aWNlIFVuYXZhaWxhYmxlJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MzEgUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZSByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU4NQogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQzMSBSZXF1ZXN0IEhlYWRlciBGaWVsZHMgVG9vIExhcmdlIHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2NTg1CiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MzEgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDMxOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1JlcXVlc3QgSGVhZGVyIEZpZWxkcyBUb28gTGFyZ2UnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNyBFeHBlY3RhdGlvbiBGYWlsZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDE3IEV4cGVjdGF0aW9uIEZhaWxlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQxNyBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MTc7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnRXhwZWN0YXRpb24gRmFpbGVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MTMgUmVxdWVzdCBFbnRpdHkgVG9vIExhcmdlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMyBSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MTMgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDEzOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAwIEJhZCBSZXF1ZXN0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwMCBCYWQgUmVxdWVzdCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwMCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDA7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnQmFkIFJlcXVlc3QnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMiBQcmVjb25kaXRpb24gRmFpbGVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxMiBQcmVjb25kaXRpb24gRmFpbGVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDEyIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQxMjsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdQcmVjb25kaXRpb24gRmFpbGVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciAzMDYgU3dpdGNoIFByb3h5IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDMwNiBTd2l0Y2ggUHJveHkgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF8zMDYgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gMzA2OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1N3aXRjaCBQcm94eSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA5IENvbmZsaWN0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwOSBDb25mbGljdCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwOSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDk7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnQ29uZmxpY3QnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNiBSZXF1ZXN0ZWQgUmFuZ2UgTm90IFNhdGlzZmlhYmxlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQxNiBSZXF1ZXN0ZWQgUmFuZ2UgTm90IFNhdGlzZmlhYmxlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDE2IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQxNjsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdSZXF1ZXN0ZWQgUmFuZ2UgTm90IFNhdGlzZmlhYmxlJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MjkgVG9vIE1hbnkgUmVxdWVzdHMgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL2RyYWZ0LW5vdHRpbmdoYW0taHR0cC1uZXctc3RhdHVzLTA0CiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDI5IFRvbyBNYW55IFJlcXVlc3RzIHJlc3BvbnNlcwogKgogKiBAc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9kcmFmdC1ub3R0aW5naGFtLWh0dHAtbmV3LXN0YXR1cy0wNAogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDI5IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQyOTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdUb28gTWFueSBSZXF1ZXN0cyc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDI4IFByZWNvbmRpdGlvbiBSZXF1aXJlZCByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU4NQogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQyOCBQcmVjb25kaXRpb24gUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1ODUKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQyOCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0Mjg7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUHJlY29uZGl0aW9uIFJlcXVpcmVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MDggUmVxdWVzdCBUaW1lb3V0IHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwOCBSZXF1ZXN0IFRpbWVvdXQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF80MDggZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNDA4OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ1JlcXVlc3QgVGltZW91dCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA0IE5vdCBGb3VuZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA0MDQgTm90IEZvdW5kIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA0IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwNDsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdOb3QgRm91bmQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwNSBIVFRQIFZlcnNpb24gTm90IFN1cHBvcnRlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA1MDUgSFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF81MDUgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNTA1OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ0hUVFAgVmVyc2lvbiBOb3QgU3VwcG9ydGVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciAzMDQgTm90IE1vZGlmaWVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDMwNCBOb3QgTW9kaWZpZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF8zMDQgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gMzA0OwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ05vdCBNb2RpZmllZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNTExIE5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWQgcmVzcG9uc2VzCiAqCiAqIEBzZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1ODUKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCgovKioKICogRXhjZXB0aW9uIGZvciA1MTEgTmV0d29yayBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZCByZXNwb25zZXMKICoKICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU4NQogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNTExIGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDUxMTsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdOZXR3b3JrIEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA0MDYgTm90IEFjY2VwdGFibGUgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA2IE5vdCBBY2NlcHRhYmxlIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KY2xhc3MgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA2IGV4dGVuZHMgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFAgewoJLyoqCgkgKiBIVFRQIHN0YXR1cyBjb2RlCgkgKgoJICogQHZhciBpbnRlZ2VyCgkgKi8KCXByb3RlY3RlZCAkY29kZSA9IDQwNjsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdOb3QgQWNjZXB0YWJsZSc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDA3IFByb3h5IEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwNyBQcm94eSBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwNyBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDc7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWQnOwp9Cjw/cGhwCi8qKgogKiBFeGNlcHRpb24gZm9yIDQwMSBVbmF1dGhvcml6ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBmb3IgNDAxIFVuYXV0aG9yaXplZCByZXNwb25zZXMKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQXzQwMSBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQIHsKCS8qKgoJICogSFRUUCBzdGF0dXMgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSA0MDE7CgoJLyoqCgkgKiBSZWFzb24gcGhyYXNlCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRyZWFzb24gPSAnVW5hdXRob3JpemVkJzsKfQo8P3BocAovKioKICogRXhjZXB0aW9uIGZvciA1MDEgTm90IEltcGxlbWVudGVkIHJlc3BvbnNlcwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKi8KCi8qKgogKiBFeGNlcHRpb24gZm9yIDUwMSBOb3QgSW1wbGVtZW50ZWQgcmVzcG9uc2VzCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUF81MDEgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gNTAxOwoKCS8qKgoJICogUmVhc29uIHBocmFzZQoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkcmVhc29uID0gJ05vdCBJbXBsZW1lbnRlZCc7Cn0KPD9waHAKLyoqCiAqIEV4Y2VwdGlvbiBiYXNlZCBvbiBIVFRQIHJlc3BvbnNlCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEV4Y2VwdGlvbiBiYXNlZCBvbiBIVFRQIHJlc3BvbnNlCiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCBleHRlbmRzIFJlcXVlc3RzX0V4Y2VwdGlvbiB7CgkvKioKCSAqIEhUVFAgc3RhdHVzIGNvZGUKCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJcHJvdGVjdGVkICRjb2RlID0gMDsKCgkvKioKCSAqIFJlYXNvbiBwaHJhc2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVbmtub3duJzsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBleGNlcHRpb24KCSAqCgkgKiBUaGVyZSBpcyBubyBtZWNoYW5pc20gdG8gcGFzcyBpbiB0aGUgc3RhdHVzIGNvZGUsIGFzIHRoaXMgaXMgc2V0IGJ5IHRoZQoJICogc3ViY2xhc3MgdXNlZC4gUmVhc29uIHBocmFzZXMgY2FuIHZhcnksIGhvd2V2ZXIuCgkgKgoJICogQHBhcmFtIHN0cmluZ3xudWxsICRyZWFzb24gUmVhc29uIHBocmFzZQoJICogQHBhcmFtIG1peGVkICRkYXRhIEFzc29jaWF0ZWQgZGF0YQoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlYXNvbiA9IG51bGwsICRkYXRhID0gbnVsbCkgewoJCWlmICgkcmVhc29uICE9PSBudWxsKSB7CgkJCSR0aGlzLT5yZWFzb24gPSAkcmVhc29uOwoJCX0KCgkJJG1lc3NhZ2UgPSBzcHJpbnRmKCclZCAlcycsICR0aGlzLT5jb2RlLCAkdGhpcy0+cmVhc29uKTsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAnaHR0cHJlc3BvbnNlJywgJGRhdGEsICR0aGlzLT5jb2RlKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgc3RhdHVzIG1lc3NhZ2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldFJlYXNvbigpIHsKCQlyZXR1cm4gJHRoaXMtPnJlYXNvbjsKCX0KCgkvKioKCSAqIEdldCB0aGUgY29ycmVjdCBleGNlcHRpb24gY2xhc3MgZm9yIGEgZ2l2ZW4gZXJyb3IgY29kZQoJICoKCSAqIEBwYXJhbSBpbnR8Ym9vbCAkY29kZSBIVFRQIHN0YXR1cyBjb2RlLCBvciBmYWxzZSBpZiB1bmF2YWlsYWJsZQoJICogQHJldHVybiBzdHJpbmcgRXhjZXB0aW9uIGNsYXNzIG5hbWUgdG8gdXNlCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NsYXNzKCRjb2RlKSB7CgkJaWYgKCEkY29kZSkgewoJCQlyZXR1cm4gJ1JlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQX1Vua25vd24nOwoJCX0KCgkJJGNsYXNzID0gc3ByaW50ZignUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfJWQnLCAkY29kZSk7CgkJaWYgKGNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CgkJCXJldHVybiAkY2xhc3M7CgkJfQoKCQlyZXR1cm4gJ1JlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQX1Vua25vd24nOwoJfQp9Cjw/cGhwCgpjbGFzcyBSZXF1ZXN0c19FeGNlcHRpb25fVHJhbnNwb3J0X2NVUkwgZXh0ZW5kcyBSZXF1ZXN0c19FeGNlcHRpb25fVHJhbnNwb3J0IHsKCgljb25zdCBFQVNZICA9ICdjVVJMRWFzeSc7Cgljb25zdCBNVUxUSSA9ICdjVVJMTXVsdGknOwoJY29uc3QgU0hBUkUgPSAnY1VSTFNoYXJlJzsKCgkvKioKCSAqIGNVUkwgZXJyb3IgY29kZQoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwcm90ZWN0ZWQgJGNvZGUgPSAtMTsKCgkvKioKCSAqIFdoaWNoIHR5cGUgb2YgY1VSTCBlcnJvcgoJICoKCSAqIEVBU1l8TVVMVEl8U0hBUkUKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHR5cGUgPSAnVW5rbm93bic7CgoJLyoqCgkgKiBDbGVhciB0ZXh0IGVycm9yIG1lc3NhZ2UKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHJlYXNvbiA9ICdVbmtub3duJzsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsICR0eXBlLCAkZGF0YSA9IG51bGwsICRjb2RlID0gMCkgewoJCWlmICgkdHlwZSAhPT0gbnVsbCkgewoJCQkkdGhpcy0+dHlwZSA9ICR0eXBlOwoJCX0KCgkJaWYgKCRjb2RlICE9PSBudWxsKSB7CgkJCSR0aGlzLT5jb2RlID0gJGNvZGU7CgkJfQoKCQlpZiAoJG1lc3NhZ2UgIT09IG51bGwpIHsKCQkJJHRoaXMtPnJlYXNvbiA9ICRtZXNzYWdlOwoJCX0KCgkJJG1lc3NhZ2UgPSBzcHJpbnRmKCclZCAlcycsICR0aGlzLT5jb2RlLCAkdGhpcy0+cmVhc29uKTsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkdGhpcy0+dHlwZSwgJGRhdGEsICR0aGlzLT5jb2RlKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgZXJyb3IgbWVzc2FnZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0UmVhc29uKCkgewoJCXJldHVybiAkdGhpcy0+cmVhc29uOwoJfQoKfQo8P3BocAovKioKICogSGFuZGxlcyBhZGRpbmcgYW5kIGRpc3BhdGNoaW5nIGV2ZW50cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCgovKioKICogSGFuZGxlcyBhZGRpbmcgYW5kIGRpc3BhdGNoaW5nIGV2ZW50cwogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBVdGlsaXRpZXMKICovCmNsYXNzIFJlcXVlc3RzX0hvb2tzIGltcGxlbWVudHMgUmVxdWVzdHNfSG9va2VyIHsKCS8qKgoJICogUmVnaXN0ZXJlZCBjYWxsYmFja3MgZm9yIGVhY2ggaG9vawoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRob29rcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBDb25zdHJ1Y3RvcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJLy8gcGFzcwoJfQoKCS8qKgoJICogUmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSBob29rCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBjYWxsYmFjayAkY2FsbGJhY2sgRnVuY3Rpb24vbWV0aG9kIHRvIGNhbGwgb24gZXZlbnQKCSAqIEBwYXJhbSBpbnQgJHByaW9yaXR5IFByaW9yaXR5IG51bWJlci4gPDAgaXMgZXhlY3V0ZWQgZWFybGllciwgPjAgaXMgZXhlY3V0ZWQgbGF0ZXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRob29rLCAkY2FsbGJhY2ssICRwcmlvcml0eSA9IDApIHsKCQlpZiAoIWlzc2V0KCR0aGlzLT5ob29rc1skaG9va10pKSB7CgkJCSR0aGlzLT5ob29rc1skaG9va10gPSBhcnJheSgpOwoJCX0KCQlpZiAoIWlzc2V0KCR0aGlzLT5ob29rc1skaG9va11bJHByaW9yaXR5XSkpIHsKCQkJJHRoaXMtPmhvb2tzWyRob29rXVskcHJpb3JpdHldID0gYXJyYXkoKTsKCQl9CgoJCSR0aGlzLT5ob29rc1skaG9va11bJHByaW9yaXR5XVtdID0gJGNhbGxiYWNrOwoJfQoKCS8qKgoJICogRGlzcGF0Y2ggYSBtZXNzYWdlCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaG9vayBIb29rIG5hbWUKCSAqIEBwYXJhbSBhcnJheSAkcGFyYW1ldGVycyBQYXJhbWV0ZXJzIHRvIHBhc3MgdG8gY2FsbGJhY2tzCgkgKiBAcmV0dXJuIGJvb2xlYW4gU3VjY2Vzc2Z1bG5lc3MKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoKCRob29rLCAkcGFyYW1ldGVycyA9IGFycmF5KCkpIHsKCQlpZiAoZW1wdHkoJHRoaXMtPmhvb2tzWyRob29rXSkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJZm9yZWFjaCAoJHRoaXMtPmhvb2tzWyRob29rXSBhcyAkcHJpb3JpdHkgPT4gJGhvb2tlZCkgewoJCQlmb3JlYWNoICgkaG9va2VkIGFzICRjYWxsYmFjaykgewoJCQkJY2FsbF91c2VyX2Z1bmNfYXJyYXkoJGNhbGxiYWNrLCAkcGFyYW1ldGVycyk7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQp9Cjw/cGhwCi8qKgogKiBBdXRoZW50aWNhdGlvbiBwcm92aWRlciBpbnRlcmZhY2UKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgQXV0aGVudGljYXRpb24KICovCgovKioKICogQXV0aGVudGljYXRpb24gcHJvdmlkZXIgaW50ZXJmYWNlCiAqCiAqIEltcGxlbWVudCB0aGlzIGludGVyZmFjZSB0byBhY3QgYXMgYW4gYXV0aGVudGljYXRpb24gcHJvdmlkZXIuCiAqCiAqIFBhcmFtZXRlcnMgc2hvdWxkIGJlIHBhc3NlZCB2aWEgdGhlIGNvbnN0cnVjdG9yIHdoZXJlIHBvc3NpYmxlLCBhcyB0aGlzCiAqIG1ha2VzIGl0IG11Y2ggZWFzaWVyIGZvciB1c2VycyB0byB1c2UgeW91ciBwcm92aWRlci4KICoKICogQHNlZSBSZXF1ZXN0c19Ib29rcwogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBBdXRoZW50aWNhdGlvbgogKi8KaW50ZXJmYWNlIFJlcXVlc3RzX0F1dGggewoJLyoqCgkgKiBSZWdpc3RlciBob29rcyBhcyBuZWVkZWQKCSAqCgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaW4ge0BzZWUgUmVxdWVzdHM6OnJlcXVlc3R9IHdoZW4gdGhlIHVzZXIgaGFzIHNldAoJICogYW4gaW5zdGFuY2UgYXMgdGhlICdhdXRoJyBvcHRpb24uIFVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlZ2lzdGVyIGFsbCB0aGUKCSAqIGhvb2tzIHlvdSdsbCBuZWVkLgoJICoKCSAqIEBzZWUgUmVxdWVzdHNfSG9va3M6OnJlZ2lzdGVyCgkgKiBAcGFyYW0gUmVxdWVzdHNfSG9va3MgJGhvb2tzIEhvb2sgc3lzdGVtCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWdpc3RlcihSZXF1ZXN0c19Ib29rcyAkaG9va3MpOwp9Cjw/cGhwCi8qKgogKiBjVVJMIEhUVFAgdHJhbnNwb3J0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFRyYW5zcG9ydAogKi8KCi8qKgogKiBjVVJMIEhUVFAgdHJhbnNwb3J0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFRyYW5zcG9ydAogKi8KY2xhc3MgUmVxdWVzdHNfVHJhbnNwb3J0X2NVUkwgaW1wbGVtZW50cyBSZXF1ZXN0c19UcmFuc3BvcnQgewoJY29uc3QgQ1VSTF83XzEwXzUgPSAweDA3MEEwNTsKCWNvbnN0IENVUkxfN18xNl8yID0gMHgwNzEwMDI7CgoJLyoqCgkgKiBSYXcgSFRUUCBkYXRhCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRoZWFkZXJzID0gJyc7CgoJLyoqCgkgKiBSYXcgYm9keSBkYXRhCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRyZXNwb25zZV9kYXRhID0gJyc7CgoJLyoqCgkgKiBJbmZvcm1hdGlvbiBvbiB0aGUgY3VycmVudCByZXF1ZXN0CgkgKgoJICogQHZhciBhcnJheSBjVVJMIGluZm9ybWF0aW9uIGFycmF5LCBzZWUge0BzZWUgaHR0cHM6Ly9zZWN1cmUucGhwLm5ldC9jdXJsX2dldGluZm99CgkgKi8KCXB1YmxpYyAkaW5mbzsKCgkvKioKCSAqIGNVUkwgdmVyc2lvbiBudW1iZXIKCSAqCgkgKiBAdmFyIGludAoJICovCglwdWJsaWMgJHZlcnNpb247CgoJLyoqCgkgKiBjVVJMIGhhbmRsZQoJICoKCSAqIEB2YXIgcmVzb3VyY2UKCSAqLwoJcHJvdGVjdGVkICRoYW5kbGU7CgoJLyoqCgkgKiBIb29rIGRpc3BhdGNoZXIgaW5zdGFuY2UKCSAqCgkgKiBAdmFyIFJlcXVlc3RzX0hvb2tzCgkgKi8KCXByb3RlY3RlZCAkaG9va3M7CgoJLyoqCgkgKiBIYXZlIHdlIGZpbmlzaGVkIHRoZSBoZWFkZXJzIHlldD8KCSAqCgkgKiBAdmFyIGJvb2xlYW4KCSAqLwoJcHJvdGVjdGVkICRkb25lX2hlYWRlcnMgPSBmYWxzZTsKCgkvKioKCSAqIElmIHN0cmVhbWluZyB0byBhIGZpbGUsIGtlZXAgdGhlIGZpbGUgcG9pbnRlcgoJICoKCSAqIEB2YXIgcmVzb3VyY2UKCSAqLwoJcHJvdGVjdGVkICRzdHJlYW1faGFuZGxlOwoKCS8qKgoJICogSG93IG1hbnkgYnl0ZXMgYXJlIGluIHRoZSByZXNwb25zZSBib2R5PwoJICoKCSAqIEB2YXIgaW50CgkgKi8KCXByb3RlY3RlZCAkcmVzcG9uc2VfYnl0ZXM7CgoJLyoqCgkgKiBXaGF0J3MgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHdlIHNob3VsZCBrZWVwPwoJICoKCSAqIEB2YXIgaW50fGJvb2wgQnl0ZSBjb3VudCwgb3IgZmFsc2UgaWYgbm8gbGltaXQuCgkgKi8KCXByb3RlY3RlZCAkcmVzcG9uc2VfYnl0ZV9saW1pdDsKCgkvKioKCSAqIENvbnN0cnVjdG9yCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQkkY3VybCAgICAgICAgICA9IGN1cmxfdmVyc2lvbigpOwoJCSR0aGlzLT52ZXJzaW9uID0gJGN1cmxbJ3ZlcnNpb25fbnVtYmVyJ107CgkJJHRoaXMtPmhhbmRsZSAgPSBjdXJsX2luaXQoKTsKCgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9IRUFERVIsIGZhbHNlKTsKCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1JFVFVSTlRSQU5TRkVSLCAxKTsKCQlpZiAoJHRoaXMtPnZlcnNpb24gPj0gc2VsZjo6Q1VSTF83XzEwXzUpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9FTkNPRElORywgJycpOwoJCX0KCQlpZiAoZGVmaW5lZCgnQ1VSTE9QVF9QUk9UT0NPTFMnKSkgewoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5Db25zdGFudHMuTmV3Q29uc3RhbnRzLmN1cmxvcHRfcHJvdG9jb2xzRm91bmQKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9QUk9UT0NPTFMsIENVUkxQUk9UT19IVFRQIHwgQ1VSTFBST1RPX0hUVFBTKTsKCQl9CgkJaWYgKGRlZmluZWQoJ0NVUkxPUFRfUkVESVJfUFJPVE9DT0xTJykpIHsKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuQ29uc3RhbnRzLk5ld0NvbnN0YW50cy5jdXJsb3B0X3JlZGlyX3Byb3RvY29sc0ZvdW5kCgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfUkVESVJfUFJPVE9DT0xTLCBDVVJMUFJPVE9fSFRUUCB8IENVUkxQUk9UT19IVFRQUyk7CgkJfQoJfQoKCS8qKgoJICogRGVzdHJ1Y3RvcgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpIHsKCQlpZiAoaXNfcmVzb3VyY2UoJHRoaXMtPmhhbmRsZSkpIHsKCQkJY3VybF9jbG9zZSgkdGhpcy0+aGFuZGxlKTsKCQl9Cgl9CgoJLyoqCgkgKiBQZXJmb3JtIGEgcmVxdWVzdAoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGEgY1VSTCBlcnJvciAoYGN1cmxlcnJvcmApCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0byByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcmVxdWVzdCBoZWFkZXJzCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkYXRhIERhdGEgdG8gc2VuZCBlaXRoZXIgYXMgdGhlIFBPU1QgYm9keSwgb3IgYXMgcGFyYW1ldGVycyBpbiB0aGUgVVJMIGZvciBhIEdFVC9IRUFECgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgUmVxdWVzdCBvcHRpb25zLCBzZWUge0BzZWUgUmVxdWVzdHM6OnJlc3BvbnNlKCl9IGZvciBkb2N1bWVudGF0aW9uCgkgKiBAcmV0dXJuIHN0cmluZyBSYXcgSFRUUCByZXN1bHQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3QoJHVybCwgJGhlYWRlcnMgPSBhcnJheSgpLCAkZGF0YSA9IGFycmF5KCksICRvcHRpb25zID0gYXJyYXkoKSkgewoJCSR0aGlzLT5ob29rcyA9ICRvcHRpb25zWydob29rcyddOwoKCQkkdGhpcy0+c2V0dXBfaGFuZGxlKCR1cmwsICRoZWFkZXJzLCAkZGF0YSwgJG9wdGlvbnMpOwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYmVmb3JlX3NlbmQnLCBhcnJheSgmJHRoaXMtPmhhbmRsZSkpOwoKCQlpZiAoJG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIT09IGZhbHNlKSB7CgkJCSR0aGlzLT5zdHJlYW1faGFuZGxlID0gZm9wZW4oJG9wdGlvbnNbJ2ZpbGVuYW1lJ10sICd3YicpOwoJCX0KCgkJJHRoaXMtPnJlc3BvbnNlX2RhdGEgICAgICAgPSAnJzsKCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZXMgICAgICA9IDA7CgkJJHRoaXMtPnJlc3BvbnNlX2J5dGVfbGltaXQgPSBmYWxzZTsKCQlpZiAoJG9wdGlvbnNbJ21heF9ieXRlcyddICE9PSBmYWxzZSkgewoJCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCA9ICRvcHRpb25zWydtYXhfYnl0ZXMnXTsKCQl9CgoJCWlmIChpc3NldCgkb3B0aW9uc1sndmVyaWZ5J10pKSB7CgkJCWlmICgkb3B0aW9uc1sndmVyaWZ5J10gPT09IGZhbHNlKSB7CgkJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1NTTF9WRVJJRllIT1NULCAwKTsKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIsIDApOwoJCQl9CgkJCWVsc2VpZiAoaXNfc3RyaW5nKCRvcHRpb25zWyd2ZXJpZnknXSkpIHsKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQ0FJTkZPLCAkb3B0aW9uc1sndmVyaWZ5J10pOwoJCQl9CgkJfQoKCQlpZiAoaXNzZXQoJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSkgJiYgJG9wdGlvbnNbJ3ZlcmlmeW5hbWUnXSA9PT0gZmFsc2UpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCwgMCk7CgkJfQoKCQljdXJsX2V4ZWMoJHRoaXMtPmhhbmRsZSk7CgkJJHJlc3BvbnNlID0gJHRoaXMtPnJlc3BvbnNlX2RhdGE7CgoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnY3VybC5hZnRlcl9zZW5kJywgYXJyYXkoKSk7CgoJCWlmIChjdXJsX2Vycm5vKCR0aGlzLT5oYW5kbGUpID09PSAyMyB8fCBjdXJsX2Vycm5vKCR0aGlzLT5oYW5kbGUpID09PSA2MSkgewoJCQkvLyBSZXNldCBlbmNvZGluZyBhbmQgdHJ5IGFnYWluCgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfRU5DT0RJTkcsICdub25lJyk7CgoJCQkkdGhpcy0+cmVzcG9uc2VfZGF0YSAgPSAnJzsKCQkJJHRoaXMtPnJlc3BvbnNlX2J5dGVzID0gMDsKCQkJY3VybF9leGVjKCR0aGlzLT5oYW5kbGUpOwoJCQkkcmVzcG9uc2UgPSAkdGhpcy0+cmVzcG9uc2VfZGF0YTsKCQl9CgoJCSR0aGlzLT5wcm9jZXNzX3Jlc3BvbnNlKCRyZXNwb25zZSwgJG9wdGlvbnMpOwoKCQkvLyBOZWVkIHRvIHJlbW92ZSB0aGUgJHRoaXMgcmVmZXJlbmNlIGZyb20gdGhlIGN1cmwgaGFuZGxlLgoJCS8vIE90aGVyd2lzZSBSZXF1ZXN0c19UcmFuc3BvcnRfY1VSTCB3b250IGJlIGdhcmJhZ2UgY29sbGVjdGVkIGFuZCB0aGUgY3VybF9jbG9zZSgpIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLgoJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfSEVBREVSRlVOQ1RJT04sIG51bGwpOwoJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfV1JJVEVGVU5DVElPTiwgbnVsbCk7CgoJCXJldHVybiAkdGhpcy0+aGVhZGVyczsKCX0KCgkvKioKCSAqIFNlbmQgbXVsdGlwbGUgcmVxdWVzdHMgc2ltdWx0YW5lb3VzbHkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlcXVlc3RzIFJlcXVlc3QgZGF0YQoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIEdsb2JhbCBvcHRpb25zCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIFJlcXVlc3RzX1Jlc3BvbnNlIG9iamVjdHMgKG1heSBjb250YWluIFJlcXVlc3RzX0V4Y2VwdGlvbiBvciBzdHJpbmcgcmVzcG9uc2VzIGFzIHdlbGwpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0X211bHRpcGxlKCRyZXF1ZXN0cywgJG9wdGlvbnMpIHsKCQkvLyBJZiB5b3UncmUgbm90IHJlcXVlc3RpbmcsIHdlIGNhbid0IGdldCBhbnkgcmVzcG9uc2VzIMKvXF8o44OEKV8vwq8KCQlpZiAoZW1wdHkoJHJlcXVlc3RzKSkgewoJCQlyZXR1cm4gYXJyYXkoKTsKCQl9CgoJCSRtdWx0aWhhbmRsZSA9IGN1cmxfbXVsdGlfaW5pdCgpOwoJCSRzdWJyZXF1ZXN0cyA9IGFycmF5KCk7CgkJJHN1YmhhbmRsZXMgID0gYXJyYXkoKTsKCgkJJGNsYXNzID0gZ2V0X2NsYXNzKCR0aGlzKTsKCQlmb3JlYWNoICgkcmVxdWVzdHMgYXMgJGlkID0+ICRyZXF1ZXN0KSB7CgkJCSRzdWJyZXF1ZXN0c1skaWRdID0gbmV3ICRjbGFzcygpOwoJCQkkc3ViaGFuZGxlc1skaWRdICA9ICRzdWJyZXF1ZXN0c1skaWRdLT5nZXRfc3VicmVxdWVzdF9oYW5kbGUoJHJlcXVlc3RbJ3VybCddLCAkcmVxdWVzdFsnaGVhZGVycyddLCAkcmVxdWVzdFsnZGF0YSddLCAkcmVxdWVzdFsnb3B0aW9ucyddKTsKCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYmVmb3JlX211bHRpX2FkZCcsIGFycmF5KCYkc3ViaGFuZGxlc1skaWRdKSk7CgkJCWN1cmxfbXVsdGlfYWRkX2hhbmRsZSgkbXVsdGloYW5kbGUsICRzdWJoYW5kbGVzWyRpZF0pOwoJCX0KCgkJJGNvbXBsZXRlZCAgICAgICA9IDA7CgkJJHJlc3BvbnNlcyAgICAgICA9IGFycmF5KCk7CgkJJHN1YnJlcXVlc3Rjb3VudCA9IGNvdW50KCRzdWJyZXF1ZXN0cyk7CgoJCSRyZXF1ZXN0WydvcHRpb25zJ11bJ2hvb2tzJ10tPmRpc3BhdGNoKCdjdXJsLmJlZm9yZV9tdWx0aV9leGVjJywgYXJyYXkoJiRtdWx0aWhhbmRsZSkpOwoKCQlkbyB7CgkJCSRhY3RpdmUgPSAwOwoKCQkJZG8gewoJCQkJJHN0YXR1cyA9IGN1cmxfbXVsdGlfZXhlYygkbXVsdGloYW5kbGUsICRhY3RpdmUpOwoJCQl9CgkJCXdoaWxlICgkc3RhdHVzID09PSBDVVJMTV9DQUxMX01VTFRJX1BFUkZPUk0pOwoKCQkJJHRvX3Byb2Nlc3MgPSBhcnJheSgpOwoKCQkJLy8gUmVhZCB0aGUgaW5mb3JtYXRpb24gYXMgbmVlZGVkCgkJCXdoaWxlICgkZG9uZSA9IGN1cmxfbXVsdGlfaW5mb19yZWFkKCRtdWx0aWhhbmRsZSkpIHsKCQkJCSRrZXkgPSBhcnJheV9zZWFyY2goJGRvbmVbJ2hhbmRsZSddLCAkc3ViaGFuZGxlcywgdHJ1ZSk7CgkJCQlpZiAoIWlzc2V0KCR0b19wcm9jZXNzWyRrZXldKSkgewoJCQkJCSR0b19wcm9jZXNzWyRrZXldID0gJGRvbmU7CgkJCQl9CgkJCX0KCgkJCS8vIFBhcnNlIHRoZSBmaW5pc2hlZCByZXF1ZXN0cyBiZWZvcmUgd2Ugc3RhcnQgZ2V0dGluZyB0aGUgbmV3IG9uZXMKCQkJZm9yZWFjaCAoJHRvX3Byb2Nlc3MgYXMgJGtleSA9PiAkZG9uZSkgewoJCQkJJG9wdGlvbnMgPSAkcmVxdWVzdHNbJGtleV1bJ29wdGlvbnMnXTsKCQkJCWlmICgkZG9uZVsncmVzdWx0J10gIT09IENVUkxFX09LKSB7CgkJCQkJLy9nZXQgZXJyb3Igc3RyaW5nIGZvciBoYW5kbGUuCgkJCQkJJHJlYXNvbiAgICAgICAgICA9IGN1cmxfZXJyb3IoJGRvbmVbJ2hhbmRsZSddKTsKCQkJCQkkZXhjZXB0aW9uICAgICAgID0gbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbl9UcmFuc3BvcnRfY1VSTCgKCQkJCQkJJHJlYXNvbiwKCQkJCQkJUmVxdWVzdHNfRXhjZXB0aW9uX1RyYW5zcG9ydF9jVVJMOjpFQVNZLAoJCQkJCQkkZG9uZVsnaGFuZGxlJ10sCgkJCQkJCSRkb25lWydyZXN1bHQnXQoJCQkJCSk7CgkJCQkJJHJlc3BvbnNlc1ska2V5XSA9ICRleGNlcHRpb247CgkJCQkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCd0cmFuc3BvcnQuaW50ZXJuYWwucGFyc2VfZXJyb3InLCBhcnJheSgmJHJlc3BvbnNlc1ska2V5XSwgJHJlcXVlc3RzWyRrZXldKSk7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkkcmVzcG9uc2VzWyRrZXldID0gJHN1YnJlcXVlc3RzWyRrZXldLT5wcm9jZXNzX3Jlc3BvbnNlKCRzdWJyZXF1ZXN0c1ska2V5XS0+cmVzcG9uc2VfZGF0YSwgJG9wdGlvbnMpOwoKCQkJCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ3RyYW5zcG9ydC5pbnRlcm5hbC5wYXJzZV9yZXNwb25zZScsIGFycmF5KCYkcmVzcG9uc2VzWyRrZXldLCAkcmVxdWVzdHNbJGtleV0pKTsKCQkJCX0KCgkJCQljdXJsX211bHRpX3JlbW92ZV9oYW5kbGUoJG11bHRpaGFuZGxlLCAkZG9uZVsnaGFuZGxlJ10pOwoJCQkJY3VybF9jbG9zZSgkZG9uZVsnaGFuZGxlJ10pOwoKCQkJCWlmICghaXNfc3RyaW5nKCRyZXNwb25zZXNbJGtleV0pKSB7CgkJCQkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdtdWx0aXBsZS5yZXF1ZXN0LmNvbXBsZXRlJywgYXJyYXkoJiRyZXNwb25zZXNbJGtleV0sICRrZXkpKTsKCQkJCX0KCQkJCSRjb21wbGV0ZWQrKzsKCQkJfQoJCX0KCQl3aGlsZSAoJGFjdGl2ZSB8fCAkY29tcGxldGVkIDwgJHN1YnJlcXVlc3Rjb3VudCk7CgoJCSRyZXF1ZXN0WydvcHRpb25zJ11bJ2hvb2tzJ10tPmRpc3BhdGNoKCdjdXJsLmFmdGVyX211bHRpX2V4ZWMnLCBhcnJheSgmJG11bHRpaGFuZGxlKSk7CgoJCWN1cmxfbXVsdGlfY2xvc2UoJG11bHRpaGFuZGxlKTsKCgkJcmV0dXJuICRyZXNwb25zZXM7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNVUkwgaGFuZGxlIGZvciB1c2UgaW4gYSBtdWx0aS1yZXF1ZXN0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0byByZXF1ZXN0CgkgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgQXNzb2NpYXRpdmUgYXJyYXkgb2YgcmVxdWVzdCBoZWFkZXJzCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkYXRhIERhdGEgdG8gc2VuZCBlaXRoZXIgYXMgdGhlIFBPU1QgYm9keSwgb3IgYXMgcGFyYW1ldGVycyBpbiB0aGUgVVJMIGZvciBhIEdFVC9IRUFECgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgUmVxdWVzdCBvcHRpb25zLCBzZWUge0BzZWUgUmVxdWVzdHM6OnJlc3BvbnNlKCl9IGZvciBkb2N1bWVudGF0aW9uCgkgKiBAcmV0dXJuIHJlc291cmNlIFN1YnJlcXVlc3QncyBjVVJMIGhhbmRsZQoJICovCglwdWJsaWMgZnVuY3Rpb24gJmdldF9zdWJyZXF1ZXN0X2hhbmRsZSgkdXJsLCAkaGVhZGVycywgJGRhdGEsICRvcHRpb25zKSB7CgkJJHRoaXMtPnNldHVwX2hhbmRsZSgkdXJsLCAkaGVhZGVycywgJGRhdGEsICRvcHRpb25zKTsKCgkJaWYgKCRvcHRpb25zWydmaWxlbmFtZSddICE9PSBmYWxzZSkgewoJCQkkdGhpcy0+c3RyZWFtX2hhbmRsZSA9IGZvcGVuKCRvcHRpb25zWydmaWxlbmFtZSddLCAnd2InKTsKCQl9CgoJCSR0aGlzLT5yZXNwb25zZV9kYXRhICAgICAgID0gJyc7CgkJJHRoaXMtPnJlc3BvbnNlX2J5dGVzICAgICAgPSAwOwoJCSR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0ID0gZmFsc2U7CgkJaWYgKCRvcHRpb25zWydtYXhfYnl0ZXMnXSAhPT0gZmFsc2UpIHsKCQkJJHRoaXMtPnJlc3BvbnNlX2J5dGVfbGltaXQgPSAkb3B0aW9uc1snbWF4X2J5dGVzJ107CgkJfQoJCSR0aGlzLT5ob29rcyA9ICRvcHRpb25zWydob29rcyddOwoKCQlyZXR1cm4gJHRoaXMtPmhhbmRsZTsKCX0KCgkvKioKCSAqIFNldHVwIHRoZSBjVVJMIGhhbmRsZSBmb3IgdGhlIGdpdmVuIGRhdGEKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgVVJMIHRvIHJlcXVlc3QKCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBBc3NvY2lhdGl2ZSBhcnJheSBvZiByZXF1ZXN0IGhlYWRlcnMKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGRhdGEgRGF0YSB0byBzZW5kIGVpdGhlciBhcyB0aGUgUE9TVCBib2R5LCBvciBhcyBwYXJhbWV0ZXJzIGluIHRoZSBVUkwgZm9yIGEgR0VUL0hFQUQKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBSZXF1ZXN0IG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldHVwX2hhbmRsZSgkdXJsLCAkaGVhZGVycywgJGRhdGEsICRvcHRpb25zKSB7CgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdjdXJsLmJlZm9yZV9yZXF1ZXN0JywgYXJyYXkoJiR0aGlzLT5oYW5kbGUpKTsKCgkJLy8gRm9yY2UgY2xvc2luZyB0aGUgY29ubmVjdGlvbiBmb3Igb2xkIHZlcnNpb25zIG9mIGNVUkwgKDw3LjIyKS4KCQlpZiAoIWlzc2V0KCRoZWFkZXJzWydDb25uZWN0aW9uJ10pKSB7CgkJCSRoZWFkZXJzWydDb25uZWN0aW9uJ10gPSAnY2xvc2UnOwoJCX0KCgkJLyoqCgkJICogQWRkICJFeHBlY3QiIGhlYWRlci4KCQkgKgoJCSAqIEJ5IGRlZmF1bHQsIGNVUkwgYWRkcyBhICJFeHBlY3Q6IDEwMC1Db250aW51ZSIgdG8gbW9zdCByZXF1ZXN0cy4gVGhpcyBoZWFkZXIgY2FuCgkJICogYWRkIGFzIG11Y2ggYXMgYSBzZWNvbmQgdG8gdGhlIHRpbWUgaXQgdGFrZXMgZm9yIGNVUkwgdG8gcGVyZm9ybSBhIHJlcXVlc3QuIFRvCgkJICogcHJldmVudCB0aGlzLCB3ZSBuZWVkIHRvIHNldCBhbiBlbXB0eSAiRXhwZWN0IiBoZWFkZXIuIFRvIG1hdGNoIHRoZSBiZWhhdmlvdXIgb2YKCQkgKiBHdXp6bGUsIHdlJ2xsIGFkZCB0aGUgZW1wdHkgaGVhZGVyIHRvIHJlcXVlc3RzIHRoYXQgYXJlIHNtYWxsZXIgdGhhbiAxIE1CIGFuZCB1c2UKCQkgKiBIVFRQLzEuMS4KCQkgKgoJCSAqIGh0dHBzOi8vY3VybC5zZS9tYWlsL2xpYi0yMDE3LTA3LzAwMTMuaHRtbAoJCSAqLwoJCWlmICghaXNzZXQoJGhlYWRlcnNbJ0V4cGVjdCddKSAmJiAkb3B0aW9uc1sncHJvdG9jb2xfdmVyc2lvbiddID09PSAxLjEpIHsKCQkJJGhlYWRlcnNbJ0V4cGVjdCddID0gJHRoaXMtPmdldF9leHBlY3RfaGVhZGVyKCRkYXRhKTsKCQl9CgoJCSRoZWFkZXJzID0gUmVxdWVzdHM6OmZsYXR0ZW4oJGhlYWRlcnMpOwoKCQlpZiAoIWVtcHR5KCRkYXRhKSkgewoJCQkkZGF0YV9mb3JtYXQgPSAkb3B0aW9uc1snZGF0YV9mb3JtYXQnXTsKCgkJCWlmICgkZGF0YV9mb3JtYXQgPT09ICdxdWVyeScpIHsKCQkJCSR1cmwgID0gc2VsZjo6Zm9ybWF0X2dldCgkdXJsLCAkZGF0YSk7CgkJCQkkZGF0YSA9ICcnOwoJCQl9CgkJCWVsc2VpZiAoIWlzX3N0cmluZygkZGF0YSkpIHsKCQkJCSRkYXRhID0gaHR0cF9idWlsZF9xdWVyeSgkZGF0YSwgbnVsbCwgJyYnKTsKCQkJfQoJCX0KCgkJc3dpdGNoICgkb3B0aW9uc1sndHlwZSddKSB7CgkJCWNhc2UgUmVxdWVzdHM6OlBPU1Q6CgkJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1BPU1QsIHRydWUpOwoJCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9QT1NURklFTERTLCAkZGF0YSk7CgkJCQlicmVhazsKCQkJY2FzZSBSZXF1ZXN0czo6SEVBRDoKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQ1VTVE9NUkVRVUVTVCwgJG9wdGlvbnNbJ3R5cGUnXSk7CgkJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX05PQk9EWSwgdHJ1ZSk7CgkJCQlicmVhazsKCQkJY2FzZSBSZXF1ZXN0czo6VFJBQ0U6CgkJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0NVU1RPTVJFUVVFU1QsICRvcHRpb25zWyd0eXBlJ10pOwoJCQkJYnJlYWs7CgkJCWNhc2UgUmVxdWVzdHM6OlBBVENIOgoJCQljYXNlIFJlcXVlc3RzOjpQVVQ6CgkJCWNhc2UgUmVxdWVzdHM6OkRFTEVURToKCQkJY2FzZSBSZXF1ZXN0czo6T1BUSU9OUzoKCQkJZGVmYXVsdDoKCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQ1VTVE9NUkVRVUVTVCwgJG9wdGlvbnNbJ3R5cGUnXSk7CgkJCQlpZiAoIWVtcHR5KCRkYXRhKSkgewoJCQkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfUE9TVEZJRUxEUywgJGRhdGEpOwoJCQkJfQoJCX0KCgkJLy8gY1VSTCByZXF1aXJlcyBhIG1pbmltdW0gdGltZW91dCBvZiAxIHNlY29uZCB3aGVuIHVzaW5nIHRoZSBzeXN0ZW0KCQkvLyBETlMgcmVzb2x2ZXIsIGFzIGl0IHVzZXMgYGFsYXJtKClgLCB3aGljaCBpcyBzZWNvbmQgcmVzb2x1dGlvbiBvbmx5LgoJCS8vIFRoZXJlJ3Mgbm8gd2F5IHRvIGRldGVjdCB3aGljaCBETlMgcmVzb2x2ZXIgaXMgYmVpbmcgdXNlZCBmcm9tIG91cgoJCS8vIGVuZCwgc28gd2UgbmVlZCB0byByb3VuZCB1cCByZWdhcmRsZXNzIG9mIHRoZSBzdXBwbGllZCB0aW1lb3V0LgoJCS8vCgkJLy8gaHR0cHM6Ly9naXRodWIuY29tL2N1cmwvY3VybC9ibG9iLzRmNDUyNDBiYzg0YTlhYTY0OGM4ZjcyNDNiZTdiNzllOWY5MzIzYTUvbGliL2hvc3RpcC5jI0w2MDYtTDYwOQoJCSR0aW1lb3V0ID0gbWF4KCRvcHRpb25zWyd0aW1lb3V0J10sIDEpOwoKCQlpZiAoaXNfaW50KCR0aW1lb3V0KSB8fCAkdGhpcy0+dmVyc2lvbiA8IHNlbGY6OkNVUkxfN18xNl8yKSB7CgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfVElNRU9VVCwgY2VpbCgkdGltZW91dCkpOwoJCX0KCQllbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFBIUENvbXBhdGliaWxpdHkuQ29uc3RhbnRzLk5ld0NvbnN0YW50cy5jdXJsb3B0X3RpbWVvdXRfbXNGb3VuZAoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1RJTUVPVVRfTVMsIHJvdW5kKCR0aW1lb3V0ICogMTAwMCkpOwoJCX0KCgkJaWYgKGlzX2ludCgkb3B0aW9uc1snY29ubmVjdF90aW1lb3V0J10pIHx8ICR0aGlzLT52ZXJzaW9uIDwgc2VsZjo6Q1VSTF83XzE2XzIpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVCwgY2VpbCgkb3B0aW9uc1snY29ubmVjdF90aW1lb3V0J10pKTsKCQl9CgkJZWxzZSB7CgkJCS8vIHBocGNzOmlnbm9yZSBQSFBDb21wYXRpYmlsaXR5LkNvbnN0YW50cy5OZXdDb25zdGFudHMuY3VybG9wdF9jb25uZWN0dGltZW91dF9tc0ZvdW5kCgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQ09OTkVDVFRJTUVPVVRfTVMsIHJvdW5kKCRvcHRpb25zWydjb25uZWN0X3RpbWVvdXQnXSAqIDEwMDApKTsKCQl9CgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9VUkwsICR1cmwpOwoJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfUkVGRVJFUiwgJHVybCk7CgkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9VU0VSQUdFTlQsICRvcHRpb25zWyd1c2VyYWdlbnQnXSk7CgkJaWYgKCFlbXB0eSgkaGVhZGVycykpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9IVFRQSEVBREVSLCAkaGVhZGVycyk7CgkJfQoJCWlmICgkb3B0aW9uc1sncHJvdG9jb2xfdmVyc2lvbiddID09PSAxLjEpIHsKCQkJY3VybF9zZXRvcHQoJHRoaXMtPmhhbmRsZSwgQ1VSTE9QVF9IVFRQX1ZFUlNJT04sIENVUkxfSFRUUF9WRVJTSU9OXzFfMSk7CgkJfQoJCWVsc2UgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0hUVFBfVkVSU0lPTiwgQ1VSTF9IVFRQX1ZFUlNJT05fMV8wKTsKCQl9CgoJCWlmICgkb3B0aW9uc1snYmxvY2tpbmcnXSA9PT0gdHJ1ZSkgewoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX0hFQURFUkZVTkNUSU9OLCBhcnJheSgkdGhpcywgJ3N0cmVhbV9oZWFkZXJzJykpOwoJCQljdXJsX3NldG9wdCgkdGhpcy0+aGFuZGxlLCBDVVJMT1BUX1dSSVRFRlVOQ1RJT04sIGFycmF5KCR0aGlzLCAnc3RyZWFtX2JvZHknKSk7CgkJCWN1cmxfc2V0b3B0KCR0aGlzLT5oYW5kbGUsIENVUkxPUFRfQlVGRkVSU0laRSwgUmVxdWVzdHM6OkJVRkZFUl9TSVpFKTsKCQl9Cgl9CgoJLyoqCgkgKiBQcm9jZXNzIGEgcmVzcG9uc2UKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRyZXNwb25zZSBSZXNwb25zZSBkYXRhIGZyb20gdGhlIGJvZHkKCSAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBSZXF1ZXN0IG9wdGlvbnMKCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIEhUVFAgcmVzcG9uc2UgZGF0YSBpbmNsdWRpbmcgaGVhZGVycy4gRmFsc2UgaWYgbm9uLWJsb2NraW5nLgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByb2Nlc3NfcmVzcG9uc2UoJHJlc3BvbnNlLCAkb3B0aW9ucykgewoJCWlmICgkb3B0aW9uc1snYmxvY2tpbmcnXSA9PT0gZmFsc2UpIHsKCQkJJGZha2VfaGVhZGVycyA9ICcnOwoJCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2N1cmwuYWZ0ZXJfcmVxdWVzdCcsIGFycmF5KCYkZmFrZV9oZWFkZXJzKSk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJaWYgKCRvcHRpb25zWydmaWxlbmFtZSddICE9PSBmYWxzZSAmJiAkdGhpcy0+c3RyZWFtX2hhbmRsZSkgewoJCQlmY2xvc2UoJHRoaXMtPnN0cmVhbV9oYW5kbGUpOwoJCQkkdGhpcy0+aGVhZGVycyA9IHRyaW0oJHRoaXMtPmhlYWRlcnMpOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPmhlYWRlcnMgLj0gJHJlc3BvbnNlOwoJCX0KCgkJaWYgKGN1cmxfZXJybm8oJHRoaXMtPmhhbmRsZSkpIHsKCQkJJGVycm9yID0gc3ByaW50ZigKCQkJCSdjVVJMIGVycm9yICVzOiAlcycsCgkJCQljdXJsX2Vycm5vKCR0aGlzLT5oYW5kbGUpLAoJCQkJY3VybF9lcnJvcigkdGhpcy0+aGFuZGxlKQoJCQkpOwoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCRlcnJvciwgJ2N1cmxlcnJvcicsICR0aGlzLT5oYW5kbGUpOwoJCX0KCQkkdGhpcy0+aW5mbyA9IGN1cmxfZ2V0aW5mbygkdGhpcy0+aGFuZGxlKTsKCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdjdXJsLmFmdGVyX3JlcXVlc3QnLCBhcnJheSgmJHRoaXMtPmhlYWRlcnMsICYkdGhpcy0+aW5mbykpOwoJCXJldHVybiAkdGhpcy0+aGVhZGVyczsKCX0KCgkvKioKCSAqIENvbGxlY3QgdGhlIGhlYWRlcnMgYXMgdGhleSBhcmUgcmVjZWl2ZWQKCSAqCgkgKiBAcGFyYW0gcmVzb3VyY2UgJGhhbmRsZSBjVVJMIHJlc291cmNlCgkgKiBAcGFyYW0gc3RyaW5nICRoZWFkZXJzIEhlYWRlciBzdHJpbmcKCSAqIEByZXR1cm4gaW50ZWdlciBMZW5ndGggb2YgcHJvdmlkZWQgaGVhZGVyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdHJlYW1faGVhZGVycygkaGFuZGxlLCAkaGVhZGVycykgewoJCS8vIFdoeSBkbyB3ZSBkbyB0aGlzPyBjVVJMIHdpbGwgc2VuZCBib3RoIHRoZSBmaW5hbCByZXNwb25zZSBhbmQgYW55CgkJLy8gaW50ZXJpbSByZXNwb25zZXMsIHN1Y2ggYXMgYSAxMDAgQ29udGludWUuIFdlIGRvbid0IG5lZWQgdGhhdC4KCQkvLyAoV2UgbWF5IHdhbnQgdG8ga2VlcCB0aGlzIHNvbWV3aGVyZSBqdXN0IGluIGNhc2UpCgkJaWYgKCR0aGlzLT5kb25lX2hlYWRlcnMpIHsKCQkJJHRoaXMtPmhlYWRlcnMgICAgICA9ICcnOwoJCQkkdGhpcy0+ZG9uZV9oZWFkZXJzID0gZmFsc2U7CgkJfQoJCSR0aGlzLT5oZWFkZXJzIC49ICRoZWFkZXJzOwoKCQlpZiAoJGhlYWRlcnMgPT09ICJcclxuIikgewoJCQkkdGhpcy0+ZG9uZV9oZWFkZXJzID0gdHJ1ZTsKCQl9CgkJcmV0dXJuIHN0cmxlbigkaGVhZGVycyk7Cgl9CgoJLyoqCgkgKiBDb2xsZWN0IGRhdGEgYXMgaXQncyByZWNlaXZlZAoJICoKCSAqIEBzaW5jZSAxLjYuMQoJICoKCSAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlIGNVUkwgcmVzb3VyY2UKCSAqIEBwYXJhbSBzdHJpbmcgJGRhdGEgQm9keSBkYXRhCgkgKiBAcmV0dXJuIGludGVnZXIgTGVuZ3RoIG9mIHByb3ZpZGVkIGRhdGEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN0cmVhbV9ib2R5KCRoYW5kbGUsICRkYXRhKSB7CgkJJHRoaXMtPmhvb2tzLT5kaXNwYXRjaCgncmVxdWVzdC5wcm9ncmVzcycsIGFycmF5KCRkYXRhLCAkdGhpcy0+cmVzcG9uc2VfYnl0ZXMsICR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0KSk7CgkJJGRhdGFfbGVuZ3RoID0gc3RybGVuKCRkYXRhKTsKCgkJLy8gQXJlIHdlIGxpbWl0aW5nIHRoZSByZXNwb25zZSBzaXplPwoJCWlmICgkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCkgewoJCQlpZiAoJHRoaXMtPnJlc3BvbnNlX2J5dGVzID09PSAkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCkgewoJCQkJLy8gQWxyZWFkeSBhdCBtYXhpbXVtLCBtb3ZlIG9uCgkJCQlyZXR1cm4gJGRhdGFfbGVuZ3RoOwoJCQl9CgoJCQlpZiAoKCR0aGlzLT5yZXNwb25zZV9ieXRlcyArICRkYXRhX2xlbmd0aCkgPiAkdGhpcy0+cmVzcG9uc2VfYnl0ZV9saW1pdCkgewoJCQkJLy8gTGltaXQgdGhlIGxlbmd0aAoJCQkJJGxpbWl0ZWRfbGVuZ3RoID0gKCR0aGlzLT5yZXNwb25zZV9ieXRlX2xpbWl0IC0gJHRoaXMtPnJlc3BvbnNlX2J5dGVzKTsKCQkJCSRkYXRhICAgICAgICAgICA9IHN1YnN0cigkZGF0YSwgMCwgJGxpbWl0ZWRfbGVuZ3RoKTsKCQkJfQoJCX0KCgkJaWYgKCR0aGlzLT5zdHJlYW1faGFuZGxlKSB7CgkJCWZ3cml0ZSgkdGhpcy0+c3RyZWFtX2hhbmRsZSwgJGRhdGEpOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPnJlc3BvbnNlX2RhdGEgLj0gJGRhdGE7CgkJfQoKCQkkdGhpcy0+cmVzcG9uc2VfYnl0ZXMgKz0gc3RybGVuKCRkYXRhKTsKCQlyZXR1cm4gJGRhdGFfbGVuZ3RoOwoJfQoKCS8qKgoJICogRm9ybWF0IGEgVVJMIGdpdmVuIEdFVCBkYXRhCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcGFyYW0gYXJyYXl8b2JqZWN0ICRkYXRhIERhdGEgdG8gYnVpbGQgcXVlcnkgdXNpbmcsIHNlZSB7QHNlZSBodHRwczovL3NlY3VyZS5waHAubmV0L2h0dHBfYnVpbGRfcXVlcnl9CgkgKiBAcmV0dXJuIHN0cmluZyBVUkwgd2l0aCBkYXRhCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0X2dldCgkdXJsLCAkZGF0YSkgewoJCWlmICghZW1wdHkoJGRhdGEpKSB7CgkJCSRxdWVyeSAgICAgPSAnJzsKCQkJJHVybF9wYXJ0cyA9IHBhcnNlX3VybCgkdXJsKTsKCQkJaWYgKGVtcHR5KCR1cmxfcGFydHNbJ3F1ZXJ5J10pKSB7CgkJCQkkdXJsX3BhcnRzWydxdWVyeSddID0gJyc7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcXVlcnkgPSAkdXJsX3BhcnRzWydxdWVyeSddOwoJCQl9CgoJCQkkcXVlcnkgLj0gJyYnIC4gaHR0cF9idWlsZF9xdWVyeSgkZGF0YSwgbnVsbCwgJyYnKTsKCQkJJHF1ZXJ5ICA9IHRyaW0oJHF1ZXJ5LCAnJicpOwoKCQkJaWYgKGVtcHR5KCR1cmxfcGFydHNbJ3F1ZXJ5J10pKSB7CgkJCQkkdXJsIC49ICc/JyAuICRxdWVyeTsKCQkJfQoJCQllbHNlIHsKCQkJCSR1cmwgPSBzdHJfcmVwbGFjZSgkdXJsX3BhcnRzWydxdWVyeSddLCAkcXVlcnksICR1cmwpOwoJCQl9CgkJfQoJCXJldHVybiAkdXJsOwoJfQoKCS8qKgoJICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBpcyB2YWxpZAoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0cmFuc3BvcnQgaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0ZXN0KCRjYXBhYmlsaXRpZXMgPSBhcnJheSgpKSB7CgkJaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N1cmxfaW5pdCcpIHx8ICFmdW5jdGlvbl9leGlzdHMoJ2N1cmxfZXhlYycpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIElmIG5lZWRlZCwgY2hlY2sgdGhhdCBvdXIgaW5zdGFsbGVkIGN1cmwgdmVyc2lvbiBzdXBwb3J0cyBTU0wKCQlpZiAoaXNzZXQoJGNhcGFiaWxpdGllc1snc3NsJ10pICYmICRjYXBhYmlsaXRpZXNbJ3NzbCddKSB7CgkJCSRjdXJsX3ZlcnNpb24gPSBjdXJsX3ZlcnNpb24oKTsKCQkJaWYgKCEoQ1VSTF9WRVJTSU9OX1NTTCAmICRjdXJsX3ZlcnNpb25bJ2ZlYXR1cmVzJ10pKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogR2V0IHRoZSBjb3JyZWN0ICJFeHBlY3QiIGhlYWRlciBmb3IgdGhlIGdpdmVuIHJlcXVlc3QgZGF0YS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkYXRhIERhdGEgdG8gc2VuZCBlaXRoZXIgYXMgdGhlIFBPU1QgYm9keSwgb3IgYXMgcGFyYW1ldGVycyBpbiB0aGUgVVJMIGZvciBhIEdFVC9IRUFELgoJICogQHJldHVybiBzdHJpbmcgVGhlICJFeHBlY3QiIGhlYWRlci4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9leHBlY3RfaGVhZGVyKCRkYXRhKSB7CgkJaWYgKCFpc19hcnJheSgkZGF0YSkpIHsKCQkJcmV0dXJuIHN0cmxlbigoc3RyaW5nKSAkZGF0YSkgPj0gMTA0ODU3NiA/ICcxMDAtQ29udGludWUnIDogJyc7CgkJfQoKCQkkYnl0ZXNpemUgPSAwOwoJCSRpdGVyYXRvciA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKG5ldyBSZWN1cnNpdmVBcnJheUl0ZXJhdG9yKCRkYXRhKSk7CgoJCWZvcmVhY2ggKCRpdGVyYXRvciBhcyAkZGF0dW0pIHsKCQkJJGJ5dGVzaXplICs9IHN0cmxlbigoc3RyaW5nKSAkZGF0dW0pOwoKCQkJaWYgKCRieXRlc2l6ZSA+PSAxMDQ4NTc2KSB7CgkJCQlyZXR1cm4gJzEwMC1Db250aW51ZSc7CgkJCX0KCQl9CgoJCXJldHVybiAnJzsKCX0KfQo8P3BocAovKioKICogZnNvY2tvcGVuIEhUVFAgdHJhbnNwb3J0CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFRyYW5zcG9ydAogKi8KCi8qKgogKiBmc29ja29wZW4gSFRUUCB0cmFuc3BvcnQKICoKICogQHBhY2thZ2UgUmVxdWVzdHMKICogQHN1YnBhY2thZ2UgVHJhbnNwb3J0CiAqLwpjbGFzcyBSZXF1ZXN0c19UcmFuc3BvcnRfZnNvY2tvcGVuIGltcGxlbWVudHMgUmVxdWVzdHNfVHJhbnNwb3J0IHsKCS8qKgoJICogU2Vjb25kIHRvIG1pY3Jvc2Vjb25kIGNvbnZlcnNpb24KCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJY29uc3QgU0VDT05EX0lOX01JQ1JPU0VDT05EUyA9IDEwMDAwMDA7CgoJLyoqCgkgKiBSYXcgSFRUUCBkYXRhCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRoZWFkZXJzID0gJyc7CgoJLyoqCgkgKiBTdHJlYW0gbWV0YWRhdGEKCSAqCgkgKiBAdmFyIGFycmF5IEFzc29jaWF0aXZlIGFycmF5IG9mIHByb3BlcnRpZXMsIHNlZSB7QHNlZSBodHRwczovL3NlY3VyZS5waHAubmV0L3N0cmVhbV9nZXRfbWV0YV9kYXRhfQoJICovCglwdWJsaWMgJGluZm87CgoJLyoqCgkgKiBXaGF0J3MgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHdlIHNob3VsZCBrZWVwPwoJICoKCSAqIEB2YXIgaW50fGJvb2wgQnl0ZSBjb3VudCwgb3IgZmFsc2UgaWYgbm8gbGltaXQuCgkgKi8KCXByb3RlY3RlZCAkbWF4X2J5dGVzID0gZmFsc2U7CgoJcHJvdGVjdGVkICRjb25uZWN0X2Vycm9yID0gJyc7CgoJLyoqCgkgKiBQZXJmb3JtIGEgcmVxdWVzdAoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGZhaWx1cmUgdG8gY29ubmVjdCB0byBzb2NrZXQgKGBmc29ja29wZW5lcnJvcmApCgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBzb2NrZXQgdGltZW91dCAoYHRpbWVvdXRgKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgdG8gcmVxdWVzdAoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIEFzc29jaWF0aXZlIGFycmF5IG9mIHJlcXVlc3QgaGVhZGVycwoJICogQHBhcmFtIHN0cmluZ3xhcnJheSAkZGF0YSBEYXRhIHRvIHNlbmQgZWl0aGVyIGFzIHRoZSBQT1NUIGJvZHksIG9yIGFzIHBhcmFtZXRlcnMgaW4gdGhlIFVSTCBmb3IgYSBHRVQvSEVBRAoJICogQHBhcmFtIGFycmF5ICRvcHRpb25zIFJlcXVlc3Qgb3B0aW9ucywgc2VlIHtAc2VlIFJlcXVlc3RzOjpyZXNwb25zZSgpfSBmb3IgZG9jdW1lbnRhdGlvbgoJICogQHJldHVybiBzdHJpbmcgUmF3IEhUVFAgcmVzdWx0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXF1ZXN0KCR1cmwsICRoZWFkZXJzID0gYXJyYXkoKSwgJGRhdGEgPSBhcnJheSgpLCAkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5iZWZvcmVfcmVxdWVzdCcpOwoKCQkkdXJsX3BhcnRzID0gcGFyc2VfdXJsKCR1cmwpOwoJCWlmIChlbXB0eSgkdXJsX3BhcnRzKSkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdJbnZhbGlkIFVSTC4nLCAnaW52YWxpZHVybCcsICR1cmwpOwoJCX0KCQkkaG9zdCAgICAgICAgICAgICAgICAgICAgID0gJHVybF9wYXJ0c1snaG9zdCddOwoJCSRjb250ZXh0ICAgICAgICAgICAgICAgICAgPSBzdHJlYW1fY29udGV4dF9jcmVhdGUoKTsKCQkkdmVyaWZ5bmFtZSAgICAgICAgICAgICAgID0gZmFsc2U7CgkJJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVycyA9IG5ldyBSZXF1ZXN0c19VdGlsaXR5X0Nhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkoJGhlYWRlcnMpOwoKCQkvLyBIVFRQUyBzdXBwb3J0CgkJaWYgKGlzc2V0KCR1cmxfcGFydHNbJ3NjaGVtZSddKSAmJiBzdHJ0b2xvd2VyKCR1cmxfcGFydHNbJ3NjaGVtZSddKSA9PT0gJ2h0dHBzJykgewoJCQkkcmVtb3RlX3NvY2tldCA9ICdzc2w6Ly8nIC4gJGhvc3Q7CgkJCWlmICghaXNzZXQoJHVybF9wYXJ0c1sncG9ydCddKSkgewoJCQkJJHVybF9wYXJ0c1sncG9ydCddID0gNDQzOwoJCQl9CgoJCQkkY29udGV4dF9vcHRpb25zID0gYXJyYXkoCgkJCQkndmVyaWZ5X3BlZXInICAgICAgID0+IHRydWUsCgkJCQknY2FwdHVyZV9wZWVyX2NlcnQnID0+IHRydWUsCgkJCSk7CgkJCSR2ZXJpZnluYW1lICAgICAgPSB0cnVlOwoKCQkJLy8gU05JLCBpZiBlbmFibGVkIChPcGVuU1NMID49MC45LjhqKQoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5Db25zdGFudHMuTmV3Q29uc3RhbnRzLm9wZW5zc2xfdGxzZXh0X3NlcnZlcl9uYW1lRm91bmQKCQkJaWYgKGRlZmluZWQoJ09QRU5TU0xfVExTRVhUX1NFUlZFUl9OQU1FJykgJiYgT1BFTlNTTF9UTFNFWFRfU0VSVkVSX05BTUUpIHsKCQkJCSRjb250ZXh0X29wdGlvbnNbJ1NOSV9lbmFibGVkJ10gPSB0cnVlOwoJCQkJaWYgKGlzc2V0KCRvcHRpb25zWyd2ZXJpZnluYW1lJ10pICYmICRvcHRpb25zWyd2ZXJpZnluYW1lJ10gPT09IGZhbHNlKSB7CgkJCQkJJGNvbnRleHRfb3B0aW9uc1snU05JX2VuYWJsZWQnXSA9IGZhbHNlOwoJCQkJfQoJCQl9CgoJCQlpZiAoaXNzZXQoJG9wdGlvbnNbJ3ZlcmlmeSddKSkgewoJCQkJaWYgKCRvcHRpb25zWyd2ZXJpZnknXSA9PT0gZmFsc2UpIHsKCQkJCQkkY29udGV4dF9vcHRpb25zWyd2ZXJpZnlfcGVlciddICAgICAgPSBmYWxzZTsKCQkJCQkkY29udGV4dF9vcHRpb25zWyd2ZXJpZnlfcGVlcl9uYW1lJ10gPSBmYWxzZTsKCQkJCQkkdmVyaWZ5bmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgPSBmYWxzZTsKCQkJCX0KCQkJCWVsc2VpZiAoaXNfc3RyaW5nKCRvcHRpb25zWyd2ZXJpZnknXSkpIHsKCQkJCQkkY29udGV4dF9vcHRpb25zWydjYWZpbGUnXSA9ICRvcHRpb25zWyd2ZXJpZnknXTsKCQkJCX0KCQkJfQoKCQkJaWYgKGlzc2V0KCRvcHRpb25zWyd2ZXJpZnluYW1lJ10pICYmICRvcHRpb25zWyd2ZXJpZnluYW1lJ10gPT09IGZhbHNlKSB7CgkJCQkkY29udGV4dF9vcHRpb25zWyd2ZXJpZnlfcGVlcl9uYW1lJ10gPSBmYWxzZTsKCQkJCSR2ZXJpZnluYW1lICAgICAgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlOwoJCQl9CgoJCQlzdHJlYW1fY29udGV4dF9zZXRfb3B0aW9uKCRjb250ZXh0LCBhcnJheSgnc3NsJyA9PiAkY29udGV4dF9vcHRpb25zKSk7CgkJfQoJCWVsc2UgewoJCQkkcmVtb3RlX3NvY2tldCA9ICd0Y3A6Ly8nIC4gJGhvc3Q7CgkJfQoKCQkkdGhpcy0+bWF4X2J5dGVzID0gJG9wdGlvbnNbJ21heF9ieXRlcyddOwoKCQlpZiAoIWlzc2V0KCR1cmxfcGFydHNbJ3BvcnQnXSkpIHsKCQkJJHVybF9wYXJ0c1sncG9ydCddID0gODA7CgkJfQoJCSRyZW1vdGVfc29ja2V0IC49ICc6JyAuICR1cmxfcGFydHNbJ3BvcnQnXTsKCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuRGV2ZWxvcG1lbnRGdW5jdGlvbnMuZXJyb3JfbG9nX3NldF9lcnJvcl9oYW5kbGVyCgkJc2V0X2Vycm9yX2hhbmRsZXIoYXJyYXkoJHRoaXMsICdjb25uZWN0X2Vycm9yX2hhbmRsZXInKSwgRV9XQVJOSU5HIHwgRV9OT1RJQ0UpOwoKCQkkb3B0aW9uc1snaG9va3MnXS0+ZGlzcGF0Y2goJ2Zzb2Nrb3Blbi5yZW1vdGVfc29ja2V0JywgYXJyYXkoJiRyZW1vdGVfc29ja2V0KSk7CgoJCSRzb2NrZXQgPSBzdHJlYW1fc29ja2V0X2NsaWVudCgkcmVtb3RlX3NvY2tldCwgJGVycm5vLCAkZXJyc3RyLCBjZWlsKCRvcHRpb25zWydjb25uZWN0X3RpbWVvdXQnXSksIFNUUkVBTV9DTElFTlRfQ09OTkVDVCwgJGNvbnRleHQpOwoKCQlyZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCgkJaWYgKCR2ZXJpZnluYW1lICYmICEkdGhpcy0+dmVyaWZ5X2NlcnRpZmljYXRlX2Zyb21fY29udGV4dCgkaG9zdCwgJGNvbnRleHQpKSB7CgkJCXRocm93IG5ldyBSZXF1ZXN0c19FeGNlcHRpb24oJ1NTTCBjZXJ0aWZpY2F0ZSBkaWQgbm90IG1hdGNoIHRoZSByZXF1ZXN0ZWQgZG9tYWluIG5hbWUnLCAnc3NsLm5vX21hdGNoJyk7CgkJfQoKCQlpZiAoISRzb2NrZXQpIHsKCQkJaWYgKCRlcnJubyA9PT0gMCkgewoJCQkJLy8gQ29ubmVjdGlvbiBpc3N1ZQoJCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbihydHJpbSgkdGhpcy0+Y29ubmVjdF9lcnJvciksICdmc29ja29wZW4uY29ubmVjdF9lcnJvcicpOwoJCQl9CgoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCRlcnJzdHIsICdmc29ja29wZW5lcnJvcicsIG51bGwsICRlcnJubyk7CgkJfQoKCQkkZGF0YV9mb3JtYXQgPSAkb3B0aW9uc1snZGF0YV9mb3JtYXQnXTsKCgkJaWYgKCRkYXRhX2Zvcm1hdCA9PT0gJ3F1ZXJ5JykgewoJCQkkcGF0aCA9IHNlbGY6OmZvcm1hdF9nZXQoJHVybF9wYXJ0cywgJGRhdGEpOwoJCQkkZGF0YSA9ICcnOwoJCX0KCQllbHNlIHsKCQkJJHBhdGggPSBzZWxmOjpmb3JtYXRfZ2V0KCR1cmxfcGFydHMsIGFycmF5KCkpOwoJCX0KCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4ucmVtb3RlX2hvc3RfcGF0aCcsIGFycmF5KCYkcGF0aCwgJHVybCkpOwoKCQkkcmVxdWVzdF9ib2R5ID0gJyc7CgkJJG91dCAgICAgICAgICA9IHNwcmludGYoIiVzICVzIEhUVFAvJS4xRlxyXG4iLCAkb3B0aW9uc1sndHlwZSddLCAkcGF0aCwgJG9wdGlvbnNbJ3Byb3RvY29sX3ZlcnNpb24nXSk7CgoJCWlmICgkb3B0aW9uc1sndHlwZSddICE9PSBSZXF1ZXN0czo6VFJBQ0UpIHsKCQkJaWYgKGlzX2FycmF5KCRkYXRhKSkgewoJCQkJJHJlcXVlc3RfYm9keSA9IGh0dHBfYnVpbGRfcXVlcnkoJGRhdGEsICcnLCAnJicpOwoJCQl9CgkJCWVsc2UgewoJCQkJJHJlcXVlc3RfYm9keSA9ICRkYXRhOwoJCQl9CgoJCQkvLyBBbHdheXMgaW5jbHVkZSBDb250ZW50LWxlbmd0aCBvbiBQT1NUIHJlcXVlc3RzIHRvIHByZXZlbnQKCQkJLy8gNDExIGVycm9ycyBmcm9tIHNvbWUgc2VydmVycyB3aGVuIHRoZSBib2R5IGlzIGVtcHR5LgoJCQlpZiAoIWVtcHR5KCRkYXRhKSB8fCAkb3B0aW9uc1sndHlwZSddID09PSBSZXF1ZXN0czo6UE9TVCkgewoJCQkJaWYgKCFpc3NldCgkY2FzZV9pbnNlbnNpdGl2ZV9oZWFkZXJzWydDb250ZW50LUxlbmd0aCddKSkgewoJCQkJCSRoZWFkZXJzWydDb250ZW50LUxlbmd0aCddID0gc3RybGVuKCRyZXF1ZXN0X2JvZHkpOwoJCQkJfQoKCQkJCWlmICghaXNzZXQoJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVyc1snQ29udGVudC1UeXBlJ10pKSB7CgkJCQkJJGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOCc7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICghaXNzZXQoJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVyc1snSG9zdCddKSkgewoJCQkkb3V0IC49IHNwcmludGYoJ0hvc3Q6ICVzJywgJHVybF9wYXJ0c1snaG9zdCddKTsKCgkJCWlmICgoc3RydG9sb3dlcigkdXJsX3BhcnRzWydzY2hlbWUnXSkgPT09ICdodHRwJyAmJiAkdXJsX3BhcnRzWydwb3J0J10gIT09IDgwKSB8fCAoc3RydG9sb3dlcigkdXJsX3BhcnRzWydzY2hlbWUnXSkgPT09ICdodHRwcycgJiYgJHVybF9wYXJ0c1sncG9ydCddICE9PSA0NDMpKSB7CgkJCQkkb3V0IC49ICc6JyAuICR1cmxfcGFydHNbJ3BvcnQnXTsKCQkJfQoJCQkkb3V0IC49ICJcclxuIjsKCQl9CgoJCWlmICghaXNzZXQoJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVyc1snVXNlci1BZ2VudCddKSkgewoJCQkkb3V0IC49IHNwcmludGYoIlVzZXItQWdlbnQ6ICVzXHJcbiIsICRvcHRpb25zWyd1c2VyYWdlbnQnXSk7CgkJfQoKCQkkYWNjZXB0X2VuY29kaW5nID0gJHRoaXMtPmFjY2VwdF9lbmNvZGluZygpOwoJCWlmICghaXNzZXQoJGNhc2VfaW5zZW5zaXRpdmVfaGVhZGVyc1snQWNjZXB0LUVuY29kaW5nJ10pICYmICFlbXB0eSgkYWNjZXB0X2VuY29kaW5nKSkgewoJCQkkb3V0IC49IHNwcmludGYoIkFjY2VwdC1FbmNvZGluZzogJXNcclxuIiwgJGFjY2VwdF9lbmNvZGluZyk7CgkJfQoKCQkkaGVhZGVycyA9IFJlcXVlc3RzOjpmbGF0dGVuKCRoZWFkZXJzKTsKCgkJaWYgKCFlbXB0eSgkaGVhZGVycykpIHsKCQkJJG91dCAuPSBpbXBsb2RlKCJcclxuIiwgJGhlYWRlcnMpIC4gIlxyXG4iOwoJCX0KCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4uYWZ0ZXJfaGVhZGVycycsIGFycmF5KCYkb3V0KSk7CgoJCWlmIChzdWJzdHIoJG91dCwgLTIpICE9PSAiXHJcbiIpIHsKCQkJJG91dCAuPSAiXHJcbiI7CgkJfQoKCQlpZiAoIWlzc2V0KCRjYXNlX2luc2Vuc2l0aXZlX2hlYWRlcnNbJ0Nvbm5lY3Rpb24nXSkpIHsKCQkJJG91dCAuPSAiQ29ubmVjdGlvbjogQ2xvc2VcclxuIjsKCQl9CgoJCSRvdXQgLj0gIlxyXG4iIC4gJHJlcXVlc3RfYm9keTsKCgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4uYmVmb3JlX3NlbmQnLCBhcnJheSgmJG91dCkpOwoKCQlmd3JpdGUoJHNvY2tldCwgJG91dCk7CgkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4uYWZ0ZXJfc2VuZCcsIGFycmF5KCRvdXQpKTsKCgkJaWYgKCEkb3B0aW9uc1snYmxvY2tpbmcnXSkgewoJCQlmY2xvc2UoJHNvY2tldCk7CgkJCSRmYWtlX2hlYWRlcnMgPSAnJzsKCQkJJG9wdGlvbnNbJ2hvb2tzJ10tPmRpc3BhdGNoKCdmc29ja29wZW4uYWZ0ZXJfcmVxdWVzdCcsIGFycmF5KCYkZmFrZV9oZWFkZXJzKSk7CgkJCXJldHVybiAnJzsKCQl9CgoJCSR0aW1lb3V0X3NlYyA9IChpbnQpIGZsb29yKCRvcHRpb25zWyd0aW1lb3V0J10pOwoJCWlmICgkdGltZW91dF9zZWMgPT09ICRvcHRpb25zWyd0aW1lb3V0J10pIHsKCQkJJHRpbWVvdXRfbXNlYyA9IDA7CgkJfQoJCWVsc2UgewoJCQkkdGltZW91dF9tc2VjID0gc2VsZjo6U0VDT05EX0lOX01JQ1JPU0VDT05EUyAqICRvcHRpb25zWyd0aW1lb3V0J10gJSBzZWxmOjpTRUNPTkRfSU5fTUlDUk9TRUNPTkRTOwoJCX0KCQlzdHJlYW1fc2V0X3RpbWVvdXQoJHNvY2tldCwgJHRpbWVvdXRfc2VjLCAkdGltZW91dF9tc2VjKTsKCgkJJHJlc3BvbnNlICAgPSAnJzsKCQkkYm9keSAgICAgICA9ICcnOwoJCSRoZWFkZXJzICAgID0gJyc7CgkJJHRoaXMtPmluZm8gPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkc29ja2V0KTsKCQkkc2l6ZSAgICAgICA9IDA7CgkJJGRvaW5nYm9keSAgPSBmYWxzZTsKCQkkZG93bmxvYWQgICA9IGZhbHNlOwoJCWlmICgkb3B0aW9uc1snZmlsZW5hbWUnXSkgewoJCQkkZG93bmxvYWQgPSBmb3Blbigkb3B0aW9uc1snZmlsZW5hbWUnXSwgJ3diJyk7CgkJfQoKCQl3aGlsZSAoIWZlb2YoJHNvY2tldCkpIHsKCQkJJHRoaXMtPmluZm8gPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkc29ja2V0KTsKCQkJaWYgKCR0aGlzLT5pbmZvWyd0aW1lZF9vdXQnXSkgewoJCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignZnNvY2tldCB0aW1lZCBvdXQnLCAndGltZW91dCcpOwoJCQl9CgoJCQkkYmxvY2sgPSBmcmVhZCgkc29ja2V0LCBSZXF1ZXN0czo6QlVGRkVSX1NJWkUpOwoJCQlpZiAoISRkb2luZ2JvZHkpIHsKCQkJCSRyZXNwb25zZSAuPSAkYmxvY2s7CgkJCQlpZiAoc3RycG9zKCRyZXNwb25zZSwgIlxyXG5cclxuIikpIHsKCQkJCQlsaXN0KCRoZWFkZXJzLCAkYmxvY2spID0gZXhwbG9kZSgiXHJcblxyXG4iLCAkcmVzcG9uc2UsIDIpOwoJCQkJCSRkb2luZ2JvZHkgICAgICAgICAgICAgPSB0cnVlOwoJCQkJfQoJCQl9CgoJCQkvLyBBcmUgd2UgaW4gYm9keSBtb2RlIG5vdz8KCQkJaWYgKCRkb2luZ2JvZHkpIHsKCQkJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgncmVxdWVzdC5wcm9ncmVzcycsIGFycmF5KCRibG9jaywgJHNpemUsICR0aGlzLT5tYXhfYnl0ZXMpKTsKCQkJCSRkYXRhX2xlbmd0aCA9IHN0cmxlbigkYmxvY2spOwoJCQkJaWYgKCR0aGlzLT5tYXhfYnl0ZXMpIHsKCQkJCQkvLyBIYXZlIHdlIGFscmVhZHkgaGl0IGEgbGltaXQ/CgkJCQkJaWYgKCRzaXplID09PSAkdGhpcy0+bWF4X2J5dGVzKSB7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCQkJCQlpZiAoKCRzaXplICsgJGRhdGFfbGVuZ3RoKSA+ICR0aGlzLT5tYXhfYnl0ZXMpIHsKCQkJCQkJLy8gTGltaXQgdGhlIGxlbmd0aAoJCQkJCQkkbGltaXRlZF9sZW5ndGggPSAoJHRoaXMtPm1heF9ieXRlcyAtICRzaXplKTsKCQkJCQkJJGJsb2NrICAgICAgICAgID0gc3Vic3RyKCRibG9jaywgMCwgJGxpbWl0ZWRfbGVuZ3RoKTsKCQkJCQl9CgkJCQl9CgoJCQkJJHNpemUgKz0gc3RybGVuKCRibG9jayk7CgkJCQlpZiAoJGRvd25sb2FkKSB7CgkJCQkJZndyaXRlKCRkb3dubG9hZCwgJGJsb2NrKTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCSRib2R5IC49ICRibG9jazsKCQkJCX0KCQkJfQoJCX0KCQkkdGhpcy0+aGVhZGVycyA9ICRoZWFkZXJzOwoKCQlpZiAoJGRvd25sb2FkKSB7CgkJCWZjbG9zZSgkZG93bmxvYWQpOwoJCX0KCQllbHNlIHsKCQkJJHRoaXMtPmhlYWRlcnMgLj0gIlxyXG5cclxuIiAuICRib2R5OwoJCX0KCQlmY2xvc2UoJHNvY2tldCk7CgoJCSRvcHRpb25zWydob29rcyddLT5kaXNwYXRjaCgnZnNvY2tvcGVuLmFmdGVyX3JlcXVlc3QnLCBhcnJheSgmJHRoaXMtPmhlYWRlcnMsICYkdGhpcy0+aW5mbykpOwoJCXJldHVybiAkdGhpcy0+aGVhZGVyczsKCX0KCgkvKioKCSAqIFNlbmQgbXVsdGlwbGUgcmVxdWVzdHMgc2ltdWx0YW5lb3VzbHkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlcXVlc3RzIFJlcXVlc3QgZGF0YSAoYXJyYXkgb2YgJ3VybCcsICdoZWFkZXJzJywgJ2RhdGEnLCAnb3B0aW9ucycpIGFzIHBlciB7QHNlZSBSZXF1ZXN0c19UcmFuc3BvcnQ6OnJlcXVlc3R9CgkgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgR2xvYmFsIG9wdGlvbnMsIHNlZSB7QHNlZSBSZXF1ZXN0czo6cmVzcG9uc2UoKX0gZm9yIGRvY3VtZW50YXRpb24KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgb2YgUmVxdWVzdHNfUmVzcG9uc2Ugb2JqZWN0cyAobWF5IGNvbnRhaW4gUmVxdWVzdHNfRXhjZXB0aW9uIG9yIHN0cmluZyByZXNwb25zZXMgYXMgd2VsbCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlcXVlc3RfbXVsdGlwbGUoJHJlcXVlc3RzLCAkb3B0aW9ucykgewoJCSRyZXNwb25zZXMgPSBhcnJheSgpOwoJCSRjbGFzcyAgICAgPSBnZXRfY2xhc3MoJHRoaXMpOwoJCWZvcmVhY2ggKCRyZXF1ZXN0cyBhcyAkaWQgPT4gJHJlcXVlc3QpIHsKCQkJdHJ5IHsKCQkJCSRoYW5kbGVyICAgICAgICA9IG5ldyAkY2xhc3MoKTsKCQkJCSRyZXNwb25zZXNbJGlkXSA9ICRoYW5kbGVyLT5yZXF1ZXN0KCRyZXF1ZXN0Wyd1cmwnXSwgJHJlcXVlc3RbJ2hlYWRlcnMnXSwgJHJlcXVlc3RbJ2RhdGEnXSwgJHJlcXVlc3RbJ29wdGlvbnMnXSk7CgoJCQkJJHJlcXVlc3RbJ29wdGlvbnMnXVsnaG9va3MnXS0+ZGlzcGF0Y2goJ3RyYW5zcG9ydC5pbnRlcm5hbC5wYXJzZV9yZXNwb25zZScsIGFycmF5KCYkcmVzcG9uc2VzWyRpZF0sICRyZXF1ZXN0KSk7CgkJCX0KCQkJY2F0Y2ggKFJlcXVlc3RzX0V4Y2VwdGlvbiAkZSkgewoJCQkJJHJlc3BvbnNlc1skaWRdID0gJGU7CgkJCX0KCgkJCWlmICghaXNfc3RyaW5nKCRyZXNwb25zZXNbJGlkXSkpIHsKCQkJCSRyZXF1ZXN0WydvcHRpb25zJ11bJ2hvb2tzJ10tPmRpc3BhdGNoKCdtdWx0aXBsZS5yZXF1ZXN0LmNvbXBsZXRlJywgYXJyYXkoJiRyZXNwb25zZXNbJGlkXSwgJGlkKSk7CgkJCX0KCQl9CgoJCXJldHVybiAkcmVzcG9uc2VzOwoJfQoKCS8qKgoJICogUmV0cmlldmUgdGhlIGVuY29kaW5ncyB3ZSBjYW4gYWNjZXB0CgkgKgoJICogQHJldHVybiBzdHJpbmcgQWNjZXB0LUVuY29kaW5nIGhlYWRlciB2YWx1ZQoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGFjY2VwdF9lbmNvZGluZygpIHsKCQkkdHlwZSA9IGFycmF5KCk7CgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnZ3ppbmZsYXRlJykpIHsKCQkJJHR5cGVbXSA9ICdkZWZsYXRlO3E9MS4wJzsKCQl9CgoJCWlmIChmdW5jdGlvbl9leGlzdHMoJ2d6dW5jb21wcmVzcycpKSB7CgkJCSR0eXBlW10gPSAnY29tcHJlc3M7cT0wLjUnOwoJCX0KCgkJJHR5cGVbXSA9ICdnemlwO3E9MC41JzsKCgkJcmV0dXJuIGltcGxvZGUoJywgJywgJHR5cGUpOwoJfQoKCS8qKgoJICogRm9ybWF0IGEgVVJMIGdpdmVuIEdFVCBkYXRhCgkgKgoJICogQHBhcmFtIGFycmF5ICR1cmxfcGFydHMKCSAqIEBwYXJhbSBhcnJheXxvYmplY3QgJGRhdGEgRGF0YSB0byBidWlsZCBxdWVyeSB1c2luZywgc2VlIHtAc2VlIGh0dHBzOi8vc2VjdXJlLnBocC5uZXQvaHR0cF9idWlsZF9xdWVyeX0KCSAqIEByZXR1cm4gc3RyaW5nIFVSTCB3aXRoIGRhdGEKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXRfZ2V0KCR1cmxfcGFydHMsICRkYXRhKSB7CgkJaWYgKCFlbXB0eSgkZGF0YSkpIHsKCQkJaWYgKGVtcHR5KCR1cmxfcGFydHNbJ3F1ZXJ5J10pKSB7CgkJCQkkdXJsX3BhcnRzWydxdWVyeSddID0gJyc7CgkJCX0KCgkJCSR1cmxfcGFydHNbJ3F1ZXJ5J10gLj0gJyYnIC4gaHR0cF9idWlsZF9xdWVyeSgkZGF0YSwgJycsICcmJyk7CgkJCSR1cmxfcGFydHNbJ3F1ZXJ5J10gID0gdHJpbSgkdXJsX3BhcnRzWydxdWVyeSddLCAnJicpOwoJCX0KCQlpZiAoaXNzZXQoJHVybF9wYXJ0c1sncGF0aCddKSkgewoJCQlpZiAoaXNzZXQoJHVybF9wYXJ0c1sncXVlcnknXSkpIHsKCQkJCSRnZXQgPSAkdXJsX3BhcnRzWydwYXRoJ10gLiAnPycgLiAkdXJsX3BhcnRzWydxdWVyeSddOwoJCQl9CgkJCWVsc2UgewoJCQkJJGdldCA9ICR1cmxfcGFydHNbJ3BhdGgnXTsKCQkJfQoJCX0KCQllbHNlIHsKCQkJJGdldCA9ICcvJzsKCQl9CgkJcmV0dXJuICRnZXQ7Cgl9CgoJLyoqCgkgKiBFcnJvciBoYW5kbGVyIGZvciBzdHJlYW1fc29ja2V0X2NsaWVudCgpCgkgKgoJICogQHBhcmFtIGludCAkZXJybm8gRXJyb3IgbnVtYmVyIChlLmcuIEVfV0FSTklORykKCSAqIEBwYXJhbSBzdHJpbmcgJGVycnN0ciBFcnJvciBtZXNzYWdlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjb25uZWN0X2Vycm9yX2hhbmRsZXIoJGVycm5vLCAkZXJyc3RyKSB7CgkJLy8gRG91YmxlLWNoZWNrIHdlIGNhbiBoYW5kbGUgaXQKCQlpZiAoKCRlcnJubyAmIEVfV0FSTklORykgPT09IDAgJiYgKCRlcnJubyAmIEVfTk9USUNFKSA9PT0gMCkgewoJCQkvLyBSZXR1cm4gZmFsc2UgdG8gaW5kaWNhdGUgdGhlIGRlZmF1bHQgZXJyb3IgaGFuZGxlciBzaG91bGQgZW5nYWdlCgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR0aGlzLT5jb25uZWN0X2Vycm9yIC49ICRlcnJzdHIgLiAiXG4iOwoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogVmVyaWZ5IHRoZSBjZXJ0aWZpY2F0ZSBhZ2FpbnN0IGNvbW1vbiBuYW1lIGFuZCBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWVzCgkgKgoJICogVW5mb3J0dW5hdGVseSwgUEhQIGRvZXNuJ3QgY2hlY2sgdGhlIGNlcnRpZmljYXRlIGFnYWluc3QgdGhlIGFsdGVybmF0aXZlCgkgKiBuYW1lcywgbGVhZGluZyB0aGluZ3MgbGlrZSAnaHR0cHM6Ly93d3cuZ2l0aHViLmNvbS8nIHRvIGJlIGludmFsaWQuCgkgKiBJbnN0ZWFkCgkgKgoJICogQHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgxOCNzZWN0aW9uLTMuMSBSRkMyODE4LCBTZWN0aW9uIDMuMQoJICoKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIGZhaWx1cmUgdG8gY29ubmVjdCB2aWEgVExTIChgZnNvY2tvcGVuLnNzbC5jb25uZWN0X2Vycm9yYCkKCSAqIEB0aHJvd3MgUmVxdWVzdHNfRXhjZXB0aW9uIE9uIG5vdCBvYnRhaW5pbmcgYSBtYXRjaCBmb3IgdGhlIGhvc3QgKGBmc29ja29wZW4uc3NsLm5vX21hdGNoYCkKCSAqIEBwYXJhbSBzdHJpbmcgJGhvc3QgSG9zdCBuYW1lIHRvIHZlcmlmeSBhZ2FpbnN0CgkgKiBAcGFyYW0gcmVzb3VyY2UgJGNvbnRleHQgU3RyZWFtIGNvbnRleHQKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gdmVyaWZ5X2NlcnRpZmljYXRlX2Zyb21fY29udGV4dCgkaG9zdCwgJGNvbnRleHQpIHsKCQkkbWV0YSA9IHN0cmVhbV9jb250ZXh0X2dldF9vcHRpb25zKCRjb250ZXh0KTsKCgkJLy8gSWYgd2UgZG9uJ3QgaGF2ZSBTU0wgb3B0aW9ucywgdGhlbiB3ZSBjb3VsZG4ndCBtYWtlIHRoZSBjb25uZWN0aW9uIGF0CgkJLy8gYWxsCgkJaWYgKGVtcHR5KCRtZXRhKSB8fCBlbXB0eSgkbWV0YVsnc3NsJ10pIHx8IGVtcHR5KCRtZXRhWydzc2wnXVsncGVlcl9jZXJ0aWZpY2F0ZSddKSkgewoJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKHJ0cmltKCR0aGlzLT5jb25uZWN0X2Vycm9yKSwgJ3NzbC5jb25uZWN0X2Vycm9yJyk7CgkJfQoKCQkkY2VydCA9IG9wZW5zc2xfeDUwOV9wYXJzZSgkbWV0YVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXSk7CgoJCXJldHVybiBSZXF1ZXN0c19TU0w6OnZlcmlmeV9jZXJ0aWZpY2F0ZSgkaG9zdCwgJGNlcnQpOwoJfQoKCS8qKgoJICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBpcyB2YWxpZAoJICoKCSAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKCSAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0cmFuc3BvcnQgaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0ZXN0KCRjYXBhYmlsaXRpZXMgPSBhcnJheSgpKSB7CgkJaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Zzb2Nrb3BlbicpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8vIElmIG5lZWRlZCwgY2hlY2sgdGhhdCBzdHJlYW1zIHN1cHBvcnQgU1NMCgkJaWYgKGlzc2V0KCRjYXBhYmlsaXRpZXNbJ3NzbCddKSAmJiAkY2FwYWJpbGl0aWVzWydzc2wnXSkgewoJCQlpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSB8fCAhZnVuY3Rpb25fZXhpc3RzKCdvcGVuc3NsX3g1MDlfcGFyc2UnKSkgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkvLyBDdXJyZW50bHkgYnJva2VuLCB0aGFua3MgdG8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2hodm0vaXNzdWVzLzIxNTYKCQkJaWYgKGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQp9Cjw/cGhwCi8qKgogKiBIVFRQIHJlc3BvbnNlIGNsYXNzCiAqCiAqIENvbnRhaW5zIGEgcmVzcG9uc2UgZnJvbSBSZXF1ZXN0czo6cmVxdWVzdCgpCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqLwoKLyoqCiAqIEhUVFAgcmVzcG9uc2UgY2xhc3MKICoKICogQ29udGFpbnMgYSByZXNwb25zZSBmcm9tIFJlcXVlc3RzOjpyZXF1ZXN0KCkKICogQHBhY2thZ2UgUmVxdWVzdHMKICovCmNsYXNzIFJlcXVlc3RzX1Jlc3BvbnNlIHsKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5oZWFkZXJzID0gbmV3IFJlcXVlc3RzX1Jlc3BvbnNlX0hlYWRlcnMoKTsKCQkkdGhpcy0+Y29va2llcyA9IG5ldyBSZXF1ZXN0c19Db29raWVfSmFyKCk7Cgl9CgoJLyoqCgkgKiBSZXNwb25zZSBib2R5CgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICRib2R5ID0gJyc7CgoJLyoqCgkgKiBSYXcgSFRUUCBkYXRhIGZyb20gdGhlIHRyYW5zcG9ydAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXB1YmxpYyAkcmF3ID0gJyc7CgoJLyoqCgkgKiBIZWFkZXJzLCBhcyBhbiBhc3NvY2lhdGl2ZSBhcnJheQoJICoKCSAqIEB2YXIgUmVxdWVzdHNfUmVzcG9uc2VfSGVhZGVycyBBcnJheS1saWtlIG9iamVjdCByZXByZXNlbnRpbmcgaGVhZGVycwoJICovCglwdWJsaWMgJGhlYWRlcnMgPSBhcnJheSgpOwoKCS8qKgoJICogU3RhdHVzIGNvZGUsIGZhbHNlIGlmIG5vbi1ibG9ja2luZwoJICoKCSAqIEB2YXIgaW50ZWdlcnxib29sZWFuCgkgKi8KCXB1YmxpYyAkc3RhdHVzX2NvZGUgPSBmYWxzZTsKCgkvKioKCSAqIFByb3RvY29sIHZlcnNpb24sIGZhbHNlIGlmIG5vbi1ibG9ja2luZwoJICoKCSAqIEB2YXIgZmxvYXR8Ym9vbGVhbgoJICovCglwdWJsaWMgJHByb3RvY29sX3ZlcnNpb24gPSBmYWxzZTsKCgkvKioKCSAqIFdoZXRoZXIgdGhlIHJlcXVlc3Qgc3VjY2VlZGVkIG9yIG5vdAoJICoKCSAqIEB2YXIgYm9vbGVhbgoJICovCglwdWJsaWMgJHN1Y2Nlc3MgPSBmYWxzZTsKCgkvKioKCSAqIE51bWJlciBvZiByZWRpcmVjdHMgdGhlIHJlcXVlc3QgdXNlZAoJICoKCSAqIEB2YXIgaW50ZWdlcgoJICovCglwdWJsaWMgJHJlZGlyZWN0cyA9IDA7CgoJLyoqCgkgKiBVUkwgcmVxdWVzdGVkCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHVibGljICR1cmwgPSAnJzsKCgkvKioKCSAqIFByZXZpb3VzIHJlcXVlc3RzIChmcm9tIHJlZGlyZWN0cykKCSAqCgkgKiBAdmFyIGFycmF5IEFycmF5IG9mIFJlcXVlc3RzX1Jlc3BvbnNlIG9iamVjdHMKCSAqLwoJcHVibGljICRoaXN0b3J5ID0gYXJyYXkoKTsKCgkvKioKCSAqIENvb2tpZXMgZnJvbSB0aGUgcmVxdWVzdAoJICoKCSAqIEB2YXIgUmVxdWVzdHNfQ29va2llX0phciBBcnJheS1saWtlIG9iamVjdCByZXByZXNlbnRpbmcgYSBjb29raWUgamFyCgkgKi8KCXB1YmxpYyAkY29va2llcyA9IGFycmF5KCk7CgoJLyoqCgkgKiBJcyB0aGUgcmVzcG9uc2UgYSByZWRpcmVjdD8KCSAqCgkgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiByZWRpcmVjdCAoM3h4IHN0YXR1cyksIGZhbHNlIGlmIG5vdC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX3JlZGlyZWN0KCkgewoJCSRjb2RlID0gJHRoaXMtPnN0YXR1c19jb2RlOwoJCXJldHVybiBpbl9hcnJheSgkY29kZSwgYXJyYXkoMzAwLCAzMDEsIDMwMiwgMzAzLCAzMDcpLCB0cnVlKSB8fCAkY29kZSA+IDMwNyAmJiAkY29kZSA8IDQwMDsKCX0KCgkvKioKCSAqIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHJlcXVlc3Qgd2FzIG5vdCBzdWNjZXNzZnVsCgkgKgoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb24gSWYgYCRhbGxvd19yZWRpcmVjdHNgIGlzIGZhbHNlLCBhbmQgY29kZSBpcyAzeHggKGByZXNwb25zZS5ub19yZWRpcmVjdHNgKQoJICogQHRocm93cyBSZXF1ZXN0c19FeGNlcHRpb25fSFRUUCBPbiBub24tc3VjY2Vzc2Z1bCBzdGF0dXMgY29kZS4gRXhjZXB0aW9uIGNsYXNzIGNvcnJlc3BvbmRzIHRvIGNvZGUgKGUuZy4ge0BzZWUgUmVxdWVzdHNfRXhjZXB0aW9uX0hUVFBfNDA0fSkKCSAqIEBwYXJhbSBib29sZWFuICRhbGxvd19yZWRpcmVjdHMgU2V0IHRvIGZhbHNlIHRvIHRocm93IG9uIGEgM3h4IGFzIHdlbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRocm93X2Zvcl9zdGF0dXMoJGFsbG93X3JlZGlyZWN0cyA9IHRydWUpIHsKCQlpZiAoJHRoaXMtPmlzX3JlZGlyZWN0KCkpIHsKCQkJaWYgKCEkYWxsb3dfcmVkaXJlY3RzKSB7CgkJCQl0aHJvdyBuZXcgUmVxdWVzdHNfRXhjZXB0aW9uKCdSZWRpcmVjdGlvbiBub3QgYWxsb3dlZCcsICdyZXNwb25zZS5ub19yZWRpcmVjdHMnLCAkdGhpcyk7CgkJCX0KCQl9CgkJZWxzZWlmICghJHRoaXMtPnN1Y2Nlc3MpIHsKCQkJJGV4Y2VwdGlvbiA9IFJlcXVlc3RzX0V4Y2VwdGlvbl9IVFRQOjpnZXRfY2xhc3MoJHRoaXMtPnN0YXR1c19jb2RlKTsKCQkJdGhyb3cgbmV3ICRleGNlcHRpb24obnVsbCwgJHRoaXMpOwoJCX0KCX0KfQo8P3BocAovKioKICogSFRUUCBQcm94eSBjb25uZWN0aW9uIGludGVyZmFjZQogKgogKiBAcGFja2FnZSBSZXF1ZXN0cwogKiBAc3VicGFja2FnZSBQcm94eQogKiBAc2luY2UgMS42CiAqLwoKLyoqCiAqIEhUVFAgUHJveHkgY29ubmVjdGlvbiBpbnRlcmZhY2UKICoKICogUHJvdmlkZXMgYSBoYW5kbGVyIGZvciBjb25uZWN0aW9uIHZpYSBhbiBIVFRQIHByb3h5CiAqCiAqIEBwYWNrYWdlIFJlcXVlc3RzCiAqIEBzdWJwYWNrYWdlIFByb3h5CiAqIEBzaW5jZSAxLjYKICovCmNsYXNzIFJlcXVlc3RzX1Byb3h5X0hUVFAgaW1wbGVtZW50cyBSZXF1ZXN0c19Qcm94eSB7CgkvKioKCSAqIFByb3h5IGhvc3QgYW5kIHBvcnQKCSAqCgkgKiBOb3RhdGlvbjogImhvc3Q6cG9ydCIgKGVnIDEyNy4wLjAuMTo4MDgwIG9yIHNvbWVwcm94eS5jb206MzEyOCkKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHByb3h5OwoKCS8qKgoJICogVXNlcm5hbWUKCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwdWJsaWMgJHVzZXI7CgoJLyoqCgkgKiBQYXNzd29yZAoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXB1YmxpYyAkcGFzczsKCgkvKioKCSAqIERvIHdlIG5lZWQgdG8gYXV0aGVudGljYXRlPyAoaWUgdXNlcm5hbWUgJiBwYXNzd29yZCBoYXZlIGJlZW4gcHJvdmlkZWQpCgkgKgoJICogQHZhciBib29sZWFuCgkgKi8KCXB1YmxpYyAkdXNlX2F1dGhlbnRpY2F0aW9uOwoKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqCgkgKiBAc2luY2UgMS42CgkgKiBAdGhyb3dzIFJlcXVlc3RzX0V4Y2VwdGlvbiBPbiBpbmNvcnJlY3QgbnVtYmVyIG9mIGFyZ3VtZW50cyAoYGF1dGhiYXNpY2JhZGFyZ3NgKQoJICogQHBhcmFtIGFycmF5fG51bGwgJGFyZ3MgQXJyYXkgb2YgdXNlciBhbmQgcGFzc3dvcmQuIE11c3QgaGF2ZSBleGFjdGx5IHR3byBlbGVtZW50cwoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGFyZ3MgPSBudWxsKSB7CgkJaWYgKGlzX3N0cmluZygkYXJncykpIHsKCQkJJHRoaXMtPnByb3h5ID0gJGFyZ3M7CgkJfQoJCWVsc2VpZiAoaXNfYXJyYXkoJGFyZ3MpKSB7CgkJCWlmIChjb3VudCgkYXJncykgPT09IDEpIHsKCQkJCWxpc3QoJHRoaXMtPnByb3h5KSA9ICRhcmdzOwoJCQl9CgkJCWVsc2VpZiAoY291bnQoJGFyZ3MpID09PSAzKSB7CgkJCQlsaXN0KCR0aGlzLT5wcm94eSwgJHRoaXMtPnVzZXIsICR0aGlzLT5wYXNzKSA9ICRhcmdzOwoJCQkJJHRoaXMtPnVzZV9hdXRoZW50aWNhdGlvbiAgICAgICAgICAgICAgICAgICAgPSB0cnVlOwoJCQl9CgkJCWVsc2UgewoJCQkJdGhyb3cgbmV3IFJlcXVlc3RzX0V4Y2VwdGlvbignSW52YWxpZCBudW1iZXIgb2YgYXJndW1lbnRzJywgJ3Byb3h5aHR0cGJhZGFyZ3MnKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFJlZ2lzdGVyIHRoZSBuZWNlc3NhcnkgY2FsbGJhY2tzCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHNlZSBjdXJsX2JlZm9yZV9zZW5kCgkgKiBAc2VlIGZzb2Nrb3Blbl9yZW1vdGVfc29ja2V0CgkgKiBAc2VlIGZzb2Nrb3Blbl9yZW1vdGVfaG9zdF9wYXRoCgkgKiBAc2VlIGZzb2Nrb3Blbl9oZWFkZXIKCSAqIEBwYXJhbSBSZXF1ZXN0c19Ib29rcyAkaG9va3MgSG9vayBzeXN0ZW0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKFJlcXVlc3RzX0hvb2tzICRob29rcykgewoJCSRob29rcy0+cmVnaXN0ZXIoJ2N1cmwuYmVmb3JlX3NlbmQnLCBhcnJheSgkdGhpcywgJ2N1cmxfYmVmb3JlX3NlbmQnKSk7CgoJCSRob29rcy0+cmVnaXN0ZXIoJ2Zzb2Nrb3Blbi5yZW1vdGVfc29ja2V0JywgYXJyYXkoJHRoaXMsICdmc29ja29wZW5fcmVtb3RlX3NvY2tldCcpKTsKCQkkaG9va3MtPnJlZ2lzdGVyKCdmc29ja29wZW4ucmVtb3RlX2hvc3RfcGF0aCcsIGFycmF5KCR0aGlzLCAnZnNvY2tvcGVuX3JlbW90ZV9ob3N0X3BhdGgnKSk7CgkJaWYgKCR0aGlzLT51c2VfYXV0aGVudGljYXRpb24pIHsKCQkJJGhvb2tzLT5yZWdpc3RlcignZnNvY2tvcGVuLmFmdGVyX2hlYWRlcnMnLCBhcnJheSgkdGhpcywgJ2Zzb2Nrb3Blbl9oZWFkZXInKSk7CgkJfQoJfQoKCS8qKgoJICogU2V0IGNVUkwgcGFyYW1ldGVycyBiZWZvcmUgdGhlIGRhdGEgaXMgc2VudAoJICoKCSAqIEBzaW5jZSAxLjYKCSAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlIGNVUkwgcmVzb3VyY2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cmxfYmVmb3JlX3NlbmQoJiRoYW5kbGUpIHsKCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1BST1hZVFlQRSwgQ1VSTFBST1hZX0hUVFApOwoJCWN1cmxfc2V0b3B0KCRoYW5kbGUsIENVUkxPUFRfUFJPWFksICR0aGlzLT5wcm94eSk7CgoJCWlmICgkdGhpcy0+dXNlX2F1dGhlbnRpY2F0aW9uKSB7CgkJCWN1cmxfc2V0b3B0KCRoYW5kbGUsIENVUkxPUFRfUFJPWFlBVVRILCBDVVJMQVVUSF9BTlkpOwoJCQljdXJsX3NldG9wdCgkaGFuZGxlLCBDVVJMT1BUX1BST1hZVVNFUlBXRCwgJHRoaXMtPmdldF9hdXRoX3N0cmluZygpKTsKCQl9Cgl9CgoJLyoqCgkgKiBBbHRlciByZW1vdGUgc29ja2V0IGluZm9ybWF0aW9uIGJlZm9yZSBvcGVuaW5nIHNvY2tldCBjb25uZWN0aW9uCgkgKgoJICogQHNpbmNlIDEuNgoJICogQHBhcmFtIHN0cmluZyAkcmVtb3RlX3NvY2tldCBTb2NrZXQgY29ubmVjdGlvbiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZzb2Nrb3Blbl9yZW1vdGVfc29ja2V0KCYkcmVtb3RlX3NvY2tldCkgewoJCSRyZW1vdGVfc29ja2V0ID0gJHRoaXMtPnByb3h5OwoJfQoKCS8qKgoJICogQWx0ZXIgcmVtb3RlIHBhdGggYmVmb3JlIGdldHRpbmcgc3RyZWFtIGRhdGEKCSAqCgkgKiBAc2luY2UgMS42CgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gc2VuZCBpbiBIVFRQIHJlcXVlc3Qgc3RyaW5nICgiR0VUIC4uLiIpCgkgKiBAcGFyYW0gc3RyaW5nICR1cmwgRnVsbCBVUkwgd2UncmUgcmVxdWVzdGluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZnNvY2tvcGVuX3JlbW90ZV9ob3N0X3BhdGgoJiRwYXRoLCAkdXJsKSB7CgkJJHBhdGggPSAkdXJsOwoJfQoKCS8qKgoJICogQWRkIGV4dHJhIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3QgYmVmb3JlIHNlbmRpbmcKCSAqCgkgKiBAc2luY2UgMS42CgkgKiBAcGFyYW0gc3RyaW5nICRvdXQgSFRUUCBoZWFkZXIgc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmc29ja29wZW5faGVhZGVyKCYkb3V0KSB7CgkJJG91dCAuPSBzcHJpbnRmKCJQcm94eS1BdXRob3JpemF0aW9uOiBCYXNpYyAlc1xyXG4iLCBiYXNlNjRfZW5jb2RlKCR0aGlzLT5nZXRfYXV0aF9zdHJpbmcoKSkpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhdXRoZW50aWNhdGlvbiBzdHJpbmcgKHVzZXI6cGFzcykKCSAqCgkgKiBAc2luY2UgMS42CgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2F1dGhfc3RyaW5nKCkgewoJCXJldHVybiAkdGhpcy0+dXNlciAuICc6JyAuICR0aGlzLT5wYXNzOwoJfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci94ZGVidWctaGFuZGxlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxYZGVidWdIYW5kbGVyOwoKLyoqCiAqIFByb3ZpZGVzIHV0aWxpdHkgZnVuY3Rpb25zIHRvIHByZXBhcmUgYSBjaGlsZCBwcm9jZXNzIGNvbW1hbmQtbGluZSBhbmQgc2V0CiAqIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiB0aGF0IHByb2Nlc3MuCiAqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgUHJvY2Vzcwp7CiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgcGFyYW1ldGVycywgaW5jbHVkaW5nIGEgY29sb3Igb3B0aW9uIGlmIHJlcXVpcmVkCiAgICAgKgogICAgICogQSBjb2xvciBvcHRpb24gaXMgbmVlZGVkIGJlY2F1c2UgY2hpbGQgcHJvY2VzcyBvdXRwdXQgaXMgcGlwZWQuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhcmdzIFRoZSBzY3JpcHQgcGFyYW1ldGVycwogICAgICogQHBhcmFtIHN0cmluZyAkY29sb3JPcHRpb24gVGhlIGxvbmcgb3B0aW9uIHRvIGZvcmNlIGNvbG9yIG91dHB1dAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhZGRDb2xvck9wdGlvbihhcnJheSAkYXJncywgJGNvbG9yT3B0aW9uKQogICAgewogICAgICAgIGlmICghJGNvbG9yT3B0aW9uCiAgICAgICAgICAgIHx8IGluX2FycmF5KCRjb2xvck9wdGlvbiwgJGFyZ3MpCiAgICAgICAgICAgIHx8ICFwcmVnX21hdGNoKCcvXi0tKFthLXpdKyQpfCheLS1bYS16XSs9KS8nLCAkY29sb3JPcHRpb24sICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gJGFyZ3M7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgIC8vIEhhbmRsZSAtLWNvbG9yKHMpPSBvcHRpb25zCiAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gKCRpbmRleCA9IGFycmF5X3NlYXJjaCgkbWF0Y2hlc1syXS4nYXV0bycsICRhcmdzKSkpIHsKICAgICAgICAgICAgICAgICRhcmdzWyRpbmRleF0gPSAkY29sb3JPcHRpb247CiAgICAgICAgICAgICAgICByZXR1cm4gJGFyZ3M7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX2dyZXAoJy9eJy4kbWF0Y2hlc1syXS4nLycsICRhcmdzKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhcmdzOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCctLW5vLScuJG1hdGNoZXNbMV0sICRhcmdzKSkgewogICAgICAgICAgICByZXR1cm4gJGFyZ3M7CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayBmb3IgTk9fQ09MT1IgdmFyaWFibGUgKGh0dHBzOi8vbm8tY29sb3Iub3JnLykKICAgICAgICBpZiAoZmFsc2UgIT09IGdldGVudignTk9fQ09MT1InKSkgewogICAgICAgICAgICByZXR1cm4gJGFyZ3M7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgIT09ICgkaW5kZXggPSBhcnJheV9zZWFyY2goJy0tJywgJGFyZ3MpKSkgewogICAgICAgICAgICAvLyBQb3NpdGlvbiBvcHRpb24gYmVmb3JlIGRvdWJsZS1kYXNoIGRlbGltaXRlcgogICAgICAgICAgICBhcnJheV9zcGxpY2UoJGFyZ3MsICRpbmRleCwgMCwgJGNvbG9yT3B0aW9uKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYXJnc1tdID0gJGNvbG9yT3B0aW9uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhcmdzOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc2hlbGwgYXJndW1lbnQuCiAgICAgKgogICAgICogRnJvbSBodHRwczovL2dpdGh1Yi5jb20vam9obnN0ZXZlbnNvbi93aW5ib3gtYXJncwogICAgICogTUlUIExpY2Vuc2VkIChjKSBKb2huIFN0ZXZlbnNvbiA8am9obi1zdGV2ZW5zb25AYmx1ZXlvbmRlci5jby51az4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhcmcgIFRoZSBhcmd1bWVudCB0byBiZSBlc2NhcGVkCiAgICAgKiBAcGFyYW0gYm9vbCAgICRtZXRhIEFkZGl0aW9uYWxseSBlc2NhcGUgY21kLmV4ZSBtZXRhIGNoYXJhY3RlcnMKICAgICAqIEBwYXJhbSBib29sICRtb2R1bGUgVGhlIGFyZ3VtZW50IGlzIHRoZSBtb2R1bGUgdG8gaW52b2tlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGVzY2FwZWQgYXJndW1lbnQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGUoJGFyZywgJG1ldGEgPSB0cnVlLCAkbW9kdWxlID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFkZWZpbmVkKCdQSFBfV0lORE9XU19WRVJTSU9OX0JVSUxEJykpIHsKICAgICAgICAgICAgcmV0dXJuICInIi5zdHJfcmVwbGFjZSgiJyIsICInXFwnJyIsICRhcmcpLiInIjsKICAgICAgICB9CgogICAgICAgICRxdW90ZSA9IHN0cnBicmsoJGFyZywgIiBcdCIpICE9PSBmYWxzZSB8fCAkYXJnID09PSAnJzsKCiAgICAgICAgJGFyZyA9IHByZWdfcmVwbGFjZSgnLyhcXFxcKikiLycsICckMSQxXFwiJywgJGFyZywgLTEsICRkcXVvdGVzKTsKCiAgICAgICAgaWYgKCRtZXRhKSB7CiAgICAgICAgICAgICRtZXRhID0gJGRxdW90ZXMgfHwgcHJlZ19tYXRjaCgnLyVbXiVdKyUvJywgJGFyZyk7CgogICAgICAgICAgICBpZiAoISRtZXRhKSB7CiAgICAgICAgICAgICAgICAkcXVvdGUgPSAkcXVvdGUgfHwgc3RycGJyaygkYXJnLCAnXiZ8PD4oKScpICE9PSBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRtb2R1bGUgJiYgISRkcXVvdGVzICYmICRxdW90ZSkgewogICAgICAgICAgICAgICAgJG1ldGEgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRxdW90ZSkgewogICAgICAgICAgICAkYXJnID0gJyInLnByZWdfcmVwbGFjZSgnLyhcXFxcKikkLycsICckMSQxJywgJGFyZykuJyInOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRtZXRhKSB7CiAgICAgICAgICAgICRhcmcgPSBwcmVnX3JlcGxhY2UoJy8oWyJeJnw8PigpJV0pLycsICdeJDEnLCAkYXJnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYXJnOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBvdXRwdXQgc3RyZWFtIHN1cHBvcnRzIGNvbG9ycwogICAgICoKICAgICAqIFRoaXMgaXMgdHJpY2t5IG9uIFdpbmRvd3MsIGJlY2F1c2UgQ3lnd2luLCBNc3lzMiBldGMgZW11bGF0ZSBwc2V1ZG8KICAgICAqIHRlcm1pbmFscyB2aWEgbmFtZWQgcGlwZXMsIHNvIHdlIGNhbiBvbmx5IGNoZWNrIHRoZSBlbnZpcm9ubWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJG91dHB1dCBBIHZhbGlkIENMSSBvdXRwdXQgc3RyZWFtCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHNDb2xvcigkb3V0cHV0KQogICAgewogICAgICAgIGlmICgnSHlwZXInID09PSBnZXRlbnYoJ1RFUk1fUFJPR1JBTScpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKSkgewogICAgICAgICAgICByZXR1cm4gKGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQnKQogICAgICAgICAgICAgICAgJiYgc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQoJG91dHB1dCkpCiAgICAgICAgICAgICAgICB8fCBmYWxzZSAhPT0gZ2V0ZW52KCdBTlNJQ09OJykKICAgICAgICAgICAgICAgIHx8ICdPTicgPT09IGdldGVudignQ29uRW11QU5TSScpCiAgICAgICAgICAgICAgICB8fCAneHRlcm0nID09PSBnZXRlbnYoJ1RFUk0nKTsKICAgICAgICB9CgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3N0cmVhbV9pc2F0dHknKSkgewogICAgICAgICAgICByZXR1cm4gc3RyZWFtX2lzYXR0eSgkb3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2lzYXR0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBwb3NpeF9pc2F0dHkoJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkc3RhdCA9IGZzdGF0KCRvdXRwdXQpOwogICAgICAgIC8vIENoZWNrIGlmIGZvcm1hdHRlZCBtb2RlIGlzIFNfSUZDSFIKICAgICAgICByZXR1cm4gJHN0YXQgPyAwMDIwMDAwID09PSAoJHN0YXRbJ21vZGUnXSAmIDAxNzAwMDApIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBwdXRlbnYgZW52aXJvbm1lbnQgY2hhbmdlcyBhdmFpbGFibGUgaW4gJF9TRVJWRVIgYW5kICRfRU5WCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xmYWxzZSAkdmFsdWUgQSBmYWxzZSB2YWx1ZSB1bnNldHMgdGhlIHZhcmlhYmxlCiAgICAgKgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIHdhcyBzZXQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRFbnYoJG5hbWUsICR2YWx1ZSA9IGZhbHNlKQogICAgewogICAgICAgICR1bnNldCA9IGZhbHNlID09PSAkdmFsdWU7CgogICAgICAgIGlmICghcHV0ZW52KCR1bnNldCA/ICRuYW1lIDogJG5hbWUuJz0nLiR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR1bnNldCkgewogICAgICAgICAgICB1bnNldCgkX1NFUlZFUlskbmFtZV0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRfU0VSVkVSWyRuYW1lXSA9ICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIC8vIFVwZGF0ZSAkX0VOViBpZiBpdCBpcyBiZWluZyB1c2VkCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJpcG9zKChzdHJpbmcpIGluaV9nZXQoJ3ZhcmlhYmxlc19vcmRlcicpLCAnRScpKSB7CiAgICAgICAgICAgIGlmICgkdW5zZXQpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRfRU5WWyRuYW1lXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkX0VOVlskbmFtZV0gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci94ZGVidWctaGFuZGxlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxYZGVidWdIYW5kbGVyOwoKLyoqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBQaHBDb25maWcKewogICAgLyoqCiAgICAgKiBVc2UgdGhlIG9yaWdpbmFsIFBIUCBjb25maWd1cmF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBQSFAgY2xpIG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVzZU9yaWdpbmFsKCkKICAgIHsKICAgICAgICAkdGhpcy0+Z2V0RGF0YUFuZFJlc2V0KCk7CiAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2Ugc3RhbmRhcmQgcmVzdGFydCBzZXR0aW5ncwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgUEhQIGNsaSBvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1c2VTdGFuZGFyZCgpCiAgICB7CiAgICAgICAgaWYgKCRkYXRhID0gJHRoaXMtPmdldERhdGFBbmRSZXNldCgpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgnLW4nLCAnLWMnLCAkZGF0YVsndG1wSW5pJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2UgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHBlcnNpc3Qgc2V0dGluZ3MKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFBIUCBjbGkgb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXNlUGVyc2lzdGVudCgpCiAgICB7CiAgICAgICAgaWYgKCRkYXRhID0gJHRoaXMtPmdldERhdGFBbmRSZXNldCgpKSB7CiAgICAgICAgICAgIFByb2Nlc3M6OnNldEVudignUEhQUkMnLCAkZGF0YVsndG1wSW5pJ10pOwogICAgICAgICAgICBQcm9jZXNzOjpzZXRFbnYoJ1BIUF9JTklfU0NBTl9ESVInLCAnJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcmVzdGFydCBkYXRhIGlmIGF2YWlsYWJsZSBhbmQgcmVzZXRzIHRoZSBlbnZpcm9ubWVudAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERhdGFBbmRSZXNldCgpCiAgICB7CiAgICAgICAgaWYgKCRkYXRhID0gWGRlYnVnSGFuZGxlcjo6Z2V0UmVzdGFydFNldHRpbmdzKCkpIHsKICAgICAgICAgICAgUHJvY2Vzczo6c2V0RW52KCdQSFBSQycsICRkYXRhWydwaHByYyddKTsKICAgICAgICAgICAgUHJvY2Vzczo6c2V0RW52KCdQSFBfSU5JX1NDQU5fRElSJywgJGRhdGFbJ3NjYW5EaXInXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFhkZWJ1Z0hhbmRsZXI7Cgp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKb2huIFN0ZXZlbnNvbiA8am9obi1zdGV2ZW5zb25AYmx1ZXlvbmRlci5jby51az4KICovCmNsYXNzIFhkZWJ1Z0hhbmRsZXIKewogICAgY29uc3QgU1VGRklYX0FMTE9XID0gJ19BTExPV19YREVCVUcnOwogICAgY29uc3QgU1VGRklYX0lOSVMgPSAnX09SSUdJTkFMX0lOSVMnOwogICAgY29uc3QgUkVTVEFSVF9JRCA9ICdpbnRlcm5hbCc7CiAgICBjb25zdCBSRVNUQVJUX1NFVFRJTkdTID0gJ1hERUJVR19IQU5ETEVSX1NFVFRJTkdTJzsKICAgIGNvbnN0IERFQlVHID0gJ1hERUJVR19IQU5ETEVSX0RFQlVHJzsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJvdGVjdGVkICR0bXBJbmk7CgogICAgcHJpdmF0ZSBzdGF0aWMgJGluUmVzdGFydDsKICAgIHByaXZhdGUgc3RhdGljICRuYW1lOwogICAgcHJpdmF0ZSBzdGF0aWMgJHNraXBwZWQ7CgogICAgcHJpdmF0ZSAkY2xpOwogICAgcHJpdmF0ZSAkY29sb3JPcHRpb247CiAgICBwcml2YXRlICRkZWJ1ZzsKICAgIHByaXZhdGUgJGVudkFsbG93WGRlYnVnOwogICAgcHJpdmF0ZSAkZW52T3JpZ2luYWxJbmlzOwogICAgcHJpdmF0ZSAkbG9hZGVkOwogICAgcHJpdmF0ZSAkcGVyc2lzdGVudDsKICAgIHByaXZhdGUgJHNjcmlwdDsKICAgIC8qKiBAdmFyIFN0YXR1c3xudWxsICovCiAgICBwcml2YXRlICRzdGF0dXNXcml0ZXI7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcgogICAgICoKICAgICAqIFRoZSAkZW52UHJlZml4IGlzIHVzZWQgdG8gY3JlYXRlIGRpc3RpbmN0IGVudmlyb25tZW50IHZhcmlhYmxlcy4gSXQgaXMKICAgICAqIHVwcGVyY2FzZWQgYW5kIHByZXBlbmRlZCB0byB0aGUgZGVmYXVsdCBiYXNlIHZhbHVlcy4gRm9yIGV4YW1wbGUgJ215YXBwJwogICAgICogd291bGQgcmVzdWx0IGluIE1ZQVBQX0FMTE9XX1hERUJVRyBhbmQgTVlBUFBfT1JJR0lOQUxfSU5JUy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlbnZQcmVmaXggVmFsdWUgdXNlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbG9yT3B0aW9uIENvbW1hbmQtbGluZSBsb25nIG9wdGlvbiB0byBmb3JjZSBjb2xvciBvdXRwdXQKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gSWYgYSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGVudlByZWZpeCwgJGNvbG9yT3B0aW9uID0gJycpCiAgICB7CiAgICAgICAgaWYgKCFpc19zdHJpbmcoJGVudlByZWZpeCkgfHwgZW1wdHkoJGVudlByZWZpeCkgfHwgIWlzX3N0cmluZygkY29sb3JPcHRpb24pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignSW52YWxpZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXInKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRuYW1lID0gc3RydG91cHBlcigkZW52UHJlZml4KTsKICAgICAgICAkdGhpcy0+ZW52QWxsb3dYZGVidWcgPSBzZWxmOjokbmFtZS5zZWxmOjpTVUZGSVhfQUxMT1c7CiAgICAgICAgJHRoaXMtPmVudk9yaWdpbmFsSW5pcyA9IHNlbGY6OiRuYW1lLnNlbGY6OlNVRkZJWF9JTklTOwoKICAgICAgICAkdGhpcy0+Y29sb3JPcHRpb24gPSAkY29sb3JPcHRpb247CgogICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCd4ZGVidWcnKSkgewogICAgICAgICAgICAkZXh0ID0gbmV3IFxSZWZsZWN0aW9uRXh0ZW5zaW9uKCd4ZGVidWcnKTsKICAgICAgICAgICAgJHRoaXMtPmxvYWRlZCA9ICRleHQtPmdldFZlcnNpb24oKSA/OiAndW5rbm93bic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmNsaSA9IFBIUF9TQVBJID09PSAnY2xpJykgewogICAgICAgICAgICAkdGhpcy0+ZGVidWcgPSBnZXRlbnYoc2VsZjo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0YXR1c1dyaXRlciA9IG5ldyBTdGF0dXMoJHRoaXMtPmVudkFsbG93WGRlYnVnLCAoYm9vbCkgJHRoaXMtPmRlYnVnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFjdGl2YXRlcyBzdGF0dXMgbWVzc2FnZSBvdXRwdXQgdG8gYSBQU1IzIGxvZ2dlcgogICAgICoKICAgICAqIEBwYXJhbSBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcihMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcikKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdHVzV3JpdGVyLT5zZXRMb2dnZXIoJGxvZ2dlcik7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWFpbiBzY3JpcHQgbG9jYXRpb24gaWYgaXQgY2Fubm90IGJlIGNhbGxlZCBmcm9tIGFyZ3YKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzY3JpcHQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNYWluU2NyaXB0KCRzY3JpcHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjcmlwdCA9ICRzY3JpcHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUGVyc2lzdCB0aGUgc2V0dGluZ3MgdG8ga2VlcCBYZGVidWcgb3V0IG9mIHN1Yi1wcm9jZXNzZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQZXJzaXN0ZW50KCkKICAgIHsKICAgICAgICAkdGhpcy0+cGVyc2lzdGVudCA9IHRydWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIFhkZWJ1ZyBpcyBsb2FkZWQgYW5kIHRoZSBwcm9jZXNzIG5lZWRzIHRvIGJlIHJlc3RhcnRlZAogICAgICoKICAgICAqIFRoaXMgYmVoYXZpb3VyIGNhbiBiZSBkaXNhYmxlZCBieSBzZXR0aW5nIHRoZSBNWUFQUF9BTExPV19YREVCVUcKICAgICAqIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIDEuIFRoaXMgdmFyaWFibGUgaXMgdXNlZCBpbnRlcm5hbGx5IHNvIHRoYXQKICAgICAqIHRoZSByZXN0YXJ0ZWQgcHJvY2VzcyBpcyBjcmVhdGVkIG9ubHkgb25jZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCkKICAgIHsKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6Q0hFQ0ssICR0aGlzLT5sb2FkZWQpOwogICAgICAgICRlbnZBcmdzID0gZXhwbG9kZSgnfCcsIChzdHJpbmcpIGdldGVudigkdGhpcy0+ZW52QWxsb3dYZGVidWcpKTsKCiAgICAgICAgaWYgKGVtcHR5KCRlbnZBcmdzWzBdKSAmJiAkdGhpcy0+cmVxdWlyZXNSZXN0YXJ0KChib29sKSAkdGhpcy0+bG9hZGVkKSkgewogICAgICAgICAgICAvLyBSZXN0YXJ0IHJlcXVpcmVkCiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpSRVNUQVJUKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJlcGFyZVJlc3RhcnQoKSkgewogICAgICAgICAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2V0Q29tbWFuZCgpOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlc3RhcnQoJGNvbW1hbmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjpSRVNUQVJUX0lEID09PSAkZW52QXJnc1swXSAmJiBjb3VudCgkZW52QXJncykgPT09IDUpIHsKICAgICAgICAgICAgLy8gUmVzdGFydGVkLCBzbyB1bnNldCBlbnZpcm9ubWVudCB2YXJpYWJsZSBhbmQgdXNlIHNhdmVkIHZhbHVlcwogICAgICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6UkVTVEFSVEVEKTsKCiAgICAgICAgICAgIFByb2Nlc3M6OnNldEVudigkdGhpcy0+ZW52QWxsb3dYZGVidWcpOwogICAgICAgICAgICBzZWxmOjokaW5SZXN0YXJ0ID0gdHJ1ZTsKCiAgICAgICAgICAgIGlmICghJHRoaXMtPmxvYWRlZCkgewogICAgICAgICAgICAgICAgLy8gU2tpcHBlZCB2ZXJzaW9uIGlzIG9ubHkgc2V0IGlmIFhkZWJ1ZyBpcyBub3QgbG9hZGVkCiAgICAgICAgICAgICAgICBzZWxmOjokc2tpcHBlZCA9ICRlbnZBcmdzWzFdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+dHJ5RW5hYmxlU2lnbmFscygpOwoKICAgICAgICAgICAgLy8gUHV0IHJlc3RhcnQgc2V0dGluZ3MgaW4gdGhlIGVudmlyb25tZW50CiAgICAgICAgICAgICR0aGlzLT5zZXRFbnZSZXN0YXJ0U2V0dGluZ3MoJGVudkFyZ3MpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6Tk9SRVNUQVJUKTsKCiAgICAgICAgaWYgKCRzZXR0aW5ncyA9IHNlbGY6OmdldFJlc3RhcnRTZXR0aW5ncygpKSB7CiAgICAgICAgICAgIC8vIENhbGxlZCB3aXRoIGV4aXN0aW5nIHNldHRpbmdzLCBzbyBzeW5jIG91ciBzZXR0aW5ncwogICAgICAgICAgICAkdGhpcy0+c3luY1NldHRpbmdzKCRzZXR0aW5ncyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBwaHAuaW5pIGxvY2F0aW9ucyB3aXRoIGF0IGxlYXN0IG9uZSBlbnRyeQogICAgICoKICAgICAqIFRoZSBlcXVpdmFsZW50IG9mIGNhbGxpbmcgcGhwX2luaV9sb2FkZWRfZmlsZSB0aGVuIHBocF9pbmlfc2Nhbm5lZF9maWxlcy4KICAgICAqIFRoZSBsb2FkZWQgaW5pIGxvY2F0aW9uIGlzIHRoZSBmaXJzdCBlbnRyeSBhbmQgbWF5IGJlIGVtcHR5LgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRBbGxJbmlGaWxlcygpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eShzZWxmOjokbmFtZSkpIHsKICAgICAgICAgICAgJGVudiA9IGdldGVudihzZWxmOjokbmFtZS5zZWxmOjpTVUZGSVhfSU5JUyk7CgogICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRlbnYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBleHBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkZW52KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBhdGhzID0gYXJyYXkoKHN0cmluZykgcGhwX2luaV9sb2FkZWRfZmlsZSgpKTsKCiAgICAgICAgaWYgKCRzY2FubmVkID0gcGhwX2luaV9zY2FubmVkX2ZpbGVzKCkpIHsKICAgICAgICAgICAgJHBhdGhzID0gYXJyYXlfbWVyZ2UoJHBhdGhzLCBhcnJheV9tYXAoJ3RyaW0nLCBleHBsb2RlKCcsJywgJHNjYW5uZWQpKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhdGhzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiByZXN0YXJ0IHNldHRpbmdzIG9yIG51bGwKICAgICAqCiAgICAgKiBTZXR0aW5ncyB3aWxsIGJlIGF2YWlsYWJsZSBpZiB0aGUgY3VycmVudCBwcm9jZXNzIHdhcyByZXN0YXJ0ZWQsIG9yCiAgICAgKiBjYWxsZWQgd2l0aCB0aGUgc2V0dGluZ3MgZnJvbSBhbiBleGlzdGluZyByZXN0YXJ0LgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJlc3RhcnRTZXR0aW5ncygpCiAgICB7CiAgICAgICAgJGVudkFyZ3MgPSBleHBsb2RlKCd8JywgKHN0cmluZykgZ2V0ZW52KHNlbGY6OlJFU1RBUlRfU0VUVElOR1MpKTsKCiAgICAgICAgaWYgKGNvdW50KCRlbnZBcmdzKSAhPT0gNgogICAgICAgICAgICB8fCAoIXNlbGY6OiRpblJlc3RhcnQgJiYgcGhwX2luaV9sb2FkZWRfZmlsZSgpICE9PSAkZW52QXJnc1swXSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICd0bXBJbmknID0+ICRlbnZBcmdzWzBdLAogICAgICAgICAgICAnc2Nhbm5lZEluaXMnID0+IChib29sKSAkZW52QXJnc1sxXSwKICAgICAgICAgICAgJ3NjYW5EaXInID0+ICcqJyA9PT0gJGVudkFyZ3NbMl0gPyBmYWxzZSA6ICRlbnZBcmdzWzJdLAogICAgICAgICAgICAncGhwcmMnID0+ICcqJyA9PT0gJGVudkFyZ3NbM10gPyBmYWxzZSA6ICRlbnZBcmdzWzNdLAogICAgICAgICAgICAnaW5pcycgPT4gZXhwbG9kZShQQVRIX1NFUEFSQVRPUiwgJGVudkFyZ3NbNF0pLAogICAgICAgICAgICAnc2tpcHBlZCcgPT4gJGVudkFyZ3NbNV0sCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFhkZWJ1ZyB2ZXJzaW9uIHRoYXQgdHJpZ2dlcmVkIGEgc3VjY2Vzc2Z1bCByZXN0YXJ0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTa2lwcGVkVmVyc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIChzdHJpbmcpIHNlbGY6OiRza2lwcGVkOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIFhkZWJ1ZyBpcyBsb2FkZWQsIG9yIGFzIGRpcmVjdGVkIGJ5IGFuIGV4dGVuZGluZyBjbGFzcwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpc0xvYWRlZCBXaGV0aGVyIFhkZWJ1ZyBpcyBsb2FkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlcXVpcmVzUmVzdGFydCgkaXNMb2FkZWQpCiAgICB7CiAgICAgICAgcmV0dXJuICRpc0xvYWRlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEFsbG93cyBhbiBleHRlbmRpbmcgY2xhc3MgdG8gYWNjZXNzIHRoZSB0bXBJbmkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZXN0YXJ0KCRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5kb1Jlc3RhcnQoJGNvbW1hbmQpOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIHJlc3RhcnRlZCBjb21tYW5kIHRoZW4gZGVsZXRlcyB0aGUgdG1wIGluaQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb1Jlc3RhcnQoJGNvbW1hbmQpCiAgICB7CiAgICAgICAgJHRoaXMtPnRyeUVuYWJsZVNpZ25hbHMoKTsKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6UkVTVEFSVElORywgJGNvbW1hbmQpOwoKICAgICAgICAvLyBQcmVmZXIgcHJvY19vcGVuIHRvIGtlZXAgZmRzIGludGFjdCwgYmVjYXVzZSBwYXNzdGhydSBwaXBlcyB0byBzdGRvdXQKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSkgewogICAgICAgICAgICBpZiAoZGVmaW5lZCgnUEhQX1dJTkRPV1NfVkVSU0lPTl9CVUlMRCcpICYmIFBIUF9WRVJTSU9OX0lEIDwgODAwMDApIHsKICAgICAgICAgICAgICAgICRjb21tYW5kID0gJyInLiRjb21tYW5kLiciJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcHJvY2VzcyA9IHByb2Nfb3BlbigkY29tbWFuZCwgYXJyYXkoKSwgJHBpcGVzKTsKICAgICAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRwcm9jZXNzKSkgewogICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gcHJvY19jbG9zZSgkcHJvY2Vzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXNzdGhydSgkY29tbWFuZCwgJGV4aXRDb2RlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJGV4aXRDb2RlKSkgewogICAgICAgICAgICAvLyBVbmxpa2VseSB0aGF0IHRoZSBkZWZhdWx0IHNoZWxsIGNhbm5vdCBiZSBpbnZva2VkCiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpFUlJPUiwgJ1VuYWJsZSB0byByZXN0YXJ0IHByb2Nlc3MnKTsKICAgICAgICAgICAgJGV4aXRDb2RlID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6OklORk8sICdSZXN0YXJ0ZWQgcHJvY2VzcyBleGl0ZWQgJy4kZXhpdENvZGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5kZWJ1ZyA9PT0gJzInKSB7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpJTkZPLCAnVGVtcCBpbmkgc2F2ZWQ6ICcuJHRoaXMtPnRtcEluaSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgQHVubGluaygkdGhpcy0+dG1wSW5pKTsKICAgICAgICB9CgogICAgICAgIGV4aXQoJGV4aXRDb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBldmVyeXRoaW5nIHdhcyB3cml0dGVuIGZvciB0aGUgcmVzdGFydAogICAgICoKICAgICAqIElmIGFueSBvZiB0aGUgZm9sbG93aW5nIGZhaWxzIChob3dldmVyIHVubGlrZWx5KSB3ZSBtdXN0IHJldHVybiBmYWxzZSB0bwogICAgICogc3RvcCBwb3RlbnRpYWwgcmVjdXJzaW9uOgogICAgICogICAtIHRtcCBpbmkgZmlsZSBjcmVhdGlvbgogICAgICogICAtIGVudmlyb25tZW50IHZhcmlhYmxlIGNyZWF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcHJlcGFyZVJlc3RhcnQoKQogICAgewogICAgICAgICRlcnJvciA9ICcnOwogICAgICAgICRpbmlGaWxlcyA9IHNlbGY6OmdldEFsbEluaUZpbGVzKCk7CiAgICAgICAgJHNjYW5uZWRJbmlzID0gY291bnQoJGluaUZpbGVzKSA+IDE7CiAgICAgICAgJHRtcERpciA9IHN5c19nZXRfdGVtcF9kaXIoKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+Y2xpKSB7CiAgICAgICAgICAgICRlcnJvciA9ICdVbnN1cHBvcnRlZCBTQVBJOiAnLlBIUF9TQVBJOwogICAgICAgIH0gZWxzZWlmICghZGVmaW5lZCgnUEhQX0JJTkFSWScpKSB7CiAgICAgICAgICAgICRlcnJvciA9ICdQSFAgdmVyc2lvbiBpcyB0b28gb2xkOiAnLlBIUF9WRVJTSU9OOwogICAgICAgIH0gZWxzZWlmICghJHRoaXMtPmNoZWNrQ29uZmlndXJhdGlvbigkaW5mbykpIHsKICAgICAgICAgICAgJGVycm9yID0gJGluZm87CiAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+Y2hlY2tTY2FuRGlyQ29uZmlnKCkpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1BIUCB2ZXJzaW9uIGRvZXMgbm90IHJlcG9ydCBzY2FubmVkIGluaXM6ICcuUEhQX1ZFUlNJT047CiAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+Y2hlY2tNYWluU2NyaXB0KCkpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1VuYWJsZSB0byBhY2Nlc3MgbWFpbiBzY3JpcHQ6ICcuJHRoaXMtPnNjcmlwdDsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT53cml0ZVRtcEluaSgkaW5pRmlsZXMsICR0bXBEaXIsICRlcnJvcikpIHsKICAgICAgICAgICAgJGVycm9yID0gJGVycm9yID86ICdVbmFibGUgdG8gY3JlYXRlIHRlbXAgaW5pIGZpbGUgYXQ6ICcuJHRtcERpcjsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5zZXRFbnZpcm9ubWVudCgkc2Nhbm5lZEluaXMsICRpbmlGaWxlcykpIHsKICAgICAgICAgICAgJGVycm9yID0gJ1VuYWJsZSB0byBzZXQgZW52aXJvbm1lbnQgdmFyaWFibGVzJzsKICAgICAgICB9CgogICAgICAgIGlmICgkZXJyb3IpIHsKICAgICAgICAgICAgJHRoaXMtPm5vdGlmeShTdGF0dXM6OkVSUk9SLCAkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGVtcHR5KCRlcnJvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHRtcCBpbmkgZmlsZSB3YXMgd3JpdHRlbgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5pRmlsZXMgQWxsIGluaSBmaWxlcyB1c2VkIGluIHRoZSBjdXJyZW50IHByb2Nlc3MKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRtcERpciBUaGUgc3lzdGVtIHRlbXBvcmFyeSBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVycm9yIFNldCBieSBtZXRob2QgaWYgaW5pIGZpbGUgY2Fubm90IGJlIHJlYWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZVRtcEluaShhcnJheSAkaW5pRmlsZXMsICR0bXBEaXIsICYkZXJyb3IpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+dG1wSW5pID0gQHRlbXBuYW0oJHRtcERpciwgJycpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vICRpbmlGaWxlcyBoYXMgYXQgbGVhc3Qgb25lIGl0ZW0gYW5kIGl0IG1heSBiZSBlbXB0eQogICAgICAgIGlmIChlbXB0eSgkaW5pRmlsZXNbMF0pKSB7CiAgICAgICAgICAgIGFycmF5X3NoaWZ0KCRpbmlGaWxlcyk7CiAgICAgICAgfQoKICAgICAgICAkY29udGVudCA9ICcnOwogICAgICAgICRyZWdleCA9ICcvXlxzKih6ZW5kX2V4dGVuc2lvblxzKj0uKnhkZWJ1Zy4qKSQvbWknOwoKICAgICAgICBmb3JlYWNoICgkaW5pRmlsZXMgYXMgJGZpbGUpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGluYWNjZXNzaWJsZSBpbmkgZmlsZXMKICAgICAgICAgICAgaWYgKCgkZGF0YSA9IEBmaWxlX2dldF9jb250ZW50cygkZmlsZSkpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJGVycm9yID0gJ1VuYWJsZSB0byByZWFkIGluaTogJy4kZmlsZTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY29udGVudCAuPSBwcmVnX3JlcGxhY2UoJHJlZ2V4LCAnOyQxJywgJGRhdGEpLlBIUF9FT0w7CiAgICAgICAgfQoKICAgICAgICAvLyBNZXJnZSBsb2FkZWQgc2V0dGluZ3MgaW50byBvdXIgaW5pIGNvbnRlbnQsIGlmIGl0IGlzIHZhbGlkCiAgICAgICAgaWYgKCRjb25maWcgPSBwYXJzZV9pbmlfc3RyaW5nKCRjb250ZW50KSkgewogICAgICAgICAgICAkbG9hZGVkID0gaW5pX2dldF9hbGwobnVsbCwgZmFsc2UpOwogICAgICAgICAgICAkY29udGVudCAuPSAkdGhpcy0+bWVyZ2VMb2FkZWRDb25maWcoJGxvYWRlZCwgJGNvbmZpZyk7CiAgICAgICAgfQoKICAgICAgICAvLyBXb3JrLWFyb3VuZCBmb3IgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD03NTkzMgogICAgICAgICRjb250ZW50IC49ICdvcGNhY2hlLmVuYWJsZV9jbGk9MCcuUEhQX0VPTDsKCiAgICAgICAgcmV0dXJuIEBmaWxlX3B1dF9jb250ZW50cygkdGhpcy0+dG1wSW5pLCAkY29udGVudCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZXN0YXJ0IGNvbW1hbmQgbGluZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q29tbWFuZCgpCiAgICB7CiAgICAgICAgJHBocCA9IGFycmF5KFBIUF9CSU5BUlkpOwogICAgICAgICRhcmdzID0gYXJyYXlfc2xpY2UoJF9TRVJWRVJbJ2FyZ3YnXSwgMSk7CgogICAgICAgIGlmICghJHRoaXMtPnBlcnNpc3RlbnQpIHsKICAgICAgICAgICAgLy8gVXNlIGNvbW1hbmQtbGluZSBvcHRpb25zCiAgICAgICAgICAgIGFycmF5X3B1c2goJHBocCwgJy1uJywgJy1jJywgJHRoaXMtPnRtcEluaSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZGVmaW5lZCgnU1RET1VUJykgJiYgUHJvY2Vzczo6c3VwcG9ydHNDb2xvcihTVERPVVQpKSB7CiAgICAgICAgICAgICRhcmdzID0gUHJvY2Vzczo6YWRkQ29sb3JPcHRpb24oJGFyZ3MsICR0aGlzLT5jb2xvck9wdGlvbik7CiAgICAgICAgfQoKICAgICAgICAkYXJncyA9IGFycmF5X21lcmdlKCRwaHAsIGFycmF5KCR0aGlzLT5zY3JpcHQpLCAkYXJncyk7CgogICAgICAgICRjbWQgPSBQcm9jZXNzOjplc2NhcGUoYXJyYXlfc2hpZnQoJGFyZ3MpLCB0cnVlLCB0cnVlKTsKICAgICAgICBmb3JlYWNoICgkYXJncyBhcyAkYXJnKSB7CiAgICAgICAgICAgICRjbWQgLj0gJyAnLlByb2Nlc3M6OmVzY2FwZSgkYXJnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY21kOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSByZXN0YXJ0IGVudmlyb25tZW50IHZhcmlhYmxlcyB3ZXJlIHNldAogICAgICoKICAgICAqIE5vIG5lZWQgdG8gdXBkYXRlICRfU0VSVkVSIHNpbmNlIHRoaXMgaXMgc2V0IGluIHRoZSByZXN0YXJ0ZWQgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkc2Nhbm5lZEluaXMgV2hldGhlciB0aGVyZSB3ZXJlIHNjYW5uZWQgaW5pIGZpbGVzCiAgICAgKiBAcGFyYW0gYXJyYXkgJGluaUZpbGVzIEFsbCBpbmkgZmlsZXMgdXNlZCBpbiB0aGUgY3VycmVudCBwcm9jZXNzCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0RW52aXJvbm1lbnQoJHNjYW5uZWRJbmlzLCBhcnJheSAkaW5pRmlsZXMpCiAgICB7CiAgICAgICAgJHNjYW5EaXIgPSBnZXRlbnYoJ1BIUF9JTklfU0NBTl9ESVInKTsKICAgICAgICAkcGhwcmMgPSBnZXRlbnYoJ1BIUFJDJyk7CgogICAgICAgIC8vIE1ha2Ugb3JpZ2luYWwgaW5pcyBhdmFpbGFibGUgdG8gcmVzdGFydGVkIHByb2Nlc3MKICAgICAgICBpZiAoIXB1dGVudigkdGhpcy0+ZW52T3JpZ2luYWxJbmlzLic9Jy5pbXBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkaW5pRmlsZXMpKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnBlcnNpc3RlbnQpIHsKICAgICAgICAgICAgLy8gVXNlIHRoZSBlbnZpcm9ubWVudCB0byBwZXJzaXN0IHRoZSBzZXR0aW5ncwogICAgICAgICAgICBpZiAoIXB1dGVudignUEhQX0lOSV9TQ0FOX0RJUj0nKSB8fCAhcHV0ZW52KCdQSFBSQz0nLiR0aGlzLT50bXBJbmkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEZsYWcgcmVzdGFydGVkIHByb2Nlc3MgYW5kIHNhdmUgdmFsdWVzIGZvciBpdCB0byB1c2UKICAgICAgICAkZW52QXJncyA9IGFycmF5KAogICAgICAgICAgICBzZWxmOjpSRVNUQVJUX0lELAogICAgICAgICAgICAkdGhpcy0+bG9hZGVkLAogICAgICAgICAgICAoaW50KSAkc2Nhbm5lZEluaXMsCiAgICAgICAgICAgIGZhbHNlID09PSAkc2NhbkRpciA/ICcqJyA6ICRzY2FuRGlyLAogICAgICAgICAgICBmYWxzZSA9PT0gJHBocHJjID8gJyonIDogJHBocHJjLAogICAgICAgICk7CgogICAgICAgIHJldHVybiBwdXRlbnYoJHRoaXMtPmVudkFsbG93WGRlYnVnLic9Jy5pbXBsb2RlKCd8JywgJGVudkFyZ3MpKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvZ3Mgc3RhdHVzIG1lc3NhZ2VzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3AgU3RhdHVzIGhhbmRsZXIgY29uc3RhbnQKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkZGF0YSBPcHRpb25hbCBkYXRhCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm90aWZ5KCRvcCwgJGRhdGEgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5zdGF0dXNXcml0ZXItPnJlcG9ydCgkb3AsICRkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgZGVmYXVsdCwgY2hhbmdlZCBhbmQgY29tbWFuZC1saW5lIGluaSBzZXR0aW5ncwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkbG9hZGVkQ29uZmlnIEFsbCBjdXJyZW50IGluaSBzZXR0aW5ncwogICAgICogQHBhcmFtIGFycmF5ICRpbmlDb25maWcgU2V0dGluZ3MgZnJvbSB1c2VyIGluaSBmaWxlcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbWVyZ2VMb2FkZWRDb25maWcoYXJyYXkgJGxvYWRlZENvbmZpZywgYXJyYXkgJGluaUNvbmZpZykKICAgIHsKICAgICAgICAkY29udGVudCA9ICcnOwoKICAgICAgICBmb3JlYWNoICgkbG9hZGVkQ29uZmlnIGFzICRuYW1lID0+ICR2YWx1ZSkgewogICAgICAgICAgICAvLyBWYWx1ZSB3aWxsIGVpdGhlciBiZSBudWxsLCBzdHJpbmcgb3IgYXJyYXkgKEhIVk0gb25seSkKICAgICAgICAgICAgaWYgKCFpc19zdHJpbmcoJHZhbHVlKQogICAgICAgICAgICAgICAgfHwgc3RycG9zKCRuYW1lLCAneGRlYnVnJykgPT09IDAKICAgICAgICAgICAgICAgIHx8ICRuYW1lID09PSAnYXBjLm1tYXBfZmlsZV9tYXNrJykgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJGluaUNvbmZpZ1skbmFtZV0pIHx8ICRpbmlDb25maWdbJG5hbWVdICE9PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIC8vIERvdWJsZS1xdW90ZSBlc2NhcGUgZWFjaCB2YWx1ZQogICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gJG5hbWUuJz0iJy5hZGRjc2xhc2hlcygkdmFsdWUsICdcXCInKS4nIicuUEhQX0VPTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb250ZW50OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzY3JpcHQgbmFtZSBjYW4gYmUgdXNlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrTWFpblNjcmlwdCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5zY3JpcHQpIHsKICAgICAgICAgICAgLy8gQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gc2V0IC0tIGZvciBzdGFuZGFyZCBpbnB1dAogICAgICAgICAgICByZXR1cm4gZmlsZV9leGlzdHMoJHRoaXMtPnNjcmlwdCkgfHwgJy0tJyA9PT0gJHRoaXMtPnNjcmlwdDsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+c2NyaXB0ID0gJF9TRVJWRVJbJ2FyZ3YnXVswXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBVc2UgYSBiYWNrdHJhY2UgdG8gcmVzb2x2ZSBQaGFyIGFuZCBjaGRpciBpc3N1ZXMKICAgICAgICAkb3B0aW9ucyA9IFBIUF9WRVJTSU9OX0lEID49IDUwMzA2ID8gREVCVUdfQkFDS1RSQUNFX0lHTk9SRV9BUkdTIDogZmFsc2U7CiAgICAgICAgJHRyYWNlID0gZGVidWdfYmFja3RyYWNlKCRvcHRpb25zKTsKCiAgICAgICAgaWYgKCgkbWFpbiA9IGVuZCgkdHJhY2UpKSAmJiBpc3NldCgkbWFpblsnZmlsZSddKSkgewogICAgICAgICAgICByZXR1cm4gZmlsZV9leGlzdHMoJHRoaXMtPnNjcmlwdCA9ICRtYWluWydmaWxlJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyByZXN0YXJ0IHNldHRpbmdzIHRvIHRoZSBlbnZpcm9ubWVudAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkZW52QXJncwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldEVudlJlc3RhcnRTZXR0aW5ncygkZW52QXJncykKICAgIHsKICAgICAgICAkc2V0dGluZ3MgPSBhcnJheSgKICAgICAgICAgICAgcGhwX2luaV9sb2FkZWRfZmlsZSgpLAogICAgICAgICAgICAkZW52QXJnc1syXSwKICAgICAgICAgICAgJGVudkFyZ3NbM10sCiAgICAgICAgICAgICRlbnZBcmdzWzRdLAogICAgICAgICAgICBnZXRlbnYoJHRoaXMtPmVudk9yaWdpbmFsSW5pcyksCiAgICAgICAgICAgIHNlbGY6OiRza2lwcGVkLAogICAgICAgICk7CgogICAgICAgIFByb2Nlc3M6OnNldEVudihzZWxmOjpSRVNUQVJUX1NFVFRJTkdTLCBpbXBsb2RlKCd8JywgJHNldHRpbmdzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTeW5jcyBzZXR0aW5ncyBhbmQgdGhlIGVudmlyb25tZW50IGlmIGNhbGxlZCB3aXRoIGV4aXN0aW5nIHNldHRpbmdzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRzZXR0aW5ncwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN5bmNTZXR0aW5ncyhhcnJheSAkc2V0dGluZ3MpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSBnZXRlbnYoJHRoaXMtPmVudk9yaWdpbmFsSW5pcykpIHsKICAgICAgICAgICAgLy8gQ2FsbGVkIGJ5IGFub3RoZXIgYXBwLCBzbyBtYWtlIG9yaWdpbmFsIGluaXMgYXZhaWxhYmxlCiAgICAgICAgICAgIFByb2Nlc3M6OnNldEVudigkdGhpcy0+ZW52T3JpZ2luYWxJbmlzLCBpbXBsb2RlKFBBVEhfU0VQQVJBVE9SLCAkc2V0dGluZ3NbJ2luaXMnXSkpOwogICAgICAgIH0KCiAgICAgICAgc2VsZjo6JHNraXBwZWQgPSAkc2V0dGluZ3NbJ3NraXBwZWQnXTsKICAgICAgICAkdGhpcy0+bm90aWZ5KFN0YXR1czo6SU5GTywgJ1Byb2Nlc3MgY2FsbGVkIHdpdGggZXhpc3RpbmcgcmVzdGFydCBzZXR0aW5ncycpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBzY2FubmVkIGluaXMgYW5kIFBIUCBpcyBhYmxlIHRvIHJlcG9ydCB0aGVtCiAgICAgKgogICAgICogcGhwX2luaV9zY2FubmVkX2ZpbGVzIHdpbGwgZmFpbCB3aGVuIFBIUF9DT05GSUdfRklMRV9TQ0FOX0RJUiBpcyBlbXB0eS4KICAgICAqIEZpeGVkIGluIDcuMS4xMyBhbmQgNy4yLjEKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja1NjYW5EaXJDb25maWcoKQogICAgewogICAgICAgIHJldHVybiAhKGdldGVudignUEhQX0lOSV9TQ0FOX0RJUicpCiAgICAgICAgICAgICYmICFQSFBfQ09ORklHX0ZJTEVfU0NBTl9ESVIKICAgICAgICAgICAgJiYgKFBIUF9WRVJTSU9OX0lEIDwgNzAxMTMKICAgICAgICAgICAgfHwgUEhQX1ZFUlNJT05fSUQgPT09IDcwMjAwKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgYXJlIG5vIGtub3duIGNvbmZpZ3VyYXRpb24gaXNzdWVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaW5mbyBTZXQgYnkgbWV0aG9kCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0NvbmZpZ3VyYXRpb24oJiRpbmZvKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSAmJiAhZnVuY3Rpb25fZXhpc3RzKCdwYXNzdGhydScpKSB7CiAgICAgICAgICAgICRpbmZvID0gJ2V4ZWN1dGlvbiBmdW5jdGlvbnMgaGF2ZSBiZWVuIGRpc2FibGVkIChwcm9jX29wZW4gb3IgcGFzc3RocnUgcmVxdWlyZWQpJzsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ3VvcHonKSAmJiAhaW5pX2dldCgndW9wei5kaXNhYmxlJykpIHsKICAgICAgICAgICAgLy8gdW9weiB3b3JrcyBhdCBvcGNvZGUgbGV2ZWwgYW5kIGRpc2FibGVzIGV4aXQgY2FsbHMKICAgICAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygndW9wel9hbGxvd19leGl0JykpIHsKICAgICAgICAgICAgICAgIEB1b3B6X2FsbG93X2V4aXQodHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaW5mbyA9ICd1b3B6IGV4dGVuc2lvbiBpcyBub3QgY29tcGF0aWJsZSc7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlcyBhc3luYyBzaWduYWxzIGFuZCBjb250cm9sIGludGVycnVwdHMgaW4gdGhlIHJlc3RhcnRlZCBwcm9jZXNzCiAgICAgKgogICAgICogQXZhaWxhYmxlIG9uIFVuaXggUEhQIDcuMSsgd2l0aCB0aGUgcGNudGwgZXh0ZW5zaW9uIGFuZCBXaW5kb3dzIFBIUCA3LjQrLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRyeUVuYWJsZVNpZ25hbHMoKQogICAgewogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3BjbnRsX2FzeW5jX3NpZ25hbHMnKSAmJiBmdW5jdGlvbl9leGlzdHMoJ3BjbnRsX3NpZ25hbCcpKSB7CiAgICAgICAgICAgIHBjbnRsX2FzeW5jX3NpZ25hbHModHJ1ZSk7CiAgICAgICAgICAgICRtZXNzYWdlID0gJ0FzeW5jIHNpZ25hbHMgZW5hYmxlZCc7CgogICAgICAgICAgICBpZiAoIXNlbGY6OiRpblJlc3RhcnQpIHsKICAgICAgICAgICAgICAgIC8vIFJlc3RhcnRpbmcsIHNvIGlnbm9yZSBTSUdJTlQgaW4gcGFyZW50CiAgICAgICAgICAgICAgICBwY250bF9zaWduYWwoU0lHSU5ULCBTSUdfSUdOKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICcgKFNJR0lOVCA9IFNJR19JR04pJzsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2ludChwY250bF9zaWduYWxfZ2V0X2hhbmRsZXIoU0lHSU5UKSkpIHsKICAgICAgICAgICAgICAgIC8vIFJlc3RhcnRlZCwgbm8gaGFuZGxlciBzZXQgc28gZm9yY2UgZGVmYXVsdCBhY3Rpb24KICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIFNJR19ERkwpOwogICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJyAoU0lHSU5UID0gU0lHX0RGTCknOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpJTkZPLCAkbWVzc2FnZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXNlbGY6OiRpblJlc3RhcnQgJiYgZnVuY3Rpb25fZXhpc3RzKCdzYXBpX3dpbmRvd3Nfc2V0X2N0cmxfaGFuZGxlcicpKSB7CiAgICAgICAgICAgIC8vIFJlc3RhcnRpbmcsIHNvIHNldCBhIGhhbmRsZXIgdG8gaWdub3JlIENUUkwgZXZlbnRzIGluIHRoZSBwYXJlbnQuCiAgICAgICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGF0IENUUkwrQyBldmVudHMgd2lsbCBiZSBhdmFpbGFibGUgaW4gdGhlIGNoaWxkCiAgICAgICAgICAgIC8vIHByb2Nlc3Mgd2l0aG91dCBoYXZpbmcgdG8gZW5hYmxlIHRoZW0gdGhlcmUsIHdoaWNoIGlzIHVucmVsaWFibGUuCiAgICAgICAgICAgIHNhcGlfd2luZG93c19zZXRfY3RybF9oYW5kbGVyKGZ1bmN0aW9uICgkZXZ0KSB7fSk7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnkoU3RhdHVzOjpJTkZPLCAnQ1RSTCBzaWduYWxzIHN1cHByZXNzZWQnKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFhkZWJ1Z0hhbmRsZXI7Cgp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CnVzZSBQc3JcTG9nXExvZ0xldmVsOwoKLyoqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgU3RhdHVzCnsKICAgIGNvbnN0IEVOVl9SRVNUQVJUID0gJ1hERUJVR19IQU5ETEVSX1JFU1RBUlQnOwogICAgY29uc3QgQ0hFQ0sgPSAnQ2hlY2snOwogICAgY29uc3QgRVJST1IgPSAnRXJyb3InOwogICAgY29uc3QgSU5GTyA9ICdJbmZvJzsKICAgIGNvbnN0IE5PUkVTVEFSVCA9ICdOb1Jlc3RhcnQnOwogICAgY29uc3QgUkVTVEFSVCA9ICdSZXN0YXJ0JzsKICAgIGNvbnN0IFJFU1RBUlRJTkcgPSAnUmVzdGFydGluZyc7CiAgICBjb25zdCBSRVNUQVJURUQgPSAnUmVzdGFydGVkJzsKCiAgICBwcml2YXRlICRkZWJ1ZzsKICAgIHByaXZhdGUgJGVudkFsbG93WGRlYnVnOwogICAgcHJpdmF0ZSAkbG9hZGVkOwogICAgcHJpdmF0ZSAkbG9nZ2VyOwogICAgcHJpdmF0ZSAkdGltZTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZW52QWxsb3dYZGVidWcgUHJlZml4ZWQgX0FMTE9XX1hERUJVRyBuYW1lCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVidWcgV2hldGhlciBkZWJ1ZyBvdXRwdXQgaXMgcmVxdWlyZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRlbnZBbGxvd1hkZWJ1ZywgJGRlYnVnKQogICAgewogICAgICAgICRzdGFydCA9IGdldGVudihzZWxmOjpFTlZfUkVTVEFSVCk7CiAgICAgICAgUHJvY2Vzczo6c2V0RW52KHNlbGY6OkVOVl9SRVNUQVJUKTsKICAgICAgICAkdGhpcy0+dGltZSA9ICRzdGFydCA/IHJvdW5kKChtaWNyb3RpbWUodHJ1ZSkgLSAkc3RhcnQpICogMTAwMCkgOiAwOwoKICAgICAgICAkdGhpcy0+ZW52QWxsb3dYZGVidWcgPSAkZW52QWxsb3dYZGVidWc7CiAgICAgICAgJHRoaXMtPmRlYnVnID0gJGRlYnVnICYmIGRlZmluZWQoJ1NUREVSUicpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2dnZXIoTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZ2dlciA9ICRsb2dnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxscyBhIGhhbmRsZXIgbWV0aG9kIHRvIHJlcG9ydCBhIG1lc3NhZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcCBUaGUgaGFuZGxlciBjb25zdGFudAogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRkYXRhIERhdGEgcmVxdWlyZWQgYnkgdGhlIGhhbmRsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlcG9ydCgkb3AsICRkYXRhKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bG9nZ2VyIHx8ICR0aGlzLT5kZWJ1ZykgewogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYyhhcnJheSgkdGhpcywgJ3JlcG9ydCcuJG9wKSwgJGRhdGEpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE91dHB1dHMgYSBzdGF0dXMgbWVzc2FnZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxldmVsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3V0cHV0KCR0ZXh0LCAkbGV2ZWwgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bG9nZ2VyKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2dnZXItPmxvZygkbGV2ZWwgPzogTG9nTGV2ZWw6OkRFQlVHLCAkdGV4dCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmRlYnVnKSB7CiAgICAgICAgICAgIGZ3cml0ZShTVERFUlIsIHNwcmludGYoJ3hkZWJ1Zy1oYW5kbGVyWyVkXSAlcycsIGdldG15cGlkKCksICR0ZXh0LlBIUF9FT0wpKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXBvcnRDaGVjaygkbG9hZGVkKQogICAgewogICAgICAgICR0aGlzLT5sb2FkZWQgPSAkbG9hZGVkOwogICAgICAgICR0aGlzLT5vdXRwdXQoJ0NoZWNraW5nICcuJHRoaXMtPmVudkFsbG93WGRlYnVnKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydEVycm9yKCRlcnJvcikKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0KHNwcmludGYoJ05vIHJlc3RhcnQgKCVzKScsICRlcnJvciksIExvZ0xldmVsOjpXQVJOSU5HKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydEluZm8oJGluZm8pCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dCgkaW5mbyk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXBvcnROb1Jlc3RhcnQoKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQoJHRoaXMtPmdldExvYWRlZE1lc3NhZ2UoKSk7CgogICAgICAgIGlmICgkdGhpcy0+bG9hZGVkKSB7CiAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignTm8gcmVzdGFydCAoJXMpJywgJHRoaXMtPmdldEVudkFsbG93KCkpOwogICAgICAgICAgICBpZiAoIWdldGVudigkdGhpcy0+ZW52QWxsb3dYZGVidWcpKSB7CiAgICAgICAgICAgICAgICAkdGV4dCAuPSAnIEFsbG93ZWQgYnkgYXBwbGljYXRpb24nOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcG9ydFJlc3RhcnQoKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQoJHRoaXMtPmdldExvYWRlZE1lc3NhZ2UoKSk7CiAgICAgICAgUHJvY2Vzczo6c2V0RW52KHNlbGY6OkVOVl9SRVNUQVJULCAoc3RyaW5nKSBtaWNyb3RpbWUodHJ1ZSkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVwb3J0UmVzdGFydGVkKCkKICAgIHsKICAgICAgICAkbG9hZGVkID0gJHRoaXMtPmdldExvYWRlZE1lc3NhZ2UoKTsKICAgICAgICAkdGV4dCA9IHNwcmludGYoJ1Jlc3RhcnRlZCAoJWQgbXMpLiAlcycsICR0aGlzLT50aW1lLCAkbG9hZGVkKTsKICAgICAgICAkbGV2ZWwgPSAkdGhpcy0+bG9hZGVkID8gTG9nTGV2ZWw6OldBUk5JTkcgOiBudWxsOwogICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQsICRsZXZlbCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXBvcnRSZXN0YXJ0aW5nKCRjb21tYW5kKQogICAgewogICAgICAgICR0ZXh0ID0gc3ByaW50ZignUHJvY2VzcyByZXN0YXJ0aW5nICglcyknLCAkdGhpcy0+Z2V0RW52QWxsb3coKSk7CiAgICAgICAgJHRoaXMtPm91dHB1dCgkdGV4dCk7CiAgICAgICAgJHRleHQgPSAnUnVubmluZyAnLiRjb21tYW5kOwogICAgICAgICR0aGlzLT5vdXRwdXQoJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgX0FMTE9XX1hERUJVRyBlbnZpcm9ubWVudCB2YXJpYWJsZSBhcyBuYW1lPXZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRFbnZBbGxvdygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lbnZBbGxvd1hkZWJ1Zy4nPScuZ2V0ZW52KCR0aGlzLT5lbnZBbGxvd1hkZWJ1Zyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBYZGVidWcgc3RhdHVzIGFuZCB2ZXJzaW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRMb2FkZWRNZXNzYWdlKCkKICAgIHsKICAgICAgICAkbG9hZGVkID0gJHRoaXMtPmxvYWRlZCA/IHNwcmludGYoJ2xvYWRlZCAoJXMpJywgJHRoaXMtPmxvYWRlZCkgOiAnbm90IGxvYWRlZCc7CiAgICAgICAgcmV0dXJuICdUaGUgWGRlYnVnIGV4dGVuc2lvbiBpcyAnLiRsb2FkZWQ7CiAgICB9Cn0KPD9waHAKCgoKCgoKCgoKCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcVmVyc2lvblBhcnNlcjsKCgoKCgoKCgpjbGFzcyBJbnN0YWxsZWRWZXJzaW9ucwp7CnByaXZhdGUgc3RhdGljICRpbnN0YWxsZWQgPSBhcnJheSAoCiAgJ3Jvb3QnID0+IAogIGFycmF5ICgKICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ2Rldi1yZWxlYXNlLTItNS0wJywKICAgICd2ZXJzaW9uJyA9PiAnZGV2LXJlbGVhc2UtMi01LTAnLAogICAgJ2FsaWFzZXMnID0+IAogICAgYXJyYXkgKAogICAgKSwKICAgICdyZWZlcmVuY2UnID0+ICc1MDA1ODBjYzc0MGU5MmEyYjkyZGMyNmVlZWM5ZjA0NmExYWNhZTZkJywKICAgICduYW1lJyA9PiAnd3AtY2xpL3dwLWNsaS1idW5kbGUnLAogICksCiAgJ3ZlcnNpb25zJyA9PiAKICBhcnJheSAoCiAgICAnY29tcG9zZXIvY2EtYnVuZGxlJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4yLjknLAogICAgICAndmVyc2lvbicgPT4gJzEuMi45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzc4YTBlMjg4ZmRjZWJmOTJhYTIzMThhOGQzNjU2MTY4ZGE2YWMxYTUnLAogICAgKSwKICAgICdjb21wb3Nlci9jb21wb3NlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzIuMC4xMycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEzLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzk4NmU4Yjg2YjdiNTcwNjMyYWQwYTkwNWMzNzI2YzMzZGQ0YzBlZmInLAogICAgKSwKICAgICdjb21wb3Nlci9tZXRhZGF0YS1taW5pZmllcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuMC4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjAuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdjNTQ5ZDIzODI5NTM2ZjBkMGU5ODRhYWFiYmYwMmFmOTFmNDQzMjA3JywKICAgICksCiAgICAnY29tcG9zZXIvc2VtdmVyJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMy4yLjQnLAogICAgICAndmVyc2lvbicgPT4gJzMuMi40LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2EwMmZkZjkzMGEzYzFjM2VkM2E0OWI1ZjYzODU5YzBjMjBlMTA0NjQnLAogICAgKSwKICAgICdjb21wb3Nlci9zcGR4LWxpY2Vuc2VzJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS41LjUnLAogICAgICAndmVyc2lvbicgPT4gJzEuNS41LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2RlMzAzMjhhN2FmODY4MGVmZGMwM2UzOTZhYWQyNGJlZmQ1MTMyMDAnLAogICAgKSwKICAgICdjb21wb3Nlci94ZGVidWctaGFuZGxlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuNC42JywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjQuNi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdmMjdlMDZjZDk2NzU4MDFkZjQ0MWIzNjU2NTY5YjMyOGUwNGFhMzdjJywKICAgICksCiAgICAnZ2V0dGV4dC9nZXR0ZXh0JyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjQuOC40JywKICAgICAgJ3ZlcnNpb24nID0+ICc0LjguNC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc1OGJjMGY3ZjM3ZTc4ZWZiMGY5NzU4ZjkzZDRhMGY2NjlmMGY4NGExJywKICAgICksCiAgICAnZ2V0dGV4dC9sYW5ndWFnZXMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcyLjYuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi42LjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnMzhlYTA0ODJmNjQ5ZTA4MDJlNDc1ZjBlZDE5ZmE5OTNiY2I3YTYxOCcsCiAgICApLAogICAgJ2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICc1LjIuMTAnLAogICAgICAndmVyc2lvbicgPT4gJzUuMi4xMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyYmE5YzhjODYyZWNkNTUxMGVkMTZjNjM0MGFhOWY2ZWFkYjRmMzFiJywKICAgICksCiAgICAnbWNrODkvcGVhc3QnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS4xMi4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjEyLjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnODMzYmU3YTI5NDYyN2E4YzViMWM0ODJjYmY0ODlmNzNiZjliODA4NicsCiAgICApLAogICAgJ211c3RhY2hlL211c3RhY2hlJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMTMuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xMy4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U5NWM1YTAwOGMyM2QzMTUxZDU5ZWE3MjQ4NGQ0ZjcyMDQ5YWI3ZjQnLAogICAgKSwKICAgICduYi9veHltZWwnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MC4xLjAnLAogICAgICAndmVyc2lvbicgPT4gJzAuMS4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2NiZTYyNmVmNTVkNWM0Y2M5YjVlNmUzOTA0YjM5NTg2MWVhNzZlM2MnLAogICAgKSwKICAgICdwc3IvbG9nJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4xLjQnLAogICAgICAndmVyc2lvbicgPT4gJzEuMS40LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2Q0OTY5NWI5MDljM2I3NjI4YjYyODlkYjU0NzlhMWMyMDQ2MDFmMTEnLAogICAgKSwKICAgICdwc3IvbG9nLWltcGxlbWVudGF0aW9uJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3Byb3ZpZGVkJyA9PiAKICAgICAgYXJyYXkgKAogICAgICAgIDAgPT4gJzEuMCcsCiAgICAgICksCiAgICApLAogICAgJ3JlYWN0L3Byb21pc2UnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi44LjAnLAogICAgICAndmVyc2lvbicgPT4gJzIuOC4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YzY2ZmOTZhMTk3MzY3MTQ1MjRjYTBkZDFkNDEzMGRlNzNkYmJiYzQnLAogICAgKSwKICAgICdybWNjdWUvcmVxdWVzdHMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS44LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuOC4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2FmYmU0NzkwZTRkZWYwMzU4MWM0YTA5NjNhMWU4YWEwMWY2MDMwZjEnLAogICAgKSwKICAgICdzZWxkL2pzb25saW50JyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS44LjMnLAogICAgICAndmVyc2lvbicgPT4gJzEuOC4zLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzlhZDZjZTc5YzM0MmZiZDQ0ZGYxMGVhOTU1MTFhMWIyNGRlZTViNTcnLAogICAgKSwKICAgICdzZWxkL3BoYXItdXRpbHMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcxLjEuMScsCiAgICAgICd2ZXJzaW9uJyA9PiAnMS4xLjEuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnODY3NGIxZDg0ZmZiNDdjYzU5YTEwMWY1ZDVhM2I2MWU4N2QyMzc5NicsCiAgICApLAogICAgJ3N5bWZvbnkvY29uc29sZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhMTBiMWRhNmZjOTMwODBjMTgwYmJhNzIxOWI1ZmY1Yjc1MThmZTgxJywKICAgICksCiAgICAnc3ltZm9ueS9kZWJ1ZycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhYjQyODg5ZGU1N2ZkZmNmY2MwNzU5YWIxMDJlMmZkNGVhNzJkY2FlJywKICAgICksCiAgICAnc3ltZm9ueS9maWxlc3lzdGVtJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U1OGQ3ODQxY2RkZmVkNmU4NDY4MjkwNDBkY2EyY2NhMGViYmJiYjMnLAogICAgKSwKICAgICdzeW1mb255L2ZpbmRlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdiNmI2YWQzZGIzZWRiMWI0YjFjMTg5NmIxOTc1ZmI2ODQ5OTRkZTZlJywKICAgICksCiAgICAnc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjE5LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuMTkuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhZWQ1OTY5MTNiNzBmYWU1N2JlNTNkODZmYWEyZTllZjg1YTIyOTdiJywKICAgICksCiAgICAnc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjE5LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuMTkuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdiNWY3YjkzMmVlNmZhODAyZmM3OTJlYWJkNzdjNGM4ODA4NDUxN2NlJywKICAgICksCiAgICAnc3ltZm9ueS9wcm9jZXNzJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2I4NjQ4Y2YxZDVhZjEyYTQ0YTUxZDA3ZWY5YmY5ODA5MjFmMTVmY2EnLAogICAgKSwKICAgICd3cC1jbGkvY2FjaGUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYmY1ZDNkMzM1ZGU1ZjlkOTMxODA2ODJmMTA3YzIzOGE4M2M0YjAyYycsCiAgICApLAogICAgJ3dwLWNsaS9jaGVja3N1bS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcwZjU4YWY5MTRhNGFmMzAxOGNlODM0NDk4NjkzMDBkNjVkZjlmNjEzJywKICAgICksCiAgICAnd3AtY2xpL2NvbmZpZy1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc0NmIwOTZlYWUyYzExNmJlZDMwYzhkNjQ5ZjZlMmExZDRkYjAzNWMxJywKICAgICksCiAgICAnd3AtY2xpL2NvcmUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYjdmNDRmMDNhM2EzNTE0Nzk4Y2RhMjFiNjFhNDE4ZjA4YWVjZTMyNCcsCiAgICApLAogICAgJ3dwLWNsaS9jcm9uLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjgnLAogICAgICAndmVyc2lvbicgPT4gJzIuMC44LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YwZDQ5M2ZmNGQ0ZjIwZWU2ZDZmZDU0OTVkYTFiYzE3NjBmOWRhMTUnLAogICAgKSwKICAgICd3cC1jbGkvZGItY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMTMnLAogICAgICAndmVyc2lvbicgPT4gJzIuMC4xMy4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyNjliZjI2YTY2OTE1ZDY1MjZiMTAxNWY3Yzc1OWZmZTA0Mzg2YmY3JywKICAgICksCiAgICAnd3AtY2xpL2VtYmVkLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2VjNzRmM2YzNGNiOWMwMjhmZDM5ZWJmOGNjYTNhMTUwNGZkNTk5YmEnLAogICAgKSwKICAgICd3cC1jbGkvZW50aXR5LWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjAnLAogICAgICAndmVyc2lvbicgPT4gJzIuMS4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzliM2MwMzBkNWIwNTZmM2Y3Yjg4MzVlMTE3MTM5ZjkyNzk5MzQwYTknLAogICAgKSwKICAgICd3cC1jbGkvZXZhbC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdkY2RhMDIxOTRiZDBjYTc3M2NlMDNkZWM2MDkzYWMwZDI3MWY4OTc2JywKICAgICksCiAgICAnd3AtY2xpL2V4cG9ydC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdlOTRmNWY5ZTg0NzY4OTE5YWE2Y2QyMTkzZWIwYzhiOTk0ZTdmNGM5JywKICAgICksCiAgICAnd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc3YWQ0ZjljMGM5M2ExZWU3Mzc1MjFmODI1ZjE2MWQ0Yjc5YTQ2OTQ1JywKICAgICksCiAgICAnd3AtY2xpL2kxOG4tY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjIuOCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4yLjguMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnOGJjMjM0NjE3ZWRjNTMzNTkwYWMwZjQxMDgwMTY0YThkODVlYzljZScsCiAgICApLAogICAgJ3dwLWNsaS9pbXBvcnQtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNzVlNmQ0MjczYjRhOWRiZjUxMGQ2OWE0NGY5MzcxZWVlMGQwMTI5NCcsCiAgICApLAogICAgJ3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEwLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzRjMDJlZjQzMWUyODI1ZWFjN2IwMmU1Y2Y0ODA0YzQ3MTY3YjZiYWYnLAogICAgKSwKICAgICd3cC1jbGkvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC42JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuNi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyNmMxYzBhNzllZDExOTRjODYzY2I5NWZhMzY0YjRkYjc5MjlkN2NjJywKICAgICksCiAgICAnd3AtY2xpL21lZGlhLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjExJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTEuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnMTY1YTQ2MmUyMzRlNTVkYjIxNzRmOWYwZjZmYWI3MjA0MGU5YzUxMCcsCiAgICApLAogICAgJ3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcwLjYuMycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMC42LjMuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNmFhMGI0ZGE2OWNlOWU5YTJjODQwMmRhYjhkNDNjZjMyYzU4MWNjNycsCiAgICApLAogICAgJ3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjEnLAogICAgICAndmVyc2lvbicgPT4gJzIuMS4xLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzJlMzQ1ZGY2YzY3ZDRmOWI0YmY0MmNlMTJhN2ZhMDdiMmI0NDM5OWQnLAogICAgKSwKICAgICd3cC1jbGkvcGhwLWNsaS10b29scycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YwLjExLjEyJywKICAgICAgJ3ZlcnNpb24nID0+ICcwLjExLjEyLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U0NzJlMDg0ODlmNzUwNGQ5ZThjNWM1YTA1N2UxNDE5Y2QxYjJiM2UnLAogICAgKSwKICAgICd3cC1jbGkvcmV3cml0ZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc0NjgzNThlMDc5NDNhN2E4YmU3MGM5NWUyMGQ0NTQxMmQ4Mjg5OWFjJywKICAgICksCiAgICAnd3AtY2xpL3JvbGUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNzQ2MDU2NmZlYmU4MmIxNGMzNGIxMDVjNGM2MzI2ZDNlMjNmOTI5NScsCiAgICApLAogICAgJ3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xNCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjE0LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2NkZTQ0NTI0ZmQwNDk5YzAzNjRhNWFlM2E2ZGM0OTI3OTZlODBlMGEnLAogICAgKSwKICAgICd3cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMTInLAogICAgICAndmVyc2lvbicgPT4gJzIuMC4xMi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc3ZDkzYWJiZGZkMGMzMjM5MDJhYzIxZmMzNDE4NjA0MWJlNzQzZmQwJywKICAgICksCiAgICAnd3AtY2xpL3NlcnZlci1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyOTk3NmFlZjVjMmJkZjE1OWI4NzAwZWFiMjZiYWZjOTQzZjBiZTBjJywKICAgICksCiAgICAnd3AtY2xpL3NoZWxsLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YyN2IzNGE4N2I1MTVkYTY0NmQyZTcwMThhOGFiYzEyNTQ0MTZmZWMnLAogICAgKSwKICAgICd3cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYWQ0YmQ0ZTZiNmE1M2FmYTRiYTg2NjRhNmRkNjk1YmU2ZmViNjkyZScsCiAgICApLAogICAgJ3dwLWNsaS93aWRnZXQtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuNCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjQuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNWM3YjRlMTQ3Yjc3ZTNkNzY4YTlhMDM0NjkzZWJjN2JhMTk4MDcwNycsCiAgICApLAogICAgJ3dwLWNsaS93cC1jbGknID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICdkZXYtbWFzdGVyJywKICAgICAgJ3ZlcnNpb24nID0+ICdkZXYtbWFzdGVyJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICAgMCA9PiAnMi41LngtZGV2JywKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzBiY2YwYzU0ZjRkMzU2ODUyMTFkNDM1ZTI1MjE5Y2M3YWNiZTZkNDgnLAogICAgKSwKICAgICd3cC1jbGkvd3AtY2xpLWJ1bmRsZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ2Rldi1yZWxlYXNlLTItNS0wJywKICAgICAgJ3ZlcnNpb24nID0+ICdkZXYtcmVsZWFzZS0yLTUtMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNTAwNTgwY2M3NDBlOTJhMmI5MmRjMjZlZWVjOWYwNDZhMWFjYWU2ZCcsCiAgICApLAogICAgJ3dwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXInID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS4yLjgnLAogICAgICAndmVyc2lvbicgPT4gJzEuMi44LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzBiYjJiOTE2MmMzOGNhNzIzNzAzODBhZWExMWRjMDZlNDMxZTEzYTUnLAogICAgKSwKICApLAopOwpwcml2YXRlIHN0YXRpYyAkY2FuR2V0VmVuZG9yczsKcHJpdmF0ZSBzdGF0aWMgJGluc3RhbGxlZEJ5VmVuZG9yID0gYXJyYXkoKTsKCgoKCgoKCnB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVkUGFja2FnZXMoKQp7CiRwYWNrYWdlcyA9IGFycmF5KCk7CmZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKJHBhY2thZ2VzW10gPSBhcnJheV9rZXlzKCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ10pOwp9CgppZiAoMSA9PT0gXGNvdW50KCRwYWNrYWdlcykpIHsKcmV0dXJuICRwYWNrYWdlc1swXTsKfQoKcmV0dXJuIGFycmF5X2tleXMoYXJyYXlfZmxpcChcY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHBhY2thZ2VzKSkpOwp9CgoKCgoKCgoKCnB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNJbnN0YWxsZWQoJHBhY2thZ2VOYW1lKQp7CmZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKaWYgKGlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKcmV0dXJuIHRydWU7Cn0KfQoKcmV0dXJuIGZhbHNlOwp9CgoKCgoKCgoKCgoKCgoKcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYXRpc2ZpZXMoVmVyc2lvblBhcnNlciAkcGFyc2VyLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KQp7CiRjb25zdHJhaW50ID0gJHBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCk7CiRwcm92aWRlZCA9ICRwYXJzZXItPnBhcnNlQ29uc3RyYWludHMoc2VsZjo6Z2V0VmVyc2lvblJhbmdlcygkcGFja2FnZU5hbWUpKTsKCnJldHVybiAkcHJvdmlkZWQtPm1hdGNoZXMoJGNvbnN0cmFpbnQpOwp9CgoKCgoKCgoKCgpwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb25SYW5nZXMoJHBhY2thZ2VOYW1lKQp7CmZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CmNvbnRpbnVlOwp9CgokcmFuZ2VzID0gYXJyYXkoKTsKaWYgKGlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsncHJldHR5X3ZlcnNpb24nXSkpIHsKJHJhbmdlc1tdID0gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcmV0dHlfdmVyc2lvbiddOwp9CmlmIChhcnJheV9rZXlfZXhpc3RzKCdhbGlhc2VzJywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewokcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydhbGlhc2VzJ10pOwp9CmlmIChhcnJheV9rZXlfZXhpc3RzKCdyZXBsYWNlZCcsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKJHJhbmdlcyA9IGFycmF5X21lcmdlKCRyYW5nZXMsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsncmVwbGFjZWQnXSk7Cn0KaWYgKGFycmF5X2tleV9leGlzdHMoJ3Byb3ZpZGVkJywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewokcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydwcm92aWRlZCddKTsKfQoKcmV0dXJuIGltcGxvZGUoJyB8fCAnLCAkcmFuZ2VzKTsKfQoKdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKfQoKCgoKCnB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigkcGFja2FnZU5hbWUpCnsKZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewppZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKY29udGludWU7Cn0KCmlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWyd2ZXJzaW9uJ10pKSB7CnJldHVybiBudWxsOwp9CgpyZXR1cm4gJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWyd2ZXJzaW9uJ107Cn0KCnRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7Cn0KCgoKCgpwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oJHBhY2thZ2VOYW1lKQp7CmZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CmNvbnRpbnVlOwp9CgppZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsncHJldHR5X3ZlcnNpb24nXSkpIHsKcmV0dXJuIG51bGw7Cn0KCnJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ107Cn0KCnRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7Cn0KCgoKCgpwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJlZmVyZW5jZSgkcGFja2FnZU5hbWUpCnsKZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewppZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKY29udGludWU7Cn0KCmlmICghaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydyZWZlcmVuY2UnXSkpIHsKcmV0dXJuIG51bGw7Cn0KCnJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlZmVyZW5jZSddOwp9Cgp0aHJvdyBuZXcgXE91dE9mQm91bmRzRXhjZXB0aW9uKCdQYWNrYWdlICInIC4gJHBhY2thZ2VOYW1lIC4gJyIgaXMgbm90IGluc3RhbGxlZCcpOwp9CgoKCgoKcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSb290UGFja2FnZSgpCnsKJGluc3RhbGxlZCA9IHNlbGY6OmdldEluc3RhbGxlZCgpOwoKcmV0dXJuICRpbnN0YWxsZWRbMF1bJ3Jvb3QnXTsKfQoKCgoKCgoKcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSYXdEYXRhKCkKewpyZXR1cm4gc2VsZjo6JGluc3RhbGxlZDsKfQoKCgoKCgoKCgoKCgoKCgoKCgoKcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWxvYWQoJGRhdGEpCnsKc2VsZjo6JGluc3RhbGxlZCA9ICRkYXRhOwpzZWxmOjokaW5zdGFsbGVkQnlWZW5kb3IgPSBhcnJheSgpOwp9CgoKCgoKcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVkKCkKewppZiAobnVsbCA9PT0gc2VsZjo6JGNhbkdldFZlbmRvcnMpIHsKc2VsZjo6JGNhbkdldFZlbmRvcnMgPSBtZXRob2RfZXhpc3RzKCdDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlcicsICdnZXRSZWdpc3RlcmVkTG9hZGVycycpOwp9CgokaW5zdGFsbGVkID0gYXJyYXkoKTsKCmlmIChzZWxmOjokY2FuR2V0VmVuZG9ycykgewpmb3JlYWNoIChDbGFzc0xvYWRlcjo6Z2V0UmVnaXN0ZXJlZExvYWRlcnMoKSBhcyAkdmVuZG9yRGlyID0+ICRsb2FkZXIpIHsKaWYgKGlzc2V0KHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvclskdmVuZG9yRGlyXSkpIHsKJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZEJ5VmVuZG9yWyR2ZW5kb3JEaXJdOwp9IGVsc2VpZiAoaXNfZmlsZSgkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLnBocCcpKSB7CiRpbnN0YWxsZWRbXSA9IHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvclskdmVuZG9yRGlyXSA9IHJlcXVpcmUgJHZlbmRvckRpci4nL2NvbXBvc2VyL2luc3RhbGxlZC5waHAnOwp9Cn0KfQoKJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZDsKCnJldHVybiAkaW5zdGFsbGVkOwp9Cn0KPD9waHAKCi8vIGF1dG9sb2FkX2NsYXNzbWFwLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokdmVuZG9yRGlyID0gZGlybmFtZShkaXJuYW1lKF9fRklMRV9fKSk7CiRiYXNlRGlyID0gZGlybmFtZSgkdmVuZG9yRGlyKTsKCnJldHVybiBhcnJheSgKICAgICdDb21wb3NlclxcSW5zdGFsbGVkVmVyc2lvbnMnID0+ICR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocCcsCiAgICAnV1BfQ0xJJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvd3AtY2xpL3BocC9jbGFzcy13cC1jbGkucGhwJywKICAgICdXUF9DTElfQ29tbWFuZCcgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3dwLWNsaS9waHAvY2xhc3Mtd3AtY2xpLWNvbW1hbmQucGhwJywKKTsKPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3NwZHgtbGljZW5zZXMuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU3BkeDsKCmNsYXNzIFNwZHhMaWNlbnNlcwp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIGNvbnN0IExJQ0VOU0VTX0ZJTEUgPSAnc3BkeC1saWNlbnNlcy5qc29uJzsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIGNvbnN0IEVYQ0VQVElPTlNfRklMRSA9ICdzcGR4LWV4Y2VwdGlvbnMuanNvbic7CgogICAgLyoqCiAgICAgKiBDb250YWlucyBhbGwgdGhlIGxpY2Vuc2VzLgogICAgICoKICAgICAqIFRoZSBhcnJheSBpcyBpbmRleGVkIGJ5IGxpY2Vuc2UgaWRlbnRpZmllcnMsIHdoaWNoIGNvbnRhaW4KICAgICAqIGEgbnVtZXJpY2FsbHkgaW5kZXhlZCBhcnJheSB3aXRoIGxpY2Vuc2UgZGV0YWlscy4KICAgICAqCiAgICAgKiAgWyBsb3dlcmNhc2VkIGxpY2Vuc2UgaWRlbnRpZmllciA9PgogICAgICogICAgICBbIDAgPT4gaWRlbnRpZmllciAoc3RyaW5nKSwgMSA9PiBmdWxsIG5hbWUgKHN0cmluZyksIDIgPT4gb3NpIGNlcnRpZmllZCAoYm9vbCksIDMgPT4gZGVwcmVjYXRlZCAoYm9vbCkgXQogICAgICogICAgLCAuLi4KICAgICAqICBdCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRsaWNlbnNlczsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJGxpY2Vuc2VzRXhwcmVzc2lvbjsKCiAgICAvKioKICAgICAqIENvbnRhaW5zIGFsbCB0aGUgbGljZW5zZSBleGNlcHRpb25zLgogICAgICoKICAgICAqIFRoZSBhcnJheSBpcyBpbmRleGVkIGJ5IGxpY2Vuc2UgZXhjZXB0aW9uIGlkZW50aWZpZXJzLCB3aGljaCBjb250YWluCiAgICAgKiBhIG51bWVyaWNhbGx5IGluZGV4ZWQgYXJyYXkgd2l0aCBsaWNlbnNlIGV4Y2VwdGlvbiBkZXRhaWxzLgogICAgICoKICAgICAqICBbIGxvd2VyY2FzZWQgZXhjZXB0aW9uIGlkZW50aWZpZXIgPT4KICAgICAqICAgICAgWyAwID0+IGV4Y2VwdGlvbiBpZGVudGlmaWVyIChzdHJpbmcpLCAxID0+IGZ1bGwgbmFtZSAoc3RyaW5nKSBdCiAgICAgKiAgICAsIC4uLgogICAgICogIF0KICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJGV4Y2VwdGlvbnM7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICRleGNlcHRpb25zRXhwcmVzc2lvbjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5sb2FkTGljZW5zZXMoKTsKICAgICAgICAkdGhpcy0+bG9hZEV4Y2VwdGlvbnMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgbGljZW5zZSBtZXRhZGF0YSBieSBsaWNlbnNlIGlkZW50aWZpZXIuCiAgICAgKgogICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGEgbGluayB0byB0aGUgZnVsbCBsaWNlbnNlIHRleHQgdG8gdGhlIGxpY2Vuc2UgbWV0YWRhdGEuCiAgICAgKiBUaGUgYXJyYXkgcmV0dXJuZWQgaXMgaW4gdGhlIGZvcm0gb2Y6CiAgICAgKgogICAgICogIFsgMCA9PiBmdWxsIG5hbWUgKHN0cmluZyksIDEgPT4gb3NpIGNlcnRpZmllZCwgMiA9PiBsaW5rIHRvIGxpY2Vuc2UgdGV4dCAoc3RyaW5nKSwgMyA9PiBkZXByZWNhdGlvbiBzdGF0dXMgKGJvb2wpIF0KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaWNlbnNlQnlJZGVudGlmaWVyKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRrZXkgPSBzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKTsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+bGljZW5zZXNbJGtleV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGxpc3QoJGlkZW50aWZpZXIsICRuYW1lLCAkaXNPc2lBcHByb3ZlZCwgJGlzRGVwcmVjYXRlZExpY2Vuc2VJZCkgPSAkdGhpcy0+bGljZW5zZXNbJGtleV07CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICRpc09zaUFwcHJvdmVkLAogICAgICAgICAgICAnaHR0cHM6Ly9zcGR4Lm9yZy9saWNlbnNlcy8nIC4gJGlkZW50aWZpZXIgLiAnLmh0bWwjbGljZW5zZVRleHQnLAogICAgICAgICAgICAkaXNEZXByZWNhdGVkTGljZW5zZUlkLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBsaWNlbnNlcyBpbmZvcm1hdGlvbiwga2V5ZWQgYnkgdGhlIGxvd2VyY2FzZWQgbGljZW5zZSBpZGVudGlmaWVyLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXSBFYWNoIGl0ZW0gaXMgWyAwID0+IGlkZW50aWZpZXIgKHN0cmluZyksIDEgPT4gZnVsbCBuYW1lIChzdHJpbmcpLCAyID0+IG9zaSBjZXJ0aWZpZWQgKGJvb2wpLCAzID0+IGRlcHJlY2F0ZWQgKGJvb2wpIF0KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpY2Vuc2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxpY2Vuc2VzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBsaWNlbnNlIGV4Y2VwdGlvbiBtZXRhZGF0YSBieSBsaWNlbnNlIGV4Y2VwdGlvbiBpZGVudGlmaWVyLgogICAgICoKICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBhIGxpbmsgdG8gdGhlIGZ1bGwgbGljZW5zZSBleGNlcHRpb24gdGV4dCB0byB0aGUgbGljZW5zZSBleGNlcHRpb24gbWV0YWRhdGEuCiAgICAgKiBUaGUgYXJyYXkgcmV0dXJuZWQgaXMgaW4gdGhlIGZvcm0gb2Y6CiAgICAgKgogICAgICogIFsgMCA9PiBmdWxsIG5hbWUgKHN0cmluZyksIDEgPT4gbGluayB0byBsaWNlbnNlIHRleHQgKHN0cmluZykgXQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkZW50aWZpZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4Y2VwdGlvbkJ5SWRlbnRpZmllcigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAka2V5ID0gc3RydG9sb3dlcigkaWRlbnRpZmllcik7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmV4Y2VwdGlvbnNbJGtleV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGxpc3QoJGlkZW50aWZpZXIsICRuYW1lKSA9ICR0aGlzLT5leGNlcHRpb25zWyRrZXldOwoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICAnaHR0cHM6Ly9zcGR4Lm9yZy9saWNlbnNlcy8nIC4gJGlkZW50aWZpZXIgLiAnLmh0bWwjbGljZW5zZUV4Y2VwdGlvblRleHQnLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzaG9ydCBpZGVudGlmaWVyIG9mIGEgbGljZW5zZSAob3IgbGljZW5zZSBleGNlcHRpb24pIGJ5IGZ1bGwgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWRlbnRpZmllckJ5TmFtZSgkbmFtZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bGljZW5zZXMgYXMgJGxpY2Vuc2VEYXRhKSB7CiAgICAgICAgICAgIGlmICgkbGljZW5zZURhdGFbMV0gPT09ICRuYW1lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpY2Vuc2VEYXRhWzBdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZXhjZXB0aW9ucyBhcyAkbGljZW5zZURhdGEpIHsKICAgICAgICAgICAgaWYgKCRsaWNlbnNlRGF0YVsxXSA9PT0gJG5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGljZW5zZURhdGFbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBPU0kgQXBwcm92ZWQgc3RhdHVzIGZvciBhIGxpY2Vuc2UgYnkgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc09zaUFwcHJvdmVkQnlJZGVudGlmaWVyKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGljZW5zZXNbc3RydG9sb3dlcigkaWRlbnRpZmllcildWzJdOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVwcmVjYXRpb24gc3RhdHVzIGZvciBhIGxpY2Vuc2UgYnkgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlcHJlY2F0ZWRCeUlkZW50aWZpZXIoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlc1tzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKV1bM107CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRsaWNlbnNlCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZSgkbGljZW5zZSkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJGxpY2Vuc2UpKSB7CiAgICAgICAgICAgICRjb3VudCA9IGNvdW50KCRsaWNlbnNlKTsKICAgICAgICAgICAgaWYgKCRjb3VudCAhPT0gY291bnQoYXJyYXlfZmlsdGVyKCRsaWNlbnNlLCAnaXNfc3RyaW5nJykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQXJyYXkgb2Ygc3RyaW5ncyBleHBlY3RlZC4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGljZW5zZSA9ICRjb3VudCA+IDEgID8gJygnIC4gaW1wbG9kZSgnIE9SICcsICRsaWNlbnNlKSAuICcpJyA6IChzdHJpbmcpIHJlc2V0KCRsaWNlbnNlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfc3RyaW5nKCRsaWNlbnNlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ0FycmF5IG9yIFN0cmluZyBleHBlY3RlZCwgJXMgZ2l2ZW4uJywKICAgICAgICAgICAgICAgIGdldHR5cGUoJGxpY2Vuc2UpCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1ZhbGlkTGljZW5zZVN0cmluZygkbGljZW5zZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJlc291cmNlc0RpcigpCiAgICB7CiAgICAgICAgcmV0dXJuIGRpcm5hbWUoX19ESVJfXykgLiAnL3Jlcyc7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkTGljZW5zZXMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bGljZW5zZXMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cyhzZWxmOjpnZXRSZXNvdXJjZXNEaXIoKSAuICcvJyAuIHNlbGY6OkxJQ0VOU0VTX0ZJTEUpOwogICAgICAgICR0aGlzLT5saWNlbnNlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKGpzb25fZGVjb2RlKCRqc29uLCB0cnVlKSBhcyAkaWRlbnRpZmllciA9PiAkbGljZW5zZSkgewogICAgICAgICAgICAkdGhpcy0+bGljZW5zZXNbc3RydG9sb3dlcigkaWRlbnRpZmllcildID0gYXJyYXkoJGlkZW50aWZpZXIsICRsaWNlbnNlWzBdLCAkbGljZW5zZVsxXSwgJGxpY2Vuc2VbMl0pOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRFeGNlcHRpb25zKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cyhzZWxmOjpnZXRSZXNvdXJjZXNEaXIoKSAuICcvJyAuIHNlbGY6OkVYQ0VQVElPTlNfRklMRSk7CiAgICAgICAgJHRoaXMtPmV4Y2VwdGlvbnMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoIChqc29uX2RlY29kZSgkanNvbiwgdHJ1ZSkgYXMgJGlkZW50aWZpZXIgPT4gJGV4Y2VwdGlvbikgewogICAgICAgICAgICAkdGhpcy0+ZXhjZXB0aW9uc1tzdHJ0b2xvd2VyKCRpZGVudGlmaWVyKV0gPSBhcnJheSgkaWRlbnRpZmllciwgJGV4Y2VwdGlvblswXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRMaWNlbnNlc0V4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+bGljZW5zZXNFeHByZXNzaW9uKSB7CiAgICAgICAgICAgICRsaWNlbnNlcyA9IGFycmF5X21hcCgncHJlZ19xdW90ZScsIGFycmF5X2tleXMoJHRoaXMtPmxpY2Vuc2VzKSk7CiAgICAgICAgICAgIHJzb3J0KCRsaWNlbnNlcyk7CiAgICAgICAgICAgICRsaWNlbnNlcyA9IGltcGxvZGUoJ3wnLCAkbGljZW5zZXMpOwogICAgICAgICAgICAkdGhpcy0+bGljZW5zZXNFeHByZXNzaW9uID0gJGxpY2Vuc2VzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlc0V4cHJlc3Npb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEV4Y2VwdGlvbnNFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uKSB7CiAgICAgICAgICAgICRleGNlcHRpb25zID0gYXJyYXlfbWFwKCdwcmVnX3F1b3RlJywgYXJyYXlfa2V5cygkdGhpcy0+ZXhjZXB0aW9ucykpOwogICAgICAgICAgICByc29ydCgkZXhjZXB0aW9ucyk7CiAgICAgICAgICAgICRleGNlcHRpb25zID0gaW1wbG9kZSgnfCcsICRleGNlcHRpb25zKTsKICAgICAgICAgICAgJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uID0gJGV4Y2VwdGlvbnM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4Y2VwdGlvbnNFeHByZXNzaW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbGljZW5zZQogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1ZhbGlkTGljZW5zZVN0cmluZygkbGljZW5zZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxpY2Vuc2VzW3N0cnRvbG93ZXIoJGxpY2Vuc2UpXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkbGljZW5zZXMgPSAkdGhpcy0+Z2V0TGljZW5zZXNFeHByZXNzaW9uKCk7CiAgICAgICAgJGV4Y2VwdGlvbnMgPSAkdGhpcy0+Z2V0RXhjZXB0aW9uc0V4cHJlc3Npb24oKTsKCiAgICAgICAgJHJlZ2V4ID0gPDw8UkVHRVgKewooPyhERUZJTkUpCiAgICAjIGlkc3RyaW5nOiAxKiggQUxQSEEgLyBESUdJVCAvIC0gLyAuICkKICAgICg/PGlkc3RyaW5nPltccExccE4uLV17MSx9KQoKICAgICMgbGljZW5zZS1pZDogdGFrZW4gZnJvbSBsaXN0CiAgICAoPzxsaWNlbnNlaWQ+JHtsaWNlbnNlc30pCgogICAgIyBsaWNlbnNlLWV4Y2VwdGlvbi1pZDogdGFrZW4gZnJvbSBsaXN0CiAgICAoPzxsaWNlbnNlZXhjZXB0aW9uaWQ+JHtleGNlcHRpb25zfSkKCiAgICAjIGxpY2Vuc2UtcmVmOiBbRG9jdW1lbnRSZWYtMSooaWRzdHJpbmcpOl1MaWNlbnNlUmVmLTEqKGlkc3RyaW5nKQogICAgKD88bGljZW5zZXJlZj4oPzpEb2N1bWVudFJlZi0oPyZpZHN0cmluZyk6KT9MaWNlbnNlUmVmLSg/Jmlkc3RyaW5nKSkKCiAgICAjIHNpbXBsZS1leHByZXNzc2lvbjogbGljZW5zZS1pZCAvIGxpY2Vuc2UtaWQrIC8gbGljZW5zZS1yZWYKICAgICg/PHNpbXBsZV9leHByZXNzaW9uPig/JmxpY2Vuc2VpZClcKz8gfCAoPyZsaWNlbnNlaWQpIHwgKD8mbGljZW5zZXJlZikpCgogICAgIyBjb21wb3VuZC1leHByZXNzaW9uOiAxKigKICAgICMgICBzaW1wbGUtZXhwcmVzc2lvbiAvCiAgICAjICAgc2ltcGxlLWV4cHJlc3Npb24gV0lUSCBsaWNlbnNlLWV4Y2VwdGlvbi1pZCAvCiAgICAjICAgY29tcG91bmQtZXhwcmVzc2lvbiBBTkQgY29tcG91bmQtZXhwcmVzc2lvbiAvCiAgICAjICAgY29tcG91bmQtZXhwcmVzc2lvbiBPUiBjb21wb3VuZC1leHByZXNzaW9uCiAgICAjICkgLyAoIGNvbXBvdW5kLWV4cHJlc3Npb24gKSApCiAgICAoPzxjb21wb3VuZF9oZWFkPgogICAgICAgICg/JnNpbXBsZV9leHByZXNzaW9uKSAoIFxzKyBXSVRIIFxzKyAoPyZsaWNlbnNlZXhjZXB0aW9uaWQpKT8KICAgICAgICAgICAgfCBcKCBccyogKD8mY29tcG91bmRfZXhwcmVzc2lvbikgXHMqIFwpCiAgICApCiAgICAoPzxjb21wb3VuZF9leHByZXNzaW9uPgogICAgICAgICg/JmNvbXBvdW5kX2hlYWQpICg/OiBccysgKD86QU5EfE9SKSBccysgKD8mY29tcG91bmRfZXhwcmVzc2lvbikpPwogICAgKQoKICAgICMgbGljZW5zZS1leHByZXNzaW9uOiAxKjEoc2ltcGxlLWV4cHJlc3Npb24gLyBjb21wb3VuZC1leHByZXNzaW9uKQogICAgKD88bGljZW5zZV9leHByZXNzaW9uPig/JmNvbXBvdW5kX2V4cHJlc3Npb24pIHwgKD8mc2ltcGxlX2V4cHJlc3Npb24pKQopICMgZW5kIG9mIGRlZmluZQoKXihOT05FIHwgTk9BU1NFUlRJT04gfCAoPyZsaWNlbnNlX2V4cHJlc3Npb24pKSQKfXhpClJFR0VYOwoKICAgICAgICAkbWF0Y2ggPSBwcmVnX21hdGNoKCRyZWdleCwgJGxpY2Vuc2UpOwoKICAgICAgICBpZiAoMCA9PT0gJG1hdGNoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJG1hdGNoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignUmVnZXggZmFpbGVkIHRvIGNvbXBpbGUvcnVuLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8vIGF1dG9sb2FkX3BzcjQucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKCiR2ZW5kb3JEaXIgPSBkaXJuYW1lKGRpcm5hbWUoX19GSUxFX18pKTsKJGJhc2VEaXIgPSBkaXJuYW1lKCR2ZW5kb3JEaXIpOwoKcmV0dXJuIGFycmF5KAogICAgJ1dQX0NMSVxcTWFpbnRlbmFuY2VNb2RlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQvc3JjJyksCiAgICAnV1BfQ0xJXFxJMThuXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9pMThuLWNvbW1hbmQvc3JjJyksCiAgICAnV1BfQ0xJXFxFbWJlZHNcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjJyksCiAgICAnV1BfQ0xJXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMvV1BfQ0xJJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjL1dQX0NMSScpLAogICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxNYnN0cmluZ1xcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nJyksCiAgICAnU3ltZm9ueVxcUG9seWZpbGxcXEN0eXBlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3N5bWZvbnkvcG9seWZpbGwtY3R5cGUnKSwKICAgICdTeW1mb255XFxDb21wb25lbnRcXFByb2Nlc3NcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc3ltZm9ueS9wcm9jZXNzJyksCiAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaW5kZXJcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc3ltZm9ueS9maW5kZXInKSwKICAgICdTeW1mb255XFxDb21wb25lbnRcXEZpbGVzeXN0ZW1cXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc3ltZm9ueS9maWxlc3lzdGVtJyksCiAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxDb25zb2xlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3N5bWZvbnkvY29uc29sZScpLAogICAgJ1NlbGRcXFBoYXJVdGlsc1xcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9zZWxkL3BoYXItdXRpbHMvc3JjJyksCiAgICAnU2VsZFxcSnNvbkxpbnRcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvc2VsZC9qc29ubGludC9zcmMvU2VsZC9Kc29uTGludCcpLAogICAgJ1JlYWN0XFxQcm9taXNlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3JlYWN0L3Byb21pc2Uvc3JjJyksCiAgICAnUHNyXFxMb2dcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvcHNyL2xvZy9Qc3IvTG9nJyksCiAgICAnUGVhc3RcXHRlc3RcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvbWNrODkvcGVhc3QvdGVzdC9QZWFzdCcpLAogICAgJ1BlYXN0XFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL21jazg5L3BlYXN0L2xpYi9QZWFzdCcpLAogICAgJ011c3Rhbmdvc3RhbmdcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9zcmMnKSwKICAgICdKc29uU2NoZW1hXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEvc3JjL0pzb25TY2hlbWEnKSwKICAgICdHZXR0ZXh0XFxMYW5ndWFnZXNcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjJyksCiAgICAnR2V0dGV4dFxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9nZXR0ZXh0L2dldHRleHQvc3JjJyksCiAgICAnQ29tcG9zZXJcXFhkZWJ1Z0hhbmRsZXJcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvY29tcG9zZXIveGRlYnVnLWhhbmRsZXIvc3JjJyksCiAgICAnQ29tcG9zZXJcXFNlbXZlclxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9jb21wb3Nlci9zZW12ZXIvc3JjJyksCiAgICAnQ29tcG9zZXJcXE1ldGFkYXRhTWluaWZpZXJcXCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIvc3JjJyksCiAgICAnQ29tcG9zZXJcXENhQnVuZGxlXFwnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL2NhLWJ1bmRsZS9zcmMnKSwKICAgICdDb21wb3NlclxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXInKSwKICAgICcnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jYWNoZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jaGVja3N1bS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jcm9uLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2RiLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9ldmFsLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2V4cG9ydC1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9leHRlbnNpb24tY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvaW1wb3J0LWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL21lZGlhLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3BhY2thZ2UtY29tbWFuZC9zcmMnLCAkdmVuZG9yRGlyIC4gJy93cC1jbGkvcmV3cml0ZS1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9yb2xlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc3JjJywgJHZlbmRvckRpciAuICcvd3AtY2xpL3NlcnZlci1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zaGVsbC1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kL3NyYycsICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC9zcmMnKSwKKTsKPD9waHAKCi8vIHBsYXRmb3JtX2NoZWNrLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokaXNzdWVzID0gYXJyYXkoKTsKCmlmICghKFBIUF9WRVJTSU9OX0lEID49IDUwNjAwKSkgewogICAgJGlzc3Vlc1tdID0gJ1lvdXIgQ29tcG9zZXIgZGVwZW5kZW5jaWVzIHJlcXVpcmUgYSBQSFAgdmVyc2lvbiAiPj0gNS42LjAiLiBZb3UgYXJlIHJ1bm5pbmcgJyAuIFBIUF9WRVJTSU9OIC4gJy4nOwp9CgppZiAoJGlzc3VlcykgewogICAgaWYgKCFoZWFkZXJzX3NlbnQoKSkgewogICAgICAgIGhlYWRlcignSFRUUC8xLjEgNTAwIEludGVybmFsIFNlcnZlciBFcnJvcicpOwogICAgfQogICAgaWYgKCFpbmlfZ2V0KCdkaXNwbGF5X2Vycm9ycycpKSB7CiAgICAgICAgaWYgKFBIUF9TQVBJID09PSAnY2xpJyB8fCBQSFBfU0FQSSA9PT0gJ3BocGRiZycpIHsKICAgICAgICAgICAgZndyaXRlKFNUREVSUiwgJ0NvbXBvc2VyIGRldGVjdGVkIGlzc3VlcyBpbiB5b3VyIHBsYXRmb3JtOicgLiBQSFBfRU9MLlBIUF9FT0wgLiBpbXBsb2RlKFBIUF9FT0wsICRpc3N1ZXMpIC4gUEhQX0VPTC5QSFBfRU9MKTsKICAgICAgICB9IGVsc2VpZiAoIWhlYWRlcnNfc2VudCgpKSB7CiAgICAgICAgICAgIGVjaG8gJ0NvbXBvc2VyIGRldGVjdGVkIGlzc3VlcyBpbiB5b3VyIHBsYXRmb3JtOicgLiBQSFBfRU9MLlBIUF9FT0wgLiBzdHJfcmVwbGFjZSgnWW91IGFyZSBydW5uaW5nICcuUEhQX1ZFUlNJT04uJy4nLCAnJywgaW1wbG9kZShQSFBfRU9MLCAkaXNzdWVzKSkgLiBQSFBfRU9MLlBIUF9FT0w7CiAgICAgICAgfQogICAgfQogICAgdHJpZ2dlcl9lcnJvcigKICAgICAgICAnQ29tcG9zZXIgZGV0ZWN0ZWQgaXNzdWVzIGluIHlvdXIgcGxhdGZvcm06ICcgLiBpbXBsb2RlKCcgJywgJGlzc3VlcyksCiAgICAgICAgRV9VU0VSX0VSUk9SCiAgICApOwp9Cjw/cGhwCgovLyBhdXRvbG9hZF9uYW1lc3BhY2VzLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokdmVuZG9yRGlyID0gZGlybmFtZShkaXJuYW1lKF9fRklMRV9fKSk7CiRiYXNlRGlyID0gZGlybmFtZSgkdmVuZG9yRGlyKTsKCnJldHVybiBhcnJheSgKICAgICdjbGknID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9waHAtY2xpLXRvb2xzL2xpYicpLAogICAgJ1dQX0NMSVxcJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy93cC1jbGkvd3AtY2xpL3BocCcpLAogICAgJ1JlcXVlc3RzJyA9PiBhcnJheSgkdmVuZG9yRGlyIC4gJy9ybWNjdWUvcmVxdWVzdHMvbGlicmFyeScpLAogICAgJ094eW1lbCcgPT4gYXJyYXkoJHZlbmRvckRpciAuICcvbmIvb3h5bWVsJyksCiAgICAnTXVzdGFjaGUnID0+IGFycmF5KCR2ZW5kb3JEaXIgLiAnL211c3RhY2hlL211c3RhY2hlL3NyYycpLAopOwo8P3BocAoKLy8gYXV0b2xvYWRfc3RhdGljLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7CgpjbGFzcyBDb21wb3NlclN0YXRpY0luaXRiZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkOAp7CiAgICBwdWJsaWMgc3RhdGljICRmaWxlcyA9IGFycmF5ICgKICAgICAgICAnYmUwMWI5YjE2OTI1ZGNiMjIxNjVjNDBiNDY2ODFhYzYnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9jbGkucGhwJywKICAgICAgICAnMzkzNzgwNjEwNWNjOGUyMjFiOGZhOGRiNWI3MGQyZjInID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9pbmNsdWRlcy9mdW5jdGlvbnMucGhwJywKICAgICAgICAnOGEwYWQwMmRmNmE1MDg3ZjJjMzgwZjhmZDUyZGIyNzMnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2NhY2hlLWNvbW1hbmQvY2FjaGUtY29tbWFuZC5waHAnLAogICAgICAgICdmM2YwMTk5YTNlY2Q5ZjUwMWQwYTNiMzYxYmQyZjYxYycgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZW50aXR5LWNvbW1hbmQvZW50aXR5LWNvbW1hbmQucGhwJywKICAgICAgICAnM2YyMDEwMzNkNWFjZWIyMjkzMzE0MjczYmU4OGY3YzYnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL2V4dGVuc2lvbi1jb21tYW5kLnBocCcsCiAgICAgICAgJ2M2NWY3NTMzNzVmYWVlMzQ5YjdhZGM0OGMyZWU3Y2MyJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9kYi1jb21tYW5kL2RiLWNvbW1hbmQucGhwJywKICAgICAgICAnMGU2ZDdiZjRhNTgxMWJmYTVjZjQwYzVjY2Q2ZmFlNmEnID0+IF9fRElSX18gLiAnLy4uJyAuICcvc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9ib290c3RyYXAucGhwJywKICAgICAgICAnMzIwY2RlMjJmNjZkZDRmNWQzZmQ2MjFkM2U4OGI5OGYnID0+IF9fRElSX18gLiAnLy4uJyAuICcvc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZS9ib290c3RyYXAucGhwJywKICAgICAgICAnYWQxNTVmOGYxY2YwZDQxOGZlNDllMjQ4ZGI4YzY2MWInID0+IF9fRElSX18gLiAnLy4uJyAuICcvcmVhY3QvcHJvbWlzZS9zcmMvZnVuY3Rpb25zX2luY2x1ZGUucGhwJywKICAgICAgICAnZDk3OWMxMWZlODBiYTk2YWUzMDM3YjQzNDI5ZmU1NDYnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvc2NhZmZvbGQtY29tbWFuZC5waHAnLAogICAgICAgICc1YzZlYzVjZmY4ZjlkNjI1NzcyYzhlZDE0N2Y2Yjg5NCcgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZXhwb3J0LWNvbW1hbmQvZXhwb3J0LWNvbW1hbmQucGhwJywKICAgICAgICAnYjY2ZDI5NzU3ZmNiMmZiN2E5NjA4ZDA2OGUzNzE2YjAnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvY2hlY2tzdW0tY29tbWFuZC5waHAnLAogICAgICAgICdhYzk0OWNlNDBhOTgxODE5YmExMzI0NzM1MThhOWEzMScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyL3NyYy9XUENvbmZpZ1RyYW5zZm9ybWVyLnBocCcsCiAgICAgICAgJzMwY2JiNmU0MTIyZGM5ODhlNDk0YzZiOWMwNDM4MjMzJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9pbXBvcnQtY29tbWFuZC9pbXBvcnQtY29tbWFuZC5waHAnLAogICAgICAgICc1ZTA5OWQzY2FjNjc3ZGQyYmVjMTAwM2VhNzcwNzc0NScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvbWVkaWEtY29tbWFuZC9tZWRpYS1jb21tYW5kLnBocCcsCiAgICAgICAgJ2JhMzY2Zjk2ZjRmZGRiZGVmNjFhZDdhODYyYjQ0ZjYxJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQvcGFja2FnZS1jb21tYW5kLnBocCcsCiAgICAgICAgJzVkZWFmNmNlOWM4YmJkZmI2NTEwNGM3ZTkzOGQ1ODc1JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9jb25maWctY29tbWFuZC5waHAnLAogICAgICAgICc2OGMzOWI4ODIxNWI2Y2Y3YTBkYTE2NDE2NjY3MGVmOScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL2NvcmUtY29tbWFuZC5waHAnLAogICAgICAgICc3NjU0ZTAwYmYwZTYzMjU4MDc2NDQwMGJkODI5M2E5YycgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY3Jvbi1jb21tYW5kL2Nyb24tY29tbWFuZC5waHAnLAogICAgICAgICcwMjFkM2ExMzQ3MTU1NmYwYjU3MDM4ZDY3OWY3ZjhlYScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZW1iZWQtY29tbWFuZC9lbWJlZC1jb21tYW5kLnBocCcsCiAgICAgICAgJ2Y5NThkY2EzZjQxMmZkNzk3NWRhMTcwMDkxMmE5MzIxJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9ldmFsLWNvbW1hbmQvZXZhbC1jb21tYW5kLnBocCcsCiAgICAgICAgJ2ZmYjQ2NWE0OTRjMzEwMTIxOGM0NDE3MTgwYzJjOWEyJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9pMThuLWNvbW1hbmQvaTE4bi1jb21tYW5kLnBocCcsCiAgICAgICAgJ2FjZTBkMjA1ZGI3ZjQxMzVlYzMyMTMyYTAwNzZkNTU1JyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL2xhbmd1YWdlLWNvbW1hbmQucGhwJywKICAgICAgICAnMWM4OGMxZWZmMDUyMTdhOGNhYzgwYzY0YzlhYzIwODAnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQucGhwJywKICAgICAgICAnZjM5OWMxYzhkMGM3ODdkNWM5NGMwOTg4NGNkZDk3NjInID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3Jld3JpdGUtY29tbWFuZC9yZXdyaXRlLWNvbW1hbmQucGhwJywKICAgICAgICAnMDgwZmFkZDY2NzE5NWQwNTVjNWEyMzM4NmYyNzAyNjEnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3JvbGUtY29tbWFuZC9yb2xlLWNvbW1hbmQucGhwJywKICAgICAgICAnOGVjYjEzZjhiYmMyMmIxYjM0ZDEyYjE0ZWMwMTA3N2EnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC5waHAnLAogICAgICAgICc5ZjA0ZGQwYWE1ZDY3ZWM3NWE3NWM4OGMzNDVhMDc5ZScgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc2VydmVyLWNvbW1hbmQvc2VydmVyLWNvbW1hbmQucGhwJywKICAgICAgICAnMTI5ZDU4ZmE4MTUxMzc0YWNlYjg1NzFiY2FhOTc1MDQnID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NoZWxsLWNvbW1hbmQvc2hlbGwtY29tbWFuZC5waHAnLAogICAgICAgICc4NTE5Nzc5YmJiNjVlZWI4NDJhZjJmNjI5Y2U3YjZmOCcgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZC9zdXBlci1hZG1pbi1jb21tYW5kLnBocCcsCiAgICAgICAgJzFmMDUzNzJhZmNjN2QwYzUxYTMwNWNlZjFkNTZkZDAxJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC93aWRnZXQtY29tbWFuZC5waHAnLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRwcmVmaXhMZW5ndGhzUHNyNCA9IGFycmF5ICgKICAgICAgICAnVycgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnV1BfQ0xJXFxNYWludGVuYW5jZU1vZGVcXCcgPT4gMjMsCiAgICAgICAgICAgICdXUF9DTElcXEkxOG5cXCcgPT4gMTIsCiAgICAgICAgICAgICdXUF9DTElcXEVtYmVkc1xcJyA9PiAxNCwKICAgICAgICAgICAgJ1dQX0NMSVxcJyA9PiA3LAogICAgICAgICksCiAgICAgICAgJ1MnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxNYnN0cmluZ1xcJyA9PiAyNiwKICAgICAgICAgICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxDdHlwZVxcJyA9PiAyMywKICAgICAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcUHJvY2Vzc1xcJyA9PiAyNiwKICAgICAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcRmluZGVyXFwnID0+IDI1LAogICAgICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaWxlc3lzdGVtXFwnID0+IDI5LAogICAgICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxEZWJ1Z1xcJyA9PiAyNCwKICAgICAgICAgICAgJ1N5bWZvbnlcXENvbXBvbmVudFxcQ29uc29sZVxcJyA9PiAyNiwKICAgICAgICAgICAgJ1NlbGRcXFBoYXJVdGlsc1xcJyA9PiAxNSwKICAgICAgICAgICAgJ1NlbGRcXEpzb25MaW50XFwnID0+IDE0LAogICAgICAgICksCiAgICAgICAgJ1InID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ1JlYWN0XFxQcm9taXNlXFwnID0+IDE0LAogICAgICAgICksCiAgICAgICAgJ1AnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ1BzclxcTG9nXFwnID0+IDgsCiAgICAgICAgICAgICdQZWFzdFxcdGVzdFxcJyA9PiAxMSwKICAgICAgICAgICAgJ1BlYXN0XFwnID0+IDYsCiAgICAgICAgKSwKICAgICAgICAnTScgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnTXVzdGFuZ29zdGFuZ1xcJyA9PiAxNCwKICAgICAgICApLAogICAgICAgICdKJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdKc29uU2NoZW1hXFwnID0+IDExLAogICAgICAgICksCiAgICAgICAgJ0cnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ0dldHRleHRcXExhbmd1YWdlc1xcJyA9PiAxOCwKICAgICAgICAgICAgJ0dldHRleHRcXCcgPT4gOCwKICAgICAgICApLAogICAgICAgICdDJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdDb21wb3NlclxcWGRlYnVnSGFuZGxlclxcJyA9PiAyMywKICAgICAgICAgICAgJ0NvbXBvc2VyXFxTcGR4XFwnID0+IDE0LAogICAgICAgICAgICAnQ29tcG9zZXJcXFNlbXZlclxcJyA9PiAxNiwKICAgICAgICAgICAgJ0NvbXBvc2VyXFxNZXRhZGF0YU1pbmlmaWVyXFwnID0+IDI2LAogICAgICAgICAgICAnQ29tcG9zZXJcXENhQnVuZGxlXFwnID0+IDE4LAogICAgICAgICAgICAnQ29tcG9zZXJcXCcgPT4gOSwKICAgICAgICApLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRwcmVmaXhEaXJzUHNyNCA9IGFycmF5ICgKICAgICAgICAnV1BfQ0xJXFxNYWludGVuYW5jZU1vZGVcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9zcmMnLAogICAgICAgICksCiAgICAgICAgJ1dQX0NMSVxcSTE4blxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvaTE4bi1jb21tYW5kL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnV1BfQ0xJXFxFbWJlZHNcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2VtYmVkLWNvbW1hbmQvc3JjJywKICAgICAgICApLAogICAgICAgICdXUF9DTElcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2VudGl0eS1jb21tYW5kL3NyYy9XUF9DTEknLAogICAgICAgICAgICAxID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjL1dQX0NMSScsCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcUG9seWZpbGxcXE1ic3RyaW5nXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3N5bWZvbnkvcG9seWZpbGwtbWJzdHJpbmcnLAogICAgICAgICksCiAgICAgICAgJ1N5bWZvbnlcXFBvbHlmaWxsXFxDdHlwZVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L3BvbHlmaWxsLWN0eXBlJywKICAgICAgICApLAogICAgICAgICdTeW1mb255XFxDb21wb25lbnRcXFByb2Nlc3NcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvc3ltZm9ueS9wcm9jZXNzJywKICAgICAgICApLAogICAgICAgICdTeW1mb255XFxDb21wb25lbnRcXEZpbmRlclxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9zeW1mb255L2ZpbmRlcicsCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxGaWxlc3lzdGVtXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3N5bWZvbnkvZmlsZXN5c3RlbScsCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxEZWJ1Z1xcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgKSwKICAgICAgICAnU3ltZm9ueVxcQ29tcG9uZW50XFxDb25zb2xlXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3N5bWZvbnkvY29uc29sZScsCiAgICAgICAgKSwKICAgICAgICAnU2VsZFxcUGhhclV0aWxzXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3NlbGQvcGhhci11dGlscy9zcmMnLAogICAgICAgICksCiAgICAgICAgJ1NlbGRcXEpzb25MaW50XFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3NlbGQvanNvbmxpbnQvc3JjL1NlbGQvSnNvbkxpbnQnLAogICAgICAgICksCiAgICAgICAgJ1JlYWN0XFxQcm9taXNlXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3JlYWN0L3Byb21pc2Uvc3JjJywKICAgICAgICApLAogICAgICAgICdQc3JcXExvZ1xcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9wc3IvbG9nL1Bzci9Mb2cnLAogICAgICAgICksCiAgICAgICAgJ1BlYXN0XFx0ZXN0XFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL21jazg5L3BlYXN0L3Rlc3QvUGVhc3QnLAogICAgICAgICksCiAgICAgICAgJ1BlYXN0XFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL21jazg5L3BlYXN0L2xpYi9QZWFzdCcsCiAgICAgICAgKSwKICAgICAgICAnTXVzdGFuZ29zdGFuZ1xcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvbXVzdGFuZ29zdGFuZy1zcHljL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnSnNvblNjaGVtYVxcJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9qdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL3NyYy9Kc29uU2NoZW1hJywKICAgICAgICApLAogICAgICAgICdHZXR0ZXh0XFxMYW5ndWFnZXNcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvZ2V0dGV4dC9sYW5ndWFnZXMvc3JjJywKICAgICAgICApLAogICAgICAgICdHZXR0ZXh0XFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2dldHRleHQvZ2V0dGV4dC9zcmMnLAogICAgICAgICksCiAgICAgICAgJ0NvbXBvc2VyXFxYZGVidWdIYW5kbGVyXFwnID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL2NvbXBvc2VyL3hkZWJ1Zy1oYW5kbGVyL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnQ29tcG9zZXJcXFNwZHhcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICksCiAgICAgICAgJ0NvbXBvc2VyXFxTZW12ZXJcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvY29tcG9zZXIvc2VtdmVyL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnQ29tcG9zZXJcXE1ldGFkYXRhTWluaWZpZXJcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIvc3JjJywKICAgICAgICApLAogICAgICAgICdDb21wb3NlclxcQ2FCdW5kbGVcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvY29tcG9zZXIvY2EtYnVuZGxlL3NyYycsCiAgICAgICAgKSwKICAgICAgICAnQ29tcG9zZXJcXCcgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvY29tcG9zZXIvY29tcG9zZXIvc3JjL0NvbXBvc2VyJywKICAgICAgICApLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRmYWxsYmFja0RpcnNQc3I0ID0gYXJyYXkgKAogICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY2FjaGUtY29tbWFuZC9zcmMnLAogICAgICAgIDEgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY2hlY2tzdW0tY29tbWFuZC9zcmMnLAogICAgICAgIDIgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY29uZmlnLWNvbW1hbmQvc3JjJywKICAgICAgICAzID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2NvcmUtY29tbWFuZC9zcmMnLAogICAgICAgIDQgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvY3Jvbi1jb21tYW5kL3NyYycsCiAgICAgICAgNSA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9kYi1jb21tYW5kL3NyYycsCiAgICAgICAgNiA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9lbnRpdHktY29tbWFuZC9zcmMnLAogICAgICAgIDcgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZXZhbC1jb21tYW5kL3NyYycsCiAgICAgICAgOCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9leHBvcnQtY29tbWFuZC9zcmMnLAogICAgICAgIDkgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQvc3JjJywKICAgICAgICAxMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9pbXBvcnQtY29tbWFuZC9zcmMnLAogICAgICAgIDExID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQvc3JjJywKICAgICAgICAxMiA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9tZWRpYS1jb21tYW5kL3NyYycsCiAgICAgICAgMTMgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcGFja2FnZS1jb21tYW5kL3NyYycsCiAgICAgICAgMTQgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcmV3cml0ZS1jb21tYW5kL3NyYycsCiAgICAgICAgMTUgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvcm9sZS1jb21tYW5kL3NyYycsCiAgICAgICAgMTYgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC9zcmMnLAogICAgICAgIDE3ID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc3JjJywKICAgICAgICAxOCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zZXJ2ZXItY29tbWFuZC9zcmMnLAogICAgICAgIDE5ID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3NoZWxsLWNvbW1hbmQvc3JjJywKICAgICAgICAyMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kL3NyYycsCiAgICAgICAgMjEgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvd2lkZ2V0LWNvbW1hbmQvc3JjJywKICAgICk7CgogICAgcHVibGljIHN0YXRpYyAkcHJlZml4ZXNQc3IwID0gYXJyYXkgKAogICAgICAgICdjJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdjbGknID0+IAogICAgICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3BocC1jbGktdG9vbHMvbGliJywKICAgICAgICAgICAgKSwKICAgICAgICApLAogICAgICAgICdXJyA9PiAKICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICdXUF9DTElcXCcgPT4gCiAgICAgICAgICAgIGFycmF5ICgKICAgICAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy93cC1jbGkvd3AtY2xpL3BocCcsCiAgICAgICAgICAgICksCiAgICAgICAgKSwKICAgICAgICAnUicgPT4gCiAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAnUmVxdWVzdHMnID0+IAogICAgICAgICAgICBhcnJheSAoCiAgICAgICAgICAgICAgICAwID0+IF9fRElSX18gLiAnLy4uJyAuICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnknLAogICAgICAgICAgICApLAogICAgICAgICksCiAgICAgICAgJ08nID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ094eW1lbCcgPT4gCiAgICAgICAgICAgIGFycmF5ICgKICAgICAgICAgICAgICAgIDAgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9uYi9veHltZWwnLAogICAgICAgICAgICApLAogICAgICAgICksCiAgICAgICAgJ00nID0+IAogICAgICAgIGFycmF5ICgKICAgICAgICAgICAgJ011c3RhY2hlJyA9PiAKICAgICAgICAgICAgYXJyYXkgKAogICAgICAgICAgICAgICAgMCA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL211c3RhY2hlL211c3RhY2hlL3NyYycsCiAgICAgICAgICAgICksCiAgICAgICAgKSwKICAgICk7CgogICAgcHVibGljIHN0YXRpYyAkY2xhc3NNYXAgPSBhcnJheSAoCiAgICAgICAgJ0NvbXBvc2VyXFxJbnN0YWxsZWRWZXJzaW9ucycgPT4gX19ESVJfXyAuICcvLi4nIC4gJy9jb21wb3Nlci9JbnN0YWxsZWRWZXJzaW9ucy5waHAnLAogICAgICAgICdXUF9DTEknID0+IF9fRElSX18gLiAnLy4uJyAuICcvd3AtY2xpL3dwLWNsaS9waHAvY2xhc3Mtd3AtY2xpLnBocCcsCiAgICAgICAgJ1dQX0NMSV9Db21tYW5kJyA9PiBfX0RJUl9fIC4gJy8uLicgLiAnL3dwLWNsaS93cC1jbGkvcGhwL2NsYXNzLXdwLWNsaS1jb21tYW5kLnBocCcsCiAgICApOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5pdGlhbGl6ZXIoQ2xhc3NMb2FkZXIgJGxvYWRlcikKICAgIHsKICAgICAgICByZXR1cm4gXENsb3N1cmU6OmJpbmQoZnVuY3Rpb24gKCkgdXNlICgkbG9hZGVyKSB7CiAgICAgICAgICAgICRsb2FkZXItPnByZWZpeExlbmd0aHNQc3I0ID0gQ29tcG9zZXJTdGF0aWNJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDg6OiRwcmVmaXhMZW5ndGhzUHNyNDsKICAgICAgICAgICAgJGxvYWRlci0+cHJlZml4RGlyc1BzcjQgPSBDb21wb3NlclN0YXRpY0luaXRiZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkODo6JHByZWZpeERpcnNQc3I0OwogICAgICAgICAgICAkbG9hZGVyLT5mYWxsYmFja0RpcnNQc3I0ID0gQ29tcG9zZXJTdGF0aWNJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDg6OiRmYWxsYmFja0RpcnNQc3I0OwogICAgICAgICAgICAkbG9hZGVyLT5wcmVmaXhlc1BzcjAgPSBDb21wb3NlclN0YXRpY0luaXRiZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkODo6JHByZWZpeGVzUHNyMDsKICAgICAgICAgICAgJGxvYWRlci0+Y2xhc3NNYXAgPSBDb21wb3NlclN0YXRpY0luaXRiZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkODo6JGNsYXNzTWFwOwoKICAgICAgICB9LCBudWxsLCBDbGFzc0xvYWRlcjo6Y2xhc3MpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyOwoKdXNlIENvbXBvc2VyXENvbmZpZ1xKc29uQ29uZmlnU291cmNlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBcmNoaXZlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uR3Vlc3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXFV0aWxcU2lsZW5jZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgU2VsZFxKc29uTGludFxEdXBsaWNhdGVLZXlFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJTdHlsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXQ7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnREaXNwYXRjaGVyOwp1c2UgQ29tcG9zZXJcQXV0b2xvYWRcQXV0b2xvYWRHZW5lcmF0b3I7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgU2VsZFxKc29uTGludFxKc29uUGFyc2VyOwoKLyoqCiAqIENyZWF0ZXMgYSBjb25maWd1cmVkIGluc3RhbmNlIG9mIGNvbXBvc2VyLgogKgogKiBAYXV0aG9yIFJ5YW4gV2VhdmVyIDxyeWFuQGtucGxhYnMuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgSWdvciBXaWVkbGVyIDxpZ29yQHdpZWRsZXIuY2g+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBGYWN0b3J5CnsKICAgIC8qKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRIb21lRGlyKCkKICAgIHsKICAgICAgICAkaG9tZSA9IGdldGVudignQ09NUE9TRVJfSE9NRScpOwogICAgICAgIGlmICgkaG9tZSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIGlmICghZ2V0ZW52KCdBUFBEQVRBJykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIEFQUERBVEEgb3IgQ09NUE9TRVJfSE9NRSBlbnZpcm9ubWVudCB2YXJpYWJsZSBtdXN0IGJlIHNldCBmb3IgY29tcG9zZXIgdG8gcnVuIGNvcnJlY3RseScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcnRyaW0oc3RydHIoZ2V0ZW52KCdBUFBEQVRBJyksICdcXCcsICcvJyksICcvJykgLiAnL0NvbXBvc2VyJzsKICAgICAgICB9CgogICAgICAgICR1c2VyRGlyID0gc2VsZjo6Z2V0VXNlckRpcigpOwogICAgICAgICRkaXJzID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKHNlbGY6OnVzZVhkZygpKSB7CiAgICAgICAgICAgIC8vIFhERyBCYXNlIERpcmVjdG9yeSBTcGVjaWZpY2F0aW9ucwogICAgICAgICAgICAkeGRnQ29uZmlnID0gZ2V0ZW52KCdYREdfQ09ORklHX0hPTUUnKTsKICAgICAgICAgICAgaWYgKCEkeGRnQ29uZmlnKSB7CiAgICAgICAgICAgICAgICAkeGRnQ29uZmlnID0gJHVzZXJEaXIgLiAnLy5jb25maWcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGlyc1tdID0gJHhkZ0NvbmZpZyAuICcvY29tcG9zZXInOwogICAgICAgIH0KCiAgICAgICAgJGRpcnNbXSA9ICR1c2VyRGlyIC4gJy8uY29tcG9zZXInOwoKICAgICAgICAvLyBzZWxlY3QgZmlyc3QgZGlyIHdoaWNoIGV4aXN0cyBvZjogJFhER19DT05GSUdfSE9NRS9jb21wb3NlciBvciB+Ly5jb21wb3NlcgogICAgICAgIGZvcmVhY2ggKCRkaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKFNpbGVuY2VyOjpjYWxsKCdpc19kaXInLCAkZGlyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkaXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGlmIG5vbmUgZXhpc3RzLCB3ZSBkZWZhdWx0IHRvIGZpcnN0IGRlZmluZWQgb25lIChYREcgb25lIGlmIHN5c3RlbSB1c2VzIGl0LCBvciB+Ly5jb21wb3NlciBvdGhlcndpc2UpCiAgICAgICAgcmV0dXJuICRkaXJzWzBdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJGhvbWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0Q2FjaGVEaXIoJGhvbWUpCiAgICB7CiAgICAgICAgJGNhY2hlRGlyID0gZ2V0ZW52KCdDT01QT1NFUl9DQUNIRV9ESVInKTsKICAgICAgICBpZiAoJGNhY2hlRGlyKSB7CiAgICAgICAgICAgIHJldHVybiAkY2FjaGVEaXI7CiAgICAgICAgfQoKICAgICAgICAkaG9tZUVudiA9IGdldGVudignQ09NUE9TRVJfSE9NRScpOwogICAgICAgIGlmICgkaG9tZUVudikgewogICAgICAgICAgICByZXR1cm4gJGhvbWVFbnYgLiAnL2NhY2hlJzsKICAgICAgICB9CgogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgaWYgKCRjYWNoZURpciA9IGdldGVudignTE9DQUxBUFBEQVRBJykpIHsKICAgICAgICAgICAgICAgICRjYWNoZURpciAuPSAnL0NvbXBvc2VyJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjYWNoZURpciA9ICRob21lIC4gJy9jYWNoZSc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBydHJpbShzdHJ0cigkY2FjaGVEaXIsICdcXCcsICcvJyksICcvJyk7CiAgICAgICAgfQoKICAgICAgICAkdXNlckRpciA9IHNlbGY6OmdldFVzZXJEaXIoKTsKICAgICAgICBpZiAoJGhvbWUgPT09ICR1c2VyRGlyIC4gJy8uY29tcG9zZXInICYmIGlzX2RpcigkaG9tZSAuICcvY2FjaGUnKSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWUgLiAnL2NhY2hlJzsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjp1c2VYZGcoKSkgewogICAgICAgICAgICAkeGRnQ2FjaGUgPSBnZXRlbnYoJ1hER19DQUNIRV9IT01FJykgPzogJHVzZXJEaXIgLiAnLy5jYWNoZSc7CgogICAgICAgICAgICByZXR1cm4gJHhkZ0NhY2hlIC4gJy9jb21wb3Nlcic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGhvbWUgLiAnL2NhY2hlJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRob21lCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldERhdGFEaXIoJGhvbWUpCiAgICB7CiAgICAgICAgJGhvbWVFbnYgPSBnZXRlbnYoJ0NPTVBPU0VSX0hPTUUnKTsKICAgICAgICBpZiAoJGhvbWVFbnYpIHsKICAgICAgICAgICAgcmV0dXJuICRob21lRW52OwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICByZXR1cm4gc3RydHIoJGhvbWUsICdcXCcsICcvJyk7CiAgICAgICAgfQoKICAgICAgICAkdXNlckRpciA9IHNlbGY6OmdldFVzZXJEaXIoKTsKICAgICAgICBpZiAoJGhvbWUgIT09ICR1c2VyRGlyIC4gJy8uY29tcG9zZXInICYmIHNlbGY6OnVzZVhkZygpKSB7CiAgICAgICAgICAgICR4ZGdEYXRhID0gZ2V0ZW52KCdYREdfREFUQV9IT01FJykgPzogJHVzZXJEaXIgLiAnLy5sb2NhbC9zaGFyZSc7CgogICAgICAgICAgICByZXR1cm4gJHhkZ0RhdGEgLiAnL2NvbXBvc2VyJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaG9tZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2V8bnVsbCAkaW8KICAgICAqIEByZXR1cm4gQ29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlQ29uZmlnKElPSW50ZXJmYWNlICRpbyA9IG51bGwsICRjd2QgPSBudWxsKQogICAgewogICAgICAgICRjd2QgPSAkY3dkID86IGdldGN3ZCgpOwoKICAgICAgICAkY29uZmlnID0gbmV3IENvbmZpZyh0cnVlLCAkY3dkKTsKCiAgICAgICAgLy8gZGV0ZXJtaW5lIGFuZCBhZGQgbWFpbiBkaXJzIHRvIHRoZSBjb25maWcKICAgICAgICAkaG9tZSA9IHNlbGY6OmdldEhvbWVEaXIoKTsKICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiBhcnJheSgKICAgICAgICAgICAgJ2hvbWUnID0+ICRob21lLAogICAgICAgICAgICAnY2FjaGUtZGlyJyA9PiBzZWxmOjpnZXRDYWNoZURpcigkaG9tZSksCiAgICAgICAgICAgICdkYXRhLWRpcicgPT4gc2VsZjo6Z2V0RGF0YURpcigkaG9tZSksCiAgICAgICAgKSkpOwoKICAgICAgICAvLyBsb2FkIGdsb2JhbCBjb25maWcKICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZSgkY29uZmlnLT5nZXQoJ2hvbWUnKS4nL2NvbmZpZy5qc29uJyk7CiAgICAgICAgaWYgKCRmaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICBpZiAoJGlvICYmICRpby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0xvYWRpbmcgY29uZmlnIGZpbGUgJyAuICRmaWxlLT5nZXRQYXRoKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjb25maWctPm1lcmdlKCRmaWxlLT5yZWFkKCkpOwogICAgICAgIH0KICAgICAgICAkY29uZmlnLT5zZXRDb25maWdTb3VyY2UobmV3IEpzb25Db25maWdTb3VyY2UoJGZpbGUpKTsKCiAgICAgICAgJGh0YWNjZXNzUHJvdGVjdCA9IChib29sKSAkY29uZmlnLT5nZXQoJ2h0YWNjZXNzLXByb3RlY3QnKTsKICAgICAgICBpZiAoJGh0YWNjZXNzUHJvdGVjdCkgewogICAgICAgICAgICAvLyBQcm90ZWN0IGRpcmVjdG9yeSBhZ2FpbnN0IHdlYiBhY2Nlc3MuIFNpbmNlIEhPTUUgY291bGQgYmUKICAgICAgICAgICAgLy8gdGhlIHd3dy1kYXRhJ3MgdXNlciBob21lIGFuZCBiZSB3ZWItYWNjZXNzaWJsZSBpdCBpcyBhCiAgICAgICAgICAgIC8vIHBvdGVudGlhbCBzZWN1cml0eSByaXNrCiAgICAgICAgICAgICRkaXJzID0gYXJyYXkoJGNvbmZpZy0+Z2V0KCdob21lJyksICRjb25maWctPmdldCgnY2FjaGUtZGlyJyksICRjb25maWctPmdldCgnZGF0YS1kaXInKSk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJGRpciAuICcvLmh0YWNjZXNzJykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2RpcigkZGlyKSkgewogICAgICAgICAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnbWtkaXInLCAkZGlyLCAwNzc3LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2ZpbGVfcHV0X2NvbnRlbnRzJywgJGRpciAuICcvLmh0YWNjZXNzJywgJ0RlbnkgZnJvbSBhbGwnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gbG9hZCBnbG9iYWwgYXV0aCBmaWxlCiAgICAgICAgJGZpbGUgPSBuZXcgSnNvbkZpbGUoJGNvbmZpZy0+Z2V0KCdob21lJykuJy9hdXRoLmpzb24nKTsKICAgICAgICBpZiAoJGZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIGlmICgkaW8gJiYgJGlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTG9hZGluZyBjb25maWcgZmlsZSAnIC4gJGZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvbmZpZy0+bWVyZ2UoYXJyYXkoJ2NvbmZpZycgPT4gJGZpbGUtPnJlYWQoKSkpOwogICAgICAgIH0KICAgICAgICAkY29uZmlnLT5zZXRBdXRoQ29uZmlnU291cmNlKG5ldyBKc29uQ29uZmlnU291cmNlKCRmaWxlLCB0cnVlKSk7CgogICAgICAgIC8vIGxvYWQgQ09NUE9TRVJfQVVUSCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpZiBzZXQKICAgICAgICBpZiAoJGNvbXBvc2VyQXV0aEVudiA9IGdldGVudignQ09NUE9TRVJfQVVUSCcpKSB7CiAgICAgICAgICAgICRhdXRoRGF0YSA9IGpzb25fZGVjb2RlKCRjb21wb3NlckF1dGhFbnYsIHRydWUpOwoKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRhdXRoRGF0YSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0NPTVBPU0VSX0FVVEggZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbWFsZm9ybWVkLCBzaG91bGQgYmUgYSB2YWxpZCBKU09OIG9iamVjdCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGlvICYmICRpby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0xvYWRpbmcgYXV0aCBjb25maWcgZnJvbSBDT01QT1NFUl9BVVRIJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvbmZpZy0+bWVyZ2UoYXJyYXkoJ2NvbmZpZycgPT4gJGF1dGhEYXRhKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbmZpZzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbXBvc2VyRmlsZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRyaW0oZ2V0ZW52KCdDT01QT1NFUicpKSA/OiAnLi9jb21wb3Nlci5qc29uJzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldExvY2tGaWxlKCRjb21wb3NlckZpbGUpCiAgICB7CiAgICAgICAgcmV0dXJuICJqc29uIiA9PT0gcGF0aGluZm8oJGNvbXBvc2VyRmlsZSwgUEFUSElORk9fRVhURU5TSU9OKQogICAgICAgICAgICAgICAgPyBzdWJzdHIoJGNvbXBvc2VyRmlsZSwgMCwgLTQpLidsb2NrJwogICAgICAgICAgICAgICAgOiAkY29tcG9zZXJGaWxlIC4gJy5sb2NrJzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZUFkZGl0aW9uYWxTdHlsZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ2hpZ2hsaWdodCcgPT4gbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCdyZWQnKSwKICAgICAgICAgICAgJ3dhcm5pbmcnID0+IG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgnYmxhY2snLCAneWVsbG93JyksCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBDb25zb2xlT3V0cHV0IGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBDb25zb2xlT3V0cHV0CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlT3V0cHV0KCkKICAgIHsKICAgICAgICAkc3R5bGVzID0gc2VsZjo6Y3JlYXRlQWRkaXRpb25hbFN0eWxlcygpOwogICAgICAgICRmb3JtYXR0ZXIgPSBuZXcgT3V0cHV0Rm9ybWF0dGVyKGZhbHNlLCAkc3R5bGVzKTsKCiAgICAgICAgcmV0dXJuIG5ldyBDb25zb2xlT3V0cHV0KENvbnNvbGVPdXRwdXQ6OlZFUkJPU0lUWV9OT1JNQUwsIG51bGwsICRmb3JtYXR0ZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIENvbXBvc2VyIGluc3RhbmNlCiAgICAgKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAgICAgICAgICAgICAgICRpbyAgICAgICAgICAgICBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtICBhcnJheXxzdHJpbmd8bnVsbCAgICAgICAgICRsb2NhbENvbmZpZyAgICBlaXRoZXIgYSBjb25maWd1cmF0aW9uIGFycmF5IG9yIGEgZmlsZW5hbWUgdG8gcmVhZCBmcm9tLCBpZiBudWxsIGl0IHdpbGwKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZCBmcm9tIHRoZSBkZWZhdWx0IGZpbGVuYW1lCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAgJGRpc2FibGVQbHVnaW5zIFdoZXRoZXIgcGx1Z2lucyBzaG91bGQgbm90IGJlIGxvYWRlZAogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICRmdWxsTG9hZCAgICAgICBXaGV0aGVyIHRvIGluaXRpYWxpemUgZXZlcnl0aGluZyBvciBvbmx5IG1haW4gcHJvamVjdCBzdHVmZiAodXNlZCB3aGVuIGxvYWRpbmcgdGhlIGdsb2JhbCBjb21wb3NlcikKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVDb21wb3NlcihJT0ludGVyZmFjZSAkaW8sICRsb2NhbENvbmZpZyA9IG51bGwsICRkaXNhYmxlUGx1Z2lucyA9IGZhbHNlLCAkY3dkID0gbnVsbCwgJGZ1bGxMb2FkID0gdHJ1ZSkKICAgIHsKICAgICAgICAkY3dkID0gJGN3ZCA/OiBnZXRjd2QoKTsKCiAgICAgICAgLy8gbG9hZCBDb21wb3NlciBjb25maWd1cmF0aW9uCiAgICAgICAgaWYgKG51bGwgPT09ICRsb2NhbENvbmZpZykgewogICAgICAgICAgICAkbG9jYWxDb25maWcgPSBzdGF0aWM6OmdldENvbXBvc2VyRmlsZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX3N0cmluZygkbG9jYWxDb25maWcpKSB7CiAgICAgICAgICAgICRjb21wb3NlckZpbGUgPSAkbG9jYWxDb25maWc7CgogICAgICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZSgkbG9jYWxDb25maWcsIG51bGwsICRpbyk7CgogICAgICAgICAgICBpZiAoISRmaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgaWYgKCRsb2NhbENvbmZpZyA9PT0gJy4vY29tcG9zZXIuanNvbicgfHwgJGxvY2FsQ29uZmlnID09PSAnY29tcG9zZXIuanNvbicpIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDb21wb3NlciBjb3VsZCBub3QgZmluZCBhIGNvbXBvc2VyLmpzb24gZmlsZSBpbiAnLiRjd2Q7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0NvbXBvc2VyIGNvdWxkIG5vdCBmaW5kIHRoZSBjb25maWcgZmlsZTogJy4kbG9jYWxDb25maWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkaW5zdHJ1Y3Rpb25zID0gJGZ1bGxMb2FkID8gJ1RvIGluaXRpYWxpemUgYSBwcm9qZWN0LCBwbGVhc2UgY3JlYXRlIGEgY29tcG9zZXIuanNvbiBmaWxlIGFzIGRlc2NyaWJlZCBpbiB0aGUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvICJHZXR0aW5nIFN0YXJ0ZWQiIHNlY3Rpb24nIDogJyc7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigkbWVzc2FnZS5QSFBfRU9MLiRpbnN0cnVjdGlvbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZmlsZS0+dmFsaWRhdGVTY2hlbWEoSnNvbkZpbGU6OkxBWF9TQ0hFTUEpOwogICAgICAgICAgICAkanNvblBhcnNlciA9IG5ldyBKc29uUGFyc2VyOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGpzb25QYXJzZXItPnBhcnNlKGZpbGVfZ2V0X2NvbnRlbnRzKCRsb2NhbENvbmZpZyksIEpzb25QYXJzZXI6OkRFVEVDVF9LRVlfQ09ORkxJQ1RTKTsKICAgICAgICAgICAgfSBjYXRjaCAoRHVwbGljYXRlS2V5RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkZGV0YWlscyA9ICRlLT5nZXREZXRhaWxzKCk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPktleSAnLiRkZXRhaWxzWydrZXknXS4nIGlzIGEgZHVwbGljYXRlIGluICcuJGxvY2FsQ29uZmlnLicgYXQgbGluZSAnLiRkZXRhaWxzWydsaW5lJ10uJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxvY2FsQ29uZmlnID0gJGZpbGUtPnJlYWQoKTsKICAgICAgICB9CgogICAgICAgIC8vIExvYWQgY29uZmlnIGFuZCBvdmVycmlkZSB3aXRoIGxvY2FsIGNvbmZpZy9hdXRoIGNvbmZpZwogICAgICAgICRjb25maWcgPSBzdGF0aWM6OmNyZWF0ZUNvbmZpZygkaW8sICRjd2QpOwogICAgICAgICRjb25maWctPm1lcmdlKCRsb2NhbENvbmZpZyk7CiAgICAgICAgaWYgKGlzc2V0KCRjb21wb3NlckZpbGUpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTG9hZGluZyBjb25maWcgZmlsZSAnIC4gJGNvbXBvc2VyRmlsZSAuJyAoJy5yZWFscGF0aCgkY29tcG9zZXJGaWxlKS4nKScsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICRjb25maWctPnNldENvbmZpZ1NvdXJjZShuZXcgSnNvbkNvbmZpZ1NvdXJjZShuZXcgSnNvbkZpbGUocmVhbHBhdGgoJGNvbXBvc2VyRmlsZSksIG51bGwsICRpbykpKTsKCiAgICAgICAgICAgICRsb2NhbEF1dGhGaWxlID0gbmV3IEpzb25GaWxlKGRpcm5hbWUocmVhbHBhdGgoJGNvbXBvc2VyRmlsZSkpIC4gJy9hdXRoLmpzb24nLCBudWxsLCAkaW8pOwogICAgICAgICAgICBpZiAoJGxvY2FsQXV0aEZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0xvYWRpbmcgY29uZmlnIGZpbGUgJyAuICRsb2NhbEF1dGhGaWxlLT5nZXRQYXRoKCksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiAkbG9jYWxBdXRoRmlsZS0+cmVhZCgpKSk7CiAgICAgICAgICAgICAgICAkY29uZmlnLT5zZXRBdXRoQ29uZmlnU291cmNlKG5ldyBKc29uQ29uZmlnU291cmNlKCRsb2NhbEF1dGhGaWxlLCB0cnVlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR2ZW5kb3JEaXIgPSAkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKTsKCiAgICAgICAgLy8gaW5pdGlhbGl6ZSBjb21wb3NlcgogICAgICAgICRjb21wb3NlciA9IG5ldyBDb21wb3NlcigpOwogICAgICAgICRjb21wb3Nlci0+c2V0Q29uZmlnKCRjb25maWcpOwoKICAgICAgICBpZiAoJGZ1bGxMb2FkKSB7CiAgICAgICAgICAgIC8vIGxvYWQgYXV0aCBjb25maWdzIGludG8gdGhlIElPIGluc3RhbmNlCiAgICAgICAgICAgICRpby0+bG9hZENvbmZpZ3VyYXRpb24oJGNvbmZpZyk7CgogICAgICAgICAgICAvLyBsb2FkIGV4aXN0aW5nIENvbXBvc2VyXEluc3RhbGxlZFZlcnNpb25zIGluc3RhbmNlIGlmIGF2YWlsYWJsZQogICAgICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cygnQ29tcG9zZXJcSW5zdGFsbGVkVmVyc2lvbnMnLCBmYWxzZSkgJiYgZmlsZV9leGlzdHMoJGluc3RhbGxlZFZlcnNpb25zUGF0aCA9ICRjb25maWctPmdldCgndmVuZG9yLWRpcicpLicvY29tcG9zZXIvSW5zdGFsbGVkVmVyc2lvbnMucGhwJykpIHsKICAgICAgICAgICAgICAgIGluY2x1ZGUgJGluc3RhbGxlZFZlcnNpb25zUGF0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGh0dHBEb3dubG9hZGVyID0gc2VsZjo6Y3JlYXRlSHR0cERvd25sb2FkZXIoJGlvLCAkY29uZmlnKTsKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkbG9vcCA9IG5ldyBMb29wKCRodHRwRG93bmxvYWRlciwgJHByb2Nlc3MpOwogICAgICAgICRjb21wb3Nlci0+c2V0TG9vcCgkbG9vcCk7CgogICAgICAgIC8vIGluaXRpYWxpemUgZXZlbnQgZGlzcGF0Y2hlcgogICAgICAgICRkaXNwYXRjaGVyID0gbmV3IEV2ZW50RGlzcGF0Y2hlcigkY29tcG9zZXIsICRpbywgJHByb2Nlc3MpOwogICAgICAgICRjb21wb3Nlci0+c2V0RXZlbnREaXNwYXRjaGVyKCRkaXNwYXRjaGVyKTsKCiAgICAgICAgLy8gaW5pdGlhbGl6ZSByZXBvc2l0b3J5IG1hbmFnZXIKICAgICAgICAkcm0gPSBSZXBvc2l0b3J5RmFjdG9yeTo6bWFuYWdlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGRpc3BhdGNoZXIsICRwcm9jZXNzKTsKICAgICAgICAkY29tcG9zZXItPnNldFJlcG9zaXRvcnlNYW5hZ2VyKCRybSk7CgogICAgICAgIC8vIGZvcmNlLXNldCB0aGUgdmVyc2lvbiBvZiB0aGUgZ2xvYmFsIHBhY2thZ2UgaWYgbm90IGRlZmluZWQgYXMKICAgICAgICAvLyBndWVzc2luZyBpdCBhZGRzIG5vIHZhbHVlIGFuZCBvbmx5IHRha2VzIHRpbWUKICAgICAgICBpZiAoISRmdWxsTG9hZCAmJiAhaXNzZXQoJGxvY2FsQ29uZmlnWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICRsb2NhbENvbmZpZ1sndmVyc2lvbiddID0gJzEuMC4wJzsKICAgICAgICB9CgogICAgICAgIC8vIGxvYWQgcGFja2FnZQogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZ3Vlc3NlciA9IG5ldyBWZXJzaW9uR3Vlc3NlcigkY29uZmlnLCAkcHJvY2VzcywgJHBhcnNlcik7CiAgICAgICAgJGxvYWRlciA9ICR0aGlzLT5sb2FkUm9vdFBhY2thZ2UoJHJtLCAkY29uZmlnLCAkcGFyc2VyLCAkZ3Vlc3NlciwgJGlvKTsKICAgICAgICAkcGFja2FnZSA9ICRsb2FkZXItPmxvYWQoJGxvY2FsQ29uZmlnLCAnQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZScsICRjd2QpOwogICAgICAgICRjb21wb3Nlci0+c2V0UGFja2FnZSgkcGFja2FnZSk7CgogICAgICAgIC8vIGxvYWQgbG9jYWwgcmVwb3NpdG9yeQogICAgICAgICR0aGlzLT5hZGRMb2NhbFJlcG9zaXRvcnkoJGlvLCAkcm0sICR2ZW5kb3JEaXIsICRwYWNrYWdlKTsKCiAgICAgICAgLy8gaW5pdGlhbGl6ZSBpbnN0YWxsYXRpb24gbWFuYWdlcgogICAgICAgICRpbSA9ICR0aGlzLT5jcmVhdGVJbnN0YWxsYXRpb25NYW5hZ2VyKCRsb29wLCAkaW8sICRkaXNwYXRjaGVyKTsKICAgICAgICAkY29tcG9zZXItPnNldEluc3RhbGxhdGlvbk1hbmFnZXIoJGltKTsKCiAgICAgICAgaWYgKCRmdWxsTG9hZCkgewogICAgICAgICAgICAvLyBpbml0aWFsaXplIGRvd25sb2FkIG1hbmFnZXIKICAgICAgICAgICAgJGRtID0gJHRoaXMtPmNyZWF0ZURvd25sb2FkTWFuYWdlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJHByb2Nlc3MsICRkaXNwYXRjaGVyKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5zZXREb3dubG9hZE1hbmFnZXIoJGRtKTsKCiAgICAgICAgICAgIC8vIGluaXRpYWxpemUgYXV0b2xvYWQgZ2VuZXJhdG9yCiAgICAgICAgICAgICRnZW5lcmF0b3IgPSBuZXcgQXV0b2xvYWRHZW5lcmF0b3IoJGRpc3BhdGNoZXIsICRpbyk7CiAgICAgICAgICAgICRjb21wb3Nlci0+c2V0QXV0b2xvYWRHZW5lcmF0b3IoJGdlbmVyYXRvcik7CgogICAgICAgICAgICAvLyBpbml0aWFsaXplIGFyY2hpdmUgbWFuYWdlcgogICAgICAgICAgICAkYW0gPSAkdGhpcy0+Y3JlYXRlQXJjaGl2ZU1hbmFnZXIoJGNvbmZpZywgJGRtLCAkbG9vcCk7CiAgICAgICAgICAgICRjb21wb3Nlci0+c2V0QXJjaGl2ZU1hbmFnZXIoJGFtKTsKICAgICAgICB9CgogICAgICAgIC8vIGFkZCBpbnN0YWxsZXJzIHRvIHRoZSBtYW5hZ2VyIChtdXN0IGhhcHBlbiBhZnRlciBkb3dubG9hZCBtYW5hZ2VyIGlzIGNyZWF0ZWQgc2luY2UgdGhleSByZWFkIGl0IG91dCBvZiAkY29tcG9zZXIpCiAgICAgICAgJHRoaXMtPmNyZWF0ZURlZmF1bHRJbnN0YWxsZXJzKCRpbSwgJGNvbXBvc2VyLCAkaW8sICRwcm9jZXNzKTsKCiAgICAgICAgaWYgKCRmdWxsTG9hZCkgewogICAgICAgICAgICAkZ2xvYmFsQ29tcG9zZXIgPSBudWxsOwogICAgICAgICAgICBpZiAocmVhbHBhdGgoJGNvbmZpZy0+Z2V0KCdob21lJykpICE9PSAkY3dkKSB7CiAgICAgICAgICAgICAgICAkZ2xvYmFsQ29tcG9zZXIgPSAkdGhpcy0+Y3JlYXRlR2xvYmFsQ29tcG9zZXIoJGlvLCAkY29uZmlnLCAkZGlzYWJsZVBsdWdpbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcG0gPSAkdGhpcy0+Y3JlYXRlUGx1Z2luTWFuYWdlcigkaW8sICRjb21wb3NlciwgJGdsb2JhbENvbXBvc2VyLCAkZGlzYWJsZVBsdWdpbnMpOwogICAgICAgICAgICAkY29tcG9zZXItPnNldFBsdWdpbk1hbmFnZXIoJHBtKTsKCiAgICAgICAgICAgICRwbS0+bG9hZEluc3RhbGxlZFBsdWdpbnMoKTsKICAgICAgICB9CgogICAgICAgIC8vIGluaXQgbG9ja2VyIGlmIHBvc3NpYmxlCiAgICAgICAgaWYgKCRmdWxsTG9hZCAmJiBpc3NldCgkY29tcG9zZXJGaWxlKSkgewogICAgICAgICAgICAkbG9ja0ZpbGUgPSBzZWxmOjpnZXRMb2NrRmlsZSgkY29tcG9zZXJGaWxlKTsKCiAgICAgICAgICAgICRsb2NrZXIgPSBuZXcgUGFja2FnZVxMb2NrZXIoJGlvLCBuZXcgSnNvbkZpbGUoJGxvY2tGaWxlLCBudWxsLCAkaW8pLCAkaW0sIGZpbGVfZ2V0X2NvbnRlbnRzKCRjb21wb3NlckZpbGUpLCAkcHJvY2Vzcyk7CiAgICAgICAgICAgICRjb21wb3Nlci0+c2V0TG9ja2VyKCRsb2NrZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRmdWxsTG9hZCkgewogICAgICAgICAgICAkaW5pdEV2ZW50ID0gbmV3IEV2ZW50KFBsdWdpbkV2ZW50czo6SU5JVCk7CiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoKCRpbml0RXZlbnQtPmdldE5hbWUoKSwgJGluaXRFdmVudCk7CgogICAgICAgICAgICAvLyBvbmNlIGV2ZXJ5dGhpbmcgaXMgaW5pdGlhbGl6ZWQgd2UgY2FuCiAgICAgICAgICAgIC8vIHB1cmdlIHBhY2thZ2VzIGZyb20gbG9jYWwgcmVwb3MgaWYgdGhleSBoYXZlIGJlZW4gZGVsZXRlZCBvbiB0aGUgZmlsZXN5c3RlbQogICAgICAgICAgICBpZiAoJHJtLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnB1cmdlUGFja2FnZXMoJHJtLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSwgJGltKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAkaW8gICAgICAgICAgICAgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAkZGlzYWJsZVBsdWdpbnMgV2hldGhlciBwbHVnaW5zIHNob3VsZCBub3QgYmUgbG9hZGVkCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVHbG9iYWwoSU9JbnRlcmZhY2UgJGlvLCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkZmFjdG9yeSA9IG5ldyBzdGF0aWMoKTsKCiAgICAgICAgcmV0dXJuICRmYWN0b3J5LT5jcmVhdGVHbG9iYWxDb21wb3NlcigkaW8sIHN0YXRpYzo6Y3JlYXRlQ29uZmlnKCRpbyksICRkaXNhYmxlUGx1Z2lucywgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeVxSZXBvc2l0b3J5TWFuYWdlciAkcm0KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICR2ZW5kb3JEaXIKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZExvY2FsUmVwb3NpdG9yeShJT0ludGVyZmFjZSAkaW8sIFJlcG9zaXRvcnlNYW5hZ2VyICRybSwgJHZlbmRvckRpciwgUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlKQogICAgewogICAgICAgICRybS0+c2V0TG9jYWxSZXBvc2l0b3J5KG5ldyBSZXBvc2l0b3J5XEluc3RhbGxlZEZpbGVzeXN0ZW1SZXBvc2l0b3J5KG5ldyBKc29uRmlsZSgkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLmpzb24nLCBudWxsLCAkaW8pLCB0cnVlLCAkcm9vdFBhY2thZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgICAkY29uZmlnCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZUdsb2JhbENvbXBvc2VyKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRkaXNhYmxlUGx1Z2lucywgJGZ1bGxMb2FkID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Y3JlYXRlQ29tcG9zZXIoJGlvLCAkY29uZmlnLT5nZXQoJ2hvbWUnKSAuICcvY29tcG9zZXIuanNvbicsICRkaXNhYmxlUGx1Z2lucywgJGNvbmZpZy0+Z2V0KCdob21lJyksICRmdWxsTG9hZCk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIGdsb2JhbCBjb21wb3NlcjogJy4kZS0+Z2V0TWVzc2FnZSgpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9cSU9JbnRlcmZhY2UgICAgICAgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSAgRXZlbnREaXNwYXRjaGVyICAgICAgICAgICAgJGV2ZW50RGlzcGF0Y2hlcgogICAgICogQHJldHVybiBEb3dubG9hZGVyXERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlRG93bmxvYWRNYW5hZ2VyKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwpCiAgICB7CiAgICAgICAgJGNhY2hlID0gbnVsbDsKICAgICAgICBpZiAoJGNvbmZpZy0+Z2V0KCdjYWNoZS1maWxlcy10dGwnKSA+IDApIHsKICAgICAgICAgICAgJGNhY2hlID0gbmV3IENhY2hlKCRpbywgJGNvbmZpZy0+Z2V0KCdjYWNoZS1maWxlcy1kaXInKSwgJ2EtejAtOV8uLycpOwogICAgICAgICAgICAkY2FjaGUtPnNldFJlYWRPbmx5KCRjb25maWctPmdldCgnY2FjaGUtcmVhZC1vbmx5JykpOwogICAgICAgIH0KCiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oJHByb2Nlc3MpOwoKICAgICAgICAkZG0gPSBuZXcgRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXIoJGlvLCBmYWxzZSwgJGZzKTsKICAgICAgICBzd2l0Y2ggKCRwcmVmZXJyZWQgPSAkY29uZmlnLT5nZXQoJ3ByZWZlcnJlZC1pbnN0YWxsJykpIHsKICAgICAgICAgICAgY2FzZSAnZGlzdCc6CiAgICAgICAgICAgICAgICAkZG0tPnNldFByZWZlckRpc3QodHJ1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnc291cmNlJzoKICAgICAgICAgICAgICAgICRkbS0+c2V0UHJlZmVyU291cmNlKHRydWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2F1dG8nOgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gbm9vcAogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfYXJyYXkoJHByZWZlcnJlZCkpIHsKICAgICAgICAgICAgJGRtLT5zZXRQcmVmZXJlbmNlcygkcHJlZmVycmVkKTsKICAgICAgICB9CgogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcignZ2l0JywgbmV3IERvd25sb2FkZXJcR2l0RG93bmxvYWRlcigkaW8sICRjb25maWcsICRwcm9jZXNzLCAkZnMpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ3N2bicsIG5ldyBEb3dubG9hZGVyXFN2bkRvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkcHJvY2VzcywgJGZzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdmb3NzaWwnLCBuZXcgRG93bmxvYWRlclxGb3NzaWxEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJHByb2Nlc3MsICRmcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcignaGcnLCBuZXcgRG93bmxvYWRlclxIZ0Rvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkcHJvY2VzcywgJGZzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdwZXJmb3JjZScsIG5ldyBEb3dubG9hZGVyXFBlcmZvcmNlRG93bmxvYWRlcigkaW8sICRjb25maWcsICRwcm9jZXNzLCAkZnMpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ3ppcCcsIG5ldyBEb3dubG9hZGVyXFppcERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcigncmFyJywgbmV3IERvd25sb2FkZXJcUmFyRG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCd0YXInLCBuZXcgRG93bmxvYWRlclxUYXJEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkZXZlbnREaXNwYXRjaGVyLCAkY2FjaGUsICRmcywgJHByb2Nlc3MpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ2d6aXAnLCBuZXcgRG93bmxvYWRlclxHemlwRG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCd4eicsIG5ldyBEb3dubG9hZGVyXFh6RG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CiAgICAgICAgJGRtLT5zZXREb3dubG9hZGVyKCdwaGFyJywgbmV3IERvd25sb2FkZXJcUGhhckRvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXIsICRldmVudERpc3BhdGNoZXIsICRjYWNoZSwgJGZzLCAkcHJvY2VzcykpOwogICAgICAgICRkbS0+c2V0RG93bmxvYWRlcignZmlsZScsIG5ldyBEb3dubG9hZGVyXEZpbGVEb3dubG9hZGVyKCRpbywgJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyLCAkZXZlbnREaXNwYXRjaGVyLCAkY2FjaGUsICRmcywgJHByb2Nlc3MpKTsKICAgICAgICAkZG0tPnNldERvd25sb2FkZXIoJ3BhdGgnLCBuZXcgRG93bmxvYWRlclxQYXRoRG93bmxvYWRlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJGNhY2hlLCAkZnMsICRwcm9jZXNzKSk7CgogICAgICAgIHJldHVybiAkZG07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICAgICAgICAgICAgICRjb25maWcgVGhlIGNvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSAgRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXIgJGRtICAgICBNYW5hZ2VyIHVzZSB0byBkb3dubG9hZCBzb3VyY2VzCiAgICAgKiBAcmV0dXJuIEFyY2hpdmVyXEFyY2hpdmVNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVBcmNoaXZlTWFuYWdlcihDb25maWcgJGNvbmZpZywgRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXIgJGRtLCBMb29wICRsb29wKQogICAgewogICAgICAgICRhbSA9IG5ldyBBcmNoaXZlclxBcmNoaXZlTWFuYWdlcigkZG0sICRsb29wKTsKICAgICAgICAkYW0tPmFkZEFyY2hpdmVyKG5ldyBBcmNoaXZlclxaaXBBcmNoaXZlcik7CiAgICAgICAgJGFtLT5hZGRBcmNoaXZlcihuZXcgQXJjaGl2ZXJcUGhhckFyY2hpdmVyKTsKCiAgICAgICAgcmV0dXJuICRhbTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbXBvc2VyICAgICAgICAgICAgICRjb21wb3NlcgogICAgICogQHBhcmFtICBDb21wb3NlciAgICAgICAgICAgICAkZ2xvYmFsQ29tcG9zZXIKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgJGRpc2FibGVQbHVnaW5zCiAgICAgKiBAcmV0dXJuIFBsdWdpblxQbHVnaW5NYW5hZ2VyCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVQbHVnaW5NYW5hZ2VyKElPSW50ZXJmYWNlICRpbywgQ29tcG9zZXIgJGNvbXBvc2VyLCBDb21wb3NlciAkZ2xvYmFsQ29tcG9zZXIgPSBudWxsLCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZSkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFBsdWdpblxQbHVnaW5NYW5hZ2VyKCRpbywgJGNvbXBvc2VyLCAkZ2xvYmFsQ29tcG9zZXIsICRkaXNhYmxlUGx1Z2lucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVJbnN0YWxsYXRpb25NYW5hZ2VyKExvb3AgJGxvb3AsIElPSW50ZXJmYWNlICRpbywgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBuZXcgSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXIoJGxvb3AsICRpbywgJGV2ZW50RGlzcGF0Y2hlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXIgJGltCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyCiAgICAgKiBAcGFyYW0gSU9cSU9JbnRlcmZhY2UgICAgICAgICAgICAgICAgJGlvCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0SW5zdGFsbGVycyhJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlciAkaW0sIENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKICAgICAgICAkYmluYXJ5SW5zdGFsbGVyID0gbmV3IEluc3RhbGxlclxCaW5hcnlJbnN0YWxsZXIoJGlvLCBydHJpbSgkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2Jpbi1kaXInKSwgJy8nKSwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdiaW4tY29tcGF0JyksICRmcyk7CgogICAgICAgICRpbS0+YWRkSW5zdGFsbGVyKG5ldyBJbnN0YWxsZXJcTGlicmFyeUluc3RhbGxlcigkaW8sICRjb21wb3NlciwgbnVsbCwgJGZzLCAkYmluYXJ5SW5zdGFsbGVyKSk7CiAgICAgICAgJGltLT5hZGRJbnN0YWxsZXIobmV3IEluc3RhbGxlclxQbHVnaW5JbnN0YWxsZXIoJGlvLCAkY29tcG9zZXIsICRmcywgJGJpbmFyeUluc3RhbGxlcikpOwogICAgICAgICRpbS0+YWRkSW5zdGFsbGVyKG5ldyBJbnN0YWxsZXJcTWV0YXBhY2thZ2VJbnN0YWxsZXIoJGlvKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlICAgJHJlcG8gcmVwb3NpdG9yeSB0byBwdXJnZSBwYWNrYWdlcyBmcm9tCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXIgJGltICAgbWFuYWdlciB0byBjaGVjayB3aGV0aGVyIHBhY2thZ2VzIGFyZSBzdGlsbCBpbnN0YWxsZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHB1cmdlUGFja2FnZXMoV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlciAkaW0pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCEkaW0tPmlzUGFja2FnZUluc3RhbGxlZCgkcmVwbywgJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAkcmVwby0+cmVtb3ZlUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxvYWRSb290UGFja2FnZShSZXBvc2l0b3J5TWFuYWdlciAkcm0sIENvbmZpZyAkY29uZmlnLCBWZXJzaW9uUGFyc2VyICRwYXJzZXIsIFZlcnNpb25HdWVzc2VyICRndWVzc2VyLCBJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBQYWNrYWdlXExvYWRlclxSb290UGFja2FnZUxvYWRlcigkcm0sICRjb25maWcsICRwYXJzZXIsICRndWVzc2VyLCAkaW8pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAkaW8gICAgICAgICAgICAgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgbWl4ZWQgICAgICAgJGNvbmZpZyAgICAgICAgIGVpdGhlciBhIGNvbmZpZ3VyYXRpb24gYXJyYXkgb3IgYSBmaWxlbmFtZSB0byByZWFkIGZyb20sIGlmIG51bGwgaXQgd2lsbCByZWFkIGZyb20KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkZWZhdWx0IGZpbGVuYW1lCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICRkaXNhYmxlUGx1Z2lucyBXaGV0aGVyIHBsdWdpbnMgc2hvdWxkIG5vdCBiZSBsb2FkZWQKICAgICAqIEByZXR1cm4gQ29tcG9zZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGUoSU9JbnRlcmZhY2UgJGlvLCAkY29uZmlnID0gbnVsbCwgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGZhY3RvcnkgPSBuZXcgc3RhdGljKCk7CgogICAgICAgIHJldHVybiAkZmFjdG9yeS0+Y3JlYXRlQ29tcG9zZXIoJGlvLCAkY29uZmlnLCAkZGlzYWJsZVBsdWdpbnMpOwogICAgfQoKICAgIC8qKgogICAgICogSWYgeW91IGFyZSBjYWxsaW5nIHRoaXMgaW4gYSBwbHVnaW4sIHlvdSBwcm9iYWJseSBzaG91bGQgaW5zdGVhZCB1c2UgJGNvbXBvc2VyLT5nZXRMb29wKCktPmdldEh0dHBEb3dubG9hZGVyKCkKICAgICAqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgICRpbyAgICAgIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICRjb25maWcgIENvbmZpZyBpbnN0YW5jZQogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAkb3B0aW9ucyBBcnJheSBvZiBvcHRpb25zIHBhc3NlZCBkaXJlY3RseSB0byBIdHRwRG93bmxvYWRlciBjb25zdHJ1Y3RvcgogICAgICogQHJldHVybiBIdHRwRG93bmxvYWRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZUh0dHBEb3dubG9hZGVyKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBzdGF0aWMgJHdhcm5lZCA9IGZhbHNlOwogICAgICAgICRkaXNhYmxlVGxzID0gZmFsc2U7CiAgICAgICAgLy8gYWxsb3cgcnVubmluZyB0aGUgY29uZmlnIGNvbW1hbmQgaWYgZGlzYWJsZS10bHMgaXMgaW4gdGhlIGFyZyBsaXN0LCBldmVuIGlmIG9wZW5zc2wgaXMgbWlzc2luZywgdG8gYWxsb3cgZGlzYWJsaW5nIGl0IHZpYSB0aGUgY29uZmlnIGNvbW1hbmQKICAgICAgICBpZiAoaXNzZXQoJF9TRVJWRVJbJ2FyZ3YnXSkgJiYgaW5fYXJyYXkoJ2Rpc2FibGUtdGxzJywgJF9TRVJWRVJbJ2FyZ3YnXSkgJiYgKGluX2FycmF5KCdjb25mJywgJF9TRVJWRVJbJ2FyZ3YnXSkgfHwgaW5fYXJyYXkoJ2NvbmZpZycsICRfU0VSVkVSWydhcmd2J10pKSkgewogICAgICAgICAgICAkd2FybmVkID0gdHJ1ZTsKICAgICAgICAgICAgJGRpc2FibGVUbHMgPSAhZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpOwogICAgICAgIH0gZWxzZWlmICgkY29uZmlnICYmICRjb25maWctPmdldCgnZGlzYWJsZS10bHMnKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICBpZiAoISR3YXJuZWQpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSBydW5uaW5nIENvbXBvc2VyIHdpdGggU1NML1RMUyBwcm90ZWN0aW9uIGRpc2FibGVkLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkd2FybmVkID0gdHJ1ZTsKICAgICAgICAgICAgJGRpc2FibGVUbHMgPSB0cnVlOwogICAgICAgIH0gZWxzZWlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb25cTm9Tc2xFeGNlcHRpb24oJ1RoZSBvcGVuc3NsIGV4dGVuc2lvbiBpcyByZXF1aXJlZCBmb3IgU1NML1RMUyBwcm90ZWN0aW9uIGJ1dCBpcyBub3QgYXZhaWxhYmxlLiAnCiAgICAgICAgICAgICAgICAuICdJZiB5b3UgY2FuIG5vdCBlbmFibGUgdGhlIG9wZW5zc2wgZXh0ZW5zaW9uLCB5b3UgY2FuIGRpc2FibGUgdGhpcyBlcnJvciwgYXQgeW91ciBvd24gcmlzaywgYnkgc2V0dGluZyB0aGUgXCdkaXNhYmxlLXRsc1wnIG9wdGlvbiB0byB0cnVlLicpOwogICAgICAgIH0KICAgICAgICAkaHR0cERvd25sb2FkZXJPcHRpb25zID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGRpc2FibGVUbHMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICgkY29uZmlnICYmICRjb25maWctPmdldCgnY2FmaWxlJykpIHsKICAgICAgICAgICAgICAgICRodHRwRG93bmxvYWRlck9wdGlvbnNbJ3NzbCddWydjYWZpbGUnXSA9ICRjb25maWctPmdldCgnY2FmaWxlJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRjb25maWcgJiYgJGNvbmZpZy0+Z2V0KCdjYXBhdGgnKSkgewogICAgICAgICAgICAgICAgJGh0dHBEb3dubG9hZGVyT3B0aW9uc1snc3NsJ11bJ2NhcGF0aCddID0gJGNvbmZpZy0+Z2V0KCdjYXBhdGgnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaHR0cERvd25sb2FkZXJPcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJGh0dHBEb3dubG9hZGVyT3B0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICAkaHR0cERvd25sb2FkZXIgPSBuZXcgSHR0cERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkaHR0cERvd25sb2FkZXJPcHRpb25zLCAkZGlzYWJsZVRscyk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCRlLT5nZXRNZXNzYWdlKCksICdjYWZpbGUnKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGVycm9yPlVuYWJsZSB0byBsb2NhdGUgYSB2YWxpZCBDQSBjZXJ0aWZpY2F0ZSBmaWxlLiBZb3UgbXVzdCBzZXQgYSB2YWxpZCBcJ2NhZmlsZVwnIG9wdGlvbi48L2Vycm9yPicpOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGVycm9yPkEgdmFsaWQgQ0EgY2VydGlmaWNhdGUgZmlsZSBpcyByZXF1aXJlZCBmb3IgU1NML1RMUyBwcm90ZWN0aW9uLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDYwMCkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5JdCBpcyByZWNvbW1lbmRlZCB5b3UgdXBncmFkZSB0byBQSFAgNS42KyB3aGljaCBjYW4gZGV0ZWN0IHlvdXIgc3lzdGVtIENBIGZpbGUgYXV0b21hdGljYWxseS48L2Vycm9yPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGVycm9yPllvdSBjYW4gZGlzYWJsZSB0aGlzIGVycm9yLCBhdCB5b3VyIG93biByaXNrLCBieSBzZXR0aW5nIHRoZSBcJ2Rpc2FibGUtdGxzXCcgb3B0aW9uIHRvIHRydWUuPC9lcnJvcj4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaHR0cERvd25sb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdXNlWGRnKCkKICAgIHsKICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKCRfU0VSVkVSKSBhcyAka2V5KSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGtleSwgJ1hER18nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChTaWxlbmNlcjo6Y2FsbCgnaXNfZGlyJywgJy9ldGMveGRnJykpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRVc2VyRGlyKCkKICAgIHsKICAgICAgICAkaG9tZSA9IGdldGVudignSE9NRScpOwogICAgICAgIGlmICghJGhvbWUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgSE9NRSBvciBDT01QT1NFUl9IT01FIGVudmlyb25tZW50IHZhcmlhYmxlIG11c3QgYmUgc2V0IGZvciBjb21wb3NlciB0byBydW4gY29ycmVjdGx5Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcnRyaW0oc3RydHIoJGhvbWUsICdcXCcsICcvJyksICcvJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnXENvbmZpZ1NvdXJjZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ29uZmlnCnsKICAgIGNvbnN0IFJFTEFUSVZFX1BBVEhTID0gMTsKCiAgICBwdWJsaWMgc3RhdGljICRkZWZhdWx0Q29uZmlnID0gYXJyYXkoCiAgICAgICAgJ3Byb2Nlc3MtdGltZW91dCcgPT4gMzAwLAogICAgICAgICd1c2UtaW5jbHVkZS1wYXRoJyA9PiBmYWxzZSwKICAgICAgICAncHJlZmVycmVkLWluc3RhbGwnID0+ICdhdXRvJywKICAgICAgICAnbm90aWZ5LW9uLWluc3RhbGwnID0+IHRydWUsCiAgICAgICAgJ2dpdGh1Yi1wcm90b2NvbHMnID0+IGFycmF5KCdodHRwcycsICdzc2gnLCAnZ2l0JyksCiAgICAgICAgJ3ZlbmRvci1kaXInID0+ICd2ZW5kb3InLAogICAgICAgICdiaW4tZGlyJyA9PiAneyR2ZW5kb3ItZGlyfS9iaW4nLAogICAgICAgICdjYWNoZS1kaXInID0+ICd7JGhvbWV9L2NhY2hlJywKICAgICAgICAnZGF0YS1kaXInID0+ICd7JGhvbWV9JywKICAgICAgICAnY2FjaGUtZmlsZXMtZGlyJyA9PiAneyRjYWNoZS1kaXJ9L2ZpbGVzJywKICAgICAgICAnY2FjaGUtcmVwby1kaXInID0+ICd7JGNhY2hlLWRpcn0vcmVwbycsCiAgICAgICAgJ2NhY2hlLXZjcy1kaXInID0+ICd7JGNhY2hlLWRpcn0vdmNzJywKICAgICAgICAnY2FjaGUtdHRsJyA9PiAxNTU1MjAwMCwgLy8gNiBtb250aHMKICAgICAgICAnY2FjaGUtZmlsZXMtdHRsJyA9PiBudWxsLCAvLyBmYWxsYmFjayB0byBjYWNoZS10dGwKICAgICAgICAnY2FjaGUtZmlsZXMtbWF4c2l6ZScgPT4gJzMwME1pQicsCiAgICAgICAgJ2NhY2hlLXJlYWQtb25seScgPT4gZmFsc2UsCiAgICAgICAgJ2Jpbi1jb21wYXQnID0+ICdhdXRvJywKICAgICAgICAnZGlzY2FyZC1jaGFuZ2VzJyA9PiBmYWxzZSwKICAgICAgICAnYXV0b2xvYWRlci1zdWZmaXgnID0+IG51bGwsCiAgICAgICAgJ3NvcnQtcGFja2FnZXMnID0+IGZhbHNlLAogICAgICAgICdvcHRpbWl6ZS1hdXRvbG9hZGVyJyA9PiBmYWxzZSwKICAgICAgICAnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScgPT4gZmFsc2UsCiAgICAgICAgJ2FwY3UtYXV0b2xvYWRlcicgPT4gZmFsc2UsCiAgICAgICAgJ3ByZXBlbmQtYXV0b2xvYWRlcicgPT4gdHJ1ZSwKICAgICAgICAnZ2l0aHViLWRvbWFpbnMnID0+IGFycmF5KCdnaXRodWIuY29tJyksCiAgICAgICAgJ2JpdGJ1Y2tldC1leHBvc2UtaG9zdG5hbWUnID0+IHRydWUsCiAgICAgICAgJ2Rpc2FibGUtdGxzJyA9PiBmYWxzZSwKICAgICAgICAnc2VjdXJlLWh0dHAnID0+IHRydWUsCiAgICAgICAgJ2NhZmlsZScgPT4gbnVsbCwKICAgICAgICAnY2FwYXRoJyA9PiBudWxsLAogICAgICAgICdnaXRodWItZXhwb3NlLWhvc3RuYW1lJyA9PiB0cnVlLAogICAgICAgICdnaXRsYWItZG9tYWlucycgPT4gYXJyYXkoJ2dpdGxhYi5jb20nKSwKICAgICAgICAnc3RvcmUtYXV0aHMnID0+ICdwcm9tcHQnLAogICAgICAgICdwbGF0Zm9ybScgPT4gYXJyYXkoKSwKICAgICAgICAnYXJjaGl2ZS1mb3JtYXQnID0+ICd0YXInLAogICAgICAgICdhcmNoaXZlLWRpcicgPT4gJy4nLAogICAgICAgICdodGFjY2Vzcy1wcm90ZWN0JyA9PiB0cnVlLAogICAgICAgICd1c2UtZ2l0aHViLWFwaScgPT4gdHJ1ZSwKICAgICAgICAnbG9jaycgPT4gdHJ1ZSwKICAgICAgICAncGxhdGZvcm0tY2hlY2snID0+ICdwaHAtb25seScsCiAgICAgICAgLy8gdmFsaWQga2V5cyB3aXRob3V0IGRlZmF1bHRzIChhdXRoIGNvbmZpZyBzdHVmZik6CiAgICAgICAgLy8gYml0YnVja2V0LW9hdXRoCiAgICAgICAgLy8gZ2l0aHViLW9hdXRoCiAgICAgICAgLy8gZ2l0bGFiLW9hdXRoCiAgICAgICAgLy8gZ2l0bGFiLXRva2VuCiAgICAgICAgLy8gaHR0cC1iYXNpYwogICAgICAgIC8vIGJlYXJlcgogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljICRkZWZhdWx0UmVwb3NpdG9yaWVzID0gYXJyYXkoCiAgICAgICAgJ3BhY2thZ2lzdC5vcmcnID0+IGFycmF5KAogICAgICAgICAgICAndHlwZScgPT4gJ2NvbXBvc2VyJywKICAgICAgICAgICAgJ3VybCcgPT4gJ2h0dHBzOi8vcmVwby5wYWNrYWdpc3Qub3JnJywKICAgICAgICApLAogICAgKTsKCiAgICBwcml2YXRlICRjb25maWc7CiAgICBwcml2YXRlICRiYXNlRGlyOwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yaWVzOwogICAgLyoqIEB2YXIgQ29uZmlnU291cmNlSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRjb25maWdTb3VyY2U7CiAgICAvKiogQHZhciBDb25maWdTb3VyY2VJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGF1dGhDb25maWdTb3VyY2U7CiAgICBwcml2YXRlICR1c2VFbnZpcm9ubWVudDsKICAgIHByaXZhdGUgJHdhcm5lZEhvc3RzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICAgJHVzZUVudmlyb25tZW50IFVzZSBDT01QT1NFUl8gZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHJlcGxhY2UgY29uZmlnIHNldHRpbmdzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyICAgICAgICBPcHRpb25hbCBiYXNlIGRpcmVjdG9yeSBvZiB0aGUgY29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXNlRW52aXJvbm1lbnQgPSB0cnVlLCAkYmFzZURpciA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gbG9hZCBkZWZhdWx0cwogICAgICAgICR0aGlzLT5jb25maWcgPSBzdGF0aWM6OiRkZWZhdWx0Q29uZmlnOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSBzdGF0aWM6OiRkZWZhdWx0UmVwb3NpdG9yaWVzOwogICAgICAgICR0aGlzLT51c2VFbnZpcm9ubWVudCA9IChib29sKSAkdXNlRW52aXJvbm1lbnQ7CiAgICAgICAgJHRoaXMtPmJhc2VEaXIgPSAkYmFzZURpcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmlnU291cmNlKENvbmZpZ1NvdXJjZUludGVyZmFjZSAkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UgPSAkc291cmNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25maWdTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uZmlnU291cmNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdXRoQ29uZmlnU291cmNlKENvbmZpZ1NvdXJjZUludGVyZmFjZSAkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5hdXRoQ29uZmlnU291cmNlID0gJHNvdXJjZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aENvbmZpZ1NvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hdXRoQ29uZmlnU291cmNlOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIG5ldyBjb25maWcgdmFsdWVzIHdpdGggdGhlIGV4aXN0aW5nIG9uZXMgKG92ZXJyaWRpbmcpCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRjb25maWcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1lcmdlKCRjb25maWcpCiAgICB7CiAgICAgICAgLy8gb3ZlcnJpZGUgZGVmYXVsdHMgd2l0aCBnaXZlbiBjb25maWcKICAgICAgICBpZiAoIWVtcHR5KCRjb25maWdbJ2NvbmZpZyddKSAmJiBpc19hcnJheSgkY29uZmlnWydjb25maWcnXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1snY29uZmlnJ10gYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGtleSwgYXJyYXkoJ2JpdGJ1Y2tldC1vYXV0aCcsICdnaXRodWItb2F1dGgnLCAnZ2l0bGFiLW9hdXRoJywgJ2dpdGxhYi10b2tlbicsICdodHRwLWJhc2ljJywgJ2JlYXJlcicpKSAmJiBpc3NldCgkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdbJGtleV0gPSBhcnJheV9tZXJnZSgkdGhpcy0+Y29uZmlnWyRrZXldLCAkdmFsKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgka2V5LCBhcnJheSgnZ2l0bGFiLWRvbWFpbnMnLCAnZ2l0aHViLWRvbWFpbnMnKSkgJiYgaXNzZXQoJHRoaXMtPmNvbmZpZ1ska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gYXJyYXlfdW5pcXVlKGFycmF5X21lcmdlKCR0aGlzLT5jb25maWdbJGtleV0sICR2YWwpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgncHJlZmVycmVkLWluc3RhbGwnID09PSAka2V5ICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWwpIHx8IGlzX2FycmF5KCR0aGlzLT5jb25maWdbJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHZhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWwgPSBhcnJheSgnKicgPT4gJHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1ska2V5XSA9IGFycmF5KCcqJyA9PiAkdGhpcy0+Y29uZmlnWyRrZXldKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnWyRrZXldID0gYXJyYXlfbWVyZ2UoJHRoaXMtPmNvbmZpZ1ska2V5XSwgJHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmdWxsIG1hdGNoIHBhdHRlcm4gbmVlZHMgdG8gYmUgbGFzdAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1ska2V5XVsnKiddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHdpbGRjYXJkID0gJHRoaXMtPmNvbmZpZ1ska2V5XVsnKiddOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1ska2V5XVsnKiddKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdbJGtleV1bJyonXSA9ICR3aWxkY2FyZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdbJGtleV0gPSAkdmFsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1ska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10pICYmIGlzX2FycmF5KCRjb25maWdbJ3JlcG9zaXRvcmllcyddKSkgewogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzID0gYXJyYXlfcmV2ZXJzZSgkdGhpcy0+cmVwb3NpdG9yaWVzLCB0cnVlKTsKICAgICAgICAgICAgJG5ld1JlcG9zID0gYXJyYXlfcmV2ZXJzZSgkY29uZmlnWydyZXBvc2l0b3JpZXMnXSwgdHJ1ZSk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRuZXdSZXBvcyBhcyAkbmFtZSA9PiAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAgICAgLy8gZGlzYWJsZSBhIHJlcG9zaXRvcnkgYnkgbmFtZQogICAgICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kaXNhYmxlUmVwb0J5TmFtZSgkbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gZGlzYWJsZSBhIHJlcG9zaXRvcnkgd2l0aCBhbiBhbm9ueW1vdXMgeyJuYW1lIjogZmFsc2V9IHJlcG8KICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkcmVwb3NpdG9yeSkgJiYgMSA9PT0gY291bnQoJHJlcG9zaXRvcnkpICYmIGZhbHNlID09PSBjdXJyZW50KCRyZXBvc2l0b3J5KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kaXNhYmxlUmVwb0J5TmFtZShrZXkoJHJlcG9zaXRvcnkpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBhdXRvLWRlYWN0aXZhdGUgdGhlIGRlZmF1bHQgcGFja2FnaXN0Lm9yZyByZXBvIGlmIGl0IGdldHMgcmVkZWZpbmVkCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlcG9zaXRvcnlbJ3R5cGUnXSwgJHJlcG9zaXRvcnlbJ3VybCddKSAmJiAkcmVwb3NpdG9yeVsndHlwZSddID09PSAnY29tcG9zZXInICYmIHByZWdfbWF0Y2goJ3teaHR0cHM/Oi8vKD86W2EtejAtOS0uXStcLik/cGFja2FnaXN0Lm9yZygvfCQpfScsICRyZXBvc2l0b3J5Wyd1cmwnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzYWJsZVJlcG9CeU5hbWUoJ3BhY2thZ2lzdC5vcmcnKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBzdG9yZSByZXBvCiAgICAgICAgICAgICAgICBpZiAoaXNfaW50KCRuYW1lKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXNbXSA9ICRyZXBvc2l0b3J5OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG5hbWUgPT09ICdwYWNrYWdpc3QnKSB7IC8vIEJDIHN1cHBvcnQgZm9yIGRlZmF1bHQgInBhY2thZ2lzdCIgbmFtZWQgcmVwbwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzWyRuYW1lIC4gJy5vcmcnXSA9ICRyZXBvc2l0b3J5OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXNbJG5hbWVdID0gJHJlcG9zaXRvcnk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSBhcnJheV9yZXZlcnNlKCR0aGlzLT5yZXBvc2l0b3JpZXMsIHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcmllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3JpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0dGluZwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGtleQogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAkZmxhZ3MgT3B0aW9ucyAoc2VlIGNsYXNzIGNvbnN0YW50cykKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgka2V5LCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgIHN3aXRjaCAoJGtleSkgewogICAgICAgICAgICAvLyBzdHJpbmdzL3BhdGhzIHdpdGggZW52IHZhciBhbmQgeyRyZWZzfSBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ3ZlbmRvci1kaXInOgogICAgICAgICAgICBjYXNlICdiaW4tZGlyJzoKICAgICAgICAgICAgY2FzZSAncHJvY2Vzcy10aW1lb3V0JzoKICAgICAgICAgICAgY2FzZSAnZGF0YS1kaXInOgogICAgICAgICAgICBjYXNlICdjYWNoZS1kaXInOgogICAgICAgICAgICBjYXNlICdjYWNoZS1maWxlcy1kaXInOgogICAgICAgICAgICBjYXNlICdjYWNoZS1yZXBvLWRpcic6CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLXZjcy1kaXInOgogICAgICAgICAgICBjYXNlICdjYWZpbGUnOgogICAgICAgICAgICBjYXNlICdjYXBhdGgnOgogICAgICAgICAgICAgICAgLy8gY29udmVydCBmb28tYmFyIHRvIENPTVBPU0VSX0ZPT19CQVIgYW5kIGNoZWNrIGlmIGl0IGV4aXN0cyBzaW5jZSBpdCBvdmVycmlkZXMgdGhlIGxvY2FsIGNvbmZpZwogICAgICAgICAgICAgICAgJGVudiA9ICdDT01QT1NFUl8nIC4gc3RydG91cHBlcihzdHJ0cigka2V5LCAnLScsICdfJykpOwoKICAgICAgICAgICAgICAgICR2YWwgPSAkdGhpcy0+Z2V0Q29tcG9zZXJFbnYoJGVudik7CiAgICAgICAgICAgICAgICAkdmFsID0gcnRyaW0oKHN0cmluZykgJHRoaXMtPnByb2Nlc3MoZmFsc2UgIT09ICR2YWwgPyAkdmFsIDogJHRoaXMtPmNvbmZpZ1ska2V5XSwgJGZsYWdzKSwgJy9cXCcpOwogICAgICAgICAgICAgICAgJHZhbCA9IFBsYXRmb3JtOjpleHBhbmRQYXRoKCR2YWwpOwoKICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJGtleSwgLTQpICE9PSAnLWRpcicpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gKCgkZmxhZ3MgJiBzZWxmOjpSRUxBVElWRV9QQVRIUykgPT0gc2VsZjo6UkVMQVRJVkVfUEFUSFMpID8gJHZhbCA6ICR0aGlzLT5yZWFscGF0aCgkdmFsKTsKCiAgICAgICAgICAgIC8vIGJvb2xlYW5zIHdpdGggZW52IHZhciBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLXJlYWQtb25seSc6CiAgICAgICAgICAgIGNhc2UgJ2h0YWNjZXNzLXByb3RlY3QnOgogICAgICAgICAgICAgICAgLy8gY29udmVydCBmb28tYmFyIHRvIENPTVBPU0VSX0ZPT19CQVIgYW5kIGNoZWNrIGlmIGl0IGV4aXN0cyBzaW5jZSBpdCBvdmVycmlkZXMgdGhlIGxvY2FsIGNvbmZpZwogICAgICAgICAgICAgICAgJGVudiA9ICdDT01QT1NFUl8nIC4gc3RydG91cHBlcihzdHJ0cigka2V5LCAnLScsICdfJykpOwoKICAgICAgICAgICAgICAgICR2YWwgPSAkdGhpcy0+Z2V0Q29tcG9zZXJFbnYoJGVudik7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsID0gJHRoaXMtPmNvbmZpZ1ska2V5XTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHZhbDsKCiAgICAgICAgICAgIC8vIGJvb2xlYW5zIHdpdGhvdXQgZW52IHZhciBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ2Rpc2FibGUtdGxzJzoKICAgICAgICAgICAgY2FzZSAnc2VjdXJlLWh0dHAnOgogICAgICAgICAgICBjYXNlICd1c2UtZ2l0aHViLWFwaSc6CiAgICAgICAgICAgIGNhc2UgJ2xvY2snOgogICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIGZvciBzZWN1cmUtaHR0cAogICAgICAgICAgICAgICAgaWYgKCRrZXkgPT09ICdzZWN1cmUtaHR0cCcgJiYgJHRoaXMtPmdldCgnZGlzYWJsZS10bHMnKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZpZ1ska2V5XSAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHRoaXMtPmNvbmZpZ1ska2V5XTsKCiAgICAgICAgICAgIC8vIGludHMgd2l0aG91dCBlbnYgdmFyIHN1cHBvcnQKICAgICAgICAgICAgY2FzZSAnY2FjaGUtdHRsJzoKICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWyRrZXldOwoKICAgICAgICAgICAgLy8gbnVtYmVycyB3aXRoIGtiL21iL2diIHN1cHBvcnQsIHdpdGhvdXQgZW52IHZhciBzdXBwb3J0CiAgICAgICAgICAgIGNhc2UgJ2NhY2hlLWZpbGVzLW1heHNpemUnOgogICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvXlxzKihbMC05Ll0rKVxzKig/Oihba21nXSkoPzppP2IpPyk/XHMqJC9pJywgJHRoaXMtPmNvbmZpZ1ska2V5XSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IHBhcnNlIHRoZSB2YWx1ZSBvZiAnJGtleSc6IHskdGhpcy0+Y29uZmlnWyRrZXldfSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHNpemUgPSAkbWF0Y2hlc1sxXTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0cnRvbG93ZXIoJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2cnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNpemUgKj0gMTAyNDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludGVudGlvbmFsIGZhbGx0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBicmVhawogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdtJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzaXplICo9IDEwMjQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlbnRpb25hbCBmYWxsdGhyb3VnaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gYnJlYWsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnayc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2l6ZSAqPSAxMDI0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkc2l6ZTsKCiAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZXMgYmVsb3cKICAgICAgICAgICAgY2FzZSAnY2FjaGUtZmlsZXMtdHRsJzoKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWyRrZXldOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+Y29uZmlnWydjYWNoZS10dGwnXTsKCiAgICAgICAgICAgIGNhc2UgJ2hvbWUnOgogICAgICAgICAgICAgICAgJHZhbCA9IHByZWdfcmVwbGFjZSgnI14oXCRIT01FfH4pKC98JCkjJywgcnRyaW0oZ2V0ZW52KCdIT01FJykgPzogZ2V0ZW52KCdVU0VSUFJPRklMRScpLCAnL1xcJykgLiAnLycsICR0aGlzLT5jb25maWdbJGtleV0pOwoKICAgICAgICAgICAgICAgIHJldHVybiBydHJpbSgkdGhpcy0+cHJvY2VzcygkdmFsLCAkZmxhZ3MpLCAnL1xcJyk7CgogICAgICAgICAgICBjYXNlICdiaW4tY29tcGF0JzoKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5nZXRDb21wb3NlckVudignQ09NUE9TRVJfQklOX0NPTVBBVCcpID86ICR0aGlzLT5jb25maWdbJGtleV07CgogICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkdmFsdWUsIGFycmF5KCdhdXRvJywgJ2Z1bGwnKSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHZhbHVlIGZvciAnYmluLWNvbXBhdCc6IHskdmFsdWV9LiBFeHBlY3RlZCBhdXRvLCBmdWxsIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKCiAgICAgICAgICAgIGNhc2UgJ2Rpc2NhcmQtY2hhbmdlcyc6CiAgICAgICAgICAgICAgICBpZiAoJGVudiA9ICR0aGlzLT5nZXRDb21wb3NlckVudignQ09NUE9TRVJfRElTQ0FSRF9DSEFOR0VTJykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRlbnYsIGFycmF5KCdzdGFzaCcsICd0cnVlJywgJ2ZhbHNlJywgJzEnLCAnMCcpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCB2YWx1ZSBmb3IgQ09NUE9TRVJfRElTQ0FSRF9DSEFOR0VTOiB7JGVudn0uIEV4cGVjdGVkIDEsIDAsIHRydWUsIGZhbHNlIG9yIHN0YXNoIgogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJ3N0YXNoJyA9PT0gJGVudikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3N0YXNoJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgc3RyaW5nIHZhbHVlIHRvIGJvb2wKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGVudiAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJGVudjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCR0aGlzLT5jb25maWdbJGtleV0sIGFycmF5KHRydWUsIGZhbHNlLCAnc3Rhc2gnKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHZhbHVlIGZvciAnZGlzY2FyZC1jaGFuZ2VzJzogeyR0aGlzLT5jb25maWdbJGtleV19LiBFeHBlY3RlZCB0cnVlLCBmYWxzZSBvciBzdGFzaCIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29uZmlnWyRrZXldOwoKICAgICAgICAgICAgY2FzZSAnZ2l0aHViLXByb3RvY29scyc6CiAgICAgICAgICAgICAgICAkcHJvdG9zID0gJHRoaXMtPmNvbmZpZ1snZ2l0aHViLXByb3RvY29scyddOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb25maWdbJ3NlY3VyZS1odHRwJ10gJiYgZmFsc2UgIT09ICgkaW5kZXggPSBhcnJheV9zZWFyY2goJ2dpdCcsICRwcm90b3MpKSkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRwcm90b3NbJGluZGV4XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmVzZXQoJHByb3RvcykgPT09ICdodHRwJykgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGh0dHAgcHJvdG9jb2wgZm9yIGdpdGh1YiBpcyBub3QgYXZhaWxhYmxlIGFueW1vcmUsIHVwZGF0ZSB5b3VyIGNvbmZpZ1wncyBnaXRodWItcHJvdG9jb2xzIHRvIHVzZSAiaHR0cHMiLCAiZ2l0IiBvciAic3NoIicpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkcHJvdG9zOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbmZpZ1ska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3MoJHRoaXMtPmNvbmZpZ1ska2V5XSwgJGZsYWdzKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFsbCgkZmxhZ3MgPSAwKQogICAgewogICAgICAgICRhbGwgPSBhcnJheSgKICAgICAgICAgICAgJ3JlcG9zaXRvcmllcycgPT4gJHRoaXMtPmdldFJlcG9zaXRvcmllcygpLAogICAgICAgICk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkdGhpcy0+Y29uZmlnKSBhcyAka2V5KSB7CiAgICAgICAgICAgICRhbGxbJ2NvbmZpZyddWyRrZXldID0gJHRoaXMtPmdldCgka2V5LCAkZmxhZ3MpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhbGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJhdygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAncmVwb3NpdG9yaWVzJyA9PiAkdGhpcy0+Z2V0UmVwb3NpdG9yaWVzKCksCiAgICAgICAgICAgICdjb25maWcnID0+ICR0aGlzLT5jb25maWcsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIGEgc2V0dGluZyBleGlzdHMKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAka2V5CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhcygka2V5KQogICAgewogICAgICAgIHJldHVybiBhcnJheV9rZXlfZXhpc3RzKCRrZXksICR0aGlzLT5jb25maWcpOwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgeyRyZWZzfSBpbnNpZGUgYSBjb25maWcgc3RyaW5nCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmd8aW50fG51bGwgJHZhbHVlIGEgY29uZmlnIHN0cmluZyB0aGF0IGNhbiBjb250YWluIHskcmVmcy10by1vdGhlci1jb25maWd9CiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAkZmxhZ3MgT3B0aW9ucyAoc2VlIGNsYXNzIGNvbnN0YW50cykKICAgICAqIEByZXR1cm4gc3RyaW5nfGludHxudWxsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcHJvY2VzcygkdmFsdWUsICRmbGFncykKICAgIHsKICAgICAgICAkY29uZmlnID0gJHRoaXM7CgogICAgICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJyNce1wkKC4rKVx9IycsIGZ1bmN0aW9uICgkbWF0Y2gpIHVzZSAoJGNvbmZpZywgJGZsYWdzKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uZmlnLT5nZXQoJG1hdGNoWzFdLCAkZmxhZ3MpOwogICAgICAgIH0sICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyByZWxhdGl2ZSBwYXRocyBpbiBhYnNvbHV0ZSBwYXRocyB3aXRob3V0IHJlYWxwYXRoKCkKICAgICAqCiAgICAgKiBTaW5jZSB0aGUgZGlycyBtaWdodCBub3QgZXhpc3QgeWV0IHdlIGNhbiBub3QgY2FsbCByZWFscGF0aCBvciBpdCB3aWxsIGZhaWwuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVhbHBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86L3xbYS16XTp8W2EtejAtOS5dKzovLyl9aScsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gJHBhdGg7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJhc2VEaXIgLiAnLycgLiAkcGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWRzIHRoZSB2YWx1ZSBvZiBhIENvbXBvc2VyIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAgKgogICAgICogVGhpcyBzaG91bGQgYmUgdXNlZCB0byByZWFkIENPTVBPU0VSXyBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICAgICAqIHRoYXQgb3ZlcmxvYWQgY29uZmlnIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICR2YXIKICAgICAqIEByZXR1cm4gc3RyaW5nfGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb21wb3NlckVudigkdmFyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+dXNlRW52aXJvbm1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGdldGVudigkdmFyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRpc2FibGVSZXBvQnlOYW1lKCRuYW1lKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVwb3NpdG9yaWVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJlcG9zaXRvcmllc1skbmFtZV0pOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9PT0gJ3BhY2thZ2lzdCcpIHsgLy8gQkMgc3VwcG9ydCBmb3IgZGVmYXVsdCAicGFja2FnaXN0IiBuYW1lZCByZXBvCiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yZXBvc2l0b3JpZXNbJ3BhY2thZ2lzdC5vcmcnXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoYXQgdGhlIHBhc3NlZCBVUkwgaXMgYWxsb3dlZCB0byBiZSB1c2VkIGJ5IGN1cnJlbnQgY29uZmlnLCBvciB0aHJvd3MgYW4gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdXJsCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9oaWJpdFVybEJ5Q29uZmlnKCR1cmwsIElPSW50ZXJmYWNlICRpbyA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gUmV0dXJuIHJpZ2h0IGF3YXkgaWYgdGhlIFVSTCBpcyBtYWxmb3JtZWQgb3IgY3VzdG9tIChzZWUgaXNzdWUgIzUxNzMpCiAgICAgICAgaWYgKGZhbHNlID09PSBmaWx0ZXJfdmFyKCR1cmwsIEZJTFRFUl9WQUxJREFURV9VUkwpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIEV4dHJhY3Qgc2NoZW1lIGFuZCB0aHJvdyBleGNlcHRpb24gb24ga25vd24gaW5zZWN1cmUgcHJvdG9jb2xzCiAgICAgICAgJHNjaGVtZSA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1NDSEVNRSk7CiAgICAgICAgaWYgKGluX2FycmF5KCRzY2hlbWUsIGFycmF5KCdodHRwJywgJ2dpdCcsICdmdHAnLCAnc3ZuJykpKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Z2V0KCdzZWN1cmUtaHR0cCcpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCJZb3VyIGNvbmZpZ3VyYXRpb24gZG9lcyBub3QgYWxsb3cgY29ubmVjdGlvbnMgdG8gJHVybC4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wNi1jb25maWcubWQjc2VjdXJlLWh0dHAgZm9yIGRldGFpbHMuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbykgewogICAgICAgICAgICAgICAgJGhvc3QgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9IT1NUKTsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPndhcm5lZEhvc3RzWyRob3N0XSkpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoIjx3YXJuaW5nPldhcm5pbmc6IEFjY2Vzc2luZyAkaG9zdCBvdmVyICRzY2hlbWUgd2hpY2ggaXMgYW4gaW5zZWN1cmUgcHJvdG9jb2wuPC93YXJuaW5nPiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPndhcm5lZEhvc3RzWyRob3N0XSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2VkIGJ5IGxvbmctcnVubmluZyBjdXN0b20gc2NyaXB0cyBpbiBjb21wb3Nlci5qc29uCiAgICAgKgogICAgICogInNjcmlwdHMiOiB7CiAgICAgKiAgICJ3YXRjaCI6IFsKICAgICAqICAgICAiQ29tcG9zZXJcXENvbmZpZzo6ZGlzYWJsZVByb2Nlc3NUaW1lb3V0IiwKICAgICAqICAgICAidmVuZG9yL2Jpbi9sb25nLXJ1bm5pbmctc2NyaXB0IC0td2F0Y2giCiAgICAgKiAgIF0KICAgICAqIH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkaXNhYmxlUHJvY2Vzc1RpbWVvdXQoKQogICAgewogICAgICAgIC8vIE92ZXJyaWRlIGdsb2JhbCB0aW1lb3V0IHNldCBlYXJsaWVyIGJ5IGVudmlyb25tZW50IG9yIGNvbmZpZwogICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6c2V0VGltZW91dCgwKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCnVzZSBDb21wb3NlclxBdXRvbG9hZFxBdXRvbG9hZEdlbmVyYXRvcjsKdXNlIENvbXBvc2VyXENvbnNvbGVcR2l0aHViQWN0aW9uRXJyb3I7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcRGVmYXVsdFBvbGljeTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxMb2NhbFJlcG9UcmFuc2FjdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxMb2NrVHJhbnNhY3Rpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVwZGF0ZU9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVW5pbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFBvb2w7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUmVxdWVzdDsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxTb2x2ZXI7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcU29sdmVyUHJvYmxlbXNFeGNlcHRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUG9saWN5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxEb3dubG9hZE1hbmFnZXI7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnREaXNwYXRjaGVyOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXEluc3RhbGxhdGlvbk1hbmFnZXI7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGVyRXZlbnRzOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290QWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcRHVtcGVyXEFycmF5RHVtcGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEFycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvY2tlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcRmlsdGVyUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUm9vdFBhY2thZ2VSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxMb2NrQXJyYXlSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgQmVhdSBTaW1lbnNlbiA8YmVhdUBkZmx5ZGV2LmNvbT4KICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEluc3RhbGxlcgp7CiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uZmlnCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBSb290UGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgLy8gVE9ETyBjYW4gd2UgZ2V0IHJpZCBvZiB0aGUgYmVsb3cgYW5kIGp1c3QgdXNlIHRoZSBwYWNrYWdlIGl0c2VsZj8KICAgIC8qKgogICAgICogQHZhciBSb290UGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGZpeGVkUm9vdFBhY2thZ2U7CgogICAgLyoqCiAgICAgKiBAdmFyIERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGRvd25sb2FkTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgUmVwb3NpdG9yeU1hbmFnZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRyZXBvc2l0b3J5TWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgTG9ja2VyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbG9ja2VyOwoKICAgIC8qKgogICAgICogQHZhciBJbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5zdGFsbGF0aW9uTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEB2YXIgRXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXZlbnREaXNwYXRjaGVyOwoKICAgIC8qKgogICAgICogQHZhciBBdXRvbG9hZEdlbmVyYXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGF1dG9sb2FkR2VuZXJhdG9yOwoKICAgIHByb3RlY3RlZCAkcHJlZmVyU291cmNlID0gZmFsc2U7CiAgICBwcm90ZWN0ZWQgJHByZWZlckRpc3QgPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkb3B0aW1pemVBdXRvbG9hZGVyID0gZmFsc2U7CiAgICBwcm90ZWN0ZWQgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IGZhbHNlOwogICAgcHJvdGVjdGVkICRhcGN1QXV0b2xvYWRlciA9IGZhbHNlOwogICAgcHJvdGVjdGVkICRhcGN1QXV0b2xvYWRlclByZWZpeDsKICAgIHByb3RlY3RlZCAkZGV2TW9kZSA9IGZhbHNlOwogICAgcHJvdGVjdGVkICRkcnlSdW4gPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkdmVyYm9zZSA9IGZhbHNlOwogICAgcHJvdGVjdGVkICR1cGRhdGUgPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkaW5zdGFsbCA9IHRydWU7CiAgICBwcm90ZWN0ZWQgJGR1bXBBdXRvbG9hZGVyID0gdHJ1ZTsKICAgIHByb3RlY3RlZCAkcnVuU2NyaXB0cyA9IHRydWU7CiAgICBwcm90ZWN0ZWQgJGlnbm9yZVBsYXRmb3JtUmVxcyA9IGZhbHNlOwogICAgcHJvdGVjdGVkICRwcmVmZXJTdGFibGUgPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkcHJlZmVyTG93ZXN0ID0gZmFsc2U7CiAgICBwcm90ZWN0ZWQgJHdyaXRlTG9jazsKICAgIHByb3RlY3RlZCAkZXhlY3V0ZU9wZXJhdGlvbnMgPSB0cnVlOwoKICAgIC8qKgogICAgICogQXJyYXkgb2YgcGFja2FnZSBuYW1lcy9nbG9icyBmbGFnZ2VkIGZvciB1cGRhdGUKICAgICAqCiAgICAgKiBAdmFyIGFycmF5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkICR1cGRhdGVNaXJyb3JzID0gZmFsc2U7CiAgICBwcm90ZWN0ZWQgJHVwZGF0ZUFsbG93TGlzdDsKICAgIHByb3RlY3RlZCAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVEOwoKICAgIC8qKgogICAgICogQHZhciBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcjsKCiAgICAvKioKICAgICAqIEB2YXIgUmVwb3NpdG9yeUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgICAgICAkaW8KICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEBwYXJhbSBEb3dubG9hZE1hbmFnZXIgICAgICAkZG93bmxvYWRNYW5hZ2VyCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeU1hbmFnZXIgICAgJHJlcG9zaXRvcnlNYW5hZ2VyCiAgICAgKiBAcGFyYW0gTG9ja2VyICAgICAgICAgICAgICAgJGxvY2tlcgogICAgICogQHBhcmFtIEluc3RhbGxhdGlvbk1hbmFnZXIgICRpbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKiBAcGFyYW0gRXZlbnREaXNwYXRjaGVyICAgICAgJGV2ZW50RGlzcGF0Y2hlcgogICAgICogQHBhcmFtIEF1dG9sb2FkR2VuZXJhdG9yICAgICRhdXRvbG9hZEdlbmVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIERvd25sb2FkTWFuYWdlciAkZG93bmxvYWRNYW5hZ2VyLCBSZXBvc2l0b3J5TWFuYWdlciAkcmVwb3NpdG9yeU1hbmFnZXIsIExvY2tlciAkbG9ja2VyLCBJbnN0YWxsYXRpb25NYW5hZ2VyICRpbnN0YWxsYXRpb25NYW5hZ2VyLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciwgQXV0b2xvYWRHZW5lcmF0b3IgJGF1dG9sb2FkR2VuZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cGFja2FnZSA9ICRwYWNrYWdlOwogICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXIgPSAkZG93bmxvYWRNYW5hZ2VyOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlciA9ICRyZXBvc2l0b3J5TWFuYWdlcjsKICAgICAgICAkdGhpcy0+bG9ja2VyID0gJGxvY2tlcjsKICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlciA9ICRpbnN0YWxsYXRpb25NYW5hZ2VyOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvciA9ICRhdXRvbG9hZEdlbmVyYXRvcjsKCiAgICAgICAgJHRoaXMtPndyaXRlTG9jayA9ICRjb25maWctPmdldCgnbG9jaycpOwogICAgfQoKICAgIC8qKgogICAgICogUnVuIGluc3RhbGxhdGlvbiAob3IgdXBkYXRlKQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICogQHJldHVybiBpbnQgICAgICAgIDAgb24gc3VjY2VzcyBvciBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcnVuKCkKICAgIHsKICAgICAgICAvLyBEaXNhYmxlIEdDIHRvIHNhdmUgQ1BVIGN5Y2xlcywgYXMgdGhlIGRlcGVuZGVuY3kgc29sdmVyIGNhbiBjcmVhdGUgaHVuZHJlZHMgb2YgdGhvdXNhbmRzCiAgICAgICAgLy8gb2YgUEhQIG9iamVjdHMsIHRoZSBHQyBjYW4gc3BlbmQgcXVpdGUgc29tZSB0aW1lIHdhbGtpbmcgdGhlIHRyZWUgb2YgcmVmZXJlbmNlcyBsb29raW5nCiAgICAgICAgLy8gZm9yIHN0dWZmIHRvIGNvbGxlY3Qgd2hpbGUgdGhlcmUgaXMgbm90aGluZyB0byBjb2xsZWN0LiBUaGlzIHNsb3dzIHRoaW5ncyBkb3duIGRyYW1hdGljYWxseQogICAgICAgIC8vIGFuZCB0dXJuaW5nIGl0IG9mZiByZXN1bHRzIGluIG11Y2ggYmV0dGVyIHBlcmZvcm1hbmNlLiBEbyBub3QgdHJ5IHRoaXMgYXQgaG9tZSBob3dldmVyLgogICAgICAgIGdjX2NvbGxlY3RfY3ljbGVzKCk7CiAgICAgICAgZ2NfZGlzYWJsZSgpOwoKICAgICAgICBpZiAoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCAmJiAkdGhpcy0+dXBkYXRlTWlycm9ycykgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIlRoZSBpbnN0YWxsZXIgb3B0aW9ucyB1cGRhdGVNaXJyb3JzIGFuZCB1cGRhdGVBbGxvd0xpc3QgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4iKTsKICAgICAgICB9CgogICAgICAgICRpc0ZyZXNoSW5zdGFsbCA9ICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlci0+Z2V0TG9jYWxSZXBvc2l0b3J5KCktPmlzRnJlc2goKTsKCiAgICAgICAgLy8gRm9yY2UgdXBkYXRlIGlmIHRoZXJlIGlzIG5vIGxvY2sgZmlsZSBwcmVzZW50CiAgICAgICAgaWYgKCEkdGhpcy0+dXBkYXRlICYmICEkdGhpcy0+bG9ja2VyLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Tm8gbG9jayBmaWxlIGZvdW5kLiBVcGRhdGluZyBkZXBlbmRlbmNpZXMgaW5zdGVhZCBvZiBpbnN0YWxsaW5nIGZyb20gbG9jayBmaWxlLiBVc2UgY29tcG9zZXIgdXBkYXRlIG92ZXIgY29tcG9zZXIgaW5zdGFsbCBpZiB5b3UgZG8gbm90IGhhdmUgYSBsb2NrIGZpbGUuPC93YXJuaW5nPicpOwogICAgICAgICAgICAkdGhpcy0+dXBkYXRlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZHJ5UnVuKSB7CiAgICAgICAgICAgICR0aGlzLT52ZXJib3NlID0gdHJ1ZTsKICAgICAgICAgICAgJHRoaXMtPnJ1blNjcmlwdHMgPSBmYWxzZTsKICAgICAgICAgICAgJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zID0gZmFsc2U7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUxvY2sgPSBmYWxzZTsKICAgICAgICAgICAgJHRoaXMtPmR1bXBBdXRvbG9hZGVyID0gZmFsc2U7CiAgICAgICAgICAgICR0aGlzLT5tb2NrTG9jYWxSZXBvc2l0b3JpZXMoJHRoaXMtPnJlcG9zaXRvcnlNYW5hZ2VyKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlICYmICEkdGhpcy0+aW5zdGFsbCkgewogICAgICAgICAgICAkdGhpcy0+ZHVtcEF1dG9sb2FkZXIgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cnVuU2NyaXB0cykgewogICAgICAgICAgICAkX1NFUlZFUlsnQ09NUE9TRVJfREVWX01PREUnXSA9ICR0aGlzLT5kZXZNb2RlID8gJzEnIDogJzAnOwogICAgICAgICAgICBwdXRlbnYoJ0NPTVBPU0VSX0RFVl9NT0RFPScuJF9TRVJWRVJbJ0NPTVBPU0VSX0RFVl9NT0RFJ10pOwoKICAgICAgICAgICAgLy8gZGlzcGF0Y2ggcHJlIGV2ZW50CiAgICAgICAgICAgIC8vIHNob3VsZCB3ZSB0cmVhdCB0aGlzIG1vcmUgc3RyaWN0bHkgYXMgcnVubmluZyBhbiB1cGRhdGUgYW5kIHRoZW4gcnVubmluZyBhbiBpbnN0YWxsLCB0cmlnZ2VyaW5nIGV2ZW50cyBtdWx0aXBsZSB0aW1lcz8KICAgICAgICAgICAgJGV2ZW50TmFtZSA9ICR0aGlzLT51cGRhdGUgPyBTY3JpcHRFdmVudHM6OlBSRV9VUERBVEVfQ01EIDogU2NyaXB0RXZlbnRzOjpQUkVfSU5TVEFMTF9DTUQ7CiAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoU2NyaXB0KCRldmVudE5hbWUsICR0aGlzLT5kZXZNb2RlKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPnNldFByZWZlclNvdXJjZSgkdGhpcy0+cHJlZmVyU291cmNlKTsKICAgICAgICAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5zZXRQcmVmZXJEaXN0KCR0aGlzLT5wcmVmZXJEaXN0KTsKCiAgICAgICAgJGxvY2FsUmVwbyA9ICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlci0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgogICAgICAgIGlmICghJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIgPSBuZXcgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcigkdGhpcy0+aW8pOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCR0aGlzLT51cGRhdGUpIHsKICAgICAgICAgICAgICAgICRyZXMgPSAkdGhpcy0+ZG9VcGRhdGUoJGxvY2FsUmVwbywgJHRoaXMtPmluc3RhbGwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJlcyA9ICR0aGlzLT5kb0luc3RhbGwoJGxvY2FsUmVwbyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRyZXMgIT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zICYmICR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5jb25maWctPmdldCgnbm90aWZ5LW9uLWluc3RhbGwnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXItPm5vdGlmeUluc3RhbGxzKCR0aGlzLT5pbyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zICYmICR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5jb25maWctPmdldCgnbm90aWZ5LW9uLWluc3RhbGwnKSkgewogICAgICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlci0+bm90aWZ5SW5zdGFsbHMoJHRoaXMtPmlvKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkoCiAgICAgICAgICAgICAgICAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCR0aGlzLT5kZXZNb2RlKSwKICAgICAgICAgICAgICAgICR0aGlzLT5jcmVhdGVQbGF0Zm9ybVJlcG8oZmFsc2UpLAogICAgICAgICAgICAgICAgbmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeShjbG9uZSAkdGhpcy0+cGFja2FnZSksCiAgICAgICAgICAgICkpOwogICAgICAgICAgICBpZiAoJGlzRnJlc2hJbnN0YWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlci0+YWRkU3VnZ2VzdGlvbnNGcm9tUGFja2FnZSgkdGhpcy0+cGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXItPm91dHB1dE1pbmltYWxpc3RpYygkaW5zdGFsbGVkUmVwbyk7CiAgICAgICAgfQoKICAgICAgICAvLyBGaW5kIGFiYW5kb25lZCBwYWNrYWdlcyBhbmQgd2FybiB1c2VyCiAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnkgPSAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KHRydWUpOwogICAgICAgIGZvcmVhY2ggKCRsb2NrZWRSZXBvc2l0b3J5LT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2UgfHwgISRwYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlcGxhY2VtZW50ID0gaXNfc3RyaW5nKCRwYWNrYWdlLT5nZXRSZXBsYWNlbWVudFBhY2thZ2UoKSkKICAgICAgICAgICAgICAgID8gJ1VzZSAnIC4gJHBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpIC4gJyBpbnN0ZWFkJwogICAgICAgICAgICAgICAgOiAnTm8gcmVwbGFjZW1lbnQgd2FzIHN1Z2dlc3RlZCc7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICI8d2FybmluZz5QYWNrYWdlICVzIGlzIGFiYW5kb25lZCwgeW91IHNob3VsZCBhdm9pZCB1c2luZyBpdC4gJXMuPC93YXJuaW5nPiIsCiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZHVtcEF1dG9sb2FkZXIpIHsKICAgICAgICAgICAgLy8gd3JpdGUgYXV0b2xvYWRlcgogICAgICAgICAgICBpZiAoJHRoaXMtPm9wdGltaXplQXV0b2xvYWRlcikgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5HZW5lcmF0aW5nIG9wdGltaXplZCBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGluZm8+R2VuZXJhdGluZyBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmF1dG9sb2FkR2VuZXJhdG9yLT5zZXREZXZNb2RlKCR0aGlzLT5kZXZNb2RlKTsKICAgICAgICAgICAgJHRoaXMtPmF1dG9sb2FkR2VuZXJhdG9yLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0QXBjdSgkdGhpcy0+YXBjdUF1dG9sb2FkZXIsICR0aGlzLT5hcGN1QXV0b2xvYWRlclByZWZpeCk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0UnVuU2NyaXB0cygkdGhpcy0+cnVuU2NyaXB0cyk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+c2V0SWdub3JlUGxhdGZvcm1SZXF1aXJlbWVudHMoJHRoaXMtPmlnbm9yZVBsYXRmb3JtUmVxcyk7CiAgICAgICAgICAgICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvci0+ZHVtcCgkdGhpcy0+Y29uZmlnLCAkbG9jYWxSZXBvLCAkdGhpcy0+cGFja2FnZSwgJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXIsICdjb21wb3NlcicsICR0aGlzLT5vcHRpbWl6ZUF1dG9sb2FkZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5pbnN0YWxsICYmICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucykgewogICAgICAgICAgICAvLyBmb3JjZSBiaW5hcmllcyByZS1nZW5lcmF0aW9uIGluIGNhc2UgdGhleSBhcmUgbWlzc2luZwogICAgICAgICAgICBmb3JlYWNoICgkbG9jYWxSZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlci0+ZW5zdXJlQmluYXJpZXNQcmVzZW5jZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRmdW5kaW5nQ291bnQgPSAwOwogICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICEkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+Z2V0RnVuZGluZygpKSB7CiAgICAgICAgICAgICAgICAkZnVuZGluZ0NvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRmdW5kaW5nQ291bnQpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAgICAgc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAiPGluZm8+JWQgcGFja2FnZSVzIHlvdSBhcmUgdXNpbmcgJXMgbG9va2luZyBmb3IgZnVuZGluZy48L2luZm8+IiwKICAgICAgICAgICAgICAgICAgICAkZnVuZGluZ0NvdW50LAogICAgICAgICAgICAgICAgICAgIDEgPT09ICRmdW5kaW5nQ291bnQgPyAnJyA6ICdzJywKICAgICAgICAgICAgICAgICAgICAxID09PSAkZnVuZGluZ0NvdW50ID8gJ2lzJyA6ICdhcmUnCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgJzxpbmZvPlVzZSB0aGUgYGNvbXBvc2VyIGZ1bmRgIGNvbW1hbmQgdG8gZmluZCBvdXQgbW9yZSE8L2luZm8+JywKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnJ1blNjcmlwdHMpIHsKICAgICAgICAgICAgLy8gZGlzcGF0Y2ggcG9zdCBldmVudAogICAgICAgICAgICAkZXZlbnROYW1lID0gJHRoaXMtPnVwZGF0ZSA/IFNjcmlwdEV2ZW50czo6UE9TVF9VUERBVEVfQ01EIDogU2NyaXB0RXZlbnRzOjpQT1NUX0lOU1RBTExfQ01EOwogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFNjcmlwdCgkZXZlbnROYW1lLCAkdGhpcy0+ZGV2TW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvLyByZS1lbmFibGUgR0MgZXhjZXB0IG9uIEhIVk0gd2hpY2ggdHJpZ2dlcnMgYSB3YXJuaW5nIGhlcmUKICAgICAgICBpZiAoIWRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgIGdjX2VuYWJsZSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvVXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJGxvY2FsUmVwbywgJGRvSW5zdGFsbCkKICAgIHsKICAgICAgICAkcGxhdGZvcm1SZXBvID0gJHRoaXMtPmNyZWF0ZVBsYXRmb3JtUmVwbyh0cnVlKTsKICAgICAgICAkYWxpYXNlcyA9ICR0aGlzLT5nZXRSb290QWxpYXNlcyh0cnVlKTsKCiAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnkgPSBudWxsOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmxvY2tlci0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnkgPSAkdGhpcy0+bG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXFNlbGRcSnNvbkxpbnRcUGFyc2luZ0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCB8fCAkdGhpcy0+dXBkYXRlTWlycm9ycykgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSB3ZSBhcmUgZG9pbmcgYSBwYXJ0aWFsIHVwZGF0ZSBvciB1cGRhdGluZyBtaXJyb3JzLCB0aGUgbG9jayBmaWxlIGlzIG5lZWRlZCBzbyB3ZSBlcnJvcgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBpZ25vcmluZyBwYXJzZSBlcnJvcnMgYXMgdGhlIGxvY2sgZmlsZSB3aWxsIGJlIHJlZ2VuZXJhdGVkIGZyb20gc2NyYXRjaCB3aGVuCiAgICAgICAgICAgIC8vIGRvaW5nIGEgZnVsbCB1cGRhdGUKICAgICAgICB9CgogICAgICAgIGlmICgoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCB8fCAkdGhpcy0+dXBkYXRlTWlycm9ycykgJiYgISRsb2NrZWRSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkNhbm5vdCB1cGRhdGUgJyAuICgkdGhpcy0+dXBkYXRlTWlycm9ycyA/ICdsb2NrIGZpbGUgaW5mb3JtYXRpb24nIDogJ29ubHkgYSBwYXJ0aWFsIHNldCBvZiBwYWNrYWdlcycpIC4gJyB3aXRob3V0IGEgbG9jayBmaWxlIHByZXNlbnQuIFJ1biBgY29tcG9zZXIgdXBkYXRlYCB0byBnZW5lcmF0ZSBhIGxvY2sgZmlsZS48L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGluZm8+TG9hZGluZyBjb21wb3NlciByZXBvc2l0b3JpZXMgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uPC9pbmZvPicpOwoKICAgICAgICAvLyBjcmVhdGluZyByZXBvc2l0b3J5IHNldAogICAgICAgICRwb2xpY3kgPSAkdGhpcy0+Y3JlYXRlUG9saWN5KHRydWUpOwogICAgICAgICRyZXBvc2l0b3J5U2V0ID0gJHRoaXMtPmNyZWF0ZVJlcG9zaXRvcnlTZXQodHJ1ZSwgJHBsYXRmb3JtUmVwbywgJGFsaWFzZXMpOwogICAgICAgICRyZXBvc2l0b3JpZXMgPSAkdGhpcy0+cmVwb3NpdG9yeU1hbmFnZXItPmdldFJlcG9zaXRvcmllcygpOwogICAgICAgIGZvcmVhY2ggKCRyZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoJHJlcG9zaXRvcnkpOwogICAgICAgIH0KICAgICAgICBpZiAoJGxvY2tlZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoJGxvY2tlZFJlcG9zaXRvcnkpOwogICAgICAgIH0KCiAgICAgICAgJHJlcXVlc3QgPSAkdGhpcy0+Y3JlYXRlUmVxdWVzdCgkdGhpcy0+Zml4ZWRSb290UGFja2FnZSwgJHBsYXRmb3JtUmVwbywgJGxvY2tlZFJlcG9zaXRvcnkpOwogICAgICAgICR0aGlzLT5yZXF1aXJlUGFja2FnZXNGb3JVcGRhdGUoJHJlcXVlc3QsICRsb2NrZWRSZXBvc2l0b3J5LCB0cnVlKTsKCiAgICAgICAgLy8gcGFzcyB0aGUgYWxsb3cgbGlzdCBpbnRvIHRoZSByZXF1ZXN0LCBzbyB0aGUgcG9vbCBidWlsZGVyIGNhbiBhcHBseSBpdAogICAgICAgIGlmICgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0KSB7CiAgICAgICAgICAgICRyZXF1ZXN0LT5zZXRVcGRhdGVBbGxvd0xpc3QoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCwgJHRoaXMtPnVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyk7CiAgICAgICAgfQoKICAgICAgICAkcG9vbCA9ICRyZXBvc2l0b3J5U2V0LT5jcmVhdGVQb29sKCRyZXF1ZXN0LCAkdGhpcy0+aW8sICR0aGlzLT5ldmVudERpc3BhdGNoZXIpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPlVwZGF0aW5nIGRlcGVuZGVuY2llczwvaW5mbz4nKTsKCiAgICAgICAgLy8gc29sdmUgZGVwZW5kZW5jaWVzCiAgICAgICAgJHNvbHZlciA9IG5ldyBTb2x2ZXIoJHBvbGljeSwgJHBvb2wsICR0aGlzLT5pbyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGxvY2tUcmFuc2FjdGlvbiA9ICRzb2x2ZXItPnNvbHZlKCRyZXF1ZXN0LCAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzKTsKICAgICAgICAgICAgJHJ1bGVTZXRTaXplID0gJHNvbHZlci0+Z2V0UnVsZVNldFNpemUoKTsKICAgICAgICAgICAgJHNvbHZlciA9IG51bGw7CiAgICAgICAgfSBjYXRjaCAoU29sdmVyUHJvYmxlbXNFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVyciA9ICdZb3VyIHJlcXVpcmVtZW50cyBjb3VsZCBub3QgYmUgcmVzb2x2ZWQgdG8gYW4gaW5zdGFsbGFibGUgc2V0IG9mIHBhY2thZ2VzLic7CiAgICAgICAgICAgICRwcmV0dHlQcm9ibGVtID0gJGUtPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkdGhpcy0+aW8tPmlzVmVyYm9zZSgpKTsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPicuICRlcnIgLic8L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkcHJldHR5UHJvYmxlbSk7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmRldk1vZGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+UnVubmluZyB1cGRhdGUgd2l0aCAtLW5vLWRldiBkb2VzIG5vdCBtZWFuIHJlcXVpcmUtZGV2IGlzIGlnbm9yZWQsIGl0IGp1c3QgbWVhbnMgdGhlIHBhY2thZ2VzIHdpbGwgbm90IGJlIGluc3RhbGxlZC4gSWYgZGV2IHJlcXVpcmVtZW50cyBhcmUgYmxvY2tpbmcgdGhlIHVwZGF0ZSB5b3UgaGF2ZSB0byByZXNvbHZlIHRob3NlIHByb2JsZW1zLjwvd2FybmluZz4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZ2hlID0gbmV3IEdpdGh1YkFjdGlvbkVycm9yKCR0aGlzLT5pbyk7CiAgICAgICAgICAgICRnaGUtPmVtaXQoJGVyci4iXG4iLiRwcmV0dHlQcm9ibGVtKTsKCiAgICAgICAgICAgIHJldHVybiBtYXgoMSwgJGUtPmdldENvZGUoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIkFuYWx5emVkICIuY291bnQoJHBvb2wpLiIgcGFja2FnZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMiLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJBbmFseXplZCAiLiRydWxlU2V0U2l6ZS4iIHJ1bGVzIHRvIHJlc29sdmUgZGVwZW5kZW5jaWVzIiwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICBpZiAoISRsb2NrVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ05vdGhpbmcgdG8gbW9kaWZ5IGluIGxvY2sgZmlsZScpOwogICAgICAgIH0KCiAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPmV4dHJhY3REZXZQYWNrYWdlcygkbG9ja1RyYW5zYWN0aW9uLCAkcGxhdGZvcm1SZXBvLCAkYWxpYXNlcywgJHBvbGljeSwgJGxvY2tlZFJlcG9zaXRvcnkpOwogICAgICAgIGlmICgkZXhpdENvZGUgIT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgICAgICB9CgogICAgICAgIC8vIHdyaXRlIGxvY2sKICAgICAgICAkcGxhdGZvcm1SZXFzID0gJHRoaXMtPmV4dHJhY3RQbGF0Zm9ybVJlcXVpcmVtZW50cygkdGhpcy0+cGFja2FnZS0+Z2V0UmVxdWlyZXMoKSk7CiAgICAgICAgJHBsYXRmb3JtRGV2UmVxcyA9ICR0aGlzLT5leHRyYWN0UGxhdGZvcm1SZXF1aXJlbWVudHMoJHRoaXMtPnBhY2thZ2UtPmdldERldlJlcXVpcmVzKCkpOwoKICAgICAgICAkaW5zdGFsbHNVcGRhdGVzID0gJHVuaW5zdGFsbHMgPSBhcnJheSgpOwogICAgICAgIGlmICgkbG9ja1RyYW5zYWN0aW9uLT5nZXRPcGVyYXRpb25zKCkpIHsKICAgICAgICAgICAgJGluc3RhbGxOYW1lcyA9ICR1cGRhdGVOYW1lcyA9ICR1bmluc3RhbGxOYW1lcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NrVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSBhcyAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIEluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbHNVcGRhdGVzW10gPSAkb3BlcmF0aW9uOwogICAgICAgICAgICAgICAgICAgICRpbnN0YWxsTmFtZXNbXSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKS0+Z2V0UHJldHR5TmFtZSgpLic6Jy4kb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCktPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gbWlycm9ycy9tZXRhZGF0YSBmcm9tIGEgcGFja2FnZSBnZXRzIHVwZGF0ZWQgd2UgZG8gbm90IHdhbnQgdG8gbGlzdCBpdCBhcyBhbgogICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBpbiB0aGUgb3V0cHV0IGFzIGl0IGlzIG9ubHkgYW4gaW50ZXJuYWwgbG9jayBmaWxlIG1ldGFkYXRhIHVwZGF0ZQogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+dXBkYXRlTWlycm9ycwogICAgICAgICAgICAgICAgICAgICAgICAmJiAkb3BlcmF0aW9uLT5nZXRJbml0aWFsUGFja2FnZSgpLT5nZXROYW1lKCkgPT0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXROYW1lKCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKS0+Z2V0VmVyc2lvbigpID09ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKS0+Z2V0VmVyc2lvbigpCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxzVXBkYXRlc1tdID0gJG9wZXJhdGlvbjsKICAgICAgICAgICAgICAgICAgICAkdXBkYXRlTmFtZXNbXSA9ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKS0+Z2V0UHJldHR5TmFtZSgpLic6Jy4kb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCktPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVuaW5zdGFsbE9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgICR1bmluc3RhbGxzW10gPSAkb3BlcmF0aW9uOwogICAgICAgICAgICAgICAgICAgICR1bmluc3RhbGxOYW1lc1tdID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpLT5nZXRQcmV0dHlOYW1lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgIjxpbmZvPkxvY2sgZmlsZSBvcGVyYXRpb25zOiAlZCBpbnN0YWxsJXMsICVkIHVwZGF0ZSVzLCAlZCByZW1vdmFsJXM8L2luZm8+IiwKICAgICAgICAgICAgICAgIGNvdW50KCRpbnN0YWxsTmFtZXMpLAogICAgICAgICAgICAgICAgMSA9PT0gY291bnQoJGluc3RhbGxOYW1lcykgPyAnJyA6ICdzJywKICAgICAgICAgICAgICAgIGNvdW50KCR1cGRhdGVOYW1lcyksCiAgICAgICAgICAgICAgICAxID09PSBjb3VudCgkdXBkYXRlTmFtZXMpID8gJycgOiAncycsCiAgICAgICAgICAgICAgICBjb3VudCgkdW5pbnN0YWxscyksCiAgICAgICAgICAgICAgICAxID09PSBjb3VudCgkdW5pbnN0YWxscykgPyAnJyA6ICdzJwogICAgICAgICAgICApKTsKICAgICAgICAgICAgaWYgKCRpbnN0YWxsTmFtZXMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiSW5zdGFsbHM6ICIuaW1wbG9kZSgnLCAnLCAkaW5zdGFsbE5hbWVzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdXBkYXRlTmFtZXMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiVXBkYXRlczogIi5pbXBsb2RlKCcsICcsICR1cGRhdGVOYW1lcyksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHVuaW5zdGFsbHMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiUmVtb3ZhbHM6ICIuaW1wbG9kZSgnLCAnLCAkdW5pbnN0YWxsTmFtZXMpLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzb3J0QnlOYW1lID0gZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBVcGRhdGVPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICRhID0gJGEtPmdldFRhcmdldFBhY2thZ2UoKS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGEgPSAkYS0+Z2V0UGFja2FnZSgpLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRiIGluc3RhbmNlb2YgVXBkYXRlT3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICAkYiA9ICRiLT5nZXRUYXJnZXRQYWNrYWdlKCktPmdldE5hbWUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRiID0gJGItPmdldFBhY2thZ2UoKS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhLCAkYik7CiAgICAgICAgfTsKICAgICAgICB1c29ydCgkdW5pbnN0YWxscywgJHNvcnRCeU5hbWUpOwogICAgICAgIHVzb3J0KCRpbnN0YWxsc1VwZGF0ZXMsICRzb3J0QnlOYW1lKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJHVuaW5zdGFsbHMsICRpbnN0YWxsc1VwZGF0ZXMpIGFzICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgLy8gY29sbGVjdCBzdWdnZXN0aW9ucwogICAgICAgICAgICBpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIEluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyLT5hZGRTdWdnZXN0aW9uc0Zyb21QYWNrYWdlKCRvcGVyYXRpb24tPmdldFBhY2thZ2UoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG91dHB1dCBvcCwgYnV0IGFsaWFzIG9wIG9ubHkgaW4gZGVidWcgdmVyYm9zaXR5CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gc3RycG9zKCRvcGVyYXRpb24tPmdldE9wZXJhdGlvblR5cGUoKSwgJ0FsaWFzJykgfHwgJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAtICcgLiAkb3BlcmF0aW9uLT5zaG93KHRydWUpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHVwZGF0ZWRMb2NrID0gJHRoaXMtPmxvY2tlci0+c2V0TG9ja0RhdGEoCiAgICAgICAgICAgICRsb2NrVHJhbnNhY3Rpb24tPmdldE5ld0xvY2tQYWNrYWdlcyhmYWxzZSwgJHRoaXMtPnVwZGF0ZU1pcnJvcnMpLAogICAgICAgICAgICAkbG9ja1RyYW5zYWN0aW9uLT5nZXROZXdMb2NrUGFja2FnZXModHJ1ZSwgJHRoaXMtPnVwZGF0ZU1pcnJvcnMpLAogICAgICAgICAgICAkcGxhdGZvcm1SZXFzLAogICAgICAgICAgICAkcGxhdGZvcm1EZXZSZXFzLAogICAgICAgICAgICAkbG9ja1RyYW5zYWN0aW9uLT5nZXRBbGlhc2VzKCRhbGlhc2VzKSwKICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2UtPmdldE1pbmltdW1TdGFiaWxpdHkoKSwKICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2UtPmdldFN0YWJpbGl0eUZsYWdzKCksCiAgICAgICAgICAgICR0aGlzLT5wcmVmZXJTdGFibGUgfHwgJHRoaXMtPnBhY2thZ2UtPmdldFByZWZlclN0YWJsZSgpLAogICAgICAgICAgICAkdGhpcy0+cHJlZmVyTG93ZXN0LAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKSwKICAgICAgICAgICAgJHRoaXMtPndyaXRlTG9jayAmJiAkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMKICAgICAgICApOwogICAgICAgIGlmICgkdXBkYXRlZExvY2sgJiYgJHRoaXMtPndyaXRlTG9jayAmJiAkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5Xcml0aW5nIGxvY2sgZmlsZTwvaW5mbz4nKTsKICAgICAgICB9CgogICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzI3NjQKICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zICYmIGNvdW50KCRsb2NrVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSkgPiAwKSB7CiAgICAgICAgICAgICR2ZW5kb3JEaXIgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKTsKICAgICAgICAgICAgaWYgKGlzX2RpcigkdmVuZG9yRGlyKSkgewogICAgICAgICAgICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzIGFzIHRoaXMgZmFpbHMgc29tZXRpbWVzIG9uIE9TWCBmb3Igbm8gYXBwYXJlbnQgcmVhc29uCiAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy80MDcwI2lzc3VlY29tbWVudC0xMjk3OTI3NDgKICAgICAgICAgICAgICAgIEB0b3VjaCgkdmVuZG9yRGlyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRkb0luc3RhbGwpIHsKICAgICAgICAgICAgLy8gVE9ETyBlbnN1cmUgbG9jayBpcyB1c2VkIGZyb20gbG9ja2VyIGFzLWlzLCBzaW5jZSBpdCBtYXkgbm90IGhhdmUgYmVlbiB3cml0dGVuIHRvIGRpc2sgaW4gY2FzZSBvZiBleGVjdXRlT3BlcmF0aW9ucyA9PSBmYWxzZQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvSW5zdGFsbCgkbG9jYWxSZXBvLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogUnVuIHRoZSBzb2x2ZXIgYSBzZWNvbmQgdGltZSBvbiB0b3Agb2YgdGhlIGV4aXN0aW5nIHVwZGF0ZSByZXN1bHQgd2l0aCBvbmx5IHRoZSBjdXJyZW50IHJlc3VsdCBzZXQgaW4gdGhlIHBvb2wKICAgICAqIGFuZCBzZWUgd2hhdCBwYWNrYWdlcyB3b3VsZCBnZXQgcmVtb3ZlZCBpZiB3ZSBvbmx5IGhhZCB0aGUgbm9uLWRldiBwYWNrYWdlcyBpbiB0aGUgc29sdmVyIHJlcXVlc3QKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3REZXZQYWNrYWdlcyhMb2NrVHJhbnNhY3Rpb24gJGxvY2tUcmFuc2FjdGlvbiwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8sIGFycmF5ICRhbGlhc2VzLCBQb2xpY3lJbnRlcmZhY2UgJHBvbGljeSwgTG9ja0FycmF5UmVwb3NpdG9yeSAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+cGFja2FnZS0+Z2V0RGV2UmVxdWlyZXMoKSkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICRyZXN1bHRSZXBvID0gbmV3IEFycmF5UmVwb3NpdG9yeShhcnJheSgpKTsKICAgICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKG51bGwsIHRydWUpOwogICAgICAgICRkdW1wZXIgPSBuZXcgQXJyYXlEdW1wZXIoKTsKICAgICAgICBmb3JlYWNoICgkbG9ja1RyYW5zYWN0aW9uLT5nZXROZXdMb2NrUGFja2FnZXMoZmFsc2UpIGFzICRwa2cpIHsKICAgICAgICAgICAgJHJlc3VsdFJlcG8tPmFkZFBhY2thZ2UoJGxvYWRlci0+bG9hZCgkZHVtcGVyLT5kdW1wKCRwa2cpKSk7CiAgICAgICAgfQoKICAgICAgICAkcmVwb3NpdG9yeVNldCA9ICR0aGlzLT5jcmVhdGVSZXBvc2l0b3J5U2V0KHRydWUsICRwbGF0Zm9ybVJlcG8sICRhbGlhc2VzKTsKICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeSgkcmVzdWx0UmVwbyk7CgogICAgICAgICRyZXF1ZXN0ID0gJHRoaXMtPmNyZWF0ZVJlcXVlc3QoJHRoaXMtPmZpeGVkUm9vdFBhY2thZ2UsICRwbGF0Zm9ybVJlcG8pOwogICAgICAgICR0aGlzLT5yZXF1aXJlUGFja2FnZXNGb3JVcGRhdGUoJHJlcXVlc3QsICRsb2NrZWRSZXBvc2l0b3J5LCBmYWxzZSk7CgogICAgICAgICRwb29sID0gJHJlcG9zaXRvcnlTZXQtPmNyZWF0ZVBvb2xXaXRoQWxsUGFja2FnZXMoKTsKCiAgICAgICAgJHNvbHZlciA9IG5ldyBTb2x2ZXIoJHBvbGljeSwgJHBvb2wsICR0aGlzLT5pbyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJG5vbkRldkxvY2tUcmFuc2FjdGlvbiA9ICRzb2x2ZXItPnNvbHZlKCRyZXF1ZXN0LCAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzKTsKICAgICAgICAgICAgJHNvbHZlciA9IG51bGw7CiAgICAgICAgfSBjYXRjaCAoU29sdmVyUHJvYmxlbXNFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVyciA9ICdVbmFibGUgdG8gZmluZCBhIGNvbXBhdGlibGUgc2V0IG9mIHBhY2thZ2VzIGJhc2VkIG9uIHlvdXIgbm9uLWRldiByZXF1aXJlbWVudHMgYWxvbmUuJzsKICAgICAgICAgICAgJHByZXR0eVByb2JsZW0gPSAkZS0+Z2V0UHJldHR5U3RyaW5nKCRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wsICR0aGlzLT5pby0+aXNWZXJib3NlKCksIHRydWUpOwoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4gJGVyciAuJzwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdZb3VyIHJlcXVpcmVtZW50cyBjYW4gYmUgcmVzb2x2ZWQgc3VjY2Vzc2Z1bGx5IHdoZW4gcmVxdWlyZS1kZXYgcGFja2FnZXMgYXJlIHByZXNlbnQuJyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IG1heSBuZWVkIHRvIG1vdmUgcGFja2FnZXMgZnJvbSByZXF1aXJlLWRldiBvciBzb21lIG9mIHRoZWlyIGRlcGVuZGVuY2llcyB0byByZXF1aXJlLicpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJHByZXR0eVByb2JsZW0pOwoKICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAkZ2hlLT5lbWl0KCRlcnIuIlxuIi4kcHJldHR5UHJvYmxlbSk7CgogICAgICAgICAgICByZXR1cm4gbWF4KDEsICRlLT5nZXRDb2RlKCkpOwogICAgICAgIH0KCiAgICAgICAgJGxvY2tUcmFuc2FjdGlvbi0+c2V0Tm9uRGV2UGFja2FnZXMoJG5vbkRldkxvY2tUcmFuc2FjdGlvbik7CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NhbFJlcG8KICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAkYWxyZWFkeVNvbHZlZCBXaGV0aGVyIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgYXMgcGFydCBvZiBhbiB1cGRhdGUgY29tbWFuZCBvciBpbmRlcGVuZGVudGx5CiAgICAgKiBAcmV0dXJuIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpdCBjb2RlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCAkYWxyZWFkeVNvbHZlZCA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGluZm8+SW5zdGFsbGluZyBkZXBlbmRlbmNpZXMgZnJvbSBsb2NrIGZpbGUnLigkdGhpcy0+ZGV2TW9kZSA/ICcgKGluY2x1ZGluZyByZXF1aXJlLWRldiknIDogJycpLic8L2luZm8+Jyk7CgogICAgICAgICRsb2NrZWRSZXBvc2l0b3J5ID0gJHRoaXMtPmxvY2tlci0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgkdGhpcy0+ZGV2TW9kZSk7CgogICAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBsb2NrIGZpbGUgd29ya3Mgd2l0aCB0aGUgY3VycmVudCBwbGF0Zm9ybSByZXBvc2l0b3J5CiAgICAgICAgLy8gd2UgY2FuIHNraXAgdGhpcyBwYXJ0IGlmIHdlJ3JlIGRvaW5nIHRoaXMgYXMgdGhlIHNlY29uZCBzdGVwIGFmdGVyIGFuIHVwZGF0ZQogICAgICAgIGlmICghJGFscmVhZHlTb2x2ZWQpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5WZXJpZnlpbmcgbG9jayBmaWxlIGNvbnRlbnRzIGNhbiBiZSBpbnN0YWxsZWQgb24gY3VycmVudCBwbGF0Zm9ybS48L2luZm8+Jyk7CgogICAgICAgICAgICAkcGxhdGZvcm1SZXBvID0gJHRoaXMtPmNyZWF0ZVBsYXRmb3JtUmVwbyhmYWxzZSk7CiAgICAgICAgICAgIC8vIGNyZWF0aW5nIHJlcG9zaXRvcnkgc2V0CiAgICAgICAgICAgICRwb2xpY3kgPSAkdGhpcy0+Y3JlYXRlUG9saWN5KGZhbHNlKTsKICAgICAgICAgICAgLy8gdXNlIGFsaWFzZXMgZnJvbSBsb2NrIGZpbGUgb25seSwgc28gZW1wdHkgcm9vdCBhbGlhc2VzIGhlcmUKICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQgPSAkdGhpcy0+Y3JlYXRlUmVwb3NpdG9yeVNldChmYWxzZSwgJHBsYXRmb3JtUmVwbywgYXJyYXkoKSwgJGxvY2tlZFJlcG9zaXRvcnkpOwogICAgICAgICAgICAkcmVwb3NpdG9yeVNldC0+YWRkUmVwb3NpdG9yeSgkbG9ja2VkUmVwb3NpdG9yeSk7CgogICAgICAgICAgICAvLyBjcmVhdGluZyByZXF1aXJlbWVudHMgcmVxdWVzdAogICAgICAgICAgICAkcmVxdWVzdCA9ICR0aGlzLT5jcmVhdGVSZXF1ZXN0KCR0aGlzLT5maXhlZFJvb3RQYWNrYWdlLCAkcGxhdGZvcm1SZXBvLCAkbG9ja2VkUmVwb3NpdG9yeSk7CgogICAgICAgICAgICBpZiAoISR0aGlzLT5sb2NrZXItPmlzRnJlc2goKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5XYXJuaW5nOiBUaGUgbG9jayBmaWxlIGlzIG5vdCB1cCB0byBkYXRlIHdpdGggdGhlIGxhdGVzdCBjaGFuZ2VzIGluIGNvbXBvc2VyLmpzb24uIFlvdSBtYXkgYmUgZ2V0dGluZyBvdXRkYXRlZCBkZXBlbmRlbmNpZXMuIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgeW91IHJ1biBgY29tcG9zZXIgdXBkYXRlYCBvciBgY29tcG9zZXIgdXBkYXRlIDxwYWNrYWdlIG5hbWU+YC48L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tlZFJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRyZXF1ZXN0LT5maXhMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmxvY2tlci0+Z2V0UGxhdGZvcm1SZXF1aXJlbWVudHMoJHRoaXMtPmRldk1vZGUpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAkcmVxdWVzdC0+cmVxdWlyZU5hbWUoJGxpbmstPmdldFRhcmdldCgpLCAkbGluay0+Z2V0Q29uc3RyYWludCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBvb2wgPSAkcmVwb3NpdG9yeVNldC0+Y3JlYXRlUG9vbCgkcmVxdWVzdCwgJHRoaXMtPmlvLCAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKTsKCiAgICAgICAgICAgIC8vIHNvbHZlIGRlcGVuZGVuY2llcwogICAgICAgICAgICAkc29sdmVyID0gbmV3IFNvbHZlcigkcG9saWN5LCAkcG9vbCwgJHRoaXMtPmlvKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRsb2NrVHJhbnNhY3Rpb24gPSAkc29sdmVyLT5zb2x2ZSgkcmVxdWVzdCwgJHRoaXMtPmlnbm9yZVBsYXRmb3JtUmVxcyk7CiAgICAgICAgICAgICAgICAkc29sdmVyID0gbnVsbDsKCiAgICAgICAgICAgICAgICAvLyBpbnN0YWxsaW5nIHRoZSBsb2NrZWQgcGFja2FnZXMgb24gdGhpcyBwbGF0Zm9ybSByZXN1bHRlZCBpbiBsb2NrIG1vZGlmeWluZyBvcGVyYXRpb25zLCB0aGVyZSB3YXNuJ3QgYSBjb25mbGljdCwgYnV0IHRoZSBsb2NrIGZpbGUgYXMtaXMgc2VlbXMgdG8gbm90IHdvcmsgb24gdGhpcyBzeXN0ZW0KICAgICAgICAgICAgICAgIGlmICgwICE9PSBjb3VudCgkbG9ja1RyYW5zYWN0aW9uLT5nZXRPcGVyYXRpb25zKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+WW91ciBsb2NrIGZpbGUgY2Fubm90IGJlIGluc3RhbGxlZCBvbiB0aGlzIHN5c3RlbSB3aXRob3V0IGNoYW5nZXMuIFBsZWFzZSBydW4gY29tcG9zZXIgdXBkYXRlLjwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKFNvbHZlclByb2JsZW1zRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkZXJyID0gJ1lvdXIgbG9jayBmaWxlIGRvZXMgbm90IGNvbnRhaW4gYSBjb21wYXRpYmxlIHNldCBvZiBwYWNrYWdlcy4gUGxlYXNlIHJ1biBjb21wb3NlciB1cGRhdGUuJzsKICAgICAgICAgICAgICAgICRwcmV0dHlQcm9ibGVtID0gJGUtPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkdGhpcy0+aW8tPmlzVmVyYm9zZSgpKTsKCiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nLiAkZXJyIC4nPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRwcmV0dHlQcm9ibGVtKTsKCiAgICAgICAgICAgICAgICAkZ2hlID0gbmV3IEdpdGh1YkFjdGlvbkVycm9yKCR0aGlzLT5pbyk7CiAgICAgICAgICAgICAgICAkZ2hlLT5lbWl0KCRlcnIuIlxuIi4kcHJldHR5UHJvYmxlbSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIG1heCgxLCAkZS0+Z2V0Q29kZSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETyBpbiBob3cgZmFyIGRvIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgaGVyZSB0byBlbnN1cmUgZGV2IHBhY2thZ2VzIGJlaW5nIHVwZGF0ZWQgdG8gbGF0ZXN0IGluIGxvY2sgd2l0aG91dCB2ZXJzaW9uIGNoYW5nZSBhcmUgdHJlYXRlZCBjb3JyZWN0bHk/CiAgICAgICAgJGxvY2FsUmVwb1RyYW5zYWN0aW9uID0gbmV3IExvY2FsUmVwb1RyYW5zYWN0aW9uKCRsb2NrZWRSZXBvc2l0b3J5LCAkbG9jYWxSZXBvKTsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaEluc3RhbGxlckV2ZW50KEluc3RhbGxlckV2ZW50czo6UFJFX09QRVJBVElPTlNfRVhFQywgJHRoaXMtPmRldk1vZGUsICR0aGlzLT5leGVjdXRlT3BlcmF0aW9ucywgJGxvY2FsUmVwb1RyYW5zYWN0aW9uKTsKCiAgICAgICAgaWYgKCEkbG9jYWxSZXBvVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ05vdGhpbmcgdG8gaW5zdGFsbCwgdXBkYXRlIG9yIHJlbW92ZScpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpKSB7CiAgICAgICAgICAgICRpbnN0YWxscyA9ICR1cGRhdGVzID0gJHVuaW5zdGFsbHMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbG9jYWxSZXBvVHJhbnNhY3Rpb24tPmdldE9wZXJhdGlvbnMoKSBhcyAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIEluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbHNbXSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKS0+Z2V0UHJldHR5TmFtZSgpLic6Jy4kb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCktPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJG9wZXJhdGlvbiBpbnN0YW5jZW9mIFVwZGF0ZU9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgICAgICR1cGRhdGVzW10gPSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCktPmdldFByZXR0eU5hbWUoKS4nOicuJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRvcGVyYXRpb24gaW5zdGFuY2VvZiBVbmluc3RhbGxPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAkdW5pbnN0YWxsc1tdID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpLT5nZXRQcmV0dHlOYW1lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgIjxpbmZvPlBhY2thZ2Ugb3BlcmF0aW9uczogJWQgaW5zdGFsbCVzLCAlZCB1cGRhdGUlcywgJWQgcmVtb3ZhbCVzPC9pbmZvPiIsCiAgICAgICAgICAgICAgICBjb3VudCgkaW5zdGFsbHMpLAogICAgICAgICAgICAgICAgMSA9PT0gY291bnQoJGluc3RhbGxzKSA/ICcnIDogJ3MnLAogICAgICAgICAgICAgICAgY291bnQoJHVwZGF0ZXMpLAogICAgICAgICAgICAgICAgMSA9PT0gY291bnQoJHVwZGF0ZXMpID8gJycgOiAncycsCiAgICAgICAgICAgICAgICBjb3VudCgkdW5pbnN0YWxscyksCiAgICAgICAgICAgICAgICAxID09PSBjb3VudCgkdW5pbnN0YWxscykgPyAnJyA6ICdzJwogICAgICAgICAgICApKTsKICAgICAgICAgICAgaWYgKCRpbnN0YWxscykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJJbnN0YWxsczogIi5pbXBsb2RlKCcsICcsICRpbnN0YWxscyksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHVwZGF0ZXMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiVXBkYXRlczogIi5pbXBsb2RlKCcsICcsICR1cGRhdGVzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdW5pbnN0YWxscykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCJSZW1vdmFsczogIi5pbXBsb2RlKCcsICcsICR1bmluc3RhbGxzKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmV4ZWN1dGVPcGVyYXRpb25zKSB7CiAgICAgICAgICAgICRsb2NhbFJlcG8tPnNldERldlBhY2thZ2VOYW1lcygkdGhpcy0+bG9ja2VyLT5nZXREZXZQYWNrYWdlTmFtZXMoKSk7CiAgICAgICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyLT5leGVjdXRlKCRsb2NhbFJlcG8sICRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpLCAkdGhpcy0+ZGV2TW9kZSwgJHRoaXMtPnJ1blNjcmlwdHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG9UcmFuc2FjdGlvbi0+Z2V0T3BlcmF0aW9ucygpIGFzICRvcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgIC8vIG91dHB1dCBvcCwgYnV0IGFsaWFzIG9wIG9ubHkgaW4gZGVidWcgdmVyYm9zaXR5CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkb3BlcmF0aW9uLT5nZXRPcGVyYXRpb25UeXBlKCksICdBbGlhcycpIHx8ICR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgIC0gJyAuICRvcGVyYXRpb24tPnNob3coZmFsc2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZVBsYXRmb3JtUmVwbygkZm9yVXBkYXRlKQogICAgewogICAgICAgIGlmICgkZm9yVXBkYXRlKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICR0aGlzLT5jb25maWctPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICR0aGlzLT5sb2NrZXItPmdldFBsYXRmb3JtT3ZlcnJpZGVzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgJGZvclVwZGF0ZQogICAgICogQHBhcmFtICBQbGF0Zm9ybVJlcG9zaXRvcnkgICAgICAgJHBsYXRmb3JtUmVwbwogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICAgICAgJHJvb3RBbGlhc2VzCiAgICAgKiBAcGFyYW0gIFJlcG9zaXRvcnlJbnRlcmZhY2V8bnVsbCAkbG9ja2VkUmVwb3NpdG9yeQogICAgICogQHJldHVybiBSZXBvc2l0b3J5U2V0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlUmVwb3NpdG9yeVNldCgkZm9yVXBkYXRlLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbywgYXJyYXkgJHJvb3RBbGlhc2VzID0gYXJyYXkoKSwgJGxvY2tlZFJlcG9zaXRvcnkgPSBudWxsKQogICAgewogICAgICAgIGlmICgkZm9yVXBkYXRlKSB7CiAgICAgICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHRoaXMtPnBhY2thZ2UtPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICAgICAgJHN0YWJpbGl0eUZsYWdzID0gJHRoaXMtPnBhY2thZ2UtPmdldFN0YWJpbGl0eUZsYWdzKCk7CgogICAgICAgICAgICAkcmVxdWlyZXMgPSBhcnJheV9tZXJnZSgkdGhpcy0+cGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwgJHRoaXMtPnBhY2thZ2UtPmdldERldlJlcXVpcmVzKCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHRoaXMtPmxvY2tlci0+Z2V0TWluaW11bVN0YWJpbGl0eSgpOwogICAgICAgICAgICAkc3RhYmlsaXR5RmxhZ3MgPSAkdGhpcy0+bG9ja2VyLT5nZXRTdGFiaWxpdHlGbGFncygpOwoKICAgICAgICAgICAgJHJlcXVpcmVzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tlZFJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50LT5zZXRQcmV0dHlTdHJpbmcoJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAkcmVxdWlyZXNbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkY29uc3RyYWludDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJvb3RSZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVzIGFzICRyZXEgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgZnJvbSB0aGUgcm9vdCBwYWNrYWdlIHRvIGF2b2lkIGZpbHRlcmluZyBvdXQgZXhpc3RpbmcgcGxhdGZvcm0gcGFja2FnZXMKICAgICAgICAgICAgaWYgKCh0cnVlID09PSAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzIHx8IChpc19hcnJheSgkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzKSAmJiBpbl9hcnJheSgkcmVxLCAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzLCB0cnVlKSkpICYmIFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY29uc3RyYWludCBpbnN0YW5jZW9mIExpbmspIHsKICAgICAgICAgICAgICAgICRyb290UmVxdWlyZXNbJHJlcV0gPSAkY29uc3RyYWludC0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJvb3RSZXF1aXJlc1skcmVxXSA9ICRjb25zdHJhaW50OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Zml4ZWRSb290UGFja2FnZSA9IGNsb25lICR0aGlzLT5wYWNrYWdlOwogICAgICAgICR0aGlzLT5maXhlZFJvb3RQYWNrYWdlLT5zZXRSZXF1aXJlcyhhcnJheSgpKTsKICAgICAgICAkdGhpcy0+Zml4ZWRSb290UGFja2FnZS0+c2V0RGV2UmVxdWlyZXMoYXJyYXkoKSk7CgogICAgICAgICRzdGFiaWxpdHlGbGFnc1skdGhpcy0+cGFja2FnZS0+Z2V0TmFtZSgpXSA9IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHRoaXMtPnBhY2thZ2UtPmdldFZlcnNpb24oKSldOwoKICAgICAgICAkcmVwb3NpdG9yeVNldCA9IG5ldyBSZXBvc2l0b3J5U2V0KCRtaW5pbXVtU3RhYmlsaXR5LCAkc3RhYmlsaXR5RmxhZ3MsICRyb290QWxpYXNlcywgJHRoaXMtPnBhY2thZ2UtPmdldFJlZmVyZW5jZXMoKSwgJHJvb3RSZXF1aXJlcyk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkobmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeSgkdGhpcy0+Zml4ZWRSb290UGFja2FnZSkpOwogICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCRwbGF0Zm9ybVJlcG8pOwogICAgICAgIGlmICgkdGhpcy0+YWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeSkgewogICAgICAgICAgICAvLyBhbGxvdyB1c2luZyBpbnN0YWxsZWQgcmVwb3MgaWYgbmVlZGVkIHRvIGF2b2lkIHdhcm5pbmdzIGFib3V0IGluc3RhbGxlZCByZXBvc2l0b3JpZXMgYmVpbmcgdXNlZCBpbiB0aGUgUmVwb3NpdG9yeVNldAogICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvOTU3NAogICAgICAgICAgICAkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yaWVzID0gJHRoaXMtPmFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnk7CiAgICAgICAgICAgIGlmICgkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yaWVzIGluc3RhbmNlb2YgQ29tcG9zaXRlUmVwb3NpdG9yeSkgewogICAgICAgICAgICAgICAgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcmllcyA9ICRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMtPmdldFJlcG9zaXRvcmllcygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcmllcyA9IGFycmF5KCRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3JpZXMgYXMgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgICAgIGlmICgkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeSBpbnN0YW5jZW9mIEluc3RhbGxlZFJlcG9zaXRvcnkgfHwgJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkgaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFsbG93SW5zdGFsbGVkUmVwb3NpdG9yaWVzKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KCR0aGlzLT5hZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVwb3NpdG9yeVNldDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gRGVmYXVsdFBvbGljeQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVBvbGljeSgkZm9yVXBkYXRlKQogICAgewogICAgICAgICRwcmVmZXJTdGFibGUgPSBudWxsOwogICAgICAgICRwcmVmZXJMb3dlc3QgPSBudWxsOwogICAgICAgIGlmICghJGZvclVwZGF0ZSkgewogICAgICAgICAgICAkcHJlZmVyU3RhYmxlID0gJHRoaXMtPmxvY2tlci0+Z2V0UHJlZmVyU3RhYmxlKCk7CiAgICAgICAgICAgICRwcmVmZXJMb3dlc3QgPSAkdGhpcy0+bG9ja2VyLT5nZXRQcmVmZXJMb3dlc3QoKTsKICAgICAgICB9CiAgICAgICAgLy8gb2xkIGxvY2sgZmlsZSB3aXRob3V0IHByZWZlciBzdGFibGUvbG93ZXN0IHdpbGwgcmV0dXJuIG51bGwKICAgICAgICAvLyBzbyBpbiB0aGlzIGNhc2Ugd2UgdXNlIHRoZSBjb21wb3Nlci5qc29uIGluZm8KICAgICAgICBpZiAobnVsbCA9PT0gJHByZWZlclN0YWJsZSkgewogICAgICAgICAgICAkcHJlZmVyU3RhYmxlID0gJHRoaXMtPnByZWZlclN0YWJsZSB8fCAkdGhpcy0+cGFja2FnZS0+Z2V0UHJlZmVyU3RhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsID09PSAkcHJlZmVyTG93ZXN0KSB7CiAgICAgICAgICAgICRwcmVmZXJMb3dlc3QgPSAkdGhpcy0+cHJlZmVyTG93ZXN0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0UG9saWN5KCRwcmVmZXJTdGFibGUsICRwcmVmZXJMb3dlc3QpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSZXF1ZXN0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdChSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UsIFBsYXRmb3JtUmVwb3NpdG9yeSAkcGxhdGZvcm1SZXBvLCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvc2l0b3J5ID0gbnVsbCkKICAgIHsKICAgICAgICAkcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KCRsb2NrZWRSZXBvc2l0b3J5KTsKCiAgICAgICAgJHJlcXVlc3QtPmZpeFBhY2thZ2UoJHJvb3RQYWNrYWdlKTsKICAgICAgICBpZiAoJHJvb3RQYWNrYWdlIGluc3RhbmNlb2YgUm9vdEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkcmVxdWVzdC0+Zml4UGFja2FnZSgkcm9vdFBhY2thZ2UtPmdldEFsaWFzT2YoKSk7CiAgICAgICAgfQoKICAgICAgICAkZml4ZWRQYWNrYWdlcyA9ICRwbGF0Zm9ybVJlcG8tPmdldFBhY2thZ2VzKCk7CiAgICAgICAgaWYgKCR0aGlzLT5hZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICRmaXhlZFBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJGZpeGVkUGFja2FnZXMsICR0aGlzLT5hZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5LT5nZXRQYWNrYWdlcygpKTsKICAgICAgICB9CgogICAgICAgIC8vIGZpeCB0aGUgdmVyc2lvbiBvZiBhbGwgcGxhdGZvcm0gcGFja2FnZXMgKyBhZGRpdGlvbmFsbHkgaW5zdGFsbGVkIHBhY2thZ2VzCiAgICAgICAgLy8gdG8gcHJldmVudCB0aGUgc29sdmVyIHRyeWluZyB0byByZW1vdmUgb3IgdXBkYXRlIHRob3NlCiAgICAgICAgLy8gVE9ETyB3aHkgbm90IHJlcGxhY2VzPwogICAgICAgICRwcm92aWRlZCA9ICRyb290UGFja2FnZS0+Z2V0UHJvdmlkZXMoKTsKICAgICAgICBmb3JlYWNoICgkZml4ZWRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAvLyBza2lwIHBsYXRmb3JtIHBhY2thZ2VzIHRoYXQgYXJlIHByb3ZpZGVkIGJ5IHRoZSByb290IHBhY2thZ2UKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRSZXBvc2l0b3J5KCkgIT09ICRwbGF0Zm9ybVJlcG8KICAgICAgICAgICAgICAgIHx8ICFpc3NldCgkcHJvdmlkZWRbJHBhY2thZ2UtPmdldE5hbWUoKV0pCiAgICAgICAgICAgICAgICB8fCAhJHByb3ZpZGVkWyRwYWNrYWdlLT5nZXROYW1lKCldLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkcmVxdWVzdC0+Zml4UGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVxdWVzdDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcXVpcmVQYWNrYWdlc0ZvclVwZGF0ZShSZXF1ZXN0ICRyZXF1ZXN0LCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvc2l0b3J5ID0gbnVsbCwgJGluY2x1ZGVEZXZSZXF1aXJlcyA9IHRydWUpCiAgICB7CiAgICAgICAgLy8gaWYgd2UncmUgdXBkYXRpbmcgbWlycm9ycyB3ZSB3YW50IHRvIGtlZXAgZXhhY3RseSB0aGUgc2FtZSB2ZXJzaW9ucyBpbnN0YWxsZWQgd2hpY2ggYXJlIGluIHRoZSBsb2NrIGZpbGUsIGJ1dCB3ZSB3YW50IGN1cnJlbnQgcmVtb3RlIG1ldGFkYXRhCiAgICAgICAgaWYgKCR0aGlzLT51cGRhdGVNaXJyb3JzKSB7CiAgICAgICAgICAgICRleGNsdWRlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgaWYgKCEkaW5jbHVkZURldlJlcXVpcmVzKSB7CiAgICAgICAgICAgICAgICAkZXhjbHVkZWRQYWNrYWdlcyA9IGFycmF5X2ZsaXAoJHRoaXMtPmxvY2tlci0+Z2V0RGV2UGFja2FnZU5hbWVzKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSBhcyAkbG9ja2VkUGFja2FnZSkgewogICAgICAgICAgICAgICAgLy8gZXhjbHVkZSBhbGlhcyBwYWNrYWdlcyBoZXJlIGFzIGZvciByb290IGFsaWFzZXMsIGJvdGggYWxpYXMgYW5kIGFsaWFzZWQgYXJlCiAgICAgICAgICAgICAgICAvLyBwcmVzZW50IGluIHRoZSBsb2NrIHJlcG8gYW5kIHdlIG9ubHkgd2FudCB0byByZXF1aXJlIHRoZSBhbGlhc2VkIHZlcnNpb24KICAgICAgICAgICAgICAgIGlmICghJGxvY2tlZFBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYgIWlzc2V0KCRleGNsdWRlZFBhY2thZ2VzWyRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAgICAgICAgICRyZXF1ZXN0LT5yZXF1aXJlTmFtZSgkbG9ja2VkUGFja2FnZS0+Z2V0TmFtZSgpLCBuZXcgQ29uc3RyYWludCgnPT0nLCAkbG9ja2VkUGFja2FnZS0+Z2V0VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbGlua3MgPSAkdGhpcy0+cGFja2FnZS0+Z2V0UmVxdWlyZXMoKTsKICAgICAgICAgICAgaWYgKCRpbmNsdWRlRGV2UmVxdWlyZXMpIHsKICAgICAgICAgICAgICAgICRsaW5rcyA9IGFycmF5X21lcmdlKCRsaW5rcywgJHRoaXMtPnBhY2thZ2UtPmdldERldlJlcXVpcmVzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHJlcXVlc3QtPnJlcXVpcmVOYW1lKCRsaW5rLT5nZXRUYXJnZXQoKSwgJGxpbmstPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGJvb2wgICRmb3JVcGRhdGUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSb290QWxpYXNlcygkZm9yVXBkYXRlKQogICAgewogICAgICAgIGlmICgkZm9yVXBkYXRlKSB7CiAgICAgICAgICAgICRhbGlhc2VzID0gJHRoaXMtPnBhY2thZ2UtPmdldEFsaWFzZXMoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYWxpYXNlcyA9ICR0aGlzLT5sb2NrZXItPmdldEFsaWFzZXMoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYWxpYXNlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgYXJyYXkgJGxpbmtzCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdFBsYXRmb3JtUmVxdWlyZW1lbnRzKGFycmF5ICRsaW5rcykKICAgIHsKICAgICAgICAkcGxhdGZvcm1SZXFzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJGxpbmstPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgJHBsYXRmb3JtUmVxc1skbGluay0+Z2V0VGFyZ2V0KCldID0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwbGF0Zm9ybVJlcXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBsYWNlIGxvY2FsIHJlcG9zaXRvcmllcyB3aXRoIEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeSBpbnN0YW5jZXMKICAgICAqCiAgICAgKiBUaGlzIGlzIHRvIHByZXZlbnQgYW55IGFjY2lkZW50YWwgbW9kaWZpY2F0aW9uIG9mIHRoZSBleGlzdGluZyByZXBvcyBvbiBkaXNrCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlNYW5hZ2VyICRybQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1vY2tMb2NhbFJlcG9zaXRvcmllcyhSZXBvc2l0b3J5TWFuYWdlciAkcm0pCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcm0tPmdldExvY2FsUmVwb3NpdG9yeSgpLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICRwYWNrYWdlc1soc3RyaW5nKSAkcGFja2FnZV0gPSBjbG9uZSAkcGFja2FnZTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRrZXkgPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkYWxpYXMgPSAoc3RyaW5nKSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgJHBhY2thZ2VzWyRrZXldID0gbmV3IEFsaWFzUGFja2FnZSgkcGFja2FnZXNbJGFsaWFzXSwgJHBhY2thZ2UtPmdldFZlcnNpb24oKSwgJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHJtLT5zZXRMb2NhbFJlcG9zaXRvcnkoCiAgICAgICAgICAgIG5ldyBJbnN0YWxsZWRBcnJheVJlcG9zaXRvcnkoJHBhY2thZ2VzKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgSW5zdGFsbGVyCiAgICAgKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAkaW8KICAgICAqIEBwYXJhbSAgQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZShJT0ludGVyZmFjZSAkaW8sIENvbXBvc2VyICRjb21wb3NlcikKICAgIHsKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygKICAgICAgICAgICAgJGlvLAogICAgICAgICAgICAkY29tcG9zZXItPmdldENvbmZpZygpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldFBhY2thZ2UoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldExvY2tlcigpLAogICAgICAgICAgICAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRBdXRvbG9hZEdlbmVyYXRvcigpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgUmVwb3NpdG9yeUludGVyZmFjZSAkYWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeQogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWRkaXRpb25hbEZpeGVkUmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRhZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5KQogICAgewogICAgICAgICR0aGlzLT5hZGRpdGlvbmFsRml4ZWRSZXBvc2l0b3J5ID0gJGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gcnVuIGluIGRyeW1vZGUgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGRyeVJ1bgogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERyeVJ1bigkZHJ5UnVuID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZHJ5UnVuID0gKGJvb2wpICRkcnlSdW47CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcywgaWYgdGhpcyBpcyBhIGRyeSBydW4gKHNpbXVsYXRpb24gbW9kZSkuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RyeVJ1bigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kcnlSdW47CiAgICB9CgogICAgLyoqCiAgICAgKiBwcmVmZXIgc291cmNlIGluc3RhbGxhdGlvbgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRwcmVmZXJTb3VyY2UKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlclNvdXJjZSA9IChib29sKSAkcHJlZmVyU291cmNlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBwcmVmZXIgZGlzdCBpbnN0YWxsYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkcHJlZmVyRGlzdAogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlckRpc3QoJHByZWZlckRpc3QgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5wcmVmZXJEaXN0ID0gKGJvb2wpICRwcmVmZXJEaXN0OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCBnZW5lcmF0ZWQgYXV0b2xvYWRlciBhcmUgb3B0aW1pemVkCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJG9wdGltaXplQXV0b2xvYWRlcgogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGltaXplQXV0b2xvYWRlcigkb3B0aW1pemVBdXRvbG9hZGVyKQogICAgewogICAgICAgICR0aGlzLT5vcHRpbWl6ZUF1dG9sb2FkZXIgPSAoYm9vbCkgJG9wdGltaXplQXV0b2xvYWRlcjsKICAgICAgICBpZiAoISR0aGlzLT5vcHRpbWl6ZUF1dG9sb2FkZXIpIHsKICAgICAgICAgICAgLy8gRm9yY2UgY2xhc3NNYXBBdXRob3JpdGF0aXZlIG9mZiB3aGVuIG5vdCBvcHRpbWl6aW5nIHRoZQogICAgICAgICAgICAvLyBhdXRvbG9hZGVyCiAgICAgICAgICAgICR0aGlzLT5zZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciBvciBub3QgZ2VuZXJhdGVkIGF1dG9sb2FkZXIgY29uc2lkZXJzIHRoZSBjbGFzcyBtYXAKICAgICAqIGF1dGhvcml0YXRpdmUuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZQogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY2xhc3NNYXBBdXRob3JpdGF0aXZlKQogICAgewogICAgICAgICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmUgPSAoYm9vbCkgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZTsKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAvLyBGb3JjZSBvcHRpbWl6ZUF1dG9sb2FkZXIgd2hlbiBjbGFzc21hcCBpcyBhdXRob3JpdGF0aXZlCiAgICAgICAgICAgICR0aGlzLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIodHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgQVBDdSBjYWNoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgJGFwY3VBdXRvbG9hZGVyCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xudWxsICRhcGN1QXV0b2xvYWRlclByZWZpeAogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFwY3VBdXRvbG9hZGVyKCRhcGN1QXV0b2xvYWRlciwgJGFwY3VBdXRvbG9hZGVyUHJlZml4ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YXBjdUF1dG9sb2FkZXIgPSAkYXBjdUF1dG9sb2FkZXI7CiAgICAgICAgJHRoaXMtPmFwY3VBdXRvbG9hZGVyUHJlZml4ID0gJGFwY3VBdXRvbG9hZGVyUHJlZml4OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB1cGRhdGUgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkdXBkYXRlCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlKCR1cGRhdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZSA9IChib29sKSAkdXBkYXRlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBbGxvd3MgZGlzYWJsaW5nIHRoZSBpbnN0YWxsIHN0ZXAgYWZ0ZXIgYW4gdXBkYXRlCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGluc3RhbGwKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnN0YWxsKCRpbnN0YWxsKQogICAgewogICAgICAgICR0aGlzLT5pbnN0YWxsID0gKGJvb2wpICRpbnN0YWxsOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBlbmFibGVzIGRldiBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRkZXZNb2RlCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2TW9kZSgkZGV2TW9kZSA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAoYm9vbCkgJGRldk1vZGU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHNldCB3aGV0aGVyIHRvIHJ1biBhdXRvbG9hZGVyIG9yIG5vdAogICAgICoKICAgICAqIFRoaXMgaXMgZGlzYWJsZWQgaW1wbGljaXRseSB3aGVuIGVuYWJsaW5nIGRyeVJ1bgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRkdW1wQXV0b2xvYWRlcgogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldER1bXBBdXRvbG9hZGVyKCRkdW1wQXV0b2xvYWRlciA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmR1bXBBdXRvbG9hZGVyID0gKGJvb2wpICRkdW1wQXV0b2xvYWRlcjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogc2V0IHdoZXRoZXIgdG8gcnVuIHNjcmlwdHMgb3Igbm90CiAgICAgKgogICAgICogVGhpcyBpcyBkaXNhYmxlZCBpbXBsaWNpdGx5IHdoZW4gZW5hYmxpbmcgZHJ5UnVuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJHJ1blNjcmlwdHMKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSdW5TY3JpcHRzKCRydW5TY3JpcHRzID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+cnVuU2NyaXB0cyA9IChib29sKSAkcnVuU2NyaXB0czsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogc2V0IHRoZSBjb25maWcgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAkY29uZmlnCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmlnKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBydW4gaW4gdmVyYm9zZSBtb2RlCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJHZlcmJvc2UKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWZXJib3NlKCR2ZXJib3NlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyYm9zZSA9IChib29sKSAkdmVyYm9zZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzLCBpZiBydW5uaW5nIGluIHZlcmJvc2UgbW9kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52ZXJib3NlOwogICAgfQoKICAgIC8qKgogICAgICogc2V0IGlnbm9yZSBQbGF0Zm9ybSBQYWNrYWdlIHJlcXVpcmVtZW50cwogICAgICoKICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIHRydWUsIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgYXJlIGlnbm9yZWQKICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIGZhbHNlLCBubyBwbGF0Zm9ybSByZXF1aXJlbWVudHMgYXJlIGlnbm9yZWQKICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIHN0cmluZ1tdLCB0aG9zZSBwYWNrYWdlcyB3aWxsIGJlIGlnbm9yZWQKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2x8YXJyYXkgJGlnbm9yZVBsYXRmb3JtUmVxcwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElnbm9yZVBsYXRmb3JtUmVxdWlyZW1lbnRzKCRpZ25vcmVQbGF0Zm9ybVJlcXMpCiAgICB7CiAgICAgICAgaWYgKGlzX2FycmF5KCRpZ25vcmVQbGF0Zm9ybVJlcXMpKSB7CiAgICAgICAgICAgICR0aGlzLT5pZ25vcmVQbGF0Zm9ybVJlcXMgPSBhcnJheV9maWx0ZXIoJGlnbm9yZVBsYXRmb3JtUmVxcywgZnVuY3Rpb24gKCRyZXEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZXEpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzID0gKGJvb2wpICRpZ25vcmVQbGF0Zm9ybVJlcXM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcGRhdGUgdGhlIGxvY2sgZmlsZSB0byB0aGUgZXhhY3Qgc2FtZSB2ZXJzaW9ucyBhbmQgcmVmZXJlbmNlcyBidXQgdXNlIGN1cnJlbnQgcmVtb3RlIG1ldGFkYXRhIGxpa2UgVVJMcyBhbmQgbWlycm9yIGluZm8KICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAkdXBkYXRlTWlycm9ycwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFVwZGF0ZU1pcnJvcnMoJHVwZGF0ZU1pcnJvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZU1pcnJvcnMgPSAkdXBkYXRlTWlycm9yczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogcmVzdHJpY3QgdGhlIHVwZGF0ZSBvcGVyYXRpb24gdG8gYSBmZXcgcGFja2FnZXMsIGFsbCBvdGhlciBwYWNrYWdlcwogICAgICogdGhhdCBhcmUgYWxyZWFkeSBpbnN0YWxsZWQgd2lsbCBiZSBrZXB0IGF0IHRoZWlyIGN1cnJlbnQgdmVyc2lvbgogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICRwYWNrYWdlcwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFVwZGF0ZUFsbG93TGlzdChhcnJheSAkcGFja2FnZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCA9IGFycmF5X2ZsaXAoYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgJHBhY2thZ2VzKSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNob3VsZCBkZXBlbmRlbmNpZXMgb2YgcGFja2FnZXMgbWFya2VkIGZvciB1cGRhdGUgYmUgdXBkYXRlZD8KICAgICAqCiAgICAgKiBEZXBlbmRpbmcgb24gdGhlIGNob3NlbiBjb25zdGFudCB0aGlzIHdpbGwgZWl0aGVyIG9ubHkgdXBkYXRlIHRoZSBkaXJlY3RseSBuYW1lZCBwYWNrYWdlcywgYWxsIHRyYW5zaXRpdmUKICAgICAqIGRlcGVuZGVuY2llcyB3aGljaCBhcmUgbm90IHJvb3QgcmVxdWlyZW1lbnQgb3IgYWxsIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIGluY2x1ZGluZyByb290IHJlcXVpcmVtZW50cwogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgT25lIG9mIHRoZSBVUERBVEVfIGNvbnN0YW50cyBvbiB0aGUgUmVxdWVzdCBjbGFzcwogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcygkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcywgYXJyYXkoUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVELCBSZXF1ZXN0OjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTX05PX1JPT1RfUkVRVUlSRSwgUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUyksIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCB2YWx1ZSBmb3IgdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzIHN1cHBsaWVkIik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2hvdWxkIHBhY2thZ2VzIGJlIHByZWZlcnJlZCBpbiBhIHN0YWJsZSB2ZXJzaW9uIHdoZW4gdXBkYXRpbmc/CiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJHByZWZlclN0YWJsZQogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlclN0YWJsZSgkcHJlZmVyU3RhYmxlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZmVyU3RhYmxlID0gKGJvb2wpICRwcmVmZXJTdGFibGU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNob3VsZCBwYWNrYWdlcyBiZSBwcmVmZXJyZWQgaW4gYSBsb3dlc3QgdmVyc2lvbiB3aGVuIHVwZGF0aW5nPwogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICRwcmVmZXJMb3dlc3QKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJMb3dlc3QoJHByZWZlckxvd2VzdCA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZWZlckxvd2VzdCA9IChib29sKSAkcHJlZmVyTG93ZXN0OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaG91bGQgdGhlIGxvY2sgZmlsZSBiZSB1cGRhdGVkIHdoZW4gdXBkYXRpbmc/CiAgICAgKgogICAgICogVGhpcyBpcyBkaXNhYmxlZCBpbXBsaWNpdGx5IHdoZW4gZW5hYmxpbmcgZHJ5UnVuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJHdyaXRlTG9jawogICAgICogQHJldHVybiBJbnN0YWxsZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFdyaXRlTG9jaygkd3JpdGVMb2NrID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVMb2NrID0gKGJvb2wpICR3cml0ZUxvY2s7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNob3VsZCB0aGUgb3BlcmF0aW9ucyAocGFja2FnZSBpbnN0YWxsLCB1cGRhdGUgYW5kIHJlbW92YWwpIGJlIGV4ZWN1dGVkIG9uIGRpc2s/CiAgICAgKgogICAgICogVGhpcyBpcyBkaXNhYmxlZCBpbXBsaWNpdGx5IHdoZW4gZW5hYmxpbmcgZHJ5UnVuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgJGV4ZWN1dGVPcGVyYXRpb25zCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhlY3V0ZU9wZXJhdGlvbnMoJGV4ZWN1dGVPcGVyYXRpb25zID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMgPSAoYm9vbCkgJGV4ZWN1dGVPcGVyYXRpb25zOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNhYmxlcyBwbHVnaW5zLgogICAgICoKICAgICAqIENhbGwgdGhpcyBpZiB5b3Ugd2FudCB0byBlbnN1cmUgdGhhdCB0aGlyZC1wYXJ0eSBjb2RlIG5ldmVyIGdldHMKICAgICAqIGV4ZWN1dGVkLiBUaGUgZGVmYXVsdCBpcyB0byBhdXRvbWF0aWNhbGx5IGluc3RhbGwsIGFuZCBleGVjdXRlCiAgICAgKiBjdXN0b20gdGhpcmQtcGFydHkgaW5zdGFsbGVycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZVBsdWdpbnMoKQogICAgewogICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyLT5kaXNhYmxlUGx1Z2lucygpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIgJHN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIKICAgICAqIEByZXR1cm4gSW5zdGFsbGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIgJHN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIgPSAkc3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsYXRmb3JtOwoKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhlY3V0YWJsZUZpbmRlcjsKCmNsYXNzIEhodm1EZXRlY3Rvcgp7CiAgICBwcml2YXRlIHN0YXRpYyAkaGh2bVZlcnNpb247CiAgICBwcml2YXRlICRleGVjdXRhYmxlRmluZGVyOwogICAgcHJpdmF0ZSAkcHJvY2Vzc0V4ZWN1dG9yOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChFeGVjdXRhYmxlRmluZGVyICAkZXhlY3V0YWJsZUZpbmRlciA9IG51bGwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2Vzc0V4ZWN1dG9yID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXhlY3V0YWJsZUZpbmRlciA9ICRleGVjdXRhYmxlRmluZGVyOwogICAgICAgICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IgPSAkcHJvY2Vzc0V4ZWN1dG9yOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZXNldCgpCiAgICB7CiAgICAgICAgc2VsZjo6JGhodm1WZXJzaW9uID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09IHNlbGY6OiRoaHZtVmVyc2lvbikgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGhodm1WZXJzaW9uID86IG51bGw7CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokaGh2bVZlcnNpb24gPSBkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSA/IEhIVk1fVkVSU0lPTiA6IG51bGw7CiAgICAgICAgaWYgKHNlbGY6OiRoaHZtVmVyc2lvbiA9PT0gbnVsbCAmJiAhUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgIHNlbGY6OiRoaHZtVmVyc2lvbiA9IGZhbHNlOwogICAgICAgICAgICAkdGhpcy0+ZXhlY3V0YWJsZUZpbmRlciA9ICR0aGlzLT5leGVjdXRhYmxlRmluZGVyID86IG5ldyBFeGVjdXRhYmxlRmluZGVyKCk7CiAgICAgICAgICAgICRoaHZtUGF0aCA9ICR0aGlzLT5leGVjdXRhYmxlRmluZGVyLT5maW5kKCdoaHZtJyk7CiAgICAgICAgICAgIGlmICgkaGh2bVBhdGggIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IgPSAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoKTsKICAgICAgICAgICAgICAgICRleGl0Q29kZSA9ICR0aGlzLT5wcm9jZXNzRXhlY3V0b3ItPmV4ZWN1dGUoCiAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGhodm1QYXRoKS4KICAgICAgICAgICAgICAgICAgICAnIC0tcGhwIC1kIGhodm0uaml0PTAgLXIgImVjaG8gSEhWTV9WRVJTSU9OOyIgMj4vZGV2L251bGwnLAogICAgICAgICAgICAgICAgICAgIHNlbGY6OiRoaHZtVmVyc2lvbgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkZXhpdENvZGUgIT09IDApIHsKICAgICAgICAgICAgICAgICAgICBzZWxmOjokaGh2bVZlcnNpb24gPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRoaHZtVmVyc2lvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbGF0Zm9ybTsKCi8qKgogKiBAYXV0aG9yIExhcnMgU3Ryb2pueSA8bGFyc0BzdHJvam55Lm5ldD4KICovCmNsYXNzIFZlcnNpb24KewogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRvcGVuc3NsVmVyc2lvbgogICAgICogQHBhcmFtICBib29sICAgICAgICAkaXNGaXBzCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFyc2VPcGVuc3NsKCRvcGVuc3NsVmVyc2lvbiwgJiRpc0ZpcHMpCiAgICB7CiAgICAgICAgJGlzRmlwcyA9IGZhbHNlOwoKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eKD88dmVyc2lvbj5bMC05Ll0rKSg/PHBhdGNoPlthLXpdezAsMn0pPyg/PHN1ZmZpeD4oPzotPyg/OmRldnxwcmV8YWxwaGF8YmV0YXxyY3xmaXBzKVtcZF0qKSopPyQvJywgJG9wZW5zc2xWZXJzaW9uLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkaXNGaXBzID0gc3RycG9zKCRtYXRjaGVzWydzdWZmaXgnXSwgJ2ZpcHMnKSAhPT0gZmFsc2U7CiAgICAgICAgJHN1ZmZpeCA9IHN0cnRyKCctJy5sdHJpbSgkbWF0Y2hlc1snc3VmZml4J10sICctJyksIGFycmF5KCctZmlwcycgPT4gJycsICctcHJlJyA9PiAnLWFscGhhJykpOwogICAgICAgICRwYXRjaCA9IHNlbGY6OmNvbnZlcnRBbHBoYVZlcnNpb25Ub0ludFZlcnNpb24oJG1hdGNoZXNbJ3BhdGNoJ10pOwoKICAgICAgICByZXR1cm4gcnRyaW0oJG1hdGNoZXNbJ3ZlcnNpb24nXS4nLicuJHBhdGNoLiRzdWZmaXgsICctJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRsaWJqcGVnVmVyc2lvbgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHBhcnNlTGlianBlZygkbGlianBlZ1ZlcnNpb24pCiAgICB7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvXig/PG1ham9yPlxkKykoPzxtaW5vcj5bYS16XSopJC8nLCAkbGlianBlZ1ZlcnNpb24sICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlc1snbWFqb3InXS4nLicuc2VsZjo6Y29udmVydEFscGhhVmVyc2lvblRvSW50VmVyc2lvbigkbWF0Y2hlc1snbWlub3InXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICR6b25laW5mb1ZlcnNpb24KICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZVpvbmVpbmZvVmVyc2lvbigkem9uZWluZm9WZXJzaW9uKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL14oPzx5ZWFyPlxkezR9KSg/PHJldmlzaW9uPlthLXpdKikkLycsICR6b25laW5mb1ZlcnNpb24sICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlc1sneWVhciddLicuJy5zZWxmOjpjb252ZXJ0QWxwaGFWZXJzaW9uVG9JbnRWZXJzaW9uKCRtYXRjaGVzWydyZXZpc2lvbiddKTsKICAgIH0KCiAgICAvKioKICAgICAqICIiID0+IDAsICJhIiA9PiAxLCAiemciID0+IDMzCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGFscGhhCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0QWxwaGFWZXJzaW9uVG9JbnRWZXJzaW9uKCRhbHBoYSkKICAgIHsKICAgICAgICByZXR1cm4gc3RybGVuKCRhbHBoYSkgKiAoLW9yZCgnYScpICsgMSkgKyBhcnJheV9zdW0oYXJyYXlfbWFwKCdvcmQnLCBzdHJfc3BsaXQoJGFscGhhKSkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgICAgJHZlcnNpb25JZAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0TGlieHBtVmVyc2lvbklkKCR2ZXJzaW9uSWQpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmNvbnZlcnRWZXJzaW9uSWQoJHZlcnNpb25JZCwgMTAwKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgaW50ICAgICR2ZXJzaW9uSWQKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29udmVydE9wZW5sZGFwVmVyc2lvbklkKCR2ZXJzaW9uSWQpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmNvbnZlcnRWZXJzaW9uSWQoJHZlcnNpb25JZCwgMTAwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0VmVyc2lvbklkKCR2ZXJzaW9uSWQsICRiYXNlKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKAogICAgICAgICAgICAnJWQuJWQuJWQnLAogICAgICAgICAgICAkdmVyc2lvbklkIC8gKCRiYXNlICogJGJhc2UpLAogICAgICAgICAgICAoJHZlcnNpb25JZCAvICRiYXNlKSAlICRiYXNlLAogICAgICAgICAgICAkdmVyc2lvbklkICUgJGJhc2UKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsYXRmb3JtOwoKY2xhc3MgUnVudGltZQp7CiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRjb25zdGFudAogICAgICogQHBhcmFtICBjbGFzcy1zdHJpbmcgJGNsYXNzCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0NvbnN0YW50KCRjb25zdGFudCwgJGNsYXNzID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gZGVmaW5lZChsdHJpbSgkY2xhc3MuJzo6Jy4kY29uc3RhbnQsICc6JykpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgJGNvbnN0YW50CiAgICAgKiBAcGFyYW0gIGNsYXNzLXN0cmluZyAkY2xhc3MKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnN0YW50KCRjb25zdGFudCwgJGNsYXNzID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gY29uc3RhbnQobHRyaW0oJGNsYXNzLic6OicuJGNvbnN0YW50LCAnOicpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRmbgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNGdW5jdGlvbigkZm4pCiAgICB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uX2V4aXN0cygkZm4pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBjYWxsYWJsZSAkY2FsbGFibGUKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgJGFyZ3VtZW50cwogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW52b2tlKCRjYWxsYWJsZSwgYXJyYXkgJGFyZ3VtZW50cyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCRjYWxsYWJsZSwgJGFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGNsYXNzLXN0cmluZyAkY2xhc3MKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ2xhc3MoJGNsYXNzKQogICAgewogICAgICAgIHJldHVybiBjbGFzc19leGlzdHMoJGNsYXNzLCBmYWxzZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGNsYXNzLXN0cmluZyAkY2xhc3MKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICAgICRhcmd1bWVudHMKICAgICAqIEByZXR1cm4gb2JqZWN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25zdHJ1Y3QoJGNsYXNzLCBhcnJheSAkYXJndW1lbnRzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJGFyZ3VtZW50cykpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyAkY2xhc3M7CiAgICAgICAgfQoKICAgICAgICAkcmVmbCA9IG5ldyBcUmVmbGVjdGlvbkNsYXNzKCRjbGFzcyk7CgogICAgICAgIHJldHVybiAkcmVmbC0+bmV3SW5zdGFuY2VBcmdzKCRhcmd1bWVudHMpOwogICAgfQoKICAgIC8qKiBAcmV0dXJuIHN0cmluZ1tdICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuIGdldF9sb2FkZWRfZXh0ZW5zaW9ucygpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJGV4dGVuc2lvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dGVuc2lvblZlcnNpb24oJGV4dGVuc2lvbikKICAgIHsKICAgICAgICByZXR1cm4gcGhwdmVyc2lvbigkZXh0ZW5zaW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRleHRlbnNpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHRlbnNpb25JbmZvKCRleHRlbnNpb24pCiAgICB7CiAgICAgICAgJHJlZmxlY3RvciA9IG5ldyBcUmVmbGVjdGlvbkV4dGVuc2lvbigkZXh0ZW5zaW9uKTsKCiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICAkcmVmbGVjdG9yLT5pbmZvKCk7CgogICAgICAgIHJldHVybiBvYl9nZXRfY2xlYW4oKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCnVzZSBDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxWZXJzaW9uUGFyc2VyOwoKLyoqCiAqIFRoaXMgY2xhc3MgaXMgY29waWVkIGluIGV2ZXJ5IENvbXBvc2VyIGluc3RhbGxlZCBwcm9qZWN0IGFuZCBhdmFpbGFibGUgdG8gYWxsCiAqCiAqIFNlZSBhbHNvIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wNy1ydW50aW1lLm1kI2luc3RhbGxlZC12ZXJzaW9ucwogKgogKiBUbyByZXF1aXJlIGl0J3MgcHJlc2VuY2UsIHlvdSBjYW4gcmVxdWlyZSBgY29tcG9zZXItcnVudGltZS1hcGkgXjIuMGAKICovCmNsYXNzIEluc3RhbGxlZFZlcnNpb25zCnsKICAgIHByaXZhdGUgc3RhdGljICRpbnN0YWxsZWQ7CiAgICBwcml2YXRlIHN0YXRpYyAkY2FuR2V0VmVuZG9yczsKICAgIHByaXZhdGUgc3RhdGljICRpbnN0YWxsZWRCeVZlbmRvciA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgcGFja2FnZSBuYW1lcyB3aGljaCBhcmUgcHJlc2VudCwgZWl0aGVyIGJ5IGJlaW5nIGluc3RhbGxlZCwgcmVwbGFjZWQgb3IgcHJvdmlkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGxpc3Q8c3RyaW5nPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEluc3RhbGxlZFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgJHBhY2thZ2VzW10gPSBhcnJheV9rZXlzKCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXNbMF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cyhhcnJheV9mbGlwKFxjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGFja2FnZSBpcyBpbnN0YWxsZWQKICAgICAqCiAgICAgKiBUaGlzIGFsc28gcmV0dXJucyB0cnVlIGlmIHRoZSBwYWNrYWdlIG5hbWUgaXMgcHJvdmlkZWQgb3IgcmVwbGFjZWQgYnkgYW5vdGhlciBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0luc3RhbGxlZCgkcGFja2FnZU5hbWUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBwYWNrYWdlIHNhdGlzZmllcyBhIHZlcnNpb24gY29uc3RyYWludAogICAgICoKICAgICAqIGUuZy4gSWYgeW91IHdhbnQgdG8ga25vdyB3aGV0aGVyIHZlcnNpb24gMi4zKyBvZiBwYWNrYWdlIGZvby9iYXIgaXMgaW5zdGFsbGVkLCB5b3Ugd291bGQgY2FsbDoKICAgICAqCiAgICAgKiAgIENvbXBvc2VyXEluc3RhbGxlZFZlcnNpb25zOjpzYXRpc2ZpZXMobmV3IFZlcnNpb25QYXJzZXIsICdmb28vYmFyJywgJ14yLjMnKQogICAgICoKICAgICAqIEBwYXJhbSBWZXJzaW9uUGFyc2VyICRwYXJzZXIgICAgICBJbnN0YWxsIGNvbXBvc2VyL3NlbXZlciB0byBoYXZlIGFjY2VzcyB0byB0aGlzIGNsYXNzIGFuZCBmdW5jdGlvbmFsaXR5CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAkcGFja2FnZU5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICRjb25zdHJhaW50ICBBIHZlcnNpb24gY29uc3RyYWludCB0byBjaGVjayBmb3IsIGlmIHlvdSBwYXNzIG9uZSB5b3UgaGF2ZSB0byBtYWtlIHN1cmUgY29tcG9zZXIvc2VtdmVyIGlzIHJlcXVpcmVkIGJ5IHlvdXIgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhdGlzZmllcyhWZXJzaW9uUGFyc2VyICRwYXJzZXIsICRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJGNvbnN0cmFpbnQgPSAkcGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICAkcHJvdmlkZWQgPSAkcGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKHNlbGY6OmdldFZlcnNpb25SYW5nZXMoJHBhY2thZ2VOYW1lKSk7CgogICAgICAgIHJldHVybiAkcHJvdmlkZWQtPm1hdGNoZXMoJGNvbnN0cmFpbnQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHZlcnNpb24gY29uc3RyYWludCByZXByZXNlbnRpbmcgYWxsIHRoZSByYW5nZShzKSB3aGljaCBhcmUgaW5zdGFsbGVkIGZvciBhIGdpdmVuIHBhY2thZ2UKICAgICAqCiAgICAgKiBJdCBpcyBlYXNpZXIgdG8gdXNlIHRoaXMgdmlhIGlzSW5zdGFsbGVkKCkgd2l0aCB0aGUgJGNvbnN0cmFpbnQgYXJndW1lbnQgaWYgeW91IG5lZWQgdG8gY2hlY2sKICAgICAqIHdoZXRoZXIgYSBnaXZlbiB2ZXJzaW9uIG9mIGEgcGFja2FnZSBpcyBpbnN0YWxsZWQsIGFuZCBub3QganVzdCB3aGV0aGVyIGl0IGV4aXN0cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmcgVmVyc2lvbiBjb25zdHJhaW50IHVzYWJsZSB3aXRoIGNvbXBvc2VyL3NlbXZlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb25SYW5nZXMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJhbmdlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzW10gPSAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ2FsaWFzZXMnLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkcmFuZ2VzID0gYXJyYXlfbWVyZ2UoJHJhbmdlcywgJGluc3RhbGxlZFsndmVyc2lvbnMnXVskcGFja2FnZU5hbWVdWydhbGlhc2VzJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdyZXBsYWNlZCcsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICRyYW5nZXMgPSBhcnJheV9tZXJnZSgkcmFuZ2VzLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlcGxhY2VkJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdwcm92aWRlZCcsICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgICRyYW5nZXMgPSBhcnJheV9tZXJnZSgkcmFuZ2VzLCAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3Byb3ZpZGVkJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaW1wbG9kZSgnIHx8ICcsICRyYW5nZXMpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIElmIHRoZSBwYWNrYWdlIGlzIGJlaW5nIHJlcGxhY2VkIG9yIHByb3ZpZGVkIGJ1dCBpcyBub3QgcmVhbGx5IGluc3RhbGxlZCwgbnVsbCB3aWxsIGJlIHJldHVybmVkIGFzIHZlcnNpb24sIHVzZSBzYXRpc2ZpZXMgb3IgZ2V0VmVyc2lvblJhbmdlcyBpZiB5b3UgbmVlZCB0byBrbm93IGlmIGEgZ2l2ZW4gdmVyc2lvbiBpcyBwcmVzZW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigkcGFja2FnZU5hbWUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6Z2V0SW5zdGFsbGVkKCkgYXMgJGluc3RhbGxlZCkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyB2ZXJzaW9uLCB1c2Ugc2F0aXNmaWVzIG9yIGdldFZlcnNpb25SYW5nZXMgaWYgeW91IG5lZWQgdG8ga25vdyBpZiBhIGdpdmVuIHZlcnNpb24gaXMgcHJlc2VudAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3ByZXR0eV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRpbnN0YWxsZWRbJ3ZlcnNpb25zJ11bJHBhY2thZ2VOYW1lXVsncHJldHR5X3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcT3V0T2ZCb3VuZHNFeGNlcHRpb24oJ1BhY2thZ2UgIicgLiAkcGFja2FnZU5hbWUgLiAnIiBpcyBub3QgaW5zdGFsbGVkJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRwYWNrYWdlTmFtZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBJZiB0aGUgcGFja2FnZSBpcyBiZWluZyByZXBsYWNlZCBvciBwcm92aWRlZCBidXQgaXMgbm90IHJlYWxseSBpbnN0YWxsZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZCBhcyByZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSZWZlcmVuY2UoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgIGZvcmVhY2ggKHNlbGY6OmdldEluc3RhbGxlZCgpIGFzICRpbnN0YWxsZWQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlZmVyZW5jZSddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVkWyd2ZXJzaW9ucyddWyRwYWNrYWdlTmFtZV1bJ3JlZmVyZW5jZSddOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignUGFja2FnZSAiJyAuICRwYWNrYWdlTmFtZSAuICciIGlzIG5vdCBpbnN0YWxsZWQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXl7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHJlZmVyZW5jZTogc3RyaW5nLCBwcmV0dHlfdmVyc2lvbjogc3RyaW5nLCBhbGlhc2VzOiBzdHJpbmdbXX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSb290UGFja2FnZSgpCiAgICB7CiAgICAgICAgJGluc3RhbGxlZCA9IHNlbGY6OmdldEluc3RhbGxlZCgpOwoKICAgICAgICByZXR1cm4gJGluc3RhbGxlZFswXVsncm9vdCddOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmF3IGluc3RhbGxlZC5waHAgZGF0YSBmb3IgY3VzdG9tIGltcGxlbWVudGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXQogICAgICogQHBzYWxtLXJldHVybiBhcnJheXtyb290OiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7cHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdfT59CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UmF3RGF0YSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRpbnN0YWxsZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBMZXRzIHlvdSByZWxvYWQgdGhlIHN0YXRpYyBhcnJheSBmcm9tIGFub3RoZXIgZmlsZQogICAgICoKICAgICAqIFRoaXMgaXMgb25seSB1c2VmdWwgZm9yIGNvbXBsZXggaW50ZWdyYXRpb25zIGluIHdoaWNoIGEgcHJvamVjdCBuZWVkcyB0byB1c2UKICAgICAqIHRoaXMgY2xhc3MgYnV0IHRoZW4gYWxzbyBuZWVkcyB0byBleGVjdXRlIGFub3RoZXIgcHJvamVjdCdzIGF1dG9sb2FkZXIgaW4gcHJvY2VzcywKICAgICAqIGFuZCB3YW50cyB0byBlbnN1cmUgYm90aCBwcm9qZWN0cyBoYXZlIGFjY2VzcyB0byB0aGVpciB2ZXJzaW9uIG9mIGluc3RhbGxlZC5waHAuCiAgICAgKgogICAgICogQSB0eXBpY2FsIGNhc2Ugd291bGQgYmUgUEhQVW5pdCwgd2hlcmUgaXQgd291bGQgbmVlZCB0byBtYWtlIHN1cmUgaXQgcmVhZHMgYWxsCiAgICAgKiB0aGUgZGF0YSBpdCBuZWVkcyBmcm9tIHRoaXMgY2xhc3MsIHRoZW4gY2FsbCByZWxvYWQoKSB3aXRoCiAgICAgKiBgcmVxdWlyZSAkQ1dEL3ZlbmRvci9jb21wb3Nlci9pbnN0YWxsZWQucGhwYCAob3Igc2ltaWxhcikgYXMgaW5wdXQgdG8gbWFrZSBzdXJlCiAgICAgKiB0aGUgcHJvamVjdCBpbiB3aGljaCBpdCBydW5zIGNhbiB0aGVuIGFsc28gdXNlIHRoaXMgY2xhc3Mgc2FmZWx5LCB3aXRob3V0CiAgICAgKiBpbnRlcmZlcmVuY2UgYmV0d2VlbiBQSFBVbml0J3MgZGVwZW5kZW5jaWVzIGFuZCB0aGUgcHJvamVjdCdzIGRlcGVuZGVuY2llcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5W10gJGRhdGEgQSB2ZW5kb3IvY29tcG9zZXIvaW5zdGFsbGVkLnBocCBkYXRhIHNldAogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHBzYWxtLXBhcmFtIGFycmF5e3Jvb3Q6IGFycmF5e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCByZWZlcmVuY2U6IHN0cmluZywgcHJldHR5X3ZlcnNpb246IHN0cmluZywgYWxpYXNlczogc3RyaW5nW119LCB2ZXJzaW9uczogYXJyYXk8c3RyaW5nLCBhcnJheXtwcmV0dHlfdmVyc2lvbj86IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgYWxpYXNlcz86IHN0cmluZ1tdLCByZWZlcmVuY2U/OiBzdHJpbmcsIHJlcGxhY2VkPzogc3RyaW5nW10sIHByb3ZpZGVkPzogc3RyaW5nW119Pn0gJGRhdGEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWxvYWQoJGRhdGEpCiAgICB7CiAgICAgICAgc2VsZjo6JGluc3RhbGxlZCA9ICRkYXRhOwogICAgICAgIHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvciA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5W10KICAgICAqIEBwc2FsbS1yZXR1cm4gbGlzdDxhcnJheXtyb290OiBhcnJheXtuYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgcmVmZXJlbmNlOiBzdHJpbmcsIHByZXR0eV92ZXJzaW9uOiBzdHJpbmcsIGFsaWFzZXM6IHN0cmluZ1tdfSwgdmVyc2lvbnM6IGFycmF5PHN0cmluZywgYXJyYXl7cHJldHR5X3ZlcnNpb24/OiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcsIGFsaWFzZXM/OiBzdHJpbmdbXSwgcmVmZXJlbmNlPzogc3RyaW5nLCByZXBsYWNlZD86IHN0cmluZ1tdLCBwcm92aWRlZD86IHN0cmluZ1tdfT59PgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRJbnN0YWxsZWQoKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokY2FuR2V0VmVuZG9ycykgewogICAgICAgICAgICBzZWxmOjokY2FuR2V0VmVuZG9ycyA9IG1ldGhvZF9leGlzdHMoJ0NvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyJywgJ2dldFJlZ2lzdGVyZWRMb2FkZXJzJyk7CiAgICAgICAgfQoKICAgICAgICAkaW5zdGFsbGVkID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKHNlbGY6OiRjYW5HZXRWZW5kb3JzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKENsYXNzTG9hZGVyOjpnZXRSZWdpc3RlcmVkTG9hZGVycygpIGFzICR2ZW5kb3JEaXIgPT4gJGxvYWRlcikgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRpbnN0YWxsZWRCeVZlbmRvclskdmVuZG9yRGlyXSkpIHsKICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbGVkW10gPSBzZWxmOjokaW5zdGFsbGVkQnlWZW5kb3JbJHZlbmRvckRpcl07CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfZmlsZSgkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLnBocCcpKSB7CiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxlZFtdID0gc2VsZjo6JGluc3RhbGxlZEJ5VmVuZG9yWyR2ZW5kb3JEaXJdID0gcmVxdWlyZSAkdmVuZG9yRGlyLicvY29tcG9zZXIvaW5zdGFsbGVkLnBocCc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRpbnN0YWxsZWRbXSA9IHNlbGY6OiRpbnN0YWxsZWQ7CgogICAgICAgIHJldHVybiAkaW5zdGFsbGVkOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIENvbXBvc2l0ZSByZXBvc2l0b3J5LgogKgogKiBAYXV0aG9yIEJlYXUgU2ltZW5zZW4gPGJlYXVAZGZseWRldi5jb20+CiAqLwpjbGFzcyBDb21wb3NpdGVSZXBvc2l0b3J5IGltcGxlbWVudHMgUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIExpc3Qgb2YgcmVwb3NpdG9yaWVzCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcmllczsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0gYXJyYXkgJHJlcG9zaXRvcmllcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9zaXRvcmllcykKICAgIHsKICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRSZXBvc2l0b3J5KCRyZXBvKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2NvbXBvc2l0ZSByZXBvICgnLmltcGxvZGUoJywgJywgYXJyYXlfbWFwKGZ1bmN0aW9uICgkcmVwbykgewogICAgICAgICAgICByZXR1cm4gJHJlcG8tPmdldFJlcG9OYW1lKCk7CiAgICAgICAgfSwgJHRoaXMtPnJlcG9zaXRvcmllcykpLicpJzsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIHRoZSB3cmFwcGVkIHJlcG9zaXRvcmllcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcmllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3JpZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgaWYgKCRyZXBvc2l0b3J5LT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcGFja2FnZSA9ICRyZXBvc2l0b3J5LT5maW5kUGFja2FnZSgkbmFtZSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICBpZiAobnVsbCAhPT0gJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgLyogQHZhciAkcmVwb3NpdG9yeSBSZXBvc2l0b3J5SW50ZXJmYWNlICovCiAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlcyA/IGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsICRwYWNrYWdlcykgOiBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRuYW1lc0ZvdW5kID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcmVzdWx0ID0gJHJlcG9zaXRvcnktPmxvYWRQYWNrYWdlcygkcGFja2FnZU1hcCwgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgJHN0YWJpbGl0eUZsYWdzLCAkYWxyZWFkeUxvYWRlZCk7CiAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlc3VsdFsncGFja2FnZXMnXTsKICAgICAgICAgICAgJG5hbWVzRm91bmRbXSA9ICRyZXN1bHRbJ25hbWVzRm91bmQnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3BhY2thZ2VzJyA9PiAkcGFja2FnZXMgPyBjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpIDogYXJyYXkoKSwKICAgICAgICAgICAgJ25hbWVzRm91bmQnID0+ICRuYW1lc0ZvdW5kID8gYXJyYXlfdW5pcXVlKGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsICRuYW1lc0ZvdW5kKSkgOiBhcnJheSgpLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWFyY2goJHF1ZXJ5LCAkbW9kZSA9IDAsICR0eXBlID0gbnVsbCkKICAgIHsKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgJG1hdGNoZXNbXSA9ICRyZXBvc2l0b3J5LT5zZWFyY2goJHF1ZXJ5LCAkbW9kZSwgJHR5cGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYXRjaGVzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJG1hdGNoZXMpIDogYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgLyogQHZhciAkcmVwb3NpdG9yeSBSZXBvc2l0b3J5SW50ZXJmYWNlICovCiAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJHJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2VzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHBhY2thZ2VzKSA6IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICRyZXN1bHRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcmVzdWx0c1tdID0gJHJlcG9zaXRvcnktPmdldFByb3ZpZGVycygkcGFja2FnZU5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRzID8gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJHJlc3VsdHMpIDogYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qIEB2YXIgJHJlcG9zaXRvcnkgUmVwb3NpdG9yeUludGVyZmFjZSAqLwogICAgICAgICAgICAkcmVwb3NpdG9yeS0+cmVtb3ZlUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnQoKQogICAgewogICAgICAgICR0b3RhbCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAvKiBAdmFyICRyZXBvc2l0b3J5IFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgICAgICAgICAgJHRvdGFsICs9ICRyZXBvc2l0b3J5LT5jb3VudCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0b3RhbDsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIHJlcG9zaXRvcnkuCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5KQogICAgewogICAgICAgIGlmICgkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIHNlbGYpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcnktPmdldFJlcG9zaXRvcmllcygpIGFzICRyZXBvKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUmVwb3NpdG9yeSgkcmVwbyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yaWVzW10gPSAkcmVwb3NpdG9yeTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXFZjc0RyaXZlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxWYWxpZGF0aW5nQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxJbnZhbGlkUGFja2FnZUV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXExvYWRlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBDb21wb3NlclxVdGlsXFVybDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBWY3NSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgQ29uZmlndXJhYmxlUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJHVybDsKICAgIHByb3RlY3RlZCAkcGFja2FnZU5hbWU7CiAgICBwcm90ZWN0ZWQgJGlzVmVyYm9zZTsKICAgIHByb3RlY3RlZCAkaXNWZXJ5VmVyYm9zZTsKICAgIHByb3RlY3RlZCAkaW87CiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIHByb3RlY3RlZCAkdmVyc2lvblBhcnNlcjsKICAgIHByb3RlY3RlZCAkdHlwZTsKICAgIHByb3RlY3RlZCAkbG9hZGVyOwogICAgcHJvdGVjdGVkICRyZXBvQ29uZmlnOwogICAgcHJvdGVjdGVkICRodHRwRG93bmxvYWRlcjsKICAgIHByb3RlY3RlZCAkcHJvY2Vzc0V4ZWN1dG9yOwogICAgcHJvdGVjdGVkICRicmFuY2hFcnJvck9jY3VycmVkID0gZmFsc2U7CiAgICBwcml2YXRlICRkcml2ZXJzOwogICAgLyoqIEB2YXIgVmNzRHJpdmVySW50ZXJmYWNlICovCiAgICBwcml2YXRlICRkcml2ZXI7CiAgICAvKiogQHZhciBWZXJzaW9uQ2FjaGVJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJHZlcnNpb25DYWNoZTsKICAgIHByaXZhdGUgJGVtcHR5UmVmZXJlbmNlcyA9IGFycmF5KCk7CiAgICBwcml2YXRlICR2ZXJzaW9uVHJhbnNwb3J0RXhjZXB0aW9ucyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXBvQ29uZmlnLCBJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIEV2ZW50RGlzcGF0Y2hlciAkZGlzcGF0Y2hlciA9IG51bGwsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwsIGFycmF5ICRkcml2ZXJzID0gbnVsbCwgVmVyc2lvbkNhY2hlSW50ZXJmYWNlICR2ZXJzaW9uQ2FjaGUgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgICAgICAkdGhpcy0+ZHJpdmVycyA9ICRkcml2ZXJzID86IGFycmF5KAogICAgICAgICAgICAnZ2l0aHViJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcR2l0SHViRHJpdmVyJywKICAgICAgICAgICAgJ2dpdGxhYicgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEdpdExhYkRyaXZlcicsCiAgICAgICAgICAgICdnaXQtYml0YnVja2V0JyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcR2l0Qml0YnVja2V0RHJpdmVyJywKICAgICAgICAgICAgJ2dpdCcgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEdpdERyaXZlcicsCiAgICAgICAgICAgICdoZy1iaXRidWNrZXQnID0+ICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1xIZ0JpdGJ1Y2tldERyaXZlcicsCiAgICAgICAgICAgICdoZycgPT4gJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzXEhnRHJpdmVyJywKICAgICAgICAgICAgJ3BlcmZvcmNlJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcUGVyZm9yY2VEcml2ZXInLAogICAgICAgICAgICAnZm9zc2lsJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcRm9zc2lsRHJpdmVyJywKICAgICAgICAgICAgLy8gc3ZuIG11c3QgYmUgbGFzdCBiZWNhdXNlIGlkZW50aWZ5aW5nIGEgc3VidmVyc2lvbiBzZXJ2ZXIgZm9yIHN1cmUgaXMgcHJhY3RpY2FsbHkgaW1wb3NzaWJsZQogICAgICAgICAgICAnc3ZuJyA9PiAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NcU3ZuRHJpdmVyJywKICAgICAgICApOwoKICAgICAgICAkdGhpcy0+dXJsID0gJHJlcG9Db25maWdbJ3VybCddOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+dHlwZSA9IGlzc2V0KCRyZXBvQ29uZmlnWyd0eXBlJ10pID8gJHJlcG9Db25maWdbJ3R5cGUnXSA6ICd2Y3MnOwogICAgICAgICR0aGlzLT5pc1ZlcmJvc2UgPSAkaW8tPmlzVmVyYm9zZSgpOwogICAgICAgICR0aGlzLT5pc1ZlcnlWZXJib3NlID0gJGlvLT5pc1ZlcnlWZXJib3NlKCk7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnJlcG9Db25maWcgPSAkcmVwb0NvbmZpZzsKICAgICAgICAkdGhpcy0+dmVyc2lvbkNhY2hlID0gJHZlcnNpb25DYWNoZTsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvciA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgICRkcml2ZXJDbGFzcyA9IGdldF9jbGFzcygkdGhpcy0+Z2V0RHJpdmVyKCkpOwogICAgICAgICRkcml2ZXJUeXBlID0gYXJyYXlfc2VhcmNoKCRkcml2ZXJDbGFzcywgJHRoaXMtPmRyaXZlcnMpOwogICAgICAgIGlmICghJGRyaXZlclR5cGUpIHsKICAgICAgICAgICAgJGRyaXZlclR5cGUgPSAkZHJpdmVyQ2xhc3M7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3ZjcyByZXBvICgnLiRkcml2ZXJUeXBlLicgJy5Vcmw6OnNhbml0aXplKCR0aGlzLT51cmwpLicpJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0NvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvQ29uZmlnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2FkZXIoTG9hZGVySW50ZXJmYWNlICRsb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRlciA9ICRsb2FkZXI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERyaXZlcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5kcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5kcml2ZXI7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmRyaXZlcnNbJHRoaXMtPnR5cGVdKSkgewogICAgICAgICAgICAkY2xhc3MgPSAkdGhpcy0+ZHJpdmVyc1skdGhpcy0+dHlwZV07CiAgICAgICAgICAgICR0aGlzLT5kcml2ZXIgPSBuZXcgJGNsYXNzKCR0aGlzLT5yZXBvQ29uZmlnLCAkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5odHRwRG93bmxvYWRlciwgJHRoaXMtPnByb2Nlc3NFeGVjdXRvcik7CiAgICAgICAgICAgICR0aGlzLT5kcml2ZXItPmluaXRpYWxpemUoKTsKCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZHJpdmVyOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmRyaXZlcnMgYXMgJGRyaXZlcikgewogICAgICAgICAgICBpZiAoJGRyaXZlcjo6c3VwcG9ydHMoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRyaXZlciA9IG5ldyAkZHJpdmVyKCR0aGlzLT5yZXBvQ29uZmlnLCAkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5odHRwRG93bmxvYWRlciwgJHRoaXMtPnByb2Nlc3NFeGVjdXRvcik7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZHJpdmVyLT5pbml0aWFsaXplKCk7CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5kcml2ZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5kcml2ZXJzIGFzICRkcml2ZXIpIHsKICAgICAgICAgICAgaWYgKCRkcml2ZXI6OnN1cHBvcnRzKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnVybCwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5kcml2ZXIgPSBuZXcgJGRyaXZlcigkdGhpcy0+cmVwb0NvbmZpZywgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+aHR0cERvd25sb2FkZXIsICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpOwogICAgICAgICAgICAgICAgJHRoaXMtPmRyaXZlci0+aW5pdGlhbGl6ZSgpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZHJpdmVyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYWRJbnZhbGlkQnJhbmNoZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoRXJyb3JPY2N1cnJlZDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW1wdHlSZWZlcmVuY2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVtcHR5UmVmZXJlbmNlczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyc2lvblRyYW5zcG9ydEV4Y2VwdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvblRyYW5zcG9ydEV4Y2VwdGlvbnM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIHBhcmVudDo6aW5pdGlhbGl6ZSgpOwoKICAgICAgICAkaXNWZXJib3NlID0gJHRoaXMtPmlzVmVyYm9zZTsKICAgICAgICAkaXNWZXJ5VmVyYm9zZSA9ICR0aGlzLT5pc1ZlcnlWZXJib3NlOwoKICAgICAgICAkZHJpdmVyID0gJHRoaXMtPmdldERyaXZlcigpOwogICAgICAgIGlmICghJGRyaXZlcikgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignTm8gZHJpdmVyIGZvdW5kIHRvIGhhbmRsZSBWQ1MgcmVwb3NpdG9yeSAnLiR0aGlzLT51cmwpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICBpZiAoISR0aGlzLT5sb2FkZXIpIHsKICAgICAgICAgICAgJHRoaXMtPmxvYWRlciA9IG5ldyBBcnJheUxvYWRlcigkdGhpcy0+dmVyc2lvblBhcnNlcik7CiAgICAgICAgfQoKICAgICAgICAkaGFzUm9vdElkZW50aWZpZXJDb21wb3Nlckpzb24gPSBmYWxzZTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkaGFzUm9vdElkZW50aWZpZXJDb21wb3Nlckpzb24gPSAkZHJpdmVyLT5oYXNDb21wb3NlckZpbGUoJGRyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKSk7CiAgICAgICAgICAgIGlmICgkaGFzUm9vdElkZW50aWZpZXJDb21wb3Nlckpzb24pIHsKICAgICAgICAgICAgICAgICRkYXRhID0gJGRyaXZlci0+Z2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkZHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlTmFtZSA9ICFlbXB0eSgkZGF0YVsnbmFtZSddKSA/ICRkYXRhWyduYW1lJ10gOiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPlNraXBwZWQgcGFyc2luZyAnLiRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkuJywgJy4kZS0+Z2V0TWVzc2FnZSgpLic8L2Vycm9yPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkZHJpdmVyLT5nZXRUYWdzKCkgYXMgJHRhZyA9PiAkaWRlbnRpZmllcikgewogICAgICAgICAgICAkbXNnID0gJ1JlYWRpbmcgY29tcG9zZXIuanNvbiBvZiA8aW5mbz4nIC4gKCR0aGlzLT5wYWNrYWdlTmFtZSA/OiAkdGhpcy0+dXJsKSAuICc8L2luZm8+ICg8Y29tbWVudD4nIC4gJHRhZyAuICc8L2NvbW1lbnQ+KSc7CiAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGlzVmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcigkbXNnLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHN0cmlwIHRoZSByZWxlYXNlLSBwcmVmaXggZnJvbSB0YWdzIGlmIHByZXNlbnQKICAgICAgICAgICAgJHRhZyA9IHN0cl9yZXBsYWNlKCdyZWxlYXNlLScsICcnLCAkdGFnKTsKCiAgICAgICAgICAgICRjYWNoZWRQYWNrYWdlID0gJHRoaXMtPmdldENhY2hlZFBhY2thZ2VWZXJzaW9uKCR0YWcsICRpZGVudGlmaWVyLCAkaXNWZXJib3NlLCAkaXNWZXJ5VmVyYm9zZSk7CiAgICAgICAgICAgIGlmICgkY2FjaGVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGNhY2hlZFBhY2thZ2UpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkY2FjaGVkUGFja2FnZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lbXB0eVJlZmVyZW5jZXNbXSA9ICRpZGVudGlmaWVyOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRwYXJzZWRUYWcgPSAkdGhpcy0+dmFsaWRhdGVUYWcoJHRhZykpIHsKICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCB0YWcgJy4kdGFnLicsIGludmFsaWQgdGFnIG5hbWU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICghJGRhdGEgPSAkZHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgdGFnICcuJHRhZy4nLCBubyBjb21wb3NlciBmaWxlPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBtYW51YWxseSB2ZXJzaW9uZWQgcGFja2FnZQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRkYXRhWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkZGF0YVsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYXV0by12ZXJzaW9uZWQgcGFja2FnZSwgcmVhZCB2YWx1ZSBmcm9tIHRhZwogICAgICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uJ10gPSAkdGFnOwogICAgICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRwYXJzZWRUYWc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRhZyBwYWNrYWdlcyBoYXZlIG5vIC1kZXYgZmxhZwogICAgICAgICAgICAgICAgJGRhdGFbJ3ZlcnNpb24nXSA9IHByZWdfcmVwbGFjZSgne1suLV0/ZGV2JH1pJywgJycsICRkYXRhWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddID0gcHJlZ19yZXBsYWNlKCd7KF5kZXYtfFsuLV0/ZGV2JCl9aScsICcnLCAkZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10pOwoKICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0YWcgZG8gbm90IGNvbnRhaW4gdGhlIGRlZmF1bHQtYnJhbmNoIG1hcmtlcgogICAgICAgICAgICAgICAgdW5zZXQoJGRhdGFbJ2RlZmF1bHQtYnJhbmNoJ10pOwoKICAgICAgICAgICAgICAgIC8vIGJyb2tlbiBwYWNrYWdlLCB2ZXJzaW9uIGRvZXNuJ3QgbWF0Y2ggdGFnCiAgICAgICAgICAgICAgICBpZiAoJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddICE9PSAkcGFyc2VkVGFnKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7KF5kZXYtfFsuLV0/ZGV2JCl9aScsICRwYXJzZWRUYWcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgdGFnICcuJHRhZy4nLCBpbnZhbGlkIHRhZyBuYW1lLCB0YWdzIGNhbiBub3QgdXNlIGRldiBwcmVmaXhlcyBvciBzdWZmaXhlczwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCB0YWcgJy4kdGFnLicsIHRhZyAoJy4kcGFyc2VkVGFnLicpIGRvZXMgbm90IG1hdGNoIHZlcnNpb24gKCcuJGRhdGFbJ3ZlcnNpb25fbm9ybWFsaXplZCddLicpIGluIGNvbXBvc2VyLmpzb248L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRhZ1BhY2thZ2VOYW1lID0gJHRoaXMtPnBhY2thZ2VOYW1lID86IChpc3NldCgkZGF0YVsnbmFtZSddKSA/ICRkYXRhWyduYW1lJ10gOiAnJyk7CiAgICAgICAgICAgICAgICBpZiAoJGV4aXN0aW5nUGFja2FnZSA9ICR0aGlzLT5maW5kUGFja2FnZSgkdGFnUGFja2FnZU5hbWUsICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGVkIHRhZyAnLiR0YWcuJywgaXQgY29uZmxpY3RzIHdpdGggYW4gYW5vdGhlciB0YWcgKCcuJGV4aXN0aW5nUGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLicpIGFzIGJvdGggcmVzb2x2ZSB0byAnLiRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXS4nIGludGVybmFsbHk8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignSW1wb3J0aW5nIHRhZyAnLiR0YWcuJyAoJy4kZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10uJyknKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkdGhpcy0+bG9hZGVyLT5sb2FkKCR0aGlzLT5wcmVQcm9jZXNzKCRkcml2ZXIsICRkYXRhLCAkaWRlbnRpZmllcikpKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25UcmFuc3BvcnRFeGNlcHRpb25zWyd0YWdzJ11bJHRhZ10gPSAkZTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lbXB0eVJlZmVyZW5jZXNbXSA9ICRpZGVudGlmaWVyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gNDAxIHx8ICRlLT5nZXRDb2RlKCkgPT09IDQwMykgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgdGFnICcuJHRhZy4nLCAnLigkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiA/ICdubyBjb21wb3NlciBmaWxlIHdhcyBmb3VuZCAoJyAuICRlLT5nZXRDb2RlKCkgLiAnIEhUVFAgc3RhdHVzIGNvZGUpJyA6ICRlLT5nZXRNZXNzYWdlKCkpLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPm92ZXJ3cml0ZUVycm9yKCcnLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICAkYnJhbmNoZXMgPSAkZHJpdmVyLT5nZXRCcmFuY2hlcygpOwogICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgcm9vdCBpZGVudGlmaWVyIGJyYW5jaCBnZXRzIGxvYWRlZCBmaXJzdAogICAgICAgIGlmICgkaGFzUm9vdElkZW50aWZpZXJDb21wb3Nlckpzb24gJiYgaXNzZXQoJGJyYW5jaGVzWyRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCldKSkgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgkZHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpID0+ICRicmFuY2hlc1skZHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpXSkgKyAkYnJhbmNoZXM7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkYnJhbmNoZXMgYXMgJGJyYW5jaCA9PiAkaWRlbnRpZmllcikgewogICAgICAgICAgICAkbXNnID0gJ1JlYWRpbmcgY29tcG9zZXIuanNvbiBvZiA8aW5mbz4nIC4gKCR0aGlzLT5wYWNrYWdlTmFtZSA/OiAkdGhpcy0+dXJsKSAuICc8L2luZm8+ICg8Y29tbWVudD4nIC4gJGJyYW5jaCAuICc8L2NvbW1lbnQ+KSc7CiAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGlzVmVyYm9zZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcigkbXNnLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJHBhcnNlZEJyYW5jaCA9ICR0aGlzLT52YWxpZGF0ZUJyYW5jaCgkYnJhbmNoKSkgewogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGVkIGJyYW5jaCAnLiRicmFuY2guJywgaW52YWxpZCBuYW1lPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBicmFuY2ggcGFja2FnZXMgaGF2ZSBhIGRldiBmbGFnCiAgICAgICAgICAgIGlmIChzdHJwb3MoJHBhcnNlZEJyYW5jaCwgJ2Rldi0nKSA9PT0gMCB8fCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUyA9PT0gJHBhcnNlZEJyYW5jaCkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAnZGV2LScgLiAkYnJhbmNoOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHByZWZpeCA9IHN0cnBvcygkYnJhbmNoLCAndicpID09PSAwID8gJ3YnIDogJyc7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICRwcmVmaXggLiBwcmVnX3JlcGxhY2UoJ3soXC45ezd9KSt9JywgJy54JywgJHBhcnNlZEJyYW5jaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjYWNoZWRQYWNrYWdlID0gJHRoaXMtPmdldENhY2hlZFBhY2thZ2VWZXJzaW9uKCR2ZXJzaW9uLCAkaWRlbnRpZmllciwgJGlzVmVyYm9zZSwgJGlzVmVyeVZlcmJvc2UsICRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkgPT09ICRicmFuY2gpOwogICAgICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRjYWNoZWRQYWNrYWdlKTsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICghJGRhdGEgPSAkZHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlNraXBwZWQgYnJhbmNoICcuJGJyYW5jaC4nLCBubyBjb21wb3NlciBmaWxlPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW1wdHlSZWZlcmVuY2VzW10gPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBicmFuY2hlcyBhcmUgYWx3YXlzIGF1dG8tdmVyc2lvbmVkLCByZWFkIHZhbHVlIGZyb20gYnJhbmNoIG5hbWUKICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uJ10gPSAkdmVyc2lvbjsKICAgICAgICAgICAgICAgICRkYXRhWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRwYXJzZWRCcmFuY2g7CgogICAgICAgICAgICAgICAgdW5zZXQoJGRhdGFbJ2RlZmF1bHQtYnJhbmNoJ10pOwogICAgICAgICAgICAgICAgaWYgKCRkcml2ZXItPmdldFJvb3RJZGVudGlmaWVyKCkgPT09ICRicmFuY2gpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YVsnZGVmYXVsdC1icmFuY2gnXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRpc1ZlcnlWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdJbXBvcnRpbmcgYnJhbmNoICcuJGJyYW5jaC4nICgnLiRkYXRhWyd2ZXJzaW9uJ10uJyknKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFja2FnZURhdGEgPSAkdGhpcy0+cHJlUHJvY2VzcygkZHJpdmVyLCAkZGF0YSwgJGlkZW50aWZpZXIpOwogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bG9hZGVyLT5sb2FkKCRwYWNrYWdlRGF0YSk7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmxvYWRlciBpbnN0YW5jZW9mIFZhbGlkYXRpbmdBcnJheUxvYWRlciAmJiAkdGhpcy0+bG9hZGVyLT5nZXRXYXJuaW5ncygpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYWNrYWdlRXhjZXB0aW9uKCR0aGlzLT5sb2FkZXItPmdldEVycm9ycygpLCAkdGhpcy0+bG9hZGVyLT5nZXRXYXJuaW5ncygpLCAkcGFja2FnZURhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT52ZXJzaW9uVHJhbnNwb3J0RXhjZXB0aW9uc1snYnJhbmNoZXMnXVskYnJhbmNoXSA9ICRlOwogICAgICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lbXB0eVJlZmVyZW5jZXNbXSA9ICRpZGVudGlmaWVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IDQwMSB8fCAkZS0+Z2V0Q29kZSgpID09PSA0MDMpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCBicmFuY2ggJy4kYnJhbmNoLicsIG5vIGNvbXBvc2VyIGZpbGUgd2FzIGZvdW5kICgnIC4gJGUtPmdldENvZGUoKSAuICcgSFRUUCBzdGF0dXMgY29kZSk8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCEkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+YnJhbmNoRXJyb3JPY2N1cnJlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5Ta2lwcGVkIGJyYW5jaCAnLiRicmFuY2guJywgJy4kZS0+Z2V0TWVzc2FnZSgpLic8L2Vycm9yPicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRkcml2ZXItPmNsZWFudXAoKTsKCiAgICAgICAgaWYgKCEkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPm92ZXJ3cml0ZUVycm9yKCcnLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5nZXRQYWNrYWdlcygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUmVwb3NpdG9yeUV4Y2VwdGlvbignTm8gdmFsaWQgY29tcG9zZXIuanNvbiB3YXMgZm91bmQgaW4gYW55IGJyYW5jaCBvciB0YWcgb2YgJy4kdGhpcy0+dXJsLicsIGNvdWxkIG5vdCBsb2FkIGEgcGFja2FnZSBmcm9tIGl0LicpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJlUHJvY2VzcyhWY3NEcml2ZXJJbnRlcmZhY2UgJGRyaXZlciwgYXJyYXkgJGRhdGEsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIC8vIGtlZXAgdGhlIG5hbWUgb2YgdGhlIG1haW4gaWRlbnRpZmllciBmb3IgYWxsIHBhY2thZ2VzCiAgICAgICAgLy8gdGhpcyBlbnN1cmVzIHRoYXQgYSBwYWNrYWdlIGNhbiBiZSByZW5hbWVkIGluIG9uZSBwbGFjZSBhbmQgdGhhdCBhbGwgb2xkIHRhZ3MKICAgICAgICAvLyB3aWxsIHN0aWxsIGJlIGluc3RhbGxhYmxlIHVzaW5nIHRoYXQgbmV3IG5hbWUgd2l0aG91dCByZXF1aXJpbmcgcmUtdGFnZ2luZwogICAgICAgICRkYXRhUGFja2FnZU5hbWUgPSBpc3NldCgkZGF0YVsnbmFtZSddKSA/ICRkYXRhWyduYW1lJ10gOiBudWxsOwogICAgICAgICRkYXRhWyduYW1lJ10gPSAkdGhpcy0+cGFja2FnZU5hbWUgPzogJGRhdGFQYWNrYWdlTmFtZTsKCiAgICAgICAgaWYgKCFpc3NldCgkZGF0YVsnZGlzdCddKSkgewogICAgICAgICAgICAkZGF0YVsnZGlzdCddID0gJGRyaXZlci0+Z2V0RGlzdCgkaWRlbnRpZmllcik7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoJGRhdGFbJ3NvdXJjZSddKSkgewogICAgICAgICAgICAkZGF0YVsnc291cmNlJ10gPSAkZHJpdmVyLT5nZXRTb3VyY2UoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkYXRhOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVCcmFuY2goJGJyYW5jaCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkbm9ybWFsaXplZEJyYW5jaCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemVCcmFuY2goJGJyYW5jaCk7CgogICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHRoZSBicmFuY2ggbmFtZSBoYXMgbm8gd2VpcmQgY2hhcmFjdGVycyBjb25mbGljdGluZyB3aXRoIGNvbnN0cmFpbnRzCiAgICAgICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRub3JtYWxpemVkQnJhbmNoKTsKCiAgICAgICAgICAgIHJldHVybiAkbm9ybWFsaXplZEJyYW5jaDsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZVRhZygkdmVyc2lvbikKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkdmVyc2lvbik7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q2FjaGVkUGFja2FnZVZlcnNpb24oJHZlcnNpb24sICRpZGVudGlmaWVyLCAkaXNWZXJib3NlLCAkaXNWZXJ5VmVyYm9zZSwgJGlzRGVmYXVsdEJyYW5jaCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnZlcnNpb25DYWNoZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkY2FjaGVkUGFja2FnZSA9ICR0aGlzLT52ZXJzaW9uQ2FjaGUtPmdldFZlcnNpb25QYWNrYWdlKCR2ZXJzaW9uLCAkaWRlbnRpZmllcik7CiAgICAgICAgaWYgKCRjYWNoZWRQYWNrYWdlID09PSBmYWxzZSkgewogICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCAnLiR2ZXJzaW9uLicsIG5vIGNvbXBvc2VyIGZpbGUgKGNhY2hlZCBmcm9tIHJlZiAnLiRpZGVudGlmaWVyLicpPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgJG1zZyA9ICdGb3VuZCBjYWNoZWQgY29tcG9zZXIuanNvbiBvZiA8aW5mbz4nIC4gKCR0aGlzLT5wYWNrYWdlTmFtZSA/OiAkdGhpcy0+dXJsKSAuICc8L2luZm8+ICg8Y29tbWVudD4nIC4gJHZlcnNpb24gLiAnPC9jb21tZW50PiknOwogICAgICAgICAgICBpZiAoJGlzVmVyeVZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbXNnKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRpc1ZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoJG1zZywgZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB1bnNldCgkY2FjaGVkUGFja2FnZVsnZGVmYXVsdC1icmFuY2gnXSk7CiAgICAgICAgICAgIGlmICgkaXNEZWZhdWx0QnJhbmNoKSB7CiAgICAgICAgICAgICAgICAkY2FjaGVkUGFja2FnZVsnZGVmYXVsdC1icmFuY2gnXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZXhpc3RpbmdQYWNrYWdlID0gJHRoaXMtPmZpbmRQYWNrYWdlKCRjYWNoZWRQYWNrYWdlWyduYW1lJ10sIG5ldyBDb25zdHJhaW50KCc9JywgJGNhY2hlZFBhY2thZ2VbJ3ZlcnNpb25fbm9ybWFsaXplZCddKSkpIHsKICAgICAgICAgICAgICAgIGlmICgkaXNWZXJ5VmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+U2tpcHBlZCBjYWNoZWQgdmVyc2lvbiAnLiR2ZXJzaW9uLicsIGl0IGNvbmZsaWN0cyB3aXRoIGFuIGFub3RoZXIgdGFnICgnLiRleGlzdGluZ1BhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKS4nKSBhcyBib3RoIHJlc29sdmUgdG8gJy4kY2FjaGVkUGFja2FnZVsndmVyc2lvbl9ub3JtYWxpemVkJ10uJyBpbnRlcm5hbGx5PC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNhY2hlZFBhY2thZ2UgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhY2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkZXItPmxvYWQoJGNhY2hlZFBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCi8qKgogKiBJbnN0YWxsZWQgYXJyYXkgcmVwb3NpdG9yeS4KICoKICogVGhpcyBpcyB1c2VkIGFzIGFuIGluLW1lbW9yeSBJbnN0YWxsZWRSZXBvc2l0b3J5IG1vc3RseSBmb3IgdGVzdGluZyBwdXJwb3NlcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBJbnN0YWxsZWRBcnJheVJlcG9zaXRvcnkgZXh0ZW5kcyBXcml0YWJsZUFycmF5UmVwb3NpdG9yeSBpbXBsZW1lbnRzIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UKewogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2luc3RhbGxlZCAnLnBhcmVudDo6Z2V0UmVwb05hbWUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRnJlc2goKQogICAgewogICAgICAgIC8vIHRoaXMgaXMgbm90IGEgY29tcGxldGVseSBjb3JyZWN0IGltcGxlbWVudGF0aW9uIGJ1dCB0aGVyZSBpcyBubyB3YXkgdG8KICAgICAgICAvLyBkaXN0aW5ndWlzaCBhbiBlbXB0eSByZXBvIGFuZCBhIG5ld2x5IGNyZWF0ZWQgb25lIGdpdmVuIHRoaXMgaXMgYWxsIGluLW1lbW9yeQogICAgICAgIHJldHVybiAkdGhpcy0+Y291bnQoKSA9PT0gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxQb29sOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFBvb2xCdWlsZGVyOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFJlcXVlc3Q7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnREaXNwYXRjaGVyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xOdWxsSU87CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFN0YWJpbGl0eUZpbHRlcjsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUmVwb3NpdG9yeVNldAp7CiAgICAvKioKICAgICAqIFBhY2thZ2VzIGFyZSByZXR1cm5lZCBldmVuIHRob3VnaCB0aGVpciBzdGFiaWxpdHkgZG9lcyBub3QgbWF0Y2ggdGhlIHJlcXVpcmVkIHN0YWJpbGl0eQogICAgICovCiAgICBjb25zdCBBTExPV19VTkFDQ0VQVEFCTEVfU1RBQklMSVRJRVMgPSAxOwogICAgLyoqCiAgICAgKiBQYWNrYWdlcyB3aWxsIGJlIGxvb2tlZCB1cCBpbiBhbGwgcmVwb3NpdG9yaWVzLCBldmVuIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGZvdW5kIGluIGEgaGlnaGVyIHByaW8gb25lCiAgICAgKi8KICAgIGNvbnN0IEFMTE9XX1NIQURPV0VEX1JFUE9TSVRPUklFUyA9IDI7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5W10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxzdHJpbmcsIGFycmF5e2FsaWFzOiBzdHJpbmcsIGFsaWFzX25vcm1hbGl6ZWQ6IHN0cmluZ30+PgogICAgICovCiAgICBwcml2YXRlICRyb290QWxpYXNlczsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RSZWZlcmVuY2VzOwoKICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2VbXSAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yaWVzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgaW50W10gYXJyYXkgb2Ygc3RhYmlsaXR5ID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIGludD4KICAgICAqLwogICAgcHJpdmF0ZSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzOwoKICAgIC8qKgogICAgICogQHZhciBpbnRbXSBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgaW50PgogICAgICovCiAgICBwcml2YXRlICRzdGFiaWxpdHlGbGFnczsKCiAgICBwcml2YXRlICRyb290UmVxdWlyZXM7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkbG9ja2VkID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRhbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogSW4gbW9zdCBjYXNlcyBpZiB5b3UgYXJlIGxvb2tpbmcgdG8gdXNlIHRoaXMgY2xhc3MgYXMgYSB3YXkgdG8gZmluZCBwYWNrYWdlcyBmcm9tIHJlcG9zaXRvcmllcwogICAgICogcGFzc2luZyBtaW5pbXVtU3RhYmlsaXR5IGlzIGFsbCB5b3UgbmVlZCB0byB3b3JyeSBhYm91dC4gVGhlIHJlc3QgaXMgZm9yIGFkdmFuY2VkIHBvb2wgY3JlYXRpb24gaW5jbHVkaW5nCiAgICAgKiBhbGlhc2VzLCBwaW5uZWQgcmVmZXJlbmNlcyBhbmQgb3RoZXIgc3BlY2lhbCBjYXNlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtaW5pbXVtU3RhYmlsaXR5CiAgICAgKiBAcGFyYW0gaW50W10gICRzdGFiaWxpdHlGbGFncyAgIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwc2FsbS1wYXJhbSBhcnJheTxzdHJpbmcsIGludD4gJHN0YWJpbGl0eUZsYWdzCiAgICAgKiBAcGFyYW0gYXJyYXlbXSAkcm9vdEFsaWFzZXMKICAgICAqIEBwc2FsbS1wYXJhbSBsaXN0PGFycmF5e3BhY2thZ2U6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9PiAkcm9vdEFsaWFzZXMKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkcm9vdFJlZmVyZW5jZXMgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IHNvdXJjZSByZWZlcmVuY2UKICAgICAqIEBwc2FsbS1wYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJvb3RSZWZlcmVuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWluaW11bVN0YWJpbGl0eSA9ICdzdGFibGUnLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MgPSBhcnJheSgpLCBhcnJheSAkcm9vdEFsaWFzZXMgPSBhcnJheSgpLCBhcnJheSAkcm9vdFJlZmVyZW5jZXMgPSBhcnJheSgpLCBhcnJheSAkcm9vdFJlcXVpcmVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+cm9vdEFsaWFzZXMgPSBzZWxmOjpnZXRSb290QWxpYXNlc1BlclBhY2thZ2UoJHJvb3RBbGlhc2VzKTsKICAgICAgICAkdGhpcy0+cm9vdFJlZmVyZW5jZXMgPSAkcm9vdFJlZmVyZW5jZXM7CgogICAgICAgICR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMgYXMgJHN0YWJpbGl0eSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCR2YWx1ZSA8PSBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyRtaW5pbXVtU3RhYmlsaXR5XSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllc1skc3RhYmlsaXR5XSA9ICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MgPSAkc3RhYmlsaXR5RmxhZ3M7CiAgICAgICAgJHRoaXMtPnJvb3RSZXF1aXJlcyA9ICRyb290UmVxdWlyZXM7CiAgICAgICAgZm9yZWFjaCAoJHJvb3RSZXF1aXJlcyBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yb290UmVxdWlyZXNbJG5hbWVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWxsb3dJbnN0YWxsZWRSZXBvc2l0b3JpZXMoJGFsbG93ID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWxsb3dJbnN0YWxsZWRSZXBvc2l0b3JpZXMgPSAkYWxsb3c7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RSZXF1aXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UmVxdWlyZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgcmVwb3NpdG9yeSB0byB0aGlzIHJlcG9zaXRvcnkgc2V0CiAgICAgKgogICAgICogVGhlIGZpcnN0IHJlcG9zIGFkZGVkIGhhdmUgYSBoaWdoZXIgcHJpb3JpdHkuIEFzIHNvb24gYXMgYSBwYWNrYWdlIGlzIGZvdW5kIGluIGFueQogICAgICogcmVwb3NpdG9yeSB0aGUgc2VhcmNoIGZvciB0aGF0IHBhY2thZ2UgZW5kcywgYW5kIGZvbGxvd2luZyByZXBvcyB3aWxsIG5vdCBiZSBjb25zdWx0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gQSBwYWNrYWdlIHJlcG9zaXRvcnkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbykKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmxvY2tlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIlBvb2wgaGFzIGFscmVhZHkgYmVlbiBjcmVhdGVkIGZyb20gdGhpcyByZXBvc2l0b3J5IHNldCwgaXQgY2Fubm90IGJlIG1vZGlmaWVkIGFueW1vcmUuIik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlcG8gaW5zdGFuY2VvZiBDb21wb3NpdGVSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICRyZXBvcyA9ICRyZXBvLT5nZXRSZXBvc2l0b3JpZXMoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmVwb3MgPSBhcnJheSgkcmVwbyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcmVwb3MgYXMgJHJlcG8pIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllc1tdID0gJHJlcG87CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRmluZCBwYWNrYWdlcyBwcm92aWRpbmcgb3IgbWF0Y2hpbmcgYSBuYW1lIGFuZCBvcHRpb25hbGx5IG1lZXRpbmcgYSBjb25zdHJhaW50IGluIGFsbCByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBSZXR1cm5lZCBpbiB0aGUgb3JkZXIgb2YgcmVwb3NpdG9yaWVzLCBtYXRjaGluZyBwcmlvcml0eQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgKiBAcGFyYW0gIENvbnN0cmFpbnRJbnRlcmZhY2V8bnVsbCAkY29uc3RyYWludAogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAgICAgICAgJGZsYWdzICAgICAgYW55IG9mIHRoZSBBTExPV18qIGNvbnN0YW50cyBmcm9tIHRoaXMgY2xhc3MgdG8gdHdlYWsgd2hhdCBpcyByZXR1cm5lZAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2VzKCRuYW1lLCBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50ID0gbnVsbCwgJGZsYWdzID0gMCkKICAgIHsKICAgICAgICAkaWdub3JlU3RhYmlsaXR5ID0gKCRmbGFncyAmIHNlbGY6OkFMTE9XX1VOQUNDRVBUQUJMRV9TVEFCSUxJVElFUykgIT09IDA7CiAgICAgICAgJGxvYWRGcm9tQWxsUmVwb3MgPSAoJGZsYWdzICYgc2VsZjo6QUxMT1dfU0hBRE9XRURfUkVQT1NJVE9SSUVTKSAhPT0gMDsKCiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGxvYWRGcm9tQWxsUmVwb3MpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlcG9zaXRvcmllcyBhcyAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcmVwb3NpdG9yeS0+ZmluZFBhY2thZ2VzKCRuYW1lLCAkY29uc3RyYWludCkgPzogYXJyYXkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkcmVwb3NpdG9yeS0+bG9hZFBhY2thZ2VzKGFycmF5KCRuYW1lID0+ICRjb25zdHJhaW50KSwgJGlnbm9yZVN0YWJpbGl0eSA/IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMgOiAkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkaWdub3JlU3RhYmlsaXR5ID8gYXJyYXkoKSA6ICR0aGlzLT5zdGFiaWxpdHlGbGFncyk7CgogICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcmVzdWx0WydwYWNrYWdlcyddOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdFsnbmFtZXNGb3VuZCddIGFzICRuYW1lRm91bmQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBsb2FkaW5nIHRoZSBzYW1lIHBhY2thZ2UgYWdhaW4gZnJvbSBvdGhlciByZXBvc2l0b3JpZXMgb25jZSBpdCBoYXMgYmVlbiBmb3VuZAogICAgICAgICAgICAgICAgICAgIGlmICgkbmFtZSA9PT0gJG5hbWVGb3VuZCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGNhbmRpZGF0ZXMgPSAkcGFja2FnZXMgPyBjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCAkcGFja2FnZXMpIDogYXJyYXkoKTsKCiAgICAgICAgLy8gd2hlbiB1c2luZyBsb2FkUGFja2FnZXMgYWJvdmUgKCEkbG9hZEZyb21BbGxSZXBvcykgdGhlIHJlcG9zIGFscmVhZHkgZmlsdGVyIGZvciBzdGFiaWxpdHkgc28gbm8gbmVlZCB0byBkbyBpdCBhZ2FpbgogICAgICAgIGlmICgkaWdub3JlU3RhYmlsaXR5IHx8ICEkbG9hZEZyb21BbGxSZXBvcykgewogICAgICAgICAgICByZXR1cm4gJGNhbmRpZGF0ZXM7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkY2FuZGlkYXRlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNQYWNrYWdlQWNjZXB0YWJsZSgkY2FuZGlkYXRlLT5nZXROYW1lcygpLCAkY2FuZGlkYXRlLT5nZXRTdGFiaWxpdHkoKSkpIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9ICRjYW5kaWRhdGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICRwcm92aWRlcnMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgaWYgKCRyZXBvUHJvdmlkZXJzID0gJHJlcG9zaXRvcnktPmdldFByb3ZpZGVycygkcGFja2FnZU5hbWUpKSB7CiAgICAgICAgICAgICAgICAkcHJvdmlkZXJzID0gYXJyYXlfbWVyZ2UoJHByb3ZpZGVycywgJHJlcG9Qcm92aWRlcnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb3ZpZGVyczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNQYWNrYWdlQWNjZXB0YWJsZSgkbmFtZXMsICRzdGFiaWxpdHkpCiAgICB7CiAgICAgICAgcmV0dXJuIFN0YWJpbGl0eUZpbHRlcjo6aXNQYWNrYWdlQWNjZXB0YWJsZSgkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkdGhpcy0+c3RhYmlsaXR5RmxhZ3MsICRuYW1lcywgJHN0YWJpbGl0eSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBwb29sIGZvciBkZXBlbmRlbmN5IHJlc29sdXRpb24gZnJvbSB0aGUgcGFja2FnZXMgaW4gdGhpcyByZXBvc2l0b3J5IHNldC4KICAgICAqCiAgICAgKiBAcmV0dXJuIFBvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZVBvb2woUmVxdWVzdCAkcmVxdWVzdCwgSU9JbnRlcmZhY2UgJGlvLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHBvb2xCdWlsZGVyID0gbmV3IFBvb2xCdWlsZGVyKCR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsICR0aGlzLT5zdGFiaWxpdHlGbGFncywgJHRoaXMtPnJvb3RBbGlhc2VzLCAkdGhpcy0+cm9vdFJlZmVyZW5jZXMsICRpbywgJGV2ZW50RGlzcGF0Y2hlcik7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvc2l0b3JpZXMgYXMgJHJlcG8pIHsKICAgICAgICAgICAgaWYgKCgkcmVwbyBpbnN0YW5jZW9mIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgfHwgJHJlcG8gaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5KSAmJiAhJHRoaXMtPmFsbG93SW5zdGFsbGVkUmVwb3NpdG9yaWVzKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdUaGUgcG9vbCBjYW4gbm90IGFjY2VwdCBwYWNrYWdlcyBmcm9tIGFuIGluc3RhbGxlZCByZXBvc2l0b3J5Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2NrZWQgPSB0cnVlOwoKICAgICAgICByZXR1cm4gJHBvb2xCdWlsZGVyLT5idWlsZFBvb2woJHRoaXMtPnJlcG9zaXRvcmllcywgJHJlcXVlc3QpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgcG9vbCBmb3IgZGVwZW5kZW5jeSByZXNvbHV0aW9uIGZyb20gdGhlIHBhY2thZ2VzIGluIHRoaXMgcmVwb3NpdG9yeSBzZXQuCiAgICAgKgogICAgICogQHJldHVybiBQb29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVQb29sV2l0aEFsbFBhY2thZ2VzKCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgIGlmICgoJHJlcG8gaW5zdGFuY2VvZiBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlIHx8ICRyZXBvIGluc3RhbmNlb2YgSW5zdGFsbGVkUmVwb3NpdG9yeSkgJiYgISR0aGlzLT5hbGxvd0luc3RhbGxlZFJlcG9zaXRvcmllcykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignVGhlIHBvb2wgY2FuIG5vdCBhY2NlcHQgcGFja2FnZXMgZnJvbSBhbiBpbnN0YWxsZWQgcmVwb3NpdG9yeScpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9ja2VkID0gdHJ1ZTsKCiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXBvc2l0b3J5LT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXNbXSA9ICRwYWNrYWdlOwoKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+cm9vdEFsaWFzZXNbJHBhY2thZ2UtPmdldE5hbWUoKV1bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGFsaWFzID0gJHRoaXMtPnJvb3RBbGlhc2VzWyRwYWNrYWdlLT5nZXROYW1lKCldWyRwYWNrYWdlLT5nZXRWZXJzaW9uKCldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRwYWNrYWdlLT5nZXRBbGlhc09mKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSBuZXcgQWxpYXNQYWNrYWdlKCRwYWNrYWdlLCAkYWxpYXNbJ2FsaWFzX25vcm1hbGl6ZWQnXSwgJGFsaWFzWydhbGlhcyddKTsKICAgICAgICAgICAgICAgICAgICAkYWxpYXNQYWNrYWdlLT5zZXRSb290UGFja2FnZUFsaWFzKHRydWUpOwogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBQb29sKCRwYWNrYWdlcyk7CiAgICB9CgogICAgLy8gVE9ETyB1bmlmeSB0aGlzIHdpdGggYWJvdmUgaW4gc29tZSBzaW1wbGVyIHZlcnNpb24gd2l0aG91dCAicmVxdWVzdCI/CiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUG9vbEZvclBhY2thZ2UoJHBhY2thZ2VOYW1lLCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWF0ZVBvb2xGb3JQYWNrYWdlcyhhcnJheSgkcGFja2FnZU5hbWUpLCAkbG9ja2VkUmVwbyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZVBvb2xGb3JQYWNrYWdlcygkcGFja2FnZU5hbWVzLCBMb2NrQXJyYXlSZXBvc2l0b3J5ICRsb2NrZWRSZXBvID0gbnVsbCkKICAgIHsKICAgICAgICAkcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KCRsb2NrZWRSZXBvKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VOYW1lcyBhcyAkcGFja2FnZU5hbWUpIHsKICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignY3JlYXRlUG9vbEZvclBhY2thZ2UocykgY2FuIG5vdCBiZSB1c2VkIGZvciBwbGF0Zm9ybSBwYWNrYWdlcywgYXMgdGhleSBhcmUgbmV2ZXIgbG9hZGVkIGJ5IHRoZSBQb29sQnVpbGRlciB3aGljaCBleHBlY3RzIHRoZW0gdG8gYmUgZml4ZWQuIFVzZSBjcmVhdGVQb29sV2l0aEFsbFBhY2thZ2VzIG9yIHBhc3MgaW4gYSBwcm9wZXIgcmVxdWVzdCB3aXRoIHRoZSBwbGF0Zm9ybSBwYWNrYWdlcyB5b3UgbmVlZCBmaXhlZCBpbiBpdC4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlcXVlc3QtPnJlcXVpcmVOYW1lKCRwYWNrYWdlTmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWF0ZVBvb2woJHJlcXVlc3QsIG5ldyBOdWxsSU8oKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0Um9vdEFsaWFzZXNQZXJQYWNrYWdlKGFycmF5ICRhbGlhc2VzKQogICAgewogICAgICAgICRub3JtYWxpemVkQWxpYXNlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRhbGlhc2VzIGFzICRhbGlhcykgewogICAgICAgICAgICAkbm9ybWFsaXplZEFsaWFzZXNbJGFsaWFzWydwYWNrYWdlJ11dWyRhbGlhc1sndmVyc2lvbiddXSA9IGFycmF5KAogICAgICAgICAgICAgICAgJ2FsaWFzJyA9PiAkYWxpYXNbJ2FsaWFzJ10sCiAgICAgICAgICAgICAgICAnYWxpYXNfbm9ybWFsaXplZCcgPT4gJGFsaWFzWydhbGlhc19ub3JtYWxpemVkJ10sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5vcm1hbGl6ZWRBbGlhc2VzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxMb2FkZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFRhcjsKdXNlIENvbXBvc2VyXFV0aWxcWmlwOwoKLyoqCiAqIEBhdXRob3IgU2VyZ2UgU21lcnRpbiA8c2VyZy5zbWVydGluQGdtYWlsLmNvbT4KICovCmNsYXNzIEFydGlmYWN0UmVwb3NpdG9yeSBleHRlbmRzIEFycmF5UmVwb3NpdG9yeSBpbXBsZW1lbnRzIENvbmZpZ3VyYWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgTG9hZGVySW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGxvYWRlcjsKCiAgICBwcm90ZWN0ZWQgJGxvb2t1cDsKICAgIHByb3RlY3RlZCAkcmVwb0NvbmZpZzsKICAgIHByaXZhdGUgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcmVwb0NvbmZpZywgSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ3ppcCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGFydGlmYWN0IHJlcG9zaXRvcnkgcmVxdWlyZXMgUEhQXCdzIHppcCBleHRlbnNpb24nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoKTsKICAgICAgICAkdGhpcy0+bG9va3VwID0gJHJlcG9Db25maWdbJ3VybCddOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+cmVwb0NvbmZpZyA9ICRyZXBvQ29uZmlnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdhcnRpZmFjdCByZXBvICgnLiR0aGlzLT5sb29rdXAuJyknOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvQ29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9Db25maWc7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIHBhcmVudDo6aW5pdGlhbGl6ZSgpOwoKICAgICAgICAkdGhpcy0+c2NhbkRpcmVjdG9yeSgkdGhpcy0+bG9va3VwKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNjYW5EaXJlY3RvcnkoJHBhdGgpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwoKICAgICAgICAkZGlyZWN0b3J5ID0gbmV3IFxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkcGF0aCwgXFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpGT0xMT1dfU1lNTElOS1MpOwogICAgICAgICRpdGVyYXRvciA9IG5ldyBcUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigkZGlyZWN0b3J5KTsKICAgICAgICAkcmVnZXggPSBuZXcgXFJlZ2V4SXRlcmF0b3IoJGl0ZXJhdG9yLCAnL14uK1wuKHppcHxwaGFyfHRhcnxnenx0Z3opJC9pJyk7CiAgICAgICAgZm9yZWFjaCAoJHJlZ2V4IGFzICRmaWxlKSB7CiAgICAgICAgICAgIC8qIEB2YXIgJGZpbGUgXFNwbEZpbGVJbmZvICovCiAgICAgICAgICAgIGlmICghJGZpbGUtPmlzRmlsZSgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+Z2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkZmlsZSk7CiAgICAgICAgICAgIGlmICghJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiRmlsZSA8Y29tbWVudD57JGZpbGUtPmdldEJhc2VuYW1lKCl9PC9jb21tZW50PiBkb2Vzbid0IHNlZW0gdG8gaG9sZCBhIHBhY2thZ2UiLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRlbXBsYXRlID0gJ0ZvdW5kIHBhY2thZ2UgPGluZm8+JXM8L2luZm8+ICg8Y29tbWVudD4lczwvY29tbWVudD4pIGluIGZpbGUgPGluZm8+JXM8L2luZm8+JzsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoJHRlbXBsYXRlLCAkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLCAkZmlsZS0+Z2V0QmFzZW5hbWUoKSksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKCiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb21wb3NlckluZm9ybWF0aW9uKFxTcGxGaWxlSW5mbyAkZmlsZSkKICAgIHsKICAgICAgICAkanNvbiA9IG51bGw7CiAgICAgICAgJGZpbGVUeXBlID0gbnVsbDsKICAgICAgICAkZmlsZUV4dGVuc2lvbiA9IHBhdGhpbmZvKCRmaWxlLT5nZXRQYXRobmFtZSgpLCBQQVRISU5GT19FWFRFTlNJT04pOwogICAgICAgIGlmIChpbl9hcnJheSgkZmlsZUV4dGVuc2lvbiwgYXJyYXkoJ2d6JywgJ3RhcicsICd0Z3onKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJGZpbGVUeXBlID0gJ3Rhcic7CiAgICAgICAgfSBlbHNlaWYgKCRmaWxlRXh0ZW5zaW9uID09PSAnemlwJykgewogICAgICAgICAgICAkZmlsZVR5cGUgPSAnemlwJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZpbGVzIHdpdGggIicuJGZpbGVFeHRlbnNpb24uJyIgZXh0ZW5zaW9ucyBhcmVuXCd0IHN1cHBvcnRlZC4gT25seSBaSVAgYW5kIFRBUi9UQVIuR1ovVEdaIGFyY2hpdmVzIGFyZSBzdXBwb3J0ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoJGZpbGVUeXBlID09PSAndGFyJykgewogICAgICAgICAgICAgICAgJGpzb24gPSBUYXI6OmdldENvbXBvc2VySnNvbigkZmlsZS0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkanNvbiA9IFppcDo6Z2V0Q29tcG9zZXJKc29uKCRmaWxlLT5nZXRQYXRobmFtZSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKCdGYWlsZWQgbG9hZGluZyBwYWNrYWdlICcuJGZpbGUtPmdldFBhdGhuYW1lKCkuJzogJy4kZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCksIGZhbHNlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGpzb24pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2UgPSBKc29uRmlsZTo6cGFyc2VKc29uKCRqc29uLCAkZmlsZS0+Z2V0UGF0aG5hbWUoKS4nI2NvbXBvc2VyLmpzb24nKTsKICAgICAgICAkcGFja2FnZVsnZGlzdCddID0gYXJyYXkoCiAgICAgICAgICAgICd0eXBlJyA9PiAkZmlsZVR5cGUsCiAgICAgICAgICAgICd1cmwnID0+IHN0cnRyKCRmaWxlLT5nZXRQYXRobmFtZSgpLCAnXFwnLCAnLycpLAogICAgICAgICAgICAnc2hhc3VtJyA9PiBzaGExX2ZpbGUoJGZpbGUtPmdldFJlYWxQYXRoKCkpLAogICAgICAgICk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmxvYWRlci0+bG9hZCgkcGFja2FnZSk7CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignRmFpbGVkIGxvYWRpbmcgcGFja2FnZSBpbiAnLiRmaWxlLic6ICcuJGUtPmdldE1lc3NhZ2UoKSwgMCwgJGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CgovKioKICogSW5zdGFsbGFibGUgcmVwb3NpdG9yeSBpbnRlcmZhY2UuCiAqCiAqIEp1c3QgdXNlZCB0byB0YWcgaW5zdGFsbGVkIHJlcG9zaXRvcmllcyBzbyB0aGUgYmFzZSBjbGFzc2VzIGNhbiBhY3QgZGlmZmVyZW50bHkgb24gQWxpYXMgcGFja2FnZXMKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KaW50ZXJmYWNlIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgZXh0ZW5kcyBXcml0YWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiBwYWNrYWdlcyB3ZXJlIG5ldmVyIGluc3RhbGxlZCBpbiB0aGlzIHJlcG9zaXRvcnkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRnJlc2goKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKLyoqCiAqIFRocm93biB3aGVuIGEgc2VjdXJpdHkgcHJvYmxlbSwgbGlrZSBhIGJyb2tlbiBvciBtaXNzaW5nIHNpZ25hdHVyZQogKgogKiBAYXV0aG9yIEVyaWMgRGFzcGV0IDxlZGFzcGV0QHN1cnZvbC5mcj4KICovCmNsYXNzIFJlcG9zaXRvcnlTZWN1cml0eUV4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKCi8qKgogKiBGaWx0ZXJzIHdoaWNoIHBhY2thZ2VzIGFyZSBzZWVuIGFzIGNhbm9uaWNhbCBvbiB0aGlzIHJlcG8gYnkgbG9hZFBhY2thZ2VzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEZpbHRlclJlcG9zaXRvcnkgaW1wbGVtZW50cyBSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJG9ubHkgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkZXhjbHVkZSA9IGFycmF5KCk7CiAgICBwcml2YXRlICRjYW5vbmljYWwgPSB0cnVlOwogICAgcHJpdmF0ZSAkcmVwbzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydvbmx5J10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJG9wdGlvbnNbJ29ubHknXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCcib25seSIga2V5IGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkuJyBzaG91bGQgYmUgYW4gYXJyYXknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+b25seSA9ICd7XicuaW1wbG9kZSgnfCcsIGFycmF5X21hcChmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCR2YWwsICclcycpOwogICAgICAgICAgICB9LCAkb3B0aW9uc1snb25seSddKSkgLickfWlEJzsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydleGNsdWRlJ10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJG9wdGlvbnNbJ2V4Y2x1ZGUnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCciZXhjbHVkZSIga2V5IGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkuJyBzaG91bGQgYmUgYW4gYXJyYXknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+ZXhjbHVkZSA9ICd7XicuaW1wbG9kZSgnfCcsIGFycmF5X21hcChmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCR2YWwsICclcycpOwogICAgICAgICAgICB9LCAkb3B0aW9uc1snZXhjbHVkZSddKSkgLickfWlEJzsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5leGNsdWRlICYmICR0aGlzLT5vbmx5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdPbmx5IG9uZSBvZiAib25seSIgYW5kICJleGNsdWRlIiBjYW4gYmUgc3BlY2lmaWVkIGZvciByZXBvc2l0b3J5ICcuJHJlcG8tPmdldFJlcG9OYW1lKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICBpZiAoIWlzX2Jvb2woJG9wdGlvbnNbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJyJjYW5vbmljYWwiIGtleSBmb3IgcmVwb3NpdG9yeSAnLiRyZXBvLT5nZXRSZXBvTmFtZSgpLicgc2hvdWxkIGJlIGEgYm9vbGVhbicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jYW5vbmljYWwgPSAkb3B0aW9uc1snY2Fub25pY2FsJ107CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVwbyA9ICRyZXBvOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvLT5nZXRSZXBvTmFtZSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcnkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwbzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1BhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlzQWxsb3dlZCgkbmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG8tPmZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pc0FsbG93ZWQoJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvLT5maW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRQYWNrYWdlcyhhcnJheSAkcGFja2FnZU1hcCwgYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCBhcnJheSAkYWxyZWFkeUxvYWRlZCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VNYXAgYXMgJG5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aXNBbGxvd2VkKCRuYW1lKSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VNYXBbJG5hbWVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkcGFja2FnZU1hcCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ25hbWVzRm91bmQnID0+IGFycmF5KCksICdwYWNrYWdlcycgPT4gYXJyYXkoKSk7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPnJlcG8tPmxvYWRQYWNrYWdlcygkcGFja2FnZU1hcCwgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgJHN0YWJpbGl0eUZsYWdzLCAkYWxyZWFkeUxvYWRlZCk7CiAgICAgICAgaWYgKCEkdGhpcy0+Y2Fub25pY2FsKSB7CiAgICAgICAgICAgICRyZXN1bHRbJ25hbWVzRm91bmQnXSA9IGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlYXJjaCgkcXVlcnksICRtb2RlID0gMCwgJHR5cGUgPSBudWxsKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwby0+c2VhcmNoKCRxdWVyeSwgJG1vZGUsICR0eXBlKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmlzQWxsb3dlZCgkcGFja2FnZVsnbmFtZSddKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNBbGxvd2VkKCRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZXBvLT5nZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKSBhcyAkcHJvdmlkZXIpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5pc0FsbG93ZWQoJHByb3ZpZGVyWyduYW1lJ10pKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkcHJvdmlkZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwby0+cmVtb3ZlUGFja2FnZSgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5yZXBvLT5jb3VudCgpID4gMCkgewogICAgICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmdldFBhY2thZ2VzKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc0FsbG93ZWQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+b25seSAmJiAhJHRoaXMtPmV4Y2x1ZGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPm9ubHkpIHsKICAgICAgICAgICAgcmV0dXJuIChib29sKSBwcmVnX21hdGNoKCR0aGlzLT5vbmx5LCAkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIXByZWdfbWF0Y2goJHRoaXMtPmV4Y2x1ZGUsICRuYW1lKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwoKLyoqCiAqIFJlcG9zaXRvcnkgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgUmVwb3NpdG9yeUludGVyZmFjZSBleHRlbmRzIFxDb3VudGFibGUKewogICAgY29uc3QgU0VBUkNIX0ZVTExURVhUID0gMDsKICAgIGNvbnN0IFNFQVJDSF9OQU1FID0gMTsKCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBzcGVjaWZpZWQgcGFja2FnZSByZWdpc3RlcmVkIChpbnN0YWxsZWQpLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1BhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7CgogICAgLyoqCiAgICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG1hdGNoIG9mIGEgcGFja2FnZSBieSBuYW1lIGFuZCB2ZXJzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8Q29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCBwYWNrYWdlIHZlcnNpb24gb3IgdmVyc2lvbiBjb25zdHJhaW50IHRvIG1hdGNoIGFnYWluc3QKICAgICAqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KTsKCiAgICAvKioKICAgICAqIFNlYXJjaGVzIGZvciBhbGwgcGFja2FnZXMgbWF0Y2hpbmcgYSBuYW1lIGFuZCBvcHRpb25hbGx5IGEgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICAgICAgJG5hbWUgICAgICAgcGFja2FnZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgbGlzdCBvZiByZWdpc3RlcmVkIHBhY2thZ2VzLgogICAgICoKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBsaXN0IG9mIHJlZ2lzdGVyZWQgcGFja2FnZXMgd2l0aCB0aGUgc3VwcGxpZWQgbmFtZQogICAgICoKICAgICAqIC0gVGhlIHBhY2thZ2VzIHJldHVybmVkIGFyZSB0aGUgcGFja2FnZXMgZm91bmQgd2hpY2ggbWF0Y2ggdGhlIGNvbnN0cmFpbnRzLCBhY2NlcHRhYmxlIHN0YWJpbGl0eSBhbmQgc3RhYmlsaXR5IGZsYWdzIHByb3ZpZGVkCiAgICAgKiAtIFRoZSBuYW1lc0ZvdW5kIHJldHVybmVkIGFyZSBuYW1lcyB3aGljaCBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBjYW5vbmljYWxseSBmb3VuZCBpbiB0aGlzIHJlcG9zaXRvcnksIHRoYXQgc2hvdWxkIG5vdCBiZSBsb29rZWQgdXAgaW4gYW55IGZ1cnRoZXIgbG93ZXIgcHJpb3JpdHkgcmVwb3NpdG9yaWVzCiAgICAgKgogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2VbXSAkcGFja2FnZU5hbWVNYXAgICAgICAgIHBhY2thZ2UgbmFtZXMgcG9pbnRpbmcgdG8gY29uc3RyYWludHMKICAgICAqIEBwYXJhbSBpbnRbXSAgICAgICAgICAgICAgICAgJGFjY2VwdGFibGVTdGFiaWxpdGllcyBhcnJheSBvZiBzdGFiaWxpdHkgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcHNhbG0tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwYXJhbSBpbnRbXSAkc3RhYmlsaXR5RmxhZ3MgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSBhcnJheVtdICRhbHJlYWR5TG9hZGVkIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBwYWNrYWdlIHZlcnNpb24gPT4gcGFja2FnZQogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBQYWNrYWdlSW50ZXJmYWNlPj4gJGFscmVhZHlMb2FkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFtuYW1lc0ZvdW5kID0+IHN0cmluZ1tdLCBwYWNrYWdlcyA9PiBQYWNrYWdlSW50ZXJmYWNlW11dCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5e25hbWVzRm91bmQ6IHN0cmluZ1tdLCBwYWNrYWdlczogUGFja2FnZUludGVyZmFjZVtdfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlTmFtZU1hcCwgYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCBhcnJheSAkYWxyZWFkeUxvYWRlZCA9IGFycmF5KCkpOwoKICAgIC8qKgogICAgICogU2VhcmNoZXMgdGhlIHJlcG9zaXRvcnkgZm9yIHBhY2thZ2VzIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlcnkgc2VhcmNoIHF1ZXJ5CiAgICAgKiBAcGFyYW0gaW50ICAgICRtb2RlICBhIHNldCBvZiBTRUFSQ0hfKiBjb25zdGFudHMgdG8gc2VhcmNoIG9uLCBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGRvIGEgYmVzdCBlZmZvcnQgb25seQogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSAgVGhlIHR5cGUgb2YgcGFja2FnZSB0byBzZWFyY2ggZm9yLiBEZWZhdWx0cyB0byBhbGwgdHlwZXMgb2YgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5W10gYW4gYXJyYXkgb2YgYXJyYXkoJ25hbWUnID0+ICcuLi4nLCAnZGVzY3JpcHRpb24nID0+ICcuLi4nKQogICAgICogQHBzYWxtLXJldHVybiBsaXN0PGFycmF5e25hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZ30+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWFyY2goJHF1ZXJ5LCAkbW9kZSA9IDAsICR0eXBlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwYWNrYWdlcyBwcm92aWRpbmcgYSBnaXZlbiBwYWNrYWdlIG5hbWUKICAgICAqCiAgICAgKiBQYWNrYWdlcyB3aGljaCBoYXZlIHRoZSBzYW1lIG5hbWUgYXMgJHBhY2thZ2VOYW1lIHNob3VsZCBub3QgYmUgcmV0dXJuZWQsIG9ubHkgdGhvc2UgdGhhdCBoYXZlIGEgInByb3ZpZGUiIG9uIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2VOYW1lIHBhY2thZ2UgbmFtZSB3aGljaCBtdXN0IGJlIHByb3ZpZGVkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdIGFuIGFycmF5IHdpdGggdGhlIHByb3ZpZGVyIG5hbWUgYXMga2V5IGFuZCB2YWx1ZSBvZiBhcnJheSgnbmFtZScgPT4gJy4uLicsICdkZXNjcmlwdGlvbicgPT4gJy4uLicsICd0eXBlJyA9PiAnLi4uJykKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXk8c3RyaW5nLCBhcnJheXtuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcsIHR5cGU6IHN0cmluZ30+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuYW1lIHJlcHJlc2VudGluZyB0aGlzIHJlcG9zaXRvcnkgdG8gdGhlIHVzZXIKICAgICAqCiAgICAgKiBUaGlzIGlzIGJlc3QgZWZmb3J0IGFuZCBkZWZpbml0ZWx5IGNhbiBub3QgYWx3YXlzIGJlIHZlcnkgcHJlY2lzZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvbkd1ZXNzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwp1c2UgQ29tcG9zZXJcVXRpbFxHaXQgYXMgR2l0VXRpbDsKCi8qKgogKiBUaGlzIHJlcG9zaXRvcnkgYWxsb3dzIGluc3RhbGxpbmcgbG9jYWwgcGFja2FnZXMgdGhhdCBhcmUgbm90IG5lY2Vzc2FyaWx5IHVuZGVyIHRoZWlyIG93biBWQ1MuCiAqCiAqIFRoZSBsb2NhbCBwYWNrYWdlcyB3aWxsIGJlIHN5bWxpbmtlZCB3aGVuIHBvc3NpYmxlLCBlbHNlIHRoZXkgd2lsbCBiZSBjb3BpZWQuCiAqCiAqIEBjb2RlCiAqICJyZXF1aXJlIjogewogKiAgICAgIjx2ZW5kb3I+Lzxsb2NhbC1wYWNrYWdlPiI6ICIqIgogKiB9LAogKiAicmVwb3NpdG9yaWVzIjogWwogKiAgICAgewogKiAgICAgICAgICJ0eXBlIjogInBhdGgiLAogKiAgICAgICAgICJ1cmwiOiAiLi4vLi4vcmVsYXRpdmUvcGF0aC90by9wYWNrYWdlLyIKICogICAgIH0sCiAqICAgICB7CiAqICAgICAgICAgInR5cGUiOiAicGF0aCIsCiAqICAgICAgICAgInVybCI6ICIvYWJzb2x1dGUvcGF0aC90by9wYWNrYWdlLyIKICogICAgIH0sCiAqICAgICB7CiAqICAgICAgICAgInR5cGUiOiAicGF0aCIsCiAqICAgICAgICAgInVybCI6ICIvYWJzb2x1dGUvcGF0aC90by9zZXZlcmFsL3BhY2thZ2VzLyoiCiAqICAgICB9LAogKiAgICAgewogKiAgICAgICAgICJ0eXBlIjogInBhdGgiLAogKiAgICAgICAgICJ1cmwiOiAiLi4vLi4vcmVsYXRpdmUvcGF0aC90by9wYWNrYWdlLyIsCiAqICAgICAgICAgIm9wdGlvbnMiOiB7CiAqICAgICAgICAgICAgICJzeW1saW5rIjogZmFsc2UKICogICAgICAgICB9CiAqICAgICB9LAogKiBdCiAqIEBlbmRjb2RlCiAqCiAqIEBhdXRob3IgU2FtdWVsIFJvemUgPHNhbXVlbC5yb3plQGdtYWlsLmNvbT4KICogQGF1dGhvciBKb2hhbm4gUmVpbmtlIDxqb2hhbm4ucmVpbmtlQGdtYWlsLmNvbT4KICovCmNsYXNzIFBhdGhSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgQ29uZmlndXJhYmxlUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEB2YXIgQXJyYXlMb2FkZXIKICAgICAqLwogICAgcHJpdmF0ZSAkbG9hZGVyOwoKICAgIC8qKgogICAgICogQHZhciBWZXJzaW9uR3Vlc3NlcgogICAgICovCiAgICBwcml2YXRlICR2ZXJzaW9uR3Vlc3NlcjsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHVybDsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSAkcmVwb0NvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yCiAgICAgKi8KICAgIHByaXZhdGUgJHByb2Nlc3M7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJG9wdGlvbnM7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBwYXRoIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICRyZXBvQ29uZmlnCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgJGNvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9Db25maWcsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkcmVwb0NvbmZpZ1sndXJsJ10pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IG11c3Qgc3BlY2lmeSB0aGUgYHVybGAgY29uZmlndXJhdGlvbiBmb3IgdGhlIHBhdGggcmVwb3NpdG9yeScpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxvYWRlciA9IG5ldyBBcnJheUxvYWRlcihudWxsLCB0cnVlKTsKICAgICAgICAkdGhpcy0+dXJsID0gUGxhdGZvcm06OmV4cGFuZFBhdGgoJHJlcG9Db25maWdbJ3VybCddKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkdGhpcy0+dmVyc2lvbkd1ZXNzZXIgPSBuZXcgVmVyc2lvbkd1ZXNzZXIoJGNvbmZpZywgJHRoaXMtPnByb2Nlc3MsIG5ldyBWZXJzaW9uUGFyc2VyKCkpOwogICAgICAgICR0aGlzLT5yZXBvQ29uZmlnID0gJHJlcG9Db25maWc7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBpc3NldCgkcmVwb0NvbmZpZ1snb3B0aW9ucyddKSA/ICRyZXBvQ29uZmlnWydvcHRpb25zJ10gOiBhcnJheSgpOwogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPm9wdGlvbnNbJ3JlbGF0aXZlJ10pKSB7CiAgICAgICAgICAgICRmaWxlc3lzdGVtID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnNbJ3JlbGF0aXZlJ10gPSAhJGZpbGVzeXN0ZW0tPmlzQWJzb2x1dGVQYXRoKCR0aGlzLT51cmwpOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdwYXRoIHJlcG8gKCcuVXJsOjpzYW5pdGl6ZSgkdGhpcy0+cmVwb0NvbmZpZ1sndXJsJ10pLicpJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0NvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvQ29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcGF0aCByZXBvc2l0b3J5LgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYmFzaWNhbGx5IHJlYWQgdGhlIGZvbGRlciBhbmQgYWRkIHRoZSBmb3VuZCBwYWNrYWdlLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICR1cmxNYXRjaGVzID0gJHRoaXMtPmdldFVybE1hdGNoZXMoKTsKCiAgICAgICAgaWYgKGVtcHR5KCR1cmxNYXRjaGVzKSkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne1sqe31dfScsICR0aGlzLT51cmwpKSB7CiAgICAgICAgICAgICAgICAkdXJsID0gJHRoaXMtPnVybDsKICAgICAgICAgICAgICAgIHdoaWxlIChwcmVnX21hdGNoKCd7Wyp7fV19JywgJHVybCkpIHsKICAgICAgICAgICAgICAgICAgICAkdXJsID0gZGlybmFtZSgkdXJsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHRoZSBwYXJlbnQgZGlyZWN0b3J5IGJlZm9yZSBhbnkgd2lsZGNhcmQgZXhpc3RzLCBzbyB3ZSBhc3N1bWUgaXQgaXMgY29ycmVjdGx5IGNvbmZpZ3VyZWQgYnV0IHNpbXBseSBlbXB0eQogICAgICAgICAgICAgICAgaWYgKGlzX2RpcigkdXJsKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgYHVybGAgc3VwcGxpZWQgZm9yIHRoZSBwYXRoICgnIC4gJHRoaXMtPnVybCAuICcpIHJlcG9zaXRvcnkgZG9lcyBub3QgZXhpc3QnKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR1cmxNYXRjaGVzIGFzICR1cmwpIHsKICAgICAgICAgICAgJHBhdGggPSByZWFscGF0aCgkdXJsKSAuIERJUkVDVE9SWV9TRVBBUkFUT1I7CiAgICAgICAgICAgICRjb21wb3NlckZpbGVQYXRoID0gJHBhdGguJ2NvbXBvc2VyLmpzb24nOwoKICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkY29tcG9zZXJGaWxlUGF0aCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkanNvbiA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRjb21wb3NlckZpbGVQYXRoKTsKICAgICAgICAgICAgJHBhY2thZ2UgPSBKc29uRmlsZTo6cGFyc2VKc29uKCRqc29uLCAkY29tcG9zZXJGaWxlUGF0aCk7CiAgICAgICAgICAgICRwYWNrYWdlWydkaXN0J10gPSBhcnJheSgKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAncGF0aCcsCiAgICAgICAgICAgICAgICAndXJsJyA9PiAkdXJsLAogICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gc2hhMSgkanNvbiAuIHNlcmlhbGl6ZSgkdGhpcy0+b3B0aW9ucykpLAogICAgICAgICAgICApOwogICAgICAgICAgICAkcGFja2FnZVsndHJhbnNwb3J0LW9wdGlvbnMnXSA9ICR0aGlzLT5vcHRpb25zOwogICAgICAgICAgICB1bnNldCgkcGFja2FnZVsndHJhbnNwb3J0LW9wdGlvbnMnXVsndmVyc2lvbnMnXSk7CgogICAgICAgICAgICAvLyB1c2UgdGhlIHZlcnNpb24gcHJvdmlkZWQgYXMgb3B0aW9uIGlmIGF2YWlsYWJsZQogICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ25hbWUnXSwgJHRoaXMtPm9wdGlvbnNbJ3ZlcnNpb25zJ11bJHBhY2thZ2VbJ25hbWUnXV0pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZVsndmVyc2lvbiddID0gJHRoaXMtPm9wdGlvbnNbJ3ZlcnNpb25zJ11bJHBhY2thZ2VbJ25hbWUnXV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNhcnJ5IG92ZXIgdGhlIHJvb3QgcGFja2FnZSB2ZXJzaW9uIGlmIHRoaXMgcGF0aCByZXBvIGlzIGluIHRoZSBzYW1lIGdpdCByZXBvc2l0b3J5IGFzIHJvb3QgcGFja2FnZQogICAgICAgICAgICBpZiAoIWlzc2V0KCRwYWNrYWdlWyd2ZXJzaW9uJ10pICYmICgkcm9vdFZlcnNpb24gPSBnZXRlbnYoJ0NPTVBPU0VSX1JPT1RfVkVSU0lPTicpKSkgewogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgcmV2LXBhcnNlIEhFQUQnLCAkcmVmMSwgJHBhdGgpCiAgICAgICAgICAgICAgICAgICAgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZXYtcGFyc2UgSEVBRCcsICRyZWYyKQogICAgICAgICAgICAgICAgICAgICYmICRyZWYxID09PSAkcmVmMgogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb24nXSA9ICRyb290VmVyc2lvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG91dHB1dCA9ICcnOwogICAgICAgICAgICBpZiAoaXNfZGlyKCRwYXRoIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICcuZ2l0JykgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBsb2cgLW4xIC0tcHJldHR5PSVIJy5HaXRVdGlsOjpnZXROb1Nob3dTaWduYXR1cmVGbGFnKCR0aGlzLT5wcm9jZXNzKSwgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZVsnZGlzdCddWydyZWZlcmVuY2UnXSA9IHRyaW0oJG91dHB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uRGF0YSA9ICR0aGlzLT52ZXJzaW9uR3Vlc3Nlci0+Z3Vlc3NWZXJzaW9uKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHZlcnNpb25EYXRhKSAmJiAkdmVyc2lvbkRhdGFbJ3ByZXR0eV92ZXJzaW9uJ10pIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhIGZlYXR1cmUgYnJhbmNoIGRldGVjdGVkLCB3ZSBhZGQgYSBzZWNvbmQgcGFja2FnZXMgd2l0aCB0aGUgZmVhdHVyZSBicmFuY2ggdmVyc2lvbgogICAgICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJHZlcnNpb25EYXRhWydmZWF0dXJlX3ByZXR0eV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlWyd2ZXJzaW9uJ10gPSAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHRoaXMtPmxvYWRlci0+bG9hZCgkcGFja2FnZSkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb24nXSA9ICR2ZXJzaW9uRGF0YVsncHJldHR5X3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VbJ3ZlcnNpb24nXSA9ICdkZXYtbWFzdGVyJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bG9hZGVyLT5sb2FkKCRwYWNrYWdlKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIGxpc3Qgb2YgYWxsIChwb3NzaWJseSByZWxhdGl2ZSkgcGF0aCBuYW1lcyBtYXRjaGluZyBnaXZlbiB1cmwgKHN1cHBvcnRzIGdsb2JiaW5nKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VXJsTWF0Y2hlcygpCiAgICB7CiAgICAgICAgJGZsYWdzID0gR0xPQl9NQVJLIHwgR0xPQl9PTkxZRElSOwoKICAgICAgICBpZiAoZGVmaW5lZCgnR0xPQl9CUkFDRScpKSB7CiAgICAgICAgICAgICRmbGFncyB8PSBHTE9CX0JSQUNFOwogICAgICAgIH0gZWxzZWlmIChzdHJwb3MoJHRoaXMtPnVybCwgJ3snKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR0aGlzLT51cmwsICd9JykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIG9wZXJhdGluZyBzeXN0ZW0gZG9lcyBub3Qgc3VwcG9ydCBHTE9CX0JSQUNFIHdoaWNoIGlzIHJlcXVpcmVkIGZvciB0aGUgdXJsICcuICR0aGlzLT51cmwpOwogICAgICAgIH0KCiAgICAgICAgLy8gRW5zdXJlIGVudmlyb25tZW50LXNwZWNpZmljIHBhdGggc2VwYXJhdG9ycyBhcmUgbm9ybWFsaXplZCB0byBVUkwgc2VwYXJhdG9ycwogICAgICAgIHJldHVybiBhcnJheV9tYXAoZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgcmV0dXJuIHJ0cmltKHN0cl9yZXBsYWNlKERJUkVDVE9SWV9TRVBBUkFUT1IsICcvJywgJHZhbCksICcvJyk7CiAgICAgICAgfSwgZ2xvYigkdGhpcy0+dXJsLCAkZmxhZ3MpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKLyoqCiAqIEJ1aWxkcyBsaXN0IG9mIHBhY2thZ2UgZnJvbSBQRUFSIGNoYW5uZWwuCiAqCiAqIFBhY2thZ2VzIHJlYWQgZnJvbSBjaGFubmVsIGFyZSBuYW1lZCBhcyAncGVhci17Y2hhbm5lbE5hbWV9L3twYWNrYWdlTmFtZX0nCiAqIGFuZCBoYXMgYWxpYXNlZCBhcyAncGVhci17Y2hhbm5lbEFsaWFzfS97cGFja2FnZU5hbWV9JwogKgogKiBAYXV0aG9yIEJlbmphbWluIEViZXJsZWkgPGtvbnRha3RAYmViZXJsZWkuZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGRlcHJlY2F0ZWQKICogQHByaXZhdGUKICovCmNsYXNzIFBlYXJSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgUEVBUiByZXBvc2l0b3J5IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBDb21wb3NlciAyLjAnKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBsYXRmb3JtXEhodm1EZXRlY3RvcjsKdXNlIENvbXBvc2VyXFBsYXRmb3JtXFJ1bnRpbWU7CnVzZSBDb21wb3NlclxQbGF0Zm9ybVxWZXJzaW9uOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkludGVyZmFjZTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgQ29tcG9zZXJcWGRlYnVnSGFuZGxlclxYZGVidWdIYW5kbGVyOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBsYXRmb3JtUmVwb3NpdG9yeSBleHRlbmRzIEFycmF5UmVwb3NpdG9yeQp7CiAgICBjb25zdCBQTEFURk9STV9QQUNLQUdFX1JFR0VYID0gJ3teKD86cGhwKD86LTY0Yml0fC1pcHY2fC16dHN8LWRlYnVnKT98aGh2bXwoPzpleHR8bGliKS1bYS16MC05XSg/OltfLi1dP1thLXowLTldKykqfGNvbXBvc2VyLSg/OnBsdWdpbnxydW50aW1lKS1hcGkpJH1pRCc7CgogICAgLyoqCiAgICAgKiBAdmFyIFZlcnNpb25QYXJzZXIKICAgICAqLwogICAgcHJpdmF0ZSAkdmVyc2lvblBhcnNlcjsKCiAgICAvKioKICAgICAqIERlZmluZXMgb3ZlcnJpZGVzIHNvIHRoYXQgdGhlIHBsYXRmb3JtIGNhbiBiZSBtb2NrZWQKICAgICAqCiAgICAgKiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IHZlcnNpb24gbnVtYmVyIG1hcHBpbmdzCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRvdmVycmlkZXMgPSBhcnJheSgpOwoKICAgIHByaXZhdGUgJHJ1bnRpbWU7CiAgICBwcml2YXRlICRoaHZtRGV0ZWN0b3I7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRwYWNrYWdlcyA9IGFycmF5KCksIGFycmF5ICRvdmVycmlkZXMgPSBhcnJheSgpLCBSdW50aW1lICRydW50aW1lID0gbnVsbCwgSGh2bURldGVjdG9yICRoaHZtRGV0ZWN0b3IgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5ydW50aW1lID0gJHJ1bnRpbWUgPzogbmV3IFJ1bnRpbWUoKTsKICAgICAgICAkdGhpcy0+aGh2bURldGVjdG9yID0gJGhodm1EZXRlY3RvciA/OiBuZXcgSGh2bURldGVjdG9yKCk7CiAgICAgICAgZm9yZWFjaCAoJG92ZXJyaWRlcyBhcyAkbmFtZSA9PiAkdmVyc2lvbikgewogICAgICAgICAgICAkdGhpcy0+b3ZlcnJpZGVzW3N0cnRvbG93ZXIoJG5hbWUpXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSwgJ3ZlcnNpb24nID0+ICR2ZXJzaW9uKTsKICAgICAgICB9CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcGFja2FnZXMpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdwbGF0Zm9ybSByZXBvJzsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKCiAgICAgICAgLy8gQWRkIGVhY2ggb2YgdGhlIG92ZXJyaWRlIHZlcnNpb25zIGFzIG9wdGlvbnMuCiAgICAgICAgLy8gTGF0ZXIgd2UgbWlnaHQgZXZlbiByZXBsYWNlIHRoZSBleHRlbnNpb25zIGluc3RlYWQuCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm92ZXJyaWRlcyBhcyAkb3ZlcnJpZGUpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBpdCdzIGEgcGxhdGZvcm0gcGFja2FnZS4KICAgICAgICAgICAgaWYgKCFzZWxmOjppc1BsYXRmb3JtUGFja2FnZSgkb3ZlcnJpZGVbJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIHBsYXRmb3JtIHBhY2thZ2UgbmFtZSBpbiBjb25maWcucGxhdGZvcm06ICcuJG92ZXJyaWRlWyduYW1lJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+YWRkT3ZlcnJpZGRlblBhY2thZ2UoJG92ZXJyaWRlKTsKICAgICAgICB9CgogICAgICAgICRwcmV0dHlWZXJzaW9uID0gUGx1Z2luSW50ZXJmYWNlOjpQTFVHSU5fQVBJX1ZFUlNJT047CiAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAkY29tcG9zZXJQbHVnaW5BcGkgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCdjb21wb3Nlci1wbHVnaW4tYXBpJywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAkY29tcG9zZXJQbHVnaW5BcGktPnNldERlc2NyaXB0aW9uKCdUaGUgQ29tcG9zZXIgUGx1Z2luIEFQSScpOwogICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRjb21wb3NlclBsdWdpbkFwaSk7CgogICAgICAgICRwcmV0dHlWZXJzaW9uID0gQ29tcG9zZXI6OlJVTlRJTUVfQVBJX1ZFUlNJT047CiAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAkY29tcG9zZXJSdW50aW1lQXBpID0gbmV3IENvbXBsZXRlUGFja2FnZSgnY29tcG9zZXItcnVudGltZS1hcGknLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICRjb21wb3NlclJ1bnRpbWVBcGktPnNldERlc2NyaXB0aW9uKCdUaGUgQ29tcG9zZXIgUnVudGltZSBBUEknKTsKICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkY29tcG9zZXJSdW50aW1lQXBpKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BIUF9WRVJTSU9OJyk7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9IHByZWdfcmVwbGFjZSgnI14oW15+Ky1dKykuKiQjJywgJyQxJywgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdQSFBfVkVSU0lPTicpKTsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICB9CgogICAgICAgICRwaHAgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCdwaHAnLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICRwaHAtPnNldERlc2NyaXB0aW9uKCdUaGUgUEhQIGludGVycHJldGVyJyk7CiAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBocCk7CgogICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BIUF9ERUJVRycpKSB7CiAgICAgICAgICAgICRwaHBkZWJ1ZyA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ3BocC1kZWJ1ZycsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICRwaHBkZWJ1Zy0+c2V0RGVzY3JpcHRpb24oJ1RoZSBQSFAgaW50ZXJwcmV0ZXIsIHdpdGggZGVidWdnaW5nIHN5bWJvbHMnKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBocGRlYnVnKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ1BIUF9aVFMnKSAmJiAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BIUF9aVFMnKSkgewogICAgICAgICAgICAkcGhwenRzID0gbmV3IENvbXBsZXRlUGFja2FnZSgncGhwLXp0cycsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICRwaHB6dHMtPnNldERlc2NyaXB0aW9uKCdUaGUgUEhQIGludGVycHJldGVyLCB3aXRoIFplbmQgVGhyZWFkIFNhZmV0eScpOwogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkcGhwenRzKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BIUF9JTlRfU0laRScpID09PSA4KSB7CiAgICAgICAgICAgICRwaHA2NCA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJ3BocC02NGJpdCcsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICRwaHA2NC0+c2V0RGVzY3JpcHRpb24oJ1RoZSBQSFAgaW50ZXJwcmV0ZXIsIDY0Yml0Jyk7CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwaHA2NCk7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgQUZfSU5FVDYgY29uc3RhbnQgaXMgb25seSBkZWZpbmVkIGlmIGV4dC1zb2NrZXRzIGlzIGF2YWlsYWJsZSBidXQKICAgICAgICAvLyBJUHY2IHN1cHBvcnQgbWlnaHQgc3RpbGwgYmUgYXZhaWxhYmxlLgogICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ0FGX0lORVQ2JykgfHwgU2lsZW5jZXI6OmNhbGwoYXJyYXkoJHRoaXMtPnJ1bnRpbWUsICdpbnZva2UnKSwgJ2luZXRfcHRvbicsIGFycmF5KCc6OicpKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgJHBocElwdjYgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCdwaHAtaXB2NicsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICRwaHBJcHY2LT5zZXREZXNjcmlwdGlvbignVGhlIFBIUCBpbnRlcnByZXRlciwgd2l0aCBJUHY2IHN1cHBvcnQnKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBocElwdjYpOwogICAgICAgIH0KCiAgICAgICAgJGxvYWRlZEV4dGVuc2lvbnMgPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9ucygpOwoKICAgICAgICAvLyBFeHRlbnNpb25zIHNjYW5uaW5nCiAgICAgICAgZm9yZWFjaCAoJGxvYWRlZEV4dGVuc2lvbnMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgaWYgKGluX2FycmF5KCRuYW1lLCBhcnJheSgnc3RhbmRhcmQnLCAnQ29yZScpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5hZGRFeHRlbnNpb24oJG5hbWUsICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25WZXJzaW9uKCRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayBmb3IgWGRlYnVnIGluIGEgcmVzdGFydGVkIHByb2Nlc3MKICAgICAgICBpZiAoIWluX2FycmF5KCd4ZGVidWcnLCAkbG9hZGVkRXh0ZW5zaW9ucywgdHJ1ZSkgJiYgKCRwcmV0dHlWZXJzaW9uID0gWGRlYnVnSGFuZGxlcjo6Z2V0U2tpcHBlZFZlcnNpb24oKSkpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEV4dGVuc2lvbigneGRlYnVnJywgJHByZXR0eVZlcnNpb24pOwogICAgICAgIH0KCiAgICAgICAgLy8gQW5vdGhlciBxdWljayBsb29wLCBqdXN0IGZvciBwb3NzaWJsZSBsaWJyYXJpZXMKICAgICAgICAvLyBEb2luZyBpdCB0aGlzIHdheSB0byBrbm93IHRoYXQgZnVuY3Rpb25zIG9yIGNvbnN0YW50cyBleGlzdCBiZWZvcmUKICAgICAgICAvLyByZWx5aW5nIG9uIHRoZW0uCiAgICAgICAgZm9yZWFjaCAoJGxvYWRlZEV4dGVuc2lvbnMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgc3dpdGNoICgkbmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSAnYW1xcCc6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIGxpYnJhYmJpdG1xIHZlcnNpb24gPT4gMC45LjAKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15saWJyYWJiaXRtcSB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbGlicmFiYml0bXFNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYnJhYmJpdG1xJywgJGxpYnJhYmJpdG1xTWF0Y2hlc1sndmVyc2lvbiddLCAnQU1RUCBsaWJyYWJiaXRtcSB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBBTVFQIHByb3RvY29sIHZlcnNpb24gPT4gMC05LTEKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15BTVFQIHByb3RvY29sIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRwcm90b2NvbE1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictcHJvdG9jb2wnLCBzdHJfcmVwbGFjZSgnLScsICcuJywgJHByb3RvY29sTWF0Y2hlc1sndmVyc2lvbiddKSwgJ0FNUVAgcHJvdG9jb2wgdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdiejInOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBCWmlwMiBWZXJzaW9uID0+IDEuMC42LCA2LVNlcHQtMjAxMAogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXkJaaXAyIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKiksL2ltJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZSwgJG1hdGNoZXNbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2N1cmwnOgogICAgICAgICAgICAgICAgICAgICRjdXJsVmVyc2lvbiA9ICR0aGlzLT5ydW50aW1lLT5pbnZva2UoJ2N1cmxfdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCAkY3VybFZlcnNpb25bJ3ZlcnNpb24nXSk7CgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBTU0wgVmVyc2lvbiA9PiBPcGVuU1NMLzEuMC4xdAogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XlNTTCBWZXJzaW9uID0+ICg/PGxpYnJhcnk+W14vXSspLyg/PHZlcnNpb24+LispJH1pbScsICRpbmZvLCAkc3NsTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpYnJhcnkgPSBzdHJ0b2xvd2VyKCRzc2xNYXRjaGVzWydsaWJyYXJ5J10pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpYnJhcnkgPT09ICdvcGVuc3NsJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnNlZFZlcnNpb24gPSBWZXJzaW9uOjpwYXJzZU9wZW5zc2woJHNzbE1hdGNoZXNbJ3ZlcnNpb24nXSwgJGlzRmlwcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLW9wZW5zc2wnLigkaXNGaXBzID8gJy1maXBzJyA6ICcnKSwgJHBhcnNlZFZlcnNpb24sICdjdXJsIE9wZW5TU0wgdmVyc2lvbiAoJy4kcGFyc2VkVmVyc2lvbi4nKScsIGFycmF5KCksICRpc0ZpcHMgPyBhcnJheSgnY3VybC1vcGVuc3NsJykgOiBhcnJheSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictJy4kbGlicmFyeSwgJHNzbE1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2N1cmwgJy4kbGlicmFyeS4nIHZlcnNpb24gKCcuJHNzbE1hdGNoZXNbJ3ZlcnNpb24nXS4nKScsIGFycmF5KCdjdXJsLW9wZW5zc2wnKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGxpYlNTSCBWZXJzaW9uID0+IGxpYnNzaDIvMS40LjMKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15saWJTU0ggVmVyc2lvbiA9PiAoPzxsaWJyYXJ5PlteL10rKS8oPzx2ZXJzaW9uPi4rPykoPzovLiopPyR9aW0nLCAkaW5mbywgJHNzaE1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictJy5zdHJ0b2xvd2VyKCRzc2hNYXRjaGVzWydsaWJyYXJ5J10pLCAkc3NoTWF0Y2hlc1sndmVyc2lvbiddLCAnY3VybCAnLiRzc2hNYXRjaGVzWydsaWJyYXJ5J10uJyB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBaTGliIFZlcnNpb24gPT4gMS4yLjgKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15aTGliIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkfWltJywgJGluZm8sICR6bGliTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy16bGliJywgJHpsaWJNYXRjaGVzWyd2ZXJzaW9uJ10sICdjdXJsIHpsaWIgdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdkYXRlJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gdGltZWxpYiB2ZXJzaW9uID0+IDIwMTguMDMKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL150aW1lbGliIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICR0aW1lbGliTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy10aW1lbGliJywgJHRpbWVsaWJNYXRjaGVzWyd2ZXJzaW9uJ10sICdkYXRlIHRpbWVsaWIgdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVGltZXpvbmUgRGF0YWJhc2UgPT4gaW50ZXJuYWwKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15UaW1lem9uZSBEYXRhYmFzZSA9PiAoPzxzb3VyY2U+aW50ZXJuYWx8ZXh0ZXJuYWwpJC9pbScsICRpbmZvLCAkem9uZWluZm9Tb3VyY2VNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXh0ZXJuYWwgPSAkem9uZWluZm9Tb3VyY2VNYXRjaGVzWydzb3VyY2UnXSA9PT0gJ2V4dGVybmFsJzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eIk9sc29uIiBUaW1lem9uZSBEYXRhYmFzZSBWZXJzaW9uID0+ICg/PHZlcnNpb24+Lis/KShcLnN5c3RlbSk/JC9pbScsICRpbmZvLCAkem9uZWluZm9NYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHRpbWV6b25lZGIgaXMgcHJvdmlkZWQgYnkgZXh0L3RpbWV6b25lZGIsIHJlZ2lzdGVyIHRoYXQgdmVyc2lvbiBhcyBhIHJlcGxhY2VtZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGV4dGVybmFsICYmIGluX2FycmF5KCd0aW1lem9uZWRiJywgJGxvYWRlZEV4dGVuc2lvbnMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ3RpbWV6b25lZGItem9uZWluZm8nLCAkem9uZWluZm9NYXRjaGVzWyd2ZXJzaW9uJ10sICd6b25laW5mbyAoIk9sc29uIikgZGF0YWJhc2UgZm9yIGRhdGUgKHJlcGxhY2VkIGJ5IHRpbWV6b25lZGIpJywgYXJyYXkoJG5hbWUuJy16b25laW5mbycpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy16b25laW5mbycsICR6b25laW5mb01hdGNoZXNbJ3ZlcnNpb24nXSwgJ3pvbmVpbmZvICgiT2xzb24iKSBkYXRhYmFzZSBmb3IgZGF0ZScpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbGVpbmZvJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbGlibWFnaWMgPT4gNTM3CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9ebGlibWFnaWMgPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRtYWdpY01hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGlibWFnaWMnLCAkbWFnaWNNYXRjaGVzWyd2ZXJzaW9uJ10sICdmaWxlaW5mbyBsaWJtYWdpYyB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2dkJzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZSwgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdHRF9WRVJTSU9OJykpOwoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9ebGliSlBFRyBWZXJzaW9uID0+ICg/PHZlcnNpb24+Lis/KSg/OiBjb21wYXRpYmxlKT8kL2ltJywgJGluZm8sICRsaWJqcGVnTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJqcGVnJywgVmVyc2lvbjo6cGFyc2VMaWJqcGVnKCRsaWJqcGVnTWF0Y2hlc1sndmVyc2lvbiddKSwgJ2xpYmpwZWcgdmVyc2lvbiBmb3IgZ2QnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXmxpYlBORyBWZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbGlicG5nTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJwbmcnLCAkbGlicG5nTWF0Y2hlc1sndmVyc2lvbiddLCAnbGlicG5nIHZlcnNpb24gZm9yIGdkJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15GcmVlVHlwZSBWZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkZnJlZXR5cGVNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWZyZWV0eXBlJywgJGZyZWV0eXBlTWF0Y2hlc1sndmVyc2lvbiddLCAnZnJlZXR5cGUgdmVyc2lvbiBmb3IgZ2QnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXmxpYlhwbSBWZXJzaW9uID0+ICg/PHZlcnNpb25JZD5cZCspJC9pbScsICRpbmZvLCAkbGlieHBtTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJ4cG0nLCBWZXJzaW9uOjpjb252ZXJ0TGlieHBtVmVyc2lvbklkKCRsaWJ4cG1NYXRjaGVzWyd2ZXJzaW9uSWQnXSksICdsaWJ4cG0gdmVyc2lvbiBmb3IgZ2QnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2dtcCc6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnR01QX1ZFUlNJT04nKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnaWNvbnYnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ0lDT05WX1ZFUlNJT04nKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnaW50bCc6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9ICdUaGUgSUNVIHVuaWNvZGUgYW5kIGdsb2JhbGl6YXRpb24gc3VwcG9ydCBsaWJyYXJ5JzsKICAgICAgICAgICAgICAgICAgICAvLyBUcnV0aHkgY2hlY2sgaXMgZm9yIHRlc3Rpbmcgb25seSBzbyB3ZSBjYW4gbWFrZSB0aGUgY29uZGl0aW9uIGZhaWwKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJ1bnRpbWUtPmhhc0NvbnN0YW50KCdJTlRMX0lDVV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2ljdScsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnSU5UTF9JQ1VfVkVSU0lPTicpLCAkZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvXklDVSB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2ljdScsICRtYXRjaGVzWyd2ZXJzaW9uJ10sICRkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBJQ1UgVFpEYXRhIHZlcnNpb24gPT4gMjAxOWMKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15JQ1UgVFpEYXRhIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKikkL2ltJywgJGluZm8sICR6b25laW5mb01hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCdpY3Utem9uZWluZm8nLCBWZXJzaW9uOjpwYXJzZVpvbmVpbmZvVmVyc2lvbigkem9uZWluZm9NYXRjaGVzWyd2ZXJzaW9uJ10pLCAnem9uZWluZm8gKCJPbHNvbiIpIGRhdGFiYXNlIGZvciBpY3UnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEFkZCBhIHNlcGFyYXRlIHZlcnNpb24gZm9yIHRoZSBDTERSIGxpYnJhcnkgdmVyc2lvbgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ2xhc3MoJ1Jlc291cmNlQnVuZGxlJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNsZHJWZXJzaW9uID0gJHRoaXMtPnJ1bnRpbWUtPmludm9rZShhcnJheSgnUmVzb3VyY2VCdW5kbGUnLCAnY3JlYXRlJyksIGFycmF5KCdyb290JywgJ0lDVURBVEEnLCBmYWxzZSkpLT5nZXQoJ1ZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJ2ljdS1jbGRyJywgJGNsZHJWZXJzaW9uLCAnSUNVIENMRFIgcHJvamVjdCB2ZXJzaW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnJ1bnRpbWUtPmhhc0NsYXNzKCdJbnRsQ2hhcicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCdpY3UtdW5pY29kZScsIGltcGxvZGUoJy4nLCBhcnJheV9zbGljZSgkdGhpcy0+cnVudGltZS0+aW52b2tlKGFycmF5KCdJbnRsQ2hhcicsICdnZXRVbmljb2RlVmVyc2lvbicpKSwgMCwgMykpLCAnSUNVIHVuaWNvZGUgdmVyc2lvbicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdpbWFnaWNrJzoKICAgICAgICAgICAgICAgICAgICAkaW1hZ2VNYWdpY2tWZXJzaW9uID0gJHRoaXMtPnJ1bnRpbWUtPmNvbnN0cnVjdCgnSW1hZ2ljaycpLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgLy8gNi54OiBJbWFnZU1hZ2ljayA2LjIuOSAwOC8yNC8wNiBRMTYgaHR0cDovL3d3dy5pbWFnZW1hZ2ljay5vcmcKICAgICAgICAgICAgICAgICAgICAvLyA3Lng6IEltYWdlTWFnaWNrIDcuMC44LTM0IFExNiB4ODZfNjQgMjAxOS0wMy0yMyBodHRwczovL2ltYWdlbWFnaWNrLm9yZwogICAgICAgICAgICAgICAgICAgIHByZWdfbWF0Y2goJy9eSW1hZ2VNYWdpY2sgKD88dmVyc2lvbj5bXGQuXSspKD86LSg/PHBhdGNoPlxkKykpPy8nLCAkaW1hZ2VNYWdpY2tWZXJzaW9uWyd2ZXJzaW9uU3RyaW5nJ10sICRtYXRjaGVzKTsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICRtYXRjaGVzWyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWydwYXRjaCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSAnLicuJG1hdGNoZXNbJ3BhdGNoJ107CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWltYWdlbWFnaWNrJywgJHZlcnNpb24sIG51bGwsIGFycmF5KCdpbWFnaWNrJykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2xkYXAnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15WZW5kb3IgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uSWQ+XGQrKSQvaW0nLCAkaW5mbywgJG1hdGNoZXMpICYmIHByZWdfbWF0Y2goJy9eVmVuZG9yIE5hbWUgPT4gKD88dmVuZG9yPi4rKSQvaW0nLCAkaW5mbywgJHZlbmRvck1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictJy5zdHJ0b2xvd2VyKCR2ZW5kb3JNYXRjaGVzWyd2ZW5kb3InXSksIFZlcnNpb246OmNvbnZlcnRPcGVubGRhcFZlcnNpb25JZCgkbWF0Y2hlc1sndmVyc2lvbklkJ10pLCAkdmVuZG9yTWF0Y2hlc1sndmVuZG9yJ10uJyB2ZXJzaW9uIG9mIGxkYXAnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbGlieG1sJzoKICAgICAgICAgICAgICAgICAgICAvLyBleHQvZG9tLCBleHQvc2ltcGxleG1sLCBleHQveG1scmVhZGVyIGFuZCBleHQveG1sd3JpdGVyIHVzZSB0aGUgc2FtZSBsaWJ4bWwgYXMgdGhlIGV4dC9saWJ4bWwKICAgICAgICAgICAgICAgICAgICAkbGlieG1sUHJvdmlkZXMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRleHRlbnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRleHRlbnNpb24gLiAnLWxpYnhtbCc7CiAgICAgICAgICAgICAgICAgICAgfSwgYXJyYXlfaW50ZXJzZWN0KCRsb2FkZWRFeHRlbnNpb25zLCBhcnJheSgnZG9tJywgJ3NpbXBsZXhtbCcsICd4bWwnLCAneG1scmVhZGVyJywgJ3htbHdyaXRlcicpKSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnTElCWE1MX0RPVFRFRF9WRVJTSU9OJyksICdsaWJ4bWwgbGlicmFyeSB2ZXJzaW9uJywgYXJyYXkoKSwgJGxpYnhtbFByb3ZpZGVzKTsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbWJzdHJpbmcnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBsaWJtYmZsIHZlcnNpb24gPT4gMS4zLjIKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15saWJtYmZsIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRsaWJtYmZsTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJtYmZsJywgJGxpYm1iZmxNYXRjaGVzWyd2ZXJzaW9uJ10sICdtYnN0cmluZyBsaWJtYmZsIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ01CX09OSUdVUlVNQV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1vbmlndXJ1bWEnLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ01CX09OSUdVUlVNQV9WRVJTSU9OJyksICdtYnN0cmluZyBvbmlndXJ1bWEgdmVyc2lvbicpOwoKICAgICAgICAgICAgICAgICAgICAvLyBNdWx0aWJ5dGUgcmVnZXggKG9uaWd1cnVtYSkgdmVyc2lvbiA9PiA1LjkuNQogICAgICAgICAgICAgICAgICAgIC8vIG9uaWd1cnVtYSB2ZXJzaW9uID0+IDYuOS4wCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJy9eKD86b25pZ3VydW1hfE11bHRpYnl0ZSByZWdleCBcKG9uaWd1cnVtYVwpKSB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkb25pZ3VydW1hTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1vbmlndXJ1bWEnLCAkb25pZ3VydW1hTWF0Y2hlc1sndmVyc2lvbiddLCAnbWJzdHJpbmcgb25pZ3VydW1hIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21lbWNhY2hlZCc6CiAgICAgICAgICAgICAgICAgICAgJGluZm8gPSAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIGxpYm1lbWNhY2hlZCB2ZXJzaW9uID0+IDEuMC4xOAogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXmxpYm1lbWNhY2hlZCB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJtZW1jYWNoZWQnLCAkbWF0Y2hlc1sndmVyc2lvbiddLCAnbGlibWVtY2FjaGVkIHZlcnNpb24nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnb3BlbnNzbCc6CiAgICAgICAgICAgICAgICAgICAgLy8gT3BlblNTTCAxLjEuMWcgIDIxIEFwciAyMDIwCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86T3BlblNTTHxMaWJyZVNTTCk/XHMqKD88dmVyc2lvbj5cUyspfWknLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ09QRU5TU0xfVkVSU0lPTl9URVhUJyksICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFyc2VkVmVyc2lvbiA9IFZlcnNpb246OnBhcnNlT3BlbnNzbCgkbWF0Y2hlc1sndmVyc2lvbiddLCAkaXNGaXBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuKCRpc0ZpcHMgPyAnLWZpcHMnIDogJycpLCAkcGFyc2VkVmVyc2lvbiwgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdPUEVOU1NMX1ZFUlNJT05fVEVYVCcpLCBhcnJheSgpLCAkaXNGaXBzID8gYXJyYXkoJG5hbWUpIDogYXJyYXkoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3BjcmUnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCBwcmVnX3JlcGxhY2UoJ3teKFxTKykuKn0nLCAnJDEnLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1BDUkVfVkVSU0lPTicpKSk7CgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBQQ1JFIFVuaWNvZGUgVmVyc2lvbiA9PiAxMi4xLjAKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15QQ1JFIFVuaWNvZGUgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJHBjcmVVbmljb2RlTWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy11bmljb2RlJywgJHBjcmVVbmljb2RlTWF0Y2hlc1sndmVyc2lvbiddLCAnUENSRSBVbmljb2RlIHZlcnNpb24gc3VwcG9ydCcpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWxuZCc6CiAgICAgICAgICAgICAgICBjYXNlICdwZG9fbXlzcWwnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oPzpDbGllbnQgQVBJIHZlcnNpb258VmVyc2lvbikgPT4gbXlzcWxuZCAoPzx2ZXJzaW9uPi4rPykgL21pJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLW15c3FsbmQnLCAkbWF0Y2hlc1sndmVyc2lvbiddLCAnbXlzcWxuZCBsaWJyYXJ5IHZlcnNpb24gZm9yICcuJG5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtb25nb2RiJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9ebGlibW9uZ29jIGJ1bmRsZWQgdmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJGxpYm1vbmdvY01hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGlibW9uZ29jJywgJGxpYm1vbmdvY01hdGNoZXNbJ3ZlcnNpb24nXSwgJ2xpYm1vbmdvYyB2ZXJzaW9uIG9mIG1vbmdvZGInKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXmxpYmJzb24gYnVuZGxlZCB2ZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbGliYnNvbk1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGliYnNvbicsICRsaWJic29uTWF0Y2hlc1sndmVyc2lvbiddLCAnbGliYnNvbiB2ZXJzaW9uIG9mIG1vbmdvZGInKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgY2FzZSAncGRvX3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCRuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eUG9zdGdyZVNRTFwobGlicHFcKSBWZXJzaW9uID0+ICg/PHZlcnNpb24+LiopJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJwcScsICRtYXRjaGVzWyd2ZXJzaW9uJ10sICdsaWJwcSBmb3IgJy4kbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2xpYnNvZGl1bSc6CiAgICAgICAgICAgICAgICBjYXNlICdzb2RpdW0nOgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ1NPRElVTV9MSUJSQVJZX1ZFUlNJT04nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnbGlic29kaXVtJywgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdTT0RJVU1fTElCUkFSWV9WRVJTSU9OJykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdzcWxpdGUzJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3Bkb19zcWxpdGUnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15TUUxpdGUgTGlicmFyeSA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictc3FsaXRlJywgJG1hdGNoZXNbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3NzaDInOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15saWJzc2gyIHZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZS4nLWxpYnNzaDInLCAkbWF0Y2hlc1sndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAneHNsJzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnbGlieHNsdCcsICR0aGlzLT5ydW50aW1lLT5nZXRDb25zdGFudCgnTElCWFNMVF9ET1RURURfVkVSU0lPTicpLCBudWxsLCBhcnJheSgneHNsJykpOwoKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5ydW50aW1lLT5nZXRFeHRlbnNpb25JbmZvKCd4c2wnKTsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15saWJ4c2x0IGNvbXBpbGVkIGFnYWluc3QgbGlieG1sIFZlcnNpb24gPT4gKD88dmVyc2lvbj4uKykkL2ltJywgJGluZm8sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgnbGlieHNsdC1saWJ4bWwnLCAkbWF0Y2hlc1sndmVyc2lvbiddLCAnbGlieG1sIHZlcnNpb24gbGlieHNsdCBpcyBjb21waWxlZCBhZ2FpbnN0Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3lhbWwnOgogICAgICAgICAgICAgICAgICAgICRpbmZvID0gJHRoaXMtPnJ1bnRpbWUtPmdldEV4dGVuc2lvbkluZm8oJ3lhbWwnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eTGliWUFNTCBWZXJzaW9uID0+ICg/PHZlcnNpb24+LispJC9pbScsICRpbmZvLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpYnJhcnkoJG5hbWUuJy1saWJ5YW1sJywgJG1hdGNoZXNbJ3ZlcnNpb24nXSwgJ2xpYnlhbWwgdmVyc2lvbiBvZiB5YW1sJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3ppcCc6CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ydW50aW1lLT5oYXNDb25zdGFudCgnTElCWklQX1ZFUlNJT04nLCAnWmlwQXJjaGl2ZScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLictbGliemlwJywgJHRoaXMtPnJ1bnRpbWUtPmdldENvbnN0YW50KCdMSUJaSVBfVkVSU0lPTicsICdaaXBBcmNoaXZlJyksIG51bGwsIGFycmF5KCd6aXAnKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3psaWInOgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cnVudGltZS0+aGFzQ29uc3RhbnQoJ1pMSUJfVkVSU0lPTicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaWJyYXJ5KCRuYW1lLCAkdGhpcy0+cnVudGltZS0+Z2V0Q29uc3RhbnQoJ1pMSUJfVkVSU0lPTicpKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gTGlua2VkIFZlcnNpb24gPT4gMS4yLjgKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgnL15MaW5rZWQgVmVyc2lvbiA9PiAoPzx2ZXJzaW9uPi4rKSQvaW0nLCAkdGhpcy0+cnVudGltZS0+Z2V0RXh0ZW5zaW9uSW5mbygkbmFtZSksICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlicmFyeSgkbmFtZSwgJG1hdGNoZXNbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRoaHZtVmVyc2lvbiA9ICR0aGlzLT5oaHZtRGV0ZWN0b3ItPmdldFZlcnNpb24oKTsKICAgICAgICBpZiAoJGhodm1WZXJzaW9uKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRoaHZtVmVyc2lvbjsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gcHJlZ19yZXBsYWNlKCcjXihbXn4rLV0rKS4qJCMnLCAnJDEnLCAkaGh2bVZlcnNpb24pOwogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGhodm0gPSBuZXcgQ29tcGxldGVQYWNrYWdlKCdoaHZtJywgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgJGhodm0tPnNldERlc2NyaXB0aW9uKCdUaGUgSEhWTSBSdW50aW1lICg2NGJpdCknKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJGhodm0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAvLyBTa2lwIGlmIG92ZXJyaWRkZW4KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm92ZXJyaWRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgJG92ZXJyaWRlciA9ICR0aGlzLT5maW5kUGFja2FnZSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAnKicpOwogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFZlcnNpb24oKSA9PT0gJG92ZXJyaWRlci0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdzYW1lIGFzIGFjdHVhbCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdhY3R1YWw6ICcuJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3ZlcnJpZGVyLT5zZXREZXNjcmlwdGlvbigkb3ZlcnJpZGVyLT5nZXREZXNjcmlwdGlvbigpLicsICcuJGFjdHVhbFRleHQpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU2tpcCBpZiBQSFAgaXMgb3ZlcnJpZGRlbiBhbmQgd2UgYXJlIGFkZGluZyBhIHBocC0qIHBhY2thZ2UKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm92ZXJyaWRlc1sncGhwJ10pICYmIDAgPT09IHN0cnBvcygkcGFja2FnZS0+Z2V0TmFtZSgpLCAncGhwLScpKSB7CiAgICAgICAgICAgICRvdmVycmlkZXIgPSAkdGhpcy0+YWRkT3ZlcnJpZGRlblBhY2thZ2UoJHRoaXMtPm92ZXJyaWRlc1sncGhwJ10sICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkpOwogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFZlcnNpb24oKSA9PT0gJG92ZXJyaWRlci0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdzYW1lIGFzIGFjdHVhbCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkYWN0dWFsVGV4dCA9ICdhY3R1YWw6ICcuJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3ZlcnJpZGVyLT5zZXREZXNjcmlwdGlvbigkb3ZlcnJpZGVyLT5nZXREZXNjcmlwdGlvbigpLicsICcuJGFjdHVhbFRleHQpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjphZGRQYWNrYWdlKCRwYWNrYWdlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFkZE92ZXJyaWRkZW5QYWNrYWdlKGFycmF5ICRvdmVycmlkZSwgJG5hbWUgPSBudWxsKQogICAgewogICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkb3ZlcnJpZGVbJ3ZlcnNpb24nXSk7CiAgICAgICAgJHBhY2thZ2UgPSBuZXcgQ29tcGxldGVQYWNrYWdlKCRuYW1lID86ICRvdmVycmlkZVsnbmFtZSddLCAkdmVyc2lvbiwgJG92ZXJyaWRlWyd2ZXJzaW9uJ10pOwogICAgICAgICRwYWNrYWdlLT5zZXREZXNjcmlwdGlvbignUGFja2FnZSBvdmVycmlkZGVuIHZpYSBjb25maWcucGxhdGZvcm0nKTsKICAgICAgICAkcGFja2FnZS0+c2V0RXh0cmEoYXJyYXkoJ2NvbmZpZy5wbGF0Zm9ybScgPT4gdHJ1ZSkpOwogICAgICAgIHBhcmVudDo6YWRkUGFja2FnZSgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgdmVyc2lvbiBhbmQgYWRkcyBhIG5ldyBwYWNrYWdlIHRvIHRoZSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRuYW1lCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHByZXR0eVZlcnNpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRFeHRlbnNpb24oJG5hbWUsICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgICRleHRyYURlc2NyaXB0aW9uID0gbnVsbDsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRleHRyYURlc2NyaXB0aW9uID0gJyAoYWN0dWFsIHZlcnNpb246ICcuJHByZXR0eVZlcnNpb24uJyknOwogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oXGQrXC5cZCtcLlxkKyg/OlwuXGQrKT8pfScsICRwcmV0dHlWZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJzAnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZU5hbWUgPSAkdGhpcy0+YnVpbGRQYWNrYWdlTmFtZSgkbmFtZSk7CiAgICAgICAgJGV4dCA9IG5ldyBDb21wbGV0ZVBhY2thZ2UoJHBhY2thZ2VOYW1lLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICRleHQtPnNldERlc2NyaXB0aW9uKCdUaGUgJy4kbmFtZS4nIFBIUCBleHRlbnNpb24nLiRleHRyYURlc2NyaXB0aW9uKTsKCiAgICAgICAgaWYgKCRuYW1lID09PSAndXVpZCcpIHsKICAgICAgICAgICAgJGV4dC0+c2V0UmVwbGFjZXMoYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgTGluaygnZXh0LXV1aWQnLCAnbGliLXV1aWQnLCBuZXcgQ29uc3RyYWludCgnPScsICR2ZXJzaW9uKSwgTGluazo6VFlQRV9SRVBMQUNFLCAkZXh0LT5nZXRQcmV0dHlWZXJzaW9uKCkpLAogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYnVpbGRQYWNrYWdlTmFtZSgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJ2V4dC0nIC4gc3RyX3JlcGxhY2UoJyAnLCAnLScsIHN0cnRvbG93ZXIoJG5hbWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRwcmV0dHlWZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGRlc2NyaXB0aW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJHJlcGxhY2VzCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICAgJHByb3ZpZGVzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkTGlicmFyeSgkbmFtZSwgJHByZXR0eVZlcnNpb24sICRkZXNjcmlwdGlvbiA9IG51bGwsIGFycmF5ICRyZXBsYWNlcyA9IGFycmF5KCksIGFycmF5ICRwcm92aWRlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRwcmV0dHlWZXJzaW9uKTsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVzY3JpcHRpb24gPT09IG51bGwpIHsKICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJ1RoZSAnLiRuYW1lLicgbGlicmFyeSc7CiAgICAgICAgfQoKICAgICAgICAkbGliID0gbmV3IENvbXBsZXRlUGFja2FnZSgnbGliLScuJG5hbWUsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgJGxpYi0+c2V0RGVzY3JpcHRpb24oJGRlc2NyaXB0aW9uKTsKCiAgICAgICAgJGxpbmtzID0gZnVuY3Rpb24gKCRhbGlhcykgdXNlICgkbmFtZSwgJHZlcnNpb24sICRsaWIpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBMaW5rKCdsaWItJy4kbmFtZSwgJ2xpYi0nLiRhbGlhcywgbmV3IENvbnN0cmFpbnQoJz0nLCAkdmVyc2lvbiksIExpbms6OlRZUEVfUkVQTEFDRSwgJGxpYi0+Z2V0UHJldHR5VmVyc2lvbigpKTsKICAgICAgICB9OwogICAgICAgICRsaWItPnNldFJlcGxhY2VzKGFycmF5X21hcCgkbGlua3MsICRyZXBsYWNlcykpOwogICAgICAgICRsaWItPnNldFByb3ZpZGVzKGFycmF5X21hcCgkbGlua3MsICRwcm92aWRlcykpOwoKICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkbGliKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIGEgcGFja2FnZSBuYW1lIGlzIGEgcGxhdGZvcm0gcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNQbGF0Zm9ybVBhY2thZ2UoJG5hbWUpCiAgICB7CiAgICAgICAgc3RhdGljICRjYWNoZSA9IGFycmF5KCk7CgogICAgICAgIGlmIChpc3NldCgkY2FjaGVbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gJGNhY2hlWyRuYW1lXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2FjaGVbJG5hbWVdID0gKGJvb2wpIHByZWdfbWF0Y2goUGxhdGZvcm1SZXBvc2l0b3J5OjpQTEFURk9STV9QQUNLQUdFX1JFR0VYLCAkbmFtZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcQ2FjaGU7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcR2l0SHViOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdEh1YkRyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICBwcm90ZWN0ZWQgJG93bmVyOwogICAgcHJvdGVjdGVkICRyZXBvc2l0b3J5OwogICAgcHJvdGVjdGVkICR0YWdzOwogICAgcHJvdGVjdGVkICRicmFuY2hlczsKICAgIHByb3RlY3RlZCAkcm9vdElkZW50aWZpZXI7CiAgICBwcm90ZWN0ZWQgJHJlcG9EYXRhOwogICAgcHJvdGVjdGVkICRoYXNJc3N1ZXM7CiAgICBwcm90ZWN0ZWQgJGlzUHJpdmF0ZSA9IGZhbHNlOwogICAgcHJpdmF0ZSAkaXNBcmNoaXZlZCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkZnVuZGluZ0luZm87CgogICAgLyoqCiAgICAgKiBHaXQgRHJpdmVyCiAgICAgKgogICAgICogQHZhciBHaXREcml2ZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRnaXREcml2ZXI7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBwcmVnX21hdGNoKCcjXig/Oig/Omh0dHBzP3xnaXQpOi8vKFteL10rKS98Z2l0QChbXjpdKyk6Lz8pKFteL10rKS8oLis/KSg/OlwuZ2l0fC8pPyQjJywgJHRoaXMtPnVybCwgJG1hdGNoKTsKICAgICAgICAkdGhpcy0+b3duZXIgPSAkbWF0Y2hbM107CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnkgPSAkbWF0Y2hbNF07CiAgICAgICAgJHRoaXMtPm9yaWdpblVybCA9IHN0cnRvbG93ZXIoIWVtcHR5KCRtYXRjaFsxXSkgPyAkbWF0Y2hbMV0gOiAkbWF0Y2hbMl0pOwogICAgICAgIGlmICgkdGhpcy0+b3JpZ2luVXJsID09PSAnd3d3LmdpdGh1Yi5jb20nKSB7CiAgICAgICAgICAgICR0aGlzLT5vcmlnaW5VcmwgPSAnZ2l0aHViLmNvbSc7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jYWNoZSA9IG5ldyBDYWNoZSgkdGhpcy0+aW8sICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKS4nLycuJHRoaXMtPm9yaWdpblVybC4nLycuJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeSk7CiAgICAgICAgJHRoaXMtPmNhY2hlLT5zZXRSZWFkT25seSgkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlYWQtb25seScpKTsKCiAgICAgICAgaWYgKCR0aGlzLT5jb25maWctPmdldCgndXNlLWdpdGh1Yi1hcGknKSA9PT0gZmFsc2UgfHwgKGlzc2V0KCR0aGlzLT5yZXBvQ29uZmlnWyduby1hcGknXSkgJiYgJHRoaXMtPnJlcG9Db25maWdbJ25vLWFwaSddKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0dXBHaXREcml2ZXIoJHRoaXMtPnVybCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZmV0Y2hSb290SWRlbnRpZmllcigpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3J5VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2h0dHBzOi8vJy4kdGhpcy0+b3JpZ2luVXJsLicvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290SWRlbnRpZmllcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldFVybCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdodHRwczovLycgLiAkdGhpcy0+b3JpZ2luVXJsIC4gJy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0QXBpVXJsKCkKICAgIHsKICAgICAgICBpZiAoJ2dpdGh1Yi5jb20nID09PSAkdGhpcy0+b3JpZ2luVXJsKSB7CiAgICAgICAgICAgICRhcGlVcmwgPSAnYXBpLmdpdGh1Yi5jb20nOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRhcGlVcmwgPSAkdGhpcy0+b3JpZ2luVXJsIC4gJy9hcGkvdjMnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdodHRwczovLycgLiAkYXBpVXJsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRTb3VyY2UoJGlkZW50aWZpZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPmlzUHJpdmF0ZSkgewogICAgICAgICAgICAvLyBQcml2YXRlIEdpdEh1YiByZXBvc2l0b3JpZXMgc2hvdWxkIGJlIGFjY2Vzc2VkIHVzaW5nIHRoZQogICAgICAgICAgICAvLyBTU0ggdmVyc2lvbiBvZiB0aGUgVVJMLgogICAgICAgICAgICAkdXJsID0gJHRoaXMtPmdlbmVyYXRlU3NoVXJsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHVybCA9ICR0aGlzLT5nZXRVcmwoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ2dpdCcsICd1cmwnID0+ICR1cmwsICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHVybCA9ICR0aGlzLT5nZXRBcGlVcmwoKSAuICcvcmVwb3MvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5LicvemlwYmFsbC8nLiRpZGVudGlmaWVyOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICd6aXAnLCAndXJsJyA9PiAkdXJsLCAncmVmZXJlbmNlJyA9PiAkaWRlbnRpZmllciwgJ3NoYXN1bScgPT4gJycpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSAmJiAkcmVzID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRCYXNlQ29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRpZGVudGlmaWVyLCBqc29uX2VuY29kZSgkY29tcG9zZXIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAgICAgLy8gc3BlY2lhbHMgZm9yIGdpdGh1YgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ3N1cHBvcnQnXVsnc291cmNlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGxhYmVsID0gYXJyYXlfc2VhcmNoKCRpZGVudGlmaWVyLCAkdGhpcy0+Z2V0VGFncygpKSA/OiBhcnJheV9zZWFyY2goJGlkZW50aWZpZXIsICR0aGlzLT5nZXRCcmFuY2hlcygpKSA/OiAkaWRlbnRpZmllcjsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnc291cmNlJ10gPSBzcHJpbnRmKCdodHRwczovLyVzLyVzLyVzL3RyZWUvJXMnLCAkdGhpcy0+b3JpZ2luVXJsLCAkdGhpcy0+b3duZXIsICR0aGlzLT5yZXBvc2l0b3J5LCAkbGFiZWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ3N1cHBvcnQnXVsnaXNzdWVzJ10pICYmICR0aGlzLT5oYXNJc3N1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnaXNzdWVzJ10gPSBzcHJpbnRmKCdodHRwczovLyVzLyVzLyVzL2lzc3VlcycsICR0aGlzLT5vcmlnaW5VcmwsICR0aGlzLT5vd25lciwgJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2FiYW5kb25lZCddKSAmJiAkdGhpcy0+aXNBcmNoaXZlZCkgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclsnYWJhbmRvbmVkJ10gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2Z1bmRpbmcnXSkgJiYgJGZ1bmRpbmcgPSAkdGhpcy0+Z2V0RnVuZGluZ0luZm8oKSkgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclsnZnVuZGluZyddID0gJGZ1bmRpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gJGNvbXBvc2VyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RnVuZGluZ0luZm8oKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+ZnVuZGluZ0luZm8pIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mdW5kaW5nSW5mbzsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+b3JpZ2luVXJsICE9PSAnZ2l0aHViLmNvbScpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mdW5kaW5nSW5mbyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy9jb250ZW50cy8uZ2l0aHViL0ZVTkRJTkcueW1sJywgJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLy5naXRodWIvY29udGVudHMvRlVORElORy55bWwnKSBhcyAkZmlsZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJGZpbGUsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlLAogICAgICAgICAgICAgICAgKSktPmRlY29kZUpzb24oKTsKICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZW1wdHkoJHJlc3BvbnNlWydjb250ZW50J10pIHx8ICRyZXNwb25zZVsnZW5jb2RpbmcnXSAhPT0gJ2Jhc2U2NCcgfHwgISgkZnVuZGluZyA9IGJhc2U2NF9kZWNvZGUoJHJlc3BvbnNlWydjb250ZW50J10pKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChlbXB0eSgkZnVuZGluZykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mdW5kaW5nSW5mbyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgJGtleSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAocHJlZ19zcGxpdCgne1xyP1xufScsICRmdW5kaW5nKSBhcyAkbGluZSkgewogICAgICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oXHcrKVxzKjpccyooLispJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teXFsoLiopXF0oPzpccyojLiopPyR9JywgJG1hdGNoWzJdLCAkbWF0Y2gyKSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21hcCgndHJpbScsIHByZWdfc3BsaXQoJ3tbXCciXT9ccyosXHMqW1wnIl0/fScsICRtYXRjaDJbMV0pKSBhcyAkaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgndHlwZScgPT4gJG1hdGNoWzFdLCAndXJsJyA9PiB0cmltKCRpdGVtLCAnIlwnICcpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgne14oW14jXS4qPykoXHMrIy4qKT8kfScsICRtYXRjaFsyXSwgJG1hdGNoMikpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgndHlwZScgPT4gJG1hdGNoWzFdLCAndXJsJyA9PiB0cmltKCRtYXRjaDJbMV0sICciXCcgJykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGtleSA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCd7XihcdyspXHMqOlxzKiNccyokfScsICRsaW5lLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAka2V5ID0gJG1hdGNoWzFdOwogICAgICAgICAgICB9IGVsc2VpZiAoJGtleSAmJiBwcmVnX21hdGNoKCd7Xi1ccyooLispKFxzKyMuKik/JH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoJ3R5cGUnID0+ICRrZXksICd1cmwnID0+IHRyaW0oJG1hdGNoWzFdLCAnIlwnICcpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdCBhcyAka2V5ID0+ICRpdGVtKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJGl0ZW1bJ3R5cGUnXSkgewogICAgICAgICAgICAgICAgY2FzZSAndGlkZWxpZnQnOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vdGlkZWxpZnQuY29tL2Z1bmRpbmcvZ2l0aHViLycgLiAkaXRlbVsndXJsJ107CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdnaXRodWInOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3BhdHJlb24nOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vd3d3LnBhdHJlb24uY29tLycgLiBiYXNlbmFtZSgkaXRlbVsndXJsJ10pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnb3RlY2hpZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9vdGVjaGllLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5fY29sbGVjdGl2ZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9vcGVuY29sbGVjdGl2ZS5jb20vJyAuIGJhc2VuYW1lKCRpdGVtWyd1cmwnXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdsaWJlcmFwYXknOgogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbJGtleV1bJ3VybCddID0gJ2h0dHBzOi8vbGliZXJhcGF5LmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2tvX2ZpJzoKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WyRrZXldWyd1cmwnXSA9ICdodHRwczovL2tvLWZpLmNvbS8nIC4gYmFzZW5hbWUoJGl0ZW1bJ3VybCddKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2lzc3VlaHVudCc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9pc3N1ZWh1bnQuaW8vci8nIC4gJGl0ZW1bJ3VybCddOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnY29tbXVuaXR5X2JyaWRnZSc6CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XVsndXJsJ10gPSAnaHR0cHM6Ly9mdW5kaW5nLmNvbW11bml0eWJyaWRnZS5vcmcvcHJvamVjdHMvJyAuIGJhc2VuYW1lKCRpdGVtWyd1cmwnXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZnVuZGluZ0luZm8gPSAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy9jb250ZW50cy8nIC4gJGZpbGUgLiAnP3JlZj0nLnVybGVuY29kZSgkaWRlbnRpZmllcik7CiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSktPmRlY29kZUpzb24oKTsKICAgICAgICBpZiAoZW1wdHkoJHJlc291cmNlWydjb250ZW50J10pIHx8ICRyZXNvdXJjZVsnZW5jb2RpbmcnXSAhPT0gJ2Jhc2U2NCcgfHwgISgkY29udGVudCA9IGJhc2U2NF9kZWNvZGUoJHJlc291cmNlWydjb250ZW50J10pKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCByZXRyaWV2ZSAnIC4gJGZpbGUgLiAnIGZvciAnLiRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy9jb21taXRzLycudXJsZW5jb2RlKCRpZGVudGlmaWVyKTsKICAgICAgICAkY29tbWl0ID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSktPmRlY29kZUpzb24oKTsKCiAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJGNvbW1pdFsnY29tbWl0J11bJ2NvbW1pdHRlciddWydkYXRlJ10pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldFRhZ3MoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy90YWdzP3Blcl9wYWdlPTEwMCc7CgogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0Q29udGVudHMoJHJlc291cmNlKTsKICAgICAgICAgICAgICAgICR0YWdzRGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRhZ3NEYXRhIGFzICR0YWcpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dGFnc1skdGFnWyduYW1lJ11dID0gJHRhZ1snY29tbWl0J11bJ3NoYSddOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXROZXh0UGFnZSgkcmVzcG9uc2UpOwogICAgICAgICAgICB9IHdoaWxlICgkcmVzb3VyY2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50YWdzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QnJhbmNoZXMoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRCcmFuY2hlcygpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmJyYW5jaGVzKSB7CiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXRBcGlVcmwoKSAuICcvcmVwb3MvJy4kdGhpcy0+b3duZXIuJy8nLiR0aGlzLT5yZXBvc2l0b3J5LicvZ2l0L3JlZnMvaGVhZHM/cGVyX3BhZ2U9MTAwJzsKCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVzb3VyY2UpOwogICAgICAgICAgICAgICAgJGJyYW5jaERhdGEgPSAkcmVzcG9uc2UtPmRlY29kZUpzb24oKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRicmFuY2hEYXRhIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZSA9IHN1YnN0cigkYnJhbmNoWydyZWYnXSwgMTEpOwogICAgICAgICAgICAgICAgICAgIGlmICgkbmFtZSAhPT0gJ2doLXBhZ2VzJykgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXNbJG5hbWVdID0gJGJyYW5jaFsnb2JqZWN0J11bJ3NoYSddOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzb3VyY2UgPSAkdGhpcy0+Z2V0TmV4dFBhZ2UoJHJlc3BvbnNlKTsKICAgICAgICAgICAgfSB3aGlsZSAoJHJlc291cmNlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHVybCwgJGRlZXAgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJyNeKCg/Omh0dHBzP3xnaXQpOi8vKFteL10rKS98Z2l0QChbXjpdKyk6Lz8pKFteL10rKS8oLis/KSg/OlwuZ2l0fC8pPyQjJywgJHVybCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRvcmlnaW5VcmwgPSAhZW1wdHkoJG1hdGNoZXNbMl0pID8gJG1hdGNoZXNbMl0gOiAkbWF0Y2hlc1szXTsKICAgICAgICBpZiAoIWluX2FycmF5KHN0cnRvbG93ZXIocHJlZ19yZXBsYWNlKCd7Xnd3d1wufWknLCAnJywgJG9yaWdpblVybCkpLCAkY29uZmlnLT5nZXQoJ2dpdGh1Yi1kb21haW5zJykpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignU2tpcHBpbmcgR2l0SHViIGRyaXZlciBmb3IgJy4kdXJsLicgYmVjYXVzZSB0aGUgT3BlblNTTCBQSFAgZXh0ZW5zaW9uIGlzIG1pc3NpbmcuJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlcyBiYWNrIHRoZSBsb2FkZWQgPGdpdGh1Yi1hcGk+L3JlcG9zLzxvd25lcj4vPHJlcG8+IHJlc3VsdAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0RhdGEoKQogICAgewogICAgICAgICR0aGlzLT5mZXRjaFJvb3RJZGVudGlmaWVyKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVwb0RhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdGhpcy0+b3JpZ2luVXJsLCAnOicpKSB7CiAgICAgICAgICAgIHJldHVybiAnc3NoOi8vZ2l0QCcgLiAkdGhpcy0+b3JpZ2luVXJsIC4gJy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdnaXRAJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnOicuJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nLmdpdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb250ZW50cygkdXJsLCAkZmV0Y2hpbmdSZXBvRGF0YSA9IGZhbHNlKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkZ2l0SHViVXRpbCA9IG5ldyBHaXRIdWIoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKCiAgICAgICAgICAgIHN3aXRjaCAoJGUtPmdldENvZGUoKSkgewogICAgICAgICAgICAgICAgY2FzZSA0MDE6CiAgICAgICAgICAgICAgICBjYXNlIDQwNDoKICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gYXV0aG9yaXplIG9ubHkgaWYgd2UgYXJlIGZldGNoaW5nIHRoZSBtYWluIC9yZXBvcy9mb28vYmFyIGRhdGEsIG90aGVyd2lzZSBpdCBtdXN0IGJlIGEgcmVhbCA0MDQKICAgICAgICAgICAgICAgICAgICBpZiAoISRmZXRjaGluZ1JlcG9EYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRzY29wZXNJc3N1ZWQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICRzY29wZXNOZWVkZWQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGlmICgkaGVhZGVycyA9ICRlLT5nZXRIZWFkZXJzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRzY29wZXMgPSBSZXNwb25zZTo6ZmluZEhlYWRlclZhbHVlKCRoZWFkZXJzLCAnWC1PQXV0aC1TY29wZXMnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNjb3Blc0lzc3VlZCA9IGV4cGxvZGUoJyAnLCAkc2NvcGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHNjb3BlcyA9IFJlc3BvbnNlOjpmaW5kSGVhZGVyVmFsdWUoJGhlYWRlcnMsICdYLUFjY2VwdGVkLU9BdXRoLVNjb3BlcycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2NvcGVzTmVlZGVkID0gZXhwbG9kZSgnICcsICRzY29wZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRzY29wZXNGYWlsZWQgPSBhcnJheV9kaWZmKCRzY29wZXNOZWVkZWQsICRzY29wZXNJc3N1ZWQpOwogICAgICAgICAgICAgICAgICAgIC8vIG5vbi1hdXRoZW50aWNhdGVkIHJlcXVlc3RzIGdldCBubyBzY29wZXNOZWVkZWQsIHNvIGFzayBmb3IgY3JlZGVudGlhbHMKICAgICAgICAgICAgICAgICAgICAvLyBhdXRoZW50aWNhdGVkIHJlcXVlc3RzIHdoaWNoIGZhaWxlZCBzb21lIHNjb3BlcyBzaG91bGQgYXNrIGZvciBuZXcgY3JlZGVudGlhbHMgdG9vCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkaGVhZGVycyB8fCAhY291bnQoJHNjb3Blc05lZWRlZCkgfHwgY291bnQoJHNjb3Blc0ZhaWxlZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkdGhpcy0+b3JpZ2luVXJsLCAnWW91ciBHaXRIdWIgY3JlZGVudGlhbHMgYXJlIHJlcXVpcmVkIHRvIGZldGNoIHByaXZhdGUgcmVwb3NpdG9yeSBtZXRhZGF0YSAoPGluZm8+Jy4kdGhpcy0+dXJsLic8L2luZm8+KScpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CgogICAgICAgICAgICAgICAgY2FzZSA0MDM6CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCR0aGlzLT5vcmlnaW5VcmwpICYmICRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgJiYgJGZldGNoaW5nUmVwb0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRlZCA9ICRnaXRIdWJVdGlsLT5pc1JhdGVMaW1pdGVkKCRlLT5nZXRIZWFkZXJzKCkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJHRoaXMtPm9yaWdpblVybCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+R2l0SHViIEFQSSBsaW1pdCBleGhhdXN0ZWQuIEZhaWxlZCB0byBnZXQgbWV0YWRhdGEgZm9yIHRoZSAnLiR0aGlzLT51cmwuJyByZXBvc2l0b3J5LCB0cnkgcnVubmluZyBpbiBpbnRlcmFjdGl2ZSBtb2RlIHNvIHRoYXQgeW91IGNhbiBlbnRlciB5b3VyIEdpdEh1YiBjcmVkZW50aWFscyB0byBpbmNyZWFzZSB0aGUgQVBJIGxpbWl0PC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkZ2l0SHViVXRpbC0+YXV0aG9yaXplT0F1dGhJbnRlcmFjdGl2ZWx5KCR0aGlzLT5vcmlnaW5VcmwsICdBUEkgbGltaXQgZXhoYXVzdGVkLiBFbnRlciB5b3VyIEdpdEh1YiBjcmVkZW50aWFscyB0byBnZXQgYSBsYXJnZXIgQVBJIGxpbWl0ICg8aW5mbz4nLiR0aGlzLT51cmwuJzwvaW5mbz4pJyk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkcmF0ZUxpbWl0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdCA9ICRnaXRIdWJVdGlsLT5nZXRSYXRlTGltaXQoJGUtPmdldEhlYWRlcnMoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj5HaXRIdWIgQVBJIGxpbWl0ICglZCBjYWxscy9ocikgaXMgZXhoYXVzdGVkLiBZb3UgYXJlIGFscmVhZHkgYXV0aG9yaXplZCBzbyB5b3UgaGF2ZSB0byB3YWl0IHVudGlsICVzIGJlZm9yZSBkb2luZyBtb3JlIHJlcXVlc3RzPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdFsnbGltaXQnXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRbJ3Jlc2V0J10KICAgICAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRmV0Y2ggcm9vdCBpZGVudGlmaWVyIGZyb20gR2l0SHViCiAgICAgKgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZldGNoUm9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cmVwb0RhdGEpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHJlcG9EYXRhVXJsID0gJHRoaXMtPmdldEFwaVVybCgpIC4gJy9yZXBvcy8nLiR0aGlzLT5vd25lci4nLycuJHRoaXMtPnJlcG9zaXRvcnk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGF0YSA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVwb0RhdGFVcmwsIHRydWUpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSA0OTkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hdHRlbXB0Q2xvbmVGYWxsYmFjaygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5yZXBvRGF0YSAmJiBudWxsICE9PSAkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vd25lciA9ICR0aGlzLT5yZXBvRGF0YVsnb3duZXInXVsnbG9naW4nXTsKICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSA9ICR0aGlzLT5yZXBvRGF0YVsnbmFtZSddOwoKICAgICAgICAkdGhpcy0+aXNQcml2YXRlID0gIWVtcHR5KCR0aGlzLT5yZXBvRGF0YVsncHJpdmF0ZSddKTsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlcG9EYXRhWydkZWZhdWx0X2JyYW5jaCddKSkgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAkdGhpcy0+cmVwb0RhdGFbJ2RlZmF1bHRfYnJhbmNoJ107CiAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCR0aGlzLT5yZXBvRGF0YVsnbWFzdGVyX2JyYW5jaCddKSkgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAkdGhpcy0+cmVwb0RhdGFbJ21hc3Rlcl9icmFuY2gnXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAnbWFzdGVyJzsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmhhc0lzc3VlcyA9ICFlbXB0eSgkdGhpcy0+cmVwb0RhdGFbJ2hhc19pc3N1ZXMnXSk7CiAgICAgICAgJHRoaXMtPmlzQXJjaGl2ZWQgPSAhZW1wdHkoJHRoaXMtPnJlcG9EYXRhWydhcmNoaXZlZCddKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXR0ZW1wdENsb25lRmFsbGJhY2soKQogICAgewogICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSB0cnVlOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBJZiB0aGlzIHJlcG9zaXRvcnkgbWF5IGJlIHByaXZhdGUgKGhhcmQgdG8gc2F5IGZvciBzdXJlLAogICAgICAgICAgICAvLyBHaXRIdWIgcmV0dXJucyA0MDQgZm9yIHByaXZhdGUgcmVwb3NpdG9yaWVzKSBhbmQgd2UKICAgICAgICAgICAgLy8gY2Fubm90IGFzayBmb3IgYXV0aGVudGljYXRpb24gY3JlZGVudGlhbHMgKGJlY2F1c2Ugd2UKICAgICAgICAgICAgLy8gYXJlIG5vdCBpbnRlcmFjdGl2ZSkgdGhlbiB3ZSBmYWxsYmFjayB0byBHaXREcml2ZXIuCiAgICAgICAgICAgICR0aGlzLT5zZXR1cEdpdERyaXZlcigkdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkdGhpcy0+Z2l0RHJpdmVyID0gbnVsbDsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkZhaWxlZCB0byBjbG9uZSB0aGUgJy4kdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKS4nIHJlcG9zaXRvcnksIHRyeSBydW5uaW5nIGluIGludGVyYWN0aXZlIG1vZGUgc28gdGhhdCB5b3UgY2FuIGVudGVyIHlvdXIgR2l0SHViIGNyZWRlbnRpYWxzPC9lcnJvcj4nKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXR1cEdpdERyaXZlcigkdXJsKQogICAgewogICAgICAgICR0aGlzLT5naXREcml2ZXIgPSBuZXcgR2l0RHJpdmVyKAogICAgICAgICAgICBhcnJheSgndXJsJyA9PiAkdXJsKSwKICAgICAgICAgICAgJHRoaXMtPmlvLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLAogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIsCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Z2l0RHJpdmVyLT5pbml0aWFsaXplKCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldE5leHRQYWdlKFJlc3BvbnNlICRyZXNwb25zZSkKICAgIHsKICAgICAgICAkaGVhZGVyID0gJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2xpbmsnKTsKCiAgICAgICAgJGxpbmtzID0gZXhwbG9kZSgnLCcsICRoZWFkZXIpOwogICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnezwoLis/KT47ICpyZWw9Im5leHQifScsICRsaW5rLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcVXRpbFxIZyBhcyBIZ1V0aWxzOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIFBlciBCZXJuaGFyZHQgPHBsYkB3ZWJmYWN0b3J5LmRlPgogKi8KY2xhc3MgSGdEcml2ZXIgZXh0ZW5kcyBWY3NEcml2ZXIKewogICAgcHJvdGVjdGVkICR0YWdzOwogICAgcHJvdGVjdGVkICRicmFuY2hlczsKICAgIHByb3RlY3RlZCAkcm9vdElkZW50aWZpZXI7CiAgICBwcm90ZWN0ZWQgJHJlcG9EaXI7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBpZiAoRmlsZXN5c3RlbTo6aXNMb2NhbFBhdGgoJHRoaXMtPnVybCkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9EaXIgPSAkdGhpcy0+dXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghQ2FjaGU6OmlzVXNhYmxlKCR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdIZ0RyaXZlciByZXF1aXJlcyBhIHVzYWJsZSBjYWNoZSBkaXJlY3RvcnksIGFuZCBpdCBsb29rcyBsaWtlIHlvdSBzZXQgaXQgdG8gYmUgZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNhY2hlRGlyID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJyk7CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGlyID0gJGNhY2hlRGlyIC4gJy8nIC4gcHJlZ19yZXBsYWNlKCd7W15hLXowLTldfWknLCAnLScsICR0aGlzLT51cmwpIC4gJy8nOwoKICAgICAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAgICAgJGZzLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJGNhY2hlRGlyKTsKCiAgICAgICAgICAgIGlmICghaXNfd3JpdGFibGUoZGlybmFtZSgkdGhpcy0+cmVwb0RpcikpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NhbiBub3QgY2xvbmUgJy4kdGhpcy0+dXJsLicgdG8gYWNjZXNzIHBhY2thZ2UgaW5mb3JtYXRpb24uIFRoZSAiJy4kY2FjaGVEaXIuJyIgZGlyZWN0b3J5IGlzIG5vdCB3cml0YWJsZSBieSB0aGUgY3VycmVudCB1c2VyLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBFbnN1cmUgd2UgYXJlIGFsbG93ZWQgdG8gdXNlIHRoaXMgVVJMIGJ5IGNvbmZpZwogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLT5wcm9oaWJpdFVybEJ5Q29uZmlnKCR0aGlzLT51cmwsICR0aGlzLT5pbyk7CgogICAgICAgICAgICAkaGdVdGlscyA9IG5ldyBIZ1V0aWxzKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSByZXBvIGlmIGl0IGlzIGEgdmFsaWQgaGcgcmVwb3NpdG9yeQogICAgICAgICAgICBpZiAoaXNfZGlyKCR0aGlzLT5yZXBvRGlyKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgc3VtbWFyeScsICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKSkgewogICAgICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdoZyBwdWxsJywgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+RmFpbGVkIHRvIHVwZGF0ZSAnLiR0aGlzLT51cmwuJywgcGFja2FnZSBpbmZvcm1hdGlvbiBmcm9tIHRoaXMgcmVwb3NpdG9yeSBtYXkgYmUgb3V0ZGF0ZWQgKCcuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkuJyk8L2Vycm9yPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gY2xlYW4gdXAgZGlyZWN0b3J5IGFuZCBkbyBhIGZyZXNoIGNsb25lIGludG8gaXQKICAgICAgICAgICAgICAgICRmcy0+cmVtb3ZlRGlyZWN0b3J5KCR0aGlzLT5yZXBvRGlyKTsKCiAgICAgICAgICAgICAgICAkcmVwb0RpciA9ICR0aGlzLT5yZXBvRGlyOwogICAgICAgICAgICAgICAgJGNvbW1hbmQgPSBmdW5jdGlvbiAoJHVybCkgdXNlICgkcmVwb0RpcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdoZyBjbG9uZSAtLW5vdXBkYXRlIC0tICVzICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRyZXBvRGlyKSk7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICRoZ1V0aWxzLT5ydW5Db21tYW5kKCRjb21tYW5kLCAkdGhpcy0+dXJsLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmdldFRhZ3MoKTsKICAgICAgICAkdGhpcy0+Z2V0QnJhbmNoZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnJvb3RJZGVudGlmaWVyKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKHNwcmludGYoJ2hnIHRpcCAtLXRlbXBsYXRlICJ7bm9kZX0iJyksICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKTsKICAgICAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpOwogICAgICAgICAgICAkdGhpcy0+cm9vdElkZW50aWZpZXIgPSAkb3V0cHV0WzBdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290SWRlbnRpZmllcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAnaGcnLCAndXJsJyA9PiAkdGhpcy0+Z2V0VXJsKCksICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZignaGcgY2F0IC1yICVzICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGlkZW50aWZpZXIpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkpOwogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRyZXNvdXJjZSwgJGNvbnRlbnQsICR0aGlzLT5yZXBvRGlyKTsKCiAgICAgICAgaWYgKCF0cmltKCRjb250ZW50KSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKAogICAgICAgICAgICBzcHJpbnRmKAogICAgICAgICAgICAgICAgJ2hnIGxvZyAtLXRlbXBsYXRlICJ7ZGF0ZXxyZmMzMzM5ZGF0ZX0iIC1yICVzJywKICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRpZGVudGlmaWVyKQogICAgICAgICAgICApLAogICAgICAgICAgICAkb3V0cHV0LAogICAgICAgICAgICAkdGhpcy0+cmVwb0RpcgogICAgICAgICk7CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKHRyaW0oJG91dHB1dCksIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnRhZ3MpIHsKICAgICAgICAgICAgJHRhZ3MgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIHRhZ3MnLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICR0YWcpIHsKICAgICAgICAgICAgICAgIGlmICgkdGFnICYmIHByZWdfbWF0Y2goJyheKFteXHNdKylccytcZCs6KC4qKSQpJywgJHRhZywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICR0YWdzWyRtYXRjaFsxXV0gPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zZXQoJHRhZ3NbJ3RpcCddKTsKCiAgICAgICAgICAgICR0aGlzLT50YWdzID0gJHRhZ3M7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgpOwogICAgICAgICAgICAkYm9va21hcmtzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdoZyBicmFuY2hlcycsICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCkgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgaWYgKCRicmFuY2ggJiYgcHJlZ19tYXRjaCgnKF4oW15cc10rKVxzK1xkKzooW2EtZjAtOV0rKSknLCAkYnJhbmNoLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyRtYXRjaFsxXV0gPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdoZyBib29rbWFya3MnLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmIHByZWdfbWF0Y2goJyheKD86W1xzKl0qKShbXlxzXSspXHMrXGQrOiguKikkKScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkYm9va21hcmtzWyRtYXRjaFsxXV0gPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEJyYW5jaGVzIHdpbGwgaGF2ZSBwcmVmZXJlbmNlIG92ZXIgYm9va21hcmtzCiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9IGFycmF5X21lcmdlKCRib29rbWFya3MsICRicmFuY2hlcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmJyYW5jaGVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJyMoXig/Omh0dHBzP3xzc2gpOi8vKD86W15AXStAKT9iaXRidWNrZXQub3JnfGh0dHBzOi8vKD86Lio/KVwua2lsbmhnLmNvbSkjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9jYWwgZmlsZXN5c3RlbQogICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdXJsKSkgewogICAgICAgICAgICAkdXJsID0gRmlsZXN5c3RlbTo6Z2V0UGxhdGZvcm1QYXRoKCR1cmwpOwogICAgICAgICAgICBpZiAoIWlzX2RpcigkdXJsKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIGhnIHJlcG8gaW4gdGhhdCBwYXRoCiAgICAgICAgICAgIGlmICgkcHJvY2Vzcy0+ZXhlY3V0ZSgnaGcgc3VtbWFyeScsICRvdXRwdXQsICR1cmwpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkZGVlcCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkZXhpdCA9ICRwcm9jZXNzLT5leGVjdXRlKHNwcmludGYoJ2hnIGlkZW50aWZ5IC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCkpLCAkaWdub3JlZCk7CgogICAgICAgIHJldHVybiAkZXhpdCA9PT0gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcVXJsOwp1c2UgQ29tcG9zZXJcVXRpbFxTdm4gYXMgU3ZuVXRpbDsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIFRpbGwgS2xhbXBhZWNrZWwgPHRpbGxAcGhwLm5ldD4KICovCmNsYXNzIFN2bkRyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICBwcm90ZWN0ZWQgJGJhc2VVcmw7CiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzOwogICAgcHJvdGVjdGVkICRyb290SWRlbnRpZmllcjsKCiAgICBwcm90ZWN0ZWQgJHRydW5rUGF0aCA9ICd0cnVuayc7CiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzUGF0aCA9ICdicmFuY2hlcyc7CiAgICBwcm90ZWN0ZWQgJHRhZ3NQYXRoID0gJ3RhZ3MnOwogICAgcHJvdGVjdGVkICRwYWNrYWdlUGF0aCA9ICcnOwogICAgcHJvdGVjdGVkICRjYWNoZUNyZWRlbnRpYWxzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEB2YXIgXENvbXBvc2VyXFV0aWxcU3ZuCiAgICAgKi8KICAgIHByaXZhdGUgJHV0aWw7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICAkdGhpcy0+dXJsID0gJHRoaXMtPmJhc2VVcmwgPSBydHJpbShzZWxmOjpub3JtYWxpemVVcmwoJHRoaXMtPnVybCksICcvJyk7CgogICAgICAgIFN2blV0aWw6OmNsZWFuRW52KCk7CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVwb0NvbmZpZ1sndHJ1bmstcGF0aCddKSkgewogICAgICAgICAgICAkdGhpcy0+dHJ1bmtQYXRoID0gJHRoaXMtPnJlcG9Db25maWdbJ3RydW5rLXBhdGgnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5yZXBvQ29uZmlnWydicmFuY2hlcy1wYXRoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlc1BhdGggPSAkdGhpcy0+cmVwb0NvbmZpZ1snYnJhbmNoZXMtcGF0aCddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlcG9Db25maWdbJ3RhZ3MtcGF0aCddKSkgewogICAgICAgICAgICAkdGhpcy0+dGFnc1BhdGggPSAkdGhpcy0+cmVwb0NvbmZpZ1sndGFncy1wYXRoJ107CiAgICAgICAgfQogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdzdm4tY2FjaGUtY3JlZGVudGlhbHMnLCAkdGhpcy0+cmVwb0NvbmZpZykpIHsKICAgICAgICAgICAgJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPSAoYm9vbCkgJHRoaXMtPnJlcG9Db25maWdbJ3N2bi1jYWNoZS1jcmVkZW50aWFscyddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlcG9Db25maWdbJ3BhY2thZ2UtcGF0aCddKSkgewogICAgICAgICAgICAkdGhpcy0+cGFja2FnZVBhdGggPSAnLycgLiB0cmltKCR0aGlzLT5yZXBvQ29uZmlnWydwYWNrYWdlLXBhdGgnXSwgJy8nKTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSAhPT0gKCRwb3MgPSBzdHJycG9zKCR0aGlzLT51cmwsICcvJyAuICR0aGlzLT50cnVua1BhdGgpKSkgewogICAgICAgICAgICAkdGhpcy0+YmFzZVVybCA9IHN1YnN0cigkdGhpcy0+dXJsLCAwLCAkcG9zKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jYWNoZSA9IG5ldyBDYWNoZSgkdGhpcy0+aW8sICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKS4nLycucHJlZ19yZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCBVcmw6OnNhbml0aXplKCR0aGlzLT5iYXNlVXJsKSkpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CgogICAgICAgICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICR0aGlzLT5nZXRUYWdzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290SWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290SWRlbnRpZmllciA/OiAkdGhpcy0+dHJ1bmtQYXRoOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICdzdm4nLCAndXJsJyA9PiAkdGhpcy0+YmFzZVVybCwgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNob3VsZENhY2hlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2FjaGUgJiYgcHJlZ19tYXRjaCgne0BcZCskfScsICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikgJiYgJHJlcyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkaWRlbnRpZmllci4nLmpzb24nKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRCYXNlQ29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAkZS0+Z2V0TWVzc2FnZSgpOwogICAgICAgICAgICAgICAgaWYgKHN0cmlwb3MoJG1lc3NhZ2UsICdwYXRoIG5vdCBmb3VuZCcpID09PSBmYWxzZSAmJiBzdHJpcG9zKCRtZXNzYWdlLCAnc3ZuOiB3YXJuaW5nOiBXMTYwMDEzJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyByZW1lbWJlciBhIG5vdC1leGlzdGVudCBjb21wb3Nlci5qc29uCiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGlkZW50aWZpZXIuJy5qc29uJywganNvbl9lbmNvZGUoJGNvbXBvc2VyKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gJGNvbXBvc2VyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkaWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgICRpZGVudGlmaWVyID0gJy8nIC4gdHJpbSgkaWRlbnRpZmllciwgJy8nKSAuICcvJzsKCiAgICAgICAgcHJlZ19tYXRjaCgne14oLis/KShAXGQrKT8vJH0nLCAkaWRlbnRpZmllciwgJG1hdGNoKTsKICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsyXSkpIHsKICAgICAgICAgICAgJHBhdGggPSAkbWF0Y2hbMV07CiAgICAgICAgICAgICRyZXYgPSAkbWF0Y2hbMl07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhdGggPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgJHJldiA9ICcnOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHJlc291cmNlID0gJHBhdGguJGZpbGU7CiAgICAgICAgICAgICRvdXRwdXQgPSAkdGhpcy0+ZXhlY3V0ZSgnc3ZuIGNhdCcsICR0aGlzLT5iYXNlVXJsIC4gJHJlc291cmNlIC4gJHJldik7CiAgICAgICAgICAgIGlmICghdHJpbSgkb3V0cHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRpZGVudGlmaWVyID0gJy8nIC4gdHJpbSgkaWRlbnRpZmllciwgJy8nKSAuICcvJzsKCiAgICAgICAgcHJlZ19tYXRjaCgne14oLis/KShAXGQrKT8vJH0nLCAkaWRlbnRpZmllciwgJG1hdGNoKTsKICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsyXSkpIHsKICAgICAgICAgICAgJHBhdGggPSAkbWF0Y2hbMV07CiAgICAgICAgICAgICRyZXYgPSAkbWF0Y2hbMl07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhdGggPSAkaWRlbnRpZmllcjsKICAgICAgICAgICAgJHJldiA9ICcnOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5leGVjdXRlKCdzdm4gaW5mbycsICR0aGlzLT5iYXNlVXJsIC4gJHBhdGggLiAkcmV2KTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAoJGxpbmUgJiYgcHJlZ19tYXRjaCgne15MYXN0IENoYW5nZWQgRGF0ZTogKFteKF0rKX0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJG1hdGNoWzFdLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhZ3MoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+dGFncykgewogICAgICAgICAgICAkdGhpcy0+dGFncyA9IGFycmF5KCk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPnRhZ3NQYXRoICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5leGVjdXRlKCdzdm4gbHMgLS12ZXJib3NlJywgJHRoaXMtPmJhc2VVcmwgLiAnLycgLiAkdGhpcy0+dGFnc1BhdGgpOwogICAgICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmUgJiYgcHJlZ19tYXRjaCgne15ccyooXFMrKS4qPyhcUyspXHMqJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaFsxXSwgJG1hdGNoWzJdKSAmJiAkbWF0Y2hbMl0gIT09ICcuLycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dGFnc1tydHJpbSgkbWF0Y2hbMl0sICcvJyldID0gJHRoaXMtPmJ1aWxkSWRlbnRpZmllcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy8nIC4gJHRoaXMtPnRhZ3NQYXRoIC4gJy8nIC4gJG1hdGNoWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hbMV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXMgPSBhcnJheSgpOwoKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdGhpcy0+dHJ1bmtQYXRoKSB7CiAgICAgICAgICAgICAgICAkdHJ1bmtQYXJlbnQgPSAkdGhpcy0+YmFzZVVybCAuICcvJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0cnVua1BhcmVudCA9ICR0aGlzLT5iYXNlVXJsIC4gJy8nIC4gJHRoaXMtPnRydW5rUGF0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG91dHB1dCA9ICR0aGlzLT5leGVjdXRlKCdzdm4gbHMgLS12ZXJib3NlJywgJHRydW5rUGFyZW50KTsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmUgJiYgcHJlZ19tYXRjaCgne15ccyooXFMrKS4qPyhcUyspXHMqJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoWzFdLCAkbWF0Y2hbMl0pICYmICRtYXRjaFsyXSA9PT0gJy4vJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzWyd0cnVuayddID0gJHRoaXMtPmJ1aWxkSWRlbnRpZmllcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLycgLiAkdGhpcy0+dHJ1bmtQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yb290SWRlbnRpZmllciA9ICR0aGlzLT5icmFuY2hlc1sndHJ1bmsnXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCRvdXRwdXQpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5icmFuY2hlc1BhdGggIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPmV4ZWN1dGUoJ3N2biBscyAtLXZlcmJvc2UnLCAkdGhpcy0+YmFzZVVybCAuICcvJyAuICR0aGlzLT5icmFuY2hlc1BhdGgpOwogICAgICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcyh0cmltKCRvdXRwdXQpKSBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmUgJiYgcHJlZ19tYXRjaCgne15ccyooXFMrKS4qPyhcUyspXHMqJH0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaFsxXSwgJG1hdGNoWzJdKSAmJiAkbWF0Y2hbMl0gIT09ICcuLycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXNbcnRyaW0oJG1hdGNoWzJdLCAnLycpXSA9ICR0aGlzLT5idWlsZElkZW50aWZpZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcvJyAuICR0aGlzLT5icmFuY2hlc1BhdGggLiAnLycgLiAkbWF0Y2hbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHVybCwgJGRlZXAgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdXJsID0gc2VsZjo6bm9ybWFsaXplVXJsKCR1cmwpOwogICAgICAgIGlmIChwcmVnX21hdGNoKCcjKF5zdm46Ly98XnN2blwrc3NoOi8vfHN2blwuKSNpJywgJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBwcm9jZWVkIHdpdGggZGVlcCBjaGVjayBmb3IgbG9jYWwgdXJscyBzaW5jZSB0aGV5IGFyZSBmYXN0IHRvIHByb2Nlc3MKICAgICAgICBpZiAoISRkZWVwICYmICFGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdXJsKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkZXhpdCA9ICRwcm9jZXNzLT5leGVjdXRlKAogICAgICAgICAgICAic3ZuIGluZm8gLS1ub24taW50ZXJhY3RpdmUgLS0gIi5Qcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSwKICAgICAgICAgICAgJGlnbm9yZWRPdXRwdXQKICAgICAgICApOwoKICAgICAgICBpZiAoJGV4aXQgPT09IDApIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBkZWZpbml0ZWx5IGEgU3VidmVyc2lvbiByZXBvc2l0b3J5LgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIFN1YnZlcnNpb24gY2xpZW50IDEuNyBhbmQgb2xkZXIKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cmlwb3MoJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICdhdXRob3JpemF0aW9uIGZhaWxlZDonKSkgewogICAgICAgICAgICAvLyBUaGlzIGlzIGxpa2VseSBhIHJlbW90ZSBTdWJ2ZXJzaW9uIHJlcG9zaXRvcnkgdGhhdCByZXF1aXJlcwogICAgICAgICAgICAvLyBhdXRoZW50aWNhdGlvbi4gV2Ugd2lsbCBoYW5kbGUgYWN0dWFsIGF1dGhlbnRpY2F0aW9uIGxhdGVyLgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIFN1YnZlcnNpb24gY2xpZW50IDEuOCBhbmQgbmV3ZXIKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cmlwb3MoJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICdBdXRoZW50aWNhdGlvbiBmYWlsZWQnKSkgewogICAgICAgICAgICAvLyBUaGlzIGlzIGxpa2VseSBhIHJlbW90ZSBTdWJ2ZXJzaW9uIG9yIG5ld2VyIHJlcG9zaXRvcnkgdGhhdCByZXF1aXJlcwogICAgICAgICAgICAvLyBhdXRoZW50aWNhdGlvbi4gV2Ugd2lsbCBoYW5kbGUgYWN0dWFsIGF1dGhlbnRpY2F0aW9uIGxhdGVyLgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEFuIGFic29sdXRlIHBhdGggKGxlYWRpbmcgJy8nKSBpcyBjb252ZXJ0ZWQgdG8gYSBmaWxlOi8vIHVybC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIG5vcm1hbGl6ZVVybCgkdXJsKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgaWYgKCRmcy0+aXNBYnNvbHV0ZVBhdGgoJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuICdmaWxlOi8vJyAuIHN0cnRyKCR1cmwsICdcXCcsICcvJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgYW4gU1ZOIGNvbW1hbmQgYW5kIHRyeSB0byBmaXggdXAgdGhlIHByb2Nlc3Mgd2l0aCBjcmVkZW50aWFscwogICAgICogaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGNvbW1hbmQgVGhlIHN2biBjb21tYW5kIHRvIHJ1bi4KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHVybCAgICAgVGhlIFNWTiBVUkwuCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZSgkY29tbWFuZCwgJHVybCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnV0aWwpIHsKICAgICAgICAgICAgJHRoaXMtPnV0aWwgPSBuZXcgU3ZuVXRpbCgkdGhpcy0+YmFzZVVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgICAgICR0aGlzLT51dGlsLT5zZXRDYWNoZUNyZWRlbnRpYWxzKCR0aGlzLT5jYWNoZUNyZWRlbnRpYWxzKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dXRpbC0+ZXhlY3V0ZSgkY29tbWFuZCwgJHVybCk7CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT51dGlsLT5iaW5hcnlWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGxvYWQgJy4kdGhpcy0+dXJsLicsIHN2biB3YXMgbm90IGZvdW5kLCBjaGVjayB0aGF0IGl0IGlzIGluc3RhbGxlZCBhbmQgaW4geW91ciBQQVRIIGVudi4nIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAnUmVwb3NpdG9yeSAnLiR0aGlzLT51cmwuJyBjb3VsZCBub3QgYmUgcHJvY2Vzc2VkLCAnLiRlLT5nZXRNZXNzYWdlKCkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZCB0aGUgaWRlbnRpZmllciByZXNwZWN0aW5nICJwYWNrYWdlLXBhdGgiIGNvbmZpZyBvcHRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlRGlyICBUaGUgcGF0aCB0byB0cnVuay9icmFuY2gvdGFnCiAgICAgKiBAcGFyYW0gaW50ICAgICRyZXZpc2lvbiBUaGUgcmV2aXNpb24gbWFyayB0byBhZGQgdG8gaWRlbnRpZmllcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBidWlsZElkZW50aWZpZXIoJGJhc2VEaXIsICRyZXZpc2lvbikKICAgIHsKICAgICAgICByZXR1cm4gcnRyaW0oJGJhc2VEaXIsICcvJykgLiAkdGhpcy0+cGFja2FnZVBhdGggLiAnL0AnIC4gJHJldmlzaW9uOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBWY3NEcml2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgZHJpdmVyIChnaXQgY2xvbmUsIHN2biBjaGVja291dCwgZmV0Y2ggaW5mbyBldGMpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNvbXBvc2VyLmpzb24gZmlsZSBpbmZvcm1hdGlvbgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRpZGVudGlmaWVyIEFueSBpZGVudGlmaWVyIHRvIGEgc3BlY2lmaWMgYnJhbmNoL3RhZy9jb21taXQKICAgICAqIEByZXR1cm4gYXJyYXkgIGNvbnRhaW5pbmcgYWxsIGluZm9zIGZyb20gdGhlIGNvbXBvc2VyLmpzb24gZmlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQgb2YgJGZpbGUgb3IgbnVsbCBpZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdC4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRmaWxlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBjaGFuZ2VkYXRlIGZvciAkaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIFxEYXRlVGltZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcm9vdCBpZGVudGlmaWVyICh0cnVuaywgbWFzdGVyLCBkZWZhdWx0L3RpcCAuLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290SWRlbnRpZmllcigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGxpc3Qgb2YgYnJhbmNoZXMgaW4gdGhlIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEJyYW5jaCBuYW1lcyBhcyBrZXlzLCBpZGVudGlmaWVycyBhcyB2YWx1ZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaGVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gbGlzdCBvZiB0YWdzIGluIHRoZSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBUYWcgbmFtZXMgYXMga2V5cywgaWRlbnRpZmllcnMgYXMgdmFsdWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgJGlkZW50aWZpZXIgQW55IGlkZW50aWZpZXIgdG8gYSBzcGVjaWZpYyBicmFuY2gvdGFnL2NvbW1pdAogICAgICogQHJldHVybiBhcnJheXxudWxsIFdpdGggdHlwZSwgdXJsIHJlZmVyZW5jZSBhbmQgc2hhc3VtIGtleXMuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0KCRpZGVudGlmaWVyKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRpZGVudGlmaWVyIEFueSBpZGVudGlmaWVyIHRvIGEgc3BlY2lmaWMgYnJhbmNoL3RhZy9jb21taXQKICAgICAqIEByZXR1cm4gYXJyYXkgIFdpdGggdHlwZSwgdXJsIGFuZCByZWZlcmVuY2Uga2V5cy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIFVSTCBvZiB0aGUgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSByZXBvc2l0b3J5IGhhcyBhIGNvbXBvc2VyIGZpbGUgZm9yIGEgZ2l2ZW4gaWRlbnRpZmllciwKICAgICAqIGZhbHNlIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkaWRlbnRpZmllciBBbnkgaWRlbnRpZmllciB0byBhIHNwZWNpZmljIGJyYW5jaC90YWcvY29tbWl0CiAgICAgKiBAcmV0dXJuIGJvb2wgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IGhhcyBhIGNvbXBvc2VyIGZpbGUgZm9yIGEgZ2l2ZW4gaWRlbnRpZmllci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0NvbXBvc2VyRmlsZSgkaWRlbnRpZmllcik7CgogICAgLyoqCiAgICAgKiBQZXJmb3JtcyBhbnkgY2xlYW51cCBuZWNlc3NhcnkgYXMgdGhlIGRyaXZlciBpcyBub3QgbG9uZ2VyIG5lZWRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoaXMgZHJpdmVyIGNhbiBoYW5kbGUgYSBnaXZlbiB1cmwKICAgICAqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICRpbyAgICAgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgJGNvbmZpZyBjdXJyZW50ICRjb25maWcKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHVybCAgICBVUkwgdG8gdmFsaWRhdGUvY2hlY2sKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgJGRlZXAgICB1bmxlc3MgdHJ1ZSwgb25seSBzaGFsbG93IGNoZWNrcyAodXJsIG1hdGNoaW5nIHR5cGljYWxseSkgc2hvdWxkIGJlIGRvbmUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcVXRpbFxCaXRidWNrZXQ7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBcUmVzcG9uc2U7CgphYnN0cmFjdCBjbGFzcyBCaXRidWNrZXREcml2ZXIgZXh0ZW5kcyBWY3NEcml2ZXIKewogICAgcHJvdGVjdGVkICRvd25lcjsKICAgIHByb3RlY3RlZCAkcmVwb3NpdG9yeTsKICAgIHByb3RlY3RlZCAkaGFzSXNzdWVzOwogICAgcHJvdGVjdGVkICRyb290SWRlbnRpZmllcjsKICAgIHByb3RlY3RlZCAkdGFnczsKICAgIHByb3RlY3RlZCAkYnJhbmNoZXM7CiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzVXJsID0gJyc7CiAgICBwcm90ZWN0ZWQgJHRhZ3NVcmwgPSAnJzsKICAgIHByb3RlY3RlZCAkaG9tZVVybCA9ICcnOwogICAgcHJvdGVjdGVkICR3ZWJzaXRlID0gJyc7CiAgICBwcm90ZWN0ZWQgJGNsb25lSHR0cHNVcmwgPSAnJzsKCiAgICAvKioKICAgICAqIEB2YXIgVmNzRHJpdmVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmFsbGJhY2tEcml2ZXI7CiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCBpZiBzZXQgZWl0aGVyIGdpdCBvciBoZyAqLwogICAgcHJvdGVjdGVkICR2Y3NUeXBlOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcHJlZ19tYXRjaCgnI15odHRwcz86Ly9iaXRidWNrZXRcLm9yZy8oW14vXSspLyhbXi9dKz8pKFwuZ2l0fC8/KSQjaScsICR0aGlzLT51cmwsICRtYXRjaCk7CiAgICAgICAgJHRoaXMtPm93bmVyID0gJG1hdGNoWzFdOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5ID0gJG1hdGNoWzJdOwogICAgICAgICR0aGlzLT5vcmlnaW5VcmwgPSAnYml0YnVja2V0Lm9yZyc7CiAgICAgICAgJHRoaXMtPmNhY2hlID0gbmV3IENhY2hlKAogICAgICAgICAgICAkdGhpcy0+aW8sCiAgICAgICAgICAgIGltcGxvZGUoJy8nLCBhcnJheSgKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKSwKICAgICAgICAgICAgICAgICR0aGlzLT5vcmlnaW5VcmwsCiAgICAgICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSwKICAgICAgICAgICAgKSkKICAgICAgICApOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0VXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNsb25lSHR0cHNVcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBmZXRjaCB0aGUgcmVwb3NpdG9yeSBkYXRhIHZpYSB0aGUgQml0QnVja2V0IEFQSSBhbmQKICAgICAqIHNldHMgc29tZSBwYXJhbWV0ZXJzIHdoaWNoIGFyZSB1c2VkIGluIG90aGVyIG1ldGhvZHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFJlcG9EYXRhKCkKICAgIHsKICAgICAgICAkcmVzb3VyY2UgPSBzcHJpbnRmKAogICAgICAgICAgICAnaHR0cHM6Ly9hcGkuYml0YnVja2V0Lm9yZy8yLjAvcmVwb3NpdG9yaWVzLyVzLyVzPyVzJywKICAgICAgICAgICAgJHRoaXMtPm93bmVyLAogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSwKICAgICAgICAgICAgaHR0cF9idWlsZF9xdWVyeSgKICAgICAgICAgICAgICAgIGFycmF5KCdmaWVsZHMnID0+ICctcHJvamVjdCwtb3duZXInKSwKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAnJicKICAgICAgICAgICAgKQogICAgICAgICk7CgogICAgICAgICRyZXBvRGF0YSA9ICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSwgdHJ1ZSktPmRlY29kZUpzb24oKTsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnBhcnNlQ2xvbmVVcmxzKCRyZXBvRGF0YVsnbGlua3MnXVsnY2xvbmUnXSk7CgogICAgICAgICR0aGlzLT5oYXNJc3N1ZXMgPSAhZW1wdHkoJHJlcG9EYXRhWydoYXNfaXNzdWVzJ10pOwogICAgICAgICR0aGlzLT5icmFuY2hlc1VybCA9ICRyZXBvRGF0YVsnbGlua3MnXVsnYnJhbmNoZXMnXVsnaHJlZiddOwogICAgICAgICR0aGlzLT50YWdzVXJsID0gJHJlcG9EYXRhWydsaW5rcyddWyd0YWdzJ11bJ2hyZWYnXTsKICAgICAgICAkdGhpcy0+aG9tZVVybCA9ICRyZXBvRGF0YVsnbGlua3MnXVsnaHRtbCddWydocmVmJ107CiAgICAgICAgJHRoaXMtPndlYnNpdGUgPSAkcmVwb0RhdGFbJ3dlYnNpdGUnXTsKICAgICAgICAkdGhpcy0+dmNzVHlwZSA9ICRyZXBvRGF0YVsnc2NtJ107CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5zaG91bGRDYWNoZSgkaWRlbnRpZmllcikgJiYgJHJlcyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkaWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHJlcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0QmFzZUNvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpOwoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNhY2hlLT53cml0ZSgkaWRlbnRpZmllciwganNvbl9lbmNvZGUoJGNvbXBvc2VyKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIC8vIHNwZWNpYWxzIGZvciBiaXRidWNrZXQKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbXBvc2VyWydzdXBwb3J0J11bJ3NvdXJjZSddKSkgewogICAgICAgICAgICAgICAgICAgICRsYWJlbCA9IGFycmF5X3NlYXJjaCgKICAgICAgICAgICAgICAgICAgICAgICAgJGlkZW50aWZpZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5nZXRUYWdzKCkKICAgICAgICAgICAgICAgICAgICApID86IGFycmF5X3NlYXJjaCgKICAgICAgICAgICAgICAgICAgICAgICAgJGlkZW50aWZpZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5nZXRCcmFuY2hlcygpCiAgICAgICAgICAgICAgICAgICAgKSA/OiAkaWRlbnRpZmllcjsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJGxhYmVsLCAkdGFncyA9ICR0aGlzLT5nZXRUYWdzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRoYXNoID0gJHRhZ3NbJGxhYmVsXTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoYXJyYXlfa2V5X2V4aXN0cygkbGFiZWwsICRicmFuY2hlcyA9ICR0aGlzLT5nZXRCcmFuY2hlcygpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaGFzaCA9ICRicmFuY2hlc1skbGFiZWxdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkaGFzaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydzdXBwb3J0J11bJ3NvdXJjZSddID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdodHRwczovLyVzLyVzLyVzL3NyYycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3JpZ2luVXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm93bmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnkKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnc291cmNlJ10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vJXMvJXMvJXMvc3JjLyVzLz9hdD0lcycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3JpZ2luVXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm93bmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaGFzaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYWJlbAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbXBvc2VyWydzdXBwb3J0J11bJ2lzc3VlcyddKSAmJiAkdGhpcy0+aGFzSXNzdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydzdXBwb3J0J11bJ2lzc3VlcyddID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHBzOi8vJXMvJXMvJXMvaXNzdWVzJywKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9yaWdpblVybCwKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm93bmVyLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjb21wb3NlclsnaG9tZXBhZ2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ2hvbWVwYWdlJ10gPSBlbXB0eSgkdGhpcy0+d2Vic2l0ZSkgPyAkdGhpcy0+aG9tZVVybCA6ICR0aGlzLT53ZWJzaXRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXSA9ICRjb21wb3NlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5mb0NhY2hlWyRpZGVudGlmaWVyXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCRpZGVudGlmaWVyLCAnLycpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkYnJhbmNoZXMgPSAkdGhpcy0+Z2V0QnJhbmNoZXMoKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRicmFuY2hlc1skaWRlbnRpZmllcl0pKSB7CiAgICAgICAgICAgICAgICAkaWRlbnRpZmllciA9ICRicmFuY2hlc1skaWRlbnRpZmllcl07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICdodHRwczovL2FwaS5iaXRidWNrZXQub3JnLzIuMC9yZXBvc2l0b3JpZXMvJXMvJXMvc3JjLyVzLyVzJywKICAgICAgICAgICAgJHRoaXMtPm93bmVyLAogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSwKICAgICAgICAgICAgJGlkZW50aWZpZXIsCiAgICAgICAgICAgICRmaWxlCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSktPmdldEJvZHkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJGlkZW50aWZpZXIsICcvJykgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9ICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGJyYW5jaGVzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgICAgICRpZGVudGlmaWVyID0gJGJyYW5jaGVzWyRpZGVudGlmaWVyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gc3ByaW50ZigKICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLmJpdGJ1Y2tldC5vcmcvMi4wL3JlcG9zaXRvcmllcy8lcy8lcy9jb21taXQvJXM/ZmllbGRzPWRhdGUnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICAkaWRlbnRpZmllcgogICAgICAgICk7CiAgICAgICAgJGNvbW1pdCA9ICR0aGlzLT5mZXRjaFdpdGhPQXV0aENyZWRlbnRpYWxzKCRyZXNvdXJjZSktPmRlY29kZUpzb24oKTsKCiAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJGNvbW1pdFsnZGF0ZSddKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldFNvdXJjZSgkaWRlbnRpZmllcik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICR0aGlzLT52Y3NUeXBlLCAndXJsJyA9PiAkdGhpcy0+Z2V0VXJsKCksICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXREaXN0KCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgICR1cmwgPSBzcHJpbnRmKAogICAgICAgICAgICAnaHR0cHM6Ly9iaXRidWNrZXQub3JnLyVzLyVzL2dldC8lcy56aXAnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5LAogICAgICAgICAgICAkaWRlbnRpZmllcgogICAgICAgICk7CgogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ3ppcCcsICd1cmwnID0+ICR1cmwsICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyLCAnc2hhc3VtJyA9PiAnJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmZhbGxiYWNrRHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmdldFRhZ3MoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+dGFncykgewogICAgICAgICAgICAkdGhpcy0+dGFncyA9IGFycmF5KCk7CiAgICAgICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXM/JXMnLAogICAgICAgICAgICAgICAgJHRoaXMtPnRhZ3NVcmwsCiAgICAgICAgICAgICAgICBodHRwX2J1aWxkX3F1ZXJ5KAogICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAncGFnZWxlbicgPT4gMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAnZmllbGRzJyA9PiAndmFsdWVzLm5hbWUsdmFsdWVzLnRhcmdldC5oYXNoLG5leHQnLAogICAgICAgICAgICAgICAgICAgICAgICAnc29ydCcgPT4gJy10YXJnZXQuZGF0ZScsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICcmJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgICAgICAkaGFzTmV4dCA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlICgkaGFzTmV4dCkgewogICAgICAgICAgICAgICAgJHRhZ3NEYXRhID0gJHRoaXMtPmZldGNoV2l0aE9BdXRoQ3JlZGVudGlhbHMoJHJlc291cmNlKS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRhZ3NEYXRhWyd2YWx1ZXMnXSBhcyAkZGF0YSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT50YWdzWyRkYXRhWyduYW1lJ11dID0gJGRhdGFbJ3RhcmdldCddWydoYXNoJ107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHRhZ3NEYXRhWyduZXh0J10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGhhc05leHQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc291cmNlID0gJHRhZ3NEYXRhWyduZXh0J107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT52Y3NUeXBlID09PSAnaGcnKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+dGFnc1sndGlwJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRCcmFuY2hlcygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXMgPSBhcnJheSgpOwogICAgICAgICAgICAkcmVzb3VyY2UgPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgJyVzPyVzJywKICAgICAgICAgICAgICAgICR0aGlzLT5icmFuY2hlc1VybCwKICAgICAgICAgICAgICAgIGh0dHBfYnVpbGRfcXVlcnkoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICdwYWdlbGVuJyA9PiAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICdmaWVsZHMnID0+ICd2YWx1ZXMubmFtZSx2YWx1ZXMudGFyZ2V0Lmhhc2gsdmFsdWVzLmhlYWRzLG5leHQnLAogICAgICAgICAgICAgICAgICAgICAgICAnc29ydCcgPT4gJy10YXJnZXQuZGF0ZScsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICcmJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgICAgICAkaGFzTmV4dCA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlICgkaGFzTmV4dCkgewogICAgICAgICAgICAgICAgJGJyYW5jaERhdGEgPSAkdGhpcy0+ZmV0Y2hXaXRoT0F1dGhDcmVkZW50aWFscygkcmVzb3VyY2UpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYnJhbmNoRGF0YVsndmFsdWVzJ10gYXMgJGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGhlYWRsZXNzIGJyYW5jaGVzIHdoaWNoIHNlZW0gdG8gYmUgZGVsZXRlZCBicmFuY2hlcyB0aGF0IGJpdGJ1Y2tldCBuZXZlcnRoZWxlc3MgcmV0dXJucyBpbiB0aGUgQVBJCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT52Y3NUeXBlID09PSAnaGcnICYmIGVtcHR5KCRkYXRhWydoZWFkcyddKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5icmFuY2hlc1skZGF0YVsnbmFtZSddXSA9ICRkYXRhWyd0YXJnZXQnXVsnaGFzaCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGVtcHR5KCRicmFuY2hEYXRhWyduZXh0J10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGhhc05leHQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc291cmNlID0gJGJyYW5jaERhdGFbJ25leHQnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcmVtb3RlIGNvbnRlbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsICAgICAgICAgICAgICBUaGUgVVJMIG9mIGNvbnRlbnQKICAgICAqIEBwYXJhbSBib29sICAgJGZldGNoaW5nUmVwb0RhdGEKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlc3BvbnNlIFRoZSByZXN1bHQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZldGNoV2l0aE9BdXRoQ3JlZGVudGlhbHMoJHVybCwgJGZldGNoaW5nUmVwb0RhdGEgPSBmYWxzZSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRDb250ZW50cygkdXJsKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGJpdGJ1Y2tldFV0aWwgPSBuZXcgQml0YnVja2V0KCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MsICR0aGlzLT5odHRwRG93bmxvYWRlcik7CgogICAgICAgICAgICBpZiAoNDAzID09PSAkZS0+Z2V0Q29kZSgpIHx8ICg0MDEgPT09ICRlLT5nZXRDb2RlKCkgJiYgc3RycG9zKCRlLT5nZXRNZXNzYWdlKCksICdDb3VsZCBub3QgYXV0aGVudGljYXRlIGFnYWluc3QnKSA9PT0gMCkpIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkdGhpcy0+b3JpZ2luVXJsKQogICAgICAgICAgICAgICAgICAgICYmICRiaXRidWNrZXRVdGlsLT5hdXRob3JpemVPQXV0aCgkdGhpcy0+b3JpZ2luVXJsKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSAmJiAkZmV0Y2hpbmdSZXBvRGF0YSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+YXR0ZW1wdENsb25lRmFsbGJhY2soKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICdkdW1teScpLCAyMDAsIGFycmF5KCksICdudWxsJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCk7CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGF0dGVtcHRDbG9uZUZhbGxiYWNrKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkdGhpcy0+c2V0dXBGYWxsYmFja0RyaXZlcigkdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEcml2ZXIgPSBudWxsOwoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKAogICAgICAgICAgICAgICAgJzxlcnJvcj5GYWlsZWQgdG8gY2xvbmUgdGhlICcgLiAkdGhpcy0+Z2VuZXJhdGVTc2hVcmwoKSAuICcgcmVwb3NpdG9yeSwgdHJ5IHJ1bm5pbmcgaW4gaW50ZXJhY3RpdmUgbW9kZScKICAgICAgICAgICAgICAgICAgICAuICcgc28gdGhhdCB5b3UgY2FuIGVudGVyIHlvdXIgQml0YnVja2V0IE9BdXRoIGNvbnN1bWVyIGNyZWRlbnRpYWxzPC9lcnJvcj4nCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICR1cmwKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0dXBGYWxsYmFja0RyaXZlcigkdXJsKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgYXJyYXkgJGNsb25lTGlua3MKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbG9uZVVybHMoYXJyYXkgJGNsb25lTGlua3MpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGNsb25lTGlua3MgYXMgJGNsb25lTGluaykgewogICAgICAgICAgICBpZiAoJGNsb25lTGlua1snbmFtZSddID09PSAnaHR0cHMnKSB7CiAgICAgICAgICAgICAgICAvLyBGb3JtYXQ6IGh0dHBzOi8vKHVzZXJAKWJpdGJ1Y2tldC5vcmcve3VzZXJ9L3tyZXBvfQogICAgICAgICAgICAgICAgLy8gU3RyaXAgdXNlcm5hbWUgZnJvbSBVUkwgKG9ubHkgcHJlc2VudCBpbiBjbG9uZSBVUkwncyBmb3IgcHJpdmF0ZSByZXBvc2l0b3JpZXMpCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2xvbmVIdHRwc1VybCA9IHByZWdfcmVwbGFjZSgnL2h0dHBzOlwvXC8oW15AXStAKT8vJywgJ2h0dHBzOi8vJywgJGNsb25lTGlua1snaHJlZiddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TWFpbkJyYW5jaERhdGEoKQogICAgewogICAgICAgICRyZXNvdXJjZSA9IHNwcmludGYoCiAgICAgICAgICAgICdodHRwczovL2FwaS5iaXRidWNrZXQub3JnLzIuMC9yZXBvc2l0b3JpZXMvJXMvJXM/ZmllbGRzPW1haW5icmFuY2gnLAogICAgICAgICAgICAkdGhpcy0+b3duZXIsCiAgICAgICAgICAgICR0aGlzLT5yZXBvc2l0b3J5CiAgICAgICAgKTsKCiAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZmV0Y2hXaXRoT0F1dGhDcmVkZW50aWFscygkcmVzb3VyY2UpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydtYWluYnJhbmNoJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAkZGF0YVsnbWFpbmJyYW5jaCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFVybDsKdXNlIENvbXBvc2VyXFV0aWxcR2l0IGFzIEdpdFV0aWw7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdERyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzOwogICAgcHJvdGVjdGVkICRyb290SWRlbnRpZmllcjsKICAgIHByb3RlY3RlZCAkcmVwb0RpcjsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAkdGhpcy0+dXJsID0gcHJlZ19yZXBsYWNlKCd7W1xcL11cLmdpdC8/JH0nLCAnJywgJHRoaXMtPnVybCk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCR0aGlzLT51cmwpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byByZWFkIHBhY2thZ2UgaW5mb3JtYXRpb24gZnJvbSAnLiR0aGlzLT51cmwuJyBhcyB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZXBvRGlyID0gJHRoaXMtPnVybDsKICAgICAgICAgICAgJGNhY2hlVXJsID0gcmVhbHBhdGgoJHRoaXMtPnVybCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFDYWNoZTo6aXNVc2FibGUoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0dpdERyaXZlciByZXF1aXJlcyBhIHVzYWJsZSBjYWNoZSBkaXJlY3RvcnksIGFuZCBpdCBsb29rcyBsaWtlIHlvdSBzZXQgaXQgdG8gYmUgZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnJlcG9EaXIgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSAuICcvJyAuIHByZWdfcmVwbGFjZSgne1teYS16MC05Ll19aScsICctJywgJHRoaXMtPnVybCkgLiAnLyc7CgogICAgICAgICAgICBHaXRVdGlsOjpjbGVhbkVudigpOwoKICAgICAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAgICAgJGZzLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoZGlybmFtZSgkdGhpcy0+cmVwb0RpcikpOwoKICAgICAgICAgICAgaWYgKCFpc193cml0YWJsZShkaXJuYW1lKCR0aGlzLT5yZXBvRGlyKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ2FuIG5vdCBjbG9uZSAnLiR0aGlzLT51cmwuJyB0byBhY2Nlc3MgcGFja2FnZSBpbmZvcm1hdGlvbi4gVGhlICInLmRpcm5hbWUoJHRoaXMtPnJlcG9EaXIpLiciIGRpcmVjdG9yeSBpcyBub3Qgd3JpdGFibGUgYnkgdGhlIGN1cnJlbnQgdXNlci4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tec3NoOi8vW15AXStAW146XSs6W14wLTldK30nLCAkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBzb3VyY2UgVVJMICcuJHRoaXMtPnVybC4nIGlzIGludmFsaWQsIHNzaCBVUkxzIHNob3VsZCBoYXZlIGEgcG9ydCBudW1iZXIgYWZ0ZXIgIjoiLicuIlxuIi4nVXNlIHNzaDovL2dpdEBleGFtcGxlLmNvbToyMi9wYXRoIG9yIGp1c3QgZ2l0QGV4YW1wbGUuY29tOnBhdGggaWYgeW91IGRvIG5vdCB3YW50IHRvIHByb3ZpZGUgYSBwYXNzd29yZCBvciBjdXN0b20gcG9ydC4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGdpdFV0aWwgPSBuZXcgR2l0VXRpbCgkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzLCAkZnMpOwogICAgICAgICAgICBpZiAoISRnaXRVdGlsLT5zeW5jTWlycm9yKCR0aGlzLT51cmwsICR0aGlzLT5yZXBvRGlyKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJHRoaXMtPnJlcG9EaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gY2xvbmUgJy4kdGhpcy0+dXJsLicgdG8gcmVhZCBwYWNrYWdlIGluZm9ybWF0aW9uIGZyb20gaXQnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkZhaWxlZCB0byB1cGRhdGUgJy4kdGhpcy0+dXJsLicsIHBhY2thZ2UgaW5mb3JtYXRpb24gZnJvbSB0aGlzIHJlcG9zaXRvcnkgbWF5IGJlIG91dGRhdGVkPC9lcnJvcj4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNhY2hlVXJsID0gJHRoaXMtPnVybDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5nZXRUYWdzKCk7CiAgICAgICAgJHRoaXMtPmdldEJyYW5jaGVzKCk7CgogICAgICAgICR0aGlzLT5jYWNoZSA9IG5ldyBDYWNoZSgkdGhpcy0+aW8sICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKS4nLycucHJlZ19yZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCBVcmw6OnNhbml0aXplKCRjYWNoZVVybCkpKTsKICAgICAgICAkdGhpcy0+Y2FjaGUtPnNldFJlYWRPbmx5KCR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVhZC1vbmx5JykpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gJ21hc3Rlcic7CgogICAgICAgICAgICAvLyBzZWxlY3QgY3VycmVudGx5IGNoZWNrZWQgb3V0IGJyYW5jaCBpZiBtYXN0ZXIgaXMgbm90IGF2YWlsYWJsZQogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGJyYW5jaCAtLW5vLWNvbG9yJywgJG91dHB1dCwgJHRoaXMtPnJlcG9EaXIpOwogICAgICAgICAgICAkYnJhbmNoZXMgPSAkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KTsKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgnKiBtYXN0ZXInLCAkYnJhbmNoZXMpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYnJhbmNoZXMgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmIHByZWdfbWF0Y2goJ3teXCogKyhcUyspfScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdElkZW50aWZpZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ2dpdCcsICd1cmwnID0+ICR0aGlzLT5nZXRVcmwoKSwgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAkcmVzb3VyY2UgPSBzcHJpbnRmKCclczolcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRpZGVudGlmaWVyKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGZpbGUpKTsKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZShzcHJpbnRmKCdnaXQgc2hvdyAlcycsICRyZXNvdXJjZSksICRjb250ZW50LCAkdGhpcy0+cmVwb0Rpcik7CgogICAgICAgIGlmICghdHJpbSgkY29udGVudCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKHNwcmludGYoCiAgICAgICAgICAgICdnaXQgLWMgbG9nLnNob3dTaWduYXR1cmU9ZmFsc2UgbG9nIC0xIC0tZm9ybWF0PSUlYXQgJXMnLAogICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkaWRlbnRpZmllcikKICAgICAgICApLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKCdAJy50cmltKCRvdXRwdXQpLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgc2hvdy1yZWYgLS10YWdzIC0tZGVyZWZlcmVuY2UnLCAkb3V0cHV0LCAkdGhpcy0+cmVwb0Rpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvdXRwdXQgPSAkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkdGFnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRhZyAmJiBwcmVnX21hdGNoKCd7XihbYS1mMC05XXs0MH0pIHJlZnMvdGFncy8oXFMrPykoXF5ce1x9KT8kfScsICR0YWcsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dGFnc1skbWF0Y2hbMl1dID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBicmFuY2ggLS1uby1jb2xvciAtLW5vLWFiYnJldiAtdicsICRvdXRwdXQsICR0aGlzLT5yZXBvRGlyKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCkgYXMgJGJyYW5jaCkgewogICAgICAgICAgICAgICAgaWYgKCRicmFuY2ggJiYgIXByZWdfbWF0Y2goJ3teICpbXi9dKy9IRUFEIH0nLCAkYnJhbmNoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xig/OlwqICk/ICooXFMrKSAqKFthLWYwLTldKykoPzogLiopPyR9JywgJGJyYW5jaCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJG1hdGNoWzFdXSA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9ICRicmFuY2hlczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcG9ydHMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHVybCwgJGRlZXAgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnIyheZ2l0Oi8vfFwuZ2l0Lz8kfGdpdCg/Om9saXRlKT9AfC8vZ2l0XC58Ly9naXRodWIuY29tLykjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9jYWwgZmlsZXN5c3RlbQogICAgICAgIGlmIChGaWxlc3lzdGVtOjppc0xvY2FsUGF0aCgkdXJsKSkgewogICAgICAgICAgICAkdXJsID0gRmlsZXN5c3RlbTo6Z2V0UGxhdGZvcm1QYXRoKCR1cmwpOwogICAgICAgICAgICBpZiAoIWlzX2RpcigkdXJsKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIGdpdCByZXBvIGluIHRoYXQgcGF0aAogICAgICAgICAgICBpZiAoJHByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCB0YWcnLCAkb3V0cHV0LCAkdXJsKSA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGRlZXApIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGdpdFV0aWwgPSBuZXcgR2l0VXRpbCgkaW8sICRjb25maWcsIG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKSwgbmV3IEZpbGVzeXN0ZW0oKSk7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGdpdFV0aWwtPnJ1bkNvbW1hbmQoZnVuY3Rpb24gKCR1cmwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnZ2l0IGxzLXJlbW90ZSAtLWhlYWRzIC0tICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKTsKICAgICAgICAgICAgfSwgJHVybCwgc3lzX2dldF90ZW1wX2RpcigpKTsKICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIEEgZHJpdmVyIGltcGxlbWVudGF0aW9uIGZvciBkcml2ZXIgd2l0aCBhdXRoZW50aWNhdGlvbiBpbnRlcmFjdGlvbi4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmFic3RyYWN0IGNsYXNzIFZjc0RyaXZlciBpbXBsZW1lbnRzIFZjc0RyaXZlckludGVyZmFjZQp7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkdXJsOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJG9yaWdpblVybDsKICAgIC8qKiBAdmFyIGFycmF5ICovCiAgICBwcm90ZWN0ZWQgJHJlcG9Db25maWc7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgYXJyYXkgKi8KICAgIHByb3RlY3RlZCAkaW5mb0NhY2hlID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIENhY2hlICovCiAgICBwcm90ZWN0ZWQgJGNhY2hlOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAkcmVwb0NvbmZpZyAgICAgVGhlIHJlcG9zaXRvcnkgY29uZmlndXJhdGlvbgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAkaW8gICAgICAgICAgICAgVGhlIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgICAgICRjb25maWcgICAgICAgICBUaGUgY29tcG9zZXIgY29uZmlndXJhdGlvbgogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICAkaHR0cERvd25sb2FkZXIgUmVtb3RlIEZpbGVzeXN0ZW0sIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqIEBwYXJhbSBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgICAgICAgIFByb2Nlc3MgaW5zdGFuY2UsIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqLwogICAgZmluYWwgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXBvQ29uZmlnLCBJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcykKICAgIHsKICAgICAgICBpZiAoRmlsZXN5c3RlbTo6aXNMb2NhbFBhdGgoJHJlcG9Db25maWdbJ3VybCddKSkgewogICAgICAgICAgICAkcmVwb0NvbmZpZ1sndXJsJ10gPSBGaWxlc3lzdGVtOjpnZXRQbGF0Zm9ybVBhdGgoJHJlcG9Db25maWdbJ3VybCddKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT51cmwgPSAkcmVwb0NvbmZpZ1sndXJsJ107CiAgICAgICAgJHRoaXMtPm9yaWdpblVybCA9ICRyZXBvQ29uZmlnWyd1cmwnXTsKICAgICAgICAkdGhpcy0+cmVwb0NvbmZpZyA9ICRyZXBvQ29uZmlnOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGdpdmVuICRpZGVudGlmaWVyIHNob3VsZCBiZSBjYWNoZWQgb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNob3VsZENhY2hlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2FjaGUgJiYgcHJlZ19tYXRjaCgne15bYS1mMC05XXs0MH0kfWlEJywgJGlkZW50aWZpZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSAmJiAkcmVzID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkcmVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2FjaGUtPndyaXRlKCRpZGVudGlmaWVyLCBqc29uX2VuY29kZSgkY29tcG9zZXIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl0gPSAkY29tcG9zZXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl07CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRjb21wb3NlckZpbGVDb250ZW50ID0gJHRoaXMtPmdldEZpbGVDb250ZW50KCdjb21wb3Nlci5qc29uJywgJGlkZW50aWZpZXIpOwoKICAgICAgICBpZiAoISRjb21wb3NlckZpbGVDb250ZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkY29tcG9zZXJGaWxlQ29udGVudCwgJGlkZW50aWZpZXIgLiAnOmNvbXBvc2VyLmpzb24nKTsKCiAgICAgICAgaWYgKGVtcHR5KCRjb21wb3NlclsndGltZSddKSAmJiAkY2hhbmdlRGF0ZSA9ICR0aGlzLT5nZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAkY29tcG9zZXJbJ3RpbWUnXSA9ICRjaGFuZ2VEYXRlLT5mb3JtYXQoREFURV9SRkMzMzM5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNDb21wb3NlckZpbGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIChib29sKSAkdGhpcy0+Z2V0Q29tcG9zZXJJbmZvcm1hdGlvbigkaWRlbnRpZmllcik7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGh0dHBzIG9yIGh0dHAgcHJvdG9jb2wgZGVwZW5kaW5nIG9uIFNTTCBzdXBwb3J0LgogICAgICoKICAgICAqIENhbGwgdGhpcyBvbmx5IGlmIHlvdSBrbm93IHRoYXQgdGhlIHNlcnZlciBzdXBwb3J0cyBib3RoLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBjb3JyZWN0IHR5cGUgb2YgcHJvdG9jb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFNjaGVtZSgpCiAgICB7CiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSkgewogICAgICAgICAgICByZXR1cm4gJ2h0dHBzJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnaHR0cCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHJlbW90ZSBjb250ZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybCBUaGUgVVJMIG9mIGNvbnRlbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlc3BvbnNlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb250ZW50cygkdXJsKQogICAgewogICAgICAgICRvcHRpb25zID0gaXNzZXQoJHRoaXMtPnJlcG9Db25maWdbJ29wdGlvbnMnXSkgPyAkdGhpcy0+cmVwb0NvbmZpZ1snb3B0aW9ucyddIDogYXJyYXkoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR1cmwsICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcR2l0TGFiOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwoKLyoqCiAqIERyaXZlciBmb3IgR2l0TGFiIEFQSSwgdXNlIHRoZSBHaXQgZHJpdmVyIGZvciBsb2NhbCBjaGVja291dHMuCiAqCiAqIEBhdXRob3IgSGVucmlrIEJqw7hybnNrb3YgPGhlbnJpa0BianJuc2tvdi5kaz4KICogQGF1dGhvciBKw6lyw7RtZSBUYW1hcmVsbGUgPGplcm9tZUB0YW1hcmVsbGUubmV0PgogKi8KY2xhc3MgR2l0TGFiRHJpdmVyIGV4dGVuZHMgVmNzRHJpdmVyCnsKICAgIHByaXZhdGUgJHNjaGVtZTsKICAgIHByaXZhdGUgJG5hbWVzcGFjZTsKICAgIHByaXZhdGUgJHJlcG9zaXRvcnk7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IFByb2plY3QgZGF0YSByZXR1cm5lZCBieSBHaXRMYWIgQVBJCiAgICAgKi8KICAgIHByaXZhdGUgJHByb2plY3Q7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IEtlZXBzIGNvbW1pdHMgcmV0dXJuZWQgYnkgR2l0TGFiIEFQSQogICAgICovCiAgICBwcml2YXRlICRjb21taXRzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkgTGlzdCBvZiB0YWcgPT4gcmVmZXJlbmNlCiAgICAgKi8KICAgIHByaXZhdGUgJHRhZ3M7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IExpc3Qgb2YgYnJhbmNoID0+IHJlZmVyZW5jZQogICAgICovCiAgICBwcml2YXRlICRicmFuY2hlczsKCiAgICAvKioKICAgICAqIEdpdCBEcml2ZXIKICAgICAqCiAgICAgKiBAdmFyIEdpdERyaXZlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGdpdERyaXZlcjsKCiAgICAvKioKICAgICAqIERlZmF1bHRzIHRvIHRydWUgdW5sZXNzIHdlIGNhbiBtYWtlIHN1cmUgaXQgaXMgcHVibGljCiAgICAgKgogICAgICogQHZhciBib29sIGRlZmluZXMgd2hldGhlciB0aGUgcmVwbyBpcyBwcml2YXRlIG9yIG5vdAogICAgICovCiAgICBwcml2YXRlICRpc1ByaXZhdGUgPSB0cnVlOwoKICAgIC8qKgogICAgICogQHZhciBib29sIHRydWUgaWYgdGhlIG9yaWdpbiBoYXMgYSBwb3J0IG51bWJlciBvciBhIHBhdGggY29tcG9uZW50IGluIGl0CiAgICAgKi8KICAgIHByaXZhdGUgJGhhc05vbnN0YW5kYXJkT3JpZ2luID0gZmFsc2U7CgogICAgY29uc3QgVVJMX1JFR0VYID0gJyNeKD86KD9QPHNjaGVtZT5odHRwcz8pOi8vKD9QPGRvbWFpbj4uKz8pKD86Oig/UDxwb3J0PlswLTldKykpPy98Z2l0QCg/UDxkb21haW4yPlteOl0rKTopKD9QPHBhcnRzPi4rKS8oP1A8cmVwbz5bXi9dKz8pKD86XC5naXR8Lyk/JCMnOwoKICAgIC8qKgogICAgICogRXh0cmFjdHMgaW5mb3JtYXRpb24gZnJvbSB0aGUgcmVwb3NpdG9yeSB1cmwuCiAgICAgKgogICAgICogU1NIIHVybHMgdXNlIGh0dHBzIGJ5IGRlZmF1bHQuIFNldCAic2VjdXJlLWh0dHAiOiBmYWxzZSBvbiB0aGUgcmVwb3NpdG9yeSBjb25maWcgdG8gdXNlIGh0dHAgaW5zdGVhZC4KICAgICAqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goc2VsZjo6VVJMX1JFR0VYLCAkdGhpcy0+dXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGUgVVJMIHByb3ZpZGVkIGlzIGludmFsaWQuIEl0IG11c3QgYmUgdGhlIEhUVFAgVVJMIG9mIGEgR2l0TGFiIHByb2plY3QuJyk7CiAgICAgICAgfQoKICAgICAgICAkZ3Vlc3NlZERvbWFpbiA9ICFlbXB0eSgkbWF0Y2hbJ2RvbWFpbiddKSA/ICRtYXRjaFsnZG9tYWluJ10gOiAkbWF0Y2hbJ2RvbWFpbjInXTsKICAgICAgICAkY29uZmlndXJlZERvbWFpbnMgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyk7CiAgICAgICAgJHVybFBhcnRzID0gZXhwbG9kZSgnLycsICRtYXRjaFsncGFydHMnXSk7CgogICAgICAgICR0aGlzLT5zY2hlbWUgPSAhZW1wdHkoJG1hdGNoWydzY2hlbWUnXSkKICAgICAgICAgICAgPyAkbWF0Y2hbJ3NjaGVtZSddCiAgICAgICAgICAgIDogKGlzc2V0KCR0aGlzLT5yZXBvQ29uZmlnWydzZWN1cmUtaHR0cCddKSAmJiAkdGhpcy0+cmVwb0NvbmZpZ1snc2VjdXJlLWh0dHAnXSA9PT0gZmFsc2UgPyAnaHR0cCcgOiAnaHR0cHMnKQogICAgICAgIDsKICAgICAgICAkdGhpcy0+b3JpZ2luVXJsID0gc2VsZjo6ZGV0ZXJtaW5lT3JpZ2luKCRjb25maWd1cmVkRG9tYWlucywgJGd1ZXNzZWREb21haW4sICR1cmxQYXJ0cywgJG1hdGNoWydwb3J0J10pOwoKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdGhpcy0+b3JpZ2luVXJsLCAnOicpIHx8IGZhbHNlICE9PSBzdHJwb3MoJHRoaXMtPm9yaWdpblVybCwgJy8nKSkgewogICAgICAgICAgICAkdGhpcy0+aGFzTm9uc3RhbmRhcmRPcmlnaW4gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm5hbWVzcGFjZSA9IGltcGxvZGUoJy8nLCAkdXJsUGFydHMpOwogICAgICAgICR0aGlzLT5yZXBvc2l0b3J5ID0gcHJlZ19yZXBsYWNlKCcjKFwuZ2l0KSQjJywgJycsICRtYXRjaFsncmVwbyddKTsKCiAgICAgICAgJHRoaXMtPmNhY2hlID0gbmV3IENhY2hlKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpLicvJy4kdGhpcy0+b3JpZ2luVXJsLicvJy4kdGhpcy0+bmFtZXNwYWNlLicvJy4kdGhpcy0+cmVwb3NpdG9yeSk7CiAgICAgICAgJHRoaXMtPmNhY2hlLT5zZXRSZWFkT25seSgkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlYWQtb25seScpKTsKCiAgICAgICAgJHRoaXMtPmZldGNoUHJvamVjdCgpOwogICAgfQoKICAgIC8qKgogICAgICogVXBkYXRlcyB0aGUgSHR0cERvd25sb2FkZXIgaW5zdGFuY2UuCiAgICAgKiBNYWlubHkgdXNlZnVsIGZvciB0ZXN0cy4KICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEh0dHBEb3dubG9hZGVyKEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlcikKICAgIHsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmluZm9DYWNoZVskaWRlbnRpZmllcl0pKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2hvdWxkQ2FjaGUoJGlkZW50aWZpZXIpICYmICRyZXMgPSAkdGhpcy0+Y2FjaGUtPnJlYWQoJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXIgPSBKc29uRmlsZTo6cGFyc2VKc29uKCRyZXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldEJhc2VDb21wb3NlckluZm9ybWF0aW9uKCRpZGVudGlmaWVyKTsKCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnNob3VsZENhY2hlKCRpZGVudGlmaWVyKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGlkZW50aWZpZXIsIGpzb25fZW5jb2RlKCRjb21wb3NlcikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICAgICAvLyBzcGVjaWFscyBmb3IgZ2l0bGFiICh0aGlzIGRhdGEgaXMgb25seSBhdmFpbGFibGUgaWYgYXV0aGVudGljYXRpb24gaXMgcHJvdmlkZWQpCiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjb21wb3Nlclsnc3VwcG9ydCddWydpc3N1ZXMnXSkgJiYgaXNzZXQoJHRoaXMtPnByb2plY3RbJ19saW5rcyddWydpc3N1ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tcG9zZXJbJ3N1cHBvcnQnXVsnaXNzdWVzJ10gPSAkdGhpcy0+cHJvamVjdFsnX2xpbmtzJ11bJ2lzc3VlcyddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29tcG9zZXJbJ2FiYW5kb25lZCddKSAmJiAhZW1wdHkoJHRoaXMtPnByb2plY3RbJ2FyY2hpdmVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbXBvc2VyWydhYmFuZG9uZWQnXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdID0gJGNvbXBvc2VyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmZvQ2FjaGVbJGlkZW50aWZpZXJdOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29udmVydCB0aGUgcm9vdCBpZGVudGlmaWVyIHRvIGEgY2FjaGVhYmxlIGNvbW1pdCBpZAogICAgICAgIGlmICghcHJlZ19tYXRjaCgne1thLWYwLTldezQwfX1pJywgJGlkZW50aWZpZXIpKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9ICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGJyYW5jaGVzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgICAgICRpZGVudGlmaWVyID0gJGJyYW5jaGVzWyRpZGVudGlmaWVyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpLicvcmVwb3NpdG9yeS9maWxlcy8nLiR0aGlzLT51cmxFbmNvZGVBbGwoJGZpbGUpLicvcmF3P3JlZj0nLiRpZGVudGlmaWVyOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkY29udGVudCA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVzb3VyY2UpLT5nZXRCb2R5KCk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpICE9PSA0MDQpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5naXREcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXREcml2ZXItPmdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb21taXRzWyRpZGVudGlmaWVyXSkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBcRGF0ZVRpbWUoJHRoaXMtPmNvbW1pdHNbJGlkZW50aWZpZXJdWydjb21taXR0ZWRfZGF0ZSddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3J5VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzUHJpdmF0ZSA/ICR0aGlzLT5wcm9qZWN0Wydzc2hfdXJsX3RvX3JlcG8nXSA6ICR0aGlzLT5wcm9qZWN0WydodHRwX3VybF90b19yZXBvJ107CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRVcmwoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvamVjdFsnd2ViX3VybCddOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdCgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICAkdXJsID0gJHRoaXMtPmdldEFwaVVybCgpLicvcmVwb3NpdG9yeS9hcmNoaXZlLnppcD9zaGE9Jy4kaWRlbnRpZmllcjsKCiAgICAgICAgcmV0dXJuIGFycmF5KCd0eXBlJyA9PiAnemlwJywgJ3VybCcgPT4gJHVybCwgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIsICdzaGFzdW0nID0+ICcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0U291cmNlKCRpZGVudGlmaWVyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgndHlwZScgPT4gJ2dpdCcsICd1cmwnID0+ICR0aGlzLT5nZXRSZXBvc2l0b3J5VXJsKCksICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvamVjdFsnZGVmYXVsdF9icmFuY2gnXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaGVzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdpdERyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdpdERyaXZlci0+Z2V0QnJhbmNoZXMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmJyYW5jaGVzKSB7CiAgICAgICAgICAgICR0aGlzLT5icmFuY2hlcyA9ICR0aGlzLT5nZXRSZWZlcmVuY2VzKCdicmFuY2hlcycpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhZ3MoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2l0RHJpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0RHJpdmVyLT5nZXRUYWdzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0aGlzLT50YWdzID0gJHRoaXMtPmdldFJlZmVyZW5jZXMoJ3RhZ3MnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nIEJhc2UgVVJMIGZvciBHaXRMYWIgQVBJIHYzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcGlVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2NoZW1lLic6Ly8nLiR0aGlzLT5vcmlnaW5VcmwuJy9hcGkvdjQvcHJvamVjdHMvJy4kdGhpcy0+dXJsRW5jb2RlQWxsKCR0aGlzLT5uYW1lc3BhY2UpLiclMkYnLiR0aGlzLT51cmxFbmNvZGVBbGwoJHRoaXMtPnJlcG9zaXRvcnkpOwogICAgfQoKICAgIC8qKgogICAgICogVXJsZW5jb2RlIGFsbCBub24gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuIHJhd3VybGVuY29kZSgpIGNhbiBub3QgYmUgdXNlZCBhcyBpdCBkb2VzIG5vdCBlbmNvZGUgYC5gCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHN0cmluZwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1cmxFbmNvZGVBbGwoJHN0cmluZykKICAgIHsKICAgICAgICAkZW5jb2RlZCA9ICcnOwogICAgICAgIGZvciAoJGkgPSAwOyBpc3NldCgkc3RyaW5nWyRpXSk7ICRpKyspIHsKICAgICAgICAgICAgJGNoYXJhY3RlciA9ICRzdHJpbmdbJGldOwogICAgICAgICAgICBpZiAoIWN0eXBlX2FsbnVtKCRjaGFyYWN0ZXIpICYmICFpbl9hcnJheSgkY2hhcmFjdGVyLCBhcnJheSgnLScsICdfJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkY2hhcmFjdGVyID0gJyUnIC4gc3ByaW50ZignJTAyWCcsIG9yZCgkY2hhcmFjdGVyKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVuY29kZWQgLj0gJGNoYXJhY3RlcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZW5jb2RlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIHdoZXJlIGtleXMgYXJlIG5hbWVkIHJlZmVyZW5jZXMgbGlrZSB0YWdzIG9yIGJyYW5jaGVzIGFuZCB0aGUgdmFsdWUgYSBzaGEKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFJlZmVyZW5jZXMoJHR5cGUpCiAgICB7CiAgICAgICAgJHBlclBhZ2UgPSAxMDA7CiAgICAgICAgJHJlc291cmNlID0gJHRoaXMtPmdldEFwaVVybCgpLicvcmVwb3NpdG9yeS8nLiR0eXBlLic/cGVyX3BhZ2U9Jy4kcGVyUGFnZTsKCiAgICAgICAgJHJlZmVyZW5jZXMgPSBhcnJheSgpOwogICAgICAgIGRvIHsKICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmdldENvbnRlbnRzKCRyZXNvdXJjZSk7CiAgICAgICAgICAgICRkYXRhID0gJHJlc3BvbnNlLT5kZWNvZGVKc29uKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkZGF0YSBhcyAkZGF0dW0pIHsKICAgICAgICAgICAgICAgICRyZWZlcmVuY2VzWyRkYXR1bVsnbmFtZSddXSA9ICRkYXR1bVsnY29tbWl0J11bJ2lkJ107CgogICAgICAgICAgICAgICAgLy8gS2VlcCB0aGUgbGFzdCBjb21taXQgZGF0ZSBvZiBhIHJlZmVyZW5jZSB0byBhdm9pZAogICAgICAgICAgICAgICAgLy8gdW5uZWNlc3NhcnkgQVBJIGNhbGwgd2hlbiByZXRyaWV2aW5nIHRoZSBjb21wb3NlciBmaWxlLgogICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1pdHNbJGRhdHVtWydjb21taXQnXVsnaWQnXV0gPSAkZGF0dW1bJ2NvbW1pdCddOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY291bnQoJGRhdGEpID49ICRwZXJQYWdlKSB7CiAgICAgICAgICAgICAgICAkcmVzb3VyY2UgPSAkdGhpcy0+Z2V0TmV4dFBhZ2UoJHJlc3BvbnNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXNvdXJjZSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSB3aGlsZSAoJHJlc291cmNlKTsKCiAgICAgICAgcmV0dXJuICRyZWZlcmVuY2VzOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaFByb2plY3QoKQogICAgewogICAgICAgIC8vIHdlIG5lZWQgdG8gZmV0Y2ggdGhlIGRlZmF1bHQgYnJhbmNoIGZyb20gdGhlIGFwaQogICAgICAgICRyZXNvdXJjZSA9ICR0aGlzLT5nZXRBcGlVcmwoKTsKICAgICAgICAkdGhpcy0+cHJvamVjdCA9ICR0aGlzLT5nZXRDb250ZW50cygkcmVzb3VyY2UsIHRydWUpLT5kZWNvZGVKc29uKCk7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcm9qZWN0Wyd2aXNpYmlsaXR5J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSAkdGhpcy0+cHJvamVjdFsndmlzaWJpbGl0eSddICE9PSAncHVibGljJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBjbGllbnQgaXMgbm90IGF1dGhlbmRpY2F0ZWQsIHRoZXJlZm9yZSByZXBvc2l0b3J5IGhhcyB0byBiZSBwdWJsaWMKICAgICAgICAgICAgJHRoaXMtPmlzUHJpdmF0ZSA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXR0ZW1wdENsb25lRmFsbGJhY2soKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNQcml2YXRlID09PSBmYWxzZSkgewogICAgICAgICAgICAkdXJsID0gJHRoaXMtPmdlbmVyYXRlUHVibGljVXJsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHVybCA9ICR0aGlzLT5nZW5lcmF0ZVNzaFVybCgpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gSWYgdGhpcyByZXBvc2l0b3J5IG1heSBiZSBwcml2YXRlIGFuZCB3ZQogICAgICAgICAgICAvLyBjYW5ub3QgYXNrIGZvciBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscyAoYmVjYXVzZSB3ZQogICAgICAgICAgICAvLyBhcmUgbm90IGludGVyYWN0aXZlKSB0aGVuIHdlIGZhbGxiYWNrIHRvIEdpdERyaXZlci4KICAgICAgICAgICAgJHRoaXMtPnNldHVwR2l0RHJpdmVyKCR1cmwpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmdpdERyaXZlciA9IG51bGw7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5GYWlsZWQgdG8gY2xvbmUgdGhlICcuJHVybC4nIHJlcG9zaXRvcnksIHRyeSBydW5uaW5nIGluIGludGVyYWN0aXZlIG1vZGUgc28gdGhhdCB5b3UgY2FuIGVudGVyIHlvdXIgY3JlZGVudGlhbHM8L2Vycm9yPicpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBTU0ggVVJMCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhc05vbnN0YW5kYXJkT3JpZ2luKSB7CiAgICAgICAgICAgIHJldHVybiAnc3NoOi8vZ2l0QCcuJHRoaXMtPm9yaWdpblVybC4nLycuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdnaXRAJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnOicuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZW5lcmF0ZVB1YmxpY1VybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zY2hlbWUgLiAnOi8vJyAuICR0aGlzLT5vcmlnaW5VcmwgLiAnLycuJHRoaXMtPm5hbWVzcGFjZS4nLycuJHRoaXMtPnJlcG9zaXRvcnkuJy5naXQnOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXR1cEdpdERyaXZlcigkdXJsKQogICAgewogICAgICAgICR0aGlzLT5naXREcml2ZXIgPSBuZXcgR2l0RHJpdmVyKAogICAgICAgICAgICBhcnJheSgndXJsJyA9PiAkdXJsKSwKICAgICAgICAgICAgJHRoaXMtPmlvLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLAogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIsCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Z2l0RHJpdmVyLT5pbml0aWFsaXplKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb250ZW50cygkdXJsLCAkZmV0Y2hpbmdSZXBvRGF0YSA9IGZhbHNlKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXNwb25zZSA9IHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CgogICAgICAgICAgICBpZiAoJGZldGNoaW5nUmVwb0RhdGEpIHsKICAgICAgICAgICAgICAgICRqc29uID0gJHJlc3BvbnNlLT5kZWNvZGVKc29uKCk7CgogICAgICAgICAgICAgICAgLy8gQWNjZXNzaW5nIHRoZSBBUEkgd2l0aCBhIHRva2VuIHdpdGggR3Vlc3QgKDEwKSBhY2Nlc3Mgd2lsbCByZXR1cm4KICAgICAgICAgICAgICAgIC8vIG1vcmUgZGF0YSB0aGFuIHVuYXV0aGVudGljYXRlZCBhY2Nlc3MgYnV0IG5vIGRlZmF1bHRfYnJhbmNoIGRhdGEKICAgICAgICAgICAgICAgIC8vIGFjY2Vzc2luZyBmaWxlcyB2aWEgdGhlIEFQSSB3aWxsIHRoZW4gYWxzbyBmYWlsCiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRqc29uWydkZWZhdWx0X2JyYW5jaCddKSAmJiBpc3NldCgkanNvblsncGVybWlzc2lvbnMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aXNQcml2YXRlID0gJGpzb25bJ3Zpc2liaWxpdHknXSAhPT0gJ3B1YmxpYyc7CgogICAgICAgICAgICAgICAgICAgICRtb3JlVGhhbkd1ZXN0QWNjZXNzID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgYm90aCBhY2Nlc3MgbGV2ZWxzIChlLmcuIHByb2plY3QsIGdyb3VwKQogICAgICAgICAgICAgICAgICAgIC8vIC0gdmFsdWUgd2lsbCBiZSBudWxsIGlmIG5vIGFjY2VzcyBpcyBzZXQKICAgICAgICAgICAgICAgICAgICAvLyAtIHZhbHVlIHdpbGwgYmUgYXJyYXkgd2l0aCBrZXkgYWNjZXNzX2xldmVsIGlmIHNldAogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRqc29uWydwZXJtaXNzaW9ucyddIGFzICRwZXJtaXNzaW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcGVybWlzc2lvbiAmJiAkcGVybWlzc2lvblsnYWNjZXNzX2xldmVsJ10gPiAxMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1vcmVUaGFuR3Vlc3RBY2Nlc3MgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoISRtb3JlVGhhbkd1ZXN0QWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+R2l0TGFiIHRva2VuIHdpdGggR3Vlc3Qgb25seSBhY2Nlc3MgZGV0ZWN0ZWQ8L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmF0dGVtcHRDbG9uZUZhbGxiYWNrKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGZvcmNlIGF1dGggYXMgdGhlIHVuYXV0aGVudGljYXRlZCB2ZXJzaW9uIG9mIHRoZSBBUEkgaXMgYnJva2VuCiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRqc29uWydkZWZhdWx0X2JyYW5jaCddKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJGpzb25bJ2lkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pc1ByaXZhdGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0dpdExhYiBBUEkgc2VlbXMgdG8gbm90IGJlIGF1dGhlbnRpY2F0ZWQgYXMgaXQgZGlkIG5vdCByZXR1cm4gYSBkZWZhdWx0X2JyYW5jaCcsIDQwMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzcG9uc2U7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRnaXRMYWJVdGlsID0gbmV3IEdpdExhYigkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzLCAkdGhpcy0+aHR0cERvd25sb2FkZXIpOwoKICAgICAgICAgICAgc3dpdGNoICgkZS0+Z2V0Q29kZSgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIDQwMToKICAgICAgICAgICAgICAgIGNhc2UgNDA0OgogICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBhdXRob3JpemUgb25seSBpZiB3ZSBhcmUgZmV0Y2hpbmcgdGhlIG1haW4gL3JlcG9zL2Zvby9iYXIgZGF0YSwgb3RoZXJ3aXNlIGl0IG11c3QgYmUgYSByZWFsIDQwNAogICAgICAgICAgICAgICAgICAgIGlmICghJGZldGNoaW5nUmVwb0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJGdpdExhYlV0aWwtPmF1dGhvcml6ZU9BdXRoKCR0aGlzLT5vcmlnaW5VcmwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmF0dGVtcHRDbG9uZUZhbGxiYWNrKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoYXJyYXkoJ3VybCcgPT4gJ2R1bW15JyksIDIwMCwgYXJyYXkoKSwgJ251bGwnKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkZhaWxlZCB0byBkb3dubG9hZCAnIC4gJHRoaXMtPm5hbWVzcGFjZSAuICcvJyAuICR0aGlzLT5yZXBvc2l0b3J5IC4gJzonIC4gJGUtPmdldE1lc3NhZ2UoKSAuICc8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgJGdpdExhYlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkdGhpcy0+c2NoZW1lLCAkdGhpcy0+b3JpZ2luVXJsLCAnWW91ciBjcmVkZW50aWFscyBhcmUgcmVxdWlyZWQgdG8gZmV0Y2ggcHJpdmF0ZSByZXBvc2l0b3J5IG1ldGFkYXRhICg8aW5mbz4nLiR0aGlzLT51cmwuJzwvaW5mbz4pJyk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmdldENvbnRlbnRzKCR1cmwpOwoKICAgICAgICAgICAgICAgIGNhc2UgNDAzOgogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkdGhpcy0+b3JpZ2luVXJsKSAmJiAkZ2l0TGFiVXRpbC0+YXV0aG9yaXplT0F1dGgoJHRoaXMtPm9yaWdpblVybCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6Z2V0Q29udGVudHMoJHVybCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpICYmICRmZXRjaGluZ1JlcG9EYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+YXR0ZW1wdENsb25lRmFsbGJhY2soKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAnZHVtbXknKSwgMjAwLCBhcnJheSgpLCAnbnVsbCcpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVXNlcyB0aGUgY29uZmlnIGBnaXRsYWItZG9tYWluc2AgdG8gc2VlIGlmIHRoZSBkcml2ZXIgc3VwcG9ydHMgdGhlIHVybCBmb3IgdGhlCiAgICAgKiByZXBvc2l0b3J5IGdpdmVuLgogICAgICoKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0cyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkdXJsLCAkZGVlcCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaChzZWxmOjpVUkxfUkVHRVgsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHNjaGVtZSA9ICFlbXB0eSgkbWF0Y2hbJ3NjaGVtZSddKSA/ICRtYXRjaFsnc2NoZW1lJ10gOiBudWxsOwogICAgICAgICRndWVzc2VkRG9tYWluID0gIWVtcHR5KCRtYXRjaFsnZG9tYWluJ10pID8gJG1hdGNoWydkb21haW4nXSA6ICRtYXRjaFsnZG9tYWluMiddOwogICAgICAgICR1cmxQYXJ0cyA9IGV4cGxvZGUoJy8nLCAkbWF0Y2hbJ3BhcnRzJ10pOwoKICAgICAgICBpZiAoZmFsc2UgPT09IHNlbGY6OmRldGVybWluZU9yaWdpbigoYXJyYXkpICRjb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSwgJGd1ZXNzZWREb21haW4sICR1cmxQYXJ0cywgJG1hdGNoWydwb3J0J10pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgnaHR0cHMnID09PSAkc2NoZW1lICYmICFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdTa2lwcGluZyBHaXRMYWIgZHJpdmVyIGZvciAnLiR1cmwuJyBiZWNhdXNlIHRoZSBPcGVuU1NMIFBIUCBleHRlbnNpb24gaXMgbWlzc2luZy4nLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TmV4dFBhZ2UoUmVzcG9uc2UgJHJlc3BvbnNlKQogICAgewogICAgICAgICRoZWFkZXIgPSAkcmVzcG9uc2UtPmdldEhlYWRlcignbGluaycpOwoKICAgICAgICAkbGlua3MgPSBleHBsb2RlKCcsJywgJGhlYWRlcik7CiAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7PCguKz8pPjsgKnJlbD0ibmV4dCJ9JywgJGxpbmssICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICRjb25maWd1cmVkRG9tYWlucwogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkZ3Vlc3NlZERvbWFpbgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAkdXJsUGFydHMKICAgICAqIEByZXR1cm4gYm9vbHxzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZGV0ZXJtaW5lT3JpZ2luKGFycmF5ICRjb25maWd1cmVkRG9tYWlucywgJGd1ZXNzZWREb21haW4sIGFycmF5ICYkdXJsUGFydHMsICRwb3J0TnVtYmVyKQogICAgewogICAgICAgICRndWVzc2VkRG9tYWluID0gc3RydG9sb3dlcigkZ3Vlc3NlZERvbWFpbik7CgogICAgICAgIGlmIChpbl9hcnJheSgkZ3Vlc3NlZERvbWFpbiwgJGNvbmZpZ3VyZWREb21haW5zKSB8fCAoJHBvcnROdW1iZXIgJiYgaW5fYXJyYXkoJGd1ZXNzZWREb21haW4uJzonLiRwb3J0TnVtYmVyLCAkY29uZmlndXJlZERvbWFpbnMpKSkgewogICAgICAgICAgICBpZiAoJHBvcnROdW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZ3Vlc3NlZERvbWFpbi4nOicuJHBvcnROdW1iZXI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkZ3Vlc3NlZERvbWFpbjsKICAgICAgICB9CgogICAgICAgIGlmICgkcG9ydE51bWJlcikgewogICAgICAgICAgICAkZ3Vlc3NlZERvbWFpbiAuPSAnOicuJHBvcnROdW1iZXI7CiAgICAgICAgfQoKICAgICAgICB3aGlsZSAobnVsbCAhPT0gKCRwYXJ0ID0gYXJyYXlfc2hpZnQoJHVybFBhcnRzKSkpIHsKICAgICAgICAgICAgJGd1ZXNzZWREb21haW4gLj0gJy8nIC4gJHBhcnQ7CgogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGd1ZXNzZWREb21haW4sICRjb25maWd1cmVkRG9tYWlucykgfHwgKCRwb3J0TnVtYmVyICYmIGluX2FycmF5KHByZWdfcmVwbGFjZSgnezpcZCt9JywgJycsICRndWVzc2VkRG9tYWluKSwgJGNvbmZpZ3VyZWREb21haW5zKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZ3Vlc3NlZERvbWFpbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENhY2hlOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFV0aWxcUGVyZm9yY2U7CgovKioKICogQGF1dGhvciBNYXR0IFdoaXR0b20gPE1hdHQuV2hpdHRvbUB2ZXRlcmFuc3VuaXRlZC5jb20+CiAqLwpjbGFzcyBQZXJmb3JjZURyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICBwcm90ZWN0ZWQgJGRlcG90OwogICAgcHJvdGVjdGVkICRicmFuY2g7CiAgICAvKiogQHZhciBQZXJmb3JjZSAqLwogICAgcHJvdGVjdGVkICRwZXJmb3JjZTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgICR0aGlzLT5kZXBvdCA9ICR0aGlzLT5yZXBvQ29uZmlnWydkZXBvdCddOwogICAgICAgICR0aGlzLT5icmFuY2ggPSAnJzsKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5yZXBvQ29uZmlnWydicmFuY2gnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaCA9ICR0aGlzLT5yZXBvQ29uZmlnWydicmFuY2gnXTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pbml0UGVyZm9yY2UoJHRoaXMtPnJlcG9Db25maWcpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+cDRMb2dpbigpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+Y2hlY2tTdHJlYW0oKTsKCiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT53cml0ZVA0Q2xpZW50U3BlYygpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZS0+Y29ubmVjdENsaWVudCgpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRQZXJmb3JjZSgkcmVwb0NvbmZpZykKICAgIHsKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5wZXJmb3JjZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFDYWNoZTo6aXNVc2FibGUoJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignUGVyZm9yY2VEcml2ZXIgcmVxdWlyZXMgYSB1c2FibGUgY2FjaGUgZGlyZWN0b3J5LCBhbmQgaXQgbG9va3MgbGlrZSB5b3Ugc2V0IGl0IHRvIGJlIGRpc2FibGVkJyk7CiAgICAgICAgfQoKICAgICAgICAkcmVwb0RpciA9ICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpIC4gJy8nIC4gJHRoaXMtPmRlcG90OwogICAgICAgICR0aGlzLT5wZXJmb3JjZSA9IFBlcmZvcmNlOjpjcmVhdGUoJHJlcG9Db25maWcsICR0aGlzLT5nZXRVcmwoKSwgJHJlcG9EaXIsICR0aGlzLT5wcm9jZXNzLCAkdGhpcy0+aW8pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGVyZm9yY2UtPmdldEZpbGVDb250ZW50KCRmaWxlLCAkaWRlbnRpZmllcik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGFuZ2VEYXRlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QnJhbmNoZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGVyZm9yY2UtPmdldEJyYW5jaGVzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBlcmZvcmNlLT5nZXRUYWdzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0KCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3R5cGUnID0+ICdwZXJmb3JjZScsCiAgICAgICAgICAgICd1cmwnID0+ICR0aGlzLT5yZXBvQ29uZmlnWyd1cmwnXSwKICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJGlkZW50aWZpZXIsCiAgICAgICAgICAgICdwNHVzZXInID0+ICR0aGlzLT5wZXJmb3JjZS0+Z2V0VXNlcigpLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29tcG9zZXJGaWxlKCRpZGVudGlmaWVyKQogICAgewogICAgICAgICRjb21wb3NlckluZm8gPSAkdGhpcy0+cGVyZm9yY2UtPmdldENvbXBvc2VySW5mb3JtYXRpb24oJy8vJyAuICR0aGlzLT5kZXBvdCAuICcvJyAuICRpZGVudGlmaWVyKTsKCiAgICAgICAgcmV0dXJuICFlbXB0eSgkY29tcG9zZXJJbmZvKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRzKCR1cmwpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRkZWVwIHx8IHByZWdfbWF0Y2goJyNcYihwZXJmb3JjZXxwNClcYiNpJywgJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIFBlcmZvcmNlOjpjaGVja1NlcnZlckV4aXN0cygkdXJsLCBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5jbGVhbnVwQ2xpZW50U3BlYygpOwogICAgICAgICR0aGlzLT5wZXJmb3JjZSA9IG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERlcG90KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlcG90OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2goKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YnJhbmNoOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnlcVmNzOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgUGVyIEJlcm5oYXJkdCA8cGxiQHdlYmZhY3RvcnkuZGU+CiAqLwpjbGFzcyBHaXRCaXRidWNrZXREcml2ZXIgZXh0ZW5kcyBCaXRidWNrZXREcml2ZXIKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSb290SWRlbnRpZmllcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mYWxsYmFja0RyaXZlcikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5yb290SWRlbnRpZmllcikgewogICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRSZXBvRGF0YSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRHJpdmVyLT5nZXRSb290SWRlbnRpZmllcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnZjc1R5cGUgIT09ICdnaXQnKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVybC4nIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIGdpdCByZXBvc2l0b3J5LCB1c2UgJy4KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xvbmVIdHRwc1VybC4nIGlmIHRoaXMgaXMgYSBtZXJjdXJpYWwgYml0YnVja2V0IHJlcG9zaXRvcnknCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWFpbkJyYW5jaERhdGEgPSAkdGhpcy0+Z2V0TWFpbkJyYW5jaERhdGEoKTsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gIWVtcHR5KCRtYWluQnJhbmNoRGF0YVsnbmFtZSddKSA/ICRtYWluQnJhbmNoRGF0YVsnbmFtZSddIDogJ21hc3Rlcic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RJZGVudGlmaWVyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1cHBvcnRzKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsICR1cmwsICRkZWVwID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcjXmh0dHBzPzovL2JpdGJ1Y2tldFwub3JnLyhbXi9dKykvKC4rPylcLmdpdCQjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignU2tpcHBpbmcgQml0YnVja2V0IGdpdCBkcml2ZXIgZm9yICcuJHVybC4nIGJlY2F1c2UgdGhlIE9wZW5TU0wgUEhQIGV4dGVuc2lvbiBpcyBtaXNzaW5nLicsIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0dXBGYWxsYmFja0RyaXZlcigkdXJsKQogICAgewogICAgICAgICR0aGlzLT5mYWxsYmFja0RyaXZlciA9IG5ldyBHaXREcml2ZXIoCiAgICAgICAgICAgIGFycmF5KCd1cmwnID0+ICR1cmwpLAogICAgICAgICAgICAkdGhpcy0+aW8sCiAgICAgICAgICAgICR0aGlzLT5jb25maWcsCiAgICAgICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciwKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MKICAgICAgICApOwogICAgICAgICR0aGlzLT5mYWxsYmFja0RyaXZlci0+aW5pdGlhbGl6ZSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2VuZXJhdGVTc2hVcmwoKQogICAgewogICAgICAgIHJldHVybiAnZ2l0QCcgLiAkdGhpcy0+b3JpZ2luVXJsIC4gJzonIC4gJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeS4nLmdpdCc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3M7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBQZXIgQmVybmhhcmR0IDxwbGJAd2ViZmFjdG9yeS5kZT4KICovCmNsYXNzIEhnQml0YnVja2V0RHJpdmVyIGV4dGVuZHMgQml0YnVja2V0RHJpdmVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdElkZW50aWZpZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tEcml2ZXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cm9vdElkZW50aWZpZXIpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+Z2V0UmVwb0RhdGEoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RyaXZlci0+Z2V0Um9vdElkZW50aWZpZXIoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT52Y3NUeXBlICE9PSAnaGcnKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVybC4nIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIG1lcmN1cmlhbCByZXBvc2l0b3J5LCB1c2UgJy4KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xvbmVIdHRwc1VybC4nIGlmIHRoaXMgaXMgYSBnaXQgYml0YnVja2V0IHJlcG9zaXRvcnknCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWFpbkJyYW5jaERhdGEgPSAkdGhpcy0+Z2V0TWFpbkJyYW5jaERhdGEoKTsKICAgICAgICAgICAgJHRoaXMtPnJvb3RJZGVudGlmaWVyID0gIWVtcHR5KCRtYWluQnJhbmNoRGF0YVsnbmFtZSddKSA/ICRtYWluQnJhbmNoRGF0YVsnbmFtZSddIDogJ2RlZmF1bHQnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290SWRlbnRpZmllcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0cyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkdXJsLCAkZGVlcCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnI15odHRwcz86Ly9iaXRidWNrZXRcLm9yZy8oW14vXSspLyhbXi9dKykvPyQjaScsICR1cmwpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignU2tpcHBpbmcgQml0YnVja2V0IGhnIGRyaXZlciBmb3IgJy4kdXJsLicgYmVjYXVzZSB0aGUgT3BlblNTTCBQSFAgZXh0ZW5zaW9uIGlzIG1pc3NpbmcuJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXR1cEZhbGxiYWNrRHJpdmVyKCR1cmwpCiAgICB7CiAgICAgICAgJHRoaXMtPmZhbGxiYWNrRHJpdmVyID0gbmV3IEhnRHJpdmVyKAogICAgICAgICAgICBhcnJheSgndXJsJyA9PiAkdXJsKSwKICAgICAgICAgICAgJHRoaXMtPmlvLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLAogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIsCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEcml2ZXItPmluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlU3NoVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3NzaDovL2hnQCcgLiAkdGhpcy0+b3JpZ2luVXJsIC4gJy8nIC4gJHRoaXMtPm93bmVyLicvJy4kdGhpcy0+cmVwb3NpdG9yeTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjczsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBCb2h3YVogPGh0dHA6Ly9ib2h3YXoubmV0Lz4KICovCmNsYXNzIEZvc3NpbERyaXZlciBleHRlbmRzIFZjc0RyaXZlcgp7CiAgICBwcm90ZWN0ZWQgJHRhZ3M7CiAgICBwcm90ZWN0ZWQgJGJyYW5jaGVzOwogICAgcHJvdGVjdGVkICRyb290SWRlbnRpZmllcjsKICAgIHByb3RlY3RlZCAkcmVwb0ZpbGU7CiAgICBwcm90ZWN0ZWQgJGNoZWNrb3V0RGlyOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgLy8gTWFrZSBzdXJlIGZvc3NpbCBpcyBpbnN0YWxsZWQgYW5kIHJlYWNoYWJsZS4KICAgICAgICAkdGhpcy0+Y2hlY2tGb3NzaWwoKTsKCiAgICAgICAgLy8gRW5zdXJlIHdlIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGlzIFVSTCBieSBjb25maWcuCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdGhpcy0+dXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICAvLyBPbmx5IGlmIHVybCBwb2ludHMgdG8gYSBsb2NhbGx5IGFjY2Vzc2libGUgZGlyZWN0b3J5LCBhc3N1bWUgaXQncyB0aGUgY2hlY2tvdXQgZGlyZWN0b3J5LgogICAgICAgIC8vIE90aGVyd2lzZSwgaXQgc2hvdWxkIGJlIHNvbWV0aGluZyBmb3NzaWwgY2FuIGNsb25lIGZyb20uCiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR0aGlzLT51cmwpICYmIGlzX2RpcigkdGhpcy0+dXJsKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tvdXREaXIgPSAkdGhpcy0+dXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghQ2FjaGU6OmlzVXNhYmxlKCR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKSkgfHwgIUNhY2hlOjppc1VzYWJsZSgkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRm9zc2lsRHJpdmVyIHJlcXVpcmVzIGEgdXNhYmxlIGNhY2hlIGRpcmVjdG9yeSwgYW5kIGl0IGxvb2tzIGxpa2UgeW91IHNldCBpdCB0byBiZSBkaXNhYmxlZCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9jYWxOYW1lID0gcHJlZ19yZXBsYWNlKCd7W15hLXowLTldfWknLCAnLScsICR0aGlzLT51cmwpOwogICAgICAgICAgICAkdGhpcy0+cmVwb0ZpbGUgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXJlcG8tZGlyJykgLiAnLycgLiAkbG9jYWxOYW1lIC4gJy5mb3NzaWwnOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tvdXREaXIgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKSAuICcvJyAuICRsb2NhbE5hbWUgLiAnLyc7CgogICAgICAgICAgICAkdGhpcy0+dXBkYXRlTG9jYWxSZXBvKCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Z2V0VGFncygpOwogICAgICAgICR0aGlzLT5nZXRCcmFuY2hlcygpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgdGhhdCBmb3NzaWwgY2FuIGJlIGludm9rZWQgdmlhIGNvbW1hbmQgbGluZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrRm9zc2lsKCkKICAgIHsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCB2ZXJzaW9uJywgJGlnbm9yZWRPdXRwdXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiZm9zc2lsIHdhcyBub3QgZm91bmQsIGNoZWNrIHRoYXQgaXQgaXMgaW5zdGFsbGVkIGFuZCBpbiB5b3VyIFBBVEggZW52LlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsb25lIG9yIHVwZGF0ZSBleGlzdGluZyBsb2NhbCBmb3NzaWwgcmVwb3NpdG9yeS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZUxvY2FsUmVwbygpCiAgICB7CiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkZnMtPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGhpcy0+Y2hlY2tvdXREaXIpOwoKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKGRpcm5hbWUoJHRoaXMtPmNoZWNrb3V0RGlyKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW4gbm90IGNsb25lICcuJHRoaXMtPnVybC4nIHRvIGFjY2VzcyBwYWNrYWdlIGluZm9ybWF0aW9uLiBUaGUgIicuJHRoaXMtPmNoZWNrb3V0RGlyLiciIGRpcmVjdG9yeSBpcyBub3Qgd3JpdGFibGUgYnkgdGhlIGN1cnJlbnQgdXNlci4nKTsKICAgICAgICB9CgogICAgICAgIC8vIHVwZGF0ZSB0aGUgcmVwbyBpZiBpdCBpcyBhIHZhbGlkIGZvc3NpbCByZXBvc2l0b3J5CiAgICAgICAgaWYgKGlzX2ZpbGUoJHRoaXMtPnJlcG9GaWxlKSAmJiBpc19kaXIoJHRoaXMtPmNoZWNrb3V0RGlyKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZm9zc2lsIGluZm8nLCAkb3V0cHV0LCAkdGhpcy0+Y2hlY2tvdXREaXIpKSB7CiAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZm9zc2lsIHB1bGwnLCAkb3V0cHV0LCAkdGhpcy0+Y2hlY2tvdXREaXIpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5GYWlsZWQgdG8gdXBkYXRlICcuJHRoaXMtPnVybC4nLCBwYWNrYWdlIGluZm9ybWF0aW9uIGZyb20gdGhpcyByZXBvc2l0b3J5IG1heSBiZSBvdXRkYXRlZCAoJy4kdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKS4nKTwvZXJyb3I+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBjbGVhbiB1cCBkaXJlY3RvcnkgYW5kIGRvIGEgZnJlc2ggY2xvbmUgaW50byBpdAogICAgICAgICAgICAkZnMtPnJlbW92ZURpcmVjdG9yeSgkdGhpcy0+Y2hlY2tvdXREaXIpOwogICAgICAgICAgICAkZnMtPnJlbW92ZSgkdGhpcy0+cmVwb0ZpbGUpOwoKICAgICAgICAgICAgJGZzLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJHRoaXMtPmNoZWNrb3V0RGlyKTsKCiAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZShzcHJpbnRmKCdmb3NzaWwgY2xvbmUgLS0gJXMgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGhpcy0+dXJsKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRoaXMtPnJlcG9GaWxlKSksICRvdXRwdXQpKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gY2xvbmUgJy4kdGhpcy0+dXJsLicgdG8gcmVwb3NpdG9yeSAnIC4gJHRoaXMtPnJlcG9GaWxlIC4gIlxuXG4iIC4kb3V0cHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKHNwcmludGYoJ2Zvc3NpbCBvcGVuIC0tbmVzdGVkIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRoaXMtPnJlcG9GaWxlKSksICRvdXRwdXQsICR0aGlzLT5jaGVja291dERpcikpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgPSAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKTsKCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBvcGVuIHJlcG9zaXRvcnkgJy4kdGhpcy0+cmVwb0ZpbGUuJyBpbiAnIC4gJHRoaXMtPmNoZWNrb3V0RGlyIC4gIlxuXG4iIC4kb3V0cHV0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnJvb3RJZGVudGlmaWVyKSB7CiAgICAgICAgICAgICR0aGlzLT5yb290SWRlbnRpZmllciA9ICd0cnVuayc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RJZGVudGlmaWVyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgkaWRlbnRpZmllcikKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoJ3R5cGUnID0+ICdmb3NzaWwnLCAndXJsJyA9PiAkdGhpcy0+Z2V0VXJsKCksICdyZWZlcmVuY2UnID0+ICRpZGVudGlmaWVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3QoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlQ29udGVudCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdmb3NzaWwgY2F0IC1yICVzIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGlkZW50aWZpZXIpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkpOwogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkY29udGVudCwgJHRoaXMtPmNoZWNrb3V0RGlyKTsKCiAgICAgICAgaWYgKCF0cmltKCRjb250ZW50KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZURhdGUoJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBmaW5mbyAtYiAtbiAxIGNvbXBvc2VyLmpzb24nLCAkb3V0cHV0LCAkdGhpcy0+Y2hlY2tvdXREaXIpOwogICAgICAgIGxpc3QoLCAkZGF0ZSkgPSBleHBsb2RlKCcgJywgdHJpbSgkb3V0cHV0KSwgMyk7CgogICAgICAgIHJldHVybiBuZXcgXERhdGVUaW1lKCRkYXRlLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT50YWdzKSB7CiAgICAgICAgICAgICR0YWdzID0gYXJyYXkoKTsKCiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgdGFnIGxpc3QnLCAkb3V0cHV0LCAkdGhpcy0+Y2hlY2tvdXREaXIpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkdGFnKSB7CiAgICAgICAgICAgICAgICAkdGFnc1skdGFnXSA9ICR0YWc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT50YWdzID0gJHRhZ3M7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCcmFuY2hlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5icmFuY2hlcykgewogICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgpOwoKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBicmFuY2ggbGlzdCcsICRvdXRwdXQsICR0aGlzLT5jaGVja291dERpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcm9jZXNzLT5zcGxpdExpbmVzKCRvdXRwdXQpIGFzICRicmFuY2gpIHsKICAgICAgICAgICAgICAgICRicmFuY2ggPSB0cmltKHByZWdfcmVwbGFjZSgnL15cKi8nLCAnJywgdHJpbSgkYnJhbmNoKSkpOwogICAgICAgICAgICAgICAgJGJyYW5jaGVzWyRicmFuY2hdID0gJGJyYW5jaDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmJyYW5jaGVzID0gJGJyYW5jaGVzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5icmFuY2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0cyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkdXJsLCAkZGVlcCA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcjKF4oPzpodHRwcz98c3NoKTovLyg/OlteQF1AKT8oPzpjaGlzZWxhcHBcLmNvbXxmb3NzaWxcLikpI2knLCAkdXJsKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChwcmVnX21hdGNoKCchL2Zvc3NpbC98XC5mb3NzaWwhJywgJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBsb2NhbCBmaWxlc3lzdGVtCiAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR1cmwpKSB7CiAgICAgICAgICAgICR1cmwgPSBGaWxlc3lzdGVtOjpnZXRQbGF0Zm9ybVBhdGgoJHVybCk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCR1cmwpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGEgZm9zc2lsIHJlcG8gaW4gdGhhdCBwYXRoCiAgICAgICAgICAgIGlmICgkcHJvY2Vzcy0+ZXhlY3V0ZSgnZm9zc2lsIGluZm8nLCAkb3V0cHV0LCAkdXJsKSA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxTdGFiaWxpdHlGaWx0ZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKCi8qKgogKiBBIHJlcG9zaXRvcnkgaW1wbGVtZW50YXRpb24gdGhhdCBzaW1wbHkgc3RvcmVzIHBhY2thZ2VzIGluIGFuIGFycmF5CiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBBcnJheVJlcG9zaXRvcnkgaW1wbGVtZW50cyBSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2VbXSAqLwogICAgcHJvdGVjdGVkICRwYWNrYWdlczsKCiAgICAvKioKICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZVtdIGluZGV4ZWQgYnkgcGFja2FnZSB1bmlxdWUgbmFtZSBhbmQgdXNlZCB0byBjYWNoZSBoYXNQYWNrYWdlIGNhbGxzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFja2FnZU1hcDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHBhY2thZ2VzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgIHJldHVybiAnYXJyYXkgcmVwbyAoZGVmaW5pbmcgJy4kdGhpcy0+Y291bnQoKS4nIHBhY2thZ2UnLigkdGhpcy0+Y291bnQoKSA+IDEgPyAncycgOiAnJykuJyknOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Z2V0UGFja2FnZXMoKTsKCiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgJG5hbWVzRm91bmQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZU1hcCkpIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAoISRwYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldIHx8ICRwYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldLT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSkKICAgICAgICAgICAgICAgICAgICAmJiBTdGFiaWxpdHlGaWx0ZXI6OmlzUGFja2FnZUFjY2VwdGFibGUoJGFjY2VwdGFibGVTdGFiaWxpdGllcywgJHN0YWJpbGl0eUZsYWdzLCAkcGFja2FnZS0+Z2V0TmFtZXMoKSwgJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpKQogICAgICAgICAgICAgICAgICAgICYmICFpc3NldCgkYWxyZWFkeUxvYWRlZFskcGFja2FnZS0+Z2V0TmFtZSgpXVskcGFja2FnZS0+Z2V0VmVyc2lvbigpXSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBzZWxlY3RlZCBwYWNrYWdlcyB3aGljaCBtYXRjaCBzdGFiaWxpdHkgcmVxdWlyZW1lbnRzCiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgYWxpYXNlZCBwYWNrYWdlIGZvciBwYWNrYWdlcyB3aGVyZSB0aGUgYWxpYXMgbWF0Y2hlcwogICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAhaXNzZXQoJHJlc3VsdFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UtPmdldEFsaWFzT2YoKSldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZS0+Z2V0QWxpYXNPZigpKV0gPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbmFtZXNGb3VuZFskcGFja2FnZS0+Z2V0TmFtZSgpXSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGFkZCBhbGlhc2VzIG9mIHBhY2thZ2VzIHRoYXQgd2VyZSBzZWxlY3RlZCwgZXZlbiBpZiB0aGUgYWxpYXNlcyBkaWQgbm90IG1hdGNoCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXN1bHRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgnbmFtZXNGb3VuZCcgPT4gYXJyYXlfa2V5cygkbmFtZXNGb3VuZCksICdwYWNrYWdlcycgPT4gJHJlc3VsdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZSgkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKCiAgICAgICAgaWYgKCEkY29uc3RyYWludCBpbnN0YW5jZW9mIENvbnN0cmFpbnRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICAgICAkY29uc3RyYWludCA9ICR2ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkbmFtZSA9PT0gJHBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgJHBrZ0NvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgIGlmICgkY29uc3RyYWludC0+bWF0Y2hlcygkcGtnQ29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2VzKCRuYW1lLCAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gbm9ybWFsaXplIG5hbWUKICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CgogICAgICAgIGlmIChudWxsICE9PSAkY29uc3RyYWludCAmJiAhJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBDb25zdHJhaW50SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJG5hbWUgPT09ICRwYWNrYWdlLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSAkY29uc3RyYWludCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNbXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhY2thZ2VzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCRxdWVyeSwgJG1vZGUgPSAwLCAkdHlwZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHJlZ2V4ID0gJ3soPzonLmltcGxvZGUoJ3wnLCBwcmVnX3NwbGl0KCd7XHMrfScsICRxdWVyeSkpLicpfWknOwoKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHJlZ2V4LCAkbmFtZSkKICAgICAgICAgICAgICAgIHx8ICgkbW9kZSA9PT0gc2VsZjo6U0VBUkNIX0ZVTExURVhUICYmICRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmIHByZWdfbWF0Y2goJHJlZ2V4LCBpbXBsb2RlKCcgJywgKGFycmF5KSAkcGFja2FnZS0+Z2V0S2V5d29yZHMoKSkgLiAnICcgLiAkcGFja2FnZS0+Z2V0RGVzY3JpcHRpb24oKSkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgaWYgKG51bGwgIT09ICR0eXBlICYmICRwYWNrYWdlLT5nZXRUeXBlKCkgIT09ICR0eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG1hdGNoZXNbJG5hbWVdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgJ2Rlc2NyaXB0aW9uJyA9PiAkcGFja2FnZSBpbnN0YW5jZW9mIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSA/ICRwYWNrYWdlLT5nZXREZXNjcmlwdGlvbigpIDogbnVsbCwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV92YWx1ZXMoJG1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cGFja2FnZU1hcCA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+cGFja2FnZU1hcCA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQYWNrYWdlcygpIGFzICRyZXBvUGFja2FnZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2VNYXBbJHJlcG9QYWNrYWdlLT5nZXRVbmlxdWVOYW1lKCldID0gJHJlcG9QYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPnBhY2thZ2VNYXBbJHBhY2thZ2UtPmdldFVuaXF1ZU5hbWUoKV0pOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBwYWNrYWdlIHRvIHRoZSByZXBvc2l0b3J5CiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnBhY2thZ2VzKSB7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CiAgICAgICAgfQogICAgICAgICRwYWNrYWdlLT5zZXRSZXBvc2l0b3J5KCR0aGlzKTsKICAgICAgICAkdGhpcy0+cGFja2FnZXNbXSA9ICRwYWNrYWdlOwoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgJGFsaWFzZWRQYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRhbGlhc2VkUGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgkYWxpYXNlZFBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpbnZhbGlkYXRlIHBhY2thZ2UgbWFwIGNhY2hlCiAgICAgICAgJHRoaXMtPnBhY2thZ2VNYXAgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHJlc3VsdFskY2FuZGlkYXRlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZS0+Z2V0UHJvdmlkZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlTmFtZSA9PT0gJGxpbmstPmdldFRhcmdldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFskY2FuZGlkYXRlLT5nZXROYW1lKCldID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICduYW1lJyA9PiAkY2FuZGlkYXRlLT5nZXROYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gJGNhbmRpZGF0ZS0+Z2V0RGVzY3JpcHRpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3R5cGUnID0+ICRjYW5kaWRhdGUtPmdldFR5cGUoKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVBbGlhc1BhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGFsaWFzLCAkcHJldHR5QWxpYXMpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBBbGlhc1BhY2thZ2UoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgPyAkcGFja2FnZS0+Z2V0QWxpYXNPZigpIDogJHBhY2thZ2UsICRhbGlhcywgJHByZXR0eUFsaWFzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgcGFja2FnZSBmcm9tIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSAkcGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAka2V5ID0+ICRyZXBvUGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2VJZCA9PT0gJHJlcG9QYWNrYWdlLT5nZXRVbmlxdWVOYW1lKCkpIHsKICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkdGhpcy0+cGFja2FnZXMsICRrZXksIDEpOwoKICAgICAgICAgICAgICAgIC8vIGludmFsaWRhdGUgcGFja2FnZSBtYXAgY2FjaGUKICAgICAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlTWFwID0gbnVsbDsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5wYWNrYWdlcykgewogICAgICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBwYWNrYWdlcyBpbiB0aGlzIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBOdW1iZXIgb2YgcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnBhY2thZ2VzKSB7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPnBhY2thZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBwYWNrYWdlcyBhcnJheS4gTW9zdGx5IG1lYW50IGFzIGFuIGV4dGVuc2lvbiBwb2ludC4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRpYWxpemUoKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlcyA9IGFycmF5KCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCi8qKgogKiBMb2NrIGFycmF5IHJlcG9zaXRvcnkuCiAqCiAqIFJlZ3VsYXIgYXJyYXkgcmVwb3NpdG9yeSwgb25seSB1c2VzIGEgZGlmZmVyZW50IHR5cGUgdG8gaWRlbnRpZnkgdGhlIGxvY2sgZmlsZSBhcyB0aGUgc291cmNlIG9mIGluZm8KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIExvY2tBcnJheVJlcG9zaXRvcnkgZXh0ZW5kcyBBcnJheVJlcG9zaXRvcnkKewogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2xvY2sgcmVwbyc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CgovKioKICogUmVwb3NpdG9yaWVzIG1hbmFnZXIuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmNsYXNzIFJlcG9zaXRvcnlNYW5hZ2VyCnsKICAgIC8qKiBAdmFyIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGxvY2FsUmVwb3NpdG9yeTsKICAgIC8qKiBAdmFyIGxpc3Q8UmVwb3NpdG9yeUludGVyZmFjZT4gKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcmllcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIHN0cmluZz4gKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcnlDbGFzc2VzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgLyoqIEB2YXIgP0V2ZW50RGlzcGF0Y2hlciAqLwogICAgcHJpdmF0ZSAkZXZlbnREaXNwYXRjaGVyOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcml2YXRlICRwcm9jZXNzOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIsIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyID0gbnVsbCwgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoZXMgZm9yIGEgcGFja2FnZSBieSBpdCdzIG5hbWUgYW5kIHZlcnNpb24gaW4gbWFuYWdlZCByZXBvc2l0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8XENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVwb3NpdG9yaWVzIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkgKi8KICAgICAgICAgICAgaWYgKCRwYWNrYWdlID0gJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZWFyY2hlcyBmb3IgYWxsIHBhY2thZ2VzIG1hdGNoaW5nIGEgbmFtZSBhbmQgb3B0aW9uYWxseSBhIHZlcnNpb24gaW4gbWFuYWdlZCByZXBvc2l0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8XENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgcGFja2FnZSB2ZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBtYXRjaCBhZ2FpbnN0CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFJlcG9zaXRvcmllcygpIGFzICRyZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5X21lcmdlKCRwYWNrYWdlcywgJHJlcG9zaXRvcnktPmZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeSByZXBvc2l0b3J5IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcmllc1tdID0gJHJlcG9zaXRvcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgcmVwb3NpdG9yeSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjaGFpbgogICAgICoKICAgICAqIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW5qZWN0aW5nIGFkZGl0aW9uYWwgcmVwb3NpdG9yaWVzIHRoYXQgc2hvdWxkIHRydW1wIFBhY2thZ2lzdCwgZS5nLiBmcm9tIGEgcGx1Z2luLgogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5IHJlcG9zaXRvcnkgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBlbmRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgYXJyYXlfdW5zaGlmdCgkdGhpcy0+cmVwb3NpdG9yaWVzLCAkcmVwb3NpdG9yeSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmV3IHJlcG9zaXRvcnkgZm9yIGEgc3BlY2lmaWMgaW5zdGFsbGF0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0eXBlICAgcmVwb3NpdG9yeSB0eXBlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgICAgICAgICAgICAgJGNvbmZpZyByZXBvc2l0b3J5IGNvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkbmFtZSAgIHJlcG9zaXRvcnkgbmFtZQogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHJlcG9zaXRvcnkgZm9yIHByb3ZpZGVkIHR5cGUgaXMgbm90IHJlZ2lzdGVyZWQKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUmVwb3NpdG9yeSgkdHlwZSwgJGNvbmZpZywgJG5hbWUgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlcG9zaXRvcnlDbGFzc2VzWyR0eXBlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1JlcG9zaXRvcnkgdHlwZSBpcyBub3QgcmVnaXN0ZXJlZDogJy4kdHlwZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1sncGFja2FnaXN0J10pICYmIGZhbHNlID09PSAkY29uZmlnWydwYWNrYWdpc3QnXSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlJlcG9zaXRvcnkgIicuJG5hbWUuJyIgKCcuanNvbl9lbmNvZGUoJGNvbmZpZykuJykgaGFzIGEgcGFja2FnaXN0IGtleSB3aGljaCBzaG91bGQgYmUgaW4gaXRzIG93biByZXBvc2l0b3J5IGRlZmluaXRpb248L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICAkY2xhc3MgPSAkdGhpcy0+cmVwb3NpdG9yeUNsYXNzZXNbJHR5cGVdOwoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snb25seSddKSB8fCBpc3NldCgkY29uZmlnWydleGNsdWRlJ10pIHx8IGlzc2V0KCRjb25maWdbJ2Nhbm9uaWNhbCddKSkgewogICAgICAgICAgICAkZmlsdGVyQ29uZmlnID0gJGNvbmZpZzsKICAgICAgICAgICAgdW5zZXQoJGNvbmZpZ1snb25seSddLCAkY29uZmlnWydleGNsdWRlJ10sICRjb25maWdbJ2Nhbm9uaWNhbCddKTsKICAgICAgICB9CgogICAgICAgICRyZXBvc2l0b3J5ID0gbmV3ICRjbGFzcygkY29uZmlnLCAkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5odHRwRG93bmxvYWRlciwgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciwgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICBpZiAoaXNzZXQoJGZpbHRlckNvbmZpZykpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcnkgPSBuZXcgRmlsdGVyUmVwb3NpdG9yeSgkcmVwb3NpdG9yeSwgJGZpbHRlckNvbmZpZyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcG9zaXRvcnk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZXMgcmVwb3NpdG9yeSBjbGFzcyBmb3IgYSBzcGVjaWZpYyBpbnN0YWxsYXRpb24gdHlwZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlICBpbnN0YWxsYXRpb24gdHlwZQogICAgICogQHBhcmFtIHN0cmluZyAkY2xhc3MgY2xhc3MgbmFtZSBvZiB0aGUgcmVwbyBpbXBsZW1lbnRhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yeUNsYXNzKCR0eXBlLCAkY2xhc3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlDbGFzc2VzWyR0eXBlXSA9ICRjbGFzczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIHJlcG9zaXRvcmllcywgZXhjZXB0IGxvY2FsIG9uZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgbG9jYWwgcmVwb3NpdG9yeSBmb3IgdGhlIHByb2plY3QuCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkgcmVwb3NpdG9yeSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9jYWxSZXBvc2l0b3J5KEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2FsUmVwb3NpdG9yeSA9ICRyZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBsb2NhbCByZXBvc2l0b3J5IGZvciB0aGUgcHJvamVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2FsUmVwb3NpdG9yeSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NhbFJlcG9zaXRvcnk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlcjsKCi8qKgogKiBXcml0YWJsZSByZXBvc2l0b3J5IGludGVyZmFjZS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBXcml0YWJsZVJlcG9zaXRvcnlJbnRlcmZhY2UgZXh0ZW5kcyBSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogV3JpdGVzIHJlcG9zaXRvcnkgKGYuZS4gdG8gdGhlIGRpc2MpLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRkZXZNb2RlIFdoZXRoZXIgZGV2IHJlcXVpcmVtZW50cyB3ZXJlIGluY2x1ZGVkIG9yIG5vdCBpbiB0aGlzIGluc3RhbGxhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJGRldk1vZGUsIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIpOwoKICAgIC8qKgogICAgICogQWRkcyBwYWNrYWdlIHRvIHRoZSByZXBvc2l0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHBhY2thZ2UgZnJvbSB0aGUgcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpOwoKICAgIC8qKgogICAgICogR2V0IHVuaXF1ZSBwYWNrYWdlcyAoYXQgbW9zdCBvbmUgcGFja2FnZSBvZiBlYWNoIG5hbWUpLCB3aXRoIGFsaWFzZXMgcmVzb2x2ZWQgYW5kIHJlbW92ZWQuCiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENhbm9uaWNhbFBhY2thZ2VzKCk7CgogICAgLyoqCiAgICAgKiBGb3JjZXMgYSByZWxvYWQgb2YgYWxsIHBhY2thZ2VzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVsb2FkKCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGRldlBhY2thZ2VOYW1lcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2UGFja2FnZU5hbWVzKGFycmF5ICRkZXZQYWNrYWdlTmFtZXMpOwoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXSBOYW1lcyBvZiBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkIHRocm91Z2ggcmVxdWlyZS1kZXYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlBhY2thZ2VOYW1lcygpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBSb290IHBhY2thZ2UgcmVwb3NpdG9yeS4KICoKICogVGhpcyBpcyB1c2VkIGZvciBzZXJ2aW5nIHRoZSBSb290UGFja2FnZSBpbnNpZGUgYW4gaW4tbWVtb3J5IEluc3RhbGxlZFJlcG9zaXRvcnkKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUm9vdFBhY2thZ2VSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSb290UGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KGFycmF5KCRwYWNrYWdlKSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9OYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3Jvb3QgcGFja2FnZSByZXBvJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJlcG9zaXRvcnlGYWN0b3J5CnsKICAgIC8qKgogICAgICogQHBhcmFtICBJT0ludGVyZmFjZSAkaW8KICAgICAqIEBwYXJhbSAgQ29uZmlnICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkcmVwb3NpdG9yeQogICAgICogQHBhcmFtICBib29sICAgICAgICAkYWxsb3dGaWxlc3lzdGVtCiAgICAgKiBAcmV0dXJuIGFycmF5fG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29uZmlnRnJvbVN0cmluZyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkcmVwb3NpdG9yeSwgJGFsbG93RmlsZXN5c3RlbSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgwID09PSBzdHJwb3MoJHJlcG9zaXRvcnksICdodHRwJykpIHsKICAgICAgICAgICAgJHJlcG9Db25maWcgPSBhcnJheSgndHlwZScgPT4gJ2NvbXBvc2VyJywgJ3VybCcgPT4gJHJlcG9zaXRvcnkpOwogICAgICAgIH0gZWxzZWlmICgianNvbiIgPT09IHBhdGhpbmZvKCRyZXBvc2l0b3J5LCBQQVRISU5GT19FWFRFTlNJT04pKSB7CiAgICAgICAgICAgICRqc29uID0gbmV3IEpzb25GaWxlKCRyZXBvc2l0b3J5LCBGYWN0b3J5OjpjcmVhdGVIdHRwRG93bmxvYWRlcigkaW8sICRjb25maWcpKTsKICAgICAgICAgICAgJGRhdGEgPSAkanNvbi0+cmVhZCgpOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydwYWNrYWdlcyddKSB8fCAhZW1wdHkoJGRhdGFbJ2luY2x1ZGVzJ10pIHx8ICFlbXB0eSgkZGF0YVsncHJvdmlkZXItaW5jbHVkZXMnXSkpIHsKICAgICAgICAgICAgICAgICRyZXBvQ29uZmlnID0gYXJyYXkoJ3R5cGUnID0+ICdjb21wb3NlcicsICd1cmwnID0+ICdmaWxlOi8vJyAuIHN0cnRyKHJlYWxwYXRoKCRyZXBvc2l0b3J5KSwgJ1xcJywgJy8nKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkYWxsb3dGaWxlc3lzdGVtKSB7CiAgICAgICAgICAgICAgICAkcmVwb0NvbmZpZyA9IGFycmF5KCd0eXBlJyA9PiAnZmlsZXN5c3RlbScsICdqc29uJyA9PiAkanNvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByZXBvc2l0b3J5IFVSTCAoJHJlcG9zaXRvcnkpIGdpdmVuLiBUaGlzIGZpbGUgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGNvbXBvc2VyIHJlcG9zaXRvcnkuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCRyZXBvc2l0b3J5LCAneycpID09PSAwKSB7CiAgICAgICAgICAgIC8vIGFzc3VtZSBpdCBpcyBhIGpzb24gb2JqZWN0IHRoYXQgbWFrZXMgYSByZXBvIGNvbmZpZwogICAgICAgICAgICAkcmVwb0NvbmZpZyA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHJlcG9zaXRvcnkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHJlcG9zaXRvcnkgdXJsICgkcmVwb3NpdG9yeSkgZ2l2ZW4uIEhhcyB0byBiZSBhIC5qc29uIGZpbGUsIGFuIGh0dHAgdXJsIG9yIGEgSlNPTiBvYmplY3QuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcG9Db25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICRyZXBvc2l0b3J5CiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgJGFsbG93RmlsZXN5c3RlbQogICAgICogQHJldHVybiBSZXBvc2l0b3J5SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZyhJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkcmVwb3NpdG9yeSwgJGFsbG93RmlsZXN5c3RlbSA9IGZhbHNlLCBSZXBvc2l0b3J5TWFuYWdlciAkcm0gPSBudWxsKQogICAgewogICAgICAgICRyZXBvQ29uZmlnID0gc3RhdGljOjpjb25maWdGcm9tU3RyaW5nKCRpbywgJGNvbmZpZywgJHJlcG9zaXRvcnksICRhbGxvd0ZpbGVzeXN0ZW0pOwoKICAgICAgICByZXR1cm4gc3RhdGljOjpjcmVhdGVSZXBvKCRpbywgJGNvbmZpZywgJHJlcG9Db25maWcsICRybSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlICAgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICRyZXBvQ29uZmlnCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVSZXBvKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIGFycmF5ICRyZXBvQ29uZmlnLCBSZXBvc2l0b3J5TWFuYWdlciAkcm0gPSBudWxsKQogICAgewogICAgICAgIGlmICghJHJtKSB7CiAgICAgICAgICAgICRybSA9IHN0YXRpYzo6bWFuYWdlcigkaW8sICRjb25maWcsIEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZykpOwogICAgICAgIH0KICAgICAgICAkcmVwb3MgPSBzdGF0aWM6OmNyZWF0ZVJlcG9zKCRybSwgYXJyYXkoJHJlcG9Db25maWcpKTsKCiAgICAgICAgcmV0dXJuIHJlc2V0KCRyZXBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElPSW50ZXJmYWNlfG51bGwgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbmZpZ3xudWxsICAgICAgICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtICBSZXBvc2l0b3J5TWFuYWdlcnxudWxsICRybQogICAgICogQHJldHVybiBSZXBvc2l0b3J5SW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZWZhdWx0UmVwb3MoSU9JbnRlcmZhY2UgJGlvID0gbnVsbCwgQ29uZmlnICRjb25maWcgPSBudWxsLCBSZXBvc2l0b3J5TWFuYWdlciAkcm0gPSBudWxsKQogICAgewogICAgICAgIGlmICghJGNvbmZpZykgewogICAgICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCRpbyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW8pIHsKICAgICAgICAgICAgJGlvLT5sb2FkQ29uZmlndXJhdGlvbigkY29uZmlnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkcm0pIHsKICAgICAgICAgICAgaWYgKCEkaW8pIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGlzIGZ1bmN0aW9uIHJlcXVpcmVzIGVpdGhlciBhbiBJT0ludGVyZmFjZSBvciBhIFJlcG9zaXRvcnlNYW5hZ2VyJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJtID0gc3RhdGljOjptYW5hZ2VyKCRpbywgJGNvbmZpZywgRmFjdG9yeTo6Y3JlYXRlSHR0cERvd25sb2FkZXIoJGlvLCAkY29uZmlnKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RhdGljOjpjcmVhdGVSZXBvcygkcm0sICRjb25maWctPmdldFJlcG9zaXRvcmllcygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAgICAgJGlvCiAgICAgKiBAcGFyYW0gIENvbmZpZyAgICAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSAgRXZlbnREaXNwYXRjaGVyICAgJGV2ZW50RGlzcGF0Y2hlcgogICAgICogQHBhcmFtICBIdHRwRG93bmxvYWRlciAgICAkaHR0cERvd25sb2FkZXIKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeU1hbmFnZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYW5hZ2VyKElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICRybSA9IG5ldyBSZXBvc2l0b3J5TWFuYWdlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJGV2ZW50RGlzcGF0Y2hlciwgJHByb2Nlc3MpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdjb21wb3NlcicsICdDb21wb3NlclxSZXBvc2l0b3J5XENvbXBvc2VyUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCd2Y3MnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3BhY2thZ2UnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxQYWNrYWdlUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdwZWFyJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcUGVhclJlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnZ2l0JywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdnaXQtYml0YnVja2V0JywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdnaXRodWInLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ2dpdGxhYicsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnc3ZuJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdmb3NzaWwnLCAnQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Jyk7CiAgICAgICAgJHJtLT5zZXRSZXBvc2l0b3J5Q2xhc3MoJ3BlcmZvcmNlJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdoZycsICdDb21wb3NlclxSZXBvc2l0b3J5XFZjc1JlcG9zaXRvcnknKTsKICAgICAgICAkcm0tPnNldFJlcG9zaXRvcnlDbGFzcygnaGctYml0YnVja2V0JywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcVmNzUmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdhcnRpZmFjdCcsICdDb21wb3NlclxSZXBvc2l0b3J5XEFydGlmYWN0UmVwb3NpdG9yeScpOwogICAgICAgICRybS0+c2V0UmVwb3NpdG9yeUNsYXNzKCdwYXRoJywgJ0NvbXBvc2VyXFJlcG9zaXRvcnlcUGF0aFJlcG9zaXRvcnknKTsKCiAgICAgICAgcmV0dXJuICRybTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZVJlcG9zKFJlcG9zaXRvcnlNYW5hZ2VyICRybSwgYXJyYXkgJHJlcG9Db25maWdzKQogICAgewogICAgICAgICRyZXBvcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRyZXBvQ29uZmlncyBhcyAkaW5kZXggPT4gJHJlcG8pIHsKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkcmVwbykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCcicmVwb3NpdG9yaWVzIiBzaG91bGQgYmUgYW4gYXJyYXkgb2YgcmVwb3NpdG9yeSBkZWZpbml0aW9ucywgb25seSBhIHNpbmdsZSByZXBvc2l0b3J5IHdhcyBnaXZlbicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHJlcG8pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignUmVwb3NpdG9yeSAiJy4kaW5kZXguJyIgKCcuanNvbl9lbmNvZGUoJHJlcG8pLicpIHNob3VsZCBiZSBhbiBhcnJheSwgJy5nZXR0eXBlKCRyZXBvKS4nIGdpdmVuJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkcmVwb1sndHlwZSddKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1JlcG9zaXRvcnkgIicuJGluZGV4LiciICgnLmpzb25fZW5jb2RlKCRyZXBvKS4nKSBtdXN0IGhhdmUgYSB0eXBlIGRlZmluZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5hbWUgPSBzZWxmOjpnZW5lcmF0ZVJlcG9zaXRvcnlOYW1lKCRpbmRleCwgJHJlcG8sICRyZXBvcyk7CiAgICAgICAgICAgIGlmICgkcmVwb1sndHlwZSddID09PSAnZmlsZXN5c3RlbScpIHsKICAgICAgICAgICAgICAgICRyZXBvc1skbmFtZV0gPSBuZXcgRmlsZXN5c3RlbVJlcG9zaXRvcnkoJHJlcG9bJ2pzb24nXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVwb3NbJG5hbWVdID0gJHJtLT5jcmVhdGVSZXBvc2l0b3J5KCRyZXBvWyd0eXBlJ10sICRyZXBvLCAkaW5kZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlcG9zOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVSZXBvc2l0b3J5TmFtZSgkaW5kZXgsIGFycmF5ICRyZXBvLCBhcnJheSAkZXhpc3RpbmdSZXBvcykKICAgIHsKICAgICAgICAkbmFtZSA9IGlzX2ludCgkaW5kZXgpICYmIGlzc2V0KCRyZXBvWyd1cmwnXSkgPyBwcmVnX3JlcGxhY2UoJ3teaHR0cHM/Oi8vfWknLCAnJywgJHJlcG9bJ3VybCddKSA6ICRpbmRleDsKICAgICAgICB3aGlsZSAoaXNzZXQoJGV4aXN0aW5nUmVwb3NbJG5hbWVdKSkgewogICAgICAgICAgICAkbmFtZSAuPSAnMic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5hbWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCi8qKgogKiBFeGNlcHRpb24gdGhyb3duIHdoZW4gYSBwYWNrYWdlIHJlcG9zaXRvcnkgaXMgdXR0ZXJseSBicm9rZW4KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSW52YWxpZFJlcG9zaXRvcnlFeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKLyoqCiAqIENvbmZpZ3VyYWJsZSByZXBvc2l0b3J5IGludGVyZmFjZS4KICoKICogQGF1dGhvciBMdWthcyBIb216YSA8bHVrYXNob216QGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBDb25maWd1cmFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvQ29uZmlnKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwoKLyoqCiAqIEZpbGVzeXN0ZW0gcmVwb3NpdG9yeS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgRmlsZXN5c3RlbVJlcG9zaXRvcnkgZXh0ZW5kcyBXcml0YWJsZUFycmF5UmVwb3NpdG9yeQp7CiAgICBwcm90ZWN0ZWQgJGZpbGU7CiAgICBwcml2YXRlICRkdW1wVmVyc2lvbnM7CiAgICBwcml2YXRlICRyb290UGFja2FnZTsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIGZpbGVzeXN0ZW0gcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gSnNvbkZpbGUgICAgICAgICAgICAgICRyZXBvc2l0b3J5RmlsZSByZXBvc2l0b3J5IGpzb24gZmlsZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAkZHVtcFZlcnNpb25zCiAgICAgKiBAcGFyYW0gP1Jvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSAgICBNdXN0IGJlIHByb3ZpZGVkIGlmICRkdW1wVmVyc2lvbnMgaXMgdHJ1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSnNvbkZpbGUgJHJlcG9zaXRvcnlGaWxlLCAkZHVtcFZlcnNpb25zID0gZmFsc2UsIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgICAgICR0aGlzLT5maWxlID0gJHJlcG9zaXRvcnlGaWxlOwogICAgICAgICR0aGlzLT5kdW1wVmVyc2lvbnMgPSAkZHVtcFZlcnNpb25zOwogICAgICAgICR0aGlzLT5yb290UGFja2FnZSA9ICRyb290UGFja2FnZTsKICAgICAgICBpZiAoJGR1bXBWZXJzaW9ucyAmJiAhJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdFeHBlY3RlZCBhIHJvb3QgcGFja2FnZSBpbnN0YW5jZSBpZiAkZHVtcFZlcnNpb25zIGlzIHRydWUnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyByZXBvc2l0b3J5IChyZWFkcyBmaWxlLCBvciByZW1vdGUgYWRkcmVzcykuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBwYXJlbnQ6OmluaXRpYWxpemUoKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+ZmlsZS0+ZXhpc3RzKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZmlsZS0+cmVhZCgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ3BhY2thZ2VzJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZXMgPSAkZGF0YVsncGFja2FnZXMnXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICRkYXRhOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ2Rldi1wYWNrYWdlLW5hbWVzJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2V0RGV2UGFja2FnZU5hbWVzKCRkYXRhWydkZXYtcGFja2FnZS1uYW1lcyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignQ291bGQgbm90IHBhcnNlIHBhY2thZ2UgbGlzdCBmcm9tIHRoZSByZXBvc2l0b3J5Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUmVwb3NpdG9yeUV4Y2VwdGlvbignSW52YWxpZCByZXBvc2l0b3J5IGRhdGEgaW4gJy4kdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpLicsIHBhY2thZ2VzIGNvdWxkIG5vdCBiZSBsb2FkZWQ6IFsnLmdldF9jbGFzcygkZSkuJ10gJy4kZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICB9CgogICAgICAgICRsb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIobnVsbCwgdHJ1ZSk7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlRGF0YSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRsb2FkZXItPmxvYWQoJHBhY2thZ2VEYXRhKTsKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVsb2FkKCkKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZXMgPSBudWxsOwogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgd3JpdGFibGUgcmVwb3NpdG9yeS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRkZXZNb2RlLCBJbnN0YWxsYXRpb25NYW5hZ2VyICRpbnN0YWxsYXRpb25NYW5hZ2VyKQogICAgewogICAgICAgICRkYXRhID0gYXJyYXkoJ3BhY2thZ2VzJyA9PiBhcnJheSgpLCAnZGV2JyA9PiAkZGV2TW9kZSwgJ2Rldi1wYWNrYWdlLW5hbWVzJyA9PiBhcnJheSgpKTsKICAgICAgICAkZHVtcGVyID0gbmV3IEFycmF5RHVtcGVyKCk7CiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkcmVwb0RpciA9IGRpcm5hbWUoJGZzLT5ub3JtYWxpemVQYXRoKCR0aGlzLT5maWxlLT5nZXRQYXRoKCkpKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldENhbm9uaWNhbFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHBrZ0FycmF5ID0gJGR1bXBlci0+ZHVtcCgkcGFja2FnZSk7CiAgICAgICAgICAgICRwYXRoID0gJGluc3RhbGxhdGlvbk1hbmFnZXItPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgICAgICAgICAgJHBrZ0FycmF5WydpbnN0YWxsLXBhdGgnXSA9ICgnJyAhPT0gJHBhdGggJiYgbnVsbCAhPT0gJHBhdGgpID8gJGZzLT5maW5kU2hvcnRlc3RQYXRoKCRyZXBvRGlyLCAkZnMtPmlzQWJzb2x1dGVQYXRoKCRwYXRoKSA/ICRwYXRoIDogZ2V0Y3dkKCkgLiAnLycgLiAkcGF0aCwgdHJ1ZSkgOiBudWxsOwogICAgICAgICAgICAkZGF0YVsncGFja2FnZXMnXVtdID0gJHBrZ0FycmF5OwoKICAgICAgICAgICAgLy8gb25seSB3cml0ZSB0byB0aGUgZmlsZXMgdGhlIG5hbWVzIHdoaWNoIGFyZSByZWFsbHkgaW5zdGFsbGVkLCBhcyB3ZSByZWNlaXZlIHRoZSBmdWxsIGxpc3QKICAgICAgICAgICAgLy8gb2YgZGV2IHBhY2thZ2UgbmFtZXMgYmVmb3JlIHRoZXkgZ2V0IGluc3RhbGxlZCBkdXJpbmcgY29tcG9zZXIgaW5zdGFsbAogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJHRoaXMtPmRldlBhY2thZ2VOYW1lcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydkZXYtcGFja2FnZS1uYW1lcyddW10gPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzb3J0KCRkYXRhWydkZXYtcGFja2FnZS1uYW1lcyddKTsKICAgICAgICB1c29ydCgkZGF0YVsncGFja2FnZXMnXSwgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhWyduYW1lJ10sICRiWyduYW1lJ10pOwogICAgICAgIH0pOwoKICAgICAgICAkdGhpcy0+ZmlsZS0+d3JpdGUoJGRhdGEpOwoKCiAgICAgICAgaWYgKCR0aGlzLT5kdW1wVmVyc2lvbnMpIHsKICAgICAgICAgICAgJHZlcnNpb25zID0gJHRoaXMtPmdlbmVyYXRlSW5zdGFsbGVkVmVyc2lvbnMoJGluc3RhbGxhdGlvbk1hbmFnZXIpOwoKICAgICAgICAgICAgJGZzLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCRyZXBvRGlyLicvaW5zdGFsbGVkLnBocCcsICc8P3BocCByZXR1cm4gJy52YXJfZXhwb3J0KCR2ZXJzaW9ucywgdHJ1ZSkuJzsnLiJcbiIpOwogICAgICAgICAgICAkaW5zdGFsbGVkVmVyc2lvbnNDbGFzcyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18uJy8uLi9JbnN0YWxsZWRWZXJzaW9ucy5waHAnKTsKICAgICAgICAgICAgLy8gd2hpbGUgbm90IHN0cmljdGx5IG5lZWRlZCBzaW5jZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC85NjM1IC0gd2Uga2VlcCB0aGlzIGZvciBCQwogICAgICAgICAgICAvLyBhbmQgb3ZlcmFsbCBicm9hZGVyIGNvbXBhdGliaWxpdHkgd2l0aCBwZW9wbGUgdGhhdCBtYXkgbm90IHVzZSBDb21wb3NlcidzIENsYXNzTG9hZGVyLiBUaGV5IGNhbgogICAgICAgICAgICAvLyBzaW1wbHkgaW5jbHVkZSBJbnN0YWxsZWRWZXJzaW9ucy5waHAgbWFudWFsbHkgYW5kIGhhdmUgaXQgd29ya2luZyBpbiBhIGJhc2ljIHdheS4KICAgICAgICAgICAgJGluc3RhbGxlZFZlcnNpb25zQ2xhc3MgPSBzdHJfcmVwbGFjZSgncHJpdmF0ZSBzdGF0aWMgJGluc3RhbGxlZDsnLCAncHJpdmF0ZSBzdGF0aWMgJGluc3RhbGxlZCA9ICcudmFyX2V4cG9ydCgkdmVyc2lvbnMsIHRydWUpLic7JywgJGluc3RhbGxlZFZlcnNpb25zQ2xhc3MpOwogICAgICAgICAgICAkZnMtPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHJlcG9EaXIuJy9JbnN0YWxsZWRWZXJzaW9ucy5waHAnLCAkaW5zdGFsbGVkVmVyc2lvbnNDbGFzcyk7CgogICAgICAgICAgICBcQ29tcG9zZXJcSW5zdGFsbGVkVmVyc2lvbnM6OnJlbG9hZCgkdmVyc2lvbnMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gP2FycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2VuZXJhdGVJbnN0YWxsZWRWZXJzaW9ucyhJbnN0YWxsYXRpb25NYW5hZ2VyICRpbnN0YWxsYXRpb25NYW5hZ2VyKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmR1bXBWZXJzaW9ucykgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5KCd2ZXJzaW9ucycgPT4gYXJyYXkoKSk7CiAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmdldFBhY2thZ2VzKCk7CiAgICAgICAgJHBhY2thZ2VzW10gPSAkcm9vdFBhY2thZ2UgPSAkdGhpcy0+cm9vdFBhY2thZ2U7CiAgICAgICAgd2hpbGUgKCRyb290UGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkcm9vdFBhY2thZ2UgPSAkcm9vdFBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcm9vdFBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICAvLyBhZGQgcmVhbCBpbnN0YWxsZWQgcGFja2FnZXMKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlZmVyZW5jZSA9IG51bGw7CiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCkpIHsKICAgICAgICAgICAgICAgICRyZWZlcmVuY2UgPSAkcGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCkgPT09ICdzb3VyY2UnID8gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpIDogJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHJlZmVyZW5jZSkgewogICAgICAgICAgICAgICAgJHJlZmVyZW5jZSA9ICgkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkgPzogJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkgPzogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlLT5nZXROYW1lKCldID0gYXJyYXkoCiAgICAgICAgICAgICAgICAncHJldHR5X3ZlcnNpb24nID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHBhY2thZ2UtPmdldFZlcnNpb24oKSwKICAgICAgICAgICAgICAgICdhbGlhc2VzJyA9PiBhcnJheSgpLAogICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJHJlZmVyZW5jZSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sncm9vdCddID0gJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRwYWNrYWdlLT5nZXROYW1lKCldOwogICAgICAgICAgICAgICAgJHZlcnNpb25zWydyb290J11bJ25hbWUnXSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGFkZCBwcm92aWRlZC9yZXBsYWNlZCBwYWNrYWdlcwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkcmVwbGFjZSkgewogICAgICAgICAgICAgICAgLy8gZXhjbHVkZSBwbGF0Zm9ybSByZXBsYWNlcyBhcyB3aGVuIHRoZXkgYXJlIHJlYWxseSB0aGVyZSB3ZSBjYW4gbm90IGNoZWNrIGZvciB0aGVpciBwcmVzZW5jZQogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcGxhY2UtPmdldFRhcmdldCgpKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlcGxhY2VkID0gJHJlcGxhY2UtPmdldFByZXR0eUNvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgIGlmICgkcmVwbGFjZWQgPT09ICdzZWxmLnZlcnNpb24nKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VkID0gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHZlcnNpb25zWyd2ZXJzaW9ucyddWyRyZXBsYWNlLT5nZXRUYXJnZXQoKV1bJ3JlcGxhY2VkJ10pIHx8ICFpbl9hcnJheSgkcmVwbGFjZWQsICR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcmVwbGFjZS0+Z2V0VGFyZ2V0KCldWydyZXBsYWNlZCddLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcmVwbGFjZS0+Z2V0VGFyZ2V0KCldWydyZXBsYWNlZCddW10gPSAkcmVwbGFjZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFByb3ZpZGVzKCkgYXMgJHByb3ZpZGUpIHsKICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGUgcGxhdGZvcm0gcHJvdmlkZXMgYXMgd2hlbiB0aGV5IGFyZSByZWFsbHkgdGhlcmUgd2UgY2FuIG5vdCBjaGVjayBmb3IgdGhlaXIgcHJlc2VuY2UKICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRwcm92aWRlLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwcm92aWRlZCA9ICRwcm92aWRlLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICBpZiAoJHByb3ZpZGVkID09PSAnc2VsZi52ZXJzaW9uJykgewogICAgICAgICAgICAgICAgICAgICRwcm92aWRlZCA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR2ZXJzaW9uc1sndmVyc2lvbnMnXVskcHJvdmlkZS0+Z2V0VGFyZ2V0KCldWydwcm92aWRlZCddKSB8fCAhaW5fYXJyYXkoJHByb3ZpZGVkLCAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHByb3ZpZGUtPmdldFRhcmdldCgpXVsncHJvdmlkZWQnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHByb3ZpZGUtPmdldFRhcmdldCgpXVsncHJvdmlkZWQnXVtdID0gJHByb3ZpZGVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBhZGQgYWxpYXNlcwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoISRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdmVyc2lvbnNbJ3ZlcnNpb25zJ11bJHBhY2thZ2UtPmdldE5hbWUoKV1bJ2FsaWFzZXMnXVtdID0gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1sncm9vdCddWydhbGlhc2VzJ11bXSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGtzb3J0KCR2ZXJzaW9uc1sndmVyc2lvbnMnXSk7CiAgICAgICAga3NvcnQoJHZlcnNpb25zKTsKCiAgICAgICAgcmV0dXJuICR2ZXJzaW9uczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKaW50ZXJmYWNlIFZlcnNpb25DYWNoZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkdmVyc2lvbgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRpZGVudGlmaWVyCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGx8ZmFsc2UgUGFja2FnZSB2ZXJzaW9uIGRhdGEgaWYgZm91bmQsIGZhbHNlIHRvIGluZGljYXRlIHRoZSBpZGVudGlmaWVyIGlzIGtub3duIGJ1dCBoYXMgbm8gcGFja2FnZSwgbnVsbCBmb3IgYW4gdW5rbm93biBpZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uUGFja2FnZSgkdmVyc2lvbiwgJGlkZW50aWZpZXIpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFJlcG9zaXRvcnk7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE1hdGNoQWxsQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CgovKioKICogSW5zdGFsbGVkIHJlcG9zaXRvcnkgaXMgYSBjb21wb3NpdGUgb2YgYWxsIGluc3RhbGxlZCByZXBvIHR5cGVzLgogKgogKiBUaGUgbWFpbiB1c2UgY2FzZSBpcyB0YWdnaW5nIGEgcmVwbyBhcyBhbiAiaW5zdGFsbGVkIiByZXBvc2l0b3J5LCBhbmQgb2ZmZXJpbmcgYSB3YXkgdG8gZ2V0IHByb3ZpZGVycy9yZXBsYWNlcnMgZWFzaWx5LgogKgogKiBJbnN0YWxsZWQgcmVwb3MgYXJlIExvY2tBcnJheVJlcG9zaXRvcnksIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UsIFJvb3RQYWNrYWdlUmVwb3NpdG9yeSBhbmQgUGxhdGZvcm1SZXBvc2l0b3J5CiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEluc3RhbGxlZFJlcG9zaXRvcnkgZXh0ZW5kcyBDb21wb3NpdGVSZXBvc2l0b3J5CnsKICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXNXaXRoUmVwbGFjZXJzQW5kUHJvdmlkZXJzKCRuYW1lLCAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKCiAgICAgICAgaWYgKG51bGwgIT09ICRjb25zdHJhaW50ICYmICEkY29uc3RyYWludCBpbnN0YW5jZW9mIENvbnN0cmFpbnRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICAgICAkY29uc3RyYWludCA9ICR2ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgICRtYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UmVwb3NpdG9yaWVzKCkgYXMgJHJlcG8pIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICAgICAgaWYgKCRuYW1lID09PSAkY2FuZGlkYXRlLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJGNvbnN0cmFpbnQgfHwgJGNvbnN0cmFpbnQtPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz09JywgJGNhbmRpZGF0ZS0+Z2V0VmVyc2lvbigpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoZXNbXSA9ICRjYW5kaWRhdGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21lcmdlKCRjYW5kaWRhdGUtPmdldFByb3ZpZGVzKCksICRjYW5kaWRhdGUtPmdldFJlcGxhY2VzKCkpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSA9PT0gJGxpbmstPmdldFRhcmdldCgpCiAgICAgICAgICAgICAgICAgICAgICAgICYmICgkY29uc3RyYWludCA9PT0gbnVsbCB8fCAkbGluay0+Z2V0Q29uc3RyYWludCgpID09PSBudWxsIHx8ICRjb25zdHJhaW50LT5tYXRjaGVzKCRsaW5rLT5nZXRDb25zdHJhaW50KCkpKQogICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tdID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWF0Y2hlczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGxpbmtzIGNhdXNpbmcgdGhlIHJlcXVlc3RlZCBuZWVkbGUgcGFja2FnZXMgdG8gYmUgaW5zdGFsbGVkLCBhcyBhbiBhc3NvY2lhdGl2ZSBhcnJheSB3aXRoIHRoZQogICAgICogZGVwZW5kZW50J3MgbmFtZSBhcyBrZXksIGFuZCBhbiBhcnJheSBjb250YWluaW5nIGluIG9yZGVyIHRoZSBQYWNrYWdlSW50ZXJmYWNlIGFuZCBMaW5rIGRlc2NyaWJpbmcgdGhlIHJlbGF0aW9uc2hpcAogICAgICogYXMgdmFsdWVzLiBJZiByZWN1cnNpdmUgbG9va3VwIHdhcyByZXF1ZXN0ZWQgYSB0aGlyZCB2YWx1ZSBpcyByZXR1cm5lZCBjb250YWluaW5nIGFuIGlkZW50aWNhbGx5IGZvcm1lZCBhcnJheSB1cAogICAgICogdG8gdGhlIHJvb3QgcGFja2FnZS4gVGhhdCB0aGlyZCB2YWx1ZSB3aWxsIGJlIGZhbHNlIGluIGNhc2UgYSBjaXJjdWxhciByZWN1cnNpb24gd2FzIGRldGVjdGVkLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nfHN0cmluZ1tdICAgICAgICAgICRuZWVkbGUgICAgICAgIFRoZSBwYWNrYWdlIG5hbWUocykgdG8gaW5zcGVjdC4KICAgICAqIEBwYXJhbSAgQ29uc3RyYWludEludGVyZmFjZXxudWxsICRjb25zdHJhaW50ICAgIE9wdGlvbmFsIGNvbnN0cmFpbnQgdG8gZmlsdGVyIGJ5LgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgJGludmVydCAgICAgICAgV2hldGhlciB0byBpbnZlcnQgbWF0Y2hlcyB0byBkaXNjb3ZlciByZWFzb25zIGZvciB0aGUgcGFja2FnZSAqTk9UKiB0byBiZSBpbnN0YWxsZWQuCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAkcmVjdXJzZSAgICAgICBXaGV0aGVyIHRvIHJlY3Vyc2l2ZWx5IGV4cGFuZCB0aGUgcmVxdWlyZW1lbnQgdHJlZSB1cCB0byB0aGUgcm9vdCBwYWNrYWdlLgogICAgICogQHBhcmFtICBzdHJpbmdbXSAgICAgICAgICAgICAgICAgJHBhY2thZ2VzRm91bmQgVXNlZCBpbnRlcm5hbGx5IHdoZW4gcmVjdXJyaW5nCiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgICAgICAgICAgICAgICBBbiBhc3NvY2lhdGl2ZSBhcnJheSBvZiBhcnJheXMgYXMgZGVzY3JpYmVkIGFib3ZlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVwZW5kZW50cygkbmVlZGxlLCAkY29uc3RyYWludCA9IG51bGwsICRpbnZlcnQgPSBmYWxzZSwgJHJlY3Vyc2UgPSB0cnVlLCAkcGFja2FnZXNGb3VuZCA9IG51bGwpCiAgICB7CiAgICAgICAgJG5lZWRsZXMgPSBhcnJheV9tYXAoJ3N0cnRvbG93ZXInLCAoYXJyYXkpICRuZWVkbGUpOwogICAgICAgICRyZXN1bHRzID0gYXJyYXkoKTsKCiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgYXJyYXkgd2l0aCB0aGUgbmVlZGxlcyBiZWZvcmUgYW55IHJlY3Vyc2lvbiBvY2N1cnMKICAgICAgICBpZiAobnVsbCA9PT0gJHBhY2thZ2VzRm91bmQpIHsKICAgICAgICAgICAgJHBhY2thZ2VzRm91bmQgPSAkbmVlZGxlczsKICAgICAgICB9CgogICAgICAgIC8vIGxvY2F0ZSByb290IHBhY2thZ2UgZm9yIHVzZSBiZWxvdwogICAgICAgICRyb290UGFja2FnZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICRyb290UGFja2FnZSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIExvb3Agb3ZlciBhbGwgY3VycmVudGx5IGluc3RhbGxlZCBwYWNrYWdlcy4KICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkbGlua3MgPSAkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKTsKCiAgICAgICAgICAgIC8vIGVhY2ggbG9vcCBuZWVkcyBpdHMgb3duICJ0cmVlIiBhcyB3ZSB3YW50IHRvIHNob3cgdGhlIGNvbXBsZXRlIGRlcGVuZGVudCBzZXQgb2YgZXZlcnkgbmVlZGxlCiAgICAgICAgICAgIC8vIHdpdGhvdXQgd2FybmluZyBhbGwgdGhlIHRpbWUgYWJvdXQgZmluZGluZyBjaXJjdWxhciBkZXBzCiAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZSA9ICRwYWNrYWdlc0ZvdW5kOwoKICAgICAgICAgICAgLy8gUmVwbGFjZW1lbnRzIGFyZSBjb25zaWRlcmVkIHZhbGlkIHJlYXNvbnMgZm9yIGEgcGFja2FnZSB0byBiZSBpbnN0YWxsZWQgZHVyaW5nIGZvcndhcmQgcmVzb2x1dGlvbgogICAgICAgICAgICBpZiAoISRpbnZlcnQpIHsKICAgICAgICAgICAgICAgICRsaW5rcyArPSAkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKTsKCiAgICAgICAgICAgICAgICAvLyBPbiBmb3J3YXJkIHNlYXJjaCwgY2hlY2sgaWYgYW55IHJlcGxhY2VkIHBhY2thZ2Ugd2FzIHJlcXVpcmVkIGFuZCBhZGQgdGhlIHJlcGxhY2VkCiAgICAgICAgICAgICAgICAvLyBwYWNrYWdlcyB0byB0aGUgbGlzdCBvZiBuZWVkbGVzLiBDb250cmFyeSB0byB0aGUgY3Jvc3MtcmVmZXJlbmNlIGxpbmsgY2hlY2sgYmVsb3csCiAgICAgICAgICAgICAgICAvLyByZXBsYWNlZCBwYWNrYWdlcyBhcmUgdGhlIHRhcmdldCBvZiBsaW5rcy4KICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXBsYWNlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5lZWRsZXMgYXMgJG5lZWRsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFNvdXJjZSgpID09PSAkbmVlZGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgKCRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGNvbnN0cmFpbnQpID09PSAhJGludmVydCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IGRpc3BsYXllZCB0aGlzIG5vZGUncyBkZXBlbmRlbmNpZXMsIGN1dHRpbmcgc2hvcnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGxpbmstPmdldFRhcmdldCgpLCAkcGFja2FnZXNJblRyZWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZVtdID0gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZXBlbmRlbnRzID0gJHJlY3Vyc2UgPyAkdGhpcy0+Z2V0RGVwZW5kZW50cygkbGluay0+Z2V0VGFyZ2V0KCksIG51bGwsIGZhbHNlLCB0cnVlLCAkcGFja2FnZXNJblRyZWUpIDogYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoJHBhY2thZ2UsICRsaW5rLCAkZGVwZW5kZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5lZWRsZXNbXSA9ICRsaW5rLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUmVxdWlyZS1kZXYgaXMgb25seSByZWxldmFudCBmb3IgdGhlIHJvb3QgcGFja2FnZQogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJGxpbmtzICs9ICRwYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDcm9zcy1yZWZlcmVuY2UgYWxsIGRpc2NvdmVyZWQgbGlua3MgdG8gdGhlIG5lZWRsZXMKICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmVlZGxlcyBhcyAkbmVlZGxlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRUYXJnZXQoKSA9PT0gJG5lZWRsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgKCRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGNvbnN0cmFpbnQpID09PSAhJGludmVydCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgZGlzcGxheWVkIHRoaXMgbm9kZSdzIGRlcGVuZGVuY2llcywgY3V0dGluZyBzaG9ydAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRsaW5rLT5nZXRTb3VyY2UoKSwgJHBhY2thZ2VzSW5UcmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZVtdID0gJGxpbmstPmdldFNvdXJjZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlcGVuZGVudHMgPSAkcmVjdXJzZSA/ICR0aGlzLT5nZXREZXBlbmRlbnRzKCRsaW5rLT5nZXRTb3VyY2UoKSwgbnVsbCwgZmFsc2UsIHRydWUsICRwYWNrYWdlc0luVHJlZSkgOiBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRwYWNrYWdlLCAkbGluaywgJGRlcGVuZGVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBXaGVuIGludmVydGluZywgd2UgbmVlZCB0byBjaGVjayBmb3IgY29uZmxpY3RzIG9mIHRoZSBuZWVkbGVzIGFnYWluc3QgaW5zdGFsbGVkIHBhY2thZ2VzCiAgICAgICAgICAgIGlmICgkaW52ZXJ0ICYmIGluX2FycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRuZWVkbGVzKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldENvbmZsaWN0cygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbmRQYWNrYWdlcygkbGluay0+Z2V0VGFyZ2V0KCkpIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSBuZXcgQ29uc3RyYWludCgnPScsICRwa2ctPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCR2ZXJzaW9uKSA9PT0gJGludmVydCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRwYWNrYWdlLCAkbGluaywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBXaGVuIGludmVydGluZywgd2UgbmVlZCB0byBjaGVjayBmb3IgY29uZmxpY3RzIG9mIHRoZSBuZWVkbGVzJyByZXF1aXJlbWVudHMgYWdhaW5zdCBpbnN0YWxsZWQgcGFja2FnZXMKICAgICAgICAgICAgaWYgKCRpbnZlcnQgJiYgJGNvbnN0cmFpbnQgJiYgaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJG5lZWRsZXMpICYmICRjb25zdHJhaW50LT5tYXRjaGVzKG5ldyBDb25zdHJhaW50KCc9JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSkpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5maW5kUGFja2FnZSgkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRDb25zdHJhaW50KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHBsYXRmb3JtUGtnID0gJHRoaXMtPmZpbmRQYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSwgJyonKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJHBsYXRmb3JtUGtnID8gJ2J1dCAnLiRwbGF0Zm9ybVBrZy0+Z2V0UHJldHR5VmVyc2lvbigpLicgaXMgaW5zdGFsbGVkJyA6ICdidXQgaXQgaXMgbWlzc2luZyc7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgbmV3IExpbmsoJHBhY2thZ2UtPmdldE5hbWUoKSwgJGxpbmstPmdldFRhcmdldCgpLCBuZXcgTWF0Y2hBbGxDb25zdHJhaW50LCBMaW5rOjpUWVBFX1JFUVVJUkUsICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkuJyAnLiRkZXNjcmlwdGlvbiksIGZhbHNlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBhY2thZ2VzKCkgYXMgJHBrZykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRsaW5rLT5nZXRUYXJnZXQoKSwgJHBrZy0+Z2V0TmFtZXMoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9IG5ldyBDb25zdHJhaW50KCc9JywgJHBrZy0+Z2V0VmVyc2lvbigpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0VGFyZ2V0KCkgIT09ICRwa2ctPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoJHBrZy0+Z2V0UmVwbGFjZXMoKSwgJHBrZy0+Z2V0UHJvdmlkZXMoKSkgYXMgJHByb3YpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFRhcmdldCgpID09PSAkcHJvdi0+Z2V0VGFyZ2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkcHJvdi0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJGxpbmstPmdldENvbnN0cmFpbnQoKS0+bWF0Y2hlcygkdmVyc2lvbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGhhdmUgYSByb290IHBhY2thZ2UgKHdlIHNob3VsZCBidXQgY2FuIG5vdCBndWFyYW50ZWUuLikgd2Ugc2hvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHJvb3QgcmVxdWlyZXMgYXMgd2VsbCB0byBwZXJoYXBzIGFsbG93IHRvIGZpbmQgYW4gaXNzdWUgdGhlcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcm9vdFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkcm9vdFBhY2thZ2UtPmdldFJlcXVpcmVzKCksICRyb290UGFja2FnZS0+Z2V0RGV2UmVxdWlyZXMoKSkgYXMgJHJvb3RSZXEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRyb290UmVxLT5nZXRUYXJnZXQoKSwgJHBrZy0+Z2V0TmFtZXMoKSkgJiYgISRyb290UmVxLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGxpbmstPmdldENvbnN0cmFpbnQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcm9vdFBhY2thZ2UsICRyb290UmVxLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0c1tdID0gYXJyYXkoJHBhY2thZ2UsICRsaW5rLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCRyb290UGFja2FnZSwgbmV3IExpbmsoJHJvb3RQYWNrYWdlLT5nZXROYW1lKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgbmV3IE1hdGNoQWxsQ29uc3RyYWludCwgJ2RvZXMgbm90IHJlcXVpcmUnLCAnYnV0ICcgLiAkcGtnLT5nZXRQcmV0dHlWZXJzaW9uKCkgLiAnIGlzIGluc3RhbGxlZCcpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vIHJvb3Qgc28gbGV0J3MganVzdCBwcmludCB3aGF0ZXZlciB3ZSBmb3VuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgkcGFja2FnZSwgJGxpbmssIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGtzb3J0KCRyZXN1bHRzKTsKCiAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdpbnN0YWxsZWQgcmVwbyAoJy5pbXBsb2RlKCcsICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHJlcG8pIHsKICAgICAgICAgICAgcmV0dXJuICRyZXBvLT5nZXRSZXBvTmFtZSgpOwogICAgICAgIH0sICR0aGlzLT5nZXRSZXBvc2l0b3JpZXMoKSkpLicpJzsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIHJlcG9zaXRvcnkuCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUmVwb3NpdG9yeShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5KQogICAgewogICAgICAgIGlmICgKICAgICAgICAgICAgJHJlcG9zaXRvcnkgaW5zdGFuY2VvZiBMb2NrQXJyYXlSZXBvc2l0b3J5CiAgICAgICAgICAgIHx8ICRyZXBvc2l0b3J5IGluc3RhbmNlb2YgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZQogICAgICAgICAgICB8fCAkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlUmVwb3NpdG9yeQogICAgICAgICAgICB8fCAkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIFBsYXRmb3JtUmVwb3NpdG9yeQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50OjphZGRSZXBvc2l0b3J5KCRyZXBvc2l0b3J5KTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0FuIEluc3RhbGxlZFJlcG9zaXRvcnkgY2FuIG5vdCBjb250YWluIGEgcmVwb3NpdG9yeSBvZiB0eXBlICcuZ2V0X2NsYXNzKCRyZXBvc2l0b3J5KS4nICgnLiRyZXBvc2l0b3J5LT5nZXRSZXBvTmFtZSgpLicpJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcQXJyYXlMb2FkZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFN0YWJpbGl0eUZpbHRlcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBpbGluZ01hdGNoZXI7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxMb29wOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFBsdWdpblxQcmVGaWxlRG93bmxvYWRFdmVudDsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwXFJlc3BvbnNlOwp1c2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ29tcG9zZXJSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgQ29uZmlndXJhYmxlUmVwb3NpdG9yeUludGVyZmFjZQp7CiAgICBwcml2YXRlICRyZXBvQ29uZmlnOwogICAgcHJpdmF0ZSAkb3B0aW9uczsKICAgIHByaXZhdGUgJHVybDsKICAgIHByaXZhdGUgJGJhc2VVcmw7CiAgICBwcml2YXRlICRpbzsKICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgcHJpdmF0ZSAkbG9vcDsKICAgIHByb3RlY3RlZCAkY2FjaGU7CiAgICBwcm90ZWN0ZWQgJG5vdGlmeVVybDsKICAgIHByb3RlY3RlZCAkc2VhcmNoVXJsOwogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgYSBVUkwgY29udGFpbmluZyAlcGFja2FnZSUgd2hpY2ggY2FuIGJlIHF1ZXJpZWQgdG8gZ2V0IHByb3ZpZGVycyBvZiBhIGdpdmVuIG5hbWUgKi8KICAgIHByb3RlY3RlZCAkcHJvdmlkZXJzQXBpVXJsOwogICAgcHJvdGVjdGVkICRoYXNQcm92aWRlcnMgPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkcHJvdmlkZXJzVXJsOwogICAgcHJvdGVjdGVkICRsaXN0VXJsOwogICAgLyoqIEB2YXIgYm9vbCBJbmRpY2F0ZXMgd2hldGhlciBhIGNvbXByZWhlbnNpdmUgbGlzdCBvZiBwYWNrYWdlcyB0aGlzIHJlcG9zaXRvcnkgbWlnaHQgcHJvdmlkZSBpcyBleHByZXNzZWQgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdC4gKiovCiAgICBwcm90ZWN0ZWQgJGhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ID0gZmFsc2U7CiAgICBwcm90ZWN0ZWQgJGF2YWlsYWJsZVBhY2thZ2VzOwogICAgcHJvdGVjdGVkICRhdmFpbGFibGVQYWNrYWdlUGF0dGVybnM7CiAgICBwcm90ZWN0ZWQgJGxhenlQcm92aWRlcnNVcmw7CiAgICBwcm90ZWN0ZWQgJHByb3ZpZGVyTGlzdGluZzsKICAgIHByb3RlY3RlZCAkbG9hZGVyOwogICAgcHJpdmF0ZSAkYWxsb3dTc2xEb3duZ3JhZGUgPSBmYWxzZTsKICAgIHByaXZhdGUgJGV2ZW50RGlzcGF0Y2hlcjsKICAgIHByaXZhdGUgJHNvdXJjZU1pcnJvcnM7CiAgICBwcml2YXRlICRkaXN0TWlycm9yczsKICAgIHByaXZhdGUgJGRlZ3JhZGVkTW9kZSA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcm9vdERhdGE7CiAgICBwcml2YXRlICRoYXNQYXJ0aWFsUGFja2FnZXM7CiAgICBwcml2YXRlICRwYXJ0aWFsUGFja2FnZXNCeU5hbWU7CgogICAgLyoqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByaXZhdGUKICAgICAqIEB2YXIgYXJyYXkgbGlzdCBvZiBwYWNrYWdlIG5hbWVzIHdoaWNoIGFyZSBmcmVzaCBhbmQgY2FuIGJlIGxvYWRlZCBmcm9tIHRoZSBjYWNoZSBkaXJlY3RseSBpbiBjYXNlIGxvYWRQYWNrYWdlIGlzIGNhbGxlZCBzZXZlcmFsIHRpbWVzCiAgICAgKiAgICAgICAgICAgIHVzZWZ1bCBmb3IgdjIgbWV0YWRhdGEgcmVwb3NpdG9yaWVzIHdpdGggbGF6eSBwcm92aWRlcnMKICAgICAqLwogICAgcHVibGljICRmcmVzaE1ldGFkYXRhVXJscyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByaXZhdGUKICAgICAqIEB2YXIgYXJyYXkgbGlzdCBvZiBwYWNrYWdlIG5hbWVzIHdoaWNoIHJldHVybmVkIGEgNDA0IGFuZCBzaG91bGQgbm90IGJlIHJlLWZldGNoZWQgaW4gY2FzZSBsb2FkUGFja2FnZSBpcyBjYWxsZWQgc2V2ZXJhbCB0aW1lcwogICAgICogICAgICAgICAgICB1c2VmdWwgZm9yIHYyIG1ldGFkYXRhIHJlcG9zaXRvcmllcyB3aXRoIGxhenkgcHJvdmlkZXJzCiAgICAgKi8KICAgIHB1YmxpYyAkcGFja2FnZXNOb3RGb3VuZENhY2hlID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogVE9ETyB2MyBzaG91bGQgbWFrZSB0aGlzIHByaXZhdGUgb25jZSB3ZSBjYW4gZHJvcCBQSFAgNS4zIHN1cHBvcnQKICAgICAqIEBwcml2YXRlCiAgICAgKi8KICAgIHB1YmxpYyAkdmVyc2lvblBhcnNlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJlcG9Db25maWcsIElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciwgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoKTsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3teW1x3Ll0rXD8/Oi8vfScsICRyZXBvQ29uZmlnWyd1cmwnXSkpIHsKICAgICAgICAgICAgLy8gYXNzdW1lIGh0dHAgYXMgdGhlIGRlZmF1bHQgcHJvdG9jb2wKICAgICAgICAgICAgJHJlcG9Db25maWdbJ3VybCddID0gJ2h0dHA6Ly8nLiRyZXBvQ29uZmlnWyd1cmwnXTsKICAgICAgICB9CiAgICAgICAgJHJlcG9Db25maWdbJ3VybCddID0gcnRyaW0oJHJlcG9Db25maWdbJ3VybCddLCAnLycpOwoKICAgICAgICBpZiAoc3RycG9zKCRyZXBvQ29uZmlnWyd1cmwnXSwgJ2h0dHBzPycpID09PSAwKSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnWyd1cmwnXSA9IChleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgPyAnaHR0cHMnIDogJ2h0dHAnKSAuIHN1YnN0cigkcmVwb0NvbmZpZ1sndXJsJ10sIDYpOwogICAgICAgIH0KCiAgICAgICAgJHVybEJpdHMgPSBwYXJzZV91cmwoJHJlcG9Db25maWdbJ3VybCddKTsKICAgICAgICBpZiAoJHVybEJpdHMgPT09IGZhbHNlIHx8IGVtcHR5KCR1cmxCaXRzWydzY2hlbWUnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0ludmFsaWQgdXJsIGdpdmVuIGZvciBDb21wb3NlciByZXBvc2l0b3J5OiAnLiRyZXBvQ29uZmlnWyd1cmwnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRyZXBvQ29uZmlnWydvcHRpb25zJ10pKSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnWydvcHRpb25zJ10gPSBhcnJheSgpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ2FsbG93X3NzbF9kb3duZ3JhZGUnXSkgJiYgdHJ1ZSA9PT0gJHJlcG9Db25maWdbJ2FsbG93X3NzbF9kb3duZ3JhZGUnXSkgewogICAgICAgICAgICAkdGhpcy0+YWxsb3dTc2xEb3duZ3JhZGUgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSAkcmVwb0NvbmZpZ1snb3B0aW9ucyddOwogICAgICAgICR0aGlzLT51cmwgPSAkcmVwb0NvbmZpZ1sndXJsJ107CgogICAgICAgIC8vIGZvcmNlIHVybCBmb3IgcGFja2FnaXN0Lm9yZyB0byByZXBvLnBhY2thZ2lzdC5vcmcKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oP1A8cHJvdG8+aHR0cHM/KTovL3BhY2thZ2lzdFwub3JnLz8kfWknLCAkdGhpcy0+dXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT51cmwgPSAkbWF0Y2hbJ3Byb3RvJ10uJzovL3JlcG8ucGFja2FnaXN0Lm9yZyc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YmFzZVVybCA9IHJ0cmltKHByZWdfcmVwbGFjZSgneyg/Oi9bXi9cXFxcXStcLmpzb24pPyg/Ols/I10uKik/JH0nLCAnJywgJHRoaXMtPnVybCksICcvJyk7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jYWNoZSA9IG5ldyBDYWNoZSgkaW8sICRjb25maWctPmdldCgnY2FjaGUtcmVwby1kaXInKS4nLycucHJlZ19yZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCBVcmw6OnNhbml0aXplKCR0aGlzLT51cmwpKSwgJ2EtejAtOS4kficpOwogICAgICAgICR0aGlzLT5jYWNoZS0+c2V0UmVhZE9ubHkoJGNvbmZpZy0+Z2V0KCdjYWNoZS1yZWFkLW9ubHknKSk7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICR0aGlzLT5sb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoJHRoaXMtPnZlcnNpb25QYXJzZXIpOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkdGhpcy0+cmVwb0NvbmZpZyA9ICRyZXBvQ29uZmlnOwogICAgICAgICR0aGlzLT5sb29wID0gbmV3IExvb3AoJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgIHJldHVybiAnY29tcG9zZXIgcmVwbyAoJy5Vcmw6OnNhbml0aXplKCR0aGlzLT51cmwpLicpJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb0NvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvQ29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFBhY2thZ2UoJG5hbWUsICRjb25zdHJhaW50KQogICAgewogICAgICAgIC8vIHRoaXMgY2FsbCBpbml0aWFsaXplcyBsb2FkUm9vdFNlcnZlckZpbGUgd2hpY2ggaXMgbmVlZGVkIGZvciB0aGUgcmVzdCBiZWxvdyB0byB3b3JrCiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKICAgICAgICBpZiAoISRjb25zdHJhaW50IGluc3RhbmNlb2YgQ29uc3RyYWludEludGVyZmFjZSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmIGlzc2V0KCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJQYWNrYWdlcygkdGhpcy0+d2hhdFByb3ZpZGVzKCRuYW1lKSwgJGNvbnN0cmFpbnQsIHRydWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPmhhc0F2YWlsYWJsZVBhY2thZ2VMaXN0ICYmICEkdGhpcy0+bGF6eVByb3ZpZGVyc1JlcG9Db250YWlucygkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmxvYWRBc3luY1BhY2thZ2VzKGFycmF5KCRuYW1lID0+ICRjb25zdHJhaW50KSk7CgogICAgICAgICAgICByZXR1cm4gcmVzZXQoJHBhY2thZ2VzWydwYWNrYWdlcyddKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaGFzUHJvdmlkZXJzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQcm92aWRlck5hbWVzKCkgYXMgJHByb3ZpZGVyTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKCRuYW1lID09PSAkcHJvdmlkZXJOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWx0ZXJQYWNrYWdlcygkdGhpcy0+d2hhdFByb3ZpZGVzKCRwcm92aWRlck5hbWUpLCAkY29uc3RyYWludCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmZpbmRQYWNrYWdlKCRuYW1lLCAkY29uc3RyYWludCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUGFja2FnZXMoJG5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAvLyB0aGlzIGNhbGwgaW5pdGlhbGl6ZXMgbG9hZFJvb3RTZXJ2ZXJGaWxlIHdoaWNoIGlzIG5lZWRlZCBmb3IgdGhlIHJlc3QgYmVsb3cgdG8gd29yawogICAgICAgICRoYXNQcm92aWRlcnMgPSAkdGhpcy0+aGFzUHJvdmlkZXJzKCk7CgogICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CiAgICAgICAgaWYgKG51bGwgIT09ICRjb25zdHJhaW50ICYmICEkY29uc3RyYWludCBpbnN0YW5jZW9mIENvbnN0cmFpbnRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMoKSAmJiBpc3NldCgkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsdGVyUGFja2FnZXMoJHRoaXMtPndoYXRQcm92aWRlcygkbmFtZSksICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXNBdmFpbGFibGVQYWNrYWdlTGlzdCAmJiAhJHRoaXMtPmxhenlQcm92aWRlcnNSZXBvQ29udGFpbnMoJG5hbWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5sb2FkQXN5bmNQYWNrYWdlcyhhcnJheSgkbmFtZSA9PiAkY29uc3RyYWludCkpOwoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHRbJ3BhY2thZ2VzJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycykgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UHJvdmlkZXJOYW1lcygpIGFzICRwcm92aWRlck5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkbmFtZSA9PT0gJHByb3ZpZGVyTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsdGVyUGFja2FnZXMoJHRoaXMtPndoYXRQcm92aWRlcygkcHJvdmlkZXJOYW1lKSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmZpbmRQYWNrYWdlcygkbmFtZSwgJGNvbnN0cmFpbnQpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZmlsdGVyUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzLCAkY29uc3RyYWludCA9IG51bGwsICRyZXR1cm5GaXJzdE1hdGNoID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmICgkcmV0dXJuRmlyc3RNYXRjaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc2V0KCRwYWNrYWdlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICAkZmlsdGVyZWRQYWNrYWdlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkcGtnQ29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpOwoKICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50LT5tYXRjaGVzKCRwa2dDb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgaWYgKCRyZXR1cm5GaXJzdE1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRmaWx0ZXJlZFBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXR1cm5GaXJzdE1hdGNoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaWx0ZXJlZFBhY2thZ2VzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5sYXp5UHJvdmlkZXJzVXJsKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMpICYmICEkdGhpcy0+YXZhaWxhYmxlUGFja2FnZVBhdHRlcm5zKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZU1hcCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU1hcFskbmFtZV0gPSBuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5sb2FkQXN5bmNQYWNrYWdlcygkcGFja2FnZU1hcCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3ZhbHVlcygkcmVzdWx0WydwYWNrYWdlcyddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3ZhbHVlcygkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignQ29tcG9zZXIgcmVwb3NpdG9yaWVzIHRoYXQgaGF2ZSBsYXp5IHByb3ZpZGVycyBhbmQgbm8gYXZhaWxhYmxlLXBhY2thZ2VzIGxpc3QgY2FuIG5vdCBsb2FkIHRoZSBjb21wbGV0ZSBsaXN0IG9mIHBhY2thZ2VzLCB1c2UgZ2V0UGFja2FnZU5hbWVzIGluc3RlYWQuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycykgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDb21wb3NlciByZXBvc2l0b3JpZXMgdGhhdCBoYXZlIHByb3ZpZGVycyBjYW4gbm90IGxvYWQgdGhlIGNvbXBsZXRlIGxpc3Qgb2YgcGFja2FnZXMsIHVzZSBnZXRQYWNrYWdlTmFtZXMgaW5zdGVhZC4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmdldFBhY2thZ2VzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2VOYW1lcygkcGFja2FnZUZpbHRlciA9IG51bGwpCiAgICB7CiAgICAgICAgJGhhc1Byb3ZpZGVycyA9ICR0aGlzLT5oYXNQcm92aWRlcnMoKTsKCiAgICAgICAgJHBhY2thZ2VGaWx0ZXJDYiA9IGZ1bmN0aW9uICgkbmFtZSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9OwogICAgICAgIGlmIChudWxsICE9PSAkcGFja2FnZUZpbHRlcikgewogICAgICAgICAgICAkcGFja2FnZUZpbHRlclJlZ2V4ID0gJ3teJy5zdHJfcmVwbGFjZSgnXFwqJywgJy4qPycsIHByZWdfcXVvdGUoJHBhY2thZ2VGaWx0ZXIpKS4nJH1pJzsKICAgICAgICAgICAgJHBhY2thZ2VGaWx0ZXJDYiA9IGZ1bmN0aW9uICgkbmFtZSkgdXNlICgkcGFja2FnZUZpbHRlclJlZ2V4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGJvb2wpIHByZWdfbWF0Y2goJHBhY2thZ2VGaWx0ZXJSZWdleCwgJG5hbWUpOwogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5sYXp5UHJvdmlkZXJzVXJsKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdGhpcy0+YXZhaWxhYmxlUGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfZmlsdGVyKGFycmF5X2tleXMoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VzKSwgJHBhY2thZ2VGaWx0ZXJDYik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+bGlzdFVybCkgewogICAgICAgICAgICAgICAgJHVybCA9ICR0aGlzLT5saXN0VXJsOwogICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlRmlsdGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJHVybCAuPSAnP2ZpbHRlcj0nLnVybGVuY29kZSgkcGFja2FnZUZpbHRlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR1cmwsICR0aGlzLT5vcHRpb25zKS0+ZGVjb2RlSnNvbigpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzdWx0WydwYWNrYWdlTmFtZXMnXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXNQYXJ0aWFsUGFja2FnZXMoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X2ZpbHRlcihhcnJheV9rZXlzKCR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWUpLCAkcGFja2FnZUZpbHRlckNiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycykgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfZmlsdGVyKCR0aGlzLT5nZXRQcm92aWRlck5hbWVzKCksICRwYWNrYWdlRmlsdGVyQ2IpOwogICAgICAgIH0KCiAgICAgICAgJG5hbWVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2VGaWx0ZXJDYigkcGFja2FnZS0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgJG5hbWVzW10gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5hbWVzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VOYW1lTWFwLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAvLyB0aGlzIGNhbGwgaW5pdGlhbGl6ZXMgbG9hZFJvb3RTZXJ2ZXJGaWxlIHdoaWNoIGlzIG5lZWRlZCBmb3IgdGhlIHJlc3QgYmVsb3cgdG8gd29yawogICAgICAgICRoYXNQcm92aWRlcnMgPSAkdGhpcy0+aGFzUHJvdmlkZXJzKCk7CgogICAgICAgIGlmICghJGhhc1Byb3ZpZGVycyAmJiAhJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpICYmICEkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50Ojpsb2FkUGFja2FnZXMoJHBhY2thZ2VOYW1lTWFwLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsICRhbHJlYWR5TG9hZGVkKTsKICAgICAgICB9CgogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJG5hbWVzRm91bmQgPSBhcnJheSgpOwoKICAgICAgICBpZiAoJGhhc1Byb3ZpZGVycyB8fCAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzKCkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VOYW1lTWFwIGFzICRuYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgLy8gaWYgYSByZXBvIGhhcyBubyBwcm92aWRlcnMgYnV0IG9ubHkgcGFydGlhbCBwYWNrYWdlcyBhbmQgdGhlIHBhcnRpYWwgcGFja2FnZXMgYXJlIG1pc3NpbmcKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2UgZG9uJ3Qgd2FudCB0byBjYWxsIHdoYXRQcm92aWRlcyBhcyBpdCB3b3VsZCB0cnkgdG8gbG9hZCBmcm9tIHRoZSBwcm92aWRlcnMgYW5kIGZhaWwKICAgICAgICAgICAgICAgIGlmICghJGhhc1Byb3ZpZGVycyAmJiAhaXNzZXQoJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZVskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGNhbmRpZGF0ZXMgPSAkdGhpcy0+d2hhdFByb3ZpZGVzKCRuYW1lLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsICRhbHJlYWR5TG9hZGVkKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjYW5kaWRhdGVzIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpICE9PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCd3aGF0UHJvdmlkZXMgc2hvdWxkIG5ldmVyIHJldHVybiBhIHBhY2thZ2Ugd2l0aCBhIGRpZmZlcmVudCBuYW1lIHRoYW4gdGhlIHJlcXVlc3RlZCBvbmUnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5hbWVzRm91bmRbJG5hbWVdID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkY29uc3RyYWludCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkY2FuZGlkYXRlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1tzcGxfb2JqZWN0X2hhc2goJGNhbmRpZGF0ZSldID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGUgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgJiYgIWlzc2V0KCRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSA9ICRjYW5kaWRhdGUtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBhZGQgYWxpYXNlcyBvZiBtYXRjaGVkIHBhY2thZ2VzIGV2ZW4gaWYgdGhleSBkaWQgbm90IG1hdGNoIHRoZSBjb25zdHJhaW50CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY2FuZGlkYXRlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGUgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzW3NwbF9vYmplY3RfaGFzaCgkY2FuZGlkYXRlKV0gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJHBhY2thZ2VzLCAkbWF0Y2hlcyk7CgogICAgICAgICAgICAgICAgdW5zZXQoJHBhY2thZ2VOYW1lTWFwWyRuYW1lXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiBjb3VudCgkcGFja2FnZU5hbWVNYXApKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aGFzQXZhaWxhYmxlUGFja2FnZUxpc3QpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTmFtZU1hcCBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmxhenlQcm92aWRlcnNSZXBvQ29udGFpbnMoc3RydG9sb3dlcigkbmFtZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlTmFtZU1hcFskbmFtZV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5sb2FkQXN5bmNQYWNrYWdlcygkcGFja2FnZU5hbWVNYXAsICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgJGFscmVhZHlMb2FkZWQpOwogICAgICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9tZXJnZSgkcGFja2FnZXMsICRyZXN1bHRbJ3BhY2thZ2VzJ10pOwogICAgICAgICAgICAkbmFtZXNGb3VuZCA9IGFycmF5X21lcmdlKCRuYW1lc0ZvdW5kLCAkcmVzdWx0WyduYW1lc0ZvdW5kJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCduYW1lc0ZvdW5kJyA9PiBhcnJheV9rZXlzKCRuYW1lc0ZvdW5kKSwgJ3BhY2thZ2VzJyA9PiAkcGFja2FnZXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VhcmNoKCRxdWVyeSwgJG1vZGUgPSAwLCAkdHlwZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpOwoKICAgICAgICBpZiAoJHRoaXMtPnNlYXJjaFVybCAmJiAkbW9kZSA9PT0gc2VsZjo6U0VBUkNIX0ZVTExURVhUKSB7CiAgICAgICAgICAgICR1cmwgPSBzdHJfcmVwbGFjZShhcnJheSgnJXF1ZXJ5JScsICcldHlwZSUnKSwgYXJyYXkoJHF1ZXJ5LCAkdHlwZSksICR0aGlzLT5zZWFyY2hVcmwpOwoKICAgICAgICAgICAgJHNlYXJjaCA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR1cmwsICR0aGlzLT5vcHRpb25zKS0+ZGVjb2RlSnNvbigpOwoKICAgICAgICAgICAgaWYgKGVtcHR5KCRzZWFyY2hbJ3Jlc3VsdHMnXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzdWx0cyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzZWFyY2hbJ3Jlc3VsdHMnXSBhcyAkcmVzdWx0KSB7CiAgICAgICAgICAgICAgICAvLyBkbyBub3Qgc2hvdyB2aXJ0dWFsIHBhY2thZ2VzIGluIHJlc3VsdHMgYXMgdGhleSBhcmUgbm90IGRpcmVjdGx5IHVzZWZ1bCBmcm9tIGEgY29tcG9zZXIgcGVyc3BlY3RpdmUKICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkcmVzdWx0Wyd2aXJ0dWFsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9ICRyZXN1bHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0czsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aGFzUHJvdmlkZXJzKCkgfHwgJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpIHsKICAgICAgICAgICAgJHJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgICAgICAkcmVnZXggPSAneyg/OicuaW1wbG9kZSgnfCcsIHByZWdfc3BsaXQoJ3tccyt9JywgJHF1ZXJ5KSkuJyl9aSc7CgogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Z2V0UGFja2FnZU5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCRyZWdleCwgJG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0czsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OnNlYXJjaCgkcXVlcnksICRtb2RlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvdmlkZXJzKCRwYWNrYWdlTmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9hZFJvb3RTZXJ2ZXJGaWxlKCk7CiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CgogICAgICAgIGlmICgkdGhpcy0+cHJvdmlkZXJzQXBpVXJsKSB7CiAgICAgICAgICAgICRhcGlSZXN1bHQgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldChzdHJfcmVwbGFjZSgnJXBhY2thZ2UlJywgJHBhY2thZ2VOYW1lLCAkdGhpcy0+cHJvdmlkZXJzQXBpVXJsKSwgJHRoaXMtPm9wdGlvbnMpLT5kZWNvZGVKc29uKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkYXBpUmVzdWx0Wydwcm92aWRlcnMnXSBhcyAkcHJvdmlkZXIpIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbJHByb3ZpZGVyWyduYW1lJ11dID0gJHByb3ZpZGVyOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzKCkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZSBhcyAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXN1bHRbJGNhbmRpZGF0ZVsnbmFtZSddXSkgfHwgIWlzc2V0KCRjYW5kaWRhdGVbJ3Byb3ZpZGUnXVskcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFskY2FuZGlkYXRlWyduYW1lJ11dID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICduYW1lJyA9PiAkY2FuZGlkYXRlWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gaXNzZXQoJGNhbmRpZGF0ZVsnZGVzY3JpcHRpb24nXSkgPyAkY2FuZGlkYXRlWydkZXNjcmlwdGlvbiddIDogJycsCiAgICAgICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiBpc3NldCgkY2FuZGlkYXRlWyd0eXBlJ10pID8gJGNhbmRpZGF0ZVsndHlwZSddIDogJycsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wYWNrYWdlcykgewogICAgICAgICAgICAkcmVzdWx0ID0gYXJyYXlfbWVyZ2UoJHJlc3VsdCwgcGFyZW50OjpnZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFByb3ZpZGVyTmFtZXMoKQogICAgewogICAgICAgICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5wcm92aWRlckxpc3RpbmcpIHsKICAgICAgICAgICAgJHRoaXMtPmxvYWRQcm92aWRlckxpc3RpbmdzKCR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpIHsKICAgICAgICAgICAgLy8gQ2FuIG5vdCBkZXRlcm1pbmUgbGlzdCBvZiBwcm92aWRlZCBwYWNrYWdlcyBmb3IgbGF6eSByZXBvc2l0b3JpZXMKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnByb3ZpZGVyc1VybCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfa2V5cygkdGhpcy0+cHJvdmlkZXJMaXN0aW5nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmVQYWNrYWdlVHJhbnNwb3J0T3B0aW9ucyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXREaXN0VXJscygpIGFzICR1cmwpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkdXJsLCAkdGhpcy0+YmFzZVVybCkgPT09IDApIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRUcmFuc3BvcnRPcHRpb25zKCR0aGlzLT5vcHRpb25zKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBoYXNQcm92aWRlcnMoKQogICAgewogICAgICAgICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNQcm92aWRlcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRuYW1lIHBhY2thZ2UgbmFtZQogICAgICogQHJldHVybiBhcnJheXxtaXhlZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdoYXRQcm92aWRlcygkbmFtZSwgYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcyA9IG51bGwsIGFycmF5ICRzdGFiaWxpdHlGbGFncyA9IG51bGwsIGFycmF5ICRhbHJlYWR5TG9hZGVkID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSBudWxsOwogICAgICAgIGlmICghJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcygpIHx8ICFpc3NldCgkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lWyRuYW1lXSkpIHsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSBwYWNrYWdlcywgcm9vdCBwYWNrYWdlIGFuZCBjb21wb3Nlci1wbHVnaW4tYXBpCiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSB8fCAnX19yb290X18nID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cHJvdmlkZXJMaXN0aW5nKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFByb3ZpZGVyTGlzdGluZ3MoJHRoaXMtPmxvYWRSb290U2VydmVyRmlsZSgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVzZUxhc3RNb2RpZmllZENoZWNrID0gZmFsc2U7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiAhaXNzZXQoJHRoaXMtPnByb3ZpZGVyTGlzdGluZ1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkaGFzaCA9IG51bGw7CiAgICAgICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoJyVwYWNrYWdlJScsICRuYW1lLCAkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCk7CiAgICAgICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnJCcpLicuanNvbic7CiAgICAgICAgICAgICAgICAkdXNlTGFzdE1vZGlmaWVkQ2hlY2sgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnByb3ZpZGVyc1VybCkgewogICAgICAgICAgICAgICAgLy8gcGFja2FnZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHJlcG8KICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnByb3ZpZGVyTGlzdGluZ1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGhhc2ggPSAkdGhpcy0+cHJvdmlkZXJMaXN0aW5nWyRuYW1lXVsnc2hhMjU2J107CiAgICAgICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVwYWNrYWdlJScsICclaGFzaCUnKSwgYXJyYXkoJG5hbWUsICRoYXNoKSwgJHRoaXMtPnByb3ZpZGVyc1VybCk7CiAgICAgICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnJCcpLicuanNvbic7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBhY2thZ2VzID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRjYWNoZUtleSkgewogICAgICAgICAgICAgICAgaWYgKCEkdXNlTGFzdE1vZGlmaWVkQ2hlY2sgJiYgJGhhc2ggJiYgJHRoaXMtPmNhY2hlLT5zaGEyNTYoJGNhY2hlS2V5KSA9PT0gJGhhc2gpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXMgPSBqc29uX2RlY29kZSgkdGhpcy0+Y2FjaGUtPnJlYWQoJGNhY2hlS2V5KSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzU291cmNlID0gJ2NhY2hlZCBmaWxlICgnLiRjYWNoZUtleS4nIG9yaWdpbmF0aW5nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkdXNlTGFzdE1vZGlmaWVkQ2hlY2spIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRlbnRzID0gJHRoaXMtPmNhY2hlLT5yZWFkKCRjYWNoZUtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnRzID0ganNvbl9kZWNvZGUoJGNvbnRlbnRzLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgYWxyZWFkeSBsb2FkZWQgc29tZSBwYWNrYWdlcyBmcm9tIHRoaXMgZmlsZSwgc28gYXNzdW1lIGl0IGlzIGZyZXNoIGFuZCBhdm9pZCBmZXRjaGluZyBpdCBhZ2FpbgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGFscmVhZHlMb2FkZWRbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJGNvbnRlbnRzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzU291cmNlID0gJ2NhY2hlZCBmaWxlICgnLiRjYWNoZUtleS4nIG9yaWdpbmF0aW5nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRjb250ZW50c1snbGFzdC1tb2RpZmllZCddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmZldGNoRmlsZUlmTGFzdE1vZGlmaWVkKCR1cmwsICRjYWNoZUtleSwgJGNvbnRlbnRzWydsYXN0LW1vZGlmaWVkJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gdHJ1ZSA9PT0gJHJlc3BvbnNlID8gJGNvbnRlbnRzIDogJHJlc3BvbnNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzU291cmNlID0gdHJ1ZSA9PT0gJHJlc3BvbnNlID8gJ2NhY2hlZCBmaWxlICgnLiRjYWNoZUtleS4nIG9yaWdpbmF0aW5nIGZyb20gJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJyA6ICdkb3dubG9hZGVkIGZpbGUgKCcuVXJsOjpzYW5pdGl6ZSgkdXJsKS4nKSc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICR0aGlzLT5mZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkaGFzaCwgJHVzZUxhc3RNb2RpZmllZENoZWNrKTsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSAnZG93bmxvYWRlZCBmaWxlICgnLlVybDo6c2FuaXRpemUoJHVybCkuJyknOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gNDA0cyBhcmUgYWNjZXB0YWJsZSBmb3IgbGF6eSBwcm92aWRlciByZXBvcwogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCAmJiBpbl9hcnJheSgkZS0+Z2V0U3RhdHVzQ29kZSgpLCBhcnJheSg0MDQsIDQ5OSksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCdwYWNrYWdlcycgPT4gYXJyYXkoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdub3QtZm91bmQgZmlsZSAoJy5Vcmw6OnNhbml0aXplKCR1cmwpLicpJzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQ5OSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5lcnJvcignPHdhcm5pbmc+JyAuICRlLT5nZXRNZXNzYWdlKCkgLiAnPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkbG9hZGluZ1BhcnRpYWxQYWNrYWdlID0gZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoJ3BhY2thZ2VzJyA9PiBhcnJheSgndmVyc2lvbnMnID0+ICR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbJG5hbWVdKSk7CiAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdyb290IGZpbGUgKCcuVXJsOjpzYW5pdGl6ZSgkdGhpcy0+Z2V0UGFja2FnZXNKc29uVXJsKCkpLicpJzsKICAgICAgICAgICAgJGxvYWRpbmdQYXJ0aWFsUGFja2FnZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAkdmVyc2lvbnNUb0xvYWQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlc1sncGFja2FnZXMnXSBhcyAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zIGFzICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAkbm9ybWFsaXplZE5hbWUgPSBzdHJ0b2xvd2VyKCR2ZXJzaW9uWyduYW1lJ10pOwoKICAgICAgICAgICAgICAgIC8vIG9ubHkgbG9hZCB0aGUgYWN0dWFsIG5hbWVkIHBhY2thZ2UsIG5vdCBvdGhlciBwYWNrYWdlcyB0aGF0IG1pZ2h0IGZpbmQgdGhlbXNlbHZlcyBpbiB0aGUgc2FtZSBmaWxlCiAgICAgICAgICAgICAgICBpZiAoJG5vcm1hbGl6ZWROYW1lICE9PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJGxvYWRpbmdQYXJ0aWFsUGFja2FnZSAmJiAkdGhpcy0+aGFzUGFydGlhbFBhY2thZ2VzKCkgJiYgaXNzZXQoJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZVskbm9ybWFsaXplZE5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHZlcnNpb25zVG9Mb2FkWyR2ZXJzaW9uWyd1aWQnXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHZlcnNpb25bJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9PT0gVmVyc2lvblBhcnNlcjo6REVGQVVMVF9CUkFOQ0hfQUxJQVMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxpbmcgb2YgZXhpc3RpbmcgcmVwb3Mgd2hpY2ggbmVlZCB0byByZW1haW4gY29tcG9zZXIgdjEgY29tcGF0aWJsZSwgaW4gY2FzZSB0aGUgdmVyc2lvbl9ub3JtYWxpemVkIGNvbnRhaW5lZCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUywgd2UgcmVub3JtYWxpemUgaXQKICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25bJ3ZlcnNpb25fbm9ybWFsaXplZCddID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkdmVyc2lvblsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGxvYWRpbmcgcGFja2FnZXMgd2hpY2ggaGF2ZSBhbHJlYWR5IGJlZW4gbG9hZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhbHJlYWR5TG9hZGVkWyRuYW1lXVskdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ11dKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aXNWZXJzaW9uQWNjZXB0YWJsZShudWxsLCAkbm9ybWFsaXplZE5hbWUsICR2ZXJzaW9uLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uc1RvTG9hZFskdmVyc2lvblsndWlkJ11dID0gJHZlcnNpb247CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBsb2FkIGFjY2VwdGFibGUgcGFja2FnZXMgaW4gdGhlIHByb3ZpZGVycwogICAgICAgICRsb2FkZWRQYWNrYWdlcyA9ICR0aGlzLT5jcmVhdGVQYWNrYWdlcygkdmVyc2lvbnNUb0xvYWQsICRwYWNrYWdlc1NvdXJjZSk7CiAgICAgICAgJHVpZHMgPSBhcnJheV9rZXlzKCR2ZXJzaW9uc1RvTG9hZCk7CgogICAgICAgIGZvcmVhY2ggKCRsb2FkZWRQYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldFJlcG9zaXRvcnkoJHRoaXMpOwogICAgICAgICAgICAkdWlkID0gJHVpZHNbJGluZGV4XTsKCiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGFsaWFzZWQgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgJGFsaWFzZWQtPnNldFJlcG9zaXRvcnkoJHRoaXMpOwoKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZF0gPSAkYWxpYXNlZDsKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZC4nLWFsaWFzJ10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbJHVpZF0gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBwYXJlbnQ6OmluaXRpYWxpemUoKTsKCiAgICAgICAgJHJlcG9EYXRhID0gJHRoaXMtPmxvYWREYXRhRnJvbVNlcnZlcigpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y3JlYXRlUGFja2FnZXMoJHJlcG9EYXRhLCAncm9vdCBmaWxlICgnLlVybDo6c2FuaXRpemUoJHRoaXMtPmdldFBhY2thZ2VzSnNvblVybCgpKS4nKScpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmV3IHBhY2thZ2UgdG8gdGhlIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHBhcmVudDo6YWRkUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgJHRoaXMtPmNvbmZpZ3VyZVBhY2thZ2VUcmFuc3BvcnRPcHRpb25zKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkcGFja2FnZU5hbWVzIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBDb25zdHJhaW50SW50ZXJmYWNlfG51bGwgLSBpZiBhIGNvbnN0cmFpbnQgaXMgcHJvdmlkZWQsIG9ubHkgcGFja2FnZXMgbWF0Y2hpbmcgaXQgd2lsbCBiZSBsb2FkZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkQXN5bmNQYWNrYWdlcyhhcnJheSAkcGFja2FnZU5hbWVzLCBhcnJheSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzID0gbnVsbCwgYXJyYXkgJHN0YWJpbGl0eUZsYWdzID0gbnVsbCwgYXJyYXkgJGFscmVhZHlMb2FkZWQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKCiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkbmFtZXNGb3VuZCA9IGFycmF5KCk7CiAgICAgICAgJHByb21pc2VzID0gYXJyYXkoKTsKICAgICAgICAkcmVwbyA9ICR0aGlzOwoKICAgICAgICBpZiAoISR0aGlzLT5sYXp5UHJvdmlkZXJzVXJsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ2xvYWRBc3luY1BhY2thZ2VzIG9ubHkgc3VwcG9ydHMgdjIgcHJvdG9jb2wgY29tcG9zZXIgcmVwb3Mgd2l0aCBhIG1ldGFkYXRhLXVybCcpOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9hZCB+ZGV2IHZlcnNpb25zIG9mIHRoZSBwYWNrYWdlcyBhcyB3ZWxsIGlmIG5lZWRlZAogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTmFtZXMgYXMgJG5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgPT09IG51bGwgfHwgJHN0YWJpbGl0eUZsYWdzID09PSBudWxsIHx8IFN0YWJpbGl0eUZpbHRlcjo6aXNQYWNrYWdlQWNjZXB0YWJsZSgkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5KCRuYW1lKSwgJ2RldicpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZU5hbWVzWyRuYW1lLid+ZGV2J10gPSAkY29uc3RyYWludDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBpZiBvbmx5IGRldiBzdGFiaWxpdHkgaXMgcmVxdWVzdGVkLCB3ZSBza2lwIGxvYWRpbmcgdGhlIG5vbiBkZXYgZmlsZQogICAgICAgICAgICBpZiAoaXNzZXQoJGFjY2VwdGFibGVTdGFiaWxpdGllc1snZGV2J10pICYmIGNvdW50KCRhY2NlcHRhYmxlU3RhYmlsaXRpZXMpID09PSAxICYmIGNvdW50KCRzdGFiaWxpdHlGbGFncykgPT09IDApIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlTmFtZXNbJG5hbWVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VOYW1lcyBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwoKICAgICAgICAgICAgJHJlYWxOYW1lID0gcHJlZ19yZXBsYWNlKCd7fmRldiR9JywgJycsICRuYW1lKTsKICAgICAgICAgICAgLy8gc2tpcCBwbGF0Zm9ybSBwYWNrYWdlcywgcm9vdCBwYWNrYWdlIGFuZCBjb21wb3Nlci1wbHVnaW4tYXBpCiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZWFsTmFtZSkgfHwgJ19fcm9vdF9fJyA9PT0gJHJlYWxOYW1lKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHVybCA9IHN0cl9yZXBsYWNlKCclcGFja2FnZSUnLCAkbmFtZSwgJHRoaXMtPmxhenlQcm92aWRlcnNVcmwpOwogICAgICAgICAgICAkY2FjaGVLZXkgPSAncHJvdmlkZXItJy5zdHJ0cigkbmFtZSwgJy8nLCAnficpLicuanNvbic7CgogICAgICAgICAgICAkbGFzdE1vZGlmaWVkID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRjb250ZW50cyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpKSB7CiAgICAgICAgICAgICAgICAkY29udGVudHMgPSBqc29uX2RlY29kZSgkY29udGVudHMsIHRydWUpOwogICAgICAgICAgICAgICAgJGxhc3RNb2RpZmllZCA9IGlzc2V0KCRjb250ZW50c1snbGFzdC1tb2RpZmllZCddKSA/ICRjb250ZW50c1snbGFzdC1tb2RpZmllZCddIDogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb21pc2VzW10gPSAkdGhpcy0+YXN5bmNGZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkbGFzdE1vZGlmaWVkKQogICAgICAgICAgICAgICAgLT50aGVuKGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJiRwYWNrYWdlcywgJiRuYW1lc0ZvdW5kLCAkdXJsLCAkY2FjaGVLZXksICRjb250ZW50cywgJHJlYWxOYW1lLCAkY29uc3RyYWludCwgJHJlcG8sICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsICRzdGFiaWxpdHlGbGFncywgJGFscmVhZHlMb2FkZWQpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNTb3VyY2UgPSAnZG93bmxvYWRlZCBmaWxlICgnLlVybDo6c2FuaXRpemUoJHVybCkuJyknOwoKICAgICAgICAgICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJHJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1NvdXJjZSA9ICdjYWNoZWQgZmlsZSAoJy4kY2FjaGVLZXkuJyBvcmlnaW5hdGluZyBmcm9tICcuVXJsOjpzYW5pdGl6ZSgkdXJsKS4nKSc7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICRjb250ZW50czsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHJlc3BvbnNlWydwYWNrYWdlcyddWyRyZWFsTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9ICRyZXNwb25zZVsncGFja2FnZXMnXVskcmVhbE5hbWVdOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJlc3BvbnNlWydtaW5pZmllZCddKSAmJiAkcmVzcG9uc2VbJ21pbmlmaWVkJ10gPT09ICdjb21wb3Nlci8yLjAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9IE1ldGFkYXRhTWluaWZpZXI6OmV4cGFuZCgkdmVyc2lvbnMpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJG5hbWVzRm91bmRbJHJlYWxOYW1lXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zVG9Mb2FkID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvblsndmVyc2lvbl9ub3JtYWxpemVkJ10gPSAkcmVwby0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHZlcnNpb25bJ3ZlcnNpb25fbm9ybWFsaXplZCddID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxpbmcgb2YgZXhpc3RpbmcgcmVwb3Mgd2hpY2ggbmVlZCB0byByZW1haW4gY29tcG9zZXIgdjEgY29tcGF0aWJsZSwgaW4gY2FzZSB0aGUgdmVyc2lvbl9ub3JtYWxpemVkIGNvbnRhaW5lZCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUywgd2UgcmVub3JtYWxpemUgaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXSA9ICRyZXBvLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHZlcnNpb25bJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGxvYWRpbmcgcGFja2FnZXMgd2hpY2ggaGF2ZSBhbHJlYWR5IGJlZW4gbG9hZGVkCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYWxyZWFkeUxvYWRlZFskcmVhbE5hbWVdWyR2ZXJzaW9uWyd2ZXJzaW9uX25vcm1hbGl6ZWQnXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXBvLT5pc1ZlcnNpb25BY2NlcHRhYmxlKCRjb25zdHJhaW50LCAkcmVhbE5hbWUsICR2ZXJzaW9uLCAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnNUb0xvYWRbXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkbG9hZGVkUGFja2FnZXMgPSAkcmVwby0+Y3JlYXRlUGFja2FnZXMoJHZlcnNpb25zVG9Mb2FkLCAkcGFja2FnZXNTb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsb2FkZWRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0UmVwb3NpdG9yeSgkcmVwbyk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICFpc3NldCgkcGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlLT5nZXRBbGlhc09mKCkpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRBbGlhc09mKCktPnNldFJlcG9zaXRvcnkoJHJlcG8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZS0+Z2V0QWxpYXNPZigpKV0gPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9vcC0+d2FpdCgkcHJvbWlzZXMpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ25hbWVzRm91bmQnID0+ICRuYW1lc0ZvdW5kLCAncGFja2FnZXMnID0+ICRwYWNrYWdlcyk7CiAgICAgICAgLy8gUmVwb3NpdG9yeVNldCBzaG91bGQgY2FsbCBsb2FkTWV0YWRhdGEsIGdldE1ldGFkYXRhIHdoZW4gYWxsIHByb21pc2VzIHJlc29sdmVkLCB0aGVuIG1ldGFkYXRhQ29tcGxldGUgd2hlbiBkb25lIHNvIHdlIGNhbiBHQyB0aGUgbG9hZGVkIGpzb24gYW5kIHdoYXRub3QgdGhlbiBhcyBuZWVkZWQKICAgIH0KCiAgICAvKioKICAgICAqIFRPRE8gdjMgc2hvdWxkIG1ha2UgdGhpcyBwcml2YXRlIG9uY2Ugd2UgY2FuIGRyb3AgUEhQIDUuMyBzdXBwb3J0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBwYWNrYWdlIG5hbWUgKG11c3QgYmUgbG93ZXJjYXNlZCBhbHJlYWR5KQogICAgICogQHByaXZhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyc2lvbkFjY2VwdGFibGUoJGNvbnN0cmFpbnQsICRuYW1lLCAkdmVyc2lvbkRhdGEsIGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgPSBudWxsLCBhcnJheSAkc3RhYmlsaXR5RmxhZ3MgPSBudWxsKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5KCR2ZXJzaW9uRGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10pOwoKICAgICAgICBpZiAoJGFsaWFzID0gJHRoaXMtPmxvYWRlci0+Z2V0QnJhbmNoQWxpYXMoJHZlcnNpb25EYXRhKSkgewogICAgICAgICAgICAkdmVyc2lvbnNbXSA9ICRhbGlhczsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAkdmVyc2lvbikgewogICAgICAgICAgICBpZiAobnVsbCAhPT0gJGFjY2VwdGFibGVTdGFiaWxpdGllcyAmJiBudWxsICE9PSAkc3RhYmlsaXR5RmxhZ3MgJiYgIVN0YWJpbGl0eUZpbHRlcjo6aXNQYWNrYWdlQWNjZXB0YWJsZSgkYWNjZXB0YWJsZVN0YWJpbGl0aWVzLCAkc3RhYmlsaXR5RmxhZ3MsIGFycmF5KCRuYW1lKSwgVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHZlcnNpb24pKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkY29uc3RyYWludCAmJiAhQ29tcGlsaW5nTWF0Y2hlcjo6bWF0Y2goJGNvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkdmVyc2lvbikpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhY2thZ2VzSnNvblVybCgpCiAgICB7CiAgICAgICAgJGpzb25VcmxQYXJ0cyA9IHBhcnNlX3VybCgkdGhpcy0+dXJsKTsKCiAgICAgICAgaWYgKGlzc2V0KCRqc29uVXJsUGFydHNbJ3BhdGgnXSkgJiYgZmFsc2UgIT09IHN0cnBvcygkanNvblVybFBhcnRzWydwYXRoJ10sICcuanNvbicpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT51cmwgLiAnL3BhY2thZ2VzLmpzb24nOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBsb2FkUm9vdFNlcnZlckZpbGUoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+cm9vdERhdGEpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yb290RGF0YTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpICYmIHN0cnBvcygkdGhpcy0+dXJsLCAnaHR0cHMnKSA9PT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1lvdSBtdXN0IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24gaW4geW91ciBwaHAuaW5pIHRvIGxvYWQgaW5mb3JtYXRpb24gZnJvbSAnLiR0aGlzLT51cmwpOwogICAgICAgIH0KCiAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZmV0Y2hGaWxlKCR0aGlzLT5nZXRQYWNrYWdlc0pzb25VcmwoKSwgJ3BhY2thZ2VzLmpzb24nKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsnbm90aWZ5LWJhdGNoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnlVcmwgPSAkdGhpcy0+Y2Fub25pY2FsaXplVXJsKCRkYXRhWydub3RpZnktYmF0Y2gnXSk7CiAgICAgICAgfSBlbHNlaWYgKCFlbXB0eSgkZGF0YVsnbm90aWZ5J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5ub3RpZnlVcmwgPSAkdGhpcy0+Y2Fub25pY2FsaXplVXJsKCRkYXRhWydub3RpZnknXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydzZWFyY2gnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNlYXJjaFVybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ3NlYXJjaCddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ21pcnJvcnMnXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGFbJ21pcnJvcnMnXSBhcyAkbWlycm9yKSB7CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRtaXJyb3JbJ2dpdC11cmwnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c291cmNlTWlycm9yc1snZ2l0J11bXSA9IGFycmF5KCd1cmwnID0+ICRtaXJyb3JbJ2dpdC11cmwnXSwgJ3ByZWZlcnJlZCcgPT4gIWVtcHR5KCRtaXJyb3JbJ3ByZWZlcnJlZCddKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRtaXJyb3JbJ2hnLXVybCddKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zb3VyY2VNaXJyb3JzWydoZyddW10gPSBhcnJheSgndXJsJyA9PiAkbWlycm9yWydoZy11cmwnXSwgJ3ByZWZlcnJlZCcgPT4gIWVtcHR5KCRtaXJyb3JbJ3ByZWZlcnJlZCddKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRtaXJyb3JbJ2Rpc3QtdXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRpc3RNaXJyb3JzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ3VybCcgPT4gJHRoaXMtPmNhbm9uaWNhbGl6ZVVybCgkbWlycm9yWydkaXN0LXVybCddKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3ByZWZlcnJlZCcgPT4gIWVtcHR5KCRtaXJyb3JbJ3ByZWZlcnJlZCddKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydwcm92aWRlcnMtbGF6eS11cmwnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmxhenlQcm92aWRlcnNVcmwgPSAkdGhpcy0+Y2Fub25pY2FsaXplVXJsKCRkYXRhWydwcm92aWRlcnMtbGF6eS11cmwnXSk7CiAgICAgICAgICAgICR0aGlzLT5oYXNQcm92aWRlcnMgPSB0cnVlOwoKICAgICAgICAgICAgJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcyA9ICFlbXB0eSgkZGF0YVsncGFja2FnZXMnXSkgJiYgaXNfYXJyYXkoJGRhdGFbJ3BhY2thZ2VzJ10pOwogICAgICAgIH0KCiAgICAgICAgLy8gSG9ycmlibGUgaGFjayB0byB3b3JrYXJvdW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvOTI5NyBhbmQgYmFkIG1pcnJvcnMsIHNob3VsZCBiZSBkaXNhYmxlZCBpZiBwb3NzaWJsZSBvbmNlIHRoZXkgZml4IHRoaW5ncwogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ21ldGFkYXRhLXVybCddKSAmJiAhZW1wdHkoJGRhdGFbJ2xpc3QnXSkgJiYgJGRhdGFbJ21ldGFkYXRhLXVybCddID09PSAnL3AvJXBhY2thZ2UlLmpzb24nICYmICRkYXRhWydsaXN0J10gPT09ICdodHRwczovL3BhY2thZ2lzdC5vcmcvcGFja2FnZXMvbGlzdC5qc29uJykgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNvbXBvc2VyIDIgcmVwb3NpdG9yeSBzdXBwb3J0IGZvciAnLiR0aGlzLT51cmwuJyBoYXMgYmVlbiBkaXNhYmxlZCBkdWUgdG8gd2hhdCBzZWVtcyBsaWtlIGEgbWlzY29uZmlndXJhdGlvbi4gSWYgdGhpcyBpcyBhIHBhY2thZ2lzdC5vcmcgbWlycm9yIHdlIHJlY29tbWVuZCByZW1vdmluZyBpdCBhcyBDb21wb3NlciAyIGhhbmRsZXMgbmV0d29yayBvcGVyYXRpb25zIG11Y2ggZmFzdGVyIGFuZCBzaG91bGQgd29yayBmaW5lIHdpdGhvdXQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB1bnNldCgkZGF0YVsnbWV0YWRhdGEtdXJsJ10pOwogICAgICAgIH0KCiAgICAgICAgLy8gbWV0YWRhdGEtdXJsIGluZGljYXRlcyBWMiByZXBvIHByb3RvY29sIHNvIGl0IHRha2VzIG92ZXIgZnJvbSBhbGwgdGhlIFYxIHR5cGVzCiAgICAgICAgLy8gVjIgb25seSBoYXMgbGF6eVByb3ZpZGVycyBhbmQgcG9zc2libHkgcGFydGlhbCBwYWNrYWdlcywgYnV0IG5vIGFiaWxpdHkgdG8gcHJvY2VzcyBhbnl0aGluZyBlbHNlLAogICAgICAgIC8vIFYyIGFsc28gc3VwcG9ydHMgYXN5bmMgbG9hZGluZwogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ21ldGFkYXRhLXVybCddKSkgewogICAgICAgICAgICAkdGhpcy0+bGF6eVByb3ZpZGVyc1VybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ21ldGFkYXRhLXVybCddKTsKICAgICAgICAgICAgJHRoaXMtPnByb3ZpZGVyc1VybCA9IG51bGw7CiAgICAgICAgICAgICR0aGlzLT5oYXNQcm92aWRlcnMgPSBmYWxzZTsKICAgICAgICAgICAgJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcyA9ICFlbXB0eSgkZGF0YVsncGFja2FnZXMnXSkgJiYgaXNfYXJyYXkoJGRhdGFbJ3BhY2thZ2VzJ10pOwogICAgICAgICAgICAkdGhpcy0+YWxsb3dTc2xEb3duZ3JhZGUgPSBmYWxzZTsKCiAgICAgICAgICAgIC8vIHByb3ZpZGVzIGEgbGlzdCBvZiBwYWNrYWdlIG5hbWVzIHRoYXQgYXJlIGF2YWlsYWJsZSBpbiB0aGlzIHJlcG8KICAgICAgICAgICAgLy8gdGhpcyBkaXNhYmxlcyBsYXp5LXByb3ZpZGVyIGJlaGF2aW9yIGluIHRoZSBzZW5zZSB0aGF0IGlmIGEgbGlzdCBpcyBhdmFpbGFibGUgd2UgYXNzdW1lIGl0IGlzIGZpbml0ZSBhbmQgd29uJ3Qgc2VhcmNoIGZvciBvdGhlciBwYWNrYWdlcyBpbiB0aGF0IHJlcG8KICAgICAgICAgICAgLy8gd2hpbGUgaWYgbm8gbGlzdCBpcyB0aGVyZSBsYXp5UHJvdmlkZXJzVXJsIGlzIHVzZWQgd2hlbiBsb29raW5nIGZvciBhbnkgcGFja2FnZSBuYW1lIHRvIHNlZSBpZiB0aGUgcmVwbyBrbm93cyBpdAogICAgICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydhdmFpbGFibGUtcGFja2FnZXMnXSkpIHsKICAgICAgICAgICAgICAgICRhdmFpbFBhY2thZ2VzID0gYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgJGRhdGFbJ2F2YWlsYWJsZS1wYWNrYWdlcyddKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hdmFpbGFibGVQYWNrYWdlcyA9IGFycmF5X2NvbWJpbmUoJGF2YWlsUGFja2FnZXMsICRhdmFpbFBhY2thZ2VzKTsKICAgICAgICAgICAgICAgICR0aGlzLT5oYXNBdmFpbGFibGVQYWNrYWdlTGlzdCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFByb3ZpZGVzIGEgbGlzdCBvZiBwYWNrYWdlIG5hbWUgcGF0dGVybnMgKHVzaW5nICogd2lsZGNhcmRzIHRvIG1hdGNoIGFueSBzdWJzdHJpbmcsIGUuZy4gInZlbmRvci8qIikgdGhhdCBhcmUgYXZhaWxhYmxlIGluIHRoaXMgcmVwbwogICAgICAgICAgICAvLyBEaXNhYmxlcyBsYXp5LXByb3ZpZGVyIGJlaGF2aW9yIGFzIHdpdGggYXZhaWxhYmxlLXBhY2thZ2VzLCBidXQgbWF5IGFsbG93IG11Y2ggbW9yZSBjb21wYWN0IGV4cHJlc3Npb24gb2YgcGFja2FnZXMgY292ZXJlZCBieSB0aGlzIHJlcG9zaXRvcnkuCiAgICAgICAgICAgIC8vIE92ZXItc3BlY2lmeWluZyBjb3ZlcmVkIHBhY2thZ2VzIGlzIHNhZmUsIGJ1dCBtYXkgcmVzdWx0IGluIGluY3JlYXNlZCB0cmFmZmljIHRvIHlvdXIgcmVwb3NpdG9yeS4KICAgICAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsnYXZhaWxhYmxlLXBhY2thZ2UtcGF0dGVybnMnXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hdmFpbGFibGVQYWNrYWdlUGF0dGVybnMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRwYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYXR0ZXJuKTsKICAgICAgICAgICAgICAgIH0sICRkYXRhWydhdmFpbGFibGUtcGFja2FnZS1wYXR0ZXJucyddKTsKICAgICAgICAgICAgICAgICR0aGlzLT5oYXNBdmFpbGFibGVQYWNrYWdlTGlzdCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFJlbW92ZSBsZWdhY3kga2V5cyBhcyBtb3N0IHJlcG9zIG5lZWQgdG8gYmUgY29tcGF0aWJsZSB3aXRoIENvbXBvc2VyIHYxCiAgICAgICAgICAgIC8vIGFzIHdlbGwgYnV0IHdlIGFyZSBub3QgaW50ZXJlc3RlZCBpbiB0aGUgb2xkIGZvcm1hdCBhbnltb3JlIGF0IHRoaXMgcG9pbnQKICAgICAgICAgICAgdW5zZXQoJGRhdGFbJ3Byb3ZpZGVycy11cmwnXSwgJGRhdGFbJ3Byb3ZpZGVycyddLCAkZGF0YVsncHJvdmlkZXJzLWluY2x1ZGVzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5hbGxvd1NzbERvd25ncmFkZSkgewogICAgICAgICAgICAkdGhpcy0+dXJsID0gc3RyX3JlcGxhY2UoJ2h0dHBzOi8vJywgJ2h0dHA6Ly8nLCAkdGhpcy0+dXJsKTsKICAgICAgICAgICAgJHRoaXMtPmJhc2VVcmwgPSBzdHJfcmVwbGFjZSgnaHR0cHM6Ly8nLCAnaHR0cDovLycsICR0aGlzLT5iYXNlVXJsKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGRhdGFbJ3Byb3ZpZGVycy11cmwnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnByb3ZpZGVyc1VybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ3Byb3ZpZGVycy11cmwnXSk7CiAgICAgICAgICAgICR0aGlzLT5oYXNQcm92aWRlcnMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVsnbGlzdCddKSkgewogICAgICAgICAgICAkdGhpcy0+bGlzdFVybCA9ICR0aGlzLT5jYW5vbmljYWxpemVVcmwoJGRhdGFbJ2xpc3QnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydwcm92aWRlcnMnXSkgfHwgIWVtcHR5KCRkYXRhWydwcm92aWRlcnMtaW5jbHVkZXMnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmhhc1Byb3ZpZGVycyA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRkYXRhWydwcm92aWRlcnMtYXBpJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm92aWRlcnNBcGlVcmwgPSAkdGhpcy0+Y2Fub25pY2FsaXplVXJsKCRkYXRhWydwcm92aWRlcnMtYXBpJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290RGF0YSA9ICRkYXRhOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2Fub25pY2FsaXplVXJsKCR1cmwpCiAgICB7CiAgICAgICAgaWYgKCcvJyA9PT0gJHVybFswXSkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15bXjpdKys6Ly9bXi9dKit9JywgJHRoaXMtPnVybCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbMF0gLiAkdXJsOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnVybDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJsOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZERhdGFGcm9tU2VydmVyKCkKICAgIHsKICAgICAgICAkZGF0YSA9ICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkSW5jbHVkZXMoJGRhdGEpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaGFzUGFydGlhbFBhY2thZ2VzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlcyAmJiBudWxsID09PSAkdGhpcy0+cGFydGlhbFBhY2thZ2VzQnlOYW1lKSB7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplUGFydGlhbFBhY2thZ2VzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1BhcnRpYWxQYWNrYWdlczsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRQcm92aWRlckxpc3RpbmdzKCRkYXRhKQogICAgewogICAgICAgIGlmIChpc3NldCgkZGF0YVsncHJvdmlkZXJzJ10pKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHRoaXMtPnByb3ZpZGVyTGlzdGluZykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm92aWRlckxpc3RpbmcgPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcm92aWRlckxpc3RpbmcgPSBhcnJheV9tZXJnZSgkdGhpcy0+cHJvdmlkZXJMaXN0aW5nLCAkZGF0YVsncHJvdmlkZXJzJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wcm92aWRlcnNVcmwgJiYgaXNzZXQoJGRhdGFbJ3Byb3ZpZGVyLWluY2x1ZGVzJ10pKSB7CiAgICAgICAgICAgICRpbmNsdWRlcyA9ICRkYXRhWydwcm92aWRlci1pbmNsdWRlcyddOwogICAgICAgICAgICBmb3JlYWNoICgkaW5jbHVkZXMgYXMgJGluY2x1ZGUgPT4gJG1ldGFkYXRhKSB7CiAgICAgICAgICAgICAgICAkdXJsID0gJHRoaXMtPmJhc2VVcmwgLiAnLycgLiBzdHJfcmVwbGFjZSgnJWhhc2glJywgJG1ldGFkYXRhWydzaGEyNTYnXSwgJGluY2x1ZGUpOwogICAgICAgICAgICAgICAgJGNhY2hlS2V5ID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVoYXNoJScsJyQnKSwgJycsICRpbmNsdWRlKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y2FjaGUtPnNoYTI1NigkY2FjaGVLZXkpID09PSAkbWV0YWRhdGFbJ3NoYTI1NiddKSB7CiAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVkRGF0YSA9IGpzb25fZGVjb2RlKCR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVkRGF0YSA9ICR0aGlzLT5mZXRjaEZpbGUoJHVybCwgJGNhY2hlS2V5LCAkbWV0YWRhdGFbJ3NoYTI1NiddKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFByb3ZpZGVyTGlzdGluZ3MoJGluY2x1ZGVkRGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkSW5jbHVkZXMoJGRhdGEpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgLy8gbGVnYWN5IHJlcG8gaGFuZGxpbmcKICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydwYWNrYWdlcyddKSAmJiAhaXNzZXQoJGRhdGFbJ2luY2x1ZGVzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhIGFzICRwa2cpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwa2dbJ3ZlcnNpb25zJ10gYXMgJG1ldGFkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkbWV0YWRhdGE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ3BhY2thZ2VzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhWydwYWNrYWdlcyddIGFzICRwYWNrYWdlID0+ICR2ZXJzaW9ucykgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zIGFzICR2ZXJzaW9uID0+ICRtZXRhZGF0YSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJG1ldGFkYXRhOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ2luY2x1ZGVzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhWydpbmNsdWRlcyddIGFzICRpbmNsdWRlID0+ICRtZXRhZGF0YSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtZXRhZGF0YVsnc2hhMSddKSAmJiAkdGhpcy0+Y2FjaGUtPnNoYTEoJGluY2x1ZGUpID09PSAkbWV0YWRhdGFbJ3NoYTEnXSkgewogICAgICAgICAgICAgICAgICAgICRpbmNsdWRlZERhdGEgPSBqc29uX2RlY29kZSgkdGhpcy0+Y2FjaGUtPnJlYWQoJGluY2x1ZGUpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGluY2x1ZGVkRGF0YSA9ICR0aGlzLT5mZXRjaEZpbGUoJGluY2x1ZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJHBhY2thZ2VzLCAkdGhpcy0+bG9hZEluY2x1ZGVzKCRpbmNsdWRlZERhdGEpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIFRPRE8gdjMgc2hvdWxkIG1ha2UgdGhpcyBwcml2YXRlIG9uY2Ugd2UgY2FuIGRyb3AgUEhQIDUuMyBzdXBwb3J0CiAgICAgKgogICAgICogQHByaXZhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZVBhY2thZ2VzKGFycmF5ICRwYWNrYWdlcywgJHNvdXJjZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkcGFja2FnZXMpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJiRkYXRhKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydub3RpZmljYXRpb24tdXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ25vdGlmaWNhdGlvbi11cmwnXSA9ICR0aGlzLT5ub3RpZnlVcmw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwYWNrYWdlSW5zdGFuY2VzID0gJHRoaXMtPmxvYWRlci0+bG9hZFBhY2thZ2VzKCRwYWNrYWdlcywgJ0NvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlJyk7CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZUluc3RhbmNlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5zb3VyY2VNaXJyb3JzWyRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCldKSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRTb3VyY2VNaXJyb3JzKCR0aGlzLT5zb3VyY2VNaXJyb3JzWyRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0TWlycm9ycygkdGhpcy0+ZGlzdE1pcnJvcnMpOwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ3VyZVBhY2thZ2VUcmFuc3BvcnRPcHRpb25zKCRwYWNrYWdlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlSW5zdGFuY2VzOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgbG9hZCBwYWNrYWdlcyAnLihpc3NldCgkcGFja2FnZXNbMF1bJ25hbWUnXSkgPyAkcGFja2FnZXNbMF1bJ25hbWUnXSA6IGpzb25fZW5jb2RlKCRwYWNrYWdlcykpLicgaW4gJy4kdGhpcy0+Z2V0UmVwb05hbWUoKS4oJHNvdXJjZSA/ICcgZnJvbSAnLiRzb3VyY2UgOiAnJykuJzogWycuZ2V0X2NsYXNzKCRlKS4nXSAnLiRlLT5nZXRNZXNzYWdlKCksIDAsICRlKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZldGNoRmlsZSgkZmlsZW5hbWUsICRjYWNoZUtleSA9IG51bGwsICRzaGEyNTYgPSBudWxsLCAkc3RvcmVMYXN0TW9kaWZpZWRUaW1lID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRjYWNoZUtleSkgewogICAgICAgICAgICAkY2FjaGVLZXkgPSAkZmlsZW5hbWU7CiAgICAgICAgICAgICRmaWxlbmFtZSA9ICR0aGlzLT5iYXNlVXJsLicvJy4kZmlsZW5hbWU7CiAgICAgICAgfQoKICAgICAgICAvLyB1cmwtZW5jb2RlICQgc2lnbnMgaW4gVVJMcyBhcyBiYWQgcHJveGllcyBjaG9rZSBvbiB0aGVtCiAgICAgICAgaWYgKCgkcG9zID0gc3RycG9zKCRmaWxlbmFtZSwgJyQnKSkgJiYgcHJlZ19tYXRjaCgne15odHRwcz86Ly99aScsICRmaWxlbmFtZSkpIHsKICAgICAgICAgICAgJGZpbGVuYW1lID0gc3Vic3RyKCRmaWxlbmFtZSwgMCwgJHBvcykgLiAnJTI0JyAuIHN1YnN0cigkZmlsZW5hbWUsICRwb3MgKyAxKTsKICAgICAgICB9CgogICAgICAgICRyZXRyaWVzID0gMzsKICAgICAgICB3aGlsZSAoJHJldHJpZXMtLSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ldmVudERpc3BhdGNoZXIpIHsKICAgICAgICAgICAgICAgICAgICAkcHJlRmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUHJlRmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQUkVfRklMRV9ET1dOTE9BRCwgJHRoaXMtPmh0dHBEb3dubG9hZGVyLCAkZmlsZW5hbWUsICdtZXRhZGF0YScpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0TmFtZSgpLCAkcHJlRmlsZURvd25sb2FkRXZlbnQpOwogICAgICAgICAgICAgICAgICAgICRmaWxlbmFtZSA9ICRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0UHJvY2Vzc2VkVXJsKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJGZpbGVuYW1lLCAkdGhpcy0+b3B0aW9ucyk7CiAgICAgICAgICAgICAgICAkanNvbiA9ICRyZXNwb25zZS0+Z2V0Qm9keSgpOwogICAgICAgICAgICAgICAgaWYgKCRzaGEyNTYgJiYgJHNoYTI1NiAhPT0gaGFzaCgnc2hhMjU2JywgJGpzb24pKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gdW5kbyBkb3duZ3JhZGUgYmVmb3JlIHRyeWluZyBhZ2FpbiBpZiBodHRwIHNlZW1zIHRvIGJlIGhpamFja2VkIG9yIG1vZGlmeWluZyBjb250ZW50IHNvbWVob3cKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmFsbG93U3NsRG93bmdyYWRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cmwgPSBzdHJfcmVwbGFjZSgnaHR0cDovLycsICdodHRwczovLycsICR0aGlzLT51cmwpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YmFzZVVybCA9IHN0cl9yZXBsYWNlKCdodHRwOi8vJywgJ2h0dHBzOi8vJywgJHRoaXMtPmJhc2VVcmwpOwogICAgICAgICAgICAgICAgICAgICAgICAkZmlsZW5hbWUgPSBzdHJfcmVwbGFjZSgnaHR0cDovLycsICdodHRwczovLycsICRmaWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHJldHJpZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRPRE8gdXNlIHNjYXJpZXIgd29yZGluZyBvbmNlIHdlIGtub3cgZm9yIHN1cmUgaXQgZG9lc24ndCBkbyBmYWxzZSBwb3NpdGl2ZXMgYW55bW9yZQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXBvc2l0b3J5U2VjdXJpdHlFeGNlcHRpb24oJ1RoZSBjb250ZW50cyBvZiAnLiRmaWxlbmFtZS4nIGRvIG5vdCBtYXRjaCBpdHMgc2lnbmF0dXJlLiBUaGlzIGNvdWxkIGluZGljYXRlIGEgbWFuLWluLXRoZS1taWRkbGUgYXR0YWNrIG9yIGUuZy4gYW50aXZpcnVzIHNvZnR3YXJlIGNvcnJ1cHRpbmcgZmlsZXMuIFRyeSBydW5uaW5nIGNvbXBvc2VyIGFnYWluIGFuZCByZXBvcnQgdGhpcyBpZiB5b3UgdGhpbmsgaXQgaXMgYSBtaXN0YWtlLicpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRkYXRhID0gJHJlc3BvbnNlLT5kZWNvZGVKc29uKCk7CiAgICAgICAgICAgICAgICBIdHRwRG93bmxvYWRlcjo6b3V0cHV0V2FybmluZ3MoJHRoaXMtPmlvLCAkdGhpcy0+dXJsLCAkZGF0YSk7CgogICAgICAgICAgICAgICAgaWYgKCRjYWNoZUtleSAmJiAhJHRoaXMtPmNhY2hlLT5pc1JlYWRPbmx5KCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHN0b3JlTGFzdE1vZGlmaWVkVGltZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbGFzdE1vZGlmaWVkRGF0ZSA9ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdsYXN0LW1vZGlmaWVkJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGFzdE1vZGlmaWVkRGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ2xhc3QtbW9kaWZpZWQnXSA9ICRsYXN0TW9kaWZpZWREYXRlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGpzb24gPSBqc29uX2VuY29kZSgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNhY2hlLT53cml0ZSgkY2FjaGVLZXksICRqc29uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzcG9uc2UtPmNvbGxlY3QoKTsKCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgXExvZ2ljRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkcmV0cmllcykgewogICAgICAgICAgICAgICAgICAgIHVzbGVlcCgxMDAwMDApOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFJlcG9zaXRvcnlTZWN1cml0eUV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkY2FjaGVLZXkgJiYgKCRjb250ZW50cyA9ICR0aGlzLT5jYWNoZS0+cmVhZCgkY2FjaGVLZXkpKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmRlZ3JhZGVkTW9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJHRoaXMtPnVybC4nIGNvdWxkIG5vdCBiZSBmdWxseSBsb2FkZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSwgcGFja2FnZSBpbmZvcm1hdGlvbiB3YXMgbG9hZGVkIGZyb20gdGhlIGxvY2FsIGNhY2hlIGFuZCBtYXkgYmUgb3V0IG9mIGRhdGU8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5kZWdyYWRlZE1vZGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRkYXRhID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkY29udGVudHMsICR0aGlzLT5jYWNoZS0+Z2V0Um9vdCgpLiRjYWNoZUtleSk7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCRkYXRhKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJDb21wb3NlclJlcG9zaXRvcnk6IFVuZGVmaW5lZCBcJGRhdGEuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBmZXRjaEZpbGVJZkxhc3RNb2RpZmllZCgkZmlsZW5hbWUsICRjYWNoZUtleSwgJGxhc3RNb2RpZmllZFRpbWUpCiAgICB7CiAgICAgICAgJHJldHJpZXMgPSAzOwogICAgICAgIHdoaWxlICgkcmV0cmllcy0tKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgICAgICRwcmVGaWxlRG93bmxvYWRFdmVudCA9IG5ldyBQcmVGaWxlRG93bmxvYWRFdmVudChQbHVnaW5FdmVudHM6OlBSRV9GSUxFX0RPV05MT0FELCAkdGhpcy0+aHR0cERvd25sb2FkZXIsICRmaWxlbmFtZSwgJ21ldGFkYXRhJyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXROYW1lKCksICRwcmVGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgICAgICAgICAgJGZpbGVuYW1lID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICR0aGlzLT5vcHRpb25zOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gKGFycmF5KSAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddW10gPSAnSWYtTW9kaWZpZWQtU2luY2U6ICcuJGxhc3RNb2RpZmllZFRpbWU7CiAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkZmlsZW5hbWUsICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICRqc29uID0gJHJlc3BvbnNlLT5nZXRCb2R5KCk7CiAgICAgICAgICAgICAgICBpZiAoJGpzb24gPT09ICcnICYmICRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSAzMDQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkZGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICAgICAgSHR0cERvd25sb2FkZXI6Om91dHB1dFdhcm5pbmdzKCR0aGlzLT5pbywgJHRoaXMtPnVybCwgJGRhdGEpOwoKICAgICAgICAgICAgICAgICRsYXN0TW9kaWZpZWREYXRlID0gJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2xhc3QtbW9kaWZpZWQnKTsKICAgICAgICAgICAgICAgICRyZXNwb25zZS0+Y29sbGVjdCgpOwogICAgICAgICAgICAgICAgaWYgKCRsYXN0TW9kaWZpZWREYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJ2xhc3QtbW9kaWZpZWQnXSA9ICRsYXN0TW9kaWZpZWREYXRlOwogICAgICAgICAgICAgICAgICAgICRqc29uID0ganNvbl9lbmNvZGUoJGRhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+Y2FjaGUtPmlzUmVhZE9ubHkoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+d3JpdGUoJGNhY2hlS2V5LCAkanNvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRkYXRhOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBcTG9naWNFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGUtPmdldFN0YXR1c0NvZGUoKSA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRyZXRyaWVzKSB7CiAgICAgICAgICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVncmFkZWRNb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLiR0aGlzLT51cmwuJyBjb3VsZCBub3QgYmUgZnVsbHkgbG9hZGVkICgnLiRlLT5nZXRNZXNzYWdlKCkuJyksIHBhY2thZ2UgaW5mb3JtYXRpb24gd2FzIGxvYWRlZCBmcm9tIHRoZSBsb2NhbCBjYWNoZSBhbmQgbWF5IGJlIG91dCBvZiBkYXRlPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmRlZ3JhZGVkTW9kZSA9IHRydWU7CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBhc3luY0ZldGNoRmlsZSgkZmlsZW5hbWUsICRjYWNoZUtleSwgJGxhc3RNb2RpZmllZFRpbWUgPSBudWxsKQogICAgewogICAgICAgICRyZXRyaWVzID0gMzsKCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wYWNrYWdlc05vdEZvdW5kQ2FjaGVbJGZpbGVuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoYXJyYXkoJ3BhY2thZ2VzJyA9PiBhcnJheSgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmZyZXNoTWV0YWRhdGFVcmxzWyRmaWxlbmFtZV0pICYmICRsYXN0TW9kaWZpZWRUaW1lKSB7CiAgICAgICAgICAgIC8vIG1ha2UgaXQgbG9vayBsaWtlIHdlIGdvdCBhIDMwNCByZXNwb25zZQogICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSh0cnVlKTsKICAgICAgICB9CgogICAgICAgICRodHRwRG93bmxvYWRlciA9ICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgICAgICBpZiAoJHRoaXMtPmV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAkcHJlRmlsZURvd25sb2FkRXZlbnQgPSBuZXcgUHJlRmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQUkVfRklMRV9ET1dOTE9BRCwgJHRoaXMtPmh0dHBEb3dubG9hZGVyLCAkZmlsZW5hbWUsICdtZXRhZGF0YScpOwogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaCgkcHJlRmlsZURvd25sb2FkRXZlbnQtPmdldE5hbWUoKSwgJHByZUZpbGVEb3dubG9hZEV2ZW50KTsKICAgICAgICAgICAgJGZpbGVuYW1lID0gJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRQcm9jZXNzZWRVcmwoKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zID0gJHRoaXMtPm9wdGlvbnM7CiAgICAgICAgaWYgKCRsYXN0TW9kaWZpZWRUaW1lKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkpIHsKICAgICAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gKGFycmF5KSAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJ0lmLU1vZGlmaWVkLVNpbmNlOiAnLiRsYXN0TW9kaWZpZWRUaW1lOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICR1cmwgPSAkdGhpcy0+dXJsOwogICAgICAgICRjYWNoZSA9ICR0aGlzLT5jYWNoZTsKICAgICAgICAkZGVncmFkZWRNb2RlID0gJiR0aGlzLT5kZWdyYWRlZE1vZGU7CiAgICAgICAgJHJlcG8gPSAkdGhpczsKCiAgICAgICAgJGFjY2VwdCA9IGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJGlvLCAkdXJsLCAkZmlsZW5hbWUsICRjYWNoZSwgJGNhY2hlS2V5LCAkcmVwbykgewogICAgICAgICAgICAvLyBwYWNrYWdlIG5vdCBmb3VuZCBpcyBhY2NlcHRhYmxlIGZvciBhIHYyIHByb3RvY29sIHJlcG9zaXRvcnkKICAgICAgICAgICAgaWYgKCRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0MDQpIHsKICAgICAgICAgICAgICAgICRyZXBvLT5wYWNrYWdlc05vdEZvdW5kQ2FjaGVbJGZpbGVuYW1lXSA9IHRydWU7CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdwYWNrYWdlcycgPT4gYXJyYXkoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRqc29uID0gJHJlc3BvbnNlLT5nZXRCb2R5KCk7CiAgICAgICAgICAgIGlmICgkanNvbiA9PT0gJycgJiYgJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDMwNCkgewogICAgICAgICAgICAgICAgJHJlcG8tPmZyZXNoTWV0YWRhdGFVcmxzWyRmaWxlbmFtZV0gPSB0cnVlOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGF0YSA9ICRyZXNwb25zZS0+ZGVjb2RlSnNvbigpOwogICAgICAgICAgICBIdHRwRG93bmxvYWRlcjo6b3V0cHV0V2FybmluZ3MoJGlvLCAkdXJsLCAkZGF0YSk7CgogICAgICAgICAgICAkbGFzdE1vZGlmaWVkRGF0ZSA9ICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdsYXN0LW1vZGlmaWVkJyk7CiAgICAgICAgICAgICRyZXNwb25zZS0+Y29sbGVjdCgpOwogICAgICAgICAgICBpZiAoJGxhc3RNb2RpZmllZERhdGUpIHsKICAgICAgICAgICAgICAgICRkYXRhWydsYXN0LW1vZGlmaWVkJ10gPSAkbGFzdE1vZGlmaWVkRGF0ZTsKICAgICAgICAgICAgICAgICRqc29uID0gSnNvbkZpbGU6OmVuY29kZSgkZGF0YSwgSnNvbkZpbGU6OkpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBKc29uRmlsZTo6SlNPTl9VTkVTQ0FQRURfVU5JQ09ERSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkY2FjaGUtPmlzUmVhZE9ubHkoKSkgewogICAgICAgICAgICAgICAgJGNhY2hlLT53cml0ZSgkY2FjaGVLZXksICRqc29uKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVwby0+ZnJlc2hNZXRhZGF0YVVybHNbJGZpbGVuYW1lXSA9IHRydWU7CgogICAgICAgICAgICByZXR1cm4gJGRhdGE7CiAgICAgICAgfTsKCiAgICAgICAgJHJlamVjdCA9IGZ1bmN0aW9uICgkZSkgdXNlICgmJHJldHJpZXMsICRodHRwRG93bmxvYWRlciwgJGZpbGVuYW1lLCAkb3B0aW9ucywgJiRyZWplY3QsICRhY2NlcHQsICRpbywgJHVybCwgJiRkZWdyYWRlZE1vZGUsICRyZXBvKSB7CiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAkZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0MDQpIHsKICAgICAgICAgICAgICAgICRyZXBvLT5wYWNrYWdlc05vdEZvdW5kQ2FjaGVbJGZpbGVuYW1lXSA9IHRydWU7CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBzcGVjaWFsIGVycm9yIGNvZGUgcmV0dXJuZWQgd2hlbiBuZXR3b3JrIGlzIGJlaW5nIGFydGlmaWNpYWxseSBkaXNhYmxlZAogICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGUtPmdldFN0YXR1c0NvZGUoKSA9PT0gNDk5KSB7CiAgICAgICAgICAgICAgICAkcmV0cmllcyA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgtLSRyZXRyaWVzID4gMCkgewogICAgICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRodHRwRG93bmxvYWRlci0+YWRkKCRmaWxlbmFtZSwgJG9wdGlvbnMpLT50aGVuKCRhY2NlcHQsICRyZWplY3QpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRkZWdyYWRlZE1vZGUpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Jy4kdXJsLicgY291bGQgbm90IGJlIGZ1bGx5IGxvYWRlZCAoJy4kZS0+Z2V0TWVzc2FnZSgpLicpLCBwYWNrYWdlIGluZm9ybWF0aW9uIHdhcyBsb2FkZWQgZnJvbSB0aGUgbG9jYWwgY2FjaGUgYW5kIG1heSBiZSBvdXQgb2YgZGF0ZTwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZGVncmFkZWRNb2RlID0gdHJ1ZTsKCiAgICAgICAgICAgIC8vIHNwZWNpYWwgZXJyb3IgY29kZSByZXR1cm5lZCB3aGVuIG5ldHdvcmsgaXMgYmVpbmcgYXJ0aWZpY2lhbGx5IGRpc2FibGVkCiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAkZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0OTkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYWNjZXB0KG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAkdXJsKSwgNDA0LCBhcnJheSgpLCAnJykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9OwoKICAgICAgICByZXR1cm4gJGh0dHBEb3dubG9hZGVyLT5hZGQoJGZpbGVuYW1lLCAkb3B0aW9ucyktPnRoZW4oJGFjY2VwdCwgJHJlamVjdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGluaXRpYWxpemVzIHRoZSBwYWNrYWdlcyBrZXkgb2YgYSBwYXJ0aWFsIHBhY2thZ2VzLmpzb24gdGhhdCBjb250YWluIHNvbWUgcGFja2FnZXMgaW5saW5lZCArIGEgcHJvdmlkZXJzLWxhenktdXJsCiAgICAgKgogICAgICogVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgb25jZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRpYWxpemVQYXJ0aWFsUGFja2FnZXMoKQogICAgewogICAgICAgICRyb290RGF0YSA9ICR0aGlzLT5sb2FkUm9vdFNlcnZlckZpbGUoKTsKCiAgICAgICAgJHRoaXMtPnBhcnRpYWxQYWNrYWdlc0J5TmFtZSA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJvb3REYXRhWydwYWNrYWdlcyddIGFzICRwYWNrYWdlID0+ICR2ZXJzaW9ucykgewogICAgICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJ0aWFsUGFja2FnZXNCeU5hbWVbc3RydG9sb3dlcigkdmVyc2lvblsnbmFtZSddKV1bXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyB3aXBlIHJvb3REYXRhIGFzIGl0IGlzIGZ1bGx5IGNvbnN1bWVkIGF0IHRoaXMgcG9pbnQgYW5kIHRoaXMgc2F2ZXMgc29tZSBtZW1vcnkKICAgICAgICAkdGhpcy0+cm9vdERhdGEgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBwYWNrYWdlIG5hbWUgaXMgcHJlc2VudCBpbiB0aGlzIGxhenkgcHJvdmlkZXJzIHJlcG8KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sICAgdHJ1ZSBpZiB0aGUgcGFja2FnZSBuYW1lIGlzIHByZXNlbnQgaW4gYXZhaWxhYmxlUGFja2FnZXMgb3IgbWF0Y2hlZCBieSBhdmFpbGFibGVQYWNrYWdlUGF0dGVybnMKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxhenlQcm92aWRlcnNSZXBvQ29udGFpbnMoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzQXZhaWxhYmxlUGFja2FnZUxpc3QpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignbGF6eVByb3ZpZGVyc1JlcG9Db250YWlucyBzaG91bGQgbm90IGJlIGNhbGxlZCB1bmxlc3MgaGFzQXZhaWxhYmxlUGFja2FnZUxpc3QgaXMgdHJ1ZScpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX2FycmF5KCR0aGlzLT5hdmFpbGFibGVQYWNrYWdlcykgJiYgaXNzZXQoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfYXJyYXkoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VQYXR0ZXJucykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmF2YWlsYWJsZVBhY2thZ2VQYXR0ZXJucyBhcyAkcHJvdmlkZXJSZWdleCkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHByb3ZpZGVyUmVnZXgsICRuYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXFZhbGlkYXRpbmdBcnJheUxvYWRlcjsKCi8qKgogKiBQYWNrYWdlIHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBhY2thZ2VSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5CnsKICAgIHByaXZhdGUgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIGZpbGVzeXN0ZW0gcmVwb3NpdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGNvbmZpZyBwYWNrYWdlIGRlZmluaXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRjb25maWcpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgpOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnWydwYWNrYWdlJ107CgogICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIGFycmF5IG9mIHBhY2thZ2UgZGVmaW5pdGlvbnMKICAgICAgICBpZiAoIWlzX251bWVyaWMoa2V5KCR0aGlzLT5jb25maWcpKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnID0gYXJyYXkoJHRoaXMtPmNvbmZpZyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcmVwb3NpdG9yeSAocmVhZHMgZmlsZSwgb3IgcmVtb3RlIGFkZHJlc3MpLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCk7CgogICAgICAgICRsb2FkZXIgPSBuZXcgVmFsaWRhdGluZ0FycmF5TG9hZGVyKG5ldyBBcnJheUxvYWRlcihudWxsLCB0cnVlKSwgZmFsc2UpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWcgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJGxvYWRlci0+bG9hZCgkcGFja2FnZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUmVwb3NpdG9yeUV4Y2VwdGlvbignQSByZXBvc2l0b3J5IG9mIHR5cGUgInBhY2thZ2UiIGNvbnRhaW5zIGFuIGludmFsaWQgcGFja2FnZSBkZWZpbml0aW9uOiAnLiRlLT5nZXRNZXNzYWdlKCkuIlxuXG5JbnZhbGlkIHBhY2thZ2UgZGVmaW5pdGlvbjpcbiIuanNvbl9lbmNvZGUoJHBhY2thZ2UpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb05hbWUoKQogICAgewogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2UoJ3teYXJyYXkgfScsICdwYWNrYWdlICcsIHBhcmVudDo6Z2V0UmVwb05hbWUoKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUmVwb3NpdG9yeTsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwoKLyoqCiAqIFdyaXRhYmxlIGFycmF5IHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFdyaXRhYmxlQXJyYXlSZXBvc2l0b3J5IGV4dGVuZHMgQXJyYXlSZXBvc2l0b3J5IGltcGxlbWVudHMgV3JpdGFibGVSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGRldlBhY2thZ2VOYW1lcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZQYWNrYWdlTmFtZXMoYXJyYXkgJGRldlBhY2thZ2VOYW1lcykKICAgIHsKICAgICAgICAkdGhpcy0+ZGV2UGFja2FnZU5hbWVzID0gJGRldlBhY2thZ2VOYW1lczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlBhY2thZ2VOYW1lcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZQYWNrYWdlTmFtZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZGV2TW9kZSwgSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlcikKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbG9hZCgpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDYW5vbmljYWxQYWNrYWdlcygpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmdldFBhY2thZ2VzKCk7CgogICAgICAgIC8vIGdldCBhdCBtb3N0IG9uZSBwYWNrYWdlIG9mIGVhY2ggbmFtZSwgcHJlZmVycmluZyBub24tYWxpYXNlZCBvbmVzCiAgICAgICAgJHBhY2thZ2VzQnlOYW1lID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkcGFja2FnZXNCeU5hbWVbJHBhY2thZ2UtPmdldE5hbWUoKV0pIHx8ICRwYWNrYWdlc0J5TmFtZVskcGFja2FnZS0+Z2V0TmFtZSgpXSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzQnlOYW1lWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjYW5vbmljYWxQYWNrYWdlcyA9IGFycmF5KCk7CgogICAgICAgIC8vIHVuZm9sZCBhbGlhc2VkIHBhY2thZ2VzCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzQnlOYW1lIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIHdoaWxlICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2Fub25pY2FsUGFja2FnZXNbXSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjYW5vbmljYWxQYWNrYWdlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxSZXBvc2l0b3J5OwoKLyoqCiAqIEluc3RhbGxlZCBmaWxlc3lzdGVtIHJlcG9zaXRvcnkuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEluc3RhbGxlZEZpbGVzeXN0ZW1SZXBvc2l0b3J5IGV4dGVuZHMgRmlsZXN5c3RlbVJlcG9zaXRvcnkgaW1wbGVtZW50cyBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdpbnN0YWxsZWQgJy5wYXJlbnQ6OmdldFJlcG9OYW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ZyZXNoKCkKICAgIHsKICAgICAgICByZXR1cm4gISR0aGlzLT5maWxlLT5leGlzdHMoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb25zb2xlOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwoKZmluYWwgY2xhc3MgR2l0aHViQWN0aW9uRXJyb3IKewogICAgLyoqCiAgICAgKiBAdmFyIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW87CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGZpbGUKICAgICAqIEBwYXJhbSBudWxsfGludCAgICAkbGluZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW1pdCgkbWVzc2FnZSwgJGZpbGUgPSBudWxsLCAkbGluZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGdldGVudignR0lUSFVCX0FDVElPTlMnKSAmJiAhZ2V0ZW52KCdDT01QT1NFUl9URVNUU19BUkVfUlVOTklORycpKSB7CiAgICAgICAgICAgIC8vIG5ld2xpbmVzIG5lZWQgdG8gYmUgZW5jb2RlZAogICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvc3RhcnRlci13b3JrZmxvd3MvaXNzdWVzLzY4I2lzc3VlY29tbWVudC01ODE0Nzk0NDgKICAgICAgICAgICAgJG1lc3NhZ2UgPSBzdHJfcmVwbGFjZSgiXG4iLCAnJTBBJywgJG1lc3NhZ2UpOwoKICAgICAgICAgICAgaWYgKCRmaWxlICYmICRsaW5lKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKCI6OmVycm9yIGZpbGU9Ii4gJGZpbGUgLiIsbGluZT0iLiAkbGluZSAuIjo6Ii4gJG1lc3NhZ2UpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGZpbGUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGUoIjo6ZXJyb3IgZmlsZT0iLiAkZmlsZSAuIjo6Ii4gJG1lc3NhZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgiOjplcnJvciA6OiIuICRtZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb25zb2xlOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBIdG1sT3V0cHV0Rm9ybWF0dGVyIGV4dGVuZHMgT3V0cHV0Rm9ybWF0dGVyCnsKICAgIHByaXZhdGUgc3RhdGljICRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzID0gYXJyYXkoCiAgICAgICAgMzAgPT4gJ2JsYWNrJywKICAgICAgICAzMSA9PiAncmVkJywKICAgICAgICAzMiA9PiAnZ3JlZW4nLAogICAgICAgIDMzID0+ICd5ZWxsb3cnLAogICAgICAgIDM0ID0+ICdibHVlJywKICAgICAgICAzNSA9PiAnbWFnZW50YScsCiAgICAgICAgMzYgPT4gJ2N5YW4nLAogICAgICAgIDM3ID0+ICd3aGl0ZScsCiAgICApOwogICAgcHJpdmF0ZSBzdGF0aWMgJGF2YWlsYWJsZUJhY2tncm91bmRDb2xvcnMgPSBhcnJheSgKICAgICAgICA0MCA9PiAnYmxhY2snLAogICAgICAgIDQxID0+ICdyZWQnLAogICAgICAgIDQyID0+ICdncmVlbicsCiAgICAgICAgNDMgPT4gJ3llbGxvdycsCiAgICAgICAgNDQgPT4gJ2JsdWUnLAogICAgICAgIDQ1ID0+ICdtYWdlbnRhJywKICAgICAgICA0NiA9PiAnY3lhbicsCiAgICAgICAgNDcgPT4gJ3doaXRlJywKICAgICk7CiAgICBwcml2YXRlIHN0YXRpYyAkYXZhaWxhYmxlT3B0aW9ucyA9IGFycmF5KAogICAgICAgIDEgPT4gJ2JvbGQnLAogICAgICAgIDQgPT4gJ3VuZGVyc2NvcmUnLAogICAgICAgIC8vNSA9PiAnYmxpbmsnLAogICAgICAgIC8vNyA9PiAncmV2ZXJzZScsCiAgICAgICAgLy84ID0+ICdjb25jZWFsJwogICAgKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkc3R5bGVzIEFycmF5IG9mICJuYW1lID0+IEZvcm1hdHRlclN0eWxlIiBpbnN0YW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRzdHlsZXMgPSBhcnJheSgpKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QodHJ1ZSwgJHN0eWxlcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZvcm1hdCgkbWVzc2FnZSkKICAgIHsKICAgICAgICAkZm9ybWF0dGVkID0gcGFyZW50Ojpmb3JtYXQoJG1lc3NhZ2UpOwoKICAgICAgICAkY2xlYXJFc2NhcGVDb2RlcyA9ICcoPzozOXw0OXwwfDIyfDI0fDI1fDI3fDI4KSc7CgogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2VfY2FsbGJhY2soIntcMDMzXFsoWzAtOTtdKyltKC4qPylcMDMzXFsoPzoiLiRjbGVhckVzY2FwZUNvZGVzLiI7KSo/Ii4kY2xlYXJFc2NhcGVDb2Rlcy4ibX1zIiwgYXJyYXkoJHRoaXMsICdmb3JtYXRIdG1sJyksICRmb3JtYXR0ZWQpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZm9ybWF0SHRtbCgkbWF0Y2hlcykKICAgIHsKICAgICAgICAkb3V0ID0gJzxzcGFuIHN0eWxlPSInOwogICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJzsnLCAkbWF0Y2hlc1sxXSkgYXMgJGNvZGUpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzWyRjb2RlXSkpIHsKICAgICAgICAgICAgICAgICRvdXQgLj0gJ2NvbG9yOicuc2VsZjo6JGF2YWlsYWJsZUZvcmVncm91bmRDb2xvcnNbJGNvZGVdLic7JzsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KHNlbGY6OiRhdmFpbGFibGVCYWNrZ3JvdW5kQ29sb3JzWyRjb2RlXSkpIHsKICAgICAgICAgICAgICAgICRvdXQgLj0gJ2JhY2tncm91bmQtY29sb3I6Jy5zZWxmOjokYXZhaWxhYmxlQmFja2dyb3VuZENvbG9yc1skY29kZV0uJzsnOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoc2VsZjo6JGF2YWlsYWJsZU9wdGlvbnNbJGNvZGVdKSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChzZWxmOjokYXZhaWxhYmxlT3B0aW9uc1skY29kZV0pIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICdib2xkJzoKICAgICAgICAgICAgICAgICAgICAgICAgJG91dCAuPSAnZm9udC13ZWlnaHQ6Ym9sZDsnOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAndW5kZXJzY29yZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXQgLj0gJ3RleHQtZGVjb3JhdGlvbjp1bmRlcmxpbmU7JzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3V0LiciPicuJG1hdGNoZXNbMl0uJzwvc3Bhbj4nOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbnNvbGU7Cgp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcU2lsZW5jZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uIGFzIEJhc2VBcHBsaWNhdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlclNldDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTZWxkXEpzb25MaW50XFBhcnNpbmdFeGNlcHRpb247CnVzZSBDb21wb3NlclxDb21tYW5kOwp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xDb25zb2xlSU87CnVzZSBDb21wb3NlclxKc29uXEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcVXRpbFxFcnJvckhhbmRsZXI7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXFNjcmlwdEV4ZWN1dGlvbkV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXEV4Y2VwdGlvblxOb1NzbEV4Y2VwdGlvbjsKCi8qKgogKiBUaGUgY29uc29sZSBhcHBsaWNhdGlvbiB0aGF0IGhhbmRsZXMgdGhlIGNvbW1hbmRzCiAqCiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wbGFicy5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmNsYXNzIEFwcGxpY2F0aW9uIGV4dGVuZHMgQmFzZUFwcGxpY2F0aW9uCnsKICAgIC8qKgogICAgICogQHZhciBDb21wb3NlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbXBvc2VyOwoKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGlvOwoKICAgIHByaXZhdGUgc3RhdGljICRsb2dvID0gJyAgIF9fX19fXwogIC8gX19fXy9fX18gIF9fX18gX19fICBfX19fICBfX19fICBfX19fX19fXyAgX19fX18KIC8gLyAgIC8gX18gXC8gX18gYF9fIFwvIF9fIFwvIF9fIFwvIF9fXy8gXyBcLyBfX18vCi8gL19fXy8gL18vIC8gLyAvIC8gLyAvIC9fLyAvIC9fLyAoX18gICkgIF9fLyAvClxfX19fL1xfX19fL18vIC9fLyAvXy8gLl9fXy9cX19fXy9fX19fL1xfX18vXy8KICAgICAgICAgICAgICAgICAgICAvXy8KJzsKCiAgICBwcml2YXRlICRoYXNQbHVnaW5Db21tYW5kcyA9IGZhbHNlOwogICAgcHJpdmF0ZSAkZGlzYWJsZVBsdWdpbnNCeURlZmF1bHQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nIFN0b3JlIHRoZSBpbml0aWFsIHdvcmtpbmcgZGlyZWN0b3J5IGF0IHN0YXJ0dXAgdGltZQogICAgICovCiAgICBwcml2YXRlICRpbml0aWFsV29ya2luZ0RpcmVjdG9yeTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgIHN0YXRpYyAkc2h1dGRvd25SZWdpc3RlcmVkID0gZmFsc2U7CgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2luaV9zZXQnKSAmJiBleHRlbnNpb25fbG9hZGVkKCd4ZGVidWcnKSkgewogICAgICAgICAgICBpbmlfc2V0KCd4ZGVidWcuc2hvd19leGNlcHRpb25fdHJhY2UnLCBmYWxzZSk7CiAgICAgICAgICAgIGluaV9zZXQoJ3hkZWJ1Zy5zY3JlYW0nLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdkYXRlX2RlZmF1bHRfdGltZXpvbmVfc2V0JykgJiYgZnVuY3Rpb25fZXhpc3RzKCdkYXRlX2RlZmF1bHRfdGltZXpvbmVfZ2V0JykpIHsKICAgICAgICAgICAgZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldChTaWxlbmNlcjo6Y2FsbCgnZGF0ZV9kZWZhdWx0X3RpbWV6b25lX2dldCcpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHNodXRkb3duUmVnaXN0ZXJlZCkgewogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwY250bF9hc3luY19zaWduYWxzJykgJiYgZnVuY3Rpb25fZXhpc3RzKCdwY250bF9zaWduYWwnKSkgewogICAgICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIGZ1bmN0aW9uICgkc2lnKSB7CiAgICAgICAgICAgICAgICAgICAgZXhpdCgxMzApOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzaHV0ZG93blJlZ2lzdGVyZWQgPSB0cnVlOwoKICAgICAgICAgICAgcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgJGxhc3RFcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgogICAgICAgICAgICAgICAgaWYgKCRsYXN0RXJyb3IgJiYgJGxhc3RFcnJvclsnbWVzc2FnZSddICYmCiAgICAgICAgICAgICAgICAgICAoc3RycG9zKCRsYXN0RXJyb3JbJ21lc3NhZ2UnXSwgJ0FsbG93ZWQgbWVtb3J5JykgIT09IGZhbHNlIC8qWmVuZCBQSFAgb3V0IG9mIG1lbW9yeSBlcnJvciovIHx8CiAgICAgICAgICAgICAgICAgICAgc3RycG9zKCRsYXN0RXJyb3JbJ21lc3NhZ2UnXSwgJ2V4Y2VlZGVkIG1lbW9yeScpICE9PSBmYWxzZSAvKkhIVk0gb3V0IG9mIG1lbW9yeSBlcnJvcnMqLykpIHsKICAgICAgICAgICAgICAgICAgICBlY2hvICJcbiIuICdDaGVjayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvdHJvdWJsZXNob290aW5nLm1kI21lbW9yeS1saW1pdC1lcnJvcnMgZm9yIG1vcmUgaW5mbyBvbiBob3cgdG8gaGFuZGxlIG91dCBvZiBtZW1vcnkgZXJyb3JzLic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvID0gbmV3IE51bGxJTygpOwoKICAgICAgICAkdGhpcy0+aW5pdGlhbFdvcmtpbmdEaXJlY3RvcnkgPSBnZXRjd2QoKTsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgnQ29tcG9zZXInLCBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJ1bihJbnB1dEludGVyZmFjZSAkaW5wdXQgPSBudWxsLCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvdXRwdXQpIHsKICAgICAgICAgICAgJG91dHB1dCA9IEZhY3Rvcnk6OmNyZWF0ZU91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDo6cnVuKCRpbnB1dCwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb1J1bihJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICR0aGlzLT5kaXNhYmxlUGx1Z2luc0J5RGVmYXVsdCA9ICRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctLW5vLXBsdWdpbnMnKTsKCiAgICAgICAgaWYgKGdldGVudignQ09NUE9TRVJfTk9fSU5URVJBQ1RJT04nKSB8fCAhUGxhdGZvcm06OmlzVHR5KGRlZmluZWQoJ1NURElOJykgPyBTVERJTiA6IGZvcGVuKCdwaHA6Ly9zdGRpbicsICdyJykpKSB7CiAgICAgICAgICAgICRpbnB1dC0+c2V0SW50ZXJhY3RpdmUoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmlvID0gbmV3IENvbnNvbGVJTygkaW5wdXQsICRvdXRwdXQsIG5ldyBIZWxwZXJTZXQoYXJyYXkoCiAgICAgICAgICAgIG5ldyBRdWVzdGlvbkhlbHBlcigpLAogICAgICAgICkpKTsKICAgICAgICBFcnJvckhhbmRsZXI6OnJlZ2lzdGVyKCRpbyk7CgogICAgICAgIGlmICgkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbignLS1uby1jYWNoZScpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignRGlzYWJsaW5nIGNhY2hlIHVzYWdlJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgJF9TRVJWRVJbJ0NPTVBPU0VSX0NBQ0hFX0RJUiddID0gUGxhdGZvcm06OmlzV2luZG93cygpID8gJ251bCcgOiAnL2Rldi9udWxsJzsKICAgICAgICAgICAgcHV0ZW52KCdDT01QT1NFUl9DQUNIRV9ESVI9Jy4kX1NFUlZFUlsnQ09NUE9TRVJfQ0FDSEVfRElSJ10pOwogICAgICAgIH0KCiAgICAgICAgLy8gc3dpdGNoIHdvcmtpbmcgZGlyCiAgICAgICAgaWYgKCRuZXdXb3JrRGlyID0gJHRoaXMtPmdldE5ld1dvcmtpbmdEaXIoJGlucHV0KSkgewogICAgICAgICAgICAkb2xkV29ya2luZ0RpciA9IGdldGN3ZCgpOwogICAgICAgICAgICBjaGRpcigkbmV3V29ya0Rpcik7CiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsV29ya2luZ0RpcmVjdG9yeSA9ICRuZXdXb3JrRGlyOwogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ0NoYW5nZWQgQ1dEIHRvICcgLiBnZXRjd2QoKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICB9CgogICAgICAgIC8vIGRldGVybWluZSBjb21tYW5kIG5hbWUgdG8gYmUgZXhlY3V0ZWQgd2l0aG91dCBpbmNsdWRpbmcgcGx1Z2luIGNvbW1hbmRzCiAgICAgICAgJGNvbW1hbmROYW1lID0gJyc7CiAgICAgICAgaWYgKCRuYW1lID0gJHRoaXMtPmdldENvbW1hbmROYW1lKCRpbnB1dCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRjb21tYW5kTmFtZSA9ICR0aGlzLT5maW5kKCRuYW1lKS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9IGNhdGNoIChDb21tYW5kTm90Rm91bmRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIHdlJ2xsIGNoZWNrIGNvbW1hbmQgdmFsaWRpdHkgYWdhaW4gbGF0ZXIgYWZ0ZXIgcGx1Z2lucyBhcmUgbG9hZGVkCiAgICAgICAgICAgICAgICAkY29tbWFuZE5hbWUgPSBmYWxzZTsKICAgICAgICAgICAgfSBjYXRjaCAoXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBwcm9tcHQgdXNlciBmb3IgZGlyIGNoYW5nZSBpZiBubyBjb21wb3Nlci5qc29uIGlzIHByZXNlbnQgaW4gY3VycmVudCBkaXIKICAgICAgICBpZiAoJGlvLT5pc0ludGVyYWN0aXZlKCkgJiYgISRuZXdXb3JrRGlyICYmICFpbl9hcnJheSgkY29tbWFuZE5hbWUsIGFycmF5KCcnLCAnbGlzdCcsICdpbml0JywgJ2Fib3V0JywgJ2hlbHAnLCAnZGlhZ25vc2UnLCAnc2VsZi11cGRhdGUnLCAnZ2xvYmFsJywgJ2NyZWF0ZS1wcm9qZWN0JywgJ291dGRhdGVkJyksIHRydWUpICYmICFmaWxlX2V4aXN0cyhGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKSkpIHsKICAgICAgICAgICAgJGRpciA9IGRpcm5hbWUoZ2V0Y3dkKCkpOwogICAgICAgICAgICAkaG9tZSA9IHJlYWxwYXRoKGdldGVudignSE9NRScpID86IGdldGVudignVVNFUlBST0ZJTEUnKSA/OiAnLycpOwoKICAgICAgICAgICAgLy8gYWJvcnQgd2hlbiB3ZSByZWFjaCB0aGUgaG9tZSBkaXIgb3IgdG9wIG9mIHRoZSBmaWxlc3lzdGVtCiAgICAgICAgICAgIHdoaWxlIChkaXJuYW1lKCRkaXIpICE9PSAkZGlyICYmICRkaXIgIT09ICRob21lKSB7CiAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGRpci4nLycuRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpby0+YXNrQ29uZmlybWF0aW9uKCc8aW5mbz5ObyBjb21wb3Nlci5qc29uIGluIGN1cnJlbnQgZGlyZWN0b3J5LCBkbyB5b3Ugd2FudCB0byB1c2UgdGhlIG9uZSBhdCAnLiRkaXIuJz88L2luZm8+IFs8Y29tbWVudD5ZLG48L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG9sZFdvcmtpbmdEaXIgPSBnZXRjd2QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hkaXIoJGRpcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGRpciA9IGRpcm5hbWUoJGRpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmRpc2FibGVQbHVnaW5zQnlEZWZhdWx0ICYmICEkdGhpcy0+aGFzUGx1Z2luQ29tbWFuZHMgJiYgJ2dsb2JhbCcgIT09ICRjb21tYW5kTmFtZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFBsdWdpbkNvbW1hbmRzKCkgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmhhcygkY29tbWFuZC0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlBsdWdpbiBjb21tYW5kICcuJGNvbW1hbmQtPmdldE5hbWUoKS4nICgnLmdldF9jbGFzcygkY29tbWFuZCkuJykgd291bGQgb3ZlcnJpZGUgYSBDb21wb3NlciBjb21tYW5kIGFuZCBoYXMgYmVlbiBza2lwcGVkPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGQoJGNvbW1hbmQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoTm9Tc2xFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIHN1cHByZXNzIHRoZXNlIGFzIHRoZXkgYXJlIG5vdCByZWxldmFudCBhdCB0aGlzIHBvaW50CiAgICAgICAgICAgIH0gY2F0Y2ggKFBhcnNpbmdFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRkZXRhaWxzID0gJGUtPmdldERldGFpbHMoKTsKCiAgICAgICAgICAgICAgICAkZmlsZSA9IHJlYWxwYXRoKEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpKTsKCiAgICAgICAgICAgICAgICAkbGluZSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoJGRldGFpbHMgJiYgaXNzZXQoJGRldGFpbHNbJ2xpbmUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9ICRkZXRhaWxzWydsaW5lJ107CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAgICAgJGdoZS0+ZW1pdCgkZS0+Z2V0TWVzc2FnZSgpLCAkZmlsZSwgJGxpbmUpOwoKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aGFzUGx1Z2luQ29tbWFuZHMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gZGV0ZXJtaW5lIGNvbW1hbmQgbmFtZSB0byBiZSBleGVjdXRlZCBpbmNsIHBsdWdpbiBjb21tYW5kcywgYW5kIGNoZWNrIGlmIGl0J3MgYSBwcm94eSBjb21tYW5kCiAgICAgICAgJGlzUHJveHlDb21tYW5kID0gZmFsc2U7CiAgICAgICAgaWYgKCRuYW1lID0gJHRoaXMtPmdldENvbW1hbmROYW1lKCRpbnB1dCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRjb21tYW5kID0gJHRoaXMtPmZpbmQoJG5hbWUpOwogICAgICAgICAgICAgICAgJGNvbW1hbmROYW1lID0gJGNvbW1hbmQtPmdldE5hbWUoKTsKICAgICAgICAgICAgICAgICRpc1Byb3h5Q29tbWFuZCA9ICgkY29tbWFuZCBpbnN0YW5jZW9mIENvbW1hbmRcQmFzZUNvbW1hbmQgJiYgJGNvbW1hbmQtPmlzUHJveHlDb21tYW5kKCkpOwogICAgICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGlzUHJveHlDb21tYW5kKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ1J1bm5pbmcgJXMgKCVzKSB3aXRoICVzIG9uICVzJywKICAgICAgICAgICAgICAgIENvbXBvc2VyOjpnZXRWZXJzaW9uKCksCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6UkVMRUFTRV9EQVRFLAogICAgICAgICAgICAgICAgZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykgPyAnSEhWTSAnLkhIVk1fVkVSU0lPTiA6ICdQSFAgJy5QSFBfVkVSU0lPTiwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uX2V4aXN0cygncGhwX3VuYW1lJykgPyBwaHBfdW5hbWUoJ3MnKSAuICcgLyAnIC4gcGhwX3VuYW1lKCdyJykgOiAnVW5rbm93biBPUycKICAgICAgICAgICAgKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKCiAgICAgICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDUwMzAyKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNvbXBvc2VyIG9ubHkgb2ZmaWNpYWxseSBzdXBwb3J0cyBQSFAgNS4zLjIgYW5kIGFib3ZlLCB5b3Ugd2lsbCBtb3N0IGxpa2VseSBlbmNvdW50ZXIgcHJvYmxlbXMgd2l0aCB5b3VyIFBIUCAnLlBIUF9WRVJTSU9OLicsIHVwZ3JhZGluZyBpcyBzdHJvbmdseSByZWNvbW1lbmRlZC48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCd4ZGVidWcnKSAmJiAhZ2V0ZW52KCdDT01QT1NFUl9ESVNBQkxFX1hERUJVR19XQVJOJykpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Q29tcG9zZXIgaXMgb3BlcmF0aW5nIHNsb3dlciB0aGFuIG5vcm1hbCBiZWNhdXNlIHlvdSBoYXZlIFhkZWJ1ZyBlbmFibGVkLiBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcveGRlYnVnPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZGVmaW5lZCgnQ09NUE9TRVJfREVWX1dBUk5JTkdfVElNRScpICYmICRjb21tYW5kTmFtZSAhPT0gJ3NlbGYtdXBkYXRlJyAmJiAkY29tbWFuZE5hbWUgIT09ICdzZWxmdXBkYXRlJyAmJiB0aW1lKCkgPiBDT01QT1NFUl9ERVZfV0FSTklOR19USU1FKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZignPHdhcm5pbmc+V2FybmluZzogVGhpcyBkZXZlbG9wbWVudCBidWlsZCBvZiBDb21wb3NlciBpcyBvdmVyIDYwIGRheXMgb2xkLiBJdCBpcyByZWNvbW1lbmRlZCB0byB1cGRhdGUgaXQgYnkgcnVubmluZyAiJXMgc2VsZi11cGRhdGUiIHRvIGdldCB0aGUgbGF0ZXN0IHZlcnNpb24uPC93YXJuaW5nPicsICRfU0VSVkVSWydQSFBfU0VMRiddKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkKICAgICAgICAgICAgICAgICYmIGZ1bmN0aW9uX2V4aXN0cygnZXhlYycpCiAgICAgICAgICAgICAgICAmJiAhZ2V0ZW52KCdDT01QT1NFUl9BTExPV19TVVBFUlVTRVInKQogICAgICAgICAgICAgICAgJiYgKGluaV9nZXQoJ29wZW5fYmFzZWRpcicpIHx8ICFmaWxlX2V4aXN0cygnLy5kb2NrZXJlbnYnKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXR1aWQnKSAmJiBwb3NpeF9nZXR1aWQoKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY29tbWFuZE5hbWUgIT09ICdzZWxmLXVwZGF0ZScgJiYgJGNvbW1hbmROYW1lICE9PSAnc2VsZnVwZGF0ZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5EbyBub3QgcnVuIENvbXBvc2VyIGFzIHJvb3Qvc3VwZXIgdXNlciEgU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL3Jvb3QgZm9yIGRldGFpbHM8L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJGlvLT5hc2tDb25maXJtYXRpb24oJzxpbmZvPkNvbnRpbnVlIGFzIHJvb3Qvc3VwZXIgdXNlcjwvaW5mbz4gWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkdWlkID0gKGludCkgZ2V0ZW52KCdTVURPX1VJRCcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNpbGVudGx5IGNsb2JiZXIgYW55IHN1ZG8gY3JlZGVudGlhbHMgb24gdGhlIGludm9raW5nIHVzZXIgdG8gYXZvaWQgcHJpdmlsZWdlIGVzY2FsYXRpb25zIGxhdGVyIG9uCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZi4gaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy81MTE5CiAgICAgICAgICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdleGVjJywgInN1ZG8gLXUgXFwjeyR1aWR9IHN1ZG8gLUsgPiAvZGV2L251bGwgMj4mMSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFNpbGVudGx5IGNsb2JiZXIgYW55IHJlbWFpbmluZyBzdWRvIGxlYXNlcyBvbiB0aGUgY3VycmVudCB1c2VyIGFzIHdlbGwgdG8gYXZvaWQgcHJpdmlsZWdlIGVzY2FsYXRpb25zCiAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnZXhlYycsICdzdWRvIC1LID4gL2Rldi9udWxsIDI+JjEnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgc3lzdGVtIHRlbXAgZm9sZGVyIGZvciB1c2FiaWxpdHkgYXMgaXQgY2FuIGNhdXNlIHdlaXJkIHJ1bnRpbWUgaXNzdWVzIG90aGVyd2lzZQogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbChmdW5jdGlvbiAoKSB1c2UgKCRpbykgewogICAgICAgICAgICAgICAgJHRlbXBmaWxlID0gc3lzX2dldF90ZW1wX2RpcigpIC4gJy90ZW1wLScgLiBtZDUobWljcm90aW1lKCkpOwogICAgICAgICAgICAgICAgaWYgKCEoZmlsZV9wdXRfY29udGVudHMoJHRlbXBmaWxlLCBfX0ZJTEVfXykgJiYgKGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wZmlsZSkgPT0gX19GSUxFX18pICYmIHVubGluaygkdGVtcGZpbGUpICYmICFmaWxlX2V4aXN0cygkdGVtcGZpbGUpKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+UEhQIHRlbXAgZGlyZWN0b3J5ICglcykgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IHdyaXRhYmxlIHRvIENvbXBvc2VyLiBTZXQgc3lzX3RlbXBfZGlyIGluIHlvdXIgcGhwLmluaTwvZXJyb3I+Jywgc3lzX2dldF90ZW1wX2RpcigpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgLy8gYWRkIG5vbi1zdGFuZGFyZCBzY3JpcHRzIGFzIG93biBjb21tYW5kcwogICAgICAgICAgICAkZmlsZSA9IEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpOwogICAgICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkgJiYgaXNfcmVhZGFibGUoJGZpbGUpICYmIGlzX2FycmF5KCRjb21wb3NlciA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKSwgdHJ1ZSkpKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyWydzY3JpcHRzJ10pICYmIGlzX2FycmF5KCRjb21wb3Nlclsnc2NyaXB0cyddKSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb21wb3Nlclsnc2NyaXB0cyddIGFzICRzY3JpcHQgPT4gJGR1bW15KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZGVmaW5lZCgnQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czo6Jy5zdHJfcmVwbGFjZSgnLScsICdfJywgc3RydG91cHBlcigkc2NyaXB0KSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmhhcygkc2NyaXB0KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QSBzY3JpcHQgbmFtZWQgJy4kc2NyaXB0Licgd291bGQgb3ZlcnJpZGUgYSBDb21wb3NlciBjb21tYW5kIGFuZCBoYXMgYmVlbiBza2lwcGVkPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSBudWxsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyWydzY3JpcHRzLWRlc2NyaXB0aW9ucyddWyRzY3JpcHRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSAkY29tcG9zZXJbJ3NjcmlwdHMtZGVzY3JpcHRpb25zJ11bJHNjcmlwdF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkKG5ldyBDb21tYW5kXFNjcmlwdEFsaWFzQ29tbWFuZCgkc2NyaXB0LCAkZGVzY3JpcHRpb24pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctLXByb2ZpbGUnKSkgewogICAgICAgICAgICAgICAgJHN0YXJ0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+ZW5hYmxlRGVidWdnaW5nKCRzdGFydFRpbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzdWx0ID0gcGFyZW50Ojpkb1J1bigkaW5wdXQsICRvdXRwdXQpOwoKICAgICAgICAgICAgLy8gY2hkaXIgYmFjayB0byAkb2xkV29ya2luZ0RpciBpZiBzZXQKICAgICAgICAgICAgaWYgKGlzc2V0KCRvbGRXb3JraW5nRGlyKSkgewogICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NoZGlyJywgJG9sZFdvcmtpbmdEaXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJHN0YXJ0VGltZSkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+TWVtb3J5IHVzYWdlOiAnLnJvdW5kKG1lbW9yeV9nZXRfdXNhZ2UoKSAvIDEwMjQgLyAxMDI0LCAyKS4nTWlCIChwZWFrOiAnLnJvdW5kKG1lbW9yeV9nZXRfcGVha191c2FnZSgpIC8gMTAyNCAvIDEwMjQsIDIpLidNaUIpLCB0aW1lOiAnLnJvdW5kKG1pY3JvdGltZSh0cnVlKSAtICRzdGFydFRpbWUsIDIpLidzJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfSBjYXRjaCAoU2NyaXB0RXhlY3V0aW9uRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybiAoaW50KSAkZS0+Z2V0Q29kZSgpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGdoZSA9IG5ldyBHaXRodWJBY3Rpb25FcnJvcigkdGhpcy0+aW8pOwogICAgICAgICAgICAkZ2hlLT5lbWl0KCRlLT5nZXRNZXNzYWdlKCkpOwoKICAgICAgICAgICAgJHRoaXMtPmhpbnRDb21tb25FcnJvcnMoJGUpOwoKICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElucHV0SW50ZXJmYWNlICAgICRpbnB1dAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXROZXdXb3JraW5nRGlyKElucHV0SW50ZXJmYWNlICRpbnB1dCkKICAgIHsKICAgICAgICAkd29ya2luZ0RpciA9ICRpbnB1dC0+Z2V0UGFyYW1ldGVyT3B0aW9uKGFycmF5KCctLXdvcmtpbmctZGlyJywgJy1kJykpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJHdvcmtpbmdEaXIgJiYgIWlzX2Rpcigkd29ya2luZ0RpcikpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdJbnZhbGlkIHdvcmtpbmcgZGlyZWN0b3J5IHNwZWNpZmllZCwgJy4kd29ya2luZ0Rpci4nIGRvZXMgbm90IGV4aXN0LicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR3b3JraW5nRGlyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhpbnRDb21tb25FcnJvcnMoJGV4Y2VwdGlvbikKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgU2lsZW5jZXI6OnN1cHByZXNzKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CgogICAgICAgICAgICAgICAgJG1pblNwYWNlRnJlZSA9IDEwMjQgKiAxMDI0OwogICAgICAgICAgICAgICAgaWYgKCgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKSkpICE9PSBmYWxzZSAmJiAkZGYgPCAkbWluU3BhY2VGcmVlKQogICAgICAgICAgICAgICAgICAgIHx8ICgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSAkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSkpICE9PSBmYWxzZSAmJiAkZGYgPCAkbWluU3BhY2VGcmVlKQogICAgICAgICAgICAgICAgICAgIHx8ICgoJGRmID0gZGlza19mcmVlX3NwYWNlKCRkaXIgPSBzeXNfZ2V0X3RlbXBfZGlyKCkpKSAhPT0gZmFsc2UgJiYgJGRmIDwgJG1pblNwYWNlRnJlZSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlRoZSBkaXNrIGhvc3RpbmcgJy4kZGlyLicgaXMgZnVsbCwgdGhpcyBtYXkgYmUgdGhlIGNhdXNlIG9mIHRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KICAgICAgICBTaWxlbmNlcjo6cmVzdG9yZSgpOwoKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpICYmIGZhbHNlICE9PSBzdHJwb3MoJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpLCAnVGhlIHN5c3RlbSBjYW5ub3QgZmluZCB0aGUgcGF0aCBzcGVjaWZpZWQnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5UaGUgZm9sbG93aW5nIGV4Y2VwdGlvbiBtYXkgYmUgY2F1c2VkIGJ5IGEgc3RhbGUgZW50cnkgaW4geW91ciBjbWQuZXhlIEF1dG9SdW48L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjLXRoZS1zeXN0ZW0tY2Fubm90LWZpbmQtdGhlLXBhdGgtc3BlY2lmaWVkLXdpbmRvd3MtIGZvciBkZXRhaWxzPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpLCAnZm9yayBmYWlsZWQgLSBDYW5ub3QgYWxsb2NhdGUgbWVtb3J5JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+VGhlIGZvbGxvd2luZyBleGNlcHRpb24gaXMgY2F1c2VkIGJ5IGEgbGFjayBvZiBtZW1vcnkgb3Igc3dhcCwgb3Igbm90IGhhdmluZyBzd2FwIGNvbmZpZ3VyZWQ8L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjcHJvYy1vcGVuLWZvcmstZmFpbGVkLWVycm9ycyBmb3IgZGV0YWlsczwvZXJyb3I+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaGludHMgPSBIdHRwRG93bmxvYWRlcjo6Z2V0RXhjZXB0aW9uSGludHMoJGV4Y2VwdGlvbikpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGhpbnRzIGFzICRoaW50KSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJGhpbnQsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlZAogICAgICogQHBhcmFtICBib29sfG51bGwgICAgICAgICAgICAgICAkZGlzYWJsZVBsdWdpbnMKICAgICAqIEB0aHJvd3MgSnNvblZhbGlkYXRpb25FeGNlcHRpb24KICAgICAqIEByZXR1cm4gXENvbXBvc2VyXENvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wb3NlcigkcmVxdWlyZWQgPSB0cnVlLCAkZGlzYWJsZVBsdWdpbnMgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgJGRpc2FibGVQbHVnaW5zID0gJHRoaXMtPmRpc2FibGVQbHVnaW5zQnlEZWZhdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21wb3NlcikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlKCR0aGlzLT5pbywgbnVsbCwgJGRpc2FibGVQbHVnaW5zKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRyZXF1aXJlZCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJGVycm9ycyA9ICcgLSAnIC4gaW1wbG9kZShQSFBfRU9MIC4gJyAtICcsICRlLT5nZXRFcnJvcnMoKSk7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICRlLT5nZXRNZXNzYWdlKCkgLiAnOicgLiBQSFBfRU9MIC4gJGVycm9yczsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbigkbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHRoZSBjYWNoZWQgY29tcG9zZXIgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0Q29tcG9zZXIoKQogICAgewogICAgICAgICR0aGlzLT5jb21wb3NlciA9IG51bGw7CiAgICAgICAgaWYgKCR0aGlzLT5nZXRJTygpICYmIG1ldGhvZF9leGlzdHMoJHRoaXMtPmdldElPKCksICdyZXNldEF1dGhlbnRpY2F0aW9ucycpKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT5yZXNldEF1dGhlbnRpY2F0aW9ucygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElPKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlvOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWxwKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6JGxvZ28gLiBwYXJlbnQ6OmdldEhlbHAoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIGFsbCB0aGUgY29tcG9zZXIgY29tbWFuZHMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXREZWZhdWx0Q29tbWFuZHMoKQogICAgewogICAgICAgICRjb21tYW5kcyA9IGFycmF5X21lcmdlKHBhcmVudDo6Z2V0RGVmYXVsdENvbW1hbmRzKCksIGFycmF5KAogICAgICAgICAgICBuZXcgQ29tbWFuZFxBYm91dENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcQ29uZmlnQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxEZXBlbmRzQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxQcm9oaWJpdHNDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEluaXRDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEluc3RhbGxDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXENyZWF0ZVByb2plY3RDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFVwZGF0ZUNvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcU2VhcmNoQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxWYWxpZGF0ZUNvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcU2hvd0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcU3VnZ2VzdHNDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXFJlcXVpcmVDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXER1bXBBdXRvbG9hZENvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcU3RhdHVzQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxBcmNoaXZlQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxEaWFnbm9zZUNvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcUnVuU2NyaXB0Q29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxMaWNlbnNlc0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcR2xvYmFsQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxDbGVhckNhY2hlQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxSZW1vdmVDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEhvbWVDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXEV4ZWNDb21tYW5kKCksCiAgICAgICAgICAgIG5ldyBDb21tYW5kXE91dGRhdGVkQ29tbWFuZCgpLAogICAgICAgICAgICBuZXcgQ29tbWFuZFxDaGVja1BsYXRmb3JtUmVxc0NvbW1hbmQoKSwKICAgICAgICAgICAgbmV3IENvbW1hbmRcRnVuZENvbW1hbmQoKSwKICAgICAgICApKTsKCiAgICAgICAgaWYgKHN0cnBvcyhfX0ZJTEVfXywgJ3BoYXI6JykgPT09IDApIHsKICAgICAgICAgICAgJGNvbW1hbmRzW10gPSBuZXcgQ29tbWFuZFxTZWxmVXBkYXRlQ29tbWFuZCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvbmdWZXJzaW9uKCkKICAgIHsKICAgICAgICBpZiAoQ29tcG9zZXI6OkJSQU5DSF9BTElBU19WRVJTSU9OICYmIENvbXBvc2VyOjpCUkFOQ0hfQUxJQVNfVkVSU0lPTiAhPT0gJ0BwYWNrYWdlX2JyYW5jaF9hbGlhc192ZXJzaW9uJy4nQCcpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoCiAgICAgICAgICAgICAgICAnPGluZm8+JXM8L2luZm8+IHZlcnNpb24gPGNvbW1lbnQ+JXMgKCVzKTwvY29tbWVudD4gJXMnLAogICAgICAgICAgICAgICAgJHRoaXMtPmdldE5hbWUoKSwKICAgICAgICAgICAgICAgIENvbXBvc2VyOjpCUkFOQ0hfQUxJQVNfVkVSU0lPTiwKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRWZXJzaW9uKCksCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6UkVMRUFTRV9EQVRFCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcGFyZW50OjpnZXRMb25nVmVyc2lvbigpIC4gJyAnIC4gQ29tcG9zZXI6OlJFTEVBU0VfREFURTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldERlZmF1bHRJbnB1dERlZmluaXRpb24oKQogICAgewogICAgICAgICRkZWZpbml0aW9uID0gcGFyZW50OjpnZXREZWZhdWx0SW5wdXREZWZpbml0aW9uKCk7CiAgICAgICAgJGRlZmluaXRpb24tPmFkZE9wdGlvbihuZXcgSW5wdXRPcHRpb24oJy0tcHJvZmlsZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzcGxheSB0aW1pbmcgYW5kIG1lbW9yeSB1c2FnZSBpbmZvcm1hdGlvbicpKTsKICAgICAgICAkZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbignLS1uby1wbHVnaW5zJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIGRpc2FibGUgcGx1Z2lucy4nKSk7CiAgICAgICAgJGRlZmluaXRpb24tPmFkZE9wdGlvbihuZXcgSW5wdXRPcHRpb24oJy0td29ya2luZy1kaXInLCAnLWQnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdJZiBzcGVjaWZpZWQsIHVzZSB0aGUgZ2l2ZW4gZGlyZWN0b3J5IGFzIHdvcmtpbmcgZGlyZWN0b3J5LicpKTsKICAgICAgICAkZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbignLS1uby1jYWNoZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJldmVudCB1c2Ugb2YgdGhlIGNhY2hlJykpOwoKICAgICAgICByZXR1cm4gJGRlZmluaXRpb247CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQbHVnaW5Db21tYW5kcygpCiAgICB7CiAgICAgICAgJGNvbW1hbmRzID0gYXJyYXkoKTsKCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlLCBmYWxzZSk7CiAgICAgICAgaWYgKG51bGwgPT09ICRjb21wb3NlcikgewogICAgICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGVHbG9iYWwoJHRoaXMtPmlvKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkY29tcG9zZXIpIHsKICAgICAgICAgICAgJHBtID0gJGNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwbS0+Z2V0UGx1Z2luQ2FwYWJpbGl0aWVzKCdDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxDb21tYW5kUHJvdmlkZXInLCBhcnJheSgnY29tcG9zZXInID0+ICRjb21wb3NlciwgJ2lvJyA9PiAkdGhpcy0+aW8pKSBhcyAkY2FwYWJpbGl0eSkgewogICAgICAgICAgICAgICAgJG5ld0NvbW1hbmRzID0gJGNhcGFiaWxpdHktPmdldENvbW1hbmRzKCk7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRuZXdDb21tYW5kcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignUGx1Z2luIGNhcGFiaWxpdHkgJy5nZXRfY2xhc3MoJGNhcGFiaWxpdHkpLicgZmFpbGVkIHRvIHJldHVybiBhbiBhcnJheSBmcm9tIGdldENvbW1hbmRzJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmV3Q29tbWFuZHMgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISRjb21tYW5kIGluc3RhbmNlb2YgQ29tbWFuZFxCYXNlQ29tbWFuZCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignUGx1Z2luIGNhcGFiaWxpdHkgJy5nZXRfY2xhc3MoJGNhcGFiaWxpdHkpLicgcmV0dXJuZWQgYW4gaW52YWxpZCB2YWx1ZSwgd2UgZXhwZWN0ZWQgYW4gYXJyYXkgb2YgQ29tcG9zZXJcQ29tbWFuZFxCYXNlQ29tbWFuZCBvYmplY3RzJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvbW1hbmRzID0gYXJyYXlfbWVyZ2UoJGNvbW1hbmRzLCAkbmV3Q29tbWFuZHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbW1hbmRzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB3b3JraW5nIGRpcmVjdG9yeSBhdCBzdGFydHVwIHRpbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5pdGlhbFdvcmtpbmdEaXJlY3RvcnkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5pdGlhbFdvcmtpbmdEaXJlY3Rvcnk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUXVlc3Rpb247Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxRdWVzdGlvbjsKCi8qKgogKiBSZXByZXNlbnRzIGEgeWVzL25vIHF1ZXN0aW9uCiAqIEVuZm9yY2VzIHN0cmljdCByZXNwb25zZXMgcmF0aGVyIHRoYW4gbm9uLXN0YW5kYXJkIGFuc3dlcnMgY291bnRpbmcgYXMgZGVmYXVsdAogKiBCYXNlZCBvbiBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENvbmZpcm1hdGlvblF1ZXN0aW9uCiAqCiAqIEBhdXRob3IgVGhlbyBUb25nZSA8dGhlb0B0aGVvdG9uZ2UuY28udWs+CiAqLwpjbGFzcyBTdHJpY3RDb25maXJtYXRpb25RdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKICAgIHByaXZhdGUgJHRydWVBbnN3ZXJSZWdleDsKICAgIHByaXZhdGUgJGZhbHNlQW5zd2VyUmVnZXg7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci5zCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gICAgICAgICBUaGUgcXVlc3Rpb24gdG8gYXNrIHRvIHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0ICAgICAgICAgIFRoZSBkZWZhdWx0IGFuc3dlciB0byByZXR1cm4sIHRydWUgb3IgZmFsc2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRydWVBbnN3ZXJSZWdleCAgQSByZWdleCB0byBtYXRjaCB0aGUgInllcyIgYW5zd2VyCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmYWxzZUFuc3dlclJlZ2V4IEEgcmVnZXggdG8gbWF0Y2ggdGhlICJubyIgYW5zd2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcXVlc3Rpb24sICRkZWZhdWx0ID0gdHJ1ZSwgJHRydWVBbnN3ZXJSZWdleCA9ICcvXnkoPzplcyk/JC9pJywgJGZhbHNlQW5zd2VyUmVnZXggPSAnL15ubz8kL2knKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAoYm9vbCkgJGRlZmF1bHQpOwoKICAgICAgICAkdGhpcy0+dHJ1ZUFuc3dlclJlZ2V4ID0gJHRydWVBbnN3ZXJSZWdleDsKICAgICAgICAkdGhpcy0+ZmFsc2VBbnN3ZXJSZWdleCA9ICRmYWxzZUFuc3dlclJlZ2V4OwogICAgICAgICR0aGlzLT5zZXROb3JtYWxpemVyKCR0aGlzLT5nZXREZWZhdWx0Tm9ybWFsaXplcigpKTsKICAgICAgICAkdGhpcy0+c2V0VmFsaWRhdG9yKCR0aGlzLT5nZXREZWZhdWx0VmFsaWRhdG9yKCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBhbnN3ZXIgbm9ybWFsaXplci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RGVmYXVsdE5vcm1hbGl6ZXIoKQogICAgewogICAgICAgICRkZWZhdWx0ID0gJHRoaXMtPmdldERlZmF1bHQoKTsKICAgICAgICAkdHJ1ZVJlZ2V4ID0gJHRoaXMtPnRydWVBbnN3ZXJSZWdleDsKICAgICAgICAkZmFsc2VSZWdleCA9ICR0aGlzLT5mYWxzZUFuc3dlclJlZ2V4OwoKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCRhbnN3ZXIpIHVzZSAoJGRlZmF1bHQsICR0cnVlUmVnZXgsICRmYWxzZVJlZ2V4KSB7CiAgICAgICAgICAgIGlmIChpc19ib29sKCRhbnN3ZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGFuc3dlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZW1wdHkoJGFuc3dlcikgJiYgIWVtcHR5KCRkZWZhdWx0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkdHJ1ZVJlZ2V4LCAkYW5zd2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCRmYWxzZVJlZ2V4LCAkYW5zd2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBhbnN3ZXIgdmFsaWRhdG9yLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREZWZhdWx0VmFsaWRhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCRhbnN3ZXIpIHsKICAgICAgICAgICAgaWYgKCFpc19ib29sKCRhbnN3ZXIpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQbGVhc2UgYW5zd2VyIHllcywgeSwgbm8sIG9yIG4uJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkYW5zd2VyOwogICAgICAgIH07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwoKLyoqCiAqIFJlcHJlc2VudHMgYSBsaW5rIGJldHdlZW4gdHdvIHBhY2thZ2VzLCByZXByZXNlbnRlZCBieSB0aGVpciBuYW1lcwogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgTGluawp7CiAgICBjb25zdCBUWVBFX1JFUVVJUkUgPSAncmVxdWlyZXMnOwogICAgY29uc3QgVFlQRV9ERVZfUkVRVUlSRSA9ICdkZXZSZXF1aXJlcyc7CiAgICBjb25zdCBUWVBFX1BST1ZJREUgPSAncHJvdmlkZXMnOwogICAgY29uc3QgVFlQRV9DT05GTElDVCA9ICdjb25mbGljdHMnOwogICAgY29uc3QgVFlQRV9SRVBMQUNFID0gJ3JlcGxhY2VzJzsKCiAgICAvKioKICAgICAqIFdpbGwgYmUgY29udmVydGVkIGludG8gYSBjb25zdGFudCBvbmNlIHRoZSBtaW4gUEhQIHZlcnNpb24gYWxsb3dzIHRoaXMKICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkVFlQRVMgPSBhcnJheSgKICAgICAgICBzZWxmOjpUWVBFX1JFUVVJUkUsCiAgICAgICAgc2VsZjo6VFlQRV9ERVZfUkVRVUlSRSwKICAgICAgICBzZWxmOjpUWVBFX1BST1ZJREUsCiAgICAgICAgc2VsZjo6VFlQRV9DT05GTElDVCwKICAgICAgICBzZWxmOjpUWVBFX1JFUExBQ0UsCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRzb3VyY2U7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHRhcmdldDsKCiAgICAvKioKICAgICAqIEB2YXIgQ29uc3RyYWludEludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnN0cmFpbnQ7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQHBocHN0YW4tdmFyIHNlbGY6OlRZUEVfKiAkZGVzY3JpcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkICRkZXNjcmlwdGlvbjsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlDb25zdHJhaW50OwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBwYWNrYWdlIGxpbmsuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJHNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJHRhcmdldAogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgIENvbnN0cmFpbnQgYXBwbHlpbmcgdG8gdGhlIHRhcmdldCBvZiB0aGlzIGxpbmsKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiBVc2VkIHRvIGNyZWF0ZSBhIGRlc2NyaXB0aXZlIHN0cmluZyByZXByZXNlbnRhdGlvbgogICAgICogQHBocHN0YW4tcGFyYW0gc2VsZjo6VFlQRV8qICRkZXNjcmlwdGlvbgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRwcmV0dHlDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICAkc291cmNlLAogICAgICAgICR0YXJnZXQsCiAgICAgICAgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCwKICAgICAgICAkZGVzY3JpcHRpb24gPSAncmVsYXRlcyB0bycsCiAgICAgICAgJHByZXR0eUNvbnN0cmFpbnQgPSBudWxsCiAgICApIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gc3RydG9sb3dlcigkc291cmNlKTsKICAgICAgICAkdGhpcy0+dGFyZ2V0ID0gc3RydG9sb3dlcigkdGFyZ2V0KTsKICAgICAgICAkdGhpcy0+Y29uc3RyYWludCA9ICRjb25zdHJhaW50OwogICAgICAgICR0aGlzLT5kZXNjcmlwdGlvbiA9ICRkZXNjcmlwdGlvbjsKICAgICAgICAkdGhpcy0+cHJldHR5Q29uc3RyYWludCA9ICRwcmV0dHlDb25zdHJhaW50OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlc2NyaXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRhcmdldDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29uc3RyYWludEludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uc3RyYWludCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25zdHJhaW50OwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uIElmIG5vIHByZXR0eSBjb25zdHJhaW50IHdhcyBwcm92aWRlZAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eUNvbnN0cmFpbnQoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+cHJldHR5Q29uc3RyYWludCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbihzcHJpbnRmKCdMaW5rICVzIGhhcyBiZWVuIG1pc2NvbmZpZ3VyZWQgYW5kIGhhZCBubyBwcmV0dHlDb25zdHJhaW50IGdpdmVuLicsICR0aGlzKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eUNvbnN0cmFpbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2UuJyAnLiR0aGlzLT5kZXNjcmlwdGlvbi4nICcuJHRoaXMtPnRhcmdldC4nICgnLiR0aGlzLT5jb25zdHJhaW50LicpJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkc291cmNlUGFja2FnZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZyhQYWNrYWdlSW50ZXJmYWNlICRzb3VyY2VQYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkc291cmNlUGFja2FnZS0+Z2V0UHJldHR5U3RyaW5nKCkuJyAnLiR0aGlzLT5kZXNjcmlwdGlvbi4nICcuJHRoaXMtPnRhcmdldC4oJHRoaXMtPmNvbnN0cmFpbnQgPyAnICcuJHRoaXMtPmNvbnN0cmFpbnQtPmdldFByZXR0eVN0cmluZygpIDogJycpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxMb2NrQXJyYXlSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXEFycmF5TG9hZGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxHaXQgYXMgR2l0VXRpbDsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgU2VsZFxKc29uTGludFxQYXJzaW5nRXhjZXB0aW9uOwoKLyoqCiAqIFJlYWRzL3dyaXRlcyBwcm9qZWN0IGxvY2tmaWxlIChjb21wb3Nlci5sb2NrKS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgTG9ja2VyCnsKICAgIC8qKiBAdmFyIEpzb25GaWxlICovCiAgICBwcml2YXRlICRsb2NrRmlsZTsKICAgIC8qKiBAdmFyIEluc3RhbGxhdGlvbk1hbmFnZXIgKi8KICAgIHByaXZhdGUgJGluc3RhbGxhdGlvbk1hbmFnZXI7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGhhc2g7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbnRlbnRIYXNoOwogICAgLyoqIEB2YXIgQXJyYXlMb2FkZXIgKi8KICAgIHByaXZhdGUgJGxvYWRlcjsKICAgIC8qKiBAdmFyIEFycmF5RHVtcGVyICovCiAgICBwcml2YXRlICRkdW1wZXI7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByaXZhdGUgJHByb2Nlc3M7CiAgICBwcml2YXRlICRsb2NrRGF0YUNhY2hlOwogICAgcHJpdmF0ZSAkdmlydHVhbEZpbGVXcml0dGVuOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcGFja2FnZXMgbG9ja2VyLgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgICAgICRpbwogICAgICogQHBhcmFtIEpzb25GaWxlICAgICAgICAgICAgJGxvY2tGaWxlICAgICAgICAgICAgIGxvY2tmaWxlIGxvYWRlcgogICAgICogQHBhcmFtIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIgIGluc3RhbGxhdGlvbiBtYW5hZ2VyIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAkY29tcG9zZXJGaWxlQ29udGVudHMgVGhlIGNvbnRlbnRzIG9mIHRoZSBjb21wb3NlciBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIEpzb25GaWxlICRsb2NrRmlsZSwgSW5zdGFsbGF0aW9uTWFuYWdlciAkaW5zdGFsbGF0aW9uTWFuYWdlciwgJGNvbXBvc2VyRmlsZUNvbnRlbnRzLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5sb2NrRmlsZSA9ICRsb2NrRmlsZTsKICAgICAgICAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlciA9ICRpbnN0YWxsYXRpb25NYW5hZ2VyOwogICAgICAgICR0aGlzLT5oYXNoID0gbWQ1KCRjb21wb3NlckZpbGVDb250ZW50cyk7CiAgICAgICAgJHRoaXMtPmNvbnRlbnRIYXNoID0gc2VsZjo6Z2V0Q29udGVudEhhc2goJGNvbXBvc2VyRmlsZUNvbnRlbnRzKTsKICAgICAgICAkdGhpcy0+bG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKG51bGwsIHRydWUpOwogICAgICAgICR0aGlzLT5kdW1wZXIgPSBuZXcgQXJyYXlEdW1wZXIoKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1kNSBoYXNoIG9mIHRoZSBzb3J0ZWQgY29udGVudCBvZiB0aGUgY29tcG9zZXIgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21wb3NlckZpbGVDb250ZW50cyBUaGUgY29udGVudHMgb2YgdGhlIGNvbXBvc2VyIGZpbGUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDb250ZW50SGFzaCgkY29tcG9zZXJGaWxlQ29udGVudHMpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSBqc29uX2RlY29kZSgkY29tcG9zZXJGaWxlQ29udGVudHMsIHRydWUpOwoKICAgICAgICAkcmVsZXZhbnRLZXlzID0gYXJyYXkoCiAgICAgICAgICAgICduYW1lJywKICAgICAgICAgICAgJ3ZlcnNpb24nLAogICAgICAgICAgICAncmVxdWlyZScsCiAgICAgICAgICAgICdyZXF1aXJlLWRldicsCiAgICAgICAgICAgICdjb25mbGljdCcsCiAgICAgICAgICAgICdyZXBsYWNlJywKICAgICAgICAgICAgJ3Byb3ZpZGUnLAogICAgICAgICAgICAnbWluaW11bS1zdGFiaWxpdHknLAogICAgICAgICAgICAncHJlZmVyLXN0YWJsZScsCiAgICAgICAgICAgICdyZXBvc2l0b3JpZXMnLAogICAgICAgICAgICAnZXh0cmEnLAogICAgICAgICk7CgogICAgICAgICRyZWxldmFudENvbnRlbnQgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoIChhcnJheV9pbnRlcnNlY3QoJHJlbGV2YW50S2V5cywgYXJyYXlfa2V5cygkY29udGVudCkpIGFzICRrZXkpIHsKICAgICAgICAgICAgJHJlbGV2YW50Q29udGVudFska2V5XSA9ICRjb250ZW50WyRrZXldOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGNvbnRlbnRbJ2NvbmZpZyddWydwbGF0Zm9ybSddKSkgewogICAgICAgICAgICAkcmVsZXZhbnRDb250ZW50Wydjb25maWcnXVsncGxhdGZvcm0nXSA9ICRjb250ZW50Wydjb25maWcnXVsncGxhdGZvcm0nXTsKICAgICAgICB9CgogICAgICAgIGtzb3J0KCRyZWxldmFudENvbnRlbnQpOwoKICAgICAgICByZXR1cm4gbWQ1KGpzb25fZW5jb2RlKCRyZWxldmFudENvbnRlbnQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIGxvY2tlciBoYXMgYmVlbiBsb2NrZWQgKGxvY2tmaWxlIGZvdW5kKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzTG9ja2VkKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52aXJ0dWFsRmlsZVdyaXR0ZW4gJiYgISR0aGlzLT5sb2NrRmlsZS0+ZXhpc3RzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGRhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCRkYXRhWydwYWNrYWdlcyddKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBsb2NrIGZpbGUgaXMgc3RpbGwgdXAgdG8gZGF0ZSB3aXRoIHRoZSBjdXJyZW50IGhhc2gKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRnJlc2goKQogICAgewogICAgICAgICRsb2NrID0gJHRoaXMtPmxvY2tGaWxlLT5yZWFkKCk7CgogICAgICAgIGlmICghZW1wdHkoJGxvY2tbJ2NvbnRlbnQtaGFzaCddKSkgewogICAgICAgICAgICAvLyBUaGVyZSBpcyBhIGNvbnRlbnQgaGFzaCBrZXksIHVzZSB0aGF0IGluc3RlYWQgb2YgdGhlIGZpbGUgaGFzaAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRlbnRIYXNoID09PSAkbG9ja1snY29udGVudC1oYXNoJ107CiAgICAgICAgfQoKICAgICAgICAvLyBCQyBzdXBwb3J0IGZvciBvbGQgbG9jayBmaWxlcyB3aXRob3V0IGNvbnRlbnQtaGFzaAogICAgICAgIGlmICghZW1wdHkoJGxvY2tbJ2hhc2gnXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNoID09PSAkbG9ja1snaGFzaCddOwogICAgICAgIH0KCiAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSByZWFjaGVkIHVubGVzcyB0aGUgbG9jayBmaWxlIGlzIGNvcnJ1cHRlZCwgc28gYXNzdW1lIGl0J3Mgb3V0IG9mIGRhdGUKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZWFyY2hlcyBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBsb2NrZWQgcGFja2FnZXMsIHJldHJpZXZlZCBmcm9tIHJlZ2lzdGVyZWQgcmVwb3NpdG9yaWVzLgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkd2l0aERldlJlcXMgdHJ1ZSB0byByZXRyaWV2ZSB0aGUgbG9ja2VkIGRldiBwYWNrYWdlcwogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBcQ29tcG9zZXJcUmVwb3NpdG9yeVxMb2NrQXJyYXlSZXBvc2l0b3J5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NrZWRSZXBvc2l0b3J5KCR3aXRoRGV2UmVxcyA9IGZhbHNlKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwogICAgICAgICRwYWNrYWdlcyA9IG5ldyBMb2NrQXJyYXlSZXBvc2l0b3J5KCk7CgogICAgICAgICRsb2NrZWRQYWNrYWdlcyA9ICRsb2NrRGF0YVsncGFja2FnZXMnXTsKICAgICAgICBpZiAoJHdpdGhEZXZSZXFzKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkbG9ja0RhdGFbJ3BhY2thZ2VzLWRldiddKSkgewogICAgICAgICAgICAgICAgJGxvY2tlZFBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJGxvY2tlZFBhY2thZ2VzLCAkbG9ja0RhdGFbJ3BhY2thZ2VzLWRldiddKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIGxvY2sgZmlsZSBkb2VzIG5vdCBjb250YWluIHJlcXVpcmUtZGV2IGluZm9ybWF0aW9uLCBydW4gaW5zdGFsbCB3aXRoIHRoZSAtLW5vLWRldiBvcHRpb24gb3IgZGVsZXRlIGl0IGFuZCBydW4gY29tcG9zZXIgdXBkYXRlIHRvIGdlbmVyYXRlIGEgbmV3IGxvY2sgZmlsZS4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGVtcHR5KCRsb2NrZWRQYWNrYWdlcykpIHsKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlczsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkbG9ja2VkUGFja2FnZXNbMF1bJ25hbWUnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2VCeU5hbWUgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUGFja2FnZXMgYXMgJGluZm8pIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmxvYWRlci0+bG9hZCgkaW5mbyk7CiAgICAgICAgICAgICAgICAkcGFja2FnZXMtPmFkZFBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgJHBhY2thZ2VCeU5hbWVbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkcGFja2FnZTsKCiAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZUJ5TmFtZVskcGFja2FnZS0+Z2V0QWxpYXNPZigpLT5nZXROYW1lKCldID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzc2V0KCRsb2NrRGF0YVsnYWxpYXNlcyddKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxvY2tEYXRhWydhbGlhc2VzJ10gYXMgJGFsaWFzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlQnlOYW1lWyRhbGlhc1sncGFja2FnZSddXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGFsaWFzUGtnID0gbmV3IEFsaWFzUGFja2FnZSgkcGFja2FnZUJ5TmFtZVskYWxpYXNbJ3BhY2thZ2UnXV0sICRhbGlhc1snYWxpYXNfbm9ybWFsaXplZCddLCAkYWxpYXNbJ2FsaWFzJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAkYWxpYXNQa2ctPnNldFJvb3RQYWNrYWdlQWxpYXModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlcy0+YWRkUGFja2FnZSgkYWxpYXNQa2cpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlczsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91ciBjb21wb3Nlci5sb2NrIGlzIGludmFsaWQuIFJ1biAiY29tcG9zZXIgdXBkYXRlIiB0byBnZW5lcmF0ZSBhIG5ldyBvbmUuJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIE5hbWVzIG9mIGRlcGVuZGVuY2llcyBpbnN0YWxsZWQgdGhyb3VnaCByZXF1aXJlLWRldgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGV2UGFja2FnZU5hbWVzKCkKICAgIHsKICAgICAgICAkbmFtZXMgPSBhcnJheSgpOwogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwogICAgICAgIGlmIChpc3NldCgkbG9ja0RhdGFbJ3BhY2thZ2VzLWRldiddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkbG9ja0RhdGFbJ3BhY2thZ2VzLWRldiddIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkbmFtZXNbXSA9IHN0cnRvbG93ZXIoJHBhY2thZ2VbJ25hbWUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbmFtZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwbGF0Zm9ybSByZXF1aXJlbWVudHMgc3RvcmVkIGluIHRoZSBsb2NrIGZpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAkd2l0aERldlJlcXMgaWYgdHJ1ZSwgdGhlIHBsYXRmb3JtIHJlcXVpcmVtZW50cyBmcm9tIHRoZSByZXF1aXJlLWRldiBibG9jayBhcmUgYWxzbyByZXR1cm5lZAogICAgICogQHJldHVybiBcQ29tcG9zZXJcUGFja2FnZVxMaW5rW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtUmVxdWlyZW1lbnRzKCR3aXRoRGV2UmVxcyA9IGZhbHNlKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwogICAgICAgICRyZXF1aXJlbWVudHMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoIWVtcHR5KCRsb2NrRGF0YVsncGxhdGZvcm0nXSkpIHsKICAgICAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5sb2FkZXItPnBhcnNlTGlua3MoCiAgICAgICAgICAgICAgICAnX19yb290X18nLAogICAgICAgICAgICAgICAgJzEuMC4wJywKICAgICAgICAgICAgICAgIExpbms6OlRZUEVfUkVRVUlSRSwKICAgICAgICAgICAgICAgIGlzc2V0KCRsb2NrRGF0YVsncGxhdGZvcm0nXSkgPyAkbG9ja0RhdGFbJ3BsYXRmb3JtJ10gOiBhcnJheSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHdpdGhEZXZSZXFzICYmICFlbXB0eSgkbG9ja0RhdGFbJ3BsYXRmb3JtLWRldiddKSkgewogICAgICAgICAgICAkZGV2UmVxdWlyZW1lbnRzID0gJHRoaXMtPmxvYWRlci0+cGFyc2VMaW5rcygKICAgICAgICAgICAgICAgICdfX3Jvb3RfXycsCiAgICAgICAgICAgICAgICAnMS4wLjAnLAogICAgICAgICAgICAgICAgTGluazo6VFlQRV9SRVFVSVJFLAogICAgICAgICAgICAgICAgaXNzZXQoJGxvY2tEYXRhWydwbGF0Zm9ybS1kZXYnXSkgPyAkbG9ja0RhdGFbJ3BsYXRmb3JtLWRldiddIDogYXJyYXkoKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgJHJlcXVpcmVtZW50cyA9IGFycmF5X21lcmdlKCRyZXF1aXJlbWVudHMsICRkZXZSZXF1aXJlbWVudHMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXF1aXJlbWVudHM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGxvY2tEYXRhWydtaW5pbXVtLXN0YWJpbGl0eSddKSA/ICRsb2NrRGF0YVsnbWluaW11bS1zdGFiaWxpdHknXSA6ICdzdGFibGUnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGFiaWxpdHlGbGFncygpCiAgICB7CiAgICAgICAgJGxvY2tEYXRhID0gJHRoaXMtPmdldExvY2tEYXRhKCk7CgogICAgICAgIHJldHVybiBpc3NldCgkbG9ja0RhdGFbJ3N0YWJpbGl0eS1mbGFncyddKSA/ICRsb2NrRGF0YVsnc3RhYmlsaXR5LWZsYWdzJ10gOiBhcnJheSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmZXJTdGFibGUoKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICAvLyByZXR1cm4gbnVsbCBpZiBub3Qgc2V0IHRvIGFsbG93IGNhbGxlciBsb2dpYyB0byBjaG9vc2UgdGhlCiAgICAgICAgLy8gcmlnaHQgYmVoYXZpb3Igc2luY2Ugb2xkIGxvY2sgZmlsZXMgaGF2ZSBubyBwcmVmZXItc3RhYmxlCiAgICAgICAgcmV0dXJuIGlzc2V0KCRsb2NrRGF0YVsncHJlZmVyLXN0YWJsZSddKSA/ICRsb2NrRGF0YVsncHJlZmVyLXN0YWJsZSddIDogbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyTG93ZXN0KCkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgLy8gcmV0dXJuIG51bGwgaWYgbm90IHNldCB0byBhbGxvdyBjYWxsZXIgbG9naWMgdG8gY2hvb3NlIHRoZQogICAgICAgIC8vIHJpZ2h0IGJlaGF2aW9yIHNpbmNlIG9sZCBsb2NrIGZpbGVzIGhhdmUgbm8gcHJlZmVyLWxvd2VzdAogICAgICAgIHJldHVybiBpc3NldCgkbG9ja0RhdGFbJ3ByZWZlci1sb3dlc3QnXSkgPyAkbG9ja0RhdGFbJ3ByZWZlci1sb3dlc3QnXSA6IG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtT3ZlcnJpZGVzKCkKICAgIHsKICAgICAgICAkbG9ja0RhdGEgPSAkdGhpcy0+Z2V0TG9ja0RhdGEoKTsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCRsb2NrRGF0YVsncGxhdGZvcm0tb3ZlcnJpZGVzJ10pID8gJGxvY2tEYXRhWydwbGF0Zm9ybS1vdmVycmlkZXMnXSA6IGFycmF5KCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsaWFzZXMoKQogICAgewogICAgICAgICRsb2NrRGF0YSA9ICR0aGlzLT5nZXRMb2NrRGF0YSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJGxvY2tEYXRhWydhbGlhc2VzJ10pID8gJGxvY2tEYXRhWydhbGlhc2VzJ10gOiBhcnJheSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NrRGF0YSgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5sb2NrRGF0YUNhY2hlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bG9ja0RhdGFDYWNoZTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmxvY2tGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdObyBsb2NrZmlsZSBmb3VuZC4gVW5hYmxlIHRvIHJlYWQgbG9ja2VkIHBhY2thZ2VzJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmxvY2tEYXRhQ2FjaGUgPSAkdGhpcy0+bG9ja0ZpbGUtPnJlYWQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvY2tzIHByb3ZpZGVkIGRhdGEgaW50byBsb2NrZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRwYWNrYWdlcyAgICAgICAgICBhcnJheSBvZiBwYWNrYWdlcwogICAgICogQHBhcmFtIG1peGVkICAkZGV2UGFja2FnZXMgICAgICAgYXJyYXkgb2YgZGV2IHBhY2thZ2VzIG9yIG51bGwgaWYgaW5zdGFsbGVkIHdpdGhvdXQgLS1kZXYKICAgICAqIEBwYXJhbSBhcnJheSAgJHBsYXRmb3JtUmVxcyAgICAgIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBjb25zdHJhaW50IGZvciByZXF1aXJlZCBwbGF0Zm9ybSBwYWNrYWdlcwogICAgICogQHBhcmFtIG1peGVkICAkcGxhdGZvcm1EZXZSZXFzICAgYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IGNvbnN0cmFpbnQgZm9yIGRldi1yZXF1aXJlZCBwbGF0Zm9ybSBwYWNrYWdlcwogICAgICogQHBhcmFtIGFycmF5ICAkYWxpYXNlcyAgICAgICAgICAgYXJyYXkgb2YgYWxpYXNlcwogICAgICogQHBhcmFtIHN0cmluZyAkbWluaW11bVN0YWJpbGl0eQogICAgICogQHBhcmFtIGFycmF5ICAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSBib29sICAgJHByZWZlclN0YWJsZQogICAgICogQHBhcmFtIGJvb2wgICAkcHJlZmVyTG93ZXN0CiAgICAgKiBAcGFyYW0gYXJyYXkgICRwbGF0Zm9ybU92ZXJyaWRlcwogICAgICogQHBhcmFtIGJvb2wgICAkd3JpdGUgICAgICAgICAgICAgV2hldGhlciB0byBhY3R1YWxseSB3cml0ZSBkYXRhIHRvIGRpc2ssIHVzZWZ1bCBpbiB0ZXN0cyBhbmQgZm9yIC0tZHJ5LXJ1bgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9ja0RhdGEoYXJyYXkgJHBhY2thZ2VzLCAkZGV2UGFja2FnZXMsIGFycmF5ICRwbGF0Zm9ybVJlcXMsICRwbGF0Zm9ybURldlJlcXMsIGFycmF5ICRhbGlhc2VzLCAkbWluaW11bVN0YWJpbGl0eSwgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCAkcHJlZmVyU3RhYmxlLCAkcHJlZmVyTG93ZXN0LCBhcnJheSAkcGxhdGZvcm1PdmVycmlkZXMsICR3cml0ZSA9IHRydWUpCiAgICB7CiAgICAgICAgLy8ga2VlcCBvbGQgZGVmYXVsdCBicmFuY2ggbmFtZXMgbm9ybWFsaXplZCB0byBERUZBVUxUX0JSQU5DSF9BTElBUyBmb3IgQkMgYXMgdGhhdCBpcyBob3cgQ29tcG9zZXIgMSBvdXRwdXRzIHRoZSBsb2NrIGZpbGUKICAgICAgICAvLyB3aGVuIGxvYWRpbmcgdGhlIGxvY2sgZmlsZSB0aGUgdmVyc2lvbiBpcyBhbnl3YXkgaWdub3JlZCBpbiBDb21wb3NlciAyLCBzbyBpdCBoYXMgbm8gYWR2ZXJzZSBlZmZlY3QKICAgICAgICAkYWxpYXNlcyA9IGFycmF5X21hcChmdW5jdGlvbiAoJGFsaWFzKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkYWxpYXNbJ3ZlcnNpb24nXSwgYXJyYXkoJ2Rldi1tYXN0ZXInLCAnZGV2LXRydW5rJywgJ2Rldi1kZWZhdWx0JyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkYWxpYXNbJ3ZlcnNpb24nXSA9IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGFsaWFzOwogICAgICAgIH0sICRhbGlhc2VzKTsKCiAgICAgICAgJGxvY2sgPSBhcnJheSgKICAgICAgICAgICAgJ19yZWFkbWUnID0+IGFycmF5KCdUaGlzIGZpbGUgbG9ja3MgdGhlIGRlcGVuZGVuY2llcyBvZiB5b3VyIHByb2plY3QgdG8gYSBrbm93biBzdGF0ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUmVhZCBtb3JlIGFib3V0IGl0IGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMS1iYXNpYy11c2FnZS5tZCNpbnN0YWxsaW5nLWRlcGVuZGVuY2llcycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhpcyBmaWxlIGlzIEBnZW5lcicuJ2F0ZWQgYXV0b21hdGljYWxseScsICksCiAgICAgICAgICAgICdjb250ZW50LWhhc2gnID0+ICR0aGlzLT5jb250ZW50SGFzaCwKICAgICAgICAgICAgJ3BhY2thZ2VzJyA9PiBudWxsLAogICAgICAgICAgICAncGFja2FnZXMtZGV2JyA9PiBudWxsLAogICAgICAgICAgICAnYWxpYXNlcycgPT4gJGFsaWFzZXMsCiAgICAgICAgICAgICdtaW5pbXVtLXN0YWJpbGl0eScgPT4gJG1pbmltdW1TdGFiaWxpdHksCiAgICAgICAgICAgICdzdGFiaWxpdHktZmxhZ3MnID0+ICRzdGFiaWxpdHlGbGFncywKICAgICAgICAgICAgJ3ByZWZlci1zdGFibGUnID0+ICRwcmVmZXJTdGFibGUsCiAgICAgICAgICAgICdwcmVmZXItbG93ZXN0JyA9PiAkcHJlZmVyTG93ZXN0LAogICAgICAgICk7CgogICAgICAgICRsb2NrWydwYWNrYWdlcyddID0gJHRoaXMtPmxvY2tQYWNrYWdlcygkcGFja2FnZXMpOwogICAgICAgIGlmIChudWxsICE9PSAkZGV2UGFja2FnZXMpIHsKICAgICAgICAgICAgJGxvY2tbJ3BhY2thZ2VzLWRldiddID0gJHRoaXMtPmxvY2tQYWNrYWdlcygkZGV2UGFja2FnZXMpOwogICAgICAgIH0KCiAgICAgICAgJGxvY2tbJ3BsYXRmb3JtJ10gPSAkcGxhdGZvcm1SZXFzOwogICAgICAgICRsb2NrWydwbGF0Zm9ybS1kZXYnXSA9ICRwbGF0Zm9ybURldlJlcXM7CiAgICAgICAgaWYgKCRwbGF0Zm9ybU92ZXJyaWRlcykgewogICAgICAgICAgICAkbG9ja1sncGxhdGZvcm0tb3ZlcnJpZGVzJ10gPSAkcGxhdGZvcm1PdmVycmlkZXM7CiAgICAgICAgfQogICAgICAgICRsb2NrWydwbHVnaW4tYXBpLXZlcnNpb24nXSA9IFBsdWdpbkludGVyZmFjZTo6UExVR0lOX0FQSV9WRVJTSU9OOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkaXNMb2NrZWQgPSAkdGhpcy0+aXNMb2NrZWQoKTsKICAgICAgICB9IGNhdGNoIChQYXJzaW5nRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRpc0xvY2tlZCA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoISRpc0xvY2tlZCB8fCAkbG9jayAhPT0gJHRoaXMtPmdldExvY2tEYXRhKCkpIHsKICAgICAgICAgICAgaWYgKCR3cml0ZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxvY2tGaWxlLT53cml0ZSgkbG9jayk7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9ja0RhdGFDYWNoZSA9IG51bGw7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmlydHVhbEZpbGVXcml0dGVuID0gZmFsc2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmlydHVhbEZpbGVXcml0dGVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5sb2NrRGF0YUNhY2hlID0gSnNvbkZpbGU6OnBhcnNlSnNvbihKc29uRmlsZTo6ZW5jb2RlKCRsb2NrLCA0NDggJiBKc29uRmlsZTo6SlNPTl9QUkVUVFlfUFJJTlQpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2NrUGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICRsb2NrZWQgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICAgICAkdmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CgogICAgICAgICAgICBpZiAoISRuYW1lIHx8ICEkdmVyc2lvbikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdQYWNrYWdlICIlcyIgaGFzIG5vIHZlcnNpb24gb3IgbmFtZSBhbmQgY2FuIG5vdCBiZSBsb2NrZWQnLAogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHNwZWMgPSAkdGhpcy0+ZHVtcGVyLT5kdW1wKCRwYWNrYWdlKTsKICAgICAgICAgICAgdW5zZXQoJHNwZWNbJ3ZlcnNpb25fbm9ybWFsaXplZCddKTsKCiAgICAgICAgICAgIC8vIGFsd2F5cyBtb3ZlIHRpbWUgdG8gdGhlIGVuZCBvZiB0aGUgcGFja2FnZSBkZWZpbml0aW9uCiAgICAgICAgICAgICR0aW1lID0gaXNzZXQoJHNwZWNbJ3RpbWUnXSkgPyAkc3BlY1sndGltZSddIDogbnVsbDsKICAgICAgICAgICAgdW5zZXQoJHNwZWNbJ3RpbWUnXSk7CiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+aXNEZXYoKSAmJiAkcGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCkgPT09ICdzb3VyY2UnKSB7CiAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIGV4YWN0IGNvbW1pdCB0aW1lIG9mIHRoZSBjdXJyZW50IHJlZmVyZW5jZSBpZiBpdCdzIGEgZGV2IHBhY2thZ2UKICAgICAgICAgICAgICAgICR0aW1lID0gJHRoaXMtPmdldFBhY2thZ2VUaW1lKCRwYWNrYWdlKSA/OiAkdGltZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVsbCAhPT0gJHRpbWUpIHsKICAgICAgICAgICAgICAgICRzcGVjWyd0aW1lJ10gPSAkdGltZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdW5zZXQoJHNwZWNbJ2luc3RhbGxhdGlvbi1zb3VyY2UnXSk7CgogICAgICAgICAgICAkbG9ja2VkW10gPSAkc3BlYzsKICAgICAgICB9CgogICAgICAgIHVzb3J0KCRsb2NrZWQsIGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgJGNvbXBhcmlzb24gPSBzdHJjbXAoJGFbJ25hbWUnXSwgJGJbJ25hbWUnXSk7CgogICAgICAgICAgICBpZiAoMCAhPT0gJGNvbXBhcmlzb24pIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29tcGFyaXNvbjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgaXQgaXMgdGhlIHNhbWUgcGFja2FnZSwgY29tcGFyZSB0aGUgdmVyc2lvbnMgdG8gbWFrZSB0aGUgb3JkZXIgZGV0ZXJtaW5pc3RpYwogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhWyd2ZXJzaW9uJ10sICRiWyd2ZXJzaW9uJ10pOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gJGxvY2tlZDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2VzJ3MgZGF0ZXRpbWUgZm9yIGl0cyBzb3VyY2UgcmVmZXJlbmNlLgogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBUaGUgcGFja2FnZSB0byBzY2FuLgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCAgICAgIFRoZSBmb3JtYXR0ZWQgZGF0ZXRpbWUgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQYWNrYWdlVGltZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRwYXRoID0gcmVhbHBhdGgoJHRoaXMtPmluc3RhbGxhdGlvbk1hbmFnZXItPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKSk7CiAgICAgICAgJHNvdXJjZVR5cGUgPSAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpOwogICAgICAgICRkYXRldGltZSA9IG51bGw7CgogICAgICAgIGlmICgkcGF0aCAmJiBpbl9hcnJheSgkc291cmNlVHlwZSwgYXJyYXkoJ2dpdCcsICdoZycpKSkgewogICAgICAgICAgICAkc291cmNlUmVmID0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpID86ICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCk7CiAgICAgICAgICAgIHN3aXRjaCAoJHNvdXJjZVR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ2dpdCc6CiAgICAgICAgICAgICAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgbG9nIC1uMSAtLXByZXR0eT0lY3QgJy5Qcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkc291cmNlUmVmKS5HaXRVdGlsOjpnZXROb1Nob3dTaWduYXR1cmVGbGFnKCR0aGlzLT5wcm9jZXNzKSwgJG91dHB1dCwgJHBhdGgpICYmIHByZWdfbWF0Y2goJ3teXHMqXGQrXHMqJH0nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZGF0ZXRpbWUgPSBuZXcgXERhdGVUaW1lKCdAJy50cmltKCRvdXRwdXQpLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdoZyc6CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdoZyBsb2cgLS10ZW1wbGF0ZSAie2RhdGV8aGdkYXRlfSIgLXIgJy5Qcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkc291cmNlUmVmKSwgJG91dHB1dCwgJHBhdGgpICYmIHByZWdfbWF0Y2goJ3teXHMqKFxkKylccyp9JywgJG91dHB1dCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZGF0ZXRpbWUgPSBuZXcgXERhdGVUaW1lKCdAJy4kbWF0Y2hbMV0sIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGV0aW1lID8gJGRhdGV0aW1lLT5mb3JtYXQoREFURV9SRkMzMzM5KSA6IG51bGw7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQWxpYXNQYWNrYWdlIGV4dGVuZHMgQmFzZVBhY2thZ2UgaW1wbGVtZW50cyBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UKewogICAgcHJvdGVjdGVkICR2ZXJzaW9uOwogICAgcHJvdGVjdGVkICRwcmV0dHlWZXJzaW9uOwogICAgcHJvdGVjdGVkICRkZXY7CiAgICBwcm90ZWN0ZWQgJHJvb3RQYWNrYWdlQWxpYXMgPSBmYWxzZTsKICAgIHByb3RlY3RlZCAkc3RhYmlsaXR5OwogICAgcHJvdGVjdGVkICRoYXNTZWxmVmVyc2lvblJlcXVpcmVzID0gZmFsc2U7CgogICAgLyoqIEB2YXIgUGFja2FnZUludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRhbGlhc09mOwogICAgLyoqIEB2YXIgTGlua1tdICovCiAgICBwcm90ZWN0ZWQgJHJlcXVpcmVzOwogICAgLyoqIEB2YXIgTGlua1tdICovCiAgICBwcm90ZWN0ZWQgJGRldlJlcXVpcmVzOwogICAgLyoqIEB2YXIgTGlua1tdICovCiAgICBwcm90ZWN0ZWQgJGNvbmZsaWN0czsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRwcm92aWRlczsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRyZXBsYWNlczsKCiAgICAvKioKICAgICAqIEFsbCBkZXNjZW5kYW50cycgY29uc3RydWN0b3JzIHNob3VsZCBjYWxsIHRoaXMgcGFyZW50IGNvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJGFsaWFzT2YgICAgICAgVGhlIHBhY2thZ2UgdGhpcyBwYWNrYWdlIGlzIGFuIGFsaWFzIG9mCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdmVyc2lvbiAgICAgICBUaGUgdmVyc2lvbiB0aGUgYWxpYXMgbXVzdCByZXBvcnQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRwcmV0dHlWZXJzaW9uIFRoZSBhbGlhcydzIG5vbi1ub3JtYWxpemVkIHZlcnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFBhY2thZ2VJbnRlcmZhY2UgJGFsaWFzT2YsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbikKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRhbGlhc09mLT5nZXROYW1lKCkpOwoKICAgICAgICAkdGhpcy0+dmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgICR0aGlzLT5wcmV0dHlWZXJzaW9uID0gJHByZXR0eVZlcnNpb247CiAgICAgICAgJHRoaXMtPmFsaWFzT2YgPSAkYWxpYXNPZjsKICAgICAgICAkdGhpcy0+c3RhYmlsaXR5ID0gVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHZlcnNpb24pOwogICAgICAgICR0aGlzLT5kZXYgPSAkdGhpcy0+c3RhYmlsaXR5ID09PSAnZGV2JzsKCiAgICAgICAgZm9yZWFjaCAoTGluazo6JFRZUEVTIGFzICR0eXBlKSB7CiAgICAgICAgICAgICRsaW5rcyA9ICRhbGlhc09mLT57J2dldCcgLiB1Y2ZpcnN0KCR0eXBlKX0oKTsKICAgICAgICAgICAgJHRoaXMtPiR0eXBlID0gJHRoaXMtPnJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcygkbGlua3MsICR0eXBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsaWFzT2YoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFiaWxpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RldigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXY7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXF1aXJlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZsaWN0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25mbGljdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm92aWRlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcGxhY2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcGxhY2VzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGV2UmVxdWlyZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2UmVxdWlyZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZXMgd2hldGhlciB0aGlzIGlzIGFuIGFsaWFzIGNyZWF0ZWQgYnkgYW4gYWxpYXNpbmcgaW4gdGhlIHJlcXVpcmVtZW50cyBvZiB0aGUgcm9vdCBwYWNrYWdlIG9yIG5vdAogICAgICoKICAgICAqIFVzZSBieSB0aGUgcG9saWN5IGZvciBzb3J0aW5nIG1hbnVhbGx5IGFsaWFzZWQgcGFja2FnZXMgZmlyc3QsIHNlZSAjNTc2CiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Um9vdFBhY2thZ2VBbGlhcygkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UGFja2FnZUFsaWFzID0gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBzZXRSb290UGFja2FnZUFsaWFzCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUm9vdFBhY2thZ2VBbGlhcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yb290UGFja2FnZUFsaWFzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIExpbmtbXSAkbGlua3MKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmtUeXBlCiAgICAgKgogICAgICogQHJldHVybiBMaW5rW10KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcyhhcnJheSAkbGlua3MsICRsaW5rVHlwZSkKICAgIHsKICAgICAgICAvLyBmb3Igc2VsZi52ZXJzaW9uIHJlcXVpcmVtZW50cywgd2UgdXNlIHRoZSBvcmlnaW5hbCBwYWNrYWdlJ3MgYnJhbmNoIG5hbWUgaW5zdGVhZCwgdG8gYXZvaWQgbGVha2luZyB0aGUgbWFnaWMgZGV2LW1hc3Rlci1hbGlhcyB0byB1c2VycwogICAgICAgICRwcmV0dHlWZXJzaW9uID0gJHRoaXMtPnByZXR0eVZlcnNpb247CiAgICAgICAgaWYgKCRwcmV0dHlWZXJzaW9uID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICR0aGlzLT5hbGlhc09mLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGluX2FycmF5KCRsaW5rVHlwZSwgYXJyYXkoTGluazo6VFlQRV9DT05GTElDVCwgTGluazo6VFlQRV9QUk9WSURFLCBMaW5rOjpUWVBFX1JFUExBQ0UpLCB0cnVlKSkgewogICAgICAgICAgICAkbmV3TGlua3MgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIC8vIGxpbmsgaXMgc2VsZi52ZXJzaW9uLCBidXQgbXVzdCBiZSByZXBsYWNpbmcgYWxzbyB0aGUgcmVwbGFjZWQgdmVyc2lvbgogICAgICAgICAgICAgICAgaWYgKCdzZWxmLnZlcnNpb24nID09PSAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJG5ld0xpbmtzW10gPSBuZXcgTGluaygkbGluay0+Z2V0U291cmNlKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgJGNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPScsICR0aGlzLT52ZXJzaW9uKSwgJGxpbmtUeXBlLCAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQtPnNldFByZXR0eVN0cmluZygkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpbmtzID0gYXJyYXlfbWVyZ2UoJGxpbmtzLCAkbmV3TGlua3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkaW5kZXggPT4gJGxpbmspIHsKICAgICAgICAgICAgICAgIGlmICgnc2VsZi52ZXJzaW9uJyA9PT0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbGlua1R5cGUgPT09IExpbms6OlRZUEVfUkVRVUlSRSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aGFzU2VsZlZlcnNpb25SZXF1aXJlcyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsaW5rc1skaW5kZXhdID0gbmV3IExpbmsoJGxpbmstPmdldFNvdXJjZSgpLCAkbGluay0+Z2V0VGFyZ2V0KCksICRjb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAkdGhpcy0+dmVyc2lvbiksICRsaW5rVHlwZSwgJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50LT5zZXRQcmV0dHlTdHJpbmcoJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxpbmtzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNTZWxmVmVyc2lvblJlcXVpcmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1NlbGZWZXJzaW9uUmVxdWlyZXM7CiAgICB9CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICogV3JhcHBlcnMgYXJvdW5kIHRoZSBhbGlhc2VkIHBhY2thZ2UgKgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRUeXBlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhcmdldERpcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRUYXJnZXREaXIoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXh0cmEoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RXh0cmEoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5zdGFsbGF0aW9uU291cmNlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRJbnN0YWxsYXRpb25Tb3VyY2UoJHR5cGUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsYXRpb25Tb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U291cmNlVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U291cmNlVXJsKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVVybHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U291cmNlVXJscygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VSZWZlcmVuY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZVJlZmVyZW5jZSgkcmVmZXJlbmNlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+c2V0U291cmNlUmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VNaXJyb3JzKCRtaXJyb3JzKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+c2V0U291cmNlTWlycm9ycygkbWlycm9ycyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZU1pcnJvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U291cmNlTWlycm9ycygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREaXN0VHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldERpc3RVcmwoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFVybHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RGlzdFVybHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFJlZmVyZW5jZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREaXN0UmVmZXJlbmNlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RSZWZlcmVuY2UoJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPnNldERpc3RSZWZlcmVuY2UoJHJlZmVyZW5jZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RTaGExQ2hlY2tzdW0oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RGlzdFNoYTFDaGVja3N1bSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFuc3BvcnRPcHRpb25zKGFycmF5ICRvcHRpb25zKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+c2V0VHJhbnNwb3J0T3B0aW9ucygkb3B0aW9ucyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zcG9ydE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXN0TWlycm9ycygkbWlycm9ycykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPnNldERpc3RNaXJyb3JzKCRtaXJyb3JzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdE1pcnJvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RGlzdE1pcnJvcnMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2NyaXB0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRTY3JpcHRzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldExpY2Vuc2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0TGljZW5zZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvbG9hZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBdXRvbG9hZCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZBdXRvbG9hZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXREZXZBdXRvbG9hZCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbmNsdWRlUGF0aHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0SW5jbHVkZVBhdGhzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcmllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRSZXBvc2l0b3JpZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVsZWFzZURhdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0UmVsZWFzZURhdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QmluYXJpZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0QmluYXJpZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2V5d29yZHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0S2V5d29yZHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0RGVzY3JpcHRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SG9tZXBhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0SG9tZXBhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3VnZ2VzdHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U3VnZ2VzdHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aG9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBdXRob3JzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0U3VwcG9ydCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdW5kaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldEZ1bmRpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Tm90aWZpY2F0aW9uVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldE5vdGlmaWNhdGlvblVybCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmNoaXZlTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBcmNoaXZlTmFtZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmNoaXZlRXhjbHVkZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+Z2V0QXJjaGl2ZUV4Y2x1ZGVzKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVmYXVsdEJyYW5jaCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5pc0RlZmF1bHRCcmFuY2goKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBYmFuZG9uZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+aXNBYmFuZG9uZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZW1lbnRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gcGFyZW50OjpfX3RvU3RyaW5nKCkuJyAoJy4oJHRoaXMtPnJvb3RQYWNrYWdlQWxpYXMgPyAncm9vdCAnIDogJycpLiAnYWxpYXMgb2YgJy4kdGhpcy0+YWxpYXNPZi0+Z2V0VmVyc2lvbigpLicpJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFVybCgkdXJsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWxpYXNPZi0+c2V0RGlzdFVybCgkdXJsKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFR5cGUoJHR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5zZXREaXN0VHlwZSgkdHlwZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5zZXRTb3VyY2VEaXN0UmVmZXJlbmNlcygkcmVmZXJlbmNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlOwoKLyoqCiAqIERlZmluZXMgcGFja2FnZSBtZXRhZGF0YSB0aGF0IGlzIG5vdCBuZWNlc3NhcmlseSBuZWVkZWQgZm9yIHNvbHZpbmcgYW5kIGluc3RhbGxpbmcgcGFja2FnZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmludGVyZmFjZSBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgZXh0ZW5kcyBQYWNrYWdlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2NyaXB0cyBvZiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5W10gYXJyYXkoJ3NjcmlwdCBuYW1lJyA9PiBhcnJheSgnbGlzdGVuZXJzJykpCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgc3RyaW5nW10+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY3JpcHRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlcG9zaXRvcmllcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXSBSZXBvc2l0b3JpZXMKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXk8YXJyYXl7dHlwZTogc3RyaW5nLCB1cmw/OiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlIGxpY2Vuc2UsIGUuZy4gTUlULCBCU0QsIEdQTAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10gVGhlIHBhY2thZ2UgbGljZW5zZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExpY2Vuc2UoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2Yga2V5d29yZHMgcmVsYXRpbmcgdG8gdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXl3b3JkcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBkZXNjcmlwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBob21lcGFnZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIb21lcGFnZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBhdXRob3JzIG9mIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogRWFjaCBpdGVtIGNhbiBjb250YWluIG5hbWUvaG9tZXBhZ2UvZW1haWwga2V5cwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXlbXQogICAgICogQHBzYWxtLXJldHVybiBhcnJheTxhcnJheXs/bmFtZTogc3RyaW5nLCBob21lcGFnZT86IHN0cmluZywgZW1haWw/OiBzdHJpbmcsIHJvbGU/OiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aG9ycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3VwcG9ydCBpbmZvcm1hdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXk8c3RyaW5nLCBzdHJpbmc+CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdXBwb3J0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGZ1bmRpbmcgb3B0aW9ucyBmb3IgdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBFYWNoIGl0ZW0gd2lsbCBjb250YWluIHR5cGUgYW5kIHVybCBrZXlzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PGFycmF5e3R5cGU6IHN0cmluZywgdXJsOiBzdHJpbmd9PgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVuZGluZygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBpZiB0aGUgcGFja2FnZSBpcyBhYmFuZG9uZWQgb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0FiYW5kb25lZCgpOwoKICAgIC8qKgogICAgICogSWYgdGhlIHBhY2thZ2UgaXMgYWJhbmRvbmVkIGFuZCBoYXMgYSBzdWdnZXN0ZWQgcmVwbGFjZW1lbnQsIHRoaXMgbWV0aG9kIHJldHVybnMgaXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZW1lbnRQYWNrYWdlKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCi8qKgogKiBUaGUgcm9vdCBwYWNrYWdlIHJlcHJlc2VudHMgdGhlIHByb2plY3QncyBjb21wb3Nlci5qc29uIGFuZCBjb250YWlucyBhZGRpdGlvbmFsIG1ldGFkYXRhCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJvb3RQYWNrYWdlIGV4dGVuZHMgQ29tcGxldGVQYWNrYWdlIGltcGxlbWVudHMgUm9vdFBhY2thZ2VJbnRlcmZhY2UKewogICAgY29uc3QgREVGQVVMVF9QUkVUVFlfVkVSU0lPTiA9ICcxLjAuMCtuby12ZXJzaW9uLXNldCc7CgogICAgcHJvdGVjdGVkICRtaW5pbXVtU3RhYmlsaXR5ID0gJ3N0YWJsZSc7CiAgICBwcm90ZWN0ZWQgJHByZWZlclN0YWJsZSA9IGZhbHNlOwogICAgcHJvdGVjdGVkICRzdGFiaWxpdHlGbGFncyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJGNvbmZpZyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJHJlZmVyZW5jZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRhbGlhc2VzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgbWluaW11bVN0YWJpbGl0eQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1pbmltdW1TdGFiaWxpdHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1pbmltdW1TdGFiaWxpdHkoJG1pbmltdW1TdGFiaWxpdHkpCiAgICB7CiAgICAgICAgJHRoaXMtPm1pbmltdW1TdGFiaWxpdHkgPSAkbWluaW11bVN0YWJpbGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWluaW11bVN0YWJpbGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgc3RhYmlsaXR5RmxhZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHN0YWJpbGl0eUZsYWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGFiaWxpdHlGbGFncyhhcnJheSAkc3RhYmlsaXR5RmxhZ3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YWJpbGl0eUZsYWdzID0gJHN0YWJpbGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhYmlsaXR5RmxhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHByZWZlclN0YWJsZQogICAgICoKICAgICAqIEBwYXJhbSBib29sICRwcmVmZXJTdGFibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlclN0YWJsZSgkcHJlZmVyU3RhYmxlKQogICAgewogICAgICAgICR0aGlzLT5wcmVmZXJTdGFibGUgPSAkcHJlZmVyU3RhYmxlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyU3RhYmxlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZlclN0YWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgY29uZmlnCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRjb25maWcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZpZyhhcnJheSAkY29uZmlnKQogICAgewogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVmZXJlbmNlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkcmVmZXJlbmNlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVmZXJlbmNlcyhhcnJheSAkcmVmZXJlbmNlcykKICAgIHsKICAgICAgICAkdGhpcy0+cmVmZXJlbmNlcyA9ICRyZWZlcmVuY2VzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWZlcmVuY2VzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBhbGlhc2VzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhbGlhc2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBbGlhc2VzKGFycmF5ICRhbGlhc2VzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc2VzID0gJGFsaWFzZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbGlhc2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU2VtdmVyXFZlcnNpb25QYXJzZXIgYXMgU2VtdmVyVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxTZW12ZXI7CgpjbGFzcyBWZXJzaW9uUGFyc2VyIGV4dGVuZHMgU2VtdmVyVmVyc2lvblBhcnNlcgp7CiAgICBjb25zdCBERUZBVUxUX0JSQU5DSF9BTElBUyA9ICc5OTk5OTk5LWRldic7CgogICAgcHJpdmF0ZSBzdGF0aWMgJGNvbnN0cmFpbnRzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnRzKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGNvbnN0cmFpbnRzWyRjb25zdHJhaW50c10pKSB7CiAgICAgICAgICAgIHNlbGY6OiRjb25zdHJhaW50c1skY29uc3RyYWludHNdID0gcGFyZW50OjpwYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50cyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGNvbnN0cmFpbnRzWyRjb25zdHJhaW50c107CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgcGFja2FnZS92ZXJzaW9uIHBhaXJzLgogICAgICoKICAgICAqIFRoZSBwYXJzaW5nIHJlc3VsdHMgaW4gYW4gYXJyYXkgb2YgYXJyYXlzLCBlYWNoIG9mIHdoaWNoCiAgICAgKiBjb250YWluIGEgJ25hbWUnIGtleSB3aXRoIHZhbHVlIGFuZCBvcHRpb25hbGx5IGEgJ3ZlcnNpb24nIGtleSB3aXRoIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkcGFpcnMgYSBzZXQgb2YgcGFja2FnZS92ZXJzaW9uIHBhaXJzIHNlcGFyYXRlZCBieSAiOiIsICI9IiBvciAiICIKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5W10gYXJyYXkgb2YgYXJyYXlzIGNvbnRhaW5pbmcgYSBuYW1lIGFuZCAoaWYgcHJvdmlkZWQpIGEgdmVyc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VOYW1lVmVyc2lvblBhaXJzKGFycmF5ICRwYWlycykKICAgIHsKICAgICAgICAkcGFpcnMgPSBhcnJheV92YWx1ZXMoJHBhaXJzKTsKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKCiAgICAgICAgZm9yICgkaSA9IDAsICRjb3VudCA9IGNvdW50KCRwYWlycyk7ICRpIDwgJGNvdW50OyAkaSsrKSB7CiAgICAgICAgICAgICRwYWlyID0gcHJlZ19yZXBsYWNlKCd7XihbXj06IF0rKVs9OiBdKC4qKSR9JywgJyQxICQyJywgdHJpbSgkcGFpcnNbJGldKSk7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gc3RycG9zKCRwYWlyLCAnICcpICYmIGlzc2V0KCRwYWlyc1skaSArIDFdKSAmJiBmYWxzZSA9PT0gc3RycG9zKCRwYWlyc1skaSArIDFdLCAnLycpICYmICFQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRwYWlyc1skaSArIDFdKSkgewogICAgICAgICAgICAgICAgJHBhaXIgLj0gJyAnLiRwYWlyc1skaSArIDFdOwogICAgICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHN0cnBvcygkcGFpciwgJyAnKSkgewogICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJHZlcnNpb24pID0gZXhwbG9kZSgnICcsICRwYWlyLCAyKTsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KCduYW1lJyA9PiAkbmFtZSwgJ3ZlcnNpb24nID0+ICR2ZXJzaW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KCduYW1lJyA9PiAkcGFpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNVcGdyYWRlKCRub3JtYWxpemVkRnJvbSwgJG5vcm1hbGl6ZWRUbykKICAgIHsKICAgICAgICBpZiAoJG5vcm1hbGl6ZWRGcm9tID09PSAkbm9ybWFsaXplZFRvKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGluX2FycmF5KCRub3JtYWxpemVkRnJvbSwgYXJyYXkoJ2Rldi1tYXN0ZXInLCAnZGV2LXRydW5rJywgJ2Rldi1kZWZhdWx0JyksIHRydWUpKSB7CiAgICAgICAgICAgICRub3JtYWxpemVkRnJvbSA9IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgIH0KICAgICAgICBpZiAoaW5fYXJyYXkoJG5vcm1hbGl6ZWRUbywgYXJyYXkoJ2Rldi1tYXN0ZXInLCAnZGV2LXRydW5rJywgJ2Rldi1kZWZhdWx0JyksIHRydWUpKSB7CiAgICAgICAgICAgICRub3JtYWxpemVkVG8gPSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUzsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJG5vcm1hbGl6ZWRGcm9tLCAnZGV2LScpID09PSAwIHx8IHN0cnBvcygkbm9ybWFsaXplZFRvLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHNvcnRlZCA9IFNlbXZlcjo6c29ydChhcnJheSgkbm9ybWFsaXplZFRvLCAkbm9ybWFsaXplZEZyb20pKTsKCiAgICAgICAgcmV0dXJuICRzb3J0ZWRbMF0gPT09ICRub3JtYWxpemVkRnJvbTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcRHVtcGVyXEFycmF5RHVtcGVyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIFNlbGVjdHMgdGhlIGJlc3QgcG9zc2libGUgdmVyc2lvbiBmb3IgYSBwYWNrYWdlCiAqCiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wdW5pdmVyc2l0eS5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFZlcnNpb25TZWxlY3Rvcgp7CiAgICBwcml2YXRlICRyZXBvc2l0b3J5U2V0OwoKICAgIHByaXZhdGUgJHBsYXRmb3JtQ29uc3RyYWludHMgPSBhcnJheSgpOwoKICAgIHByaXZhdGUgJHBhcnNlcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbyBJZiBwYXNzZWQgaW4sIHRoZSB2ZXJzaW9ucyBmb3VuZCB3aWxsIGJlIGZpbHRlcmVkIGFnYWluc3QgdGhlaXIgcmVxdWlyZW1lbnRzIHRvIGVsaW1pbmF0ZSBhbnkgbm90IG1hdGNoaW5nIHRoZSBjdXJyZW50IHBsYXRmb3JtIHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlTZXQgPSAkcmVwb3NpdG9yeVNldDsKICAgICAgICBpZiAoJHBsYXRmb3JtUmVwbykgewogICAgICAgICAgICBmb3JlYWNoICgkcGxhdGZvcm1SZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGxhdGZvcm1Db25zdHJhaW50c1skcGFja2FnZS0+Z2V0TmFtZSgpXVtdID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHBhY2thZ2UtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIHBhY2thZ2UgbmFtZSBhbmQgb3B0aW9uYWwgdmVyc2lvbiwgcmV0dXJucyB0aGUgbGF0ZXN0IFBhY2thZ2VJbnRlcmZhY2UKICAgICAqIHRoYXQgbWF0Y2hlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgJHRhcmdldFBhY2thZ2VWZXJzaW9uCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgJHByZWZlcnJlZFN0YWJpbGl0eQogICAgICogQHBhcmFtICBib29sfGFycmF5ICAgICAgICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMKICAgICAqIEByZXR1cm4gUGFja2FnZUludGVyZmFjZXxmYWxzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZEJlc3RDYW5kaWRhdGUoJHBhY2thZ2VOYW1lLCAkdGFyZ2V0UGFja2FnZVZlcnNpb24gPSBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJ3N0YWJsZScsICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSBmYWxzZSwgJHJlcG9TZXRGbGFncyA9IDApCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyRwcmVmZXJyZWRTdGFiaWxpdHldKSkgewogICAgICAgICAgICAvLyBJZiB5b3UgZ2V0IHRoaXMsIG1heWJlIHlvdSBhcmUgc3RpbGwgcmVseWluZyBvbiB0aGUgQ29tcG9zZXIgMS54IHNpZ25hdHVyZSB3aGVyZSB0aGUgM3JkIGFyZyB3YXMgdGhlIHBocCB2ZXJzaW9uCiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdFeHBlY3RlZCBhIHZhbGlkIHN0YWJpbGl0eSBuYW1lIGFzIDNyZCBhcmd1bWVudCwgZ290ICcuJHByZWZlcnJlZFN0YWJpbGl0eSk7CiAgICAgICAgfQoKICAgICAgICAkY29uc3RyYWludCA9ICR0YXJnZXRQYWNrYWdlVmVyc2lvbiA/ICR0aGlzLT5nZXRQYXJzZXIoKS0+cGFyc2VDb25zdHJhaW50cygkdGFyZ2V0UGFja2FnZVZlcnNpb24pIDogbnVsbDsKICAgICAgICAkY2FuZGlkYXRlcyA9ICR0aGlzLT5yZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoc3RydG9sb3dlcigkcGFja2FnZU5hbWUpLCAkY29uc3RyYWludCwgJHJlcG9TZXRGbGFncyk7CgogICAgICAgIGlmICgkdGhpcy0+cGxhdGZvcm1Db25zdHJhaW50cyAmJiB0cnVlICE9PSAkaWdub3JlUGxhdGZvcm1SZXFzKSB7CiAgICAgICAgICAgICRwbGF0Zm9ybUNvbnN0cmFpbnRzID0gJHRoaXMtPnBsYXRmb3JtQ29uc3RyYWludHM7CiAgICAgICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSAkaWdub3JlUGxhdGZvcm1SZXFzID86IGFycmF5KCk7CiAgICAgICAgICAgICRjYW5kaWRhdGVzID0gYXJyYXlfZmlsdGVyKCRjYW5kaWRhdGVzLCBmdW5jdGlvbiAoJHBrZykgdXNlICgkcGxhdGZvcm1Db25zdHJhaW50cywgJGlnbm9yZVBsYXRmb3JtUmVxcykgewogICAgICAgICAgICAgICAgJHJlcXMgPSAkcGtnLT5nZXRSZXF1aXJlcygpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZXFzIGFzICRuYW1lID0+ICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkbmFtZSwgJGlnbm9yZVBsYXRmb3JtUmVxcywgdHJ1ZSkgJiYgaXNzZXQoJHBsYXRmb3JtQ29uc3RyYWludHNbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGxhdGZvcm1Db25zdHJhaW50c1skbmFtZV0gYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0Q29uc3RyYWludCgpLT5tYXRjaGVzKCRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkY2FuZGlkYXRlcykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBzZWxlY3QgaGlnaGVzdCB2ZXJzaW9uIGlmIHdlIGhhdmUgbWFueQogICAgICAgICRwYWNrYWdlID0gcmVzZXQoJGNhbmRpZGF0ZXMpOwogICAgICAgICRtaW5Qcmlvcml0eSA9IEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbJHByZWZlcnJlZFN0YWJpbGl0eV07CiAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZXMgYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICAkY2FuZGlkYXRlUHJpb3JpdHkgPSAkY2FuZGlkYXRlLT5nZXRTdGFiaWxpdHlQcmlvcml0eSgpOwogICAgICAgICAgICAkY3VycmVudFByaW9yaXR5ID0gJHBhY2thZ2UtPmdldFN0YWJpbGl0eVByaW9yaXR5KCk7CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbGVzcyBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBtb3JlIHN0YWJsZSB0aGFuIGNhbmRpZGF0ZSwgc2tpcCBpdAogICAgICAgICAgICBpZiAoJG1pblByaW9yaXR5IDwgJGNhbmRpZGF0ZVByaW9yaXR5ICYmICRjdXJyZW50UHJpb3JpdHkgPCAkY2FuZGlkYXRlUHJpb3JpdHkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbGVzcyBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBsZXNzIHN0YWJsZSB0aGFuIGNhbmRpZGF0ZSwgc2VsZWN0IGNhbmRpZGF0ZQogICAgICAgICAgICBpZiAoJG1pblByaW9yaXR5IDwgJGNhbmRpZGF0ZVByaW9yaXR5ICYmICRjYW5kaWRhdGVQcmlvcml0eSA8ICRjdXJyZW50UHJpb3JpdHkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJGNhbmRpZGF0ZTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYW5kaWRhdGUgaXMgbW9yZSBzdGFibGUgdGhhbiBvdXIgcHJlZmVycmVkIHN0YWJpbGl0eSwKICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgcGFja2FnZSBpcyBsZXNzIHN0YWJsZSB0aGFuIHByZWZlcnJlZCBzdGFiaWxpdHksIHNlbGVjdCBjYW5kaWRhdGUKICAgICAgICAgICAgaWYgKCRtaW5Qcmlvcml0eSA+PSAkY2FuZGlkYXRlUHJpb3JpdHkgJiYgJG1pblByaW9yaXR5IDwgJGN1cnJlbnRQcmlvcml0eSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNlbGVjdCBoaWdoZXN0IHZlcnNpb24gb2YgdGhlIHR3bwogICAgICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKCRwYWNrYWdlLT5nZXRWZXJzaW9uKCksICRjYW5kaWRhdGUtPmdldFZlcnNpb24oKSwgJzwnKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSBlbmQgdXAgd2l0aCA5OTk5OTk5LWRldiBhcyBzZWxlY3RlZCBwYWNrYWdlLCBtYWtlIHN1cmUgd2UgdXNlIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIGluc3RlYWQgb2YgdGhlIGFsaWFzCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdpdmVuIGEgY29uY3JldGUgdmVyc2lvbiwgdGhpcyByZXR1cm5zIGEgXiBjb25zdHJhaW50ICh3aGVuIHBvc3NpYmxlKQogICAgICogdGhhdCBzaG91bGQgYmUgdXNlZCwgZm9yIGV4YW1wbGUsIGluIGNvbXBvc2VyLmpzb24uCiAgICAgKgogICAgICogRm9yIGV4YW1wbGU6CiAgICAgKiAgKiAxLjIuMSAgICAgICAgIC0+IF4xLjIKICAgICAqICAqIDEuMiAgICAgICAgICAgLT4gXjEuMgogICAgICogICogdjMuMi4xICAgICAgICAtPiBeMy4yCiAgICAgKiAgKiAyLjAtYmV0YS4xICAgIC0+IF4yLjBAYmV0YQogICAgICogICogZGV2LW1hc3RlciAgICAtPiBeMi4xQGRldiAgICAgIChkZXYgdmVyc2lvbiB3aXRoIGFsaWFzKQogICAgICogICogZGV2LW1hc3RlciAgICAtPiBkZXYtbWFzdGVyICAgIChkZXYgdmVyc2lvbnMgYXJlIHVudG91Y2hlZCkKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kUmVjb21tZW5kZWRSZXF1aXJlVmVyc2lvbihQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR2ZXJzaW9uID0gJHBhY2thZ2UtPmdldFZlcnNpb24oKTsKICAgICAgICBpZiAoISRwYWNrYWdlLT5pc0RldigpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dHJhbnNmb3JtVmVyc2lvbigkdmVyc2lvbiwgJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSwgJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpKTsKICAgICAgICB9CgogICAgICAgICRsb2FkZXIgPSBuZXcgQXJyYXlMb2FkZXIoJHRoaXMtPmdldFBhcnNlcigpKTsKICAgICAgICAkZHVtcGVyID0gbmV3IEFycmF5RHVtcGVyKCk7CiAgICAgICAgJGV4dHJhID0gJGxvYWRlci0+Z2V0QnJhbmNoQWxpYXMoJGR1bXBlci0+ZHVtcCgkcGFja2FnZSkpOwogICAgICAgIGlmICgkZXh0cmEgJiYgJGV4dHJhICE9PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAkZXh0cmEgPSBwcmVnX3JlcGxhY2UoJ3teKFxkK1wuXGQrXC5cZCspKFwuOTk5OTk5OSktZGV2JH0nLCAnJDEuMCcsICRleHRyYSwgLTEsICRjb3VudCk7CiAgICAgICAgICAgIGlmICgkY291bnQpIHsKICAgICAgICAgICAgICAgICRleHRyYSA9IHN0cl9yZXBsYWNlKCcuOTk5OTk5OScsICcuMCcsICRleHRyYSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT50cmFuc2Zvcm1WZXJzaW9uKCRleHRyYSwgJGV4dHJhLCAnZGV2Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdHJhbnNmb3JtVmVyc2lvbigkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24sICRzdGFiaWxpdHkpCiAgICB7CiAgICAgICAgLy8gYXR0ZW1wdCB0byB0cmFuc2Zvcm0gMi4xLjEgdG8gMi4xCiAgICAgICAgLy8gdGhpcyBhbGxvd3MgeW91IHRvIHVwZ3JhZGUgdGhyb3VnaCBtaW5vciB2ZXJzaW9ucwogICAgICAgICRzZW1hbnRpY1ZlcnNpb25QYXJ0cyA9IGV4cGxvZGUoJy4nLCAkdmVyc2lvbik7CgogICAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgc2VtdmVyLWxvb2tpbmcgdmVyc2lvbgogICAgICAgIGlmIChjb3VudCgkc2VtYW50aWNWZXJzaW9uUGFydHMpID09IDQgJiYgcHJlZ19tYXRjaCgne14wXEQ/fScsICRzZW1hbnRpY1ZlcnNpb25QYXJ0c1szXSkpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBsYXN0IHBhcnRzIChpLmUuIHRoZSBwYXRjaCB2ZXJzaW9uIG51bWJlciBhbmQgYW55IGV4dHJhKQogICAgICAgICAgICBpZiAoJHNlbWFudGljVmVyc2lvblBhcnRzWzBdID09PSAnMCcpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRzZW1hbnRpY1ZlcnNpb25QYXJ0c1szXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1bnNldCgkc2VtYW50aWNWZXJzaW9uUGFydHNbMl0sICRzZW1hbnRpY1ZlcnNpb25QYXJ0c1szXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZlcnNpb24gPSBpbXBsb2RlKCcuJywgJHNlbWFudGljVmVyc2lvblBhcnRzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gJHByZXR0eVZlcnNpb247CiAgICAgICAgfQoKICAgICAgICAvLyBhcHBlbmQgc3RhYmlsaXR5IGZsYWcgaWYgbm90IGRlZmF1bHQKICAgICAgICBpZiAoJHN0YWJpbGl0eSAhPSAnc3RhYmxlJykgewogICAgICAgICAgICAkdmVyc2lvbiAuPSAnQCcuJHN0YWJpbGl0eTsKICAgICAgICB9CgogICAgICAgIC8vIDIuMSAtPiBeMi4xCiAgICAgICAgcmV0dXJuICdeJyAuICR2ZXJzaW9uOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UGFyc2VyKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnBhcnNlciA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+cGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cGFyc2VyOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvbjsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFZjc1xIZ0RyaXZlcjsKdXNlIENvbXBvc2VyXElPXE51bGxJTzsKdXNlIENvbXBvc2VyXFNlbXZlclxWZXJzaW9uUGFyc2VyIGFzIFNlbXZlclZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxVdGlsXEdpdCBhcyBHaXRVdGlsOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxTdm4gYXMgU3ZuVXRpbDsKCi8qKgogKiBUcnkgdG8gZ3Vlc3MgdGhlIGN1cnJlbnQgdmVyc2lvbiBudW1iZXIgYmFzZWQgb24gZGlmZmVyZW50IFZDUyBjb25maWd1cmF0aW9uLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgU2FtdWVsIFJvemUgPHNhbXVlbC5yb3plQGdtYWlsLmNvbT4KICovCmNsYXNzIFZlcnNpb25HdWVzc2VyCnsKICAgIC8qKgogICAgICogQHZhciBDb25maWcKICAgICAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBQcm9jZXNzRXhlY3V0b3IKICAgICAqLwogICAgcHJpdmF0ZSAkcHJvY2VzczsKCiAgICAvKioKICAgICAqIEB2YXIgU2VtdmVyVmVyc2lvblBhcnNlcgogICAgICovCiAgICBwcml2YXRlICR2ZXJzaW9uUGFyc2VyOwoKICAgIC8qKgogICAgICogQHBhcmFtIENvbmZpZyAgICAgICAgICAgICAgJGNvbmZpZwogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAgICAgJHByb2Nlc3MKICAgICAqIEBwYXJhbSBTZW12ZXJWZXJzaW9uUGFyc2VyICR2ZXJzaW9uUGFyc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzLCBTZW12ZXJWZXJzaW9uUGFyc2VyICR2ZXJzaW9uUGFyc2VyKQogICAgewogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3M7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSAkdmVyc2lvblBhcnNlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAgJHBhY2thZ2VDb25maWcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggICAgICAgICAgUGF0aCB0byBndWVzcyBpbnRvCiAgICAgKgogICAgICogQHJldHVybiBudWxsfGFycmF5IHZlcnNpb25EYXRhLCAndmVyc2lvbicsICdwcmV0dHlfdmVyc2lvbicgYW5kICdjb21taXQnIGtleXMsIGlmIHRoZSB2ZXJzaW9uIGlzIGEgZmVhdHVyZSBicmFuY2gsICdmZWF0dXJlX3ZlcnNpb24nIGFuZCAnZmVhdHVyZV9wcmV0dHlfdmVyc2lvbicga2V5cyBtYXkgYWxzbyBiZSByZXR1cm5lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ3Vlc3NWZXJzaW9uKGFycmF5ICRwYWNrYWdlQ29uZmlnLCAkcGF0aCkKICAgIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvbkRhdGEgPSAkdGhpcy0+Z3Vlc3NHaXRWZXJzaW9uKCRwYWNrYWdlQ29uZmlnLCAkcGF0aCk7CiAgICAgICAgaWYgKG51bGwgIT09ICR2ZXJzaW9uRGF0YSAmJiBudWxsICE9PSAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnBvc3Rwcm9jZXNzKCR2ZXJzaW9uRGF0YSk7CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvbkRhdGEgPSAkdGhpcy0+Z3Vlc3NIZ1ZlcnNpb24oJHBhY2thZ2VDb25maWcsICRwYXRoKTsKICAgICAgICBpZiAobnVsbCAhPT0gJHZlcnNpb25EYXRhICYmIG51bGwgIT09ICR2ZXJzaW9uRGF0YVsndmVyc2lvbiddKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cG9zdHByb2Nlc3MoJHZlcnNpb25EYXRhKTsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uRGF0YSA9ICR0aGlzLT5ndWVzc0Zvc3NpbFZlcnNpb24oJHBhdGgpOwogICAgICAgIGlmIChudWxsICE9PSAkdmVyc2lvbkRhdGEgJiYgbnVsbCAhPT0gJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3N0cHJvY2VzcygkdmVyc2lvbkRhdGEpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25EYXRhID0gJHRoaXMtPmd1ZXNzU3ZuVmVyc2lvbigkcGFja2FnZUNvbmZpZywgJHBhdGgpOwogICAgICAgIGlmIChudWxsICE9PSAkdmVyc2lvbkRhdGEgJiYgbnVsbCAhPT0gJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3N0cHJvY2VzcygkdmVyc2lvbkRhdGEpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBwb3N0cHJvY2VzcyhhcnJheSAkdmVyc2lvbkRhdGEpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddKSAmJiAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfdmVyc2lvbiddID09PSAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSAmJiAkdmVyc2lvbkRhdGFbJ2ZlYXR1cmVfcHJldHR5X3ZlcnNpb24nXSA9PT0gJHZlcnNpb25EYXRhWydwcmV0dHlfdmVyc2lvbiddKSB7CiAgICAgICAgICAgIHVuc2V0KCR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10sICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV9wcmV0dHlfdmVyc2lvbiddKTsKICAgICAgICB9CgogICAgICAgIGlmICgnLWRldicgPT09IHN1YnN0cigkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSwgLTQpICYmIHByZWdfbWF0Y2goJ3tcLjl7N319JywgJHZlcnNpb25EYXRhWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICR2ZXJzaW9uRGF0YVsncHJldHR5X3ZlcnNpb24nXSA9IHByZWdfcmVwbGFjZSgneyhcLjl7N30pK30nLCAnLngnLCAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10pICYmICctZGV2JyA9PT0gc3Vic3RyKCR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10sIC00KSAmJiBwcmVnX21hdGNoKCd7XC45ezd9fScsICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV9wcmV0dHlfdmVyc2lvbiddID0gcHJlZ19yZXBsYWNlKCd7KFwuOXs3fSkrfScsICcueCcsICR2ZXJzaW9uRGF0YVsnZmVhdHVyZV92ZXJzaW9uJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2ZXJzaW9uRGF0YTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGd1ZXNzR2l0VmVyc2lvbihhcnJheSAkcGFja2FnZUNvbmZpZywgJHBhdGgpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICAkY29tbWl0ID0gbnVsbDsKICAgICAgICAkdmVyc2lvbiA9IG51bGw7CiAgICAgICAgJHByZXR0eVZlcnNpb24gPSBudWxsOwogICAgICAgICRmZWF0dXJlVmVyc2lvbiA9IG51bGw7CiAgICAgICAgJGZlYXR1cmVQcmV0dHlWZXJzaW9uID0gbnVsbDsKICAgICAgICAkaXNEZXRhY2hlZCA9IGZhbHNlOwoKICAgICAgICAvLyB0cnkgdG8gZmV0Y2ggY3VycmVudCB2ZXJzaW9uIGZyb20gZ2l0IGJyYW5jaAogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGJyYW5jaCAtYSAtLW5vLWNvbG9yIC0tbm8tYWJicmV2IC12JywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICRpc0ZlYXR1cmVCcmFuY2ggPSBmYWxzZTsKCiAgICAgICAgICAgIC8vIGZpbmQgY3VycmVudCBicmFuY2ggYW5kIGNvbGxlY3QgYWxsIGJyYW5jaCBuYW1lcwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJvY2Vzcy0+c3BsaXRMaW5lcygkb3V0cHV0KSBhcyAkYnJhbmNoKSB7CiAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaCAmJiBwcmVnX21hdGNoKCd7Xig/OlwqICkgKihcKG5vIGJyYW5jaFwpfFwoZGV0YWNoZWQgZnJvbSBcUytcKXxcKEhFQUQgZGV0YWNoZWQgYXQgXFMrXCl8XFMrKSAqKFthLWYwLTldKykgLiokfScsICRicmFuY2gsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaFsxXSA9PT0gJyhubyBicmFuY2gpJwogICAgICAgICAgICAgICAgICAgICAgICB8fCBzdHJwb3MoJG1hdGNoWzFdLCAnKGRldGFjaGVkICcpID09PSAwCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IHN0cnBvcygkbWF0Y2hbMV0sICcoSEVBRCBkZXRhY2hlZCBhdCcpID09PSAwCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJ2Rldi0nIC4gJG1hdGNoWzJdOwogICAgICAgICAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgICAgICAgICAkaXNGZWF0dXJlQnJhbmNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGlzRGV0YWNoZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZUJyYW5jaCgkbWF0Y2hbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICdkZXYtJyAuICRtYXRjaFsxXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGlzRmVhdHVyZUJyYW5jaCA9ICR0aGlzLT5pc0ZlYXR1cmVCcmFuY2goJHBhY2thZ2VDb25maWcsICRtYXRjaFsxXSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJG1hdGNoWzJdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb21taXQgPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoICYmICFwcmVnX21hdGNoKCd7XiAqLisvSEVBRCB9JywgJGJyYW5jaCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oPzpcKiApPyAqKCg/OnJlbW90ZXMvKD86b3JpZ2lufHVwc3RyZWFtKS8pP1teXHMvXSspICooW2EtZjAtOV0rKSAuKiR9JywgJGJyYW5jaCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbXSA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaXNGZWF0dXJlQnJhbmNoKSB7CiAgICAgICAgICAgICAgICAkZmVhdHVyZVZlcnNpb24gPSAkdmVyc2lvbjsKICAgICAgICAgICAgICAgICRmZWF0dXJlUHJldHR5VmVyc2lvbiA9ICRwcmV0dHlWZXJzaW9uOwoKICAgICAgICAgICAgICAgIC8vIHRyeSB0byBmaW5kIHRoZSBiZXN0IChuZWFyZXN0KSB2ZXJzaW9uIGJyYW5jaCB0byBhc3N1bWUgdGhpcyBmZWF0dXJlJ3MgdmVyc2lvbgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5ndWVzc0ZlYXR1cmVWZXJzaW9uKCRwYWNrYWdlQ29uZmlnLCAkdmVyc2lvbiwgJGJyYW5jaGVzLCAnZ2l0IHJldi1saXN0ICVjYW5kaWRhdGUlLi4lYnJhbmNoJScsICRwYXRoKTsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHJlc3VsdFsndmVyc2lvbiddOwogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSAkcmVzdWx0WydwcmV0dHlfdmVyc2lvbiddOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoISR2ZXJzaW9uIHx8ICRpc0RldGFjaGVkKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+dmVyc2lvbkZyb21HaXRUYWdzKCRwYXRoKTsKICAgICAgICAgICAgaWYgKCRyZXN1bHQpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHJlc3VsdFsndmVyc2lvbiddOwogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSAkcmVzdWx0WydwcmV0dHlfdmVyc2lvbiddOwogICAgICAgICAgICAgICAgJGZlYXR1cmVWZXJzaW9uID0gbnVsbDsKICAgICAgICAgICAgICAgICRmZWF0dXJlUHJldHR5VmVyc2lvbiA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGNvbW1pdCkgewogICAgICAgICAgICAkY29tbWFuZCA9ICdnaXQgbG9nIC0tcHJldHR5PSIlSCIgLW4xIEhFQUQnLkdpdFV0aWw6OmdldE5vU2hvd1NpZ25hdHVyZUZsYWcoJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgJGNvbW1pdCA9IHRyaW0oJG91dHB1dCkgPzogbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRmZWF0dXJlVmVyc2lvbikgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAnY29tbWl0JyA9PiAkY29tbWl0LCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uLCAnZmVhdHVyZV92ZXJzaW9uJyA9PiAkZmVhdHVyZVZlcnNpb24sICdmZWF0dXJlX3ByZXR0eV92ZXJzaW9uJyA9PiAkZmVhdHVyZVByZXR0eVZlcnNpb24pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gJGNvbW1pdCwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkcHJldHR5VmVyc2lvbik7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiB2ZXJzaW9uRnJvbUdpdFRhZ3MoJHBhdGgpCiAgICB7CiAgICAgICAgLy8gdHJ5IHRvIGZldGNoIGN1cnJlbnQgdmVyc2lvbiBmcm9tIGdpdCB0YWdzCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgZGVzY3JpYmUgLS1leGFjdC1tYXRjaCAtLXRhZ3MnLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSh0cmltKCRvdXRwdXQpKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAncHJldHR5X3ZlcnNpb24nID0+IHRyaW0oJG91dHB1dCkpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NIZ1ZlcnNpb24oYXJyYXkgJHBhY2thZ2VDb25maWcsICRwYXRoKQogICAgewogICAgICAgIC8vIHRyeSB0byBmZXRjaCBjdXJyZW50IHZlcnNpb24gZnJvbSBoZyBicmFuY2gKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIGJyYW5jaCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAkYnJhbmNoID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRicmFuY2gpOwogICAgICAgICAgICAkaXNGZWF0dXJlQnJhbmNoID0gMCA9PT0gc3RycG9zKCR2ZXJzaW9uLCAnZGV2LScpOwoKICAgICAgICAgICAgaWYgKFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTID09PSAkdmVyc2lvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gbnVsbCwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnZGV2LScuJGJyYW5jaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGlzRmVhdHVyZUJyYW5jaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gbnVsbCwgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkdmVyc2lvbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlLXVzZSB0aGUgSGdEcml2ZXIgdG8gZmV0Y2ggYnJhbmNoZXMgKHRoaXMgcHJvcGVybHkgaW5jbHVkZXMgYm9va21hcmtzKQogICAgICAgICAgICAkaW8gPSBuZXcgTnVsbElPKCk7CiAgICAgICAgICAgICRkcml2ZXIgPSBuZXcgSGdEcml2ZXIoYXJyYXkoJ3VybCcgPT4gJHBhdGgpLCAkaW8sICR0aGlzLT5jb25maWcsIG5ldyBIdHRwRG93bmxvYWRlcigkaW8sICR0aGlzLT5jb25maWcpLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgICAgICRicmFuY2hlcyA9IGFycmF5X2tleXMoJGRyaXZlci0+Z2V0QnJhbmNoZXMoKSk7CgogICAgICAgICAgICAvLyB0cnkgdG8gZmluZCB0aGUgYmVzdCAobmVhcmVzdCkgdmVyc2lvbiBicmFuY2ggdG8gYXNzdW1lIHRoaXMgZmVhdHVyZSdzIHZlcnNpb24KICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5ndWVzc0ZlYXR1cmVWZXJzaW9uKCRwYWNrYWdlQ29uZmlnLCAkdmVyc2lvbiwgJGJyYW5jaGVzLCAnaGcgbG9nIC1yICJub3QgYW5jZXN0b3JzKFwnJWNhbmRpZGF0ZSVcJykgYW5kIGFuY2VzdG9ycyhcJyVicmFuY2glXCcpIiAtLXRlbXBsYXRlICJ7bm9kZX1cXG4iJywgJHBhdGgpOwogICAgICAgICAgICAkcmVzdWx0Wydjb21taXQnXSA9ICcnOwogICAgICAgICAgICAkcmVzdWx0WydmZWF0dXJlX3ZlcnNpb24nXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAkcmVzdWx0WydmZWF0dXJlX3ByZXR0eV92ZXJzaW9uJ10gPSAkdmVyc2lvbjsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGd1ZXNzRmVhdHVyZVZlcnNpb24oYXJyYXkgJHBhY2thZ2VDb25maWcsICR2ZXJzaW9uLCBhcnJheSAkYnJhbmNoZXMsICRzY21DbWRsaW5lLCAkcGF0aCkKICAgIHsKICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICR2ZXJzaW9uOwoKICAgICAgICAvLyBpZ25vcmUgZmVhdHVyZSBicmFuY2hlcyBpZiB0aGV5IGhhdmUgbm8gYnJhbmNoLWFsaWFzIG9yIHNlbGYudmVyc2lvbiBpcyB1c2VkCiAgICAgICAgLy8gYW5kIGZpbmQgdGhlIGJyYW5jaCB0aGV5IGNhbWUgZnJvbSB0byB1c2UgYXMgYSB2ZXJzaW9uIGluc3RlYWQKICAgICAgICBpZiAoIWlzc2V0KCRwYWNrYWdlQ29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXVskdmVyc2lvbl0pCiAgICAgICAgICAgIHx8IHN0cnBvcyhqc29uX2VuY29kZSgkcGFja2FnZUNvbmZpZyksICcic2VsZi52ZXJzaW9uIicpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRicmFuY2ggPSBwcmVnX3JlcGxhY2UoJ3teZGV2LX0nLCAnJywgJHZlcnNpb24pOwogICAgICAgICAgICAkbGVuZ3RoID0gUEhQX0lOVF9NQVg7CgogICAgICAgICAgICAvLyByZXR1cm4gZGlyZWN0bHksIGlmIGJyYW5jaCBpcyBjb25maWd1cmVkIHRvIGJlIG5vbi1mZWF0dXJlIGJyYW5jaAogICAgICAgICAgICBpZiAoISR0aGlzLT5pc0ZlYXR1cmVCcmFuY2goJHBhY2thZ2VDb25maWcsICRicmFuY2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc29ydCBsb2NhbCBicmFuY2hlcyBmaXJzdCB0aGVuIHJlbW90ZSBvbmVzCiAgICAgICAgICAgIC8vIGFuZCBzb3J0IG51bWVyaWMgYnJhbmNoZXMgYmVsb3cgbmFtZWQgb25lcywgdG8gbWFrZSBzdXJlIGlmIHRoZSBicmFuY2ggaGFzIHRoZSBzYW1lIGRpc3RhbmNlIGZyb20gbWFpbiBhbmQgMS4xMCBhbmQgMS45IGZvciBleGFtcGxlLCBtYWluIGlzIHBpY2tlZAogICAgICAgICAgICAvLyBhbmQgc29ydCB1c2luZyBuYXR1cmFsIHNvcnQgc28gdGhhdCAxLjEwIHdpbGwgYXBwZWFyIGJlZm9yZSAxLjkKICAgICAgICAgICAgdXNvcnQoJGJyYW5jaGVzLCBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICAgICAkYVJlbW90ZSA9IDAgPT09IHN0cnBvcygkYSwgJ3JlbW90ZXMvJyk7CiAgICAgICAgICAgICAgICAkYlJlbW90ZSA9IDAgPT09IHN0cnBvcygkYiwgJ3JlbW90ZXMvJyk7CgogICAgICAgICAgICAgICAgaWYgKCRhUmVtb3RlICE9PSAkYlJlbW90ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkYVJlbW90ZSA/IDEgOiAtMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gc3RybmF0Y2FzZWNtcCgkYiwgJGEpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRicmFuY2hlcyBhcyAkY2FuZGlkYXRlKSB7CiAgICAgICAgICAgICAgICAkY2FuZGlkYXRlVmVyc2lvbiA9IHByZWdfcmVwbGFjZSgne15yZW1vdGVzL1xTKy99JywgJycsICRjYW5kaWRhdGUpOwoKICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBjb21wYXJlIGFnYWluc3QgaXRzZWxmIG9yIG90aGVyIGZlYXR1cmUgYnJhbmNoZXMKICAgICAgICAgICAgICAgIGlmICgkY2FuZGlkYXRlID09PSAkYnJhbmNoIHx8ICR0aGlzLT5pc0ZlYXR1cmVCcmFuY2goJHBhY2thZ2VDb25maWcsICRjYW5kaWRhdGVWZXJzaW9uKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjbWRMaW5lID0gc3RyX3JlcGxhY2UoYXJyYXkoJyVjYW5kaWRhdGUlJywgJyVicmFuY2glJyksIGFycmF5KCRjYW5kaWRhdGUsICRicmFuY2gpLCAkc2NtQ21kbGluZSk7CiAgICAgICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNtZExpbmUsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJG91dHB1dCkgPCAkbGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgJGxlbmd0aCA9IHN0cmxlbigkb3V0cHV0KTsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemVCcmFuY2goJGNhbmRpZGF0ZVZlcnNpb24pOwogICAgICAgICAgICAgICAgICAgICRwcmV0dHlWZXJzaW9uID0gJ2Rldi0nIC4gJGNhbmRpZGF0ZVZlcnNpb247CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzRmVhdHVyZUJyYW5jaChhcnJheSAkcGFja2FnZUNvbmZpZywgJGJyYW5jaE5hbWUpCiAgICB7CiAgICAgICAgJG5vbkZlYXR1cmVCcmFuY2hlcyA9ICcnOwogICAgICAgIGlmICghZW1wdHkoJHBhY2thZ2VDb25maWdbJ25vbi1mZWF0dXJlLWJyYW5jaGVzJ10pKSB7CiAgICAgICAgICAgICRub25GZWF0dXJlQnJhbmNoZXMgPSBpbXBsb2RlKCd8JywgJHBhY2thZ2VDb25maWdbJ25vbi1mZWF0dXJlLWJyYW5jaGVzJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICFwcmVnX21hdGNoKCd7XignIC4gJG5vbkZlYXR1cmVCcmFuY2hlcyAuICd8bWFzdGVyfG1haW58bGF0ZXN0fG5leHR8Y3VycmVudHxzdXBwb3J0fHRpcHx0cnVua3xkZWZhdWx0fGRldmVsb3B8XGQrXC4uKykkfScsICRicmFuY2hOYW1lLCAkbWF0Y2gpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NGb3NzaWxWZXJzaW9uKCRwYXRoKQogICAgewogICAgICAgICR2ZXJzaW9uID0gbnVsbDsKICAgICAgICAkcHJldHR5VmVyc2lvbiA9IG51bGw7CgogICAgICAgIC8vIHRyeSB0byBmZXRjaCBjdXJyZW50IHZlcnNpb24gZnJvbSBmb3NzaWwKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCBicmFuY2ggbGlzdCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAkYnJhbmNoID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRicmFuY2gpOwogICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICdkZXYtJyAuICRicmFuY2g7CiAgICAgICAgfQoKICAgICAgICAvLyB0cnkgdG8gZmV0Y2ggY3VycmVudCB2ZXJzaW9uIGZyb20gZm9zc2lsIHRhZ3MKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2Zvc3NpbCB0YWcgbGlzdCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKHRyaW0oJG91dHB1dCkpOwogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSB0cmltKCRvdXRwdXQpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgndmVyc2lvbicgPT4gJHZlcnNpb24sICdjb21taXQnID0+ICcnLCAncHJldHR5X3ZlcnNpb24nID0+ICRwcmV0dHlWZXJzaW9uKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGd1ZXNzU3ZuVmVyc2lvbihhcnJheSAkcGFja2FnZUNvbmZpZywgJHBhdGgpCiAgICB7CiAgICAgICAgU3ZuVXRpbDo6Y2xlYW5FbnYoKTsKCiAgICAgICAgLy8gdHJ5IHRvIGZldGNoIGN1cnJlbnQgdmVyc2lvbiBmcm9tIHN2bgogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnc3ZuIGluZm8gLS14bWwnLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgJHRydW5rUGF0aCA9IGlzc2V0KCRwYWNrYWdlQ29uZmlnWyd0cnVuay1wYXRoJ10pID8gcHJlZ19xdW90ZSgkcGFja2FnZUNvbmZpZ1sndHJ1bmstcGF0aCddLCAnIycpIDogJ3RydW5rJzsKICAgICAgICAgICAgJGJyYW5jaGVzUGF0aCA9IGlzc2V0KCRwYWNrYWdlQ29uZmlnWydicmFuY2hlcy1wYXRoJ10pID8gcHJlZ19xdW90ZSgkcGFja2FnZUNvbmZpZ1snYnJhbmNoZXMtcGF0aCddLCAnIycpIDogJ2JyYW5jaGVzJzsKICAgICAgICAgICAgJHRhZ3NQYXRoID0gaXNzZXQoJHBhY2thZ2VDb25maWdbJ3RhZ3MtcGF0aCddKSA/IHByZWdfcXVvdGUoJHBhY2thZ2VDb25maWdbJ3RhZ3MtcGF0aCddLCAnIycpIDogJ3RhZ3MnOwoKICAgICAgICAgICAgJHVybFBhdHRlcm4gPSAnIzx1cmw+LiovKCcgLiAkdHJ1bmtQYXRoIC4gJ3woJyAuICRicmFuY2hlc1BhdGggLiAnfCcgLiAkdGFnc1BhdGggLiAnKS8oLiopKTwvdXJsPiMnOwoKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHVybFBhdHRlcm4sICRvdXRwdXQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWzJdKSAmJiAoJGJyYW5jaGVzUGF0aCA9PT0gJG1hdGNoZXNbMl0gfHwgJHRhZ3NQYXRoID09PSAkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gYSBicmFuY2hlcyBwYXRoCiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKCRtYXRjaGVzWzNdKTsKICAgICAgICAgICAgICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICdkZXYtJyAuICRtYXRjaGVzWzNdOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3ZlcnNpb24nID0+ICR2ZXJzaW9uLCAnY29tbWl0JyA9PiAnJywgJ3ByZXR0eV92ZXJzaW9uJyA9PiAkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHByZXR0eVZlcnNpb24gPSB0cmltKCRtYXRjaGVzWzFdKTsKICAgICAgICAgICAgICAgIGlmICgkcHJldHR5VmVyc2lvbiA9PT0gJ3RydW5rJykgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJ2Rldi10cnVuayc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkcHJldHR5VmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwgJ2NvbW1pdCcgPT4gJycsICdwcmV0dHlfdmVyc2lvbicgPT4gJHByZXR0eVZlcnNpb24pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvbjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFN0YWJpbGl0eUZpbHRlcgp7CiAgICAvKioKICAgICAqIENoZWNrcyBpZiBhbnkgb2YgdGhlIHByb3ZpZGVkIHBhY2thZ2UgbmFtZXMgaW4gdGhlIGdpdmVuIHN0YWJpbGl0eSBtYXRjaCB0aGUgY29uZmlndXJlZCBhY2NlcHRhYmxlIHN0YWJpbGl0eSBhbmQgZmxhZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gaW50W10gJGFjY2VwdGFibGVTdGFiaWxpdGllcyBhcnJheSBvZiBzdGFiaWxpdHkgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qIHZhbHVlCiAgICAgKiBAcHNhbG0tcGFyYW0gYXJyYXk8c3RyaW5nLCBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyo+ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMKICAgICAqIEBwYXJhbSBpbnRbXSAkc3RhYmlsaXR5RmxhZ3MgYW4gYXJyYXkgb2YgcGFja2FnZSBuYW1lID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkc3RhYmlsaXR5RmxhZ3MKICAgICAqIEBwYXJhbSAgc3RyaW5nW10gJG5hbWVzICAgICBUaGUgcGFja2FnZSBuYW1lKHMpIHRvIGNoZWNrIGZvciBzdGFiaWxpdHkgZmxhZ3MKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHN0YWJpbGl0eSBvbmUgb2YgJ3N0YWJsZScsICdSQycsICdiZXRhJywgJ2FscGhhJyBvciAnZGV2JwogICAgICogQHJldHVybiBib29sICAgICB0cnVlIGlmIGFueSBwYWNrYWdlIG5hbWUgaXMgYWNjZXB0YWJsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzUGFja2FnZUFjY2VwdGFibGUoYXJyYXkgJGFjY2VwdGFibGVTdGFiaWxpdGllcywgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCAkbmFtZXMsICRzdGFiaWxpdHkpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJG5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgIC8vIGFsbG93IGlmIHBhY2thZ2UgbWF0Y2hlcyB0aGUgcGFja2FnZS1zcGVjaWZpYyBzdGFiaWxpdHkgZmxhZwogICAgICAgICAgICBpZiAoaXNzZXQoJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIGlmIChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzWyRzdGFiaWxpdHldIDw9ICRzdGFiaWxpdHlGbGFnc1skbmFtZV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRhY2NlcHRhYmxlU3RhYmlsaXRpZXNbJHN0YWJpbGl0eV0pKSB7CiAgICAgICAgICAgICAgICAvLyBhbGxvdyBpZiBwYWNrYWdlIG1hdGNoZXMgdGhlIGdsb2JhbCBzdGFiaWxpdHkgcmVxdWlyZW1lbnQgYW5kIGhhcyBubyBleGNlcHRpb24KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCi8qKgogKiBEZWZpbmVzIGFkZGl0aW9uYWwgZmllbGRzIHRoYXQgYXJlIG9ubHkgbmVlZGVkIGZvciB0aGUgcm9vdCBwYWNrYWdlCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBSb290UGFja2FnZUludGVyZmFjZSBleHRlbmRzIENvbXBsZXRlUGFja2FnZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgcGFja2FnZSBuYW1lcyBhbmQgdGhlaXIgYWxpYXNlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsaWFzZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gc3RhYmlsaXR5IG9mIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YWJpbGl0eSBmbGFncyB0byBhcHBseSB0byBkZXBlbmRlbmNpZXMKICAgICAqCiAgICAgKiBhcnJheSgnZm9vL2JhcicgPT4gJ2RldicpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5RmxhZ3MoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgcGFja2FnZSBuYW1lcyBhbmQgc291cmNlIHJlZmVyZW5jZXMgdGhhdCBtdXN0IGJlIGVuZm9yY2VkIG9uIHRoZW0KICAgICAqCiAgICAgKiBhcnJheSgnZm9vL2JhcicgPT4gJ2FiY2QxMjM0JykKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWZlcmVuY2VzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJvb3QgcGFja2FnZSBwcmVmZXJzIHBpY2tpbmcgc3RhYmxlIHBhY2thZ2VzIG92ZXIgdW5zdGFibGUgb25lcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZmVyU3RhYmxlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByb290IHBhY2thZ2UncyBjb25maWd1cmF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlcXVpcmVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIExpbmtbXSAkcmVxdWlyZXMgQSBzZXQgb2YgcGFja2FnZSBsaW5rcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVxdWlyZXMoYXJyYXkgJHJlcXVpcmVzKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVjb21tZW5kZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRkZXZSZXF1aXJlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZSZXF1aXJlcyhhcnJheSAkZGV2UmVxdWlyZXMpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBjb25mbGljdGluZyBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSBMaW5rW10gJGNvbmZsaWN0cyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25mbGljdHMoYXJyYXkgJGNvbmZsaWN0cyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHByb3ZpZGVkIHZpcnR1YWwgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRwcm92aWRlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm92aWRlcyhhcnJheSAkcHJvdmlkZXMpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBwYWNrYWdlcyB0aGlzIG9uZSByZXBsYWNlcwogICAgICoKICAgICAqIEBwYXJhbSBMaW5rW10gJHJlcGxhY2VzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcGxhY2VzKGFycmF5ICRyZXBsYWNlcyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlcG9zaXRvcmllcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkcmVwb3NpdG9yaWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXBvc2l0b3JpZXMoJHJlcG9zaXRvcmllcyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGF1dG9sb2FkIG1hcHBpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGF1dG9sb2FkIE1hcHBpbmcgb2YgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dG9sb2FkKGFycmF5ICRhdXRvbG9hZCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRldiBhdXRvbG9hZCBtYXBwaW5nCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRkZXZBdXRvbG9hZCBNYXBwaW5nIG9mIGRldiBhdXRvbG9hZGluZyBydWxlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2QXV0b2xvYWQoYXJyYXkgJGRldkF1dG9sb2FkKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgc3RhYmlsaXR5RmxhZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHN0YWJpbGl0eUZsYWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGFiaWxpdHlGbGFncyhhcnJheSAkc3RhYmlsaXR5RmxhZ3MpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBzdWdnZXN0ZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHN1Z2dlc3RzIEEgc2V0IG9mIHBhY2thZ2UgbmFtZXMvY29tbWVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN1Z2dlc3RzKGFycmF5ICRzdWdnZXN0cyk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGV4dHJhCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHRyYShhcnJheSAkZXh0cmEpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogQmFzZSBjbGFzcyBmb3IgcGFja2FnZXMgcHJvdmlkaW5nIG5hbWUgc3RvcmFnZSBhbmQgZGVmYXVsdCBtYXRjaCBpbXBsZW1lbnRhdGlvbgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KYWJzdHJhY3QgY2xhc3MgQmFzZVBhY2thZ2UgaW1wbGVtZW50cyBQYWNrYWdlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHN0cmluZywgYXJyYXl7ZGVzY3JpcHRpb246IHN0cmluZywgbWV0aG9kOiBMaW5rOjpUWVBFXyp9PgogICAgICovCiAgICBwdWJsaWMgc3RhdGljICRzdXBwb3J0ZWRMaW5rVHlwZXMgPSBhcnJheSgKICAgICAgICAncmVxdWlyZScgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVxdWlyZXMnLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX1JFUVVJUkUpLAogICAgICAgICdjb25mbGljdCcgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAnY29uZmxpY3RzJywgJ21ldGhvZCcgPT4gTGluazo6VFlQRV9DT05GTElDVCksCiAgICAgICAgJ3Byb3ZpZGUnID0+IGFycmF5KCdkZXNjcmlwdGlvbicgPT4gJ3Byb3ZpZGVzJywgJ21ldGhvZCcgPT4gTGluazo6VFlQRV9QUk9WSURFKSwKICAgICAgICAncmVwbGFjZScgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVwbGFjZXMnLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX1JFUExBQ0UpLAogICAgICAgICdyZXF1aXJlLWRldicgPT4gYXJyYXkoJ2Rlc2NyaXB0aW9uJyA9PiAncmVxdWlyZXMgKGZvciBkZXZlbG9wbWVudCknLCAnbWV0aG9kJyA9PiBMaW5rOjpUWVBFX0RFVl9SRVFVSVJFKSwKICAgICk7CgogICAgY29uc3QgU1RBQklMSVRZX1NUQUJMRSA9IDA7CiAgICBjb25zdCBTVEFCSUxJVFlfUkMgPSA1OwogICAgY29uc3QgU1RBQklMSVRZX0JFVEEgPSAxMDsKICAgIGNvbnN0IFNUQUJJTElUWV9BTFBIQSA9IDE1OwogICAgY29uc3QgU1RBQklMSVRZX0RFViA9IDIwOwoKICAgIHB1YmxpYyBzdGF0aWMgJHN0YWJpbGl0aWVzID0gYXJyYXkoCiAgICAgICAgJ3N0YWJsZScgPT4gc2VsZjo6U1RBQklMSVRZX1NUQUJMRSwKICAgICAgICAnUkMnID0+IHNlbGY6OlNUQUJJTElUWV9SQywKICAgICAgICAnYmV0YScgPT4gc2VsZjo6U1RBQklMSVRZX0JFVEEsCiAgICAgICAgJ2FscGhhJyA9PiBzZWxmOjpTVEFCSUxJVFlfQUxQSEEsCiAgICAgICAgJ2RldicgPT4gc2VsZjo6U1RBQklMSVRZX0RFViwKICAgICk7CgogICAgLyoqCiAgICAgKiBSRUFELU9OTFk6IFRoZSBwYWNrYWdlIGlkLCBwdWJsaWMgZm9yIGZhc3QgYWNjZXNzIGluIGRlcGVuZGVuY3kgc29sdmVyCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwdWJsaWMgJGlkOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByb3RlY3RlZCAkcHJldHR5TmFtZTsKICAgIC8qKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkcmVwb3NpdG9yeTsKICAgIC8qKiBAdmFyIGFycmF5ICovCiAgICBwcm90ZWN0ZWQgJHRyYW5zcG9ydE9wdGlvbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQWxsIGRlc2NlbmRhbnRzJyBjb25zdHJ1Y3RvcnMgc2hvdWxkIGNhbGwgdGhpcyBwYXJlbnQgY29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBwYWNrYWdlJ3MgbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eU5hbWUgPSAkbmFtZTsKICAgICAgICAkdGhpcy0+bmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwogICAgICAgICR0aGlzLT5pZCA9IC0xOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcmV0dHlOYW1lOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoJHByb3ZpZGVzID0gdHJ1ZSkKICAgIHsKICAgICAgICAkbmFtZXMgPSBhcnJheSgKICAgICAgICAgICAgJHRoaXMtPmdldE5hbWUoKSA9PiB0cnVlLAogICAgICAgICk7CgogICAgICAgIGlmICgkcHJvdmlkZXMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFByb3ZpZGVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRuYW1lc1skbGluay0+Z2V0VGFyZ2V0KCldID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFJlcGxhY2VzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgJG5hbWVzWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJG5hbWVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcG9zaXRvcnkoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3NpdG9yeSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnJlcG9zaXRvcnkgJiYgJHJlcG9zaXRvcnkgIT09ICR0aGlzLT5yZXBvc2l0b3J5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0EgcGFja2FnZSBjYW4gb25seSBiZSBhZGRlZCB0byBvbmUgcmVwb3NpdG9yeScpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeSA9ICRyZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHJhbnNwb3J0T3B0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50cmFuc3BvcnRPcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogQ29uZmlndXJlcyB0aGUgbGlzdCBvZiBvcHRpb25zIHRvIGRvd25sb2FkIHBhY2thZ2UgZGlzdCBmaWxlcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhbnNwb3J0T3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+dHJhbnNwb3J0T3B0aW9ucyA9ICRvcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogY2hlY2tzIGlmIHRoaXMgcGFja2FnZSBpcyBhIHBsYXRmb3JtIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUGxhdGZvcm0oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgUGxhdGZvcm1SZXBvc2l0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIHVuaXF1ZSBuYW1lLCBjb25zdHJ1Y3RlZCBmcm9tIG5hbWUsIHZlcnNpb24gYW5kIHJlbGVhc2UgdHlwZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VW5pcXVlTmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXROYW1lKCkuJy0nLiR0aGlzLT5nZXRWZXJzaW9uKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGVxdWFscyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRzZWxmID0gJHRoaXM7CiAgICAgICAgaWYgKCR0aGlzIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRzZWxmID0gJHRoaXMtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZSA9PT0gJHNlbGY7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyB0aGUgcGFja2FnZSBpbnRvIGEgcmVhZGFibGUgYW5kIHVuaXF1ZSBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRVbmlxdWVOYW1lKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRQcmV0dHlOYW1lKCkuJyAnLiR0aGlzLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdWxsUHJldHR5VmVyc2lvbigkdHJ1bmNhdGUgPSB0cnVlLCAkZGlzcGxheU1vZGUgPSBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUZfSUZfREVWKQogICAgewogICAgICAgIGlmICgkZGlzcGxheU1vZGUgPT09IFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfU09VUkNFX1JFRl9JRl9ERVYgJiYKICAgICAgICAgICAgKCEkdGhpcy0+aXNEZXYoKSB8fCAhXGluX2FycmF5KCR0aGlzLT5nZXRTb3VyY2VUeXBlKCksIGFycmF5KCdoZycsICdnaXQnKSkpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoICgkZGlzcGxheU1vZGUpIHsKICAgICAgICAgICAgY2FzZSBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUZfSUZfREVWOgogICAgICAgICAgICBjYXNlIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfU09VUkNFX1JFRjoKICAgICAgICAgICAgICAgICRyZWZlcmVuY2UgPSAkdGhpcy0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX0RJU1RfUkVGOgogICAgICAgICAgICAgICAgJHJlZmVyZW5jZSA9ICR0aGlzLT5nZXREaXN0UmVmZXJlbmNlKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdEaXNwbGF5IG1vZGUgJy4kZGlzcGxheU1vZGUuJyBpcyBub3Qgc3VwcG9ydGVkJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBzb3VyY2UgcmVmZXJlbmNlIGlzIGEgc2hhMSBoYXNoIC0tIHRydW5jYXRlCiAgICAgICAgaWYgKCR0cnVuY2F0ZSAmJiBcc3RybGVuKCRyZWZlcmVuY2UpID09PSA0MCAmJiAkdGhpcy0+Z2V0U291cmNlVHlwZSgpICE9PSAnc3ZuJykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZXR0eVZlcnNpb24oKSAuICcgJyAuIHN1YnN0cigkcmVmZXJlbmNlLCAwLCA3KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UHJldHR5VmVyc2lvbigpIC4gJyAnIC4gJHJlZmVyZW5jZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhYmlsaXR5UHJpb3JpdHkoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjokc3RhYmlsaXRpZXNbJHRoaXMtPmdldFN0YWJpbGl0eSgpXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jbG9uZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnkgPSBudWxsOwogICAgICAgICR0aGlzLT5pZCA9IC0xOwogICAgfQoKICAgIC8qKgogICAgICogQnVpbGQgYSByZWdleHAgZnJvbSBhIHBhY2thZ2UgbmFtZSwgZXhwYW5kaW5nICogZ2xvYnMgYXMgcmVxdWlyZWQKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkYWxsb3dQYXR0ZXJuCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkd3JhcCAgICAgICAgIFdyYXAgdGhlIGNsZWFuZWQgc3RyaW5nIGJ5IHRoZSBnaXZlbiBzdHJpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFja2FnZU5hbWVUb1JlZ2V4cCgkYWxsb3dQYXR0ZXJuLCAkd3JhcCA9ICd7XiVzJH1pJykKICAgIHsKICAgICAgICAkY2xlYW5lZEFsbG93UGF0dGVybiA9IHN0cl9yZXBsYWNlKCdcXConLCAnLionLCBwcmVnX3F1b3RlKCRhbGxvd1BhdHRlcm4pKTsKCiAgICAgICAgcmV0dXJuIHNwcmludGYoJHdyYXAsICRjbGVhbmVkQWxsb3dQYXR0ZXJuKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CgovKioKICogQGF1dGhvciBNYXR0aGlldSBNb3F1ZXQgPG1hdHRoaWV1QG1vcXVldC5uZXQ+CiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKi8KY2xhc3MgQXJjaGl2ZU1hbmFnZXIKewogICAgLyoqIEB2YXIgRG93bmxvYWRNYW5hZ2VyICovCiAgICBwcm90ZWN0ZWQgJGRvd25sb2FkTWFuYWdlcjsKICAgIC8qKiBAdmFyIExvb3AgKi8KICAgIHByb3RlY3RlZCAkbG9vcDsKCiAgICAvKioKICAgICAqIEB2YXIgQXJjaGl2ZXJJbnRlcmZhY2VbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyY2hpdmVycyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRvdmVyd3JpdGVGaWxlcyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gRG93bmxvYWRNYW5hZ2VyICRkb3dubG9hZE1hbmFnZXIgQSBtYW5hZ2VyIHVzZWQgdG8gZG93bmxvYWQgcGFja2FnZSBzb3VyY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChEb3dubG9hZE1hbmFnZXIgJGRvd25sb2FkTWFuYWdlciwgTG9vcCAkbG9vcCkKICAgIHsKICAgICAgICAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyID0gJGRvd25sb2FkTWFuYWdlcjsKICAgICAgICAkdGhpcy0+bG9vcCA9ICRsb29wOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIEFyY2hpdmVySW50ZXJmYWNlICRhcmNoaXZlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQXJjaGl2ZXIoQXJjaGl2ZXJJbnRlcmZhY2UgJGFyY2hpdmVyKQogICAgewogICAgICAgICR0aGlzLT5hcmNoaXZlcnNbXSA9ICRhcmNoaXZlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB3aGV0aGVyIGV4aXN0aW5nIGFyY2hpdmVzIHNob3VsZCBiZSBvdmVyd3JpdHRlbgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRvdmVyd3JpdGVGaWxlcyBOZXcgc2V0dGluZwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE92ZXJ3cml0ZUZpbGVzKCRvdmVyd3JpdGVGaWxlcykKICAgIHsKICAgICAgICAkdGhpcy0+b3ZlcndyaXRlRmlsZXMgPSAkb3ZlcndyaXRlRmlsZXM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdlbmVyYXRlIGEgZGlzdGluY3QgZmlsZW5hbWUgZm9yIGEgcGFydGljdWxhciB2ZXJzaW9uIG9mIGEgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBUaGUgcGFja2FnZSB0byBnZXQgYSBuYW1lIGZvcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEEgZmlsZW5hbWUgd2l0aG91dCBhbiBleHRlbnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2VGaWxlbmFtZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXJjaGl2ZU5hbWUoKSkgewogICAgICAgICAgICAkYmFzZU5hbWUgPSAkcGFja2FnZS0+Z2V0QXJjaGl2ZU5hbWUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYmFzZU5hbWUgPSBwcmVnX3JlcGxhY2UoJyNbXmEtejAtOS1fXSNpJywgJy0nLCAkcGFja2FnZS0+Z2V0TmFtZSgpKTsKICAgICAgICB9CiAgICAgICAgJG5hbWVQYXJ0cyA9IGFycmF5KCRiYXNlTmFtZSk7CgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XlthLWYwLTldezQwfSR9JywgJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkpIHsKICAgICAgICAgICAgYXJyYXlfcHVzaCgkbmFtZVBhcnRzLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpLCAkcGFja2FnZS0+Z2V0RGlzdFR5cGUoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYXJyYXlfcHVzaCgkbmFtZVBhcnRzLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgJG5hbWVQYXJ0c1tdID0gc3Vic3RyKHNoYTEoJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSwgMCwgNik7CiAgICAgICAgfQoKICAgICAgICAkbmFtZSA9IGltcGxvZGUoJy0nLCBhcnJheV9maWx0ZXIoJG5hbWVQYXJ0cywgZnVuY3Rpb24gKCRwKSB7CiAgICAgICAgICAgIHJldHVybiAhZW1wdHkoJHApOwogICAgICAgIH0pKTsKCiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKCcvJywgJy0nLCAkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gYXJjaGl2ZSBvZiB0aGUgc3BlY2lmaWVkIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICRwYWNrYWdlICAgICAgIFRoZSBwYWNrYWdlIHRvIGFyY2hpdmUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkZm9ybWF0ICAgICAgICBUaGUgZm9ybWF0IG9mIHRoZSBhcmNoaXZlICh6aXAsIHRhciwgLi4uKQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0YXJnZXREaXIgICAgIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gYnVpbGQgdGhlIGFyY2hpdmUKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgICAgICAgICAgICAgICAkZmlsZU5hbWUgICAgICBUaGUgcmVsYXRpdmUgZmlsZSBuYW1lIHRvIHVzZSBmb3IgdGhlIGFyY2hpdmUsIG9yIG51bGwgdG8gZ2VuZXJhdGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgcGFja2FnZSBuYW1lLiBOb3RlIHRoYXQgdGhlIGZvcm1hdCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoaXMgbmFtZQogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICRpZ25vcmVGaWx0ZXJzIElnbm9yZSBmaWx0ZXJzIHdoZW4gbG9va2luZyBmb3IgZmlsZXMgaW4gdGhlIHBhY2thZ2UKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgICAgICAgICAgIFRoZSBwYXRoIG9mIHRoZSBjcmVhdGVkIGFyY2hpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZvcm1hdCwgJHRhcmdldERpciwgJGZpbGVOYW1lID0gbnVsbCwgJGlnbm9yZUZpbHRlcnMgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJGZvcm1hdCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0Zvcm1hdCBtdXN0IGJlIHNwZWNpZmllZCcpOwogICAgICAgIH0KCiAgICAgICAgLy8gU2VhcmNoIGZvciB0aGUgbW9zdCBhcHByb3ByaWF0ZSBhcmNoaXZlcgogICAgICAgICR1c2FibGVBcmNoaXZlciA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFyY2hpdmVycyBhcyAkYXJjaGl2ZXIpIHsKICAgICAgICAgICAgaWYgKCRhcmNoaXZlci0+c3VwcG9ydHMoJGZvcm1hdCwgJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKSkpIHsKICAgICAgICAgICAgICAgICR1c2FibGVBcmNoaXZlciA9ICRhcmNoaXZlcjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVja3MgdGhlIGZvcm1hdC9zb3VyY2UgdHlwZSBhcmUgc3VwcG9ydGVkIGJlZm9yZSBkb3dubG9hZGluZyB0aGUgcGFja2FnZQogICAgICAgIGlmIChudWxsID09PSAkdXNhYmxlQXJjaGl2ZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ05vIGFyY2hpdmVyIGZvdW5kIHRvIHN1cHBvcnQgJXMgZm9ybWF0JywgJGZvcm1hdCkpOwogICAgICAgIH0KCiAgICAgICAgJGZpbGVzeXN0ZW0gPSBuZXcgRmlsZXN5c3RlbSgpOwoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290UGFja2FnZUludGVyZmFjZSkgewogICAgICAgICAgICAkc291cmNlUGF0aCA9IHJlYWxwYXRoKCcuJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gRGlyZWN0b3J5IHVzZWQgdG8gZG93bmxvYWQgdGhlIHNvdXJjZXMKICAgICAgICAgICAgJHNvdXJjZVBhdGggPSBzeXNfZ2V0X3RlbXBfZGlyKCkuJy9jb21wb3Nlcl9hcmNoaXZlJy51bmlxaWQoKTsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkc291cmNlUGF0aCk7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgLy8gRG93bmxvYWQgc291cmNlcwogICAgICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5kb3dubG9hZCgkcGFja2FnZSwgJHNvdXJjZVBhdGgpOwogICAgICAgICAgICAgICAgJHRoaXMtPmxvb3AtPndhaXQoYXJyYXkoJHByb21pc2UpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmluc3RhbGwoJHBhY2thZ2UsICRzb3VyY2VQYXRoKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkc291cmNlUGF0aCk7CiAgICAgICAgICAgICAgICB0aHJvdyAgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIGV4Y2x1ZGUgZnJvbSBkb3dubG9hZGVkIGNvbXBvc2VyLmpzb24KICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRjb21wb3Nlckpzb25QYXRoID0gJHNvdXJjZVBhdGguJy9jb21wb3Nlci5qc29uJykpIHsKICAgICAgICAgICAgICAgICRqc29uRmlsZSA9IG5ldyBKc29uRmlsZSgkY29tcG9zZXJKc29uUGF0aCk7CiAgICAgICAgICAgICAgICAkanNvbkRhdGEgPSAkanNvbkZpbGUtPnJlYWQoKTsKICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJGpzb25EYXRhWydhcmNoaXZlJ11bJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0QXJjaGl2ZU5hbWUoJGpzb25EYXRhWydhcmNoaXZlJ11bJ25hbWUnXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRqc29uRGF0YVsnYXJjaGl2ZSddWydleGNsdWRlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldEFyY2hpdmVFeGNsdWRlcygkanNvbkRhdGFbJ2FyY2hpdmUnXVsnZXhjbHVkZSddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRmaWxlTmFtZSkgewogICAgICAgICAgICAkcGFja2FnZU5hbWUgPSAkdGhpcy0+Z2V0UGFja2FnZUZpbGVuYW1lKCRwYWNrYWdlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFja2FnZU5hbWUgPSAkZmlsZU5hbWU7CiAgICAgICAgfQoKICAgICAgICAvLyBBcmNoaXZlIGZpbGVuYW1lCiAgICAgICAgJGZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGFyZ2V0RGlyKTsKICAgICAgICAkdGFyZ2V0ID0gcmVhbHBhdGgoJHRhcmdldERpcikuJy8nLiRwYWNrYWdlTmFtZS4nLicuJGZvcm1hdDsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKGRpcm5hbWUoJHRhcmdldCkpOwoKICAgICAgICBpZiAoISR0aGlzLT5vdmVyd3JpdGVGaWxlcyAmJiBmaWxlX2V4aXN0cygkdGFyZ2V0KSkgewogICAgICAgICAgICByZXR1cm4gJHRhcmdldDsKICAgICAgICB9CgogICAgICAgIC8vIENyZWF0ZSB0aGUgYXJjaGl2ZQogICAgICAgICR0ZW1wVGFyZ2V0ID0gc3lzX2dldF90ZW1wX2RpcigpLicvY29tcG9zZXJfYXJjaGl2ZScudW5pcWlkKCkuJy4nLiRmb3JtYXQ7CiAgICAgICAgJGZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cyhkaXJuYW1lKCR0ZW1wVGFyZ2V0KSk7CgogICAgICAgICRhcmNoaXZlUGF0aCA9ICR1c2FibGVBcmNoaXZlci0+YXJjaGl2ZSgkc291cmNlUGF0aCwgJHRlbXBUYXJnZXQsICRmb3JtYXQsICRwYWNrYWdlLT5nZXRBcmNoaXZlRXhjbHVkZXMoKSwgJGlnbm9yZUZpbHRlcnMpOwogICAgICAgICRmaWxlc3lzdGVtLT5yZW5hbWUoJGFyY2hpdmVQYXRoLCAkdGFyZ2V0KTsKCiAgICAgICAgLy8gY2xlYW51cCB0ZW1wb3JhcnkgZG93bmxvYWQKICAgICAgICBpZiAoISRwYWNrYWdlIGluc3RhbmNlb2YgUm9vdFBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkc291cmNlUGF0aCk7CiAgICAgICAgfQogICAgICAgICRmaWxlc3lzdGVtLT5yZW1vdmUoJHRlbXBUYXJnZXQpOwoKICAgICAgICByZXR1cm4gJHRhcmdldDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKLyoqCiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAYXV0aG9yIE1hdHRoaWV1IE1vcXVldCA8bWF0dGhpZXVAbW9xdWV0Lm5ldD4KICovCmNsYXNzIFBoYXJBcmNoaXZlciBpbXBsZW1lbnRzIEFyY2hpdmVySW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGZvcm1hdHMgPSBhcnJheSgKICAgICAgICAnemlwJyA9PiBcUGhhcjo6WklQLAogICAgICAgICd0YXInID0+IFxQaGFyOjpUQVIsCiAgICAgICAgJ3Rhci5neicgPT4gXFBoYXI6OlRBUiwKICAgICAgICAndGFyLmJ6MicgPT4gXFBoYXI6OlRBUiwKICAgICk7CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkY29tcHJlc3NGb3JtYXRzID0gYXJyYXkoCiAgICAgICAgJ3Rhci5neicgPT4gXFBoYXI6OkdaLAogICAgICAgICd0YXIuYnoyJyA9PiBcUGhhcjo6QloyLAogICAgKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoJHNvdXJjZXMsICR0YXJnZXQsICRmb3JtYXQsIGFycmF5ICRleGNsdWRlcyA9IGFycmF5KCksICRpZ25vcmVGaWx0ZXJzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHNvdXJjZXMgPSByZWFscGF0aCgkc291cmNlcyk7CgogICAgICAgIC8vIFBoYXIgd291bGQgb3RoZXJ3aXNlIGxvYWQgdGhlIGZpbGUgd2hpY2ggd2UgZG9uJ3Qgd2FudAogICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGFyZ2V0KSkgewogICAgICAgICAgICB1bmxpbmsoJHRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICAkZmlsZW5hbWUgPSBzdWJzdHIoJHRhcmdldCwgMCwgc3RycnBvcygkdGFyZ2V0LCAkZm9ybWF0KSAtIDEpOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY29tcHJlc3MgZm9ybWF0CiAgICAgICAgICAgIGlmIChpc3NldChzdGF0aWM6OiRjb21wcmVzc0Zvcm1hdHNbJGZvcm1hdF0pKSB7CiAgICAgICAgICAgICAgICAvLyBDdXJyZW50IGNvbXByZXNzIGZvcm1hdCBzdXBwb3J0ZWQgYmFzZSBvbiB0YXIKICAgICAgICAgICAgICAgICR0YXJnZXQgPSAkZmlsZW5hbWUgLiAnLnRhcic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwaGFyID0gbmV3IFxQaGFyRGF0YSgkdGFyZ2V0LCBudWxsLCBudWxsLCBzdGF0aWM6OiRmb3JtYXRzWyRmb3JtYXRdKTsKICAgICAgICAgICAgJGZpbGVzID0gbmV3IEFyY2hpdmFibGVGaWxlc0ZpbmRlcigkc291cmNlcywgJGV4Y2x1ZGVzLCAkaWdub3JlRmlsdGVycyk7CiAgICAgICAgICAgICRmaWxlc09ubHkgPSBuZXcgQXJjaGl2YWJsZUZpbGVzRmlsdGVyKCRmaWxlcyk7CiAgICAgICAgICAgICRwaGFyLT5idWlsZEZyb21JdGVyYXRvcigkZmlsZXNPbmx5LCAkc291cmNlcyk7CiAgICAgICAgICAgICRmaWxlc09ubHktPmFkZEVtcHR5RGlyKCRwaGFyLCAkc291cmNlcyk7CgogICAgICAgICAgICBpZiAoaXNzZXQoc3RhdGljOjokY29tcHJlc3NGb3JtYXRzWyRmb3JtYXRdKSkgewogICAgICAgICAgICAgICAgLy8gQ2hlY2sgY2FuIGJlIGNvbXByZXNzZWQ/CiAgICAgICAgICAgICAgICBpZiAoISRwaGFyLT5jYW5Db21wcmVzcyhzdGF0aWM6OiRjb21wcmVzc0Zvcm1hdHNbJGZvcm1hdF0pKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ0NhbiBub3QgY29tcHJlc3MgdG8gJXMgZm9ybWF0JywgJGZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBvbGQgdGFyCiAgICAgICAgICAgICAgICB1bmxpbmsoJHRhcmdldCk7CgogICAgICAgICAgICAgICAgLy8gQ29tcHJlc3MgdGhlIG5ldyB0YXIKICAgICAgICAgICAgICAgICRwaGFyLT5jb21wcmVzcyhzdGF0aWM6OiRjb21wcmVzc0Zvcm1hdHNbJGZvcm1hdF0pOwoKICAgICAgICAgICAgICAgIC8vIE1ha2UgdGhlIGNvcnJlY3QgZmlsZW5hbWUKICAgICAgICAgICAgICAgICR0YXJnZXQgPSAkZmlsZW5hbWUgLiAnLicgLiAkZm9ybWF0OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRhcmdldDsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICJDb3VsZCBub3QgY3JlYXRlIGFyY2hpdmUgJyVzJyBmcm9tICclcyc6ICVzIiwKICAgICAgICAgICAgICAgICR0YXJnZXQsCiAgICAgICAgICAgICAgICAkc291cmNlcywKICAgICAgICAgICAgICAgICRlLT5nZXRNZXNzYWdlKCkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkbWVzc2FnZSwgJGUtPmdldENvZGUoKSwgJGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRmb3JtYXQsICRzb3VyY2VUeXBlKQogICAgewogICAgICAgIHJldHVybiBpc3NldChzdGF0aWM6OiRmb3JtYXRzWyRmb3JtYXRdKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIEZpbGVzeXN0ZW1JdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcU3BsRmlsZUluZm87CgovKioKICogQSBTeW1mb255IEZpbmRlciB3cmFwcGVyIHdoaWNoIGxvY2F0ZXMgZmlsZXMgdGhhdCBzaG91bGQgZ28gaW50byBhcmNoaXZlcwogKgogKiBIYW5kbGVzIC5naXRpZ25vcmUsIC5naXRhdHRyaWJ1dGVzIGFuZCAuaGdpZ25vcmUgZmlsZXMgYXMgd2VsbCBhcyBjb21wb3NlcidzCiAqIG93biBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQXJjaGl2YWJsZUZpbGVzRmluZGVyIGV4dGVuZHMgXEZpbHRlckl0ZXJhdG9yCnsKICAgIC8qKgogICAgICogQHZhciBGaW5kZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRmaW5kZXI7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaW50ZXJuYWwgU3ltZm9ueSBGaW5kZXIgd2l0aCBhcHByb3ByaWF0ZSBmaWx0ZXJzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlcyAgICAgICBQYXRoIHRvIHNvdXJjZSBmaWxlcyB0byBiZSBhcmNoaXZlZAogICAgICogQHBhcmFtIGFycmF5ICAkZXhjbHVkZXMgICAgICBDb21wb3NlcidzIG93biBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogICAgICogQHBhcmFtIGJvb2wgICAkaWdub3JlRmlsdGVycyBJZ25vcmUgZmlsdGVycyB3aGVuIGxvb2tpbmcgZm9yIGZpbGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc291cmNlcywgYXJyYXkgJGV4Y2x1ZGVzLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlKQogICAgewogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CgogICAgICAgICRzb3VyY2VzID0gJGZzLT5ub3JtYWxpemVQYXRoKHJlYWxwYXRoKCRzb3VyY2VzKSk7CgogICAgICAgIGlmICgkaWdub3JlRmlsdGVycykgewogICAgICAgICAgICAkZmlsdGVycyA9IGFycmF5KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGZpbHRlcnMgPSBhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBIZ0V4Y2x1ZGVGaWx0ZXIoJHNvdXJjZXMpLAogICAgICAgICAgICAgICAgbmV3IEdpdEV4Y2x1ZGVGaWx0ZXIoJHNvdXJjZXMpLAogICAgICAgICAgICAgICAgbmV3IENvbXBvc2VyRXhjbHVkZUZpbHRlcigkc291cmNlcywgJGV4Y2x1ZGVzKSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maW5kZXIgPSBuZXcgRmluZGVyKCk7CgogICAgICAgICRmaWx0ZXIgPSBmdW5jdGlvbiAoXFNwbEZpbGVJbmZvICRmaWxlKSB1c2UgKCRzb3VyY2VzLCAkZmlsdGVycywgJGZzKSB7CiAgICAgICAgICAgIGlmICgkZmlsZS0+aXNMaW5rKCkgJiYgc3RycG9zKCRmaWxlLT5nZXRSZWFsUGF0aCgpLCAkc291cmNlcykgIT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlbGF0aXZlUGF0aCA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgICAgICcjXicucHJlZ19xdW90ZSgkc291cmNlcywgJyMnKS4nIycsCiAgICAgICAgICAgICAgICAnJywKICAgICAgICAgICAgICAgICRmcy0+bm9ybWFsaXplUGF0aCgkZmlsZS0+Z2V0UmVhbFBhdGgoKSkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRleGNsdWRlID0gZmFsc2U7CiAgICAgICAgICAgIGZvcmVhY2ggKCRmaWx0ZXJzIGFzICRmaWx0ZXIpIHsKICAgICAgICAgICAgICAgICRleGNsdWRlID0gJGZpbHRlci0+ZmlsdGVyKCRyZWxhdGl2ZVBhdGgsICRleGNsdWRlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICEkZXhjbHVkZTsKICAgICAgICB9OwoKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkZmlsdGVyLCAnYmluZFRvJykpIHsKICAgICAgICAgICAgJGZpbHRlciA9ICRmaWx0ZXItPmJpbmRUbyhudWxsKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maW5kZXIKICAgICAgICAgICAgLT5pbigkc291cmNlcykKICAgICAgICAgICAgLT5maWx0ZXIoJGZpbHRlcikKICAgICAgICAgICAgLT5pZ25vcmVWQ1ModHJ1ZSkKICAgICAgICAgICAgLT5pZ25vcmVEb3RGaWxlcyhmYWxzZSk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHRoaXMtPmZpbmRlci0+Z2V0SXRlcmF0b3IoKSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgU3BsRmlsZUluZm8gJGN1cnJlbnQgKi8KICAgICAgICAkY3VycmVudCA9ICR0aGlzLT5nZXRJbm5lckl0ZXJhdG9yKCktPmN1cnJlbnQoKTsKCiAgICAgICAgaWYgKCEkY3VycmVudC0+aXNEaXIoKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRpdGVyYXRvciA9IG5ldyBGaWxlc3lzdGVtSXRlcmF0b3IoJGN1cnJlbnQsIEZpbGVzeXN0ZW1JdGVyYXRvcjo6U0tJUF9ET1RTKTsKCiAgICAgICAgcmV0dXJuICEkaXRlcmF0b3ItPnZhbGlkKCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxBcmNoaXZlcjsKCi8qKgogKiBBbiBleGNsdWRlIGZpbHRlciB0aGF0IHByb2Nlc3NlcyBnaXRpZ25vcmUgYW5kIGdpdGF0dHJpYnV0ZXMKICoKICogSXQgcmVzcGVjdHMgZXhwb3J0LWlnbm9yZSBnaXQgYXR0cmlidXRlcwogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgR2l0RXhjbHVkZUZpbHRlciBleHRlbmRzIEJhc2VFeGNsdWRlRmlsdGVyCnsKICAgIC8qKgogICAgICogUGFyc2VzIC5naXRpZ25vcmUgYW5kIC5naXRhdHRyaWJ1dGVzIGZpbGVzIGlmIHRoZXkgZXhpc3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VQYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc291cmNlUGF0aCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRzb3VyY2VQYXRoKTsKCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRzb3VyY2VQYXRoLicvLmdpdGlnbm9yZScpKSB7CiAgICAgICAgICAgICR0aGlzLT5leGNsdWRlUGF0dGVybnMgPSAkdGhpcy0+cGFyc2VMaW5lcygKICAgICAgICAgICAgICAgIGZpbGUoJHNvdXJjZVBhdGguJy8uZ2l0aWdub3JlJyksCiAgICAgICAgICAgICAgICBhcnJheSgkdGhpcywgJ3BhcnNlR2l0SWdub3JlTGluZScpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWxlX2V4aXN0cygkc291cmNlUGF0aC4nLy5naXRhdHRyaWJ1dGVzJykpIHsKICAgICAgICAgICAgJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucywKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUxpbmVzKAogICAgICAgICAgICAgICAgICAgIGZpbGUoJHNvdXJjZVBhdGguJy8uZ2l0YXR0cmlidXRlcycpLAogICAgICAgICAgICAgICAgICAgIGFycmF5KCR0aGlzLCAncGFyc2VHaXRBdHRyaWJ1dGVzTGluZScpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2FsbGJhY2sgbGluZSBwYXJzZXIgd2hpY2ggcHJvY2VzcyBnaXRpZ25vcmUgbGluZXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIEEgbGluZSBmcm9tIC5naXRpZ25vcmUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlR2l0SWdub3JlTGluZSgkbGluZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdlbmVyYXRlUGF0dGVybigkbGluZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsYmFjayBwYXJzZXIgd2hpY2ggZmluZHMgZXhwb3J0LWlnbm9yZSBydWxlcyBpbiBnaXQgYXR0cmlidXRlIGxpbmVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBBIGxpbmUgZnJvbSAuZ2l0YXR0cmlidXRlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbCBBbiBleGNsdWRlIHBhdHRlcm4gZm9yIGZpbHRlcigpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUdpdEF0dHJpYnV0ZXNMaW5lKCRsaW5lKQogICAgewogICAgICAgICRwYXJ0cyA9IHByZWdfc3BsaXQoJyNccysjJywgJGxpbmUpOwoKICAgICAgICBpZiAoY291bnQoJHBhcnRzKSA9PSAyICYmICRwYXJ0c1sxXSA9PT0gJ2V4cG9ydC1pZ25vcmUnKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2VuZXJhdGVQYXR0ZXJuKCRwYXJ0c1swXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlcjsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KYWJzdHJhY3QgY2xhc3MgQmFzZUV4Y2x1ZGVGaWx0ZXIKewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZVBhdGg7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhjbHVkZVBhdHRlcm5zOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlUGF0aCBEaXJlY3RvcnkgY29udGFpbmluZyBzb3VyY2VzIHRvIGJlIGZpbHRlcmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc291cmNlUGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlUGF0aCA9ICRzb3VyY2VQYXRoOwogICAgICAgICR0aGlzLT5leGNsdWRlUGF0dGVybnMgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHRoZSBnaXZlbiBwYXRoIGFnYWluc3QgYWxsIGV4Y2x1ZGUgcGF0dGVybnMgaW4gdGhpcyBmaWx0ZXIKICAgICAqCiAgICAgKiBOZWdhdGVkIHBhdHRlcm5zIG92ZXJ3cml0ZSBleGNsdWRlIGRlY2lzaW9ucyBvZiBwcmV2aW91cyBmaWx0ZXJzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlbGF0aXZlUGF0aCBUaGUgZmlsZSdzIHBhdGggcmVsYXRpdmUgdG8gdGhlIHNvdXJjZVBhdGgKICAgICAqIEBwYXJhbSBib29sICAgJGV4Y2x1ZGUgICAgICBXaGV0aGVyIGEgcHJldmlvdXMgZmlsdGVyIHdhbnRzIHRvIGV4Y2x1ZGUgdGhpcyBmaWxlCiAgICAgKgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGZpbGUgc2hvdWxkIGJlIGV4Y2x1ZGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoJHJlbGF0aXZlUGF0aCwgJGV4Y2x1ZGUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucyBhcyAkcGF0dGVybkRhdGEpIHsKICAgICAgICAgICAgbGlzdCgkcGF0dGVybiwgJG5lZ2F0ZSwgJHN0cmlwTGVhZGluZ1NsYXNoKSA9ICRwYXR0ZXJuRGF0YTsKCiAgICAgICAgICAgIGlmICgkc3RyaXBMZWFkaW5nU2xhc2gpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gc3Vic3RyKCRyZWxhdGl2ZVBhdGgsIDEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBhdGggPSAkcmVsYXRpdmVQYXRoOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoQHByZWdfbWF0Y2goJHBhdHRlcm4sICRwYXRoKSkgewogICAgICAgICAgICAgICAgJGV4Y2x1ZGUgPSAhJG5lZ2F0ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRleGNsdWRlOwogICAgfQoKICAgIC8qKgogICAgICogUHJvY2Vzc2VzIGEgZmlsZSBjb250YWluaW5nIGV4Y2x1ZGUgcnVsZXMgb2YgZGlmZmVyZW50IGZvcm1hdHMgcGVyIGxpbmUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgJGxpbmVzICAgICAgQSBzZXQgb2YgbGluZXMgdG8gYmUgcGFyc2VkCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGxpbmVQYXJzZXIgVGhlIHBhcnNlciB0byBiZSB1c2VkIG9uIGVhY2ggbGluZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgRXhjbHVkZSBwYXR0ZXJucyB0byBiZSB1c2VkIGluIGZpbHRlcigpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxpbmVzKGFycmF5ICRsaW5lcywgJGxpbmVQYXJzZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2ZpbHRlcigKICAgICAgICAgICAgYXJyYXlfbWFwKAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRsaW5lKSB1c2UgKCRsaW5lUGFyc2VyKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkbGluZSB8fCAwID09PSBzdHJwb3MoJGxpbmUsICcjJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoJGxpbmVQYXJzZXIsICRsaW5lKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAkbGluZXMKICAgICAgICAgICAgKSwKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHBhdHRlcm4gIT09IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGEgc2V0IG9mIGV4Y2x1ZGUgcGF0dGVybnMgZm9yIGZpbHRlcigpIGZyb20gZ2l0aWdub3JlIHJ1bGVzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRydWxlcyBBIGxpc3Qgb2YgZXhjbHVkZSBydWxlcyBpbiBnaXRpZ25vcmUgc3ludGF4CiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBFeGNsdWRlIHBhdHRlcm5zCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZW5lcmF0ZVBhdHRlcm5zKCRydWxlcykKICAgIHsKICAgICAgICAkcGF0dGVybnMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRydWxlcyBhcyAkcnVsZSkgewogICAgICAgICAgICAkcGF0dGVybnNbXSA9ICR0aGlzLT5nZW5lcmF0ZVBhdHRlcm4oJHJ1bGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYXR0ZXJuczsKICAgIH0KCiAgICAvKioKICAgICAqIEdlbmVyYXRlcyBhbiBleGNsdWRlIHBhdHRlcm4gZm9yIGZpbHRlcigpIGZyb20gYSBnaXRpZ25vcmUgcnVsZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJ1bGUgQW4gZXhjbHVkZSBydWxlIGluIGdpdGlnbm9yZSBzeW50YXgKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFuIGV4Y2x1ZGUgcGF0dGVybgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2VuZXJhdGVQYXR0ZXJuKCRydWxlKQogICAgewogICAgICAgICRuZWdhdGUgPSBmYWxzZTsKICAgICAgICAkcGF0dGVybiA9ICcnOwoKICAgICAgICBpZiAoJHJ1bGUgIT09ICcnICYmICRydWxlWzBdID09PSAnIScpIHsKICAgICAgICAgICAgJG5lZ2F0ZSA9IHRydWU7CiAgICAgICAgICAgICRydWxlID0gbHRyaW0oJHJ1bGUsICchJyk7CiAgICAgICAgfQoKICAgICAgICAkZmlyc3RTbGFzaFBvc2l0aW9uID0gc3RycG9zKCRydWxlLCAnLycpOwogICAgICAgIGlmICgwID09PSAkZmlyc3RTbGFzaFBvc2l0aW9uKSB7CiAgICAgICAgICAgICRwYXR0ZXJuID0gJ14vJzsKICAgICAgICB9IGVsc2VpZiAoZmFsc2UgPT09ICRmaXJzdFNsYXNoUG9zaXRpb24gfHwgc3RybGVuKCRydWxlKSAtIDEgPT09ICRmaXJzdFNsYXNoUG9zaXRpb24pIHsKICAgICAgICAgICAgJHBhdHRlcm4gPSAnLyc7CiAgICAgICAgfQoKICAgICAgICAkcnVsZSA9IHRyaW0oJHJ1bGUsICcvJyk7CiAgICAgICAgCiAgICAgICAgLy8gcmVtb3ZlIGRlbGltaXRlcnMgYXMgd2VsbCBhcyBjYXJldCAoXikgYW5kIGRvbGxhciBzaWduICgkKSBmcm9tIHRoZSByZWdleAogICAgICAgICRydWxlID0gc3Vic3RyKEZpbmRlclxHbG9iOjp0b1JlZ2V4KCRydWxlKSwgMiwgLTIpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJ3snLiRwYXR0ZXJuLiRydWxlLicoPz0kfC8pfScsICRuZWdhdGUsIGZhbHNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXEFyY2hpdmVyOwoKLyoqCiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKiBAYXV0aG9yIE1hdHRoaWV1IE1vcXVldCA8bWF0dGhpZXVAbW9xdWV0Lm5ldD4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmludGVyZmFjZSBBcmNoaXZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBhcmNoaXZlIGZyb20gdGhlIHNvdXJjZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlcyAgVGhlIHNvdXJjZXMgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQgICBUaGUgdGFyZ2V0IGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdCAgIFRoZSBmb3JtYXQgdXNlZCBmb3IgYXJjaGl2ZQogICAgICogQHBhcmFtIGFycmF5ICAkZXhjbHVkZXMgQSBsaXN0IG9mIHBhdHRlcm5zIGZvciBmaWxlcyB0byBleGNsdWRlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHBhdGggdG8gdGhlIHdyaXR0ZW4gYXJjaGl2ZSBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmNoaXZlKCRzb3VyY2VzLCAkdGFyZ2V0LCAkZm9ybWF0LCBhcnJheSAkZXhjbHVkZXMgPSBhcnJheSgpLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdCBzdXBwb3J0ZWQgYnkgdGhlIGFyY2hpdmVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdCAgICAgVGhlIGFyY2hpdmUgZm9ybWF0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VUeXBlIFRoZSBzb3VyY2UgdHlwZSAoZ2l0LCBzdm4sIGhnLCBldGMuKQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBmb3JtYXQgaXMgc3VwcG9ydGVkIGJ5IHRoZSBhcmNoaXZlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJGZvcm1hdCwgJHNvdXJjZVR5cGUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7Cgp1c2UgRmlsdGVySXRlcmF0b3I7CnVzZSBQaGFyRGF0YTsKCmNsYXNzIEFyY2hpdmFibGVGaWxlc0ZpbHRlciBleHRlbmRzIEZpbHRlckl0ZXJhdG9yCnsKICAgIHByaXZhdGUgJGRpcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhY2NlcHRhYmxlLCBvdGhlcndpc2UgZmFsc2UuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHQoKQogICAgewogICAgICAgICRmaWxlID0gJHRoaXMtPmdldElubmVySXRlcmF0b3IoKS0+Y3VycmVudCgpOwogICAgICAgIGlmICgkZmlsZS0+aXNEaXIoKSkgewogICAgICAgICAgICAkdGhpcy0+ZGlyc1tdID0gKHN0cmluZykgJGZpbGU7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRW1wdHlEaXIoUGhhckRhdGEgJHBoYXIsICRzb3VyY2VzKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5kaXJzIGFzICRmaWxlcGF0aCkgewogICAgICAgICAgICAkbG9jYWxuYW1lID0gc3RyX3JlcGxhY2UoJHNvdXJjZXMgLiAiLyIsICcnLCAkZmlsZXBhdGgpOwogICAgICAgICAgICAkcGhhci0+YWRkRW1wdHlEaXIoJGxvY2FsbmFtZSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyOwoKLyoqCiAqIEFuIGV4Y2x1ZGUgZmlsdGVyIHRoYXQgcHJvY2Vzc2VzIGhnaWdub3JlIGZpbGVzCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBIZ0V4Y2x1ZGVGaWx0ZXIgZXh0ZW5kcyBCYXNlRXhjbHVkZUZpbHRlcgp7CiAgICBjb25zdCBIR19JR05PUkVfUkVHRVggPSAxOwogICAgY29uc3QgSEdfSUdOT1JFX0dMT0IgPSAyOwoKICAgIC8qKgogICAgICogRWl0aGVyIEhHX0lHTk9SRV9SRUdFWCBvciBIR19JR05PUkVfR0xPQgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRwYXR0ZXJuTW9kZTsKCiAgICAvKioKICAgICAqIFBhcnNlcyAuaGdpZ25vcmUgZmlsZSBpZiBpdCBleGlzdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZVBhdGgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzb3VyY2VQYXRoKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHNvdXJjZVBhdGgpOwoKICAgICAgICAkdGhpcy0+cGF0dGVybk1vZGUgPSBzZWxmOjpIR19JR05PUkVfUkVHRVg7CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkc291cmNlUGF0aC4nLy5oZ2lnbm9yZScpKSB7CiAgICAgICAgICAgICR0aGlzLT5leGNsdWRlUGF0dGVybnMgPSAkdGhpcy0+cGFyc2VMaW5lcygKICAgICAgICAgICAgICAgIGZpbGUoJHNvdXJjZVBhdGguJy8uaGdpZ25vcmUnKSwKICAgICAgICAgICAgICAgIGFycmF5KCR0aGlzLCAncGFyc2VIZ0lnbm9yZUxpbmUnKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENhbGxiYWNrIGxpbmUgcGFyc2VyIHdoaWNoIHByb2Nlc3MgaGdpZ25vcmUgbGluZXMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIEEgbGluZSBmcm9tIC5oZ2lnbm9yZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbCBBbiBleGNsdWRlIHBhdHRlcm4gZm9yIGZpbHRlcigpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUhnSWdub3JlTGluZSgkbGluZSkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnI15zeW50YXhccyo6XHMqKGdsb2J8cmVnZXhwKSQjJywgJGxpbmUsICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJG1hdGNoZXNbMV0gPT09ICdnbG9iJykgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhdHRlcm5Nb2RlID0gc2VsZjo6SEdfSUdOT1JFX0dMT0I7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGF0dGVybk1vZGUgPSBzZWxmOjpIR19JR05PUkVfUkVHRVg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wYXR0ZXJuTW9kZSA9PSBzZWxmOjpIR19JR05PUkVfR0xPQikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnBhdHRlcm5Gcm9tR2xvYigkbGluZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBhdHRlcm5Gcm9tUmVnZXgoJGxpbmUpOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkgZnJvbSBhIGhnIGdsb2IgZXhwcmVzc2lvbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUgQSBsaW5lIGZyb20gLmhnaWdub3JlIGluIGdsb2IgbW9kZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gZXhjbHVkZSBwYXR0ZXJuIGZvciBmaWx0ZXIoKQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGF0dGVybkZyb21HbG9iKCRsaW5lKQogICAgewogICAgICAgICRwYXR0ZXJuID0gJyMnLnN1YnN0cihGaW5kZXJcR2xvYjo6dG9SZWdleCgkbGluZSksIDIsIC0xKS4nIyc7CiAgICAgICAgJHBhdHRlcm4gPSBzdHJfcmVwbGFjZSgnW14vXSonLCAnLionLCAkcGF0dGVybik7CgogICAgICAgIHJldHVybiBhcnJheSgkcGF0dGVybiwgZmFsc2UsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkgZnJvbSBhIGhnIHJlZ2V4cCBleHByZXNzaW9uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBBIGxpbmUgZnJvbSAuaGdpZ25vcmUgaW4gcmVnZXhwIG1vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFuIGV4Y2x1ZGUgcGF0dGVybiBmb3IgZmlsdGVyKCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhdHRlcm5Gcm9tUmVnZXgoJGxpbmUpCiAgICB7CiAgICAgICAgLy8gV1RGIG5lZWQgdG8gZXNjYXBlIHRoZSBkZWxpbWl0ZXIgc2FmZWx5CiAgICAgICAgJHBhdHRlcm4gPSAnIycucHJlZ19yZXBsYWNlKCcvKCg/OlxcXFxcXFxcKSopKFxcXFw/KSMvJywgJ1wxXDJcMlxcIycsICRsaW5lKS4nIyc7CgogICAgICAgIHJldHVybiBhcnJheSgkcGF0dGVybiwgZmFsc2UsIHRydWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7CgovKioKICogQW4gZXhjbHVkZSBmaWx0ZXIgd2hpY2ggcHJvY2Vzc2VzIGNvbXBvc2VyJ3Mgb3duIGV4Y2x1ZGUgcnVsZXMKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIENvbXBvc2VyRXhjbHVkZUZpbHRlciBleHRlbmRzIEJhc2VFeGNsdWRlRmlsdGVyCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlUGF0aCAgIERpcmVjdG9yeSBjb250YWluaW5nIHNvdXJjZXMgdG8gYmUgZmlsdGVyZWQKICAgICAqIEBwYXJhbSBhcnJheSAgJGV4Y2x1ZGVSdWxlcyBBbiBhcnJheSBvZiBleGNsdWRlIHJ1bGVzIGZyb20gY29tcG9zZXIuanNvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNvdXJjZVBhdGgsIGFycmF5ICRleGNsdWRlUnVsZXMpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkc291cmNlUGF0aCk7CiAgICAgICAgJHRoaXMtPmV4Y2x1ZGVQYXR0ZXJucyA9ICR0aGlzLT5nZW5lcmF0ZVBhdHRlcm5zKCRleGNsdWRlUnVsZXMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXI7Cgp1c2UgWmlwQXJjaGl2ZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKCi8qKgogKiBAYXV0aG9yIEphbiBQcmllc2VyIDxqYW5AcHJpZXNlci5uZXQ+CiAqLwpjbGFzcyBaaXBBcmNoaXZlciBpbXBsZW1lbnRzIEFyY2hpdmVySW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGZvcm1hdHMgPSBhcnJheSgKICAgICAgICAnemlwJyA9PiAxLAogICAgKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoJHNvdXJjZXMsICR0YXJnZXQsICRmb3JtYXQsIGFycmF5ICRleGNsdWRlcyA9IGFycmF5KCksICRpZ25vcmVGaWx0ZXJzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkc291cmNlcyA9ICRmcy0+bm9ybWFsaXplUGF0aCgkc291cmNlcyk7CgogICAgICAgICR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOwogICAgICAgICRyZXMgPSAkemlwLT5vcGVuKCR0YXJnZXQsIFppcEFyY2hpdmU6OkNSRUFURSk7CiAgICAgICAgaWYgKCRyZXMgPT09IHRydWUpIHsKICAgICAgICAgICAgJGZpbGVzID0gbmV3IEFyY2hpdmFibGVGaWxlc0ZpbmRlcigkc291cmNlcywgJGV4Y2x1ZGVzLCAkaWdub3JlRmlsdGVycyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRmaWxlcyBhcyAkZmlsZSkgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgXFNwbEZpbGVJbmZvICRmaWxlICovCiAgICAgICAgICAgICAgICAkZmlsZXBhdGggPSBzdHJ0cigkZmlsZS0+Z2V0UGF0aCgpLiIvIi4kZmlsZS0+Z2V0RmlsZW5hbWUoKSwgJ1xcJywgJy8nKTsKICAgICAgICAgICAgICAgICRsb2NhbG5hbWUgPSAkZmlsZXBhdGg7CiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRsb2NhbG5hbWUsICRzb3VyY2VzIC4gJy8nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICRsb2NhbG5hbWUgPSBzdWJzdHIoJGxvY2FsbmFtZSwgc3RybGVuKCRzb3VyY2VzIC4gJy8nKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGZpbGUtPmlzRGlyKCkpIHsKICAgICAgICAgICAgICAgICAgICAkemlwLT5hZGRFbXB0eURpcigkbG9jYWxuYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHppcC0+YWRkRmlsZSgkZmlsZXBhdGgsICRsb2NhbG5hbWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogWmlwQXJjaGl2ZTo6c2V0RXh0ZXJuYWxBdHRyaWJ1dGVzTmFtZSBpcyBhdmFpbGFibGUgZnJvbSA+PSBQSFAgNS42CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA1MDYwMCkgewogICAgICAgICAgICAgICAgICAgICRwZXJtcyA9IGZpbGVwZXJtcygkZmlsZXBhdGgpOwoKICAgICAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAgICAgKiBFbnN1cmUgdG8gcHJlc2VydmUgdGhlIHBlcm1pc3Npb24gdW1hc2tzIGZvciB0aGUgZmlsZXBhdGggaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgJHppcC0+c2V0RXh0ZXJuYWxBdHRyaWJ1dGVzTmFtZSgkbG9jYWxuYW1lLCBaaXBBcmNoaXZlOjpPUFNZU19VTklYLCAkcGVybXMgPDwgMTYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkemlwLT5jbG9zZSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRhcmdldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoCiAgICAgICAgICAgICJDb3VsZCBub3QgY3JlYXRlIGFyY2hpdmUgJyVzJyBmcm9tICclcyc6ICVzIiwKICAgICAgICAgICAgJHRhcmdldCwKICAgICAgICAgICAgJHNvdXJjZXMsCiAgICAgICAgICAgICR6aXAtPmdldFN0YXR1c1N0cmluZygpCiAgICAgICAgKTsKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJGZvcm1hdCwgJHNvdXJjZVR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KHN0YXRpYzo6JGZvcm1hdHNbJGZvcm1hdF0pICYmICR0aGlzLT5jb21wcmVzc2lvbkF2YWlsYWJsZSgpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY29tcHJlc3Npb25BdmFpbGFibGUoKQogICAgewogICAgICAgIHJldHVybiBjbGFzc19leGlzdHMoJ1ppcEFyY2hpdmUnKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJvb3RBbGlhc1BhY2thZ2UgZXh0ZW5kcyBBbGlhc1BhY2thZ2UgaW1wbGVtZW50cyBSb290UGFja2FnZUludGVyZmFjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUm9vdFBhY2thZ2VJbnRlcmZhY2UgJGFsaWFzT2YsICR2ZXJzaW9uLCAkcHJldHR5VmVyc2lvbikKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRhbGlhc09mLCAkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRBbGlhc2VzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNaW5pbXVtU3RhYmlsaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eUZsYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFN0YWJpbGl0eUZsYWdzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWZlcmVuY2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsaWFzT2YtPmdldFJlZmVyZW5jZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZWZlclN0YWJsZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRQcmVmZXJTdGFibGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZpZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc09mLT5nZXRDb25maWcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcXVpcmVzKGFycmF5ICRyZXF1aXJlKQogICAgewogICAgICAgICR0aGlzLT5yZXF1aXJlcyA9ICR0aGlzLT5yZXBsYWNlU2VsZlZlcnNpb25EZXBlbmRlbmNpZXMoJHJlcXVpcmUsIExpbms6OlRZUEVfUkVRVUlSRSk7CgogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRSZXF1aXJlcygkcmVxdWlyZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXZSZXF1aXJlcyhhcnJheSAkZGV2UmVxdWlyZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV2UmVxdWlyZXMgPSAkdGhpcy0+cmVwbGFjZVNlbGZWZXJzaW9uRGVwZW5kZW5jaWVzKCRkZXZSZXF1aXJlLCBMaW5rOjpUWVBFX0RFVl9SRVFVSVJFKTsKCiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldERldlJlcXVpcmVzKCRkZXZSZXF1aXJlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZsaWN0cyhhcnJheSAkY29uZmxpY3RzKQogICAgewogICAgICAgICR0aGlzLT5jb25mbGljdHMgPSAkdGhpcy0+cmVwbGFjZVNlbGZWZXJzaW9uRGVwZW5kZW5jaWVzKCRjb25mbGljdHMsIExpbms6OlRZUEVfQ09ORkxJQ1QpOwogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRDb25mbGljdHMoJGNvbmZsaWN0cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm92aWRlcyhhcnJheSAkcHJvdmlkZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb3ZpZGVzID0gJHRoaXMtPnJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcygkcHJvdmlkZXMsIExpbms6OlRZUEVfUFJPVklERSk7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFByb3ZpZGVzKCRwcm92aWRlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXBsYWNlcyhhcnJheSAkcmVwbGFjZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcGxhY2VzID0gJHRoaXMtPnJlcGxhY2VTZWxmVmVyc2lvbkRlcGVuZGVuY2llcygkcmVwbGFjZXMsIExpbms6OlRZUEVfUkVQTEFDRSk7CiAgICAgICAgJHRoaXMtPmFsaWFzT2YtPnNldFJlcGxhY2VzKCRyZXBsYWNlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXBvc2l0b3JpZXMoJHJlcG9zaXRvcmllcykKICAgIHsKICAgICAgICAkdGhpcy0+YWxpYXNPZi0+c2V0UmVwb3NpdG9yaWVzKCRyZXBvc2l0b3JpZXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0b2xvYWQoYXJyYXkgJGF1dG9sb2FkKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRBdXRvbG9hZCgkYXV0b2xvYWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2QXV0b2xvYWQoYXJyYXkgJGRldkF1dG9sb2FkKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXREZXZBdXRvbG9hZCgkZGV2QXV0b2xvYWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RhYmlsaXR5RmxhZ3MoYXJyYXkgJHN0YWJpbGl0eUZsYWdzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRTdGFiaWxpdHlGbGFncygkc3RhYmlsaXR5RmxhZ3MpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VnZ2VzdHMoYXJyYXkgJHN1Z2dlc3RzKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRTdWdnZXN0cygkc3VnZ2VzdHMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXh0cmEoYXJyYXkgJGV4dHJhKQogICAgewogICAgICAgICR0aGlzLT5hbGlhc09mLT5zZXRFeHRyYSgkZXh0cmEpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Nsb25lKCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY2xvbmUoKTsKICAgICAgICAkdGhpcy0+YWxpYXNPZiA9IGNsb25lICR0aGlzLT5hbGlhc09mOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2U7CgovKioKICogUGFja2FnZSBjb250YWluaW5nIGFkZGl0aW9uYWwgbWV0YWRhdGEgdGhhdCBpcyBub3QgdXNlZCBieSB0aGUgc29sdmVyCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBDb21wbGV0ZVBhY2thZ2UgZXh0ZW5kcyBQYWNrYWdlIGltcGxlbWVudHMgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCAkcmVwb3NpdG9yaWVzOwogICAgcHJvdGVjdGVkICRsaWNlbnNlID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAka2V5d29yZHM7CiAgICBwcm90ZWN0ZWQgJGF1dGhvcnM7CiAgICBwcm90ZWN0ZWQgJGRlc2NyaXB0aW9uOwogICAgcHJvdGVjdGVkICRob21lcGFnZTsKICAgIHByb3RlY3RlZCAkc2NyaXB0cyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJHN1cHBvcnQgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRmdW5kaW5nID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkYWJhbmRvbmVkID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHNjcmlwdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNjcmlwdHMoYXJyYXkgJHNjcmlwdHMpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjcmlwdHMgPSAkc2NyaXB0czsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNjcmlwdHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2NyaXB0czsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVwb3NpdG9yaWVzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRyZXBvc2l0b3JpZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlcG9zaXRvcmllcygkcmVwb3NpdG9yaWVzKQogICAgewogICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSAkcmVwb3NpdG9yaWVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgbGljZW5zZQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkbGljZW5zZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGljZW5zZShhcnJheSAkbGljZW5zZSkKICAgIHsKICAgICAgICAkdGhpcy0+bGljZW5zZSA9ICRsaWNlbnNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGljZW5zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saWNlbnNlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBrZXl3b3JkcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAka2V5d29yZHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtleXdvcmRzKGFycmF5ICRrZXl3b3JkcykKICAgIHsKICAgICAgICAkdGhpcy0+a2V5d29yZHMgPSAka2V5d29yZHM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRLZXl3b3JkcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5rZXl3b3JkczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgYXV0aG9ycwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXV0aG9ycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0aG9ycyhhcnJheSAkYXV0aG9ycykKICAgIHsKICAgICAgICAkdGhpcy0+YXV0aG9ycyA9ICRhdXRob3JzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aG9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hdXRob3JzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBkZXNjcmlwdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZXNjcmlwdGlvbigkZGVzY3JpcHRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmRlc2NyaXB0aW9uID0gJGRlc2NyaXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVzY3JpcHRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGhvbWVwYWdlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaG9tZXBhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhvbWVwYWdlKCRob21lcGFnZSkKICAgIHsKICAgICAgICAkdGhpcy0+aG9tZXBhZ2UgPSAkaG9tZXBhZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIb21lcGFnZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ob21lcGFnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgc3VwcG9ydCBpbmZvcm1hdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkc3VwcG9ydAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3VwcG9ydChhcnJheSAkc3VwcG9ydCkKICAgIHsKICAgICAgICAkdGhpcy0+c3VwcG9ydCA9ICRzdXBwb3J0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3VwcG9ydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdXBwb3J0OwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBmdW5kaW5nCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRmdW5kaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGdW5kaW5nKGFycmF5ICRmdW5kaW5nKQogICAgewogICAgICAgICR0aGlzLT5mdW5kaW5nID0gJGZ1bmRpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdW5kaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZ1bmRpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQWJhbmRvbmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpICR0aGlzLT5hYmFuZG9uZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbHxzdHJpbmcgJGFiYW5kb25lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWJhbmRvbmVkKCRhYmFuZG9uZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFiYW5kb25lZCA9ICRhYmFuZG9uZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBJZiB0aGUgcGFja2FnZSBpcyBhYmFuZG9uZWQgYW5kIGhhcyBhIHN1Z2dlc3RlZCByZXBsYWNlbWVudCwgdGhpcyBtZXRob2QgcmV0dXJucyBpdAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcGxhY2VtZW50UGFja2FnZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRoaXMtPmFiYW5kb25lZCkgPyAkdGhpcy0+YWJhbmRvbmVkIDogbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxDb21wb3Nlck1pcnJvcjsKCi8qKgogKiBDb3JlIHBhY2thZ2UgZGVmaW5pdGlvbnMgdGhhdCBhcmUgbmVlZGVkIHRvIHJlc29sdmUgZGVwZW5kZW5jaWVzIGFuZCBpbnN0YWxsIHBhY2thZ2VzCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQYWNrYWdlIGV4dGVuZHMgQmFzZVBhY2thZ2UKewogICAgcHJvdGVjdGVkICR0eXBlOwogICAgcHJvdGVjdGVkICR0YXJnZXREaXI7CiAgICBwcm90ZWN0ZWQgJGluc3RhbGxhdGlvblNvdXJjZTsKICAgIHByb3RlY3RlZCAkc291cmNlVHlwZTsKICAgIHByb3RlY3RlZCAkc291cmNlVXJsOwogICAgcHJvdGVjdGVkICRzb3VyY2VSZWZlcmVuY2U7CiAgICBwcm90ZWN0ZWQgJHNvdXJjZU1pcnJvcnM7CiAgICBwcm90ZWN0ZWQgJGRpc3RUeXBlOwogICAgcHJvdGVjdGVkICRkaXN0VXJsOwogICAgcHJvdGVjdGVkICRkaXN0UmVmZXJlbmNlOwogICAgcHJvdGVjdGVkICRkaXN0U2hhMUNoZWNrc3VtOwogICAgcHJvdGVjdGVkICRkaXN0TWlycm9yczsKICAgIHByb3RlY3RlZCAkdmVyc2lvbjsKICAgIHByb3RlY3RlZCAkcHJldHR5VmVyc2lvbjsKICAgIHByb3RlY3RlZCAkcmVsZWFzZURhdGU7CiAgICBwcm90ZWN0ZWQgJGV4dHJhID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkYmluYXJpZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRkZXY7CiAgICBwcm90ZWN0ZWQgJHN0YWJpbGl0eTsKICAgIHByb3RlY3RlZCAkbm90aWZpY2F0aW9uVXJsOwoKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBMaW5rW10gKi8KICAgIHByb3RlY3RlZCAkY29uZmxpY3RzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIExpbmtbXSAqLwogICAgcHJvdGVjdGVkICRwcm92aWRlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBMaW5rW10gKi8KICAgIHByb3RlY3RlZCAkcmVwbGFjZXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgTGlua1tdICovCiAgICBwcm90ZWN0ZWQgJGRldlJlcXVpcmVzID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkc3VnZ2VzdHMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRhdXRvbG9hZCA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJGRldkF1dG9sb2FkID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkaW5jbHVkZVBhdGhzID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkYXJjaGl2ZU5hbWU7CiAgICBwcm90ZWN0ZWQgJGFyY2hpdmVFeGNsdWRlcyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJGlzRGVmYXVsdEJyYW5jaCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBpbiBtZW1vcnkgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgICAgICAgIFRoZSBwYWNrYWdlJ3MgbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgICAgICBUaGUgcGFja2FnZSdzIHZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZXR0eVZlcnNpb24gVGhlIHBhY2thZ2UncyBub24tbm9ybWFsaXplZCB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJHZlcnNpb24sICRwcmV0dHlWZXJzaW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUpOwoKICAgICAgICAkdGhpcy0+dmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgICR0aGlzLT5wcmV0dHlWZXJzaW9uID0gJHByZXR0eVZlcnNpb247CgogICAgICAgICR0aGlzLT5zdGFiaWxpdHkgPSBWZXJzaW9uUGFyc2VyOjpwYXJzZVN0YWJpbGl0eSgkdmVyc2lvbik7CiAgICAgICAgJHRoaXMtPmRldiA9ICR0aGlzLT5zdGFiaWxpdHkgPT09ICdkZXYnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXYoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHlwZSgkdHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50eXBlID86ICdsaWJyYXJ5JzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFiaWxpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXREaXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRhcmdldERpcigkdGFyZ2V0RGlyKQogICAgewogICAgICAgICR0aGlzLT50YXJnZXREaXIgPSAkdGFyZ2V0RGlyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0RGlyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnRhcmdldERpcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbHRyaW0ocHJlZ19yZXBsYWNlKCd7ICg/Ol58W1xcXFwvXSspIFwuXC4/ICg/OltcXFxcL10rfCQpICg/OlwuXC4/ICg/OltcXFxcL10rfCQpICkqfXgnLCAnLycsICR0aGlzLT50YXJnZXREaXIpLCAnLycpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRleHRyYQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXh0cmEoYXJyYXkgJGV4dHJhKQogICAgewogICAgICAgICR0aGlzLT5leHRyYSA9ICRleHRyYTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dHJhKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4dHJhOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRiaW5hcmllcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QmluYXJpZXMoYXJyYXkgJGJpbmFyaWVzKQogICAgewogICAgICAgICR0aGlzLT5iaW5hcmllcyA9ICRiaW5hcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJpbmFyaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJpbmFyaWVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5zdGFsbGF0aW9uU291cmNlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25Tb3VyY2UgPSAkdHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxhdGlvblNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnN0YWxsYXRpb25Tb3VyY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2VUeXBlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2VUeXBlID0gJHR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNvdXJjZVR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZVVybCgkdXJsKQogICAgewogICAgICAgICR0aGlzLT5zb3VyY2VVcmwgPSAkdXJsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNvdXJjZVVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlUmVmZXJlbmNlKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvdXJjZVJlZmVyZW5jZSA9ICRyZWZlcmVuY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VSZWZlcmVuY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlUmVmZXJlbmNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5fG51bGwgJG1pcnJvcnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZU1pcnJvcnMoJG1pcnJvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvdXJjZU1pcnJvcnMgPSAkbWlycm9yczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZU1pcnJvcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlTWlycm9yczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVVybHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VXJscygkdGhpcy0+c291cmNlVXJsLCAkdGhpcy0+c291cmNlTWlycm9ycywgJHRoaXMtPnNvdXJjZVJlZmVyZW5jZSwgJHRoaXMtPnNvdXJjZVR5cGUsICdzb3VyY2UnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RUeXBlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5kaXN0VHlwZSA9ICR0eXBlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzdFR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RVcmwoJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzdFVybCA9ICR1cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc3RVcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RSZWZlcmVuY2UoJHJlZmVyZW5jZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzdFJlZmVyZW5jZSA9ICRyZWZlcmVuY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0UmVmZXJlbmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc3RSZWZlcmVuY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzaGExY2hlY2tzdW0KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RTaGExQ2hlY2tzdW0oJHNoYTFjaGVja3N1bSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzdFNoYTFDaGVja3N1bSA9ICRzaGExY2hlY2tzdW07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0U2hhMUNoZWNrc3VtKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc3RTaGExQ2hlY2tzdW07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAkbWlycm9ycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdE1pcnJvcnMoJG1pcnJvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmRpc3RNaXJyb3JzID0gJG1pcnJvcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0TWlycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kaXN0TWlycm9yczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RVcmxzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFVybHMoJHRoaXMtPmRpc3RVcmwsICR0aGlzLT5kaXN0TWlycm9ycywgJHRoaXMtPmRpc3RSZWZlcmVuY2UsICR0aGlzLT5kaXN0VHlwZSwgJ2Rpc3QnKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5VmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVsZWFzZURhdGUKICAgICAqCiAgICAgKiBAcGFyYW0gXERhdGVUaW1lICRyZWxlYXNlRGF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVsZWFzZURhdGUoXERhdGVUaW1lICRyZWxlYXNlRGF0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+cmVsZWFzZURhdGUgPSAkcmVsZWFzZURhdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWxlYXNlRGF0ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWxlYXNlRGF0ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcmVxdWlyZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRyZXF1aXJlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXF1aXJlcyhhcnJheSAkcmVxdWlyZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVzID0gJHJlcXVpcmVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVxdWlyZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVxdWlyZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGNvbmZsaWN0aW5nIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIExpbmtbXSAkY29uZmxpY3RzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbmZsaWN0cyhhcnJheSAkY29uZmxpY3RzKQogICAgewogICAgICAgICR0aGlzLT5jb25mbGljdHMgPSAkY29uZmxpY3RzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmxpY3RzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZsaWN0czsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcHJvdmlkZWQgdmlydHVhbCBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSBMaW5rW10gJHByb3ZpZGVzIEEgc2V0IG9mIHBhY2thZ2UgbGlua3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb3ZpZGVzKGFycmF5ICRwcm92aWRlcykKICAgIHsKICAgICAgICAkdGhpcy0+cHJvdmlkZXMgPSAkcHJvdmlkZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm92aWRlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm92aWRlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgcGFja2FnZXMgdGhpcyBvbmUgcmVwbGFjZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTGlua1tdICRyZXBsYWNlcyBBIHNldCBvZiBwYWNrYWdlIGxpbmtzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXBsYWNlcyhhcnJheSAkcmVwbGFjZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcGxhY2VzID0gJHJlcGxhY2VzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwbGFjZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVwbGFjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHJlY29tbWVuZGVkIHBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIExpbmtbXSAkZGV2UmVxdWlyZXMgQSBzZXQgb2YgcGFja2FnZSBsaW5rcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2UmVxdWlyZXMoYXJyYXkgJGRldlJlcXVpcmVzKQogICAgewogICAgICAgICR0aGlzLT5kZXZSZXF1aXJlcyA9ICRkZXZSZXF1aXJlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldlJlcXVpcmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldlJlcXVpcmVzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBzdWdnZXN0ZWQgcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHN1Z2dlc3RzIEEgc2V0IG9mIHBhY2thZ2UgbmFtZXMvY29tbWVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN1Z2dlc3RzKGFycmF5ICRzdWdnZXN0cykKICAgIHsKICAgICAgICAkdGhpcy0+c3VnZ2VzdHMgPSAkc3VnZ2VzdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdWdnZXN0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdWdnZXN0czsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgYXV0b2xvYWQgbWFwcGluZwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXV0b2xvYWQgTWFwcGluZyBvZiBhdXRvbG9hZGluZyBydWxlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0b2xvYWQoYXJyYXkgJGF1dG9sb2FkKQogICAgewogICAgICAgICR0aGlzLT5hdXRvbG9hZCA9ICRhdXRvbG9hZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dG9sb2FkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF1dG9sb2FkOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBkZXYgYXV0b2xvYWQgbWFwcGluZwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkZGV2QXV0b2xvYWQgTWFwcGluZyBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERldkF1dG9sb2FkKGFycmF5ICRkZXZBdXRvbG9hZCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV2QXV0b2xvYWQgPSAkZGV2QXV0b2xvYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZBdXRvbG9hZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZBdXRvbG9hZDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxpc3Qgb2YgcGF0aHMgYWRkZWQgdG8gUEhQJ3MgaW5jbHVkZSBwYXRoLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkaW5jbHVkZVBhdGhzIExpc3Qgb2YgZGlyZWN0b3JpZXMuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbmNsdWRlUGF0aHMoYXJyYXkgJGluY2x1ZGVQYXRocykKICAgIHsKICAgICAgICAkdGhpcy0+aW5jbHVkZVBhdGhzID0gJGluY2x1ZGVQYXRoczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluY2x1ZGVQYXRocygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmNsdWRlUGF0aHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBub3RpZmljYXRpb24gVVJMCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbm90aWZpY2F0aW9uVXJsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROb3RpZmljYXRpb25VcmwoJG5vdGlmaWNhdGlvblVybCkKICAgIHsKICAgICAgICAkdGhpcy0+bm90aWZpY2F0aW9uVXJsID0gJG5vdGlmaWNhdGlvblVybDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5vdGlmaWNhdGlvblVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ub3RpZmljYXRpb25Vcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGRlZmF1bHQgYmFzZSBmaWxlbmFtZSBmb3IgYXJjaGl2ZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVOYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5hcmNoaXZlTmFtZSA9ICRuYW1lOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZU5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJjaGl2ZU5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgbGlzdCBvZiBwYXR0ZXJucyB0byBiZSBleGNsdWRlZCBmcm9tIGFyY2hpdmVzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRleGNsdWRlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJjaGl2ZUV4Y2x1ZGVzKGFycmF5ICRleGNsdWRlcykKICAgIHsKICAgICAgICAkdGhpcy0+YXJjaGl2ZUV4Y2x1ZGVzID0gJGV4Y2x1ZGVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZUV4Y2x1ZGVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyY2hpdmVFeGNsdWRlczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRkZWZhdWx0QnJhbmNoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJc0RlZmF1bHRCcmFuY2goJGRlZmF1bHRCcmFuY2gpCiAgICB7CiAgICAgICAgJHRoaXMtPmlzRGVmYXVsdEJyYW5jaCA9ICRkZWZhdWx0QnJhbmNoOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWZhdWx0QnJhbmNoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzRGVmYXVsdEJyYW5jaDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRyZWZlcmVuY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldFNvdXJjZVJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAgICAgLy8gb25seSBiaXRidWNrZXQsIGdpdGh1YiBhbmQgZ2l0bGFiIGhhdmUgYXV0byBnZW5lcmF0ZWQgZGlzdCBVUkxzIHRoYXQgZWFzaWx5IGFsbG93IHJlcGxhY2luZyB0aGUgcmVmZXJlbmNlIGluIHRoZSBkaXN0IFVSTAogICAgICAgIC8vIFRPRE8gZ2VuZXJhbGl6ZSB0aGlzIGEgYml0IGZvciBzZWxmLW1hbmFnZWQvb24tcHJlbSB2ZXJzaW9ucz8gU29tZSBraW5kIG9mIHJlcGxhY2UgdG9rZW4gaW4gZGlzdCB1cmxzIHdoaWNoIGFsbG93IHRoaXM/CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teaHR0cHM/Oi8vKD86KD86d3d3XC4pP2JpdGJ1Y2tldFwub3JnfChhcGlcLik/Z2l0aHViXC5jb218KD86d3d3XC4pP2dpdGxhYlwuY29tKS99aScsICR0aGlzLT5nZXREaXN0VXJsKCkpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREaXN0UmVmZXJlbmNlKCRyZWZlcmVuY2UpOwogICAgICAgICAgICAkdGhpcy0+c2V0RGlzdFVybChwcmVnX3JlcGxhY2UoJ3soPzw9L3xzaGE9KVthLWYwLTldezQwfSg/PS98JCl9aScsICRyZWZlcmVuY2UsICR0aGlzLT5nZXREaXN0VXJsKCkpKTsKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmdldERpc3RSZWZlcmVuY2UoKSkgeyAvLyB1cGRhdGUgdGhlIGRpc3QgcmVmZXJlbmNlIGlmIHRoZXJlIHdhcyBvbmUsIGJ1dCBpZiBub25lIHdhcyBwcm92aWRlZCBpZ25vcmUgaXQKICAgICAgICAgICAgJHRoaXMtPnNldERpc3RSZWZlcmVuY2UoJHJlZmVyZW5jZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgY3VycmVudCB2ZXJzaW9uIGFuZCBwcmV0dHkgdmVyc2lvbiB3aXRoIHBhc3NlZCB2YWx1ZXMuCiAgICAgKiBJdCBhbHNvIHNldHMgc3RhYmlsaXR5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gICAgICAgVGhlIHBhY2thZ2UncyBub3JtYWxpemVkIHZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZXR0eVZlcnNpb24gVGhlIHBhY2thZ2UncyBub24tbm9ybWFsaXplZCB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXBsYWNlVmVyc2lvbigkdmVyc2lvbiwgJHByZXR0eVZlcnNpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnZlcnNpb24gPSAkdmVyc2lvbjsKICAgICAgICAkdGhpcy0+cHJldHR5VmVyc2lvbiA9ICRwcmV0dHlWZXJzaW9uOwoKICAgICAgICAkdGhpcy0+c3RhYmlsaXR5ID0gVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHZlcnNpb24pOwogICAgICAgICR0aGlzLT5kZXYgPSAkdGhpcy0+c3RhYmlsaXR5ID09PSAnZGV2JzsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VXJscygkdXJsLCAkbWlycm9ycywgJHJlZiwgJHR5cGUsICR1cmxUeXBlKQogICAgewogICAgICAgIGlmICghJHVybCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CiAgICAgICAgJHVybHMgPSBhcnJheSgkdXJsKTsKICAgICAgICBpZiAoJG1pcnJvcnMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJG1pcnJvcnMgYXMgJG1pcnJvcikgewogICAgICAgICAgICAgICAgaWYgKCR1cmxUeXBlID09PSAnZGlzdCcpIHsKICAgICAgICAgICAgICAgICAgICAkbWlycm9yVXJsID0gQ29tcG9zZXJNaXJyb3I6OnByb2Nlc3NVcmwoJG1pcnJvclsndXJsJ10sICR0aGlzLT5uYW1lLCAkdGhpcy0+dmVyc2lvbiwgJHJlZiwgJHR5cGUpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR1cmxUeXBlID09PSAnc291cmNlJyAmJiAkdHlwZSA9PT0gJ2dpdCcpIHsKICAgICAgICAgICAgICAgICAgICAkbWlycm9yVXJsID0gQ29tcG9zZXJNaXJyb3I6OnByb2Nlc3NHaXRVcmwoJG1pcnJvclsndXJsJ10sICR0aGlzLT5uYW1lLCAkdXJsLCAkdHlwZSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHVybFR5cGUgPT09ICdzb3VyY2UnICYmICR0eXBlID09PSAnaGcnKSB7CiAgICAgICAgICAgICAgICAgICAgJG1pcnJvclVybCA9IENvbXBvc2VyTWlycm9yOjpwcm9jZXNzSGdVcmwoJG1pcnJvclsndXJsJ10sICR0aGlzLT5uYW1lLCAkdXJsLCAkdHlwZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFcaW5fYXJyYXkoJG1pcnJvclVybCwgJHVybHMpKSB7CiAgICAgICAgICAgICAgICAgICAgJGZ1bmMgPSAkbWlycm9yWydwcmVmZXJyZWQnXSA/ICdhcnJheV91bnNoaWZ0JyA6ICdhcnJheV9wdXNoJzsKICAgICAgICAgICAgICAgICAgICAkZnVuYygkdXJscywgJG1pcnJvclVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdXJsczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXENvbXBhcmVyOwoKLyoqCiAqIGNsYXNzIENvbXBhcmVyCiAqCiAqIEBhdXRob3IgSGVjdG9yIFByYXRzIDxoZWN0b3JwcmF0c29ydGVnYUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDb21wYXJlcgp7CiAgICBwcml2YXRlICRzb3VyY2U7CiAgICBwcml2YXRlICR1cGRhdGU7CiAgICBwcml2YXRlICRjaGFuZ2VkOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTb3VyY2UoJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gJHNvdXJjZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlKCR1cGRhdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnVwZGF0ZSA9ICR1cGRhdGU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5nZWQoJHRvU3RyaW5nID0gZmFsc2UsICRleHBsaWNhdGVkID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGNoYW5nZWQgPSAkdGhpcy0+Y2hhbmdlZDsKICAgICAgICBpZiAoIWNvdW50KCRjaGFuZ2VkKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICgkZXhwbGljYXRlZCkgewogICAgICAgICAgICBmb3JlYWNoICgkY2hhbmdlZCBhcyAkc2VjdGlvbktleSA9PiAkaXRlbVNlY3Rpb24pIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRpdGVtU2VjdGlvbiBhcyAkaXRlbUtleSA9PiAkaXRlbSkgewogICAgICAgICAgICAgICAgICAgICRjaGFuZ2VkWyRzZWN0aW9uS2V5XVskaXRlbUtleV0gPSAkaXRlbS4nICgnLiRzZWN0aW9uS2V5LicpJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0b1N0cmluZykgewogICAgICAgICAgICBmb3JlYWNoICgkY2hhbmdlZCBhcyAkc2VjdGlvbktleSA9PiAkaXRlbVNlY3Rpb24pIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRpdGVtU2VjdGlvbiBhcyAkaXRlbUtleSA9PiAkaXRlbSkgewogICAgICAgICAgICAgICAgICAgICRjaGFuZ2VkWydzdHJpbmcnXVtdID0gJGl0ZW0uIlxyXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRjaGFuZ2VkID0gaW1wbG9kZSgiXHJcbiIsICRjaGFuZ2VkWydzdHJpbmcnXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNoYW5nZWQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvQ29tcGFyZSgpCiAgICB7CiAgICAgICAgJHNvdXJjZSA9IGFycmF5KCk7CiAgICAgICAgJGRlc3RpbmF0aW9uID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+Y2hhbmdlZCA9IGFycmF5KCk7CiAgICAgICAgJGN1cnJlbnREaXJlY3RvcnkgPSBnZXRjd2QoKTsKICAgICAgICBjaGRpcigkdGhpcy0+c291cmNlKTsKICAgICAgICAkc291cmNlID0gJHRoaXMtPmRvVHJlZSgnLicsICRzb3VyY2UpOwogICAgICAgIGlmICghaXNfYXJyYXkoJHNvdXJjZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBjaGRpcigkY3VycmVudERpcmVjdG9yeSk7CiAgICAgICAgY2hkaXIoJHRoaXMtPnVwZGF0ZSk7CiAgICAgICAgJGRlc3RpbmF0aW9uID0gJHRoaXMtPmRvVHJlZSgnLicsICRkZXN0aW5hdGlvbik7CiAgICAgICAgaWYgKCFpc19hcnJheSgkZGVzdGluYXRpb24pKSB7CiAgICAgICAgICAgIGV4aXQ7CiAgICAgICAgfQogICAgICAgIGNoZGlyKCRjdXJyZW50RGlyZWN0b3J5KTsKICAgICAgICBmb3JlYWNoICgkc291cmNlIGFzICRkaXIgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZSBhcyAkZmlsZSA9PiAkaGFzaCkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRkZXN0aW5hdGlvblskZGlyXVskZmlsZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRoYXNoICE9PSAkZGVzdGluYXRpb25bJGRpcl1bJGZpbGVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGFuZ2VkWydjaGFuZ2VkJ11bXSA9ICRkaXIuJy8nLiRmaWxlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoYW5nZWRbJ3JlbW92ZWQnXVtdID0gJGRpci4nLycuJGZpbGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJGRlc3RpbmF0aW9uIGFzICRkaXIgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZSBhcyAkZmlsZSA9PiAkaGFzaCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkc291cmNlWyRkaXJdWyRmaWxlXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhbmdlZFsnYWRkZWQnXVtdID0gJGRpci4nLycuJGZpbGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb1RyZWUoJGRpciwgJiRhcnJheSkKICAgIHsKICAgICAgICBpZiAoJGRoID0gb3BlbmRpcigkZGlyKSkgewogICAgICAgICAgICB3aGlsZSAoJGZpbGUgPSByZWFkZGlyKCRkaCkpIHsKICAgICAgICAgICAgICAgIGlmICgkZmlsZSAhPT0gJy4nICYmICRmaWxlICE9PSAnLi4nKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2xpbmsoJGRpci4nLycuJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhcnJheVskZGlyXVskZmlsZV0gPSByZWFkbGluaygkZGlyLicvJy4kZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2RpcigkZGlyLicvJy4kZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb3VudCgkYXJyYXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYXJyYXlbMF0gPSAnVGVtcCc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZG9UcmVlKCRkaXIuJy8nLiRmaWxlLCAkYXJyYXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfZmlsZSgkZGlyLicvJy4kZmlsZSkgJiYgZmlsZXNpemUoJGRpci4nLycuJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhcnJheVskZGlyXVskZmlsZV0gPSBtZDVfZmlsZSgkZGlyLicvJy4kZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3VudCgkYXJyYXkpID4gMSAmJiBpc3NldCgkYXJyYXlbJzAnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRhcnJheVsnMCddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRhcnJheTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CgovKioKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQXJyYXlMb2FkZXIgaW1wbGVtZW50cyBMb2FkZXJJbnRlcmZhY2UKewogICAgcHJvdGVjdGVkICR2ZXJzaW9uUGFyc2VyOwogICAgcHJvdGVjdGVkICRsb2FkT3B0aW9uczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoVmVyc2lvblBhcnNlciAkcGFyc2VyID0gbnVsbCwgJGxvYWRPcHRpb25zID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcGFyc2VyKSB7CiAgICAgICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSAkcGFyc2VyOwogICAgICAgICR0aGlzLT5sb2FkT3B0aW9ucyA9ICRsb2FkT3B0aW9uczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZChhcnJheSAkY29uZmlnLCAkY2xhc3MgPSAnQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2UnKQogICAgewogICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmNyZWF0ZU9iamVjdCgkY29uZmlnLCAkY2xhc3MpOwoKICAgICAgICBmb3JlYWNoIChQYWNrYWdlXEJhc2VQYWNrYWdlOjokc3VwcG9ydGVkTGlua1R5cGVzIGFzICR0eXBlID0+ICRvcHRzKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWyR0eXBlXSkpIHsKICAgICAgICAgICAgICAgICRtZXRob2QgPSAnc2V0Jy51Y2ZpcnN0KCRvcHRzWydtZXRob2QnXSk7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+eyRtZXRob2R9KAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUxpbmtzKAogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0TmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAkb3B0c1snZGVzY3JpcHRpb24nXSwKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1skdHlwZV0KICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5jb25maWd1cmVPYmplY3QoJHBhY2thZ2UsICRjb25maWcpOwoKICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRQYWNrYWdlcyhhcnJheSAkdmVyc2lvbnMsICRjbGFzcykKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRsaW5rQ2FjaGUgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+Y3JlYXRlT2JqZWN0KCR2ZXJzaW9uLCAkY2xhc3MpOwoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ3VyZUNhY2hlZExpbmtzKCRsaW5rQ2FjaGUsICRwYWNrYWdlLCAkdmVyc2lvbik7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmNvbmZpZ3VyZU9iamVjdCgkcGFja2FnZSwgJHZlcnNpb24pOwoKICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVPYmplY3QoYXJyYXkgJGNvbmZpZywgJGNsYXNzKQogICAgewogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1snbmFtZSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignVW5rbm93biBwYWNrYWdlIGhhcyBubyBuYW1lIGRlZmluZWQgKCcuanNvbl9lbmNvZGUoJGNvbmZpZykuJykuJyk7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignUGFja2FnZSAnLiRjb25maWdbJ25hbWUnXS4nIGhhcyBubyB2ZXJzaW9uIGRlZmluZWQuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgYWxyZWFkeSBub3JtYWxpemVkIHZlcnNpb25zCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3ZlcnNpb25fbm9ybWFsaXplZCddKSkgewogICAgICAgICAgICAkdmVyc2lvbiA9ICRjb25maWdbJ3ZlcnNpb25fbm9ybWFsaXplZCddOwoKICAgICAgICAgICAgLy8gaGFuZGxpbmcgb2YgZXhpc3RpbmcgcmVwb3Mgd2hpY2ggbmVlZCB0byByZW1haW4gY29tcG9zZXIgdjEgY29tcGF0aWJsZSwgaW4gY2FzZSB0aGUgdmVyc2lvbl9ub3JtYWxpemVkIGNvbnRhaW5lZCBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUywgd2UgcmVub3JtYWxpemUgaXQKICAgICAgICAgICAgaWYgKCR2ZXJzaW9uID09PSBWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBUykgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRjb25maWdbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJGNvbmZpZ1sndmVyc2lvbiddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgJGNsYXNzKCRjb25maWdbJ25hbWUnXSwgJHZlcnNpb24sICRjb25maWdbJ3ZlcnNpb24nXSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb25maWd1cmVPYmplY3QoJHBhY2thZ2UsIGFycmF5ICRjb25maWcpCiAgICB7CiAgICAgICAgJHBhY2thZ2UtPnNldFR5cGUoaXNzZXQoJGNvbmZpZ1sndHlwZSddKSA/IHN0cnRvbG93ZXIoJGNvbmZpZ1sndHlwZSddKSA6ICdsaWJyYXJ5Jyk7CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWyd0YXJnZXQtZGlyJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRUYXJnZXREaXIoJGNvbmZpZ1sndGFyZ2V0LWRpciddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydleHRyYSddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snZXh0cmEnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldEV4dHJhKCRjb25maWdbJ2V4dHJhJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2JpbiddKSkgewogICAgICAgICAgICBpZiAoIVxpc19hcnJheSgkY29uZmlnWydiaW4nXSkpIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ2JpbiddID0gYXJyYXkoJGNvbmZpZ1snYmluJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJ2JpbiddIGFzICRrZXkgPT4gJGJpbikgewogICAgICAgICAgICAgICAgJGNvbmZpZ1snYmluJ11bJGtleV0gPSBsdHJpbSgkYmluLCAnLycpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRCaW5hcmllcygkY29uZmlnWydiaW4nXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snaW5zdGFsbGF0aW9uLXNvdXJjZSddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0SW5zdGFsbGF0aW9uU291cmNlKCRjb25maWdbJ2luc3RhbGxhdGlvbi1zb3VyY2UnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snZGVmYXVsdC1icmFuY2gnXSkgJiYgJGNvbmZpZ1snZGVmYXVsdC1icmFuY2gnXSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0SXNEZWZhdWx0QnJhbmNoKHRydWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3NvdXJjZSddKSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCRjb25maWdbJ3NvdXJjZSddWyd0eXBlJ10sICRjb25maWdbJ3NvdXJjZSddWyd1cmwnXSwgJGNvbmZpZ1snc291cmNlJ11bJ3JlZmVyZW5jZSddKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAiUGFja2FnZSAlcydzIHNvdXJjZSBrZXkgc2hvdWxkIGJlIHNwZWNpZmllZCBhcyB7XCJ0eXBlXCI6IC4uLiwgXCJ1cmxcIjogLi4uLCBcInJlZmVyZW5jZVwiOiAuLi59LFxuJXMgZ2l2ZW4uIiwKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAganNvbl9lbmNvZGUoJGNvbmZpZ1snc291cmNlJ10pCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlVHlwZSgkY29uZmlnWydzb3VyY2UnXVsndHlwZSddKTsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZVVybCgkY29uZmlnWydzb3VyY2UnXVsndXJsJ10pOwogICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlUmVmZXJlbmNlKGlzc2V0KCRjb25maWdbJ3NvdXJjZSddWydyZWZlcmVuY2UnXSkgPyAkY29uZmlnWydzb3VyY2UnXVsncmVmZXJlbmNlJ10gOiBudWxsKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3NvdXJjZSddWydtaXJyb3JzJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlTWlycm9ycygkY29uZmlnWydzb3VyY2UnXVsnbWlycm9ycyddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2Rpc3QnXSkpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkY29uZmlnWydkaXN0J11bJ3R5cGUnXSwgJGNvbmZpZ1snZGlzdCddWyd1cmwnXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgIlBhY2thZ2UgJXMncyBkaXN0IGtleSBzaG91bGQgYmUgc3BlY2lmaWVkIGFzICIuCiAgICAgICAgICAgICAgICAgICAgIntcInR5cGVcIjogLi4uLCBcInVybFwiOiAuLi4sIFwicmVmZXJlbmNlXCI6IC4uLiwgXCJzaGFzdW1cIjogLi4ufSxcbiVzIGdpdmVuLiIsCiAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1snbmFtZSddLAogICAgICAgICAgICAgICAgICAgIGpzb25fZW5jb2RlKCRjb25maWdbJ2Rpc3QnXSkKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0VHlwZSgkY29uZmlnWydkaXN0J11bJ3R5cGUnXSk7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0VXJsKCRjb25maWdbJ2Rpc3QnXVsndXJsJ10pOwogICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdFJlZmVyZW5jZShpc3NldCgkY29uZmlnWydkaXN0J11bJ3JlZmVyZW5jZSddKSA/ICRjb25maWdbJ2Rpc3QnXVsncmVmZXJlbmNlJ10gOiBudWxsKTsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldERpc3RTaGExQ2hlY2tzdW0oaXNzZXQoJGNvbmZpZ1snZGlzdCddWydzaGFzdW0nXSkgPyAkY29uZmlnWydkaXN0J11bJ3NoYXN1bSddIDogbnVsbCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydkaXN0J11bJ21pcnJvcnMnXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXREaXN0TWlycm9ycygkY29uZmlnWydkaXN0J11bJ21pcnJvcnMnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydzdWdnZXN0J10pICYmIFxpc19hcnJheSgkY29uZmlnWydzdWdnZXN0J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJ3N1Z2dlc3QnXSBhcyAkdGFyZ2V0ID0+ICRyZWFzb24pIHsKICAgICAgICAgICAgICAgIGlmICgnc2VsZi52ZXJzaW9uJyA9PT0gdHJpbSgkcmVhc29uKSkgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ3N1Z2dlc3QnXVskdGFyZ2V0XSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhY2thZ2UtPnNldFN1Z2dlc3RzKCRjb25maWdbJ3N1Z2dlc3QnXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snYXV0b2xvYWQnXSkpIHsKICAgICAgICAgICAgJHBhY2thZ2UtPnNldEF1dG9sb2FkKCRjb25maWdbJ2F1dG9sb2FkJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2F1dG9sb2FkLWRldiddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0RGV2QXV0b2xvYWQoJGNvbmZpZ1snYXV0b2xvYWQtZGV2J10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2luY2x1ZGUtcGF0aCddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0SW5jbHVkZVBhdGhzKCRjb25maWdbJ2luY2x1ZGUtcGF0aCddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1sndGltZSddKSkgewogICAgICAgICAgICAkdGltZSA9IHByZWdfbWF0Y2goJy9eXGQrKyQvRCcsICRjb25maWdbJ3RpbWUnXSkgPyAnQCcuJGNvbmZpZ1sndGltZSddIDogJGNvbmZpZ1sndGltZSddOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRkYXRlID0gbmV3IFxEYXRlVGltZSgkdGltZSwgbmV3IFxEYXRlVGltZVpvbmUoJ1VUQycpKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRSZWxlYXNlRGF0ZSgkZGF0ZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydub3RpZmljYXRpb24tdXJsJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXROb3RpZmljYXRpb25VcmwoJGNvbmZpZ1snbm90aWZpY2F0aW9uLXVybCddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snYXJjaGl2ZSddWyduYW1lJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBcmNoaXZlTmFtZSgkY29uZmlnWydhcmNoaXZlJ11bJ25hbWUnXSk7CiAgICAgICAgfQogICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snYXJjaGl2ZSddWydleGNsdWRlJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlLT5zZXRBcmNoaXZlRXhjbHVkZXMoJGNvbmZpZ1snYXJjaGl2ZSddWydleGNsdWRlJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3NjcmlwdHMnXSkgJiYgXGlzX2FycmF5KCRjb25maWdbJ3NjcmlwdHMnXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJ3NjcmlwdHMnXSBhcyAkZXZlbnQgPT4gJGxpc3RlbmVycykgewogICAgICAgICAgICAgICAgICAgICRjb25maWdbJ3NjcmlwdHMnXVskZXZlbnRdID0gKGFycmF5KSAkbGlzdGVuZXJzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3NjcmlwdHMnXVsnY29tcG9zZXInXSkpIHsKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdUaGUgYGNvbXBvc2VyYCBzY3JpcHQgbmFtZSBpcyByZXNlcnZlZCBmb3IgaW50ZXJuYWwgdXNlLCBwbGVhc2UgYXZvaWQgZGVmaW5pbmcgaXQnLCBFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0U2NyaXB0cygkY29uZmlnWydzY3JpcHRzJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRjb25maWdbJ2Rlc2NyaXB0aW9uJ10pICYmIFxpc19zdHJpbmcoJGNvbmZpZ1snZGVzY3JpcHRpb24nXSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXREZXNjcmlwdGlvbigkY29uZmlnWydkZXNjcmlwdGlvbiddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydob21lcGFnZSddKSAmJiBcaXNfc3RyaW5nKCRjb25maWdbJ2hvbWVwYWdlJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0SG9tZXBhZ2UoJGNvbmZpZ1snaG9tZXBhZ2UnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1sna2V5d29yZHMnXSkgJiYgXGlzX2FycmF5KCRjb25maWdbJ2tleXdvcmRzJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0S2V5d29yZHMoJGNvbmZpZ1sna2V5d29yZHMnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbmZpZ1snbGljZW5zZSddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldExpY2Vuc2UoXGlzX2FycmF5KCRjb25maWdbJ2xpY2Vuc2UnXSkgPyAkY29uZmlnWydsaWNlbnNlJ10gOiBhcnJheSgkY29uZmlnWydsaWNlbnNlJ10pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydhdXRob3JzJ10pICYmIFxpc19hcnJheSgkY29uZmlnWydhdXRob3JzJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0QXV0aG9ycygkY29uZmlnWydhdXRob3JzJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snc3VwcG9ydCddKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFN1cHBvcnQoJGNvbmZpZ1snc3VwcG9ydCddKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkY29uZmlnWydmdW5kaW5nJ10pICYmIFxpc19hcnJheSgkY29uZmlnWydmdW5kaW5nJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0RnVuZGluZygkY29uZmlnWydmdW5kaW5nJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snYWJhbmRvbmVkJ10pKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0QWJhbmRvbmVkKCRjb25maWdbJ2FiYW5kb25lZCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5sb2FkT3B0aW9ucyAmJiBpc3NldCgkY29uZmlnWyd0cmFuc3BvcnQtb3B0aW9ucyddKSkgewogICAgICAgICAgICAkcGFja2FnZS0+c2V0VHJhbnNwb3J0T3B0aW9ucygkY29uZmlnWyd0cmFuc3BvcnQtb3B0aW9ucyddKTsKICAgICAgICB9CgogICAgICAgIGlmICgkYWxpYXNOb3JtYWxpemVkID0gJHRoaXMtPmdldEJyYW5jaEFsaWFzKCRjb25maWcpKSB7CiAgICAgICAgICAgICRwcmV0dHlBbGlhcyA9IHByZWdfcmVwbGFjZSgneyhcLjl7N30pK30nLCAnLngnLCAkYWxpYXNOb3JtYWxpemVkKTsKCiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJvb3RBbGlhc1BhY2thZ2UoJHBhY2thZ2UsICRhbGlhc05vcm1hbGl6ZWQsICRwcmV0dHlBbGlhcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgQWxpYXNQYWNrYWdlKCRwYWNrYWdlLCAkYWxpYXNOb3JtYWxpemVkLCAkcHJldHR5QWxpYXMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY29uZmlndXJlQ2FjaGVkTGlua3MoJiRsaW5rQ2FjaGUsICRwYWNrYWdlLCBhcnJheSAkY29uZmlnKQogICAgewogICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAkcHJldHR5VmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CgogICAgICAgIGZvcmVhY2ggKFBhY2thZ2VcQmFzZVBhY2thZ2U6OiRzdXBwb3J0ZWRMaW5rVHlwZXMgYXMgJHR5cGUgPT4gJG9wdHMpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJHR5cGVdKSkgewogICAgICAgICAgICAgICAgJG1ldGhvZCA9ICdzZXQnLnVjZmlyc3QoJG9wdHNbJ21ldGhvZCddKTsKCiAgICAgICAgICAgICAgICAkbGlua3MgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1skdHlwZV0gYXMgJHByZXR0eVRhcmdldCA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICR0YXJnZXQgPSBzdHJ0b2xvd2VyKCRwcmV0dHlUYXJnZXQpOwogICAgICAgICAgICAgICAgICAgIGlmICgkY29uc3RyYWludCA9PT0gJ3NlbGYudmVyc2lvbicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmtzWyR0YXJnZXRdID0gJHRoaXMtPmNyZWF0ZUxpbmsoJG5hbWUsICRwcmV0dHlWZXJzaW9uLCAkb3B0c1snZGVzY3JpcHRpb24nXSwgJHRhcmdldCwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGxpbmtDYWNoZVskbmFtZV1bJHR5cGVdWyR0YXJnZXRdWyRjb25zdHJhaW50XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5rQ2FjaGVbJG5hbWVdWyR0eXBlXVskdGFyZ2V0XVskY29uc3RyYWludF0gPSBhcnJheSgkdGFyZ2V0LCAkdGhpcy0+Y3JlYXRlTGluaygkbmFtZSwgJHByZXR0eVZlcnNpb24sICRvcHRzWydkZXNjcmlwdGlvbiddLCAkdGFyZ2V0LCAkY29uc3RyYWludCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBsaXN0KCR0YXJnZXQsICRsaW5rKSA9ICRsaW5rQ2FjaGVbJG5hbWVdWyR0eXBlXVskdGFyZ2V0XVskY29uc3RyYWludF07CiAgICAgICAgICAgICAgICAgICAgICAgICRsaW5rc1skdGFyZ2V0XSA9ICRsaW5rOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFja2FnZS0+eyRtZXRob2R9KCRsaW5rcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2UgICAgICAgIHNvdXJjZSBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZVZlcnNpb24gc291cmNlIHBhY2thZ2UgdmVyc2lvbiAocHJldHR5IHZlcnNpb24gaWRlYWxseSkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRlc2NyaXB0aW9uICAgbGluayBkZXNjcmlwdGlvbiAoZS5nLiByZXF1aXJlcywgcmVwbGFjZXMsIC4uKQogICAgICogQHBocHN0YW4tcGFyYW0gTGluazo6VFlQRV8qICRkZXNjcmlwdGlvbgogICAgICogQHBhcmFtICBhcnJheSAgJGxpbmtzIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBjb25zdHJhaW50IG1hcHBpbmdzCiAgICAgKiBAcmV0dXJuIExpbmtbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VMaW5rcygkc291cmNlLCAkc291cmNlVmVyc2lvbiwgJGRlc2NyaXB0aW9uLCAkbGlua3MpCiAgICB7CiAgICAgICAgJHJlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICR0YXJnZXQgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgJHJlc1tzdHJ0b2xvd2VyKCR0YXJnZXQpXSA9ICR0aGlzLT5jcmVhdGVMaW5rKCRzb3VyY2UsICRzb3VyY2VWZXJzaW9uLCAkZGVzY3JpcHRpb24sICR0YXJnZXQsICRjb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlTGluaygkc291cmNlLCAkc291cmNlVmVyc2lvbiwgJGRlc2NyaXB0aW9uLCAkdGFyZ2V0LCAkcHJldHR5Q29uc3RyYWludCkKICAgIHsKICAgICAgICBpZiAoIVxpc19zdHJpbmcoJHByZXR0eUNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdMaW5rIGNvbnN0cmFpbnQgaW4gJy4kc291cmNlLicgJy4kZGVzY3JpcHRpb24uJyA+ICcuJHRhcmdldC4nIHNob3VsZCBiZSBhIHN0cmluZywgZ290ICcuXGdldHR5cGUoJHByZXR0eUNvbnN0cmFpbnQpIC4gJyAoJyAuIHZhcl9leHBvcnQoJHByZXR0eUNvbnN0cmFpbnQsIHRydWUpIC4gJyknKTsKICAgICAgICB9CiAgICAgICAgaWYgKCdzZWxmLnZlcnNpb24nID09PSAkcHJldHR5Q29uc3RyYWludCkgewogICAgICAgICAgICAkcGFyc2VkQ29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRzb3VyY2VWZXJzaW9uKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFyc2VkQ29uc3RyYWludCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZUNvbnN0cmFpbnRzKCRwcmV0dHlDb25zdHJhaW50KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgTGluaygkc291cmNlLCAkdGFyZ2V0LCAkcGFyc2VkQ29uc3RyYWludCwgJGRlc2NyaXB0aW9uLCAkcHJldHR5Q29uc3RyYWludCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgYSBicmFuY2ggYWxpYXMgKGRldi1tYXN0ZXIgPT4gMS4wLngtZGV2IGZvciBleGFtcGxlKSBpZiBpdCBleGlzdHMKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICRjb25maWcgdGhlIGVudGlyZSBwYWNrYWdlIGNvbmZpZwogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIGJyYW5jaCBhbGlhcyBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaEFsaWFzKGFycmF5ICRjb25maWcpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkY29uZmlnWyd2ZXJzaW9uJ10sICdkZXYtJykgIT09IDAgJiYgJy1kZXYnICE9PSBzdWJzdHIoJGNvbmZpZ1sndmVyc2lvbiddLCAtNCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddKSAmJiBcaXNfYXJyYXkoJGNvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddIGFzICRzb3VyY2VCcmFuY2ggPT4gJHRhcmdldEJyYW5jaCkgewogICAgICAgICAgICAgICAgLy8gZW5zdXJlIGl0IGlzIGFuIGFsaWFzIHRvIGEgLWRldiBwYWNrYWdlCiAgICAgICAgICAgICAgICBpZiAoJy1kZXYnICE9PSBzdWJzdHIoJHRhcmdldEJyYW5jaCwgLTQpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbm9ybWFsaXplIHdpdGhvdXQgLWRldiBhbmQgZW5zdXJlIGl0J3MgYSBudW1lcmljIGJyYW5jaCB0aGF0IGlzIHBhcnNlYWJsZQogICAgICAgICAgICAgICAgaWYgKCR0YXJnZXRCcmFuY2ggPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRlZFRhcmdldEJyYW5jaCA9IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWRhdGVkVGFyZ2V0QnJhbmNoID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZUJyYW5jaChzdWJzdHIoJHRhcmdldEJyYW5jaCwgMCwgLTQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgnLWRldicgIT09IHN1YnN0cigkdmFsaWRhdGVkVGFyZ2V0QnJhbmNoLCAtNCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBlbnN1cmUgdGhhdCBpdCBpcyB0aGUgY3VycmVudCBicmFuY2ggYWxpYXNpbmcgaXRzZWxmCiAgICAgICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkY29uZmlnWyd2ZXJzaW9uJ10pICE9PSBzdHJ0b2xvd2VyKCRzb3VyY2VCcmFuY2gpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSWYgdXNpbmcgbnVtZXJpYyBhbGlhc2VzIGVuc3VyZSB0aGUgYWxpYXMgaXMgYSB2YWxpZCBzdWJ2ZXJzaW9uCiAgICAgICAgICAgICAgICBpZiAoKCRzb3VyY2VQcmVmaXggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJHNvdXJjZUJyYW5jaCkpCiAgICAgICAgICAgICAgICAgICAgJiYgKCR0YXJnZXRQcmVmaXggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJHRhcmdldEJyYW5jaCkpCiAgICAgICAgICAgICAgICAgICAgJiYgKHN0cmlwb3MoJHRhcmdldFByZWZpeCwgJHNvdXJjZVByZWZpeCkgIT09IDApCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbGlkYXRlZFRhcmdldEJyYW5jaDsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgICAgIGlmICgKICAgICAgICAgICAgaXNzZXQoJGNvbmZpZ1snZGVmYXVsdC1icmFuY2gnXSkKICAgICAgICAgICAgJiYgJGNvbmZpZ1snZGVmYXVsdC1icmFuY2gnXSA9PT0gdHJ1ZQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlTnVtZXJpY0FsaWFzUHJlZml4KCRjb25maWdbJ3ZlcnNpb24nXSkKICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCi8qKgogKiBEZWZpbmVzIGEgbG9hZGVyIHRoYXQgdGFrZXMgYW4gYXJyYXkgdG8gY3JlYXRlIHBhY2thZ2UgaW5zdGFuY2VzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmludGVyZmFjZSBMb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHBhY2thZ2UgZnJvbSBhbiBhcnJheSB0byBhIHJlYWwgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgUGFja2FnZSBjb25maWcKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2xhc3MgICBQYWNrYWdlIGNsYXNzIHRvIHVzZQogICAgICogQHJldHVybiBcQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKGFycmF5ICRwYWNrYWdlLCAkY2xhc3MgPSAnQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2UnKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBJbnZhbGlkUGFja2FnZUV4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24KewogICAgcHJpdmF0ZSAkZXJyb3JzOwogICAgcHJpdmF0ZSAkd2FybmluZ3M7CiAgICBwcml2YXRlICRkYXRhOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZXJyb3JzLCBhcnJheSAkd2FybmluZ3MsIGFycmF5ICRkYXRhKQogICAgewogICAgICAgICR0aGlzLT5lcnJvcnMgPSAkZXJyb3JzOwogICAgICAgICR0aGlzLT53YXJuaW5ncyA9ICR3YXJuaW5nczsKICAgICAgICAkdGhpcy0+ZGF0YSA9ICRkYXRhOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoIkludmFsaWQgcGFja2FnZSBpbmZvcm1hdGlvbjogXG4iLmltcGxvZGUoIlxuIiwgYXJyYXlfbWVyZ2UoJGVycm9ycywgJHdhcm5pbmdzKSkpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREYXRhKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRhdGE7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcnM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFdhcm5pbmdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPndhcm5pbmdzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUZhY3Rvcnk7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvbkd1ZXNzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CgovKioKICogQXJyYXlMb2FkZXIgYnVpbHQgZm9yIHRoZSBzb2xlIHB1cnBvc2Ugb2YgbG9hZGluZyB0aGUgcm9vdCBwYWNrYWdlCiAqCiAqIFNldHMgYWRkaXRpb25hbCBkZWZhdWx0cyBhbmQgbG9hZHMgcmVwb3NpdG9yaWVzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFJvb3RQYWNrYWdlTG9hZGVyIGV4dGVuZHMgQXJyYXlMb2FkZXIKewogICAgLyoqCiAgICAgKiBAdmFyIFJlcG9zaXRvcnlNYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJG1hbmFnZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIENvbmZpZwogICAgICovCiAgICBwcml2YXRlICRjb25maWc7CgogICAgLyoqCiAgICAgKiBAdmFyIFZlcnNpb25HdWVzc2VyCiAgICAgKi8KICAgIHByaXZhdGUgJHZlcnNpb25HdWVzc2VyOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZXBvc2l0b3J5TWFuYWdlciAkbWFuYWdlciwgQ29uZmlnICRjb25maWcsIFZlcnNpb25QYXJzZXIgJHBhcnNlciA9IG51bGwsIFZlcnNpb25HdWVzc2VyICR2ZXJzaW9uR3Vlc3NlciA9IG51bGwsIElPSW50ZXJmYWNlICRpbyA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcGFyc2VyKTsKCiAgICAgICAgJHRoaXMtPm1hbmFnZXIgPSAkbWFuYWdlcjsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+dmVyc2lvbkd1ZXNzZXIgPSAkdmVyc2lvbkd1ZXNzZXIgPzogbmV3IFZlcnNpb25HdWVzc2VyKCRjb25maWcsIG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKSwgJHRoaXMtPnZlcnNpb25QYXJzZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICAkY29uZmlnIHBhY2thZ2UgZGF0YQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAkY2xhc3MgIEZRQ04gdG8gYmUgaW5zdGFudGlhdGVkCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICRjd2QgICAgY3dkIG9mIHRoZSByb290IHBhY2thZ2UgdG8gYmUgdXNlZCB0byBndWVzcyB0aGUgdmVyc2lvbiBpZiBpdCBpcyBub3QgcHJvdmlkZWQKICAgICAqIEByZXR1cm4gUm9vdFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoYXJyYXkgJGNvbmZpZywgJGNsYXNzID0gJ0NvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2UnLCAkY3dkID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCRjb25maWdbJ25hbWUnXSkpIHsKICAgICAgICAgICAgJGNvbmZpZ1snbmFtZSddID0gJ19fcm9vdF9fJzsKICAgICAgICB9IGVsc2VpZiAoJGVyciA9IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6aGFzUGFja2FnZU5hbWluZ0Vycm9yKCRjb25maWdbJ25hbWUnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdZb3VyIHBhY2thZ2UgbmFtZSAnLiRlcnIpOwogICAgICAgIH0KICAgICAgICAkYXV0b1ZlcnNpb25lZCA9IGZhbHNlOwogICAgICAgIGlmICghaXNzZXQoJGNvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICAkY29tbWl0ID0gbnVsbDsKCiAgICAgICAgICAgIC8vIG92ZXJyaWRlIHdpdGggZW52IHZhciBpZiBhdmFpbGFibGUKICAgICAgICAgICAgaWYgKGdldGVudignQ09NUE9TRVJfUk9PVF9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ3ZlcnNpb24nXSA9IGdldGVudignQ09NUE9TRVJfUk9PVF9WRVJTSU9OJyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbkRhdGEgPSAkdGhpcy0+dmVyc2lvbkd1ZXNzZXItPmd1ZXNzVmVyc2lvbigkY29uZmlnLCAkY3dkID86IGdldGN3ZCgpKTsKICAgICAgICAgICAgICAgIGlmICgkdmVyc2lvbkRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWyd2ZXJzaW9uJ10gPSAkdmVyc2lvbkRhdGFbJ3ByZXR0eV92ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1sndmVyc2lvbl9ub3JtYWxpemVkJ10gPSAkdmVyc2lvbkRhdGFbJ3ZlcnNpb24nXTsKICAgICAgICAgICAgICAgICAgICAkY29tbWl0ID0gJHZlcnNpb25EYXRhWydjb21taXQnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFpc3NldCgkY29uZmlnWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWyd2ZXJzaW9uJ10gPSAnMS4wLjAnOwogICAgICAgICAgICAgICAgJGF1dG9WZXJzaW9uZWQgPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNvbW1pdCkgewogICAgICAgICAgICAgICAgJGNvbmZpZ1snc291cmNlJ10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAndHlwZScgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgJ3VybCcgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJGNvbW1pdCwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkY29uZmlnWydkaXN0J10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAndHlwZScgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgJ3VybCcgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJGNvbW1pdCwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyZWFsUGFja2FnZSA9ICRwYWNrYWdlID0gcGFyZW50Ojpsb2FkKCRjb25maWcsICRjbGFzcyk7CiAgICAgICAgaWYgKCRyZWFsUGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRhdXRvVmVyc2lvbmVkKSB7CiAgICAgICAgICAgICRyZWFsUGFja2FnZS0+cmVwbGFjZVZlcnNpb24oJHJlYWxQYWNrYWdlLT5nZXRWZXJzaW9uKCksIFJvb3RQYWNrYWdlOjpERUZBVUxUX1BSRVRUWV9WRVJTSU9OKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydtaW5pbXVtLXN0YWJpbGl0eSddKSkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UtPnNldE1pbmltdW1TdGFiaWxpdHkoVmVyc2lvblBhcnNlcjo6bm9ybWFsaXplU3RhYmlsaXR5KCRjb25maWdbJ21pbmltdW0tc3RhYmlsaXR5J10pKTsKICAgICAgICB9CgogICAgICAgICRhbGlhc2VzID0gYXJyYXkoKTsKICAgICAgICAkc3RhYmlsaXR5RmxhZ3MgPSBhcnJheSgpOwogICAgICAgICRyZWZlcmVuY2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoIChhcnJheSgncmVxdWlyZScsICdyZXF1aXJlLWRldicpIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1skbGlua1R5cGVdKSkgewogICAgICAgICAgICAgICAgJGxpbmtJbmZvID0gQmFzZVBhY2thZ2U6OiRzdXBwb3J0ZWRMaW5rVHlwZXNbJGxpbmtUeXBlXTsKICAgICAgICAgICAgICAgICRtZXRob2QgPSAnZ2V0Jy51Y2ZpcnN0KCRsaW5rSW5mb1snbWV0aG9kJ10pOwogICAgICAgICAgICAgICAgJGxpbmtzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZWFsUGFja2FnZS0+JG1ldGhvZCgpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmtzWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSAkbGluay0+Z2V0Q29uc3RyYWludCgpLT5nZXRQcmV0dHlTdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRhbGlhc2VzID0gJHRoaXMtPmV4dHJhY3RBbGlhc2VzKCRsaW5rcywgJGFsaWFzZXMpOwogICAgICAgICAgICAgICAgJHN0YWJpbGl0eUZsYWdzID0gJHRoaXMtPmV4dHJhY3RTdGFiaWxpdHlGbGFncygkbGlua3MsICRzdGFiaWxpdHlGbGFncywgJHJlYWxQYWNrYWdlLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCkpOwogICAgICAgICAgICAgICAgJHJlZmVyZW5jZXMgPSAkdGhpcy0+ZXh0cmFjdFJlZmVyZW5jZXMoJGxpbmtzLCAkcmVmZXJlbmNlcyk7CgogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRsaW5rc1skY29uZmlnWyduYW1lJ11dKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdSb290IHBhY2thZ2UgXCclc1wnIGNhbm5vdCByZXF1aXJlIGl0c2VsZiBpbiBpdHMgY29tcG9zZXIuanNvbicgLiBQSFBfRU9MIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRGlkIHlvdSBhY2NpZGVudGFsbHkgbmFtZSB5b3VyIHJvb3QgcGFja2FnZSBhZnRlciBhbiBleHRlcm5hbCBwYWNrYWdlPycsICRjb25maWdbJ25hbWUnXSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKEJhc2VQYWNrYWdlOjokc3VwcG9ydGVkTGlua1R5cGVzKSBhcyAkbGlua1R5cGUpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJGxpbmtUeXBlXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb25maWdbJGxpbmtUeXBlXSBhcyAkbGlua05hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGVyciA9IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6aGFzUGFja2FnZU5hbWluZ0Vycm9yKCRsaW5rTmFtZSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRsaW5rVHlwZS4nLicuJGVycik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmVhbFBhY2thZ2UtPnNldEFsaWFzZXMoJGFsaWFzZXMpOwogICAgICAgICRyZWFsUGFja2FnZS0+c2V0U3RhYmlsaXR5RmxhZ3MoJHN0YWJpbGl0eUZsYWdzKTsKICAgICAgICAkcmVhbFBhY2thZ2UtPnNldFJlZmVyZW5jZXMoJHJlZmVyZW5jZXMpOwoKICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1sncHJlZmVyLXN0YWJsZSddKSkgewogICAgICAgICAgICAkcmVhbFBhY2thZ2UtPnNldFByZWZlclN0YWJsZSgoYm9vbCkgJGNvbmZpZ1sncHJlZmVyLXN0YWJsZSddKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkY29uZmlnWydjb25maWcnXSkpIHsKICAgICAgICAgICAgJHJlYWxQYWNrYWdlLT5zZXRDb25maWcoJGNvbmZpZ1snY29uZmlnJ10pOwogICAgICAgIH0KCiAgICAgICAgJHJlcG9zID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcyhudWxsLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+bWFuYWdlcik7CiAgICAgICAgZm9yZWFjaCAoJHJlcG9zIGFzICRyZXBvKSB7CiAgICAgICAgICAgICR0aGlzLT5tYW5hZ2VyLT5hZGRSZXBvc2l0b3J5KCRyZXBvKTsKICAgICAgICB9CiAgICAgICAgJHJlYWxQYWNrYWdlLT5zZXRSZXBvc2l0b3JpZXMoJHRoaXMtPmNvbmZpZy0+Z2V0UmVwb3NpdG9yaWVzKCkpOwoKICAgICAgICByZXR1cm4gJHBhY2thZ2U7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBleHRyYWN0QWxpYXNlcyhhcnJheSAkcmVxdWlyZXMsIGFycmF5ICRhbGlhc2VzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxTmFtZSA9PiAkcmVxVmVyc2lvbikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oW14sXHMjXSspKD86I1teIF0rKT8gK2FzICsoW14sXHNdKykkfScsICRyZXFWZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAkYWxpYXNlc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ3BhY2thZ2UnID0+IHN0cnRvbG93ZXIoJHJlcU5hbWUpLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRtYXRjaFsxXSwgJHJlcVZlcnNpb24pLAogICAgICAgICAgICAgICAgICAgICdhbGlhcycgPT4gJG1hdGNoWzJdLAogICAgICAgICAgICAgICAgICAgICdhbGlhc19ub3JtYWxpemVkJyA9PiAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRtYXRjaFsyXSwgJHJlcVZlcnNpb24pLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlaWYgKHN0cnBvcygkcmVxVmVyc2lvbiwgJyBhcyAnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdJbnZhbGlkIGFsaWFzIGRlZmluaXRpb24gaW4gIicuJHJlcU5hbWUuJyI6ICInLiRyZXFWZXJzaW9uLiciLiBBbGlhc2VzIHNob3VsZCBiZSBpbiB0aGUgZm9ybSAiZXhhY3QtdmVyc2lvbiBhcyBvdGhlci1leGFjdC12ZXJzaW9uIi4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhbGlhc2VzOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdFN0YWJpbGl0eUZsYWdzKGFycmF5ICRyZXF1aXJlcywgYXJyYXkgJHN0YWJpbGl0eUZsYWdzLCAkbWluaW11bVN0YWJpbGl0eSkKICAgIHsKICAgICAgICAkc3RhYmlsaXRpZXMgPSBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzOwogICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHN0YWJpbGl0aWVzWyRtaW5pbXVtU3RhYmlsaXR5XTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcU5hbWUgPT4gJHJlcVZlcnNpb24pIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnRzID0gYXJyYXkoKTsKCiAgICAgICAgICAgIC8vIGV4dHJhY3QgYWxsIHN1Yi1jb25zdHJhaW50cyBpbiBjYXNlIGl0IGlzIGFuIE9SL0FORCBtdWx0aS1jb25zdHJhaW50CiAgICAgICAgICAgICRvclNwbGl0ID0gcHJlZ19zcGxpdCgne1xzKlx8XHw/XHMqfScsIHRyaW0oJHJlcVZlcnNpb24pKTsKICAgICAgICAgICAgZm9yZWFjaCAoJG9yU3BsaXQgYXMgJG9yQ29uc3RyYWludCkgewogICAgICAgICAgICAgICAgJGFuZFNwbGl0ID0gcHJlZ19zcGxpdCgneyg/PCFefGFzfFs9PjwgLF0pICooPzwhLSlbLCBdKD8hLSkgKig/ISx8YXN8JCl9JywgJG9yQ29uc3RyYWludCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYW5kU3BsaXQgYXMgJGFuZENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludHNbXSA9ICRhbmRDb25zdHJhaW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBwYXJzZSBleHBsaWNpdCBzdGFiaWxpdHkgZmxhZ3MgdG8gdGhlIG1vc3QgdW5zdGFibGUKICAgICAgICAgICAgJG1hdGNoID0gZmFsc2U7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teW15AXSo/QCgnLmltcGxvZGUoJ3wnLCBhcnJheV9rZXlzKCRzdGFiaWxpdGllcykpLicpJH1pJywgJGNvbnN0cmFpbnQsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJHJlcU5hbWUpOwogICAgICAgICAgICAgICAgICAgICRzdGFiaWxpdHkgPSAkc3RhYmlsaXRpZXNbVmVyc2lvblBhcnNlcjo6bm9ybWFsaXplU3RhYmlsaXR5KCRtYXRjaFsxXSldOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSkgJiYgJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSA+ICRzdGFiaWxpdHkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRzdGFiaWxpdHlGbGFnc1skbmFtZV0gPSAkc3RhYmlsaXR5OwogICAgICAgICAgICAgICAgICAgICRtYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbWF0Y2gpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkY29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIC8vIGluZmVyIGZsYWdzIGZvciByZXF1aXJlbWVudHMgdGhhdCBoYXZlIGFuIGV4cGxpY2l0IC1kZXYgb3IgLWJldGEgdmVyc2lvbiBzcGVjaWZpZWQgYnV0IG9ubHkKICAgICAgICAgICAgICAgIC8vIGZvciB0aG9zZSB0aGF0IGFyZSBtb3JlIHVuc3RhYmxlIHRoYW4gdGhlIG1pbmltdW1TdGFiaWxpdHkgb3IgZXhpc3RpbmcgZmxhZ3MKICAgICAgICAgICAgICAgICRyZXFWZXJzaW9uID0gcHJlZ19yZXBsYWNlKCd7XihbXixcc0BdKykgYXMgLiskfScsICckMScsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XlteLFxzQF0rJH0nLCAkcmVxVmVyc2lvbikgJiYgJ3N0YWJsZScgIT09ICgkc3RhYmlsaXR5TmFtZSA9IFZlcnNpb25QYXJzZXI6OnBhcnNlU3RhYmlsaXR5KCRyZXFWZXJzaW9uKSkpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJHJlcU5hbWUpOwogICAgICAgICAgICAgICAgICAgICRzdGFiaWxpdHkgPSAkc3RhYmlsaXRpZXNbJHN0YWJpbGl0eU5hbWVdOwogICAgICAgICAgICAgICAgICAgIGlmICgoaXNzZXQoJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSkgJiYgJHN0YWJpbGl0eUZsYWdzWyRuYW1lXSA+ICRzdGFiaWxpdHkpIHx8ICgkbWluaW11bVN0YWJpbGl0eSA+ICRzdGFiaWxpdHkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkc3RhYmlsaXR5RmxhZ3NbJG5hbWVdID0gJHN0YWJpbGl0eTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdGFiaWxpdHlGbGFnczsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RSZWZlcmVuY2VzKGFycmF5ICRyZXF1aXJlcywgYXJyYXkgJHJlZmVyZW5jZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVzIGFzICRyZXFOYW1lID0+ICRyZXFWZXJzaW9uKSB7CiAgICAgICAgICAgICRyZXFWZXJzaW9uID0gcHJlZ19yZXBsYWNlKCd7XihbXixcc0BdKykgYXMgLiskfScsICckMScsICRyZXFWZXJzaW9uKTsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teW14sXHNAXSs/IyhbYS1mMC05XSspJH0nLCAkcmVxVmVyc2lvbiwgJG1hdGNoKSAmJiAnZGV2JyA9PT0gVmVyc2lvblBhcnNlcjo6cGFyc2VTdGFiaWxpdHkoJHJlcVZlcnNpb24pKSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJHJlcU5hbWUpOwogICAgICAgICAgICAgICAgJHJlZmVyZW5jZXNbJG5hbWVdID0gJG1hdGNoWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlZmVyZW5jZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcU3BkeFxTcGR4TGljZW5zZXM7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmFsaWRhdGluZ0FycmF5TG9hZGVyIGltcGxlbWVudHMgTG9hZGVySW50ZXJmYWNlCnsKICAgIGNvbnN0IENIRUNLX0FMTCA9IDM7CiAgICBjb25zdCBDSEVDS19VTkJPVU5EX0NPTlNUUkFJTlRTID0gMTsKICAgIGNvbnN0IENIRUNLX1NUUklDVF9DT05TVFJBSU5UUyA9IDI7CgogICAgcHJpdmF0ZSAkbG9hZGVyOwogICAgcHJpdmF0ZSAkdmVyc2lvblBhcnNlcjsKICAgIHByaXZhdGUgJGVycm9yczsKICAgIHByaXZhdGUgJHdhcm5pbmdzOwogICAgcHJpdmF0ZSAkY29uZmlnOwogICAgcHJpdmF0ZSAkc3RyaWN0TmFtZTsKICAgIHByaXZhdGUgJGZsYWdzOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChMb2FkZXJJbnRlcmZhY2UgJGxvYWRlciwgJHN0cmljdE5hbWUgPSB0cnVlLCBWZXJzaW9uUGFyc2VyICRwYXJzZXIgPSBudWxsLCAkZmxhZ3MgPSAwKQogICAgewogICAgICAgICR0aGlzLT5sb2FkZXIgPSAkbG9hZGVyOwogICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyID0gJHBhcnNlciA/OiBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICR0aGlzLT5zdHJpY3ROYW1lID0gJHN0cmljdE5hbWU7CiAgICAgICAgJHRoaXMtPmZsYWdzID0gJGZsYWdzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkKGFycmF5ICRjb25maWcsICRjbGFzcyA9ICdDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZScpCiAgICB7CiAgICAgICAgJHRoaXMtPmVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPndhcm5pbmdzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKCiAgICAgICAgaWYgKCRlcnIgPSBzZWxmOjpoYXNQYWNrYWdlTmFtaW5nRXJyb3IoJGNvbmZpZ1snbmFtZSddKSkgewogICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdEZXByZWNhdGlvbiB3YXJuaW5nOiBZb3VyIHBhY2thZ2UgbmFtZSAnLiRlcnIuJyBNYWtlIHN1cmUgeW91IGZpeCB0aGlzIGFzIENvbXBvc2VyIDIuMCB3aWxsIGVycm9yLic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnN0cmljdE5hbWUpIHsKICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlUmVnZXgoJ25hbWUnLCAnW0EtWmEtejAtOV1bQS1aYS16MC05Xy4tXSovW0EtWmEtejAtOV1bQS1aYS16MC05Xy4tXSonLCB0cnVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ25hbWUnLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmNvbmZpZ1sndmVyc2lvbiddKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZSgkdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAndmVyc2lvbiA6IGludmFsaWQgdmFsdWUgKCcuJHRoaXMtPmNvbmZpZ1sndmVyc2lvbiddLicpOiAnLiRlLT5nZXRNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyd2ZXJzaW9uJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5jb25maWdbJ2NvbmZpZyddWydwbGF0Zm9ybSddKSkgewogICAgICAgICAgICBmb3JlYWNoICgoYXJyYXkpICR0aGlzLT5jb25maWdbJ2NvbmZpZyddWydwbGF0Zm9ybSddIGFzICRrZXkgPT4gJHBsYXRmb3JtKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHBsYXRmb3JtKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnY29uZmlnLnBsYXRmb3JtLicgLiAka2V5IC4gJyA6IGludmFsaWQgdmFsdWUgKCcuJHBsYXRmb3JtLicpOiAnLiRlLT5nZXRNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT52YWxpZGF0ZVJlZ2V4KCd0eXBlJywgJ1tBLVphLXowLTktXSsnKTsKICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ3RhcmdldC1kaXInKTsKICAgICAgICAkdGhpcy0+dmFsaWRhdGVBcnJheSgnZXh0cmEnKTsKCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJ2JpbiddKSkgewogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCR0aGlzLT5jb25maWdbJ2JpbiddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlU3RyaW5nKCdiaW4nKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZUZsYXRBcnJheSgnYmluJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT52YWxpZGF0ZUFycmF5KCdzY3JpcHRzJyk7IC8vIFRPRE8gdmFsaWRhdGUgZXZlbnQgbmFtZXMgJiBsaXN0ZW5lciBzeW50YXgKICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ2Rlc2NyaXB0aW9uJyk7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRlVXJsKCdob21lcGFnZScpOwogICAgICAgICR0aGlzLT52YWxpZGF0ZUZsYXRBcnJheSgna2V5d29yZHMnLCAnW1xwe059XHB7TH0gLl8tXSsnKTsKCiAgICAgICAgJHJlbGVhc2VEYXRlID0gbnVsbDsKICAgICAgICAkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ3RpbWUnKTsKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5jb25maWdbJ3RpbWUnXSkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRyZWxlYXNlRGF0ZSA9IG5ldyBcRGF0ZVRpbWUoJHRoaXMtPmNvbmZpZ1sndGltZSddLCBuZXcgXERhdGVUaW1lWm9uZSgnVVRDJykpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAndGltZSA6IGludmFsaWQgdmFsdWUgKCcuJHRoaXMtPmNvbmZpZ1sndGltZSddLicpOiAnLiRlLT5nZXRNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyd0aW1lJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBmb3IgbGljZW5zZSB2YWxpZGl0eSBvbiBuZXdseSB1cGRhdGVkIGJyYW5jaGVzCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJ2xpY2Vuc2UnXSkgJiYgKCEkcmVsZWFzZURhdGUgfHwgJHJlbGVhc2VEYXRlLT5nZXRUaW1lc3RhbXAoKSA+PSBzdHJ0b3RpbWUoJy04ZGF5cycpKSkgewogICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHRoaXMtPmNvbmZpZ1snbGljZW5zZSddKSB8fCBpc19zdHJpbmcoJHRoaXMtPmNvbmZpZ1snbGljZW5zZSddKSkgewogICAgICAgICAgICAgICAgJGxpY2Vuc2VzID0gKGFycmF5KSAkdGhpcy0+Y29uZmlnWydsaWNlbnNlJ107CgogICAgICAgICAgICAgICAgJGxpY2Vuc2VWYWxpZGF0b3IgPSBuZXcgU3BkeExpY2Vuc2VzKCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGljZW5zZXMgYXMgJGxpY2Vuc2UpIHsKICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHByb3ByaWV0YXJ5IGJ5IE1JVCBmb3IgdmFsaWRhdGlvbiBwdXJwb3NlcyBzaW5jZSBpdCdzIG5vdCBhIHZhbGlkIFNQRFggaWRlbnRpZmllciwgYnV0IGlzIGFjY2VwdGVkIGJ5IGNvbXBvc2VyCiAgICAgICAgICAgICAgICAgICAgaWYgKCdwcm9wcmlldGFyeScgPT09ICRsaWNlbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbGljZW5zZVRvVmFsaWRhdGUgPSBzdHJfcmVwbGFjZSgncHJvcHJpZXRhcnknLCAnTUlUJywgJGxpY2Vuc2UpOwogICAgICAgICAgICAgICAgICAgIGlmICghJGxpY2Vuc2VWYWxpZGF0b3ItPnZhbGlkYXRlKCRsaWNlbnNlVG9WYWxpZGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaWNlbnNlVmFsaWRhdG9yLT52YWxpZGF0ZSh0cmltKCRsaWNlbnNlVG9WYWxpZGF0ZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0xpY2Vuc2UgJXMgbXVzdCBub3QgY29udGFpbiBleHRyYSBzcGFjZXMsIG1ha2Ugc3VyZSB0byB0cmltIGl0LicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbl9lbmNvZGUoJGxpY2Vuc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdMaWNlbnNlICVzIGlzIG5vdCBhIHZhbGlkIFNQRFggbGljZW5zZSBpZGVudGlmaWVyLCBzZWUgaHR0cHM6Ly9zcGR4Lm9yZy9saWNlbnNlcy8gaWYgeW91IHVzZSBhbiBvcGVuIGxpY2Vuc2UuJyAuIFBIUF9FT0wgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJZiB0aGUgc29mdHdhcmUgaXMgY2xvc2VkLXNvdXJjZSwgeW91IG1heSB1c2UgInByb3ByaWV0YXJ5IiBhcyBsaWNlbnNlLicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbl9lbmNvZGUoJGxpY2Vuc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnZhbGlkYXRlQXJyYXkoJ2F1dGhvcnMnKSAmJiAhZW1wdHkoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ10gYXMgJGtleSA9PiAkYXV0aG9yKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRhdXRob3IpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJ2F1dGhvcnMuJy4ka2V5LicgOiBzaG91bGQgYmUgYW4gYXJyYXksICcuZ2V0dHlwZSgkYXV0aG9yKS4nIGdpdmVuJzsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydhdXRob3JzJ11bJGtleV0pOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ2hvbWVwYWdlJywgJ2VtYWlsJywgJ25hbWUnLCAncm9sZScpIGFzICRhdXRob3JEYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhdXRob3JbJGF1dGhvckRhdGFdKSAmJiAhaXNfc3RyaW5nKCRhdXRob3JbJGF1dGhvckRhdGFdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnYXV0aG9ycy4nLiRrZXkuJy4nLiRhdXRob3JEYXRhLicgOiBpbnZhbGlkIHZhbHVlLCBtdXN0IGJlIGEgc3RyaW5nJzsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddWyRrZXldWyRhdXRob3JEYXRhXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhdXRob3JbJ2hvbWVwYWdlJ10pICYmICEkdGhpcy0+ZmlsdGVyVXJsKCRhdXRob3JbJ2hvbWVwYWdlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnYXV0aG9ycy4nLiRrZXkuJy5ob21lcGFnZSA6IGludmFsaWQgdmFsdWUgKCcuJGF1dGhvclsnaG9tZXBhZ2UnXS4nKSwgbXVzdCBiZSBhbiBodHRwL2h0dHBzIFVSTCc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddWyRrZXldWydob21lcGFnZSddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYXV0aG9yWydlbWFpbCddKSAmJiAhZmlsdGVyX3ZhcigkYXV0aG9yWydlbWFpbCddLCBGSUxURVJfVkFMSURBVEVfRU1BSUwpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnYXV0aG9ycy4nLiRrZXkuJy5lbWFpbCA6IGludmFsaWQgdmFsdWUgKCcuJGF1dGhvclsnZW1haWwnXS4nKSwgbXVzdCBiZSBhIHZhbGlkIGVtYWlsIGFkZHJlc3MnOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXVska2V5XVsnZW1haWwnXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbmZpZ1snYXV0aG9ycyddWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2F1dGhvcnMnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnc3VwcG9ydCcpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCdpc3N1ZXMnLCAnZm9ydW0nLCAnd2lraScsICdzb3VyY2UnLCAnZW1haWwnLCAnaXJjJywgJ2RvY3MnLCAncnNzJywgJ2NoYXQnKSBhcyAka2V5KSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWyRrZXldKSAmJiAhaXNfc3RyaW5nKCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnc3VwcG9ydC4nLiRrZXkuJyA6IGludmFsaWQgdmFsdWUsIG11c3QgYmUgYSBzdHJpbmcnOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2VtYWlsJ10pICYmICFmaWx0ZXJfdmFyKCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnZW1haWwnXSwgRklMVEVSX1ZBTElEQVRFX0VNQUlMKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnc3VwcG9ydC5lbWFpbCA6IGludmFsaWQgdmFsdWUgKCcuJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWydlbWFpbCddLicpLCBtdXN0IGJlIGEgdmFsaWQgZW1haWwgYWRkcmVzcyc7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJ2VtYWlsJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWydpcmMnXSkgJiYgISR0aGlzLT5maWx0ZXJVcmwoJHRoaXMtPmNvbmZpZ1snc3VwcG9ydCddWydpcmMnXSwgYXJyYXkoJ2lyYycpKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnc3VwcG9ydC5pcmMgOiBpbnZhbGlkIHZhbHVlICgnLiR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnaXJjJ10uJyksIG11c3QgYmUgYSBpcmM6Ly88c2VydmVyPi88Y2hhbm5lbD4gVVJMJzsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVsnaXJjJ10pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgnaXNzdWVzJywgJ2ZvcnVtJywgJ3dpa2knLCAnc291cmNlJywgJ2RvY3MnLCAnY2hhdCcpIGFzICRrZXkpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJGtleV0pICYmICEkdGhpcy0+ZmlsdGVyVXJsKCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdzdXBwb3J0LicuJGtleS4nIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWydzdXBwb3J0J11bJGtleV0uJyksIG11c3QgYmUgYW4gaHR0cC9odHRwcyBVUkwnOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ3N1cHBvcnQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnZnVuZGluZycpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydmdW5kaW5nJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSBhcyAka2V5ID0+ICRmdW5kaW5nT3B0aW9uKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRmdW5kaW5nT3B0aW9uKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdmdW5kaW5nLicuJGtleS4nIDogc2hvdWxkIGJlIGFuIGFycmF5LCAnLmdldHR5cGUoJGZ1bmRpbmdPcHRpb24pLicgZ2l2ZW4nOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgndHlwZScsICd1cmwnKSBhcyAkZnVuZGluZ0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGZ1bmRpbmdPcHRpb25bJGZ1bmRpbmdEYXRhXSkgJiYgIWlzX3N0cmluZygkZnVuZGluZ09wdGlvblskZnVuZGluZ0RhdGFdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnZnVuZGluZy4nLiRrZXkuJy4nLiRmdW5kaW5nRGF0YS4nIDogaW52YWxpZCB2YWx1ZSwgbXVzdCBiZSBhIHN0cmluZyc7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XVskZnVuZGluZ0RhdGFdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGZ1bmRpbmdPcHRpb25bJ3VybCddKSAmJiAhJHRoaXMtPmZpbHRlclVybCgkZnVuZGluZ09wdGlvblsndXJsJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnZnVuZGluZy4nLiRrZXkuJy51cmwgOiBpbnZhbGlkIHZhbHVlICgnLiRmdW5kaW5nT3B0aW9uWyd1cmwnXS4nKSwgbXVzdCBiZSBhbiBodHRwL2h0dHBzIFVSTCc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snZnVuZGluZyddWyRrZXldWyd1cmwnXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbmZpZ1snZnVuZGluZyddWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2Z1bmRpbmcnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR1bmJvdW5kQ29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9JywgJzEwMDAwMDAwLWRldicpOwogICAgICAgICRzdGFibGVDb25zdHJhaW50ID0gbmV3IENvbnN0cmFpbnQoJz0nLCAnMS4wLjAnKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlcykgYXMgJGxpbmtUeXBlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgkbGlua1R5cGUpICYmIGlzc2V0KCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXSBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZXJyID0gc2VsZjo6aGFzUGFja2FnZU5hbWluZ0Vycm9yKCRwYWNrYWdlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdEZXByZWNhdGlvbiB3YXJuaW5nOiAnLiRsaW5rVHlwZS4nLicuJGVyci4nIE1ha2Ugc3VyZSB5b3UgZml4IHRoaXMgYXMgQ29tcG9zZXIgMi4wIHdpbGwgZXJyb3IuJzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoIXByZWdfbWF0Y2goJ3teW0EtWmEtejAtOV8uLy1dKyR9JywgJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogaW52YWxpZCBrZXksIHBhY2thZ2UgbmFtZXMgbXVzdCBiZSBzdHJpbmdzIGNvbnRhaW5pbmcgb25seSBbQS1aYS16MC05Xy4vLV0nOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJGxpbmtUeXBlLicuJy4kcGFja2FnZS4nIDogaW52YWxpZCB2YWx1ZSwgbXVzdCBiZSBhIHN0cmluZyBjb250YWluaW5nIGEgdmVyc2lvbiBjb25zdHJhaW50JzsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skbGlua1R5cGVdWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCdzZWxmLnZlcnNpb24nICE9PSAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmtDb25zdHJhaW50ID0gJHRoaXMtPnZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkbGlua1R5cGUuJy4nLiRwYWNrYWdlLicgOiBpbnZhbGlkIHZlcnNpb24gY29uc3RyYWludCAoJy4kZS0+Z2V0TWVzc2FnZSgpLicpJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJGxpbmtUeXBlXVskcGFja2FnZV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHJlcXVpcmVzIGZvciB1bmJvdW5kIGNvbnN0cmFpbnRzIG9uIG5vbi1wbGF0Zm9ybSBwYWNrYWdlcwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJHRoaXMtPmZsYWdzICYgc2VsZjo6Q0hFQ0tfVU5CT1VORF9DT05TVFJBSU5UUykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICdyZXF1aXJlJyA9PT0gJGxpbmtUeXBlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAkbGlua0NvbnN0cmFpbnQtPm1hdGNoZXMoJHVuYm91bmRDb25zdHJhaW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIVBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHBhY2thZ2UpCiAgICAgICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAkbGlua1R5cGUuJy4nLiRwYWNrYWdlLicgOiB1bmJvdW5kIHZlcnNpb24gY29uc3RyYWludHMgKCcuJGNvbnN0cmFpbnQuJykgc2hvdWxkIGJlIGF2b2lkZWQnOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayByZXF1aXJlcyBmb3IgZXhhY3QgY29uc3RyYWludHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgkdGhpcy0+ZmxhZ3MgJiBzZWxmOjpDSEVDS19TVFJJQ1RfQ09OU1RSQUlOVFMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAncmVxdWlyZScgPT09ICRsaW5rVHlwZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc3RycG9zKCRsaW5rQ29uc3RyYWludCwgJz0nKSA9PT0gMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgJHN0YWJsZUNvbnN0cmFpbnQtPnZlcnNpb25Db21wYXJlKCRzdGFibGVDb25zdHJhaW50LCAkbGlua0NvbnN0cmFpbnQsICc8PScpCiAgICAgICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAkbGlua1R5cGUuJy4nLiRwYWNrYWdlLicgOiBleGFjdCB2ZXJzaW9uIGNvbnN0cmFpbnRzICgnLiRjb25zdHJhaW50LicpIHNob3VsZCBiZSBhdm9pZGVkIGlmIHRoZSBwYWNrYWdlIGZvbGxvd3Mgc2VtYW50aWMgdmVyc2lvbmluZyc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnc3VnZ2VzdCcpICYmICFlbXB0eSgkdGhpcy0+Y29uZmlnWydzdWdnZXN0J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJ3N1Z2dlc3QnXSBhcyAkcGFja2FnZSA9PiAkZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCRkZXNjcmlwdGlvbikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAnc3VnZ2VzdC4nLiRwYWNrYWdlLicgOiBpbnZhbGlkIHZhbHVlLCBtdXN0IGJlIGEgc3RyaW5nIGRlc2NyaWJpbmcgd2h5IHRoZSBwYWNrYWdlIGlzIHN1Z2dlc3RlZCc7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snc3VnZ2VzdCddWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVTdHJpbmcoJ21pbmltdW0tc3RhYmlsaXR5JykgJiYgIWVtcHR5KCR0aGlzLT5jb25maWdbJ21pbmltdW0tc3RhYmlsaXR5J10pKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skdGhpcy0+Y29uZmlnWydtaW5pbXVtLXN0YWJpbGl0eSddXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICdtaW5pbXVtLXN0YWJpbGl0eSA6IGludmFsaWQgdmFsdWUgKCcuJHRoaXMtPmNvbmZpZ1snbWluaW11bS1zdGFiaWxpdHknXS4nKSwgbXVzdCBiZSBvbmUgb2YgJy5pbXBsb2RlKCcsICcsIGFycmF5X2tleXMoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllcykpOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snbWluaW11bS1zdGFiaWxpdHknXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBcnJheSgnYXV0b2xvYWQnKSAmJiAhZW1wdHkoJHRoaXMtPmNvbmZpZ1snYXV0b2xvYWQnXSkpIHsKICAgICAgICAgICAgJHR5cGVzID0gYXJyYXkoJ3Bzci0wJywgJ3Bzci00JywgJ2NsYXNzbWFwJywgJ2ZpbGVzJywgJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCcpOwogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uZmlnWydhdXRvbG9hZCddIGFzICR0eXBlID0+ICR0eXBlQ29uZmlnKSB7CiAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCR0eXBlLCAkdHlwZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJ2F1dG9sb2FkIDogaW52YWxpZCB2YWx1ZSAoJy4kdHlwZS4nKSwgbXVzdCBiZSBvbmUgb2YgJy5pbXBsb2RlKCcsICcsICR0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1snYXV0b2xvYWQnXVskdHlwZV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0eXBlID09PSAncHNyLTQnKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHR5cGVDb25maWcgYXMgJG5hbWVzcGFjZSA9PiAkZGlycykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5hbWVzcGFjZSAhPT0gJycgJiYgJ1xcJyAhPT0gc3Vic3RyKCRuYW1lc3BhY2UsIC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJ2F1dG9sb2FkLnBzci00IDogaW52YWxpZCB2YWx1ZSAoJy4kbmFtZXNwYWNlLicpLCBuYW1lc3BhY2VzIG11c3QgZW5kIHdpdGggYSBuYW1lc3BhY2Ugc2VwYXJhdG9yLCBzaG91bGQgYmUgJy4kbmFtZXNwYWNlLidcXFxcJzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+Y29uZmlnWydhdXRvbG9hZCddWydwc3ItNCddKSAmJiAhZW1wdHkoJHRoaXMtPmNvbmZpZ1sndGFyZ2V0LWRpciddKSkgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAndGFyZ2V0LWRpciA6IHRoaXMgY2FuIG5vdCBiZSB1c2VkIHRvZ2V0aGVyIHdpdGggdGhlIGF1dG9sb2FkLnBzci00IHNldHRpbmcsIHJlbW92ZSB0YXJnZXQtZGlyIHRvIHVwZ3JhZGUgdG8gcHNyLTQnOwogICAgICAgICAgICAvLyBVbnNldCB0aGUgcHNyLTQgc2V0dGluZywgc2luY2UgdW5zZXR0aW5nIHRhcmdldC1kaXIgbWlnaHQKICAgICAgICAgICAgLy8gaW50ZXJmZXJlIHdpdGggb3RoZXIgc2V0dGluZ3MuCiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2F1dG9sb2FkJ11bJ3Bzci00J10pOwogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETyB2YWxpZGF0ZSBkaXN0CiAgICAgICAgLy8gVE9ETyB2YWxpZGF0ZSBzb3VyY2UKCiAgICAgICAgLy8gVE9ETyB2YWxpZGF0ZSByZXBvc2l0b3JpZXMKICAgICAgICAvLyBUT0RPIHZhbGlkYXRlIHBhY2thZ2UgcmVwb3NpdG9yaWVzJyBwYWNrYWdlcyB1c2luZyB0aGlzIHJlY3Vyc2l2ZWx5CgogICAgICAgICR0aGlzLT52YWxpZGF0ZUZsYXRBcnJheSgnaW5jbHVkZS1wYXRoJyk7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRlQXJyYXkoJ3RyYW5zcG9ydC1vcHRpb25zJyk7CgogICAgICAgIC8vIGJyYW5jaCBhbGlhcyB2YWxpZGF0aW9uCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddKSkgewogICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR0aGlzLT5jb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yc1tdID0gJ2V4dHJhLmJyYW5jaC1hbGlhcyA6IG11c3QgYmUgYW4gYXJyYXkgb2YgdmVyc2lvbnMgPT4gYWxpYXNlcyc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXSBhcyAkc291cmNlQnJhbmNoID0+ICR0YXJnZXRCcmFuY2gpIHsKICAgICAgICAgICAgICAgICAgICAvLyBlbnN1cmUgaXQgaXMgYW4gYWxpYXMgdG8gYSAtZGV2IHBhY2thZ2UKICAgICAgICAgICAgICAgICAgICBpZiAoJy1kZXYnICE9PSBzdWJzdHIoJHRhcmdldEJyYW5jaCwgLTQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJ2V4dHJhLmJyYW5jaC1hbGlhcy4nLiRzb3VyY2VCcmFuY2guJyA6IHRoZSB0YXJnZXQgYnJhbmNoICgnLiR0YXJnZXRCcmFuY2guJykgbXVzdCBlbmQgaW4gLWRldic7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddWyRzb3VyY2VCcmFuY2hdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gbm9ybWFsaXplIHdpdGhvdXQgLWRldiBhbmQgZW5zdXJlIGl0J3MgYSBudW1lcmljIGJyYW5jaCB0aGF0IGlzIHBhcnNlYWJsZQogICAgICAgICAgICAgICAgICAgICR2YWxpZGF0ZWRUYXJnZXRCcmFuY2ggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplQnJhbmNoKHN1YnN0cigkdGFyZ2V0QnJhbmNoLCAwLCAtNCkpOwogICAgICAgICAgICAgICAgICAgIGlmICgnLWRldicgIT09IHN1YnN0cigkdmFsaWRhdGVkVGFyZ2V0QnJhbmNoLCAtNCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhcm5pbmdzW10gPSAnZXh0cmEuYnJhbmNoLWFsaWFzLicuJHNvdXJjZUJyYW5jaC4nIDogdGhlIHRhcmdldCBicmFuY2ggKCcuJHRhcmdldEJyYW5jaC4nKSBtdXN0IGJlIGEgcGFyc2VhYmxlIG51bWJlciBsaWtlIDIuMC1kZXYnOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXVskc291cmNlQnJhbmNoXSk7CgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIElmIHVzaW5nIG51bWVyaWMgYWxpYXNlcyBlbnN1cmUgdGhlIGFsaWFzIGlzIGEgdmFsaWQgc3VidmVyc2lvbgogICAgICAgICAgICAgICAgICAgIGlmICgoJHNvdXJjZVByZWZpeCA9ICR0aGlzLT52ZXJzaW9uUGFyc2VyLT5wYXJzZU51bWVyaWNBbGlhc1ByZWZpeCgkc291cmNlQnJhbmNoKSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCR0YXJnZXRQcmVmaXggPSAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJHRhcmdldEJyYW5jaCkpCiAgICAgICAgICAgICAgICAgICAgICAgICYmIChzdHJpcG9zKCR0YXJnZXRQcmVmaXgsICRzb3VyY2VQcmVmaXgpICE9PSAwKQogICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2FybmluZ3NbXSA9ICdleHRyYS5icmFuY2gtYWxpYXMuJy4kc291cmNlQnJhbmNoLicgOiB0aGUgdGFyZ2V0IGJyYW5jaCAoJy4kdGFyZ2V0QnJhbmNoLicpIGlzIG5vdCBhIHZhbGlkIG51bWVyaWMgYWxpYXMgZm9yIHRoaXMgdmVyc2lvbic7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJ2V4dHJhJ11bJ2JyYW5jaC1hbGlhcyddWyRzb3VyY2VCcmFuY2hdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZXJyb3JzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFja2FnZUV4Y2VwdGlvbigkdGhpcy0+ZXJyb3JzLCAkdGhpcy0+d2FybmluZ3MsICRjb25maWcpOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+bG9hZGVyLT5sb2FkKCR0aGlzLT5jb25maWcsICRjbGFzcyk7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9IG51bGw7CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0V2FybmluZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+d2FybmluZ3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcnM7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYXNQYWNrYWdlTmFtaW5nRXJyb3IoJG5hbWUsICRpc0xpbmsgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkbmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XlthLXowLTldKD86W18uLV0/W2EtejAtOV0rKSovW2EtejAtOV0oPzooPzpbXy5dP3wtezAsMn0pW2EtejAtOV0rKSokfWlEJywgJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkbmFtZS4nIGlzIGludmFsaWQsIGl0IHNob3VsZCBoYXZlIGEgdmVuZG9yIG5hbWUsIGEgZm9yd2FyZCBzbGFzaCwgYW5kIGEgcGFja2FnZSBuYW1lLiBUaGUgdmVuZG9yIGFuZCBwYWNrYWdlIG5hbWUgY2FuIGJlIHdvcmRzIHNlcGFyYXRlZCBieSAtLCAuIG9yIF8uIFRoZSBjb21wbGV0ZSBuYW1lIHNob3VsZCBtYXRjaCAiXlthLXowLTldKFtfLi1dP1thLXowLTldKykqL1thLXowLTldKChbXy5dP3wtezAsMn0pW2EtejAtOV0rKSokIi4nOwogICAgICAgIH0KCiAgICAgICAgJHJlc2VydmVkTmFtZXMgPSBhcnJheSgnbnVsJywgJ2NvbicsICdwcm4nLCAnYXV4JywgJ2NvbTEnLCAnY29tMicsICdjb20zJywgJ2NvbTQnLCAnY29tNScsICdjb202JywgJ2NvbTcnLCAnY29tOCcsICdjb205JywgJ2xwdDEnLCAnbHB0MicsICdscHQzJywgJ2xwdDQnLCAnbHB0NScsICdscHQ2JywgJ2xwdDcnLCAnbHB0OCcsICdscHQ5Jyk7CiAgICAgICAgJGJpdHMgPSBleHBsb2RlKCcvJywgc3RydG9sb3dlcigkbmFtZSkpOwogICAgICAgIGlmIChpbl9hcnJheSgkYml0c1swXSwgJHJlc2VydmVkTmFtZXMsIHRydWUpIHx8IGluX2FycmF5KCRiaXRzWzFdLCAkcmVzZXJ2ZWROYW1lcywgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICRuYW1lLicgaXMgcmVzZXJ2ZWQsIHBhY2thZ2UgYW5kIHZlbmRvciBuYW1lcyBjYW4gbm90IG1hdGNoIGFueSBvZjogJy5pbXBsb2RlKCcsICcsICRyZXNlcnZlZE5hbWVzKS4nLic7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJlZ19tYXRjaCgne1wuanNvbiR9JywgJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkbmFtZS4nIGlzIGludmFsaWQsIHBhY2thZ2UgbmFtZXMgY2FuIG5vdCBlbmQgaW4gLmpzb24sIGNvbnNpZGVyIHJlbmFtaW5nIGl0IG9yIHBlcmhhcHMgdXNpbmcgYSAtanNvbiBzdWZmaXggaW5zdGVhZC4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tbQS1aXX0nLCAkbmFtZSkpIHsKICAgICAgICAgICAgaWYgKCRpc0xpbmspIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbmFtZS4nIGlzIGludmFsaWQsIGl0IHNob3VsZCBub3QgY29udGFpbiB1cHBlcmNhc2UgY2hhcmFjdGVycy4gUGxlYXNlIHVzZSAnLnN0cnRvbG93ZXIoJG5hbWUpLicgaW5zdGVhZC4nOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc3VnZ2VzdE5hbWUgPSBwcmVnX3JlcGxhY2UoJ3soPzooW2Etel0pKFtBLVpdKXwoW0EtWl0pKFtBLVpdW2Etel0pKX0nLCAnXFwxXFwzLVxcMlxcNCcsICRuYW1lKTsKICAgICAgICAgICAgJHN1Z2dlc3ROYW1lID0gc3RydG9sb3dlcigkc3VnZ2VzdE5hbWUpOwoKICAgICAgICAgICAgcmV0dXJuICRuYW1lLicgaXMgaW52YWxpZCwgaXQgc2hvdWxkIG5vdCBjb250YWluIHVwcGVyY2FzZSBjaGFyYWN0ZXJzLiBXZSBzdWdnZXN0IHVzaW5nICcuJHN1Z2dlc3ROYW1lLicgaW5zdGVhZC4nOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlUmVnZXgoJHByb3BlcnR5LCAkcmVnZXgsICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZVN0cmluZygkcHJvcGVydHksICRtYW5kYXRvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghcHJlZ19tYXRjaCgne14nLiRyZWdleC4nJH11JywgJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICRwcm9wZXJ0eS4nIDogaW52YWxpZCB2YWx1ZSAoJy4kdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0uJyksIG11c3QgbWF0Y2ggJy4kcmVnZXg7CiAgICAgICAgICAgIGlmICgkbWFuZGF0b3J5KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJG1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVTdHJpbmcoJHByb3BlcnR5LCAkbWFuZGF0b3J5ID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkgJiYgIWlzX3N0cmluZygkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRwcm9wZXJ0eS4nIDogc2hvdWxkIGJlIGEgc3RyaW5nLCAnLmdldHR5cGUoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKS4nIGdpdmVuJzsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSB8fCB0cmltKCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkgPT09ICcnKSB7CiAgICAgICAgICAgIGlmICgkbWFuZGF0b3J5KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkcHJvcGVydHkuJyA6IG11c3QgYmUgcHJlc2VudCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVBcnJheSgkcHJvcGVydHksICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSAmJiAhaXNfYXJyYXkoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldKSkgewogICAgICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkcHJvcGVydHkuJyA6IHNob3VsZCBiZSBhbiBhcnJheSwgJy5nZXR0eXBlKCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkuJyBnaXZlbic7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkgfHwgIWNvdW50KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSkpIHsKICAgICAgICAgICAgaWYgKCRtYW5kYXRvcnkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRwcm9wZXJ0eS4nIDogbXVzdCBiZSBwcmVzZW50IGFuZCBjb250YWluIGF0IGxlYXN0IG9uZSBlbGVtZW50JzsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZUZsYXRBcnJheSgkcHJvcGVydHksICRyZWdleCA9IG51bGwsICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZUFycmF5KCRwcm9wZXJ0eSwgJG1hbmRhdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHBhc3MgPSB0cnVlOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkdmFsdWUpICYmICFpc19udW1lcmljKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnNbXSA9ICRwcm9wZXJ0eS4nLicuJGtleS4nIDogbXVzdCBiZSBhIHN0cmluZyBvciBpbnQsICcuZ2V0dHlwZSgkdmFsdWUpLicgZ2l2ZW4nOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmNvbmZpZ1skcHJvcGVydHldWyRrZXldKTsKICAgICAgICAgICAgICAgICRwYXNzID0gZmFsc2U7CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkcmVnZXggJiYgIXByZWdfbWF0Y2goJ3teJy4kcmVnZXguJyR9dScsICR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJHByb3BlcnR5LicuJy4ka2V5LicgOiBpbnZhbGlkIHZhbHVlICgnLiR2YWx1ZS4nKSwgbXVzdCBtYXRjaCAnLiRyZWdleDsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XVska2V5XSk7CiAgICAgICAgICAgICAgICAkcGFzcyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhc3M7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZVVybCgkcHJvcGVydHksICRtYW5kYXRvcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZVN0cmluZygkcHJvcGVydHksICRtYW5kYXRvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPmZpbHRlclVybCgkdGhpcy0+Y29uZmlnWyRwcm9wZXJ0eV0pKSB7CiAgICAgICAgICAgICR0aGlzLT53YXJuaW5nc1tdID0gJHByb3BlcnR5LicgOiBpbnZhbGlkIHZhbHVlICgnLiR0aGlzLT5jb25maWdbJHByb3BlcnR5XS4nKSwgbXVzdCBiZSBhbiBodHRwL2h0dHBzIFVSTCc7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb25maWdbJHByb3BlcnR5XSk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbHRlclVybCgkdmFsdWUsIGFycmF5ICRzY2hlbWVzID0gYXJyYXkoJ2h0dHAnLCAnaHR0cHMnKSkKICAgIHsKICAgICAgICBpZiAoJHZhbHVlID09PSAnJykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRiaXRzID0gcGFyc2VfdXJsKCR2YWx1ZSk7CiAgICAgICAgaWYgKGVtcHR5KCRiaXRzWydzY2hlbWUnXSkgfHwgZW1wdHkoJGJpdHNbJ2hvc3QnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpbl9hcnJheSgkYml0c1snc2NoZW1lJ10sICRzY2hlbWVzLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQYWNrYWdlXExvYWRlcjsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwoKLyoqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaGl2IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBKc29uTG9hZGVyCnsKICAgIHByaXZhdGUgJGxvYWRlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTG9hZGVySW50ZXJmYWNlICRsb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvYWRlciA9ICRsb2FkZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xKc29uRmlsZSAgICAgICAgICAgICAgICAgICAgJGpzb24gQSBmaWxlbmFtZSwganNvbiBzdHJpbmcgb3IgSnNvbkZpbGUgaW5zdGFuY2UgdG8gbG9hZCB0aGUgcGFja2FnZSBmcm9tCiAgICAgKiBAcmV0dXJuIFxDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWQoJGpzb24pCiAgICB7CiAgICAgICAgaWYgKCRqc29uIGluc3RhbmNlb2YgSnNvbkZpbGUpIHsKICAgICAgICAgICAgJGNvbmZpZyA9ICRqc29uLT5yZWFkKCk7CiAgICAgICAgfSBlbHNlaWYgKGZpbGVfZXhpc3RzKCRqc29uKSkgewogICAgICAgICAgICAkY29uZmlnID0gSnNvbkZpbGU6OnBhcnNlSnNvbihmaWxlX2dldF9jb250ZW50cygkanNvbiksICRqc29uKTsKICAgICAgICB9IGVsc2VpZiAoaXNfc3RyaW5nKCRqc29uKSkgewogICAgICAgICAgICAkY29uZmlnID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkanNvbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICJKc29uTG9hZGVyOiBVbmtub3duIFwkanNvbiBwYXJhbWV0ZXIgJXMuIFBsZWFzZSByZXBvcnQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy9uZXcuIiwKICAgICAgICAgICAgICAgIGdldHR5cGUoJGpzb24pCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2FkZXItPmxvYWQoJGNvbmZpZyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZVxEdW1wZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hpdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBBcnJheUR1bXBlcgp7CiAgICBwdWJsaWMgZnVuY3Rpb24gZHVtcChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRrZXlzID0gYXJyYXkoCiAgICAgICAgICAgICdiaW5hcmllcycgPT4gJ2JpbicsCiAgICAgICAgICAgICd0eXBlJywKICAgICAgICAgICAgJ2V4dHJhJywKICAgICAgICAgICAgJ2luc3RhbGxhdGlvblNvdXJjZScgPT4gJ2luc3RhbGxhdGlvbi1zb3VyY2UnLAogICAgICAgICAgICAnYXV0b2xvYWQnLAogICAgICAgICAgICAnZGV2QXV0b2xvYWQnID0+ICdhdXRvbG9hZC1kZXYnLAogICAgICAgICAgICAnbm90aWZpY2F0aW9uVXJsJyA9PiAnbm90aWZpY2F0aW9uLXVybCcsCiAgICAgICAgICAgICdpbmNsdWRlUGF0aHMnID0+ICdpbmNsdWRlLXBhdGgnLAogICAgICAgICk7CgogICAgICAgICRkYXRhID0gYXJyYXkoKTsKICAgICAgICAkZGF0YVsnbmFtZSddID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKICAgICAgICAkZGF0YVsndmVyc2lvbiddID0gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAkZGF0YVsndmVyc2lvbl9ub3JtYWxpemVkJ10gPSAkcGFja2FnZS0+Z2V0VmVyc2lvbigpOwoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFRhcmdldERpcigpKSB7CiAgICAgICAgICAgICRkYXRhWyd0YXJnZXQtZGlyJ10gPSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKSkgewogICAgICAgICAgICAkZGF0YVsnc291cmNlJ11bJ3R5cGUnXSA9ICRwYWNrYWdlLT5nZXRTb3VyY2VUeXBlKCk7CiAgICAgICAgICAgICRkYXRhWydzb3VyY2UnXVsndXJsJ10gPSAkcGFja2FnZS0+Z2V0U291cmNlVXJsKCk7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAoJHZhbHVlID0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ3NvdXJjZSddWydyZWZlcmVuY2UnXSA9ICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJG1pcnJvcnMgPSAkcGFja2FnZS0+Z2V0U291cmNlTWlycm9ycygpKSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnc291cmNlJ11bJ21pcnJvcnMnXSA9ICRtaXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldERpc3RUeXBlKCkpIHsKICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsndHlwZSddID0gJHBhY2thZ2UtPmdldERpc3RUeXBlKCk7CiAgICAgICAgICAgICRkYXRhWydkaXN0J11bJ3VybCddID0gJHBhY2thZ2UtPmdldERpc3RVcmwoKTsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICgkdmFsdWUgPSAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsncmVmZXJlbmNlJ10gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bGwgIT09ICgkdmFsdWUgPSAkcGFja2FnZS0+Z2V0RGlzdFNoYTFDaGVja3N1bSgpKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2Rpc3QnXVsnc2hhc3VtJ10gPSAkdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRtaXJyb3JzID0gJHBhY2thZ2UtPmdldERpc3RNaXJyb3JzKCkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydkaXN0J11bJ21pcnJvcnMnXSA9ICRtaXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldEFyY2hpdmVOYW1lKCkpIHsKICAgICAgICAgICAgJGRhdGFbJ2FyY2hpdmUnXVsnbmFtZSddID0gJHBhY2thZ2UtPmdldEFyY2hpdmVOYW1lKCk7CiAgICAgICAgfQogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXJjaGl2ZUV4Y2x1ZGVzKCkpIHsKICAgICAgICAgICAgJGRhdGFbJ2FyY2hpdmUnXVsnZXhjbHVkZSddID0gJHBhY2thZ2UtPmdldEFyY2hpdmVFeGNsdWRlcygpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoQmFzZVBhY2thZ2U6OiRzdXBwb3J0ZWRMaW5rVHlwZXMgYXMgJHR5cGUgPT4gJG9wdHMpIHsKICAgICAgICAgICAgaWYgKCRsaW5rcyA9ICRwYWNrYWdlLT57J2dldCcudWNmaXJzdCgkb3B0c1snbWV0aG9kJ10pfSgpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YVskdHlwZV1bJGxpbmstPmdldFRhcmdldCgpXSA9ICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBrc29ydCgkZGF0YVskdHlwZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2VzID0gJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCkpIHsKICAgICAgICAgICAga3NvcnQoJHBhY2thZ2VzKTsKICAgICAgICAgICAgJGRhdGFbJ3N1Z2dlc3QnXSA9ICRwYWNrYWdlczsKICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0UmVsZWFzZURhdGUoKSkgewogICAgICAgICAgICAkZGF0YVsndGltZSddID0gJHBhY2thZ2UtPmdldFJlbGVhc2VEYXRlKCktPmZvcm1hdChEQVRFX1JGQzMzMzkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5pc0RlZmF1bHRCcmFuY2goKSkgewogICAgICAgICAgICAkZGF0YVsnZGVmYXVsdC1icmFuY2gnXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkZGF0YSA9ICR0aGlzLT5kdW1wVmFsdWVzKCRwYWNrYWdlLCAka2V5cywgJGRhdGEpOwoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJGtleXMgPSBhcnJheSgKICAgICAgICAgICAgICAgICdzY3JpcHRzJywKICAgICAgICAgICAgICAgICdsaWNlbnNlJywKICAgICAgICAgICAgICAgICdhdXRob3JzJywKICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbicsCiAgICAgICAgICAgICAgICAnaG9tZXBhZ2UnLAogICAgICAgICAgICAgICAgJ2tleXdvcmRzJywKICAgICAgICAgICAgICAgICdyZXBvc2l0b3JpZXMnLAogICAgICAgICAgICAgICAgJ3N1cHBvcnQnLAogICAgICAgICAgICAgICAgJ2Z1bmRpbmcnLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJGRhdGEgPSAkdGhpcy0+ZHVtcFZhbHVlcygkcGFja2FnZSwgJGtleXMsICRkYXRhKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVsna2V5d29yZHMnXSkgJiYgXGlzX2FycmF5KCRkYXRhWydrZXl3b3JkcyddKSkgewogICAgICAgICAgICAgICAgc29ydCgkZGF0YVsna2V5d29yZHMnXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+aXNBYmFuZG9uZWQoKSkgewogICAgICAgICAgICAgICAgJGRhdGFbJ2FiYW5kb25lZCddID0gJHBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpID86IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJHBhY2thZ2UtPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICAgICAgaWYgKCRtaW5pbXVtU3RhYmlsaXR5KSB7CiAgICAgICAgICAgICAgICAkZGF0YVsnbWluaW11bS1zdGFiaWxpdHknXSA9ICRtaW5pbXVtU3RhYmlsaXR5OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRwYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCkpID4gMCkgewogICAgICAgICAgICAkZGF0YVsndHJhbnNwb3J0LW9wdGlvbnMnXSA9ICRwYWNrYWdlLT5nZXRUcmFuc3BvcnRPcHRpb25zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBkdW1wVmFsdWVzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIGFycmF5ICRrZXlzLCBhcnJheSAkZGF0YSkKICAgIHsKICAgICAgICBmb3JlYWNoICgka2V5cyBhcyAkbWV0aG9kID0+ICRrZXkpIHsKICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoJG1ldGhvZCkpIHsKICAgICAgICAgICAgICAgICRtZXRob2QgPSAka2V5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZ2V0dGVyID0gJ2dldCcudWNmaXJzdCgkbWV0aG9kKTsKICAgICAgICAgICAgJHZhbHVlID0gJHBhY2thZ2UtPiRnZXR0ZXIoKTsKCiAgICAgICAgICAgIGlmIChudWxsICE9PSAkdmFsdWUgJiYgIShcaXNfYXJyYXkoJHZhbHVlKSAmJiAwID09PSBcY291bnQoJHZhbHVlKSkpIHsKICAgICAgICAgICAgICAgICRkYXRhWyRrZXldID0gJHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGFja2FnZTsKCnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CgovKioKICogRGVmaW5lcyB0aGUgZXNzZW50aWFsIGluZm9ybWF0aW9uIGEgcGFja2FnZSBoYXMgdGhhdCBpcyB1c2VkIGR1cmluZyBzb2x2aW5nL2luc3RhbGxhdGlvbgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgUGFja2FnZUludGVyZmFjZQp7CiAgICBjb25zdCBESVNQTEFZX1NPVVJDRV9SRUZfSUZfREVWID0gMDsKICAgIGNvbnN0IERJU1BMQVlfU09VUkNFX1JFRiA9IDE7CiAgICBjb25zdCBESVNQTEFZX0RJU1RfUkVGID0gMjsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UncyBuYW1lIHdpdGhvdXQgdmVyc2lvbiBpbmZvLCB0aHVzIG5vdCBhIHVuaXF1ZSBpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcGFja2FnZSBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlJ3MgcHJldHR5IChpLmUuIHdpdGggcHJvcGVyIGNhc2UpIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBwYWNrYWdlIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgbmFtZXMgdGhhdCBjb3VsZCByZWZlciB0byB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBObyB2ZXJzaW9uIG9yIHJlbGVhc2UgdHlwZSBpbmZvcm1hdGlvbiBzaG91bGQgYmUgaW5jbHVkZWQgaW4gYW55IG9mIHRoZQogICAgICogbmFtZXMuIFByb3ZpZGVkIG9yIHJlcGxhY2VkIHBhY2thZ2UgbmFtZXMgbmVlZCB0byBiZSByZXR1cm5lZCBhcyB3ZWxsLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRwcm92aWRlcyBXaGV0aGVyIHByb3ZpZGVkIG5hbWVzIHNob3VsZCBiZSBpbmNsdWRlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10gQW4gYXJyYXkgb2Ygc3RyaW5ncyByZWZlcnJpbmcgdG8gdGhpcyBwYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lcygkcHJvdmlkZXMgPSB0cnVlKTsKCiAgICAvKioKICAgICAqIEFsbG93cyB0aGUgc29sdmVyIHRvIHNldCBhbiBpZCBmb3IgdGhpcyBwYWNrYWdlIHRvIHJlZmVyIHRvIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZCgkaWQpOwoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSBwYWNrYWdlJ3MgaWQgc2V0IHRocm91Z2ggc2V0SWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgcHJldmlvdXNseSBzZXQgcGFja2FnZSBpZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgcGFja2FnZSBpcyBhIGRldmVsb3BtZW50IHZpcnR1YWwgcGFja2FnZSBvciBhIGNvbmNyZXRlIG9uZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXYoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgdHlwZSwgZS5nLiBsaWJyYXJ5CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHBhY2thZ2UgdHlwZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSB0YXJnZXREaXIgcHJvcGVydHkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBwYWNrYWdlIHRhcmdldERpcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0RGlyKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYWNrYWdlIGV4dHJhIGRhdGEKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBwYWNrYWdlIGV4dHJhIGRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4dHJhKCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHNvdXJjZSBmcm9tIHdoaWNoIHRoaXMgcGFja2FnZSB3YXMgaW5zdGFsbGVkIChzb3VyY2UvZGlzdCkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSBzb3VyY2UvZGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5zdGFsbGF0aW9uU291cmNlKCR0eXBlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgc291cmNlIGZyb20gd2hpY2ggdGhpcyBwYWNrYWdlIHdhcyBpbnN0YWxsZWQgKHNvdXJjZS9kaXN0KS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBzb3VyY2UvZGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZXBvc2l0b3J5IHR5cGUgb2YgdGhpcyBwYWNrYWdlLCBlLmcuIGdpdCwgc3ZuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHJlcG9zaXRvcnkgdHlwZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U291cmNlVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVwb3NpdG9yeSB1cmwgb2YgdGhpcyBwYWNrYWdlLCBlLmcuIGdpdDovL2dpdGh1Yi5jb20vbmFkZXJtYW4vY29tcG9zZXIuZ2l0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHJlcG9zaXRvcnkgdXJsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VVcmwoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlcG9zaXRvcnkgdXJscyBvZiB0aGlzIHBhY2thZ2UgaW5jbHVkaW5nIG1pcnJvcnMsIGUuZy4gZ2l0Oi8vZ2l0aHViLmNvbS9uYWRlcm1hbi9jb21wb3Nlci5naXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VVcmxzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZXBvc2l0b3J5IHJlZmVyZW5jZSBvZiB0aGlzIHBhY2thZ2UsIGUuZy4gbWFzdGVyLCAxLjAuMCBvciBhIGNvbW1pdCBoYXNoIGZvciBnaXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcmVwb3NpdG9yeSByZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZVJlZmVyZW5jZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc291cmNlIG1pcnJvcnMgb2YgdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VNaXJyb3JzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBkaXN0cmlidXRpb24gYXJjaGl2ZSBvZiB0aGlzIHZlcnNpb24sIGUuZy4gemlwLCB0YXJiYWxsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHJlcG9zaXRvcnkgdHlwZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVybCBvZiB0aGUgZGlzdHJpYnV0aW9uIGFyY2hpdmUgb2YgdGhpcyB2ZXJzaW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3RVcmwoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVybHMgb2YgdGhlIGRpc3RyaWJ1dGlvbiBhcmNoaXZlIG9mIHRoaXMgdmVyc2lvbiwgaW5jbHVkaW5nIG1pcnJvcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0VXJscygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIG9mIHRoZSBkaXN0cmlidXRpb24gYXJjaGl2ZSBvZiB0aGlzIHZlcnNpb24sIGUuZy4gbWFzdGVyLCAxLjAuMCBvciBhIGNvbW1pdCBoYXNoIGZvciBnaXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzdFJlZmVyZW5jZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2hhMSBjaGVja3N1bSBmb3IgdGhlIGRpc3RyaWJ1dGlvbiBhcmNoaXZlIG9mIHRoaXMgdmVyc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0U2hhMUNoZWNrc3VtKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXN0IG1pcnJvcnMgb2YgdGhpcyBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREaXN0TWlycm9ycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBvZiB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcmV0dHkgKGkuZS4gbm9uLW5vcm1hbGl6ZWQpIHZlcnNpb24gc3RyaW5nIG9mIHRoaXMgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIHZlcnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVZlcnNpb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByZXR0eSB2ZXJzaW9uIHN0cmluZyBwbHVzIGEgZ2l0IG9yIGhnIGNvbW1pdCBoYXNoIG9mIHRoaXMgcGFja2FnZQogICAgICoKICAgICAqIEBzZWUgZ2V0UHJldHR5VmVyc2lvbgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICR0cnVuY2F0ZSAgICBJZiB0aGUgc291cmNlIHJlZmVyZW5jZSBpcyBhIHNoYTEgaGFzaCwgdHJ1bmNhdGUgaXQKICAgICAqIEBwYXJhbSAgaW50ICAgICRkaXNwbGF5TW9kZSBPbmUgb2YgdGhlIERJU1BMQVlfIGNvbnN0YW50cyBvbiB0aGlzIGludGVyZmFjZSBkZXRlcm1pbmluZyBkaXNwbGF5IG9mIHJlZmVyZW5jZXMKICAgICAqIEByZXR1cm4gc3RyaW5nIHZlcnNpb24KICAgICAqCiAgICAgKiBAcHNhbG0tcGFyYW0gc2VsZjo6RElTUExBWV9TT1VSQ0VfUkVGX0lGX0RFVnxzZWxmOjpESVNQTEFZX1NPVVJDRV9SRUZ8c2VsZjo6RElTUExBWV9ESVNUX1JFRiAkZGlzcGxheU1vZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZ1bGxQcmV0dHlWZXJzaW9uKCR0cnVuY2F0ZSA9IHRydWUsICRkaXNwbGF5TW9kZSA9IHNlbGY6OkRJU1BMQVlfU09VUkNFX1JFRl9JRl9ERVYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVsZWFzZSBkYXRlIG9mIHRoZSBwYWNrYWdlCiAgICAgKgogICAgICogQHJldHVybiBcRGF0ZVRpbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlbGVhc2VEYXRlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGFiaWxpdHkgb2YgdGhpcyBwYWNrYWdlOiBvbmUgb2YgKGRldiwgYWxwaGEsIGJldGEsIFJDLCBzdGFibGUpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBsaW5rcyB0byBwYWNrYWdlcyB3aGljaCBuZWVkIHRvIGJlIGluc3RhbGxlZCBiZWZvcmUKICAgICAqIHRoaXMgcGFja2FnZSBjYW4gYmUgaW5zdGFsbGVkCiAgICAgKgogICAgICogQHJldHVybiBMaW5rW10gQW4gYXJyYXkgb2YgcGFja2FnZSBsaW5rcyBkZWZpbmluZyByZXF1aXJlZCBwYWNrYWdlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVxdWlyZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgbGlua3MgdG8gcGFja2FnZXMgd2hpY2ggbXVzdCBub3QgYmUgaW5zdGFsbGVkIGF0IHRoZQogICAgICogc2FtZSB0aW1lIGFzIHRoaXMgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gTGlua1tdIEFuIGFycmF5IG9mIHBhY2thZ2UgbGlua3MgZGVmaW5pbmcgY29uZmxpY3RpbmcgcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZsaWN0cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBsaW5rcyB0byB2aXJ0dWFsIHBhY2thZ2VzIHRoYXQgYXJlIHByb3ZpZGVkIHRocm91Z2gKICAgICAqIHRoaXMgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gTGlua1tdIEFuIGFycmF5IG9mIHBhY2thZ2UgbGlua3MgZGVmaW5pbmcgcHJvdmlkZWQgcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb3ZpZGVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGxpbmtzIHRvIHBhY2thZ2VzIHdoaWNoIGNhbiBhbHRlcm5hdGl2ZWx5IGJlCiAgICAgKiBzYXRpc2ZpZWQgYnkgaW5zdGFsbGluZyB0aGlzIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIExpbmtbXSBBbiBhcnJheSBvZiBwYWNrYWdlIGxpbmtzIGRlZmluaW5nIHJlcGxhY2VkIHBhY2thZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBsYWNlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBsaW5rcyB0byBwYWNrYWdlcyB3aGljaCBhcmUgcmVxdWlyZWQgdG8gZGV2ZWxvcAogICAgICogdGhpcyBwYWNrYWdlLiBUaGVzZSBhcmUgaW5zdGFsbGVkIGlmIGluIGRldiBtb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gTGlua1tdIEFuIGFycmF5IG9mIHBhY2thZ2UgbGlua3MgZGVmaW5pbmcgcGFja2FnZXMgcmVxdWlyZWQgZm9yIGRldmVsb3BtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZSZXF1aXJlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBwYWNrYWdlIG5hbWVzIGFuZCByZWFzb25zIHdoeSB0aGV5IGFyZSB1c2VmdWwgaW4KICAgICAqIGNvbWJpbmF0aW9uIHdpdGggdGhpcyBwYWNrYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgcGFja2FnZSBzdWdnZXN0aW9ucyB3aXRoIGRlc2NyaXB0aW9ucwogICAgICogQHBzYWxtLXJldHVybiBhcnJheTxzdHJpbmcsIHN0cmluZz4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1Z2dlc3RzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFzc29jaWF0aXZlIGFycmF5IG9mIGF1dG9sb2FkaW5nIHJ1bGVzCiAgICAgKgogICAgICogeyI8dHlwZT4iOiB7IjxuYW1lc3BhY2UiOiAiPGRpcmVjdG9yeT4ifX0KICAgICAqCiAgICAgKiBUeXBlIGlzIGVpdGhlciAicHNyLTQiLCAicHNyLTAiLCAiY2xhc3NtYXAiIG9yICJmaWxlcyIuIE5hbWVzcGFjZXMgYXJlIG1hcHBlZCB0bwogICAgICogZGlyZWN0b3JpZXMgZm9yIGF1dG9sb2FkaW5nIHVzaW5nIHRoZSB0eXBlIHNwZWNpZmllZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IE1hcHBpbmcgb2YgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXl7cHNyLTA/OiBhcnJheTxzdHJpbmcsIHN0cmluZz4sIHBzci00PzogYXJyYXk8c3RyaW5nLCBzdHJpbmc+LCBjbGFzc21hcD86IGxpc3Q8c3RyaW5nPiwgZmlsZXM/OiBsaXN0PHN0cmluZz59CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvbG9hZCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhc3NvY2lhdGl2ZSBhcnJheSBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqCiAgICAgKiB7Ijx0eXBlPiI6IHsiPG5hbWVzcGFjZSI6ICI8ZGlyZWN0b3J5PiJ9fQogICAgICoKICAgICAqIFR5cGUgaXMgZWl0aGVyICJwc3ItNCIsICJwc3ItMCIsICJjbGFzc21hcCIgb3IgImZpbGVzIi4gTmFtZXNwYWNlcyBhcmUgbWFwcGVkIHRvCiAgICAgKiBkaXJlY3RvcmllcyBmb3IgYXV0b2xvYWRpbmcgdXNpbmcgdGhlIHR5cGUgc3BlY2lmaWVkLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgTWFwcGluZyBvZiBkZXYgYXV0b2xvYWRpbmcgcnVsZXMKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXl7cHNyLTA/OiBhcnJheTxzdHJpbmcsIHN0cmluZz4sIHBzci00PzogYXJyYXk8c3RyaW5nLCBzdHJpbmc+LCBjbGFzc21hcD86IGxpc3Q8c3RyaW5nPiwgZmlsZXM/OiBsaXN0PHN0cmluZz59CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXZBdXRvbG9hZCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZGlyZWN0b3JpZXMgd2hpY2ggc2hvdWxkIGdldCBhZGRlZCB0byBQSFAncwogICAgICogaW5jbHVkZSBwYXRoLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluY2x1ZGVQYXRocygpOwoKICAgIC8qKgogICAgICogU3RvcmVzIGEgcmVmZXJlbmNlIHRvIHRoZSByZXBvc2l0b3J5IHRoYXQgb3ducyB0aGUgcGFja2FnZQogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvc2l0b3J5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG9zaXRvcnkpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgcmVwb3NpdG9yeSB0aGF0IG93bnMgdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9zaXRvcnkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgYmluYXJpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCaW5hcmllcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIHVuaXF1ZSBuYW1lLCBjb25zdHJ1Y3RlZCBmcm9tIG5hbWUgYW5kIHZlcnNpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVuaXF1ZU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2Ugbm90aWZpY2F0aW9uIHVybAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROb3RpZmljYXRpb25VcmwoKTsKCiAgICAvKioKICAgICAqIENvbnZlcnRzIHRoZSBwYWNrYWdlIGludG8gYSByZWFkYWJsZSBhbmQgdW5pcXVlIHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCk7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyB0aGUgcGFja2FnZSBpbnRvIGEgcHJldHR5IHJlYWRhYmxlIHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgZGVmYXVsdCBiYXNlIGZpbGVuYW1lIGZvciBhcmNoaXZlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHBhdHRlcm5zIHRvIGV4Y2x1ZGUgZnJvbSBwYWNrYWdlIGFyY2hpdmVzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZUV4Y2x1ZGVzKCk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVmYXVsdEJyYW5jaCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2Ygb3B0aW9ucyB0byBkb3dubG9hZCBwYWNrYWdlIGRpc3QgZmlsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUcmFuc3BvcnRPcHRpb25zKCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZVJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFVybCgkdXJsKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc3RUeXBlKCR0eXBlKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGlzdFJlZmVyZW5jZSgkcmVmZXJlbmNlKTsKCiAgICAvKioKICAgICAqIFNldCBkaXN0IGFuZCBzb3VyY2UgcmVmZXJlbmNlcyBhbmQgdXBkYXRlIGRpc3QgVVJMIGZvciBvbmVzIHRoYXQgY29udGFpbiBhIHJlZmVyZW5jZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlZmVyZW5jZQogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlRGlzdFJlZmVyZW5jZXMoJHJlZmVyZW5jZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSU87Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CgovKioKICogVGhlIElucHV0L091dHB1dCBoZWxwZXIgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEZyYW7Dp29pcyBQbHVjaGlubyA8ZnJhbmNvaXMucGx1Y2hpbm9Ab3BlbmRpc3BsYXkuY29tPgogKi8KaW50ZXJmYWNlIElPSW50ZXJmYWNlIGV4dGVuZHMgTG9nZ2VySW50ZXJmYWNlCnsKICAgIGNvbnN0IFFVSUVUID0gMTsKICAgIGNvbnN0IE5PUk1BTCA9IDI7CiAgICBjb25zdCBWRVJCT1NFID0gNDsKICAgIGNvbnN0IFZFUllfVkVSQk9TRSA9IDg7CiAgICBjb25zdCBERUJVRyA9IDE2OwoKICAgIC8qKgogICAgICogSXMgdGhpcyBpbnB1dCBtZWFucyBpbnRlcmFjdGl2ZT8KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUoKTsKCiAgICAvKioKICAgICAqIElzIHRoaXMgb3V0cHV0IHZlcmJvc2U/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKTsKCiAgICAvKioKICAgICAqIElzIHRoZSBvdXRwdXQgdmVyeSB2ZXJib3NlPwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpOwoKICAgIC8qKgogICAgICogSXMgdGhlIG91dHB1dCBpbiBkZWJ1ZyB2ZXJib3NpdHk/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlYnVnKCk7CgogICAgLyoqCiAgICAgKiBJcyB0aGlzIG91dHB1dCBkZWNvcmF0ZWQ/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlY29yYXRlZCgpOwoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzICBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBsaW5lcyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUgICBXaGV0aGVyIHRvIGFkZCBhIG5ld2xpbmUgb3Igbm90CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICR2ZXJib3NpdHkgVmVyYm9zaXR5IGxldmVsIGZyb20gdGhlIFZFUkJPU0lUWV8qIGNvbnN0YW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpOwoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgZXJyb3Igb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzICBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBsaW5lcyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUgICBXaGV0aGVyIHRvIGFkZCBhIG5ld2xpbmUgb3Igbm90CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICR2ZXJib3NpdHkgVmVyYm9zaXR5IGxldmVsIGZyb20gdGhlIFZFUkJPU0lUWV8qIGNvbnN0YW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVFcnJvcigkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCk7CgogICAgLyoqCiAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBvdXRwdXQsIHdpdGhvdXQgZm9ybWF0dGluZyBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlcyAgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2YgbGluZXMgb3IgYSBzaW5nbGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRuZXdsaW5lICAgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICogQHBhcmFtIGludCAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlUmF3KCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKTsKCiAgICAvKioKICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGVycm9yIG91dHB1dCwgd2l0aG91dCBmb3JtYXR0aW5nIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzICBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBsaW5lcyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUgICBXaGV0aGVyIHRvIGFkZCBhIG5ld2xpbmUgb3Igbm90CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICR2ZXJib3NpdHkgVmVyYm9zaXR5IGxldmVsIGZyb20gdGhlIFZFUkJPU0lUWV8qIGNvbnN0YW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVFcnJvclJhdygkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCk7CgogICAgLyoqCiAgICAgKiBPdmVyd3JpdGVzIGEgcHJldmlvdXMgbWVzc2FnZSB0byB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzICBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBsaW5lcyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUgICBXaGV0aGVyIHRvIGFkZCBhIG5ld2xpbmUgb3Igbm90CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICRzaXplICAgICAgVGhlIHNpemUgb2YgbGluZQogICAgICogQHBhcmFtIGludCAgICAgICAgICAkdmVyYm9zaXR5IFZlcmJvc2l0eSBsZXZlbCBmcm9tIHRoZSBWRVJCT1NJVFlfKiBjb25zdGFudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHNpemUgPSBudWxsLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKTsKCiAgICAvKioKICAgICAqIE92ZXJ3cml0ZXMgYSBwcmV2aW91cyBtZXNzYWdlIHRvIHRoZSBlcnJvciBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZXMgIFRoZSBtZXNzYWdlIGFzIGFuIGFycmF5IG9mIGxpbmVzIG9yIGEgc2luZ2xlIHN0cmluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkbmV3bGluZSAgIFdoZXRoZXIgdG8gYWRkIGEgbmV3bGluZSBvciBub3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgJHNpemUgICAgICBUaGUgc2l6ZSBvZiBsaW5lCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICR2ZXJib3NpdHkgVmVyYm9zaXR5IGxldmVsIGZyb20gdGhlIFZFUkJPU0lUWV8qIGNvbnN0YW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb3ZlcndyaXRlRXJyb3IoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICRzaXplID0gbnVsbCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCk7CgogICAgLyoqCiAgICAgKiBBc2tzIGEgcXVlc3Rpb24gdG8gdGhlIHVzZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gVGhlIHF1ZXN0aW9uIHRvIGFzawogICAgICogQHBhcmFtIHN0cmluZyAkZGVmYXVsdCAgVGhlIGRlZmF1bHQgYW5zd2VyIGlmIG5vbmUgaXMgZ2l2ZW4gYnkgdGhlIHVzZXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIElmIHRoZXJlIGlzIG5vIGRhdGEgdG8gcmVhZCBpbiB0aGUgaW5wdXQgc3RyZWFtCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsICAgICAgIFRoZSB1c2VyIGFuc3dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSBudWxsKTsKCiAgICAvKioKICAgICAqIEFza3MgYSBjb25maXJtYXRpb24gdG8gdGhlIHVzZXIuCiAgICAgKgogICAgICogVGhlIHF1ZXN0aW9uIHdpbGwgYmUgYXNrZWQgdW50aWwgdGhlIHVzZXIgYW5zd2VycyBieSBub3RoaW5nLCB5ZXMsIG9yIG5vLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sKICAgICAqIEBwYXJhbSBib29sICAgJGRlZmF1bHQgIFRoZSBkZWZhdWx0IGFuc3dlciBpZiB0aGUgdXNlciBlbnRlcnMgbm90aGluZwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSB1c2VyIGhhcyBjb25maXJtZWQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQ29uZmlybWF0aW9uKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSB0cnVlKTsKCiAgICAvKioKICAgICAqIEFza3MgZm9yIGEgdmFsdWUgYW5kIHZhbGlkYXRlcyB0aGUgcmVzcG9uc2UuCiAgICAgKgogICAgICogVGhlIHZhbGlkYXRvciByZWNlaXZlcyB0aGUgZGF0YSB0byB2YWxpZGF0ZS4gSXQgbXVzdCByZXR1cm4gdGhlCiAgICAgKiB2YWxpZGF0ZWQgZGF0YSB3aGVuIHRoZSBkYXRhIGlzIHZhbGlkIGFuZCB0aHJvdyBhbiBleGNlcHRpb24KICAgICAqIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHF1ZXN0aW9uICBUaGUgcXVlc3Rpb24gdG8gYXNrCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJHZhbGlkYXRvciBBIFBIUCBjYWxsYmFjawogICAgICogQHBhcmFtIG51bGx8aW50ICRhdHRlbXB0cyAgTWF4IG51bWJlciBvZiB0aW1lcyB0byBhc2sgYmVmb3JlIGdpdmluZyB1cCAoZGVmYXVsdCBvZiBudWxsIG1lYW5zIGluZmluaXRlKQogICAgICogQHBhcmFtIG1peGVkICAgICRkZWZhdWx0ICAgVGhlIGRlZmF1bHQgYW5zd2VyIGlmIG5vbmUgaXMgZ2l2ZW4gYnkgdGhlIHVzZXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24gV2hlbiBhbnkgb2YgdGhlIHZhbGlkYXRvcnMgcmV0dXJuIGFuIGVycm9yCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tBbmRWYWxpZGF0ZSgkcXVlc3Rpb24sICR2YWxpZGF0b3IsICRhdHRlbXB0cyA9IG51bGwsICRkZWZhdWx0ID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBBc2tzIGEgcXVlc3Rpb24gdG8gdGhlIHVzZXIgYW5kIGhpZGUgdGhlIGFuc3dlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRxdWVzdGlvbiBUaGUgcXVlc3Rpb24gdG8gYXNrCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgYW5zd2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tBbmRIaWRlQW5zd2VyKCRxdWVzdGlvbik7CgogICAgLyoqCiAgICAgKiBBc2tzIHRoZSB1c2VyIHRvIHNlbGVjdCBhIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkcXVlc3Rpb24gICAgIFRoZSBxdWVzdGlvbiB0byBhc2sKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAkY2hvaWNlcyAgICAgIExpc3Qgb2YgY2hvaWNlcyB0byBwaWNrIGZyb20KICAgICAqIEBwYXJhbSBib29sfHN0cmluZyAkZGVmYXVsdCAgICAgIFRoZSBkZWZhdWx0IGFuc3dlciBpZiB0aGUgdXNlciBlbnRlcnMgbm90aGluZwogICAgICogQHBhcmFtIGJvb2x8aW50ICAgICRhdHRlbXB0cyAgICAgTWF4IG51bWJlciBvZiB0aW1lcyB0byBhc2sgYmVmb3JlIGdpdmluZyB1cCAoZmFsc2UgYnkgZGVmYXVsdCwgd2hpY2ggbWVhbnMgaW5maW5pdGUpCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGVycm9yTWVzc2FnZSBNZXNzYWdlIHdoaWNoIHdpbGwgYmUgc2hvd24gaWYgaW52YWxpZCB2YWx1ZSBmcm9tIGNob2ljZSBsaXN0IHdvdWxkIGJlIHBpY2tlZAogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRtdWx0aXNlbGVjdCAgU2VsZWN0IG1vcmUgdGhhbiBvbmUgdmFsdWUgc2VwYXJhdGVkIGJ5IGNvbW1hCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGludHxzdHJpbmd8YXJyYXl8Ym9vbCAgICAgVGhlIHNlbGVjdGVkIHZhbHVlIG9yIHZhbHVlcyAodGhlIGtleSBvZiB0aGUgY2hvaWNlcyBhcnJheSkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlbGVjdCgkcXVlc3Rpb24sICRjaG9pY2VzLCAkZGVmYXVsdCwgJGF0dGVtcHRzID0gZmFsc2UsICRlcnJvck1lc3NhZ2UgPSAnVmFsdWUgIiVzIiBpcyBpbnZhbGlkJywgJG11bHRpc2VsZWN0ID0gZmFsc2UpOwoKICAgIC8qKgogICAgICogR2V0IGFsbCBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBlbnRlcmVkLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIG1hcCBvZiBhdXRoZW50aWNhdGlvbiBkYXRhCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRoZW50aWNhdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFZlcmlmeSBpZiB0aGUgcmVwb3NpdG9yeSBoYXMgYSBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXBvc2l0b3J5TmFtZSBUaGUgdW5pcXVlIG5hbWUgb2YgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQXV0aGVudGljYXRpb24oJHJlcG9zaXRvcnlOYW1lKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIG9mIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVwb3NpdG9yeU5hbWUgVGhlIHVuaXF1ZSBuYW1lIG9mIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSAndXNlcm5hbWUnIGFuZCAncGFzc3dvcmQnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhlIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVwb3NpdG9yeU5hbWUgVGhlIHVuaXF1ZSBuYW1lIG9mIHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVzZXJuYW1lICAgICAgIFRoZSB1c2VybmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkcGFzc3dvcmQgICAgICAgVGhlIHBhc3N3b3JkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUsICR1c2VybmFtZSwgJHBhc3N3b3JkID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBMb2FkcyBhdXRoZW50aWNhdGlvbnMgZnJvbSBhIGNvbmZpZyBpbnN0YW5jZQogICAgICoKICAgICAqIEBwYXJhbSBDb25maWcgJGNvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9hZENvbmZpZ3VyYXRpb24oQ29uZmlnICRjb25maWcpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKdXNlIENvbXBvc2VyXFF1ZXN0aW9uXFN0cmljdENvbmZpcm1hdGlvblF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcSGVscGVyU2V0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUHJvZ3Jlc3NCYXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQ29uc29sZU91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cQ2hvaWNlUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXFF1ZXN0aW9uOwoKLyoqCiAqIFRoZSBJbnB1dC9PdXRwdXQgaGVscGVyLgogKgogKiBAYXV0aG9yIEZyYW7Dp29pcyBQbHVjaGlubyA8ZnJhbmNvaXMucGx1Y2hpbm9Ab3BlbmRpc3BsYXkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb25zb2xlSU8gZXh0ZW5kcyBCYXNlSU8KewogICAgLyoqIEB2YXIgSW5wdXRJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW5wdXQ7CiAgICAvKiogQHZhciBPdXRwdXRJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkb3V0cHV0OwogICAgLyoqIEB2YXIgSGVscGVyU2V0ICovCiAgICBwcm90ZWN0ZWQgJGhlbHBlclNldDsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRsYXN0TWVzc2FnZTsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJvdGVjdGVkICRsYXN0TWVzc2FnZUVycjsKCiAgICAvKiogQHZhciBmbG9hdCAqLwogICAgcHJpdmF0ZSAkc3RhcnRUaW1lOwogICAgLyoqIEB2YXIgYXJyYXk8aW50LCBpbnQ+ICovCiAgICBwcml2YXRlICR2ZXJib3NpdHlNYXA7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5wdXRJbnRlcmZhY2UgICRpbnB1dCAgICAgVGhlIGlucHV0IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQgICAgVGhlIG91dHB1dCBpbnN0YW5jZQogICAgICogQHBhcmFtIEhlbHBlclNldCAgICAgICAkaGVscGVyU2V0IFRoZSBoZWxwZXJTZXQgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIEhlbHBlclNldCAkaGVscGVyU2V0KQogICAgewogICAgICAgICR0aGlzLT5pbnB1dCA9ICRpbnB1dDsKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gJG91dHB1dDsKICAgICAgICAkdGhpcy0+aGVscGVyU2V0ID0gJGhlbHBlclNldDsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5TWFwID0gYXJyYXkoCiAgICAgICAgICAgIHNlbGY6OlFVSUVUID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1FVSUVULAogICAgICAgICAgICBzZWxmOjpOT1JNQUwgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfTk9STUFMLAogICAgICAgICAgICBzZWxmOjpWRVJCT1NFID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUkJPU0UsCiAgICAgICAgICAgIHNlbGY6OlZFUllfVkVSQk9TRSA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UsCiAgICAgICAgICAgIHNlbGY6OkRFQlVHID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX0RFQlVHLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gZmxvYXQgJHN0YXJ0VGltZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlRGVidWdnaW5nKCRzdGFydFRpbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXJ0VGltZSA9ICRzdGFydFRpbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0ludGVyYWN0aXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlucHV0LT5pc0ludGVyYWN0aXZlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlY29yYXRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSA+PSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldFZlcmJvc2l0eSgpID49IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5nZXRWZXJib3NpdHkoKSA+PSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9ERUJVRzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgICAgICR0aGlzLT5kb1dyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsIGZhbHNlLCAkdmVyYm9zaXR5KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlRXJyb3IoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvV3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgdHJ1ZSwgJHZlcmJvc2l0eSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZVJhdygkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgICAgICAkdGhpcy0+ZG9Xcml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lLCBmYWxzZSwgJHZlcmJvc2l0eSwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZUVycm9yUmF3KCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgICAgICR0aGlzLT5kb1dyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsIHRydWUsICR2ZXJib3NpdHksIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5fHN0cmluZyAkbWVzc2FnZXMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJHN0ZGVycgogICAgICogQHBhcmFtIGludCAgICAgICAgICAkdmVyYm9zaXR5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9Xcml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lLCAkc3RkZXJyLCAkdmVyYm9zaXR5LCAkcmF3ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHNmVmVyYm9zaXR5ID0gJHRoaXMtPnZlcmJvc2l0eU1hcFskdmVyYm9zaXR5XTsKICAgICAgICBpZiAoJHNmVmVyYm9zaXR5ID4gJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFjayB0byBrZWVwIG91ciB1c2FnZSBCQyB3aXRoIHN5bWZvbnk8Mi44IHZlcnNpb25zCiAgICAgICAgLy8gdGhpcyByZW1vdmVzIHRoZSBxdWlldCBvdXRwdXQgYnV0IHRoZXJlIGlzIG5vIHdheSBhcm91bmQgaXQKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvNDkxMwogICAgICAgIGlmIChPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCA9PT0gMCkgewogICAgICAgICAgICAkc2ZWZXJib3NpdHkgPSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9OT1JNQUw7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJhdykgewogICAgICAgICAgICBpZiAoJHNmVmVyYm9zaXR5ID09PSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9OT1JNQUwpIHsKICAgICAgICAgICAgICAgICRzZlZlcmJvc2l0eSA9IE91dHB1dEludGVyZmFjZTo6T1VUUFVUX1JBVzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRzZlZlcmJvc2l0eSB8PSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9SQVc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+c3RhcnRUaW1lKSB7CiAgICAgICAgICAgICRtZW1vcnlVc2FnZSA9IG1lbW9yeV9nZXRfdXNhZ2UoKSAvIDEwMjQgLyAxMDI0OwogICAgICAgICAgICAkdGltZVNwZW50ID0gbWljcm90aW1lKHRydWUpIC0gJHRoaXMtPnN0YXJ0VGltZTsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkbWVzc2FnZSkgdXNlICgkbWVtb3J5VXNhZ2UsICR0aW1lU3BlbnQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdbJS4xZk1pQi8lLjJmc10gJXMnLCAkbWVtb3J5VXNhZ2UsICR0aW1lU3BlbnQsICRtZXNzYWdlKTsKICAgICAgICAgICAgfSwgKGFycmF5KSAkbWVzc2FnZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRydWUgPT09ICRzdGRlcnIgJiYgJHRoaXMtPm91dHB1dCBpbnN0YW5jZW9mIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKS0+d3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHNmVmVyYm9zaXR5KTsKICAgICAgICAgICAgJHRoaXMtPmxhc3RNZXNzYWdlRXJyID0gaW1wbG9kZSgkbmV3bGluZSA/ICJcbiIgOiAnJywgKGFycmF5KSAkbWVzc2FnZXMpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHNmVmVyYm9zaXR5KTsKICAgICAgICAkdGhpcy0+bGFzdE1lc3NhZ2UgPSBpbXBsb2RlKCRuZXdsaW5lID8gIlxuIiA6ICcnLCAoYXJyYXkpICRtZXNzYWdlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdmVyd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IHRydWUsICRzaXplID0gbnVsbCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgICAgICAkdGhpcy0+ZG9PdmVyd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHNpemUsIGZhbHNlLCAkdmVyYm9zaXR5KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkc2l6ZSA9IG51bGwsICR2ZXJib3NpdHkgPSBzZWxmOjpOT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvT3ZlcndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzaXplLCB0cnVlLCAkdmVyYm9zaXR5KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheXxzdHJpbmcgJG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRuZXdsaW5lCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICRzaXplCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRzdGRlcnIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgJHZlcmJvc2l0eQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRvT3ZlcndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICRzaXplLCAkc3RkZXJyLCAkdmVyYm9zaXR5KQogICAgewogICAgICAgIC8vIG1lc3NhZ2VzIGNhbiBiZSBhbiBhcnJheSwgbGV0J3MgY29udmVydCBpdCB0byBzdHJpbmcgYW55d2F5CiAgICAgICAgJG1lc3NhZ2VzID0gaW1wbG9kZSgkbmV3bGluZSA/ICJcbiIgOiAnJywgKGFycmF5KSAkbWVzc2FnZXMpOwoKICAgICAgICAvLyBzaW5jZSBvdmVyd3JpdGUgaXMgc3VwcG9zZWQgdG8gb3ZlcndyaXRlIGxhc3QgbWVzc2FnZS4uLgogICAgICAgIGlmICghaXNzZXQoJHNpemUpKSB7CiAgICAgICAgICAgIC8vIHJlbW92aW5nIHBvc3NpYmxlIGZvcm1hdHRpbmcgb2YgbGFzdE1lc3NhZ2Ugd2l0aCBzdHJpcF90YWdzCiAgICAgICAgICAgICRzaXplID0gc3RybGVuKHN0cmlwX3RhZ3MoJHN0ZGVyciA/ICR0aGlzLT5sYXN0TWVzc2FnZUVyciA6ICR0aGlzLT5sYXN0TWVzc2FnZSkpOwogICAgICAgIH0KICAgICAgICAvLyAuLi5sZXQncyBmaWxsIGl0cyBsZW5ndGggd2l0aCBiYWNrc3BhY2VzCiAgICAgICAgJHRoaXMtPmRvV3JpdGUoc3RyX3JlcGVhdCgiXHgwOCIsICRzaXplKSwgZmFsc2UsICRzdGRlcnIsICR2ZXJib3NpdHkpOwoKICAgICAgICAvLyB3cml0ZSB0aGUgbmV3IG1lc3NhZ2UKICAgICAgICAkdGhpcy0+ZG9Xcml0ZSgkbWVzc2FnZXMsIGZhbHNlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKCiAgICAgICAgLy8gSW4gY21kLmV4ZSBvbiBXaW44LjEgKHBvc3NpYmx5IDEwPyksIHRoZSBsaW5lIGNhbiBub3QgYmUgY2xlYXJlZCwgc28gd2UgbmVlZCB0bwogICAgICAgIC8vIHRyYWNrIHRoZSBsZW5ndGggb2YgcHJldmlvdXMgb3V0cHV0IGFuZCBmaWxsIGl0IHdpdGggc3BhY2VzIHRvIG1ha2Ugc3VyZSB0aGUgbGluZSBpcyBjbGVhcmVkLgogICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC81ODM2IGZvciBtb3JlIGRldGFpbHMKICAgICAgICAkZmlsbCA9ICRzaXplIC0gc3RybGVuKHN0cmlwX3RhZ3MoJG1lc3NhZ2VzKSk7CiAgICAgICAgaWYgKCRmaWxsID4gMCkgewogICAgICAgICAgICAvLyB3aGl0ZXNwYWNlIHdoYXRldmVyIGhhcyBsZWZ0CiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKHN0cl9yZXBlYXQoJyAnLCAkZmlsbCksIGZhbHNlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKICAgICAgICAgICAgLy8gbW92ZSB0aGUgY3Vyc29yIGJhY2sKICAgICAgICAgICAgJHRoaXMtPmRvV3JpdGUoc3RyX3JlcGVhdCgiXHgwOCIsICRmaWxsKSwgZmFsc2UsICRzdGRlcnIsICR2ZXJib3NpdHkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRuZXdsaW5lKSB7CiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKCcnLCB0cnVlLCAkc3RkZXJyLCAkdmVyYm9zaXR5KTsKICAgICAgICB9CgogICAgICAgIGlmICgkc3RkZXJyKSB7CiAgICAgICAgICAgICR0aGlzLT5sYXN0TWVzc2FnZUVyciA9ICRtZXNzYWdlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+bGFzdE1lc3NhZ2UgPSAkbWVzc2FnZXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBpbnQgICAgICAgICAkbWF4CiAgICAgKiBAcmV0dXJuIFByb2dyZXNzQmFyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9ncmVzc0JhcigkbWF4ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFByb2dyZXNzQmFyKCR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkbWF4KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFzaygkcXVlc3Rpb24sICRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICAvKiogQHZhciBcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUXVlc3Rpb25IZWxwZXIgJGhlbHBlciAqLwogICAgICAgICRoZWxwZXIgPSAkdGhpcy0+aGVscGVyU2V0LT5nZXQoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFF1ZXN0aW9uKCRxdWVzdGlvbiwgJGRlZmF1bHQpOwoKICAgICAgICByZXR1cm4gJGhlbHBlci0+YXNrKCR0aGlzLT5pbnB1dCwgJHRoaXMtPmdldEVycm9yT3V0cHV0KCksICRxdWVzdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tDb25maXJtYXRpb24oJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IHRydWUpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyICRoZWxwZXIgKi8KICAgICAgICAkaGVscGVyID0gJHRoaXMtPmhlbHBlclNldC0+Z2V0KCdxdWVzdGlvbicpOwogICAgICAgICRxdWVzdGlvbiA9IG5ldyBTdHJpY3RDb25maXJtYXRpb25RdWVzdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0KTsKCiAgICAgICAgcmV0dXJuICRoZWxwZXItPmFzaygkdGhpcy0+aW5wdXQsICR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kVmFsaWRhdGUoJHF1ZXN0aW9uLCAkdmFsaWRhdG9yLCAkYXR0ZW1wdHMgPSBudWxsLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgLyoqIEB2YXIgXFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyICRoZWxwZXIgKi8KICAgICAgICAkaGVscGVyID0gJHRoaXMtPmhlbHBlclNldC0+Z2V0KCdxdWVzdGlvbicpOwogICAgICAgICRxdWVzdGlvbiA9IG5ldyBRdWVzdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0KTsKICAgICAgICAkcXVlc3Rpb24tPnNldFZhbGlkYXRvcigkdmFsaWRhdG9yKTsKICAgICAgICAkcXVlc3Rpb24tPnNldE1heEF0dGVtcHRzKCRhdHRlbXB0cyk7CgogICAgICAgIHJldHVybiAkaGVscGVyLT5hc2soJHRoaXMtPmlucHV0LCAkdGhpcy0+Z2V0RXJyb3JPdXRwdXQoKSwgJHF1ZXN0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0FuZEhpZGVBbnN3ZXIoJHF1ZXN0aW9uKQogICAgewogICAgICAgIC8qKiBAdmFyIFxTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxRdWVzdGlvbkhlbHBlciAkaGVscGVyICovCiAgICAgICAgJGhlbHBlciA9ICR0aGlzLT5oZWxwZXJTZXQtPmdldCgncXVlc3Rpb24nKTsKICAgICAgICAkcXVlc3Rpb24gPSBuZXcgUXVlc3Rpb24oJHF1ZXN0aW9uKTsKICAgICAgICAkcXVlc3Rpb24tPnNldEhpZGRlbih0cnVlKTsKCiAgICAgICAgcmV0dXJuICRoZWxwZXItPmFzaygkdGhpcy0+aW5wdXQsICR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VsZWN0KCRxdWVzdGlvbiwgJGNob2ljZXMsICRkZWZhdWx0LCAkYXR0ZW1wdHMgPSBmYWxzZSwgJGVycm9yTWVzc2FnZSA9ICdWYWx1ZSAiJXMiIGlzIGludmFsaWQnLCAkbXVsdGlzZWxlY3QgPSBmYWxzZSkKICAgIHsKICAgICAgICAvKiogQHZhciBcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUXVlc3Rpb25IZWxwZXIgJGhlbHBlciAqLwogICAgICAgICRoZWxwZXIgPSAkdGhpcy0+aGVscGVyU2V0LT5nZXQoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IENob2ljZVF1ZXN0aW9uKCRxdWVzdGlvbiwgJGNob2ljZXMsICRkZWZhdWx0KTsKICAgICAgICAkcXVlc3Rpb24tPnNldE1heEF0dGVtcHRzKCRhdHRlbXB0cyA/OiBudWxsKTsgLy8gSU9JbnRlcmZhY2UgcmVxdWlyZXMgZmFsc2UsIGFuZCBRdWVzdGlvbiByZXF1aXJlcyBudWxsIG9yIGludAogICAgICAgICRxdWVzdGlvbi0+c2V0RXJyb3JNZXNzYWdlKCRlcnJvck1lc3NhZ2UpOwogICAgICAgICRxdWVzdGlvbi0+c2V0TXVsdGlzZWxlY3QoJG11bHRpc2VsZWN0KTsKCiAgICAgICAgJHJlc3VsdCA9ICRoZWxwZXItPmFzaygkdGhpcy0+aW5wdXQsICR0aGlzLT5nZXRFcnJvck91dHB1dCgpLCAkcXVlc3Rpb24pOwoKICAgICAgICBpZiAoIWlzX2FycmF5KCRyZXN1bHQpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSBhcnJheV9zZWFyY2goJHJlc3VsdCwgJGNob2ljZXMsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRjaG9pY2VzIGFzICRpbmRleCA9PiAkY2hvaWNlKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY2hvaWNlLCAkcmVzdWx0LCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9IChzdHJpbmcpICRpbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHRzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBPdXRwdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRFcnJvck91dHB1dCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSU87Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBQc3JcTG9nXExvZ0xldmVsOwoKYWJzdHJhY3QgY2xhc3MgQmFzZUlPIGltcGxlbWVudHMgSU9JbnRlcmZhY2UKewogICAgcHJvdGVjdGVkICRhdXRoZW50aWNhdGlvbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXV0aGVudGljYXRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF1dGhlbnRpY2F0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0QXV0aGVudGljYXRpb25zKCkKICAgIHsKICAgICAgICAkdGhpcy0+YXV0aGVudGljYXRpb25zID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0F1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmF1dGhlbnRpY2F0aW9uc1skcmVwb3NpdG9yeU5hbWVdKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmF1dGhlbnRpY2F0aW9uc1skcmVwb3NpdG9yeU5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmF1dGhlbnRpY2F0aW9uc1skcmVwb3NpdG9yeU5hbWVdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCd1c2VybmFtZScgPT4gbnVsbCwgJ3Bhc3N3b3JkJyA9PiBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSwgJHVzZXJuYW1lLCAkcGFzc3dvcmQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5hdXRoZW50aWNhdGlvbnNbJHJlcG9zaXRvcnlOYW1lXSA9IGFycmF5KCd1c2VybmFtZScgPT4gJHVzZXJuYW1lLCAncGFzc3dvcmQnID0+ICRwYXNzd29yZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZVJhdygkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHZlcmJvc2l0eSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZUVycm9yUmF3KCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgICAgICR0aGlzLT53cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUsICR2ZXJib3NpdHkpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgZm9yIG92ZXJ3cml0ZSBhbmQgc2V0IHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhlIHJlcG9zaXRvcnkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVwb3NpdG9yeU5hbWUgVGhlIHVuaXF1ZSBuYW1lIG9mIHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVzZXJuYW1lICAgICAgIFRoZSB1c2VybmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkcGFzc3dvcmQgICAgICAgVGhlIHBhc3N3b3JkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRyZXBvc2l0b3J5TmFtZSwgJHVzZXJuYW1lLCAkcGFzc3dvcmQgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aGFzQXV0aGVudGljYXRpb24oJHJlcG9zaXRvcnlOYW1lKSkgewogICAgICAgICAgICAkYXV0aCA9ICR0aGlzLT5nZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUpOwogICAgICAgICAgICBpZiAoJGF1dGhbJ3VzZXJuYW1lJ10gPT09ICR1c2VybmFtZSAmJiAkYXV0aFsncGFzc3dvcmQnXSA9PT0gJHBhc3N3b3JkKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKAogICAgICAgICAgICAgICAgc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAiPHdhcm5pbmc+V2FybmluZzogWW91IHNob3VsZCBhdm9pZCBvdmVyd3JpdGluZyBhbHJlYWR5IGRlZmluZWQgYXV0aCBzZXR0aW5ncyBmb3IgJXMuPC93YXJuaW5nPiIsCiAgICAgICAgICAgICAgICAgICAgJHJlcG9zaXRvcnlOYW1lCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5zZXRBdXRoZW50aWNhdGlvbigkcmVwb3NpdG9yeU5hbWUsICR1c2VybmFtZSwgJHBhc3N3b3JkKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRDb25maWd1cmF0aW9uKENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgICRiaXRidWNrZXRPYXV0aCA9ICRjb25maWctPmdldCgnYml0YnVja2V0LW9hdXRoJykgPzogYXJyYXkoKTsKICAgICAgICAkZ2l0aHViT2F1dGggPSAkY29uZmlnLT5nZXQoJ2dpdGh1Yi1vYXV0aCcpID86IGFycmF5KCk7CiAgICAgICAgJGdpdGxhYk9hdXRoID0gJGNvbmZpZy0+Z2V0KCdnaXRsYWItb2F1dGgnKSA/OiBhcnJheSgpOwogICAgICAgICRnaXRsYWJUb2tlbiA9ICRjb25maWctPmdldCgnZ2l0bGFiLXRva2VuJykgPzogYXJyYXkoKTsKICAgICAgICAkaHR0cEJhc2ljID0gJGNvbmZpZy0+Z2V0KCdodHRwLWJhc2ljJykgPzogYXJyYXkoKTsKICAgICAgICAkYmVhcmVyVG9rZW4gPSAkY29uZmlnLT5nZXQoJ2JlYXJlcicpID86IGFycmF5KCk7CgogICAgICAgIC8vIHJlbG9hZCBvYXV0aCB0b2tlbnMgZnJvbSBjb25maWcgaWYgYXZhaWxhYmxlCgogICAgICAgIGZvcmVhY2ggKCRiaXRidWNrZXRPYXV0aCBhcyAkZG9tYWluID0+ICRjcmVkKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICRjcmVkWydjb25zdW1lci1rZXknXSwgJGNyZWRbJ2NvbnN1bWVyLXNlY3JldCddKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRodWJPYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAvLyBhbGxvd2VkIGNoYXJzIGZvciBHSCB0b2tlbnMgYXJlIGZyb20gaHR0cHM6Ly9naXRodWIuYmxvZy9jaGFuZ2Vsb2cvMjAyMS0wMy0wNC1hdXRoZW50aWNhdGlvbi10b2tlbi1mb3JtYXQtdXBkYXRlcy8KICAgICAgICAgICAgLy8gcGx1cyBkb3RzIHdoaWNoIHdlcmUgYXQgc29tZSBwb2ludCB1c2VkIGZvciBHSCBhcHAgaW50ZWdyYXRpb24gdG9rZW5zCiAgICAgICAgICAgIGlmICghcHJlZ19tYXRjaCgne15bLkEtWmEtejAtOV9dKyR9JywgJHRva2VuKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ1lvdXIgZ2l0aHViIG9hdXRoIHRva2VuIGZvciAnLiRkb21haW4uJyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnM6ICInLiR0b2tlbi4nIicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR0b2tlbiwgJ3gtb2F1dGgtYmFzaWMnKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRsYWJPYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tBbmRTZXRBdXRoZW50aWNhdGlvbigkZG9tYWluLCAkdG9rZW4sICdvYXV0aDInKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRnaXRsYWJUb2tlbiBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAkdXNlcm5hbWUgPSBpc19hcnJheSgkdG9rZW4pICYmIGFycmF5X2tleV9leGlzdHMoInVzZXJuYW1lIiwgJHRva2VuKSA/ICR0b2tlblsidXNlcm5hbWUiXSA6ICR0b2tlbjsKICAgICAgICAgICAgJHBhc3N3b3JkID0gaXNfYXJyYXkoJHRva2VuKSAmJiBhcnJheV9rZXlfZXhpc3RzKCJ0b2tlbiIsICR0b2tlbikgPyAkdG9rZW5bInRva2VuIl0gOiAncHJpdmF0ZS10b2tlbic7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR1c2VybmFtZSwgJHBhc3N3b3JkKTsKICAgICAgICB9CgogICAgICAgIC8vIHJlbG9hZCBodHRwIGJhc2ljIGNyZWRlbnRpYWxzIGZyb20gY29uZmlnIGlmIGF2YWlsYWJsZQogICAgICAgIGZvcmVhY2ggKCRodHRwQmFzaWMgYXMgJGRvbWFpbiA9PiAkY3JlZCkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tBbmRTZXRBdXRoZW50aWNhdGlvbigkZG9tYWluLCAkY3JlZFsndXNlcm5hbWUnXSwgJGNyZWRbJ3Bhc3N3b3JkJ10pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGJlYXJlclRva2VuIGFzICRkb21haW4gPT4gJHRva2VuKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FuZFNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR0b2tlbiwgJ2JlYXJlcicpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2V0dXAgcHJvY2VzcyB0aW1lb3V0CiAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjpzZXRUaW1lb3V0KChpbnQpICRjb25maWctPmdldCgncHJvY2Vzcy10aW1lb3V0JykpOwogICAgfQoKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAkY29udGV4dAogICAgICogQHJldHVybiBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvZyhMb2dMZXZlbDo6RU1FUkdFTkNZLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAkY29udGV4dAogICAgICogQHJldHVybiBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGVydCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nKExvZ0xldmVsOjpBTEVSVCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyaXRpY2FsIGNvbmRpdGlvbnMuCiAgICAgKgogICAgICogRXhhbXBsZTogQXBwbGljYXRpb24gY29tcG9uZW50IHVuYXZhaWxhYmxlLCB1bmV4cGVjdGVkIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtICBhcnJheSAgJGNvbnRleHQKICAgICAqIEByZXR1cm4gbnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JpdGljYWwoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvZyhMb2dMZXZlbDo6Q1JJVElDQUwsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW50aW1lIGVycm9ycyB0aGF0IGRvIG5vdCByZXF1aXJlIGltbWVkaWF0ZSBhY3Rpb24gYnV0IHNob3VsZCB0eXBpY2FsbHkKICAgICAqIGJlIGxvZ2dlZCBhbmQgbW9uaXRvcmVkLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAkY29udGV4dAogICAgICogQHJldHVybiBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nKExvZ0xldmVsOjpFUlJPUiwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtICBhcnJheSAgJGNvbnRleHQKICAgICAqIEByZXR1cm4gbnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nKExvZ0xldmVsOjpXQVJOSU5HLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogTm9ybWFsIGJ1dCBzaWduaWZpY2FudCBldmVudHMuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSAgYXJyYXkgICRjb250ZXh0CiAgICAgKiBAcmV0dXJuIG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGljZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nKExvZ0xldmVsOjpOT1RJQ0UsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcmVzdGluZyBldmVudHMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlciBsb2dzIGluLCBTUUwgbG9ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtICBhcnJheSAgJGNvbnRleHQKICAgICAqIEByZXR1cm4gbnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9nKExvZ0xldmVsOjpJTkZPLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRGV0YWlsZWQgZGVidWcgaW5mb3JtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSAgYXJyYXkgICRjb250ZXh0CiAgICAgKiBAcmV0dXJuIG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlYnVnKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2coTG9nTGV2ZWw6OkRFQlVHLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogTG9ncyB3aXRoIGFuIGFyYml0cmFyeSBsZXZlbC4KICAgICAqCiAgICAgKiBAcGFyYW0gIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSAgc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAkY29udGV4dAogICAgICogQHJldHVybiBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2coJGxldmVsLCAkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmIChpbl9hcnJheSgkbGV2ZWwsIGFycmF5KExvZ0xldmVsOjpFTUVSR0VOQ1ksIExvZ0xldmVsOjpBTEVSVCwgTG9nTGV2ZWw6OkNSSVRJQ0FMLCBMb2dMZXZlbDo6RVJST1IpKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVFcnJvcignPGVycm9yPicuJG1lc3NhZ2UuJzwvZXJyb3I+Jyk7CiAgICAgICAgfSBlbHNlaWYgKCRsZXZlbCA9PT0gTG9nTGV2ZWw6OldBUk5JTkcpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJG1lc3NhZ2UuJzwvd2FybmluZz4nKTsKICAgICAgICB9IGVsc2VpZiAoJGxldmVsID09PSBMb2dMZXZlbDo6Tk9USUNFKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKCc8aW5mbz4nLiRtZXNzYWdlLic8L2luZm8+JywgdHJ1ZSwgc2VsZjo6VkVSQk9TRSk7CiAgICAgICAgfSBlbHNlaWYgKCRsZXZlbCA9PT0gTG9nTGV2ZWw6OklORk8pIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlRXJyb3IoJzxpbmZvPicuJG1lc3NhZ2UuJzwvaW5mbz4nLCB0cnVlLCBzZWxmOjpWRVJZX1ZFUkJPU0UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZUVycm9yKCRtZXNzYWdlLCB0cnVlLCBzZWxmOjpERUJVRyk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcU3RyZWFtT3V0cHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XFN0cmluZ0lucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcSGVscGVyU2V0OwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEJ1ZmZlcklPIGV4dGVuZHMgQ29uc29sZUlPCnsKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dAogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkKICAgICAqIEBwYXJhbSBPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2V8bnVsbCAkZm9ybWF0dGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5wdXQgPSAnJywgJHZlcmJvc2l0eSA9IFN0cmVhbU91dHB1dDo6VkVSQk9TSVRZX05PUk1BTCwgT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIgPSBudWxsKQogICAgewogICAgICAgICRpbnB1dCA9IG5ldyBTdHJpbmdJbnB1dCgkaW5wdXQpOwogICAgICAgICRpbnB1dC0+c2V0SW50ZXJhY3RpdmUoZmFsc2UpOwoKICAgICAgICAkb3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vbWVtb3J5JywgJ3J3JyksICR2ZXJib3NpdHksICRmb3JtYXR0ZXIgPyAkZm9ybWF0dGVyLT5pc0RlY29yYXRlZCgpIDogZmFsc2UsICRmb3JtYXR0ZXIpOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpbnB1dCwgJG91dHB1dCwgbmV3IEhlbHBlclNldChhcnJheSgKICAgICAgICAgICAgbmV3IFF1ZXN0aW9uSGVscGVyKCksCiAgICAgICAgKSkpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdXRwdXQoKQogICAgewogICAgICAgIGZzZWVrKCR0aGlzLT5vdXRwdXQtPmdldFN0cmVhbSgpLCAwKTsKCiAgICAgICAgJG91dHB1dCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPm91dHB1dC0+Z2V0U3RyZWFtKCkpOwoKICAgICAgICAkb3V0cHV0ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCJ7KD88PV58XG58XHgwOCkoLis/KShceDA4Kyl9IiwgZnVuY3Rpb24gKCRtYXRjaGVzKSB7CiAgICAgICAgICAgICRwcmUgPSBzdHJpcF90YWdzKCRtYXRjaGVzWzFdKTsKCiAgICAgICAgICAgIGlmIChzdHJsZW4oJHByZSkgPT09IHN0cmxlbigkbWF0Y2hlc1syXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVE9ETyByZXZlcnNlIHBhcnNlIHRoZSBzdHJpbmcsIHNraXBwaW5nIHNwYW4gdGFncyBhbmQgXDAzM1xbKFswLTk7XSspbSguKj8pXDAzM1xbMG0gc3R5bGUgYmxvYnMKICAgICAgICAgICAgcmV0dXJuIHJ0cmltKCRtYXRjaGVzWzFdKS4iXG4iOwogICAgICAgIH0sICRvdXRwdXQpOwoKICAgICAgICByZXR1cm4gJG91dHB1dDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXNlcklucHV0cyhhcnJheSAkaW5wdXRzKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlucHV0IGluc3RhbmNlb2YgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignU2V0dGluZyB0aGUgdXNlciBpbnB1dHMgcmVxdWlyZXMgYXQgbGVhc3QgdGhlIHZlcnNpb24gMy4yIG9mIHRoZSBzeW1mb255L2NvbnNvbGUgY29tcG9uZW50LicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlucHV0LT5zZXRTdHJlYW0oJHRoaXMtPmNyZWF0ZVN0cmVhbSgkaW5wdXRzKSk7CiAgICAgICAgJHRoaXMtPmlucHV0LT5zZXRJbnRlcmFjdGl2ZSh0cnVlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbShhcnJheSAkaW5wdXRzKQogICAgewogICAgICAgICRzdHJlYW0gPSBmb3BlbigncGhwOi8vbWVtb3J5JywgJ3IrJyk7CgogICAgICAgIGZvcmVhY2ggKCRpbnB1dHMgYXMgJGlucHV0KSB7CiAgICAgICAgICAgIGZ3cml0ZSgkc3RyZWFtLCAkaW5wdXQuUEhQX0VPTCk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJHN0cmVhbSk7CgogICAgICAgIHJldHVybiAkc3RyZWFtOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXElPOwoKLyoqCiAqIElPSW50ZXJmYWNlIHRoYXQgaXMgbm90IGludGVyYWN0aXZlIGFuZCBuZXZlciB3cml0ZXMgdGhlIG91dHB1dAogKgogKiBAYXV0aG9yIENocmlzdG9waGUgQ29ldm9ldCA8c3RvZkBub3RrLm9yZz4KICovCmNsYXNzIE51bGxJTyBleHRlbmRzIEJhc2VJTwp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWJ1ZygpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVFcnJvcigkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gdHJ1ZSwgJHNpemUgPSA4MCwgJHZlcmJvc2l0eSA9IHNlbGY6Ok5PUk1BTCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG92ZXJ3cml0ZUVycm9yKCRtZXNzYWdlcywgJG5ld2xpbmUgPSB0cnVlLCAkc2l6ZSA9IDgwLCAkdmVyYm9zaXR5ID0gc2VsZjo6Tk9STUFMKQogICAgewogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0ID0gdHJ1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tBbmRWYWxpZGF0ZSgkcXVlc3Rpb24sICR2YWxpZGF0b3IsICRhdHRlbXB0cyA9IGZhbHNlLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrQW5kSGlkZUFuc3dlcigkcXVlc3Rpb24pCiAgICB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWxlY3QoJHF1ZXN0aW9uLCAkY2hvaWNlcywgJGRlZmF1bHQsICRhdHRlbXB0cyA9IGZhbHNlLCAkZXJyb3JNZXNzYWdlID0gJ1ZhbHVlICIlcyIgaXMgaW52YWxpZCcsICRtdWx0aXNlbGVjdCA9IGZhbHNlKQogICAgewogICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgUGF1bCBXZW5rZSA8d2Vua2UucGF1bEBnbWFpbC5jb20+CiAqLwpjbGFzcyBCaXRidWNrZXQKewogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcml2YXRlICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByaXZhdGUgJHByb2Nlc3M7CiAgICAvKiogQHZhciBIdHRwRG93bmxvYWRlciAqLwogICAgcHJpdmF0ZSAkaHR0cERvd25sb2FkZXI7CiAgICAvKiogQHZhciBhcnJheSAqLwogICAgcHJpdmF0ZSAkdG9rZW4gPSBhcnJheSgpOwogICAgLyoqIEB2YXIgaW50fG51bGwgKi8KICAgIHByaXZhdGUgJHRpbWU7CgogICAgY29uc3QgT0FVVEgyX0FDQ0VTU19UT0tFTl9VUkwgPSAnaHR0cHM6Ly9iaXRidWNrZXQub3JnL3NpdGUvb2F1dGgyL2FjY2Vzc190b2tlbic7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgJGNvbmZpZyAgICAgICAgIFRoZSBjb21wb3NlciBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzICAgICAgICBQcm9jZXNzIGluc3RhbmNlLCBpbmplY3RhYmxlIGZvciBtb2NraW5nCiAgICAgKiBAcGFyYW0gSHR0cERvd25sb2FkZXIgICRodHRwRG93bmxvYWRlciBSZW1vdGUgRmlsZXN5c3RlbSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkdGltZSAgICAgICAgICAgVGltZXN0YW1wLCBpbmplY3RhYmxlIGZvciBtb2NraW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsLCBIdHRwRG93bmxvYWRlciAkaHR0cERvd25sb2FkZXIgPSBudWxsLCAkdGltZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlciA/OiBGYWN0b3J5OjpjcmVhdGVIdHRwRG93bmxvYWRlcigkdGhpcy0+aW8sICRjb25maWcpOwogICAgICAgICR0aGlzLT50aW1lID0gJHRpbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VG9rZW4oKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnRva2VuWydhY2Nlc3NfdG9rZW4nXSkpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT50b2tlblsnYWNjZXNzX3Rva2VuJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBhdXRob3JpemUgYSBCaXRidWNrZXQgZG9tYWluIHZpYSBPQXV0aAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvcmlnaW5VcmwgVGhlIGhvc3QgdGhpcyBCaXRidWNrZXQgaW5zdGFuY2UgaXMgbG9jYXRlZCBhdAogICAgICogQHJldHVybiBib29sICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aCgkb3JpZ2luVXJsKQogICAgewogICAgICAgIGlmICgkb3JpZ2luVXJsICE9PSAnYml0YnVja2V0Lm9yZycpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgYXZhaWxhYmxlIHVzZSB0b2tlbiBmcm9tIGdpdCBjb25maWcKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBjb25maWcgYml0YnVja2V0LmFjY2Vzc3Rva2VuJywgJG91dHB1dCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAneC10b2tlbi1hdXRoJywgdHJpbSgkb3V0cHV0KSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlcXVlc3RBY2Nlc3NUb2tlbigpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoc2VsZjo6T0FVVEgyX0FDQ0VTU19UT0tFTl9VUkwsIGFycmF5KAogICAgICAgICAgICAgICAgJ3JldHJ5LWF1dGgtZmFpbHVyZScgPT4gZmFsc2UsCiAgICAgICAgICAgICAgICAnaHR0cCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ21ldGhvZCcgPT4gJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgICdjb250ZW50JyA9PiAnZ3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMnLAogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgKSk7CgogICAgICAgICAgICAkdGhpcy0+dG9rZW4gPSAkcmVzcG9uc2UtPmRlY29kZUpzb24oKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IDQwMCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+SW52YWxpZCBPQXV0aCBjb25zdW1lciBwcm92aWRlZC48L2Vycm9yPicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdUaGlzIGNhbiBoYXZlIHR3byByZWFzb25zOicpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcxLiBZb3UgYXJlIGF1dGhlbnRpY2F0aW5nIHdpdGggYSBiaXRidWNrZXQgdXNlcm5hbWUvcGFzc3dvcmQgY29tYmluYXRpb24nKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignMi4gWW91IGFyZSB1c2luZyBhbiBPQXV0aCBjb25zdW1lciwgYnV0IGRpZG5cJ3QgY29uZmlndXJlIGEgKGR1bW15KSBjYWxsYmFjayB1cmwnKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGluX2FycmF5KCRlLT5nZXRDb2RlKCksIGFycmF5KDQwMywgNDAxKSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPkludmFsaWQgT0F1dGggY29uc3VtZXIgcHJvdmlkZWQuPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIGFkZCBpdCBtYW51YWxseSBsYXRlciBieSB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBiaXRidWNrZXQtb2F1dGguYml0YnVja2V0Lm9yZyA8Y29uc3VtZXIta2V5PiA8Y29uc3VtZXItc2VjcmV0PiInKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdXRob3JpemVzIGEgQml0YnVja2V0IGRvbWFpbiBpbnRlcmFjdGl2ZWx5IHZpYSBPQXV0aAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgJG9yaWdpblVybCBUaGUgaG9zdCB0aGlzIEJpdGJ1Y2tldCBpbnN0YW5jZSBpcyBsb2NhdGVkIGF0CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlICAgVGhlIHJlYXNvbiB0aGlzIGF1dGhvcml6YXRpb24gaXMgcmVxdWlyZWQKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEB0aHJvd3MgVHJhbnNwb3J0RXhjZXB0aW9ufFxFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG9yaWdpblVybCwgJG1lc3NhZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICgkbWVzc2FnZSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG1lc3NhZ2UpOwogICAgICAgIH0KCiAgICAgICAgJHVybCA9ICdodHRwczovL3N1cHBvcnQuYXRsYXNzaWFuLmNvbS9iaXRidWNrZXQtY2xvdWQvZG9jcy91c2Utb2F1dGgtb24tYml0YnVja2V0LWNsb3VkLyc7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJ0ZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIG9uICVzJywgJHVybCkpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCd0byBjcmVhdGUgYSBjb25zdW1lci4gSXQgd2lsbCBiZSBzdG9yZWQgaW4gIiVzIiBmb3IgZnV0dXJlIHVzZSBieSBDb21wb3Nlci4nLCAkdGhpcy0+Y29uZmlnLT5nZXRBdXRoQ29uZmlnU291cmNlKCktPmdldE5hbWUoKSkpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRW5zdXJlIHlvdSBlbnRlciBhICJDYWxsYmFjayBVUkwiIChodHRwOi8vZXhhbXBsZS5jb20gaXMgZmluZSkgb3IgaXQgd2lsbCBub3QgYmUgcG9zc2libGUgdG8gY3JlYXRlIGFuIEFjY2VzcyBUb2tlbiAodGhpcyBjYWxsYmFjayB1cmwgd2lsbCBub3QgYmUgdXNlZCBieSBjb21wb3NlciknKTsKCiAgICAgICAgJGNvbnN1bWVyS2V5ID0gdHJpbSgkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJ0NvbnN1bWVyIEtleSAoaGlkZGVuKTogJykpOwoKICAgICAgICBpZiAoISRjb25zdW1lcktleSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPk5vIGNvbnN1bWVyIGtleSBnaXZlbiwgYWJvcnRpbmcuPC93YXJuaW5nPicpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1lvdSBjYW4gYWxzbyBhZGQgaXQgbWFudWFsbHkgbGF0ZXIgYnkgdXNpbmcgImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLWF1dGggYml0YnVja2V0LW9hdXRoLmJpdGJ1Y2tldC5vcmcgPGNvbnN1bWVyLWtleT4gPGNvbnN1bWVyLXNlY3JldD4iJyk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkY29uc3VtZXJTZWNyZXQgPSB0cmltKCR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcignQ29uc3VtZXIgU2VjcmV0IChoaWRkZW4pOiAnKSk7CgogICAgICAgIGlmICghJGNvbnN1bWVyU2VjcmV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Tm8gY29uc3VtZXIgc2VjcmV0IGdpdmVuLCBhYm9ydGluZy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIGFkZCBpdCBtYW51YWxseSBsYXRlciBieSB1c2luZyAiY29tcG9zZXIgY29uZmlnIC0tZ2xvYmFsIC0tYXV0aCBiaXRidWNrZXQtb2F1dGguYml0YnVja2V0Lm9yZyA8Y29uc3VtZXIta2V5PiA8Y29uc3VtZXItc2VjcmV0PiInKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgJGNvbnN1bWVyS2V5LCAkY29uc3VtZXJTZWNyZXQpOwoKICAgICAgICBpZiAoISR0aGlzLT5yZXF1ZXN0QWNjZXNzVG9rZW4oKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpbiB1c2VyIGNvbmZpZwogICAgICAgICR0aGlzLT5zdG9yZUluQXV0aENvbmZpZygkb3JpZ2luVXJsLCAkY29uc3VtZXJLZXksICRjb25zdW1lclNlY3JldCk7CgogICAgICAgIC8vIFJlbW92ZSBjb25mbGljdGluZyBiYXNpYyBhdXRoIGNyZWRlbnRpYWxzIChpZiBhdmFpbGFibGUpCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5yZW1vdmVDb25maWdTZXR0aW5nKCdodHRwLWJhc2ljLicgLiAkb3JpZ2luVXJsKTsKCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz5Db25zdW1lciBzdG9yZWQgc3VjY2Vzc2Z1bGx5LjwvaW5mbz4nKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgYW4gYWNjZXNzIHRva2VuIGZyb20gQml0YnVja2V0LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvcmlnaW5VcmwKICAgICAqIEBwYXJhbSAgc3RyaW5nICRjb25zdW1lcktleQogICAgICogQHBhcmFtICBzdHJpbmcgJGNvbnN1bWVyU2VjcmV0CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVxdWVzdFRva2VuKCRvcmlnaW5VcmwsICRjb25zdW1lcktleSwgJGNvbnN1bWVyU2VjcmV0KQogICAgewogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPnRva2VuKSB8fCAkdGhpcy0+Z2V0VG9rZW5Gcm9tQ29uZmlnKCRvcmlnaW5VcmwpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkY29uc3VtZXJLZXksICRjb25zdW1lclNlY3JldCk7CiAgICAgICAgaWYgKCEkdGhpcy0+cmVxdWVzdEFjY2Vzc1Rva2VuKCkpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0b3JlSW5BdXRoQ29uZmlnKCRvcmlnaW5VcmwsICRjb25zdW1lcktleSwgJGNvbnN1bWVyU2VjcmV0KTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT50b2tlblsnYWNjZXNzX3Rva2VuJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSB0aGUgbmV3L3VwZGF0ZWQgY3JlZGVudGlhbHMgdG8gdGhlIGNvbmZpZ3VyYXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpblVybAogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3VtZXJLZXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN1bWVyU2VjcmV0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc3RvcmVJbkF1dGhDb25maWcoJG9yaWdpblVybCwgJGNvbnN1bWVyS2V5LCAkY29uc3VtZXJTZWNyZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0Q29uZmlnU291cmNlKCktPnJlbW92ZUNvbmZpZ1NldHRpbmcoJ2JpdGJ1Y2tldC1vYXV0aC4nLiRvcmlnaW5VcmwpOwoKICAgICAgICAkdGltZSA9IG51bGwgPT09ICR0aGlzLT50aW1lID8gdGltZSgpIDogJHRoaXMtPnRpbWU7CiAgICAgICAgJGNvbnN1bWVyID0gYXJyYXkoCiAgICAgICAgICAgICJjb25zdW1lci1rZXkiID0+ICRjb25zdW1lcktleSwKICAgICAgICAgICAgImNvbnN1bWVyLXNlY3JldCIgPT4gJGNvbnN1bWVyU2VjcmV0LAogICAgICAgICAgICAiYWNjZXNzLXRva2VuIiA9PiAkdGhpcy0+dG9rZW5bJ2FjY2Vzc190b2tlbiddLAogICAgICAgICAgICAiYWNjZXNzLXRva2VuLWV4cGlyYXRpb24iID0+ICR0aW1lICsgJHRoaXMtPnRva2VuWydleHBpcmVzX2luJ10sCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5hZGRDb25maWdTZXR0aW5nKCdiaXRidWNrZXQtb2F1dGguJy4kb3JpZ2luVXJsLCAkY29uc3VtZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9yaWdpblVybAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VG9rZW5Gcm9tQ29uZmlnKCRvcmlnaW5VcmwpCiAgICB7CiAgICAgICAgJGF1dGhDb25maWcgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2JpdGJ1Y2tldC1vYXV0aCcpOwoKICAgICAgICBpZiAoCiAgICAgICAgICAgICFpc3NldCgkYXV0aENvbmZpZ1skb3JpZ2luVXJsXVsnYWNjZXNzLXRva2VuJ10sICRhdXRoQ29uZmlnWyRvcmlnaW5VcmxdWydhY2Nlc3MtdG9rZW4tZXhwaXJhdGlvbiddKQogICAgICAgICAgICB8fCB0aW1lKCkgPiAkYXV0aENvbmZpZ1skb3JpZ2luVXJsXVsnYWNjZXNzLXRva2VuLWV4cGlyYXRpb24nXQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dG9rZW4gPSBhcnJheSgKICAgICAgICAgICAgJ2FjY2Vzc190b2tlbicgPT4gJGF1dGhDb25maWdbJG9yaWdpblVybF1bJ2FjY2Vzcy10b2tlbiddLAogICAgICAgICk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxEb3dubG9hZGVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlSW50ZXJmYWNlOwoKY2xhc3MgU3luY0hlbHBlcgp7CiAgICAvKioKICAgICAqIEhlbHBzIHlvdSBkb3dubG9hZCArIGluc3RhbGwgYSBzaW5nbGUgcGFja2FnZSBpbiBhIHN5bmNocm9ub3VzIHdheQogICAgICoKICAgICAqIFRoaXMgZXhlY3V0ZXMgYWxsIHRoZSByZXF1aXJlZCBzdGVwcyBhbmQgd2FpdHMgZm9yIHByb21pc2VzIHRvIGNvbXBsZXRlCiAgICAgKgogICAgICogQHBhcmFtIExvb3AgICAgICAgICAgICAgICAgICAkbG9vcCAgICAgICAgTG9vcCBpbnN0YW5jZSB3aGljaCB5b3UgY2FuIGdldCBmcm9tICRjb21wb3Nlci0+Z2V0TG9vcCgpCiAgICAgKiBAcGFyYW0gRG93bmxvYWRlckludGVyZmFjZSAgICRkb3dubG9hZGVyICBEb3dubG9hZGVyIGluc3RhbmNlIHlvdSBjYW4gZ2V0IGZyb20gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKS0+Z2V0RG93bmxvYWRlcignemlwJykgZm9yIGV4YW1wbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJHBhdGggICAgICAgIHRoZSBpbnN0YWxsYXRpb24gcGF0aCBmb3IgdGhlIHBhY2thZ2UKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgICAgIHRoZSBwYWNrYWdlIHRvIGluc3RhbGwKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlfG51bGwgJHByZXZQYWNrYWdlIHRoZSBwcmV2aW91cyBwYWNrYWdlIGlmIHRoaXMgaXMgYW4gdXBkYXRlIGFuZCBub3QgYW4gaW5pdGlhbCBpbnN0YWxsYXRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkb3dubG9hZEFuZEluc3RhbGxQYWNrYWdlU3luYyhMb29wICRsb29wLCBEb3dubG9hZGVySW50ZXJmYWNlICRkb3dubG9hZGVyLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICR0eXBlID0gJHByZXZQYWNrYWdlID8gJ3VwZGF0ZScgOiAnaW5zdGFsbCc7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+ZG93bmxvYWQoJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpKTsKCiAgICAgICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpKTsKCiAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gJ3VwZGF0ZScpIHsKICAgICAgICAgICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+dXBkYXRlKCRwYWNrYWdlLCAkcGF0aCwgJHByZXZQYWNrYWdlKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWxmOjphd2FpdCgkbG9vcCwgJGRvd25sb2FkZXItPmluc3RhbGwoJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgc2VsZjo6YXdhaXQoJGxvb3AsICRkb3dubG9hZGVyLT5jbGVhbnVwKCR0eXBlLCAkcGFja2FnZSwgJHBhdGgsICRwcmV2UGFja2FnZSkpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OmF3YWl0KCRsb29wLCAkZG93bmxvYWRlci0+Y2xlYW51cCgkdHlwZSwgJHBhY2thZ2UsICRwYXRoLCAkcHJldlBhY2thZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdhaXRzIGZvciBhIHByb21pc2UgdG8gcmVzb2x2ZQogICAgICoKICAgICAqIEBwYXJhbSBMb29wICAgICAgICAgICAgICAgICAgJGxvb3AgICAgTG9vcCBpbnN0YW5jZSB3aGljaCB5b3UgY2FuIGdldCBmcm9tICRjb21wb3Nlci0+Z2V0TG9vcCgpCiAgICAgKiBAcGFyYW0gUHJvbWlzZUludGVyZmFjZXxudWxsICRwcm9taXNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYXdhaXQoTG9vcCAkbG9vcCwgUHJvbWlzZUludGVyZmFjZSAkcHJvbWlzZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRwcm9taXNlKSB7CiAgICAgICAgICAgICRsb29wLT53YWl0KGFycmF5KCRwcm9taXNlKSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3NVdGlsczsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFJ1bnRpbWVFeGNlcHRpb247CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2U7CgovKioKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFByb2Nlc3NFeGVjdXRvcgp7CiAgICBjb25zdCBTVEFUVVNfUVVFVUVEID0gMTsKICAgIGNvbnN0IFNUQVRVU19TVEFSVEVEID0gMjsKICAgIGNvbnN0IFNUQVRVU19DT01QTEVURUQgPSAzOwogICAgY29uc3QgU1RBVFVTX0ZBSUxFRCA9IDQ7CiAgICBjb25zdCBTVEFUVVNfQUJPUlRFRCA9IDU7CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkdGltZW91dCA9IDMwMDsKCiAgICBwcm90ZWN0ZWQgJGNhcHR1cmVPdXRwdXQ7CiAgICBwcm90ZWN0ZWQgJGVycm9yT3V0cHV0OwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKioKICAgICAqIEBwc2FsbS12YXIgYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIG1peGVkPj4KICAgICAqLwogICAgcHJpdmF0ZSAkam9icyA9IGFycmF5KCk7CiAgICBwcml2YXRlICRydW5uaW5nSm9icyA9IDA7CiAgICBwcml2YXRlICRtYXhKb2JzID0gMTA7CiAgICBwcml2YXRlICRpZEdlbiA9IDA7CiAgICBwcml2YXRlICRhbGxvd0FzeW5jID0gZmFsc2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICogcnVucyBhIHByb2Nlc3Mgb24gdGhlIGNvbW1hbmRsaW5lCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGNvbW1hbmQgdGhlIGNvbW1hbmQgdG8gZXhlY3V0ZQogICAgICogQHBhcmFtICBtaXhlZCAgJG91dHB1dCAgdGhlIG91dHB1dCB3aWxsIGJlIHdyaXR0ZW4gaW50byB0aGlzIHZhciBpZiBwYXNzZWQgYnkgcmVmCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBpZiBhIGNhbGxhYmxlIGlzIHBhc3NlZCBpdCB3aWxsIGJlIHVzZWQgYXMgb3V0cHV0IGhhbmRsZXIKICAgICAqIEBwYXJhbSAgc3RyaW5nICRjd2QgICAgIHRoZSB3b3JraW5nIGRpcmVjdG9yeQogICAgICogQHJldHVybiBpbnQgICAgc3RhdHVzY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZSgkY29tbWFuZCwgJiRvdXRwdXQgPSBudWxsLCAkY3dkID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoZnVuY19udW1fYXJncygpID4gMSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvRXhlY3V0ZSgkY29tbWFuZCwgJGN3ZCwgZmFsc2UsICRvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb0V4ZWN1dGUoJGNvbW1hbmQsICRjd2QsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHJ1bnMgYSBwcm9jZXNzIG9uIHRoZSBjb21tYW5kbGluZSBpbiBUVFkgbW9kZQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRjb21tYW5kIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGUKICAgICAqIEBwYXJhbSAgc3RyaW5nICRjd2QgICAgIHRoZSB3b3JraW5nIGRpcmVjdG9yeQogICAgICogQHJldHVybiBpbnQgICAgc3RhdHVzY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZVR0eSgkY29tbWFuZCwgJGN3ZCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1R0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9FeGVjdXRlKCRjb21tYW5kLCAkY3dkLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG9FeGVjdXRlKCRjb21tYW5kLCAkY3dkLCBmYWxzZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBkb0V4ZWN1dGUoJGNvbW1hbmQsICRjd2QsICR0dHksICYkb3V0cHV0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlvICYmICR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICRzYWZlQ29tbWFuZCA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygnezovLyg/UDx1c2VyPlteOi9cc10rKTooP1A8cGFzc3dvcmQ+W15AXHMvXSspQH1pJywgZnVuY3Rpb24gKCRtKSB7CiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdXNlcm5hbWUgbG9va3MgbGlrZSBhIGxvbmcgKDEyY2hhcispIGhleCBzdHJpbmcsIG9yIGEgbW9kZXJuIGdpdGh1YiB0b2tlbiAoZS5nLiBnaHBfeHh4KSB3ZSBvYmZ1c2NhdGUgdGhhdAogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFthLWYwLTldezEyLH18Z2hbYS16XV9bYS16QS1aMC05X10rKSR9JywgJG1bJ3VzZXInXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzovLyoqKjoqKipAJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJzovLycuJG1bJ3VzZXInXS4nOioqKkAnOwogICAgICAgICAgICB9LCAkY29tbWFuZCk7CiAgICAgICAgICAgICRzYWZlQ29tbWFuZCA9IHByZWdfcmVwbGFjZSgiey0tcGFzc3dvcmQgKC4qW15cXFxcXVwnKSB9IiwgJy0tcGFzc3dvcmQgXCcqKipcJyAnLCAkc2FmZUNvbW1hbmQpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0V4ZWN1dGluZyBjb21tYW5kICgnLigkY3dkID86ICdDV0QnKS4nKTogJy4kc2FmZUNvbW1hbmQpOwogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETyBpbiAyLjIsIHRoZXNlIHR3byBjaGVja3MgY2FuIGJlIGRyb3BwZWQgYXMgU3ltZm9ueSA0KyBzdXBwb3J0cyB0aGVtIG91dCBvZiB0aGUgYm94CiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgbnVsbCB0cmFuc2xhdGUgdG8gdGhlIHByb3BlciBkaXJlY3RvcnkgaW4gY2FzZSB0aGUgZGlyIGlzIGEgc3ltbGluawogICAgICAgIC8vIGFuZCB3ZSBjYWxsIGEgZ2l0IGNvbW1hbmQsIGJlY2F1c2UgbXN5c2dpdCBkb2VzIG5vdCBoYW5kbGUgc3ltbGlua3MgcHJvcGVybHkKICAgICAgICBpZiAobnVsbCA9PT0gJGN3ZCAmJiBQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgZmFsc2UgIT09IHN0cnBvcygkY29tbWFuZCwgJ2dpdCcpICYmIGdldGN3ZCgpKSB7CiAgICAgICAgICAgICRjd2QgPSByZWFscGF0aChnZXRjd2QoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkY3dkICYmICFpc19kaXIoJGN3ZCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgZ2l2ZW4gQ1dEIGZvciB0aGUgcHJvY2VzcyBkb2VzIG5vdCBleGlzdDogJy4kY3dkKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jYXB0dXJlT3V0cHV0ID0gZnVuY19udW1fYXJncygpID4gMzsKICAgICAgICAkdGhpcy0+ZXJyb3JPdXRwdXQgPSBudWxsOwoKICAgICAgICAvLyBUT0RPIGluIHYzLCBjb21tYW5kcyBzaG91bGQgYmUgcGFzc2VkIGluIGFzIGFycmF5cyBvZiBjbWQgKyBhcmdzCiAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJ1N5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzcycsICdmcm9tU2hlbGxDb21tYW5kbGluZScpKSB7CiAgICAgICAgICAgICRwcm9jZXNzID0gUHJvY2Vzczo6ZnJvbVNoZWxsQ29tbWFuZGxpbmUoJGNvbW1hbmQsICRjd2QsIG51bGwsIG51bGwsIHN0YXRpYzo6Z2V0VGltZW91dCgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCRjb21tYW5kLCAkY3dkLCBudWxsLCBudWxsLCBzdGF0aWM6OmdldFRpbWVvdXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpICYmICR0dHkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRwcm9jZXNzLT5zZXRUdHkodHJ1ZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBUVFkgZW5hYmxpbmcgZXJyb3JzCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjYWxsYmFjayA9IGlzX2NhbGxhYmxlKCRvdXRwdXQpID8gJG91dHB1dCA6IGFycmF5KCR0aGlzLCAnb3V0cHV0SGFuZGxlcicpOwogICAgICAgICRwcm9jZXNzLT5ydW4oJGNhbGxiYWNrKTsKCiAgICAgICAgaWYgKCR0aGlzLT5jYXB0dXJlT3V0cHV0ICYmICFpc19jYWxsYWJsZSgkb3V0cHV0KSkgewogICAgICAgICAgICAkb3V0cHV0ID0gJHByb2Nlc3MtPmdldE91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmVycm9yT3V0cHV0ID0gJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CgogICAgICAgIHJldHVybiAkcHJvY2Vzcy0+Z2V0RXhpdENvZGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHN0YXJ0cyBhIHByb2Nlc3Mgb24gdGhlIGNvbW1hbmRsaW5lIGluIGFzeW5jIG1vZGUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgJGNvbW1hbmQgdGhlIGNvbW1hbmQgdG8gZXhlY3V0ZQogICAgICogQHBhcmFtICBzdHJpbmcgICRjd2QgICAgIHRoZSB3b3JraW5nIGRpcmVjdG9yeQogICAgICogQHJldHVybiBQcm9taXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlQXN5bmMoJGNvbW1hbmQsICRjd2QgPSBudWxsKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmFsbG93QXN5bmMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignWW91IG11c3QgdXNlIHRoZSBQcm9jZXNzRXhlY3V0b3IgaW5zdGFuY2Ugd2hpY2ggaXMgcGFydCBvZiBhIENvbXBvc2VyXExvb3AgaW5zdGFuY2UgdG8gYmUgYWJsZSB0byBydW4gYXN5bmMgcHJvY2Vzc2VzJyk7CiAgICAgICAgfQoKICAgICAgICAkam9iID0gYXJyYXkoCiAgICAgICAgICAgICdpZCcgPT4gJHRoaXMtPmlkR2VuKyssCiAgICAgICAgICAgICdzdGF0dXMnID0+IHNlbGY6OlNUQVRVU19RVUVVRUQsCiAgICAgICAgICAgICdjb21tYW5kJyA9PiAkY29tbWFuZCwKICAgICAgICAgICAgJ2N3ZCcgPT4gJGN3ZCwKICAgICAgICApOwoKICAgICAgICAkcmVzb2x2ZXIgPSBmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QpIHVzZSAoJiRqb2IpIHsKICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19RVUVVRUQ7CiAgICAgICAgICAgICRqb2JbJ3Jlc29sdmUnXSA9ICRyZXNvbHZlOwogICAgICAgICAgICAkam9iWydyZWplY3QnXSA9ICRyZWplY3Q7CiAgICAgICAgfTsKCiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgJGNhbmNlbGVyID0gZnVuY3Rpb24gKCkgdXNlICgmJGpvYikgewogICAgICAgICAgICBpZiAoJGpvYlsnc3RhdHVzJ10gPT09IFByb2Nlc3NFeGVjdXRvcjo6U1RBVFVTX1FVRVVFRCkgewogICAgICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19BQk9SVEVEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSAhPT0gUHJvY2Vzc0V4ZWN1dG9yOjpTVEFUVVNfU1RBUlRFRCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gUHJvY2Vzc0V4ZWN1dG9yOjpTVEFUVVNfQUJPUlRFRDsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChkZWZpbmVkKCdTSUdJTlQnKSkgewogICAgICAgICAgICAgICAgICAgICRqb2JbJ3Byb2Nlc3MnXS0+c2lnbmFsKFNJR0lOVCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIHNpZ25hbCBjYW4gdGhyb3cgaW4gdmFyaW91cyBjb25kaXRpb25zLCBidXQgd2UgZG9uJ3QgY2FyZSBpZiBpdCBmYWlscwogICAgICAgICAgICB9CiAgICAgICAgICAgICRqb2JbJ3Byb2Nlc3MnXS0+c3RvcCgxKTsKCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQWJvcnRlZCBwcm9jZXNzJyk7CiAgICAgICAgfTsKCiAgICAgICAgJHByb21pc2UgPSBuZXcgUHJvbWlzZSgkcmVzb2x2ZXIsICRjYW5jZWxlcik7CiAgICAgICAgJHByb21pc2UgPSAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCYkam9iLCAkc2VsZikgewogICAgICAgICAgICBpZiAoJGpvYlsncHJvY2VzcyddLT5pc1N1Y2Nlc3NmdWwoKSkgewogICAgICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBQcm9jZXNzRXhlY3V0b3I6OlNUQVRVU19DT01QTEVURUQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IFByb2Nlc3NFeGVjdXRvcjo6U1RBVFVTX0ZBSUxFRDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVE9ETyAzLjAgdGhpcyBzaG91bGQgYmUgZG9uZSBkaXJlY3RseSBvbiAkdGhpcyB3aGVuIFBIUCA1LjMgaXMgZHJvcHBlZAogICAgICAgICAgICAkc2VsZi0+bWFya0pvYkRvbmUoKTsKCiAgICAgICAgICAgIHJldHVybiAkam9iWydwcm9jZXNzJ107CiAgICAgICAgfSwgZnVuY3Rpb24gKCRlKSB1c2UgKCYkam9iLCAkc2VsZikgewogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IFByb2Nlc3NFeGVjdXRvcjo6U1RBVFVTX0ZBSUxFRDsKCiAgICAgICAgICAgICRzZWxmLT5tYXJrSm9iRG9uZSgpOwoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfSk7CiAgICAgICAgJHRoaXMtPmpvYnNbJGpvYlsnaWQnXV0gPSAmJGpvYjsKCiAgICAgICAgaWYgKCR0aGlzLT5ydW5uaW5nSm9icyA8ICR0aGlzLT5tYXhKb2JzKSB7CiAgICAgICAgICAgICR0aGlzLT5zdGFydEpvYigkam9iWydpZCddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0Sm9iKCRpZCkKICAgIHsKICAgICAgICAkam9iID0gJiR0aGlzLT5qb2JzWyRpZF07CiAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddICE9PSBzZWxmOjpTVEFUVVNfUVVFVUVEKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIHN0YXJ0IGpvYgogICAgICAgICRqb2JbJ3N0YXR1cyddID0gc2VsZjo6U1RBVFVTX1NUQVJURUQ7CiAgICAgICAgJHRoaXMtPnJ1bm5pbmdKb2JzKys7CgogICAgICAgICRjb21tYW5kID0gJGpvYlsnY29tbWFuZCddOwogICAgICAgICRjd2QgPSAkam9iWydjd2QnXTsKCiAgICAgICAgaWYgKCR0aGlzLT5pbyAmJiAkdGhpcy0+aW8tPmlzRGVidWcoKSkgewogICAgICAgICAgICAkc2FmZUNvbW1hbmQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJ3s6Ly8oP1A8dXNlcj5bXjovXHNdKyk6KD9QPHBhc3N3b3JkPlteQFxzL10rKUB9aScsIGZ1bmN0aW9uICgkbSkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teW2EtZjAtOV17MTIsfSR9JywgJG1bJ3VzZXInXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzovLyoqKjoqKipAJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJzovLycuJG1bJ3VzZXInXS4nOioqKkAnOwogICAgICAgICAgICB9LCAkY29tbWFuZCk7CiAgICAgICAgICAgICRzYWZlQ29tbWFuZCA9IHByZWdfcmVwbGFjZSgiey0tcGFzc3dvcmQgKC4qW15cXFxcXVwnKSB9IiwgJy0tcGFzc3dvcmQgXCcqKipcJyAnLCAkc2FmZUNvbW1hbmQpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0V4ZWN1dGluZyBhc3luYyBjb21tYW5kICgnLigkY3dkID86ICdDV0QnKS4nKTogJy4kc2FmZUNvbW1hbmQpOwogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETyBpbiAyLjIsIHRoZXNlIHR3byBjaGVja3MgY2FuIGJlIGRyb3BwZWQgYXMgU3ltZm9ueSA0KyBzdXBwb3J0cyB0aGVtIG91dCBvZiB0aGUgYm94CiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgbnVsbCB0cmFuc2xhdGUgdG8gdGhlIHByb3BlciBkaXJlY3RvcnkgaW4gY2FzZSB0aGUgZGlyIGlzIGEgc3ltbGluawogICAgICAgIC8vIGFuZCB3ZSBjYWxsIGEgZ2l0IGNvbW1hbmQsIGJlY2F1c2UgbXN5c2dpdCBkb2VzIG5vdCBoYW5kbGUgc3ltbGlua3MgcHJvcGVybHkKICAgICAgICBpZiAobnVsbCA9PT0gJGN3ZCAmJiBQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgZmFsc2UgIT09IHN0cnBvcygkY29tbWFuZCwgJ2dpdCcpICYmIGdldGN3ZCgpKSB7CiAgICAgICAgICAgICRjd2QgPSByZWFscGF0aChnZXRjd2QoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkY3dkICYmICFpc19kaXIoJGN3ZCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgZ2l2ZW4gQ1dEIGZvciB0aGUgcHJvY2VzcyBkb2VzIG5vdCBleGlzdDogJy4kY3dkKTsKICAgICAgICB9CgogICAgICAgIC8vIFRPRE8gaW4gdjMsIGNvbW1hbmRzIHNob3VsZCBiZSBwYXNzZWQgaW4gYXMgYXJyYXlzIG9mIGNtZCArIGFyZ3MKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzJywgJ2Zyb21TaGVsbENvbW1hbmRsaW5lJykpIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBQcm9jZXNzOjpmcm9tU2hlbGxDb21tYW5kbGluZSgkY29tbWFuZCwgJGN3ZCwgbnVsbCwgbnVsbCwgc3RhdGljOjpnZXRUaW1lb3V0KCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoJGNvbW1hbmQsICRjd2QsIG51bGwsIG51bGwsIHN0YXRpYzo6Z2V0VGltZW91dCgpKTsKICAgICAgICB9CgogICAgICAgICRqb2JbJ3Byb2Nlc3MnXSA9ICRwcm9jZXNzOwoKICAgICAgICAkcHJvY2Vzcy0+c3RhcnQoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FpdCgkaW5kZXggPSBudWxsKQogICAgewogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmNvdW50QWN0aXZlSm9icygkaW5kZXgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzbGVlcCgxMDAwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZUFzeW5jKCkKICAgIHsKICAgICAgICAkdGhpcy0+YWxsb3dBc3luYyA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBudW1iZXIgb2YgYWN0aXZlIChxdWV1ZWQgb3Igc3RhcnRlZCkgam9icwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnRBY3RpdmVKb2JzKCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gdGljawogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5qb2JzIGFzICRqb2IpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfU1RBUlRFRCkgewogICAgICAgICAgICAgICAgaWYgKCEkam9iWydwcm9jZXNzJ10tPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJGpvYlsncmVzb2x2ZSddLCAkam9iWydwcm9jZXNzJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnJ1bm5pbmdKb2JzIDwgJHRoaXMtPm1heEpvYnMpIHsKICAgICAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSA9PT0gc2VsZjo6U1RBVFVTX1FVRVVFRCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFydEpvYigkam9iWydpZCddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICRpbmRleCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmpvYnNbJGluZGV4XVsnc3RhdHVzJ10gPCBzZWxmOjpTVEFUVVNfQ09NUExFVEVEID8gMSA6IDA7CiAgICAgICAgfQoKICAgICAgICAkYWN0aXZlID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+am9icyBhcyAkam9iKSB7CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSA8IHNlbGY6OlNUQVRVU19DT01QTEVURUQpIHsKICAgICAgICAgICAgICAgICRhY3RpdmUrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5qb2JzWyRqb2JbJ2lkJ11dKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhY3RpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcHJpdmF0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFya0pvYkRvbmUoKQogICAgewogICAgICAgICR0aGlzLT5ydW5uaW5nSm9icy0tOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3BsaXRMaW5lcygkb3V0cHV0KQogICAgewogICAgICAgICRvdXRwdXQgPSB0cmltKCRvdXRwdXQpOwoKICAgICAgICByZXR1cm4gKChzdHJpbmcpICRvdXRwdXQgPT09ICcnKSA/IGFycmF5KCkgOiBwcmVnX3NwbGl0KCd7XHI/XG59JywgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYW55IGVycm9yIG91dHB1dCBmcm9tIHRoZSBsYXN0IGNvbW1hbmQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3JPdXRwdXQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG91dHB1dEhhbmRsZXIoJHR5cGUsICRidWZmZXIpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jYXB0dXJlT3V0cHV0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+aW8pIHsKICAgICAgICAgICAgZWNobyAkYnVmZmVyOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKFByb2Nlc3M6OkVSUiA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yUmF3KCRidWZmZXIsIGZhbHNlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlUmF3KCRidWZmZXIsIGZhbHNlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRUaW1lb3V0KCkKICAgIHsKICAgICAgICByZXR1cm4gc3RhdGljOjokdGltZW91dDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldFRpbWVvdXQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgc3RhdGljOjokdGltZW91dCA9ICR0aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgc2hlbGwgYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXJndW1lbnQgVGhlIGFyZ3VtZW50IHRoYXQgd2lsbCBiZSBlc2NhcGVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGVzY2FwZWQgYXJndW1lbnQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGUoJGFyZ3VtZW50KQogICAgewogICAgICAgIHJldHVybiBzZWxmOjplc2NhcGVBcmd1bWVudCgkYXJndW1lbnQpOwogICAgfQoKICAgIC8qKgogICAgICogQ29weSBvZiBQcm9jZXNzVXRpbHM6OmVzY2FwZUFyZ3VtZW50KCkgdGhhdCBpcyBkZXByZWNhdGVkIGluIFN5bWZvbnkgMy4zIGFuZCByZW1vdmVkIGluIFN5bWZvbnkgNC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGVzY2FwZUFyZ3VtZW50KCRhcmd1bWVudCkKICAgIHsKICAgICAgICAvL0ZpeCBmb3IgUEhQIGJ1ZyAjNDM3ODQgZXNjYXBlc2hlbGxhcmcgcmVtb3ZlcyAlIGZyb20gZ2l2ZW4gc3RyaW5nCiAgICAgICAgLy9GaXggZm9yIFBIUCBidWcgIzQ5NDQ2IGVzY2FwZXNoZWxsYXJnIGRvZXNuJ3Qgd29yayBvbiBXaW5kb3dzCiAgICAgICAgLy9Ac2VlIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NDM3ODQKICAgICAgICAvL0BzZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD00OTQ0NgogICAgICAgIGlmICgnXFwnID09PSBESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgIGlmICgoc3RyaW5nKSAkYXJndW1lbnQgPT09ICcnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZXNjYXBlc2hlbGxhcmcoJGFyZ3VtZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCA9ICcnOwogICAgICAgICAgICAkcXVvdGUgPSBmYWxzZTsKICAgICAgICAgICAgZm9yZWFjaCAocHJlZ19zcGxpdCgnLygiKS8nLCAkYXJndW1lbnQsIC0xLCBQUkVHX1NQTElUX05PX0VNUFRZIHwgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFKSBhcyAkcGFydCkgewogICAgICAgICAgICAgICAgaWYgKCciJyA9PT0gJHBhcnQpIHsKICAgICAgICAgICAgICAgICAgICAkZXNjYXBlZEFyZ3VtZW50IC49ICdcXCInOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKHNlbGY6OmlzU3Vycm91bmRlZEJ5KCRwYXJ0LCAnJScpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZW52aXJvbm1lbnQgdmFyaWFibGUgZXhwYW5zaW9uCiAgICAgICAgICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCAuPSAnXiUiJy5zdWJzdHIoJHBhcnQsIDEsIC0xKS4nIl4lJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZXNjYXBlIHRyYWlsaW5nIGJhY2tzbGFzaAogICAgICAgICAgICAgICAgICAgIGlmICgnXFwnID09PSBzdWJzdHIoJHBhcnQsIC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFydCAuPSAnXFwnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkcXVvdGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRlc2NhcGVkQXJndW1lbnQgLj0gJHBhcnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRxdW90ZSkgewogICAgICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCA9ICciJy4kZXNjYXBlZEFyZ3VtZW50LiciJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRlc2NhcGVkQXJndW1lbnQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIiciLnN0cl9yZXBsYWNlKCInIiwgIidcXCcnIiwgJGFyZ3VtZW50KS4iJyI7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaXNTdXJyb3VuZGVkQnkoJGFyZywgJGNoYXIpCiAgICB7CiAgICAgICAgcmV0dXJuIDIgPCBzdHJsZW4oJGFyZykgJiYgJGNoYXIgPT09ICRhcmdbMF0gJiYgJGNoYXIgPT09ICRhcmdbc3RybGVuKCRhcmcpIC0gMV07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbFxIdHRwOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxVdGlsXFN0cmVhbUNvbnRleHRGYWN0b3J5Owp1c2UgQ29tcG9zZXJcVXRpbFxBdXRoSGVscGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgUmVhY3RcUHJvbWlzZVxQcm9taXNlOwoKLyoqCiAqIEBpbnRlcm5hbAogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgTmljb2xhcyBHcmVrYXMgPHBAdGNod29yay5jb20+CiAqLwpjbGFzcyBDdXJsRG93bmxvYWRlcgp7CiAgICBwcml2YXRlICRtdWx0aUhhbmRsZTsKICAgIHByaXZhdGUgJHNoYXJlSGFuZGxlOwogICAgcHJpdmF0ZSAkam9icyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJpdmF0ZSAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByaXZhdGUgJGNvbmZpZzsKICAgIC8qKiBAdmFyIEF1dGhIZWxwZXIgKi8KICAgIHByaXZhdGUgJGF1dGhIZWxwZXI7CiAgICBwcml2YXRlICRzZWxlY3RUaW1lb3V0ID0gNS4wOwogICAgcHJpdmF0ZSAkbWF4UmVkaXJlY3RzID0gMjA7CiAgICAvKiogQHZhciBQcm94eU1hbmFnZXIgKi8KICAgIHByaXZhdGUgJHByb3h5TWFuYWdlcjsKICAgIHByaXZhdGUgJHN1cHBvcnRzU2VjdXJlUHJveHk7CiAgICBwcm90ZWN0ZWQgJG11bHRpRXJyb3JzID0gYXJyYXkoCiAgICAgICAgQ1VSTE1fQkFEX0hBTkRMRSA9PiBhcnJheSgnQ1VSTE1fQkFEX0hBTkRMRScsICdUaGUgcGFzc2VkLWluIGhhbmRsZSBpcyBub3QgYSB2YWxpZCBDVVJMTSBoYW5kbGUuJyksCiAgICAgICAgQ1VSTE1fQkFEX0VBU1lfSEFORExFID0+IGFycmF5KCdDVVJMTV9CQURfRUFTWV9IQU5ETEUnLCAiQW4gZWFzeSBoYW5kbGUgd2FzIG5vdCBnb29kL3ZhbGlkLiBJdCBjb3VsZCBtZWFuIHRoYXQgaXQgaXNuJ3QgYW4gZWFzeSBoYW5kbGUgYXQgYWxsLCBvciBwb3NzaWJseSB0aGF0IHRoZSBoYW5kbGUgYWxyZWFkeSBpcyBpbiB1c2VkIGJ5IHRoaXMgb3IgYW5vdGhlciBtdWx0aSBoYW5kbGUuIiksCiAgICAgICAgQ1VSTE1fT1VUX09GX01FTU9SWSA9PiBhcnJheSgnQ1VSTE1fT1VUX09GX01FTU9SWScsICdZb3UgYXJlIGRvb21lZC4nKSwKICAgICAgICBDVVJMTV9JTlRFUk5BTF9FUlJPUiA9PiBhcnJheSgnQ1VSTE1fSU5URVJOQUxfRVJST1InLCAnVGhpcyBjYW4gb25seSBiZSByZXR1cm5lZCBpZiBsaWJjdXJsIGJ1Z3MuIFBsZWFzZSByZXBvcnQgaXQgdG8gdXMhJyksCiAgICApOwoKICAgIHByaXZhdGUgc3RhdGljICRvcHRpb25zID0gYXJyYXkoCiAgICAgICAgJ2h0dHAnID0+IGFycmF5KAogICAgICAgICAgICAnbWV0aG9kJyA9PiBDVVJMT1BUX0NVU1RPTVJFUVVFU1QsCiAgICAgICAgICAgICdjb250ZW50JyA9PiBDVVJMT1BUX1BPU1RGSUVMRFMsCiAgICAgICAgICAgICdoZWFkZXInID0+IENVUkxPUFRfSFRUUEhFQURFUiwKICAgICAgICAgICAgJ3RpbWVvdXQnID0+IENVUkxPUFRfVElNRU9VVCwKICAgICAgICApLAogICAgICAgICdzc2wnID0+IGFycmF5KAogICAgICAgICAgICAnY2FmaWxlJyA9PiBDVVJMT1BUX0NBSU5GTywKICAgICAgICAgICAgJ2NhcGF0aCcgPT4gQ1VSTE9QVF9DQVBBVEgsCiAgICAgICAgICAgICd2ZXJpZnlfcGVlcicgPT4gQ1VSTE9QVF9TU0xfVkVSSUZZUEVFUiwKICAgICAgICAgICAgJ3ZlcmlmeV9wZWVyX25hbWUnID0+IENVUkxPUFRfU1NMX1ZFUklGWUhPU1QsCiAgICAgICAgICAgICdsb2NhbF9jZXJ0JyA9PiBDVVJMT1BUX1NTTENFUlQsCiAgICAgICAgICAgICdsb2NhbF9waycgPT4gQ1VSTE9QVF9TU0xLRVksCiAgICAgICAgICAgICdwYXNzcGhyYXNlJyA9PiBDVVJMT1BUX1NTTEtFWVBBU1NXRCwKICAgICAgICApLAogICAgKTsKCiAgICBwcml2YXRlIHN0YXRpYyAkdGltZUluZm8gPSBhcnJheSgKICAgICAgICAndG90YWxfdGltZScgPT4gdHJ1ZSwKICAgICAgICAnbmFtZWxvb2t1cF90aW1lJyA9PiB0cnVlLAogICAgICAgICdjb25uZWN0X3RpbWUnID0+IHRydWUsCiAgICAgICAgJ3ByZXRyYW5zZmVyX3RpbWUnID0+IHRydWUsCiAgICAgICAgJ3N0YXJ0dHJhbnNmZXJfdGltZScgPT4gdHJ1ZSwKICAgICAgICAncmVkaXJlY3RfdGltZScgPT4gdHJ1ZSwKICAgICk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSwgJGRpc2FibGVUbHMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CgogICAgICAgICR0aGlzLT5tdWx0aUhhbmRsZSA9ICRtaCA9IGN1cmxfbXVsdGlfaW5pdCgpOwogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2N1cmxfbXVsdGlfc2V0b3B0JykpIHsKICAgICAgICAgICAgY3VybF9tdWx0aV9zZXRvcHQoJG1oLCBDVVJMTU9QVF9QSVBFTElOSU5HLCBQSFBfVkVSU0lPTl9JRCA+PSA3MDQwMCA/IC8qIENVUkxQSVBFX01VTFRJUExFWCAqLyAyIDogLypDVVJMUElQRV9IVFRQMSB8IENVUkxQSVBFX01VTFRJUExFWCovIDMpOwogICAgICAgICAgICBpZiAoZGVmaW5lZCgnQ1VSTE1PUFRfTUFYX0hPU1RfQ09OTkVDVElPTlMnKSAmJiAhZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgICAgIGN1cmxfbXVsdGlfc2V0b3B0KCRtaCwgQ1VSTE1PUFRfTUFYX0hPU1RfQ09OTkVDVElPTlMsIDgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3NoYXJlX2luaXQnKSkgewogICAgICAgICAgICAkdGhpcy0+c2hhcmVIYW5kbGUgPSAkc2ggPSBjdXJsX3NoYXJlX2luaXQoKTsKICAgICAgICAgICAgY3VybF9zaGFyZV9zZXRvcHQoJHNoLCBDVVJMU0hPUFRfU0hBUkUsIENVUkxfTE9DS19EQVRBX0NPT0tJRSk7CiAgICAgICAgICAgIGN1cmxfc2hhcmVfc2V0b3B0KCRzaCwgQ1VSTFNIT1BUX1NIQVJFLCBDVVJMX0xPQ0tfREFUQV9ETlMpOwogICAgICAgICAgICBjdXJsX3NoYXJlX3NldG9wdCgkc2gsIENVUkxTSE9QVF9TSEFSRSwgQ1VSTF9MT0NLX0RBVEFfU1NMX1NFU1NJT04pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmF1dGhIZWxwZXIgPSBuZXcgQXV0aEhlbHBlcigkaW8sICRjb25maWcpOwogICAgICAgICR0aGlzLT5wcm94eU1hbmFnZXIgPSBQcm94eU1hbmFnZXI6OmdldEluc3RhbmNlKCk7CgogICAgICAgICR2ZXJzaW9uID0gY3VybF92ZXJzaW9uKCk7CiAgICAgICAgJGZlYXR1cmVzID0gJHZlcnNpb25bJ2ZlYXR1cmVzJ107CiAgICAgICAgJHRoaXMtPnN1cHBvcnRzU2VjdXJlUHJveHkgPSBkZWZpbmVkKCdDVVJMX1ZFUlNJT05fSFRUUFNfUFJPWFknKSAmJiAoJGZlYXR1cmVzICYgQ1VSTF9WRVJTSU9OX0hUVFBTX1BST1hZKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gaW50IGludGVybmFsIGpvYiBpZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoJHJlc29sdmUsICRyZWplY3QsICRvcmlnaW4sICR1cmwsICRvcHRpb25zLCAkY29weVRvID0gbnVsbCkKICAgIHsKICAgICAgICAkYXR0cmlidXRlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydyZXRyeS1hdXRoLWZhaWx1cmUnXSkpIHsKICAgICAgICAgICAgJGF0dHJpYnV0ZXNbJ3JldHJ5QXV0aEZhaWx1cmUnXSA9ICRvcHRpb25zWydyZXRyeS1hdXRoLWZhaWx1cmUnXTsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ3JldHJ5LWF1dGgtZmFpbHVyZSddKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5pdERvd25sb2FkKCRyZXNvbHZlLCAkcmVqZWN0LCAkb3JpZ2luLCAkdXJsLCAkb3B0aW9ucywgJGNvcHlUbywgJGF0dHJpYnV0ZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQgaW50ZXJuYWwgam9iIGlkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaW5pdERvd25sb2FkKCRyZXNvbHZlLCAkcmVqZWN0LCAkb3JpZ2luLCAkdXJsLCAkb3B0aW9ucywgJGNvcHlUbyA9IG51bGwsIGFycmF5ICRhdHRyaWJ1dGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkYXR0cmlidXRlcyA9IGFycmF5X21lcmdlKGFycmF5KAogICAgICAgICAgICAncmV0cnlBdXRoRmFpbHVyZScgPT4gdHJ1ZSwKICAgICAgICAgICAgJ3JlZGlyZWN0cycgPT4gMCwKICAgICAgICAgICAgJ3N0b3JlQXV0aCcgPT4gZmFsc2UsCiAgICAgICAgKSwgJGF0dHJpYnV0ZXMpOwoKICAgICAgICAkb3JpZ2luYWxPcHRpb25zID0gJG9wdGlvbnM7CgogICAgICAgIC8vIGNoZWNrIFVSTCBjYW4gYmUgYWNjZXNzZWQgKGkuZS4gaXMgbm90IGluc2VjdXJlKSwgYnV0IGFsbG93IGluc2VjdXJlIFBhY2thZ2lzdCBjYWxscyB0byAkaGFzaGVkIHByb3ZpZGVycyBhcyBmaWxlIGludGVncml0eSBpcyB2ZXJpZmllZCB3aXRoIHNoYTI1NgogICAgICAgIGlmICghcHJlZ19tYXRjaCgne15odHRwOi8vKHJlcG9cLik/cGFja2FnaXN0XC5vcmcvcC99JywgJHVybCkgfHwgKGZhbHNlID09PSBzdHJwb3MoJHVybCwgJyQnKSAmJiBmYWxzZSA9PT0gc3RycG9zKCR1cmwsICclMjQnKSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdXJsLCAkdGhpcy0+aW8pOwogICAgICAgIH0KCiAgICAgICAgJGN1cmxIYW5kbGUgPSBjdXJsX2luaXQoKTsKICAgICAgICAkaGVhZGVySGFuZGxlID0gZm9wZW4oJ3BocDovL3RlbXAvbWF4bWVtb3J5OjMyNzY4JywgJ3crYicpOwoKICAgICAgICBpZiAoJGNvcHlUbykgewogICAgICAgICAgICAkZXJyb3JNZXNzYWdlID0gJyc7CiAgICAgICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGZ1bmN0aW9uICgkY29kZSwgJG1zZykgdXNlICgmJGVycm9yTWVzc2FnZSkgewogICAgICAgICAgICAgICAgaWYgKCRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkZXJyb3JNZXNzYWdlIC49ICJcbiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZXJyb3JNZXNzYWdlIC49IHByZWdfcmVwbGFjZSgne15mb3BlblwoLio/XCk6IH0nLCAnJywgJG1zZyk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkYm9keUhhbmRsZSA9IGZvcGVuKCRjb3B5VG8uJ34nLCAndytiJyk7CiAgICAgICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwogICAgICAgICAgICBpZiAoISRib2R5SGFuZGxlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgIicuJHVybC4nIiBmaWxlIGNvdWxkIG5vdCBiZSB3cml0dGVuIHRvICcuJGNvcHlUby4nOiAnLiRlcnJvck1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGJvZHlIYW5kbGUgPSBAZm9wZW4oJ3BocDovL3RlbXAvbWF4bWVtb3J5OjUyNDI4OCcsICd3K2InKTsKICAgICAgICB9CgogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1VSTCwgJHVybCk7CiAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfRk9MTE9XTE9DQVRJT04sIGZhbHNlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVCwgMTApOwogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX1RJTUVPVVQsIDMwMCk7CiAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfV1JJVEVIRUFERVIsICRoZWFkZXJIYW5kbGUpOwogICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX0ZJTEUsICRib2R5SGFuZGxlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9FTkNPRElORywgImd6aXAiKTsKICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9QUk9UT0NPTFMsIENVUkxQUk9UT19IVFRQIHwgQ1VSTFBST1RPX0hUVFBTKTsKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3NoYXJlX2luaXQnKSkgewogICAgICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9TSEFSRSwgJHRoaXMtPnNoYXJlSGFuZGxlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gYXJyYXlfZGlmZigkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSwgYXJyYXkoJ0Nvbm5lY3Rpb246IGNsb3NlJykpOwogICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddW10gPSAnQ29ubmVjdGlvbjoga2VlcC1hbGl2ZSc7CgogICAgICAgICR2ZXJzaW9uID0gY3VybF92ZXJzaW9uKCk7CiAgICAgICAgJGZlYXR1cmVzID0gJHZlcnNpb25bJ2ZlYXR1cmVzJ107CiAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkdXJsLCAnaHR0cHM6Ly8nKSAmJiBcZGVmaW5lZCgnQ1VSTF9WRVJTSU9OX0hUVFAyJykgJiYgXGRlZmluZWQoJ0NVUkxfSFRUUF9WRVJTSU9OXzJfMCcpICYmIChDVVJMX1ZFUlNJT05fSFRUUDIgJiAkZmVhdHVyZXMpKSB7CiAgICAgICAgICAgIGN1cmxfc2V0b3B0KCRjdXJsSGFuZGxlLCBDVVJMT1BUX0hUVFBfVkVSU0lPTiwgQ1VSTF9IVFRQX1ZFUlNJT05fMl8wKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gJHRoaXMtPmF1dGhIZWxwZXItPmFkZEF1dGhlbnRpY2F0aW9uSGVhZGVyKCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddLCAkb3JpZ2luLCAkdXJsKTsKICAgICAgICAkb3B0aW9ucyA9IFN0cmVhbUNvbnRleHRGYWN0b3J5Ojppbml0T3B0aW9ucygkdXJsLCAkb3B0aW9ucywgdHJ1ZSk7CgogICAgICAgIGZvcmVhY2ggKHNlbGY6OiRvcHRpb25zIGFzICR0eXBlID0+ICRjdXJsT3B0aW9ucykgewogICAgICAgICAgICBmb3JlYWNoICgkY3VybE9wdGlvbnMgYXMgJG5hbWUgPT4gJGN1cmxPcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1skdHlwZV1bJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gJ3NzbCcgJiYgJG5hbWUgPT09ICd2ZXJpZnlfcGVlcl9uYW1lJykgewogICAgICAgICAgICAgICAgICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgJGN1cmxPcHRpb24sICRvcHRpb25zWyR0eXBlXVskbmFtZV0gPT09IHRydWUgPyAyIDogJG9wdGlvbnNbJHR5cGVdWyRuYW1lXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsICRjdXJsT3B0aW9uLCAkb3B0aW9uc1skdHlwZV1bJG5hbWVdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEFsd2F5cyBzZXQgQ1VSTE9QVF9QUk9YWSB0byBlbmFibGUvZGlzYWJsZSBwcm94eSBoYW5kbGluZwogICAgICAgIC8vIEFueSBwcm94eSBhdXRob3JpemF0aW9uIGlzIGluY2x1ZGVkIGluIHRoZSBwcm94eSB1cmwKICAgICAgICAkcHJveHkgPSAkdGhpcy0+cHJveHlNYW5hZ2VyLT5nZXRQcm94eUZvclJlcXVlc3QoJHVybCk7CiAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfUFJPWFksICRwcm94eS0+Z2V0VXJsKCkpOwoKICAgICAgICAvLyBDdXJsIG5lZWRzIGNlcnRpZmljYXRlIGxvY2F0aW9ucyBmb3Igc2VjdXJlIHByb3hpZXMuCiAgICAgICAgLy8gQ1VSTE9QVF9QUk9YWV9TU0xfVkVSSUZZX1BFRVIvSE9TVCBhcmUgZW5hYmxlZCBieSBkZWZhdWx0CiAgICAgICAgaWYgKCRwcm94eS0+aXNTZWN1cmUoKSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5zdXBwb3J0c1NlY3VyZVByb3h5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb25uZWN0aW5nIHRvIGEgc2VjdXJlIHByb3h5IHVzaW5nIGN1cmwgaXMgbm90IHN1cHBvcnRlZCBvbiBQSFAgdmVyc2lvbnMgYmVsb3cgNy4zLjAuJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlbXB0eSgkb3B0aW9uc1snc3NsJ11bJ2NhZmlsZSddKSkgewogICAgICAgICAgICAgICAgY3VybF9zZXRvcHQoJGN1cmxIYW5kbGUsIENVUkxPUFRfUFJPWFlfQ0FJTkZPLCAkb3B0aW9uc1snc3NsJ11bJ2NhZmlsZSddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWVtcHR5KCRvcHRpb25zWydzc2wnXVsnY2FwYXRoJ10pKSB7CiAgICAgICAgICAgICAgICBjdXJsX3NldG9wdCgkY3VybEhhbmRsZSwgQ1VSTE9QVF9QUk9YWV9DQVBBVEgsICRvcHRpb25zWydzc2wnXVsnY2FwYXRoJ10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcHJvZ3Jlc3MgPSBhcnJheV9kaWZmX2tleShjdXJsX2dldGluZm8oJGN1cmxIYW5kbGUpLCBzZWxmOjokdGltZUluZm8pOwoKICAgICAgICAkdGhpcy0+am9ic1soaW50KSAkY3VybEhhbmRsZV0gPSBhcnJheSgKICAgICAgICAgICAgJ3VybCcgPT4gJHVybCwKICAgICAgICAgICAgJ29yaWdpbicgPT4gJG9yaWdpbiwKICAgICAgICAgICAgJ2F0dHJpYnV0ZXMnID0+ICRhdHRyaWJ1dGVzLAogICAgICAgICAgICAnb3B0aW9ucycgPT4gJG9yaWdpbmFsT3B0aW9ucywKICAgICAgICAgICAgJ3Byb2dyZXNzJyA9PiAkcHJvZ3Jlc3MsCiAgICAgICAgICAgICdjdXJsSGFuZGxlJyA9PiAkY3VybEhhbmRsZSwKICAgICAgICAgICAgJ2ZpbGVuYW1lJyA9PiAkY29weVRvLAogICAgICAgICAgICAnaGVhZGVySGFuZGxlJyA9PiAkaGVhZGVySGFuZGxlLAogICAgICAgICAgICAnYm9keUhhbmRsZScgPT4gJGJvZHlIYW5kbGUsCiAgICAgICAgICAgICdyZXNvbHZlJyA9PiAkcmVzb2x2ZSwKICAgICAgICAgICAgJ3JlamVjdCcgPT4gJHJlamVjdCwKICAgICAgICApOwoKICAgICAgICAkdXNpbmdQcm94eSA9ICRwcm94eS0+Z2V0Rm9ybWF0dGVkVXJsKCcgdXNpbmcgcHJveHkgKCVzKScpOwogICAgICAgICRpZk1vZGlmaWVkID0gZmFsc2UgIT09IHN0cmlwb3MoaW1wbG9kZSgnLCcsICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSwgJ2lmLW1vZGlmaWVkLXNpbmNlOicpID8gJyBpZiBtb2RpZmllZCcgOiAnJzsKICAgICAgICBpZiAoJGF0dHJpYnV0ZXNbJ3JlZGlyZWN0cyddID09PSAwKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRG93bmxvYWRpbmcgJyAuIFVybDo6c2FuaXRpemUoJHVybCkgLiAkdXNpbmdQcm94eSAuICRpZk1vZGlmaWVkLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNoZWNrQ3VybFJlc3VsdChjdXJsX211bHRpX2FkZF9oYW5kbGUoJHRoaXMtPm11bHRpSGFuZGxlLCAkY3VybEhhbmRsZSkpOwogICAgICAgIC8vIFRPRE8gcHJvZ3Jlc3MKCiAgICAgICAgcmV0dXJuIChpbnQpICRjdXJsSGFuZGxlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhYm9ydFJlcXVlc3QoJGlkKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+am9ic1skaWRdLCAkdGhpcy0+am9ic1skaWRdWydoYW5kbGUnXSkpIHsKICAgICAgICAgICAgJGpvYiA9ICR0aGlzLT5qb2JzWyRpZF07CiAgICAgICAgICAgIGN1cmxfbXVsdGlfcmVtb3ZlX2hhbmRsZSgkdGhpcy0+bXVsdGlIYW5kbGUsICRqb2JbJ2hhbmRsZSddKTsKICAgICAgICAgICAgY3VybF9jbG9zZSgkam9iWydoYW5kbGUnXSk7CiAgICAgICAgICAgIGlmIChpc19yZXNvdXJjZSgkam9iWydoZWFkZXJIYW5kbGUnXSkpIHsKICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydoZWFkZXJIYW5kbGUnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRqb2JbJ2JvZHlIYW5kbGUnXSkpIHsKICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydib2R5SGFuZGxlJ10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkam9iWydmaWxlbmFtZSddKSB7CiAgICAgICAgICAgICAgICBAdW5saW5rKCRqb2JbJ2ZpbGVuYW1lJ10uJ34nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdGhpcy0+am9ic1skaWRdKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRpY2soKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmpvYnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGFjdGl2ZSA9IHRydWU7CiAgICAgICAgJHRoaXMtPmNoZWNrQ3VybFJlc3VsdChjdXJsX211bHRpX2V4ZWMoJHRoaXMtPm11bHRpSGFuZGxlLCAkYWN0aXZlKSk7CiAgICAgICAgaWYgKC0xID09PSBjdXJsX211bHRpX3NlbGVjdCgkdGhpcy0+bXVsdGlIYW5kbGUsICR0aGlzLT5zZWxlY3RUaW1lb3V0KSkgewogICAgICAgICAgICAvLyBzbGVlcCBpbiBjYXNlIHNlbGVjdCByZXR1cm5zIC0xIGFzIGl0IGNhbiBoYXBwZW4gb24gb2xkIHBocCB2ZXJzaW9ucyBvciBzb21lIHBsYXRmb3JtcyB3aGVyZSBjdXJsIGRvZXMgbm90IG1hbmFnZSB0byBkbyB0aGUgc2VsZWN0CiAgICAgICAgICAgIHVzbGVlcCgxNTApOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKCRwcm9ncmVzcyA9IGN1cmxfbXVsdGlfaW5mb19yZWFkKCR0aGlzLT5tdWx0aUhhbmRsZSkpIHsKICAgICAgICAgICAgJGN1cmxIYW5kbGUgPSAkcHJvZ3Jlc3NbJ2hhbmRsZSddOwogICAgICAgICAgICAkcmVzdWx0ID0gJHByb2dyZXNzWydyZXN1bHQnXTsKICAgICAgICAgICAgJGkgPSAoaW50KSAkY3VybEhhbmRsZTsKICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+am9ic1skaV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb2dyZXNzID0gY3VybF9nZXRpbmZvKCRjdXJsSGFuZGxlKTsKICAgICAgICAgICAgJGpvYiA9ICR0aGlzLT5qb2JzWyRpXTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmpvYnNbJGldKTsKICAgICAgICAgICAgJGVycm9yID0gY3VybF9lcnJvcigkY3VybEhhbmRsZSk7CiAgICAgICAgICAgICRlcnJubyA9IGN1cmxfZXJybm8oJGN1cmxIYW5kbGUpOwogICAgICAgICAgICBjdXJsX211bHRpX3JlbW92ZV9oYW5kbGUoJHRoaXMtPm11bHRpSGFuZGxlLCAkY3VybEhhbmRsZSk7CiAgICAgICAgICAgIGN1cmxfY2xvc2UoJGN1cmxIYW5kbGUpOwoKICAgICAgICAgICAgJGhlYWRlcnMgPSBudWxsOwogICAgICAgICAgICAkc3RhdHVzQ29kZSA9IG51bGw7CiAgICAgICAgICAgICRyZXNwb25zZSA9IG51bGw7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBUT0RPIHByb2dyZXNzCiAgICAgICAgICAgICAgICBpZiAoQ1VSTEVfT0sgIT09ICRlcnJubyB8fCAkZXJyb3IgfHwgJHJlc3VsdCAhPT0gQ1VSTEVfT0spIHsKICAgICAgICAgICAgICAgICAgICAkZXJybm8gPSAkZXJybm8gPzogJHJlc3VsdDsKICAgICAgICAgICAgICAgICAgICBpZiAoISRlcnJvciAmJiBmdW5jdGlvbl9leGlzdHMoJ2N1cmxfc3RyZXJyb3InKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXJyb3IgPSBjdXJsX3N0cmVycm9yKCRlcnJubyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ2N1cmwgZXJyb3IgJy4kZXJybm8uJyB3aGlsZSBkb3dubG9hZGluZyAnLlVybDo6c2FuaXRpemUoJHByb2dyZXNzWyd1cmwnXSkuJzogJy4kZXJyb3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHN0YXR1c0NvZGUgPSAkcHJvZ3Jlc3NbJ2h0dHBfY29kZSddOwogICAgICAgICAgICAgICAgcmV3aW5kKCRqb2JbJ2hlYWRlckhhbmRsZSddKTsKICAgICAgICAgICAgICAgICRoZWFkZXJzID0gZXhwbG9kZSgiXHJcbiIsIHJ0cmltKHN0cmVhbV9nZXRfY29udGVudHMoJGpvYlsnaGVhZGVySGFuZGxlJ10pKSk7CiAgICAgICAgICAgICAgICBmY2xvc2UoJGpvYlsnaGVhZGVySGFuZGxlJ10pOwoKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ1JlY2VpdmVkIHVuZXhwZWN0ZWQgaHR0cCBzdGF0dXMgY29kZSAwIHdpdGhvdXQgZXJyb3IgZm9yICcuVXJsOjpzYW5pdGl6ZSgkcHJvZ3Jlc3NbJ3VybCddKS4nOiBoZWFkZXJzICcudmFyX2V4cG9ydCgkaGVhZGVycywgdHJ1ZSkuJyBjdXJsIGluZm8gJy52YXJfZXhwb3J0KCRwcm9ncmVzcywgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHByZXBhcmUgcmVzcG9uc2Ugb2JqZWN0CiAgICAgICAgICAgICAgICBpZiAoJGpvYlsnZmlsZW5hbWUnXSkgewogICAgICAgICAgICAgICAgICAgICRjb250ZW50cyA9ICRqb2JbJ2ZpbGVuYW1lJ10uJ34nOwogICAgICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSAzMDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV3aW5kKCRqb2JbJ2JvZHlIYW5kbGUnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50cyA9IHN0cmVhbV9nZXRfY29udGVudHMoJGpvYlsnYm9keUhhbmRsZSddKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gbmV3IEN1cmxSZXNwb25zZShhcnJheSgndXJsJyA9PiAkcHJvZ3Jlc3NbJ3VybCddKSwgJHN0YXR1c0NvZGUsICRoZWFkZXJzLCAkY29udGVudHMsICRwcm9ncmVzcyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdbJy4kc3RhdHVzQ29kZS4nXSAnLlVybDo6c2FuaXRpemUoJHByb2dyZXNzWyd1cmwnXSksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJld2luZCgkam9iWydib2R5SGFuZGxlJ10pOwogICAgICAgICAgICAgICAgICAgICRjb250ZW50cyA9IHN0cmVhbV9nZXRfY29udGVudHMoJGpvYlsnYm9keUhhbmRsZSddKTsKICAgICAgICAgICAgICAgICAgICAkcmVzcG9uc2UgPSBuZXcgQ3VybFJlc3BvbnNlKGFycmF5KCd1cmwnID0+ICRwcm9ncmVzc1sndXJsJ10pLCAkc3RhdHVzQ29kZSwgJGhlYWRlcnMsICRjb250ZW50cywgJHByb2dyZXNzKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1snLiRzdGF0dXNDb2RlLiddICcuVXJsOjpzYW5pdGl6ZSgkcHJvZ3Jlc3NbJ3VybCddKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZjbG9zZSgkam9iWydib2R5SGFuZGxlJ10pOwoKICAgICAgICAgICAgICAgIGlmICgkcmVzcG9uc2UtPmdldFN0YXR1c0NvZGUoKSA+PSA0MDAgJiYgJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpID09PSAnYXBwbGljYXRpb24vanNvbicpIHsKICAgICAgICAgICAgICAgICAgICBIdHRwRG93bmxvYWRlcjo6b3V0cHV0V2FybmluZ3MoJHRoaXMtPmlvLCAkam9iWydvcmlnaW4nXSwganNvbl9kZWNvZGUoJHJlc3BvbnNlLT5nZXRCb2R5KCksIHRydWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmlzQXV0aGVudGljYXRlZFJldHJ5TmVlZGVkKCRqb2IsICRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICBpZiAoJHJlc3VsdFsncmV0cnknXSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXN0YXJ0Sm9iKCRqb2IsICRqb2JbJ3VybCddLCBhcnJheSgnc3RvcmVBdXRoJyA9PiAkcmVzdWx0WydzdG9yZUF1dGgnXSkpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGhhbmRsZSAzeHggcmVkaXJlY3RzLCAzMDQgTm90IE1vZGlmaWVkIGlzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICBpZiAoJHN0YXR1c0NvZGUgPj0gMzAwICYmICRzdGF0dXNDb2RlIDw9IDM5OSAmJiAkc3RhdHVzQ29kZSAhPT0gMzA0ICYmICRqb2JbJ2F0dHJpYnV0ZXMnXVsncmVkaXJlY3RzJ10gPCAkdGhpcy0+bWF4UmVkaXJlY3RzKSB7CiAgICAgICAgICAgICAgICAgICAgJGxvY2F0aW9uID0gJHRoaXMtPmhhbmRsZVJlZGlyZWN0KCRqb2IsICRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsb2NhdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVzdGFydEpvYigkam9iLCAkbG9jYXRpb24sIGFycmF5KCdyZWRpcmVjdHMnID0+ICRqb2JbJ2F0dHJpYnV0ZXMnXVsncmVkaXJlY3RzJ10gKyAxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBmYWlsIDR4eCBhbmQgNXh4IHJlc3BvbnNlcyBhbmQgY2FwdHVyZSB0aGUgcmVzcG9uc2UKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSA0MDAgJiYgJHN0YXR1c0NvZGUgPD0gNTk5KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJHRoaXMtPmZhaWxSZXNwb25zZSgkam9iLCAkcmVzcG9uc2UsICRyZXNwb25zZS0+Z2V0U3RhdHVzTWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGpvYlsnYXR0cmlidXRlcyddWydzdG9yZUF1dGgnXSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hdXRoSGVscGVyLT5zdG9yZUF1dGgoJGpvYlsnb3JpZ2luJ10sICRqb2JbJ2F0dHJpYnV0ZXMnXVsnc3RvcmVBdXRoJ10pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHJlc29sdmUgcHJvbWlzZQogICAgICAgICAgICAgICAgaWYgKCRqb2JbJ2ZpbGVuYW1lJ10pIHsKICAgICAgICAgICAgICAgICAgICByZW5hbWUoJGpvYlsnZmlsZW5hbWUnXS4nficsICRqb2JbJ2ZpbGVuYW1lJ10pOwogICAgICAgICAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3Jlc29sdmUnXSwgJHJlc3BvbnNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJGpvYlsncmVzb2x2ZSddLCAkcmVzcG9uc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJGhlYWRlcnMpIHsKICAgICAgICAgICAgICAgICAgICAkZS0+c2V0SGVhZGVycygkaGVhZGVycyk7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFN0YXR1c0NvZGUoJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRyZXNwb25zZSkgewogICAgICAgICAgICAgICAgICAgICRlLT5zZXRSZXNwb25zZSgkcmVzcG9uc2UtPmdldEJvZHkoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24gJiYgJHByb2dyZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlSW5mbygkcHJvZ3Jlc3MpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJGpvYiwgJGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+am9icyBhcyAkaSA9PiAkY3VybEhhbmRsZSkgewogICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5qb2JzWyRpXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjdXJsSGFuZGxlID0gJHRoaXMtPmpvYnNbJGldWydjdXJsSGFuZGxlJ107CiAgICAgICAgICAgICRwcm9ncmVzcyA9IGFycmF5X2RpZmZfa2V5KGN1cmxfZ2V0aW5mbygkY3VybEhhbmRsZSksIHNlbGY6OiR0aW1lSW5mbyk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPmpvYnNbJGldWydwcm9ncmVzcyddICE9PSAkcHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5qb2JzWyRpXVsncHJvZ3Jlc3MnXSA9ICRwcm9ncmVzczsKCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmpvYnNbJGldWydvcHRpb25zJ11bJ21heF9maWxlX3NpemUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb21wYXJlIG1heF9maWxlX3NpemUgd2l0aCB0aGUgY29udGVudC1sZW5ndGggaGVhZGVyIHRoaXMgdmFsdWUgd2lsbCBiZSAtMSB1bnRpbCB0aGUgaGVhZGVyIGlzIHBhcnNlZAogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+am9ic1skaV1bJ29wdGlvbnMnXVsnbWF4X2ZpbGVfc2l6ZSddIDwgJHByb2dyZXNzWydkb3dubG9hZF9jb250ZW50X2xlbmd0aCddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJHRoaXMtPmpvYnNbJGldLCBuZXcgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbignTWF4aW11bSBhbGxvd2VkIGRvd25sb2FkIHNpemUgcmVhY2hlZC4gQ29udGVudC1sZW5ndGggaGVhZGVyIGluZGljYXRlcyAnIC4gJHByb2dyZXNzWydkb3dubG9hZF9jb250ZW50X2xlbmd0aCddIC4gJyBieXRlcy4gQWxsb3dlZCAnIC4gICR0aGlzLT5qb2JzWyRpXVsnb3B0aW9ucyddWydtYXhfZmlsZV9zaXplJ10gLiAnIGJ5dGVzJykpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGFyZSBtYXhfZmlsZV9zaXplIHdpdGggdGhlIGRvd25sb2FkIHNpemUgaW4gYnl0ZXMKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmpvYnNbJGldWydvcHRpb25zJ11bJ21heF9maWxlX3NpemUnXSA8ICRwcm9ncmVzc1snc2l6ZV9kb3dubG9hZCddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RKb2IoJHRoaXMtPmpvYnNbJGldLCBuZXcgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbignTWF4aW11bSBhbGxvd2VkIGRvd25sb2FkIHNpemUgcmVhY2hlZC4gRG93bmxvYWRlZCAnIC4gJHByb2dyZXNzWydzaXplX2Rvd25sb2FkJ10gLiAnIG9mIGFsbG93ZWQgJyAuICAkdGhpcy0+am9ic1skaV1bJ29wdGlvbnMnXVsnbWF4X2ZpbGVfc2l6ZSddIC4gJyBieXRlcycpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gVE9ETyBwcm9ncmVzcwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaGFuZGxlUmVkaXJlY3QoYXJyYXkgJGpvYiwgUmVzcG9uc2UgJHJlc3BvbnNlKQogICAgewogICAgICAgIGlmICgkbG9jYXRpb25IZWFkZXIgPSAkcmVzcG9uc2UtPmdldEhlYWRlcignbG9jYXRpb24nKSkgewogICAgICAgICAgICBpZiAocGFyc2VfdXJsKCRsb2NhdGlvbkhlYWRlciwgUEhQX1VSTF9TQ0hFTUUpKSB7CiAgICAgICAgICAgICAgICAvLyBBYnNvbHV0ZSBVUkw7IGUuZy4gaHR0cHM6Ly9leGFtcGxlLmNvbS9jb21wb3NlcgogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9ICRsb2NhdGlvbkhlYWRlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKHBhcnNlX3VybCgkbG9jYXRpb25IZWFkZXIsIFBIUF9VUkxfSE9TVCkpIHsKICAgICAgICAgICAgICAgIC8vIFNjaGVtZSByZWxhdGl2ZTsgZS5nLiAvL2V4YW1wbGUuY29tL2ZvbwogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9IHBhcnNlX3VybCgkam9iWyd1cmwnXSwgUEhQX1VSTF9TQ0hFTUUpLic6Jy4kbG9jYXRpb25IZWFkZXI7CiAgICAgICAgICAgIH0gZWxzZWlmICgnLycgPT09ICRsb2NhdGlvbkhlYWRlclswXSkgewogICAgICAgICAgICAgICAgLy8gQWJzb2x1dGUgcGF0aDsgZS5nLiAvZm9vCiAgICAgICAgICAgICAgICAkdXJsSG9zdCA9IHBhcnNlX3VybCgkam9iWyd1cmwnXSwgUEhQX1VSTF9IT1NUKTsKCiAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHBhdGggdXNpbmcgaG9zdG5hbWUgYXMgYW4gYW5jaG9yLgogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9IHByZWdfcmVwbGFjZSgne14oLisoPzovL3xAKScucHJlZ19xdW90ZSgkdXJsSG9zdCkuJyg/OjpcZCspPykoPzpbL1w/XS4qKT8kfScsICdcMScuJGxvY2F0aW9uSGVhZGVyLCAkam9iWyd1cmwnXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBSZWxhdGl2ZSBwYXRoOyBlLmcuIGZvbwogICAgICAgICAgICAgICAgLy8gVGhpcyBhY3R1YWxseSBkaWZmZXJzIGZyb20gUEhQIHdoaWNoIHNlZW1zIHRvIGFkZCBkdXBsaWNhdGUgc2xhc2hlcy4KICAgICAgICAgICAgICAgICR0YXJnZXRVcmwgPSBwcmVnX3JlcGxhY2UoJ3teKC4rLylbXi8/XSooPzpcPy4qKT8kfScsICdcMScuJGxvY2F0aW9uSGVhZGVyLCAkam9iWyd1cmwnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJHRhcmdldFVybCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJ0ZvbGxvd2luZyByZWRpcmVjdCAoJXUpICVzJywgJGpvYlsnYXR0cmlidXRlcyddWydyZWRpcmVjdHMnXSArIDEsIFVybDo6c2FuaXRpemUoJHRhcmdldFVybCkpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgcmV0dXJuICR0YXJnZXRVcmw7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgIicuJGpvYlsndXJsJ10uJyIgZmlsZSBjb3VsZCBub3QgYmUgZG93bmxvYWRlZCwgZ290IHJlZGlyZWN0IHdpdGhvdXQgTG9jYXRpb24gKCcuJHJlc3BvbnNlLT5nZXRTdGF0dXNNZXNzYWdlKCkuJyknKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzQXV0aGVudGljYXRlZFJldHJ5TmVlZGVkKGFycmF5ICRqb2IsIFJlc3BvbnNlICRyZXNwb25zZSkKICAgIHsKICAgICAgICBpZiAoaW5fYXJyYXkoJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCksIGFycmF5KDQwMSwgNDAzKSkgJiYgJGpvYlsnYXR0cmlidXRlcyddWydyZXRyeUF1dGhGYWlsdXJlJ10pIHsKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5hdXRoSGVscGVyLT5wcm9tcHRBdXRoSWZOZWVkZWQoJGpvYlsndXJsJ10sICRqb2JbJ29yaWdpbiddLCAkcmVzcG9uc2UtPmdldFN0YXR1c0NvZGUoKSwgJHJlc3BvbnNlLT5nZXRTdGF0dXNNZXNzYWdlKCksICRyZXNwb25zZS0+Z2V0SGVhZGVycygpKTsKCiAgICAgICAgICAgIGlmICgkcmVzdWx0WydyZXRyeSddKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGxvY2F0aW9uSGVhZGVyID0gJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2xvY2F0aW9uJyk7CiAgICAgICAgJG5lZWRzQXV0aFJldHJ5ID0gZmFsc2U7CgogICAgICAgIC8vIGNoZWNrIGZvciBiaXRidWNrZXQgbG9naW4gcGFnZSBhc2tpbmcgdG8gYXV0aGVudGljYXRlCiAgICAgICAgaWYgKAogICAgICAgICAgICAkam9iWydvcmlnaW4nXSA9PT0gJ2JpdGJ1Y2tldC5vcmcnCiAgICAgICAgICAgICYmICEkdGhpcy0+YXV0aEhlbHBlci0+aXNQdWJsaWNCaXRCdWNrZXREb3dubG9hZCgkam9iWyd1cmwnXSkKICAgICAgICAgICAgJiYgc3Vic3RyKCRqb2JbJ3VybCddLCAtNCkgPT09ICcuemlwJwogICAgICAgICAgICAmJiAoISRsb2NhdGlvbkhlYWRlciB8fCBzdWJzdHIoJGxvY2F0aW9uSGVhZGVyLCAtNCkgIT09ICcuemlwJykKICAgICAgICAgICAgJiYgcHJlZ19tYXRjaCgne150ZXh0L2h0bWxcYn1pJywgJHJlc3BvbnNlLT5nZXRIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKQogICAgICAgICkgewogICAgICAgICAgICAkbmVlZHNBdXRoUmV0cnkgPSAnQml0YnVja2V0IHJlcXVpcmVzIGF1dGhlbnRpY2F0aW9uIGFuZCBpdCB3YXMgbm90IHByb3ZpZGVkJzsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBnaXRsYWIgNDA0IHdoZW4gZG93bmxvYWRpbmcgYXJjaGl2ZXMKICAgICAgICBpZiAoCiAgICAgICAgICAgICRyZXNwb25zZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0MDQKICAgICAgICAgICAgJiYgJHRoaXMtPmNvbmZpZyAmJiBpbl9hcnJheSgkam9iWydvcmlnaW4nXSwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpLCB0cnVlKQogICAgICAgICAgICAmJiBmYWxzZSAhPT0gc3RycG9zKCRqb2JbJ3VybCddLCAnYXJjaGl2ZS56aXAnKQogICAgICAgICkgewogICAgICAgICAgICAkbmVlZHNBdXRoUmV0cnkgPSAnR2l0TGFiIHJlcXVpcmVzIGF1dGhlbnRpY2F0aW9uIGFuZCBpdCB3YXMgbm90IHByb3ZpZGVkJzsKICAgICAgICB9CgogICAgICAgIGlmICgkbmVlZHNBdXRoUmV0cnkpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ2F0dHJpYnV0ZXMnXVsncmV0cnlBdXRoRmFpbHVyZSddKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmF1dGhIZWxwZXItPnByb21wdEF1dGhJZk5lZWRlZCgkam9iWyd1cmwnXSwgJGpvYlsnb3JpZ2luJ10sIDQwMSk7CiAgICAgICAgICAgICAgICBpZiAoJHJlc3VsdFsncmV0cnknXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkdGhpcy0+ZmFpbFJlc3BvbnNlKCRqb2IsICRyZXNwb25zZSwgJG5lZWRzQXV0aFJldHJ5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgncmV0cnknID0+IGZhbHNlLCAnc3RvcmVBdXRoJyA9PiBmYWxzZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZXN0YXJ0Sm9iKGFycmF5ICRqb2IsICR1cmwsIGFycmF5ICRhdHRyaWJ1dGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoJGpvYlsnZmlsZW5hbWUnXSkgewogICAgICAgICAgICBAdW5saW5rKCRqb2JbJ2ZpbGVuYW1lJ10uJ34nKTsKICAgICAgICB9CgogICAgICAgICRhdHRyaWJ1dGVzID0gYXJyYXlfbWVyZ2UoJGpvYlsnYXR0cmlidXRlcyddLCAkYXR0cmlidXRlcyk7CiAgICAgICAgJG9yaWdpbiA9IFVybDo6Z2V0T3JpZ2luKCR0aGlzLT5jb25maWcsICR1cmwpOwoKICAgICAgICAkdGhpcy0+aW5pdERvd25sb2FkKCRqb2JbJ3Jlc29sdmUnXSwgJGpvYlsncmVqZWN0J10sICRvcmlnaW4sICR1cmwsICRqb2JbJ29wdGlvbnMnXSwgJGpvYlsnZmlsZW5hbWUnXSwgJGF0dHJpYnV0ZXMpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZmFpbFJlc3BvbnNlKGFycmF5ICRqb2IsIFJlc3BvbnNlICRyZXNwb25zZSwgJGVycm9yTWVzc2FnZSkKICAgIHsKICAgICAgICBpZiAoJGpvYlsnZmlsZW5hbWUnXSkgewogICAgICAgICAgICBAdW5saW5rKCRqb2JbJ2ZpbGVuYW1lJ10uJ34nKTsKICAgICAgICB9CgogICAgICAgICRkZXRhaWxzID0gJyc7CiAgICAgICAgaWYgKCRyZXNwb25zZS0+Z2V0SGVhZGVyKCdjb250ZW50LXR5cGUnKSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nKSB7CiAgICAgICAgICAgICRkZXRhaWxzID0gJzonLlBIUF9FT0wuc3Vic3RyKCRyZXNwb25zZS0+Z2V0Qm9keSgpLCAwLCAyMDApLihzdHJsZW4oJHJlc3BvbnNlLT5nZXRCb2R5KCkpID4gMjAwID8gJy4uLicgOiAnJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiRqb2JbJ3VybCddLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQgKCcuJGVycm9yTWVzc2FnZS4nKScgLiAkZGV0YWlscywgJHJlc3BvbnNlLT5nZXRTdGF0dXNDb2RlKCkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVqZWN0Sm9iKGFycmF5ICRqb2IsIFxFeGNlcHRpb24gJGUpCiAgICB7CiAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRqb2JbJ2hlYWRlckhhbmRsZSddKSkgewogICAgICAgICAgICBmY2xvc2UoJGpvYlsnaGVhZGVySGFuZGxlJ10pOwogICAgICAgIH0KICAgICAgICBpZiAoaXNfcmVzb3VyY2UoJGpvYlsnYm9keUhhbmRsZSddKSkgewogICAgICAgICAgICBmY2xvc2UoJGpvYlsnYm9keUhhbmRsZSddKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRqb2JbJ2ZpbGVuYW1lJ10pIHsKICAgICAgICAgICAgQHVubGluaygkam9iWydmaWxlbmFtZSddLid+Jyk7CiAgICAgICAgfQogICAgICAgIGNhbGxfdXNlcl9mdW5jKCRqb2JbJ3JlamVjdCddLCAkZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0N1cmxSZXN1bHQoJGNvZGUpCiAgICB7CiAgICAgICAgaWYgKCRjb2RlICE9IENVUkxNX09LICYmICRjb2RlICE9IENVUkxNX0NBTExfTVVMVElfUEVSRk9STSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICBpc3NldCgkdGhpcy0+bXVsdGlFcnJvcnNbJGNvZGVdKQogICAgICAgICAgICAgICAgPyAiY1VSTCBlcnJvcjogeyRjb2RlfSAoeyR0aGlzLT5tdWx0aUVycm9yc1skY29kZV1bMF19KTogY1VSTCBtZXNzYWdlOiB7JHRoaXMtPm11bHRpRXJyb3JzWyRjb2RlXVsxXX0iCiAgICAgICAgICAgICAgICA6ICdVbmV4cGVjdGVkIGNVUkwgZXJyb3I6ICcgLiAkY29kZQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsXEh0dHA7CgovKioKICogUHJveHkgZGlzY292ZXJ5IGFuZCBoZWxwZXIgY2xhc3MKICoKICogQGludGVybmFsCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBQcm94eUhlbHBlcgp7CiAgICAvKioKICAgICAqIFJldHVybnMgcHJveHkgZW52aXJvbm1lbnQgdmFsdWVzCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBvbiBtYWxmb3JtZWQgdXJsCiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgICAgICAgIGh0dHBQcm94eSwgaHR0cHNQcm94eSwgbm9Qcm94eSB2YWx1ZXMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRQcm94eURhdGEoKQogICAgewogICAgICAgICRodHRwUHJveHkgPSBudWxsOwogICAgICAgICRodHRwc1Byb3h5ID0gbnVsbDsKCiAgICAgICAgLy8gSGFuZGxlIGh0dHBfcHJveHkvSFRUUF9QUk9YWSBvbiBDTEkgb25seSBmb3Igc2VjdXJpdHkgcmVhc29ucwogICAgICAgIGlmIChQSFBfU0FQSSA9PT0gJ2NsaScgfHwgUEhQX1NBUEkgPT09ICdwaHBkYmcnKSB7CiAgICAgICAgICAgIGlmICgkZW52ID0gc2VsZjo6Z2V0UHJveHlFbnYoYXJyYXkoJ2h0dHBfcHJveHknLCAnSFRUUF9QUk9YWScpLCAkbmFtZSkpIHsKICAgICAgICAgICAgICAgICRodHRwUHJveHkgPSBzZWxmOjpjaGVja1Byb3h5KCRlbnYsICRuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUHJlZmVyIENHSV9IVFRQX1BST1hZIGlmIGF2YWlsYWJsZQogICAgICAgIGlmICgkZW52ID0gc2VsZjo6Z2V0UHJveHlFbnYoYXJyYXkoJ0NHSV9IVFRQX1BST1hZJyksICRuYW1lKSkgewogICAgICAgICAgICAkaHR0cFByb3h5ID0gc2VsZjo6Y2hlY2tQcm94eSgkZW52LCAkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBIYW5kbGUgaHR0cHNfcHJveHkvSFRUUFNfUFJPWFkKICAgICAgICBpZiAoJGVudiA9IHNlbGY6OmdldFByb3h5RW52KGFycmF5KCdodHRwc19wcm94eScsICdIVFRQU19QUk9YWScpLCAkbmFtZSkpIHsKICAgICAgICAgICAgJGh0dHBzUHJveHkgPSBzZWxmOjpjaGVja1Byb3h5KCRlbnYsICRuYW1lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaHR0cHNQcm94eSA9ICRodHRwUHJveHk7CiAgICAgICAgfQoKICAgICAgICAvLyBIYW5kbGUgbm9fcHJveHkKICAgICAgICAkbm9Qcm94eSA9IHNlbGY6OmdldFByb3h5RW52KGFycmF5KCdub19wcm94eScsICdOT19QUk9YWScpLCAkbmFtZSk7CgogICAgICAgIHJldHVybiBhcnJheSgkaHR0cFByb3h5LCAkaHR0cHNQcm94eSwgJG5vUHJveHkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBodHRwIGNvbnRleHQgb3B0aW9ucyBmb3IgdGhlIHByb3h5IHVybAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwcm94eVVybAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRleHRPcHRpb25zKCRwcm94eVVybCkKICAgIHsKICAgICAgICAkcHJveHkgPSBwYXJzZV91cmwoJHByb3h5VXJsKTsKCiAgICAgICAgLy8gUmVtb3ZlIGFueSBhdXRob3JpemF0aW9uCiAgICAgICAgJHByb3h5VXJsID0gc2VsZjo6Zm9ybWF0UGFyc2VkVXJsKCRwcm94eSwgZmFsc2UpOwogICAgICAgICRwcm94eVVybCA9IHN0cl9yZXBsYWNlKGFycmF5KCdodHRwOi8vJywgJ2h0dHBzOi8vJyksIGFycmF5KCd0Y3A6Ly8nLCAnc3NsOi8vJyksICRwcm94eVVybCk7CgogICAgICAgICRvcHRpb25zWydodHRwJ11bJ3Byb3h5J10gPSAkcHJveHlVcmw7CgogICAgICAgIC8vIEhhbmRsZSBhbnkgYXV0aG9yaXphdGlvbgogICAgICAgIGlmIChpc3NldCgkcHJveHlbJ3VzZXInXSkpIHsKICAgICAgICAgICAgJGF1dGggPSByYXd1cmxkZWNvZGUoJHByb3h5Wyd1c2VyJ10pOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRwcm94eVsncGFzcyddKSkgewogICAgICAgICAgICAgICAgJGF1dGggLj0gJzonIC4gcmF3dXJsZGVjb2RlKCRwcm94eVsncGFzcyddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkYXV0aCA9IGJhc2U2NF9lbmNvZGUoJGF1dGgpOwogICAgICAgICAgICAvLyBTZXQgaGVhZGVyIGFzIGEgc3RyaW5nCiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gIlByb3h5LUF1dGhvcml6YXRpb246IEJhc2ljIHskYXV0aH0iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cy91bnNldHMgcmVxdWVzdF9mdWxsdXJpIHZhbHVlIGluIGh0dHAgY29udGV4dCBvcHRpb25zIGFycmF5CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVxdWVzdFVybAogICAgICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyAgICBTZXQgYnkgbWV0aG9kCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0UmVxdWVzdEZ1bGxVcmkoJHJlcXVlc3RVcmwsIGFycmF5ICYkb3B0aW9ucykKICAgIHsKICAgICAgICBpZiAoJ2h0dHAnID09PSBwYXJzZV91cmwoJHJlcXVlc3RVcmwsIFBIUF9VUkxfU0NIRU1FKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydyZXF1ZXN0X2Z1bGx1cmknXSA9IHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ2h0dHAnXVsncmVxdWVzdF9mdWxsdXJpJ10pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNlYXJjaGVzICRfU0VSVkVSIGZvciBjYXNlLXNlbnNpdGl2ZSB2YWx1ZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICRuYW1lcyBOYW1lcyB0byBzZWFyY2ggZm9yCiAgICAgKiBAcGFyYW0gIG1peGVkICAgICAgICRuYW1lICBOYW1lIG9mIGFueSBmb3VuZCB2YWx1ZQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgZm91bmQgdmFsdWUKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0UHJveHlFbnYoYXJyYXkgJG5hbWVzLCAmJG5hbWUpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJG5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJF9TRVJWRVJbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRfU0VSVkVSWyRuYW1lXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhbmQgZm9ybWF0cyBhIHByb3h5IHVybCBmcm9tIHRoZSBlbnZpcm9ubWVudAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHByb3h5VXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRlbnZOYW1lCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIG9uIG1hbGZvcm1lZCB1cmwKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICAgVGhlIGZvcm1hdHRlZCBwcm94eSB1cmwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY2hlY2tQcm94eSgkcHJveHlVcmwsICRlbnZOYW1lKQogICAgewogICAgICAgICRlcnJvciA9IHNwcmludGYoJ21hbGZvcm1lZCAlcyB1cmwnLCAkZW52TmFtZSk7CiAgICAgICAgJHByb3h5ID0gcGFyc2VfdXJsKCRwcm94eVVybCk7CgogICAgICAgIC8vIFdlIG5lZWQgcGFyc2VfdXJsIHRvIGhhdmUgaWRlbnRpZmllZCBhIGhvc3QKICAgICAgICBpZiAoIWlzc2V0KCRwcm94eVsnaG9zdCddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgICRwcm94eVVybCA9IHNlbGY6OmZvcm1hdFBhcnNlZFVybCgkcHJveHksIHRydWUpOwoKICAgICAgICAvLyBXZSBuZWVkIGEgcG9ydCBiZWNhdXNlIHN0cmVhbXMgYW5kIGN1cmwgdXNlIGRpZmZlcmVudCBkZWZhdWx0cwogICAgICAgIGlmICghcGFyc2VfdXJsKCRwcm94eVVybCwgUEhQX1VSTF9QT1JUKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJveHlVcmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgdXJsIGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0cwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXkgICRwcm94eSAgICAgICBWYWx1ZXMgZnJvbSBwYXJzZV91cmwKICAgICAqIEBwYXJhbSAgYm9vbCAgICRpbmNsdWRlQXV0aCBXaGV0aGVyIHRvIGluY2x1ZGUgYXV0aG9yaXphdGlvbiB2YWx1ZXMKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBmb3JtYXR0ZWQgdmFsdWUKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0UGFyc2VkVXJsKGFycmF5ICRwcm94eSwgJGluY2x1ZGVBdXRoKQogICAgewogICAgICAgICRwcm94eVVybCA9IGlzc2V0KCRwcm94eVsnc2NoZW1lJ10pID8gc3RydG9sb3dlcigkcHJveHlbJ3NjaGVtZSddKSAuICc6Ly8nIDogJyc7CgogICAgICAgIGlmICgkaW5jbHVkZUF1dGggJiYgaXNzZXQoJHByb3h5Wyd1c2VyJ10pKSB7CiAgICAgICAgICAgICRwcm94eVVybCAuPSAkcHJveHlbJ3VzZXInXTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkcHJveHlbJ3Bhc3MnXSkpIHsKICAgICAgICAgICAgICAgICRwcm94eVVybCAuPSAnOicgLiAkcHJveHlbJ3Bhc3MnXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcHJveHlVcmwgLj0gJ0AnOwogICAgICAgIH0KCiAgICAgICAgJHByb3h5VXJsIC49ICRwcm94eVsnaG9zdCddOwoKICAgICAgICBpZiAoaXNzZXQoJHByb3h5Wydwb3J0J10pKSB7CiAgICAgICAgICAgICRwcm94eVVybCAuPSAnOicgLiAkcHJveHlbJ3BvcnQnXTsKICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCRwcm94eVVybCwgJ2h0dHA6Ly8nKSA9PT0gMCkgewogICAgICAgICAgICAkcHJveHlVcmwgLj0gJzo4MCc7CiAgICAgICAgfSBlbHNlaWYgKHN0cnBvcygkcHJveHlVcmwsICdodHRwczovLycpID09PSAwKSB7CiAgICAgICAgICAgICRwcm94eVVybCAuPSAnOjQ0Myc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb3h5VXJsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWxcSHR0cDsKCmNsYXNzIEN1cmxSZXNwb25zZSBleHRlbmRzIFJlc3BvbnNlCnsKICAgIHByaXZhdGUgJGN1cmxJbmZvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcmVxdWVzdCwgJGNvZGUsIGFycmF5ICRoZWFkZXJzLCAkYm9keSwgYXJyYXkgJGN1cmxJbmZvKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHJlcXVlc3QsICRjb2RlLCAkaGVhZGVycywgJGJvZHkpOwogICAgICAgICR0aGlzLT5jdXJsSW5mbyA9ICRjdXJsSW5mbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEN1cmxJbmZvKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmN1cmxJbmZvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWxcSHR0cDsKCnVzZSBDb21wb3NlclxVdGlsXFVybDsKCi8qKgogKiBAaW50ZXJuYWwKICogQGF1dGhvciBKb2huIFN0ZXZlbnNvbiA8am9obi1zdGV2ZW5zb25AYmx1ZXlvbmRlci5jby51az4KICovCmNsYXNzIFJlcXVlc3RQcm94eQp7CiAgICBwcml2YXRlICRjb250ZXh0T3B0aW9uczsKICAgIHByaXZhdGUgJGlzU2VjdXJlOwogICAgcHJpdmF0ZSAkZm9ybWF0dGVkVXJsOwogICAgcHJpdmF0ZSAkdXJsOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0T3B0aW9ucwogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybWF0dGVkVXJsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXJsLCBhcnJheSAkY29udGV4dE9wdGlvbnMsICRmb3JtYXR0ZWRVcmwpCiAgICB7CiAgICAgICAgJHRoaXMtPnVybCA9ICR1cmw7CiAgICAgICAgJHRoaXMtPmNvbnRleHRPcHRpb25zID0gJGNvbnRleHRPcHRpb25zOwogICAgICAgICR0aGlzLT5mb3JtYXR0ZWRVcmwgPSAkZm9ybWF0dGVkVXJsOwogICAgICAgICR0aGlzLT5pc1NlY3VyZSA9IDAgPT09IHN0cnBvcygkdXJsLCAnaHR0cHM6Ly8nKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgY29udGV4dCBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGV4dE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29udGV4dE9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzYWZlIHByb3h5IHVybCBmcm9tIHRoZSBsYXN0IHJlcXVlc3QKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xudWxsICRmb3JtYXQgT3V0cHV0IGZvcm1hdCBzcGVjaWZpZXIKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgU2FmZSBwcm94eSwgbm8gcHJveHkgb3IgZW1wdHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlZFVybCgkZm9ybWF0ID0gJycpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICcnOwogICAgICAgIGlmICgkdGhpcy0+Zm9ybWF0dGVkVXJsKSB7CiAgICAgICAgICAgICRmb3JtYXQgPSAkZm9ybWF0ID86ICclcyc7CiAgICAgICAgICAgICRyZXN1bHQgPSBzcHJpbnRmKCRmb3JtYXQsICR0aGlzLT5mb3JtYXR0ZWRVcmwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm94eSB1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBQcm94eSB1cmwgb3IgZW1wdHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHNlY3VyZS1wcm94eQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBGYWxzZSBpZiBub3Qgc2VjdXJlIG9yIHRoZXJlIGlzIG5vIHByb3h5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1NlY3VyZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1NlY3VyZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsXEh0dHA7Cgp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxVdGlsXE5vUHJveHlQYXR0ZXJuOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CgovKioKICogQGludGVybmFsCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBQcm94eU1hbmFnZXIKewogICAgcHJpdmF0ZSAkZXJyb3I7CiAgICBwcml2YXRlICRmdWxsUHJveHk7CiAgICBwcml2YXRlICRzYWZlUHJveHk7CiAgICBwcml2YXRlICRzdHJlYW1zOwogICAgcHJpdmF0ZSAkaGFzUHJveHk7CiAgICBwcml2YXRlICRpbmZvOwogICAgcHJpdmF0ZSAkbGFzdFByb3h5OwogICAgLyoqIEB2YXIgTm9Qcm94eVBhdHRlcm4gKi8KICAgIHByaXZhdGUgJG5vUHJveHlIYW5kbGVyOwoKICAgIC8qKiBAdmFyIFByb3h5TWFuYWdlciAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGluc3RhbmNlOwoKICAgIHByaXZhdGUgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5mdWxsUHJveHkgPSAkdGhpcy0+c2FmZVByb3h5ID0gYXJyYXkoCiAgICAgICAgICAgICdodHRwJyA9PiBudWxsLAogICAgICAgICAgICAnaHR0cHMnID0+IG51bGwsCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPnN0cmVhbXNbJ2h0dHAnXSA9ICR0aGlzLT5zdHJlYW1zWydodHRwcyddID0gYXJyYXkoCiAgICAgICAgICAgICdvcHRpb25zJyA9PiBudWxsLAogICAgICAgICk7CgogICAgICAgICR0aGlzLT5oYXNQcm94eSA9IGZhbHNlOwogICAgICAgICR0aGlzLT5pbml0UHJveHlEYXRhKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFByb3h5TWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEluc3RhbmNlKCkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRpbnN0YW5jZSkgewogICAgICAgICAgICBzZWxmOjokaW5zdGFuY2UgPSBuZXcgc2VsZigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRpbnN0YW5jZTsKICAgIH0KCiAgICAvKioKICAgICAqIENsZWFycyB0aGUgcGVyc2lzdGVudCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICBzZWxmOjokaW5zdGFuY2UgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIFJlcXVlc3RQcm94eSBpbnN0YW5jZSBmb3IgdGhlIHJlcXVlc3QgdXJsCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJHJlcXVlc3RVcmwKICAgICAqIEByZXR1cm4gUmVxdWVzdFByb3h5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm94eUZvclJlcXVlc3QoJHJlcXVlc3RVcmwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5lcnJvcikgewogICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdVbmFibGUgdG8gdXNlIGEgcHJveHk6ICcuJHRoaXMtPmVycm9yKTsKICAgICAgICB9CgogICAgICAgICRzY2hlbWUgPSBwYXJzZV91cmwoJHJlcXVlc3RVcmwsIFBIUF9VUkxfU0NIRU1FKSA/OiAnaHR0cCc7CiAgICAgICAgJHByb3h5VXJsID0gJyc7CiAgICAgICAgJG9wdGlvbnMgPSBhcnJheSgpOwogICAgICAgICRmb3JtYXR0ZWRQcm94eVVybCA9ICcnOwoKICAgICAgICBpZiAoJHRoaXMtPmhhc1Byb3h5ICYmIGluX2FycmF5KCRzY2hlbWUsIGFycmF5KCdodHRwJywgJ2h0dHBzJyksIHRydWUpICYmICR0aGlzLT5mdWxsUHJveHlbJHNjaGVtZV0pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5ub1Byb3h5KCRyZXF1ZXN0VXJsKSkgewogICAgICAgICAgICAgICAgJGZvcm1hdHRlZFByb3h5VXJsID0gJ2V4Y2x1ZGVkIGJ5IG5vX3Byb3h5JzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm94eVVybCA9ICR0aGlzLT5mdWxsUHJveHlbJHNjaGVtZV07CiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICR0aGlzLT5zdHJlYW1zWyRzY2hlbWVdWydvcHRpb25zJ107CiAgICAgICAgICAgICAgICBQcm94eUhlbHBlcjo6c2V0UmVxdWVzdEZ1bGxVcmkoJHJlcXVlc3RVcmwsICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICRmb3JtYXR0ZWRQcm94eVVybCA9ICR0aGlzLT5zYWZlUHJveHlbJHNjaGVtZV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUmVxdWVzdFByb3h5KCRwcm94eVVybCwgJG9wdGlvbnMsICRmb3JtYXR0ZWRQcm94eVVybCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBwcm94eSBpcyBiZWluZyB1c2VkCiAgICAgKgogICAgICogQHJldHVybiBib29sIElmIGZhbHNlIGFueSBlcnJvciB3aWxsIGJlIGluICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Byb3h5aW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1Byb3h5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwcm94eSBjb25maWd1cmF0aW9uIGluZm8gd2hpY2ggY2FuIGJlIHNob3duIHRvIHRoZSB1c2VyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBTYWZlIHByb3h5IFVSTCBvciBhbiBlcnJvciBtZXNzYWdlIGlmIHNldHRpbmcgdXAgcHJveHkgZmFpbGVkIG9yIG51bGwgaWYgbm8gcHJveHkgd2FzIGNvbmZpZ3VyZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlZFByb3h5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc1Byb3h5ID8gJHRoaXMtPmluZm8gOiAkdGhpcy0+ZXJyb3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBwcm94eSB2YWx1ZXMgZnJvbSB0aGUgZW52aXJvbm1lbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0UHJveHlEYXRhKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBsaXN0KCRodHRwUHJveHksICRodHRwc1Byb3h5LCAkbm9Qcm94eSkgPSBQcm94eUhlbHBlcjo6Z2V0UHJveHlEYXRhKCk7CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yID0gJGUtPmdldE1lc3NhZ2UoKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRpbmZvID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKCRodHRwUHJveHkpIHsKICAgICAgICAgICAgJGluZm9bXSA9ICR0aGlzLT5zZXREYXRhKCRodHRwUHJveHksICdodHRwJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaHR0cHNQcm94eSkgewogICAgICAgICAgICAkaW5mb1tdID0gJHRoaXMtPnNldERhdGEoJGh0dHBzUHJveHksICdodHRwcycpOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPmhhc1Byb3h5KSB7CiAgICAgICAgICAgICR0aGlzLT5pbmZvID0gaW1wbG9kZSgnLCAnLCAkaW5mbyk7CiAgICAgICAgICAgIGlmICgkbm9Qcm94eSkgewogICAgICAgICAgICAgICAgJHRoaXMtPm5vUHJveHlIYW5kbGVyID0gYXJyYXkobmV3IE5vUHJveHlQYXR0ZXJuKCRub1Byb3h5KSwgJ3Rlc3QnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgaW5pdGlhbCBkYXRhCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsICAgIFByb3h5IHVybAogICAgICogQHBhcmFtIHN0cmluZyAkc2NoZW1lIEVudmlyb25tZW50IHZhcmlhYmxlIHNjaGVtZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldERhdGEoJHVybCwgJHNjaGVtZSkKICAgIHsKICAgICAgICAkc2FmZVByb3h5ID0gVXJsOjpzYW5pdGl6ZSgkdXJsKTsKICAgICAgICAkdGhpcy0+ZnVsbFByb3h5WyRzY2hlbWVdID0gJHVybDsKICAgICAgICAkdGhpcy0+c2FmZVByb3h5WyRzY2hlbWVdID0gJHNhZmVQcm94eTsKICAgICAgICAkdGhpcy0+c3RyZWFtc1skc2NoZW1lXVsnb3B0aW9ucyddID0gUHJveHlIZWxwZXI6OmdldENvbnRleHRPcHRpb25zKCR1cmwpOwogICAgICAgICR0aGlzLT5oYXNQcm94eSA9IHRydWU7CgogICAgICAgIHJldHVybiBzcHJpbnRmKCclcz0lcycsICRzY2hlbWUsICRzYWZlUHJveHkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGEgdXJsIG1hdGNoZXMgbm9fcHJveHkgdmFsdWUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcmVxdWVzdFVybAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm9Qcm94eSgkcmVxdWVzdFVybCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm5vUHJveHlIYW5kbGVyKSB7CiAgICAgICAgICAgIGlmIChjYWxsX3VzZXJfZnVuYygkdGhpcy0+bm9Qcm94eUhhbmRsZXIsICRyZXF1ZXN0VXJsKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxhc3RQcm94eSA9ICdleGNsdWRlZCBieSBub19wcm94eSc7CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsXEh0dHA7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKCmNsYXNzIFJlc3BvbnNlCnsKICAgIHByaXZhdGUgJHJlcXVlc3Q7CiAgICBwcml2YXRlICRjb2RlOwogICAgcHJpdmF0ZSAkaGVhZGVyczsKICAgIHByaXZhdGUgJGJvZHk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRyZXF1ZXN0LCAkY29kZSwgYXJyYXkgJGhlYWRlcnMsICRib2R5KQogICAgewogICAgICAgIGlmICghaXNzZXQoJHJlcXVlc3RbJ3VybCddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCd1cmwga2V5IG1pc3NpbmcgZnJvbSByZXF1ZXN0IGFycmF5Jyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5yZXF1ZXN0ID0gJHJlcXVlc3Q7CiAgICAgICAgJHRoaXMtPmNvZGUgPSAoaW50KSAkY29kZTsKICAgICAgICAkdGhpcy0+aGVhZGVycyA9ICRoZWFkZXJzOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c01lc3NhZ2UoKQogICAgewogICAgICAgICR2YWx1ZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15IVFRQL1xTKyBcZCt9aScsICRoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIG9mIHJlZGlyZWN0cywgaGVhZGVycyBjb250YWluIHRoZSBoZWFkZXJzIG9mIGFsbCByZXNwb25zZXMKICAgICAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBub3QgcmV0dXJuIGRpcmVjdGx5IGFuZCBuZWVkIHRvIGtlZXAgaXRlcmF0aW5nCiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkaGVhZGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWFkZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhlYWRlcnM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlYWRlcigkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6ZmluZEhlYWRlclZhbHVlKCR0aGlzLT5oZWFkZXJzLCAkbmFtZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVjb2RlSnNvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmJvZHksICR0aGlzLT5yZXF1ZXN0Wyd1cmwnXSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNvbGxlY3QoKQogICAgewogICAgICAgICR0aGlzLT5yZXF1ZXN0ID0gJHRoaXMtPmNvZGUgPSAkdGhpcy0+aGVhZGVycyA9ICR0aGlzLT5ib2R5ID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICAgJGhlYWRlcnMgYXJyYXkgb2YgcmV0dXJuZWQgaGVhZGVycyBsaWtlIGZyb20gZ2V0TGFzdEhlYWRlcnMoKQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkbmFtZSAgICBoZWFkZXIgbmFtZSAoY2FzZSBpbnNlbnNpdGl2ZSkKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmaW5kSGVhZGVyVmFsdWUoYXJyYXkgJGhlYWRlcnMsICRuYW1lKQogICAgewogICAgICAgICR2YWx1ZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJGhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14nLnByZWdfcXVvdGUoJG5hbWUpLic6XHMqKC4rPylccyokfWknLCAkaGVhZGVyLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBzdGRDbGFzczsKCi8qKgogKiBUZXN0cyBVUkxzIGFnYWluc3QgTk9fUFJPWFkgcGF0dGVybnMKICovCmNsYXNzIE5vUHJveHlQYXR0ZXJuCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmdbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGhvc3ROYW1lcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIG9iamVjdFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcnVsZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbm9wcm94eTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdHRlcm4gTk9fUFJPWFkgcGF0dGVybgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPmhvc3ROYW1lcyA9IHByZWdfc3BsaXQoJ3tbXHMsXSt9JywgJHBhdHRlcm4sIG51bGwsIFBSRUdfU1BMSVRfTk9fRU1QVFkpOwogICAgICAgICR0aGlzLT5ub3Byb3h5ID0gZW1wdHkoJHRoaXMtPmhvc3ROYW1lcykgfHwgJyonID09PSAkdGhpcy0+aG9zdE5hbWVzWzBdOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGEgVVJMIG1hdGNoZXMgdGhlIE5PX1BST1hZIHBhdHRlcm4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRlc3QoJHVybCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm5vcHJveHkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR1cmxEYXRhID0gJHRoaXMtPmdldFVybERhdGEoJHVybCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmhvc3ROYW1lcyBhcyAkaW5kZXggPT4gJGhvc3ROYW1lKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bWF0Y2goJGluZGV4LCAkaG9zdE5hbWUsICR1cmxEYXRhKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgZmFsc2UgaXMgdGhlIHVybCBjYW5ub3QgYmUgcGFyc2VkLCBvdGhlcndpc2UgYSBkYXRhIG9iamVjdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbHxzdGRjbGFzcwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VXJsRGF0YSgkdXJsKQogICAgewogICAgICAgIGlmICghJGhvc3QgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9IT1NUKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcG9ydCA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1BPUlQpOwoKICAgICAgICBpZiAoZW1wdHkoJHBvcnQpKSB7CiAgICAgICAgICAgIHN3aXRjaCAocGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfU0NIRU1FKSkgewogICAgICAgICAgICAgICAgY2FzZSAnaHR0cCc6CiAgICAgICAgICAgICAgICAgICAgJHBvcnQgPSA4MDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2h0dHBzJzoKICAgICAgICAgICAgICAgICAgICAkcG9ydCA9IDQ0MzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGhvc3ROYW1lID0gJGhvc3QgLiAoJHBvcnQgPyAnOicgLiAkcG9ydCA6ICcnKTsKICAgICAgICBsaXN0KCRob3N0LCAkcG9ydCwgJGVycikgPSAkdGhpcy0+c3BsaXRIb3N0UG9ydCgkaG9zdE5hbWUpOwoKICAgICAgICBpZiAoJGVyciB8fCAhJHRoaXMtPmlwQ2hlY2tEYXRhKCRob3N0LCAkaXBkYXRhKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPm1ha2VEYXRhKCRob3N0LCAkcG9ydCwgJGlwZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHVybCBpcyBtYXRjaGVkIGJ5IGEgcnVsZQogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgJGluZGV4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRob3N0TmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBtYXRjaCgkaW5kZXgsICRob3N0TmFtZSwgJHVybCkKICAgIHsKICAgICAgICBpZiAoISRydWxlID0gJHRoaXMtPmdldFJ1bGUoJGluZGV4LCAkaG9zdE5hbWUpKSB7CiAgICAgICAgICAgIC8vIERhdGEgbXVzdCBoYXZlIGJlZW4gbWlzZm9ybWF0dGVkCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkcnVsZS0+aXBkYXRhKSB7CiAgICAgICAgICAgIC8vIE1hdGNoIGlwZGF0YSBmaXJzdAogICAgICAgICAgICBpZiAoISR1cmwtPmlwZGF0YSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHJ1bGUtPmlwZGF0YS0+bmV0bWFzaykgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaFJhbmdlKCRydWxlLT5pcGRhdGEsICR1cmwtPmlwZGF0YSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtYXRjaCA9ICRydWxlLT5pcGRhdGEtPmlwID09PSAkdXJsLT5pcGRhdGEtPmlwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIE1hdGNoIGhvc3QgYW5kIHBvcnQKICAgICAgICAgICAgJGhheXN0YWNrID0gc3Vic3RyKCR1cmwtPm5hbWUsIC1zdHJsZW4oJHJ1bGUtPm5hbWUpKTsKICAgICAgICAgICAgJG1hdGNoID0gc3RyaXBvcygkaGF5c3RhY2ssICRydWxlLT5uYW1lKSA9PT0gMDsKICAgICAgICB9CgogICAgICAgIGlmICgkbWF0Y2ggJiYgJHJ1bGUtPnBvcnQpIHsKICAgICAgICAgICAgJG1hdGNoID0gJHJ1bGUtPnBvcnQgPT09ICR1cmwtPnBvcnQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB0YXJnZXQgaXAgaXMgaW4gdGhlIG5ldHdvcmsgcmFuZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gc3RkQ2xhc3MgJG5ldHdvcmsKICAgICAqIEBwYXJhbSBzdGRDbGFzcyAkdGFyZ2V0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBtYXRjaFJhbmdlKHN0ZENsYXNzICRuZXR3b3JrLCBzdGRDbGFzcyAkdGFyZ2V0KQogICAgewogICAgICAgICRuZXQgPSB1bnBhY2soJ0MqJywgJG5ldHdvcmstPmlwKTsKICAgICAgICAkbWFzayA9IHVucGFjaygnQyonLCAkbmV0d29yay0+bmV0bWFzayk7CiAgICAgICAgJGlwID0gdW5wYWNrKCdDKicsICR0YXJnZXQtPmlwKTsKCiAgICAgICAgZm9yICgkaSA9IDE7ICRpIDwgMTc7ICsrJGkpIHsKICAgICAgICAgICAgaWYgKCgkbmV0WyRpXSAmICRtYXNrWyRpXSkgIT09ICgkaXBbJGldICYgJG1hc2tbJGldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIG9yIGNyZWF0ZXMgcnVsZSBkYXRhIGZvciBhIGhvc3RuYW1lCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAkaW5kZXgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGhvc3ROYW1lCiAgICAgKgogICAgICogQHJldHVybiBudWxsfHN0ZENsYXNzIE51bGwgaWYgdGhlIGhvc3RuYW1lIGlzIGludmFsaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSdWxlKCRpbmRleCwgJGhvc3ROYW1lKQogICAgewogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRpbmRleCwgJHRoaXMtPnJ1bGVzKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJ1bGVzWyRpbmRleF07CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cnVsZXNbJGluZGV4XSA9IG51bGw7CiAgICAgICAgbGlzdCgkaG9zdCwgJHBvcnQsICRlcnIpID0gJHRoaXMtPnNwbGl0SG9zdFBvcnQoJGhvc3ROYW1lKTsKCiAgICAgICAgaWYgKCRlcnIgfHwgISR0aGlzLT5pcENoZWNrRGF0YSgkaG9zdCwgJGlwZGF0YSwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cnVsZXNbJGluZGV4XSA9ICR0aGlzLT5tYWtlRGF0YSgkaG9zdCwgJHBvcnQsICRpcGRhdGEpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPnJ1bGVzWyRpbmRleF07CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb250YWluaW5nIElQIGRhdGEgaWYgdGhlIGhvc3QgaXMgYW4gSVAgYWRkcmVzcwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICRob3N0CiAgICAgKiBAcGFyYW0gbnVsbHxzdGRjbGFzcyAkaXBkYXRhICAgICAgU2V0IGJ5IG1ldGhvZCBpZiBJUCBhZGRyZXNzIGZvdW5kCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAkYWxsb3dQcmVmaXggV2hldGhlciBhIENJRFIgcHJlZml4LWxlbmd0aCBpcyBleHBlY3RlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBGYWxzZSBpZiB0aGUgaG9zdCBjb250YWlucyBpbnZhbGlkIGRhdGEKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpcENoZWNrRGF0YSgkaG9zdCwgJiRpcGRhdGEsICRhbGxvd1ByZWZpeCA9IGZhbHNlKQogICAgewogICAgICAgICRpcGRhdGEgPSBudWxsOwogICAgICAgICRuZXRtYXNrID0gbnVsbDsKICAgICAgICAkcHJlZml4ID0gbnVsbDsKICAgICAgICAkbW9kaWZpZWQgPSBmYWxzZTsKCiAgICAgICAgLy8gQ2hlY2sgZm9yIGEgQ0lEUiBwcmVmaXgtbGVuZ3RoCiAgICAgICAgaWYgKHN0cnBvcygkaG9zdCwgJy8nKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgbGlzdCgkaG9zdCwgJHByZWZpeCkgPSBleHBsb2RlKCcvJywgJGhvc3QpOwoKICAgICAgICAgICAgaWYgKCEkYWxsb3dQcmVmaXggfHwgISR0aGlzLT52YWxpZGF0ZUludCgkcHJlZml4LCAwLCAxMjgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHByZWZpeCA9IChpbnQpICRwcmVmaXg7CiAgICAgICAgICAgICRtb2RpZmllZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBTZWUgaWYgdGhpcyBpcyBhbiBpcCBhZGRyZXNzCiAgICAgICAgaWYgKCFmaWx0ZXJfdmFyKCRob3N0LCBGSUxURVJfVkFMSURBVEVfSVApKSB7CiAgICAgICAgICAgIHJldHVybiAhJG1vZGlmaWVkOwogICAgICAgIH0KCiAgICAgICAgbGlzdCgkaXAsICRzaXplKSA9ICR0aGlzLT5pcEdldEFkZHIoJGhvc3QpOwoKICAgICAgICBpZiAoJHByZWZpeCAhPT0gbnVsbCkgewogICAgICAgICAgICAvLyBDaGVjayBmb3IgYSB2YWxpZCBwcmVmaXgKICAgICAgICAgICAgaWYgKCRwcmVmaXggPiAkc2l6ZSAqIDgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGlzdCgkaXAsICRuZXRtYXNrKSA9ICR0aGlzLT5pcEdldE5ldHdvcmsoJGlwLCAkc2l6ZSwgJHByZWZpeCk7CiAgICAgICAgfQoKICAgICAgICAkaXBkYXRhID0gJHRoaXMtPm1ha2VJcERhdGEoJGlwLCAkc2l6ZSwgJG5ldG1hc2spOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIElQIGluX2FkZHIgYW5kIGl0cyBieXRlIHNpemUKICAgICAqCiAgICAgKiBJUHY0IGFkZHJlc3NlcyBhcmUgYWx3YXlzIG1hcHBlZCB0byBJUHY2LCB3aGljaCBzaW1wbGlmaWVzIGhhbmRsaW5nCiAgICAgKiBhbmQgY29tcGFyaXNvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRob3N0CiAgICAgKgogICAgICogQHJldHVybiBtaXhlZFtdIGluX2FkZHIsIHNpemUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpcEdldEFkZHIoJGhvc3QpCiAgICB7CiAgICAgICAgJGlwID0gaW5ldF9wdG9uKCRob3N0KTsKICAgICAgICAkc2l6ZSA9IHN0cmxlbigkaXApOwogICAgICAgICRtYXBwZWQgPSAkdGhpcy0+aXBNYXBUbzYoJGlwLCAkc2l6ZSk7CgogICAgICAgIHJldHVybiBhcnJheSgkbWFwcGVkLCAkc2l6ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBiaW5hcnkgbmV0d29yayBtYXNrIG1hcHBlZCB0byBJUHY2CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJlZml4IENJRFIgcHJlZml4LWxlbmd0aAogICAgICogQHBhcmFtIGludCAgICAkc2l6ZSAgIEJ5dGUgc2l6ZSBvZiBpbl9hZGRyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpcEdldE1hc2soJHByZWZpeCwgJHNpemUpCiAgICB7CiAgICAgICAgJG1hc2sgPSAnJzsKCiAgICAgICAgaWYgKCRvbmVzID0gZmxvb3IoJHByZWZpeCAvIDgpKSB7CiAgICAgICAgICAgICRtYXNrID0gc3RyX3JlcGVhdChjaHIoMjU1KSwgJG9uZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZW1haW5kZXIgPSAkcHJlZml4ICUgOCkgewogICAgICAgICAgICAkbWFzayAuPSBjaHIoMHhmZiBeICgweGZmID4+ICRyZW1haW5kZXIpKTsKICAgICAgICB9CgogICAgICAgICRtYXNrID0gc3RyX3BhZCgkbWFzaywgJHNpemUsIGNocigwKSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+aXBNYXBUbzYoJG1hc2ssICRzaXplKTsKICAgIH0KCiAgICAvKioKICAgICAqIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIG5ldHdvcmsgYW5kIG1hc2sKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyYW5nZUlwIElQIGluX2FkZHIKICAgICAqIEBwYXJhbSBpbnQgICAgJHNpemUgICAgQnl0ZSBzaXplIG9mIGluX2FkZHIKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZWZpeCAgQ0lEUiBwcmVmaXgtbGVuZ3RoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXSBuZXR3b3JrIGluX2FkZHIsIGJpbmFyeSBtYXNrCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXBHZXROZXR3b3JrKCRyYW5nZUlwLCAkc2l6ZSwgJHByZWZpeCkKICAgIHsKICAgICAgICAkbmV0bWFzayA9ICR0aGlzLT5pcEdldE1hc2soJHByZWZpeCwgJHNpemUpOwoKICAgICAgICAvLyBHZXQgdGhlIG5ldHdvcmsgZnJvbSB0aGUgYWRkcmVzcyBhbmQgbWFzawogICAgICAgICRtYXNrID0gdW5wYWNrKCdDKicsICRuZXRtYXNrKTsKICAgICAgICAkaXAgPSB1bnBhY2soJ0MqJywgJHJhbmdlSXApOwogICAgICAgICRuZXQgPSAnJzsKCiAgICAgICAgZm9yICgkaSA9IDE7ICRpIDwgMTc7ICsrJGkpIHsKICAgICAgICAgICAgJG5ldCAuPSBjaHIoJGlwWyRpXSAmICRtYXNrWyRpXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJG5ldCwgJG5ldG1hc2spOwogICAgfQoKICAgIC8qKgogICAgICogTWFwcyBhbiBJUHY0IGFkZHJlc3MgdG8gSVB2NgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJpbmFyeSBpbl9hZGRyCiAgICAgKiBAcGFyYW0gaW50ICAgICRzaXplICAgQnl0ZSBzaXplIG9mIGluX2FkZHIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBNYXBwZWQgb3IgZXhpc3RpbmcgaW5fYWRkcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlwTWFwVG82KCRiaW5hcnksICRzaXplKQogICAgewogICAgICAgIGlmICgkc2l6ZSA9PT0gNCkgewogICAgICAgICAgICAkcHJlZml4ID0gc3RyX3JlcGVhdChjaHIoMCksIDEwKSAuIHN0cl9yZXBlYXQoY2hyKDI1NSksIDIpOwogICAgICAgICAgICAkYmluYXJ5ID0gJHByZWZpeCAuICRiaW5hcnk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGJpbmFyeTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBydWxlIGRhdGEgb2JqZWN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgJGhvc3QKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICRwb3J0CiAgICAgKiBAcGFyYW0gbnVsbHxzdGRjbGFzcyAkaXBkYXRhCiAgICAgKgogICAgICogQHJldHVybiBzdGRjbGFzcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1ha2VEYXRhKCRob3N0LCAkcG9ydCwgJGlwZGF0YSkKICAgIHsKICAgICAgICByZXR1cm4gKG9iamVjdCkgYXJyYXkoCiAgICAgICAgICAgICdob3N0JyA9PiAkaG9zdCwKICAgICAgICAgICAgJ25hbWUnID0+ICcuJyAuIGx0cmltKCRob3N0LCAnLicpLAogICAgICAgICAgICAncG9ydCcgPT4gJHBvcnQsCiAgICAgICAgICAgICdpcGRhdGEnID0+ICRpcGRhdGEsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gaXAgZGF0YSBvYmplY3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGlwICAgICAgaW5fYWRkcgogICAgICogQHBhcmFtIGludCAgICAgICAgICRzaXplICAgIEJ5dGUgc2l6ZSBvZiBpbl9hZGRyCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJG5ldG1hc2sgTmV0d29yayBtYXNrCiAgICAgKgogICAgICogQHJldHVybiBzdGRjbGFzcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1ha2VJcERhdGEoJGlwLCAkc2l6ZSwgJG5ldG1hc2spCiAgICB7CiAgICAgICAgcmV0dXJuIChvYmplY3QpIGFycmF5KAogICAgICAgICAgICAnaXAnID0+ICRpcCwKICAgICAgICAgICAgJ3NpemUnID0+ICRzaXplLAogICAgICAgICAgICAnbmV0bWFzaycgPT4gJG5ldG1hc2ssCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNwbGl0cyB0aGUgaG9zdG5hbWUgaW50byBob3N0IGFuZCBwb3J0IGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRob3N0TmFtZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWRbXSBob3N0LCBwb3J0LCBpZiB0aGVyZSB3YXMgZXJyb3IKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzcGxpdEhvc3RQb3J0KCRob3N0TmFtZSkKICAgIHsKICAgICAgICAvLyBob3N0LCBwb3J0LCBlcnIKICAgICAgICAkZXJyb3IgPSBhcnJheSgnJywgJycsIHRydWUpOwogICAgICAgICRwb3J0ID0gMDsKICAgICAgICAkaXA2ID0gJyc7CgogICAgICAgIC8vIENoZWNrIGZvciBzcXVhcmUtYnJhY2tldCBub3RhdGlvbgogICAgICAgIGlmICgkaG9zdE5hbWVbMF0gPT09ICdbJykgewogICAgICAgICAgICAkaW5kZXggPSBzdHJwb3MoJGhvc3ROYW1lLCAnXScpOwoKICAgICAgICAgICAgLy8gVGhlIHNtYWxsZXN0IGlwNiBhZGRyZXNzIGlzIDo6CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGluZGV4IHx8ICRpbmRleCA8IDMpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZXJyb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpcDYgPSBzdWJzdHIoJGhvc3ROYW1lLCAxLCAkaW5kZXggLSAxKTsKICAgICAgICAgICAgJGhvc3ROYW1lID0gc3Vic3RyKCRob3N0TmFtZSwgJGluZGV4ICsgMSk7CgogICAgICAgICAgICBpZiAoc3RycGJyaygkaG9zdE5hbWUsICdbXScpICE9PSBmYWxzZSB8fCBzdWJzdHJfY291bnQoJGhvc3ROYW1lLCAnOicpID4gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHN1YnN0cl9jb3VudCgkaG9zdE5hbWUsICc6JykgPT09IDEpIHsKICAgICAgICAgICAgJGluZGV4ID0gc3RycG9zKCRob3N0TmFtZSwgJzonKTsKICAgICAgICAgICAgJHBvcnQgPSBzdWJzdHIoJGhvc3ROYW1lLCAkaW5kZXggKyAxKTsKICAgICAgICAgICAgJGhvc3ROYW1lID0gc3Vic3RyKCRob3N0TmFtZSwgMCwgJGluZGV4KTsKCiAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlSW50KCRwb3J0LCAxLCA2NTUzNSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZXJyb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwb3J0ID0gKGludCkgJHBvcnQ7CiAgICAgICAgfQoKICAgICAgICAkaG9zdCA9ICRpcDYgLiAkaG9zdE5hbWU7CgogICAgICAgIHJldHVybiBhcnJheSgkaG9zdCwgJHBvcnQsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdyYXBwZXIgYXJvdW5kIGZpbHRlcl92YXIgRklMVEVSX1ZBTElEQVRFX0lOVAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGludAogICAgICogQHBhcmFtIGludCAgICAkbWluCiAgICAgKiBAcGFyYW0gaW50ICAgICRtYXgKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZUludCgkaW50LCAkbWluLCAkbWF4KQogICAgewogICAgICAgICRvcHRpb25zID0gYXJyYXkoCiAgICAgICAgICAgICdvcHRpb25zJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICdtaW5fcmFuZ2UnID0+ICRtaW4sCiAgICAgICAgICAgICAgICAnbWF4X3JhbmdlJyA9PiAkbWF4LAogICAgICAgICAgICApLAogICAgICAgICk7CgogICAgICAgIHJldHVybiBmYWxzZSAhPT0gZmlsdGVyX3ZhcigkaW50LCBGSUxURVJfVkFMSURBVEVfSU5ULCAkb3B0aW9ucyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxJT0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgRmlsZXN5c3RlbQp7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByaXZhdGUgJHByb2Nlc3NFeGVjdXRvcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUHJvY2Vzc0V4ZWN1dG9yICRleGVjdXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvciA9ICRleGVjdXRvcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCRmaWxlKQogICAgewogICAgICAgIGlmIChpc19kaXIoJGZpbGUpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlRGlyZWN0b3J5KCRmaWxlKTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT51bmxpbmsoJGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGEgZGlyZWN0b3J5IGlzIGVtcHR5CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGRpcgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RpckVtcHR5KCRkaXIpCiAgICB7CiAgICAgICAgJGZpbmRlciA9IEZpbmRlcjo6Y3JlYXRlKCkKICAgICAgICAgICAgLT5pZ25vcmVWQ1MoZmFsc2UpCiAgICAgICAgICAgIC0+aWdub3JlRG90RmlsZXMoZmFsc2UpCiAgICAgICAgICAgIC0+ZGVwdGgoMCkKICAgICAgICAgICAgLT5pbigkZGlyKTsKCiAgICAgICAgcmV0dXJuIFxjb3VudCgkZmluZGVyKSA9PT0gMDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZW1wdHlEaXJlY3RvcnkoJGRpciwgJGVuc3VyZURpcmVjdG9yeUV4aXN0cyA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKGlzX2xpbmsoJGRpcikgJiYgZmlsZV9leGlzdHMoJGRpcikpIHsKICAgICAgICAgICAgJHRoaXMtPnVubGluaygkZGlyKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZW5zdXJlRGlyZWN0b3J5RXhpc3RzKSB7CiAgICAgICAgICAgICR0aGlzLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJGRpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfZGlyKCRkaXIpKSB7CiAgICAgICAgICAgICRmaW5kZXIgPSBGaW5kZXI6OmNyZWF0ZSgpCiAgICAgICAgICAgICAgICAtPmlnbm9yZVZDUyhmYWxzZSkKICAgICAgICAgICAgICAgIC0+aWdub3JlRG90RmlsZXMoZmFsc2UpCiAgICAgICAgICAgICAgICAtPmRlcHRoKDApCiAgICAgICAgICAgICAgICAtPmluKCRkaXIpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgoc3RyaW5nKSAkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSByZW1vdmUgYSBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBVc2VzIHRoZSBwcm9jZXNzIGNvbXBvbmVudCBpZiBwcm9jX29wZW4gaXMgZW5hYmxlZCBvbiB0aGUgUEhQCiAgICAgKiBpbnN0YWxsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkZGlyZWN0b3J5CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZURpcmVjdG9yeSgkZGlyZWN0b3J5KQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNTeW1saW5rZWREaXJlY3RvcnkoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT51bmxpbmtTeW1saW5rZWREaXJlY3RvcnkoJGRpcmVjdG9yeSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmlzSnVuY3Rpb24oJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVKdW5jdGlvbigkZGlyZWN0b3J5KTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19saW5rKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiB1bmxpbmsoJGRpcmVjdG9yeSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWlzX2RpcigkZGlyZWN0b3J5KSB8fCAhZmlsZV9leGlzdHMoJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oPzpbYS16XTopP1svXFxcXF0rJH1pJywgJGRpcmVjdG9yeSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdBYm9ydGluZyBhbiBhdHRlbXB0ZWQgZGVsZXRpb24gb2YgJy4kZGlyZWN0b3J5LicsIHRoaXMgd2FzIHByb2JhYmx5IG5vdCBpbnRlbmRlZCwgaWYgaXQgaXMgYSByZWFsIHVzZSBjYXNlIHBsZWFzZSByZXBvcnQgaXQuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVxmdW5jdGlvbl9leGlzdHMoJ3Byb2Nfb3BlbicpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlRGlyZWN0b3J5UGhwKCRkaXJlY3RvcnkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAkY21kID0gc3ByaW50Zigncm1kaXIgL1MgL1EgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShyZWFscGF0aCgkZGlyZWN0b3J5KSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjbWQgPSBzcHJpbnRmKCdybSAtcmYgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZGlyZWN0b3J5KSk7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmdldFByb2Nlc3MoKS0+ZXhlY3V0ZSgkY21kLCAkb3V0cHV0KSA9PT0gMDsKCiAgICAgICAgLy8gY2xlYXIgc3RhdCBjYWNoZSBiZWNhdXNlIGV4dGVybmFsIHByb2Nlc3NlcyBhcmVuJ3QgdHJhY2tlZCBieSB0aGUgcGhwIHN0YXQgY2FjaGUKICAgICAgICBjbGVhcnN0YXRjYWNoZSgpOwoKICAgICAgICBpZiAoJHJlc3VsdCAmJiAhaXNfZGlyKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVEaXJlY3RvcnlQaHAoJGRpcmVjdG9yeSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSBkZWxldGUgZGlyZWN0b3J5IHVzaW5nIFBIUCBpdGVyYXRvcnMuCiAgICAgKgogICAgICogVXNlcyBhIENISUxEX0ZJUlNUIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IgdG8gc29ydCBmaWxlcwogICAgICogYmVmb3JlIGRpcmVjdG9yaWVzLCBjcmVhdGluZyBhIHNpbmdsZSBub24tcmVjdXJzaXZlIGxvb3AKICAgICAqIHRvIGRlbGV0ZSBmaWxlcy9kaXJlY3RvcmllcyBpbiB0aGUgY29ycmVjdCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkZGlyZWN0b3J5CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZURpcmVjdG9yeVBocCgkZGlyZWN0b3J5KQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRpdCA9IG5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkZGlyZWN0b3J5LCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTKTsKICAgICAgICB9IGNhdGNoIChcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIC8vIHJlLXRyeSBvbmNlIGFmdGVyIGNsZWFyaW5nIHRoZSBzdGF0IGNhY2hlIGlmIGl0IGZhaWxlZCBhcyBpdAogICAgICAgICAgICAvLyBzb21ldGltZXMgZmFpbHMgd2l0aG91dCBhcHBhcmVudCByZWFzb24sIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzQwMDkKICAgICAgICAgICAgY2xlYXJzdGF0Y2FjaGUoKTsKICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaXQgPSBuZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJGRpcmVjdG9yeSwgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUyk7CiAgICAgICAgfQogICAgICAgICRyaSA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKCRpdCwgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6Q0hJTERfRklSU1QpOwoKICAgICAgICBmb3JlYWNoICgkcmkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKCRmaWxlLT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cm1kaXIoJGZpbGUtPmdldFBhdGhuYW1lKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnVubGluaygkZmlsZS0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cm1kaXIoJGRpcmVjdG9yeSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGVuc3VyZURpcmVjdG9yeUV4aXN0cygkZGlyZWN0b3J5KQogICAgewogICAgICAgIGlmICghaXNfZGlyKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZGlyZWN0b3J5KSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICRkaXJlY3RvcnkuJyBleGlzdHMgYW5kIGlzIG5vdCBhIGRpcmVjdG9yeS4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghQG1rZGlyKCRkaXJlY3RvcnksIDA3NzcsIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJGRpcmVjdG9yeS4nIGRvZXMgbm90IGV4aXN0IGFuZCBjb3VsZCBub3QgYmUgY3JlYXRlZC4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQXR0ZW1wdHMgdG8gdW5saW5rIGEgZmlsZSBhbmQgaW4gY2FzZSBvZiBmYWlsdXJlIHJldHJpZXMgYWZ0ZXIgMzUwbXMgb24gd2luZG93cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGgKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5saW5rKCRwYXRoKQogICAgewogICAgICAgICR1bmxpbmtlZCA9IEAkdGhpcy0+dW5saW5rSW1wbGVtZW50YXRpb24oJHBhdGgpOwogICAgICAgIGlmICghJHVubGlua2VkKSB7CiAgICAgICAgICAgIC8vIHJldHJ5IGFmdGVyIGEgYml0IG9uIHdpbmRvd3Mgc2luY2UgaXQgdGVuZHMgdG8gYmUgdG91Y2h5IHdpdGggbWFzcyByZW1vdmFscwogICAgICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICB1c2xlZXAoMzUwMDAwKTsKICAgICAgICAgICAgICAgICR1bmxpbmtlZCA9IEAkdGhpcy0+dW5saW5rSW1wbGVtZW50YXRpb24oJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISR1bmxpbmtlZCkgewogICAgICAgICAgICAgICAgJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0NvdWxkIG5vdCBkZWxldGUgJy4kcGF0aC4nOiAnIC4gQCRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblRoaXMgY2FuIGJlIGR1ZSB0byBhbiBhbnRpdmlydXMgb3IgdGhlIFdpbmRvd3MgU2VhcmNoIEluZGV4ZXIgbG9ja2luZyB0aGUgZmlsZSB3aGlsZSB0aGV5IGFyZSBhbmFseXplZCI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRtZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBybWRpciBhIGZpbGUgYW5kIGluIGNhc2Ugb2YgZmFpbHVyZSByZXRyaWVzIGFmdGVyIDM1MG1zIG9uIHdpbmRvd3MKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJtZGlyKCRwYXRoKQogICAgewogICAgICAgICRkZWxldGVkID0gQHJtZGlyKCRwYXRoKTsKICAgICAgICBpZiAoISRkZWxldGVkKSB7CiAgICAgICAgICAgIC8vIHJldHJ5IGFmdGVyIGEgYml0IG9uIHdpbmRvd3Mgc2luY2UgaXQgdGVuZHMgdG8gYmUgdG91Y2h5IHdpdGggbWFzcyByZW1vdmFscwogICAgICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICB1c2xlZXAoMzUwMDAwKTsKICAgICAgICAgICAgICAgICRkZWxldGVkID0gQHJtZGlyKCRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkZGVsZXRlZCkgewogICAgICAgICAgICAgICAgJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0NvdWxkIG5vdCBkZWxldGUgJy4kcGF0aC4nOiAnIC4gQCRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblRoaXMgY2FuIGJlIGR1ZSB0byBhbiBhbnRpdmlydXMgb3IgdGhlIFdpbmRvd3MgU2VhcmNoIEluZGV4ZXIgbG9ja2luZyB0aGUgZmlsZSB3aGlsZSB0aGV5IGFyZSBhbmFseXplZCI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRtZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IHRoZW4gZGVsZXRlIGlzIGEgbm9uLWF0b21pYyB2ZXJzaW9uIG9mIHtAbGluayByZW5hbWV9LgogICAgICoKICAgICAqIFNvbWUgc3lzdGVtcyBjYW4ndCByZW5hbWUgYW5kIGFsc28gZG9uJ3QgaGF2ZSBwcm9jX29wZW4sCiAgICAgKiB3aGljaCByZXF1aXJlcyB0aGlzIHNvbHV0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5VGhlblJlbW92ZSgkc291cmNlLCAkdGFyZ2V0KQogICAgewogICAgICAgICR0aGlzLT5jb3B5KCRzb3VyY2UsICR0YXJnZXQpOwogICAgICAgIGlmICghaXNfZGlyKCRzb3VyY2UpKSB7CiAgICAgICAgICAgICR0aGlzLT51bmxpbmsoJHNvdXJjZSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVtb3ZlRGlyZWN0b3J5UGhwKCRzb3VyY2UpOwogICAgfQoKICAgIC8qKgogICAgICogQ29waWVzIGEgZmlsZSBvciBkaXJlY3RvcnkgZnJvbSAkc291cmNlIHRvICR0YXJnZXQuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHNvdXJjZQogICAgICogQHBhcmFtICBzdHJpbmcgJHRhcmdldAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5KCRzb3VyY2UsICR0YXJnZXQpCiAgICB7CiAgICAgICAgaWYgKCFpc19kaXIoJHNvdXJjZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGNvcHkoJHNvdXJjZSwgJHRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICAkaXQgPSBuZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJHNvdXJjZSwgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OlNLSVBfRE9UUyk7CiAgICAgICAgJHJpID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoJGl0LCBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpTRUxGX0ZJUlNUKTsKICAgICAgICAkdGhpcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0YXJnZXQpOwoKICAgICAgICAkcmVzdWx0ID0gdHJ1ZTsKICAgICAgICAvKiogQHZhciBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvciAkcmkgKi8KICAgICAgICBmb3JlYWNoICgkcmkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJHRhcmdldFBhdGggPSAkdGFyZ2V0IC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRyaS0+Z2V0U3ViUGF0aG5hbWUoKTsKICAgICAgICAgICAgaWYgKCRmaWxlLT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0YXJnZXRQYXRoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkcmVzdWx0ICYmIGNvcHkoJGZpbGUtPmdldFBhdGhuYW1lKCksICR0YXJnZXRQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbmFtZSgkc291cmNlLCAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICh0cnVlID09PSBAcmVuYW1lKCRzb3VyY2UsICR0YXJnZXQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghXGZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvcHlUaGVuUmVtb3ZlKCRzb3VyY2UsICR0YXJnZXQpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAvLyBUcnkgdG8gY29weSAmIGRlbGV0ZSAtIHRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciByYW5kb20gIkFjY2VzcyBkZW5pZWQiIGVycm9ycy4KICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCd4Y29weSAlcyAlcyAvRSAvSSAvUSAvWScsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRzb3VyY2UpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGFyZ2V0KSk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Z2V0UHJvY2VzcygpLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0KTsKCiAgICAgICAgICAgIC8vIGNsZWFyIHN0YXQgY2FjaGUgYmVjYXVzZSBleHRlcm5hbCBwcm9jZXNzZXMgYXJlbid0IHRyYWNrZWQgYnkgdGhlIHBocCBzdGF0IGNhY2hlCiAgICAgICAgICAgIGNsZWFyc3RhdGNhY2hlKCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkc291cmNlKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBXZSBkbyBub3QgdXNlIFBIUCdzICJyZW5hbWUiIGZ1bmN0aW9uIGhlcmUgc2luY2UgaXQgZG9lcyBub3Qgc3VwcG9ydAogICAgICAgICAgICAvLyB0aGUgY2FzZSB3aGVyZSAkc291cmNlLCBhbmQgJHRhcmdldCBhcmUgbG9jYXRlZCBvbiBkaWZmZXJlbnQgcGFydGl0aW9ucy4KICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdtdiAlcyAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRzb3VyY2UpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGFyZ2V0KSk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Z2V0UHJvY2VzcygpLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0KTsKCiAgICAgICAgICAgIC8vIGNsZWFyIHN0YXQgY2FjaGUgYmVjYXVzZSBleHRlcm5hbCBwcm9jZXNzZXMgYXJlbid0IHRyYWNrZWQgYnkgdGhlIHBocCBzdGF0IGNhY2hlCiAgICAgICAgICAgIGNsZWFyc3RhdGNhY2hlKCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29weVRoZW5SZW1vdmUoJHNvdXJjZSwgJHRhcmdldCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzaG9ydGVzdCBwYXRoIGZyb20gJGZyb20gdG8gJHRvCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRmcm9tCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHRvCiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAgICAgICAgICAgJGRpcmVjdG9yaWVzIGlmIHRydWUsIHRoZSBzb3VyY2UvdGFyZ2V0IGFyZSBjb25zaWRlcmVkIHRvIGJlIGRpcmVjdG9yaWVzCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kU2hvcnRlc3RQYXRoKCRmcm9tLCAkdG8sICRkaXJlY3RvcmllcyA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlzQWJzb2x1dGVQYXRoKCRmcm9tKSB8fCAhJHRoaXMtPmlzQWJzb2x1dGVQYXRoKCR0bykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignJGZyb20gKCVzKSBhbmQgJHRvICglcykgbXVzdCBiZSBhYnNvbHV0ZSBwYXRocy4nLCAkZnJvbSwgJHRvKSk7CiAgICAgICAgfQoKICAgICAgICAkZnJvbSA9IGxjZmlyc3QoJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJGZyb20pKTsKICAgICAgICAkdG8gPSBsY2ZpcnN0KCR0aGlzLT5ub3JtYWxpemVQYXRoKCR0bykpOwoKICAgICAgICBpZiAoJGRpcmVjdG9yaWVzKSB7CiAgICAgICAgICAgICRmcm9tID0gcnRyaW0oJGZyb20sICcvJykgLiAnL2R1bW15X2ZpbGUnOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxkaXJuYW1lKCRmcm9tKSA9PT0gXGRpcm5hbWUoJHRvKSkgewogICAgICAgICAgICByZXR1cm4gJy4vJy5iYXNlbmFtZSgkdG8pOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSAkdG87CiAgICAgICAgd2hpbGUgKHN0cnBvcygkZnJvbS4nLycsICRjb21tb25QYXRoLicvJykgIT09IDAgJiYgJy8nICE9PSAkY29tbW9uUGF0aCAmJiAhcHJlZ19tYXRjaCgne15bYS16XTovPyR9aScsICRjb21tb25QYXRoKSkgewogICAgICAgICAgICAkY29tbW9uUGF0aCA9IHN0cnRyKFxkaXJuYW1lKCRjb21tb25QYXRoKSwgJ1xcJywgJy8nKTsKICAgICAgICB9CgogICAgICAgIGlmICgwICE9PSBzdHJwb3MoJGZyb20sICRjb21tb25QYXRoKSB8fCAnLycgPT09ICRjb21tb25QYXRoKSB7CiAgICAgICAgICAgIHJldHVybiAkdG87CiAgICAgICAgfQoKICAgICAgICAkY29tbW9uUGF0aCA9IHJ0cmltKCRjb21tb25QYXRoLCAnLycpIC4gJy8nOwogICAgICAgICRzb3VyY2VQYXRoRGVwdGggPSBzdWJzdHJfY291bnQoc3Vic3RyKCRmcm9tLCBcc3RybGVuKCRjb21tb25QYXRoKSksICcvJyk7CiAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gc3RyX3JlcGVhdCgnLi4vJywgJHNvdXJjZVBhdGhEZXB0aCk7CgogICAgICAgIHJldHVybiAoJGNvbW1vblBhdGhDb2RlIC4gc3Vic3RyKCR0bywgXHN0cmxlbigkY29tbW9uUGF0aCkpKSA/OiAnLi8nOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBQSFAgY29kZSB0aGF0LCB3aGVuIGV4ZWN1dGVkIGluICRmcm9tLCB3aWxsIHJldHVybiB0aGUgcGF0aCB0byAkdG8KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJGZyb20KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkdG8KICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAkZGlyZWN0b3JpZXMgaWYgdHJ1ZSwgdGhlIHNvdXJjZS90YXJnZXQgYXJlIGNvbnNpZGVyZWQgdG8gYmUgZGlyZWN0b3JpZXMKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAkc3RhdGljQ29kZQogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZFNob3J0ZXN0UGF0aENvZGUoJGZyb20sICR0bywgJGRpcmVjdG9yaWVzID0gZmFsc2UsICRzdGF0aWNDb2RlID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJGZyb20pIHx8ICEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJHRvKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCckZnJvbSAoJXMpIGFuZCAkdG8gKCVzKSBtdXN0IGJlIGFic29sdXRlIHBhdGhzLicsICRmcm9tLCAkdG8pKTsKICAgICAgICB9CgogICAgICAgICRmcm9tID0gbGNmaXJzdCgkdGhpcy0+bm9ybWFsaXplUGF0aCgkZnJvbSkpOwogICAgICAgICR0byA9IGxjZmlyc3QoJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHRvKSk7CgogICAgICAgIGlmICgkZnJvbSA9PT0gJHRvKSB7CiAgICAgICAgICAgIHJldHVybiAkZGlyZWN0b3JpZXMgPyAnX19ESVJfXycgOiAnX19GSUxFX18nOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSAkdG87CiAgICAgICAgd2hpbGUgKHN0cnBvcygkZnJvbS4nLycsICRjb21tb25QYXRoLicvJykgIT09IDAgJiYgJy8nICE9PSAkY29tbW9uUGF0aCAmJiAhcHJlZ19tYXRjaCgne15bYS16XTovPyR9aScsICRjb21tb25QYXRoKSAmJiAnLicgIT09ICRjb21tb25QYXRoKSB7CiAgICAgICAgICAgICRjb21tb25QYXRoID0gc3RydHIoXGRpcm5hbWUoJGNvbW1vblBhdGgpLCAnXFwnLCAnLycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKDAgIT09IHN0cnBvcygkZnJvbSwgJGNvbW1vblBhdGgpIHx8ICcvJyA9PT0gJGNvbW1vblBhdGggfHwgJy4nID09PSAkY29tbW9uUGF0aCkgewogICAgICAgICAgICByZXR1cm4gdmFyX2V4cG9ydCgkdG8sIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vblBhdGggPSBydHJpbSgkY29tbW9uUGF0aCwgJy8nKSAuICcvJzsKICAgICAgICBpZiAoc3RycG9zKCR0bywgJGZyb20uJy8nKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gJ19fRElSX18gLiAnLnZhcl9leHBvcnQoc3Vic3RyKCR0bywgXHN0cmxlbigkZnJvbSkpLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgJHNvdXJjZVBhdGhEZXB0aCA9IHN1YnN0cl9jb3VudChzdWJzdHIoJGZyb20sIFxzdHJsZW4oJGNvbW1vblBhdGgpKSwgJy8nKSArICRkaXJlY3RvcmllczsKICAgICAgICBpZiAoJHN0YXRpY0NvZGUpIHsKICAgICAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gIl9fRElSX18gLiAnIi5zdHJfcmVwZWF0KCcvLi4nLCAkc291cmNlUGF0aERlcHRoKS4iJyI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNvbW1vblBhdGhDb2RlID0gc3RyX3JlcGVhdCgnZGlybmFtZSgnLCAkc291cmNlUGF0aERlcHRoKS4nX19ESVJfXycuc3RyX3JlcGVhdCgnKScsICRzb3VyY2VQYXRoRGVwdGgpOwogICAgICAgIH0KICAgICAgICAkcmVsVGFyZ2V0ID0gc3Vic3RyKCR0bywgXHN0cmxlbigkY29tbW9uUGF0aCkpOwoKICAgICAgICByZXR1cm4gJGNvbW1vblBhdGhDb2RlIC4gKFxzdHJsZW4oJHJlbFRhcmdldCkgPyAnLicgLiB2YXJfZXhwb3J0KCcvJyAuICRyZWxUYXJnZXQsIHRydWUpIDogJycpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBwYXRoIGlzIGFic29sdXRlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBYnNvbHV0ZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0cnBvcygkcGF0aCwgJy8nKSA9PT0gMCB8fCBzdWJzdHIoJHBhdGgsIDEsIDEpID09PSAnOicgfHwgc3RycG9zKCRwYXRoLCAnXFxcXCcpID09PSAwOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBzaXplIG9mIGEgZmlsZSBvciBkaXJlY3Rvcnkgc3BlY2lmaWVkIGJ5IHBhdGguIElmIGEgZGlyZWN0b3J5IGlzCiAgICAgKiBnaXZlbiwgaXQncyBzaXplIHdpbGwgYmUgY29tcHV0ZWQgcmVjdXJzaXZlbHkuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkcGF0aCBQYXRoIHRvIHRoZSBmaWxlIG9yIGRpcmVjdG9yeQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNpemUoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCIkcGF0aCBkb2VzIG5vdCBleGlzdC4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5kaXJlY3RvcnlTaXplKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmaWxlc2l6ZSgkcGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWxpemUgYSBwYXRoLiBUaGlzIHJlcGxhY2VzIGJhY2tzbGFzaGVzIHdpdGggc2xhc2hlcywgcmVtb3ZlcyBlbmRpbmcKICAgICAqIHNsYXNoIGFuZCBjb2xsYXBzZXMgcmVkdW5kYW50IHNlcGFyYXRvcnMgYW5kIHVwLWxldmVsIHJlZmVyZW5jZXMuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGggUGF0aCB0byB0aGUgZmlsZSBvciBkaXJlY3RvcnkKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemVQYXRoKCRwYXRoKQogICAgewogICAgICAgICRwYXJ0cyA9IGFycmF5KCk7CiAgICAgICAgJHBhdGggPSBzdHJ0cigkcGF0aCwgJ1xcJywgJy8nKTsKICAgICAgICAkcHJlZml4ID0gJyc7CiAgICAgICAgJGFic29sdXRlID0gZmFsc2U7CgogICAgICAgIC8vIGV4dHJhY3QgYSBwcmVmaXggYmVpbmcgYSBwcm90b2NvbDovLywgcHJvdG9jb2w6LCBwcm90b2NvbDovL2RyaXZlOiBvciBzaW1wbHkgZHJpdmU6CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKCBbMC05YS16XXsyLH0rOiAoPzogLy8gKD86IFthLXpdOiApPyApPyB8IFthLXpdOiApfWl4JywgJHBhdGgsICRtYXRjaCkpIHsKICAgICAgICAgICAgJHByZWZpeCA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgJHBhdGggPSBzdWJzdHIoJHBhdGgsIFxzdHJsZW4oJHByZWZpeCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkcGF0aCwgJy8nKSA9PT0gMCkgewogICAgICAgICAgICAkYWJzb2x1dGUgPSB0cnVlOwogICAgICAgICAgICAkcGF0aCA9IHN1YnN0cigkcGF0aCwgMSk7CiAgICAgICAgfQoKICAgICAgICAkdXAgPSBmYWxzZTsKICAgICAgICBmb3JlYWNoIChleHBsb2RlKCcvJywgJHBhdGgpIGFzICRjaHVuaykgewogICAgICAgICAgICBpZiAoJy4uJyA9PT0gJGNodW5rICYmICgkYWJzb2x1dGUgfHwgJHVwKSkgewogICAgICAgICAgICAgICAgYXJyYXlfcG9wKCRwYXJ0cyk7CiAgICAgICAgICAgICAgICAkdXAgPSAhKGVtcHR5KCRwYXJ0cykgfHwgJy4uJyA9PT0gZW5kKCRwYXJ0cykpOwogICAgICAgICAgICB9IGVsc2VpZiAoJy4nICE9PSAkY2h1bmsgJiYgJycgIT09ICRjaHVuaykgewogICAgICAgICAgICAgICAgJHBhcnRzW10gPSAkY2h1bms7CiAgICAgICAgICAgICAgICAkdXAgPSAnLi4nICE9PSAkY2h1bms7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJlZml4LigkYWJzb2x1dGUgPyAnLycgOiAnJykuaW1wbG9kZSgnLycsICRwYXJ0cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmUgdHJhaWxpbmcgc2xhc2hlcyBpZiBwcmVzZW50IHRvIGF2b2lkIGlzc3VlcyB3aXRoIHN5bWxpbmtzCiAgICAgKgogICAgICogQW5kIG90aGVyIHBvc3NpYmxlIHVuZm9yZXNlZW4gZGlzYXN0ZXJzLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvOTQyMgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRwYXRoCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0cmltVHJhaWxpbmdTbGFzaCgkcGF0aCkKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3teWy9cXFxcXSskfScsICRwYXRoKSkgewogICAgICAgICAgICAkcGF0aCA9IHJ0cmltKCRwYXRoLCAnL1xcJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gaWYgdGhlIGdpdmVuIHBhdGggaXMgbG9jYWwKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNMb2NhbFBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIChib29sKSBwcmVnX21hdGNoKCd7XihmaWxlOi8vKD8hLy8pfC8oPyEvKXwvP1thLXpdOltcXFxcL118XC5cLltcXFxcL118W2EtejAtOV8uLV0rW1xcXFwvXSl9aScsICRwYXRoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsYXRmb3JtUGF0aCgkcGF0aCkKICAgIHsKICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICRwYXRoID0gcHJlZ19yZXBsYWNlKCd7Xig/OmZpbGU6Ly8vKFthLXpdKTo/Lyl9aScsICdmaWxlOi8vJDE6LycsICRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2UoJ3teZmlsZTovL31pJywgJycsICRwYXRoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGlyZWN0b3J5U2l6ZSgkZGlyZWN0b3J5KQogICAgewogICAgICAgICRpdCA9IG5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkZGlyZWN0b3J5LCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTKTsKICAgICAgICAkcmkgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigkaXQsIFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUKTsKCiAgICAgICAgJHNpemUgPSAwOwogICAgICAgIGZvcmVhY2ggKCRyaSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoJGZpbGUtPmlzRmlsZSgpKSB7CiAgICAgICAgICAgICAgICAkc2l6ZSArPSAkZmlsZS0+Z2V0U2l6ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNpemU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFByb2Nlc3NFeGVjdXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UHJvY2VzcygpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzRXhlY3V0b3IgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NFeGVjdXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIGRlbGV0ZSBzeW1ib2xpYyBsaW5rIGltcGxlbWVudGF0aW9uIChjb21tb25seSBrbm93biBhcyAidW5saW5rKCkiKQogICAgICoKICAgICAqIHN5bWJvbGljIGxpbmtzIG9uIHdpbmRvd3Mgd2hpY2ggbGluayB0byBkaXJlY3RvcmllcyBuZWVkIHJtZGlyIGluc3RlYWQgb2YgdW5saW5rCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVubGlua0ltcGxlbWVudGF0aW9uKCRwYXRoKQogICAgewogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgaXNfZGlyKCRwYXRoKSAmJiBpc19saW5rKCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gcm1kaXIoJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHVubGluaygkcGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgcmVsYXRpdmUgc3ltbGluayBmcm9tICRsaW5rIHRvICR0YXJnZXQKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdGFyZ2V0IFRoZSBwYXRoIG9mIHRoZSBiaW5hcnkgZmlsZSB0byBiZSBzeW1saW5rZWQKICAgICAqIEBwYXJhbSAgc3RyaW5nICRsaW5rICAgVGhlIHBhdGggd2hlcmUgdGhlIHN5bWxpbmsgc2hvdWxkIGJlIGNyZWF0ZWQKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVsYXRpdmVTeW1saW5rKCR0YXJnZXQsICRsaW5rKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdzeW1saW5rJykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGN3ZCA9IGdldGN3ZCgpOwoKICAgICAgICAkcmVsYXRpdmVQYXRoID0gJHRoaXMtPmZpbmRTaG9ydGVzdFBhdGgoJGxpbmssICR0YXJnZXQpOwogICAgICAgIGNoZGlyKFxkaXJuYW1lKCRsaW5rKSk7CiAgICAgICAgJHJlc3VsdCA9IEBzeW1saW5rKCRyZWxhdGl2ZVBhdGgsICRsaW5rKTsKCiAgICAgICAgY2hkaXIoJGN3ZCk7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogcmV0dXJuIHRydWUgaWYgdGhhdCBkaXJlY3RvcnkgaXMgYSBzeW1saW5rLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpcmVjdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNTeW1saW5rZWREaXJlY3RvcnkoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICBpZiAoIWlzX2RpcigkZGlyZWN0b3J5KSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcmVzb2x2ZWQgPSAkdGhpcy0+cmVzb2x2ZVN5bWxpbmtlZERpcmVjdG9yeVN5bWxpbmsoJGRpcmVjdG9yeSk7CgogICAgICAgIHJldHVybiBpc19saW5rKCRyZXNvbHZlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB1bmxpbmtTeW1saW5rZWREaXJlY3RvcnkoJGRpcmVjdG9yeSkKICAgIHsKICAgICAgICAkcmVzb2x2ZWQgPSAkdGhpcy0+cmVzb2x2ZVN5bWxpbmtlZERpcmVjdG9yeVN5bWxpbmsoJGRpcmVjdG9yeSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+dW5saW5rKCRyZXNvbHZlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiByZXNvbHZlIHBhdGhuYW1lIHRvIHN5bWJvbGljIGxpbmsgb2YgYSBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRobmFtZSBkaXJlY3RvcnkgcGF0aCB0byByZXNvbHZlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVzb2x2ZWQgcGF0aCB0byBzeW1ib2xpYyBsaW5rIG9yIG9yaWdpbmFsIHBhdGhuYW1lICh1bnJlc29sdmVkKQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlc29sdmVTeW1saW5rZWREaXJlY3RvcnlTeW1saW5rKCRwYXRobmFtZSkKICAgIHsKICAgICAgICBpZiAoIWlzX2RpcigkcGF0aG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGF0aG5hbWU7CiAgICAgICAgfQoKICAgICAgICAkcmVzb2x2ZWQgPSBydHJpbSgkcGF0aG5hbWUsICcvJyk7CgogICAgICAgIGlmICghXHN0cmxlbigkcmVzb2x2ZWQpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGF0aG5hbWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc29sdmVkOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbiBOVEZTIGp1bmN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldAogICAgICogQHBhcmFtIHN0cmluZyAkanVuY3Rpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGp1bmN0aW9uKCR0YXJnZXQsICRqdW5jdGlvbikKICAgIHsKICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKHNwcmludGYoJ0Z1bmN0aW9uICVzIGlzIG5vdCBhdmFpbGFibGUgb24gbm9uLVdpbmRvd3MgcGxhdGZvcm0nLCBfX0NMQVNTX18pKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpc19kaXIoJHRhcmdldCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0Nhbm5vdCBqdW5jdGlvbiB0byAiJXMiIGFzIGl0IGlzIG5vdCBhIGRpcmVjdG9yeS4nLCAkdGFyZ2V0KSwgMCwgbnVsbCwgJHRhcmdldCk7CiAgICAgICAgfQogICAgICAgICRjbWQgPSBzcHJpbnRmKAogICAgICAgICAgICAnbWtsaW5rIC9KICVzICVzJywKICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoc3RyX3JlcGxhY2UoJy8nLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkanVuY3Rpb24pKSwKICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUocmVhbHBhdGgoJHRhcmdldCkpCiAgICAgICAgKTsKICAgICAgICBpZiAoJHRoaXMtPmdldFByb2Nlc3MoKS0+ZXhlY3V0ZSgkY21kLCAkb3V0cHV0KSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNyZWF0ZSBqdW5jdGlvbiB0byAiJXMiIGF0ICIlcyIuJywgJHRhcmdldCwgJGp1bmN0aW9uKSwgMCwgbnVsbCwgJHRhcmdldCk7CiAgICAgICAgfQogICAgICAgIGNsZWFyc3RhdGNhY2hlKHRydWUsICRqdW5jdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHRhcmdldCBkaXJlY3RvcnkgaXMgYSBXaW5kb3dzIE5URlMgSnVuY3Rpb24uCiAgICAgKgogICAgICogV2UgdGVzdCBpZiB0aGUgcGF0aCBpcyBhIGRpcmVjdG9yeSBhbmQgbm90IGFuIG9yZGluYXJ5IGxpbmssIHRoZW4gY2hlY2sKICAgICAqIHRoYXQgdGhlIG1vZGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBsc3RhdCAod2hpY2ggZ2l2ZXMgdGhlIHN0YXR1cyBvZiB0aGUKICAgICAqIGxpbmsgaXRzZWxmKSBpcyBub3QgYSBkaXJlY3RvcnksIGJ5IHJlcGxpY2F0aW5nIHRoZSBQT1NJWCBTX0lTRElSIHRlc3QuCiAgICAgKgogICAgICogVGhpcyBsb2dpYyB3b3JrcyBiZWNhdXNlIFBIUCBkb2VzIG5vdCBzZXQgdGhlIG1vZGUgdmFsdWUgZm9yIGEganVuY3Rpb24sCiAgICAgKiBzaW5jZSB0aGVyZSBpcyBubyB1bml2ZXJzYWwgZmlsZSB0eXBlIGZsYWcgZm9yIGl0LiBVbmZvcnR1bmF0ZWx5IGFuCiAgICAgKiB1bmluaXRpYWxpemVkIHZhcmlhYmxlIGluIFBIUCBwcmlvciB0byA3LjIuMTYgYW5kIDcuMy4zIG1heSBjYXVzZSBhCiAgICAgKiByYW5kb20gdmFsdWUgdG8gYmUgcmV0dXJuZWQuIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTc3NTUyCiAgICAgKgogICAgICogSWYgdGhpcyByYW5kb20gdmFsdWUgcGFzc2VzIHRoZSBTX0lTRElSIHRlc3QsIHRoZW4gYSBqdW5jdGlvbiB3aWxsIG5vdCBiZQogICAgICogZGV0ZWN0ZWQgYW5kIGEgcmVjdXJzaXZlIGRlbGV0ZSBvcGVyYXRpb24gY291bGQgbGVhZCB0byBsb3NzIG9mIGRhdGEgaW4KICAgICAqIHRoZSB0YXJnZXQgZGlyZWN0b3J5LiBOb3RlIHRoYXQgV2luZG93cyBybWRpciBjYW4gaGFuZGxlIHRoaXMgc2l0dWF0aW9uCiAgICAgKiBhbmQgd2lsbCBvbmx5IGRlbGV0ZSB0aGUganVuY3Rpb24gKGZyb20gV2luZG93cyA3IG9ud2FyZHMpLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRqdW5jdGlvbiBQYXRoIHRvIGNoZWNrLgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0p1bmN0aW9uKCRqdW5jdGlvbikKICAgIHsKICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBJbXBvcnRhbnQgdG8gY2xlYXIgYWxsIGNhY2hlcyBmaXJzdAogICAgICAgIGNsZWFyc3RhdGNhY2hlKHRydWUsICRqdW5jdGlvbik7CgogICAgICAgIGlmICghaXNfZGlyKCRqdW5jdGlvbikgfHwgaXNfbGluaygkanVuY3Rpb24pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRzdGF0ID0gbHN0YXQoJGp1bmN0aW9uKTsKCiAgICAgICAgLy8gU19JU0RJUiB0ZXN0IChTX0lGRElSIGlzIDB4NDAwMCwgU19JRk1UIGlzIDB4RjAwMCBiaXRtYXNrKQogICAgICAgIHJldHVybiAkc3RhdCA/IDB4NDAwMCAhPT0gKCRzdGF0Wydtb2RlJ10gJiAweEYwMDApIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGEgV2luZG93cyBOVEZTIGp1bmN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRqdW5jdGlvbgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVKdW5jdGlvbigkanVuY3Rpb24pCiAgICB7CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAkanVuY3Rpb24gPSBydHJpbShzdHJfcmVwbGFjZSgnLycsIERJUkVDVE9SWV9TRVBBUkFUT1IsICRqdW5jdGlvbiksIERJUkVDVE9SWV9TRVBBUkFUT1IpOwogICAgICAgIGlmICghJHRoaXMtPmlzSnVuY3Rpb24oJGp1bmN0aW9uKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignJXMgaXMgbm90IGEganVuY3Rpb24gYW5kIHRodXMgY2Fubm90IGJlIHJlbW92ZWQgYXMgb25lJywgJGp1bmN0aW9uKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJtZGlyKCRqdW5jdGlvbik7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHBhdGgsICRjb250ZW50KQogICAgewogICAgICAgICRjdXJyZW50Q29udGVudCA9IEBmaWxlX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgaWYgKCEkY3VycmVudENvbnRlbnQgfHwgKCRjdXJyZW50Q29udGVudCAhPSAkY29udGVudCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkY29udGVudCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIENvcHkgZmlsZSB1c2luZyBzdHJlYW1fY29weV90b19zdHJlYW0gdG8gd29yayBhcm91bmQgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD02NDYzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNhZmVDb3B5KCRzb3VyY2UsICR0YXJnZXQpCiAgICB7CiAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkdGFyZ2V0KSB8fCAhZmlsZV9leGlzdHMoJHNvdXJjZSkgfHwgISR0aGlzLT5maWxlc0FyZUVxdWFsKCRzb3VyY2UsICR0YXJnZXQpKSB7CiAgICAgICAgICAgICRzb3VyY2UgPSBmb3Blbigkc291cmNlLCAncicpOwogICAgICAgICAgICAkdGFyZ2V0ID0gZm9wZW4oJHRhcmdldCwgJ3crJyk7CgogICAgICAgICAgICBzdHJlYW1fY29weV90b19zdHJlYW0oJHNvdXJjZSwgJHRhcmdldCk7CiAgICAgICAgICAgIGZjbG9zZSgkc291cmNlKTsKICAgICAgICAgICAgZmNsb3NlKCR0YXJnZXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIGNvbXBhcmUgMiBmaWxlcwogICAgICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzA2MDEyNS9jYW4taS11c2UtZmlsZS1nZXQtY29udGVudHMtdG8tY29tcGFyZS10d28tZmlsZXMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaWxlc0FyZUVxdWFsKCRhLCAkYikKICAgIHsKICAgICAgICAvLyBDaGVjayBpZiBmaWxlc2l6ZSBpcyBkaWZmZXJlbnQKICAgICAgICBpZiAoZmlsZXNpemUoJGEpICE9PSBmaWxlc2l6ZSgkYikpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgaWYgY29udGVudCBpcyBkaWZmZXJlbnQKICAgICAgICAkYWggPSBmb3BlbigkYSwgJ3JiJyk7CiAgICAgICAgJGJoID0gZm9wZW4oJGIsICdyYicpOwoKICAgICAgICAkcmVzdWx0ID0gdHJ1ZTsKICAgICAgICB3aGlsZSAoIWZlb2YoJGFoKSkgewogICAgICAgICAgICBpZiAoZnJlYWQoJGFoLCA4MTkyKSAhPSBmcmVhZCgkYmgsIDgxOTIpKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZmNsb3NlKCRhaCk7CiAgICAgICAgZmNsb3NlKCRiaCk7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CgovKioKICogQGF1dGhvciBNYXR0IFdoaXR0b20gPE1hdHQuV2hpdHRvbUB2ZXRlcmFuc3VuaXRlZC5jb20+CiAqLwpjbGFzcyBQZXJmb3JjZQp7CiAgICBwcm90ZWN0ZWQgJHBhdGg7CiAgICBwcm90ZWN0ZWQgJHA0RGVwb3Q7CiAgICBwcm90ZWN0ZWQgJHA0Q2xpZW50OwogICAgcHJvdGVjdGVkICRwNFVzZXI7CiAgICBwcm90ZWN0ZWQgJHA0UGFzc3dvcmQ7CiAgICBwcm90ZWN0ZWQgJHA0UG9ydDsKICAgIHByb3RlY3RlZCAkcDRTdHJlYW07CiAgICBwcm90ZWN0ZWQgJHA0Q2xpZW50U3BlYzsKICAgIHByb3RlY3RlZCAkcDREZXBvdFR5cGU7CiAgICBwcm90ZWN0ZWQgJHA0QnJhbmNoOwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgcHJvdGVjdGVkICR1bmlxdWVQZXJmb3JjZUNsaWVudE5hbWU7CiAgICBwcm90ZWN0ZWQgJHdpbmRvd3NGbGFnOwogICAgcHJvdGVjdGVkICRjb21tYW5kUmVzdWx0OwoKICAgIHByb3RlY3RlZCAkaW87CgogICAgcHJvdGVjdGVkICRmaWxlc3lzdGVtOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcmVwb0NvbmZpZywgJHBvcnQsICRwYXRoLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MsICRpc1dpbmRvd3MsIElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICAkdGhpcy0+d2luZG93c0ZsYWcgPSAkaXNXaW5kb3dzOwogICAgICAgICR0aGlzLT5wNFBvcnQgPSAkcG9ydDsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZVBhdGgoJHBhdGgpOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3M7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoJHJlcG9Db25maWcpOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZSgkcmVwb0NvbmZpZywgJHBvcnQsICRwYXRoLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MsIElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFBlcmZvcmNlKCRyZXBvQ29uZmlnLCAkcG9ydCwgJHBhdGgsICRwcm9jZXNzLCBQbGF0Zm9ybTo6aXNXaW5kb3dzKCksICRpbyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja1NlcnZlckV4aXN0cygkdXJsLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3NFeGVjdXRvcikKICAgIHsKICAgICAgICAkb3V0cHV0ID0gbnVsbDsKCiAgICAgICAgcmV0dXJuICAwID09PSAkcHJvY2Vzc0V4ZWN1dG9yLT5leGVjdXRlKCdwNCAtcCAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCkgLiAnIGluZm8gLXMnLCAkb3V0cHV0KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZSgkcmVwb0NvbmZpZykKICAgIHsKICAgICAgICAkdGhpcy0+dW5pcXVlUGVyZm9yY2VDbGllbnROYW1lID0gJHRoaXMtPmdlbmVyYXRlVW5pcXVlUGVyZm9yY2VDbGllbnROYW1lKCk7CiAgICAgICAgaWYgKCEkcmVwb0NvbmZpZykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkcmVwb0NvbmZpZ1sndW5pcXVlX3BlcmZvcmNlX2NsaWVudF9uYW1lJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT51bmlxdWVQZXJmb3JjZUNsaWVudE5hbWUgPSAkcmVwb0NvbmZpZ1sndW5pcXVlX3BlcmZvcmNlX2NsaWVudF9uYW1lJ107CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ2RlcG90J10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wNERlcG90ID0gJHJlcG9Db25maWdbJ2RlcG90J107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkcmVwb0NvbmZpZ1snYnJhbmNoJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5wNEJyYW5jaCA9ICRyZXBvQ29uZmlnWydicmFuY2gnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRyZXBvQ29uZmlnWydwNHVzZXInXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnA0VXNlciA9ICRyZXBvQ29uZmlnWydwNHVzZXInXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cDRVc2VyID0gJHRoaXMtPmdldFA0dmFyaWFibGUoJ1A0VVNFUicpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHJlcG9Db25maWdbJ3A0cGFzc3dvcmQnXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnA0UGFzc3dvcmQgPSAkcmVwb0NvbmZpZ1sncDRwYXNzd29yZCddOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5pdGlhbGl6ZURlcG90QW5kQnJhbmNoKCRkZXBvdCwgJGJyYW5jaCkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJGRlcG90KSkgewogICAgICAgICAgICAkdGhpcy0+cDREZXBvdCA9ICRkZXBvdDsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRicmFuY2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5wNEJyYW5jaCA9ICRicmFuY2g7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZVVuaXF1ZVBlcmZvcmNlQ2xpZW50TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGdldGhvc3RuYW1lKCkgLiAiXyIgLiB0aW1lKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXBDbGllbnRTcGVjKCkKICAgIHsKICAgICAgICAkY2xpZW50ID0gJHRoaXMtPmdldENsaWVudCgpOwogICAgICAgICR0YXNrID0gJ2NsaWVudCAtZCAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGNsaWVudCk7CiAgICAgICAgJHVzZVA0Q2xpZW50ID0gZmFsc2U7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJHRhc2ssICR1c2VQNENsaWVudCk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkY2xpZW50U3BlYyA9ICR0aGlzLT5nZXRQNENsaWVudFNwZWMoKTsKICAgICAgICAkZmlsZVN5c3RlbSA9ICR0aGlzLT5nZXRGaWxlc3lzdGVtKCk7CiAgICAgICAgJGZpbGVTeXN0ZW0tPnJlbW92ZSgkY2xpZW50U3BlYyk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kUmVzdWx0ID0gJyc7CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJHRoaXMtPmNvbW1hbmRSZXN1bHQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDbGllbnQoKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnA0Q2xpZW50KSkgewogICAgICAgICAgICAkY2xlYW5TdHJlYW1OYW1lID0gc3RyX3JlcGxhY2UoYXJyYXkoJy8vJywgJy8nLCAnQCcpLCBhcnJheSgnJywgJ18nLCAnJyksICR0aGlzLT5nZXRTdHJlYW0oKSk7CiAgICAgICAgICAgICR0aGlzLT5wNENsaWVudCA9ICdjb21wb3Nlcl9wZXJmb3JjZV8nIC4gJHRoaXMtPnVuaXF1ZVBlcmZvcmNlQ2xpZW50TmFtZSAuICdfJyAuICRjbGVhblN0cmVhbU5hbWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnA0Q2xpZW50OwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhdGg7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGluaXRpYWxpemVQYXRoKCRwYXRoKQogICAgewogICAgICAgICR0aGlzLT5wYXRoID0gJHBhdGg7CiAgICAgICAgJGZzID0gJHRoaXMtPmdldEZpbGVzeXN0ZW0oKTsKICAgICAgICAkZnMtPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkcGF0aCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBvcnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cDRQb3J0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJlYW0oJHN0cmVhbSkKICAgIHsKICAgICAgICAkdGhpcy0+cDRTdHJlYW0gPSAkc3RyZWFtOwogICAgICAgICRpbmRleCA9IHN0cnJwb3MoJHN0cmVhbSwgJy8nKTsKICAgICAgICAvL1N0cmVhbSBmb3JtYXQgaXMgLy9kZXBvdC9zdHJlYW0sIHdoaWxlIG5vbi1zdHJlYW1pbmcgZGVwb3QgaXMgLy9kZXBvdAogICAgICAgIGlmICgkaW5kZXggPiAyKSB7CiAgICAgICAgICAgICR0aGlzLT5wNERlcG90VHlwZSA9ICdzdHJlYW0nOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNTdHJlYW0oKQogICAgewogICAgICAgIHJldHVybiAoc3RyY21wKCR0aGlzLT5wNERlcG90VHlwZSwgJ3N0cmVhbScpID09PSAwKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyZWFtKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5wNFN0cmVhbSkpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5pc1N0cmVhbSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cDRTdHJlYW0gPSAnLy8nIC4gJHRoaXMtPnA0RGVwb3QgLiAnLycgLiAkdGhpcy0+cDRCcmFuY2g7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cDRTdHJlYW0gPSAnLy8nIC4gJHRoaXMtPnA0RGVwb3Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cDRTdHJlYW07CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0cmVhbVdpdGhvdXRMYWJlbCgkc3RyZWFtKQogICAgewogICAgICAgICRpbmRleCA9IHN0cnBvcygkc3RyZWFtLCAnQCcpOwogICAgICAgIGlmICgkaW5kZXggPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RyZWFtOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN1YnN0cigkc3RyZWFtLCAwLCAkaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQNENsaWVudFNwZWMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGF0aCAuICcvJyAuICR0aGlzLT5nZXRDbGllbnQoKSAuICcucDQuc3BlYyc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cDRVc2VyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VyKCR1c2VyKQogICAgewogICAgICAgICR0aGlzLT5wNFVzZXIgPSAkdXNlcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcXVlcnlQNFVzZXIoKQogICAgewogICAgICAgICR0aGlzLT5nZXRVc2VyKCk7CiAgICAgICAgaWYgKHN0cmxlbigkdGhpcy0+cDRVc2VyKSA+IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+cDRVc2VyID0gJHRoaXMtPmdldFA0dmFyaWFibGUoJ1A0VVNFUicpOwogICAgICAgIGlmIChzdHJsZW4oJHRoaXMtPnA0VXNlcikgPiAwKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnA0VXNlciA9ICR0aGlzLT5pby0+YXNrKCdFbnRlciBQNCBVc2VyOicpOwogICAgICAgIGlmICgkdGhpcy0+d2luZG93c0ZsYWcpIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSAncDQgc2V0IFA0VVNFUj0nIC4gJHRoaXMtPnA0VXNlcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29tbWFuZCA9ICdleHBvcnQgUDRVU0VSPScgLiAkdGhpcy0+cDRVc2VyOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQNHZhcmlhYmxlKCRuYW1lKQogICAgewogICAgICAgIGlmICgkdGhpcy0+d2luZG93c0ZsYWcpIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSAncDQgc2V0JzsKICAgICAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAgICAgJHJlc3VsdCA9IHRyaW0oJHRoaXMtPmNvbW1hbmRSZXN1bHQpOwogICAgICAgICAgICAkcmVzQXJyYXkgPSBleHBsb2RlKFBIUF9FT0wsICRyZXN1bHQpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVzQXJyYXkgYXMgJGxpbmUpIHsKICAgICAgICAgICAgICAgICRmaWVsZHMgPSBleHBsb2RlKCc9JywgJGxpbmUpOwogICAgICAgICAgICAgICAgaWYgKHN0cmNtcCgkbmFtZSwgJGZpZWxkc1swXSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICRpbmRleCA9IHN0cnBvcygkZmllbGRzWzFdLCAnICcpOwogICAgICAgICAgICAgICAgICAgIGlmICgkaW5kZXggPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRmaWVsZHNbMV07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gc3Vic3RyKCRmaWVsZHNbMV0sIDAsICRpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IHRyaW0oJHZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkY29tbWFuZCA9ICdlY2hvICQnIC4gJG5hbWU7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkcmVzdWx0ID0gdHJpbSgkdGhpcy0+Y29tbWFuZFJlc3VsdCk7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeVA0UGFzc3dvcmQoKQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cDRQYXNzd29yZCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wNFBhc3N3b3JkOwogICAgICAgIH0KICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+Z2V0UDR2YXJpYWJsZSgnUDRQQVNTV0QnKTsKICAgICAgICBpZiAoc3RybGVuKCRwYXNzd29yZCkgPD0gMCkgewogICAgICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJ0VudGVyIHBhc3N3b3JkIGZvciBQZXJmb3JjZSB1c2VyICcgLiAkdGhpcy0+Z2V0VXNlcigpIC4gJzogJyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5wNFBhc3N3b3JkID0gJHBhc3N3b3JkOwoKICAgICAgICByZXR1cm4gJHBhc3N3b3JkOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZVA0Q29tbWFuZCgkY29tbWFuZCwgJHVzZUNsaWVudCA9IHRydWUpCiAgICB7CiAgICAgICAgJHA0Q29tbWFuZCA9ICdwNCAnOwogICAgICAgICRwNENvbW1hbmQgLj0gJy11ICcgLiAkdGhpcy0+Z2V0VXNlcigpIC4gJyAnOwogICAgICAgIGlmICgkdXNlQ2xpZW50KSB7CiAgICAgICAgICAgICRwNENvbW1hbmQgLj0gJy1jICcgLiAkdGhpcy0+Z2V0Q2xpZW50KCkgLiAnICc7CiAgICAgICAgfQogICAgICAgICRwNENvbW1hbmQgLj0gJy1wICcgLiAkdGhpcy0+Z2V0UG9ydCgpIC4gJyAnIC4gJGNvbW1hbmQ7CgogICAgICAgIHJldHVybiAkcDRDb21tYW5kOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0xvZ2dlZEluKCkKICAgIHsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnbG9naW4gLXMnLCBmYWxzZSk7CiAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICBpZiAoJGV4aXRDb2RlKSB7CiAgICAgICAgICAgICRlcnJvck91dHB1dCA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAkaW5kZXggPSBzdHJwb3MoJGVycm9yT3V0cHV0LCAkdGhpcy0+Z2V0VXNlcigpKTsKICAgICAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRpbmRleCA9IHN0cnBvcygkZXJyb3JPdXRwdXQsICdwNCcpOwogICAgICAgICAgICAgICAgaWYgKCRpbmRleCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigncDQgY29tbWFuZCBub3QgZm91bmQgaW4gcGF0aDogJyAuICRlcnJvck91dHB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oJ0ludmFsaWQgdXNlciBuYW1lOiAnIC4gJHRoaXMtPmdldFVzZXIoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY29ubmVjdENsaWVudCgpCiAgICB7CiAgICAgICAgJHA0Q3JlYXRlQ2xpZW50Q29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgKICAgICAgICAgICAgJ2NsaWVudCAtaSA8ICcgLiBzdHJfcmVwbGFjZSgiICIsICJcXCAiLCAkdGhpcy0+Z2V0UDRDbGllbnRTcGVjKCkpCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJHA0Q3JlYXRlQ2xpZW50Q29tbWFuZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHN5bmNDb2RlQmFzZSgkc291cmNlUmVmZXJlbmNlKQogICAgewogICAgICAgICRwcmV2RGlyID0gZ2V0Y3dkKCk7CiAgICAgICAgY2hkaXIoJHRoaXMtPnBhdGgpOwogICAgICAgICRwNFN5bmNDb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCdzeW5jIC1mICcpOwogICAgICAgIGlmIChudWxsICE9PSAkc291cmNlUmVmZXJlbmNlKSB7CiAgICAgICAgICAgICRwNFN5bmNDb21tYW5kIC49ICdAJyAuICRzb3VyY2VSZWZlcmVuY2U7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkcDRTeW5jQ29tbWFuZCk7CiAgICAgICAgY2hkaXIoJHByZXZEaXIpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZUNsaWVudFNwZWNUb0ZpbGUoJHNwZWMpCiAgICB7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnQ2xpZW50OiAnIC4gJHRoaXMtPmdldENsaWVudCgpIC4gUEhQX0VPTCAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ1VwZGF0ZTogJyAuIGRhdGUoJ1kvbS9kIEg6aTpzJykgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnQWNjZXNzOiAnIC4gZGF0ZSgnWS9tL2QgSDppOnMnKSAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ093bmVyOiAgJyAuICR0aGlzLT5nZXRVc2VyKCkgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgZndyaXRlKCRzcGVjLCAnRGVzY3JpcHRpb246JyAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJyAgQ3JlYXRlZCBieSAnIC4gJHRoaXMtPmdldFVzZXIoKSAuICcgZnJvbSBjb21wb3Nlci4nIC4gUEhQX0VPTCAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ1Jvb3Q6ICcgLiAkdGhpcy0+Z2V0UGF0aCgpIC4gUEhQX0VPTCAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ09wdGlvbnM6ICBub2FsbHdyaXRlIG5vY2xvYmJlciBub2NvbXByZXNzIHVubG9ja2VkIG1vZHRpbWUgcm1kaXInIC4gUEhQX0VPTCAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ1N1Ym1pdE9wdGlvbnM6ICByZXZlcnR1bmNoYW5nZWQnIC4gUEhQX0VPTCAuIFBIUF9FT0wpOwogICAgICAgIGZ3cml0ZSgkc3BlYywgJ0xpbmVFbmQ6ICBsb2NhbCcgLiBQSFBfRU9MIC4gUEhQX0VPTCk7CiAgICAgICAgaWYgKCR0aGlzLT5pc1N0cmVhbSgpKSB7CiAgICAgICAgICAgIGZ3cml0ZSgkc3BlYywgJ1N0cmVhbTonIC4gUEhQX0VPTCk7CiAgICAgICAgICAgIGZ3cml0ZSgkc3BlYywgJyAgJyAuICR0aGlzLT5nZXRTdHJlYW1XaXRob3V0TGFiZWwoJHRoaXMtPnA0U3RyZWFtKSAuIFBIUF9FT0wpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZ3cml0ZSgKICAgICAgICAgICAgICAgICRzcGVjLAogICAgICAgICAgICAgICAgJ1ZpZXc6ICAnIC4gJHRoaXMtPmdldFN0cmVhbSgpIC4gJy8uLi4gIC8vJyAuICR0aGlzLT5nZXRDbGllbnQoKSAuICcvLi4uICcgLiBQSFBfRU9MCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZVA0Q2xpZW50U3BlYygpCiAgICB7CiAgICAgICAgJGNsaWVudFNwZWMgPSAkdGhpcy0+Z2V0UDRDbGllbnRTcGVjKCk7CiAgICAgICAgJHNwZWMgPSBmb3BlbigkY2xpZW50U3BlYywgJ3cnKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVDbGllbnRTcGVjVG9GaWxlKCRzcGVjKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGZjbG9zZSgkc3BlYyk7CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgICAgICBmY2xvc2UoJHNwZWMpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZWFkKCRwaXBlLCAkbmFtZSkKICAgIHsKICAgICAgICBpZiAoZmVvZigkcGlwZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkbGluZSA9IGZnZXRzKCRwaXBlKTsKICAgICAgICB3aGlsZSAoJGxpbmUgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRsaW5lID0gZmdldHMoJHBpcGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gd2luZG93c0xvZ2luKCRwYXNzd29yZCkKICAgIHsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnIGxvZ2luIC1hJyk7CgogICAgICAgIC8vIFRPRE8gaW4gdjMgZ2VuZXJhdGUgY29tbWFuZCBhcyBhbiBhcnJheQogICAgICAgIGlmIChtZXRob2RfZXhpc3RzKCdTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3MnLCAnZnJvbVNoZWxsQ29tbWFuZGxpbmUnKSkgewogICAgICAgICAgICAkcHJvY2VzcyA9IFByb2Nlc3M6OmZyb21TaGVsbENvbW1hbmRsaW5lKCRjb21tYW5kLCBudWxsLCBudWxsLCAkcGFzc3dvcmQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoJGNvbW1hbmQsIG51bGwsIG51bGwsICRwYXNzd29yZCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb2Nlc3MtPnJ1bigpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwNExvZ2luKCkKICAgIHsKICAgICAgICAkdGhpcy0+cXVlcnlQNFVzZXIoKTsKICAgICAgICBpZiAoISR0aGlzLT5pc0xvZ2dlZEluKCkpIHsKICAgICAgICAgICAgJHBhc3N3b3JkID0gJHRoaXMtPnF1ZXJ5UDRQYXNzd29yZCgpOwogICAgICAgICAgICBpZiAoJHRoaXMtPndpbmRvd3NGbGFnKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d2luZG93c0xvZ2luKCRwYXNzd29yZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29tbWFuZCA9ICdlY2hvICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGFzc3dvcmQpICAuICcgfCAnIC4gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCcgbG9naW4gLWEnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICAgICAgICAgaWYgKCRleGl0Q29kZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJFcnJvciBsb2dnaW5nIGluOiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VySW5mb3JtYXRpb24oJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyRmlsZUNvbnRlbnQgPSAkdGhpcy0+Z2V0RmlsZUNvbnRlbnQoJ2NvbXBvc2VyLmpzb24nLCAkaWRlbnRpZmllcik7CgogICAgICAgIGlmICghJGNvbXBvc2VyRmlsZUNvbnRlbnQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGpzb25fZGVjb2RlKCRjb21wb3NlckZpbGVDb250ZW50LCB0cnVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZUNvbnRlbnQoJGZpbGUsICRpZGVudGlmaWVyKQogICAgewogICAgICAgICRwYXRoID0gJHRoaXMtPmdldEZpbGVQYXRoKCRmaWxlLCAkaWRlbnRpZmllcik7CgogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCcgcHJpbnQgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKSk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CgogICAgICAgIGlmICghdHJpbSgkcmVzdWx0KSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlUGF0aCgkZmlsZSwgJGlkZW50aWZpZXIpCiAgICB7CiAgICAgICAgJGluZGV4ID0gc3RycG9zKCRpZGVudGlmaWVyLCAnQCcpOwogICAgICAgIGlmICgkaW5kZXggPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAkaWRlbnRpZmllci4gJy8nIC4gJGZpbGU7CiAgICAgICAgfQoKICAgICAgICAkcGF0aCA9IHN1YnN0cigkaWRlbnRpZmllciwgMCwgJGluZGV4KSAuICcvJyAuICRmaWxlIC4gc3Vic3RyKCRpZGVudGlmaWVyLCAkaW5kZXgpOwogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCcgZmlsZXMgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKSwgZmFsc2UpOwogICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkY29tbWFuZCk7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jb21tYW5kUmVzdWx0OwogICAgICAgICRpbmRleDIgPSBzdHJwb3MoJHJlc3VsdCwgJ25vIHN1Y2ggZmlsZShzKS4nKTsKICAgICAgICBpZiAoJGluZGV4MiA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJGluZGV4MyA9IHN0cnBvcygkcmVzdWx0LCAnY2hhbmdlJyk7CiAgICAgICAgICAgIGlmICgkaW5kZXgzICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJHBocmFzZSA9IHRyaW0oc3Vic3RyKCRyZXN1bHQsICRpbmRleDMpKTsKICAgICAgICAgICAgICAgICRmaWVsZHMgPSBleHBsb2RlKCcgJywgJHBocmFzZSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkaWRlbnRpZmllciwgMCwgJGluZGV4KSAuICcvJyAuICRmaWxlIC4gJ0AnIC4gJGZpZWxkc1sxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEJyYW5jaGVzKCkKICAgIHsKICAgICAgICAkcG9zc2libGVCcmFuY2hlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNTdHJlYW0oKSkgewogICAgICAgICAgICAkcG9zc2libGVCcmFuY2hlc1skdGhpcy0+cDRCcmFuY2hdID0gJHRoaXMtPmdldFN0cmVhbSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCdzdHJlYW1zICcuUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJy8vJyAuICR0aGlzLT5wNERlcG90IC4gJy8uLi4nKSk7CiAgICAgICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkY29tbWFuZCk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y29tbWFuZFJlc3VsdDsKICAgICAgICAgICAgJHJlc0FycmF5ID0gZXhwbG9kZShQSFBfRU9MLCAkcmVzdWx0KTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc0FycmF5IGFzICRsaW5lKSB7CiAgICAgICAgICAgICAgICAkcmVzQml0cyA9IGV4cGxvZGUoJyAnLCAkbGluZSk7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHJlc0JpdHMpID4gNCkgewogICAgICAgICAgICAgICAgICAgICRicmFuY2ggPSBwcmVnX3JlcGxhY2UoJy9bXkEtWmEtejAtOSBdLycsICcnLCAkcmVzQml0c1s0XSk7CiAgICAgICAgICAgICAgICAgICAgJHBvc3NpYmxlQnJhbmNoZXNbJGJyYW5jaF0gPSAkcmVzQml0c1sxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnY2hhbmdlcyAnLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdGhpcy0+Z2V0U3RyZWFtKCkgLiAnLy4uLicpLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGVDb21tYW5kKCRjb21tYW5kKTsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CiAgICAgICAgJHJlc0FycmF5ID0gZXhwbG9kZShQSFBfRU9MLCAkcmVzdWx0KTsKICAgICAgICAkbGFzdENvbW1pdCA9ICRyZXNBcnJheVswXTsKICAgICAgICAkbGFzdENvbW1pdEFyciA9IGV4cGxvZGUoJyAnLCAkbGFzdENvbW1pdCk7CiAgICAgICAgJGxhc3RDb21taXROdW0gPSAkbGFzdENvbW1pdEFyclsxXTsKCiAgICAgICAgcmV0dXJuIGFycmF5KCdtYXN0ZXInID0+ICRwb3NzaWJsZUJyYW5jaGVzWyR0aGlzLT5wNEJyYW5jaF0gLiAnQCcuICRsYXN0Q29tbWl0TnVtKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFncygpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Z2VuZXJhdGVQNENvbW1hbmQoJ2xhYmVscycpOwogICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkY29tbWFuZCk7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jb21tYW5kUmVzdWx0OwogICAgICAgICRyZXNBcnJheSA9IGV4cGxvZGUoUEhQX0VPTCwgJHJlc3VsdCk7CiAgICAgICAgJHRhZ3MgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyZXNBcnJheSBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRsaW5lLCAnTGFiZWwnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRmaWVsZHMgPSBleHBsb2RlKCcgJywgJGxpbmUpOwogICAgICAgICAgICAgICAgJHRhZ3NbJGZpZWxkc1sxXV0gPSAkdGhpcy0+Z2V0U3RyZWFtKCkgLiAnQCcgLiAkZmllbGRzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRhZ3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrU3RyZWFtKCkKICAgIHsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnZGVwb3RzJywgZmFsc2UpOwogICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkY29tbWFuZCk7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jb21tYW5kUmVzdWx0OwogICAgICAgICRyZXNBcnJheSA9IGV4cGxvZGUoUEhQX0VPTCwgJHJlc3VsdCk7CiAgICAgICAgZm9yZWFjaCAoJHJlc0FycmF5IGFzICRsaW5lKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGxpbmUsICdEZXBvdCcpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJGZpZWxkcyA9IGV4cGxvZGUoJyAnLCAkbGluZSk7CiAgICAgICAgICAgICAgICBpZiAoc3RyY21wKCR0aGlzLT5wNERlcG90LCAkZmllbGRzWzFdKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wNERlcG90VHlwZSA9ICRmaWVsZHNbM107CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aXNTdHJlYW0oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICRyZWZlcmVuY2UKICAgICAqIEByZXR1cm4gbWl4ZWR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2hhbmdlTGlzdCgkcmVmZXJlbmNlKQogICAgewogICAgICAgICRpbmRleCA9IHN0cnBvcygkcmVmZXJlbmNlLCAnQCcpOwogICAgICAgIGlmICgkaW5kZXggPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkbGFiZWwgPSBzdWJzdHIoJHJlZmVyZW5jZSwgJGluZGV4KTsKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZW5lcmF0ZVA0Q29tbWFuZCgnIGNoYW5nZXMgLW0xICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkbGFiZWwpKTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZUNvbW1hbmQoJGNvbW1hbmQpOwogICAgICAgICRjaGFuZ2VzID0gJHRoaXMtPmNvbW1hbmRSZXN1bHQ7CiAgICAgICAgaWYgKHN0cnBvcygkY2hhbmdlcywgJ0NoYW5nZScpICE9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkZmllbGRzID0gZXhwbG9kZSgnICcsICRjaGFuZ2VzKTsKCiAgICAgICAgcmV0dXJuICRmaWVsZHNbMV07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgJGZyb21SZWZlcmVuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAkdG9SZWZlcmVuY2UKICAgICAqIEByZXR1cm4gbWl4ZWR8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlKQogICAgewogICAgICAgICRmcm9tQ2hhbmdlTGlzdCA9ICR0aGlzLT5nZXRDaGFuZ2VMaXN0KCRmcm9tUmVmZXJlbmNlKTsKICAgICAgICBpZiAoJGZyb21DaGFuZ2VMaXN0ID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkdG9DaGFuZ2VMaXN0ID0gJHRoaXMtPmdldENoYW5nZUxpc3QoJHRvUmVmZXJlbmNlKTsKICAgICAgICBpZiAoJHRvQ2hhbmdlTGlzdCA9PT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJGluZGV4ID0gc3RycG9zKCRmcm9tUmVmZXJlbmNlLCAnQCcpOwogICAgICAgICRtYWluID0gc3Vic3RyKCRmcm9tUmVmZXJlbmNlLCAwLCAkaW5kZXgpIC4gJy8uLi4nOwogICAgICAgICRjb21tYW5kID0gJHRoaXMtPmdlbmVyYXRlUDRDb21tYW5kKCdmaWxlbG9nICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkbWFpbiAuICdAJyAuICRmcm9tQ2hhbmdlTGlzdC4gJywnIC4gJHRvQ2hhbmdlTGlzdCkpOwogICAgICAgICR0aGlzLT5leGVjdXRlQ29tbWFuZCgkY29tbWFuZCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWFuZFJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZXN5c3RlbSgpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5maWxlc3lzdGVtKSkgewogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9IG5ldyBGaWxlc3lzdGVtKCR0aGlzLT5wcm9jZXNzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZXN5c3RlbTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RmlsZXN5c3RlbShGaWxlc3lzdGVtICRmcykKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBVcmwKewogICAgLyoqCiAgICAgKiBAcGFyYW0gIENvbmZpZyAkY29uZmlnCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcmVmCiAgICAgKiBAcmV0dXJuIHN0cmluZyB0aGUgdXBkYXRlZCBVUkwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1cGRhdGVEaXN0UmVmZXJlbmNlKENvbmZpZyAkY29uZmlnLCAkdXJsLCAkcmVmKQogICAgewogICAgICAgICRob3N0ID0gcGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfSE9TVCk7CgogICAgICAgIGlmICgkaG9zdCA9PT0gJ2FwaS5naXRodWIuY29tJyB8fCAkaG9zdCA9PT0gJ2dpdGh1Yi5jb20nIHx8ICRob3N0ID09PSAnd3d3LmdpdGh1Yi5jb20nKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9naXRodWJcLmNvbS8oW14vXSspLyhbXi9dKykvKHppcHx0YXIpYmFsbC8oLispJH1pJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgLy8gdXBkYXRlIGxlZ2FjeSBnaXRodWIgYXJjaGl2ZXMgdG8gQVBJIGNhbGxzIHdpdGggdGhlIHByb3BlciByZWZlcmVuY2UKICAgICAgICAgICAgICAgICR1cmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnLycgLiAkbWF0Y2hbM10gLiAnYmFsbC8nIC4gJHJlZjsKICAgICAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3teaHR0cHM/Oi8vKD86d3d3XC4pP2dpdGh1YlwuY29tLyhbXi9dKykvKFteL10rKS9hcmNoaXZlLy4rXC4oemlwfHRhcikoPzpcLmd6KT8kfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgY3VycmVudCBnaXRodWIgd2ViIGFyY2hpdmVzIHRvIEFQSSBjYWxscyB3aXRoIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJyAuICRtYXRjaFsxXSAuICcvJy4gJG1hdGNoWzJdIC4gJy8nIC4gJG1hdGNoWzNdIC4gJ2JhbGwvJyAuICRyZWY7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCd7Xmh0dHBzPzovL2FwaVwuZ2l0aHViXC5jb20vcmVwb3MvKFteL10rKS8oW14vXSspLyh6aXB8dGFyKWJhbGwoPzovLispPyR9aScsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBhcGkgYXJjaGl2ZXMgdG8gdGhlIHByb3BlciByZWZlcmVuY2UKICAgICAgICAgICAgICAgICR1cmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnLycgLiAkbWF0Y2hbM10gLiAnYmFsbC8nIC4gJHJlZjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkaG9zdCA9PT0gJ2JpdGJ1Y2tldC5vcmcnIHx8ICRob3N0ID09PSAnd3d3LmJpdGJ1Y2tldC5vcmcnKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9iaXRidWNrZXRcLm9yZy8oW14vXSspLyhbXi9dKykvZ2V0LyguKylcLih6aXB8dGFyXC5nenx0YXJcLmJ6MikkfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgQml0YnVja2V0IGFyY2hpdmVzIHRvIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vYml0YnVja2V0Lm9yZy8nIC4gJG1hdGNoWzFdIC4gJy8nLiAkbWF0Y2hbMl0gLiAnL2dldC8nIC4gJHJlZiAuICcuJyAuICRtYXRjaFs0XTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkaG9zdCA9PT0gJ2dpdGxhYi5jb20nIHx8ICRob3N0ID09PSAnd3d3LmdpdGxhYi5jb20nKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xmh0dHBzPzovLyg/Ond3d1wuKT9naXRsYWJcLmNvbS9hcGkvdlszNF0vcHJvamVjdHMvKFteL10rKS9yZXBvc2l0b3J5L2FyY2hpdmVcLih6aXB8dGFyXC5nenx0YXJcLmJ6Mnx0YXIpXD9zaGE9LiskfWknLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgR2l0bGFiIGFyY2hpdmVzIHRvIHRoZSBwcm9wZXIgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAkdXJsID0gJ2h0dHBzOi8vZ2l0bGFiLmNvbS9hcGkvdjQvcHJvamVjdHMvJyAuICRtYXRjaFsxXSAuICcvcmVwb3NpdG9yeS9hcmNoaXZlLicgLiAkbWF0Y2hbMl0gLiAnP3NoYT0nIC4gJHJlZjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkaG9zdCwgJGNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpLCB0cnVlKSkgewogICAgICAgICAgICAkdXJsID0gcHJlZ19yZXBsYWNlKCd7KC9yZXBvcy9bXi9dKy9bXi9dKy8oemlwfHRhciliYWxsKSg/Oi8uKyk/JH1pJywgJyQxLycuJHJlZiwgJHVybCk7CiAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCRob3N0LCAkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksIHRydWUpKSB7CiAgICAgICAgICAgICR1cmwgPSBwcmVnX3JlcGxhY2UoJ3soL2FwaS92WzM0XS9wcm9qZWN0cy9bXi9dKy9yZXBvc2l0b3J5L2FyY2hpdmVcLig/OnppcHx0YXJcLmd6fHRhclwuYnoyfHRhcilcP3NoYT0pLiskfWknLCAnJHsxfScuJHJlZiwgJHVybCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICR1cmwKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0T3JpZ2luKENvbmZpZyAkY29uZmlnLCAkdXJsKQogICAgewogICAgICAgIGlmICgwID09PSBzdHJwb3MoJHVybCwgJ2ZpbGU6Ly8nKSkgewogICAgICAgICAgICByZXR1cm4gJHVybDsKICAgICAgICB9CgogICAgICAgICRvcmlnaW4gPSAoc3RyaW5nKSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9IT1NUKTsKICAgICAgICBpZiAoJHBvcnQgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9QT1JUKSkgewogICAgICAgICAgICAkb3JpZ2luIC49ICc6Jy4kcG9ydDsKICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJG9yaWdpbiwgJy5naXRodWIuY29tJykgPT09IChzdHJsZW4oJG9yaWdpbikgLSAxMSkpIHsKICAgICAgICAgICAgcmV0dXJuICdnaXRodWIuY29tJzsKICAgICAgICB9CgogICAgICAgIGlmICgkb3JpZ2luID09PSAncmVwby5wYWNrYWdpc3Qub3JnJykgewogICAgICAgICAgICByZXR1cm4gJ3BhY2thZ2lzdC5vcmcnOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRvcmlnaW4gPT09ICcnKSB7CiAgICAgICAgICAgICRvcmlnaW4gPSAkdXJsOwogICAgICAgIH0KCiAgICAgICAgLy8gR2l0bGFiIGNhbiBiZSBpbnN0YWxsZWQgaW4gYSBub24tcm9vdCBjb250ZXh0IChpLmUuIGdpdGxhYi5jb20vZm9vKS4gV2hlbiBkb3dubG9hZGluZyBhcmNoaXZlcyB0aGUgb3JpZ2luVXJsCiAgICAgICAgLy8gaXMgdGhlIGhvc3Qgd2l0aG91dCB0aGUgcGF0aCwgc28gd2UgbG9vayBmb3IgdGhlIHJlZ2lzdGVyZWQgZ2l0bGFiLWRvbWFpbnMgbWF0Y2hpbmcgdGhlIGhvc3QgaGVyZQogICAgICAgIGlmICgKICAgICAgICAgICAgaXNfYXJyYXkoJGNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpKQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gc3RycG9zKCRvcmlnaW4sICcvJykKICAgICAgICAgICAgJiYgIWluX2FycmF5KCRvcmlnaW4sICRjb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSkKICAgICAgICApIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpIGFzICRnaXRsYWJEb21haW4pIHsKICAgICAgICAgICAgICAgIGlmICgwID09PSBzdHJwb3MoJGdpdGxhYkRvbWFpbiwgJG9yaWdpbikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGdpdGxhYkRvbWFpbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvcmlnaW47CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYW5pdGl6ZSgkdXJsKQogICAgewogICAgICAgIC8vIEdpdEh1YiByZXBvc2l0b3J5IHJlbmFtZSByZXN1bHQgaW4gcmVkaXJlY3QgbG9jYXRpb25zIGNvbnRhaW5pbmcgdGhlIGFjY2Vzc190b2tlbiBhcyBHRVQgcGFyYW1ldGVyCiAgICAgICAgLy8gZS5nLiBodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zaXRvcmllcy85OTk5OTk5OTk5P2FjY2Vzc190b2tlbj1naXRodWJfdG9rZW4KICAgICAgICAkdXJsID0gcHJlZ19yZXBsYWNlKCd7KFsmP11hY2Nlc3NfdG9rZW49KVteJl0rfScsICckMSoqKicsICR1cmwpOwoKICAgICAgICAkdXJsID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCd7KD9QPHByZWZpeD46Ly98XikoP1A8dXNlcj5bXjovXHNAXSspOig/UDxwYXNzd29yZD5bXkBccy9dKylAfWknLCBmdW5jdGlvbiAoJG0pIHsKICAgICAgICAgICAgLy8gaWYgdGhlIHVzZXJuYW1lIGxvb2tzIGxpa2UgYSBsb25nICgxMmNoYXIrKSBoZXggc3RyaW5nLCBvciBhIG1vZGVybiBnaXRodWIgdG9rZW4gKGUuZy4gZ3AxX3h4eCkgd2Ugb2JmdXNjYXRlIHRoYXQKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFthLWYwLTldezEyLH18Z1thLXpdXGRfW2EtekEtWjAtOV9dKykkfScsICRtWyd1c2VyJ10pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1bJ3ByZWZpeCddLicqKio6KioqQCc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkbVsncHJlZml4J10uJG1bJ3VzZXInXS4nOioqKkAnOwogICAgICAgIH0sICR1cmwpOwoKICAgICAgICByZXR1cm4gJHVybDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKLyoqCiAqIFBsYXRmb3JtIGhlbHBlciBmb3IgdW5pZm9ybSBwbGF0Zm9ybS1zcGVjaWZpYyB0ZXN0cy4KICoKICogQGF1dGhvciBOaWVscyBLZXVyZW50amVzIDxuaWVscy5rZXVyZW50amVzQG9taW5lcy5jb20+CiAqLwpjbGFzcyBQbGF0Zm9ybQp7CiAgICAvKiogQHZhciA/Ym9vbCAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGlzVmlydHVhbEJveEd1ZXN0ID0gbnVsbDsKCiAgICAvKioKICAgICAqIFBhcnNlcyB0aWxkZXMgYW5kIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBwYXRocy4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBleHBhbmRQYXRoKCRwYXRoKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcjXn5bXFwvXSMnLCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmdldFVzZXJEaXJlY3RvcnkoKSAuIHN1YnN0cigkcGF0aCwgMSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCcjXihcJHwoP1A8cGVyY2VudD4lKSkoP1A8dmFyPlx3KyspKD8ocGVyY2VudCklKSg/UDxwYXRoPi4qKSMnLCBmdW5jdGlvbiAoJG1hdGNoZXMpIHsKICAgICAgICAgICAgLy8gVHJlYXQgSE9NRSBhcyBhbiBhbGlhcyBmb3IgVVNFUlBST0ZJTEUgb24gV2luZG93cyBmb3IgbGVnYWN5IHJlYXNvbnMKICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiAkbWF0Y2hlc1sndmFyJ10gPT0gJ0hPTUUnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGdldGVudignSE9NRScpID86IGdldGVudignVVNFUlBST0ZJTEUnKSkgLiAkbWF0Y2hlc1sncGF0aCddOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZ2V0ZW52KCRtYXRjaGVzWyd2YXInXSkgLiAkbWF0Y2hlc1sncGF0aCddOwogICAgICAgIH0sICRwYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gSWYgdGhlIHVzZXIgaG9tZSBjb3VsZCBub3QgcmVsaWFibHkgYmUgZGV0ZXJtaW5lZAogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgICBUaGUgZm9ybWFsIHVzZXIgaG9tZSBhcyBkZXRlY3RlZCBmcm9tIGVudmlyb25tZW50IHBhcmFtZXRlcnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRVc2VyRGlyZWN0b3J5KCkKICAgIHsKICAgICAgICBpZiAoZmFsc2UgIT09ICgkaG9tZSA9IGdldGVudignSE9NRScpKSkgewogICAgICAgICAgICByZXR1cm4gJGhvbWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZjo6aXNXaW5kb3dzKCkgJiYgZmFsc2UgIT09ICgkaG9tZSA9IGdldGVudignVVNFUlBST0ZJTEUnKSkpIHsKICAgICAgICAgICAgcmV0dXJuICRob21lOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldHVpZCcpICYmIFxmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldHB3dWlkJykpIHsKICAgICAgICAgICAgJGluZm8gPSBwb3NpeF9nZXRwd3VpZChwb3NpeF9nZXR1aWQoKSk7CgogICAgICAgICAgICByZXR1cm4gJGluZm9bJ2RpciddOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgZGV0ZXJtaW5lIHVzZXIgZGlyZWN0b3J5Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgaG9zdCBtYWNoaW5lIGlzIHJ1bm5pbmcgYSBXaW5kb3dzIE9TCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNXaW5kb3dzKCkKICAgIHsKICAgICAgICByZXR1cm4gXGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzdHIKICAgICAqIEByZXR1cm4gaW50ICAgIHJldHVybiBhIGd1YXJhbnRlZWQgYmluYXJ5IGxlbmd0aCBvZiB0aGUgc3RyaW5nLCByZWdhcmRsZXNzIG9mIHNpbGx5IG1ic3RyaW5nIGNvbmZpZ3MKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdHJsZW4oJHN0cikKICAgIHsKICAgICAgICBzdGF0aWMgJHVzZU1iU3RyaW5nID0gbnVsbDsKICAgICAgICBpZiAobnVsbCA9PT0gJHVzZU1iU3RyaW5nKSB7CiAgICAgICAgICAgICR1c2VNYlN0cmluZyA9IFxmdW5jdGlvbl9leGlzdHMoJ21iX3N0cmxlbicpICYmIGluaV9nZXQoJ21ic3RyaW5nLmZ1bmNfb3ZlcmxvYWQnKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdXNlTWJTdHJpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIG1iX3N0cmxlbigkc3RyLCAnOGJpdCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxzdHJsZW4oJHN0cik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1R0eSgkZmQgPSBudWxsKQogICAgewogICAgICAgIGlmICgkZmQgPT09IG51bGwpIHsKICAgICAgICAgICAgJGZkID0gZGVmaW5lZCgnU1RET1VUJykgPyBTVERPVVQgOiBmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKTsKICAgICAgICB9CgogICAgICAgIC8vIGRldGVjdCBtc3lzZ2l0L21pbmd3IGFuZCBhc3N1bWUgdGhpcyBpcyBhIHR0eSBiZWNhdXNlIGRldGVjdGlvbgogICAgICAgIC8vIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy85NjkwCiAgICAgICAgaWYgKGluX2FycmF5KHN0cnRvdXBwZXIoZ2V0ZW52KCdNU1lTVEVNJykgPzogJycpLCBhcnJheSgnTUlOR1czMicsICdNSU5HVzY0JyksIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbW9kZXJuIGNyb3NzLXBsYXRmb3JtIGZ1bmN0aW9uLCBpbmNsdWRlcyB0aGUgZnN0YXQKICAgICAgICAvLyBmYWxsYmFjayBzbyBpZiBpdCBpcyBwcmVzZW50IHdlIHRydXN0IGl0CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnc3RyZWFtX2lzYXR0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJlYW1faXNhdHR5KCRmZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBvbmx5IHRydXN0aW5nIHRoaXMgaWYgaXQgaXMgcG9zaXRpdmUsIG90aGVyd2lzZSBwcmVmZXIgZnN0YXQgZmFsbGJhY2sKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9pc2F0dHknKSAmJiBwb3NpeF9pc2F0dHkoJGZkKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRzdGF0ID0gQGZzdGF0KCRmZCk7CiAgICAgICAgLy8gQ2hlY2sgaWYgZm9ybWF0dGVkIG1vZGUgaXMgU19JRkNIUgogICAgICAgIHJldHVybiAkc3RhdCA/IDAwMjAwMDAgPT09ICgkc3RhdFsnbW9kZSddICYgMDE3MDAwMCkgOiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHdvcmthcm91bmRGaWxlc3lzdGVtSXNzdWVzKCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6aXNWaXJ0dWFsQm94R3Vlc3QoKSkgewogICAgICAgICAgICB1c2xlZXAoMjAwMDAwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyBkZXRlY3Rpb24gb2YgVmlydHVhbEJveCBndWVzdCBWTXMKICAgICAqCiAgICAgKiBUaGlzIHdvcmtzIGJhc2VkIG9uIHRoZSBwcm9jZXNzJyB1c2VyIGJlaW5nICJ2YWdyYW50IiwgdGhlIENPTVBPU0VSX1JVTlRJTUVfRU5WIGVudiB2YXIgYmVpbmcgc2V0IHRvICJ2aXJ0dWFsYm94Iiwgb3IgbHNtb2Qgc2hvd2luZyB0aGUgdmlydHVhbGJveCBndWVzdCBhZGRpdGlvbnMgYXJlIGxvYWRlZAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc1ZpcnR1YWxCb3hHdWVzdCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCkgewogICAgICAgICAgICBzZWxmOjokaXNWaXJ0dWFsQm94R3Vlc3QgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKHNlbGY6OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRwd3VpZCcpICYmIGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZXVpZCcpKSB7CiAgICAgICAgICAgICAgICAkcHJvY2Vzc1VzZXIgPSBwb3NpeF9nZXRwd3VpZChwb3NpeF9nZXRldWlkKCkpOwogICAgICAgICAgICAgICAgaWYgKCRwcm9jZXNzVXNlciAmJiAkcHJvY2Vzc1VzZXJbJ25hbWUnXSA9PT0gJ3ZhZ3JhbnQnKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChnZXRlbnYoJ0NPTVBPU0VSX1JVTlRJTUVfRU5WJykgPT09ICd2aXJ0dWFsYm94JykgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRpc1ZpcnR1YWxCb3hHdWVzdCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdQSFBfT1NfRkFNSUxZJykgJiYgUEhQX09TX0ZBTUlMWSA9PT0gJ0xpbnV4JykgewogICAgICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkcHJvY2Vzcy0+ZXhlY3V0ZSgnbHNtb2QgfCBncmVwIHZib3hndWVzdCcsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbm9vcAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGlzVmlydHVhbEJveEd1ZXN0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7CgovKioKICogQGF1dGhvciBBbmRyZWFzIFNjaGVtcHAgPGFuZHJlYXMuc2NoZW1wcEB0ZXJtaW5hbDQyLmNoPgogKi8KY2xhc3MgWmlwCnsKICAgIC8qKgogICAgICogR2V0cyBjb250ZW50IG9mIHRoZSByb290IGNvbXBvc2VyLmpzb24gaW5zaWRlIGEgWklQIGFyY2hpdmUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aFRvWmlwCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbXBvc2VySnNvbigkcGF0aFRvWmlwKQogICAgewogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnemlwJykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgWmlwIFV0aWwgcmVxdWlyZXMgUEhQXCdzIHppcCBleHRlbnNpb24nKTsKICAgICAgICB9CgogICAgICAgICR6aXAgPSBuZXcgXFppcEFyY2hpdmUoKTsKICAgICAgICBpZiAoJHppcC0+b3BlbigkcGF0aFRvWmlwKSAhPT0gdHJ1ZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICgwID09ICR6aXAtPm51bUZpbGVzKSB7CiAgICAgICAgICAgICR6aXAtPmNsb3NlKCk7CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRmb3VuZEZpbGVJbmRleCA9IHNlbGY6OmxvY2F0ZUZpbGUoJHppcCwgJ2NvbXBvc2VyLmpzb24nKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRmb3VuZEZpbGVJbmRleCkgewogICAgICAgICAgICAkemlwLT5jbG9zZSgpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkY29udGVudCA9IG51bGw7CiAgICAgICAgJGNvbmZpZ3VyYXRpb25GaWxlTmFtZSA9ICR6aXAtPmdldE5hbWVJbmRleCgkZm91bmRGaWxlSW5kZXgpOwogICAgICAgICRzdHJlYW0gPSAkemlwLT5nZXRTdHJlYW0oJGNvbmZpZ3VyYXRpb25GaWxlTmFtZSk7CgogICAgICAgIGlmIChmYWxzZSAhPT0gJHN0cmVhbSkgewogICAgICAgICAgICAkY29udGVudCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHN0cmVhbSk7CiAgICAgICAgfQoKICAgICAgICAkemlwLT5jbG9zZSgpOwoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kIGEgZmlsZSBieSBuYW1lLCByZXR1cm5pbmcgdGhlIG9uZSB0aGF0IGhhcyB0aGUgc2hvcnRlc3QgcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFxaaXBBcmNoaXZlICAgICAgICR6aXAKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGZpbGVuYW1lCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbG9jYXRlRmlsZShcWmlwQXJjaGl2ZSAkemlwLCAkZmlsZW5hbWUpCiAgICB7CiAgICAgICAgLy8gcmV0dXJuIHJvb3QgY29tcG9zZXIuanNvbiBpZiBpdCBpcyB0aGVyZSBhbmQgaXMgYSBmaWxlCiAgICAgICAgaWYgKGZhbHNlICE9PSAoJGluZGV4ID0gJHppcC0+bG9jYXRlTmFtZSgkZmlsZW5hbWUpKSAmJiAkemlwLT5nZXRGcm9tSW5kZXgoJGluZGV4KSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICRpbmRleDsKICAgICAgICB9CgogICAgICAgICR0b3BMZXZlbFBhdGhzID0gYXJyYXkoKTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkemlwLT5udW1GaWxlczsgJGkrKykgewogICAgICAgICAgICAkbmFtZSA9ICR6aXAtPmdldE5hbWVJbmRleCgkaSk7CiAgICAgICAgICAgICRkaXJuYW1lID0gZGlybmFtZSgkbmFtZSk7CgogICAgICAgICAgICAvLyBpZ25vcmUgT1NYIHNwZWNpZmljIHJlc291cmNlIGZvcmsgZm9sZGVyCiAgICAgICAgICAgIGlmIChzdHJwb3MoJG5hbWUsICdfX01BQ09TWCcpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGhhbmRsZSBhcmNoaXZlcyB3aXRoIHByb3BlciBUT0MKICAgICAgICAgICAgaWYgKCRkaXJuYW1lID09PSAnLicpIHsKICAgICAgICAgICAgICAgICR0b3BMZXZlbFBhdGhzWyRuYW1lXSA9IHRydWU7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR0b3BMZXZlbFBhdGhzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0FyY2hpdmUgaGFzIG1vcmUgdGhhbiBvbmUgdG9wIGxldmVsIGRpcmVjdG9yaWVzLCBhbmQgbm8gY29tcG9zZXIuanNvbiB3YXMgZm91bmQgb24gdGhlIHRvcCBsZXZlbCwgc28gaXRcJ3MgYW4gaW52YWxpZCBhcmNoaXZlLiBUb3AgbGV2ZWwgcGF0aHMgZm91bmQgd2VyZTogJy5pbXBsb2RlKCcsJywgYXJyYXlfa2V5cygkdG9wTGV2ZWxQYXRocykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgYXJjaGl2ZXMgd2hpY2ggZG8gbm90IGhhdmUgYSBUT0MgcmVjb3JkIGZvciB0aGUgZGlyZWN0b3J5IGl0c2VsZgogICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkZGlybmFtZSwgJ1xcJykgJiYgZmFsc2UgPT09IHN0cnBvcygkZGlybmFtZSwgJy8nKSkgewogICAgICAgICAgICAgICAgJHRvcExldmVsUGF0aHNbJGRpcm5hbWUuJy8nXSA9IHRydWU7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR0b3BMZXZlbFBhdGhzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0FyY2hpdmUgaGFzIG1vcmUgdGhhbiBvbmUgdG9wIGxldmVsIGRpcmVjdG9yaWVzLCBhbmQgbm8gY29tcG9zZXIuanNvbiB3YXMgZm91bmQgb24gdGhlIHRvcCBsZXZlbCwgc28gaXRcJ3MgYW4gaW52YWxpZCBhcmNoaXZlLiBUb3AgbGV2ZWwgcGF0aHMgZm91bmQgd2VyZTogJy5pbXBsb2RlKCcsJywgYXJyYXlfa2V5cygkdG9wTGV2ZWxQYXRocykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0b3BMZXZlbFBhdGhzICYmIGZhbHNlICE9PSAoJGluZGV4ID0gJHppcC0+bG9jYXRlTmFtZShrZXkoJHRvcExldmVsUGF0aHMpLiRmaWxlbmFtZSkpICYmICR6aXAtPmdldEZyb21JbmRleCgkaW5kZXgpICE9PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gJGluZGV4OwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGVpdGhlciBhdCB0aGUgdG9wIGxldmVsIG9yIHdpdGhpbiB0aGUgdG9wbW9zdCBkaXJlY3RvcnknKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKLyoqCiAqIEBhdXRob3IgV2lzc2VtIFJpYWhpIDx3aXNzZW1yQGdtYWlsLmNvbT4KICovCmNsYXNzIFRhcgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGhUb0FyY2hpdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXJKc29uKCRwYXRoVG9BcmNoaXZlKQogICAgewogICAgICAgICRwaGFyID0gbmV3IFxQaGFyRGF0YSgkcGF0aFRvQXJjaGl2ZSk7CgogICAgICAgIGlmICghJHBoYXItPnZhbGlkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6ZXh0cmFjdENvbXBvc2VySnNvbkZyb21Gb2xkZXIoJHBoYXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFxQaGFyRGF0YSAkcGhhcgogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0Q29tcG9zZXJKc29uRnJvbUZvbGRlcihcUGhhckRhdGEgJHBoYXIpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRwaGFyWydjb21wb3Nlci5qc29uJ10pKSB7CiAgICAgICAgICAgIHJldHVybiAkcGhhclsnY29tcG9zZXIuanNvbiddLT5nZXRDb250ZW50KCk7CiAgICAgICAgfQoKICAgICAgICAkdG9wTGV2ZWxQYXRocyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBoYXIgYXMgJGZvbGRlckZpbGUpIHsKICAgICAgICAgICAgJG5hbWUgPSAkZm9sZGVyRmlsZS0+Z2V0QmFzZW5hbWUoKTsKCiAgICAgICAgICAgIGlmICgkZm9sZGVyRmlsZS0+aXNEaXIoKSkgewogICAgICAgICAgICAgICAgJHRvcExldmVsUGF0aHNbJG5hbWVdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChcY291bnQoJHRvcExldmVsUGF0aHMpID4gMSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQXJjaGl2ZSBoYXMgbW9yZSB0aGFuIG9uZSB0b3AgbGV2ZWwgZGlyZWN0b3JpZXMsIGFuZCBubyBjb21wb3Nlci5qc29uIHdhcyBmb3VuZCBvbiB0aGUgdG9wIGxldmVsLCBzbyBpdFwncyBhbiBpbnZhbGlkIGFyY2hpdmUuIFRvcCBsZXZlbCBwYXRocyBmb3VuZCB3ZXJlOiAnLmltcGxvZGUoJywnLCBhcnJheV9rZXlzKCR0b3BMZXZlbFBhdGhzKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXJKc29uUGF0aCA9IGtleSgkdG9wTGV2ZWxQYXRocykuJy9jb21wb3Nlci5qc29uJzsKICAgICAgICBpZiAoJHRvcExldmVsUGF0aHMgJiYgaXNzZXQoJHBoYXJbJGNvbXBvc2VySnNvblBhdGhdKSkgewogICAgICAgICAgICByZXR1cm4gJHBoYXJbJGNvbXBvc2VySnNvblBhdGhdLT5nZXRDb250ZW50KCk7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ05vIGNvbXBvc2VyLmpzb24gZm91bmQgZWl0aGVyIGF0IHRoZSB0b3AgbGV2ZWwgb3Igd2l0aGluIHRoZSB0b3Btb3N0IGRpcmVjdG9yeScpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBBdXRoSGVscGVyCnsKICAgIHByb3RlY3RlZCAkaW87CiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIHByaXZhdGUgJGRpc3BsYXllZE9yaWdpbkF1dGhlbnRpY2F0aW9ucyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRvcmlnaW4KICAgICAqIEBwYXJhbSBzdHJpbmd8Ym9vbCAkc3RvcmVBdXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdG9yZUF1dGgoJG9yaWdpbiwgJHN0b3JlQXV0aCkKICAgIHsKICAgICAgICAkc3RvcmUgPSBmYWxzZTsKICAgICAgICAkY29uZmlnU291cmNlID0gJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpOwogICAgICAgIGlmICgkc3RvcmVBdXRoID09PSB0cnVlKSB7CiAgICAgICAgICAgICRzdG9yZSA9ICRjb25maWdTb3VyY2U7CiAgICAgICAgfSBlbHNlaWYgKCRzdG9yZUF1dGggPT09ICdwcm9tcHQnKSB7CiAgICAgICAgICAgICRhbnN3ZXIgPSAkdGhpcy0+aW8tPmFza0FuZFZhbGlkYXRlKAogICAgICAgICAgICAgICAgJ0RvIHlvdSB3YW50IHRvIHN0b3JlIGNyZWRlbnRpYWxzIGZvciAnLiRvcmlnaW4uJyBpbiAnLiRjb25maWdTb3VyY2UtPmdldE5hbWUoKS4nID8gW1luXSAnLAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICRpbnB1dCA9IHN0cnRvbG93ZXIoc3Vic3RyKHRyaW0oJHZhbHVlKSwgMCwgMSkpOwogICAgICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkaW5wdXQsIGFycmF5KCd5JywnbicpKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1BsZWFzZSBhbnN3ZXIgKHkpZXMgb3IgKG4pbycpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAneScKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICgkYW5zd2VyID09PSAneScpIHsKICAgICAgICAgICAgICAgICRzdG9yZSA9ICRjb25maWdTb3VyY2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRzdG9yZSkgewogICAgICAgICAgICAkc3RvcmUtPmFkZENvbmZpZ1NldHRpbmcoCiAgICAgICAgICAgICAgICAnaHR0cC1iYXNpYy4nLiRvcmlnaW4sCiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW4pCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAkdXJsCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRvcmlnaW4KICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgJHN0YXR1c0NvZGUgSFRUUCBzdGF0dXMgY29kZSB0aGF0IHRyaWdnZXJlZCB0aGlzIGNhbGwKICAgICAqIEBwYXJhbSAgc3RyaW5nfG51bGwgJHJlYXNvbiAgICAgYSBtZXNzYWdlL2Rlc2NyaXB0aW9uIGV4cGxhaW5pbmcgd2h5IHRoaXMgd2FzIGNhbGxlZAogICAgICogQHBhcmFtICBzdHJpbmdbXSAgICAkaGVhZGVycwogICAgICogQHJldHVybiBhcnJheXxudWxsICBjb250YWluaW5nIHJldHJ5IChib29sKSBhbmQgc3RvcmVBdXRoIChzdHJpbmd8Ym9vbCkga2V5cywgaWYgcmV0cnkgaXMgdHJ1ZSB0aGUgcmVxdWVzdCBzaG91bGQgYmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWVkLCBpZiBzdG9yZUF1dGggaXMgdHJ1ZSB0aGVuIG9uIGEgc3VjY2Vzc2Z1bCByZXRyeSB0aGUgYXV0aGVudGljYXRpb24gc2hvdWxkIGJlIHBlcnNpc3RlZCB0byBhdXRoLmpzb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb21wdEF1dGhJZk5lZWRlZCgkdXJsLCAkb3JpZ2luLCAkc3RhdHVzQ29kZSwgJHJlYXNvbiA9IG51bGwsICRoZWFkZXJzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkc3RvcmVBdXRoID0gZmFsc2U7CgogICAgICAgIGlmIChpbl9hcnJheSgkb3JpZ2luLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGh1Yi1kb21haW5zJyksIHRydWUpKSB7CiAgICAgICAgICAgICRnaXRIdWJVdGlsID0gbmV3IEdpdEh1YigkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsIG51bGwpOwogICAgICAgICAgICAkbWVzc2FnZSA9ICJcbiI7CgogICAgICAgICAgICAkcmF0ZUxpbWl0ZWQgPSAkZ2l0SHViVXRpbC0+aXNSYXRlTGltaXRlZCgkaGVhZGVycyk7CiAgICAgICAgICAgIGlmICgkcmF0ZUxpbWl0ZWQpIHsKICAgICAgICAgICAgICAgICRyYXRlTGltaXQgPSAkZ2l0SHViVXRpbC0+Z2V0UmF0ZUxpbWl0KCRoZWFkZXJzKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCRvcmlnaW4pKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnUmV2aWV3IHlvdXIgY29uZmlndXJlZCBHaXRIdWIgT0F1dGggdG9rZW4gb3IgZW50ZXIgYSBuZXcgb25lIHRvIGdvIG92ZXIgdGhlIEFQSSByYXRlIGxpbWl0Lic7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0NyZWF0ZSBhIEdpdEh1YiBPQXV0aCB0b2tlbiB0byBnbyBvdmVyIHRoZSBBUEkgcmF0ZSBsaW1pdC4nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnR2l0SHViIEFQSSBsaW1pdCAoJWQgY2FsbHMvaHIpIGlzIGV4aGF1c3RlZCwgY291bGQgbm90IGZldGNoICcuJHVybC4nLiAnLiRtZXNzYWdlLicgWW91IGNhbiBhbHNvIHdhaXQgdW50aWwgJXMgZm9yIHRoZSByYXRlIGxpbWl0IHRvIHJlc2V0LicsCiAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdFsnbGltaXQnXSwKICAgICAgICAgICAgICAgICAgICAkcmF0ZUxpbWl0WydyZXNldCddCiAgICAgICAgICAgICAgICApLiJcbiI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAnQ291bGQgbm90IGZldGNoICcuJHVybC4nLCBwbGVhc2UgJzsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+aW8tPmhhc0F1dGhlbnRpY2F0aW9uKCRvcmlnaW4pKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJ3JldmlldyB5b3VyIGNvbmZpZ3VyZWQgR2l0SHViIE9BdXRoIHRva2VuIG9yIGVudGVyIGEgbmV3IG9uZSB0byBhY2Nlc3MgcHJpdmF0ZSByZXBvcyc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICdjcmVhdGUgYSBHaXRIdWIgT0F1dGggdG9rZW4gdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRnaXRIdWJVdGlsLT5hdXRob3JpemVPQXV0aCgkb3JpZ2luKQogICAgICAgICAgICAgICAgJiYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSB8fCAhJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkb3JpZ2luLCAkbWVzc2FnZSkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignQ291bGQgbm90IGF1dGhlbnRpY2F0ZSBhZ2FpbnN0ICcuJG9yaWdpbiwgNDAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkb3JpZ2luLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksIHRydWUpKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gIlxuIi4nQ291bGQgbm90IGZldGNoICcuJHVybC4nLCBlbnRlciB5b3VyICcgLiAkb3JpZ2luIC4gJyBjcmVkZW50aWFscyAnIC4oJHN0YXR1c0NvZGUgPT09IDQwMSA/ICd0byBhY2Nlc3MgcHJpdmF0ZSByZXBvcycgOiAndG8gZ28gb3ZlciB0aGUgQVBJIHJhdGUgbGltaXQnKTsKICAgICAgICAgICAgJGdpdExhYlV0aWwgPSBuZXcgR2l0TGFiKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgbnVsbCk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSAmJiAoJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW4pKSAmJiBpbl9hcnJheSgkYXV0aFsncGFzc3dvcmQnXSwgYXJyYXkoJ2dpdGxhYi1jaS10b2tlbicsICdwcml2YXRlLXRva2VuJywgJ29hdXRoMicpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigiSW52YWxpZCBjcmVkZW50aWFscyBmb3IgJyIgLiAkdXJsIC4gIicsIGFib3J0aW5nLiIsICRzdGF0dXNDb2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkZ2l0TGFiVXRpbC0+YXV0aG9yaXplT0F1dGgoJG9yaWdpbikKICAgICAgICAgICAgICAgICYmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgfHwgISRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkocGFyc2VfdXJsKCR1cmwsIFBIUF9VUkxfU0NIRU1FKSwgJG9yaWdpbiwgJG1lc3NhZ2UpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgYWdhaW5zdCAnLiRvcmlnaW4sIDQwMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJG9yaWdpbiA9PT0gJ2JpdGJ1Y2tldC5vcmcnIHx8ICRvcmlnaW4gPT09ICdhcGkuYml0YnVja2V0Lm9yZycpIHsKICAgICAgICAgICAgJGFza0Zvck9BdXRoVG9rZW4gPSB0cnVlOwogICAgICAgICAgICAkb3JpZ2luID0gJ2JpdGJ1Y2tldC5vcmcnOwogICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW4pOwogICAgICAgICAgICAgICAgaWYgKCRhdXRoWyd1c2VybmFtZSddICE9PSAneC10b2tlbi1hdXRoJykgewogICAgICAgICAgICAgICAgICAgICRiaXRidWNrZXRVdGlsID0gbmV3IEJpdGJ1Y2tldCgkdGhpcy0+aW8sICR0aGlzLT5jb25maWcpOwogICAgICAgICAgICAgICAgICAgICRhY2Nlc3NUb2tlbiA9ICRiaXRidWNrZXRVdGlsLT5yZXF1ZXN0VG9rZW4oJG9yaWdpbiwgJGF1dGhbJ3VzZXJuYW1lJ10sICRhdXRoWydwYXNzd29yZCddKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRhY2Nlc3NUb2tlbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luLCAneC10b2tlbi1hdXRoJywgJGFjY2Vzc1Rva2VuKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGFza0Zvck9BdXRoVG9rZW4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgYWdhaW5zdCAnIC4gJG9yaWdpbiwgNDAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRhc2tGb3JPQXV0aFRva2VuKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICJcbiIuJ0NvdWxkIG5vdCBmZXRjaCAnIC4gJHVybCAuICcsIHBsZWFzZSBjcmVhdGUgYSBiaXRidWNrZXQgT0F1dGggdG9rZW4gdG8gJyAuICgoJHN0YXR1c0NvZGUgPT09IDQwMSB8fCAkc3RhdHVzQ29kZSA9PT0gNDAzKSA/ICdhY2Nlc3MgcHJpdmF0ZSByZXBvcycgOiAnZ28gb3ZlciB0aGUgQVBJIHJhdGUgbGltaXQnKTsKICAgICAgICAgICAgICAgICRiaXRCdWNrZXRVdGlsID0gbmV3IEJpdGJ1Y2tldCgkdGhpcy0+aW8sICR0aGlzLT5jb25maWcpOwogICAgICAgICAgICAgICAgaWYgKCEkYml0QnVja2V0VXRpbC0+YXV0aG9yaXplT0F1dGgoJG9yaWdpbikKICAgICAgICAgICAgICAgICAgICAmJiAoISR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpIHx8ICEkYml0QnVja2V0VXRpbC0+YXV0aG9yaXplT0F1dGhJbnRlcmFjdGl2ZWx5KCRvcmlnaW4sICRtZXNzYWdlKSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgYWdhaW5zdCAnIC4gJG9yaWdpbiwgNDAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIDQwNHMgYXJlIG9ubHkgaGFuZGxlZCBmb3IgZ2l0aHViCiAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZhaWwgaWYgdGhlIGNvbnNvbGUgaXMgbm90IGludGVyYWN0aXZlCiAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA9PT0gNDAxKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVGhlICciIC4gJHVybCAuICInIFVSTCByZXF1aXJlZCBhdXRoZW50aWNhdGlvbi5cbllvdSBtdXN0IGJlIHVzaW5nIHRoZSBpbnRlcmFjdGl2ZSBjb25zb2xlIHRvIGF1dGhlbnRpY2F0ZSI7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXR1c0NvZGUgPT09IDQwMykgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlRoZSAnIiAuICR1cmwgLiAiJyBVUkwgY291bGQgbm90IGJlIGFjY2Vzc2VkOiAiIC4gJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiVW5rbm93biBlcnJvciBjb2RlICciIC4gJHN0YXR1c0NvZGUgLiAiJywgcmVhc29uOiAiIC4gJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCRtZXNzYWdlLCAkc3RhdHVzQ29kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gZmFpbCBpZiB3ZSBhbHJlYWR5IGhhdmUgYXV0aAogICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbigiSW52YWxpZCBjcmVkZW50aWFscyBmb3IgJyIgLiAkdXJsIC4gIicsIGFib3J0aW5nLiIsICRzdGF0dXNDb2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgQXV0aGVudGljYXRpb24gcmVxdWlyZWQgKDxpbmZvPicuJG9yaWdpbi4nPC9pbmZvPik6Jyk7CiAgICAgICAgICAgICR1c2VybmFtZSA9ICR0aGlzLT5pby0+YXNrKCcgICAgICBVc2VybmFtZTogJyk7CiAgICAgICAgICAgICRwYXNzd29yZCA9ICR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcignICAgICAgUGFzc3dvcmQ6ICcpOwogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW4sICR1c2VybmFtZSwgJHBhc3N3b3JkKTsKICAgICAgICAgICAgJHN0b3JlQXV0aCA9ICR0aGlzLT5jb25maWctPmdldCgnc3RvcmUtYXV0aHMnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgncmV0cnknID0+IHRydWUsICdzdG9yZUF1dGgnID0+ICRzdG9yZUF1dGgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBhcnJheSAgJGhlYWRlcnMKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvcmlnaW4KICAgICAqIEBwYXJhbSAgc3RyaW5nICR1cmwKICAgICAqIEByZXR1cm4gYXJyYXkgIHVwZGF0ZWQgaGVhZGVycyBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQXV0aGVudGljYXRpb25IZWFkZXIoYXJyYXkgJGhlYWRlcnMsICRvcmlnaW4sICR1cmwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG9yaWdpbikpIHsKICAgICAgICAgICAgJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgPSBudWxsOwogICAgICAgICAgICAkYXV0aCA9ICR0aGlzLT5pby0+Z2V0QXV0aGVudGljYXRpb24oJG9yaWdpbik7CiAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ2JlYXJlcicpIHsKICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogQmVhcmVyICcuJGF1dGhbJ3VzZXJuYW1lJ107CiAgICAgICAgICAgIH0gZWxzZWlmICgnZ2l0aHViLmNvbScgPT09ICRvcmlnaW4gJiYgJ3gtb2F1dGgtYmFzaWMnID09PSAkYXV0aFsncGFzc3dvcmQnXSkgewogICAgICAgICAgICAgICAgLy8gb25seSBhZGQgdGhlIGFjY2Vzc190b2tlbiBpZiBpdCBpcyBhY3R1YWxseSBhIGdpdGh1YiBBUEkgVVJMCiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15odHRwcz86Ly9hcGlcLmdpdGh1YlwuY29tL30nLCAkdXJsKSkgewogICAgICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogdG9rZW4gJy4kYXV0aFsndXNlcm5hbWUnXTsKICAgICAgICAgICAgICAgICAgICAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSA9ICdVc2luZyBHaXRIdWIgdG9rZW4gYXV0aGVudGljYXRpb24nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICBpbl9hcnJheSgkb3JpZ2luLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksIHRydWUpCiAgICAgICAgICAgICAgICAmJiBpbl9hcnJheSgkYXV0aFsncGFzc3dvcmQnXSwgYXJyYXkoJ29hdXRoMicsICdwcml2YXRlLXRva2VuJywgJ2dpdGxhYi1jaS10b2tlbicpLCB0cnVlKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ29hdXRoMicpIHsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVyc1tdID0gJ0F1dGhvcml6YXRpb246IEJlYXJlciAnLiRhdXRoWyd1c2VybmFtZSddOwogICAgICAgICAgICAgICAgICAgICRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlID0gJ1VzaW5nIEdpdExhYiBPQXV0aCB0b2tlbiBhdXRoZW50aWNhdGlvbic7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGF1dGhbJ3Bhc3N3b3JkJ10gPT09ICdwcml2YXRlLXRva2VuJyB8fCAkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ2dpdGxhYi1jaS10b2tlbicpIHsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVyc1tdID0gJ1BSSVZBVEUtVE9LRU46ICcuJGF1dGhbJ3VzZXJuYW1lJ107CiAgICAgICAgICAgICAgICAgICAgJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgPSAnVXNpbmcgR2l0TGFiIHByaXZhdGUgdG9rZW4gYXV0aGVudGljYXRpb24nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICAnYml0YnVja2V0Lm9yZycgPT09ICRvcmlnaW4KICAgICAgICAgICAgICAgICYmICR1cmwgIT09IEJpdGJ1Y2tldDo6T0FVVEgyX0FDQ0VTU19UT0tFTl9VUkwKICAgICAgICAgICAgICAgICYmICd4LXRva2VuLWF1dGgnID09PSAkYXV0aFsndXNlcm5hbWUnXQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlzUHVibGljQml0QnVja2V0RG93bmxvYWQoJHVybCkpIHsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVyc1tdID0gJ0F1dGhvcml6YXRpb246IEJlYXJlciAnIC4gJGF1dGhbJ3Bhc3N3b3JkJ107CiAgICAgICAgICAgICAgICAgICAgJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgPSAnVXNpbmcgQml0YnVja2V0IE9BdXRoIHRva2VuIGF1dGhlbnRpY2F0aW9uJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRhdXRoU3RyID0gYmFzZTY0X2VuY29kZSgkYXV0aFsndXNlcm5hbWUnXSAuICc6JyAuICRhdXRoWydwYXNzd29yZCddKTsKICAgICAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQXV0aG9yaXphdGlvbjogQmFzaWMgJy4kYXV0aFN0cjsKICAgICAgICAgICAgICAgICRhdXRoZW50aWNhdGlvbkRpc3BsYXlNZXNzYWdlID0gJ1VzaW5nIEhUVFAgYmFzaWMgYXV0aGVudGljYXRpb24gd2l0aCB1c2VybmFtZSAiJyAuICRhdXRoWyd1c2VybmFtZSddIC4gJyInOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGF1dGhlbnRpY2F0aW9uRGlzcGxheU1lc3NhZ2UgJiYgKCFpc3NldCgkdGhpcy0+ZGlzcGxheWVkT3JpZ2luQXV0aGVudGljYXRpb25zWyRvcmlnaW5dKSB8fCAkdGhpcy0+ZGlzcGxheWVkT3JpZ2luQXV0aGVudGljYXRpb25zWyRvcmlnaW5dICE9PSAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kaXNwbGF5ZWRPcmlnaW5BdXRoZW50aWNhdGlvbnNbJG9yaWdpbl0gPSAkYXV0aGVudGljYXRpb25EaXNwbGF5TWVzc2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkb3JpZ2luLCBhcnJheSgnYXBpLmJpdGJ1Y2tldC5vcmcnLCAnYXBpLmdpdGh1Yi5jb20nKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRBdXRoZW50aWNhdGlvbkhlYWRlcigkaGVhZGVycywgc3RyX3JlcGxhY2UoJ2FwaS4nLCAnJywgJG9yaWdpbiksICR1cmwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRoZWFkZXJzOwogICAgfQoKICAgIC8qKgogICAgICogQGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy81NTg0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsVG9CaXRCdWNrZXRGaWxlIFVSTCB0byBhIGZpbGUgYXQgYml0YnVja2V0Lm9yZy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgZ2l2ZW4gVVJMIGlzIGEgcHVibGljIEJpdEJ1Y2tldCBkb3dubG9hZCB3aGljaCByZXF1aXJlcyBubyBhdXRoZW50aWNhdGlvbi4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUHVibGljQml0QnVja2V0RG93bmxvYWQoJHVybFRvQml0QnVja2V0RmlsZSkKICAgIHsKICAgICAgICAkZG9tYWluID0gcGFyc2VfdXJsKCR1cmxUb0JpdEJ1Y2tldEZpbGUsIFBIUF9VUkxfSE9TVCk7CiAgICAgICAgaWYgKHN0cnBvcygkZG9tYWluLCAnYml0YnVja2V0Lm9yZycpID09PSBmYWxzZSkgewogICAgICAgICAgICAvLyBCaXRidWNrZXQgZG93bmxvYWRzIGFyZSBob3N0ZWQgb24gYW1hem9uYXdzLgogICAgICAgICAgICAvLyBXZSBkbyBub3QgbmVlZCB0byBhdXRoZW50aWNhdGUgdGhlcmUgYXQgYWxsCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHBhdGggPSBwYXJzZV91cmwoJHVybFRvQml0QnVja2V0RmlsZSwgUEhQX1VSTF9QQVRIKTsKCiAgICAgICAgLy8gUGF0aCBmb3IgYSBwdWJsaWMgZG93bmxvYWQgZm9sbG93cyB0aGlzIHBhdHRlcm4gL3t1c2VyfS97cmVwb30vZG93bmxvYWRzL3t3aGF0ZXZlcn0KICAgICAgICAvLyB7QGxpbmsgaHR0cHM6Ly9ibG9nLmJpdGJ1Y2tldC5vcmcvMjAwOS8wNC8xMi9uZXctZmVhdHVyZS1kb3dubG9hZHMvfQogICAgICAgICRwYXRoUGFydHMgPSBleHBsb2RlKCcvJywgJHBhdGgpOwoKICAgICAgICByZXR1cm4gY291bnQoJHBhdGhQYXJ0cykgPj0gNCAmJiAkcGF0aFBhcnRzWzNdID09ICdkb3dubG9hZHMnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7CgpAdHJpZ2dlcl9lcnJvcignQ29tcG9zZXJcVXRpbFxNZXRhZGF0YU1pbmlmaWVyIGlzIGRlcHJlY2F0ZWQsIHVzZSBDb21wb3NlclxNZXRhZGF0YU1pbmlmaWVyXE1ldGFkYXRhTWluaWZpZXIgZnJvbSBjb21wb3Nlci9tZXRhZGF0YS1taW5pZmllciBpbnN0ZWFkLicsIEVfVVNFUl9ERVBSRUNBVEVEKTsKCi8qKgogKiBAZGVwcmVjYXRlZCBVc2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyIGluc3RlYWQKICovCmNsYXNzIE1ldGFkYXRhTWluaWZpZXIgZXh0ZW5kcyBcQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllclxNZXRhZGF0YU1pbmlmaWVyCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgUm9zaGFuIEdhdXRhbSA8cm9zaGFuLmdhdXRhbUBob3RtYWlsLmNvbT4KICovCmNsYXNzIEdpdExhYgp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcm90ZWN0ZWQgJGh0dHBEb3dubG9hZGVyOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAkaW8gICAgICAgICAgICAgVGhlIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgICAgICRjb25maWcgICAgICAgICBUaGUgY29tcG9zZXIgY29uZmlndXJhdGlvbgogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyAgICAgICAgUHJvY2VzcyBpbnN0YW5jZSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICAkaHR0cERvd25sb2FkZXIgUmVtb3RlIEZpbGVzeXN0ZW0sIGluamVjdGFibGUgZm9yIG1vY2tpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlciA/OiBGYWN0b3J5OjpjcmVhdGVIdHRwRG93bmxvYWRlcigkdGhpcy0+aW8sICRjb25maWcpOwogICAgfQoKICAgIC8qKgogICAgICogQXR0ZW1wdHMgdG8gYXV0aG9yaXplIGEgR2l0TGFiIGRvbWFpbiB2aWEgT0F1dGguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgR2l0TGFiIGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aCgkb3JpZ2luVXJsKQogICAgewogICAgICAgIC8vIGJlZm9yZSBjb21wb3NlciAxLjksIG9yaWdpbiBVUkxzIGhhZCBubyBwb3J0IG51bWJlciBpbiB0aGVtCiAgICAgICAgJGJjT3JpZ2luVXJsID0gcHJlZ19yZXBsYWNlKCd7OlxkK30nLCAnJywgJG9yaWdpblVybCk7CgogICAgICAgIGlmICghaW5fYXJyYXkoJG9yaWdpblVybCwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRsYWItZG9tYWlucycpLCB0cnVlKSAmJiAhaW5fYXJyYXkoJGJjT3JpZ2luVXJsLCAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJyksIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIGlmIGF2YWlsYWJsZSB1c2UgdG9rZW4gZnJvbSBnaXQgY29uZmlnCiAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgY29uZmlnIGdpdGxhYi5hY2Nlc3N0b2tlbicsICRvdXRwdXQpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgdHJpbSgkb3V0cHV0KSwgJ29hdXRoMicpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIGRlcGxveSB0b2tlbiBmcm9tIGdpdCBjb25maWcKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBjb25maWcgZ2l0bGFiLmRlcGxveXRva2VuLnVzZXInLCAkdG9rZW5Vc2VyKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBnaXRsYWIuZGVwbG95dG9rZW4udG9rZW4nLCAkdG9rZW5QYXNzd29yZCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCB0cmltKCR0b2tlblVzZXIpLCB0cmltKCR0b2tlblBhc3N3b3JkKSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGlmIGF2YWlsYWJsZSB1c2UgdG9rZW4gZnJvbSBjb21wb3NlciBjb25maWcKICAgICAgICAkYXV0aFRva2VucyA9ICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLXRva2VuJyk7CgogICAgICAgIGlmIChpc3NldCgkYXV0aFRva2Vuc1skb3JpZ2luVXJsXSkpIHsKICAgICAgICAgICAgJHRva2VuID0gJGF1dGhUb2tlbnNbJG9yaWdpblVybF07CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGF1dGhUb2tlbnNbJGJjT3JpZ2luVXJsXSkpIHsKICAgICAgICAgICAgJHRva2VuID0gJGF1dGhUb2tlbnNbJGJjT3JpZ2luVXJsXTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdG9rZW4pKSB7CiAgICAgICAgICAgICR1c2VybmFtZSA9IGlzX2FycmF5KCR0b2tlbikgJiYgYXJyYXlfa2V5X2V4aXN0cygidXNlcm5hbWUiLCAkdG9rZW4pID8gJHRva2VuWyJ1c2VybmFtZSJdIDogJHRva2VuOwogICAgICAgICAgICAkcGFzc3dvcmQgPSBpc19hcnJheSgkdG9rZW4pICYmIGFycmF5X2tleV9leGlzdHMoInRva2VuIiwgJHRva2VuKSA/ICR0b2tlblsidG9rZW4iXSA6ICdwcml2YXRlLXRva2VuJzsKICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkdXNlcm5hbWUsICRwYXNzd29yZCk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dGhvcml6ZXMgYSBHaXRMYWIgZG9tYWluIGludGVyYWN0aXZlbHkgdmlhIE9BdXRoLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNjaGVtZSAgICBTY2hlbWUgdXNlZCBpbiB0aGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgR2l0TGFiIGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgICBUaGUgcmVhc29uIHRoaXMgYXV0aG9yaXphdGlvbiBpcyByZXF1aXJlZAogICAgICoKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEB0aHJvd3MgVHJhbnNwb3J0RXhjZXB0aW9ufFxFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJHNjaGVtZSwgJG9yaWdpblVybCwgJG1lc3NhZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICgkbWVzc2FnZSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG1lc3NhZ2UpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJ0EgdG9rZW4gd2lsbCBiZSBjcmVhdGVkIGFuZCBzdG9yZWQgaW4gIiVzIiwgeW91ciBwYXNzd29yZCB3aWxsIG5ldmVyIGJlIHN0b3JlZCcsICR0aGlzLT5jb25maWctPmdldEF1dGhDb25maWdTb3VyY2UoKS0+Z2V0TmFtZSgpKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdUbyByZXZva2UgYWNjZXNzIHRvIHRoaXMgdG9rZW4geW91IGNhbiB2aXNpdCAnLiRzY2hlbWUuJzovLycuJG9yaWdpblVybC4nL3Byb2ZpbGUvYXBwbGljYXRpb25zJyk7CgogICAgICAgICRhdHRlbXB0Q291bnRlciA9IDA7CgogICAgICAgIHdoaWxlICgkYXR0ZW1wdENvdW50ZXIrKyA8IDUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5jcmVhdGVUb2tlbigkc2NoZW1lLCAkb3JpZ2luVXJsKTsKICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyA0MDEgaXMgYmFkIGNyZWRlbnRpYWxzLAogICAgICAgICAgICAgICAgLy8gNDAzIGlzIG1heCBsb2dpbiBhdHRlbXB0cyBleGNlZWRlZAogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRlLT5nZXRDb2RlKCksIGFycmF5KDQwMywgNDAxKSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoNDAxID09PSAkZS0+Z2V0Q29kZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXNwb25zZSA9IGpzb25fZGVjb2RlKCRlLT5nZXRSZXNwb25zZSgpLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXNwb25zZVsnZXJyb3InXSkgJiYgJHJlc3BvbnNlWydlcnJvciddID09PSAnaW52YWxpZF9ncmFudCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignQmFkIGNyZWRlbnRpYWxzLiBJZiB5b3UgaGF2ZSB0d28gZmFjdG9yIGF1dGhlbnRpY2F0aW9uIGVuYWJsZWQgeW91IHdpbGwgaGF2ZSB0byBtYW51YWxseSBjcmVhdGUgYSBwZXJzb25hbCBhY2Nlc3MgdG9rZW4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignQmFkIGNyZWRlbnRpYWxzLicpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdNYXhpbXVtIG51bWJlciBvZiBsb2dpbiBhdHRlbXB0cyBleGNlZWRlZC4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci4nKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignWW91IGNhbiBhbHNvIG1hbnVhbGx5IGNyZWF0ZSBhIHBlcnNvbmFsIGFjY2VzcyB0b2tlbiBlbmFibGluZyB0aGUgInJlYWRfYXBpIiBzY29wZSBhdCAnLiRzY2hlbWUuJzovLycuJG9yaWdpblVybC4nL3Byb2ZpbGUvcGVyc29uYWxfYWNjZXNzX3Rva2VucycpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignQWRkIGl0IHVzaW5nICJjb21wb3NlciBjb25maWcgLS1nbG9iYWwgLS1hdXRoIGdpdGxhYi10b2tlbi4nLiRvcmlnaW5VcmwuJyA8dG9rZW4+IicpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkb3JpZ2luVXJsLCAkcmVzcG9uc2VbJ2FjY2Vzc190b2tlbiddLCAnb2F1dGgyJyk7CgogICAgICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpbiB1c2VyIGNvbmZpZyBpbiBhdXRoIGZpbGUKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5hZGRDb25maWdTZXR0aW5nKCdnaXRsYWItb2F1dGguJy4kb3JpZ2luVXJsLCAkcmVzcG9uc2VbJ2FjY2Vzc190b2tlbiddKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdJbnZhbGlkIEdpdExhYiBjcmVkZW50aWFscyA1IHRpbWVzIGluIGEgcm93LCBhYm9ydGluZy4nKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZVRva2VuKCRzY2hlbWUsICRvcmlnaW5VcmwpCiAgICB7CiAgICAgICAgJHVzZXJuYW1lID0gJHRoaXMtPmlvLT5hc2soJ1VzZXJuYW1lOiAnKTsKICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJ1Bhc3N3b3JkOiAnKTsKCiAgICAgICAgJGhlYWRlcnMgPSBhcnJheSgnQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTsKCiAgICAgICAgJGFwaVVybCA9ICRvcmlnaW5Vcmw7CiAgICAgICAgJGRhdGEgPSBodHRwX2J1aWxkX3F1ZXJ5KGFycmF5KAogICAgICAgICAgICAndXNlcm5hbWUnID0+ICR1c2VybmFtZSwKICAgICAgICAgICAgJ3Bhc3N3b3JkJyA9PiAkcGFzc3dvcmQsCiAgICAgICAgICAgICdncmFudF90eXBlJyA9PiAncGFzc3dvcmQnLAogICAgICAgICksIG51bGwsICcmJyk7CiAgICAgICAgJG9wdGlvbnMgPSBhcnJheSgKICAgICAgICAgICAgJ3JldHJ5LWF1dGgtZmFpbHVyZScgPT4gZmFsc2UsCiAgICAgICAgICAgICdodHRwJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICdtZXRob2QnID0+ICdQT1NUJywKICAgICAgICAgICAgICAgICdoZWFkZXInID0+ICRoZWFkZXJzLAogICAgICAgICAgICAgICAgJ2NvbnRlbnQnID0+ICRkYXRhLAogICAgICAgICAgICApLAogICAgICAgICk7CgogICAgICAgICR0b2tlbiA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRzY2hlbWUuJzovLycuJGFwaVVybC4nL29hdXRoL3Rva2VuJywgJG9wdGlvbnMpLT5kZWNvZGVKc29uKCk7CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignVG9rZW4gc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQnKTsKCiAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENhQnVuZGxlXENhQnVuZGxlOwoKLyoqCiAqIEBhdXRob3IgQ2hyaXMgU21pdGggPGNocmlzQGNzMjc4Lm9yZz4KICovCmZpbmFsIGNsYXNzIFRsc0hlbHBlcgp7CiAgICAvKioKICAgICAqIE1hdGNoIGhvc3RuYW1lIGFnYWluc3QgYSBjZXJ0aWZpY2F0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRjZXJ0aWZpY2F0ZSBYLjUwOSBjZXJ0aWZpY2F0ZQogICAgICogQHBhcmFtIHN0cmluZyAkaG9zdG5hbWUgICAgSG9zdG5hbWUgaW4gdGhlIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAkY24gICAgICAgICAgU2V0IHRvIHRoZSBjb21tb24gbmFtZSBvZiB0aGUgY2VydGlmaWNhdGUgaWZmIG1hdGNoIGZvdW5kCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2hlY2tDZXJ0aWZpY2F0ZUhvc3QoJGNlcnRpZmljYXRlLCAkaG9zdG5hbWUsICYkY24gPSBudWxsKQogICAgewogICAgICAgICRuYW1lcyA9IHNlbGY6OmdldENlcnRpZmljYXRlTmFtZXMoJGNlcnRpZmljYXRlKTsKCiAgICAgICAgaWYgKGVtcHR5KCRuYW1lcykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGNvbWJpbmVkTmFtZXMgPSBhcnJheV9tZXJnZSgkbmFtZXNbJ3NhbiddLCBhcnJheSgkbmFtZXNbJ2NuJ10pKTsKICAgICAgICAkaG9zdG5hbWUgPSBzdHJ0b2xvd2VyKCRob3N0bmFtZSk7CgogICAgICAgIGZvcmVhY2ggKCRjb21iaW5lZE5hbWVzIGFzICRjZXJ0TmFtZSkgewogICAgICAgICAgICAkbWF0Y2hlciA9IHNlbGY6OmNlcnROYW1lTWF0Y2hlcigkY2VydE5hbWUpOwoKICAgICAgICAgICAgaWYgKCRtYXRjaGVyICYmICRtYXRjaGVyKCRob3N0bmFtZSkpIHsKICAgICAgICAgICAgICAgICRjbiA9ICRuYW1lc1snY24nXTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCBETlMgbmFtZXMgb3V0IG9mIGFuIFguNTA5IGNlcnRpZmljYXRlLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkY2VydGlmaWNhdGUgWC41MDkgY2VydGlmaWNhdGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDZXJ0aWZpY2F0ZU5hbWVzKCRjZXJ0aWZpY2F0ZSkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJGNlcnRpZmljYXRlKSkgewogICAgICAgICAgICAkaW5mbyA9ICRjZXJ0aWZpY2F0ZTsKICAgICAgICB9IGVsc2VpZiAoQ2FCdW5kbGU6OmlzT3BlbnNzbFBhcnNlU2FmZSgpKSB7CiAgICAgICAgICAgICRpbmZvID0gb3BlbnNzbF94NTA5X3BhcnNlKCRjZXJ0aWZpY2F0ZSwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkaW5mb1snc3ViamVjdCddWydjb21tb25OYW1lJ10pKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1vbk5hbWUgPSBzdHJ0b2xvd2VyKCRpbmZvWydzdWJqZWN0J11bJ2NvbW1vbk5hbWUnXSk7CiAgICAgICAgJHN1YmplY3RBbHROYW1lcyA9IGFycmF5KCk7CgogICAgICAgIGlmIChpc3NldCgkaW5mb1snZXh0ZW5zaW9ucyddWydzdWJqZWN0QWx0TmFtZSddKSkgewogICAgICAgICAgICAkc3ViamVjdEFsdE5hbWVzID0gcHJlZ19zcGxpdCgne1xzKixccyp9JywgJGluZm9bJ2V4dGVuc2lvbnMnXVsnc3ViamVjdEFsdE5hbWUnXSk7CiAgICAgICAgICAgICRzdWJqZWN0QWx0TmFtZXMgPSBhcnJheV9maWx0ZXIoYXJyYXlfbWFwKGZ1bmN0aW9uICgkbmFtZSkgewogICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkbmFtZSwgJ0ROUzonKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHJ0b2xvd2VyKGx0cmltKHN1YnN0cigkbmFtZSwgNCkpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfSwgJHN1YmplY3RBbHROYW1lcykpOwogICAgICAgICAgICAkc3ViamVjdEFsdE5hbWVzID0gYXJyYXlfdmFsdWVzKCRzdWJqZWN0QWx0TmFtZXMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAnY24nID0+ICRjb21tb25OYW1lLAogICAgICAgICAgICAnc2FuJyA9PiAkc3ViamVjdEFsdE5hbWVzLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGNlcnRpZmljYXRlIHBpbi4KICAgICAqCiAgICAgKiBCeSBLZXZpbiBNY0FydGh1ciBvZiBTdG9ybVRpZGUgRGlnaXRhbCBTdHVkaW9zIEluYy4KICAgICAqIEBLZXZpblNNY0FydGh1ciAvIGh0dHBzOi8vZ2l0aHViLmNvbS9TdG9ybVRpZGUKICAgICAqCiAgICAgKiBTZWUgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL2RyYWZ0LWlldGYtd2Vic2VjLWtleS1waW5uaW5nLTAyCiAgICAgKgogICAgICogVGhpcyBtZXRob2Qgd2FzIGFkYXB0ZWQgZnJvbSBTc2x1cnAuCiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vRXZhbkRvdFByby9Tc2x1cnAKICAgICAqCiAgICAgKiAoYykgRXZhbiBDb3VyeSA8bWVAZXZhbmNvdXJ5LmNvbT4KICAgICAqCiAgICAgKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2Ugc2VlIGJlbG93OgogICAgICoKICAgICAqIENvcHlyaWdodCAoYykgMjAxMywgRXZhbiBDb3VyeQogICAgICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICAgICAqCiAgICAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLAogICAgICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgogICAgICoKICAgICAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICAgICAqICAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKgogICAgICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogICAgICogICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogICAgICogICAgICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAgICAgKgogICAgICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFORAogICAgICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKICAgICAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKICAgICAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IKICAgICAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwogICAgICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOwogICAgICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OCiAgICAgKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogICAgICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMKICAgICAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENlcnRpZmljYXRlRmluZ2VycHJpbnQoJGNlcnRpZmljYXRlKQogICAgewogICAgICAgICRwdWJrZXlkZXRhaWxzID0gb3BlbnNzbF9wa2V5X2dldF9kZXRhaWxzKG9wZW5zc2xfZ2V0X3B1YmxpY2tleSgkY2VydGlmaWNhdGUpKTsKICAgICAgICAkcHVia2V5cGVtID0gJHB1YmtleWRldGFpbHNbJ2tleSddOwogICAgICAgIC8vQ29udmVydCBQRU0gdG8gREVSIGJlZm9yZSBTSEExJ2luZwogICAgICAgICRzdGFydCA9ICctLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLSc7CiAgICAgICAgJGVuZCA9ICctLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0nOwogICAgICAgICRwZW10cmltID0gc3Vic3RyKCRwdWJrZXlwZW0sIHN0cnBvcygkcHVia2V5cGVtLCAkc3RhcnQpICsgc3RybGVuKCRzdGFydCksIChzdHJsZW4oJHB1YmtleXBlbSkgLSBzdHJwb3MoJHB1YmtleXBlbSwgJGVuZCkpICogKC0xKSk7CiAgICAgICAgJGRlciA9IGJhc2U2NF9kZWNvZGUoJHBlbXRyaW0pOwoKICAgICAgICByZXR1cm4gc2hhMSgkZGVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRlc3QgaWYgaXQgaXMgc2FmZSB0byB1c2UgdGhlIFBIUCBmdW5jdGlvbiBvcGVuc3NsX3g1MDlfcGFyc2UoKS4KICAgICAqCiAgICAgKiBUaGlzIGNoZWNrcyBpZiBPcGVuU1NMIGV4dGVuc2lvbnMgaXMgdnVsbmVyYWJsZSB0byByZW1vdGUgY29kZSBleGVjdXRpb24KICAgICAqIHZpYSB0aGUgZXhwbG9pdCBkb2N1bWVudGVkIGFzIENWRS0yMDEzLTY0MjAuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNPcGVuc3NsUGFyc2VTYWZlKCkKICAgIHsKICAgICAgICByZXR1cm4gQ2FCdW5kbGU6OmlzT3BlbnNzbFBhcnNlU2FmZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydCBjZXJ0aWZpY2F0ZSBuYW1lIGludG8gbWF0Y2hpbmcgZnVuY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2VydE5hbWUgQ04vU0FOCiAgICAgKgogICAgICogQHJldHVybiBjYWxsYWJsZXx2b2lkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNlcnROYW1lTWF0Y2hlcigkY2VydE5hbWUpCiAgICB7CiAgICAgICAgJHdpbGRjYXJkcyA9IHN1YnN0cl9jb3VudCgkY2VydE5hbWUsICcqJyk7CgogICAgICAgIGlmICgwID09PSAkd2lsZGNhcmRzKSB7CiAgICAgICAgICAgIC8vIExpdGVyYWwgbWF0Y2guCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGhvc3RuYW1lKSB1c2UgKCRjZXJ0TmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRob3N0bmFtZSA9PT0gJGNlcnROYW1lOwogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09ICR3aWxkY2FyZHMpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHMgPSBleHBsb2RlKCcuJywgJGNlcnROYW1lKTsKCiAgICAgICAgICAgIGlmICgzID4gY291bnQoJGNvbXBvbmVudHMpKSB7CiAgICAgICAgICAgICAgICAvLyBNdXN0IGhhdmUgMysgY29tcG9uZW50cwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZmlyc3RDb21wb25lbnQgPSAkY29tcG9uZW50c1swXTsKCiAgICAgICAgICAgIC8vIFdpbGRjYXJkIG11c3QgYmUgdGhlIGxhc3QgY2hhcmFjdGVyLgogICAgICAgICAgICBpZiAoJyonICE9PSAkZmlyc3RDb21wb25lbnRbc3RybGVuKCRmaXJzdENvbXBvbmVudCkgLSAxXSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkd2lsZGNhcmRSZWdleCA9IHByZWdfcXVvdGUoJGNlcnROYW1lKTsKICAgICAgICAgICAgJHdpbGRjYXJkUmVnZXggPSBzdHJfcmVwbGFjZSgnXFwqJywgJ1thLXowLTktXSsnLCAkd2lsZGNhcmRSZWdleCk7CiAgICAgICAgICAgICR3aWxkY2FyZFJlZ2V4ID0gInteeyR3aWxkY2FyZFJlZ2V4fSR9IjsKCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGhvc3RuYW1lKSB1c2UgKCR3aWxkY2FyZFJlZ2V4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMSA9PT0gcHJlZ19tYXRjaCgkd2lsZGNhcmRSZWdleCwgJGhvc3RuYW1lKTsKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXENhQnVuZGxlXENhQnVuZGxlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxVdGlsXEh0dHBcUHJveHlNYW5hZ2VyOwp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CgovKioKICogQWxsb3dzIHRoZSBjcmVhdGlvbiBvZiBhIGJhc2ljIGNvbnRleHQgc3VwcG9ydGluZyBodHRwIHByb3h5CiAqCiAqIEBhdXRob3IgSm9yZGFuIEFsbGlvdCA8am9yZGFuLmFsbGlvdEBnbWFpbC5jb20+CiAqIEBhdXRob3IgTWFya3VzIFRhY2tlciA8bUBjb2RlcmJ5aGVhcnQuZGU+CiAqLwpmaW5hbCBjbGFzcyBTdHJlYW1Db250ZXh0RmFjdG9yeQp7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBjb250ZXh0IHN1cHBvcnRpbmcgSFRUUCBwcm94aWVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsIFVSTCB0aGUgY29udGV4dCBpcyB0byBiZSB1c2VkIGZvcgogICAgICogQHBzYWxtLXBhcmFtIGFycmF5e2h0dHA6IGFycmF5e2ZvbGxvd19sb2NhdGlvbj86IGludCwgbWF4X3JlZGlyZWN0cz86IGludCwgaGVhZGVyPzogc3RyaW5nfGFycmF5PHN0cmluZywgc3RyaW5nfGludD59fSAkZGVmYXVsdE9wdGlvbnMKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICAgICAgICAgJGRlZmF1bHRPcHRpb25zIE9wdGlvbnMgdG8gbWVyZ2Ugd2l0aCB0aGUgZGVmYXVsdAogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAkZGVmYXVsdFBhcmFtcyAgUGFyYW1ldGVycyB0byBzcGVjaWZ5IG9uIHRoZSBjb250ZXh0CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIGlmIGh0dHBzIHByb3h5IHJlcXVpcmVkIGFuZCBPcGVuU1NMIHVuaW5zdGFsbGVkCiAgICAgKiBAcmV0dXJuIHJlc291cmNlICAgICAgICAgIERlZmF1bHQgY29udGV4dAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRleHQoJHVybCwgYXJyYXkgJGRlZmF1bHRPcHRpb25zID0gYXJyYXkoKSwgYXJyYXkgJGRlZmF1bHRQYXJhbXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRvcHRpb25zID0gYXJyYXkoJ2h0dHAnID0+IGFycmF5KAogICAgICAgICAgICAvLyBzcGVjaWZ5IGRlZmF1bHRzIGFnYWluIHRvIHRyeSBhbmQgd29yayBiZXR0ZXIgd2l0aCBjdXJsd3JhcHBlcnMgZW5hYmxlZAogICAgICAgICAgICAnZm9sbG93X2xvY2F0aW9uJyA9PiAxLAogICAgICAgICAgICAnbWF4X3JlZGlyZWN0cycgPT4gMjAsCiAgICAgICAgKSk7CgogICAgICAgICRvcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJG9wdGlvbnMsIHNlbGY6OmluaXRPcHRpb25zKCR1cmwsICRkZWZhdWx0T3B0aW9ucykpOwogICAgICAgIHVuc2V0KCRkZWZhdWx0T3B0aW9uc1snaHR0cCddWydoZWFkZXInXSk7CiAgICAgICAgJG9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkb3B0aW9ucywgJGRlZmF1bHRPcHRpb25zKTsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IHNlbGY6OmZpeEh0dHBIZWFkZXJGaWVsZCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RyZWFtX2NvbnRleHRfY3JlYXRlKCRvcHRpb25zLCAkZGVmYXVsdFBhcmFtcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqIEBwYXJhbSBhcnJheSAgJG9wdGlvbnMKICAgICAqIEBwYXJhbSBib29sICAgJGZvckN1cmwgV2hlbiB0cnVlLCB3aWxsIG5vdCBhZGQgcHJveHkgdmFsdWVzIGFzIHRoZXNlIGFyZSBoYW5kbGVkIHNlcGFyYXRlbHkKICAgICAqIEBwc2FsbS1yZXR1cm4gYXJyYXl7aHR0cDp7aGVhZGVyOiBzdHJpbmdbXSwgcHJveHk/OiBzdHJpbmcsIHJlcXVlc3RfZnVsbHVyaTogYm9vbH0sIHNzbDogYXJyYXl9CiAgICAgKiBAcmV0dXJuIGFycmF5IGZvcm1hdHRlZCBhcyBhIHN0cmVhbSBjb250ZXh0IGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaW5pdE9wdGlvbnMoJHVybCwgYXJyYXkgJG9wdGlvbnMsICRmb3JDdXJsID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBoZWFkZXJzIGFyZSBpbiBhbiBhcnJheSBmb3JtCiAgICAgICAgaWYgKCFpc3NldCgkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10gPSBhcnJheSgpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNfc3RyaW5nKCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSA9IGV4cGxvZGUoIlxyXG4iLCAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXSk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgc3RyZWFtIHByb3h5IG9wdGlvbnMgaWYgdGhlcmUgaXMgYSBwcm94eQogICAgICAgIGlmICghJGZvckN1cmwpIHsKICAgICAgICAgICAgJHByb3h5ID0gUHJveHlNYW5hZ2VyOjpnZXRJbnN0YW5jZSgpLT5nZXRQcm94eUZvclJlcXVlc3QoJHVybCk7CiAgICAgICAgICAgIGlmICgkcHJveHlPcHRpb25zID0gJHByb3h5LT5nZXRDb250ZXh0T3B0aW9ucygpKSB7CiAgICAgICAgICAgICAgICAkaXNIdHRwc1JlcXVlc3QgPSAwID09PSBzdHJwb3MoJHVybCwgJ2h0dHBzOi8vJyk7CgogICAgICAgICAgICAgICAgaWYgKCRwcm94eS0+aXNTZWN1cmUoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1lvdSBtdXN0IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24gdG8gdXNlIGEgc2VjdXJlIHByb3h5LicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJGlzSHR0cHNSZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1lvdSBtdXN0IGVuYWJsZSB0aGUgY3VybCBleHRlbnNpb24gdG8gbWFrZSBodHRwcyByZXF1ZXN0cyB0aHJvdWdoIGEgc2VjdXJlIHByb3h5LicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkaXNIdHRwc1JlcXVlc3QgJiYgIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1lvdSBtdXN0IGVuYWJsZSB0aGUgb3BlbnNzbCBleHRlbnNpb24gdG8gbWFrZSBodHRwcyByZXF1ZXN0cyB0aHJvdWdoIGEgcHJveHkuJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSGVhZGVyIHdpbGwgYmUgYSBQcm94eS1BdXRob3JpemF0aW9uIHN0cmluZyBvciBub3Qgc2V0CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHByb3h5T3B0aW9uc1snaHR0cCddWydoZWFkZXInXSkpIHsKICAgICAgICAgICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gJHByb3h5T3B0aW9uc1snaHR0cCddWydoZWFkZXInXTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkcHJveHlPcHRpb25zWydodHRwJ11bJ2hlYWRlciddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRvcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJG9wdGlvbnMsICRwcm94eU9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgJHBocFZlcnNpb24gPSAnSEhWTSAnIC4gSEhWTV9WRVJTSU9OOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwaHBWZXJzaW9uID0gJ1BIUCAnIC4gUEhQX01BSk9SX1ZFUlNJT04gLiAnLicgLiBQSFBfTUlOT1JfVkVSU0lPTiAuICcuJyAuIFBIUF9SRUxFQVNFX1ZFUlNJT047CiAgICAgICAgfQoKICAgICAgICBpZiAoJGZvckN1cmwpIHsKICAgICAgICAgICAgJGN1cmwgPSBjdXJsX3ZlcnNpb24oKTsKICAgICAgICAgICAgJGh0dHBWZXJzaW9uID0gJ2NVUkwgJy4kY3VybFsndmVyc2lvbiddOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRodHRwVmVyc2lvbiA9ICdzdHJlYW1zJzsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pIHx8IGZhbHNlID09PSBzdHJpcG9zKGltcGxvZGUoJycsICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSwgJ3VzZXItYWdlbnQnKSkgewogICAgICAgICAgICAkb3B0aW9uc1snaHR0cCddWydoZWFkZXInXVtdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICdVc2VyLUFnZW50OiBDb21wb3Nlci8lcyAoJXM7ICVzOyAlczsgJXMlcyknLAogICAgICAgICAgICAgICAgQ29tcG9zZXI6OmdldFZlcnNpb24oKSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uX2V4aXN0cygncGhwX3VuYW1lJykgPyBwaHBfdW5hbWUoJ3MnKSA6ICdVbmtub3duJywKICAgICAgICAgICAgICAgIGZ1bmN0aW9uX2V4aXN0cygncGhwX3VuYW1lJykgPyBwaHBfdW5hbWUoJ3InKSA6ICdVbmtub3duJywKICAgICAgICAgICAgICAgICRwaHBWZXJzaW9uLAogICAgICAgICAgICAgICAgJGh0dHBWZXJzaW9uLAogICAgICAgICAgICAgICAgZ2V0ZW52KCdDSScpID8gJzsgQ0knIDogJycKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRUbHNEZWZhdWx0cyhhcnJheSAkb3B0aW9ucywgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgICRjaXBoZXJzID0gaW1wbG9kZSgnOicsIGFycmF5KAogICAgICAgICAgICAnRUNESEUtUlNBLUFFUzEyOC1HQ00tU0hBMjU2JywKICAgICAgICAgICAgJ0VDREhFLUVDRFNBLUFFUzEyOC1HQ00tU0hBMjU2JywKICAgICAgICAgICAgJ0VDREhFLVJTQS1BRVMyNTYtR0NNLVNIQTM4NCcsCiAgICAgICAgICAgICdFQ0RIRS1FQ0RTQS1BRVMyNTYtR0NNLVNIQTM4NCcsCiAgICAgICAgICAgICdESEUtUlNBLUFFUzEyOC1HQ00tU0hBMjU2JywKICAgICAgICAgICAgJ0RIRS1EU1MtQUVTMTI4LUdDTS1TSEEyNTYnLAogICAgICAgICAgICAna0VESCtBRVNHQ00nLAogICAgICAgICAgICAnRUNESEUtUlNBLUFFUzEyOC1TSEEyNTYnLAogICAgICAgICAgICAnRUNESEUtRUNEU0EtQUVTMTI4LVNIQTI1NicsCiAgICAgICAgICAgICdFQ0RIRS1SU0EtQUVTMTI4LVNIQScsCiAgICAgICAgICAgICdFQ0RIRS1FQ0RTQS1BRVMxMjgtU0hBJywKICAgICAgICAgICAgJ0VDREhFLVJTQS1BRVMyNTYtU0hBMzg0JywKICAgICAgICAgICAgJ0VDREhFLUVDRFNBLUFFUzI1Ni1TSEEzODQnLAogICAgICAgICAgICAnRUNESEUtUlNBLUFFUzI1Ni1TSEEnLAogICAgICAgICAgICAnRUNESEUtRUNEU0EtQUVTMjU2LVNIQScsCiAgICAgICAgICAgICdESEUtUlNBLUFFUzEyOC1TSEEyNTYnLAogICAgICAgICAgICAnREhFLVJTQS1BRVMxMjgtU0hBJywKICAgICAgICAgICAgJ0RIRS1EU1MtQUVTMTI4LVNIQTI1NicsCiAgICAgICAgICAgICdESEUtUlNBLUFFUzI1Ni1TSEEyNTYnLAogICAgICAgICAgICAnREhFLURTUy1BRVMyNTYtU0hBJywKICAgICAgICAgICAgJ0RIRS1SU0EtQUVTMjU2LVNIQScsCiAgICAgICAgICAgICdBRVMxMjgtR0NNLVNIQTI1NicsCiAgICAgICAgICAgICdBRVMyNTYtR0NNLVNIQTM4NCcsCiAgICAgICAgICAgICdBRVMxMjgtU0hBMjU2JywKICAgICAgICAgICAgJ0FFUzI1Ni1TSEEyNTYnLAogICAgICAgICAgICAnQUVTMTI4LVNIQScsCiAgICAgICAgICAgICdBRVMyNTYtU0hBJywKICAgICAgICAgICAgJ0FFUycsCiAgICAgICAgICAgICdDQU1FTExJQScsCiAgICAgICAgICAgICdERVMtQ0JDMy1TSEEnLAogICAgICAgICAgICAnIWFOVUxMJywKICAgICAgICAgICAgJyFlTlVMTCcsCiAgICAgICAgICAgICchRVhQT1JUJywKICAgICAgICAgICAgJyFERVMnLAogICAgICAgICAgICAnIVJDNCcsCiAgICAgICAgICAgICchTUQ1JywKICAgICAgICAgICAgJyFQU0snLAogICAgICAgICAgICAnIWFFQ0RIJywKICAgICAgICAgICAgJyFFREgtRFNTLURFUy1DQkMzLVNIQScsCiAgICAgICAgICAgICchRURILVJTQS1ERVMtQ0JDMy1TSEEnLAogICAgICAgICAgICAnIUtSQjUtREVTLUNCQzMtU0hBJywKICAgICAgICApKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ05fbWF0Y2ggYW5kIFNOSV9zZXJ2ZXJfbmFtZSBhcmUgb25seSBrbm93biBvbmNlIGEgVVJMIGlzIHBhc3NlZC4KICAgICAgICAgKiBUaGV5IHdpbGwgYmUgc2V0IGluIHRoZSBnZXRPcHRpb25zRm9yVXJsKCkgbWV0aG9kIHdoaWNoIHJlY2VpdmVzIGEgVVJMLgogICAgICAgICAqCiAgICAgICAgICogY2FmaWxlIG9yIGNhcGF0aCBjYW4gYmUgb3ZlcnJpZGRlbiBieSBwYXNzaW5nIGluIHRob3NlIG9wdGlvbnMgdG8gY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgJGRlZmF1bHRzID0gYXJyYXkoCiAgICAgICAgICAgICdzc2wnID0+IGFycmF5KAogICAgICAgICAgICAgICAgJ2NpcGhlcnMnID0+ICRjaXBoZXJzLAogICAgICAgICAgICAgICAgJ3ZlcmlmeV9wZWVyJyA9PiB0cnVlLAogICAgICAgICAgICAgICAgJ3ZlcmlmeV9kZXB0aCcgPT4gNywKICAgICAgICAgICAgICAgICdTTklfZW5hYmxlZCcgPT4gdHJ1ZSwKICAgICAgICAgICAgICAgICdjYXB0dXJlX3BlZXJfY2VydCcgPT4gdHJ1ZSwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3NzbCddKSkgewogICAgICAgICAgICAkZGVmYXVsdHNbJ3NzbCddID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJGRlZmF1bHRzWydzc2wnXSwgJG9wdGlvbnNbJ3NzbCddKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEF0dGVtcHQgdG8gZmluZCBhIGxvY2FsIGNhZmlsZSBvciB0aHJvdyBhbiBleGNlcHRpb24gaWYgbm9uZSBwcmUtc2V0CiAgICAgICAgICogVGhlIHVzZXIgbWF5IGdvIGRvd25sb2FkIG9uZSBpZiB0aGlzIG9jY3Vycy4KICAgICAgICAgKi8KICAgICAgICBpZiAoIWlzc2V0KCRkZWZhdWx0c1snc3NsJ11bJ2NhZmlsZSddKSAmJiAhaXNzZXQoJGRlZmF1bHRzWydzc2wnXVsnY2FwYXRoJ10pKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBDYUJ1bmRsZTo6Z2V0U3lzdGVtQ2FSb290QnVuZGxlUGF0aCgkbG9nZ2VyKTsKCiAgICAgICAgICAgIGlmIChpc19kaXIoJHJlc3VsdCkpIHsKICAgICAgICAgICAgICAgICRkZWZhdWx0c1snc3NsJ11bJ2NhcGF0aCddID0gJHJlc3VsdDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRkZWZhdWx0c1snc3NsJ11bJ2NhZmlsZSddID0gJHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRkZWZhdWx0c1snc3NsJ11bJ2NhZmlsZSddKSAmJiAoIWlzX3JlYWRhYmxlKCRkZWZhdWx0c1snc3NsJ11bJ2NhZmlsZSddKSB8fCAhQ2FCdW5kbGU6OnZhbGlkYXRlQ2FGaWxlKCRkZWZhdWx0c1snc3NsJ11bJ2NhZmlsZSddLCAkbG9nZ2VyKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlIGNvbmZpZ3VyZWQgY2FmaWxlIHdhcyBub3QgdmFsaWQgb3IgY291bGQgbm90IGJlIHJlYWQuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJGRlZmF1bHRzWydzc2wnXVsnY2FwYXRoJ10pICYmICghaXNfZGlyKCRkZWZhdWx0c1snc3NsJ11bJ2NhcGF0aCddKSB8fCAhaXNfcmVhZGFibGUoJGRlZmF1bHRzWydzc2wnXVsnY2FwYXRoJ10pKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgY29uZmlndXJlZCBjYXBhdGggd2FzIG5vdCB2YWxpZCBvciBjb3VsZCBub3QgYmUgcmVhZC4nKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIERpc2FibGUgVExTIGNvbXByZXNzaW9uIHRvIHByZXZlbnQgQ1JJTUUgYXR0YWNrcyB3aGVyZSBzdXBwb3J0ZWQuCiAgICAgICAgICovCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDUwNDEzKSB7CiAgICAgICAgICAgICRkZWZhdWx0c1snc3NsJ11bJ2Rpc2FibGVfY29tcHJlc3Npb24nXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRlZmF1bHRzOwogICAgfQoKICAgIC8qKgogICAgICogQSBidWcgaW4gUEhQIHByZXZlbnRzIHRoZSBoZWFkZXJzIGZyb20gY29ycmVjdGx5IGJlaW5nIHNlbnQgd2hlbiBhIGNvbnRlbnQtdHlwZSBoZWFkZXIgaXMgcHJlc2VudCBhbmQKICAgICAqIE5PVCBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheQogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGZpeGVzIHRoZSBhcnJheSBieSBtb3ZpbmcgdGhlIGNvbnRlbnQtdHlwZSBoZWFkZXIgdG8gdGhlIGVuZAogICAgICoKICAgICAqIEBsaW5rIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NjE1NDgKICAgICAqIEBwYXJhbSAgc3RyaW5nfGFycmF5ICRoZWFkZXIKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZml4SHR0cEhlYWRlckZpZWxkKCRoZWFkZXIpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkaGVhZGVyKSkgewogICAgICAgICAgICAkaGVhZGVyID0gZXhwbG9kZSgiXHJcbiIsICRoZWFkZXIpOwogICAgICAgIH0KICAgICAgICB1YXNvcnQoJGhlYWRlciwgZnVuY3Rpb24gKCRlbCkgewogICAgICAgICAgICByZXR1cm4gc3RyaXBvcygkZWwsICdjb250ZW50LXR5cGUnKSA9PT0gMCA/IDEgOiAtMTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRoZWFkZXI7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIFRpbGwgS2xhbXBhZWNrZWwgPHRpbGxAcGhwLm5ldD4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgU3ZuCnsKICAgIGNvbnN0IE1BWF9RVFlfQVVUSF9UUklFUyA9IDU7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkY3JlZGVudGlhbHM7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRoYXNBdXRoOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdXJsOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2FjaGVDcmVkZW50aWFscyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBAdmFyIFByb2Nlc3NFeGVjdXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3M7CgogICAgLyoqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHF0eUF1dGhUcmllcyA9IDA7CgogICAgLyoqCiAgICAgKiBAdmFyIFxDb21wb3NlclxDb25maWcKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICR2ZXJzaW9uOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAkdXJsCiAgICAgKiBAcGFyYW0gXENvbXBvc2VyXElPXElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIENvbmZpZyAgICAgICAgICAgICAgICAgICAkY29uZmlnCiAgICAgKiBAcGFyYW0gUHJvY2Vzc0V4ZWN1dG9yICAgICAgICAgICRwcm9jZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXJsLCBJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT51cmwgPSAkdXJsOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNsZWFuRW52KCkKICAgIHsKICAgICAgICAvLyBjbGVhbiB1cCBlbnYgZm9yIE9TWCwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMjE0NiNpc3N1ZWNvbW1lbnQtMzU0Nzg5NDAKICAgICAgICBwdXRlbnYoIkRZTERfTElCUkFSWV9QQVRIIik7CiAgICAgICAgdW5zZXQoJF9TRVJWRVJbJ0RZTERfTElCUkFSWV9QQVRIJ10pOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSBhbiBTVk4gcmVtb3RlIGNvbW1hbmQgYW5kIHRyeSB0byBmaXggdXAgdGhlIHByb2Nlc3Mgd2l0aCBjcmVkZW50aWFscwogICAgICogaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbW1hbmQgU1ZOIGNvbW1hbmQgdG8gcnVuCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwgICAgIFNWTiB1cmwKICAgICAqIEBwYXJhbSBzdHJpbmcgJGN3ZCAgICAgV29ya2luZyBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggICAgVGFyZ2V0IGZvciBhIGNoZWNrb3V0CiAgICAgKiBAcGFyYW0gYm9vbCAgICR2ZXJib3NlIE91dHB1dCBhbGwgb3V0cHV0IHRvIHRoZSB1c2VyCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4ZWN1dGUoJGNvbW1hbmQsICR1cmwsICRjd2QgPSBudWxsLCAkcGF0aCA9IG51bGwsICR2ZXJib3NlID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy8gRW5zdXJlIHdlIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGlzIFVSTCBieSBjb25maWcKICAgICAgICAkdGhpcy0+Y29uZmlnLT5wcm9oaWJpdFVybEJ5Q29uZmlnKCR1cmwsICR0aGlzLT5pbyk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXhlY3V0ZVdpdGhBdXRoUmV0cnkoJGNvbW1hbmQsICRjd2QsICR1cmwsICRwYXRoLCAkdmVyYm9zZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlIGFuIFNWTiBsb2NhbCBjb21tYW5kIGFuZCB0cnkgdG8gZml4IHVwIHRoZSBwcm9jZXNzIHdpdGggY3JlZGVudGlhbHMKICAgICAqIGlmIG5lY2Vzc2FyeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kIFNWTiBjb21tYW5kIHRvIHJ1bgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aCAgICBQYXRoIGFyZ3VtZW50IHBhc3NlZCB0aHJ1IHRvIHRoZSBjb21tYW5kCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjd2QgICAgIFdvcmtpbmcgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gYm9vbCAgICR2ZXJib3NlIE91dHB1dCBhbGwgb3V0cHV0IHRvIHRoZSB1c2VyCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4ZWN1dGVMb2NhbCgkY29tbWFuZCwgJHBhdGgsICRjd2QgPSBudWxsLCAkdmVyYm9zZSA9IGZhbHNlKQogICAgewogICAgICAgIC8vIEEgbG9jYWwgY29tbWFuZCBoYXMgbm8gcmVtb3RlIHVybAogICAgICAgIHJldHVybiAkdGhpcy0+ZXhlY3V0ZVdpdGhBdXRoUmV0cnkoJGNvbW1hbmQsICRjd2QsICcnLCAkcGF0aCwgJHZlcmJvc2UpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZXhlY3V0ZVdpdGhBdXRoUmV0cnkoJHN2bkNvbW1hbmQsICRjd2QsICR1cmwsICRwYXRoLCAkdmVyYm9zZSkKICAgIHsKICAgICAgICAvLyBSZWdlbmVyYXRlIHRoZSBjb21tYW5kIGF0IGVhY2ggdHJ5LCB0byB1c2UgdGhlIG5ld2x5IHVzZXItcHJvdmlkZWQgY3JlZGVudGlhbHMKICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5nZXRDb21tYW5kKCRzdm5Db21tYW5kLCAkdXJsLCAkcGF0aCk7CgogICAgICAgICRvdXRwdXQgPSBudWxsOwogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKICAgICAgICAkaGFuZGxlciA9IGZ1bmN0aW9uICgkdHlwZSwgJGJ1ZmZlcikgdXNlICgmJG91dHB1dCwgJGlvLCAkdmVyYm9zZSkgewogICAgICAgICAgICBpZiAoJHR5cGUgIT09ICdvdXQnKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0cnBvcygkYnVmZmVyLCAnUmVkaXJlY3RpbmcgdG8gVVJMICcpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG91dHB1dCAuPSAkYnVmZmVyOwogICAgICAgICAgICBpZiAoJHZlcmJvc2UpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigkYnVmZmVyLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgICRzdGF0dXMgPSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGhhbmRsZXIsICRjd2QpOwogICAgICAgIGlmICgwID09PSAkc3RhdHVzKSB7CiAgICAgICAgICAgIHJldHVybiAkb3V0cHV0OwogICAgICAgIH0KCiAgICAgICAgJGVycm9yT3V0cHV0ID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgJGZ1bGxPdXRwdXQgPSBpbXBsb2RlKCJcbiIsIGFycmF5KCRvdXRwdXQsICRlcnJvck91dHB1dCkpOwoKICAgICAgICAvLyB0aGUgZXJyb3IgaXMgbm90IGF1dGgtcmVsYXRlZAogICAgICAgIGlmIChmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ0NvdWxkIG5vdCBhdXRoZW50aWNhdGUgdG8gc2VydmVyOicpCiAgICAgICAgICAgICYmIGZhbHNlID09PSBzdHJpcG9zKCRmdWxsT3V0cHV0LCAnYXV0aG9yaXphdGlvbiBmYWlsZWQnKQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ3N2bjogRTE3MDAwMTonKQogICAgICAgICAgICAmJiBmYWxzZSA9PT0gc3RyaXBvcygkZnVsbE91dHB1dCwgJ3N2bjogRTIxNTAwNDonKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGZ1bGxPdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+aGFzQXV0aCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5kb0F1dGhEYW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IHRvIGF1dGhlbnRpY2F0ZSBpZiBtYXhpbXVtIHF1YW50aXR5IG9mIHRyaWVzIG5vdCByZWFjaGVkCiAgICAgICAgaWYgKCR0aGlzLT5xdHlBdXRoVHJpZXMrKyA8IHNlbGY6Ok1BWF9RVFlfQVVUSF9UUklFUykgewogICAgICAgICAgICAvLyByZXN0YXJ0IHRoZSBwcm9jZXNzCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXhlY3V0ZVdpdGhBdXRoUmV0cnkoJHN2bkNvbW1hbmQsICRjd2QsICR1cmwsICRwYXRoLCAkdmVyYm9zZSk7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICd3cm9uZyBjcmVkZW50aWFscyBwcm92aWRlZCAoJy4kZnVsbE91dHB1dC4nKScKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGJvb2wgJGNhY2hlQ3JlZGVudGlhbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENhY2hlQ3JlZGVudGlhbHMoJGNhY2hlQ3JlZGVudGlhbHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPSAkY2FjaGVDcmVkZW50aWFsczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcG9zaXRvcmllcyByZXF1ZXN0cyBjcmVkZW50aWFscywgbGV0J3MgcHV0IHRoZW0gaW4uCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBcQ29tcG9zZXJcVXRpbFxTdm4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvQXV0aERhbmNlKCkKICAgIHsKICAgICAgICAvLyBjYW5ub3QgYXNrIGZvciBjcmVkZW50aWFscyBpbiBub24gaW50ZXJhY3RpdmUgbW9kZQogICAgICAgIGlmICghJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ2NhbiBub3QgYXNrIGZvciBhdXRoZW50aWNhdGlvbiBpbiBub24gaW50ZXJhY3RpdmUgbW9kZScKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiVGhlIFN1YnZlcnNpb24gc2VydmVyICh7JHRoaXMtPnVybH0pIHJlcXVlc3RlZCBjcmVkZW50aWFsczoiKTsKCiAgICAgICAgJHRoaXMtPmhhc0F1dGggPSB0cnVlOwogICAgICAgICR0aGlzLT5jcmVkZW50aWFsc1sndXNlcm5hbWUnXSA9ICR0aGlzLT5pby0+YXNrKCJVc2VybmFtZTogIik7CiAgICAgICAgJHRoaXMtPmNyZWRlbnRpYWxzWydwYXNzd29yZCddID0gJHRoaXMtPmlvLT5hc2tBbmRIaWRlQW5zd2VyKCJQYXNzd29yZDogIik7CgogICAgICAgICR0aGlzLT5jYWNoZUNyZWRlbnRpYWxzID0gJHRoaXMtPmlvLT5hc2tDb25maXJtYXRpb24oIlNob3VsZCBTdWJ2ZXJzaW9uIGNhY2hlIHRoZXNlIGNyZWRlbnRpYWxzPyAoeWVzL25vKSAiKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQSBtZXRob2QgdG8gY3JlYXRlIHRoZSBzdm4gY29tbWFuZHMgcnVuLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNtZCAgVXN1YWxseSAnc3ZuIGxzJyBvciBzb21ldGhpbmcgbGlrZSB0aGF0LgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsICBSZXBvIFVSTC4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggVGFyZ2V0IGZvciBhIGNoZWNrb3V0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1hbmQoJGNtZCwgJHVybCwgJHBhdGggPSBudWxsKQogICAgewogICAgICAgICRjbWQgPSBzcHJpbnRmKAogICAgICAgICAgICAnJXMgJXMlcyAtLSAlcycsCiAgICAgICAgICAgICRjbWQsCiAgICAgICAgICAgICctLW5vbi1pbnRlcmFjdGl2ZSAnLAogICAgICAgICAgICAkdGhpcy0+Z2V0Q3JlZGVudGlhbFN0cmluZygpLAogICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKQogICAgICAgICk7CgogICAgICAgIGlmICgkcGF0aCkgewogICAgICAgICAgICAkY21kIC49ICcgJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY21kOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjcmVkZW50aWFsIHN0cmluZyBmb3IgdGhlIHN2biBjb21tYW5kLgogICAgICoKICAgICAqIEFkZHMgLS1uby1hdXRoLWNhY2hlIHdoZW4gY3JlZGVudGlhbHMgYXJlIHByZXNlbnQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENyZWRlbnRpYWxTdHJpbmcoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc0F1dGgoKSkgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZigKICAgICAgICAgICAgJyAlcy0tdXNlcm5hbWUgJXMgLS1wYXNzd29yZCAlcyAnLAogICAgICAgICAgICAkdGhpcy0+Z2V0QXV0aENhY2hlKCksCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0aGlzLT5nZXRVc2VybmFtZSgpKSwKICAgICAgICAgICAgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRoaXMtPmdldFBhc3N3b3JkKCkpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcGFzc3dvcmQgZm9yIHRoZSBzdm4gY29tbWFuZC4gQ2FuIGJlIGVtcHR5LgogICAgICoKICAgICAqIEB0aHJvd3MgXExvZ2ljRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGFzc3dvcmQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y3JlZGVudGlhbHMgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbigiTm8gc3ZuIGF1dGggZGV0ZWN0ZWQuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmNyZWRlbnRpYWxzWydwYXNzd29yZCddKSA/ICR0aGlzLT5jcmVkZW50aWFsc1sncGFzc3dvcmQnXSA6ICcnOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB1c2VybmFtZSBmb3IgdGhlIHN2biBjb21tYW5kLgogICAgICoKICAgICAqIEB0aHJvd3MgXExvZ2ljRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VXNlcm5hbWUoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y3JlZGVudGlhbHMgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbigiTm8gc3ZuIGF1dGggZGV0ZWN0ZWQuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNyZWRlbnRpYWxzWyd1c2VybmFtZSddOwogICAgfQoKICAgIC8qKgogICAgICogRGV0ZWN0IFN2biBBdXRoLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaGFzQXV0aCgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5oYXNBdXRoKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aDsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJHRoaXMtPmNyZWF0ZUF1dGhGcm9tQ29uZmlnKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmNyZWF0ZUF1dGhGcm9tVXJsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKGJvb2wpICR0aGlzLT5oYXNBdXRoOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBuby1hdXRoLWNhY2hlIHN3aXRjaC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0QXV0aENhY2hlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPyAnJyA6ICctLW5vLWF1dGgtY2FjaGUgJzsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSB0aGUgYXV0aCBwYXJhbXMgZnJvbSB0aGUgY29uZmlndXJhdGlvbiBmaWxlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZUF1dGhGcm9tQ29uZmlnKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5jb25maWctPmhhcygnaHR0cC1iYXNpYycpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGF1dGhDb25maWcgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2h0dHAtYmFzaWMnKTsKCiAgICAgICAgJGhvc3QgPSBwYXJzZV91cmwoJHRoaXMtPnVybCwgUEhQX1VSTF9IT1NUKTsKICAgICAgICBpZiAoaXNzZXQoJGF1dGhDb25maWdbJGhvc3RdKSkgewogICAgICAgICAgICAkdGhpcy0+Y3JlZGVudGlhbHNbJ3VzZXJuYW1lJ10gPSAkYXV0aENvbmZpZ1skaG9zdF1bJ3VzZXJuYW1lJ107CiAgICAgICAgICAgICR0aGlzLT5jcmVkZW50aWFsc1sncGFzc3dvcmQnXSA9ICRhdXRoQ29uZmlnWyRob3N0XVsncGFzc3dvcmQnXTsKCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmhhc0F1dGggPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSB0aGUgYXV0aCBwYXJhbXMgZnJvbSB0aGUgdXJsCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY3JlYXRlQXV0aEZyb21VcmwoKQogICAgewogICAgICAgICR1cmkgPSBwYXJzZV91cmwoJHRoaXMtPnVybCk7CiAgICAgICAgaWYgKGVtcHR5KCR1cmlbJ3VzZXInXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNBdXRoID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y3JlZGVudGlhbHNbJ3VzZXJuYW1lJ10gPSAkdXJpWyd1c2VyJ107CiAgICAgICAgaWYgKCFlbXB0eSgkdXJpWydwYXNzJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5jcmVkZW50aWFsc1sncGFzc3dvcmQnXSA9ICR1cmlbJ3Bhc3MnXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aGFzQXV0aCA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBzdm4gYmluYXJ5IGNvbnRhaW5lZCBpbiBQQVRICiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYmluYXJ5VmVyc2lvbigpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokdmVyc2lvbikgewogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ3N2biAtLXZlcnNpb24nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3soXGQrKD86XC5cZCspKyl9JywgJG91dHB1dCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgIHNlbGY6OiR2ZXJzaW9uID0gJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHZlcnNpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCi8qKgogKiBDb21wb3NlciBtaXJyb3IgdXRpbGl0aWVzCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENvbXBvc2VyTWlycm9yCnsKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvY2Vzc1VybCgkbWlycm9yVXJsLCAkcGFja2FnZU5hbWUsICR2ZXJzaW9uLCAkcmVmZXJlbmNlLCAkdHlwZSkKICAgIHsKICAgICAgICBpZiAoJHJlZmVyZW5jZSkgewogICAgICAgICAgICAkcmVmZXJlbmNlID0gcHJlZ19tYXRjaCgne14oW2EtZjAtOV0qfCVyZWZlcmVuY2UlKSR9JywgJHJlZmVyZW5jZSkgPyAkcmVmZXJlbmNlIDogbWQ1KCRyZWZlcmVuY2UpOwogICAgICAgIH0KICAgICAgICAkdmVyc2lvbiA9IHN0cnBvcygkdmVyc2lvbiwgJy8nKSA9PT0gZmFsc2UgPyAkdmVyc2lvbiA6IG1kNSgkdmVyc2lvbik7CgogICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgKICAgICAgICAgICAgYXJyYXkoJyVwYWNrYWdlJScsICcldmVyc2lvbiUnLCAnJXJlZmVyZW5jZSUnLCAnJXR5cGUlJyksCiAgICAgICAgICAgIGFycmF5KCRwYWNrYWdlTmFtZSwgJHZlcnNpb24sICRyZWZlcmVuY2UsICR0eXBlKSwKICAgICAgICAgICAgJG1pcnJvclVybAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9jZXNzR2l0VXJsKCRtaXJyb3JVcmwsICRwYWNrYWdlTmFtZSwgJHVybCwgJHR5cGUpCiAgICB7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJyNeKD86KD86aHR0cHM/fGdpdCk6Ly9naXRodWJcLmNvbS98Z2l0QGdpdGh1YlwuY29tOikoW14vXSspLyguKz8pKD86XC5naXQpPyQjJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAkdXJsID0gJ2doLScuJG1hdGNoWzFdLicvJy4kbWF0Y2hbMl07CiAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJyNeaHR0cHM6Ly9iaXRidWNrZXRcLm9yZy8oW14vXSspLyguKz8pKD86XC5naXQpPy8/JCMnLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR1cmwgPSAnYmItJy4kbWF0Y2hbMV0uJy8nLiRtYXRjaFsyXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdXJsID0gcHJlZ19yZXBsYWNlKCd7W15hLXowLTlfLi1dfWknLCAnLScsIHRyaW0oJHVybCwgJy8nKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoCiAgICAgICAgICAgIGFycmF5KCclcGFja2FnZSUnLCAnJW5vcm1hbGl6ZWRVcmwlJywgJyV0eXBlJScpLAogICAgICAgICAgICBhcnJheSgkcGFja2FnZU5hbWUsICR1cmwsICR0eXBlKSwKICAgICAgICAgICAgJG1pcnJvclVybAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9jZXNzSGdVcmwoJG1pcnJvclVybCwgJHBhY2thZ2VOYW1lLCAkdXJsLCAkdHlwZSkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6cHJvY2Vzc0dpdFVybCgkbWlycm9yVXJsLCAkcGFja2FnZU5hbWUsICR1cmwsICR0eXBlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCmNsYXNzIFBhY2thZ2VTb3J0ZXIKewogICAgLyoqCiAgICAgKiBTb3J0cyBwYWNrYWdlcyBieSBkZXBlbmRlbmN5IHdlaWdodAogICAgICoKICAgICAqIFBhY2thZ2VzIG9mIGVxdWFsIHdlaWdodCByZXRhaW4gdGhlIG9yaWdpbmFsIG9yZGVyCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAkcGFja2FnZXMKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzb3J0UGFja2FnZXMoYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgICR1c2FnZUxpc3QgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsgLyoqIEB2YXIgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSAqLwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwgJHBhY2thZ2UtPmdldERldlJlcXVpcmVzKCkpIGFzICRsaW5rKSB7IC8qKiBAdmFyIExpbmsgJGxpbmsgKi8KICAgICAgICAgICAgICAgICR0YXJnZXQgPSAkbGluay0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgICAgICAkdXNhZ2VMaXN0WyR0YXJnZXRdW10gPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRjb21wdXRpbmcgPSBhcnJheSgpOwogICAgICAgICRjb21wdXRlZCA9IGFycmF5KCk7CiAgICAgICAgJGNvbXB1dGVJbXBvcnRhbmNlID0gZnVuY3Rpb24gKCRuYW1lKSB1c2UgKCYkY29tcHV0ZUltcG9ydGFuY2UsICYkY29tcHV0aW5nLCAmJGNvbXB1dGVkLCAkdXNhZ2VMaXN0KSB7CiAgICAgICAgICAgIC8vIHJldXNpbmcgY29tcHV0ZWQgaW1wb3J0YW5jZQogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXB1dGVkWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29tcHV0ZWRbJG5hbWVdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjYW5jZWxpbmcgY2lyY3VsYXIgZGVwZW5kZW5jeQogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXB1dGluZ1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbXB1dGluZ1skbmFtZV0gPSB0cnVlOwogICAgICAgICAgICAkd2VpZ2h0ID0gMDsKCiAgICAgICAgICAgIGlmIChpc3NldCgkdXNhZ2VMaXN0WyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR1c2FnZUxpc3RbJG5hbWVdIGFzICR1c2VyKSB7CiAgICAgICAgICAgICAgICAgICAgJHdlaWdodCAtPSAxIC0gJGNvbXB1dGVJbXBvcnRhbmNlKCR1c2VyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdW5zZXQoJGNvbXB1dGluZ1skbmFtZV0pOwogICAgICAgICAgICAkY29tcHV0ZWRbJG5hbWVdID0gJHdlaWdodDsKCiAgICAgICAgICAgIHJldHVybiAkd2VpZ2h0OwogICAgICAgIH07CgogICAgICAgICR3ZWlnaHRMaXN0ID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRpbmRleCA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAkd2VpZ2h0ID0gJGNvbXB1dGVJbXBvcnRhbmNlKCRwYWNrYWdlLT5nZXROYW1lKCkpOwogICAgICAgICAgICAkd2VpZ2h0TGlzdFskaW5kZXhdID0gJHdlaWdodDsKICAgICAgICB9CgogICAgICAgICRzdGFibGVfc29ydCA9IGZ1bmN0aW9uICgmJGFycmF5KSB7CiAgICAgICAgICAgIHN0YXRpYyAkdHJhbnNmb3JtLCAkcmVzdG9yZTsKCiAgICAgICAgICAgICRpID0gMDsKCiAgICAgICAgICAgIGlmICghJHRyYW5zZm9ybSkgewogICAgICAgICAgICAgICAgJHRyYW5zZm9ybSA9IGZ1bmN0aW9uICgmJHYsICRrKSB1c2UgKCYkaSkgewogICAgICAgICAgICAgICAgICAgICR2ID0gYXJyYXkoJHYsICsrJGksICRrLCAkdik7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICRyZXN0b3JlID0gZnVuY3Rpb24gKCYkdikgewogICAgICAgICAgICAgICAgICAgICR2ID0gJHZbM107CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICBhcnJheV93YWxrKCRhcnJheSwgJHRyYW5zZm9ybSk7CiAgICAgICAgICAgIGFzb3J0KCRhcnJheSk7CiAgICAgICAgICAgIGFycmF5X3dhbGsoJGFycmF5LCAkcmVzdG9yZSk7CiAgICAgICAgfTsKCiAgICAgICAgJHN0YWJsZV9zb3J0KCR3ZWlnaHRMaXN0KTsKCiAgICAgICAgJHNvcnRlZFBhY2thZ2VzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkd2VpZ2h0TGlzdCkgYXMgJGluZGV4KSB7CiAgICAgICAgICAgICRzb3J0ZWRQYWNrYWdlc1tdID0gJHBhY2thZ2VzWyRpbmRleF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNvcnRlZFBhY2thZ2VzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgR2l0SHViCnsKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgLyoqIEB2YXIgSHR0cERvd25sb2FkZXIgKi8KICAgIHByb3RlY3RlZCAkaHR0cERvd25sb2FkZXI7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgICBUaGUgSU8gaW5zdGFuY2UKICAgICAqIEBwYXJhbSBDb25maWcgICAgICAgICAgJGNvbmZpZyAgICAgICAgIFRoZSBjb21wb3NlciBjb25maWd1cmF0aW9uCiAgICAgKiBAcGFyYW0gUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzICAgICAgICBQcm9jZXNzIGluc3RhbmNlLCBpbmplY3RhYmxlIGZvciBtb2NraW5nCiAgICAgKiBAcGFyYW0gSHR0cERvd25sb2FkZXIgICRodHRwRG93bmxvYWRlciBSZW1vdGUgRmlsZXN5c3RlbSwgaW5qZWN0YWJsZSBmb3IgbW9ja2luZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzID0gbnVsbCwgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyID86IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCR0aGlzLT5pbywgJGNvbmZpZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBhdXRob3JpemUgYSBHaXRIdWIgZG9tYWluIHZpYSBPQXV0aAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRvcmlnaW5VcmwgVGhlIGhvc3QgdGhpcyBHaXRIdWIgaW5zdGFuY2UgaXMgbG9jYXRlZCBhdAogICAgICogQHJldHVybiBib29sICAgdHJ1ZSBvbiBzdWNjZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdXRob3JpemVPQXV0aCgkb3JpZ2luVXJsKQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJG9yaWdpblVybCwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBhdmFpbGFibGUgdXNlIHRva2VuIGZyb20gZ2l0IGNvbmZpZwogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGNvbmZpZyBnaXRodWIuYWNjZXNzdG9rZW4nLCAkb3V0cHV0KSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRvcmlnaW5VcmwsIHRyaW0oJG91dHB1dCksICd4LW9hdXRoLWJhc2ljJyk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dGhvcml6ZXMgYSBHaXRIdWIgZG9tYWluIGludGVyYWN0aXZlbHkgdmlhIE9BdXRoCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkb3JpZ2luVXJsIFRoZSBob3N0IHRoaXMgR2l0SHViIGluc3RhbmNlIGlzIGxvY2F0ZWQgYXQKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgICBUaGUgcmVhc29uIHRoaXMgYXV0aG9yaXphdGlvbiBpcyByZXF1aXJlZAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb258XEV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkb3JpZ2luVXJsLCAkbWVzc2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRtZXNzYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbWVzc2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkbm90ZSA9ICdDb21wb3Nlcic7CiAgICAgICAgaWYgKCR0aGlzLT5jb25maWctPmdldCgnZ2l0aHViLWV4cG9zZS1ob3N0bmFtZScpID09PSB0cnVlICYmIDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdob3N0bmFtZScsICRvdXRwdXQpKSB7CiAgICAgICAgICAgICRub3RlIC49ICcgb24gJyAuIHRyaW0oJG91dHB1dCk7CiAgICAgICAgfQogICAgICAgICRub3RlIC49ICcgJyAuIGRhdGUoJ1ktbS1kIEhpJyk7CgogICAgICAgICR1cmwgPSAnaHR0cHM6Ly8nLiRvcmlnaW5VcmwuJy9zZXR0aW5ncy90b2tlbnMvbmV3P3Njb3Blcz1yZXBvJmRlc2NyaXB0aW9uPScgLiBzdHJfcmVwbGFjZSgnJTIwJywgJysnLCByYXd1cmxlbmNvZGUoJG5vdGUpKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignSGVhZCB0byAlcycsICR1cmwpKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZigndG8gcmV0cmlldmUgYSB0b2tlbi4gSXQgd2lsbCBiZSBzdG9yZWQgaW4gIiVzIiBmb3IgZnV0dXJlIHVzZSBieSBDb21wb3Nlci4nLCAkdGhpcy0+Y29uZmlnLT5nZXRBdXRoQ29uZmlnU291cmNlKCktPmdldE5hbWUoKSkpOwoKICAgICAgICAkdG9rZW4gPSB0cmltKCR0aGlzLT5pby0+YXNrQW5kSGlkZUFuc3dlcignVG9rZW4gKGhpZGRlbik6ICcpKTsKCiAgICAgICAgaWYgKCEkdG9rZW4pIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5ObyB0b2tlbiBnaXZlbiwgYWJvcnRpbmcuPC93YXJuaW5nPicpOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1lvdSBjYW4gYWxzbyBhZGQgaXQgbWFudWFsbHkgbGF0ZXIgYnkgdXNpbmcgImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLWF1dGggZ2l0aHViLW9hdXRoLmdpdGh1Yi5jb20gPHRva2VuPiInKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG9yaWdpblVybCwgJHRva2VuLCAneC1vYXV0aC1iYXNpYycpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkYXBpVXJsID0gKCdnaXRodWIuY29tJyA9PT0gJG9yaWdpblVybCkgPyAnYXBpLmdpdGh1Yi5jb20vJyA6ICRvcmlnaW5VcmwgLiAnL2FwaS92My8nOwoKICAgICAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJ2h0dHBzOi8vJy4gJGFwaVVybCwgYXJyYXkoCiAgICAgICAgICAgICAgICAncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSwKICAgICAgICAgICAgKSk7CiAgICAgICAgfSBjYXRjaCAoVHJhbnNwb3J0RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkZS0+Z2V0Q29kZSgpLCBhcnJheSg0MDMsIDQwMSkpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxlcnJvcj5JbnZhbGlkIHRva2VuIHByb3ZpZGVkLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1lvdSBjYW4gYWxzbyBhZGQgaXQgbWFudWFsbHkgbGF0ZXIgYnkgdXNpbmcgImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLWF1dGggZ2l0aHViLW9hdXRoLmdpdGh1Yi5jb20gPHRva2VuPiInKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgLy8gc3RvcmUgdmFsdWUgaW4gdXNlciBjb25maWcKICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXRDb25maWdTb3VyY2UoKS0+cmVtb3ZlQ29uZmlnU2V0dGluZygnZ2l0aHViLW9hdXRoLicuJG9yaWdpblVybCk7CiAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0QXV0aENvbmZpZ1NvdXJjZSgpLT5hZGRDb25maWdTZXR0aW5nKCdnaXRodWItb2F1dGguJy4kb3JpZ2luVXJsLCAkdG9rZW4pOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzxpbmZvPlRva2VuIHN0b3JlZCBzdWNjZXNzZnVsbHkuPC9pbmZvPicpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgcmF0ZWxpbWl0IGZyb20gcmVzcG9uc2UuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIEhlYWRlcnMgZnJvbSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFzc29jaWF0aXZlIGFycmF5IHdpdGggdGhlIGtleXMgbGltaXQgYW5kIHJlc2V0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmF0ZUxpbWl0KGFycmF5ICRoZWFkZXJzKQogICAgewogICAgICAgICRyYXRlTGltaXQgPSBhcnJheSgKICAgICAgICAgICAgJ2xpbWl0JyA9PiAnPycsCiAgICAgICAgICAgICdyZXNldCcgPT4gJz8nLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRoZWFkZXIpIHsKICAgICAgICAgICAgJGhlYWRlciA9IHRyaW0oJGhlYWRlcik7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gc3RycG9zKCRoZWFkZXIsICdYLVJhdGVMaW1pdC0nKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGlzdCgkdHlwZSwgJHZhbHVlKSA9IGV4cGxvZGUoJzonLCAkaGVhZGVyLCAyKTsKICAgICAgICAgICAgc3dpdGNoICgkdHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAnWC1SYXRlTGltaXQtTGltaXQnOgogICAgICAgICAgICAgICAgICAgICRyYXRlTGltaXRbJ2xpbWl0J10gPSAoaW50KSB0cmltKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdYLVJhdGVMaW1pdC1SZXNldCc6CiAgICAgICAgICAgICAgICAgICAgJHJhdGVMaW1pdFsncmVzZXQnXSA9IGRhdGUoJ1ktbS1kIEg6aTpzJywgKGludCkgdHJpbSgkdmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyYXRlTGltaXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kcyB3aGV0aGVyIGEgcmVxdWVzdCBmYWlsZWQgZHVlIHRvIHJhdGUgbGltaXRpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgSGVhZGVycyBmcm9tIENvbXBvc2VyXERvd25sb2FkZXJcVHJhbnNwb3J0RXhjZXB0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSYXRlTGltaXRlZChhcnJheSAkaGVhZGVycykKICAgIHsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XlgtUmF0ZUxpbWl0LVJlbWFpbmluZzogKjAkfWknLCB0cmltKCRoZWFkZXIpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxDYUJ1bmRsZVxDYUJ1bmRsZTsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cFxSZXNwb25zZTsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cFxQcm94eU1hbmFnZXI7CgovKioKICogQGludGVybmFsCiAqIEBhdXRob3IgRnJhbsOnb2lzIFBsdWNoaW5vIDxmcmFuY29pcy5wbHVjaGlub0BvcGVuZGlzcGxheS5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJlbW90ZUZpbGVzeXN0ZW0KewogICAgcHJpdmF0ZSAkaW87CiAgICBwcml2YXRlICRjb25maWc7CiAgICBwcml2YXRlICRzY2hlbWU7CiAgICBwcml2YXRlICRieXRlc01heDsKICAgIHByaXZhdGUgJG9yaWdpblVybDsKICAgIHByaXZhdGUgJGZpbGVVcmw7CiAgICBwcml2YXRlICRmaWxlTmFtZTsKICAgIHByaXZhdGUgJHJldHJ5OwogICAgcHJpdmF0ZSAkcHJvZ3Jlc3M7CiAgICBwcml2YXRlICRsYXN0UHJvZ3Jlc3M7CiAgICBwcml2YXRlICRvcHRpb25zID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJHBlZXJDZXJ0aWZpY2F0ZU1hcCA9IGFycmF5KCk7CiAgICBwcml2YXRlICRkaXNhYmxlVGxzID0gZmFsc2U7CiAgICBwcml2YXRlICRsYXN0SGVhZGVyczsKICAgIHByaXZhdGUgJHN0b3JlQXV0aDsKICAgIHByaXZhdGUgJGF1dGhIZWxwZXI7CiAgICBwcml2YXRlICRkZWdyYWRlZE1vZGUgPSBmYWxzZTsKICAgIHByaXZhdGUgJHJlZGlyZWN0czsKICAgIHByaXZhdGUgJG1heFJlZGlyZWN0cyA9IDIwOwogICAgcHJpdmF0ZSAkcHJveHlNYW5hZ2VyOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbyAgICAgICAgIFRoZSBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtIENvbmZpZyAgICAgICRjb25maWcgICAgIFRoZSBjb25maWcKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAkb3B0aW9ucyAgICBUaGUgb3B0aW9ucwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRkaXNhYmxlVGxzCiAgICAgKiBAcGFyYW0gQXV0aEhlbHBlciAgJGF1dGhIZWxwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSwgJGRpc2FibGVUbHMgPSBmYWxzZSwgQXV0aEhlbHBlciAkYXV0aEhlbHBlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwoKICAgICAgICAvLyBTZXR1cCBUTFMgb3B0aW9ucwogICAgICAgIC8vIFRoZSBjYWZpbGUgb3B0aW9uIGNhbiBiZSBzZXQgdmlhIGNvbmZpZy5qc29uCiAgICAgICAgaWYgKCRkaXNhYmxlVGxzID09PSBmYWxzZSkgewogICAgICAgICAgICAkdGhpcy0+b3B0aW9ucyA9IFN0cmVhbUNvbnRleHRGYWN0b3J5OjpnZXRUbHNEZWZhdWx0cygkb3B0aW9ucywgJGlvKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+ZGlzYWJsZVRscyA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgdGhlIG90aGVyIGV4dGVybmFsbHkgc2V0IG9wdGlvbnMgbm9ybWFsbHkuCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5hdXRoSGVscGVyID0gaXNzZXQoJGF1dGhIZWxwZXIpID8gJGF1dGhIZWxwZXIgOiBuZXcgQXV0aEhlbHBlcigkaW8sICRjb25maWcpOwogICAgICAgICR0aGlzLT5wcm94eU1hbmFnZXIgPSBQcm94eU1hbmFnZXI6OmdldEluc3RhbmNlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IHRoZSByZW1vdGUgZmlsZSBpbiBsb2NhbC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5VcmwgVGhlIG9yaWdpbiBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVVcmwgICBUaGUgZmlsZSBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVOYW1lICB0aGUgbG9jYWwgZmlsZW5hbWUKICAgICAqIEBwYXJhbSBib29sICAgJHByb2dyZXNzICBEaXNwbGF5IHRoZSBwcm9ncmVzc2lvbgogICAgICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyAgIEFkZGl0aW9uYWwgY29udGV4dCBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvcHkoJG9yaWdpblVybCwgJGZpbGVVcmwsICRmaWxlTmFtZSwgJHByb2dyZXNzID0gdHJ1ZSwgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkb3B0aW9ucywgJGZpbGVOYW1lLCAkcHJvZ3Jlc3MpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjb250ZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpblVybCBUaGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZVVybCAgIFRoZSBmaWxlIFVSTAogICAgICogQHBhcmFtIGJvb2wgICAkcHJvZ3Jlc3MgIERpc3BsYXkgdGhlIHByb2dyZXNzaW9uCiAgICAgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zICAgQWRkaXRpb25hbCBjb250ZXh0IG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIFRoZSBjb250ZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZW50cygkb3JpZ2luVXJsLCAkZmlsZVVybCwgJHByb2dyZXNzID0gdHJ1ZSwgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkb3B0aW9ucywgbnVsbCwgJHByb2dyZXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIHRoZSBvcHRpb25zIHNldCBpbiB0aGUgY29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IE9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlcyBuZXcgb3B0aW9ucwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+b3B0aW9ucyA9IGFycmF5X3JlcGxhY2VfcmVjdXJzaXZlKCR0aGlzLT5vcHRpb25zLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpcyBkaXNhYmxlIFRMUy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVGxzRGlzYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGlzYWJsZVRscyA9PT0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGhlYWRlcnMgb2YgdGhlIGxhc3QgcmVxdWVzdAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhc3RIZWFkZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhc3RIZWFkZXJzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBhcnJheSAgICAkaGVhZGVycyBhcnJheSBvZiByZXR1cm5lZCBoZWFkZXJzIGxpa2UgZnJvbSBnZXRMYXN0SGVhZGVycygpCiAgICAgKiBAcmV0dXJuIGludHxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZmluZFN0YXR1c0NvZGUoYXJyYXkgJGhlYWRlcnMpCiAgICB7CiAgICAgICAgJHZhbHVlID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XkhUVFAvXFMrIChcZCspfWknLCAkaGVhZGVyLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIG9mIHJlZGlyZWN0cywgaHR0cF9yZXNwb25zZV9oZWFkZXJzIGNvbnRhaW5zIHRoZSBoZWFkZXJzIG9mIGFsbCByZXNwb25zZXMKICAgICAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBub3QgcmV0dXJuIGRpcmVjdGx5IGFuZCBuZWVkIHRvIGtlZXAgaXRlcmF0aW5nCiAgICAgICAgICAgICAgICAkdmFsdWUgPSAoaW50KSAkbWF0Y2hbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICRoZWFkZXJzIGFycmF5IG9mIHJldHVybmVkIGhlYWRlcnMgbGlrZSBmcm9tIGdldExhc3RIZWFkZXJzKCkKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRTdGF0dXNNZXNzYWdlKGFycmF5ICRoZWFkZXJzKQogICAgewogICAgICAgICR2YWx1ZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJGhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15IVFRQL1xTKyBcZCt9aScsICRoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIG9mIHJlZGlyZWN0cywgaHR0cF9yZXNwb25zZV9oZWFkZXJzIGNvbnRhaW5zIHRoZSBoZWFkZXJzIG9mIGFsbCByZXNwb25zZXMKICAgICAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBub3QgcmV0dXJuIGRpcmVjdGx5IGFuZCBuZWVkIHRvIGtlZXAgaXRlcmF0aW5nCiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkaGVhZGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGZpbGUgY29udGVudCBvciBjb3B5IGFjdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5VcmwgICAgICAgICBUaGUgb3JpZ2luIFVSTAogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZVVybCAgICAgICAgICAgVGhlIGZpbGUgVVJMCiAgICAgKiBAcGFyYW0gYXJyYXkgICRhZGRpdGlvbmFsT3B0aW9ucyBjb250ZXh0IG9wdGlvbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVOYW1lICAgICAgICAgIHRoZSBsb2NhbCBmaWxlbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkcHJvZ3Jlc3MgICAgICAgICAgRGlzcGxheSB0aGUgcHJvZ3Jlc3Npb24KICAgICAqCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbnxcRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbiAgICAgICAgICAgIFdoZW4gdGhlIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXQoJG9yaWdpblVybCwgJGZpbGVVcmwsICRhZGRpdGlvbmFsT3B0aW9ucyA9IGFycmF5KCksICRmaWxlTmFtZSA9IG51bGwsICRwcm9ncmVzcyA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnNjaGVtZSA9IHBhcnNlX3VybCgkZmlsZVVybCwgUEhQX1VSTF9TQ0hFTUUpOwogICAgICAgICR0aGlzLT5ieXRlc01heCA9IDA7CiAgICAgICAgJHRoaXMtPm9yaWdpblVybCA9ICRvcmlnaW5Vcmw7CiAgICAgICAgJHRoaXMtPmZpbGVVcmwgPSAkZmlsZVVybDsKICAgICAgICAkdGhpcy0+ZmlsZU5hbWUgPSAkZmlsZU5hbWU7CiAgICAgICAgJHRoaXMtPnByb2dyZXNzID0gJHByb2dyZXNzOwogICAgICAgICR0aGlzLT5sYXN0UHJvZ3Jlc3MgPSBudWxsOwogICAgICAgICRyZXRyeUF1dGhGYWlsdXJlID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+bGFzdEhlYWRlcnMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5yZWRpcmVjdHMgPSAxOyAvLyBUaGUgZmlyc3QgcmVxdWVzdCBjb3VudHMuCgogICAgICAgICR0ZW1wQWRkaXRpb25hbE9wdGlvbnMgPSAkYWRkaXRpb25hbE9wdGlvbnM7CiAgICAgICAgaWYgKGlzc2V0KCR0ZW1wQWRkaXRpb25hbE9wdGlvbnNbJ3JldHJ5LWF1dGgtZmFpbHVyZSddKSkgewogICAgICAgICAgICAkcmV0cnlBdXRoRmFpbHVyZSA9IChib29sKSAkdGVtcEFkZGl0aW9uYWxPcHRpb25zWydyZXRyeS1hdXRoLWZhaWx1cmUnXTsKCiAgICAgICAgICAgIHVuc2V0KCR0ZW1wQWRkaXRpb25hbE9wdGlvbnNbJ3JldHJ5LWF1dGgtZmFpbHVyZSddKTsKICAgICAgICB9CgogICAgICAgICRpc1JlZGlyZWN0ID0gZmFsc2U7CiAgICAgICAgaWYgKGlzc2V0KCR0ZW1wQWRkaXRpb25hbE9wdGlvbnNbJ3JlZGlyZWN0cyddKSkgewogICAgICAgICAgICAkdGhpcy0+cmVkaXJlY3RzID0gJHRlbXBBZGRpdGlvbmFsT3B0aW9uc1sncmVkaXJlY3RzJ107CiAgICAgICAgICAgICRpc1JlZGlyZWN0ID0gdHJ1ZTsKCiAgICAgICAgICAgIHVuc2V0KCR0ZW1wQWRkaXRpb25hbE9wdGlvbnNbJ3JlZGlyZWN0cyddKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zID0gJHRoaXMtPmdldE9wdGlvbnNGb3JVcmwoJG9yaWdpblVybCwgJHRlbXBBZGRpdGlvbmFsT3B0aW9ucyk7CiAgICAgICAgdW5zZXQoJHRlbXBBZGRpdGlvbmFsT3B0aW9ucyk7CgogICAgICAgICRvcmlnRmlsZVVybCA9ICRmaWxlVXJsOwoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2dpdGxhYi10b2tlbiddKSkgewogICAgICAgICAgICAkZmlsZVVybCAuPSAoZmFsc2UgPT09IHN0cnBvcygkZmlsZVVybCwgJz8nKSA/ICc/JyA6ICcmJykgLiAnYWNjZXNzX3Rva2VuPScuJG9wdGlvbnNbJ2dpdGxhYi10b2tlbiddOwogICAgICAgICAgICB1bnNldCgkb3B0aW9uc1snZ2l0bGFiLXRva2VuJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydodHRwJ10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2lnbm9yZV9lcnJvcnMnXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmRlZ3JhZGVkTW9kZSAmJiBzdHJwb3MoJGZpbGVVcmwsICdodHRwOi8vcmVwby5wYWNrYWdpc3Qub3JnLycpID09PSAwKSB7CiAgICAgICAgICAgIC8vIGFjY2VzcyBwYWNrYWdpc3QgdXNpbmcgdGhlIHJlc29sdmVkIElQdjQgaW5zdGVhZCBvZiB0aGUgaG9zdG5hbWUgdG8gZm9yY2UgSVB2NCBwcm90b2NvbAogICAgICAgICAgICAkZmlsZVVybCA9ICdodHRwOi8vJyAuIGdldGhvc3RieW5hbWUoJ3JlcG8ucGFja2FnaXN0Lm9yZycpIC4gc3Vic3RyKCRmaWxlVXJsLCAyMCk7CiAgICAgICAgICAgICRkZWdyYWRlZFBhY2thZ2lzdCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkbWF4RmlsZVNpemUgPSBudWxsOwogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snbWF4X2ZpbGVfc2l6ZSddKSkgewogICAgICAgICAgICAkbWF4RmlsZVNpemUgPSAkb3B0aW9uc1snbWF4X2ZpbGVfc2l6ZSddOwogICAgICAgICAgICB1bnNldCgkb3B0aW9uc1snbWF4X2ZpbGVfc2l6ZSddKTsKICAgICAgICB9CgogICAgICAgICRjdHggPSBTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0Q29udGV4dCgkZmlsZVVybCwgJG9wdGlvbnMsIGFycmF5KCdub3RpZmljYXRpb24nID0+IGFycmF5KCR0aGlzLCAnY2FsbGJhY2tHZXQnKSkpOwoKICAgICAgICAkcHJveHkgPSAkdGhpcy0+cHJveHlNYW5hZ2VyLT5nZXRQcm94eUZvclJlcXVlc3QoJGZpbGVVcmwpOwogICAgICAgICR1c2luZ1Byb3h5ID0gJHByb3h5LT5nZXRGb3JtYXR0ZWRVcmwoJyB1c2luZyBwcm94eSAoJXMpJyk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKChzdHJwb3MoJG9yaWdGaWxlVXJsLCAnaHR0cCcpID09PSAwID8gJ0Rvd25sb2FkaW5nICcgOiAnUmVhZGluZyAnKSAuIFVybDo6c2FuaXRpemUoJG9yaWdGaWxlVXJsKSAuICR1c2luZ1Byb3h5LCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgIHVuc2V0KCRvcmlnRmlsZVVybCwgJHByb3h5LCAkdXNpbmdQcm94eSk7CgogICAgICAgIC8vIENoZWNrIGZvciBzZWN1cmUgSFRUUCwgYnV0IGFsbG93IGluc2VjdXJlIFBhY2thZ2lzdCBjYWxscyB0byAkaGFzaGVkIHByb3ZpZGVycyBhcyBmaWxlIGludGVncml0eSBpcyB2ZXJpZmllZCB3aXRoIHNoYTI1NgogICAgICAgIGlmICgoIXByZWdfbWF0Y2goJ3teaHR0cDovLyhyZXBvXC4pP3BhY2thZ2lzdFwub3JnL3AvfScsICRmaWxlVXJsKSB8fCAoZmFsc2UgPT09IHN0cnBvcygkZmlsZVVybCwgJyQnKSAmJiBmYWxzZSA9PT0gc3RycG9zKCRmaWxlVXJsLCAnJTI0JykpKSAmJiBlbXB0eSgkZGVncmFkZWRQYWNrYWdpc3QpICYmICR0aGlzLT5jb25maWcpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkZmlsZVVybCwgJHRoaXMtPmlvKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+cHJvZ3Jlc3MgJiYgISRpc1JlZGlyZWN0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiRG93bmxvYWRpbmcgKDxjb21tZW50PmNvbm5lY3RpbmcuLi48L2NvbW1lbnQ+KSIsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgICRlcnJvck1lc3NhZ2UgPSAnJzsKICAgICAgICAkZXJyb3JDb2RlID0gMDsKICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoZnVuY3Rpb24gKCRjb2RlLCAkbXNnKSB1c2UgKCYkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgIGlmICgkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAkZXJyb3JNZXNzYWdlIC49ICJcbiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVycm9yTWVzc2FnZSAuPSBwcmVnX3JlcGxhY2UoJ3teZmlsZV9nZXRfY29udGVudHNcKC4qP1wpOiB9JywgJycsICRtc2cpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSk7CiAgICAgICAgJGh0dHBfcmVzcG9uc2VfaGVhZGVyID0gYXJyYXkoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmdldFJlbW90ZUNvbnRlbnRzKCRvcmlnaW5VcmwsICRmaWxlVXJsLCAkY3R4LCAkaHR0cF9yZXNwb25zZV9oZWFkZXIsICRtYXhGaWxlU2l6ZSk7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRodHRwX3Jlc3BvbnNlX2hlYWRlclswXSkpIHsKICAgICAgICAgICAgICAgICRzdGF0dXNDb2RlID0gc2VsZjo6ZmluZFN0YXR1c0NvZGUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSA0MDAgJiYgUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LXR5cGUnKSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nKSB7CiAgICAgICAgICAgICAgICAgICAgSHR0cERvd25sb2FkZXI6Om91dHB1dFdhcm5pbmdzKCR0aGlzLT5pbywgJG9yaWdpblVybCwganNvbl9kZWNvZGUoJHJlc3VsdCwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkc3RhdHVzQ29kZSwgYXJyYXkoNDAxLCA0MDMpKSAmJiAkcmV0cnlBdXRoRmFpbHVyZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wcm9tcHRBdXRoQW5kUmV0cnkoJHN0YXR1c0NvZGUsICR0aGlzLT5maW5kU3RhdHVzTWVzc2FnZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpLCAkaHR0cF9yZXNwb25zZV9oZWFkZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29udGVudExlbmd0aCA9ICFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pID8gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LWxlbmd0aCcpIDogbnVsbDsKICAgICAgICAgICAgaWYgKCRjb250ZW50TGVuZ3RoICYmIFBsYXRmb3JtOjpzdHJsZW4oJHJlc3VsdCkgPCAkY29udGVudExlbmd0aCkgewogICAgICAgICAgICAgICAgLy8gYWxhcywgdGhpcyBpcyBub3QgcG9zc2libGUgdmlhIHRoZSBzdHJlYW0gY2FsbGJhY2sgYmVjYXVzZSBTVFJFQU1fTk9USUZZX0NPTVBMRVRFRCBpcyBkb2N1bWVudGVkLCBidXQgbm90IGltcGxlbWVudGVkIGFueXdoZXJlIGluIFBIUAogICAgICAgICAgICAgICAgJGUgPSBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdDb250ZW50LUxlbmd0aCBtaXNtYXRjaCwgcmVjZWl2ZWQgJy5QbGF0Zm9ybTo6c3RybGVuKCRyZXN1bHQpLicgYnl0ZXMgb3V0IG9mIHRoZSBleHBlY3RlZCAnLiRjb250ZW50TGVuZ3RoKTsKICAgICAgICAgICAgICAgICRlLT5zZXRIZWFkZXJzKCRodHRwX3Jlc3BvbnNlX2hlYWRlcik7CiAgICAgICAgICAgICAgICAkZS0+c2V0U3RhdHVzQ29kZShzZWxmOjpmaW5kU3RhdHVzQ29kZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCRyZXN1bHQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignQ29udGVudC1MZW5ndGggbWlzbWF0Y2gsIHJlY2VpdmVkICcuUGxhdGZvcm06OnN0cmxlbigkcmVzdWx0KS4nIG91dCBvZiAnLiRjb250ZW50TGVuZ3RoLicgYnl0ZXM6ICgnIC4gYmFzZTY0X2VuY29kZSgkcmVzdWx0KS4nKScsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDUwNjAwICYmICFlbXB0eSgkb3B0aW9uc1snc3NsJ11bJ3BlZXJfZmluZ2VycHJpbnQnXSkpIHsKICAgICAgICAgICAgICAgIC8vIEVtdWxhdGUgZmluZ2VycHJpbnQgdmFsaWRhdGlvbiBvbiBQSFAgPCA1LjYKICAgICAgICAgICAgICAgICRwYXJhbXMgPSBzdHJlYW1fY29udGV4dF9nZXRfcGFyYW1zKCRjdHgpOwogICAgICAgICAgICAgICAgJGV4cGVjdGVkUGVlckZpbmdlcnByaW50ID0gJG9wdGlvbnNbJ3NzbCddWydwZWVyX2ZpbmdlcnByaW50J107CiAgICAgICAgICAgICAgICAkcGVlckZpbmdlcnByaW50ID0gVGxzSGVscGVyOjpnZXRDZXJ0aWZpY2F0ZUZpbmdlcnByaW50KCRwYXJhbXNbJ29wdGlvbnMnXVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXSk7CgogICAgICAgICAgICAgICAgLy8gQ29uc3RhbnQgdGltZSBjb21wYXJlPz8hCiAgICAgICAgICAgICAgICBpZiAoJGV4cGVjdGVkUGVlckZpbmdlcnByaW50ICE9PSAkcGVlckZpbmdlcnByaW50KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignUGVlciBmaW5nZXJwcmludCBkaWQgbm90IG1hdGNoJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAhZW1wdHkoJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdKSkgewogICAgICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgICAgICRlLT5zZXRTdGF0dXNDb2RlKHNlbGY6OmZpbmRTdGF0dXNDb2RlKCRodHRwX3Jlc3BvbnNlX2hlYWRlcikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAkcmVzdWx0ICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoJGVycm9yTWVzc2FnZSAmJiAhZmlsdGVyX3ZhcihpbmlfZ2V0KCdhbGxvd191cmxfZm9wZW4nKSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4pKSB7CiAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgPSAnYWxsb3dfdXJsX2ZvcGVuIG11c3QgYmUgZW5hYmxlZCBpbiBwaHAuaW5pICgnLiRlcnJvck1lc3NhZ2UuJyknOwogICAgICAgIH0KICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKICAgICAgICBpZiAoaXNzZXQoJGUpICYmICEkdGhpcy0+cmV0cnkpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVncmFkZWRNb2RlICYmIGZhbHNlICE9PSBzdHJwb3MoJGUtPmdldE1lc3NhZ2UoKSwgJ09wZXJhdGlvbiB0aW1lZCBvdXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRlZ3JhZGVkTW9kZSA9IHRydWU7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+Jy4kZS0+Z2V0TWVzc2FnZSgpLic8L2Vycm9yPicsCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj5SZXRyeWluZyB3aXRoIGRlZ3JhZGVkIG1vZGUsIGNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjZGVncmFkZWQtbW9kZSBmb3IgbW9yZSBpbmZvPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5nZXQoJHRoaXMtPm9yaWdpblVybCwgJHRoaXMtPmZpbGVVcmwsICRhZGRpdGlvbmFsT3B0aW9ucywgJHRoaXMtPmZpbGVOYW1lLCAkdGhpcy0+cHJvZ3Jlc3MpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgICRzdGF0dXNDb2RlID0gbnVsbDsKICAgICAgICAkY29udGVudFR5cGUgPSBudWxsOwogICAgICAgICRsb2NhdGlvbkhlYWRlciA9IG51bGw7CiAgICAgICAgaWYgKCFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0pKSB7CiAgICAgICAgICAgICRzdGF0dXNDb2RlID0gc2VsZjo6ZmluZFN0YXR1c0NvZGUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgJGNvbnRlbnRUeXBlID0gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdjb250ZW50LXR5cGUnKTsKICAgICAgICAgICAgJGxvY2F0aW9uSGVhZGVyID0gUmVzcG9uc2U6OmZpbmRIZWFkZXJWYWx1ZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIsICdsb2NhdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgZm9yIGJpdGJ1Y2tldCBsb2dpbiBwYWdlIGFza2luZyB0byBhdXRoZW50aWNhdGUKICAgICAgICBpZiAoJG9yaWdpblVybCA9PT0gJ2JpdGJ1Y2tldC5vcmcnCiAgICAgICAgICAgICYmICEkdGhpcy0+YXV0aEhlbHBlci0+aXNQdWJsaWNCaXRCdWNrZXREb3dubG9hZCgkZmlsZVVybCkKICAgICAgICAgICAgJiYgc3Vic3RyKCRmaWxlVXJsLCAtNCkgPT09ICcuemlwJwogICAgICAgICAgICAmJiAoISRsb2NhdGlvbkhlYWRlciB8fCBzdWJzdHIocGFyc2VfdXJsKCRsb2NhdGlvbkhlYWRlciwgUEhQX1VSTF9QQVRIKSwgLTQpICE9PSAnLnppcCcpCiAgICAgICAgICAgICYmICRjb250ZW50VHlwZSAmJiBwcmVnX21hdGNoKCd7XnRleHQvaHRtbFxifWknLCAkY29udGVudFR5cGUpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCRyZXRyeUF1dGhGYWlsdXJlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvbXB0QXV0aEFuZFJldHJ5KDQwMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBnaXRsYWIgNDA0IHdoZW4gZG93bmxvYWRpbmcgYXJjaGl2ZXMKICAgICAgICBpZiAoJHN0YXR1c0NvZGUgPT09IDQwNAogICAgICAgICAgICAmJiAkdGhpcy0+Y29uZmlnICYmIGluX2FycmF5KCRvcmlnaW5VcmwsICR0aGlzLT5jb25maWctPmdldCgnZ2l0bGFiLWRvbWFpbnMnKSwgdHJ1ZSkKICAgICAgICAgICAgJiYgZmFsc2UgIT09IHN0cnBvcygkZmlsZVVybCwgJ2FyY2hpdmUuemlwJykKICAgICAgICApIHsKICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgICAgICBpZiAoJHJldHJ5QXV0aEZhaWx1cmUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9tcHRBdXRoQW5kUmV0cnkoNDAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIDN4eCByZWRpcmVjdHMsIDMwNCBOb3QgTW9kaWZpZWQgaXMgZXhjbHVkZWQKICAgICAgICAkaGFzRm9sbG93ZWRSZWRpcmVjdCA9IGZhbHNlOwogICAgICAgIGlmICgkc3RhdHVzQ29kZSA+PSAzMDAgJiYgJHN0YXR1c0NvZGUgPD0gMzk5ICYmICRzdGF0dXNDb2RlICE9PSAzMDQgJiYgJHRoaXMtPnJlZGlyZWN0cyA8ICR0aGlzLT5tYXhSZWRpcmVjdHMpIHsKICAgICAgICAgICAgJGhhc0ZvbGxvd2VkUmVkaXJlY3QgPSB0cnVlOwogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmhhbmRsZVJlZGlyZWN0KCRodHRwX3Jlc3BvbnNlX2hlYWRlciwgJGFkZGl0aW9uYWxPcHRpb25zLCAkcmVzdWx0KTsKICAgICAgICB9CgogICAgICAgIC8vIGZhaWwgNHh4IGFuZCA1eHggcmVzcG9uc2VzIGFuZCBjYXB0dXJlIHRoZSByZXNwb25zZQogICAgICAgIGlmICgkc3RhdHVzQ29kZSAmJiAkc3RhdHVzQ29kZSA+PSA0MDAgJiYgJHN0YXR1c0NvZGUgPD0gNTk5KSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnJldHJ5KSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnByb2dyZXNzICYmICEkaXNSZWRpcmVjdCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoIkRvd25sb2FkaW5nICg8ZXJyb3I+ZmFpbGVkPC9lcnJvcj4pIiwgZmFsc2UpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRlID0gbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiR0aGlzLT5maWxlVXJsLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQgKCcuJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdLicpJywgJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgICAgICRlLT5zZXRSZXNwb25zZSgkdGhpcy0+ZGVjb2RlUmVzdWx0KCRyZXN1bHQsICRodHRwX3Jlc3BvbnNlX2hlYWRlcikpOwogICAgICAgICAgICAgICAgJGUtPnNldFN0YXR1c0NvZGUoJHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wcm9ncmVzcyAmJiAhJHRoaXMtPnJldHJ5ICYmICEkaXNSZWRpcmVjdCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPm92ZXJ3cml0ZUVycm9yKCJEb3dubG9hZGluZyAoIi4oJHJlc3VsdCA9PT0gZmFsc2UgPyAnPGVycm9yPmZhaWxlZDwvZXJyb3I+JyA6ICc8Y29tbWVudD4xMDAlPC9jb21tZW50PicpLiIpIiwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gZGVjb2RlIGd6aXAKICAgICAgICBpZiAoJHJlc3VsdCAmJiBleHRlbnNpb25fbG9hZGVkKCd6bGliJykgJiYgc3RycG9zKCRmaWxlVXJsLCAnaHR0cCcpID09PSAwICYmICEkaGFzRm9sbG93ZWRSZWRpcmVjdCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWdyYWRlZE1vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVncmFkZWRNb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgICAgICAnJywKICAgICAgICAgICAgICAgICAgICAnPGVycm9yPkZhaWxlZCB0byBkZWNvZGUgcmVzcG9uc2U6ICcuJGUtPmdldE1lc3NhZ2UoKS4nPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+UmV0cnlpbmcgd2l0aCBkZWdyYWRlZCBtb2RlLCBjaGVjayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvdHJvdWJsZXNob290aW5nLm1kI2RlZ3JhZGVkLW1vZGUgZm9yIG1vcmUgaW5mbzwvZXJyb3I+JywKICAgICAgICAgICAgICAgICkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCR0aGlzLT5vcmlnaW5VcmwsICR0aGlzLT5maWxlVXJsLCAkYWRkaXRpb25hbE9wdGlvbnMsICR0aGlzLT5maWxlTmFtZSwgJHRoaXMtPnByb2dyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIGNvcHkgY29tbWFuZCBpZiBkb3dubG9hZCB3YXMgc3VjY2Vzc2Z1bAogICAgICAgIGlmIChmYWxzZSAhPT0gJHJlc3VsdCAmJiBudWxsICE9PSAkZmlsZU5hbWUgJiYgISRpc1JlZGlyZWN0KSB7CiAgICAgICAgICAgIGlmICgnJyA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignIicuJHRoaXMtPmZpbGVVcmwuJyIgYXBwZWFycyBicm9rZW4sIGFuZCByZXR1cm5lZCBhbiBlbXB0eSAyMDAgcmVzcG9uc2UnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICcnOwogICAgICAgICAgICBzZXRfZXJyb3JfaGFuZGxlcihmdW5jdGlvbiAoJGNvZGUsICRtc2cpIHVzZSAoJiRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgIGlmICgkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yTWVzc2FnZSAuPSAiXG4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGVycm9yTWVzc2FnZSAuPSBwcmVnX3JlcGxhY2UoJ3teZmlsZV9wdXRfY29udGVudHNcKC4qP1wpOiB9JywgJycsICRtc2cpOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgJHJlc3VsdCA9IChib29sKSBmaWxlX3B1dF9jb250ZW50cygkZmlsZU5hbWUsICRyZXN1bHQpOwogICAgICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkcmVzdWx0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdUaGUgIicuJHRoaXMtPmZpbGVVcmwuJyIgZmlsZSBjb3VsZCBub3QgYmUgd3JpdHRlbiB0byAnLiRmaWxlTmFtZS4nOiAnLiRlcnJvck1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBIYW5kbGUgU1NMIGNlcnQgbWF0Y2ggaXNzdWVzCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmVzdWx0ICYmIGZhbHNlICE9PSBzdHJwb3MoJGVycm9yTWVzc2FnZSwgJ1BlZXIgY2VydGlmaWNhdGUnKSAmJiBQSFBfVkVSU0lPTl9JRCA8IDUwNjAwKSB7CiAgICAgICAgICAgIC8vIENlcnRpZmljYXRlIG5hbWUgZXJyb3IsIFBIUCBkb2Vzbid0IHN1cHBvcnQgc3ViamVjdEFsdE5hbWUgb24gUEhQIDwgNS42CiAgICAgICAgICAgIC8vIFRoZSBwcm9jZWR1cmUgdG8gaGFuZGxlIHNBTiBmb3Igb2xkZXIgUEhQJ3MgaXM6CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIDEuIE9wZW4gc29ja2V0IHRvIHJlbW90ZSBzZXJ2ZXIgYW5kIGZldGNoIGNlcnRpZmljYXRlIChkaXNhYmxpbmcgcGVlcgogICAgICAgICAgICAvLyAgICB2YWxpZGF0aW9uIGJlY2F1c2UgUEhQIGVycm9ycyB3aXRob3V0IGdpdmluZyB1cCB0aGUgY2VydGlmaWNhdGUuKQogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAyLiBWZXJpZnlpbmcgdGhlIGRvbWFpbiBpbiB0aGUgVVJMIGFnYWluc3QgdGhlIG5hbWVzIGluIHRoZSBzQU4gZmllbGQuCiAgICAgICAgICAgIC8vICAgIElmIHRoZXJlIGlzIGEgbWF0Y2ggcmVjb3JkIHRoZSBhdXRob3JpdHkgW2hvc3QvcG9ydF0sIGNlcnRpZmljYXRlCiAgICAgICAgICAgIC8vICAgIGNvbW1vbiBuYW1lLCBhbmQgY2VydGlmaWNhdGUgZmluZ2VycHJpbnQuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIDMuIFJldHJ5IHRoZSBvcmlnaW5hbCByZXF1ZXN0IGJ1dCBjaGFuZ2luZyB0aGUgQ05fbWF0Y2ggcGFyYW1ldGVyIHRvCiAgICAgICAgICAgIC8vICAgIHRoZSBjb21tb24gbmFtZSBleHRyYWN0ZWQgZnJvbSB0aGUgY2VydGlmaWNhdGUgaW4gc3RlcCAyLgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyA0LiBUbyBwcmV2ZW50IGFueSBhdHRlbXB0IGF0IGJlaW5nIGhvb2R3aW5rZWQgYnkgc3dpdGNoaW5nIHRoZQogICAgICAgICAgICAvLyAgICBjZXJ0aWZpY2F0ZSBiZXR3ZWVuIHN0ZXBzIDIgYW5kIDMgdGhlIGZpbmdlcnByaW50IG9mIHRoZSBjZXJ0aWZpY2F0ZQogICAgICAgICAgICAvLyAgICBwcmVzZW50ZWQgaW4gc3RlcCAzIGlzIGNvbXBhcmVkIGFnYWluc3QgdGhlIG9uZSByZWNvcmRlZCBpbiBzdGVwIDIuCiAgICAgICAgICAgIGlmIChDYUJ1bmRsZTo6aXNPcGVuc3NsUGFyc2VTYWZlKCkpIHsKICAgICAgICAgICAgICAgICRjZXJ0RGV0YWlscyA9ICR0aGlzLT5nZXRDZXJ0aWZpY2F0ZUNuQW5kRnAoJHRoaXMtPmZpbGVVcmwsICRvcHRpb25zKTsKCiAgICAgICAgICAgICAgICBpZiAoJGNlcnREZXRhaWxzKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnBlZXJDZXJ0aWZpY2F0ZU1hcFskdGhpcy0+Z2V0VXJsQXV0aG9yaXR5KCR0aGlzLT5maWxlVXJsKV0gPSAkY2VydERldGFpbHM7CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXRyeSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj5Zb3VyIHZlcnNpb24gb2YgUEhQLCAlcywgaXMgYWZmZWN0ZWQgYnkgQ1ZFLTIwMTMtNjQyMCBhbmQgY2Fubm90IHNhZmVseSBwZXJmb3JtIGNlcnRpZmljYXRlIHZhbGlkYXRpb24sIHdlIHN0cm9uZ2x5IHN1Z2dlc3QgeW91IHVwZ3JhZGUuPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgICAgIFBIUF9WRVJTSU9OCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5yZXRyeSkgewogICAgICAgICAgICAkdGhpcy0+cmV0cnkgPSBmYWxzZTsKCiAgICAgICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Z2V0KCR0aGlzLT5vcmlnaW5VcmwsICR0aGlzLT5maWxlVXJsLCAkYWRkaXRpb25hbE9wdGlvbnMsICR0aGlzLT5maWxlTmFtZSwgJHRoaXMtPnByb2dyZXNzKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c3RvcmVBdXRoICYmICR0aGlzLT5jb25maWcpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hdXRoSGVscGVyLT5zdG9yZUF1dGgoJHRoaXMtPm9yaWdpblVybCwgJHRoaXMtPnN0b3JlQXV0aCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3RvcmVBdXRoID0gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmVzdWx0KSB7CiAgICAgICAgICAgICRlID0gbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignVGhlICInLiR0aGlzLT5maWxlVXJsLiciIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQ6ICcuJGVycm9yTWVzc2FnZSwgJGVycm9yQ29kZSk7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdKSkgewogICAgICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVncmFkZWRNb2RlICYmIGZhbHNlICE9PSBzdHJwb3MoJGUtPmdldE1lc3NhZ2UoKSwgJ09wZXJhdGlvbiB0aW1lZCBvdXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRlZ3JhZGVkTW9kZSA9IHRydWU7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycpOwogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+Jy4kZS0+Z2V0TWVzc2FnZSgpLic8L2Vycm9yPicsCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj5SZXRyeWluZyB3aXRoIGRlZ3JhZGVkIG1vZGUsIGNoZWNrIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQjZGVncmFkZWQtbW9kZSBmb3IgbW9yZSBpbmZvPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5nZXQoJHRoaXMtPm9yaWdpblVybCwgJHRoaXMtPmZpbGVVcmwsICRhZGRpdGlvbmFsT3B0aW9ucywgJHRoaXMtPmZpbGVOYW1lLCAkdGhpcy0+cHJvZ3Jlc3MpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdKSkgewogICAgICAgICAgICAkdGhpcy0+bGFzdEhlYWRlcnMgPSAkaHR0cF9yZXNwb25zZV9oZWFkZXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBjb250ZW50cyBvZiByZW1vdGUgVVJMLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkb3JpZ2luVXJsICAgVGhlIG9yaWdpbiBVUkwKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkZmlsZVVybCAgICAgVGhlIGZpbGUgVVJMCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJGNvbnRleHQgICAgIFRoZSBzdHJlYW0gY29udGV4dAogICAgICogQHBhcmFtIGludCAgICAgICRtYXhGaWxlU2l6ZSBUaGUgbWF4aW11bSBhbGxvd2VkIGZpbGUgc2l6ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFRoZSByZXNwb25zZSBjb250ZW50cyBvciBmYWxzZSBvbiBmYWlsdXJlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRSZW1vdGVDb250ZW50cygkb3JpZ2luVXJsLCAkZmlsZVVybCwgJGNvbnRleHQsIGFycmF5ICYkcmVzcG9uc2VIZWFkZXJzID0gbnVsbCwgJG1heEZpbGVTaXplID0gbnVsbCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRlID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRtYXhGaWxlU2l6ZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlVXJsLCBmYWxzZSwgJGNvbnRleHQsIDAsICRtYXhGaWxlU2l6ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBwYXNzaW5nIGBudWxsYCB0byBmaWxlX2dldF9jb250ZW50cyB3aWxsIGNvbnZlcnQgYG51bGxgIHRvIGAwYCBhbmQgcmV0dXJuIDAgYnl0ZXMKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBmaWxlX2dldF9jb250ZW50cygkZmlsZVVybCwgZmFsc2UsICRjb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGUpIHsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1heEZpbGVTaXplICE9PSBudWxsICYmIFBsYXRmb3JtOjpzdHJsZW4oJHJlc3VsdCkgPj0gJG1heEZpbGVTaXplKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBNYXhGaWxlU2l6ZUV4Y2VlZGVkRXhjZXB0aW9uKCdNYXhpbXVtIGFsbG93ZWQgZG93bmxvYWQgc2l6ZSByZWFjaGVkLiBEb3dubG9hZGVkICcgLiBQbGF0Zm9ybTo6c3RybGVuKCRyZXN1bHQpIC4gJyBvZiBhbGxvd2VkICcgLiAgJG1heEZpbGVTaXplIC4gJyBieXRlcycpOwogICAgICAgIH0KCiAgICAgICAgLy8gaHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vcmVzZXJ2ZWQudmFyaWFibGVzLmh0dHByZXNwb25zZWhlYWRlci5waHAKICAgICAgICAkcmVzcG9uc2VIZWFkZXJzID0gaXNzZXQoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSA/ICRodHRwX3Jlc3BvbnNlX2hlYWRlciA6IGFycmF5KCk7CgogICAgICAgIGlmIChudWxsICE9PSAkZSkgewogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IG5vdGlmaWNhdGlvbiBhY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICAgJG5vdGlmaWNhdGlvbkNvZGUgVGhlIG5vdGlmaWNhdGlvbiBjb2RlCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAkc2V2ZXJpdHkgICAgICAgICBUaGUgc2V2ZXJpdHkgbGV2ZWwKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICRtZXNzYWdlICAgICAgICAgIFRoZSBtZXNzYWdlCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAkbWVzc2FnZUNvZGUgICAgICBUaGUgbWVzc2FnZSBjb2RlCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAkYnl0ZXNUcmFuc2ZlcnJlZCBUaGUgbG9hZGVkIHNpemUKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICAgICRieXRlc01heCAgICAgICAgIFRoZSB0b3RhbCBzaXplCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2FsbGJhY2tHZXQoJG5vdGlmaWNhdGlvbkNvZGUsICRzZXZlcml0eSwgJG1lc3NhZ2UsICRtZXNzYWdlQ29kZSwgJGJ5dGVzVHJhbnNmZXJyZWQsICRieXRlc01heCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRub3RpZmljYXRpb25Db2RlKSB7CiAgICAgICAgICAgIGNhc2UgU1RSRUFNX05PVElGWV9GQUlMVVJFOgogICAgICAgICAgICAgICAgaWYgKDQwMCA9PT0gJG1lc3NhZ2VDb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBtaWdodCBoYXBwZW4gaWYgeW91ciBob3N0IGlzIHNlY3VyZWQgYnkgc3NsIGNsaWVudCBjZXJ0aWZpY2F0ZSBhdXRoZW50aWNhdGlvbgogICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB5b3UgZG8gbm90IHNlbmQgYW4gYXBwcm9wcmlhdGUgY2VydGlmaWNhdGUKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCJUaGUgJyIgLiAkdGhpcy0+ZmlsZVVybCAuICInIFVSTCBjb3VsZCBub3QgYmUgYWNjZXNzZWQ6ICIgLiAkbWVzc2FnZSwgJG1lc3NhZ2VDb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTVFJFQU1fTk9USUZZX0ZJTEVfU0laRV9JUzoKICAgICAgICAgICAgICAgICR0aGlzLT5ieXRlc01heCA9ICRieXRlc01heDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTVFJFQU1fTk9USUZZX1BST0dSRVNTOgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5ieXRlc01heCA+IDAgJiYgJHRoaXMtPnByb2dyZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgJHByb2dyZXNzaW9uID0gbWluKDEwMCwgcm91bmQoJGJ5dGVzVHJhbnNmZXJyZWQgLyAkdGhpcy0+Ynl0ZXNNYXggKiAxMDApKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCgwID09PSAkcHJvZ3Jlc3Npb24gJSA1KSAmJiAxMDAgIT09ICRwcm9ncmVzc2lvbiAmJiAkcHJvZ3Jlc3Npb24gIT09ICR0aGlzLT5sYXN0UHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmxhc3RQcm9ncmVzcyA9ICRwcm9ncmVzc2lvbjsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5vdmVyd3JpdGVFcnJvcigiRG93bmxvYWRpbmcgKDxjb21tZW50PiRwcm9ncmVzc2lvbiU8L2NvbW1lbnQ+KSIsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByb21wdEF1dGhBbmRSZXRyeSgkaHR0cFN0YXR1cywgJHJlYXNvbiA9IG51bGwsICRoZWFkZXJzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmF1dGhIZWxwZXItPnByb21wdEF1dGhJZk5lZWRlZCgkdGhpcy0+ZmlsZVVybCwgJHRoaXMtPm9yaWdpblVybCwgJGh0dHBTdGF0dXMsICRyZWFzb24sICRoZWFkZXJzKTsKCiAgICAgICAgJHRoaXMtPnN0b3JlQXV0aCA9ICRyZXN1bHRbJ3N0b3JlQXV0aCddOwogICAgICAgICR0aGlzLT5yZXRyeSA9ICRyZXN1bHRbJ3JldHJ5J107CgogICAgICAgIGlmICgkdGhpcy0+cmV0cnkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zcG9ydEV4Y2VwdGlvbignUkVUUlknKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldE9wdGlvbnNGb3JVcmwoJG9yaWdpblVybCwgJGFkZGl0aW9uYWxPcHRpb25zKQogICAgewogICAgICAgICR0bHNPcHRpb25zID0gYXJyYXkoKTsKCiAgICAgICAgLy8gU2V0dXAgcmVtYWluaW5nIFRMUyBvcHRpb25zIC0gdGhlIG1hdGNoaW5nIG1heSBuZWVkIG1vbml0b3JpbmcsIGVzcC4gd3d3IHZzIG5vbmUgaW4gQ04KICAgICAgICBpZiAoJHRoaXMtPmRpc2FibGVUbHMgPT09IGZhbHNlICYmIFBIUF9WRVJTSU9OX0lEIDwgNTA2MDAgJiYgIXN0cmVhbV9pc19sb2NhbCgkdGhpcy0+ZmlsZVVybCkpIHsKICAgICAgICAgICAgJGhvc3QgPSBwYXJzZV91cmwoJHRoaXMtPmZpbGVVcmwsIFBIUF9VUkxfSE9TVCk7CgogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDMwNCkgewogICAgICAgICAgICAgICAgLy8gUEhQIDwgNS4zLjQgZG9lcyBub3Qgc3VwcG9ydCBmb2xsb3dfbG9jYXRpb24sIGZvciB0aG9zZSBwZW9wbGUKICAgICAgICAgICAgICAgIC8vIGRvIHNvbWUgcmVhbGx5IG5hc3R5IGhhcmQgY29kZWQgdHJhbnNmb3JtYXRpb25zLiBUaGVzZSB3aWxsCiAgICAgICAgICAgICAgICAvLyBzdGlsbCBicmVha2Rvd24gaWYgdGhlIHNpdGUgcmVkaXJlY3RzIHRvIGEgZG9tYWluIHdlIGRvbid0CiAgICAgICAgICAgICAgICAvLyBleHBlY3QuCgogICAgICAgICAgICAgICAgaWYgKCRob3N0ID09PSAnZ2l0aHViLmNvbScgfHwgJGhvc3QgPT09ICdhcGkuZ2l0aHViLmNvbScpIHsKICAgICAgICAgICAgICAgICAgICAkaG9zdCA9ICcqLmdpdGh1Yi5jb20nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGxzT3B0aW9uc1snc3NsJ11bJ0NOX21hdGNoJ10gPSAkaG9zdDsKICAgICAgICAgICAgJHRsc09wdGlvbnNbJ3NzbCddWydTTklfc2VydmVyX25hbWUnXSA9ICRob3N0OwoKICAgICAgICAgICAgJHVybEF1dGhvcml0eSA9ICR0aGlzLT5nZXRVcmxBdXRob3JpdHkoJHRoaXMtPmZpbGVVcmwpOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wZWVyQ2VydGlmaWNhdGVNYXBbJHVybEF1dGhvcml0eV0pKSB7CiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgc3ViamVjdEFsdE5hbWUgb24gbGVzc2VyIFBIUCdzLgogICAgICAgICAgICAgICAgJGNlcnRNYXAgPSAkdGhpcy0+cGVlckNlcnRpZmljYXRlTWFwWyR1cmxBdXRob3JpdHldOwoKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdVc2luZyA8aW5mbz4lczwvaW5mbz4gYXMgQ04gZm9yIHN1YmplY3RBbHROYW1lIGVuYWJsZWQgaG9zdCA8aW5mbz4lczwvaW5mbz4nLAogICAgICAgICAgICAgICAgICAgICRjZXJ0TWFwWydjbiddLAogICAgICAgICAgICAgICAgICAgICR1cmxBdXRob3JpdHkKICAgICAgICAgICAgICAgICksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CgogICAgICAgICAgICAgICAgJHRsc09wdGlvbnNbJ3NzbCddWydDTl9tYXRjaCddID0gJGNlcnRNYXBbJ2NuJ107CiAgICAgICAgICAgICAgICAkdGxzT3B0aW9uc1snc3NsJ11bJ3BlZXJfZmluZ2VycHJpbnQnXSA9ICRjZXJ0TWFwWydmcCddOwogICAgICAgICAgICB9IGVsc2VpZiAoIUNhQnVuZGxlOjppc09wZW5zc2xQYXJzZVNhZmUoKSAmJiAkaG9zdCA9PT0gJ3JlcG8ucGFja2FnaXN0Lm9yZycpIHsKICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBzdWJqZWN0QWx0TmFtZSBmb3IgcGFja2FnaXN0Lm9yZydzIHJlcG8gZG9tYWluIG9uIHZlcnkgb2xkIFBIUHMKICAgICAgICAgICAgICAgICR0bHNPcHRpb25zWydzc2wnXVsnQ05fbWF0Y2gnXSA9ICdwYWNrYWdpc3Qub3JnJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGhlYWRlcnMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgnemxpYicpKSB7CiAgICAgICAgICAgICRoZWFkZXJzW10gPSAnQWNjZXB0LUVuY29kaW5nOiBnemlwJzsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoJHRoaXMtPm9wdGlvbnMsICR0bHNPcHRpb25zLCAkYWRkaXRpb25hbE9wdGlvbnMpOwogICAgICAgIGlmICghJHRoaXMtPmRlZ3JhZGVkTW9kZSkgewogICAgICAgICAgICAvLyBkZWdyYWRlZCBtb2RlIGRpc2FibGVzIEhUVFAvMS4xIHdoaWNoIGNhdXNlcyBpc3N1ZXMgd2l0aCBzb21lIGJhZAogICAgICAgICAgICAvLyBwcm94aWVzL3NvZnR3YXJlIGR1ZSB0byB0aGUgdXNlIG9mIGNodW5rZWQgZW5jb2RpbmcKICAgICAgICAgICAgJG9wdGlvbnNbJ2h0dHAnXVsncHJvdG9jb2xfdmVyc2lvbiddID0gMS4xOwogICAgICAgICAgICAkaGVhZGVyc1tdID0gJ0Nvbm5lY3Rpb246IGNsb3NlJzsKICAgICAgICB9CgogICAgICAgICRoZWFkZXJzID0gJHRoaXMtPmF1dGhIZWxwZXItPmFkZEF1dGhlbnRpY2F0aW9uSGVhZGVyKCRoZWFkZXJzLCAkb3JpZ2luVXJsLCAkdGhpcy0+ZmlsZVVybCk7CgogICAgICAgICRvcHRpb25zWydodHRwJ11bJ2ZvbGxvd19sb2NhdGlvbiddID0gMDsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddKSAmJiAhaXNfYXJyYXkoJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddID0gZXhwbG9kZSgiXHJcbiIsIHRyaW0oJG9wdGlvbnNbJ2h0dHAnXVsnaGVhZGVyJ10sICJcclxuIikpOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgICRvcHRpb25zWydodHRwJ11bJ2hlYWRlciddW10gPSAkaGVhZGVyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvcHRpb25zOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaGFuZGxlUmVkaXJlY3QoYXJyYXkgJGh0dHBfcmVzcG9uc2VfaGVhZGVyLCBhcnJheSAkYWRkaXRpb25hbE9wdGlvbnMsICRyZXN1bHQpCiAgICB7CiAgICAgICAgaWYgKCRsb2NhdGlvbkhlYWRlciA9IFJlc3BvbnNlOjpmaW5kSGVhZGVyVmFsdWUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyLCAnbG9jYXRpb24nKSkgewogICAgICAgICAgICBpZiAocGFyc2VfdXJsKCRsb2NhdGlvbkhlYWRlciwgUEhQX1VSTF9TQ0hFTUUpKSB7CiAgICAgICAgICAgICAgICAvLyBBYnNvbHV0ZSBVUkw7IGUuZy4gaHR0cHM6Ly9leGFtcGxlLmNvbS9jb21wb3NlcgogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9ICRsb2NhdGlvbkhlYWRlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKHBhcnNlX3VybCgkbG9jYXRpb25IZWFkZXIsIFBIUF9VUkxfSE9TVCkpIHsKICAgICAgICAgICAgICAgIC8vIFNjaGVtZSByZWxhdGl2ZTsgZS5nLiAvL2V4YW1wbGUuY29tL2ZvbwogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9ICR0aGlzLT5zY2hlbWUuJzonLiRsb2NhdGlvbkhlYWRlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKCcvJyA9PT0gJGxvY2F0aW9uSGVhZGVyWzBdKSB7CiAgICAgICAgICAgICAgICAvLyBBYnNvbHV0ZSBwYXRoOyBlLmcuIC9mb28KICAgICAgICAgICAgICAgICR1cmxIb3N0ID0gcGFyc2VfdXJsKCR0aGlzLT5maWxlVXJsLCBQSFBfVVJMX0hPU1QpOwoKICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgcGF0aCB1c2luZyBob3N0bmFtZSBhcyBhbiBhbmNob3IuCiAgICAgICAgICAgICAgICAkdGFyZ2V0VXJsID0gcHJlZ19yZXBsYWNlKCd7XiguKyg/Oi8vfEApJy5wcmVnX3F1b3RlKCR1cmxIb3N0KS4nKD86OlxkKyk/KSg/OlsvXD9dLiopPyR9JywgJ1wxJy4kbG9jYXRpb25IZWFkZXIsICR0aGlzLT5maWxlVXJsKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFJlbGF0aXZlIHBhdGg7IGUuZy4gZm9vCiAgICAgICAgICAgICAgICAvLyBUaGlzIGFjdHVhbGx5IGRpZmZlcnMgZnJvbSBQSFAgd2hpY2ggc2VlbXMgdG8gYWRkIGR1cGxpY2F0ZSBzbGFzaGVzLgogICAgICAgICAgICAgICAgJHRhcmdldFVybCA9IHByZWdfcmVwbGFjZSgne14oLisvKVteLz9dKig/Olw/LiopPyR9JywgJ1wxJy4kbG9jYXRpb25IZWFkZXIsICR0aGlzLT5maWxlVXJsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkdGFyZ2V0VXJsKSkgewogICAgICAgICAgICAkdGhpcy0+cmVkaXJlY3RzKys7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCdGb2xsb3dpbmcgcmVkaXJlY3QgKCV1KSAlcycsICR0aGlzLT5yZWRpcmVjdHMsIFVybDo6c2FuaXRpemUoJHRhcmdldFVybCkpLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgJGFkZGl0aW9uYWxPcHRpb25zWydyZWRpcmVjdHMnXSA9ICR0aGlzLT5yZWRpcmVjdHM7CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldChwYXJzZV91cmwoJHRhcmdldFVybCwgUEhQX1VSTF9IT1NUKSwgJHRhcmdldFVybCwgJGFkZGl0aW9uYWxPcHRpb25zLCAkdGhpcy0+ZmlsZU5hbWUsICR0aGlzLT5wcm9ncmVzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5yZXRyeSkgewogICAgICAgICAgICAkZSA9IG5ldyBUcmFuc3BvcnRFeGNlcHRpb24oJ1RoZSAiJy4kdGhpcy0+ZmlsZVVybC4nIiBmaWxlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLCBnb3QgcmVkaXJlY3Qgd2l0aG91dCBMb2NhdGlvbiAoJy4kaHR0cF9yZXNwb25zZV9oZWFkZXJbMF0uJyknKTsKICAgICAgICAgICAgJGUtPnNldEhlYWRlcnMoJGh0dHBfcmVzcG9uc2VfaGVhZGVyKTsKICAgICAgICAgICAgJGUtPnNldFJlc3BvbnNlKCR0aGlzLT5kZWNvZGVSZXN1bHQoJHJlc3VsdCwgJGh0dHBfcmVzcG9uc2VfaGVhZGVyKSk7CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEZldGNoIGNlcnRpZmljYXRlIGNvbW1vbiBuYW1lIGFuZCBmaW5nZXJwcmludCBmb3IgdmFsaWRhdGlvbiBvZiBTQU4uCiAgICAgKgogICAgICogQHRvZG8gUmVtb3ZlIHdoZW4gUEhQIDUuNiBpcyBtaW5pbXVtIHN1cHBvcnRlZCB2ZXJzaW9uLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENlcnRpZmljYXRlQ25BbmRGcCgkdXJsLCAkb3B0aW9ucykKICAgIHsKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxCYWRNZXRob2RDYWxsRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXMgbXVzdCBub3QgYmUgdXNlZCBvbiBQSFAgPj0gNS42JywKICAgICAgICAgICAgICAgIF9fTUVUSE9EX18KICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAkY29udGV4dCA9IFN0cmVhbUNvbnRleHRGYWN0b3J5OjpnZXRDb250ZXh0KCR1cmwsICRvcHRpb25zLCBhcnJheSgnb3B0aW9ucycgPT4gYXJyYXkoCiAgICAgICAgICAgICdzc2wnID0+IGFycmF5KAogICAgICAgICAgICAgICAgJ2NhcHR1cmVfcGVlcl9jZXJ0JyA9PiB0cnVlLAogICAgICAgICAgICAgICAgJ3ZlcmlmeV9wZWVyJyA9PiBmYWxzZSwgLy8gWWVzIHRoaXMgaXMgZnVja2luZyBpbnNhbmUhIEJ1dCBQSFAgaXMgbGFtZS4KICAgICAgICAgICAgKSwgKSwKICAgICAgICApKTsKCiAgICAgICAgLy8gSWRlYWxseSB0aGlzIHdvdWxkIGp1c3QgdXNlIHN0cmVhbV9zb2NrZXRfY2xpZW50KCkgdG8gYXZvaWQgc2VuZGluZyBhCiAgICAgICAgLy8gSFRUUCByZXF1ZXN0IGJ1dCB0aGF0IGRvZXMgbm90IGNhcHR1cmUgdGhlIGNlcnRpZmljYXRlLgogICAgICAgIGlmIChmYWxzZSA9PT0gJGhhbmRsZSA9IEBmb3BlbigkdXJsLCAncmInLCBmYWxzZSwgJGNvbnRleHQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIENsb3NlIG5vbiBhdXRoZW50aWNhdGVkIGNvbm5lY3Rpb24gd2l0aG91dCByZWFkaW5nIGFueSBjb250ZW50LgogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKICAgICAgICAkaGFuZGxlID0gbnVsbDsKCiAgICAgICAgJHBhcmFtcyA9IHN0cmVhbV9jb250ZXh0X2dldF9wYXJhbXMoJGNvbnRleHQpOwoKICAgICAgICBpZiAoIWVtcHR5KCRwYXJhbXNbJ29wdGlvbnMnXVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXSkpIHsKICAgICAgICAgICAgJHBlZXJDZXJ0aWZpY2F0ZSA9ICRwYXJhbXNbJ29wdGlvbnMnXVsnc3NsJ11bJ3BlZXJfY2VydGlmaWNhdGUnXTsKCiAgICAgICAgICAgIGlmIChUbHNIZWxwZXI6OmNoZWNrQ2VydGlmaWNhdGVIb3N0KCRwZWVyQ2VydGlmaWNhdGUsIHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX0hPU1QpLCAkY29tbW9uTmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnY24nID0+ICRjb21tb25OYW1lLAogICAgICAgICAgICAgICAgICAgICdmcCcgPT4gVGxzSGVscGVyOjpnZXRDZXJ0aWZpY2F0ZUZpbmdlcnByaW50KCRwZWVyQ2VydGlmaWNhdGUpLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFVybEF1dGhvcml0eSgkdXJsKQogICAgewogICAgICAgICRkZWZhdWx0UG9ydHMgPSBhcnJheSgKICAgICAgICAgICAgJ2Z0cCcgPT4gMjEsCiAgICAgICAgICAgICdodHRwJyA9PiA4MCwKICAgICAgICAgICAgJ2h0dHBzJyA9PiA0NDMsCiAgICAgICAgICAgICdzc2gyLnNmdHAnID0+IDIyLAogICAgICAgICAgICAnc3NoMi5zY3AnID0+IDIyLAogICAgICAgICk7CgogICAgICAgICRzY2hlbWUgPSBwYXJzZV91cmwoJHVybCwgUEhQX1VSTF9TQ0hFTUUpOwoKICAgICAgICBpZiAoIWlzc2V0KCRkZWZhdWx0UG9ydHNbJHNjaGVtZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnQ291bGQgbm90IGdldCBkZWZhdWx0IHBvcnQgZm9yIHVua25vd24gc2NoZW1lOiAlcycsCiAgICAgICAgICAgICAgICAkc2NoZW1lCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJGRlZmF1bHRQb3J0ID0gJGRlZmF1bHRQb3J0c1skc2NoZW1lXTsKICAgICAgICAkcG9ydCA9IHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX1BPUlQpID86ICRkZWZhdWx0UG9ydDsKCiAgICAgICAgcmV0dXJuIHBhcnNlX3VybCgkdXJsLCBQSFBfVVJMX0hPU1QpLic6Jy4kcG9ydDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRlY29kZVJlc3VsdCgkcmVzdWx0LCAkaHR0cF9yZXNwb25zZV9oZWFkZXIpCiAgICB7CiAgICAgICAgLy8gZGVjb2RlIGd6aXAKICAgICAgICBpZiAoJHJlc3VsdCAmJiBleHRlbnNpb25fbG9hZGVkKCd6bGliJykpIHsKICAgICAgICAgICAgJGNvbnRlbnRFbmNvZGluZyA9IFJlc3BvbnNlOjpmaW5kSGVhZGVyVmFsdWUoJGh0dHBfcmVzcG9uc2VfaGVhZGVyLCAnY29udGVudC1lbmNvZGluZycpOwogICAgICAgICAgICAkZGVjb2RlID0gJGNvbnRlbnRFbmNvZGluZyAmJiAnZ3ppcCcgPT09IHN0cnRvbG93ZXIoJGNvbnRlbnRFbmNvZGluZyk7CgogICAgICAgICAgICBpZiAoJGRlY29kZSkgewogICAgICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDUwNDAwKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCA9IHpsaWJfZGVjb2RlKCRyZXN1bHQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyB3b3JrIGFyb3VuZCBpc3N1ZSB3aXRoIGd6dW5jb21wcmVzcyAmIGNvIHRoYXQgZG8gbm90IHdvcmsgd2l0aCBhbGwgZ3ppcCBjaGVja3N1bXMKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gZmlsZV9nZXRfY29udGVudHMoJ2NvbXByZXNzLnpsaWI6Ly9kYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsJy5iYXNlNjRfZW5jb2RlKCRyZXN1bHQpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdGYWlsZWQgdG8gZGVjb2RlIHpsaWIgc3RyZWFtJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFV0aWw7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cFxSZXNwb25zZTsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcRXhjZXB0aW9uXElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBIdHRwRG93bmxvYWRlcgp7CiAgICBjb25zdCBTVEFUVVNfUVVFVUVEID0gMTsKICAgIGNvbnN0IFNUQVRVU19TVEFSVEVEID0gMjsKICAgIGNvbnN0IFNUQVRVU19DT01QTEVURUQgPSAzOwogICAgY29uc3QgU1RBVFVTX0ZBSUxFRCA9IDQ7CiAgICBjb25zdCBTVEFUVVNfQUJPUlRFRCA9IDU7CgogICAgcHJpdmF0ZSAkaW87CiAgICBwcml2YXRlICRjb25maWc7CiAgICBwcml2YXRlICRqb2JzID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJG9wdGlvbnMgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkcnVubmluZ0pvYnMgPSAwOwogICAgcHJpdmF0ZSAkbWF4Sm9icyA9IDEyOwogICAgcHJpdmF0ZSAkY3VybDsKICAgIHByaXZhdGUgJHJmczsKICAgIHByaXZhdGUgJGlkR2VuID0gMDsKICAgIHByaXZhdGUgJGRpc2FibGVkOwogICAgcHJpdmF0ZSAkYWxsb3dBc3luYyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbyAgICAgICAgIFRoZSBJTyBpbnN0YW5jZQogICAgICogQHBhcmFtIENvbmZpZyAgICAgICRjb25maWcgICAgIFRoZSBjb25maWcKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAkb3B0aW9ucyAgICBUaGUgb3B0aW9ucwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRkaXNhYmxlVGxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCksICRkaXNhYmxlVGxzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwoKICAgICAgICAkdGhpcy0+ZGlzYWJsZWQgPSAoYm9vbCkgZ2V0ZW52KCdDT01QT1NFUl9ESVNBQkxFX05FVFdPUksnKTsKCiAgICAgICAgLy8gU2V0dXAgVExTIG9wdGlvbnMKICAgICAgICAvLyBUaGUgY2FmaWxlIG9wdGlvbiBjYW4gYmUgc2V0IHZpYSBjb25maWcuanNvbgogICAgICAgIGlmICgkZGlzYWJsZVRscyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0VGxzRGVmYXVsdHMoJG9wdGlvbnMsICRpbyk7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgdGhlIG90aGVyIGV4dGVybmFsbHkgc2V0IG9wdGlvbnMgbm9ybWFsbHkuCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgICAgICR0aGlzLT5jb25maWcgPSAkY29uZmlnOwoKICAgICAgICBpZiAoc2VsZjo6aXNDdXJsRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5jdXJsID0gbmV3IEh0dHBcQ3VybERvd25sb2FkZXIoJGlvLCAkY29uZmlnLCAkb3B0aW9ucywgJGRpc2FibGVUbHMpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJmcyA9IG5ldyBSZW1vdGVGaWxlc3lzdGVtKCRpbywgJGNvbmZpZywgJG9wdGlvbnMsICRkaXNhYmxlVGxzKTsKCiAgICAgICAgaWYgKGlzX251bWVyaWMoJG1heEpvYnMgPSBnZXRlbnYoJ0NPTVBPU0VSX01BWF9QQVJBTExFTF9IVFRQJykpKSB7CiAgICAgICAgICAgICR0aGlzLT5tYXhKb2JzID0gbWF4KDEsIG1pbig1MCwgKGludCkgJG1heEpvYnMpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEb3dubG9hZCBhIGZpbGUgc3luY2hyb25vdXNseQogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHVybCAgICAgVVJMIHRvIGRvd25sb2FkCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICRvcHRpb25zIFN0cmVhbSBjb250ZXh0IG9wdGlvbnMgZS5nLiBodHRwczovL3d3dy5waHAubmV0L21hbnVhbC9lbi9jb250ZXh0Lmh0dHAucGhwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdGhvdWdoIG5vdCBhbGwgb3B0aW9ucyBhcmUgc3VwcG9ydGVkIHdoZW4gdXNpbmcgdGhlIGRlZmF1bHQgY3VybCBkb3dubG9hZGVyCiAgICAgKiBAcmV0dXJuIFJlc3BvbnNlCiAgICAgKgogICAgICogQHRocm93cyBUcmFuc3BvcnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkdXJsLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgbGlzdCgkam9iKSA9ICR0aGlzLT5hZGRKb2IoYXJyYXkoJ3VybCcgPT4gJHVybCwgJ29wdGlvbnMnID0+ICRvcHRpb25zLCAnY29weVRvJyA9PiBmYWxzZSksIHRydWUpOwogICAgICAgICR0aGlzLT53YWl0KCRqb2JbJ2lkJ10pOwoKICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0UmVzcG9uc2UoJGpvYlsnaWQnXSk7CgogICAgICAgIC8vIGNoZWNrIGZvciBmYWlsZWQgY3VybCByZXNwb25zZSAoZW1wdHkgYm9keSBidXQgc3VjY2Vzc2Z1bCBsb29raW5nIHJlc3BvbnNlKQogICAgICAgIGlmICgKICAgICAgICAgICAgJHRoaXMtPmN1cmwKICAgICAgICAgICAgJiYgUEhQX1ZFUlNJT05fSUQgPCA3MDAwMAogICAgICAgICAgICAmJiAkcmVzcG9uc2UtPmdldEJvZHkoKSA9PT0gbnVsbAogICAgICAgICAgICAmJiAkcmVzcG9uc2UtPmdldFN0YXR1c0NvZGUoKSA9PT0gMjAwCiAgICAgICAgICAgICYmICRyZXNwb25zZS0+Z2V0SGVhZGVyKCdjb250ZW50LWxlbmd0aCcpICE9PSAnMCcKICAgICAgICApIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5jVVJMIGRvd25sb2FkZXIgZmFpbGVkIHRvIHJldHVybiBhIHJlc3BvbnNlLCBkaXNhYmxpbmcgaXQgYW5kIHByb2NlZWRpbmcgaW4gc2xvdyBtb2RlLjwvd2FybmluZz4nKTsKCiAgICAgICAgICAgICR0aGlzLT5jdXJsID0gbnVsbDsKCiAgICAgICAgICAgIGxpc3QoJGpvYikgPSAkdGhpcy0+YWRkSm9iKGFycmF5KCd1cmwnID0+ICR1cmwsICdvcHRpb25zJyA9PiAkb3B0aW9ucywgJ2NvcHlUbycgPT4gZmFsc2UpLCB0cnVlKTsKICAgICAgICAgICAgJHRoaXMtPndhaXQoJGpvYlsnaWQnXSk7CgogICAgICAgICAgICAkcmVzcG9uc2UgPSAkdGhpcy0+Z2V0UmVzcG9uc2UoJGpvYlsnaWQnXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3BvbnNlOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGFzeW5jIGRvd25sb2FkIG9wZXJhdGlvbgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHVybCAgICAgVVJMIHRvIGRvd25sb2FkCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICRvcHRpb25zIFN0cmVhbSBjb250ZXh0IG9wdGlvbnMgZS5nLiBodHRwczovL3d3dy5waHAubmV0L21hbnVhbC9lbi9jb250ZXh0Lmh0dHAucGhwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdGhvdWdoIG5vdCBhbGwgb3B0aW9ucyBhcmUgc3VwcG9ydGVkIHdoZW4gdXNpbmcgdGhlIGRlZmF1bHQgY3VybCBkb3dubG9hZGVyCiAgICAgKiBAcmV0dXJuIFByb21pc2UKICAgICAqCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkKCR1cmwsICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBsaXN0KCwgJHByb21pc2UpID0gJHRoaXMtPmFkZEpvYihhcnJheSgndXJsJyA9PiAkdXJsLCAnb3B0aW9ucycgPT4gJG9wdGlvbnMsICdjb3B5VG8nID0+IGZhbHNlKSk7CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvcHkgYSBmaWxlIHN5bmNocm9ub3VzbHkKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICR1cmwgICAgIFVSTCB0byBkb3dubG9hZAogICAgICogQHBhcmFtICBzdHJpbmcgICAkdG8gICAgICBQYXRoIHRvIGNvcHkgdG8KICAgICAqIEBwYXJhbSAgYXJyYXkgICAgJG9wdGlvbnMgU3RyZWFtIGNvbnRleHQgb3B0aW9ucyBlLmcuIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2NvbnRleHQuaHR0cC5waHAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0aG91Z2ggbm90IGFsbCBvcHRpb25zIGFyZSBzdXBwb3J0ZWQgd2hlbiB1c2luZyB0aGUgZGVmYXVsdCBjdXJsIGRvd25sb2FkZXIKICAgICAqIEByZXR1cm4gUmVzcG9uc2UKICAgICAqCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weSgkdXJsLCAkdG8sICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBsaXN0KCRqb2IpID0gJHRoaXMtPmFkZEpvYihhcnJheSgndXJsJyA9PiAkdXJsLCAnb3B0aW9ucycgPT4gJG9wdGlvbnMsICdjb3B5VG8nID0+ICR0byksIHRydWUpOwogICAgICAgICR0aGlzLT53YWl0KCRqb2JbJ2lkJ10pOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFJlc3BvbnNlKCRqb2JbJ2lkJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGFzeW5jIGNvcHkgb3BlcmF0aW9uCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAkdXJsICAgICBVUkwgdG8gZG93bmxvYWQKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgJHRvICAgICAgUGF0aCB0byBjb3B5IHRvCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICRvcHRpb25zIFN0cmVhbSBjb250ZXh0IG9wdGlvbnMgZS5nLiBodHRwczovL3d3dy5waHAubmV0L21hbnVhbC9lbi9jb250ZXh0Lmh0dHAucGhwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdGhvdWdoIG5vdCBhbGwgb3B0aW9ucyBhcmUgc3VwcG9ydGVkIHdoZW4gdXNpbmcgdGhlIGRlZmF1bHQgY3VybCBkb3dubG9hZGVyCiAgICAgKiBAcmV0dXJuIFByb21pc2UKICAgICAqCiAgICAgKiBAdGhyb3dzIFRyYW5zcG9ydEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQ29weSgkdXJsLCAkdG8sICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBsaXN0KCwgJHByb21pc2UpID0gJHRoaXMtPmFkZEpvYihhcnJheSgndXJsJyA9PiAkdXJsLCAnb3B0aW9ucycgPT4gJG9wdGlvbnMsICdjb3B5VG8nID0+ICR0bykpOwoKICAgICAgICByZXR1cm4gJHByb21pc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSB0aGUgb3B0aW9ucyBzZXQgaW4gdGhlIGNvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBPcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZXMgbmV3IG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbnMoYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkSm9iKCRyZXF1ZXN0LCAkc3luYyA9IGZhbHNlKQogICAgewogICAgICAgICRyZXF1ZXN0WydvcHRpb25zJ10gPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+b3B0aW9ucywgJHJlcXVlc3RbJ29wdGlvbnMnXSk7CgogICAgICAgICRqb2IgPSBhcnJheSgKICAgICAgICAgICAgJ2lkJyA9PiAkdGhpcy0+aWRHZW4rKywKICAgICAgICAgICAgJ3N0YXR1cycgPT4gc2VsZjo6U1RBVFVTX1FVRVVFRCwKICAgICAgICAgICAgJ3JlcXVlc3QnID0+ICRyZXF1ZXN0LAogICAgICAgICAgICAnc3luYycgPT4gJHN5bmMsCiAgICAgICAgICAgICdvcmlnaW4nID0+IFVybDo6Z2V0T3JpZ2luKCR0aGlzLT5jb25maWcsICRyZXF1ZXN0Wyd1cmwnXSksCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCEkc3luYyAmJiAhJHRoaXMtPmFsbG93QXN5bmMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignWW91IG11c3QgdXNlIHRoZSBIdHRwRG93bmxvYWRlciBpbnN0YW5jZSB3aGljaCBpcyBwYXJ0IG9mIGEgQ29tcG9zZXJcTG9vcCBpbnN0YW5jZSB0byBiZSBhYmxlIHRvIHJ1biBhc3luYyBodHRwIHJlcXVlc3RzJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjYXB0dXJlIHVzZXJuYW1lL3Bhc3N3b3JkIGZyb20gVVJMIGlmIHRoZXJlIGlzIG9uZQogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xmh0dHBzPzovLyhbXjovXSspOihbXkAvXSspQChbXi9dKyl9aScsICRyZXF1ZXN0Wyd1cmwnXSwgJG1hdGNoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRqb2JbJ29yaWdpbiddLCByYXd1cmxkZWNvZGUoJG1hdGNoWzFdKSwgcmF3dXJsZGVjb2RlKCRtYXRjaFsyXSkpOwogICAgICAgIH0KCiAgICAgICAgJHJmcyA9ICR0aGlzLT5yZnM7CgogICAgICAgIGlmICgkdGhpcy0+Y2FuVXNlQ3VybCgkam9iKSkgewogICAgICAgICAgICAkcmVzb2x2ZXIgPSBmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QpIHVzZSAoJiRqb2IpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19RVUVVRUQ7CiAgICAgICAgICAgICAgICAkam9iWydyZXNvbHZlJ10gPSAkcmVzb2x2ZTsKICAgICAgICAgICAgICAgICRqb2JbJ3JlamVjdCddID0gJHJlamVjdDsKICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmVzb2x2ZXIgPSBmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QpIHVzZSAoJiRqb2IsICRyZnMpIHsKICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGpvYgogICAgICAgICAgICAgICAgJHVybCA9ICRqb2JbJ3JlcXVlc3QnXVsndXJsJ107CiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddOwoKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19TVEFSVEVEOwoKICAgICAgICAgICAgICAgIGlmICgkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKSB7CiAgICAgICAgICAgICAgICAgICAgJHJmcy0+Y29weSgkam9iWydvcmlnaW4nXSwgJHVybCwgJGpvYlsncmVxdWVzdCddWydjb3B5VG8nXSwgZmFsc2UgLyogVE9ETyBwcm9ncmVzcyAqLywgJG9wdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAkaGVhZGVycyA9ICRyZnMtPmdldExhc3RIZWFkZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gbmV3IEh0dHBcUmVzcG9uc2UoJGpvYlsncmVxdWVzdCddLCAkcmZzLT5maW5kU3RhdHVzQ29kZSgkaGVhZGVycyksICRoZWFkZXJzLCAkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddLid+Jyk7CgogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHJmcy0+Z2V0Q29udGVudHMoJGpvYlsnb3JpZ2luJ10sICR1cmwsIGZhbHNlIC8qIFRPRE8gcHJvZ3Jlc3MgKi8sICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVycyA9ICRyZnMtPmdldExhc3RIZWFkZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgJHJlc3BvbnNlID0gbmV3IEh0dHBcUmVzcG9uc2UoJGpvYlsncmVxdWVzdCddLCAkcmZzLT5maW5kU3RhdHVzQ29kZSgkaGVhZGVycyksICRoZWFkZXJzLCAkYm9keSk7CgogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCRyZXNwb25zZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzOwogICAgICAgICRjdXJsID0gJHRoaXMtPmN1cmw7CgogICAgICAgICRjYW5jZWxlciA9IGZ1bmN0aW9uICgpIHVzZSAoJiRqb2IsICRjdXJsKSB7CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSA9PT0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19RVUVVRUQpIHsKICAgICAgICAgICAgICAgICRqb2JbJ3N0YXR1cyddID0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19BQk9SVEVEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSAhPT0gSHR0cERvd25sb2FkZXI6OlNUQVRVU19TVEFSVEVEKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGpvYlsnc3RhdHVzJ10gPSBIdHRwRG93bmxvYWRlcjo6U1RBVFVTX0FCT1JURUQ7CiAgICAgICAgICAgIGlmIChpc3NldCgkam9iWydjdXJsX2lkJ10pKSB7CiAgICAgICAgICAgICAgICAkY3VybC0+YWJvcnRSZXF1ZXN0KCRqb2JbJ2N1cmxfaWQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbignRG93bmxvYWQgb2YgJyAuIFVybDo6c2FuaXRpemUoJGpvYlsncmVxdWVzdCddWyd1cmwnXSkgLiAnIGNhbmNlbGVkJyk7CiAgICAgICAgfTsKCiAgICAgICAgJHByb21pc2UgPSBuZXcgUHJvbWlzZSgkcmVzb2x2ZXIsICRjYW5jZWxlcik7CiAgICAgICAgJHByb21pc2UgPSAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoJHJlc3BvbnNlKSB1c2UgKCYkam9iLCAkZG93bmxvYWRlcikgewogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IEh0dHBEb3dubG9hZGVyOjpTVEFUVVNfQ09NUExFVEVEOwogICAgICAgICAgICAkam9iWydyZXNwb25zZSddID0gJHJlc3BvbnNlOwoKICAgICAgICAgICAgLy8gVE9ETyAzLjAgdGhpcyBzaG91bGQgYmUgZG9uZSBkaXJlY3RseSBvbiAkdGhpcyB3aGVuIFBIUCA1LjMgaXMgZHJvcHBlZAogICAgICAgICAgICAkZG93bmxvYWRlci0+bWFya0pvYkRvbmUoKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzcG9uc2U7CiAgICAgICAgfSwgZnVuY3Rpb24gKCRlKSB1c2UgKCYkam9iLCAkZG93bmxvYWRlcikgewogICAgICAgICAgICAkam9iWydzdGF0dXMnXSA9IEh0dHBEb3dubG9hZGVyOjpTVEFUVVNfRkFJTEVEOwogICAgICAgICAgICAkam9iWydleGNlcHRpb24nXSA9ICRlOwoKICAgICAgICAgICAgJGRvd25sb2FkZXItPm1hcmtKb2JEb25lKCk7CgogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9KTsKICAgICAgICAkdGhpcy0+am9ic1skam9iWydpZCddXSA9ICYkam9iOwoKICAgICAgICBpZiAoJHRoaXMtPnJ1bm5pbmdKb2JzIDwgJHRoaXMtPm1heEpvYnMpIHsKICAgICAgICAgICAgJHRoaXMtPnN0YXJ0Sm9iKCRqb2JbJ2lkJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCRqb2IsICRwcm9taXNlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0Sm9iKCRpZCkKICAgIHsKICAgICAgICAkam9iID0gJiR0aGlzLT5qb2JzWyRpZF07CiAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddICE9PSBzZWxmOjpTVEFUVVNfUVVFVUVEKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIHN0YXJ0IGpvYgogICAgICAgICRqb2JbJ3N0YXR1cyddID0gc2VsZjo6U1RBVFVTX1NUQVJURUQ7CiAgICAgICAgJHRoaXMtPnJ1bm5pbmdKb2JzKys7CgogICAgICAgICRyZXNvbHZlID0gJGpvYlsncmVzb2x2ZSddOwogICAgICAgICRyZWplY3QgPSAkam9iWydyZWplY3QnXTsKICAgICAgICAkdXJsID0gJGpvYlsncmVxdWVzdCddWyd1cmwnXTsKICAgICAgICAkb3B0aW9ucyA9ICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddOwogICAgICAgICRvcmlnaW4gPSAkam9iWydvcmlnaW4nXTsKCiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlZCkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGpvYlsncmVxdWVzdCddWydvcHRpb25zJ11bJ2h0dHAnXVsnaGVhZGVyJ10pICYmIGZhbHNlICE9PSBzdHJpcG9zKGltcGxvZGUoJycsICRqb2JbJ3JlcXVlc3QnXVsnb3B0aW9ucyddWydodHRwJ11bJ2hlYWRlciddKSwgJ2lmLW1vZGlmaWVkLXNpbmNlJykpIHsKICAgICAgICAgICAgICAgICRyZXNvbHZlKG5ldyBSZXNwb25zZShhcnJheSgndXJsJyA9PiAkdXJsKSwgMzA0LCBhcnJheSgpLCAnJykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGUgPSBuZXcgVHJhbnNwb3J0RXhjZXB0aW9uKCdOZXR3b3JrIGRpc2FibGVkLCByZXF1ZXN0IGNhbmNlbGVkOiAnLlVybDo6c2FuaXRpemUoJHVybCksIDQ5OSk7CiAgICAgICAgICAgICAgICAkZS0+c2V0U3RhdHVzQ29kZSg0OTkpOwogICAgICAgICAgICAgICAgJHJlamVjdCgkZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKSB7CiAgICAgICAgICAgICAgICAkam9iWydjdXJsX2lkJ10gPSAkdGhpcy0+Y3VybC0+ZG93bmxvYWQoJHJlc29sdmUsICRyZWplY3QsICRvcmlnaW4sICR1cmwsICRvcHRpb25zLCAkam9iWydyZXF1ZXN0J11bJ2NvcHlUbyddKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRqb2JbJ2N1cmxfaWQnXSA9ICR0aGlzLT5jdXJsLT5kb3dubG9hZCgkcmVzb2x2ZSwgJHJlamVjdCwgJG9yaWdpbiwgJHVybCwgJG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICRyZWplY3QoJGV4Y2VwdGlvbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHByaXZhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hcmtKb2JEb25lKCkKICAgIHsKICAgICAgICAkdGhpcy0+cnVubmluZ0pvYnMtLTsKICAgIH0KCiAgICAvKioKICAgICAqIFdhaXQgZm9yIGN1cnJlbnQgYXN5bmMgZG93bmxvYWQgam9icyB0byBjb21wbGV0ZQogICAgICoKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAkaW5kZXggRm9yIGludGVybmFsIHVzZSBvbmx5LCB0aGUgam9iIGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YWl0KCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgZG8gewogICAgICAgICAgICAkam9iQ291bnQgPSAkdGhpcy0+Y291bnRBY3RpdmVKb2JzKCRpbmRleCk7CiAgICAgICAgfSB3aGlsZSAoJGpvYkNvdW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlQXN5bmMoKQogICAgewogICAgICAgICR0aGlzLT5hbGxvd0FzeW5jID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICoKICAgICAqIEBwYXJhbSAgaW50fG51bGwgJGluZGV4IEZvciBpbnRlcm5hbCB1c2Ugb25seSwgdGhlIGpvYiBpZAogICAgICogQHJldHVybiBpbnQgICAgICBudW1iZXIgb2YgYWN0aXZlIChxdWV1ZWQgb3Igc3RhcnRlZCkgam9icwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY291bnRBY3RpdmVKb2JzKCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5ydW5uaW5nSm9icyA8ICR0aGlzLT5tYXhKb2JzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5qb2JzIGFzICRqb2IpIHsKICAgICAgICAgICAgICAgIGlmICgkam9iWydzdGF0dXMnXSA9PT0gc2VsZjo6U1RBVFVTX1FVRVVFRCAmJiAkdGhpcy0+cnVubmluZ0pvYnMgPCAkdGhpcy0+bWF4Sm9icykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFydEpvYigkam9iWydpZCddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5jdXJsKSB7CiAgICAgICAgICAgICR0aGlzLT5jdXJsLT50aWNrKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGluZGV4KSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+am9ic1skaW5kZXhdWydzdGF0dXMnXSA8IHNlbGY6OlNUQVRVU19DT01QTEVURUQgPyAxIDogMDsKICAgICAgICB9CgogICAgICAgICRhY3RpdmUgPSAwOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5qb2JzIGFzICRqb2IpIHsKICAgICAgICAgICAgaWYgKCRqb2JbJ3N0YXR1cyddIDwgc2VsZjo6U1RBVFVTX0NPTVBMRVRFRCkgewogICAgICAgICAgICAgICAgJGFjdGl2ZSsrOwogICAgICAgICAgICB9IGVsc2VpZiAoISRqb2JbJ3N5bmMnXSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmpvYnNbJGpvYlsnaWQnXV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGFjdGl2ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFJlc3BvbnNlKCRpbmRleCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5qb2JzWyRpbmRleF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0ludmFsaWQgcmVxdWVzdCBpZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5qb2JzWyRpbmRleF1bJ3N0YXR1cyddID09PSBzZWxmOjpTVEFUVVNfRkFJTEVEKSB7CiAgICAgICAgICAgIHRocm93ICR0aGlzLT5qb2JzWyRpbmRleF1bJ2V4Y2VwdGlvbiddOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+am9ic1skaW5kZXhdWydyZXNwb25zZSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdSZXNwb25zZSBub3QgYXZhaWxhYmxlIHlldCwgY2FsbCB3YWl0KCkgZmlyc3QnKTsKICAgICAgICB9CgogICAgICAgICRyZXNwID0gJHRoaXMtPmpvYnNbJGluZGV4XVsncmVzcG9uc2UnXTsKCiAgICAgICAgdW5zZXQoJHRoaXMtPmpvYnNbJGluZGV4XSk7CgogICAgICAgIHJldHVybiAkcmVzcDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG91dHB1dFdhcm5pbmdzKElPSW50ZXJmYWNlICRpbywgJHVybCwgJGRhdGEpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3dhcm5pbmcnLCAnaW5mbycpIGFzICR0eXBlKSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkZGF0YVskdHlwZV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkZGF0YVskdHlwZSAuICctdmVyc2lvbnMnXSkpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGRhdGFbJHR5cGUgLiAnLXZlcnNpb25zJ10pOwogICAgICAgICAgICAgICAgJGNvbXBvc2VyID0gbmV3IENvbnN0cmFpbnQoJz09JywgJHZlcnNpb25QYXJzZXItPm5vcm1hbGl6ZShDb21wb3Nlcjo6Z2V0VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICBpZiAoISRjb25zdHJhaW50LT5tYXRjaGVzKCRjb21wb3NlcikpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8Jy4kdHlwZS4nPicudWNmaXJzdCgkdHlwZSkuJyBmcm9tICcuVXJsOjpzYW5pdGl6ZSgkdXJsKS4nOiAnLiRkYXRhWyR0eXBlXS4nPC8nLiR0eXBlLic+Jyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RXhjZXB0aW9uSGludHMoXEV4Y2VwdGlvbiAkZSkKICAgIHsKICAgICAgICBpZiAoISRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgKICAgICAgICAgICAgZmFsc2UgIT09IHN0cnBvcygkZS0+Z2V0TWVzc2FnZSgpLCAnUmVzb2x2aW5nIHRpbWVkIG91dCcpCiAgICAgICAgICAgIHx8IGZhbHNlICE9PSBzdHJwb3MoJGUtPmdldE1lc3NhZ2UoKSwgJ0NvdWxkIG5vdCByZXNvbHZlIGhvc3QnKQogICAgICAgICkgewogICAgICAgICAgICBTaWxlbmNlcjo6c3VwcHJlc3MoKTsKICAgICAgICAgICAgJHRlc3RDb25uZWN0aXZpdHkgPSBmaWxlX2dldF9jb250ZW50cygnaHR0cHM6Ly84LjguOC44JywgZmFsc2UsIHN0cmVhbV9jb250ZXh0X2NyZWF0ZShhcnJheSgKICAgICAgICAgICAgICAgICdzc2wnID0+IGFycmF5KCd2ZXJpZnlfcGVlcicgPT4gZmFsc2UpLAogICAgICAgICAgICAgICAgJ2h0dHAnID0+IGFycmF5KCdmb2xsb3dfbG9jYXRpb24nID0+IGZhbHNlLCAnaWdub3JlX2Vycm9ycycgPT4gdHJ1ZSksCiAgICAgICAgICAgICkpKTsKICAgICAgICAgICAgU2lsZW5jZXI6OnJlc3RvcmUoKTsKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkdGVzdENvbm5lY3Rpdml0eSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+VGhlIGZvbGxvd2luZyBleGNlcHRpb24gcHJvYmFibHkgaW5kaWNhdGVzIHlvdSBoYXZlIG1pc2NvbmZpZ3VyZWQgRE5TIHJlc29sdmVyKHMpPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgJzxlcnJvcj5UaGUgZm9sbG93aW5nIGV4Y2VwdGlvbiBwcm9iYWJseSBpbmRpY2F0ZXMgeW91IGFyZSBvZmZsaW5lIG9yIGhhdmUgbWlzY29uZmlndXJlZCBETlMgcmVzb2x2ZXIocyk8L2Vycm9yPicsCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2FuVXNlQ3VybChhcnJheSAkam9iKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmN1cmwpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7Xmh0dHBzPzovL31pJywgJGpvYlsncmVxdWVzdCddWyd1cmwnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkam9iWydyZXF1ZXN0J11bJ29wdGlvbnMnXVsnc3NsJ11bJ2FsbG93X3NlbGZfc2lnbmVkJ10pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNDdXJsRW5hYmxlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIFxleHRlbnNpb25fbG9hZGVkKCdjdXJsJykgJiYgXGZ1bmN0aW9uX2V4aXN0cygnY3VybF9tdWx0aV9leGVjJykgJiYgXGZ1bmN0aW9uX2V4aXN0cygnY3VybF9tdWx0aV9pbml0Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxQcm9ncmVzc0JhcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBMb29wCnsKICAgIC8qKiBAdmFyIEh0dHBEb3dubG9hZGVyICovCiAgICBwcml2YXRlICRodHRwRG93bmxvYWRlcjsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvcnxudWxsICovCiAgICBwcml2YXRlICRwcm9jZXNzRXhlY3V0b3I7CiAgICAvKiogQHZhciBQcm9taXNlW11bXSAqLwogICAgcHJpdmF0ZSAkY3VycmVudFByb21pc2VzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGludCAqLwogICAgcHJpdmF0ZSAkd2FpdEluZGV4ID0gMDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3NFeGVjdXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gJGh0dHBEb3dubG9hZGVyOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlci0+ZW5hYmxlQXN5bmMoKTsKCiAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvciA9ICRwcm9jZXNzRXhlY3V0b3I7CiAgICAgICAgaWYgKCR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpIHsKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3NFeGVjdXRvci0+ZW5hYmxlQXN5bmMoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEh0dHBEb3dubG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIdHRwRG93bmxvYWRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUHJvY2Vzc0V4ZWN1dG9yfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb2Nlc3NFeGVjdXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzRXhlY3V0b3I7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHdhaXQoYXJyYXkgJHByb21pc2VzLCBQcm9ncmVzc0JhciAkcHJvZ3Jlc3MgPSBudWxsKQogICAgewogICAgICAgIC8qKiBAdmFyIFxFeGNlcHRpb258bnVsbCAqLwogICAgICAgICR1bmNhdWdodCA9IG51bGw7CgogICAgICAgIFxSZWFjdFxQcm9taXNlXGFsbCgkcHJvbWlzZXMpLT50aGVuKAogICAgICAgICAgICBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGZ1bmN0aW9uICgkZSkgdXNlICgmJHVuY2F1Z2h0KSB7CiAgICAgICAgICAgICAgICAkdW5jYXVnaHQgPSAkZTsKICAgICAgICAgICAgfQogICAgICAgICk7CgogICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgZXZlcnkgZ3JvdXAgb2YgcHJvbWlzZXMgdGhhdCBpcyB3YWl0ZWQgb24sIHNvIGFib3J0Sm9icyBjYW4KICAgICAgICAvLyBjYW5jZWwgdGhlbSBhbGwsIGV2ZW4gaWYgd2FpdCgpIHdhcyBjYWxsZWQgd2l0aGluIGEgd2FpdCgpCiAgICAgICAgJHdhaXRJbmRleCA9ICR0aGlzLT53YWl0SW5kZXgrKzsKICAgICAgICAkdGhpcy0+Y3VycmVudFByb21pc2VzWyR3YWl0SW5kZXhdID0gJHByb21pc2VzOwoKICAgICAgICBpZiAoJHByb2dyZXNzKSB7CiAgICAgICAgICAgICR0b3RhbEpvYnMgPSAwOwogICAgICAgICAgICBpZiAoJHRoaXMtPmh0dHBEb3dubG9hZGVyKSB7CiAgICAgICAgICAgICAgICAkdG90YWxKb2JzICs9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Y291bnRBY3RpdmVKb2JzKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5wcm9jZXNzRXhlY3V0b3IpIHsKICAgICAgICAgICAgICAgICR0b3RhbEpvYnMgKz0gJHRoaXMtPnByb2Nlc3NFeGVjdXRvci0+Y291bnRBY3RpdmVKb2JzKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHByb2dyZXNzLT5zdGFydCgkdG90YWxKb2JzKTsKICAgICAgICB9CgogICAgICAgICRsYXN0VXBkYXRlID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkYWN0aXZlSm9icyA9IDA7CgogICAgICAgICAgICBpZiAoJHRoaXMtPmh0dHBEb3dubG9hZGVyKSB7CiAgICAgICAgICAgICAgICAkYWN0aXZlSm9icyArPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmNvdW50QWN0aXZlSm9icygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yKSB7CiAgICAgICAgICAgICAgICAkYWN0aXZlSm9icyArPSAkdGhpcy0+cHJvY2Vzc0V4ZWN1dG9yLT5jb3VudEFjdGl2ZUpvYnMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRwcm9ncmVzcyAmJiBtaWNyb3RpbWUodHJ1ZSkgLSAkbGFzdFVwZGF0ZSA+IDAuMSkgewogICAgICAgICAgICAgICAgJGxhc3RVcGRhdGUgPSBtaWNyb3RpbWUodHJ1ZSk7CiAgICAgICAgICAgICAgICAkcHJvZ3Jlc3MtPnNldFByb2dyZXNzKCRwcm9ncmVzcy0+Z2V0TWF4U3RlcHMoKSAtICRhY3RpdmVKb2JzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkYWN0aXZlSm9icykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGFzIHdlIHNraXAgcHJvZ3Jlc3MgdXBkYXRlcyBpZiB0aGV5IGFyZSB0b28gcXVpY2ssIG1ha2Ugc3VyZSB3ZSBkbyBvbmUgbGFzdCBvbmUgaGVyZSBhdCAxMDAlCiAgICAgICAgaWYgKCRwcm9ncmVzcykgewogICAgICAgICAgICAkcHJvZ3Jlc3MtPnNldFByb2dyZXNzKCRwcm9ncmVzcy0+Z2V0TWF4U3RlcHMoKSk7CiAgICAgICAgfQoKICAgICAgICB1bnNldCgkdGhpcy0+Y3VycmVudFByb21pc2VzWyR3YWl0SW5kZXhdKTsKICAgICAgICBpZiAoJHVuY2F1Z2h0KSB7CiAgICAgICAgICAgIHRocm93ICR1bmNhdWdodDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFib3J0Sm9icygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmN1cnJlbnRQcm9taXNlcyBhcyAkcHJvbWlzZUdyb3VwKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwcm9taXNlR3JvdXAgYXMgJHByb21pc2UpIHsKICAgICAgICAgICAgICAgICRwcm9taXNlLT5jYW5jZWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdpdAp7CiAgICBwcml2YXRlIHN0YXRpYyAkdmVyc2lvbiA9IGZhbHNlOwoKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcm90ZWN0ZWQgJGlvOwogICAgLyoqIEB2YXIgQ29uZmlnICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgLyoqIEB2YXIgRmlsZXN5c3RlbSAqLwogICAgcHJvdGVjdGVkICRmaWxlc3lzdGVtOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MsIEZpbGVzeXN0ZW0gJGZzKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtID0gJGZzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRjd2QsICRpbml0aWFsQ2xvbmUgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBFbnN1cmUgd2UgYXJlIGFsbG93ZWQgdG8gdXNlIHRoaXMgVVJMIGJ5IGNvbmZpZwogICAgICAgICR0aGlzLT5jb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJHVybCwgJHRoaXMtPmlvKTsKCiAgICAgICAgaWYgKCRpbml0aWFsQ2xvbmUpIHsKICAgICAgICAgICAgJG9yaWdDd2QgPSAkY3dkOwogICAgICAgICAgICAkY3dkID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XnNzaDovL1teQF0rQFteOl0rOlteMC05XSt9JywgJHVybCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBzb3VyY2UgVVJMICcgLiAkdXJsIC4gJyBpcyBpbnZhbGlkLCBzc2ggVVJMcyBzaG91bGQgaGF2ZSBhIHBvcnQgbnVtYmVyIGFmdGVyICI6Ii4nIC4gIlxuIiAuICdVc2Ugc3NoOi8vZ2l0QGV4YW1wbGUuY29tOjIyL3BhdGggb3IganVzdCBnaXRAZXhhbXBsZS5jb206cGF0aCBpZiB5b3UgZG8gbm90IHdhbnQgdG8gcHJvdmlkZSBhIHBhc3N3b3JkIG9yIGN1c3RvbSBwb3J0LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaW5pdGlhbENsb25lKSB7CiAgICAgICAgICAgIC8vIGNhcHR1cmUgdXNlcm5hbWUvcGFzc3dvcmQgZnJvbSBVUkwgaWYgdGhlcmUgaXMgb25lIGFuZCB3ZSBoYXZlIG5vIGF1dGggY29uZmlndXJlZCB5ZXQKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZW1vdGUgLXYnLCAkb3V0cHV0LCAkY3dkKTsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86Y29tcG9zZXJ8b3JpZ2luKVxzK2h0dHBzPzovLyguKyk6KC4rKUAoW14vXSspfWltJywgJG91dHB1dCwgJG1hdGNoKSAmJiAhJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbM10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFszXSwgcmF3dXJsZGVjb2RlKCRtYXRjaFsxXSksIHJhd3VybGRlY29kZSgkbWF0Y2hbMl0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHByb3RvY29scyA9ICR0aGlzLT5jb25maWctPmdldCgnZ2l0aHViLXByb3RvY29scycpOwogICAgICAgIGlmICghaXNfYXJyYXkoJHByb3RvY29scykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb25maWcgdmFsdWUgImdpdGh1Yi1wcm90b2NvbHMiIG11c3QgYmUgYW4gYXJyYXksIGdvdCAnIC4gZ2V0dHlwZSgkcHJvdG9jb2xzKSk7CiAgICAgICAgfQogICAgICAgIC8vIHB1YmxpYyBnaXRodWIsIGF1dG9zd2l0Y2ggcHJvdG9jb2xzCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86aHR0cHM/fGdpdCk6Ly8nIC4gc2VsZjo6Z2V0R2l0SHViRG9tYWluc1JlZ2V4KCR0aGlzLT5jb25maWcpIC4gJy8oLiopfScsICR1cmwsICRtYXRjaCkpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHByb3RvY29scyBhcyAkcHJvdG9jb2wpIHsKICAgICAgICAgICAgICAgIGlmICgnc3NoJyA9PT0gJHByb3RvY29sKSB7CiAgICAgICAgICAgICAgICAgICAgJHByb3RvVXJsID0gImdpdEAiIC4gJG1hdGNoWzFdIC4gIjoiIC4gJG1hdGNoWzJdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcHJvdG9VcmwgPSAkcHJvdG9jb2wgLiAiOi8vIiAuICRtYXRjaFsxXSAuICIvIiAuICRtYXRjaFsyXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJHByb3RvVXJsKSwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSAnLSAnIC4gJHByb3RvVXJsIC4gIlxuIiAuIHByZWdfcmVwbGFjZSgnI14jbScsICcgICcsICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKCiAgICAgICAgICAgICAgICBpZiAoJGluaXRpYWxDbG9uZSAmJiBpc3NldCgkb3JpZ0N3ZCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRvcmlnQ3dkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZmFpbGVkIHRvIGNoZWNrb3V0LCBmaXJzdCBjaGVjayBnaXQgYWNjZXNzaWJpbGl0eQogICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzFdKSAmJiAhJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT50aHJvd0V4Y2VwdGlvbignRmFpbGVkIHRvIGNsb25lICcgLiAkdXJsIC4gJyB2aWEgJyAuIGltcGxvZGUoJywgJywgJHByb3RvY29scykgLiAnIHByb3RvY29scywgYWJvcnRpbmcuJyAuICJcblxuIiAuIGltcGxvZGUoIlxuIiwgJG1lc3NhZ2VzKSwgJHVybCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGlmIHdlIGhhdmUgYSBwcml2YXRlIGdpdGh1YiB1cmwgYW5kIHRoZSBzc2ggcHJvdG9jb2wgaXMgZGlzYWJsZWQgdGhlbiB3ZSBza2lwIGl0IGFuZCBkaXJlY3RseSBmYWxsYmFjayB0byBodHRwcwogICAgICAgICRieXBhc3NTc2hGb3JHaXRIdWIgPSBwcmVnX21hdGNoKCd7XmdpdEAnIC4gc2VsZjo6Z2V0R2l0SHViRG9tYWluc1JlZ2V4KCR0aGlzLT5jb25maWcpIC4gJzooLis/KVwuZ2l0JH1pJywgJHVybCkgJiYgIWluX2FycmF5KCdzc2gnLCAkcHJvdG9jb2xzLCB0cnVlKTsKCiAgICAgICAgJGNvbW1hbmQgPSBjYWxsX3VzZXJfZnVuYygkY29tbWFuZENhbGxhYmxlLCAkdXJsKTsKCiAgICAgICAgJGF1dGggPSBudWxsOwogICAgICAgIGlmICgkYnlwYXNzU3NoRm9yR2l0SHViIHx8IDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgJGVycm9yTXNnID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgIC8vIHByaXZhdGUgZ2l0aHViIHJlcG9zaXRvcnkgd2l0aG91dCBzc2gga2V5IGFjY2VzcywgdHJ5IGh0dHBzIHdpdGggYXV0aAogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15naXRAJyAuIHNlbGY6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICc6KC4rPylcLmdpdCR9aScsICR1cmwsICRtYXRjaCkKICAgICAgICAgICAgICAgIHx8IHByZWdfbWF0Y2goJ3teaHR0cHM/Oi8vJyAuIHNlbGY6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICcvKC4qPykoPzpcLmdpdCk/JH1pJywgJHVybCwgJG1hdGNoKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwgPSBuZXcgR2l0SHViKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ0Nsb25pbmcgZmFpbGVkIHVzaW5nIGFuIHNzaCBrZXkgZm9yIGF1dGhlbnRpY2F0aW9uLCBlbnRlciB5b3VyIEdpdEh1YiBjcmVkZW50aWFscyB0byBhY2Nlc3MgcHJpdmF0ZSByZXBvcyc7CgogICAgICAgICAgICAgICAgICAgIGlmICghJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoKCRtYXRjaFsxXSkgJiYgJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGdpdEh1YlV0aWwtPmF1dGhvcml6ZU9BdXRoSW50ZXJhY3RpdmVseSgkbWF0Y2hbMV0sICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzFdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pOwogICAgICAgICAgICAgICAgICAgICRhdXRoVXJsID0gJ2h0dHBzOi8vJyAuIHJhd3VybGVuY29kZSgkYXV0aFsndXNlcm5hbWUnXSkgLiAnOicgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3Bhc3N3b3JkJ10pIC4gJ0AnIC4gJG1hdGNoWzFdIC4gJy8nIC4gJG1hdGNoWzJdIC4gJy5naXQnOwogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgne15odHRwczovLyhiaXRidWNrZXRcLm9yZykvKC4qPykoPzpcLmdpdCk/JH1pJywgJHVybCwgJG1hdGNoKSkgeyAvL2JpdGJ1Y2tldCBvYXV0aAogICAgICAgICAgICAgICAgJGJpdGJ1Y2tldFV0aWwgPSBuZXcgQml0YnVja2V0KCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnRW50ZXIgeW91ciBCaXRidWNrZXQgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRiaXRidWNrZXRVdGlsLT5hdXRob3JpemVPQXV0aCgkbWF0Y2hbMV0pICYmICR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRiaXRidWNrZXRVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG1hdGNoWzFdLCAkbWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRhY2Nlc3NUb2tlbiA9ICRiaXRidWNrZXRVdGlsLT5nZXRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPnNldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSwgJ3gtdG9rZW4tYXV0aCcsICRhY2Nlc3NUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy9XZSdyZSBhdXRoZW50aWNhdGluZyB3aXRoIGEgbG9jYWxseSBzdG9yZWQgY29uc3VtZXIuCiAgICAgICAgICAgICAgICAgICAgJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSk7CgogICAgICAgICAgICAgICAgICAgIC8vV2UgYWxyZWFkeSBoYXZlIGFuIGFjY2Vzc190b2tlbiBmcm9tIGEgcHJldmlvdXMgcmVxdWVzdC4KICAgICAgICAgICAgICAgICAgICBpZiAoJGF1dGhbJ3VzZXJuYW1lJ10gIT09ICd4LXRva2VuLWF1dGgnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhY2Nlc3NUb2tlbiA9ICRiaXRidWNrZXRVdGlsLT5yZXF1ZXN0VG9rZW4oJG1hdGNoWzFdLCAkYXV0aFsndXNlcm5hbWUnXSwgJGF1dGhbJ3Bhc3N3b3JkJ10pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRhY2Nlc3NUb2tlbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+c2V0QXV0aGVudGljYXRpb24oJG1hdGNoWzFdLCAneC10b2tlbi1hdXRoJywgJGFjY2Vzc1Rva2VuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGF1dGggPSAkdGhpcy0+aW8tPmdldEF1dGhlbnRpY2F0aW9uKCRtYXRjaFsxXSk7CiAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAnaHR0cHM6Ly8nIC4gcmF3dXJsZW5jb2RlKCRhdXRoWyd1c2VybmFtZSddKSAuICc6JyAuIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkgLiAnQCcgLiAkbWF0Y2hbMV0gLiAnLycgLiAkbWF0Y2hbMl0gLiAnLmdpdCc7CgogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gRmFsbGluZyBiYWNrIHRvIHNzaAogICAgICAgICAgICAgICAgICAgICRzc2hVcmwgPSAnZ2l0QGJpdGJ1Y2tldC5vcmc6JyAuICRtYXRjaFsyXSAuICcuZ2l0JzsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBObyBiaXRidWNrZXQgYXV0aGVudGljYXRpb24gY29uZmlndXJlZC4gRmFsbGluZyBiYWNrIHRvIHNzaC4nKTsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZCA9IGNhbGxfdXNlcl9mdW5jKCRjb21tYW5kQ2FsbGFibGUsICRzc2hVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICBwcmVnX21hdGNoKCd7XihnaXQpQCcgLiBzZWxmOjpnZXRHaXRMYWJEb21haW5zUmVnZXgoJHRoaXMtPmNvbmZpZykgLiAnOiguKz9cLmdpdCkkfWknLCAkdXJsLCAkbWF0Y2gpCiAgICAgICAgICAgICAgICB8fCBwcmVnX21hdGNoKCd7XihodHRwcz8pOi8vJyAuIHNlbGY6OmdldEdpdExhYkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKSAuICcvKC4qKX1pJywgJHVybCwgJG1hdGNoKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGlmICgkbWF0Y2hbMV0gPT09ICdnaXQnKSB7CiAgICAgICAgICAgICAgICAgICAgJG1hdGNoWzFdID0gJ2h0dHBzJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRnaXRMYWJVdGlsID0gbmV3IEdpdExhYigkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzKTsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdDbG9uaW5nIGZhaWxlZCwgZW50ZXIgeW91ciBHaXRMYWIgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHByaXZhdGUgcmVwb3MnOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aCgkbWF0Y2hbMl0pICYmICR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRnaXRMYWJVdGlsLT5hdXRob3JpemVPQXV0aEludGVyYWN0aXZlbHkoJG1hdGNoWzFdLCAkbWF0Y2hbMl0sICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0pOwogICAgICAgICAgICAgICAgICAgIGlmICgkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ3ByaXZhdGUtdG9rZW4nIHx8ICRhdXRoWydwYXNzd29yZCddID09PSAnb2F1dGgyJyB8fCAkYXV0aFsncGFzc3dvcmQnXSA9PT0gJ2dpdGxhYi1jaS10b2tlbicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAkbWF0Y2hbMV0gLiAnOi8vJyAuIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkgLiAnOicgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJ0AnIC4gJG1hdGNoWzJdIC4gJy8nIC4gJG1hdGNoWzNdOyAvLyBzd2FwIHVzZXJuYW1lIGFuZCBwYXNzd29yZAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRoVXJsID0gJG1hdGNoWzFdIC4gJzovLycgLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJzonIC4gcmF3dXJsZW5jb2RlKCRhdXRoWydwYXNzd29yZCddKSAuICdAJyAuICRtYXRjaFsyXSAuICcvJyAuICRtYXRjaFszXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhVcmwpOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsICRjd2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRlcnJvck1zZyA9ICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlzQXV0aGVudGljYXRpb25GYWlsdXJlKCR1cmwsICRtYXRjaCkpIHsgLy8gcHJpdmF0ZSBub24tZ2l0aHViL2dpdGxhYi9iaXRidWNrZXQgcmVwbyB0aGF0IGZhaWxlZCB0byBhdXRoZW50aWNhdGUKICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJG1hdGNoWzJdLCAnQCcpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkYXV0aFBhcnRzLCAkbWF0Y2hbMl0pID0gZXhwbG9kZSgnQCcsICRtYXRjaFsyXSwgMik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHN0b3JlQXV0aCA9IGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aGFzQXV0aGVudGljYXRpb24oJG1hdGNoWzJdKSkgewogICAgICAgICAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0pOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRVc2VybmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRhdXRoUGFydHMpICYmICRhdXRoUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGF1dGhQYXJ0cywgJzonKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgkZGVmYXVsdFVzZXJuYW1lLCApID0gZXhwbG9kZSgnOicsICRhdXRoUGFydHMsIDIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRVc2VybmFtZSA9ICRhdXRoUGFydHM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIEF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkICg8aW5mbz4nIC4gJG1hdGNoWzJdIC4gJzwvaW5mbz4pOicpOwogICAgICAgICAgICAgICAgICAgICRhdXRoID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICd1c2VybmFtZScgPT4gJHRoaXMtPmlvLT5hc2soJyAgICAgIFVzZXJuYW1lOiAnLCAkZGVmYXVsdFVzZXJuYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3Bhc3N3b3JkJyA9PiAkdGhpcy0+aW8tPmFza0FuZEhpZGVBbnN3ZXIoJyAgICAgIFBhc3N3b3JkOiAnKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRzdG9yZUF1dGggPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ3N0b3JlLWF1dGhzJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRhdXRoKSB7CiAgICAgICAgICAgICAgICAgICAgJGF1dGhVcmwgPSAkbWF0Y2hbMV0gLiByYXd1cmxlbmNvZGUoJGF1dGhbJ3VzZXJuYW1lJ10pIC4gJzonIC4gcmF3dXJsZW5jb2RlKCRhdXRoWydwYXNzd29yZCddKSAuICdAJyAuICRtYXRjaFsyXSAuICRtYXRjaFszXTsKCiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmQgPSBjYWxsX3VzZXJfZnVuYygkY29tbWFuZENhbGxhYmxlLCAkYXV0aFVybCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT5zZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbMl0sICRhdXRoWyd1c2VybmFtZSddLCAkYXV0aFsncGFzc3dvcmQnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRoSGVscGVyID0gbmV3IEF1dGhIZWxwZXIoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGF1dGhIZWxwZXItPnN0b3JlQXV0aCgkbWF0Y2hbMl0sICRzdG9yZUF1dGgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGVycm9yTXNnID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaW5pdGlhbENsb25lICYmIGlzc2V0KCRvcmlnQ3dkKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkb3JpZ0N3ZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT50aHJvd0V4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJGVycm9yTXNnLCAkdXJsKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHN5bmNNaXJyb3IoJHVybCwgJGRpcikKICAgIHsKICAgICAgICBpZiAoZ2V0ZW52KCdDT01QT1NFUl9ESVNBQkxFX05FVFdPUksnKSAmJiBnZXRlbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpICE9PSAncHJpbWUnKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QWJvcnRpbmcgZ2l0IG1pcnJvciBzeW5jIG9mICcuJHVybC4nIGFzIG5ldHdvcmsgaXMgZGlzYWJsZWQ8L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyB1cGRhdGUgdGhlIHJlcG8gaWYgaXQgaXMgYSB2YWxpZCBnaXQgcmVwb3NpdG9yeQogICAgICAgIGlmIChpc19kaXIoJGRpcikgJiYgMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCByZXYtcGFyc2UgLS1naXQtZGlyJywgJG91dHB1dCwgJGRpcikgJiYgdHJpbSgkb3V0cHV0KSA9PT0gJy4nKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkY29tbWFuZENhbGxhYmxlID0gZnVuY3Rpb24gKCR1cmwpIHsKICAgICAgICAgICAgICAgICAgICAkc2FuaXRpemVkVXJsID0gcHJlZ19yZXBsYWNlKCd7Oi8vKFteQF0rPyk6KC4rPylAfScsICc6Ly8nLCAkdXJsKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJ2dpdCByZW1vdGUgc2V0LXVybCBvcmlnaW4gLS0gJXMgJiYgZ2l0IHJlbW90ZSB1cGRhdGUgLS1wcnVuZSBvcmlnaW4gJiYgZ2l0IHJlbW90ZSBzZXQtdXJsIG9yaWdpbiAtLSAlcyAmJiBnaXQgZ2MgLS1hdXRvJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRzYW5pdGl6ZWRVcmwpKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAkdGhpcy0+cnVuQ29tbWFuZCgkY29tbWFuZENhbGxhYmxlLCAkdXJsLCAkZGlyKTsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+U3luYyBtaXJyb3IgZmFpbGVkOiAnIC4gJGUtPmdldE1lc3NhZ2UoKSAuICc8L2Vycm9yPicsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGNsZWFuIHVwIGRpcmVjdG9yeSBhbmQgZG8gYSBmcmVzaCBjbG9uZSBpbnRvIGl0CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkZGlyKTsKCiAgICAgICAgJGNvbW1hbmRDYWxsYWJsZSA9IGZ1bmN0aW9uICgkdXJsKSB1c2UgKCRkaXIpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJ2dpdCBjbG9uZSAtLW1pcnJvciAtLSAlcyAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZGlyKSk7CiAgICAgICAgfTsKCiAgICAgICAgJHRoaXMtPnJ1bkNvbW1hbmQoJGNvbW1hbmRDYWxsYWJsZSwgJHVybCwgJGRpciwgdHJ1ZSk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBmZXRjaFJlZk9yU3luY01pcnJvcigkdXJsLCAkZGlyLCAkcmVmKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2hlY2tSZWZJc0luTWlycm9yKCRkaXIsICRyZWYpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5zeW5jTWlycm9yKCR1cmwsICRkaXIpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y2hlY2tSZWZJc0luTWlycm9yKCRkaXIsICRyZWYpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Tm9TaG93U2lnbmF0dXJlRmxhZyhQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MpCiAgICB7CiAgICAgICAgJGdpdFZlcnNpb24gPSBzZWxmOjpnZXRWZXJzaW9uKCRwcm9jZXNzKTsKICAgICAgICBpZiAoJGdpdFZlcnNpb24gJiYgdmVyc2lvbl9jb21wYXJlKCRnaXRWZXJzaW9uLCAnMi4xMC4wLXJjMCcsICc+PScpKSB7CiAgICAgICAgICAgIHJldHVybiAnIC0tbm8tc2hvdy1zaWduYXR1cmUnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICcnOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tSZWZJc0luTWlycm9yKCRkaXIsICRyZWYpCiAgICB7CiAgICAgICAgaWYgKGlzX2RpcigkZGlyKSAmJiAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHJldi1wYXJzZSAtLWdpdC1kaXInLCAkb3V0cHV0LCAkZGlyKSAmJiB0cmltKCRvdXRwdXQpID09PSAnLicpIHsKICAgICAgICAgICAgJGVzY2FwZWRSZWYgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVmLidee2NvbW1pdH0nKTsKICAgICAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoc3ByaW50ZignZ2l0IHJldi1wYXJzZSAtLXF1aWV0IC0tdmVyaWZ5ICVzJywgJGVzY2FwZWRSZWYpLCAkaWdub3JlZE91dHB1dCwgJGRpcik7CiAgICAgICAgICAgIGlmICgkZXhpdENvZGUgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc0F1dGhlbnRpY2F0aW9uRmFpbHVyZSgkdXJsLCAmJG1hdGNoKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgne14oaHR0cHM/Oi8vKShbXi9dKykoLiopJH1pJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkYXV0aEZhaWx1cmVzID0gYXJyYXkoCiAgICAgICAgICAgICdmYXRhbDogQXV0aGVudGljYXRpb24gZmFpbGVkJywKICAgICAgICAgICAgJ3JlbW90ZSBlcnJvcjogSW52YWxpZCB1c2VybmFtZSBvciBwYXNzd29yZC4nLAogICAgICAgICAgICAnZXJyb3I6IDQwMSBVbmF1dGhvcml6ZWQnLAogICAgICAgICAgICAnZmF0YWw6IHVuYWJsZSB0byBhY2Nlc3MnLAogICAgICAgICAgICAnZmF0YWw6IGNvdWxkIG5vdCByZWFkIFVzZXJuYW1lJywKICAgICAgICApOwoKICAgICAgICAkZXJyb3JPdXRwdXQgPSAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICBmb3JlYWNoICgkYXV0aEZhaWx1cmVzIGFzICRhdXRoRmFpbHVyZSkgewogICAgICAgICAgICBpZiAoc3RycG9zKCRlcnJvck91dHB1dCwgJGF1dGhGYWlsdXJlKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjbGVhbkVudigpCiAgICB7CiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTA0MDAgJiYgaW5pX2dldCgnc2FmZV9tb2RlJykgJiYgZmFsc2UgPT09IHN0cnBvcyhpbmlfZ2V0KCdzYWZlX21vZGVfYWxsb3dlZF9lbnZfdmFycycpLCAnR0lUX0FTS1BBU1MnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ3NhZmVfbW9kZSBpcyBlbmFibGVkIGFuZCBzYWZlX21vZGVfYWxsb3dlZF9lbnZfdmFycyBkb2VzIG5vdCBjb250YWluIEdJVF9BU0tQQVNTLCBjYW4gbm90IHNldCBlbnYgdmFyLiBZb3UgY2FuIGRpc2FibGUgc2FmZV9tb2RlIHdpdGggIi1kc2FmZV9tb2RlPTAiIHdoZW4gcnVubmluZyBjb21wb3NlcicpOwogICAgICAgIH0KCiAgICAgICAgLy8gYWRkZWQgaW4gZ2l0IDEuNy4xLCBwcmV2ZW50cyBwcm9tcHRpbmcgdGhlIHVzZXIgZm9yIHVzZXJuYW1lL3Bhc3N3b3JkCiAgICAgICAgaWYgKGdldGVudignR0lUX0FTS1BBU1MnKSAhPT0gJ2VjaG8nKSB7CiAgICAgICAgICAgIHB1dGVudignR0lUX0FTS1BBU1M9ZWNobycpOwogICAgICAgICAgICAkX1NFUlZFUlsnR0lUX0FTS1BBU1MnXSA9ICdlY2hvJzsKICAgICAgICB9CgogICAgICAgIC8vIGNsZWFuIHVwIHJvZ3VlIGdpdCBlbnYgdmFycyBpbiBjYXNlIHRoaXMgaXMgcnVubmluZyBpbiBhIGdpdCBob29rCiAgICAgICAgaWYgKGdldGVudignR0lUX0RJUicpKSB7CiAgICAgICAgICAgIHB1dGVudignR0lUX0RJUicpOwogICAgICAgICAgICB1bnNldCgkX1NFUlZFUlsnR0lUX0RJUiddKTsKICAgICAgICB9CiAgICAgICAgaWYgKGdldGVudignR0lUX1dPUktfVFJFRScpKSB7CiAgICAgICAgICAgIHB1dGVudignR0lUX1dPUktfVFJFRScpOwogICAgICAgICAgICB1bnNldCgkX1NFUlZFUlsnR0lUX1dPUktfVFJFRSddKTsKICAgICAgICB9CgogICAgICAgIC8vIFJ1biBwcm9jZXNzZXMgd2l0aCBwcmVkaWN0YWJsZSBMQU5HVUFHRQogICAgICAgIGlmIChnZXRlbnYoJ0xBTkdVQUdFJykgIT09ICdDJykgewogICAgICAgICAgICBwdXRlbnYoJ0xBTkdVQUdFPUMnKTsKICAgICAgICAgICAgJF9TRVJWRVJbJ0xBTkdVQUdFJ10gPSAnQyc7CiAgICAgICAgfQoKICAgICAgICAvLyBjbGVhbiB1cCBlbnYgZm9yIE9TWCwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMjE0NiNpc3N1ZWNvbW1lbnQtMzU0Nzg5NDAKICAgICAgICBwdXRlbnYoIkRZTERfTElCUkFSWV9QQVRIIik7CiAgICAgICAgdW5zZXQoJF9TRVJWRVJbJ0RZTERfTElCUkFSWV9QQVRIJ10pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0R2l0SHViRG9tYWluc1JlZ2V4KENvbmZpZyAkY29uZmlnKQogICAgewogICAgICAgIHJldHVybiAnKCcgLiBpbXBsb2RlKCd8JywgYXJyYXlfbWFwKCdwcmVnX3F1b3RlJywgJGNvbmZpZy0+Z2V0KCdnaXRodWItZG9tYWlucycpKSkgLiAnKSc7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRHaXRMYWJEb21haW5zUmVnZXgoQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgcmV0dXJuICcoJyAuIGltcGxvZGUoJ3wnLCBhcnJheV9tYXAoJ3ByZWdfcXVvdGUnLCAkY29uZmlnLT5nZXQoJ2dpdGxhYi1kb21haW5zJykpKSAuICcpJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKCRtZXNzYWdlLCAkdXJsKQogICAgewogICAgICAgIC8vIGdpdCBtaWdodCBkZWxldGUgYSBkaXJlY3Rvcnkgd2hlbiBpdCBmYWlscyBhbmQgcGhwIHdpbGwgbm90IGtub3cKICAgICAgICBjbGVhcnN0YXRjYWNoZSgpOwoKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCAtLXZlcnNpb24nLCAkaWdub3JlZE91dHB1dCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKFVybDo6c2FuaXRpemUoJ0ZhaWxlZCB0byBjbG9uZSAnIC4gJHVybCAuICcsIGdpdCB3YXMgbm90IGZvdW5kLCBjaGVjayB0aGF0IGl0IGlzIGluc3RhbGxlZCBhbmQgaW4geW91ciBQQVRIIGVudi4nIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihVcmw6OnNhbml0aXplKCRtZXNzYWdlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgZ2l0IHZlcnNpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgZ2l0IHZlcnNpb24gbnVtYmVyLCBpZiBwcmVzZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFZlcnNpb24oUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgIGlmIChmYWxzZSA9PT0gc2VsZjo6JHZlcnNpb24pIHsKICAgICAgICAgICAgc2VsZjo6JHZlcnNpb24gPSBudWxsOwogICAgICAgICAgICBpZiAoMCA9PT0gJHByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCAtLXZlcnNpb24nLCAkb3V0cHV0KSAmJiBwcmVnX21hdGNoKCcvXmdpdCB2ZXJzaW9uIChcZCsoPzpcLlxkKykrKS9tJywgJG91dHB1dCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokdmVyc2lvbiA9ICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JHZlcnNpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCi8qKgogKiBUZW1wb3JhcmlseSBzdXBwcmVzcyBQSFAgZXJyb3IgcmVwb3J0aW5nLCB1c3VhbGx5IHdhcm5pbmdzIGFuZCBiZWxvdy4KICoKICogQGF1dGhvciBOaWVscyBLZXVyZW50amVzIDxuaWVscy5rZXVyZW50amVzQG9taW5lcy5jb20+CiAqLwpjbGFzcyBTaWxlbmNlcgp7CiAgICAvKioKICAgICAqIEB2YXIgaW50W10gVW5wb3Agc3RhY2sKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHN0YWNrID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFN1cHByZXNzZXMgZ2l2ZW4gbWFzayBvciBlcnJvcnMuCiAgICAgKgogICAgICogQHBhcmFtICBpbnR8bnVsbCAkbWFzayBFcnJvciBsZXZlbHMgdG8gc3VwcHJlc3MsIGRlZmF1bHQgdmFsdWUgTlVMTCBpbmRpY2F0ZXMgYWxsIHdhcm5pbmdzIGFuZCBiZWxvdy4KICAgICAqIEByZXR1cm4gaW50ICAgICAgVGhlIG9sZCBlcnJvciByZXBvcnRpbmcgbGV2ZWwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VwcHJlc3MoJG1hc2sgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNzZXQoJG1hc2spKSB7CiAgICAgICAgICAgICRtYXNrID0gRV9XQVJOSU5HIHwgRV9OT1RJQ0UgfCBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UgfCBFX0RFUFJFQ0FURUQgfCBFX1VTRVJfREVQUkVDQVRFRCB8IEVfU1RSSUNUOwogICAgICAgIH0KICAgICAgICAkb2xkID0gZXJyb3JfcmVwb3J0aW5nKCk7CiAgICAgICAgc2VsZjo6JHN0YWNrW10gPSAkb2xkOwogICAgICAgIGVycm9yX3JlcG9ydGluZygkb2xkICYgfiRtYXNrKTsKCiAgICAgICAgcmV0dXJuICRvbGQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXN0b3JlcyBhIHNpbmdsZSBzdGF0ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXN0b3JlKCkKICAgIHsKICAgICAgICBpZiAoIWVtcHR5KHNlbGY6OiRzdGFjaykpIHsKICAgICAgICAgICAgZXJyb3JfcmVwb3J0aW5nKGFycmF5X3BvcChzZWxmOjokc3RhY2spKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxscyBhIHNwZWNpZmllZCBmdW5jdGlvbiB3aGlsZSBzaWxlbmNpbmcgd2FybmluZ3MgYW5kIGJlbG93LgogICAgICoKICAgICAqIEZ1dHVyZSBpbXByb3ZlbWVudDogd2hlbiBQSFAgcmVxdWlyZW1lbnRzIGFyZSByYWlzZWQgYWRkIENhbGxhYmxlIHR5cGUgaGludCAoNS40KSBhbmQgdmFyaWFkaWMgcGFyYW1ldGVycyAoNS42KQogICAgICoKICAgICAqIEBwYXJhbSAgY2FsbGFibGUgICAkY2FsbGFibGUgRnVuY3Rpb24gdG8gZXhlY3V0ZS4KICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiBBbnkgZXhjZXB0aW9ucyBmcm9tIHRoZSBjYWxsYmFjayBhcmUgcmV0aHJvd24uCiAgICAgKiBAcmV0dXJuIG1peGVkICAgICAgUmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjYWxsKCRjYWxsYWJsZSAvKiwgLi4uJHBhcmFtZXRlcnMgKi8pCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc2VsZjo6c3VwcHJlc3MoKTsKICAgICAgICAgICAgJHJlc3VsdCA9IGNhbGxfdXNlcl9mdW5jX2FycmF5KCRjYWxsYWJsZSwgYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAxKSk7CiAgICAgICAgICAgIHNlbGY6OnJlc3RvcmUoKTsKCiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gVXNlIGEgZmluYWxseSBibG9jayBmb3IgdGhpcyB3aGVuIHJlcXVpcmVtZW50cyBhcmUgcmFpc2VkIHRvIFBIUCA1LjUKICAgICAgICAgICAgc2VsZjo6cmVzdG9yZSgpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvbmFzIFJlbmF1ZG90IDxqb25hcy5yZW5hdWRvdEBnbWFpbC5jb20+CiAqLwpjbGFzcyBIZwp7CiAgICBwcml2YXRlIHN0YXRpYyAkdmVyc2lvbiA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIFxDb21wb3NlclxDb25maWcKICAgICAqLwogICAgcHJpdmF0ZSAkY29uZmlnOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3IKICAgICAqLwogICAgcHJpdmF0ZSAkcHJvY2VzczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgUHJvY2Vzc0V4ZWN1dG9yICRwcm9jZXNzKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRjd2QpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbmZpZy0+cHJvaGliaXRVcmxCeUNvbmZpZygkdXJsLCAkdGhpcy0+aW8pOwoKICAgICAgICAvLyBUcnkgYXMgaXMKICAgICAgICAkY29tbWFuZCA9IGNhbGxfdXNlcl9mdW5jKCRjb21tYW5kQ2FsbGFibGUsICR1cmwpOwoKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0LCAkY3dkKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBUcnkgd2l0aCB0aGUgYXV0aGVudGljYXRpb24gaW5mb3JtYXRpb24gYXZhaWxhYmxlCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKGh0dHBzPyk6Ly8oKC4rKSg/Olw6KC4rKSk/QCk/KFteL10rKSgvLiopP31taScsICR1cmwsICRtYXRjaCkgJiYgJHRoaXMtPmlvLT5oYXNBdXRoZW50aWNhdGlvbigkbWF0Y2hbNV0pKSB7CiAgICAgICAgICAgICRhdXRoID0gJHRoaXMtPmlvLT5nZXRBdXRoZW50aWNhdGlvbigkbWF0Y2hbNV0pOwogICAgICAgICAgICAkYXV0aGVudGljYXRlZFVybCA9ICRtYXRjaFsxXSAuICc6Ly8nIC4gcmF3dXJsZW5jb2RlKCRhdXRoWyd1c2VybmFtZSddKSAuICc6JyAuIHJhd3VybGVuY29kZSgkYXV0aFsncGFzc3dvcmQnXSkgLiAnQCcgLiAkbWF0Y2hbNV0gLiAoIWVtcHR5KCRtYXRjaFs2XSkgPyAkbWF0Y2hbNl0gOiBudWxsKTsKCiAgICAgICAgICAgICRjb21tYW5kID0gY2FsbF91c2VyX2Z1bmMoJGNvbW1hbmRDYWxsYWJsZSwgJGF1dGhlbnRpY2F0ZWRVcmwpOwoKICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgJGN3ZCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVycm9yID0gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGVycm9yID0gJ1RoZSBnaXZlbiBVUkwgKCcgLiAkdXJsIC4gJykgZG9lcyBub3QgbWF0Y2ggdGhlIHJlcXVpcmVkIGZvcm1hdCAoaHR0cChzKTovLyh1c2VybmFtZTpwYXNzd29yZEApZXhhbXBsZS5jb20vcGF0aC10by1yZXBvc2l0b3J5KSc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dGhyb3dFeGNlcHRpb24oJ0ZhaWxlZCB0byBjbG9uZSAnIC4gJHVybCAuICcsICcgLiAiXG5cbiIgLiAkZXJyb3IsICR1cmwpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdGhyb3dFeGNlcHRpb24oJG1lc3NhZ2UsICR1cmwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OmdldFZlcnNpb24oJHRoaXMtPnByb2Nlc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihVcmw6OnNhbml0aXplKCdGYWlsZWQgdG8gY2xvbmUgJyAuICR1cmwgLiAnLCBoZyB3YXMgbm90IGZvdW5kLCBjaGVjayB0aGF0IGl0IGlzIGluc3RhbGxlZCBhbmQgaW4geW91ciBQQVRIIGVudi4nIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihVcmw6OnNhbml0aXplKCRtZXNzYWdlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgaGcgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBoZyB2ZXJzaW9uIG51bWJlciwgaWYgcHJlc2VudC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcykKICAgIHsKICAgICAgICBpZiAoZmFsc2UgPT09IHNlbGY6OiR2ZXJzaW9uKSB7CiAgICAgICAgICAgIHNlbGY6OiR2ZXJzaW9uID0gbnVsbDsKICAgICAgICAgICAgaWYgKDAgPT09ICRwcm9jZXNzLT5leGVjdXRlKCdoZyAtLXZlcnNpb24nLCAkb3V0cHV0KSAmJiBwcmVnX21hdGNoKCcvXi4rPyAoXGQrKD86XC5cZCspKylcKT9ccj9cbi8nLCAkb3V0cHV0LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIHNlbGY6OiR2ZXJzaW9uID0gJG1hdGNoZXNbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokdmVyc2lvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxVdGlsOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9hZGVyXEFycmF5TG9hZGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcVmFsaWRhdGluZ0FycmF5TG9hZGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcSW52YWxpZFBhY2thZ2VFeGNlcHRpb247CnVzZSBDb21wb3NlclxKc29uXEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcU3BkeFxTcGR4TGljZW5zZXM7CgovKioKICogVmFsaWRhdGVzIGEgY29tcG9zZXIgY29uZmlndXJhdGlvbi4KICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENvbmZpZ1ZhbGlkYXRvcgp7CiAgICBjb25zdCBDSEVDS19WRVJTSU9OID0gMTsKCiAgICBwcml2YXRlICRpbzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyB0aGUgY29uZmlnLCBhbmQgcmV0dXJucyB0aGUgcmVzdWx0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgICAgICAgICAgICAgICAgICAgICAgIFRoZSBwYXRoIHRvIHRoZSBmaWxlCiAgICAgKiBAcGFyYW0gaW50ICAgICRhcnJheUxvYWRlclZhbGlkYXRpb25GbGFncyBGbGFncyBmb3IgQXJyYXlMb2FkZXIgdmFsaWRhdGlvbgogICAgICogQHBhcmFtIGludCAgICAkZmxhZ3MgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MgZm9yIHZhbGlkYXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IGEgdHJpcGxlIGNvbnRhaW5pbmcgdGhlIGVycm9ycywgcHVibGlzaGFibGUgZXJyb3JzLCBhbmQgd2FybmluZ3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlKCRmaWxlLCAkYXJyYXlMb2FkZXJWYWxpZGF0aW9uRmxhZ3MgPSBWYWxpZGF0aW5nQXJyYXlMb2FkZXI6OkNIRUNLX0FMTCwgJGZsYWdzID0gc2VsZjo6Q0hFQ0tfVkVSU0lPTikKICAgIHsKICAgICAgICAkZXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkcHVibGlzaEVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgJHdhcm5pbmdzID0gYXJyYXkoKTsKCiAgICAgICAgLy8gdmFsaWRhdGUganNvbiBzY2hlbWEKICAgICAgICAkbGF4VmFsaWQgPSBmYWxzZTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkanNvbiA9IG5ldyBKc29uRmlsZSgkZmlsZSwgbnVsbCwgJHRoaXMtPmlvKTsKICAgICAgICAgICAgJG1hbmlmZXN0ID0gJGpzb24tPnJlYWQoKTsKCiAgICAgICAgICAgICRqc29uLT52YWxpZGF0ZVNjaGVtYShKc29uRmlsZTo6TEFYX1NDSEVNQSk7CiAgICAgICAgICAgICRsYXhWYWxpZCA9IHRydWU7CiAgICAgICAgICAgICRqc29uLT52YWxpZGF0ZVNjaGVtYSgpOwogICAgICAgIH0gY2F0Y2ggKEpzb25WYWxpZGF0aW9uRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRlLT5nZXRFcnJvcnMoKSBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICAgICAgaWYgKCRsYXhWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICRwdWJsaXNoRXJyb3JzW10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yc1tdID0gJG1lc3NhZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRlcnJvcnNbXSA9ICRlLT5nZXRNZXNzYWdlKCk7CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoJGVycm9ycywgJHB1Ymxpc2hFcnJvcnMsICR3YXJuaW5ncyk7CiAgICAgICAgfQoKICAgICAgICAvLyB2YWxpZGF0ZSBhY3R1YWwgZGF0YQogICAgICAgIGlmIChlbXB0eSgkbWFuaWZlc3RbJ2xpY2Vuc2UnXSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAnTm8gbGljZW5zZSBzcGVjaWZpZWQsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGRvIHNvLiBGb3IgY2xvc2VkLXNvdXJjZSBzb2Z0d2FyZSB5b3UgbWF5IHVzZSAicHJvcHJpZXRhcnkiIGFzIGxpY2Vuc2UuJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbGljZW5zZXMgPSAoYXJyYXkpICRtYW5pZmVzdFsnbGljZW5zZSddOwoKICAgICAgICAgICAgLy8gc3RyaXAgcHJvcHJpZXRhcnkgc2luY2UgaXQncyBub3QgYSB2YWxpZCBTUERYIGlkZW50aWZpZXIsIGJ1dCBpcyBhY2NlcHRlZCBieSBjb21wb3NlcgogICAgICAgICAgICBmb3JlYWNoICgkbGljZW5zZXMgYXMgJGtleSA9PiAkbGljZW5zZSkgewogICAgICAgICAgICAgICAgaWYgKCdwcm9wcmlldGFyeScgPT09ICRsaWNlbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGxpY2Vuc2VzWyRrZXldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpY2Vuc2VWYWxpZGF0b3IgPSBuZXcgU3BkeExpY2Vuc2VzKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaWNlbnNlcyBhcyAkbGljZW5zZSkgewogICAgICAgICAgICAgICAgJHNwZHhMaWNlbnNlID0gJGxpY2Vuc2VWYWxpZGF0b3ItPmdldExpY2Vuc2VCeUlkZW50aWZpZXIoJGxpY2Vuc2UpOwogICAgICAgICAgICAgICAgaWYgKCRzcGR4TGljZW5zZSAmJiAkc3BkeExpY2Vuc2VbM10pIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15bQUxdP0dQTC1bMTIzXShcLlswMV0pP1wrJH1pJywgJGxpY2Vuc2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR3YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdMaWNlbnNlICIlcyIgaXMgYSBkZXByZWNhdGVkIFNQRFggbGljZW5zZSBpZGVudGlmaWVyLCB1c2UgIicuc3RyX3JlcGxhY2UoJysnLCAnJywgJGxpY2Vuc2UpLictb3ItbGF0ZXIiIGluc3RlYWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxpY2Vuc2UKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgne15bQUxdP0dQTC1bMTIzXShcLlswMV0pPyR9aScsICRsaWNlbnNlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkd2FybmluZ3NbXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTGljZW5zZSAiJXMiIGlzIGEgZGVwcmVjYXRlZCBTUERYIGxpY2Vuc2UgaWRlbnRpZmllciwgdXNlICInLiRsaWNlbnNlLictb25seSIgb3IgIicuJGxpY2Vuc2UuJy1vci1sYXRlciIgaW5zdGVhZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGljZW5zZQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR3YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdMaWNlbnNlICIlcyIgaXMgYSBkZXByZWNhdGVkIFNQRFggbGljZW5zZSBpZGVudGlmaWVyLCBzZWUgaHR0cHM6Ly9zcGR4Lm9yZy9saWNlbnNlcy8nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxpY2Vuc2UKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgoJGZsYWdzICYgc2VsZjo6Q0hFQ0tfVkVSU0lPTikgJiYgaXNzZXQoJG1hbmlmZXN0Wyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICR3YXJuaW5nc1tdID0gJ1RoZSB2ZXJzaW9uIGZpZWxkIGlzIHByZXNlbnQsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGxlYXZlIGl0IG91dCBpZiB0aGUgcGFja2FnZSBpcyBwdWJsaXNoZWQgb24gUGFja2FnaXN0Lic7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRtYW5pZmVzdFsnbmFtZSddKSAmJiBwcmVnX21hdGNoKCd7W0EtWl19JywgJG1hbmlmZXN0WyduYW1lJ10pKSB7CiAgICAgICAgICAgICRzdWdnZXN0TmFtZSA9IHByZWdfcmVwbGFjZSgneyg/OihbYS16XSkoW0EtWl0pfChbQS1aXSkoW0EtWl1bYS16XSkpfScsICdcXDFcXDMtXFwyXFw0JywgJG1hbmlmZXN0WyduYW1lJ10pOwogICAgICAgICAgICAkc3VnZ2VzdE5hbWUgPSBzdHJ0b2xvd2VyKCRzdWdnZXN0TmFtZSk7CgogICAgICAgICAgICAkcHVibGlzaEVycm9yc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICdOYW1lICIlcyIgZG9lcyBub3QgbWF0Y2ggdGhlIGJlc3QgcHJhY3RpY2UgKGUuZy4gbG93ZXItY2FzZWQvd2l0aC1kYXNoZXMpLiBXZSBzdWdnZXN0IHVzaW5nICIlcyIgaW5zdGVhZC4gQXMgc3VjaCB5b3Ugd2lsbCBub3QgYmUgYWJsZSB0byBzdWJtaXQgaXQgdG8gUGFja2FnaXN0LicsCiAgICAgICAgICAgICAgICAkbWFuaWZlc3RbJ25hbWUnXSwKICAgICAgICAgICAgICAgICRzdWdnZXN0TmFtZQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkbWFuaWZlc3RbJ3R5cGUnXSkgJiYgJG1hbmlmZXN0Wyd0eXBlJ10gPT0gJ2NvbXBvc2VyLWluc3RhbGxlcicpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAiVGhlIHBhY2thZ2UgdHlwZSAnY29tcG9zZXItaW5zdGFsbGVyJyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgZGlzdHJpYnV0ZSB5b3VyIGN1c3RvbSBpbnN0YWxsZXJzIGFzIHBsdWdpbnMgZnJvbSBub3cgb24uIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvYXJ0aWNsZXMvcGx1Z2lucy5tZCBmb3IgcGx1Z2luIGRvY3VtZW50YXRpb24uIjsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlLWRldiBvdmVycmlkZXMKICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlJ10sICRtYW5pZmVzdFsncmVxdWlyZS1kZXYnXSkpIHsKICAgICAgICAgICAgJHJlcXVpcmVPdmVycmlkZXMgPSBhcnJheV9pbnRlcnNlY3Rfa2V5KCRtYW5pZmVzdFsncmVxdWlyZSddLCAkbWFuaWZlc3RbJ3JlcXVpcmUtZGV2J10pOwoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkcmVxdWlyZU92ZXJyaWRlcykpIHsKICAgICAgICAgICAgICAgICRwbHVyYWwgPSAoY291bnQoJHJlcXVpcmVPdmVycmlkZXMpID4gMSkgPyAnYXJlJyA6ICdpcyc7CiAgICAgICAgICAgICAgICAkd2FybmluZ3NbXSA9IGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkcmVxdWlyZU92ZXJyaWRlcykpLiAiIHskcGx1cmFsfSByZXF1aXJlZCBib3RoIGluIHJlcXVpcmUgYW5kIHJlcXVpcmUtZGV2LCB0aGlzIGNhbiBsZWFkIHRvIHVuZXhwZWN0ZWQgYmVoYXZpb3IiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBmb3IgbWVhbmluZ2xlc3MgcHJvdmlkZS9yZXBsYWNlIHNhdGlzZnlpbmcgcmVxdWlyZW1lbnRzCiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3Byb3ZpZGUnLCAncmVwbGFjZScpIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WyRsaW5rVHlwZV0pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheSgncmVxdWlyZScsICdyZXF1aXJlLWRldicpIGFzICRyZXF1aXJlVHlwZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJHJlcXVpcmVUeXBlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hbmlmZXN0WyRsaW5rVHlwZV0gYXMgJHByb3ZpZGUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJHJlcXVpcmVUeXBlXVskcHJvdmlkZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAnVGhlIHBhY2thZ2UgJyAuICRwcm92aWRlIC4gJyBpbiAnLiRyZXF1aXJlVHlwZS4nIGlzIGFsc28gbGlzdGVkIGluICcuJGxpbmtUeXBlLicgd2hpY2ggc2F0aXNmaWVzIHRoZSByZXF1aXJlbWVudC4gUmVtb3ZlIGl0IGZyb20gJy4kbGlua1R5cGUuJyBpZiB5b3Ugd2lzaCB0byBpbnN0YWxsIGl0Lic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBjb21taXQgcmVmZXJlbmNlcwogICAgICAgICRyZXF1aXJlID0gaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlJ10pID8gJG1hbmlmZXN0WydyZXF1aXJlJ10gOiBhcnJheSgpOwogICAgICAgICRyZXF1aXJlRGV2ID0gaXNzZXQoJG1hbmlmZXN0WydyZXF1aXJlLWRldiddKSA/ICRtYW5pZmVzdFsncmVxdWlyZS1kZXYnXSA6IGFycmF5KCk7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfbWVyZ2UoJHJlcXVpcmUsICRyZXF1aXJlRGV2KTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UgPT4gJHZlcnNpb24pIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy8jLycsICR2ZXJzaW9uKSA9PT0gMSkgewogICAgICAgICAgICAgICAgJHdhcm5pbmdzW10gPSBzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdUaGUgcGFja2FnZSAiJXMiIGlzIHBvaW50aW5nIHRvIGEgY29tbWl0LXJlZiwgdGhpcyBpcyBiYWQgcHJhY3RpY2UgYW5kIGNhbiBjYXVzZSB1bmZvcmVzZWVuIGlzc3Vlcy4nLAogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZXBvcnQgc2NyaXB0cy1kZXNjcmlwdGlvbnMgZm9yIG5vbi1leGlzdGVudCBzY3JpcHRzCiAgICAgICAgJHNjcmlwdHNEZXNjcmlwdGlvbnMgPSBpc3NldCgkbWFuaWZlc3RbJ3NjcmlwdHMtZGVzY3JpcHRpb25zJ10pID8gJG1hbmlmZXN0WydzY3JpcHRzLWRlc2NyaXB0aW9ucyddIDogYXJyYXkoKTsKICAgICAgICAkc2NyaXB0cyA9IGlzc2V0KCRtYW5pZmVzdFsnc2NyaXB0cyddKSA/ICRtYW5pZmVzdFsnc2NyaXB0cyddIDogYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkc2NyaXB0c0Rlc2NyaXB0aW9ucyBhcyAkc2NyaXB0TmFtZSA9PiAkc2NyaXB0RGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRzY3JpcHROYW1lLCAkc2NyaXB0cykpIHsKICAgICAgICAgICAgICAgICR3YXJuaW5nc1tdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnRGVzY3JpcHRpb24gZm9yIG5vbi1leGlzdGVudCBzY3JpcHQgIiVzIiBmb3VuZCBpbiAic2NyaXB0cy1kZXNjcmlwdGlvbnMiJywKICAgICAgICAgICAgICAgICAgICAkc2NyaXB0TmFtZQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgZm9yIGVtcHR5IHBzci0wL3Bzci00IG5hbWVzcGFjZSBwcmVmaXhlcwogICAgICAgIGlmIChpc3NldCgkbWFuaWZlc3RbJ2F1dG9sb2FkJ11bJ3Bzci0wJ11bJyddKSkgewogICAgICAgICAgICAkd2FybmluZ3NbXSA9ICJEZWZpbmluZyBhdXRvbG9hZC5wc3ItMCB3aXRoIGFuIGVtcHR5IG5hbWVzcGFjZSBwcmVmaXggaXMgYSBiYWQgaWRlYSBmb3IgcGVyZm9ybWFuY2UiOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG1hbmlmZXN0WydhdXRvbG9hZCddWydwc3ItNCddWycnXSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzW10gPSAiRGVmaW5pbmcgYXV0b2xvYWQucHNyLTQgd2l0aCBhbiBlbXB0eSBuYW1lc3BhY2UgcHJlZml4IGlzIGEgYmFkIGlkZWEgZm9yIHBlcmZvcm1hbmNlIjsKICAgICAgICB9CgogICAgICAgICRsb2FkZXIgPSBuZXcgVmFsaWRhdGluZ0FycmF5TG9hZGVyKG5ldyBBcnJheUxvYWRlcigpLCB0cnVlLCBudWxsLCAkYXJyYXlMb2FkZXJWYWxpZGF0aW9uRmxhZ3MpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJG1hbmlmZXN0Wyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkbWFuaWZlc3RbJ3ZlcnNpb24nXSA9ICcxLjAuMCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkbWFuaWZlc3RbJ25hbWUnXSkpIHsKICAgICAgICAgICAgICAgICRtYW5pZmVzdFsnbmFtZSddID0gJ2R1bW15L2R1bW15JzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbG9hZGVyLT5sb2FkKCRtYW5pZmVzdCk7CiAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhY2thZ2VFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGVycm9ycyA9IGFycmF5X21lcmdlKCRlcnJvcnMsICRlLT5nZXRFcnJvcnMoKSk7CiAgICAgICAgfQoKICAgICAgICAkd2FybmluZ3MgPSBhcnJheV9tZXJnZSgkd2FybmluZ3MsICRsb2FkZXItPmdldFdhcm5pbmdzKCkpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJGVycm9ycywgJHB1Ymxpc2hFcnJvcnMsICR3YXJuaW5ncyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxYZGVidWdIYW5kbGVyXFhkZWJ1Z0hhbmRsZXI7CgovKioKICogUHJvdmlkZXMgaW5pIGZpbGUgbG9jYXRpb24gZnVuY3Rpb25zIHRoYXQgd29yayB3aXRoIGFuZCB3aXRob3V0IGEgcmVzdGFydC4KICogV2hlbiB0aGUgcHJvY2VzcyBoYXMgcmVzdGFydGVkIGl0IHVzZXMgYSB0bXAgaW5pIGFuZCBzdG9yZXMgdGhlIG9yaWdpbmFsCiAqIGluaSBsb2NhdGlvbnMgaW4gYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuCiAqCiAqIEBhdXRob3IgSm9obiBTdGV2ZW5zb24gPGpvaG4tc3RldmVuc29uQGJsdWV5b25kZXIuY28udWs+CiAqLwpjbGFzcyBJbmlIZWxwZXIKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHBocC5pbmkgbG9jYXRpb25zIHdpdGggYXQgbGVhc3Qgb25lIGVudHJ5CiAgICAgKgogICAgICogVGhlIGVxdWl2YWxlbnQgb2YgY2FsbGluZyBwaHBfaW5pX2xvYWRlZF9maWxlIHRoZW4gcGhwX2luaV9zY2FubmVkX2ZpbGVzLgogICAgICogVGhlIGxvYWRlZCBpbmkgbG9jYXRpb24gaXMgdGhlIGZpcnN0IGVudHJ5IGFuZCBtYXkgYmUgZW1wdHkuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEFsbCgpCiAgICB7CiAgICAgICAgcmV0dXJuIFhkZWJ1Z0hhbmRsZXI6OmdldEFsbEluaUZpbGVzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBsb2FkZWQgcGhwLmluaSBmaWxlKHMpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRNZXNzYWdlKCkKICAgIHsKICAgICAgICAkcGF0aHMgPSBzZWxmOjpnZXRBbGwoKTsKCiAgICAgICAgaWYgKGVtcHR5KCRwYXRoc1swXSkpIHsKICAgICAgICAgICAgYXJyYXlfc2hpZnQoJHBhdGhzKTsKICAgICAgICB9CgogICAgICAgICRpbmkgPSBhcnJheV9zaGlmdCgkcGF0aHMpOwoKICAgICAgICBpZiAoZW1wdHkoJGluaSkpIHsKICAgICAgICAgICAgcmV0dXJuICdBIHBocC5pbmkgZmlsZSBkb2VzIG5vdCBleGlzdC4gWW91IHdpbGwgaGF2ZSB0byBjcmVhdGUgb25lLic7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRwYXRocykpIHsKICAgICAgICAgICAgcmV0dXJuICdZb3VyIGNvbW1hbmQtbGluZSBQSFAgaXMgdXNpbmcgbXVsdGlwbGUgaW5pIGZpbGVzLiBSdW4gYHBocCAtLWluaWAgdG8gc2hvdyB0aGVtLic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ1RoZSBwaHAuaW5pIHVzZWQgYnkgeW91ciBjb21tYW5kLWxpbmUgUEhQIGlzOiAnLiRpbmk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcVXRpbDsKCnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKCi8qKgogKiBDb252ZXJ0IFBIUCBlcnJvcnMgaW50byBleGNlcHRpb25zCiAqCiAqIEBhdXRob3IgQXJ0ZW0gTG9wYXRhIDxiaW96c2hvY2tAZ21haWwuY29tPgogKi8KY2xhc3MgRXJyb3JIYW5kbGVyCnsKICAgIHByaXZhdGUgc3RhdGljICRpbzsKCiAgICAvKioKICAgICAqIEVycm9yIGhhbmRsZXIKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZXZlbCAgIExldmVsIG9mIHRoZSBlcnJvciByYWlzZWQKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgRXJyb3IgbWVzc2FnZQogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSAgICBGaWxlbmFtZSB0aGF0IHRoZSBlcnJvciB3YXMgcmFpc2VkIGluCiAgICAgKiBAcGFyYW0gaW50ICAgICRsaW5lICAgIExpbmUgbnVtYmVyIHRoZSBlcnJvciB3YXMgcmFpc2VkIGF0CiAgICAgKgogICAgICogQHN0YXRpYwogICAgICogQHRocm93cyBcRXJyb3JFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhbmRsZSgkbGV2ZWwsICRtZXNzYWdlLCAkZmlsZSwgJGxpbmUpCiAgICB7CiAgICAgICAgLy8gZXJyb3IgY29kZSBpcyBub3QgaW5jbHVkZWQgaW4gZXJyb3JfcmVwb3J0aW5nCiAgICAgICAgaWYgKCEoZXJyb3JfcmVwb3J0aW5nKCkgJiAkbGV2ZWwpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChmaWx0ZXJfdmFyKGluaV9nZXQoJ3hkZWJ1Zy5zY3JlYW0nKSwgRklMVEVSX1ZBTElEQVRFX0JPT0xFQU4pKSB7CiAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblxuV2FybmluZzogWW91IGhhdmUgeGRlYnVnLnNjcmVhbSBlbmFibGVkLCB0aGUgd2FybmluZyBhYm92ZSBtYXkgYmUiLgogICAgICAgICAgICAiXG5hIGxlZ2l0aW1hdGVseSBzdXBwcmVzc2VkIGVycm9yIHRoYXQgeW91IHdlcmUgbm90IHN1cHBvc2VkIHRvIHNlZS4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsZXZlbCAhPT0gRV9ERVBSRUNBVEVEICYmICRsZXZlbCAhPT0gRV9VU0VSX0RFUFJFQ0FURUQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFcnJvckV4Y2VwdGlvbigkbWVzc2FnZSwgMCwgJGxldmVsLCAkZmlsZSwgJGxpbmUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6OiRpbykgewogICAgICAgICAgICBzZWxmOjokaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkRlcHJlY2F0aW9uIE5vdGljZTogJy4kbWVzc2FnZS4nIGluICcuJGZpbGUuJzonLiRsaW5lLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIGlmIChzZWxmOjokaW8tPmlzVmVyYm9zZSgpKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlN0YWNrIHRyYWNlOjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgIHNlbGY6OiRpby0+d3JpdGVFcnJvcihhcnJheV9maWx0ZXIoYXJyYXlfbWFwKGZ1bmN0aW9uICgkYSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYVsnbGluZSddLCAkYVsnZmlsZSddKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzx3YXJuaW5nPiAnLiRhWydmaWxlJ10uJzonLiRhWydsaW5lJ10uJzwvd2FybmluZz4nOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9LCBhcnJheV9zbGljZShkZWJ1Z19iYWNrdHJhY2UoKSwgMikpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgZXJyb3IgaGFuZGxlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2V8bnVsbCAkaW8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZWdpc3RlcihJT0ludGVyZmFjZSAkaW8gPSBudWxsKQogICAgewogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGFycmF5KF9fQ0xBU1NfXywgJ2hhbmRsZScpKTsKICAgICAgICBlcnJvcl9yZXBvcnRpbmcoRV9BTEwgfCBFX1NUUklDVCk7CiAgICAgICAgc2VsZjo6JGlvID0gJGlvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNjcmlwdDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50IGFzIEJhc2VFdmVudDsKCi8qKgogKiBUaGUgc2NyaXB0IGV2ZW50IGNsYXNzCiAqCiAqIEBhdXRob3IgRnJhbsOnb2lzIFBsdWNoaW5vIDxmcmFuY29pcy5wbHVjaGlub0BvcGVuZGlzcGxheS5jb20+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBFdmVudCBleHRlbmRzIEJhc2VFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgQ29tcG9zZXIgVGhlIGNvbXBvc2VyIGluc3RhbmNlCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbXBvc2VyOwoKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZSBUaGUgSU8gaW5zdGFuY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wgRGV2IG1vZGUgZmxhZwogICAgICovCiAgICBwcml2YXRlICRkZXZNb2RlOwoKICAgIC8qKgogICAgICogQHZhciBCYXNlRXZlbnQKICAgICAqLwogICAgcHJpdmF0ZSAkb3JpZ2luYXRpbmdFdmVudDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZSAgICAgVGhlIGV2ZW50IG5hbWUKICAgICAqIEBwYXJhbSBDb21wb3NlciAgICAkY29tcG9zZXIgVGhlIGNvbXBvc2VyIG9iamVjdAogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbyAgICAgICBUaGUgSU9JbnRlcmZhY2Ugb2JqZWN0CiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGRldk1vZGUgIFdoZXRoZXIgb3Igbm90IHdlIGFyZSBpbiBkZXYgbW9kZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICRhcmdzICAgICBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgJGZsYWdzICAgIE9wdGlvbmFsIGZsYWdzIHRvIHBhc3MgZGF0YSBub3QgYXMgYXJndW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCBDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbywgJGRldk1vZGUgPSBmYWxzZSwgYXJyYXkgJGFyZ3MgPSBhcnJheSgpLCBhcnJheSAkZmxhZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUsICRhcmdzLCAkZmxhZ3MpOwogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAkZGV2TW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbXBvc2VyIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gQ29tcG9zZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBvc2VyOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgSU8gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBJT0ludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SU8oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW87CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGRldiBtb2RlIGZsYWcKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGV2TW9kZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXZNb2RlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBvcmlnaW5hdGluZyBldmVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIFxDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnR8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3JpZ2luYXRpbmdFdmVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcmlnaW5hdGluZ0V2ZW50OwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBvcmlnaW5hdGluZyBldmVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFxDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnQgJGV2ZW50CiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcmlnaW5hdGluZ0V2ZW50KEJhc2VFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPm9yaWdpbmF0aW5nRXZlbnQgPSAkdGhpcy0+Y2FsY3VsYXRlT3JpZ2luYXRpbmdFdmVudCgkZXZlbnQpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB1cHBlci1tb3N0IGV2ZW50IGluIGNoYWluLgogICAgICoKICAgICAqIEBwYXJhbSAgXENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudCAkZXZlbnQKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNhbGN1bGF0ZU9yaWdpbmF0aW5nRXZlbnQoQmFzZUV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICBpZiAoJGV2ZW50IGluc3RhbmNlb2YgRXZlbnQgJiYgJGV2ZW50LT5nZXRPcmlnaW5hdGluZ0V2ZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jYWxjdWxhdGVPcmlnaW5hdGluZ0V2ZW50KCRldmVudC0+Z2V0T3JpZ2luYXRpbmdFdmVudCgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZXZlbnQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2NyaXB0OwoKLyoqCiAqIFRoZSBTY3JpcHQgRXZlbnRzLgogKgogKiBAYXV0aG9yIEZyYW7Dp29pcyBQbHVjaGlubyA8ZnJhbmNvaXMucGx1Y2hpbm9Ab3BlbmRpc3BsYXkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBTY3JpcHRFdmVudHMKewogICAgLyoqCiAgICAgKiBUaGUgUFJFX0lOU1RBTExfQ01EIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIGluc3RhbGwgY29tbWFuZCBpcyBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9JTlNUQUxMX0NNRCA9ICdwcmUtaW5zdGFsbC1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfSU5TVEFMTF9DTUQgZXZlbnQgb2NjdXJzIGFmdGVyIHRoZSBpbnN0YWxsIGNvbW1hbmQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX0lOU1RBTExfQ01EID0gJ3Bvc3QtaW5zdGFsbC1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9VUERBVEVfQ01EIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIHVwZGF0ZSBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX1VQREFURV9DTUQgPSAncHJlLXVwZGF0ZS1jbWQnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfVVBEQVRFX0NNRCBldmVudCBvY2N1cnMgYWZ0ZXIgdGhlIHVwZGF0ZSBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9VUERBVEVfQ01EID0gJ3Bvc3QtdXBkYXRlLWNtZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX1NUQVRVU19DTUQgZXZlbnQgb2NjdXJzIGJlZm9yZSB0aGUgc3RhdHVzIGNvbW1hbmQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfU1RBVFVTX0NNRCA9ICdwcmUtc3RhdHVzLWNtZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9TVEFUVVNfQ01EIGV2ZW50IG9jY3VycyBhZnRlciB0aGUgc3RhdHVzIGNvbW1hbmQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX1NUQVRVU19DTUQgPSAncG9zdC1zdGF0dXMtY21kJzsKCiAgICAvKioKICAgICAqIFRoZSBQUkVfQVVUT0xPQURfRFVNUCBldmVudCBvY2N1cnMgYmVmb3JlIHRoZSBhdXRvbG9hZCBmaWxlIGlzIGdlbmVyYXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9BVVRPTE9BRF9EVU1QID0gJ3ByZS1hdXRvbG9hZC1kdW1wJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX0FVVE9MT0FEX0RVTVAgZXZlbnQgb2NjdXJzIGFmdGVyIHRoZSBhdXRvbG9hZCBmaWxlIGhhcyBiZWVuIGdlbmVyYXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcU2NyaXB0XEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfQVVUT0xPQURfRFVNUCA9ICdwb3N0LWF1dG9sb2FkLWR1bXAnOwoKICAgIC8qKgogICAgICogVGhlIFBPU1RfUk9PVF9QQUNLQUdFX0lOU1RBTEwgZXZlbnQgb2NjdXJzIGFmdGVyIHRoZSByb290IHBhY2thZ2UgaGFzIGJlZW4gaW5zdGFsbGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9ST09UX1BBQ0tBR0VfSU5TVEFMTCA9ICdwb3N0LXJvb3QtcGFja2FnZS1pbnN0YWxsJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX0NSRUFURV9QUk9KRUNUIGV2ZW50IG9jY3VycyBhZnRlciB0aGUgY3JlYXRlLXByb2plY3QgY29tbWFuZCBoYXMgYmVlbiBleGVjdXRlZC4KICAgICAqIE5vdGU6IEV2ZW50IG9jY3VycyBhZnRlciBQT1NUX0lOU1RBTExfQ01ECiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXFNjcmlwdFxFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX0NSRUFURV9QUk9KRUNUX0NNRCA9ICdwb3N0LWNyZWF0ZS1wcm9qZWN0LWNtZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX0FSQ0hJVkVfQ01EIGV2ZW50IG9jY3VycyBiZWZvcmUgdGhlIHVwZGF0ZSBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX0FSQ0hJVkVfQ01EID0gJ3ByZS1hcmNoaXZlLWNtZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9BUkNISVZFX0NNRCBldmVudCBvY2N1cnMgYWZ0ZXIgdGhlIHN0YXR1cyBjb21tYW5kIGlzIGV4ZWN1dGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxTY3JpcHRcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9BUkNISVZFX0NNRCA9ICdwb3N0LWFyY2hpdmUtY21kJzsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFJlcXVlc3Q7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CgovKioKICogVGhlIHByZSBjb21tYW5kIHJ1biBldmVudC4KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUHJlUG9vbENyZWF0ZUV2ZW50IGV4dGVuZHMgRXZlbnQKewogICAgLyoqCiAgICAgKiBAdmFyIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlICRyZXBvc2l0b3JpZXM7CiAgICAvKioKICAgICAqIEB2YXIgUmVxdWVzdAogICAgICovCiAgICBwcml2YXRlICRyZXF1ZXN0OwogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJGFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRzdGFiaWxpdHlGbGFnczsKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRyb290QWxpYXNlczsKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRyb290UmVmZXJlbmNlczsKICAgIC8qKgogICAgICogQHZhciBQYWNrYWdlSW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZXM7CiAgICAvKioKICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByaXZhdGUgJHVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICRuYW1lICAgICAgICAgVGhlIGV2ZW50IG5hbWUKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlW10gJHJlcG9zaXRvcmllcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsIGFycmF5ICRyZXBvc2l0b3JpZXMsIFJlcXVlc3QgJHJlcXVlc3QsIGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsIGFycmF5ICRzdGFiaWxpdHlGbGFncywgYXJyYXkgJHJvb3RBbGlhc2VzLCBhcnJheSAkcm9vdFJlZmVyZW5jZXMsIGFycmF5ICRwYWNrYWdlcywgYXJyYXkgJHVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXMpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbmFtZSk7CgogICAgICAgICR0aGlzLT5yZXBvc2l0b3JpZXMgPSAkcmVwb3NpdG9yaWVzOwogICAgICAgICR0aGlzLT5yZXF1ZXN0ID0gJHJlcXVlc3Q7CiAgICAgICAgJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllcyA9ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXM7CiAgICAgICAgJHRoaXMtPnN0YWJpbGl0eUZsYWdzID0gJHN0YWJpbGl0eUZsYWdzOwogICAgICAgICR0aGlzLT5yb290QWxpYXNlcyA9ICRyb290QWxpYXNlczsKICAgICAgICAkdGhpcy0+cm9vdFJlZmVyZW5jZXMgPSAkcm9vdFJlZmVyZW5jZXM7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzID0gJHBhY2thZ2VzOwogICAgICAgICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZFBhY2thZ2VzID0gJHVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zaXRvcmllczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVxdWVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXF1ZXN0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWNjZXB0YWJsZVN0YWJpbGl0aWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YWJpbGl0eUZsYWdzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YWJpbGl0eUZsYWdzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheVtdIG9mIHBhY2thZ2UgPT4gdmVyc2lvbiA9PiBbYWxpYXMsIGFsaWFzX25vcm1hbGl6ZWRdCiAgICAgKiBAcHNhbG0tcmV0dXJuIGFycmF5PHN0cmluZywgYXJyYXk8c3RyaW5nLCBhcnJheXthbGlhczogc3RyaW5nLCBhbGlhc19ub3JtYWxpemVkOiBzdHJpbmd9Pj4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3RBbGlhc2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJvb3RBbGlhc2VzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Um9vdFJlZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdFJlZmVyZW5jZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZFBhY2thZ2VzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2VbXSAkcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlcykKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZXMgPSAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZVtdICRwYWNrYWdlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlcyhhcnJheSAkcGFja2FnZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkUGFja2FnZXMgPSAkcGFja2FnZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgovKioKICogUGx1Z2luIGludGVyZmFjZQogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KaW50ZXJmYWNlIFBsdWdpbkludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcm5hbCBjb21wb3Nlci1wbHVnaW4tYXBpIHBhY2thZ2UKICAgICAqCiAgICAgKiBUaGlzIGlzIHVzZWQgdG8gZGVub3RlIHRoZSBBUEkgdmVyc2lvbiBvZiBQbHVnaW4gc3BlY2lmaWMKICAgICAqIGZlYXR1cmVzLCBidXQgaXMgYWxzbyBidW1wZWQgdG8gYSBuZXcgbWFqb3IgaWYgQ29tcG9zZXIKICAgICAqIGluY2x1ZGVzIGEgbWFqb3IgYnJlYWsgaW4gaW50ZXJuYWwgQVBJcyB3aGljaCBhcmUgc3VzY2VwdGlibGUKICAgICAqIHRvIGJlIHVzZWQgYnkgcGx1Z2lucy4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQTFVHSU5fQVBJX1ZFUlNJT04gPSAnMi4wLjAnOwoKICAgIC8qKgogICAgICogQXBwbHkgcGx1Z2luIG1vZGlmaWNhdGlvbnMgdG8gQ29tcG9zZXIKICAgICAqCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZShDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbyk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYW55IGhvb2tzIGZyb20gQ29tcG9zZXIKICAgICAqCiAgICAgKiBUaGlzIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBwbHVnaW4gaXMgZGVhY3RpdmF0ZWQgYmVmb3JlIGJlaW5nCiAgICAgKiB1bmluc3RhbGxlZCwgYnV0IGFsc28gYmVmb3JlIGl0IGdldHMgdXBncmFkZWQgdG8gYSBuZXcgdmVyc2lvbgogICAgICogc28gdGhlIG9sZCBvbmUgY2FuIGJlIGRlYWN0aXZhdGVkIGFuZCB0aGUgbmV3IG9uZSBhY3RpdmF0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZShDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbyk7CgogICAgLyoqCiAgICAgKiBQcmVwYXJlIHRoZSBwbHVnaW4gdG8gYmUgdW5pbnN0YWxsZWQKICAgICAqCiAgICAgKiBUaGlzIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGRlYWN0aXZhdGUuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKCi8qKgogKiBUaGUgcHJlIGZpbGUgZG93bmxvYWQgZXZlbnQuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQcmVGaWxlRG93bmxvYWRFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBIdHRwRG93bmxvYWRlcgogICAgICovCiAgICBwcml2YXRlICRodHRwRG93bmxvYWRlcjsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJHByb2Nlc3NlZFVybDsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSAkY3VzdG9tQ2FjaGVLZXk7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICR0eXBlOwoKICAgIC8qKgogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcml2YXRlICRjb250ZXh0OwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRuYW1lICAgICAgICAgICBUaGUgZXZlbnQgbmFtZQogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRwcm9jZXNzZWRVcmwKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAkdHlwZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICRjb250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCAkcHJvY2Vzc2VkVXJsLCAkdHlwZSwgJGNvbnRleHQgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUpOwogICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlciA9ICRodHRwRG93bmxvYWRlcjsKICAgICAgICAkdGhpcy0+cHJvY2Vzc2VkVXJsID0gJHByb2Nlc3NlZFVybDsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgICAgICR0aGlzLT5jb250ZXh0ID0gJGNvbnRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEh0dHBEb3dubG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIdHRwRG93bmxvYWRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5odHRwRG93bmxvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgcHJvY2Vzc2VkIFVSTCB0aGF0IHdpbGwgYmUgZG93bmxvYWRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvY2Vzc2VkVXJsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NlZFVybDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2Nlc3NlZCBVUkwgdGhhdCB3aWxsIGJlIGRvd25sb2FkZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvY2Vzc2VkVXJsIE5ldyBwcm9jZXNzZWQgVVJMCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9jZXNzZWRVcmwoJHByb2Nlc3NlZFVybCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2Vzc2VkVXJsID0gJHByb2Nlc3NlZFVybDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhIGN1c3RvbSBwYWNrYWdlIGNhY2hlIGtleSBmb3IgdGhpcyBkb3dubG9hZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDdXN0b21DYWNoZUtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jdXN0b21DYWNoZUtleTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBjdXN0b20gcGFja2FnZSBjYWNoZSBrZXkgZm9yIHRoaXMgZG93bmxvYWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjdXN0b21DYWNoZUtleSBOZXcgY2FjaGUga2V5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDdXN0b21DYWNoZUtleSgkY3VzdG9tQ2FjaGVLZXkpCiAgICB7CiAgICAgICAgJHRoaXMtPmN1c3RvbUNhY2hlS2V5ID0gJGN1c3RvbUNhY2hlS2V5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGlzIGRvd25sb2FkIChwYWNrYWdlLCBtZXRhZGF0YSkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnRleHQgb2YgdGhpcyBkb3dubG9hZCwgaWYgYW55LgogICAgICoKICAgICAqIElmIHRoaXMgZG93bmxvYWQgaXMgb2YgdHlwZSBwYWNrYWdlLCB0aGUgcGFja2FnZSBvYmplY3QgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb250ZXh0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsdWdpbjsKCnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CgovKioKICogVGhlIHBvc3QgZmlsZSBkb3dubG9hZCBldmVudC4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFBvc3RGaWxlRG93bmxvYWRFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkZmlsZU5hbWU7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByaXZhdGUgJGNoZWNrc3VtOwoKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkdXJsOwoKICAgIC8qKgogICAgICogQHZhciBcQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJHBhY2thZ2U7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkbmFtZSAgICAgVGhlIGV2ZW50IG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRmaWxlTmFtZSBUaGUgZmlsZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAkY2hlY2tzdW0gVGhlIGNoZWNrc3VtCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdXJsICAgICAgVGhlIHByb2Nlc3NlZCB1cmwKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICBUaGUgcGFja2FnZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCAkZmlsZU5hbWUsICRjaGVja3N1bSwgJHVybCwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRuYW1lKTsKICAgICAgICAkdGhpcy0+ZmlsZU5hbWUgPSAkZmlsZU5hbWU7CiAgICAgICAgJHRoaXMtPmNoZWNrc3VtID0gJGNoZWNrc3VtOwogICAgICAgICR0aGlzLT51cmwgPSAkdXJsOwogICAgICAgICR0aGlzLT5wYWNrYWdlID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIHRhcmdldCBmaWxlIG5hbWUgbG9jYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVOYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGVOYW1lOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY2hlY2tzdW0uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hlY2tzdW0oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hlY2tzdW07CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9jZXNzZWQgVVJMLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJsOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBwYWNrYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZSBUaGUgcGFja2FnZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47CgovKioKICogVGhlIFBsdWdpbiBFdmVudHMuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBQbHVnaW5FdmVudHMKewogICAgLyoqCiAgICAgKiBUaGUgSU5JVCBldmVudCBvY2N1cnMgYWZ0ZXIgYSBDb21wb3NlciBpbnN0YW5jZSBpcyBkb25lIGJlaW5nIGluaXRpYWxpemVkCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhCiAgICAgKiBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgSU5JVCA9ICdpbml0JzsKCiAgICAvKioKICAgICAqIFRoZSBDT01NQU5EIGV2ZW50IG9jY3VycyBhcyBhIGNvbW1hbmQgYmVnaW5zCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhCiAgICAgKiBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IENPTU1BTkQgPSAnY29tbWFuZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX0ZJTEVfRE9XTkxPQUQgZXZlbnQgb2NjdXJzIGJlZm9yZSBkb3dubG9hZGluZyBhIGZpbGUKICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEKICAgICAqIENvbXBvc2VyXFBsdWdpblxQcmVGaWxlRG93bmxvYWRFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfRklMRV9ET1dOTE9BRCA9ICdwcmUtZmlsZS1kb3dubG9hZCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9GSUxFX0RPV05MT0FEIGV2ZW50IG9jY3VycyBhZnRlciBkb3dubG9hZGluZyBhIHBhY2thZ2UgZGlzdCBmaWxlCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhCiAgICAgKiBDb21wb3NlclxQbHVnaW5cUG9zdEZpbGVEb3dubG9hZEV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfRklMRV9ET1dOTE9BRCA9ICdwb3N0LWZpbGUtZG93bmxvYWQnOwoKICAgIC8qKgogICAgICogVGhlIFBSRV9DT01NQU5EX1JVTiBldmVudCBvY2N1cnMgYmVmb3JlIGEgY29tbWFuZCBpcyBleGVjdXRlZCBhbmQgbGV0cyB5b3UgbW9kaWZ5IHRoZSBpbnB1dCBhcmd1bWVudHMvb3B0aW9ucwogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYQogICAgICogQ29tcG9zZXJcUGx1Z2luXFByZUNvbW1hbmRSdW5FdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfQ09NTUFORF9SVU4gPSAncHJlLWNvbW1hbmQtcnVuJzsKCiAgICAvKioKICAgICAqIFRoZSBQUkVfUE9PTF9DUkVBVEUgZXZlbnQgb2NjdXJzIGJlZm9yZSB0aGUgUG9vbCBvZiBwYWNrYWdlcyBpcyBjcmVhdGVkLCBhbmQgbGV0cwogICAgICogeW91IGZpbHRlciB0aGUgbGlzdCBvZiBwYWNrYWdlcyB3aGljaCBpcyBnb2luZyB0byBlbnRlciB0aGUgU29sdmVyCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhCiAgICAgKiBDb21wb3NlclxQbHVnaW5cUHJlUG9vbENyZWF0ZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBSRV9QT09MX0NSRUFURSA9ICdwcmUtcG9vbC1jcmVhdGUnOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsdWdpbjsKCnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEFuIGV2ZW50IGZvciBhbGwgY29tbWFuZHMuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBDb21tYW5kRXZlbnQgZXh0ZW5kcyBFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbW1hbmROYW1lOwoKICAgIC8qKgogICAgICogQHZhciBJbnB1dEludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRpbnB1dDsKCiAgICAvKioKICAgICAqIEB2YXIgT3V0cHV0SW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJG91dHB1dDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJG5hbWUgICAgICAgIFRoZSBldmVudCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRjb21tYW5kTmFtZSBUaGUgY29tbWFuZCBuYW1lCiAgICAgKiBAcGFyYW0gSW5wdXRJbnRlcmZhY2UgICRpbnB1dAogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICRhcmdzICAgICAgICBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICRmbGFncyAgICAgICBPcHRpb25hbCBmbGFncyB0byBwYXNzIGRhdGEgbm90IGFzIGFyZ3VtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJGNvbW1hbmROYW1lLCAkaW5wdXQsICRvdXRwdXQsIGFycmF5ICRhcmdzID0gYXJyYXkoKSwgYXJyYXkgJGZsYWdzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRuYW1lLCAkYXJncywgJGZsYWdzKTsKICAgICAgICAkdGhpcy0+Y29tbWFuZE5hbWUgPSAkY29tbWFuZE5hbWU7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tbWFuZCBpbnB1dCBpbnRlcmZhY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgY29tbWFuZCBvdXRwdXQgaW50ZXJmYWNlCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE91dHB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQgYmVpbmcgcnVuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbW1hbmROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmROYW1lOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFBsdWdpblxDYXBhYmlsaXR5OwoKLyoqCiAqIE1hcmtlciBpbnRlcmZhY2UgZm9yIFBsdWdpbiBjYXBhYmlsaXRpZXMuCiAqIEV2ZXJ5IG5ldyBDYXBhYmlsaXR5IHdoaWNoIGlzIGFkZGVkIHRvIHRoZSBQbHVnaW4gQVBJIG11c3QgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgogKgogKiBAYXBpCiAqLwppbnRlcmZhY2UgQ2FwYWJpbGl0eQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luXENhcGFiaWxpdHk7CgovKioKICogQ29tbWFuZHMgUHJvdmlkZXIgSW50ZXJmYWNlCiAqCiAqIFRoaXMgY2FwYWJpbGl0eSB3aWxsIHJlY2VpdmUgYW4gYXJyYXkgd2l0aCAnY29tcG9zZXInIGFuZCAnaW8nIGtleXMgYXMKICogY29uc3RydWN0b3IgYXJndW1lbnQuIFRob3NlIGNvbnRhaW4gQ29tcG9zZXJcQ29tcG9zZXIgYW5kIENvbXBvc2VyXElPXElPSW50ZXJmYWNlCiAqIGluc3RhbmNlcy4gSXQgYWxzbyBjb250YWlucyBhICdwbHVnaW4nIGtleSBjb250YWluaW5nIHRoZSBwbHVnaW4gaW5zdGFuY2UgdGhhdAogKiBjcmVhdGVkIHRoZSBjYXBhYmlsaXR5LgogKgogKiBAYXV0aG9yIErDqXLDqW15IERlcnVzc8OpIDxqZXJlbXlAZGVydXNzZS5jb20+CiAqLwppbnRlcmZhY2UgQ29tbWFuZFByb3ZpZGVyIGV4dGVuZHMgQ2FwYWJpbGl0eQp7CiAgICAvKioKICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBjb21tYW5kcwogICAgICoKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXENvbW1hbmRcQmFzZUNvbW1hbmRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZHMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47CgovKioKICogUGx1Z2lucyB3aGljaCBuZWVkIHRvIGV4cG9zZSB2YXJpb3VzIGltcGxlbWVudGF0aW9ucwogKiBvZiB0aGUgQ29tcG9zZXIgUGx1Z2luIENhcGFiaWxpdGllcyBtdXN0IGhhdmUgdGhlaXIKICogZGVjbGFyZWQgUGx1Z2luIGNsYXNzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZS4KICoKICogQGFwaQogKi8KaW50ZXJmYWNlIENhcGFibGUKewogICAgLyoqCiAgICAgKiBNZXRob2QgYnkgd2hpY2ggYSBQbHVnaW4gYW5ub3VuY2VzIGl0cyBBUEkgaW1wbGVtZW50YXRpb25zLCB0aHJvdWdoIGFuIGFycmF5CiAgICAgKiB3aXRoIGEgc3BlY2lhbCBzdHJ1Y3R1cmUuCiAgICAgKgogICAgICogVGhlIGtleSBtdXN0IGJlIGEgc3RyaW5nLCByZXByZXNlbnRpbmcgYSBmdWxseSBxdWFsaWZpZWQgY2xhc3MvaW50ZXJmYWNlIG5hbWUKICAgICAqIHdoaWNoIENvbXBvc2VyIFBsdWdpbiBBUEkgZXhwb3Nlcy4KICAgICAqIFRoZSB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nIGFzIHdlbGwsIHJlcHJlc2VudGluZyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUKICAgICAqIG9mIHRoZSBpbXBsZW1lbnRpbmcgY2xhc3MuCiAgICAgKgogICAgICogQHR1dG9yaWFsCiAgICAgKgogICAgICogcmV0dXJuIGFycmF5KAogICAgICogICAgICdDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxDb21tYW5kUHJvdmlkZXInID0+ICdNeVxDb21tYW5kUHJvdmlkZXInLAogICAgICogICAgICdDb21wb3NlclxQbHVnaW5cQ2FwYWJpbGl0eVxWYWxpZGF0b3InICAgICAgID0+ICdNeVxWYWxpZGF0b3InLAogICAgICogKTsKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDYXBhYmlsaXRpZXMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxQbHVnaW47Cgp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKCi8qKgogKiBUaGUgcHJlIGNvbW1hbmQgcnVuIGV2ZW50LgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQcmVDb21tYW5kUnVuRXZlbnQgZXh0ZW5kcyBFdmVudAp7CiAgICAvKioKICAgICAqIEB2YXIgSW5wdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW5wdXQ7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcml2YXRlICRjb21tYW5kOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICRuYW1lICAgIFRoZSBldmVudCBuYW1lCiAgICAgKiBAcGFyYW0gSW5wdXRJbnRlcmZhY2UgJGlucHV0CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgJGNvbW1hbmQgVGhlIGNvbW1hbmQgYWJvdXQgdG8gYmUgZXhlY3V0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCBJbnB1dEludGVyZmFjZSAkaW5wdXQsICRjb21tYW5kKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG5hbWUpOwogICAgICAgICR0aGlzLT5pbnB1dCA9ICRpbnB1dDsKICAgICAgICAkdGhpcy0+Y29tbWFuZCA9ICRjb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29uc29sZSBpbnB1dAogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElucHV0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlucHV0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tbWFuZCBhYm91dCB0byBiZSBleGVjdXRlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcUGx1Z2luOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50U3Vic2NyaWJlckludGVyZmFjZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFJvb3RQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXENhcGFiaWxpdHlcQ2FwYWJpbGl0eTsKdXNlIENvbXBvc2VyXFV0aWxcUGFja2FnZVNvcnRlcjsKCi8qKgogKiBQbHVnaW4gbWFuYWdlcgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBQbHVnaW5NYW5hZ2VyCnsKICAgIC8qKiBAdmFyIENvbXBvc2VyICovCiAgICBwcm90ZWN0ZWQgJGNvbXBvc2VyOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciBDb21wb3NlciAqLwogICAgcHJvdGVjdGVkICRnbG9iYWxDb21wb3NlcjsKICAgIC8qKiBAdmFyIFZlcnNpb25QYXJzZXIgKi8KICAgIHByb3RlY3RlZCAkdmVyc2lvblBhcnNlcjsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkZGlzYWJsZVBsdWdpbnMgPSBmYWxzZTsKCiAgICAvKiogQHZhciBhcnJheTxQbHVnaW5JbnRlcmZhY2U+ICovCiAgICBwcm90ZWN0ZWQgJHBsdWdpbnMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBQbHVnaW5JbnRlcmZhY2U+ICovCiAgICBwcm90ZWN0ZWQgJHJlZ2lzdGVyZWRQbHVnaW5zID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgc3RhdGljICRjbGFzc0NvdW50ZXIgPSAwOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcGx1Z2luIG1hbmFnZXIKICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGNvbXBvc2VyCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgJGdsb2JhbENvbXBvc2VyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGRpc2FibGVQbHVnaW5zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbXBvc2VyICRjb21wb3NlciwgQ29tcG9zZXIgJGdsb2JhbENvbXBvc2VyID0gbnVsbCwgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+Z2xvYmFsQ29tcG9zZXIgPSAkZ2xvYmFsQ29tcG9zZXI7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgICR0aGlzLT5kaXNhYmxlUGx1Z2lucyA9ICRkaXNhYmxlUGx1Z2luczsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWRzIGFsbCBwbHVnaW5zIGZyb20gY3VycmVudGx5IGluc3RhbGxlZCBwbHVnaW4gcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRJbnN0YWxsZWRQbHVnaW5zKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmRpc2FibGVQbHVnaW5zKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRyZXBvID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkZ2xvYmFsUmVwbyA9ICR0aGlzLT5nbG9iYWxDb21wb3NlciA/ICR0aGlzLT5nbG9iYWxDb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCkgOiBudWxsOwogICAgICAgIGlmICgkcmVwbykgewogICAgICAgICAgICAkdGhpcy0+bG9hZFJlcG9zaXRvcnkoJHJlcG8sIGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRnbG9iYWxSZXBvKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkUmVwb3NpdG9yeSgkZ2xvYmFsUmVwbywgdHJ1ZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbGwgY3VycmVudGx5IGFjdGl2ZSBwbHVnaW4gaW5zdGFuY2VzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBwbHVnaW5zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQbHVnaW5zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBsdWdpbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGdsb2JhbCBjb21wb3NlciBvciBudWxsIHdoZW4gbWFpbiBjb21wb3NlciBpcyBub3QgZnVsbHkgbG9hZGVkCiAgICAgKgogICAgICogQHJldHVybiBDb21wb3NlcnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRHbG9iYWxDb21wb3NlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nbG9iYWxDb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVyIGEgcGx1Z2luIHBhY2thZ2UsIGFjdGl2YXRlIGl0IGV0Yy4KICAgICAqCiAgICAgKiBJZiBpdCdzIG9mIHR5cGUgY29tcG9zZXItaW5zdGFsbGVyIGl0IGlzIHJlZ2lzdGVyZWQgYXMgYW4gaW5zdGFsbGVyCiAgICAgKiBpbnN0ZWFkIGZvciBCQwogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAkZmFpbE9uTWlzc2luZ0NsYXNzZXMgQnkgZGVmYXVsdCB0aGlzIHNpbGVudGx5IHNraXBzIHBsdWdpbnMgdGhhdCBjYW4gbm90IGJlIGZvdW5kLCBidXQgaWYgc2V0IHRvIHRydWUgaXQgZmFpbHMgd2l0aCBhbiBleGNlcHRpb24KICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICRpc0dsb2JhbFBsdWdpbiAgICAgICBTZXQgdG8gdHJ1ZSB0byBkZW5vdGUgcGx1Z2lucyB3aGljaCBhcmUgaW5zdGFsbGVkIGluIHRoZSBnbG9iYWwgQ29tcG9zZXIgZGlyZWN0b3J5CiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWdpc3RlclBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZhaWxPbk1pc3NpbmdDbGFzc2VzID0gZmFsc2UsICRpc0dsb2JhbFBsdWdpbiA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRUeXBlKCkgPT09ICdjb21wb3Nlci1wbHVnaW4nKSB7CiAgICAgICAgICAgICRyZXF1aXJlc0NvbXBvc2VyID0gbnVsbDsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsgLyoqIEB2YXIgTGluayAkbGluayAqLwogICAgICAgICAgICAgICAgaWYgKCdjb21wb3Nlci1wbHVnaW4tYXBpJyA9PT0gJGxpbmstPmdldFRhcmdldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVzQ29tcG9zZXIgPSAkbGluay0+Z2V0Q29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRyZXF1aXJlc0NvbXBvc2VyKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIlBsdWdpbiAiLiRwYWNrYWdlLT5nZXROYW1lKCkuIiBpcyBtaXNzaW5nIGEgcmVxdWlyZSBzdGF0ZW1lbnQgZm9yIGEgdmVyc2lvbiBvZiB0aGUgY29tcG9zZXItcGx1Z2luLWFwaSBwYWNrYWdlLiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY3VycmVudFBsdWdpbkFwaVZlcnNpb24gPSAkdGhpcy0+Z2V0UGx1Z2luQXBpVmVyc2lvbigpOwogICAgICAgICAgICAkY3VycmVudFBsdWdpbkFwaUNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkdGhpcy0+dmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCRjdXJyZW50UGx1Z2luQXBpVmVyc2lvbikpOwoKICAgICAgICAgICAgaWYgKCRyZXF1aXJlc0NvbXBvc2VyLT5nZXRQcmV0dHlTdHJpbmcoKSA9PT0gJHRoaXMtPmdldFBsdWdpbkFwaVZlcnNpb24oKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5UaGUgIicgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gJyIgcGx1Z2luIHJlcXVpcmVzIGNvbXBvc2VyLXBsdWdpbi1hcGkgJy4kdGhpcy0+Z2V0UGx1Z2luQXBpVmVyc2lvbigpLicsIHRoaXMgKldJTEwqIGJyZWFrIGluIHRoZSBmdXR1cmUgYW5kIGl0IHNob3VsZCBiZSBmaXhlZCBBU0FQIChyZXF1aXJlIF4nLiR0aGlzLT5nZXRQbHVnaW5BcGlWZXJzaW9uKCkuJyBpbnN0ZWFkIGZvciBleGFtcGxlKS48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0gZWxzZWlmICghJHJlcXVpcmVzQ29tcG9zZXItPm1hdGNoZXMoJGN1cnJlbnRQbHVnaW5BcGlDb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5UaGUgIicgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gJyIgcGx1Z2luICcuKCRpc0dsb2JhbFBsdWdpbiA/ICcoaW5zdGFsbGVkIGdsb2JhbGx5KSAnIDogJycpLid3YXMgc2tpcHBlZCBiZWNhdXNlIGl0IHJlcXVpcmVzIGEgUGx1Z2luIEFQSSB2ZXJzaW9uICgiJyAuICRyZXF1aXJlc0NvbXBvc2VyLT5nZXRQcmV0dHlTdHJpbmcoKSAuICciKSB0aGF0IGRvZXMgbm90IG1hdGNoIHlvdXIgQ29tcG9zZXIgaW5zdGFsbGF0aW9uICgiJyAuICRjdXJyZW50UGx1Z2luQXBpVmVyc2lvbiAuICciKS4gWW91IG1heSBuZWVkIHRvIHJ1biBjb21wb3NlciB1cGRhdGUgd2l0aCB0aGUgIi0tbm8tcGx1Z2lucyIgb3B0aW9uLjwvd2FybmluZz4nKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0TmFtZSgpID09PSAnc3ltZm9ueS9mbGV4JyAmJiBwcmVnX21hdGNoKCd7XlswLTkuXSskfScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpICYmIHZlcnNpb25fY29tcGFyZSgkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAnMS45LjgnLCAnPCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlRoZSAiJyAuICRwYWNrYWdlLT5nZXROYW1lKCkgLiAnIiBwbHVnaW4gJy4oJGlzR2xvYmFsUGx1Z2luID8gJyhpbnN0YWxsZWQgZ2xvYmFsbHkpICcgOiAnJykuJ3dhcyBza2lwcGVkIGJlY2F1c2UgaXQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBDb21wb3NlciAyKy4gTWFrZSBzdXJlIHRvIHVwZGF0ZSBpdCB0byB2ZXJzaW9uIDEuOS44IG9yIGdyZWF0ZXIuPC93YXJuaW5nPicpOwoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG9sZEluc3RhbGxlclBsdWdpbiA9ICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItaW5zdGFsbGVyJyk7CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRleHRyYSA9ICRwYWNrYWdlLT5nZXRFeHRyYSgpOwogICAgICAgIGlmIChlbXB0eSgkZXh0cmFbJ2NsYXNzJ10pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdFcnJvciB3aGlsZSBpbnN0YWxsaW5nICcuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nLCBjb21wb3Nlci1wbHVnaW4gcGFja2FnZXMgc2hvdWxkIGhhdmUgYSBjbGFzcyBkZWZpbmVkIGluIHRoZWlyIGV4dHJhIGtleSB0byBiZSB1c2FibGUuJyk7CiAgICAgICAgfQogICAgICAgICRjbGFzc2VzID0gaXNfYXJyYXkoJGV4dHJhWydjbGFzcyddKSA/ICRleHRyYVsnY2xhc3MnXSA6IGFycmF5KCRleHRyYVsnY2xhc3MnXSk7CgogICAgICAgICRsb2NhbFJlcG8gPSAkdGhpcy0+Y29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgICRnbG9iYWxSZXBvID0gJHRoaXMtPmdsb2JhbENvbXBvc2VyID8gJHRoaXMtPmdsb2JhbENvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSA6IG51bGw7CgogICAgICAgICRyb290UGFja2FnZSA9IGNsb25lICR0aGlzLT5jb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICRyb290UGFja2FnZVJlcG8gPSBuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRyb290UGFja2FnZSk7CiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgkbG9jYWxSZXBvLCAkcm9vdFBhY2thZ2VSZXBvKSk7CiAgICAgICAgaWYgKCRnbG9iYWxSZXBvKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvLT5hZGRSZXBvc2l0b3J5KCRnbG9iYWxSZXBvKTsKICAgICAgICB9CgogICAgICAgICRhdXRvbG9hZFBhY2thZ2VzID0gYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSA9PiAkcGFja2FnZSk7CiAgICAgICAgJGF1dG9sb2FkUGFja2FnZXMgPSAkdGhpcy0+Y29sbGVjdERlcGVuZGVuY2llcygkaW5zdGFsbGVkUmVwbywgJGF1dG9sb2FkUGFja2FnZXMsICRwYWNrYWdlKTsKCiAgICAgICAgJGdlbmVyYXRvciA9ICR0aGlzLT5jb21wb3Nlci0+Z2V0QXV0b2xvYWRHZW5lcmF0b3IoKTsKICAgICAgICAkYXV0b2xvYWRzID0gYXJyYXkoYXJyYXkoJHJvb3RQYWNrYWdlLCAnJykpOwogICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZFBhY2thZ2VzIGFzICRhdXRvbG9hZFBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRhdXRvbG9hZFBhY2thZ2UgPT09ICRyb290UGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRkb3dubG9hZFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJGF1dG9sb2FkUGFja2FnZSwgJGdsb2JhbFJlcG8gJiYgJGdsb2JhbFJlcG8tPmhhc1BhY2thZ2UoJGF1dG9sb2FkUGFja2FnZSkpOwogICAgICAgICAgICAkYXV0b2xvYWRzW10gPSBhcnJheSgkYXV0b2xvYWRQYWNrYWdlLCAkZG93bmxvYWRQYXRoKTsKICAgICAgICB9CgogICAgICAgICRtYXAgPSAkZ2VuZXJhdG9yLT5wYXJzZUF1dG9sb2FkcygkYXV0b2xvYWRzLCAkcm9vdFBhY2thZ2UpOwogICAgICAgICRjbGFzc0xvYWRlciA9ICRnZW5lcmF0b3ItPmNyZWF0ZUxvYWRlcigkbWFwLCAkdGhpcy0+Y29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3ZlbmRvci1kaXInKSk7CiAgICAgICAgJGNsYXNzTG9hZGVyLT5yZWdpc3RlcihmYWxzZSk7CgogICAgICAgIGZvcmVhY2ggKCRjbGFzc2VzIGFzICRjbGFzcykgewogICAgICAgICAgICBpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcywgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICAkY2xhc3MgPSB0cmltKCRjbGFzcywgJ1xcJyk7CiAgICAgICAgICAgICAgICAkcGF0aCA9ICRjbGFzc0xvYWRlci0+ZmluZEZpbGUoJGNsYXNzKTsKICAgICAgICAgICAgICAgICRjb2RlID0gZmlsZV9nZXRfY29udGVudHMoJHBhdGgpOwogICAgICAgICAgICAgICAgJHNlcGFyYXRvclBvcyA9IHN0cnJwb3MoJGNsYXNzLCAnXFwnKTsKICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSAkY2xhc3M7CiAgICAgICAgICAgICAgICBpZiAoJHNlcGFyYXRvclBvcykgewogICAgICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSBzdWJzdHIoJGNsYXNzLCAkc2VwYXJhdG9yUG9zICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSA9IHByZWdfcmVwbGFjZSgne14oKD86ZmluYWxccyspPyg/OlxzKikpY2xhc3NccysoJy5wcmVnX3F1b3RlKCRjbGFzc05hbWUpLicpfW1pJywgJyQxY2xhc3MgJDJfY29tcG9zZXJfdG1wJy5zZWxmOjokY2xhc3NDb3VudGVyLCAkY29kZSwgMSk7CiAgICAgICAgICAgICAgICAkY29kZSA9IHN0cnRyKCRjb2RlLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnX19GSUxFX18nID0+IHZhcl9leHBvcnQoJHBhdGgsIHRydWUpLAogICAgICAgICAgICAgICAgICAgICdfX0RJUl9fJyA9PiB2YXJfZXhwb3J0KGRpcm5hbWUoJHBhdGgpLCB0cnVlKSwKICAgICAgICAgICAgICAgICAgICAnX19DTEFTU19fJyA9PiB2YXJfZXhwb3J0KCRjbGFzcywgdHJ1ZSksCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICRjb2RlID0gcHJlZ19yZXBsYWNlKCcvXlxzKjxcPyhwaHApPy9pJywgJycsICRjb2RlLCAxKTsKICAgICAgICAgICAgICAgIGV2YWwoJGNvZGUpOwogICAgICAgICAgICAgICAgJGNsYXNzIC49ICdfY29tcG9zZXJfdG1wJy5zZWxmOjokY2xhc3NDb3VudGVyOwogICAgICAgICAgICAgICAgc2VsZjo6JGNsYXNzQ291bnRlcisrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG9sZEluc3RhbGxlclBsdWdpbikgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Mb2FkaW5nICInLiRwYWNrYWdlLT5nZXROYW1lKCkgLiAnIiAnLigkaXNHbG9iYWxQbHVnaW4gPyAnKGluc3RhbGxlZCBnbG9iYWxseSkgJyA6ICcnKS4nd2hpY2ggaXMgYSBsZWdhY3kgY29tcG9zZXItaW5zdGFsbGVyIGJ1aWx0IGZvciBDb21wb3NlciAxLngsIGl0IGlzIGxpa2VseSB0byBjYXVzZSBpc3N1ZXMgYXMgeW91IGFyZSBydW5uaW5nIENvbXBvc2VyIDIueC48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVyID0gbmV3ICRjbGFzcygkdGhpcy0+aW8sICR0aGlzLT5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+YWRkSW5zdGFsbGVyKCRpbnN0YWxsZXIpOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJGluc3RhbGxlcjsKICAgICAgICAgICAgfSBlbHNlaWYgKGNsYXNzX2V4aXN0cygkY2xhc3MpKSB7CiAgICAgICAgICAgICAgICAkcGx1Z2luID0gbmV3ICRjbGFzcygpOwogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFBsdWdpbigkcGx1Z2luLCAkaXNHbG9iYWxQbHVnaW4sICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwbHVnaW47CiAgICAgICAgICAgIH0gZWxzZWlmICgkZmFpbE9uTWlzc2luZ0NsYXNzZXMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdQbHVnaW4gJy4kcGFja2FnZS0+Z2V0TmFtZSgpLicgY291bGQgbm90IGJlIGluaXRpYWxpemVkLCBjbGFzcyBub3QgZm91bmQ6ICcuJGNsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERlYWN0aXZhdGVzIGEgcGx1Z2luIHBhY2thZ2UKICAgICAqCiAgICAgKiBJZiBpdCdzIG9mIHR5cGUgY29tcG9zZXItaW5zdGFsbGVyIGl0IGlzIHVucmVnaXN0ZXJlZCBmcm9tIHRoZSBpbnN0YWxsZXJzCiAgICAgKiBpbnN0ZWFkIGZvciBCQwogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWFjdGl2YXRlUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJG9sZEluc3RhbGxlclBsdWdpbiA9ICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItaW5zdGFsbGVyJyk7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoJG9sZEluc3RhbGxlclBsdWdpbikgewogICAgICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldOwogICAgICAgICAgICB1bnNldCgkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+cmVtb3ZlSW5zdGFsbGVyKCRpbnN0YWxsZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwbHVnaW4gPSAkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV07CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgICAgICR0aGlzLT5yZW1vdmVQbHVnaW4oJHBsdWdpbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVW5pbnN0YWxsIGEgcGx1Z2luIHBhY2thZ2UKICAgICAqCiAgICAgKiBJZiBpdCdzIG9mIHR5cGUgY29tcG9zZXItaW5zdGFsbGVyIGl0IGlzIHVucmVnaXN0ZXJlZCBmcm9tIHRoZSBpbnN0YWxsZXJzCiAgICAgKiBpbnN0ZWFkIGZvciBCQwogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGxQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5kaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkb2xkSW5zdGFsbGVyUGx1Z2luID0gKCRwYWNrYWdlLT5nZXRUeXBlKCkgPT09ICdjb21wb3Nlci1pbnN0YWxsZXInKTsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cmVnaXN0ZXJlZFBsdWdpbnNbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkb2xkSW5zdGFsbGVyUGx1Z2luKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWFjdGl2YXRlUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBsdWdpbiA9ICR0aGlzLT5yZWdpc3RlcmVkUGx1Z2luc1skcGFja2FnZS0+Z2V0TmFtZSgpXTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnJlZ2lzdGVyZWRQbHVnaW5zWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICAgICAgJHRoaXMtPnJlbW92ZVBsdWdpbigkcGx1Z2luKTsKICAgICAgICAgICAgJHRoaXMtPnVuaW5zdGFsbFBsdWdpbigkcGx1Z2luKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBpbnRlcm5hbCBjb21wb3Nlci1wbHVnaW4tYXBpIHBhY2thZ2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBsdWdpbkFwaVZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiBQbHVnaW5JbnRlcmZhY2U6OlBMVUdJTl9BUElfVkVSU0lPTjsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBwbHVnaW4sIGFjdGl2YXRlcyBpdCBhbmQgcmVnaXN0ZXJzIGl0IHdpdGggdGhlIGV2ZW50IGRpc3BhdGNoZXIKICAgICAqCiAgICAgKiBJZGVhbGx5IHBsdWdpbiBwYWNrYWdlcyBzaG91bGQgYmUgcmVnaXN0ZXJlZCB2aWEgcmVnaXN0ZXJQYWNrYWdlLCBidXQgaWYgeW91IHVzZSBDb21wb3NlcgogICAgICogcHJvZ3JhbW1hdGljYWxseSBhbmQgd2FudCB0byByZWdpc3RlciBhIHBsdWdpbiBjbGFzcyBkaXJlY3RseSB0aGlzIGlzIGEgdmFsaWQgd2F5CiAgICAgKiB0byBkbyBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gUGx1Z2luSW50ZXJmYWNlICAgJHBsdWdpbiAgICAgICAgcGx1Z2luIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gP1BhY2thZ2VJbnRlcmZhY2UgJHNvdXJjZVBhY2thZ2UgUGFja2FnZSBmcm9tIHdoaWNoIHRoZSBwbHVnaW4gY29tZXMgZnJvbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUGx1Z2luKFBsdWdpbkludGVyZmFjZSAkcGx1Z2luLCAkaXNHbG9iYWxQbHVnaW4gPSBmYWxzZSwgUGFja2FnZUludGVyZmFjZSAkc291cmNlUGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGRldGFpbHMgPSBhcnJheSgpOwogICAgICAgIGlmICgkc291cmNlUGFja2FnZSkgewogICAgICAgICAgICAkZGV0YWlsc1tdID0gJ2Zyb20gJy4kc291cmNlUGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoJGlzR2xvYmFsUGx1Z2luKSB7CiAgICAgICAgICAgICRkZXRhaWxzW10gPSAnaW5zdGFsbGVkIGdsb2JhbGx5JzsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdMb2FkaW5nIHBsdWdpbiAnLmdldF9jbGFzcygkcGx1Z2luKS4oJGRldGFpbHMgPyAnICgnLmltcGxvZGUoJywgJywgJGRldGFpbHMpLicpJyA6ICcnKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAkdGhpcy0+cGx1Z2luc1tdID0gJHBsdWdpbjsKICAgICAgICAkcGx1Z2luLT5hY3RpdmF0ZSgkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbyk7CgogICAgICAgIGlmICgkcGx1Z2luIGluc3RhbmNlb2YgRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmFkZFN1YnNjcmliZXIoJHBsdWdpbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhIHBsdWdpbiwgZGVhY3RpdmF0ZXMgaXQgYW5kIHJlbW92ZXMgYW55IGxpc3RlbmVyIHRoZSBwbHVnaW4gaGFzIHNldCBvbiB0aGUgcGx1Z2luIGluc3RhbmNlCiAgICAgKgogICAgICogSWRlYWxseSBwbHVnaW4gcGFja2FnZXMgc2hvdWxkIGJlIGRlYWN0aXZhdGVkIHZpYSBkZWFjdGl2YXRlUGFja2FnZSwgYnV0IGlmIHlvdSB1c2UgQ29tcG9zZXIKICAgICAqIHByb2dyYW1tYXRpY2FsbHkgYW5kIHdhbnQgdG8gZGVyZWdpc3RlciBhIHBsdWdpbiBjbGFzcyBkaXJlY3RseSB0aGlzIGlzIGEgdmFsaWQgd2F5CiAgICAgKiB0byBkbyBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4gcGx1Z2luIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVQbHVnaW4oUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4pCiAgICB7CiAgICAgICAgJGluZGV4ID0gYXJyYXlfc2VhcmNoKCRwbHVnaW4sICR0aGlzLT5wbHVnaW5zLCB0cnVlKTsKICAgICAgICBpZiAoJGluZGV4ID09PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1VubG9hZGluZyBwbHVnaW4gJy5nZXRfY2xhc3MoJHBsdWdpbiksIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgdW5zZXQoJHRoaXMtPnBsdWdpbnNbJGluZGV4XSk7CiAgICAgICAgJHBsdWdpbi0+ZGVhY3RpdmF0ZSgkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbyk7CgogICAgICAgICR0aGlzLT5jb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPnJlbW92ZUxpc3RlbmVyKCRwbHVnaW4pOwogICAgfQoKICAgIC8qKgogICAgICogTm90aWZpZXMgYSBwbHVnaW4gaXQgaXMgYmVpbmcgdW5pbnN0YWxsZWQgYW5kIHNob3VsZCBjbGVhbiB1cAogICAgICoKICAgICAqIElkZWFsbHkgcGx1Z2luIHBhY2thZ2VzIHNob3VsZCBiZSB1bmluc3RhbGxlZCB2aWEgdW5pbnN0YWxsUGFja2FnZSwgYnV0IGlmIHlvdSB1c2UgQ29tcG9zZXIKICAgICAqIHByb2dyYW1tYXRpY2FsbHkgYW5kIHdhbnQgdG8gZGVyZWdpc3RlciBhIHBsdWdpbiBjbGFzcyBkaXJlY3RseSB0aGlzIGlzIGEgdmFsaWQgd2F5CiAgICAgKiB0byBkbyBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4gcGx1Z2luIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGxQbHVnaW4oUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdVbmluc3RhbGxpbmcgcGx1Z2luICcuZ2V0X2NsYXNzKCRwbHVnaW4pLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICRwbHVnaW4tPnVuaW5zdGFsbCgkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkIGFsbCBwbHVnaW5zIGFuZCBpbnN0YWxsZXJzIGZyb20gYSByZXBvc2l0b3J5CiAgICAgKgogICAgICogSWYgYSBwbHVnaW4gcmVxdWlyZXMgYW5vdGhlciBwbHVnaW4sIHRoZSByZXF1aXJlZCBvbmUgd2lsbCBiZSBsb2FkZWQgZmlyc3QKICAgICAqCiAgICAgKiBOb3RlIHRoYXQgcGx1Z2lucyBpbiB0aGUgc3BlY2lmaWVkIHJlcG9zaXRvcnkgdGhhdCByZWx5IG9uIGV2ZW50cyB0aGF0CiAgICAgKiBoYXZlIGZpcmVkIHByaW9yIHRvIGxvYWRpbmcgd2lsbCBiZSBtaXNzZWQuIFRoaXMgbWVhbnMgeW91IGxpa2VseSB3YW50IHRvCiAgICAgKiBjYWxsIHRoaXMgbWV0aG9kIGFzIGVhcmx5IGFzIHBvc3NpYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvIFJlcG9zaXRvcnkgdG8gc2NhbiBmb3IgcGx1Z2lucyB0byBpbnN0YWxsCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvYWRSZXBvc2l0b3J5KFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sICRpc0dsb2JhbFJlcG8pCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gJHJlcG8tPmdldFBhY2thZ2VzKCk7CiAgICAgICAgJHNvcnRlZFBhY2thZ2VzID0gUGFja2FnZVNvcnRlcjo6c29ydFBhY2thZ2VzKCRwYWNrYWdlcyk7CiAgICAgICAgZm9yZWFjaCAoJHNvcnRlZFBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCdjb21wb3Nlci1wbHVnaW4nID09PSAkcGFja2FnZS0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVnaXN0ZXJQYWNrYWdlKCRwYWNrYWdlLCBmYWxzZSwgJGlzR2xvYmFsUmVwbyk7CiAgICAgICAgICAgIC8vIEJhY2t3YXJkIGNvbXBhdGliaWxpdHkKICAgICAgICAgICAgfSBlbHNlaWYgKCdjb21wb3Nlci1pbnN0YWxsZXInID09PSAkcGFja2FnZS0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVnaXN0ZXJQYWNrYWdlKCRwYWNrYWdlLCBmYWxzZSwgJGlzR2xvYmFsUmVwbyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSBnZW5lcmF0ZXMgYSBtYXAgb2YgcGFja2FnZSBuYW1lcyB0byBwYWNrYWdlcyBmb3IgYWxsIGRlcHMKICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbyBTZXQgb2YgbG9jYWwgcmVwb3MKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICRjb2xsZWN0ZWQgICAgIEN1cnJlbnQgc3RhdGUgb2YgdGhlIG1hcCBmb3IgcmVjdXJzaW9uCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAkcGFja2FnZSAgICAgICBUaGUgcGFja2FnZSB0byBhbmFseXplCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBNYXAgb2YgcGFja2FnZSBuYW1lcyB0byBwYWNrYWdlcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNvbGxlY3REZXBlbmRlbmNpZXMoSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywgYXJyYXkgJGNvbGxlY3RlZCwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkcmVxdWlyZUxpbmspIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJHJlcXVpcmVMaW5rLT5nZXRUYXJnZXQoKSkgYXMgJHJlcXVpcmVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY29sbGVjdGVkWyRyZXF1aXJlZFBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbGxlY3RlZFskcmVxdWlyZWRQYWNrYWdlLT5nZXROYW1lKCldID0gJHJlcXVpcmVkUGFja2FnZTsKICAgICAgICAgICAgICAgICAgICAkY29sbGVjdGVkID0gJHRoaXMtPmNvbGxlY3REZXBlbmRlbmNpZXMoJGluc3RhbGxlZFJlcG8sICRjb2xsZWN0ZWQsICRyZXF1aXJlZFBhY2thZ2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbGxlY3RlZDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUgcGF0aCBhIHBhY2thZ2UgaXMgaW5zdGFsbGVkIHRvLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAkZ2xvYmFsICBXaGV0aGVyIHRoaXMgaXMgYSBnbG9iYWwgcGFja2FnZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEluc3RhbGwgcGF0aAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEluc3RhbGxQYXRoKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRnbG9iYWwgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISRnbG9iYWwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmdsb2JhbENvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgUGx1Z2luSW50ZXJmYWNlICAgJHBsdWdpbgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkY2FwYWJpbGl0eQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBPbiBlbXB0eSBvciBub24tc3RyaW5nIGltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWUgdmFsdWUKICAgICAqIEByZXR1cm4gbnVsbHxzdHJpbmcgICAgICAgVGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBvZiB0aGUgaW1wbGVtZW50YXRpb24gb3IgbnVsbCBpZiBQbHVnaW4gaXMgbm90IG9mIENhcGFibGUgdHlwZSBvciBkb2VzIG5vdCBwcm92aWRlIGl0CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDYXBhYmlsaXR5SW1wbGVtZW50YXRpb25DbGFzc05hbWUoUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4sICRjYXBhYmlsaXR5KQogICAgewogICAgICAgIGlmICghKCRwbHVnaW4gaW5zdGFuY2VvZiBDYXBhYmxlKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjYXBhYmlsaXRpZXMgPSAoYXJyYXkpICRwbHVnaW4tPmdldENhcGFiaWxpdGllcygpOwoKICAgICAgICBpZiAoIWVtcHR5KCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKSAmJiBpc19zdHJpbmcoJGNhcGFiaWxpdGllc1skY2FwYWJpbGl0eV0pICYmIHRyaW0oJGNhcGFiaWxpdGllc1skY2FwYWJpbGl0eV0pKSB7CiAgICAgICAgICAgIHJldHVybiB0cmltKCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKTsKICAgICAgICB9CgogICAgICAgIGlmICgKICAgICAgICAgICAgYXJyYXlfa2V5X2V4aXN0cygkY2FwYWJpbGl0eSwgJGNhcGFiaWxpdGllcykKICAgICAgICAgICAgJiYgKGVtcHR5KCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKSB8fCAhaXNfc3RyaW5nKCRjYXBhYmlsaXRpZXNbJGNhcGFiaWxpdHldKSB8fCAhdHJpbSgkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSkpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdQbHVnaW4gJy5nZXRfY2xhc3MoJHBsdWdpbikuJyBwcm92aWRlZCBpbnZhbGlkIGNhcGFiaWxpdHkgY2xhc3MgbmFtZShzKSwgZ290ICcudmFyX2V4cG9ydCgkY2FwYWJpbGl0aWVzWyRjYXBhYmlsaXR5XSwgMSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRjYXBhYmlsaXR5Q2xhc3NOYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgQVBJIGludGVyZmFjZSB3aGljaCB0aGUgcGx1Z2luIG1heSBwcm92aWRlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbXBsZW1lbnRhdGlvbiBvZi4KICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICAgICAgICRjdG9yQXJncyAgICAgICAgICAgIEFyZ3VtZW50cyBwYXNzZWQgdG8gQ2FwYWJpbGl0eSdzIGNvbnN0cnVjdG9yLgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2VlcGluZyBpdCBhbiBhcnJheSB3aWxsIGFsbG93IGZ1dHVyZSB2YWx1ZXMgdG8gYmUgcGFzc2VkIHdcbyBjaGFuZ2luZyB0aGUgc2lnbmF0dXJlLgogICAgICogQHJldHVybiBudWxsfENhcGFiaWxpdHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdWdpbkNhcGFiaWxpdHkoUGx1Z2luSW50ZXJmYWNlICRwbHVnaW4sICRjYXBhYmlsaXR5Q2xhc3NOYW1lLCBhcnJheSAkY3RvckFyZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmICgkY2FwYWJpbGl0eUNsYXNzID0gJHRoaXMtPmdldENhcGFiaWxpdHlJbXBsZW1lbnRhdGlvbkNsYXNzTmFtZSgkcGx1Z2luLCAkY2FwYWJpbGl0eUNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJGNhcGFiaWxpdHlDbGFzcykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiQ2Fubm90IGluc3RhbnRpYXRlIENhcGFiaWxpdHksIGFzIGNsYXNzICRjYXBhYmlsaXR5Q2xhc3MgZnJvbSBwbHVnaW4gIi5nZXRfY2xhc3MoJHBsdWdpbikuIiBkb2VzIG5vdCBleGlzdC4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGN0b3JBcmdzWydwbHVnaW4nXSA9ICRwbHVnaW47CiAgICAgICAgICAgICRjYXBhYmlsaXR5T2JqID0gbmV3ICRjYXBhYmlsaXR5Q2xhc3MoJGN0b3JBcmdzKTsKCiAgICAgICAgICAgIC8vIEZJWE1FIHRoZXNlIGNvdWxkIHVzZSBpc19hIGFuZCBkbyB0aGUgY2hlY2sgKmJlZm9yZSogaW5zdGFudGlhdGluZyBvbmNlIGRyb3Agc3VwcG9ydCBmb3IgcGhwPDUuMy45CiAgICAgICAgICAgIGlmICghJGNhcGFiaWxpdHlPYmogaW5zdGFuY2VvZiBDYXBhYmlsaXR5IHx8ICEkY2FwYWJpbGl0eU9iaiBpbnN0YW5jZW9mICRjYXBhYmlsaXR5Q2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJ0NsYXNzICcgLiAkY2FwYWJpbGl0eUNsYXNzIC4gJyBtdXN0IGltcGxlbWVudCBib3RoIENvbXBvc2VyXFBsdWdpblxDYXBhYmlsaXR5XENhcGFiaWxpdHkgYW5kICcuICRjYXBhYmlsaXR5Q2xhc3NOYW1lIC4gJy4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGNhcGFiaWxpdHlPYmo7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgJGNhcGFiaWxpdHlDbGFzc05hbWUgVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBBUEkgaW50ZXJmYWNlIHdoaWNoIHRoZSBwbHVnaW4gbWF5IHByb3ZpZGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGltcGxlbWVudGF0aW9uIG9mLgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgJGN0b3JBcmdzICAgICAgICAgICAgQXJndW1lbnRzIHBhc3NlZCB0byBDYXBhYmlsaXR5J3MgY29uc3RydWN0b3IuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZWVwaW5nIGl0IGFuIGFycmF5IHdpbGwgYWxsb3cgZnV0dXJlIHZhbHVlcyB0byBiZSBwYXNzZWQgd1xvIGNoYW5naW5nIHRoZSBzaWduYXR1cmUuCiAgICAgKiBAcmV0dXJuIENhcGFiaWxpdHlbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGx1Z2luQ2FwYWJpbGl0aWVzKCRjYXBhYmlsaXR5Q2xhc3NOYW1lLCBhcnJheSAkY3RvckFyZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgICRjYXBhYmlsaXRpZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRQbHVnaW5zKCkgYXMgJHBsdWdpbikgewogICAgICAgICAgICBpZiAoJGNhcGFiaWxpdHkgPSAkdGhpcy0+Z2V0UGx1Z2luQ2FwYWJpbGl0eSgkcGx1Z2luLCAkY2FwYWJpbGl0eUNsYXNzTmFtZSwgJGN0b3JBcmdzKSkgewogICAgICAgICAgICAgICAgJGNhcGFiaWxpdGllc1tdID0gJGNhcGFiaWxpdHk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2FwYWJpbGl0aWVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlcjsKCi8qKgogKiBBbiBFdmVudFN1YnNjcmliZXIga25vd3Mgd2hpY2ggZXZlbnRzIGl0IGlzIGludGVyZXN0ZWQgaW4uCiAqCiAqIElmIGFuIEV2ZW50U3Vic2NyaWJlciBpcyBhZGRlZCB0byBhbiBFdmVudERpc3BhdGNoZXIsIHRoZSBtYW5hZ2VyIGludm9rZXMKICoge0BsaW5rIGdldFN1YnNjcmliZWRFdmVudHN9IGFuZCByZWdpc3RlcnMgdGhlIHN1YnNjcmliZXIgYXMgYSBsaXN0ZW5lciBmb3IgYWxsCiAqIHJldHVybmVkIGV2ZW50cy4KICoKICogQGF1dGhvciBHdWlsaGVybWUgQmxhbmNvIDxndWlsaGVybWVibGFuY29AaG90bWFpbC5jb20+CiAqIEBhdXRob3IgSm9uYXRoYW4gV2FnZSA8am9ud2FnZUBnbWFpbC5jb20+CiAqIEBhdXRob3IgUm9tYW4gQm9yc2NoZWwgPHJvbWFuQGNvZGUtZmFjdG9yeS5vcmc+CiAqIEBhdXRob3IgQmVybmhhcmQgU2NodXNzZWsgPGJzY2h1c3Nla0BnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBldmVudCBuYW1lcyB0aGlzIHN1YnNjcmliZXIgd2FudHMgdG8gbGlzdGVuIHRvLgogICAgICoKICAgICAqIFRoZSBhcnJheSBrZXlzIGFyZSBldmVudCBuYW1lcyBhbmQgdGhlIHZhbHVlIGNhbiBiZToKICAgICAqCiAgICAgKiAqIFRoZSBtZXRob2QgbmFtZSB0byBjYWxsIChwcmlvcml0eSBkZWZhdWx0cyB0byAwKQogICAgICogKiBBbiBhcnJheSBjb21wb3NlZCBvZiB0aGUgbWV0aG9kIG5hbWUgdG8gY2FsbCBhbmQgdGhlIHByaW9yaXR5CiAgICAgKiAqIEFuIGFycmF5IG9mIGFycmF5cyBjb21wb3NlZCBvZiB0aGUgbWV0aG9kIG5hbWVzIHRvIGNhbGwgYW5kIHJlc3BlY3RpdmUKICAgICAqICAgcHJpb3JpdGllcywgb3IgMCBpZiB1bnNldAogICAgICoKICAgICAqIEZvciBpbnN0YW5jZToKICAgICAqCiAgICAgKiAqIGFycmF5KCdldmVudE5hbWUnID0+ICdtZXRob2ROYW1lJykKICAgICAqICogYXJyYXkoJ2V2ZW50TmFtZScgPT4gYXJyYXkoJ21ldGhvZE5hbWUnLCAkcHJpb3JpdHkpKQogICAgICogKiBhcnJheSgnZXZlbnROYW1lJyA9PiBhcnJheShhcnJheSgnbWV0aG9kTmFtZTEnLCAkcHJpb3JpdHkpLCBhcnJheSgnbWV0aG9kTmFtZTInKSkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBldmVudCBuYW1lcyB0byBsaXN0ZW4gdG8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTdWJzY3JpYmVkRXZlbnRzKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFNjcmlwdEV4ZWN1dGlvbkV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXI7CgovKioKICogVGhlIGJhc2UgZXZlbnQgY2xhc3MKICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcgVGhpcyBldmVudCdzIG5hbWUKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheSBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyLCB0aGVzZSB3aWxsIGJlIGZvcndhcmRlZCB0byBDTEkgc2NyaXB0IGhhbmRsZXJzCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJnczsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkgRmxhZ3MgdXNhYmxlIGluIFBIUCBzY3JpcHQgaGFuZGxlcnMKICAgICAqLwogICAgcHJvdGVjdGVkICRmbGFnczsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbCBXaGV0aGVyIHRoZSBldmVudCBzaG91bGQgbm90IGJlIHBhc3NlZCB0byBtb3JlIGxpc3RlbmVycwogICAgICovCiAgICBwcml2YXRlICRwcm9wYWdhdGlvblN0b3BwZWQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBldmVudCBuYW1lCiAgICAgKiBAcGFyYW0gYXJyYXkgICRhcmdzICBBcmd1bWVudHMgcGFzc2VkIGJ5IHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYXJyYXkgICRmbGFncyBPcHRpb25hbCBmbGFncyB0byBwYXNzIGRhdGEgbm90IGFzIGFyZ3VtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgYXJyYXkgJGFyZ3MgPSBhcnJheSgpLCBhcnJheSAkZmxhZ3MgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgJHRoaXMtPmFyZ3MgPSAkYXJnczsKICAgICAgICAkdGhpcy0+ZmxhZ3MgPSAkZmxhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBldmVudCdzIG5hbWUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGV2ZW50IG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV2ZW50J3MgYXJndW1lbnRzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIGV2ZW50IGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBldmVudCdzIGZsYWdzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIGV2ZW50IGZsYWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGbGFncygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mbGFnczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBzdG9wUHJvcGFnYXRpb24gaGFzIGJlZW4gY2FsbGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgcHJvcGFnYXRpb24gaGFzIGJlZW4gc3RvcHBlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNQcm9wYWdhdGlvblN0b3BwZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGFnYXRpb25TdG9wcGVkOwogICAgfQoKICAgIC8qKgogICAgICogUHJldmVudHMgdGhlIGV2ZW50IGZyb20gYmVpbmcgcGFzc2VkIHRvIGZ1cnRoZXIgbGlzdGVuZXJzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdG9wUHJvcGFnYXRpb24oKQogICAgewogICAgICAgICR0aGlzLT5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlcjsKCnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcVHJhbnNhY3Rpb247CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGVyRXZlbnQ7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cT3BlcmF0aW9uSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2NyaXB0Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudDsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxCaW5hcnlJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFNjcmlwdFxFdmVudCBhcyBTY3JpcHRFdmVudDsKdXNlIENvbXBvc2VyXENsYXNzTG9hZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaHBFeGVjdXRhYmxlRmluZGVyOwoKLyoqCiAqIFRoZSBFdmVudCBEaXNwYXRjaGVyLgogKgogKiBFeGFtcGxlIGluIGNvbW1hbmQ6CiAqICAgICAkZGlzcGF0Y2hlciA9IG5ldyBFdmVudERpc3BhdGNoZXIoJHRoaXMtPmdldENvbXBvc2VyKCksICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJTygpKTsKICogICAgIC8vIC4uLgogKiAgICAgJGRpc3BhdGNoZXItPmRpc3BhdGNoKFNjcmlwdEV2ZW50czo6UE9TVF9JTlNUQUxMX0NNRCk7CiAqICAgICAvLyAuLi4KICoKICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgRXZlbnREaXNwYXRjaGVyCnsKICAgIC8qKiBAdmFyIENvbXBvc2VyICovCiAgICBwcm90ZWN0ZWQgJGNvbXBvc2VyOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciA/Q2xhc3NMb2FkZXIgKi8KICAgIHByb3RlY3RlZCAkbG9hZGVyOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3M7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIGFycmF5PGludCwgYXJyYXk8Y2FsbGFibGV8c3RyaW5nPj4+ICovCiAgICBwcm90ZWN0ZWQgJGxpc3RlbmVycyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBsaXN0PHN0cmluZz4gKi8KICAgIHByaXZhdGUgJGV2ZW50U3RhY2s7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgICAgICAgICRjb21wb3NlciBUaGUgY29tcG9zZXIgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgJGlvICAgICAgIFRoZSBJT0ludGVyZmFjZSBpbnN0YW5jZQogICAgICogQHBhcmFtIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tcG9zZXIgJGNvbXBvc2VyLCBJT0ludGVyZmFjZSAkaW8sIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gJGNvbXBvc2VyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzID86IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkdGhpcy0+ZXZlbnRTdGFjayA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwYXRjaCBhbiBldmVudAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRldmVudE5hbWUgQW4gZXZlbnQgbmFtZQogICAgICogQHBhcmFtICBFdmVudCAgJGV2ZW50CiAgICAgKiBAcmV0dXJuIGludCAgICByZXR1cm4gY29kZSBvZiB0aGUgZXhlY3V0ZWQgc2NyaXB0IGlmIGFueSwgZm9yIHBocCBzY3JpcHRzIGEgZmFsc2UgcmV0dXJuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgaXMgY2hhbmdlZCB0byAxLCBhbnl0aGluZyBlbHNlIHRvIDAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoKCRldmVudE5hbWUsIEV2ZW50ICRldmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRldmVudCkgewogICAgICAgICAgICAkZXZlbnQgPSBuZXcgRXZlbnQoJGV2ZW50TmFtZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvRGlzcGF0Y2goJGV2ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIERpc3BhdGNoIGEgc2NyaXB0IGV2ZW50LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRldmVudE5hbWUgICAgICBUaGUgY29uc3RhbnQgaW4gU2NyaXB0RXZlbnRzCiAgICAgKiBAcGFyYW0gIGJvb2wgICAkZGV2TW9kZQogICAgICogQHBhcmFtICBhcnJheSAgJGFkZGl0aW9uYWxBcmdzIEFyZ3VtZW50cyBwYXNzZWQgYnkgdGhlIHVzZXIKICAgICAqIEBwYXJhbSAgYXJyYXkgICRmbGFncyAgICAgICAgICBPcHRpb25hbCBmbGFncyB0byBwYXNzIGRhdGEgbm90IGFzIGFyZ3VtZW50CiAgICAgKiBAcmV0dXJuIGludCAgICByZXR1cm4gY29kZSBvZiB0aGUgZXhlY3V0ZWQgc2NyaXB0IGlmIGFueSwgZm9yIHBocCBzY3JpcHRzIGEgZmFsc2UgcmV0dXJuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBpcyBjaGFuZ2VkIHRvIDEsIGFueXRoaW5nIGVsc2UgdG8gMAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzcGF0Y2hTY3JpcHQoJGV2ZW50TmFtZSwgJGRldk1vZGUgPSBmYWxzZSwgJGFkZGl0aW9uYWxBcmdzID0gYXJyYXkoKSwgJGZsYWdzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvRGlzcGF0Y2gobmV3IFNjcmlwdFxFdmVudCgkZXZlbnROYW1lLCAkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbywgJGRldk1vZGUsICRhZGRpdGlvbmFsQXJncywgJGZsYWdzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwYXRjaCBhIHBhY2thZ2UgZXZlbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJGV2ZW50TmFtZSAgVGhlIGNvbnN0YW50IGluIFBhY2thZ2VFdmVudHMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICRkZXZNb2RlICAgIFdoZXRoZXIgb3Igbm90IHdlIGFyZSBpbiBkZXYgbW9kZQogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgJGxvY2FsUmVwbyAgVGhlIGluc3RhbGxlZCByZXBvc2l0b3J5CiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAgICAkb3BlcmF0aW9ucyBUaGUgbGlzdCBvZiBvcGVyYXRpb25zCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlICAkb3BlcmF0aW9uICBUaGUgcGFja2FnZSBiZWluZyBpbnN0YWxsZWQvdXBkYXRlZC9yZW1vdmVkCiAgICAgKgogICAgICogQHJldHVybiBpbnQgcmV0dXJuIGNvZGUgb2YgdGhlIGV4ZWN1dGVkIHNjcmlwdCBpZiBhbnksIGZvciBwaHAgc2NyaXB0cyBhIGZhbHNlIHJldHVybgogICAgICogICAgICAgICAgICAgdmFsdWUgaXMgY2hhbmdlZCB0byAxLCBhbnl0aGluZyBlbHNlIHRvIDAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc3BhdGNoUGFja2FnZUV2ZW50KCRldmVudE5hbWUsICRkZXZNb2RlLCBSZXBvc2l0b3J5SW50ZXJmYWNlICRsb2NhbFJlcG8sIGFycmF5ICRvcGVyYXRpb25zLCBPcGVyYXRpb25JbnRlcmZhY2UgJG9wZXJhdGlvbikKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvRGlzcGF0Y2gobmV3IFBhY2thZ2VFdmVudCgkZXZlbnROYW1lLCAkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbywgJGRldk1vZGUsICRsb2NhbFJlcG8sICRvcGVyYXRpb25zLCAkb3BlcmF0aW9uKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwYXRjaCBhIGluc3RhbGxlciBldmVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGV2ZW50TmFtZSAgICAgICAgIFRoZSBjb25zdGFudCBpbiBJbnN0YWxsZXJFdmVudHMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkZGV2TW9kZSAgICAgICAgICAgV2hldGhlciBvciBub3Qgd2UgYXJlIGluIGRldiBtb2RlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGV4ZWN1dGVPcGVyYXRpb25zIFRydWUgaWYgb3BlcmF0aW9ucyB3aWxsIGJlIGV4ZWN1dGVkLCBmYWxzZSBpbiAtLWRyeS1ydW4KICAgICAqIEBwYXJhbSBUcmFuc2FjdGlvbiAkdHJhbnNhY3Rpb24gICAgICAgVGhlIHRyYW5zYWN0aW9uIGNvbnRhaW5zIHRoZSBsaXN0IG9mIG9wZXJhdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCByZXR1cm4gY29kZSBvZiB0aGUgZXhlY3V0ZWQgc2NyaXB0IGlmIGFueSwgZm9yIHBocCBzY3JpcHRzIGEgZmFsc2UgcmV0dXJuCiAgICAgKiAgICAgICAgICAgICB2YWx1ZSBpcyBjaGFuZ2VkIHRvIDEsIGFueXRoaW5nIGVsc2UgdG8gMAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzcGF0Y2hJbnN0YWxsZXJFdmVudCgkZXZlbnROYW1lLCAkZGV2TW9kZSwgJGV4ZWN1dGVPcGVyYXRpb25zLCBUcmFuc2FjdGlvbiAkdHJhbnNhY3Rpb24pCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kb0Rpc3BhdGNoKG5ldyBJbnN0YWxsZXJFdmVudCgkZXZlbnROYW1lLCAkdGhpcy0+Y29tcG9zZXIsICR0aGlzLT5pbywgJGRldk1vZGUsICRleGVjdXRlT3BlcmF0aW9ucywgJHRyYW5zYWN0aW9uKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUcmlnZ2VycyB0aGUgbGlzdGVuZXJzIG9mIGFuIGV2ZW50LgogICAgICoKICAgICAqIEBwYXJhbSAgRXZlbnQgICAgICAgICAgICAgICAgICAgICAgICAkZXZlbnQgVGhlIGV2ZW50IG9iamVjdCB0byBwYXNzIHRvIHRoZSBldmVudCBoYW5kbGVycy9saXN0ZW5lcnMuCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9ufFxFeGNlcHRpb24KICAgICAqIEByZXR1cm4gaW50ICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29kZSBvZiB0aGUgZXhlY3V0ZWQgc2NyaXB0IGlmIGFueSwgZm9yIHBocCBzY3JpcHRzIGEgZmFsc2UgcmV0dXJuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgaXMgY2hhbmdlZCB0byAxLCBhbnl0aGluZyBlbHNlIHRvIDAKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRGlzcGF0Y2goRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgIGlmIChnZXRlbnYoJ0NPTVBPU0VSX0RFQlVHX0VWRU5UUycpKSB7CiAgICAgICAgICAgICRkZXRhaWxzID0gbnVsbDsKICAgICAgICAgICAgaWYgKCRldmVudCBpbnN0YW5jZW9mIFBhY2thZ2VFdmVudCkgewogICAgICAgICAgICAgICAgJGRldGFpbHMgPSAoc3RyaW5nKSAkZXZlbnQtPmdldE9wZXJhdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRGlzcGF0Y2hpbmcgPGluZm8+Jy4kZXZlbnQtPmdldE5hbWUoKS4nPC9pbmZvPicuKCRkZXRhaWxzID8gJyAoJy4kZGV0YWlscy4nKScgOiAnJykuJyBldmVudCcpOwogICAgICAgIH0KCiAgICAgICAgJGxpc3RlbmVycyA9ICR0aGlzLT5nZXRMaXN0ZW5lcnMoJGV2ZW50KTsKCiAgICAgICAgJHRoaXMtPnB1c2hFdmVudCgkZXZlbnQpOwoKICAgICAgICAkcmV0dXJuTWF4ID0gMDsKICAgICAgICBmb3JlYWNoICgkbGlzdGVuZXJzIGFzICRjYWxsYWJsZSkgewogICAgICAgICAgICAkcmV0dXJuID0gMDsKICAgICAgICAgICAgJHRoaXMtPmVuc3VyZUJpbkRpcklzSW5QYXRoKCk7CgogICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkY2FsbGFibGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2NhbGxhYmxlKCRjYWxsYWJsZSkpIHsKICAgICAgICAgICAgICAgICAgICAkY2xhc3NOYW1lID0gaXNfb2JqZWN0KCRjYWxsYWJsZVswXSkgPyBnZXRfY2xhc3MoJGNhbGxhYmxlWzBdKSA6ICRjYWxsYWJsZVswXTsKCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdTdWJzY3JpYmVyICcuJGNsYXNzTmFtZS4nOjonLiRjYWxsYWJsZVsxXS4nIGZvciBldmVudCAnLiRldmVudC0+Z2V0TmFtZSgpLicgaXMgbm90IGNhbGxhYmxlLCBtYWtlIHN1cmUgdGhlIGZ1bmN0aW9uIGlzIGRlZmluZWQgYW5kIHB1YmxpYycpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRjYWxsYWJsZSkgJiYgKGlzX3N0cmluZygkY2FsbGFibGVbMF0pIHx8IGlzX29iamVjdCgkY2FsbGFibGVbMF0pKSAmJiBpc19zdHJpbmcoJGNhbGxhYmxlWzFdKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc+ICVzOiAlcycsICRldmVudC0+Z2V0TmFtZSgpLCAoaXNfb2JqZWN0KCRjYWxsYWJsZVswXSkgPyBnZXRfY2xhc3MoJGNhbGxhYmxlWzBdKSA6ICRjYWxsYWJsZVswXSkuJy0+Jy4kY2FsbGFibGVbMV0pLCB0cnVlLCBJT0ludGVyZmFjZTo6VkVSQk9TRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmV0dXJuID0gZmFsc2UgPT09IGNhbGxfdXNlcl9mdW5jKCRjYWxsYWJsZSwgJGV2ZW50KSA/IDEgOiAwOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlzQ29tcG9zZXJTY3JpcHQoJGNhbGxhYmxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJz4gJXM6ICVzJywgJGV2ZW50LT5nZXROYW1lKCksICRjYWxsYWJsZSksIHRydWUsIElPSW50ZXJmYWNlOjpWRVJCT1NFKTsKCiAgICAgICAgICAgICAgICAkc2NyaXB0ID0gZXhwbG9kZSgnICcsIHN1YnN0cigkY2FsbGFibGUsIDEpKTsKICAgICAgICAgICAgICAgICRzY3JpcHROYW1lID0gJHNjcmlwdFswXTsKICAgICAgICAgICAgICAgIHVuc2V0KCRzY3JpcHRbMF0pOwoKICAgICAgICAgICAgICAgICRhcmdzID0gYXJyYXlfbWVyZ2UoJHNjcmlwdCwgJGV2ZW50LT5nZXRBcmd1bWVudHMoKSk7CiAgICAgICAgICAgICAgICAkZmxhZ3MgPSAkZXZlbnQtPmdldEZsYWdzKCk7CiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRjYWxsYWJsZSwgJ0Bjb21wb3NlciAnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICRleGVjID0gJHRoaXMtPmdldFBocEV4ZWNDb21tYW5kKCkgLiAnICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShnZXRlbnYoJ0NPTVBPU0VSX0JJTkFSWScpKSAuICcgJyAuIGltcGxvZGUoJyAnLCAkYXJncyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgIT09ICgkZXhpdENvZGUgPSAkdGhpcy0+ZXhlY3V0ZVR0eSgkZXhlYykpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+U2NyaXB0ICVzIGhhbmRsaW5nIHRoZSAlcyBldmVudCByZXR1cm5lZCB3aXRoIGVycm9yIGNvZGUgJy4kZXhpdENvZGUuJzwvZXJyb3I+JywgJGNhbGxhYmxlLCAkZXZlbnQtPmdldE5hbWUoKSksIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NyaXB0RXhlY3V0aW9uRXhjZXB0aW9uKCdFcnJvciBPdXRwdXQ6ICcuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICRleGl0Q29kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRMaXN0ZW5lcnMobmV3IEV2ZW50KCRzY3JpcHROYW1lKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJzx3YXJuaW5nPllvdSBtYWRlIGEgcmVmZXJlbmNlIHRvIGEgbm9uLWV4aXN0ZW50IHNjcmlwdCAlczwvd2FybmluZz4nLCAkY2FsbGFibGUpLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgLyoqIEB2YXIgSW5zdGFsbGVyRXZlbnQgJGV2ZW50ICovCiAgICAgICAgICAgICAgICAgICAgICAgICRzY3JpcHRFdmVudCA9IG5ldyBTY3JpcHRcRXZlbnQoJHNjcmlwdE5hbWUsICRldmVudC0+Z2V0Q29tcG9zZXIoKSwgJGV2ZW50LT5nZXRJTygpLCAkZXZlbnQtPmlzRGV2TW9kZSgpLCAkYXJncywgJGZsYWdzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHNjcmlwdEV2ZW50LT5zZXRPcmlnaW5hdGluZ0V2ZW50KCRldmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXR1cm4gPSAkdGhpcy0+ZGlzcGF0Y2goJHNjcmlwdE5hbWUsICRzY3JpcHRFdmVudCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2NyaXB0RXhlY3V0aW9uRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+U2NyaXB0ICVzIHdhcyBjYWxsZWQgdmlhICVzPC9lcnJvcj4nLCAkY2FsbGFibGUsICRldmVudC0+Z2V0TmFtZSgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlzUGhwU2NyaXB0KCRjYWxsYWJsZSkpIHsKICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSBzdWJzdHIoJGNhbGxhYmxlLCAwLCBzdHJwb3MoJGNhbGxhYmxlLCAnOjonKSk7CiAgICAgICAgICAgICAgICAkbWV0aG9kTmFtZSA9IHN1YnN0cigkY2FsbGFibGUsIHN0cnBvcygkY2FsbGFibGUsICc6OicpICsgMik7CgogICAgICAgICAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJGNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNsYXNzICcuJGNsYXNzTmFtZS4nIGlzIG5vdCBhdXRvbG9hZGFibGUsIGNhbiBub3QgY2FsbCAnLiRldmVudC0+Z2V0TmFtZSgpLicgc2NyaXB0PC93YXJuaW5nPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzX2NhbGxhYmxlKCRjYWxsYWJsZSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPk1ldGhvZCAnLiRjYWxsYWJsZS4nIGlzIG5vdCBjYWxsYWJsZSwgY2FuIG5vdCBjYWxsICcuJGV2ZW50LT5nZXROYW1lKCkuJyBzY3JpcHQ8L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRyZXR1cm4gPSBmYWxzZSA9PT0gJHRoaXMtPmV4ZWN1dGVFdmVudFBocFNjcmlwdCgkY2xhc3NOYW1lLCAkbWV0aG9kTmFtZSwgJGV2ZW50KSA/IDEgOiAwOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlNjcmlwdCAlcyBoYW5kbGluZyB0aGUgJXMgZXZlbnQgdGVybWluYXRlZCB3aXRoIGFuIGV4Y2VwdGlvbiI7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy5zcHJpbnRmKCRtZXNzYWdlLCAkY2FsbGFibGUsICRldmVudC0+Z2V0TmFtZSgpKS4nPC9lcnJvcj4nLCB0cnVlLCBJT0ludGVyZmFjZTo6UVVJRVQpOwogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGFyZ3MgPSBpbXBsb2RlKCcgJywgYXJyYXlfbWFwKGFycmF5KCdDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcicsICdlc2NhcGUnKSwgJGV2ZW50LT5nZXRBcmd1bWVudHMoKSkpOwogICAgICAgICAgICAgICAgJGV4ZWMgPSAkY2FsbGFibGUgLiAoJGFyZ3MgPT09ICcnID8gJycgOiAnICcuJGFyZ3MpOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNWZXJib3NlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignPiAlczogJXMnLCAkZXZlbnQtPmdldE5hbWUoKSwgJGV4ZWMpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkZXZlbnQtPmdldE5hbWUoKSAhPT0gJ19fZXhlY19jb21tYW5kJykgewogICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBvdXRwdXQgdGhlIGNvbW1hbmQgYmVpbmcgcnVuIHdoZW4gdXNpbmcgYGNvbXBvc2VyIGV4ZWNgIGFzIGl0IGlzIGZhaXJseSBvYnZpb3VzIHRoZSB1c2VyIGlzIHJ1bm5pbmcgaXQKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignPiAlcycsICRleGVjKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHBvc3NpYmxlTG9jYWxCaW5hcmllcyA9ICR0aGlzLT5jb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRCaW5hcmllcygpOwogICAgICAgICAgICAgICAgaWYgKCRwb3NzaWJsZUxvY2FsQmluYXJpZXMpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9zc2libGVMb2NhbEJpbmFyaWVzIGFzICRsb2NhbEV4ZWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tcYicucHJlZ19xdW90ZSgkY2FsbGFibGUpLickfScsICRsb2NhbEV4ZWMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FsbGVyID0gQmluYXJ5SW5zdGFsbGVyOjpkZXRlcm1pbmVCaW5hcnlDYWxsZXIoJGxvY2FsRXhlYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXhlYyA9IHByZWdfcmVwbGFjZSgne14nLnByZWdfcXVvdGUoJGNhbGxhYmxlKS4nfScsICRjYWxsZXIgLiAnICcgLiAkbG9jYWxFeGVjLCAkZXhlYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRleGVjLCAnQHB1dGVudiAnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIHB1dGVudihzdWJzdHIoJGV4ZWMsIDgpKTsKICAgICAgICAgICAgICAgICAgICBsaXN0KCR2YXIsICR2YWx1ZSkgPSBleHBsb2RlKCc9Jywgc3Vic3RyKCRleGVjLCA4KSwgMik7CiAgICAgICAgICAgICAgICAgICAgJF9TRVJWRVJbJHZhcl0gPSAkdmFsdWU7CgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkZXhlYywgJ0BwaHAgJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkcGF0aEFuZEFyZ3MgPSBzdWJzdHIoJGV4ZWMsIDUpOwogICAgICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGhBbmRBcmdzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCd7XlxTK30nLCBmdW5jdGlvbiAoJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnLycsICdcXCcsICRwYXRoWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgJHBhdGhBbmRBcmdzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGV4ZWMgPSAkdGhpcy0+Z2V0UGhwRXhlY0NvbW1hbmQoKSAuICcgJyAuICRwYXRoQW5kQXJnczsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGZpbmRlciA9IG5ldyBQaHBFeGVjdXRhYmxlRmluZGVyKCk7CiAgICAgICAgICAgICAgICAgICAgJHBocFBhdGggPSAkZmluZGVyLT5maW5kKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBocFBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJF9TRVJWRVJbJ1BIUF9CSU5BUlknXSA9ICRwaHBQYXRoOwogICAgICAgICAgICAgICAgICAgICAgICBwdXRlbnYoJ1BIUF9CSU5BUlk9JyAuICRfU0VSVkVSWydQSFBfQklOQVJZJ10pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXhlYyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygne15cUyt9JywgZnVuY3Rpb24gKCRwYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJy8nLCAnXFwnLCAkcGF0aFswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0sICRleGVjKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaWYgY29tcG9zZXIgaXMgYmVpbmcgZXhlY3V0ZWQsIG1ha2Ugc3VyZSBpdCBydW5zIHRoZSBleHBlY3RlZCBjb21wb3NlciBmcm9tIGN1cnJlbnQgcGF0aAogICAgICAgICAgICAgICAgLy8gcmVzb2x1dGlvbiwgZXZlbiBpZiBiaW4tZGlyIGNvbnRhaW5zIGNvbXBvc2VyIHRvbyBiZWNhdXNlIHRoZSBwcm9qZWN0IHJlcXVpcmVzIGNvbXBvc2VyL2NvbXBvc2VyCiAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy84NzQ4CiAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRleGVjLCAnY29tcG9zZXIgJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkZXhlYyA9ICR0aGlzLT5nZXRQaHBFeGVjQ29tbWFuZCgpIC4gJyAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoZ2V0ZW52KCdDT01QT1NFUl9CSU5BUlknKSkgLiBzdWJzdHIoJGV4ZWMsIDgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgwICE9PSAoJGV4aXRDb2RlID0gJHRoaXMtPmV4ZWN1dGVUdHkoJGV4ZWMpKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+U2NyaXB0ICVzIGhhbmRsaW5nIHRoZSAlcyBldmVudCByZXR1cm5lZCB3aXRoIGVycm9yIGNvZGUgJy4kZXhpdENvZGUuJzwvZXJyb3I+JywgJGNhbGxhYmxlLCAkZXZlbnQtPmdldE5hbWUoKSksIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTY3JpcHRFeGVjdXRpb25FeGNlcHRpb24oJ0Vycm9yIE91dHB1dDogJy4kdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSwgJGV4aXRDb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJldHVybk1heCA9IG1heCgkcmV0dXJuTWF4LCAkcmV0dXJuKTsKCiAgICAgICAgICAgIGlmICgkZXZlbnQtPmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cG9wRXZlbnQoKTsKCiAgICAgICAgcmV0dXJuICRyZXR1cm5NYXg7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGVUdHkoJGV4ZWMpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZVR0eSgkZXhlYyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGV4ZWMpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQaHBFeGVjQ29tbWFuZCgpCiAgICB7CiAgICAgICAgJGZpbmRlciA9IG5ldyBQaHBFeGVjdXRhYmxlRmluZGVyKCk7CiAgICAgICAgJHBocFBhdGggPSAkZmluZGVyLT5maW5kKGZhbHNlKTsKICAgICAgICBpZiAoISRwaHBQYXRoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGxvY2F0ZSBQSFAgYmluYXJ5IHRvIGV4ZWN1dGUgJy4kcGhwUGF0aCk7CiAgICAgICAgfQogICAgICAgICRwaHBBcmdzID0gJGZpbmRlci0+ZmluZEFyZ3VtZW50cygpOwogICAgICAgICRwaHBBcmdzID0gJHBocEFyZ3MgPyAnICcgLiBpbXBsb2RlKCcgJywgJHBocEFyZ3MpIDogJyc7CiAgICAgICAgJGFsbG93VXJsRk9wZW5GbGFnID0gJyAtZCBhbGxvd191cmxfZm9wZW49JyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKGluaV9nZXQoJ2FsbG93X3VybF9mb3BlbicpKTsKICAgICAgICAkZGlzYWJsZUZ1bmN0aW9uc0ZsYWcgPSAnIC1kIGRpc2FibGVfZnVuY3Rpb25zPScgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShpbmlfZ2V0KCdkaXNhYmxlX2Z1bmN0aW9ucycpKTsKICAgICAgICAkbWVtb3J5TGltaXRGbGFnID0gJyAtZCBtZW1vcnlfbGltaXQ9JyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKGluaV9nZXQoJ21lbW9yeV9saW1pdCcpKTsKCiAgICAgICAgcmV0dXJuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwaHBQYXRoKSAuICRwaHBBcmdzIC4gJGFsbG93VXJsRk9wZW5GbGFnIC4gJGRpc2FibGVGdW5jdGlvbnNGbGFnIC4gJG1lbW9yeUxpbWl0RmxhZzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzTmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkbWV0aG9kTmFtZQogICAgICogQHBhcmFtIEV2ZW50ICAkZXZlbnQgICAgICBFdmVudCBpbnZva2luZyB0aGUgUEhQIGNhbGxhYmxlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlRXZlbnRQaHBTY3JpcHQoJGNsYXNzTmFtZSwgJG1ldGhvZE5hbWUsIEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlvLT5pc1ZlcmJvc2UoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignPiAlczogJXM6OiVzJywgJGV2ZW50LT5nZXROYW1lKCksICRjbGFzc05hbWUsICRtZXRob2ROYW1lKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKHNwcmludGYoJz4gJXM6OiVzJywgJGNsYXNzTmFtZSwgJG1ldGhvZE5hbWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2xhc3NOYW1lOjokbWV0aG9kTmFtZSgkZXZlbnQpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgbGlzdGVuZXIgZm9yIGEgcGFydGljdWxhciBldmVudAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkZXZlbnROYW1lIFRoZSBldmVudCBuYW1lIC0gdHlwaWNhbGx5IGEgY29uc3RhbnQKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkbGlzdGVuZXIgIEEgY2FsbGFibGUgZXhwZWN0aW5nIGFuIGV2ZW50IGFyZ3VtZW50CiAgICAgKiBAcGFyYW0gaW50ICAgICAgJHByaW9yaXR5ICBBIGhpZ2hlciB2YWx1ZSByZXByZXNlbnRzIGEgaGlnaGVyIHByaW9yaXR5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRMaXN0ZW5lcigkZXZlbnROYW1lLCAkbGlzdGVuZXIsICRwcmlvcml0eSA9IDApCiAgICB7CiAgICAgICAgJHRoaXMtPmxpc3RlbmVyc1skZXZlbnROYW1lXVskcHJpb3JpdHldW10gPSAkbGlzdGVuZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8b2JqZWN0ICRsaXN0ZW5lciBBIGNhbGxhYmxlIG9yIGFuIG9iamVjdCBpbnN0YW5jZSBmb3Igd2hpY2ggYWxsIGxpc3RlbmVycyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoJGxpc3RlbmVyKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5saXN0ZW5lcnMgYXMgJGV2ZW50TmFtZSA9PiAkcHJpb3JpdGllcykgewogICAgICAgICAgICBmb3JlYWNoICgkcHJpb3JpdGllcyBhcyAkcHJpb3JpdHkgPT4gJGxpc3RlbmVycykgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpc3RlbmVycyBhcyAkaW5kZXggPT4gJGNhbmRpZGF0ZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbGlzdGVuZXIgPT09ICRjYW5kaWRhdGUgfHwgKGlzX2FycmF5KCRjYW5kaWRhdGUpICYmIGlzX29iamVjdCgkbGlzdGVuZXIpICYmICRjYW5kaWRhdGVbMF0gPT09ICRsaXN0ZW5lcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmxpc3RlbmVyc1skZXZlbnROYW1lXVskcHJpb3JpdHldWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgb2JqZWN0IG1ldGhvZHMgYXMgbGlzdGVuZXJzIGZvciB0aGUgZXZlbnRzIGluIGdldFN1YnNjcmliZWRFdmVudHMKICAgICAqCiAgICAgKiBAc2VlIEV2ZW50U3Vic2NyaWJlckludGVyZmFjZQogICAgICoKICAgICAqIEBwYXJhbSBFdmVudFN1YnNjcmliZXJJbnRlcmZhY2UgJHN1YnNjcmliZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFN1YnNjcmliZXIoRXZlbnRTdWJzY3JpYmVySW50ZXJmYWNlICRzdWJzY3JpYmVyKQogICAgewogICAgICAgIGZvcmVhY2ggKCRzdWJzY3JpYmVyLT5nZXRTdWJzY3JpYmVkRXZlbnRzKCkgYXMgJGV2ZW50TmFtZSA9PiAkcGFyYW1zKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHBhcmFtcykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMaXN0ZW5lcigkZXZlbnROYW1lLCBhcnJheSgkc3Vic2NyaWJlciwgJHBhcmFtcykpOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNfc3RyaW5nKCRwYXJhbXNbMF0pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTGlzdGVuZXIoJGV2ZW50TmFtZSwgYXJyYXkoJHN1YnNjcmliZXIsICRwYXJhbXNbMF0pLCBpc3NldCgkcGFyYW1zWzFdKSA/ICRwYXJhbXNbMV0gOiAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYXJhbXMgYXMgJGxpc3RlbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZExpc3RlbmVyKCRldmVudE5hbWUsIGFycmF5KCRzdWJzY3JpYmVyLCAkbGlzdGVuZXJbMF0pLCBpc3NldCgkbGlzdGVuZXJbMV0pID8gJGxpc3RlbmVyWzFdIDogMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgYWxsIGxpc3RlbmVycyBmb3IgYSBnaXZlbiBldmVudAogICAgICoKICAgICAqIEBwYXJhbSAgRXZlbnQgJGV2ZW50CiAgICAgKiBAcmV0dXJuIGFycmF5IEFsbCBsaXN0ZW5lcnM6IGNhbGxhYmxlcyBhbmQgc2NyaXB0cwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICAkc2NyaXB0TGlzdGVuZXJzID0gJHRoaXMtPmdldFNjcmlwdExpc3RlbmVycygkZXZlbnQpOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5saXN0ZW5lcnNbJGV2ZW50LT5nZXROYW1lKCldWzBdKSkgewogICAgICAgICAgICAkdGhpcy0+bGlzdGVuZXJzWyRldmVudC0+Z2V0TmFtZSgpXVswXSA9IGFycmF5KCk7CiAgICAgICAgfQogICAgICAgIGtyc29ydCgkdGhpcy0+bGlzdGVuZXJzWyRldmVudC0+Z2V0TmFtZSgpXSk7CgogICAgICAgICRsaXN0ZW5lcnMgPSAkdGhpcy0+bGlzdGVuZXJzOwogICAgICAgICRsaXN0ZW5lcnNbJGV2ZW50LT5nZXROYW1lKCldWzBdID0gYXJyYXlfbWVyZ2UoJGxpc3RlbmVyc1skZXZlbnQtPmdldE5hbWUoKV1bMF0sICRzY3JpcHRMaXN0ZW5lcnMpOwoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgJGxpc3RlbmVyc1skZXZlbnQtPmdldE5hbWUoKV0pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGFuIGV2ZW50IGhhcyBsaXN0ZW5lcnMgcmVnaXN0ZXJlZAogICAgICoKICAgICAqIEBwYXJhbSAgRXZlbnQgJGV2ZW50CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0V2ZW50TGlzdGVuZXJzKEV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICAkbGlzdGVuZXJzID0gJHRoaXMtPmdldExpc3RlbmVycygkZXZlbnQpOwoKICAgICAgICByZXR1cm4gY291bnQoJGxpc3RlbmVycykgPiAwOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgYWxsIGxpc3RlbmVycyBkZWZpbmVkIGFzIHNjcmlwdHMgaW4gdGhlIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIEV2ZW50ICRldmVudCBFdmVudCBvYmplY3QKICAgICAqIEByZXR1cm4gYXJyYXkgTGlzdGVuZXJzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRTY3JpcHRMaXN0ZW5lcnMoRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgJHNjcmlwdHMgPSAkcGFja2FnZS0+Z2V0U2NyaXB0cygpOwoKICAgICAgICBpZiAoZW1wdHkoJHNjcmlwdHNbJGV2ZW50LT5nZXROYW1lKCldKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bG9hZGVyKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkZXItPnVucmVnaXN0ZXIoKTsKICAgICAgICB9CgogICAgICAgICRnZW5lcmF0b3IgPSAkdGhpcy0+Y29tcG9zZXItPmdldEF1dG9sb2FkR2VuZXJhdG9yKCk7CiAgICAgICAgaWYgKCRldmVudCBpbnN0YW5jZW9mIFNjcmlwdEV2ZW50KSB7CiAgICAgICAgICAgICRnZW5lcmF0b3ItPnNldERldk1vZGUoJGV2ZW50LT5pc0Rldk1vZGUoKSk7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+Y29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpLT5nZXRDYW5vbmljYWxQYWNrYWdlcygpOwogICAgICAgICRwYWNrYWdlTWFwID0gJGdlbmVyYXRvci0+YnVpbGRQYWNrYWdlTWFwKCR0aGlzLT5jb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLCAkcGFja2FnZSwgJHBhY2thZ2VzKTsKICAgICAgICAkbWFwID0gJGdlbmVyYXRvci0+cGFyc2VBdXRvbG9hZHMoJHBhY2thZ2VNYXAsICRwYWNrYWdlKTsKICAgICAgICAkdGhpcy0+bG9hZGVyID0gJGdlbmVyYXRvci0+Y3JlYXRlTG9hZGVyKCRtYXAsICR0aGlzLT5jb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgndmVuZG9yLWRpcicpKTsKICAgICAgICAkdGhpcy0+bG9hZGVyLT5yZWdpc3RlcihmYWxzZSk7CgogICAgICAgIHJldHVybiAkc2NyaXB0c1skZXZlbnQtPmdldE5hbWUoKV07CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc3RyaW5nIGdpdmVuIHJlZmVyZW5jZXMgYSBjbGFzcyBwYXRoIGFuZCBtZXRob2QKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkY2FsbGFibGUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNQaHBTY3JpcHQoJGNhbGxhYmxlKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSA9PT0gc3RycG9zKCRjYWxsYWJsZSwgJyAnKSAmJiBmYWxzZSAhPT0gc3RycG9zKCRjYWxsYWJsZSwgJzo6Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc3RyaW5nIGdpdmVuIHJlZmVyZW5jZXMgYSBjb21wb3NlciBydW4tc2NyaXB0CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGNhbGxhYmxlCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzQ29tcG9zZXJTY3JpcHQoJGNhbGxhYmxlKQogICAgewogICAgICAgIHJldHVybiBzdHJwb3MoJGNhbGxhYmxlLCAnQCcpID09PSAwICYmIHN0cnBvcygkY2FsbGFibGUsICdAcGhwICcpICE9PSAwICYmIHN0cnBvcygkY2FsbGFibGUsICdAcHV0ZW52ICcpICE9PSAwOwogICAgfQoKICAgIC8qKgogICAgICogUHVzaCBhbiBldmVudCB0byB0aGUgc3RhY2sgb2YgYWN0aXZlIGV2ZW50CiAgICAgKgogICAgICogQHBhcmFtICBFdmVudCAgICAgICAgICAgICAkZXZlbnQKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwdXNoRXZlbnQoRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgICRldmVudE5hbWUgPSAkZXZlbnQtPmdldE5hbWUoKTsKICAgICAgICBpZiAoaW5fYXJyYXkoJGV2ZW50TmFtZSwgJHRoaXMtPmV2ZW50U3RhY2spKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCJDaXJjdWxhciBjYWxsIHRvIHNjcmlwdCBoYW5kbGVyICclcycgZGV0ZWN0ZWQiLCAkZXZlbnROYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfcHVzaCgkdGhpcy0+ZXZlbnRTdGFjaywgJGV2ZW50TmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQb3BzIHRoZSBhY3RpdmUgZXZlbnQgZnJvbSB0aGUgc3RhY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwb3BFdmVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X3BvcCgkdGhpcy0+ZXZlbnRTdGFjayk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbnN1cmVCaW5EaXJJc0luUGF0aCgpCiAgICB7CiAgICAgICAgJHBhdGhTdHIgPSAnUEFUSCc7CiAgICAgICAgaWYgKCFpc3NldCgkX1NFUlZFUlskcGF0aFN0cl0pICYmIGlzc2V0KCRfU0VSVkVSWydQYXRoJ10pKSB7CiAgICAgICAgICAgICRwYXRoU3RyID0gJ1BhdGgnOwogICAgICAgIH0KCiAgICAgICAgLy8gYWRkIHRoZSBiaW4gZGlyIHRvIHRoZSBQQVRIIHRvIG1ha2UgbG9jYWwgYmluYXJpZXMgb2YgZGVwcyB1c2FibGUgaW4gc2NyaXB0cwogICAgICAgICRiaW5EaXIgPSAkdGhpcy0+Y29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2Jpbi1kaXInKTsKICAgICAgICBpZiAoaXNfZGlyKCRiaW5EaXIpKSB7CiAgICAgICAgICAgICRiaW5EaXIgPSByZWFscGF0aCgkYmluRGlyKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRfU0VSVkVSWyRwYXRoU3RyXSkgJiYgIXByZWdfbWF0Y2goJ3soXnwnLlBBVEhfU0VQQVJBVE9SLicpJy5wcmVnX3F1b3RlKCRiaW5EaXIpLicoJHwnLlBBVEhfU0VQQVJBVE9SLicpfScsICRfU0VSVkVSWyRwYXRoU3RyXSkpIHsKICAgICAgICAgICAgICAgICRfU0VSVkVSWyRwYXRoU3RyXSA9ICRiaW5EaXIuUEFUSF9TRVBBUkFUT1IuZ2V0ZW52KCRwYXRoU3RyKTsKICAgICAgICAgICAgICAgIHB1dGVudigkcGF0aFN0ci4nPScuJF9TRVJWRVJbJHBhdGhTdHJdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlcjsKCnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcQ2FCdW5kbGVcQ2FCdW5kbGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcRmluZGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzOwp1c2UgU2VsZFxQaGFyVXRpbHNcVGltZXN0YW1wczsKdXNlIFNlbGRcUGhhclV0aWxzXExpbnRlcjsKCi8qKgogKiBUaGUgQ29tcGlsZXIgY2xhc3MgY29tcGlsZXMgY29tcG9zZXIgaW50byBhIHBoYXIKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENvbXBpbGVyCnsKICAgIHByaXZhdGUgJHZlcnNpb247CiAgICBwcml2YXRlICRicmFuY2hBbGlhc1ZlcnNpb24gPSAnJzsKICAgIHByaXZhdGUgJHZlcnNpb25EYXRlOwoKICAgIC8qKgogICAgICogQ29tcGlsZXMgY29tcG9zZXIgaW50byBhIHNpbmdsZSBwaGFyIGZpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwaGFyRmlsZSBUaGUgZnVsbCBwYXRoIHRvIHRoZSBmaWxlIHRvIGNyZWF0ZQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGlsZSgkcGhhckZpbGUgPSAnY29tcG9zZXIucGhhcicpCiAgICB7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRwaGFyRmlsZSkpIHsKICAgICAgICAgICAgdW5saW5rKCRwaGFyRmlsZSk7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzKCdnaXQgbG9nIC0tcHJldHR5PSIlSCIgLW4xIEhFQUQnLCBfX0RJUl9fKTsKICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW5cJ3QgcnVuIGdpdCBsb2cuIFlvdSBtdXN0IGVuc3VyZSB0byBydW4gY29tcGlsZSBmcm9tIGNvbXBvc2VyIGdpdCByZXBvc2l0b3J5IGNsb25lIGFuZCB0aGF0IGdpdCBiaW5hcnkgaXMgYXZhaWxhYmxlLicpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+dmVyc2lvbiA9IHRyaW0oJHByb2Nlc3MtPmdldE91dHB1dCgpKTsKCiAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcygnZ2l0IGxvZyAtbjEgLS1wcmV0dHk9JWNpIEhFQUQnLCBfX0RJUl9fKTsKICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDYW5cJ3QgcnVuIGdpdCBsb2cuIFlvdSBtdXN0IGVuc3VyZSB0byBydW4gY29tcGlsZSBmcm9tIGNvbXBvc2VyIGdpdCByZXBvc2l0b3J5IGNsb25lIGFuZCB0aGF0IGdpdCBiaW5hcnkgaXMgYXZhaWxhYmxlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnZlcnNpb25EYXRlID0gbmV3IFxEYXRlVGltZSh0cmltKCRwcm9jZXNzLT5nZXRPdXRwdXQoKSkpOwogICAgICAgICR0aGlzLT52ZXJzaW9uRGF0ZS0+c2V0VGltZXpvbmUobmV3IFxEYXRlVGltZVpvbmUoJ1VUQycpKTsKCiAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcygnZ2l0IGRlc2NyaWJlIC0tdGFncyAtLWV4YWN0LW1hdGNoIEhFQUQnKTsKICAgICAgICBpZiAoJHByb2Nlc3MtPnJ1bigpID09IDApIHsKICAgICAgICAgICAgJHRoaXMtPnZlcnNpb24gPSB0cmltKCRwcm9jZXNzLT5nZXRPdXRwdXQoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gZ2V0IGJyYW5jaC1hbGlhcyBkZWZpbmVkIGluIGNvbXBvc2VyLmpzb24gZm9yIGRldi1tYXN0ZXIgKGlmIGFueSkKICAgICAgICAgICAgJGxvY2FsQ29uZmlnID0gX19ESVJfXy4nLy4uLy4uL2NvbXBvc2VyLmpzb24nOwogICAgICAgICAgICAkZmlsZSA9IG5ldyBKc29uRmlsZSgkbG9jYWxDb25maWcpOwogICAgICAgICAgICAkbG9jYWxDb25maWcgPSAkZmlsZS0+cmVhZCgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxvY2FsQ29uZmlnWydleHRyYSddWydicmFuY2gtYWxpYXMnXVsnZGV2LW1hc3RlciddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmJyYW5jaEFsaWFzVmVyc2lvbiA9ICRsb2NhbENvbmZpZ1snZXh0cmEnXVsnYnJhbmNoLWFsaWFzJ11bJ2Rldi1tYXN0ZXInXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHBoYXIgPSBuZXcgXFBoYXIoJHBoYXJGaWxlLCAwLCAnY29tcG9zZXIucGhhcicpOwogICAgICAgICRwaGFyLT5zZXRTaWduYXR1cmVBbGdvcml0aG0oXFBoYXI6OlNIQTEpOwoKICAgICAgICAkcGhhci0+c3RhcnRCdWZmZXJpbmcoKTsKCiAgICAgICAgJGZpbmRlclNvcnQgPSBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJjbXAoc3RydHIoJGEtPmdldFJlYWxQYXRoKCksICdcXCcsICcvJyksIHN0cnRyKCRiLT5nZXRSZWFsUGF0aCgpLCAnXFwnLCAnLycpKTsKICAgICAgICB9OwoKICAgICAgICAvLyBBZGQgQ29tcG9zZXIgc291cmNlcwogICAgICAgICRmaW5kZXIgPSBuZXcgRmluZGVyKCk7CiAgICAgICAgJGZpbmRlci0+ZmlsZXMoKQogICAgICAgICAgICAtPmlnbm9yZVZDUyh0cnVlKQogICAgICAgICAgICAtPm5hbWUoJyoucGhwJykKICAgICAgICAgICAgLT5ub3ROYW1lKCdDb21waWxlci5waHAnKQogICAgICAgICAgICAtPm5vdE5hbWUoJ0NsYXNzTG9hZGVyLnBocCcpCiAgICAgICAgICAgIC0+aW4oX19ESVJfXy4nLy4uJykKICAgICAgICAgICAgLT5zb3J0KCRmaW5kZXJTb3J0KQogICAgICAgIDsKICAgICAgICBmb3JlYWNoICgkZmluZGVyIGFzICRmaWxlKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCAkZmlsZSk7CiAgICAgICAgfQogICAgICAgIC8vIEFkZCBDbGFzc0xvYWRlciBzZXBhcmF0ZWx5IHRvIG1ha2Ugc3VyZSBpdCByZXRhaW5zIHRoZSBkb2NibG9ja3MgYXMgaXQgd2lsbCBnZXQgY29waWVkIGludG8gcHJvamVjdHMKICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgbmV3IFxTcGxGaWxlSW5mbyhfX0RJUl9fIC4gJy9BdXRvbG9hZC9DbGFzc0xvYWRlci5waHAnKSwgZmFsc2UpOwoKICAgICAgICAvLyBBZGQgQ29tcG9zZXIgcmVzb3VyY2VzCiAgICAgICAgJGZpbmRlciA9IG5ldyBGaW5kZXIoKTsKICAgICAgICAkZmluZGVyLT5maWxlcygpCiAgICAgICAgICAgIC0+aW4oX19ESVJfXy4nLy4uLy4uL3JlcycpCiAgICAgICAgICAgIC0+c29ydCgkZmluZGVyU29ydCkKICAgICAgICA7CiAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkZmlsZSkgewogICAgICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgJGZpbGUsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIC8vIEFkZCB2ZW5kb3IgZmlsZXMKICAgICAgICAkZmluZGVyID0gbmV3IEZpbmRlcigpOwogICAgICAgICRmaW5kZXItPmZpbGVzKCkKICAgICAgICAgICAgLT5pZ25vcmVWQ1ModHJ1ZSkKICAgICAgICAgICAgLT5ub3RQYXRoKCcvXC8oY29tcG9zZXJcLihqc29ufGxvY2spfFtBLVpdK1wubWR8XC5naXRpZ25vcmV8YXBwdmV5b3IueW1sfHBocHVuaXRcLnhtbFwuZGlzdHxwaHBzdGFuXC5uZW9uXC5kaXN0fHBocHN0YW4tY29uZmlnXC5uZW9uKSQvJykKICAgICAgICAgICAgLT5ub3RQYXRoKCcvYmluXC8oanNvbmxpbnR8dmFsaWRhdGUtanNvbnxzaW1wbGUtcGhwdW5pdCkoXC5iYXQpPyQvJykKICAgICAgICAgICAgLT5ub3RQYXRoKCdzeW1mb255L2RlYnVnL1Jlc291cmNlcy9leHQvJykKICAgICAgICAgICAgLT5ub3RQYXRoKCdqdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL2RlbW8vJykKICAgICAgICAgICAgLT5ub3RQYXRoKCdqdXN0aW5yYWluYm93L2pzb24tc2NoZW1hL2Rpc3QvJykKICAgICAgICAgICAgLT5ub3RQYXRoKCdjb21wb3Nlci9pbnN0YWxsZWQuanNvbicpCiAgICAgICAgICAgIC0+bm90UGF0aCgnY29tcG9zZXIvTElDRU5TRScpCiAgICAgICAgICAgIC0+ZXhjbHVkZSgnVGVzdHMnKQogICAgICAgICAgICAtPmV4Y2x1ZGUoJ3Rlc3RzJykKICAgICAgICAgICAgLT5leGNsdWRlKCdkb2NzJykKICAgICAgICAgICAgLT5pbihfX0RJUl9fLicvLi4vLi4vdmVuZG9yLycpCiAgICAgICAgICAgIC0+c29ydCgkZmluZGVyU29ydCkKICAgICAgICA7CgogICAgICAgICRleHRyYUZpbGVzID0gYXJyYXkoCiAgICAgICAgICAgIHJlYWxwYXRoKF9fRElSX18gLiAnLy4uLy4uL3ZlbmRvci9jb21wb3Nlci9zcGR4LWxpY2Vuc2VzL3Jlcy9zcGR4LWV4Y2VwdGlvbnMuanNvbicpLAogICAgICAgICAgICByZWFscGF0aChfX0RJUl9fIC4gJy8uLi8uLi92ZW5kb3IvY29tcG9zZXIvc3BkeC1saWNlbnNlcy9yZXMvc3BkeC1saWNlbnNlcy5qc29uJyksCiAgICAgICAgICAgIHJlYWxwYXRoKENhQnVuZGxlOjpnZXRCdW5kbGVkQ2FCdW5kbGVQYXRoKCkpLAogICAgICAgICAgICByZWFscGF0aChfX0RJUl9fIC4gJy8uLi8uLi92ZW5kb3Ivc3ltZm9ueS9jb25zb2xlL1Jlc291cmNlcy9iaW4vaGlkZGVuaW5wdXQuZXhlJyksCiAgICAgICAgICAgIHJlYWxwYXRoKF9fRElSX18gLiAnLy4uLy4uL3ZlbmRvci9zeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nL1Jlc291cmNlcy9tYl9jb252ZXJ0X3ZhcmlhYmxlcy5waHA4JyksCiAgICAgICAgKTsKICAgICAgICAkdW5leHBlY3RlZEZpbGVzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoaW5fYXJyYXkocmVhbHBhdGgoJGZpbGUpLCAkZXh0cmFGaWxlcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRleHRyYUZpbGVzW2FycmF5X3NlYXJjaChyZWFscGF0aCgkZmlsZSksICRleHRyYUZpbGVzLCB0cnVlKV0pOwogICAgICAgICAgICB9IGVsc2VpZiAoIXByZWdfbWF0Y2goJ3soL0xJQ0VOU0V8XC5waHApJH0nLCAkZmlsZSkpIHsKICAgICAgICAgICAgICAgICR1bmV4cGVjdGVkRmlsZXNbXSA9IChzdHJpbmcpICRmaWxlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne1wucGhwW1xkLl0qJH0nLCAkZmlsZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRGaWxlKCRwaGFyLCAkZmlsZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgJGZpbGUsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRleHRyYUZpbGVzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlc2UgZmlsZXMgd2VyZSBleHBlY3RlZCBidXQgbm90IGFkZGVkIHRvIHRoZSBwaGFyLCB0aGV5IG1pZ2h0IGJlIGV4Y2x1ZGVkIG9yIGdvbmUgZnJvbSB0aGUgc291cmNlIHBhY2thZ2U6Jy5QSFBfRU9MLmltcGxvZGUoUEhQX0VPTCwgJGV4dHJhRmlsZXMpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCR1bmV4cGVjdGVkRmlsZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGVzZSBmaWxlcyB3ZXJlIHVuZXhwZWN0ZWRseSBhZGRlZCB0byB0aGUgcGhhciwgbWFrZSBzdXJlIHRoZXkgYXJlIGV4Y2x1ZGVkIG9yIGxpc3RlZCBpbiAkZXh0cmFGaWxlczonLlBIUF9FT0wuaW1wbG9kZShQSFBfRU9MLCAkdW5leHBlY3RlZEZpbGVzKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgYmluL2NvbXBvc2VyCiAgICAgICAgJHRoaXMtPmFkZENvbXBvc2VyQmluKCRwaGFyKTsKCiAgICAgICAgLy8gU3R1YnMKICAgICAgICAkcGhhci0+c2V0U3R1YigkdGhpcy0+Z2V0U3R1YigpKTsKCiAgICAgICAgJHBoYXItPnN0b3BCdWZmZXJpbmcoKTsKCiAgICAgICAgLy8gZGlzYWJsZWQgZm9yIGludGVyb3BlcmFiaWxpdHkgd2l0aCBzeXN0ZW1zIHdpdGhvdXQgZ3ppcCBleHQKICAgICAgICAvLyAkcGhhci0+Y29tcHJlc3NGaWxlcyhcUGhhcjo6R1opOwoKICAgICAgICAkdGhpcy0+YWRkRmlsZSgkcGhhciwgbmV3IFxTcGxGaWxlSW5mbyhfX0RJUl9fLicvLi4vLi4vTElDRU5TRScpLCBmYWxzZSk7CgogICAgICAgIHVuc2V0KCRwaGFyKTsKCiAgICAgICAgLy8gcmUtc2lnbiB0aGUgcGhhciB3aXRoIHJlcHJvZHVjaWJsZSB0aW1lc3RhbXAgLyBzaWduYXR1cmUKICAgICAgICAkdXRpbCA9IG5ldyBUaW1lc3RhbXBzKCRwaGFyRmlsZSk7CiAgICAgICAgJHV0aWwtPnVwZGF0ZVRpbWVzdGFtcHMoJHRoaXMtPnZlcnNpb25EYXRlKTsKICAgICAgICAkdXRpbC0+c2F2ZSgkcGhhckZpbGUsIFxQaGFyOjpTSEExKTsKCiAgICAgICAgTGludGVyOjpsaW50KCRwaGFyRmlsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIFxTcGxGaWxlSW5mbyAkZmlsZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSZWxhdGl2ZUZpbGVQYXRoKCRmaWxlKQogICAgewogICAgICAgICRyZWFsUGF0aCA9ICRmaWxlLT5nZXRSZWFsUGF0aCgpOwogICAgICAgICRwYXRoUHJlZml4ID0gZGlybmFtZShkaXJuYW1lKF9fRElSX18pKS5ESVJFQ1RPUllfU0VQQVJBVE9SOwoKICAgICAgICAkcG9zID0gc3RycG9zKCRyZWFsUGF0aCwgJHBhdGhQcmVmaXgpOwogICAgICAgICRyZWxhdGl2ZVBhdGggPSAoJHBvcyAhPT0gZmFsc2UpID8gc3Vic3RyX3JlcGxhY2UoJHJlYWxQYXRoLCAnJywgJHBvcywgc3RybGVuKCRwYXRoUHJlZml4KSkgOiAkcmVhbFBhdGg7CgogICAgICAgIHJldHVybiBzdHJ0cigkcmVsYXRpdmVQYXRoLCAnXFwnLCAnLycpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkRmlsZSgkcGhhciwgJGZpbGUsICRzdHJpcCA9IHRydWUpCiAgICB7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+Z2V0UmVsYXRpdmVGaWxlUGF0aCgkZmlsZSk7CiAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cygkZmlsZSk7CiAgICAgICAgaWYgKCRzdHJpcCkgewogICAgICAgICAgICAkY29udGVudCA9ICR0aGlzLT5zdHJpcFdoaXRlc3BhY2UoJGNvbnRlbnQpOwogICAgICAgIH0gZWxzZWlmICgnTElDRU5TRScgPT09IGJhc2VuYW1lKCRmaWxlKSkgewogICAgICAgICAgICAkY29udGVudCA9ICJcbiIuJGNvbnRlbnQuIlxuIjsKICAgICAgICB9CgogICAgICAgIGlmICgkcGF0aCA9PT0gJ3NyYy9Db21wb3Nlci9Db21wb3Nlci5waHAnKSB7CiAgICAgICAgICAgICRjb250ZW50ID0gc3RydHIoCiAgICAgICAgICAgICAgICAkY29udGVudCwKICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICdAcGFja2FnZV92ZXJzaW9uQCcgPT4gJHRoaXMtPnZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgJ0BwYWNrYWdlX2JyYW5jaF9hbGlhc192ZXJzaW9uQCcgPT4gJHRoaXMtPmJyYW5jaEFsaWFzVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAnQHJlbGVhc2VfZGF0ZUAnID0+ICR0aGlzLT52ZXJzaW9uRGF0ZS0+Zm9ybWF0KCdZLW0tZCBIOmk6cycpLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgICAgICAkY29udGVudCA9IHByZWdfcmVwbGFjZSgne1NPVVJDRV9WRVJTSU9OID0gXCdbXlwnXStcJzt9JywgJ1NPVVJDRV9WRVJTSU9OID0gXCdcJzsnLCAkY29udGVudCk7CiAgICAgICAgfQoKICAgICAgICAkcGhhci0+YWRkRnJvbVN0cmluZygkcGF0aCwgJGNvbnRlbnQpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkQ29tcG9zZXJCaW4oJHBoYXIpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cyhfX0RJUl9fLicvLi4vLi4vYmluL2NvbXBvc2VyJyk7CiAgICAgICAgJGNvbnRlbnQgPSBwcmVnX3JlcGxhY2UoJ3teIyEvdXNyL2Jpbi9lbnYgcGhwXHMqfScsICcnLCAkY29udGVudCk7CiAgICAgICAgJHBoYXItPmFkZEZyb21TdHJpbmcoJ2Jpbi9jb21wb3NlcicsICRjb250ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgd2hpdGVzcGFjZSBmcm9tIGEgUEhQIHNvdXJjZSBzdHJpbmcgd2hpbGUgcHJlc2VydmluZyBsaW5lIG51bWJlcnMuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHNvdXJjZSBBIFBIUCBzdHJpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBQSFAgc3RyaW5nIHdpdGggdGhlIHdoaXRlc3BhY2UgcmVtb3ZlZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0cmlwV2hpdGVzcGFjZSgkc291cmNlKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCd0b2tlbl9nZXRfYWxsJykpIHsKICAgICAgICAgICAgcmV0dXJuICRzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0ID0gJyc7CiAgICAgICAgZm9yZWFjaCAodG9rZW5fZ2V0X2FsbCgkc291cmNlKSBhcyAkdG9rZW4pIHsKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdG9rZW4pKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0b2tlbjsKICAgICAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCR0b2tlblswXSwgYXJyYXkoVF9DT01NRU5ULCBUX0RPQ19DT01NRU5UKSkpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQgLj0gc3RyX3JlcGVhdCgiXG4iLCBzdWJzdHJfY291bnQoJHRva2VuWzFdLCAiXG4iKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChUX1dISVRFU1BBQ0UgPT09ICR0b2tlblswXSkgewogICAgICAgICAgICAgICAgLy8gcmVkdWNlIHdpZGUgc3BhY2VzCiAgICAgICAgICAgICAgICAkd2hpdGVzcGFjZSA9IHByZWdfcmVwbGFjZSgne1sgXHRdK30nLCAnICcsICR0b2tlblsxXSk7CiAgICAgICAgICAgICAgICAvLyBub3JtYWxpemUgbmV3bGluZXMgdG8gXG4KICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gcHJlZ19yZXBsYWNlKCd7KD86XHJcbnxccnxcbil9JywgIlxuIiwgJHdoaXRlc3BhY2UpOwogICAgICAgICAgICAgICAgLy8gdHJpbSBsZWFkaW5nIHNwYWNlcwogICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSBwcmVnX3JlcGxhY2UoJ3tcbiArfScsICJcbiIsICR3aGl0ZXNwYWNlKTsKICAgICAgICAgICAgICAgICRvdXRwdXQgLj0gJHdoaXRlc3BhY2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0b2tlblsxXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRTdHViKCkKICAgIHsKICAgICAgICAkc3R1YiA9IDw8PCdFT0YnCiMhL3Vzci9iaW4vZW52IHBocAo8P3BocAovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIGxpY2Vuc2UgdGhhdCBpcyBsb2NhdGVkIGF0IHRoZSBib3R0b20gb2YgdGhpcyBmaWxlLgogKi8KCi8vIEF2b2lkIEFQQyBjYXVzaW5nIHJhbmRvbSBmYXRhbCBlcnJvcnMgcGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvMjY0CmlmIChleHRlbnNpb25fbG9hZGVkKCdhcGMnKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5lbmFibGVfY2xpJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5jYWNoZV9ieV9kZWZhdWx0JyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSkgewogICAgaWYgKHZlcnNpb25fY29tcGFyZShwaHB2ZXJzaW9uKCdhcGMnKSwgJzMuMC4xMicsICc+PScpKSB7CiAgICAgICAgaW5pX3NldCgnYXBjLmNhY2hlX2J5X2RlZmF1bHQnLCAwKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZndyaXRlKFNUREVSUiwgJ1dhcm5pbmc6IEFQQyA8PSAzLjAuMTIgbWF5IGNhdXNlIGZhdGFsIGVycm9ycyB3aGVuIHJ1bm5pbmcgY29tcG9zZXIgY29tbWFuZHMuJy5QSFBfRU9MKTsKICAgICAgICBmd3JpdGUoU1RERVJSLCAnVXBkYXRlIEFQQywgb3Igc2V0IGFwYy5lbmFibGVfY2xpIG9yIGFwYy5jYWNoZV9ieV9kZWZhdWx0IHRvIDAgaW4geW91ciBwaHAuaW5pLicuUEhQX0VPTCk7CiAgICB9Cn0KClBoYXI6Om1hcFBoYXIoJ2NvbXBvc2VyLnBoYXInKTsKCkVPRjsKCiAgICAgICAgLy8gYWRkIHdhcm5pbmcgb25jZSB0aGUgcGhhciBpcyBvbGRlciB0aGFuIDYwIGRheXMKICAgICAgICBpZiAocHJlZ19tYXRjaCgne15bYS1mMC05XSskfScsICR0aGlzLT52ZXJzaW9uKSkgewogICAgICAgICAgICAkd2FybmluZ1RpbWUgPSAkdGhpcy0+dmVyc2lvbkRhdGUtPmZvcm1hdCgnVScpICsgNjAgKiA4NjQwMDsKICAgICAgICAgICAgJHN0dWIgLj0gImRlZmluZSgnQ09NUE9TRVJfREVWX1dBUk5JTkdfVElNRScsICR3YXJuaW5nVGltZSk7XG4iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdHViIC4gPDw8J0VPRicKcmVxdWlyZSAncGhhcjovL2NvbXBvc2VyLnBoYXIvYmluL2NvbXBvc2VyJzsKCl9fSEFMVF9DT01QSUxFUigpOwpFT0Y7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XEJvdW5kOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcUGFja2FnZVNvcnRlcjsKCi8qKgogKiBAYXV0aG9yIElnb3IgV2llZGxlciA8aWdvckB3aWVkbGVyLmNoPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBBdXRvbG9hZEdlbmVyYXRvcgp7CiAgICAvKioKICAgICAqIEB2YXIgRXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHByaXZhdGUgJGV2ZW50RGlzcGF0Y2hlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkZGV2TW9kZSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJGFwY3UgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSAkYXBjdVByZWZpeDsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRydW5TY3JpcHRzID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2x8YXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSAkaWdub3JlUGxhdGZvcm1SZXFzID0gZmFsc2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyLCBJT0ludGVyZmFjZSAkaW8gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGV2TW9kZSgkZGV2TW9kZSA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAoYm9vbCkgJGRldk1vZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgdGhlIGNsYXNzIG1hcAogICAgICogYXV0aG9yaXRhdGl2ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkY2xhc3NNYXBBdXRob3JpdGF0aXZlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlID0gKGJvb2wpICRjbGFzc01hcEF1dGhvcml0YXRpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCBnZW5lcmF0ZWQgYXV0b2xvYWRlciBjb25zaWRlcnMgQVBDdSBjYWNoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICAgICAgICAkYXBjdQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRhcGN1UHJlZml4CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcGN1KCRhcGN1LCAkYXBjdVByZWZpeCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmFwY3UgPSAoYm9vbCkgJGFwY3U7CiAgICAgICAgJHRoaXMtPmFwY3VQcmVmaXggPSAkYXBjdVByZWZpeCAhPT0gbnVsbCA/IChzdHJpbmcpICRhcGN1UHJlZml4IDogJGFwY3VQcmVmaXg7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgd2hldGhlciB0byBydW4gc2NyaXB0cyBvciBub3QKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkcnVuU2NyaXB0cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UnVuU2NyaXB0cygkcnVuU2NyaXB0cyA9IHRydWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnJ1blNjcmlwdHMgPSAoYm9vbCkgJHJ1blNjcmlwdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIHNob3VsZCBiZSBpZ25vcmVkCiAgICAgKgogICAgICogSWYgdGhpcyBpcyBzZXQgdG8gdHJ1ZSwgdGhlIHBsYXRmb3JtIGNoZWNrIGZpbGUgd2lsbCBub3QgYmUgZ2VuZXJhdGVkCiAgICAgKiBJZiB0aGlzIGlzIHNldCB0byBmYWxzZSwgdGhlIHBsYXRmb3JtIGNoZWNrIGZpbGUgd2lsbCBiZSBnZW5lcmF0ZWQgd2l0aCBhbGwgcmVxdWlyZW1lbnRzCiAgICAgKiBJZiB0aGlzIGlzIHNldCB0byBzdHJpbmdbXSwgdGhvc2UgcGFja2FnZXMgd2lsbCBiZSBpZ25vcmVkIGZyb20gdGhlIHBsYXRmb3JtIGNoZWNrIGZpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8Ym9vbCAkaWdub3JlUGxhdGZvcm1SZXFzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgewogICAgICAgIGlmIChpc19hcnJheSgkaWdub3JlUGxhdGZvcm1SZXFzKSkgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlUGxhdGZvcm1SZXFzID0gYXJyYXlfZmlsdGVyKCRpZ25vcmVQbGF0Zm9ybVJlcXMsIGZ1bmN0aW9uICgkcmVxKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcmVxKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmlnbm9yZVBsYXRmb3JtUmVxcyA9IChib29sKSAkaWdub3JlUGxhdGZvcm1SZXFzOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZHVtcChDb25maWcgJGNvbmZpZywgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UsIEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIsICR0YXJnZXREaXIsICRzY2FuUHNyUGFja2FnZXMgPSBmYWxzZSwgJHN1ZmZpeCA9ICcnKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlKSB7CiAgICAgICAgICAgIC8vIEZvcmNlIHNjYW5Qc3JQYWNrYWdlcyB3aGVuIGNsYXNzbWFwIGlzIGF1dGhvcml0YXRpdmUKICAgICAgICAgICAgJHNjYW5Qc3JQYWNrYWdlcyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+cnVuU2NyaXB0cykgewogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBSRV9BVVRPTE9BRF9EVU1QLCAkdGhpcy0+ZGV2TW9kZSwgYXJyYXkoKSwgYXJyYXkoCiAgICAgICAgICAgICAgICAnb3B0aW1pemUnID0+IChib29sKSAkc2NhblBzclBhY2thZ2VzLAogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgICRmaWxlc3lzdGVtID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRjb25maWctPmdldCgndmVuZG9yLWRpcicpKTsKICAgICAgICAvLyBEbyBub3QgcmVtb3ZlIGRvdWJsZSByZWFscGF0aCgpIGNhbGxzLgogICAgICAgIC8vIEZpeGVzIGZhaWxpbmcgV2luZG93cyByZWFscGF0aCgpIGltcGxlbWVudGF0aW9uLgogICAgICAgIC8vIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTcyNzM4CiAgICAgICAgJGJhc2VQYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgocmVhbHBhdGgocmVhbHBhdGgoZ2V0Y3dkKCkpKSk7CiAgICAgICAgJHZlbmRvclBhdGggPSAkZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aChyZWFscGF0aChyZWFscGF0aCgkY29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSkpKTsKICAgICAgICAkdXNlR2xvYmFsSW5jbHVkZVBhdGggPSAoYm9vbCkgJGNvbmZpZy0+Z2V0KCd1c2UtaW5jbHVkZS1wYXRoJyk7CiAgICAgICAgJHByZXBlbmRBdXRvbG9hZGVyID0gJGNvbmZpZy0+Z2V0KCdwcmVwZW5kLWF1dG9sb2FkZXInKSA9PT0gZmFsc2UgPyAnZmFsc2UnIDogJ3RydWUnOwogICAgICAgICR0YXJnZXREaXIgPSAkdmVuZG9yUGF0aC4nLycuJHRhcmdldERpcjsKICAgICAgICAkZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0YXJnZXREaXIpOwoKICAgICAgICAkdmVuZG9yUGF0aENvZGUgPSAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUocmVhbHBhdGgoJHRhcmdldERpciksICR2ZW5kb3JQYXRoLCB0cnVlKTsKICAgICAgICAkdmVuZG9yUGF0aENvZGU1MiA9IHN0cl9yZXBsYWNlKCdfX0RJUl9fJywgJ2Rpcm5hbWUoX19GSUxFX18pJywgJHZlbmRvclBhdGhDb2RlKTsKICAgICAgICAkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZSA9ICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZSgkdmVuZG9yUGF0aCwgcmVhbHBhdGgoJHRhcmdldERpciksIHRydWUpOwoKICAgICAgICAkYXBwQmFzZURpckNvZGUgPSAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUoJHZlbmRvclBhdGgsICRiYXNlUGF0aCwgdHJ1ZSk7CiAgICAgICAgJGFwcEJhc2VEaXJDb2RlID0gc3RyX3JlcGxhY2UoJ19fRElSX18nLCAnJHZlbmRvckRpcicsICRhcHBCYXNlRGlyQ29kZSk7CgogICAgICAgICRuYW1lc3BhY2VzRmlsZSA9IDw8PEVPRgo8P3BocAoKLy8gYXV0b2xvYWRfbmFtZXNwYWNlcy5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKXCR2ZW5kb3JEaXIgPSAkdmVuZG9yUGF0aENvZGU1MjsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAoKRU9GOwoKICAgICAgICAkcHNyNEZpbGUgPSA8PDxFT0YKPD9waHAKCi8vIGF1dG9sb2FkX3BzcjQucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKClwkdmVuZG9yRGlyID0gJHZlbmRvclBhdGhDb2RlNTI7ClwkYmFzZURpciA9ICRhcHBCYXNlRGlyQ29kZTsKCnJldHVybiBhcnJheSgKCkVPRjsKCiAgICAgICAgLy8gQ29sbGVjdCBpbmZvcm1hdGlvbiBmcm9tIGFsbCBwYWNrYWdlcy4KICAgICAgICAkZGV2UGFja2FnZU5hbWVzID0gJGxvY2FsUmVwby0+Z2V0RGV2UGFja2FnZU5hbWVzKCk7CiAgICAgICAgJHBhY2thZ2VNYXAgPSAkdGhpcy0+YnVpbGRQYWNrYWdlTWFwKCRpbnN0YWxsYXRpb25NYW5hZ2VyLCAkcm9vdFBhY2thZ2UsICRsb2NhbFJlcG8tPmdldENhbm9uaWNhbFBhY2thZ2VzKCkpOwogICAgICAgIGlmICgkdGhpcy0+ZGV2TW9kZSkgewogICAgICAgICAgICAvLyBpZiBkZXYgbW9kZSBpcyBlbmFibGVkLCB0aGVuIHdlIGRvIG5vdCBmaWx0ZXIgYW55IGRldiBwYWNrYWdlcyBvdXQgc28gZGlzYWJsZSB0aGlzIGVudGlyZWx5CiAgICAgICAgICAgICRmaWx0ZXJlZERldlBhY2thZ2VzID0gZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gaWYgdGhlIGxpc3Qgb2YgZGV2IHBhY2thZ2UgbmFtZXMgaXMgYXZhaWxhYmxlIHdlIHVzZSB0aGF0IHN0cmFpZ2h0LCBvdGhlcndpc2UgcGFzcyB0cnVlIHdoaWNoIG1lYW5zIHVzZSBsZWdhY3kgYWxnbyB0byBmaWd1cmUgdGhlbSBvdXQKICAgICAgICAgICAgJGZpbHRlcmVkRGV2UGFja2FnZXMgPSAkZGV2UGFja2FnZU5hbWVzID86IHRydWU7CiAgICAgICAgfQogICAgICAgICRhdXRvbG9hZHMgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHMoJHBhY2thZ2VNYXAsICRyb290UGFja2FnZSwgJGZpbHRlcmVkRGV2UGFja2FnZXMpOwoKICAgICAgICAvLyBQcm9jZXNzIHRoZSAncHNyLTAnIGJhc2UgZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1sncHNyLTAnXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAkZXhwb3J0ZWRQYXRocyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXRocyBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJGV4cG9ydGVkUGF0aHNbXSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRleHBvcnRlZFByZWZpeCA9IHZhcl9leHBvcnQoJG5hbWVzcGFjZSwgdHJ1ZSk7CiAgICAgICAgICAgICRuYW1lc3BhY2VzRmlsZSAuPSAiICAgICRleHBvcnRlZFByZWZpeCA9PiAiOwogICAgICAgICAgICAkbmFtZXNwYWNlc0ZpbGUgLj0gImFycmF5KCIuaW1wbG9kZSgnLCAnLCAkZXhwb3J0ZWRQYXRocykuIiksXG4iOwogICAgICAgIH0KICAgICAgICAkbmFtZXNwYWNlc0ZpbGUgLj0gIik7XG4iOwoKICAgICAgICAvLyBQcm9jZXNzIHRoZSAncHNyLTQnIGJhc2UgZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1sncHNyLTQnXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAkZXhwb3J0ZWRQYXRocyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXRocyBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJGV4cG9ydGVkUGF0aHNbXSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRleHBvcnRlZFByZWZpeCA9IHZhcl9leHBvcnQoJG5hbWVzcGFjZSwgdHJ1ZSk7CiAgICAgICAgICAgICRwc3I0RmlsZSAuPSAiICAgICRleHBvcnRlZFByZWZpeCA9PiAiOwogICAgICAgICAgICAkcHNyNEZpbGUgLj0gImFycmF5KCIuaW1wbG9kZSgnLCAnLCAkZXhwb3J0ZWRQYXRocykuIiksXG4iOwogICAgICAgIH0KICAgICAgICAkcHNyNEZpbGUgLj0gIik7XG4iOwoKICAgICAgICAkY2xhc3NtYXBGaWxlID0gPDw8RU9GCjw/cGhwCgovLyBhdXRvbG9hZF9jbGFzc21hcC5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKXCR2ZW5kb3JEaXIgPSAkdmVuZG9yUGF0aENvZGU1MjsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAoKRU9GOwoKICAgICAgICAvLyBhZGQgY3VzdG9tIHBzci0wIGF1dG9sb2FkaW5nIGlmIHRoZSByb290IHBhY2thZ2UgaGFzIGEgdGFyZ2V0IGRpcgogICAgICAgICR0YXJnZXREaXJMb2FkZXIgPSBudWxsOwogICAgICAgICRtYWluQXV0b2xvYWQgPSAkcm9vdFBhY2thZ2UtPmdldEF1dG9sb2FkKCk7CiAgICAgICAgaWYgKCRyb290UGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkgJiYgIWVtcHR5KCRtYWluQXV0b2xvYWRbJ3Bzci0wJ10pKSB7CiAgICAgICAgICAgICRsZXZlbHMgPSBzdWJzdHJfY291bnQoJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHJvb3RQYWNrYWdlLT5nZXRUYXJnZXREaXIoKSksICcvJykgKyAxOwogICAgICAgICAgICAkcHJlZml4ZXMgPSBpbXBsb2RlKCcsICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHByZWZpeCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhcl9leHBvcnQoJHByZWZpeCwgdHJ1ZSk7CiAgICAgICAgICAgIH0sIGFycmF5X2tleXMoJG1haW5BdXRvbG9hZFsncHNyLTAnXSkpKTsKICAgICAgICAgICAgJGJhc2VEaXJGcm9tVGFyZ2V0RGlyQ29kZSA9ICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZSgkdGFyZ2V0RGlyLCAkYmFzZVBhdGgsIHRydWUpOwoKICAgICAgICAgICAgJHRhcmdldERpckxvYWRlciA9IDw8PEVPRgoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYXV0b2xvYWQoXCRjbGFzcykKICAgIHsKICAgICAgICBcJGRpciA9ICRiYXNlRGlyRnJvbVRhcmdldERpckNvZGUgLiAnLyc7CiAgICAgICAgXCRwcmVmaXhlcyA9IGFycmF5KCRwcmVmaXhlcyk7CiAgICAgICAgZm9yZWFjaCAoXCRwcmVmaXhlcyBhcyBcJHByZWZpeCkgewogICAgICAgICAgICBpZiAoMCAhPT0gc3RycG9zKFwkY2xhc3MsIFwkcHJlZml4KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXCRwYXRoID0gXCRkaXIgLiBpbXBsb2RlKCcvJywgYXJyYXlfc2xpY2UoZXhwbG9kZSgnXFxcXCcsIFwkY2xhc3MpLCAkbGV2ZWxzKSkuJy5waHAnOwogICAgICAgICAgICBpZiAoIVwkcGF0aCA9IHN0cmVhbV9yZXNvbHZlX2luY2x1ZGVfcGF0aChcJHBhdGgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWlyZSBcJHBhdGg7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgpFT0Y7CiAgICAgICAgfQoKICAgICAgICAkZXhjbHVkZWQgPSBudWxsOwogICAgICAgIGlmICghZW1wdHkoJGF1dG9sb2Fkc1snZXhjbHVkZS1mcm9tLWNsYXNzbWFwJ10pKSB7CiAgICAgICAgICAgICRleGNsdWRlZCA9ICRhdXRvbG9hZHNbJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCddOwogICAgICAgIH0KCiAgICAgICAgJGNsYXNzTWFwID0gYXJyYXkoKTsKICAgICAgICAkYW1iaWd1b3VzQ2xhc3NlcyA9IGFycmF5KCk7CiAgICAgICAgJHNjYW5uZWRGaWxlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2Fkc1snY2xhc3NtYXAnXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICRjbGFzc01hcCA9ICR0aGlzLT5hZGRDbGFzc01hcENvZGUoJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICRkaXIsICRleGNsdWRlZCwgbnVsbCwgbnVsbCwgJGNsYXNzTWFwLCAkYW1iaWd1b3VzQ2xhc3NlcywgJHNjYW5uZWRGaWxlcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHNjYW5Qc3JQYWNrYWdlcykgewogICAgICAgICAgICAkbmFtZXNwYWNlc1RvU2NhbiA9IGFycmF5KCk7CgogICAgICAgICAgICAvLyBTY2FuIHRoZSBQU1ItMC80IGRpcmVjdG9yaWVzIGZvciBjbGFzcyBmaWxlcywgYW5kIGFkZCB0aGVtIHRvIHRoZSBjbGFzcyBtYXAKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3Bzci00JywgJ3Bzci0wJykgYXMgJHBzclR5cGUpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJHBzclR5cGVdIGFzICRuYW1lc3BhY2UgPT4gJHBhdGhzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5hbWVzcGFjZXNUb1NjYW5bJG5hbWVzcGFjZV1bXSA9IGFycmF5KCdwYXRocycgPT4gJHBhdGhzLCAndHlwZScgPT4gJHBzclR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBrcnNvcnQoJG5hbWVzcGFjZXNUb1NjYW4pOwoKICAgICAgICAgICAgZm9yZWFjaCAoJG5hbWVzcGFjZXNUb1NjYW4gYXMgJG5hbWVzcGFjZSA9PiAkZ3JvdXBzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZ3JvdXBzIGFzICRncm91cCkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRncm91cFsncGF0aHMnXSBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXIgPSAkZmlsZXN5c3RlbS0+bm9ybWFsaXplUGF0aCgkZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJGRpcikgPyAkZGlyIDogJGJhc2VQYXRoLicvJy4kZGlyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkY2xhc3NNYXAgPSAkdGhpcy0+YWRkQ2xhc3NNYXBDb2RlKCRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkZGlyLCAkZXhjbHVkZWQsICRuYW1lc3BhY2UsICRncm91cFsndHlwZSddLCAkY2xhc3NNYXAsICRhbWJpZ3VvdXNDbGFzc2VzLCAkc2Nhbm5lZEZpbGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRhbWJpZ3VvdXNDbGFzc2VzIGFzICRjbGFzc05hbWUgPT4gJGFtYmlnaW91c1BhdGhzKSB7CiAgICAgICAgICAgICRjbGVhblBhdGggPSBzdHJfcmVwbGFjZShhcnJheSgnJHZlbmRvckRpciAuIFwnJywgJyRiYXNlRGlyIC4gXCcnLCAiJyxcbiIpLCBhcnJheSgkdmVuZG9yUGF0aCwgJGJhc2VQYXRoLCAnJyksICRjbGFzc01hcFskY2xhc3NOYW1lXSk7CgogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICAnPHdhcm5pbmc+V2FybmluZzogQW1iaWd1b3VzIGNsYXNzIHJlc29sdXRpb24sICInLiRjbGFzc05hbWUuJyInLgogICAgICAgICAgICAgICAgJyB3YXMgZm91bmQgJy4gKGNvdW50KCRhbWJpZ2lvdXNQYXRocykgKyAxKSAuJ3g6IGluICInLiRjbGVhblBhdGguJyIgYW5kICInLiBpbXBsb2RlKCciLCAiJywgJGFtYmlnaW91c1BhdGhzKSAuJyIsIHRoZSBmaXJzdCB3aWxsIGJlIHVzZWQuPC93YXJuaW5nPicKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRjbGFzc01hcFsnQ29tcG9zZXJcXEluc3RhbGxlZFZlcnNpb25zJ10gPSAiXCR2ZW5kb3JEaXIgLiAnL2NvbXBvc2VyL0luc3RhbGxlZFZlcnNpb25zLnBocCcsXG4iOwogICAgICAgIGtzb3J0KCRjbGFzc01hcCk7CiAgICAgICAgZm9yZWFjaCAoJGNsYXNzTWFwIGFzICRjbGFzcyA9PiAkY29kZSkgewogICAgICAgICAgICAkY2xhc3NtYXBGaWxlIC49ICcgICAgJy52YXJfZXhwb3J0KCRjbGFzcywgdHJ1ZSkuJyA9PiAnLiRjb2RlOwogICAgICAgIH0KICAgICAgICAkY2xhc3NtYXBGaWxlIC49ICIpO1xuIjsKCiAgICAgICAgaWYgKCEkc3VmZml4KSB7CiAgICAgICAgICAgIGlmICghJGNvbmZpZy0+Z2V0KCdhdXRvbG9hZGVyLXN1ZmZpeCcpICYmIGlzX3JlYWRhYmxlKCR2ZW5kb3JQYXRoLicvYXV0b2xvYWQucGhwJykpIHsKICAgICAgICAgICAgICAgICRjb250ZW50ID0gZmlsZV9nZXRfY29udGVudHMoJHZlbmRvclBhdGguJy9hdXRvbG9hZC5waHAnKTsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7Q29tcG9zZXJBdXRvbG9hZGVySW5pdChbXjpcc10rKTo6fScsICRjb250ZW50LCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgJHN1ZmZpeCA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkc3VmZml4KSB7CiAgICAgICAgICAgICAgICAkc3VmZml4ID0gJGNvbmZpZy0+Z2V0KCdhdXRvbG9hZGVyLXN1ZmZpeCcpID86IG1kNSh1bmlxaWQoJycsIHRydWUpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHRhcmdldERpci4nL2F1dG9sb2FkX25hbWVzcGFjZXMucGhwJywgJG5hbWVzcGFjZXNGaWxlKTsKICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkdGFyZ2V0RGlyLicvYXV0b2xvYWRfcHNyNC5waHAnLCAkcHNyNEZpbGUpOwogICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0YXJnZXREaXIuJy9hdXRvbG9hZF9jbGFzc21hcC5waHAnLCAkY2xhc3NtYXBGaWxlKTsKICAgICAgICAkaW5jbHVkZVBhdGhGaWxlUGF0aCA9ICR0YXJnZXREaXIuJy9pbmNsdWRlX3BhdGhzLnBocCc7CiAgICAgICAgaWYgKCRpbmNsdWRlUGF0aEZpbGVDb250ZW50cyA9ICR0aGlzLT5nZXRJbmNsdWRlUGF0aHNGaWxlKCRwYWNrYWdlTWFwLCAkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHZlbmRvclBhdGhDb2RlNTIsICRhcHBCYXNlRGlyQ29kZSkpIHsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJGluY2x1ZGVQYXRoRmlsZVBhdGgsICRpbmNsdWRlUGF0aEZpbGVDb250ZW50cyk7CiAgICAgICAgfSBlbHNlaWYgKGZpbGVfZXhpc3RzKCRpbmNsdWRlUGF0aEZpbGVQYXRoKSkgewogICAgICAgICAgICB1bmxpbmsoJGluY2x1ZGVQYXRoRmlsZVBhdGgpOwogICAgICAgIH0KICAgICAgICAkaW5jbHVkZUZpbGVzRmlsZVBhdGggPSAkdGFyZ2V0RGlyLicvYXV0b2xvYWRfZmlsZXMucGhwJzsKICAgICAgICBpZiAoJGluY2x1ZGVGaWxlc0ZpbGVDb250ZW50cyA9ICR0aGlzLT5nZXRJbmNsdWRlRmlsZXNGaWxlKCRhdXRvbG9hZHNbJ2ZpbGVzJ10sICRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkdmVuZG9yUGF0aENvZGU1MiwgJGFwcEJhc2VEaXJDb2RlKSkgewogICAgICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkaW5jbHVkZUZpbGVzRmlsZVBhdGgsICRpbmNsdWRlRmlsZXNGaWxlQ29udGVudHMpOwogICAgICAgIH0gZWxzZWlmIChmaWxlX2V4aXN0cygkaW5jbHVkZUZpbGVzRmlsZVBhdGgpKSB7CiAgICAgICAgICAgIHVubGluaygkaW5jbHVkZUZpbGVzRmlsZVBhdGgpOwogICAgICAgIH0KICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkdGFyZ2V0RGlyLicvYXV0b2xvYWRfc3RhdGljLnBocCcsICR0aGlzLT5nZXRTdGF0aWNGaWxlKCRzdWZmaXgsICR0YXJnZXREaXIsICR2ZW5kb3JQYXRoLCAkYmFzZVBhdGgsICRzdGF0aWNQaHBWZXJzaW9uKSk7CiAgICAgICAgJGNoZWNrUGxhdGZvcm0gPSAkY29uZmlnLT5nZXQoJ3BsYXRmb3JtLWNoZWNrJykgJiYgJHRoaXMtPmlnbm9yZVBsYXRmb3JtUmVxcyAhPT0gdHJ1ZTsKICAgICAgICAkcGxhdGZvcm1DaGVja0NvbnRlbnQgPSBudWxsOwogICAgICAgIGlmICgkY2hlY2tQbGF0Zm9ybSkgewogICAgICAgICAgICAkcGxhdGZvcm1DaGVja0NvbnRlbnQgPSAkdGhpcy0+Z2V0UGxhdGZvcm1DaGVjaygkcGFja2FnZU1hcCwgJHRoaXMtPmlnbm9yZVBsYXRmb3JtUmVxcyA/OiBhcnJheSgpLCAkY29uZmlnLT5nZXQoJ3BsYXRmb3JtLWNoZWNrJyksICRkZXZQYWNrYWdlTmFtZXMpOwogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHBsYXRmb3JtQ2hlY2tDb250ZW50KSB7CiAgICAgICAgICAgICAgICAkY2hlY2tQbGF0Zm9ybSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkY2hlY2tQbGF0Zm9ybSkgewogICAgICAgICAgICAkZmlsZXN5c3RlbS0+ZmlsZVB1dENvbnRlbnRzSWZNb2RpZmllZCgkdGFyZ2V0RGlyLicvcGxhdGZvcm1fY2hlY2sucGhwJywgJHBsYXRmb3JtQ2hlY2tDb250ZW50KTsKICAgICAgICB9IGVsc2VpZiAoZmlsZV9leGlzdHMoJHRhcmdldERpci4nL3BsYXRmb3JtX2NoZWNrLnBocCcpKSB7CiAgICAgICAgICAgIHVubGluaygkdGFyZ2V0RGlyLicvcGxhdGZvcm1fY2hlY2sucGhwJyk7CiAgICAgICAgfQogICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR2ZW5kb3JQYXRoLicvYXV0b2xvYWQucGhwJywgJHRoaXMtPmdldEF1dG9sb2FkRmlsZSgkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZSwgJHN1ZmZpeCkpOwogICAgICAgICRmaWxlc3lzdGVtLT5maWxlUHV0Q29udGVudHNJZk1vZGlmaWVkKCR0YXJnZXREaXIuJy9hdXRvbG9hZF9yZWFsLnBocCcsICR0aGlzLT5nZXRBdXRvbG9hZFJlYWxGaWxlKHRydWUsIChib29sKSAkaW5jbHVkZVBhdGhGaWxlQ29udGVudHMsICR0YXJnZXREaXJMb2FkZXIsIChib29sKSAkaW5jbHVkZUZpbGVzRmlsZUNvbnRlbnRzLCAkdmVuZG9yUGF0aENvZGUsICRhcHBCYXNlRGlyQ29kZSwgJHN1ZmZpeCwgJHVzZUdsb2JhbEluY2x1ZGVQYXRoLCAkcHJlcGVuZEF1dG9sb2FkZXIsICRzdGF0aWNQaHBWZXJzaW9uLCAkY2hlY2tQbGF0Zm9ybSkpOwoKICAgICAgICAkZmlsZXN5c3RlbS0+c2FmZUNvcHkoX19ESVJfXy4nL0NsYXNzTG9hZGVyLnBocCcsICR0YXJnZXREaXIuJy9DbGFzc0xvYWRlci5waHAnKTsKICAgICAgICAkZmlsZXN5c3RlbS0+c2FmZUNvcHkoX19ESVJfXy4nLy4uLy4uLy4uL0xJQ0VOU0UnLCAkdGFyZ2V0RGlyLicvTElDRU5TRScpOwoKICAgICAgICBpZiAoJHRoaXMtPnJ1blNjcmlwdHMpIHsKICAgICAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2hTY3JpcHQoU2NyaXB0RXZlbnRzOjpQT1NUX0FVVE9MT0FEX0RVTVAsICR0aGlzLT5kZXZNb2RlLCBhcnJheSgpLCBhcnJheSgKICAgICAgICAgICAgICAgICdvcHRpbWl6ZScgPT4gKGJvb2wpICRzY2FuUHNyUGFja2FnZXMsCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNvdW50KCRjbGFzc01hcCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRDbGFzc01hcENvZGUoJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgYXJyYXkgJGNsYXNzTWFwLCBhcnJheSAmJGFtYmlndW91c0NsYXNzZXMsIGFycmF5ICYkc2Nhbm5lZEZpbGVzKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZW5lcmF0ZUNsYXNzTWFwKCRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgdHJ1ZSwgJHNjYW5uZWRGaWxlcykgYXMgJGNsYXNzID0+ICRwYXRoKSB7CiAgICAgICAgICAgICRwYXRoQ29kZSA9ICR0aGlzLT5nZXRQYXRoQ29kZSgkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpLiIsXG4iOwogICAgICAgICAgICBpZiAoIWlzc2V0KCRjbGFzc01hcFskY2xhc3NdKSkgewogICAgICAgICAgICAgICAgJGNsYXNzTWFwWyRjbGFzc10gPSAkcGF0aENvZGU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+aW8gJiYgJGNsYXNzTWFwWyRjbGFzc10gIT09ICRwYXRoQ29kZSAmJiAhcHJlZ19tYXRjaCgney8odGVzdHxmaXh0dXJlfGV4YW1wbGV8c3R1YilzPy99aScsIHN0cnRyKCRjbGFzc01hcFskY2xhc3NdLicgJy4kcGF0aCwgJ1xcJywgJy8nKSkpIHsKICAgICAgICAgICAgICAgICRhbWJpZ3VvdXNDbGFzc2VzWyRjbGFzc11bXSA9ICRwYXRoOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNsYXNzTWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtID9hcnJheSAkZXhjbHVkZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZW5lcmF0ZUNsYXNzTWFwKCRkaXIsICRleGNsdWRlZCwgJG5hbWVzcGFjZUZpbHRlciwgJGF1dG9sb2FkVHlwZSwgJHNob3dBbWJpZ3VvdXNXYXJuaW5nLCBhcnJheSAmJHNjYW5uZWRGaWxlcykKICAgIHsKICAgICAgICBpZiAoJGV4Y2x1ZGVkKSB7CiAgICAgICAgICAgIC8vIGZpbHRlciBleGNsdWRlZCBwYXR0ZXJucyBoZXJlIHRvIG9ubHkgdXNlIHRob3NlIG1hdGNoaW5nICRkaXIKICAgICAgICAgICAgLy8gZXhjbHVkZS1mcm9tLWNsYXNzbWFwIHBhdHRlcm5zIGFyZSBhbGwgcmVhbHBhdGgnZCBzbyB3ZSBjYW4gb25seSBmaWx0ZXIgdGhlbSBpZiAkZGlyIGV4aXN0cyBzbyB0aGF0IHJlYWxwYXRoKCRkaXIpIHdpbGwgd29yawogICAgICAgICAgICAvLyBpZiAkZGlyIGRvZXMgbm90IGV4aXN0LCBpdCBzaG91bGQgYW55d2F5IG5vdCBmaW5kIGFueXRoaW5nIHRoZXJlIHNvIG5vIHRyb3VibGUKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRkaXIpKSB7CiAgICAgICAgICAgICAgICAvLyB0cmFuc2Zvcm0gJGRpciBpbiB0aGUgc2FtZSB3YXkgdGhhdCBleGNsdWRlLWZyb20tY2xhc3NtYXAgcGF0dGVybnMgYXJlIHRyYW5zZm9ybWVkIHNvIHdlIGNhbiBtYXRjaCB0aGVtIGFnYWluc3QgZWFjaCBvdGhlcgogICAgICAgICAgICAgICAgJGRpck1hdGNoID0gcHJlZ19xdW90ZShzdHJ0cihyZWFscGF0aCgkZGlyKSwgJ1xcJywgJy8nKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZXhjbHVkZWQgYXMgJGluZGV4ID0+ICRwYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmFjdCB0aGUgY29uc3RhbnQgc3RyaW5nIHByZWZpeCBvZiB0aGUgcGF0dGVybiBoZXJlLCB1bnRpbCB3ZSByZWFjaCBhIG5vbi1lc2NhcGVkIHJlZ2V4IHNwZWNpYWwgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAgICAgJHBhdHRlcm4gPSBwcmVnX3JlcGxhY2UoJ3teKChbXi4rKj9cW15cXSQoKXt9PSE8Pnw6XFxcXCMtXSt8XFxcXFsuKyo/XFteXF0kKCl7fT0hPD58OiMtXSkqKS4qfScsICckMScsICRwYXR0ZXJuKTsKICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcGF0dGVybiBpcyBub3QgYSBzdWJzZXQgb3Igc3VwZXJzZXQgb2YgJGRpciwgaXQgaXMgdW5yZWxhdGVkIGFuZCB3ZSBza2lwIGl0CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgIT09IHN0cnBvcygkcGF0dGVybiwgJGRpck1hdGNoKSAmJiAwICE9PSBzdHJwb3MoJGRpck1hdGNoLCAkcGF0dGVybikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGV4Y2x1ZGVkWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGV4Y2x1ZGVkID0gJGV4Y2x1ZGVkID8gJ3soJyAuIGltcGxvZGUoJ3wnLCAkZXhjbHVkZWQpIC4gJyl9JyA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gQ2xhc3NNYXBHZW5lcmF0b3I6OmNyZWF0ZU1hcCgkZGlyLCAkZXhjbHVkZWQsICRzaG93QW1iaWd1b3VzV2FybmluZyA/ICR0aGlzLT5pbyA6IG51bGwsICRuYW1lc3BhY2VGaWx0ZXIsICRhdXRvbG9hZFR5cGUsICRzY2FubmVkRmlsZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYnVpbGRQYWNrYWdlTWFwKEluc3RhbGxhdGlvbk1hbmFnZXIgJGluc3RhbGxhdGlvbk1hbmFnZXIsIFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlLCBhcnJheSAkcGFja2FnZXMpCiAgICB7CiAgICAgICAgLy8gYnVpbGQgcGFja2FnZSA9PiBpbnN0YWxsIHBhdGggbWFwCiAgICAgICAgJHBhY2thZ2VNYXAgPSBhcnJheShhcnJheSgkcm9vdFBhY2thZ2UsICcnKSk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZVBhY2thZ2UoJHBhY2thZ2UpOwoKICAgICAgICAgICAgJHBhY2thZ2VNYXBbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgJHBhY2thZ2UsCiAgICAgICAgICAgICAgICAkaW5zdGFsbGF0aW9uTWFuYWdlci0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlTWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gVGhyb3dzIGFuIGV4Y2VwdGlvbiwgaWYgdGhlIHBhY2thZ2UgaGFzIGlsbGVnYWwgc2V0dGluZ3MuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZVBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkYXV0b2xvYWQgPSAkcGFja2FnZS0+Z2V0QXV0b2xvYWQoKTsKICAgICAgICBpZiAoIWVtcHR5KCRhdXRvbG9hZFsncHNyLTQnXSkgJiYgbnVsbCAhPT0gJHBhY2thZ2UtPmdldFRhcmdldERpcigpKSB7CiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgJHBhY2thZ2UtPmdldFRhcmdldERpcigpOwogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiUFNSLTQgYXV0b2xvYWRpbmcgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhlIHRhcmdldC1kaXIgcHJvcGVydHksIHJlbW92ZSB0aGUgdGFyZ2V0LWRpciBpbiBwYWNrYWdlICckbmFtZScuIik7CiAgICAgICAgfQogICAgICAgIGlmICghZW1wdHkoJGF1dG9sb2FkWydwc3ItNCddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkYXV0b2xvYWRbJ3Bzci00J10gYXMgJG5hbWVzcGFjZSA9PiAkZGlycykgewogICAgICAgICAgICAgICAgaWYgKCRuYW1lc3BhY2UgIT09ICcnICYmICdcXCcgIT09IHN1YnN0cigkbmFtZXNwYWNlLCAtMSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigicHNyLTQgbmFtZXNwYWNlcyBtdXN0IGVuZCB3aXRoIGEgbmFtZXNwYWNlIHNlcGFyYXRvciwgJyRuYW1lc3BhY2UnIGRvZXMgbm90LCB1c2UgJyRuYW1lc3BhY2VcXCcuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21waWxlcyBhbiBvcmRlcmVkIGxpc3Qgb2YgbmFtZXNwYWNlID0+IHBhdGggbWFwcGluZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgICAgICAgICRwYWNrYWdlTWFwICAgICAgICAgIGFycmF5IG9mIGFycmF5KHBhY2thZ2UsIGluc3RhbGxEaXItcmVsYXRpdmUtdG8tY29tcG9zZXIuanNvbikKICAgICAqIEBwYXJhbSAgUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlICAgICAgICAgcm9vdCBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIGJvb2x8c3RyaW5nW10gICAgICAgICRmaWx0ZXJlZERldlBhY2thZ2VzIElmIGFuIGFycmF5LCB0aGUgbGlzdCBvZiBwYWNrYWdlcyB0aGF0IG11c3QgYmUgcmVtb3ZlZC4gSWYgYm9vbCwgd2hldGhlciB0byBmaWx0ZXIgb3V0IHJlcXVpcmUtZGV2IHBhY2thZ2VzCiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgICAgICAgICAgIGFycmF5KCdwc3ItMCcgPT4gYXJyYXkoJ05zXFxGb28nID0+IGFycmF5KCdpbnN0YWxsRGlyJykpKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VBdXRvbG9hZHMoYXJyYXkgJHBhY2thZ2VNYXAsIFBhY2thZ2VJbnRlcmZhY2UgJHJvb3RQYWNrYWdlLCAkZmlsdGVyZWREZXZQYWNrYWdlcyA9IGZhbHNlKQogICAgewogICAgICAgICRyb290UGFja2FnZU1hcCA9IGFycmF5X3NoaWZ0KCRwYWNrYWdlTWFwKTsKICAgICAgICBpZiAoaXNfYXJyYXkoJGZpbHRlcmVkRGV2UGFja2FnZXMpKSB7CiAgICAgICAgICAgICRwYWNrYWdlTWFwID0gYXJyYXlfZmlsdGVyKCRwYWNrYWdlTWFwLCBmdW5jdGlvbiAoJGl0ZW0pIHVzZSAoJGZpbHRlcmVkRGV2UGFja2FnZXMpIHsKICAgICAgICAgICAgICAgIHJldHVybiAhaW5fYXJyYXkoJGl0ZW1bMF0tPmdldE5hbWUoKSwgJGZpbHRlcmVkRGV2UGFja2FnZXMsIHRydWUpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2VpZiAoJGZpbHRlcmVkRGV2UGFja2FnZXMpIHsKICAgICAgICAgICAgJHBhY2thZ2VNYXAgPSAkdGhpcy0+ZmlsdGVyUGFja2FnZU1hcCgkcGFja2FnZU1hcCwgJHJvb3RQYWNrYWdlKTsKICAgICAgICB9CiAgICAgICAgJHNvcnRlZFBhY2thZ2VNYXAgPSAkdGhpcy0+c29ydFBhY2thZ2VNYXAoJHBhY2thZ2VNYXApOwogICAgICAgICRzb3J0ZWRQYWNrYWdlTWFwW10gPSAkcm9vdFBhY2thZ2VNYXA7CiAgICAgICAgYXJyYXlfdW5zaGlmdCgkcGFja2FnZU1hcCwgJHJvb3RQYWNrYWdlTWFwKTsKCiAgICAgICAgJHBzcjAgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHNUeXBlKCRwYWNrYWdlTWFwLCAncHNyLTAnLCAkcm9vdFBhY2thZ2UpOwogICAgICAgICRwc3I0ID0gJHRoaXMtPnBhcnNlQXV0b2xvYWRzVHlwZSgkcGFja2FnZU1hcCwgJ3Bzci00JywgJHJvb3RQYWNrYWdlKTsKICAgICAgICAkY2xhc3NtYXAgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHNUeXBlKGFycmF5X3JldmVyc2UoJHNvcnRlZFBhY2thZ2VNYXApLCAnY2xhc3NtYXAnLCAkcm9vdFBhY2thZ2UpOwogICAgICAgICRmaWxlcyA9ICR0aGlzLT5wYXJzZUF1dG9sb2Fkc1R5cGUoJHNvcnRlZFBhY2thZ2VNYXAsICdmaWxlcycsICRyb290UGFja2FnZSk7CiAgICAgICAgJGV4Y2x1ZGUgPSAkdGhpcy0+cGFyc2VBdXRvbG9hZHNUeXBlKCRzb3J0ZWRQYWNrYWdlTWFwLCAnZXhjbHVkZS1mcm9tLWNsYXNzbWFwJywgJHJvb3RQYWNrYWdlKTsKCiAgICAgICAga3Jzb3J0KCRwc3IwKTsKICAgICAgICBrcnNvcnQoJHBzcjQpOwoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICdwc3ItMCcgPT4gJHBzcjAsCiAgICAgICAgICAgICdwc3ItNCcgPT4gJHBzcjQsCiAgICAgICAgICAgICdjbGFzc21hcCcgPT4gJGNsYXNzbWFwLAogICAgICAgICAgICAnZmlsZXMnID0+ICRmaWxlcywKICAgICAgICAgICAgJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCcgPT4gJGV4Y2x1ZGUsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyBhbiBhdXRvbG9hZGVyIGJhc2VkIG9uIGFuIGF1dG9sb2FkIG1hcCByZXR1cm5lZCBieSBwYXJzZUF1dG9sb2FkcwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXkgICAgICAgJGF1dG9sb2FkcyBzZWUgcGFyc2VBdXRvbG9hZHMgcmV0dXJuIHZhbHVlCiAgICAgKiBAcmV0dXJuIENsYXNzTG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVMb2FkZXIoYXJyYXkgJGF1dG9sb2FkcywgJHZlbmRvckRpciA9IG51bGwpCiAgICB7CiAgICAgICAgJGxvYWRlciA9IG5ldyBDbGFzc0xvYWRlcigkdmVuZG9yRGlyKTsKCiAgICAgICAgaWYgKGlzc2V0KCRhdXRvbG9hZHNbJ3Bzci0wJ10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJ3Bzci0wJ10gYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkKCRuYW1lc3BhY2UsICRwYXRoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRhdXRvbG9hZHNbJ3Bzci00J10pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHNbJ3Bzci00J10gYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkUHNyNCgkbmFtZXNwYWNlLCAkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkYXV0b2xvYWRzWydjbGFzc21hcCddKSkgewogICAgICAgICAgICAkZXhjbHVkZWQgPSBudWxsOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRhdXRvbG9hZHNbJ2V4Y2x1ZGUtZnJvbS1jbGFzc21hcCddKSkgewogICAgICAgICAgICAgICAgJGV4Y2x1ZGVkID0gJGF1dG9sb2Fkc1snZXhjbHVkZS1mcm9tLWNsYXNzbWFwJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRzY2FubmVkRmlsZXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkYXV0b2xvYWRzWydjbGFzc21hcCddIGFzICRkaXIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJGxvYWRlci0+YWRkQ2xhc3NNYXAoJHRoaXMtPmdlbmVyYXRlQ2xhc3NNYXAoJGRpciwgJGV4Y2x1ZGVkLCBudWxsLCBudWxsLCBmYWxzZSwgJHNjYW5uZWRGaWxlcykpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuJGUtPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxvYWRlcjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0SW5jbHVkZVBhdGhzRmlsZShhcnJheSAkcGFja2FnZU1hcCwgRmlsZXN5c3RlbSAkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHZlbmRvclBhdGhDb2RlLCAkYXBwQmFzZURpckNvZGUpCiAgICB7CiAgICAgICAgJGluY2x1ZGVQYXRocyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTWFwIGFzICRpdGVtKSB7CiAgICAgICAgICAgIGxpc3QoJHBhY2thZ2UsICRpbnN0YWxsUGF0aCkgPSAkaXRlbTsKCiAgICAgICAgICAgIGlmIChudWxsICE9PSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkgJiYgc3RybGVuKCRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKSkgPiAwKSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbFBhdGggPSBzdWJzdHIoJGluc3RhbGxQYXRoLCAwLCAtc3RybGVuKCcvJy4kcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldEluY2x1ZGVQYXRocygpIGFzICRpbmNsdWRlUGF0aCkgewogICAgICAgICAgICAgICAgJGluY2x1ZGVQYXRoID0gdHJpbSgkaW5jbHVkZVBhdGgsICcvJyk7CiAgICAgICAgICAgICAgICAkaW5jbHVkZVBhdGhzW10gPSBlbXB0eSgkaW5zdGFsbFBhdGgpID8gJGluY2x1ZGVQYXRoIDogJGluc3RhbGxQYXRoLicvJy4kaW5jbHVkZVBhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJGluY2x1ZGVQYXRocykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaW5jbHVkZVBhdGhzQ29kZSA9ICcnOwogICAgICAgIGZvcmVhY2ggKCRpbmNsdWRlUGF0aHMgYXMgJHBhdGgpIHsKICAgICAgICAgICAgJGluY2x1ZGVQYXRoc0NvZGUgLj0gIiAgICAiIC4gJHRoaXMtPmdldFBhdGhDb2RlKCRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkcGF0aCkgLiAiLFxuIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiA8PDxFT0YKPD9waHAKCi8vIGluY2x1ZGVfcGF0aHMucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKClwkdmVuZG9yRGlyID0gJHZlbmRvclBhdGhDb2RlOwpcJGJhc2VEaXIgPSAkYXBwQmFzZURpckNvZGU7CgpyZXR1cm4gYXJyYXkoCiRpbmNsdWRlUGF0aHNDb2RlKTsKCkVPRjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0SW5jbHVkZUZpbGVzRmlsZShhcnJheSAkZmlsZXMsIEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0sICRiYXNlUGF0aCwgJHZlbmRvclBhdGgsICR2ZW5kb3JQYXRoQ29kZSwgJGFwcEJhc2VEaXJDb2RlKQogICAgewogICAgICAgICRmaWxlc0NvZGUgPSAnJzsKICAgICAgICBmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGVJZGVudGlmaWVyID0+ICRmdW5jdGlvbkZpbGUpIHsKICAgICAgICAgICAgJGZpbGVzQ29kZSAuPSAnICAgICcgLiB2YXJfZXhwb3J0KCRmaWxlSWRlbnRpZmllciwgdHJ1ZSkgLiAnID0+ICcKICAgICAgICAgICAgICAgIC4gJHRoaXMtPmdldFBhdGhDb2RlKCRmaWxlc3lzdGVtLCAkYmFzZVBhdGgsICR2ZW5kb3JQYXRoLCAkZnVuY3Rpb25GaWxlKSAuICIsXG4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkZmlsZXNDb2RlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiA8PDxFT0YKPD9waHAKCi8vIGF1dG9sb2FkX2ZpbGVzLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpcJHZlbmRvckRpciA9ICR2ZW5kb3JQYXRoQ29kZTsKXCRiYXNlRGlyID0gJGFwcEJhc2VEaXJDb2RlOwoKcmV0dXJuIGFycmF5KAokZmlsZXNDb2RlKTsKCkVPRjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGF0aENvZGUoRmlsZXN5c3RlbSAkZmlsZXN5c3RlbSwgJGJhc2VQYXRoLCAkdmVuZG9yUGF0aCwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJHBhdGgpKSB7CiAgICAgICAgICAgICRwYXRoID0gJGJhc2VQYXRoIC4gJy8nIC4gJHBhdGg7CiAgICAgICAgfQogICAgICAgICRwYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwoKICAgICAgICAkYmFzZURpciA9ICcnOwogICAgICAgIGlmIChzdHJwb3MoJHBhdGguJy8nLCAkdmVuZG9yUGF0aC4nLycpID09PSAwKSB7CiAgICAgICAgICAgICRwYXRoID0gc3Vic3RyKCRwYXRoLCBzdHJsZW4oJHZlbmRvclBhdGgpKTsKICAgICAgICAgICAgJGJhc2VEaXIgPSAnJHZlbmRvckRpcic7CgogICAgICAgICAgICBpZiAoJHBhdGggIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkYmFzZURpciAuPSAiIC4gIjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYXRoID0gJGZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJGZpbGVzeXN0ZW0tPmZpbmRTaG9ydGVzdFBhdGgoJGJhc2VQYXRoLCAkcGF0aCwgdHJ1ZSkpOwogICAgICAgICAgICBpZiAoISRmaWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRiYXNlRGlyID0gJyRiYXNlRGlyIC4gJzsKICAgICAgICAgICAgICAgICRwYXRoID0gJy8nIC4gJHBhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChzdHJwb3MoJHBhdGgsICcucGhhcicpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkYmFzZURpciA9ICIncGhhcjovLycgLiAiIC4gJGJhc2VEaXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGJhc2VEaXIgLiAoKCRwYXRoICE9PSBmYWxzZSkgPyB2YXJfZXhwb3J0KCRwYXRoLCB0cnVlKSA6ICIiKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0UGxhdGZvcm1DaGVjayhhcnJheSAkcGFja2FnZU1hcCwgYXJyYXkgJGlnbm9yZVBsYXRmb3JtUmVxcywgJGNoZWNrUGxhdGZvcm0sIGFycmF5ICRkZXZQYWNrYWdlTmFtZXMpCiAgICB7CiAgICAgICAgJGxvd2VzdFBocFZlcnNpb24gPSBCb3VuZDo6emVybygpOwogICAgICAgICRyZXF1aXJlZEV4dGVuc2lvbnMgPSBhcnJheSgpOwogICAgICAgICRleHRlbnNpb25Qcm92aWRlcnMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU1hcCBhcyAkaXRlbSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRpdGVtWzBdOwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSwgJHBhY2thZ2UtPmdldFByb3ZpZGVzKCkpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15leHQtKC4rKSR9aUQnLCAkbGluay0+Z2V0VGFyZ2V0KCksICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAkZXh0ZW5zaW9uUHJvdmlkZXJzWyRtYXRjaFsxXV1bXSA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCkgPzogbmV3IE1hdGNoQWxsQ29uc3RyYWludCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZU1hcCBhcyAkaXRlbSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRpdGVtWzBdOwogICAgICAgICAgICAvLyBza2lwIGRldiBkZXBlbmRlbmNpZXMgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIGFzIHBsYXRmb3JtLWNoZWNrIHJlYWxseSBzaG91bGQgb25seSBiZSBhIHByb2R1Y3Rpb24gc2FmZWd1YXJkCiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkZGV2UGFja2FnZU5hbWVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGxpbmstPmdldFRhcmdldCgpLCAkaWdub3JlUGxhdGZvcm1SZXFzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgncGhwJyA9PT0gJGxpbmstPmdldFRhcmdldCgpICYmICgkY29uc3RyYWludCA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50LT5nZXRMb3dlckJvdW5kKCktPmNvbXBhcmVUbygkbG93ZXN0UGhwVmVyc2lvbiwgJz4nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbG93ZXN0UGhwVmVyc2lvbiA9ICRjb25zdHJhaW50LT5nZXRMb3dlckJvdW5kKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkY2hlY2tQbGF0Zm9ybSA9PT0gdHJ1ZSAmJiBwcmVnX21hdGNoKCd7XmV4dC0oLispJH1pRCcsICRsaW5rLT5nZXRUYXJnZXQoKSwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHNraXAgZXh0ZW5zaW9uIGNoZWNrcyBpZiB0aGV5IGhhdmUgYSB2YWxpZCBwcm92aWRlci9yZXBsYWNlcgogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZXh0ZW5zaW9uUHJvdmlkZXJzWyRtYXRjaFsxXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRleHRlbnNpb25Qcm92aWRlcnNbJG1hdGNoWzFdXSBhcyAkcHJvdmlkZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJGxpbmstPmdldENvbnN0cmFpbnQoKSB8fCAkcHJvdmlkZWQtPm1hdGNoZXMoJGxpbmstPmdldENvbnN0cmFpbnQoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJG1hdGNoWzFdID09PSAnemVuZC1vcGNhY2hlJykgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hbMV0gPSAnemVuZCBvcGNhY2hlJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRleHRlbnNpb24gPSB2YXJfZXhwb3J0KCRtYXRjaFsxXSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRtYXRjaFsxXSA9PT0gJ3BjbnRsJyB8fCAkbWF0Y2hbMV0gPT09ICdyZWFkbGluZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVkRXh0ZW5zaW9uc1skZXh0ZW5zaW9uXSA9ICJQSFBfU0FQSSAhPT0gJ2NsaScgfHwgZXh0ZW5zaW9uX2xvYWRlZCgkZXh0ZW5zaW9uKSB8fCBcJG1pc3NpbmdFeHRlbnNpb25zW10gPSAkZXh0ZW5zaW9uO1xuIjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZWRFeHRlbnNpb25zWyRleHRlbnNpb25dID0gImV4dGVuc2lvbl9sb2FkZWQoJGV4dGVuc2lvbikgfHwgXCRtaXNzaW5nRXh0ZW5zaW9uc1tdID0gJGV4dGVuc2lvbjtcbiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBrc29ydCgkcmVxdWlyZWRFeHRlbnNpb25zKTsKCiAgICAgICAgJGZvcm1hdFRvUGhwVmVyc2lvbklkID0gZnVuY3Rpb24gKEJvdW5kICRib3VuZCkgewogICAgICAgICAgICBpZiAoJGJvdW5kLT5pc1plcm8oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYm91bmQtPmlzUG9zaXRpdmVJbmZpbml0eSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gOTk5OTk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2ZXJzaW9uID0gc3RyX3JlcGxhY2UoJy0nLCAnLicsICRib3VuZC0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgJGNodW5rcyA9IGFycmF5X21hcCgnaW50dmFsJywgZXhwbG9kZSgnLicsICR2ZXJzaW9uKSk7CgogICAgICAgICAgICByZXR1cm4gJGNodW5rc1swXSAqIDEwMDAwICsgJGNodW5rc1sxXSAqIDEwMCArICRjaHVua3NbMl07CiAgICAgICAgfTsKCiAgICAgICAgJGZvcm1hdFRvSHVtYW5SZWFkYWJsZSA9IGZ1bmN0aW9uIChCb3VuZCAkYm91bmQpIHsKICAgICAgICAgICAgaWYgKCRib3VuZC0+aXNaZXJvKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGJvdW5kLT5pc1Bvc2l0aXZlSW5maW5pdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDk5OTk5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdmVyc2lvbiA9IHN0cl9yZXBsYWNlKCctJywgJy4nLCAkYm91bmQtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICRjaHVua3MgPSBleHBsb2RlKCcuJywgJHZlcnNpb24pOwogICAgICAgICAgICAkY2h1bmtzID0gYXJyYXlfc2xpY2UoJGNodW5rcywgMCwgMyk7CgogICAgICAgICAgICByZXR1cm4gaW1wbG9kZSgnLicsICRjaHVua3MpOwogICAgICAgIH07CgogICAgICAgICRyZXF1aXJlZFBocCA9ICcnOwogICAgICAgICRyZXF1aXJlZFBocEVycm9yID0gJyc7CiAgICAgICAgaWYgKCEkbG93ZXN0UGhwVmVyc2lvbi0+aXNaZXJvKCkpIHsKICAgICAgICAgICAgJG9wZXJhdG9yID0gJGxvd2VzdFBocFZlcnNpb24tPmlzSW5jbHVzaXZlKCkgPyAnPj0nIDogJz4nOwogICAgICAgICAgICAkcmVxdWlyZWRQaHAgPSAnUEhQX1ZFUlNJT05fSUQgJy4kb3BlcmF0b3IuJyAnLiRmb3JtYXRUb1BocFZlcnNpb25JZCgkbG93ZXN0UGhwVmVyc2lvbik7CiAgICAgICAgICAgICRyZXF1aXJlZFBocEVycm9yID0gJyInLiRvcGVyYXRvci4nICcuJGZvcm1hdFRvSHVtYW5SZWFkYWJsZSgkbG93ZXN0UGhwVmVyc2lvbikuJyInOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXF1aXJlZFBocCkgewogICAgICAgICAgICAkcmVxdWlyZWRQaHAgPSA8PDxQSFBfQ0hFQ0sKCmlmICghKCRyZXF1aXJlZFBocCkpIHsKICAgIFwkaXNzdWVzW10gPSAnWW91ciBDb21wb3NlciBkZXBlbmRlbmNpZXMgcmVxdWlyZSBhIFBIUCB2ZXJzaW9uICRyZXF1aXJlZFBocEVycm9yLiBZb3UgYXJlIHJ1bm5pbmcgJyAuIFBIUF9WRVJTSU9OIC4gJy4nOwp9CgpQSFBfQ0hFQ0s7CiAgICAgICAgfQoKICAgICAgICAkcmVxdWlyZWRFeHRlbnNpb25zID0gaW1wbG9kZSgnJywgJHJlcXVpcmVkRXh0ZW5zaW9ucyk7CiAgICAgICAgaWYgKCcnICE9PSAkcmVxdWlyZWRFeHRlbnNpb25zKSB7CiAgICAgICAgICAgICRyZXF1aXJlZEV4dGVuc2lvbnMgPSA8PDxFWFRfQ0hFQ0tTCgpcJG1pc3NpbmdFeHRlbnNpb25zID0gYXJyYXkoKTsKJHJlcXVpcmVkRXh0ZW5zaW9ucwppZiAoXCRtaXNzaW5nRXh0ZW5zaW9ucykgewogICAgXCRpc3N1ZXNbXSA9ICdZb3VyIENvbXBvc2VyIGRlcGVuZGVuY2llcyByZXF1aXJlIHRoZSBmb2xsb3dpbmcgUEhQIGV4dGVuc2lvbnMgdG8gYmUgaW5zdGFsbGVkOiAnIC4gaW1wbG9kZSgnLCAnLCBcJG1pc3NpbmdFeHRlbnNpb25zKSAuICcuJzsKfQoKRVhUX0NIRUNLUzsKICAgICAgICB9CgogICAgICAgIGlmICghJHJlcXVpcmVkUGhwICYmICEkcmVxdWlyZWRFeHRlbnNpb25zKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDw8PFBMQVRGT1JNX0NIRUNLCjw/cGhwCgovLyBwbGF0Zm9ybV9jaGVjay5waHAgQGdlbmVyYXRlZCBieSBDb21wb3NlcgoKXCRpc3N1ZXMgPSBhcnJheSgpOwoke3JlcXVpcmVkUGhwfSR7cmVxdWlyZWRFeHRlbnNpb25zfQppZiAoXCRpc3N1ZXMpIHsKICAgIGlmICghaGVhZGVyc19zZW50KCkpIHsKICAgICAgICBoZWFkZXIoJ0hUVFAvMS4xIDUwMCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InKTsKICAgIH0KICAgIGlmICghaW5pX2dldCgnZGlzcGxheV9lcnJvcnMnKSkgewogICAgICAgIGlmIChQSFBfU0FQSSA9PT0gJ2NsaScgfHwgUEhQX1NBUEkgPT09ICdwaHBkYmcnKSB7CiAgICAgICAgICAgIGZ3cml0ZShTVERFUlIsICdDb21wb3NlciBkZXRlY3RlZCBpc3N1ZXMgaW4geW91ciBwbGF0Zm9ybTonIC4gUEhQX0VPTC5QSFBfRU9MIC4gaW1wbG9kZShQSFBfRU9MLCBcJGlzc3VlcykgLiBQSFBfRU9MLlBIUF9FT0wpOwogICAgICAgIH0gZWxzZWlmICghaGVhZGVyc19zZW50KCkpIHsKICAgICAgICAgICAgZWNobyAnQ29tcG9zZXIgZGV0ZWN0ZWQgaXNzdWVzIGluIHlvdXIgcGxhdGZvcm06JyAuIFBIUF9FT0wuUEhQX0VPTCAuIHN0cl9yZXBsYWNlKCdZb3UgYXJlIHJ1bm5pbmcgJy5QSFBfVkVSU0lPTi4nLicsICcnLCBpbXBsb2RlKFBIUF9FT0wsIFwkaXNzdWVzKSkgLiBQSFBfRU9MLlBIUF9FT0w7CiAgICAgICAgfQogICAgfQogICAgdHJpZ2dlcl9lcnJvcigKICAgICAgICAnQ29tcG9zZXIgZGV0ZWN0ZWQgaXNzdWVzIGluIHlvdXIgcGxhdGZvcm06ICcgLiBpbXBsb2RlKCcgJywgXCRpc3N1ZXMpLAogICAgICAgIEVfVVNFUl9FUlJPUgogICAgKTsKfQoKUExBVEZPUk1fQ0hFQ0s7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEF1dG9sb2FkRmlsZSgkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZSwgJHN1ZmZpeCkKICAgIHsKICAgICAgICAkbGFzdENoYXIgPSAkdmVuZG9yUGF0aFRvVGFyZ2V0RGlyQ29kZVtzdHJsZW4oJHZlbmRvclBhdGhUb1RhcmdldERpckNvZGUpIC0gMV07CiAgICAgICAgaWYgKCInIiA9PT0gJGxhc3RDaGFyIHx8ICciJyA9PT0gJGxhc3RDaGFyKSB7CiAgICAgICAgICAgICR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlID0gc3Vic3RyKCR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlLCAwLCAtMSkuJy9hdXRvbG9hZF9yZWFsLnBocCcuJGxhc3RDaGFyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR2ZW5kb3JQYXRoVG9UYXJnZXREaXJDb2RlIC49ICIgLiAnL2F1dG9sb2FkX3JlYWwucGhwJyI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gPDw8QVVUT0xPQUQKPD9waHAKCi8vIGF1dG9sb2FkLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpyZXF1aXJlX29uY2UgJHZlbmRvclBhdGhUb1RhcmdldERpckNvZGU7CgpyZXR1cm4gQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXg6OmdldExvYWRlcigpOwoKQVVUT0xPQUQ7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEF1dG9sb2FkUmVhbEZpbGUoJHVzZUNsYXNzTWFwLCAkdXNlSW5jbHVkZVBhdGgsICR0YXJnZXREaXJMb2FkZXIsICR1c2VJbmNsdWRlRmlsZXMsICR2ZW5kb3JQYXRoQ29kZSwgJGFwcEJhc2VEaXJDb2RlLCAkc3VmZml4LCAkdXNlR2xvYmFsSW5jbHVkZVBhdGgsICRwcmVwZW5kQXV0b2xvYWRlciwgJHN0YXRpY1BocFZlcnNpb24sICRjaGVja1BsYXRmb3JtKQogICAgewogICAgICAgICRmaWxlID0gPDw8SEVBREVSCjw/cGhwCgovLyBhdXRvbG9hZF9yZWFsLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpjbGFzcyBDb21wb3NlckF1dG9sb2FkZXJJbml0JHN1ZmZpeAp7CiAgICBwcml2YXRlIHN0YXRpYyBcJGxvYWRlcjsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWRDbGFzc0xvYWRlcihcJGNsYXNzKQogICAgewogICAgICAgIGlmICgnQ29tcG9zZXJcXEF1dG9sb2FkXFxDbGFzc0xvYWRlcicgPT09IFwkY2xhc3MpIHsKICAgICAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9DbGFzc0xvYWRlci5waHAnOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gXENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0TG9hZGVyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gc2VsZjo6XCRsb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OlwkbG9hZGVyOwogICAgICAgIH0KCgpIRUFERVI7CgogICAgICAgIGlmICgkY2hlY2tQbGF0Zm9ybSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnUExBVEZPUk1fQ0hFQ0snCiAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9wbGF0Zm9ybV9jaGVjay5waHAnOwoKClBMQVRGT1JNX0NIRUNLOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgLj0gPDw8Q0xBU1NMT0FERVJfSU5JVAogICAgICAgIHNwbF9hdXRvbG9hZF9yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnbG9hZENsYXNzTG9hZGVyJyksIHRydWUsICRwcmVwZW5kQXV0b2xvYWRlcik7CiAgICAgICAgc2VsZjo6XCRsb2FkZXIgPSBcJGxvYWRlciA9IG5ldyBcXENvbXBvc2VyXFxBdXRvbG9hZFxcQ2xhc3NMb2FkZXIoXFxkaXJuYW1lKFxcZGlybmFtZShfX0ZJTEVfXykpKTsKICAgICAgICBzcGxfYXV0b2xvYWRfdW5yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnbG9hZENsYXNzTG9hZGVyJykpOwoKCkNMQVNTTE9BREVSX0lOSVQ7CgogICAgICAgIGlmICgkdXNlSW5jbHVkZVBhdGgpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8J0lOQ0xVREVfUEFUSCcKICAgICAgICAkaW5jbHVkZVBhdGhzID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9pbmNsdWRlX3BhdGhzLnBocCc7CiAgICAgICAgJGluY2x1ZGVQYXRoc1tdID0gZ2V0X2luY2x1ZGVfcGF0aCgpOwogICAgICAgIHNldF9pbmNsdWRlX3BhdGgoaW1wbG9kZShQQVRIX1NFUEFSQVRPUiwgJGluY2x1ZGVQYXRocykpOwoKCklOQ0xVREVfUEFUSDsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PFNUQVRJQ19JTklUCiAgICAgICAgXCR1c2VTdGF0aWNMb2FkZXIgPSBQSFBfVkVSU0lPTl9JRCA+PSAkc3RhdGljUGhwVmVyc2lvbiAmJiAhZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykgJiYgKCFmdW5jdGlvbl9leGlzdHMoJ3plbmRfbG9hZGVyX2ZpbGVfZW5jb2RlZCcpIHx8ICF6ZW5kX2xvYWRlcl9maWxlX2VuY29kZWQoKSk7CiAgICAgICAgaWYgKFwkdXNlU3RhdGljTG9hZGVyKSB7CiAgICAgICAgICAgIHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfc3RhdGljLnBocCc7CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYyhcQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0JHN1ZmZpeDo6Z2V0SW5pdGlhbGl6ZXIoXCRsb2FkZXIpKTsKICAgICAgICB9IGVsc2UgewoKU1RBVElDX0lOSVQ7CgogICAgICAgIGlmICghJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnUFNSMDQnCiAgICAgICAgICAgICRtYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX25hbWVzcGFjZXMucGhwJzsKICAgICAgICAgICAgZm9yZWFjaCAoJG1hcCBhcyAkbmFtZXNwYWNlID0+ICRwYXRoKSB7CiAgICAgICAgICAgICAgICAkbG9hZGVyLT5zZXQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWFwID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9wc3I0LnBocCc7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+c2V0UHNyNCgkbmFtZXNwYWNlLCAkcGF0aCk7CiAgICAgICAgICAgIH0KCgpQU1IwNDsKICAgICAgICB9CgogICAgICAgIGlmICgkdXNlQ2xhc3NNYXApIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8J0NMQVNTTUFQJwogICAgICAgICAgICAkY2xhc3NNYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2NsYXNzbWFwLnBocCc7CiAgICAgICAgICAgIGlmICgkY2xhc3NNYXApIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPmFkZENsYXNzTWFwKCRjbGFzc01hcCk7CiAgICAgICAgICAgIH0KCkNMQVNTTUFQOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgLj0gIiAgICAgICAgfVxuXG4iOwoKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkgewogICAgICAgICAgICAkZmlsZSAuPSA8PDwnQ0xBU1NNQVBBVVRIT1JJVEFUSVZFJwogICAgICAgICRsb2FkZXItPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSh0cnVlKTsKCkNMQVNTTUFQQVVUSE9SSVRBVElWRTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+YXBjdSkgewogICAgICAgICAgICAkYXBjdVByZWZpeCA9IHZhcl9leHBvcnQoKCR0aGlzLT5hcGN1UHJlZml4ICE9PSBudWxsID8gJHRoaXMtPmFwY3VQcmVmaXggOiBzdWJzdHIoYmFzZTY0X2VuY29kZShtZDUodW5pcWlkKCcnLCB0cnVlKSwgdHJ1ZSkpLCAwLCAtMykpLCB0cnVlKTsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8QVBDVQogICAgICAgIFwkbG9hZGVyLT5zZXRBcGN1UHJlZml4KCRhcGN1UHJlZml4KTsKCkFQQ1U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHVzZUdsb2JhbEluY2x1ZGVQYXRoKSB7CiAgICAgICAgICAgICRmaWxlIC49IDw8PCdJTkNMVURFUEFUSCcKICAgICAgICAkbG9hZGVyLT5zZXRVc2VJbmNsdWRlUGF0aCh0cnVlKTsKCklOQ0xVREVQQVRIOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0YXJnZXREaXJMb2FkZXIpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8UkVHSVNURVJfVEFSR0VUX0RJUl9BVVRPTE9BRAogICAgICAgIHNwbF9hdXRvbG9hZF9yZWdpc3RlcihhcnJheSgnQ29tcG9zZXJBdXRvbG9hZGVySW5pdCRzdWZmaXgnLCAnYXV0b2xvYWQnKSwgdHJ1ZSwgdHJ1ZSk7CgoKUkVHSVNURVJfVEFSR0VUX0RJUl9BVVRPTE9BRDsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PFJFR0lTVEVSX0xPQURFUgogICAgICAgIFwkbG9hZGVyLT5yZWdpc3RlcigkcHJlcGVuZEF1dG9sb2FkZXIpOwoKClJFR0lTVEVSX0xPQURFUjsKCiAgICAgICAgaWYgKCR1c2VJbmNsdWRlRmlsZXMpIHsKICAgICAgICAgICAgJGZpbGUgLj0gPDw8SU5DTFVERV9GSUxFUwogICAgICAgIGlmIChcJHVzZVN0YXRpY0xvYWRlcikgewogICAgICAgICAgICBcJGluY2x1ZGVGaWxlcyA9IENvbXBvc2VyXEF1dG9sb2FkXENvbXBvc2VyU3RhdGljSW5pdCRzdWZmaXg6OlwkZmlsZXM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgXCRpbmNsdWRlRmlsZXMgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2ZpbGVzLnBocCc7CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKFwkaW5jbHVkZUZpbGVzIGFzIFwkZmlsZUlkZW50aWZpZXIgPT4gXCRmaWxlKSB7CiAgICAgICAgICAgIGNvbXBvc2VyUmVxdWlyZSRzdWZmaXgoXCRmaWxlSWRlbnRpZmllciwgXCRmaWxlKTsKICAgICAgICB9CgoKSU5DTFVERV9GSUxFUzsKICAgICAgICB9CgogICAgICAgICRmaWxlIC49IDw8PE1FVEhPRF9GT09URVIKICAgICAgICByZXR1cm4gXCRsb2FkZXI7CiAgICB9CgpNRVRIT0RfRk9PVEVSOwoKICAgICAgICAkZmlsZSAuPSAkdGFyZ2V0RGlyTG9hZGVyOwoKICAgICAgICBpZiAoJHVzZUluY2x1ZGVGaWxlcykgewogICAgICAgICAgICByZXR1cm4gJGZpbGUgLiA8PDxGT09URVIKfQoKZnVuY3Rpb24gY29tcG9zZXJSZXF1aXJlJHN1ZmZpeChcJGZpbGVJZGVudGlmaWVyLCBcJGZpbGUpCnsKICAgIGlmIChlbXB0eShcJEdMT0JBTFNbJ19fY29tcG9zZXJfYXV0b2xvYWRfZmlsZXMnXVtcJGZpbGVJZGVudGlmaWVyXSkpIHsKICAgICAgICByZXF1aXJlIFwkZmlsZTsKCiAgICAgICAgXCRHTE9CQUxTWydfX2NvbXBvc2VyX2F1dG9sb2FkX2ZpbGVzJ11bXCRmaWxlSWRlbnRpZmllcl0gPSB0cnVlOwogICAgfQp9CgpGT09URVI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGUgLiA8PDxGT09URVIKfQoKRk9PVEVSOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRTdGF0aWNGaWxlKCRzdWZmaXgsICR0YXJnZXREaXIsICR2ZW5kb3JQYXRoLCAkYmFzZVBhdGgsICYkc3RhdGljUGhwVmVyc2lvbikKICAgIHsKICAgICAgICAkc3RhdGljUGhwVmVyc2lvbiA9IDUwNjAwOwoKICAgICAgICAkZmlsZSA9IDw8PEhFQURFUgo8P3BocAoKLy8gYXV0b2xvYWRfc3RhdGljLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7CgpjbGFzcyBDb21wb3NlclN0YXRpY0luaXQkc3VmZml4CnsKCkhFQURFUjsKCiAgICAgICAgJGxvYWRlciA9IG5ldyBDbGFzc0xvYWRlcigpOwoKICAgICAgICAkbWFwID0gcmVxdWlyZSAkdGFyZ2V0RGlyIC4gJy9hdXRvbG9hZF9uYW1lc3BhY2VzLnBocCc7CiAgICAgICAgZm9yZWFjaCAoJG1hcCBhcyAkbmFtZXNwYWNlID0+ICRwYXRoKSB7CiAgICAgICAgICAgICRsb2FkZXItPnNldCgkbmFtZXNwYWNlLCAkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICAkbWFwID0gcmVxdWlyZSAkdGFyZ2V0RGlyIC4gJy9hdXRvbG9hZF9wc3I0LnBocCc7CiAgICAgICAgZm9yZWFjaCAoJG1hcCBhcyAkbmFtZXNwYWNlID0+ICRwYXRoKSB7CiAgICAgICAgICAgICRsb2FkZXItPnNldFBzcjQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJGNsYXNzTWFwID0gcmVxdWlyZSAkdGFyZ2V0RGlyIC4gJy9hdXRvbG9hZF9jbGFzc21hcC5waHAnOwogICAgICAgIGlmICgkY2xhc3NNYXApIHsKICAgICAgICAgICAgJGxvYWRlci0+YWRkQ2xhc3NNYXAoJGNsYXNzTWFwKTsKICAgICAgICB9CgogICAgICAgICRmaWxlc3lzdGVtID0gbmV3IEZpbGVzeXN0ZW0oKTsKCiAgICAgICAgJHZlbmRvclBhdGhDb2RlID0gJyA9PiAnIC4gJGZpbGVzeXN0ZW0tPmZpbmRTaG9ydGVzdFBhdGhDb2RlKHJlYWxwYXRoKCR0YXJnZXREaXIpLCAkdmVuZG9yUGF0aCwgdHJ1ZSwgdHJ1ZSkgLiAiIC4gJy8iOwogICAgICAgICR2ZW5kb3JQaGFyUGF0aENvZGUgPSAnID0+IFwncGhhcjovL1wnIC4gJyAuICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZShyZWFscGF0aCgkdGFyZ2V0RGlyKSwgJHZlbmRvclBhdGgsIHRydWUsIHRydWUpIC4gIiAuICcvIjsKICAgICAgICAkYXBwQmFzZURpckNvZGUgPSAnID0+ICcgLiAkZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aENvZGUocmVhbHBhdGgoJHRhcmdldERpciksICRiYXNlUGF0aCwgdHJ1ZSwgdHJ1ZSkgLiAiIC4gJy8iOwogICAgICAgICRhcHBCYXNlRGlyUGhhckNvZGUgPSAnID0+IFwncGhhcjovL1wnIC4gJyAuICRmaWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoQ29kZShyZWFscGF0aCgkdGFyZ2V0RGlyKSwgJGJhc2VQYXRoLCB0cnVlLCB0cnVlKSAuICIgLiAnLyI7CgogICAgICAgICRhYnNvbHV0ZVZlbmRvclBhdGhDb2RlID0gJyA9PiAnIC4gc3Vic3RyKHZhcl9leHBvcnQocnRyaW0oJHZlbmRvckRpciwgJ1xcLycpIC4gJy8nLCB0cnVlKSwgMCwgLTEpOwogICAgICAgICRhYnNvbHV0ZVZlbmRvclBoYXJQYXRoQ29kZSA9ICcgPT4gJyAuIHN1YnN0cih2YXJfZXhwb3J0KHJ0cmltKCdwaGFyOi8vJyAuICR2ZW5kb3JEaXIsICdcXC8nKSAuICcvJywgdHJ1ZSksIDAsIC0xKTsKICAgICAgICAkYWJzb2x1dGVBcHBCYXNlRGlyQ29kZSA9ICcgPT4gJyAuIHN1YnN0cih2YXJfZXhwb3J0KHJ0cmltKCRiYXNlRGlyLCAnXFwvJykgLiAnLycsIHRydWUpLCAwLCAtMSk7CiAgICAgICAgJGFic29sdXRlQXBwQmFzZURpclBoYXJDb2RlID0gJyA9PiAnIC4gc3Vic3RyKHZhcl9leHBvcnQocnRyaW0oJ3BoYXI6Ly8nIC4gJGJhc2VEaXIsICdcXC8nKSAuICcvJywgdHJ1ZSksIDAsIC0xKTsKCiAgICAgICAgJGluaXRpYWxpemVyID0gJyc7CiAgICAgICAgJHByZWZpeCA9ICJcMENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyXDAiOwogICAgICAgICRwcmVmaXhMZW4gPSBzdHJsZW4oJHByZWZpeCk7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCR0YXJnZXREaXIgLiAnL2F1dG9sb2FkX2ZpbGVzLnBocCcpKSB7CiAgICAgICAgICAgICRtYXBzID0gYXJyYXkoJ2ZpbGVzJyA9PiByZXF1aXJlICR0YXJnZXREaXIgLiAnL2F1dG9sb2FkX2ZpbGVzLnBocCcpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRtYXBzID0gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKChhcnJheSkgJGxvYWRlciBhcyAkcHJvcCA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCR2YWx1ZSAmJiAwID09PSBzdHJwb3MoJHByb3AsICRwcmVmaXgpKSB7CiAgICAgICAgICAgICAgICAkbWFwc1tzdWJzdHIoJHByb3AsICRwcmVmaXhMZW4pXSA9ICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG1hcHMgYXMgJHByb3AgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmIChjb3VudCgkdmFsdWUpID4gMzI3NjcpIHsKICAgICAgICAgICAgICAgIC8vIFN0YXRpYyBhcnJheXMgYXJlIGxpbWl0ZWQgdG8gMzI3NjcgdmFsdWVzIG9uIFBIUCA1LjYKICAgICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC82ODA1NwogICAgICAgICAgICAgICAgJHN0YXRpY1BocFZlcnNpb24gPSA3MDAwMDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdmFsdWUgPSBzdHJ0cigKICAgICAgICAgICAgICAgIHZhcl9leHBvcnQoJHZhbHVlLCB0cnVlKSwKICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICRhYnNvbHV0ZVZlbmRvclBhdGhDb2RlID0+ICR2ZW5kb3JQYXRoQ29kZSwKICAgICAgICAgICAgICAgICAgICAkYWJzb2x1dGVWZW5kb3JQaGFyUGF0aENvZGUgPT4gJHZlbmRvclBoYXJQYXRoQ29kZSwKICAgICAgICAgICAgICAgICAgICAkYWJzb2x1dGVBcHBCYXNlRGlyQ29kZSA9PiAkYXBwQmFzZURpckNvZGUsCiAgICAgICAgICAgICAgICAgICAgJGFic29sdXRlQXBwQmFzZURpclBoYXJDb2RlID0+ICRhcHBCYXNlRGlyUGhhckNvZGUsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICR2YWx1ZSA9IGx0cmltKHByZWdfcmVwbGFjZSgnL14gKi9tJywgJyAgICAkMCQwJywgJHZhbHVlKSk7CgogICAgICAgICAgICAkZmlsZSAuPSBzcHJpbnRmKCIgICAgcHVibGljIHN0YXRpYyAkJXMgPSAlcztcblxuIiwgJHByb3AsICR2YWx1ZSk7CiAgICAgICAgICAgIGlmICgnZmlsZXMnICE9PSAkcHJvcCkgewogICAgICAgICAgICAgICAgJGluaXRpYWxpemVyIC49ICIgICAgICAgICAgICBcJGxvYWRlci0+JHByb3AgPSBDb21wb3NlclN0YXRpY0luaXQkc3VmZml4OjpcJCRwcm9wO1xuIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaWxlIC4gPDw8SU5JVElBTElaRVIKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5pdGlhbGl6ZXIoQ2xhc3NMb2FkZXIgXCRsb2FkZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIFxDbG9zdXJlOjpiaW5kKGZ1bmN0aW9uICgpIHVzZSAoXCRsb2FkZXIpIHsKJGluaXRpYWxpemVyCiAgICAgICAgfSwgbnVsbCwgQ2xhc3NMb2FkZXI6OmNsYXNzKTsKICAgIH0KfQoKSU5JVElBTElaRVI7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXV0b2xvYWRzVHlwZShhcnJheSAkcGFja2FnZU1hcCwgJHR5cGUsIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSkKICAgIHsKICAgICAgICAkYXV0b2xvYWRzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VNYXAgYXMgJGl0ZW0pIHsKICAgICAgICAgICAgbGlzdCgkcGFja2FnZSwgJGluc3RhbGxQYXRoKSA9ICRpdGVtOwoKICAgICAgICAgICAgJGF1dG9sb2FkID0gJHBhY2thZ2UtPmdldEF1dG9sb2FkKCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGV2TW9kZSAmJiAkcGFja2FnZSA9PT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkYXV0b2xvYWQgPSBhcnJheV9tZXJnZV9yZWN1cnNpdmUoJGF1dG9sb2FkLCAkcGFja2FnZS0+Z2V0RGV2QXV0b2xvYWQoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNraXAgbWlzY29uZmlndXJlZCBwYWNrYWdlcwogICAgICAgICAgICBpZiAoIWlzc2V0KCRhdXRvbG9hZFskdHlwZV0pIHx8ICFpc19hcnJheSgkYXV0b2xvYWRbJHR5cGVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bGwgIT09ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKSAmJiAkcGFja2FnZSAhPT0gJHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbFBhdGggPSBzdWJzdHIoJGluc3RhbGxQYXRoLCAwLCAtc3RybGVuKCcvJy4kcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2FkWyR0eXBlXSBhcyAkbmFtZXNwYWNlID0+ICRwYXRocykgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoKGFycmF5KSAkcGF0aHMgYXMgJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKCR0eXBlID09PSAnZmlsZXMnIHx8ICR0eXBlID09PSAnY2xhc3NtYXAnIHx8ICR0eXBlID09PSAnZXhjbHVkZS1mcm9tLWNsYXNzbWFwJykgJiYgJHBhY2thZ2UtPmdldFRhcmdldERpcigpICYmICFpc19yZWFkYWJsZSgkaW5zdGFsbFBhdGguJy8nLiRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGFyZ2V0LWRpciBmcm9tIGZpbGUgcGF0aHMgb2YgdGhlIHJvb3QgcGFja2FnZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UgPT09ICRyb290UGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRhcmdldERpciA9IHN0cl9yZXBsYWNlKCdcXDxkaXJzZXBcXD4nLCAnW1xcXFwvXScsIHByZWdfcXVvdGUoc3RyX3JlcGxhY2UoYXJyYXkoJy8nLCAnXFwnKSwgJzxkaXJzZXA+JywgJHBhY2thZ2UtPmdldFRhcmdldERpcigpKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGggPSBsdHJpbShwcmVnX3JlcGxhY2UoJ3teJy4kdGFyZ2V0RGlyLid9JywgJycsIGx0cmltKCRwYXRoLCAnXFwvJykpLCAnXFwvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGFyZ2V0LWRpciBmcm9tIGZpbGUgcGF0aHMgdGhhdCBkb24ndCBoYXZlIGl0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCA9ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKSAuICcvJyAuICRwYXRoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdleGNsdWRlLWZyb20tY2xhc3NtYXAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcnN0IGVzY2FwZSB1c2VyIGlucHV0CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoID0gcHJlZ19yZXBsYWNlKCd7Lyt9JywgJy8nLCBwcmVnX3F1b3RlKHRyaW0oc3RydHIoJHBhdGgsICdcXCcsICcvJyksICcvJykpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBzdXBwb3J0IGZvciB3aWxkY2FyZHMgKiBhbmQgKioKICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGggPSBzdHJ0cigkcGF0aCwgYXJyYXkoJ1xcKlxcKicgPT4gJy4rPycsICdcXConID0+ICdbXi9dKz8nKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgc3VwcG9ydCBmb3IgdXAtbGV2ZWwgcmVsYXRpdmUgcGF0aHMKICAgICAgICAgICAgICAgICAgICAgICAgJHVwZGlyID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGggPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAne14oKD86KD86XFxcXFxcLil7MSwyfSsvKSspfScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJG1hdGNoZXMpIHVzZSAoJiR1cGRpcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWF0Y2hlc1sxXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdW5kbyBwcmVnX3F1b3RlIGZvciB0aGUgbWF0Y2hlZCBzdHJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHVwZGlyID0gc3RyX3JlcGxhY2UoJ1xcLicsICcuJywgJG1hdGNoZXNbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXRoCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkaW5zdGFsbFBhdGgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW5zdGFsbFBhdGggPSBzdHJ0cihnZXRjd2QoKSwgJ1xcJywgJy8nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc29sdmVkUGF0aCA9IHJlYWxwYXRoKCRpbnN0YWxsUGF0aCAuICcvJyAuICR1cGRpcik7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRvbG9hZHNbXSA9IHByZWdfcXVvdGUoc3RydHIoJHJlc29sdmVkUGF0aCwgJ1xcJywgJy8nKSkgLiAnLycgLiAkcGF0aCAuICcoJHwvKSc7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHJlbGF0aXZlUGF0aCA9IGVtcHR5KCRpbnN0YWxsUGF0aCkgPyAoZW1wdHkoJHBhdGgpID8gJy4nIDogJHBhdGgpIDogJGluc3RhbGxQYXRoLicvJy4kcGF0aDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0eXBlID09PSAnZmlsZXMnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhdXRvbG9hZHNbJHRoaXMtPmdldEZpbGVJZGVudGlmaWVyKCRwYWNrYWdlLCAkcGF0aCldID0gJHJlbGF0aXZlUGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gJ2NsYXNzbWFwJykgewogICAgICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRzW10gPSAkcmVsYXRpdmVQYXRoOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRhdXRvbG9hZHNbJG5hbWVzcGFjZV1bXSA9ICRyZWxhdGl2ZVBhdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkYXV0b2xvYWRzOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRGaWxlSWRlbnRpZmllcihQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gbWQ1KCRwYWNrYWdlLT5nZXROYW1lKCkgLiAnOicgLiAkcGF0aCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIG91dCBkZXYtZGVwZW5kZW5jaWVzCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICAkcGFja2FnZU1hcAogICAgICogQHBhcmFtICBSb290UGFja2FnZUludGVyZmFjZSAkcm9vdFBhY2thZ2UKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbHRlclBhY2thZ2VNYXAoYXJyYXkgJHBhY2thZ2VNYXAsIFJvb3RQYWNrYWdlSW50ZXJmYWNlICRyb290UGFja2FnZSkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRpbmNsdWRlID0gYXJyYXkoKTsKICAgICAgICAkcmVwbGFjZWRCeSA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlTWFwIGFzICRpdGVtKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJGl0ZW1bMF07CiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgJHBhY2thZ2VzWyRuYW1lXSA9ICRwYWNrYWdlOwogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkcmVwbGFjZSkgewogICAgICAgICAgICAgICAgJHJlcGxhY2VkQnlbJHJlcGxhY2UtPmdldFRhcmdldCgpXSA9ICRuYW1lOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkYWRkID0gZnVuY3Rpb24gKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpIHVzZSAoJiRhZGQsICRwYWNrYWdlcywgJiRpbmNsdWRlLCAkcmVwbGFjZWRCeSkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHRhcmdldCA9ICRsaW5rLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcmVwbGFjZWRCeVskdGFyZ2V0XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gJHJlcGxhY2VkQnlbJHRhcmdldF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRpbmNsdWRlWyR0YXJnZXRdKSkgewogICAgICAgICAgICAgICAgICAgICRpbmNsdWRlWyR0YXJnZXRdID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VzWyR0YXJnZXRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYWRkKCRwYWNrYWdlc1skdGFyZ2V0XSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICAkYWRkKCRyb290UGFja2FnZSk7CgogICAgICAgIHJldHVybiBhcnJheV9maWx0ZXIoCiAgICAgICAgICAgICRwYWNrYWdlTWFwLAogICAgICAgICAgICBmdW5jdGlvbiAoJGl0ZW0pIHVzZSAoJGluY2x1ZGUpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJGl0ZW1bMF07CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0TmFtZXMoKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkaW5jbHVkZVskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogU29ydHMgcGFja2FnZXMgYnkgZGVwZW5kZW5jeSB3ZWlnaHQKICAgICAqCiAgICAgKiBQYWNrYWdlcyBvZiBlcXVhbCB3ZWlnaHQgcmV0YWluIHRoZSBvcmlnaW5hbCBvcmRlcgogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXkgJHBhY2thZ2VNYXAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNvcnRQYWNrYWdlTWFwKGFycmF5ICRwYWNrYWdlTWFwKQogICAgewogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJHBhdGhzID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VNYXAgYXMgJGl0ZW0pIHsKICAgICAgICAgICAgbGlzdCgkcGFja2FnZSwgJHBhdGgpID0gJGl0ZW07CiAgICAgICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAgICAgJHBhY2thZ2VzWyRuYW1lXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAkcGF0aHNbJG5hbWVdID0gJHBhdGg7CiAgICAgICAgfQoKICAgICAgICAkc29ydGVkUGFja2FnZXMgPSBQYWNrYWdlU29ydGVyOjpzb3J0UGFja2FnZXMoJHBhY2thZ2VzKTsKCiAgICAgICAgJHNvcnRlZFBhY2thZ2VNYXAgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkc29ydGVkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICAkc29ydGVkUGFja2FnZU1hcFtdID0gYXJyYXkoJHBhY2thZ2VzWyRuYW1lXSwgJHBhdGhzWyRuYW1lXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHNvcnRlZFBhY2thZ2VNYXA7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7CgovKioKICogQ2xhc3NMb2FkZXIgaW1wbGVtZW50cyBhIFBTUi0wLCBQU1ItNCBhbmQgY2xhc3NtYXAgY2xhc3MgbG9hZGVyLgogKgogKiAgICAgJGxvYWRlciA9IG5ldyBcQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXIoKTsKICoKICogICAgIC8vIHJlZ2lzdGVyIGNsYXNzZXMgd2l0aCBuYW1lc3BhY2VzCiAqICAgICAkbG9hZGVyLT5hZGQoJ1N5bWZvbnlcQ29tcG9uZW50JywgX19ESVJfXy4nL2NvbXBvbmVudCcpOwogKiAgICAgJGxvYWRlci0+YWRkKCdTeW1mb255JywgICAgICAgICAgIF9fRElSX18uJy9mcmFtZXdvcmsnKTsKICoKICogICAgIC8vIGFjdGl2YXRlIHRoZSBhdXRvbG9hZGVyCiAqICAgICAkbG9hZGVyLT5yZWdpc3RlcigpOwogKgogKiAgICAgLy8gdG8gZW5hYmxlIHNlYXJjaGluZyB0aGUgaW5jbHVkZSBwYXRoIChlZy4gZm9yIFBFQVIgcGFja2FnZXMpCiAqICAgICAkbG9hZGVyLT5zZXRVc2VJbmNsdWRlUGF0aCh0cnVlKTsKICoKICogSW4gdGhpcyBleGFtcGxlLCBpZiB5b3UgdHJ5IHRvIHVzZSBhIGNsYXNzIGluIHRoZSBTeW1mb255XENvbXBvbmVudAogKiBuYW1lc3BhY2Ugb3Igb25lIG9mIGl0cyBjaGlsZHJlbiAoU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZSBmb3IgaW5zdGFuY2UpLAogKiB0aGUgYXV0b2xvYWRlciB3aWxsIGZpcnN0IGxvb2sgZm9yIHRoZSBjbGFzcyB1bmRlciB0aGUgY29tcG9uZW50LwogKiBkaXJlY3RvcnksIGFuZCBpdCB3aWxsIHRoZW4gZmFsbGJhY2sgdG8gdGhlIGZyYW1ld29yay8gZGlyZWN0b3J5IGlmIG5vdAogKiBmb3VuZCBiZWZvcmUgZ2l2aW5nIHVwLgogKgogKiBUaGlzIGNsYXNzIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlIFN5bWZvbnkgVW5pdmVyc2FsQ2xhc3NMb2FkZXIuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBzZWUgICAgaHR0cHM6Ly93d3cucGhwLWZpZy5vcmcvcHNyL3Bzci0wLwogKiBAc2VlICAgIGh0dHBzOi8vd3d3LnBocC1maWcub3JnL3Bzci9wc3ItNC8KICovCmNsYXNzIENsYXNzTG9hZGVyCnsKICAgIHByaXZhdGUgJHZlbmRvckRpcjsKCiAgICAvLyBQU1ItNAogICAgcHJpdmF0ZSAkcHJlZml4TGVuZ3Roc1BzcjQgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkcHJlZml4RGlyc1BzcjQgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyNCA9IGFycmF5KCk7CgogICAgLy8gUFNSLTAKICAgIHByaXZhdGUgJHByZWZpeGVzUHNyMCA9IGFycmF5KCk7CiAgICBwcml2YXRlICRmYWxsYmFja0RpcnNQc3IwID0gYXJyYXkoKTsKCiAgICBwcml2YXRlICR1c2VJbmNsdWRlUGF0aCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkY2xhc3NNYXAgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlID0gZmFsc2U7CiAgICBwcml2YXRlICRtaXNzaW5nQ2xhc3NlcyA9IGFycmF5KCk7CiAgICBwcml2YXRlICRhcGN1UHJlZml4OwoKICAgIHByaXZhdGUgc3RhdGljICRyZWdpc3RlcmVkTG9hZGVycyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2ZW5kb3JEaXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT52ZW5kb3JEaXIgPSAkdmVuZG9yRGlyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXhlcygpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+cHJlZml4ZXNQc3IwKSkgewogICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfdmFsdWVzKCR0aGlzLT5wcmVmaXhlc1BzcjApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXhlc1BzcjQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJlZml4RGlyc1BzcjQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEZhbGxiYWNrRGlycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGYWxsYmFja0RpcnNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENsYXNzTWFwKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNsYXNzTWFwOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRjbGFzc01hcCBDbGFzcyB0byBmaWxlbmFtZSBtYXAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENsYXNzTWFwKGFycmF5ICRjbGFzc01hcCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNsYXNzTWFwKSB7CiAgICAgICAgICAgICR0aGlzLT5jbGFzc01hcCA9IGFycmF5X21lcmdlKCR0aGlzLT5jbGFzc01hcCwgJGNsYXNzTWFwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Y2xhc3NNYXAgPSAkY2xhc3NNYXA7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwgZWl0aGVyCiAgICAgKiBhcHBlbmRpbmcgb3IgcHJlcGVuZGluZyB0byB0aGUgb25lcyBwcmV2aW91c2x5IHNldCBmb3IgdGhpcyBwcmVmaXguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkcHJlZml4ICBUaGUgcHJlZml4CiAgICAgKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRwYXRocyAgIFRoZSBQU1ItMCByb290IGRpcmVjdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRwcmVwZW5kIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlyZWN0b3JpZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRmaXJzdCA9ICRwcmVmaXhbMF07CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0pKSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XQogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdLAogICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLCBlaXRoZXIKICAgICAqIGFwcGVuZGluZyBvciBwcmVwZW5kaW5nIHRvIHRoZSBvbmVzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIG5hbWVzcGFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICRwcmVmaXggIFRoZSBwcmVmaXgvbmFtZXNwYWNlLCB3aXRoIHRyYWlsaW5nICdcXCcKICAgICAqIEBwYXJhbSBhcnJheXxzdHJpbmcgJHBhdGhzICAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBkaXJlY3RvcmllcwogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHNyNCgkcHJlZml4LCAkcGF0aHMsICRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGRpcmVjdG9yaWVzIGZvciB0aGUgcm9vdCBuYW1lc3BhY2UuCiAgICAgICAgICAgIGlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0ID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQsCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoIWlzc2V0KCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSkpIHsKICAgICAgICAgICAgLy8gUmVnaXN0ZXIgZGlyZWN0b3JpZXMgZm9yIGEgbmV3IG5hbWVzcGFjZS4KICAgICAgICAgICAgJGxlbmd0aCA9IHN0cmxlbigkcHJlZml4KTsKICAgICAgICAgICAgaWYgKCdcXCcgIT09ICRwcmVmaXhbJGxlbmd0aCAtIDFdKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiQSBub24tZW1wdHkgUFNSLTQgcHJlZml4IG11c3QgZW5kIHdpdGggYSBuYW1lc3BhY2Ugc2VwYXJhdG9yLiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhMZW5ndGhzUHNyNFskcHJlZml4WzBdXVskcHJlZml4XSA9ICRsZW5ndGg7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZWlmICgkcHJlcGVuZCkgewogICAgICAgICAgICAvLyBQcmVwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzLAogICAgICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdCiAgICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQXBwZW5kIGRpcmVjdG9yaWVzIGZvciBhbiBhbHJlYWR5IHJlZ2lzdGVyZWQgbmFtZXNwYWNlLgogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XSwKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi0wIGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIHByZWZpeCwKICAgICAqIHJlcGxhY2luZyBhbnkgb3RoZXJzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIHByZWZpeC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICRwcmVmaXggVGhlIHByZWZpeAogICAgICogQHBhcmFtIGFycmF5fHN0cmluZyAkcGF0aHMgIFRoZSBQU1ItMCBiYXNlIGRpcmVjdG9yaWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJHByZWZpeFswXV1bJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBzZXQgb2YgUFNSLTQgZGlyZWN0b3JpZXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLAogICAgICogcmVwbGFjaW5nIGFueSBvdGhlcnMgcHJldmlvdXNseSBzZXQgZm9yIHRoaXMgbmFtZXNwYWNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHByZWZpeCBUaGUgcHJlZml4L25hbWVzcGFjZSwgd2l0aCB0cmFpbGluZyAnXFwnCiAgICAgKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRwYXRocyAgVGhlIFBTUi00IGJhc2UgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBzcjQoJHByZWZpeCwgJHBhdGhzKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNCA9IChhcnJheSkgJHBhdGhzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHByZWZpeCk7CiAgICAgICAgICAgIGlmICgnXFwnICE9PSAkcHJlZml4WyRsZW5ndGggLSAxXSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIkEgbm9uLWVtcHR5IFBTUi00IHByZWZpeCBtdXN0IGVuZCB3aXRoIGEgbmFtZXNwYWNlIHNlcGFyYXRvci4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJHByZWZpeFswXV1bJHByZWZpeF0gPSAkbGVuZ3RoOwogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBvbiBzZWFyY2hpbmcgdGhlIGluY2x1ZGUgcGF0aCBmb3IgY2xhc3MgZmlsZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHVzZUluY2x1ZGVQYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVc2VJbmNsdWRlUGF0aCgkdXNlSW5jbHVkZVBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPnVzZUluY2x1ZGVQYXRoID0gJHVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogQ2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgdGhlIGF1dG9sb2FkZXIgdXNlcyB0aGUgaW5jbHVkZSBwYXRoIHRvIGNoZWNrCiAgICAgKiBmb3IgY2xhc3Nlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzZUluY2x1ZGVQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVzZUluY2x1ZGVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogVHVybnMgb2ZmIHNlYXJjaGluZyB0aGUgcHJlZml4IGFuZCBmYWxsYmFjayBkaXJlY3RvcmllcyBmb3IgY2xhc3NlcwogICAgICogdGhhdCBoYXZlIG5vdCBiZWVuIHJlZ2lzdGVyZWQgd2l0aCB0aGUgY2xhc3MgbWFwLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjbGFzc01hcEF1dGhvcml0YXRpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY2xhc3NNYXBBdXRob3JpdGF0aXZlKQogICAgewogICAgICAgICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmUgPSAkY2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogU2hvdWxkIGNsYXNzIGxvb2t1cCBmYWlsIGlmIG5vdCBmb3VuZCBpbiB0aGUgY3VycmVudCBjbGFzcyBtYXA/CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0NsYXNzTWFwQXV0aG9yaXRhdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBUEN1IHByZWZpeCB0byB1c2UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMsIGlmIHRoZSBleHRlbnNpb24gaXMgZW5hYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGFwY3VQcmVmaXgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFwY3VQcmVmaXgoJGFwY3VQcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPmFwY3VQcmVmaXggPSBmdW5jdGlvbl9leGlzdHMoJ2FwY3VfZmV0Y2gnKSAmJiBmaWx0ZXJfdmFyKGluaV9nZXQoJ2FwYy5lbmFibGVkJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSA/ICRhcGN1UHJlZml4IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBBUEN1IHByZWZpeCBpbiB1c2UsIG9yIG51bGwgaWYgQVBDdSBjYWNoaW5nIGlzIG5vdCBlbmFibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFwY3VQcmVmaXgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXBjdVByZWZpeDsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyB0aGlzIGluc3RhbmNlIGFzIGFuIGF1dG9sb2FkZXIuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHByZXBlbmQgV2hldGhlciB0byBwcmVwZW5kIHRoZSBhdXRvbG9hZGVyIG9yIG5vdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoJHByZXBlbmQgPSBmYWxzZSkKICAgIHsKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSwgdHJ1ZSwgJHByZXBlbmQpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnZlbmRvckRpcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzID0gYXJyYXkoJHRoaXMtPnZlbmRvckRpciA9PiAkdGhpcykgKyBzZWxmOjokcmVnaXN0ZXJlZExvYWRlcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdW5zZXQoc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdKTsKICAgICAgICAgICAgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzWyR0aGlzLT52ZW5kb3JEaXJdID0gJHRoaXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVW5yZWdpc3RlcnMgdGhpcyBpbnN0YW5jZSBhcyBhbiBhdXRvbG9hZGVyLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5yZWdpc3RlcigpCiAgICB7CiAgICAgICAgc3BsX2F1dG9sb2FkX3VucmVnaXN0ZXIoYXJyYXkoJHRoaXMsICdsb2FkQ2xhc3MnKSk7CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+dmVuZG9yRGlyKSB7CiAgICAgICAgICAgIHVuc2V0KHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyc1skdGhpcy0+dmVuZG9yRGlyXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG9hZHMgdGhlIGdpdmVuIGNsYXNzIG9yIGludGVyZmFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAkY2xhc3MgVGhlIG5hbWUgb2YgdGhlIGNsYXNzCiAgICAgKiBAcmV0dXJuIGJvb2x8bnVsbCBUcnVlIGlmIGxvYWRlZCwgbnVsbCBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvYWRDbGFzcygkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCRmaWxlID0gJHRoaXMtPmZpbmRGaWxlKCRjbGFzcykpIHsKICAgICAgICAgICAgaW5jbHVkZUZpbGUoJGZpbGUpOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgdGhlIHBhdGggdG8gdGhlIGZpbGUgd2hlcmUgdGhlIGNsYXNzIGlzIGRlZmluZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2xhc3MgVGhlIG5hbWUgb2YgdGhlIGNsYXNzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UgVGhlIHBhdGggaWYgZm91bmQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZEZpbGUoJGNsYXNzKQogICAgewogICAgICAgIC8vIGNsYXNzIG1hcCBsb29rdXAKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmNsYXNzTWFwWyRjbGFzc10pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y2xhc3NNYXBbJGNsYXNzXTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5jbGFzc01hcEF1dGhvcml0YXRpdmUgfHwgaXNzZXQoJHRoaXMtPm1pc3NpbmdDbGFzc2VzWyRjbGFzc10pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5hcGN1UHJlZml4KSB7CiAgICAgICAgICAgICRmaWxlID0gYXBjdV9mZXRjaCgkdGhpcy0+YXBjdVByZWZpeC4kY2xhc3MsICRoaXQpOwogICAgICAgICAgICBpZiAoJGhpdCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZmlsZSA9ICR0aGlzLT5maW5kRmlsZVdpdGhFeHRlbnNpb24oJGNsYXNzLCAnLnBocCcpOwoKICAgICAgICAvLyBTZWFyY2ggZm9yIEhhY2sgZmlsZXMgaWYgd2UgYXJlIHJ1bm5pbmcgb24gSEhWTQogICAgICAgIGlmIChmYWxzZSA9PT0gJGZpbGUgJiYgZGVmaW5lZCgnSEhWTV9WRVJTSU9OJykpIHsKICAgICAgICAgICAgJGZpbGUgPSAkdGhpcy0+ZmluZEZpbGVXaXRoRXh0ZW5zaW9uKCRjbGFzcywgJy5oaCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5hcGN1UHJlZml4KSB7CiAgICAgICAgICAgIGFwY3VfYWRkKCR0aGlzLT5hcGN1UHJlZml4LiRjbGFzcywgJGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkZmlsZSkgewogICAgICAgICAgICAvLyBSZW1lbWJlciB0aGF0IHRoaXMgY2xhc3MgZG9lcyBub3QgZXhpc3QuCiAgICAgICAgICAgICR0aGlzLT5taXNzaW5nQ2xhc3Nlc1skY2xhc3NdID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnRseSByZWdpc3RlcmVkIGxvYWRlcnMgaW5kZXhlZCBieSB0aGVpciBjb3JyZXNwb25kaW5nIHZlbmRvciBkaXJlY3Rvcmllcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGZbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFJlZ2lzdGVyZWRMb2FkZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZEZpbGVXaXRoRXh0ZW5zaW9uKCRjbGFzcywgJGV4dCkKICAgIHsKICAgICAgICAvLyBQU1ItNCBsb29rdXAKICAgICAgICAkbG9naWNhbFBhdGhQc3I0ID0gc3RydHIoJGNsYXNzLCAnXFwnLCBESVJFQ1RPUllfU0VQQVJBVE9SKSAuICRleHQ7CgogICAgICAgICRmaXJzdCA9ICRjbGFzc1swXTsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnByZWZpeExlbmd0aHNQc3I0WyRmaXJzdF0pKSB7CiAgICAgICAgICAgICRzdWJQYXRoID0gJGNsYXNzOwogICAgICAgICAgICB3aGlsZSAoZmFsc2UgIT09ICRsYXN0UG9zID0gc3RycnBvcygkc3ViUGF0aCwgJ1xcJykpIHsKICAgICAgICAgICAgICAgICRzdWJQYXRoID0gc3Vic3RyKCRzdWJQYXRoLCAwLCAkbGFzdFBvcyk7CiAgICAgICAgICAgICAgICAkc2VhcmNoID0gJHN1YlBhdGggLiAnXFwnOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcmVmaXhEaXJzUHNyNFskc2VhcmNoXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGF0aEVuZCA9IERJUkVDVE9SWV9TRVBBUkFUT1IgLiBzdWJzdHIoJGxvZ2ljYWxQYXRoUHNyNCwgJGxhc3RQb3MgKyAxKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHNlYXJjaF0gYXMgJGRpcikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSAkZGlyIC4gJHBhdGhFbmQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBTUi00IGZhbGxiYWNrIGRpcnMKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNCBhcyAkZGlyKSB7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGxvZ2ljYWxQYXRoUHNyNCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTAgbG9va3VwCiAgICAgICAgaWYgKGZhbHNlICE9PSAkcG9zID0gc3RycnBvcygkY2xhc3MsICdcXCcpKSB7CiAgICAgICAgICAgIC8vIG5hbWVzcGFjZWQgY2xhc3MgbmFtZQogICAgICAgICAgICAkbG9naWNhbFBhdGhQc3IwID0gc3Vic3RyKCRsb2dpY2FsUGF0aFBzcjQsIDAsICRwb3MgKyAxKQogICAgICAgICAgICAgICAgLiBzdHJ0cihzdWJzdHIoJGxvZ2ljYWxQYXRoUHNyNCwgJHBvcyArIDEpLCAnXycsIERJUkVDVE9SWV9TRVBBUkFUT1IpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFBFQVItbGlrZSBjbGFzcyBuYW1lCiAgICAgICAgICAgICRsb2dpY2FsUGF0aFBzcjAgPSBzdHJ0cigkY2xhc3MsICdfJywgRElSRUNUT1JZX1NFUEFSQVRPUikgLiAkZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdIGFzICRwcmVmaXggPT4gJGRpcnMpIHsKICAgICAgICAgICAgICAgIGlmICgwID09PSBzdHJwb3MoJGNsYXNzLCAkcHJlZml4KSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkbG9naWNhbFBhdGhQc3IwKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBQU1ItMCBmYWxsYmFjayBkaXJzCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAgYXMgJGRpcikgewogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSAkZGlyIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRsb2dpY2FsUGF0aFBzcjApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBTUi0wIGluY2x1ZGUgcGF0aHMuCiAgICAgICAgaWYgKCR0aGlzLT51c2VJbmNsdWRlUGF0aCAmJiAkZmlsZSA9IHN0cmVhbV9yZXNvbHZlX2luY2x1ZGVfcGF0aCgkbG9naWNhbFBhdGhQc3IwKSkgewogICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KCi8qKgogKiBTY29wZSBpc29sYXRlZCBpbmNsdWRlLgogKgogKiBQcmV2ZW50cyBhY2Nlc3MgdG8gJHRoaXMvc2VsZiBmcm9tIGluY2x1ZGVkIGZpbGVzLgogKi8KZnVuY3Rpb24gaW5jbHVkZUZpbGUoJGZpbGUpCnsKICAgIGluY2x1ZGUgJGZpbGU7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgovKgogKiBUaGlzIGZpbGUgaXMgY29waWVkIGZyb20gdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQXV0b2xvYWQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEZpbmRlcjsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwoKLyoqCiAqIENsYXNzTWFwR2VuZXJhdG9yCiAqCiAqIEBhdXRob3IgR3l1bGEgU2FsbGFpIDxzYWxsYTAxNkBnbWFpbC5jb20+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIENsYXNzTWFwR2VuZXJhdG9yCnsKICAgIC8qKgogICAgICogR2VuZXJhdGUgYSBjbGFzcyBtYXAgZmlsZQogICAgICoKICAgICAqIEBwYXJhbSBcVHJhdmVyc2FibGUgJGRpcnMgRGlyZWN0b3JpZXMgb3IgYSBzaW5nbGUgcGF0aCB0byBzZWFyY2ggaW4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGZpbGUgVGhlIG5hbWUgb2YgdGhlIGNsYXNzIG1hcCBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZHVtcCgkZGlycywgJGZpbGUpCiAgICB7CiAgICAgICAgJG1hcHMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkZGlycyBhcyAkZGlyKSB7CiAgICAgICAgICAgICRtYXBzID0gYXJyYXlfbWVyZ2UoJG1hcHMsIHN0YXRpYzo6Y3JlYXRlTWFwKCRkaXIpKTsKICAgICAgICB9CgogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRmaWxlLCBzcHJpbnRmKCc8P3BocCByZXR1cm4gJXM7JywgdmFyX2V4cG9ydCgkbWFwcywgdHJ1ZSkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgZmlsZXMgaW4gdGhlIGdpdmVuIGRpcmVjdG9yeSBzZWFyY2hpbmcgZm9yIGNsYXNzZXMKICAgICAqCiAgICAgKiBAcGFyYW0gXEl0ZXJhdG9yfHN0cmluZyAkcGF0aCAgICAgICAgIFRoZSBwYXRoIHRvIHNlYXJjaCBpbiBvciBhbiBpdGVyYXRvcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGV4Y2x1ZGVkICAgICBSZWdleCB0aGF0IG1hdGNoZXMgZmlsZSBwYXRocyB0byBiZSBleGNsdWRlZCBmcm9tIHRoZSBjbGFzc21hcAogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAgJGlvICAgICAgICAgICBJTyBvYmplY3QKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRuYW1lc3BhY2UgICAgT3B0aW9uYWwgbmFtZXNwYWNlIHByZWZpeCB0byBmaWx0ZXIgYnkKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRhdXRvbG9hZFR5cGUgcHNyLTB8cHNyLTQgT3B0aW9uYWwgYXV0b2xvYWQgc3RhbmRhcmQgdG8gdXNlIG1hcHBpbmcgcnVsZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIFdoZW4gdGhlIHBhdGggaXMgbmVpdGhlciBhbiBleGlzdGluZyBmaWxlIG5vciBkaXJlY3RvcnkKICAgICAqIEByZXR1cm4gYXJyYXkgICAgICAgICAgICAgQSBjbGFzcyBtYXAgYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVNYXAoJHBhdGgsICRleGNsdWRlZCA9IG51bGwsIElPSW50ZXJmYWNlICRpbyA9IG51bGwsICRuYW1lc3BhY2UgPSBudWxsLCAkYXV0b2xvYWRUeXBlID0gbnVsbCwgJiRzY2FubmVkRmlsZXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRiYXNlUGF0aCA9ICRwYXRoOwogICAgICAgIGlmIChpc19zdHJpbmcoJHBhdGgpKSB7CiAgICAgICAgICAgIGlmIChpc19maWxlKCRwYXRoKSkgewogICAgICAgICAgICAgICAgJHBhdGggPSBhcnJheShuZXcgXFNwbEZpbGVJbmZvKCRwYXRoKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJHBhdGgpIHx8IHN0cnBvcygkcGF0aCwgJyonKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gRmluZGVyOjpjcmVhdGUoKS0+ZmlsZXMoKS0+Zm9sbG93TGlua3MoKS0+bmFtZSgnL1wuKHBocHxpbmN8aGgpJC8nKS0+aW4oJHBhdGgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdDb3VsZCBub3Qgc2NhbiBmb3IgY2xhc3NlcyBpbnNpZGUgIicuJHBhdGguCiAgICAgICAgICAgICAgICAgICAgJyIgd2hpY2ggZG9lcyBub3QgYXBwZWFyIHRvIGJlIGEgZmlsZSBub3IgYSBmb2xkZXInCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKG51bGwgIT09ICRhdXRvbG9hZFR5cGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdQYXRoIG11c3QgYmUgYSBzdHJpbmcgd2hlbiBzcGVjaWZ5aW5nIGFuIGF1dG9sb2FkIHR5cGUnKTsKICAgICAgICB9CgogICAgICAgICRtYXAgPSBhcnJheSgpOwogICAgICAgICRmaWxlc3lzdGVtID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAkY3dkID0gcmVhbHBhdGgoZ2V0Y3dkKCkpOwoKICAgICAgICBmb3JlYWNoICgkcGF0aCBhcyAkZmlsZSkgewogICAgICAgICAgICAkZmlsZVBhdGggPSAkZmlsZS0+Z2V0UGF0aG5hbWUoKTsKICAgICAgICAgICAgaWYgKCFpbl9hcnJheShwYXRoaW5mbygkZmlsZVBhdGgsIFBBVEhJTkZPX0VYVEVOU0lPTiksIGFycmF5KCdwaHAnLCAnaW5jJywgJ2hoJykpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkZmlsZXN5c3RlbS0+aXNBYnNvbHV0ZVBhdGgoJGZpbGVQYXRoKSkgewogICAgICAgICAgICAgICAgJGZpbGVQYXRoID0gJGN3ZCAuICcvJyAuICRmaWxlUGF0aDsKICAgICAgICAgICAgICAgICRmaWxlUGF0aCA9ICRmaWxlc3lzdGVtLT5ub3JtYWxpemVQYXRoKCRmaWxlUGF0aCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZmlsZVBhdGggPSBwcmVnX3JlcGxhY2UoJ3tbXFxcXC9dezIsfX0nLCAnLycsICRmaWxlUGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZWFsUGF0aCA9IHJlYWxwYXRoKCRmaWxlUGF0aCk7CgogICAgICAgICAgICAvLyBpZiBhIGxpc3Qgb2Ygc2Nhbm5lZCBmaWxlcyBpcyBnaXZlbiwgYXZvaWQgc2Nhbm5pbmcgdHdpY2UgdGhlIHNhbWUgZmlsZSB0byBzYXZlIGN5Y2xlcyBhbmQgYXZvaWQgZ2VuZXJhdGluZyB3YXJuaW5ncwogICAgICAgICAgICAvLyBpbiBjYXNlIGEgUFNSLTAvNCBkZWNsYXJhdGlvbiBmb2xsb3dzIGFub3RoZXIgbW9yZSBzcGVjaWZpYyBvbmUsIG9yIGEgY2xhc3NtYXAgZGVjbGFyYXRpb24sIHdoaWNoIGNvdmVyZWQgdGhpcyBmaWxlIGFscmVhZHkKICAgICAgICAgICAgaWYgKGlzc2V0KCRzY2FubmVkRmlsZXNbJHJlYWxQYXRoXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayB0aGUgcmVhbHBhdGggb2YgdGhlIGZpbGUgYWdhaW5zdCB0aGUgZXhjbHVkZWQgcGF0aHMgYXMgdGhlIHBhdGggbWlnaHQgYmUgYSBzeW1saW5rIGFuZCB0aGUgZXhjbHVkZWQgcGF0aCBpcyByZWFscGF0aCdkIHNvIHN5bWxpbmsgYXJlIHJlc29sdmVkCiAgICAgICAgICAgIGlmICgkZXhjbHVkZWQgJiYgcHJlZ19tYXRjaCgkZXhjbHVkZWQsIHN0cnRyKCRyZWFsUGF0aCwgJ1xcJywgJy8nKSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIG5vbi1yZWFscGF0aCBvZiBmaWxlIGZvciBkaXJlY3RvcmllcyBzeW1saW5rIGluIHByb2plY3QgZGlyCiAgICAgICAgICAgIGlmICgkZXhjbHVkZWQgJiYgcHJlZ19tYXRjaCgkZXhjbHVkZWQsIHN0cnRyKCRmaWxlUGF0aCwgJ1xcJywgJy8nKSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2xhc3NlcyA9IHNlbGY6OmZpbmRDbGFzc2VzKCRmaWxlUGF0aCk7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAkYXV0b2xvYWRUeXBlKSB7CiAgICAgICAgICAgICAgICAkY2xhc3NlcyA9IHNlbGY6OmZpbHRlckJ5TmFtZXNwYWNlKCRjbGFzc2VzLCAkZmlsZVBhdGgsICRuYW1lc3BhY2UsICRhdXRvbG9hZFR5cGUsICRiYXNlUGF0aCwgJGlvKTsKCiAgICAgICAgICAgICAgICAvLyBpZiBubyB2YWxpZCBjbGFzcyB3YXMgZm91bmQgaW4gdGhlIGZpbGUgdGhlbiB3ZSBkbyBub3QgbWFyayBpdCBhcyBzY2FubmVkIGFzIGl0IG1pZ2h0IHN0aWxsIGJlIG1hdGNoZWQgYnkgYW5vdGhlciBydWxlIGxhdGVyCiAgICAgICAgICAgICAgICBpZiAoJGNsYXNzZXMpIHsKICAgICAgICAgICAgICAgICAgICAkc2Nhbm5lZEZpbGVzWyRyZWFsUGF0aF0gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gY2xhc3NtYXAgYXV0b2xvYWQgcnVsZXMgYWx3YXlzIGNvbGxlY3QgYWxsIGNsYXNzZXMgc28gZm9yIHRoZXNlIHdlIGRlZmluaXRlbHkgZG8gbm90IHdhbnQgdG8gc2NhbiBhZ2FpbgogICAgICAgICAgICAgICAgJHNjYW5uZWRGaWxlc1skcmVhbFBhdGhdID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJGNsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgICAgICAvLyBza2lwIGNsYXNzZXMgbm90IHdpdGhpbiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHByZWZpeAogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICRhdXRvbG9hZFR5cGUgJiYgbnVsbCAhPT0gJG5hbWVzcGFjZSAmJiAnJyAhPT0gJG5hbWVzcGFjZSAmJiAwICE9PSBzdHJwb3MoJGNsYXNzLCAkbmFtZXNwYWNlKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJG1hcFskY2xhc3NdKSkgewogICAgICAgICAgICAgICAgICAgICRtYXBbJGNsYXNzXSA9ICRmaWxlUGF0aDsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkaW8gJiYgJG1hcFskY2xhc3NdICE9PSAkZmlsZVBhdGggJiYgIXByZWdfbWF0Y2goJ3svKHRlc3R8Zml4dHVyZXxleGFtcGxlfHN0dWIpcz8vfWknLCBzdHJ0cigkbWFwWyRjbGFzc10uJyAnLiRmaWxlUGF0aCwgJ1xcJywgJy8nKSkpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICc8d2FybmluZz5XYXJuaW5nOiBBbWJpZ3VvdXMgY2xhc3MgcmVzb2x1dGlvbiwgIicuJGNsYXNzLiciJy4KICAgICAgICAgICAgICAgICAgICAgICAgJyB3YXMgZm91bmQgaW4gYm90aCAiJy4kbWFwWyRjbGFzc10uJyIgYW5kICInLiRmaWxlUGF0aC4nIiwgdGhlIGZpcnN0IHdpbGwgYmUgdXNlZC48L3dhcm5pbmc+JwogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWFwOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlIGNsYXNzZXMgd2hpY2ggY291bGQgbm90IGhhdmUgYmVlbiBsb2FkZWQgYnkgbmFtZXNwYWNlIGF1dG9sb2FkZXJzCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAkY2xhc3NlcyAgICAgICBmb3VuZCBjbGFzc2VzIGluIGdpdmVuIGZpbGUKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgJGZpbGVQYXRoICAgICAgY3VycmVudCBmaWxlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRiYXNlTmFtZXNwYWNlIHByZWZpeCBvZiBnaXZlbiBhdXRvbG9hZCBtYXBwaW5nCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRuYW1lc3BhY2VUeXBlIHBzci0wfHBzci00CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICRiYXNlUGF0aCAgICAgIHJvb3QgZGlyZWN0b3J5IG9mIGdpdmVuIGF1dG9sb2FkIG1hcHBpbmcKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgJGlvICAgICAgICAgICAgSU8gb2JqZWN0CiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgIHZhbGlkIGNsYXNzZXMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZmlsdGVyQnlOYW1lc3BhY2UoJGNsYXNzZXMsICRmaWxlUGF0aCwgJGJhc2VOYW1lc3BhY2UsICRuYW1lc3BhY2VUeXBlLCAkYmFzZVBhdGgsICRpbykKICAgIHsKICAgICAgICAkdmFsaWRDbGFzc2VzID0gYXJyYXkoKTsKICAgICAgICAkcmVqZWN0ZWRDbGFzc2VzID0gYXJyYXkoKTsKCiAgICAgICAgJHJlYWxTdWJQYXRoID0gc3Vic3RyKCRmaWxlUGF0aCwgc3RybGVuKCRiYXNlUGF0aCkgKyAxKTsKICAgICAgICAkcmVhbFN1YlBhdGggPSBzdWJzdHIoJHJlYWxTdWJQYXRoLCAwLCBzdHJycG9zKCRyZWFsU3ViUGF0aCwgJy4nKSk7CgogICAgICAgIGZvcmVhY2ggKCRjbGFzc2VzIGFzICRjbGFzcykgewogICAgICAgICAgICAvLyBzaWxlbnRseSBza2lwIGlmIG5zIGRvZXNuJ3QgaGF2ZSBjb21tb24gcm9vdAogICAgICAgICAgICBpZiAoJycgIT09ICRiYXNlTmFtZXNwYWNlICYmIDAgIT09IHN0cnBvcygkY2xhc3MsICRiYXNlTmFtZXNwYWNlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gdHJhbnNmb3JtIGNsYXNzIG5hbWUgdG8gZmlsZSBwYXRoIGFuZCB2YWxpZGF0ZQogICAgICAgICAgICBpZiAoJ3Bzci0wJyA9PT0gJG5hbWVzcGFjZVR5cGUpIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VMZW5ndGggPSBzdHJycG9zKCRjbGFzcywgJ1xcJyk7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRuYW1lc3BhY2VMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAkbmFtZXNwYWNlID0gc3Vic3RyKCRjbGFzcywgMCwgJG5hbWVzcGFjZUxlbmd0aCArIDEpOwogICAgICAgICAgICAgICAgICAgICRjbGFzc05hbWUgPSBzdWJzdHIoJGNsYXNzLCAkbmFtZXNwYWNlTGVuZ3RoICsgMSk7CiAgICAgICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkbmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICAuIHN0cl9yZXBsYWNlKCdfJywgRElSRUNUT1JZX1NFUEFSQVRPUiwgJGNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRzdWJQYXRoID0gc3RyX3JlcGxhY2UoJ18nLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkY2xhc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJ3Bzci00JyA9PT0gJG5hbWVzcGFjZVR5cGUpIHsKICAgICAgICAgICAgICAgICRzdWJOYW1lc3BhY2UgPSAoJycgIT09ICRiYXNlTmFtZXNwYWNlKSA/IHN1YnN0cigkY2xhc3MsIHN0cmxlbigkYmFzZU5hbWVzcGFjZSkpIDogJGNsYXNzOwogICAgICAgICAgICAgICAgJHN1YlBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCBESVJFQ1RPUllfU0VQQVJBVE9SLCAkc3ViTmFtZXNwYWNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigibmFtZXNwYWNlVHlwZSBtdXN0IGJlIHBzci0wIG9yIHBzci00LCAkbmFtZXNwYWNlVHlwZSBnaXZlbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkc3ViUGF0aCA9PT0gJHJlYWxTdWJQYXRoKSB7CiAgICAgICAgICAgICAgICAkdmFsaWRDbGFzc2VzW10gPSAkY2xhc3M7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVqZWN0ZWRDbGFzc2VzW10gPSAkY2xhc3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gd2FybiBvbmx5IGlmIG5vIHZhbGlkIGNsYXNzZXMsIGVsc2Ugc2lsZW50bHkgc2tpcCBpbnZhbGlkCiAgICAgICAgaWYgKGVtcHR5KCR2YWxpZENsYXNzZXMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRyZWplY3RlZENsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlvKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCI8d2FybmluZz5DbGFzcyAkY2xhc3MgbG9jYXRlZCBpbiAiLnByZWdfcmVwbGFjZSgne14nLnByZWdfcXVvdGUoZ2V0Y3dkKCkpLid9JywgJy4nLCAkZmlsZVBhdGgsIDEpLiIgZG9lcyBub3QgY29tcGx5IHdpdGggJG5hbWVzcGFjZVR5cGUgYXV0b2xvYWRpbmcgc3RhbmRhcmQuIFNraXBwaW5nLjwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbGlkQ2xhc3NlczsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgdGhlIGNsYXNzZXMgaW4gdGhlIGdpdmVuIGZpbGUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoIFRoZSBmaWxlIHRvIGNoZWNrCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgICAgICAgIFRoZSBmb3VuZCBjbGFzc2VzCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZpbmRDbGFzc2VzKCRwYXRoKQogICAgewogICAgICAgICRleHRyYVR5cGVzID0gUEhQX1ZFUlNJT05fSUQgPCA1MDQwMCA/ICcnIDogJ3x0cmFpdCc7CiAgICAgICAgaWYgKGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpICYmIHZlcnNpb25fY29tcGFyZShISFZNX1ZFUlNJT04sICczLjMnLCAnPj0nKSkgewogICAgICAgICAgICAkZXh0cmFUeXBlcyAuPSAnfGVudW0nOwogICAgICAgIH0KCiAgICAgICAgLy8gVXNlIEAgaGVyZSBpbnN0ZWFkIG9mIFNpbGVuY2VyIHRvIGFjdGl2ZWx5IHN1cHByZXNzICd1bmhlbHBmdWwnIG91dHB1dAogICAgICAgIC8vIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9wdWxsLzQ4ODYKICAgICAgICAkY29udGVudHMgPSBAcGhwX3N0cmlwX3doaXRlc3BhY2UoJHBhdGgpOwogICAgICAgIGlmICghJGNvbnRlbnRzKSB7CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdGaWxlIGF0ICIlcyIgZG9lcyBub3QgZXhpc3QsIGNoZWNrIHlvdXIgY2xhc3NtYXAgZGVmaW5pdGlvbnMnOwogICAgICAgICAgICB9IGVsc2VpZiAoIWlzX3JlYWRhYmxlKCRwYXRoKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnRmlsZSBhdCAiJXMiIGlzIG5vdCByZWFkYWJsZSwgY2hlY2sgaXRzIHBlcm1pc3Npb25zJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCcnID09PSB0cmltKGZpbGVfZ2V0X2NvbnRlbnRzKCRwYXRoKSkpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBpbnB1dCBmaWxlIHdhcyByZWFsbHkgZW1wdHkgYW5kIHRodXMgY29udGFpbnMgbm8gY2xhc3NlcwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdGaWxlIGF0ICIlcyIgY291bGQgbm90IGJlIHBhcnNlZCBhcyBQSFAsIGl0IG1heSBiZSBiaW5hcnkgb3IgY29ycnVwdGVkJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGVycm9yWydtZXNzYWdlJ10pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSBQSFBfRU9MIC4gJ1RoZSBmb2xsb3dpbmcgbWVzc2FnZSBtYXkgYmUgaGVscGZ1bDonIC4gUEhQX0VPTCAuICRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCRtZXNzYWdlLCAkcGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgLy8gcmV0dXJuIGVhcmx5IGlmIHRoZXJlIGlzIG5vIGNoYW5jZSBvZiBtYXRjaGluZyBhbnl0aGluZyBpbiB0aGlzIGZpbGUKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3tcYig/OmNsYXNzfGludGVyZmFjZScuJGV4dHJhVHlwZXMuJylcc31pJywgJGNvbnRlbnRzKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgIC8vIHN0cmlwIGhlcmVkb2NzL25vd2RvY3MKICAgICAgICAkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoJ3s8PDxbIFx0XSooW1wnIl0/KShcdyspXFwxKD86XHJcbnxcbnxccikoPzouKj8pKD86XHJcbnxcbnxccikoPzpccyopXFwyKD89XHMrfFs7LC4pXSl9cycsICdudWxsJywgJGNvbnRlbnRzKTsKICAgICAgICAvLyBzdHJpcCBzdHJpbmdzCiAgICAgICAgJGNvbnRlbnRzID0gcHJlZ19yZXBsYWNlKCd7IlteIlxcXFxdKisoXFxcXC5bXiJcXFxcXSorKSorInxcJ1teXCdcXFxcXSorKFxcXFwuW15cJ1xcXFxdKispKitcJ31zJywgJ251bGwnLCAkY29udGVudHMpOwogICAgICAgIC8vIHN0cmlwIGxlYWRpbmcgbm9uLXBocCBjb2RlIGlmIG5lZWRlZAogICAgICAgIGlmIChzdHJwb3MoJGNvbnRlbnRzLCAnPD8nKSAhPT0gMCkgewogICAgICAgICAgICAkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoJ3teLis/PFw/fXMnLCAnPD8nLCAkY29udGVudHMsIDEsICRyZXBsYWNlbWVudHMpOwogICAgICAgICAgICBpZiAoJHJlcGxhY2VtZW50cyA9PT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gc3RyaXAgbm9uLXBocCBibG9ja3MgaW4gdGhlIGZpbGUKICAgICAgICAkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoJ3tcPz4oPzpbXjxdKyt8PCg/IVw/KSkqKzxcP31zJywgJz8+PD8nLCAkY29udGVudHMpOwogICAgICAgIC8vIHN0cmlwIHRyYWlsaW5nIG5vbi1waHAgY29kZSBpZiBuZWVkZWQKICAgICAgICAkcG9zID0gc3RycnBvcygkY29udGVudHMsICc/PicpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJHBvcyAmJiBmYWxzZSA9PT0gc3RycG9zKHN1YnN0cigkY29udGVudHMsICRwb3MpLCAnPD8nKSkgewogICAgICAgICAgICAkY29udGVudHMgPSBzdWJzdHIoJGNvbnRlbnRzLCAwLCAkcG9zKTsKICAgICAgICB9CiAgICAgICAgLy8gc3RyaXAgY29tbWVudHMgaWYgc2hvcnQgb3BlbiB0YWdzIGFyZSBpbiB0aGUgZmlsZQogICAgICAgIGlmIChwcmVnX21hdGNoKCd7KDxcPykoPyEocGhwfGhoKSl9aScsICRjb250ZW50cykpIHsKICAgICAgICAgICAgJGNvbnRlbnRzID0gcHJlZ19yZXBsYWNlKCd7Ly8uKiB8IC9cKig/OlteKl0rK3xcKig/IS8pKSpcKi99eCcsICcnLCAkY29udGVudHMpOwogICAgICAgIH0KCiAgICAgICAgcHJlZ19tYXRjaF9hbGwoJ3sKICAgICAgICAgICAgKD86CiAgICAgICAgICAgICAgICAgXGIoPzwhW1wkOj5dKSg/UDx0eXBlPmNsYXNzfGludGVyZmFjZScuJGV4dHJhVHlwZXMuJykgXHMrKyAoP1A8bmFtZT5bYS16QS1aX1x4N2YtXHhmZjpdW2EtekEtWjAtOV9ceDdmLVx4ZmY6XC1dKispCiAgICAgICAgICAgICAgIHwgXGIoPzwhW1wkOj5dKSg/UDxucz5uYW1lc3BhY2UpICg/UDxuc25hbWU+XHMrK1thLXpBLVpfXHg3Zi1ceGZmXVthLXpBLVowLTlfXHg3Zi1ceGZmXSorKD86XHMqK1xcXFxccyorW2EtekEtWl9ceDdmLVx4ZmZdW2EtekEtWjAtOV9ceDdmLVx4ZmZdKispKispPyBccyorIFtceztdCiAgICAgICAgICAgICkKICAgICAgICB9aXgnLCAkY29udGVudHMsICRtYXRjaGVzKTsKCiAgICAgICAgJGNsYXNzZXMgPSBhcnJheSgpOwogICAgICAgICRuYW1lc3BhY2UgPSAnJzsKCiAgICAgICAgZm9yICgkaSA9IDAsICRsZW4gPSBjb3VudCgkbWF0Y2hlc1sndHlwZSddKTsgJGkgPCAkbGVuOyAkaSsrKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoZXNbJ25zJ11bJGldKSkgewogICAgICAgICAgICAgICAgJG5hbWVzcGFjZSA9IHN0cl9yZXBsYWNlKGFycmF5KCcgJywgIlx0IiwgIlxyIiwgIlxuIiksICcnLCAkbWF0Y2hlc1snbnNuYW1lJ11bJGldKSAuICdcXCc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9ICRtYXRjaGVzWyduYW1lJ11bJGldOwogICAgICAgICAgICAgICAgLy8gc2tpcCBhbm9uIGNsYXNzZXMgZXh0ZW5kaW5nL2ltcGxlbWVudGluZwogICAgICAgICAgICAgICAgaWYgKCRuYW1lID09PSAnZXh0ZW5kcycgfHwgJG5hbWUgPT09ICdpbXBsZW1lbnRzJykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRuYW1lWzBdID09PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGFuIFhIUCBjbGFzcywgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3hocAogICAgICAgICAgICAgICAgICAgICRuYW1lID0gJ3hocCcuc3Vic3RyKHN0cl9yZXBsYWNlKGFycmF5KCctJywgJzonKSwgYXJyYXkoJ18nLCAnX18nKSwgJG5hbWUpLCAxKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbWF0Y2hlc1sndHlwZSddWyRpXSA9PT0gJ2VudW0nKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSW4gSGFjaywgc29tZXRoaW5nIGxpa2U6CiAgICAgICAgICAgICAgICAgICAgLy8gICBlbnVtIEZvbzogaW50IHsgSEVSUCA9ICcxMjMnOyB9CiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlZ2V4IGFib3ZlIGNhcHR1cmVzIHRoZSBjb2xvbiwgd2hpY2ggaXNuJ3QgcGFydCBvZgogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjbGFzcyBuYW1lLgogICAgICAgICAgICAgICAgICAgICRuYW1lID0gcnRyaW0oJG5hbWUsICc6Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY2xhc3Nlc1tdID0gbHRyaW0oJG5hbWVzcGFjZSAuICRuYW1lLCAnXFwnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjbGFzc2VzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcVGFibGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcU3R5bGVcU3ltZm9ueVN0eWxlOwoKLyoqCiAqIEBhdXRob3IgQmVub8OudCBNZXJsZXQgPGJlbm9pdC5tZXJsZXRAZ21haWwuY29tPgogKi8KY2xhc3MgTGljZW5zZXNDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdsaWNlbnNlcycpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIGluZm9ybWF0aW9uIGFib3V0IGxpY2Vuc2VzIG9mIGRlcGVuZGVuY2llcy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsICdmJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnRm9ybWF0IG9mIHRoZSBvdXRwdXQ6IHRleHQsIGpzb24gb3Igc3VtbWFyeScsICd0ZXh0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgc2VhcmNoIGluIHJlcXVpcmUtZGV2IHBhY2thZ2VzLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIGxpY2Vuc2UgY29tbWFuZCBkaXNwbGF5cyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbGljZW5zZXMgb2YKdGhlIGluc3RhbGxlZCBkZXBlbmRlbmNpZXMuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNsaWNlbnNlcwpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwoKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICdsaWNlbnNlcycsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJHJvb3QgPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKTsKICAgICAgICAkcmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmZpbHRlclJlcXVpcmVkUGFja2FnZXMoJHJlcG8sICRyb290KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+YXBwZW5kUGFja2FnZXMoJHJlcG8tPmdldFBhY2thZ2VzKCksIGFycmF5KCkpOwogICAgICAgIH0KCiAgICAgICAga3NvcnQoJHBhY2thZ2VzKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgc3dpdGNoICgkZm9ybWF0ID0gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpKSB7CiAgICAgICAgICAgIGNhc2UgJ3RleHQnOgogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnTmFtZTogPGNvbW1lbnQ+Jy4kcm9vdC0+Z2V0UHJldHR5TmFtZSgpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdWZXJzaW9uOiA8Y29tbWVudD4nLiRyb290LT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdMaWNlbnNlczogPGNvbW1lbnQ+Jy4oaW1wbG9kZSgnLCAnLCAkcm9vdC0+Z2V0TGljZW5zZSgpKSA/OiAnbm9uZScpLic8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCdEZXBlbmRlbmNpZXM6Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcnKTsKCiAgICAgICAgICAgICAgICAkdGFibGUgPSBuZXcgVGFibGUoJG91dHB1dCk7CiAgICAgICAgICAgICAgICAkdGFibGUtPnNldFN0eWxlKCdjb21wYWN0Jyk7CiAgICAgICAgICAgICAgICAkdGFibGVTdHlsZSA9ICR0YWJsZS0+Z2V0U3R5bGUoKTsKICAgICAgICAgICAgICAgIGlmIChtZXRob2RfZXhpc3RzKCR0YWJsZVN0eWxlLCAnc2V0VmVydGljYWxCb3JkZXJDaGFycycpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRhYmxlU3R5bGUtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcnMoJycpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGFibGVTdHlsZS0+c2V0VmVydGljYWxCb3JkZXJDaGFyKCcnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0YWJsZVN0eWxlLT5zZXRDZWxsUm93Q29udGVudEZvcm1hdCgnJXMgICcpOwogICAgICAgICAgICAgICAgJHRhYmxlLT5zZXRIZWFkZXJzKGFycmF5KCdOYW1lJywgJ1ZlcnNpb24nLCAnTGljZW5zZScpKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICR0YWJsZS0+YWRkUm93KGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgaW1wbG9kZSgnLCAnLCAkcGFja2FnZS0+Z2V0TGljZW5zZSgpKSA/OiAnbm9uZScsCiAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGFibGUtPnJlbmRlcigpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdqc29uJzoKICAgICAgICAgICAgICAgICRkZXBlbmRlbmNpZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGRlcGVuZGVuY2llc1skcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgICdsaWNlbnNlJyA9PiAkcGFja2FnZS0+Z2V0TGljZW5zZSgpLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGlvLT53cml0ZShKc29uRmlsZTo6ZW5jb2RlKGFycmF5KAogICAgICAgICAgICAgICAgICAgICduYW1lJyA9PiAkcm9vdC0+Z2V0UHJldHR5TmFtZSgpLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcm9vdC0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSwKICAgICAgICAgICAgICAgICAgICAnbGljZW5zZScgPT4gJHJvb3QtPmdldExpY2Vuc2UoKSwKICAgICAgICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJyA9PiAkZGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgKSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdzdW1tYXJ5JzoKICAgICAgICAgICAgICAgICR1c2VkTGljZW5zZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpY2Vuc2UgPSAkcGFja2FnZS0+Z2V0TGljZW5zZSgpOwogICAgICAgICAgICAgICAgICAgICRsaWNlbnNlTmFtZSA9ICRsaWNlbnNlWzBdOwogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHVzZWRMaWNlbnNlc1skbGljZW5zZU5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdXNlZExpY2Vuc2VzWyRsaWNlbnNlTmFtZV0gPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdXNlZExpY2Vuc2VzWyRsaWNlbnNlTmFtZV0rKzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTb3J0IGxpY2Vuc2VzIHNvIHRoYXQgdGhlIG1vc3QgdXNlZCBsaWNlbnNlIHdpbGwgYXBwZWFyIGZpcnN0CiAgICAgICAgICAgICAgICBhcnNvcnQoJHVzZWRMaWNlbnNlcywgU09SVF9OVU1FUklDKTsKCiAgICAgICAgICAgICAgICAkcm93cyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdXNlZExpY2Vuc2VzIGFzICR1c2VkTGljZW5zZSA9PiAkbnVtYmVyT2ZEZXBlbmRlbmNpZXMpIHsKICAgICAgICAgICAgICAgICAgICAkcm93c1tdID0gYXJyYXkoJHVzZWRMaWNlbnNlLCAkbnVtYmVyT2ZEZXBlbmRlbmNpZXMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRzeW1mb255SW8gPSBuZXcgU3ltZm9ueVN0eWxlKCRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgICAgICAgICAkc3ltZm9ueUlvLT50YWJsZSgKICAgICAgICAgICAgICAgICAgICBhcnJheSgnTGljZW5zZScsICdOdW1iZXIgb2YgZGVwZW5kZW5jaWVzJyksCiAgICAgICAgICAgICAgICAgICAgJHJvd3MKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdVbnN1cHBvcnRlZCBmb3JtYXQgIiVzIi4gIFNlZSBoZWxwIGZvciBzdXBwb3J0ZWQgZm9ybWF0cy4nLCAkZm9ybWF0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgcGFja2FnZSByZXF1aXJlcyBhbmQgY2hpbGQgcmVxdWlyZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8KICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAkcGFja2FnZQogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICRidWNrZXQKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmaWx0ZXJSZXF1aXJlZFBhY2thZ2VzKFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRidWNrZXQgPSBhcnJheSgpKQogICAgewogICAgICAgICRyZXF1aXJlcyA9IGFycmF5X2tleXMoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkpOwoKICAgICAgICAkcGFja2FnZUxpc3ROYW1lcyA9IGFycmF5X2tleXMoJGJ1Y2tldCk7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfZmlsdGVyKAogICAgICAgICAgICAkcmVwby0+Z2V0UGFja2FnZXMoKSwKICAgICAgICAgICAgZnVuY3Rpb24gKCRwYWNrYWdlKSB1c2UgKCRyZXF1aXJlcywgJHBhY2thZ2VMaXN0TmFtZXMpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcmVxdWlyZXMpICYmICFpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZUxpc3ROYW1lcyk7CiAgICAgICAgICAgIH0KICAgICAgICApOwoKICAgICAgICAkYnVja2V0ID0gJHRoaXMtPmFwcGVuZFBhY2thZ2VzKCRwYWNrYWdlcywgJGJ1Y2tldCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkYnVja2V0ID0gJHRoaXMtPmZpbHRlclJlcXVpcmVkUGFja2FnZXMoJHJlcG8sICRwYWNrYWdlLCAkYnVja2V0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYnVja2V0OwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBwYWNrYWdlcyB0byB0aGUgcGFja2FnZSBsaXN0CiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAkcGFja2FnZXMgdGhlIGxpc3Qgb2YgcGFja2FnZXMgdG8gYWRkCiAgICAgKiBAcGFyYW0gIGFycmF5ICRidWNrZXQgICB0aGUgbGlzdCB0byBhZGQgcGFja2FnZXMgdG8KICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlcywgYXJyYXkgJGJ1Y2tldCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGJ1Y2tldFskcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRidWNrZXQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBTY3JpcHRBbGlhc0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcml2YXRlICRzY3JpcHQ7CiAgICBwcml2YXRlICRkZXNjcmlwdGlvbjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNjcmlwdCwgJGRlc2NyaXB0aW9uKQogICAgewogICAgICAgICR0aGlzLT5zY3JpcHQgPSAkc2NyaXB0OwogICAgICAgICR0aGlzLT5kZXNjcmlwdGlvbiA9IGVtcHR5KCRkZXNjcmlwdGlvbikgPyAnUnVucyB0aGUgJy4kc2NyaXB0Licgc2NyaXB0IGFzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbi4nIDogJGRlc2NyaXB0aW9uOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCR0aGlzLT5zY3JpcHQpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJHRoaXMtPmRlc2NyaXB0aW9uKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2V0cyB0aGUgZGV2IG1vZGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgdGhlIGRldiBtb2RlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2FyZ3MnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+cnVuLXNjcmlwdDwvaW5mbz4gY29tbWFuZCBydW5zIHNjcmlwdHMgZGVmaW5lZCBpbiBjb21wb3Nlci5qc29uOgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgcnVuLXNjcmlwdCBwb3N0LXVwZGF0ZS1jbWQ8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNydW4tc2NyaXB0CkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRhcmdzID0gJGlucHV0LT5nZXRBcmd1bWVudHMoKTsKCiAgICAgICAgcmV0dXJuICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KCR0aGlzLT5zY3JpcHQsICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSB8fCAhJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpLCAkYXJnc1snYXJncyddKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFNjcmlwdFxTY3JpcHRFdmVudHM7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQ3JlYXRlcyBhbiBhcmNoaXZlIG9mIGEgcGFja2FnZSBmb3IgZGlzdHJpYnV0aW9uLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQXJjaGl2ZUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2FyY2hpdmUnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdDcmVhdGVzIGFuIGFyY2hpdmUgb2YgdGhpcyBjb21wb3NlciBwYWNrYWdlLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdwYWNrYWdlJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdUaGUgcGFja2FnZSB0byBhcmNoaXZlIGluc3RlYWQgb2YgdGhlIGN1cnJlbnQgcHJvamVjdCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3ZlcnNpb24nLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ0EgdmVyc2lvbiBjb25zdHJhaW50IHRvIGZpbmQgdGhlIHBhY2thZ2UgdG8gYXJjaGl2ZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmb3JtYXQnLCAnZicsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0Zvcm1hdCBvZiB0aGUgcmVzdWx0aW5nIGFyY2hpdmU6IHRhciBvciB6aXAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGlyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnV3JpdGUgdGhlIGFyY2hpdmUgdG8gdGhpcyBkaXJlY3RvcnknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZmlsZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1dyaXRlIHRoZSBhcmNoaXZlIHdpdGggdGhlIGdpdmVuIGZpbGUgbmFtZS4nCiAgICAgICAgICAgICAgICAgICAgLicgTm90ZSB0aGF0IHRoZSBmb3JtYXQgd2lsbCBiZSBhcHBlbmRlZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLWZpbHRlcnMnLCBmYWxzZSwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdJZ25vcmUgZmlsdGVycyB3aGVuIHNhdmluZyBwYWNrYWdlJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+YXJjaGl2ZTwvaW5mbz4gY29tbWFuZCBjcmVhdGVzIGFuIGFyY2hpdmUgb2YgdGhlIHNwZWNpZmllZCBmb3JtYXQKY29udGFpbmluZyB0aGUgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIG9mIHRoZSBDb21wb3NlciBwcm9qZWN0IG9yIHRoZSBzcGVjaWZpZWQKcGFja2FnZSBpbiB0aGUgc3BlY2lmaWVkIHZlcnNpb24gYW5kIHdyaXRlcyBpdCB0byB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeS4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGFyY2hpdmUgWy0tZm9ybWF0PXppcF0gWy0tZGlyPS9mb29dIFtwYWNrYWdlIFt2ZXJzaW9uXV08L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNhcmNoaXZlCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlKTsKICAgICAgICAkY29uZmlnID0gbnVsbDsKCiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkY29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKTsKICAgICAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnYXJjaGl2ZScsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgICAgICRldmVudERpc3BhdGNoZXIgPSAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpOwogICAgICAgICAgICAkZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwogICAgICAgICAgICAkZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBSRV9BUkNISVZFX0NNRCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRjb25maWcpIHsKICAgICAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKSkgewogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignZm9ybWF0JywgJGNvbmZpZy0+Z2V0KCdhcmNoaXZlLWZvcm1hdCcpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgPT09ICRpbnB1dC0+Z2V0T3B0aW9uKCdkaXInKSkgewogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignZGlyJywgJGNvbmZpZy0+Z2V0KCdhcmNoaXZlLWRpcicpKTsKICAgICAgICB9CgogICAgICAgICRyZXR1cm5Db2RlID0gJHRoaXMtPmFyY2hpdmUoCiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLAogICAgICAgICAgICAkY29uZmlnLAogICAgICAgICAgICAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3ZlcnNpb24nKSwKICAgICAgICAgICAgJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignZGlyJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdmaWxlJyksCiAgICAgICAgICAgICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtZmlsdGVycycpLAogICAgICAgICAgICAkY29tcG9zZXIKICAgICAgICApOwoKICAgICAgICBpZiAoMCA9PT0gJHJldHVybkNvZGUgJiYgJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KFNjcmlwdEV2ZW50czo6UE9TVF9BUkNISVZFX0NNRCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJldHVybkNvZGU7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFyY2hpdmUoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgJHBhY2thZ2VOYW1lID0gbnVsbCwgJHZlcnNpb24gPSBudWxsLCAkZm9ybWF0ID0gJ3RhcicsICRkZXN0ID0gJy4nLCAkZmlsZU5hbWUgPSBudWxsLCAkaWdub3JlRmlsdGVycyA9IGZhbHNlLCBDb21wb3NlciAkY29tcG9zZXIgPSBudWxsKQogICAgewogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGFyY2hpdmVNYW5hZ2VyID0gJGNvbXBvc2VyLT5nZXRBcmNoaXZlTWFuYWdlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmYWN0b3J5ID0gbmV3IEZhY3Rvcnk7CiAgICAgICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigpOwogICAgICAgICAgICAkaHR0cERvd25sb2FkZXIgPSBGYWN0b3J5OjpjcmVhdGVIdHRwRG93bmxvYWRlcigkaW8sICRjb25maWcpOwogICAgICAgICAgICAkZG93bmxvYWRNYW5hZ2VyID0gJGZhY3RvcnktPmNyZWF0ZURvd25sb2FkTWFuYWdlcigkaW8sICRjb25maWcsICRodHRwRG93bmxvYWRlciwgJHByb2Nlc3MpOwogICAgICAgICAgICAkYXJjaGl2ZU1hbmFnZXIgPSAkZmFjdG9yeS0+Y3JlYXRlQXJjaGl2ZU1hbmFnZXIoJGNvbmZpZywgJGRvd25sb2FkTWFuYWdlciwgbmV3IExvb3AoJGh0dHBEb3dubG9hZGVyLCAkcHJvY2VzcykpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5zZWxlY3RQYWNrYWdlKCRpbywgJHBhY2thZ2VOYW1lLCAkdmVyc2lvbik7CgogICAgICAgICAgICBpZiAoISRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmdldENvbXBvc2VyKCktPmdldFBhY2thZ2UoKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Q3JlYXRpbmcgdGhlIGFyY2hpdmUgaW50byAiJy4kZGVzdC4nIi48L2luZm8+Jyk7CiAgICAgICAgJHBhY2thZ2VQYXRoID0gJGFyY2hpdmVNYW5hZ2VyLT5hcmNoaXZlKCRwYWNrYWdlLCAkZm9ybWF0LCAkZGVzdCwgJGZpbGVOYW1lLCAkaWdub3JlRmlsdGVycyk7CiAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW07CiAgICAgICAgJHNob3J0UGF0aCA9ICRmcy0+ZmluZFNob3J0ZXN0UGF0aChnZXRjd2QoKSwgJHBhY2thZ2VQYXRoLCB0cnVlKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCdDcmVhdGVkOiAnLCBmYWxzZSk7CiAgICAgICAgJGlvLT53cml0ZShzdHJsZW4oJHNob3J0UGF0aCkgPCBzdHJsZW4oJHBhY2thZ2VQYXRoKSA/ICRzaG9ydFBhdGggOiAkcGFja2FnZVBhdGgpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2VsZWN0UGFja2FnZShJT0ludGVyZmFjZSAkaW8sICRwYWNrYWdlTmFtZSwgJHZlcnNpb24gPSBudWxsKQogICAgewogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+U2VhcmNoaW5nIGZvciB0aGUgc3BlY2lmaWVkIHBhY2thZ2UuPC9pbmZvPicpOwoKICAgICAgICBpZiAoJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlKSkgewogICAgICAgICAgICAkbG9jYWxSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgJHJlcG8gPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZShhcnJheSgkbG9jYWxSZXBvKSwgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCR0aGlzLT5nZXRJTygpKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgc2VhcmNoaW5nIHBhY2thZ2VzIGZyb20gJyAuIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkZGVmYXVsdFJlcG9zKSkpOwogICAgICAgICAgICAkcmVwbyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRkZWZhdWx0UmVwb3MpOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VzID0gJHJlcG8tPmZpbmRQYWNrYWdlcygkcGFja2FnZU5hbWUsICR2ZXJzaW9uKTsKCiAgICAgICAgaWYgKGNvdW50KCRwYWNrYWdlcykgPiAxKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gcmVzZXQoJHBhY2thZ2VzKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5Gb3VuZCBtdWx0aXBsZSBtYXRjaGVzLCBzZWxlY3RlZCAnLiRwYWNrYWdlLT5nZXRQcmV0dHlTdHJpbmcoKS4nLjwvaW5mbz4nKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdBbHRlcm5hdGl2ZXMgd2VyZSAnLmltcGxvZGUoJywgJywgYXJyYXlfbWFwKGZ1bmN0aW9uICgkcCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRwLT5nZXRQcmV0dHlTdHJpbmcoKTsKICAgICAgICAgICAgfSwgJHBhY2thZ2VzKSkuJy4nKTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8Y29tbWVudD5QbGVhc2UgdXNlIGEgbW9yZSBzcGVjaWZpYyBjb25zdHJhaW50IHRvIHBpY2sgYSBkaWZmZXJlbnQgcGFja2FnZS48L2NvbW1lbnQ+Jyk7CiAgICAgICAgfSBlbHNlaWYgKCRwYWNrYWdlcykgewogICAgICAgICAgICAkcGFja2FnZSA9IHJlc2V0KCRwYWNrYWdlcyk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Rm91bmQgYW4gZXhhY3QgbWF0Y2ggJy4kcGFja2FnZS0+Z2V0UHJldHR5U3RyaW5nKCkuJy48L2luZm8+Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Q291bGQgbm90IGZpbmQgYSBwYWNrYWdlIG1hdGNoaW5nICcuJHBhY2thZ2VOYW1lLicuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25TZWxlY3RvcjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5RmFjdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxBcnJheUlucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4ZWN1dGFibGVGaW5kZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CgovKioKICogQGF1dGhvciBKdXN0aW4gUmFpbmJvdyA8anVzdGluLnJhaW5ib3dAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBJbml0Q29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIC8qKiBAdmFyIENvbXBvc2l0ZVJlcG9zaXRvcnkgKi8KICAgIHByb3RlY3RlZCAkcmVwb3M7CgogICAgLyoqIEB2YXIgYXJyYXkgKi8KICAgIHByaXZhdGUgJGdpdENvbmZpZzsKCiAgICAvKiogQHZhciBSZXBvc2l0b3J5U2V0W10gKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcnlTZXRzOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2luaXQnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdDcmVhdGVzIGEgYmFzaWMgY29tcG9zZXIuanNvbiBmaWxlIGluIGN1cnJlbnQgZGlyZWN0b3J5LicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbmFtZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ05hbWUgb2YgdGhlIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGVzY3JpcHRpb24nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdEZXNjcmlwdGlvbiBvZiBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2F1dGhvcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0F1dGhvciBuYW1lIG9mIHBhY2thZ2UnKSwKICAgICAgICAgICAgICAgIC8vIG5ldyBJbnB1dE9wdGlvbigndmVyc2lvbicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVmVyc2lvbiBvZiBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3R5cGUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfT1BUSU9OQUwsICdUeXBlIG9mIHBhY2thZ2UgKGUuZy4gbGlicmFyeSwgcHJvamVjdCwgbWV0YXBhY2thZ2UsIGNvbXBvc2VyLXBsdWdpbiknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaG9tZXBhZ2UnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdIb21lcGFnZSBvZiBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3JlcXVpcmUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVkgfCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdQYWNrYWdlIHRvIHJlcXVpcmUgd2l0aCBhIHZlcnNpb24gY29uc3RyYWludCwgZS5nLiBmb28vYmFyOjEuMC4wIG9yIGZvby9iYXI9MS4wLjAgb3IgImZvby9iYXIgMS4wLjAiJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3JlcXVpcmUtZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZIHwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnUGFja2FnZSB0byByZXF1aXJlIGZvciBkZXZlbG9wbWVudCB3aXRoIGEgdmVyc2lvbiBjb25zdHJhaW50LCBlLmcuIGZvby9iYXI6MS4wLjAgb3IgZm9vL2Jhcj0xLjAuMCBvciAiZm9vL2JhciAxLjAuMCInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc3RhYmlsaXR5JywgJ3MnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdNaW5pbXVtIHN0YWJpbGl0eSAoZW1wdHkgb3Igb25lIG9mOiAnLmltcGxvZGUoJywgJywgYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzKSkuJyknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbGljZW5zZScsICdsJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnTGljZW5zZSBvZiBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3JlcG9zaXRvcnknLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdBZGQgY3VzdG9tIHJlcG9zaXRvcmllcywgZWl0aGVyIGJ5IFVSTCBvciB1c2luZyBKU09OIGFycmF5cycpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPmluaXQ8L2luZm8+IGNvbW1hbmQgY3JlYXRlcyBhIGJhc2ljIGNvbXBvc2VyLmpzb24gZmlsZQppbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBpbml0PC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjaW5pdApFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgJGFsbG93bGlzdCA9IGFycmF5KCduYW1lJywgJ2Rlc2NyaXB0aW9uJywgJ2F1dGhvcicsICd0eXBlJywgJ2hvbWVwYWdlJywgJ3JlcXVpcmUnLCAncmVxdWlyZS1kZXYnLCAnc3RhYmlsaXR5JywgJ2xpY2Vuc2UnKTsKICAgICAgICAkb3B0aW9ucyA9IGFycmF5X2ZpbHRlcihhcnJheV9pbnRlcnNlY3Rfa2V5KCRpbnB1dC0+Z2V0T3B0aW9ucygpLCBhcnJheV9mbGlwKCRhbGxvd2xpc3QpKSk7CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snYXV0aG9yJ10pKSB7CiAgICAgICAgICAgICRvcHRpb25zWydhdXRob3JzJ10gPSAkdGhpcy0+Zm9ybWF0QXV0aG9ycygkb3B0aW9uc1snYXV0aG9yJ10pOwogICAgICAgICAgICB1bnNldCgkb3B0aW9uc1snYXV0aG9yJ10pOwogICAgICAgIH0KCiAgICAgICAgJHJlcG9zaXRvcmllcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdyZXBvc2l0b3J5Jyk7CiAgICAgICAgaWYgKCRyZXBvc2l0b3JpZXMpIHsKICAgICAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygkaW8pOwogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgICAgICAkb3B0aW9uc1sncmVwb3NpdG9yaWVzJ11bXSA9IFJlcG9zaXRvcnlGYWN0b3J5Ojpjb25maWdGcm9tU3RyaW5nKCRpbywgJGNvbmZpZywgJHJlcG8sIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3N0YWJpbGl0eSddKSkgewogICAgICAgICAgICAkb3B0aW9uc1snbWluaW11bS1zdGFiaWxpdHknXSA9ICRvcHRpb25zWydzdGFiaWxpdHknXTsKICAgICAgICAgICAgdW5zZXQoJG9wdGlvbnNbJ3N0YWJpbGl0eSddKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb25zWydyZXF1aXJlJ10gPSBpc3NldCgkb3B0aW9uc1sncmVxdWlyZSddKSA/ICR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJG9wdGlvbnNbJ3JlcXVpcmUnXSkgOiBuZXcgXHN0ZENsYXNzOwogICAgICAgIGlmIChhcnJheSgpID09PSAkb3B0aW9uc1sncmVxdWlyZSddKSB7CiAgICAgICAgICAgICRvcHRpb25zWydyZXF1aXJlJ10gPSBuZXcgXHN0ZENsYXNzOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydyZXF1aXJlLWRldiddKSkgewogICAgICAgICAgICAkb3B0aW9uc1sncmVxdWlyZS1kZXYnXSA9ICR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10pOwogICAgICAgICAgICBpZiAoYXJyYXkoKSA9PT0gJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10pIHsKICAgICAgICAgICAgICAgICRvcHRpb25zWydyZXF1aXJlLWRldiddID0gbmV3IFxzdGRDbGFzczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSBuZXcgSnNvbkZpbGUoRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCkpOwogICAgICAgICRqc29uID0gSnNvbkZpbGU6OmVuY29kZSgkb3B0aW9ucyk7CgogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoYXJyYXkoJycsICRqc29uLCAnJykpOwogICAgICAgICAgICBpZiAoISRpby0+YXNrQ29uZmlybWF0aW9uKCdEbyB5b3UgY29uZmlybSBnZW5lcmF0aW9uIFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkNvbW1hbmQgYWJvcnRlZDwvZXJyb3I+Jyk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoanNvbl9lbmNvZGUoJG9wdGlvbnMpID09PSAneyJyZXF1aXJlIjp7fX0nKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1lvdSBoYXZlIHRvIHJ1biB0aGlzIGNvbW1hbmQgaW4gaW50ZXJhY3RpdmUgbW9kZSwgb3Igc3BlY2lmeSBhdCBsZWFzdCBzb21lIGRhdGEgdXNpbmcgLS1uYW1lLCAtLXJlcXVpcmUsIGV0Yy4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdXcml0aW5nIGNvbXBvc2VyLmpzb24nKTsKICAgICAgICB9CgogICAgICAgICRmaWxlLT53cml0ZSgkb3B0aW9ucyk7CgogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSAmJiBpc19kaXIoJy5naXQnKSkgewogICAgICAgICAgICAkaWdub3JlRmlsZSA9IHJlYWxwYXRoKCcuZ2l0aWdub3JlJyk7CgogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRpZ25vcmVGaWxlKSB7CiAgICAgICAgICAgICAgICAkaWdub3JlRmlsZSA9IHJlYWxwYXRoKCcuJykgLiAnLy5naXRpZ25vcmUnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISR0aGlzLT5oYXNWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUpKSB7CiAgICAgICAgICAgICAgICAkcXVlc3Rpb24gPSAnV291bGQgeW91IGxpa2UgdGhlIDxpbmZvPnZlbmRvcjwvaW5mbz4gZGlyZWN0b3J5IGFkZGVkIHRvIHlvdXIgPGluZm8+LmdpdGlnbm9yZTwvaW5mbz4gWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnOwoKICAgICAgICAgICAgICAgIGlmICgkaW8tPmFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZFZlbmRvcklnbm9yZSgkaWdub3JlRmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRxdWVzdGlvbiA9ICdXb3VsZCB5b3UgbGlrZSB0byBpbnN0YWxsIGRlcGVuZGVuY2llcyBub3cgWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnOwogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSAmJiAkdGhpcy0+aGFzRGVwZW5kZW5jaWVzKCRvcHRpb25zKSAmJiAkaW8tPmFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24pKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVEZXBlbmRlbmNpZXMoJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGludGVyYWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGdpdCA9ICR0aGlzLT5nZXRHaXRDb25maWcoKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICAkZm9ybWF0dGVyID0gJHRoaXMtPmdldEhlbHBlclNldCgpLT5nZXQoJ2Zvcm1hdHRlcicpOwoKICAgICAgICAvLyBpbml0aWFsaXplIHJlcG9zIGlmIGNvbmZpZ3VyZWQKICAgICAgICAkcmVwb3NpdG9yaWVzID0gJGlucHV0LT5nZXRPcHRpb24oJ3JlcG9zaXRvcnknKTsKICAgICAgICBpZiAoJHJlcG9zaXRvcmllcykgewogICAgICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCRpbyk7CiAgICAgICAgICAgICRyZXBvcyA9IGFycmF5KG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkpOwogICAgICAgICAgICAkY3JlYXRlRGVmYXVsdFBhY2thZ2lzdFJlcG8gPSB0cnVlOwogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3NpdG9yaWVzIGFzICRyZXBvKSB7CiAgICAgICAgICAgICAgICAkcmVwb0NvbmZpZyA9IFJlcG9zaXRvcnlGYWN0b3J5Ojpjb25maWdGcm9tU3RyaW5nKCRpbywgJGNvbmZpZywgJHJlcG8sIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIChpc3NldCgkcmVwb0NvbmZpZ1sncGFja2FnaXN0J10pICYmICRyZXBvQ29uZmlnID09PSBhcnJheSgncGFja2FnaXN0JyA9PiBmYWxzZSkpCiAgICAgICAgICAgICAgICAgICAgfHwgKGlzc2V0KCRyZXBvQ29uZmlnWydwYWNrYWdpc3Qub3JnJ10pICYmICRyZXBvQ29uZmlnID09PSBhcnJheSgncGFja2FnaXN0Lm9yZycgPT4gZmFsc2UpKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJGNyZWF0ZURlZmF1bHRQYWNrYWdpc3RSZXBvID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmVwb3NbXSA9IFJlcG9zaXRvcnlGYWN0b3J5OjpjcmVhdGVSZXBvKCRpbywgJGNvbmZpZywgJHJlcG9Db25maWcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNyZWF0ZURlZmF1bHRQYWNrYWdpc3RSZXBvKSB7CiAgICAgICAgICAgICAgICAkcmVwb3NbXSA9IFJlcG9zaXRvcnlGYWN0b3J5OjpjcmVhdGVSZXBvKCRpbywgJGNvbmZpZywgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ3R5cGUnID0+ICdjb21wb3NlcicsCiAgICAgICAgICAgICAgICAgICAgJ3VybCcgPT4gJ2h0dHBzOi8vcmVwby5wYWNrYWdpc3Qub3JnJywKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+cmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeSgkcmVwb3MpOwogICAgICAgICAgICB1bnNldCgkcmVwb3MsICRjb25maWcsICRyZXBvc2l0b3JpZXMpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAnJywKICAgICAgICAgICAgJGZvcm1hdHRlci0+Zm9ybWF0QmxvY2soJ1dlbGNvbWUgdG8gdGhlIENvbXBvc2VyIGNvbmZpZyBnZW5lcmF0b3InLCAnYmc9Ymx1ZTtmZz13aGl0ZScsIHRydWUpLAogICAgICAgICAgICAnJywKICAgICAgICApKTsKCiAgICAgICAgLy8gbmFtZXNwYWNlCiAgICAgICAgJGlvLT53cml0ZUVycm9yKGFycmF5KAogICAgICAgICAgICAnJywKICAgICAgICAgICAgJ1RoaXMgY29tbWFuZCB3aWxsIGd1aWRlIHlvdSB0aHJvdWdoIGNyZWF0aW5nIHlvdXIgY29tcG9zZXIuanNvbiBjb25maWcuJywKICAgICAgICAgICAgJycsCiAgICAgICAgKSk7CgogICAgICAgICRjd2QgPSByZWFscGF0aCgiLiIpOwoKICAgICAgICBpZiAoISRuYW1lID0gJGlucHV0LT5nZXRPcHRpb24oJ25hbWUnKSkgewogICAgICAgICAgICAkbmFtZSA9IGJhc2VuYW1lKCRjd2QpOwogICAgICAgICAgICAkbmFtZSA9IHByZWdfcmVwbGFjZSgneyg/OihbYS16XSkoW0EtWl0pfChbQS1aXSkoW0EtWl1bYS16XSkpfScsICdcXDFcXDMtXFwyXFw0JywgJG5hbWUpOwogICAgICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJG5hbWUpOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX1ZFTkRPUiddKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAkX1NFUlZFUlsnQ09NUE9TRVJfREVGQVVMVF9WRU5ET1InXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGdpdFsnZ2l0aHViLnVzZXInXSkpIHsKICAgICAgICAgICAgICAgICRuYW1lID0gJGdpdFsnZ2l0aHViLnVzZXInXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoIWVtcHR5KCRfU0VSVkVSWydVU0VSTkFNRSddKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAkX1NFUlZFUlsnVVNFUk5BTUUnXSAuICcvJyAuICRuYW1lOwogICAgICAgICAgICB9IGVsc2VpZiAoIWVtcHR5KCRfU0VSVkVSWydVU0VSJ10pKSB7CiAgICAgICAgICAgICAgICAkbmFtZSA9ICRfU0VSVkVSWydVU0VSJ10gLiAnLycgLiAkbmFtZTsKICAgICAgICAgICAgfSBlbHNlaWYgKGdldF9jdXJyZW50X3VzZXIoKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSBnZXRfY3VycmVudF91c2VyKCkgLiAnLycgLiAkbmFtZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHBhY2thZ2UgbmFtZXMgbXVzdCBiZSBpbiB0aGUgZm9ybWF0IGZvby9iYXIKICAgICAgICAgICAgICAgICRuYW1lIC49ICcvJyAuICRuYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRuYW1lID0gc3RydG9sb3dlcigkbmFtZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XlthLXowLTlfLi1dKy9bYS16MC05Xy4tXSskfUQnLCAkbmFtZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdUaGUgcGFja2FnZSBuYW1lICcuJG5hbWUuJyBpcyBpbnZhbGlkLCBpdCBzaG91bGQgYmUgbG93ZXJjYXNlIGFuZCBoYXZlIGEgdmVuZG9yIG5hbWUsIGEgZm9yd2FyZCBzbGFzaCwgYW5kIGEgcGFja2FnZSBuYW1lLCBtYXRjaGluZzogW2EtejAtOV8uLV0rL1thLXowLTlfLi1dKycKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRuYW1lID0gJGlvLT5hc2tBbmRWYWxpZGF0ZSgKICAgICAgICAgICAgJ1BhY2thZ2UgbmFtZSAoPHZlbmRvcj4vPG5hbWU+KSBbPGNvbW1lbnQ+Jy4kbmFtZS4nPC9jb21tZW50Pl06ICcsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG5hbWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XlthLXowLTlfLi1dKy9bYS16MC05Xy4tXSskfUQnLCAkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgcGFja2FnZSBuYW1lICcuJHZhbHVlLicgaXMgaW52YWxpZCwgaXQgc2hvdWxkIGJlIGxvd2VyY2FzZSBhbmQgaGF2ZSBhIHZlbmRvciBuYW1lLCBhIGZvcndhcmQgc2xhc2gsIGFuZCBhIHBhY2thZ2UgbmFtZSwgbWF0Y2hpbmc6IFthLXowLTlfLi1dKy9bYS16MC05Xy4tXSsnCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgICAgICB9LAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICAkbmFtZQogICAgICAgICk7CiAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ25hbWUnLCAkbmFtZSk7CgogICAgICAgICRkZXNjcmlwdGlvbiA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXNjcmlwdGlvbicpID86IGZhbHNlOwogICAgICAgICRkZXNjcmlwdGlvbiA9ICRpby0+YXNrKAogICAgICAgICAgICAnRGVzY3JpcHRpb24gWzxjb21tZW50PicuJGRlc2NyaXB0aW9uLic8L2NvbW1lbnQ+XTogJywKICAgICAgICAgICAgJGRlc2NyaXB0aW9uCiAgICAgICAgKTsKICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignZGVzY3JpcHRpb24nLCAkZGVzY3JpcHRpb24pOwoKICAgICAgICBpZiAobnVsbCA9PT0gJGF1dGhvciA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdhdXRob3InKSkgewogICAgICAgICAgICBpZiAoIWVtcHR5KCRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX0FVVEhPUiddKSkgewogICAgICAgICAgICAgICAgJGF1dGhvcl9uYW1lID0gJF9TRVJWRVJbJ0NPTVBPU0VSX0RFRkFVTFRfQVVUSE9SJ107CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkZ2l0Wyd1c2VyLm5hbWUnXSkpIHsKICAgICAgICAgICAgICAgICRhdXRob3JfbmFtZSA9ICRnaXRbJ3VzZXIubmFtZSddOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRfU0VSVkVSWydDT01QT1NFUl9ERUZBVUxUX0VNQUlMJ10pKSB7CiAgICAgICAgICAgICAgICAkYXV0aG9yX2VtYWlsID0gJF9TRVJWRVJbJ0NPTVBPU0VSX0RFRkFVTFRfRU1BSUwnXTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRnaXRbJ3VzZXIuZW1haWwnXSkpIHsKICAgICAgICAgICAgICAgICRhdXRob3JfZW1haWwgPSAkZ2l0Wyd1c2VyLmVtYWlsJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc3NldCgkYXV0aG9yX25hbWUsICRhdXRob3JfZW1haWwpKSB7CiAgICAgICAgICAgICAgICAkYXV0aG9yID0gc3ByaW50ZignJXMgPCVzPicsICRhdXRob3JfbmFtZSwgJGF1dGhvcl9lbWFpbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzZWxmID0gJHRoaXM7CiAgICAgICAgJGF1dGhvciA9ICRpby0+YXNrQW5kVmFsaWRhdGUoCiAgICAgICAgICAgICdBdXRob3IgWzxjb21tZW50PicuJGF1dGhvci4nPC9jb21tZW50PiwgbiB0byBza2lwXTogJywKICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWx1ZSkgdXNlICgkc2VsZiwgJGF1dGhvcikgewogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJ24nIHx8ICR2YWx1ZSA9PT0gJ25vJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR2YWx1ZSA/OiAkYXV0aG9yOwogICAgICAgICAgICAgICAgJGF1dGhvciA9ICRzZWxmLT5wYXJzZUF1dGhvclN0cmluZygkdmFsdWUpOwoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCclcyA8JXM+JywgJGF1dGhvclsnbmFtZSddLCAkYXV0aG9yWydlbWFpbCddKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgJGF1dGhvcgogICAgICAgICk7CiAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ2F1dGhvcicsICRhdXRob3IpOwoKICAgICAgICAkbWluaW11bVN0YWJpbGl0eSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdzdGFiaWxpdHknKSA/OiBudWxsOwogICAgICAgICRtaW5pbXVtU3RhYmlsaXR5ID0gJGlvLT5hc2tBbmRWYWxpZGF0ZSgKICAgICAgICAgICAgJ01pbmltdW0gU3RhYmlsaXR5IFs8Y29tbWVudD4nLiRtaW5pbXVtU3RhYmlsaXR5Lic8L2NvbW1lbnQ+XTogJywKICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWx1ZSkgdXNlICgkbWluaW11bVN0YWJpbGl0eSkgewogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkbWluaW11bVN0YWJpbGl0eTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXNbJHZhbHVlXSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgJ0ludmFsaWQgbWluaW11bSBzdGFiaWxpdHkgIicuJHZhbHVlLiciLiBNdXN0IGJlIGVtcHR5IG9yIG9uZSBvZjogJy4KICAgICAgICAgICAgICAgICAgICAgICAgaW1wbG9kZSgnLCAnLCBhcnJheV9rZXlzKEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMpKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgJG1pbmltdW1TdGFiaWxpdHkKICAgICAgICApOwogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdzdGFiaWxpdHknLCAkbWluaW11bVN0YWJpbGl0eSk7CgogICAgICAgICR0eXBlID0gJGlucHV0LT5nZXRPcHRpb24oJ3R5cGUnKSA/OiBmYWxzZTsKICAgICAgICAkdHlwZSA9ICRpby0+YXNrKAogICAgICAgICAgICAnUGFja2FnZSBUeXBlIChlLmcuIGxpYnJhcnksIHByb2plY3QsIG1ldGFwYWNrYWdlLCBjb21wb3Nlci1wbHVnaW4pIFs8Y29tbWVudD4nLiR0eXBlLic8L2NvbW1lbnQ+XTogJywKICAgICAgICAgICAgJHR5cGUKICAgICAgICApOwogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCd0eXBlJywgJHR5cGUpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJGxpY2Vuc2UgPSAkaW5wdXQtPmdldE9wdGlvbignbGljZW5zZScpKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJF9TRVJWRVJbJ0NPTVBPU0VSX0RFRkFVTFRfTElDRU5TRSddKSkgewogICAgICAgICAgICAgICAgJGxpY2Vuc2UgPSAkX1NFUlZFUlsnQ09NUE9TRVJfREVGQVVMVF9MSUNFTlNFJ107CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRsaWNlbnNlID0gJGlvLT5hc2soCiAgICAgICAgICAgICdMaWNlbnNlIFs8Y29tbWVudD4nLiRsaWNlbnNlLic8L2NvbW1lbnQ+XTogJywKICAgICAgICAgICAgJGxpY2Vuc2UKICAgICAgICApOwogICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdsaWNlbnNlJywgJGxpY2Vuc2UpOwoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoYXJyYXkoJycsICdEZWZpbmUgeW91ciBkZXBlbmRlbmNpZXMuJywgJycpKTsKCiAgICAgICAgLy8gcHJlcGFyZSB0byByZXNvbHZlIGRlcGVuZGVuY2llcwogICAgICAgICRyZXBvcyA9ICR0aGlzLT5nZXRSZXBvcygpOwogICAgICAgICRwcmVmZXJyZWRTdGFiaWxpdHkgPSAkbWluaW11bVN0YWJpbGl0eSA/OiAnc3RhYmxlJzsKICAgICAgICAkcGxhdGZvcm1SZXBvID0gbnVsbDsKICAgICAgICBpZiAoJHJlcG9zIGluc3RhbmNlb2YgQ29tcG9zaXRlUmVwb3NpdG9yeSkgewogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3MtPmdldFJlcG9zaXRvcmllcygpIGFzICRjYW5kaWRhdGVSZXBvKSB7CiAgICAgICAgICAgICAgICBpZiAoJGNhbmRpZGF0ZVJlcG8gaW5zdGFuY2VvZiBQbGF0Zm9ybVJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgICAgICAgICAkcGxhdGZvcm1SZXBvID0gJGNhbmRpZGF0ZVJlcG87CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRxdWVzdGlvbiA9ICdXb3VsZCB5b3UgbGlrZSB0byBkZWZpbmUgeW91ciBkZXBlbmRlbmNpZXMgKHJlcXVpcmUpIGludGVyYWN0aXZlbHkgWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnOwogICAgICAgICRyZXF1aXJlID0gJGlucHV0LT5nZXRPcHRpb24oJ3JlcXVpcmUnKTsKICAgICAgICAkcmVxdWlyZW1lbnRzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHJlcXVpcmUgfHwgJGlvLT5hc2tDb25maXJtYXRpb24oJHF1ZXN0aW9uKSkgewogICAgICAgICAgICAkcmVxdWlyZW1lbnRzID0gJHRoaXMtPmRldGVybWluZVJlcXVpcmVtZW50cygkaW5wdXQsICRvdXRwdXQsICRyZXF1aXJlLCAkcGxhdGZvcm1SZXBvLCAkcHJlZmVycmVkU3RhYmlsaXR5KTsKICAgICAgICB9CiAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ3JlcXVpcmUnLCAkcmVxdWlyZW1lbnRzKTsKCiAgICAgICAgJHF1ZXN0aW9uID0gJ1dvdWxkIHlvdSBsaWtlIHRvIGRlZmluZSB5b3VyIGRldiBkZXBlbmRlbmNpZXMgKHJlcXVpcmUtZGV2KSBpbnRlcmFjdGl2ZWx5IFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJzsKICAgICAgICAkcmVxdWlyZURldiA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdyZXF1aXJlLWRldicpOwogICAgICAgICRkZXZSZXF1aXJlbWVudHMgPSBhcnJheSgpOwogICAgICAgIGlmICgkcmVxdWlyZURldiB8fCAkaW8tPmFza0NvbmZpcm1hdGlvbigkcXVlc3Rpb24pKSB7CiAgICAgICAgICAgICRkZXZSZXF1aXJlbWVudHMgPSAkdGhpcy0+ZGV0ZXJtaW5lUmVxdWlyZW1lbnRzKCRpbnB1dCwgJG91dHB1dCwgJHJlcXVpcmVEZXYsICRwbGF0Zm9ybVJlcG8sICRwcmVmZXJyZWRTdGFiaWxpdHkpOwogICAgICAgIH0KICAgICAgICAkaW5wdXQtPnNldE9wdGlvbigncmVxdWlyZS1kZXYnLCAkZGV2UmVxdWlyZW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwcml2YXRlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkYXV0aG9yCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUF1dGhvclN0cmluZygkYXV0aG9yKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXig/UDxuYW1lPlstIC4sXHB7TH1ccHtOfVxwe01ufVwn4oCZIigpXSspIDwoP1A8ZW1haWw+Lis/KT4kL3UnLCAkYXV0aG9yLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aXNWYWxpZEVtYWlsKCRtYXRjaFsnZW1haWwnXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gdHJpbSgkbWF0Y2hbJ25hbWUnXSksCiAgICAgICAgICAgICAgICAgICAgJ2VtYWlsJyA9PiAkbWF0Y2hbJ2VtYWlsJ10sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgJ0ludmFsaWQgYXV0aG9yIHN0cmluZy4gIE11c3QgYmUgaW4gdGhlIGZvcm1hdDogJy4KICAgICAgICAgICAgJ0pvaG4gU21pdGggPGpvaG5AZXhhbXBsZS5jb20+JwogICAgICAgICk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbmRQYWNrYWdlcygkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFJlcG9zKCktPnNlYXJjaCgkbmFtZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFJlcG9zKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5yZXBvcykgewogICAgICAgICAgICAkdGhpcy0+cmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgIGFycmF5KG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkpLAogICAgICAgICAgICAgICAgUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcygkdGhpcy0+Z2V0SU8oKSkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9zOwogICAgfQoKICAgIGZpbmFsIHByb3RlY3RlZCBmdW5jdGlvbiBkZXRlcm1pbmVSZXF1aXJlbWVudHMoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJHJlcXVpcmVzID0gYXJyYXkoKSwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gPSBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJ3N0YWJsZScsICRjaGVja1Byb3ZpZGVkVmVyc2lvbnMgPSB0cnVlLCAkZml4ZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHJlcXVpcmVzKSB7CiAgICAgICAgICAgICRyZXF1aXJlcyA9ICR0aGlzLT5ub3JtYWxpemVSZXF1aXJlbWVudHMoJHJlcXVpcmVzKTsKICAgICAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVzIGFzICRyZXF1aXJlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGhlIGJlc3QgdmVyc2lvbiBhdXRvbWF0aWNhbGx5CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJHZlcnNpb24pID0gJHRoaXMtPmZpbmRCZXN0VmVyc2lvbkFuZE5hbWVGb3JQYWNrYWdlKCRpbnB1dCwgJHJlcXVpcmVtZW50WyduYW1lJ10sICRwbGF0Zm9ybVJlcG8sICRwcmVmZXJyZWRTdGFiaWxpdHksIG51bGwsIG51bGwsICRmaXhlZCk7CiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50Wyd2ZXJzaW9uJ10gPSAkdmVyc2lvbjsKCiAgICAgICAgICAgICAgICAgICAgLy8gcmVwbGFjZSBwYWNrYWdlIG5hbWUgZnJvbSBwYWNrYWdpc3Qub3JnCiAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50WyduYW1lJ10gPSAkbmFtZTsKCiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICdVc2luZyB2ZXJzaW9uIDxpbmZvPiVzPC9pbmZvPiBmb3IgPGluZm8+JXM8L2luZm8+JywKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVtZW50Wyd2ZXJzaW9uJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlbWVudFsnbmFtZSddCiAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgdGhlIHNwZWNpZmllZCB2ZXJzaW9uL2NvbnN0cmFpbnQgZXhpc3RzIGJlZm9yZSB3ZSBwcm9jZWVkCiAgICAgICAgICAgICAgICAgICAgbGlzdCgkbmFtZSkgPSAkdGhpcy0+ZmluZEJlc3RWZXJzaW9uQW5kTmFtZUZvclBhY2thZ2UoJGlucHV0LCAkcmVxdWlyZW1lbnRbJ25hbWUnXSwgJHBsYXRmb3JtUmVwbywgJHByZWZlcnJlZFN0YWJpbGl0eSwgJGNoZWNrUHJvdmlkZWRWZXJzaW9ucyA/ICRyZXF1aXJlbWVudFsndmVyc2lvbiddIDogbnVsbCwgJ2RldicsICRmaXhlZCk7CgogICAgICAgICAgICAgICAgICAgIC8vIHJlcGxhY2UgcGFja2FnZSBuYW1lIGZyb20gcGFja2FnaXN0Lm9yZwogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlbWVudFsnbmFtZSddID0gJG5hbWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gJHJlcXVpcmVtZW50WyduYW1lJ10gLiAnICcgLiAkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CgogICAgICAgIC8vIENvbGxlY3QgZXhpc3RpbmcgcGFja2FnZXMKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoZmFsc2UpOwogICAgICAgICRpbnN0YWxsZWRSZXBvID0gJGNvbXBvc2VyID8gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSA6IG51bGw7CiAgICAgICAgJGV4aXN0aW5nUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGlmICgkaW5zdGFsbGVkUmVwbykgewogICAgICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJGV4aXN0aW5nUGFja2FnZXNbXSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdW5zZXQoJGNvbXBvc2VyLCAkaW5zdGFsbGVkUmVwbyk7CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIHdoaWxlIChudWxsICE9PSAkcGFja2FnZSA9ICRpby0+YXNrKCdTZWFyY2ggZm9yIGEgcGFja2FnZTogJykpIHsKICAgICAgICAgICAgJG1hdGNoZXMgPSAkdGhpcy0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlKTsKCiAgICAgICAgICAgIGlmIChjb3VudCgkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBwYWNrYWdlcyBmcm9tIHNlYXJjaCByZXN1bHRzLgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXMgYXMgJHBvc2l0aW9uID0+ICRmb3VuZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJGZvdW5kUGFja2FnZVsnbmFtZSddLCAkZXhpc3RpbmdQYWNrYWdlcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJG1hdGNoZXNbJHBvc2l0aW9uXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1hdGNoZXMgPSBhcnJheV92YWx1ZXMoJG1hdGNoZXMpOwoKICAgICAgICAgICAgICAgICRleGFjdE1hdGNoID0gbnVsbDsKICAgICAgICAgICAgICAgICRjaG9pY2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzIGFzICRwb3NpdGlvbiA9PiAkZm91bmRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGFiYW5kb25lZCA9ICcnOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZm91bmRQYWNrYWdlWydhYmFuZG9uZWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkZm91bmRQYWNrYWdlWydhYmFuZG9uZWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXBsYWNlbWVudCA9IHNwcmludGYoJ1VzZSAlcyBpbnN0ZWFkJywgJGZvdW5kUGFja2FnZVsnYWJhbmRvbmVkJ10pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50ID0gJ05vIHJlcGxhY2VtZW50IHdhcyBzdWdnZXN0ZWQnOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRhYmFuZG9uZWQgPSBzcHJpbnRmKCc8d2FybmluZz5BYmFuZG9uZWQuICVzLjwvd2FybmluZz4nLCAkcmVwbGFjZW1lbnQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGNob2ljZXNbXSA9IHNwcmludGYoJyA8aW5mbz4lNXM8L2luZm8+ICVzICVzJywgIlskcG9zaXRpb25dIiwgJGZvdW5kUGFja2FnZVsnbmFtZSddLCAkYWJhbmRvbmVkKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGZvdW5kUGFja2FnZVsnbmFtZSddID09PSAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXhhY3RNYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBubyBtYXRjaCwgcHJvbXB0IHdoaWNoIHRvIHBpY2sKICAgICAgICAgICAgICAgIGlmICghJGV4YWN0TWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICcnLAogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCdGb3VuZCA8aW5mbz4lczwvaW5mbz4gcGFja2FnZXMgbWF0Y2hpbmcgPGluZm8+JXM8L2luZm8+JywgY291bnQoJG1hdGNoZXMpLCAkcGFja2FnZSksCiAgICAgICAgICAgICAgICAgICAgICAgICcnLAogICAgICAgICAgICAgICAgICAgICkpOwoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJGNob2ljZXMpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignJyk7CgogICAgICAgICAgICAgICAgICAgICR2YWxpZGF0b3IgPSBmdW5jdGlvbiAoJHNlbGVjdGlvbikgdXNlICgkbWF0Y2hlcywgJHZlcnNpb25QYXJzZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCcnID09PSAkc2VsZWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19udW1lcmljKCRzZWxlY3Rpb24pICYmIGlzc2V0KCRtYXRjaGVzWyhpbnQpICRzZWxlY3Rpb25dKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkbWF0Y2hlc1soaW50KSAkc2VsZWN0aW9uXTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2VbJ25hbWUnXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teXHMqKD9QPG5hbWU+W1xTL10rKSg/OlxzKyg/UDx2ZXJzaW9uPlxTKykpP1xzKiR9JywgJHNlbGVjdGlvbiwgJHBhY2thZ2VNYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlTWF0Y2hlc1sndmVyc2lvbiddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhcnNpbmcgYGFjbWUvZXhhbXBsZSB+Mi4zYAoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSB2ZXJzaW9uIGNvbnN0cmFpbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkcGFja2FnZU1hdGNoZXNbJ3ZlcnNpb24nXSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZU1hdGNoZXNbJ25hbWUnXS4nICcuJHBhY2thZ2VNYXRjaGVzWyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2luZyBgYWNtZS9leGFtcGxlYAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlTWF0Y2hlc1snbmFtZSddOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbignTm90IGEgdmFsaWQgc2VsZWN0aW9uJyk7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkaW8tPmFza0FuZFZhbGlkYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAnRW50ZXIgcGFja2FnZSAjIHRvIGFkZCwgb3IgdGhlIGNvbXBsZXRlIHBhY2thZ2UgbmFtZSBpZiBpdCBpcyBub3QgbGlzdGVkOiAnLAogICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRhdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAzLAogICAgICAgICAgICAgICAgICAgICAgICBmYWxzZQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbm8gY29uc3RyYWludCB5ZXQsIGRldGVybWluZSB0aGUgYmVzdCB2ZXJzaW9uIGF1dG9tYXRpY2FsbHkKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJHBhY2thZ2UgJiYgZmFsc2UgPT09IHN0cnBvcygkcGFja2FnZSwgJyAnKSkgewogICAgICAgICAgICAgICAgICAgICR2YWxpZGF0b3IgPSBmdW5jdGlvbiAoJGlucHV0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dCA9IHRyaW0oJGlucHV0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkaW5wdXQgPzogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkaW8tPmFza0FuZFZhbGlkYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAnRW50ZXIgdGhlIHZlcnNpb24gY29uc3RyYWludCB0byByZXF1aXJlIChvciBsZWF2ZSBibGFuayB0byB1c2UgdGhlIGxhdGVzdCB2ZXJzaW9uKTogJywKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbGlkYXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgMywKICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoLCAkY29uc3RyYWludCkgPSAkdGhpcy0+ZmluZEJlc3RWZXJzaW9uQW5kTmFtZUZvclBhY2thZ2UoJGlucHV0LCAkcGFja2FnZSwgJHBsYXRmb3JtUmVwbywgJHByZWZlcnJlZFN0YWJpbGl0eSk7CgogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVc2luZyB2ZXJzaW9uIDxpbmZvPiVzPC9pbmZvPiBmb3IgPGluZm8+JXM8L2luZm8+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UKICAgICAgICAgICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSAuPSAnICcuJGNvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlc1tdID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgJGV4aXN0aW5nUGFja2FnZXNbXSA9IHN1YnN0cigkcGFja2FnZSwgMCwgc3RycG9zKCRwYWNrYWdlLCAnICcpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXF1aXJlczsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZm9ybWF0QXV0aG9ycygkYXV0aG9yKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgkdGhpcy0+cGFyc2VBdXRob3JTdHJpbmcoJGF1dGhvcikpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRHaXRDb25maWcoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+Z2l0Q29uZmlnKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2l0Q29uZmlnOwogICAgICAgIH0KCiAgICAgICAgJGZpbmRlciA9IG5ldyBFeGVjdXRhYmxlRmluZGVyKCk7CiAgICAgICAgJGdpdEJpbiA9ICRmaW5kZXItPmZpbmQoJ2dpdCcpOwoKICAgICAgICAvLyBUT0RPIGluIHYzIGFsd2F5cyBjYWxsIHdpdGggYW4gYXJyYXkKICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygnU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQcm9jZXNzJywgJ2Zyb21TaGVsbENvbW1hbmRsaW5lJykpIHsKICAgICAgICAgICAgJGNtZCA9IG5ldyBQcm9jZXNzKGFycmF5KCRnaXRCaW4sICdjb25maWcnLCAnLWwnKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNtZCA9IG5ldyBQcm9jZXNzKHNwcmludGYoJyVzIGNvbmZpZyAtbCcsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRnaXRCaW4pKSk7CiAgICAgICAgfQogICAgICAgICRjbWQtPnJ1bigpOwoKICAgICAgICBpZiAoJGNtZC0+aXNTdWNjZXNzZnVsKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmdpdENvbmZpZyA9IGFycmF5KCk7CiAgICAgICAgICAgIHByZWdfbWF0Y2hfYWxsKCd7XihbXj1dKyk9KC4qKSR9bScsICRjbWQtPmdldE91dHB1dCgpLCAkbWF0Y2hlcywgUFJFR19TRVRfT1JERVIpOwogICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5naXRDb25maWdbJG1hdGNoWzFdXSA9ICRtYXRjaFsyXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5naXRDb25maWc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmdpdENvbmZpZyA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhlIGxvY2FsIC5naXRpZ25vcmUgZmlsZSBmb3IgdGhlIENvbXBvc2VyIHZlbmRvciBkaXJlY3RvcnkuCiAgICAgKgogICAgICogVGVzdGVkIHBhdHRlcm5zIGluY2x1ZGU6CiAgICAgKiAgIi8kdmVuZG9yIgogICAgICogICIkdmVuZG9yIgogICAgICogICIkdmVuZG9yLyIKICAgICAqICAiLyR2ZW5kb3IvIgogICAgICogICIvJHZlbmRvci8qIgogICAgICogICIkdmVuZG9yLyoiCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWdub3JlRmlsZQogICAgICogQHBhcmFtIHN0cmluZyAkdmVuZG9yCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUsICR2ZW5kb3IgPSAndmVuZG9yJykKICAgIHsKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRpZ25vcmVGaWxlKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkcGF0dGVybiA9IHNwcmludGYoJ3teLz8lcygvXCo/KT8kfScsIHByZWdfcXVvdGUoJHZlbmRvcikpOwoKICAgICAgICAkbGluZXMgPSBmaWxlKCRpZ25vcmVGaWxlLCBGSUxFX0lHTk9SRV9ORVdfTElORVMpOwogICAgICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkbGluZSkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcGF0dGVybiwgJGxpbmUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRWZW5kb3JJZ25vcmUoJGlnbm9yZUZpbGUsICR2ZW5kb3IgPSAnL3ZlbmRvci8nKQogICAgewogICAgICAgICRjb250ZW50cyA9ICIiOwogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaWdub3JlRmlsZSkpIHsKICAgICAgICAgICAgJGNvbnRlbnRzID0gZmlsZV9nZXRfY29udGVudHMoJGlnbm9yZUZpbGUpOwoKICAgICAgICAgICAgaWYgKHN0cnBvcygkY29udGVudHMsICJcbiIpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAkY29udGVudHMgLj0gIlxuIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGlnbm9yZUZpbGUsICRjb250ZW50cyAuICR2ZW5kb3IuICJcbiIpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc1ZhbGlkRW1haWwoJGVtYWlsKQogICAgewogICAgICAgIC8vIGFzc3VtZSBpdCdzIHZhbGlkIGlmIHdlIGNhbid0IHZhbGlkYXRlIGl0CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2ZpbHRlcl92YXInKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIHBocCA8NS4zLjMgaGFzIGEgdmVyeSBicm9rZW4gZW1haWwgdmFsaWRhdG9yLCBzbyBieXBhc3MgY2hlY2tzCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTAzMDMpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2UgIT09IGZpbHRlcl92YXIoJGVtYWlsLCBGSUxURVJfVkFMSURBVEVfRU1BSUwpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeVNldChJbnB1dEludGVyZmFjZSAkaW5wdXQsICRtaW5pbXVtU3RhYmlsaXR5ID0gbnVsbCkKICAgIHsKICAgICAgICAka2V5ID0gJG1pbmltdW1TdGFiaWxpdHkgPzogJ2RlZmF1bHQnOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5yZXBvc2l0b3J5U2V0c1ska2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlTZXRzWyRrZXldID0gJHJlcG9zaXRvcnlTZXQgPSBuZXcgUmVwb3NpdG9yeVNldCgkbWluaW11bVN0YWJpbGl0eSA/OiAkdGhpcy0+Z2V0TWluaW11bVN0YWJpbGl0eSgkaW5wdXQpKTsKICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoJHRoaXMtPmdldFJlcG9zKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3J5U2V0c1ska2V5XTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldE1pbmltdW1TdGFiaWxpdHkoSW5wdXRJbnRlcmZhY2UgJGlucHV0KQogICAgewogICAgICAgIGlmICgkaW5wdXQtPmhhc09wdGlvbignc3RhYmlsaXR5JykpIHsKICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkaW5wdXQtPmdldE9wdGlvbignc3RhYmlsaXR5JykgPzogJ3N0YWJsZScpOwogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSBGYWN0b3J5OjpnZXRDb21wb3NlckZpbGUoKTsKICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkgJiYgaXNfcmVhZGFibGUoJGZpbGUpICYmIGlzX2FycmF5KCRjb21wb3NlciA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKSwgdHJ1ZSkpKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGNvbXBvc2VyWydtaW5pbXVtLXN0YWJpbGl0eSddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkY29tcG9zZXJbJ21pbmltdW0tc3RhYmlsaXR5J10pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3N0YWJsZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIHBhY2thZ2UgbmFtZSwgdGhpcyBkZXRlcm1pbmVzIHRoZSBiZXN0IHZlcnNpb24gdG8gdXNlIGluIHRoZSByZXF1aXJlIGtleS4KICAgICAqCiAgICAgKiBUaGlzIHJldHVybnMgYSB2ZXJzaW9uIHdpdGggdGhlIH4gb3BlcmF0b3IgcHJlZml4ZWQgd2hlbiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIElucHV0SW50ZXJmYWNlICAgICAgICAgICAgJGlucHV0CiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJG5hbWUKICAgICAqIEBwYXJhbSAgUGxhdGZvcm1SZXBvc2l0b3J5fG51bGwgICAkcGxhdGZvcm1SZXBvCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHByZWZlcnJlZFN0YWJpbGl0eQogICAgICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICAgICAgICAgICAgICRyZXF1aXJlZFZlcnNpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkbWluaW11bVN0YWJpbGl0eQogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAgICAgICAgICRmaXhlZAogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGFycmF5ICAgICAgICAgICAgICAgICAgICAgbmFtZSB2ZXJzaW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZEJlc3RWZXJzaW9uQW5kTmFtZUZvclBhY2thZ2UoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCAkbmFtZSwgUGxhdGZvcm1SZXBvc2l0b3J5ICRwbGF0Zm9ybVJlcG8gPSBudWxsLCAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJ3N0YWJsZScsICRyZXF1aXJlZFZlcnNpb24gPSBudWxsLCAkbWluaW11bVN0YWJpbGl0eSA9IG51bGwsICRmaXhlZCA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gaGFuZGxlIGlnbm9yZS1wbGF0Zm9ybS1yZXFzIGZsYWcgaWYgcHJlc2VudAogICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSBmYWxzZTsKICAgICAgICBpZiAoJGlucHV0LT5oYXNPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgJiYgJGlucHV0LT5oYXNPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnKSkgewogICAgICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gZmluZCB0aGUgbGF0ZXN0IHZlcnNpb24gYWxsb3dlZCBpbiB0aGlzIHJlcG8gc2V0CiAgICAgICAgJHZlcnNpb25TZWxlY3RvciA9IG5ldyBWZXJzaW9uU2VsZWN0b3IoJHRoaXMtPmdldFJlcG9zaXRvcnlTZXQoJGlucHV0LCAkbWluaW11bVN0YWJpbGl0eSksICRwbGF0Zm9ybVJlcG8pOwoKICAgICAgICAkcGFja2FnZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcmVxdWlyZWRWZXJzaW9uLCAkcHJlZmVycmVkU3RhYmlsaXR5LCAkaWdub3JlUGxhdGZvcm1SZXFzKTsKCiAgICAgICAgaWYgKCEkcGFja2FnZSkgewogICAgICAgICAgICAvLyBwbGF0Zm9ybSBwYWNrYWdlcyBjYW4gbm90IGJlIGZvdW5kIGluIHRoZSBwb29sIGluIHZlcnNpb25zIG90aGVyIHRoYW4gdGhlIGxvY2FsIHBsYXRmb3JtJ3MgaGFzCiAgICAgICAgICAgIC8vIHNvIGlmIHBsYXRmb3JtIHJlcXMgYXJlIGlnbm9yZWQgd2UganVzdCB0YWtlIHRoZSB1c2VyJ3Mgd29yZCBmb3IgaXQKICAgICAgICAgICAgaWYgKCh0cnVlID09PSAkaWdub3JlUGxhdGZvcm1SZXFzIHx8IChpc19hcnJheSgkaWdub3JlUGxhdGZvcm1SZXFzKSAmJiBpbl9hcnJheSgkbmFtZSwgJGlnbm9yZVBsYXRmb3JtUmVxcykpKSAmJiBQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRuYW1lLCAkcmVxdWlyZWRWZXJzaW9uID86ICcqJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIFBIUCB2ZXJzaW9uIHdhcyB0aGUgcHJvYmxlbQogICAgICAgICAgICBpZiAodHJ1ZSAhPT0gJGlnbm9yZVBsYXRmb3JtUmVxcyAmJiAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHJlcXVpcmVkVmVyc2lvbiwgJHByZWZlcnJlZFN0YWJpbGl0eSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ1BhY2thZ2UgJXMlcyBoYXMgYSBQSFAgcmVxdWlyZW1lbnQgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQSFAgdmVyc2lvbiwgUEhQIGV4dGVuc2lvbnMgYW5kIENvbXBvc2VyIHZlcnNpb24nLAogICAgICAgICAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlZFZlcnNpb24gPyAnIGF0IHZlcnNpb24gJy4kcmVxdWlyZWRWZXJzaW9uIDogJycKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIG1pbmltdW0gc3RhYmlsaXR5IHdhcyB0aGUgcHJvYmxlbSBidXQgdGhlIHBhY2thZ2UgZXhpc3RzCiAgICAgICAgICAgIGlmICgkcGFja2FnZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcmVxdWlyZWRWZXJzaW9uLCAkcHJlZmVycmVkU3RhYmlsaXR5LCAkaWdub3JlUGxhdGZvcm1SZXFzLCBSZXBvc2l0b3J5U2V0OjpBTExPV19VTkFDQ0VQVEFCTEVfU1RBQklMSVRJRVMpKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBtdXN0IGZpcnN0IHZlcmlmeSBpZiBhIHZhbGlkIHBhY2thZ2Ugd291bGQgYmUgZm91bmQgaW4gYSBsb3dlciBwcmlvcml0eSByZXBvc2l0b3J5CiAgICAgICAgICAgICAgICBpZiAoJGFsbFJlcG9zUGFja2FnZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcmVxdWlyZWRWZXJzaW9uLCAkcHJlZmVycmVkU3RhYmlsaXR5LCAkaWdub3JlUGxhdGZvcm1SZXFzLCBSZXBvc2l0b3J5U2V0OjpBTExPV19TSEFET1dFRF9SRVBPU0lUT1JJRVMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdQYWNrYWdlICcuJG5hbWUuJyBleGlzdHMgaW4gJy4kYWxsUmVwb3NQYWNrYWdlLT5nZXRSZXBvc2l0b3J5KCktPmdldFJlcG9OYW1lKCkuJyBhbmQgJy4kcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgd2hpY2ggaGFzIGEgaGlnaGVyIHJlcG9zaXRvcnkgcHJpb3JpdHkuIFRoZSBwYWNrYWdlcyB3aXRoIGhpZ2hlciBwcmlvcml0eSBkbyBub3QgbWF0Y2ggeW91ciBtaW5pbXVtLXN0YWJpbGl0eSBhbmQgYXJlIHRoZXJlZm9yZSBub3QgaW5zdGFsbGFibGUuIFNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9yZXBvcHJpbyBmb3IgZGV0YWlscyBhbmQgYXNzaXN0YW5jZS4nCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdDb3VsZCBub3QgZmluZCBhIHZlcnNpb24gb2YgcGFja2FnZSAlcyBtYXRjaGluZyB5b3VyIG1pbmltdW0tc3RhYmlsaXR5ICglcykuIFJlcXVpcmUgaXQgd2l0aCBhbiBleHBsaWNpdCB2ZXJzaW9uIGNvbnN0cmFpbnQgYWxsb3dpbmcgaXRzIGRlc2lyZWQgc3RhYmlsaXR5LicsCiAgICAgICAgICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmdldE1pbmltdW1TdGFiaWxpdHkoJGlucHV0KQogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgcmVxdWlyZWQgdmVyc2lvbiB3YXMgdGhlIHByb2JsZW0KICAgICAgICAgICAgaWYgKCRyZXF1aXJlZFZlcnNpb24gJiYgJHBhY2thZ2UgPSAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgbnVsbCwgJHByZWZlcnJlZFN0YWJpbGl0eSwgJGlnbm9yZVBsYXRmb3JtUmVxcykpIHsKICAgICAgICAgICAgICAgIC8vIHdlIG11c3QgZmlyc3QgdmVyaWZ5IGlmIGEgdmFsaWQgcGFja2FnZSB3b3VsZCBiZSBmb3VuZCBpbiBhIGxvd2VyIHByaW9yaXR5IHJlcG9zaXRvcnkKICAgICAgICAgICAgICAgIGlmICgkYWxsUmVwb3NQYWNrYWdlID0gJHZlcnNpb25TZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoJG5hbWUsICRyZXF1aXJlZFZlcnNpb24sICRwcmVmZXJyZWRTdGFiaWxpdHksIGZhbHNlLCBSZXBvc2l0b3J5U2V0OjpBTExPV19TSEFET1dFRF9SRVBPU0lUT1JJRVMpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdQYWNrYWdlICcuJG5hbWUuJyBleGlzdHMgaW4gJy4kYWxsUmVwb3NQYWNrYWdlLT5nZXRSZXBvc2l0b3J5KCktPmdldFJlcG9OYW1lKCkuJyBhbmQgJy4kcGFja2FnZS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgd2hpY2ggaGFzIGEgaGlnaGVyIHJlcG9zaXRvcnkgcHJpb3JpdHkuIFRoZSBwYWNrYWdlcyB3aXRoIGhpZ2hlciBwcmlvcml0eSBkbyBub3QgbWF0Y2ggeW91ciBjb25zdHJhaW50IGFuZCBhcmUgdGhlcmVmb3JlIG5vdCBpbnN0YWxsYWJsZS4gU2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL3JlcG9wcmlvIGZvciBkZXRhaWxzIGFuZCBhc3Npc3RhbmNlLicKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIHBhY2thZ2UgJXMgaW4gYSB2ZXJzaW9uIG1hdGNoaW5nICVzJywKICAgICAgICAgICAgICAgICAgICAkbmFtZSwKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZWRWZXJzaW9uCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBQSFAgdmVyc2lvbiB3YXMgdGhlIHByb2JsZW0gZm9yIGFsbCB2ZXJzaW9ucwogICAgICAgICAgICBpZiAodHJ1ZSAhPT0gJGlnbm9yZVBsYXRmb3JtUmVxcyAmJiAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgbnVsbCwgJHByZWZlcnJlZFN0YWJpbGl0eSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIHBhY2thZ2UgJXMgaW4gYW55IHZlcnNpb24gbWF0Y2hpbmcgeW91ciBQSFAgdmVyc2lvbiwgUEhQIGV4dGVuc2lvbnMgYW5kIENvbXBvc2VyIHZlcnNpb24nLAogICAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHNpbWlsYXIgbmFtZXMvdHlwb3MKICAgICAgICAgICAgJHNpbWlsYXIgPSAkdGhpcy0+ZmluZFNpbWlsYXIoJG5hbWUpOwogICAgICAgICAgICBpZiAoJHNpbWlsYXIpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBmaW5kIHBhY2thZ2UgJXMuXG5cbkRpZCB5b3UgbWVhbiAiIC4gKGNvdW50KCRzaW1pbGFyKSA+IDEgPyAnb25lIG9mIHRoZXNlJyA6ICd0aGlzJykgLiAiP1xuICAgICVzIiwKICAgICAgICAgICAgICAgICAgICAkbmFtZSwKICAgICAgICAgICAgICAgICAgICBpbXBsb2RlKCJcbiAgICAiLCAkc2ltaWxhcikKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIGEgbWF0Y2hpbmcgdmVyc2lvbiBvZiBwYWNrYWdlICVzLiBDaGVjayB0aGUgcGFja2FnZSBzcGVsbGluZywgeW91ciB2ZXJzaW9uIGNvbnN0cmFpbnQgYW5kIHRoYXQgdGhlIHBhY2thZ2UgaXMgYXZhaWxhYmxlIGluIGEgc3RhYmlsaXR5IHdoaWNoIG1hdGNoZXMgeW91ciBtaW5pbXVtLXN0YWJpbGl0eSAoJXMpLicsCiAgICAgICAgICAgICAgICAkbmFtZSwKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCRpbnB1dCkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICRmaXhlZCA/ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgOiAkdmVyc2lvblNlbGVjdG9yLT5maW5kUmVjb21tZW5kZWRSZXF1aXJlVmVyc2lvbigkcGFja2FnZSksCiAgICAgICAgKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbmRTaW1pbGFyKCRwYWNrYWdlKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXN1bHRzID0gJHRoaXMtPnJlcG9zLT5zZWFyY2goJHBhY2thZ2UpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gaWdub3JlIHNlYXJjaCBlcnJvcnMKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQogICAgICAgICRzaW1pbGFyUGFja2FnZXMgPSBhcnJheSgpOwoKICAgICAgICAkaW5zdGFsbGVkUmVwbyA9ICR0aGlzLT5nZXRDb21wb3NlcigpLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICBpZiAoJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlKCRyZXN1bHRbJ25hbWUnXSwgJyonKSkgewogICAgICAgICAgICAgICAgLy8gSWdub3JlIGluc3RhbGxlZCBwYWNrYWdlCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc2ltaWxhclBhY2thZ2VzWyRyZXN1bHRbJ25hbWUnXV0gPSBsZXZlbnNodGVpbigkcGFja2FnZSwgJHJlc3VsdFsnbmFtZSddKTsKICAgICAgICB9CiAgICAgICAgYXNvcnQoJHNpbWlsYXJQYWNrYWdlcyk7CgogICAgICAgIHJldHVybiBhcnJheV9rZXlzKGFycmF5X3NsaWNlKCRzaW1pbGFyUGFja2FnZXMsIDAsIDUpKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVwZGF0ZURlcGVuZGVuY2llcygkb3V0cHV0KQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR1cGRhdGVDb21tYW5kID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPmZpbmQoJ3VwZGF0ZScpOwogICAgICAgICAgICAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+cmVzZXRDb21wb3NlcigpOwogICAgICAgICAgICAkdXBkYXRlQ29tbWFuZC0+cnVuKG5ldyBBcnJheUlucHV0KGFycmF5KCkpLCAkb3V0cHV0KTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCdDb3VsZCBub3QgdXBkYXRlIGRlcGVuZGVuY2llcy4gUnVuIGBjb21wb3NlciB1cGRhdGVgIHRvIHNlZSBtb3JlIGluZm9ybWF0aW9uLicpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGhhc0RlcGVuZGVuY2llcygkb3B0aW9ucykKICAgIHsKICAgICAgICAkcmVxdWlyZXMgPSAoYXJyYXkpICRvcHRpb25zWydyZXF1aXJlJ107CiAgICAgICAgJGRldlJlcXVpcmVzID0gaXNzZXQoJG9wdGlvbnNbJ3JlcXVpcmUtZGV2J10pID8gKGFycmF5KSAkb3B0aW9uc1sncmVxdWlyZS1kZXYnXSA6IGFycmF5KCk7CgogICAgICAgIHJldHVybiAhZW1wdHkoJHJlcXVpcmVzKSB8fCAhZW1wdHkoJGRldlJlcXVpcmVzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXFNjcmlwdFxFdmVudCBhcyBTY3JpcHRFdmVudDsKdXNlIENvbXBvc2VyXFNjcmlwdFxTY3JpcHRFdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuLnBvdGVuY2llckBnbWFpbC5jb20+CiAqLwpjbGFzcyBSdW5TY3JpcHRDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IEFycmF5IHdpdGggY29tbWFuZCBldmVudHMKICAgICAqLwogICAgcHJvdGVjdGVkICRzY3JpcHRFdmVudHMgPSBhcnJheSgKICAgICAgICBTY3JpcHRFdmVudHM6OlBSRV9JTlNUQUxMX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfSU5TVEFMTF9DTUQsCiAgICAgICAgU2NyaXB0RXZlbnRzOjpQUkVfVVBEQVRFX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfVVBEQVRFX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBSRV9TVEFUVVNfQ01ELAogICAgICAgIFNjcmlwdEV2ZW50czo6UE9TVF9TVEFUVVNfQ01ELAogICAgICAgIFNjcmlwdEV2ZW50czo6UE9TVF9ST09UX1BBQ0tBR0VfSU5TVEFMTCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBPU1RfQ1JFQVRFX1BST0pFQ1RfQ01ELAogICAgICAgIFNjcmlwdEV2ZW50czo6UFJFX0FSQ0hJVkVfQ01ELAogICAgICAgIFNjcmlwdEV2ZW50czo6UE9TVF9BUkNISVZFX0NNRCwKICAgICAgICBTY3JpcHRFdmVudHM6OlBSRV9BVVRPTE9BRF9EVU1QLAogICAgICAgIFNjcmlwdEV2ZW50czo6UE9TVF9BVVRPTE9BRF9EVU1QLAogICAgKTsKCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3J1bi1zY3JpcHQnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ3J1bicpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdSdW5zIHRoZSBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbi4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnc2NyaXB0JywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdTY3JpcHQgbmFtZSB0byBydW4uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnYXJncycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICcnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndGltZW91dCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1NldHMgc2NyaXB0IHRpbWVvdXQgaW4gc2Vjb25kcywgb3IgMCBmb3IgbmV2ZXIuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2V0cyB0aGUgZGV2IG1vZGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgdGhlIGRldiBtb2RlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaXN0JywgJ2wnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3Qgc2NyaXB0cy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz5ydW4tc2NyaXB0PC9pbmZvPiBjb21tYW5kIHJ1bnMgc2NyaXB0cyBkZWZpbmVkIGluIGNvbXBvc2VyLmpzb246Cgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBydW4tc2NyaXB0IHBvc3QtdXBkYXRlLWNtZDwvaW5mbz4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3J1bi1zY3JpcHQKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xpc3QnKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmxpc3RTY3JpcHRzKCRvdXRwdXQpOwogICAgICAgIH0KICAgICAgICBpZiAoISRpbnB1dC0+Z2V0QXJndW1lbnQoJ3NjcmlwdCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBhcmd1bWVudCAic2NyaXB0IicpOwogICAgICAgIH0KCiAgICAgICAgJHNjcmlwdCA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3NjcmlwdCcpOwogICAgICAgIGlmICghaW5fYXJyYXkoJHNjcmlwdCwgJHRoaXMtPnNjcmlwdEV2ZW50cykpIHsKICAgICAgICAgICAgaWYgKGRlZmluZWQoJ0NvbXBvc2VyXFNjcmlwdFxTY3JpcHRFdmVudHM6Oicuc3RyX3JlcGxhY2UoJy0nLCAnXycsIHN0cnRvdXBwZXIoJHNjcmlwdCkpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignU2NyaXB0ICIlcyIgY2Fubm90IGJlIHJ1biB3aXRoIHRoaXMgY29tbWFuZCcsICRzY3JpcHQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CiAgICAgICAgJGRldk1vZGUgPSAkaW5wdXQtPmdldE9wdGlvbignZGV2JykgfHwgISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKTsKICAgICAgICAkZXZlbnQgPSBuZXcgU2NyaXB0RXZlbnQoJHNjcmlwdCwgJGNvbXBvc2VyLCAkdGhpcy0+Z2V0SU8oKSwgJGRldk1vZGUpOwogICAgICAgICRoYXNMaXN0ZW5lcnMgPSAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5oYXNFdmVudExpc3RlbmVycygkZXZlbnQpOwogICAgICAgIGlmICghJGhhc0xpc3RlbmVycykgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdTY3JpcHQgIiVzIiBpcyBub3QgZGVmaW5lZCBpbiB0aGlzIHBhY2thZ2UnLCAkc2NyaXB0KSk7CiAgICAgICAgfQoKICAgICAgICAkYXJncyA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2FyZ3MnKTsKCiAgICAgICAgaWYgKG51bGwgIT09ICR0aW1lb3V0ID0gJGlucHV0LT5nZXRPcHRpb24oJ3RpbWVvdXQnKSkgewogICAgICAgICAgICBpZiAoIWN0eXBlX2RpZ2l0KCR0aW1lb3V0KSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaW1lb3V0IHZhbHVlIG11c3QgYmUgbnVtZXJpYyBhbmQgcG9zaXRpdmUgaWYgZGVmaW5lZCwgb3IgMCBmb3IgZm9yZXZlcicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE92ZXJyaWRlIGdsb2JhbCB0aW1lb3V0IHNldCBiZWZvcmUgaW4gQ29tcG9zZXIgYnkgZW52aXJvbm1lbnQgb3IgY29uZmlnCiAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6c2V0VGltZW91dCgoaW50KSAkdGltZW91dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2hTY3JpcHQoJHNjcmlwdCwgJGRldk1vZGUsICRhcmdzKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbGlzdFNjcmlwdHMoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHNjcmlwdHMgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UGFja2FnZSgpLT5nZXRTY3JpcHRzKCk7CgogICAgICAgIGlmICghY291bnQoJHNjcmlwdHMpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5zY3JpcHRzOjwvaW5mbz4nKTsKICAgICAgICAkdGFibGUgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRzY3JpcHRzIGFzICRuYW1lID0+ICRzY3JpcHQpIHsKICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gJyc7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkY21kID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPmZpbmQoJG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKCRjbWQgaW5zdGFuY2VvZiBTY3JpcHRBbGlhc0NvbW1hbmQpIHsKICAgICAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSAkY21kLT5nZXREZXNjcmlwdGlvbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAvLyBpZ25vcmUgc2NyaXB0cyB0aGF0IGhhdmUgbm8gY29tbWFuZCBhc3NvY2lhdGVkLCBsaWtlIG5hdGl2ZSBDb21wb3NlciBzY3JpcHQgbGlzdGVuZXJzCiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRhYmxlW10gPSBhcnJheSgnICAnLiRuYW1lLCAkZGVzY3JpcHRpb24pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJlbmRlclRhYmxlKCR0YWJsZSwgJG91dHB1dCk7CgogICAgICAgIHJldHVybiAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKCi8qKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICovCmNsYXNzIFNlYXJjaENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgJG1hdGNoZXM7CiAgICBwcm90ZWN0ZWQgJGxvd01hdGNoZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICR0b2tlbnM7CiAgICBwcm90ZWN0ZWQgJG91dHB1dDsKICAgIHByb3RlY3RlZCAkb25seU5hbWU7CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdzZWFyY2gnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdTZWFyY2hlcyBmb3IgcGFja2FnZXMuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvbmx5LW5hbWUnLCAnTicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2VhcmNoIG9ubHkgaW4gbmFtZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd0eXBlJywgJ3QnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdTZWFyY2ggZm9yIGEgc3BlY2lmaWMgcGFja2FnZSB0eXBlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgndG9rZW5zJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpSRVFVSVJFRCwgJ3Rva2VucyB0byBzZWFyY2ggZm9yJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgc2VhcmNoIGNvbW1hbmQgc2VhcmNoZXMgZm9yIHBhY2thZ2VzIGJ5IGl0cyBuYW1lCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHNlYXJjaCBzeW1mb255IGNvbXBvc2VyPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjc2VhcmNoCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgLy8gaW5pdCByZXBvcwogICAgICAgICRwbGF0Zm9ybVJlcG8gPSBuZXcgUGxhdGZvcm1SZXBvc2l0b3J5OwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGlmICghKCRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSkpKSB7CiAgICAgICAgICAgICRjb21wb3NlciA9IEZhY3Rvcnk6OmNyZWF0ZSgkdGhpcy0+Z2V0SU8oKSwgYXJyYXkoKSwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpKTsKICAgICAgICB9CiAgICAgICAgJGxvY2FsUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheSgkbG9jYWxSZXBvLCAkcGxhdGZvcm1SZXBvKSk7CiAgICAgICAgJHJlcG9zID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoYXJyYXlfbWVyZ2UoYXJyYXkoJGluc3RhbGxlZFJlcG8pLCAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpKSk7CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3NlYXJjaCcsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJG9ubHlOYW1lID0gJGlucHV0LT5nZXRPcHRpb24oJ29ubHktbmFtZScpOwogICAgICAgICR0eXBlID0gJGlucHV0LT5nZXRPcHRpb24oJ3R5cGUnKSA/OiBudWxsOwoKICAgICAgICAkZmxhZ3MgPSAkb25seU5hbWUgPyBSZXBvc2l0b3J5SW50ZXJmYWNlOjpTRUFSQ0hfTkFNRSA6IFJlcG9zaXRvcnlJbnRlcmZhY2U6OlNFQVJDSF9GVUxMVEVYVDsKICAgICAgICAkcmVzdWx0cyA9ICRyZXBvcy0+c2VhcmNoKGltcGxvZGUoJyAnLCAkaW5wdXQtPmdldEFyZ3VtZW50KCd0b2tlbnMnKSksICRmbGFncywgJHR5cGUpOwoKICAgICAgICBmb3JlYWNoICgkcmVzdWx0cyBhcyAkcmVzdWx0KSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJHJlc3VsdFsnbmFtZSddIC4gKGlzc2V0KCRyZXN1bHRbJ2Rlc2NyaXB0aW9uJ10pID8gJyAnLiAkcmVzdWx0WydkZXNjcmlwdGlvbiddIDogJycpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcQ29tcG9zZXI7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcVXRpbFxDb25maWdWYWxpZGF0b3I7CnVzZSBDb21wb3NlclxVdGlsXEluaUhlbHBlcjsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFV0aWxcU3RyZWFtQ29udGV4dEZhY3Rvcnk7CnVzZSBDb21wb3NlclxTZWxmVXBkYXRlXEtleXM7CnVzZSBDb21wb3NlclxTZWxmVXBkYXRlXFZlcnNpb25zOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhlY3V0YWJsZUZpbmRlcjsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBEaWFnbm9zZUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKiogQHZhciBIdHRwRG93bmxvYWRlciAqLwogICAgcHJvdGVjdGVkICRodHRwRG93bmxvYWRlcjsKCiAgICAvKiogQHZhciBQcm9jZXNzRXhlY3V0b3IgKi8KICAgIHByb3RlY3RlZCAkcHJvY2VzczsKCiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByb3RlY3RlZCAkZXhpdENvZGUgPSAwOwoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnZGlhZ25vc2UnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdEaWFnbm9zZXMgdGhlIHN5c3RlbSB0byBpZGVudGlmeSBjb21tb24gZXJyb3JzLicpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+ZGlhZ25vc2U8L2luZm8+IGNvbW1hbmQgY2hlY2tzIGNvbW1vbiBlcnJvcnMgdG8gaGVscCBkZWJ1Z2dpbmcgcHJvYmxlbXMuCgpUaGUgcHJvY2VzcyBleGl0IGNvZGUgd2lsbCBiZSAxIGluIGNhc2Ugb2Ygd2FybmluZ3MgYW5kIDIgZm9yIGVycm9ycy4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI2RpYWdub3NlCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnZGlhZ25vc2UnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwoKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgY29tcG9zZXIuanNvbjogJywgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0NvbXBvc2VyU2NoZW1hKCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkY29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CiAgICAgICAgfQoKICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiBhcnJheSgnc2VjdXJlLWh0dHAnID0+IGZhbHNlKSkpOwogICAgICAgICRjb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJ2h0dHA6Ly9yZXBvLnBhY2thZ2lzdC5vcmcnLCBuZXcgTnVsbElPKTsKCiAgICAgICAgJHRoaXMtPmh0dHBEb3dubG9hZGVyID0gRmFjdG9yeTo6Y3JlYXRlSHR0cERvd25sb2FkZXIoJGlvLCAkY29uZmlnKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKCiAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgcGxhdGZvcm0gc2V0dGluZ3M6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja1BsYXRmb3JtKCkpOwoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBnaXQgc2V0dGluZ3M6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0dpdCgpKTsKCiAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgaHR0cCBjb25uZWN0aXZpdHkgdG8gcGFja2FnaXN0OiAnLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tIdHRwKCdodHRwJywgJGNvbmZpZykpOwoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBodHRwcyBjb25uZWN0aXZpdHkgdG8gcGFja2FnaXN0OiAnLCBmYWxzZSk7CiAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tIdHRwKCdodHRwcycsICRjb25maWcpKTsKCiAgICAgICAgJG9wdHMgPSBzdHJlYW1fY29udGV4dF9nZXRfb3B0aW9ucyhTdHJlYW1Db250ZXh0RmFjdG9yeTo6Z2V0Q29udGV4dCgnaHR0cDovL2V4YW1wbGUub3JnJykpOwogICAgICAgIGlmICghZW1wdHkoJG9wdHNbJ2h0dHAnXVsncHJveHknXSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgSFRUUCBwcm94eTogJywgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0h0dHBQcm94eSgpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb2F1dGggPSAkY29uZmlnLT5nZXQoJ2dpdGh1Yi1vYXV0aCcpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRvYXV0aCBhcyAkZG9tYWluID0+ICR0b2tlbikgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgJy4kZG9tYWluLicgb2F1dGggYWNjZXNzOiAnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0dpdGh1Yk9hdXRoKCRkb21haW4sICR0b2tlbikpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnQ2hlY2tpbmcgZ2l0aHViLmNvbSByYXRlIGxpbWl0OiAnLCBmYWxzZSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcmF0ZSA9ICR0aGlzLT5nZXRHaXRodWJSYXRlTGltaXQoJ2dpdGh1Yi5jb20nKTsKICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHJhdGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkcmF0ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoMTAgPiAkcmF0ZVsncmVtYWluaW5nJ10pIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8d2FybmluZz5XQVJOSU5HPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJzxjb21tZW50PkdpdGh1YiBoYXMgYSByYXRlIGxpbWl0IG9uIHRoZWlyIEFQSS4gJwogICAgICAgICAgICAgICAgICAgICAgICAuICdZb3UgY3VycmVudGx5IGhhdmUgPG9wdGlvbnM9Ym9sZD4ldTwvb3B0aW9ucz1ib2xkPiAnCiAgICAgICAgICAgICAgICAgICAgICAgIC4gJ291dCBvZiA8b3B0aW9ucz1ib2xkPiV1PC9vcHRpb25zPWJvbGQ+IHJlcXVlc3RzIGxlZnQuJyAuIFBIUF9FT0wKICAgICAgICAgICAgICAgICAgICAgICAgLiAnU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLmdpdGh1Yi5jb20vdjMvI3JhdGUtbGltaXRpbmcgYW5kIGFsc28nIC4gUEhQX0VPTAogICAgICAgICAgICAgICAgICAgICAgICAuICcgICAgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jL2FydGljbGVzL3Ryb3VibGVzaG9vdGluZy5tZCNhcGktcmF0ZS1saW1pdC1hbmQtb2F1dGgtdG9rZW5zPC9jb21tZW50PicsCiAgICAgICAgICAgICAgICAgICAgICAgICRyYXRlWydyZW1haW5pbmcnXSwKICAgICAgICAgICAgICAgICAgICAgICAgJHJhdGVbJ2xpbWl0J10KICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCh0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRlIGluc3RhbmNlb2YgVHJhbnNwb3J0RXhjZXB0aW9uICYmICRlLT5nZXRDb2RlKCkgPT09IDQwMSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJzxjb21tZW50PlRoZSBvYXV0aCB0b2tlbiBmb3IgZ2l0aHViLmNvbSBzZWVtcyBpbnZhbGlkLCBydW4gImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLXVuc2V0IGdpdGh1Yi1vYXV0aC5naXRodWIuY29tIiB0byByZW1vdmUgaXQ8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkaW8tPndyaXRlKCdDaGVja2luZyBkaXNrIGZyZWUgc3BhY2U6ICcsIGZhbHNlKTsKICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCR0aGlzLT5jaGVja0Rpc2tTcGFjZSgkY29uZmlnKSk7CgogICAgICAgIGlmIChzdHJwb3MoX19GSUxFX18sICdwaGFyOicpID09PSAwKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJ0NoZWNraW5nIHB1YmtleXM6ICcsIGZhbHNlKTsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tQdWJLZXlzKCRjb25maWcpKTsKCiAgICAgICAgICAgICRpby0+d3JpdGUoJ0NoZWNraW5nIGNvbXBvc2VyIHZlcnNpb246ICcsIGZhbHNlKTsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dFJlc3VsdCgkdGhpcy0+Y2hlY2tWZXJzaW9uKCRjb25maWcpKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoc3ByaW50ZignQ29tcG9zZXIgdmVyc2lvbjogPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgQ29tcG9zZXI6OmdldFZlcnNpb24oKSkpOwoKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSAkY29uZmlnLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKTsKICAgICAgICAkcGxhdGZvcm1SZXBvID0gbmV3IFBsYXRmb3JtUmVwb3NpdG9yeShhcnJheSgpLCAkcGxhdGZvcm1PdmVycmlkZXMpOwogICAgICAgICRwaHBQa2cgPSAkcGxhdGZvcm1SZXBvLT5maW5kUGFja2FnZSgncGhwJywgJyonKTsKICAgICAgICAkcGhwVmVyc2lvbiA9ICRwaHBQa2ctPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkcGhwUGtnLT5nZXREZXNjcmlwdGlvbigpLCAnb3ZlcnJpZGRlbicpKSB7CiAgICAgICAgICAgICRwaHBWZXJzaW9uIC49ICcgLSAnIC4gJHBocFBrZy0+Z2V0RGVzY3JpcHRpb24oKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoc3ByaW50ZignUEhQIHZlcnNpb246IDxjb21tZW50PiVzPC9jb21tZW50PicsICRwaHBWZXJzaW9uKSk7CgogICAgICAgIGlmIChkZWZpbmVkKCdQSFBfQklOQVJZJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZShzcHJpbnRmKCdQSFAgYmluYXJ5IHBhdGg6IDxjb21tZW50PiVzPC9jb21tZW50PicsIFBIUF9CSU5BUlkpKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoJ09wZW5TU0wgdmVyc2lvbjogJyAuIChkZWZpbmVkKCdPUEVOU1NMX1ZFUlNJT05fVEVYVCcpID8gJzxjb21tZW50PicuT1BFTlNTTF9WRVJTSU9OX1RFWFQuJzwvY29tbWVudD4nIDogJzxlcnJvcj5taXNzaW5nPC9lcnJvcj4nKSk7CiAgICAgICAgJGlvLT53cml0ZSgnY1VSTCB2ZXJzaW9uOiAnIC4gJHRoaXMtPmdldEN1cmxWZXJzaW9uKCkpOwoKICAgICAgICAkZmluZGVyID0gbmV3IEV4ZWN1dGFibGVGaW5kZXI7CiAgICAgICAgJGhhc1N5c3RlbVVuemlwID0gKGJvb2wpICRmaW5kZXItPmZpbmQoJ3VuemlwJyk7CiAgICAgICAgJGlvLT53cml0ZSgKICAgICAgICAgICAgJ3ppcDogJyAuIChleHRlbnNpb25fbG9hZGVkKCd6aXAnKSA/ICc8Y29tbWVudD5leHRlbnNpb24gcHJlc2VudDwvY29tbWVudD4nIDogJzxjb21tZW50PmV4dGVuc2lvbiBub3QgbG9hZGVkPC9jb21tZW50PicpCiAgICAgICAgICAgIC4gJywgJyAuICgkaGFzU3lzdGVtVW56aXAgPyAnPGNvbW1lbnQ+dW56aXAgcHJlc2VudDwvY29tbWVudD4nIDogJzxjb21tZW50PnVuemlwIG5vdCBhdmFpbGFibGU8L2NvbW1lbnQ+JykKICAgICAgICApOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4aXRDb2RlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tDb21wb3NlclNjaGVtYSgpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9IG5ldyBDb25maWdWYWxpZGF0b3IoJHRoaXMtPmdldElPKCkpOwogICAgICAgIGxpc3QoJGVycm9ycywgLCAkd2FybmluZ3MpID0gJHZhbGlkYXRvci0+dmFsaWRhdGUoRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCkpOwoKICAgICAgICBpZiAoJGVycm9ycyB8fCAkd2FybmluZ3MpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnZXJyb3InID0+ICRlcnJvcnMsCiAgICAgICAgICAgICAgICAnd2FybmluZycgPT4gJHdhcm5pbmdzLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJG91dHB1dCA9ICcnOwogICAgICAgICAgICBmb3JlYWNoICgkbWVzc2FnZXMgYXMgJHN0eWxlID0+ICRtc2dzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbXNncyBhcyAkbXNnKSB7CiAgICAgICAgICAgICAgICAgICAgJG91dHB1dCAuPSAnPCcgLiAkc3R5bGUgLiAnPicgLiAkbXNnIC4gJzwvJyAuICRzdHlsZSAuICc+JyAuIFBIUF9FT0w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBydHJpbSgkb3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tHaXQoKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdnaXQgY29uZmlnIGNvbG9yLnVpJywgJG91dHB1dCk7CiAgICAgICAgaWYgKHN0cnRvbG93ZXIodHJpbSgkb3V0cHV0KSkgPT09ICdhbHdheXMnKSB7CiAgICAgICAgICAgIHJldHVybiAnPGNvbW1lbnQ+WW91ciBnaXQgY29sb3IudWkgc2V0dGluZyBpcyBzZXQgdG8gYWx3YXlzLCB0aGlzIGlzIGtub3duIHRvIGNyZWF0ZSBpc3N1ZXMuIFVzZSAiZ2l0IGNvbmZpZyAtLWdsb2JhbCBjb2xvci51aSB0cnVlIiB0byBzZXQgaXQgY29ycmVjdGx5LjwvY29tbWVudD4nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0h0dHAoJHByb3RvLCBDb25maWcgJGNvbmZpZykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNoZWNrQ29ubmVjdGl2aXR5KCk7CiAgICAgICAgaWYgKCRyZXN1bHQgIT09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHByb3RvID09PSAnaHR0cHMnICYmICRjb25maWctPmdldCgnZGlzYWJsZS10bHMnKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAkdGxzV2FybmluZyA9ICc8d2FybmluZz5Db21wb3NlciBpcyBjb25maWd1cmVkIHRvIGRpc2FibGUgU1NML1RMUyBwcm90ZWN0aW9uLiBUaGlzIHdpbGwgbGVhdmUgcmVtb3RlIEhUVFBTIHJlcXVlc3RzIHZ1bG5lcmFibGUgdG8gTWFuLUluLVRoZS1NaWRkbGUgYXR0YWNrcy48L3dhcm5pbmc+JzsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRwcm90byAuICc6Ly9yZXBvLnBhY2thZ2lzdC5vcmcvcGFja2FnZXMuanNvbicpOwogICAgICAgIH0gY2F0Y2ggKFRyYW5zcG9ydEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGhpbnRzID0gSHR0cERvd25sb2FkZXI6OmdldEV4Y2VwdGlvbkhpbnRzKCRlKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGhpbnRzIGFzICRoaW50KSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gJGhpbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXN1bHRbXSA9ICc8ZXJyb3I+WycgLiBnZXRfY2xhc3MoJGUpIC4gJ10gJyAuICRlLT5nZXRNZXNzYWdlKCkgLiAnPC9lcnJvcj4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KCR0bHNXYXJuaW5nKSkgewogICAgICAgICAgICAkcmVzdWx0W10gPSAkdGxzV2FybmluZzsKICAgICAgICB9CgogICAgICAgIGlmIChjb3VudCgkcmVzdWx0KSA+IDApIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrSHR0cFByb3h5KCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNoZWNrQ29ubmVjdGl2aXR5KCk7CiAgICAgICAgaWYgKCRyZXN1bHQgIT09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAkcHJvdG9jb2wgPSBleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgPyAnaHR0cHMnIDogJ2h0dHAnOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRqc29uID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJHByb3RvY29sIC4gJzovL3JlcG8ucGFja2FnaXN0Lm9yZy9wYWNrYWdlcy5qc29uJyktPmRlY29kZUpzb24oKTsKICAgICAgICAgICAgJGhhc2ggPSByZXNldCgkanNvblsncHJvdmlkZXItaW5jbHVkZXMnXSk7CiAgICAgICAgICAgICRoYXNoID0gJGhhc2hbJ3NoYTI1NiddOwogICAgICAgICAgICAkcGF0aCA9IHN0cl9yZXBsYWNlKCclaGFzaCUnLCAkaGFzaCwga2V5KCRqc29uWydwcm92aWRlci1pbmNsdWRlcyddKSk7CiAgICAgICAgICAgICRwcm92aWRlciA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRwcm90b2NvbCAuICc6Ly9yZXBvLnBhY2thZ2lzdC5vcmcvJy4kcGF0aCktPmdldEJvZHkoKTsKCiAgICAgICAgICAgIGlmIChoYXNoKCdzaGEyNTYnLCAkcHJvdmlkZXIpICE9PSAkaGFzaCkgewogICAgICAgICAgICAgICAgcmV0dXJuICdJdCBzZWVtcyB0aGF0IHlvdXIgcHJveHkgaXMgbW9kaWZ5aW5nIGh0dHAgdHJhZmZpYyBvbiB0aGUgZmx5JzsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgcmV0dXJuICRlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0dpdGh1Yk9hdXRoKCRkb21haW4sICR0b2tlbikKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPmNoZWNrQ29ubmVjdGl2aXR5KCk7CiAgICAgICAgaWYgKCRyZXN1bHQgIT09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+c2V0QXV0aGVudGljYXRpb24oJGRvbWFpbiwgJHRva2VuLCAneC1vYXV0aC1iYXNpYycpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR1cmwgPSAkZG9tYWluID09PSAnZ2l0aHViLmNvbScgPyAnaHR0cHM6Ly9hcGkuJy4kZG9tYWluLicvJyA6ICdodHRwczovLycuJGRvbWFpbi4nL2FwaS92My8nOwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCR1cmwsIGFycmF5KAogICAgICAgICAgICAgICAgJ3JldHJ5LWF1dGgtZmFpbHVyZScgPT4gZmFsc2UsCiAgICAgICAgICAgICkpID8gdHJ1ZSA6ICdVbmV4cGVjdGVkIGVycm9yJzsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAkZS0+Z2V0Q29kZSgpID09PSA0MDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAnPGNvbW1lbnQ+VGhlIG9hdXRoIHRva2VuIGZvciAnLiRkb21haW4uJyBzZWVtcyBpbnZhbGlkLCBydW4gImNvbXBvc2VyIGNvbmZpZyAtLWdsb2JhbCAtLXVuc2V0IGdpdGh1Yi1vYXV0aC4nLiRkb21haW4uJyIgdG8gcmVtb3ZlIGl0PC9jb21tZW50Pic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAkZG9tYWluCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAkdG9rZW4KICAgICAqIEB0aHJvd3MgVHJhbnNwb3J0RXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGFycmF5fHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEdpdGh1YlJhdGVMaW1pdCgkZG9tYWluLCAkdG9rZW4gPSBudWxsKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y2hlY2tDb25uZWN0aXZpdHkoKTsKICAgICAgICBpZiAoJHJlc3VsdCAhPT0gdHJ1ZSkgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIGlmICgkdG9rZW4pIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPnNldEF1dGhlbnRpY2F0aW9uKCRkb21haW4sICR0b2tlbiwgJ3gtb2F1dGgtYmFzaWMnKTsKICAgICAgICB9CgogICAgICAgICR1cmwgPSAkZG9tYWluID09PSAnZ2l0aHViLmNvbScgPyAnaHR0cHM6Ly9hcGkuJy4kZG9tYWluLicvcmF0ZV9saW1pdCcgOiAnaHR0cHM6Ly8nLiRkb21haW4uJy9hcGkvcmF0ZV9saW1pdCc7CiAgICAgICAgJGRhdGEgPSAkdGhpcy0+aHR0cERvd25sb2FkZXItPmdldCgkdXJsLCBhcnJheSgncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSkpLT5kZWNvZGVKc29uKCk7CgogICAgICAgIHJldHVybiAkZGF0YVsncmVzb3VyY2VzJ11bJ2NvcmUnXTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrRGlza1NwYWNlKCRjb25maWcpCiAgICB7CiAgICAgICAgJG1pblNwYWNlRnJlZSA9IDEwMjQgKiAxMDI0OwogICAgICAgIGlmICgoKCRkZiA9IEBkaXNrX2ZyZWVfc3BhY2UoJGRpciA9ICRjb25maWctPmdldCgnaG9tZScpKSkgIT09IGZhbHNlICYmICRkZiA8ICRtaW5TcGFjZUZyZWUpCiAgICAgICAgICAgIHx8ICgoJGRmID0gQGRpc2tfZnJlZV9zcGFjZSgkZGlyID0gJGNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJykpKSAhPT0gZmFsc2UgJiYgJGRmIDwgJG1pblNwYWNlRnJlZSkKICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuICc8ZXJyb3I+VGhlIGRpc2sgaG9zdGluZyAnLiRkaXIuJyBpcyBmdWxsPC9lcnJvcj4nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja1B1YktleXMoJGNvbmZpZykKICAgIHsKICAgICAgICAkaG9tZSA9ICRjb25maWctPmdldCgnaG9tZScpOwogICAgICAgICRlcnJvcnMgPSBhcnJheSgpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGhvbWUuJy9rZXlzLnRhZ3MucHViJykgJiYgZmlsZV9leGlzdHMoJGhvbWUuJy9rZXlzLmRldi5wdWInKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCcnKTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaG9tZS4nL2tleXMudGFncy5wdWInKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCdUYWdzIFB1YmxpYyBLZXkgRmluZ2VycHJpbnQ6ICcgLiBLZXlzOjpmaW5nZXJwcmludCgkaG9tZS4nL2tleXMudGFncy5wdWInKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGVycm9yc1tdID0gJzxlcnJvcj5NaXNzaW5nIHB1YmtleSBmb3IgdGFncyB2ZXJpZmljYXRpb248L2Vycm9yPic7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGhvbWUuJy9rZXlzLmRldi5wdWInKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCdEZXYgUHVibGljIEtleSBGaW5nZXJwcmludDogJyAuIEtleXM6OmZpbmdlcnByaW50KCRob21lLicva2V5cy5kZXYucHViJykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRlcnJvcnNbXSA9ICc8ZXJyb3I+TWlzc2luZyBwdWJrZXkgZm9yIGRldiB2ZXJpZmljYXRpb248L2Vycm9yPic7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVycm9ycykgewogICAgICAgICAgICAkZXJyb3JzW10gPSAnPGVycm9yPlJ1biBjb21wb3NlciBzZWxmLXVwZGF0ZSAtLXVwZGF0ZS1rZXlzIHRvIHNldCB0aGVtIHVwPC9lcnJvcj4nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRlcnJvcnMgPzogdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNoZWNrVmVyc2lvbigkY29uZmlnKQogICAgewogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+Y2hlY2tDb25uZWN0aXZpdHkoKTsKICAgICAgICBpZiAoJHJlc3VsdCAhPT0gdHJ1ZSkgewogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uc1V0aWwgPSBuZXcgVmVyc2lvbnMoJGNvbmZpZywgJHRoaXMtPmh0dHBEb3dubG9hZGVyKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkbGF0ZXN0ID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICByZXR1cm4gJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoQ29tcG9zZXI6OlZFUlNJT04gIT09ICRsYXRlc3RbJ3ZlcnNpb24nXSAmJiBDb21wb3Nlcjo6VkVSU0lPTiAhPT0gJ0BwYWNrYWdlX3ZlcnNpb25AJykgewogICAgICAgICAgICByZXR1cm4gJzxjb21tZW50PllvdSBhcmUgbm90IHJ1bm5pbmcgdGhlIGxhdGVzdCAnLiR2ZXJzaW9uc1V0aWwtPmdldENoYW5uZWwoKS4nIHZlcnNpb24sIHJ1biBgY29tcG9zZXIgc2VsZi11cGRhdGVgIHRvIHVwZGF0ZSAoJy5Db21wb3Nlcjo6VkVSU0lPTi4nID0+ICcuJGxhdGVzdFsndmVyc2lvbiddLicpPC9jb21tZW50Pic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEN1cmxWZXJzaW9uKCkKICAgIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgnY3VybCcpKSB7CiAgICAgICAgICAgIGlmICghSHR0cERvd25sb2FkZXI6OmlzQ3VybEVuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICc8ZXJyb3I+ZGlzYWJsZWQgdmlhIGRpc2FibGVfZnVuY3Rpb25zLCB1c2luZyBwaHAgc3RyZWFtcyBmYWxsYmFjaywgd2hpY2ggcmVkdWNlcyBwZXJmb3JtYW5jZTwvZXJyb3I+JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZlcnNpb24gPSBjdXJsX3ZlcnNpb24oKTsKCiAgICAgICAgICAgIHJldHVybiAnPGNvbW1lbnQ+Jy4kdmVyc2lvblsndmVyc2lvbiddLic8L2NvbW1lbnQ+ICcuCiAgICAgICAgICAgICAgICAnbGlieiA8Y29tbWVudD4nLihpc3NldCgkdmVyc2lvblsnbGliel92ZXJzaW9uJ10pID8gJHZlcnNpb25bJ2xpYnpfdmVyc2lvbiddIDogJ21pc3NpbmcnKS4nPC9jb21tZW50PiAnLgogICAgICAgICAgICAgICAgJ3NzbCA8Y29tbWVudD4nLihpc3NldCgkdmVyc2lvblsnc3NsX3ZlcnNpb24nXSkgPyAkdmVyc2lvblsnc3NsX3ZlcnNpb24nXSA6ICdtaXNzaW5nJykuJzwvY29tbWVudD4nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICc8ZXJyb3I+bWlzc2luZywgdXNpbmcgcGhwIHN0cmVhbXMgZmFsbGJhY2ssIHdoaWNoIHJlZHVjZXMgcGVyZm9ybWFuY2U8L2Vycm9yPic7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbHxzdHJpbmd8XEV4Y2VwdGlvbiAkcmVzdWx0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3V0cHV0UmVzdWx0KCRyZXN1bHQpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKHRydWUgPT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+T0s8L2luZm8+Jyk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaGFkRXJyb3IgPSBmYWxzZTsKICAgICAgICAkaGFkV2FybmluZyA9IGZhbHNlOwogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2YgXEV4Y2VwdGlvbikgewogICAgICAgICAgICAkcmVzdWx0ID0gJzxlcnJvcj5bJy5nZXRfY2xhc3MoJHJlc3VsdCkuJ10gJy4kcmVzdWx0LT5nZXRNZXNzYWdlKCkuJzwvZXJyb3I+JzsKICAgICAgICB9CgogICAgICAgIGlmICghJHJlc3VsdCkgewogICAgICAgICAgICAvLyBmYWxzZXkgcmVzdWx0cyBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBhbiBlcnJvciwgZXZlbiBpZiB0aGVyZSBpcyBub3RoaW5nIHRvIG91dHB1dAogICAgICAgICAgICAkaGFkRXJyb3IgPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHJlc3VsdCkpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBhcnJheSgkcmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkcmVzdWx0IGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkbWVzc2FnZSwgJzxlcnJvcj4nKSkgewogICAgICAgICAgICAgICAgICAgICRoYWRFcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoZmFsc2UgIT09IHN0cnBvcygkbWVzc2FnZSwgJzx3YXJuaW5nPicpKSB7CiAgICAgICAgICAgICAgICAgICAgJGhhZFdhcm5pbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhZEVycm9yKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzxlcnJvcj5GQUlMPC9lcnJvcj4nKTsKICAgICAgICAgICAgJHRoaXMtPmV4aXRDb2RlID0gbWF4KCR0aGlzLT5leGl0Q29kZSwgMik7CiAgICAgICAgfSBlbHNlaWYgKCRoYWRXYXJuaW5nKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzx3YXJuaW5nPldBUk5JTkc8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICR0aGlzLT5leGl0Q29kZSA9IG1heCgkdGhpcy0+ZXhpdENvZGUsIDEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXN1bHQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdCBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja1BsYXRmb3JtKCkKICAgIHsKICAgICAgICAkb3V0cHV0ID0gJyc7CiAgICAgICAgJG91dCA9IGZ1bmN0aW9uICgkbXNnLCAkc3R5bGUpIHVzZSAoJiRvdXRwdXQpIHsKICAgICAgICAgICAgJG91dHB1dCAuPSAnPCcuJHN0eWxlLic+Jy4kbXNnLic8LycuJHN0eWxlLic+Jy5QSFBfRU9MOwogICAgICAgIH07CgogICAgICAgIC8vIGNvZGUgYmVsb3cgdGFrZW4gZnJvbSBnZXRjb21wb3Nlci5vcmcvaW5zdGFsbGVyLCBhbnkgY2hhbmdlcyBzaG91bGQgYmUgbWFkZSB0aGVyZSBhbmQgcmVwbGljYXRlZCBoZXJlCiAgICAgICAgJGVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgJHdhcm5pbmdzID0gYXJyYXkoKTsKICAgICAgICAkZGlzcGxheUluaU1lc3NhZ2UgPSBmYWxzZTsKCiAgICAgICAgJGluaU1lc3NhZ2UgPSBQSFBfRU9MLlBIUF9FT0wuSW5pSGVscGVyOjpnZXRNZXNzYWdlKCk7CiAgICAgICAgJGluaU1lc3NhZ2UgLj0gUEhQX0VPTC4nSWYgeW91IGNhbiBub3QgbW9kaWZ5IHRoZSBpbmkgZmlsZSwgeW91IGNhbiBhbHNvIHJ1biBgcGhwIC1kIG9wdGlvbj12YWx1ZWAgdG8gbW9kaWZ5IGluaSB2YWx1ZXMgb24gdGhlIGZseS4gWW91IGNhbiB1c2UgLWQgbXVsdGlwbGUgdGltZXMuJzsKCiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2pzb25fZGVjb2RlJykpIHsKICAgICAgICAgICAgJGVycm9yc1snanNvbiddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnUGhhcicpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ3BoYXInXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ2ZpbHRlcicpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ2ZpbHRlciddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnaGFzaCcpKSB7CiAgICAgICAgICAgICRlcnJvcnNbJ2hhc2gnXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ2ljb252JykgJiYgIWV4dGVuc2lvbl9sb2FkZWQoJ21ic3RyaW5nJykpIHsKICAgICAgICAgICAgJGVycm9yc1snaWNvbnZfbWJzdHJpbmcnXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWZpbHRlcl92YXIoaW5pX2dldCgnYWxsb3dfdXJsX2ZvcGVuJyksIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKSkgewogICAgICAgICAgICAkZXJyb3JzWydhbGxvd191cmxfZm9wZW4nXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgnaW9uQ3ViZSBMb2FkZXInKSAmJiBpb25jdWJlX2xvYWRlcl9pdmVyc2lvbigpIDwgNDAwMDkpIHsKICAgICAgICAgICAgJGVycm9yc1snaW9uY3ViZSddID0gaW9uY3ViZV9sb2FkZXJfdmVyc2lvbigpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgNTAzMDIpIHsKICAgICAgICAgICAgJGVycm9yc1sncGhwJ10gPSBQSFBfVkVSU0lPTjsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJGVycm9yc1sncGhwJ10pICYmIFBIUF9WRVJTSU9OX0lEIDwgNTAzMDQpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWydwaHAnXSA9IFBIUF9WRVJTSU9OOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpIHsKICAgICAgICAgICAgJGVycm9yc1snb3BlbnNzbCddID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykgJiYgT1BFTlNTTF9WRVJTSU9OX05VTUJFUiA8IDB4MTAwMDEwMGYpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWydvcGVuc3NsX3ZlcnNpb24nXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWRlZmluZWQoJ0hIVk1fVkVSU0lPTicpICYmICFleHRlbnNpb25fbG9hZGVkKCdhcGN1JykgJiYgZmlsdGVyX3ZhcihpbmlfZ2V0KCdhcGMuZW5hYmxlX2NsaScpLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTikpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWydhcGNfY2xpJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCd6bGliJykpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWyd6bGliJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICBwaHBpbmZvKElORk9fR0VORVJBTCk7CiAgICAgICAgJHBocGluZm8gPSBvYl9nZXRfY2xlYW4oKTsKICAgICAgICBpZiAocHJlZ19tYXRjaCgne0NvbmZpZ3VyZSBDb21tYW5kKD86ICo8L3RkPjx0ZCBjbGFzcz0idiI+fCAqPT4gKikoLio/KSg/OjwvdGQ+fCQpfW0nLCAkcGhwaW5mbywgJG1hdGNoKSkgewogICAgICAgICAgICAkY29uZmlndXJlID0gJG1hdGNoWzFdOwoKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGNvbmZpZ3VyZSwgJy0tZW5hYmxlLXNpZ2NoaWxkJykpIHsKICAgICAgICAgICAgICAgICR3YXJuaW5nc1snc2lnY2hpbGQnXSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCRjb25maWd1cmUsICctLXdpdGgtY3VybHdyYXBwZXJzJykpIHsKICAgICAgICAgICAgICAgICR3YXJuaW5nc1snY3VybHdyYXBwZXJzJ10gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZmlsdGVyX3ZhcihpbmlfZ2V0KCd4ZGVidWcucHJvZmlsZXJfZW5hYmxlZCcpLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTikpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWyd4ZGVidWdfcHJvZmlsZSddID0gdHJ1ZTsKICAgICAgICB9IGVsc2VpZiAoZXh0ZW5zaW9uX2xvYWRlZCgneGRlYnVnJykpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWyd4ZGVidWdfbG9hZGVkJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKQogICAgICAgICAgICAmJiAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNy4yLjIzJywgJzwnKQogICAgICAgICAgICB8fCAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNy4zLjAnLCAnPj0nKQogICAgICAgICAgICAmJiB2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc3LjMuMTAnLCAnPCcpKSkpIHsKICAgICAgICAgICAgJHdhcm5pbmdzWydvbmVkcml2ZSddID0gUEhQX1ZFUlNJT047CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRlcnJvcnMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRlcnJvcnMgYXMgJGVycm9yID0+ICRjdXJyZW50KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCRlcnJvcikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2pzb24nOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBqc29uIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1qc29uIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3BoYXInOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBwaGFyIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1waGFyIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gUEhQX0VPTC4iVGhlIGZpbHRlciBleHRlbnNpb24gaXMgbWlzc2luZy4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJJbnN0YWxsIGl0IG9yIHJlY29tcGlsZSBwaHAgd2l0aG91dCAtLWRpc2FibGUtZmlsdGVyIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2hhc2gnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBoYXNoIGV4dGVuc2lvbiBpcyBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgaXQgb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1oYXNoIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ljb252X21ic3RyaW5nJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSBQSFBfRU9MLiJUaGUgaWNvbnYgT1IgbWJzdHJpbmcgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkIGFuZCBib3RoIGFyZSBtaXNzaW5nLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIkluc3RhbGwgZWl0aGVyIG9mIHRoZW0gb3IgcmVjb21waWxlIHBocCB3aXRob3V0IC0tZGlzYWJsZS1pY29udiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdwaHAnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIllvdXIgUEhQICh7JGN1cnJlbnR9KSBpcyB0b28gb2xkLCB5b3UgbXVzdCB1cGdyYWRlIHRvIFBIUCA1LjMuMiBvciBoaWdoZXIuIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2FsbG93X3VybF9mb3Blbic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gUEhQX0VPTC4iVGhlIGFsbG93X3VybF9mb3BlbiBzZXR0aW5nIGlzIGluY29ycmVjdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgOiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiAgICBhbGxvd191cmxfZm9wZW4gPSBPbiI7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXNwbGF5SW5pTWVzc2FnZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdpb25jdWJlJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSBQSFBfRU9MLiJZb3VyIGlvbkN1YmUgTG9hZGVyIGV4dGVuc2lvbiAoJGN1cnJlbnQpIGlzIGluY29tcGF0aWJsZSB3aXRoIFBoYXIgZmlsZXMuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiVXBncmFkZSB0byBpb25DdWJlIDQuMC45IG9yIGhpZ2hlciBvciByZW1vdmUgdGhpcyBsaW5lIChwYXRoIG1heSBiZSBkaWZmZXJlbnQpIGZyb20geW91ciBgcGhwLmluaWAgdG8gZGlzYWJsZSBpdDoiLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICIgICAgemVuZF9leHRlbnNpb24gPSAvdXNyL2xpYi9waHA1LzIwMDkwNjI2K2xmcy9pb25jdWJlX2xvYWRlcl9saW5fNS4zLnNvIjsKICAgICAgICAgICAgICAgICAgICAgICAgJGRpc3BsYXlJbmlNZXNzYWdlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5zc2wnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9IFBIUF9FT0wuIlRoZSBvcGVuc3NsIGV4dGVuc2lvbiBpcyBtaXNzaW5nLCB3aGljaCBtZWFucyB0aGF0IHNlY3VyZSBIVFRQUyB0cmFuc2ZlcnMgYXJlIGltcG9zc2libGUuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiSWYgcG9zc2libGUgeW91IHNob3VsZCBlbmFibGUgaXQgb3IgcmVjb21waWxlIHBocCB3aXRoIC0td2l0aC1vcGVuc3NsIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoIkRpYWdub3NlQ29tbWFuZDogVW5rbm93biBlcnJvciB0eXBlIFwiJXNcIi4gUGxlYXNlIHJlcG9ydCBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzL25ldy4iLCAkZXJyb3IpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRvdXQoJHRleHQsICdlcnJvcicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3V0cHV0IC49IFBIUF9FT0w7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR3YXJuaW5ncykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHdhcm5pbmdzIGFzICR3YXJuaW5nID0+ICRjdXJyZW50KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCR3YXJuaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXBjX2NsaSc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSBhcGMuZW5hYmxlX2NsaSBzZXR0aW5nIGlzIGluY29ycmVjdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgOiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiAgYXBjLmVuYWJsZV9jbGkgPSBPZmYiOwogICAgICAgICAgICAgICAgICAgICAgICAkZGlzcGxheUluaU1lc3NhZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnemxpYic6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gJ1RoZSB6bGliIGV4dGVuc2lvbiBpcyBub3QgbG9hZGVkLCB0aGlzIGNhbiBzbG93IGRvd24gQ29tcG9zZXIgYSBsb3QuJy5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAnSWYgcG9zc2libGUsIGVuYWJsZSBpdCBvciByZWNvbXBpbGUgcGhwIHdpdGggLS13aXRoLXpsaWInLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXNwbGF5SW5pTWVzc2FnZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdzaWdjaGlsZCc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlBIUCB3YXMgY29tcGlsZWQgd2l0aCAtLWVuYWJsZS1zaWdjaGlsZCB3aGljaCBjYW4gY2F1c2UgaXNzdWVzIG9uIHNvbWUgcGxhdGZvcm1zLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIlJlY29tcGlsZSBpdCB3aXRob3V0IHRoaXMgZmxhZyBpZiBwb3NzaWJsZSwgc2VlIGFsc286Ii5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiICBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTIyOTk5IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2N1cmx3cmFwcGVycyc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlBIUCB3YXMgY29tcGlsZWQgd2l0aCAtLXdpdGgtY3VybHdyYXBwZXJzIHdoaWNoIHdpbGwgY2F1c2UgaXNzdWVzIHdpdGggSFRUUCBhdXRoZW50aWNhdGlvbiBhbmQgR2l0SHViLiIuUEhQX0VPTDsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgLj0gIiBSZWNvbXBpbGUgaXQgd2l0aG91dCB0aGlzIGZsYWcgaWYgcG9zc2libGUiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAncGhwJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSAiWW91ciBQSFAgKHskY3VycmVudH0pIGlzIHF1aXRlIG9sZCwgdXBncmFkaW5nIHRvIFBIUCA1LjMuNCBvciBoaWdoZXIgaXMgcmVjb21tZW5kZWQuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiIENvbXBvc2VyIHdvcmtzIHdpdGggNS4zLjIrIGZvciBtb3N0IHBlb3BsZSwgYnV0IHRoZXJlIG1pZ2h0IGJlIGVkZ2UgY2FzZSBpc3N1ZXMuIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ29wZW5zc2xfdmVyc2lvbic6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gcGFyc2UgdmVyc2lvbiBudW1iZXIgb3V0LCBmYWxsYmFjayB0byB3aG9sZSBzdHJpbmcgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVuc3NsVmVyc2lvbiA9IHN0cnN0cih0cmltKHN0cnN0cihPUEVOU1NMX1ZFUlNJT05fVEVYVCwgJyAnKSksICcgJywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVuc3NsVmVyc2lvbiA9ICRvcGVuc3NsVmVyc2lvbiA/OiBPUEVOU1NMX1ZFUlNJT05fVEVYVDsKCiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSBPcGVuU1NMIGxpYnJhcnkgKHskb3BlbnNzbFZlcnNpb259KSB1c2VkIGJ5IFBIUCBkb2VzIG5vdCBzdXBwb3J0IFRMU3YxLjIgb3IgVExTdjEuMS4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJJZiBwb3NzaWJsZSB5b3Ugc2hvdWxkIHVwZ3JhZGUgT3BlblNTTCB0byB2ZXJzaW9uIDEuMC4xIG9yIGFib3ZlLiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICd4ZGVidWdfbG9hZGVkJzoKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHQgPSAiVGhlIHhkZWJ1ZyBleHRlbnNpb24gaXMgbG9hZGVkLCB0aGlzIGNhbiBzbG93IGRvd24gQ29tcG9zZXIgYSBsaXR0bGUuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiIERpc2FibGluZyBpdCB3aGVuIHVzaW5nIENvbXBvc2VyIGlzIHJlY29tbWVuZGVkLiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICd4ZGVidWdfcHJvZmlsZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0ID0gIlRoZSB4ZGVidWcucHJvZmlsZXJfZW5hYmxlZCBzZXR0aW5nIGlzIGVuYWJsZWQsIHRoaXMgY2FuIHNsb3cgZG93biBDb21wb3NlciBhIGxvdC4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICJBZGQgdGhlIGZvbGxvd2luZyB0byB0aGUgZW5kIG9mIHlvdXIgYHBocC5pbmlgIHRvIGRpc2FibGUgaXQ6Ii5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiICB4ZGVidWcucHJvZmlsZXJfZW5hYmxlZCA9IDAiOwogICAgICAgICAgICAgICAgICAgICAgICAkZGlzcGxheUluaU1lc3NhZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnb25lZHJpdmUnOgogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCA9ICJUaGUgV2luZG93cyBPbmVEcml2ZSBmb2xkZXIgaXMgbm90IHN1cHBvcnRlZCBvbiBQSFAgdmVyc2lvbnMgYmVsb3cgNy4yLjIzIGFuZCA3LjMuMTAuIi5QSFBfRU9MOwogICAgICAgICAgICAgICAgICAgICAgICAkdGV4dCAuPSAiVXBncmFkZSB5b3VyIFBIUCAoeyRjdXJyZW50fSkgdG8gdXNlIHRoaXMgbG9jYXRpb24gd2l0aCBDb21wb3Nlci4iLlBIUF9FT0w7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCJEaWFnbm9zZUNvbW1hbmQ6IFVua25vd24gd2FybmluZyB0eXBlIFwiJXNcIi4gUGxlYXNlIHJlcG9ydCBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzL25ldy4iLCAkd2FybmluZykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG91dCgkdGV4dCwgJ2NvbW1lbnQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRkaXNwbGF5SW5pTWVzc2FnZSkgewogICAgICAgICAgICAkb3V0KCRpbmlNZXNzYWdlLCAnY29tbWVudCcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICEkd2FybmluZ3MgJiYgISRlcnJvcnMgPyB0cnVlIDogJG91dHB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIGFsbG93X3VybF9mb3BlbiBpcyBPTgogICAgICoKICAgICAqIEByZXR1cm4gdHJ1ZXxzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjaGVja0Nvbm5lY3Rpdml0eSgpCiAgICB7CiAgICAgICAgaWYgKCFpbmlfZ2V0KCdhbGxvd191cmxfZm9wZW4nKSkgewogICAgICAgICAgICByZXR1cm4gJzxpbmZvPlNraXBwZWQgYmVjYXVzZSBhbGxvd191cmxfZm9wZW4gaXMgbWlzc2luZy48L2luZm8+JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUZhY3Rvcnk7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICovCmNsYXNzIEhvbWVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnYnJvd3NlJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdob21lJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ09wZW5zIHRoZSBwYWNrYWdlXCdzIHJlcG9zaXRvcnkgVVJMIG9yIGhvbWVwYWdlIGluIHlvdXIgYnJvd3Nlci4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZXMnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSwgJ1BhY2thZ2UocykgdG8gYnJvd3NlIHRvLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdob21lcGFnZScsICdIJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcGVuIHRoZSBob21lcGFnZSBpbnN0ZWFkIG9mIHRoZSByZXBvc2l0b3J5IFVSTC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc2hvdycsICdzJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPbmx5IHNob3cgdGhlIGhvbWVwYWdlIG9yIHJlcG9zaXRvcnkgVVJMLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIGhvbWUgY29tbWFuZCBvcGVucyBvciBzaG93cyBhIHBhY2thZ2UncyByZXBvc2l0b3J5IFVSTCBvcgpob21lcGFnZSBpbiB5b3VyIGRlZmF1bHQgYnJvd3Nlci4KClRvIG9wZW4gdGhlIGhvbWVwYWdlIGJ5IGRlZmF1bHQsIHVzZSAtSCBvciAtLWhvbWVwYWdlLgpUbyBzaG93IGluc3RlYWQgb2Ygb3BlbiB0aGUgcmVwb3NpdG9yeSBvciBob21lcGFnZSBVUkwsIHVzZSAtcyBvciAtLXNob3cuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNicm93c2UtaG9tZQpFT1QKICAgICAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkcmVwb3MgPSAkdGhpcy0+aW5pdGlhbGl6ZVJlcG9zKCk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgJHJldHVybiA9IDA7CgogICAgICAgICRwYWNrYWdlcyA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyk7CiAgICAgICAgaWYgKCEkcGFja2FnZXMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdObyBwYWNrYWdlIHNwZWNpZmllZCwgb3BlbmluZyBob21lcGFnZSBmb3IgdGhlIHJvb3QgcGFja2FnZScpOwogICAgICAgICAgICAkcGFja2FnZXMgPSBhcnJheSgkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0UGFja2FnZSgpLT5nZXROYW1lKCkpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICAkaGFuZGxlZCA9IGZhbHNlOwogICAgICAgICAgICAkcGFja2FnZUV4aXN0cyA9IGZhbHNlOwogICAgICAgICAgICBmb3JlYWNoICgkcmVwb3MgYXMgJHJlcG8pIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZXBvLT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlRXhpc3RzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJiYgJHRoaXMtPmhhbmRsZVBhY2thZ2UoJHBhY2thZ2UsICRpbnB1dC0+Z2V0T3B0aW9uKCdob21lcGFnZScpLCAkaW5wdXQtPmdldE9wdGlvbignc2hvdycpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRwYWNrYWdlRXhpc3RzKSB7CiAgICAgICAgICAgICAgICAkcmV0dXJuID0gMTsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+UGFja2FnZSAnLiRwYWNrYWdlTmFtZS4nIG5vdCBmb3VuZDwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkaGFuZGxlZCkgewogICAgICAgICAgICAgICAgJHJldHVybiA9IDE7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicuKCRpbnB1dC0+Z2V0T3B0aW9uKCdob21lcGFnZScpID8gJ0ludmFsaWQgb3IgbWlzc2luZyBob21lcGFnZScgOiAnSW52YWxpZCBvciBtaXNzaW5nIHJlcG9zaXRvcnkgVVJMJykuJyBmb3IgJy4kcGFja2FnZU5hbWUuJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXR1cm47CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBoYW5kbGVQYWNrYWdlKENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHNob3dIb21lcGFnZSwgJHNob3dPbmx5KQogICAgewogICAgICAgICRzdXBwb3J0ID0gJHBhY2thZ2UtPmdldFN1cHBvcnQoKTsKICAgICAgICAkdXJsID0gaXNzZXQoJHN1cHBvcnRbJ3NvdXJjZSddKSA/ICRzdXBwb3J0Wydzb3VyY2UnXSA6ICRwYWNrYWdlLT5nZXRTb3VyY2VVcmwoKTsKICAgICAgICBpZiAoISR1cmwgfHwgJHNob3dIb21lcGFnZSkgewogICAgICAgICAgICAkdXJsID0gJHBhY2thZ2UtPmdldEhvbWVwYWdlKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR1cmwgfHwgIWZpbHRlcl92YXIoJHVybCwgRklMVEVSX1ZBTElEQVRFX1VSTCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRzaG93T25seSkgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoc3ByaW50ZignPGluZm8+JXM8L2luZm8+JywgJHVybCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5vcGVuQnJvd3NlcigkdXJsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogb3BlbnMgYSB1cmwgaW4geW91ciBzeXN0ZW0gZGVmYXVsdCBicm93c2VyCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3BlbkJyb3dzZXIoJHVybCkKICAgIHsKICAgICAgICAkdXJsID0gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCk7CgogICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkdGhpcy0+Z2V0SU8oKSk7CiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICByZXR1cm4gJHByb2Nlc3MtPmV4ZWN1dGUoJ3N0YXJ0ICJ3ZWIiIGV4cGxvcmVyICInIC4gJHVybCAuICciJywgJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkbGludXggPSAkcHJvY2Vzcy0+ZXhlY3V0ZSgnd2hpY2ggeGRnLW9wZW4nLCAkb3V0cHV0KTsKICAgICAgICAkb3N4ID0gJHByb2Nlc3MtPmV4ZWN1dGUoJ3doaWNoIG9wZW4nLCAkb3V0cHV0KTsKCiAgICAgICAgaWYgKDAgPT09ICRsaW51eCkgewogICAgICAgICAgICAkcHJvY2Vzcy0+ZXhlY3V0ZSgneGRnLW9wZW4gJyAuICR1cmwsICRvdXRwdXQpOwogICAgICAgIH0gZWxzZWlmICgwID09PSAkb3N4KSB7CiAgICAgICAgICAgICRwcm9jZXNzLT5leGVjdXRlKCdvcGVuICcgLiAkdXJsLCAkb3V0cHV0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignTm8gc3VpdGFibGUgYnJvd3NlciBvcGVuaW5nIGNvbW1hbmQgZm91bmQsIG9wZW4geW91cnNlbGY6ICcgLiAkdXJsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyByZXBvc2l0b3JpZXMKICAgICAqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlcG9zIGluIG9yZGVyIHRoZXkgc2hvdWxkIGJlIGNoZWNrZWQgaW4KICAgICAqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlJbnRlcmZhY2VbXQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRpYWxpemVSZXBvcygpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKGZhbHNlKTsKCiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICBhcnJheShuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpKSksIC8vIHJvb3QgcGFja2FnZQogICAgICAgICAgICAgICAgYXJyYXkoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSksIC8vIGluc3RhbGxlZCBwYWNrYWdlcwogICAgICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSAvLyByZW1vdGVzCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gUmVwb3NpdG9yeUZhY3Rvcnk6OmRlZmF1bHRSZXBvcygkdGhpcy0+Z2V0SU8oKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxEZWZhdWx0UG9saWN5Owp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblNlbGVjdG9yOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zZXJSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSb290UGFja2FnZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFNlbXZlcjsKdXNlIENvbXBvc2VyXFNwZHhcU3BkeExpY2Vuc2VzOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlclN0eWxlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlcm1pbmFsOwoKLyoqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgSsOpcsOpbXkgUm9tZXkgPGplcmVteUZyZWVBZ2VudD4KICogQGF1dGhvciBNaWhhaSBQbGFzb2lhbnUgPG1paGFpQHBsYXNvaWFudS5kZT4KICovCmNsYXNzIFNob3dDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqIEB2YXIgVmVyc2lvblBhcnNlciAqLwogICAgcHJvdGVjdGVkICR2ZXJzaW9uUGFyc2VyOwogICAgcHJvdGVjdGVkICRjb2xvcnM7CgogICAgLyoqIEB2YXIgUmVwb3NpdG9yeVNldCAqLwogICAgcHJpdmF0ZSAkcmVwb3NpdG9yeVNldDsKCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3Nob3cnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ2luZm8nKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3MgaW5mb3JtYXRpb24gYWJvdXQgcGFja2FnZXMuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2UnLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2UgdG8gaW5zcGVjdC4gT3IgYSBuYW1lIGluY2x1ZGluZyBhIHdpbGRjYXJkICgqKSB0byBmaWx0ZXIgbGlzdHMgb2YgcGFja2FnZXMgaW5zdGVhZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCd2ZXJzaW9uJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdWZXJzaW9uIG9yIHZlcnNpb24gY29uc3RyYWludCB0byBpbnNwZWN0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FsbCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnTGlzdCBhbGwgcGFja2FnZXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbG9ja2VkJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IGFsbCBsb2NrZWQgcGFja2FnZXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaW5zdGFsbGVkJywgJ2knLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3QgaW5zdGFsbGVkIHBhY2thZ2VzIG9ubHkgKGVuYWJsZWQgYnkgZGVmYXVsdCwgb25seSBwcmVzZW50IGZvciBCQykuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3BsYXRmb3JtJywgJ3AnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3QgcGxhdGZvcm0gcGFja2FnZXMgb25seScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhdmFpbGFibGUnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnTGlzdCBhdmFpbGFibGUgcGFja2FnZXMgb25seScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzZWxmJywgJ3MnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgdGhlIHJvb3QgcGFja2FnZSBpbmZvcm1hdGlvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduYW1lLW9ubHknLCAnTicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnTGlzdCBwYWNrYWdlIG5hbWVzIG9ubHknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncGF0aCcsICdQJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IHBhY2thZ2UgcGF0aHMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndHJlZScsICd0JywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdMaXN0IHRoZSBkZXBlbmRlbmNpZXMgYXMgYSB0cmVlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2xhdGVzdCcsICdsJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IHRoZSBsYXRlc3QgdmVyc2lvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvdXRkYXRlZCcsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IHRoZSBsYXRlc3QgdmVyc2lvbiBidXQgb25seSBmb3IgcGFja2FnZXMgdGhhdCBhcmUgb3V0ZGF0ZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIHNwZWNpZmllZCBwYWNrYWdlKHMpLiBVc2UgaXQgd2l0aCB0aGUgLS1vdXRkYXRlZCBvcHRpb24gaWYgeW91IGRvblwndCB3YW50IHRvIGJlIGluZm9ybWVkIGFib3V0IG5ldyB2ZXJzaW9ucyBvZiBzb21lIHBhY2thZ2VzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdtaW5vci1vbmx5JywgJ20nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgb25seSBwYWNrYWdlcyB0aGF0IGhhdmUgbWlub3IgU2VtVmVyLWNvbXBhdGlibGUgdXBkYXRlcy4gVXNlIHdpdGggdGhlIC0tb3V0ZGF0ZWQgb3B0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkaXJlY3QnLCAnRCcsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvd3Mgb25seSBwYWNrYWdlcyB0aGF0IGFyZSBkaXJlY3RseSByZXF1aXJlZCBieSB0aGUgcm9vdCBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3N0cmljdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUmV0dXJuIGEgbm9uLXplcm8gZXhpdCBjb2RlIHdoZW4gdGhlcmUgYXJlIG91dGRhdGVkIHBhY2thZ2VzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsICdmJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnRm9ybWF0IG9mIHRoZSBvdXRwdXQ6IHRleHQgb3IganNvbicsICd0ZXh0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgc2VhcmNoIGluIHJlcXVpcmUtZGV2IHBhY2thZ2VzLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHNob3cgY29tbWFuZCBkaXNwbGF5cyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhIHBhY2thZ2UsIG9yCmxpc3RzIGFsbCBwYWNrYWdlcyBhdmFpbGFibGUuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNzaG93CkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3RyZWUnKSkgewogICAgICAgICAgICAkdGhpcy0+aW5pdFN0eWxlcygkb3V0cHV0KTsKICAgICAgICB9CgogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignaW5zdGFsbGVkJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAiaW5zdGFsbGVkIi4gT25seSBpbnN0YWxsZWQgcGFja2FnZXMgYXJlIHNob3duIGJ5IGRlZmF1bHQgbm93LiBUaGUgLS1hbGwgb3B0aW9uIGNhbiBiZSB1c2VkIHRvIHNob3cgYWxsIHBhY2thZ2VzLjwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignb3V0ZGF0ZWQnKSkgewogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbignbGF0ZXN0JywgdHJ1ZSk7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgdXNpbmcgdGhlIG9wdGlvbiAiaWdub3JlIiBmb3IgYWN0aW9uIG90aGVyIHRoYW4gIm91dGRhdGVkIiwgaXQgd2lsbCBiZSBpZ25vcmVkLjwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGlyZWN0JykgJiYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdhbGwnKSB8fCAkaW5wdXQtPmdldE9wdGlvbignYXZhaWxhYmxlJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3BsYXRmb3JtJykpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignVGhlIC0tZGlyZWN0ICgtRCkgb3B0aW9uIGlzIG5vdCB1c2FibGUgaW4gY29tYmluYXRpb24gd2l0aCAtLWFsbCwgLS1wbGF0Zm9ybSAoLXApIG9yIC0tYXZhaWxhYmxlICgtYSknKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd0cmVlJykgJiYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdhbGwnKSB8fCAkaW5wdXQtPmdldE9wdGlvbignYXZhaWxhYmxlJykpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignVGhlIC0tdHJlZSAoLXQpIG9wdGlvbiBpcyBub3QgdXNhYmxlIGluIGNvbWJpbmF0aW9uIHdpdGggLS1hbGwgb3IgLS1hdmFpbGFibGUgKC1hKScpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3RyZWUnKSAmJiAkaW5wdXQtPmdldE9wdGlvbignbGF0ZXN0JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdUaGUgLS10cmVlICgtdCkgb3B0aW9uIGlzIG5vdCB1c2FibGUgaW4gY29tYmluYXRpb24gd2l0aCAtLWxhdGVzdCAoLWwpJyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndHJlZScpICYmICRpbnB1dC0+Z2V0T3B0aW9uKCdwYXRoJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdUaGUgLS10cmVlICgtdCkgb3B0aW9uIGlzIG5vdCB1c2FibGUgaW4gY29tYmluYXRpb24gd2l0aCAtLXBhdGggKC1QKScpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAkZm9ybWF0ID0gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpOwogICAgICAgIGlmICghaW5fYXJyYXkoJGZvcm1hdCwgYXJyYXkoJ3RleHQnLCAnanNvbicpKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3Ioc3ByaW50ZignVW5zdXBwb3J0ZWQgZm9ybWF0ICIlcyIuIFNlZSBoZWxwIGZvciBzdXBwb3J0ZWQgZm9ybWF0cy4nLCAkZm9ybWF0KSk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIC8vIGluaXQgcmVwb3MKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSBhcnJheSgpOwogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJHBsYXRmb3JtT3ZlcnJpZGVzID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdwbGF0Zm9ybScpID86IGFycmF5KCk7CiAgICAgICAgfQogICAgICAgICRwbGF0Zm9ybVJlcG8gPSBuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KGFycmF5KCksICRwbGF0Zm9ybU92ZXJyaWRlcyk7CiAgICAgICAgJGxvY2tlZFJlcG8gPSBudWxsOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3NlbGYnKSkgewogICAgICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5nZXRDb21wb3NlcigpLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbmFtZS1vbmx5JykpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJHBhY2thZ2UtPmdldE5hbWUoKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlcG9zID0gJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheShuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRwYWNrYWdlKSkpOwogICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmdldE9wdGlvbigncGxhdGZvcm0nKSkgewogICAgICAgICAgICAkcmVwb3MgPSAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRwbGF0Zm9ybVJlcG8pKTsKICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2F2YWlsYWJsZScpKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkoJHBsYXRmb3JtUmVwbykpOwogICAgICAgICAgICBpZiAoJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICAgICAkcmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeSgkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpKTsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvLT5hZGRSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGRlZmF1bHRSZXBvcyA9IFJlcG9zaXRvcnlGYWN0b3J5OjpkZWZhdWx0UmVwb3MoJGlvKTsKICAgICAgICAgICAgICAgICRyZXBvcyA9IG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KCRkZWZhdWx0UmVwb3MpOwogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdObyBjb21wb3Nlci5qc29uIGZvdW5kIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgc2hvd2luZyBhdmFpbGFibGUgcGFja2FnZXMgZnJvbSAnIC4gaW1wbG9kZSgnLCAnLCBhcnJheV9rZXlzKCRkZWZhdWx0UmVwb3MpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2FsbCcpICYmICRjb21wb3NlcikgewogICAgICAgICAgICAkbG9jYWxSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgJGxvY2tlciA9ICRjb21wb3Nlci0+Z2V0TG9ja2VyKCk7CiAgICAgICAgICAgIGlmICgkbG9ja2VyLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICAgICAkbG9ja2VkUmVwbyA9ICRsb2NrZXItPmdldExvY2tlZFJlcG9zaXRvcnkodHJ1ZSk7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRsb2NrZWRSZXBvLCAkbG9jYWxSZXBvLCAkcGxhdGZvcm1SZXBvKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRsb2NhbFJlcG8sICRwbGF0Zm9ybVJlcG8pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZShhcnJheSgkaW5zdGFsbGVkUmVwbyksICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0UmVwb3NpdG9yaWVzKCkpKTsKICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2FsbCcpKSB7CiAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCRpbyk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignTm8gY29tcG9zZXIuanNvbiBmb3VuZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnksIHNob3dpbmcgYXZhaWxhYmxlIHBhY2thZ2VzIGZyb20gJyAuIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkZGVmYXVsdFJlcG9zKSkpOwogICAgICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRwbGF0Zm9ybVJlcG8pKTsKICAgICAgICAgICAgJHJlcG9zID0gbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoYXJyYXlfbWVyZ2UoYXJyYXkoJGluc3RhbGxlZFJlcG8pLCAkZGVmYXVsdFJlcG9zKSk7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdsb2NrZWQnKSkgewogICAgICAgICAgICBpZiAoISRjb21wb3NlciB8fCAhJGNvbXBvc2VyLT5nZXRMb2NrZXIoKS0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0EgdmFsaWQgY29tcG9zZXIuanNvbiBhbmQgY29tcG9zZXIubG9jayBmaWxlcyBpcyByZXF1aXJlZCB0byBydW4gdGhpcyBjb21tYW5kIHdpdGggLS1sb2NrZWQnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbG9ja2VyID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKTsKICAgICAgICAgICAgJGxvY2tlZFJlcG8gPSAkbG9ja2VyLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpOwogICAgICAgICAgICAkcmVwb3MgPSAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRsb2NrZWRSZXBvKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gLS1pbnN0YWxsZWQgLyBkZWZhdWx0IGNhc2UKICAgICAgICAgICAgaWYgKCEkY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyb290UGtnID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgICRyZXBvcyA9ICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKSkpOwoKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmZpbHRlclJlcXVpcmVkUGFja2FnZXMoJGluc3RhbGxlZFJlcG8sICRyb290UGtnKTsKICAgICAgICAgICAgICAgICRyZXBvcyA9ICRpbnN0YWxsZWRSZXBvID0gbmV3IEluc3RhbGxlZFJlcG9zaXRvcnkoYXJyYXkobmV3IEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeShhcnJheV9tYXAoZnVuY3Rpb24gKCRwa2cpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xvbmUgJHBrZzsKICAgICAgICAgICAgICAgIH0sICRwYWNrYWdlcykpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCkgJiYgKCRyb290UGtnLT5nZXRSZXF1aXJlcygpIHx8ICRyb290UGtnLT5nZXREZXZSZXF1aXJlcygpKSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5ObyBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkLiBUcnkgcnVubmluZyBjb21wb3NlciBpbnN0YWxsIG9yIHVwZGF0ZS48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkY29tcG9zZXIpIHsKICAgICAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnc2hvdycsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoKCRjb21tYW5kRXZlbnQtPmdldE5hbWUoKSwgJGNvbW1hbmRFdmVudCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpICYmIG51bGwgPT09ICRjb21wb3NlcikgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ05vIGNvbXBvc2VyLmpzb24gZm91bmQgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LCBkaXNhYmxpbmcgImxhdGVzdCIgb3B0aW9uJyk7CiAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCdsYXRlc3QnLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZUZpbHRlciA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2UnKTsKCiAgICAgICAgLy8gc2hvdyBzaW5nbGUgcGFja2FnZSBvciBzaW5nbGUgdmVyc2lvbgogICAgICAgIGlmICgoJHBhY2thZ2VGaWx0ZXIgJiYgZmFsc2UgPT09IHN0cnBvcygkcGFja2FnZUZpbHRlciwgJyonKSkgfHwgIWVtcHR5KCRwYWNrYWdlKSkgewogICAgICAgICAgICBpZiAoZW1wdHkoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICBsaXN0KCRwYWNrYWdlLCAkdmVyc2lvbnMpID0gJHRoaXMtPmdldFBhY2thZ2UoJGluc3RhbGxlZFJlcG8sICRyZXBvcywgJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpLCAkaW5wdXQtPmdldEFyZ3VtZW50KCd2ZXJzaW9uJykpOwoKICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICAkb3B0aW9ucyA9ICRpbnB1dC0+Z2V0T3B0aW9ucygpOwogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJG9wdGlvbnNbJ3dvcmtpbmctZGlyJ10pIHx8ICFmaWxlX2V4aXN0cygnY29tcG9zZXIuanNvbicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2UnKSkgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCdwbGF0Zm9ybScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnIC4gJHBhY2thZ2VGaWx0ZXIgLiAnIG5vdCBmb3VuZCwgdHJ5IHVzaW5nIC0tcGxhdGZvcm0gKC1wKSB0byBzaG93IHBsYXRmb3JtIHBhY2thZ2VzLicpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlICcgLiAkcGFja2FnZUZpbHRlciAuICcgbm90IGZvdW5kJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1BhY2thZ2UgJyAuICRwYWNrYWdlRmlsdGVyIC4gJyBub3QgZm91bmQgaW4gJyAuICRvcHRpb25zWyd3b3JraW5nLWRpciddIC4gJy9jb21wb3Nlci5qc29uJyk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHZlcnNpb25zID0gYXJyYXkoJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSA9PiAkcGFja2FnZS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGV4aXRDb2RlID0gMDsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd0cmVlJykpIHsKICAgICAgICAgICAgICAgICRhcnJheVRyZWUgPSAkdGhpcy0+Z2VuZXJhdGVQYWNrYWdlVHJlZSgkcGFja2FnZSwgJGluc3RhbGxlZFJlcG8sICRyZXBvcyk7CgogICAgICAgICAgICAgICAgaWYgKCdqc29uJyA9PT0gJGZvcm1hdCkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoSnNvbkZpbGU6OmVuY29kZShhcnJheSgnaW5zdGFsbGVkJyA9PiBhcnJheSgkYXJyYXlUcmVlKSkpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlQYWNrYWdlVHJlZShhcnJheSgkYXJyYXlUcmVlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbGF0ZXN0UGFja2FnZSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpKSB7CiAgICAgICAgICAgICAgICAgICAgJGxhdGVzdFBhY2thZ2UgPSAkdGhpcy0+ZmluZExhdGVzdFBhY2thZ2UoJHBhY2thZ2UsICRjb21wb3NlciwgJHBsYXRmb3JtUmVwbywgJGlucHV0LT5nZXRPcHRpb24oJ21pbm9yLW9ubHknKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykgJiYgJGlucHV0LT5nZXRPcHRpb24oJ3N0cmljdCcpICYmICRsYXRlc3RQYWNrYWdlICYmICRsYXRlc3RQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpICE9PSAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAmJiAhJGxhdGVzdFBhY2thZ2UtPmlzQWJhbmRvbmVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdwYXRoJykpIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRwYWNrYWdlLT5nZXROYW1lKCksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcgJyAuIHN0cnRvayhyZWFscGF0aCgkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpKSwgIlxyXG4iKSk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZXhpdENvZGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCdqc29uJyA9PT0gJGZvcm1hdCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5wcmludFBhY2thZ2VJbmZvQXNKc29uKCRwYWNrYWdlLCAkdmVyc2lvbnMsICRpbnN0YWxsZWRSZXBvLCAkbGF0ZXN0UGFja2FnZSA/OiBudWxsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnByaW50UGFja2FnZUluZm8oJHBhY2thZ2UsICR2ZXJzaW9ucywgJGluc3RhbGxlZFJlcG8sICRsYXRlc3RQYWNrYWdlID86IG51bGwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGV4aXRDb2RlOwogICAgICAgIH0KCiAgICAgICAgLy8gc2hvdyB0cmVlIHZpZXcgaWYgcmVxdWVzdGVkCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd0cmVlJykpIHsKICAgICAgICAgICAgJHJvb3RSZXF1aXJlcyA9ICR0aGlzLT5nZXRSb290UmVxdWlyZXMoKTsKICAgICAgICAgICAgJHBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCk7CiAgICAgICAgICAgIHVzb3J0KCRwYWNrYWdlcywgJ3N0cmNtcCcpOwogICAgICAgICAgICAkYXJyYXlUcmVlID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJHJvb3RSZXF1aXJlcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAkYXJyYXlUcmVlW10gPSAkdGhpcy0+Z2VuZXJhdGVQYWNrYWdlVHJlZSgkcGFja2FnZSwgJGluc3RhbGxlZFJlcG8sICRyZXBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgnanNvbicgPT09ICRmb3JtYXQpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoSnNvbkZpbGU6OmVuY29kZShhcnJheSgnaW5zdGFsbGVkJyA9PiAkYXJyYXlUcmVlKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlQYWNrYWdlVHJlZSgkYXJyYXlUcmVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlcG9zIGluc3RhbmNlb2YgQ29tcG9zaXRlUmVwb3NpdG9yeSkgewogICAgICAgICAgICAkcmVwb3MgPSAkcmVwb3MtPmdldFJlcG9zaXRvcmllcygpOwogICAgICAgIH0gZWxzZWlmICghaXNfYXJyYXkoJHJlcG9zKSkgewogICAgICAgICAgICAkcmVwb3MgPSBhcnJheSgkcmVwb3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gbGlzdCBwYWNrYWdlcwogICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgJHBhY2thZ2VGaWx0ZXJSZWdleCA9IG51bGw7CiAgICAgICAgaWYgKG51bGwgIT09ICRwYWNrYWdlRmlsdGVyKSB7CiAgICAgICAgICAgICRwYWNrYWdlRmlsdGVyUmVnZXggPSAne14nLnN0cl9yZXBsYWNlKCdcXConLCAnLio/JywgcHJlZ19xdW90ZSgkcGFja2FnZUZpbHRlcikpLickfWknOwogICAgICAgIH0KCiAgICAgICAgJHBhY2thZ2VMaXN0RmlsdGVyID0gYXJyYXkoKTsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2RpcmVjdCcpKSB7CiAgICAgICAgICAgICRwYWNrYWdlTGlzdEZpbHRlciA9ICR0aGlzLT5nZXRSb290UmVxdWlyZXMoKTsKICAgICAgICB9CgogICAgICAgIGlmIChjbGFzc19leGlzdHMoJ1N5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcVGVybWluYWwnKSkgewogICAgICAgICAgICAkdGVybWluYWwgPSBuZXcgVGVybWluYWwoKTsKICAgICAgICAgICAgJHdpZHRoID0gJHRlcm1pbmFsLT5nZXRXaWR0aCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEZvciB2ZXJzaW9ucyBvZiBTeW1mb255IGNvbnNvbGUgYmVmb3JlIDMuMgogICAgICAgICAgICBsaXN0KCR3aWR0aCkgPSAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+Z2V0VGVybWluYWxEaW1lbnNpb25zKCk7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsID09PSAkd2lkdGgpIHsKICAgICAgICAgICAgLy8gSW4gY2FzZSB0aGUgd2lkdGggaXMgbm90IGRldGVjdGVkLCB3ZSdyZSBwcm9iYWJseSBydW5uaW5nIHRoZSBjb21tYW5kCiAgICAgICAgICAgIC8vIG91dHNpZGUgb2YgYSByZWFsIHRlcm1pbmFsLCB1c2Ugc3BhY2Ugd2l0aG91dCBhIGxpbWl0CiAgICAgICAgICAgICR3aWR0aCA9IFBIUF9JTlRfTUFYOwogICAgICAgIH0KICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICR3aWR0aC0tOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR3aWR0aCA9IG1heCg4MCwgJHdpZHRoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigncGF0aCcpICYmIG51bGwgPT09ICRjb21wb3NlcikgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ05vIGNvbXBvc2VyLmpzb24gZm91bmQgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LCBkaXNhYmxpbmcgInBhdGgiIG9wdGlvbicpOwogICAgICAgICAgICAkaW5wdXQtPnNldE9wdGlvbigncGF0aCcsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZXBvcyBhcyAkcmVwbykgewogICAgICAgICAgICBpZiAoJHJlcG8gPT09ICRwbGF0Zm9ybVJlcG8pIHsKICAgICAgICAgICAgICAgICR0eXBlID0gJ3BsYXRmb3JtJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRsb2NrZWRSZXBvICE9PSBudWxsICYmICRyZXBvID09PSAkbG9ja2VkUmVwbykgewogICAgICAgICAgICAgICAgJHR5cGUgPSAnbG9ja2VkJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRyZXBvID09PSAkaW5zdGFsbGVkUmVwbyB8fCBpbl9hcnJheSgkcmVwbywgJGluc3RhbGxlZFJlcG8tPmdldFJlcG9zaXRvcmllcygpLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHR5cGUgPSAnaW5zdGFsbGVkJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0eXBlID0gJ2F2YWlsYWJsZSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRyZXBvIGluc3RhbmNlb2YgQ29tcG9zZXJSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZU5hbWVzKCRwYWNrYWdlRmlsdGVyKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlc1skdHlwZV1bJG5hbWVdID0gJG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVwby0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXSkKICAgICAgICAgICAgICAgICAgICAgICAgfHwgIWlzX29iamVjdCgkcGFja2FnZXNbJHR5cGVdWyRwYWNrYWdlLT5nZXROYW1lKCldKQogICAgICAgICAgICAgICAgICAgICAgICB8fCB2ZXJzaW9uX2NvbXBhcmUoJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0VmVyc2lvbigpLCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAnPCcpCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHBhY2thZ2VGaWx0ZXJSZWdleCB8fCBwcmVnX21hdGNoKCRwYWNrYWdlRmlsdGVyUmVnZXgsICRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRwYWNrYWdlTGlzdEZpbHRlciB8fCBpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcGFja2FnZUxpc3RGaWx0ZXIsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzWyR0eXBlXVskcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkc2hvd0FsbFR5cGVzID0gJGlucHV0LT5nZXRPcHRpb24oJ2FsbCcpOwogICAgICAgICRzaG93TGF0ZXN0ID0gJGlucHV0LT5nZXRPcHRpb24oJ2xhdGVzdCcpOwogICAgICAgICRzaG93TWlub3JPbmx5ID0gJGlucHV0LT5nZXRPcHRpb24oJ21pbm9yLW9ubHknKTsKICAgICAgICAkaWdub3JlZFBhY2thZ2VzID0gYXJyYXlfbWFwKCdzdHJ0b2xvd2VyJywgJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZScpKTsKICAgICAgICAkaW5kZW50ID0gJHNob3dBbGxUeXBlcyA/ICcgICcgOiAnJzsKICAgICAgICAkbGF0ZXN0UGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICRleGl0Q29kZSA9IDA7CiAgICAgICAgJHZpZXdEYXRhID0gYXJyYXkoKTsKICAgICAgICAkdmlld01ldGFEYXRhID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoIChhcnJheSgncGxhdGZvcm0nID0+IHRydWUsICdsb2NrZWQnID0+IHRydWUsICdhdmFpbGFibGUnID0+IGZhbHNlLCAnaW5zdGFsbGVkJyA9PiB0cnVlKSBhcyAkdHlwZSA9PiAkc2hvd1ZlcnNpb24pIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlc1skdHlwZV0pKSB7CiAgICAgICAgICAgICAgICBrc29ydCgkcGFja2FnZXNbJHR5cGVdKTsKCiAgICAgICAgICAgICAgICAkbmFtZUxlbmd0aCA9ICR2ZXJzaW9uTGVuZ3RoID0gJGxhdGVzdExlbmd0aCA9IDA7CgogICAgICAgICAgICAgICAgaWYgKCRzaG93TGF0ZXN0ICYmICRzaG93VmVyc2lvbikgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlc1skdHlwZV0gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX29iamVjdCgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJHRoaXMtPmZpbmRMYXRlc3RQYWNrYWdlKCRwYWNrYWdlLCAkY29tcG9zZXIsICRwbGF0Zm9ybVJlcG8sICRzaG93TWlub3JPbmx5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGF0ZXN0UGFja2FnZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGF0ZXN0UGFja2FnZXNbJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKV0gPSAkbGF0ZXN0UGFja2FnZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkd3JpdGVQYXRoID0gISRpbnB1dC0+Z2V0T3B0aW9uKCduYW1lLW9ubHknKSAmJiAkaW5wdXQtPmdldE9wdGlvbigncGF0aCcpOwogICAgICAgICAgICAgICAgJHdyaXRlVmVyc2lvbiA9ICEkaW5wdXQtPmdldE9wdGlvbignbmFtZS1vbmx5JykgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCdwYXRoJykgJiYgJHNob3dWZXJzaW9uOwogICAgICAgICAgICAgICAgJHdyaXRlTGF0ZXN0ID0gJHdyaXRlVmVyc2lvbiAmJiAkc2hvd0xhdGVzdDsKICAgICAgICAgICAgICAgICR3cml0ZURlc2NyaXB0aW9uID0gISRpbnB1dC0+Z2V0T3B0aW9uKCduYW1lLW9ubHknKSAmJiAhJGlucHV0LT5nZXRPcHRpb24oJ3BhdGgnKTsKCiAgICAgICAgICAgICAgICAkaGFzT3V0ZGF0ZWRQYWNrYWdlcyA9IGZhbHNlOwoKICAgICAgICAgICAgICAgICR2aWV3RGF0YVskdHlwZV0gPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzWyR0eXBlXSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGEgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRzaG93TGF0ZXN0ICYmIGlzc2V0KCRsYXRlc3RQYWNrYWdlc1skcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJGxhdGVzdFBhY2thZ2VzWyRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCldOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgaWYgQ29tcG9zZXIgaXMgY2hlY2tpbmcgb3V0ZGF0ZWQgZGVwZW5kZW5jaWVzIGFuZCBpZiBjdXJyZW50IHBhY2thZ2Ugc2hvdWxkIHRyaWdnZXIgbm9uLWRlZmF1bHQgZXhpdCBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlSXNVcFRvRGF0ZSA9ICRsYXRlc3RQYWNrYWdlICYmICRsYXRlc3RQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpID09PSAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAmJiAhJGxhdGVzdFBhY2thZ2UtPmlzQWJhbmRvbmVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlSXNJZ25vcmVkID0gXGluX2FycmF5KCRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksICRpZ25vcmVkUGFja2FnZXMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykgJiYgKCRwYWNrYWdlSXNVcFRvRGF0ZSB8fCAkcGFja2FnZUlzSWdub3JlZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ291dGRhdGVkJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3N0cmljdCcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaGFzT3V0ZGF0ZWRQYWNrYWdlcyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGFbJ25hbWUnXSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRuYW1lTGVuZ3RoID0gbWF4KCRuYW1lTGVuZ3RoLCBzdHJsZW4oJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHdyaXRlVmVyc2lvbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VWaWV3RGF0YVsndmVyc2lvbiddID0gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbkxlbmd0aCA9IG1heCgkdmVyc2lvbkxlbmd0aCwgc3RybGVuKCRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR3cml0ZUxhdGVzdCAmJiAkbGF0ZXN0UGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VWaWV3RGF0YVsnbGF0ZXN0J10gPSAkbGF0ZXN0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGFbJ2xhdGVzdC1zdGF0dXMnXSA9ICR0aGlzLT5nZXRVcGRhdGVTdGF0dXMoJGxhdGVzdFBhY2thZ2UsICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RMZW5ndGggPSBtYXgoJGxhdGVzdExlbmd0aCwgc3RybGVuKCRsYXRlc3RQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR3cml0ZURlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWydkZXNjcmlwdGlvbiddID0gJHBhY2thZ2UtPmdldERlc2NyaXB0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR3cml0ZVBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlVmlld0RhdGFbJ3BhdGgnXSA9IHN0cnRvayhyZWFscGF0aCgkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpKSwgIlxyXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlICYmICRsYXRlc3RQYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnQgPSBpc19zdHJpbmcoJGxhdGVzdFBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJ1VzZSAnIC4gJGxhdGVzdFBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpIC4gJyBpbnN0ZWFkJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ05vIHJlcGxhY2VtZW50IHdhcyBzdWdnZXN0ZWQnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VXYXJuaW5nID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUGFja2FnZSAlcyBpcyBhYmFuZG9uZWQsIHlvdSBzaG91bGQgYXZvaWQgdXNpbmcgaXQuICVzLicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWyd3YXJuaW5nJ10gPSAkcGFja2FnZVdhcm5pbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZVZpZXdEYXRhWyduYW1lJ10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5hbWVMZW5ndGggPSBtYXgoJG5hbWVMZW5ndGgsIHN0cmxlbigkcGFja2FnZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdmlld0RhdGFbJHR5cGVdW10gPSAkcGFja2FnZVZpZXdEYXRhOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHZpZXdNZXRhRGF0YVskdHlwZV0gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZUxlbmd0aCcgPT4gJG5hbWVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgJ3ZlcnNpb25MZW5ndGgnID0+ICR2ZXJzaW9uTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICdsYXRlc3RMZW5ndGgnID0+ICRsYXRlc3RMZW5ndGgsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdzdHJpY3QnKSAmJiAkaGFzT3V0ZGF0ZWRQYWNrYWdlcykgewogICAgICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IDE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgnanNvbicgPT09ICRmb3JtYXQpIHsKICAgICAgICAgICAgJGlvLT53cml0ZShKc29uRmlsZTo6ZW5jb2RlKCR2aWV3RGF0YSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR2aWV3RGF0YSBhcyAkdHlwZSA9PiAkcGFja2FnZXMpIHsKICAgICAgICAgICAgICAgICRuYW1lTGVuZ3RoID0gJHZpZXdNZXRhRGF0YVskdHlwZV1bJ25hbWVMZW5ndGgnXTsKICAgICAgICAgICAgICAgICR2ZXJzaW9uTGVuZ3RoID0gJHZpZXdNZXRhRGF0YVskdHlwZV1bJ3ZlcnNpb25MZW5ndGgnXTsKICAgICAgICAgICAgICAgICRsYXRlc3RMZW5ndGggPSAkdmlld01ldGFEYXRhWyR0eXBlXVsnbGF0ZXN0TGVuZ3RoJ107CgogICAgICAgICAgICAgICAgJHdyaXRlVmVyc2lvbiA9ICRuYW1lTGVuZ3RoICsgJHZlcnNpb25MZW5ndGggKyAzIDw9ICR3aWR0aDsKICAgICAgICAgICAgICAgICR3cml0ZUxhdGVzdCA9ICRuYW1lTGVuZ3RoICsgJHZlcnNpb25MZW5ndGggKyAkbGF0ZXN0TGVuZ3RoICsgMyA8PSAkd2lkdGg7CiAgICAgICAgICAgICAgICAkd3JpdGVEZXNjcmlwdGlvbiA9ICRuYW1lTGVuZ3RoICsgJHZlcnNpb25MZW5ndGggKyAkbGF0ZXN0TGVuZ3RoICsgMjQgPD0gJHdpZHRoOwoKICAgICAgICAgICAgICAgIGlmICgkd3JpdGVMYXRlc3QgJiYgISRpby0+aXNEZWNvcmF0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICRsYXRlc3RMZW5ndGggKz0gMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHNob3dBbGxUeXBlcykgewogICAgICAgICAgICAgICAgICAgIGlmICgnYXZhaWxhYmxlJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGNvbW1lbnQ+JyAuICR0eXBlIC4gJzwvY29tbWVudD46Jyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+JyAuICR0eXBlIC4gJzwvaW5mbz46Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJGluZGVudCAuIHN0cl9wYWQoJHBhY2thZ2VbJ25hbWUnXSwgJG5hbWVMZW5ndGgsICcgJyksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ3ZlcnNpb24nXSkgJiYgJHdyaXRlVmVyc2lvbikgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcgJyAuIHN0cl9wYWQoJHBhY2thZ2VbJ3ZlcnNpb24nXSwgJHZlcnNpb25MZW5ndGgsICcgJyksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlWydsYXRlc3QnXSkgJiYgJHdyaXRlTGF0ZXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRsYXRlc3RWZXJzaW9uID0gJHBhY2thZ2VbJ2xhdGVzdCddOwogICAgICAgICAgICAgICAgICAgICAgICAkdXBkYXRlU3RhdHVzID0gJHBhY2thZ2VbJ2xhdGVzdC1zdGF0dXMnXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHN0eWxlID0gJHRoaXMtPnVwZGF0ZVN0YXR1c1RvVmVyc2lvblN0eWxlKCR1cGRhdGVTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRpby0+aXNEZWNvcmF0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhdGVzdFZlcnNpb24gPSBzdHJfcmVwbGFjZShhcnJheSgndXAtdG8tZGF0ZScsICdzZW12ZXItc2FmZS11cGRhdGUnLCAndXBkYXRlLXBvc3NpYmxlJyksIGFycmF5KCc9JywgJyEnLCAnficpLCAkdXBkYXRlU3RhdHVzKSAuICcgJyAuICRsYXRlc3RWZXJzaW9uOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJyA8JyAuICRzdHlsZSAuICc+JyAuIHN0cl9wYWQoJGxhdGVzdFZlcnNpb24sICRsYXRlc3RMZW5ndGgsICcgJykgLiAnPC8nIC4gJHN0eWxlIC4gJz4nLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsnZGVzY3JpcHRpb24nXSkgJiYgJHdyaXRlRGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gc3RydG9rKCRwYWNrYWdlWydkZXNjcmlwdGlvbiddLCAiXHJcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAkcmVtYWluaW5nID0gJHdpZHRoIC0gJG5hbWVMZW5ndGggLSAkdmVyc2lvbkxlbmd0aCAtIDQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkd3JpdGVMYXRlc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZW1haW5pbmcgLT0gJGxhdGVzdExlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRkZXNjcmlwdGlvbikgPiAkcmVtYWluaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gPSBzdWJzdHIoJGRlc2NyaXB0aW9uLCAwLCAkcmVtYWluaW5nIC0gMykgLiAnLi4uJzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCcgJyAuICRkZXNjcmlwdGlvbiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHBhY2thZ2VbJ3BhdGgnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnICcgLiAkcGFja2FnZVsncGF0aCddLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJycpOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsnd2FybmluZyddKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8d2FybmluZz4nIC4gJHBhY2thZ2VbJ3dhcm5pbmcnXSAuICc8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkc2hvd0FsbFR5cGVzKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkZXhpdENvZGU7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFJvb3RSZXF1aXJlcygpCiAgICB7CiAgICAgICAgJHJvb3RQYWNrYWdlID0gJHRoaXMtPmdldENvbXBvc2VyKCktPmdldFBhY2thZ2UoKTsKCiAgICAgICAgcmV0dXJuIGFycmF5X21hcCgKICAgICAgICAgICAgJ3N0cnRvbG93ZXInLAogICAgICAgICAgICBhcnJheV9rZXlzKGFycmF5X21lcmdlKCRyb290UGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwgJHJvb3RQYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpKSkKICAgICAgICApOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRWZXJzaW9uU3R5bGUoUGFja2FnZUludGVyZmFjZSAkbGF0ZXN0UGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVwZGF0ZVN0YXR1c1RvVmVyc2lvblN0eWxlKCR0aGlzLT5nZXRVcGRhdGVTdGF0dXMoJGxhdGVzdFBhY2thZ2UsICRwYWNrYWdlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBmaW5kcyBhIHBhY2thZ2UgYnkgbmFtZSBhbmQgdmVyc2lvbiBpZiBwcm92aWRlZAogICAgICoKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeSAgICAgICAgJGluc3RhbGxlZFJlcG8KICAgICAqIEBwYXJhbSAgUmVwb3NpdG9yeUludGVyZmFjZSAgICAgICAgJHJlcG9zCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgKiBAcGFyYW0gIENvbnN0cmFpbnRJbnRlcmZhY2V8c3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYXJyYXkgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlLCBhcnJheSBvZiB2ZXJzaW9ucykKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBhY2thZ2UoSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywgUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwb3MsICRuYW1lLCAkdmVyc2lvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdHJ0b2xvd2VyKCRuYW1lKTsKICAgICAgICAkY29uc3RyYWludCA9IGlzX3N0cmluZygkdmVyc2lvbikgPyAkdGhpcy0+dmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkdmVyc2lvbikgOiAkdmVyc2lvbjsKCiAgICAgICAgJHBvbGljeSA9IG5ldyBEZWZhdWx0UG9saWN5KCk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQgPSBuZXcgUmVwb3NpdG9yeVNldCgnZGV2Jyk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFsbG93SW5zdGFsbGVkUmVwb3NpdG9yaWVzKCk7CiAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoJHJlcG9zKTsKCiAgICAgICAgJG1hdGNoZWRQYWNrYWdlID0gbnVsbDsKICAgICAgICAkdmVyc2lvbnMgPSBhcnJheSgpOwogICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRuYW1lKSkgewogICAgICAgICAgICAkcG9vbCA9ICRyZXBvc2l0b3J5U2V0LT5jcmVhdGVQb29sV2l0aEFsbFBhY2thZ2VzKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBvb2wgPSAkcmVwb3NpdG9yeVNldC0+Y3JlYXRlUG9vbEZvclBhY2thZ2UoJG5hbWUpOwogICAgICAgIH0KICAgICAgICAkbWF0Y2hlcyA9ICRwb29sLT53aGF0UHJvdmlkZXMoJG5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgLy8gc2VsZWN0IGFuIGV4YWN0IG1hdGNoIGlmIGl0IGlzIGluIHRoZSBpbnN0YWxsZWQgcmVwbyBhbmQgbm8gc3BlY2lmaWMgdmVyc2lvbiB3YXMgcmVxdWlyZWQKICAgICAgICAgICAgaWYgKG51bGwgPT09ICR2ZXJzaW9uICYmICRpbnN0YWxsZWRSZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgJG1hdGNoZWRQYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2ZXJzaW9uc1skcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpXSA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgICAgICRtYXRjaGVzWyRpbmRleF0gPSAkcGFja2FnZS0+Z2V0SWQoKTsKICAgICAgICB9CgogICAgICAgIC8vIHNlbGVjdCBwcmVmZXJyZWQgcGFja2FnZSBhY2NvcmRpbmcgdG8gcG9saWN5IHJ1bGVzCiAgICAgICAgaWYgKCEkbWF0Y2hlZFBhY2thZ2UgJiYgJG1hdGNoZXMgJiYgJHByZWZlcnJlZCA9ICRwb2xpY3ktPnNlbGVjdFByZWZlcnJlZFBhY2thZ2VzKCRwb29sLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgJG1hdGNoZWRQYWNrYWdlID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJHByZWZlcnJlZFswXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoJG1hdGNoZWRQYWNrYWdlLCAkdmVyc2lvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIHBhY2thZ2UgaW5mby4KICAgICAqCiAgICAgKiBAcGFyYW0gQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucwogICAgICogQHBhcmFtIEluc3RhbGxlZFJlcG9zaXRvcnkgICAgICAkaW5zdGFsbGVkUmVwbwogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAgICAkbGF0ZXN0UGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRQYWNrYWdlSW5mbyhDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIGFycmF5ICR2ZXJzaW9ucywgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywgUGFja2FnZUludGVyZmFjZSAkbGF0ZXN0UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgICR0aGlzLT5wcmludE1ldGEoJHBhY2thZ2UsICR2ZXJzaW9ucywgJGluc3RhbGxlZFJlcG8sICRsYXRlc3RQYWNrYWdlID86IG51bGwpOwogICAgICAgICR0aGlzLT5wcmludExpbmtzKCRwYWNrYWdlLCBMaW5rOjpUWVBFX1JFUVVJUkUpOwogICAgICAgICR0aGlzLT5wcmludExpbmtzKCRwYWNrYWdlLCBMaW5rOjpUWVBFX0RFVl9SRVFVSVJFLCAncmVxdWlyZXMgKGRldiknKTsKCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRTdWdnZXN0cygpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoIlxuPGluZm8+c3VnZ2VzdHM8L2luZm8+Iik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRTdWdnZXN0cygpIGFzICRzdWdnZXN0ZWQgPT4gJHJlYXNvbikgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgkc3VnZ2VzdGVkIC4gJyA8Y29tbWVudD4nIC4gJHJlYXNvbiAuICc8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcmludExpbmtzKCRwYWNrYWdlLCBMaW5rOjpUWVBFX1BST1ZJREUpOwogICAgICAgICR0aGlzLT5wcmludExpbmtzKCRwYWNrYWdlLCBMaW5rOjpUWVBFX0NPTkZMSUNUKTsKICAgICAgICAkdGhpcy0+cHJpbnRMaW5rcygkcGFja2FnZSwgTGluazo6VFlQRV9SRVBMQUNFKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByaW50cyBwYWNrYWdlIG1ldGFkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeSAgICAgICRpbnN0YWxsZWRSZXBvCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZXxudWxsICAgICRsYXRlc3RQYWNrYWdlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludE1ldGEoQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBhcnJheSAkdmVyc2lvbnMsIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGxhdGVzdFBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPm5hbWU8L2luZm8+ICAgICA6ICcgLiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpKTsKICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz5kZXNjcmlwLjwvaW5mbz4gOiAnIC4gJHBhY2thZ2UtPmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPmtleXdvcmRzPC9pbmZvPiA6ICcgLiBpbXBsb2RlKCcsICcsICRwYWNrYWdlLT5nZXRLZXl3b3JkcygpID86IGFycmF5KCkpKTsKICAgICAgICAkdGhpcy0+cHJpbnRWZXJzaW9ucygkcGFja2FnZSwgJHZlcnNpb25zLCAkaW5zdGFsbGVkUmVwbyk7CiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlKSB7CiAgICAgICAgICAgICRzdHlsZSA9ICR0aGlzLT5nZXRWZXJzaW9uU3R5bGUoJGxhdGVzdFBhY2thZ2UsICRwYWNrYWdlKTsKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+bGF0ZXN0PC9pbmZvPiAgIDogPCcuJHN0eWxlLic+JyAuICRsYXRlc3RQYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgLiAnPC8nLiRzdHlsZS4nPicpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgfQogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPnR5cGU8L2luZm8+ICAgICA6ICcgLiAkcGFja2FnZS0+Z2V0VHlwZSgpKTsKICAgICAgICAkdGhpcy0+cHJpbnRMaWNlbnNlcygkcGFja2FnZSk7CiAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+aG9tZXBhZ2U8L2luZm8+IDogJyAuICRwYWNrYWdlLT5nZXRIb21lcGFnZSgpKTsKICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz5zb3VyY2U8L2luZm8+ICAgOiAnIC4gc3ByaW50ZignWyVzXSA8Y29tbWVudD4lczwvY29tbWVudD4gJXMnLCAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpLCAkcGFja2FnZS0+Z2V0U291cmNlVXJsKCksICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkpOwogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPmRpc3Q8L2luZm8+ICAgICA6ICcgLiBzcHJpbnRmKCdbJXNdIDxjb21tZW50PiVzPC9jb21tZW50PiAlcycsICRwYWNrYWdlLT5nZXREaXN0VHlwZSgpLCAkcGFja2FnZS0+Z2V0RGlzdFVybCgpLCAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKSk7CiAgICAgICAgaWYgKCRpbnN0YWxsZWRSZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz5wYXRoPC9pbmZvPiAgICAgOiAnIC4gc3ByaW50ZignJXMnLCByZWFscGF0aCgkdGhpcy0+Z2V0Q29tcG9zZXIoKS0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSkpKSk7CiAgICAgICAgfQogICAgICAgICRpby0+d3JpdGUoJzxpbmZvPm5hbWVzPC9pbmZvPiAgICA6ICcgLiBpbXBsb2RlKCcsICcsICRwYWNrYWdlLT5nZXROYW1lcygpKSk7CgogICAgICAgIGlmICgkbGF0ZXN0UGFja2FnZS0+aXNBYmFuZG9uZWQoKSkgewogICAgICAgICAgICAkcmVwbGFjZW1lbnQgPSAoJGxhdGVzdFBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpICE9PSBudWxsKQogICAgICAgICAgICAgICAgPyAnIFRoZSBhdXRob3Igc3VnZ2VzdHMgdXNpbmcgdGhlICcgLiAkbGF0ZXN0UGFja2FnZS0+Z2V0UmVwbGFjZW1lbnRQYWNrYWdlKCkuICcgcGFja2FnZSBpbnN0ZWFkLicKICAgICAgICAgICAgICAgIDogbnVsbDsKCiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgIHNwcmludGYoJzx3YXJuaW5nPkF0dGVudGlvbjogVGhpcyBwYWNrYWdlIGlzIGFiYW5kb25lZCBhbmQgbm8gbG9uZ2VyIG1haW50YWluZWQuJXM8L3dhcm5pbmc+JywgJHJlcGxhY2VtZW50KQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRTdXBwb3J0KCkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZSgiXG48aW5mbz5zdXBwb3J0PC9pbmZvPiIpOwogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0U3VwcG9ydCgpIGFzICR0eXBlID0+ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGNvbW1lbnQ+JyAuICR0eXBlIC4gJzwvY29tbWVudD4gOiAnLiR2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QXV0b2xvYWQoKSkgewogICAgICAgICAgICAkaW8tPndyaXRlKCJcbjxpbmZvPmF1dG9sb2FkPC9pbmZvPiIpOwogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0QXV0b2xvYWQoKSBhcyAkdHlwZSA9PiAkYXV0b2xvYWRzKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8Y29tbWVudD4nIC4gJHR5cGUgLiAnPC9jb21tZW50PicpOwoKICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gJ3Bzci0wJyB8fCAkdHlwZSA9PT0gJ3Bzci00JykgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhdXRvbG9hZHMgYXMgJG5hbWUgPT4gJHBhdGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgoJG5hbWUgPzogJyonKSAuICcgPT4gJyAuIChpc19hcnJheSgkcGF0aCkgPyBpbXBsb2RlKCcsICcsICRwYXRoKSA6ICgkcGF0aCA/OiAnLicpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAnY2xhc3NtYXAnKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZShpbXBsb2RlKCcsICcsICRhdXRvbG9hZHMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldEluY2x1ZGVQYXRocygpKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8Y29tbWVudD5pbmNsdWRlLXBhdGg8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKGltcGxvZGUoJywgJywgJHBhY2thZ2UtPmdldEluY2x1ZGVQYXRocygpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludHMgYWxsIGF2YWlsYWJsZSB2ZXJzaW9ucyBvZiB0aGlzIHBhY2thZ2UgYW5kIGhpZ2hsaWdodHMgdGhlIGluc3RhbGxlZCBvbmUgaWYgYW55LgogICAgICoKICAgICAqIEBwYXJhbSBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICAgICAgJHZlcnNpb25zCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeSAgICAgICRpbnN0YWxsZWRSZXBvCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFZlcnNpb25zKENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgYXJyYXkgJHZlcnNpb25zLCBJbnN0YWxsZWRSZXBvc2l0b3J5ICRpbnN0YWxsZWRSZXBvKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5X2tleXMoJHZlcnNpb25zKTsKICAgICAgICAkdmVyc2lvbnMgPSBTZW12ZXI6OnJzb3J0KCR2ZXJzaW9ucyk7CgogICAgICAgIC8vIGhpZ2hsaWdodCBpbnN0YWxsZWQgdmVyc2lvbgogICAgICAgIGlmICgkaW5zdGFsbGVkUGFja2FnZXMgPSAkaW5zdGFsbGVkUmVwby0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRQYWNrYWdlcyBhcyAkaW5zdGFsbGVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGluc3RhbGxlZFZlcnNpb24gPSAkaW5zdGFsbGVkUGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgICAgICAgICAgJGtleSA9IGFycmF5X3NlYXJjaCgkaW5zdGFsbGVkVmVyc2lvbiwgJHZlcnNpb25zKTsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJGtleSkgewogICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uc1ska2V5XSA9ICc8aW5mbz4qICcgLiAkaW5zdGFsbGVkVmVyc2lvbiAuICc8L2luZm8+JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25zID0gaW1wbG9kZSgnLCAnLCAkdmVyc2lvbnMpOwoKICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJzxpbmZvPnZlcnNpb25zPC9pbmZvPiA6ICcgLiAkdmVyc2lvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogcHJpbnQgbGluayBvYmplY3RzCiAgICAgKgogICAgICogQHBhcmFtIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAkbGlua1R5cGUKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgJHRpdGxlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludExpbmtzKENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGxpbmtUeXBlLCAkdGl0bGUgPSBudWxsKQogICAgewogICAgICAgICR0aXRsZSA9ICR0aXRsZSA/OiAkbGlua1R5cGU7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKCRsaW5rcyA9ICRwYWNrYWdlLT57J2dldCcudWNmaXJzdCgkbGlua1R5cGUpfSgpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoIlxuPGluZm8+IiAuICR0aXRsZSAuICI8L2luZm8+Iik7CgogICAgICAgICAgICBmb3JlYWNoICgkbGlua3MgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJGxpbmstPmdldFRhcmdldCgpIC4gJyA8Y29tbWVudD4nIC4gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSAuICc8L2NvbW1lbnQ+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIGxpY2Vuc2VzIG9mIGEgcGFja2FnZSB3aXRoIG1ldGFkYXRhCiAgICAgKgogICAgICogQHBhcmFtIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcHJpbnRMaWNlbnNlcyhDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHNwZHhMaWNlbnNlcyA9IG5ldyBTcGR4TGljZW5zZXMoKTsKCiAgICAgICAgJGxpY2Vuc2VzID0gJHBhY2thZ2UtPmdldExpY2Vuc2UoKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgZm9yZWFjaCAoJGxpY2Vuc2VzIGFzICRsaWNlbnNlSWQpIHsKICAgICAgICAgICAgJGxpY2Vuc2UgPSAkc3BkeExpY2Vuc2VzLT5nZXRMaWNlbnNlQnlJZGVudGlmaWVyKCRsaWNlbnNlSWQpOyAvLyBrZXlzOiAwIGZ1bGxuYW1lLCAxIG9zaSwgMiB1cmwKCiAgICAgICAgICAgIGlmICghJGxpY2Vuc2UpIHsKICAgICAgICAgICAgICAgICRvdXQgPSAkbGljZW5zZUlkOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaXMgbGljZW5zZSBPU0kgYXBwcm92ZWQ/CiAgICAgICAgICAgICAgICBpZiAoJGxpY2Vuc2VbMV0gPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkb3V0ID0gc3ByaW50ZignJXMgKCVzKSAoT1NJIGFwcHJvdmVkKSAlcycsICRsaWNlbnNlWzBdLCAkbGljZW5zZUlkLCAkbGljZW5zZVsyXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRvdXQgPSBzcHJpbnRmKCclcyAoJXMpICVzJywgJGxpY2Vuc2VbMF0sICRsaWNlbnNlSWQsICRsaWNlbnNlWzJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+bGljZW5zZTwvaW5mbz4gIDogJyAuICRvdXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByaW50cyBwYWNrYWdlIGluZm8gaW4gSlNPTiBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbnMKICAgICAqIEBwYXJhbSBJbnN0YWxsZWRSZXBvc2l0b3J5ICAgICAgJGluc3RhbGxlZFJlcG8KICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlfG51bGwgICAgJGxhdGVzdFBhY2thZ2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByaW50UGFja2FnZUluZm9Bc0pzb24oQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBhcnJheSAkdmVyc2lvbnMsIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGxhdGVzdFBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICRqc29uID0gYXJyYXkoCiAgICAgICAgICAgICduYW1lJyA9PiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+ICRwYWNrYWdlLT5nZXREZXNjcmlwdGlvbigpLAogICAgICAgICAgICAna2V5d29yZHMnID0+ICRwYWNrYWdlLT5nZXRLZXl3b3JkcygpID86IGFycmF5KCksCiAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0VHlwZSgpLAogICAgICAgICAgICAnaG9tZXBhZ2UnID0+ICRwYWNrYWdlLT5nZXRIb21lcGFnZSgpLAogICAgICAgICAgICAnbmFtZXMnID0+ICRwYWNrYWdlLT5nZXROYW1lcygpLAogICAgICAgICk7CgogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZFZlcnNpb25zKCRqc29uLCAkdmVyc2lvbnMpOwogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZExpY2Vuc2VzKCRqc29uLCAkcGFja2FnZSk7CgogICAgICAgIGlmICgkbGF0ZXN0UGFja2FnZSkgewogICAgICAgICAgICAkanNvblsnbGF0ZXN0J10gPSAkbGF0ZXN0UGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRsYXRlc3RQYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFNvdXJjZVR5cGUoKSkgewogICAgICAgICAgICAkanNvblsnc291cmNlJ10gPSBhcnJheSgKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpLAogICAgICAgICAgICAgICAgJ3VybCcgPT4gJHBhY2thZ2UtPmdldFNvdXJjZVVybCgpLAogICAgICAgICAgICAgICAgJ3JlZmVyZW5jZScgPT4gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXREaXN0VHlwZSgpKSB7CiAgICAgICAgICAgICRqc29uWydkaXN0J10gPSBhcnJheSgKICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkcGFja2FnZS0+Z2V0RGlzdFR5cGUoKSwKICAgICAgICAgICAgICAgICd1cmwnID0+ICRwYWNrYWdlLT5nZXREaXN0VXJsKCksCiAgICAgICAgICAgICAgICAncmVmZXJlbmNlJyA9PiAkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnN0YWxsZWRSZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAkanNvblsncGF0aCddID0gcmVhbHBhdGgoJHRoaXMtPmdldENvbXBvc2VyKCktPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKS0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpKTsKICAgICAgICAgICAgaWYgKCRqc29uWydwYXRoJ10gPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkanNvblsncGF0aCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlLT5pc0FiYW5kb25lZCgpKSB7CiAgICAgICAgICAgICRqc29uWydyZXBsYWNlbWVudCddID0gJGxhdGVzdFBhY2thZ2UtPmdldFJlcGxhY2VtZW50UGFja2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRTdWdnZXN0cygpKSB7CiAgICAgICAgICAgICRqc29uWydzdWdnZXN0cyddID0gJHBhY2thZ2UtPmdldFN1Z2dlc3RzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UtPmdldFN1cHBvcnQoKSkgewogICAgICAgICAgICAkanNvblsnc3VwcG9ydCddID0gJHBhY2thZ2UtPmdldFN1cHBvcnQoKTsKICAgICAgICB9CgogICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZEF1dG9sb2FkKCRqc29uLCAkcGFja2FnZSk7CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0SW5jbHVkZVBhdGhzKCkpIHsKICAgICAgICAgICAgJGpzb25bJ2luY2x1ZGVfcGF0aCddID0gJHBhY2thZ2UtPmdldEluY2x1ZGVQYXRocygpOwogICAgICAgIH0KCiAgICAgICAgJGpzb24gPSAkdGhpcy0+YXBwZW5kTGlua3MoJGpzb24sICRwYWNrYWdlKTsKCiAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKEpzb25GaWxlOjplbmNvZGUoJGpzb24pKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFwcGVuZFZlcnNpb25zKCRqc29uLCBhcnJheSAkdmVyc2lvbnMpCiAgICB7CiAgICAgICAgdWFzb3J0KCR2ZXJzaW9ucywgJ3ZlcnNpb25fY29tcGFyZScpOwogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5X2tleXMoYXJyYXlfcmV2ZXJzZSgkdmVyc2lvbnMpKTsKICAgICAgICAkanNvblsndmVyc2lvbnMnXSA9ICR2ZXJzaW9uczsKCiAgICAgICAgcmV0dXJuICRqc29uOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kTGljZW5zZXMoJGpzb24sIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJGxpY2Vuc2VzID0gJHBhY2thZ2UtPmdldExpY2Vuc2UoKSkgewogICAgICAgICAgICAkc3BkeExpY2Vuc2VzID0gbmV3IFNwZHhMaWNlbnNlcygpOwoKICAgICAgICAgICAgJGpzb25bJ2xpY2Vuc2VzJ10gPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaWNlbnNlSWQpIHVzZSAoJHNwZHhMaWNlbnNlcykgewogICAgICAgICAgICAgICAgJGxpY2Vuc2UgPSAkc3BkeExpY2Vuc2VzLT5nZXRMaWNlbnNlQnlJZGVudGlmaWVyKCRsaWNlbnNlSWQpOyAvLyBrZXlzOiAwIGZ1bGxuYW1lLCAxIG9zaSwgMiB1cmwKCiAgICAgICAgICAgICAgICBpZiAoISRsaWNlbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRsaWNlbnNlSWQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgICAgICduYW1lJyA9PiAkbGljZW5zZVswXSwKICAgICAgICAgICAgICAgICAgICAnb3NpJyA9PiAkbGljZW5zZUlkLAogICAgICAgICAgICAgICAgICAgICd1cmwnID0+ICRsaWNlbnNlWzJdLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSwgJGxpY2Vuc2VzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkanNvbjsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFwcGVuZEF1dG9sb2FkKCRqc29uLCBDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRBdXRvbG9hZCgpKSB7CiAgICAgICAgICAgICRhdXRvbG9hZCA9IGFycmF5KCk7CgogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0QXV0b2xvYWQoKSBhcyAkdHlwZSA9PiAkYXV0b2xvYWRzKSB7CiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICdwc3ItMCcgfHwgJHR5cGUgPT09ICdwc3ItNCcpIHsKICAgICAgICAgICAgICAgICAgICAkcHNyID0gYXJyYXkoKTsKCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGF1dG9sb2FkcyBhcyAkbmFtZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRwYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCA9ICcuJzsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHBzclskbmFtZSA/OiAnKiddID0gJHBhdGg7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkYXV0b2xvYWRbJHR5cGVdID0gJHBzcjsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gJ2NsYXNzbWFwJykgewogICAgICAgICAgICAgICAgICAgICRhdXRvbG9hZFsnY2xhc3NtYXAnXSA9ICRhdXRvbG9hZHM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRqc29uWydhdXRvbG9hZCddID0gJGF1dG9sb2FkOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kTGlua3MoJGpzb24sIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoIChMaW5rOjokVFlQRVMgYXMgJGxpbmtUeXBlKSB7CiAgICAgICAgICAgICRqc29uID0gJHRoaXMtPmFwcGVuZExpbmsoJGpzb24sICRwYWNrYWdlLCAkbGlua1R5cGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kTGluaygkanNvbiwgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkbGlua1R5cGUpCiAgICB7CiAgICAgICAgJGxpbmtzID0gJHBhY2thZ2UtPnsnZ2V0JyAuIHVjZmlyc3QoJGxpbmtUeXBlKX0oKTsKCiAgICAgICAgaWYgKCRsaW5rcykgewogICAgICAgICAgICAkanNvblskbGlua1R5cGVdID0gYXJyYXkoKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJGpzb25bJGxpbmtUeXBlXVskbGluay0+Z2V0VGFyZ2V0KCldID0gJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdCBzdHlsZXMgZm9yIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRTdHlsZXMoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbG9ycyA9IGFycmF5KAogICAgICAgICAgICAnZ3JlZW4nLAogICAgICAgICAgICAneWVsbG93JywKICAgICAgICAgICAgJ2N5YW4nLAogICAgICAgICAgICAnbWFnZW50YScsCiAgICAgICAgICAgICdibHVlJywKICAgICAgICApOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29sb3JzIGFzICRjb2xvcikgewogICAgICAgICAgICAkc3R5bGUgPSBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoJGNvbG9yKTsKICAgICAgICAgICAgJG91dHB1dC0+Z2V0Rm9ybWF0dGVyKCktPnNldFN0eWxlKCRjb2xvciwgJHN0eWxlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwbGF5IHRoZSB0cmVlCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhcnJheVRyZWUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRpc3BsYXlQYWNrYWdlVHJlZShhcnJheSAkYXJyYXlUcmVlKQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGZvcmVhY2ggKCRhcnJheVRyZWUgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGlvLT53cml0ZShzcHJpbnRmKCc8aW5mbz4lczwvaW5mbz4nLCAkcGFja2FnZVsnbmFtZSddKSwgZmFsc2UpOwogICAgICAgICAgICAkaW8tPndyaXRlKCcgJyAuICRwYWNrYWdlWyd2ZXJzaW9uJ10sIGZhbHNlKTsKICAgICAgICAgICAgJGlvLT53cml0ZSgnICcgLiBzdHJ0b2soJHBhY2thZ2VbJ2Rlc2NyaXB0aW9uJ10sICJcclxuIikpOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRwYWNrYWdlWydyZXF1aXJlcyddKSkgewogICAgICAgICAgICAgICAgJHJlcXVpcmVzID0gJHBhY2thZ2VbJ3JlcXVpcmVzJ107CiAgICAgICAgICAgICAgICAkdHJlZUJhciA9ICfilJwnOwogICAgICAgICAgICAgICAgJGogPSAwOwogICAgICAgICAgICAgICAgJHRvdGFsID0gY291bnQoJHJlcXVpcmVzKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZXF1aXJlcyBhcyAkcmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlTmFtZSA9ICRyZXF1aXJlWyduYW1lJ107CiAgICAgICAgICAgICAgICAgICAgJGorKzsKICAgICAgICAgICAgICAgICAgICBpZiAoJGogPT09ICR0b3RhbCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdHJlZUJhciA9ICfilJQnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbGV2ZWwgPSAxOwogICAgICAgICAgICAgICAgICAgICRjb2xvciA9ICR0aGlzLT5jb2xvcnNbJGxldmVsXTsKICAgICAgICAgICAgICAgICAgICAkaW5mbyA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICclc+KUgOKUgDwlcz4lczwvJXM+ICVzJywKICAgICAgICAgICAgICAgICAgICAgICAgJHRyZWVCYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICRjb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcXVpcmVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAkY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyd2ZXJzaW9uJ10KICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRyZWVMaW5lKCRpbmZvKTsKCiAgICAgICAgICAgICAgICAgICAgJHRyZWVCYXIgPSBzdHJfcmVwbGFjZSgn4pSUJywgJyAnLCAkdHJlZUJhcik7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2VzSW5UcmVlID0gYXJyYXkoJHBhY2thZ2VbJ25hbWUnXSwgJHJlcXVpcmVOYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlUcmVlKCRyZXF1aXJlLCAkcGFja2FnZXNJblRyZWUsICR0cmVlQmFyLCAkbGV2ZWwgKyAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdlbmVyYXRlIHRoZSBwYWNrYWdlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgJHBhY2thZ2UKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbwogICAgICogQHBhcmFtICBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZW1vdGVSZXBvcwogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2VuZXJhdGVQYWNrYWdlVHJlZSgKICAgICAgICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLAogICAgICAgIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8sCiAgICAgICAgUmVwb3NpdG9yeUludGVyZmFjZSAkcmVtb3RlUmVwb3MKICAgICkgewogICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlLT5nZXRSZXF1aXJlcygpOwogICAgICAgIGtzb3J0KCRyZXF1aXJlcyk7CiAgICAgICAgJGNoaWxkcmVuID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmVOYW1lID0+ICRyZXF1aXJlKSB7CiAgICAgICAgICAgICRwYWNrYWdlc0luVHJlZSA9IGFycmF5KCRwYWNrYWdlLT5nZXROYW1lKCksICRyZXF1aXJlTmFtZSk7CgogICAgICAgICAgICAkdHJlZUNoaWxkRGVzYyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ25hbWUnID0+ICRyZXF1aXJlTmFtZSwKICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcmVxdWlyZS0+Z2V0UHJldHR5Q29uc3RyYWludCgpLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJGRlZXBDaGlsZHJlbiA9ICR0aGlzLT5hZGRUcmVlKCRyZXF1aXJlTmFtZSwgJHJlcXVpcmUsICRpbnN0YWxsZWRSZXBvLCAkcmVtb3RlUmVwb3MsICRwYWNrYWdlc0luVHJlZSk7CgogICAgICAgICAgICBpZiAoJGRlZXBDaGlsZHJlbikgewogICAgICAgICAgICAgICAgJHRyZWVDaGlsZERlc2NbJ3JlcXVpcmVzJ10gPSAkZGVlcENoaWxkcmVuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2hpbGRyZW5bXSA9ICR0cmVlQ2hpbGREZXNjOwogICAgICAgIH0KICAgICAgICAkdHJlZSA9IGFycmF5KAogICAgICAgICAgICAnbmFtZScgPT4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwKICAgICAgICAgICAgJ3ZlcnNpb24nID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksCiAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gJHBhY2thZ2UtPmdldERlc2NyaXB0aW9uKCksCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRjaGlsZHJlbikgewogICAgICAgICAgICAkdHJlZVsncmVxdWlyZXMnXSA9ICRjaGlsZHJlbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdHJlZTsKICAgIH0KCiAgICAvKioKICAgICAqIERpc3BsYXkgYSBwYWNrYWdlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRwYWNrYWdlc0luVHJlZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkcHJldmlvdXNUcmVlQmFyCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICRsZXZlbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGlzcGxheVRyZWUoCiAgICAgICAgJHBhY2thZ2UsCiAgICAgICAgYXJyYXkgJHBhY2thZ2VzSW5UcmVlLAogICAgICAgICRwcmV2aW91c1RyZWVCYXIgPSAn4pScJywKICAgICAgICAkbGV2ZWwgPSAxCiAgICApIHsKICAgICAgICAkcHJldmlvdXNUcmVlQmFyID0gc3RyX3JlcGxhY2UoJ+KUnCcsICfilIInLCAkcHJldmlvdXNUcmVlQmFyKTsKICAgICAgICBpZiAoaXNfYXJyYXkoJHBhY2thZ2UpICYmIGlzc2V0KCRwYWNrYWdlWydyZXF1aXJlcyddKSkgewogICAgICAgICAgICAkcmVxdWlyZXMgPSAkcGFja2FnZVsncmVxdWlyZXMnXTsKICAgICAgICAgICAgJHRyZWVCYXIgPSAkcHJldmlvdXNUcmVlQmFyIC4gJyAg4pScJzsKICAgICAgICAgICAgJGkgPSAwOwogICAgICAgICAgICAkdG90YWwgPSBjb3VudCgkcmVxdWlyZXMpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICRjdXJyZW50VHJlZSA9ICRwYWNrYWdlc0luVHJlZTsKICAgICAgICAgICAgICAgICRpKys7CiAgICAgICAgICAgICAgICBpZiAoJGkgPT09ICR0b3RhbCkgewogICAgICAgICAgICAgICAgICAgICR0cmVlQmFyID0gJHByZXZpb3VzVHJlZUJhciAuICcgIOKUlCc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29sb3JJZGVudCA9ICRsZXZlbCAlIGNvdW50KCR0aGlzLT5jb2xvcnMpOwogICAgICAgICAgICAgICAgJGNvbG9yID0gJHRoaXMtPmNvbG9yc1skY29sb3JJZGVudF07CgogICAgICAgICAgICAgICAgJGNpcmN1bGFyV2FybiA9IGluX2FycmF5KAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRUcmVlLAogICAgICAgICAgICAgICAgICAgIHRydWUKICAgICAgICAgICAgICAgICkgPyAnKGNpcmN1bGFyIGRlcGVuZGVuY3kgYWJvcnRlZCBoZXJlKScgOiAnJzsKICAgICAgICAgICAgICAgICRpbmZvID0gcnRyaW0oc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnJXPilIDilIA8JXM+JXM8LyVzPiAlcyAlcycsCiAgICAgICAgICAgICAgICAgICAgJHRyZWVCYXIsCiAgICAgICAgICAgICAgICAgICAgJGNvbG9yLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJGNvbG9yLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlWyd2ZXJzaW9uJ10sCiAgICAgICAgICAgICAgICAgICAgJGNpcmN1bGFyV2FybgogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUcmVlTGluZSgkaW5mbyk7CgogICAgICAgICAgICAgICAgJHRyZWVCYXIgPSBzdHJfcmVwbGFjZSgn4pSUJywgJyAnLCAkdHJlZUJhcik7CgogICAgICAgICAgICAgICAgJGN1cnJlbnRUcmVlW10gPSAkcmVxdWlyZVsnbmFtZSddOwogICAgICAgICAgICAgICAgJHRoaXMtPmRpc3BsYXlUcmVlKCRyZXF1aXJlLCAkY3VycmVudFRyZWUsICR0cmVlQmFyLCAkbGV2ZWwgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERpc3BsYXkgYSBwYWNrYWdlIHRyZWUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICRuYW1lCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2V8c3RyaW5nICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnkgICAgICRpbnN0YWxsZWRSZXBvCiAgICAgKiBAcGFyYW0gIFJlcG9zaXRvcnlJbnRlcmZhY2UgICAgICRyZW1vdGVSZXBvcwogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICAgICAkcGFja2FnZXNJblRyZWUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFRyZWUoCiAgICAgICAgJG5hbWUsCiAgICAgICAgJHBhY2thZ2UsCiAgICAgICAgSW5zdGFsbGVkUmVwb3NpdG9yeSAkaW5zdGFsbGVkUmVwbywKICAgICAgICBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZW1vdGVSZXBvcywKICAgICAgICBhcnJheSAkcGFja2FnZXNJblRyZWUKICAgICkgewogICAgICAgICRjaGlsZHJlbiA9IGFycmF5KCk7CiAgICAgICAgbGlzdCgkcGFja2FnZSkgPSAkdGhpcy0+Z2V0UGFja2FnZSgKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8sCiAgICAgICAgICAgICRyZW1vdGVSZXBvcywKICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlDb25zdHJhaW50KCkgPT09ICdzZWxmLnZlcnNpb24nID8gJHBhY2thZ2UtPmdldENvbnN0cmFpbnQoKSA6ICRwYWNrYWdlLT5nZXRQcmV0dHlDb25zdHJhaW50KCkKICAgICAgICApOwogICAgICAgIGlmIChpc19vYmplY3QoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICRyZXF1aXJlcyA9ICRwYWNrYWdlLT5nZXRSZXF1aXJlcygpOwogICAgICAgICAgICBrc29ydCgkcmVxdWlyZXMpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmVOYW1lID0+ICRyZXF1aXJlKSB7CiAgICAgICAgICAgICAgICAkY3VycmVudFRyZWUgPSAkcGFja2FnZXNJblRyZWU7CgogICAgICAgICAgICAgICAgJHRyZWVDaGlsZERlc2MgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgPT4gJHJlcXVpcmVOYW1lLAogICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcmVxdWlyZS0+Z2V0UHJldHR5Q29uc3RyYWludCgpLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBpZiAoIWluX2FycmF5KCRyZXF1aXJlTmFtZSwgJGN1cnJlbnRUcmVlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICRjdXJyZW50VHJlZVtdID0gJHJlcXVpcmVOYW1lOwogICAgICAgICAgICAgICAgICAgICRkZWVwQ2hpbGRyZW4gPSAkdGhpcy0+YWRkVHJlZSgkcmVxdWlyZU5hbWUsICRyZXF1aXJlLCAkaW5zdGFsbGVkUmVwbywgJHJlbW90ZVJlcG9zLCAkY3VycmVudFRyZWUpOwogICAgICAgICAgICAgICAgICAgIGlmICgkZGVlcENoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0cmVlQ2hpbGREZXNjWydyZXF1aXJlcyddID0gJGRlZXBDaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGNoaWxkcmVuW10gPSAkdHJlZUNoaWxkRGVzYzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjaGlsZHJlbjsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVwZGF0ZVN0YXR1c1RvVmVyc2lvblN0eWxlKCR1cGRhdGVTdGF0dXMpCiAgICB7CiAgICAgICAgLy8gJ3VwLXRvLWRhdGUnIGlzIHByaW50ZWQgZ3JlZW4KICAgICAgICAvLyAnc2VtdmVyLXNhZmUtdXBkYXRlJyBpcyBwcmludGVkIHJlZAogICAgICAgIC8vICd1cGRhdGUtcG9zc2libGUnIGlzIHByaW50ZWQgeWVsbG93CiAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKGFycmF5KCd1cC10by1kYXRlJywgJ3NlbXZlci1zYWZlLXVwZGF0ZScsICd1cGRhdGUtcG9zc2libGUnKSwgYXJyYXkoJ2luZm8nLCAnaGlnaGxpZ2h0JywgJ2NvbW1lbnQnKSwgJHVwZGF0ZVN0YXR1cyk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRVcGRhdGVTdGF0dXMoUGFja2FnZUludGVyZmFjZSAkbGF0ZXN0UGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJGxhdGVzdFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgPT09ICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpKSB7CiAgICAgICAgICAgIHJldHVybiAndXAtdG8tZGF0ZSc7CiAgICAgICAgfQoKICAgICAgICAkY29uc3RyYWludCA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgaWYgKDAgIT09IHN0cnBvcygkY29uc3RyYWludCwgJ2Rldi0nKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICdeJy4kY29uc3RyYWludDsKICAgICAgICB9CiAgICAgICAgaWYgKCRsYXRlc3RQYWNrYWdlLT5nZXRWZXJzaW9uKCkgJiYgU2VtdmVyOjpzYXRpc2ZpZXMoJGxhdGVzdFBhY2thZ2UtPmdldFZlcnNpb24oKSwgJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgIC8vIGl0IG5lZWRzIGFuIGltbWVkaWF0ZSBzZW12ZXItY29tcGxpYW50IHVwZ3JhZGUKICAgICAgICAgICAgcmV0dXJuICdzZW12ZXItc2FmZS11cGRhdGUnOwogICAgICAgIH0KCiAgICAgICAgLy8gaXQgbmVlZHMgYW4gdXBncmFkZSBidXQgaGFzIHBvdGVudGlhbCBCQyBicmVha3Mgc28gaXMgbm90IHVyZ2VudAogICAgICAgIHJldHVybiAndXBkYXRlLXBvc3NpYmxlJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlVHJlZUxpbmUoJGxpbmUpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKCEkaW8tPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgJGxpbmUgPSBzdHJfcmVwbGFjZShhcnJheSgn4pSUJywgJ+KUnCcsICfilIDilIAnLCAn4pSCJyksIGFycmF5KCdgLScsICd8LScsICctJywgJ3wnKSwgJGxpbmUpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZSgkbGluZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIHBhY2thZ2UsIHRoaXMgZmluZHMgdGhlIGxhdGVzdCBwYWNrYWdlIG1hdGNoaW5nIGl0CiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgICAkcGFja2FnZQogICAgICogQHBhcmFtIENvbXBvc2VyICAgICAgICAgICAkY29tcG9zZXIKICAgICAqIEBwYXJhbSBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAkbWlub3JPbmx5CiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlfGZhbHNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZExhdGVzdFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgQ29tcG9zZXIgJGNvbXBvc2VyLCBQbGF0Zm9ybVJlcG9zaXRvcnkgJHBsYXRmb3JtUmVwbywgJG1pbm9yT25seSA9IGZhbHNlKQogICAgewogICAgICAgIC8vIGZpbmQgdGhlIGxhdGVzdCB2ZXJzaW9uIGFsbG93ZWQgaW4gdGhpcyByZXBvIHNldAogICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKICAgICAgICAkdmVyc2lvblNlbGVjdG9yID0gbmV3IFZlcnNpb25TZWxlY3RvcigkdGhpcy0+Z2V0UmVwb3NpdG9yeVNldCgkY29tcG9zZXIpLCAkcGxhdGZvcm1SZXBvKTsKICAgICAgICAkc3RhYmlsaXR5ID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICAkZmxhZ3MgPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKTsKICAgICAgICBpZiAoaXNzZXQoJGZsYWdzWyRuYW1lXSkpIHsKICAgICAgICAgICAgJHN0YWJpbGl0eSA9IGFycmF5X3NlYXJjaCgkZmxhZ3NbJG5hbWVdLCBCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgICRiZXN0U3RhYmlsaXR5ID0gJHN0YWJpbGl0eTsKICAgICAgICBpZiAoJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldFByZWZlclN0YWJsZSgpKSB7CiAgICAgICAgICAgICRiZXN0U3RhYmlsaXR5ID0gJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpOwogICAgICAgIH0KCiAgICAgICAgJHRhcmdldFZlcnNpb24gPSBudWxsOwogICAgICAgIGlmICgwID09PSBzdHJwb3MoJHBhY2thZ2UtPmdldFZlcnNpb24oKSwgJ2Rldi0nKSkgewogICAgICAgICAgICAkdGFyZ2V0VmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRhcmdldFZlcnNpb24gPT09IG51bGwgJiYgJG1pbm9yT25seSkgewogICAgICAgICAgICAkdGFyZ2V0VmVyc2lvbiA9ICdeJyAuICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CiAgICAgICAgfQoKICAgICAgICAkY2FuZGlkYXRlID0gJHZlcnNpb25TZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoJG5hbWUsICR0YXJnZXRWZXJzaW9uLCAkYmVzdFN0YWJpbGl0eSk7CiAgICAgICAgd2hpbGUgKCRjYW5kaWRhdGUgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgJGNhbmRpZGF0ZSA9ICRjYW5kaWRhdGUtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2FuZGlkYXRlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UmVwb3NpdG9yeVNldChDb21wb3NlciAkY29tcG9zZXIpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+cmVwb3NpdG9yeVNldCkgewogICAgICAgICAgICAkdGhpcy0+cmVwb3NpdG9yeVNldCA9IG5ldyBSZXBvc2l0b3J5U2V0KCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCksICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRTdGFiaWxpdHlGbGFncygpKTsKICAgICAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkobmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRSZXBvc2l0b3JpZXMoKSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3J5U2V0OwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBwYWNrYWdlIHJlcXVpcmVzIGFuZCBjaGlsZCByZXF1aXJlcwogICAgICoKICAgICAqIEBwYXJhbSAgUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbwogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICRwYWNrYWdlCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgICAgICAgJGJ1Y2tldAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbHRlclJlcXVpcmVkUGFja2FnZXMoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGJ1Y2tldCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHJlcXVpcmVzID0gJHBhY2thZ2UtPmdldFJlcXVpcmVzKCk7CgogICAgICAgIGZvcmVhY2ggKCRyZXBvLT5nZXRQYWNrYWdlcygpIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZS0+Z2V0TmFtZXMoKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXF1aXJlc1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkY2FuZGlkYXRlLCAkYnVja2V0LCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYnVja2V0W10gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgICAgICAgICAkYnVja2V0ID0gJHRoaXMtPmZpbHRlclJlcXVpcmVkUGFja2FnZXMoJHJlcG8sICRjYW5kaWRhdGUsICRidWNrZXQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRidWNrZXQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxBcnJheUlucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBPdXRkYXRlZENvbW1hbmQgZXh0ZW5kcyBTaG93Q29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ291dGRhdGVkJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3MgYSBsaXN0IG9mIGluc3RhbGxlZCBwYWNrYWdlcyB0aGF0IGhhdmUgdXBkYXRlcyBhdmFpbGFibGUsIGluY2x1ZGluZyB0aGVpciBsYXRlc3QgdmVyc2lvbi4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnUGFja2FnZSB0byBpbnNwZWN0LiBPciBhIG5hbWUgaW5jbHVkaW5nIGEgd2lsZGNhcmQgKCopIHRvIGZpbHRlciBsaXN0cyBvZiBwYWNrYWdlcyBpbnN0ZWFkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvdXRkYXRlZCcsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IG9ubHkgcGFja2FnZXMgdGhhdCBhcmUgb3V0ZGF0ZWQgKHRoaXMgaXMgdGhlIGRlZmF1bHQsIGJ1dCBwcmVzZW50IGhlcmUgZm9yIGNvbXBhdCB3aXRoIGBzaG93YCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhbGwnLCAnYScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvdyBhbGwgaW5zdGFsbGVkIHBhY2thZ2VzIHdpdGggdGhlaXIgbGF0ZXN0IHZlcnNpb25zJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2xvY2tlZCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvd3MgdXBkYXRlcyBmb3IgcGFja2FnZXMgZnJvbSB0aGUgbG9jayBmaWxlLCByZWdhcmRsZXNzIG9mIHdoYXQgaXMgY3VycmVudGx5IGluIHZlbmRvciBkaXInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGlyZWN0JywgJ0QnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3dzIG9ubHkgcGFja2FnZXMgdGhhdCBhcmUgZGlyZWN0bHkgcmVxdWlyZWQgYnkgdGhlIHJvb3QgcGFja2FnZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzdHJpY3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JldHVybiBhIG5vbi16ZXJvIGV4aXQgY29kZSB3aGVuIHRoZXJlIGFyZSBvdXRkYXRlZCBwYWNrYWdlcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdtaW5vci1vbmx5JywgJ20nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgb25seSBwYWNrYWdlcyB0aGF0IGhhdmUgbWlub3IgU2VtVmVyLWNvbXBhdGlibGUgdXBkYXRlcy4gVXNlIHdpdGggdGhlIC0tb3V0ZGF0ZWQgb3B0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmb3JtYXQnLCAnZicsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ0Zvcm1hdCBvZiB0aGUgb3V0cHV0OiB0ZXh0IG9yIGpzb24nLCAndGV4dCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQgfCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVksICdJZ25vcmUgc3BlY2lmaWVkIHBhY2thZ2UocykuIFVzZSBpdCB3aXRoIHRoZSAtLW91dGRhdGVkIG9wdGlvbiBpZiB5b3UgZG9uXCd0IHdhbnQgdG8gYmUgaW5mb3JtZWQgYWJvdXQgbmV3IHZlcnNpb25zIG9mIHNvbWUgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWRldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRGlzYWJsZXMgc2VhcmNoIGluIHJlcXVpcmUtZGV2IHBhY2thZ2VzLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIG91dGRhdGVkIGNvbW1hbmQgaXMganVzdCBhIHByb3h5IGZvciBgY29tcG9zZXIgc2hvdyAtbGAKClRoZSBjb2xvciBjb2RpbmcgKG9yIHNpZ25hZ2UgaWYgeW91IGhhdmUgQU5TSSBjb2xvcnMgZGlzYWJsZWQpIGZvciBkZXBlbmRlbmN5IHZlcnNpb25zIGlzIGFzIHN1Y2g6CgotIDxpbmZvPmdyZWVuPC9pbmZvPiAoPSk6IERlcGVuZGVuY3kgaXMgaW4gdGhlIGxhdGVzdCB2ZXJzaW9uIGFuZCBpcyB1cCB0byBkYXRlLgotIDxjb21tZW50PnllbGxvdzwvY29tbWVudD4gKH4pOiBEZXBlbmRlbmN5IGhhcyBhIG5ldyB2ZXJzaW9uIGF2YWlsYWJsZSB0aGF0IGluY2x1ZGVzIGJhY2t3YXJkcwogIGNvbXBhdGliaWxpdHkgYnJlYWtzIGFjY29yZGluZyB0byBzZW12ZXIsIHNvIHVwZ3JhZGUgd2hlbiB5b3UgY2FuIGJ1dCBpdAogIG1heSBpbnZvbHZlIHdvcmsuCi0gPGhpZ2hsaWdodD5yZWQ8L2hpZ2hsaWdodD4gKCEpOiBEZXBlbmRlbmN5IGhhcyBhIG5ldyB2ZXJzaW9uIHRoYXQgaXMgc2VtdmVyLWNvbXBhdGlibGUgYW5kIHlvdSBzaG91bGQgdXBncmFkZSBpdC4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI291dGRhdGVkCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGFyZ3MgPSBhcnJheSgKICAgICAgICAgICAgJ2NvbW1hbmQnID0+ICdzaG93JywKICAgICAgICAgICAgJy0tbGF0ZXN0JyA9PiB0cnVlLAogICAgICAgICk7CiAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignYWxsJykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tb3V0ZGF0ZWQnXSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGlyZWN0JykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tZGlyZWN0J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpKSB7CiAgICAgICAgICAgICRhcmdzWydwYWNrYWdlJ10gPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlJyk7CiAgICAgICAgfQogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc3RyaWN0JykpIHsKICAgICAgICAgICAgJGFyZ3NbJy0tc3RyaWN0J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ21pbm9yLW9ubHknKSkgewogICAgICAgICAgICAkYXJnc1snLS1taW5vci1vbmx5J10gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xvY2tlZCcpKSB7CiAgICAgICAgICAgICRhcmdzWyctLWxvY2tlZCddID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkgewogICAgICAgICAgICAkYXJnc1snLS1uby1kZXYnXSA9IHRydWU7CiAgICAgICAgfQogICAgICAgICRhcmdzWyctLWZvcm1hdCddID0gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpOwogICAgICAgICRhcmdzWyctLWlnbm9yZSddID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZScpOwoKICAgICAgICAkaW5wdXQgPSBuZXcgQXJyYXlJbnB1dCgkYXJncyk7CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+cnVuKCRpbnB1dCwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Byb3h5Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxQYWNrYWdlXENvbXBsZXRlUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE1hdGNoQWxsQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBOaWNvbGFzIEdyZWthcyA8cEB0Y2h3b3JrLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgRnVuZENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcy0+c2V0TmFtZSgnZnVuZCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0Rpc2NvdmVyIGhvdyB0byBoZWxwIGZ1bmQgdGhlIG1haW50ZW5hbmNlIG9mIHlvdXIgZGVwZW5kZW5jaWVzLicpCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRyZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkcmVtb3RlUmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeSgkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpKTsKICAgICAgICAkZnVuZGluZ3MgPSBhcnJheSgpOwoKICAgICAgICAkcGFja2FnZXNUb0xvYWQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRyZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhY2thZ2VzVG9Mb2FkWyRwYWNrYWdlLT5nZXROYW1lKCldID0gbmV3IE1hdGNoQWxsQ29uc3RyYWludCgpOwogICAgICAgIH0KCiAgICAgICAgLy8gbG9hZCBhbGwgcGFja2FnZXMgZGV2IHZlcnNpb25zIGluIHBhcmFsbGVsCiAgICAgICAgJHJlc3VsdCA9ICRyZW1vdGVSZXBvcy0+bG9hZFBhY2thZ2VzKCRwYWNrYWdlc1RvTG9hZCwgYXJyYXkoJ2RldicgPT4gQmFzZVBhY2thZ2U6OlNUQUJJTElUWV9ERVYpLCBhcnJheSgpKTsKCiAgICAgICAgLy8gY29sbGVjdCBmdW5kaW5nIGRhdGEgZnJvbSBkZWZhdWx0IGJyYW5jaGVzCiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdFsncGFja2FnZXMnXSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAhJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UKICAgICAgICAgICAgICAgICYmICRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlCiAgICAgICAgICAgICAgICAmJiAkcGFja2FnZS0+aXNEZWZhdWx0QnJhbmNoKCkKICAgICAgICAgICAgICAgICYmICRwYWNrYWdlLT5nZXRGdW5kaW5nKCkKICAgICAgICAgICAgICAgICYmIGlzc2V0KCRwYWNrYWdlc1RvTG9hZFskcGFja2FnZS0+Z2V0TmFtZSgpXSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkZnVuZGluZ3MgPSAkdGhpcy0+aW5zZXJ0RnVuZGluZ0RhdGEoJGZ1bmRpbmdzLCAkcGFja2FnZSk7CiAgICAgICAgICAgICAgICB1bnNldCgkcGFja2FnZXNUb0xvYWRbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBjb2xsZWN0IGZ1bmRpbmcgZnJvbSBpbnN0YWxsZWQgcGFja2FnZXMgaWYgbm9uZSB3YXMgZm91bmQgaW4gdGhlIGRlZmF1bHQgYnJhbmNoIGFib3ZlCiAgICAgICAgZm9yZWFjaCAoJHJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlIHx8ICFpc3NldCgkcGFja2FnZXNUb0xvYWRbJHBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmICRwYWNrYWdlLT5nZXRGdW5kaW5nKCkpIHsKICAgICAgICAgICAgICAgICRmdW5kaW5ncyA9ICR0aGlzLT5pbnNlcnRGdW5kaW5nRGF0YSgkZnVuZGluZ3MsICRwYWNrYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAga3NvcnQoJGZ1bmRpbmdzKTsKCiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkZnVuZGluZ3MpIHsKICAgICAgICAgICAgJHByZXYgPSBudWxsOwoKICAgICAgICAgICAgJGlvLT53cml0ZSgnVGhlIGZvbGxvd2luZyBwYWNrYWdlcyB3ZXJlIGZvdW5kIGluIHlvdXIgZGVwZW5kZW5jaWVzIHdoaWNoIHB1Ymxpc2ggZnVuZGluZyBpbmZvcm1hdGlvbjonKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRmdW5kaW5ncyBhcyAkdmVuZG9yID0+ICRsaW5rcykgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnJyk7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlKHNwcmludGYoIjxjb21tZW50PiVzPC9jb21tZW50PiIsICR2ZW5kb3IpKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5rcyBhcyAkdXJsID0+ICRwYWNrYWdlcykgewogICAgICAgICAgICAgICAgICAgICRsaW5lID0gc3ByaW50ZignICA8aW5mbz4lczwvaW5mbz4nLCBpbXBsb2RlKCcsICcsICRwYWNrYWdlcykpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoJHByZXYgIT09ICRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJGxpbmUpOwogICAgICAgICAgICAgICAgICAgICAgICAkcHJldiA9ICRsaW5lOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZShzcHJpbnRmKCcgICAgJXMnLCAkdXJsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpby0+d3JpdGUoIiIpOwogICAgICAgICAgICAkaW8tPndyaXRlKCJQbGVhc2UgY29uc2lkZXIgZm9sbG93aW5nIHRoZXNlIGxpbmtzIGFuZCBzcG9uc29yaW5nIHRoZSB3b3JrIG9mIHBhY2thZ2UgYXV0aG9ycyEiKTsKICAgICAgICAgICAgJGlvLT53cml0ZSgiVGhhbmsgeW91ISIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoIk5vIGZ1bmRpbmcgbGlua3Mgd2VyZSBmb3VuZCBpbiB5b3VyIHBhY2thZ2UgZGVwZW5kZW5jaWVzLiBUaGlzIGRvZXNuJ3QgbWVhbiB0aGV5IGRvbid0IG5lZWQgeW91ciBzdXBwb3J0ISIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbnNlcnRGdW5kaW5nRGF0YShhcnJheSAkZnVuZGluZ3MsIENvbXBsZXRlUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0RnVuZGluZygpIGFzICRmdW5kaW5nT3B0aW9uKSB7CiAgICAgICAgICAgIGxpc3QoJHZlbmRvciwgJHBhY2thZ2VOYW1lKSA9IGV4cGxvZGUoJy8nLCAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpKTsKICAgICAgICAgICAgLy8gaWdub3JlIG1hbGZvcm1lZCBmdW5kaW5nIGVudHJpZXMKICAgICAgICAgICAgaWYgKGVtcHR5KCRmdW5kaW5nT3B0aW9uWyd1cmwnXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR1cmwgPSAkZnVuZGluZ09wdGlvblsndXJsJ107CiAgICAgICAgICAgIGlmICghZW1wdHkoJGZ1bmRpbmdPcHRpb25bJ3R5cGUnXSkgJiYgJGZ1bmRpbmdPcHRpb25bJ3R5cGUnXSA9PT0gJ2dpdGh1YicgJiYgcHJlZ19tYXRjaCgne15odHRwczovL2dpdGh1Yi5jb20vKFteL10rKSR9JywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgJHVybCA9ICdodHRwczovL2dpdGh1Yi5jb20vc3BvbnNvcnMvJy4kbWF0Y2hbMV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGZ1bmRpbmdzWyR2ZW5kb3JdWyR1cmxdW10gPSAkcGFja2FnZU5hbWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZ1bmRpbmdzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJvb3RQYWNrYWdlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgpjbGFzcyBTdWdnZXN0c0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3N1Z2dlc3RzJykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3MgcGFja2FnZSBzdWdnZXN0aW9ucy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2J5LXBhY2thZ2UnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0dyb3VwcyBvdXRwdXQgYnkgc3VnZ2VzdGluZyBwYWNrYWdlIChkZWZhdWx0KScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdieS1zdWdnZXN0aW9uJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdHcm91cHMgb3V0cHV0IGJ5IHN1Z2dlc3RlZCBwYWNrYWdlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FsbCcsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IHN1Z2dlc3Rpb25zIGZyb20gYWxsIGRlcGVuZGVuY2llcywgaW5jbHVkaW5nIHRyYW5zaXRpdmUgb25lcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93IG9ubHkgbGlzdCBvZiBzdWdnZXN0ZWQgcGFja2FnZSBuYW1lcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0V4Y2x1ZGUgc3VnZ2VzdGlvbnMgZnJvbSByZXF1aXJlLWRldiBwYWNrYWdlcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2VzJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2VzIHRoYXQgeW91IHdhbnQgdG8gbGlzdCBzdWdnZXN0aW9ucyBmcm9tLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKClRoZSA8aW5mbz4lY29tbWFuZC5uYW1lJTwvaW5mbz4gY29tbWFuZCBzaG93cyBhIHNvcnRlZCBsaXN0IG9mIHN1Z2dlc3RlZCBwYWNrYWdlcy4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3N1Z2dlc3RzCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwoKICAgICAgICAkaW5zdGFsbGVkUmVwb3MgPSBhcnJheSgKICAgICAgICAgICAgbmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeShjbG9uZSAkY29tcG9zZXItPmdldFBhY2thZ2UoKSksCiAgICAgICAgKTsKCiAgICAgICAgJGxvY2tlciA9ICRjb21wb3Nlci0+Z2V0TG9ja2VyKCk7CiAgICAgICAgaWYgKCRsb2NrZXItPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG9zW10gPSBuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KGFycmF5KCksICRsb2NrZXItPmdldFBsYXRmb3JtT3ZlcnJpZGVzKCkpOwogICAgICAgICAgICAkaW5zdGFsbGVkUmVwb3NbXSA9ICRsb2NrZXItPmdldExvY2tlZFJlcG9zaXRvcnkoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG9zW10gPSBuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KGFycmF5KCksICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpKTsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG9zW10gPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldExvY2FsUmVwb3NpdG9yeSgpOwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeSgkaW5zdGFsbGVkUmVwb3MpOwogICAgICAgICRyZXBvcnRlciA9IG5ldyBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKCR0aGlzLT5nZXRJTygpKTsKCiAgICAgICAgJGZpbHRlciA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyk7CiAgICAgICAgJHBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCk7CiAgICAgICAgJHBhY2thZ2VzW10gPSAkY29tcG9zZXItPmdldFBhY2thZ2UoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkZmlsdGVyKSAmJiAhaW5fYXJyYXkoJHBhY2thZ2UtPmdldE5hbWUoKSwgJGZpbHRlcikpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVwb3J0ZXItPmFkZFN1Z2dlc3Rpb25zRnJvbVBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gRGV0ZXJtaW5lIG91dHB1dCBtb2RlLCBkZWZhdWx0IGlzIGJ5LXBhY2thZ2UKICAgICAgICAkbW9kZSA9IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI6Ok1PREVfQllfUEFDS0FHRTsKCiAgICAgICAgLy8gaWYgYnktc3VnZ2VzdGlvbiBpcyBnaXZlbiB3ZSBvdmVycmlkZSB0aGUgZGVmYXVsdAogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignYnktc3VnZ2VzdGlvbicpKSB7CiAgICAgICAgICAgICRtb2RlID0gU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcjo6TU9ERV9CWV9TVUdHRVNUSU9OOwogICAgICAgIH0KICAgICAgICAvLyB1bmxlc3MgYnktcGFja2FnZSBpcyBhbHNvIHByZXNlbnQgdGhlbiB3ZSBlbmFibGUgYm90aAogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignYnktcGFja2FnZScpKSB7CiAgICAgICAgICAgICRtb2RlIHw9IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI6Ok1PREVfQllfUEFDS0FHRTsKICAgICAgICB9CiAgICAgICAgLy8gbGlzdCBpcyBleGNsdXNpdmUgYW5kIG92ZXJyaWRlcyBldmVyeXRoaW5nIGVsc2UKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xpc3QnKSkgewogICAgICAgICAgICAkbW9kZSA9IFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI6Ok1PREVfTElTVDsKICAgICAgICB9CgogICAgICAgICRyZXBvcnRlci0+b3V0cHV0KCRtb2RlLCAkaW5zdGFsbGVkUmVwbywgZW1wdHkoJGZpbHRlcikgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCdhbGwnKSA/ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpIDogbnVsbCk7CgogICAgICAgIHJldHVybiAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIE5pZWxzIEtldXJlbnRqZXMgPG5pZWxzLmtldXJlbnRqZXNAb21pbmVzLmNvbT4KICovCmNsYXNzIERlcGVuZHNDb21tYW5kIGV4dGVuZHMgQmFzZURlcGVuZGVuY3lDb21tYW5kCnsKICAgIC8qKgogICAgICogQ29uZmlndXJlIGNvbW1hbmQgbWV0YWRhdGEuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgIHBhcmVudDo6Y29uZmlndXJlKCk7CgogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnZGVwZW5kcycpCiAgICAgICAgICAgIC0+c2V0QWxpYXNlcyhhcnJheSgnd2h5JykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1Nob3dzIHdoaWNoIHBhY2thZ2VzIGNhdXNlIHRoZSBnaXZlbiBwYWNrYWdlIHRvIGJlIGluc3RhbGxlZC4nKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKRGlzcGxheXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgd2hlcmUgYSBwYWNrYWdlIGlzIHJlZmVyZW5jZWQuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBkZXBlbmRzIGNvbXBvc2VyL2NvbXBvc2VyPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjZGVwZW5kcy13aHktCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtICBJbnB1dEludGVyZmFjZSAgJGlucHV0CiAgICAgKiBAcGFyYW0gIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIHJldHVybiBwYXJlbnQ6OmRvRXhlY3V0ZSgkaW5wdXQsICRvdXRwdXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXENoYW5nZVJlcG9ydEludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRHZjc0Rvd25sb2FkZXJJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFZjc0NhcGFibGVEb3dubG9hZGVySW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxEdW1wZXJcQXJyYXlEdW1wZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvbkd1ZXNzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFBsdWdpblxDb21tYW5kRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIEBhdXRob3IgVGlhZ28gUmliZWlybyA8dGlhZ28ucmliZWlyb0BzZWVnbm8uY29tPgogKiBAYXV0aG9yIFJ1aSBNYXJpbmhvIDxydWkubWFyaW5ob0BzZWVnbm8uY29tPgogKi8KY2xhc3MgU3RhdHVzQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIGNvbnN0IEVYSVRfQ09ERV9FUlJPUlMgPSAxOwogICAgY29uc3QgRVhJVF9DT0RFX1VOUFVTSEVEX0NIQU5HRVMgPSAyOwogICAgY29uc3QgRVhJVF9DT0RFX1ZFUlNJT05fQ0hBTkdFUyA9IDQ7CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIFxTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdzdGF0dXMnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdTaG93cyBhIGxpc3Qgb2YgbG9jYWxseSBtb2RpZmllZCBwYWNrYWdlcy4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ZlcmJvc2UnLCAndnx2dnx2dnYnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Nob3cgbW9kaWZpZWQgZmlsZXMgZm9yIGVhY2ggZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgY2hhbmdlcy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSBzdGF0dXMgY29tbWFuZCBkaXNwbGF5cyBhIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIHRoYXQgaGF2ZQpiZWVuIG1vZGlmaWVkIGxvY2FsbHkuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNzdGF0dXMKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIElucHV0SW50ZXJmYWNlICAkaW5wdXQKICAgICAqIEBwYXJhbSAgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3N0YXR1cycsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgLy8gRGlzcGF0Y2ggcHJlLXN0YXR1cy1jb21tYW5kCiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2hTY3JpcHQoU2NyaXB0RXZlbnRzOjpQUkVfU1RBVFVTX0NNRCwgdHJ1ZSk7CgogICAgICAgICRleGl0Q29kZSA9ICR0aGlzLT5kb0V4ZWN1dGUoJGlucHV0KTsKCiAgICAgICAgLy8gRGlzcGF0Y2ggcG9zdC1zdGF0dXMtY29tbWFuZAogICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KFNjcmlwdEV2ZW50czo6UE9TVF9TVEFUVVNfQ01ELCB0cnVlKTsKCiAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgSW5wdXRJbnRlcmZhY2UgJGlucHV0CiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRvRXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQpCiAgICB7CiAgICAgICAgLy8gaW5pdCByZXBvcwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwoKICAgICAgICAkaW5zdGFsbGVkUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgogICAgICAgICRkbSA9ICRjb21wb3Nlci0+Z2V0RG93bmxvYWRNYW5hZ2VyKCk7CiAgICAgICAgJGltID0gJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCk7CgogICAgICAgICRlcnJvcnMgPSBhcnJheSgpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICR1bnB1c2hlZENoYW5nZXMgPSBhcnJheSgpOwogICAgICAgICR2Y3NWZXJzaW9uQ2hhbmdlcyA9IGFycmF5KCk7CgogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZ3Vlc3NlciA9IG5ldyBWZXJzaW9uR3Vlc3NlcigkY29tcG9zZXItPmdldENvbmZpZygpLCBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyksICRwYXJzZXIpOwogICAgICAgICRkdW1wZXIgPSBuZXcgQXJyYXlEdW1wZXI7CgogICAgICAgIC8vIGxpc3QgcGFja2FnZXMKICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUmVwby0+Z2V0Q2Fub25pY2FsUGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkZG93bmxvYWRlciA9ICRkbS0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICAkdGFyZ2V0RGlyID0gJGltLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgICAgICBpZiAoJGRvd25sb2FkZXIgaW5zdGFuY2VvZiBDaGFuZ2VSZXBvcnRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgIGlmIChpc19saW5rKCR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yc1skdGFyZ2V0RGlyXSA9ICR0YXJnZXREaXIgLiAnIGlzIGEgc3ltYm9saWMgbGluay4nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkY2hhbmdlcyA9ICRkb3dubG9hZGVyLT5nZXRMb2NhbENoYW5nZXMoJHBhY2thZ2UsICR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yc1skdGFyZ2V0RGlyXSA9ICRjaGFuZ2VzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGRvd25sb2FkZXIgaW5zdGFuY2VvZiBWY3NDYXBhYmxlRG93bmxvYWRlckludGVyZmFjZSkgewogICAgICAgICAgICAgICAgaWYgKCRkb3dubG9hZGVyLT5nZXRWY3NSZWZlcmVuY2UoJHBhY2thZ2UsICR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkcGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc291cmNlJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmV2aW91c1JlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkaXN0JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmV2aW91c1JlZiA9ICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmV2aW91c1JlZiA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkY3VycmVudFZlcnNpb24gPSAkZ3Vlc3Nlci0+Z3Vlc3NWZXJzaW9uKCRkdW1wZXItPmR1bXAoJHBhY2thZ2UpLCAkdGFyZ2V0RGlyKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRwcmV2aW91c1JlZiAmJiAkY3VycmVudFZlcnNpb24gJiYgJGN1cnJlbnRWZXJzaW9uWydjb21taXQnXSAhPT0gJHByZXZpb3VzUmVmKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2Y3NWZXJzaW9uQ2hhbmdlc1skdGFyZ2V0RGlyXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ByZXZpb3VzJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmVyc2lvbicgPT4gJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncmVmJyA9PiAkcHJldmlvdXNSZWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2N1cnJlbnQnID0+IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkY3VycmVudFZlcnNpb25bJ3ByZXR0eV92ZXJzaW9uJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3JlZicgPT4gJGN1cnJlbnRWZXJzaW9uWydjb21taXQnXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGRvd25sb2FkZXIgaW5zdGFuY2VvZiBEdmNzRG93bmxvYWRlckludGVyZmFjZSkgewogICAgICAgICAgICAgICAgaWYgKCR1bnB1c2hlZCA9ICRkb3dubG9hZGVyLT5nZXRVbnB1c2hlZENoYW5nZXMoJHBhY2thZ2UsICR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgJHVucHVzaGVkQ2hhbmdlc1skdGFyZ2V0RGlyXSA9ICR1bnB1c2hlZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gb3V0cHV0IGVycm9ycy93YXJuaW5ncwogICAgICAgIGlmICghJGVycm9ycyAmJiAhJHVucHVzaGVkQ2hhbmdlcyAmJiAhJHZjc1ZlcnNpb25DaGFuZ2VzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Tm8gbG9jYWwgY2hhbmdlczwvaW5mbz4nKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRlcnJvcnMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+WW91IGhhdmUgY2hhbmdlcyBpbiB0aGUgZm9sbG93aW5nIGRlcGVuZGVuY2llczo8L2Vycm9yPicpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGVycm9ycyBhcyAkcGF0aCA9PiAkY2hhbmdlcykgewogICAgICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpIHsKICAgICAgICAgICAgICAgICAgICAkaW5kZW50ZWRDaGFuZ2VzID0gaW1wbG9kZSgiXG4iLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnICAgICcgLiBsdHJpbSgkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgfSwgZXhwbG9kZSgiXG4iLCAkY2hhbmdlcykpKTsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz4nLiRwYXRoLic8L2luZm8+OicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJGluZGVudGVkQ2hhbmdlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJHBhdGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHVucHVzaGVkQ2hhbmdlcykgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBoYXZlIHVucHVzaGVkIGNoYW5nZXMgb24gdGhlIGN1cnJlbnQgYnJhbmNoIGluIHRoZSBmb2xsb3dpbmcgZGVwZW5kZW5jaWVzOjwvd2FybmluZz4nKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCR1bnB1c2hlZENoYW5nZXMgYXMgJHBhdGggPT4gJGNoYW5nZXMpIHsKICAgICAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndmVyYm9zZScpKSB7CiAgICAgICAgICAgICAgICAgICAgJGluZGVudGVkQ2hhbmdlcyA9IGltcGxvZGUoIlxuIiwgYXJyYXlfbWFwKGZ1bmN0aW9uICgkbGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyAgICAnIC4gbHRyaW0oJGxpbmUpOwogICAgICAgICAgICAgICAgICAgIH0sIGV4cGxvZGUoIlxuIiwgJGNoYW5nZXMpKSk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnPGluZm8+Jy4kcGF0aC4nPC9pbmZvPjonKTsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRpbmRlbnRlZENoYW5nZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR2Y3NWZXJzaW9uQ2hhbmdlcykgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBoYXZlIHZlcnNpb24gdmFyaWF0aW9ucyBpbiB0aGUgZm9sbG93aW5nIGRlcGVuZGVuY2llczo8L3dhcm5pbmc+Jyk7CgogICAgICAgICAgICBmb3JlYWNoICgkdmNzVmVyc2lvbkNoYW5nZXMgYXMgJHBhdGggPT4gJGNoYW5nZXMpIHsKICAgICAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndmVyYm9zZScpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgZG9uJ3QgY2FuJ3QgZmluZCBhIHZlcnNpb24sIHVzZSB0aGUgcmVmIGluc3RlYWQuCiAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRWZXJzaW9uID0gJGNoYW5nZXNbJ2N1cnJlbnQnXVsndmVyc2lvbiddID86ICRjaGFuZ2VzWydjdXJyZW50J11bJ3JlZiddOwogICAgICAgICAgICAgICAgICAgICRwcmV2aW91c1ZlcnNpb24gPSAkY2hhbmdlc1sncHJldmlvdXMnXVsndmVyc2lvbiddID86ICRjaGFuZ2VzWydwcmV2aW91cyddWydyZWYnXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRpby0+aXNWZXJ5VmVyYm9zZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE91dHB1dCB0aGUgcmVmIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBvciBub3QgaXQncyBiZWluZyB1c2VkIGFzIHRoZSB2ZXJzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgICRjdXJyZW50VmVyc2lvbiAuPSBzcHJpbnRmKCcgKCVzKScsICRjaGFuZ2VzWydjdXJyZW50J11bJ3JlZiddKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHByZXZpb3VzVmVyc2lvbiAuPSBzcHJpbnRmKCcgKCVzKScsICRjaGFuZ2VzWydwcmV2aW91cyddWydyZWYnXSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCc8aW5mbz4nLiRwYXRoLic8L2luZm8+OicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGUoc3ByaW50ZignICAgIEZyb20gPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+IHRvIDxjb21tZW50PiVzPC9jb21tZW50PicsICRwcmV2aW91c1ZlcnNpb24sICRjdXJyZW50VmVyc2lvbikpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlKCRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCgkZXJyb3JzIHx8ICR1bnB1c2hlZENoYW5nZXMgfHwgJHZjc1ZlcnNpb25DaGFuZ2VzKSAmJiAhJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJ1VzZSAtLXZlcmJvc2UgKC12KSB0byBzZWUgYSBsaXN0IG9mIGZpbGVzJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKCRlcnJvcnMgPyBzZWxmOjpFWElUX0NPREVfRVJST1JTIDogMCkgKyAoJHVucHVzaGVkQ2hhbmdlcyA/IHNlbGY6OkVYSVRfQ09ERV9VTlBVU0hFRF9DSEFOR0VTIDogMCkgKyAoJHZjc1ZlcnNpb25DaGFuZ2VzID8gc2VsZjo6RVhJVF9DT0RFX1ZFUlNJT05fQ0hBTkdFUyA6IDApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBEdW1wQXV0b2xvYWRDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdkdW1wLWF1dG9sb2FkJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdkdW1wYXV0b2xvYWQnKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignRHVtcHMgdGhlIGF1dG9sb2FkZXIuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwcyB0aGUgZXhlY3V0aW9uIG9mIGFsbCBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbiBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvcHRpbWl6ZScsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZXMgUFNSMCBhbmQgUFNSNCBwYWNrYWdlcyB0byBiZSBsb2FkZWQgd2l0aCBjbGFzc21hcHMgdG9vLCBnb29kIGZvciBwcm9kdWN0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJywgJ2EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0F1dG9sb2FkIGNsYXNzZXMgZnJvbSB0aGUgY2xhc3NtYXAgb25seS4gSW1wbGljaXRseSBlbmFibGVzIGAtLW9wdGltaXplYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVXNlIEFQQ3UgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FwY3UtcHJlZml4JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnVXNlIGEgY3VzdG9tIHByZWZpeCBmb3IgdGhlIEFQQ3UgYXV0b2xvYWRlciBjYWNoZS4gSW1wbGljaXRseSBlbmFibGVzIC0tYXBjdScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIGF1dG9sb2FkLWRldiBydWxlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGR1bXAtYXV0b2xvYWQ8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNkdW1wLWF1dG9sb2FkLWR1bXBhdXRvbG9hZC0KRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKCiAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAnZHVtcC1hdXRvbG9hZCcsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGluc3RhbGxhdGlvbk1hbmFnZXIgPSAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKTsKICAgICAgICAkbG9jYWxSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAkcGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICRjb25maWcgPSAkY29tcG9zZXItPmdldENvbmZpZygpOwoKICAgICAgICAkb3B0aW1pemUgPSAkaW5wdXQtPmdldE9wdGlvbignb3B0aW1pemUnKSB8fCAkY29uZmlnLT5nZXQoJ29wdGltaXplLWF1dG9sb2FkZXInKTsKICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbmZpZy0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgJGFwY3VQcmVmaXggPSAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1JykgfHwgJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKTsKCiAgICAgICAgaWYgKCRhdXRob3JpdGF0aXZlKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgnPGluZm8+R2VuZXJhdGluZyBvcHRpbWl6ZWQgYXV0b2xvYWQgZmlsZXMgKGF1dGhvcml0YXRpdmUpPC9pbmZvPicpOwogICAgICAgIH0gZWxzZWlmICgkb3B0aW1pemUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKCc8aW5mbz5HZW5lcmF0aW5nIG9wdGltaXplZCBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJzxpbmZvPkdlbmVyYXRpbmcgYXV0b2xvYWQgZmlsZXM8L2luZm8+Jyk7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkZ2VuZXJhdG9yID0gJGNvbXBvc2VyLT5nZXRBdXRvbG9hZEdlbmVyYXRvcigpOwogICAgICAgICRnZW5lcmF0b3ItPnNldERldk1vZGUoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSk7CiAgICAgICAgJGdlbmVyYXRvci0+c2V0Q2xhc3NNYXBBdXRob3JpdGF0aXZlKCRhdXRob3JpdGF0aXZlKTsKICAgICAgICAkZ2VuZXJhdG9yLT5zZXRBcGN1KCRhcGN1LCAkYXBjdVByZWZpeCk7CiAgICAgICAgJGdlbmVyYXRvci0+c2V0UnVuU2NyaXB0cyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXNjcmlwdHMnKSk7CiAgICAgICAgJGdlbmVyYXRvci0+c2V0SWdub3JlUGxhdGZvcm1SZXF1aXJlbWVudHMoJGlnbm9yZVBsYXRmb3JtUmVxcyk7CiAgICAgICAgJG51bWJlck9mQ2xhc3NlcyA9ICRnZW5lcmF0b3ItPmR1bXAoJGNvbmZpZywgJGxvY2FsUmVwbywgJHBhY2thZ2UsICRpbnN0YWxsYXRpb25NYW5hZ2VyLCAnY29tcG9zZXInLCAkb3B0aW1pemUpOwoKICAgICAgICBpZiAoJGF1dGhvcml0YXRpdmUpIHsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKCc8aW5mbz5HZW5lcmF0ZWQgb3B0aW1pemVkIGF1dG9sb2FkIGZpbGVzIChhdXRob3JpdGF0aXZlKSBjb250YWluaW5nICcuICRudW1iZXJPZkNsYXNzZXMgLicgY2xhc3NlczwvaW5mbz4nKTsKICAgICAgICB9IGVsc2VpZiAoJG9wdGltaXplKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgnPGluZm8+R2VuZXJhdGVkIG9wdGltaXplZCBhdXRvbG9hZCBmaWxlcyBjb250YWluaW5nICcuICRudW1iZXJPZkNsYXNzZXMgLicgY2xhc3NlczwvaW5mbz4nKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoJzxpbmZvPkdlbmVyYXRlZCBhdXRvbG9hZCBmaWxlczwvaW5mbz4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBBYm91dENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2Fib3V0JykKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3MgdGhlIHNob3J0IGluZm9ybWF0aW9uIGFib3V0IENvbXBvc2VyLicpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVAo8aW5mbz5waHAgY29tcG9zZXIucGhhciBhYm91dDwvaW5mbz4KRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGUoCiAgICAgICAgICAgIDw8PEVPVAo8aW5mbz5Db21wb3NlciAtIERlcGVuZGVuY3kgTWFuYWdlciBmb3IgUEhQPC9pbmZvPgo8Y29tbWVudD5Db21wb3NlciBpcyBhIGRlcGVuZGVuY3kgbWFuYWdlciB0cmFja2luZyBsb2NhbCBkZXBlbmRlbmNpZXMgb2YgeW91ciBwcm9qZWN0cyBhbmQgbGlicmFyaWVzLgpTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvIGZvciBtb3JlIGluZm9ybWF0aW9uLjwvY29tbWVudD4KRU9UCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFBsYXRmb3JtUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUm9vdFBhY2thZ2VSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5OwoKY2xhc3MgQ2hlY2tQbGF0Zm9ybVJlcXNDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldE5hbWUoJ2NoZWNrLXBsYXRmb3JtLXJlcXMnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdDaGVjayB0aGF0IHBsYXRmb3JtIHJlcXVpcmVtZW50cyBhcmUgc2F0aXNmaWVkLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBjaGVja2luZyBvZiByZXF1aXJlLWRldiBwYWNrYWdlcyByZXF1aXJlbWVudHMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2xvY2snLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0NoZWNrcyByZXF1aXJlbWVudHMgb25seSBmcm9tIHRoZSBsb2NrIGZpbGUsIG5vdCBmcm9tIGluc3RhbGxlZCBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UCkNoZWNrcyB0aGF0IHlvdXIgUEhQIGFuZCBleHRlbnNpb25zIHZlcnNpb25zIG1hdGNoIHRoZSBwbGF0Zm9ybSByZXF1aXJlbWVudHMgb2YgdGhlIGluc3RhbGxlZCBwYWNrYWdlcy4KClVubGlrZSB1cGRhdGUvaW5zdGFsbCwgdGhpcyBjb21tYW5kIHdpbGwgaWdub3JlIGNvbmZpZy5wbGF0Zm9ybSBzZXR0aW5ncyBhbmQgY2hlY2sgdGhlIHJlYWwgcGxhdGZvcm0gcGFja2FnZXMgc28geW91IGNhbiBiZSBjZXJ0YWluIHlvdSBoYXZlIHRoZSByZXF1aXJlZCBwbGF0Zm9ybSBkZXBlbmRlbmNpZXMuCgo8aW5mbz5waHAgY29tcG9zZXIucGhhciBjaGVjay1wbGF0Zm9ybS1yZXFzPC9pbmZvPgoKRU9UCiAgICAgICAgICAgICk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKCiAgICAgICAgJHJlcXVpcmVzID0gYXJyYXkoKTsKICAgICAgICAkcmVtb3ZlUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbG9jaycpKSB7CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCc8aW5mbz5DaGVja2luZyAnLigkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykgPyAnbm9uLWRldiAnIDogJycpLidwbGF0Zm9ybSByZXF1aXJlbWVudHMgdXNpbmcgdGhlIGxvY2sgZmlsZTwvaW5mbz4nKTsKICAgICAgICAgICAgJGluc3RhbGxlZFJlcG8gPSAkY29tcG9zZXItPmdldExvY2tlcigpLT5nZXRMb2NrZWRSZXBvc2l0b3J5KCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgLy8gZmFsbGJhY2sgdG8gbG9ja2ZpbGUgaWYgaW5zdGFsbGVkIHJlcG8gaXMgZW1wdHkKICAgICAgICAgICAgaWYgKCEkaW5zdGFsbGVkUmVwby0+Z2V0UGFja2FnZXMoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzx3YXJuaW5nPk5vIHZlbmRvciBkaXIgcHJlc2VudCwgY2hlY2tpbmcgJy4oJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpID8gJ25vbi1kZXYgJyA6ICcnKS4ncGxhdGZvcm0gcmVxdWlyZW1lbnRzIGZyb20gdGhlIGxvY2sgZmlsZTwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWRSZXBvID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKS0+Z2V0TG9ja2VkUmVwb3NpdG9yeSghJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgICAgICAgICAkcmVtb3ZlUGFja2FnZXMgPSAkaW5zdGFsbGVkUmVwby0+Z2V0RGV2UGFja2FnZU5hbWVzKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzxpbmZvPkNoZWNraW5nICcuKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSA/ICdub24tZGV2ICcgOiAnJykuJ3BsYXRmb3JtIHJlcXVpcmVtZW50cyBmb3IgcGFja2FnZXMgaW4gdGhlIHZlbmRvciBkaXI8L2luZm8+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgJHJlcXVpcmVzICs9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXREZXZSZXF1aXJlcygpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVzIGFzICRyZXF1aXJlID0+ICRsaW5rKSB7CiAgICAgICAgICAgICRyZXF1aXJlc1skcmVxdWlyZV0gPSBhcnJheSgkbGluayk7CiAgICAgICAgfQoKICAgICAgICAkaW5zdGFsbGVkUmVwbyA9IG5ldyBJbnN0YWxsZWRSZXBvc2l0b3J5KGFycmF5KCRpbnN0YWxsZWRSZXBvLCBuZXcgUm9vdFBhY2thZ2VSZXBvc2l0b3J5KCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpKSkpOwogICAgICAgIGZvcmVhY2ggKCRpbnN0YWxsZWRSZXBvLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkcGFja2FnZS0+Z2V0TmFtZSgpLCAkcmVtb3ZlUGFja2FnZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkcmVxdWlyZSA9PiAkbGluaykgewogICAgICAgICAgICAgICAgJHJlcXVpcmVzWyRyZXF1aXJlXVtdID0gJGxpbms7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGtzb3J0KCRyZXF1aXJlcyk7CgogICAgICAgICRpbnN0YWxsZWRSZXBvLT5hZGRSZXBvc2l0b3J5KG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkoYXJyYXkoKSwgYXJyYXkoKSkpOwoKICAgICAgICAkcmVzdWx0cyA9IGFycmF5KCk7CiAgICAgICAgJGV4aXRDb2RlID0gMDsKCiAgICAgICAgLyoqCiAgICAgICAgICogQHZhciBMaW5rW10gJGxpbmtzCiAgICAgICAgICovCiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVzIGFzICRyZXF1aXJlID0+ICRsaW5rcykgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcmVxdWlyZSkpIHsKICAgICAgICAgICAgICAgICRjYW5kaWRhdGVzID0gJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJHJlcXVpcmUpOwogICAgICAgICAgICAgICAgaWYgKCRjYW5kaWRhdGVzKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcVJlc3VsdHMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjYW5kaWRhdGVzIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNhbmRpZGF0ZUNvbnN0cmFpbnQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNhbmRpZGF0ZS0+Z2V0TmFtZSgpID09PSAkcmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNhbmRpZGF0ZUNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgnPScsICRjYW5kaWRhdGUtPmdldFZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlQ29uc3RyYWludC0+c2V0UHJldHR5U3RyaW5nKCRjYW5kaWRhdGUtPmdldFByZXR0eVZlcnNpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkY2FuZGlkYXRlLT5nZXRQcm92aWRlcygpLCAkY2FuZGlkYXRlLT5nZXRSZXBsYWNlcygpKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0VGFyZ2V0KCkgPT09ICRyZXF1aXJlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGVDb25zdHJhaW50ID0gJGxpbmstPmdldENvbnN0cmFpbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBzYWZldHkgY2hlY2sgZm9yIHBocHN0YW4sIGJ1dCBpdCBzaG91bGQgbm90IGJlIHBvc3NpYmxlIHRvIGdldCBhIGNhbmRpZGF0ZSBvdXQgb2YgZmluZFBhY2thZ2VzV2l0aFJlcGxhY2Vyc0FuZFByb3ZpZGVycyB3aXRob3V0IGEgY29uc3RyYWludCBtYXRjaGluZyAkcmVxdWlyZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRjYW5kaWRhdGVDb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpbmtzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMoJGNhbmRpZGF0ZUNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlcVJlc3VsdHNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2FuZGlkYXRlLT5nZXROYW1lKCkgPT09ICRyZXF1aXJlID8gJGNhbmRpZGF0ZS0+Z2V0UHJldHR5TmFtZSgpIDogJHJlcXVpcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGVDb25zdHJhaW50LT5nZXRQcmV0dHlTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZXJyb3I+ZmFpbGVkPC9lcnJvcj4nLigkY2FuZGlkYXRlLT5nZXROYW1lKCkgPT09ICRyZXF1aXJlID8gJycgOiAnIDxjb21tZW50PnByb3ZpZGVkIGJ5ICcuJGNhbmRpZGF0ZS0+Z2V0UHJldHR5TmFtZSgpLic8L2NvbW1lbnQ+JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB0byBuZXh0IGNhbmRpZGF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGUtPmdldE5hbWUoKSA9PT0gJHJlcXVpcmUgPyAkY2FuZGlkYXRlLT5nZXRQcmV0dHlOYW1lKCkgOiAkcmVxdWlyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYW5kaWRhdGVDb25zdHJhaW50LT5nZXRQcmV0dHlTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGluZm8+c3VjY2VzczwvaW5mbz4nLigkY2FuZGlkYXRlLT5nZXROYW1lKCkgPT09ICRyZXF1aXJlID8gJycgOiAnIDxjb21tZW50PnByb3ZpZGVkIGJ5ICcuJGNhbmRpZGF0ZS0+Z2V0UHJldHR5TmFtZSgpLic8L2NvbW1lbnQ+JyksCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW5kaWRhdGUgbWF0Y2hlZCwgc2tpcCB0byBuZXh0IHJlcXVpcmVtZW50CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBzaG93IHRoZSBmaXJzdCBlcnJvciBmcm9tIGV2ZXJ5IGZhaWxlZCBjYW5kaWRhdGUKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0cyA9IGFycmF5X21lcmdlKCRyZXN1bHRzLCAkcmVxUmVzdWx0cyk7CiAgICAgICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gbWF4KCRleGl0Q29kZSwgMSk7CgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZSwKICAgICAgICAgICAgICAgICAgICAnbi9hJywKICAgICAgICAgICAgICAgICAgICAkbGlua3NbMF0sCiAgICAgICAgICAgICAgICAgICAgJzxlcnJvcj5taXNzaW5nPC9lcnJvcj4nLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSBtYXgoJGV4aXRDb2RlLCAyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnByaW50VGFibGUoJG91dHB1dCwgJHJlc3VsdHMpOwoKICAgICAgICByZXR1cm4gJGV4aXRDb2RlOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFRhYmxlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcmVzdWx0cykKICAgIHsKICAgICAgICAkcm93cyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHZhciBMaW5rfG51bGwgJGxpbmsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGxpc3QoJHBsYXRmb3JtUGFja2FnZSwgJHZlcnNpb24sICRsaW5rLCAkc3RhdHVzKSA9ICRyZXN1bHQ7CiAgICAgICAgICAgICRyb3dzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICRwbGF0Zm9ybVBhY2thZ2UsCiAgICAgICAgICAgICAgICAkdmVyc2lvbiwKICAgICAgICAgICAgICAgICRsaW5rID8gc3ByaW50ZignJXMgJXMgJXMgKCVzKScsICRsaW5rLT5nZXRTb3VyY2UoKSwgJGxpbmstPmdldERlc2NyaXB0aW9uKCksICRsaW5rLT5nZXRUYXJnZXQoKSwgJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSkgOiAnJywKICAgICAgICAgICAgICAgICRzdGF0dXMsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVuZGVyVGFibGUoJHJvd3MsICRvdXRwdXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXEluc3RhbGxlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxQcm9qZWN0SW5zdGFsbGVyOwp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyXFN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblNlbGVjdG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxBbGlhc1BhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxDb21wb3NpdGVSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZEZpbGVzeXN0ZW1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0Owp1c2UgQ29tcG9zZXJcU2NyaXB0XFNjcmlwdEV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcU2lsZW5jZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcQ29uZmlnXEpzb25Db25maWdTb3VyY2U7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwoKLyoqCiAqIEluc3RhbGwgYSBwYWNrYWdlIGFzIG5ldyBwcm9qZWN0IGludG8gbmV3IGRpcmVjdG9yeS4KICoKICogQGF1dGhvciBCZW5qYW1pbiBFYmVybGVpIDxrb250YWt0QGJlYmVybGVpLmRlPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgVG9iaWFzIE11bmsgPHNjaG11bmtAdXNyYmluLmRlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQ3JlYXRlUHJvamVjdENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICAvKioKICAgICAqIEB2YXIgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJHN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXI7CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdjcmVhdGUtcHJvamVjdCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0NyZWF0ZXMgbmV3IHByb2plY3QgZnJvbSBhIHBhY2thZ2UgaW50byBnaXZlbiBkaXJlY3RvcnkuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2UnLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1BhY2thZ2UgbmFtZSB0byBiZSBpbnN0YWxsZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdkaXJlY3RvcnknLCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ0RpcmVjdG9yeSB3aGVyZSB0aGUgZmlsZXMgc2hvdWxkIGJlIGNyZWF0ZWQnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCd2ZXJzaW9uJywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdWZXJzaW9uLCB3aWxsIGRlZmF1bHQgdG8gbGF0ZXN0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3N0YWJpbGl0eScsICdzJywgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnTWluaW11bS1zdGFiaWxpdHkgYWxsb3dlZCAodW5sZXNzIGEgdmVyc2lvbiBpcyBzcGVjaWZpZWQpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IGV2ZW4gZm9yIGRldiB2ZXJzaW9ucy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVwb3NpdG9yeScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0FkZCBjdXN0b20gcmVwb3NpdG9yaWVzIHRvIGxvb2sgdGhlIHBhY2thZ2UgdXAsIGVpdGhlciBieSBVUkwgb3IgdXNpbmcgSlNPTiBhcnJheXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmVwb3NpdG9yeS11cmwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdERVBSRUNBVEVEOiBVc2UgLS1yZXBvc2l0b3J5IGluc3RlYWQuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2FkZC1yZXBvc2l0b3J5JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBZGQgdGhlIGN1c3RvbSByZXBvc2l0b3J5IGluIHRoZSBjb21wb3Nlci5qc29uLiBJZiBhIGxvY2sgZmlsZSBpcyBwcmVzZW50IGl0IHdpbGwgYmUgZGVsZXRlZCBhbmQgYW4gdXBkYXRlIHdpbGwgYmUgcnVuIGluc3RlYWQgb2YgaW5zdGFsbC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdFbmFibGVzIGluc3RhbGxhdGlvbiBvZiByZXF1aXJlLWRldiBwYWNrYWdlcyAoZW5hYmxlZCBieSBkZWZhdWx0LCBvbmx5IHByZXNlbnQgZm9yIEJDKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyBpbnN0YWxsYXRpb24gb2YgcmVxdWlyZS1kZXYgcGFja2FnZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWN1c3RvbS1pbnN0YWxsZXJzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdERVBSRUNBVEVEOiBVc2Ugbm8tcGx1Z2lucyBpbnN0ZWFkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIHByZXZlbnQgZXhlY3V0aW9uIG9mIGFsbCBkZWZpbmVkIHNjcmlwdHMgaW4gdGhlIHJvb3QgcGFja2FnZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tcHJvZ3Jlc3MnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCBvdXRwdXQgZG93bmxvYWQgcHJvZ3Jlc3MuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXNlY3VyZS1odHRwJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlIHRoZSBzZWN1cmUtaHR0cCBjb25maWcgb3B0aW9uIHRlbXBvcmFyaWx5IHdoaWxlIGluc3RhbGxpbmcgdGhlIHJvb3QgcGFja2FnZS4gVXNlIGF0IHlvdXIgb3duIHJpc2suIFVzaW5nIHRoaXMgZmxhZyBpcyBhIGJhZCBpZGVhLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdrZWVwLXZjcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnV2hldGhlciB0byBwcmV2ZW50IGRlbGV0aW5nIHRoZSB2Y3MgZm9sZGVyLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyZW1vdmUtdmNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIGZvcmNlIGRlbGV0aW9uIG9mIHRoZSB2Y3MgZm9sZGVyIHdpdGhvdXQgcHJvbXB0aW5nLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIHNraXAgaW5zdGFsbGF0aW9uIG9mIHRoZSBwYWNrYWdlIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCB8IElucHV0T3B0aW9uOjpWQUxVRV9JU19BUlJBWSwgJ0lnbm9yZSBhIHNwZWNpZmljIHBsYXRmb3JtIHJlcXVpcmVtZW50IChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0lnbm9yZSBhbGwgcGxhdGZvcm0gcmVxdWlyZW1lbnRzIChwaHAgJiBleHQtIHBhY2thZ2VzKS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXNrJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGV0aGVyIHRvIGFzayBmb3IgcHJvamVjdCBkaXJlY3RvcnkuJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+Y3JlYXRlLXByb2plY3Q8L2luZm8+IGNvbW1hbmQgY3JlYXRlcyBhIG5ldyBwcm9qZWN0IGZyb20gYSBnaXZlbgpwYWNrYWdlIGludG8gYSBuZXcgZGlyZWN0b3J5LiBJZiBleGVjdXRlZCB3aXRob3V0IHBhcmFtcyBhbmQgaW4gYSBkaXJlY3RvcnkKd2l0aCBhIGNvbXBvc2VyLmpzb24gZmlsZSBpdCBpbnN0YWxscyB0aGUgcGFja2FnZXMgZm9yIHRoZSBjdXJyZW50IHByb2plY3QuCgpZb3UgY2FuIHVzZSB0aGlzIGNvbW1hbmQgdG8gYm9vdHN0cmFwIG5ldyBwcm9qZWN0cyBvciBzZXR1cCBhIGNsZWFuCnZlcnNpb24tY29udHJvbGxlZCBpbnN0YWxsYXRpb24gZm9yIGRldmVsb3BlcnMgb2YgeW91ciBwcm9qZWN0LgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgY3JlYXRlLXByb2plY3QgdmVuZG9yL3Byb2plY3QgdGFyZ2V0LWRpcmVjdG9yeSBbdmVyc2lvbl08L2luZm8+CgpZb3UgY2FuIGFsc28gc3BlY2lmeSB0aGUgdmVyc2lvbiB3aXRoIHRoZSBwYWNrYWdlIG5hbWUgdXNpbmcgPSBvciA6IGFzIHNlcGFyYXRvci4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGNyZWF0ZS1wcm9qZWN0IHZlbmRvci9wcm9qZWN0OnZlcnNpb24gdGFyZ2V0LWRpcmVjdG9yeTwvaW5mbz4KClRvIGluc3RhbGwgdW5zdGFibGUgcGFja2FnZXMsIGVpdGhlciBzcGVjaWZ5IHRoZSB2ZXJzaW9uIHlvdSB3YW50LCBvciB1c2UgdGhlCi0tc3RhYmlsaXR5PWRldiAod2hlcmUgZGV2IGNhbiBiZSBvbmUgb2YgUkMsIGJldGEsIGFscGhhIG9yIGRldikuCgpUbyBzZXR1cCBhIGRldmVsb3BlciB3b3JrYWJsZSB2ZXJzaW9uIHlvdSBzaG91bGQgY3JlYXRlIHRoZSBwcm9qZWN0IHVzaW5nIHRoZSBzb3VyY2UKY29udHJvbGxlZCBjb2RlIGJ5IGFwcGVuZGluZyB0aGUgPGluZm8+Jy0tcHJlZmVyLXNvdXJjZSc8L2luZm8+IGZsYWcuCgpUbyBpbnN0YWxsIGEgcGFja2FnZSBmcm9tIGFub3RoZXIgcmVwb3NpdG9yeSB0aGFuIHRoZSBkZWZhdWx0IG9uZSB5b3UKY2FuIHBhc3MgdGhlIDxpbmZvPictLXJlcG9zaXRvcnk9aHR0cHM6Ly9teXJlcG9zaXRvcnkub3JnJzwvaW5mbz4gZmxhZy4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI2NyZWF0ZS1wcm9qZWN0CkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBsaXN0KCRwcmVmZXJTb3VyY2UsICRwcmVmZXJEaXN0KSA9ICR0aGlzLT5nZXRQcmVmZXJyZWRJbnN0YWxsT3B0aW9ucygkY29uZmlnLCAkaW5wdXQsIHRydWUpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2RldicpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gImRldiIuIERldiBwYWNrYWdlcyBhcmUgaW5zdGFsbGVkIGJ5IGRlZmF1bHQgbm93Ljwvd2FybmluZz4nKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1jdXN0b20taW5zdGFsbGVycycpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gIm5vLWN1c3RvbS1pbnN0YWxsZXJzIi4gVXNlICJuby1wbHVnaW5zIiBpbnN0ZWFkLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgJGlucHV0LT5zZXRPcHRpb24oJ25vLXBsdWdpbnMnLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmlzSW50ZXJhY3RpdmUoKSAmJiAkaW5wdXQtPmdldE9wdGlvbignYXNrJykpIHsKICAgICAgICAgICAgJHBhcnRzID0gZXhwbG9kZSgiLyIsIHN0cnRvbG93ZXIoJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpKSwgMik7CiAgICAgICAgICAgICRpbnB1dC0+c2V0QXJndW1lbnQoJ2RpcmVjdG9yeScsICRpby0+YXNrKCdOZXcgcHJvamVjdCBkaXJlY3RvcnkgWzxjb21tZW50PicuYXJyYXlfcG9wKCRwYXJ0cykuJzwvY29tbWVudD5dOiAnKSk7CiAgICAgICAgfQoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmluc3RhbGxQcm9qZWN0KAogICAgICAgICAgICAkaW8sCiAgICAgICAgICAgICRjb25maWcsCiAgICAgICAgICAgICRpbnB1dCwKICAgICAgICAgICAgJGlucHV0LT5nZXRBcmd1bWVudCgncGFja2FnZScpLAogICAgICAgICAgICAkaW5wdXQtPmdldEFyZ3VtZW50KCdkaXJlY3RvcnknKSwKICAgICAgICAgICAgJGlucHV0LT5nZXRBcmd1bWVudCgndmVyc2lvbicpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignc3RhYmlsaXR5JyksCiAgICAgICAgICAgICRwcmVmZXJTb3VyY2UsCiAgICAgICAgICAgICRwcmVmZXJEaXN0LAogICAgICAgICAgICAhJGlucHV0LT5nZXRPcHRpb24oJ25vLWRldicpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbigncmVwb3NpdG9yeScpID86ICRpbnB1dC0+Z2V0T3B0aW9uKCdyZXBvc2l0b3J5LXVybCcpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignbm8tc2NyaXB0cycpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignbm8tcHJvZ3Jlc3MnKSwKICAgICAgICAgICAgJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSwKICAgICAgICAgICAgJGlnbm9yZVBsYXRmb3JtUmVxcywKICAgICAgICAgICAgISRpbnB1dC0+Z2V0T3B0aW9uKCduby1zZWN1cmUtaHR0cCcpLAogICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignYWRkLXJlcG9zaXRvcnknKQogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGxQcm9qZWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgJHBhY2thZ2VOYW1lLCAkZGlyZWN0b3J5ID0gbnVsbCwgJHBhY2thZ2VWZXJzaW9uID0gbnVsbCwgJHN0YWJpbGl0eSA9ICdzdGFibGUnLCAkcHJlZmVyU291cmNlID0gZmFsc2UsICRwcmVmZXJEaXN0ID0gZmFsc2UsICRpbnN0YWxsRGV2UGFja2FnZXMgPSBmYWxzZSwgJHJlcG9zaXRvcmllcyA9IG51bGwsICRkaXNhYmxlUGx1Z2lucyA9IGZhbHNlLCAkbm9TY3JpcHRzID0gZmFsc2UsICRub1Byb2dyZXNzID0gZmFsc2UsICRub0luc3RhbGwgPSBmYWxzZSwgJGlnbm9yZVBsYXRmb3JtUmVxcyA9IGZhbHNlLCAkc2VjdXJlSHR0cCA9IHRydWUsICRhZGRSZXBvc2l0b3J5ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJG9sZEN3ZCA9IGdldGN3ZCgpOwoKICAgICAgICBpZiAoJHJlcG9zaXRvcmllcyAhPT0gbnVsbCAmJiAhaXNfYXJyYXkoJHJlcG9zaXRvcmllcykpIHsKICAgICAgICAgICAgJHJlcG9zaXRvcmllcyA9IChhcnJheSkgJHJlcG9zaXRvcmllczsKICAgICAgICB9CgogICAgICAgIC8vIHdlIG5lZWQgdG8gbWFudWFsbHkgbG9hZCB0aGUgY29uZmlndXJhdGlvbiB0byBwYXNzIHRoZSBhdXRoIGNyZWRlbnRpYWxzIHRvIHRoZSBpbyBpbnRlcmZhY2UhCiAgICAgICAgJGlvLT5sb2FkQ29uZmlndXJhdGlvbigkY29uZmlnKTsKCiAgICAgICAgJHRoaXMtPnN1Z2dlc3RlZFBhY2thZ2VzUmVwb3J0ZXIgPSBuZXcgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcigkaW8pOwoKICAgICAgICBpZiAoJHBhY2thZ2VOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRGcm9tVmNzID0gJHRoaXMtPmluc3RhbGxSb290UGFja2FnZSgkaW8sICRjb25maWcsICRwYWNrYWdlTmFtZSwgJGRpcmVjdG9yeSwgJHBhY2thZ2VWZXJzaW9uLCAkc3RhYmlsaXR5LCAkcHJlZmVyU291cmNlLCAkcHJlZmVyRGlzdCwgJGluc3RhbGxEZXZQYWNrYWdlcywgJHJlcG9zaXRvcmllcywgJGRpc2FibGVQbHVnaW5zLCAkbm9TY3JpcHRzLCAkbm9Qcm9ncmVzcywgJGlnbm9yZVBsYXRmb3JtUmVxcywgJHNlY3VyZUh0dHApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpbnN0YWxsZWRGcm9tVmNzID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlcG9zaXRvcmllcyAhPT0gbnVsbCAmJiAkYWRkUmVwb3NpdG9yeSAmJiBpc19maWxlKCdjb21wb3Nlci5sb2NrJykpIHsKICAgICAgICAgICAgdW5saW5rKCdjb21wb3Nlci5sb2NrJyk7CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoJGlvLCBudWxsLCAkZGlzYWJsZVBsdWdpbnMpOwoKICAgICAgICAvLyBhZGQgdGhlIHJlcG9zaXRvcnkgdG8gdGhlIGNvbXBvc2VyLmpzb24gYW5kIHVzZSBpdCBmb3IgdGhlIGluc3RhbGwgcnVuIGxhdGVyCiAgICAgICAgaWYgKCRyZXBvc2l0b3JpZXMgIT09IG51bGwgJiYgJGFkZFJlcG9zaXRvcnkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkaW5kZXggPT4gJHJlcG8pIHsKICAgICAgICAgICAgICAgICRyZXBvQ29uZmlnID0gUmVwb3NpdG9yeUZhY3Rvcnk6OmNvbmZpZ0Zyb21TdHJpbmcoJGlvLCAkY29tcG9zZXItPmdldENvbmZpZygpLCAkcmVwbywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAkY29tcG9zZXJKc29uUmVwb3NpdG9yaWVzQ29uZmlnID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0UmVwb3NpdG9yaWVzKCk7CiAgICAgICAgICAgICAgICAkbmFtZSA9IFJlcG9zaXRvcnlGYWN0b3J5OjpnZW5lcmF0ZVJlcG9zaXRvcnlOYW1lKCRpbmRleCwgJHJlcG9Db25maWcsICRjb21wb3Nlckpzb25SZXBvc2l0b3JpZXNDb25maWcpOwogICAgICAgICAgICAgICAgJGNvbmZpZ1NvdXJjZSA9IG5ldyBKc29uQ29uZmlnU291cmNlKG5ldyBKc29uRmlsZSgnY29tcG9zZXIuanNvbicpKTsKCiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKGlzc2V0KCRyZXBvQ29uZmlnWydwYWNrYWdpc3QnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3QnID0+IGZhbHNlKSkKICAgICAgICAgICAgICAgICAgICB8fCAoaXNzZXQoJHJlcG9Db25maWdbJ3BhY2thZ2lzdC5vcmcnXSkgJiYgJHJlcG9Db25maWcgPT09IGFycmF5KCdwYWNrYWdpc3Qub3JnJyA9PiBmYWxzZSkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnU291cmNlLT5hZGRSZXBvc2l0b3J5KCdwYWNrYWdpc3Qub3JnJywgZmFsc2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnU291cmNlLT5hZGRSZXBvc2l0b3J5KCRuYW1lLCAkcmVwb0NvbmZpZywgZmFsc2UpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjb21wb3NlciA9IEZhY3Rvcnk6OmNyZWF0ZSgkaW8sIG51bGwsICRkaXNhYmxlUGx1Z2lucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCRwcm9jZXNzKTsKCiAgICAgICAgaWYgKCRub1NjcmlwdHMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIC8vIGRpc3BhdGNoIGV2ZW50CiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoU2NyaXB0KFNjcmlwdEV2ZW50czo6UE9TVF9ST09UX1BBQ0tBR0VfSU5TVEFMTCwgJGluc3RhbGxEZXZQYWNrYWdlcyk7CiAgICAgICAgfQoKICAgICAgICAvLyB1c2UgdGhlIG5ldyBjb25maWcgaW5jbHVkaW5nIHRoZSBuZXdseSBpbnN0YWxsZWQgcHJvamVjdAogICAgICAgICRjb25maWcgPSAkY29tcG9zZXItPmdldENvbmZpZygpOwogICAgICAgIGxpc3QoJHByZWZlclNvdXJjZSwgJHByZWZlckRpc3QpID0gJHRoaXMtPmdldFByZWZlcnJlZEluc3RhbGxPcHRpb25zKCRjb25maWcsICRpbnB1dCk7CgogICAgICAgIC8vIGluc3RhbGwgZGVwZW5kZW5jaWVzIG9mIHRoZSBjcmVhdGVkIHByb2plY3QKICAgICAgICBpZiAoJG5vSW5zdGFsbCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkbm9Qcm9ncmVzcyk7CgogICAgICAgICAgICAkaW5zdGFsbGVyID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwogICAgICAgICAgICAkaW5zdGFsbGVyLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgICAgIC0+c2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCkKICAgICAgICAgICAgICAgIC0+c2V0RGV2TW9kZSgkaW5zdGFsbERldlBhY2thZ2VzKQogICAgICAgICAgICAgICAgLT5zZXRSdW5TY3JpcHRzKCEkbm9TY3JpcHRzKQogICAgICAgICAgICAgICAgLT5zZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgICAgICAgICAgICAgLT5zZXRTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKCR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyKQogICAgICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJGNvbmZpZy0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykpCiAgICAgICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkY29uZmlnLT5nZXQoJ2NsYXNzbWFwLWF1dGhvcml0YXRpdmUnKSkKICAgICAgICAgICAgICAgIC0+c2V0QXBjdUF1dG9sb2FkZXIoJGNvbmZpZy0+Z2V0KCdhcGN1LWF1dG9sb2FkZXInKSk7CgogICAgICAgICAgICBpZiAoISRjb21wb3Nlci0+Z2V0TG9ja2VyKCktPmlzTG9ja2VkKCkpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZXItPnNldFVwZGF0ZSh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRkaXNhYmxlUGx1Z2lucykgewogICAgICAgICAgICAgICAgJGluc3RhbGxlci0+ZGlzYWJsZVBsdWdpbnMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN0YXR1cyA9ICRpbnN0YWxsZXItPnJ1bigpOwogICAgICAgICAgICBpZiAoMCAhPT0gJHN0YXR1cykgewogICAgICAgICAgICAgICAgcmV0dXJuICRzdGF0dXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRoYXNWY3MgPSAkaW5zdGFsbGVkRnJvbVZjczsKICAgICAgICBpZiAoCiAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbigna2VlcC12Y3MnKQogICAgICAgICAgICAmJiAkaW5zdGFsbGVkRnJvbVZjcwogICAgICAgICAgICAmJiAoCiAgICAgICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbigncmVtb3ZlLXZjcycpCiAgICAgICAgICAgICAgICB8fCAhJGlvLT5pc0ludGVyYWN0aXZlKCkKICAgICAgICAgICAgICAgIHx8ICRpby0+YXNrQ29uZmlybWF0aW9uKCc8aW5mbz5EbyB5b3Ugd2FudCB0byByZW1vdmUgdGhlIGV4aXN0aW5nIFZDUyAoLmdpdCwgLnN2bi4uKSBoaXN0b3J5PzwvaW5mbz4gWzxjb21tZW50PlksbjwvY29tbWVudD5dPyAnKQogICAgICAgICAgICApCiAgICAgICAgKSB7CiAgICAgICAgICAgICRmaW5kZXIgPSBuZXcgRmluZGVyKCk7CiAgICAgICAgICAgICRmaW5kZXItPmRlcHRoKDApLT5kaXJlY3RvcmllcygpLT5pbihnZXRjd2QoKSktPmlnbm9yZVZDUyhmYWxzZSktPmlnbm9yZURvdEZpbGVzKGZhbHNlKTsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJy5zdm4nLCAnX3N2bicsICdDVlMnLCAnX2RhcmNzJywgJy5hcmNoLXBhcmFtcycsICcubW9ub3RvbmUnLCAnLmJ6cicsICcuZ2l0JywgJy5oZycsICcuZnNsY2tvdXQnLCAnX0ZPU1NJTF8nKSBhcyAkdmNzTmFtZSkgewogICAgICAgICAgICAgICAgJGZpbmRlci0+bmFtZSgkdmNzTmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkZGlycyA9IGl0ZXJhdG9yX3RvX2FycmF5KCRmaW5kZXIpOwogICAgICAgICAgICAgICAgdW5zZXQoJGZpbmRlcik7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGlycyBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkZnMtPnJlbW92ZURpcmVjdG9yeSgkZGlyKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCByZW1vdmUgJy4kZGlyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPkFuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlbW92aW5nIHRoZSBWQ1MgbWV0YWRhdGE6ICcuJGUtPmdldE1lc3NhZ2UoKS4nPC9lcnJvcj4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGhhc1ZjcyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gcmV3cml0aW5nIHNlbGYudmVyc2lvbiBkZXBlbmRlbmNpZXMgd2l0aCBleHBsaWNpdCB2ZXJzaW9uIG51bWJlcnMgaWYgdGhlIHBhY2thZ2UncyB2Y3MgbWV0YWRhdGEgaXMgZ29uZQogICAgICAgIGlmICghJGhhc1ZjcykgewogICAgICAgICAgICAkcGFja2FnZSA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICAkY29uZmlnU291cmNlID0gbmV3IEpzb25Db25maWdTb3VyY2UobmV3IEpzb25GaWxlKCdjb21wb3Nlci5qc29uJykpOwogICAgICAgICAgICBmb3JlYWNoIChCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlcyBhcyAkdHlwZSA9PiAkbWV0YSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPnsnZ2V0Jy4kbWV0YVsnbWV0aG9kJ119KCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSA9PT0gJ3NlbGYudmVyc2lvbicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1NvdXJjZS0+YWRkTGluaygkdHlwZSwgJGxpbmstPmdldFRhcmdldCgpLCAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkbm9TY3JpcHRzID09PSBmYWxzZSkgewogICAgICAgICAgICAvLyBkaXNwYXRjaCBldmVudAogICAgICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaFNjcmlwdChTY3JpcHRFdmVudHM6OlBPU1RfQ1JFQVRFX1BST0pFQ1RfQ01ELCAkaW5zdGFsbERldlBhY2thZ2VzKTsKICAgICAgICB9CgogICAgICAgIGNoZGlyKCRvbGRDd2QpOwogICAgICAgICR2ZW5kb3JDb21wb3NlckRpciA9ICRjb25maWctPmdldCgndmVuZG9yLWRpcicpLicvY29tcG9zZXInOwogICAgICAgIGlmIChpc19kaXIoJHZlbmRvckNvbXBvc2VyRGlyKSAmJiAkZnMtPmlzRGlyRW1wdHkoJHZlbmRvckNvbXBvc2VyRGlyKSkgewogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdmVuZG9yQ29tcG9zZXJEaXIpOwogICAgICAgICAgICAkdmVuZG9yRGlyID0gJGNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJyk7CiAgICAgICAgICAgIGlmIChpc19kaXIoJHZlbmRvckRpcikgJiYgJGZzLT5pc0RpckVtcHR5KCR2ZW5kb3JEaXIpKSB7CiAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdmVuZG9yRGlyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluc3RhbGxSb290UGFja2FnZShJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCAkcGFja2FnZU5hbWUsICRkaXJlY3RvcnkgPSBudWxsLCAkcGFja2FnZVZlcnNpb24gPSBudWxsLCAkc3RhYmlsaXR5ID0gJ3N0YWJsZScsICRwcmVmZXJTb3VyY2UgPSBmYWxzZSwgJHByZWZlckRpc3QgPSBmYWxzZSwgJGluc3RhbGxEZXZQYWNrYWdlcyA9IGZhbHNlLCBhcnJheSAkcmVwb3NpdG9yaWVzID0gbnVsbCwgJGRpc2FibGVQbHVnaW5zID0gZmFsc2UsICRub1NjcmlwdHMgPSBmYWxzZSwgJG5vUHJvZ3Jlc3MgPSBmYWxzZSwgJGlnbm9yZVBsYXRmb3JtUmVxcyA9IGZhbHNlLCAkc2VjdXJlSHR0cCA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKCEkc2VjdXJlSHR0cCkgewogICAgICAgICAgICAkY29uZmlnLT5tZXJnZShhcnJheSgnY29uZmlnJyA9PiBhcnJheSgnc2VjdXJlLWh0dHAnID0+IGZhbHNlKSkpOwogICAgICAgIH0KCiAgICAgICAgJHBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9ICRwYXJzZXItPnBhcnNlTmFtZVZlcnNpb25QYWlycyhhcnJheSgkcGFja2FnZU5hbWUpKTsKICAgICAgICAkbmFtZSA9IHN0cnRvbG93ZXIoJHJlcXVpcmVtZW50c1swXVsnbmFtZSddKTsKICAgICAgICBpZiAoISRwYWNrYWdlVmVyc2lvbiAmJiBpc3NldCgkcmVxdWlyZW1lbnRzWzBdWyd2ZXJzaW9uJ10pKSB7CiAgICAgICAgICAgICRwYWNrYWdlVmVyc2lvbiA9ICRyZXF1aXJlbWVudHNbMF1bJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIC8vIGlmIG5vIGRpcmVjdG9yeSB3YXMgc3BlY2lmaWVkLCB1c2UgdGhlIDJuZCBwYXJ0IG9mIHRoZSBwYWNrYWdlIG5hbWUKICAgICAgICBpZiAobnVsbCA9PT0gJGRpcmVjdG9yeSkgewogICAgICAgICAgICAkcGFydHMgPSBleHBsb2RlKCIvIiwgJG5hbWUsIDIpOwogICAgICAgICAgICAkZGlyZWN0b3J5ID0gZ2V0Y3dkKCkgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gYXJyYXlfcG9wKCRwYXJ0cyk7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2VzcyA9IG5ldyBQcm9jZXNzRXhlY3V0b3IoJGlvKTsKICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgkcHJvY2Vzcyk7CiAgICAgICAgaWYgKCEkZnMtPmlzQWJzb2x1dGVQYXRoKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICRkaXJlY3RvcnkgPSBnZXRjd2QoKSAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkZGlyZWN0b3J5OwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5DcmVhdGluZyBhICInIC4gJHBhY2thZ2VOYW1lIC4gJyIgcHJvamVjdCBhdCAiJyAuICRmcy0+ZmluZFNob3J0ZXN0UGF0aChnZXRjd2QoKSwgJGRpcmVjdG9yeSwgdHJ1ZSkgLiAnIjwvaW5mbz4nKTsKCiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQ2Fubm90IGNyZWF0ZSBwcm9qZWN0IGRpcmVjdG9yeSBhdCAiJy4kZGlyZWN0b3J5LiciLCBpdCBleGlzdHMgYXMgYSBmaWxlLicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGZzLT5pc0RpckVtcHR5KCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUHJvamVjdCBkaXJlY3RvcnkgIicuJGRpcmVjdG9yeS4nIiBpcyBub3QgZW1wdHkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkc3RhYmlsaXR5KSB7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkcGFja2FnZVZlcnNpb24pIHsKICAgICAgICAgICAgICAgICRzdGFiaWxpdHkgPSAnc3RhYmxlJzsKICAgICAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3teW14sXHNdKj9AKCcuaW1wbG9kZSgnfCcsIGFycmF5X2tleXMoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllcykpLicpJH1pJywgJHBhY2thZ2VWZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAkc3RhYmlsaXR5ID0gJG1hdGNoWzFdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHN0YWJpbGl0eSA9IFZlcnNpb25QYXJzZXI6OnBhcnNlU3RhYmlsaXR5KCRwYWNrYWdlVmVyc2lvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzdGFiaWxpdHkgPSBWZXJzaW9uUGFyc2VyOjpub3JtYWxpemVTdGFiaWxpdHkoJHN0YWJpbGl0eSk7CgogICAgICAgIGlmICghaXNzZXQoQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skc3RhYmlsaXR5XSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ludmFsaWQgc3RhYmlsaXR5IHByb3ZpZGVkICgnLiRzdGFiaWxpdHkuJyksIG11c3QgYmUgb25lIG9mOiAnLmltcGxvZGUoJywgJywgYXJyYXlfa2V5cyhCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzKSkpOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlKCRpbywgJGNvbmZpZy0+YWxsKCksICRkaXNhYmxlUGx1Z2lucyk7CiAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CiAgICAgICAgJHJtID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpOwoKICAgICAgICAkcmVwb3NpdG9yeVNldCA9IG5ldyBSZXBvc2l0b3J5U2V0KCRzdGFiaWxpdHkpOwogICAgICAgIGlmIChudWxsID09PSAkcmVwb3NpdG9yaWVzKSB7CiAgICAgICAgICAgICRyZXBvc2l0b3J5U2V0LT5hZGRSZXBvc2l0b3J5KG5ldyBDb21wb3NpdGVSZXBvc2l0b3J5KFJlcG9zaXRvcnlGYWN0b3J5OjpkZWZhdWx0UmVwb3MoJGlvLCAkY29uZmlnLCAkcm0pKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcG9zaXRvcmllcyBhcyAkcmVwbykgewogICAgICAgICAgICAgICAgJHJlcG9Db25maWcgPSBSZXBvc2l0b3J5RmFjdG9yeTo6Y29uZmlnRnJvbVN0cmluZygkaW8sICRjb25maWcsICRyZXBvLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAoaXNzZXQoJHJlcG9Db25maWdbJ3BhY2thZ2lzdCddKSAmJiAkcmVwb0NvbmZpZyA9PT0gYXJyYXkoJ3BhY2thZ2lzdCcgPT4gZmFsc2UpKQogICAgICAgICAgICAgICAgICAgIHx8IChpc3NldCgkcmVwb0NvbmZpZ1sncGFja2FnaXN0Lm9yZyddKSAmJiAkcmVwb0NvbmZpZyA9PT0gYXJyYXkoJ3BhY2thZ2lzdC5vcmcnID0+IGZhbHNlKSkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlcG9zaXRvcnlTZXQtPmFkZFJlcG9zaXRvcnkoUmVwb3NpdG9yeUZhY3Rvcnk6OmNyZWF0ZVJlcG8oJGlvLCAkY29uZmlnLCAkcmVwb0NvbmZpZywgJHJtKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwbGF0Zm9ybU92ZXJyaWRlcyA9ICRjb25maWctPmdldCgncGxhdGZvcm0nKSA/OiBhcnJheSgpOwogICAgICAgICRwbGF0Zm9ybVJlcG8gPSBuZXcgUGxhdGZvcm1SZXBvc2l0b3J5KGFycmF5KCksICRwbGF0Zm9ybU92ZXJyaWRlcyk7CgogICAgICAgIC8vIGZpbmQgdGhlIGxhdGVzdCB2ZXJzaW9uIGlmIHRoZXJlIGFyZSBtdWx0aXBsZQogICAgICAgICR2ZXJzaW9uU2VsZWN0b3IgPSBuZXcgVmVyc2lvblNlbGVjdG9yKCRyZXBvc2l0b3J5U2V0LCAkcGxhdGZvcm1SZXBvKTsKICAgICAgICAkcGFja2FnZSA9ICR2ZXJzaW9uU2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCRuYW1lLCAkcGFja2FnZVZlcnNpb24sICRzdGFiaWxpdHksICRpZ25vcmVQbGF0Zm9ybVJlcXMpOwoKICAgICAgICBpZiAoISRwYWNrYWdlKSB7CiAgICAgICAgICAgICRlcnJvck1lc3NhZ2UgPSAiQ291bGQgbm90IGZpbmQgcGFja2FnZSAkbmFtZSB3aXRoICIgLiAoJHBhY2thZ2VWZXJzaW9uID8gInZlcnNpb24gJHBhY2thZ2VWZXJzaW9uIiA6ICJzdGFiaWxpdHkgJHN0YWJpbGl0eSIpOwogICAgICAgICAgICBpZiAodHJ1ZSAhPT0gJGlnbm9yZVBsYXRmb3JtUmVxcyAmJiAkdmVyc2lvblNlbGVjdG9yLT5maW5kQmVzdENhbmRpZGF0ZSgkbmFtZSwgJHBhY2thZ2VWZXJzaW9uLCAkc3RhYmlsaXR5LCB0cnVlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJGVycm9yTWVzc2FnZSAuJyBpbiBhIHZlcnNpb24gaW5zdGFsbGFibGUgdXNpbmcgeW91ciBQSFAgdmVyc2lvbiwgUEhQIGV4dGVuc2lvbnMgYW5kIENvbXBvc2VyIHZlcnNpb24uJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCRlcnJvck1lc3NhZ2UgLicuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGVyIEN0cmwrQyBmb3IgdW5peC1saWtlIHN5c3RlbXMKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwY250bF9hc3luY19zaWduYWxzJykgJiYgZnVuY3Rpb25fZXhpc3RzKCdwY250bF9zaWduYWwnKSkgewogICAgICAgICAgICBAbWtkaXIoJGRpcmVjdG9yeSwgMDc3NywgdHJ1ZSk7CiAgICAgICAgICAgIGlmICgkcmVhbERpciA9IHJlYWxwYXRoKCRkaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICAgICBwY250bF9hc3luY19zaWduYWxzKHRydWUpOwogICAgICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0lOVCwgZnVuY3Rpb24gKCkgdXNlICgkcmVhbERpcikgewogICAgICAgICAgICAgICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICAgICAgICAgJGZzLT5yZW1vdmVEaXJlY3RvcnkoJHJlYWxEaXIpOwogICAgICAgICAgICAgICAgICAgIGV4aXQoMTMwKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIGhhbmRsZXIgQ3RybCtDIGZvciBXaW5kb3dzIG9uIFBIUCA3LjQrCiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXInKSAmJiBQSFBfU0FQSSA9PT0gJ2NsaScpIHsKICAgICAgICAgICAgQG1rZGlyKCRkaXJlY3RvcnksIDA3NzcsIHRydWUpOwogICAgICAgICAgICBpZiAoJHJlYWxEaXIgPSByZWFscGF0aCgkZGlyZWN0b3J5KSkgewogICAgICAgICAgICAgICAgc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXIoZnVuY3Rpb24gKCkgdXNlICgkcmVhbERpcikgewogICAgICAgICAgICAgICAgICAgICRmcyA9IG5ldyBGaWxlc3lzdGVtKCk7CiAgICAgICAgICAgICAgICAgICAgJGZzLT5yZW1vdmVEaXJlY3RvcnkoJHJlYWxEaXIpOwogICAgICAgICAgICAgICAgICAgIGV4aXQoMTMwKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBhdm9pZCBkaXNwbGF5aW5nIDk5OTk5OTktZGV2IGFzIHZlcnNpb24gaWYgZGVmYXVsdC1icmFuY2ggd2FzIHNlbGVjdGVkCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+SW5zdGFsbGluZyAnIC4gJHBhY2thZ2UtPmdldE5hbWUoKSAuICcgKCcgLiAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oZmFsc2UpIC4gJyk8L2luZm8+Jyk7CgogICAgICAgIGlmICgkZGlzYWJsZVBsdWdpbnMpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5QbHVnaW5zIGhhdmUgYmVlbiBkaXNhYmxlZC48L2luZm8+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSAkcGFja2FnZS0+Z2V0QWxpYXNPZigpOwogICAgICAgIH0KCiAgICAgICAgJGRtID0gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKTsKICAgICAgICAkZG0tPnNldFByZWZlclNvdXJjZSgkcHJlZmVyU291cmNlKQogICAgICAgICAgICAtPnNldFByZWZlckRpc3QoJHByZWZlckRpc3QpOwoKICAgICAgICAkcHJvamVjdEluc3RhbGxlciA9IG5ldyBQcm9qZWN0SW5zdGFsbGVyKCRkaXJlY3RvcnksICRkbSwgJGZzKTsKICAgICAgICAkaW0gPSAkY29tcG9zZXItPmdldEluc3RhbGxhdGlvbk1hbmFnZXIoKTsKICAgICAgICAkaW0tPnNldE91dHB1dFByb2dyZXNzKCEkbm9Qcm9ncmVzcyk7CiAgICAgICAgJGltLT5hZGRJbnN0YWxsZXIoJHByb2plY3RJbnN0YWxsZXIpOwogICAgICAgICRpbS0+ZXhlY3V0ZShuZXcgSW5zdGFsbGVkRmlsZXN5c3RlbVJlcG9zaXRvcnkobmV3IEpzb25GaWxlKCdwaHA6Ly9tZW1vcnknKSksIGFycmF5KG5ldyBJbnN0YWxsT3BlcmF0aW9uKCRwYWNrYWdlKSkpOwogICAgICAgICRpbS0+bm90aWZ5SW5zdGFsbHMoJGlvKTsKCiAgICAgICAgLy8gY29sbGVjdCBzdWdnZXN0aW9ucwogICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyLT5hZGRTdWdnZXN0aW9uc0Zyb21QYWNrYWdlKCRwYWNrYWdlKTsKCiAgICAgICAgJGluc3RhbGxlZEZyb21WY3MgPSAnc291cmNlJyA9PT0gJHBhY2thZ2UtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpOwoKICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPkNyZWF0ZWQgcHJvamVjdCBpbiAnIC4gJGRpcmVjdG9yeSAuICc8L2luZm8+Jyk7CiAgICAgICAgY2hkaXIoJGRpcmVjdG9yeSk7CgogICAgICAgICRfU0VSVkVSWydDT01QT1NFUl9ST09UX1ZFUlNJT04nXSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgcHV0ZW52KCdDT01QT1NFUl9ST09UX1ZFUlNJT049Jy4kX1NFUlZFUlsnQ09NUE9TRVJfUk9PVF9WRVJTSU9OJ10pOwoKICAgICAgICByZXR1cm4gJGluc3RhbGxlZEZyb21WY3M7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcQ29uZmlnXEpzb25Db25maWdTb3VyY2U7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXEJhc2VQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgSm9zaHVhIEVzdGVzIDxKb3NodWEuRXN0ZXNAaW9zdHVkaW8uY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDb25maWdDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBAdmFyIENvbmZpZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbmZpZzsKCiAgICAvKioKICAgICAqIEB2YXIgSnNvbkZpbGUKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25maWdGaWxlOwoKICAgIC8qKgogICAgICogQHZhciBKc29uQ29uZmlnU291cmNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnU291cmNlOwoKICAgIC8qKgogICAgICogQHZhciBKc29uRmlsZQogICAgICovCiAgICBwcm90ZWN0ZWQgJGF1dGhDb25maWdGaWxlOwoKICAgIC8qKgogICAgICogQHZhciBKc29uQ29uZmlnU291cmNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXV0aENvbmZpZ1NvdXJjZTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdjb25maWcnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdTZXRzIGNvbmZpZyBvcHRpb25zLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZ2xvYmFsJywgJ2cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0FwcGx5IGNvbW1hbmQgdG8gdGhlIGdsb2JhbCBjb25maWcgZmlsZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdlZGl0b3InLCAnZScsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT3BlbiBlZGl0b3InKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXV0aCcsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBZmZlY3QgYXV0aCBjb25maWcgZmlsZSAob25seSB1c2VkIGZvciAtLWVkaXRvciknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndW5zZXQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Vuc2V0IHRoZSBnaXZlbiBzZXR0aW5nLWtleScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaXN0JywgJ2wnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0xpc3QgY29uZmlndXJhdGlvbiBzZXR0aW5ncycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdmaWxlJywgJ2YnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdJZiB5b3Ugd2FudCB0byBjaG9vc2UgYSBkaWZmZXJlbnQgY29tcG9zZXIuanNvbiBvciBjb25maWcuanNvbicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhYnNvbHV0ZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUmV0dXJucyBhYnNvbHV0ZSBwYXRocyB3aGVuIGZldGNoaW5nICotZGlyIGNvbmZpZyB2YWx1ZXMgaW5zdGVhZCBvZiByZWxhdGl2ZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdqc29uJywgJ2onLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0pTT04gZGVjb2RlIHRoZSBzZXR0aW5nIHZhbHVlLCB0byBiZSB1c2VkIHdpdGggZXh0cmEuKiBrZXlzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ21lcmdlJywgJ20nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ01lcmdlIHRoZSBzZXR0aW5nIHZhbHVlIHdpdGggdGhlIGN1cnJlbnQgdmFsdWUsIHRvIGJlIHVzZWQgd2l0aCBleHRyYS4qIGtleXMgaW4gY29tYmluYXRpb24gd2l0aCAtLWpzb24nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBwZW5kJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdXaGVuIGFkZGluZyBhIHJlcG9zaXRvcnksIGFwcGVuZCBpdCAobG93ZXN0IHByaW9yaXR5KSB0byB0aGUgZXhpc3Rpbmcgb25lcyBpbnN0ZWFkIG9mIHByZXBlbmRpbmcgaXQgKGhpZ2hlc3QgcHJpb3JpdHkpJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnc2V0dGluZy1rZXknLCBudWxsLCAnU2V0dGluZyBrZXknKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdzZXR0aW5nLXZhbHVlJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVksICdTZXR0aW5nIHZhbHVlJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGlzIGNvbW1hbmQgYWxsb3dzIHlvdSB0byBlZGl0IGNvbXBvc2VyIGNvbmZpZyBzZXR0aW5ncyBhbmQgcmVwb3NpdG9yaWVzCmluIGVpdGhlciB0aGUgbG9jYWwgY29tcG9zZXIuanNvbiBmaWxlIG9yIHRoZSBnbG9iYWwgY29uZmlnLmpzb24gZmlsZS4KCkFkZGl0aW9uYWxseSBpdCBsZXRzIHlvdSBlZGl0IG1vc3QgcHJvcGVydGllcyBpbiB0aGUgbG9jYWwgY29tcG9zZXIuanNvbi4KClRvIHNldCBhIGNvbmZpZyBzZXR0aW5nOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgYmluLWRpciBiaW4vPC9jb21tZW50PgoKVG8gcmVhZCBhIGNvbmZpZyBzZXR0aW5nOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgYmluLWRpcjwvY29tbWVudD4KICAgIE91dHB1dHM6IDxpbmZvPmJpbjwvaW5mbz4KClRvIGVkaXQgdGhlIGdsb2JhbCBjb25maWcuanNvbiBmaWxlOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgLS1nbG9iYWw8L2NvbW1lbnQ+CgpUbyBhZGQgYSByZXBvc2l0b3J5OgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgcmVwb3NpdG9yaWVzLmZvbyB2Y3MgaHR0cHM6Ly9iYXIuY29tPC9jb21tZW50PgoKVG8gcmVtb3ZlIGEgcmVwb3NpdG9yeSAocmVwbyBpcyBhIHNob3J0IGFsaWFzIGZvciByZXBvc2l0b3JpZXMpOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgLS11bnNldCByZXBvLmZvbzwvY29tbWVudD4KClRvIGRpc2FibGUgcGFja2FnaXN0OgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgcmVwby5wYWNrYWdpc3QgZmFsc2U8L2NvbW1lbnQ+CgpZb3UgY2FuIGFsdGVyIHJlcG9zaXRvcmllcyBpbiB0aGUgZ2xvYmFsIGNvbmZpZy5qc29uIGZpbGUgYnkgcGFzc2luZyBpbiB0aGUKPGluZm8+LS1nbG9iYWw8L2luZm8+IG9wdGlvbi4KClRvIGFkZCBvciBlZGl0IHN1Z2dlc3RlZCBwYWNrYWdlcyB5b3UgY2FuIHVzZToKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIHN1Z2dlc3QucGFja2FnZSByZWFzb24gZm9yIHRoZSBzdWdnZXN0aW9uPC9jb21tZW50PgoKVG8gYWRkIG9yIGVkaXQgZXh0cmEgcHJvcGVydGllcyB5b3UgY2FuIHVzZToKCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIGV4dHJhLnByb3BlcnR5IHZhbHVlPC9jb21tZW50PgoKT3IgdG8gYWRkIGEgY29tcGxleCB2YWx1ZSB5b3UgY2FuIHVzZSBqc29uIHdpdGg6CgogICAgPGNvbW1lbnQ+JWNvbW1hbmQuZnVsbF9uYW1lJSBleHRyYS5wcm9wZXJ0eSAtLWpzb24gJ3siZm9vIjp0cnVlLCAiYmFyIjogW119JzwvY29tbWVudD4KClRvIGVkaXQgdGhlIGZpbGUgaW4gYW4gZXh0ZXJuYWwgZWRpdG9yOgoKICAgIDxjb21tZW50PiVjb21tYW5kLmZ1bGxfbmFtZSUgLS1lZGl0b3I8L2NvbW1lbnQ+CgpUbyBjaG9vc2UgeW91ciBlZGl0b3IgeW91IGNhbiBzZXQgdGhlICJFRElUT1IiIGVudiB2YXJpYWJsZS4KClRvIGdldCBhIGxpc3Qgb2YgY29uZmlndXJhdGlvbiB2YWx1ZXMgaW4gdGhlIGZpbGU6CgogICAgPGNvbW1lbnQ+JWNvbW1hbmQuZnVsbF9uYW1lJSAtLWxpc3Q8L2NvbW1lbnQ+CgpZb3UgY2FuIGFsd2F5cyBwYXNzIG1vcmUgdGhhbiBvbmUgb3B0aW9uLiBBcyBhbiBleGFtcGxlLCBpZiB5b3Ugd2FudCB0byBlZGl0IHRoZQpnbG9iYWwgY29uZmlnLmpzb24gZmlsZS4KCiAgICA8Y29tbWVudD4lY29tbWFuZC5mdWxsX25hbWUlIC0tZWRpdG9yIC0tZ2xvYmFsPC9jb21tZW50PgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjY29uZmlnCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIHBhcmVudDo6aW5pdGlhbGl6ZSgkaW5wdXQsICRvdXRwdXQpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpICYmIG51bGwgIT09ICRpbnB1dC0+Z2V0T3B0aW9uKCdmaWxlJykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCctLWZpbGUgYW5kIC0tZ2xvYmFsIGNhbiBub3QgYmUgY29tYmluZWQnKTsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICR0aGlzLT5jb25maWcgPSBGYWN0b3J5OjpjcmVhdGVDb25maWcoJGlvKTsKCiAgICAgICAgLy8gR2V0IHRoZSBsb2NhbCBjb21wb3Nlci5qc29uLCBnbG9iYWwgY29uZmlnLmpzb24sIG9yIGlmIHRoZSB1c2VyCiAgICAgICAgLy8gcGFzc2VkIGluIGEgZmlsZSB0byB1c2UKICAgICAgICAkY29uZmlnRmlsZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdnbG9iYWwnKQogICAgICAgICAgICA/ICgkdGhpcy0+Y29uZmlnLT5nZXQoJ2hvbWUnKSAuICcvY29uZmlnLmpzb24nKQogICAgICAgICAgICA6ICgkaW5wdXQtPmdldE9wdGlvbignZmlsZScpID86IEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpKTsKCiAgICAgICAgLy8gQ3JlYXRlIGdsb2JhbCBjb21wb3Nlci5qc29uIGlmIHRoaXMgd2FzIGludm9rZWQgdXNpbmcgYGNvbXBvc2VyIGdsb2JhbCBjb25maWdgCiAgICAgICAgaWYgKAogICAgICAgICAgICAoJGNvbmZpZ0ZpbGUgPT09ICdjb21wb3Nlci5qc29uJyB8fCAkY29uZmlnRmlsZSA9PT0gJy4vY29tcG9zZXIuanNvbicpCiAgICAgICAgICAgICYmICFmaWxlX2V4aXN0cygkY29uZmlnRmlsZSkKICAgICAgICAgICAgJiYgcmVhbHBhdGgoZ2V0Y3dkKCkpID09PSByZWFscGF0aCgkdGhpcy0+Y29uZmlnLT5nZXQoJ2hvbWUnKSkKICAgICAgICApIHsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGNvbmZpZ0ZpbGUsICJ7XG59XG4iKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb25maWdGaWxlID0gbmV3IEpzb25GaWxlKCRjb25maWdGaWxlLCBudWxsLCAkaW8pOwogICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UgPSBuZXcgSnNvbkNvbmZpZ1NvdXJjZSgkdGhpcy0+Y29uZmlnRmlsZSk7CgogICAgICAgICRhdXRoQ29uZmlnRmlsZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdnbG9iYWwnKQogICAgICAgICAgICA/ICgkdGhpcy0+Y29uZmlnLT5nZXQoJ2hvbWUnKSAuICcvYXV0aC5qc29uJykKICAgICAgICAgICAgOiBkaXJuYW1lKHJlYWxwYXRoKCRjb25maWdGaWxlKSkgLiAnL2F1dGguanNvbic7CgogICAgICAgICR0aGlzLT5hdXRoQ29uZmlnRmlsZSA9IG5ldyBKc29uRmlsZSgkYXV0aENvbmZpZ0ZpbGUsIG51bGwsICRpbyk7CiAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UgPSBuZXcgSnNvbkNvbmZpZ1NvdXJjZSgkdGhpcy0+YXV0aENvbmZpZ0ZpbGUsIHRydWUpOwoKICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBnbG9iYWwgZmlsZSBpZiBpdCdzIG5vdCB0aGVyZSwgaWdub3JpbmcgYW55IHdhcm5pbmdzIG9yIG5vdGljZXMKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpICYmICEkdGhpcy0+Y29uZmlnRmlsZS0+ZXhpc3RzKCkpIHsKICAgICAgICAgICAgdG91Y2goJHRoaXMtPmNvbmZpZ0ZpbGUtPmdldFBhdGgoKSk7CiAgICAgICAgICAgICR0aGlzLT5jb25maWdGaWxlLT53cml0ZShhcnJheSgnY29uZmlnJyA9PiBuZXcgXEFycmF5T2JqZWN0KSk7CiAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCdjaG1vZCcsICR0aGlzLT5jb25maWdGaWxlLT5nZXRQYXRoKCksIDA2MDApOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpICYmICEkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIHRvdWNoKCR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+Z2V0UGF0aCgpKTsKICAgICAgICAgICAgJHRoaXMtPmF1dGhDb25maWdGaWxlLT53cml0ZShhcnJheSgnYml0YnVja2V0LW9hdXRoJyA9PiBuZXcgXEFycmF5T2JqZWN0LCAnZ2l0aHViLW9hdXRoJyA9PiBuZXcgXEFycmF5T2JqZWN0LCAnZ2l0bGFiLW9hdXRoJyA9PiBuZXcgXEFycmF5T2JqZWN0LCAnZ2l0bGFiLXRva2VuJyA9PiBuZXcgXEFycmF5T2JqZWN0LCAnaHR0cC1iYXNpYycgPT4gbmV3IFxBcnJheU9iamVjdCwgJ2JlYXJlcicgPT4gbmV3IFxBcnJheU9iamVjdCkpOwogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnY2htb2QnLCAkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPmdldFBhdGgoKSwgMDYwMCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5jb25maWdGaWxlLT5leGlzdHMoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignRmlsZSAiJXMiIGNhbm5vdCBiZSBmb3VuZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnknLCAkY29uZmlnRmlsZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAvLyBPcGVuIGZpbGUgaW4gZWRpdG9yCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdlZGl0b3InKSkgewogICAgICAgICAgICAkZWRpdG9yID0gZXNjYXBlc2hlbGxjbWQoZ2V0ZW52KCdFRElUT1InKSk7CiAgICAgICAgICAgIGlmICghJGVkaXRvcikgewogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICRlZGl0b3IgPSAnbm90ZXBhZCc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCdlZGl0b3InLCAndmltJywgJ3ZpJywgJ25hbm8nLCAncGljbycsICdlZCcpIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4ZWMoJ3doaWNoICcuJGNhbmRpZGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlZGl0b3IgPSAkY2FuZGlkYXRlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRmaWxlID0gJGlucHV0LT5nZXRPcHRpb24oJ2F1dGgnKSA/ICR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+Z2V0UGF0aCgpIDogJHRoaXMtPmNvbmZpZ0ZpbGUtPmdldFBhdGgoKTsKICAgICAgICAgICAgc3lzdGVtKCRlZGl0b3IgLiAnICcgLiAkZmlsZSAuIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgPyAnJyA6ICcgPiBgdHR5YCcpKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignZ2xvYmFsJykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+bWVyZ2UoJHRoaXMtPmNvbmZpZ0ZpbGUtPnJlYWQoKSk7CiAgICAgICAgICAgICR0aGlzLT5jb25maWctPm1lcmdlKGFycmF5KCdjb25maWcnID0+ICR0aGlzLT5hdXRoQ29uZmlnRmlsZS0+ZXhpc3RzKCkgPyAkdGhpcy0+YXV0aENvbmZpZ0ZpbGUtPnJlYWQoKSA6IGFycmF5KCkpKTsKICAgICAgICB9CgogICAgICAgIC8vIExpc3QgdGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGZpbGUgc2V0dGluZ3MKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2xpc3QnKSkgewogICAgICAgICAgICAkdGhpcy0+bGlzdENvbmZpZ3VyYXRpb24oJHRoaXMtPmNvbmZpZy0+YWxsKCksICR0aGlzLT5jb25maWctPnJhdygpLCAkb3V0cHV0KTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJHNldHRpbmdLZXkgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzZXR0aW5nLWtleScpOwogICAgICAgIGlmICghJHNldHRpbmdLZXkgfHwgIWlzX3N0cmluZygkc2V0dGluZ0tleSkpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGUgdXNlciBlbnRlcnMgaW4gYSBjb25maWcgdmFyaWFibGUsIHBhcnNlIGl0IGFuZCBzYXZlIHRvIGZpbGUKICAgICAgICBpZiAoYXJyYXkoKSAhPT0gJGlucHV0LT5nZXRBcmd1bWVudCgnc2V0dGluZy12YWx1ZScpICYmICRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IGNhbiBub3QgY29tYmluZSBhIHNldHRpbmcgdmFsdWUgd2l0aCAtLXVuc2V0Jyk7CiAgICAgICAgfQoKICAgICAgICAvLyBzaG93IHRoZSB2YWx1ZSBpZiBubyB2YWx1ZSBpcyBwcm92aWRlZAogICAgICAgIGlmIChhcnJheSgpID09PSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzZXR0aW5nLXZhbHVlJykgJiYgISRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICRwcm9wZXJ0aWVzID0gYXJyYXkoJ25hbWUnLCAndHlwZScsICdkZXNjcmlwdGlvbicsICdob21lcGFnZScsICd2ZXJzaW9uJywgJ21pbmltdW0tc3RhYmlsaXR5JywgJ3ByZWZlci1zdGFibGUnLCAna2V5d29yZHMnLCAnbGljZW5zZScsICdleHRyYScpOwogICAgICAgICAgICAkcmF3RGF0YSA9ICR0aGlzLT5jb25maWdGaWxlLT5yZWFkKCk7CiAgICAgICAgICAgICRkYXRhID0gJHRoaXMtPmNvbmZpZy0+YWxsKCk7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXnJlcG9zPyg/Oml0b3JpZXMpPyg/OlwuKC4rKSk/LycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJG1hdGNoZXNbMV0pIHx8ICRtYXRjaGVzWzFdID09PSAnJykgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IGlzc2V0KCRkYXRhWydyZXBvc2l0b3JpZXMnXSkgPyAkZGF0YVsncmVwb3NpdG9yaWVzJ10gOiBhcnJheSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWydyZXBvc2l0b3JpZXMnXVskbWF0Y2hlc1sxXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGVyZSBpcyBubyAnLiRtYXRjaGVzWzFdLicgcmVwb3NpdG9yeSBkZWZpbmVkJyk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkZGF0YVsncmVwb3NpdG9yaWVzJ11bJG1hdGNoZXNbMV1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCRzZXR0aW5nS2V5LCAnLicpKSB7CiAgICAgICAgICAgICAgICAkYml0cyA9IGV4cGxvZGUoJy4nLCAkc2V0dGluZ0tleSk7CiAgICAgICAgICAgICAgICBpZiAoJGJpdHNbMF0gPT09ICdleHRyYScpIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YSA9ICRyYXdEYXRhOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZGF0YSA9ICRkYXRhWydjb25maWcnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGJpdHMgYXMgJGJpdCkgewogICAgICAgICAgICAgICAgICAgICRrZXkgPSBpc3NldCgka2V5KSA/ICRrZXkuJy4nLiRiaXQgOiAkYml0OwogICAgICAgICAgICAgICAgICAgICRtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGEgPSAkZGF0YVska2V5XTsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGtleSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRzZXR0aW5nS2V5LicgaXMgbm90IGRlZmluZWQuJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHZhbHVlID0gJGRhdGE7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkZGF0YVsnY29uZmlnJ11bJHNldHRpbmdLZXldKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCRzZXR0aW5nS2V5LCAkaW5wdXQtPmdldE9wdGlvbignYWJzb2x1dGUnKSA/IDAgOiBDb25maWc6OlJFTEFUSVZFX1BBVEhTKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRyYXdEYXRhWyRzZXR0aW5nS2V5XSkgJiYgaW5fYXJyYXkoJHNldHRpbmdLZXksICRwcm9wZXJ0aWVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHJhd0RhdGFbJHNldHRpbmdLZXldOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRzZXR0aW5nS2V5LicgaXMgbm90IGRlZmluZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IGpzb25fZW5jb2RlKCR2YWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgkdmFsdWUsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgICR2YWx1ZXMgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdzZXR0aW5nLXZhbHVlJyk7IC8vIHdoYXQgdGhlIHVzZXIgaXMgdHJ5aW5nIHRvIGFkZC9jaGFuZ2UKCiAgICAgICAgJGJvb2xlYW5WYWxpZGF0b3IgPSBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICByZXR1cm4gaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJyksIHRydWUpOwogICAgICAgIH07CiAgICAgICAgJGJvb2xlYW5Ob3JtYWxpemVyID0gZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgcmV0dXJuICR2YWwgIT09ICdmYWxzZScgJiYgKGJvb2wpICR2YWw7CiAgICAgICAgfTsKCiAgICAgICAgLy8gaGFuZGxlIGNvbmZpZyB2YWx1ZXMKICAgICAgICAkdW5pcXVlQ29uZmlnVmFsdWVzID0gYXJyYXkoCiAgICAgICAgICAgICdwcm9jZXNzLXRpbWVvdXQnID0+IGFycmF5KCdpc19udW1lcmljJywgJ2ludHZhbCcpLAogICAgICAgICAgICAndXNlLWluY2x1ZGUtcGF0aCcgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICd1c2UtZ2l0aHViLWFwaScgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdwcmVmZXJyZWQtaW5zdGFsbCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgnYXV0bycsICdzb3VyY2UnLCAnZGlzdCcpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgJ3N0b3JlLWF1dGhzJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluX2FycmF5KCR2YWwsIGFycmF5KCd0cnVlJywgJ2ZhbHNlJywgJ3Byb21wdCcpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICgncHJvbXB0JyA9PT0gJHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3Byb21wdCc7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdub3RpZnktb24taW5zdGFsbCcgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICd2ZW5kb3ItZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2Jpbi1kaXInID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnYXJjaGl2ZS1kaXInID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnYXJjaGl2ZS1mb3JtYXQnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnZGF0YS1kaXInID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnY2FjaGUtZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2NhY2hlLWZpbGVzLWRpcicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdjYWNoZS1yZXBvLWRpcicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdjYWNoZS12Y3MtZGlyJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ2NhY2hlLXR0bCcgPT4gYXJyYXkoJ2lzX251bWVyaWMnLCAnaW50dmFsJyksCiAgICAgICAgICAgICdjYWNoZS1maWxlcy10dGwnID0+IGFycmF5KCdpc19udW1lcmljJywgJ2ludHZhbCcpLAogICAgICAgICAgICAnY2FjaGUtZmlsZXMtbWF4c2l6ZScgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmVnX21hdGNoKCcvXlxzKihbMC05Ll0rKVxzKig/Oihba21nXSkoPzppP2IpPyk/XHMqJC9pJywgJHZhbCkgPiAwOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnYmluLWNvbXBhdCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbl9hcnJheSgkdmFsLCBhcnJheSgnYXV0bycsICdmdWxsJykpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnZGlzY2FyZC1jaGFuZ2VzJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluX2FycmF5KCR2YWwsIGFycmF5KCdzdGFzaCcsICd0cnVlJywgJ2ZhbHNlJywgJzEnLCAnMCcpLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICgnc3Rhc2gnID09PSAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnc3Rhc2gnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWwgIT09ICdmYWxzZScgJiYgKGJvb2wpICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnYXV0b2xvYWRlci1zdWZmaXgnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWwgPT09ICdudWxsJyA/IG51bGwgOiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ3NvcnQtcGFja2FnZXMnID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnb3B0aW1pemUtYXV0b2xvYWRlcicgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICAgICAgJ2FwY3UtYXV0b2xvYWRlcicgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdwcmVwZW5kLWF1dG9sb2FkZXInID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnZGlzYWJsZS10bHMnID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnc2VjdXJlLWh0dHAnID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAnY2FmaWxlJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVfZXhpc3RzKCR2YWwpICYmIGlzX3JlYWRhYmxlKCR2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWwgPT09ICdudWxsJyA/IG51bGwgOiAkdmFsOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgJ2NhcGF0aCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc19kaXIoJHZhbCkgJiYgaXNfcmVhZGFibGUoJHZhbCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCA9PT0gJ251bGwnID8gbnVsbCA6ICR2YWw7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLAogICAgICAgICAgICAnZ2l0aHViLWV4cG9zZS1ob3N0bmFtZScgPT4gYXJyYXkoJGJvb2xlYW5WYWxpZGF0b3IsICRib29sZWFuTm9ybWFsaXplciksCiAgICAgICAgICAgICdodGFjY2Vzcy1wcm90ZWN0JyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICAgICAgJ2xvY2snID0+IGFycmF5KCRib29sZWFuVmFsaWRhdG9yLCAkYm9vbGVhbk5vcm1hbGl6ZXIpLAogICAgICAgICAgICAncGxhdGZvcm0tY2hlY2snID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ3BocC1vbmx5JywgJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJyksIHRydWUpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCdwaHAtb25seScgPT09ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdwaHAtb25seSc7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHZhbCAhPT0gJ2ZhbHNlJyAmJiAoYm9vbCkgJHZhbDsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgKTsKICAgICAgICAkbXVsdGlDb25maWdWYWx1ZXMgPSBhcnJheSgKICAgICAgICAgICAgJ2dpdGh1Yi1wcm90b2NvbHMnID0+IGFycmF5KAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19hcnJheSgkdmFscykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdhcnJheSBleHBlY3RlZCc7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdmFscyBhcyAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHZhbCwgYXJyYXkoJ2dpdCcsICdodHRwcycsICdzc2gnKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAndmFsaWQgcHJvdG9jb2xzIGluY2x1ZGU6IGdpdCwgaHR0cHMsIHNzaCc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdnaXRodWItZG9tYWlucycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR2YWxzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2FycmF5IGV4cGVjdGVkJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdnaXRsYWItZG9tYWlucycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR2YWxzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2FycmF5IGV4cGVjdGVkJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpICYmIChpc3NldCgkdW5pcXVlQ29uZmlnVmFsdWVzWyRzZXR0aW5nS2V5XSkgfHwgaXNzZXQoJG11bHRpQ29uZmlnVmFsdWVzWyRzZXR0aW5nS2V5XSkpKSB7CiAgICAgICAgICAgIGlmICgkc2V0dGluZ0tleSA9PT0gJ2Rpc2FibGUtdGxzJyAmJiAkdGhpcy0+Y29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCc8aW5mbz5Zb3UgYXJlIG5vdyBydW5uaW5nIENvbXBvc2VyIHdpdGggU1NML1RMUyBwcm90ZWN0aW9uIGVuYWJsZWQuPC9pbmZvPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJHVuaXF1ZUNvbmZpZ1ZhbHVlc1skc2V0dGluZ0tleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5oYW5kbGVTaW5nbGVWYWx1ZSgkc2V0dGluZ0tleSwgJHVuaXF1ZUNvbmZpZ1ZhbHVlc1skc2V0dGluZ0tleV0sICR2YWx1ZXMsICdhZGRDb25maWdTZXR0aW5nJyk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRtdWx0aUNvbmZpZ1ZhbHVlc1skc2V0dGluZ0tleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5oYW5kbGVNdWx0aVZhbHVlKCRzZXR0aW5nS2V5LCAkbXVsdGlDb25maWdWYWx1ZXNbJHNldHRpbmdLZXldLCAkdmFsdWVzLCAnYWRkQ29uZmlnU2V0dGluZycpOwoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIC8vIGhhbmRsZSBwcmVmZXJyZWQtaW5zdGFsbCBwZXItcGFja2FnZSBjb25maWcKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15wcmVmZXJyZWQtaW5zdGFsbFwuKC4rKS8nLCAkc2V0dGluZ0tleSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpc3QoJHZhbGlkYXRvcikgPSAkdW5pcXVlQ29uZmlnVmFsdWVzWydwcmVmZXJyZWQtaW5zdGFsbCddOwogICAgICAgICAgICBpZiAoISR2YWxpZGF0b3IoJHZhbHVlc1swXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignSW52YWxpZCB2YWx1ZSBmb3IgJy4kc2V0dGluZ0tleS4nLiBTaG91bGQgYmUgb25lIG9mOiBhdXRvLCBzb3VyY2UsIG9yIGRpc3QnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSwgJHZhbHVlc1swXSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBwcm9wZXJ0aWVzCiAgICAgICAgJHVuaXF1ZVByb3BzID0gYXJyYXkoCiAgICAgICAgICAgICduYW1lJyA9PiBhcnJheSgnaXNfc3RyaW5nJywgZnVuY3Rpb24gKCR2YWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsOwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgJ3R5cGUnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnZGVzY3JpcHRpb24nID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAnaG9tZXBhZ2UnID0+IGFycmF5KCdpc19zdHJpbmcnLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWw7CiAgICAgICAgICAgIH0pLAogICAgICAgICAgICAndmVyc2lvbicgPT4gYXJyYXkoJ2lzX3N0cmluZycsIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbDsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgICdtaW5pbXVtLXN0YWJpbGl0eScgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc3NldChCYXNlUGFja2FnZTo6JHN0YWJpbGl0aWVzW1ZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkdmFsKV0pOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZlcnNpb25QYXJzZXI6Om5vcm1hbGl6ZVN0YWJpbGl0eSgkdmFsKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdwcmVmZXItc3RhYmxlJyA9PiBhcnJheSgkYm9vbGVhblZhbGlkYXRvciwgJGJvb2xlYW5Ob3JtYWxpemVyKSwKICAgICAgICApOwogICAgICAgICRtdWx0aVByb3BzID0gYXJyYXkoCiAgICAgICAgICAgICdrZXl3b3JkcycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoJHZhbHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR2YWxzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2FycmF5IGV4cGVjdGVkJzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmFsczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICksCiAgICAgICAgICAgICdsaWNlbnNlJyA9PiBhcnJheSgKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkdmFscykgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHZhbHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYXJyYXkgZXhwZWN0ZWQnOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR2YWxzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWxzOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKSwKICAgICAgICApOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2dsb2JhbCcpICYmIChpc3NldCgkdW5pcXVlUHJvcHNbJHNldHRpbmdLZXldKSB8fCBpc3NldCgkbXVsdGlQcm9wc1skc2V0dGluZ0tleV0pIHx8IHN0cnBvcygkc2V0dGluZ0tleSwgJ2V4dHJhLicpID09PSAwKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlICcuJHNldHRpbmdLZXkuJyBwcm9wZXJ0eSBjYW4gbm90IGJlIHNldCBpbiB0aGUgZ2xvYmFsIGNvbmZpZy5qc29uIGZpbGUuIFVzZSBgY29tcG9zZXIgZ2xvYmFsIGNvbmZpZ2AgdG8gYXBwbHkgY2hhbmdlcyB0byB0aGUgZ2xvYmFsIGNvbXBvc2VyLmpzb24nKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpICYmIChpc3NldCgkdW5pcXVlUHJvcHNbJHNldHRpbmdLZXldKSB8fCBpc3NldCgkbXVsdGlQcm9wc1skc2V0dGluZ0tleV0pKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVQcm9wZXJ0eSgkc2V0dGluZ0tleSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCR1bmlxdWVQcm9wc1skc2V0dGluZ0tleV0pKSB7CiAgICAgICAgICAgICR0aGlzLT5oYW5kbGVTaW5nbGVWYWx1ZSgkc2V0dGluZ0tleSwgJHVuaXF1ZVByb3BzWyRzZXR0aW5nS2V5XSwgJHZhbHVlcywgJ2FkZFByb3BlcnR5Jyk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRtdWx0aVByb3BzWyRzZXR0aW5nS2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPmhhbmRsZU11bHRpVmFsdWUoJHNldHRpbmdLZXksICRtdWx0aVByb3BzWyRzZXR0aW5nS2V5XSwgJHZhbHVlcywgJ2FkZFByb3BlcnR5Jyk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSByZXBvc2l0b3JpZXMKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15yZXBvcz8oPzppdG9yaWVzKT9cLiguKykvJywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZVJlcG9zaXRvcnkoJG1hdGNoZXNbMV0pOwoKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoMiA9PT0gY291bnQoJHZhbHVlcykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZFJlcG9zaXRvcnkoJG1hdGNoZXNbMV0sIGFycmF5KAogICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkdmFsdWVzWzBdLAogICAgICAgICAgICAgICAgICAgICd1cmwnID0+ICR2YWx1ZXNbMV0sCiAgICAgICAgICAgICAgICApLCAkaW5wdXQtPmdldE9wdGlvbignYXBwZW5kJykpOwoKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoMSA9PT0gY291bnQoJHZhbHVlcykpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IHN0cnRvbG93ZXIoJHZhbHVlc1swXSk7CiAgICAgICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJGJvb2xlYW5WYWxpZGF0b3IoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGJvb2xlYW5Ob3JtYWxpemVyKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkUmVwb3NpdG9yeSgkbWF0Y2hlc1sxXSwgZmFsc2UsICRpbnB1dC0+Z2V0T3B0aW9uKCdhcHBlbmQnKSk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHZhbHVlc1swXSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkUmVwb3NpdG9yeSgkbWF0Y2hlc1sxXSwgJHZhbHVlLCAkaW5wdXQtPmdldE9wdGlvbignYXBwZW5kJykpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdZb3UgbXVzdCBwYXNzIHRoZSB0eXBlIGFuZCBhIHVybC4gRXhhbXBsZTogcGhwIGNvbXBvc2VyLnBoYXIgY29uZmlnIHJlcG9zaXRvcmllcy5mb28gdmNzIGh0dHBzOi8vYmFyLmNvbScpOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIGV4dHJhCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eZXh0cmFcLiguKykvJywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPnJlbW92ZVByb3BlcnR5KCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZhbHVlID0gJHZhbHVlc1swXTsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdqc29uJykpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHZhbHVlKTsKICAgICAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbWVyZ2UnKSkgewogICAgICAgICAgICAgICAgICAgICRjdXJyZW50VmFsdWUgPSAkdGhpcy0+Y29uZmlnRmlsZS0+cmVhZCgpOwogICAgICAgICAgICAgICAgICAgICRiaXRzID0gZXhwbG9kZSgnLicsICRzZXR0aW5nS2V5KTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkYml0cyBhcyAkYml0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjdXJyZW50VmFsdWUgPSBpc3NldCgkY3VycmVudFZhbHVlWyRiaXRdKSA/ICRjdXJyZW50VmFsdWVbJGJpdF0gOiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJGN1cnJlbnRWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gYXJyYXlfbWVyZ2UoJGN1cnJlbnRWYWx1ZSwgJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkUHJvcGVydHkoJHNldHRpbmdLZXksICR2YWx1ZSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBzdWdnZXN0CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9ec3VnZ2VzdFwuKC4rKS8nLCAkc2V0dGluZ0tleSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlUHJvcGVydHkoJHNldHRpbmdLZXkpOwoKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5hZGRQcm9wZXJ0eSgkc2V0dGluZ0tleSwgaW1wbG9kZSgnICcsICR2YWx1ZXMpKTsKCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlIHVuc2V0dGluZyBleHRyYS9zdWdnZXN0CiAgICAgICAgaWYgKGluX2FycmF5KCRzZXR0aW5nS2V5LCBhcnJheSgnc3VnZ2VzdCcsICdleHRyYScpLCB0cnVlKSAmJiAkaW5wdXQtPmdldE9wdGlvbigndW5zZXQnKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVQcm9wZXJ0eSgkc2V0dGluZ0tleSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBwbGF0Zm9ybQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXnBsYXRmb3JtXC4oLispLycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRzZXR0aW5nS2V5KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSwgJHZhbHVlc1swXSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSB1bnNldHRpbmcgcGxhdGZvcm0KICAgICAgICBpZiAoJHNldHRpbmdLZXkgPT09ICdwbGF0Zm9ybScgJiYgJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkc2V0dGluZ0tleSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBhdXRoCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKGJpdGJ1Y2tldC1vYXV0aHxnaXRodWItb2F1dGh8Z2l0bGFiLW9hdXRofGdpdGxhYi10b2tlbnxodHRwLWJhc2ljfGJlYXJlcilcLiguKykvJywgJHNldHRpbmdLZXksICRtYXRjaGVzKSkgewogICAgICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3Vuc2V0JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hdXRoQ29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbWF0Y2hlc1sxXSA9PT0gJ2JpdGJ1Y2tldC1vYXV0aCcpIHsKICAgICAgICAgICAgICAgIGlmICgyICE9PSBjb3VudCgkdmFsdWVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRXhwZWN0ZWQgdHdvIGFyZ3VtZW50cyAoY29uc3VtZXIta2V5LCBjb25zdW1lci1zZWNyZXQpLCBnb3QgJy5jb3VudCgkdmFsdWVzKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVDb25maWdTZXR0aW5nKCRtYXRjaGVzWzFdLicuJy4kbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXV0aENvbmZpZ1NvdXJjZS0+YWRkQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0sIGFycmF5KCdjb25zdW1lci1rZXknID0+ICR2YWx1ZXNbMF0sICdjb25zdW1lci1zZWNyZXQnID0+ICR2YWx1ZXNbMV0pKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRtYXRjaGVzWzFdID09PSAnZ2l0bGFiLXRva2VuJyAmJiAyID09PSBjb3VudCgkdmFsdWVzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0pOwogICAgICAgICAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UtPmFkZENvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdLCBhcnJheSgndXNlcm5hbWUnID0+ICR2YWx1ZXNbMF0sICd0b2tlbicgPT4gJHZhbHVlc1sxXSkpOwogICAgICAgICAgICB9IGVsc2VpZiAoaW5fYXJyYXkoJG1hdGNoZXNbMV0sIGFycmF5KCdnaXRodWItb2F1dGgnLCAnZ2l0bGFiLW9hdXRoJywgJ2dpdGxhYi10b2tlbicsICdiZWFyZXInKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIGlmICgxICE9PSBjb3VudCgkdmFsdWVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVG9vIG1hbnkgYXJndW1lbnRzLCBleHBlY3RlZCBvbmx5IG9uZSB0b2tlbicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0pOwogICAgICAgICAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UtPmFkZENvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdLCAkdmFsdWVzWzBdKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRtYXRjaGVzWzFdID09PSAnaHR0cC1iYXNpYycpIHsKICAgICAgICAgICAgICAgIGlmICgyICE9PSBjb3VudCgkdmFsdWVzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRXhwZWN0ZWQgdHdvIGFyZ3VtZW50cyAodXNlcm5hbWUsIHBhc3N3b3JkKSwgZ290ICcuY291bnQoJHZhbHVlcykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmNvbmZpZ1NvdXJjZS0+cmVtb3ZlQ29uZmlnU2V0dGluZygkbWF0Y2hlc1sxXS4nLicuJG1hdGNoZXNbMl0pOwogICAgICAgICAgICAgICAgJHRoaXMtPmF1dGhDb25maWdTb3VyY2UtPmFkZENvbmZpZ1NldHRpbmcoJG1hdGNoZXNbMV0uJy4nLiRtYXRjaGVzWzJdLCBhcnJheSgndXNlcm5hbWUnID0+ICR2YWx1ZXNbMF0sICdwYXNzd29yZCcgPT4gJHZhbHVlc1sxXSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBzY3JpcHQKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15zY3JpcHRzXC4oLispLycsICRzZXR0aW5nS2V5LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1bnNldCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uZmlnU291cmNlLT5yZW1vdmVQcm9wZXJ0eSgkc2V0dGluZ0tleSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5jb25maWdTb3VyY2UtPmFkZFByb3BlcnR5KCRzZXR0aW5nS2V5LCBjb3VudCgkdmFsdWVzKSA+IDEgPyAkdmFsdWVzIDogJHZhbHVlc1swXSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdTZXR0aW5nICcuJHNldHRpbmdLZXkuJyBkb2VzIG5vdCBleGlzdCBvciBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgY29tbWFuZCcpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVTaW5nbGVWYWx1ZSgka2V5LCBhcnJheSAkY2FsbGJhY2tzLCBhcnJheSAkdmFsdWVzLCAkbWV0aG9kKQogICAgewogICAgICAgIGxpc3QoJHZhbGlkYXRvciwgJG5vcm1hbGl6ZXIpID0gJGNhbGxiYWNrczsKICAgICAgICBpZiAoMSAhPT0gY291bnQoJHZhbHVlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdZb3UgY2FuIG9ubHkgcGFzcyBvbmUgdmFsdWUuIEV4YW1wbGU6IHBocCBjb21wb3Nlci5waGFyIGNvbmZpZyBwcm9jZXNzLXRpbWVvdXQgMzAwJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSAhPT0gJHZhbGlkYXRpb24gPSAkdmFsaWRhdG9yKCR2YWx1ZXNbMF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJyIlcyIgaXMgYW4gaW52YWxpZCB2YWx1ZScuKCR2YWxpZGF0aW9uID8gJyAoJy4kdmFsaWRhdGlvbi4nKScgOiAnJyksCiAgICAgICAgICAgICAgICAkdmFsdWVzWzBdCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJG5vcm1hbGl6ZWRWYWx1ZSA9ICRub3JtYWxpemVyKCR2YWx1ZXNbMF0pOwoKICAgICAgICBpZiAoJGtleSA9PT0gJ2Rpc2FibGUtdGxzJykgewogICAgICAgICAgICBpZiAoISRub3JtYWxpemVkVmFsdWUgJiYgJHRoaXMtPmNvbmZpZy0+Z2V0KCdkaXNhYmxlLXRscycpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Z2V0SU8oKS0+d3JpdGVFcnJvcignPGluZm8+WW91IGFyZSBub3cgcnVubmluZyBDb21wb3NlciB3aXRoIFNTTC9UTFMgcHJvdGVjdGlvbiBlbmFibGVkLjwvaW5mbz4nKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRub3JtYWxpemVkVmFsdWUgJiYgISR0aGlzLT5jb25maWctPmdldCgnZGlzYWJsZS10bHMnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgbm93IHJ1bm5pbmcgQ29tcG9zZXIgd2l0aCBTU0wvVExTIHByb3RlY3Rpb24gZGlzYWJsZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoYXJyYXkoJHRoaXMtPmNvbmZpZ1NvdXJjZSwgJG1ldGhvZCksICRrZXksICRub3JtYWxpemVkVmFsdWUpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYW5kbGVNdWx0aVZhbHVlKCRrZXksIGFycmF5ICRjYWxsYmFja3MsIGFycmF5ICR2YWx1ZXMsICRtZXRob2QpCiAgICB7CiAgICAgICAgbGlzdCgkdmFsaWRhdG9yLCAkbm9ybWFsaXplcikgPSAkY2FsbGJhY2tzOwogICAgICAgIGlmICh0cnVlICE9PSAkdmFsaWRhdGlvbiA9ICR2YWxpZGF0b3IoJHZhbHVlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnJXMgaXMgYW4gaW52YWxpZCB2YWx1ZScuKCR2YWxpZGF0aW9uID8gJyAoJy4kdmFsaWRhdGlvbi4nKScgOiAnJyksCiAgICAgICAgICAgICAgICBqc29uX2VuY29kZSgkdmFsdWVzKQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuYyhhcnJheSgkdGhpcy0+Y29uZmlnU291cmNlLCAkbWV0aG9kKSwgJGtleSwgJG5vcm1hbGl6ZXIoJHZhbHVlcykpOwogICAgfQoKICAgIC8qKgogICAgICogRGlzcGxheSB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgaW4gYSBwcmV0dHkgZm9ybWF0dGVkIHdheQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgJGNvbnRlbnRzCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICRyYXdDb250ZW50cwogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICRrCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBsaXN0Q29uZmlndXJhdGlvbihhcnJheSAkY29udGVudHMsIGFycmF5ICRyYXdDb250ZW50cywgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRrID0gbnVsbCkKICAgIHsKICAgICAgICAkb3JpZ0sgPSAkazsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICBmb3JlYWNoICgkY29udGVudHMgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCRrID09PSBudWxsICYmICFpbl9hcnJheSgka2V5LCBhcnJheSgnY29uZmlnJywgJ3JlcG9zaXRvcmllcycpKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyYXdWYWwgPSBpc3NldCgkcmF3Q29udGVudHNbJGtleV0pID8gJHJhd0NvbnRlbnRzWyRrZXldIDogbnVsbDsKCiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdmFsdWUpICYmICghaXNfbnVtZXJpYyhrZXkoJHZhbHVlKSkgfHwgKCRrZXkgPT09ICdyZXBvc2l0b3JpZXMnICYmIG51bGwgPT09ICRrKSkpIHsKICAgICAgICAgICAgICAgICRrIC49IHByZWdfcmVwbGFjZSgne15jb25maWdcLn0nLCAnJywgJGtleSAuICcuJyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+bGlzdENvbmZpZ3VyYXRpb24oJHZhbHVlLCAkcmF3VmFsLCAkb3V0cHV0LCAkayk7CiAgICAgICAgICAgICAgICAkayA9ICRvcmlnSzsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IGFycmF5X21hcChmdW5jdGlvbiAoJHZhbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc19hcnJheSgkdmFsKSA/IGpzb25fZW5jb2RlKCR2YWwpIDogJHZhbDsKICAgICAgICAgICAgICAgIH0sICR2YWx1ZSk7CgogICAgICAgICAgICAgICAgJHZhbHVlID0gJ1snLmltcGxvZGUoJywgJywgJHZhbHVlKS4nXSc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpc19ib29sKCR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IHZhcl9leHBvcnQoJHZhbHVlLCB0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkcmF3VmFsKSAmJiAkcmF3VmFsICE9ICR2YWx1ZSkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZSgnWzxjb21tZW50PicgLiAkayAuICRrZXkgLiAnPC9jb21tZW50Pl0gPGluZm8+JyAuICRyYXdWYWwgLiAnICgnIC4gJHZhbHVlIC4gJyk8L2luZm8+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OlFVSUVUKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGUoJ1s8Y29tbWVudD4nIC4gJGsgLiAka2V5IC4gJzwvY29tbWVudD5dIDxpbmZvPicgLiAkdmFsdWUgLiAnPC9pbmZvPicsIHRydWUsIElPSW50ZXJmYWNlOjpRVUlFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXENvbmZpZzsKdXNlIENvbXBvc2VyXENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xOdWxsSU87CnVzZSBDb21wb3NlclxQbHVnaW5cUHJlQ29tbWFuZFJ1bkV2ZW50Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcVGFibGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CgovKioKICogQmFzZSBjbGFzcyBmb3IgQ29tcG9zZXIgY29tbWFuZHMKICoKICogQG1ldGhvZCBBcHBsaWNhdGlvbiBnZXRBcHBsaWNhdGlvbigpCiAqCiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wbGFicy5jb20+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBCYXNlQ29tbWFuZCBleHRlbmRzIENvbW1hbmQKewogICAgLyoqCiAgICAgKiBAdmFyIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSAkY29tcG9zZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGlvOwoKICAgIC8qKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAkcmVxdWlyZWQKICAgICAqIEBwYXJhbSAgYm9vbHxudWxsICAgICAgICAgJGRpc2FibGVQbHVnaW5zCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbXBvc2VyKCRyZXF1aXJlZCA9IHRydWUsICRkaXNhYmxlUGx1Z2lucyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21wb3NlcikgewogICAgICAgICAgICAkYXBwbGljYXRpb24gPSAkdGhpcy0+Z2V0QXBwbGljYXRpb24oKTsKICAgICAgICAgICAgaWYgKCRhcHBsaWNhdGlvbiBpbnN0YW5jZW9mIEFwcGxpY2F0aW9uKSB7CiAgICAgICAgICAgICAgICAvKiBAdmFyICRhcHBsaWNhdGlvbiAgICBBcHBsaWNhdGlvbiAqLwogICAgICAgICAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gJGFwcGxpY2F0aW9uLT5nZXRDb21wb3NlcigkcmVxdWlyZWQsICRkaXNhYmxlUGx1Z2lucyk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkcmVxdWlyZWQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAnQ291bGQgbm90IGNyZWF0ZSBhIENvbXBvc2VyXENvbXBvc2VyIGluc3RhbmNlLCB5b3UgbXVzdCBpbmplY3QgJy4KICAgICAgICAgICAgICAgICAgICAnb25lIGlmIHRoaXMgY29tbWFuZCBpcyBub3QgdXNlZCB3aXRoIGEgQ29tcG9zZXJcQ29uc29sZVxBcHBsaWNhdGlvbiBpbnN0YW5jZScKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ29tcG9zZXIgJGNvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21wb3NlcihDb21wb3NlciAkY29tcG9zZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gJGNvbXBvc2VyOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgY2FjaGVkIGNvbXBvc2VyIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNldENvbXBvc2VyKCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcG9zZXIgPSBudWxsOwogICAgICAgICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5yZXNldENvbXBvc2VyKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGlzIGNvbW1hbmQgaXMgbWVhbnQgdG8gY2FsbCBhbm90aGVyIGNvbW1hbmQuCiAgICAgKgogICAgICogVGhpcyBpcyBtYWlubHkgbmVlZGVkIHRvIGF2b2lkIGR1cGxpY2F0ZWQgd2FybmluZ3MgbWVzc2FnZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Byb3h5Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBJT0ludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SU8oKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+aW8pIHsKICAgICAgICAgICAgJGFwcGxpY2F0aW9uID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCk7CiAgICAgICAgICAgIGlmICgkYXBwbGljYXRpb24gaW5zdGFuY2VvZiBBcHBsaWNhdGlvbikgewogICAgICAgICAgICAgICAgLyogQHZhciAkYXBwbGljYXRpb24gICAgQXBwbGljYXRpb24gKi8KICAgICAgICAgICAgICAgICR0aGlzLT5pbyA9ICRhcHBsaWNhdGlvbi0+Z2V0SU8oKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbyA9IG5ldyBOdWxsSU8oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAkaW8KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElPKElPSW50ZXJmYWNlICRpbykKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgLy8gaW5pdGlhbGl6ZSBhIHBsdWdpbi1lbmFibGVkIENvbXBvc2VyIGluc3RhbmNlLCBlaXRoZXIgbG9jYWwgb3IgZ2xvYmFsCiAgICAgICAgJGRpc2FibGVQbHVnaW5zID0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpOwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcihmYWxzZSwgJGRpc2FibGVQbHVnaW5zKTsKICAgICAgICBpZiAobnVsbCA9PT0gJGNvbXBvc2VyKSB7CiAgICAgICAgICAgICRjb21wb3NlciA9IEZhY3Rvcnk6OmNyZWF0ZUdsb2JhbCgkdGhpcy0+Z2V0SU8oKSwgJGRpc2FibGVQbHVnaW5zKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRjb21wb3NlcikgewogICAgICAgICAgICAkcHJlQ29tbWFuZFJ1bkV2ZW50ID0gbmV3IFByZUNvbW1hbmRSdW5FdmVudChQbHVnaW5FdmVudHM6OlBSRV9DT01NQU5EX1JVTiwgJGlucHV0LCAkdGhpcy0+Z2V0TmFtZSgpKTsKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJHByZUNvbW1hbmRSdW5FdmVudC0+Z2V0TmFtZSgpLCAkcHJlQ29tbWFuZFJ1bkV2ZW50KTsKICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbihhcnJheSgnLS1uby1hbnNpJykpICYmICRpbnB1dC0+aGFzT3B0aW9uKCduby1wcm9ncmVzcycpKSB7CiAgICAgICAgICAgICRpbnB1dC0+c2V0T3B0aW9uKCduby1wcm9ncmVzcycsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50Ojppbml0aWFsaXplKCRpbnB1dCwgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHByZWZlclNvdXJjZSBhbmQgcHJlZmVyRGlzdCB2YWx1ZXMgYmFzZWQgb24gdGhlIGNvbmZpZ3VyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIENvbmZpZyAgICAgICAgICRjb25maWcKICAgICAqIEBwYXJhbSBJbnB1dEludGVyZmFjZSAkaW5wdXQKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAka2VlcFZjc1JlcXVpcmVzUHJlZmVyU291cmNlCiAgICAgKgogICAgICogQHJldHVybiBib29sW10gQW4gYXJyYXkgY29tcG9zZWQgb2YgdGhlIHByZWZlclNvdXJjZSBhbmQgcHJlZmVyRGlzdCB2YWx1ZXMKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFByZWZlcnJlZEluc3RhbGxPcHRpb25zKENvbmZpZyAkY29uZmlnLCBJbnB1dEludGVyZmFjZSAkaW5wdXQsICRrZWVwVmNzUmVxdWlyZXNQcmVmZXJTb3VyY2UgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcHJlZmVyU291cmNlID0gZmFsc2U7CiAgICAgICAgJHByZWZlckRpc3QgPSBmYWxzZTsKCiAgICAgICAgc3dpdGNoICgkY29uZmlnLT5nZXQoJ3ByZWZlcnJlZC1pbnN0YWxsJykpIHsKICAgICAgICAgICAgY2FzZSAnc291cmNlJzoKICAgICAgICAgICAgICAgICRwcmVmZXJTb3VyY2UgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2Rpc3QnOgogICAgICAgICAgICAgICAgJHByZWZlckRpc3QgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2F1dG8nOgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gbm9vcAogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1zb3VyY2UnKSB8fCAkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLWRpc3QnKSB8fCAoJGtlZXBWY3NSZXF1aXJlc1ByZWZlclNvdXJjZSAmJiAkaW5wdXQtPmhhc09wdGlvbigna2VlcC12Y3MnKSAmJiAkaW5wdXQtPmdldE9wdGlvbigna2VlcC12Y3MnKSkpIHsKICAgICAgICAgICAgJHByZWZlclNvdXJjZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItc291cmNlJykgfHwgKCRrZWVwVmNzUmVxdWlyZXNQcmVmZXJTb3VyY2UgJiYgJGlucHV0LT5oYXNPcHRpb24oJ2tlZXAtdmNzJykgJiYgJGlucHV0LT5nZXRPcHRpb24oJ2tlZXAtdmNzJykpOwogICAgICAgICAgICAkcHJlZmVyRGlzdCA9IChib29sKSAkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLWRpc3QnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgkcHJlZmVyU291cmNlLCAkcHJlZmVyRGlzdCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZvcm1hdFJlcXVpcmVtZW50cyhhcnJheSAkcmVxdWlyZW1lbnRzKQogICAgewogICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5ub3JtYWxpemVSZXF1aXJlbWVudHMoJHJlcXVpcmVtZW50cyk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcmVxdWlyZW1lbnQpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdPcHRpb24gJy4kcmVxdWlyZW1lbnRbJ25hbWUnXSAuJyBpcyBtaXNzaW5nIGEgdmVyc2lvbiBjb25zdHJhaW50LCB1c2UgZS5nLiAnLiRyZXF1aXJlbWVudFsnbmFtZSddLic6XjEuMCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXF1aXJlc1skcmVxdWlyZW1lbnRbJ25hbWUnXV0gPSAkcmVxdWlyZW1lbnRbJ3ZlcnNpb24nXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVxdWlyZXM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIG5vcm1hbGl6ZVJlcXVpcmVtZW50cyhhcnJheSAkcmVxdWlyZW1lbnRzKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwoKICAgICAgICByZXR1cm4gJHBhcnNlci0+cGFyc2VOYW1lVmVyc2lvblBhaXJzKCRyZXF1aXJlbWVudHMpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZW5kZXJUYWJsZShhcnJheSAkdGFibGUsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRyZW5kZXJlciA9IG5ldyBUYWJsZSgkb3V0cHV0KTsKICAgICAgICAkcmVuZGVyZXItPnNldFN0eWxlKCdjb21wYWN0Jyk7CiAgICAgICAgJHJlbmRlcmVyU3R5bGUgPSAkcmVuZGVyZXItPmdldFN0eWxlKCk7CiAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJHJlbmRlcmVyU3R5bGUsICdzZXRWZXJ0aWNhbEJvcmRlckNoYXJzJykpIHsKICAgICAgICAgICAgJHJlbmRlcmVyU3R5bGUtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcnMoJycpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZW5kZXJlclN0eWxlLT5zZXRWZXJ0aWNhbEJvcmRlckNoYXIoJycpOwogICAgICAgIH0KICAgICAgICAkcmVuZGVyZXJTdHlsZS0+c2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoJyVzICAnKTsKICAgICAgICAkcmVuZGVyZXItPnNldFJvd3MoJHRhYmxlKS0+cmVuZGVyKCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb25maWdcSnNvbkNvbmZpZ1NvdXJjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxKc29uXEpzb25GaWxlOwp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKCi8qKgogKiBAYXV0aG9yIFBpZXJyZSBkdSBQbGVzc2lzIDxwZHBsZXNAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBSZW1vdmVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdyZW1vdmUnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdSZW1vdmVzIGEgcGFja2FnZSBmcm9tIHRoZSByZXF1aXJlIG9yIHJlcXVpcmUtZGV2LicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdwYWNrYWdlcycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQsICdQYWNrYWdlcyB0aGF0IHNob3VsZCBiZSByZW1vdmVkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JlbW92ZXMgYSBwYWNrYWdlIGZyb20gdGhlIHJlcXVpcmUtZGV2IHNlY3Rpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RyeS1ydW4nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ091dHB1dHMgdGhlIG9wZXJhdGlvbnMgYnV0IHdpbGwgbm90IGV4ZWN1dGUgYW55dGhpbmcgKGltcGxpY2l0bHkgZW5hYmxlcyAtLXZlcmJvc2UpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1wcm9ncmVzcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IG91dHB1dCBkb3dubG9hZCBwcm9ncmVzcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tdXBkYXRlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyB0aGUgYXV0b21hdGljIHVwZGF0ZSBvZiB0aGUgZGVwZW5kZW5jaWVzIChpbXBsaWVzIC0tbm8taW5zdGFsbCkuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXAgdGhlIGluc3RhbGwgc3RlcCBhZnRlciB1cGRhdGluZyB0aGUgY29tcG9zZXIubG9jayBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwcyB0aGUgZXhlY3V0aW9uIG9mIGFsbCBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbiBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUtbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSdW4gdGhlIGRlcGVuZGVuY3kgdXBkYXRlIHdpdGggdGhlIC0tbm8tZGV2IG9wdGlvbi4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJywgJ3cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0FsbG93cyBpbmhlcml0ZWQgZGVwZW5kZW5jaWVzIHRvIGJlIHVwZGF0ZWQgd2l0aCBleHBsaWNpdCBkZXBlbmRlbmNpZXMuIChEZXByZWNyYXRlZCwgaXMgbm93IGRlZmF1bHQgYmVoYXZpb3IpJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3VwZGF0ZS13aXRoLWFsbC1kZXBlbmRlbmNpZXMnLCAnVycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxsb3dzIGFsbCBpbmhlcml0ZWQgZGVwZW5kZW5jaWVzIHRvIGJlIHVwZGF0ZWQsIGluY2x1ZGluZyB0aG9zZSB0aGF0IGFyZSByb290IHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignd2l0aC1hbGwtZGVwZW5kZW5jaWVzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBbGlhcyBmb3IgLS11cGRhdGUtd2l0aC1hbGwtZGVwZW5kZW5jaWVzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXVwZGF0ZS13aXRoLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG9lcyBub3QgYWxsb3cgaW5oZXJpdGVkIGRlcGVuZGVuY2llcyB0byBiZSB1cGRhdGVkIHdpdGggZXhwbGljaXQgZGVwZW5kZW5jaWVzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1bnVzZWQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JlbW92ZSBhbGwgcGFja2FnZXMgd2hpY2ggYXJlIGxvY2tlZCBidXQgbm90IHJlcXVpcmVkIGJ5IGFueSBvdGhlciBwYWNrYWdlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIGEgc3BlY2lmaWMgcGxhdGZvcm0gcmVxdWlyZW1lbnQgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJywgJ28nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ09wdGltaXplIGF1dG9sb2FkZXIgZHVyaW5nIGF1dG9sb2FkZXIgZHVtcCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJywgJ2EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0F1dG9sb2FkIGNsYXNzZXMgZnJvbSB0aGUgY2xhc3NtYXAgb25seS4gSW1wbGljaXRseSBlbmFibGVzIGAtLW9wdGltaXplLWF1dG9sb2FkZXJgLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1VzZSBBUEN1IHRvIGNhY2hlIGZvdW5kL25vdC1mb3VuZCBjbGFzc2VzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXItcHJlZml4JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVELCAnVXNlIGEgY3VzdG9tIHByZWZpeCBmb3IgdGhlIEFQQ3UgYXV0b2xvYWRlciBjYWNoZS4gSW1wbGljaXRseSBlbmFibGVzIC0tYXBjdS1hdXRvbG9hZGVyJyksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApUaGUgPGluZm8+cmVtb3ZlPC9pbmZvPiBjb21tYW5kIHJlbW92ZXMgYSBwYWNrYWdlIGZyb20gdGhlIGN1cnJlbnQKbGlzdCBvZiBpbnN0YWxsZWQgcGFja2FnZXMKCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHJlbW92ZTwvaW5mbz4KClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3JlbW92ZQpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW50ZXJhY3QoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3VudXNlZCcpKSB7CiAgICAgICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3NlcigpOwogICAgICAgICAgICAkbG9ja2VyID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKTsKICAgICAgICAgICAgaWYgKCEkbG9ja2VyLT5pc0xvY2tlZCgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignQSB2YWxpZCBjb21wb3Nlci5sb2NrIGZpbGUgaXMgcmVxdWlyZWQgdG8gcnVuIHRoaXMgY29tbWFuZCB3aXRoIC0tdW51c2VkJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRsb2NrZWRQYWNrYWdlcyA9ICRsb2NrZXItPmdldExvY2tlZFJlcG9zaXRvcnkoKS0+Z2V0UGFja2FnZXMoKTsKCiAgICAgICAgICAgICRyZXF1aXJlZCA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21lcmdlKCRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRSZXF1aXJlcygpLCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0RGV2UmVxdWlyZXMoKSkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRyZXF1aXJlZFskbGluay0+Z2V0VGFyZ2V0KCldID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgJGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUGFja2FnZXMgYXMgJGluZGV4ID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRyZXF1aXJlZFskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXF1aXJlZFskbGluay0+Z2V0VGFyZ2V0KCldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkbG9ja2VkUGFja2FnZXNbJGluZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSB3aGlsZSAoJGZvdW5kKTsKCiAgICAgICAgICAgICR1bnVzZWQgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICR1bnVzZWRbXSA9ICRwYWNrYWdlLT5nZXROYW1lKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGlucHV0LT5zZXRBcmd1bWVudCgncGFja2FnZXMnLCBhcnJheV9tZXJnZSgkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpLCAkdW51c2VkKSk7CgogICAgICAgICAgICBpZiAoISRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZUVycm9yKCc8aW5mbz5ObyB1bnVzZWQgcGFja2FnZXMgdG8gcmVtb3ZlPC9pbmZvPicpOwogICAgICAgICAgICAgICAgJHRoaXMtPnNldENvZGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkcGFja2FnZXMgPSAkaW5wdXQtPmdldEFyZ3VtZW50KCdwYWNrYWdlcycpOwogICAgICAgICRwYWNrYWdlcyA9IGFycmF5X21hcCgnc3RydG9sb3dlcicsICRwYWNrYWdlcyk7CgogICAgICAgICRmaWxlID0gRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCk7CgogICAgICAgICRqc29uRmlsZSA9IG5ldyBKc29uRmlsZSgkZmlsZSk7CiAgICAgICAgJGNvbXBvc2VyID0gJGpzb25GaWxlLT5yZWFkKCk7CiAgICAgICAgJGNvbXBvc2VyQmFja3VwID0gZmlsZV9nZXRfY29udGVudHMoJGpzb25GaWxlLT5nZXRQYXRoKCkpOwoKICAgICAgICAkanNvbiA9IG5ldyBKc29uQ29uZmlnU291cmNlKCRqc29uRmlsZSk7CgogICAgICAgICR0eXBlID0gJGlucHV0LT5nZXRPcHRpb24oJ2RldicpID8gJ3JlcXVpcmUtZGV2JyA6ICdyZXF1aXJlJzsKICAgICAgICAkYWx0VHlwZSA9ICEkaW5wdXQtPmdldE9wdGlvbignZGV2JykgPyAncmVxdWlyZS1kZXYnIDogJ3JlcXVpcmUnOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3VwZGF0ZS13aXRoLWRlcGVuZGVuY2llcycpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gInVwZGF0ZS13aXRoLWRlcGVuZGVuY2llcyIuIFRoaXMgaXMgbm93IGRlZmF1bHQgYmVoYXZpb3VyLiBUaGUgLS1uby11cGRhdGUtd2l0aC1kZXBlbmRlbmNpZXMgb3B0aW9uIGNhbiBiZSB1c2VkIHRvIHJlbW92ZSBhIHBhY2thZ2Ugd2l0aG91dCBpdHMgZGVwZW5kZW5jaWVzLjwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgIC8vIG1ha2Ugc3VyZSBuYW1lIGNoZWNrcyBhcmUgZG9uZSBjYXNlIGluc2Vuc2l0aXZlbHkKICAgICAgICBmb3JlYWNoIChhcnJheSgncmVxdWlyZScsICdyZXF1aXJlLWRldicpIGFzICRsaW5rVHlwZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyWyRsaW5rVHlwZV0pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkY29tcG9zZXJbJGxpbmtUeXBlXSBhcyAkbmFtZSA9PiAkdmVyc2lvbikgewogICAgICAgICAgICAgICAgICAgICRjb21wb3NlclskbGlua1R5cGVdW3N0cnRvbG93ZXIoJG5hbWUpXSA9ICRuYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZHJ5UnVuID0gJGlucHV0LT5nZXRPcHRpb24oJ2RyeS1ydW4nKTsKICAgICAgICAkdG9SZW1vdmUgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGNvbXBvc2VyWyR0eXBlXVskcGFja2FnZV0pKSB7CiAgICAgICAgICAgICAgICBpZiAoJGRyeVJ1bikgewogICAgICAgICAgICAgICAgICAgICR0b1JlbW92ZVskdHlwZV1bXSA9ICRjb21wb3NlclskdHlwZV1bJHBhY2thZ2VdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkanNvbi0+cmVtb3ZlTGluaygkdHlwZSwgJGNvbXBvc2VyWyR0eXBlXVskcGFja2FnZV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGNvbXBvc2VyWyRhbHRUeXBlXVskcGFja2FnZV0pKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPicgLiAkY29tcG9zZXJbJGFsdFR5cGVdWyRwYWNrYWdlXSAuICcgY291bGQgbm90IGJlIGZvdW5kIGluICcgLiAkdHlwZSAuICcgYnV0IGl0IGlzIHByZXNlbnQgaW4gJyAuICRhbHRUeXBlIC4gJzwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgIGlmICgkaW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaW8tPmFza0NvbmZpcm1hdGlvbignRG8geW91IHdhbnQgdG8gcmVtb3ZlIGl0IGZyb20gJyAuICRhbHRUeXBlIC4gJyBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZHJ5UnVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9SZW1vdmVbJGFsdFR5cGVdW10gPSAkY29tcG9zZXJbJGFsdFR5cGVdWyRwYWNrYWdlXTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRqc29uLT5yZW1vdmVMaW5rKCRhbHRUeXBlLCAkY29tcG9zZXJbJGFsdFR5cGVdWyRwYWNrYWdlXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkY29tcG9zZXJbJHR5cGVdKSAmJiAkbWF0Y2hlcyA9IHByZWdfZ3JlcChCYXNlUGFja2FnZTo6cGFja2FnZU5hbWVUb1JlZ2V4cCgkcGFja2FnZSksIGFycmF5X2tleXMoJGNvbXBvc2VyWyR0eXBlXSkpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlcyBhcyAkbWF0Y2hlZFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGRyeVJ1bikgewogICAgICAgICAgICAgICAgICAgICAgICAkdG9SZW1vdmVbJHR5cGVdW10gPSAkbWF0Y2hlZFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGpzb24tPnJlbW92ZUxpbmsoJHR5cGUsICRtYXRjaGVkUGFja2FnZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJGNvbXBvc2VyWyRhbHRUeXBlXSkgJiYgJG1hdGNoZXMgPSBwcmVnX2dyZXAoQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhY2thZ2UpLCBhcnJheV9rZXlzKCRjb21wb3NlclskYWx0VHlwZV0pKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXMgYXMgJG1hdGNoZWRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nIC4gJG1hdGNoZWRQYWNrYWdlIC4gJyBjb3VsZCBub3QgYmUgZm91bmQgaW4gJyAuICR0eXBlIC4gJyBidXQgaXQgaXMgcHJlc2VudCBpbiAnIC4gJGFsdFR5cGUgLiAnPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgIGlmICgkaW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlvLT5hc2tDb25maXJtYXRpb24oJ0RvIHlvdSB3YW50IHRvIHJlbW92ZSBpdCBmcm9tICcgLiAkYWx0VHlwZSAuICcgWzxjb21tZW50PnllczwvY29tbWVudD5dPyAnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRkcnlSdW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9SZW1vdmVbJGFsdFR5cGVdW10gPSAkbWF0Y2hlZFBhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRqc29uLT5yZW1vdmVMaW5rKCRhbHRUeXBlLCAkbWF0Y2hlZFBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz4nLiRwYWNrYWdlLicgaXMgbm90IHJlcXVpcmVkIGluIHlvdXIgY29tcG9zZXIuanNvbiBhbmQgaGFzIG5vdCBiZWVuIHJlbW92ZWQ8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Jy4kZmlsZS4nIGhhcyBiZWVuIHVwZGF0ZWQ8L2luZm8+Jyk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tdXBkYXRlJykpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvLyBVcGRhdGUgcGFja2FnZXMKICAgICAgICAkdGhpcy0+cmVzZXRDb21wb3NlcigpOwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3Nlcih0cnVlLCAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpKTsKCiAgICAgICAgaWYgKCRkcnlSdW4pIHsKICAgICAgICAgICAgJHJvb3RQYWNrYWdlID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgICRsaW5rcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ3JlcXVpcmUnID0+ICRyb290UGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgICAgICdyZXF1aXJlLWRldicgPT4gJHJvb3RQYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpLAogICAgICAgICAgICApOwogICAgICAgICAgICBmb3JlYWNoICgkdG9SZW1vdmUgYXMgJHR5cGUgPT4gJG5hbWVzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmFtZXMgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkbGlua3NbJHR5cGVdWyRuYW1lXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJvb3RQYWNrYWdlLT5zZXRSZXF1aXJlcygkbGlua3NbJ3JlcXVpcmUnXSk7CiAgICAgICAgICAgICRyb290UGFja2FnZS0+c2V0RGV2UmVxdWlyZXMoJGxpbmtzWydyZXF1aXJlLWRldiddKTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3JlbW92ZScsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkaW5wdXQtPmdldE9wdGlvbignbm8tcHJvZ3Jlc3MnKSk7CgogICAgICAgICRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwoKICAgICAgICAkdXBkYXRlRGV2TW9kZSA9ICEkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLW5vLWRldicpOwogICAgICAgICRvcHRpbWl6ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJykgfHwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdvcHRpbWl6ZS1hdXRvbG9hZGVyJyk7CiAgICAgICAgJGF1dGhvcml0YXRpdmUgPSAkaW5wdXQtPmdldE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpIHx8ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScpOwogICAgICAgICRhcGN1UHJlZml4ID0gJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlci1wcmVmaXgnKTsKICAgICAgICAkYXBjdSA9ICRhcGN1UHJlZml4ICE9PSBudWxsIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKCdhcGN1LWF1dG9sb2FkZXInKSB8fCAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ2FwY3UtYXV0b2xvYWRlcicpOwoKICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQU19OT19ST09UX1JFUVVJUkU7CiAgICAgICAgJGZsYWdzID0gJyc7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1cGRhdGUtd2l0aC1hbGwtZGVwZW5kZW5jaWVzJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycpKSB7CiAgICAgICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtYWxsLWRlcGVuZGVuY2llcyc7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby11cGRhdGUtd2l0aC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX09OTFlfTElTVEVEOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtZGVwZW5kZW5jaWVzJzsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+UnVubmluZyBjb21wb3NlciB1cGRhdGUgJy5pbXBsb2RlKCcgJywgJHBhY2thZ2VzKS4kZmxhZ3MuJzwvaW5mbz4nKTsKCiAgICAgICAgJGlnbm9yZVBsYXRmb3JtUmVxcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycpID86ICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScpID86IGZhbHNlKTsKCiAgICAgICAgJGluc3RhbGwKICAgICAgICAgICAgLT5zZXRWZXJib3NlKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpCiAgICAgICAgICAgIC0+c2V0RGV2TW9kZSgkdXBkYXRlRGV2TW9kZSkKICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJG9wdGltaXplKQogICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSkKICAgICAgICAgICAgLT5zZXRBcGN1QXV0b2xvYWRlcigkYXBjdSwgJGFwY3VQcmVmaXgpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlKHRydWUpCiAgICAgICAgICAgIC0+c2V0SW5zdGFsbCghJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSkKICAgICAgICAgICAgLT5zZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcykKICAgICAgICAgICAgLT5zZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgICAgICAgICAtPnNldFJ1blNjcmlwdHMoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1zY3JpcHRzJykpCiAgICAgICAgICAgIC0+c2V0RHJ5UnVuKCRkcnlSdW4pCiAgICAgICAgOwoKICAgICAgICAvLyBpZiBubyBsb2NrIGlzIHByZXNlbnQsIHdlIGRvIG5vdCBkbyBhIHBhcnRpYWwgdXBkYXRlIGFzCiAgICAgICAgLy8gdGhpcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBJbnN0YWxsZXIKICAgICAgICBpZiAoJGNvbXBvc2VyLT5nZXRMb2NrZXIoKS0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAkaW5zdGFsbC0+c2V0VXBkYXRlQWxsb3dMaXN0KCRwYWNrYWdlcyk7CiAgICAgICAgfQoKICAgICAgICAkc3RhdHVzID0gJGluc3RhbGwtPnJ1bigpOwogICAgICAgIGlmICgkc3RhdHVzICE9PSAwKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiXG4iLic8ZXJyb3I+UmVtb3ZhbCBmYWlsZWQsIHJldmVydGluZyAnLiRmaWxlLicgdG8gaXRzIG9yaWdpbmFsIGNvbnRlbnQuPC9lcnJvcj4nKTsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGpzb25GaWxlLT5nZXRQYXRoKCksICRjb21wb3NlckJhY2t1cCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRkcnlSdW4pIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKS0+ZmluZFBhY2thZ2VzKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPlJlbW92YWwgZmFpbGVkLCAnLiRwYWNrYWdlLicgaXMgc3RpbGwgcHJlc2VudCwgaXQgbWF5IGJlIHJlcXVpcmVkIGJ5IGFub3RoZXIgcGFja2FnZS4gU2VlIGBjb21wb3NlciB3aHkgJy4kcGFja2FnZS4nYC48L2Vycm9yPicpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdGF0dXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgRGF2aWQgTmVpbHNlbiA8cGV0YWgucEBnbWFpbC5jb20+CiAqLwpjbGFzcyBDbGVhckNhY2hlQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnY2xlYXItY2FjaGUnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ2NsZWFyY2FjaGUnLCAnY2MnKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignQ2xlYXJzIGNvbXBvc2VyXCdzIGludGVybmFsIHBhY2thZ2UgY2FjaGUuJykKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz5jbGVhci1jYWNoZTwvaW5mbz4gZGVsZXRlcyBhbGwgY2FjaGVkIHBhY2thZ2VzIGZyb20gY29tcG9zZXIncwpjYWNoZSBkaXJlY3RvcnkuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNjbGVhci1jYWNoZS1jbGVhcmNhY2hlLWNjCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICAkY2FjaGVQYXRocyA9IGFycmF5KAogICAgICAgICAgICAnY2FjaGUtdmNzLWRpcicgPT4gJGNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJyksCiAgICAgICAgICAgICdjYWNoZS1yZXBvLWRpcicgPT4gJGNvbmZpZy0+Z2V0KCdjYWNoZS1yZXBvLWRpcicpLAogICAgICAgICAgICAnY2FjaGUtZmlsZXMtZGlyJyA9PiAkY29uZmlnLT5nZXQoJ2NhY2hlLWZpbGVzLWRpcicpLAogICAgICAgICAgICAnY2FjaGUtZGlyJyA9PiAkY29uZmlnLT5nZXQoJ2NhY2hlLWRpcicpLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKCRjYWNoZVBhdGhzIGFzICRrZXkgPT4gJGNhY2hlUGF0aCkgewogICAgICAgICAgICAkY2FjaGVQYXRoID0gcmVhbHBhdGgoJGNhY2hlUGF0aCk7CiAgICAgICAgICAgIGlmICghJGNhY2hlUGF0aCkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCI8aW5mbz5DYWNoZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QgKCRrZXkpOiAkY2FjaGVQYXRoPC9pbmZvPiIpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjYWNoZSA9IG5ldyBDYWNoZSgkaW8sICRjYWNoZVBhdGgpOwogICAgICAgICAgICAkY2FjaGUtPnNldFJlYWRPbmx5KCRjb25maWctPmdldCgnY2FjaGUtcmVhZC1vbmx5JykpOwogICAgICAgICAgICBpZiAoISRjYWNoZS0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiPGluZm8+Q2FjaGUgaXMgbm90IGVuYWJsZWQgKCRrZXkpOiAkY2FjaGVQYXRoPC9pbmZvPiIpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoIjxpbmZvPkNsZWFyaW5nIGNhY2hlICgka2V5KTogJGNhY2hlUGF0aDwvaW5mbz4iKTsKICAgICAgICAgICAgJGNhY2hlLT5jbGVhcigpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5BbGwgY2FjaGVzIGNsZWFyZWQuPC9pbmZvPicpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUm9vdFBhY2thZ2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZEFycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUm9vdFBhY2thZ2VSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJTdHlsZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQmFzZSBpbXBsZW1lbnRhdGlvbiBmb3IgY29tbWFuZHMgbWFwcGluZyBkZXBlbmRlbmN5IHJlbGF0aW9uc2hpcHMuCiAqCiAqIEBhdXRob3IgTmllbHMgS2V1cmVudGplcyA8bmllbHMua2V1cmVudGplc0BvbWluZXMuY29tPgogKi8KY2xhc3MgQmFzZURlcGVuZGVuY3lDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgY29uc3QgQVJHVU1FTlRfUEFDS0FHRSA9ICdwYWNrYWdlJzsKICAgIGNvbnN0IEFSR1VNRU5UX0NPTlNUUkFJTlQgPSAnY29uc3RyYWludCc7CiAgICBjb25zdCBPUFRJT05fUkVDVVJTSVZFID0gJ3JlY3Vyc2l2ZSc7CiAgICBjb25zdCBPUFRJT05fVFJFRSA9ICd0cmVlJzsKCiAgICBwcm90ZWN0ZWQgJGNvbG9yczsKCiAgICAvKioKICAgICAqIFNldCBjb21tb24gb3B0aW9ucyBhbmQgYXJndW1lbnRzLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcy0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoc2VsZjo6QVJHVU1FTlRfUEFDS0FHRSwgSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQsICdQYWNrYWdlIHRvIGluc3BlY3QnKSwKICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoc2VsZjo6QVJHVU1FTlRfQ09OU1RSQUlOVCwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdPcHRpb25hbCB2ZXJzaW9uIGNvbnN0cmFpbnQnLCAnKicpLAogICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oc2VsZjo6T1BUSU9OX1JFQ1VSU0lWRSwgJ3InLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1JlY3Vyc2l2ZWx5IHJlc29sdmVzIHVwIHRvIHRoZSByb290IHBhY2thZ2UnKSwKICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKHNlbGY6Ok9QVElPTl9UUkVFLCAndCcsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJpbnRzIHRoZSByZXN1bHRzIGFzIGEgbmVzdGVkIHRyZWUnKSwKICAgICAgICApKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtICBJbnB1dEludGVyZmFjZSAgJGlucHV0CiAgICAgKiBAcGFyYW0gIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcGFyYW0gIGJvb2wgICAgICAgICAgICAkaW52ZXJ0ZWQgV2hldGhlciB0byBpbnZlcnQgbWF0Y2hpbmcgcHJvY2VzcyAod2h5LW5vdCB2cyB3aHkgYmVoYXZpb3VyKQogICAgICogQHJldHVybiBpbnQgICAgICAgICAgICAgRXhpdCBjb2RlIG9mIHRoZSBvcGVyYXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0V4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJGludmVydGVkID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy8gRW1pdCBjb21tYW5kIGV2ZW50IG9uIHN0YXJ0dXAKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIoKTsKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICR0aGlzLT5nZXROYW1lKCksICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJHBsYXRmb3JtT3ZlcnJpZGVzID0gJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdwbGF0Zm9ybScpID86IGFycmF5KCk7CiAgICAgICAgJGluc3RhbGxlZFJlcG8gPSBuZXcgSW5zdGFsbGVkUmVwb3NpdG9yeShhcnJheSgKICAgICAgICAgICAgbmV3IFJvb3RQYWNrYWdlUmVwb3NpdG9yeSgkY29tcG9zZXItPmdldFBhY2thZ2UoKSksCiAgICAgICAgICAgICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCksCiAgICAgICAgICAgIG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkoYXJyYXkoKSwgJHBsYXRmb3JtT3ZlcnJpZGVzKSwKICAgICAgICApKTsKCiAgICAgICAgLy8gUGFyc2UgcGFja2FnZSBuYW1lIGFuZCBjb25zdHJhaW50CiAgICAgICAgbGlzdCgkbmVlZGxlLCAkdGV4dENvbnN0cmFpbnQpID0gYXJyYXlfcGFkKAogICAgICAgICAgICBleHBsb2RlKCc6JywgJGlucHV0LT5nZXRBcmd1bWVudChzZWxmOjpBUkdVTUVOVF9QQUNLQUdFKSksCiAgICAgICAgICAgIDIsCiAgICAgICAgICAgICRpbnB1dC0+Z2V0QXJndW1lbnQoc2VsZjo6QVJHVU1FTlRfQ09OU1RSQUlOVCkKICAgICAgICApOwoKICAgICAgICAvLyBGaW5kIHBhY2thZ2VzIHRoYXQgYXJlIG9yIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBwYWNrYWdlIGZpcnN0CiAgICAgICAgJHBhY2thZ2VzID0gJGluc3RhbGxlZFJlcG8tPmZpbmRQYWNrYWdlc1dpdGhSZXBsYWNlcnNBbmRQcm92aWRlcnMoJG5lZWRsZSk7CiAgICAgICAgaWYgKGVtcHR5KCRwYWNrYWdlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQ291bGQgbm90IGZpbmQgcGFja2FnZSAiJXMiIGluIHlvdXIgcHJvamVjdCcsICRuZWVkbGUpKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZSB2ZXJzaW9uIHdlIGFzayBmb3IgaXMgbm90IGluc3RhbGxlZCB0aGVuIHdlIG5lZWQgdG8gbG9jYXRlIGl0IGluIHJlbW90ZSByZXBvcyBhbmQgYWRkIGl0LgogICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciB3aHktbm90IHRvIHJlc29sdmUgY29uZmxpY3RzIGZyb20gYW4gdW5pbnN0YWxsZWQgdmVyc2lvbiBhZ2FpbnN0IGluc3RhbGxlZCBwYWNrYWdlcy4KICAgICAgICBpZiAoISRpbnN0YWxsZWRSZXBvLT5maW5kUGFja2FnZSgkbmVlZGxlLCAkdGV4dENvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICRkZWZhdWx0UmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShSZXBvc2l0b3J5RmFjdG9yeTo6ZGVmYXVsdFJlcG9zKCR0aGlzLT5nZXRJTygpKSk7CiAgICAgICAgICAgIGlmICgkbWF0Y2ggPSAkZGVmYXVsdFJlcG9zLT5maW5kUGFja2FnZSgkbmVlZGxlLCAkdGV4dENvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAkaW5zdGFsbGVkUmVwby0+YWRkUmVwb3NpdG9yeShuZXcgSW5zdGFsbGVkQXJyYXlSZXBvc2l0b3J5KGFycmF5KGNsb25lICRtYXRjaCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSW5jbHVkZSByZXBsYWNlZCBwYWNrYWdlcyBmb3IgaW52ZXJ0ZWQgbG9va3VwcyBhcyB0aGV5IGFyZSB0aGVuIHRoZSBhY3R1YWwgc3RhcnRpbmcgcG9pbnQgdG8gY29uc2lkZXIKICAgICAgICAkbmVlZGxlcyA9IGFycmF5KCRuZWVkbGUpOwogICAgICAgIGlmICgkaW52ZXJ0ZWQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkbmVlZGxlcyA9IGFycmF5X21lcmdlKCRuZWVkbGVzLCBhcnJheV9tYXAoZnVuY3Rpb24gKExpbmsgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAgICAgfSwgJHBhY2thZ2UtPmdldFJlcGxhY2VzKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUGFyc2UgY29uc3RyYWludCBpZiBvbmUgd2FzIHN1cHBsaWVkCiAgICAgICAgaWYgKCcqJyAhPT0gJHRleHRDb25zdHJhaW50KSB7CiAgICAgICAgICAgICR2ZXJzaW9uUGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXIoKTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdmVyc2lvblBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkdGV4dENvbnN0cmFpbnQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb25zdHJhaW50ID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIFBhcnNlIHJlbmRlcmluZyBvcHRpb25zCiAgICAgICAgJHJlbmRlclRyZWUgPSAkaW5wdXQtPmdldE9wdGlvbihzZWxmOjpPUFRJT05fVFJFRSk7CiAgICAgICAgJHJlY3Vyc2l2ZSA9ICRyZW5kZXJUcmVlIHx8ICRpbnB1dC0+Z2V0T3B0aW9uKHNlbGY6Ok9QVElPTl9SRUNVUlNJVkUpOwoKICAgICAgICAvLyBSZXNvbHZlIGRlcGVuZGVuY2llcwogICAgICAgICRyZXN1bHRzID0gJGluc3RhbGxlZFJlcG8tPmdldERlcGVuZGVudHMoJG5lZWRsZXMsICRjb25zdHJhaW50LCAkaW52ZXJ0ZWQsICRyZWN1cnNpdmUpOwogICAgICAgIGlmIChlbXB0eSgkcmVzdWx0cykpIHsKICAgICAgICAgICAgJGV4dHJhID0gKG51bGwgIT09ICRjb25zdHJhaW50KSA/IHNwcmludGYoJyBpbiB2ZXJzaW9ucyAlc21hdGNoaW5nICVzJywgJGludmVydGVkID8gJ25vdCAnIDogJycsICR0ZXh0Q29uc3RyYWludCkgOiAnJzsKICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgICAgICc8aW5mbz5UaGVyZSBpcyBubyBpbnN0YWxsZWQgcGFja2FnZSBkZXBlbmRpbmcgb24gIiVzIiVzPC9pbmZvPicsCiAgICAgICAgICAgICAgICAkbmVlZGxlLAogICAgICAgICAgICAgICAgJGV4dHJhCiAgICAgICAgICAgICkpOwogICAgICAgIH0gZWxzZWlmICgkcmVuZGVyVHJlZSkgewogICAgICAgICAgICAkdGhpcy0+aW5pdFN0eWxlcygkb3V0cHV0KTsKICAgICAgICAgICAgJHJvb3QgPSAkcGFja2FnZXNbMF07CiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZShzcHJpbnRmKCc8aW5mbz4lczwvaW5mbz4gJXMgJXMnLCAkcm9vdC0+Z2V0UHJldHR5TmFtZSgpLCAkcm9vdC0+Z2V0UHJldHR5VmVyc2lvbigpLCAkcm9vdC0+Z2V0RGVzY3JpcHRpb24oKSkpOwogICAgICAgICAgICAkdGhpcy0+cHJpbnRUcmVlKCRyZXN1bHRzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJpbnRUYWJsZSgkb3V0cHV0LCAkcmVzdWx0cyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEFzc2VtYmxlcyBhbmQgcHJpbnRzIGEgYm90dG9tLXVwIHRhYmxlIG9mIHRoZSBkZXBlbmRlbmNpZXMuCiAgICAgKgogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICRyZXN1bHRzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFRhYmxlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcmVzdWx0cykKICAgIHsKICAgICAgICAkdGFibGUgPSBhcnJheSgpOwogICAgICAgICRkb3VibGVzID0gYXJyYXkoKTsKICAgICAgICBkbyB7CiAgICAgICAgICAgICRxdWV1ZSA9IGFycmF5KCk7CiAgICAgICAgICAgICRyb3dzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAgICAgICAgICAgICAqIEB2YXIgTGluayAgICAgICAgICAgICAkbGluawogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBsaXN0KCRwYWNrYWdlLCAkbGluaywgJGNoaWxkcmVuKSA9ICRyZXN1bHQ7CiAgICAgICAgICAgICAgICAkdW5pcXVlID0gKHN0cmluZykgJGxpbms7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGRvdWJsZXNbJHVuaXF1ZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZG91Ymxlc1skdW5pcXVlXSA9IHRydWU7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgPT09IFJvb3RQYWNrYWdlOjpERUZBVUxUX1BSRVRUWV9WRVJTSU9OID8gJy0nIDogJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgICAgICRyb3dzW10gPSBhcnJheSgkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLCAkdmVyc2lvbiwgJGxpbmstPmdldERlc2NyaXB0aW9uKCksIHNwcmludGYoJyVzICglcyknLCAkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRQcmV0dHlDb25zdHJhaW50KCkpKTsKICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICAgICAkcXVldWUgPSBhcnJheV9tZXJnZSgkcXVldWUsICRjaGlsZHJlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdHMgPSAkcXVldWU7CiAgICAgICAgICAgICR0YWJsZSA9IGFycmF5X21lcmdlKCRyb3dzLCAkdGFibGUpOwogICAgICAgIH0gd2hpbGUgKCFlbXB0eSgkcmVzdWx0cykpOwoKICAgICAgICAkdGhpcy0+cmVuZGVyVGFibGUoJHRhYmxlLCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXQgc3R5bGVzIGZvciB0cmVlCiAgICAgKgogICAgICogQHBhcmFtIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0U3R5bGVzKE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICR0aGlzLT5jb2xvcnMgPSBhcnJheSgKICAgICAgICAgICAgJ2dyZWVuJywKICAgICAgICAgICAgJ3llbGxvdycsCiAgICAgICAgICAgICdjeWFuJywKICAgICAgICAgICAgJ21hZ2VudGEnLAogICAgICAgICAgICAnYmx1ZScsCiAgICAgICAgKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbG9ycyBhcyAkY29sb3IpIHsKICAgICAgICAgICAgJHN0eWxlID0gbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCRjb2xvcik7CiAgICAgICAgICAgICRvdXRwdXQtPmdldEZvcm1hdHRlcigpLT5zZXRTdHlsZSgkY29sb3IsICRzdHlsZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgcHJpbnRzIGEgdHJlZSBvZiB0aGUgc2VsZWN0ZWQgcmVzdWx0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICRyZXN1bHRzIFJlc3VsdHMgdG8gYmUgcHJpbnRlZCBhdCB0aGlzIGxldmVsLgogICAgICogQHBhcmFtIHN0cmluZyAkcHJlZml4ICBQcmVmaXggb2YgdGhlIGN1cnJlbnQgdHJlZSBsZXZlbC4KICAgICAqIEBwYXJhbSBpbnQgICAgJGxldmVsICAgQ3VycmVudCBsZXZlbCBvZiByZWN1cnNpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmludFRyZWUoJHJlc3VsdHMsICRwcmVmaXggPSAnJywgJGxldmVsID0gMSkKICAgIHsKICAgICAgICAkY291bnQgPSBjb3VudCgkcmVzdWx0cyk7CiAgICAgICAgJGlkeCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJHJlc3VsdHMgYXMgJHJlc3VsdCkgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHZhciBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgICAgICAgICAqIEB2YXIgTGluayAgICAgICAgICAgICAkbGluawogICAgICAgICAgICAgKiBAdmFyIGFycmF5fGJvb2wgICAgICAgJGNoaWxkcmVuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBsaXN0KCRwYWNrYWdlLCAkbGluaywgJGNoaWxkcmVuKSA9ICRyZXN1bHQ7CgogICAgICAgICAgICAkY29sb3IgPSAkdGhpcy0+Y29sb3JzWyRsZXZlbCAlIGNvdW50KCR0aGlzLT5jb2xvcnMpXTsKICAgICAgICAgICAgJHByZXZDb2xvciA9ICR0aGlzLT5jb2xvcnNbKCRsZXZlbCAtIDEpICUgY291bnQoJHRoaXMtPmNvbG9ycyldOwogICAgICAgICAgICAkaXNMYXN0ID0gKCsrJGlkeCA9PSAkY291bnQpOwogICAgICAgICAgICAkdmVyc2lvblRleHQgPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpID09PSBSb290UGFja2FnZTo6REVGQVVMVF9QUkVUVFlfVkVSU0lPTiA/ICcnIDogJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKTsKICAgICAgICAgICAgJHBhY2thZ2VUZXh0ID0gcnRyaW0oc3ByaW50ZignPCVzPiVzPC8lMSRzPiAlcycsICRjb2xvciwgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJHZlcnNpb25UZXh0KSk7CiAgICAgICAgICAgICRsaW5rVGV4dCA9IHNwcmludGYoJyVzIDwlcz4lczwvJTIkcz4gJXMnLCAkbGluay0+Z2V0RGVzY3JpcHRpb24oKSwgJHByZXZDb2xvciwgJGxpbmstPmdldFRhcmdldCgpLCAkbGluay0+Z2V0UHJldHR5Q29uc3RyYWludCgpKTsKICAgICAgICAgICAgJGNpcmN1bGFyV2FybiA9ICRjaGlsZHJlbiA9PT0gZmFsc2UgPyAnKGNpcmN1bGFyIGRlcGVuZGVuY3kgYWJvcnRlZCBoZXJlKScgOiAnJzsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVHJlZUxpbmUocnRyaW0oc3ByaW50ZigiJXMlcyVzICglcykgJXMiLCAkcHJlZml4LCAkaXNMYXN0ID8gJ+KUlOKUgOKUgCcgOiAn4pSc4pSA4pSAJywgJHBhY2thZ2VUZXh0LCAkbGlua1RleHQsICRjaXJjdWxhcldhcm4pKSk7CiAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcmludFRyZWUoJGNoaWxkcmVuLCAkcHJlZml4IC4gKCRpc0xhc3QgPyAnICAgJyA6ICfilIIgICcpLCAkbGV2ZWwgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlVHJlZUxpbmUoJGxpbmUpCiAgICB7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CiAgICAgICAgaWYgKCEkaW8tPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgJGxpbmUgPSBzdHJfcmVwbGFjZShhcnJheSgn4pSUJywgJ+KUnCcsICfilIDilIAnLCAn4pSCJyksIGFycmF5KCdgLScsICd8LScsICctJywgJ3wnKSwgJGxpbmUpOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZSgkbGluZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxIdHRwRG93bmxvYWRlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE11bHRpQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFRhYmxlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXFF1ZXN0aW9uOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFVwZGF0ZUNvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3VwZGF0ZScpCiAgICAgICAgICAgIC0+c2V0QWxpYXNlcyhhcnJheSgndScsICd1cGdyYWRlJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1VwZ3JhZGVzIHlvdXIgZGVwZW5kZW5jaWVzIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiBhY2NvcmRpbmcgdG8gY29tcG9zZXIuanNvbiwgYW5kIHVwZGF0ZXMgdGhlIGNvbXBvc2VyLmxvY2sgZmlsZS4nKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgncGFja2FnZXMnLCBJbnB1dEFyZ3VtZW50OjpJU19BUlJBWSB8IElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnUGFja2FnZXMgdGhhdCBzaG91bGQgYmUgdXBkYXRlZCwgaWYgbm90IHByb3ZpZGVkIGFsbCBwYWNrYWdlcyBhcmUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfSVNfQVJSQVkgfCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQsICdUZW1wb3JhcnkgdmVyc2lvbiBjb25zdHJhaW50IHRvIGFkZCwgZS5nLiBmb28vYmFyOjEuMC4wIG9yIGZvby9iYXI9MS4wLjAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLXNvdXJjZScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2VzIGluc3RhbGxhdGlvbiBmcm9tIHBhY2thZ2Ugc291cmNlcyB3aGVuIHBvc3NpYmxlLCBpbmNsdWRpbmcgVkNTIGluZm9ybWF0aW9uLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItZGlzdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2VzIGluc3RhbGxhdGlvbiBmcm9tIHBhY2thZ2UgZGlzdCBldmVuIGZvciBkZXYgdmVyc2lvbnMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RyeS1ydW4nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ091dHB1dHMgdGhlIG9wZXJhdGlvbnMgYnV0IHdpbGwgbm90IGV4ZWN1dGUgYW55dGhpbmcgKGltcGxpY2l0bHkgZW5hYmxlcyAtLXZlcmJvc2UpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdkZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IEVuYWJsZXMgaW5zdGFsbGF0aW9uIG9mIHJlcXVpcmUtZGV2IHBhY2thZ2VzIChlbmFibGVkIGJ5IGRlZmF1bHQsIG9ubHkgcHJlc2VudCBmb3IgQkMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIGluc3RhbGxhdGlvbiBvZiByZXF1aXJlLWRldiBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbG9jaycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT3ZlcndyaXRlcyB0aGUgbG9jayBmaWxlIGhhc2ggdG8gc3VwcHJlc3Mgd2FybmluZyBhYm91dCB0aGUgbG9jayBmaWxlIGJlaW5nIG91dCBvZiBkYXRlIHdpdGhvdXQgdXBkYXRpbmcgcGFja2FnZSB2ZXJzaW9ucy4gUGFja2FnZSBtZXRhZGF0YSBsaWtlIG1pcnJvcnMgYW5kIFVSTHMgYXJlIHVwZGF0ZWQgaWYgdGhleSBjaGFuZ2VkLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwIHRoZSBpbnN0YWxsIHN0ZXAgYWZ0ZXIgdXBkYXRpbmcgdGhlIGNvbXBvc2VyLmxvY2sgZmlsZS4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tYXV0b2xvYWRlcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2tpcHMgYXV0b2xvYWRlciBnZW5lcmF0aW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXNjcmlwdHMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXBzIHRoZSBleGVjdXRpb24gb2YgYWxsIHNjcmlwdHMgZGVmaW5lZCBpbiBjb21wb3Nlci5qc29uIGZpbGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXN1Z2dlc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IFRoaXMgZmxhZyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1wcm9ncmVzcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IG91dHB1dCBkb3dubG9hZCBwcm9ncmVzcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignd2l0aC1kZXBlbmRlbmNpZXMnLCAndycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVXBkYXRlIGFsc28gZGVwZW5kZW5jaWVzIG9mIHBhY2thZ2VzIGluIHRoZSBhcmd1bWVudCBsaXN0LCBleGNlcHQgdGhvc2Ugd2hpY2ggYXJlIHJvb3QgcmVxdWlyZW1lbnRzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd3aXRoLWFsbC1kZXBlbmRlbmNpZXMnLCAnVycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnVXBkYXRlIGFsc28gZGVwZW5kZW5jaWVzIG9mIHBhY2thZ2VzIGluIHRoZSBhcmd1bWVudCBsaXN0LCBpbmNsdWRpbmcgdGhvc2Ugd2hpY2ggYXJlIHJvb3QgcmVxdWlyZW1lbnRzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd2ZXJib3NlJywgJ3Z8dnZ8dnZ2JywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTaG93cyBtb3JlIGRldGFpbHMgaW5jbHVkaW5nIG5ldyBjb21taXRzIHB1bGxlZCBpbiB3aGVuIHVwZGF0aW5nIHBhY2thZ2VzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdvcHRpbWl6ZS1hdXRvbG9hZGVyJywgJ28nLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ09wdGltaXplIGF1dG9sb2FkZXIgZHVyaW5nIGF1dG9sb2FkZXIgZHVtcC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBdXRvbG9hZCBjbGFzc2VzIGZyb20gdGhlIGNsYXNzbWFwIG9ubHkuIEltcGxpY2l0bHkgZW5hYmxlcyBgLS1vcHRpbWl6ZS1hdXRvbG9hZGVyYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1VzZSBhIGN1c3RvbSBwcmVmaXggZm9yIHRoZSBBUEN1IGF1dG9sb2FkZXIgY2FjaGUuIEltcGxpY2l0bHkgZW5hYmxlcyAtLWFwY3UtYXV0b2xvYWRlcicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIGEgc3BlY2lmaWMgcGxhdGZvcm0gcmVxdWlyZW1lbnQgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc3RhYmxlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdQcmVmZXIgc3RhYmxlIHZlcnNpb25zIG9mIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWxvd2VzdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJlZmVyIGxvd2VzdCB2ZXJzaW9ucyBvZiBkZXBlbmRlbmNpZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2ludGVyYWN0aXZlJywgJ2knLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ludGVyYWN0aXZlIGludGVyZmFjZSB3aXRoIGF1dG9jb21wbGV0aW9uIHRvIHNlbGVjdCB0aGUgcGFja2FnZXMgdG8gdXBkYXRlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyb290LXJlcXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1Jlc3RyaWN0cyB0aGUgdXBkYXRlIHRvIHlvdXIgZmlyc3QgZGVncmVlIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSA8aW5mbz51cGRhdGU8L2luZm8+IGNvbW1hbmQgcmVhZHMgdGhlIGNvbXBvc2VyLmpzb24gZmlsZSBmcm9tIHRoZQpjdXJyZW50IGRpcmVjdG9yeSwgcHJvY2Vzc2VzIGl0LCBhbmQgdXBkYXRlcywgcmVtb3ZlcyBvciBpbnN0YWxscyBhbGwgdGhlCmRlcGVuZGVuY2llcy4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHVwZGF0ZTwvaW5mbz4KClRvIGxpbWl0IHRoZSB1cGRhdGUgb3BlcmF0aW9uIHRvIGEgZmV3IHBhY2thZ2VzLCB5b3UgY2FuIGxpc3QgdGhlIHBhY2thZ2UocykKeW91IHdhbnQgdG8gdXBkYXRlIGFzIHN1Y2g6Cgo8aW5mbz5waHAgY29tcG9zZXIucGhhciB1cGRhdGUgdmVuZG9yL3BhY2thZ2UxIGZvby9teXBhY2thZ2UgWy4uLl08L2luZm8+CgpZb3UgbWF5IGFsc28gdXNlIGFuIGFzdGVyaXNrICgqKSBwYXR0ZXJuIHRvIGxpbWl0IHRoZSB1cGRhdGUgb3BlcmF0aW9uIHRvIHBhY2thZ2UocykKZnJvbSBhIHNwZWNpZmljIHZlbmRvcjoKCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHVwZGF0ZSB2ZW5kb3IvcGFja2FnZTEgZm9vLyogWy4uLl08L2luZm8+CgpUbyBydW4gYW4gdXBkYXRlIHdpdGggbW9yZSByZXN0cmljdGl2ZSBjb25zdHJhaW50cyB5b3UgY2FuIHVzZToKCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHVwZGF0ZSAtLXdpdGggdmVuZG9yL3BhY2thZ2U6MS4wLio8L2luZm8+CgpUbyBydW4gYSBwYXJ0aWFsIHVwZGF0ZSB3aXRoIG1vcmUgcmVzdHJpY3RpdmUgY29uc3RyYWludHMgeW91IGNhbiB1c2UgdGhlIHNob3J0aGFuZDoKCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHVwZGF0ZSB2ZW5kb3IvcGFja2FnZToxLjAuKjwvaW5mbz4KClRvIHNlbGVjdCBwYWNrYWdlcyBuYW1lcyBpbnRlcmFjdGl2ZWx5IHdpdGggYXV0by1jb21wbGV0aW9uIHVzZSA8aW5mbz4taTwvaW5mbz4uCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCN1cGRhdGUtdQpFT1QKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignZGV2JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAiLS1kZXYiLiBJdCBoYXMgbm8gZWZmZWN0IGFuZCB3aWxsIGJyZWFrIGluIENvbXBvc2VyIDMuPC93YXJuaW5nPicpOwogICAgICAgIH0KICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ25vLXN1Z2dlc3QnKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgdXNpbmcgdGhlIGRlcHJlY2F0ZWQgb3B0aW9uICItLW5vLXN1Z2dlc3QiLiBJdCBoYXMgbm8gZWZmZWN0IGFuZCB3aWxsIGJyZWFrIGluIENvbXBvc2VyIDMuPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKHRydWUsICRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJykpOwoKICAgICAgICBpZiAoIUh0dHBEb3dubG9hZGVyOjppc0N1cmxFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Db21wb3NlciBpcyBvcGVyYXRpbmcgc2lnbmlmaWNhbnRseSBzbG93ZXIgdGhhbiBub3JtYWwgYmVjYXVzZSB5b3UgZG8gbm90IGhhdmUgdGhlIFBIUCBjdXJsIGV4dGVuc2lvbiBlbmFibGVkLjwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgICRwYWNrYWdlcyA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyk7CiAgICAgICAgJHJlcXMgPSAkdGhpcy0+Zm9ybWF0UmVxdWlyZW1lbnRzKCRpbnB1dC0+Z2V0T3B0aW9uKCd3aXRoJykpOwoKICAgICAgICAvLyBleHRyYWN0IC0td2l0aCBzaG9ydGhhbmRzIGZyb20gdGhlIGFsbG93bGlzdAogICAgICAgIGlmICgkcGFja2FnZXMpIHsKICAgICAgICAgICAgJGFsbG93bGlzdFBhY2thZ2VzV2l0aFJlcXVpcmVtZW50cyA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcGtnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgne1xTK1sgPTpdXFMrfScsICRwa2cpID4gMDsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJGFsbG93bGlzdFBhY2thZ2VzV2l0aFJlcXVpcmVtZW50cykgYXMgJHBhY2thZ2UgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICRyZXFzWyRwYWNrYWdlXSA9ICRjb25zdHJhaW50OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBmb28vYmFyOnJlcSBieSBmb28vYmFyIGluIHRoZSBhbGxvd2xpc3QKICAgICAgICAgICAgZm9yZWFjaCAoJGFsbG93bGlzdFBhY2thZ2VzV2l0aFJlcXVpcmVtZW50cyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lID0gcHJlZ19yZXBsYWNlKCd7XihbXiA9Ol0rKVsgPTpdLiokfScsICckMScsICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICRpbmRleCA9IGFycmF5X3NlYXJjaCgkcGFja2FnZSwgJHBhY2thZ2VzKTsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1skaW5kZXhdID0gJHBhY2thZ2VOYW1lOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcm9vdFJlcXVpcmVzID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldFJlcXVpcmVzKCk7CiAgICAgICAgJHJvb3REZXZSZXF1aXJlcyA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXREZXZSZXF1aXJlcygpOwogICAgICAgIGZvcmVhY2ggKCRyZXFzIGFzICRwYWNrYWdlID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkcm9vdFJlcXVpcmVzWyRwYWNrYWdlXSkpIHsKICAgICAgICAgICAgICAgICRyb290UmVxdWlyZXNbJHBhY2thZ2VdID0gJHRoaXMtPmFwcGVuZENvbnN0cmFpbnRUb0xpbmsoJHJvb3RSZXF1aXJlc1skcGFja2FnZV0sICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCRyb290RGV2UmVxdWlyZXNbJHBhY2thZ2VdKSkgewogICAgICAgICAgICAgICAgJHJvb3REZXZSZXF1aXJlc1skcGFja2FnZV0gPSAkdGhpcy0+YXBwZW5kQ29uc3RyYWludFRvTGluaygkcm9vdERldlJlcXVpcmVzWyRwYWNrYWdlXSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ09ubHkgcm9vdCBwYWNrYWdlIHJlcXVpcmVtZW50cyBjYW4gcmVjZWl2ZSB0ZW1wb3JhcnkgY29uc3RyYWludHMgYW5kICcuJHBhY2thZ2UuJyBpcyBub3Qgb25lJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPnNldFJlcXVpcmVzKCRyb290UmVxdWlyZXMpOwogICAgICAgICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5zZXREZXZSZXF1aXJlcygkcm9vdERldlJlcXVpcmVzKTsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdpbnRlcmFjdGl2ZScpKSB7CiAgICAgICAgICAgICRwYWNrYWdlcyA9ICR0aGlzLT5nZXRQYWNrYWdlc0ludGVyYWN0aXZlbHkoJGlvLCAkaW5wdXQsICRvdXRwdXQsICRjb21wb3NlciwgJHBhY2thZ2VzKTsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigncm9vdC1yZXFzJykpIHsKICAgICAgICAgICAgJHJlcXVpcmVzID0gYXJyYXlfa2V5cygkcm9vdFJlcXVpcmVzKTsKICAgICAgICAgICAgaWYgKCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpIHsKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5X21lcmdlKCRyZXF1aXJlcywgYXJyYXlfa2V5cygkcm9vdERldlJlcXVpcmVzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJHBhY2thZ2VzKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gYXJyYXlfaW50ZXJzZWN0KCRwYWNrYWdlcywgJHJlcXVpcmVzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICRyZXF1aXJlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gdGhlIGFyZ3VtZW50cyBsb2NrL25vdGhpbmcvbWlycm9ycyBhcmUgbm90IHBhY2thZ2UgbmFtZXMgYnV0IHRyaWdnZXIgYSBtaXJyb3IgdXBkYXRlIGluc3RlYWQKICAgICAgICAvLyB0aGV5IGFyZSBmdXJ0aGVyIG11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGxpc3RpbmcgYWN0dWFsIHBhY2thZ2UgbmFtZXMKICAgICAgICAkZmlsdGVyZWRQYWNrYWdlcyA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcGFja2FnZSkgewogICAgICAgICAgICByZXR1cm4gIWluX2FycmF5KCRwYWNrYWdlLCBhcnJheSgnbG9jaycsICdub3RoaW5nJywgJ21pcnJvcnMnKSwgdHJ1ZSk7CiAgICAgICAgfSk7CiAgICAgICAgJHVwZGF0ZU1pcnJvcnMgPSAkaW5wdXQtPmdldE9wdGlvbignbG9jaycpIHx8IGNvdW50KCRmaWx0ZXJlZFBhY2thZ2VzKSAhPSBjb3VudCgkcGFja2FnZXMpOwogICAgICAgICRwYWNrYWdlcyA9ICRmaWx0ZXJlZFBhY2thZ2VzOwoKICAgICAgICBpZiAoJHVwZGF0ZU1pcnJvcnMgJiYgIWVtcHR5KCRwYWNrYWdlcykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+WW91IGNhbm5vdCBzaW11bHRhbmVvdXNseSB1cGRhdGUgb25seSBhIHNlbGVjdGlvbiBvZiBwYWNrYWdlcyBhbmQgcmVnZW5lcmF0ZSB0aGUgbG9jayBmaWxlIG1ldGFkYXRhLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICd1cGRhdGUnLCAkaW5wdXQsICRvdXRwdXQpOwogICAgICAgICRjb21wb3Nlci0+Z2V0RXZlbnREaXNwYXRjaGVyKCktPmRpc3BhdGNoKCRjb21tYW5kRXZlbnQtPmdldE5hbWUoKSwgJGNvbW1hbmRFdmVudCk7CgogICAgICAgICRjb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5zZXRPdXRwdXRQcm9ncmVzcyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXByb2dyZXNzJykpOwoKICAgICAgICAkaW5zdGFsbCA9IEluc3RhbGxlcjo6Y3JlYXRlKCRpbywgJGNvbXBvc2VyKTsKCiAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CiAgICAgICAgbGlzdCgkcHJlZmVyU291cmNlLCAkcHJlZmVyRGlzdCkgPSAkdGhpcy0+Z2V0UHJlZmVycmVkSW5zdGFsbE9wdGlvbnMoJGNvbmZpZywgJGlucHV0KTsKCiAgICAgICAgJG9wdGltaXplID0gJGlucHV0LT5nZXRPcHRpb24oJ29wdGltaXplLWF1dG9sb2FkZXInKSB8fCAkY29uZmlnLT5nZXQoJ29wdGltaXplLWF1dG9sb2FkZXInKTsKICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbmZpZy0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgJGFwY3VQcmVmaXggPSAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcpOwogICAgICAgICRhcGN1ID0gJGFwY3VQcmVmaXggIT09IG51bGwgfHwgJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlcicpIHx8ICRjb25maWctPmdldCgnYXBjdS1hdXRvbG9hZGVyJyk7CgogICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfT05MWV9MSVNURUQ7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd3aXRoLWFsbC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUzsKICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJykpIHsKICAgICAgICAgICAgJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9IFJlcXVlc3Q6OlVQREFURV9MSVNURURfV0lUSF9UUkFOU0lUSVZFX0RFUFNfTk9fUk9PVF9SRVFVSVJFOwogICAgICAgIH0KCiAgICAgICAgJGlnbm9yZVBsYXRmb3JtUmVxcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycpID86ICgkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcScpID86IGZhbHNlKTsKCiAgICAgICAgJGluc3RhbGwKICAgICAgICAgICAgLT5zZXREcnlSdW4oJGlucHV0LT5nZXRPcHRpb24oJ2RyeS1ydW4nKSkKICAgICAgICAgICAgLT5zZXRWZXJib3NlKCRpbnB1dC0+Z2V0T3B0aW9uKCd2ZXJib3NlJykpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyU291cmNlKCRwcmVmZXJTb3VyY2UpCiAgICAgICAgICAgIC0+c2V0UHJlZmVyRGlzdCgkcHJlZmVyRGlzdCkKICAgICAgICAgICAgLT5zZXREZXZNb2RlKCEkaW5wdXQtPmdldE9wdGlvbignbm8tZGV2JykpCiAgICAgICAgICAgIC0+c2V0RHVtcEF1dG9sb2FkZXIoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1hdXRvbG9hZGVyJykpCiAgICAgICAgICAgIC0+c2V0UnVuU2NyaXB0cyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXNjcmlwdHMnKSkKICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJG9wdGltaXplKQogICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSkKICAgICAgICAgICAgLT5zZXRBcGN1QXV0b2xvYWRlcigkYXBjdSwgJGFwY3VQcmVmaXgpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlKHRydWUpCiAgICAgICAgICAgIC0+c2V0SW5zdGFsbCghJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSkKICAgICAgICAgICAgLT5zZXRVcGRhdGVNaXJyb3JzKCR1cGRhdGVNaXJyb3JzKQogICAgICAgICAgICAtPnNldFVwZGF0ZUFsbG93TGlzdCgkcGFja2FnZXMpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKCR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMpCiAgICAgICAgICAgIC0+c2V0SWdub3JlUGxhdGZvcm1SZXF1aXJlbWVudHMoJGlnbm9yZVBsYXRmb3JtUmVxcykKICAgICAgICAgICAgLT5zZXRQcmVmZXJTdGFibGUoJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1zdGFibGUnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJMb3dlc3QoJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1sb3dlc3QnKSkKICAgICAgICA7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpKSB7CiAgICAgICAgICAgICRpbnN0YWxsLT5kaXNhYmxlUGx1Z2lucygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRpbnN0YWxsLT5ydW4oKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhY2thZ2VzSW50ZXJhY3RpdmVseShJT0ludGVyZmFjZSAkaW8sIElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIENvbXBvc2VyICRjb21wb3NlciwgYXJyYXkgJHBhY2thZ2VzKQogICAgewogICAgICAgIGlmICghJGlucHV0LT5pc0ludGVyYWN0aXZlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJy0taW50ZXJhY3RpdmUgY2Fubm90IGJlIHVzZWQgaW4gbm9uLWludGVyYWN0aXZlIHRlcm1pbmFscy4nKTsKICAgICAgICB9CgogICAgICAgICRyZXF1aXJlcyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldERldlJlcXVpcmVzKCkKICAgICAgICApOwogICAgICAgICRhdXRvY29tcGxldGVyVmFsdWVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgJHRhcmdldCA9ICRyZXF1aXJlLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgJGF1dG9jb21wbGV0ZXJWYWx1ZXNbc3RydG9sb3dlcigkdGFyZ2V0KV0gPSAkdGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgJGluc3RhbGxlZFBhY2thZ2VzID0gJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpLT5nZXRMb2NhbFJlcG9zaXRvcnkoKS0+Z2V0UGFja2FnZXMoKTsKICAgICAgICBmb3JlYWNoICgkaW5zdGFsbGVkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGF1dG9jb21wbGV0ZXJWYWx1ZXNbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgIH0KCiAgICAgICAgJGhlbHBlciA9ICR0aGlzLT5nZXRIZWxwZXIoJ3F1ZXN0aW9uJyk7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFF1ZXN0aW9uKCc8Y29tbWVudD5FbnRlciBwYWNrYWdlIG5hbWU6IDwvY29tbWVudD4nLCBudWxsKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5QcmVzcyBlbnRlciB3aXRob3V0IHZhbHVlIHRvIGVuZCBzdWJtaXNzaW9uPC9pbmZvPicpOwoKICAgICAgICBkbyB7CiAgICAgICAgICAgICRhdXRvY29tcGxldGVyVmFsdWVzID0gYXJyYXlfZGlmZigkYXV0b2NvbXBsZXRlclZhbHVlcywgJHBhY2thZ2VzKTsKICAgICAgICAgICAgJHF1ZXN0aW9uLT5zZXRBdXRvY29tcGxldGVyVmFsdWVzKCRhdXRvY29tcGxldGVyVmFsdWVzKTsKICAgICAgICAgICAgJGFkZGVkUGFja2FnZSA9ICRoZWxwZXItPmFzaygkaW5wdXQsICRvdXRwdXQsICRxdWVzdGlvbik7CgogICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkYWRkZWRQYWNrYWdlKSB8fCBlbXB0eSgkYWRkZWRQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRhZGRlZFBhY2thZ2UgPSBzdHJ0b2xvd2VyKCRhZGRlZFBhY2thZ2UpOwogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRhZGRlZFBhY2thZ2UsICRwYWNrYWdlcykpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1tdID0gJGFkZGVkUGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKHRydWUpOwoKICAgICAgICAkcGFja2FnZXMgPSBhcnJheV9maWx0ZXIoJHBhY2thZ2VzKTsKICAgICAgICBpZiAoISRwYWNrYWdlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignWW91IG11c3QgZW50ZXIgbWluaW11bSBvbmUgcGFja2FnZS4nKTsKICAgICAgICB9CgogICAgICAgICR0YWJsZSA9IG5ldyBUYWJsZSgkb3V0cHV0KTsKICAgICAgICAkdGFibGUtPnNldEhlYWRlcnMoYXJyYXkoJ1NlbGVjdGVkIHBhY2thZ2VzJykpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGFibGUtPmFkZFJvdyhhcnJheSgkcGFja2FnZSkpOwogICAgICAgIH0KICAgICAgICAkdGFibGUtPnJlbmRlcigpOwoKICAgICAgICBpZiAoJGlvLT5hc2tDb25maXJtYXRpb24oc3ByaW50ZigKICAgICAgICAgICAgJ1dvdWxkIHlvdSBsaWtlIHRvIGNvbnRpbnVlIGFuZCB1cGRhdGUgdGhlIGFib3ZlIHBhY2thZ2UlcyBbPGNvbW1lbnQ+eWVzPC9jb21tZW50Pl0/ICcsCiAgICAgICAgICAgIDEgPT09IGNvdW50KCRwYWNrYWdlcykgPyAnJyA6ICdzJwogICAgICAgICkpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0luc3RhbGxhdGlvbiBhYm9ydGVkLicpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwZW5kQ29uc3RyYWludFRvTGluayhMaW5rICRsaW5rLCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICAkcGFyc2VyID0gbmV3IFZlcnNpb25QYXJzZXI7CiAgICAgICAgJG9sZFByZXR0eVN0cmluZyA9ICRsaW5rLT5nZXRDb25zdHJhaW50KCktPmdldFByZXR0eVN0cmluZygpOwogICAgICAgICRuZXdDb25zdHJhaW50ID0gTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJGxpbmstPmdldENvbnN0cmFpbnQoKSwgJHBhcnNlci0+cGFyc2VDb25zdHJhaW50cygkY29uc3RyYWludCkpKTsKICAgICAgICAkbmV3Q29uc3RyYWludC0+c2V0UHJldHR5U3RyaW5nKCRvbGRQcmV0dHlTdHJpbmcuJywgJy4kY29uc3RyYWludCk7CgogICAgICAgIHJldHVybiBuZXcgTGluaygKICAgICAgICAgICAgJGxpbmstPmdldFNvdXJjZSgpLAogICAgICAgICAgICAkbGluay0+Z2V0VGFyZ2V0KCksCiAgICAgICAgICAgICRuZXdDb25zdHJhaW50LAogICAgICAgICAgICAkbGluay0+Z2V0RGVzY3JpcHRpb24oKSwKICAgICAgICAgICAgJGxpbmstPmdldFByZXR0eUNvbnN0cmFpbnQoKSAuICcsICcgLiAkY29uc3RyYWludAogICAgICAgICk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKCi8qKgogKiBAYXV0aG9yIERhdmV5IFNoYWZpayA8bWVAZGF2ZXlzaGFmaWsuY29tPgogKi8KY2xhc3MgRXhlY0NvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2V4ZWMnKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdFeGVjdXRlcyBhIHZlbmRvcmVkIGJpbmFyeS9zY3JpcHQuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdsaXN0JywgJ2wnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnYmluYXJ5JywgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdUaGUgYmluYXJ5IHRvIHJ1biwgZS5nLiBwaHB1bml0JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgKICAgICAgICAgICAgICAgICAgICAnYXJncycsCiAgICAgICAgICAgICAgICAgICAgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwKICAgICAgICAgICAgICAgICAgICAnQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGJpbmFyeS4gVXNlIDxpbmZvPi0tPC9pbmZvPiB0byBzZXBhcmF0ZSBmcm9tIGNvbXBvc2VyIGFyZ3VtZW50cycKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC0+c2V0SGVscCgKICAgICAgICAgICAgICAgIDw8PEVPVApFeGVjdXRlcyBhIHZlbmRvcmVkIGJpbmFyeS9zY3JpcHQuCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNleGVjCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJGNvbXBvc2VyID0gJHRoaXMtPmdldENvbXBvc2VyKCk7CiAgICAgICAgJGJpbkRpciA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnYmluLWRpcicpOwogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbGlzdCcpIHx8ICEkaW5wdXQtPmdldEFyZ3VtZW50KCdiaW5hcnknKSkgewogICAgICAgICAgICAkYmlucyA9IGdsb2IoJGJpbkRpciAuICcvKicpOwogICAgICAgICAgICAkYmlucyA9IGFycmF5X21lcmdlKCRiaW5zLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiRlIChsb2NhbCkiOwogICAgICAgICAgICB9LCAkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0QmluYXJpZXMoKSkpOwoKICAgICAgICAgICAgaWYgKCEkYmlucykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJObyBiaW5hcmllcyBmb3VuZCBpbiBjb21wb3Nlci5qc29uIG9yIGluIGJpbi1kaXIgKCRiaW5EaXIpIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5nZXRJTygpLT53cml0ZSgKICAgICAgICAgICAgICAgIDw8PEVPVAo8Y29tbWVudD5BdmFpbGFibGUgYmluYXJpZXM6PC9jb21tZW50PgpFT1QKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRiaW5zIGFzICRiaW4pIHsKICAgICAgICAgICAgICAgIC8vIHNraXAgLmJhdCBjb3BpZXMKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcHJldmlvdXNCaW4pICYmICRiaW4gPT09ICRwcmV2aW91c0Jpbi4nLmJhdCcpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcHJldmlvdXNCaW4gPSAkYmluOwogICAgICAgICAgICAgICAgJGJpbiA9IGJhc2VuYW1lKCRiaW4pOwogICAgICAgICAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlKAogICAgICAgICAgICAgICAgICAgIDw8PEVPVAo8aW5mbz4tICRiaW48L2luZm8+CkVPVAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAkYmluYXJ5ID0gJGlucHV0LT5nZXRBcmd1bWVudCgnYmluYXJ5Jyk7CgogICAgICAgICRkaXNwYXRjaGVyID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKTsKICAgICAgICAkZGlzcGF0Y2hlci0+YWRkTGlzdGVuZXIoJ19fZXhlY19jb21tYW5kJywgJGJpbmFyeSk7CgogICAgICAgIC8vIElmIHRoZSBDV0Qgd2FzIG1vZGlmaWVkLCB3ZSByZXN0b3JlIGl0IHRvIHdoYXQgaXQgd2FzIGluaXRpYWxseSwgYXMgaXQgd2FzCiAgICAgICAgLy8gbW9zdCBsaWtlbHkgbW9kaWZpZWQgYnkgdGhlIGdsb2JhbCBjb21tYW5kLCBhbmQgd2Ugd2FudCBleGVjIHRvIHJ1biBpbiB0aGUgbG9jYWwgd29ya2luZyBkaXJlY3RvcnkKICAgICAgICAvLyBub3QgdGhlIGdsb2JhbCBvbmUKICAgICAgICBpZiAoZ2V0Y3dkKCkgIT09ICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJbml0aWFsV29ya2luZ0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjaGRpcigkdGhpcy0+Z2V0QXBwbGljYXRpb24oKS0+Z2V0SW5pdGlhbFdvcmtpbmdEaXJlY3RvcnkoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHN3aXRjaCBiYWNrIHRvIHdvcmtpbmcgZGlyZWN0b3J5ICInLiR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5nZXRJbml0aWFsV29ya2luZ0RpcmVjdG9yeSgpLiciJywgMCwgJGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRpc3BhdGNoZXItPmRpc3BhdGNoU2NyaXB0KCdfX2V4ZWNfY29tbWFuZCcsIHRydWUsICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2FyZ3MnKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxMb2FkZXJcVmFsaWRhdGluZ0FycmF5TG9hZGVyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXENvbW1hbmRFdmVudDsKdXNlIENvbXBvc2VyXFBsdWdpblxQbHVnaW5FdmVudHM7CnVzZSBDb21wb3NlclxVdGlsXENvbmZpZ1ZhbGlkYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIFZhbGlkYXRlQ29tbWFuZAogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVmFsaWRhdGVDb21tYW5kIGV4dGVuZHMgQmFzZUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBjb25maWd1cmUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCd2YWxpZGF0ZScpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1ZhbGlkYXRlcyBhIGNvbXBvc2VyLmpzb24gYW5kIGNvbXBvc2VyLmxvY2suJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1jaGVjay1hbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RvIG5vdCB2YWxpZGF0ZSByZXF1aXJlcyBmb3Igb3Zlcmx5IHN0cmljdC9sb29zZSBjb25zdHJhaW50cycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1jaGVjay1sb2NrJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3QgY2hlY2sgaWYgbG9jayBmaWxlIGlzIHVwIHRvIGRhdGUnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tY2hlY2stcHVibGlzaCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IGNoZWNrIGZvciBwdWJsaXNoIGVycm9ycycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1jaGVjay12ZXJzaW9uJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3QgcmVwb3J0IGEgd2FybmluZyBpZiB0aGUgdmVyc2lvbiBmaWVsZCBpcyBwcmVzZW50JyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJywgJ0EnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Fsc28gdmFsaWRhdGUgdGhlIGNvbXBvc2VyLmpzb24gb2YgYWxsIGluc3RhbGxlZCBkZXBlbmRlbmNpZXMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc3RyaWN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXR1cm4gYSBub24temVybyBleGl0IGNvZGUgZm9yIHdhcm5pbmdzIGFzIHdlbGwgYXMgZXJyb3JzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnZmlsZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAncGF0aCB0byBjb21wb3Nlci5qc29uIGZpbGUnKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClRoZSB2YWxpZGF0ZSBjb21tYW5kIHZhbGlkYXRlcyBhIGdpdmVuIGNvbXBvc2VyLmpzb24gYW5kIGNvbXBvc2VyLmxvY2sKCkV4aXQgY29kZXMgaW4gY2FzZSBvZiBlcnJvcnMgYXJlOgoxIHZhbGlkYXRpb24gd2FybmluZyhzKSwgb25seSB3aGVuIC0tc3RyaWN0IGlzIGdpdmVuCjIgdmFsaWRhdGlvbiBlcnJvcihzKQozIGZpbGUgdW5yZWFkYWJsZSBvciBtaXNzaW5nCgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCN2YWxpZGF0ZQpFT1QKICAgICAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBJbnB1dEludGVyZmFjZSAgJGlucHV0CiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRmaWxlID0gJGlucHV0LT5nZXRBcmd1bWVudCgnZmlsZScpID86IEZhY3Rvcnk6OmdldENvbXBvc2VyRmlsZSgpOwogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwoKICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRmaWxlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nIC4gJGZpbGUgLiAnIG5vdCBmb3VuZC48L2Vycm9yPicpOwoKICAgICAgICAgICAgcmV0dXJuIDM7CiAgICAgICAgfQogICAgICAgIGlmICghaXNfcmVhZGFibGUoJGZpbGUpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPicgLiAkZmlsZSAuICcgaXMgbm90IHJlYWRhYmxlLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMzsKICAgICAgICB9CgogICAgICAgICR2YWxpZGF0b3IgPSBuZXcgQ29uZmlnVmFsaWRhdG9yKCRpbyk7CiAgICAgICAgJGNoZWNrQWxsID0gJGlucHV0LT5nZXRPcHRpb24oJ25vLWNoZWNrLWFsbCcpID8gMCA6IFZhbGlkYXRpbmdBcnJheUxvYWRlcjo6Q0hFQ0tfQUxMOwogICAgICAgICRjaGVja1B1Ymxpc2ggPSAhJGlucHV0LT5nZXRPcHRpb24oJ25vLWNoZWNrLXB1Ymxpc2gnKTsKICAgICAgICAkY2hlY2tMb2NrID0gISRpbnB1dC0+Z2V0T3B0aW9uKCduby1jaGVjay1sb2NrJyk7CiAgICAgICAgJGNoZWNrVmVyc2lvbiA9ICRpbnB1dC0+Z2V0T3B0aW9uKCduby1jaGVjay12ZXJzaW9uJykgPyAwIDogQ29uZmlnVmFsaWRhdG9yOjpDSEVDS19WRVJTSU9OOwogICAgICAgICRpc1N0cmljdCA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdzdHJpY3QnKTsKICAgICAgICBsaXN0KCRlcnJvcnMsICRwdWJsaXNoRXJyb3JzLCAkd2FybmluZ3MpID0gJHZhbGlkYXRvci0+dmFsaWRhdGUoJGZpbGUsICRjaGVja0FsbCwgJGNoZWNrVmVyc2lvbik7CgogICAgICAgICRsb2NrRXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkY29tcG9zZXIgPSBGYWN0b3J5OjpjcmVhdGUoJGlvLCAkZmlsZSwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tbm8tcGx1Z2lucycpKTsKICAgICAgICAkbG9ja2VyID0gJGNvbXBvc2VyLT5nZXRMb2NrZXIoKTsKICAgICAgICBpZiAoJGxvY2tlci0+aXNMb2NrZWQoKSAmJiAhJGxvY2tlci0+aXNGcmVzaCgpKSB7CiAgICAgICAgICAgICRsb2NrRXJyb3JzW10gPSAnVGhlIGxvY2sgZmlsZSBpcyBub3QgdXAgdG8gZGF0ZSB3aXRoIHRoZSBsYXRlc3QgY2hhbmdlcyBpbiBjb21wb3Nlci5qc29uLCBpdCBpcyByZWNvbW1lbmRlZCB0aGF0IHlvdSBydW4gYGNvbXBvc2VyIHVwZGF0ZWAgb3IgYGNvbXBvc2VyIHVwZGF0ZSA8cGFja2FnZSBuYW1lPmAuJzsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXRSZXN1bHQoJGlvLCAkZmlsZSwgJGVycm9ycywgJHdhcm5pbmdzLCAkY2hlY2tQdWJsaXNoLCAkcHVibGlzaEVycm9ycywgJGNoZWNrTG9jaywgJGxvY2tFcnJvcnMsIHRydWUpOwoKICAgICAgICAvLyAkZXJyb3JzIGluY2x1ZGUgcHVibGlzaCBhbmQgbG9jayBlcnJvcnMgd2hlbiBleGlzdHMKICAgICAgICAkZXhpdENvZGUgPSAkZXJyb3JzID8gMiA6ICgkaXNTdHJpY3QgJiYgJHdhcm5pbmdzID8gMSA6IDApOwoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtZGVwZW5kZW5jaWVzJykpIHsKICAgICAgICAgICAgJGxvY2FsUmVwbyA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsb2NhbFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICRmaWxlID0gJHBhdGggLiAnL2NvbXBvc2VyLmpzb24nOwogICAgICAgICAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkgJiYgZmlsZV9leGlzdHMoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkZXJyb3JzLCAkcHVibGlzaEVycm9ycywgJHdhcm5pbmdzKSA9ICR2YWxpZGF0b3ItPnZhbGlkYXRlKCRmaWxlLCAkY2hlY2tBbGwsICRjaGVja1ZlcnNpb24pOwoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0UmVzdWx0KCRpbywgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJGVycm9ycywgJHdhcm5pbmdzLCAkY2hlY2tQdWJsaXNoLCAkcHVibGlzaEVycm9ycyk7CgogICAgICAgICAgICAgICAgICAgIC8vICRlcnJvcnMgaW5jbHVkZSBwdWJsaXNoIGVycm9ycyB3aGVuIGV4aXN0cwogICAgICAgICAgICAgICAgICAgICRkZXBDb2RlID0gJGVycm9ycyA/IDIgOiAoJGlzU3RyaWN0ICYmICR3YXJuaW5ncyA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSBtYXgoJGRlcENvZGUsICRleGl0Q29kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21tYW5kRXZlbnQgPSBuZXcgQ29tbWFuZEV2ZW50KFBsdWdpbkV2ZW50czo6Q09NTUFORCwgJ3ZhbGlkYXRlJywgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkZXZlbnRDb2RlID0gJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgcmV0dXJuIG1heCgkZXZlbnRDb2RlLCAkZXhpdENvZGUpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gb3V0cHV0UmVzdWx0KCRpbywgJG5hbWUsICYkZXJyb3JzLCAmJHdhcm5pbmdzLCAkY2hlY2tQdWJsaXNoID0gZmFsc2UsICRwdWJsaXNoRXJyb3JzID0gYXJyYXkoKSwgJGNoZWNrTG9jayA9IGZhbHNlLCAkbG9ja0Vycm9ycyA9IGFycmF5KCksICRwcmludFNjaGVtYVVybCA9IGZhbHNlKQogICAgewogICAgICAgICRkb1ByaW50U2NoZW1hVXJsID0gZmFsc2U7CgogICAgICAgIGlmICgkZXJyb3JzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPicgLiAkbmFtZSAuICcgaXMgaW52YWxpZCwgdGhlIGZvbGxvd2luZyBlcnJvcnMvd2FybmluZ3Mgd2VyZSBmb3VuZDo8L2Vycm9yPicpOwogICAgICAgIH0gZWxzZWlmICgkcHVibGlzaEVycm9ycykgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxpbmZvPicgLiAkbmFtZSAuICcgaXMgdmFsaWQgZm9yIHNpbXBsZSB1c2FnZSB3aXRoIGNvbXBvc2VyIGJ1dCBoYXM8L2luZm8+Jyk7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+c3RyaWN0IGVycm9ycyB0aGF0IG1ha2UgaXQgdW5hYmxlIHRvIGJlIHB1Ymxpc2hlZCBhcyBhIHBhY2thZ2U6PC9pbmZvPicpOwogICAgICAgICAgICAkZG9QcmludFNjaGVtYVVybCA9ICRwcmludFNjaGVtYVVybDsKICAgICAgICB9IGVsc2VpZiAoJHdhcm5pbmdzKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+JyAuICRuYW1lIC4gJyBpcyB2YWxpZCwgYnV0IHdpdGggYSBmZXcgd2FybmluZ3M8L2luZm8+Jyk7CiAgICAgICAgICAgICRkb1ByaW50U2NoZW1hVXJsID0gJHByaW50U2NoZW1hVXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpby0+d3JpdGUoJzxpbmZvPicgLiAkbmFtZSAuICcgaXMgdmFsaWQ8L2luZm8+Jyk7CiAgICAgICAgICAgIC8vIGlmICgkbG9ja0Vycm9ycykgdGhlbiB0aGV5IHdpbGwgYmUgZGlzcGxheWVkIGJlbG93CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRvUHJpbnRTY2hlbWFVcmwpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5TZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzA0LXNjaGVtYS5tZCBmb3IgZGV0YWlscyBvbiB0aGUgc2NoZW1hPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgZXhpdCBjb2RlIHRvIDEgaW4gY2FzZSAtLXN0cmljdCBhbmQgLS1uby1jaGVjay1wdWJsaXNoLy0tbm8tY2hlY2stbG9jayBhcmUgY29tYmluZWQKICAgICAgICAkZXh0cmFXYXJuaW5ncyA9IGFycmF5KCk7CgogICAgICAgIC8vIElmIGNoZWNraW5nIHB1Ymxpc2ggZXJyb3JzLCBkaXNwbGF5IHRoZW0gYXMgZXJyb3JzLCBvdGhlcndpc2UganVzdCBzaG93IHRoZW0gYXMgd2FybmluZ3MKICAgICAgICBpZiAoJGNoZWNrUHVibGlzaCkgewogICAgICAgICAgICAkZXJyb3JzID0gYXJyYXlfbWVyZ2UoJGVycm9ycywgJHB1Ymxpc2hFcnJvcnMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRleHRyYVdhcm5pbmdzID0gYXJyYXlfbWVyZ2UoJGV4dHJhV2FybmluZ3MsICRwdWJsaXNoRXJyb3JzKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIGNoZWNraW5nIGxvY2sgZXJyb3JzLCBkaXNwbGF5IHRoZW0gYXMgZXJyb3JzLCBvdGhlcndpc2UganVzdCBzaG93IHRoZW0gYXMgd2FybmluZ3MKICAgICAgICBpZiAoJGNoZWNrTG9jaykgewogICAgICAgICAgICAkZXJyb3JzID0gYXJyYXlfbWVyZ2UoJGVycm9ycywgJGxvY2tFcnJvcnMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRleHRyYVdhcm5pbmdzID0gYXJyYXlfbWVyZ2UoJGV4dHJhV2FybmluZ3MsICRsb2NrRXJyb3JzKTsKICAgICAgICB9CgogICAgICAgICRtZXNzYWdlcyA9IGFycmF5KAogICAgICAgICAgICAnZXJyb3InID0+ICRlcnJvcnMsCiAgICAgICAgICAgICd3YXJuaW5nJyA9PiBhcnJheV9tZXJnZSgkd2FybmluZ3MsICRleHRyYVdhcm5pbmdzKSwKICAgICAgICApOwoKICAgICAgICBmb3JlYWNoICgkbWVzc2FnZXMgYXMgJHN0eWxlID0+ICRtc2dzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtc2dzIGFzICRtc2cpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPCcgLiAkc3R5bGUgLiAnPicgLiAkbXNnIC4gJzwvJyAuICRzdHlsZSAuICc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxJbnN0YWxsZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgUnlhbiBXZWF2ZXIgPHJ5YW5Aa25wbGFicy5jb20+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBJbnN0YWxsQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnaW5zdGFsbCcpCiAgICAgICAgICAgIC0+c2V0QWxpYXNlcyhhcnJheSgnaScpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdJbnN0YWxscyB0aGUgcHJvamVjdCBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgY29tcG9zZXIubG9jayBmaWxlIGlmIHByZXNlbnQsIG9yIGZhbGxzIGJhY2sgb24gdGhlIGNvbXBvc2VyLmpzb24uJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IGV2ZW4gZm9yIGRldiB2ZXJzaW9ucy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZHJ5LXJ1bicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT3V0cHV0cyB0aGUgb3BlcmF0aW9ucyBidXQgd2lsbCBub3QgZXhlY3V0ZSBhbnl0aGluZyAoaW1wbGljaXRseSBlbmFibGVzIC0tdmVyYm9zZSkuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RldicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnREVQUkVDQVRFRDogRW5hYmxlcyBpbnN0YWxsYXRpb24gb2YgcmVxdWlyZS1kZXYgcGFja2FnZXMgKGVuYWJsZWQgYnkgZGVmYXVsdCwgb25seSBwcmVzZW50IGZvciBCQykuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXN1Z2dlc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IFRoaXMgZmxhZyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1kZXYnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc2FibGVzIGluc3RhbGxhdGlvbiBvZiByZXF1aXJlLWRldiBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tYXV0b2xvYWRlcicsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2tpcHMgYXV0b2xvYWRlciBnZW5lcmF0aW9uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXNjcmlwdHMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXBzIHRoZSBleGVjdXRpb24gb2YgYWxsIHNjcmlwdHMgZGVmaW5lZCBpbiBjb21wb3Nlci5qc29uIGZpbGUuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXByb2dyZXNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3Qgb3V0cHV0IGRvd25sb2FkIHByb2dyZXNzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1pbnN0YWxsJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3QgdXNlLCBvbmx5IGRlZmluZWQgaGVyZSB0byBjYXRjaCBtaXN1c2Ugb2YgdGhlIGluc3RhbGwgY29tbWFuZC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndmVyYm9zZScsICd2fHZ2fHZ2dicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnU2hvd3MgbW9yZSBkZXRhaWxzIGluY2x1ZGluZyBuZXcgY29tbWl0cyBwdWxsZWQgaW4gd2hlbiB1cGRhdGluZyBwYWNrYWdlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZSBhdXRvbG9hZGVyIGR1cmluZyBhdXRvbG9hZGVyIGR1bXAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBdXRvbG9hZCBjbGFzc2VzIGZyb20gdGhlIGNsYXNzbWFwIG9ubHkuIEltcGxpY2l0bHkgZW5hYmxlcyBgLS1vcHRpbWl6ZS1hdXRvbG9hZGVyYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1VzZSBhIGN1c3RvbSBwcmVmaXggZm9yIHRoZSBBUEN1IGF1dG9sb2FkZXIgY2FjaGUuIEltcGxpY2l0bHkgZW5hYmxlcyAtLWFwY3UtYXV0b2xvYWRlcicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIGEgc3BlY2lmaWMgcGxhdGZvcm0gcmVxdWlyZW1lbnQgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ3BhY2thZ2VzJywgSW5wdXRBcmd1bWVudDo6SVNfQVJSQVkgfCBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCwgJ1Nob3VsZCBub3QgYmUgcHJvdmlkZWQsIHVzZSBjb21wb3NlciByZXF1aXJlIGluc3RlYWQgdG8gYWRkIGEgZ2l2ZW4gcGFja2FnZSB0byBjb21wb3Nlci5qc29uLicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPmluc3RhbGw8L2luZm8+IGNvbW1hbmQgcmVhZHMgdGhlIGNvbXBvc2VyLmxvY2sgZmlsZSBmcm9tCnRoZSBjdXJyZW50IGRpcmVjdG9yeSwgcHJvY2Vzc2VzIGl0LCBhbmQgZG93bmxvYWRzIGFuZCBpbnN0YWxscyBhbGwgdGhlCmxpYnJhcmllcyBhbmQgZGVwZW5kZW5jaWVzIG91dGxpbmVkIGluIHRoYXQgZmlsZS4gSWYgdGhlIGZpbGUgZG9lcyBub3QKZXhpc3QgaXQgd2lsbCBsb29rIGZvciBjb21wb3Nlci5qc29uIGFuZCBkbyB0aGUgc2FtZS4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIGluc3RhbGw8L2luZm8+CgpSZWFkIG1vcmUgYXQgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvZG9jLzAzLWNsaS5tZCNpbnN0YWxsLWkKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2RldicpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gIi0tZGV2Ii4gSXQgaGFzIG5vIGVmZmVjdCBhbmQgd2lsbCBicmVhayBpbiBDb21wb3NlciAzLjwvd2FybmluZz4nKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1zdWdnZXN0JykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Zb3UgYXJlIHVzaW5nIHRoZSBkZXByZWNhdGVkIG9wdGlvbiAiLS1uby1zdWdnZXN0Ii4gSXQgaGFzIG5vIGVmZmVjdCBhbmQgd2lsbCBicmVhayBpbiBDb21wb3NlciAzLjwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkYXJncyA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+SW52YWxpZCBhcmd1bWVudCAnLmltcGxvZGUoJyAnLCAkYXJncykuJy4gVXNlICJjb21wb3NlciByZXF1aXJlICcuaW1wbG9kZSgnICcsICRhcmdzKS4nIiBpbnN0ZWFkIHRvIGFkZCBwYWNrYWdlcyB0byB5b3VyIGNvbXBvc2VyLmpzb24uPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1pbnN0YWxsJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+SW52YWxpZCBvcHRpb24gIi0tbm8taW5zdGFsbCIuIFVzZSAiY29tcG9zZXIgdXBkYXRlIC0tbm8taW5zdGFsbCIgaW5zdGVhZCBpZiB5b3UgYXJlIHRyeWluZyB0byB1cGRhdGUgdGhlIGNvbXBvc2VyLmxvY2sgZmlsZS48L2Vycm9yPicpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAkY29tcG9zZXIgPSAkdGhpcy0+Z2V0Q29tcG9zZXIodHJ1ZSwgJGlucHV0LT5nZXRPcHRpb24oJ25vLXBsdWdpbnMnKSk7CgogICAgICAgIGlmICgoISRjb21wb3Nlci0+Z2V0TG9ja2VyKCkgfHwgISRjb21wb3Nlci0+Z2V0TG9ja2VyKCktPmlzTG9ja2VkKCkpICYmICFIdHRwRG93bmxvYWRlcjo6aXNDdXJsRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+Q29tcG9zZXIgaXMgb3BlcmF0aW5nIHNpZ25pZmljYW50bHkgc2xvd2VyIHRoYW4gbm9ybWFsIGJlY2F1c2UgeW91IGRvIG5vdCBoYXZlIHRoZSBQSFAgY3VybCBleHRlbnNpb24gZW5hYmxlZC48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICAkY29tbWFuZEV2ZW50ID0gbmV3IENvbW1hbmRFdmVudChQbHVnaW5FdmVudHM6OkNPTU1BTkQsICdpbnN0YWxsJywgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5kaXNwYXRjaCgkY29tbWFuZEV2ZW50LT5nZXROYW1lKCksICRjb21tYW5kRXZlbnQpOwoKICAgICAgICAkaW5zdGFsbCA9IEluc3RhbGxlcjo6Y3JlYXRlKCRpbywgJGNvbXBvc2VyKTsKCiAgICAgICAgJGNvbmZpZyA9ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCk7CiAgICAgICAgbGlzdCgkcHJlZmVyU291cmNlLCAkcHJlZmVyRGlzdCkgPSAkdGhpcy0+Z2V0UHJlZmVycmVkSW5zdGFsbE9wdGlvbnMoJGNvbmZpZywgJGlucHV0KTsKCiAgICAgICAgJG9wdGltaXplID0gJGlucHV0LT5nZXRPcHRpb24oJ29wdGltaXplLWF1dG9sb2FkZXInKSB8fCAkY29uZmlnLT5nZXQoJ29wdGltaXplLWF1dG9sb2FkZXInKTsKICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbmZpZy0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgJGFwY3VQcmVmaXggPSAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcpOwogICAgICAgICRhcGN1ID0gJGFwY3VQcmVmaXggIT09IG51bGwgfHwgJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlcicpIHx8ICRjb25maWctPmdldCgnYXBjdS1hdXRvbG9hZGVyJyk7CgogICAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSAkaW5wdXQtPmdldE9wdGlvbignaWdub3JlLXBsYXRmb3JtLXJlcXMnKSA/OiAoJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXEnKSA/OiBmYWxzZSk7CgogICAgICAgICRjb21wb3Nlci0+Z2V0SW5zdGFsbGF0aW9uTWFuYWdlcigpLT5zZXRPdXRwdXRQcm9ncmVzcyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXByb2dyZXNzJykpOwoKICAgICAgICAkaW5zdGFsbAogICAgICAgICAgICAtPnNldERyeVJ1bigkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpKQogICAgICAgICAgICAtPnNldFZlcmJvc2UoJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KQogICAgICAgICAgICAtPnNldERldk1vZGUoISRpbnB1dC0+Z2V0T3B0aW9uKCduby1kZXYnKSkKICAgICAgICAgICAgLT5zZXREdW1wQXV0b2xvYWRlcighJGlucHV0LT5nZXRPcHRpb24oJ25vLWF1dG9sb2FkZXInKSkKICAgICAgICAgICAgLT5zZXRSdW5TY3JpcHRzKCEkaW5wdXQtPmdldE9wdGlvbignbm8tc2NyaXB0cycpKQogICAgICAgICAgICAtPnNldE9wdGltaXplQXV0b2xvYWRlcigkb3B0aW1pemUpCiAgICAgICAgICAgIC0+c2V0Q2xhc3NNYXBBdXRob3JpdGF0aXZlKCRhdXRob3JpdGF0aXZlKQogICAgICAgICAgICAtPnNldEFwY3VBdXRvbG9hZGVyKCRhcGN1LCAkYXBjdVByZWZpeCkKICAgICAgICAgICAgLT5zZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgICAgIDsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCduby1wbHVnaW5zJykpIHsKICAgICAgICAgICAgJGluc3RhbGwtPmRpc2FibGVQbHVnaW5zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGluc3RhbGwtPnJ1bigpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIE5pZWxzIEtldXJlbnRqZXMgPG5pZWxzLmtldXJlbnRqZXNAb21pbmVzLmNvbT4KICovCmNsYXNzIFByb2hpYml0c0NvbW1hbmQgZXh0ZW5kcyBCYXNlRGVwZW5kZW5jeUNvbW1hbmQKewogICAgLyoqCiAgICAgKiBDb25maWd1cmUgY29tbWFuZCBtZXRhZGF0YS4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbmZpZ3VyZSgpCiAgICB7CiAgICAgICAgcGFyZW50Ojpjb25maWd1cmUoKTsKCiAgICAgICAgJHRoaXMKICAgICAgICAgICAgLT5zZXROYW1lKCdwcm9oaWJpdHMnKQogICAgICAgICAgICAtPnNldEFsaWFzZXMoYXJyYXkoJ3doeS1ub3QnKSkKICAgICAgICAgICAgLT5zZXREZXNjcmlwdGlvbignU2hvd3Mgd2hpY2ggcGFja2FnZXMgcHJldmVudCB0aGUgZ2l2ZW4gcGFja2FnZSBmcm9tIGJlaW5nIGluc3RhbGxlZC4nKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKRGlzcGxheXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgd2h5IGEgcGFja2FnZSBjYW5ub3QgYmUgaW5zdGFsbGVkLgoKPGluZm8+cGhwIGNvbXBvc2VyLnBoYXIgcHJvaGliaXRzIGNvbXBvc2VyL2NvbXBvc2VyPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjcHJvaGliaXRzLXdoeS1ub3QtCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtICBJbnB1dEludGVyZmFjZSAgJGlucHV0CiAgICAgKiBAcGFyYW0gIE91dHB1dEludGVyZmFjZSAkb3V0cHV0CiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIHJldHVybiBwYXJlbnQ6OmRvRXhlY3V0ZSgkaW5wdXQsICRvdXRwdXQsIHRydWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbW1hbmQ7Cgp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XFN0cmluZ0lucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEdsb2JhbENvbW1hbmQgZXh0ZW5kcyBCYXNlQ29tbWFuZAp7CiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2dsb2JhbCcpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0FsbG93cyBydW5uaW5nIGNvbW1hbmRzIGluIHRoZSBnbG9iYWwgY29tcG9zZXIgZGlyICgkQ09NUE9TRVJfSE9NRSkuJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2NvbW1hbmQtbmFtZScsIElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnYXJncycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICcnKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLT5zZXRIZWxwKAogICAgICAgICAgICAgICAgPDw8RU9UClVzZSB0aGlzIGNvbW1hbmQgYXMgYSB3cmFwcGVyIHRvIHJ1biBvdGhlciBDb21wb3NlciBjb21tYW5kcwp3aXRoaW4gdGhlIGdsb2JhbCBjb250ZXh0IG9mIENPTVBPU0VSX0hPTUUuCgpZb3UgY2FuIHVzZSB0aGlzIHRvIGluc3RhbGwgQ0xJIHV0aWxpdGllcyBnbG9iYWxseSwgYWxsIHlvdSBuZWVkCmlzIHRvIGFkZCB0aGUgQ09NUE9TRVJfSE9NRS92ZW5kb3IvYmluIGRpciB0byB5b3VyIFBBVEggZW52IHZhci4KCkNPTVBPU0VSX0hPTUUgaXMgYzpcVXNlcnNcPHVzZXI+XEFwcERhdGFcUm9hbWluZ1xDb21wb3NlciBvbiBXaW5kb3dzCmFuZCAvaG9tZS88dXNlcj4vLmNvbXBvc2VyIG9uIHVuaXggc3lzdGVtcy4KCklmIHlvdXIgc3lzdGVtIHVzZXMgZnJlZWRlc2t0b3Aub3JnIHN0YW5kYXJkcywgdGhlbiBpdCB3aWxsIGZpcnN0IGNoZWNrClhER19DT05GSUdfSE9NRSBvciBkZWZhdWx0IHRvIC9ob21lLzx1c2VyPi8uY29uZmlnL2NvbXBvc2VyCgpOb3RlOiBUaGlzIHBhdGggbWF5IHZhcnkgZGVwZW5kaW5nIG9uIGN1c3RvbWl6YXRpb25zIHRvIGJpbi1kaXIgaW4KY29tcG9zZXIuanNvbiBvciB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYWJsZSBDT01QT1NFUl9CSU5fRElSLgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjZ2xvYmFsCkVPVAogICAgICAgICAgICApCiAgICAgICAgOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBydW4oSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAvLyBleHRyYWN0IHJlYWwgY29tbWFuZCBuYW1lCiAgICAgICAgJHRva2VucyA9IHByZWdfc3BsaXQoJ3tccyt9JywgJGlucHV0LT5fX3RvU3RyaW5nKCkpOwogICAgICAgICRhcmdzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdG9rZW5zIGFzICR0b2tlbikgewogICAgICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlblswXSAhPT0gJy0nKSB7CiAgICAgICAgICAgICAgICAkYXJnc1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRhcmdzKSA+PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHNob3cgaGVscCBmb3IgdGhpcyBjb21tYW5kIGlmIG5vIGNvbW1hbmQgd2FzIGZvdW5kCiAgICAgICAgaWYgKGNvdW50KCRhcmdzKSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmVudDo6cnVuKCRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgQ09NUE9TRVIgZW52IHZhciBzaG91bGQgbm90IGFwcGx5IHRvIHRoZSBnbG9iYWwgZXhlY3V0aW9uIHNjb3BlCiAgICAgICAgaWYgKGdldGVudignQ09NUE9TRVInKSkgewogICAgICAgICAgICBwdXRlbnYoJ0NPTVBPU0VSJyk7CiAgICAgICAgICAgIHVuc2V0KCRfU0VSVkVSWydDT01QT1NFUiddKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoYW5nZSB0byBnbG9iYWwgZGlyCiAgICAgICAgJGNvbmZpZyA9IEZhY3Rvcnk6OmNyZWF0ZUNvbmZpZygpOwogICAgICAgICRob21lID0gJGNvbmZpZy0+Z2V0KCdob21lJyk7CgogICAgICAgIGlmICghaXNfZGlyKCRob21lKSkgewogICAgICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICAgICAkZnMtPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkaG9tZSk7CiAgICAgICAgICAgIGlmICghaXNfZGlyKCRob21lKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgY3JlYXRlIGhvbWUgZGlyZWN0b3J5Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGNoZGlyKCRob21lKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHN3aXRjaCB0byBob21lIGRpcmVjdG9yeSAiJy4kaG9tZS4nIicsIDAsICRlKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmdldElPKCktPndyaXRlRXJyb3IoJzxpbmZvPkNoYW5nZWQgY3VycmVudCBkaXJlY3RvcnkgdG8gJy4kaG9tZS4nPC9pbmZvPicpOwoKICAgICAgICAvLyBjcmVhdGUgbmV3IGlucHV0IHdpdGhvdXQgImdsb2JhbCIgY29tbWFuZCBwcmVmaXgKICAgICAgICAkaW5wdXQgPSBuZXcgU3RyaW5nSW5wdXQocHJlZ19yZXBsYWNlKCd7XGJnKD86bCg/Om8oPzpiKD86YSg/OmwpPyk/KT8pPyk/XGJ9JywgJycsICRpbnB1dC0+X190b1N0cmluZygpLCAxKSk7CiAgICAgICAgJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPnJlc2V0Q29tcG9zZXIoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLT5ydW4oJGlucHV0LCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUHJveHlDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxDb21tYW5kOwoKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxGYWN0b3J5Owp1c2UgQ29tcG9zZXJcSW5zdGFsbGVyOwp1c2UgQ29tcG9zZXJcSnNvblxKc29uRmlsZTsKdXNlIENvbXBvc2VyXEpzb25cSnNvbk1hbmlwdWxhdG9yOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXExvYWRlclxBcnJheUxvYWRlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxQbHVnaW5cQ29tbWFuZEV2ZW50Owp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcQ29tcG9zaXRlUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwoKLyoqCiAqIEBhdXRob3IgSsOpcsOpbXkgUm9tZXkgPGplcmVteUBmcmVlLWFnZW50LmZyPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBSZXF1aXJlQ29tbWFuZCBleHRlbmRzIEluaXRDb21tYW5kCnsKICAgIHByaXZhdGUgJG5ld2x5Q3JlYXRlZDsKICAgIHByaXZhdGUgJGZpcnN0UmVxdWlyZTsKICAgIHByaXZhdGUgJGpzb247CiAgICBwcml2YXRlICRmaWxlOwogICAgcHJpdmF0ZSAkY29tcG9zZXJCYWNrdXA7CiAgICAvKiogQHZhciBzdHJpbmcgZmlsZSBuYW1lICovCiAgICBwcml2YXRlICRsb2NrOwogICAgLyoqIEB2YXIgP3N0cmluZyBjb250ZW50cyBiZWZvcmUgbW9kaWZpY2F0aW9uIGlmIHRoZSBsb2NrIGZpbGUgZXhpc3RzICovCiAgICBwcml2YXRlICRsb2NrQmFja3VwOwoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgncmVxdWlyZScpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0FkZHMgcmVxdWlyZWQgcGFja2FnZXMgdG8geW91ciBjb21wb3Nlci5qc29uIGFuZCBpbnN0YWxscyB0aGVtLicpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbihhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCdwYWNrYWdlcycsIElucHV0QXJndW1lbnQ6OklTX0FSUkFZIHwgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwsICdPcHRpb25hbCBwYWNrYWdlIG5hbWUgY2FuIGFsc28gaW5jbHVkZSBhIHZlcnNpb24gY29uc3RyYWludCwgZS5nLiBmb28vYmFyIG9yIGZvby9iYXI6MS4wLjAgb3IgZm9vL2Jhcj0xLjAuMCBvciAiZm9vL2JhciAxLjAuMCInKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBZGQgcmVxdWlyZW1lbnQgdG8gcmVxdWlyZS1kZXYuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2RyeS1ydW4nLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ091dHB1dHMgdGhlIG9wZXJhdGlvbnMgYnV0IHdpbGwgbm90IGV4ZWN1dGUgYW55dGhpbmcgKGltcGxpY2l0bHkgZW5hYmxlcyAtLXZlcmJvc2UpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc291cmNlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBzb3VyY2VzIHdoZW4gcG9zc2libGUsIGluY2x1ZGluZyBWQ1MgaW5mb3JtYXRpb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3ByZWZlci1kaXN0JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZXMgaW5zdGFsbGF0aW9uIGZyb20gcGFja2FnZSBkaXN0IGV2ZW4gZm9yIGRldiB2ZXJzaW9ucy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZml4ZWQnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1dyaXRlIGZpeGVkIHZlcnNpb24gdG8gdGhlIGNvbXBvc2VyLmpzb24uJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXN1Z2dlc3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RFUFJFQ0FURUQ6IFRoaXMgZmxhZyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1wcm9ncmVzcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IG91dHB1dCBkb3dubG9hZCBwcm9ncmVzcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignbm8tdXBkYXRlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlcyB0aGUgYXV0b21hdGljIHVwZGF0ZSBvZiB0aGUgZGVwZW5kZW5jaWVzIChpbXBsaWVzIC0tbm8taW5zdGFsbCkuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLWluc3RhbGwnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NraXAgdGhlIGluc3RhbGwgc3RlcCBhZnRlciB1cGRhdGluZyB0aGUgY29tcG9zZXIubG9jayBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCduby1zY3JpcHRzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdTa2lwcyB0aGUgZXhlY3V0aW9uIG9mIGFsbCBzY3JpcHRzIGRlZmluZWQgaW4gY29tcG9zZXIuanNvbiBmaWxlLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUtbm8tZGV2JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSdW4gdGhlIGRlcGVuZGVuY3kgdXBkYXRlIHdpdGggdGhlIC0tbm8tZGV2IG9wdGlvbi4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJywgJ3cnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0FsbG93cyBpbmhlcml0ZWQgZGVwZW5kZW5jaWVzIHRvIGJlIHVwZGF0ZWQsIGV4Y2VwdCB0aG9zZSB0aGF0IGFyZSByb290IHJlcXVpcmVtZW50cy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigndXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycsICdXJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBbGxvd3MgYWxsIGluaGVyaXRlZCBkZXBlbmRlbmNpZXMgdG8gYmUgdXBkYXRlZCwgaW5jbHVkaW5nIHRob3NlIHRoYXQgYXJlIHJvb3QgcmVxdWlyZW1lbnRzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd3aXRoLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxpYXMgZm9yIC0tdXBkYXRlLXdpdGgtZGVwZW5kZW5jaWVzJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnQWxpYXMgZm9yIC0tdXBkYXRlLXdpdGgtYWxsLWRlcGVuZGVuY2llcycpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX1JFUVVJUkVEIHwgSW5wdXRPcHRpb246OlZBTFVFX0lTX0FSUkFZLCAnSWdub3JlIGEgc3BlY2lmaWMgcGxhdGZvcm0gcmVxdWlyZW1lbnQgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxcycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSWdub3JlIGFsbCBwbGF0Zm9ybSByZXF1aXJlbWVudHMgKHBocCAmIGV4dC0gcGFja2FnZXMpLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdwcmVmZXItc3RhYmxlJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdQcmVmZXIgc3RhYmxlIHZlcnNpb25zIG9mIGRlcGVuZGVuY2llcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJlZmVyLWxvd2VzdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJlZmVyIGxvd2VzdCB2ZXJzaW9ucyBvZiBkZXBlbmRlbmNpZXMuJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ3NvcnQtcGFja2FnZXMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1NvcnRzIHBhY2thZ2VzIHdoZW4gYWRkaW5nL3VwZGF0aW5nIGEgbmV3IGRlcGVuZGVuY3knKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignb3B0aW1pemUtYXV0b2xvYWRlcicsICdvJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdPcHRpbWl6ZSBhdXRvbG9hZGVyIGR1cmluZyBhdXRvbG9hZGVyIGR1bXAnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignY2xhc3NtYXAtYXV0aG9yaXRhdGl2ZScsICdhJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdBdXRvbG9hZCBjbGFzc2VzIGZyb20gdGhlIGNsYXNzbWFwIG9ubHkuIEltcGxpY2l0bHkgZW5hYmxlcyBgLS1vcHRpbWl6ZS1hdXRvbG9hZGVyYC4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdVc2UgQVBDdSB0byBjYWNoZSBmb3VuZC9ub3QtZm91bmQgY2xhc3Nlcy4nKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1VzZSBhIGN1c3RvbSBwcmVmaXggZm9yIHRoZSBBUEN1IGF1dG9sb2FkZXIgY2FjaGUuIEltcGxpY2l0bHkgZW5hYmxlcyAtLWFwY3UtYXV0b2xvYWRlcicpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIHJlcXVpcmUgY29tbWFuZCBhZGRzIHJlcXVpcmVkIHBhY2thZ2VzIHRvIHlvdXIgY29tcG9zZXIuanNvbiBhbmQgaW5zdGFsbHMgdGhlbS4KCklmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHBhY2thZ2UsIGNvbXBvc2VyIHdpbGwgcHJvbXB0IHlvdSB0byBzZWFyY2ggZm9yIGEgcGFja2FnZSwgYW5kIGdpdmVuIHJlc3VsdHMsIHByb3ZpZGUgYSBsaXN0IG9mCm1hdGNoZXMgdG8gcmVxdWlyZS4KCklmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHZlcnNpb24gY29uc3RyYWludCwgY29tcG9zZXIgd2lsbCBjaG9vc2UgYSBzdWl0YWJsZSBvbmUgYmFzZWQgb24gdGhlIGF2YWlsYWJsZSBwYWNrYWdlIHZlcnNpb25zLgoKSWYgeW91IGRvIG5vdCB3YW50IHRvIGluc3RhbGwgdGhlIG5ldyBkZXBlbmRlbmNpZXMgaW1tZWRpYXRlbHkgeW91IGNhbiBjYWxsIGl0IHdpdGggLS1uby11cGRhdGUKClJlYWQgbW9yZSBhdCBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDMtY2xpLm1kI3JlcXVpcmUKRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwY250bF9hc3luY19zaWduYWxzJykgJiYgZnVuY3Rpb25fZXhpc3RzKCdwY250bF9zaWduYWwnKSkgewogICAgICAgICAgICBwY250bF9hc3luY19zaWduYWxzKHRydWUpOwogICAgICAgICAgICBwY250bF9zaWduYWwoU0lHSU5ULCBhcnJheSgkdGhpcywgJ3JldmVydENvbXBvc2VyRmlsZScpKTsKICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR1RFUk0sIGFycmF5KCR0aGlzLCAncmV2ZXJ0Q29tcG9zZXJGaWxlJykpOwogICAgICAgICAgICBwY250bF9zaWduYWwoU0lHSFVQLCBhcnJheSgkdGhpcywgJ3JldmVydENvbXBvc2VyRmlsZScpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maWxlID0gRmFjdG9yeTo6Z2V0Q29tcG9zZXJGaWxlKCk7CiAgICAgICAgJGlvID0gJHRoaXMtPmdldElPKCk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tc3VnZ2VzdCcpKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+WW91IGFyZSB1c2luZyB0aGUgZGVwcmVjYXRlZCBvcHRpb24gIi0tbm8tc3VnZ2VzdCIuIEl0IGhhcyBubyBlZmZlY3QgYW5kIHdpbGwgYnJlYWsgaW4gQ29tcG9zZXIgMy48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bmV3bHlDcmVhdGVkID0gIWZpbGVfZXhpc3RzKCR0aGlzLT5maWxlKTsKICAgICAgICBpZiAoJHRoaXMtPm5ld2x5Q3JlYXRlZCAmJiAhZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmZpbGUsICJ7XG59XG4iKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nLiR0aGlzLT5maWxlLicgY291bGQgbm90IGJlIGNyZWF0ZWQuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICAvLyBjaGVjayBmb3IgcmVhZGFiaWxpdHkgYnkgcmVhZGluZyB0aGUgZmlsZSBhcyBpc19yZWFkYWJsZSBjYW4gbm90IGJlIHRydXN0ZWQgb24gbmV0d29yay1tb3VudHMKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3Vlcy84MjMxIGFuZCBodHRwczovL2J1Z3MucGhwLm5ldC9idWcucGhwP2lkPTY4OTI2CiAgICAgICAgaWYgKCFpc19yZWFkYWJsZSgkdGhpcy0+ZmlsZSkgJiYgZmFsc2UgPT09IFNpbGVuY2VyOjpjYWxsKCdmaWxlX2dldF9jb250ZW50cycsICR0aGlzLT5maWxlKSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj4nLiR0aGlzLT5maWxlLicgaXMgbm90IHJlYWRhYmxlLjwvZXJyb3I+Jyk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlc2l6ZSgkdGhpcy0+ZmlsZSkgPT09IDApIHsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmZpbGUsICJ7XG59XG4iKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5qc29uID0gbmV3IEpzb25GaWxlKCR0aGlzLT5maWxlKTsKICAgICAgICAkdGhpcy0+bG9jayA9IEZhY3Rvcnk6OmdldExvY2tGaWxlKCR0aGlzLT5maWxlKTsKICAgICAgICAkdGhpcy0+Y29tcG9zZXJCYWNrdXAgPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+anNvbi0+Z2V0UGF0aCgpKTsKICAgICAgICAkdGhpcy0+bG9ja0JhY2t1cCA9IGZpbGVfZXhpc3RzKCR0aGlzLT5sb2NrKSA/IGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5sb2NrKSA6IG51bGw7CgogICAgICAgIC8vIGNoZWNrIGZvciB3cml0YWJpbGl0eSBieSB3cml0aW5nIHRvIHRoZSBmaWxlIGFzIGlzX3dyaXRhYmxlIGNhbiBub3QgYmUgdHJ1c3RlZCBvbiBuZXR3b3JrLW1vdW50cwogICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzgyMzEgYW5kIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9Njg5MjYKICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCR0aGlzLT5maWxlKSAmJiAhU2lsZW5jZXI6OmNhbGwoJ2ZpbGVfcHV0X2NvbnRlbnRzJywgJHRoaXMtPmZpbGUsICR0aGlzLT5jb21wb3NlckJhY2t1cCkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+Jy4kdGhpcy0+ZmlsZS4nIGlzIG5vdCB3cml0YWJsZS48L2Vycm9yPicpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ2ZpeGVkJykgPT09IHRydWUpIHsKICAgICAgICAgICAgJGNvbmZpZyA9ICR0aGlzLT5qc29uLT5yZWFkKCk7CgogICAgICAgICAgICAkcGFja2FnZVR5cGUgPSBlbXB0eSgkY29uZmlnWyd0eXBlJ10pID8gJ2xpYnJhcnknIDogJGNvbmZpZ1sndHlwZSddOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL3B1bGwvODMxMyNpc3N1ZWNvbW1lbnQtNTMyNjM3OTU1CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoJHBhY2thZ2VUeXBlICE9PSAncHJvamVjdCcpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPiItLWZpeGVkIiBvcHRpb24gaXMgYWxsb3dlZCBmb3IgInByb2plY3QiIHBhY2thZ2UgdHlwZXMgb25seSB0byBwcmV2ZW50IHBvc3NpYmxlIG1pc3VzZXMuPC9lcnJvcj4nKTsKCiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJGNvbmZpZ1sndHlwZSddKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPklmIHlvdXIgcGFja2FnZSBpcyBub3QgbGlicmFyeSwgeW91IHNob3VsZCBleHBsaWNpdGx5IHNwZWNpZnkgInR5cGUiIHBhcmFtZXRlciBpbiBjb21wb3Nlci5qc29uLjwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3Nlcih0cnVlLCAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpKTsKICAgICAgICAkcmVwb3MgPSAkY29tcG9zZXItPmdldFJlcG9zaXRvcnlNYW5hZ2VyKCktPmdldFJlcG9zaXRvcmllcygpOwoKICAgICAgICAkcGxhdGZvcm1PdmVycmlkZXMgPSAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3BsYXRmb3JtJykgPzogYXJyYXkoKTsKICAgICAgICAvLyBpbml0aWFsaXplICR0aGlzLT5yZXBvcyBhcyBpdCBpcyB1c2VkIGJ5IHRoZSBwYXJlbnQgSW5pdENvbW1hbmQKICAgICAgICAkdGhpcy0+cmVwb3MgPSBuZXcgQ29tcG9zaXRlUmVwb3NpdG9yeShhcnJheV9tZXJnZSgKICAgICAgICAgICAgYXJyYXkoJHBsYXRmb3JtUmVwbyA9IG5ldyBQbGF0Zm9ybVJlcG9zaXRvcnkoYXJyYXkoKSwgJHBsYXRmb3JtT3ZlcnJpZGVzKSksCiAgICAgICAgICAgICRyZXBvcwogICAgICAgICkpOwoKICAgICAgICBpZiAoJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldFByZWZlclN0YWJsZSgpKSB7CiAgICAgICAgICAgICRwcmVmZXJyZWRTdGFiaWxpdHkgPSAnc3RhYmxlJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcHJlZmVycmVkU3RhYmlsaXR5ID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRyZXF1aXJlbWVudHMgPSAkdGhpcy0+ZGV0ZXJtaW5lUmVxdWlyZW1lbnRzKAogICAgICAgICAgICAgICAgJGlucHV0LAogICAgICAgICAgICAgICAgJG91dHB1dCwKICAgICAgICAgICAgICAgICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3BhY2thZ2VzJyksCiAgICAgICAgICAgICAgICAkcGxhdGZvcm1SZXBvLAogICAgICAgICAgICAgICAgJHByZWZlcnJlZFN0YWJpbGl0eSwKICAgICAgICAgICAgICAgICEkaW5wdXQtPmdldE9wdGlvbignbm8tdXBkYXRlJyksCiAgICAgICAgICAgICAgICAkaW5wdXQtPmdldE9wdGlvbignZml4ZWQnKQogICAgICAgICAgICApOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5uZXdseUNyZWF0ZWQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignTm8gY29tcG9zZXIuanNvbiBwcmVzZW50IGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSAoJy4kdGhpcy0+ZmlsZS4nKSwgdGhpcyBtYXkgYmUgdGhlIGNhdXNlIG9mIHRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uLicsIDAsICRlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICAkcmVxdWlyZUtleSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICdyZXF1aXJlLWRldicgOiAncmVxdWlyZSc7CiAgICAgICAgJHJlbW92ZUtleSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdkZXYnKSA/ICdyZXF1aXJlJyA6ICdyZXF1aXJlLWRldic7CiAgICAgICAgJHJlcXVpcmVtZW50cyA9ICR0aGlzLT5mb3JtYXRSZXF1aXJlbWVudHMoJHJlcXVpcmVtZW50cyk7CgogICAgICAgIC8vIHZhbGlkYXRlIHJlcXVpcmVtZW50cyBmb3JtYXQKICAgICAgICAkdmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkcGFja2FnZSkgPT09ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKCc8ZXJyb3I+Um9vdCBwYWNrYWdlIFwnJXNcJyBjYW5ub3QgcmVxdWlyZSBpdHNlbGYgaW4gaXRzIGNvbXBvc2VyLmpzb248L2Vycm9yPicsICRwYWNrYWdlKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgJHNvcnRQYWNrYWdlcyA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdzb3J0LXBhY2thZ2VzJykgfHwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdzb3J0LXBhY2thZ2VzJyk7CgogICAgICAgICR0aGlzLT5maXJzdFJlcXVpcmUgPSAkdGhpcy0+bmV3bHlDcmVhdGVkOwogICAgICAgIGlmICghJHRoaXMtPmZpcnN0UmVxdWlyZSkgewogICAgICAgICAgICAkY29tcG9zZXJEZWZpbml0aW9uID0gJHRoaXMtPmpzb24tPnJlYWQoKTsKICAgICAgICAgICAgaWYgKGVtcHR5KCRjb21wb3NlckRlZmluaXRpb25bJ3JlcXVpcmUnXSkgJiYgZW1wdHkoJGNvbXBvc2VyRGVmaW5pdGlvblsncmVxdWlyZS1kZXYnXSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5maXJzdFJlcXVpcmUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoISRpbnB1dC0+Z2V0T3B0aW9uKCdkcnktcnVuJykgJiYgISR0aGlzLT51cGRhdGVGaWxlQ2xlYW5seSgkdGhpcy0+anNvbiwgJHJlcXVpcmVtZW50cywgJHJlcXVpcmVLZXksICRyZW1vdmVLZXksICRzb3J0UGFja2FnZXMpKSB7CiAgICAgICAgICAgICRjb21wb3NlckRlZmluaXRpb24gPSAkdGhpcy0+anNvbi0+cmVhZCgpOwogICAgICAgICAgICBmb3JlYWNoICgkcmVxdWlyZW1lbnRzIGFzICRwYWNrYWdlID0+ICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICAgICAkY29tcG9zZXJEZWZpbml0aW9uWyRyZXF1aXJlS2V5XVskcGFja2FnZV0gPSAkdmVyc2lvbjsKICAgICAgICAgICAgICAgIHVuc2V0KCRjb21wb3NlckRlZmluaXRpb25bJHJlbW92ZUtleV1bJHBhY2thZ2VdKTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZXJEZWZpbml0aW9uWyRyZW1vdmVLZXldKSAmJiBjb3VudCgkY29tcG9zZXJEZWZpbml0aW9uWyRyZW1vdmVLZXldKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRjb21wb3NlckRlZmluaXRpb25bJHJlbW92ZUtleV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5qc29uLT53cml0ZSgkY29tcG9zZXJEZWZpbml0aW9uKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGVFcnJvcignPGluZm8+Jy4kdGhpcy0+ZmlsZS4nIGhhcyBiZWVuICcuKCR0aGlzLT5uZXdseUNyZWF0ZWQgPyAnY3JlYXRlZCcgOiAndXBkYXRlZCcpLic8L2luZm8+Jyk7CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignbm8tdXBkYXRlJykpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvVXBkYXRlKCRpbnB1dCwgJG91dHB1dCwgJGlvLCAkcmVxdWlyZW1lbnRzLCAkcmVxdWlyZUtleSwgJHJlbW92ZUtleSk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkdGhpcy0+cmV2ZXJ0Q29tcG9zZXJGaWxlKGZhbHNlKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZG9VcGRhdGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgSU9JbnRlcmZhY2UgJGlvLCBhcnJheSAkcmVxdWlyZW1lbnRzLCAkcmVxdWlyZUtleSwgJHJlbW92ZUtleSkKICAgIHsKICAgICAgICAvLyBVcGRhdGUgcGFja2FnZXMKICAgICAgICAkdGhpcy0+cmVzZXRDb21wb3NlcigpOwogICAgICAgICRjb21wb3NlciA9ICR0aGlzLT5nZXRDb21wb3Nlcih0cnVlLCAkaW5wdXQtPmdldE9wdGlvbignbm8tcGx1Z2lucycpKTsKCiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdkcnktcnVuJykpIHsKICAgICAgICAgICAgJHJvb3RQYWNrYWdlID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgICAgICRsaW5rcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ3JlcXVpcmUnID0+ICRyb290UGFja2FnZS0+Z2V0UmVxdWlyZXMoKSwKICAgICAgICAgICAgICAgICdyZXF1aXJlLWRldicgPT4gJHJvb3RQYWNrYWdlLT5nZXREZXZSZXF1aXJlcygpLAogICAgICAgICAgICApOwogICAgICAgICAgICAkbG9hZGVyID0gbmV3IEFycmF5TG9hZGVyKCk7CiAgICAgICAgICAgICRuZXdMaW5rcyA9ICRsb2FkZXItPnBhcnNlTGlua3MoJHJvb3RQYWNrYWdlLT5nZXROYW1lKCksICRyb290UGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLCBCYXNlUGFja2FnZTo6JHN1cHBvcnRlZExpbmtUeXBlc1skcmVxdWlyZUtleV1bJ2Rlc2NyaXB0aW9uJ10sICRyZXF1aXJlbWVudHMpOwogICAgICAgICAgICAkbGlua3NbJHJlcXVpcmVLZXldID0gYXJyYXlfbWVyZ2UoJGxpbmtzWyRyZXF1aXJlS2V5XSwgJG5ld0xpbmtzKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVpcmVtZW50cyBhcyAkcGFja2FnZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgdW5zZXQoJGxpbmtzWyRyZW1vdmVLZXldWyRwYWNrYWdlXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJvb3RQYWNrYWdlLT5zZXRSZXF1aXJlcygkbGlua3NbJ3JlcXVpcmUnXSk7CiAgICAgICAgICAgICRyb290UGFja2FnZS0+c2V0RGV2UmVxdWlyZXMoJGxpbmtzWydyZXF1aXJlLWRldiddKTsKICAgICAgICB9CgogICAgICAgICR1cGRhdGVEZXZNb2RlID0gISRpbnB1dC0+Z2V0T3B0aW9uKCd1cGRhdGUtbm8tZGV2Jyk7CiAgICAgICAgJG9wdGltaXplID0gJGlucHV0LT5nZXRPcHRpb24oJ29wdGltaXplLWF1dG9sb2FkZXInKSB8fCAkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ29wdGltaXplLWF1dG9sb2FkZXInKTsKICAgICAgICAkYXV0aG9yaXRhdGl2ZSA9ICRpbnB1dC0+Z2V0T3B0aW9uKCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJykgfHwgJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdjbGFzc21hcC1hdXRob3JpdGF0aXZlJyk7CiAgICAgICAgJGFwY3VQcmVmaXggPSAkaW5wdXQtPmdldE9wdGlvbignYXBjdS1hdXRvbG9hZGVyLXByZWZpeCcpOwogICAgICAgICRhcGN1ID0gJGFwY3VQcmVmaXggIT09IG51bGwgfHwgJGlucHV0LT5nZXRPcHRpb24oJ2FwY3UtYXV0b2xvYWRlcicpIHx8ICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnYXBjdS1hdXRvbG9hZGVyJyk7CgogICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfT05MWV9MSVNURUQ7CiAgICAgICAgJGZsYWdzID0gJyc7CiAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1cGRhdGUtd2l0aC1hbGwtZGVwZW5kZW5jaWVzJykgfHwgJGlucHV0LT5nZXRPcHRpb24oJ3dpdGgtYWxsLWRlcGVuZGVuY2llcycpKSB7CiAgICAgICAgICAgICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBSZXF1ZXN0OjpVUERBVEVfTElTVEVEX1dJVEhfVFJBTlNJVElWRV9ERVBTOwogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLXdpdGgtYWxsLWRlcGVuZGVuY2llcyc7CiAgICAgICAgfSBlbHNlaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCd1cGRhdGUtd2l0aC1kZXBlbmRlbmNpZXMnKSB8fCAkaW5wdXQtPmdldE9wdGlvbignd2l0aC1kZXBlbmRlbmNpZXMnKSkgewogICAgICAgICAgICAkdXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gUmVxdWVzdDo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQU19OT19ST09UX1JFUVVJUkU7CiAgICAgICAgICAgICRmbGFncyAuPSAnIC0td2l0aC1kZXBlbmRlbmNpZXMnOwogICAgICAgIH0KCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5SdW5uaW5nIGNvbXBvc2VyIHVwZGF0ZSAnLmltcGxvZGUoJyAnLCBhcnJheV9rZXlzKCRyZXF1aXJlbWVudHMpKS4kZmxhZ3MuJzwvaW5mbz4nKTsKCiAgICAgICAgJGNvbW1hbmRFdmVudCA9IG5ldyBDb21tYW5kRXZlbnQoUGx1Z2luRXZlbnRzOjpDT01NQU5ELCAncmVxdWlyZScsICRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+ZGlzcGF0Y2goJGNvbW1hbmRFdmVudC0+Z2V0TmFtZSgpLCAkY29tbWFuZEV2ZW50KTsKCiAgICAgICAgJGNvbXBvc2VyLT5nZXRJbnN0YWxsYXRpb25NYW5hZ2VyKCktPnNldE91dHB1dFByb2dyZXNzKCEkaW5wdXQtPmdldE9wdGlvbignbm8tcHJvZ3Jlc3MnKSk7CgogICAgICAgICRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoJGlvLCAkY29tcG9zZXIpOwoKICAgICAgICAkaWdub3JlUGxhdGZvcm1SZXFzID0gJGlucHV0LT5nZXRPcHRpb24oJ2lnbm9yZS1wbGF0Zm9ybS1yZXFzJykgPzogKCRpbnB1dC0+Z2V0T3B0aW9uKCdpZ25vcmUtcGxhdGZvcm0tcmVxJykgPzogZmFsc2UpOwoKICAgICAgICAkaW5zdGFsbAogICAgICAgICAgICAtPnNldERyeVJ1bigkaW5wdXQtPmdldE9wdGlvbignZHJ5LXJ1bicpKQogICAgICAgICAgICAtPnNldFZlcmJvc2UoJGlucHV0LT5nZXRPcHRpb24oJ3ZlcmJvc2UnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJTb3VyY2UoJGlucHV0LT5nZXRPcHRpb24oJ3ByZWZlci1zb3VyY2UnKSkKICAgICAgICAgICAgLT5zZXRQcmVmZXJEaXN0KCRpbnB1dC0+Z2V0T3B0aW9uKCdwcmVmZXItZGlzdCcpKQogICAgICAgICAgICAtPnNldERldk1vZGUoJHVwZGF0ZURldk1vZGUpCiAgICAgICAgICAgIC0+c2V0UnVuU2NyaXB0cyghJGlucHV0LT5nZXRPcHRpb24oJ25vLXNjcmlwdHMnKSkKICAgICAgICAgICAgLT5zZXRPcHRpbWl6ZUF1dG9sb2FkZXIoJG9wdGltaXplKQogICAgICAgICAgICAtPnNldENsYXNzTWFwQXV0aG9yaXRhdGl2ZSgkYXV0aG9yaXRhdGl2ZSkKICAgICAgICAgICAgLT5zZXRBcGN1QXV0b2xvYWRlcigkYXBjdSwgJGFwY3VQcmVmaXgpCiAgICAgICAgICAgIC0+c2V0VXBkYXRlKHRydWUpCiAgICAgICAgICAgIC0+c2V0SW5zdGFsbCghJGlucHV0LT5nZXRPcHRpb24oJ25vLWluc3RhbGwnKSkKICAgICAgICAgICAgLT5zZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcykKICAgICAgICAgICAgLT5zZXRJZ25vcmVQbGF0Zm9ybVJlcXVpcmVtZW50cygkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgICAgICAgICAtPnNldFByZWZlclN0YWJsZSgkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLXN0YWJsZScpKQogICAgICAgICAgICAtPnNldFByZWZlckxvd2VzdCgkaW5wdXQtPmdldE9wdGlvbigncHJlZmVyLWxvd2VzdCcpKQogICAgICAgIDsKCiAgICAgICAgLy8gaWYgbm8gbG9jayBpcyBwcmVzZW50LCBvciB0aGUgZmlsZSBpcyBicmFuZCBuZXcsIHdlIGRvIG5vdCBkbyBhCiAgICAgICAgLy8gcGFydGlhbCB1cGRhdGUgYXMgdGhpcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBJbnN0YWxsZXIKICAgICAgICBpZiAoISR0aGlzLT5maXJzdFJlcXVpcmUgJiYgJGNvbXBvc2VyLT5nZXRMb2NrZXIoKS0+aXNMb2NrZWQoKSkgewogICAgICAgICAgICAkaW5zdGFsbC0+c2V0VXBkYXRlQWxsb3dMaXN0KGFycmF5X2tleXMoJHJlcXVpcmVtZW50cykpOwogICAgICAgIH0KCiAgICAgICAgJHN0YXR1cyA9ICRpbnN0YWxsLT5ydW4oKTsKICAgICAgICBpZiAoJHN0YXR1cyAhPT0gMCkgewogICAgICAgICAgICAkdGhpcy0+cmV2ZXJ0Q29tcG9zZXJGaWxlKGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3RhdHVzOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdXBkYXRlRmlsZUNsZWFubHkoJGpzb24sIGFycmF5ICRuZXcsICRyZXF1aXJlS2V5LCAkcmVtb3ZlS2V5LCAkc29ydFBhY2thZ2VzKQogICAgewogICAgICAgICRjb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRqc29uLT5nZXRQYXRoKCkpOwoKICAgICAgICAkbWFuaXB1bGF0b3IgPSBuZXcgSnNvbk1hbmlwdWxhdG9yKCRjb250ZW50cyk7CgogICAgICAgIGZvcmVhY2ggKCRuZXcgYXMgJHBhY2thZ2UgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCEkbWFuaXB1bGF0b3ItPmFkZExpbmsoJHJlcXVpcmVLZXksICRwYWNrYWdlLCAkY29uc3RyYWludCwgJHNvcnRQYWNrYWdlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRtYW5pcHVsYXRvci0+cmVtb3ZlU3ViTm9kZSgkcmVtb3ZlS2V5LCAkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG1hbmlwdWxhdG9yLT5yZW1vdmVNYWluS2V5SWZFbXB0eSgkcmVtb3ZlS2V5KTsKCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGpzb24tPmdldFBhdGgoKSwgJG1hbmlwdWxhdG9yLT5nZXRDb250ZW50cygpKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGludGVyYWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZXZlcnRDb21wb3NlckZpbGUoJGhhcmRFeGl0ID0gdHJ1ZSkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgaWYgKCR0aGlzLT5uZXdseUNyZWF0ZWQpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCJcbiIuJzxlcnJvcj5JbnN0YWxsYXRpb24gZmFpbGVkLCBkZWxldGluZyAnLiR0aGlzLT5maWxlLicuPC9lcnJvcj4nKTsKICAgICAgICAgICAgdW5saW5rKCR0aGlzLT5qc29uLT5nZXRQYXRoKCkpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPmxvY2spKSB7CiAgICAgICAgICAgICAgICB1bmxpbmsoJHRoaXMtPmxvY2spOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJG1zZyA9ICcgdG8gaXRzICc7CiAgICAgICAgICAgIGlmICgkdGhpcy0+bG9ja0JhY2t1cCkgewogICAgICAgICAgICAgICAgJG1zZyA9ICcgYW5kICcuJHRoaXMtPmxvY2suJyB0byB0aGVpciAnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigiXG4iLic8ZXJyb3I+SW5zdGFsbGF0aW9uIGZhaWxlZCwgcmV2ZXJ0aW5nICcuJHRoaXMtPmZpbGUuJG1zZy4nb3JpZ2luYWwgY29udGVudC48L2Vycm9yPicpOwogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkdGhpcy0+anNvbi0+Z2V0UGF0aCgpLCAkdGhpcy0+Y29tcG9zZXJCYWNrdXApOwogICAgICAgICAgICBpZiAoJHRoaXMtPmxvY2tCYWNrdXApIHsKICAgICAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCR0aGlzLT5sb2NrLCAkdGhpcy0+bG9ja0JhY2t1cCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkaGFyZEV4aXQpIHsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29tbWFuZDsKCnVzZSBDb21wb3NlclxDb21wb3NlcjsKdXNlIENvbXBvc2VyXEZhY3Rvcnk7CnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcU2VsZlVwZGF0ZVxLZXlzOwp1c2UgQ29tcG9zZXJcU2VsZlVwZGF0ZVxWZXJzaW9uczsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxGaWxlc3lzdGVtRXhjZXB0aW9uOwp1c2UgQ29tcG9zZXJcRG93bmxvYWRlclxUcmFuc3BvcnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CgovKioKICogQGF1dGhvciBJZ29yIFdpZWRsZXIgPGlnb3JAd2llZGxlci5jaD4KICogQGF1dGhvciBLZXZpbiBSYW4gPGtyYW5AYWRvYmUuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBTZWxmVXBkYXRlQ29tbWFuZCBleHRlbmRzIEJhc2VDb21tYW5kCnsKICAgIGNvbnN0IEhPTUVQQUdFID0gJ2dldGNvbXBvc2VyLm9yZyc7CiAgICBjb25zdCBPTERfSU5TVEFMTF9FWFQgPSAnLW9sZC5waGFyJzsKCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ3NlbGYtdXBkYXRlJykKICAgICAgICAgICAgLT5zZXRBbGlhc2VzKGFycmF5KCdzZWxmdXBkYXRlJykpCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ1VwZGF0ZXMgY29tcG9zZXIucGhhciB0byB0aGUgbGF0ZXN0IHZlcnNpb24uJykKICAgICAgICAgICAgLT5zZXREZWZpbml0aW9uKGFycmF5KAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyb2xsYmFjaycsICdyJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdSZXZlcnQgdG8gYW4gb2xkZXIgaW5zdGFsbGF0aW9uIG9mIGNvbXBvc2VyJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2NsZWFuLWJhY2t1cHMnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0RlbGV0ZSBvbGQgYmFja3VwcyBkdXJpbmcgYW4gdXBkYXRlLiBUaGlzIG1ha2VzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgY29tcG9zZXIgdGhlIG9ubHkgYmFja3VwIGF2YWlsYWJsZSBhZnRlciB0aGUgdXBkYXRlJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgndmVyc2lvbicsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIHZlcnNpb24gdG8gdXBkYXRlIHRvJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ25vLXByb2dyZXNzJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3Qgb3V0cHV0IGRvd25sb2FkIHByb2dyZXNzLicpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCd1cGRhdGUta2V5cycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnUHJvbXB0IHVzZXIgZm9yIGEga2V5IHVwZGF0ZScpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdzdGFibGUnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc3RhYmxlIGNoYW5uZWwnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncHJldmlldycsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2UgYW4gdXBkYXRlIHRvIHRoZSBwcmV2aWV3IGNoYW5uZWwnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc25hcHNob3QnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc25hcHNob3QgY2hhbm5lbCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCcxJywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdGb3JjZSBhbiB1cGRhdGUgdG8gdGhlIHN0YWJsZSBjaGFubmVsLCBidXQgb25seSB1c2UgMS54IHZlcnNpb25zJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJzInLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0ZvcmNlIGFuIHVwZGF0ZSB0byB0aGUgc3RhYmxlIGNoYW5uZWwsIGJ1dCBvbmx5IHVzZSAyLnggdmVyc2lvbnMnKSwKICAgICAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignc2V0LWNoYW5uZWwtb25seScsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnT25seSBzdG9yZSB0aGUgY2hhbm5lbCBhcyB0aGUgZGVmYXVsdCBvbmUgYW5kIHRoZW4gZXhpdCcpLAogICAgICAgICAgICApKQogICAgICAgICAgICAtPnNldEhlbHAoCiAgICAgICAgICAgICAgICA8PDxFT1QKVGhlIDxpbmZvPnNlbGYtdXBkYXRlPC9pbmZvPiBjb21tYW5kIGNoZWNrcyBnZXRjb21wb3Nlci5vcmcgZm9yIG5ld2VyCnZlcnNpb25zIG9mIGNvbXBvc2VyIGFuZCBpZiBmb3VuZCwgaW5zdGFsbHMgdGhlIGxhdGVzdC4KCjxpbmZvPnBocCBjb21wb3Nlci5waGFyIHNlbGYtdXBkYXRlPC9pbmZvPgoKUmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMy1jbGkubWQjc2VsZi11cGRhdGUtc2VsZnVwZGF0ZS0KRU9UCiAgICAgICAgICAgICkKICAgICAgICA7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4ZWN1dGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkY29uZmlnID0gRmFjdG9yeTo6Y3JlYXRlQ29uZmlnKCk7CgogICAgICAgIGlmICgkY29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykgPT09IHRydWUpIHsKICAgICAgICAgICAgJGJhc2VVcmwgPSAnaHR0cDovLycgLiBzZWxmOjpIT01FUEFHRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYmFzZVVybCA9ICdodHRwczovLycgLiBzZWxmOjpIT01FUEFHRTsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRodHRwRG93bmxvYWRlciA9IEZhY3Rvcnk6OmNyZWF0ZUh0dHBEb3dubG9hZGVyKCRpbywgJGNvbmZpZyk7CgogICAgICAgICR2ZXJzaW9uc1V0aWwgPSBuZXcgVmVyc2lvbnMoJGNvbmZpZywgJGh0dHBEb3dubG9hZGVyKTsKCiAgICAgICAgLy8gc3dpdGNoIGNoYW5uZWwgaWYgcmVxdWVzdGVkCiAgICAgICAgJHJlcXVlc3RlZENoYW5uZWwgPSBudWxsOwogICAgICAgIGZvcmVhY2ggKFZlcnNpb25zOjokY2hhbm5lbHMgYXMgJGNoYW5uZWwpIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCRjaGFubmVsKSkgewogICAgICAgICAgICAgICAgJHJlcXVlc3RlZENoYW5uZWwgPSAkY2hhbm5lbDsKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1V0aWwtPnNldENoYW5uZWwoJGNoYW5uZWwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignc2V0LWNoYW5uZWwtb25seScpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJGNhY2hlRGlyID0gJGNvbmZpZy0+Z2V0KCdjYWNoZS1kaXInKTsKICAgICAgICAkcm9sbGJhY2tEaXIgPSAkY29uZmlnLT5nZXQoJ2RhdGEtZGlyJyk7CiAgICAgICAgJGhvbWUgPSAkY29uZmlnLT5nZXQoJ2hvbWUnKTsKICAgICAgICAkbG9jYWxGaWxlbmFtZSA9IHJlYWxwYXRoKCRfU0VSVkVSWydhcmd2J11bMF0pID86ICRfU0VSVkVSWydhcmd2J11bMF07CgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbigndXBkYXRlLWtleXMnKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZldGNoS2V5cygkaW8sICRjb25maWcpOwogICAgICAgIH0KCiAgICAgICAgLy8gZW5zdXJlIGNvbXBvc2VyLnBoYXIgbG9jYXRpb24gaXMgYWNjZXNzaWJsZQogICAgICAgIGlmICghZmlsZV9leGlzdHMoJGxvY2FsRmlsZW5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlc3lzdGVtRXhjZXB0aW9uKCdDb21wb3NlciB1cGRhdGUgZmFpbGVkOiB0aGUgIicuJGxvY2FsRmlsZW5hbWUuJyIgaXMgbm90IGFjY2Vzc2libGUnKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGlmIGN1cnJlbnQgZGlyIGlzIHdyaXRhYmxlIGFuZCBpZiBub3QgdHJ5IHRoZSBjYWNoZSBkaXIgZnJvbSBzZXR0aW5ncwogICAgICAgICR0bXBEaXIgPSBpc193cml0YWJsZShkaXJuYW1lKCRsb2NhbEZpbGVuYW1lKSkgPyBkaXJuYW1lKCRsb2NhbEZpbGVuYW1lKSA6ICRjYWNoZURpcjsKCiAgICAgICAgLy8gY2hlY2sgZm9yIHBlcm1pc3Npb25zIGluIGxvY2FsIGZpbGVzeXN0ZW0gYmVmb3JlIHN0YXJ0IGNvbm5lY3Rpb24gcHJvY2VzcwogICAgICAgIGlmICghaXNfd3JpdGFibGUoJHRtcERpcikpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVzeXN0ZW1FeGNlcHRpb24oJ0NvbXBvc2VyIHVwZGF0ZSBmYWlsZWQ6IHRoZSAiJy4kdG1wRGlyLiciIGRpcmVjdG9yeSB1c2VkIHRvIGRvd25sb2FkIHRoZSB0ZW1wIGZpbGUgY291bGQgbm90IGJlIHdyaXR0ZW4nKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGlmIGNvbXBvc2VyIGlzIHJ1bm5pbmcgYXMgdGhlIHNhbWUgdXNlciB0aGF0IG93bnMgdGhlIGRpcmVjdG9yeSByb290LCBvbmx5IGlmIFBPU0lYIGlzIGRlZmluZWQgYW5kIGNhbGxhYmxlCiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0cHd1aWQnKSAmJiBmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGV1aWQnKSkgewogICAgICAgICAgICAkY29tcG9zZVVzZXIgPSBwb3NpeF9nZXRwd3VpZChwb3NpeF9nZXRldWlkKCkpOwogICAgICAgICAgICAkaG9tZU93bmVyID0gcG9zaXhfZ2V0cHd1aWQoZmlsZW93bmVyKCRob21lKSk7CiAgICAgICAgICAgIGlmIChpc3NldCgkY29tcG9zZVVzZXJbJ25hbWUnXSwgJGhvbWVPd25lclsnbmFtZSddKSAmJiAkY29tcG9zZVVzZXJbJ25hbWUnXSAhPT0gJGhvbWVPd25lclsnbmFtZSddKSB7CiAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPllvdSBhcmUgcnVubmluZyBDb21wb3NlciBhcyAiJy4kY29tcG9zZVVzZXJbJ25hbWUnXS4nIiwgd2hpbGUgIicuJGhvbWUuJyIgaXMgb3duZWQgYnkgIicuJGhvbWVPd25lclsnbmFtZSddLiciPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlucHV0LT5nZXRPcHRpb24oJ3JvbGxiYWNrJykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yb2xsYmFjaygkb3V0cHV0LCAkcm9sbGJhY2tEaXIsICRsb2NhbEZpbGVuYW1lKTsKICAgICAgICB9CgogICAgICAgICRsYXRlc3QgPSAkdmVyc2lvbnNVdGlsLT5nZXRMYXRlc3QoKTsKICAgICAgICAkbGF0ZXN0U3RhYmxlID0gJHZlcnNpb25zVXRpbC0+Z2V0TGF0ZXN0KCdzdGFibGUnKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkbGF0ZXN0UHJldmlldyA9ICR2ZXJzaW9uc1V0aWwtPmdldExhdGVzdCgncHJldmlldycpOwogICAgICAgIH0gY2F0Y2ggKFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGxhdGVzdFByZXZpZXcgPSAkbGF0ZXN0U3RhYmxlOwogICAgICAgIH0KICAgICAgICAkbGF0ZXN0VmVyc2lvbiA9ICRsYXRlc3RbJ3ZlcnNpb24nXTsKICAgICAgICAkdXBkYXRlVmVyc2lvbiA9ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ3ZlcnNpb24nKSA/OiAkbGF0ZXN0VmVyc2lvbjsKICAgICAgICAkY3VycmVudE1ham9yVmVyc2lvbiA9IHByZWdfcmVwbGFjZSgne14oXGQrKS4qfScsICckMScsIENvbXBvc2VyOjpnZXRWZXJzaW9uKCkpOwogICAgICAgICR1cGRhdGVNYWpvclZlcnNpb24gPSBwcmVnX3JlcGxhY2UoJ3teKFxkKykuKn0nLCAnJDEnLCAkdXBkYXRlVmVyc2lvbik7CiAgICAgICAgJHByZXZpZXdNYWpvclZlcnNpb24gPSBwcmVnX3JlcGxhY2UoJ3teKFxkKykuKn0nLCAnJDEnLCAkbGF0ZXN0UHJldmlld1sndmVyc2lvbiddKTsKCiAgICAgICAgaWYgKCR2ZXJzaW9uc1V0aWwtPmdldENoYW5uZWwoKSA9PT0gJ3N0YWJsZScgJiYgISRpbnB1dC0+Z2V0QXJndW1lbnQoJ3ZlcnNpb24nKSkgewogICAgICAgICAgICAvLyBpZiByZXF1ZXN0aW5nIHN0YWJsZSBjaGFubmVsIGFuZCBubyBzcGVjaWZpYyB2ZXJzaW9uLCBhdm9pZCBhdXRvbWF0aWNhbGx5IHVwZ3JhZGluZyB0byB0aGUgbmV4dCBtYWpvcgogICAgICAgICAgICAvLyBzaW1wbHkgb3V0cHV0IGEgd2FybmluZyB0aGF0IHRoZSBuZXh0IG1ham9yIHN0YWJsZSBpcyBhdmFpbGFibGUgYW5kIGxldCB1c2VycyB1cGdyYWRlIHRvIGl0IG1hbnVhbGx5CiAgICAgICAgICAgIGlmICgkY3VycmVudE1ham9yVmVyc2lvbiA8ICR1cGRhdGVNYWpvclZlcnNpb24pIHsKICAgICAgICAgICAgICAgICRza2lwcGVkVmVyc2lvbiA9ICR1cGRhdGVWZXJzaW9uOwoKICAgICAgICAgICAgICAgICR2ZXJzaW9uc1V0aWwtPnNldENoYW5uZWwoJGN1cnJlbnRNYWpvclZlcnNpb24pOwoKICAgICAgICAgICAgICAgICRsYXRlc3QgPSAkdmVyc2lvbnNVdGlsLT5nZXRMYXRlc3QoKTsKICAgICAgICAgICAgICAgICRsYXRlc3RTdGFibGUgPSAkdmVyc2lvbnNVdGlsLT5nZXRMYXRlc3QoJ3N0YWJsZScpOwogICAgICAgICAgICAgICAgJGxhdGVzdFZlcnNpb24gPSAkbGF0ZXN0Wyd2ZXJzaW9uJ107CiAgICAgICAgICAgICAgICAkdXBkYXRlVmVyc2lvbiA9ICRsYXRlc3RWZXJzaW9uOwoKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QSBuZXcgc3RhYmxlIG1ham9yIHZlcnNpb24gb2YgQ29tcG9zZXIgaXMgYXZhaWxhYmxlICgnLiRza2lwcGVkVmVyc2lvbi4nKSwgcnVuICJjb21wb3NlciBzZWxmLXVwZGF0ZSAtLScuJHVwZGF0ZU1ham9yVmVyc2lvbi4nIiB0byB1cGRhdGUgdG8gaXQuIFNlZSBhbHNvIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnLycuJHVwZGF0ZU1ham9yVmVyc2lvbi4nPC93YXJuaW5nPicpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGN1cnJlbnRNYWpvclZlcnNpb24gPCAkcHJldmlld01ham9yVmVyc2lvbikgewogICAgICAgICAgICAgICAgLy8gcHJvbW90ZSBuZXh0IG1ham9yIHZlcnNpb24gaWYgYXZhaWxhYmxlIGluIHByZXZpZXcKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPHdhcm5pbmc+QSBwcmV2aWV3IHJlbGVhc2Ugb2YgdGhlIG5leHQgbWFqb3IgdmVyc2lvbiBvZiBDb21wb3NlciBpcyBhdmFpbGFibGUgKCcuJGxhdGVzdFByZXZpZXdbJ3ZlcnNpb24nXS4nKSwgcnVuICJjb21wb3NlciBzZWxmLXVwZGF0ZSAtLXByZXZpZXciIHRvIGdpdmUgaXQgYSB0cnkuIFNlZSBhbHNvIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9yZWxlYXNlcyBmb3IgY2hhbmdlbG9ncy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkcmVxdWVzdGVkQ2hhbm5lbCAmJiBpc19udW1lcmljKCRyZXF1ZXN0ZWRDaGFubmVsKSAmJiBzdHJwb3MoJGxhdGVzdFN0YWJsZVsndmVyc2lvbiddLCAkcmVxdWVzdGVkQ2hhbm5lbCkgIT09IDApIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5XYXJuaW5nOiBZb3UgZm9yY2VkIHRoZSBpbnN0YWxsIG9mICcuJGxhdGVzdFZlcnNpb24uJyB2aWEgLS0nLiRyZXF1ZXN0ZWRDaGFubmVsLicsIGJ1dCAnLiRsYXRlc3RTdGFibGVbJ3ZlcnNpb24nXS4nIGlzIHRoZSBsYXRlc3Qgc3RhYmxlIHZlcnNpb24uIFVwZGF0aW5nIHRvIGl0IHZpYSBjb21wb3NlciBzZWxmLXVwZGF0ZSAtLXN0YWJsZSBpcyByZWNvbW1lbmRlZC48L3dhcm5pbmc+Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJlZ19tYXRjaCgne15bMC05YS1mXXs0MH0kfScsICR1cGRhdGVWZXJzaW9uKSAmJiAkdXBkYXRlVmVyc2lvbiAhPT0gJGxhdGVzdFZlcnNpb24pIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+WW91IGNhbiBub3QgdXBkYXRlIHRvIGEgc3BlY2lmaWMgU0hBLTEgYXMgdGhvc2UgcGhhcnMgYXJlIG5vdCBhdmFpbGFibGUgZm9yIGRvd25sb2FkPC9lcnJvcj4nKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgJGNoYW5uZWxTdHJpbmcgPSAkdmVyc2lvbnNVdGlsLT5nZXRDaGFubmVsKCk7CiAgICAgICAgaWYgKGlzX251bWVyaWMoJGNoYW5uZWxTdHJpbmcpKSB7CiAgICAgICAgICAgICRjaGFubmVsU3RyaW5nIC49ICcueCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoQ29tcG9zZXI6OlZFUlNJT04gPT09ICR1cGRhdGVWZXJzaW9uKSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJzxpbmZvPllvdSBhcmUgYWxyZWFkeSB1c2luZyB0aGUgbGF0ZXN0IGF2YWlsYWJsZSBDb21wb3NlciB2ZXJzaW9uICVzICglcyBjaGFubmVsKS48L2luZm8+JywKICAgICAgICAgICAgICAgICAgICAkdXBkYXRlVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAkY2hhbm5lbFN0cmluZwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgLy8gcmVtb3ZlIGFsbCBiYWNrdXBzIGV4Y2VwdCBmb3IgdGhlIG1vc3QgcmVjZW50LCBpZiBhbnkKICAgICAgICAgICAgaWYgKCRpbnB1dC0+Z2V0T3B0aW9uKCdjbGVhbi1iYWNrdXBzJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jbGVhbkJhY2t1cHMoJHJvbGxiYWNrRGlyLCAkdGhpcy0+Z2V0TGFzdEJhY2t1cFZlcnNpb24oJHJvbGxiYWNrRGlyKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgJHRlbXBGaWxlbmFtZSA9ICR0bXBEaXIgLiAnLycgLiBiYXNlbmFtZSgkbG9jYWxGaWxlbmFtZSwgJy5waGFyJykuJy10ZW1wLnBoYXInOwogICAgICAgICRiYWNrdXBGaWxlID0gc3ByaW50ZigKICAgICAgICAgICAgJyVzLyVzLSVzJXMnLAogICAgICAgICAgICAkcm9sbGJhY2tEaXIsCiAgICAgICAgICAgIHN0cnRyKENvbXBvc2VyOjpSRUxFQVNFX0RBVEUsICcgOicsICdfLScpLAogICAgICAgICAgICBwcmVnX3JlcGxhY2UoJ3teKFswLTlhLWZdezd9KVswLTlhLWZdezMzfSR9JywgJyQxJywgQ29tcG9zZXI6OlZFUlNJT04pLAogICAgICAgICAgICBzZWxmOjpPTERfSU5TVEFMTF9FWFQKICAgICAgICApOwoKICAgICAgICAkdXBkYXRpbmdUb1RhZyA9ICFwcmVnX21hdGNoKCd7XlswLTlhLWZdezQwfSR9JywgJHVwZGF0ZVZlcnNpb24pOwoKICAgICAgICAkaW8tPndyaXRlKHNwcmludGYoIlVwZ3JhZGluZyB0byB2ZXJzaW9uIDxpbmZvPiVzPC9pbmZvPiAoJXMgY2hhbm5lbCkuIiwgJHVwZGF0ZVZlcnNpb24sICRjaGFubmVsU3RyaW5nKSk7CiAgICAgICAgJHJlbW90ZUZpbGVuYW1lID0gJGJhc2VVcmwgLiAoJHVwZGF0aW5nVG9UYWcgPyAiL2Rvd25sb2FkL3skdXBkYXRlVmVyc2lvbn0vY29tcG9zZXIucGhhciIgOiAnL2NvbXBvc2VyLnBoYXInKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAkc2lnbmF0dXJlID0gJGh0dHBEb3dubG9hZGVyLT5nZXQoJHJlbW90ZUZpbGVuYW1lLicuc2lnJyktPmdldEJvZHkoKTsKICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlLT5nZXRTdGF0dXNDb2RlKCkgPT09IDQwNCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1ZlcnNpb24gIicuJHVwZGF0ZVZlcnNpb24uJyIgY291bGQgbm90IGJlIGZvdW5kLicsIDAsICRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAnLCBmYWxzZSk7CiAgICAgICAgJGh0dHBEb3dubG9hZGVyLT5jb3B5KCRyZW1vdGVGaWxlbmFtZSwgJHRlbXBGaWxlbmFtZSk7CiAgICAgICAgJGlvLT53cml0ZUVycm9yKCcnKTsKCiAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkdGVtcEZpbGVuYW1lKSB8fCAhJHNpZ25hdHVyZSkgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzxlcnJvcj5UaGUgZG93bmxvYWQgb2YgdGhlIG5ldyBjb21wb3NlciB2ZXJzaW9uIGZhaWxlZCBmb3IgYW4gdW5leHBlY3RlZCByZWFzb248L2Vycm9yPicpOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAvLyB2ZXJpZnkgcGhhciBzaWduYXR1cmUKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSAmJiAkY29uZmlnLT5nZXQoJ2Rpc2FibGUtdGxzJykpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5Ta2lwcGluZyBwaGFyIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gYXMgeW91IGhhdmUgZGlzYWJsZWQgT3BlblNTTCB2aWEgY29uZmlnLmRpc2FibGUtdGxzPC93YXJuaW5nPicpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghZXh0ZW5zaW9uX2xvYWRlZCgnb3BlbnNzbCcpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBvcGVuc3NsIGV4dGVuc2lvbiBpcyByZXF1aXJlZCBmb3IgcGhhciBzaWduYXR1cmVzIHRvIGJlIHZlcmlmaWVkIGJ1dCBpdCBpcyBub3QgYXZhaWxhYmxlLiAnCiAgICAgICAgICAgICAgICAuICdJZiB5b3UgY2FuIG5vdCBlbmFibGUgdGhlIG9wZW5zc2wgZXh0ZW5zaW9uLCB5b3UgY2FuIGRpc2FibGUgdGhpcyBlcnJvciwgYXQgeW91ciBvd24gcmlzaywgYnkgc2V0dGluZyB0aGUgXCdkaXNhYmxlLXRsc1wnIG9wdGlvbiB0byB0cnVlLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc2lnRmlsZSA9ICdmaWxlOi8vJy4kaG9tZS4nLycgLiAoJHVwZGF0aW5nVG9UYWcgPyAna2V5cy50YWdzLnB1YicgOiAna2V5cy5kZXYucHViJyk7CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHNpZ0ZpbGUpKSB7CiAgICAgICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygKICAgICAgICAgICAgICAgICAgICAkaG9tZS4nL2tleXMuZGV2LnB1YicsCiAgICAgICAgICAgICAgICAgICAgPDw8REVWUFVCS0VZCi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tCk1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBbkJESGpaUzZlMFpNb0szeFREN2YKRk5DemxYalgvQWllMmRpdDhRWEEwM3BTck9UYmFNbnhPTjNoVUw0N0x6M2cxU0M2WUpFTVZIcjB6WXE0ZWxXaQppM2VjRkVnekxjaitwWk01WDZxV3UyT3p6NHZXeDNKWW8xL2EvSFlkT3VXOWUzbHdTOFZ0UzBBVkpBK1U4WDBBCmhabkJtR3BsdEhoTzhoUEtIZ2tKdGtUVXhDaGVUY2JxbjR3R0hsOFoyU2VkaURjUFRMd3FleldLVWZyWXp1MWYKby9qM1dGd0ZzNkd0SzR3ZFl0aVhyK3lzcEJaSE8zeTF1ZGY4ZUZGR2NiMlYzRWFMT3J0ZnVyNlhRVml6ak91awo4bHc1enpzZTFRcC9rbEhxYkRSc2pTeko2aUw2RjRheW5CYzZFdXF0LzhjY05BSXowckxqTGhPcmFleWo0ZU5uCjhpb2t3TUtpWHBjclFMVEtIK1JIMUpDdU9WeFE0MzZiSndiU3NwMVZ3aXFmdFBRaWVOK3R6cXkrRWlISkptR2YKVEJBYldjbmNpY0NrOXEybWQrQW1oTmJ2SE80UFdiYno5VHpDN0hKYjQ2MGp5V2V1TUV2dzNnTklwRW8yallhOQpwTVY2Y1ZxblNhK3dPYzBEN3BDOWE2Ym5lMGJ2TGNtM1MrdzZJNWlEQjNsWnNiM0E5VXRSaVNQN2FHU283RDcyCjh0QzgrY0lnWmNJN2s5dmp2T3FIK2Q3c2RPVTJ5UENuUlk2d0ZoNjIvZzhiRG5VcHI1Nm5aTjFHODlHd000ZDQKci9UVTdCUVFJenNaZ0FpcU9HWHZWa2xJZ0FNaVYwaXVjZ2Yzck5CTGpqZU5Fd05TVFRHOUYwQ3RRKzdKTHdhRQp3U0V1QXVSbStwUnFpOEJSblEvR0tVY0NBd0VBQVE9PQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0KREVWUFVCS0VZCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKAogICAgICAgICAgICAgICAgICAgICRob21lLicva2V5cy50YWdzLnB1YicsCiAgICAgICAgICAgICAgICAgICAgPDw8VEFHU1BVQktFWQotLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLQpNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQTBWaS8ySzZhcENWajc2bkNuQ2wyCk1RVVBkSytBOWVxa1lCYWNYbzJ3UUJZbXlWbFhtMi9uL1pzWDZwQ0xZUFFUSHlyNWpYYmtRekJ3OFNLcVBkbGgKdkE3TnBiTWVOQ3o3d1AvQW9idlVYTTh4UXVYS2JNRFRZMnVaNE83c00rUGZHYnB0S1BCR0xlOFo4ZDJzVW5UTwpiWHRYNkxyajEzd2tSdG83c3Qvdy9ZcDMzUkhlOVNscWtpaVM0TXNIMWpCa2NJa0VIc1JhdmVaemVkVWF4WTBNCm1iYTB1UGhHVUlucFB6RUh3cllxQkJFdFd2UDk3dDJ2dGZ4OEk1cXYyOGtoMFk2dCtqbmpMMVVyaWQyaXVRWmYKbm9DTUZJT3U0dmtzSzVIeEp4eHJOMEdPbUdtd1ZRak9PdHhrd2lrTmlvdFpHUFI0S3NWajhObkJyTFg3b0d1TQpuUXZHY2lpdStLb0MycjNIREJycERlQlZkT1d4RHpUNVI0aUkwS29MekZoMnBLcXdiWStvYk5QUzJiaisyZGdKCnJWM1Y1SmpyeTQyUU9DQk4zYzg4d1UxUEtmdE9MajJFQ3Bld1k2dm5FNDc4SWlwaUV1N0VBZEs4WndqMkxtVHIKUktRVVNhOWs3Z2dCa1laV0FlTy8yQWcwZXkzZzJiZzdlcWsrc0hFcTV5bklYZDVsaHY2dEM1UEJkSGxXaXBESwp0bDJJeGlFbmVqbk9tQXpHVml2RTFZR2R1WUJqTittanhEVnk4S0dCcmpuejFKUGdBdmdkd0oyZFl3NFJzYy9lClR6Q0ZXR2svSE02YTRmMEl6QldiSjVvdDBQSWk0YW1rMDdJb3RCWERXd3FEaVFUd3l1R0N5bTVFcVdRMkJEOTUKUkd2ODlCUEQrMkRMbkp5c25nc3ZWYVVDQXdFQUFRPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tClRBR1NQVUJLRVkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwdWJrZXlpZCA9IG9wZW5zc2xfcGtleV9nZXRfcHVibGljKCRzaWdGaWxlKTsKICAgICAgICAgICAgJGFsZ28gPSBkZWZpbmVkKCdPUEVOU1NMX0FMR09fU0hBMzg0JykgPyBPUEVOU1NMX0FMR09fU0hBMzg0IDogJ1NIQTM4NCc7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJ3NoYTM4NCcsIGFycmF5X21hcCgnc3RydG9sb3dlcicsIG9wZW5zc2xfZ2V0X21kX21ldGhvZHMoKSkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1NIQTM4NCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHlvdXIgb3BlbnNzbCBleHRlbnNpb24sIGNvdWxkIG5vdCB2ZXJpZnkgdGhlIHBoYXIgZmlsZSBpbnRlZ3JpdHknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc2lnbmF0dXJlID0ganNvbl9kZWNvZGUoJHNpZ25hdHVyZSwgdHJ1ZSk7CiAgICAgICAgICAgICRzaWduYXR1cmUgPSBiYXNlNjRfZGVjb2RlKCRzaWduYXR1cmVbJ3NoYTM4NCddKTsKICAgICAgICAgICAgJHZlcmlmaWVkID0gMSA9PT0gb3BlbnNzbF92ZXJpZnkoZmlsZV9nZXRfY29udGVudHMoJHRlbXBGaWxlbmFtZSksICRzaWduYXR1cmUsICRwdWJrZXlpZCwgJGFsZ28pOwoKICAgICAgICAgICAgLy8gUEhQIDggYXV0b21hdGljYWxseSBmcmVlcyB0aGUga2V5IGluc3RhbmNlIGFuZCBkZXByZWNhdGVzIHRoZSBmdW5jdGlvbgogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA4MDAwMCkgewogICAgICAgICAgICAgICAgb3BlbnNzbF9mcmVlX2tleSgkcHVia2V5aWQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISR2ZXJpZmllZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgcGhhciBzaWduYXR1cmUgZGlkIG5vdCBtYXRjaCB0aGUgZmlsZSB5b3UgZG93bmxvYWRlZCwgdGhpcyBtZWFucyB5b3VyIHB1YmxpYyBrZXlzIGFyZSBvdXRkYXRlZCBvciB0aGF0IHRoZSBwaGFyIGZpbGUgaXMgY29ycnVwdC9oYXMgYmVlbiBtb2RpZmllZCcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZW1vdmUgc2F2ZWQgaW5zdGFsbGF0aW9ucyBvZiBjb21wb3NlcgogICAgICAgIGlmICgkaW5wdXQtPmdldE9wdGlvbignY2xlYW4tYmFja3VwcycpKSB7CiAgICAgICAgICAgICR0aGlzLT5jbGVhbkJhY2t1cHMoJHJvbGxiYWNrRGlyKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPnNldExvY2FsUGhhcigkbG9jYWxGaWxlbmFtZSwgJHRlbXBGaWxlbmFtZSwgJGJhY2t1cEZpbGUpKSB7CiAgICAgICAgICAgIEB1bmxpbmsoJHRlbXBGaWxlbmFtZSk7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmIChmaWxlX2V4aXN0cygkYmFja3VwRmlsZSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKHNwcmludGYoCiAgICAgICAgICAgICAgICAnVXNlIDxpbmZvPmNvbXBvc2VyIHNlbGYtdXBkYXRlIC0tcm9sbGJhY2s8L2luZm8+IHRvIHJldHVybiB0byB2ZXJzaW9uIDxjb21tZW50PiVzPC9jb21tZW50PicsCiAgICAgICAgICAgICAgICBDb21wb3Nlcjo6VkVSU0lPTgogICAgICAgICAgICApKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkEgYmFja3VwIG9mIHRoZSBjdXJyZW50IHZlcnNpb24gY291bGQgbm90IGJlIHdyaXR0ZW4gdG8gJy4kYmFja3VwRmlsZS4nLCBubyByb2xsYmFjayBwb3NzaWJsZTwvd2FybmluZz4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaEtleXMoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZykKICAgIHsKICAgICAgICBpZiAoISRpby0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignUHVibGljIGtleXMgY2FuIG5vdCBiZSBmZXRjaGVkIGluIG5vbi1pbnRlcmFjdGl2ZSBtb2RlLCBwbGVhc2UgcnVuIENvbXBvc2VyIGludGVyYWN0aXZlbHknKTsKICAgICAgICB9CgogICAgICAgICRpby0+d3JpdGUoJ09wZW4gPGluZm8+aHR0cHM6Ly9jb21wb3Nlci5naXRodWIuaW8vcHVia2V5cy5odG1sPC9pbmZvPiB0byBmaW5kIHRoZSBsYXRlc3Qga2V5cycpOwoKICAgICAgICAkdmFsaWRhdG9yID0gZnVuY3Rpb24gKCR2YWx1ZSkgewogICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3teLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0kfScsIHRyaW0oJHZhbHVlKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdJbnZhbGlkIGlucHV0Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cmltKCR2YWx1ZSkuIlxuIjsKICAgICAgICB9OwoKICAgICAgICAkZGV2S2V5ID0gJyc7CiAgICAgICAgd2hpbGUgKCFwcmVnX21hdGNoKCd7KC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tLis/LS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tKX1zJywgJGRldktleSwgJG1hdGNoKSkgewogICAgICAgICAgICAkZGV2S2V5ID0gJGlvLT5hc2tBbmRWYWxpZGF0ZSgnRW50ZXIgRGV2IC8gU25hcHNob3QgUHVibGljIEtleSAoaW5jbHVkaW5nIGxpbmVzIHdpdGggLS0tLS0pOiAnLCAkdmFsaWRhdG9yKTsKICAgICAgICAgICAgd2hpbGUgKCRsaW5lID0gJGlvLT5hc2soJycpKSB7CiAgICAgICAgICAgICAgICAkZGV2S2V5IC49IHRyaW0oJGxpbmUpLiJcbiI7CiAgICAgICAgICAgICAgICBpZiAodHJpbSgkbGluZSkgPT09ICctLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0nKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJGtleVBhdGggPSAkY29uZmlnLT5nZXQoJ2hvbWUnKS4nL2tleXMuZGV2LnB1YicsICRtYXRjaFswXSk7CiAgICAgICAgJGlvLT53cml0ZSgnU3RvcmVkIGtleSB3aXRoIGZpbmdlcnByaW50OiAnIC4gS2V5czo6ZmluZ2VycHJpbnQoJGtleVBhdGgpKTsKCiAgICAgICAgJHRhZ3NLZXkgPSAnJzsKICAgICAgICB3aGlsZSAoIXByZWdfbWF0Y2goJ3soLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0uKz8tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0pfXMnLCAkdGFnc0tleSwgJG1hdGNoKSkgewogICAgICAgICAgICAkdGFnc0tleSA9ICRpby0+YXNrQW5kVmFsaWRhdGUoJ0VudGVyIFRhZ3MgUHVibGljIEtleSAoaW5jbHVkaW5nIGxpbmVzIHdpdGggLS0tLS0pOiAnLCAkdmFsaWRhdG9yKTsKICAgICAgICAgICAgd2hpbGUgKCRsaW5lID0gJGlvLT5hc2soJycpKSB7CiAgICAgICAgICAgICAgICAkdGFnc0tleSAuPSB0cmltKCRsaW5lKS4iXG4iOwogICAgICAgICAgICAgICAgaWYgKHRyaW0oJGxpbmUpID09PSAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJykgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRrZXlQYXRoID0gJGNvbmZpZy0+Z2V0KCdob21lJykuJy9rZXlzLnRhZ3MucHViJywgJG1hdGNoWzBdKTsKICAgICAgICAkaW8tPndyaXRlKCdTdG9yZWQga2V5IHdpdGggZmluZ2VycHJpbnQ6ICcgLiBLZXlzOjpmaW5nZXJwcmludCgka2V5UGF0aCkpOwoKICAgICAgICAkaW8tPndyaXRlKCdQdWJsaWMga2V5cyBzdG9yZWQgaW4gJy4kY29uZmlnLT5nZXQoJ2hvbWUnKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJvbGxiYWNrKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkcm9sbGJhY2tEaXIsICRsb2NhbEZpbGVuYW1lKQogICAgewogICAgICAgICRyb2xsYmFja1ZlcnNpb24gPSAkdGhpcy0+Z2V0TGFzdEJhY2t1cFZlcnNpb24oJHJvbGxiYWNrRGlyKTsKICAgICAgICBpZiAoISRyb2xsYmFja1ZlcnNpb24pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0NvbXBvc2VyIHJvbGxiYWNrIGZhaWxlZDogbm8gaW5zdGFsbGF0aW9uIHRvIHJvbGwgYmFjayB0byBpbiAiJy4kcm9sbGJhY2tEaXIuJyInKTsKICAgICAgICB9CgogICAgICAgICRvbGRGaWxlID0gJHJvbGxiYWNrRGlyIC4gJy8nIC4gJHJvbGxiYWNrVmVyc2lvbiAuIHNlbGY6Ok9MRF9JTlNUQUxMX0VYVDsKCiAgICAgICAgaWYgKCFpc19maWxlKCRvbGRGaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXN5c3RlbUV4Y2VwdGlvbignQ29tcG9zZXIgcm9sbGJhY2sgZmFpbGVkOiAiJy4kb2xkRmlsZS4nIiBjb3VsZCBub3QgYmUgZm91bmQnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpc19yZWFkYWJsZSgkb2xkRmlsZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVzeXN0ZW1FeGNlcHRpb24oJ0NvbXBvc2VyIHJvbGxiYWNrIGZhaWxlZDogIicuJG9sZEZpbGUuJyIgY291bGQgbm90IGJlIHJlYWQnKTsKICAgICAgICB9CgogICAgICAgICRpbyA9ICR0aGlzLT5nZXRJTygpOwogICAgICAgICRpby0+d3JpdGVFcnJvcihzcHJpbnRmKCJSb2xsaW5nIGJhY2sgdG8gdmVyc2lvbiA8aW5mbz4lczwvaW5mbz4uIiwgJHJvbGxiYWNrVmVyc2lvbikpOwogICAgICAgIGlmICghJHRoaXMtPnNldExvY2FsUGhhcigkbG9jYWxGaWxlbmFtZSwgJG9sZEZpbGUpKSB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGRvd25sb2FkZWQvcm9sbGJhY2sgcGhhciBpcyB2YWxpZCB0aGVuIG1vdmVzIGl0CiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICRsb2NhbEZpbGVuYW1lIFRoZSBjb21wb3Nlci5waGFyIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJG5ld0ZpbGVuYW1lICAgVGhlIGRvd25sb2FkZWQgb3IgYmFja3VwIHBoYXIKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAkYmFja3VwVGFyZ2V0ICBUaGUgZmlsZW5hbWUgdG8gdXNlIGZvciB0aGUgYmFja3VwCiAgICAgKiBAdGhyb3dzIEZpbGVzeXN0ZW1FeGNlcHRpb24gSWYgdGhlIGZpbGUgY2Fubm90IGJlIG1vdmVkCiAgICAgKiBAcmV0dXJuIGJvb2wgICAgICAgICAgICAgICAgV2hldGhlciB0aGUgcGhhciBpcyB2YWxpZCBhbmQgaGFzIGJlZW4gbW92ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNldExvY2FsUGhhcigkbG9jYWxGaWxlbmFtZSwgJG5ld0ZpbGVuYW1lLCAkYmFja3VwVGFyZ2V0ID0gbnVsbCkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICBAY2htb2QoJG5ld0ZpbGVuYW1lLCBmaWxlcGVybXMoJGxvY2FsRmlsZW5hbWUpKTsKCiAgICAgICAgLy8gY2hlY2sgcGhhciB2YWxpZGl0eQogICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlUGhhcigkbmV3RmlsZW5hbWUsICRlcnJvcikpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+VGhlICcuKCRiYWNrdXBUYXJnZXQgPyAndXBkYXRlJyA6ICdiYWNrdXAnKS4nIGZpbGUgaXMgY29ycnVwdGVkICgnLiRlcnJvci4nKTwvZXJyb3I+Jyk7CgogICAgICAgICAgICBpZiAoJGJhY2t1cFRhcmdldCkgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+UGxlYXNlIHJlLXJ1biB0aGUgc2VsZi11cGRhdGUgY29tbWFuZCB0byB0cnkgYWdhaW4uPC9lcnJvcj4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gY29weSBjdXJyZW50IGZpbGUgaW50byBiYWNrdXBzIGRpcgogICAgICAgIGlmICgkYmFja3VwVGFyZ2V0KSB7CiAgICAgICAgICAgIEBjb3B5KCRsb2NhbEZpbGVuYW1lLCAkYmFja3VwVGFyZ2V0KTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgICAgIC8vIHVzZSBjb3B5IHRvIGFwcGx5IHBlcm1pc3Npb25zIGZyb20gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeQogICAgICAgICAgICAgICAgLy8gYXMgcmVuYW1lIHVzZXMgc291cmNlIHBlcm1pc3Npb25zIGFuZCBtYXkgYmxvY2sgb3RoZXIgdXNlcnMKICAgICAgICAgICAgICAgIGNvcHkoJG5ld0ZpbGVuYW1lLCAkbG9jYWxGaWxlbmFtZSk7CiAgICAgICAgICAgICAgICBAdW5saW5rKCRuZXdGaWxlbmFtZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZW5hbWUoJG5ld0ZpbGVuYW1lLCAkbG9jYWxGaWxlbmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gc2VlIGlmIHdlIGNhbiBydW4gdGhpcyBvcGVyYXRpb24gYXMgYW4gQWRtaW4gb24gV2luZG93cwogICAgICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKGRpcm5hbWUoJGxvY2FsRmlsZW5hbWUpKQogICAgICAgICAgICAgICAgJiYgJGlvLT5pc0ludGVyYWN0aXZlKCkKICAgICAgICAgICAgICAgICYmICR0aGlzLT5pc1dpbmRvd3NOb25BZG1pblVzZXIoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT50cnlBc1dpbmRvd3NBZG1pbigkbG9jYWxGaWxlbmFtZSwgJG5ld0ZpbGVuYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGFjdGlvbiA9ICdDb21wb3NlciAnLigkYmFja3VwVGFyZ2V0ID8gJ3VwZGF0ZScgOiAncm9sbGJhY2snKTsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVzeXN0ZW1FeGNlcHRpb24oJGFjdGlvbi4nIGZhaWxlZDogIicuJGxvY2FsRmlsZW5hbWUuJyIgY291bGQgbm90IGJlIHdyaXR0ZW4uJy5QSFBfRU9MLiRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2xlYW5CYWNrdXBzKCRyb2xsYmFja0RpciwgJGV4Y2VwdCA9IG51bGwpCiAgICB7CiAgICAgICAgJGZpbmRlciA9ICR0aGlzLT5nZXRPbGRJbnN0YWxsYXRpb25GaW5kZXIoJHJvbGxiYWNrRGlyKTsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKICAgICAgICAkZnMgPSBuZXcgRmlsZXN5c3RlbTsKCiAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoJGV4Y2VwdCAmJiAkZmlsZS0+Z2V0QmFzZW5hbWUoc2VsZjo6T0xEX0lOU1RBTExfRVhUKSA9PT0gJGV4Y2VwdCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGZpbGUgPSAoc3RyaW5nKSAkZmlsZTsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5SZW1vdmluZzogJy4kZmlsZS4nPC9pbmZvPicpOwogICAgICAgICAgICAkZnMtPnJlbW92ZSgkZmlsZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRMYXN0QmFja3VwVmVyc2lvbigkcm9sbGJhY2tEaXIpCiAgICB7CiAgICAgICAgJGZpbmRlciA9ICR0aGlzLT5nZXRPbGRJbnN0YWxsYXRpb25GaW5kZXIoJHJvbGxiYWNrRGlyKTsKICAgICAgICAkZmluZGVyLT5zb3J0QnlOYW1lKCk7CiAgICAgICAgJGZpbGVzID0gaXRlcmF0b3JfdG9fYXJyYXkoJGZpbmRlcik7CgogICAgICAgIGlmIChjb3VudCgkZmlsZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBiYXNlbmFtZShlbmQoJGZpbGVzKSwgc2VsZjo6T0xEX0lOU1RBTExfRVhUKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0T2xkSW5zdGFsbGF0aW9uRmluZGVyKCRyb2xsYmFja0RpcikKICAgIHsKICAgICAgICByZXR1cm4gRmluZGVyOjpjcmVhdGUoKQogICAgICAgICAgICAtPmRlcHRoKDApCiAgICAgICAgICAgIC0+ZmlsZXMoKQogICAgICAgICAgICAtPm5hbWUoJyonIC4gc2VsZjo6T0xEX0lOU1RBTExfRVhUKQogICAgICAgICAgICAtPmluKCRyb2xsYmFja0Rpcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGRvd25sb2FkZWQvYmFja3VwIHBoYXIgZmlsZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkcGhhckZpbGUgVGhlIGRvd25sb2FkZWQgb3IgYmFja3VwIHBoYXIKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkZXJyb3IgICAgU2V0IGJ5IG1ldGhvZCBvbiBmYWlsdXJlCiAgICAgKgogICAgICogQ29kZSB0YWtlbiBmcm9tIGdldGNvbXBvc2VyLm9yZy9pbnN0YWxsZXIuIEFueSBjaGFuZ2VzIHNob3VsZCBiZSBtYWRlCiAgICAgKiB0aGVyZSBhbmQgcmVwbGljYXRlZCBoZXJlCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2wgICAgICAgSWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlUGhhcigkcGhhckZpbGUsICYkZXJyb3IpCiAgICB7CiAgICAgICAgaWYgKGluaV9nZXQoJ3BoYXIucmVhZG9ubHknKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIFRlc3QgdGhlIHBoYXIgdmFsaWRpdHkKICAgICAgICAgICAgJHBoYXIgPSBuZXcgXFBoYXIoJHBoYXJGaWxlKTsKICAgICAgICAgICAgLy8gRnJlZSB0aGUgdmFyaWFibGUgdG8gdW5sb2NrIHRoZSBmaWxlCiAgICAgICAgICAgIHVuc2V0KCRwaGFyKTsKICAgICAgICAgICAgJHJlc3VsdCA9IHRydWU7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoISRlIGluc3RhbmNlb2YgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAmJiAhJGUgaW5zdGFuY2VvZiBcUGhhckV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVycm9yID0gJGUtPmdldE1lc3NhZ2UoKTsKICAgICAgICAgICAgJHJlc3VsdCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIG5vbi1hZG1pbiBXaW5kb3dzIHVzZXIgYWNjb3VudAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNXaW5kb3dzTm9uQWRtaW5Vc2VyKCkKICAgIHsKICAgICAgICBpZiAoIVBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBmbHRtYy5leGUgbWFuYWdlcyBmaWx0ZXIgZHJpdmVycyBhbmQgZXJyb3JzIHdpdGhvdXQgYWRtaW4gcHJpdmlsZWdlcwogICAgICAgIGV4ZWMoJ2ZsdG1jLmV4ZSBmaWx0ZXJzJywgJG91dHB1dCwgJGV4aXRDb2RlKTsKCiAgICAgICAgcmV0dXJuICRleGl0Q29kZSAhPT0gMDsKICAgIH0KCiAgICAvKioKICAgICAqIEludm9rZXMgYSBVQUMgcHJvbXB0IHRvIHVwZGF0ZSBjb21wb3Nlci5waGFyIGFzIGFuIGFkbWluCiAgICAgKgogICAgICogVXNlcyBhIC52YnMgc2NyaXB0IHRvIGVsZXZhdGUgYW5kIHJ1biB0aGUgY21kLmV4ZSBjb3B5IGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGxvY2FsRmlsZW5hbWUgVGhlIGNvbXBvc2VyLnBoYXIgbG9jYXRpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICRuZXdGaWxlbmFtZSAgIFRoZSBkb3dubG9hZGVkIG9yIGJhY2t1cCBwaGFyCiAgICAgKiBAcmV0dXJuIGJvb2wgICBXaGV0aGVyIGNvbXBvc2VyLnBoYXIgaGFzIGJlZW4gdXBkYXRlZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdHJ5QXNXaW5kb3dzQWRtaW4oJGxvY2FsRmlsZW5hbWUsICRuZXdGaWxlbmFtZSkKICAgIHsKICAgICAgICAkaW8gPSAkdGhpcy0+Z2V0SU8oKTsKCiAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8ZXJyb3I+VW5hYmxlIHRvIHdyaXRlICInLiRsb2NhbEZpbGVuYW1lLiciLiBBY2Nlc3MgaXMgZGVuaWVkLjwvZXJyb3I+Jyk7CiAgICAgICAgJGhlbHBNZXNzYWdlID0gJ1BsZWFzZSBydW4gdGhlIHNlbGYtdXBkYXRlIGNvbW1hbmQgYXMgYW4gQWRtaW5pc3RyYXRvci4nOwogICAgICAgICRxdWVzdGlvbiA9ICdDb21wbGV0ZSB0aGlzIG9wZXJhdGlvbiB3aXRoIEFkbWluaXN0cmF0b3IgcHJpdmlsZWdlcyBbPGNvbW1lbnQ+WSxuPC9jb21tZW50Pl0/ICc7CgogICAgICAgIGlmICghJGlvLT5hc2tDb25maXJtYXRpb24oJHF1ZXN0aW9uLCBmYWxzZSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8d2FybmluZz5PcGVyYXRpb24gY2FuY2VsbGVkLiAnLiRoZWxwTWVzc2FnZS4nPC93YXJuaW5nPicpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRtcEZpbGUgPSB0ZW1wbmFtKHN5c19nZXRfdGVtcF9kaXIoKSwgJycpOwogICAgICAgICRzY3JpcHQgPSAkdG1wRmlsZS4nLnZicyc7CiAgICAgICAgcmVuYW1lKCR0bXBGaWxlLCAkc2NyaXB0KTsKCiAgICAgICAgJGNoZWNrc3VtID0gaGFzaF9maWxlKCdzaGEyNTYnLCAkbmV3RmlsZW5hbWUpOwoKICAgICAgICAvLyBjbWQncyBpbnRlcm5hbCBjb3B5IGlzIGZ1c3N5IGFib3V0IGJhY2tzbGFzaGVzCiAgICAgICAgJHNvdXJjZSA9IHN0cl9yZXBsYWNlKCcvJywgJ1xcJywgJG5ld0ZpbGVuYW1lKTsKICAgICAgICAkZGVzdGluYXRpb24gPSBzdHJfcmVwbGFjZSgnLycsICdcXCcsICRsb2NhbEZpbGVuYW1lKTsKCiAgICAgICAgJHZicyA9IDw8PEVPVApTZXQgVUFDID0gQ3JlYXRlT2JqZWN0KCJTaGVsbC5BcHBsaWNhdGlvbiIpClVBQy5TaGVsbEV4ZWN1dGUgImNtZC5leGUiLCAiL2MgY29weSAvYiAveSAiIiRzb3VyY2UiIiAiIiRkZXN0aW5hdGlvbiIiIiwgIiIsICJydW5hcyIsIDAKV3NjcmlwdC5TbGVlcCgzMDApCkVPVDsKCiAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHNjcmlwdCwgJHZicyk7CiAgICAgICAgZXhlYygnIicuJHNjcmlwdC4nIicpOwogICAgICAgIEB1bmxpbmsoJHNjcmlwdCk7CgogICAgICAgIC8vIHNlZSBpZiB0aGUgZmlsZSB3YXMgbW92ZWQgYW5kIGlzIHN0aWxsIGFjY2Vzc2libGUKICAgICAgICBpZiAoJHJlc3VsdCA9IGlzX3JlYWRhYmxlKCRsb2NhbEZpbGVuYW1lKSAmJiAoaGFzaF9maWxlKCdzaGEyNTYnLCAkbG9jYWxGaWxlbmFtZSkgPT09ICRjaGVja3N1bSkpIHsKICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCc8aW5mbz5PcGVyYXRpb24gc3VjY2VlZGVkLjwvaW5mbz4nKTsKICAgICAgICAgICAgQHVubGluaygkbmV3RmlsZW5hbWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignPGVycm9yPk9wZXJhdGlvbiBmYWlsZWQuJy4kaGVscE1lc3NhZ2UuJzwvZXJyb3I+Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxTZWxmVXBkYXRlOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEtleXMKewogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmaW5nZXJwcmludCgkcGF0aCkKICAgIHsKICAgICAgICAkaGFzaCA9IHN0cnRvdXBwZXIoaGFzaCgnc2hhMjU2JywgcHJlZ19yZXBsYWNlKCd7XHN9JywgJycsIGZpbGVfZ2V0X2NvbnRlbnRzKCRwYXRoKSkpKTsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoJyAnLCBhcnJheSgKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCAwLCA4KSwKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCA4LCA4KSwKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCAxNiwgOCksCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgMjQsIDgpLAogICAgICAgICAgICAnJywgLy8gRXh0cmEgc3BhY2UKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCAzMiwgOCksCiAgICAgICAgICAgIHN1YnN0cigkaGFzaCwgNDAsIDgpLAogICAgICAgICAgICBzdWJzdHIoJGhhc2gsIDQ4LCA4KSwKICAgICAgICAgICAgc3Vic3RyKCRoYXNoLCA1NiwgOCksCiAgICAgICAgKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VsZlVwZGF0ZTsKCnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFZlcnNpb25zCnsKICAgIHB1YmxpYyBzdGF0aWMgJGNoYW5uZWxzID0gYXJyYXkoJ3N0YWJsZScsICdwcmV2aWV3JywgJ3NuYXBzaG90JywgJzEnLCAnMicpOwoKICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgcHJpdmF0ZSAkY29uZmlnOwogICAgcHJpdmF0ZSAkY2hhbm5lbDsKICAgIHByaXZhdGUgJHZlcnNpb25zRGF0YTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29uZmlnICRjb25maWcsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlcikKICAgIHsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENoYW5uZWwoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2hhbm5lbCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNoYW5uZWw7CiAgICAgICAgfQoKICAgICAgICAkY2hhbm5lbEZpbGUgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2hvbWUnKS4nL3VwZGF0ZS1jaGFubmVsJzsKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGNoYW5uZWxGaWxlKSkgewogICAgICAgICAgICAkY2hhbm5lbCA9IHRyaW0oZmlsZV9nZXRfY29udGVudHMoJGNoYW5uZWxGaWxlKSk7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY2hhbm5lbCwgYXJyYXkoJ3N0YWJsZScsICdwcmV2aWV3JywgJ3NuYXBzaG90JyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNoYW5uZWwgPSAkY2hhbm5lbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jaGFubmVsID0gJ3N0YWJsZSc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldENoYW5uZWwoJGNoYW5uZWwpCiAgICB7CiAgICAgICAgaWYgKCFpbl9hcnJheSgkY2hhbm5lbCwgc2VsZjo6JGNoYW5uZWxzLCB0cnVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignSW52YWxpZCBjaGFubmVsICcuJGNoYW5uZWwuJywgbXVzdCBiZSBvbmUgb2Y6ICcgLiBpbXBsb2RlKCcsICcsIHNlbGY6OiRjaGFubmVscykpOwogICAgICAgIH0KCiAgICAgICAgJGNoYW5uZWxGaWxlID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdob21lJykuJy91cGRhdGUtY2hhbm5lbCc7CiAgICAgICAgJHRoaXMtPmNoYW5uZWwgPSAkY2hhbm5lbDsKICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkY2hhbm5lbEZpbGUsIChpc19udW1lcmljKCRjaGFubmVsKSA/ICdzdGFibGUnIDogJGNoYW5uZWwpLlBIUF9FT0wpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMYXRlc3QoJGNoYW5uZWwgPSBudWxsKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9ICR0aGlzLT5nZXRWZXJzaW9uc0RhdGEoKTsKCiAgICAgICAgZm9yZWFjaCAoJHZlcnNpb25zWyRjaGFubmVsID86ICR0aGlzLT5nZXRDaGFubmVsKCldIGFzICR2ZXJzaW9uKSB7CiAgICAgICAgICAgIGlmICgkdmVyc2lvblsnbWluLXBocCddIDw9IFBIUF9WRVJTSU9OX0lEKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZlcnNpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdUaGVyZSBpcyBubyB2ZXJzaW9uIG9mIENvbXBvc2VyIGF2YWlsYWJsZSBmb3IgeW91ciBQSFAgdmVyc2lvbiAoJy5QSFBfVkVSU0lPTi4nKScpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VmVyc2lvbnNEYXRhKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT52ZXJzaW9uc0RhdGEpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5jb25maWctPmdldCgnZGlzYWJsZS10bHMnKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgJHByb3RvY29sID0gJ2h0dHAnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHByb3RvY29sID0gJ2h0dHBzJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPnZlcnNpb25zRGF0YSA9ICR0aGlzLT5odHRwRG93bmxvYWRlci0+Z2V0KCRwcm90b2NvbCAuICc6Ly9nZXRjb21wb3Nlci5vcmcvdmVyc2lvbnMnKS0+ZGVjb2RlSnNvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT52ZXJzaW9uc0RhdGE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSnNvbjsKCnVzZSBFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSnNvblZhbGlkYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24KewogICAgcHJvdGVjdGVkICRlcnJvcnM7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlLCAkZXJyb3JzID0gYXJyYXkoKSwgRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmVycm9ycyA9ICRlcnJvcnM7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgMCwgJHByZXZpb3VzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxKc29uOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5OwoKLyoqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIEpzb25NYW5pcHVsYXRvcgp7CiAgICBwcml2YXRlIHN0YXRpYyAkREVGSU5FUyA9ICcoPyhERUZJTkUpCiAgICAgICAoPzxudW1iZXI+ICAgIC0/ICg/PSBbMS05XXwwKD8hXGQpICkgXGQrKyAoXC5cZCsrKT8gKFtlRV0gWystXT8rIFxkKyspPyApCiAgICAgICAoPzxib29sZWFuPiAgIHRydWUgfCBmYWxzZSB8IG51bGwgKQogICAgICAgKD88c3RyaW5nPiAgICAiIChbXiJcXFxcXSorIHwgXFxcXCBbIlxcXFxiZm5ydFwvXSB8IFxcXFwgdSBbMC05QS1GYS1mXXs0fSApKiAiICkKICAgICAgICg/PGFycmF5PiAgICAgXFsgICg/OiAgKD8manNvbikgXHMqKyAoPzogLCAoPyZqc29uKSBccyorICkqKyAgKT8rICBccyorIFxdICkKICAgICAgICg/PHBhaXI+ICAgICAgXHMqKyAoPyZzdHJpbmcpIFxzKisgOiAoPyZqc29uKSBccyorICkKICAgICAgICg/PG9iamVjdD4gICAgXHsgICg/OiAgKD8mcGFpcikgICg/OiAsICg/JnBhaXIpICApKisgICk/KyAgXHMqKyBcfSApCiAgICAgICAoPzxqc29uPiAgICAgIFxzKisgKD86ICg/Jm51bWJlcikgfCAoPyZib29sZWFuKSB8ICg/JnN0cmluZykgfCAoPyZhcnJheSkgfCAoPyZvYmplY3QpICkgKQogICAgKSc7CgogICAgcHJpdmF0ZSAkY29udGVudHM7CiAgICBwcml2YXRlICRuZXdsaW5lOwogICAgcHJpdmF0ZSAkaW5kZW50OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29udGVudHMpCiAgICB7CiAgICAgICAgJGNvbnRlbnRzID0gdHJpbSgkY29udGVudHMpOwogICAgICAgIGlmICgkY29udGVudHMgPT09ICcnKSB7CiAgICAgICAgICAgICRjb250ZW50cyA9ICd7fSc7CiAgICAgICAgfQogICAgICAgIGlmICghJHRoaXMtPnByZWdNYXRjaCgnI15ceyguKilcfSQjcycsICRjb250ZW50cykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBqc29uIGZpbGUgbXVzdCBiZSBhbiBvYmplY3QgKHt9KScpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+bmV3bGluZSA9IGZhbHNlICE9PSBzdHJwb3MoJGNvbnRlbnRzLCAiXHJcbiIpID8gIlxyXG4iIDogIlxuIjsKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkY29udGVudHMgPT09ICd7fScgPyAneycgLiAkdGhpcy0+bmV3bGluZSAuICd9JyA6ICRjb250ZW50czsKICAgICAgICAkdGhpcy0+ZGV0ZWN0SW5kZW50aW5nKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRlbnRzIC4gJHRoaXMtPm5ld2xpbmU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZExpbmsoJHR5cGUsICRwYWNrYWdlLCAkY29uc3RyYWludCwgJHNvcnRQYWNrYWdlcyA9IGZhbHNlKQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAvLyBubyBsaW5rIG9mIHRoYXQgdHlwZSB5ZXQKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyR0eXBlXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRNYWluS2V5KCR0eXBlLCBhcnJheSgkcGFja2FnZSA9PiAkY29uc3RyYWludCkpOwogICAgICAgIH0KCiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxwcm9wZXJ0eT4nLnByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkdHlwZSkpLidccyo6XHMqKSg/UDx2YWx1ZT4oPyZqc29uKSkoP1A8ZW5kPi4qKX1zeCc7CiAgICAgICAgaWYgKCEkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJGxpbmtzID0gJG1hdGNoZXNbJ3ZhbHVlJ107CgogICAgICAgIC8vIHRyeSB0byBmaW5kIGV4aXN0aW5nIGxpbmsKICAgICAgICAkcGFja2FnZVJlZ2V4ID0gc3RyX3JlcGxhY2UoJy8nLCAnXFxcXD8vJywgcHJlZ19xdW90ZSgkcGFja2FnZSkpOwogICAgICAgICRyZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nIig/UDxwYWNrYWdlPicuJHBhY2thZ2VSZWdleC4nKSIoXHMqOlxzKikoPyZzdHJpbmcpfWl4JzsKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgkcmVnZXgsICRsaW5rcywgJHBhY2thZ2VNYXRjaGVzKSkgewogICAgICAgICAgICAvLyB1cGRhdGUgZXhpc3RpbmcgbGluawogICAgICAgICAgICAkZXhpc3RpbmdQYWNrYWdlID0gJHBhY2thZ2VNYXRjaGVzWydwYWNrYWdlJ107CiAgICAgICAgICAgICRwYWNrYWdlUmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRleGlzdGluZ1BhY2thZ2UpKTsKICAgICAgICAgICAgJGxpbmtzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCd7Jy5zZWxmOjokREVGSU5FUy4nIicuJHBhY2thZ2VSZWdleC4nIig/UDxzZXBhcmF0b3I+XHMqOlxzKikoPyZzdHJpbmcpfWl4JywgZnVuY3Rpb24gKCRtKSB1c2UgKCRleGlzdGluZ1BhY2thZ2UsICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gSnNvbkZpbGU6OmVuY29kZShzdHJfcmVwbGFjZSgnXFwvJywgJy8nLCAkZXhpc3RpbmdQYWNrYWdlKSkgLiAkbVsnc2VwYXJhdG9yJ10gLiAnIicgLiAkY29uc3RyYWludCAuICciJzsKICAgICAgICAgICAgfSwgJGxpbmtzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgnI15ccypce1xzKlxTKy4qPyhccypcfVxzKikkI3MnLCAkbGlua3MsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIC8vIGxpbmsgbWlzc2luZyBidXQgbm9uIGVtcHR5IGxpbmtzCiAgICAgICAgICAgICAgICAkbGlua3MgPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgJ3snLnByZWdfcXVvdGUoJG1hdGNoWzFdKS4nJH0nLAogICAgICAgICAgICAgICAgICAgIC8vIGFkZGNzbGFzaGVzIGlzIHVzZWQgdG8gZG91YmxlIHVwIGJhY2tzbGFzaGVzLyQgc2luY2UgcHJlZ19yZXBsYWNlIHJlc29sdmVzIHRoZW0gYXMgYmFjayByZWZlcmVuY2VzIG90aGVyd2lzZSwgc2VlICMxNTg4CiAgICAgICAgICAgICAgICAgICAgYWRkY3NsYXNoZXMoJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJHBhY2thZ2UpLic6ICcuSnNvbkZpbGU6OmVuY29kZSgkY29uc3RyYWludCkgLiAkbWF0Y2hbMV0sICdcXCQnKSwKICAgICAgICAgICAgICAgICAgICAkbGlua3MKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBsaW5rcyBlbXB0eQogICAgICAgICAgICAgICAgJGxpbmtzID0gJ3snIC4gJHRoaXMtPm5ld2xpbmUgLgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgkcGFja2FnZSkuJzogJy5Kc29uRmlsZTo6ZW5jb2RlKCRjb25zdHJhaW50KSAuICR0aGlzLT5uZXdsaW5lIC4KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZW50IC4gJ30nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSA9PT0gJHNvcnRQYWNrYWdlcykgewogICAgICAgICAgICAkcmVxdWlyZW1lbnRzID0ganNvbl9kZWNvZGUoJGxpbmtzLCB0cnVlKTsKICAgICAgICAgICAgJHRoaXMtPnNvcnRQYWNrYWdlcygkcmVxdWlyZW1lbnRzKTsKICAgICAgICAgICAgJGxpbmtzID0gJHRoaXMtPmZvcm1hdCgkcmVxdWlyZW1lbnRzKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb250ZW50cyA9ICRtYXRjaGVzWydzdGFydCddIC4gJG1hdGNoZXNbJ3Byb3BlcnR5J10gLiAkbGlua3MgLiAkbWF0Y2hlc1snZW5kJ107CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogU29ydHMgcGFja2FnZXMgYnkgaW1wb3J0YW5jZSAocGxhdGZvcm0gcGFja2FnZXMgZmlyc3QsIHRoZW4gUEhQIGRlcGVuZGVuY2llcykgYW5kIGFscGhhYmV0aWNhbGx5LgogICAgICoKICAgICAqIEBsaW5rIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wMi1saWJyYXJpZXMubWQjcGxhdGZvcm0tcGFja2FnZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHBhY2thZ2VzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc29ydFBhY2thZ2VzKGFycmF5ICYkcGFja2FnZXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRwcmVmaXggPSBmdW5jdGlvbiAoJHJlcXVpcmVtZW50KSB7CiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZXF1aXJlbWVudCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICcvXnBocC8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15oaHZtLycsCiAgICAgICAgICAgICAgICAgICAgICAgICcvXmV4dC8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15saWIvJywKICAgICAgICAgICAgICAgICAgICAgICAgJy9eXEQvJywKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnMC0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcxLSQwJywKICAgICAgICAgICAgICAgICAgICAgICAgJzItJDAnLAogICAgICAgICAgICAgICAgICAgICAgICAnMy0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICc0LSQwJywKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlbWVudAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICc1LScuJHJlcXVpcmVtZW50OwogICAgICAgIH07CgogICAgICAgIHVrc29ydCgkcGFja2FnZXMsIGZ1bmN0aW9uICgkYSwgJGIpIHVzZSAoJHByZWZpeCkgewogICAgICAgICAgICByZXR1cm4gc3RybmF0Y21wKCRwcmVmaXgoJGEpLCAkcHJlZml4KCRiKSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcsICRhcHBlbmQgPSB0cnVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUsICRjb25maWcsICRhcHBlbmQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVSZXBvc2l0b3J5KCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgncmVwb3NpdG9yaWVzJywgJG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb25maWdTZXR0aW5nKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdjb25maWcnLCAkbmFtZSwgJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlQ29uZmlnU2V0dGluZygkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZVN1Yk5vZGUoJ2NvbmZpZycsICRuYW1lKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHJvcGVydHkoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoc3RycG9zKCRuYW1lLCAnc3VnZ2VzdC4nKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZFN1Yk5vZGUoJ3N1Z2dlc3QnLCBzdWJzdHIoJG5hbWUsIDgpLCAkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ2V4dHJhLicpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgnZXh0cmEnLCBzdWJzdHIoJG5hbWUsIDYpLCAkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ3NjcmlwdHMuJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdzY3JpcHRzJywgc3Vic3RyKCRuYW1lLCA4KSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YWRkTWFpbktleSgkbmFtZSwgJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHkoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ3N1Z2dlc3QuJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVTdWJOb2RlKCdzdWdnZXN0Jywgc3Vic3RyKCRuYW1lLCA4KSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCRuYW1lLCAnZXh0cmEuJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVTdWJOb2RlKCdleHRyYScsIHN1YnN0cigkbmFtZSwgNikpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ3NjcmlwdHMuJykgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVTdWJOb2RlKCdzY3JpcHRzJywgc3Vic3RyKCRuYW1lLCA4KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbW92ZU1haW5LZXkoJG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWUsICR2YWx1ZSwgJGFwcGVuZCA9IHRydWUpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CgogICAgICAgICRzdWJOYW1lID0gbnVsbDsKICAgICAgICBpZiAoaW5fYXJyYXkoJG1haW5Ob2RlLCBhcnJheSgnY29uZmlnJywgJ2V4dHJhJywgJ3NjcmlwdHMnKSkgJiYgZmFsc2UgIT09IHN0cnBvcygkbmFtZSwgJy4nKSkgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkc3ViTmFtZSkgPSBleHBsb2RlKCcuJywgJG5hbWUsIDIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbWFpbiBub2RlIHlldAogICAgICAgIGlmICghaXNzZXQoJGRlY29kZWRbJG1haW5Ob2RlXSkpIHsKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTWFpbktleSgkbWFpbk5vZGUsIGFycmF5KCRuYW1lID0+IGFycmF5KCRzdWJOYW1lID0+ICR2YWx1ZSkpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRNYWluS2V5KCRtYWluTm9kZSwgYXJyYXkoJG5hbWUgPT4gJHZhbHVlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gbWFpbiBub2RlIGNvbnRlbnQgbm90IG1hdGNoLWFibGUKICAgICAgICAkbm9kZVJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PiBccyogXHsgXHMqICg/OiAoPyZzdHJpbmcpIFxzKiA6ICg/Jmpzb24pIFxzKiAsIFxzKiApKj8nLgogICAgICAgICAgICBwcmVnX3F1b3RlKEpzb25GaWxlOjplbmNvZGUoJG1haW5Ob2RlKSkuJ1xzKjpccyopKD9QPGNvbnRlbnQ+KD8mb2JqZWN0KSkoP1A8ZW5kPi4qKX1zeCc7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnByZWdNYXRjaCgkbm9kZVJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgJGNoaWxkcmVuID0gJG1hdGNoWydjb250ZW50J107CiAgICAgICAgLy8gaW52YWxpZCBtYXRjaCBkdWUgdG8gdW4tcmVnZXhhYmxlIGNvbnRlbnQsIGFib3J0CiAgICAgICAgaWYgKCFAanNvbl9kZWNvZGUoJGNoaWxkcmVuKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkdGhhdCA9ICR0aGlzOwoKICAgICAgICAvLyBjaGlsZCBleGlzdHMKICAgICAgICAkY2hpbGRSZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nKD9QPHN0YXJ0PiInLnByZWdfcXVvdGUoJG5hbWUpLiciXHMqOlxzKikoP1A8Y29udGVudD4oPyZqc29uKSkoP1A8ZW5kPiw/KX14JzsKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgkY2hpbGRSZWdleCwgJGNoaWxkcmVuLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgJGNoaWxkcmVuID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRjaGlsZFJlZ2V4LCBmdW5jdGlvbiAoJG1hdGNoZXMpIHVzZSAoJHN1Yk5hbWUsICR2YWx1ZSwgJHRoYXQpIHsKICAgICAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICRjdXJWYWwgPSBqc29uX2RlY29kZSgkbWF0Y2hlc1snY29udGVudCddLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRjdXJWYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjdXJWYWwgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY3VyVmFsWyRzdWJOYW1lXSA9ICR2YWx1ZTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSAkY3VyVmFsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkbWF0Y2hlc1snc3RhcnQnXSAuICR0aGF0LT5mb3JtYXQoJHZhbHVlLCAxKSAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICAgICAgfSwgJGNoaWxkcmVuKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJlZ01hdGNoKCcjXnsgKD9QPGxlYWRpbmdzcGFjZT5ccyo/KSAoP1A8Y29udGVudD5cUysuKj8pPyAoP1A8dHJhaWxpbmdzcGFjZT5ccyopIH0kI3N4JywgJGNoaWxkcmVuLCAkbWF0Y2gpOwoKICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSAnJzsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbJ3RyYWlsaW5nc3BhY2UnXSkpIHsKICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gJG1hdGNoWyd0cmFpbGluZ3NwYWNlJ107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoWydjb250ZW50J10pKSB7CiAgICAgICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBhcnJheSgkc3ViTmFtZSA9PiAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNoaWxkIG1pc3NpbmcgYnV0IG5vbiBlbXB0eSBjaGlsZHJlbgogICAgICAgICAgICAgICAgaWYgKCRhcHBlbmQpIHsKICAgICAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgICAgICcjJy4kd2hpdGVzcGFjZS4nfSQjJywKICAgICAgICAgICAgICAgICAgICAgICAgYWRkY3NsYXNoZXMoJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJG5hbWUpLic6ICcuJHRoaXMtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJHdoaXRlc3BhY2UgLiAnfScsICdcXCQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgJGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSAnJzsKICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsnbGVhZGluZ3NwYWNlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR3aGl0ZXNwYWNlID0gJG1hdGNoWydsZWFkaW5nc3BhY2UnXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbiA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgICAgICAgICAgICAgJyNeeycuJHdoaXRlc3BhY2UuJyMnLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRjc2xhc2hlcygneycgLiAkd2hpdGVzcGFjZSAuIEpzb25GaWxlOjplbmNvZGUoJG5hbWUpLic6ICcuJHRoaXMtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCwgJ1xcJCcpLAogICAgICAgICAgICAgICAgICAgICAgICAkY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gYXJyYXkoJHN1Yk5hbWUgPT4gJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBjaGlsZHJlbiBwcmVzZW50IGJ1dCBlbXB0eQogICAgICAgICAgICAgICAgJGNoaWxkcmVuID0gJ3snIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJG5hbWUpLic6ICcuJHRoaXMtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJHdoaXRlc3BhY2UgLiAnfSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygkbm9kZVJlZ2V4LCBmdW5jdGlvbiAoJG0pIHVzZSAoJGNoaWxkcmVuKSB7CiAgICAgICAgICAgIHJldHVybiAkbVsnc3RhcnQnXSAuICRjaGlsZHJlbiAuICRtWydlbmQnXTsKICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lKQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAvLyBubyBub2RlIG9yIGVtcHR5IG5vZGUKICAgICAgICBpZiAoZW1wdHkoJGRlY29kZWRbJG1haW5Ob2RlXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBubyBub2RlIGNvbnRlbnQgbWF0Y2gtYWJsZQogICAgICAgICRub2RlUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+IFxzKiBceyBccyogKD86ICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICwgXHMqICkqPycuCiAgICAgICAgICAgIHByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8Y29udGVudD4oPyZvYmplY3QpKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5wcmVnTWF0Y2goJG5vZGVSZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoJGUtPmdldENvZGUoKSA9PT0gUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CgogICAgICAgICRjaGlsZHJlbiA9ICRtYXRjaFsnY29udGVudCddOwoKICAgICAgICAvLyBpbnZhbGlkIG1hdGNoIGR1ZSB0byB1bi1yZWdleGFibGUgY29udGVudCwgYWJvcnQKICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgkY2hpbGRyZW4sIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRzdWJOYW1lID0gbnVsbDsKICAgICAgICBpZiAoaW5fYXJyYXkoJG1haW5Ob2RlLCBhcnJheSgnY29uZmlnJywgJ2V4dHJhJywgJ3NjcmlwdHMnKSkgJiYgZmFsc2UgIT09IHN0cnBvcygkbmFtZSwgJy4nKSkgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkc3ViTmFtZSkgPSBleHBsb2RlKCcuJywgJG5hbWUsIDIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbm9kZSB0byByZW1vdmUKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdKSB8fCAoJHN1Yk5hbWUgJiYgIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdWyRzdWJOYW1lXSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IGFuZCBmaW5kIGEgbWF0Y2ggZm9yIHRoZSBzdWJrZXkKICAgICAgICAka2V5UmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRuYW1lKSk7CiAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJ3siJy4ka2V5UmVnZXguJyJccyo6fWknLCAkY2hpbGRyZW4pKSB7CiAgICAgICAgICAgIC8vIGZpbmQgYmVzdCBtYXRjaCBmb3IgdGhlIHZhbHVlIG9mICJuYW1lIgogICAgICAgICAgICBpZiAocHJlZ19tYXRjaF9hbGwoJ3snLnNlbGY6OiRERUZJTkVTLiciJy4ka2V5UmVnZXguJyJccyo6XHMqKD86KD8manNvbikpfXgnLCAkY2hpbGRyZW4sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgJGJlc3RNYXRjaCA9ICcnOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXNbMF0gYXMgJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkYmVzdE1hdGNoKSA8IHN0cmxlbigkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRiZXN0TWF0Y2ggPSAkbWF0Y2g7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNoaWxkcmVuQ2xlYW4gPSBwcmVnX3JlcGxhY2UoJ3ssXHMqJy5wcmVnX3F1b3RlKCRiZXN0TWF0Y2gpLid9aScsICcnLCAkY2hpbGRyZW4sIC0xLCAkY291bnQpOwogICAgICAgICAgICAgICAgaWYgKDEgIT09ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gcHJlZ19yZXBsYWNlKCd7Jy5wcmVnX3F1b3RlKCRiZXN0TWF0Y2gpLidccyosP1xzKn1pJywgJycsICRjaGlsZHJlbkNsZWFuLCAtMSwgJGNvdW50KTsKICAgICAgICAgICAgICAgICAgICBpZiAoMSAhPT0gJGNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY2hpbGRyZW5DbGVhbiA9ICRjaGlsZHJlbjsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJGNoaWxkcmVuQ2xlYW4pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJKc29uTWFuaXB1bGF0b3I6IFwkY2hpbGRyZW5DbGVhbiBpcyBub3QgZGVmaW5lZC4gUGxlYXNlIHJlcG9ydCBhdCBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzL25ldy4iKTsKICAgICAgICB9CgogICAgICAgIC8vIG5vIGNoaWxkIGRhdGEgbGVmdCwgJG5hbWUgd2FzIHRoZSBvbmx5IGtleSBpbgogICAgICAgICR0aGlzLT5wcmVnTWF0Y2goJyNeeyBccyo/ICg/UDxjb250ZW50PlxTKy4qPyk/ICg/UDx0cmFpbGluZ3NwYWNlPlxzKikgfSQjc3gnLCAkY2hpbGRyZW5DbGVhbiwgJG1hdGNoKTsKICAgICAgICBpZiAoZW1wdHkoJG1hdGNoWydjb250ZW50J10pKSB7CiAgICAgICAgICAgICRuZXdsaW5lID0gJHRoaXMtPm5ld2xpbmU7CiAgICAgICAgICAgICRpbmRlbnQgPSAkdGhpcy0+aW5kZW50OwoKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRub2RlUmVnZXgsIGZ1bmN0aW9uICgkbWF0Y2hlcykgdXNlICgkaW5kZW50LCAkbmV3bGluZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJ3snIC4gJG5ld2xpbmUgLiAkaW5kZW50IC4gJ30nIC4gJG1hdGNoZXNbJ2VuZCddOwogICAgICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAgICAgLy8gd2UgaGF2ZSBhIHN1Ym5hbWUsIHNvIHdlIHJlc3RvcmUgdGhlIHJlc3Qgb2YgJG5hbWUKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkY3VyVmFsID0ganNvbl9kZWNvZGUoJGNoaWxkcmVuLCB0cnVlKTsKICAgICAgICAgICAgICAgIHVuc2V0KCRjdXJWYWxbJG5hbWVdWyRzdWJOYW1lXSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lLCAkY3VyVmFsWyRuYW1lXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoYXQgPSAkdGhpczsKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJG5vZGVSZWdleCwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCR0aGF0LCAkbmFtZSwgJHN1Yk5hbWUsICRjaGlsZHJlbkNsZWFuKSB7CiAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJGN1clZhbCA9IGpzb25fZGVjb2RlKCRtYXRjaGVzWydjb250ZW50J10sIHRydWUpOwogICAgICAgICAgICAgICAgdW5zZXQoJGN1clZhbFskbmFtZV1bJHN1Yk5hbWVdKTsKICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gJHRoYXQtPmZvcm1hdCgkY3VyVmFsKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJGNoaWxkcmVuQ2xlYW4gLiAkbWF0Y2hlc1snZW5kJ107CiAgICAgICAgfSwgJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZE1haW5LZXkoJGtleSwgJGNvbnRlbnQpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CiAgICAgICAgJGNvbnRlbnQgPSAkdGhpcy0+Zm9ybWF0KCRjb250ZW50KTsKCiAgICAgICAgLy8ga2V5IGV4aXN0cyBhbHJlYWR5CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxrZXk+Jy5wcmVnX3F1b3RlKEpzb25GaWxlOjplbmNvZGUoJGtleSkpLidccyo6XHMqKD8manNvbikpKD9QPGVuZD4uKil9c3gnOwogICAgICAgIGlmIChpc3NldCgkZGVjb2RlZFska2V5XSkgJiYgJHRoaXMtPnByZWdNYXRjaCgkcmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIGludmFsaWQgbWF0Y2ggZHVlIHRvIHVuLXJlZ2V4YWJsZSBjb250ZW50LCBhYm9ydAogICAgICAgICAgICBpZiAoIUBqc29uX2RlY29kZSgneycuJG1hdGNoZXNbJ2tleSddLid9JykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gJG1hdGNoZXNbJ3N0YXJ0J10gLiBKc29uRmlsZTo6ZW5jb2RlKCRrZXkpLic6ICcuJGNvbnRlbnQgLiAkbWF0Y2hlc1snZW5kJ107CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGVuZCBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlIGFuZCBrZWVwIHdoaXRlc3BhY2UKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgnI1tee1xzXShccyopXH0kIycsICR0aGlzLT5jb250ZW50cywgJG1hdGNoKSkgewogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAnIycuJG1hdGNoWzFdLidcfSQjJywKICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCcsJyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuICRjb250ZW50IC4gJHRoaXMtPm5ld2xpbmUgLiAnfScsICdcXCQnKSwKICAgICAgICAgICAgICAgICR0aGlzLT5jb250ZW50cwogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBhcHBlbmQgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZQogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgJyNcfSQjJywKICAgICAgICAgICAgYWRkY3NsYXNoZXMoJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuJGNvbnRlbnQgLiAkdGhpcy0+bmV3bGluZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMKICAgICAgICApOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTWFpbktleSgka2V5KQogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJGtleSwgJGRlY29kZWQpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8ga2V5IGV4aXN0cyBhbHJlYWR5CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxyZW1vdmFsPicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCRrZXkpKS4nXHMqOlxzKig/Jmpzb24pKVxzKiw/XHMqKD9QPGVuZD4uKil9c3gnOwogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgLy8gaW52YWxpZCBtYXRjaCBkdWUgdG8gdW4tcmVnZXhhYmxlIGNvbnRlbnQsIGFib3J0CiAgICAgICAgICAgIGlmICghQGpzb25fZGVjb2RlKCd7Jy4kbWF0Y2hlc1sncmVtb3ZhbCddLid9JykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB3ZSBhcmUgbm90IGxlYXZpbmcgYSBkYW5nbGluZyBjb21tYSBvbiB0aGUgcHJldmlvdXMgbGluZSBpZiB0aGUgbGFzdCBsaW5lIHdhcyByZW1vdmVkCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcjLFxzKiQjJywgJG1hdGNoZXNbJ3N0YXJ0J10pICYmIHByZWdfbWF0Y2goJyNeXH0kIycsICRtYXRjaGVzWydlbmQnXSkpIHsKICAgICAgICAgICAgICAgICRtYXRjaGVzWydzdGFydCddID0gcnRyaW0ocHJlZ19yZXBsYWNlKCcjLChccyopJCMnLCAnJDEnLCAkbWF0Y2hlc1snc3RhcnQnXSksICR0aGlzLT5pbmRlbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkbWF0Y2hlc1snc3RhcnQnXSAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJyNeXHtccypcfVxzKiQjJywgJHRoaXMtPmNvbnRlbnRzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gIntcbn0iOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlTWFpbktleUlmRW1wdHkoJGtleSkKICAgIHsKICAgICAgICAkZGVjb2RlZCA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmNvbnRlbnRzKTsKCiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRrZXksICRkZWNvZGVkKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19hcnJheSgkZGVjb2RlZFska2V5XSkgJiYgY291bnQoJGRlY29kZWRbJGtleV0pID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlTWFpbktleSgka2V5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBmb3JtYXQoJGRhdGEsICRkZXB0aCA9IDApCiAgICB7CiAgICAgICAgaWYgKGlzX2FycmF5KCRkYXRhKSkgewogICAgICAgICAgICByZXNldCgkZGF0YSk7CgogICAgICAgICAgICBpZiAoaXNfbnVtZXJpYyhrZXkoJGRhdGEpKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRhdGEgYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgJGRhdGFbJGtleV0gPSAkdGhpcy0+Zm9ybWF0KCR2YWwsICRkZXB0aCArIDEpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnWycuaW1wbG9kZSgnLCAnLCAkZGF0YSkuJ10nOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkb3V0ID0gJ3snIC4gJHRoaXMtPm5ld2xpbmU7CiAgICAgICAgICAgICRlbGVtcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhIGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICAgICAgJGVsZW1zW10gPSBzdHJfcmVwZWF0KCR0aGlzLT5pbmRlbnQsICRkZXB0aCArIDIpIC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4gJzogJy4kdGhpcy0+Zm9ybWF0KCR2YWwsICRkZXB0aCArIDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG91dCAuIGltcGxvZGUoJywnLiR0aGlzLT5uZXdsaW5lLCAkZWxlbXMpIC4gJHRoaXMtPm5ld2xpbmUgLiBzdHJfcmVwZWF0KCR0aGlzLT5pbmRlbnQsICRkZXB0aCArIDEpIC4gJ30nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEpzb25GaWxlOjplbmNvZGUoJGRhdGEpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXRlY3RJbmRlbnRpbmcoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCd7XihbIFx0XSspIn1tJywgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgPSAkbWF0Y2hbMV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmluZGVudCA9ICcgICAgJzsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByZWdNYXRjaCgkcmUsICRzdHIsICYkbWF0Y2hlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJGNvdW50ID0gcHJlZ19tYXRjaCgkcmUsICRzdHIsICRtYXRjaGVzKTsKCiAgICAgICAgaWYgKCRjb3VudCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgc3dpdGNoIChwcmVnX2xhc3RfZXJyb3IoKSkgewogICAgICAgICAgICAgICAgY2FzZSBQUkVHX05PX0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfTk9fRVJST1InLCBQUkVHX05PX0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19JTlRFUk5BTF9FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX0lOVEVSTkFMX0VSUk9SJywgUFJFR19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfQkFDS1RSQUNLX0xJTUlUX0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfQkFDS1RSQUNLX0xJTUlUX0VSUk9SJywgUFJFR19CQUNLVFJBQ0tfTElNSVRfRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSBQUkVHX1JFQ1VSU0lPTl9MSU1JVF9FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX1JFQ1VSU0lPTl9MSU1JVF9FUlJPUicsIFBSRUdfUkVDVVJTSU9OX0xJTUlUX0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19CQURfVVRGOF9FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX0JBRF9VVEY4X0VSUk9SJywgUFJFR19CQURfVVRGOF9FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfQkFEX1VURjhfT0ZGU0VUX0VSUk9SOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfQkFEX1VURjhfT0ZGU0VUX0VSUk9SJywgUFJFR19CQURfVVRGOF9PRkZTRVRfRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSA2OiAvLyBQUkVHX0pJVF9TVEFDS0xJTUlUX0VSUk9SCiAgICAgICAgICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID4gNzAwMDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19KSVRfU1RBQ0tMSU1JVF9FUlJPUicsIDYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBubyBicmVhawogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBVbmtub3duIGVycm9yJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY291bnQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSnNvbjsKCi8qKgogKiBGb3JtYXRzIGpzb24gc3RyaW5ncyB1c2VkIGZvciBwaHAgPCA1LjQgYmVjYXVzZSB0aGUganNvbl9lbmNvZGUgZG9lc24ndAogKiBzdXBwb3J0cyB0aGUgZmxhZ3MgSlNPTl9VTkVTQ0FQRURfU0xBU0hFUyB8IEpTT05fUFJFVFRZX1BSSU5UIHwgSlNPTl9VTkVTQ0FQRURfVU5JQ09ERQogKiBpbiB0aGVzZSB2ZXJzaW9ucwogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hpdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBKc29uRm9ybWF0dGVyCnsKICAgIC8qKgogICAgICogVGhpcyBjb2RlIGlzIGJhc2VkIG9uIHRoZSBmdW5jdGlvbiBmb3VuZCBhdDoKICAgICAqICBodHRwOi8vcmVjdXJzaXZlLWRlc2lnbi5jb20vYmxvZy8yMDA4LzAzLzExL2Zvcm1hdC1qc29uLXdpdGgtcGhwLwogICAgICoKICAgICAqIE9yaWdpbmFsbHkgbGljZW5zZWQgdW5kZXIgTUlUIGJ5IERhdmUgUGVycmV0dCA8bWFpbEByZWN1cnNpdmUtZGVzaWduLmNvbT4KICAgICAqCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJGpzb24KICAgICAqIEBwYXJhbSAgYm9vbCAgICR1bmVzY2FwZVVuaWNvZGUgVW4gZXNjYXBlIHVuaWNvZGUKICAgICAqIEBwYXJhbSAgYm9vbCAgICR1bmVzY2FwZVNsYXNoZXMgVW4gZXNjYXBlIHNsYXNoZXMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0KCRqc29uLCAkdW5lc2NhcGVVbmljb2RlLCAkdW5lc2NhcGVTbGFzaGVzKQogICAgewogICAgICAgICRyZXN1bHQgPSAnJzsKICAgICAgICAkcG9zID0gMDsKICAgICAgICAkc3RyTGVuID0gc3RybGVuKCRqc29uKTsKICAgICAgICAkaW5kZW50U3RyID0gJyAgICAnOwogICAgICAgICRuZXdMaW5lID0gIlxuIjsKICAgICAgICAkb3V0T2ZRdW90ZXMgPSB0cnVlOwogICAgICAgICRidWZmZXIgPSAnJzsKICAgICAgICAkbm9lc2NhcGUgPSB0cnVlOwoKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkc3RyTGVuOyAkaSsrKSB7CiAgICAgICAgICAgIC8vIEdyYWIgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKICAgICAgICAgICAgJGNoYXIgPSBzdWJzdHIoJGpzb24sICRpLCAxKTsKCiAgICAgICAgICAgIC8vIEFyZSB3ZSBpbnNpZGUgYSBxdW90ZWQgc3RyaW5nPwogICAgICAgICAgICBpZiAoJyInID09PSAkY2hhciAmJiAkbm9lc2NhcGUpIHsKICAgICAgICAgICAgICAgICRvdXRPZlF1b3RlcyA9ICEkb3V0T2ZRdW90ZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJG91dE9mUXVvdGVzKSB7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgJG5vZXNjYXBlID0gJ1xcJyA9PT0gJGNoYXIgPyAhJG5vZXNjYXBlIDogdHJ1ZTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgnJyAhPT0gJGJ1ZmZlcikgewogICAgICAgICAgICAgICAgaWYgKCR1bmVzY2FwZVNsYXNoZXMpIHsKICAgICAgICAgICAgICAgICAgICAkYnVmZmVyID0gc3RyX3JlcGxhY2UoJ1xcLycsICcvJywgJGJ1ZmZlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCR1bmVzY2FwZVVuaWNvZGUgJiYgZnVuY3Rpb25fZXhpc3RzKCdtYl9jb252ZXJ0X2VuY29kaW5nJykpIHsKICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yOTM0NTYzL2hvdy10by1kZWNvZGUtdW5pY29kZS1lc2NhcGUtc2VxdWVuY2VzLWxpa2UtdTAwZWQtdG8tcHJvcGVyLXV0Zi04LWVuY29kZWQtY2hhCiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygnLyhcXFxcKyl1KFswLTlhLWZdezR9KS9pJywgZnVuY3Rpb24gKCRtYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICAkbCA9IHN0cmxlbigkbWF0Y2hbMV0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsICUgMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgPSBoZXhkZWMoJG1hdGNoWzJdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDB4RDgwMC4uMHhERkZGIGRlbm90ZXMgVVRGLTE2IHN1cnJvZ2F0ZSBwYWlyIHdoaWNoIHdvbid0IGJlIHVuZXNjYXBlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvNzUxMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDB4RDgwMCA8PSAkY29kZSAmJiAweERGRkYgPj0gJGNvZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcmVwZWF0KCdcXCcsICRsIC0gMSkgLiBtYl9jb252ZXJ0X2VuY29kaW5nKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2soJ0gqJywgJG1hdGNoWzJdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVVRGLTgnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVQ1MtMkJFJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaFswXTsKICAgICAgICAgICAgICAgICAgICB9LCAkYnVmZmVyKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICRidWZmZXIuJGNoYXI7CiAgICAgICAgICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCc6JyA9PT0gJGNoYXIpIHsKICAgICAgICAgICAgICAgIC8vIEFkZCBhIHNwYWNlIGFmdGVyIHRoZSA6IGNoYXJhY3RlcgogICAgICAgICAgICAgICAgJGNoYXIgLj0gJyAnOwogICAgICAgICAgICB9IGVsc2VpZiAoJ30nID09PSAkY2hhciB8fCAnXScgPT09ICRjaGFyKSB7CiAgICAgICAgICAgICAgICAkcG9zLS07CiAgICAgICAgICAgICAgICAkcHJldkNoYXIgPSBzdWJzdHIoJGpzb24sICRpIC0gMSwgMSk7CgogICAgICAgICAgICAgICAgaWYgKCd7JyAhPT0gJHByZXZDaGFyICYmICdbJyAhPT0gJHByZXZDaGFyKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBjaGFyYWN0ZXIgaXMgdGhlIGVuZCBvZiBhbiBlbGVtZW50LAogICAgICAgICAgICAgICAgICAgIC8vIG91dHB1dCBhIG5ldyBsaW5lIGFuZCBpbmRlbnQgdGhlIG5leHQgbGluZQogICAgICAgICAgICAgICAgICAgICRyZXN1bHQgLj0gJG5ld0xpbmU7CiAgICAgICAgICAgICAgICAgICAgZm9yICgkaiA9IDA7ICRqIDwgJHBvczsgJGorKykgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICRpbmRlbnRTdHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb2xsYXBzZSBlbXB0eSB7fSBhbmQgW10KICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gcnRyaW0oJHJlc3VsdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZXN1bHQgLj0gJGNoYXI7CgogICAgICAgICAgICAvLyBJZiB0aGUgbGFzdCBjaGFyYWN0ZXIgd2FzIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudCwKICAgICAgICAgICAgLy8gb3V0cHV0IGEgbmV3IGxpbmUgYW5kIGluZGVudCB0aGUgbmV4dCBsaW5lCiAgICAgICAgICAgIGlmICgnLCcgPT09ICRjaGFyIHx8ICd7JyA9PT0gJGNoYXIgfHwgJ1snID09PSAkY2hhcikgewogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkbmV3TGluZTsKCiAgICAgICAgICAgICAgICBpZiAoJ3snID09PSAkY2hhciB8fCAnWycgPT09ICRjaGFyKSB7CiAgICAgICAgICAgICAgICAgICAgJHBvcysrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoJGogPSAwOyAkaiA8ICRwb3M7ICRqKyspIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICRpbmRlbnRTdHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEpzb247Cgp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CnVzZSBTZWxkXEpzb25MaW50XEpzb25QYXJzZXI7CnVzZSBTZWxkXEpzb25MaW50XFBhcnNpbmdFeGNlcHRpb247CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXFRyYW5zcG9ydEV4Y2VwdGlvbjsKCi8qKgogKiBSZWFkcy93cml0ZXMganNvbiBmaWxlcy4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNoaXYgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSnNvbkZpbGUKewogICAgY29uc3QgTEFYX1NDSEVNQSA9IDE7CiAgICBjb25zdCBTVFJJQ1RfU0NIRU1BID0gMjsKCiAgICBjb25zdCBKU09OX1VORVNDQVBFRF9TTEFTSEVTID0gNjQ7CiAgICBjb25zdCBKU09OX1BSRVRUWV9QUklOVCA9IDEyODsKICAgIGNvbnN0IEpTT05fVU5FU0NBUEVEX1VOSUNPREUgPSAyNTY7CgogICAgY29uc3QgQ09NUE9TRVJfU0NIRU1BX1BBVEggPSAnLy4uLy4uLy4uL3Jlcy9jb21wb3Nlci1zY2hlbWEuanNvbic7CgogICAgcHJpdmF0ZSAkcGF0aDsKICAgIHByaXZhdGUgJGh0dHBEb3dubG9hZGVyOwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBqc29uIGZpbGUgcmVhZGVyL3BhcnNlci4KICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJHBhdGggICAgICAgICAgIHBhdGggdG8gYSBsb2NrZmlsZQogICAgICogQHBhcmFtICBIdHRwRG93bmxvYWRlciAgICAgICAgICAgICRodHRwRG93bmxvYWRlciByZXF1aXJlZCBmb3IgbG9hZGluZyBodHRwL2h0dHBzIGpzb24gZmlsZXMKICAgICAqIEBwYXJhbSAgSU9JbnRlcmZhY2UgICAgICAgICAgICAgICAkaW8KICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHBhdGgsIEh0dHBEb3dubG9hZGVyICRodHRwRG93bmxvYWRlciA9IG51bGwsIElPSW50ZXJmYWNlICRpbyA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhdGggPSAkcGF0aDsKCiAgICAgICAgaWYgKG51bGwgPT09ICRodHRwRG93bmxvYWRlciAmJiBwcmVnX21hdGNoKCd7Xmh0dHBzPzovL31pJywgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdodHRwIHVybHMgcmVxdWlyZSBhIEh0dHBEb3dubG9hZGVyIGluc3RhbmNlIHRvIGJlIHBhc3NlZCcpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhdGgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIGpzb24gZmlsZSBleGlzdHMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGlzdHMoKQogICAgewogICAgICAgIHJldHVybiBpc19maWxlKCR0aGlzLT5wYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWRzIGpzb24gZmlsZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24KICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWQoKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+aHR0cERvd25sb2FkZXIpIHsKICAgICAgICAgICAgICAgICRqc29uID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyLT5nZXQoJHRoaXMtPnBhdGgpLT5nZXRCb2R5KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvICYmICR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlYWxwYXRoSW5mbyA9ICcnOwogICAgICAgICAgICAgICAgICAgICRyZWFscGF0aCA9IHJlYWxwYXRoKCR0aGlzLT5wYXRoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRyZWFscGF0aCAmJiAkcmVhbHBhdGggIT09ICR0aGlzLT5wYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAkcmVhbHBhdGhJbmZvID0gJyAoJyAuICRyZWFscGF0aCAuICcpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSZWFkaW5nICcgLiAkdGhpcy0+cGF0aCAuICRyZWFscGF0aEluZm8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGpzb24gPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+cGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChUcmFuc3BvcnRFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksIDAsICRlKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IHJlYWQgJy4kdGhpcy0+cGF0aC4iXG5cbiIuJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RhdGljOjpwYXJzZUpzb24oJGpzb24sICR0aGlzLT5wYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyBqc29uIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGhhc2ggICAgd3JpdGVzIGhhc2ggaW50byBqc29uIGZpbGUKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRvcHRpb25zIGpzb25fZW5jb2RlIG9wdGlvbnMgKGRlZmF1bHRzIHRvIEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBKU09OX1BSRVRUWV9QUklOVCB8IEpTT05fVU5FU0NBUEVEX1VOSUNPREUpCiAgICAgKiBAdGhyb3dzIFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb258XEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoYXJyYXkgJGhhc2gsICRvcHRpb25zID0gNDQ4KQogICAgewogICAgICAgIGlmICgkdGhpcy0+cGF0aCA9PT0gJ3BocDovL21lbW9yeScpIHsKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPnBhdGgsIHN0YXRpYzo6ZW5jb2RlKCRoYXNoLCAkb3B0aW9ucykpOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGRpciA9IGRpcm5hbWUoJHRoaXMtPnBhdGgpOwogICAgICAgIGlmICghaXNfZGlyKCRkaXIpKSB7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZGlyKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgcmVhbHBhdGgoJGRpcikuJyBleGlzdHMgYW5kIGlzIG5vdCBhIGRpcmVjdG9yeS4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghQG1rZGlyKCRkaXIsIDA3NzcsIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAkZGlyLicgZG9lcyBub3QgZXhpc3QgYW5kIGNvdWxkIG5vdCBiZSBjcmVhdGVkLicKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRyZXRyaWVzID0gMzsKICAgICAgICB3aGlsZSAoJHJldHJpZXMtLSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHRoaXMtPnBhdGgsIHN0YXRpYzo6ZW5jb2RlKCRoYXNoLCAkb3B0aW9ucykuICgkb3B0aW9ucyAmIHNlbGY6OkpTT05fUFJFVFRZX1BSSU5UID8gIlxuIiA6ICcnKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCRyZXRyaWVzKSB7CiAgICAgICAgICAgICAgICAgICAgdXNsZWVwKDUwMDAwMCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBtb2RpZnkgZmlsZSBwcm9wZXJ0aWVzIG9ubHkgaWYgY29udGVudCBtb2RpZmllZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbGVQdXRDb250ZW50c0lmTW9kaWZpZWQoJHBhdGgsICRjb250ZW50KQogICAgewogICAgICAgICRjdXJyZW50Q29udGVudCA9IEBmaWxlX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgaWYgKCEkY3VycmVudENvbnRlbnQgfHwgKCRjdXJyZW50Q29udGVudCAhPSAkY29udGVudCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkY29udGVudCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyB0aGUgc2NoZW1hIG9mIHRoZSBjdXJyZW50IGpzb24gZmlsZSBhY2NvcmRpbmcgdG8gY29tcG9zZXItc2NoZW1hLmpzb24gcnVsZXMKICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAgICAgICRzY2hlbWEgICAgIGEgSnNvbkZpbGU6OipfU0NIRU1BIGNvbnN0YW50CiAgICAgKiBAcGFyYW0gIHN0cmluZ3xudWxsICAgICAgICAgICAgICRzY2hlbWFGaWxlIGEgcGF0aCB0byB0aGUgc2NoZW1hIGZpbGUKICAgICAqIEB0aHJvd3MgSnNvblZhbGlkYXRpb25FeGNlcHRpb24KICAgICAqIEB0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sICAgICAgICAgICAgICAgICAgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlU2NoZW1hKCRzY2hlbWEgPSBzZWxmOjpTVFJJQ1RfU0NIRU1BLCAkc2NoZW1hRmlsZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+cGF0aCk7CiAgICAgICAgJGRhdGEgPSBqc29uX2RlY29kZSgkY29udGVudCk7CgogICAgICAgIGlmIChudWxsID09PSAkZGF0YSAmJiAnbnVsbCcgIT09ICRjb250ZW50KSB7CiAgICAgICAgICAgIHNlbGY6OnZhbGlkYXRlU3ludGF4KCRjb250ZW50LCAkdGhpcy0+cGF0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHNjaGVtYUZpbGUpIHsKICAgICAgICAgICAgJHNjaGVtYUZpbGUgPSBfX0RJUl9fIC4gc2VsZjo6Q09NUE9TRVJfU0NIRU1BX1BBVEg7CiAgICAgICAgfQoKICAgICAgICAvLyBQcmVwZW5kIHdpdGggZmlsZTovLyBvbmx5IHdoZW4gbm90IHVzaW5nIGEgc3BlY2lhbCBzY2hlbWEgYWxyZWFkeSAoZS5nLiBpbiB0aGUgcGhhcikKICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBvcygkc2NoZW1hRmlsZSwgJzovLycpKSB7CiAgICAgICAgICAgICRzY2hlbWFGaWxlID0gJ2ZpbGU6Ly8nIC4gJHNjaGVtYUZpbGU7CiAgICAgICAgfQoKICAgICAgICAkc2NoZW1hRGF0YSA9IChvYmplY3QpIGFycmF5KCckcmVmJyA9PiAkc2NoZW1hRmlsZSk7CgogICAgICAgIGlmICgkc2NoZW1hID09PSBzZWxmOjpMQVhfU0NIRU1BKSB7CiAgICAgICAgICAgICRzY2hlbWFEYXRhLT5hZGRpdGlvbmFsUHJvcGVydGllcyA9IHRydWU7CiAgICAgICAgICAgICRzY2hlbWFEYXRhLT5yZXF1aXJlZCA9IGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICAkdmFsaWRhdG9yID0gbmV3IFZhbGlkYXRvcigpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCRkYXRhLCAkc2NoZW1hRGF0YSk7CgogICAgICAgIC8vIFRPRE8gYWRkIG1vcmUgdmFsaWRhdGlvbiBsaWtlIGNoZWNrIHZlcnNpb24gY29uc3RyYWludHMgYW5kIHN1Y2gsIHBlcmhhcHMgYnVpbGQgdGhhdCBpbnRvIHRoZSBhcnJheWxvYWRlcj8KCiAgICAgICAgaWYgKCEkdmFsaWRhdG9yLT5pc1ZhbGlkKCkpIHsKICAgICAgICAgICAgJGVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKChhcnJheSkgJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkgYXMgJGVycm9yKSB7CiAgICAgICAgICAgICAgICAkZXJyb3JzW10gPSAoJGVycm9yWydwcm9wZXJ0eSddID8gJGVycm9yWydwcm9wZXJ0eSddLicgOiAnIDogJycpLiRlcnJvclsnbWVzc2FnZSddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBKc29uVmFsaWRhdGlvbkV4Y2VwdGlvbignIicuJHRoaXMtPnBhdGguJyIgZG9lcyBub3QgbWF0Y2ggdGhlIGV4cGVjdGVkIEpTT04gc2NoZW1hJywgJGVycm9ycyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuY29kZXMgYW4gYXJyYXkgaW50byAob3B0aW9uYWxseSBwcmV0dHktcHJpbnRlZCkgSlNPTgogICAgICoKICAgICAqIEBwYXJhbSAgbWl4ZWQgICRkYXRhICAgIERhdGEgdG8gZW5jb2RlIGludG8gYSBmb3JtYXR0ZWQgSlNPTiBzdHJpbmcKICAgICAqIEBwYXJhbSAgaW50ICAgICRvcHRpb25zIGpzb25fZW5jb2RlIG9wdGlvbnMgKGRlZmF1bHRzIHRvIEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBKU09OX1BSRVRUWV9QUklOVCB8IEpTT05fVU5FU0NBUEVEX1VOSUNPREUpCiAgICAgKiBAcmV0dXJuIHN0cmluZyBFbmNvZGVkIGpzb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlbmNvZGUoJGRhdGEsICRvcHRpb25zID0gNDQ4KQogICAgewogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA1MDQwMCkgewogICAgICAgICAgICAkanNvbiA9IGpzb25fZW5jb2RlKCRkYXRhLCAkb3B0aW9ucyk7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGpzb24pIHsKICAgICAgICAgICAgICAgIHNlbGY6OnRocm93RW5jb2RlRXJyb3IoanNvbl9sYXN0X2Vycm9yKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAgY29tcGFjdCBicmFja2V0cyB0byBmb2xsb3cgcmVjZW50IHBocCB2ZXJzaW9ucwogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA1MDQyOCB8fCAoUEhQX1ZFUlNJT05fSUQgPj0gNTA1MDAgJiYgUEhQX1ZFUlNJT05fSUQgPCA1MDUxMikgfHwgKGRlZmluZWQoJ0pTT05fQ19WRVJTSU9OJykgJiYgdmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oJ2pzb24nKSwgJzEuMy42JywgJzwnKSkpIHsKICAgICAgICAgICAgICAgICRqc29uID0gcHJlZ19yZXBsYWNlKCcvXFtccytcXS8nLCAnW10nLCAkanNvbik7CiAgICAgICAgICAgICAgICAkanNvbiA9IHByZWdfcmVwbGFjZSgnL1x7XHMrXH0vJywgJ3t9JywgJGpzb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGpzb247CiAgICAgICAgfQoKICAgICAgICAkanNvbiA9IGpzb25fZW5jb2RlKCRkYXRhKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRqc29uKSB7CiAgICAgICAgICAgIHNlbGY6OnRocm93RW5jb2RlRXJyb3IoanNvbl9sYXN0X2Vycm9yKCkpOwogICAgICAgIH0KCiAgICAgICAgJHByZXR0eVByaW50ID0gKGJvb2wpICgkb3B0aW9ucyAmIHNlbGY6OkpTT05fUFJFVFRZX1BSSU5UKTsKICAgICAgICAkdW5lc2NhcGVVbmljb2RlID0gKGJvb2wpICgkb3B0aW9ucyAmIHNlbGY6OkpTT05fVU5FU0NBUEVEX1VOSUNPREUpOwogICAgICAgICR1bmVzY2FwZVNsYXNoZXMgPSAoYm9vbCkgKCRvcHRpb25zICYgc2VsZjo6SlNPTl9VTkVTQ0FQRURfU0xBU0hFUyk7CgogICAgICAgIGlmICghJHByZXR0eVByaW50ICYmICEkdW5lc2NhcGVVbmljb2RlICYmICEkdW5lc2NhcGVTbGFzaGVzKSB7CiAgICAgICAgICAgIHJldHVybiAkanNvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBKc29uRm9ybWF0dGVyOjpmb3JtYXQoJGpzb24sICR1bmVzY2FwZVVuaWNvZGUsICR1bmVzY2FwZVNsYXNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogVGhyb3dzIGFuIGV4Y2VwdGlvbiBhY2NvcmRpbmcgdG8gYSBnaXZlbiBjb2RlIHdpdGggYSBjdXN0b21pemVkIG1lc3NhZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICRjb2RlIHJldHVybiBjb2RlIG9mIGpzb25fbGFzdF9lcnJvciBmdW5jdGlvbgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB0aHJvd0VuY29kZUVycm9yKCRjb2RlKQogICAgewogICAgICAgIHN3aXRjaCAoJGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBKU09OX0VSUk9SX0RFUFRIOgogICAgICAgICAgICAgICAgJG1zZyA9ICdNYXhpbXVtIHN0YWNrIGRlcHRoIGV4Y2VlZGVkJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfU1RBVEVfTUlTTUFUQ0g6CiAgICAgICAgICAgICAgICAkbXNnID0gJ1VuZGVyZmxvdyBvciB0aGUgbW9kZXMgbWlzbWF0Y2gnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9DVFJMX0NIQVI6CiAgICAgICAgICAgICAgICAkbXNnID0gJ1VuZXhwZWN0ZWQgY29udHJvbCBjaGFyYWN0ZXIgZm91bmQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9VVEY4OgogICAgICAgICAgICAgICAgJG1zZyA9ICdNYWxmb3JtZWQgVVRGLTggY2hhcmFjdGVycywgcG9zc2libHkgaW5jb3JyZWN0bHkgZW5jb2RlZCc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICRtc2cgPSAnVW5rbm93biBlcnJvcic7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0pTT04gZW5jb2RpbmcgZmFpbGVkOiAnLiRtc2cpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGpzb24gc3RyaW5nIGFuZCByZXR1cm5zIGhhc2guCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkanNvbiBqc29uIHN0cmluZwogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSB0aGUganNvbiBmaWxlCiAgICAgKgogICAgICogQHRocm93cyBQYXJzaW5nRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcGFyc2VKc29uKCRqc29uLCAkZmlsZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRqc29uKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJGRhdGEgPSBqc29uX2RlY29kZSgkanNvbiwgdHJ1ZSk7CiAgICAgICAgaWYgKG51bGwgPT09ICRkYXRhICYmIEpTT05fRVJST1JfTk9ORSAhPT0ganNvbl9sYXN0X2Vycm9yKCkpIHsKICAgICAgICAgICAgc2VsZjo6dmFsaWRhdGVTeW50YXgoJGpzb24sICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyB0aGUgc3ludGF4IG9mIGEgSlNPTiBzdHJpbmcKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJGpzb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkZmlsZQogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbCAgICAgICAgICAgICAgICAgICAgICB0cnVlIG9uIHN1Y2Nlc3MKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB2YWxpZGF0ZVN5bnRheCgkanNvbiwgJGZpbGUgPSBudWxsKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgSnNvblBhcnNlcigpOwogICAgICAgICRyZXN1bHQgPSAkcGFyc2VyLT5saW50KCRqc29uKTsKICAgICAgICBpZiAobnVsbCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICBpZiAoZGVmaW5lZCgnSlNPTl9FUlJPUl9VVEY4JykgJiYgSlNPTl9FUlJPUl9VVEY4ID09PSBqc29uX2xhc3RfZXJyb3IoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJyInLiRmaWxlLiciIGlzIG5vdCBVVEYtOCwgY291bGQgbm90IHBhcnNlIGFzIEpTT04nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbignIicuJGZpbGUuJyIgZG9lcyBub3QgY29udGFpbiB2YWxpZCBKU09OJy4iXG4iLiRyZXN1bHQtPmdldE1lc3NhZ2UoKSwgJHJlc3VsdC0+Z2V0RGV0YWlscygpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFeGNlcHRpb247CgovKioKICogU3BlY2lmaWMgZXhjZXB0aW9uIGZvciBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyIGNyZWF0aW9uLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBOb1NzbEV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSXJyZWNvdmVyYWJsZURvd25sb2FkRXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXElPXENvbnNvbGVJTzsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxPcGVyYXRpb25JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVwZGF0ZU9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVW5pbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb247CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXE1hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlcjsKdXNlIENvbXBvc2VyXFV0aWxcTG9vcDsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogUGFja2FnZSBvcGVyYXRpb24gbWFuYWdlci4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgSW5zdGFsbGF0aW9uTWFuYWdlcgp7CiAgICAvKiogQHZhciBhcnJheTxJbnN0YWxsZXJJbnRlcmZhY2U+ICovCiAgICBwcml2YXRlICRpbnN0YWxsZXJzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgSW5zdGFsbGVySW50ZXJmYWNlPiAqLwogICAgcHJpdmF0ZSAkY2FjaGUgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXk8c3RyaW5nLCBhcnJheTxQYWNrYWdlSW50ZXJmYWNlPj4gKi8KICAgIHByaXZhdGUgJG5vdGlmaWFibGVQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBMb29wICovCiAgICBwcml2YXRlICRsb29wOwogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqIEB2YXIgRXZlbnREaXNwYXRjaGVyICovCiAgICBwcml2YXRlICRldmVudERpc3BhdGNoZXI7CiAgICAvKiogQHZhciBib29sICovCiAgICBwcml2YXRlICRvdXRwdXRQcm9ncmVzczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTG9vcCAkbG9vcCwgSU9JbnRlcmZhY2UgJGlvLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvb3AgPSAkbG9vcDsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciA9ICRldmVudERpc3BhdGNoZXI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICAkdGhpcy0+bm90aWZpYWJsZVBhY2thZ2VzID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgaW5zdGFsbGVyCiAgICAgKgogICAgICogQHBhcmFtIEluc3RhbGxlckludGVyZmFjZSAkaW5zdGFsbGVyIGluc3RhbGxlciBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkSW5zdGFsbGVyKEluc3RhbGxlckludGVyZmFjZSAkaW5zdGFsbGVyKQogICAgewogICAgICAgIGFycmF5X3Vuc2hpZnQoJHRoaXMtPmluc3RhbGxlcnMsICRpbnN0YWxsZXIpOwogICAgICAgICR0aGlzLT5jYWNoZSA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGluc3RhbGxlcgogICAgICoKICAgICAqIEBwYXJhbSBJbnN0YWxsZXJJbnRlcmZhY2UgJGluc3RhbGxlciBpbnN0YWxsZXIgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUluc3RhbGxlcihJbnN0YWxsZXJJbnRlcmZhY2UgJGluc3RhbGxlcikKICAgIHsKICAgICAgICBpZiAoZmFsc2UgIT09ICgka2V5ID0gYXJyYXlfc2VhcmNoKCRpbnN0YWxsZXIsICR0aGlzLT5pbnN0YWxsZXJzLCB0cnVlKSkpIHsKICAgICAgICAgICAgYXJyYXlfc3BsaWNlKCR0aGlzLT5pbnN0YWxsZXJzLCAka2V5LCAxKTsKICAgICAgICAgICAgJHRoaXMtPmNhY2hlID0gYXJyYXkoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNhYmxlcyBwbHVnaW5zLgogICAgICoKICAgICAqIFdlIHByZXZlbnQgYW55IHBsdWdpbnMgZnJvbSBiZWluZyBpbnN0YW50aWF0ZWQgYnkgc2ltcGx5CiAgICAgKiBkZWFjdGl2YXRpbmcgdGhlIGluc3RhbGxlciBmb3IgdGhlbS4gVGhpcyBlbnN1cmUgdGhhdCBubyB0aGlyZC1wYXJ0eQogICAgICogY29kZSBpcyBldmVyIGV4ZWN1dGVkLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZVBsdWdpbnMoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5pbnN0YWxsZXJzIGFzICRpID0+ICRpbnN0YWxsZXIpIHsKICAgICAgICAgICAgaWYgKCEkaW5zdGFsbGVyIGluc3RhbmNlb2YgUGx1Z2luSW5zdGFsbGVyKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmluc3RhbGxlcnNbJGldKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGluc3RhbGxlciBmb3IgYSBzcGVjaWZpYyBwYWNrYWdlIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSBwYWNrYWdlIHR5cGUKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgaW5zdGFsbGVyIGZvciBwcm92aWRlZCB0eXBlIGlzIG5vdCByZWdpc3RlcmVkCiAgICAgKiBAcmV0dXJuIEluc3RhbGxlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGVyKCR0eXBlKQogICAgewogICAgICAgICR0eXBlID0gc3RydG9sb3dlcigkdHlwZSk7CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y2FjaGVbJHR5cGVdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNhY2hlWyR0eXBlXTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5pbnN0YWxsZXJzIGFzICRpbnN0YWxsZXIpIHsKICAgICAgICAgICAgaWYgKCRpbnN0YWxsZXItPnN1cHBvcnRzKCR0eXBlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jYWNoZVskdHlwZV0gPSAkaW5zdGFsbGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVW5rbm93biBpbnN0YWxsZXIgdHlwZTogJy4kdHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciBwcm92aWRlZCBwYWNrYWdlIGlzIGluc3RhbGxlZCBpbiBvbmUgb2YgdGhlIHJlZ2lzdGVyZWQgaW5zdGFsbGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1BhY2thZ2VJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSAmJiAkdGhpcy0+aXNQYWNrYWdlSW5zdGFsbGVkKCRyZXBvLCAkcGFja2FnZS0+Z2V0QWxpYXNPZigpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SW5zdGFsbGVyKCRwYWNrYWdlLT5nZXRUeXBlKCkpLT5pc0luc3RhbGxlZCgkcmVwbywgJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogSW5zdGFsbCBiaW5hcnkgZm9yIHRoZSBnaXZlbiBwYWNrYWdlLgogICAgICogSWYgdGhlIGluc3RhbGxlciBhc3NvY2lhdGVkIHRvIHRoaXMgcGFja2FnZSBkb2Vzbid0IGhhbmRsZSB0aGF0IGZ1bmN0aW9uLCBpdCdsbCBkbyBub3RoaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIFBhY2thZ2UgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuc3VyZUJpbmFyaWVzUHJlc2VuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIC8vIG5vIGluc3RhbGxlciBmb3VuZCBmb3IgdGhlIGN1cnJlbnQgcGFja2FnZSB0eXBlIChAc2VlIGBnZXRJbnN0YWxsZXIoKWApCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIGlmIHRoZSBnaXZlbiBpbnN0YWxsZXIgc3VwcG9ydCBpbnN0YWxsaW5nIGJpbmFyaWVzCiAgICAgICAgaWYgKCRpbnN0YWxsZXIgaW5zdGFuY2VvZiBCaW5hcnlQcmVzZW5jZUludGVyZmFjZSkgewogICAgICAgICAgICAkaW5zdGFsbGVyLT5lbnN1cmVCaW5hcmllc1ByZXNlbmNlKCRwYWNrYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyBzb2x2ZXIgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICAkcmVwbyAgICAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGFkZC9yZW1vdmUvdXBkYXRlIHBhY2thZ2VzCiAgICAgKiBAcGFyYW0gT3BlcmF0aW9uSW50ZXJmYWNlW10gJG9wZXJhdGlvbnMgb3BlcmF0aW9ucyB0byBleGVjdXRlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgJGRldk1vZGUgICAgd2hldGhlciB0aGUgaW5zdGFsbCBpcyBiZWluZyBydW4gaW4gZGV2IG1vZGUKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAkcnVuU2NyaXB0cyB3aGV0aGVyIHRvIGRpc3BhdGNoIHNjcmlwdCBldmVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4ZWN1dGUoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgYXJyYXkgJG9wZXJhdGlvbnMsICRkZXZNb2RlID0gdHJ1ZSwgJHJ1blNjcmlwdHMgPSB0cnVlKQogICAgewogICAgICAgICRjbGVhbnVwUHJvbWlzZXMgPSBhcnJheSgpOwoKICAgICAgICAkbG9vcCA9ICR0aGlzLT5sb29wOwogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKICAgICAgICAkcnVuQ2xlYW51cCA9IGZ1bmN0aW9uICgpIHVzZSAoJiRjbGVhbnVwUHJvbWlzZXMsICRsb29wKSB7CiAgICAgICAgICAgICRwcm9taXNlcyA9IGFycmF5KCk7CgogICAgICAgICAgICAkbG9vcC0+YWJvcnRKb2JzKCk7CgogICAgICAgICAgICBmb3JlYWNoICgkY2xlYW51cFByb21pc2VzIGFzICRjbGVhbnVwKSB7CiAgICAgICAgICAgICAgICAkcHJvbWlzZXNbXSA9IG5ldyBcUmVhY3RcUHJvbWlzZVxQcm9taXNlKGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCkgdXNlICgkY2xlYW51cCkgewogICAgICAgICAgICAgICAgICAgICRwcm9taXNlID0gJGNsZWFudXAoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzb2x2ZSgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHJlc29sdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRwcm9taXNlcykpIHsKICAgICAgICAgICAgICAgICRsb29wLT53YWl0KCRwcm9taXNlcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAkaGFuZGxlSW50ZXJydXB0c1VuaXggPSBmdW5jdGlvbl9leGlzdHMoJ3BjbnRsX2FzeW5jX3NpZ25hbHMnKSAmJiBmdW5jdGlvbl9leGlzdHMoJ3BjbnRsX3NpZ25hbCcpOwogICAgICAgICRoYW5kbGVJbnRlcnJ1cHRzV2luZG93cyA9IGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXInKSAmJiBQSFBfU0FQSSA9PT0gJ2NsaSc7CiAgICAgICAgJHByZXZIYW5kbGVyID0gbnVsbDsKICAgICAgICAkd2luZG93c0hhbmRsZXIgPSBudWxsOwogICAgICAgIGlmICgkaGFuZGxlSW50ZXJydXB0c1VuaXgpIHsKICAgICAgICAgICAgcGNudGxfYXN5bmNfc2lnbmFscyh0cnVlKTsKICAgICAgICAgICAgJHByZXZIYW5kbGVyID0gcGNudGxfc2lnbmFsX2dldF9oYW5kbGVyKFNJR0lOVCk7CiAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsIGZ1bmN0aW9uICgkc2lnKSB1c2UgKCRydW5DbGVhbnVwLCAkcHJldkhhbmRsZXIsICRpbykgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCdSZWNlaXZlZCBTSUdJTlQsIGFib3J0aW5nJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgICRydW5DbGVhbnVwKCk7CgogICAgICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkcHJldkhhbmRsZXIsIGFycmF5KFNJR19ERkwsIFNJR19JR04pLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIGNhbGxfdXNlcl9mdW5jKCRwcmV2SGFuZGxlciwgJHNpZyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZXhpdCgxMzApOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgaWYgKCRoYW5kbGVJbnRlcnJ1cHRzV2luZG93cykgewogICAgICAgICAgICAkd2luZG93c0hhbmRsZXIgPSBmdW5jdGlvbiAoJGV2ZW50KSB1c2UgKCRydW5DbGVhbnVwLCAkaW8pIHsKICAgICAgICAgICAgICAgIGlmICgkZXZlbnQgIT09IFBIUF9XSU5ET1dTX0VWRU5UX0NUUkxfQykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignUmVjZWl2ZWQgQ1RSTCtDLCBhYm9ydGluZycsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAkcnVuQ2xlYW51cCgpOwoKICAgICAgICAgICAgICAgIGV4aXQoMTMwKTsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXIoJHdpbmRvd3NIYW5kbGVyKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIGV4ZWN1dGUgb3BlcmF0aW9ucyBpbiBiYXRjaGVzIHRvIG1ha2Ugc3VyZSBkb3dubG9hZC1tb2RpZnlpbmctcGx1Z2lucyBhcmUgaW5zdGFsbGVkCiAgICAgICAgICAgIC8vIGJlZm9yZSB0aGUgb3RoZXIgcGFja2FnZXMgZ2V0IGRvd25sb2FkZWQKICAgICAgICAgICAgJGJhdGNoZXMgPSBhcnJheSgpOwogICAgICAgICAgICAkYmF0Y2ggPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkb3BlcmF0aW9ucyBhcyAkaW5kZXggPT4gJG9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRvcGVyYXRpb24tPmdldE9wZXJhdGlvblR5cGUoKSwgYXJyYXkoJ3VwZGF0ZScsICdpbnN0YWxsJyksIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRPcGVyYXRpb25UeXBlKCkgPT09ICd1cGRhdGUnID8gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpIDogJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItcGx1Z2luJyAmJiAoJGV4dHJhID0gJHBhY2thZ2UtPmdldEV4dHJhKCkpICYmIGlzc2V0KCRleHRyYVsncGx1Z2luLW1vZGlmaWVzLWRvd25sb2FkcyddKSAmJiAkZXh0cmFbJ3BsdWdpbi1tb2RpZmllcy1kb3dubG9hZHMnXSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGJhdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYmF0Y2hlc1tdID0gJGJhdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRiYXRjaGVzW10gPSBhcnJheSgkaW5kZXggPT4gJG9wZXJhdGlvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICRiYXRjaCA9IGFycmF5KCk7CgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkYmF0Y2hbJGluZGV4XSA9ICRvcGVyYXRpb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkYmF0Y2gpIHsKICAgICAgICAgICAgICAgICRiYXRjaGVzW10gPSAkYmF0Y2g7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRiYXRjaGVzIGFzICRiYXRjaCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRvd25sb2FkQW5kRXhlY3V0ZUJhdGNoKCRyZXBvLCAkYmF0Y2gsICRjbGVhbnVwUHJvbWlzZXMsICRkZXZNb2RlLCAkcnVuU2NyaXB0cywgJG9wZXJhdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkcnVuQ2xlYW51cCgpOwoKICAgICAgICAgICAgaWYgKCRoYW5kbGVJbnRlcnJ1cHRzVW5peCkgewogICAgICAgICAgICAgICAgcGNudGxfc2lnbmFsKFNJR0lOVCwgJHByZXZIYW5kbGVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGhhbmRsZUludGVycnVwdHNXaW5kb3dzKSB7CiAgICAgICAgICAgICAgICBzYXBpX3dpbmRvd3Nfc2V0X2N0cmxfaGFuZGxlcigkcHJldkhhbmRsZXIsIGZhbHNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhhbmRsZUludGVycnVwdHNVbml4KSB7CiAgICAgICAgICAgIHBjbnRsX3NpZ25hbChTSUdJTlQsICRwcmV2SGFuZGxlcik7CiAgICAgICAgfQogICAgICAgIGlmICgkaGFuZGxlSW50ZXJydXB0c1dpbmRvd3MpIHsKICAgICAgICAgICAgc2FwaV93aW5kb3dzX3NldF9jdHJsX2hhbmRsZXIoJHByZXZIYW5kbGVyLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBkbyBhIGxhc3Qgd3JpdGUgc28gdGhhdCB3ZSB3cml0ZSB0aGUgcmVwb3NpdG9yeSBldmVuIGlmIG5vdGhpbmcgY2hhbmdlZAogICAgICAgIC8vIGFzIHRoYXQgY2FuIHRyaWdnZXIgYW4gdXBkYXRlIG9mIHNvbWUgZmlsZXMgbGlrZSBJbnN0YWxsZWRWZXJzaW9ucy5waHAgaWYKICAgICAgICAvLyBydW5uaW5nIGEgbmV3IGNvbXBvc2VyIHZlcnNpb24KICAgICAgICAkcmVwby0+d3JpdGUoJGRldk1vZGUsICR0aGlzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkb3BlcmF0aW9ucyAgICBMaXN0IG9mIG9wZXJhdGlvbnMgdG8gZXhlY3V0ZSBpbiB0aGlzIGJhdGNoCiAgICAgKiBAcGFyYW0gYXJyYXkgJGFsbE9wZXJhdGlvbnMgQ29tcGxldGUgbGlzdCBvZiBvcGVyYXRpb25zIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBpbnN0YWxsIGpvYiwgdXNlZCBmb3IgZXZlbnQgbGlzdGVuZXJzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG93bmxvYWRBbmRFeGVjdXRlQmF0Y2goUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgYXJyYXkgJG9wZXJhdGlvbnMsIGFycmF5ICYkY2xlYW51cFByb21pc2VzLCAkZGV2TW9kZSwgJHJ1blNjcmlwdHMsIGFycmF5ICRhbGxPcGVyYXRpb25zKQogICAgewogICAgICAgICRwcm9taXNlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRvcGVyYXRpb25zIGFzICRpbmRleCA9PiAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICRvcFR5cGUgPSAkb3BlcmF0aW9uLT5nZXRPcGVyYXRpb25UeXBlKCk7CgogICAgICAgICAgICAvLyBpZ25vcmluZyBhbGlhcyBvcHMgYXMgdGhleSBkb24ndCBuZWVkIHRvIGV4ZWN1dGUgYW55dGhpbmcgYXQgdGhpcyBzdGFnZQogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRvcFR5cGUsIGFycmF5KCd1cGRhdGUnLCAnaW5zdGFsbCcsICd1bmluc3RhbGwnKSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG9wVHlwZSA9PT0gJ3VwZGF0ZScpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0VGFyZ2V0UGFja2FnZSgpOwogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpOwogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaW5zdGFsbGVyID0gJHRoaXMtPmdldEluc3RhbGxlcigkcGFja2FnZS0+Z2V0VHlwZSgpKTsKCiAgICAgICAgICAgICRjbGVhbnVwUHJvbWlzZXNbJGluZGV4XSA9IGZ1bmN0aW9uICgpIHVzZSAoJG9wVHlwZSwgJGluc3RhbGxlciwgJHBhY2thZ2UsICRpbml0aWFsUGFja2FnZSkgewogICAgICAgICAgICAgICAgLy8gYXZvaWQgY2FsbGluZyBjbGVhbnVwIGlmIHRoZSBkb3dubG9hZCB3YXMgbm90IGV2ZW4gaW5pdGlhbGl6ZWQgZm9yIGEgcGFja2FnZQogICAgICAgICAgICAgICAgLy8gYXMgd2l0aG91dCBpbnN0YWxsYXRpb24gc291cmNlIGNvbmZpZ3VyZWQgbm90aGluZyB3aWxsIHdvcmsKICAgICAgICAgICAgICAgIGlmICghJHBhY2thZ2UtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkaW5zdGFsbGVyLT5jbGVhbnVwKCRvcFR5cGUsICRwYWNrYWdlLCAkaW5pdGlhbFBhY2thZ2UpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWYgKCRvcFR5cGUgIT09ICd1bmluc3RhbGwnKSB7CiAgICAgICAgICAgICAgICAkcHJvbWlzZSA9ICRpbnN0YWxsZXItPmRvd25sb2FkKCRwYWNrYWdlLCAkaW5pdGlhbFBhY2thZ2UpOwogICAgICAgICAgICAgICAgaWYgKCRwcm9taXNlKSB7CiAgICAgICAgICAgICAgICAgICAgJHByb21pc2VzW10gPSAkcHJvbWlzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gZXhlY3V0ZSBhbGwgZG93bmxvYWRzIGZpcnN0CiAgICAgICAgaWYgKGNvdW50KCRwcm9taXNlcykpIHsKICAgICAgICAgICAgJHRoaXMtPndhaXRPblByb21pc2VzKCRwcm9taXNlcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBleGVjdXRlIG9wZXJhdGlvbnMgaW4gYmF0Y2hlcyB0byBtYWtlIHN1cmUgZXZlcnkgcGx1Z2luIGlzIGluc3RhbGxlZCBpbiB0aGUKICAgICAgICAvLyByaWdodCBvcmRlciBhbmQgYWN0aXZhdGVkIGJlZm9yZSB0aGUgcGFja2FnZXMgZGVwZW5kaW5nIG9uIGl0IGFyZSBpbnN0YWxsZWQKICAgICAgICAkYmF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgJGJhdGNoID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkb3BlcmF0aW9ucyBhcyAkaW5kZXggPT4gJG9wZXJhdGlvbikgewogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJG9wZXJhdGlvbi0+Z2V0T3BlcmF0aW9uVHlwZSgpLCBhcnJheSgndXBkYXRlJywgJ2luc3RhbGwnKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0T3BlcmF0aW9uVHlwZSgpID09PSAndXBkYXRlJyA/ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKSA6ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItcGx1Z2luJyB8fCAkcGFja2FnZS0+Z2V0VHlwZSgpID09PSAnY29tcG9zZXItaW5zdGFsbGVyJykgewogICAgICAgICAgICAgICAgICAgIGlmICgkYmF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJhdGNoZXNbXSA9ICRiYXRjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGJhdGNoZXNbXSA9IGFycmF5KCRpbmRleCA9PiAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgICAgICAgICAkYmF0Y2ggPSBhcnJheSgpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkYmF0Y2hbJGluZGV4XSA9ICRvcGVyYXRpb247CiAgICAgICAgfQoKICAgICAgICBpZiAoJGJhdGNoKSB7CiAgICAgICAgICAgICRiYXRjaGVzW10gPSAkYmF0Y2g7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkYmF0Y2hlcyBhcyAkYmF0Y2gpIHsKICAgICAgICAgICAgJHRoaXMtPmV4ZWN1dGVCYXRjaCgkcmVwbywgJGJhdGNoLCAkY2xlYW51cFByb21pc2VzLCAkZGV2TW9kZSwgJHJ1blNjcmlwdHMsICRhbGxPcGVyYXRpb25zKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wZXJhdGlvbnMgICAgTGlzdCBvZiBvcGVyYXRpb25zIHRvIGV4ZWN1dGUgaW4gdGhpcyBiYXRjaAogICAgICogQHBhcmFtIGFycmF5ICRhbGxPcGVyYXRpb25zIENvbXBsZXRlIGxpc3Qgb2Ygb3BlcmF0aW9ucyB0byBiZSBleGVjdXRlZCBpbiB0aGUgaW5zdGFsbCBqb2IsIHVzZWQgZm9yIGV2ZW50IGxpc3RlbmVycwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4ZWN1dGVCYXRjaChSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBhcnJheSAkb3BlcmF0aW9ucywgYXJyYXkgJGNsZWFudXBQcm9taXNlcywgJGRldk1vZGUsICRydW5TY3JpcHRzLCBhcnJheSAkYWxsT3BlcmF0aW9ucykKICAgIHsKICAgICAgICAkcHJvbWlzZXMgPSBhcnJheSgpOwogICAgICAgICRwb3N0RXhlY0NhbGxiYWNrcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRvcGVyYXRpb25zIGFzICRpbmRleCA9PiAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICRvcFR5cGUgPSAkb3BlcmF0aW9uLT5nZXRPcGVyYXRpb25UeXBlKCk7CgogICAgICAgICAgICAvLyBpZ25vcmluZyBhbGlhcyBvcHMgYXMgdGhleSBkb24ndCBuZWVkIHRvIGV4ZWN1dGUgYW55dGhpbmcKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkb3BUeXBlLCBhcnJheSgndXBkYXRlJywgJ2luc3RhbGwnLCAndW5pbnN0YWxsJykpKSB7CiAgICAgICAgICAgICAgICAvLyBvdXRwdXQgYWxpYXMgb3BzIGluIGRlYnVnIHZlcmJvc2l0eSBhcyB0aGV5IGhhdmUgbm8gb3V0cHV0IG90aGVyd2lzZQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgIC0gJyAuICRvcGVyYXRpb24tPnNob3coZmFsc2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT4kb3BUeXBlKCRyZXBvLCAkb3BlcmF0aW9uKTsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRvcFR5cGUgPT09ICd1cGRhdGUnKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgICRpbml0aWFsUGFja2FnZSA9ICRvcGVyYXRpb24tPmdldEluaXRpYWxQYWNrYWdlKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgICRpbml0aWFsUGFja2FnZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJHBhY2thZ2UtPmdldFR5cGUoKSk7CgogICAgICAgICAgICAkZXZlbnQgPSAnQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudHM6OlBSRV9QQUNLQUdFXycuc3RydG91cHBlcigkb3BUeXBlKTsKICAgICAgICAgICAgaWYgKGRlZmluZWQoJGV2ZW50KSAmJiAkcnVuU2NyaXB0cyAmJiAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaFBhY2thZ2VFdmVudChjb25zdGFudCgkZXZlbnQpLCAkZGV2TW9kZSwgJHJlcG8sICRhbGxPcGVyYXRpb25zLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGRpc3BhdGNoZXIgPSAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyOwogICAgICAgICAgICAkaW5zdGFsbE1hbmFnZXIgPSAkdGhpczsKICAgICAgICAgICAgJGlvID0gJHRoaXMtPmlvOwoKICAgICAgICAgICAgJHByb21pc2UgPSAkaW5zdGFsbGVyLT5wcmVwYXJlKCRvcFR5cGUsICRwYWNrYWdlLCAkaW5pdGlhbFBhY2thZ2UpOwogICAgICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwcm9taXNlID0gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkb3BUeXBlLCAkaW5zdGFsbE1hbmFnZXIsICRyZXBvLCAkb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGluc3RhbGxNYW5hZ2VyLT4kb3BUeXBlKCRyZXBvLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgfSktPnRoZW4oJGNsZWFudXBQcm9taXNlc1skaW5kZXhdKQogICAgICAgICAgICAtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkaW5zdGFsbE1hbmFnZXIsICRkZXZNb2RlLCAkcmVwbykgewogICAgICAgICAgICAgICAgJHJlcG8tPndyaXRlKCRkZXZNb2RlLCAkaW5zdGFsbE1hbmFnZXIpOwogICAgICAgICAgICB9LCBmdW5jdGlvbiAoJGUpIHVzZSAoJG9wVHlwZSwgJHBhY2thZ2UsICRpbykgewogICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgPGVycm9yPicgLiB1Y2ZpcnN0KCRvcFR5cGUpIC4nIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGZhaWxlZDwvZXJyb3I+Jyk7CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgJHBvc3RFeGVjQ2FsbGJhY2tzW10gPSBmdW5jdGlvbiAoKSB1c2UgKCRvcFR5cGUsICRydW5TY3JpcHRzLCAkZGlzcGF0Y2hlciwgJGRldk1vZGUsICRyZXBvLCAkYWxsT3BlcmF0aW9ucywgJG9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJGV2ZW50ID0gJ0NvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnRzOjpQT1NUX1BBQ0tBR0VfJy5zdHJ0b3VwcGVyKCRvcFR5cGUpOwogICAgICAgICAgICAgICAgaWYgKGRlZmluZWQoJGV2ZW50KSAmJiAkcnVuU2NyaXB0cyAmJiAkZGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgICAgICRkaXNwYXRjaGVyLT5kaXNwYXRjaFBhY2thZ2VFdmVudChjb25zdGFudCgkZXZlbnQpLCAkZGV2TW9kZSwgJHJlcG8sICRhbGxPcGVyYXRpb25zLCAkb3BlcmF0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICRwcm9taXNlc1tdID0gJHByb21pc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBleGVjdXRlIGFsbCBwcmVwYXJlID0+IGluc3RhbGxzL3VwZGF0ZXMvcmVtb3ZlcyA9PiBjbGVhbnVwIHN0ZXBzCiAgICAgICAgaWYgKGNvdW50KCRwcm9taXNlcykpIHsKICAgICAgICAgICAgJHRoaXMtPndhaXRPblByb21pc2VzKCRwcm9taXNlcyk7CiAgICAgICAgfQoKICAgICAgICBQbGF0Zm9ybTo6d29ya2Fyb3VuZEZpbGVzeXN0ZW1Jc3N1ZXMoKTsKCiAgICAgICAgZm9yZWFjaCAoJHBvc3RFeGVjQ2FsbGJhY2tzIGFzICRjYikgewogICAgICAgICAgICAkY2IoKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiB3YWl0T25Qcm9taXNlcyhhcnJheSAkcHJvbWlzZXMpCiAgICB7CiAgICAgICAgJHByb2dyZXNzID0gbnVsbDsKICAgICAgICBpZiAoJHRoaXMtPm91dHB1dFByb2dyZXNzICYmICR0aGlzLT5pbyBpbnN0YW5jZW9mIENvbnNvbGVJTyAmJiAhJHRoaXMtPmlvLT5pc0RlYnVnKCkgJiYgY291bnQoJHByb21pc2VzKSA+IDEpIHsKICAgICAgICAgICAgJHByb2dyZXNzID0gJHRoaXMtPmlvLT5nZXRQcm9ncmVzc0JhcigpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+bG9vcC0+d2FpdCgkcHJvbWlzZXMsICRwcm9ncmVzcyk7CiAgICAgICAgaWYgKCRwcm9ncmVzcykgewogICAgICAgICAgICAkcHJvZ3Jlc3MtPmNsZWFyKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgaW5zdGFsbCBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gSW5zdGFsbE9wZXJhdGlvbiAgICAkb3BlcmF0aW9uIG9wZXJhdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBJbnN0YWxsT3BlcmF0aW9uICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgJHBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJHBhY2thZ2UtPmdldFR5cGUoKSk7CiAgICAgICAgJHByb21pc2UgPSAkaW5zdGFsbGVyLT5pbnN0YWxsKCRyZXBvLCAkcGFja2FnZSk7CiAgICAgICAgJHRoaXMtPm1hcmtGb3JOb3RpZmljYXRpb24oJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gJHByb21pc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB1cGRhdGUgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvICAgICAgcmVwb3NpdG9yeSBpbiB3aGljaCB0byBjaGVjawogICAgICogQHBhcmFtIFVwZGF0ZU9wZXJhdGlvbiAgICAgJG9wZXJhdGlvbiBvcGVyYXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBVcGRhdGVPcGVyYXRpb24gJG9wZXJhdGlvbikKICAgIHsKICAgICAgICAkaW5pdGlhbCA9ICRvcGVyYXRpb24tPmdldEluaXRpYWxQYWNrYWdlKCk7CiAgICAgICAgJHRhcmdldCA9ICRvcGVyYXRpb24tPmdldFRhcmdldFBhY2thZ2UoKTsKCiAgICAgICAgJGluaXRpYWxUeXBlID0gJGluaXRpYWwtPmdldFR5cGUoKTsKICAgICAgICAkdGFyZ2V0VHlwZSA9ICR0YXJnZXQtPmdldFR5cGUoKTsKCiAgICAgICAgaWYgKCRpbml0aWFsVHlwZSA9PT0gJHRhcmdldFR5cGUpIHsKICAgICAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJGluaXRpYWxUeXBlKTsKICAgICAgICAgICAgJHByb21pc2UgPSAkaW5zdGFsbGVyLT51cGRhdGUoJHJlcG8sICRpbml0aWFsLCAkdGFyZ2V0KTsKICAgICAgICAgICAgJHRoaXMtPm1hcmtGb3JOb3RpZmljYXRpb24oJHRhcmdldCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+Z2V0SW5zdGFsbGVyKCRpbml0aWFsVHlwZSktPnVuaW5zdGFsbCgkcmVwbywgJGluaXRpYWwpOwogICAgICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpbnN0YWxsZXIgPSAkdGhpcy0+Z2V0SW5zdGFsbGVyKCR0YXJnZXRUeXBlKTsKICAgICAgICAgICAgJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkaW5zdGFsbGVyLCAkcmVwbywgJHRhcmdldCkgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbnN0YWxsZXItPmluc3RhbGwoJHJlcG8sICR0YXJnZXQpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFVuaW5zdGFsbHMgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSBVbmluc3RhbGxPcGVyYXRpb24gICRvcGVyYXRpb24gb3BlcmF0aW9uIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgVW5pbnN0YWxsT3BlcmF0aW9uICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgJHBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRQYWNrYWdlKCk7CiAgICAgICAgJGluc3RhbGxlciA9ICR0aGlzLT5nZXRJbnN0YWxsZXIoJHBhY2thZ2UtPmdldFR5cGUoKSk7CgogICAgICAgIHJldHVybiAkaW5zdGFsbGVyLT51bmluc3RhbGwoJHJlcG8sICRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIG1hcmtBbGlhc0luc3RhbGxlZCBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgICAgICAgICAkcmVwbyAgICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSBNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24gJG9wZXJhdGlvbiBvcGVyYXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hcmtBbGlhc0luc3RhbGxlZChSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24gJG9wZXJhdGlvbikKICAgIHsKICAgICAgICAkcGFja2FnZSA9ICRvcGVyYXRpb24tPmdldFBhY2thZ2UoKTsKCiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgJHJlcG8tPmFkZFBhY2thZ2UoY2xvbmUgJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIG1hcmtBbGlhcyBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgICAgICAgICAgICRyZXBvICAgICAgcmVwb3NpdG9yeSBpbiB3aGljaCB0byBjaGVjawogICAgICogQHBhcmFtIE1hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9uICRvcGVyYXRpb24gb3BlcmF0aW9uIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXJrQWxpYXNVbmluc3RhbGxlZChSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBNYXJrQWxpYXNVbmluc3RhbGxlZE9wZXJhdGlvbiAkb3BlcmF0aW9uKQogICAgewogICAgICAgICRwYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0UGFja2FnZSgpOwoKICAgICAgICAkcmVwby0+cmVtb3ZlUGFja2FnZSgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnN0YWxsYXRpb24gcGF0aCBvZiBhIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRpbnN0YWxsZXIgPSAkdGhpcy0+Z2V0SW5zdGFsbGVyKCRwYWNrYWdlLT5nZXRUeXBlKCkpOwoKICAgICAgICByZXR1cm4gJGluc3RhbGxlci0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPdXRwdXRQcm9ncmVzcygkb3V0cHV0UHJvZ3Jlc3MpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dFByb2dyZXNzID0gJG91dHB1dFByb2dyZXNzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpZnlJbnN0YWxscyhJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHByb21pc2VzID0gYXJyYXkoKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5vdGlmaWFibGVQYWNrYWdlcyBhcyAkcmVwb1VybCA9PiAkcGFja2FnZXMpIHsKICAgICAgICAgICAgICAgIC8vIG5vbi1iYXRjaCBBUEksIGRlcHJlY2F0ZWQKICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJHJlcG9VcmwsICclcGFja2FnZSUnKSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdXJsID0gc3RyX3JlcGxhY2UoJyVwYWNrYWdlJScsICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksICRyZXBvVXJsKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ZlcnNpb25fbm9ybWFsaXplZCcgPT4gJHBhY2thZ2UtPmdldFZlcnNpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG9wdHMgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZXRyeS1hdXRoLWZhaWx1cmUnID0+IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2h0dHAnID0+IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtZXRob2QnID0+ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaGVhZGVyJyA9PiBhcnJheSgnQ29udGVudC10eXBlOiBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29udGVudCcgPT4gaHR0cF9idWlsZF9xdWVyeSgkcGFyYW1zLCAnJywgJyYnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGltZW91dCcgPT4gMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICAkcHJvbWlzZXNbXSA9ICR0aGlzLT5sb29wLT5nZXRIdHRwRG93bmxvYWRlcigpLT5hZGQoJHVybCwgJG9wdHMpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHBvc3REYXRhID0gYXJyYXkoJ2Rvd25sb2FkcycgPT4gYXJyYXkoKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkcG9zdERhdGFbJ2Rvd25sb2FkcyddW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uJyA9PiAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG9wdHMgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAncmV0cnktYXV0aC1mYWlsdXJlJyA9PiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAnaHR0cCcgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICdtZXRob2QnID0+ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICAgICAgJ2hlYWRlcicgPT4gYXJyYXkoJ0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbicpLAogICAgICAgICAgICAgICAgICAgICAgICAnY29udGVudCcgPT4ganNvbl9lbmNvZGUoJHBvc3REYXRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3RpbWVvdXQnID0+IDYsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgJHByb21pc2VzW10gPSAkdGhpcy0+bG9vcC0+Z2V0SHR0cERvd25sb2FkZXIoKS0+YWRkKCRyZXBvVXJsLCAkb3B0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5sb29wLT53YWl0KCRwcm9taXNlcyk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJlc2V0KCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXJrRm9yTm90aWZpY2F0aW9uKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROb3RpZmljYXRpb25VcmwoKSkgewogICAgICAgICAgICAkdGhpcy0+bm90aWZpYWJsZVBhY2thZ2VzWyRwYWNrYWdlLT5nZXROb3RpZmljYXRpb25VcmwoKV1bJHBhY2thZ2UtPmdldE5hbWUoKV0gPSAkcGFja2FnZTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxJbnN0YWxsZXJcSW5zdGFsbGF0aW9uTWFuYWdlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogSW5zdGFsbGVyIGZvciBwbHVnaW4gcGFja2FnZXMKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUGx1Z2luSW5zdGFsbGVyIGV4dGVuZHMgTGlicmFyeUluc3RhbGxlcgp7CiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIFBsdWdpbiBpbnN0YWxsZXIuCiAgICAgKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb21wb3NlciAkY29tcG9zZXIsIEZpbGVzeXN0ZW0gJGZzID0gbnVsbCwgQmluYXJ5SW5zdGFsbGVyICRiaW5hcnlJbnN0YWxsZXIgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGlvLCAkY29tcG9zZXIsICdjb21wb3Nlci1wbHVnaW4nLCAkZnMsICRiaW5hcnlJbnN0YWxsZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJHBhY2thZ2VUeXBlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZVR5cGUgPT09ICdjb21wb3Nlci1wbHVnaW4nIHx8ICRwYWNrYWdlVHlwZSA9PT0gJ2NvbXBvc2VyLWluc3RhbGxlcic7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGV4dHJhID0gJHBhY2thZ2UtPmdldEV4dHJhKCk7CiAgICAgICAgaWYgKGVtcHR5KCRleHRyYVsnY2xhc3MnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0Vycm9yIHdoaWxlIGluc3RhbGxpbmcgJy4kcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicsIGNvbXBvc2VyLXBsdWdpbiBwYWNrYWdlcyBzaG91bGQgaGF2ZSBhIGNsYXNzIGRlZmluZWQgaW4gdGhlaXIgZXh0cmEga2V5IHRvIGJlIHVzYWJsZS4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmRvd25sb2FkKCRwYWNrYWdlLCAkcHJldlBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRwcm9taXNlID0gcGFyZW50OjppbnN0YWxsKCRyZXBvLCAkcGFja2FnZSk7CiAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAkcGx1Z2luTWFuYWdlciA9ICR0aGlzLT5jb21wb3Nlci0+Z2V0UGx1Z2luTWFuYWdlcigpOwogICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRzZWxmLCAkcGx1Z2luTWFuYWdlciwgJHBhY2thZ2UsICRyZXBvKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBQbGF0Zm9ybTo6d29ya2Fyb3VuZEZpbGVzeXN0ZW1Jc3N1ZXMoKTsKICAgICAgICAgICAgICAgICRwbHVnaW5NYW5hZ2VyLT5yZWdpc3RlclBhY2thZ2UoJHBhY2thZ2UsIHRydWUpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAkc2VsZi0+cm9sbGJhY2tJbnN0YWxsKCRlLCAkcmVwbywgJHBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgICRwcm9taXNlID0gcGFyZW50Ojp1cGRhdGUoJHJlcG8sICRpbml0aWFsLCAkdGFyZ2V0KTsKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRwbHVnaW5NYW5hZ2VyID0gJHRoaXMtPmNvbXBvc2VyLT5nZXRQbHVnaW5NYW5hZ2VyKCk7CiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHNlbGYsICRwbHVnaW5NYW5hZ2VyLCAkaW5pdGlhbCwgJHRhcmdldCwgJHJlcG8pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIFBsYXRmb3JtOjp3b3JrYXJvdW5kRmlsZXN5c3RlbUlzc3VlcygpOwogICAgICAgICAgICAgICAgJHBsdWdpbk1hbmFnZXItPmRlYWN0aXZhdGVQYWNrYWdlKCRpbml0aWFsLCB0cnVlKTsKICAgICAgICAgICAgICAgICRwbHVnaW5NYW5hZ2VyLT5yZWdpc3RlclBhY2thZ2UoJHRhcmdldCwgdHJ1ZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICRzZWxmLT5yb2xsYmFja0luc3RhbGwoJGUsICRyZXBvLCAkdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcG9zZXItPmdldFBsdWdpbk1hbmFnZXIoKS0+dW5pbnN0YWxsUGFja2FnZSgkcGFja2FnZSwgdHJ1ZSk7CgogICAgICAgIHJldHVybiBwYXJlbnQ6OnVuaW5zdGFsbCgkcmVwbywgJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogVE9ETyB2MyBzaG91bGQgbWFrZSB0aGlzIHByaXZhdGUgb25jZSB3ZSBjYW4gZHJvcCBQSFAgNS4zIHN1cHBvcnQKICAgICAqIEBwcml2YXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByb2xsYmFja0luc3RhbGwoXEV4Y2VwdGlvbiAkZSwgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1BsdWdpbiBpbml0aWFsaXphdGlvbiBmYWlsZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKSwgdW5pbnN0YWxsaW5nIHBsdWdpbicpOwogICAgICAgIHBhcmVudDo6dW5pbnN0YWxsKCRyZXBvLCAkcGFja2FnZSk7CiAgICAgICAgdGhyb3cgJGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXE9wZXJhdGlvbkludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKCi8qKgogKiBUaGUgUGFja2FnZSBFdmVudC4KICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgUGFja2FnZUV2ZW50IGV4dGVuZHMgRXZlbnQKewogICAgLyoqCiAgICAgKiBAdmFyIENvbXBvc2VyCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbXBvc2VyOwoKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRpbzsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRkZXZNb2RlOwoKICAgIC8qKgogICAgICogQHZhciBSZXBvc2l0b3J5SW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGxvY2FsUmVwbzsKCiAgICAvKioKICAgICAqIEB2YXIgT3BlcmF0aW9uSW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkb3BlcmF0aW9uczsKCiAgICAvKioKICAgICAqIEB2YXIgT3BlcmF0aW9uSW50ZXJmYWNlIFRoZSBvcGVyYXRpb24gaW5zdGFuY2Ugd2hpY2ggaXMgYmVpbmcgZXhlY3V0ZWQKICAgICAqLwogICAgcHJpdmF0ZSAkb3BlcmF0aW9uOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICRldmVudE5hbWUKICAgICAqIEBwYXJhbSBDb21wb3NlciAgICAgICAgICAgICAkY29tcG9zZXIKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgICAgICAkaW8KICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAkZGV2TW9kZQogICAgICogQHBhcmFtIFJlcG9zaXRvcnlJbnRlcmZhY2UgICRsb2NhbFJlcG8KICAgICAqIEBwYXJhbSBPcGVyYXRpb25JbnRlcmZhY2VbXSAkb3BlcmF0aW9ucwogICAgICogQHBhcmFtIE9wZXJhdGlvbkludGVyZmFjZSAgICRvcGVyYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRldmVudE5hbWUsIENvbXBvc2VyICRjb21wb3NlciwgSU9JbnRlcmZhY2UgJGlvLCAkZGV2TW9kZSwgUmVwb3NpdG9yeUludGVyZmFjZSAkbG9jYWxSZXBvLCBhcnJheSAkb3BlcmF0aW9ucywgT3BlcmF0aW9uSW50ZXJmYWNlICRvcGVyYXRpb24pCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkZXZlbnROYW1lKTsKCiAgICAgICAgJHRoaXMtPmNvbXBvc2VyID0gJGNvbXBvc2VyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+ZGV2TW9kZSA9ICRkZXZNb2RlOwogICAgICAgICR0aGlzLT5sb2NhbFJlcG8gPSAkbG9jYWxSZXBvOwogICAgICAgICR0aGlzLT5vcGVyYXRpb25zID0gJG9wZXJhdGlvbnM7CiAgICAgICAgJHRoaXMtPm9wZXJhdGlvbiA9ICRvcGVyYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbXBvc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wb3NlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wb3NlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElPKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlvOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Rldk1vZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV2TW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUmVwb3NpdG9yeUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWxSZXBvKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvY2FsUmVwbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gT3BlcmF0aW9uSW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBPcGVyYXRpb25JbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERvd25sb2FkZXJcRG93bmxvYWRNYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwoKLyoqCiAqIFByb2plY3QgSW5zdGFsbGVyIGlzIHVzZWQgdG8gaW5zdGFsbCBhIHNpbmdsZSBwYWNrYWdlIGludG8gYSBkaXJlY3RvcnkgYXMKICogcm9vdCBwcm9qZWN0LgogKgogKiBAYXV0aG9yIEJlbmphbWluIEViZXJsZWkgPGtvbnRha3RAYmViZXJsZWkuZGU+CiAqLwpjbGFzcyBQcm9qZWN0SW5zdGFsbGVyIGltcGxlbWVudHMgSW5zdGFsbGVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGluc3RhbGxQYXRoOwogICAgcHJpdmF0ZSAkZG93bmxvYWRNYW5hZ2VyOwogICAgcHJpdmF0ZSAkZmlsZXN5c3RlbTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGluc3RhbGxQYXRoLCBEb3dubG9hZE1hbmFnZXIgJGRtLCBGaWxlc3lzdGVtICRmcykKICAgIHsKICAgICAgICAkdGhpcy0+aW5zdGFsbFBhdGggPSBydHJpbShzdHJ0cigkaW5zdGFsbFBhdGgsICdcXCcsICcvJyksICcvJykuJy8nOwogICAgICAgICR0aGlzLT5kb3dubG9hZE1hbmFnZXIgPSAkZG07CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWNpZGVzIGlmIHRoZSBpbnN0YWxsZXIgc3VwcG9ydHMgdGhlIGdpdmVuIHR5cGUKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGFja2FnZVR5cGUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJHBhY2thZ2VUeXBlKQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbnN0YWxsZWQoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGluc3RhbGxQYXRoID0gJHRoaXMtPmluc3RhbGxQYXRoOwogICAgICAgIGlmIChmaWxlX2V4aXN0cygkaW5zdGFsbFBhdGgpICYmICEkdGhpcy0+ZmlsZXN5c3RlbS0+aXNEaXJFbXB0eSgkaW5zdGFsbFBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJQcm9qZWN0IGRpcmVjdG9yeSAkaW5zdGFsbFBhdGggaXMgbm90IGVtcHR5LiIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWlzX2RpcigkaW5zdGFsbFBhdGgpKSB7CiAgICAgICAgICAgIG1rZGlyKCRpbnN0YWxsUGF0aCwgMDc3NywgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+ZG93bmxvYWQoJHBhY2thZ2UsICRpbnN0YWxsUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICR0aGlzLT5pbnN0YWxsUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+Y2xlYW51cCgkdHlwZSwgJHBhY2thZ2UsICR0aGlzLT5pbnN0YWxsUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+aW5zdGFsbCgkcGFja2FnZSwgJHRoaXMtPmluc3RhbGxQYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIm5vdCBzdXBwb3J0ZWQiKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgc3VwcG9ydGVkIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnN0YWxsYXRpb24gcGF0aCBvZiBhIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5zdGFsbFBhdGg7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKCi8qKgogKiBVdGlsaXR5IHRvIGhhbmRsZSBpbnN0YWxsYXRpb24gb2YgcGFja2FnZSAiYmluIi9iaW5hcmllcwogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqIEBhdXRob3IgSGVsbXV0IEh1bW1lbCA8aW5mb0BoZWxodW0uaW8+CiAqLwpjbGFzcyBCaW5hcnlJbnN0YWxsZXIKewogICAgcHJvdGVjdGVkICRiaW5EaXI7CiAgICBwcm90ZWN0ZWQgJGJpbkNvbXBhdDsKICAgIHByb3RlY3RlZCAkaW87CiAgICBwcm90ZWN0ZWQgJGZpbGVzeXN0ZW07CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgJGlvCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGJpbkRpcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRiaW5Db21wYXQKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAkZmlsZXN5c3RlbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCAkYmluRGlyLCAkYmluQ29tcGF0LCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YmluRGlyID0gJGJpbkRpcjsKICAgICAgICAkdGhpcy0+YmluQ29tcGF0ID0gJGJpbkNvbXBhdDsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsQmluYXJpZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGluc3RhbGxQYXRoLCAkd2Fybk9uT3ZlcndyaXRlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkYmluYXJpZXMgPSAkdGhpcy0+Z2V0QmluYXJpZXMoJHBhY2thZ2UpOwogICAgICAgIGlmICghJGJpbmFyaWVzKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJGJpbmFyaWVzIGFzICRiaW4pIHsKICAgICAgICAgICAgJGJpblBhdGggPSAkaW5zdGFsbFBhdGguJy8nLiRiaW47CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJGJpblBhdGgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz5Ta2lwcGVkIGluc3RhbGxhdGlvbiBvZiBiaW4gJy4kYmluLicgZm9yIHBhY2thZ2UgJy4kcGFja2FnZS0+Z2V0TmFtZSgpLic6IGZpbGUgbm90IGZvdW5kIGluIHBhY2thZ2U8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaW4gY2FzZSBhIGN1c3RvbSBpbnN0YWxsZXIgcmV0dXJuZWQgYSByZWxhdGl2ZSBwYXRoIGZvciB0aGUKICAgICAgICAgICAgLy8gJHBhY2thZ2UsIHdlIGNhbiBub3cgc2FmZWx5IHR1cm4gaXQgaW50byBhIGFic29sdXRlIHBhdGggKGFzIHdlCiAgICAgICAgICAgIC8vIGFscmVhZHkgY2hlY2tlZCB0aGUgYmluYXJ5J3MgZXhpc3RlbmNlKS4gVGhlIGZvbGxvd2luZyBoZWxwZXJzCiAgICAgICAgICAgIC8vIHdpbGwgcmVxdWlyZSBhYnNvbHV0ZSBwYXRocyB0byB3b3JrIHByb3Blcmx5LgogICAgICAgICAgICAkYmluUGF0aCA9IHJlYWxwYXRoKCRiaW5QYXRoKTsKCiAgICAgICAgICAgICR0aGlzLT5pbml0aWFsaXplQmluRGlyKCk7CiAgICAgICAgICAgICRsaW5rID0gJHRoaXMtPmJpbkRpci4nLycuYmFzZW5hbWUoJGJpbik7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkbGluaykpIHsKICAgICAgICAgICAgICAgIGlmIChpc19saW5rKCRsaW5rKSkgewogICAgICAgICAgICAgICAgICAgIC8vIGxpa2VseSBsZWZ0b3ZlciBmcm9tIGEgcHJldmlvdXMgaW5zdGFsbCwgbWFrZSBzdXJlCiAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCB0aGUgdGFyZ2V0IGlzIHN0aWxsIGV4ZWN1dGFibGUgaW4gY2FzZSB0aGlzCiAgICAgICAgICAgICAgICAgICAgLy8gaXMgYSBmcmVzaCBpbnN0YWxsIG9mIHRoZSB2ZW5kb3IuCiAgICAgICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NobW9kJywgJGxpbmssIDA3NzcgJiB+dW1hc2soKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHdhcm5Pbk92ZXJ3cml0ZSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIFNraXBwZWQgaW5zdGFsbGF0aW9uIG9mIGJpbiAnLiRiaW4uJyBmb3IgcGFja2FnZSAnLiRwYWNrYWdlLT5nZXROYW1lKCkuJzogbmFtZSBjb25mbGljdHMgd2l0aCBhbiBleGlzdGluZyBmaWxlJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5iaW5Db21wYXQgPT09ICJhdXRvIikgewogICAgICAgICAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbnN0YWxsRnVsbEJpbmFyaWVzKCRiaW5QYXRoLCAkbGluaywgJGJpbiwgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5zdGFsbFN5bWxpbmtCaW5hcmllcygkYmluUGF0aCwgJGxpbmspOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmJpbkNvbXBhdCA9PT0gImZ1bGwiKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5zdGFsbEZ1bGxCaW5hcmllcygkYmluUGF0aCwgJGxpbmssICRiaW4sICRwYWNrYWdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnY2htb2QnLCAkbGluaywgMDc3NyAmIH51bWFzaygpKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUJpbmFyaWVzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVCaW5EaXIoKTsKCiAgICAgICAgJGJpbmFyaWVzID0gJHRoaXMtPmdldEJpbmFyaWVzKCRwYWNrYWdlKTsKICAgICAgICBpZiAoISRiaW5hcmllcykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRiaW5hcmllcyBhcyAkYmluKSB7CiAgICAgICAgICAgICRsaW5rID0gJHRoaXMtPmJpbkRpci4nLycuYmFzZW5hbWUoJGJpbik7CiAgICAgICAgICAgIGlmIChpc19saW5rKCRsaW5rKSB8fCBmaWxlX2V4aXN0cygkbGluaykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT51bmxpbmsoJGxpbmspOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkbGluay4nLmJhdCcpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRsaW5rLicuYmF0Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGF0dGVtcHQgcmVtb3ZpbmcgdGhlIGJpbiBkaXIgaW4gY2FzZSBpdCBpcyBsZWZ0IGVtcHR5CiAgICAgICAgaWYgKGlzX2RpcigkdGhpcy0+YmluRGlyKSAmJiAkdGhpcy0+ZmlsZXN5c3RlbS0+aXNEaXJFbXB0eSgkdGhpcy0+YmluRGlyKSkgewogICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgncm1kaXInLCAkdGhpcy0+YmluRGlyKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBkZXRlcm1pbmVCaW5hcnlDYWxsZXIoJGJpbikKICAgIHsKICAgICAgICBpZiAoJy5iYXQnID09PSBzdWJzdHIoJGJpbiwgLTQpIHx8ICcuZXhlJyA9PT0gc3Vic3RyKCRiaW4sIC00KSkgewogICAgICAgICAgICByZXR1cm4gJ2NhbGwnOwogICAgICAgIH0KCiAgICAgICAgJGhhbmRsZSA9IGZvcGVuKCRiaW4sICdyJyk7CiAgICAgICAgJGxpbmUgPSBmZ2V0cygkaGFuZGxlKTsKICAgICAgICBmY2xvc2UoJGhhbmRsZSk7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teIyEvKD86dXNyL2Jpbi9lbnYgKT8oPzpbXi9dKy8pKiguKykkfW0nLCAkbGluZSwgJG1hdGNoKSkgewogICAgICAgICAgICByZXR1cm4gdHJpbSgkbWF0Y2hbMV0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdwaHAnOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRCaW5hcmllcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0QmluYXJpZXMoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbEZ1bGxCaW5hcmllcygkYmluUGF0aCwgJGxpbmssICRiaW4sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgLy8gYWRkIHVuaXh5IHN1cHBvcnQgZm9yIGN5Z3dpbiBhbmQgc2ltaWxhciBlbnZpcm9ubWVudHMKICAgICAgICBpZiAoJy5iYXQnICE9PSBzdWJzdHIoJGJpblBhdGgsIC00KSkgewogICAgICAgICAgICAkdGhpcy0+aW5zdGFsbFVuaXh5UHJveHlCaW5hcmllcygkYmluUGF0aCwgJGxpbmspOwogICAgICAgICAgICBAY2htb2QoJGxpbmssIDA3NzcgJiB+dW1hc2soKSk7CiAgICAgICAgICAgICRsaW5rIC49ICcuYmF0JzsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRsaW5rKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgU2tpcHBlZCBpbnN0YWxsYXRpb24gb2YgYmluICcuJGJpbi4nLmJhdCBwcm94eSBmb3IgcGFja2FnZSAnLiRwYWNrYWdlLT5nZXROYW1lKCkuJzogYSAuYmF0IHByb3h5IHdhcyBhbHJlYWR5IGluc3RhbGxlZCcpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghZmlsZV9leGlzdHMoJGxpbmspKSB7CiAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRsaW5rLCAkdGhpcy0+Z2VuZXJhdGVXaW5kb3dzUHJveHlDb2RlKCRiaW5QYXRoLCAkbGluaykpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbFN5bWxpbmtCaW5hcmllcygkYmluUGF0aCwgJGxpbmspCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZmlsZXN5c3RlbS0+cmVsYXRpdmVTeW1saW5rKCRiaW5QYXRoLCAkbGluaykpIHsKICAgICAgICAgICAgJHRoaXMtPmluc3RhbGxVbml4eVByb3h5QmluYXJpZXMoJGJpblBhdGgsICRsaW5rKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluc3RhbGxVbml4eVByb3h5QmluYXJpZXMoJGJpblBhdGgsICRsaW5rKQogICAgewogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCRsaW5rLCAkdGhpcy0+Z2VuZXJhdGVVbml4eVByb3h5Q29kZSgkYmluUGF0aCwgJGxpbmspKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdGlhbGl6ZUJpbkRpcigpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGhpcy0+YmluRGlyKTsKICAgICAgICAkdGhpcy0+YmluRGlyID0gcmVhbHBhdGgoJHRoaXMtPmJpbkRpcik7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdlbmVyYXRlV2luZG93c1Byb3h5Q29kZSgkYmluLCAkbGluaykKICAgIHsKICAgICAgICAkYmluUGF0aCA9ICR0aGlzLT5maWxlc3lzdGVtLT5maW5kU2hvcnRlc3RQYXRoKCRsaW5rLCAkYmluKTsKICAgICAgICAkY2FsbGVyID0gc2VsZjo6ZGV0ZXJtaW5lQmluYXJ5Q2FsbGVyKCRiaW4pOwoKICAgICAgICByZXR1cm4gIkBFQ0hPIE9GRlxyXG4iLgogICAgICAgICAgICAic2V0bG9jYWwgRElTQUJMRURFTEFZRURFWFBBTlNJT05cclxuIi4KICAgICAgICAgICAgIlNFVCBCSU5fVEFSR0VUPSV+ZHAwLyIudHJpbShQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkYmluUGF0aCksICciXCcnKS4iXHJcbiIuCiAgICAgICAgICAgICJ7JGNhbGxlcn0gXCIlQklOX1RBUkdFVCVcIiAlKlxyXG4iOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZW5lcmF0ZVVuaXh5UHJveHlDb2RlKCRiaW4sICRsaW5rKQogICAgewogICAgICAgICRiaW5QYXRoID0gJHRoaXMtPmZpbGVzeXN0ZW0tPmZpbmRTaG9ydGVzdFBhdGgoJGxpbmssICRiaW4pOwoKICAgICAgICAkYmluRGlyID0gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoZGlybmFtZSgkYmluUGF0aCkpOwogICAgICAgICRiaW5GaWxlID0gYmFzZW5hbWUoJGJpblBhdGgpOwoKICAgICAgICAkYmluQ29udGVudHMgPSBmaWxlX2dldF9jb250ZW50cygkYmluKTsKICAgICAgICAvLyBGb3IgcGhwIGZpbGVzLCB3ZSBnZW5lcmF0ZSBhIFBIUCBwcm94eSBpbnN0ZWFkIG9mIGEgc2hlbGwgb25lLAogICAgICAgIC8vIHdoaWNoIGFsbG93cyBjYWxsaW5nIHRoZSBwcm94eSB3aXRoIGEgY3VzdG9tIHBocCBwcm9jZXNzCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86IyEoPzovdXNyKT8vYmluL2VudiBwaHB8IyEoPzovdXNyKT8vYmluL3BocHw8P3BocClccj9cbn0nLCAkYmluQ29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgLy8gdmVyaWZ5IHRoZSBmaWxlIGlzIG5vdCBhIHBoYXIgZmlsZSwgYmVjYXVzZSB0aG9zZSBkbyBub3Qgc3VwcG9ydCBwaHAtcHJveHlpbmcKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAoJHBvcyA9IHN0cnBvcygkYmluQ29udGVudHMsICdfX0hBTFRfQ09NUElMRVInKSkgfHwgZmFsc2UgPT09IHN0cnBvcyhzdWJzdHIoJGJpbkNvbnRlbnRzLCAwLCAkcG9zKSwgJ1BoYXI6Om1hcFBoYXInKSkgewogICAgICAgICAgICAgICAgJHByb3h5Q29kZSA9IHRyaW0oJG1hdGNoWzBdKTsKICAgICAgICAgICAgICAgIC8vIGNhcnJ5IG92ZXIgdGhlIGV4aXN0aW5nIHNoZWJhbmcgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIGFkZCBvdXIgb3duCiAgICAgICAgICAgICAgICBpZiAoJHByb3h5Q29kZSA9PT0gIjw/cGhwIikgewogICAgICAgICAgICAgICAgICAgICRwcm94eUNvZGUgPSAiIyEvdXNyL2Jpbi9lbnYgcGhwIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRiaW5QYXRoRXhwb3J0ZWQgPSB2YXJfZXhwb3J0KCRiaW5QYXRoLCB0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkcHJveHlDb2RlIC4gIlxuIiAuIDw8PFBST1hZCjw/cGhwCgovKioKICogUHJveHkgUEhQIGZpbGUgZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCiAqCiAqIFRoaXMgZmlsZSBpbmNsdWRlcyB0aGUgcmVmZXJlbmNlZCBiaW4gcGF0aCAoJGJpblBhdGgpIHVzaW5nIGV2YWwgdG8gcmVtb3ZlIHRoZSBzaGViYW5nIGlmIHByZXNlbnQKICoKICogQGdlbmVyYXRlZAogKi8KClwkYmluUGF0aCA9IHJlYWxwYXRoKF9fRElSX18gLiAiLyIgLiAkYmluUGF0aEV4cG9ydGVkKTsKXCRjb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKFwkYmluUGF0aCk7ClwkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoJ3teIyEvLitcXHI/XFxuPFxcPyhwaHApP30nLCAnJywgXCRjb250ZW50cywgMSwgXCRyZXBsYWNlZCk7CmlmIChcJHJlcGxhY2VkKSB7CiAgICBcJGNvbnRlbnRzID0gc3RydHIoXCRjb250ZW50cywgYXJyYXkoCiAgICAgICAgJ19fRklMRV9fJyA9PiB2YXJfZXhwb3J0KFwkYmluUGF0aCwgdHJ1ZSksCiAgICAgICAgJ19fRElSX18nID0+IHZhcl9leHBvcnQoZGlybmFtZShcJGJpblBhdGgpLCB0cnVlKSwKICAgICkpOwoKICAgIGV2YWwoXCRjb250ZW50cyk7CiAgICBleGl0KDApOwp9CmluY2x1ZGUgXCRiaW5QYXRoOwoKUFJPWFk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwcm94eUNvZGUgPSA8PDxQUk9YWQojIS91c3IvYmluL2VudiBzaAoKZGlyPVwkKGNkICJcJHswJVsvXFxcXF0qfSIgPiAvZGV2L251bGw7IGNkICRiaW5EaXIgJiYgcHdkKQoKaWYgWyAtZCAvcHJvYy9jeWdkcml2ZSBdOyB0aGVuCiAgICBjYXNlIFwkKHdoaWNoIHBocCkgaW4KICAgICAgICBcJChyZWFkbGluayAtbiAvcHJvYy9jeWdkcml2ZSkvKikKICAgICAgICAgICAgIyBXZSBhcmUgaW4gQ3lnd2luIHVzaW5nIFdpbmRvd3MgcGhwLCBzbyB0aGUgcGF0aCBtdXN0IGJlIHRyYW5zbGF0ZWQKICAgICAgICAgICAgZGlyPVwkKGN5Z3BhdGggLW0gIlwkZGlyIik7CiAgICAgICAgICAgIDs7CiAgICBlc2FjCmZpCgoiXCR7ZGlyfS8kYmluRmlsZSIgIlwkQCIKClBST1hZOwoKICAgICAgICByZXR1cm4gJHByb3h5Q29kZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7CgovKioKICogUGFja2FnZSBFdmVudHMuCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBhY2thZ2VFdmVudHMKewogICAgLyoqCiAgICAgKiBUaGUgUFJFX1BBQ0tBR0VfSU5TVEFMTCBldmVudCBvY2N1cnMgYmVmb3JlIGEgcGFja2FnZSBpcyBpbnN0YWxsZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX1BBQ0tBR0VfSU5TVEFMTCA9ICdwcmUtcGFja2FnZS1pbnN0YWxsJzsKCiAgICAvKioKICAgICAqIFRoZSBQT1NUX1BBQ0tBR0VfSU5TVEFMTCBldmVudCBvY2N1cnMgYWZ0ZXIgYSBwYWNrYWdlIGlzIGluc3RhbGxlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGEgQ29tcG9zZXJcSW5zdGFsbGVyXFBhY2thZ2VFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQT1NUX1BBQ0tBR0VfSU5TVEFMTCA9ICdwb3N0LXBhY2thZ2UtaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBUaGUgUFJFX1BBQ0tBR0VfVVBEQVRFIGV2ZW50IG9jY3VycyBiZWZvcmUgYSBwYWNrYWdlIGlzIHVwZGF0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX1BBQ0tBR0VfVVBEQVRFID0gJ3ByZS1wYWNrYWdlLXVwZGF0ZSc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9QQUNLQUdFX1VQREFURSBldmVudCBvY2N1cnMgYWZ0ZXIgYSBwYWNrYWdlIGlzIHVwZGF0ZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUE9TVF9QQUNLQUdFX1VQREFURSA9ICdwb3N0LXBhY2thZ2UtdXBkYXRlJzsKCiAgICAvKioKICAgICAqIFRoZSBQUkVfUEFDS0FHRV9VTklOU1RBTEwgZXZlbnQgb2NjdXJzIGJlZm9yZSBhIHBhY2thZ2UgaGFzIGJlZW4gdW5pbnN0YWxsZWQuCiAgICAgKgogICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIG1ldGhvZCByZWNlaXZlcyBhIENvbXBvc2VyXEluc3RhbGxlclxQYWNrYWdlRXZlbnQgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgY29uc3QgUFJFX1BBQ0tBR0VfVU5JTlNUQUxMID0gJ3ByZS1wYWNrYWdlLXVuaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBUaGUgUE9TVF9QQUNLQUdFX1VOSU5TVEFMTCBldmVudCBvY2N1cnMgYWZ0ZXIgYSBwYWNrYWdlIGhhcyBiZWVuIHVuaW5zdGFsbGVkLgogICAgICoKICAgICAqIFRoZSBldmVudCBsaXN0ZW5lciBtZXRob2QgcmVjZWl2ZXMgYSBDb21wb3NlclxJbnN0YWxsZXJcUGFja2FnZUV2ZW50IGluc3RhbmNlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFBPU1RfUEFDS0FHRV9VTklOU1RBTEwgPSAncG9zdC1wYWNrYWdlLXVuaW5zdGFsbCc7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxQbGF0Zm9ybTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBQYWNrYWdlIGluc3RhbGxhdGlvbiBtYW5hZ2VyLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBMaWJyYXJ5SW5zdGFsbGVyIGltcGxlbWVudHMgSW5zdGFsbGVySW50ZXJmYWNlLCBCaW5hcnlQcmVzZW5jZUludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGNvbXBvc2VyOwogICAgcHJvdGVjdGVkICR2ZW5kb3JEaXI7CiAgICBwcm90ZWN0ZWQgJGJpbkRpcjsKICAgIHByb3RlY3RlZCAkZG93bmxvYWRNYW5hZ2VyOwogICAgcHJvdGVjdGVkICRpbzsKICAgIHByb3RlY3RlZCAkdHlwZTsKICAgIHByb3RlY3RlZCAkZmlsZXN5c3RlbTsKICAgIHByb3RlY3RlZCAkYmluQ29tcGF0OwogICAgcHJvdGVjdGVkICRiaW5hcnlJbnN0YWxsZXI7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBsaWJyYXJ5IGluc3RhbGxlci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbwogICAgICogQHBhcmFtIENvbXBvc2VyICAgICAgICAkY29tcG9zZXIKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgJHR5cGUKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAgICAgJGZpbGVzeXN0ZW0KICAgICAqIEBwYXJhbSBCaW5hcnlJbnN0YWxsZXIgJGJpbmFyeUluc3RhbGxlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb21wb3NlciAkY29tcG9zZXIsICR0eXBlID0gJ2xpYnJhcnknLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCwgQmluYXJ5SW5zdGFsbGVyICRiaW5hcnlJbnN0YWxsZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyID0gJGNvbXBvc2VyLT5nZXREb3dubG9hZE1hbmFnZXIoKTsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPnR5cGUgPSAkdHlwZTsKCiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICR0aGlzLT52ZW5kb3JEaXIgPSBydHJpbSgkY29tcG9zZXItPmdldENvbmZpZygpLT5nZXQoJ3ZlbmRvci1kaXInKSwgJy8nKTsKICAgICAgICAkdGhpcy0+YmluYXJ5SW5zdGFsbGVyID0gJGJpbmFyeUluc3RhbGxlciA/OiBuZXcgQmluYXJ5SW5zdGFsbGVyKCR0aGlzLT5pbywgcnRyaW0oJGNvbXBvc2VyLT5nZXRDb25maWcoKS0+Z2V0KCdiaW4tZGlyJyksICcvJyksICRjb21wb3Nlci0+Z2V0Q29uZmlnKCktPmdldCgnYmluLWNvbXBhdCcpLCAkdGhpcy0+ZmlsZXN5c3RlbSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdXBwb3J0cygkcGFja2FnZVR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuICRwYWNrYWdlVHlwZSA9PT0gJHRoaXMtPnR5cGUgfHwgbnVsbCA9PT0gJHRoaXMtPnR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0luc3RhbGxlZChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgIGlmIChpc19yZWFkYWJsZSgkaW5zdGFsbFBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgJHRoaXMtPmZpbGVzeXN0ZW0tPmlzSnVuY3Rpb24oJGluc3RhbGxQYXRoKSkgfHwgaXNfbGluaygkaW5zdGFsbFBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplVmVuZG9yRGlyKCk7CiAgICAgICAgJGRvd25sb2FkUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5kb3dubG9hZCgkcGFja2FnZSwgJGRvd25sb2FkUGF0aCwgJHByZXZQYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZVZlbmRvckRpcigpOwogICAgICAgICRkb3dubG9hZFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICRkb3dubG9hZFBhdGgsICRwcmV2UGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemVWZW5kb3JEaXIoKTsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRwYWNrYWdlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPmNsZWFudXAoJHR5cGUsICRwYWNrYWdlLCAkZG93bmxvYWRQYXRoLCAkcHJldlBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplVmVuZG9yRGlyKCk7CiAgICAgICAgJGRvd25sb2FkUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgYmluYXJpZXMgaWYgaXQgYXBwZWFycyB0aGUgcGFja2FnZSBmaWxlcyBhcmUgbWlzc2luZwogICAgICAgIGlmICghaXNfcmVhZGFibGUoJGRvd25sb2FkUGF0aCkgJiYgJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICR0aGlzLT5iaW5hcnlJbnN0YWxsZXItPnJlbW92ZUJpbmFyaWVzKCRwYWNrYWdlKTsKICAgICAgICB9CgogICAgICAgICRwcm9taXNlID0gJHRoaXMtPmluc3RhbGxDb2RlKCRwYWNrYWdlKTsKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRiaW5hcnlJbnN0YWxsZXIgPSAkdGhpcy0+YmluYXJ5SW5zdGFsbGVyOwogICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRiaW5hcnlJbnN0YWxsZXIsICRpbnN0YWxsUGF0aCwgJHBhY2thZ2UsICRyZXBvKSB7CiAgICAgICAgICAgICRiaW5hcnlJbnN0YWxsZXItPmluc3RhbGxCaW5hcmllcygkcGFja2FnZSwgJGluc3RhbGxQYXRoKTsKICAgICAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICRyZXBvLT5hZGRQYWNrYWdlKGNsb25lICRwYWNrYWdlKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCkKICAgIHsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCRpbml0aWFsKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSBpcyBub3QgaW5zdGFsbGVkOiAnLiRpbml0aWFsKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pbml0aWFsaXplVmVuZG9yRGlyKCk7CgogICAgICAgICR0aGlzLT5iaW5hcnlJbnN0YWxsZXItPnJlbW92ZUJpbmFyaWVzKCRpbml0aWFsKTsKICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT51cGRhdGVDb2RlKCRpbml0aWFsLCAkdGFyZ2V0KTsKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgICRiaW5hcnlJbnN0YWxsZXIgPSAkdGhpcy0+YmluYXJ5SW5zdGFsbGVyOwogICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkdGFyZ2V0KTsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJGJpbmFyeUluc3RhbGxlciwgJGluc3RhbGxQYXRoLCAkdGFyZ2V0LCAkaW5pdGlhbCwgJHJlcG8pIHsKICAgICAgICAgICAgJGJpbmFyeUluc3RhbGxlci0+aW5zdGFsbEJpbmFyaWVzKCR0YXJnZXQsICRpbnN0YWxsUGF0aCk7CiAgICAgICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRpbml0aWFsKTsKICAgICAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkdGFyZ2V0KSkgewogICAgICAgICAgICAgICAgJHJlcG8tPmFkZFBhY2thZ2UoY2xvbmUgJHRhcmdldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQ6ICcuJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+cmVtb3ZlQ29kZSgkcGFja2FnZSk7CiAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSBcUmVhY3RcUHJvbWlzZVxyZXNvbHZlKCk7CiAgICAgICAgfQoKICAgICAgICAkYmluYXJ5SW5zdGFsbGVyID0gJHRoaXMtPmJpbmFyeUluc3RhbGxlcjsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldFBhY2thZ2VCYXNlUGF0aCgkcGFja2FnZSk7CiAgICAgICAgJGZpbGVzeXN0ZW0gPSAkdGhpcy0+ZmlsZXN5c3RlbTsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJGJpbmFyeUluc3RhbGxlciwgJGZpbGVzeXN0ZW0sICRkb3dubG9hZFBhdGgsICRwYWNrYWdlLCAkcmVwbykgewogICAgICAgICAgICAkYmluYXJ5SW5zdGFsbGVyLT5yZW1vdmVCaW5hcmllcygkcGFja2FnZSk7CiAgICAgICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRwYWNrYWdlKTsKCiAgICAgICAgICAgIGlmIChzdHJwb3MoJHBhY2thZ2UtPmdldE5hbWUoKSwgJy8nKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VWZW5kb3JEaXIgPSBkaXJuYW1lKCRkb3dubG9hZFBhdGgpOwogICAgICAgICAgICAgICAgaWYgKGlzX2RpcigkcGFja2FnZVZlbmRvckRpcikgJiYgJGZpbGVzeXN0ZW0tPmlzRGlyRW1wdHkoJHBhY2thZ2VWZW5kb3JEaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ3JtZGlyJywgJHBhY2thZ2VWZW5kb3JEaXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplVmVuZG9yRGlyKCk7CgogICAgICAgICRiYXNlUGF0aCA9ICgkdGhpcy0+dmVuZG9yRGlyID8gJHRoaXMtPnZlbmRvckRpci4nLycgOiAnJykgLiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICR0YXJnZXREaXIgPSAkcGFja2FnZS0+Z2V0VGFyZ2V0RGlyKCk7CgogICAgICAgIHJldHVybiAkYmFzZVBhdGggLiAoJHRhcmdldERpciA/ICcvJy4kdGFyZ2V0RGlyIDogJycpOwogICAgfQoKICAgIC8qKgogICAgICogTWFrZSBzdXJlIGJpbmFyaWVzIGFyZSBpbnN0YWxsZWQgZm9yIGEgZ2l2ZW4gcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBQYWNrYWdlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbnN1cmVCaW5hcmllc1ByZXNlbmNlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmJpbmFyeUluc3RhbGxlci0+aW5zdGFsbEJpbmFyaWVzKCRwYWNrYWdlLCAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpLCBmYWxzZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBiYXNlIHBhdGggb2YgdGhlIHBhY2thZ2Ugd2l0aG91dCB0YXJnZXQtZGlyIHBhdGgKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIGZvciBCQyBhcyBnZXRJbnN0YWxsUGF0aCB0ZW5kcyB0byBiZSBvdmVycmlkZGVuIGJ5CiAgICAgKiBpbnN0YWxsZXIgcGx1Z2lucyBidXQgbm90IGdldFBhY2thZ2VCYXNlUGF0aAogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBhY2thZ2VCYXNlUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRpbnN0YWxsUGF0aCA9ICR0aGlzLT5nZXRJbnN0YWxsUGF0aCgkcGFja2FnZSk7CiAgICAgICAgJHRhcmdldERpciA9ICRwYWNrYWdlLT5nZXRUYXJnZXREaXIoKTsKCiAgICAgICAgaWYgKCR0YXJnZXREaXIpIHsKICAgICAgICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZSgney8qJy5zdHJfcmVwbGFjZSgnLycsICcvKycsIHByZWdfcXVvdGUoJHRhcmdldERpcikpLicvPyR9JywgJycsICRpbnN0YWxsUGF0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGluc3RhbGxQYXRoOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbnN0YWxsQ29kZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRkb3dubG9hZFBhdGggPSAkdGhpcy0+Z2V0SW5zdGFsbFBhdGgoJHBhY2thZ2UpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmRvd25sb2FkTWFuYWdlci0+aW5zdGFsbCgkcGFja2FnZSwgJGRvd25sb2FkUGF0aCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZUNvZGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgICRpbml0aWFsRG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCRpbml0aWFsKTsKICAgICAgICAkdGFyZ2V0RG93bmxvYWRQYXRoID0gJHRoaXMtPmdldEluc3RhbGxQYXRoKCR0YXJnZXQpOwogICAgICAgIGlmICgkdGFyZ2V0RG93bmxvYWRQYXRoICE9PSAkaW5pdGlhbERvd25sb2FkUGF0aCkgewogICAgICAgICAgICAvLyBpZiB0aGUgdGFyZ2V0IGFuZCBpbml0aWFsIGRpcnMgaW50ZXJzZWN0LCB3ZSBmb3JjZSBhIHJlbW92ZSArIGluc3RhbGwKICAgICAgICAgICAgLy8gdG8gYXZvaWQgdGhlIHJlbmFtZSB3aXBpbmcgdGhlIHRhcmdldCBkaXIgYXMgcGFydCBvZiB0aGUgaW5pdGlhbCBkaXIgY2xlYW51cAogICAgICAgICAgICBpZiAoc3RycG9zKCRpbml0aWFsRG93bmxvYWRQYXRoLCAkdGFyZ2V0RG93bmxvYWRQYXRoKSA9PT0gMAogICAgICAgICAgICAgICAgfHwgc3RycG9zKCR0YXJnZXREb3dubG9hZFBhdGgsICRpbml0aWFsRG93bmxvYWRQYXRoKSA9PT0gMAogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRwcm9taXNlID0gJHRoaXMtPnJlbW92ZUNvZGUoJGluaXRpYWwpOwogICAgICAgICAgICAgICAgaWYgKCEkcHJvbWlzZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAgICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRzZWxmLCAkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgJHJlZmxNZXRob2QgPSBuZXcgXFJlZmxlY3Rpb25NZXRob2QoJHNlbGYsICdpbnN0YWxsQ29kZScpOwogICAgICAgICAgICAgICAgICAgICRyZWZsTWV0aG9kLT5zZXRBY2Nlc3NpYmxlKHRydWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBlcXVpdmFsZW50IG9mICR0aGlzLT5pbnN0YWxsQ29kZSgkdGFyZ2V0KSB3aXRoIHBocCA1LjMgc3VwcG9ydAogICAgICAgICAgICAgICAgICAgIC8vIFRPRE8gcmVtb3ZlIHRoaXMgb25jZSA1LjMgc3VwcG9ydCBpcyBkcm9wcGVkCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRyZWZsTWV0aG9kLT5pbnZva2UoJHNlbGYsICR0YXJnZXQpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW5hbWUoJGluaXRpYWxEb3dubG9hZFBhdGgsICR0YXJnZXREb3dubG9hZFBhdGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXItPnVwZGF0ZSgkaW5pdGlhbCwgJHRhcmdldCwgJHRhcmdldERvd25sb2FkUGF0aCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbW92ZUNvZGUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkZG93bmxvYWRQYXRoID0gJHRoaXMtPmdldFBhY2thZ2VCYXNlUGF0aCgkcGFja2FnZSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZG93bmxvYWRNYW5hZ2VyLT5yZW1vdmUoJHBhY2thZ2UsICRkb3dubG9hZFBhdGgpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplVmVuZG9yRGlyKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCR0aGlzLT52ZW5kb3JEaXIpOwogICAgICAgICR0aGlzLT52ZW5kb3JEaXIgPSByZWFscGF0aCgkdGhpcy0+dmVuZG9yRGlyKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7Cgp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnk7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CgovKioKICogQWRkIHN1Z2dlc3RlZCBwYWNrYWdlcyBmcm9tIGRpZmZlcmVudCBwbGFjZXMgdG8gb3V0cHV0IHRoZW0gaW4gdGhlIGVuZC4KICoKICogQGF1dGhvciBIYXJhbGFuIERvYnJldiA8aGtkb2JyZXZAZ21haWwuY29tPgogKi8KY2xhc3MgU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgp7CiAgICBjb25zdCBNT0RFX0xJU1QgPSAxOwogICAgY29uc3QgTU9ERV9CWV9QQUNLQUdFID0gMjsKICAgIGNvbnN0IE1PREVfQllfU1VHR0VTVElPTiA9IDQ7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3VnZ2VzdGVkUGFja2FnZXMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQHZhciBJT0ludGVyZmFjZQogICAgICovCiAgICBwcml2YXRlICRpbzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkgU3VnZ2VzdGVkIHBhY2thZ2VzIHdpdGggc291cmNlLCB0YXJnZXQgYW5kIHJlYXNvbiBrZXlzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3VnZ2VzdGVkUGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgc3VnZ2VzdGVkIHBhY2thZ2VzIHRvIGJlIGxpc3RlZCBhZnRlciBpbnN0YWxsCiAgICAgKgogICAgICogQ291bGQgYmUgdXNlZCB0byBhZGQgc3VnZ2VzdGVkIHBhY2thZ2VzIGJvdGggZnJvbSB0aGUgaW5zdGFsbGVyCiAgICAgKiBvciBmcm9tIENyZWF0ZVByb2plY3RDb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkc291cmNlIFNvdXJjZSBwYWNrYWdlIHdoaWNoIG1hZGUgdGhlIHN1Z2dlc3Rpb24KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0IFRhcmdldCBwYWNrYWdlIHRvIGJlIHN1Z2dlc3RlZAogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICRyZWFzb24gUmVhc29uIHRoZSB0YXJnZXQgcGFja2FnZSB0byBiZSBzdWdnZXN0ZWQKICAgICAqIEByZXR1cm4gU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUGFja2FnZSgkc291cmNlLCAkdGFyZ2V0LCAkcmVhc29uKQogICAgewogICAgICAgICR0aGlzLT5zdWdnZXN0ZWRQYWNrYWdlc1tdID0gYXJyYXkoCiAgICAgICAgICAgICdzb3VyY2UnID0+ICRzb3VyY2UsCiAgICAgICAgICAgICd0YXJnZXQnID0+ICR0YXJnZXQsCiAgICAgICAgICAgICdyZWFzb24nID0+ICRyZWFzb24sCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFsbCBzdWdnZXN0aW9ucyBmcm9tIGEgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAgICAgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkU3VnZ2VzdGlvbnNGcm9tUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICRzb3VyY2UgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRTdWdnZXN0cygpIGFzICR0YXJnZXQgPT4gJHJlYXNvbikgewogICAgICAgICAgICAkdGhpcy0+YWRkUGFja2FnZSgKICAgICAgICAgICAgICAgICRzb3VyY2UsCiAgICAgICAgICAgICAgICAkdGFyZ2V0LAogICAgICAgICAgICAgICAgJHJlYXNvbgogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogT3V0cHV0IHN1Z2dlc3RlZCBwYWNrYWdlcy4KICAgICAqCiAgICAgKiBEbyBub3QgbGlzdCB0aGUgb25lcyBhbHJlYWR5IGluc3RhbGxlZCBpZiBpbnN0YWxsZWQgcmVwb3NpdG9yeSBwcm92aWRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAgICAgICAgJG1vZGUgICAgICAgICAgICAgT25lIG9mIHRoZSBNT0RFXyogY29uc3RhbnRzIGZyb20gdGhpcyBjbGFzcwogICAgICogQHBhcmFtICBJbnN0YWxsZWRSZXBvc2l0b3J5fG51bGwgICRpbnN0YWxsZWRSZXBvICAgIElmIHBhc3NlZCBpbiwgc3VnZ2VzdGVkIHBhY2thZ2VzIHdoaWNoIGFyZSBpbnN0YWxsZWQgYWxyZWFkeSB3aWxsIGJlIHNraXBwZWQKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZXxudWxsICAgICAkb25seURlcGVuZGVudHNPZiBJZiBwYXNzZWQgaW4sIG9ubHkgdGhlIHN1Z2dlc3Rpb25zIGZyb20gZGlyZWN0IGRlcGVuZGVudHMgb2YgdGhhdCBwYWNrYWdlLCBvciBmcm9tIHRoZSBwYWNrYWdlIGl0c2VsZiwgd2lsbCBiZSBzaG93bgogICAgICogQHJldHVybiBTdWdnZXN0ZWRQYWNrYWdlc1JlcG9ydGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvdXRwdXQoJG1vZGUsIEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8gPSBudWxsLCBQYWNrYWdlSW50ZXJmYWNlICRvbmx5RGVwZW5kZW50c09mID0gbnVsbCkKICAgIHsKICAgICAgICAkc3VnZ2VzdGVkUGFja2FnZXMgPSAkdGhpcy0+Z2V0RmlsdGVyZWRTdWdnZXN0aW9ucygkaW5zdGFsbGVkUmVwbywgJG9ubHlEZXBlbmRlbnRzT2YpOwoKICAgICAgICAkc3VnZ2VzdGVycyA9IGFycmF5KCk7CiAgICAgICAgJHN1Z2dlc3RlZCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHN1Z2dlc3RlZFBhY2thZ2VzIGFzICRzdWdnZXN0aW9uKSB7CiAgICAgICAgICAgICRzdWdnZXN0ZXJzWyRzdWdnZXN0aW9uWydzb3VyY2UnXV1bJHN1Z2dlc3Rpb25bJ3RhcmdldCddXSA9ICRzdWdnZXN0aW9uWydyZWFzb24nXTsKICAgICAgICAgICAgJHN1Z2dlc3RlZFskc3VnZ2VzdGlvblsndGFyZ2V0J11dWyRzdWdnZXN0aW9uWydzb3VyY2UnXV0gPSAkc3VnZ2VzdGlvblsncmVhc29uJ107CiAgICAgICAgfQogICAgICAgIGtzb3J0KCRzdWdnZXN0ZXJzKTsKICAgICAgICBrc29ydCgkc3VnZ2VzdGVkKTsKCiAgICAgICAgLy8gU2ltcGxlIG1vZGUKICAgICAgICBpZiAoJG1vZGUgJiBzZWxmOjpNT0RFX0xJU1QpIHsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkc3VnZ2VzdGVkKSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKCc8aW5mbz4lczwvaW5mbz4nLCAkbmFtZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIEdyb3VwZWQgYnkgcGFja2FnZQogICAgICAgIGlmICgkbW9kZSAmIHNlbGY6Ok1PREVfQllfUEFDS0FHRSkgewogICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVycyBhcyAkc3VnZ2VzdGVyID0+ICRzdWdnZXN0aW9ucykgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKCc8Y29tbWVudD4lczwvY29tbWVudD4gc3VnZ2VzdHM6JywgJHN1Z2dlc3RlcikpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRzdWdnZXN0aW9ucyBhcyAkc3VnZ2VzdGlvbiA9PiAkcmVhc29uKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzcHJpbnRmKCcgLSA8aW5mbz4lczwvaW5mbz4nIC4gKCRyZWFzb24gPyAnOiAlcycgOiAnJyksICRzdWdnZXN0aW9uLCAkdGhpcy0+ZXNjYXBlT3V0cHV0KCRyZWFzb24pKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKCcnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gR3JvdXBlZCBieSBzdWdnZXN0aW9uCiAgICAgICAgaWYgKCRtb2RlICYgc2VsZjo6TU9ERV9CWV9TVUdHRVNUSU9OKSB7CiAgICAgICAgICAgIC8vIEltcHJvdmUgcmVhZGFiaWxpdHkgaW4gZnVsbCBtb2RlCiAgICAgICAgICAgIGlmICgkbW9kZSAmIHNlbGY6Ok1PREVfQllfUEFDS0FHRSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZShzdHJfcmVwZWF0KCctJywgNzgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVkIGFzICRzdWdnZXN0aW9uID0+ICRzdWdnZXN0ZXJzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKHNwcmludGYoJzxjb21tZW50PiVzPC9jb21tZW50PiBpcyBzdWdnZXN0ZWQgYnk6JywgJHN1Z2dlc3Rpb24pKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkc3VnZ2VzdGVycyBhcyAkc3VnZ2VzdGVyID0+ICRyZWFzb24pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlKHNwcmludGYoJyAtIDxpbmZvPiVzPC9pbmZvPicgLiAoJHJlYXNvbiA/ICc6ICVzJyA6ICcnKSwgJHN1Z2dlc3RlciwgJHRoaXMtPmVzY2FwZU91dHB1dCgkcmVhc29uKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgnJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkb25seURlcGVuZGVudHNPZikgewogICAgICAgICAgICAkYWxsU3VnZ2VzdGVkUGFja2FnZXMgPSAkdGhpcy0+Z2V0RmlsdGVyZWRTdWdnZXN0aW9ucygkaW5zdGFsbGVkUmVwbyk7CiAgICAgICAgICAgICRkaWZmID0gY291bnQoJGFsbFN1Z2dlc3RlZFBhY2thZ2VzKSAtIGNvdW50KCRzdWdnZXN0ZWRQYWNrYWdlcyk7CiAgICAgICAgICAgIGlmICgkZGlmZikgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZSgnPGluZm8+Jy4kZGlmZi4nIGFkZGl0aW9uYWwgc3VnZ2VzdGlvbnM8L2luZm8+IGJ5IHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIGNhbiBiZSBzaG93biB3aXRoIDxpbmZvPi0tYWxsPC9pbmZvPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBPdXRwdXQgbnVtYmVyIG9mIG5ldyBzdWdnZXN0ZWQgcGFja2FnZXMgYW5kIGEgaGludCB0byB1c2Ugc3VnZ2VzdCBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeXxudWxsICAkaW5zdGFsbGVkUmVwbyAgICBJZiBwYXNzZWQgaW4sIHN1Z2dlc3RlZCBwYWNrYWdlcyB3aGljaCBhcmUgaW5zdGFsbGVkIGFscmVhZHkgd2lsbCBiZSBza2lwcGVkCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAgICAgJG9ubHlEZXBlbmRlbnRzT2YgSWYgcGFzc2VkIGluLCBvbmx5IHRoZSBzdWdnZXN0aW9ucyBmcm9tIGRpcmVjdCBkZXBlbmRlbnRzIG9mIHRoYXQgcGFja2FnZSwgb3IgZnJvbSB0aGUgcGFja2FnZSBpdHNlbGYsIHdpbGwgYmUgc2hvd24KICAgICAqIEByZXR1cm4gU3VnZ2VzdGVkUGFja2FnZXNSZXBvcnRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb3V0cHV0TWluaW1hbGlzdGljKEluc3RhbGxlZFJlcG9zaXRvcnkgJGluc3RhbGxlZFJlcG8gPSBudWxsLCBQYWNrYWdlSW50ZXJmYWNlICRvbmx5RGVwZW5kZW50c09mID0gbnVsbCkKICAgIHsKICAgICAgICAkc3VnZ2VzdGVkUGFja2FnZXMgPSAkdGhpcy0+Z2V0RmlsdGVyZWRTdWdnZXN0aW9ucygkaW5zdGFsbGVkUmVwbywgJG9ubHlEZXBlbmRlbnRzT2YpOwogICAgICAgIGlmICgkc3VnZ2VzdGVkUGFja2FnZXMpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8aW5mbz4nLmNvdW50KCRzdWdnZXN0ZWRQYWNrYWdlcykuJyBwYWNrYWdlIHN1Z2dlc3Rpb25zIHdlcmUgYWRkZWQgYnkgbmV3IGRlcGVuZGVuY2llcywgdXNlIGBjb21wb3NlciBzdWdnZXN0YCB0byBzZWUgZGV0YWlscy48L2luZm8+Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnl8bnVsbCAkaW5zdGFsbGVkUmVwbyAgICBJZiBwYXNzZWQgaW4sIHN1Z2dlc3RlZCBwYWNrYWdlcyB3aGljaCBhcmUgaW5zdGFsbGVkIGFscmVhZHkgd2lsbCBiZSBza2lwcGVkCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAgICAkb25seURlcGVuZGVudHNPZiBJZiBwYXNzZWQgaW4sIG9ubHkgdGhlIHN1Z2dlc3Rpb25zIGZyb20gZGlyZWN0IGRlcGVuZGVudHMgb2YgdGhhdCBwYWNrYWdlLCBvciBmcm9tIHRoZSBwYWNrYWdlIGl0c2VsZiwgd2lsbCBiZSBzaG93bgogICAgICogQHJldHVybiBhcnJheVtdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RmlsdGVyZWRTdWdnZXN0aW9ucyhJbnN0YWxsZWRSZXBvc2l0b3J5ICRpbnN0YWxsZWRSZXBvID0gbnVsbCwgUGFja2FnZUludGVyZmFjZSAkb25seURlcGVuZGVudHNPZiA9IG51bGwpCiAgICB7CiAgICAgICAgJHN1Z2dlc3RlZFBhY2thZ2VzID0gJHRoaXMtPmdldFBhY2thZ2VzKCk7CiAgICAgICAgJGluc3RhbGxlZE5hbWVzID0gYXJyYXkoKTsKICAgICAgICBpZiAobnVsbCAhPT0gJGluc3RhbGxlZFJlcG8gJiYgIWVtcHR5KCRzdWdnZXN0ZWRQYWNrYWdlcykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGluc3RhbGxlZFJlcG8tPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRpbnN0YWxsZWROYW1lcyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgICAgICRpbnN0YWxsZWROYW1lcywKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0TmFtZXMoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHNvdXJjZUZpbHRlciA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRvbmx5RGVwZW5kZW50c09mKSB7CiAgICAgICAgICAgICRzb3VyY2VGaWx0ZXIgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaW5rKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICB9LCBhcnJheV9tZXJnZSgkb25seURlcGVuZGVudHNPZi0+Z2V0UmVxdWlyZXMoKSwgJG9ubHlEZXBlbmRlbnRzT2YtPmdldERldlJlcXVpcmVzKCkpKTsKICAgICAgICAgICAgJHNvdXJjZUZpbHRlcltdID0gJG9ubHlEZXBlbmRlbnRzT2YtPmdldE5hbWUoKTsKICAgICAgICB9CgogICAgICAgICRzdWdnZXN0aW9ucyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHN1Z2dlc3RlZFBhY2thZ2VzIGFzICRzdWdnZXN0aW9uKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkc3VnZ2VzdGlvblsndGFyZ2V0J10sICRpbnN0YWxsZWROYW1lcykgfHwgKCRzb3VyY2VGaWx0ZXIgJiYgIWluX2FycmF5KCRzdWdnZXN0aW9uWydzb3VyY2UnXSwgJHNvdXJjZUZpbHRlcikpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN1Z2dlc3Rpb25zW10gPSAkc3VnZ2VzdGlvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3VnZ2VzdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkc3RyaW5nCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZU91dHB1dCgkc3RyaW5nKQogICAgewogICAgICAgIHJldHVybiBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgKICAgICAgICAgICAgJHRoaXMtPnJlbW92ZUNvbnRyb2xDaGFyYWN0ZXJzKCRzdHJpbmcpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICRzdHJpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVtb3ZlQ29udHJvbENoYXJhY3RlcnMoJHN0cmluZykKICAgIHsKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICAgICAnL1tbOmNudHJsOl1dLycsCiAgICAgICAgICAgICcnLAogICAgICAgICAgICBzdHJfcmVwbGFjZSgiXG4iLCAnICcsICRzdHJpbmcpCiAgICAgICAgKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7Cgp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIERvZXMgbm90IGluc3RhbGwgYW55dGhpbmcgYnV0IG1hcmtzIHBhY2thZ2VzIGluc3RhbGxlZCBpbiB0aGUgcmVwbwogKgogKiBVc2VmdWwgZm9yIGRyeSBydW5zCiAqCiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIE5vb3BJbnN0YWxsZXIgaW1wbGVtZW50cyBJbnN0YWxsZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdXBwb3J0cygkcGFja2FnZVR5cGUpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0luc3RhbGxlZChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcmVwYXJlKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgJHJlcG8tPmFkZFBhY2thZ2UoY2xvbmUgJHBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQpCiAgICB7CiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkaW5pdGlhbCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BhY2thZ2UgaXMgbm90IGluc3RhbGxlZDogJy4kaW5pdGlhbCk7CiAgICAgICAgfQoKICAgICAgICAkcmVwby0+cmVtb3ZlUGFja2FnZSgkaW5pdGlhbCk7CiAgICAgICAgaWYgKCEkcmVwby0+aGFzUGFja2FnZSgkdGFyZ2V0KSkgewogICAgICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkdGFyZ2V0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBpZiAoISRyZXBvLT5oYXNQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSBpcyBub3QgaW5zdGFsbGVkOiAnLiRwYWNrYWdlKTsKICAgICAgICB9CiAgICAgICAgJHJlcG8tPnJlbW92ZVBhY2thZ2UoJHBhY2thZ2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbFBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGFyZ2V0RGlyID0gJHBhY2thZ2UtPmdldFRhcmdldERpcigpOwoKICAgICAgICByZXR1cm4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSAuICgkdGFyZ2V0RGlyID8gJy8nLiR0YXJnZXREaXIgOiAnJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZTsKdXNlIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIHRoZSBwYWNrYWdlIGluc3RhbGxhdGlvbiBtYW5hZ2VyLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgSW5zdGFsbGVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogRGVjaWRlcyBpZiB0aGUgaW5zdGFsbGVyIHN1cHBvcnRzIHRoZSBnaXZlbiB0eXBlCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhY2thZ2VUeXBlCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1cHBvcnRzKCRwYWNrYWdlVHlwZSk7CgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhhdCBwcm92aWRlZCBwYWNrYWdlIGlzIGluc3RhbGxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0luc3RhbGxlZChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKCiAgICAvKioKICAgICAqIERvd25sb2FkcyB0aGUgZmlsZXMgbmVlZGVkIHRvIGxhdGVyIGluc3RhbGwgdGhlIGdpdmVuIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgICAgIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgYW4gdXBkYXRlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKTsKCiAgICAvKioKICAgICAqIERvIGFueXRoaW5nIHRoYXQgbmVlZHMgdG8gYmUgZG9uZSBiZXR3ZWVuIGFsbCBkb3dubG9hZHMgaGF2ZSBiZWVuIGNvbXBsZXRlZCBhbmQgdGhlIGFjdHVhbCBvcGVyYXRpb24gaXMgZXhlY3V0ZWQKICAgICAqCiAgICAgKiBBbGwgcGFja2FnZXMgZ2V0IGZpcnN0IGRvd25sb2FkZWQsIHRoZW4gYWxsIHRvZ2V0aGVyIHByZXBhcmVkLCB0aGVuIGFsbCB0b2dldGhlciBpbnN0YWxsZWQvdXBkYXRlZC91bmluc3RhbGxlZC4gVGhlcmVmb3JlCiAgICAgKiBmb3IgZXJyb3IgcmVjb3ZlcnkgaXQgaXMgaW1wb3J0YW50IHRvIGF2b2lkIGZhaWxpbmcgZHVyaW5nIGluc3RhbGwvdXBkYXRlL3VuaW5zdGFsbCBhcyBtdWNoIGFzIHBvc3NpYmxlLCBhbmQgcmlza3kgdGhpbmdzIG9yCiAgICAgKiB1c2VyIHByb21wdHMgc2hvdWxkIGhhcHBlbiBpbiB0aGUgcHJlcGFyZSBzdGVwIHJhdGhlci4gSW4gY2FzZSBvZiBmYWlsdXJlLCBjbGVhbnVwKCkgd2lsbCBiZSBjYWxsZWQgc28gdGhhdCBjaGFuZ2VzIGNhbgogICAgICogYmUgdW5kb25lIGFzIG11Y2ggYXMgcG9zc2libGUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHR5cGUgICAgICAgIG9uZSBvZiBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSBpbnN0YW5jZSBpbiBjYXNlIG9mIGFuIHVwZGF0ZQogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBJbnN0YWxscyBzcGVjaWZpYyBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSAgSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbyAgICByZXBvc2l0b3J5IGluIHdoaWNoIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAgICAgICAgJHBhY2thZ2UgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7CgogICAgLyoqCiAgICAgKiBVcGRhdGVzIHNwZWNpZmljIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvICAgIHJlcG9zaXRvcnkgaW4gd2hpY2ggdG8gY2hlY2sKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkaW5pdGlhbCBhbHJlYWR5IGluc3RhbGxlZCBwYWNrYWdlIHZlcnNpb24KICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICAgICAgICAkdGFyZ2V0ICB1cGRhdGVkIHZlcnNpb24KICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICAgICBpZiAkaW5pdGlhbCBwYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KTsKCiAgICAvKioKICAgICAqIFVuaW5zdGFsbHMgc3BlY2lmaWMgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8gICAgcmVwb3NpdG9yeSBpbiB3aGljaCB0byBjaGVjawogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICAgICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7CgogICAgLyoqCiAgICAgKiBEbyBhbnl0aGluZyB0byBjbGVhbnVwIGNoYW5nZXMgYXBwbGllZCBpbiB0aGUgcHJlcGFyZSBvciBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwgc3RlcHMKICAgICAqCiAgICAgKiBOb3RlIHRoYXQgY2xlYW51cCB3aWxsIGJlIGNhbGxlZCBmb3IgYWxsIHBhY2thZ2VzIHJlZ2FyZGxlc3MgaWYgdGhleSBmYWlsZWQgYW4gb3BlcmF0aW9uIG9yIG5vdCwgdG8gZ2l2ZQogICAgICogYWxsIGluc3RhbGxlcnMgYSBjaGFuZ2UgdG8gY2xlYW51cCB0aGluZ3MgdGhleSBkaWQgcHJldmlvdXNseSwgc28geW91IG5lZWQgdG8ga2VlcCB0cmFjayBvZiBjaGFuZ2VzCiAgICAgKiBhcHBsaWVkIGluIHRoZSBpbnN0YWxsZXIvZG93bmxvYWRlciB0aGVtc2VsdmVzLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiBhbiB1cGRhdGUKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5zdGFsbGF0aW9uIHBhdGggb2YgYSBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCiAgICAgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgICAgcGF0aCB0byBpbnN0YWxsIHRvLCB3aGljaCBNVVNUIG5vdCBlbmQgd2l0aCBhIHNsYXNoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxJbnN0YWxsZXI7CgpjbGFzcyBJbnN0YWxsZXJFdmVudHMKewogICAgLyoqCiAgICAgKiBUaGUgUFJFX09QRVJBVElPTlNfRVhFQyBldmVudCBvY2N1cnMgYmVmb3JlIHRoZSBsb2NrIGZpbGUgZ2V0cwogICAgICogaW5zdGFsbGVkIGFuZCBvcGVyYXRpb25zIGFyZSBleGVjdXRlZC4KICAgICAqCiAgICAgKiBUaGUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kIHJlY2VpdmVzIGFuIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsZXJFdmVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBQUkVfT1BFUkFUSU9OU19FWEVDID0gJ3ByZS1vcGVyYXRpb25zLWV4ZWMnOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVXBkYXRlT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb247CgovKioKICogTWV0YXBhY2thZ2UgaW5zdGFsbGF0aW9uIG1hbmFnZXIuCiAqCiAqIEBhdXRob3IgTWFydGluIEhhc2/FiCA8bWFydGluLmhhc29uQGdtYWlsLmNvbT4KICovCmNsYXNzIE1ldGFwYWNrYWdlSW5zdGFsbGVyIGltcGxlbWVudHMgSW5zdGFsbGVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGlvOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VwcG9ydHMoJHBhY2thZ2VUeXBlKQogICAgewogICAgICAgIHJldHVybiAkcGFja2FnZVR5cGUgPT09ICdtZXRhcGFja2FnZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0luc3RhbGxlZChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIHJldHVybiAkcmVwby0+aGFzUGFja2FnZSgkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gbm9vcAogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIC8vIG5vb3AKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBub29wCiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKEluc3RhbGxlZFJlcG9zaXRvcnlJbnRlcmZhY2UgJHJlcG8sIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIEluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkpOwoKICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkcGFja2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoSW5zdGFsbGVkUmVwb3NpdG9yeUludGVyZmFjZSAkcmVwbywgUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJGluaXRpYWwpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQ6ICcuJGluaXRpYWwpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIFVwZGF0ZU9wZXJhdGlvbjo6Zm9ybWF0KCRpbml0aWFsLCAkdGFyZ2V0KSk7CgogICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRpbml0aWFsKTsKICAgICAgICAkcmVwby0+YWRkUGFja2FnZShjbG9uZSAkdGFyZ2V0KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbChJbnN0YWxsZWRSZXBvc2l0b3J5SW50ZXJmYWNlICRyZXBvLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICghJHJlcG8tPmhhc1BhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQ6ICcuJHBhY2thZ2UpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIFVuaW5zdGFsbE9wZXJhdGlvbjo6Zm9ybWF0KCRwYWNrYWdlKSk7CgogICAgICAgICRyZXBvLT5yZW1vdmVQYWNrYWdlKCRwYWNrYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxQYXRoKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuICcnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEluc3RhbGxlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CgovKioKICogSW50ZXJmYWNlIGZvciB0aGUgcGFja2FnZSBpbnN0YWxsYXRpb24gbWFuYWdlciB0aGF0IGhhbmRsZSBiaW5hcnkgaW5zdGFsbGF0aW9uLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwppbnRlcmZhY2UgQmluYXJ5UHJlc2VuY2VJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBNYWtlIHN1cmUgYmluYXJpZXMgYXJlIGluc3RhbGxlZCBmb3IgYSBnaXZlbiBwYWNrYWdlLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuc3VyZUJpbmFyaWVzUHJlc2VuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcSW5zdGFsbGVyOwoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXFRyYW5zYWN0aW9uOwp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CgpjbGFzcyBJbnN0YWxsZXJFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIC8qKgogICAgICogQHZhciBDb21wb3NlcgogICAgICovCiAgICBwcml2YXRlICRjb21wb3NlcjsKCiAgICAvKioKICAgICAqIEB2YXIgSU9JbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkaW87CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSAkZGV2TW9kZTsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRleGVjdXRlT3BlcmF0aW9uczsKCiAgICAvKioKICAgICAqIEB2YXIgVHJhbnNhY3Rpb24KICAgICAqLwogICAgcHJpdmF0ZSAkdHJhbnNhY3Rpb247CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGV2ZW50TmFtZQogICAgICogQHBhcmFtIENvbXBvc2VyICAgICRjb21wb3NlcgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRkZXZNb2RlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgJGV4ZWN1dGVPcGVyYXRpb25zCiAgICAgKiBAcGFyYW0gVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZXZlbnROYW1lLCBDb21wb3NlciAkY29tcG9zZXIsIElPSW50ZXJmYWNlICRpbywgJGRldk1vZGUsICRleGVjdXRlT3BlcmF0aW9ucywgVHJhbnNhY3Rpb24gJHRyYW5zYWN0aW9uKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGV2ZW50TmFtZSk7CgogICAgICAgICR0aGlzLT5jb21wb3NlciA9ICRjb21wb3NlcjsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmRldk1vZGUgPSAkZGV2TW9kZTsKICAgICAgICAkdGhpcy0+ZXhlY3V0ZU9wZXJhdGlvbnMgPSAkZXhlY3V0ZU9wZXJhdGlvbnM7CiAgICAgICAgJHRoaXMtPnRyYW5zYWN0aW9uID0gJHRyYW5zYWN0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb21wb3NlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcG9zZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcG9zZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJTygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZXZNb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldk1vZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRXhlY3V0aW5nT3BlcmF0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leGVjdXRlT3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVHJhbnNhY3Rpb258bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHJhbnNhY3Rpb247CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290UGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTG9ja2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxMb29wOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5TWFuYWdlcjsKdXNlIENvbXBvc2VyXEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbk1hbmFnZXI7CnVzZSBDb21wb3NlclxEb3dubG9hZGVyXERvd25sb2FkTWFuYWdlcjsKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxBdXRvbG9hZFxBdXRvbG9hZEdlbmVyYXRvcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXJcQXJjaGl2ZU1hbmFnZXI7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hpdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgQ29tcG9zZXIKewogICAgLyoKICAgICAqIEV4YW1wbGVzIG9mIHRoZSBmb2xsb3dpbmcgY29uc3RhbnRzIGluIHRoZSB2YXJpb3VzIGNvbmZpZ3VyYXRpb25zIHRoZXkgY2FuIGJlIGluCiAgICAgKgogICAgICogcmVsZWFzZXMgKHBoYXIpOgogICAgICogY29uc3QgVkVSU0lPTiA9ICcxLjguMic7CiAgICAgKiBjb25zdCBCUkFOQ0hfQUxJQVNfVkVSU0lPTiA9ICcnOwogICAgICogY29uc3QgUkVMRUFTRV9EQVRFID0gJzIwMTktMDEtMjkgMTU6MDA6NTMnOwogICAgICogY29uc3QgU09VUkNFX1ZFUlNJT04gPSAnJzsKICAgICAqCiAgICAgKiBzbmFwc2hvdCBidWlsZHMgKHBoYXIpOgogICAgICogY29uc3QgVkVSU0lPTiA9ICdkMzg3M2EwNTY1MGUxNjgyNTEwNjdkOTY0ODg0NWMyMjBjNTBlMmQ3JzsKICAgICAqIGNvbnN0IEJSQU5DSF9BTElBU19WRVJTSU9OID0gJzEuOS1kZXYnOwogICAgICogY29uc3QgUkVMRUFTRV9EQVRFID0gJzIwMTktMDItMjAgMDc6NDM6NTYnOwogICAgICogY29uc3QgU09VUkNFX1ZFUlNJT04gPSAnJzsKICAgICAqCiAgICAgKiBzb3VyY2UgKGdpdCBjbG9uZSk6CiAgICAgKiBjb25zdCBWRVJTSU9OID0gJ0BwYWNrYWdlX3ZlcnNpb25AJzsKICAgICAqIGNvbnN0IEJSQU5DSF9BTElBU19WRVJTSU9OID0gJ0BwYWNrYWdlX2JyYW5jaF9hbGlhc192ZXJzaW9uQCc7CiAgICAgKiBjb25zdCBSRUxFQVNFX0RBVEUgPSAnQHJlbGVhc2VfZGF0ZUAnOwogICAgICogY29uc3QgU09VUkNFX1ZFUlNJT04gPSAnMS44LWRlditzb3VyY2UnOwogICAgICovCiAgICBjb25zdCBWRVJTSU9OID0gJzIuMC4xMyc7CiAgICBjb25zdCBCUkFOQ0hfQUxJQVNfVkVSU0lPTiA9ICcnOwogICAgY29uc3QgUkVMRUFTRV9EQVRFID0gJzIwMjEtMDQtMjcgMTM6MTE6MDgnOwogICAgY29uc3QgU09VUkNFX1ZFUlNJT04gPSAnJzsKCiAgICAvKioKICAgICAqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcm5hbCBjb21wb3Nlci1ydW50aW1lLWFwaSBwYWNrYWdlCiAgICAgKgogICAgICogVGhpcyBpcyB1c2VkIHRvIHZlcnNpb24gZmVhdHVyZXMgYXZhaWxhYmxlIHRvIHByb2plY3RzIGF0IHJ1bnRpbWUKICAgICAqIGxpa2UgdGhlIHBsYXRmb3JtLWNoZWNrIGZpbGUsIHRoZSBDb21wb3NlclxJbnN0YWxsZWRWZXJzaW9ucyBjbGFzcwogICAgICogYW5kIHBvc3NpYmx5IG90aGVycyBpbiB0aGUgZnV0dXJlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IFJVTlRJTUVfQVBJX1ZFUlNJT04gPSAnMi4wLjAnOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmVyc2lvbigpCiAgICB7CiAgICAgICAgLy8gbm8gcmVwbGFjZW1lbnQgZG9uZSwgdGhpcyBtdXN0IGJlIGEgc291cmNlIGNoZWNrb3V0CiAgICAgICAgaWYgKHNlbGY6OlZFUlNJT04gPT09ICdAcGFja2FnZV92ZXJzaW9uJy4nQCcpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OlNPVVJDRV9WRVJTSU9OOwogICAgICAgIH0KCiAgICAgICAgLy8gd2UgaGF2ZSBhIGJyYW5jaCBhbGlhcyBhbmQgdmVyc2lvbiBpcyBhIGNvbW1pdCBpZCwgdGhpcyBtdXN0IGJlIGEgc25hcHNob3QgYnVpbGQKICAgICAgICBpZiAoc2VsZjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04gIT09ICcnICYmIHByZWdfbWF0Y2goJ3teW2EtZjAtOV17NDB9JH0nLCBzZWxmOjpWRVJTSU9OKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6QlJBTkNIX0FMSUFTX1ZFUlNJT04uJysnLnNlbGY6OlZFUlNJT047CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6VkVSU0lPTjsKICAgIH0KCiAgICAvKioKICAgICAqIEB2YXIgUm9vdFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZTsKCiAgICAvKioKICAgICAqIEB2YXIgTG9ja2VyCiAgICAgKi8KICAgIHByaXZhdGUgJGxvY2tlcjsKCiAgICAvKioKICAgICAqIEB2YXIgTG9vcAogICAgICovCiAgICBwcml2YXRlICRsb29wOwoKICAgIC8qKgogICAgICogQHZhciBSZXBvc2l0b3J5XFJlcG9zaXRvcnlNYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJHJlcG9zaXRvcnlNYW5hZ2VyOwoKICAgIC8qKgogICAgICogQHZhciBEb3dubG9hZGVyXERvd25sb2FkTWFuYWdlcgogICAgICovCiAgICBwcml2YXRlICRkb3dubG9hZE1hbmFnZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIEluc3RhbGxlclxJbnN0YWxsYXRpb25NYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJGluc3RhbGxhdGlvbk1hbmFnZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIFBsdWdpblxQbHVnaW5NYW5hZ2VyCiAgICAgKi8KICAgIHByaXZhdGUgJHBsdWdpbk1hbmFnZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIENvbmZpZwogICAgICovCiAgICBwcml2YXRlICRjb25maWc7CgogICAgLyoqCiAgICAgKiBAdmFyIEV2ZW50RGlzcGF0Y2hlcgogICAgICovCiAgICBwcml2YXRlICRldmVudERpc3BhdGNoZXI7CgogICAgLyoqCiAgICAgKiBAdmFyIEF1dG9sb2FkXEF1dG9sb2FkR2VuZXJhdG9yCiAgICAgKi8KICAgIHByaXZhdGUgJGF1dG9sb2FkR2VuZXJhdG9yOwoKICAgIC8qKgogICAgICogQHZhciBBcmNoaXZlTWFuYWdlcgogICAgICovCiAgICBwcml2YXRlICRhcmNoaXZlTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSAgUm9vdFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGFja2FnZShSb290UGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSb290UGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIENvbmZpZyAkY29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25maWcoQ29uZmlnICRjb25maWcpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbmZpZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uZmlnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmZpZzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBMb2NrZXIgJGxvY2tlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9ja2VyKExvY2tlciAkbG9ja2VyKQogICAgewogICAgICAgICR0aGlzLT5sb2NrZXIgPSAkbG9ja2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBMb2NrZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2tlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NrZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gTG9vcCAkbG9vcAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TG9vcChMb29wICRsb29wKQogICAgewogICAgICAgICR0aGlzLT5sb29wID0gJGxvb3A7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIExvb3AKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvb3AoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9vcDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSZXBvc2l0b3J5TWFuYWdlciAkbWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVwb3NpdG9yeU1hbmFnZXIoUmVwb3NpdG9yeU1hbmFnZXIgJG1hbmFnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcG9zaXRvcnlNYW5hZ2VyID0gJG1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFJlcG9zaXRvcnlNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvc2l0b3J5TWFuYWdlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXBvc2l0b3J5TWFuYWdlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBEb3dubG9hZE1hbmFnZXIgJG1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERvd25sb2FkTWFuYWdlcihEb3dubG9hZE1hbmFnZXIgJG1hbmFnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvd25sb2FkTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBEb3dubG9hZE1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERvd25sb2FkTWFuYWdlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZE1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQXJjaGl2ZU1hbmFnZXIgJG1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyY2hpdmVNYW5hZ2VyKEFyY2hpdmVNYW5hZ2VyICRtYW5hZ2VyKQogICAgewogICAgICAgICR0aGlzLT5hcmNoaXZlTWFuYWdlciA9ICRtYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBBcmNoaXZlTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJjaGl2ZU1hbmFnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJjaGl2ZU1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSW5zdGFsbGF0aW9uTWFuYWdlciAkbWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5zdGFsbGF0aW9uTWFuYWdlcihJbnN0YWxsYXRpb25NYW5hZ2VyICRtYW5hZ2VyKQogICAgewogICAgICAgICR0aGlzLT5pbnN0YWxsYXRpb25NYW5hZ2VyID0gJG1hbmFnZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEluc3RhbGxhdGlvbk1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxhdGlvbk1hbmFnZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5zdGFsbGF0aW9uTWFuYWdlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBQbHVnaW5NYW5hZ2VyICRtYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQbHVnaW5NYW5hZ2VyKFBsdWdpbk1hbmFnZXIgJG1hbmFnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPnBsdWdpbk1hbmFnZXIgPSAkbWFuYWdlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gUGx1Z2luTWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGx1Z2luTWFuYWdlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wbHVnaW5NYW5hZ2VyOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFdmVudERpc3BhdGNoZXIoRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmV2ZW50RGlzcGF0Y2hlciA9ICRldmVudERpc3BhdGNoZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEV2ZW50RGlzcGF0Y2hlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXZlbnREaXNwYXRjaGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV2ZW50RGlzcGF0Y2hlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBBdXRvbG9hZEdlbmVyYXRvciAkYXV0b2xvYWRHZW5lcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dG9sb2FkR2VuZXJhdG9yKEF1dG9sb2FkR2VuZXJhdG9yICRhdXRvbG9hZEdlbmVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+YXV0b2xvYWRHZW5lcmF0b3IgPSAkYXV0b2xvYWRHZW5lcmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIEF1dG9sb2FkR2VuZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvbG9hZEdlbmVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hdXRvbG9hZEdlbmVyYXRvcjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVyIGludGVyZmFjZS4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KaW50ZXJmYWNlIERvd25sb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGluc3RhbGxhdGlvbiBzb3VyY2UgKGVpdGhlciBzb3VyY2Ugb3IgZGlzdCkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgInNvdXJjZSIgb3IgImRpc3QiCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnN0YWxsYXRpb25Tb3VyY2UoKTsKCiAgICAvKioKICAgICAqIFRoaXMgc2hvdWxkIGRvIGFueSBuZXR3b3JrLXJlbGF0ZWQgdGFza3MgdG8gcHJlcGFyZSBmb3IgYW4gdXBjb21pbmcgaW5zdGFsbC91cGRhdGUKICAgICAqCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBEbyBhbnl0aGluZyB0aGF0IG5lZWRzIHRvIGJlIGRvbmUgYmV0d2VlbiBhbGwgZG93bmxvYWRzIGhhdmUgYmVlbiBjb21wbGV0ZWQgYW5kIHRoZSBhY3R1YWwgb3BlcmF0aW9uIGlzIGV4ZWN1dGVkCiAgICAgKgogICAgICogQWxsIHBhY2thZ2VzIGdldCBmaXJzdCBkb3dubG9hZGVkLCB0aGVuIGFsbCB0b2dldGhlciBwcmVwYXJlZCwgdGhlbiBhbGwgdG9nZXRoZXIgaW5zdGFsbGVkL3VwZGF0ZWQvdW5pbnN0YWxsZWQuIFRoZXJlZm9yZQogICAgICogZm9yIGVycm9yIHJlY292ZXJ5IGl0IGlzIGltcG9ydGFudCB0byBhdm9pZCBmYWlsaW5nIGR1cmluZyBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwgYXMgbXVjaCBhcyBwb3NzaWJsZSwgYW5kIHJpc2t5IHRoaW5ncyBvcgogICAgICogdXNlciBwcm9tcHRzIHNob3VsZCBoYXBwZW4gaW4gdGhlIHByZXBhcmUgc3RlcCByYXRoZXIuIEluIGNhc2Ugb2YgZmFpbHVyZSwgY2xlYW51cCgpIHdpbGwgYmUgY2FsbGVkIHNvIHRoYXQgY2hhbmdlcyBjYW4KICAgICAqIGJlIHVuZG9uZSBhcyBtdWNoIGFzIHBvc3NpYmxlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHBhdGggICAgICAgIGRvd25sb2FkIHBhdGgKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgYW4gdXBkYXRlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBJbnN0YWxscyBzcGVjaWZpYyBwYWNrYWdlIGludG8gc3BlY2lmaWMgZm9sZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIGRvd25sb2FkIHBhdGgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwoKICAgIC8qKgogICAgICogVXBkYXRlcyBzcGVjaWZpYyBwYWNrYWdlIGluIHNwZWNpZmljIGZvbGRlciBmcm9tIGluaXRpYWwgdG8gdGFyZ2V0IHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwgaW5pdGlhbCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0ICB1cGRhdGVkIHBhY2thZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIGRvd25sb2FkIHBhdGgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgc3BlY2lmaWMgcGFja2FnZSBmcm9tIHNwZWNpZmljIGZvbGRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwoKICAgIC8qKgogICAgICogRG8gYW55dGhpbmcgdG8gY2xlYW51cCBjaGFuZ2VzIGFwcGxpZWQgaW4gdGhlIHByZXBhcmUgb3IgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsIHN0ZXBzCiAgICAgKgogICAgICogTm90ZSB0aGF0IGNsZWFudXAgd2lsbCBiZSBjYWxsZWQgZm9yIGFsbCBwYWNrYWdlcywgZWl0aGVyIGFmdGVyIGluc3RhbGwvdXBkYXRlL3VuaW5zdGFsbCBpcyBjb21wbGV0ZSwKICAgICAqIG9yIGlmIGFueSBwYWNrYWdlIGZhaWxlZCBhbnkgb3BlcmF0aW9uLiBUaGlzIGlzIHRvIGdpdmUgYWxsIGluc3RhbGxlcnMgYSBjaGFuZ2UgdG8gY2xlYW51cCB0aGluZ3MKICAgICAqIHRoZXkgZGlkIHByZXZpb3VzbHksIHNvIHlvdSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgY2hhbmdlcyBhcHBsaWVkIGluIHRoZSBpbnN0YWxsZXIvZG93bmxvYWRlciB0aGVtc2VsdmVzLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgICAgICAkcGFja2FnZSAgICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJHBhdGggICAgICAgIGRvd25sb2FkIHBhdGgKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAgICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgYW4gdXBkYXRlCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYW51cCgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxVdGlsXEluaUhlbHBlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIFJhckFyY2hpdmU7CgovKioKICogUkFSIGFyY2hpdmUgZG93bmxvYWRlci4KICoKICogQmFzZWQgb24gcHJldmlvdXMgd29yayBieSBKb3JkaSBCb2dnaWFubyAoe0BzZWUgWmlwRG93bmxvYWRlcn0pLgogKgogKiBAYXV0aG9yIERlcnJpY2sgTmVsc29uIDxkcnJja25sc25AZ21haWwuY29tPgogKi8KY2xhc3MgUmFyRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleHRyYWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCkKICAgIHsKICAgICAgICAkcHJvY2Vzc0Vycm9yID0gbnVsbDsKCiAgICAgICAgLy8gVHJ5IHRvIHVzZSB1bnJhciBvbiAqbml4CiAgICAgICAgaWYgKCFQbGF0Zm9ybTo6aXNXaW5kb3dzKCkpIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSAndW5yYXIgeCAtLSAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGZpbGUpIC4gJyAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpIC4gJyA+L2Rldi9udWxsICYmIGNobW9kIC1SIHUrdyAnIC4gUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHBhdGgpOwoKICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb2Nlc3NFcnJvciA9ICdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgIGlmICghY2xhc3NfZXhpc3RzKCdSYXJBcmNoaXZlJykpIHsKICAgICAgICAgICAgLy8gcGhwLmluaSBwYXRoIGlzIGFkZGVkIHRvIHRoZSBlcnJvciBtZXNzYWdlIHRvIGhlbHAgdXNlcnMgZmluZCB0aGUgY29ycmVjdCBmaWxlCiAgICAgICAgICAgICRpbmlNZXNzYWdlID0gSW5pSGVscGVyOjpnZXRNZXNzYWdlKCk7CgogICAgICAgICAgICAkZXJyb3IgPSAiQ291bGQgbm90IGRlY29tcHJlc3MgdGhlIGFyY2hpdmUsIGVuYWJsZSB0aGUgUEhQIHJhciBleHRlbnNpb24gb3IgaW5zdGFsbCB1bnJhci5cbiIKICAgICAgICAgICAgICAgIC4gJGluaU1lc3NhZ2UgLiAiXG4iIC4gJHByb2Nlc3NFcnJvcjsKCiAgICAgICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSAiQ291bGQgbm90IGRlY29tcHJlc3MgdGhlIGFyY2hpdmUsIGVuYWJsZSB0aGUgUEhQIHJhciBleHRlbnNpb24uXG4iIC4gJGluaU1lc3NhZ2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkZXJyb3IpOwogICAgICAgIH0KCiAgICAgICAgJHJhckFyY2hpdmUgPSBSYXJBcmNoaXZlOjpvcGVuKCRmaWxlKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmFyQXJjaGl2ZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignQ291bGQgbm90IG9wZW4gUkFSIGFyY2hpdmU6ICcgLiAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICAkZW50cmllcyA9ICRyYXJBcmNoaXZlLT5nZXRFbnRyaWVzKCk7CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGVudHJpZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgcmV0cmlldmUgUkFSIGFyY2hpdmUgZW50cmllcycpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGVudHJpZXMgYXMgJGVudHJ5KSB7CiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJGVudHJ5LT5leHRyYWN0KCRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgZXh0cmFjdCBlbnRyeScpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmFyQXJjaGl2ZS0+Y2xvc2UoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVyIGZvciB0YXIgZmlsZXM6IHRhciwgdGFyLmd6IG9yIHRhci5iejIKICoKICogQGF1dGhvciBLaXJpbGwgY2hFYmJhIENoZWJ1bmluIDxpYW1AY2hlYmJhLm9yZz4KICovCmNsYXNzIFRhckRvd25sb2FkZXIgZXh0ZW5kcyBBcmNoaXZlRG93bmxvYWRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKQogICAgewogICAgICAgIC8vIENhbiB0aHJvdyBhbiBVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KICAgICAgICAkYXJjaGl2ZSA9IG5ldyBcUGhhckRhdGEoJGZpbGUpOwogICAgICAgICRhcmNoaXZlLT5leHRyYWN0VG8oJHBhdGgsIG51bGwsIHRydWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcVXRpbFxQZXJmb3JjZTsKCi8qKgogKiBAYXV0aG9yIE1hdHQgV2hpdHRvbSA8TWF0dC5XaGl0dG9tQHZldGVyYW5zdW5pdGVkLmNvbT4KICovCmNsYXNzIFBlcmZvcmNlRG93bmxvYWRlciBleHRlbmRzIFZjc0Rvd25sb2FkZXIKewogICAgLyoqIEB2YXIgUGVyZm9yY2UgKi8KICAgIHByb3RlY3RlZCAkcGVyZm9yY2U7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0Rvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXJsLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgJHJlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAkbGFiZWwgPSAkdGhpcy0+Z2V0TGFiZWxGcm9tU291cmNlUmVmZXJlbmNlKCRyZWYpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0Nsb25pbmcgJyAuICRyZWYpOwogICAgICAgICR0aGlzLT5pbml0UGVyZm9yY2UoJHBhY2thZ2UsICRwYXRoLCAkdXJsKTsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPnNldFN0cmVhbSgkcmVmKTsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPnA0TG9naW4oKTsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPndyaXRlUDRDbGllbnRTcGVjKCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5jb25uZWN0Q2xpZW50KCk7CiAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5zeW5jQ29kZUJhc2UoJGxhYmVsKTsKICAgICAgICAkdGhpcy0+cGVyZm9yY2UtPmNsZWFudXBDbGllbnRTcGVjKCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRMYWJlbEZyb21Tb3VyY2VSZWZlcmVuY2UoJHJlZikKICAgIHsKICAgICAgICAkcG9zID0gc3RycG9zKCRyZWYsICdAJyk7CiAgICAgICAgaWYgKGZhbHNlICE9PSAkcG9zKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHJlZiwgJHBvcyArIDEpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGluaXRQZXJmb3JjZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5wZXJmb3JjZSkpIHsKICAgICAgICAgICAgJHRoaXMtPnBlcmZvcmNlLT5pbml0aWFsaXplUGF0aCgkcGF0aCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkcmVwb3NpdG9yeSA9ICRwYWNrYWdlLT5nZXRSZXBvc2l0b3J5KCk7CiAgICAgICAgJHJlcG9Db25maWcgPSBudWxsOwogICAgICAgIGlmICgkcmVwb3NpdG9yeSBpbnN0YW5jZW9mIFZjc1JlcG9zaXRvcnkpIHsKICAgICAgICAgICAgJHJlcG9Db25maWcgPSAkdGhpcy0+Z2V0UmVwb0NvbmZpZygkcmVwb3NpdG9yeSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5wZXJmb3JjZSA9IFBlcmZvcmNlOjpjcmVhdGUoJHJlcG9Db25maWcsICR1cmwsICRwYXRoLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmlvKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFJlcG9Db25maWcoVmNzUmVwb3NpdG9yeSAkcmVwb3NpdG9yeSkKICAgIHsKICAgICAgICByZXR1cm4gJHJlcG9zaXRvcnktPmdldFJlcG9Db25maWcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvVXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRvSW5zdGFsbCgkdGFyZ2V0LCAkcGF0aCwgJHVybCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdQZXJmb3JjZSBkcml2ZXIgZG9lcyBub3QgY2hlY2sgZm9yIGxvY2FsIGNoYW5nZXMgYmVmb3JlIG92ZXJyaWRpbmcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wZXJmb3JjZS0+Z2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGVyZm9yY2UoJHBlcmZvcmNlKQogICAgewogICAgICAgICR0aGlzLT5wZXJmb3JjZSA9ICRwZXJmb3JjZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcRXhjZXB0aW9uXElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVycyBtYW5hZ2VyLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KY2xhc3MgRG93bmxvYWRNYW5hZ2VyCnsKICAgIC8qKiBAdmFyIElPSW50ZXJmYWNlICovCiAgICBwcml2YXRlICRpbzsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJHByZWZlckRpc3QgPSBmYWxzZTsKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJHByZWZlclNvdXJjZTsKICAgIC8qKiBAdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPiAqLwogICAgcHJpdmF0ZSAkcGFja2FnZVByZWZlcmVuY2VzID0gYXJyYXkoKTsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByaXZhdGUgJGZpbGVzeXN0ZW07CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIERvd25sb2FkZXJJbnRlcmZhY2U+ICovCiAgICBwcml2YXRlICRkb3dubG9hZGVycyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBkb3dubG9hZCBtYW5hZ2VyLgogICAgICoKICAgICAqIEBwYXJhbSBJT0ludGVyZmFjZSAgICAgJGlvICAgICAgICAgICBUaGUgSW5wdXQgT3V0cHV0IEludGVyZmFjZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAkcHJlZmVyU291cmNlIHByZWZlciBkb3dubG9hZGluZyBmcm9tIHNvdXJjZQogICAgICogQHBhcmFtIEZpbGVzeXN0ZW18bnVsbCAkZmlsZXN5c3RlbSAgIGN1c3RvbSBGaWxlc3lzdGVtIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCAkcHJlZmVyU291cmNlID0gZmFsc2UsIEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+cHJlZmVyU291cmNlID0gJHByZWZlclNvdXJjZTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbSA9ICRmaWxlc3lzdGVtID86IG5ldyBGaWxlc3lzdGVtKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBkb3dubG9hZGVyIHByZWZlciBzb3VyY2UgaW5zdGFsbGF0aW9uIG92ZXIgdGhlIGRpc3QuCiAgICAgKgogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgJHByZWZlclNvdXJjZSBwcmVmZXIgZG93bmxvYWRpbmcgZnJvbSBzb3VyY2UKICAgICAqIEByZXR1cm4gRG93bmxvYWRNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJTb3VyY2UoJHByZWZlclNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZmVyU291cmNlID0gJHByZWZlclNvdXJjZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogTWFrZXMgZG93bmxvYWRlciBwcmVmZXIgZGlzdCBpbnN0YWxsYXRpb24gb3ZlciB0aGUgc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICRwcmVmZXJEaXN0IHByZWZlciBkb3dubG9hZGluZyBmcm9tIGRpc3QKICAgICAqIEByZXR1cm4gRG93bmxvYWRNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmZXJEaXN0KCRwcmVmZXJEaXN0KQogICAgewogICAgICAgICR0aGlzLT5wcmVmZXJEaXN0ID0gJHByZWZlckRpc3Q7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgZmluZSB0dW5lZCBwcmVmZXJlbmNlIHNldHRpbmdzIGZvciBwYWNrYWdlIGxldmVsIHNvdXJjZS9kaXN0IHNlbGVjdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgICAkcHJlZmVyZW5jZXMgYXJyYXkgb2YgcHJlZmVyZW5jZXMgYnkgcGFja2FnZSBwYXR0ZXJucwogICAgICogQHJldHVybiBEb3dubG9hZE1hbmFnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZlcmVuY2VzKGFycmF5ICRwcmVmZXJlbmNlcykKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZVByZWZlcmVuY2VzID0gJHByZWZlcmVuY2VzOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGluc3RhbGxlciBkb3dubG9hZGVyIGZvciBhIHNwZWNpZmljIGluc3RhbGxhdGlvbiB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAkdHlwZSAgICAgICBpbnN0YWxsYXRpb24gdHlwZQogICAgICogQHBhcmFtICBEb3dubG9hZGVySW50ZXJmYWNlICRkb3dubG9hZGVyIGRvd25sb2FkZXIgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gRG93bmxvYWRNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREb3dubG9hZGVyKCR0eXBlLCBEb3dubG9hZGVySW50ZXJmYWNlICRkb3dubG9hZGVyKQogICAgewogICAgICAgICR0eXBlID0gc3RydG9sb3dlcigkdHlwZSk7CiAgICAgICAgJHRoaXMtPmRvd25sb2FkZXJzWyR0eXBlXSA9ICRkb3dubG9hZGVyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGRvd25sb2FkZXIgZm9yIGEgc3BlY2lmaWMgaW5zdGFsbGF0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgICAgICR0eXBlIGluc3RhbGxhdGlvbiB0eXBlCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgZG93bmxvYWRlciBmb3IgcHJvdmlkZWQgdHlwZSBpcyBub3QgcmVnaXN0ZXJlZAogICAgICogQHJldHVybiBEb3dubG9hZGVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREb3dubG9hZGVyKCR0eXBlKQogICAgewogICAgICAgICR0eXBlID0gc3RydG9sb3dlcigkdHlwZSk7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+ZG93bmxvYWRlcnNbJHR5cGVdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdVbmtub3duIGRvd25sb2FkZXIgdHlwZTogJXMuIEF2YWlsYWJsZSB0eXBlczogJXMuJywgJHR5cGUsIGltcGxvZGUoJywgJywgYXJyYXlfa2V5cygkdGhpcy0+ZG93bmxvYWRlcnMpKSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kb3dubG9hZGVyc1skdHlwZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGRvd25sb2FkZXIgZm9yIGFscmVhZHkgaW5zdGFsbGVkIHBhY2thZ2UuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAgICAgICAgICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiBwYWNrYWdlIGhhcyBubyBpbnN0YWxsYXRpb24gc291cmNlIHNwZWNpZmllZAogICAgICogQHRocm93cyBcTG9naWNFeGNlcHRpb24gICAgICAgICAgIGlmIHNwZWNpZmljIGRvd25sb2FkZXIgdXNlZCB0byBsb2FkIHBhY2thZ2Ugd2l0aAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JvbmcgdHlwZQogICAgICogQHJldHVybiBEb3dubG9hZGVySW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERvd25sb2FkZXJGb3JQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJGluc3RhbGxhdGlvblNvdXJjZSA9ICRwYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKTsKCiAgICAgICAgaWYgKCdtZXRhcGFja2FnZScgPT09ICRwYWNrYWdlLT5nZXRUeXBlKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdkaXN0JyA9PT0gJGluc3RhbGxhdGlvblNvdXJjZSkgewogICAgICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzLT5nZXREb3dubG9hZGVyKCRwYWNrYWdlLT5nZXREaXN0VHlwZSgpKTsKICAgICAgICB9IGVsc2VpZiAoJ3NvdXJjZScgPT09ICRpbnN0YWxsYXRpb25Tb3VyY2UpIHsKICAgICAgICAgICAgJGRvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlcigkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICdQYWNrYWdlICcuJHBhY2thZ2UuJyBkb2VzIG5vdCBoYXZlIGFuIGluc3RhbGxhdGlvbiBzb3VyY2Ugc2V0JwogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnN0YWxsYXRpb25Tb3VyY2UgIT09ICRkb3dubG9hZGVyLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnRG93bmxvYWRlciAiJXMiIGlzIGEgJXMgdHlwZSBkb3dubG9hZGVyIGFuZCBjYW4gbm90IGJlIHVzZWQgdG8gZG93bmxvYWQgJXMgZm9yIHBhY2thZ2UgJXMnLAogICAgICAgICAgICAgICAgZ2V0X2NsYXNzKCRkb3dubG9hZGVyKSwKICAgICAgICAgICAgICAgICRkb3dubG9hZGVyLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSwKICAgICAgICAgICAgICAgICRpbnN0YWxsYXRpb25Tb3VyY2UsCiAgICAgICAgICAgICAgICAkcGFja2FnZQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZG93bmxvYWRlcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RG93bmxvYWRlclR5cGUoRG93bmxvYWRlckludGVyZmFjZSAkZG93bmxvYWRlcikKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfc2VhcmNoKCRkb3dubG9hZGVyLCAkdGhpcy0+ZG93bmxvYWRlcnMpOwogICAgfQoKICAgIC8qKgogICAgICogRG93bmxvYWRzIHBhY2thZ2UgaW50byB0YXJnZXQgZGlyLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgICAgIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJHRhcmdldERpciAgIHRhcmdldCBkaXIKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlfG51bGwgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiB1cGRhdGVzCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBhY2thZ2UgaGF2ZSBubyB1cmxzIHRvIGRvd25sb2FkIGZyb20KICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHRhcmdldERpciwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSAkdGhpcy0+bm9ybWFsaXplVGFyZ2V0RGlyKCR0YXJnZXREaXIpOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoZGlybmFtZSgkdGFyZ2V0RGlyKSk7CgogICAgICAgICRzb3VyY2VzID0gJHRoaXMtPmdldEF2YWlsYWJsZVNvdXJjZXMoJHBhY2thZ2UsICRwcmV2UGFja2FnZSk7CgogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAkZG93bmxvYWQgPSBmdW5jdGlvbiAoJHJldHJ5ID0gZmFsc2UpIHVzZSAoJiRzb3VyY2VzLCAkaW8sICRwYWNrYWdlLCAkc2VsZiwgJHRhcmdldERpciwgJiRkb3dubG9hZCwgJHByZXZQYWNrYWdlKSB7CiAgICAgICAgICAgICRzb3VyY2UgPSBhcnJheV9zaGlmdCgkc291cmNlcyk7CiAgICAgICAgICAgIGlmICgkcmV0cnkpIHsKICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPk5vdyB0cnlpbmcgdG8gZG93bmxvYWQgZnJvbSAnIC4gJHNvdXJjZSAuICc8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhY2thZ2UtPnNldEluc3RhbGxhdGlvblNvdXJjZSgkc291cmNlKTsKCiAgICAgICAgICAgICRkb3dubG9hZGVyID0gJHNlbGYtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICAgICAgaWYgKCEkZG93bmxvYWRlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGhhbmRsZUVycm9yID0gZnVuY3Rpb24gKCRlKSB1c2UgKCRzb3VyY2VzLCAkc291cmNlLCAkcGFja2FnZSwgJGlvLCAkZG93bmxvYWQpIHsKICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFxSdW50aW1lRXhjZXB0aW9uICYmICEkZSBpbnN0YW5jZW9mIElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIGlmICghJHNvdXJjZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgPHdhcm5pbmc+RmFpbGVkIHRvIGRvd25sb2FkICcuCiAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuCiAgICAgICAgICAgICAgICAgICAgICAgICcgZnJvbSAnIC4gJHNvdXJjZSAuICc6ICcuCiAgICAgICAgICAgICAgICAgICAgICAgICRlLT5nZXRNZXNzYWdlKCkuJzwvd2FybmluZz4nCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZCh0cnVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJGRvd25sb2FkZXItPmRvd25sb2FkKCRwYWNrYWdlLCAkdGFyZ2V0RGlyLCAkcHJldlBhY2thZ2UpOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGhhbmRsZUVycm9yKCRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgkcmVzdWx0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlcyA9ICRyZXN1bHQtPnRoZW4oZnVuY3Rpb24gKCRyZXMpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9LCAkaGFuZGxlRXJyb3IpOwoKICAgICAgICAgICAgcmV0dXJuICRyZXM7CiAgICAgICAgfTsKCiAgICAgICAgcmV0dXJuICRkb3dubG9hZCgpOwogICAgfQoKICAgIC8qKgogICAgICogUHJlcGFyZXMgYW4gb3BlcmF0aW9uIGV4ZWN1dGlvbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJHR5cGUgICAgICAgIG9uZSBvZiBpbnN0YWxsL3VwZGF0ZS91bmluc3RhbGwKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICAgICAgJHBhY2thZ2UgICAgIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgJHRhcmdldERpciAgIHRhcmdldCBkaXIKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlfG51bGwgJHByZXZQYWNrYWdlIHByZXZpb3VzIHBhY2thZ2UgaW5zdGFuY2UgaW4gY2FzZSBvZiB1cGRhdGVzCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICR0YXJnZXREaXIsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGFyZ2V0RGlyID0gJHRoaXMtPm5vcm1hbGl6ZVRhcmdldERpcigkdGFyZ2V0RGlyKTsKICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzLT5nZXREb3dubG9hZGVyRm9yUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgaWYgKCRkb3dubG9hZGVyKSB7CiAgICAgICAgICAgIHJldHVybiAkZG93bmxvYWRlci0+cHJlcGFyZSgkdHlwZSwgJHBhY2thZ2UsICR0YXJnZXREaXIsICRwcmV2UGFja2FnZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5zdGFsbHMgcGFja2FnZSBpbnRvIHRhcmdldCBkaXIuCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdGFyZ2V0RGlyIHRhcmdldCBkaXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgcGFja2FnZSBoYXZlIG5vIHVybHMgdG8gZG93bmxvYWQgZnJvbQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHRhcmdldERpcikKICAgIHsKICAgICAgICAkdGFyZ2V0RGlyID0gJHRoaXMtPm5vcm1hbGl6ZVRhcmdldERpcigkdGFyZ2V0RGlyKTsKICAgICAgICAkZG93bmxvYWRlciA9ICR0aGlzLT5nZXREb3dubG9hZGVyRm9yUGFja2FnZSgkcGFja2FnZSk7CiAgICAgICAgaWYgKCRkb3dubG9hZGVyKSB7CiAgICAgICAgICAgIHJldHVybiAkZG93bmxvYWRlci0+aW5zdGFsbCgkcGFja2FnZSwgJHRhcmdldERpcik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVXBkYXRlcyBwYWNrYWdlIGZyb20gaW5pdGlhbCB0byB0YXJnZXQgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCAgIGluaXRpYWwgcGFja2FnZSB2ZXJzaW9uCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0ICAgIHRhcmdldCBwYWNrYWdlIHZlcnNpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR0YXJnZXREaXIgdGFyZ2V0IGRpcgogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiBpbml0aWFsIHBhY2thZ2UgaXMgbm90IGluc3RhbGxlZAogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICR0YXJnZXREaXIpCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9ICR0aGlzLT5ub3JtYWxpemVUYXJnZXREaXIoJHRhcmdldERpcik7CiAgICAgICAgJGRvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJHRhcmdldCk7CiAgICAgICAgJGluaXRpYWxEb3dubG9hZGVyID0gJHRoaXMtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRpbml0aWFsKTsKCiAgICAgICAgLy8gbm8gZG93bmxvYWRlcnMgcHJlc2VudCBtZWFucyB1cGRhdGUgZnJvbSBtZXRhcGFja2FnZSB0byBtZXRhcGFja2FnZSwgbm90aGluZyB0byBkbwogICAgICAgIGlmICghJGluaXRpYWxEb3dubG9hZGVyICYmICEkZG93bmxvYWRlcikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSBoYXZlIGEgZG93bmxvYWRlciBwcmVzZW50IGJlZm9yZSwgYnV0IG5vdCBhZnRlciwgdGhlIHBhY2thZ2UgYmVjYW1lIGEgbWV0YXBhY2thZ2UgYW5kIGl0cyBmaWxlcyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgIGlmICghJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRpbml0aWFsRG93bmxvYWRlci0+cmVtb3ZlKCRpbml0aWFsLCAkdGFyZ2V0RGlyKTsKICAgICAgICB9CgogICAgICAgICRpbml0aWFsVHlwZSA9ICR0aGlzLT5nZXREb3dubG9hZGVyVHlwZSgkaW5pdGlhbERvd25sb2FkZXIpOwogICAgICAgICR0YXJnZXRUeXBlID0gJHRoaXMtPmdldERvd25sb2FkZXJUeXBlKCRkb3dubG9hZGVyKTsKICAgICAgICBpZiAoJGluaXRpYWxUeXBlID09PSAkdGFyZ2V0VHlwZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT51cGRhdGUoJGluaXRpYWwsICR0YXJnZXQsICR0YXJnZXREaXIpOwogICAgICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8ZXJyb3I+ICAgIFVwZGF0ZSBmYWlsZWQgKCcuJGUtPmdldE1lc3NhZ2UoKS4nKTwvZXJyb3I+Jyk7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5pby0+YXNrQ29uZmlybWF0aW9uKCcgICAgV291bGQgeW91IGxpa2UgdG8gdHJ5IHJlaW5zdGFsbGluZyB0aGUgcGFja2FnZSBpbnN0ZWFkIFs8Y29tbWVudD55ZXM8L2NvbW1lbnQ+XT8gJykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaWYgZG93bmxvYWRlciB0eXBlIGNoYW5nZWQsIG9yIHVwZGF0ZSBmYWlsZWQgYW5kIHVzZXIgYXNrcyBmb3IgcmVpbnN0YWxsLAogICAgICAgIC8vIHdlIHdpcGUgdGhlIGRpciBhbmQgZG8gYSBuZXcgaW5zdGFsbCBpbnN0ZWFkIG9mIHVwZGF0aW5nIGl0CiAgICAgICAgJHByb21pc2UgPSAkaW5pdGlhbERvd25sb2FkZXItPnJlbW92ZSgkaW5pdGlhbCwgJHRhcmdldERpcik7CiAgICAgICAgaWYgKCRwcm9taXNlKSB7CiAgICAgICAgICAgICRzZWxmID0gJHRoaXM7CgogICAgICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCRyZXMpIHVzZSAoJHNlbGYsICR0YXJnZXQsICR0YXJnZXREaXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkc2VsZi0+aW5zdGFsbCgkdGFyZ2V0LCAkdGFyZ2V0RGlyKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmluc3RhbGwoJHRhcmdldCwgJHRhcmdldERpcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIHBhY2thZ2UgZnJvbSB0YXJnZXQgZGlyLgogICAgICoKICAgICAqIEBwYXJhbSBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICAgcGFja2FnZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJHRhcmdldERpciB0YXJnZXQgZGlyCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSAkdGhpcy0+bm9ybWFsaXplVGFyZ2V0RGlyKCR0YXJnZXREaXIpOwogICAgICAgICRkb3dubG9hZGVyID0gJHRoaXMtPmdldERvd25sb2FkZXJGb3JQYWNrYWdlKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJGRvd25sb2FkZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZGVyLT5yZW1vdmUoJHBhY2thZ2UsICR0YXJnZXREaXIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsZWFucyB1cCBhIGZhaWxlZCBvcGVyYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR0eXBlICAgICAgICBvbmUgb2YgaW5zdGFsbC91cGRhdGUvdW5pbnN0YWxsCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR0YXJnZXREaXIgICB0YXJnZXQgZGlyCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZXxudWxsICRwcmV2UGFja2FnZSBwcmV2aW91cyBwYWNrYWdlIGluc3RhbmNlIGluIGNhc2Ugb2YgdXBkYXRlcwogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkdGFyZ2V0RGlyLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRhcmdldERpciA9ICR0aGlzLT5ub3JtYWxpemVUYXJnZXREaXIoJHRhcmdldERpcik7CiAgICAgICAgJGRvd25sb2FkZXIgPSAkdGhpcy0+Z2V0RG93bmxvYWRlckZvclBhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgIGlmICgkZG93bmxvYWRlcikgewogICAgICAgICAgICByZXR1cm4gJGRvd25sb2FkZXItPmNsZWFudXAoJHR5cGUsICRwYWNrYWdlLCAkdGFyZ2V0RGlyLCAkcHJldlBhY2thZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZXMgdGhlIGluc3RhbGwgcHJlZmVyZW5jZSBvZiBhIHBhY2thZ2UKICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlc29sdmVQYWNrYWdlSW5zdGFsbFByZWZlcmVuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZVByZWZlcmVuY2VzIGFzICRwYXR0ZXJuID0+ICRwcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICRwYXR0ZXJuID0gJ3teJy5zdHJfcmVwbGFjZSgnXFwqJywgJy4qJywgcHJlZ19xdW90ZSgkcGF0dGVybikpLickfWknOwogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcGF0dGVybiwgJHBhY2thZ2UtPmdldE5hbWUoKSkpIHsKICAgICAgICAgICAgICAgIGlmICgnZGlzdCcgPT09ICRwcmVmZXJlbmNlIHx8ICghJHBhY2thZ2UtPmlzRGV2KCkgJiYgJ2F1dG8nID09PSAkcHJlZmVyZW5jZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2Rpc3QnOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnc291cmNlJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlLT5pc0RldigpID8gJ3NvdXJjZScgOiAnZGlzdCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0QXZhaWxhYmxlU291cmNlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHNvdXJjZVR5cGUgPSAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpOwogICAgICAgICRkaXN0VHlwZSA9ICRwYWNrYWdlLT5nZXREaXN0VHlwZSgpOwoKICAgICAgICAvLyBhZGQgc291cmNlIGJlZm9yZSBkaXN0IGJ5IGRlZmF1bHQKICAgICAgICAkc291cmNlcyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCRzb3VyY2VUeXBlKSB7CiAgICAgICAgICAgICRzb3VyY2VzW10gPSAnc291cmNlJzsKICAgICAgICB9CiAgICAgICAgaWYgKCRkaXN0VHlwZSkgewogICAgICAgICAgICAkc291cmNlc1tdID0gJ2Rpc3QnOwogICAgICAgIH0KCiAgICAgICAgaWYgKGVtcHR5KCRzb3VyY2VzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnLiRwYWNrYWdlLicgbXVzdCBoYXZlIGEgc291cmNlIG9yIGRpc3Qgc3BlY2lmaWVkJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoCiAgICAgICAgICAgICRwcmV2UGFja2FnZQogICAgICAgICAgICAvLyBpZiB3ZSBhcmUgdXBkYXRpbmcsIHdlIHdhbnQgdG8ga2VlcCB0aGUgc2FtZSBzb3VyY2UgYXMgdGhlIHByZXZpb3VzbHkgaW5zdGFsbGVkIHBhY2thZ2UgKGlmIGF2YWlsYWJsZSBpbiB0aGUgbmV3IG9uZSkKICAgICAgICAgICAgJiYgaW5fYXJyYXkoJHByZXZQYWNrYWdlLT5nZXRJbnN0YWxsYXRpb25Tb3VyY2UoKSwgJHNvdXJjZXMsIHRydWUpCiAgICAgICAgICAgIC8vIHVubGVzcyB0aGUgcHJldmlvdXMgcGFja2FnZSB3YXMgc3RhYmxlIGRpc3QgKGJ5IGRlZmF1bHQpIGFuZCB0aGUgbmV3IHBhY2thZ2UgaXMgZGV2LCB0aGVuIHdlIGFsbG93IHRoZSBuZXcgZGVmYXVsdCB0byB0YWtlIG92ZXIKICAgICAgICAgICAgJiYgISghJHByZXZQYWNrYWdlLT5pc0RldigpICYmICRwcmV2UGFja2FnZS0+Z2V0SW5zdGFsbGF0aW9uU291cmNlKCkgPT09ICdkaXN0JyAmJiAkcGFja2FnZS0+aXNEZXYoKSkKICAgICAgICApIHsKICAgICAgICAgICAgJHByZXZTb3VyY2UgPSAkcHJldlBhY2thZ2UtPmdldEluc3RhbGxhdGlvblNvdXJjZSgpOwogICAgICAgICAgICB1c29ydCgkc291cmNlcywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcHJldlNvdXJjZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhID09PSAkcHJldlNvdXJjZSA/IC0xIDogMTsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gJHNvdXJjZXM7CiAgICAgICAgfQoKICAgICAgICAvLyByZXZlcnNlIHNvdXJjZXMgaW4gY2FzZSBkaXN0IGlzIHRoZSBwcmVmZXJyZWQgc291cmNlIGZvciB0aGlzIHBhY2thZ2UKICAgICAgICBpZiAoISR0aGlzLT5wcmVmZXJTb3VyY2UgJiYgKCR0aGlzLT5wcmVmZXJEaXN0IHx8ICdkaXN0JyA9PT0gJHRoaXMtPnJlc29sdmVQYWNrYWdlSW5zdGFsbFByZWZlcmVuY2UoJHBhY2thZ2UpKSkgewogICAgICAgICAgICAkc291cmNlcyA9IGFycmF5X3JldmVyc2UoJHNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzb3VyY2VzOwogICAgfQoKICAgIC8qKgogICAgICogRG93bmxvYWRlcnMgZXhwZWN0IGEgL3BhdGgvdG8vZGlyIHdpdGhvdXQgdHJhaWxpbmcgc2xhc2gKICAgICAqCiAgICAgKiBJZiBhbnkgSW5zdGFsbGVyIHByb3ZpZGVzIGEgcGF0aCB3aXRoIGEgdHJhaWxpbmcgc2xhc2gsIHRoaXMgY2FuIGNhdXNlIGJ1Z3Mgc28gbWFrZSBzdXJlIHdlIHJlbW92ZSB0aGVtCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBub3JtYWxpemVUYXJnZXREaXIoJGRpcikKICAgIHsKICAgICAgICBpZiAoJGRpciA9PT0gJ1xcJyB8fCAkZGlyID09PSAnLycpIHsKICAgICAgICAgICAgcmV0dXJuICRkaXI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcnRyaW0oJGRpciwgJ1xcLycpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEZpbmRlcjsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKCi8qKgogKiBCYXNlIGRvd25sb2FkZXIgZm9yIGFyY2hpdmVzCiAqCiAqIEBhdXRob3IgS2lyaWxsIGNoRWJiYSBDaGVidW5pbiA8aWFtQGNoZWJiYS5vcmc+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICogQGF1dGhvciBGcmFuw6dvaXMgUGx1Y2hpbm8gPGZyYW5jb2lzLnBsdWNoaW5vQG9wZW5kaXNwbGF5LmNvbT4KICovCmFic3RyYWN0IGNsYXNzIEFyY2hpdmVEb3dubG9hZGVyIGV4dGVuZHMgRmlsZURvd25sb2FkZXIKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBJbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpLiI6IEV4dHJhY3RpbmcgYXJjaGl2ZSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignRXh0cmFjdGluZyBhcmNoaXZlJywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJHZlbmRvckRpciA9ICR0aGlzLT5jb25maWctPmdldCgndmVuZG9yLWRpcicpOwoKICAgICAgICAvLyBjbGVhbiB1cCB0aGUgdGFyZ2V0IGRpcmVjdG9yeSwgdW5sZXNzIGl0IGNvbnRhaW5zIHRoZSB2ZW5kb3IgZGlyLCBhcyB0aGUgdmVuZG9yIGRpciBjb250YWlucwogICAgICAgIC8vIHRoZSBhcmNoaXZlIHRvIGJlIGV4dHJhY3RlZC4gVGhpcyBpcyB0aGUgY2FzZSB3aGVuIGluc3RhbGxpbmcgd2l0aCBjcmVhdGUtcHJvamVjdCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkKICAgICAgICAvLyBidXQgaW4gdGhhdCBjYXNlIHdlIGVuc3VyZSB0aGUgZGlyZWN0b3J5IGlzIGVtcHR5IGFscmVhZHkgaW4gUHJvamVjdEluc3RhbGxlciBzbyBubyBuZWVkIHRvIGVtcHR5IGl0IGhlcmUuCiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJHRoaXMtPmZpbGVzeXN0ZW0tPm5vcm1hbGl6ZVBhdGgoJHZlbmRvckRpciksICR0aGlzLT5maWxlc3lzdGVtLT5ub3JtYWxpemVQYXRoKCRwYXRoLkRJUkVDVE9SWV9TRVBBUkFUT1IpKSkgewogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW1wdHlEaXJlY3RvcnkoJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgZG8gewogICAgICAgICAgICAkdGVtcG9yYXJ5RGlyID0gJHZlbmRvckRpci4nL2NvbXBvc2VyLycuc3Vic3RyKG1kNSh1bmlxaWQoJycsIHRydWUpKSwgMCwgOCk7CiAgICAgICAgfSB3aGlsZSAoaXNfZGlyKCR0ZW1wb3JhcnlEaXIpKTsKCiAgICAgICAgJHRoaXMtPmFkZENsZWFudXBQYXRoKCRwYWNrYWdlLCAkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAvLyBhdm9pZCBjbGVhbmluZyB1cCAkcGF0aCBpZiBpbnN0YWxsaW5nIGluICIuIiBmb3IgZWcgY3JlYXRlLXByb2plY3QgYXMgd2UgY2FuIG5vdAogICAgICAgIC8vIGRlbGV0ZSB0aGUgZGlyZWN0b3J5IHdlIGFyZSBjdXJyZW50bHkgaW4gb24gd2luZG93cwogICAgICAgIGlmICghaXNfZGlyKCRwYXRoKSB8fCByZWFscGF0aCgkcGF0aCkgIT09IGdldGN3ZCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRDbGVhbnVwUGF0aCgkcGFja2FnZSwgJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cygkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAkZmlsZU5hbWUgPSAkdGhpcy0+Z2V0RmlsZU5hbWUoJHBhY2thZ2UsICRwYXRoKTsKCiAgICAgICAgJGZpbGVzeXN0ZW0gPSAkdGhpcy0+ZmlsZXN5c3RlbTsKICAgICAgICAkc2VsZiA9ICR0aGlzOwoKICAgICAgICAkY2xlYW51cCA9IGZ1bmN0aW9uICgpIHVzZSAoJHBhdGgsICRmaWxlc3lzdGVtLCAkdGVtcG9yYXJ5RGlyLCAkcGFja2FnZSwgJHNlbGYpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIGNhY2hlIGlmIHRoZSBmaWxlIHdhcyBjb3JydXB0ZWQKICAgICAgICAgICAgJHNlbGYtPmNsZWFyTGFzdENhY2hlV3JpdGUoJHBhY2thZ2UpOwoKICAgICAgICAgICAgLy8gY2xlYW4gdXAKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkgJiYgcmVhbHBhdGgoJHBhdGgpICE9PSBnZXRjd2QoKSkgewogICAgICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNlbGYtPnJlbW92ZUNsZWFudXBQYXRoKCRwYWNrYWdlLCAkdGVtcG9yYXJ5RGlyKTsKICAgICAgICAgICAgJHNlbGYtPnJlbW92ZUNsZWFudXBQYXRoKCRwYWNrYWdlLCByZWFscGF0aCgkcGF0aCkpOwogICAgICAgIH07CgogICAgICAgICRwcm9taXNlID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICAkcHJvbWlzZSA9ICR0aGlzLT5leHRyYWN0KCRwYWNrYWdlLCAkZmlsZU5hbWUsICR0ZW1wb3JhcnlEaXIpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGNsZWFudXAoKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgICAgICAkcHJvbWlzZSA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCRzZWxmLCAkcGFja2FnZSwgJGZpbGVzeXN0ZW0sICRmaWxlTmFtZSwgJHRlbXBvcmFyeURpciwgJHBhdGgpIHsKICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnVubGluaygkZmlsZU5hbWUpOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJldHVybnMgdGhlIGZvbGRlciBjb250ZW50LCBleGNsdWRpbmcgLkRTX1N0b3JlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgJGRpciBEaXJlY3RvcnkKICAgICAgICAgICAgICogQHJldHVybiBcU3BsRmlsZUluZm9bXQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgJGdldEZvbGRlckNvbnRlbnQgPSBmdW5jdGlvbiAoJGRpcikgewogICAgICAgICAgICAgICAgJGZpbmRlciA9IEZpbmRlcjo6Y3JlYXRlKCkKICAgICAgICAgICAgICAgICAgICAtPmlnbm9yZVZDUyhmYWxzZSkKICAgICAgICAgICAgICAgICAgICAtPmlnbm9yZURvdEZpbGVzKGZhbHNlKQogICAgICAgICAgICAgICAgICAgIC0+bm90TmFtZSgnLkRTX1N0b3JlJykKICAgICAgICAgICAgICAgICAgICAtPmRlcHRoKDApCiAgICAgICAgICAgICAgICAgICAgLT5pbigkZGlyKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JfdG9fYXJyYXkoJGZpbmRlcik7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgICRyZW5hbWVSZWN1cnNpdmVseSA9IG51bGw7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZW5hbWVzIChhbmQgcmVjdXJzaXZlbHkgbWVyZ2VzIGlmIG5lZWRlZCkgYSBmb2xkZXIgaW50byBhbm90aGVyIG9uZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBGb3IgY3VzdG9tIGluc3RhbGxlcnMsIHdoZXJlIHBhY2thZ2VzIG1heSBzaGFyZSBwYXRocywgYW5kIGdpdmVuIENvbXBvc2VyIDIncyBwYXJhbGxlbGlzbSwgd2UgbmVlZCB0byBtYWtlIHN1cmUKICAgICAgICAgICAgICogdGhhdCB0aGUgc291cmNlIGRpcmVjdG9yeSBnZXRzIG1lcmdlZCBpbnRvIHRoZSB0YXJnZXQgb25lIGlmIHRoZSB0YXJnZXQgZXhpc3RzLiBPdGhlcndpc2UgcmVuYW1lKCkgYnkgZGVmYXVsdCB3b3VsZAogICAgICAgICAgICAgKiBwdXQgdGhlIHNvdXJjZSBpbnRvIHRoZSB0YXJnZXQgZS5nLiBzcmMvID0+IHRhcmdldC9zcmMvIChhc3N1bWluZyB0YXJnZXQgZXhpc3RzKSBpbnN0ZWFkIG9mIHNyYy8gPT4gdGFyZ2V0LwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0gc3RyaW5nICRmcm9tIERpcmVjdG9yeQogICAgICAgICAgICAgKiBAcGFyYW0gc3RyaW5nICR0byBEaXJlY3RvcnkKICAgICAgICAgICAgICogQHJldHVybiB2b2lkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAkcmVuYW1lUmVjdXJzaXZlbHkgPSBmdW5jdGlvbiAoJGZyb20sICR0bykgdXNlICgkZmlsZXN5c3RlbSwgJGdldEZvbGRlckNvbnRlbnQsICRwYWNrYWdlLCAmJHJlbmFtZVJlY3Vyc2l2ZWx5KSB7CiAgICAgICAgICAgICAgICAkY29udGVudERpciA9ICRnZXRGb2xkZXJDb250ZW50KCRmcm9tKTsKCiAgICAgICAgICAgICAgICAvLyBtb3ZlIGZpbGVzIGJhY2sgb3V0IG9mIHRoZSB0ZW1wIGRpcgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnRlbnREaXIgYXMgJGZpbGUpIHsKICAgICAgICAgICAgICAgICAgICAkZmlsZSA9IChzdHJpbmcpICRmaWxlOwogICAgICAgICAgICAgICAgICAgIGlmIChpc19kaXIoJHRvIC4gJy8nIC4gYmFzZW5hbWUoJGZpbGUpKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzX2RpcigkZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignSW5zdGFsbGluZyAnLiRwYWNrYWdlLicgd291bGQgbGVhZCB0byBvdmVyd3JpdGluZyB0aGUgJy4kdG8uJy8nLmJhc2VuYW1lKCRmaWxlKS4nIGRpcmVjdG9yeSB3aXRoIGEgZmlsZSBmcm9tIHRoZSBwYWNrYWdlLCBpbnZhbGlkIG9wZXJhdGlvbi4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkcmVuYW1lUmVjdXJzaXZlbHkoJGZpbGUsICR0byAuICcvJyAuIGJhc2VuYW1lKCRmaWxlKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnJlbmFtZSgkZmlsZSwgJHRvIC4gJy8nIC4gYmFzZW5hbWUoJGZpbGUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAkcmVuYW1lQXNPbmUgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkcGF0aCkgfHwgKCRmaWxlc3lzdGVtLT5pc0RpckVtcHR5KCRwYXRoKSAmJiAkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRwYXRoKSkpIHsKICAgICAgICAgICAgICAgICRyZW5hbWVBc09uZSA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb250ZW50RGlyID0gJGdldEZvbGRlckNvbnRlbnQoJHRlbXBvcmFyeURpcik7CiAgICAgICAgICAgICRzaW5nbGVEaXJBdFRvcExldmVsID0gMSA9PT0gY291bnQoJGNvbnRlbnREaXIpICYmIGlzX2RpcihyZXNldCgkY29udGVudERpcikpOwoKICAgICAgICAgICAgaWYgKCRyZW5hbWVBc09uZSkgewogICAgICAgICAgICAgICAgLy8gaWYgdGhlIHRhcmdldCAkcGF0aCBpcyBjbGVhciwgd2UgY2FuIHJlbmFtZSB0aGUgd2hvbGUgcGFja2FnZSBpbiBvbmUgZ28gaW5zdGVhZCBvZiBsb29waW5nIG92ZXIgdGhlIGNvbnRlbnRzCiAgICAgICAgICAgICAgICBpZiAoJHNpbmdsZURpckF0VG9wTGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICAkZXh0cmFjdGVkRGlyID0gKHN0cmluZykgcmVzZXQoJGNvbnRlbnREaXIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZXh0cmFjdGVkRGlyID0gJHRlbXBvcmFyeURpcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRmaWxlc3lzdGVtLT5yZW5hbWUoJGV4dHJhY3RlZERpciwgJHBhdGgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gb25seSBvbmUgZGlyIGluIHRoZSBhcmNoaXZlLCBleHRyYWN0IGl0cyBjb250ZW50cyBvdXQgb2YgaXQKICAgICAgICAgICAgICAgICRmcm9tID0gJHRlbXBvcmFyeURpcjsKICAgICAgICAgICAgICAgIGlmICgkc2luZ2xlRGlyQXRUb3BMZXZlbCkgewogICAgICAgICAgICAgICAgICAgICRmcm9tID0gKHN0cmluZykgcmVzZXQoJGNvbnRlbnREaXIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZW5hbWVSZWN1cnNpdmVseSgkZnJvbSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCR0ZW1wb3JhcnlEaXIpOwogICAgICAgICAgICAkc2VsZi0+cmVtb3ZlQ2xlYW51cFBhdGgoJHBhY2thZ2UsICR0ZW1wb3JhcnlEaXIpOwogICAgICAgICAgICAkc2VsZi0+cmVtb3ZlQ2xlYW51cFBhdGgoJHBhY2thZ2UsICRwYXRoKTsKICAgICAgICB9LCBmdW5jdGlvbiAoJGUpIHVzZSAoJGNsZWFudXApIHsKICAgICAgICAgICAgJGNsZWFudXAoKTsKCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCBmaWxlIHRvIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgRXh0cmFjdGVkIGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggRGlyZWN0b3J5CiAgICAgKgogICAgICogQHRocm93cyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uIElmIGNhbiBub3QgZXh0cmFjdCBkb3dubG9hZGVkIGZpbGUgdG8gcGF0aAogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKLyoqCiAqIEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBpc3N1ZXMgZXhpc3Qgb24gbG9jYWwgZmlsZXN5c3RlbQogKgogKiBAYXV0aG9yIEphdmllciBTcGFnbm9sZXR0aSA8anNwYWdub2xldHRpQGphdmllcnNwYWdub2xldHRpLmNvbS5hcj4KICovCmNsYXNzIEZpbGVzeXN0ZW1FeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSA9ICcnLCAkY29kZSA9IDAsIFxFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCJGaWxlc3lzdGVtIGV4Y2VwdGlvbjogXG4iLiRtZXNzYWdlLCAkY29kZSwgJHByZXZpb3VzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEVkNTIERvd25sb2FkZXIgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEphbWVzIFRpdGN1bWIgPGphbWVzQGFzZ3JpbS5jb20+CiAqLwppbnRlcmZhY2UgRHZjc0Rvd25sb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBDaGVja3MgZm9yIHVucHVzaGVkIGNoYW5nZXMgdG8gYSBjdXJyZW50IGJyYW5jaAogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGRpcmVjdG9yeQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIHBhY2thZ2UgZGlyZWN0b3J5CiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsICAgICAgY2hhbmdlcyBvciBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVbnB1c2hlZENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcSU9cSU9JbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXEdpdCBhcyBHaXRVdGlsOwp1c2UgQ29tcG9zZXJcVXRpbFxVcmw7CnVzZSBDb21wb3NlclxVdGlsXFBsYXRmb3JtOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxDYWNoZTsKCi8qKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBHaXREb3dubG9hZGVyIGV4dGVuZHMgVmNzRG93bmxvYWRlciBpbXBsZW1lbnRzIER2Y3NEb3dubG9hZGVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBib29sW10KICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBib29sPgogICAgICovCiAgICBwcml2YXRlICRoYXNTdGFzaGVkQ2hhbmdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgYm9vbFtdCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgYm9vbD4KICAgICAqLwogICAgcHJpdmF0ZSAkaGFzRGlzY2FyZGVkQ2hhbmdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgR2l0VXRpbAogICAgICovCiAgICBwcml2YXRlICRnaXRVdGlsOwogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PGludCwgYXJyYXk8c3RyaW5nLCBib29sPj4KICAgICAqLwogICAgcHJpdmF0ZSAkY2FjaGVkUGFja2FnZXMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJT0ludGVyZmFjZSAkaW8sIENvbmZpZyAkY29uZmlnLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsLCBGaWxlc3lzdGVtICRmcyA9IG51bGwpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW8sICRjb25maWcsICRwcm9jZXNzLCAkZnMpOwogICAgICAgICR0aGlzLT5naXRVdGlsID0gbmV3IEdpdFV0aWwoJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHRoaXMtPmZpbGVzeXN0ZW0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Eb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CgogICAgICAgICRjYWNoZVBhdGggPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2NhY2hlLXZjcy1kaXInKS4nLycucHJlZ19yZXBsYWNlKCd7W15hLXowLTkuXX1pJywgJy0nLCAkdXJsKS4nLyc7CiAgICAgICAgJGdpdFZlcnNpb24gPSBHaXRVdGlsOjpnZXRWZXJzaW9uKCR0aGlzLT5wcm9jZXNzKTsKCiAgICAgICAgLy8gLS1kaXNzb2NpYXRlIG9wdGlvbiBpcyBvbmx5IGF2YWlsYWJsZSBzaW5jZSBnaXQgMi4zLjAtcmMwCiAgICAgICAgaWYgKCRnaXRWZXJzaW9uICYmIHZlcnNpb25fY29tcGFyZSgkZ2l0VmVyc2lvbiwgJzIuMy4wLXJjMCcsICc+PScpICYmIENhY2hlOjppc1VzYWJsZSgkY2FjaGVQYXRoKSkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSBTeW5jaW5nIDxpbmZvPiIgLiAkcGFja2FnZS0+Z2V0TmFtZSgpIC4gIjwvaW5mbz4gKDxjb21tZW50PiIgLiAkcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKSAuICI8L2NvbW1lbnQ+KSBpbnRvIGNhY2hlIik7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCcgICAgQ2xvbmluZyB0byBjYWNoZSBhdCAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRjYWNoZVBhdGgpKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgJHJlZiA9ICRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5naXRVdGlsLT5mZXRjaFJlZk9yU3luY01pcnJvcigkdXJsLCAkY2FjaGVQYXRoLCAkcmVmKSAmJiBpc19kaXIoJGNhY2hlUGF0aCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWNoZWRQYWNrYWdlc1skcGFja2FnZS0+Z2V0SWQoKV1bJHJlZl0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKG51bGwgPT09ICRnaXRWZXJzaW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignZ2l0IHdhcyBub3QgZm91bmQgaW4geW91ciBQQVRILCBza2lwcGluZyBzb3VyY2UgZG93bmxvYWQnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICAkY2FjaGVQYXRoID0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdjYWNoZS12Y3MtZGlyJykuJy8nLnByZWdfcmVwbGFjZSgne1teYS16MC05Ll19aScsICctJywgJHVybCkuJy8nOwogICAgICAgICRyZWYgPSAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CiAgICAgICAgJGZsYWcgPSBQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgPyAnL0QgJyA6ICcnOwoKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5jYWNoZWRQYWNrYWdlc1skcGFja2FnZS0+Z2V0SWQoKV1bJHJlZl0pKSB7CiAgICAgICAgICAgICRtc2cgPSAiQ2xvbmluZyAiLiR0aGlzLT5nZXRTaG9ydEhhc2goJHJlZikuJyBmcm9tIGNhY2hlJzsKICAgICAgICAgICAgJGNvbW1hbmQgPQogICAgICAgICAgICAgICAgJ2dpdCBjbG9uZSAtLW5vLWNoZWNrb3V0ICVjYWNoZVBhdGglICVwYXRoJSAtLWRpc3NvY2lhdGUgLS1yZWZlcmVuY2UgJWNhY2hlUGF0aCUgJwogICAgICAgICAgICAgICAgLiAnJiYgY2QgJy4kZmxhZy4nJXBhdGglICcKICAgICAgICAgICAgICAgIC4gJyYmIGdpdCByZW1vdGUgc2V0LXVybCBvcmlnaW4gLS0gJXNhbml0aXplZFVybCUgJiYgZ2l0IHJlbW90ZSBhZGQgY29tcG9zZXIgLS0gJXNhbml0aXplZFVybCUnOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRtc2cgPSAiQ2xvbmluZyAiLiR0aGlzLT5nZXRTaG9ydEhhc2goJHJlZik7CiAgICAgICAgICAgICRjb21tYW5kID0gJ2dpdCBjbG9uZSAtLW5vLWNoZWNrb3V0IC0tICV1cmwlICVwYXRoJSAmJiBjZCAnLiRmbGFnLiclcGF0aCUgJiYgZ2l0IHJlbW90ZSBhZGQgY29tcG9zZXIgLS0gJXVybCUgJiYgZ2l0IGZldGNoIGNvbXBvc2VyICYmIGdpdCByZW1vdGUgc2V0LXVybCBvcmlnaW4gLS0gJXNhbml0aXplZFVybCUgJiYgZ2l0IHJlbW90ZSBzZXQtdXJsIGNvbXBvc2VyIC0tICVzYW5pdGl6ZWRVcmwlJzsKICAgICAgICAgICAgaWYgKGdldGVudignQ09NUE9TRVJfRElTQUJMRV9ORVRXT1JLJykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIHJlcXVpcmVkIGdpdCByZWZlcmVuY2UgZm9yICcuJHBhY2thZ2UtPmdldE5hbWUoKS4nIGlzIG5vdCBpbiBjYWNoZSBhbmQgbmV0d29yayBpcyBkaXNhYmxlZCwgYWJvcnRpbmcnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwoKICAgICAgICAkY29tbWFuZENhbGxhYmxlID0gZnVuY3Rpb24gKCR1cmwpIHVzZSAoJHBhdGgsICRjb21tYW5kLCAkY2FjaGVQYXRoKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgKICAgICAgICAgICAgICAgIGFycmF5KCcldXJsJScsICclcGF0aCUnLCAnJWNhY2hlUGF0aCUnLCAnJXNhbml0aXplZFVybCUnKSwKICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLAogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkY2FjaGVQYXRoKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShwcmVnX3JlcGxhY2UoJ3s6Ly8oW15AXSs/KTooLis/KUB9JywgJzovLycsICR1cmwpKSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAkY29tbWFuZAogICAgICAgICAgICApOwogICAgICAgIH07CgogICAgICAgICR0aGlzLT5naXRVdGlsLT5ydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRwYXRoLCB0cnVlKTsKICAgICAgICBpZiAoJHVybCAhPT0gJHBhY2thZ2UtPmdldFNvdXJjZVVybCgpKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVPcmlnaW5VcmwoJHBhdGgsICRwYWNrYWdlLT5nZXRTb3VyY2VVcmwoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnNldFB1c2hVcmwoJHBhdGgsICR1cmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRuZXdSZWYgPSAkdGhpcy0+dXBkYXRlVG9Db21taXQoJHBhdGgsICRyZWYsICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCksICRwYWNrYWdlLT5nZXRSZWxlYXNlRGF0ZSgpKSkgewogICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSA9PT0gJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0RGlzdFJlZmVyZW5jZSgkbmV3UmVmKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlUmVmZXJlbmNlKCRuZXdSZWYpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvVXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgR2l0VXRpbDo6Y2xlYW5FbnYoKTsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoISR0aGlzLT5oYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVGhlIC5naXQgZGlyZWN0b3J5IGlzIG1pc3NpbmcgZnJvbSAnLiRwYXRoLicsIHNlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9jb21taXQtZGVwcyBmb3IgbW9yZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJGNhY2hlUGF0aCA9ICR0aGlzLT5jb25maWctPmdldCgnY2FjaGUtdmNzLWRpcicpLicvJy5wcmVnX3JlcGxhY2UoJ3tbXmEtejAtOS5dfWknLCAnLScsICR1cmwpLicvJzsKICAgICAgICAkcmVmID0gJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CgogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmNhY2hlZFBhY2thZ2VzWyR0YXJnZXQtPmdldElkKCldWyRyZWZdKSkgewogICAgICAgICAgICAkbXNnID0gIkNoZWNraW5nIG91dCAiLiR0aGlzLT5nZXRTaG9ydEhhc2goJHJlZikuJyBmcm9tIGNhY2hlJzsKICAgICAgICAgICAgJGNvbW1hbmQgPSAnKGdpdCByZXYtcGFyc2UgLS1xdWlldCAtLXZlcmlmeSAlcmVmJSB8fCAoZ2l0IHJlbW90ZSBzZXQtdXJsIGNvbXBvc2VyIC0tICVjYWNoZVBhdGglICYmIGdpdCBmZXRjaCBjb21wb3NlciAmJiBnaXQgZmV0Y2ggLS10YWdzIGNvbXBvc2VyKSkgJiYgZ2l0IHJlbW90ZSBzZXQtdXJsIGNvbXBvc2VyIC0tICVzYW5pdGl6ZWRVcmwlJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbXNnID0gIkNoZWNraW5nIG91dCAiLiR0aGlzLT5nZXRTaG9ydEhhc2goJHJlZik7CiAgICAgICAgICAgICRjb21tYW5kID0gJyhnaXQgcmVtb3RlIHNldC11cmwgY29tcG9zZXIgLS0gJXVybCUgJiYgZ2l0IHJldi1wYXJzZSAtLXF1aWV0IC0tdmVyaWZ5ICVyZWYlIHx8IChnaXQgZmV0Y2ggY29tcG9zZXIgJiYgZ2l0IGZldGNoIC0tdGFncyBjb21wb3NlcikpICYmIGdpdCByZW1vdGUgc2V0LXVybCBjb21wb3NlciAtLSAlc2FuaXRpemVkVXJsJSc7CiAgICAgICAgICAgIGlmIChnZXRlbnYoJ0NPTVBPU0VSX0RJU0FCTEVfTkVUV09SSycpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSByZXF1aXJlZCBnaXQgcmVmZXJlbmNlIGZvciAnLiR0YXJnZXQtPmdldE5hbWUoKS4nIGlzIG5vdCBpbiBjYWNoZSBhbmQgbmV0d29yayBpcyBkaXNhYmxlZCwgYWJvcnRpbmcnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCRtc2cpOwoKICAgICAgICAkY29tbWFuZENhbGxhYmxlID0gZnVuY3Rpb24gKCR1cmwpIHVzZSAoJHJlZiwgJGNvbW1hbmQsICRjYWNoZVBhdGgpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlKAogICAgICAgICAgICAgICAgYXJyYXkoJyV1cmwlJywgJyVyZWYlJywgJyVjYWNoZVBhdGglJywgJyVzYW5pdGl6ZWRVcmwlJyksCiAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdXJsKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVmLidee2NvbW1pdH0nKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkY2FjaGVQYXRoKSwKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZShwcmVnX3JlcGxhY2UoJ3s6Ly8oW15AXSs/KTooLis/KUB9JywgJzovLycsICR1cmwpKSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAkY29tbWFuZAogICAgICAgICAgICApOwogICAgICAgIH07CgogICAgICAgICR0aGlzLT5naXRVdGlsLT5ydW5Db21tYW5kKCRjb21tYW5kQ2FsbGFibGUsICR1cmwsICRwYXRoKTsKICAgICAgICBpZiAoJG5ld1JlZiA9ICR0aGlzLT51cGRhdGVUb0NvbW1pdCgkcGF0aCwgJHJlZiwgJHRhcmdldC0+Z2V0UHJldHR5VmVyc2lvbigpLCAkdGFyZ2V0LT5nZXRSZWxlYXNlRGF0ZSgpKSkgewogICAgICAgICAgICBpZiAoJHRhcmdldC0+Z2V0RGlzdFJlZmVyZW5jZSgpID09PSAkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkgewogICAgICAgICAgICAgICAgJHRhcmdldC0+c2V0RGlzdFJlZmVyZW5jZSgkbmV3UmVmKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGFyZ2V0LT5zZXRTb3VyY2VSZWZlcmVuY2UoJG5ld1JlZik7CiAgICAgICAgfQoKICAgICAgICAkdXBkYXRlT3JpZ2luVXJsID0gZmFsc2U7CiAgICAgICAgaWYgKAogICAgICAgICAgICAwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHJlbW90ZSAtdicsICRvdXRwdXQsICRwYXRoKQogICAgICAgICAgICAmJiBwcmVnX21hdGNoKCd7Xm9yaWdpblxzKyg/UDx1cmw+XFMrKX1tJywgJG91dHB1dCwgJG9yaWdpbk1hdGNoKQogICAgICAgICAgICAmJiBwcmVnX21hdGNoKCd7XmNvbXBvc2VyXHMrKD9QPHVybD5cUyspfW0nLCAkb3V0cHV0LCAkY29tcG9zZXJNYXRjaCkKICAgICAgICApIHsKICAgICAgICAgICAgaWYgKCRvcmlnaW5NYXRjaFsndXJsJ10gPT09ICRjb21wb3Nlck1hdGNoWyd1cmwnXSAmJiAkY29tcG9zZXJNYXRjaFsndXJsJ10gIT09ICR0YXJnZXQtPmdldFNvdXJjZVVybCgpKSB7CiAgICAgICAgICAgICAgICAkdXBkYXRlT3JpZ2luVXJsID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoJHVwZGF0ZU9yaWdpblVybCkgewogICAgICAgICAgICAkdGhpcy0+dXBkYXRlT3JpZ2luVXJsKCRwYXRoLCAkdGFyZ2V0LT5nZXRTb3VyY2VVcmwoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWxDaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIEdpdFV0aWw6OmNsZWFuRW52KCk7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkY29tbWFuZCA9ICdnaXQgc3RhdHVzIC0tcG9yY2VsYWluIC0tdW50cmFja2VkLWZpbGVzPW5vJzsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cmltKCRvdXRwdXQpID86IG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFVucHVzaGVkQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICBHaXRVdGlsOjpjbGVhbkVudigpOwogICAgICAgICRwYXRoID0gJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwogICAgICAgIGlmICghJHRoaXMtPmhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmQgPSAnZ2l0IHNob3ctcmVmIC0taGVhZCAtZCc7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQoKICAgICAgICAkcmVmcyA9IHRyaW0oJG91dHB1dCk7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XihbYS1mMC05XSspIEhFQUQkfW1pJywgJHJlZnMsICRtYXRjaCkpIHsKICAgICAgICAgICAgLy8gY291bGQgbm90IG1hdGNoIHRoZSBIRUFEIGZvciBzb21lIHJlYXNvbgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaGVhZFJlZiA9ICRtYXRjaFsxXTsKICAgICAgICBpZiAoIXByZWdfbWF0Y2hfYWxsKCd7XicuJGhlYWRSZWYuJyByZWZzL2hlYWRzLyguKykkfW1pJywgJHJlZnMsICRtYXRjaGVzKSkgewogICAgICAgICAgICAvLyBub3Qgb24gYSBicmFuY2gsIHdlIGFyZSBlaXRoZXIgb24gYSBub3QtbW9kaWZpZWQgdGFnIG9yIHNvbWUgc29ydCBvZiBkZXRhY2hlZCBoZWFkLCBzbyBza2lwIHRoaXMKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGNhbmRpZGF0ZUJyYW5jaGVzID0gJG1hdGNoZXNbMV07CiAgICAgICAgLy8gdXNlIHRoZSBmaXJzdCBtYXRjaCBhcyBicmFuY2ggbmFtZSBmb3Igbm93CiAgICAgICAgJGJyYW5jaCA9ICRjYW5kaWRhdGVCcmFuY2hlc1swXTsKICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gbnVsbDsKICAgICAgICAkYnJhbmNoTm90Rm91bmRFcnJvciA9IGZhbHNlOwoKICAgICAgICAvLyBkbyB0d28gcGFzc2VzLCBhcyBpZiB3ZSBmaW5kIGFueXRoaW5nIHdlIHdhbnQgdG8gZmV0Y2ggYW5kIHRoZW4gcmUtdHJ5CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDw9IDE7ICRpKyspIHsKICAgICAgICAgICAgJHJlbW90ZUJyYW5jaGVzID0gYXJyYXkoKTsKCiAgICAgICAgICAgIC8vIHRyeSB0byBmaW5kIG1hdGNoaW5nIGJyYW5jaCBuYW1lcyBpbiByZW1vdGUgcmVwb3MKICAgICAgICAgICAgZm9yZWFjaCAoJGNhbmRpZGF0ZUJyYW5jaGVzIGFzICRjYW5kaWRhdGUpIHsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoX2FsbCgne15bYS1mMC05XSsgcmVmcy9yZW1vdGVzLygoPzpbXi9dKykvJy5wcmVnX3F1b3RlKCRjYW5kaWRhdGUpLicpJH1taScsICRyZWZzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWF0Y2hlc1sxXSBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaCA9ICRjYW5kaWRhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZW1vdGVCcmFuY2hlc1tdID0gJG1hdGNoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgaXQgZG9lc24ndCBleGlzdCwgdGhlbiB3ZSBhc3N1bWUgaXQgaXMgYW4gdW5wdXNoZWQgYnJhbmNoCiAgICAgICAgICAgIC8vIHRoaXMgaXMgYmFkIGFzIHdlIGhhdmUgbm8gcmVmZXJlbmNlIHBvaW50IHRvIGRvIGEgZGlmZiBzbyB3ZSBqdXN0IGJhaWwgbGlzdGluZwogICAgICAgICAgICAvLyB0aGUgYnJhbmNoIGFzIGJlaW5nIHVucHVzaGVkCiAgICAgICAgICAgIGlmICghJHJlbW90ZUJyYW5jaGVzKSB7CiAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gJ0JyYW5jaCAnIC4gJGJyYW5jaCAuICcgY291bGQgbm90IGJlIGZvdW5kIG9uIGFueSByZW1vdGUgYW5kIGFwcGVhcnMgdG8gYmUgdW5wdXNoZWQnOwogICAgICAgICAgICAgICAgJGJyYW5jaE5vdEZvdW5kRXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaWYgZmlyc3QgaXRlcmF0aW9uIGZvdW5kIG5vIHJlbW90ZSBicmFuY2ggYnV0IGl0IGhhcyBub3cgZm91bmQgc29tZSwgcmVzZXQgJHVucHVzaGVkQ2hhbmdlcwogICAgICAgICAgICAgICAgLy8gc28gd2UgZ2V0IHRoZSByZWFsIGRpZmYgb3V0cHV0IG5vIG1hdHRlciBpdHMgbGVuZ3RoCiAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaE5vdEZvdW5kRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZW1vdGVCcmFuY2hlcyBhcyAkcmVtb3RlQnJhbmNoKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdnaXQgZGlmZiAtLW5hbWUtc3RhdHVzICVzLi4uJXMgLS0nLCAkcmVtb3RlQnJhbmNoLCAkYnJhbmNoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRvdXRwdXQgPSB0cmltKCRvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgdGhlIHNob3J0ZXN0IGRpZmYgZnJvbSBhbGwgcmVtb3RlIGJyYW5jaGVzIHdlIGNvbXBhcmUgYWdhaW5zdAogICAgICAgICAgICAgICAgICAgIGlmICgkdW5wdXNoZWRDaGFuZ2VzID09PSBudWxsIHx8IHN0cmxlbigkb3V0cHV0KSA8IHN0cmxlbigkdW5wdXNoZWRDaGFuZ2VzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdW5wdXNoZWRDaGFuZ2VzID0gJG91dHB1dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZpcnN0IHBhc3MgYW5kIHdlIGZvdW5kIHVucHVzaGVkIGNoYW5nZXMsIGZldGNoIGZyb20gYWxsIHJlbW90ZXMgdG8gbWFrZSBzdXJlIHdlIGhhdmUgdXAgdG8gZGF0ZQogICAgICAgICAgICAvLyByZW1vdGVzIGFuZCB0aGVuIHRyeSBhZ2FpbiBhcyBvdXRkYXRlZCByZW1vdGVzIGNhbiBzb21ldGltZXMgY2F1c2UgZmFsc2UtcG9zaXRpdmVzCiAgICAgICAgICAgIGlmICgkdW5wdXNoZWRDaGFuZ2VzICYmICRpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGZldGNoIC0tYWxsJywgJG91dHB1dCwgJHBhdGgpOwoKICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBsaXN0IG9mIHJlZnMgYWZ0ZXIgZmV0Y2hpbmcKICAgICAgICAgICAgICAgICRjb21tYW5kID0gJ2dpdCBzaG93LXJlZiAtLWhlYWQgLWQnOwogICAgICAgICAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZWZzID0gdHJpbSgkb3V0cHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gYWJvcnQgYWZ0ZXIgZmlyc3QgcGFzcyBpZiB3ZSBkaWRuJ3QgZmluZCBhbnl0aGluZwogICAgICAgICAgICBpZiAoISR1bnB1c2hlZENoYW5nZXMpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVucHVzaGVkQ2hhbmdlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNsZWFuQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVwZGF0ZSkKICAgIHsKICAgICAgICBHaXRVdGlsOjpjbGVhbkVudigpOwogICAgICAgICRwYXRoID0gJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwoKICAgICAgICAkdW5wdXNoZWQgPSAkdGhpcy0+Z2V0VW5wdXNoZWRDaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgaWYgKCR1bnB1c2hlZCAmJiAoJHRoaXMtPmlvLT5pc0ludGVyYWN0aXZlKCkgfHwgJHRoaXMtPmNvbmZpZy0+Z2V0KCdkaXNjYXJkLWNoYW5nZXMnKSAhPT0gdHJ1ZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdTb3VyY2UgZGlyZWN0b3J5ICcgLiAkcGF0aCAuICcgaGFzIHVucHVzaGVkIGNoYW5nZXMgb24gdGhlIGN1cnJlbnQgYnJhbmNoOiAnLiJcbiIuJHVucHVzaGVkKTsKICAgICAgICB9CgogICAgICAgIGlmICghJGNoYW5nZXMgPSAkdGhpcy0+Z2V0TG9jYWxDaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAkZGlzY2FyZENoYW5nZXMgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2Rpc2NhcmQtY2hhbmdlcycpOwogICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJGRpc2NhcmRDaGFuZ2VzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRpc2NhcmRDaGFuZ2VzKCRwYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJ3N0YXNoJyA9PT0gJGRpc2NhcmRDaGFuZ2VzKSB7CiAgICAgICAgICAgICAgICBpZiAoISR1cGRhdGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OjpjbGVhbkNoYW5nZXMoJHBhY2thZ2UsICRwYXRoLCAkdXBkYXRlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXNoQ2hhbmdlcygkcGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmNsZWFuQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgsICR1cGRhdGUpOwogICAgICAgIH0KCiAgICAgICAgJGNoYW5nZXMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRlbGVtKSB7CiAgICAgICAgICAgIHJldHVybiAnICAgICcuJGVsZW07CiAgICAgICAgfSwgcHJlZ19zcGxpdCgne1xzKlxyP1xuXHMqfScsICRjaGFuZ2VzKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPGVycm9yPicuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGhhcyBtb2RpZmllZCBmaWxlczo8L2Vycm9yPicpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheV9zbGljZSgkY2hhbmdlcywgMCwgMTApKTsKICAgICAgICBpZiAoY291bnQoJGNoYW5nZXMpID4gMTApIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPGluZm8+JyAuIChjb3VudCgkY2hhbmdlcykgLSAxMCkgLiAnIG1vcmUgZmlsZXMgbW9kaWZpZWQsIGNob29zZSAidiIgdG8gdmlldyB0aGUgZnVsbCBsaXN0PC9pbmZvPicpOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+aW8tPmFzaygnICAgIDxpbmZvPkRpc2NhcmQgY2hhbmdlcyBbeSxuLHYsZCwnLigkdXBkYXRlID8gJ3MsJyA6ICcnKS4nP10/PC9pbmZvPiAnLCAnPycpKSB7CiAgICAgICAgICAgICAgICBjYXNlICd5JzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzY2FyZENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAncyc6CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXBkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gaGVscDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFzaENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdVcGRhdGUgYWJvcnRlZCcpOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkY2hhbmdlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnZCc6CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZpZXdEaWZmKCRwYXRoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICc/JzoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaGVscDoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgeSAtIGRpc2NhcmQgY2hhbmdlcyBhbmQgYXBwbHkgdGhlICcuKCR1cGRhdGUgPyAndXBkYXRlJyA6ICd1bmluc3RhbGwnKSwKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICBuIC0gYWJvcnQgdGhlICcuKCR1cGRhdGUgPyAndXBkYXRlJyA6ICd1bmluc3RhbGwnKS4nIGFuZCBsZXQgeW91IG1hbnVhbGx5IGNsZWFuIHRoaW5ncyB1cCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgdiAtIHZpZXcgbW9kaWZpZWQgZmlsZXMnLAogICAgICAgICAgICAgICAgICAgICAgICAnICAgIGQgLSB2aWV3IGxvY2FsIG1vZGlmaWNhdGlvbnMgKGRpZmYpJywKICAgICAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHVwZGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBzIC0gc3Rhc2ggY2hhbmdlcyBhbmQgdHJ5IHRvIHJlYXBwbHkgdGhlbSBhZnRlciB0aGUgdXBkYXRlJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgID8gLSBwcmludCBoZWxwJyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZWFwcGx5Q2hhbmdlcygkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5oYXNTdGFzaGVkQ2hhbmdlc1skcGF0aF0pKSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5oYXNTdGFzaGVkQ2hhbmdlc1skcGF0aF0pOwogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICA8aW5mbz5SZS1hcHBseWluZyBzdGFzaGVkIGNoYW5nZXM8L2luZm8+Jyk7CiAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IHN0YXNoIHBvcCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJGYWlsZWQgdG8gYXBwbHkgc3Rhc2hlZCBjaGFuZ2VzOlxuXG4iLiR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdW5zZXQoJHRoaXMtPmhhc0Rpc2NhcmRlZENoYW5nZXNbJHBhdGhdKTsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIGdpdmVuIHBhdGggdG8gdGhlIGdpdmVuIGNvbW1pdCByZWYKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRyZWZlcmVuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGJyYW5jaAogICAgICogQHBhcmFtICBcRGF0ZVRpbWUgICAgICAgICAkZGF0ZQogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICogQHJldHVybiBudWxsfHN0cmluZyAgICAgICBpZiBhIHN0cmluZyBpcyByZXR1cm5lZCwgaXQgaXMgdGhlIGNvbW1pdCByZWZlcmVuY2UgdGhhdCB3YXMgY2hlY2tlZCBvdXQgaWYgdGhlIG9yaWdpbmFsIGNvdWxkIG5vdCBiZSBmb3VuZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlVG9Db21taXQoJHBhdGgsICRyZWZlcmVuY2UsICRicmFuY2gsICRkYXRlKQogICAgewogICAgICAgICRmb3JjZSA9ICFlbXB0eSgkdGhpcy0+aGFzRGlzY2FyZGVkQ2hhbmdlc1skcGF0aF0pIHx8ICFlbXB0eSgkdGhpcy0+aGFzU3Rhc2hlZENoYW5nZXNbJHBhdGhdKSA/ICctZiAnIDogJyc7CgogICAgICAgIC8vIFRoaXMgdXNlcyB0aGUgIi0tIiBzZXF1ZW5jZSB0byBzZXBhcmF0ZSBicmFuY2ggZnJvbSBmaWxlIHBhcmFtZXRlcnMuCiAgICAgICAgLy8KICAgICAgICAvLyBPdGhlcndpc2UgZ2l0IHRyaWVzIHRoZSBicmFuY2ggbmFtZSBhcyB3ZWxsIGFzIGZpbGUgbmFtZS4KICAgICAgICAvLyBJZiB0aGUgbm9uLWV4aXN0ZW50IGJyYW5jaCBpcyBhY3R1YWxseSB0aGUgbmFtZSBvZiBhIGZpbGUsIHRoZSBmaWxlCiAgICAgICAgLy8gaXMgY2hlY2tlZCBvdXQuCiAgICAgICAgJHRlbXBsYXRlID0gJ2dpdCBjaGVja291dCAnLiRmb3JjZS4nJXMgLS0gJiYgZ2l0IHJlc2V0IC0taGFyZCAlMSRzIC0tJzsKICAgICAgICAkYnJhbmNoID0gcHJlZ19yZXBsYWNlKCd7KD86XmRldi18KD86XC54KT8tZGV2JCl9aScsICcnLCAkYnJhbmNoKTsKCiAgICAgICAgJGJyYW5jaGVzID0gbnVsbDsKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBicmFuY2ggLXInLCAkb3V0cHV0LCAkcGF0aCkpIHsKICAgICAgICAgICAgJGJyYW5jaGVzID0gJG91dHB1dDsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgbm9uLWNvbW1pdGlzaCBhcmUgYnJhbmNoZXMgb3IgdGFncywgYW5kIGZldGNoIGJyYW5jaGVzIHdpdGggdGhlIHJlbW90ZSBuYW1lCiAgICAgICAgJGdpdFJlZiA9ICRyZWZlcmVuY2U7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XlthLWYwLTldezQwfSR9JywgJHJlZmVyZW5jZSkKICAgICAgICAgICAgJiYgJGJyYW5jaGVzCiAgICAgICAgICAgICYmIHByZWdfbWF0Y2goJ3teXHMrY29tcG9zZXIvJy5wcmVnX3F1b3RlKCRyZWZlcmVuY2UpLickfW0nLCAkYnJhbmNoZXMpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICcuJGZvcmNlLictQiAlcyAlcyAtLSAmJiBnaXQgcmVzZXQgLS1oYXJkICUyJHMgLS0nLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkYnJhbmNoKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJ2NvbXBvc2VyLycuJHJlZmVyZW5jZSkpOwogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHRyeSB0byBjaGVja291dCBicmFuY2ggYnkgbmFtZSBhbmQgdGhlbiByZXNldCBpdCBzbyBpdCdzIG9uIHRoZSBwcm9wZXIgYnJhbmNoIG5hbWUKICAgICAgICBpZiAocHJlZ19tYXRjaCgne15bYS1mMC05XXs0MH0kfScsICRyZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIC8vIGFkZCAndicgaW4gZnJvbnQgb2YgdGhlIGJyYW5jaCBpZiBpdCB3YXMgc3RyaXBwZWQgd2hlbiBnZW5lcmF0aW5nIHRoZSBwcmV0dHkgbmFtZQogICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3teXHMrY29tcG9zZXIvJy5wcmVnX3F1b3RlKCRicmFuY2gpLickfW0nLCAkYnJhbmNoZXMpICYmIHByZWdfbWF0Y2goJ3teXHMrY29tcG9zZXIvdicucHJlZ19xdW90ZSgkYnJhbmNoKS4nJH1tJywgJGJyYW5jaGVzKSkgewogICAgICAgICAgICAgICAgJGJyYW5jaCA9ICd2JyAuICRicmFuY2g7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICVzIC0tJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGJyYW5jaCkpOwogICAgICAgICAgICAkZmFsbGJhY2tDb21tYW5kID0gc3ByaW50ZignZ2l0IGNoZWNrb3V0ICcuJGZvcmNlLictQiAlcyAlcyAtLScsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRicmFuY2gpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgnY29tcG9zZXIvJy4kYnJhbmNoKSk7CiAgICAgICAgICAgICRyZXNldENvbW1hbmQgPSBzcHJpbnRmKCdnaXQgcmVzZXQgLS1oYXJkICVzIC0tJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHJlZmVyZW5jZSkpOwoKICAgICAgICAgICAgaWYgKDAgPT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCIoJGNvbW1hbmQgfHwgJGZhbGxiYWNrQ29tbWFuZCkgJiYgJHJlc2V0Q29tbWFuZCIsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gc3ByaW50ZigkdGVtcGxhdGUsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRnaXRSZWYpKTsKICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIHJlZmVyZW5jZSB3YXMgbm90IGZvdW5kIChwcmludHMgImZhdGFsOiByZWZlcmVuY2UgaXMgbm90IGEgdHJlZTogJHJlZiIpCiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCksICRyZWZlcmVuY2UpKSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPicuJHJlZmVyZW5jZS4nIGlzIGdvbmUgKGhpc3Rvcnkgd2FzIHJld3JpdHRlbj8pPC93YXJuaW5nPicpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKFVybDo6c2FuaXRpemUoJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwZGF0ZU9yaWdpblVybCgkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZShzcHJpbnRmKCdnaXQgcmVtb3RlIHNldC11cmwgb3JpZ2luIC0tICVzJywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHVybCkpLCAkb3V0cHV0LCAkcGF0aCk7CiAgICAgICAgJHRoaXMtPnNldFB1c2hVcmwoJHBhdGgsICR1cmwpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXRQdXNoVXJsKCRwYXRoLCAkdXJsKQogICAgewogICAgICAgIC8vIHNldCBwdXNoIHVybCBmb3IgZ2l0aHViIHByb2plY3RzCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKD86aHR0cHM/fGdpdCk6Ly8nLkdpdFV0aWw6OmdldEdpdEh1YkRvbWFpbnNSZWdleCgkdGhpcy0+Y29uZmlnKS4nLyhbXi9dKykvKFteL10rPykoPzpcLmdpdCk/JH0nLCAkdXJsLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICRwcm90b2NvbHMgPSAkdGhpcy0+Y29uZmlnLT5nZXQoJ2dpdGh1Yi1wcm90b2NvbHMnKTsKICAgICAgICAgICAgJHB1c2hVcmwgPSAnZ2l0QCcuJG1hdGNoWzFdLic6Jy4kbWF0Y2hbMl0uJy8nLiRtYXRjaFszXS4nLmdpdCc7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJ3NzaCcsICRwcm90b2NvbHMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkcHVzaFVybCA9ICdodHRwczovLycgLiAkbWF0Y2hbMV0gLiAnLycuJG1hdGNoWzJdLicvJy4kbWF0Y2hbM10uJy5naXQnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjbWQgPSBzcHJpbnRmKCdnaXQgcmVtb3RlIHNldC11cmwgLS1wdXNoIG9yaWdpbiAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwdXNoVXJsKSk7CiAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjbWQsICRpZ25vcmVkT3V0cHV0LCAkcGF0aCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlLCAkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICAkY29tbWFuZCA9IHNwcmludGYoJ2dpdCBsb2cgJXMuLiVzIC0tcHJldHR5PWZvcm1hdDoiJSVoIC0gJSVhbjogJSVzIicuR2l0VXRpbDo6Z2V0Tm9TaG93U2lnbmF0dXJlRmxhZygkdGhpcy0+cHJvY2VzcyksIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRmcm9tUmVmZXJlbmNlKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRvUmVmZXJlbmNlKSk7CgogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICRwYXRoCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkaXNjYXJkQ2hhbmdlcygkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBjbGVhbiAtZGYgJiYgZ2l0IHJlc2V0IC0taGFyZCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkNvdWxkIG5vdCByZXNldCBjaGFuZ2VzXG5cbjoiLiRvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmhhc0Rpc2NhcmRlZENoYW5nZXNbJHBhdGhdID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGgKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHN0YXNoQ2hhbmdlcygkcGF0aCkKICAgIHsKICAgICAgICAkcGF0aCA9ICR0aGlzLT5ub3JtYWxpemVQYXRoKCRwYXRoKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2dpdCBzdGFzaCAtLWluY2x1ZGUtdW50cmFja2VkJywgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigiQ291bGQgbm90IHN0YXNoIGNoYW5nZXNcblxuOiIuJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aGFzU3Rhc2hlZENoYW5nZXNbJHBhdGhdID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGgKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZpZXdEaWZmKCRwYXRoKQogICAgewogICAgICAgICRwYXRoID0gJHRoaXMtPm5vcm1hbGl6ZVBhdGgoJHBhdGgpOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnZ2l0IGRpZmYgSEVBRCcsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkNvdWxkIG5vdCB2aWV3IGRpZmZcblxuOiIuJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG91dHB1dCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIG5vcm1hbGl6ZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiBzdHJsZW4oJHBhdGgpID4gMCkgewogICAgICAgICAgICAkYmFzZVBhdGggPSAkcGF0aDsKICAgICAgICAgICAgJHJlbW92ZWQgPSBhcnJheSgpOwoKICAgICAgICAgICAgd2hpbGUgKCFpc19kaXIoJGJhc2VQYXRoKSAmJiAkYmFzZVBhdGggIT09ICdcXCcpIHsKICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJHJlbW92ZWQsIGJhc2VuYW1lKCRiYXNlUGF0aCkpOwogICAgICAgICAgICAgICAgJGJhc2VQYXRoID0gZGlybmFtZSgkYmFzZVBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGJhc2VQYXRoID09PSAnXFwnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHBhdGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRwYXRoID0gcnRyaW0ocmVhbHBhdGgoJGJhc2VQYXRoKSAuICcvJyAuIGltcGxvZGUoJy8nLCAkcmVtb3ZlZCksICcvJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpCiAgICB7CiAgICAgICAgJHBhdGggPSAkdGhpcy0+bm9ybWFsaXplUGF0aCgkcGF0aCk7CgogICAgICAgIHJldHVybiBpc19kaXIoJHBhdGguJy8uZ2l0Jyk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFNob3J0SGFzaCgkcmVmZXJlbmNlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmlvLT5pc1ZlcmJvc2UoKSAmJiBwcmVnX21hdGNoKCd7XlswLTlhLWZdezQwfSR9JywgJHJlZmVyZW5jZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkcmVmZXJlbmNlLCAwLCAxMCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlZmVyZW5jZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwoKLyoqCiAqIEBhdXRob3IgQm9od2FaIDxodHRwOi8vYm9od2F6Lm5ldC8+CiAqLwpjbGFzcyBGb3NzaWxEb3dubG9hZGVyIGV4dGVuZHMgVmNzRG93bmxvYWRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvSW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICAvLyBFbnN1cmUgd2UgYXJlIGFsbG93ZWQgdG8gdXNlIHRoaXMgVVJMIGJ5IGNvbmZpZwogICAgICAgICR0aGlzLT5jb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJHVybCwgJHRoaXMtPmlvKTsKCiAgICAgICAgJHVybCA9IFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpOwogICAgICAgICRyZWYgPSBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICRyZXBvRmlsZSA9ICRwYXRoIC4gJy5mb3NzaWwnOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiQ2xvbmluZyAiLiRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSk7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdmb3NzaWwgY2xvbmUgLS0gJXMgJXMnLCAkdXJsLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVwb0ZpbGUpKTsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdmb3NzaWwgb3BlbiAtLW5lc3RlZCAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRyZXBvRmlsZSkpOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsIHJlYWxwYXRoKCRwYXRoKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZm9zc2lsIHVwZGF0ZSAtLSAlcycsICRyZWYpOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsIHJlYWxwYXRoKCRwYXRoKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9VcGRhdGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0LCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICAvLyBFbnN1cmUgd2UgYXJlIGFsbG93ZWQgdG8gdXNlIHRoaXMgVVJMIGJ5IGNvbmZpZwogICAgICAgICR0aGlzLT5jb25maWctPnByb2hpYml0VXJsQnlDb25maWcoJHVybCwgJHRoaXMtPmlvKTsKCiAgICAgICAgJHJlZiA9IFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0YXJnZXQtPmdldFNvdXJjZVJlZmVyZW5jZSgpKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiBVcGRhdGluZyB0byAiLiR0YXJnZXQtPmdldFNvdXJjZVJlZmVyZW5jZSgpKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSAuZnNsY2tvdXQgZmlsZSBpcyBtaXNzaW5nIGZyb20gJy4kcGF0aC4nLCBzZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvY29tbWl0LWRlcHMgZm9yIG1vcmUgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZm9zc2lsIHB1bGwgJiYgZm9zc2lsIHVwICVzJywgJHJlZik7CiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkaWdub3JlZE91dHB1dCwgcmVhbHBhdGgoJHBhdGgpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCdmb3NzaWwgY2hhbmdlcycsICRvdXRwdXQsIHJlYWxwYXRoKCRwYXRoKSk7CgogICAgICAgIHJldHVybiB0cmltKCRvdXRwdXQpID86IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRDb21taXRMb2dzKCRmcm9tUmVmZXJlbmNlLCAkdG9SZWZlcmVuY2UsICRwYXRoKQogICAgewogICAgICAgICRjb21tYW5kID0gc3ByaW50ZignZm9zc2lsIHRpbWVsaW5lIC10IGNpIC1XIDAgLW4gMCBiZWZvcmUgJXMnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdG9SZWZlcmVuY2UpKTsKCiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgJGxvZyA9ICcnOwogICAgICAgICRtYXRjaCA9ICcvXGRcZDpcZFxkOlxkXGRccytcWycgLiAkdG9SZWZlcmVuY2UgLiAnXF0vJzsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3MtPnNwbGl0TGluZXMoJG91dHB1dCkgYXMgJGxpbmUpIHsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJG1hdGNoLCAkbGluZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsb2cgLj0gJGxpbmU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxvZzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gaXNfZmlsZSgkcGF0aCAuICcvLmZzbGNrb3V0JykgfHwgaXNfZmlsZSgkcGF0aCAuICcvX0ZPU1NJTF8nKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQXJjaGl2ZXJcQXJjaGl2YWJsZUZpbGVzRmluZGVyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxEdW1wZXJcQXJyYXlEdW1wZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvbkd1ZXNzZXI7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxJT0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW1cRmlsZXN5c3RlbSBhcyBTeW1mb255RmlsZXN5c3RlbTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVW5pbnN0YWxsT3BlcmF0aW9uOwoKLyoqCiAqIERvd25sb2FkIGEgcGFja2FnZSBmcm9tIGEgbG9jYWwgcGF0aC4KICoKICogQGF1dGhvciBTYW11ZWwgUm96ZSA8c2FtdWVsLnJvemVAZ21haWwuY29tPgogKiBAYXV0aG9yIEpvaGFubiBSZWlua2UgPGpvaGFubi5yZWlua2VAZ21haWwuY29tPgogKi8KY2xhc3MgUGF0aERvd25sb2FkZXIgZXh0ZW5kcyBGaWxlRG93bmxvYWRlciBpbXBsZW1lbnRzIFZjc0NhcGFibGVEb3dubG9hZGVySW50ZXJmYWNlCnsKICAgIGNvbnN0IFNUUkFURUdZX1NZTUxJTksgPSAxMDsKICAgIGNvbnN0IFNUUkFURUdZX01JUlJPUiA9IDIwOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCwgJG91dHB1dCA9IHRydWUpCiAgICB7CiAgICAgICAgJHBhdGggPSBGaWxlc3lzdGVtOjp0cmltVHJhaWxpbmdTbGFzaCgkcGF0aCk7CiAgICAgICAgJHVybCA9ICRwYWNrYWdlLT5nZXREaXN0VXJsKCk7CiAgICAgICAgJHJlYWxVcmwgPSByZWFscGF0aCgkdXJsKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRyZWFsVXJsIHx8ICFmaWxlX2V4aXN0cygkcmVhbFVybCkgfHwgIWlzX2RpcigkcmVhbFVybCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAnU291cmNlIHBhdGggIiVzIiBpcyBub3QgZm91bmQgZm9yIHBhY2thZ2UgJXMnLAogICAgICAgICAgICAgICAgJHVybCwKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXROYW1lKCkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocmVhbHBhdGgoJHBhdGgpID09PSAkcmVhbFVybCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKHJlYWxwYXRoKCRwYXRoKSAuIERJUkVDVE9SWV9TRVBBUkFUT1IsICRyZWFsVXJsIC4gRElSRUNUT1JZX1NFUEFSQVRPUikgPT09IDApIHsKICAgICAgICAgICAgLy8gSU1QT1JUQU5UIE5PVElDRTogSWYgeW91IHdpc2ggdG8gY2hhbmdlIHRoaXMsIGRvbid0LiBZb3UgYXJlIHdhc3RpbmcgeW91ciB0aW1lIGFuZCBvdXJzLgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBQbGVhc2Ugc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9wdWxsLzU5NzQgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9wdWxsLzYxNzQKICAgICAgICAgICAgLy8gZm9yIHByZXZpb3VzIGF0dGVtcHRzIHRoYXQgd2VyZSBzaHV0IGRvd24gYmVjYXVzZSB0aGV5IGRpZCBub3Qgd29yayB3ZWxsIGVub3VnaCBvciBpbnRyb2R1Y2VkIHRvbyBtYW55IHJpc2tzLgogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdQYWNrYWdlICVzIGNhbm5vdCBpbnN0YWxsIHRvICIlcyIgaW5zaWRlIGl0cyBzb3VyY2UgYXQgIiVzIicsCiAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0TmFtZSgpLAogICAgICAgICAgICAgICAgcmVhbHBhdGgoJHBhdGgpLAogICAgICAgICAgICAgICAgJHJlYWxVcmwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJG91dHB1dCA9IHRydWUpCiAgICB7CiAgICAgICAgJHBhdGggPSBGaWxlc3lzdGVtOjp0cmltVHJhaWxpbmdTbGFzaCgkcGF0aCk7CiAgICAgICAgJHVybCA9ICRwYWNrYWdlLT5nZXREaXN0VXJsKCk7CiAgICAgICAgJHJlYWxVcmwgPSByZWFscGF0aCgkdXJsKTsKCiAgICAgICAgaWYgKHJlYWxwYXRoKCRwYXRoKSA9PT0gJHJlYWxVcmwpIHsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBJbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpLic6IFNvdXJjZSBhbHJlYWR5IHByZXNlbnQnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignU291cmNlIGFscmVhZHkgcHJlc2VudCcsIGZhbHNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gR2V0IHRoZSB0cmFuc3BvcnQgb3B0aW9ucyB3aXRoIGRlZmF1bHQgdmFsdWVzCiAgICAgICAgJHRyYW5zcG9ydE9wdGlvbnMgPSAkcGFja2FnZS0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpICsgYXJyYXkoJ3N5bWxpbmsnID0+IG51bGwsICdyZWxhdGl2ZScgPT4gdHJ1ZSk7CgogICAgICAgIC8vIFdoZW4gc3ltbGluayB0cmFuc3BvcnQgb3B0aW9uIGlzIG51bGwsIGJvdGggc3ltbGluayBhbmQgbWlycm9yIGFyZSBhbGxvd2VkCiAgICAgICAgJGN1cnJlbnRTdHJhdGVneSA9IHNlbGY6OlNUUkFURUdZX1NZTUxJTks7CiAgICAgICAgJGFsbG93ZWRTdHJhdGVnaWVzID0gYXJyYXkoc2VsZjo6U1RSQVRFR1lfU1lNTElOSywgc2VsZjo6U1RSQVRFR1lfTUlSUk9SKTsKCiAgICAgICAgJG1pcnJvclBhdGhSZXBvcyA9IGdldGVudignQ09NUE9TRVJfTUlSUk9SX1BBVEhfUkVQT1MnKTsKICAgICAgICBpZiAoJG1pcnJvclBhdGhSZXBvcykgewogICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRydWUgPT09ICR0cmFuc3BvcnRPcHRpb25zWydzeW1saW5rJ10pIHsKICAgICAgICAgICAgJGN1cnJlbnRTdHJhdGVneSA9IHNlbGY6OlNUUkFURUdZX1NZTUxJTks7CiAgICAgICAgICAgICRhbGxvd2VkU3RyYXRlZ2llcyA9IGFycmF5KHNlbGY6OlNUUkFURUdZX1NZTUxJTkspOwogICAgICAgIH0gZWxzZWlmIChmYWxzZSA9PT0gJHRyYW5zcG9ydE9wdGlvbnNbJ3N5bWxpbmsnXSkgewogICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgICAgICAkYWxsb3dlZFN0cmF0ZWdpZXMgPSBhcnJheShzZWxmOjpTVFJBVEVHWV9NSVJST1IpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgd2UgY2FuIHVzZSBqdW5jdGlvbnMgc2FmZWx5IGlmIHdlIGFyZSBvbiBXaW5kb3dzCiAgICAgICAgaWYgKFBsYXRmb3JtOjppc1dpbmRvd3MoKSAmJiBzZWxmOjpTVFJBVEVHWV9TWU1MSU5LID09PSAkY3VycmVudFN0cmF0ZWd5ICYmICEkdGhpcy0+c2FmZUp1bmN0aW9ucygpKSB7CiAgICAgICAgICAgICRjdXJyZW50U3RyYXRlZ3kgPSBzZWxmOjpTVFJBVEVHWV9NSVJST1I7CiAgICAgICAgICAgICRhbGxvd2VkU3RyYXRlZ2llcyA9IGFycmF5KHNlbGY6OlNUUkFURUdZX01JUlJPUik7CiAgICAgICAgfQoKICAgICAgICAkc3ltZm9ueUZpbGVzeXN0ZW0gPSBuZXcgU3ltZm9ueUZpbGVzeXN0ZW0oKTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRwYXRoKTsKCiAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIEluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkuJzogJywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgJGlzRmFsbGJhY2sgPSBmYWxzZTsKICAgICAgICBpZiAoc2VsZjo6U1RSQVRFR1lfU1lNTElOSyA9PSAkY3VycmVudFN0cmF0ZWd5KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAoUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSW1wbGVtZW50IHN5bWxpbmtzIGFzIE5URlMganVuY3Rpb25zIG9uIFdpbmRvd3MKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignSnVuY3Rpb25pbmcgZnJvbSAlcycsICR1cmwpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmp1bmN0aW9uKCRyZWFsVXJsLCAkcGF0aCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRhYnNvbHV0ZVBhdGggPSAkcGF0aDsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5maWxlc3lzdGVtLT5pc0Fic29sdXRlUGF0aCgkYWJzb2x1dGVQYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYWJzb2x1dGVQYXRoID0gZ2V0Y3dkKCkgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJHBhdGg7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRzaG9ydGVzdFBhdGggPSAkdGhpcy0+ZmlsZXN5c3RlbS0+ZmluZFNob3J0ZXN0UGF0aCgkYWJzb2x1dGVQYXRoLCAkcmVhbFVybCk7CiAgICAgICAgICAgICAgICAgICAgJHBhdGggPSBydHJpbSgkcGF0aCwgIi8iKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignU3ltbGlua2luZyBmcm9tICVzJywgJHVybCksIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHRyYW5zcG9ydE9wdGlvbnNbJ3JlbGF0aXZlJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHN5bWZvbnlGaWxlc3lzdGVtLT5zeW1saW5rKCRzaG9ydGVzdFBhdGgsICRwYXRoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkc3ltZm9ueUZpbGVzeXN0ZW0tPnN5bWxpbmsoJHJlYWxVcmwsICRwYXRoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5fYXJyYXkoc2VsZjo6U1RSQVRFR1lfTUlSUk9SLCAkYWxsb3dlZFN0cmF0ZWdpZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICA8ZXJyb3I+U3ltbGluayBmYWlsZWQsIGZhbGxiYWNrIHRvIHVzZSBtaXJyb3JpbmchPC9lcnJvcj4nKTsKICAgICAgICAgICAgICAgICAgICAkY3VycmVudFN0cmF0ZWd5ID0gc2VsZjo6U1RSQVRFR1lfTUlSUk9SOwogICAgICAgICAgICAgICAgICAgICRpc0ZhbGxiYWNrID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1N5bWxpbmsgZnJvbSAiJXMiIHRvICIlcyIgZmFpbGVkIScsICRyZWFsVXJsLCAkcGF0aCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBGYWxsYmFjayBpZiBzeW1saW5rIGZhaWxlZCBvciBpZiBzeW1saW5rIGlzIG5vdCBhbGxvd2VkIGZvciB0aGUgcGFja2FnZQogICAgICAgIGlmIChzZWxmOjpTVFJBVEVHWV9NSVJST1IgPT0gJGN1cnJlbnRTdHJhdGVneSkgewogICAgICAgICAgICAkcmVhbFVybCA9ICR0aGlzLT5maWxlc3lzdGVtLT5ub3JtYWxpemVQYXRoKCRyZWFsVXJsKTsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihzcHJpbnRmKCclc01pcnJvcmluZyBmcm9tICVzJywgJGlzRmFsbGJhY2sgPyAnICAgICcgOiAnJywgJHVybCksIGZhbHNlKTsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEFyY2hpdmFibGVGaWxlc0ZpbmRlcigkcmVhbFVybCwgYXJyYXkoKSk7CiAgICAgICAgICAgICRzeW1mb255RmlsZXN5c3RlbS0+bWlycm9yKCRyZWFsVXJsLCAkcGF0aCwgJGl0ZXJhdG9yKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkb3V0cHV0ID0gdHJ1ZSkKICAgIHsKICAgICAgICAkcGF0aCA9IEZpbGVzeXN0ZW06OnRyaW1UcmFpbGluZ1NsYXNoKCRwYXRoKTsKICAgICAgICAvKioKICAgICAgICAgKiByZWFscGF0aCgpIG1heSByZXNvbHZlIFdpbmRvd3MganVuY3Rpb25zIHRvIHRoZSBzb3VyY2UgcGF0aCwgc28gd2UnbGwgY2hlY2sgZm9yIGEganVuY3Rpb24gZmlyc3QKICAgICAgICAgKiB0byBwcmV2ZW50IGEgZmFsc2UgcG9zaXRpdmUgd2hlbiBjaGVja2luZyBpZiB0aGUgZGlzdCBhbmQgaW5zdGFsbCBwYXRocyBhcmUgdGhlIHNhbWUuCiAgICAgICAgICogU2VlIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9Nzc2MzkKICAgICAgICAgKgogICAgICAgICAqIEZvciBqdW5jdGlvbnMgZG9uJ3QgYmxpbmRseSByZWx5IG9uIEZpbGVzeXN0ZW06OnJlbW92ZURpcmVjdG9yeSBhcyBpdCBtYXkgYmUgb3ZlcnplYWxvdXMuIElmIGEgcHJvY2VzcwogICAgICAgICAqIGluYWR2ZXJ0ZW50bHkgbG9ja3MgdGhlIGZpbGUgdGhlIHJlbW92YWwgd2lsbCBmYWlsLCBidXQgaXQgd291bGQgZmFsbCBiYWNrIHRvIHJlY3Vyc2l2ZSBkZWxldGUgd2hpY2gKICAgICAgICAgKiBpcyBkaXNhc3Ryb3VzIHdpdGhpbiBhIGp1bmN0aW9uLiBTbyBpbiB0aGF0IGNhc2Ugd2UgaGF2ZSBubyBvdGhlciByZWFsIGNob2ljZSBidXQgdG8gZmFpbCBoYXJkLgogICAgICAgICAqLwogICAgICAgIGlmIChQbGF0Zm9ybTo6aXNXaW5kb3dzKCkgJiYgJHRoaXMtPmZpbGVzeXN0ZW0tPmlzSnVuY3Rpb24oJHBhdGgpKSB7CiAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVW5pbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpLiIsIHNvdXJjZSBpcyBzdGlsbCBwcmVzZW50IGluICRwYXRoIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlSnVuY3Rpb24oJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgICA8d2FybmluZz5Db3VsZCBub3QgcmVtb3ZlIGp1bmN0aW9uIGF0ICIgLiAkcGF0aCAuICIgLSBpcyBhbm90aGVyIHByb2Nlc3MgbG9ja2luZyBpdD88L3dhcm5pbmc+Iik7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCByZWxpYWJseSByZW1vdmUganVuY3Rpb24gZm9yIHBhY2thZ2UgJyAuICRwYWNrYWdlLT5nZXROYW1lKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKHJlYWxwYXRoKCRwYXRoKSA9PT0gcmVhbHBhdGgoJHBhY2thZ2UtPmdldERpc3RVcmwoKSkpIHsKICAgICAgICAgICAgaWYgKCRvdXRwdXQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiICAtICIgLiBVbmluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkuIiwgc291cmNlIGlzIHN0aWxsIHByZXNlbnQgaW4gJHBhdGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBhcmVudDo6cmVtb3ZlKCRwYWNrYWdlLCAkcGF0aCwgJG91dHB1dCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmNzUmVmZXJlbmNlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgICRwYXRoID0gRmlsZXN5c3RlbTo6dHJpbVRyYWlsaW5nU2xhc2goJHBhdGgpOwogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZ3Vlc3NlciA9IG5ldyBWZXJzaW9uR3Vlc3NlcigkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHBhcnNlcik7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcjsKCiAgICAgICAgJHBhY2thZ2VDb25maWcgPSAkZHVtcGVyLT5kdW1wKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJHBhY2thZ2VWZXJzaW9uID0gJGd1ZXNzZXItPmd1ZXNzVmVyc2lvbigkcGFja2FnZUNvbmZpZywgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZVZlcnNpb25bJ2NvbW1pdCddOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBqdW5jdGlvbnMgY2FuIGJlIGNyZWF0ZWQgYW5kIHNhZmVseSB1c2VkIG9uIFdpbmRvd3MKICAgICAqCiAgICAgKiBBIFBIUCBidWcgbWFrZXMganVuY3Rpb24gZGV0ZWN0aW9uIGZyYWdpbGUsIGxlYWRpbmcgdG8gcG9zc2libGUgZGF0YSBsb3NzCiAgICAgKiB3aGVuIHJlbW92aW5nIGEgcGFja2FnZS4gU2VlIGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9Nzc1NTIKICAgICAqCiAgICAgKiBGb3Igc2FmZXR5IHdlIHJlcXVpcmUgYSBtaW5pbXVtIHZlcnNpb24gb2YgV2luZG93cyA3LCBzbyB3ZSBjYW4gY2FsbCB0aGUKICAgICAqIHN5c3RlbSBybWRpciB3aGljaCB3aWxsIHByZXNlcnZlIHRhcmdldCBjb250ZW50IGlmIGdpdmVuIGEganVuY3Rpb24uCiAgICAgKgogICAgICogVGhlIFBIUCBidWcgd2FzIGZpeGVkIGluIDcuMi4xNiBhbmQgNy4zLjMgKHJlcXVpcmVzIGF0IGxlYXN0IFdpbmRvd3MgNykuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2FmZUp1bmN0aW9ucygpCiAgICB7CiAgICAgICAgLy8gV2UgbmVlZCB0byBjYWxsIG1rbGluaywgYW5kIHJtZGlyIG9uIFdpbmRvd3MgNyAodmVyc2lvbiA2LjEpCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykgJiYKICAgICAgICAgICAgKFBIUF9XSU5ET1dTX1ZFUlNJT05fTUFKT1IgPiA2IHx8CiAgICAgICAgICAgIChQSFBfV0lORE9XU19WRVJTSU9OX01BSk9SID09PSA2ICYmIFBIUF9XSU5ET1dTX1ZFUlNJT05fTUlOT1IgPj0gMSkpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIENoYW5nZVJlcG9ydCBpbnRlcmZhY2UuCiAqCiAqIEBhdXRob3IgU2FzY2hhIEVnZXJlciA8c2FzY2hhLmVnZXJlckBka2QuZGU+CiAqLwppbnRlcmZhY2UgQ2hhbmdlUmVwb3J0SW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQ2hlY2tzIGZvciBjaGFuZ2VzIHRvIHRoZSBsb2NhbCBjb3B5CiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBwYWNrYWdlIGRpcmVjdG9yeQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCAgICAgIGNoYW5nZXMgb3IgbnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWxDaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBEb3dubG9hZGVyIGZvciBwaGFyIGZpbGVzCiAqCiAqIEBhdXRob3IgS2lyaWxsIGNoRWJiYSBDaGVidW5pbiA8aWFtQGNoZWJiYS5vcmc+CiAqLwpjbGFzcyBQaGFyRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXh0cmFjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpCiAgICB7CiAgICAgICAgLy8gQ2FuIHRocm93IGFuIFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICAgICRhcmNoaXZlID0gbmV3IFxQaGFyKCRmaWxlKTsKICAgICAgICAkYXJjaGl2ZS0+ZXh0cmFjdFRvKCRwYXRoLCBudWxsLCB0cnVlKTsKICAgICAgICAvKiBUT0RPOiBoYW5kbGUgb3BlbnNzbCBzaWduZWQgcGhhcnMKICAgICAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvcHVsbC8zMyNpc3N1ZWNvbW1lbnQtMjI1MDc2OAogICAgICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9rb3RvL3BoYXItdXRpbAogICAgICAgICAqIGh0dHA6Ly9ibG9nLmtvdG93aWN6Lm5ldC8yMDEwLzA4L2hhcmRlbmluZy1waHAtaG93LXRvLXNlY3VyZWx5LWluY2x1ZGUuaHRtbAogICAgICAgICAqLwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIFZDUyBDYXBhYmxlIERvd25sb2FkZXIgaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIFN0ZXZlIEJ1em9uYXMgPHN0ZXZlQGZhbmN5Z3V5LmNvbT4KICovCmludGVyZmFjZSBWY3NDYXBhYmxlRG93bmxvYWRlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEdldHMgdGhlIFZDUyBSZWZlcmVuY2UgZm9yIHRoZSBwYWNrYWdlIGF0IHBhdGgKICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UgcGFja2FnZSBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBwYWNrYWdlIGRpcmVjdG9yeQogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCAgICAgIHJlZmVyZW5jZSBvciBudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWY3NSZWZlcmVuY2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERvd25sb2FkZXI7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgVHJhbnNwb3J0RXhjZXB0aW9uIGV4dGVuZHMgXFJ1bnRpbWVFeGNlcHRpb24KewogICAgcHJvdGVjdGVkICRoZWFkZXJzOwogICAgcHJvdGVjdGVkICRyZXNwb25zZTsKICAgIHByb3RlY3RlZCAkc3RhdHVzQ29kZTsKICAgIHByb3RlY3RlZCAkcmVzcG9uc2VJbmZvID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVhZGVycygkaGVhZGVycykKICAgIHsKICAgICAgICAkdGhpcy0+aGVhZGVycyA9ICRoZWFkZXJzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWFkZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhlYWRlcnM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlc3BvbnNlKCRyZXNwb25zZSkKICAgIHsKICAgICAgICAkdGhpcy0+cmVzcG9uc2UgPSAkcmVzcG9uc2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlc3BvbnNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3BvbnNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGF0dXNDb2RlKCRzdGF0dXNDb2RlKQogICAgewogICAgICAgICR0aGlzLT5zdGF0dXNDb2RlID0gJHN0YXR1c0NvZGU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdHVzQ29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlc3BvbnNlSW5mbygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZXNwb25zZUluZm87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHJlc3BvbnNlSW5mbwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVzcG9uc2VJbmZvKGFycmF5ICRyZXNwb25zZUluZm8pCiAgICB7CiAgICAgICAgJHRoaXMtPnJlc3BvbnNlSW5mbyA9ICRyZXNwb25zZUluZm87CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFN2biBhcyBTdm5VdGlsOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxWY3NSZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CgovKioKICogQGF1dGhvciBCZW4gQmlla2VyIDxtYWlsQGJlbi1iaWVrZXIuZGU+CiAqIEBhdXRob3IgVGlsbCBLbGFtcGFlY2tlbCA8dGlsbEBwaHAubmV0PgogKi8KY2xhc3MgU3ZuRG93bmxvYWRlciBleHRlbmRzIFZjc0Rvd25sb2FkZXIKewogICAgcHJvdGVjdGVkICRjYWNoZUNyZWRlbnRpYWxzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgICAgICBTdm5VdGlsOjpjbGVhbkVudigpOwogICAgICAgICR1dGlsID0gbmV3IFN2blV0aWwoJHVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgaWYgKG51bGwgPT09ICR1dGlsLT5iaW5hcnlWZXJzaW9uKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdzdm4gd2FzIG5vdCBmb3VuZCBpbiB5b3VyIFBBVEgsIHNraXBwaW5nIHNvdXJjZSBkb3dubG9hZCcpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvSW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICBTdm5VdGlsOjpjbGVhbkVudigpOwogICAgICAgICRyZWYgPSAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CgogICAgICAgICRyZXBvID0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKTsKICAgICAgICBpZiAoJHJlcG8gaW5zdGFuY2VvZiBWY3NSZXBvc2l0b3J5KSB7CiAgICAgICAgICAgICRyZXBvQ29uZmlnID0gJHJlcG8tPmdldFJlcG9Db25maWcoKTsKICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3N2bi1jYWNoZS1jcmVkZW50aWFscycsICRyZXBvQ29uZmlnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMgPSAoYm9vbCkgJHJlcG9Db25maWdbJ3N2bi1jYWNoZS1jcmVkZW50aWFscyddOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiBDaGVja2luZyBvdXQgIi4kcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICR0aGlzLT5leGVjdXRlKCRwYWNrYWdlLCAkdXJsLCAic3ZuIGNvIiwgc3ByaW50ZigiJXMvJXMiLCAkdXJsLCAkcmVmKSwgbnVsbCwgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9VcGRhdGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0LCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICBTdm5VdGlsOjpjbGVhbkVudigpOwogICAgICAgICRyZWYgPSAkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+aGFzTWV0YWRhdGFSZXBvc2l0b3J5KCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSAuc3ZuIGRpcmVjdG9yeSBpcyBtaXNzaW5nIGZyb20gJy4kcGF0aC4nLCBzZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvY29tbWl0LWRlcHMgZm9yIG1vcmUgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICR1dGlsID0gbmV3IFN2blV0aWwoJHVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgJGZsYWdzID0gIiI7CiAgICAgICAgaWYgKHZlcnNpb25fY29tcGFyZSgkdXRpbC0+YmluYXJ5VmVyc2lvbigpLCAnMS43LjAnLCAnPj0nKSkgewogICAgICAgICAgICAkZmxhZ3MgLj0gJyAtLWlnbm9yZS1hbmNlc3RyeSc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiBDaGVja2luZyBvdXQgIiAuICRyZWYpOwogICAgICAgICR0aGlzLT5leGVjdXRlKCR0YXJnZXQsICR1cmwsICJzdm4gc3dpdGNoIiAuICRmbGFncywgc3ByaW50ZigiJXMvJXMiLCAkdXJsLCAkcmVmKSwgJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWxDaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgnc3ZuIHN0YXR1cyAtLWlnbm9yZS1leHRlcm5hbHMnLCAkb3V0cHV0LCAkcGF0aCk7CgogICAgICAgIHJldHVybiBwcmVnX21hdGNoKCd7XiAqW15YIF0gK31tJywgJG91dHB1dCkgPyAkb3V0cHV0IDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGUgYW4gU1ZOIGNvbW1hbmQgYW5kIHRyeSB0byBmaXggdXAgdGhlIHByb2Nlc3Mgd2l0aCBjcmVkZW50aWFscwogICAgICogaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGJhc2VVcmwgQmFzZSBVUkwgb2YgdGhlIHJlcG9zaXRvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGNvbW1hbmQgU1ZOIGNvbW1hbmQgdG8gcnVuCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICR1cmwgICAgIFNWTiB1cmwKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJGN3ZCAgICAgV29ya2luZyBkaXJlY3RvcnkKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHBhdGggICAgVGFyZ2V0IGZvciBhIGNoZWNrb3V0CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkYmFzZVVybCwgJGNvbW1hbmQsICR1cmwsICRjd2QgPSBudWxsLCAkcGF0aCA9IG51bGwpCiAgICB7CiAgICAgICAgJHV0aWwgPSBuZXcgU3ZuVXRpbCgkYmFzZVVybCwgJHRoaXMtPmlvLCAkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2Vzcyk7CiAgICAgICAgJHV0aWwtPnNldENhY2hlQ3JlZGVudGlhbHMoJHRoaXMtPmNhY2hlQ3JlZGVudGlhbHMpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiAkdXRpbC0+ZXhlY3V0ZSgkY29tbWFuZCwgJHVybCwgJGN3ZCwgJHBhdGgsICR0aGlzLT5pby0+aXNWZXJib3NlKCkpOwogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBjb3VsZCBub3QgYmUgZG93bmxvYWRlZCwgJy4kZS0+Z2V0TWVzc2FnZSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2xlYW5DaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXBkYXRlKQogICAgewogICAgICAgIGlmICghJGNoYW5nZXMgPSAkdGhpcy0+Z2V0TG9jYWxDaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+aW8tPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJHRoaXMtPmNvbmZpZy0+Z2V0KCdkaXNjYXJkLWNoYW5nZXMnKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5kaXNjYXJkQ2hhbmdlcygkcGF0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ6OmNsZWFuQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgsICR1cGRhdGUpOwogICAgICAgIH0KCiAgICAgICAgJGNoYW5nZXMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRlbGVtKSB7CiAgICAgICAgICAgIHJldHVybiAnICAgICcuJGVsZW07CiAgICAgICAgfSwgcHJlZ19zcGxpdCgne1xzKlxyP1xuXHMqfScsICRjaGFuZ2VzKSk7CiAgICAgICAgJGNvdW50Q2hhbmdlcyA9IGNvdW50KCRjaGFuZ2VzKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignICAgIDxlcnJvcj4nLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBoYXMgbW9kaWZpZWQgZmlsZSVzOjwvZXJyb3I+JywgJGNvdW50Q2hhbmdlcyA9PT0gMSA/ICcnIDogJ3MnKSk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKGFycmF5X3NsaWNlKCRjaGFuZ2VzLCAwLCAxMCkpOwogICAgICAgIGlmICgkY291bnRDaGFuZ2VzID4gMTApIHsKICAgICAgICAgICAgJHJlbWFpbmluZ0NoYW5nZXMgPSAkY291bnRDaGFuZ2VzIC0gMTA7CiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigKICAgICAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJyAgICA8aW5mbz4nLiRyZW1haW5pbmdDaGFuZ2VzLicgbW9yZSBmaWxlJXMgbW9kaWZpZWQsIGNob29zZSAidiIgdG8gdmlldyB0aGUgZnVsbCBsaXN0PC9pbmZvPicsCiAgICAgICAgICAgICAgICAgICAgJHJlbWFpbmluZ0NoYW5nZXMgPT09IDEgPyAnJyA6ICdzJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+aW8tPmFzaygnICAgIDxpbmZvPkRpc2NhcmQgY2hhbmdlcyBbeSxuLHYsP10/PC9pbmZvPiAnLCAnPycpKSB7CiAgICAgICAgICAgICAgICBjYXNlICd5JzoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzY2FyZENoYW5nZXMoJHBhdGgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CgogICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdVcGRhdGUgYWJvcnRlZCcpOwoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkY2hhbmdlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnPyc6CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcihhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICB5IC0gZGlzY2FyZCBjaGFuZ2VzIGFuZCBhcHBseSB0aGUgJy4oJHVwZGF0ZSA/ICd1cGRhdGUnIDogJ3VuaW5zdGFsbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAnICAgIG4gLSBhYm9ydCB0aGUgJy4oJHVwZGF0ZSA/ICd1cGRhdGUnIDogJ3VuaW5zdGFsbCcpLicgYW5kIGxldCB5b3UgbWFudWFsbHkgY2xlYW4gdGhpbmdzIHVwJywKICAgICAgICAgICAgICAgICAgICAgICAgJyAgICB2IC0gdmlldyBtb2RpZmllZCBmaWxlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICcgICAgPyAtIHByaW50IGhlbHAnLAogICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q29tbWl0TG9ncygkZnJvbVJlZmVyZW5jZSwgJHRvUmVmZXJlbmNlLCAkcGF0aCkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgne0AoXGQrKSR9JywgJGZyb21SZWZlcmVuY2UpICYmIHByZWdfbWF0Y2goJ3tAKFxkKykkfScsICR0b1JlZmVyZW5jZSkpIHsKICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIHN2biBiYXNlIHVybCBmcm9tIHRoZSBjaGVja291dCBmb2xkZXIKICAgICAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdzdm4gaW5mbyAtLW5vbi1pbnRlcmFjdGl2ZSAtLXhtbCAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYXRoKSk7CiAgICAgICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJG91dHB1dCwgJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdXJsUGF0dGVybiA9ICcjPHVybD4oLiopPC91cmw+Iyc7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCR1cmxQYXR0ZXJuLCAkb3V0cHV0LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICRiYXNlVXJsID0gJG1hdGNoZXNbMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgJ1VuYWJsZSB0byBkZXRlcm1pbmUgc3ZuIHVybCBmb3IgcGF0aCAnLiAkcGF0aAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3RyaXAgcGF0aHMgZnJvbSByZWZlcmVuY2VzIGFuZCBvbmx5IGtlZXAgdGhlIGFjdHVhbCByZXZpc2lvbgogICAgICAgICAgICAkZnJvbVJldmlzaW9uID0gcHJlZ19yZXBsYWNlKCd7LipAKFxkKykkfScsICckMScsICRmcm9tUmVmZXJlbmNlKTsKICAgICAgICAgICAgJHRvUmV2aXNpb24gPSBwcmVnX3JlcGxhY2UoJ3suKkAoXGQrKSR9JywgJyQxJywgJHRvUmVmZXJlbmNlKTsKCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50Zignc3ZuIGxvZyAtciVzOiVzIC0taW5jcmVtZW50YWwnLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZnJvbVJldmlzaW9uKSwgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJHRvUmV2aXNpb24pKTsKCiAgICAgICAgICAgICR1dGlsID0gbmV3IFN2blV0aWwoJGJhc2VVcmwsICR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwogICAgICAgICAgICAkdXRpbC0+c2V0Q2FjaGVDcmVkZW50aWFscygkdGhpcy0+Y2FjaGVDcmVkZW50aWFscyk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHV0aWwtPmV4ZWN1dGVMb2NhbCgkY29tbWFuZCwgJHBhdGgsIG51bGwsICR0aGlzLT5pby0+aXNWZXJib3NlKCkpOwogICAgICAgICAgICB9IGNhdGNoIChcUnVudGltZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIuJGUtPmdldE1lc3NhZ2UoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICJDb3VsZCBub3QgcmV0cmlldmUgY2hhbmdlcyBiZXR3ZWVuICRmcm9tUmVmZXJlbmNlIGFuZCAkdG9SZWZlcmVuY2UgZHVlIHRvIG1pc3NpbmcgcmV2aXNpb24gaW5mb3JtYXRpb24iOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkaXNjYXJkQ2hhbmdlcygkcGF0aCkKICAgIHsKICAgICAgICBpZiAoMCAhPT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ3N2biByZXZlcnQgLVIgLicsICRvdXRwdXQsICRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkNvdWxkIG5vdCByZXNldCBjaGFuZ2VzXG5cbjoiLiR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzX2RpcigkcGF0aC4nLy5zdm4nKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcUHJvY2Vzc0V4ZWN1dG9yOwp1c2UgQ29tcG9zZXJcVXRpbFxIZyBhcyBIZ1V0aWxzOwoKLyoqCiAqIEBhdXRob3IgUGVyIEJlcm5oYXJkdCA8cGxiQHdlYmZhY3RvcnkuZGU+CiAqLwpjbGFzcyBIZ0Rvd25sb2FkZXIgZXh0ZW5kcyBWY3NEb3dubG9hZGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Eb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgJHVybCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSBIZ1V0aWxzOjpnZXRWZXJzaW9uKCR0aGlzLT5wcm9jZXNzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ2hnIHdhcyBub3QgZm91bmQgaW4geW91ciBQQVRILCBza2lwcGluZyBzb3VyY2UgZG93bmxvYWQnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpCiAgICB7CiAgICAgICAgJGhnVXRpbHMgPSBuZXcgSGdVdGlscygkdGhpcy0+aW8sICR0aGlzLT5jb25maWcsICR0aGlzLT5wcm9jZXNzKTsKCiAgICAgICAgJGNsb25lQ29tbWFuZCA9IGZ1bmN0aW9uICgkdXJsKSB1c2UgKCRwYXRoKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdoZyBjbG9uZSAtLSAlcyAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCkpOwogICAgICAgIH07CgogICAgICAgICRoZ1V0aWxzLT5ydW5Db21tYW5kKCRjbG9uZUNvbW1hbmQsICR1cmwsICRwYXRoKTsKCiAgICAgICAgJHJlZiA9IFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSk7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdoZyB1cCAtLSAlcycsICRyZWYpOwogICAgICAgIGlmICgwICE9PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQsIHJlYWxwYXRoKCRwYXRoKSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAnIC4gJGNvbW1hbmQgLiAiXG5cbiIgLiAkdGhpcy0+cHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9VcGRhdGUoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbCwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0LCAkcGF0aCwgJHVybCkKICAgIHsKICAgICAgICAkaGdVdGlscyA9IG5ldyBIZ1V0aWxzKCR0aGlzLT5pbywgJHRoaXMtPmNvbmZpZywgJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICAkcmVmID0gJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgVXBkYXRpbmcgdG8gIi4kdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKSk7CgogICAgICAgIGlmICghJHRoaXMtPmhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdUaGUgLmhnIGRpcmVjdG9yeSBpcyBtaXNzaW5nIGZyb20gJy4kcGF0aC4nLCBzZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvY29tbWl0LWRlcHMgZm9yIG1vcmUgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICRjb21tYW5kID0gZnVuY3Rpb24gKCR1cmwpIHVzZSAoJHJlZikgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignaGcgcHVsbCAtLSAlcyAmJiBoZyB1cCAtLSAlcycsIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR1cmwpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcmVmKSk7CiAgICAgICAgfTsKCiAgICAgICAgJGhnVXRpbHMtPnJ1bkNvbW1hbmQoJGNvbW1hbmQsICR1cmwsICRwYXRoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvY2FsQ2hhbmdlcyhQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICBpZiAoIWlzX2RpcigkcGF0aC4nLy5oZycpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJ2hnIHN0JywgJG91dHB1dCwgcmVhbHBhdGgoJHBhdGgpKTsKCiAgICAgICAgcmV0dXJuIHRyaW0oJG91dHB1dCkgPzogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpCiAgICB7CiAgICAgICAgJGNvbW1hbmQgPSBzcHJpbnRmKCdoZyBsb2cgLXIgJXM6JXMgLS1zdHlsZSBjb21wYWN0JywgUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGZyb21SZWZlcmVuY2UpLCBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkdG9SZWZlcmVuY2UpKTsKCiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5wcm9jZXNzLT5leGVjdXRlKCRjb21tYW5kLCAkb3V0cHV0LCByZWFscGF0aCgkcGF0aCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzX2RpcigkcGF0aCAuICcvLmhnJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKCi8qKgogKiBYeiBhcmNoaXZlIGRvd25sb2FkZXIuCiAqCiAqIEBhdXRob3IgUGF2ZWwgUHVjaGtpbiA8aUBuZW9hc2NldGljLm1lPgogKiBAYXV0aG9yIFBpZXJyZSBSdWRsb2ZmIDxjb250YWN0QHJ1ZGxvZmYucHJvPgogKi8KY2xhc3MgWHpEb3dubG9hZGVyIGV4dGVuZHMgQXJjaGl2ZURvd25sb2FkZXIKewogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGV4dHJhY3QoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJGZpbGUsICRwYXRoKQogICAgewogICAgICAgICRjb21tYW5kID0gJ3RhciAteEpmICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkgLiAnIC1DICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCk7CgogICAgICAgIGlmICgwID09PSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRwcm9jZXNzRXJyb3IgPSAnRmFpbGVkIHRvIGV4ZWN1dGUgJyAuICRjb21tYW5kIC4gIlxuXG4iIC4gJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCk7CgogICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbigkcHJvY2Vzc0Vycm9yKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKY2xhc3MgTWF4RmlsZVNpemVFeGNlZWRlZEV4Y2VwdGlvbiBleHRlbmRzIFRyYW5zcG9ydEV4Y2VwdGlvbgp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxQYWNrYWdlXER1bXBlclxBcnJheUR1bXBlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uR3Vlc3NlcjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcRmlsZXN5c3RlbTsKdXNlIFJlYWN0XFByb21pc2VcUHJvbWlzZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVXBkYXRlT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxJbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyXE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb247CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KYWJzdHJhY3QgY2xhc3MgVmNzRG93bmxvYWRlciBpbXBsZW1lbnRzIERvd25sb2FkZXJJbnRlcmZhY2UsIENoYW5nZVJlcG9ydEludGVyZmFjZSwgVmNzQ2FwYWJsZURvd25sb2FkZXJJbnRlcmZhY2UKewogICAgLyoqIEB2YXIgSU9JbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkaW87CiAgICAvKiogQHZhciBDb25maWcgKi8KICAgIHByb3RlY3RlZCAkY29uZmlnOwogICAgLyoqIEB2YXIgUHJvY2Vzc0V4ZWN1dG9yICovCiAgICBwcm90ZWN0ZWQgJHByb2Nlc3M7CiAgICAvKiogQHZhciBGaWxlc3lzdGVtICovCiAgICBwcm90ZWN0ZWQgJGZpbGVzeXN0ZW07CiAgICAvKiogQHZhciBhcnJheSAqLwogICAgcHJvdGVjdGVkICRoYXNDbGVhbmVkQ2hhbmdlcyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgQ29uZmlnICRjb25maWcsIFByb2Nlc3NFeGVjdXRvciAkcHJvY2VzcyA9IG51bGwsIEZpbGVzeXN0ZW0gJGZzID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8gPSAkaW87CiAgICAgICAgJHRoaXMtPmNvbmZpZyA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzcyA/OiBuZXcgUHJvY2Vzc0V4ZWN1dG9yKCRpbyk7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZnMgPzogbmV3IEZpbGVzeXN0ZW0oJHRoaXMtPnByb2Nlc3MpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5zdGFsbGF0aW9uU291cmNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3NvdXJjZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICghJHBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdQYWNrYWdlICcuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGlzIG1pc3NpbmcgcmVmZXJlbmNlIGluZm9ybWF0aW9uJyk7CiAgICAgICAgfQoKICAgICAgICAkdXJscyA9ICR0aGlzLT5wcmVwYXJlVXJscygkcGFja2FnZS0+Z2V0U291cmNlVXJscygpKTsKCiAgICAgICAgd2hpbGUgKCR1cmwgPSBhcnJheV9zaGlmdCgkdXJscykpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZG9Eb3dubG9hZCgkcGFja2FnZSwgJHBhdGgsICR1cmwsICRwcmV2UGFja2FnZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIHJldGhyb3cgcGhwdW5pdCBleGNlcHRpb25zIHRvIGF2b2lkIGhhcmQgdG8gZGVidWcgYnVnIGZhaWx1cmVzCiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBcUEhQVW5pdFxGcmFtZXdvcmtcRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0ZhaWxlZDogWycuZ2V0X2NsYXNzKCRlKS4nXSAnLiRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGNvdW50KCR1cmxzKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIEZhaWxlZCwgdHJ5aW5nIHRoZSBuZXh0IFVSTCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFjb3VudCgkdXJscykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByZXBhcmUoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR0eXBlID09PSAndXBkYXRlJykgewogICAgICAgICAgICAkdGhpcy0+Y2xlYW5DaGFuZ2VzKCRwcmV2UGFja2FnZSwgJHBhdGgsIHRydWUpOwogICAgICAgICAgICAkdGhpcy0+aGFzQ2xlYW5lZENoYW5nZXNbJHByZXZQYWNrYWdlLT5nZXRVbmlxdWVOYW1lKCldID0gdHJ1ZTsKICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT09ICdpbnN0YWxsJykgewogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW1wdHlEaXJlY3RvcnkoJHBhdGgpOwogICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gJ3VuaW5zdGFsbCcpIHsKICAgICAgICAgICAgJHRoaXMtPmNsZWFuQ2hhbmdlcygkcGFja2FnZSwgJHBhdGgsIGZhbHNlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhbnVwKCR0eXBlLCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCwgUGFja2FnZUludGVyZmFjZSAkcHJldlBhY2thZ2UgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdHlwZSA9PT0gJ3VwZGF0ZScgJiYgaXNzZXQoJHRoaXMtPmhhc0NsZWFuZWRDaGFuZ2VzWyRwcmV2UGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJlYXBwbHlDaGFuZ2VzKCRwYXRoKTsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmhhc0NsZWFuZWRDaGFuZ2VzWyRwcmV2UGFja2FnZS0+Z2V0VW5pcXVlTmFtZSgpXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICBpZiAoISRwYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUGFja2FnZSAnLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJyBpcyBtaXNzaW5nIHJlZmVyZW5jZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIEluc3RhbGxPcGVyYXRpb246OmZvcm1hdCgkcGFja2FnZSkuJzogJywgZmFsc2UpOwoKICAgICAgICAkdXJscyA9ICR0aGlzLT5wcmVwYXJlVXJscygkcGFja2FnZS0+Z2V0U291cmNlVXJscygpKTsKICAgICAgICB3aGlsZSAoJHVybCA9IGFycmF5X3NoaWZ0KCR1cmxzKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRvSW5zdGFsbCgkcGFja2FnZSwgJHBhdGgsICR1cmwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIHJldGhyb3cgcGhwdW5pdCBleGNlcHRpb25zIHRvIGF2b2lkIGhhcmQgdG8gZGVidWcgYnVnIGZhaWx1cmVzCiAgICAgICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBcUEhQVW5pdFxGcmFtZXdvcmtcRXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0ZhaWxlZDogWycuZ2V0X2NsYXNzKCRlKS4nXSAnLiRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGNvdW50KCR1cmxzKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIEZhaWxlZCwgdHJ5aW5nIHRoZSBuZXh0IFVSTCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFjb3VudCgkdXJscykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVwZGF0ZShQYWNrYWdlSW50ZXJmYWNlICRpbml0aWFsLCBQYWNrYWdlSW50ZXJmYWNlICR0YXJnZXQsICRwYXRoKQogICAgewogICAgICAgIGlmICghJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1BhY2thZ2UgJy4kdGFyZ2V0LT5nZXRQcmV0dHlOYW1lKCkuJyBpcyBtaXNzaW5nIHJlZmVyZW5jZSBpbmZvcm1hdGlvbicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIFVwZGF0ZU9wZXJhdGlvbjo6Zm9ybWF0KCRpbml0aWFsLCAkdGFyZ2V0KS4nOiAnLCBmYWxzZSk7CgogICAgICAgICR1cmxzID0gJHRoaXMtPnByZXBhcmVVcmxzKCR0YXJnZXQtPmdldFNvdXJjZVVybHMoKSk7CgogICAgICAgICRleGNlcHRpb24gPSBudWxsOwogICAgICAgIHdoaWxlICgkdXJsID0gYXJyYXlfc2hpZnQoJHVybHMpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZG9VcGRhdGUoJGluaXRpYWwsICR0YXJnZXQsICRwYXRoLCAkdXJsKTsKCiAgICAgICAgICAgICAgICAkZXhjZXB0aW9uID0gbnVsbDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIC8vIHJldGhyb3cgcGhwdW5pdCBleGNlcHRpb25zIHRvIGF2b2lkIGhhcmQgdG8gZGVidWcgYnVnIGZhaWx1cmVzCiAgICAgICAgICAgICAgICBpZiAoJGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFxQSFBVbml0XEZyYW1ld29ya1xFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZXhjZXB0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdGYWlsZWQ6IFsnLmdldF9jbGFzcygkZXhjZXB0aW9uKS4nXSAnLiRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoY291bnQoJHVybHMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgRmFpbGVkLCB0cnlpbmcgdGhlIG5leHQgVVJMJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHByaW50IHRoZSBjb21taXQgbG9ncyBpZiBpbiB2ZXJib3NlIG1vZGUgYW5kIFZDUyBtZXRhZGF0YSBpcyBwcmVzZW50CiAgICAgICAgLy8gYmVjYXVzZSBpbiBjYXNlIG9mIG1pc3NpbmcgbWV0YWRhdGEgY29kZSB3b3VsZCB0cmlnZ2VyIGFub3RoZXIgZXhjZXB0aW9uCiAgICAgICAgaWYgKCEkZXhjZXB0aW9uICYmICR0aGlzLT5pby0+aXNWZXJib3NlKCkgJiYgJHRoaXMtPmhhc01ldGFkYXRhUmVwb3NpdG9yeSgkcGF0aCkpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAnUHVsbGluZyBpbiBjaGFuZ2VzOic7CiAgICAgICAgICAgICRsb2dzID0gJHRoaXMtPmdldENvbW1pdExvZ3MoJGluaXRpYWwtPmdldFNvdXJjZVJlZmVyZW5jZSgpLCAkdGFyZ2V0LT5nZXRTb3VyY2VSZWZlcmVuY2UoKSwgJHBhdGgpOwoKICAgICAgICAgICAgaWYgKCF0cmltKCRsb2dzKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnUm9sbGluZyBiYWNrIGNoYW5nZXM6JzsKICAgICAgICAgICAgICAgICRsb2dzID0gJHRoaXMtPmdldENvbW1pdExvZ3MoJHRhcmdldC0+Z2V0U291cmNlUmVmZXJlbmNlKCksICRpbml0aWFsLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodHJpbSgkbG9ncykpIHsKICAgICAgICAgICAgICAgICRsb2dzID0gaW1wbG9kZSgiXG4iLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcgICAgICAnIC4gJGxpbmU7CiAgICAgICAgICAgICAgICB9LCBleHBsb2RlKCJcbiIsICRsb2dzKSkpOwoKICAgICAgICAgICAgICAgIC8vIGVzY2FwZSBhbmdsZSBicmFja2V0cyBmb3IgcHJvcGVyIG91dHB1dCBpbiB0aGUgY29uc29sZQogICAgICAgICAgICAgICAgJGxvZ3MgPSBzdHJfcmVwbGFjZSgnPCcsICdcPCcsICRsb2dzKTsKCiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICAnLiRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigkbG9ncyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHVybHMgJiYgJGV4Y2VwdGlvbikgewogICAgICAgICAgICB0aHJvdyAkZXhjZXB0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVW5pbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpKTsKICAgICAgICBpZiAoISR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnkoJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignQ291bGQgbm90IGNvbXBsZXRlbHkgZGVsZXRlICcuJHBhdGguJywgYWJvcnRpbmcuJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmNzUmVmZXJlbmNlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoKQogICAgewogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZ3Vlc3NlciA9IG5ldyBWZXJzaW9uR3Vlc3NlcigkdGhpcy0+Y29uZmlnLCAkdGhpcy0+cHJvY2VzcywgJHBhcnNlcik7CiAgICAgICAgJGR1bXBlciA9IG5ldyBBcnJheUR1bXBlcjsKCiAgICAgICAgJHBhY2thZ2VDb25maWcgPSAkZHVtcGVyLT5kdW1wKCRwYWNrYWdlKTsKICAgICAgICBpZiAoJHBhY2thZ2VWZXJzaW9uID0gJGd1ZXNzZXItPmd1ZXNzVmVyc2lvbigkcGFja2FnZUNvbmZpZywgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFja2FnZVZlcnNpb25bJ2NvbW1pdCddOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByb21wdCB0aGUgdXNlciB0byBjaGVjayBpZiBjaGFuZ2VzIHNob3VsZCBiZSBzdGFzaGVkL3JlbW92ZWQgb3IgdGhlIG9wZXJhdGlvbiBhYm9ydGVkCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAkcGFja2FnZQogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkcGF0aAogICAgICogQHBhcmFtICBib29sICAgICAgICAgICAgICAkdXBkYXRlICBpZiB0cnVlICh1cGRhdGUpIHRoZSBjaGFuZ2VzIGNhbiBiZSBzdGFzaGVkIGFuZCByZWFwcGxpZWQgYWZ0ZXIgYW4gdXBkYXRlLAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBmYWxzZSAocmVtb3ZlKSB0aGUgY2hhbmdlcyBzaG91bGQgYmUgYXNzdW1lZCB0byBiZSBsb3N0IGlmIHRoZSBvcGVyYXRpb24gaXMgbm90IGFib3J0ZWQKICAgICAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gaW4gY2FzZSB0aGUgb3BlcmF0aW9uIG11c3QgYmUgYWJvcnRlZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2xlYW5DaGFuZ2VzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkdXBkYXRlKQogICAgewogICAgICAgIC8vIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGp1c3QgZmFpbHMgaWYgdGhlcmUgYXJlIGFueSBjaGFuZ2VzLCBvdmVycmlkZSBpbiBjaGlsZCBjbGFzc2VzIHRvIHByb3ZpZGUgc3Rhc2gtYWJpbGl0eQogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+Z2V0TG9jYWxDaGFuZ2VzKCRwYWNrYWdlLCAkcGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdTb3VyY2UgZGlyZWN0b3J5ICcgLiAkcGF0aCAuICcgaGFzIHVuY29tbWl0dGVkIGNoYW5nZXMuJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVhcHBseSBwcmV2aW91c2x5IHN0YXNoZXMgY2hhbmdlcyBpZiBhcHBsaWNhYmxlLCBvbmx5IGNhbGxlZCBhZnRlciBhbiB1cGRhdGUgKHJlZ2FyZGxlc3MgaWYgc3VjY2Vzc2Z1bCBvciBub3QpCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAkcGF0aAogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvcGVyYXRpb24gbXVzdCBiZSBhYm9ydGVkIG9yIHRoZSBwYXRjaCBkb2VzIG5vdCBhcHBseSBjbGVhbmx5CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZWFwcGx5Q2hhbmdlcygkcGF0aCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIERvd25sb2FkcyBkYXRhIG5lZWRlZCB0byBydW4gYW4gaW5zdGFsbC91cGRhdGUgbGF0ZXIKICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAgICAgICRwYWNrYWdlICAgICBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICRwYXRoICAgICAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR1cmwgICAgICAgICBwYWNrYWdlIHVybAogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2V8bnVsbCAkcHJldlBhY2thZ2UgcHJldmlvdXMgcGFja2FnZSAoaW4gY2FzZSBvZiBhbiB1cGRhdGUpCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvRG93bmxvYWQoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBEb3dubG9hZHMgc3BlY2lmaWMgcGFja2FnZSBpbnRvIHNwZWNpZmljIGZvbGRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSBwYWNrYWdlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdXJsICAgICBwYWNrYWdlIHVybAogICAgICoKICAgICAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZXxudWxsCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBkb0luc3RhbGwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsICR1cmwpOwoKICAgIC8qKgogICAgICogVXBkYXRlcyBzcGVjaWZpYyBwYWNrYWdlIGluIHNwZWNpZmljIGZvbGRlciBmcm9tIGluaXRpYWwgdG8gdGFyZ2V0IHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwgaW5pdGlhbCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0ICB1cGRhdGVkIHBhY2thZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRwYXRoICAgIGRvd25sb2FkIHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR1cmwgICAgIHBhY2thZ2UgdXJsCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlfG51bGwKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvVXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgsICR1cmwpOwoKICAgIC8qKgogICAgICogRmV0Y2hlcyB0aGUgY29tbWl0IGxvZ3MgYmV0d2VlbiB0d28gY29tbWl0cwogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICRmcm9tUmVmZXJlbmNlIHRoZSBzb3VyY2UgcmVmZXJlbmNlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkdG9SZWZlcmVuY2UgICB0aGUgdGFyZ2V0IHJlZmVyZW5jZQogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGggICAgICAgICAgdGhlIHBhY2thZ2UgcGF0aAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldENvbW1pdExvZ3MoJGZyb21SZWZlcmVuY2UsICR0b1JlZmVyZW5jZSwgJHBhdGgpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIFZDUyBtZXRhZGF0YSByZXBvc2l0b3J5IGhhcyBiZWVuIGluaXRpYWxpemVkCiAgICAgKiByZXBvc2l0b3J5IGV4YW1wbGU6IC5naXR8LnN2bnwuaGcKICAgICAqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBoYXNNZXRhZGF0YVJlcG9zaXRvcnkoJHBhdGgpOwoKICAgIHByaXZhdGUgZnVuY3Rpb24gcHJlcGFyZVVybHMoYXJyYXkgJHVybHMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHVybHMgYXMgJGluZGV4ID0+ICR1cmwpIHsKICAgICAgICAgICAgaWYgKEZpbGVzeXN0ZW06OmlzTG9jYWxQYXRoKCR1cmwpKSB7CiAgICAgICAgICAgICAgICAvLyByZWFscGF0aCgpIGJlbG93IHdpbGwgbm90IHVuZGVyc3RhbmQKICAgICAgICAgICAgICAgIC8vIHVybCB0aGF0IHN0YXJ0cyB3aXRoICJmaWxlOi8vIgogICAgICAgICAgICAgICAgJGZpbGVQcm90b2NvbCA9ICdmaWxlOi8vJzsKICAgICAgICAgICAgICAgICRpc0ZpbGVQcm90b2NvbCA9IGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygkdXJsLCAkZmlsZVByb3RvY29sKSkgewogICAgICAgICAgICAgICAgICAgICR1cmwgPSBzdWJzdHIoJHVybCwgc3RybGVuKCRmaWxlUHJvdG9jb2wpKTsKICAgICAgICAgICAgICAgICAgICAkaXNGaWxlUHJvdG9jb2wgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHJlYWxwYXRoKCkgYmVsb3cgd2lsbCBub3QgdW5kZXJzdGFuZCAlMjAgc3BhY2VzIGV0Yy4KICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCR1cmwsICclJykpIHsKICAgICAgICAgICAgICAgICAgICAkdXJsID0gcmF3dXJsZGVjb2RlKCR1cmwpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR1cmxzWyRpbmRleF0gPSByZWFscGF0aCgkdXJsKTsKCiAgICAgICAgICAgICAgICBpZiAoJGlzRmlsZVByb3RvY29sKSB7CiAgICAgICAgICAgICAgICAgICAgJHVybHNbJGluZGV4XSA9ICRmaWxlUHJvdG9jb2wgLiAkdXJsc1skaW5kZXhdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHVybHM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxVdGlsXEluaUhlbHBlcjsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhlY3V0YWJsZUZpbmRlcjsKdXNlIFppcEFyY2hpdmU7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgWmlwRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGhhc1N5c3RlbVVuemlwOwogICAgcHJpdmF0ZSBzdGF0aWMgJGhhc1ppcEFyY2hpdmU7CiAgICBwcml2YXRlIHN0YXRpYyAkaXNXaW5kb3dzOwoKICAgIC8qKiBAdmFyIFppcEFyY2hpdmV8bnVsbCAqLwogICAgcHJpdmF0ZSAkemlwQXJjaGl2ZU9iamVjdDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaGFzU3lzdGVtVW56aXApIHsKICAgICAgICAgICAgJGZpbmRlciA9IG5ldyBFeGVjdXRhYmxlRmluZGVyOwogICAgICAgICAgICBzZWxmOjokaGFzU3lzdGVtVW56aXAgPSAoYm9vbCkgJGZpbmRlci0+ZmluZCgndW56aXAnKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaGFzWmlwQXJjaGl2ZSkgewogICAgICAgICAgICBzZWxmOjokaGFzWmlwQXJjaGl2ZSA9IGNsYXNzX2V4aXN0cygnWmlwQXJjaGl2ZScpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFzZWxmOjokaGFzWmlwQXJjaGl2ZSAmJiAhc2VsZjo6JGhhc1N5c3RlbVVuemlwKSB7CiAgICAgICAgICAgIC8vIHBocC5pbmkgcGF0aCBpcyBhZGRlZCB0byB0aGUgZXJyb3IgbWVzc2FnZSB0byBoZWxwIHVzZXJzIGZpbmQgdGhlIGNvcnJlY3QgZmlsZQogICAgICAgICAgICAkaW5pTWVzc2FnZSA9IEluaUhlbHBlcjo6Z2V0TWVzc2FnZSgpOwogICAgICAgICAgICAkZXJyb3IgPSAiVGhlIHppcCBleHRlbnNpb24gYW5kIHVuemlwIGNvbW1hbmQgYXJlIGJvdGggbWlzc2luZywgc2tpcHBpbmcuXG4iIC4gJGluaU1lc3NhZ2U7CgogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaXNXaW5kb3dzKSB7CiAgICAgICAgICAgIHNlbGY6OiRpc1dpbmRvd3MgPSBQbGF0Zm9ybTo6aXNXaW5kb3dzKCk7CgogICAgICAgICAgICBpZiAoIXNlbGY6OiRpc1dpbmRvd3MgJiYgIXNlbGY6OiRoYXNTeXN0ZW1VbnppcCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCI8d2FybmluZz5BcyB0aGVyZSBpcyBubyAndW56aXAnIGNvbW1hbmQgaW5zdGFsbGVkIHppcCBmaWxlcyBhcmUgYmVpbmcgdW5wYWNrZWQgdXNpbmcgdGhlIFBIUCB6aXAgZXh0ZW5zaW9uLjwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiPHdhcm5pbmc+VGhpcyBtYXkgY2F1c2UgaW52YWxpZCByZXBvcnRzIG9mIGNvcnJ1cHRlZCBhcmNoaXZlcy4gQmVzaWRlcywgYW55IFVOSVggcGVybWlzc2lvbnMgKGUuZy4gZXhlY3V0YWJsZSkgZGVmaW5lZCBpbiB0aGUgYXJjaGl2ZXMgd2lsbCBiZSBsb3N0Ljwvd2FybmluZz4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiPHdhcm5pbmc+SW5zdGFsbGluZyAndW56aXAnIG1heSByZW1lZGlhdGUgdGhlbS48L3dhcm5pbmc+Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBwYXJlbnQ6OmRvd25sb2FkKCRwYWNrYWdlLCAkcGF0aCwgJHByZXZQYWNrYWdlLCAkb3V0cHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIGV4dHJhY3QgJGZpbGUgdG8gJHBhdGggd2l0aCAidW56aXAiIGNvbW1hbmQKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlICAgICAgICAgRmlsZSB0byBleHRyYWN0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoICAgICAgICAgUGF0aCB3aGVyZSB0byBleHRyYWN0IGZpbGUKICAgICAqIEBwYXJhbSBib29sICAgJGlzTGFzdENoYW5jZSBJZiB0cnVlIGl0IGlzIGNhbGxlZCBhcyBhIGZhbGxiYWNrIGFuZCBzaG91bGQgdGhyb3cgYW4gZXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdFdpdGhTeXN0ZW1VbnppcChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgsICRpc0xhc3RDaGFuY2UsICRhc3luYyA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghc2VsZjo6JGhhc1ppcEFyY2hpdmUpIHsKICAgICAgICAgICAgLy8gRm9yY2UgRXhjZXB0aW9uIHRocm93aW5nIGlmIHRoZSBPdGhlciBhbHRlcm5hdGl2ZSBpcyBub3QgYXZhaWxhYmxlCiAgICAgICAgICAgICRpc0xhc3RDaGFuY2UgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFzZWxmOjokaGFzU3lzdGVtVW56aXAgJiYgISRpc0xhc3RDaGFuY2UpIHsKICAgICAgICAgICAgLy8gVGhpcyB3YXMgY2FsbCBhcyB0aGUgZmF2b3JpdGUgZXh0cmFjdCB3YXksIGJ1dCBpcyBub3QgYXZhaWxhYmxlCiAgICAgICAgICAgIC8vIFdlIHN3aXRjaCB0byB0aGUgYWx0ZXJuYXRpdmUKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0V2l0aFppcEFyY2hpdmUoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXaGVuIGNhbGxlZCBhZnRlciBhIFppcEFyY2hpdmUgZmFpbGVkLCBwZXJoYXBzIHRoZXJlIGlzIHNvbWUgZmlsZXMgdG8gb3ZlcndyaXRlCiAgICAgICAgJG92ZXJ3cml0ZSA9ICRpc0xhc3RDaGFuY2UgPyAnLW8nIDogJyc7CiAgICAgICAgJGNvbW1hbmQgPSAndW56aXAgLXFxICcuJG92ZXJ3cml0ZS4nICcuUHJvY2Vzc0V4ZWN1dG9yOjplc2NhcGUoJGZpbGUpLicgLWQgJy5Qcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkcGF0aCk7CgogICAgICAgIGlmICgkYXN5bmMpIHsKICAgICAgICAgICAgJHNlbGYgPSAkdGhpczsKICAgICAgICAgICAgJGlvID0gJHRoaXMtPmlvOwogICAgICAgICAgICAkdHJ5RmFsbGJhY2sgPSBmdW5jdGlvbiAoJHByb2Nlc3NFcnJvcikgdXNlICgkaXNMYXN0Q2hhbmNlLCAkaW8sICRzZWxmLCAkZmlsZSwgJHBhdGgsICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGlzTGFzdENoYW5jZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRwcm9jZXNzRXJyb3I7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPicuJHByb2Nlc3NFcnJvci0+Z2V0TWVzc2FnZSgpLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgPHdhcm5pbmc+VGhpcyBtb3N0IGxpa2VseSBpcyBkdWUgdG8gYSBjdXN0b20gaW5zdGFsbGVyIHBsdWdpbiBub3QgaGFuZGxpbmcgdGhlIHJldHVybmVkIFByb21pc2UgZnJvbSB0aGUgZG93bmxvYWRlcjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz5TZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2luc3RhbGxlcnMvY29tbWl0LzUwMDZkMGMyODczMGFkZTIzM2E4ZjQyZWMzMWFjNjhmYjFjNWM5YmIgZm9yIGFuIGV4YW1wbGUgZml4PC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJyAgICA8d2FybmluZz4nLiRwcm9jZXNzRXJyb3ItPmdldE1lc3NhZ2UoKS4nPC93YXJuaW5nPicpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIFRoZSBhcmNoaXZlIG1heSBjb250YWluIGlkZW50aWNhbCBmaWxlIG5hbWVzIHdpdGggZGlmZmVyZW50IGNhcGl0YWxpemF0aW9uICh3aGljaCBmYWlscyBvbiBjYXNlIGluc2Vuc2l0aXZlIGZpbGVzeXN0ZW1zKScpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIFVuemlwIHdpdGggdW56aXAgY29tbWFuZCBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byBaaXBBcmNoaXZlIGNsYXNzJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRzZWxmLT5leHRyYWN0V2l0aFppcEFyY2hpdmUoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgdHJ1ZSk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZUFzeW5jKCRjb21tYW5kKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHByb21pc2UtPnRoZW4oZnVuY3Rpb24gKCRwcm9jZXNzKSB1c2UgKCR0cnlGYWxsYmFjaywgJGNvbW1hbmQsICRwYWNrYWdlLCAkZmlsZSkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXRwdXQgPSAkcHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG91dHB1dCA9IHN0cl9yZXBsYWNlKCcsICcuJGZpbGUuJy56aXAgb3IgJy4kZmlsZS4nLlpJUCcsICcnLCAkb3V0cHV0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdHJ5RmFsbGJhY2sobmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXh0cmFjdCAnLiRwYWNrYWdlLT5nZXROYW1lKCkuJzogKCcuJHByb2Nlc3MtPmdldEV4aXRDb2RlKCkuJykgJy4kY29tbWFuZC4iXG5cbiIuJG91dHB1dCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRyeUZhbGxiYWNrKCRlKTsKICAgICAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0cnlGYWxsYmFjaygkZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwcm9jZXNzRXJyb3IgPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgwID09PSAkZXhpdENvZGUgPSAkdGhpcy0+cHJvY2Vzcy0+ZXhlY3V0ZSgkY29tbWFuZCwgJGlnbm9yZWRPdXRwdXQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSAoJy4kZXhpdENvZGUuJykgJy4kY29tbWFuZC4iXG5cbiIuJHRoaXMtPnByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHByb2Nlc3NFcnJvciA9ICRlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpc0xhc3RDaGFuY2UpIHsKICAgICAgICAgICAgdGhyb3cgJHByb2Nlc3NFcnJvcjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignICAgIDx3YXJuaW5nPicuJHByb2Nlc3NFcnJvci0+Z2V0TWVzc2FnZSgpLic8L3dhcm5pbmc+Jyk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgVGhlIGFyY2hpdmUgbWF5IGNvbnRhaW4gaWRlbnRpY2FsIGZpbGUgbmFtZXMgd2l0aCBkaWZmZXJlbnQgY2FwaXRhbGl6YXRpb24gKHdoaWNoIGZhaWxzIG9uIGNhc2UgaW5zZW5zaXRpdmUgZmlsZXN5c3RlbXMpJyk7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgVW56aXAgd2l0aCB1bnppcCBjb21tYW5kIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvIFppcEFyY2hpdmUgY2xhc3MnKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0V2l0aFppcEFyY2hpdmUoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBleHRyYWN0ICRmaWxlIHRvICRwYXRoIHdpdGggWmlwQXJjaGl2ZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgICAgICAgICBGaWxlIHRvIGV4dHJhY3QKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggICAgICAgICBQYXRoIHdoZXJlIHRvIGV4dHJhY3QgZmlsZQogICAgICogQHBhcmFtIGJvb2wgICAkaXNMYXN0Q2hhbmNlIElmIHRydWUgaXQgaXMgY2FsbGVkIGFzIGEgZmFsbGJhY2sgYW5kIHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24KICAgICAqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByb3RlY3RlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXh0cmFjdFdpdGhaaXBBcmNoaXZlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgJGlzTGFzdENoYW5jZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRoYXNTeXN0ZW1VbnppcCkgewogICAgICAgICAgICAvLyBGb3JjZSBFeGNlcHRpb24gdGhyb3dpbmcgaWYgdGhlIE90aGVyIGFsdGVybmF0aXZlIGlzIG5vdCBhdmFpbGFibGUKICAgICAgICAgICAgJGlzTGFzdENoYW5jZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXNlbGY6OiRoYXNaaXBBcmNoaXZlICYmICEkaXNMYXN0Q2hhbmNlKSB7CiAgICAgICAgICAgIC8vIFRoaXMgd2FzIGNhbGwgYXMgdGhlIGZhdm9yaXRlIGV4dHJhY3Qgd2F5LCBidXQgaXMgbm90IGF2YWlsYWJsZQogICAgICAgICAgICAvLyBXZSBzd2l0Y2ggdG8gdGhlIGFsdGVybmF0aXZlCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXh0cmFjdFdpdGhTeXN0ZW1VbnppcCgkcGFja2FnZSwgJGZpbGUsICRwYXRoLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgICRwcm9jZXNzRXJyb3IgPSBudWxsOwogICAgICAgICR6aXBBcmNoaXZlID0gJHRoaXMtPnppcEFyY2hpdmVPYmplY3QgPzogbmV3IFppcEFyY2hpdmUoKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHRydWUgPT09ICgkcmV0dmFsID0gJHppcEFyY2hpdmUtPm9wZW4oJGZpbGUpKSkgewogICAgICAgICAgICAgICAgJGV4dHJhY3RSZXN1bHQgPSAkemlwQXJjaGl2ZS0+ZXh0cmFjdFRvKCRwYXRoKTsKCiAgICAgICAgICAgICAgICBpZiAodHJ1ZSA9PT0gJGV4dHJhY3RSZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICAkemlwQXJjaGl2ZS0+Y2xvc2UoKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFxSZWFjdFxQcm9taXNlXHJlc29sdmUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gbmV3IFxSdW50aW1lRXhjZXB0aW9uKHJ0cmltKCJUaGVyZSB3YXMgYW4gZXJyb3IgZXh0cmFjdGluZyB0aGUgWklQIGZpbGUsIGl0IGlzIGVpdGhlciBjb3JydXB0ZWQgb3IgdXNpbmcgYW4gaW52YWxpZCBmb3JtYXQuXG4iKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24ocnRyaW0oJHRoaXMtPmdldEVycm9yTWVzc2FnZSgkcmV0dmFsLCAkZmlsZSkuIlxuIiksICRyZXR2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXEVycm9yRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICRwcm9jZXNzRXJyb3IgPSBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoZSBhcmNoaXZlIG1heSBjb250YWluIGlkZW50aWNhbCBmaWxlIG5hbWVzIHdpdGggZGlmZmVyZW50IGNhcGl0YWxpemF0aW9uICh3aGljaCBmYWlscyBvbiBjYXNlIGluc2Vuc2l0aXZlIGZpbGVzeXN0ZW1zKTogJy4kZS0+Z2V0TWVzc2FnZSgpLCAwLCAkZSk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gJGU7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gJGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlzTGFzdENoYW5jZSkgewogICAgICAgICAgICB0aHJvdyAkcHJvY2Vzc0Vycm9yOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcgICAgPHdhcm5pbmc+Jy4kcHJvY2Vzc0Vycm9yLT5nZXRNZXNzYWdlKCkuJzwvd2FybmluZz4nKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgICBVbnppcCB3aXRoIFppcEFyY2hpdmUgY2xhc3MgZmFpbGVkLCBmYWxsaW5nIGJhY2sgdG8gdW56aXAgY29tbWFuZCcpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4dHJhY3RXaXRoU3lzdGVtVW56aXAoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBleHRyYWN0ICRmaWxlIHRvICRwYXRoCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBGaWxlIHRvIGV4dHJhY3QKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB3aGVyZSB0byBleHRyYWN0IGZpbGUKICAgICAqCiAgICAgKiBUT0RPIHYzIHNob3VsZCBtYWtlIHRoaXMgcHJpdmF0ZSBvbmNlIHdlIGNhbiBkcm9wIFBIUCA1LjMgc3VwcG9ydAogICAgICogQHByb3RlY3RlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXh0cmFjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkZmlsZSwgJHBhdGgpCiAgICB7CiAgICAgICAgLy8gRWFjaCBleHRyYWN0IGNhbGxzIGl0cyBhbHRlcm5hdGl2ZSBpZiBub3QgYXZhaWxhYmxlIG9yIGZhaWxzCiAgICAgICAgaWYgKHNlbGY6OiRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0V2l0aFppcEFyY2hpdmUoJHBhY2thZ2UsICRmaWxlLCAkcGF0aCwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0V2l0aFN5c3RlbVVuemlwKCRwYWNrYWdlLCAkZmlsZSwgJHBhdGgsIGZhbHNlLCB0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdpdmUgYSBtZWFuaW5nZnVsIGVycm9yIG1lc3NhZ2UgdG8gdGhlIHVzZXIuCiAgICAgKgogICAgICogQHBhcmFtICBpbnQgICAgJHJldHZhbAogICAgICogQHBhcmFtICBzdHJpbmcgJGZpbGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRFcnJvck1lc3NhZ2UoJHJldHZhbCwgJGZpbGUpCiAgICB7CiAgICAgICAgc3dpdGNoICgkcmV0dmFsKSB7CiAgICAgICAgICAgIGNhc2UgWmlwQXJjaGl2ZTo6RVJfRVhJU1RTOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIkZpbGUgJyVzJyBhbHJlYWR5IGV4aXN0cy4iLCAkZmlsZSk7CiAgICAgICAgICAgIGNhc2UgWmlwQXJjaGl2ZTo6RVJfSU5DT05TOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIlppcCBhcmNoaXZlICclcycgaXMgaW5jb25zaXN0ZW50LiIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9JTlZBTDoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCJJbnZhbGlkIGFyZ3VtZW50ICglcykiLCAkZmlsZSk7CiAgICAgICAgICAgIGNhc2UgWmlwQXJjaGl2ZTo6RVJfTUVNT1JZOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIk1hbGxvYyBmYWlsdXJlICglcykiLCAkZmlsZSk7CiAgICAgICAgICAgIGNhc2UgWmlwQXJjaGl2ZTo6RVJfTk9FTlQ6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiTm8gc3VjaCB6aXAgZmlsZTogJyVzJyIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9OT1pJUDoKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCInJXMnIGlzIG5vdCBhIHppcCBhcmNoaXZlLiIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9PUEVOOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIkNhbid0IG9wZW4gemlwIGZpbGU6ICVzIiwgJGZpbGUpOwogICAgICAgICAgICBjYXNlIFppcEFyY2hpdmU6OkVSX1JFQUQ6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiWmlwIHJlYWQgZXJyb3IgKCVzKSIsICRmaWxlKTsKICAgICAgICAgICAgY2FzZSBaaXBBcmNoaXZlOjpFUl9TRUVLOgogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIlppcCBzZWVrIGVycm9yICglcykiLCAkZmlsZSk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ByaW50ZigiJyVzJyBpcyBub3QgYSB2YWxpZCB6aXAgYXJjaGl2ZSwgZ290IGVycm9yIGNvZGU6ICVzIiwgJGZpbGUsICRyZXR2YWwpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEb3dubG9hZGVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFV0aWxcUGxhdGZvcm07CnVzZSBDb21wb3NlclxVdGlsXFByb2Nlc3NFeGVjdXRvcjsKCi8qKgogKiBHWmlwIGFyY2hpdmUgZG93bmxvYWRlci4KICoKICogQGF1dGhvciBQYXZlbCBQdWNoa2luIDxpQG5lb2FzY2V0aWMubWU+CiAqLwpjbGFzcyBHemlwRG93bmxvYWRlciBleHRlbmRzIEFyY2hpdmVEb3dubG9hZGVyCnsKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleHRyYWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRmaWxlLCAkcGF0aCkKICAgIHsKICAgICAgICAkZmlsZW5hbWUgPSBwYXRoaW5mbyhwYXJzZV91cmwoJHBhY2thZ2UtPmdldERpc3RVcmwoKSwgUEhQX1VSTF9QQVRIKSwgUEFUSElORk9fRklMRU5BTUUpOwogICAgICAgICR0YXJnZXRGaWxlcGF0aCA9ICRwYXRoIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRmaWxlbmFtZTsKCiAgICAgICAgLy8gVHJ5IHRvIHVzZSBndW56aXAgb24gKm5peAogICAgICAgIGlmICghUGxhdGZvcm06OmlzV2luZG93cygpKSB7CiAgICAgICAgICAgICRjb21tYW5kID0gJ2d6aXAgLWNkIC0tICcgLiBQcm9jZXNzRXhlY3V0b3I6OmVzY2FwZSgkZmlsZSkgLiAnID4gJyAuIFByb2Nlc3NFeGVjdXRvcjo6ZXNjYXBlKCR0YXJnZXRGaWxlcGF0aCk7CgogICAgICAgICAgICBpZiAoMCA9PT0gJHRoaXMtPnByb2Nlc3MtPmV4ZWN1dGUoJGNvbW1hbmQsICRpZ25vcmVkT3V0cHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZXh0ZW5zaW9uX2xvYWRlZCgnemxpYicpKSB7CiAgICAgICAgICAgICAgICAvLyBGYWxsYmFjayB0byB1c2luZyB0aGUgUEhQIGV4dGVuc2lvbi4KICAgICAgICAgICAgICAgICR0aGlzLT5leHRyYWN0VXNpbmdFeHQoJGZpbGUsICR0YXJnZXRGaWxlcGF0aCk7CgogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJvY2Vzc0Vycm9yID0gJ0ZhaWxlZCB0byBleGVjdXRlICcgLiAkY29tbWFuZCAuICJcblxuIiAuICR0aGlzLT5wcm9jZXNzLT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJHByb2Nlc3NFcnJvcik7CiAgICAgICAgfQoKICAgICAgICAvLyBXaW5kb3dzIHZlcnNpb24gb2YgUEhQIGhhcyBidWlsdC1pbiBzdXBwb3J0IG9mIGd6aXAgZnVuY3Rpb25zCiAgICAgICAgJHRoaXMtPmV4dHJhY3RVc2luZ0V4dCgkZmlsZSwgJHRhcmdldEZpbGVwYXRoKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RVc2luZ0V4dCgkZmlsZSwgJHRhcmdldEZpbGVwYXRoKQogICAgewogICAgICAgICRhcmNoaXZlRmlsZSA9IGd6b3BlbigkZmlsZSwgJ3JiJyk7CiAgICAgICAgJHRhcmdldEZpbGUgPSBmb3BlbigkdGFyZ2V0RmlsZXBhdGgsICd3YicpOwogICAgICAgIHdoaWxlICgkc3RyaW5nID0gZ3pyZWFkKCRhcmNoaXZlRmlsZSwgNDA5NikpIHsKICAgICAgICAgICAgZndyaXRlKCR0YXJnZXRGaWxlLCAkc3RyaW5nLCBQbGF0Zm9ybTo6c3RybGVuKCRzdHJpbmcpKTsKICAgICAgICB9CiAgICAgICAgZ3pjbG9zZSgkYXJjaGl2ZUZpbGUpOwogICAgICAgIGZjbG9zZSgkdGFyZ2V0RmlsZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRG93bmxvYWRlcjsKCnVzZSBDb21wb3NlclxDb25maWc7CnVzZSBDb21wb3NlclxDYWNoZTsKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcSU9cTnVsbElPOwp1c2UgQ29tcG9zZXJcRXhjZXB0aW9uXElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbjsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQ29tcGFyZXJcQ29tcGFyZXI7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uXFVwZGF0ZU9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbjsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb25cVW5pbnN0YWxsT3BlcmF0aW9uOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFBsdWdpbkV2ZW50czsKdXNlIENvbXBvc2VyXFBsdWdpblxQb3N0RmlsZURvd25sb2FkRXZlbnQ7CnVzZSBDb21wb3NlclxQbHVnaW5cUHJlRmlsZURvd25sb2FkRXZlbnQ7CnVzZSBDb21wb3NlclxFdmVudERpc3BhdGNoZXJcRXZlbnREaXNwYXRjaGVyOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIENvbXBvc2VyXFV0aWxcSHR0cERvd25sb2FkZXI7CnVzZSBDb21wb3NlclxVdGlsXFVybCBhcyBVcmxVdGlsOwp1c2UgQ29tcG9zZXJcVXRpbFxQcm9jZXNzRXhlY3V0b3I7CnVzZSBSZWFjdFxQcm9taXNlXFByb21pc2VJbnRlcmZhY2U7CgovKioKICogQmFzZSBkb3dubG9hZGVyIGZvciBmaWxlcwogKgogKiBAYXV0aG9yIEtpcmlsbCBjaEViYmEgQ2hlYnVuaW4gPGlhbUBjaGViYmEub3JnPgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqIEBhdXRob3IgRnJhbsOnb2lzIFBsdWNoaW5vIDxmcmFuY29pcy5wbHVjaGlub0BvcGVuZGlzcGxheS5jb20+CiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBGaWxlRG93bmxvYWRlciBpbXBsZW1lbnRzIERvd25sb2FkZXJJbnRlcmZhY2UsIENoYW5nZVJlcG9ydEludGVyZmFjZQp7CiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKICAgIC8qKiBAdmFyIENvbmZpZyAqLwogICAgcHJvdGVjdGVkICRjb25maWc7CiAgICAvKiogQHZhciBIdHRwRG93bmxvYWRlciAqLwogICAgcHJvdGVjdGVkICRodHRwRG93bmxvYWRlcjsKICAgIC8qKiBAdmFyIEZpbGVzeXN0ZW0gKi8KICAgIHByb3RlY3RlZCAkZmlsZXN5c3RlbTsKICAgIC8qKiBAdmFyIENhY2hlICovCiAgICBwcm90ZWN0ZWQgJGNhY2hlOwogICAgLyoqIEB2YXIgRXZlbnREaXNwYXRjaGVyICovCiAgICBwcm90ZWN0ZWQgJGV2ZW50RGlzcGF0Y2hlcjsKICAgIC8qKiBAdmFyIFByb2Nlc3NFeGVjdXRvciAqLwogICAgcHJvdGVjdGVkICRwcm9jZXNzOwogICAgLyoqCiAgICAgKiBAcHJpdmF0ZSB0aGlzIGlzIG9ubHkgcHVibGljIGZvciBwaHAgNS4zIHN1cHBvcnQgaW4gY2xvc3VyZXMKICAgICAqLwogICAgcHVibGljICRsYXN0Q2FjaGVXcml0ZXMgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkYWRkaXRpb25hbENsZWFudXBQYXRocyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gSU9JbnRlcmZhY2UgICAgICRpbyAgICAgICAgICAgICAgVGhlIElPIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gQ29uZmlnICAgICAgICAgICRjb25maWcgICAgICAgICAgVGhlIGNvbmZpZwogICAgICogQHBhcmFtIEh0dHBEb3dubG9hZGVyICAkaHR0cERvd25sb2FkZXIgIFRoZSByZW1vdGUgZmlsZXN5c3RlbQogICAgICogQHBhcmFtIEV2ZW50RGlzcGF0Y2hlciAkZXZlbnREaXNwYXRjaGVyIFRoZSBldmVudCBkaXNwYXRjaGVyCiAgICAgKiBAcGFyYW0gQ2FjaGUgICAgICAgICAgICRjYWNoZSAgICAgICAgICAgQ2FjaGUgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBGaWxlc3lzdGVtICAgICAgJGZpbGVzeXN0ZW0gICAgICBUaGUgZmlsZXN5c3RlbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoSU9JbnRlcmZhY2UgJGlvLCBDb25maWcgJGNvbmZpZywgSHR0cERvd25sb2FkZXIgJGh0dHBEb3dubG9hZGVyLCBFdmVudERpc3BhdGNoZXIgJGV2ZW50RGlzcGF0Y2hlciA9IG51bGwsIENhY2hlICRjYWNoZSA9IG51bGwsIEZpbGVzeXN0ZW0gJGZpbGVzeXN0ZW0gPSBudWxsLCBQcm9jZXNzRXhlY3V0b3IgJHByb2Nlc3MgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgICAgICAkdGhpcy0+Y29uZmlnID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyID0gJGV2ZW50RGlzcGF0Y2hlcjsKICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXIgPSAkaHR0cERvd25sb2FkZXI7CiAgICAgICAgJHRoaXMtPmNhY2hlID0gJGNhY2hlOwogICAgICAgICR0aGlzLT5wcm9jZXNzID0gJHByb2Nlc3MgPzogbmV3IFByb2Nlc3NFeGVjdXRvcigkaW8pOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtID0gJGZpbGVzeXN0ZW0gPzogbmV3IEZpbGVzeXN0ZW0oJHRoaXMtPnByb2Nlc3MpOwoKICAgICAgICBpZiAoJHRoaXMtPmNhY2hlICYmICR0aGlzLT5jYWNoZS0+Z2NJc05lY2Vzc2FyeSgpKSB7CiAgICAgICAgICAgICR0aGlzLT5jYWNoZS0+Z2MoJGNvbmZpZy0+Z2V0KCdjYWNoZS1maWxlcy10dGwnKSwgJGNvbmZpZy0+Z2V0KCdjYWNoZS1maWxlcy1tYXhzaXplJykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluc3RhbGxhdGlvblNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdkaXN0JzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvd25sb2FkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwsICRvdXRwdXQgPSB0cnVlKQogICAgewogICAgICAgIGlmICghJHBhY2thZ2UtPmdldERpc3RVcmwoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIGdpdmVuIHBhY2thZ2UgaXMgbWlzc2luZyB1cmwgaW5mb3JtYXRpb24nKTsKICAgICAgICB9CgogICAgICAgICRjYWNoZUtleUdlbmVyYXRvciA9IGZ1bmN0aW9uIChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAka2V5KSB7CiAgICAgICAgICAgICRjYWNoZUtleSA9IHNoYTEoJGtleSk7CgogICAgICAgICAgICByZXR1cm4gJHBhY2thZ2UtPmdldE5hbWUoKS4nLycuJGNhY2hlS2V5LicuJy4kcGFja2FnZS0+Z2V0RGlzdFR5cGUoKTsKICAgICAgICB9OwoKICAgICAgICAkcmV0cmllcyA9IDM7CiAgICAgICAgJHVybHMgPSAkcGFja2FnZS0+Z2V0RGlzdFVybHMoKTsKICAgICAgICBmb3JlYWNoICgkdXJscyBhcyAkaW5kZXggPT4gJHVybCkgewogICAgICAgICAgICAkcHJvY2Vzc2VkVXJsID0gJHRoaXMtPnByb2Nlc3NVcmwoJHBhY2thZ2UsICR1cmwpOwogICAgICAgICAgICAkdXJsc1skaW5kZXhdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnYmFzZScgPT4gJHVybCwKICAgICAgICAgICAgICAgICdwcm9jZXNzZWQnID0+ICRwcm9jZXNzZWRVcmwsCiAgICAgICAgICAgICAgICAvLyB3ZSB1c2UgdGhlIGNvbXBsZXRlIGRvd25sb2FkIHVybCBoZXJlIHRvIGF2b2lkIGNvbmZsaWN0aW5nIGVudHJpZXMKICAgICAgICAgICAgICAgIC8vIGZyb20gZGlmZmVyZW50IHBhY2thZ2VzLCB3aGljaCB3b3VsZCBwb3RlbnRpYWxseSBhbGxvdyBhIGdpdmVuIHBhY2thZ2UKICAgICAgICAgICAgICAgIC8vIGluIGEgdGhpcmQgcGFydHkgcmVwbyB0byBwcmUtcG9wdWxhdGUgdGhlIGNhY2hlIGZvciB0aGUgc2FtZSBwYWNrYWdlIGluCiAgICAgICAgICAgICAgICAvLyBwYWNrYWdpc3QgZm9yIGV4YW1wbGUuCiAgICAgICAgICAgICAgICAnY2FjaGVLZXknID0+ICRjYWNoZUtleUdlbmVyYXRvcigkcGFja2FnZSwgJHByb2Nlc3NlZFVybCksCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkZmlsZU5hbWUgPSAkdGhpcy0+Z2V0RmlsZU5hbWUoJHBhY2thZ2UsICRwYXRoKTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKCRwYXRoKTsKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW5zdXJlRGlyZWN0b3J5RXhpc3RzKGRpcm5hbWUoJGZpbGVOYW1lKSk7CgogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKICAgICAgICAkY2FjaGUgPSAkdGhpcy0+Y2FjaGU7CiAgICAgICAgJGh0dHBEb3dubG9hZGVyID0gJHRoaXMtPmh0dHBEb3dubG9hZGVyOwogICAgICAgICRldmVudERpc3BhdGNoZXIgPSAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyOwogICAgICAgICRmaWxlc3lzdGVtID0gJHRoaXMtPmZpbGVzeXN0ZW07CiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgJGFjY2VwdCA9IG51bGw7CiAgICAgICAgJHJlamVjdCA9IG51bGw7CiAgICAgICAgJGRvd25sb2FkID0gZnVuY3Rpb24gKCkgdXNlICgkaW8sICRvdXRwdXQsICRodHRwRG93bmxvYWRlciwgJGNhY2hlLCAkY2FjaGVLZXlHZW5lcmF0b3IsICRldmVudERpc3BhdGNoZXIsICRwYWNrYWdlLCAkZmlsZU5hbWUsICYkdXJscywgJiRhY2NlcHQsICYkcmVqZWN0KSB7CiAgICAgICAgICAgICR1cmwgPSByZXNldCgkdXJscyk7CiAgICAgICAgICAgICRpbmRleCA9IGtleSgkdXJscyk7CgogICAgICAgICAgICBpZiAoJGV2ZW50RGlzcGF0Y2hlcikgewogICAgICAgICAgICAgICAgJHByZUZpbGVEb3dubG9hZEV2ZW50ID0gbmV3IFByZUZpbGVEb3dubG9hZEV2ZW50KFBsdWdpbkV2ZW50czo6UFJFX0ZJTEVfRE9XTkxPQUQsICRodHRwRG93bmxvYWRlciwgJHVybFsncHJvY2Vzc2VkJ10sICdwYWNrYWdlJywgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgJGV2ZW50RGlzcGF0Y2hlci0+ZGlzcGF0Y2goJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXROYW1lKCksICRwcmVGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgICAgICBpZiAoJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRDdXN0b21DYWNoZUtleSgpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHVybFsnY2FjaGVLZXknXSA9ICRjYWNoZUtleUdlbmVyYXRvcigkcGFja2FnZSwgJHByZUZpbGVEb3dubG9hZEV2ZW50LT5nZXRDdXN0b21DYWNoZUtleSgpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcHJlRmlsZURvd25sb2FkRXZlbnQtPmdldFByb2Nlc3NlZFVybCgpICE9PSAkdXJsWydwcm9jZXNzZWQnXSkgewogICAgICAgICAgICAgICAgICAgICR1cmxbJ2NhY2hlS2V5J10gPSAkY2FjaGVLZXlHZW5lcmF0b3IoJHBhY2thZ2UsICRwcmVGaWxlRG93bmxvYWRFdmVudC0+Z2V0UHJvY2Vzc2VkVXJsKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHVybFsncHJvY2Vzc2VkJ10gPSAkcHJlRmlsZURvd25sb2FkRXZlbnQtPmdldFByb2Nlc3NlZFVybCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdXJsc1skaW5kZXhdID0gJHVybDsKCiAgICAgICAgICAgICRjaGVja3N1bSA9ICRwYWNrYWdlLT5nZXREaXN0U2hhMUNoZWNrc3VtKCk7CiAgICAgICAgICAgICRjYWNoZUtleSA9ICR1cmxbJ2NhY2hlS2V5J107CgogICAgICAgICAgICAvLyB1c2UgZnJvbSBjYWNoZSBpZiBpdCBpcyBwcmVzZW50IGFuZCBoYXMgYSB2YWxpZCBjaGVja3N1bSBvciB3ZSBoYXZlIG5vIGNoZWNrc3VtIHRvIGNoZWNrIGFnYWluc3QKICAgICAgICAgICAgaWYgKCRjYWNoZSAmJiAoISRjaGVja3N1bSB8fCAkY2hlY2tzdW0gPT09ICRjYWNoZS0+c2hhMSgkY2FjaGVLZXkpKSAmJiAkY2FjaGUtPmNvcHlUbygkY2FjaGVLZXksICRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCIgIC0gTG9hZGluZyA8aW5mbz4iIC4gJHBhY2thZ2UtPmdldE5hbWUoKSAuICI8L2luZm8+ICg8Y29tbWVudD4iIC4gJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgLiAiPC9jb21tZW50PikgZnJvbSBjYWNoZSIsIHRydWUsIElPSW50ZXJmYWNlOjpWRVJZX1ZFUkJPU0UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlc3VsdCA9IFxSZWFjdFxQcm9taXNlXHJlc29sdmUoJGZpbGVOYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCIgIC0gRG93bmxvYWRpbmcgPGluZm8+IiAuICRwYWNrYWdlLT5nZXROYW1lKCkgLiAiPC9pbmZvPiAoPGNvbW1lbnQ+IiAuICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpIC4gIjwvY29tbWVudD4pIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICRodHRwRG93bmxvYWRlci0+YWRkQ29weSgkdXJsWydwcm9jZXNzZWQnXSwgJGZpbGVOYW1lLCAkcGFja2FnZS0+Z2V0VHJhbnNwb3J0T3B0aW9ucygpKQogICAgICAgICAgICAgICAgICAgIC0+dGhlbigkYWNjZXB0LCAkcmVqZWN0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQtPnRoZW4oZnVuY3Rpb24gKCRyZXN1bHQpIHVzZSAoJGZpbGVOYW1lLCAkY2hlY2tzdW0sICR1cmwsICRwYWNrYWdlLCAkZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIHJldHJ5LCB0aGUgZmlyc3QgY2FsbCdzIFByb21pc2UgY2hhaW4gZmluYWxseSBjYWxscyB0aGlzIHR3aWNlIGF0IHRoZSBlbmQsCiAgICAgICAgICAgICAgICAvLyBvbmNlIHdpdGggJHJlc3VsdCBiZWluZyB0aGUgcmV0dXJuZWQgJGZpbGVOYW1lIGZyb20gJGFjY2VwdCwgYW5kIHRoZW4gb25jZSBmb3IgZXZlcnkKICAgICAgICAgICAgICAgIC8vIGZhaWxlZCByZXF1ZXN0IHdpdGggYSBudWxsIHJlc3VsdCwgd2hpY2ggY2FuIGJlIHNraXBwZWQuCiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZU5hbWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkZmlsZU5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJHVybFsnYmFzZSddLicgY291bGQgbm90IGJlIHNhdmVkIHRvICcuJGZpbGVOYW1lLicsIG1ha2Ugc3VyZSB0aGUnCiAgICAgICAgICAgICAgICAgICAgICAgIC4nIGRpcmVjdG9yeSBpcyB3cml0YWJsZSBhbmQgeW91IGhhdmUgaW50ZXJuZXQgY29ubmVjdGl2aXR5Jyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRjaGVja3N1bSAmJiBoYXNoX2ZpbGUoJ3NoYTEnLCAkZmlsZU5hbWUpICE9PSAkY2hlY2tzdW0pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignVGhlIGNoZWNrc3VtIHZlcmlmaWNhdGlvbiBvZiB0aGUgZmlsZSBmYWlsZWQgKGRvd25sb2FkZWQgZnJvbSAnLiR1cmxbJ2Jhc2UnXS4nKScpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJHBvc3RGaWxlRG93bmxvYWRFdmVudCA9IG5ldyBQb3N0RmlsZURvd25sb2FkRXZlbnQoUGx1Z2luRXZlbnRzOjpQT1NUX0ZJTEVfRE9XTkxPQUQsICRmaWxlTmFtZSwgJGNoZWNrc3VtLCAkdXJsWydwcm9jZXNzZWQnXSwgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICRldmVudERpc3BhdGNoZXItPmRpc3BhdGNoKCRwb3N0RmlsZURvd25sb2FkRXZlbnQtPmdldE5hbWUoKSwgJHBvc3RGaWxlRG93bmxvYWRFdmVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlTmFtZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKCiAgICAgICAgJGFjY2VwdCA9IGZ1bmN0aW9uICgkcmVzcG9uc2UpIHVzZSAoJGNhY2hlLCAkcGFja2FnZSwgJGZpbGVOYW1lLCAkc2VsZiwgJiR1cmxzKSB7CiAgICAgICAgICAgICR1cmwgPSByZXNldCgkdXJscyk7CiAgICAgICAgICAgICRjYWNoZUtleSA9ICR1cmxbJ2NhY2hlS2V5J107CgogICAgICAgICAgICBpZiAoJGNhY2hlICYmICEkY2FjaGUtPmlzUmVhZE9ubHkoKSkgewogICAgICAgICAgICAgICAgJHNlbGYtPmxhc3RDYWNoZVdyaXRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSA9ICRjYWNoZUtleTsKICAgICAgICAgICAgICAgICRjYWNoZS0+Y29weUZyb20oJGNhY2hlS2V5LCAkZmlsZU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcmVzcG9uc2UtPmNvbGxlY3QoKTsKCiAgICAgICAgICAgIHJldHVybiAkZmlsZU5hbWU7CiAgICAgICAgfTsKCiAgICAgICAgJHJlamVjdCA9IGZ1bmN0aW9uICgkZSkgdXNlICgkaW8sICYkdXJscywgJGRvd25sb2FkLCAkZmlsZU5hbWUsICRwYWNrYWdlLCAmJHJldHJpZXMsICRmaWxlc3lzdGVtLCAkc2VsZikgewogICAgICAgICAgICAvLyBjbGVhbiB1cAogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgJGZpbGVzeXN0ZW0tPnVubGluaygkZmlsZU5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzZWxmLT5jbGVhckxhc3RDYWNoZVdyaXRlKCRwYWNrYWdlKTsKCiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIElycmVjb3ZlcmFibGVEb3dubG9hZEV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIE1heEZpbGVTaXplRXhjZWVkZWRFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGUgaW5zdGFuY2VvZiBUcmFuc3BvcnRFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIC8vIGlmIHdlIGdvdCBhbiBodHRwIHJlc3BvbnNlIHdpdGggYSBwcm9wZXIgY29kZSwgdGhlbiByZXF1ZXN0aW5nIGFnYWluIHdpbGwgcHJvYmFibHkgbm90IGhlbHAsIGFib3J0CiAgICAgICAgICAgICAgICBpZiAoKDAgIT09ICRlLT5nZXRDb2RlKCkgJiYgIWluX2FycmF5KCRlLT5nZXRDb2RlKCksIGFycmF5KDUwMCwgNTAyLCA1MDMsIDUwNCkpKSB8fCAhJHJldHJpZXMpIHsKICAgICAgICAgICAgICAgICAgICAkcmV0cmllcyA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNwZWNpYWwgZXJyb3IgY29kZSByZXR1cm5lZCB3aGVuIG5ldHdvcmsgaXMgYmVpbmcgYXJ0aWZpY2lhbGx5IGRpc2FibGVkCiAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIFRyYW5zcG9ydEV4Y2VwdGlvbiAmJiAkZS0+Z2V0U3RhdHVzQ29kZSgpID09PSA0OTkpIHsKICAgICAgICAgICAgICAgICRyZXRyaWVzID0gMDsKICAgICAgICAgICAgICAgICR1cmxzID0gYXJyYXkoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRyZXRyaWVzKSB7CiAgICAgICAgICAgICAgICB1c2xlZXAoNTAwMDAwKTsKICAgICAgICAgICAgICAgICRyZXRyaWVzLS07CgogICAgICAgICAgICAgICAgcmV0dXJuICRkb3dubG9hZCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhcnJheV9zaGlmdCgkdXJscyk7CiAgICAgICAgICAgIGlmICgkdXJscykgewogICAgICAgICAgICAgICAgaWYgKCRpby0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGlvLT53cml0ZUVycm9yKCcgICAgRmFpbGVkIGRvd25sb2FkaW5nICcuJHBhY2thZ2UtPmdldE5hbWUoKS4nOiBbJy5nZXRfY2xhc3MoJGUpLiddICcuJGUtPmdldENvZGUoKS4nOiAnLiRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIFRyeWluZyB0aGUgbmV4dCBVUkwgZm9yICcuJHBhY2thZ2UtPmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpby0+d3JpdGVFcnJvcignICAgIEZhaWxlZCBkb3dubG9hZGluZyAnLiRwYWNrYWdlLT5nZXROYW1lKCkuJywgdHJ5aW5nIHRoZSBuZXh0IFVSTCAoJy4kZS0+Z2V0Q29kZSgpLic6ICcuJGUtPmdldE1lc3NhZ2UoKS4nKScpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRyZXRyaWVzID0gMzsKICAgICAgICAgICAgICAgIHVzbGVlcCgxMDAwMDApOwoKICAgICAgICAgICAgICAgIHJldHVybiAkZG93bmxvYWQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfTsKCiAgICAgICAgcmV0dXJuICRkb3dubG9hZCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlcGFyZSgkdHlwZSwgUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgsIFBhY2thZ2VJbnRlcmZhY2UgJHByZXZQYWNrYWdlID0gbnVsbCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFudXAoJHR5cGUsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCBQYWNrYWdlSW50ZXJmYWNlICRwcmV2UGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGZpbGVOYW1lID0gJHRoaXMtPmdldEZpbGVOYW1lKCRwYWNrYWdlLCAkcGF0aCk7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlTmFtZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnVubGluaygkZmlsZU5hbWUpOwogICAgICAgIH0KCiAgICAgICAgJGRpcnNUb0NsZWFuVXAgPSBhcnJheSgKICAgICAgICAgICAgJHRoaXMtPmNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJykuJy9jb21wb3Nlci8nLAogICAgICAgICAgICAkdGhpcy0+Y29uZmlnLT5nZXQoJ3ZlbmRvci1kaXInKSwKICAgICAgICAgICAgJHBhdGgsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hZGRpdGlvbmFsQ2xlYW51cFBhdGhzWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXSBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZSgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRkaXJzVG9DbGVhblVwIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGlzX2RpcigkZGlyKSAmJiAkdGhpcy0+ZmlsZXN5c3RlbS0+aXNEaXJFbXB0eSgkZGlyKSAmJiByZWFscGF0aCgkZGlyKSAhPT0gZ2V0Y3dkKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW1vdmVEaXJlY3RvcnkoJGRpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkb3V0cHV0ID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gSW5zdGFsbE9wZXJhdGlvbjo6Zm9ybWF0KCRwYWNrYWdlKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+ZW1wdHlEaXJlY3RvcnkoJHBhdGgpOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbnN1cmVEaXJlY3RvcnlFeGlzdHMoJHBhdGgpOwogICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5yZW5hbWUoJHRoaXMtPmdldEZpbGVOYW1lKCRwYWNrYWdlLCAkcGF0aCksICRwYXRoIC4gJy8nIC4gcGF0aGluZm8ocGFyc2VfdXJsKCRwYWNrYWdlLT5nZXREaXN0VXJsKCksIFBIUF9VUkxfUEFUSCksIFBBVEhJTkZPX0JBU0VOQU1FKSk7CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0QmluYXJpZXMoKSkgewogICAgICAgICAgICAvLyBTaW5nbGUgZmlsZXMgY2FuIG5vdCBoYXZlIGEgbW9kZSBzZXQgbGlrZSBmaWxlcyBpbiBhcmNoaXZlcwogICAgICAgICAgICAvLyBzbyB3ZSBtYWtlIHN1cmUgaWYgdGhlIGZpbGUgaXMgYSBiaW5hcnkgdGhhdCBpdCBpcyBleGVjdXRhYmxlCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRCaW5hcmllcygpIGFzICRiaW4pIHsKICAgICAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkcGF0aCAuICcvJyAuICRiaW4pICYmICFpc19leGVjdXRhYmxlKCRwYXRoIC4gJy8nIC4gJGJpbikpIHsKICAgICAgICAgICAgICAgICAgICBTaWxlbmNlcjo6Y2FsbCgnY2htb2QnLCAkcGF0aCAuICcvJyAuICRiaW4sIDA3NzcgJiB+dW1hc2soKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUT0RPIG1hcmsgcHJpdmF0ZSBpbiB2MwogICAgICogQHByb3RlY3RlZCBUaGlzIGlzIHB1YmxpYyBkdWUgdG8gUEhQIDUuMwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYXJMYXN0Q2FjaGVXcml0ZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2FjaGUgJiYgaXNzZXQoJHRoaXMtPmxhc3RDYWNoZVdyaXRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNhY2hlLT5yZW1vdmUoJHRoaXMtPmxhc3RDYWNoZVdyaXRlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5sYXN0Q2FjaGVXcml0ZXNbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRPRE8gbWFyayBwcml2YXRlIGluIHYzCiAgICAgKiBAcHJvdGVjdGVkIFRoaXMgaXMgcHVibGljIGR1ZSB0byBQSFAgNS4zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDbGVhbnVwUGF0aChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXVtdID0gJHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBUT0RPIG1hcmsgcHJpdmF0ZSBpbiB2MwogICAgICogQHByb3RlY3RlZCBUaGlzIGlzIHB1YmxpYyBkdWUgdG8gUEhQIDUuMwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlQ2xlYW51cFBhdGgoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHBhdGgpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hZGRpdGlvbmFsQ2xlYW51cFBhdGhzWyRwYWNrYWdlLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICAkaWR4ID0gYXJyYXlfc2VhcmNoKCRwYXRoLCAkdGhpcy0+YWRkaXRpb25hbENsZWFudXBQYXRoc1skcGFja2FnZS0+Z2V0TmFtZSgpXSk7CiAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJGlkeCkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmFkZGl0aW9uYWxDbGVhbnVwUGF0aHNbJHBhY2thZ2UtPmdldE5hbWUoKV1bJGlkeF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCwgJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCIgIC0gIiAuIFVwZGF0ZU9wZXJhdGlvbjo6Zm9ybWF0KCRpbml0aWFsLCAkdGFyZ2V0KSAuICI6ICIsIGZhbHNlKTsKCiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+cmVtb3ZlKCRpbml0aWFsLCAkcGF0aCwgZmFsc2UpOwogICAgICAgIGlmICgkcHJvbWlzZSA9PT0gbnVsbCB8fCAhJHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRwcm9taXNlID0gXFJlYWN0XFByb21pc2VccmVzb2x2ZSgpOwogICAgICAgIH0KICAgICAgICAkc2VsZiA9ICR0aGlzOwogICAgICAgICRpbyA9ICR0aGlzLT5pbzsKCiAgICAgICAgcmV0dXJuICRwcm9taXNlLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHNlbGYsICR0YXJnZXQsICRwYXRoLCAkaW8pIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkc2VsZi0+aW5zdGFsbCgkdGFyZ2V0LCAkcGF0aCwgZmFsc2UpOwogICAgICAgICAgICAkaW8tPndyaXRlRXJyb3IoJycpOwoKICAgICAgICAgICAgcmV0dXJuICRwcm9taXNlOwogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRwYXRoLCAkb3V0cHV0ID0gdHJ1ZSkKICAgIHsKICAgICAgICBpZiAoJG91dHB1dCkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoIiAgLSAiIC4gVW5pbnN0YWxsT3BlcmF0aW9uOjpmb3JtYXQoJHBhY2thZ2UpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCRwYXRoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBjb21wbGV0ZWx5IGRlbGV0ZSAnLiRwYXRoLicsIGFib3J0aW5nLicpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgZmlsZSBuYW1lIGZvciBzcGVjaWZpYyBwYWNrYWdlCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlIHBhY2thZ2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAkcGF0aCAgICBkb3dubG9hZCBwYXRoCiAgICAgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgICAgZmlsZSBuYW1lCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRGaWxlTmFtZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcGF0aCkKICAgIHsKICAgICAgICByZXR1cm4gcnRyaW0oJHRoaXMtPmNvbmZpZy0+Z2V0KCd2ZW5kb3ItZGlyJykuJy9jb21wb3Nlci90bXAtJy5tZDUoJHBhY2thZ2Uuc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKSkuJy4nLnBhdGhpbmZvKHBhcnNlX3VybCgkcGFja2FnZS0+Z2V0RGlzdFVybCgpLCBQSFBfVVJMX1BBVEgpLCBQQVRISU5GT19FWFRFTlNJT04pLCAnLicpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvY2VzcyB0aGUgZG93bmxvYWQgdXJsCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICAkcGFja2FnZSBwYWNrYWdlIHRoZSB1cmwgaXMgY29taW5nIGZyb20KICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgJHVybCAgICAgZG93bmxvYWQgdXJsCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uIElmIGFueSBwcm9ibGVtIHdpdGggdGhlIHVybAogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgICB1cmwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByb2Nlc3NVcmwoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHVybCkKICAgIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ29wZW5zc2wnKSAmJiAwID09PSBzdHJwb3MoJHVybCwgJ2h0dHBzOicpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignWW91IG11c3QgZW5hYmxlIHRoZSBvcGVuc3NsIGV4dGVuc2lvbiB0byBkb3dubG9hZCBmaWxlcyB2aWEgaHR0cHMnKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcGFja2FnZS0+Z2V0RGlzdFJlZmVyZW5jZSgpKSB7CiAgICAgICAgICAgICR1cmwgPSBVcmxVdGlsOjp1cGRhdGVEaXN0UmVmZXJlbmNlKCR0aGlzLT5jb25maWcsICR1cmwsICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR1cmw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhbENoYW5nZXMoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgJHRhcmdldERpcikKICAgIHsKICAgICAgICAkcHJldklPID0gJHRoaXMtPmlvOwoKICAgICAgICAkdGhpcy0+aW8gPSBuZXcgTnVsbElPOwogICAgICAgICR0aGlzLT5pby0+bG9hZENvbmZpZ3VyYXRpb24oJHRoaXMtPmNvbmZpZyk7CiAgICAgICAgJGUgPSBudWxsOwogICAgICAgICRvdXRwdXQgPSAnJzsKCiAgICAgICAgJHRhcmdldERpciA9IEZpbGVzeXN0ZW06OnRyaW1UcmFpbGluZ1NsYXNoKCR0YXJnZXREaXIpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChpc19kaXIoJHRhcmdldERpci4nX2NvbXBhcmUnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnJlbW92ZURpcmVjdG9yeSgkdGFyZ2V0RGlyLidfY29tcGFyZScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZG93bmxvYWQoJHBhY2thZ2UsICR0YXJnZXREaXIuJ19jb21wYXJlJywgbnVsbCwgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+aHR0cERvd25sb2FkZXItPndhaXQoKTsKICAgICAgICAgICAgJHRoaXMtPmluc3RhbGwoJHBhY2thZ2UsICR0YXJnZXREaXIuJ19jb21wYXJlJywgZmFsc2UpOwogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzcy0+d2FpdCgpOwoKICAgICAgICAgICAgJGNvbXBhcmVyID0gbmV3IENvbXBhcmVyKCk7CiAgICAgICAgICAgICRjb21wYXJlci0+c2V0U291cmNlKCR0YXJnZXREaXIuJ19jb21wYXJlJyk7CiAgICAgICAgICAgICRjb21wYXJlci0+c2V0VXBkYXRlKCR0YXJnZXREaXIpOwogICAgICAgICAgICAkY29tcGFyZXItPmRvQ29tcGFyZSgpOwogICAgICAgICAgICAkb3V0cHV0ID0gJGNvbXBhcmVyLT5nZXRDaGFuZ2VkKHRydWUsIHRydWUpOwogICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+cmVtb3ZlRGlyZWN0b3J5KCR0YXJnZXREaXIuJ19jb21wYXJlJyk7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlvID0gJHByZXZJTzsKCiAgICAgICAgaWYgKCRlKSB7CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRyaW0oJG91dHB1dCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcQ29uZmlnOwoKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxKc29uXEpzb25NYW5pcHVsYXRvcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvblZhbGlkYXRpb25FeGNlcHRpb247CnVzZSBDb21wb3NlclxVdGlsXFNpbGVuY2VyOwoKLyoqCiAqIEpTT04gQ29uZmlndXJhdGlvbiBTb3VyY2UKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEJlYXUgU2ltZW5zZW4gPGJlYXVAZGZseWRldi5jb20+CiAqLwpjbGFzcyBKc29uQ29uZmlnU291cmNlIGltcGxlbWVudHMgQ29uZmlnU291cmNlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHZhciBKc29uRmlsZQogICAgICovCiAgICBwcml2YXRlICRmaWxlOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJGF1dGhDb25maWc7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcgogICAgICoKICAgICAqIEBwYXJhbSBKc29uRmlsZSAkZmlsZQogICAgICogQHBhcmFtIGJvb2wgICAgICRhdXRoQ29uZmlnCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChKc29uRmlsZSAkZmlsZSwgJGF1dGhDb25maWcgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZmlsZSA9ICRmaWxlOwogICAgICAgICR0aGlzLT5hdXRoQ29uZmlnID0gJGF1dGhDb25maWc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGUtPmdldFBhdGgoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcsICRhcHBlbmQgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5tYW5pcHVsYXRlSnNvbignYWRkUmVwb3NpdG9yeScsICRuYW1lLCAkY29uZmlnLCAkYXBwZW5kLCBmdW5jdGlvbiAoJiRjb25maWcsICRyZXBvLCAkcmVwb0NvbmZpZykgdXNlICgkYXBwZW5kKSB7CiAgICAgICAgICAgIC8vIGlmIGNvbnZlcnRpbmcgZnJvbSBhbiBhcnJheSBmb3JtYXQgdG8gaGFzaG1hcCBmb3JtYXQsIGFuZCB0aGVyZSBpcyBhIHsicGFja2FnaXN0Lm9yZyI6ZmFsc2V9IHJlcG8sIHdlIGhhdmUKICAgICAgICAgICAgLy8gdG8gY29udmVydCBpdCB0byAicGFja2FnaXN0Lm9yZyI6IGZhbHNlIGtleSBvbiB0aGUgaGFzaG1hcCBvdGhlcndpc2UgaXQgZmFpbHMgc2NoZW1hIHZhbGlkYXRpb24KICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25maWdbJ3JlcG9zaXRvcmllcyddKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10gYXMgJGluZGV4ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGluZGV4ID09PSAkcmVwbykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoJGluZGV4KSAmJiAoJHZhbCA9PT0gYXJyYXkoJ3BhY2thZ2lzdCcgPT4gZmFsc2UpIHx8ICR2YWwgPT09IGFycmF5KCdwYWNrYWdpc3Qub3JnJyA9PiBmYWxzZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJ3JlcG9zaXRvcmllcyddWyRpbmRleF0pOwogICAgICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydyZXBvc2l0b3JpZXMnXVsncGFja2FnaXN0Lm9yZyddID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRhcHBlbmQpIHsKICAgICAgICAgICAgICAgICRjb25maWdbJ3JlcG9zaXRvcmllcyddWyRyZXBvXSA9ICRyZXBvQ29uZmlnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbmZpZ1sncmVwb3NpdG9yaWVzJ10gPSBhcnJheSgkcmVwbyA9PiAkcmVwb0NvbmZpZykgKyAkY29uZmlnWydyZXBvc2l0b3JpZXMnXTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUmVwb3NpdG9yeSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ3JlbW92ZVJlcG9zaXRvcnknLCAkbmFtZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAkcmVwbykgewogICAgICAgICAgICB1bnNldCgkY29uZmlnWydyZXBvc2l0b3JpZXMnXVskcmVwb10pOwogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQ29uZmlnU2V0dGluZygkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgICRhdXRoQ29uZmlnID0gJHRoaXMtPmF1dGhDb25maWc7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdhZGRDb25maWdTZXR0aW5nJywgJG5hbWUsICR2YWx1ZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAka2V5LCAkdmFsKSB1c2UgKCRhdXRoQ29uZmlnKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XihiaXRidWNrZXQtb2F1dGh8Z2l0aHViLW9hdXRofGdpdGxhYi1vYXV0aHxnaXRsYWItdG9rZW58YmVhcmVyfGh0dHAtYmFzaWN8cGxhdGZvcm0pXC59JywgJGtleSkpIHsKICAgICAgICAgICAgICAgIGxpc3QoJGtleSwgJGhvc3QpID0gZXhwbG9kZSgnLicsICRrZXksIDIpOwogICAgICAgICAgICAgICAgaWYgKCRhdXRoQ29uZmlnKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbmZpZ1ska2V5XVskaG9zdF0gPSAkdmFsOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydjb25maWcnXVska2V5XVskaG9zdF0gPSAkdmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbmZpZ1snY29uZmlnJ11bJGtleV0gPSAkdmFsOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVDb25maWdTZXR0aW5nKCRuYW1lKQogICAgewogICAgICAgICRhdXRoQ29uZmlnID0gJHRoaXMtPmF1dGhDb25maWc7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVDb25maWdTZXR0aW5nJywgJG5hbWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJGtleSkgdXNlICgkYXV0aENvbmZpZykgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oYml0YnVja2V0LW9hdXRofGdpdGh1Yi1vYXV0aHxnaXRsYWItb2F1dGh8Z2l0bGFiLXRva2VufGJlYXJlcnxodHRwLWJhc2ljfHBsYXRmb3JtKVwufScsICRrZXkpKSB7CiAgICAgICAgICAgICAgICBsaXN0KCRrZXksICRob3N0KSA9IGV4cGxvZGUoJy4nLCAka2V5LCAyKTsKICAgICAgICAgICAgICAgIGlmICgkYXV0aENvbmZpZykgewogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJGtleV1bJGhvc3RdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGNvbmZpZ1snY29uZmlnJ11bJGtleV1bJGhvc3RdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJ2NvbmZpZyddWyRrZXldKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHJvcGVydHkoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ2FkZFByb3BlcnR5JywgJG5hbWUsICR2YWx1ZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAka2V5LCAkdmFsKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGtleSwgJ2V4dHJhLicpID09PSAwIHx8IHN0cnBvcygka2V5LCAnc2NyaXB0cy4nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgJGJpdHMgPSBleHBsb2RlKCcuJywgJGtleSk7CiAgICAgICAgICAgICAgICAkbGFzdCA9IGFycmF5X3BvcCgkYml0cyk7CiAgICAgICAgICAgICAgICAkYXJyID0gJiRjb25maWdbcmVzZXQoJGJpdHMpXTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRiaXRzIGFzICRiaXQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcnJbJGJpdF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhcnJbJGJpdF0gPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYXJyID0gJiRhcnJbJGJpdF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkYXJyWyRsYXN0XSA9ICR2YWw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29uZmlnWyRrZXldID0gJHZhbDsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHkoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVQcm9wZXJ0eScsICRuYW1lLCBmdW5jdGlvbiAoJiRjb25maWcsICRrZXkpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygka2V5LCAnZXh0cmEuJykgPT09IDAgfHwgc3RycG9zKCRrZXksICdzY3JpcHRzLicpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkYml0cyA9IGV4cGxvZGUoJy4nLCAka2V5KTsKICAgICAgICAgICAgICAgICRsYXN0ID0gYXJyYXlfcG9wKCRiaXRzKTsKICAgICAgICAgICAgICAgICRhcnIgPSAmJGNvbmZpZ1tyZXNldCgkYml0cyldOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGJpdHMgYXMgJGJpdCkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyclskYml0XSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYXJyID0gJiRhcnJbJGJpdF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1bnNldCgkYXJyWyRsYXN0XSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1bnNldCgkY29uZmlnWyRrZXldKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGluaygkdHlwZSwgJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ2FkZExpbmsnLCAkdHlwZSwgJG5hbWUsICR2YWx1ZSwgZnVuY3Rpb24gKCYkY29uZmlnLCAkdHlwZSwgJG5hbWUsICR2YWx1ZSkgewogICAgICAgICAgICAkY29uZmlnWyR0eXBlXVskbmFtZV0gPSAkdmFsdWU7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVMaW5rKCR0eXBlLCAkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bWFuaXB1bGF0ZUpzb24oJ3JlbW92ZVN1Yk5vZGUnLCAkdHlwZSwgJG5hbWUsIGZ1bmN0aW9uICgmJGNvbmZpZywgJHR5cGUsICRuYW1lKSB7CiAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJHR5cGVdWyRuYW1lXSk7CiAgICAgICAgfSk7CiAgICAgICAgJHRoaXMtPm1hbmlwdWxhdGVKc29uKCdyZW1vdmVNYWluS2V5SWZFbXB0eScsICR0eXBlLCBmdW5jdGlvbiAoJiRjb25maWcsICR0eXBlKSB7CiAgICAgICAgICAgIGlmICgwID09PSBjb3VudCgkY29uZmlnWyR0eXBlXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRjb25maWdbJHR5cGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBtYW5pcHVsYXRlSnNvbigkbWV0aG9kLCAkYXJncywgJGZhbGxiYWNrKQogICAgewogICAgICAgICRhcmdzID0gZnVuY19nZXRfYXJncygpOwogICAgICAgIC8vIHJlbW92ZSBtZXRob2QgJiBmYWxsYmFjawogICAgICAgIGFycmF5X3NoaWZ0KCRhcmdzKTsKICAgICAgICAkZmFsbGJhY2sgPSBhcnJheV9wb3AoJGFyZ3MpOwoKICAgICAgICBpZiAoJHRoaXMtPmZpbGUtPmV4aXN0cygpKSB7CiAgICAgICAgICAgIGlmICghaXNfd3JpdGFibGUoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgZmlsZSAiJXMiIGlzIG5vdCB3cml0YWJsZS4nLCAkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNfcmVhZGFibGUoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgZmlsZSAiJXMiIGlzIG5vdCByZWFkYWJsZS4nLCAkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlLT5nZXRQYXRoKCkpOwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+YXV0aENvbmZpZykgewogICAgICAgICAgICAkY29udGVudHMgPSAie1xufVxuIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29udGVudHMgPSAie1xuICAgIFwiY29uZmlnXCI6IHtcbiAgICB9XG59XG4iOwogICAgICAgIH0KCiAgICAgICAgJG1hbmlwdWxhdG9yID0gbmV3IEpzb25NYW5pcHVsYXRvcigkY29udGVudHMpOwoKICAgICAgICAkbmV3RmlsZSA9ICEkdGhpcy0+ZmlsZS0+ZXhpc3RzKCk7CgogICAgICAgIC8vIG92ZXJyaWRlIG1hbmlwdWxhdG9yIG1ldGhvZCBmb3IgYXV0aCBjb25maWcgZmlsZXMKICAgICAgICBpZiAoJHRoaXMtPmF1dGhDb25maWcgJiYgJG1ldGhvZCA9PT0gJ2FkZENvbmZpZ1NldHRpbmcnKSB7CiAgICAgICAgICAgICRtZXRob2QgPSAnYWRkU3ViTm9kZSc7CiAgICAgICAgICAgIGxpc3QoJG1haW5Ob2RlLCAkbmFtZSkgPSBleHBsb2RlKCcuJywgJGFyZ3NbMF0sIDIpOwogICAgICAgICAgICAkYXJncyA9IGFycmF5KCRtYWluTm9kZSwgJG5hbWUsICRhcmdzWzFdKTsKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmF1dGhDb25maWcgJiYgJG1ldGhvZCA9PT0gJ3JlbW92ZUNvbmZpZ1NldHRpbmcnKSB7CiAgICAgICAgICAgICRtZXRob2QgPSAncmVtb3ZlU3ViTm9kZSc7CiAgICAgICAgICAgIGxpc3QoJG1haW5Ob2RlLCAkbmFtZSkgPSBleHBsb2RlKCcuJywgJGFyZ3NbMF0sIDIpOwogICAgICAgICAgICAkYXJncyA9IGFycmF5KCRtYWluTm9kZSwgJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IHRvIHVwZGF0ZSBjbGVhbmx5CiAgICAgICAgaWYgKGNhbGxfdXNlcl9mdW5jX2FycmF5KGFycmF5KCRtYW5pcHVsYXRvciwgJG1ldGhvZCksICRhcmdzKSkgewogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkdGhpcy0+ZmlsZS0+Z2V0UGF0aCgpLCAkbWFuaXB1bGF0b3ItPmdldENvbnRlbnRzKCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG9uIGZhaWxlZCBjbGVhbiB1cGRhdGUsIGNhbGwgdGhlIGZhbGxiYWNrIGFuZCByZXdyaXRlIHRoZSB3aG9sZSBmaWxlCiAgICAgICAgICAgICRjb25maWcgPSAkdGhpcy0+ZmlsZS0+cmVhZCgpOwogICAgICAgICAgICAkdGhpcy0+YXJyYXlVbnNoaWZ0UmVmKCRhcmdzLCAkY29uZmlnKTsKICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmNfYXJyYXkoJGZhbGxiYWNrLCAkYXJncyk7CiAgICAgICAgICAgIC8vIGF2b2lkIGVuZGluZyB1cCB3aXRoIGFycmF5cyBmb3Iga2V5cyB0aGF0IHNob3VsZCBiZSBvYmplY3RzCiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCdyZXF1aXJlJywgJ3JlcXVpcmUtZGV2JywgJ2NvbmZsaWN0JywgJ3Byb3ZpZGUnLCAncmVwbGFjZScsICdzdWdnZXN0JywgJ2NvbmZpZycsICdhdXRvbG9hZCcsICdhdXRvbG9hZC1kZXYnLCAnc2NyaXB0cycsICdzY3JpcHRzLWRlc2NyaXB0aW9ucycsICdzdXBwb3J0JykgYXMgJHByb3ApIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWyRwcm9wXSkgJiYgJGNvbmZpZ1skcHJvcF0gPT09IGFycmF5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWyRwcm9wXSA9IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXkoJ3Bzci0wJywgJ3Bzci00JykgYXMgJHByb3ApIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY29uZmlnWydhdXRvbG9hZCddWyRwcm9wXSkgJiYgJGNvbmZpZ1snYXV0b2xvYWQnXVskcHJvcF0gPT09IGFycmF5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydhdXRvbG9hZCddWyRwcm9wXSA9IG5ldyBcc3RkQ2xhc3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snYXV0b2xvYWQtZGV2J11bJHByb3BdKSAmJiAkY29uZmlnWydhdXRvbG9hZC1kZXYnXVskcHJvcF0gPT09IGFycmF5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydhdXRvbG9hZC1kZXYnXVskcHJvcF0gPSBuZXcgXHN0ZENsYXNzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCdwbGF0Zm9ybScsICdodHRwLWJhc2ljJywgJ2JlYXJlcicsICdnaXRsYWItdG9rZW4nLCAnZ2l0bGFiLW9hdXRoJywgJ2dpdGh1Yi1vYXV0aCcsICdwcmVmZXJyZWQtaW5zdGFsbCcpIGFzICRwcm9wKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNvbmZpZ1snY29uZmlnJ11bJHByb3BdKSAmJiAkY29uZmlnWydjb25maWcnXVskcHJvcF0gPT09IGFycmF5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uZmlnWydjb25maWcnXVskcHJvcF0gPSBuZXcgXHN0ZENsYXNzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5maWxlLT53cml0ZSgkY29uZmlnKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5maWxlLT52YWxpZGF0ZVNjaGVtYShKc29uRmlsZTo6TEFYX1NDSEVNQSk7CiAgICAgICAgfSBjYXRjaCAoSnNvblZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gcmVzdG9yZSBjb250ZW50cyB0byB0aGUgb3JpZ2luYWwgc3RhdGUKICAgICAgICAgICAgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmZpbGUtPmdldFBhdGgoKSwgJGNvbnRlbnRzKTsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gdXBkYXRlIGNvbXBvc2VyLmpzb24gd2l0aCBhIHZhbGlkIGZvcm1hdCwgcmV2ZXJ0aW5nIHRvIHRoZSBvcmlnaW5hbCBjb250ZW50LiBQbGVhc2UgcmVwb3J0IGFuIGlzc3VlIHRvIHVzIHdpdGggZGV0YWlscyAoY29tbWFuZCB5b3UgcnVuIGFuZCBhIGNvcHkgb2YgeW91ciBjb21wb3Nlci5qc29uKS4nLCAwLCAkZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5ld0ZpbGUpIHsKICAgICAgICAgICAgU2lsZW5jZXI6OmNhbGwoJ2NobW9kJywgJHRoaXMtPmZpbGUtPmdldFBhdGgoKSwgMDYwMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUHJlcGVuZCBhIHJlZmVyZW5jZSB0byBhbiBlbGVtZW50IHRvIHRoZSBiZWdpbm5pbmcgb2YgYW4gYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtICBhcnJheSAkYXJyYXkKICAgICAqIEBwYXJhbSAgbWl4ZWQgJHZhbHVlCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFycmF5VW5zaGlmdFJlZigmJGFycmF5LCAmJHZhbHVlKQogICAgewogICAgICAgICRyZXR1cm4gPSBhcnJheV91bnNoaWZ0KCRhcnJheSwgJycpOwogICAgICAgICRhcnJheVswXSA9ICYkdmFsdWU7CgogICAgICAgIHJldHVybiAkcmV0dXJuOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENvbmZpZzsKCi8qKgogKiBDb25maWd1cmF0aW9uIFNvdXJjZSBJbnRlcmZhY2UKICoKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAYXV0aG9yIEJlYXUgU2ltZW5zZW4gPGJlYXVAZGZseWRldi5jb20+CiAqLwppbnRlcmZhY2UgQ29uZmlnU291cmNlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQWRkIGEgcmVwb3NpdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkbmFtZSAgIE5hbWUKICAgICAqIEBwYXJhbSBhcnJheXxmYWxzZSAkY29uZmlnIENvbmZpZ3VyYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcsICRhcHBlbmQgPSB0cnVlKTsKCiAgICAvKioKICAgICAqIFJlbW92ZSBhIHJlcG9zaXRvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVSZXBvc2l0b3J5KCRuYW1lKTsKCiAgICAvKioKICAgICAqIEFkZCBhIGNvbmZpZyBzZXR0aW5nCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkbmFtZSAgTmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkdmFsdWUgVmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENvbmZpZ1NldHRpbmcoJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYSBjb25maWcgc2V0dGluZwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZUNvbmZpZ1NldHRpbmcoJG5hbWUpOwoKICAgIC8qKgogICAgICogQWRkIGEgcHJvcGVydHkKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICBOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBWYWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUHJvcGVydHkoJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYSBwcm9wZXJ0eQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KCRuYW1lKTsKCiAgICAvKioKICAgICAqIEFkZCBhIHBhY2thZ2UgbGluawogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgIFR5cGUgKHJlcXVpcmUsIHJlcXVpcmUtZGV2LCBwcm92aWRlLCBzdWdnZXN0LCByZXBsYWNlLCBjb25mbGljdCkKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIE5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIFZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRMaW5rKCR0eXBlLCAkbmFtZSwgJHZhbHVlKTsKCiAgICAvKioKICAgICAqIFJlbW92ZSBhIHBhY2thZ2UgbGluawogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgVHlwZSAocmVxdWlyZSwgcmVxdWlyZS1kZXYsIHByb3ZpZGUsIHN1Z2dlc3QsIHJlcGxhY2UsIGNvbmZsaWN0KQogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBOYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVMaW5rKCR0eXBlLCAkbmFtZSk7CgogICAgLyoqCiAgICAgKiBHaXZlcyBhIHVzZXItZnJpZW5kbHkgbmFtZSB0byB0aGlzIHNvdXJjZSAoZmlsZSBwYXRoIG9yIHNvKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBTb2x2ZXJCdWdFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbgp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgKICAgICAgICAgICAgJG1lc3NhZ2UuIlxuVGhpcyBleGNlcHRpb24gd2FzIG1vc3QgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBDb21wb3Nlci5cbiIuCiAgICAgICAgICAgICJQbGVhc2UgcmVwb3J0IHRoZSBjb21tYW5kIHlvdSByYW4sIHRoZSBleGFjdCBlcnJvciB5b3UgcmVjZWl2ZWQsIGFuZCB5b3VyIGNvbXBvc2VyLmpzb24gb24gaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NvbXBvc2VyL2lzc3VlcyAtIHRoYW5rIHlvdSFcbiIKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQmFzZVBhY2thZ2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIERlZmF1bHRQb2xpY3kgaW1wbGVtZW50cyBQb2xpY3lJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkcHJlZmVyU3RhYmxlOwogICAgcHJpdmF0ZSAkcHJlZmVyTG93ZXN0OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcHJlZmVyU3RhYmxlID0gZmFsc2UsICRwcmVmZXJMb3dlc3QgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZmVyU3RhYmxlID0gJHByZWZlclN0YWJsZTsKICAgICAgICAkdGhpcy0+cHJlZmVyTG93ZXN0ID0gJHByZWZlckxvd2VzdDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdmVyc2lvbkNvbXBhcmUoUGFja2FnZUludGVyZmFjZSAkYSwgUGFja2FnZUludGVyZmFjZSAkYiwgJG9wZXJhdG9yKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJlZmVyU3RhYmxlICYmICgkc3RhYkEgPSAkYS0+Z2V0U3RhYmlsaXR5KCkpICE9PSAoJHN0YWJCID0gJGItPmdldFN0YWJpbGl0eSgpKSkgewogICAgICAgICAgICByZXR1cm4gQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skc3RhYkFdIDwgQmFzZVBhY2thZ2U6OiRzdGFiaWxpdGllc1skc3RhYkJdOwogICAgICAgIH0KCiAgICAgICAgJGNvbnN0cmFpbnQgPSBuZXcgQ29uc3RyYWludCgkb3BlcmF0b3IsICRiLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICR2ZXJzaW9uID0gbmV3IENvbnN0cmFpbnQoJz09JywgJGEtPmdldFZlcnNpb24oKSk7CgogICAgICAgIHJldHVybiAkY29uc3RyYWludC0+bWF0Y2hTcGVjaWZpYygkdmVyc2lvbiwgdHJ1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNlbGVjdFByZWZlcnJlZFBhY2thZ2VzKFBvb2wgJHBvb2wsIGFycmF5ICRsaXRlcmFscywgJHJlcXVpcmVkUGFja2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gJHRoaXMtPmdyb3VwTGl0ZXJhbHNCeU5hbWUoJHBvb2wsICRsaXRlcmFscyk7CiAgICAgICAgJHBvbGljeSA9ICR0aGlzOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJiRuYW1lTGl0ZXJhbHMpIHsKICAgICAgICAgICAgdXNvcnQoJG5hbWVMaXRlcmFscywgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcG9saWN5LCAkcG9vbCwgJHJlcXVpcmVkUGFja2FnZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRwb2xpY3ktPmNvbXBhcmVCeVByaW9yaXR5KCRwb29sLCAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkYSksICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRiKSwgJHJlcXVpcmVkUGFja2FnZSwgdHJ1ZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICYkc29ydGVkTGl0ZXJhbHMpIHsKICAgICAgICAgICAgJHNvcnRlZExpdGVyYWxzID0gJHRoaXMtPnBydW5lVG9CZXN0VmVyc2lvbigkcG9vbCwgJHNvcnRlZExpdGVyYWxzKTsKICAgICAgICAgICAgJHNvcnRlZExpdGVyYWxzID0gJHRoaXMtPnBydW5lUmVtb3RlQWxpYXNlcygkcG9vbCwgJHNvcnRlZExpdGVyYWxzKTsKICAgICAgICB9CgogICAgICAgICRzZWxlY3RlZCA9IFxjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCBhcnJheV92YWx1ZXMoJHBhY2thZ2VzKSk7CgogICAgICAgIC8vIG5vdyBzb3J0IHRoZSByZXN1bHQgYWNyb3NzIGFsbCBwYWNrYWdlcyB0byByZXNwZWN0IHJlcGxhY2VzIGFjcm9zcyBwYWNrYWdlcwogICAgICAgIHVzb3J0KCRzZWxlY3RlZCwgZnVuY3Rpb24gKCRhLCAkYikgdXNlICgkcG9saWN5LCAkcG9vbCwgJHJlcXVpcmVkUGFja2FnZSkgewogICAgICAgICAgICByZXR1cm4gJHBvbGljeS0+Y29tcGFyZUJ5UHJpb3JpdHkoJHBvb2wsICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRhKSwgJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGIpLCAkcmVxdWlyZWRQYWNrYWdlKTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICRzZWxlY3RlZDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ3JvdXBMaXRlcmFsc0J5TmFtZShQb29sICRwb29sLCAkbGl0ZXJhbHMpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgJHBhY2thZ2VOYW1lID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpLT5nZXROYW1lKCk7CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRwYWNrYWdlc1skcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzWyRwYWNrYWdlTmFtZV0gPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYWNrYWdlc1skcGFja2FnZU5hbWVdW10gPSAkbGl0ZXJhbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcHJvdGVjdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21wYXJlQnlQcmlvcml0eShQb29sICRwb29sLCBQYWNrYWdlSW50ZXJmYWNlICRhLCBQYWNrYWdlSW50ZXJmYWNlICRiLCAkcmVxdWlyZWRQYWNrYWdlID0gbnVsbCwgJGlnbm9yZVJlcGxhY2UgPSBmYWxzZSkKICAgIHsKICAgICAgICAvLyBwcmVmZXIgYWxpYXNlcyB0byB0aGUgb3JpZ2luYWwgcGFja2FnZQogICAgICAgIGlmICgkYS0+Z2V0TmFtZSgpID09PSAkYi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICRhQWxpYXNlZCA9ICRhIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlOwogICAgICAgICAgICAkYkFsaWFzZWQgPSAkYiBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZTsKICAgICAgICAgICAgaWYgKCRhQWxpYXNlZCAmJiAhJGJBbGlhc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7IC8vIHVzZSBhCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkYUFsaWFzZWQgJiYgJGJBbGlhc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsgLy8gdXNlIGIKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkaWdub3JlUmVwbGFjZSkgewogICAgICAgICAgICAvLyByZXR1cm4gb3JpZ2luYWwsIG5vdCByZXBsYWNlZAogICAgICAgICAgICBpZiAoJHRoaXMtPnJlcGxhY2VzKCRhLCAkYikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOyAvLyB1c2UgYgogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVwbGFjZXMoJGIsICRhKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOyAvLyB1c2UgYQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBmb3IgcmVwbGFjZXJzIG5vdCByZXBsYWNpbmcgZWFjaCBvdGhlciwgcHV0IGEgaGlnaGVyIHByaW8gb24gcmVwbGFjaW5nCiAgICAgICAgICAgIC8vIHBhY2thZ2VzIHdpdGggdGhlIHNhbWUgdmVuZG9yIGFzIHRoZSByZXF1aXJlZCBwYWNrYWdlCiAgICAgICAgICAgIGlmICgkcmVxdWlyZWRQYWNrYWdlICYmIGZhbHNlICE9PSAoJHBvcyA9IHN0cnBvcygkcmVxdWlyZWRQYWNrYWdlLCAnLycpKSkgewogICAgICAgICAgICAgICAgJHJlcXVpcmVkVmVuZG9yID0gc3Vic3RyKCRyZXF1aXJlZFBhY2thZ2UsIDAsICRwb3MpOwoKICAgICAgICAgICAgICAgICRhSXNTYW1lVmVuZG9yID0gc3RycG9zKCRhLT5nZXROYW1lKCksICRyZXF1aXJlZFZlbmRvcikgPT09IDA7CiAgICAgICAgICAgICAgICAkYklzU2FtZVZlbmRvciA9IHN0cnBvcygkYi0+Z2V0TmFtZSgpLCAkcmVxdWlyZWRWZW5kb3IpID09PSAwOwoKICAgICAgICAgICAgICAgIGlmICgkYklzU2FtZVZlbmRvciAhPT0gJGFJc1NhbWVWZW5kb3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGFJc1NhbWVWZW5kb3IgPyAtMSA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHByaW9yaXR5IGVxdWFsLCBzb3J0IGJ5IHBhY2thZ2UgaWQgdG8gbWFrZSByZXByb2R1Y2libGUKICAgICAgICBpZiAoJGEtPmlkID09PSAkYi0+aWQpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKCRhLT5pZCA8ICRiLT5pZCkgPyAtMSA6IDE7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgc291cmNlIHJlcGxhY2VzIGEgcGFja2FnZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGFyZ2V0LgogICAgICoKICAgICAqIFJlcGxhY2UgY29uc3RyYWludHMgYXJlIGlnbm9yZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yCiAgICAgKiBwcmlvcml0aXNhdGlvbiwgbm90IGZvciBhY3R1YWwgY29uc3RyYWludCB2ZXJpZmljYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRzb3VyY2UKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlcGxhY2VzKFBhY2thZ2VJbnRlcmZhY2UgJHNvdXJjZSwgUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0KQogICAgewogICAgICAgIGZvcmVhY2ggKCRzb3VyY2UtPmdldFJlcGxhY2VzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgaWYgKCRsaW5rLT5nZXRUYXJnZXQoKSA9PT0gJHRhcmdldC0+Z2V0TmFtZSgpCi8vICAgICAgICAgICAgICAgICYmIChudWxsID09PSAkbGluay0+Z2V0Q29uc3RyYWludCgpIHx8Ci8vICAgICAgICAgICAgICAgICRsaW5rLT5nZXRDb25zdHJhaW50KCktPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz09JywgJHRhcmdldC0+Z2V0VmVyc2lvbigpKSkpKSB7CiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBydW5lVG9CZXN0VmVyc2lvbihQb29sICRwb29sLCAkbGl0ZXJhbHMpCiAgICB7CiAgICAgICAgJG9wZXJhdG9yID0gJHRoaXMtPnByZWZlckxvd2VzdCA/ICc8JyA6ICc+JzsKICAgICAgICAkYmVzdExpdGVyYWxzID0gYXJyYXkoJGxpdGVyYWxzWzBdKTsKICAgICAgICAkYmVzdFBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbHNbMF0pOwogICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkaSA9PiAkbGl0ZXJhbCkgewogICAgICAgICAgICBpZiAoMCA9PT0gJGkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+dmVyc2lvbkNvbXBhcmUoJHBhY2thZ2UsICRiZXN0UGFja2FnZSwgJG9wZXJhdG9yKSkgewogICAgICAgICAgICAgICAgJGJlc3RQYWNrYWdlID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAkYmVzdExpdGVyYWxzID0gYXJyYXkoJGxpdGVyYWwpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnZlcnNpb25Db21wYXJlKCRwYWNrYWdlLCAkYmVzdFBhY2thZ2UsICc9PScpKSB7CiAgICAgICAgICAgICAgICAkYmVzdExpdGVyYWxzW10gPSAkbGl0ZXJhbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRiZXN0TGl0ZXJhbHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBc3N1bWVzIHRoYXQgbG9jYWxseSBhbGlhc2VkIChpbiByb290IHBhY2thZ2UgcmVxdWlyZXMpIHBhY2thZ2VzIHRha2UgcHJpb3JpdHkgb3ZlciBicmFuY2gtYWxpYXMgb25lcwogICAgICoKICAgICAqIElmIG5vIHBhY2thZ2UgaXMgYSBsb2NhbCBhbGlhcywgbm90aGluZyBoYXBwZW5zCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcnVuZVJlbW90ZUFsaWFzZXMoUG9vbCAkcG9vbCwgYXJyYXkgJGxpdGVyYWxzKQogICAgewogICAgICAgICRoYXNMb2NhbEFsaWFzID0gZmFsc2U7CgogICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKCiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+aXNSb290UGFja2FnZUFsaWFzKCkpIHsKICAgICAgICAgICAgICAgICRoYXNMb2NhbEFsaWFzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoISRoYXNMb2NhbEFsaWFzKSB7CiAgICAgICAgICAgIHJldHVybiAkbGl0ZXJhbHM7CiAgICAgICAgfQoKICAgICAgICAkc2VsZWN0ZWQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAkcGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKCiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJiAkcGFja2FnZS0+aXNSb290UGFja2FnZUFsaWFzKCkpIHsKICAgICAgICAgICAgICAgICRzZWxlY3RlZFtdID0gJGxpdGVyYWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkc2VsZWN0ZWQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcTGluazsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUnVsZTJMaXRlcmFscyBleHRlbmRzIFJ1bGUKewogICAgcHJvdGVjdGVkICRsaXRlcmFsMTsKICAgIHByb3RlY3RlZCAkbGl0ZXJhbDI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICAgICRsaXRlcmFsMQogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAkbGl0ZXJhbDIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUgcmVhc29uIGZvciBnZW5lcmF0aW5nIHRoaXMgcnVsZQogICAgICogQHBhcmFtIExpbmt8UGFja2FnZUludGVyZmFjZSAkcmVhc29uRGF0YQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGxpdGVyYWwxLCAkbGl0ZXJhbDIsICRyZWFzb24sICRyZWFzb25EYXRhKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwoKICAgICAgICBpZiAoJGxpdGVyYWwxIDwgJGxpdGVyYWwyKSB7CiAgICAgICAgICAgICR0aGlzLT5saXRlcmFsMSA9ICRsaXRlcmFsMTsKICAgICAgICAgICAgJHRoaXMtPmxpdGVyYWwyID0gJGxpdGVyYWwyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5saXRlcmFsMSA9ICRsaXRlcmFsMjsKICAgICAgICAgICAgJHRoaXMtPmxpdGVyYWwyID0gJGxpdGVyYWwxOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGl0ZXJhbHMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgkdGhpcy0+bGl0ZXJhbDEsICR0aGlzLT5saXRlcmFsMik7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEhhc2goKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGl0ZXJhbDEuJywnLiR0aGlzLT5saXRlcmFsMjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGlzIHJ1bGUgaXMgZXF1YWwgdG8gYW5vdGhlciBvbmUKICAgICAqCiAgICAgKiBJZ25vcmVzIHdoZXRoZXIgZWl0aGVyIG9mIHRoZSBydWxlcyBpcyBkaXNhYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIFJ1bGUgJHJ1bGUgVGhlIHJ1bGUgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIHJ1bGVzIGFyZSBlcXVhbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgLy8gc3BlY2lhbGl6ZWQgZmFzdC1jYXNlCiAgICAgICAgaWYgKCRydWxlIGluc3RhbmNlb2Ygc2VsZikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmxpdGVyYWwxICE9PSAkcnVsZS0+bGl0ZXJhbDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5saXRlcmFsMiAhPT0gJHJ1bGUtPmxpdGVyYWwyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJGxpdGVyYWxzID0gJHJ1bGUtPmdldExpdGVyYWxzKCk7CiAgICAgICAgaWYgKDIgIT0gXGNvdW50KCRsaXRlcmFscykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5saXRlcmFsMSAhPT0gJGxpdGVyYWxzWzBdKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bGl0ZXJhbDIgIT09ICRsaXRlcmFsc1sxXSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBc3NlcnRpb24oKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBydWxlIGFzIGEgc3RyaW5nIG9mIHRoZSBmb3JtYXQgKExpdGVyYWwxfExpdGVyYWwyfC4uLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5pc0Rpc2FibGVkKCkgPyAnZGlzYWJsZWQoJyA6ICcoJzsKCiAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+bGl0ZXJhbDEgLiAnfCcgLiAkdGhpcy0+bGl0ZXJhbDIgLiAnKSc7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCi8qKgogKiBBbiBleHRlbnNpb24gb2YgU3BsRG91Ymx5TGlua2VkTGlzdCB3aXRoIHNlZWsgYW5kIHJlbW92YWwgb2YgY3VycmVudCBlbGVtZW50CiAqCiAqIFNwbERvdWJseUxpbmtlZExpc3Qgb25seSBhbGxvd3MgZGVsZXRpbmcgYSBwYXJ0aWN1bGFyIG9mZnNldCBhbmQgaGFzIG5vCiAqIG1ldGhvZCB0byBzZXQgdGhlIGludGVybmFsIGl0ZXJhdG9yIHRvIGEgcGFydGljdWxhciBvZmZzZXQuCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBSdWxlV2F0Y2hDaGFpbiBleHRlbmRzIFxTcGxEb3VibHlMaW5rZWRMaXN0CnsKICAgIHByb3RlY3RlZCAkb2Zmc2V0ID0gMDsKCiAgICAvKioKICAgICAqIE1vdmVzIHRoZSBpbnRlcm5hbCBpdGVyYXRvciB0byB0aGUgc3BlY2lmaWVkIG9mZnNldAogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJG9mZnNldCBUaGUgb2Zmc2V0IHRvIHNlZWsgdG8uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWVrKCRvZmZzZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPnJld2luZCgpOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRvZmZzZXQ7ICRpKyssICR0aGlzLT5uZXh0KCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgY3VycmVudCBlbGVtZW50IGZyb20gdGhlIGxpc3QKICAgICAqCiAgICAgKiBBcyBTcGxEb3VibHlMaW5rZWRMaXN0IG9ubHkgYWxsb3dzIGRlbGV0aW5nIGEgcGFydGljdWxhciBvZmZzZXQgYW5kCiAgICAgKiBpbmNvcnJlY3RseSBzZXRzIHRoZSBpbnRlcm5hbCBpdGVyYXRvciBpZiB5b3UgZGVsZXRlIHRoZSBjdXJyZW50IHZhbHVlCiAgICAgKiB0aGlzIG1ldGhvZCBzZXRzIHRoZSBpbnRlcm5hbCBpdGVyYXRvciBiYWNrIHRvIHRoZSBmb2xsb3dpbmcgZWxlbWVudAogICAgICogdXNpbmcgdGhlIHNlZWsgbWV0aG9kLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCkKICAgIHsKICAgICAgICAkb2Zmc2V0ID0gJHRoaXMtPmtleSgpOwogICAgICAgICR0aGlzLT5vZmZzZXRVbnNldCgkb2Zmc2V0KTsKICAgICAgICAkdGhpcy0+c2Vlaygkb2Zmc2V0KTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBTb2x2ZXIgaW5zdGFsbCBvcGVyYXRpb24uCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBJbnN0YWxsT3BlcmF0aW9uIGV4dGVuZHMgU29sdmVyT3BlcmF0aW9uIGltcGxlbWVudHMgT3BlcmF0aW9uSW50ZXJmYWNlCnsKICAgIGNvbnN0IFRZUEUgPSAnaW5zdGFsbCc7CgogICAgLyoqCiAgICAgKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICRwYWNrYWdlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5wYWNrYWdlID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHBhY2thZ2UgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzaG93KCRsb2NrKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpmb3JtYXQoJHRoaXMtPnBhY2thZ2UsICRsb2NrKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdChQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkbG9jayA9IGZhbHNlKQogICAgewogICAgICAgIHJldHVybiAoJGxvY2sgPyAnTG9ja2luZyAnIDogJ0luc3RhbGxpbmcgJykuJzxpbmZvPicuJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nPC9pbmZvPiAoPGNvbW1lbnQ+Jy4kcGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIFNvbHZlciB1bmluc3RhbGwgb3BlcmF0aW9uLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KY2xhc3MgVW5pbnN0YWxsT3BlcmF0aW9uIGV4dGVuZHMgU29sdmVyT3BlcmF0aW9uIGltcGxlbWVudHMgT3BlcmF0aW9uSW50ZXJmYWNlCnsKICAgIGNvbnN0IFRZUEUgPSAndW5pbnN0YWxsJzsKCiAgICAvKioKICAgICAqIEB2YXIgUGFja2FnZUludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhY2thZ2UgPSAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcGFja2FnZSBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3coJGxvY2spCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmZvcm1hdCgkdGhpcy0+cGFja2FnZSwgJGxvY2spOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0KFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRsb2NrID0gZmFsc2UpCiAgICB7CiAgICAgICAgcmV0dXJuICdSZW1vdmluZyA8aW5mbz4nLiRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJzwvaW5mbz4gKDxjb21tZW50PicuJHBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkuJzwvY29tbWVudD4pJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKLyoqCiAqIFNvbHZlciBvcGVyYXRpb24gaW50ZXJmYWNlLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgb3BlcmF0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdGlvblR5cGUoKTsKCiAgICAvKioKICAgICAqIFNlcmlhbGl6ZXMgdGhlIG9wZXJhdGlvbiBpbiBhIGh1bWFuIHJlYWRhYmxlIGZvcm1hdAogICAgICoKICAgICAqIEBwYXJhbSAgYm9vbCAgICRsb2NrIFdoZXRoZXIgdGhpcyBpcyBhbiBvcGVyYXRpb24gb24gdGhlIGxvY2sgZmlsZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3coJGxvY2spOwoKICAgIC8qKgogICAgICogU2VyaWFsaXplcyB0aGUgb3BlcmF0aW9uIGluIGEgaHVtYW4gcmVhZGFibGUgZm9ybWF0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwoKLyoqCiAqIFNvbHZlciBpbnN0YWxsIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIE1hcmtBbGlhc0luc3RhbGxlZE9wZXJhdGlvbiBleHRlbmRzIFNvbHZlck9wZXJhdGlvbiBpbXBsZW1lbnRzIE9wZXJhdGlvbkludGVyZmFjZQp7CiAgICBjb25zdCBUWVBFID0gJ21hcmtBbGlhc0luc3RhbGxlZCc7CgogICAgLyoqCiAgICAgKiBAdmFyIEFsaWFzUGFja2FnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhY2thZ2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEFsaWFzUGFja2FnZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+cGFja2FnZSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwYWNrYWdlIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gQWxpYXNQYWNrYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzaG93KCRsb2NrKQogICAgewogICAgICAgIHJldHVybiAnTWFya2luZyA8aW5mbz4nLiR0aGlzLT5wYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkuJzwvaW5mbz4gKDxjb21tZW50PicuJHRoaXMtPnBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkuJzwvY29tbWVudD4pIGFzIGluc3RhbGxlZCwgYWxpYXMgb2YgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0QWxpYXNPZigpLT5nZXRQcmV0dHlOYW1lKCkuJzwvaW5mbz4gKDxjb21tZW50PicuJHRoaXMtPnBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CgovKioKICogU29sdmVyIHVwZGF0ZSBvcGVyYXRpb24uCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBVcGRhdGVPcGVyYXRpb24gZXh0ZW5kcyBTb2x2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBPcGVyYXRpb25JbnRlcmZhY2UKewogICAgY29uc3QgVFlQRSA9ICd1cGRhdGUnOwoKICAgIC8qKgogICAgICogQHZhciBQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5pdGlhbFBhY2thZ2U7CgogICAgLyoqCiAgICAgKiBAdmFyIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHJvdGVjdGVkICR0YXJnZXRQYWNrYWdlOwoKICAgIC8qKgogICAgICogQHBhcmFtIFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwgaW5pdGlhbCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gUGFja2FnZUludGVyZmFjZSAkdGFyZ2V0ICB0YXJnZXQgcGFja2FnZSAodXBkYXRlZCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFBhY2thZ2VJbnRlcmZhY2UgJGluaXRpYWwsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbFBhY2thZ2UgPSAkaW5pdGlhbDsKICAgICAgICAkdGhpcy0+dGFyZ2V0UGFja2FnZSA9ICR0YXJnZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGluaXRpYWwgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluaXRpYWxQYWNrYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluaXRpYWxQYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0YXJnZXQgcGFja2FnZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRhcmdldFBhY2thZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGFyZ2V0UGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3coJGxvY2spCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmZvcm1hdCgkdGhpcy0+aW5pdGlhbFBhY2thZ2UsICR0aGlzLT50YXJnZXRQYWNrYWdlLCAkbG9jayk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmb3JtYXQoUGFja2FnZUludGVyZmFjZSAkaW5pdGlhbFBhY2thZ2UsIFBhY2thZ2VJbnRlcmZhY2UgJHRhcmdldFBhY2thZ2UsICRsb2NrID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGZyb21WZXJzaW9uID0gJGluaXRpYWxQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpOwogICAgICAgICR0b1ZlcnNpb24gPSAkdGFyZ2V0UGFja2FnZS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKTsKCiAgICAgICAgaWYgKCRmcm9tVmVyc2lvbiA9PT0gJHRvVmVyc2lvbiAmJiAkaW5pdGlhbFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpICE9PSAkdGFyZ2V0UGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgJGZyb21WZXJzaW9uID0gJGluaXRpYWxQYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbih0cnVlLCBQYWNrYWdlSW50ZXJmYWNlOjpESVNQTEFZX1NPVVJDRV9SRUYpOwogICAgICAgICAgICAkdG9WZXJzaW9uID0gJHRhcmdldFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfU09VUkNFX1JFRik7CiAgICAgICAgfSBlbHNlaWYgKCRmcm9tVmVyc2lvbiA9PT0gJHRvVmVyc2lvbiAmJiAkaW5pdGlhbFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSAhPT0gJHRhcmdldFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSkgewogICAgICAgICAgICAkZnJvbVZlcnNpb24gPSAkaW5pdGlhbFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfRElTVF9SRUYpOwogICAgICAgICAgICAkdG9WZXJzaW9uID0gJHRhcmdldFBhY2thZ2UtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKHRydWUsIFBhY2thZ2VJbnRlcmZhY2U6OkRJU1BMQVlfRElTVF9SRUYpOwogICAgICAgIH0KCiAgICAgICAgJGFjdGlvbk5hbWUgPSBWZXJzaW9uUGFyc2VyOjppc1VwZ3JhZGUoJGluaXRpYWxQYWNrYWdlLT5nZXRWZXJzaW9uKCksICR0YXJnZXRQYWNrYWdlLT5nZXRWZXJzaW9uKCkpID8gJ1VwZ3JhZGluZycgOiAnRG93bmdyYWRpbmcnOwoKICAgICAgICByZXR1cm4gJGFjdGlvbk5hbWUuJyA8aW5mbz4nLiRpbml0aWFsUGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiRmcm9tVmVyc2lvbi4nPC9jb21tZW50PiA9PiA8Y29tbWVudD4nLiR0b1ZlcnNpb24uJzwvY29tbWVudD4pJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcT3BlcmF0aW9uOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwoKLyoqCiAqIFNvbHZlciBpbnN0YWxsIG9wZXJhdGlvbi4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIE1hcmtBbGlhc1VuaW5zdGFsbGVkT3BlcmF0aW9uIGV4dGVuZHMgU29sdmVyT3BlcmF0aW9uIGltcGxlbWVudHMgT3BlcmF0aW9uSW50ZXJmYWNlCnsKICAgIGNvbnN0IFRZUEUgPSAnbWFya0FsaWFzVW5pbnN0YWxsZWQnOwoKICAgIC8qKgogICAgICogQHZhciBBbGlhc1BhY2thZ2UKICAgICAqLwogICAgcHJvdGVjdGVkICRwYWNrYWdlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChBbGlhc1BhY2thZ2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhY2thZ2UgPSAkcGFja2FnZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgcGFja2FnZSBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIEFsaWFzUGFja2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvdygkbG9jaykKICAgIHsKICAgICAgICByZXR1cm4gJ01hcmtpbmcgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLic8L2luZm8+ICg8Y29tbWVudD4nLiR0aGlzLT5wYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpLic8L2NvbW1lbnQ+KSBhcyB1bmluc3RhbGxlZCwgYWxpYXMgb2YgPGluZm8+Jy4kdGhpcy0+cGFja2FnZS0+Z2V0QWxpYXNPZigpLT5nZXRQcmV0dHlOYW1lKCkuJzwvaW5mbz4gKDxjb21tZW50PicuJHRoaXMtPnBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0RnVsbFByZXR0eVZlcnNpb24oKS4nPC9jb21tZW50PiknOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxPcGVyYXRpb247CgovKioKICogQWJzdHJhY3Qgb3BlcmF0aW9uIGNsYXNzLgogKgogKiBAYXV0aG9yIEFsZWtzYW5kciBCZXpwaWF0b3YgPGFsZWtzYW5kci5iZXpwaWF0b3ZAc3ByeWtlci5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBTb2x2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBPcGVyYXRpb25JbnRlcmZhY2UKewogICAgY29uc3QgVFlQRSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIG9wZXJhdGlvbiB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRpb25UeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gc3RhdGljOjpUWVBFOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zaG93KGZhbHNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJ1bGVTZXRJdGVyYXRvciBpbXBsZW1lbnRzIFxJdGVyYXRvcgp7CiAgICBwcm90ZWN0ZWQgJHJ1bGVzOwogICAgcHJvdGVjdGVkICR0eXBlczsKCiAgICBwcm90ZWN0ZWQgJGN1cnJlbnRPZmZzZXQ7CiAgICBwcm90ZWN0ZWQgJGN1cnJlbnRUeXBlOwogICAgcHJvdGVjdGVkICRjdXJyZW50VHlwZU9mZnNldDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHJ1bGVzKQogICAgewogICAgICAgICR0aGlzLT5ydWxlcyA9ICRydWxlczsKICAgICAgICAkdGhpcy0+dHlwZXMgPSBhcnJheV9rZXlzKCRydWxlcyk7CiAgICAgICAgc29ydCgkdGhpcy0+dHlwZXMpOwoKICAgICAgICAkdGhpcy0+cmV3aW5kKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXVskdGhpcy0+Y3VycmVudE9mZnNldF07CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jdXJyZW50VHlwZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmN1cnJlbnRPZmZzZXQrKzsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5jdXJyZW50T2Zmc2V0ID49IFxjb3VudCgkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRPZmZzZXQgPSAwOwoKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0Kys7CgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dHlwZXNbJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0XSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGUgPSAtMTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGUgPSAkdGhpcy0+dHlwZXNbJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0XTsKICAgICAgICAgICAgfSB3aGlsZSAoaXNzZXQoJHRoaXMtPnR5cGVzWyR0aGlzLT5jdXJyZW50VHlwZU9mZnNldF0pICYmICFcY291bnQoJHRoaXMtPnJ1bGVzWyR0aGlzLT5jdXJyZW50VHlwZV0pKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJld2luZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmN1cnJlbnRPZmZzZXQgPSAwOwoKICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGVPZmZzZXQgPSAtMTsKICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGUgPSAtMTsKCiAgICAgICAgZG8gewogICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGVPZmZzZXQrKzsKCiAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnR5cGVzWyR0aGlzLT5jdXJyZW50VHlwZU9mZnNldF0pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGUgPSAtMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y3VycmVudFR5cGUgPSAkdGhpcy0+dHlwZXNbJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0XTsKICAgICAgICB9IHdoaWxlIChpc3NldCgkdGhpcy0+dHlwZXNbJHRoaXMtPmN1cnJlbnRUeXBlT2Zmc2V0XSkgJiYgIVxjb3VudCgkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXSkpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5ydWxlc1skdGhpcy0+Y3VycmVudFR5cGVdLCAkdGhpcy0+cnVsZXNbJHRoaXMtPmN1cnJlbnRUeXBlXVskdGhpcy0+Y3VycmVudE9mZnNldF0pOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCi8qKgogKiBUaGUgUnVsZVdhdGNoR3JhcGggZWZmaWNpZW50bHkgcHJvcGFnYXRlcyBkZWNpc2lvbnMgdG8gb3RoZXIgcnVsZXMKICoKICogQWxsIHJ1bGVzIGdlbmVyYXRlZCBmb3Igc29sdmluZyBhIFNBVCBwcm9ibGVtIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIHRoZQogKiBncmFwaC4gV2hlbiBhIGRlY2lzaW9uIG9uIGEgbGl0ZXJhbCBpcyBtYWRlLCB0aGUgZ3JhcGggY2FuIGJlIHVzZWQgdG8KICogcHJvcGFnYXRlIHRoZSBkZWNpc2lvbiB0byBhbGwgb3RoZXIgcnVsZXMgaW52b2x2aW5nIHRoZSBsaXRlcmFsLCBsZWFkaW5nIHRvCiAqIG90aGVyIHRyaXZpYWwgZGVjaXNpb25zIHJlc3VsdGluZyBmcm9tIHVuaXQgY2xhdXNlcy4KICoKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJ1bGVXYXRjaEdyYXBoCnsKICAgIHByb3RlY3RlZCAkd2F0Y2hDaGFpbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogSW5zZXJ0cyBhIHJ1bGUgbm9kZSBpbnRvIHRoZSBhcHByb3ByaWF0ZSBjaGFpbnMgd2l0aGluIHRoZSBncmFwaAogICAgICoKICAgICAqIFRoZSBub2RlIGlzIHByZXBlbmRlZCB0byB0aGUgd2F0Y2ggY2hhaW5zIGZvciBlYWNoIG9mIHRoZSB0d28gbGl0ZXJhbHMgaXQKICAgICAqIHdhdGNoZXMuCiAgICAgKgogICAgICogQXNzZXJ0aW9ucyBhcmUgc2tpcHBlZCBiZWNhdXNlIHRoZXkgb25seSBkZXBlbmQgb24gYSBzaW5nbGUgcGFja2FnZSBhbmQKICAgICAqIGhhdmUgbm8gYWx0ZXJuYXRpdmUgbGl0ZXJhbCB0aGF0IGNvdWxkIGJlIHRydWUsIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8KICAgICAqIHdhdGNoIGNoYW5nZXMgaW4gYW55IGxpdGVyYWxzLgogICAgICoKICAgICAqIEBwYXJhbSBSdWxlV2F0Y2hOb2RlICRub2RlIFRoZSBydWxlIG5vZGUgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgZ3JhcGgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluc2VydChSdWxlV2F0Y2hOb2RlICRub2RlKQogICAgewogICAgICAgIGlmICgkbm9kZS0+Z2V0UnVsZSgpLT5pc0Fzc2VydGlvbigpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghJG5vZGUtPmdldFJ1bGUoKSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5KCRub2RlLT53YXRjaDEsICRub2RlLT53YXRjaDIpIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndhdGNoQ2hhaW5zWyRsaXRlcmFsXSA9IG5ldyBSdWxlV2F0Y2hDaGFpbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGhpcy0+d2F0Y2hDaGFpbnNbJGxpdGVyYWxdLT51bnNoaWZ0KCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRub2RlLT5nZXRSdWxlKCktPmdldExpdGVyYWxzKCkgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPndhdGNoQ2hhaW5zWyRsaXRlcmFsXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+d2F0Y2hDaGFpbnNbJGxpdGVyYWxdID0gbmV3IFJ1bGVXYXRjaENoYWluOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF0tPnVuc2hpZnQoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUHJvcGFnYXRlcyBhIGRlY2lzaW9uIG9uIGEgbGl0ZXJhbCB0byBhbGwgcnVsZXMgd2F0Y2hpbmcgdGhlIGxpdGVyYWwKICAgICAqCiAgICAgKiBJZiBhIGRlY2lzaW9uLCBlLmcuICtBIGhhcyBiZWVuIG1hZGUsIHRoZW4gYWxsIHJ1bGVzIGNvbnRhaW5pbmcgLUEsIGUuZy4KICAgICAqICgtQXwrQnwrQykgbm93IG5lZWQgdG8gc2F0aXNmeSBhdCBsZWFzdCBvbmUgb2YgdGhlIG90aGVyIGxpdGVyYWxzLCBzbwogICAgICogdGhhdCB0aGUgcnVsZSBhcyBhIHdob2xlIGJlY29tZXMgdHJ1ZSwgc2luY2Ugd2l0aCArQSBhcHBsaWVkIHRoZSBydWxlCiAgICAgKiBpcyBub3cgKGZhbHNlfCtCfCtDKSBzbyBlc3NlbnRpYWxseSAoK0J8K0MpLgogICAgICoKICAgICAqIFRoaXMgbWVhbnMgdGhhdCBhbGwgcnVsZXMgd2F0Y2hpbmcgdGhlIGxpdGVyYWwgLUEgbmVlZCB0byBiZSB1cGRhdGVkIHRvCiAgICAgKiB3YXRjaCAyIG90aGVyIGxpdGVyYWxzIHdoaWNoIGNhbiBzdGlsbCBiZSBzYXRpc2ZpZWQgaW5zdGVhZC4gU28gbGl0ZXJhbHMKICAgICAqIHRoYXQgY29uZmxpY3Qgd2l0aCBwcmV2aW91c2x5IG1hZGUgZGVjaXNpb25zIGFyZSBub3QgYW4gb3B0aW9uLgogICAgICoKICAgICAqIEFsdGVybmF0aXZlbHkgaXQgY2FuIG9jY3VyIHRoYXQgYSB1bml0IGNsYXVzZSByZXN1bHRzOiBlLmcuIGlmIGluIHRoZQogICAgICogYWJvdmUgZXhhbXBsZSB0aGUgcnVsZSB3YXMgKC1BfCtCKSwgdGhlbiBBIHR1cm5pbmcgdHJ1ZSBtZWFucyB0aGF0CiAgICAgKiBCIG11c3Qgbm93IGJlIGRlY2lkZWQgdHJ1ZSBhcyB3ZWxsLgogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICRkZWNpZGVkTGl0ZXJhbCBUaGUgbGl0ZXJhbCB3aGljaCB3YXMgZGVjaWRlZCAoQSBpbiBvdXIgZXhhbXBsZSkKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICRsZXZlbCAgICAgICAgICBUaGUgbGV2ZWwgYXQgd2hpY2ggdGhlIGRlY2lzaW9uIHRvb2sgcGxhY2UgYW5kIGF0IHdoaWNoCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsIHJlc3VsdGluZyBkZWNpc2lvbnMgc2hvdWxkIGJlIG1hZGUuCiAgICAgKiBAcGFyYW0gIERlY2lzaW9ucyAkZGVjaXNpb25zICAgICAgVXNlZCB0byBjaGVjayBwcmV2aW91cyBkZWNpc2lvbnMgYW5kIHRvCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXIgZGVjaXNpb25zIHJlc3VsdGluZyBmcm9tIHByb3BhZ2F0aW9uCiAgICAgKiBAcmV0dXJuIFJ1bGV8bnVsbCBJZiBhIGNvbmZsaWN0IGlzIGZvdW5kIHRoZSBjb25mbGljdGluZyBydWxlIGlzIHJldHVybmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9wYWdhdGVMaXRlcmFsKCRkZWNpZGVkTGl0ZXJhbCwgJGxldmVsLCAkZGVjaXNpb25zKQogICAgewogICAgICAgIC8vIHdlIGludmVydCB0aGUgZGVjaWRlZCBsaXRlcmFsIGhlcmUsIGV4YW1wbGU6CiAgICAgICAgLy8gQSB3YXMgZGVjaWRlZCA9PiAoLUF8Qikgbm93IHJlcXVpcmVzIEIgdG8gYmUgdHJ1ZSwgc28gd2UgbG9vayBmb3IKICAgICAgICAvLyBydWxlcyB3aGljaCBhcmUgZnVsZmlsbGVkIGJ5IC1BLCByYXRoZXIgdGhhbiBBLgogICAgICAgICRsaXRlcmFsID0gLSRkZWNpZGVkTGl0ZXJhbDsKCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+d2F0Y2hDaGFpbnNbJGxpdGVyYWxdKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRjaGFpbiA9ICR0aGlzLT53YXRjaENoYWluc1skbGl0ZXJhbF07CgogICAgICAgICRjaGFpbi0+cmV3aW5kKCk7CiAgICAgICAgd2hpbGUgKCRjaGFpbi0+dmFsaWQoKSkgewogICAgICAgICAgICAkbm9kZSA9ICRjaGFpbi0+Y3VycmVudCgpOwogICAgICAgICAgICBpZiAoISRub2RlLT5nZXRSdWxlKCkgaW5zdGFuY2VvZiBNdWx0aUNvbmZsaWN0UnVsZSkgewogICAgICAgICAgICAgICAgJG90aGVyV2F0Y2ggPSAkbm9kZS0+Z2V0T3RoZXJXYXRjaCgkbGl0ZXJhbCk7CgogICAgICAgICAgICAgICAgaWYgKCEkbm9kZS0+Z2V0UnVsZSgpLT5pc0Rpc2FibGVkKCkgJiYgISRkZWNpc2lvbnMtPnNhdGlzZnkoJG90aGVyV2F0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVMaXRlcmFscyA9ICRub2RlLT5nZXRSdWxlKCktPmdldExpdGVyYWxzKCk7CgogICAgICAgICAgICAgICAgICAgICRhbHRlcm5hdGl2ZUxpdGVyYWxzID0gYXJyYXlfZmlsdGVyKCRydWxlTGl0ZXJhbHMsIGZ1bmN0aW9uICgkcnVsZUxpdGVyYWwpIHVzZSAoJGxpdGVyYWwsICRvdGhlcldhdGNoLCAkZGVjaXNpb25zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkbGl0ZXJhbCAhPT0gJHJ1bGVMaXRlcmFsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb3RoZXJXYXRjaCAhPT0gJHJ1bGVMaXRlcmFsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhJGRlY2lzaW9ucy0+Y29uZmxpY3QoJHJ1bGVMaXRlcmFsKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRhbHRlcm5hdGl2ZUxpdGVyYWxzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCRhbHRlcm5hdGl2ZUxpdGVyYWxzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1vdmVXYXRjaCgkbGl0ZXJhbCwgY3VycmVudCgkYWx0ZXJuYXRpdmVMaXRlcmFscyksICRub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJGRlY2lzaW9ucy0+Y29uZmxpY3QoJG90aGVyV2F0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkbm9kZS0+Z2V0UnVsZSgpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9ucy0+ZGVjaWRlKCRvdGhlcldhdGNoLCAkbGV2ZWwsICRub2RlLT5nZXRSdWxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5vZGUtPmdldFJ1bGUoKS0+Z2V0TGl0ZXJhbHMoKSBhcyAkb3RoZXJMaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRsaXRlcmFsICE9PSAkb3RoZXJMaXRlcmFsICYmICEkZGVjaXNpb25zLT5zYXRpc2Z5KCRvdGhlckxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZGVjaXNpb25zLT5jb25mbGljdCgkb3RoZXJMaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRub2RlLT5nZXRSdWxlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRkZWNpc2lvbnMtPmRlY2lkZSgkb3RoZXJMaXRlcmFsLCAkbGV2ZWwsICRub2RlLT5nZXRSdWxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNoYWluLT5uZXh0KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIE1vdmVzIGEgcnVsZSBub2RlIGZyb20gb25lIHdhdGNoIGNoYWluIHRvIGFub3RoZXIKICAgICAqCiAgICAgKiBUaGUgcnVsZSBub2RlJ3Mgd2F0Y2hlZCBsaXRlcmFscyBhcmUgdXBkYXRlZCBhY2NvcmRpbmdseS4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAkZnJvbUxpdGVyYWwgQSBsaXRlcmFsIHRoZSBub2RlIHVzZWQgdG8gd2F0Y2gKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICR0b0xpdGVyYWwgICBBIGxpdGVyYWwgdGhlIG5vZGUgc2hvdWxkIHdhdGNoIG5vdwogICAgICogQHBhcmFtIFJ1bGVXYXRjaE5vZGUgJG5vZGUgICAgICAgIFRoZSBydWxlIG5vZGUgdG8gYmUgbW92ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIG1vdmVXYXRjaCgkZnJvbUxpdGVyYWwsICR0b0xpdGVyYWwsICRub2RlKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPndhdGNoQ2hhaW5zWyR0b0xpdGVyYWxdKSkgewogICAgICAgICAgICAkdGhpcy0+d2F0Y2hDaGFpbnNbJHRvTGl0ZXJhbF0gPSBuZXcgUnVsZVdhdGNoQ2hhaW47CiAgICAgICAgfQoKICAgICAgICAkbm9kZS0+bW92ZVdhdGNoKCRmcm9tTGl0ZXJhbCwgJHRvTGl0ZXJhbCk7CiAgICAgICAgJHRoaXMtPndhdGNoQ2hhaW5zWyRmcm9tTGl0ZXJhbF0tPnJlbW92ZSgpOwogICAgICAgICR0aGlzLT53YXRjaENoYWluc1skdG9MaXRlcmFsXS0+dW5zaGlmdCgkbm9kZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFV0aWxcSW5pSGVscGVyOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSZXBvc2l0b3J5U2V0OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBTb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uCnsKICAgIHByb3RlY3RlZCAkcHJvYmxlbXM7CiAgICBwcm90ZWN0ZWQgJGxlYXJuZWRQb29sOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkcHJvYmxlbXMsIGFycmF5ICRsZWFybmVkUG9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvYmxlbXMgPSAkcHJvYmxlbXM7CiAgICAgICAgJHRoaXMtPmxlYXJuZWRQb29sID0gJGxlYXJuZWRQb29sOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCdGYWlsZWQgcmVzb2x2aW5nIGRlcGVuZGVuY2llcyB3aXRoICcuY291bnQoJHByb2JsZW1zKS4nIHByb2JsZW1zLCBjYWxsIGdldFByZXR0eVN0cmluZyB0byBnZXQgZm9ybWF0dGVkIGRldGFpbHMnLCAyKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKFJlcG9zaXRvcnlTZXQgJHJlcG9zaXRvcnlTZXQsIFJlcXVlc3QgJHJlcXVlc3QsIFBvb2wgJHBvb2wsICRpc1ZlcmJvc2UsICRpc0RldkV4dHJhY3Rpb24gPSBmYWxzZSkKICAgIHsKICAgICAgICAkaW5zdGFsbGVkTWFwID0gJHJlcXVlc3QtPmdldFByZXNlbnRNYXAodHJ1ZSk7CiAgICAgICAgJGhhc0V4dGVuc2lvblByb2JsZW1zID0gZmFsc2U7CiAgICAgICAgJGlzQ2F1c2VkQnlMb2NrID0gZmFsc2U7CgogICAgICAgICRwcm9ibGVtcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2JsZW1zIGFzICRwcm9ibGVtKSB7CiAgICAgICAgICAgICRwcm9ibGVtc1tdID0gJHByb2JsZW0tPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkaW5zdGFsbGVkTWFwLCAkdGhpcy0+bGVhcm5lZFBvb2wpLiJcbiI7CgogICAgICAgICAgICBpZiAoISRoYXNFeHRlbnNpb25Qcm9ibGVtcyAmJiAkdGhpcy0+aGFzRXh0ZW5zaW9uUHJvYmxlbXMoJHByb2JsZW0tPmdldFJlYXNvbnMoKSkpIHsKICAgICAgICAgICAgICAgICRoYXNFeHRlbnNpb25Qcm9ibGVtcyA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpc0NhdXNlZEJ5TG9jayB8PSAkcHJvYmxlbS0+aXNDYXVzZWRCeUxvY2soJHJlcG9zaXRvcnlTZXQsICRyZXF1ZXN0LCAkcG9vbCk7CiAgICAgICAgfQoKICAgICAgICAkaSA9IDE7CiAgICAgICAgJHRleHQgPSAiXG4iOwogICAgICAgIGZvcmVhY2ggKGFycmF5X3VuaXF1ZSgkcHJvYmxlbXMpIGFzICRwcm9ibGVtKSB7CiAgICAgICAgICAgICR0ZXh0IC49ICIgIFByb2JsZW0gIi4oJGkrKykuJHByb2JsZW07CiAgICAgICAgfQoKICAgICAgICAkaGludHMgPSBhcnJheSgpOwogICAgICAgIGlmICghJGlzRGV2RXh0cmFjdGlvbiAmJiAoc3RycG9zKCR0ZXh0LCAnY291bGQgbm90IGJlIGZvdW5kJykgfHwgc3RycG9zKCR0ZXh0LCAnbm8gbWF0Y2hpbmcgcGFja2FnZSBmb3VuZCcpKSkgewogICAgICAgICAgICAkaGludHNbXSA9ICJQb3RlbnRpYWwgY2F1c2VzOlxuIC0gQSB0eXBvIGluIHRoZSBwYWNrYWdlIG5hbWVcbiAtIFRoZSBwYWNrYWdlIGlzIG5vdCBhdmFpbGFibGUgaW4gYSBzdGFibGUtZW5vdWdoIHZlcnNpb24gYWNjb3JkaW5nIHRvIHlvdXIgbWluaW11bS1zdGFiaWxpdHkgc2V0dGluZ1xuICAgc2VlIDxodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDQtc2NoZW1hLm1kI21pbmltdW0tc3RhYmlsaXR5PiBmb3IgbW9yZSBkZXRhaWxzLlxuIC0gSXQncyBhIHByaXZhdGUgcGFja2FnZSBhbmQgeW91IGZvcmdvdCB0byBhZGQgYSBjdXN0b20gcmVwb3NpdG9yeSB0byBmaW5kIGl0XG5cblJlYWQgPGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy9hcnRpY2xlcy90cm91Ymxlc2hvb3RpbmcubWQ+IGZvciBmdXJ0aGVyIGNvbW1vbiBwcm9ibGVtcy4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRoYXNFeHRlbnNpb25Qcm9ibGVtcykgewogICAgICAgICAgICAkaGludHNbXSA9ICR0aGlzLT5jcmVhdGVFeHRlbnNpb25IaW50KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGlzQ2F1c2VkQnlMb2NrICYmICEkaXNEZXZFeHRyYWN0aW9uICYmICEkcmVxdWVzdC0+Z2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlUm9vdERlcGVuZGVuY2llcygpKSB7CiAgICAgICAgICAgICRoaW50c1tdID0gIlVzZSB0aGUgb3B0aW9uIC0td2l0aC1hbGwtZGVwZW5kZW5jaWVzICgtVykgdG8gYWxsb3cgdXBncmFkZXMsIGRvd25ncmFkZXMgYW5kIHJlbW92YWxzIGZvciBwYWNrYWdlcyBjdXJyZW50bHkgbG9ja2VkIHRvIHNwZWNpZmljIHZlcnNpb25zLiI7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RycG9zKCR0ZXh0LCAnZm91bmQgY29tcG9zZXItcGx1Z2luLWFwaVsyLjAuMF0gYnV0IGl0IGRvZXMgbm90IG1hdGNoJykgJiYgc3RycG9zKCR0ZXh0LCAnLSBvY3JhbWl1cy9wYWNrYWdlLXZlcnNpb25zJykpIHsKICAgICAgICAgICAgJGhpbnRzW10gPSAiPHdhcm5pbmc+b2NyYW1pdXMvcGFja2FnZS12ZXJzaW9ucyBvbmx5IHByb3ZpZGVzIHN1cHBvcnQgZm9yIENvbXBvc2VyIDIgaW4gMS44Kywgd2hpY2ggcmVxdWlyZXMgUEhQIDcuNC48L3dhcm5pbmc+XG5JZiB5b3UgY2FuIG5vdCB1cGdyYWRlIFBIUCB5b3UgY2FuIHJlcXVpcmUgPGluZm8+Y29tcG9zZXIvcGFja2FnZS12ZXJzaW9ucy1kZXByZWNhdGVkPC9pbmZvPiB0byByZXNvbHZlIHRoaXMgd2l0aCBQSFAgNy4wKy4iOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJ1BIUFVuaXRcRnJhbWV3b3JrXFRlc3RDYXNlJywgZmFsc2UpKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJHRleHQsICdmb3VuZCBjb21wb3Nlci1wbHVnaW4tYXBpWzIuMC4wXSBidXQgaXQgZG9lcyBub3QgbWF0Y2gnKSkgewogICAgICAgICAgICAgICAgJGhpbnRzW10gPSAiWW91IGFyZSB1c2luZyBDb21wb3NlciAyLCB3aGljaCBzb21lIG9mIHlvdXIgcGx1Z2lucyBzZWVtIHRvIGJlIGluY29tcGF0aWJsZSB3aXRoLiBNYWtlIHN1cmUgeW91IHVwZGF0ZSB5b3VyIHBsdWdpbnMgb3IgcmVwb3J0IGEgcGx1Z2luLWlzc3VlIHRvIGFzayB0aGVtIHRvIHN1cHBvcnQgQ29tcG9zZXIgMi4iOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhpbnRzKSB7CiAgICAgICAgICAgICR0ZXh0IC49ICJcbiIgLiBpbXBsb2RlKCJcblxuIiwgJGhpbnRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvYmxlbXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvYmxlbXM7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVFeHRlbnNpb25IaW50KCkKICAgIHsKICAgICAgICAkcGF0aHMgPSBJbmlIZWxwZXI6OmdldEFsbCgpOwoKICAgICAgICBpZiAoY291bnQoJHBhdGhzKSA9PT0gMSAmJiBlbXB0eSgkcGF0aHNbMF0pKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICR0ZXh0ID0gIlRvIGVuYWJsZSBleHRlbnNpb25zLCB2ZXJpZnkgdGhhdCB0aGV5IGFyZSBlbmFibGVkIGluIHlvdXIgLmluaSBmaWxlczpcbiAgICAtICI7CiAgICAgICAgJHRleHQgLj0gaW1wbG9kZSgiXG4gICAgLSAiLCAkcGF0aHMpOwogICAgICAgICR0ZXh0IC49ICJcbllvdSBjYW4gYWxzbyBydW4gYHBocCAtLWluaWAgaW5zaWRlIHRlcm1pbmFsIHRvIHNlZSB3aGljaCBmaWxlcyBhcmUgdXNlZCBieSBQSFAgaW4gQ0xJIG1vZGUuIjsKCiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaGFzRXh0ZW5zaW9uUHJvYmxlbXMoYXJyYXkgJHJlYXNvblNldHMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHJlYXNvblNldHMgYXMgJHJlYXNvblNldCkgewogICAgICAgICAgICBmb3JlYWNoICgkcmVhc29uU2V0IGFzICRydWxlKSB7CiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRydWxlLT5nZXRSZXF1aXJlZFBhY2thZ2UoKSwgJ2V4dC0nKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXEV2ZW50RGlzcGF0Y2hlclxFdmVudERpc3BhdGNoZXI7CnVzZSBDb21wb3NlclxJT1xJT0ludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxTdGFiaWxpdHlGaWx0ZXI7CnVzZSBDb21wb3NlclxQbHVnaW5cUGx1Z2luRXZlbnRzOwp1c2UgQ29tcG9zZXJcUGx1Z2luXFByZVBvb2xDcmVhdGVFdmVudDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxSb290UGFja2FnZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29tcGlsaW5nTWF0Y2hlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTXVsdGlDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXEludGVydmFsczsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUG9vbEJ1aWxkZXIKewogICAgLyoqCiAgICAgKiBAdmFyIGludFtdCiAgICAgKi8KICAgIHByaXZhdGUgJGFjY2VwdGFibGVTdGFiaWxpdGllczsKICAgIC8qKgogICAgICogQHZhciBpbnRbXQogICAgICovCiAgICBwcml2YXRlICRzdGFiaWxpdHlGbGFnczsKICAgIC8qKgogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXl7YWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4+CiAgICAgKi8KICAgIHByaXZhdGUgJHJvb3RBbGlhc2VzOwogICAgLyoqCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgc3RyaW5nPgogICAgICovCiAgICBwcml2YXRlICRyb290UmVmZXJlbmNlczsKICAgIC8qKgogICAgICogQHZhciBFdmVudERpc3BhdGNoZXIKICAgICAqLwogICAgcHJpdmF0ZSAkZXZlbnREaXNwYXRjaGVyOwogICAgLyoqCiAgICAgKiBAdmFyIElPSW50ZXJmYWNlCiAgICAgKi8KICAgIHByaXZhdGUgJGlvOwogICAgLyoqCiAgICAgKiBAcHNhbG0tdmFyIGFycmF5PHN0cmluZywgQWxpYXNQYWNrYWdlPgogICAgICovCiAgICBwcml2YXRlICRhbGlhc01hcCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRwYWNrYWdlc1RvTG9hZCA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEBwc2FsbS12YXIgYXJyYXk8c3RyaW5nLCBDb25zdHJhaW50SW50ZXJmYWNlPgogICAgICovCiAgICBwcml2YXRlICRsb2FkZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEBwc2FsbS12YXIgYXJyYXk8aW50LCBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgUGFja2FnZUludGVyZmFjZT4+PgogICAgICovCiAgICBwcml2YXRlICRsb2FkZWRQZXJSZXBvID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHBzYWxtLXZhciBQYWNrYWdlW10KICAgICAqLwogICAgcHJpdmF0ZSAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgLyoqCiAgICAgKiBAcHNhbG0tdmFyIGxpc3Q8UGFja2FnZT4KICAgICAqLwogICAgcHJpdmF0ZSAkdW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJHVwZGF0ZUFsbG93TGlzdCA9IGFycmF5KCk7CiAgICBwcml2YXRlICRza2lwcGVkTG9hZCA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBLZWVwcyBhIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIHdoaWNoIGFyZSByb290IHJlcXVpcmVtZW50cywgYW5kIGFzIHN1Y2gKICAgICAqIGhhdmUgYWxyZWFkeSB0aGVpciBtYXhpbXVtIHJlcXVpcmVkIHJhbmdlIGxvYWRlZCBhbmQgY2FuIG5vdCBiZQogICAgICogZXh0ZW5kZWQgYnkgbWFya1BhY2thZ2VOYW1lRm9yTG9hZGluZwogICAgICoKICAgICAqIFBhY2thZ2VzIGdldCBjbGVhcmVkIGZyb20gdGhpcyBsaXN0IGlmIHRoZXkgZ2V0IHVubG9ja2VkIGFzIGluIHRoYXQgY2FzZQogICAgICogd2UgbmVlZCB0byBhY3R1YWxseSBsb2FkIHRoZW0KICAgICAqLwogICAgcHJpdmF0ZSAkbWF4RXh0ZW5kZWRSZXFzID0gYXJyYXkoKTsKICAgIC8qKgogICAgICogQHBzYWxtLXZhciBhcnJheTxzdHJpbmcsIGJvb2w+CiAgICAgKi8KICAgIHByaXZhdGUgJHVwZGF0ZUFsbG93V2FybmVkID0gYXJyYXkoKTsKCiAgICBwcml2YXRlICRpbmRleENvdW50ZXIgPSAwOwoKICAgIC8qKgogICAgICogQHBhcmFtIGludFtdICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMgYXJyYXkgb2Ygc3RhYmlsaXR5ID0+IEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKiB2YWx1ZQogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgQmFzZVBhY2thZ2U6OlNUQUJJTElUWV8qPiAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzCiAgICAgKiBAcGFyYW0gaW50W10gJHN0YWJpbGl0eUZsYWdzIGFuIGFycmF5IG9mIHBhY2thZ2UgbmFtZSA9PiBCYXNlUGFja2FnZTo6U1RBQklMSVRZXyogdmFsdWUKICAgICAqIEBwc2FsbS1wYXJhbSBhcnJheTxzdHJpbmcsIEJhc2VQYWNrYWdlOjpTVEFCSUxJVFlfKj4gJHN0YWJpbGl0eUZsYWdzCiAgICAgKiBAcGFyYW0gYXJyYXlbXSAkcm9vdEFsaWFzZXMKICAgICAqIEBwc2FsbS1wYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PHN0cmluZywgYXJyYXl7YWxpYXM6IHN0cmluZywgYWxpYXNfbm9ybWFsaXplZDogc3RyaW5nfT4+ICRyb290QWxpYXNlcwogICAgICogQHBhcmFtIHN0cmluZ1tdICRyb290UmVmZXJlbmNlcyBhbiBhcnJheSBvZiBwYWNrYWdlIG5hbWUgPT4gc291cmNlIHJlZmVyZW5jZQogICAgICogQHBzYWxtLXBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkcm9vdFJlZmVyZW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRhY2NlcHRhYmxlU3RhYmlsaXRpZXMsIGFycmF5ICRzdGFiaWxpdHlGbGFncywgYXJyYXkgJHJvb3RBbGlhc2VzLCBhcnJheSAkcm9vdFJlZmVyZW5jZXMsIElPSW50ZXJmYWNlICRpbywgRXZlbnREaXNwYXRjaGVyICRldmVudERpc3BhdGNoZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMgPSAkYWNjZXB0YWJsZVN0YWJpbGl0aWVzOwogICAgICAgICR0aGlzLT5zdGFiaWxpdHlGbGFncyA9ICRzdGFiaWxpdHlGbGFnczsKICAgICAgICAkdGhpcy0+cm9vdEFsaWFzZXMgPSAkcm9vdEFsaWFzZXM7CiAgICAgICAgJHRoaXMtPnJvb3RSZWZlcmVuY2VzID0gJHJvb3RSZWZlcmVuY2VzOwogICAgICAgICR0aGlzLT5ldmVudERpc3BhdGNoZXIgPSAkZXZlbnREaXNwYXRjaGVyOwogICAgICAgICR0aGlzLT5pbyA9ICRpbzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYnVpbGRQb29sKGFycmF5ICRyZXBvc2l0b3JpZXMsIFJlcXVlc3QgJHJlcXVlc3QpCiAgICB7CiAgICAgICAgaWYgKCRyZXF1ZXN0LT5nZXRVcGRhdGVBbGxvd0xpc3QoKSkgewogICAgICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dMaXN0ID0gJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93TGlzdCgpOwogICAgICAgICAgICAkdGhpcy0+d2FybkFib3V0Tm9uTWF0Y2hpbmdVcGRhdGVBbGxvd0xpc3QoJHJlcXVlc3QpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldExvY2tlZFJlcG9zaXRvcnkoKS0+Z2V0UGFja2FnZXMoKSBhcyAkbG9ja2VkUGFja2FnZSkgewogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+aXNVcGRhdGVBbGxvd2VkKCRsb2NrZWRQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgICRyZXF1ZXN0LT5sb2NrUGFja2FnZSgkbG9ja2VkUGFja2FnZSk7CiAgICAgICAgICAgICAgICAgICAgJGxvY2tlZE5hbWUgPSAkbG9ja2VkUGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICAgICAgICAgIC8vIHJlbWVtYmVyIHdoaWNoIHBhY2thZ2VzIHdlIHNraXBwZWQgbG9hZGluZyByZW1vdGUgY29udGVudCBmb3IgaW4gdGhpcyBwYXJ0aWFsIHVwZGF0ZQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5za2lwcGVkTG9hZFskbG9ja2VkTmFtZV0gPSAkbG9ja2VkTmFtZTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbG9ja2VkUGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2tpcHBlZExvYWRbJGxpbmstPmdldFRhcmdldCgpXSA9ICRsb2NrZWROYW1lOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldEZpeGVkT3JMb2NrZWRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIC8vIHVzaW5nIE1hdGNoQWxsQ29uc3RyYWludCBoZXJlIGJlY2F1c2UgZml4ZWQgcGFja2FnZXMgZG8gbm90IG5lZWQgdG8gcmV0cmlnZ2VyCiAgICAgICAgICAgIC8vIGxvYWRpbmcgYW55IHBhY2thZ2VzCiAgICAgICAgICAgICR0aGlzLT5sb2FkZWRQYWNrYWdlc1skcGFja2FnZS0+Z2V0TmFtZSgpXSA9IG5ldyBNYXRjaEFsbENvbnN0cmFpbnQoKTsKCiAgICAgICAgICAgIC8vIHJlcGxhY2UgbWVhbnMgY29uZmxpY3QsIHNvIGlmIGEgZml4ZWQgcGFja2FnZSByZXBsYWNlcyBhIG5hbWUsIG5vIG5lZWQgdG8gbG9hZCB0aGF0IG9uZSwgcGFja2FnZXMgd291bGQgY29uZmxpY3QgYW55d2F5cwogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRsaW5rLT5nZXRUYXJnZXQoKV0gPSBuZXcgTWF0Y2hBbGxDb25zdHJhaW50KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRPRE8gaW4gaG93IGZhciBjYW4gd2UgZG8gdGhlIGFib3ZlIGZvciBjb25mbGljdHM/IEl0J3MgbW9yZSB0cmlja3kgY2F1c2UgY29uZmxpY3RzIGNhbiBiZSBsaW1pdGVkIHRvCiAgICAgICAgICAgIC8vIHNwZWNpZmljIHZlcnNpb25zIHdoaWxlIHJlcGxhY2UgaXMgYSBjb25mbGljdCB3aXRoIGFsbCB2ZXJzaW9ucyBvZiB0aGUgbmFtZQoKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKSBpbnN0YW5jZW9mIFJvb3RQYWNrYWdlUmVwb3NpdG9yeQogICAgICAgICAgICAgICAgfHwgJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKSBpbnN0YW5jZW9mIFBsYXRmb3JtUmVwb3NpdG9yeQogICAgICAgICAgICAgICAgfHwgU3RhYmlsaXR5RmlsdGVyOjppc1BhY2thZ2VBY2NlcHRhYmxlKCR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsICR0aGlzLT5zdGFiaWxpdHlGbGFncywgJHBhY2thZ2UtPmdldE5hbWVzKCksICRwYWNrYWdlLT5nZXRTdGFiaWxpdHkoKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZFBhY2thZ2UoJHJlcXVlc3QsICRwYWNrYWdlLCBmYWxzZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldFJlcXVpcmVzKCkgYXMgJHBhY2thZ2VOYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgIC8vIGZpeGVkIGFuZCBsb2NrZWQgcGFja2FnZXMgaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQsIHNvIGlmIGEgcm9vdCByZXF1aXJlIG5lZWRzIG9uZSBvZiB0aGVtLCBubyBuZWVkIHRvIGRvIGFueXRoaW5nCiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+bG9hZGVkUGFja2FnZXNbJHBhY2thZ2VOYW1lXSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+cGFja2FnZXNUb0xvYWRbJHBhY2thZ2VOYW1lXSA9ICRjb25zdHJhaW50OwogICAgICAgICAgICAkdGhpcy0+bWF4RXh0ZW5kZWRSZXFzWyRwYWNrYWdlTmFtZV0gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gY2xlYW4gdXAgcGFja2FnZXNUb0xvYWQgZm9yIGFueXRoaW5nIHdlIG1hbnVhbGx5IG1hcmtlZCBsb2FkZWQgYWJvdmUKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZXNUb0xvYWQgYXMgJG5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5sb2FkZWRQYWNrYWdlc1skbmFtZV0pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cGFja2FnZXNUb0xvYWRbJG5hbWVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKCFlbXB0eSgkdGhpcy0+cGFja2FnZXNUb0xvYWQpKSB7CiAgICAgICAgICAgICR0aGlzLT5sb2FkUGFja2FnZXNNYXJrZWRGb3JMb2FkaW5nKCRyZXF1ZXN0LCAkcmVwb3NpdG9yaWVzKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlcyBhcyAkaSA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAvLyB3ZSBjaGVjayBhbGwgYWxpYXMgcmVsYXRlZCBwYWNrYWdlcyBhdCBvbmNlLCBzbyBubyBuZWVkIHRvIGNoZWNrIGluZGl2aWR1YWwgYWxpYXNlcwogICAgICAgICAgICAvLyBpc3NldCBhbHNvIGNoZWNrcyBub24tbnVsbCB2YWx1ZQogICAgICAgICAgICBpZiAoISRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9PScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgJGFsaWFzZWRQYWNrYWdlcyA9IGFycmF5KCRpID0+ICRwYWNrYWdlKTsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+YWxpYXNNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGFsaWFzZWRQYWNrYWdlcyArPSAkdGhpcy0+YWxpYXNNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJGZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYWxpYXNlZFBhY2thZ2VzIGFzICRwYWNrYWdlT3JBbGlhcykgewogICAgICAgICAgICAgICAgICAgIGlmIChDb21waWxpbmdNYXRjaGVyOjptYXRjaCgkY29uc3RyYWludCwgQ29uc3RyYWludDo6T1BfRVEsICRwYWNrYWdlT3JBbGlhcy0+Z2V0VmVyc2lvbigpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghJGZvdW5kKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGFsaWFzZWRQYWNrYWdlcyBhcyAkaW5kZXggPT4gJHBhY2thZ2VPckFsaWFzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5wYWNrYWdlc1skaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+ZXZlbnREaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICRwcmVQb29sQ3JlYXRlRXZlbnQgPSBuZXcgUHJlUG9vbENyZWF0ZUV2ZW50KAogICAgICAgICAgICAgICAgUGx1Z2luRXZlbnRzOjpQUkVfUE9PTF9DUkVBVEUsCiAgICAgICAgICAgICAgICAkcmVwb3NpdG9yaWVzLAogICAgICAgICAgICAgICAgJHJlcXVlc3QsCiAgICAgICAgICAgICAgICAkdGhpcy0+YWNjZXB0YWJsZVN0YWJpbGl0aWVzLAogICAgICAgICAgICAgICAgJHRoaXMtPnN0YWJpbGl0eUZsYWdzLAogICAgICAgICAgICAgICAgJHRoaXMtPnJvb3RBbGlhc2VzLAogICAgICAgICAgICAgICAgJHRoaXMtPnJvb3RSZWZlcmVuY2VzLAogICAgICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2VzLAogICAgICAgICAgICAgICAgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcwogICAgICAgICAgICApOwogICAgICAgICAgICAkdGhpcy0+ZXZlbnREaXNwYXRjaGVyLT5kaXNwYXRjaCgkcHJlUG9vbENyZWF0ZUV2ZW50LT5nZXROYW1lKCksICRwcmVQb29sQ3JlYXRlRXZlbnQpOwogICAgICAgICAgICAkdGhpcy0+cGFja2FnZXMgPSAkcHJlUG9vbENyZWF0ZUV2ZW50LT5nZXRQYWNrYWdlcygpOwogICAgICAgICAgICAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzID0gJHByZVBvb2xDcmVhdGVFdmVudC0+Z2V0VW5hY2NlcHRhYmxlRml4ZWRQYWNrYWdlcygpOwogICAgICAgIH0KCiAgICAgICAgJHBvb2wgPSBuZXcgUG9vbCgkdGhpcy0+cGFja2FnZXMsICR0aGlzLT51bmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZXMpOwoKICAgICAgICAkdGhpcy0+YWxpYXNNYXAgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5wYWNrYWdlc1RvTG9hZCA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmxvYWRlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+bG9hZGVkUGVyUmVwbyA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+bWF4RXh0ZW5kZWRSZXFzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+c2tpcHBlZExvYWQgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5pbmRleENvdW50ZXIgPSAwOwoKICAgICAgICBJbnRlcnZhbHM6OmNsZWFyKCk7CgogICAgICAgIHJldHVybiAkcG9vbDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoUmVxdWVzdCAkcmVxdWVzdCwgJG5hbWUsIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgLy8gU2tpcCBwbGF0Zm9ybSByZXF1aXJlcyBhdCB0aGlzIHN0YWdlCiAgICAgICAgaWYgKFBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFJvb3QgcmVxdWlyZSAod2hpY2ggd2FzIG5vdCB1bmxvY2tlZCkgYWxyZWFkeSBsb2FkZWQgdGhlIG1heGltdW0gcmFuZ2Ugc28gbm8KICAgICAgICAvLyBuZWVkIHRvIGNoZWNrIGFueXRoaW5nIGhlcmUKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm1heEV4dGVuZGVkUmVxc1skbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFJvb3QgcmVxdWlyZXMgY2FuIG5vdCBiZSBvdmVycnVsZWQgYnkgZGVwZW5kZW5jaWVzIHNvIHRoZXJlIGlzIG5vIHBvaW50IGluCiAgICAgICAgLy8gZXh0ZW5kaW5nIHRoZSBsb2FkZWQgY29uc3RyYWludCBmb3IgdGhvc2UuCiAgICAgICAgLy8gVGhpcyBpcyB0cmlnZ2VyZWQgd2hlbiBsb2FkaW5nIGEgcm9vdCByZXF1aXJlIHdoaWNoIHdhcyBsb2NrZWQgYnV0IGdvdCB1bmxvY2tlZCwgdGhlbgogICAgICAgIC8vIHdlIG1ha2Ugc3VyZSB0aGF0IHdlIGxvYWQgYXQgbW9zdCB0aGUgaW50ZXJ2YWxzIGNvdmVyZWQgYnkgdGhlIHJvb3QgY29uc3RyYWludC4KICAgICAgICAkcm9vdFJlcXVpcmVzID0gJHJlcXVlc3QtPmdldFJlcXVpcmVzKCk7CiAgICAgICAgaWYgKGlzc2V0KCRyb290UmVxdWlyZXNbJG5hbWVdKSAmJiAhSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkcm9vdFJlcXVpcmVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkcm9vdFJlcXVpcmVzWyRuYW1lXTsKICAgICAgICB9CgogICAgICAgIC8vIE5vdCB5ZXQgbG9hZGVkIG9yIGFscmVhZHkgbWFya2VkIGZvciBhIHJlbG9hZCwgc2V0IHRoZSBjb25zdHJhaW50IHRvIGJlIGxvYWRlZAogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgLy8gTWF5YmUgaXQgd2FzIGFscmVhZHkgbWFya2VkIGJlZm9yZSBidXQgbm90IGxvYWRlZCB5ZXQuIEluIHRoYXQgY2FzZQogICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGV4dGVuZCB0aGUgY29uc3RyYWludCAod2UgZG9uJ3QgY2hlY2sgaWYgdGhleSBhcmUgaWRlbnRpY2FsIGJlY2F1c2UKICAgICAgICAgICAgLy8gTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoKSB3aWxsIG9wdGltaXplIGFueXdheSkKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wYWNrYWdlc1RvTG9hZFskbmFtZV0pKSB7CiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IG1hcmtlZCBmb3IgbG9hZGluZyBhbmQgdGhpcyBkb2VzIG5vdCBleHBhbmQgdGhlIGNvbnN0cmFpbnQgdG8gYmUgbG9hZGVkLCBub3RoaW5nIHRvIGRvCiAgICAgICAgICAgICAgICBpZiAoSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkdGhpcy0+cGFja2FnZXNUb0xvYWRbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBleHRlbmQgdGhlIGNvbnN0cmFpbnQgdG8gYmUgbG9hZGVkCiAgICAgICAgICAgICAgICAkY29uc3RyYWludCA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJHRoaXMtPnBhY2thZ2VzVG9Mb2FkWyRuYW1lXSwgJGNvbnN0cmFpbnQpLCBmYWxzZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+cGFja2FnZXNUb0xvYWRbJG5hbWVdID0gJGNvbnN0cmFpbnQ7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBObyBuZWVkIHRvIGxvYWQgdGhpcyBwYWNrYWdlIHdpdGggdGhpcyBjb25zdHJhaW50IGJlY2F1c2UgaXQgaXMKICAgICAgICAvLyBhIHN1YnNldCBvZiB0aGUgY29uc3RyYWludCB3aXRoIHdoaWNoIHdlIGhhdmUgYWxyZWFkeSBsb2FkZWQgcGFja2FnZXMKICAgICAgICBpZiAoSW50ZXJ2YWxzOjppc1N1YnNldE9mKCRjb25zdHJhaW50LCAkdGhpcy0+bG9hZGVkUGFja2FnZXNbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBXZSBoYXZlIGFscmVhZHkgbG9hZGVkIHRoYXQgcGFja2FnZSBidXQgbm90IGluIHRoZSBjb25zdHJhaW50IHRoYXQncwogICAgICAgIC8vIHJlcXVpcmVkLiBXZSBleHRlbmQgdGhlIGNvbnN0cmFpbnQgYW5kIG1hcmsgdGhhdCBwYWNrYWdlIGFzIG5vdCBiZWluZyBsb2FkZWQKICAgICAgICAvLyB5ZXQgc28gd2UgZ2V0IHRoZSByZXF1aXJlZCBwYWNrYWdlIHZlcnNpb25zCiAgICAgICAgJHRoaXMtPnBhY2thZ2VzVG9Mb2FkWyRuYW1lXSA9IEludGVydmFsczo6Y29tcGFjdENvbnN0cmFpbnQoTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoYXJyYXkoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRuYW1lXSwgJGNvbnN0cmFpbnQpLCBmYWxzZSkpOwogICAgICAgIHVuc2V0KCR0aGlzLT5sb2FkZWRQYWNrYWdlc1skbmFtZV0pOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZFBhY2thZ2VzTWFya2VkRm9yTG9hZGluZyhSZXF1ZXN0ICRyZXF1ZXN0LCAkcmVwb3NpdG9yaWVzKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlc1RvTG9hZCBhcyAkbmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICAkdGhpcy0+bG9hZGVkUGFja2FnZXNbJG5hbWVdID0gJGNvbnN0cmFpbnQ7CiAgICAgICAgfQoKICAgICAgICAkcGFja2FnZUJhdGNoID0gJHRoaXMtPnBhY2thZ2VzVG9Mb2FkOwogICAgICAgICR0aGlzLT5wYWNrYWdlc1RvTG9hZCA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRyZXBvc2l0b3JpZXMgYXMgJHJlcG9JbmRleCA9PiAkcmVwb3NpdG9yeSkgewogICAgICAgICAgICBpZiAoZW1wdHkoJHBhY2thZ2VCYXRjaCkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyB0aGVzZSByZXBvcyBoYXZlIHRoZWlyIHBhY2thZ2VzIGZpeGVkIG9yIGxvY2tlZCBpZiB0aGV5IG5lZWQgdG8gYmUgbG9hZGVkIHNvIHdlCiAgICAgICAgICAgIC8vIG5ldmVyIG5lZWQgdG8gbG9hZCBhbnl0aGluZyBlbHNlIGZyb20gdGhlbQogICAgICAgICAgICBpZiAoJHJlcG9zaXRvcnkgaW5zdGFuY2VvZiBQbGF0Zm9ybVJlcG9zaXRvcnkgfHwgJHJlcG9zaXRvcnkgPT09ICRyZXF1ZXN0LT5nZXRMb2NrZWRSZXBvc2l0b3J5KCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHQgPSAkcmVwb3NpdG9yeS0+bG9hZFBhY2thZ2VzKCRwYWNrYWdlQmF0Y2gsICR0aGlzLT5hY2NlcHRhYmxlU3RhYmlsaXRpZXMsICR0aGlzLT5zdGFiaWxpdHlGbGFncywgaXNzZXQoJHRoaXMtPmxvYWRlZFBlclJlcG9bJHJlcG9JbmRleF0pID8gJHRoaXMtPmxvYWRlZFBlclJlcG9bJHJlcG9JbmRleF0gOiBhcnJheSgpKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXN1bHRbJ25hbWVzRm91bmQnXSBhcyAkbmFtZSkgewogICAgICAgICAgICAgICAgLy8gYXZvaWQgbG9hZGluZyB0aGUgc2FtZSBwYWNrYWdlIGFnYWluIGZyb20gb3RoZXIgcmVwb3NpdG9yaWVzIG9uY2UgaXQgaGFzIGJlZW4gZm91bmQKICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlQmF0Y2hbJG5hbWVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkcmVzdWx0WydwYWNrYWdlcyddIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG9hZGVkUGVyUmVwb1skcmVwb0luZGV4XVskcGFja2FnZS0+Z2V0TmFtZSgpXVskcGFja2FnZS0+Z2V0VmVyc2lvbigpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgJHRoaXMtPmxvYWRQYWNrYWdlKCRyZXF1ZXN0LCAkcGFja2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkUGFja2FnZShSZXF1ZXN0ICRyZXF1ZXN0LCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkcHJvcGFnYXRlVXBkYXRlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkaW5kZXggPSAkdGhpcy0+aW5kZXhDb3VudGVyKys7CiAgICAgICAgJHRoaXMtPnBhY2thZ2VzWyRpbmRleF0gPSAkcGFja2FnZTsKCiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT5hbGlhc01hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UtPmdldEFsaWFzT2YoKSldWyRpbmRleF0gPSAkcGFja2FnZTsKICAgICAgICB9CgogICAgICAgICRuYW1lID0gJHBhY2thZ2UtPmdldE5hbWUoKTsKCiAgICAgICAgLy8gd2UncmUgc2ltcGx5IHNldHRpbmcgdGhlIHJvb3QgcmVmZXJlbmNlcyBvbiBhbGwgdmVyc2lvbnMgZm9yIGEgbmFtZSBoZXJlIGFuZCByZWx5IG9uIHRoZSBzb2x2ZXIgdG8gcGljayB0aGUKICAgICAgICAvLyByaWdodCB2ZXJzaW9uLiBJdCdkIGJlIG1vcmUgd29yayB0byBmaWd1cmUgb3V0IHdoaWNoIHZlcnNpb25zIGFuZCB3aGljaCBhbGlhc2VzIG9mIHRob3NlIHZlcnNpb25zIHRoaXMgbWF5CiAgICAgICAgLy8gYXBwbHkgdG8KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJvb3RSZWZlcmVuY2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgLy8gZG8gbm90IG1vZGlmeSB0aGUgcmVmZXJlbmNlcyBvbiBhbHJlYWR5IGxvY2tlZCBvciBmaXhlZCBwYWNrYWdlcwogICAgICAgICAgICBpZiAoISRyZXF1ZXN0LT5pc0xvY2tlZFBhY2thZ2UoJHBhY2thZ2UpICYmICEkcmVxdWVzdC0+aXNGaXhlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZS0+c2V0U291cmNlRGlzdFJlZmVyZW5jZXMoJHRoaXMtPnJvb3RSZWZlcmVuY2VzWyRuYW1lXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGlmIHByb3BvZ2F0ZVVwZGF0ZSBpcyBmYWxzZSB3ZSBhcmUgbG9hZGluZyBhIGZpeGVkIG9yIGxvY2tlZCBwYWNrYWdlLCByb290IGFsaWFzZXMgZG8gbm90IGFwcGx5IGFzIHRoZXkgYXJlCiAgICAgICAgLy8gbWFudWFsbHkgbG9hZGVkIGFzIHNlcGFyYXRlIHBhY2thZ2VzIGluIHRoaXMgY2FzZQogICAgICAgIGlmICgkcHJvcGFnYXRlVXBkYXRlICYmIGlzc2V0KCR0aGlzLT5yb290QWxpYXNlc1skbmFtZV1bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0pKSB7CiAgICAgICAgICAgICRhbGlhcyA9ICR0aGlzLT5yb290QWxpYXNlc1skbmFtZV1bJHBhY2thZ2UtPmdldFZlcnNpb24oKV07CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGJhc2VQYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRiYXNlUGFja2FnZSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSBuZXcgQWxpYXNQYWNrYWdlKCRiYXNlUGFja2FnZSwgJGFsaWFzWydhbGlhc19ub3JtYWxpemVkJ10sICRhbGlhc1snYWxpYXMnXSk7CiAgICAgICAgICAgICRhbGlhc1BhY2thZ2UtPnNldFJvb3RQYWNrYWdlQWxpYXModHJ1ZSk7CgogICAgICAgICAgICAkbmV3SW5kZXggPSAkdGhpcy0+aW5kZXhDb3VudGVyKys7CiAgICAgICAgICAgICR0aGlzLT5wYWNrYWdlc1skbmV3SW5kZXhdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICAgICAgJHRoaXMtPmFsaWFzTWFwW3NwbF9vYmplY3RfaGFzaCgkYWxpYXNQYWNrYWdlLT5nZXRBbGlhc09mKCkpXVskbmV3SW5kZXhdID0gJGFsaWFzUGFja2FnZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICRyZXF1aXJlID0gJGxpbmstPmdldFRhcmdldCgpOwogICAgICAgICAgICAkbGlua0NvbnN0cmFpbnQgPSAkbGluay0+Z2V0Q29uc3RyYWludCgpOwoKICAgICAgICAgICAgLy8gaWYgdGhlIHJlcXVpcmVkIHBhY2thZ2UgaXMgbG9hZGVkIGFzIGEgbG9ja2VkIHBhY2thZ2Ugb25seSBhbmQgaGFzbid0IGhhZCBpdHMgZGVwcyBhbmFseXplZAogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnNraXBwZWRMb2FkWyRyZXF1aXJlXSkpIHsKICAgICAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIGEgZnVsbCB1cGRhdGUgb3IgdGhpcyBpcyBhIHBhcnRpYWwgdXBkYXRlIHdpdGggdHJhbnNpdGl2ZSBkZXBzIGFuZCB3ZSdyZSBjdXJyZW50bHkKICAgICAgICAgICAgICAgIC8vIGxvb2tpbmcgYXQgYSBwYWNrYWdlIHdoaWNoIG5lZWRzIHRvIGJlIHVwZGF0ZWQgd2UgbmVlZCB0byB1bmxvY2sgdGhlIHBhY2thZ2Ugd2Ugbm93IGtub3cgaXMgYQogICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jeSBvZiBhbm90aGVyIHBhY2thZ2Ugd2hpY2ggd2UgYXJlIHRyeWluZyB0byB1cGRhdGUsIGFuZCB0aGVuIGF0dGVtcHQgdG8gbG9hZCBpdCBhZ2FpbgogICAgICAgICAgICAgICAgaWYgKCRwcm9wYWdhdGVVcGRhdGUgJiYgJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcygpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXF1ZXN0LT5nZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVSb290RGVwZW5kZW5jaWVzKCkgfHwgISR0aGlzLT5pc1Jvb3RSZXF1aXJlKCRyZXF1ZXN0LCAkdGhpcy0+c2tpcHBlZExvYWRbJHJlcXVpcmVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dW5sb2NrUGFja2FnZSgkcmVxdWVzdCwgJHJlcXVpcmUpOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bWFya1BhY2thZ2VOYW1lRm9yTG9hZGluZygkcmVxdWVzdCwgJHJlcXVpcmUsICRsaW5rQ29uc3RyYWludCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCFpc3NldCgkdGhpcy0+dXBkYXRlQWxsb3dXYXJuZWRbJHRoaXMtPnNraXBwZWRMb2FkWyRyZXF1aXJlXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cGRhdGVBbGxvd1dhcm5lZFskdGhpcy0+c2tpcHBlZExvYWRbJHJlcXVpcmVdXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+RGVwZW5kZW5jeSAiJy4kdGhpcy0+c2tpcHBlZExvYWRbJHJlcXVpcmVdLiciIGlzIGFsc28gYSByb290IHJlcXVpcmVtZW50LiBQYWNrYWdlIGhhcyBub3QgYmVlbiBsaXN0ZWQgYXMgYW4gdXBkYXRlIGFyZ3VtZW50LCBzbyBrZWVwaW5nIGxvY2tlZCBhdCBvbGQgdmVyc2lvbi4gVXNlIC0td2l0aC1hbGwtZGVwZW5kZW5jaWVzICgtVykgdG8gaW5jbHVkZSByb290IGRlcGVuZGVuY2llcy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRyZXF1aXJlLCAkbGlua0NvbnN0cmFpbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB3ZSdyZSBkb2luZyBhIHBhcnRpYWwgdXBkYXRlIHdpdGggZGVwcyB3ZSBhbHNvIG5lZWQgdG8gdW5sb2NrIHBhY2thZ2VzIHdoaWNoIGFyZSBiZWluZyByZXBsYWNlZCBpbiBjYXNlCiAgICAgICAgLy8gdGhleSBhcmUgY3VycmVudGx5IGxvY2tlZCBhbmQgdGh1cyBwcmV2ZW50IHRoaXMgdXBkYXRlYWJsZSBwYWNrYWdlIGZyb20gYmVpbmcgaW5zdGFsbGFibGUvdXBkYXRlYWJsZQogICAgICAgIGlmICgkcHJvcGFnYXRlVXBkYXRlICYmICRyZXF1ZXN0LT5nZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMoKSkgewogICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZS0+Z2V0UmVwbGFjZXMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgJHJlcGxhY2UgPSAkbGluay0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxvYWRlZFBhY2thZ2VzWyRyZXBsYWNlXSwgJHRoaXMtPnNraXBwZWRMb2FkWyRyZXBsYWNlXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHJlcXVlc3QtPmdldFVwZGF0ZUFsbG93VHJhbnNpdGl2ZVJvb3REZXBlbmRlbmNpZXMoKSB8fCAhJHRoaXMtPmlzUm9vdFJlcXVpcmUoJHJlcXVlc3QsICR0aGlzLT5za2lwcGVkTG9hZFskcmVwbGFjZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51bmxvY2tQYWNrYWdlKCRyZXF1ZXN0LCAkcmVwbGFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5tYXJrUGFja2FnZU5hbWVGb3JMb2FkaW5nKCRyZXF1ZXN0LCAkcmVwbGFjZSwgJGxpbmstPmdldENvbnN0cmFpbnQoKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCEkcmVxdWVzdC0+Z2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlUm9vdERlcGVuZGVuY2llcygpICYmICR0aGlzLT5pc1Jvb3RSZXF1aXJlKCRyZXF1ZXN0LCAkcmVwbGFjZSkgJiYgIWlzc2V0KCR0aGlzLT51cGRhdGVBbGxvd1dhcm5lZFskcmVwbGFjZV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cGRhdGVBbGxvd1dhcm5lZFskcmVwbGFjZV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkRlcGVuZGVuY3kgIicuJHJlcGxhY2UuJyIgaXMgYWxzbyBhIHJvb3QgcmVxdWlyZW1lbnQuIFBhY2thZ2UgaGFzIG5vdCBiZWVuIGxpc3RlZCBhcyBhbiB1cGRhdGUgYXJndW1lbnQsIHNvIGtlZXBpbmcgbG9ja2VkIGF0IG9sZCB2ZXJzaW9uLiBVc2UgLS13aXRoLWFsbC1kZXBlbmRlbmNpZXMgKC1XKSB0byBpbmNsdWRlIHJvb3QgZGVwZW5kZW5jaWVzLjwvd2FybmluZz4nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYSBwYXJ0aWN1bGFyIG5hbWUgaXMgcmVxdWlyZWQgZGlyZWN0bHkgaW4gdGhlIHJlcXVlc3QKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1Jvb3RSZXF1aXJlKFJlcXVlc3QgJHJlcXVlc3QsICRuYW1lKQogICAgewogICAgICAgICRyb290UmVxdWlyZXMgPSAkcmVxdWVzdC0+Z2V0UmVxdWlyZXMoKTsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCRyb290UmVxdWlyZXNbJG5hbWVdKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSB1cGRhdGUgYWxsb3cgbGlzdCBhbGxvd3MgdGhpcyBwYWNrYWdlIGluIHRoZSBsb2NrIGZpbGUgdG8gYmUgdXBkYXRlZAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXNVcGRhdGVBbGxvd2VkKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnVwZGF0ZUFsbG93TGlzdCBhcyAkcGF0dGVybiA9PiAkdm9pZCkgewogICAgICAgICAgICAkcGF0dGVyblJlZ2V4cCA9IEJhc2VQYWNrYWdlOjpwYWNrYWdlTmFtZVRvUmVnZXhwKCRwYXR0ZXJuKTsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJHBhdHRlcm5SZWdleHAsICRwYWNrYWdlLT5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gd2FybkFib3V0Tm9uTWF0Y2hpbmdVcGRhdGVBbGxvd0xpc3QoUmVxdWVzdCAkcmVxdWVzdCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dXBkYXRlQWxsb3dMaXN0IGFzICRwYXR0ZXJuID0+ICR2b2lkKSB7CiAgICAgICAgICAgICRwYXR0ZXJuUmVnZXhwID0gQmFzZVBhY2thZ2U6OnBhY2thZ2VOYW1lVG9SZWdleHAoJHBhdHRlcm4pOwogICAgICAgICAgICAvLyB1cGRhdGUgcGF0dGVybiBtYXRjaGVzIGEgbG9ja2VkIHBhY2thZ2U/ID0+IGFsbCBnb29kCiAgICAgICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRMb2NrZWRSZXBvc2l0b3J5KCktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCRwYXR0ZXJuUmVnZXhwLCAkcGFja2FnZS0+Z2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gdXBkYXRlIHBhdHRlcm4gbWF0Y2hlcyBhIHJvb3QgcmVxdWlyZT8gPT4gYWxsIGdvb2QsIHByb2JhYmx5IGEgbmV3IHBhY2thZ2UKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldFJlcXVpcmVzKCkgYXMgJHBhY2thZ2VOYW1lID0+ICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcGF0dGVyblJlZ2V4cCwgJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0cnBvcygkcGF0dGVybiwgJyonKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPHdhcm5pbmc+UGF0dGVybiAiJyAuICRwYXR0ZXJuIC4gJyIgbGlzdGVkIGZvciB1cGRhdGUgZG9lcyBub3QgbWF0Y2ggYW55IGxvY2tlZCBwYWNrYWdlcy48L3dhcm5pbmc+Jyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPlBhY2thZ2UgIicgLiAkcGF0dGVybiAuICciIGxpc3RlZCBmb3IgdXBkYXRlIGlzIG5vdCBsb2NrZWQuPC93YXJuaW5nPicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV2ZXJ0cyB0aGUgZGVjaXNpb24gdG8gdXNlIGEgbG9ja2VkIHBhY2thZ2UgaWYgYSBwYXJ0aWFsIHVwZGF0ZSB3aXRoIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzCiAgICAgKiBmb3VuZCB0aGF0IHRoaXMgcGFja2FnZSBhY3R1YWxseSBuZWVkcyB0byBiZSB1cGRhdGVkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdW5sb2NrUGFja2FnZShSZXF1ZXN0ICRyZXF1ZXN0LCAkbmFtZSkKICAgIHsKCiAgICAgICAgaWYgKAogICAgICAgICAgICAvLyBpZiB3ZSB1bmZpeGVkIGEgcmVwbGFjZWQgcGFja2FnZSBuYW1lLCB3ZSBhbHNvIG5lZWQgdG8gdW5maXggdGhlIHJlcGxhY2VyIGl0c2VsZgogICAgICAgICAgICAkdGhpcy0+c2tpcHBlZExvYWRbJG5hbWVdICE9PSAkbmFtZQogICAgICAgICAgICAvLyBhcyBsb25nIGFzIGl0IHdhcyBub3QgdW5maXhlZCB5ZXQKICAgICAgICAgICAgJiYgaXNzZXQoJHRoaXMtPnNraXBwZWRMb2FkWyR0aGlzLT5za2lwcGVkTG9hZFskbmFtZV1dKQogICAgICAgICkgewogICAgICAgICAgICAkdGhpcy0+dW5sb2NrUGFja2FnZSgkcmVxdWVzdCwgJHRoaXMtPnNraXBwZWRMb2FkWyRuYW1lXSk7CiAgICAgICAgfQoKICAgICAgICB1bnNldCgkdGhpcy0+c2tpcHBlZExvYWRbJG5hbWVdLCAkdGhpcy0+bG9hZGVkUGFja2FnZXNbJG5hbWVdLCAkdGhpcy0+bWF4RXh0ZW5kZWRSZXFzWyRuYW1lXSk7CgogICAgICAgIC8vIHJlbW92ZSBsb2NrZWQgcGFja2FnZSBieSB0aGlzIG5hbWUgd2hpY2ggd2FzIGFscmVhZHkgaW5pdGlhbGl6ZWQKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUGFja2FnZXMoKSBhcyAkbG9ja2VkUGFja2FnZSkgewogICAgICAgICAgICBpZiAoISgkbG9ja2VkUGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgJiYgJGxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKSA9PT0gJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJGluZGV4ID0gYXJyYXlfc2VhcmNoKCRsb2NrZWRQYWNrYWdlLCAkdGhpcy0+cGFja2FnZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlcXVlc3QtPnVubG9ja1BhY2thZ2UoJGxvY2tlZFBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmVMb2FkZWRQYWNrYWdlKCRyZXF1ZXN0LCAkbG9ja2VkUGFja2FnZSwgJGluZGV4KTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgYW55IHJlcXVpcmVtZW50cyBmb3IgdGhpcyBwYWNrYWdlIGJ5IG90aGVyIGxvY2tlZCBvciBmaXhlZCBwYWNrYWdlcyBhcmUgbm93CiAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBsb2FkZWQsIGFzIHRoZXkgd2VyZSBwcmV2aW91c2x5IGlnbm9yZWQgYmVjYXVzZSB0aGUgbG9ja2VkIChub3cgdW5sb2NrZWQpIHBhY2thZ2UgYWxyZWFkeQogICAgICAgICAgICAgICAgICAgIC8vIHNhdGlzZmllZCB0aGVpciByZXF1aXJlbWVudHMKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0Rml4ZWRPckxvY2tlZFBhY2thZ2VzKCkgYXMgJGZpeGVkT3JMb2NrZWRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZml4ZWRPckxvY2tlZFBhY2thZ2UgIT09ICRsb2NrZWRQYWNrYWdlICYmIGlzc2V0KCR0aGlzLT5za2lwcGVkTG9hZFskZml4ZWRPckxvY2tlZFBhY2thZ2UtPmdldE5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZml4ZWRPckxvY2tlZFBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJHJlcXVpcmVMaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXF1aXJlTGluay0+Z2V0VGFyZ2V0KCkgPT09ICRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1hcmtQYWNrYWdlTmFtZUZvckxvYWRpbmcoJHJlcXVlc3QsICRsb2NrZWRQYWNrYWdlLT5nZXROYW1lKCksICRyZXF1aXJlTGluay0+Z2V0Q29uc3RyYWludCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZW1vdmVMb2FkZWRQYWNrYWdlKFJlcXVlc3QgJHJlcXVlc3QsIFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UsICRpbmRleCkKICAgIHsKICAgICAgICB1bnNldCgkdGhpcy0+cGFja2FnZXNbJGluZGV4XSk7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5hbGlhc01hcFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFsaWFzTWFwW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldIGFzICRhbGlhc0luZGV4ID0+ICRhbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgICRyZXF1ZXN0LT51bmxvY2tQYWNrYWdlKCRhbGlhc1BhY2thZ2UpOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnBhY2thZ2VzWyRhbGlhc0luZGV4XSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zZXQoJHRoaXMtPmFsaWFzTWFwW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcTG9ja0FycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNYXRjaEFsbENvbnN0cmFpbnQ7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJlcXVlc3QKewogICAgLyoqCiAgICAgKiBJZGVudGlmaWVzIGEgcGFydGlhbCB1cGRhdGUgZm9yIGxpc3RlZCBwYWNrYWdlcyBvbmx5LCBhbGwgZGVwZW5kZW5jaWVzIHdpbGwgcmVtYWluIGF0IGxvY2tlZCB2ZXJzaW9ucwogICAgICovCiAgICBjb25zdCBVUERBVEVfT05MWV9MSVNURUQgPSAwOwoKICAgIC8qKgogICAgICogSWRlbnRpZmllcyBhIHBhcnRpYWwgdXBkYXRlIGZvciBsaXN0ZWQgcGFja2FnZXMgYW5kIHJlY3Vyc2l2ZWx5IGFsbCB0aGVpciBkZXBlbmRlbmNpZXMsIGhvd2V2ZXIgZGVwZW5kZW5jaWVzCiAgICAgKiBhbHNvIGRpcmVjdGx5IHJlcXVpcmVkIGJ5IHRoZSByb290IGNvbXBvc2VyLmpzb24gYW5kIHRoZWlyIGRlcGVuZGVuY2llcyB3aWxsIHJlbWFpbiBhdCB0aGUgbG9ja2VkIHZlcnNpb24uCiAgICAgKi8KICAgIGNvbnN0IFVQREFURV9MSVNURURfV0lUSF9UUkFOU0lUSVZFX0RFUFNfTk9fUk9PVF9SRVFVSVJFID0gMTsKCiAgICAvKioKICAgICAqIElkZW50aWZpZXMgYSBwYXJ0aWFsIHVwZGF0ZSBmb3IgbGlzdGVkIHBhY2thZ2VzIGFuZCByZWN1cnNpdmVseSBhbGwgdGhlaXIgZGVwZW5kZW5jaWVzLCBldmVuIGRlcGVuZGVuY2llcwogICAgICogYWxzbyBkaXJlY3RseSByZXF1aXJlZCBieSB0aGUgcm9vdCBjb21wb3Nlci5qc29uIHdpbGwgYmUgdXBkYXRlZC4KICAgICAqLwogICAgY29uc3QgVVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUyA9IDI7CgogICAgcHJvdGVjdGVkICRsb2NrZWRSZXBvc2l0b3J5OwogICAgcHJvdGVjdGVkICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJGZpeGVkUGFja2FnZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRsb2NrZWRQYWNrYWdlcyA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJGZpeGVkTG9ja2VkUGFja2FnZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICR1cGRhdGVBbGxvd0xpc3QgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICR1cGRhdGVBbGxvd1RyYW5zaXRpdmVEZXBlbmRlbmNpZXMgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoTG9ja0FycmF5UmVwb3NpdG9yeSAkbG9ja2VkUmVwb3NpdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2tlZFJlcG9zaXRvcnkgPSAkbG9ja2VkUmVwb3NpdG9yeTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVxdWlyZU5hbWUoJHBhY2thZ2VOYW1lLCBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkcGFja2FnZU5hbWUgPSBzdHJ0b2xvd2VyKCRwYWNrYWdlTmFtZSk7CgogICAgICAgIGlmICgkY29uc3RyYWludCA9PT0gbnVsbCkgewogICAgICAgICAgICAkY29uc3RyYWludCA9IG5ldyBNYXRjaEFsbENvbnN0cmFpbnQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5yZXF1aXJlc1skcGFja2FnZU5hbWVdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdPdmVyd3JpdGluZyByZXF1aXJlcyBzZWVtcyBsaWtlIGEgYnVnICgnLiRwYWNrYWdlTmFtZS4nICcuJHRoaXMtPnJlcXVpcmVzWyRwYWNrYWdlTmFtZV0tPmdldFByZXR0eVN0cmluZygpLicgPT4gJy4kY29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCkuJywgY2hlY2sgd2h5IGl0IGlzIGhhcHBlbmluZywgbWlnaHQgYmUgYSByb290IGFsaWFzJyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5yZXF1aXJlc1skcGFja2FnZU5hbWVdID0gJGNvbnN0cmFpbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYXJrIGEgcGFja2FnZSBhcyBjdXJyZW50bHkgcHJlc2VudCBhbmQgaGF2aW5nIHRvIHJlbWFpbiBpbnN0YWxsZWQKICAgICAqCiAgICAgKiBUaGlzIGlzIHVzZWQgZm9yIHBsYXRmb3JtIHBhY2thZ2VzIHdoaWNoIGNhbm5vdCBiZSBtb2RpZmllZCBieSBDb21wb3Nlci4gQSBydWxlIGVuZm9yY2luZyB0aGVpciBpbnN0YWxsYXRpb24gaXMKICAgICAqIGdlbmVyYXRlZCBmb3IgZGVwZW5kZW5jeSByZXNvbHV0aW9uLiBQYXJ0aWFsIHVwZGF0ZXMgd2l0aCBkZXBlbmRlbmNpZXMgY2Fubm90IGluIGFueSB3YXkgbW9kaWZ5IHRoZXNlIHBhY2thZ2VzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZml4UGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5maXhlZFBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYXJrIGEgcGFja2FnZSBhcyBsb2NrZWQgdG8gYSBzcGVjaWZpYyB2ZXJzaW9uIGJ1dCByZW1vdmFibGUKICAgICAqCiAgICAgKiBUaGlzIGlzIHVzZWQgZm9yIGxvY2sgZmlsZSBwYWNrYWdlcyB3aGljaCBuZWVkIHRvIGJlIHRyZWF0ZWQgc2ltaWxhciB0byBmaXhlZCBwYWNrYWdlcyBieSB0aGUgcG9vbCBidWlsZGVyIGluCiAgICAgKiB0aGF0IGJ5IGRlZmF1bHQgdGhleSBzaG91bGQgcmVhbGx5IG9ubHkgaGF2ZSB0aGUgY3VycmVudGx5IHByZXNlbnQgdmVyc2lvbiBsb2FkZWQgYW5kIG5vIHJlbW90ZSBhbHRlcm5hdGl2ZXMuCiAgICAgKgogICAgICogSG93ZXZlciB1bmxpa2UgZml4ZWQgcGFja2FnZXMgdGhlcmUgd2lsbCBub3QgYmUgYSBzcGVjaWFsIHJ1bGUgZW5mb3JjaW5nIHRoZWlyIGluc3RhbGxhdGlvbiBmb3IgdGhlIHNvbHZlciwgc28KICAgICAqIGlmIG5vdGhpbmcgcmVxdWlyZXMgdGhlc2UgcGFja2FnZXMgdGhleSB3aWxsIGJlIHJlbW92ZWQuIEFkZGl0aW9uYWxseSBpbiBhIHBhcnRpYWwgdXBkYXRlIHRoZXNlIHBhY2thZ2VzIGNhbiBiZQogICAgICogdW5sb2NrZWQsIG1lYW5pbmcgb3RoZXIgdmVyc2lvbnMgY2FuIGJlIGluc3RhbGxlZCBpZiBleHBsaWNpdGx5IHJlcXVlc3RlZCBhcyBwYXJ0IG9mIHRoZSB1cGRhdGUuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2NrUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlKQogICAgewogICAgICAgICR0aGlzLT5sb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgfQoKICAgIC8qKgogICAgICogTWFya3MgYSBsb2NrZWQgcGFja2FnZSBmaXhlZC4gU28gaXQncyB0cmVhdGVkIGlycmVtb3ZhYmxlIGxpa2UgYSBwbGF0Zm9ybSBwYWNrYWdlLgogICAgICoKICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciB0aGUgY29tcG9zZXIgaW5zdGFsbCBzdGVwIHdoaWNoIHZlcmlmaWVzIHRoZSBsb2NrIGZpbGUgaW50ZWdyaXR5IGFuZCBzaG91bGQgbm90IGFsbG93CiAgICAgKiByZW1vdmFsIG9mIGFueSBwYWNrYWdlcy4gQXQgdGhlIHNhbWUgdGltZSBsb2NrIHBhY2thZ2VzIHRoZXJlIGNhbm5vdCBzaW1wbHkgYmUgbWFya2VkIGZpeGVkLCBhcyBlcnJvciByZXBvcnRpbmcKICAgICAqIHdvdWxkIHRoZW4gcmVwb3J0IHRoZW0gYXMgcGxhdGZvcm0gcGFja2FnZXMsIHNvIHRoaXMgc3RpbGwgbWFya3MgdGhlbSBhcyBsb2NrZWQgcGFja2FnZXMgYXQgdGhlIHNhbWUgdGltZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpeExvY2tlZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+Zml4ZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgICR0aGlzLT5maXhlZExvY2tlZFBhY2thZ2VzW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHVubG9ja1BhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICB1bnNldCgkdGhpcy0+bG9ja2VkUGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcGRhdGVBbGxvd0xpc3QoJHVwZGF0ZUFsbG93TGlzdCwgJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcykKICAgIHsKICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dMaXN0ID0gJHVwZGF0ZUFsbG93TGlzdDsKICAgICAgICAkdGhpcy0+dXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzID0gJHVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBkYXRlQWxsb3dMaXN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVwZGF0ZUFsbG93TGlzdDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBkYXRlQWxsb3dUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyAhPT0gc2VsZjo6VVBEQVRFX09OTFlfTElTVEVEOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcGRhdGVBbGxvd1RyYW5zaXRpdmVSb290RGVwZW5kZW5jaWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnVwZGF0ZUFsbG93VHJhbnNpdGl2ZURlcGVuZGVuY2llcyA9PT0gc2VsZjo6VVBEQVRFX0xJU1RFRF9XSVRIX1RSQU5TSVRJVkVfREVQUzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVxdWlyZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVxdWlyZXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpeGVkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zml4ZWRQYWNrYWdlczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNGaXhlZFBhY2thZ2UoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpeGVkUGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NrZWRQYWNrYWdlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NrZWRQYWNrYWdlczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNMb2NrZWRQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5sb2NrZWRQYWNrYWdlc1tzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSkgfHwgaXNzZXQoJHRoaXMtPmZpeGVkTG9ja2VkUGFja2FnZXNbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaXhlZE9yTG9ja2VkUGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9tZXJnZSgkdGhpcy0+Zml4ZWRQYWNrYWdlcywgJHRoaXMtPmxvY2tlZFBhY2thZ2VzKTsKICAgIH0KCiAgICAvLyBUT0RPIGxvb2sgaW50byByZW1vdmluZyB0aGUgcGFja2FnZUlkcyBvcHRpb24sIHRoZSBvbmx5IHBsYWNlIHRydWUgaXMgdXNlZCBpcyBmb3IgdGhlIGluc3RhbGxlZCBtYXAgaW4gdGhlIHNvbHZlciBwcm9ibGVtcwogICAgLy8gc29tZSBsb2NrZWQgcGFja2FnZXMgbWF5IG5vdCBiZSBpbiB0aGUgcG9vbCBzbyB0aGV5IGhhdmUgYSBwYWNrYWdlLT5pZCBvZiAtMQogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXNlbnRNYXAoJHBhY2thZ2VJZHMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcHJlc2VudE1hcCA9IGFycmF5KCk7CgogICAgICAgIGlmICgkdGhpcy0+bG9ja2VkUmVwb3NpdG9yeSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+bG9ja2VkUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAgICAgJHByZXNlbnRNYXBbJHBhY2thZ2VJZHMgPyAkcGFja2FnZS0+aWQgOiBzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Zml4ZWRQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkcHJlc2VudE1hcFskcGFja2FnZUlkcyA/ICRwYWNrYWdlLT5pZCA6IHNwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldID0gJHBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByZXNlbnRNYXA7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpeGVkUGFja2FnZXNNYXAoKQogICAgewogICAgICAgICRmaXhlZFBhY2thZ2VzTWFwID0gYXJyYXkoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpeGVkUGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGZpeGVkUGFja2FnZXNNYXBbJHBhY2thZ2UtPmlkXSA9ICRwYWNrYWdlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaXhlZFBhY2thZ2VzTWFwOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NrZWRSZXBvc2l0b3J5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxvY2tlZFJlcG9zaXRvcnk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KaW50ZXJmYWNlIFBvbGljeUludGVyZmFjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gdmVyc2lvbkNvbXBhcmUoUGFja2FnZUludGVyZmFjZSAkYSwgUGFja2FnZUludGVyZmFjZSAkYiwgJG9wZXJhdG9yKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VsZWN0UHJlZmVycmVkUGFja2FnZXMoUG9vbCAkcG9vbCwgYXJyYXkgJGxpdGVyYWxzLCAkcmVxdWlyZWRQYWNrYWdlID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFNvbHZlcgp7CiAgICBjb25zdCBCUkFOQ0hfTElURVJBTFMgPSAwOwogICAgY29uc3QgQlJBTkNIX0xFVkVMID0gMTsKCiAgICAvKiogQHZhciBQb2xpY3lJbnRlcmZhY2UgKi8KICAgIHByb3RlY3RlZCAkcG9saWN5OwogICAgLyoqIEB2YXIgUG9vbCAqLwogICAgcHJvdGVjdGVkICRwb29sOwoKICAgIC8qKiBAdmFyIFJ1bGVTZXQgKi8KICAgIHByb3RlY3RlZCAkcnVsZXM7CgogICAgLyoqIEB2YXIgUnVsZVdhdGNoR3JhcGggKi8KICAgIHByb3RlY3RlZCAkd2F0Y2hHcmFwaDsKICAgIC8qKiBAdmFyIERlY2lzaW9ucyAqLwogICAgcHJvdGVjdGVkICRkZWNpc2lvbnM7CiAgICAvKiogQHZhciBQYWNrYWdlSW50ZXJmYWNlW10gKi8KICAgIHByb3RlY3RlZCAkZml4ZWRNYXA7CgogICAgLyoqIEB2YXIgaW50ICovCiAgICBwcm90ZWN0ZWQgJHByb3BhZ2F0ZUluZGV4OwogICAgLyoqIEB2YXIgYXJyYXlbXSAqLwogICAgcHJvdGVjdGVkICRicmFuY2hlcyA9IGFycmF5KCk7CiAgICAvKiogQHZhciBQcm9ibGVtW10gKi8KICAgIHByb3RlY3RlZCAkcHJvYmxlbXMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXkgKi8KICAgIHByb3RlY3RlZCAkbGVhcm5lZFBvb2wgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYXJyYXkgKi8KICAgIHByb3RlY3RlZCAkbGVhcm5lZFdoeSA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHVibGljICR0ZXN0RmxhZ0xlYXJuZWRQb3NpdGl2ZUxpdGVyYWwgPSBmYWxzZTsKCiAgICAvKiogQHZhciBJT0ludGVyZmFjZSAqLwogICAgcHJvdGVjdGVkICRpbzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBQb2xpY3lJbnRlcmZhY2UgJHBvbGljeQogICAgICogQHBhcmFtIFBvb2wgICAgICAgICAgICAkcG9vbAogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICAgICAkaW8KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFBvbGljeUludGVyZmFjZSAkcG9saWN5LCBQb29sICRwb29sLCBJT0ludGVyZmFjZSAkaW8pCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5wb2xpY3kgPSAkcG9saWN5OwogICAgICAgICR0aGlzLT5wb29sID0gJHBvb2w7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UnVsZVNldFNpemUoKQogICAgewogICAgICAgIHJldHVybiBcY291bnQoJHRoaXMtPnJ1bGVzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UG9vbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wb29sOwogICAgfQoKICAgIC8vIGFrYSBzb2x2ZXJfbWFrZXJ1bGVkZWNpc2lvbnMKCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1ha2VBc3NlcnRpb25SdWxlRGVjaXNpb25zKCkKICAgIHsKICAgICAgICAkZGVjaXNpb25TdGFydCA9IFxjb3VudCgkdGhpcy0+ZGVjaXNpb25zKSAtIDE7CgogICAgICAgICRydWxlc0NvdW50ID0gXGNvdW50KCR0aGlzLT5ydWxlcyk7CiAgICAgICAgZm9yICgkcnVsZUluZGV4ID0gMDsgJHJ1bGVJbmRleCA8ICRydWxlc0NvdW50OyAkcnVsZUluZGV4KyspIHsKICAgICAgICAgICAgJHJ1bGUgPSAkdGhpcy0+cnVsZXMtPnJ1bGVCeUlkWyRydWxlSW5kZXhdOwoKICAgICAgICAgICAgaWYgKCEkcnVsZS0+aXNBc3NlcnRpb24oKSB8fCAkcnVsZS0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpdGVyYWxzID0gJHJ1bGUtPmdldExpdGVyYWxzKCk7CiAgICAgICAgICAgICRsaXRlcmFsID0gJGxpdGVyYWxzWzBdOwoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+ZGVjaXNpb25zLT5kZWNpZGVkKCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlKCRsaXRlcmFsLCAxLCAkcnVsZSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWNpc2lvbnMtPnNhdGlzZnkoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZm91bmQgYSBjb25mbGljdAogICAgICAgICAgICBpZiAoUnVsZVNldDo6VFlQRV9MRUFSTkVEID09PSAkcnVsZS0+Z2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAkcnVsZS0+ZGlzYWJsZSgpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb25mbGljdCA9ICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lzaW9uUnVsZSgkbGl0ZXJhbCk7CgogICAgICAgICAgICBpZiAoJGNvbmZsaWN0ICYmIFJ1bGVTZXQ6OlRZUEVfUEFDS0FHRSA9PT0gJGNvbmZsaWN0LT5nZXRUeXBlKCkpIHsKICAgICAgICAgICAgICAgICRwcm9ibGVtID0gbmV3IFByb2JsZW0oKTsKCiAgICAgICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkcnVsZSk7CiAgICAgICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkY29uZmxpY3QpOwogICAgICAgICAgICAgICAgJHJ1bGUtPmRpc2FibGUoKTsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9ibGVtc1tdID0gJHByb2JsZW07CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY29uZmxpY3Qgd2l0aCBhbm90aGVyIHJvb3QgcmVxdWlyZS9maXhlZCBwYWNrYWdlCiAgICAgICAgICAgICRwcm9ibGVtID0gbmV3IFByb2JsZW0oKTsKICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJHJ1bGUpOwogICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkY29uZmxpY3QpOwoKICAgICAgICAgICAgLy8gcHVzaCBhbGwgb2Ygb3VyIHJ1bGVzIChjYW4gb25seSBiZSByb290IHJlcXVpcmUvZml4ZWQgcGFja2FnZSBydWxlcykKICAgICAgICAgICAgLy8gYXNzZXJ0aW5nIHRoaXMgbGl0ZXJhbCBvbiB0aGUgcHJvYmxlbSBzdGFjawogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cnVsZXMtPmdldEl0ZXJhdG9yRm9yKFJ1bGVTZXQ6OlRZUEVfUkVRVUVTVCkgYXMgJGFzc2VydFJ1bGUpIHsKICAgICAgICAgICAgICAgIGlmICgkYXNzZXJ0UnVsZS0+aXNEaXNhYmxlZCgpIHx8ICEkYXNzZXJ0UnVsZS0+aXNBc3NlcnRpb24oKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRhc3NlcnRSdWxlTGl0ZXJhbHMgPSAkYXNzZXJ0UnVsZS0+Z2V0TGl0ZXJhbHMoKTsKICAgICAgICAgICAgICAgICRhc3NlcnRSdWxlTGl0ZXJhbCA9ICRhc3NlcnRSdWxlTGl0ZXJhbHNbMF07CgogICAgICAgICAgICAgICAgaWYgKGFicygkbGl0ZXJhbCkgIT09IGFicygkYXNzZXJ0UnVsZUxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkYXNzZXJ0UnVsZSk7CiAgICAgICAgICAgICAgICAkYXNzZXJ0UnVsZS0+ZGlzYWJsZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5wcm9ibGVtc1tdID0gJHByb2JsZW07CgogICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25zLT5yZXNldFRvT2Zmc2V0KCRkZWNpc2lvblN0YXJ0KTsKICAgICAgICAgICAgJHJ1bGVJbmRleCA9IC0xOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0dXBGaXhlZE1hcChSZXF1ZXN0ICRyZXF1ZXN0KQogICAgewogICAgICAgICR0aGlzLT5maXhlZE1hcCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldEZpeGVkUGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkdGhpcy0+Zml4ZWRNYXBbJHBhY2thZ2UtPmlkXSA9ICRwYWNrYWdlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBSZXF1ZXN0ICAgICRyZXF1ZXN0CiAgICAgKiBAcGFyYW0gYm9vbHxhcnJheSAkaWdub3JlUGxhdGZvcm1SZXFzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0ZvclJvb3RSZXF1aXJlUHJvYmxlbXMoUmVxdWVzdCAkcmVxdWVzdCwgJGlnbm9yZVBsYXRmb3JtUmVxcykKICAgIHsKICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0UmVxdWlyZXMoKSBhcyAkcGFja2FnZU5hbWUgPT4gJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKCh0cnVlID09PSAkaWdub3JlUGxhdGZvcm1SZXFzIHx8IChpc19hcnJheSgkaWdub3JlUGxhdGZvcm1SZXFzKSAmJiBpbl9hcnJheSgkcGFja2FnZU5hbWUsICRpZ25vcmVQbGF0Zm9ybVJlcXMsIHRydWUpKSkgJiYgUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkcGFja2FnZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+cG9vbC0+d2hhdFByb3ZpZGVzKCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAkcHJvYmxlbSA9IG5ldyBQcm9ibGVtKCk7CiAgICAgICAgICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZShuZXcgR2VuZXJpY1J1bGUoYXJyYXkoKSwgUnVsZTo6UlVMRV9ST09UX1JFUVVJUkUsIGFycmF5KCdwYWNrYWdlTmFtZScgPT4gJHBhY2thZ2VOYW1lLCAnY29uc3RyYWludCcgPT4gJGNvbnN0cmFpbnQpKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvYmxlbXNbXSA9ICRwcm9ibGVtOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBSZXF1ZXN0ICAgICAgICAgJHJlcXVlc3QKICAgICAqIEBwYXJhbSAgYm9vbHxhcnJheSAgICAgICRpZ25vcmVQbGF0Zm9ybVJlcXMKICAgICAqIEByZXR1cm4gTG9ja1RyYW5zYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzb2x2ZShSZXF1ZXN0ICRyZXF1ZXN0LCAkaWdub3JlUGxhdGZvcm1SZXFzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldHVwRml4ZWRNYXAoJHJlcXVlc3QpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ0dlbmVyYXRpbmcgcnVsZXMnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICRydWxlU2V0R2VuZXJhdG9yID0gbmV3IFJ1bGVTZXRHZW5lcmF0b3IoJHRoaXMtPnBvbGljeSwgJHRoaXMtPnBvb2wpOwogICAgICAgICR0aGlzLT5ydWxlcyA9ICRydWxlU2V0R2VuZXJhdG9yLT5nZXRSdWxlc0ZvcigkcmVxdWVzdCwgJGlnbm9yZVBsYXRmb3JtUmVxcyk7CiAgICAgICAgdW5zZXQoJHJ1bGVTZXRHZW5lcmF0b3IpOwogICAgICAgICR0aGlzLT5jaGVja0ZvclJvb3RSZXF1aXJlUHJvYmxlbXMoJHJlcXVlc3QsICRpZ25vcmVQbGF0Zm9ybVJlcXMpOwogICAgICAgICR0aGlzLT5kZWNpc2lvbnMgPSBuZXcgRGVjaXNpb25zKCR0aGlzLT5wb29sKTsKICAgICAgICAkdGhpcy0+d2F0Y2hHcmFwaCA9IG5ldyBSdWxlV2F0Y2hHcmFwaDsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJ1bGVzIGFzICRydWxlKSB7CiAgICAgICAgICAgICR0aGlzLT53YXRjaEdyYXBoLT5pbnNlcnQobmV3IFJ1bGVXYXRjaE5vZGUoJHJ1bGUpKTsKICAgICAgICB9CgogICAgICAgIC8qIG1ha2UgZGVjaXNpb25zIGJhc2VkIG9uIHJvb3QgcmVxdWlyZS9maXggYXNzZXJ0aW9ucyAqLwogICAgICAgICR0aGlzLT5tYWtlQXNzZXJ0aW9uUnVsZURlY2lzaW9ucygpOwoKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJ1Jlc29sdmluZyBkZXBlbmRlbmNpZXMgdGhyb3VnaCBTQVQnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICRiZWZvcmUgPSBtaWNyb3RpbWUodHJ1ZSk7CiAgICAgICAgJHRoaXMtPnJ1blNhdCgpOwogICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3Ioc3ByaW50ZignRGVwZW5kZW5jeSByZXNvbHV0aW9uIGNvbXBsZXRlZCBpbiAlLjNmIHNlY29uZHMnLCBtaWNyb3RpbWUodHJ1ZSkgLSAkYmVmb3JlKSwgdHJ1ZSwgSU9JbnRlcmZhY2U6OlZFUkJPU0UpOwoKICAgICAgICBpZiAoJHRoaXMtPnByb2JsZW1zKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTb2x2ZXJQcm9ibGVtc0V4Y2VwdGlvbigkdGhpcy0+cHJvYmxlbXMsICR0aGlzLT5sZWFybmVkUG9vbCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IExvY2tUcmFuc2FjdGlvbigkdGhpcy0+cG9vbCwgJHJlcXVlc3QtPmdldFByZXNlbnRNYXAoKSwgJHJlcXVlc3QtPmdldEZpeGVkUGFja2FnZXNNYXAoKSwgJHRoaXMtPmRlY2lzaW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIGRlY2lzaW9uIGFuZCBwcm9wYWdhdGVzIGl0IHRvIGFsbCBydWxlcy4KICAgICAqCiAgICAgKiBFdmFsdWF0ZXMgZWFjaCB0ZXJtIGFmZmVjdGVkIGJ5IHRoZSBkZWNpc2lvbiAobGlua2VkIHRocm91Z2ggd2F0Y2hlcykKICAgICAqIElmIHdlIGZpbmQgdW5pdCBydWxlcyB3ZSBtYWtlIG5ldyBkZWNpc2lvbnMgYmFzZWQgb24gdGhlbQogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICRsZXZlbAogICAgICogQHJldHVybiBSdWxlfG51bGwgQSBydWxlIG9uIGNvbmZsaWN0LCBvdGhlcndpc2UgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHByb3BhZ2F0ZSgkbGV2ZWwpCiAgICB7CiAgICAgICAgd2hpbGUgKCR0aGlzLT5kZWNpc2lvbnMtPnZhbGlkT2Zmc2V0KCR0aGlzLT5wcm9wYWdhdGVJbmRleCkpIHsKICAgICAgICAgICAgJGRlY2lzaW9uID0gJHRoaXMtPmRlY2lzaW9ucy0+YXRPZmZzZXQoJHRoaXMtPnByb3BhZ2F0ZUluZGV4KTsKCiAgICAgICAgICAgICRjb25mbGljdCA9ICR0aGlzLT53YXRjaEdyYXBoLT5wcm9wYWdhdGVMaXRlcmFsKAogICAgICAgICAgICAgICAgJGRlY2lzaW9uW0RlY2lzaW9uczo6REVDSVNJT05fTElURVJBTF0sCiAgICAgICAgICAgICAgICAkbGV2ZWwsCiAgICAgICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25zCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAkdGhpcy0+cHJvcGFnYXRlSW5kZXgrKzsKCiAgICAgICAgICAgIGlmICgkY29uZmxpY3QpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29uZmxpY3Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV2ZXJ0cyBhIGRlY2lzaW9uIGF0IHRoZSBnaXZlbiBsZXZlbC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJldmVydCgkbGV2ZWwpCiAgICB7CiAgICAgICAgd2hpbGUgKCEkdGhpcy0+ZGVjaXNpb25zLT5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgJGxpdGVyYWwgPSAkdGhpcy0+ZGVjaXNpb25zLT5sYXN0TGl0ZXJhbCgpOwoKICAgICAgICAgICAgaWYgKCR0aGlzLT5kZWNpc2lvbnMtPnVuZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGVjaXNpb25MZXZlbCA9ICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lzaW9uTGV2ZWwoJGxpdGVyYWwpOwoKICAgICAgICAgICAgaWYgKCRkZWNpc2lvbkxldmVsIDw9ICRsZXZlbCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbnMtPnJldmVydExhc3QoKTsKICAgICAgICAgICAgJHRoaXMtPnByb3BhZ2F0ZUluZGV4ID0gXGNvdW50KCR0aGlzLT5kZWNpc2lvbnMpOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKCFlbXB0eSgkdGhpcy0+YnJhbmNoZXMpICYmICR0aGlzLT5icmFuY2hlc1tcY291bnQoJHRoaXMtPmJyYW5jaGVzKSAtIDFdW3NlbGY6OkJSQU5DSF9MRVZFTF0gPj0gJGxldmVsKSB7CiAgICAgICAgICAgIGFycmF5X3BvcCgkdGhpcy0+YnJhbmNoZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHNldHByb3BhZ2F0ZWxlYXJuCiAgICAgKgogICAgICogYWRkIGZyZWUgZGVjaXNpb24gKGEgcG9zaXRpdmUgbGl0ZXJhbCkgdG8gZGVjaXNpb24gcXVldWUKICAgICAqIGluY3JlYXNlIGxldmVsIGFuZCBwcm9wYWdhdGUgZGVjaXNpb24KICAgICAqIHJldHVybiBpZiBubyBjb25mbGljdC4KICAgICAqCiAgICAgKiBpbiBjb25mbGljdCBjYXNlLCBhbmFseXplIGNvbmZsaWN0IHJ1bGUsIGFkZCByZXN1bHRpbmcKICAgICAqIHJ1bGUgdG8gbGVhcm50IHJ1bGUgc2V0LCBtYWtlIGRlY2lzaW9uIGZyb20gbGVhcm50CiAgICAgKiBydWxlIChhbHdheXMgdW5pdCkgYW5kIHJlLXByb3BhZ2F0ZS4KICAgICAqCiAgICAgKiByZXR1cm5zIHRoZSBuZXcgc29sdmVyIGxldmVsIG9yIDAgaWYgdW5zb2x2YWJsZQogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICAgICAgICAkbGV2ZWwKICAgICAqIEBwYXJhbSAgc3RyaW5nfGludCAkbGl0ZXJhbAogICAgICogQHBhcmFtICBSdWxlICAgICAgICRydWxlCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldFByb3BhZ2F0ZUxlYXJuKCRsZXZlbCwgJGxpdGVyYWwsIFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgJGxldmVsKys7CgogICAgICAgICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lkZSgkbGl0ZXJhbCwgJGxldmVsLCAkcnVsZSk7CgogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICRydWxlID0gJHRoaXMtPnByb3BhZ2F0ZSgkbGV2ZWwpOwoKICAgICAgICAgICAgaWYgKCEkcnVsZSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbGV2ZWwgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5hbmFseXplVW5zb2x2YWJsZSgkcnVsZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNvbmZsaWN0CiAgICAgICAgICAgIGxpc3QoJGxlYXJuTGl0ZXJhbCwgJG5ld0xldmVsLCAkbmV3UnVsZSwgJHdoeSkgPSAkdGhpcy0+YW5hbHl6ZSgkbGV2ZWwsICRydWxlKTsKCiAgICAgICAgICAgIGlmICgkbmV3TGV2ZWwgPD0gMCB8fCAkbmV3TGV2ZWwgPj0gJGxldmVsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29sdmVyQnVnRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICJUcnlpbmcgdG8gcmV2ZXJ0IHRvIGludmFsaWQgbGV2ZWwgIi4oaW50KSAkbmV3TGV2ZWwuIiBmcm9tIGxldmVsICIuKGludCkgJGxldmVsLiIuIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRuZXdSdWxlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29sdmVyQnVnRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICJObyBydWxlIHdhcyBsZWFybmVkIGZyb20gYW5hbHl6aW5nICRydWxlIGF0IGxldmVsICRsZXZlbC4iCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGV2ZWwgPSAkbmV3TGV2ZWw7CgogICAgICAgICAgICAkdGhpcy0+cmV2ZXJ0KCRsZXZlbCk7CgogICAgICAgICAgICAkdGhpcy0+cnVsZXMtPmFkZCgkbmV3UnVsZSwgUnVsZVNldDo6VFlQRV9MRUFSTkVEKTsKCiAgICAgICAgICAgICR0aGlzLT5sZWFybmVkV2h5W3NwbF9vYmplY3RfaGFzaCgkbmV3UnVsZSldID0gJHdoeTsKCiAgICAgICAgICAgICRydWxlTm9kZSA9IG5ldyBSdWxlV2F0Y2hOb2RlKCRuZXdSdWxlKTsKICAgICAgICAgICAgJHJ1bGVOb2RlLT53YXRjaDJPbkhpZ2hlc3QoJHRoaXMtPmRlY2lzaW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53YXRjaEdyYXBoLT5pbnNlcnQoJHJ1bGVOb2RlKTsKCiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbnMtPmRlY2lkZSgkbGVhcm5MaXRlcmFsLCAkbGV2ZWwsICRuZXdSdWxlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbGV2ZWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludCAgICRsZXZlbAogICAgICogQHBhcmFtICBhcnJheSAkZGVjaXNpb25RdWV1ZQogICAgICogQHBhcmFtICBSdWxlICAkcnVsZQogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZWxlY3RBbmRJbnN0YWxsKCRsZXZlbCwgYXJyYXkgJGRlY2lzaW9uUXVldWUsIFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgLy8gY2hvb3NlIGJlc3QgcGFja2FnZSB0byBpbnN0YWxsIGZyb20gZGVjaXNpb25RdWV1ZQogICAgICAgICRsaXRlcmFscyA9ICR0aGlzLT5wb2xpY3ktPnNlbGVjdFByZWZlcnJlZFBhY2thZ2VzKCR0aGlzLT5wb29sLCAkZGVjaXNpb25RdWV1ZSwgJHJ1bGUtPmdldFJlcXVpcmVkUGFja2FnZSgpKTsKCiAgICAgICAgJHNlbGVjdGVkTGl0ZXJhbCA9IGFycmF5X3NoaWZ0KCRsaXRlcmFscyk7CgogICAgICAgIC8vIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBjYW5kaWRhdGVzLCB0aGVuIGJyYW5jaAogICAgICAgIGlmIChcY291bnQoJGxpdGVyYWxzKSkgewogICAgICAgICAgICAkdGhpcy0+YnJhbmNoZXNbXSA9IGFycmF5KCRsaXRlcmFscywgJGxldmVsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+c2V0UHJvcGFnYXRlTGVhcm4oJGxldmVsLCAkc2VsZWN0ZWRMaXRlcmFsLCAkcnVsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIGludCAgICRsZXZlbAogICAgICogQHBhcmFtICBSdWxlICAkcnVsZQogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYW5hbHl6ZSgkbGV2ZWwsIFJ1bGUgJHJ1bGUpCiAgICB7CiAgICAgICAgJGFuYWx5emVkUnVsZSA9ICRydWxlOwogICAgICAgICRydWxlTGV2ZWwgPSAxOwogICAgICAgICRudW0gPSAwOwogICAgICAgICRsMW51bSA9IDA7CiAgICAgICAgJHNlZW4gPSBhcnJheSgpOwogICAgICAgICRsZWFybmVkTGl0ZXJhbHMgPSBhcnJheShudWxsKTsKCiAgICAgICAgJGRlY2lzaW9uSWQgPSBcY291bnQoJHRoaXMtPmRlY2lzaW9ucyk7CgogICAgICAgICR0aGlzLT5sZWFybmVkUG9vbFtdID0gYXJyYXkoKTsKCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgJHRoaXMtPmxlYXJuZWRQb29sW1xjb3VudCgkdGhpcy0+bGVhcm5lZFBvb2wpIC0gMV1bXSA9ICRydWxlOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHJ1bGUtPmdldExpdGVyYWxzKCkgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgIC8vIG11bHRpY29uZmxpY3RydWxlIGlzIHJlYWxseSBhIGJ1bmNoIG9mIHJ1bGVzIGluIG9uZSwgc28gc29tZSBtYXkgbm90IGhhdmUgZmluaXNoZWQgcHJvcGFnYXRpbmcgeWV0CiAgICAgICAgICAgICAgICBpZiAoJHJ1bGUgaW5zdGFuY2VvZiBNdWx0aUNvbmZsaWN0UnVsZSAmJiAhJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlZCgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBza2lwIHRoZSBvbmUgdHJ1ZSBsaXRlcmFsCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+c2F0aXNmeSgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNlZW5bYWJzKCRsaXRlcmFsKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkc2VlblthYnMoJGxpdGVyYWwpXSA9IHRydWU7CgogICAgICAgICAgICAgICAgJGwgPSAkdGhpcy0+ZGVjaXNpb25zLT5kZWNpc2lvbkxldmVsKCRsaXRlcmFsKTsKCiAgICAgICAgICAgICAgICBpZiAoMSA9PT0gJGwpIHsKICAgICAgICAgICAgICAgICAgICAkbDFudW0rKzsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbGV2ZWwgPT09ICRsKSB7CiAgICAgICAgICAgICAgICAgICAgJG51bSsrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBub3QgbGV2ZWwxIG9yIGNvbmZsaWN0IGxldmVsLCBhZGQgdG8gbmV3IHJ1bGUKICAgICAgICAgICAgICAgICAgICAkbGVhcm5lZExpdGVyYWxzW10gPSAkbGl0ZXJhbDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRsID4gJHJ1bGVMZXZlbCkgewogICAgICAgICAgICAgICAgICAgICAgICAkcnVsZUxldmVsID0gJGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCRsaXRlcmFsKTsKCiAgICAgICAgICAgICRsMXJldHJ5ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUgKCRsMXJldHJ5KSB7CiAgICAgICAgICAgICAgICAkbDFyZXRyeSA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIGlmICghJG51bSAmJiAhLS0kbDFudW0pIHsKICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbGV2ZWwgMSBsaXRlcmFscyBkb25lCiAgICAgICAgICAgICAgICAgICAgYnJlYWsgMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZGVjaXNpb25JZCA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2x2ZXJCdWdFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVhY2hlZCBpbnZhbGlkIGRlY2lzaW9uIGlkICRkZWNpc2lvbklkIHdoaWxlIGxvb2tpbmcgdGhyb3VnaCAkcnVsZSBmb3IgYSBsaXRlcmFsIHByZXNlbnQgaW4gdGhlIGFuYWx5emVkIHJ1bGUgJGFuYWx5emVkUnVsZS4iCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb25JZC0tOwoKICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb24gPSAkdGhpcy0+ZGVjaXNpb25zLT5hdE9mZnNldCgkZGVjaXNpb25JZCk7CiAgICAgICAgICAgICAgICAgICAgJGxpdGVyYWwgPSAkZGVjaXNpb25bRGVjaXNpb25zOjpERUNJU0lPTl9MSVRFUkFMXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzZWVuW2FicygkbGl0ZXJhbCldKSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdW5zZXQoJHNlZW5bYWJzKCRsaXRlcmFsKV0pOwoKICAgICAgICAgICAgICAgIGlmICgkbnVtICYmIDAgPT09IC0tJG51bSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkbGl0ZXJhbCA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnRlc3RGbGFnTGVhcm5lZFBvc2l0aXZlTGl0ZXJhbCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsZWFybmVkTGl0ZXJhbHNbMF0gPSAtJGxpdGVyYWw7CgogICAgICAgICAgICAgICAgICAgIGlmICghJGwxbnVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGVhcm5lZExpdGVyYWxzIGFzICRpID0+ICRsZWFybmVkTGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGkgIT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRzZWVuW2FicygkbGVhcm5lZExpdGVyYWwpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gb25seSBsZXZlbCAxIG1hcmtzIGxlZnQKICAgICAgICAgICAgICAgICAgICAkbDFudW0rKzsKICAgICAgICAgICAgICAgICAgICAkbDFyZXRyeSA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRkZWNpc2lvbiA9ICR0aGlzLT5kZWNpc2lvbnMtPmF0T2Zmc2V0KCRkZWNpc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICAkcnVsZSA9ICRkZWNpc2lvbltEZWNpc2lvbnM6OkRFQ0lTSU9OX1JFQVNPTl07CgogICAgICAgICAgICAgICAgICAgIGlmICgkcnVsZSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIG9ubHkgZXZlciBleGFjdGx5IG9uZSBwb3NpdGl2ZSBkZWNpc2lvbiBpbiBhIG11bHRpY29uZmxpY3QgcnVsZQogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkcnVsZS0+Z2V0TGl0ZXJhbHMoKSBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkc2VlblthYnMoJGxpdGVyYWwpXSkgJiYgJHRoaXMtPmRlY2lzaW9ucy0+c2F0aXNmeSgtJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmxlYXJuZWRQb29sW1xjb3VudCgkdGhpcy0+bGVhcm5lZFBvb2wpIC0gMV1bXSA9ICRydWxlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsID0gJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaXNpb25MZXZlbCgkbGl0ZXJhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDEgPT09ICRsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsMW51bSsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkbGV2ZWwgPT09ICRsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRudW0rKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgbGV2ZWwxIG9yIGNvbmZsaWN0IGxldmVsLCBhZGQgdG8gbmV3IHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxlYXJuZWRMaXRlcmFsc1tdID0gJGxpdGVyYWw7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGwgPiAkcnVsZUxldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcnVsZUxldmVsID0gJGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNlZW5bYWJzKCRsaXRlcmFsKV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkbDFyZXRyeSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGVjaXNpb24gPSAkdGhpcy0+ZGVjaXNpb25zLT5hdE9mZnNldCgkZGVjaXNpb25JZCk7CiAgICAgICAgICAgICRydWxlID0gJGRlY2lzaW9uW0RlY2lzaW9uczo6REVDSVNJT05fUkVBU09OXTsKICAgICAgICB9CgogICAgICAgICR3aHkgPSBcY291bnQoJHRoaXMtPmxlYXJuZWRQb29sKSAtIDE7CgogICAgICAgIGlmICghJGxlYXJuZWRMaXRlcmFsc1swXSkgewogICAgICAgICAgICB0aHJvdyBuZXcgU29sdmVyQnVnRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkRpZCBub3QgZmluZCBhIGxlYXJuYWJsZSBsaXRlcmFsIGluIGFuYWx5emVkIHJ1bGUgJGFuYWx5emVkUnVsZS4iCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkbmV3UnVsZSA9IG5ldyBHZW5lcmljUnVsZSgkbGVhcm5lZExpdGVyYWxzLCBSdWxlOjpSVUxFX0xFQVJORUQsICR3aHkpOwoKICAgICAgICByZXR1cm4gYXJyYXkoJGxlYXJuZWRMaXRlcmFsc1swXSwgJHJ1bGVMZXZlbCwgJG5ld1J1bGUsICR3aHkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gYW5hbHl6ZVVuc29sdmFibGVSdWxlKFByb2JsZW0gJHByb2JsZW0sIFJ1bGUgJGNvbmZsaWN0UnVsZSwgYXJyYXkgJiRydWxlU2VlbikKICAgIHsKICAgICAgICAkd2h5ID0gc3BsX29iamVjdF9oYXNoKCRjb25mbGljdFJ1bGUpOwogICAgICAgICRydWxlU2Vlblskd2h5XSA9IHRydWU7CgogICAgICAgIGlmICgkY29uZmxpY3RSdWxlLT5nZXRUeXBlKCkgPT0gUnVsZVNldDo6VFlQRV9MRUFSTkVEKSB7CiAgICAgICAgICAgICRsZWFybmVkV2h5ID0gJHRoaXMtPmxlYXJuZWRXaHlbJHdoeV07CiAgICAgICAgICAgICRwcm9ibGVtUnVsZXMgPSAkdGhpcy0+bGVhcm5lZFBvb2xbJGxlYXJuZWRXaHldOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHByb2JsZW1SdWxlcyBhcyAkcHJvYmxlbVJ1bGUpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHJ1bGVTZWVuW3NwbF9vYmplY3RfaGFzaCgkcHJvYmxlbVJ1bGUpXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YW5hbHl6ZVVuc29sdmFibGVSdWxlKCRwcm9ibGVtLCAkcHJvYmxlbVJ1bGUsICRydWxlU2Vlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgkY29uZmxpY3RSdWxlLT5nZXRUeXBlKCkgPT0gUnVsZVNldDo6VFlQRV9QQUNLQUdFKSB7CiAgICAgICAgICAgIC8vIHBhY2thZ2UgcnVsZXMgY2Fubm90IGJlIHBhcnQgb2YgYSBwcm9ibGVtCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRwcm9ibGVtLT5uZXh0U2VjdGlvbigpOwogICAgICAgICRwcm9ibGVtLT5hZGRSdWxlKCRjb25mbGljdFJ1bGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBSdWxlICRjb25mbGljdFJ1bGUKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYW5hbHl6ZVVuc29sdmFibGUoUnVsZSAkY29uZmxpY3RSdWxlKQogICAgewogICAgICAgICRwcm9ibGVtID0gbmV3IFByb2JsZW0oKTsKICAgICAgICAkcHJvYmxlbS0+YWRkUnVsZSgkY29uZmxpY3RSdWxlKTsKCiAgICAgICAgJHJ1bGVTZWVuID0gYXJyYXkoKTsKCiAgICAgICAgJHRoaXMtPmFuYWx5emVVbnNvbHZhYmxlUnVsZSgkcHJvYmxlbSwgJGNvbmZsaWN0UnVsZSwgJHJ1bGVTZWVuKTsKCiAgICAgICAgJHRoaXMtPnByb2JsZW1zW10gPSAkcHJvYmxlbTsKCiAgICAgICAgJHNlZW4gPSBhcnJheSgpOwogICAgICAgICRsaXRlcmFscyA9ICRjb25mbGljdFJ1bGUtPmdldExpdGVyYWxzKCk7CgogICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAvLyBza2lwIHRoZSBvbmUgdHJ1ZSBsaXRlcmFsCiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVjaXNpb25zLT5zYXRpc2Z5KCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNlZW5bYWJzKCRsaXRlcmFsKV0gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmRlY2lzaW9ucyBhcyAkZGVjaXNpb24pIHsKICAgICAgICAgICAgJGxpdGVyYWwgPSAkZGVjaXNpb25bRGVjaXNpb25zOjpERUNJU0lPTl9MSVRFUkFMXTsKCiAgICAgICAgICAgIC8vIHNraXAgbGl0ZXJhbHMgdGhhdCBhcmUgbm90IGluIHRoaXMgcnVsZQogICAgICAgICAgICBpZiAoIWlzc2V0KCRzZWVuW2FicygkbGl0ZXJhbCldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR3aHkgPSAkZGVjaXNpb25bRGVjaXNpb25zOjpERUNJU0lPTl9SRUFTT05dOwoKICAgICAgICAgICAgJHByb2JsZW0tPmFkZFJ1bGUoJHdoeSk7CiAgICAgICAgICAgICR0aGlzLT5hbmFseXplVW5zb2x2YWJsZVJ1bGUoJHByb2JsZW0sICR3aHksICRydWxlU2Vlbik7CgogICAgICAgICAgICAkbGl0ZXJhbHMgPSAkd2h5LT5nZXRMaXRlcmFscygpOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAvLyBza2lwIHRoZSBvbmUgdHJ1ZSBsaXRlcmFsCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+c2F0aXNmeSgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRzZWVuW2FicygkbGl0ZXJhbCldID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBlbmFibGUvZGlzYWJsZSBsZWFybnQgcnVsZXMKICAgICAqCiAgICAgKiB3ZSBoYXZlIGVuYWJsZWQgb3IgZGlzYWJsZWQgc29tZSBvZiBvdXIgcnVsZXMuIFdlIG5vdyByZS1lbmFibGUgYWxsCiAgICAgKiBvZiBvdXIgbGVhcm50IHJ1bGVzIGV4Y2VwdCB0aGUgb25lcyB0aGF0IHdlcmUgbGVhcm50IGZyb20gcnVsZXMgdGhhdAogICAgICogYXJlIG5vdyBkaXNhYmxlZC4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbmFibGVEaXNhYmxlTGVhcm5lZFJ1bGVzKCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cnVsZXMtPmdldEl0ZXJhdG9yRm9yKFJ1bGVTZXQ6OlRZUEVfTEVBUk5FRCkgYXMgJHJ1bGUpIHsKICAgICAgICAgICAgJHdoeSA9ICR0aGlzLT5sZWFybmVkV2h5W3NwbF9vYmplY3RfaGFzaCgkcnVsZSldOwogICAgICAgICAgICAkcHJvYmxlbVJ1bGVzID0gJHRoaXMtPmxlYXJuZWRQb29sWyR3aHldOwoKICAgICAgICAgICAgJGZvdW5kRGlzYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHByb2JsZW1SdWxlcyBhcyAkcHJvYmxlbVJ1bGUpIHsKICAgICAgICAgICAgICAgIGlmICgkcHJvYmxlbVJ1bGUtPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgICRmb3VuZERpc2FibGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRmb3VuZERpc2FibGVkICYmICRydWxlLT5pc0VuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgJHJ1bGUtPmRpc2FibGUoKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCEkZm91bmREaXNhYmxlZCAmJiAkcnVsZS0+aXNEaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAkcnVsZS0+ZW5hYmxlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBydW5TYXQoKQogICAgewogICAgICAgICR0aGlzLT5wcm9wYWdhdGVJbmRleCA9IDA7CgogICAgICAgIC8qCiAgICAgICAgICogaGVyZSdzIHRoZSBtYWluIGxvb3A6CiAgICAgICAgICogMSkgcHJvcGFnYXRlIG5ldyBkZWNpc2lvbnMgKG9ubHkgbmVlZGVkIG9uY2UpCiAgICAgICAgICogMikgZnVsZmlsbCByb290IHJlcXVpcmVzL2ZpeGVkIHBhY2thZ2VzCiAgICAgICAgICogMykgZnVsZmlsbCBhbGwgdW5yZXNvbHZlZCBydWxlcwogICAgICAgICAqIDQpIG1pbmltYWxpemUgc29sdXRpb24gaWYgd2UgaGFkIGNob2ljZXMKICAgICAgICAgKiBpZiB3ZSBlbmNvdW50ZXIgYSBwcm9ibGVtLCB3ZSByZXdpbmQgdG8gYSBzYWZlIGxldmVsIGFuZCByZXN0YXJ0CiAgICAgICAgICogd2l0aCBzdGVwIDEKICAgICAgICAgKi8KCiAgICAgICAgJGxldmVsID0gMTsKICAgICAgICAkc3lzdGVtTGV2ZWwgPSAkbGV2ZWwgKyAxOwoKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAoMSA9PT0gJGxldmVsKSB7CiAgICAgICAgICAgICAgICAkY29uZmxpY3RSdWxlID0gJHRoaXMtPnByb3BhZ2F0ZSgkbGV2ZWwpOwogICAgICAgICAgICAgICAgaWYgKG51bGwgIT09ICRjb25mbGljdFJ1bGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmFuYWx5emVVbnNvbHZhYmxlKCRjb25mbGljdFJ1bGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgcm9vdCByZXF1aXJlL2ZpeGVkIHBhY2thZ2UgcnVsZXMKICAgICAgICAgICAgaWYgKCRsZXZlbCA8ICRzeXN0ZW1MZXZlbCkgewogICAgICAgICAgICAgICAgJGl0ZXJhdG9yID0gJHRoaXMtPnJ1bGVzLT5nZXRJdGVyYXRvckZvcihSdWxlU2V0OjpUWVBFX1JFUVVFU1QpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGl0ZXJhdG9yIGFzICRydWxlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRydWxlLT5pc0VuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZGVjaXNpb25RdWV1ZSA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub25lU2F0aXNmaWVkID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRydWxlLT5nZXRMaXRlcmFscygpIGFzICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+c2F0aXNmeSgkbGl0ZXJhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9uZVNhdGlzZmllZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaXRlcmFsID4gMCAmJiAkdGhpcy0+ZGVjaXNpb25zLT51bmRlY2lkZWQoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9uUXVldWVbXSA9ICRsaXRlcmFsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5vbmVTYXRpc2ZpZWQgJiYgXGNvdW50KCRkZWNpc2lvblF1ZXVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYW55IG9mIHRoZSBvcHRpb25zIGluIHRoZSBkZWNpc2lvbiBxdWV1ZSBhcmUgZml4ZWQsIG9ubHkgdXNlIHRob3NlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJ1bmVkUXVldWUgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRlY2lzaW9uUXVldWUgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmZpeGVkTWFwW2FicygkbGl0ZXJhbCldKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJ1bmVkUXVldWVbXSA9ICRsaXRlcmFsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJHBydW5lZFF1ZXVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWNpc2lvblF1ZXVlID0gJHBydW5lZFF1ZXVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5vbmVTYXRpc2ZpZWQgJiYgXGNvdW50KCRkZWNpc2lvblF1ZXVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG9MZXZlbCA9ICRsZXZlbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZXZlbCA9ICR0aGlzLT5zZWxlY3RBbmRJbnN0YWxsKCRsZXZlbCwgJGRlY2lzaW9uUXVldWUsICRydWxlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJGxldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsZXZlbCA8PSAkb0xldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHN5c3RlbUxldmVsID0gJGxldmVsICsgMTsKCiAgICAgICAgICAgICAgICAvLyByb290IHJlcXVpcmVzL2ZpeGVkIHBhY2thZ2VzIGxlZnQKICAgICAgICAgICAgICAgICRpdGVyYXRvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKCRpdGVyYXRvci0+dmFsaWQoKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGxldmVsIDwgJHN5c3RlbUxldmVsKSB7CiAgICAgICAgICAgICAgICAkc3lzdGVtTGV2ZWwgPSAkbGV2ZWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRydWxlc0NvdW50ID0gXGNvdW50KCR0aGlzLT5ydWxlcyk7CiAgICAgICAgICAgICRwYXNzID0gMTsKCiAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignTG9va2luZyBhdCBhbGwgcnVsZXMuJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgZm9yICgkaSA9IDAsICRuID0gMDsgJG4gPCAkcnVsZXNDb3VudDsgJGkrKywgJG4rKykgewogICAgICAgICAgICAgICAgaWYgKCRpID09ICRydWxlc0NvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKDEgPT09ICRwYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcigiU29tZXRoaW5nJ3MgY2hhbmdlZCwgbG9va2luZyBhdCBhbGwgcnVsZXMgYWdhaW4gKHBhc3MgIyRwYXNzKSIsIGZhbHNlLCBJT0ludGVyZmFjZTo6REVCVUcpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pby0+b3ZlcndyaXRlRXJyb3IoIlNvbWV0aGluZydzIGNoYW5nZWQsIGxvb2tpbmcgYXQgYWxsIHJ1bGVzIGFnYWluIChwYXNzICMkcGFzcykiLCBmYWxzZSwgbnVsbCwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRpID0gMDsKICAgICAgICAgICAgICAgICAgICAkcGFzcysrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRydWxlID0gJHRoaXMtPnJ1bGVzLT5ydWxlQnlJZFskaV07CiAgICAgICAgICAgICAgICAkbGl0ZXJhbHMgPSAkcnVsZS0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgICAgICAgICBpZiAoJHJ1bGUtPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRkZWNpc2lvblF1ZXVlID0gYXJyYXkoKTsKCiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdAogICAgICAgICAgICAgICAgLy8gKiBhbGwgbmVnYXRpdmUgbGl0ZXJhbHMgYXJlIGluc3RhbGxlZAogICAgICAgICAgICAgICAgLy8gKiBubyBwb3NpdGl2ZSBsaXRlcmFsIGlzIGluc3RhbGxlZAogICAgICAgICAgICAgICAgLy8gaS5lLiB0aGUgcnVsZSBpcyBub3QgZnVsZmlsbGVkIGFuZCB3ZQogICAgICAgICAgICAgICAgLy8ganVzdCBuZWVkIHRvIGRlY2lkZSBvbiB0aGUgcG9zaXRpdmUgbGl0ZXJhbHMKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGxpdGVyYWwgPD0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5kZWNpc2lvbnMtPmRlY2lkZWRJbnN0YWxsKCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsgLy8gbmV4dCBydWxlCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaWRlZEluc3RhbGwoJGxpdGVyYWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOyAvLyBuZXh0IHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmRlY2lzaW9ucy0+dW5kZWNpZGVkKCRsaXRlcmFsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY2lzaW9uUXVldWVbXSA9ICRsaXRlcmFsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gaGF2ZSBhdCBsZWFzdCAyIGl0ZW0gdG8gcGljayBmcm9tCiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRkZWNpc2lvblF1ZXVlKSA8IDIpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbGV2ZWwgPSAkdGhpcy0+c2VsZWN0QW5kSW5zdGFsbCgkbGV2ZWwsICRkZWNpc2lvblF1ZXVlLCAkcnVsZSk7CgogICAgICAgICAgICAgICAgaWYgKDAgPT09ICRsZXZlbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBzb21ldGhpbmcgY2hhbmdlZCwgc28gbG9vayBhdCBhbGwgcnVsZXMgYWdhaW4KICAgICAgICAgICAgICAgICRydWxlc0NvdW50ID0gXGNvdW50KCR0aGlzLT5ydWxlcyk7CiAgICAgICAgICAgICAgICAkbiA9IC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGxldmVsIDwgJHN5c3RlbUxldmVsKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gbWluaW1pemF0aW9uIHN0ZXAKICAgICAgICAgICAgaWYgKFxjb3VudCgkdGhpcy0+YnJhbmNoZXMpKSB7CiAgICAgICAgICAgICAgICAkbGFzdExpdGVyYWwgPSBudWxsOwogICAgICAgICAgICAgICAgJGxhc3RMZXZlbCA9IG51bGw7CiAgICAgICAgICAgICAgICAkbGFzdEJyYW5jaEluZGV4ID0gMDsKICAgICAgICAgICAgICAgICRsYXN0QnJhbmNoT2Zmc2V0ID0gMDsKCiAgICAgICAgICAgICAgICBmb3IgKCRpID0gXGNvdW50KCR0aGlzLT5icmFuY2hlcykgLSAxOyAkaSA+PSAwOyAkaS0tKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkbGl0ZXJhbHMsICRsKSA9ICR0aGlzLT5icmFuY2hlc1skaV07CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkb2Zmc2V0ID0+ICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGl0ZXJhbCAmJiAkbGl0ZXJhbCA+IDAgJiYgJHRoaXMtPmRlY2lzaW9ucy0+ZGVjaXNpb25MZXZlbCgkbGl0ZXJhbCkgPiAkbCArIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsYXN0TGl0ZXJhbCA9ICRsaXRlcmFsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhc3RCcmFuY2hJbmRleCA9ICRpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhc3RCcmFuY2hPZmZzZXQgPSAkb2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxhc3RMZXZlbCA9ICRsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkbGFzdExpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+YnJhbmNoZXNbJGxhc3RCcmFuY2hJbmRleF1bc2VsZjo6QlJBTkNIX0xJVEVSQUxTXVskbGFzdEJyYW5jaE9mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAkbGV2ZWwgPSAkbGFzdExldmVsOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZXZlcnQoJGxldmVsKTsKCiAgICAgICAgICAgICAgICAgICAgJHdoeSA9ICR0aGlzLT5kZWNpc2lvbnMtPmxhc3RSZWFzb24oKTsKCiAgICAgICAgICAgICAgICAgICAgJGxldmVsID0gJHRoaXMtPnNldFByb3BhZ2F0ZUxlYXJuKCRsZXZlbCwgJGxhc3RMaXRlcmFsLCAkd2h5KTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRsZXZlbCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogQGludGVybmFsCiAqLwpjbGFzcyBUcmFuc2FjdGlvbgp7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVyYXRpb25zOwoKICAgIC8qKgogICAgICogUGFja2FnZXMgcHJlc2VudCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0cmFuc2FjdGlvbgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHByZXNlbnRQYWNrYWdlczsKCiAgICAvKioKICAgICAqIFBhY2thZ2Ugc2V0IHJlc3VsdGluZyBmcm9tIHRoaXMgdHJhbnNhY3Rpb24KICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRyZXN1bHRQYWNrYWdlTWFwOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlc3VsdFBhY2thZ2VzQnlOYW1lID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHByZXNlbnRQYWNrYWdlcywgJHJlc3VsdFBhY2thZ2VzKQogICAgewogICAgICAgICR0aGlzLT5wcmVzZW50UGFja2FnZXMgPSAkcHJlc2VudFBhY2thZ2VzOwogICAgICAgICR0aGlzLT5zZXRSZXN1bHRQYWNrYWdlTWFwcygkcmVzdWx0UGFja2FnZXMpOwogICAgICAgICR0aGlzLT5vcGVyYXRpb25zID0gJHRoaXMtPmNhbGN1bGF0ZU9wZXJhdGlvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRpb25zOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0UmVzdWx0UGFja2FnZU1hcHMoJHJlc3VsdFBhY2thZ2VzKQogICAgewogICAgICAgICRwYWNrYWdlU29ydCA9IGZ1bmN0aW9uIChQYWNrYWdlSW50ZXJmYWNlICRhLCBQYWNrYWdlSW50ZXJmYWNlICRiKSB7CiAgICAgICAgICAgIC8vIHNvcnQgYWxpYXMgcGFja2FnZXMgYnkgdGhlIHNhbWUgbmFtZSBiZWhpbmQgdGhlaXIgbm9uIGFsaWFzIHZlcnNpb24KICAgICAgICAgICAgaWYgKCRhLT5nZXROYW1lKCkgPT0gJGItPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgaWYgKCRhIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICE9ICRiIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRhIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlID8gLTEgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gaWYgbmFtZXMgYXJlIHRoZSBzYW1lLCBjb21wYXJlIHZlcnNpb24sIGUuZy4gdG8gc29ydCBhbGlhc2VzIHJlbGlhYmx5LCBhY3R1YWwgb3JkZXIgZG9lcyBub3QgbWF0dGVyCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyY21wKCRiLT5nZXRWZXJzaW9uKCksICRhLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRiLT5nZXROYW1lKCksICRhLT5nZXROYW1lKCkpOwogICAgICAgIH07CgogICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlTWFwID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcmVzdWx0UGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gPSAkcGFja2FnZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlc0J5TmFtZVskbmFtZV1bXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB1YXNvcnQoJHRoaXMtPnJlc3VsdFBhY2thZ2VNYXAsICRwYWNrYWdlU29ydCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlc3VsdFBhY2thZ2VzQnlOYW1lIGFzICRuYW1lID0+ICRwYWNrYWdlcykgewogICAgICAgICAgICB1YXNvcnQoJHRoaXMtPnJlc3VsdFBhY2thZ2VzQnlOYW1lWyRuYW1lXSwgJHBhY2thZ2VTb3J0KTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNhbGN1bGF0ZU9wZXJhdGlvbnMoKQogICAgewogICAgICAgICRvcGVyYXRpb25zID0gYXJyYXkoKTsKCiAgICAgICAgJHByZXNlbnRQYWNrYWdlTWFwID0gYXJyYXkoKTsKICAgICAgICAkcmVtb3ZlTWFwID0gYXJyYXkoKTsKICAgICAgICAkcHJlc2VudEFsaWFzTWFwID0gYXJyYXkoKTsKICAgICAgICAkcmVtb3ZlQWxpYXNNYXAgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcmVzZW50UGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAkcHJlc2VudEFsaWFzTWFwWyRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgJHJlbW92ZUFsaWFzTWFwWyRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpXSA9ICRwYWNrYWdlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHByZXNlbnRQYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICAkcmVtb3ZlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldID0gJHBhY2thZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRzdGFjayA9ICR0aGlzLT5nZXRSb290UGFja2FnZXMoKTsKCiAgICAgICAgJHZpc2l0ZWQgPSBhcnJheSgpOwogICAgICAgICRwcm9jZXNzZWQgPSBhcnJheSgpOwoKICAgICAgICB3aGlsZSAoIWVtcHR5KCRzdGFjaykpIHsKICAgICAgICAgICAgJHBhY2thZ2UgPSBhcnJheV9wb3AoJHN0YWNrKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkcHJvY2Vzc2VkW3NwbF9vYmplY3RfaGFzaCgkcGFja2FnZSldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNzZXQoJHZpc2l0ZWRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pKSB7CiAgICAgICAgICAgICAgICAkdmlzaXRlZFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSA9IHRydWU7CgogICAgICAgICAgICAgICAgJHN0YWNrW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRzdGFja1tdID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBvc3NpYmxlUmVxdWlyZXMgPSAkdGhpcy0+Z2V0UHJvdmlkZXJzSW5SZXN1bHQoJGxpbmspOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBvc3NpYmxlUmVxdWlyZXMgYXMgJHJlcXVpcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdGFja1tdID0gJHJlcXVpcmU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICghaXNzZXQoJHByb2Nlc3NlZFtzcGxfb2JqZWN0X2hhc2goJHBhY2thZ2UpXSkpIHsKICAgICAgICAgICAgICAgICRwcm9jZXNzZWRbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0gPSB0cnVlOwoKICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICRhbGlhc0tleSA9ICRwYWNrYWdlLT5nZXROYW1lKCkuJzo6Jy4kcGFja2FnZS0+Z2V0VmVyc2lvbigpOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkcHJlc2VudEFsaWFzTWFwWyRhbGlhc0tleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZW1vdmVBbGlhc01hcFskYWxpYXNLZXldKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxNYXJrQWxpYXNJbnN0YWxsZWRPcGVyYXRpb24oJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHNvdXJjZSA9ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIHdlIG5lZWQgdG8gdXBkYXRlPwogICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIGRpZmZlcmVudCBmb3IgbG9jaz8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgIT0gJHByZXNlbnRQYWNrYWdlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldLT5nZXRWZXJzaW9uKCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkgIT09ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0RGlzdFJlZmVyZW5jZSgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkgIT09ICRwcmVzZW50UGFja2FnZU1hcFskcGFja2FnZS0+Z2V0TmFtZSgpXS0+Z2V0U291cmNlUmVmZXJlbmNlKCkKICAgICAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxVcGRhdGVPcGVyYXRpb24oJHNvdXJjZSwgJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZW1vdmVNYXBbJHBhY2thZ2UtPmdldE5hbWUoKV0pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvcGVyYXRpb25zW10gPSBuZXcgT3BlcmF0aW9uXEluc3RhbGxPcGVyYXRpb24oJHBhY2thZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkcmVtb3ZlTWFwWyRwYWNrYWdlLT5nZXROYW1lKCldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZW1vdmVNYXAgYXMgJG5hbWUgPT4gJHBhY2thZ2UpIHsKICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkb3BlcmF0aW9ucywgbmV3IE9wZXJhdGlvblxVbmluc3RhbGxPcGVyYXRpb24oJHBhY2thZ2UpKTsKICAgICAgICB9CiAgICAgICAgZm9yZWFjaCAoJHJlbW92ZUFsaWFzTWFwIGFzICRuYW1lVmVyc2lvbiA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAkb3BlcmF0aW9uc1tdID0gbmV3IE9wZXJhdGlvblxNYXJrQWxpYXNVbmluc3RhbGxlZE9wZXJhdGlvbigkcGFja2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkb3BlcmF0aW9ucyA9ICR0aGlzLT5tb3ZlUGx1Z2luc1RvRnJvbnQoJG9wZXJhdGlvbnMpOwogICAgICAgIC8vIFRPRE8gZml4IHRoaXM6CiAgICAgICAgLy8gd2UgaGF2ZSB0byBkbyB0aGlzIGFnYWluIGhlcmUgZXZlbiB0aG91Z2ggdGhlIGFib3ZlIHN0YWNrIGNvZGUgZGlkIGl0IGJlY2F1c2UgbW92aW5nIHBsdWdpbnMgbW92ZXMgdGhlbSBiZWZvcmUgdW5pbnN0YWxscwogICAgICAgICRvcGVyYXRpb25zID0gJHRoaXMtPm1vdmVVbmluc3RhbGxzVG9Gcm9udCgkb3BlcmF0aW9ucyk7CgogICAgICAgIC8vIFRPRE8gc2tpcCB1cGRhdGVzIHdoaWNoIGRvbid0IHVwZGF0ZT8gaXMgdGhpcyBuZWVkZWQ/IHdlIHNob3VsZG4ndCBzY2hlZHVsZSB0aGlzIHVwZGF0ZSBpbiB0aGUgZmlyc3QgcGxhY2U/CiAgICAgICAgLyoKICAgICAgICBpZiAoJ3VwZGF0ZScgPT09ICRvcFR5cGUpIHsKICAgICAgICAgICAgJHRhcmdldFBhY2thZ2UgPSAkb3BlcmF0aW9uLT5nZXRUYXJnZXRQYWNrYWdlKCk7CiAgICAgICAgICAgIGlmICgkdGFyZ2V0UGFja2FnZS0+aXNEZXYoKSkgewogICAgICAgICAgICAgICAgJGluaXRpYWxQYWNrYWdlID0gJG9wZXJhdGlvbi0+Z2V0SW5pdGlhbFBhY2thZ2UoKTsKICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0UGFja2FnZS0+Z2V0VmVyc2lvbigpID09PSAkaW5pdGlhbFBhY2thZ2UtPmdldFZlcnNpb24oKQogICAgICAgICAgICAgICAgICAgICYmICghJHRhcmdldFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpIHx8ICR0YXJnZXRQYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSA9PT0gJGluaXRpYWxQYWNrYWdlLT5nZXRTb3VyY2VSZWZlcmVuY2UoKSkKICAgICAgICAgICAgICAgICAgICAmJiAoISR0YXJnZXRQYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkgfHwgJHRhcmdldFBhY2thZ2UtPmdldERpc3RSZWZlcmVuY2UoKSA9PT0gJGluaXRpYWxQYWNrYWdlLT5nZXREaXN0UmVmZXJlbmNlKCkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJyAgLSBTa2lwcGluZyB1cGRhdGUgb2YgJyAuICR0YXJnZXRQYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCkgLiAnIHRvIHRoZSBzYW1lIHJlZmVyZW5jZS1sb2NrZWQgdmVyc2lvbicsIHRydWUsIElPSW50ZXJmYWNlOjpERUJVRyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCcnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0qLwoKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdGlvbnMgPSAkb3BlcmF0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZSB3aGljaCBwYWNrYWdlcyBpbiB0aGUgcmVzdWx0IGFyZSBub3QgcmVxdWlyZWQgYnkgYW55IG90aGVyIHBhY2thZ2VzIGluIGl0LgogICAgICoKICAgICAqIFRoZXNlIHNlcnZlIGFzIGEgc3RhcnRpbmcgcG9pbnQgdG8gZW51bWVyYXRlIHBhY2thZ2VzIGluIGEgdG9wb2xvZ2ljYWwgb3JkZXIgZGVzcGl0ZSBwb3RlbnRpYWwgY3ljbGVzLgogICAgICogSWYgdGhlcmUgYXJlIHBhY2thZ2VzIHdpdGggYSBjeWNsZSBvbiB0aGUgdG9wIGxldmVsIHRoZSBwYWNrYWdlIHdpdGggdGhlIGxvd2VzdCBuYW1lIGdldHMgcGlja2VkCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Um9vdFBhY2thZ2VzKCkKICAgIHsKICAgICAgICAkcm9vdHMgPSAkdGhpcy0+cmVzdWx0UGFja2FnZU1hcDsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnJlc3VsdFBhY2thZ2VNYXAgYXMgJHBhY2thZ2VIYXNoID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJHJvb3RzWyRwYWNrYWdlSGFzaF0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldFJlcXVpcmVzKCkgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgICRwb3NzaWJsZVJlcXVpcmVzID0gJHRoaXMtPmdldFByb3ZpZGVyc0luUmVzdWx0KCRsaW5rKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9zc2libGVSZXF1aXJlcyBhcyAkcmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcmVxdWlyZSAhPT0gJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJHJvb3RzW3NwbF9vYmplY3RfaGFzaCgkcmVxdWlyZSldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcm9vdHM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFByb3ZpZGVyc0luUmVzdWx0KExpbmsgJGxpbmspCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cmVzdWx0UGFja2FnZXNCeU5hbWVbJGxpbmstPmdldFRhcmdldCgpXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3VsdFBhY2thZ2VzQnlOYW1lWyRsaW5rLT5nZXRUYXJnZXQoKV07CiAgICB9CgogICAgLyoqCiAgICAgKiBXb3JrYXJvdW5kOiBpZiB5b3VyIHBhY2thZ2VzIGRlcGVuZCBvbiBwbHVnaW5zLCB3ZSBtdXN0IGJlIHN1cmUKICAgICAqIHRoYXQgdGhvc2UgYXJlIGluc3RhbGxlZCAvIHVwZGF0ZWQgZmlyc3Q7IGVsc2UgaXQgd291bGQgbGVhZCB0byBwYWNrYWdlcwogICAgICogYmVpbmcgaW5zdGFsbGVkIG11bHRpcGxlIHRpbWVzIGluIGRpZmZlcmVudCBmb2xkZXJzLCB3aGVuIHJ1bm5pbmcgQ29tcG9zZXIKICAgICAqIHR3aWNlLgogICAgICoKICAgICAqIFdoaWxlIHRoaXMgZG9lcyBub3QgZml4IHRoZSByb290LWNhdXNlcyBvZiBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIvY29tcG9zZXIvaXNzdWVzLzExNDcsCiAgICAgKiBpdCBhdCBsZWFzdCBmaXhlcyB0aGUgc3ltcHRvbXMgYW5kIG1ha2VzIHVzYWdlIG9mIGNvbXBvc2VyIHBvc3NpYmxlIChhZ2FpbikKICAgICAqIGluIHN1Y2ggc2NlbmFyaW9zLgogICAgICoKICAgICAqIEBwYXJhbSAgT3BlcmF0aW9uXE9wZXJhdGlvbkludGVyZmFjZVtdICRvcGVyYXRpb25zCiAgICAgKiBAcmV0dXJuIE9wZXJhdGlvblxPcGVyYXRpb25JbnRlcmZhY2VbXSByZW9yZGVyZWQgb3BlcmF0aW9uIGxpc3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtb3ZlUGx1Z2luc1RvRnJvbnQoYXJyYXkgJG9wZXJhdGlvbnMpCiAgICB7CiAgICAgICAgJGRsTW9kaWZ5aW5nUGx1Z2luc05vRGVwcyA9IGFycmF5KCk7CiAgICAgICAgJGRsTW9kaWZ5aW5nUGx1Z2luc1dpdGhEZXBzID0gYXJyYXkoKTsKICAgICAgICAkZGxNb2RpZnlpbmdQbHVnaW5SZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgJHBsdWdpbnNOb0RlcHMgPSBhcnJheSgpOwogICAgICAgICRwbHVnaW5zV2l0aERlcHMgPSBhcnJheSgpOwogICAgICAgICRwbHVnaW5SZXF1aXJlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKGFycmF5X3JldmVyc2UoJG9wZXJhdGlvbnMsIHRydWUpIGFzICRpZHggPT4gJG9wKSB7CiAgICAgICAgICAgIGlmICgkb3AgaW5zdGFuY2VvZiBPcGVyYXRpb25cSW5zdGFsbE9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkb3AtPmdldFBhY2thZ2UoKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRvcCBpbnN0YW5jZW9mIE9wZXJhdGlvblxVcGRhdGVPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJG9wLT5nZXRUYXJnZXRQYWNrYWdlKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGlzRG93bmxvYWRzTW9kaWZ5aW5nUGx1Z2luID0gJHBhY2thZ2UtPmdldFR5cGUoKSA9PT0gJ2NvbXBvc2VyLXBsdWdpbicgJiYgKCRleHRyYSA9ICRwYWNrYWdlLT5nZXRFeHRyYSgpKSAmJiBpc3NldCgkZXh0cmFbJ3BsdWdpbi1tb2RpZmllcy1kb3dubG9hZHMnXSkgJiYgJGV4dHJhWydwbHVnaW4tbW9kaWZpZXMtZG93bmxvYWRzJ10gPT09IHRydWU7CgogICAgICAgICAgICAvLyBpcyB0aGlzIGEgZG93bmxvYWRzIG1vZGlmeWluZyBwbHVnaW4gb3IgYSBkZXBlbmRlbmN5IG9mIG9uZT8KICAgICAgICAgICAgaWYgKCRpc0Rvd25sb2Fkc01vZGlmeWluZ1BsdWdpbiB8fCBjb3VudChhcnJheV9pbnRlcnNlY3QoJHBhY2thZ2UtPmdldE5hbWVzKCksICRkbE1vZGlmeWluZ1BsdWdpblJlcXVpcmVzKSkpIHsKICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgcGFja2FnZSdzIHJlcXVpcmVzLCBidXQgZmlsdGVyIG91dCBhbnkgcGxhdGZvcm0gcmVxdWlyZW1lbnRzCiAgICAgICAgICAgICAgICAkcmVxdWlyZXMgPSBhcnJheV9maWx0ZXIoYXJyYXlfa2V5cygkcGFja2FnZS0+Z2V0UmVxdWlyZXMoKSksIGZ1bmN0aW9uICgkcmVxKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRyZXEpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgLy8gaXMgdGhpcyBhIHBsdWdpbiB3aXRoIG5vIG1lYW5pbmdmdWwgZGVwZW5kZW5jaWVzPwogICAgICAgICAgICAgICAgaWYgKCRpc0Rvd25sb2Fkc01vZGlmeWluZ1BsdWdpbiAmJiAhY291bnQoJHJlcXVpcmVzKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHBsdWdpbnMgd2l0aCBubyBkZXBlbmRlbmNpZXMgZ28gdG8gdGhlIHZlcnkgZnJvbnQKICAgICAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCRkbE1vZGlmeWluZ1BsdWdpbnNOb0RlcHMsICRvcCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGNhcHR1cmUgdGhlIHJlcXVpcmVtZW50cyBmb3IgdGhpcyBwYWNrYWdlIHNvIHRob3NlIHBhY2thZ2VzIHdpbGwgYmUgbW92ZWQgdXAgYXMgd2VsbAogICAgICAgICAgICAgICAgICAgICRkbE1vZGlmeWluZ1BsdWdpblJlcXVpcmVzID0gYXJyYXlfbWVyZ2UoJGRsTW9kaWZ5aW5nUGx1Z2luUmVxdWlyZXMsICRyZXF1aXJlcyk7CiAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSB0aGUgb3BlcmF0aW9uIHRvIHRoZSBmcm9udAogICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGRsTW9kaWZ5aW5nUGx1Z2luc1dpdGhEZXBzLCAkb3ApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHVuc2V0KCRvcGVyYXRpb25zWyRpZHhdKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBpcyB0aGlzIHBhY2thZ2UgYSBwbHVnaW4/CiAgICAgICAgICAgICRpc1BsdWdpbiA9ICRwYWNrYWdlLT5nZXRUeXBlKCkgPT09ICdjb21wb3Nlci1wbHVnaW4nIHx8ICRwYWNrYWdlLT5nZXRUeXBlKCkgPT09ICdjb21wb3Nlci1pbnN0YWxsZXInOwoKICAgICAgICAgICAgLy8gaXMgdGhpcyBhIHBsdWdpbiBvciBhIGRlcGVuZGVuY3kgb2YgYSBwbHVnaW4/CiAgICAgICAgICAgIGlmICgkaXNQbHVnaW4gfHwgY291bnQoYXJyYXlfaW50ZXJzZWN0KCRwYWNrYWdlLT5nZXROYW1lcygpLCAkcGx1Z2luUmVxdWlyZXMpKSkgewogICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwYWNrYWdlJ3MgcmVxdWlyZXMsIGJ1dCBmaWx0ZXIgb3V0IGFueSBwbGF0Zm9ybSByZXF1aXJlbWVudHMKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5X2ZpbHRlcihhcnJheV9rZXlzKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpKSwgZnVuY3Rpb24gKCRyZXEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIVBsYXRmb3JtUmVwb3NpdG9yeTo6aXNQbGF0Zm9ybVBhY2thZ2UoJHJlcSk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvLyBpcyB0aGlzIGEgcGx1Z2luIHdpdGggbm8gbWVhbmluZ2Z1bCBkZXBlbmRlbmNpZXM/CiAgICAgICAgICAgICAgICBpZiAoJGlzUGx1Z2luICYmICFjb3VudCgkcmVxdWlyZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcGx1Z2lucyB3aXRoIG5vIGRlcGVuZGVuY2llcyBnbyB0byB0aGUgdmVyeSBmcm9udAogICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJHBsdWdpbnNOb0RlcHMsICRvcCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGNhcHR1cmUgdGhlIHJlcXVpcmVtZW50cyBmb3IgdGhpcyBwYWNrYWdlIHNvIHRob3NlIHBhY2thZ2VzIHdpbGwgYmUgbW92ZWQgdXAgYXMgd2VsbAogICAgICAgICAgICAgICAgICAgICRwbHVnaW5SZXF1aXJlcyA9IGFycmF5X21lcmdlKCRwbHVnaW5SZXF1aXJlcywgJHJlcXVpcmVzKTsKICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIHRoZSBvcGVyYXRpb24gdG8gdGhlIGZyb250CiAgICAgICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkcGx1Z2luc1dpdGhEZXBzLCAkb3ApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHVuc2V0KCRvcGVyYXRpb25zWyRpZHhdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCRkbE1vZGlmeWluZ1BsdWdpbnNOb0RlcHMsICRkbE1vZGlmeWluZ1BsdWdpbnNXaXRoRGVwcywgJHBsdWdpbnNOb0RlcHMsICRwbHVnaW5zV2l0aERlcHMsICRvcGVyYXRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92YWxzIG9mIHBhY2thZ2VzIHNob3VsZCBiZSBleGVjdXRlZCBiZWZvcmUgaW5zdGFsbGF0aW9ucyBpbgogICAgICogY2FzZSB0d28gcGFja2FnZXMgcmVzb2x2ZSB0byB0aGUgc2FtZSBwYXRoIChkdWUgdG8gY3VzdG9tIGluc3RhbGxlcnMpCiAgICAgKgogICAgICogQHBhcmFtICBPcGVyYXRpb25cT3BlcmF0aW9uSW50ZXJmYWNlW10gJG9wZXJhdGlvbnMKICAgICAqIEByZXR1cm4gT3BlcmF0aW9uXE9wZXJhdGlvbkludGVyZmFjZVtdIHJlb3JkZXJlZCBvcGVyYXRpb24gbGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1vdmVVbmluc3RhbGxzVG9Gcm9udChhcnJheSAkb3BlcmF0aW9ucykKICAgIHsKICAgICAgICAkdW5pbnN0T3BzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkb3BlcmF0aW9ucyBhcyAkaWR4ID0+ICRvcCkgewogICAgICAgICAgICBpZiAoJG9wIGluc3RhbmNlb2YgT3BlcmF0aW9uXFVuaW5zdGFsbE9wZXJhdGlvbiB8fCAkb3AgaW5zdGFuY2VvZiBPcGVyYXRpb25cTWFya0FsaWFzVW5pbnN0YWxsZWRPcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgICR1bmluc3RPcHNbXSA9ICRvcDsKICAgICAgICAgICAgICAgIHVuc2V0KCRvcGVyYXRpb25zWyRpZHhdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCR1bmluc3RPcHMsICRvcGVyYXRpb25zKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29tcGlsaW5nTWF0Y2hlcjsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwoKLyoqCiAqIEEgcGFja2FnZSBwb29sIGNvbnRhaW5zIGFsbCBwYWNrYWdlcyBmb3IgZGVwZW5kZW5jeSByZXNvbHV0aW9uCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICovCmNsYXNzIFBvb2wgaW1wbGVtZW50cyBcQ291bnRhYmxlCnsKICAgIHByb3RlY3RlZCAkcGFja2FnZXMgPSBhcnJheSgpOwogICAgcHJvdGVjdGVkICRwYWNrYWdlQnlOYW1lID0gYXJyYXkoKTsKICAgIHByb3RlY3RlZCAkdmVyc2lvblBhcnNlcjsKICAgIHByb3RlY3RlZCAkcHJvdmlkZXJDYWNoZSA9IGFycmF5KCk7CiAgICBwcm90ZWN0ZWQgJHVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHBhY2thZ2VzID0gYXJyYXkoKSwgYXJyYXkgJHVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPnZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkdGhpcy0+c2V0UGFja2FnZXMoJHBhY2thZ2VzKTsKICAgICAgICAkdGhpcy0+dW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2VzID0gJHVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlczsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldFBhY2thZ2VzKGFycmF5ICRwYWNrYWdlcykKICAgIHsKICAgICAgICAkaWQgPSAxOwoKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHRoaXMtPnBhY2thZ2VzW10gPSAkcGFja2FnZTsKCiAgICAgICAgICAgICRwYWNrYWdlLT5pZCA9ICRpZCsrOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2UtPmdldE5hbWVzKCkgYXMgJHByb3ZpZGVkKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGFja2FnZUJ5TmFtZVskcHJvdmlkZWRdW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFja2FnZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIHBhY2thZ2Ugb2JqZWN0IGZvciBhIGdpdmVuIHBhY2thZ2UgaWQuCiAgICAgKgogICAgICogQHBhcmFtICBpbnQgICAgICAgICAgICAgICRpZAogICAgICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYWNrYWdlQnlJZCgkaWQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYWNrYWdlc1skaWQgLSAxXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgaG93IG1hbnkgcGFja2FnZXMgaGF2ZSBiZWVuIGxvYWRlZCBpbnRvIHRoZSBwb29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIFxjb3VudCgkdGhpcy0+cGFja2FnZXMpOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoZXMgYWxsIHBhY2thZ2VzIHByb3ZpZGluZyB0aGUgZ2l2ZW4gcGFja2FnZSBuYW1lIGFuZCBtYXRjaCB0aGUgY29uc3RyYWludAogICAgICoKICAgICAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICAgICAkbmFtZSAgICAgICBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHNlYXJjaGVkIGZvcgogICAgICogQHBhcmFtICBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50IEEgY29uc3RyYWludCB0aGF0IGFsbCByZXR1cm5lZAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzIG11c3QgbWF0Y2ggb3IgbnVsbCB0byByZXR1cm4gYWxsCiAgICAgKiBAcmV0dXJuIFBhY2thZ2VJbnRlcmZhY2VbXSAgQSBzZXQgb2YgcGFja2FnZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdoYXRQcm92aWRlcygkbmFtZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCA9IG51bGwpCiAgICB7CiAgICAgICAgJGtleSA9IChzdHJpbmcpICRjb25zdHJhaW50OwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cHJvdmlkZXJDYWNoZVskbmFtZV1bJGtleV0pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJvdmlkZXJDYWNoZVskbmFtZV1bJGtleV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb3ZpZGVyQ2FjaGVbJG5hbWVdWyRrZXldID0gJHRoaXMtPmNvbXB1dGVXaGF0UHJvdmlkZXMoJG5hbWUsICRjb25zdHJhaW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgd2hhdFByb3ZpZGVzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY29tcHV0ZVdoYXRQcm92aWRlcygkbmFtZSwgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cGFja2FnZUJ5TmFtZVskbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFja2FnZUJ5TmFtZVskbmFtZV0gYXMgJGNhbmRpZGF0ZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPm1hdGNoKCRjYW5kaWRhdGUsICRuYW1lLCAkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgICRtYXRjaGVzW10gPSAkY2FuZGlkYXRlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VJZCA9IGFicygkbGl0ZXJhbCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+cGFja2FnZUJ5SWQoJHBhY2thZ2VJZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGxpdGVyYWxUb1ByZXR0eVN0cmluZygkbGl0ZXJhbCwgJGluc3RhbGxlZE1hcCkKICAgIHsKICAgICAgICAkcGFja2FnZSA9ICR0aGlzLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKCiAgICAgICAgaWYgKGlzc2V0KCRpbnN0YWxsZWRNYXBbJHBhY2thZ2UtPmlkXSkpIHsKICAgICAgICAgICAgJHByZWZpeCA9ICgkbGl0ZXJhbCA+IDAgPyAna2VlcCcgOiAncmVtb3ZlJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHByZWZpeCA9ICgkbGl0ZXJhbCA+IDAgPyAnaW5zdGFsbCcgOiAnZG9uXCd0IGluc3RhbGwnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJlZml4LicgJy4kcGFja2FnZS0+Z2V0UHJldHR5U3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIHBhY2thZ2UgbWF0Y2hlcyB0aGUgZ2l2ZW4gY29uc3RyYWludCBkaXJlY3RseSBvciB0aHJvdWdoCiAgICAgKiBwcm92aWRlZCBvciByZXBsYWNlZCBwYWNrYWdlcwogICAgICoKICAgICAqIEBwYXJhbSAgUGFja2FnZUludGVyZmFjZSAgICAkY2FuZGlkYXRlCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgICAgJG5hbWUgICAgICAgTmFtZSBvZiB0aGUgcGFja2FnZSB0byBiZSBtYXRjaGVkCiAgICAgKiBAcGFyYW0gIENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQgVGhlIGNvbnN0cmFpbnQgdG8gdmVyaWZ5CiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoKCRjYW5kaWRhdGUsICRuYW1lLCBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAkY2FuZGlkYXRlTmFtZSA9ICRjYW5kaWRhdGUtPmdldE5hbWUoKTsKICAgICAgICAkY2FuZGlkYXRlVmVyc2lvbiA9ICRjYW5kaWRhdGUtPmdldFZlcnNpb24oKTsKCiAgICAgICAgaWYgKCRjYW5kaWRhdGVOYW1lID09PSAkbmFtZSkgewogICAgICAgICAgICByZXR1cm4gJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgQ29tcGlsaW5nTWF0Y2hlcjo6bWF0Y2goJGNvbnN0cmFpbnQsIENvbnN0cmFpbnQ6Ok9QX0VRLCAkY2FuZGlkYXRlVmVyc2lvbik7CiAgICAgICAgfQoKICAgICAgICAkcHJvdmlkZXMgPSAkY2FuZGlkYXRlLT5nZXRQcm92aWRlcygpOwogICAgICAgICRyZXBsYWNlcyA9ICRjYW5kaWRhdGUtPmdldFJlcGxhY2VzKCk7CgogICAgICAgIC8vIGFsaWFzZXMgY3JlYXRlIG11bHRpcGxlIHJlcGxhY2VzL3Byb3ZpZGVzIGZvciBvbmUgdGFyZ2V0IHNvIHRoZXkgY2FuIG5vdCB1c2UgdGhlIHNob3J0Y3V0IGJlbG93CiAgICAgICAgaWYgKGlzc2V0KCRyZXBsYWNlc1swXSkgfHwgaXNzZXQoJHByb3ZpZGVzWzBdKSkgewogICAgICAgICAgICBmb3JlYWNoICgkcHJvdmlkZXMgYXMgJGxpbmspIHsKICAgICAgICAgICAgICAgIGlmICgkbGluay0+Z2V0VGFyZ2V0KCkgPT09ICRuYW1lICYmICgkY29uc3RyYWludCA9PT0gbnVsbCB8fCAkY29uc3RyYWludC0+bWF0Y2hlcygkbGluay0+Z2V0Q29uc3RyYWludCgpKSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoJHJlcGxhY2VzIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoJGxpbmstPmdldFRhcmdldCgpID09PSAkbmFtZSAmJiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgJGNvbnN0cmFpbnQtPm1hdGNoZXMoJGxpbmstPmdldENvbnN0cmFpbnQoKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkcHJvdmlkZXNbJG5hbWVdKSAmJiAoJGNvbnN0cmFpbnQgPT09IG51bGwgfHwgJGNvbnN0cmFpbnQtPm1hdGNoZXMoJHByb3ZpZGVzWyRuYW1lXS0+Z2V0Q29uc3RyYWludCgpKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHJlcGxhY2VzWyRuYW1lXSkgJiYgKCRjb25zdHJhaW50ID09PSBudWxsIHx8ICRjb25zdHJhaW50LT5tYXRjaGVzKCRyZXBsYWNlc1skbmFtZV0tPmdldENvbnN0cmFpbnQoKSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc1VuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgcmV0dXJuIFxpbl9hcnJheSgkcGFja2FnZSwgJHRoaXMtPnVuYWNjZXB0YWJsZUZpeGVkT3JMb2NrZWRQYWNrYWdlcywgdHJ1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgICRzdHIgPSAiUG9vbDpcbiI7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkc3RyIC49ICctICcuc3RyX3BhZCgkcGFja2FnZS0+aWQsIDYsICcgJywgU1RSX1BBRF9MRUZUKS4nOiAnLiRwYWNrYWdlLT5nZXROYW1lKCkuIlxuIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc3RyOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXExpbms7CnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5Owp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25QYXJzZXI7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBhdXRob3IgUnViZW4gR29uemFsZXogPHJ1YmVucnVhQGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIFJ1bGUKewogICAgLy8gcmVhc29uIGNvbnN0YW50cwogICAgY29uc3QgUlVMRV9ST09UX1JFUVVJUkUgPSAyOwogICAgY29uc3QgUlVMRV9GSVhFRCA9IDM7CiAgICBjb25zdCBSVUxFX1BBQ0tBR0VfQ09ORkxJQ1QgPSA2OwogICAgY29uc3QgUlVMRV9QQUNLQUdFX1JFUVVJUkVTID0gNzsKICAgIGNvbnN0IFJVTEVfUEFDS0FHRV9TQU1FX05BTUUgPSAxMDsKICAgIGNvbnN0IFJVTEVfTEVBUk5FRCA9IDEyOwogICAgY29uc3QgUlVMRV9QQUNLQUdFX0FMSUFTID0gMTM7CiAgICBjb25zdCBSVUxFX1BBQ0tBR0VfSU5WRVJTRV9BTElBUyA9IDE0OwoKICAgIC8vIGJpdGZpZWxkIGRlZnMKICAgIGNvbnN0IEJJVEZJRUxEX1RZUEUgPSAwOwogICAgY29uc3QgQklURklFTERfUkVBU09OID0gODsKICAgIGNvbnN0IEJJVEZJRUxEX0RJU0FCTEVEID0gMTY7CgogICAgcHJvdGVjdGVkICRiaXRmaWVsZDsKICAgIHByb3RlY3RlZCAkcmVxdWVzdDsKICAgIHByb3RlY3RlZCAkcmVhc29uRGF0YTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUgcmVhc29uIGZvciBnZW5lcmF0aW5nIHRoaXMgcnVsZQogICAgICogQHBhcmFtIExpbmt8UGFja2FnZUludGVyZmFjZSAkcmVhc29uRGF0YQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlYXNvbkRhdGEgPSAkcmVhc29uRGF0YTsKCiAgICAgICAgJHRoaXMtPmJpdGZpZWxkID0gKDAgPDwgc2VsZjo6QklURklFTERfRElTQUJMRUQpIHwKICAgICAgICAgICAgKCRyZWFzb24gPDwgc2VsZjo6QklURklFTERfUkVBU09OKSB8CiAgICAgICAgICAgICgyNTUgPDwgc2VsZjo6QklURklFTERfVFlQRSk7CiAgICB9CgogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGdldExpdGVyYWxzKCk7CgogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGdldEhhc2goKTsKCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKFJ1bGUgJHJ1bGUpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWFzb24oKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPmJpdGZpZWxkICYgKDI1NSA8PCBzZWxmOjpCSVRGSUVMRF9SRUFTT04pKSA+PiBzZWxmOjpCSVRGSUVMRF9SRUFTT047CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlYXNvbkRhdGEoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVhc29uRGF0YTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVxdWlyZWRQYWNrYWdlKCkKICAgIHsKICAgICAgICAkcmVhc29uID0gJHRoaXMtPmdldFJlYXNvbigpOwoKICAgICAgICBpZiAoJHJlYXNvbiA9PT0gc2VsZjo6UlVMRV9ST09UX1JFUVVJUkUpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlTmFtZSddOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZWFzb24gPT09IHNlbGY6OlJVTEVfRklYRUQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlJ10tPmdldE5hbWUoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcmVhc29uID09PSBzZWxmOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVMpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFzb25EYXRhLT5nZXRUYXJnZXQoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldFR5cGUoJHR5cGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmJpdGZpZWxkID0gKCR0aGlzLT5iaXRmaWVsZCAmIH4oMjU1IDw8IHNlbGY6OkJJVEZJRUxEX1RZUEUpKSB8ICgoMjU1ICYgJHR5cGUpIDw8IHNlbGY6OkJJVEZJRUxEX1RZUEUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5iaXRmaWVsZCAmICgyNTUgPDwgc2VsZjo6QklURklFTERfVFlQRSkpID4+IHNlbGY6OkJJVEZJRUxEX1RZUEU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoKQogICAgewogICAgICAgICR0aGlzLT5iaXRmaWVsZCA9ICgkdGhpcy0+Yml0ZmllbGQgJiB+KDI1NSA8PCBzZWxmOjpCSVRGSUVMRF9ESVNBQkxFRCkpIHwgKDEgPDwgc2VsZjo6QklURklFTERfRElTQUJMRUQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGUoKQogICAgewogICAgICAgICR0aGlzLT5iaXRmaWVsZCAmPSB+KDI1NSA8PCBzZWxmOjpCSVRGSUVMRF9ESVNBQkxFRCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzRGlzYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiAoYm9vbCkgKCgkdGhpcy0+Yml0ZmllbGQgJiAoMjU1IDw8IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKSkgPj4gc2VsZjo6QklURklFTERfRElTQUJMRUQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0VuYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiAhKCgkdGhpcy0+Yml0ZmllbGQgJiAoMjU1IDw8IHNlbGY6OkJJVEZJRUxEX0RJU0FCTEVEKSkgPj4gc2VsZjo6QklURklFTERfRElTQUJMRUQpOwogICAgfQoKICAgIGFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBpc0Fzc2VydGlvbigpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0NhdXNlZEJ5TG9jayhSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Z2V0UmVhc29uKCkgPT09IHNlbGY6OlJVTEVfUEFDS0FHRV9SRVFVSVJFUykgewogICAgICAgICAgICBpZiAoUGxhdGZvcm1SZXBvc2l0b3J5Ojppc1BsYXRmb3JtUGFja2FnZSgkdGhpcy0+cmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRyZXF1ZXN0LT5nZXRMb2NrZWRSZXBvc2l0b3J5KCkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRMb2NrZWRSZXBvc2l0b3J5KCktPmdldFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldE5hbWUoKSA9PT0gJHRoaXMtPnJlYXNvbkRhdGEtPmdldFRhcmdldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcG9vbC0+aXNVbmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnJlYXNvbkRhdGEtPmdldENvbnN0cmFpbnQoKS0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWlyZWQgcGFja2FnZSB3YXMgbG9ja2VkIGJ1dCBoYXMgYmVlbiB1bmxvY2tlZCBhbmQgc3RpbGwgbWF0Y2hlcwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRyZXF1ZXN0LT5pc0xvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+Z2V0UmVhc29uKCkgPT09IHNlbGY6OlJVTEVfUk9PVF9SRVFVSVJFKSB7CiAgICAgICAgICAgIGlmIChQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlTmFtZSddKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkcmVxdWVzdC0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcmVxdWVzdC0+Z2V0TG9ja2VkUmVwb3NpdG9yeSgpLT5nZXRQYWNrYWdlcygpIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROYW1lKCkgPT09ICR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlTmFtZSddKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcG9vbC0+aXNVbmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnJlYXNvbkRhdGFbJ2NvbnN0cmFpbnQnXS0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPScsICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZyhSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sLCAkaXNWZXJib3NlLCBhcnJheSAkaW5zdGFsbGVkTWFwID0gYXJyYXkoKSwgYXJyYXkgJGxlYXJuZWRQb29sID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkbGl0ZXJhbHMgPSAkdGhpcy0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgc3dpdGNoICgkdGhpcy0+Z2V0UmVhc29uKCkpIHsKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1JPT1RfUkVRVUlSRToKICAgICAgICAgICAgICAgICRwYWNrYWdlTmFtZSA9ICR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlTmFtZSddOwogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkdGhpcy0+cmVhc29uRGF0YVsnY29uc3RyYWludCddOwoKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9ICRwb29sLT53aGF0UHJvdmlkZXMoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCk7CiAgICAgICAgICAgICAgICBpZiAoISRwYWNrYWdlcykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAnTm8gcGFja2FnZSBmb3VuZCB0byBzYXRpc2Z5IHJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlICcuJHBhY2thZ2VOYW1lLigkY29uc3RyYWludCA/ICcgJy4kY29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCkgOiAnJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHBhY2thZ2VzTm9uQWxpYXMgPSBhcnJheV92YWx1ZXMoYXJyYXlfZmlsdGVyKCRwYWNrYWdlcywgZnVuY3Rpb24gKCRwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEoJHAgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpOwogICAgICAgICAgICAgICAgfSkpOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRwYWNrYWdlc05vbkFsaWFzKSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2VzTm9uQWxpYXNbMF07CiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXF1ZXN0LT5pc0xvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicgaXMgbG9ja2VkIHRvIHZlcnNpb24gJy4kcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLiIgYW5kIGFuIHVwZGF0ZSBvZiB0aGlzIHBhY2thZ2Ugd2FzIG5vdCByZXF1ZXN0ZWQuIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICdSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJy4kcGFja2FnZU5hbWUuKCRjb25zdHJhaW50ID8gJyAnLiRjb25zdHJhaW50LT5nZXRQcmV0dHlTdHJpbmcoKSA6ICcnKS4nIC0+IHNhdGlzZmlhYmxlIGJ5ICcuJHRoaXMtPmZvcm1hdFBhY2thZ2VzVW5pcXVlKCRwb29sLCAkcGFja2FnZXMsICRpc1ZlcmJvc2UpLicuJzsKCiAgICAgICAgICAgIGNhc2Ugc2VsZjo6UlVMRV9GSVhFRDoKICAgICAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCR0aGlzLT5yZWFzb25EYXRhWydwYWNrYWdlJ10pOwoKICAgICAgICAgICAgICAgIGlmICgkcmVxdWVzdC0+aXNMb2NrZWRQYWNrYWdlKCRwYWNrYWdlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLicgaXMgbG9ja2VkIHRvIHZlcnNpb24gJy4kcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLicgYW5kIGFuIHVwZGF0ZSBvZiB0aGlzIHBhY2thZ2Ugd2FzIG5vdCByZXF1ZXN0ZWQuJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGlzIHByZXNlbnQgYXQgdmVyc2lvbiAnLiRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgLiAnIGFuZCBjYW5ub3QgYmUgbW9kaWZpZWQgYnkgQ29tcG9zZXInOwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfQ09ORkxJQ1Q6CiAgICAgICAgICAgICAgICAkcGFja2FnZTEgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzBdKSk7CiAgICAgICAgICAgICAgICAkcGFja2FnZTIgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzFdKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRwYWNrYWdlMi0+Z2V0UHJldHR5U3RyaW5nKCkuJyBjb25mbGljdHMgd2l0aCAnLiRwYWNrYWdlMS0+Z2V0UHJldHR5U3RyaW5nKCkuJy4nOwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVM6CiAgICAgICAgICAgICAgICAkc291cmNlTGl0ZXJhbCA9IGFycmF5X3NoaWZ0KCRsaXRlcmFscyk7CiAgICAgICAgICAgICAgICAkc291cmNlUGFja2FnZSA9ICR0aGlzLT5kZWR1cGxpY2F0ZURlZmF1bHRCcmFuY2hBbGlhcygkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkc291cmNlTGl0ZXJhbCkpOwoKICAgICAgICAgICAgICAgICRyZXF1aXJlcyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAkcmVxdWlyZXNbXSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkdGV4dCA9ICR0aGlzLT5yZWFzb25EYXRhLT5nZXRQcmV0dHlTdHJpbmcoJHNvdXJjZVBhY2thZ2UpOwogICAgICAgICAgICAgICAgaWYgKCRyZXF1aXJlcykgewogICAgICAgICAgICAgICAgICAgICR0ZXh0IC49ICcgLT4gc2F0aXNmaWFibGUgYnkgJyAuICR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJHJlcXVpcmVzLCAkaXNWZXJib3NlKSAuICcuJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldE5hbWUgPSAkdGhpcy0+cmVhc29uRGF0YS0+Z2V0VGFyZ2V0KCk7CgogICAgICAgICAgICAgICAgICAgICRyZWFzb24gPSBQcm9ibGVtOjpnZXRNaXNzaW5nUGFja2FnZVJlYXNvbigkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkdGFyZ2V0TmFtZSwgJHRoaXMtPnJlYXNvbkRhdGEtPmdldENvbnN0cmFpbnQoKSk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGV4dCAuICcgLT4gJyAuICRyZWFzb25bMV07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0ZXh0OwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX1BBQ0tBR0VfU0FNRV9OQU1FOgogICAgICAgICAgICAgICAgJHBhY2thZ2VOYW1lcyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZSA9ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRsaXRlcmFsKTsKICAgICAgICAgICAgICAgICAgICAkcGFja2FnZU5hbWVzWyRwYWNrYWdlLT5nZXROYW1lKCldID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXBsYWNlZE5hbWUgPSAkdGhpcy0+cmVhc29uRGF0YTsKCiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHBhY2thZ2VOYW1lcykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHBhY2thZ2VOYW1lc1skcmVwbGFjZWROYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICdUaGV5ICcuKGNvdW50KCRsaXRlcmFscykgPT0gMiA/ICdib3RoJyA6ICdhbGwnKS4nIHJlcGxhY2UgJy4kcmVwbGFjZWROYW1lLicgYW5kIHRodXMgY2Fubm90IGNvZXhpc3QuJzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVwbGFjZXJOYW1lcyA9ICRwYWNrYWdlTmFtZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRyZXBsYWNlck5hbWVzWyRyZXBsYWNlZE5hbWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlcGxhY2VyTmFtZXMgPSBhcnJheV9rZXlzKCRyZXBsYWNlck5hbWVzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCgkcmVwbGFjZXJOYW1lcykgPT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICRyZXBsYWNlck5hbWVzWzBdIC4gJyByZXBsYWNlcyAnOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiA9ICdbJy5pbXBsb2RlKCcsICcsICRyZXBsYWNlck5hbWVzKS4nXSByZXBsYWNlICc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHJlYXNvbiAuPSAkcmVwbGFjZWROYW1lLicgYW5kIHRodXMgY2Fubm90IGNvZXhpc3Qgd2l0aCBpdC4nOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGluc3RhbGxlZFBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAkcmVtb3ZhYmxlUGFja2FnZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRsaXRlcmFscyBhcyAkbGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGluc3RhbGxlZE1hcFthYnMoJGxpdGVyYWwpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnN0YWxsZWRQYWNrYWdlc1tdID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlbW92YWJsZVBhY2thZ2VzW10gPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkaW5zdGFsbGVkUGFja2FnZXMgJiYgJHJlbW92YWJsZVBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsICRyZW1vdmFibGVQYWNrYWdlcywgJGlzVmVyYm9zZSkuJyBjYW5ub3QgYmUgaW5zdGFsbGVkIGFzIHRoYXQgd291bGQgcmVxdWlyZSByZW1vdmluZyAnLiR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJGluc3RhbGxlZFBhY2thZ2VzLCAkaXNWZXJib3NlKS4nLiAnLiRyZWFzb247CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ09ubHkgb25lIG9mIHRoZXNlIGNhbiBiZSBpbnN0YWxsZWQ6ICcuJHRoaXMtPmZvcm1hdFBhY2thZ2VzVW5pcXVlKCRwb29sLCAkbGl0ZXJhbHMsICRpc1ZlcmJvc2UpLicuICcuJHJlYXNvbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ1lvdSBjYW4gb25seSBpbnN0YWxsIG9uZSB2ZXJzaW9uIG9mIGEgcGFja2FnZSwgc28gb25seSBvbmUgb2YgdGhlc2UgY2FuIGJlIGluc3RhbGxlZDogJyAuICR0aGlzLT5mb3JtYXRQYWNrYWdlc1VuaXF1ZSgkcG9vbCwgJGxpdGVyYWxzLCAkaXNWZXJib3NlKSAuICcuJzsKICAgICAgICAgICAgY2FzZSBzZWxmOjpSVUxFX0xFQVJORUQ6CiAgICAgICAgICAgICAgICAvKiogQFRPRE8gY3VycmVudGx5IHN0aWxsIGdlbmVyYXRlcyB3YXkgdG9vIG11Y2ggb3V0cHV0IHRvIGJlIGhlbHBmdWwsIGFuZCBpbiBzb21lIGNhc2VzIGNhbiBldmVuIGxlYWQgdG8gZW5kbGVzcyByZWN1cnNpb24gKi8KICAgICAgICAgICAgICAgIC8vIGlmIChpc3NldCgkbGVhcm5lZFBvb2xbJHRoaXMtPnJlYXNvbkRhdGFdKSkgewogICAgICAgICAgICAgICAgLy8gICAgIGVjaG8gJHRoaXMtPnJlYXNvbkRhdGEuIlxuIjsKICAgICAgICAgICAgICAgIC8vICAgICAkbGVhcm5lZFN0cmluZyA9ICcsIGxlYXJuZWQgcnVsZXM6JyAuIFByb2JsZW06OmZvcm1hdERlZHVwbGljYXRlZFJ1bGVzKCRsZWFybmVkUG9vbFskdGhpcy0+cmVhc29uRGF0YV0sICcgICAgICAgICcsICRyZXBvc2l0b3J5U2V0LCAkcmVxdWVzdCwgJHBvb2wsICRpc1ZlcmJvc2UsICRpbnN0YWxsZWRNYXAsICRsZWFybmVkUG9vbCk7CiAgICAgICAgICAgICAgICAvLyB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gICAgICRsZWFybmVkU3RyaW5nID0gJyAocmVhc29uaW5nIHVuYXZhaWxhYmxlKSc7CiAgICAgICAgICAgICAgICAvLyB9CiAgICAgICAgICAgICAgICAkbGVhcm5lZFN0cmluZyA9ICcgKGNvbmZsaWN0IGFuYWx5c2lzIHJlc3VsdCknOwoKICAgICAgICAgICAgICAgIGlmIChjb3VudCgkbGl0ZXJhbHMpID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0ID0gJHBvb2wtPmxpdGVyYWxUb1ByZXR0eVN0cmluZygkbGl0ZXJhbHNbMF0sICRpbnN0YWxsZWRNYXApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZ3JvdXBzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkaW5zdGFsbGVkTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZ3JvdXAgPSAkbGl0ZXJhbCA+IDAgPyAna2VlcCcgOiAncmVtb3ZlJzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRncm91cCA9ICRsaXRlcmFsID4gMCA/ICdpbnN0YWxsJyA6ICdkb25cJ3QgaW5zdGFsbCc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRncm91cHNbJGdyb3VwXVtdID0gJHRoaXMtPmRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKCRwYWNrYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0cyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3VwcyBhcyAkZ3JvdXAgPT4gJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRydWxlVGV4dHNbXSA9ICRncm91cCAuIChjb3VudCgkcGFja2FnZXMpID4gMSA/ICcgb25lIG9mJyA6ICcnKS4nICcgLiAkdGhpcy0+Zm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsICRwYWNrYWdlcywgJGlzVmVyYm9zZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcnVsZVRleHQgPSBpbXBsb2RlKCcgfCAnLCAkcnVsZVRleHRzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ0NvbmNsdXNpb246ICcuJHJ1bGVUZXh0LiRsZWFybmVkU3RyaW5nOwogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUEFDS0FHRV9BTElBUzoKICAgICAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbHNbMF0pOwoKICAgICAgICAgICAgICAgIC8vIGF2b2lkIHJldHVybmluZyBjb250ZW50IGxpa2UgIjk5OTk5OTktZGV2IGlzIGFuIGFsaWFzIG9mIGRldi1tYXN0ZXIiIGFzIGl0IGlzIHVzZWxlc3MKICAgICAgICAgICAgICAgIGlmICgkYWxpYXNQYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzFdKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRhbGlhc1BhY2thZ2UtPmdldFByZXR0eVN0cmluZygpIC4nIGlzIGFuIGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLicgYW5kIHRodXMgcmVxdWlyZXMgaXQgdG8gYmUgaW5zdGFsbGVkIHRvby4nOwogICAgICAgICAgICBjYXNlIHNlbGY6OlJVTEVfUEFDS0FHRV9JTlZFUlNFX0FMSUFTOgogICAgICAgICAgICAgICAgLy8gaW52ZXJzZSBhbGlhcyBydWxlcyB3b3JrIHRoZSBvdGhlciB3YXkgYXJvdW5kIHRoYW4gYWJvdmUKICAgICAgICAgICAgICAgICRhbGlhc1BhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbHNbMV0pOwoKICAgICAgICAgICAgICAgIC8vIGF2b2lkIHJldHVybmluZyBjb250ZW50IGxpa2UgIjk5OTk5OTktZGV2IGlzIGFuIGFsaWFzIG9mIGRldi1tYXN0ZXIiIGFzIGl0IGlzIHVzZWxlc3MKICAgICAgICAgICAgICAgIGlmICgkYWxpYXNQYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkdGhpcy0+ZGVkdXBsaWNhdGVEZWZhdWx0QnJhbmNoQWxpYXMoJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWxzWzBdKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICRhbGlhc1BhY2thZ2UtPmdldFByZXR0eVN0cmluZygpIC4nIGlzIGFuIGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLicgYW5kIG11c3QgYmUgaW5zdGFsbGVkIHdpdGggaXQuJzsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICRydWxlVGV4dCA9ICcnOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpdGVyYWxzIGFzICRpID0+ICRsaXRlcmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0IC49ICd8JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJ1bGVUZXh0IC49ICRwb29sLT5saXRlcmFsVG9QcmV0dHlTdHJpbmcoJGxpdGVyYWwsICRpbnN0YWxsZWRNYXApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAnKCcuJHJ1bGVUZXh0LicpJzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gUG9vbCAgJHBvb2wKICAgICAqIEBwYXJhbSBhcnJheSAkcGFja2FnZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZm9ybWF0UGFja2FnZXNVbmlxdWUoJHBvb2wsIGFycmF5ICRwYWNrYWdlcywgJGlzVmVyYm9zZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJGluZGV4ID0+ICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICghXGlzX29iamVjdCgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlc1skaW5kZXhdID0gJHBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJHBhY2thZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gUHJvYmxlbTo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRlZHVwbGljYXRlRGVmYXVsdEJyYW5jaEFsaWFzKFBhY2thZ2VJbnRlcmZhY2UgJHBhY2thZ2UpCiAgICB7CiAgICAgICAgaWYgKCRwYWNrYWdlIGluc3RhbmNlb2YgQWxpYXNQYWNrYWdlICYmICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkgPT09IFZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTKSB7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHBhY2thZ2UtPmdldEFsaWFzT2YoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGFja2FnZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqCiAqIE11bHRpQ29uZmxpY3RSdWxlKFtBLCBCLCBDXSkgYWN0cyBhcyBSdWxlKFstQSwgLUJdKSwgUnVsZShbLUEsIC1DXSksIFJ1bGUoWy1CLCAtQ10pCiAqLwpjbGFzcyBNdWx0aUNvbmZsaWN0UnVsZSBleHRlbmRzIFJ1bGUKewogICAgcHJvdGVjdGVkICRsaXRlcmFsczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICAgJGxpdGVyYWxzCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICAgICRyZWFzb24gICAgIEEgUlVMRV8qIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIHJlYXNvbiBmb3IgZ2VuZXJhdGluZyB0aGlzIHJ1bGUKICAgICAqIEBwYXJhbSBMaW5rfFBhY2thZ2VJbnRlcmZhY2UgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRsaXRlcmFscywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcmVhc29uLCAkcmVhc29uRGF0YSk7CgogICAgICAgIGlmIChcY291bnQoJGxpdGVyYWxzKSA8IDMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCJtdWx0aSBjb25mbGljdCBydWxlIHJlcXVpcmVzIGF0IGxlYXN0IDMgbGl0ZXJhbHMiKTsKICAgICAgICB9CgogICAgICAgIC8vIHNvcnQgYWxsIHBhY2thZ2VzIGFzY2VuZGluZyBieSBpZAogICAgICAgIHNvcnQoJGxpdGVyYWxzKTsKCiAgICAgICAgJHRoaXMtPmxpdGVyYWxzID0gJGxpdGVyYWxzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaXRlcmFscygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saXRlcmFsczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFzaCgpCiAgICB7CiAgICAgICAgJGRhdGEgPSB1bnBhY2soJ2loYXNoJywgbWQ1KCdjOicuaW1wbG9kZSgnLCcsICR0aGlzLT5saXRlcmFscyksIHRydWUpKTsKCiAgICAgICAgcmV0dXJuICRkYXRhWydoYXNoJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhpcyBydWxlIGlzIGVxdWFsIHRvIGFub3RoZXIgb25lCiAgICAgKgogICAgICogSWdub3JlcyB3aGV0aGVyIGVpdGhlciBvZiB0aGUgcnVsZXMgaXMgZGlzYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtICBSdWxlICRydWxlIFRoZSBydWxlIHRvIGNoZWNrIGFnYWluc3QKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBydWxlcyBhcmUgZXF1YWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVxdWFscyhSdWxlICRydWxlKQogICAgewogICAgICAgIGlmICgkcnVsZSBpbnN0YW5jZW9mIE11bHRpQ29uZmxpY3RSdWxlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bGl0ZXJhbHMgPT09ICRydWxlLT5nZXRMaXRlcmFscygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Fzc2VydGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlKCkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oIkRpc2FibGluZyBtdWx0aSBjb25mbGljdCBydWxlcyBpcyBub3QgcG9zc2libGUuIFBsZWFzZSBjb250YWN0IGNvbXBvc2VyIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3NlciB0byBsZXQgdXMgZGVidWcgd2hhdCBsZWFkIHRvIHRoaXMgc2l0dWF0aW9uLiIpOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIHJ1bGUgYXMgYSBzdHJpbmcgb2YgdGhlIGZvcm1hdCAoTGl0ZXJhbDF8TGl0ZXJhbDJ8Li4uKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICAvLyBUT0RPIG11bHRpIGNvbmZsaWN0PwogICAgICAgICRyZXN1bHQgPSAkdGhpcy0+aXNEaXNhYmxlZCgpID8gJ2Rpc2FibGVkKG11bHRpKCcgOiAnKG11bHRpKCc7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5saXRlcmFscyBhcyAkaSA9PiAkbGl0ZXJhbCkgewogICAgICAgICAgICBpZiAoJGkgIT0gMCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAnfCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdCAuPSAkbGl0ZXJhbDsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgLj0gJykpJzsKCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeUludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiBAaW50ZXJuYWwKICovCmNsYXNzIExvY2FsUmVwb1RyYW5zYWN0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb24KewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFJlcG9zaXRvcnlJbnRlcmZhY2UgJGxvY2tlZFJlcG9zaXRvcnksICRsb2NhbFJlcG9zaXRvcnkpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgKICAgICAgICAgICAgJGxvY2FsUmVwb3NpdG9yeS0+Z2V0UGFja2FnZXMoKSwKICAgICAgICAgICAgJGxvY2tlZFJlcG9zaXRvcnktPmdldFBhY2thZ2VzKCkKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxQYWNrYWdlXFBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUGxhdGZvcm1SZXBvc2l0b3J5OwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBSdWxlU2V0R2VuZXJhdG9yCnsKICAgIHByb3RlY3RlZCAkcG9saWN5OwogICAgcHJvdGVjdGVkICRwb29sOwogICAgcHJvdGVjdGVkICRydWxlczsKICAgIHByb3RlY3RlZCAkYWRkZWRNYXA7CiAgICBwcm90ZWN0ZWQgJGNvbmZsaWN0QWRkZWRNYXA7CiAgICBwcm90ZWN0ZWQgJGFkZGVkUGFja2FnZXNCeU5hbWVzOwogICAgcHJvdGVjdGVkICRjb25mbGljdHNGb3JOYW1lOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQb2xpY3lJbnRlcmZhY2UgJHBvbGljeSwgUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cG9saWN5ID0gJHBvbGljeTsKICAgICAgICAkdGhpcy0+cG9vbCA9ICRwb29sOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBydWxlIGZvciB0aGUgcmVxdWlyZW1lbnRzIG9mIGEgcGFja2FnZQogICAgICoKICAgICAqIFRoaXMgcnVsZSBpcyBvZiB0aGUgZm9ybSAoLUF8QnxDKSwgd2hlcmUgQiBhbmQgQyBhcmUgdGhlIHByb3ZpZGVycyBvZgogICAgICogb25lIHJlcXVpcmVtZW50IG9mIHRoZSBwYWNrYWdlIEEuCiAgICAgKgogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICAgIFRoZSBwYWNrYWdlIHdpdGggYSByZXF1aXJlbWVudAogICAgICogQHBhcmFtICBhcnJheSAgICAgICAgICAgICRwcm92aWRlcnMgIFRoZSBwcm92aWRlcnMgb2YgdGhlIHJlcXVpcmVtZW50CiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb24gZm9yIGdlbmVyYXRpbmcgdGhpcyBydWxlCiAgICAgKiBAcGFyYW0gIG1peGVkICAgICAgICAgICAgJHJlYXNvbkRhdGEgQW55IGRhdGEsIGUuZy4gdGhlIHJlcXVpcmVtZW50IG5hbWUsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBnb2VzIHdpdGggdGhlIHJlYXNvbgogICAgICogQHJldHVybiBSdWxlfG51bGwgICAgICAgIFRoZSBnZW5lcmF0ZWQgcnVsZSBvciBudWxsIGlmIHRhdXRvbG9naWNhbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlUmVxdWlyZVJ1bGUoUGFja2FnZUludGVyZmFjZSAkcGFja2FnZSwgYXJyYXkgJHByb3ZpZGVycywgJHJlYXNvbiwgJHJlYXNvbkRhdGEgPSBudWxsKQogICAgewogICAgICAgICRsaXRlcmFscyA9IGFycmF5KC0kcGFja2FnZS0+aWQpOwoKICAgICAgICBmb3JlYWNoICgkcHJvdmlkZXJzIGFzICRwcm92aWRlcikgewogICAgICAgICAgICAvLyBzZWxmIGZ1bGZpbGxpbmcgcnVsZT8KICAgICAgICAgICAgaWYgKCRwcm92aWRlciA9PT0gJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaXRlcmFsc1tdID0gJHByb3ZpZGVyLT5pZDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgR2VuZXJpY1J1bGUoJGxpdGVyYWxzLCAkcmVhc29uLCAkcmVhc29uRGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgcnVsZSB0byBpbnN0YWxsIGF0IGxlYXN0IG9uZSBvZiBhIHNldCBvZiBwYWNrYWdlcwogICAgICoKICAgICAqIFRoZSBydWxlIGlzIChBfEJ8Qykgd2l0aCBBLCBCIGFuZCBDIGRpZmZlcmVudCBwYWNrYWdlcy4gSWYgdGhlIGdpdmVuCiAgICAgKiBzZXQgb2YgcGFja2FnZXMgaXMgZW1wdHkgYW4gaW1wb3NzaWJsZSBydWxlIGlzIGdlbmVyYXRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIGFycmF5ICRwYWNrYWdlcyAgIFRoZSBzZXQgb2YgcGFja2FnZXMgdG8gY2hvb3NlIGZyb20KICAgICAqIEBwYXJhbSAgaW50ICAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUgcmVhc29uIGZvcgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0aW5nIHRoaXMgcnVsZQogICAgICogQHBhcmFtICBhcnJheSAkcmVhc29uRGF0YSBBZGRpdGlvbmFsIGRhdGEgbGlrZSB0aGUgcm9vdCByZXF1aXJlIG9yIGZpeCByZXF1ZXN0IGluZm8KICAgICAqIEByZXR1cm4gUnVsZSAgVGhlIGdlbmVyYXRlZCBydWxlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVJbnN0YWxsT25lT2ZSdWxlKGFycmF5ICRwYWNrYWdlcywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgJGxpdGVyYWxzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJGxpdGVyYWxzW10gPSAkcGFja2FnZS0+aWQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IEdlbmVyaWNSdWxlKCRsaXRlcmFscywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHJ1bGUgZm9yIHR3byBjb25mbGljdGluZyBwYWNrYWdlcwogICAgICoKICAgICAqIFRoZSBydWxlIGZvciBjb25mbGljdGluZyBwYWNrYWdlcyBBIGFuZCBCIGlzICgtQXwtQikuIEEgaXMgY2FsbGVkIHRoZSBpc3N1ZXIKICAgICAqIGFuZCBCIHRoZSBwcm92aWRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gIFBhY2thZ2VJbnRlcmZhY2UgJGlzc3VlciAgICAgVGhlIHBhY2thZ2UgZGVjbGFyaW5nIHRoZSBjb25mbGljdAogICAgICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwcm92aWRlciAgIFRoZSBwYWNrYWdlIGNhdXNpbmcgdGhlIGNvbmZsaWN0CiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgJHJlYXNvbiAgICAgQSBSVUxFXyogY29uc3RhbnQgZGVzY3JpYmluZyB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb24gZm9yIGdlbmVyYXRpbmcgdGhpcyBydWxlCiAgICAgKiBAcGFyYW0gIG1peGVkICAgICAgICAgICAgJHJlYXNvbkRhdGEgQW55IGRhdGEsIGUuZy4gdGhlIHBhY2thZ2UgbmFtZSwgdGhhdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvZXMgd2l0aCB0aGUgcmVhc29uCiAgICAgKiBAcmV0dXJuIFJ1bGV8bnVsbCAgICAgICAgVGhlIGdlbmVyYXRlZCBydWxlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVSdWxlMkxpdGVyYWxzKFBhY2thZ2VJbnRlcmZhY2UgJGlzc3VlciwgUGFja2FnZUludGVyZmFjZSAkcHJvdmlkZXIsICRyZWFzb24sICRyZWFzb25EYXRhID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBpZ25vcmUgc2VsZiBjb25mbGljdAogICAgICAgIGlmICgkaXNzdWVyID09PSAkcHJvdmlkZXIpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IFJ1bGUyTGl0ZXJhbHMoLSRpc3N1ZXItPmlkLCAtJHByb3ZpZGVyLT5pZCwgJHJlYXNvbiwgJHJlYXNvbkRhdGEpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVNdWx0aUNvbmZsaWN0UnVsZShhcnJheSAkcGFja2FnZXMsICRyZWFzb24sICRyZWFzb25EYXRhID0gbnVsbCkKICAgIHsKICAgICAgICAkbGl0ZXJhbHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAkbGl0ZXJhbHNbXSA9IC0kcGFja2FnZS0+aWQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRsaXRlcmFscykgPT0gMikgewogICAgICAgICAgICByZXR1cm4gbmV3IFJ1bGUyTGl0ZXJhbHMoJGxpdGVyYWxzWzBdLCAkbGl0ZXJhbHNbMV0sICRyZWFzb24sICRyZWFzb25EYXRhKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgTXVsdGlDb25mbGljdFJ1bGUoJGxpdGVyYWxzLCAkcmVhc29uLCAkcmVhc29uRGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgcnVsZSB1bmxlc3MgaXQgZHVwbGljYXRlcyBhbiBleGlzdGluZyBvbmUgb2YgYW55IHR5cGUKICAgICAqCiAgICAgKiBUbyBiZSBhYmxlIHRvIGRpcmVjdGx5IHBhc3MgaW4gdGhlIHJlc3VsdCBvZiBvbmUgb2YgdGhlIHJ1bGUgY3JlYXRpb24KICAgICAqIG1ldGhvZHMgbnVsbCBpcyBhbGxvd2VkIHdoaWNoIHdpbGwgbm90IGluc2VydCBhIHJ1bGUuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgJHR5cGUgICAgQSBUWVBFXyogY29uc3RhbnQgZGVmaW5pbmcgdGhlIHJ1bGUgdHlwZQogICAgICogQHBhcmFtIFJ1bGUgJG5ld1J1bGUgVGhlIHJ1bGUgYWJvdXQgdG8gYmUgYWRkZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRSdWxlKCR0eXBlLCBSdWxlICRuZXdSdWxlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISRuZXdSdWxlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5ydWxlcy0+YWRkKCRuZXdSdWxlLCAkdHlwZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJ1bGVzRm9yUGFja2FnZShQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCAkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgewogICAgICAgICR3b3JrUXVldWUgPSBuZXcgXFNwbFF1ZXVlOwogICAgICAgICR3b3JrUXVldWUtPmVucXVldWUoJHBhY2thZ2UpOwoKICAgICAgICB3aGlsZSAoISR3b3JrUXVldWUtPmlzRW1wdHkoKSkgewogICAgICAgICAgICAvKiogQHZhciBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICovCiAgICAgICAgICAgICRwYWNrYWdlID0gJHdvcmtRdWV1ZS0+ZGVxdWV1ZSgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5pZF0gPSAkcGFja2FnZTsKCiAgICAgICAgICAgIGlmICghJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXROYW1lcyhmYWxzZSkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkZWRQYWNrYWdlc0J5TmFtZXNbJG5hbWVdW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR3b3JrUXVldWUtPmVucXVldWUoJHBhY2thZ2UtPmdldEFsaWFzT2YoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVSZXF1aXJlUnVsZSgkcGFja2FnZSwgYXJyYXkoJHBhY2thZ2UtPmdldEFsaWFzT2YoKSksIFJ1bGU6OlJVTEVfUEFDS0FHRV9BTElBUywgJHBhY2thZ2UpKTsKCiAgICAgICAgICAgICAgICAvLyBhbGlhc2VzIG11c3QgYmUgaW5zdGFsbGVkIHdpdGggdGhlaXIgbWFpbiBwYWNrYWdlLCBzbyBjcmVhdGUgYSBydWxlIHRoZSBvdGhlciB3YXkgYXJvdW5kIGFzIHdlbGwKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRSdWxlKFJ1bGVTZXQ6OlRZUEVfUEFDS0FHRSwgJHRoaXMtPmNyZWF0ZVJlcXVpcmVSdWxlKCRwYWNrYWdlLT5nZXRBbGlhc09mKCksIGFycmF5KCRwYWNrYWdlKSwgUnVsZTo6UlVMRV9QQUNLQUdFX0lOVkVSU0VfQUxJQVMsICRwYWNrYWdlLT5nZXRBbGlhc09mKCkpKTsKCiAgICAgICAgICAgICAgICAvLyBpZiBhbGlhcyBwYWNrYWdlIGhhcyBubyBzZWxmLnZlcnNpb24gcmVxdWlyZXMsIGl0cyByZXF1aXJlbWVudHMgZG8gbm90CiAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIGJlIGFkZGVkIGFzIHRoZSBhbGlhc2VkIHBhY2thZ2UgcHJvY2Vzc2luZyB3aWxsIHRha2UgY2FyZSBvZiBpdAogICAgICAgICAgICAgICAgaWYgKCEkcGFja2FnZS0+aGFzU2VsZlZlcnNpb25SZXF1aXJlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRSZXF1aXJlcygpIGFzICRsaW5rKSB7CiAgICAgICAgICAgICAgICBpZiAoKHRydWUgPT09ICRpZ25vcmVQbGF0Zm9ybVJlcXMgfHwgKGlzX2FycmF5KCRpZ25vcmVQbGF0Zm9ybVJlcXMpICYmIGluX2FycmF5KCRsaW5rLT5nZXRUYXJnZXQoKSwgJGlnbm9yZVBsYXRmb3JtUmVxcywgdHJ1ZSkpKSAmJiBQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcG9zc2libGVSZXF1aXJlcyA9ICR0aGlzLT5wb29sLT53aGF0UHJvdmlkZXMoJGxpbmstPmdldFRhcmdldCgpLCAkbGluay0+Z2V0Q29uc3RyYWludCgpKTsKCiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVSZXF1aXJlUnVsZSgkcGFja2FnZSwgJHBvc3NpYmxlUmVxdWlyZXMsIFJ1bGU6OlJVTEVfUEFDS0FHRV9SRVFVSVJFUywgJGxpbmspKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG9zc2libGVSZXF1aXJlcyBhcyAkcmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgICR3b3JrUXVldWUtPmVucXVldWUoJHJlcXVpcmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRDb25mbGljdFJ1bGVzKCRpZ25vcmVQbGF0Zm9ybVJlcXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAvKiogQHZhciBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlICovCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFkZGVkTWFwIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlLT5nZXRDb25mbGljdHMoKSBhcyAkbGluaykgewogICAgICAgICAgICAgICAgLy8gZXZlbiBpZiBjb25saWN0IGVuZHMgdXAgYmVpbmcgd2l0aCBhbiBhbGlhcywgdGhlcmUgd291bGQgYmUgYXQgbGVhc3Qgb25lIGFjdHVhbCBwYWNrYWdlIGJ5IHRoaXMgbmFtZQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+YWRkZWRQYWNrYWdlc0J5TmFtZXNbJGxpbmstPmdldFRhcmdldCgpXSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoKHRydWUgPT09ICRpZ25vcmVQbGF0Zm9ybVJlcXMgfHwgKGlzX2FycmF5KCRpZ25vcmVQbGF0Zm9ybVJlcXMpICYmIGluX2FycmF5KCRsaW5rLT5nZXRUYXJnZXQoKSwgJGlnbm9yZVBsYXRmb3JtUmVxcywgdHJ1ZSkpKSAmJiBQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRsaW5rLT5nZXRUYXJnZXQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkY29uZmxpY3RzID0gJHRoaXMtPnBvb2wtPndoYXRQcm92aWRlcygkbGluay0+Z2V0VGFyZ2V0KCksICRsaW5rLT5nZXRDb25zdHJhaW50KCkpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb25mbGljdHMgYXMgJGNvbmZsaWN0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZGVmaW5lIHRoZSBjb25mbGljdCBydWxlIGZvciByZWd1bGFyIHBhY2thZ2VzLCBmb3IgYWxpYXMgcGFja2FnZXMgaXQncyBvbmx5IG5lZWRlZCBpZiB0aGUgbmFtZQogICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoZXMgdGhlIGNvbmZsaWN0IGV4YWN0bHksIG90aGVyd2lzZSB0aGUgbmFtZSBtYXRjaCBpcyBieSBwcm92aWRlL3JlcGxhY2Ugd2hpY2ggbWVhbnMgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gcGFja2FnZSB3aGljaCB0aGlzIGlzIGFuIGFsaWFzIG9mIHdpbGwgY29uZmxpY3QgYW55d2F5LCBzbyBubyBuZWVkIHRvIGNyZWF0ZSBhZGRpdGlvbmFsIHJ1bGVzCiAgICAgICAgICAgICAgICAgICAgaWYgKCEkY29uZmxpY3QgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UgfHwgJGNvbmZsaWN0LT5nZXROYW1lKCkgPT09ICRsaW5rLT5nZXRUYXJnZXQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVSdWxlMkxpdGVyYWxzKCRwYWNrYWdlLCAkY29uZmxpY3QsIFJ1bGU6OlJVTEVfUEFDS0FHRV9DT05GTElDVCwgJGxpbmspKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5hZGRlZFBhY2thZ2VzQnlOYW1lcyBhcyAkbmFtZSA9PiAkcGFja2FnZXMpIHsKICAgICAgICAgICAgaWYgKFxjb3VudCgkcGFja2FnZXMpID4gMSkgewogICAgICAgICAgICAgICAgJHJlYXNvbiA9IFJ1bGU6OlJVTEVfUEFDS0FHRV9TQU1FX05BTUU7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1BBQ0tBR0UsICR0aGlzLT5jcmVhdGVNdWx0aUNvbmZsaWN0UnVsZSgkcGFja2FnZXMsICRyZWFzb24sICRuYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJ1bGVzRm9yUmVxdWVzdChSZXF1ZXN0ICRyZXF1ZXN0LCAkaWdub3JlUGxhdGZvcm1SZXFzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRGaXhlZFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5pZCA9PSAtMSkgewogICAgICAgICAgICAgICAgLy8gZml4ZWQgcGFja2FnZSB3YXMgbm90IGFkZGVkIHRvIHRoZSBwb29sIGFzIGl0IGRpZCBub3QgcGFzcyB0aGUgc3RhYmlsaXR5IHJlcXVpcmVtZW50cywgdGhpcyBpcyBmaW5lCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnBvb2wtPmlzVW5hY2NlcHRhYmxlRml4ZWRPckxvY2tlZFBhY2thZ2UoJHBhY2thZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBsb29rcyBsaWtlIGEgYnVnCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJGaXhlZCBwYWNrYWdlICIuJHBhY2thZ2UtPmdldFByZXR0eVN0cmluZygpLiIgd2FzIG5vdCBhZGRlZCB0byBzb2x2ZXIgcG9vbC4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmFkZFJ1bGVzRm9yUGFja2FnZSgkcGFja2FnZSwgJGlnbm9yZVBsYXRmb3JtUmVxcyk7CgogICAgICAgICAgICAkcnVsZSA9ICR0aGlzLT5jcmVhdGVJbnN0YWxsT25lT2ZSdWxlKGFycmF5KCRwYWNrYWdlKSwgUnVsZTo6UlVMRV9GSVhFRCwgYXJyYXkoCiAgICAgICAgICAgICAgICAncGFja2FnZScgPT4gJHBhY2thZ2UsCiAgICAgICAgICAgICkpOwogICAgICAgICAgICAkdGhpcy0+YWRkUnVsZShSdWxlU2V0OjpUWVBFX1JFUVVFU1QsICRydWxlKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRyZXF1ZXN0LT5nZXRSZXF1aXJlcygpIGFzICRwYWNrYWdlTmFtZSA9PiAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoKHRydWUgPT09ICRpZ25vcmVQbGF0Zm9ybVJlcXMgfHwgKGlzX2FycmF5KCRpZ25vcmVQbGF0Zm9ybVJlcXMpICYmIGluX2FycmF5KCRwYWNrYWdlTmFtZSwgJGlnbm9yZVBsYXRmb3JtUmVxcywgdHJ1ZSkpKSAmJiBQbGF0Zm9ybVJlcG9zaXRvcnk6OmlzUGxhdGZvcm1QYWNrYWdlKCRwYWNrYWdlTmFtZSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGFja2FnZXMgPSAkdGhpcy0+cG9vbC0+d2hhdFByb3ZpZGVzKCRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQpOwogICAgICAgICAgICBpZiAoJHBhY2thZ2VzKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZXNGb3JQYWNrYWdlKCRwYWNrYWdlLCAkaWdub3JlUGxhdGZvcm1SZXFzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcnVsZSA9ICR0aGlzLT5jcmVhdGVJbnN0YWxsT25lT2ZSdWxlKCRwYWNrYWdlcywgUnVsZTo6UlVMRV9ST09UX1JFUVVJUkUsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICdwYWNrYWdlTmFtZScgPT4gJHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICdjb25zdHJhaW50JyA9PiAkY29uc3RyYWludCwKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFJ1bGUoUnVsZVNldDo6VFlQRV9SRVFVRVNULCAkcnVsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJ1bGVzRm9yUm9vdEFsaWFzZXMoJGlnbm9yZVBsYXRmb3JtUmVxcykKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cG9vbC0+Z2V0UGFja2FnZXMoKSBhcyAkcGFja2FnZSkgewogICAgICAgICAgICAvLyBlbnN1cmUgdGhhdCBydWxlcyBmb3Igcm9vdCBhbGlhcyBwYWNrYWdlcyBhbmQgYWxpYXNlcyBvZiBwYWNrYWdlcyB3aGljaCB3ZXJlIGxvYWRlZCBhcmUgYWxzbyBsb2FkZWQKICAgICAgICAgICAgLy8gZXZlbiBpZiB0aGUgYWxpYXMgaXRzZWxmIGlzbid0IHJlcXVpcmVkLCBvdGhlcndpc2UgYSBwYWNrYWdlIGNvdWxkIGJlIGluc3RhbGxlZCB3aXRob3V0IGl0cyBhbGlhcyB3aGljaAogICAgICAgICAgICAvLyBsZWFkcyB0byB1bmV4cGVjdGVkIGJlaGF2aW9yCiAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmFkZGVkTWFwWyRwYWNrYWdlLT5pZF0pICYmCiAgICAgICAgICAgICAgICAkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSAmJgogICAgICAgICAgICAgICAgKCRwYWNrYWdlLT5pc1Jvb3RQYWNrYWdlQWxpYXMoKSB8fCBpc3NldCgkdGhpcy0+YWRkZWRNYXBbJHBhY2thZ2UtPmdldEFsaWFzT2YoKS0+aWRdKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkUnVsZXNGb3JQYWNrYWdlKCRwYWNrYWdlLCAkaWdub3JlUGxhdGZvcm1SZXFzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sfGFycmF5ICRpZ25vcmVQbGF0Zm9ybVJlcXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJ1bGVzRm9yKFJlcXVlc3QgJHJlcXVlc3QsICRpZ25vcmVQbGF0Zm9ybVJlcXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+cnVsZXMgPSBuZXcgUnVsZVNldDsKCiAgICAgICAgJHRoaXMtPmFkZGVkTWFwID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+Y29uZmxpY3RBZGRlZE1hcCA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmFkZGVkUGFja2FnZXNCeU5hbWVzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+Y29uZmxpY3RzRm9yTmFtZSA9IGFycmF5KCk7CgogICAgICAgICR0aGlzLT5hZGRSdWxlc0ZvclJlcXVlc3QoJHJlcXVlc3QsICRpZ25vcmVQbGF0Zm9ybVJlcXMpOwoKICAgICAgICAkdGhpcy0+YWRkUnVsZXNGb3JSb290QWxpYXNlcygkaWdub3JlUGxhdGZvcm1SZXFzKTsKCiAgICAgICAgJHRoaXMtPmFkZENvbmZsaWN0UnVsZXMoJGlnbm9yZVBsYXRmb3JtUmVxcyk7CgogICAgICAgIC8vIFJlbW92ZSByZWZlcmVuY2VzIHRvIHBhY2thZ2VzCiAgICAgICAgJHRoaXMtPmFkZGVkTWFwID0gJHRoaXMtPmFkZGVkUGFja2FnZXNCeU5hbWVzID0gbnVsbDsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxDb21wbGV0ZVBhY2thZ2VJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxQYWNrYWdlXEFsaWFzUGFja2FnZTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeVNldDsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcTG9ja0FycmF5UmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxQYWNrYWdlXFZlcnNpb25cVmVyc2lvblBhcnNlcjsKCi8qKgogKiBSZXByZXNlbnRzIGEgcHJvYmxlbSBkZXRlY3RlZCB3aGlsZSBzb2x2aW5nIGRlcGVuZGVuY2llcwogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUHJvYmxlbQp7CiAgICAvKioKICAgICAqIEEgbWFwIGNvbnRhaW5pbmcgdGhlIGlkIG9mIGVhY2ggcnVsZSBwYXJ0IG9mIHRoaXMgcHJvYmxlbSBhcyBhIGtleQogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlYXNvblNlZW47CgogICAgLyoqCiAgICAgKiBBIHNldCBvZiByZWFzb25zIGZvciB0aGUgcHJvYmxlbSwgZWFjaCBpcyBhIHJ1bGUgb3IgYSByb290IHJlcXVpcmUgYW5kIGEgcnVsZQogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlYXNvbnMgPSBhcnJheSgpOwoKICAgIHByb3RlY3RlZCAkc2VjdGlvbiA9IDA7CgogICAgLyoqCiAgICAgKiBBZGQgYSBydWxlIGFzIGEgcmVhc29uCiAgICAgKgogICAgICogQHBhcmFtIFJ1bGUgJHJ1bGUgQSBydWxlIHdoaWNoIGlzIGEgcmVhc29uIGZvciB0aGlzIHByb2JsZW0KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJ1bGUoUnVsZSAkcnVsZSkKICAgIHsKICAgICAgICAkdGhpcy0+YWRkUmVhc29uKHNwbF9vYmplY3RfaGFzaCgkcnVsZSksICRydWxlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIGFsbCByZWFzb25zIGZvciB0aGlzIHByb2JsZW0KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBwcm9ibGVtJ3MgcmVhc29ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVhc29ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFzb25zOwogICAgfQoKICAgIC8qKgogICAgICogQSBodW1hbiByZWFkYWJsZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcm9ibGVtJ3MgcmVhc29ucwogICAgICoKICAgICAqIEBwYXJhbSAgYXJyYXkgICRpbnN0YWxsZWRNYXAgQSBtYXAgb2YgYWxsIHByZXNlbnQgcGFja2FnZXMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCwgUmVxdWVzdCAkcmVxdWVzdCwgUG9vbCAkcG9vbCwgJGlzVmVyYm9zZSwgYXJyYXkgJGluc3RhbGxlZE1hcCA9IGFycmF5KCksIGFycmF5ICRsZWFybmVkUG9vbCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgLy8gVE9ETyBkb2Vzbid0IHRoaXMgZW50aXJlbHkgZGVmZWF0IHRoZSBwdXJwb3NlIG9mIHRoZSBwcm9ibGVtIHNlY3Rpb25zPyB3aGF0J3MgdGhlIHBvaW50IG9mIHNlY3Rpb25zPwogICAgICAgICRyZWFzb25zID0gY2FsbF91c2VyX2Z1bmNfYXJyYXkoJ2FycmF5X21lcmdlJywgYXJyYXlfcmV2ZXJzZSgkdGhpcy0+cmVhc29ucykpOwoKICAgICAgICBpZiAoY291bnQoJHJlYXNvbnMpID09PSAxKSB7CiAgICAgICAgICAgIHJlc2V0KCRyZWFzb25zKTsKICAgICAgICAgICAgJHJ1bGUgPSBjdXJyZW50KCRyZWFzb25zKTsKCiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHJ1bGUtPmdldFJlYXNvbigpLCBhcnJheShSdWxlOjpSVUxFX1JPT1RfUkVRVUlSRSwgUnVsZTo6UlVMRV9GSVhFRCksIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCJTaW5nbGUgcmVhc29uIHByb2JsZW1zIG11c3QgY29udGFpbiBhIHJlcXVlc3QgcnVsZS4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHJlYXNvbkRhdGEgPSAkcnVsZS0+Z2V0UmVhc29uRGF0YSgpOwogICAgICAgICAgICAkcGFja2FnZU5hbWUgPSAkcmVhc29uRGF0YVsncGFja2FnZU5hbWUnXTsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkcmVhc29uRGF0YVsnY29uc3RyYWludCddOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25zdHJhaW50KSkgewogICAgICAgICAgICAgICAgJHBhY2thZ2VzID0gJHBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYWNrYWdlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbXB0eSgkcGFja2FnZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIlxuICAgICIuaW1wbG9kZShzZWxmOjpnZXRNaXNzaW5nUGFja2FnZVJlYXNvbigkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjpmb3JtYXREZWR1cGxpY2F0ZWRSdWxlcygkcmVhc29ucywgJyAgICAnLCAkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkaW5zdGFsbGVkTWFwLCAkbGVhcm5lZFBvb2wpOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0RGVkdXBsaWNhdGVkUnVsZXMoJHJ1bGVzLCAkaW5kZW50LCBSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sLCAkaXNWZXJib3NlLCBhcnJheSAkaW5zdGFsbGVkTWFwID0gYXJyYXkoKSwgYXJyYXkgJGxlYXJuZWRQb29sID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBhcnJheSgpOwogICAgICAgICR0ZW1wbGF0ZXMgPSBhcnJheSgpOwogICAgICAgICRwYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcjsKICAgICAgICAkZGVkdXBsaWNhdGFibGVSdWxlVHlwZXMgPSBhcnJheShSdWxlOjpSVUxFX1BBQ0tBR0VfUkVRVUlSRVMsIFJ1bGU6OlJVTEVfUEFDS0FHRV9DT05GTElDVCk7CiAgICAgICAgZm9yZWFjaCAoJHJ1bGVzIGFzICRydWxlKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHJ1bGUtPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlLCAkaW5zdGFsbGVkTWFwLCAkbGVhcm5lZFBvb2wpOwogICAgICAgICAgICBpZiAoaW5fYXJyYXkoJHJ1bGUtPmdldFJlYXNvbigpLCAkZGVkdXBsaWNhdGFibGVSdWxlVHlwZXMsIHRydWUpICYmIHByZWdfbWF0Y2goJ3teKD9QPHBhY2thZ2U+XFMrKSAoP1A8dmVyc2lvbj5cUyspICg/UDx0eXBlPnJlcXVpcmVzfGNvbmZsaWN0cyl9JywgJG1lc3NhZ2UsICRtKSkgewogICAgICAgICAgICAgICAgJHRlbXBsYXRlID0gcHJlZ19yZXBsYWNlKCd7XlxTKyBcUysgfScsICclcyVzICcsICRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICRtZXNzYWdlc1tdID0gJHRlbXBsYXRlOwogICAgICAgICAgICAgICAgJHRlbXBsYXRlc1skdGVtcGxhdGVdWyRtWzFdXVskcGFyc2VyLT5ub3JtYWxpemUoJG1bMl0pXSA9ICRtWzJdOwogICAgICAgICAgICB9IGVsc2VpZiAoJG1lc3NhZ2UgIT09ICcnKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZXNbXSA9ICRtZXNzYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoIChhcnJheV91bmlxdWUoJG1lc3NhZ2VzKSBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJHRlbXBsYXRlc1skbWVzc2FnZV0pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGVtcGxhdGVzWyRtZXNzYWdlXSBhcyAkcGFja2FnZSA9PiAkdmVyc2lvbnMpIHsKICAgICAgICAgICAgICAgICAgICB1a3NvcnQoJHZlcnNpb25zLCAndmVyc2lvbl9jb21wYXJlJyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkaXNWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9ucyA9IHNlbGY6OmNvbmRlbnNlVmVyc2lvbkxpc3QoJHZlcnNpb25zLCAxKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50KCR2ZXJzaW9ucykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgcyBmcm9tIHJlcXVpcmVzL2NvbmZsaWN0cyB0byBjb3JyZWN0IGdyYW1tYXIKICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBwcmVnX3JlcGxhY2UoJ3teKCVzJXMgKD86cmVxdWlyZXxjb25mbGljdCkpc30nLCAnJDEnLCAkbWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IHNwcmludGYoJG1lc3NhZ2UsICRwYWNrYWdlLCAnWycuaW1wbG9kZSgnLCAnLCAkdmVyc2lvbnMpLiddJyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gc3ByaW50ZigkbWVzc2FnZSwgJHBhY2thZ2UsICcgJy5yZXNldCgkdmVyc2lvbnMpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkbWVzc2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICJcbiRpbmRlbnQtICIuaW1wbG9kZSgiXG4kaW5kZW50LSAiLCAkcmVzdWx0KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNDYXVzZWRCeUxvY2soUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCwgUmVxdWVzdCAkcmVxdWVzdCwgUG9vbCAkcG9vbCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVhc29ucyBhcyAkc2VjdGlvblJ1bGVzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzZWN0aW9uUnVsZXMgYXMgJHJ1bGUpIHsKICAgICAgICAgICAgICAgIGlmICgkcnVsZS0+aXNDYXVzZWRCeUxvY2soJHJlcG9zaXRvcnlTZXQsICRyZXF1ZXN0LCAkcG9vbCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFN0b3JlIGEgcmVhc29uIGRlc2NyaXB0b3IgYnV0IGlnbm9yZSBkdXBsaWNhdGVzCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgIEEgY2Fub25pY2FsIGlkZW50aWZpZXIgZm9yIHRoZSByZWFzb24KICAgICAqIEBwYXJhbSBSdWxlICAgJHJlYXNvbiBUaGUgcmVhc29uIGRlc2NyaXB0b3IKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZFJlYXNvbigkaWQsIFJ1bGUgJHJlYXNvbikKICAgIHsKICAgICAgICAvLyBUT0RPOiBpZiBhIHJ1bGUgaXMgcGFydCBvZiBhIHByb2JsZW0gZGVzY3JpcHRpb24gaW4gdHdvIHNlY3Rpb25zLCBpc24ndCB0aGlzIGdvaW5nIHRvIHJlbW92ZSBhIG1lc3NhZ2UKICAgICAgICAvLyB0aGF0IGlzIGltcG9ydGFudCB0byB1bmRlcnN0YW5kIHRoZSBpc3N1ZT8KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cmVhc29uU2VlblskaWRdKSkgewogICAgICAgICAgICAkdGhpcy0+cmVhc29uU2VlblskaWRdID0gdHJ1ZTsKICAgICAgICAgICAgJHRoaXMtPnJlYXNvbnNbJHRoaXMtPnNlY3Rpb25dW10gPSAkcmVhc29uOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dFNlY3Rpb24oKQogICAgewogICAgICAgICR0aGlzLT5zZWN0aW9uKys7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRNaXNzaW5nUGFja2FnZVJlYXNvbihSZXBvc2l0b3J5U2V0ICRyZXBvc2l0b3J5U2V0LCBSZXF1ZXN0ICRyZXF1ZXN0LCBQb29sICRwb29sLCAkaXNWZXJib3NlLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50ID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBoYW5kbGUgcGhwL2hodm0KICAgICAgICBpZiAoJHBhY2thZ2VOYW1lID09PSAncGhwJyB8fCAkcGFja2FnZU5hbWUgPT09ICdwaHAtNjRiaXQnIHx8ICRwYWNrYWdlTmFtZSA9PT0gJ2hodm0nKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gcGhwdmVyc2lvbigpOwogICAgICAgICAgICAkYXZhaWxhYmxlID0gJHBvb2wtPndoYXRQcm92aWRlcygkcGFja2FnZU5hbWUpOwoKICAgICAgICAgICAgaWYgKGNvdW50KCRhdmFpbGFibGUpKSB7CiAgICAgICAgICAgICAgICAkZmlyc3RBdmFpbGFibGUgPSByZXNldCgkYXZhaWxhYmxlKTsKICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJGZpcnN0QXZhaWxhYmxlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CiAgICAgICAgICAgICAgICAkZXh0cmEgPSAkZmlyc3RBdmFpbGFibGUtPmdldEV4dHJhKCk7CiAgICAgICAgICAgICAgICBpZiAoJGZpcnN0QXZhaWxhYmxlIGluc3RhbmNlb2YgQ29tcGxldGVQYWNrYWdlSW50ZXJmYWNlICYmIGlzc2V0KCRleHRyYVsnY29uZmlnLnBsYXRmb3JtJ10pICYmICRleHRyYVsnY29uZmlnLnBsYXRmb3JtJ10gPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSAnOyAnIC4gc3RyX3JlcGxhY2UoJ1BhY2thZ2UgJywgJycsICRmaXJzdEF2YWlsYWJsZS0+Z2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtc2cgPSAiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgIi4kcGFja2FnZU5hbWUuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkuJyBidXQgJzsKCiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSB8fCAoY291bnQoJGF2YWlsYWJsZSkgJiYgJHBhY2thZ2VOYW1lID09PSAnaGh2bScpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG1zZywgJ3lvdXIgSEhWTSB2ZXJzaW9uIGRvZXMgbm90IHNhdGlzZnkgdGhhdCByZXF1aXJlbWVudC4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRwYWNrYWdlTmFtZSA9PT0gJ2hodm0nKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG1zZywgJ3lvdSBhcmUgcnVubmluZyB0aGlzIHdpdGggUEhQIGFuZCBub3QgSEhWTS4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRtc2csICd5b3VyICcuJHBhY2thZ2VOYW1lLicgdmVyc2lvbiAoJy4gJHZlcnNpb24gLicpIGRvZXMgbm90IHNhdGlzZnkgdGhhdCByZXF1aXJlbWVudC4nKTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBwaHAgZXh0ZW5zaW9ucwogICAgICAgIGlmICgwID09PSBzdHJpcG9zKCRwYWNrYWdlTmFtZSwgJ2V4dC0nKSkgewogICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkcGFja2FnZU5hbWUsICcgJykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgnLSAnLCAiUEhQIGV4dGVuc2lvbiAiLiRwYWNrYWdlTmFtZS4nIHNob3VsZCBiZSByZXF1aXJlZCBhcyAnLnN0cl9yZXBsYWNlKCcgJywgJy0nLCAkcGFja2FnZU5hbWUpLicuJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRleHQgPSBzdWJzdHIoJHBhY2thZ2VOYW1lLCA0KTsKICAgICAgICAgICAgJGVycm9yID0gZXh0ZW5zaW9uX2xvYWRlZCgkZXh0KSA/ICdpdCBoYXMgdGhlIHdyb25nIHZlcnNpb24gKCcuKHBocHZlcnNpb24oJGV4dCkgPzogJzAnKS4nKSBpbnN0YWxsZWQnIDogJ2l0IGlzIG1pc3NpbmcgZnJvbSB5b3VyIHN5c3RlbSc7CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzIFBIUCBleHRlbnNpb24gIi4kcGFja2FnZU5hbWUuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkuJyBidXQgJywgJGVycm9yLicuIEluc3RhbGwgb3IgZW5hYmxlIFBIUFwncyAnLiRleHQuJyBleHRlbnNpb24uJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgbGlua2VkIGxpYnMKICAgICAgICBpZiAoMCA9PT0gc3RyaXBvcygkcGFja2FnZU5hbWUsICdsaWItJykpIHsKICAgICAgICAgICAgaWYgKHN0cnRvbG93ZXIoJHBhY2thZ2VOYW1lKSA9PT0gJ2xpYi1pY3UnKSB7CiAgICAgICAgICAgICAgICAkZXJyb3IgPSBleHRlbnNpb25fbG9hZGVkKCdpbnRsJykgPyAnaXQgaGFzIHRoZSB3cm9uZyB2ZXJzaW9uIGluc3RhbGxlZCwgdHJ5IHVwZ3JhZGluZyB0aGUgaW50bCBleHRlbnNpb24uJyA6ICdpdCBpcyBtaXNzaW5nIGZyb20geW91ciBzeXN0ZW0sIG1ha2Ugc3VyZSB0aGUgaW50bCBleHRlbnNpb24gaXMgbG9hZGVkLic7CgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyBsaW5rZWQgbGlicmFyeSAiLiRwYWNrYWdlTmFtZS5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KS4nIGJ1dCAnLCAkZXJyb3IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzIGxpbmtlZCBsaWJyYXJ5ICIuJHBhY2thZ2VOYW1lLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpLicgYnV0ICcsICdpdCBoYXMgdGhlIHdyb25nIHZlcnNpb24gaW5zdGFsbGVkIG9yIGlzIG1pc3NpbmcgZnJvbSB5b3VyIHN5c3RlbSwgbWFrZSBzdXJlIHRvIGxvYWQgdGhlIGV4dGVuc2lvbiBwcm92aWRpbmcgaXQuJyk7CiAgICAgICAgfQoKICAgICAgICAkbG9ja2VkUGFja2FnZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHJlcXVlc3QtPmdldExvY2tlZFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5nZXROYW1lKCkgPT09ICRwYWNrYWdlTmFtZSkgewogICAgICAgICAgICAgICAgJGxvY2tlZFBhY2thZ2UgPSAkcGFja2FnZTsKICAgICAgICAgICAgICAgIGlmICgkcG9vbC0+aXNVbmFjY2VwdGFibGVGaXhlZE9yTG9ja2VkUGFja2FnZSgkcGFja2FnZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gIiwgJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKS4nIGlzIGZpeGVkIHRvICcuJHBhY2thZ2UtPmdldFByZXR0eVZlcnNpb24oKS4nIChsb2NrIGZpbGUgdmVyc2lvbikgYnkgYSBwYXJ0aWFsIHVwZGF0ZSBidXQgdGhhdCB2ZXJzaW9uIGlzIHJlamVjdGVkIGJ5IHlvdXIgbWluaW11bS1zdGFiaWxpdHkuIE1ha2Ugc3VyZSB5b3UgbGlzdCBpdCBhcyBhbiBhcmd1bWVudCBmb3IgdGhlIHVwZGF0ZSBjb21tYW5kLicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHRoZSBhY3R1YWwgcmVxdWVzdGVkIHBhY2thZ2UgaXMgZm91bmQgaW4gbm9ybWFsIGNvbmRpdGlvbnMKICAgICAgICAvLyBpZiBzbyBpdCBtdXN0IG1lYW4gaXQgaXMgcmVqZWN0ZWQgYnkgYW5vdGhlciBjb25zdHJhaW50IHRoYW4gdGhlIG9uZSBnaXZlbiBoZXJlCiAgICAgICAgaWYgKCRwYWNrYWdlcyA9ICRyZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgJHJvb3RSZXFzID0gJHJlcG9zaXRvcnlTZXQtPmdldFJvb3RSZXF1aXJlcygpOwogICAgICAgICAgICBpZiAoaXNzZXQoJHJvb3RSZXFzWyRwYWNrYWdlTmFtZV0pKSB7CiAgICAgICAgICAgICAgICAkZmlsdGVyZWQgPSBhcnJheV9maWx0ZXIoJHBhY2thZ2VzLCBmdW5jdGlvbiAoJHApIHVzZSAoJHJvb3RSZXFzLCAkcGFja2FnZU5hbWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHJvb3RSZXFzWyRwYWNrYWdlTmFtZV0tPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoJz09JywgJHAtPmdldFZlcnNpb24oKSkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gY291bnQoJGZpbHRlcmVkKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsICcsICdmb3VuZCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRwYWNrYWdlcywgJGlzVmVyYm9zZSkuJyBidXQgJy4oc2VsZjo6aGFzTXVsdGlwbGVOYW1lcygkcGFja2FnZXMpID8gJ3RoZXNlIGNvbmZsaWN0JyA6ICdpdCBjb25mbGljdHMnKS4nIHdpdGggeW91ciByb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZSAoJy4kcm9vdFJlcXNbJHBhY2thZ2VOYW1lXS0+Z2V0UHJldHR5U3RyaW5nKCkuJykuJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkbG9ja2VkUGFja2FnZSkgewogICAgICAgICAgICAgICAgJGZpeGVkQ29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCc9PScsICRsb2NrZWRQYWNrYWdlLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgJGZpbHRlcmVkID0gYXJyYXlfZmlsdGVyKCRwYWNrYWdlcywgZnVuY3Rpb24gKCRwKSB1c2UgKCRmaXhlZENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZpeGVkQ29uc3RyYWludC0+bWF0Y2hlcyhuZXcgQ29uc3RyYWludCgnPT0nLCAkcC0+Z2V0VmVyc2lvbigpKSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmICgwID09PSBjb3VudCgkZmlsdGVyZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpIC4gJywgJywgJ2ZvdW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlKS4nIGJ1dCB0aGUgcGFja2FnZSBpcyBmaXhlZCB0byAnLiRsb2NrZWRQYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCkuJyAobG9jayBmaWxlIHZlcnNpb24pIGJ5IGEgcGFydGlhbCB1cGRhdGUgYW5kIHRoYXQgdmVyc2lvbiBkb2VzIG5vdCBtYXRjaC4gTWFrZSBzdXJlIHlvdSBsaXN0IGl0IGFzIGFuIGFyZ3VtZW50IGZvciB0aGUgdXBkYXRlIGNvbW1hbmQuJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRub25Mb2NrZWRQYWNrYWdlcyA9IGFycmF5X2ZpbHRlcigkcGFja2FnZXMsIGZ1bmN0aW9uICgkcCkgewogICAgICAgICAgICAgICAgcmV0dXJuICEkcC0+Z2V0UmVwb3NpdG9yeSgpIGluc3RhbmNlb2YgTG9ja0FycmF5UmVwb3NpdG9yeTsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAoISRub25Mb2NrZWRQYWNrYWdlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpIC4gJywgJywgJ2ZvdW5kICcuc2VsZjo6Z2V0UGFja2FnZUxpc3QoJHBhY2thZ2VzLCAkaXNWZXJib3NlKS4nIGluIHRoZSBsb2NrIGZpbGUgYnV0IG5vdCBpbiByZW1vdGUgcmVwb3NpdG9yaWVzLCBtYWtlIHN1cmUgeW91IGF2b2lkIHVwZGF0aW5nIHRoaXMgcGFja2FnZSB0byBrZWVwIHRoZSBvbmUgZnJvbSB0aGUgbG9jayBmaWxlLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzICRwYWNrYWdlTmFtZSIuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkgLiAnLCAnLCAnZm91bmQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkcGFja2FnZXMsICRpc1ZlcmJvc2UpLicgYnV0IHRoZXNlIHdlcmUgbm90IGxvYWRlZCwgbGlrZWx5IGJlY2F1c2UgJy4oc2VsZjo6aGFzTXVsdGlwbGVOYW1lcygkcGFja2FnZXMpID8gJ3RoZXkgY29uZmxpY3QnIDogJ2l0IGNvbmZsaWN0cycpLicgd2l0aCBhbm90aGVyIHJlcXVpcmUuJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBpZiB0aGUgcGFja2FnZSBpcyBmb3VuZCB3aGVuIGJ5cGFzc2luZyBzdGFiaWxpdHkgY2hlY2tzCiAgICAgICAgaWYgKCRwYWNrYWdlcyA9ICRyZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCwgUmVwb3NpdG9yeVNldDo6QUxMT1dfVU5BQ0NFUFRBQkxFX1NUQUJJTElUSUVTKSkgewogICAgICAgICAgICAvLyB3ZSBtdXN0IGZpcnN0IHZlcmlmeSBpZiBhIHZhbGlkIHBhY2thZ2Ugd291bGQgYmUgZm91bmQgaW4gYSBsb3dlciBwcmlvcml0eSByZXBvc2l0b3J5CiAgICAgICAgICAgIGlmICgkYWxsUmVwb3NQYWNrYWdlcyA9ICRyZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCwgUmVwb3NpdG9yeVNldDo6QUxMT1dfU0hBRE9XRURfUkVQT1NJVE9SSUVTKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmNvbXB1dGVDaGVja0Zvckxvd2VyUHJpb1JlcG8oJGlzVmVyYm9zZSwgJHBhY2thZ2VOYW1lLCAkY29uc3RyYWludCwgJHBhY2thZ2VzLCAkYWxsUmVwb3NQYWNrYWdlcywgJ21pbmltdW0tc3RhYmlsaXR5Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsICcsICdmb3VuZCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRwYWNrYWdlcywgJGlzVmVyYm9zZSkuJyBidXQgJy4oc2VsZjo6aGFzTXVsdGlwbGVOYW1lcygkcGFja2FnZXMpID8gJ3RoZXNlIGRvJyA6ICdpdCBkb2VzJykuJyBub3QgbWF0Y2ggeW91ciBtaW5pbXVtLXN0YWJpbGl0eS4nKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGlmIHRoZSBwYWNrYWdlIGlzIGZvdW5kIHdoZW4gYnlwYXNzaW5nIHRoZSBjb25zdHJhaW50IGFuZCBzdGFiaWxpdHkgY2hlY2tzCiAgICAgICAgaWYgKCRwYWNrYWdlcyA9ICRyZXBvc2l0b3J5U2V0LT5maW5kUGFja2FnZXMoJHBhY2thZ2VOYW1lLCBudWxsLCBSZXBvc2l0b3J5U2V0OjpBTExPV19VTkFDQ0VQVEFCTEVfU1RBQklMSVRJRVMpKSB7CiAgICAgICAgICAgIC8vIHdlIG11c3QgZmlyc3QgdmVyaWZ5IGlmIGEgdmFsaWQgcGFja2FnZSB3b3VsZCBiZSBmb3VuZCBpbiBhIGxvd2VyIHByaW9yaXR5IHJlcG9zaXRvcnkKICAgICAgICAgICAgaWYgKCRhbGxSZXBvc1BhY2thZ2VzID0gJHJlcG9zaXRvcnlTZXQtPmZpbmRQYWNrYWdlcygkcGFja2FnZU5hbWUsICRjb25zdHJhaW50LCBSZXBvc2l0b3J5U2V0OjpBTExPV19TSEFET1dFRF9SRVBPU0lUT1JJRVMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6Y29tcHV0ZUNoZWNrRm9yTG93ZXJQcmlvUmVwbygkaXNWZXJib3NlLCAkcGFja2FnZU5hbWUsICRjb25zdHJhaW50LCAkcGFja2FnZXMsICRhbGxSZXBvc1BhY2thZ2VzLCAnY29uc3RyYWludCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzICRwYWNrYWdlTmFtZSIuc2VsZjo6Y29uc3RyYWludFRvVGV4dCgkY29uc3RyYWludCkgLiAnLCAnLCAnZm91bmQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkcGFja2FnZXMsICRpc1ZlcmJvc2UpLicgYnV0ICcuKHNlbGY6Omhhc011bHRpcGxlTmFtZXMoJHBhY2thZ2VzKSA/ICd0aGVzZSBkbycgOiAnaXQgZG9lcycpLicgbm90IG1hdGNoIHRoZSBjb25zdHJhaW50LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XltBLVphLXowLTlfLi8tXSskfScsICRwYWNrYWdlTmFtZSkpIHsKICAgICAgICAgICAgJGlsbGVnYWxDaGFycyA9IHByZWdfcmVwbGFjZSgne1tBLVphLXowLTlfLi8tXSt9JywgJycsICRwYWNrYWdlTmFtZSk7CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoIi0gUm9vdCBjb21wb3Nlci5qc29uIHJlcXVpcmVzICRwYWNrYWdlTmFtZSwgaXQgIiwgJ2NvdWxkIG5vdCBiZSBmb3VuZCwgaXQgbG9va3MgbGlrZSBpdHMgbmFtZSBpcyBpbnZhbGlkLCAiJy4kaWxsZWdhbENoYXJzLiciIGlzIG5vdCBhbGxvd2VkIGluIHBhY2thZ2UgbmFtZXMuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByb3ZpZGVycyA9ICRyZXBvc2l0b3J5U2V0LT5nZXRQcm92aWRlcnMoJHBhY2thZ2VOYW1lKSkgewogICAgICAgICAgICAkbWF4UHJvdmlkZXJzID0gMjA7CiAgICAgICAgICAgICRwcm92aWRlcnNTdHIgPSBpbXBsb2RlKGFycmF5X21hcChmdW5jdGlvbiAoJHApIHsKICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiA9ICRwWydkZXNjcmlwdGlvbiddID8gJyAnLnN1YnN0cigkcFsnZGVzY3JpcHRpb24nXSwgMCwgMTAwKSA6ICcnOwoKICAgICAgICAgICAgICAgIHJldHVybiAiICAgICAgLSAke3BbJ25hbWUnXX0iLiRkZXNjcmlwdGlvbi4iXG4iOwogICAgICAgICAgICB9LCBjb3VudCgkcHJvdmlkZXJzKSA+ICRtYXhQcm92aWRlcnMgKyAxID8gYXJyYXlfc2xpY2UoJHByb3ZpZGVycywgMCwgJG1heFByb3ZpZGVycykgOiAkcHJvdmlkZXJzKSk7CiAgICAgICAgICAgIGlmIChjb3VudCgkcHJvdmlkZXJzKSA+ICRtYXhQcm92aWRlcnMgKyAxKSB7CiAgICAgICAgICAgICAgICAkcHJvdmlkZXJzU3RyIC49ICcgICAgICAuLi4gYW5kICcuKGNvdW50KCRwcm92aWRlcnMpIC0gJG1heFByb3ZpZGVycykuJyBtb3JlLicuIlxuIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUiLnNlbGY6OmNvbnN0cmFpbnRUb1RleHQoJGNvbnN0cmFpbnQpLiIsIGl0ICIsICJjb3VsZCBub3QgYmUgZm91bmQgaW4gYW55IHZlcnNpb24sIGJ1dCB0aGUgZm9sbG93aW5nIHBhY2thZ2VzIHByb3ZpZGUgaXQ6XG4iLiRwcm92aWRlcnNTdHIuIiAgICAgIENvbnNpZGVyIHJlcXVpcmluZyBvbmUgb2YgdGhlc2UgdG8gc2F0aXNmeSB0aGUgJHBhY2thZ2VOYW1lIHJlcXVpcmVtZW50LiIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFycmF5KCItIFJvb3QgY29tcG9zZXIuanNvbiByZXF1aXJlcyAkcGFja2FnZU5hbWUsIGl0ICIsICJjb3VsZCBub3QgYmUgZm91bmQgaW4gYW55IHZlcnNpb24sIHRoZXJlIG1heSBiZSBhIHR5cG8gaW4gdGhlIHBhY2thZ2UgbmFtZS4iKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBhY2thZ2VMaXN0KGFycmF5ICRwYWNrYWdlcywgJGlzVmVyYm9zZSkKICAgIHsKICAgICAgICAkcHJlcGFyZWQgPSBhcnJheSgpOwogICAgICAgICRoYXNEZWZhdWx0QnJhbmNoID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFja2FnZXMgYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgJHByZXBhcmVkWyRwYWNrYWdlLT5nZXROYW1lKCldWyduYW1lJ10gPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwogICAgICAgICAgICAkcHJlcGFyZWRbJHBhY2thZ2UtPmdldE5hbWUoKV1bJ3ZlcnNpb25zJ11bJHBhY2thZ2UtPmdldFZlcnNpb24oKV0gPSAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpLigkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSA/ICcgKGFsaWFzIG9mICcuJHBhY2thZ2UtPmdldEFsaWFzT2YoKS0+Z2V0UHJldHR5VmVyc2lvbigpLicpJyA6ICcnKTsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlLT5pc0RlZmF1bHRCcmFuY2goKSkgewogICAgICAgICAgICAgICAgJGhhc0RlZmF1bHRCcmFuY2hbJHBhY2thZ2UtPmdldE5hbWUoKV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRwcmVwYXJlZCBhcyAkbmFtZSA9PiAkcGFja2FnZSkgewogICAgICAgICAgICAvLyByZW1vdmUgdGhlIGltcGxpY2l0IGRlZmF1bHQgYnJhbmNoIGFsaWFzIHRvIGF2b2lkIGNydWZ0IGluIHRoZSBkaXNwbGF5CiAgICAgICAgICAgIGlmIChpc3NldCgkcGFja2FnZVsndmVyc2lvbnMnXVtWZXJzaW9uUGFyc2VyOjpERUZBVUxUX0JSQU5DSF9BTElBU10sICRoYXNEZWZhdWx0QnJhbmNoWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRwYWNrYWdlWyd2ZXJzaW9ucyddW1ZlcnNpb25QYXJzZXI6OkRFRkFVTFRfQlJBTkNIX0FMSUFTXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVrc29ydCgkcGFja2FnZVsndmVyc2lvbnMnXSwgJ3ZlcnNpb25fY29tcGFyZScpOwoKICAgICAgICAgICAgaWYgKCEkaXNWZXJib3NlKSB7CiAgICAgICAgICAgICAgICAkcGFja2FnZVsndmVyc2lvbnMnXSA9IHNlbGY6OmNvbmRlbnNlVmVyc2lvbkxpc3QoJHBhY2thZ2VbJ3ZlcnNpb25zJ10sIDQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwcmVwYXJlZFskbmFtZV0gPSAkcGFja2FnZVsnbmFtZSddLidbJy5pbXBsb2RlKCcsICcsICRwYWNrYWdlWyd2ZXJzaW9ucyddKS4nXSc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaW1wbG9kZSgnLCAnLCAkcHJlcGFyZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmdbXSAgICAgJHZlcnNpb25zIGFuIGFycmF5IG9mIHByZXR0eSB2ZXJzaW9ucywgd2l0aCBub3JtYWxpemVkIHZlcnNpb25zIGFzIGtleXMKICAgICAqIEByZXR1cm4gbGlzdDxzdHJpbmc+IGEgbGlzdCBvZiBwcmV0dHkgdmVyc2lvbnMgYW5kICcuLi4nIHdoZXJlIHZlcnNpb25zIHdlcmUgcmVtb3ZlZAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb25kZW5zZVZlcnNpb25MaXN0KGFycmF5ICR2ZXJzaW9ucywgJG1heCkKICAgIHsKICAgICAgICBpZiAoY291bnQoJHZlcnNpb25zKSA8PSAkbWF4KSB7CiAgICAgICAgICAgIHJldHVybiAkdmVyc2lvbnM7CiAgICAgICAgfQoKICAgICAgICAkZmlsdGVyZWQgPSBhcnJheSgpOwogICAgICAgICRieU1ham9yID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24gPT4gJHByZXR0eSkgewogICAgICAgICAgICAkYnlNYWpvcltwcmVnX3JlcGxhY2UoJ3teKFxkKylcLi4qfScsICckMScsICR2ZXJzaW9uKV1bXSA9ICRwcmV0dHk7CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRieU1ham9yIGFzICR2ZXJzaW9uc0Zvck1ham9yKSB7CiAgICAgICAgICAgIGlmIChjb3VudCgkdmVyc2lvbnNGb3JNYWpvcikgPiAkbWF4KSB7CiAgICAgICAgICAgICAgICAkZmlsdGVyZWRbXSA9ICR2ZXJzaW9uc0Zvck1ham9yWzBdOwogICAgICAgICAgICAgICAgJGZpbHRlcmVkW10gPSAnLi4uJzsKICAgICAgICAgICAgICAgICRmaWx0ZXJlZFtdID0gJHZlcnNpb25zRm9yTWFqb3JbY291bnQoJHZlcnNpb25zRm9yTWFqb3IpIC0gMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZmlsdGVyZWQgPSBhcnJheV9tZXJnZSgkZmlsdGVyZWQsICR2ZXJzaW9uc0Zvck1ham9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmaWx0ZXJlZDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBoYXNNdWx0aXBsZU5hbWVzKGFycmF5ICRwYWNrYWdlcykKICAgIHsKICAgICAgICAkbmFtZSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHBhY2thZ2VzIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkbmFtZSA9PT0gbnVsbCB8fCAkbmFtZSA9PT0gJHBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAkcGFja2FnZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjb21wdXRlQ2hlY2tGb3JMb3dlclByaW9SZXBvKCRpc1ZlcmJvc2UsICRwYWNrYWdlTmFtZSwgJGNvbnN0cmFpbnQsIGFycmF5ICRoaWdoZXJSZXBvUGFja2FnZXMsIGFycmF5ICRhbGxSZXBvc1BhY2thZ2VzLCAkcmVhc29uKQogICAgewogICAgICAgICRuZXh0UmVwb1BhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICAkbmV4dFJlcG8gPSBudWxsOwoKICAgICAgICBmb3JlYWNoICgkYWxsUmVwb3NQYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBpZiAoJG5leHRSZXBvID09PSBudWxsIHx8ICRuZXh0UmVwbyA9PT0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKSkgewogICAgICAgICAgICAgICAgJG5leHRSZXBvUGFja2FnZXNbXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgJG5leHRSZXBvID0gJHBhY2thZ2UtPmdldFJlcG9zaXRvcnkoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJG5leHRSZXBvIGluc3RhbmNlb2YgTG9ja0FycmF5UmVwb3NpdG9yeSkgewogICAgICAgICAgICAkc2luZ3VsYXIgPSBjb3VudCgkaGlnaGVyUmVwb1BhY2thZ2VzKSA9PT0gMTsKCiAgICAgICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsIGl0IGlzICcsCiAgICAgICAgICAgICAgICAnZm91bmQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkbmV4dFJlcG9QYWNrYWdlcywgJGlzVmVyYm9zZSkuJyBpbiB0aGUgbG9jayBmaWxlIGFuZCAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRoaWdoZXJSZXBvUGFja2FnZXMsICRpc1ZlcmJvc2UpLicgZnJvbSAnLnJlc2V0KCRoaWdoZXJSZXBvUGFja2FnZXMpLT5nZXRSZXBvc2l0b3J5KCktPmdldFJlcG9OYW1lKCkuJyBidXQgJyAuICgkc2luZ3VsYXIgPyAnaXQgZG9lcycgOiAndGhlc2UgZG8nKSAuICcgbm90IG1hdGNoIHlvdXIgJy4kcmVhc29uLicgYW5kICcgLiAoJHNpbmd1bGFyID8gJ2lzJyA6ICdhcmUnKSAuICcgdGhlcmVmb3JlIG5vdCBpbnN0YWxsYWJsZS4gTWFrZSBzdXJlIHlvdSBlaXRoZXIgZml4IHRoZSAnLiRyZWFzb24uJyBvciBhdm9pZCB1cGRhdGluZyB0aGlzIHBhY2thZ2UgdG8ga2VlcCB0aGUgb25lIGZyb20gdGhlIGxvY2sgZmlsZS4nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgiLSBSb290IGNvbXBvc2VyLmpzb24gcmVxdWlyZXMgJHBhY2thZ2VOYW1lIi5zZWxmOjpjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KSAuICcsIGl0IGlzICcsICdzYXRpc2ZpYWJsZSBieSAnLnNlbGY6OmdldFBhY2thZ2VMaXN0KCRuZXh0UmVwb1BhY2thZ2VzLCAkaXNWZXJib3NlKS4nIGZyb20gJy4kbmV4dFJlcG8tPmdldFJlcG9OYW1lKCkuJyBidXQgJy5zZWxmOjpnZXRQYWNrYWdlTGlzdCgkaGlnaGVyUmVwb1BhY2thZ2VzLCAkaXNWZXJib3NlKS4nIGZyb20gJy5yZXNldCgkaGlnaGVyUmVwb1BhY2thZ2VzKS0+Z2V0UmVwb3NpdG9yeSgpLT5nZXRSZXBvTmFtZSgpLicgaGFzIGhpZ2hlciByZXBvc2l0b3J5IHByaW9yaXR5LiBUaGUgcGFja2FnZXMgd2l0aCBoaWdoZXIgcHJpb3JpdHkgZG8gbm90IG1hdGNoIHlvdXIgJy4kcmVhc29uLicgYW5kIGFyZSB0aGVyZWZvcmUgbm90IGluc3RhbGxhYmxlLiBTZWUgaHR0cHM6Ly9nZXRjb21wb3Nlci5vcmcvcmVwb3ByaW8gZm9yIGRldGFpbHMgYW5kIGFzc2lzdGFuY2UuJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBhIGNvbnN0cmFpbnQgaW50byB0ZXh0IHVzYWJsZSBpbiBhIHNlbnRlbmNlIGRlc2NyaWJpbmcgYSByZXF1ZXN0CiAgICAgKgogICAgICogQHBhcmFtICBcQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb25zdHJhaW50VG9UZXh0KCRjb25zdHJhaW50KQogICAgewogICAgICAgIHJldHVybiAkY29uc3RyYWludCA/ICcgJy4kY29uc3RyYWludC0+Z2V0UHJldHR5U3RyaW5nKCkgOiAnJzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7Cgp1c2UgQ29tcG9zZXJcUGFja2FnZVxQYWNrYWdlSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxMaW5rOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBHZW5lcmljUnVsZSBleHRlbmRzIFJ1bGUKewogICAgcHJvdGVjdGVkICRsaXRlcmFsczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICAgICAgICAgICAgJGxpdGVyYWxzCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICAgICAgICAgICAgICAgICRyZWFzb24gICAgIEEgUlVMRV8qIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIHJlYXNvbiBmb3IgZ2VuZXJhdGluZyB0aGlzIHJ1bGUKICAgICAqIEBwYXJhbSBMaW5rfFBhY2thZ2VJbnRlcmZhY2V8aW50fG51bGwgJHJlYXNvbkRhdGEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRsaXRlcmFscywgJHJlYXNvbiwgJHJlYXNvbkRhdGEpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcmVhc29uLCAkcmVhc29uRGF0YSk7CgogICAgICAgIC8vIHNvcnQgYWxsIHBhY2thZ2VzIGFzY2VuZGluZyBieSBpZAogICAgICAgIHNvcnQoJGxpdGVyYWxzKTsKCiAgICAgICAgJHRoaXMtPmxpdGVyYWxzID0gJGxpdGVyYWxzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaXRlcmFscygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5saXRlcmFsczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFzaCgpCiAgICB7CiAgICAgICAgJGRhdGEgPSB1bnBhY2soJ2loYXNoJywgbWQ1KGltcGxvZGUoJywnLCAkdGhpcy0+bGl0ZXJhbHMpLCB0cnVlKSk7CgogICAgICAgIHJldHVybiAkZGF0YVsnaGFzaCddOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoaXMgcnVsZSBpcyBlcXVhbCB0byBhbm90aGVyIG9uZQogICAgICoKICAgICAqIElnbm9yZXMgd2hldGhlciBlaXRoZXIgb2YgdGhlIHJ1bGVzIGlzIGRpc2FibGVkLgogICAgICoKICAgICAqIEBwYXJhbSAgUnVsZSAkcnVsZSBUaGUgcnVsZSB0byBjaGVjayBhZ2FpbnN0CiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgcnVsZXMgYXJlIGVxdWFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcXVhbHMoUnVsZSAkcnVsZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxpdGVyYWxzID09PSAkcnVsZS0+Z2V0TGl0ZXJhbHMoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBc3NlcnRpb24oKQogICAgewogICAgICAgIHJldHVybiAxID09PSBcY291bnQoJHRoaXMtPmxpdGVyYWxzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBydWxlIGFzIGEgc3RyaW5nIG9mIHRoZSBmb3JtYXQgKExpdGVyYWwxfExpdGVyYWwyfC4uLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5pc0Rpc2FibGVkKCkgPyAnZGlzYWJsZWQoJyA6ICcoJzsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmxpdGVyYWxzIGFzICRpID0+ICRsaXRlcmFsKSB7CiAgICAgICAgICAgIGlmICgkaSAhPSAwKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICd8JzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVzdWx0IC49ICRsaXRlcmFsOwogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCAuPSAnKSc7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlcjsKCnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQ7CgovKioKICogQGF1dGhvciBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICovCmNsYXNzIFJ1bGVTZXQgaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGUsIFxDb3VudGFibGUKewogICAgLy8gaGlnaGVzdCBwcmlvcml0eSA9PiBsb3dlc3QgbnVtYmVyCiAgICBjb25zdCBUWVBFX1BBQ0tBR0UgPSAwOwogICAgY29uc3QgVFlQRV9SRVFVRVNUID0gMTsKICAgIGNvbnN0IFRZUEVfTEVBUk5FRCA9IDQ7CgogICAgLyoqCiAgICAgKiBSRUFELU9OTFk6IExvb2t1cCB0YWJsZSBmb3IgcnVsZSBpZCB0byBydWxlIG9iamVjdAogICAgICoKICAgICAqIEB2YXIgUnVsZVtdCiAgICAgKi8KICAgIHB1YmxpYyAkcnVsZUJ5SWQ7CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkdHlwZXMgPSBhcnJheSgKICAgICAgICAyNTUgPT4gJ1VOS05PV04nLAogICAgICAgIHNlbGY6OlRZUEVfUEFDS0FHRSA9PiAnUEFDS0FHRScsCiAgICAgICAgc2VsZjo6VFlQRV9SRVFVRVNUID0+ICdSRVFVRVNUJywKICAgICAgICBzZWxmOjpUWVBFX0xFQVJORUQgPT4gJ0xFQVJORUQnLAogICAgKTsKCiAgICBwcm90ZWN0ZWQgJHJ1bGVzOwogICAgcHJvdGVjdGVkICRuZXh0UnVsZUlkOwoKICAgIHByb3RlY3RlZCAkcnVsZXNCeUhhc2g7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+bmV4dFJ1bGVJZCA9IDA7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXRUeXBlcygpIGFzICR0eXBlKSB7CiAgICAgICAgICAgICR0aGlzLT5ydWxlc1skdHlwZV0gPSBhcnJheSgpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJ1bGVzQnlIYXNoID0gYXJyYXkoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkKFJ1bGUgJHJ1bGUsICR0eXBlKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JHR5cGVzWyR0eXBlXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxPdXRPZkJvdW5kc0V4Y2VwdGlvbignVW5rbm93biBydWxlIHR5cGU6ICcgLiAkdHlwZSk7CiAgICAgICAgfQoKICAgICAgICAkaGFzaCA9ICRydWxlLT5nZXRIYXNoKCk7CgogICAgICAgIC8vIERvIG5vdCBhZGQgaWYgcnVsZSBhbHJlYWR5IGV4aXN0cwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cnVsZXNCeUhhc2hbJGhhc2hdKSkgewogICAgICAgICAgICAkcG90ZW50aWFsRHVwbGljYXRlcyA9ICR0aGlzLT5ydWxlc0J5SGFzaFskaGFzaF07CiAgICAgICAgICAgIGlmIChcaXNfYXJyYXkoJHBvdGVudGlhbER1cGxpY2F0ZXMpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcG90ZW50aWFsRHVwbGljYXRlcyBhcyAkcG90ZW50aWFsRHVwbGljYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRydWxlLT5lcXVhbHMoJHBvdGVudGlhbER1cGxpY2F0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgkcnVsZS0+ZXF1YWxzKCRwb3RlbnRpYWxEdXBsaWNhdGVzKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+cnVsZXNbJHR5cGVdKSkgewogICAgICAgICAgICAkdGhpcy0+cnVsZXNbJHR5cGVdID0gYXJyYXkoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5ydWxlc1skdHlwZV1bXSA9ICRydWxlOwogICAgICAgICR0aGlzLT5ydWxlQnlJZFskdGhpcy0+bmV4dFJ1bGVJZF0gPSAkcnVsZTsKICAgICAgICAkcnVsZS0+c2V0VHlwZSgkdHlwZSk7CgogICAgICAgICR0aGlzLT5uZXh0UnVsZUlkKys7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXSA9ICRydWxlOwogICAgICAgIH0gZWxzZWlmIChcaXNfYXJyYXkoJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXSkpIHsKICAgICAgICAgICAgJHRoaXMtPnJ1bGVzQnlIYXNoWyRoYXNoXVtdID0gJHJ1bGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJG9yaWdpbmFsUnVsZSA9ICR0aGlzLT5ydWxlc0J5SGFzaFskaGFzaF07CiAgICAgICAgICAgICR0aGlzLT5ydWxlc0J5SGFzaFskaGFzaF0gPSBhcnJheSgkb3JpZ2luYWxSdWxlLCAkcnVsZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uZXh0UnVsZUlkOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBydWxlQnlJZCgkaWQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlQnlJZFskaWRdOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSdWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ydWxlczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiBuZXcgUnVsZVNldEl0ZXJhdG9yKCR0aGlzLT5nZXRSdWxlcygpKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3JGb3IoJHR5cGVzKQogICAgewogICAgICAgIGlmICghXGlzX2FycmF5KCR0eXBlcykpIHsKICAgICAgICAgICAgJHR5cGVzID0gYXJyYXkoJHR5cGVzKTsKICAgICAgICB9CgogICAgICAgICRhbGxSdWxlcyA9ICR0aGlzLT5nZXRSdWxlcygpOwogICAgICAgICRydWxlcyA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCR0eXBlcyBhcyAkdHlwZSkgewogICAgICAgICAgICAkcnVsZXNbJHR5cGVdID0gJGFsbFJ1bGVzWyR0eXBlXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUnVsZVNldEl0ZXJhdG9yKCRydWxlcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yV2l0aG91dCgkdHlwZXMpCiAgICB7CiAgICAgICAgaWYgKCFcaXNfYXJyYXkoJHR5cGVzKSkgewogICAgICAgICAgICAkdHlwZXMgPSBhcnJheSgkdHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgJHJ1bGVzID0gJHRoaXMtPmdldFJ1bGVzKCk7CgogICAgICAgIGZvcmVhY2ggKCR0eXBlcyBhcyAkdHlwZSkgewogICAgICAgICAgICB1bnNldCgkcnVsZXNbJHR5cGVdKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUnVsZVNldEl0ZXJhdG9yKCRydWxlcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGVzKCkKICAgIHsKICAgICAgICAkdHlwZXMgPSBzZWxmOjokdHlwZXM7CiAgICAgICAgdW5zZXQoJHR5cGVzWzI1NV0pOwoKICAgICAgICByZXR1cm4gYXJyYXlfa2V5cygkdHlwZXMpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoUmVwb3NpdG9yeVNldCAkcmVwb3NpdG9yeVNldCA9IG51bGwsIFJlcXVlc3QgJHJlcXVlc3QgPSBudWxsLCBQb29sICRwb29sID0gbnVsbCwgJGlzVmVyYm9zZSA9IGZhbHNlKQogICAgewogICAgICAgICRzdHJpbmcgPSAiXG4iOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ydWxlcyBhcyAkdHlwZSA9PiAkcnVsZXMpIHsKICAgICAgICAgICAgJHN0cmluZyAuPSBzdHJfcGFkKHNlbGY6OiR0eXBlc1skdHlwZV0sIDgsICcgJykgLiAiOiAiOwogICAgICAgICAgICBmb3JlYWNoICgkcnVsZXMgYXMgJHJ1bGUpIHsKICAgICAgICAgICAgICAgICRzdHJpbmcgLj0gKCRyZXBvc2l0b3J5U2V0ICYmICRyZXF1ZXN0ICYmICRwb29sID8gJHJ1bGUtPmdldFByZXR0eVN0cmluZygkcmVwb3NpdG9yeVNldCwgJHJlcXVlc3QsICRwb29sLCAkaXNWZXJib3NlKSA6ICRydWxlKS4iXG4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzdHJpbmcgLj0gIlxuXG4iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzdHJpbmc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UHJldHR5U3RyaW5nKCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKLyoqCiAqIFdyYXBwZXIgYXJvdW5kIGEgUnVsZSB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgdHdvIGxpdGVyYWxzIGl0IHdhdGNoZXMKICoKICogVXNlZCBieSBSdWxlV2F0Y2hHcmFwaCB0byBzdG9yZSBydWxlcyBpbiB0d28gUnVsZVdhdGNoQ2hhaW5zLgogKgogKiBAYXV0aG9yIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKi8KY2xhc3MgUnVsZVdhdGNoTm9kZQp7CiAgICBwdWJsaWMgJHdhdGNoMTsKICAgIHB1YmxpYyAkd2F0Y2gyOwoKICAgIHByb3RlY3RlZCAkcnVsZTsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgbm9kZSB3YXRjaGluZyB0aGUgZmlyc3QgYW5kIHNlY29uZCBsaXRlcmFscyBvZiB0aGUgcnVsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gUnVsZSAkcnVsZSBUaGUgcnVsZSB0byB3cmFwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcnVsZSkKICAgIHsKICAgICAgICAkdGhpcy0+cnVsZSA9ICRydWxlOwoKICAgICAgICAkbGl0ZXJhbHMgPSAkcnVsZS0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgJGxpdGVyYWxDb3VudCA9IFxjb3VudCgkbGl0ZXJhbHMpOwogICAgICAgICR0aGlzLT53YXRjaDEgPSAkbGl0ZXJhbENvdW50ID4gMCA/ICRsaXRlcmFsc1swXSA6IDA7CiAgICAgICAgJHRoaXMtPndhdGNoMiA9ICRsaXRlcmFsQ291bnQgPiAxID8gJGxpdGVyYWxzWzFdIDogMDsKICAgIH0KCiAgICAvKioKICAgICAqIFBsYWNlcyB0aGUgc2Vjb25kIHdhdGNoIG9uIHRoZSBydWxlJ3MgbGl0ZXJhbCwgZGVjaWRlZCBhdCB0aGUgaGlnaGVzdCBsZXZlbAogICAgICoKICAgICAqIFVzZWZ1bCBmb3IgbGVhcm5lZCBydWxlcyB3aGVyZSB0aGUgbGl0ZXJhbCBmb3IgdGhlIGhpZ2hlc3QgcnVsZSBpcyBtb3N0CiAgICAgKiBsaWtlbHkgdG8gcXVpY2tseSBsZWFkIHRvIGZ1cnRoZXIgZGVjaXNpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBEZWNpc2lvbnMgJGRlY2lzaW9ucyBUaGUgZGVjaXNpb25zIG1hZGUgc28gZmFyIGJ5IHRoZSBzb2x2ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhdGNoMk9uSGlnaGVzdChEZWNpc2lvbnMgJGRlY2lzaW9ucykKICAgIHsKICAgICAgICAkbGl0ZXJhbHMgPSAkdGhpcy0+cnVsZS0+Z2V0TGl0ZXJhbHMoKTsKCiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIG9ubHkgMiBlbGVtZW50cywgYm90aCBhcmUgYmVpbmcgd2F0Y2hlZCBhbnl3YXkKICAgICAgICBpZiAoXGNvdW50KCRsaXRlcmFscykgPCAzIHx8ICR0aGlzLT5ydWxlIGluc3RhbmNlb2YgTXVsdGlDb25mbGljdFJ1bGUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHdhdGNoTGV2ZWwgPSAwOwoKICAgICAgICBmb3JlYWNoICgkbGl0ZXJhbHMgYXMgJGxpdGVyYWwpIHsKICAgICAgICAgICAgJGxldmVsID0gJGRlY2lzaW9ucy0+ZGVjaXNpb25MZXZlbCgkbGl0ZXJhbCk7CgogICAgICAgICAgICBpZiAoJGxldmVsID4gJHdhdGNoTGV2ZWwpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53YXRjaDIgPSAkbGl0ZXJhbDsKICAgICAgICAgICAgICAgICR3YXRjaExldmVsID0gJGxldmVsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcnVsZSB0aGlzIG5vZGUgd3JhcHMKICAgICAqCiAgICAgKiBAcmV0dXJuIFJ1bGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJ1bGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cnVsZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdpdmVuIG9uZSB3YXRjaGVkIGxpdGVyYWwsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG90aGVyIHdhdGNoZWQgbGl0ZXJhbAogICAgICoKICAgICAqIEBwYXJhbSAgaW50ICRsaXRlcmFsIFRoZSB3YXRjaGVkIGxpdGVyYWwgdGhhdCBzaG91bGQgbm90IGJlIHJldHVybmVkCiAgICAgKiBAcmV0dXJuIGludCBBIGxpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE90aGVyV2F0Y2goJGxpdGVyYWwpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT53YXRjaDEgPT0gJGxpdGVyYWwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT53YXRjaDI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPndhdGNoMTsKICAgIH0KCiAgICAvKioKICAgICAqIE1vdmVzIGEgd2F0Y2ggZnJvbSBvbmUgbGl0ZXJhbCB0byBhbm90aGVyCiAgICAgKgogICAgICogQHBhcmFtIGludCAkZnJvbSBUaGUgcHJldmlvdXNseSB3YXRjaGVkIGxpdGVyYWwKICAgICAqIEBwYXJhbSBpbnQgJHRvICAgVGhlIGxpdGVyYWwgdG8gYmUgd2F0Y2hlZCBub3cKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1vdmVXYXRjaCgkZnJvbSwgJHRvKQogICAgewogICAgICAgIGlmICgkdGhpcy0+d2F0Y2gxID09ICRmcm9tKSB7CiAgICAgICAgICAgICR0aGlzLT53YXRjaDEgPSAkdG87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPndhdGNoMiA9ICR0bzsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIENvbXBvc2VyLgogKgogKiAoYykgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqICAgICBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcRGVwZW5kZW5jeVJlc29sdmVyOwoKdXNlIENvbXBvc2VyXFBhY2thZ2VcQWxpYXNQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxSb290QWxpYXNQYWNrYWdlOwoKLyoqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgTG9ja1RyYW5zYWN0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb24KewogICAgLyoqCiAgICAgKiBwYWNrYWdlcyBpbiBjdXJyZW50IGxvY2sgZmlsZSwgcGxhdGZvcm0gcmVwbyBvciBvdGhlcndpc2UgcHJlc2VudAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHByZXNlbnRNYXA7CgogICAgLyoqCiAgICAgKiBQYWNrYWdlcyB3aGljaCBjYW5ub3QgYmUgbWFwcGVkLCBwbGF0Zm9ybSByZXBvLCByb290IHBhY2thZ2UsIG90aGVyIGZpeGVkIHJlcG9zCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkdW5sb2NrYWJsZU1hcDsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRyZXN1bHRQYWNrYWdlczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUG9vbCAkcG9vbCwgJHByZXNlbnRNYXAsICR1bmxvY2thYmxlTWFwLCAkZGVjaXNpb25zKQogICAgewogICAgICAgICR0aGlzLT5wcmVzZW50TWFwID0gJHByZXNlbnRNYXA7CiAgICAgICAgJHRoaXMtPnVubG9ja2FibGVNYXAgPSAkdW5sb2NrYWJsZU1hcDsKCiAgICAgICAgJHRoaXMtPnNldFJlc3VsdFBhY2thZ2VzKCRwb29sLCAkZGVjaXNpb25zKTsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCR0aGlzLT5wcmVzZW50TWFwLCAkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ2FsbCddKTsKICAgIH0KCiAgICAvLyBUT0RPIG1ha2UgdGhpcyBhIGJpdCBwcmV0dGllciBpbnN0ZWFkIG9mIHRoZSB0d28gdGV4dCBpbmRleGVzPwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlc3VsdFBhY2thZ2VzKFBvb2wgJHBvb2wsIERlY2lzaW9ucyAkZGVjaXNpb25zKQogICAgewogICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlcyA9IGFycmF5KCdhbGwnID0+IGFycmF5KCksICdub24tZGV2JyA9PiBhcnJheSgpLCAnZGV2JyA9PiBhcnJheSgpKTsKICAgICAgICBmb3JlYWNoICgkZGVjaXNpb25zIGFzICRpID0+ICRkZWNpc2lvbikgewogICAgICAgICAgICAkbGl0ZXJhbCA9ICRkZWNpc2lvbltEZWNpc2lvbnM6OkRFQ0lTSU9OX0xJVEVSQUxdOwoKICAgICAgICAgICAgaWYgKCRsaXRlcmFsID4gMCkgewogICAgICAgICAgICAgICAgJHBhY2thZ2UgPSAkcG9vbC0+bGl0ZXJhbFRvUGFja2FnZSgkbGl0ZXJhbCk7CgogICAgICAgICAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydhbGwnXVtdID0gJHBhY2thZ2U7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT51bmxvY2thYmxlTWFwWyRwYWNrYWdlLT5pZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydub24tZGV2J11bXSA9ICRwYWNrYWdlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROb25EZXZQYWNrYWdlcyhMb2NrVHJhbnNhY3Rpb24gJGV4dHJhY3Rpb25SZXN1bHQpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gJGV4dHJhY3Rpb25SZXN1bHQtPmdldE5ld0xvY2tQYWNrYWdlcyhmYWxzZSk7CgogICAgICAgICR0aGlzLT5yZXN1bHRQYWNrYWdlc1snZGV2J10gPSAkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ25vbi1kZXYnXTsKICAgICAgICAkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ25vbi1kZXYnXSA9IGFycmF5KCk7CgogICAgICAgIGZvcmVhY2ggKCRwYWNrYWdlcyBhcyAkcGFja2FnZSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ2RldiddIGFzICRpID0+ICRyZXN1bHRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAvLyBUT0RPIHRoaXMgY29tcGFyaXNvbiBpcyBwcm9iYWJseSBpbnN1ZmZpY2llbnQsIGFsaWFzZXMsIHdoYXQgYWJvdXQgbW9kaWZpZWQgdmVyc2lvbnM/IEkgZ3Vlc3MgdGhleSBhcmVuJ3QgcG9zc2libGU/CiAgICAgICAgICAgICAgICBpZiAoJHBhY2thZ2UtPmdldE5hbWUoKSA9PSAkcmVzdWx0UGFja2FnZS0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlc3VsdFBhY2thZ2VzWydub24tZGV2J11bXSA9ICRyZXN1bHRQYWNrYWdlOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5yZXN1bHRQYWNrYWdlc1snZGV2J11bJGldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBUT0RPIGFkZGl0aW9uYWxGaXhlZFJlcG9zaXRvcnkgbmVlZHMgdG8gYmUgbG9va2VkIGF0IGhlcmUgYXMgd2VsbD8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROZXdMb2NrUGFja2FnZXMoJGRldk1vZGUsICR1cGRhdGVNaXJyb3JzID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHBhY2thZ2VzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZXNbJGRldk1vZGUgPyAnZGV2JyA6ICdub24tZGV2J10gYXMgJHBhY2thZ2UpIHsKICAgICAgICAgICAgaWYgKCEoJHBhY2thZ2UgaW5zdGFuY2VvZiBBbGlhc1BhY2thZ2UpICYmICEoJHBhY2thZ2UgaW5zdGFuY2VvZiBSb290QWxpYXNQYWNrYWdlKSkgewogICAgICAgICAgICAgICAgLy8gaWYgd2UncmUganVzdCB1cGRhdGluZyBtaXJyb3JzIHdlIG5lZWQgdG8gcmVzZXQgcmVmZXJlbmNlcyB0byB0aGUgc2FtZSBhcyBjdXJyZW50bHkgInByZXNlbnQiIHBhY2thZ2VzJyByZWZlcmVuY2VzIHRvIGtlZXAgdGhlIGxvY2sgZmlsZSBhcy1pcwogICAgICAgICAgICAgICAgLy8gd2UgZG8gbm90IHJlc2V0IHJlZmVyZW5jZXMgaWYgdGhlIGN1cnJlbnRseSBwcmVzZW50IHBhY2thZ2UgZGlkbid0IGhhdmUgYW55LCBvciBpZiB0aGUgdHlwZSBvZiBWQ1MgaGFzIGNoYW5nZWQKICAgICAgICAgICAgICAgIGlmICgkdXBkYXRlTWlycm9ycyAmJiAhaXNzZXQoJHRoaXMtPnByZXNlbnRNYXBbc3BsX29iamVjdF9oYXNoKCRwYWNrYWdlKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByZXNlbnRNYXAgYXMgJHByZXNlbnRQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcGFja2FnZS0+Z2V0TmFtZSgpID09ICRwcmVzZW50UGFja2FnZS0+Z2V0TmFtZSgpICYmICRwYWNrYWdlLT5nZXRWZXJzaW9uKCkgPT0gJHByZXNlbnRQYWNrYWdlLT5nZXRWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkcHJlc2VudFBhY2thZ2UtPmdldFNvdXJjZVJlZmVyZW5jZSgpICYmICRwcmVzZW50UGFja2FnZS0+Z2V0U291cmNlVHlwZSgpID09PSAkcGFja2FnZS0+Z2V0U291cmNlVHlwZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhY2thZ2UtPnNldFNvdXJjZURpc3RSZWZlcmVuY2VzKCRwcmVzZW50UGFja2FnZS0+Z2V0U291cmNlUmVmZXJlbmNlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRwcmVzZW50UGFja2FnZS0+Z2V0UmVsZWFzZURhdGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYWNrYWdlLT5zZXRSZWxlYXNlRGF0ZSgkcHJlc2VudFBhY2thZ2UtPmdldFJlbGVhc2VEYXRlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhY2thZ2VzW10gPSAkcGFja2FnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYWNrYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGljaCBvZiB0aGUgZ2l2ZW4gYWxpYXNlcyBmcm9tIGNvbXBvc2VyLmpzb24gYXJlIGFjdHVhbGx5IGluIHVzZSBmb3IgdGhlIGxvY2sgZmlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygkYWxpYXNlcykKICAgIHsKICAgICAgICAkdXNlZEFsaWFzZXMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cmVzdWx0UGFja2FnZXNbJ2FsbCddIGFzICRwYWNrYWdlKSB7CiAgICAgICAgICAgIGlmICgkcGFja2FnZSBpbnN0YW5jZW9mIEFsaWFzUGFja2FnZSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGFsaWFzZXMgYXMgJGluZGV4ID0+ICRhbGlhcykgewogICAgICAgICAgICAgICAgICAgIGlmICgkYWxpYXNbJ3BhY2thZ2UnXSA9PT0gJHBhY2thZ2UtPmdldE5hbWUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdXNlZEFsaWFzZXNbXSA9ICRhbGlhczsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGFsaWFzZXNbJGluZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB1c29ydCgkdXNlZEFsaWFzZXMsIGZ1bmN0aW9uICgkYSwgJGIpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYVsncGFja2FnZSddLCAkYlsncGFja2FnZSddKTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuICR1c2VkQWxpYXNlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXI7CgovKioKICogU3RvcmVzIGRlY2lzaW9ucyBvbiBpbnN0YWxsaW5nLCByZW1vdmluZyBvciBrZWVwaW5nIHBhY2thZ2VzCiAqCiAqIEBhdXRob3IgTmlscyBBZGVybWFubiA8bmFkZXJtYW5AbmFkZXJtYW4uZGU+CiAqLwpjbGFzcyBEZWNpc2lvbnMgaW1wbGVtZW50cyBcSXRlcmF0b3IsIFxDb3VudGFibGUKewogICAgY29uc3QgREVDSVNJT05fTElURVJBTCA9IDA7CiAgICBjb25zdCBERUNJU0lPTl9SRUFTT04gPSAxOwoKICAgIHByb3RlY3RlZCAkcG9vbDsKICAgIHByb3RlY3RlZCAkZGVjaXNpb25NYXA7CiAgICBwcm90ZWN0ZWQgJGRlY2lzaW9uUXVldWUgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcG9vbCkKICAgIHsKICAgICAgICAkdGhpcy0+cG9vbCA9ICRwb29sOwogICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcCA9IGFycmF5KCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRlY2lkZSgkbGl0ZXJhbCwgJGxldmVsLCAkd2h5KQogICAgewogICAgICAgICR0aGlzLT5hZGREZWNpc2lvbigkbGl0ZXJhbCwgJGxldmVsKTsKICAgICAgICAkdGhpcy0+ZGVjaXNpb25RdWV1ZVtdID0gYXJyYXkoCiAgICAgICAgICAgIHNlbGY6OkRFQ0lTSU9OX0xJVEVSQUwgPT4gJGxpdGVyYWwsCiAgICAgICAgICAgIHNlbGY6OkRFQ0lTSU9OX1JFQVNPTiA9PiAkd2h5LAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNhdGlzZnkoJGxpdGVyYWwpCiAgICB7CiAgICAgICAgJHBhY2thZ2VJZCA9IGFicygkbGl0ZXJhbCk7CgogICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICRsaXRlcmFsID4gMCAmJiBpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pICYmICR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSA+IDAgfHwKICAgICAgICAgICAgJGxpdGVyYWwgPCAwICYmIGlzc2V0KCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSkgJiYgJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdIDwgMAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNvbmZsaWN0KCRsaXRlcmFsKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWwpOwoKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICAoaXNzZXQoJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdKSAmJiAkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0gPiAwICYmICRsaXRlcmFsIDwgMCkgfHwKICAgICAgICAgICAgKGlzc2V0KCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSkgJiYgJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdIDwgMCAmJiAkbGl0ZXJhbCA+IDApCiAgICAgICAgKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVjaWRlZCgkbGl0ZXJhbE9yUGFja2FnZUlkKQogICAgewogICAgICAgIHJldHVybiAhZW1wdHkoJHRoaXMtPmRlY2lzaW9uTWFwW2FicygkbGl0ZXJhbE9yUGFja2FnZUlkKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB1bmRlY2lkZWQoJGxpdGVyYWxPclBhY2thZ2VJZCkKICAgIHsKICAgICAgICByZXR1cm4gZW1wdHkoJHRoaXMtPmRlY2lzaW9uTWFwW2FicygkbGl0ZXJhbE9yUGFja2FnZUlkKV0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpZGVkSW5zdGFsbCgkbGl0ZXJhbE9yUGFja2FnZUlkKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWxPclBhY2thZ2VJZCk7CgogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pICYmICR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSA+IDA7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRlY2lzaW9uTGV2ZWwoJGxpdGVyYWxPclBhY2thZ2VJZCkKICAgIHsKICAgICAgICAkcGFja2FnZUlkID0gYWJzKCRsaXRlcmFsT3JQYWNrYWdlSWQpOwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0pKSB7CiAgICAgICAgICAgIHJldHVybiBhYnMoJHRoaXMtPmRlY2lzaW9uTWFwWyRwYWNrYWdlSWRdKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkZWNpc2lvblJ1bGUoJGxpdGVyYWxPclBhY2thZ2VJZCkKICAgIHsKICAgICAgICAkcGFja2FnZUlkID0gYWJzKCRsaXRlcmFsT3JQYWNrYWdlSWQpOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZGVjaXNpb25RdWV1ZSBhcyAkaSA9PiAkZGVjaXNpb24pIHsKICAgICAgICAgICAgaWYgKCRwYWNrYWdlSWQgPT09IGFicygkZGVjaXNpb25bc2VsZjo6REVDSVNJT05fTElURVJBTF0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGRlY2lzaW9uW3NlbGY6OkRFQ0lTSU9OX1JFQVNPTl07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhdE9mZnNldCgkcXVldWVPZmZzZXQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNpc2lvblF1ZXVlWyRxdWV1ZU9mZnNldF07CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkT2Zmc2V0KCRxdWV1ZU9mZnNldCkKICAgIHsKICAgICAgICByZXR1cm4gJHF1ZXVlT2Zmc2V0ID49IDAgJiYgJHF1ZXVlT2Zmc2V0IDwgXGNvdW50KCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gbGFzdFJlYXNvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNpc2lvblF1ZXVlW1xjb3VudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSkgLSAxXVtzZWxmOjpERUNJU0lPTl9SRUFTT05dOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBsYXN0TGl0ZXJhbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNpc2lvblF1ZXVlW1xjb3VudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSkgLSAxXVtzZWxmOjpERUNJU0lPTl9MSVRFUkFMXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXQoKQogICAgewogICAgICAgIHdoaWxlICgkZGVjaXNpb24gPSBhcnJheV9wb3AoJHRoaXMtPmRlY2lzaW9uUXVldWUpKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcFthYnMoJGRlY2lzaW9uW3NlbGY6OkRFQ0lTSU9OX0xJVEVSQUxdKV0gPSAwOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzZXRUb09mZnNldCgkb2Zmc2V0KQogICAgewogICAgICAgIHdoaWxlIChcY291bnQoJHRoaXMtPmRlY2lzaW9uUXVldWUpID4gJG9mZnNldCArIDEpIHsKICAgICAgICAgICAgJGRlY2lzaW9uID0gYXJyYXlfcG9wKCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgICAgICAgICAgJHRoaXMtPmRlY2lzaW9uTWFwW2FicygkZGVjaXNpb25bc2VsZjo6REVDSVNJT05fTElURVJBTF0pXSA9IDA7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZXZlcnRMYXN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGVjaXNpb25NYXBbYWJzKCR0aGlzLT5sYXN0TGl0ZXJhbCgpKV0gPSAwOwogICAgICAgIGFycmF5X3BvcCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICByZXR1cm4gXGNvdW50KCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmV3aW5kKCkKICAgIHsKICAgICAgICBlbmQoJHRoaXMtPmRlY2lzaW9uUXVldWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gY3VycmVudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGtleSgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG5leHQoKQogICAgewogICAgICAgIHJldHVybiBwcmV2KCR0aGlzLT5kZWNpc2lvblF1ZXVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSAhPT0gY3VycmVudCgkdGhpcy0+ZGVjaXNpb25RdWV1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzRW1wdHkoKQogICAgewogICAgICAgIHJldHVybiBcY291bnQoJHRoaXMtPmRlY2lzaW9uUXVldWUpID09PSAwOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGREZWNpc2lvbigkbGl0ZXJhbCwgJGxldmVsKQogICAgewogICAgICAgICRwYWNrYWdlSWQgPSBhYnMoJGxpdGVyYWwpOwoKICAgICAgICAkcHJldmlvdXNEZWNpc2lvbiA9IGlzc2V0KCR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSkgPyAkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0gOiBudWxsOwogICAgICAgIGlmICgkcHJldmlvdXNEZWNpc2lvbiAhPSAwKSB7CiAgICAgICAgICAgICRsaXRlcmFsU3RyaW5nID0gJHRoaXMtPnBvb2wtPmxpdGVyYWxUb1ByZXR0eVN0cmluZygkbGl0ZXJhbCwgYXJyYXkoKSk7CiAgICAgICAgICAgICRwYWNrYWdlID0gJHRoaXMtPnBvb2wtPmxpdGVyYWxUb1BhY2thZ2UoJGxpdGVyYWwpOwogICAgICAgICAgICB0aHJvdyBuZXcgU29sdmVyQnVnRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIlRyeWluZyB0byBkZWNpZGUgJGxpdGVyYWxTdHJpbmcgb24gbGV2ZWwgJGxldmVsLCBldmVuIHRob3VnaCAkcGFja2FnZSB3YXMgcHJldmlvdXNseSBkZWNpZGVkIGFzICIuKGludCkgJHByZXZpb3VzRGVjaXNpb24uIi4iCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGxpdGVyYWwgPiAwKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWNpc2lvbk1hcFskcGFja2FnZUlkXSA9ICRsZXZlbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+ZGVjaXNpb25NYXBbJHBhY2thZ2VJZF0gPSAtJGxldmVsOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdG9TdHJpbmcoUG9vbCAkcG9vbCA9IG51bGwpCiAgICB7CiAgICAgICAgJGRlY2lzaW9uTWFwID0gJHRoaXMtPmRlY2lzaW9uTWFwOwogICAgICAgIGtzb3J0KCRkZWNpc2lvbk1hcCk7CiAgICAgICAgJHN0ciA9ICdbJzsKICAgICAgICBmb3JlYWNoICgkZGVjaXNpb25NYXAgYXMgJHBhY2thZ2VJZCA9PiAkbGV2ZWwpIHsKICAgICAgICAgICAgJHN0ciAuPSAoKCRwb29sKSA/ICRwb29sLT5saXRlcmFsVG9QYWNrYWdlKCRwYWNrYWdlSWQpIDogJHBhY2thZ2VJZCkuJzonLiRsZXZlbC4nLCc7CiAgICAgICAgfQogICAgICAgICRzdHIgLj0gJ10nOwoKICAgICAgICByZXR1cm4gJHN0cjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50b1N0cmluZygpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyOwoKdXNlIENvbXBvc2VyXElPXElPSW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcVXRpbFxGaWxlc3lzdGVtOwp1c2UgQ29tcG9zZXJcVXRpbFxTaWxlbmNlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxGaW5kZXI7CgovKioKICogUmVhZHMvd3JpdGVzIHRvIGEgZmlsZXN5c3RlbSBjYWNoZQogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBDYWNoZQp7CiAgICBwcml2YXRlIHN0YXRpYyAkY2FjaGVDb2xsZWN0ZWQgPSBmYWxzZTsKICAgIHByaXZhdGUgJGlvOwogICAgcHJpdmF0ZSAkcm9vdDsKICAgIHByaXZhdGUgJGVuYWJsZWQgPSB0cnVlOwogICAgcHJpdmF0ZSAkYWxsb3dsaXN0OwogICAgcHJpdmF0ZSAkZmlsZXN5c3RlbTsKICAgIHByaXZhdGUgJHJlYWRPbmx5OwoKICAgIC8qKgogICAgICogQHBhcmFtIElPSW50ZXJmYWNlICRpbwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRjYWNoZURpciAgIGxvY2F0aW9uIG9mIHRoZSBjYWNoZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRhbGxvd2xpc3QgIExpc3Qgb2YgY2hhcmFjdGVycyB0aGF0IGFyZSBhbGxvd2VkIGluIHBhdGggbmFtZXMgKHVzZWQgaW4gYSByZWdleCBjaGFyYWN0ZXIgY2xhc3MpCiAgICAgKiBAcGFyYW0gRmlsZXN5c3RlbSAgJGZpbGVzeXN0ZW0gb3B0aW9uYWwgZmlsZXN5c3RlbSBpbnN0YW5jZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRyZWFkT25seSAgIHdoZXRoZXIgdGhlIGNhY2hlIGlzIGluIHJlYWRPbmx5IG1vZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElPSW50ZXJmYWNlICRpbywgJGNhY2hlRGlyLCAkYWxsb3dsaXN0ID0gJ2EtejAtOS4nLCBGaWxlc3lzdGVtICRmaWxlc3lzdGVtID0gbnVsbCwgJHJlYWRPbmx5ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmlvID0gJGlvOwogICAgICAgICR0aGlzLT5yb290ID0gcnRyaW0oJGNhY2hlRGlyLCAnL1xcJykgLiAnLyc7CiAgICAgICAgJHRoaXMtPmFsbG93bGlzdCA9ICRhbGxvd2xpc3Q7CiAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0gPSAkZmlsZXN5c3RlbSA/OiBuZXcgRmlsZXN5c3RlbSgpOwogICAgICAgICR0aGlzLT5yZWFkT25seSA9IChib29sKSAkcmVhZE9ubHk7CgogICAgICAgIGlmICghc2VsZjo6aXNVc2FibGUoJGNhY2hlRGlyKSkgewogICAgICAgICAgICAkdGhpcy0+ZW5hYmxlZCA9IGZhbHNlOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKAogICAgICAgICAgICAoIWlzX2RpcigkdGhpcy0+cm9vdCkgJiYgIVNpbGVuY2VyOjpjYWxsKCdta2RpcicsICR0aGlzLT5yb290LCAwNzc3LCB0cnVlKSkKICAgICAgICAgICAgfHwgIWlzX3dyaXRhYmxlKCR0aGlzLT5yb290KQogICAgICAgICkgewogICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJzx3YXJuaW5nPkNhbm5vdCBjcmVhdGUgY2FjaGUgZGlyZWN0b3J5ICcgLiAkdGhpcy0+cm9vdCAuICcsIG9yIGRpcmVjdG9yeSBpcyBub3Qgd3JpdGFibGUuIFByb2NlZWRpbmcgd2l0aG91dCBjYWNoZTwvd2FybmluZz4nKTsKICAgICAgICAgICAgJHRoaXMtPmVuYWJsZWQgPSBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkcmVhZE9ubHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlYWRPbmx5KCRyZWFkT25seSkKICAgIHsKICAgICAgICAkdGhpcy0+cmVhZE9ubHkgPSAoYm9vbCkgJHJlYWRPbmx5OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1JlYWRPbmx5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlYWRPbmx5OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNVc2FibGUoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuICFwcmVnX21hdGNoKCd7KF58W1xcXFwvXSkoXCRudWxsfG51bHxOVUx8L2Rldi9udWxsKShbXFxcXC9dfCQpfScsICRwYXRoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNFbmFibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVuYWJsZWQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvb3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cm9vdDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZCgkZmlsZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmVuYWJsZWQpIHsKICAgICAgICAgICAgJGZpbGUgPSBwcmVnX3JlcGxhY2UoJ3tbXicuJHRoaXMtPmFsbG93bGlzdC4nXX1pJywgJy0nLCAkZmlsZSk7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+cm9vdCAuICRmaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdSZWFkaW5nICcuJHRoaXMtPnJvb3QgLiAkZmlsZS4nIGZyb20gY2FjaGUnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+cm9vdCAuICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZmlsZSwgJGNvbnRlbnRzKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZW5hYmxlZCAmJiAhJHRoaXMtPnJlYWRPbmx5KSB7CiAgICAgICAgICAgICRmaWxlID0gcHJlZ19yZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwoKICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCdXcml0aW5nICcuJHRoaXMtPnJvb3QgLiAkZmlsZS4nIGludG8gY2FjaGUnLCB0cnVlLCBJT0ludGVyZmFjZTo6REVCVUcpOwoKICAgICAgICAgICAgJHRlbXBGaWxlTmFtZSA9ICR0aGlzLT5yb290IC4gJGZpbGUgLiB1bmlxaWQoJy4nLCB0cnVlKSAuICcudG1wJzsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlX3B1dF9jb250ZW50cygkdGVtcEZpbGVOYW1lLCAkY29udGVudHMpICE9PSBmYWxzZSAmJiByZW5hbWUoJHRlbXBGaWxlTmFtZSwgJHRoaXMtPnJvb3QgLiAkZmlsZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFcnJvckV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmlvLT53cml0ZUVycm9yKCc8d2FybmluZz5GYWlsZWQgdG8gd3JpdGUgaW50byBjYWNoZTogJy4kZS0+Z2V0TWVzc2FnZSgpLic8L3dhcm5pbmc+JywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XmZpbGVfcHV0X2NvbnRlbnRzXChcKTogT25seSAoWzAtOV0rKSBvZiAoWzAtOV0rKSBieXRlcyB3cml0dGVufScsICRlLT5nZXRNZXNzYWdlKCksICRtKSkgewogICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBwYXJ0aWFsIGZpbGUuCiAgICAgICAgICAgICAgICAgICAgdW5saW5rKCR0ZW1wRmlsZU5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICc8d2FybmluZz5Xcml0aW5nICUxJHMgaW50byBjYWNoZSBmYWlsZWQgYWZ0ZXIgJTIkdSBvZiAlMyR1IGJ5dGVzIHdyaXR0ZW4sIG9ubHkgJTQkdSBieXRlcyBvZiBmcmVlIHNwYWNlIGF2YWlsYWJsZTwvd2FybmluZz4nLAogICAgICAgICAgICAgICAgICAgICAgICAkdGVtcEZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAkbVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgJG1bMl0sCiAgICAgICAgICAgICAgICAgICAgICAgIEBkaXNrX2ZyZWVfc3BhY2UoZGlybmFtZSgkdGVtcEZpbGVOYW1lKSkKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW8tPndyaXRlRXJyb3IoJG1lc3NhZ2UpOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvcHkgYSBmaWxlIGludG8gdGhlIGNhY2hlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5RnJvbSgkZmlsZSwgJHNvdXJjZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmVuYWJsZWQgJiYgISR0aGlzLT5yZWFkT25seSkgewogICAgICAgICAgICAkZmlsZSA9IHByZWdfcmVwbGFjZSgne1teJy4kdGhpcy0+YWxsb3dsaXN0LiddfWknLCAnLScsICRmaWxlKTsKICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPmVuc3VyZURpcmVjdG9yeUV4aXN0cyhkaXJuYW1lKCR0aGlzLT5yb290IC4gJGZpbGUpKTsKCiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHNvdXJjZSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignPGVycm9yPicuJHNvdXJjZS4nIGRvZXMgbm90IGV4aXN0LCBjYW4gbm90IHdyaXRlIGludG8gY2FjaGU8L2Vycm9yPicpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmlvLT5pc0RlYnVnKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignV3JpdGluZyAnLiR0aGlzLT5yb290IC4gJGZpbGUuJyBpbnRvIGNhY2hlIGZyb20gJy4kc291cmNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGNvcHkoJHNvdXJjZSwgJHRoaXMtPnJvb3QgLiAkZmlsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3B5IGEgZmlsZSBvdXQgb2YgdGhlIGNhY2hlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3B5VG8oJGZpbGUsICR0YXJnZXQpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5lbmFibGVkKSB7CiAgICAgICAgICAgICRmaWxlID0gcHJlZ19yZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnJvb3QgLiAkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdG91Y2goJHRoaXMtPnJvb3QgLiAkZmlsZSwgZmlsZW10aW1lKCR0aGlzLT5yb290IC4gJGZpbGUpLCB0aW1lKCkpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXEVycm9yRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZmFsbGJhY2sgaW4gY2FzZSB0aGUgYWJvdmUgZmFpbGVkIGR1ZSB0byBpbmNvcnJlY3Qgb3duZXJzaGlwCiAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlci9jb21wb3Nlci9pc3N1ZXMvNDA3MAogICAgICAgICAgICAgICAgICAgIFNpbGVuY2VyOjpjYWxsKCd0b3VjaCcsICR0aGlzLT5yb290IC4gJGZpbGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0aGlzLT5pby0+d3JpdGVFcnJvcignUmVhZGluZyAnLiR0aGlzLT5yb290IC4gJGZpbGUuJyBmcm9tIGNhY2hlJywgdHJ1ZSwgSU9JbnRlcmZhY2U6OkRFQlVHKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gY29weSgkdGhpcy0+cm9vdCAuICRmaWxlLCAkdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnY0lzTmVjZXNzYXJ5KCkKICAgIHsKICAgICAgICByZXR1cm4gKCFzZWxmOjokY2FjaGVDb2xsZWN0ZWQgJiYgIW10X3JhbmQoMCwgNTApKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCRmaWxlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZW5hYmxlZCkgewogICAgICAgICAgICAkZmlsZSA9IHByZWdfcmVwbGFjZSgne1teJy4kdGhpcy0+YWxsb3dsaXN0LiddfWknLCAnLScsICRmaWxlKTsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCR0aGlzLT5yb290IC4gJGZpbGUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGVzeXN0ZW0tPnVubGluaygkdGhpcy0+cm9vdCAuICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5lbmFibGVkKSB7CiAgICAgICAgICAgICR0aGlzLT5maWxlc3lzdGVtLT5lbXB0eURpcmVjdG9yeSgkdGhpcy0+cm9vdCk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2MoJHR0bCwgJG1heFNpemUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5lbmFibGVkKSB7CiAgICAgICAgICAgICRleHBpcmUgPSBuZXcgXERhdGVUaW1lKCk7CiAgICAgICAgICAgICRleHBpcmUtPm1vZGlmeSgnLScuJHR0bC4nIHNlY29uZHMnKTsKCiAgICAgICAgICAgICRmaW5kZXIgPSAkdGhpcy0+Z2V0RmluZGVyKCktPmRhdGUoJ3VudGlsICcuJGV4cGlyZS0+Zm9ybWF0KCdZLW0tZCBIOmk6cycpKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGZpbmRlciBhcyAkZmlsZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVzeXN0ZW0tPnVubGluaygkZmlsZS0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0b3RhbFNpemUgPSAkdGhpcy0+ZmlsZXN5c3RlbS0+c2l6ZSgkdGhpcy0+cm9vdCk7CiAgICAgICAgICAgIGlmICgkdG90YWxTaXplID4gJG1heFNpemUpIHsKICAgICAgICAgICAgICAgICRpdGVyYXRvciA9ICR0aGlzLT5nZXRGaW5kZXIoKS0+c29ydEJ5QWNjZXNzZWRUaW1lKCktPmdldEl0ZXJhdG9yKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoJHRvdGFsU2l6ZSA+ICRtYXhTaXplICYmICRpdGVyYXRvci0+dmFsaWQoKSkgewogICAgICAgICAgICAgICAgICAgICRmaWxlcGF0aCA9ICRpdGVyYXRvci0+Y3VycmVudCgpLT5nZXRQYXRobmFtZSgpOwogICAgICAgICAgICAgICAgICAgICR0b3RhbFNpemUgLT0gJHRoaXMtPmZpbGVzeXN0ZW0tPnNpemUoJGZpbGVwYXRoKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmlsZXN5c3RlbS0+dW5saW5rKCRmaWxlcGF0aCk7CiAgICAgICAgICAgICAgICAgICAgJGl0ZXJhdG9yLT5uZXh0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGY6OiRjYWNoZUNvbGxlY3RlZCA9IHRydWU7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hhMSgkZmlsZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmVuYWJsZWQpIHsKICAgICAgICAgICAgJGZpbGUgPSBwcmVnX3JlcGxhY2UoJ3tbXicuJHRoaXMtPmFsbG93bGlzdC4nXX1pJywgJy0nLCAkZmlsZSk7CiAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkdGhpcy0+cm9vdCAuICRmaWxlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNoYTFfZmlsZSgkdGhpcy0+cm9vdCAuICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzaGEyNTYoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5lbmFibGVkKSB7CiAgICAgICAgICAgICRmaWxlID0gcHJlZ19yZXBsYWNlKCd7W14nLiR0aGlzLT5hbGxvd2xpc3QuJ119aScsICctJywgJGZpbGUpOwogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJHRoaXMtPnJvb3QgLiAkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoYXNoX2ZpbGUoJ3NoYTI1NicsICR0aGlzLT5yb290IC4gJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEZpbmRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuIEZpbmRlcjo6Y3JlYXRlKCktPmluKCR0aGlzLT5yb290KS0+ZmlsZXMoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCmZ1bmN0aW9uIGluY2x1ZGVJZkV4aXN0cygkZmlsZSkKewogICAgcmV0dXJuIGZpbGVfZXhpc3RzKCRmaWxlKSA/IGluY2x1ZGUgJGZpbGUgOiBmYWxzZTsKfQoKaWYgKCghJGxvYWRlciA9IGluY2x1ZGVJZkV4aXN0cyhfX0RJUl9fLicvLi4vdmVuZG9yL2F1dG9sb2FkLnBocCcpKSAmJiAoISRsb2FkZXIgPSBpbmNsdWRlSWZFeGlzdHMoX19ESVJfXy4nLy4uLy4uLy4uL2F1dG9sb2FkLnBocCcpKSkgewogICAgZWNobyAnWW91IG11c3Qgc2V0IHVwIHRoZSBwcm9qZWN0IGRlcGVuZGVuY2llcyB1c2luZyBgY29tcG9zZXIgaW5zdGFsbGAnLlBIUF9FT0wuCiAgICAgICAgJ1NlZSBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb3dubG9hZC8gZm9yIGluc3RydWN0aW9ucyBvbiBpbnN0YWxsaW5nIENvbXBvc2VyJy5QSFBfRU9MOwogICAgZXhpdCgxKTsKfQoKcmV0dXJuICRsb2FkZXI7Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBDb21wb3Nlci4KICoKICogKGMpIE5pbHMgQWRlcm1hbm4gPG5hZGVybWFuQG5hZGVybWFuLmRlPgogKiAgICAgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXEF1dG9sb2FkOwoKLyoqCiAqIENsYXNzTG9hZGVyIGltcGxlbWVudHMgYSBQU1ItMCwgUFNSLTQgYW5kIGNsYXNzbWFwIGNsYXNzIGxvYWRlci4KICoKICogICAgICRsb2FkZXIgPSBuZXcgXENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyKCk7CiAqCiAqICAgICAvLyByZWdpc3RlciBjbGFzc2VzIHdpdGggbmFtZXNwYWNlcwogKiAgICAgJGxvYWRlci0+YWRkKCdTeW1mb255XENvbXBvbmVudCcsIF9fRElSX18uJy9jb21wb25lbnQnKTsKICogICAgICRsb2FkZXItPmFkZCgnU3ltZm9ueScsICAgICAgICAgICBfX0RJUl9fLicvZnJhbWV3b3JrJyk7CiAqCiAqICAgICAvLyBhY3RpdmF0ZSB0aGUgYXV0b2xvYWRlcgogKiAgICAgJGxvYWRlci0+cmVnaXN0ZXIoKTsKICoKICogICAgIC8vIHRvIGVuYWJsZSBzZWFyY2hpbmcgdGhlIGluY2x1ZGUgcGF0aCAoZWcuIGZvciBQRUFSIHBhY2thZ2VzKQogKiAgICAgJGxvYWRlci0+c2V0VXNlSW5jbHVkZVBhdGgodHJ1ZSk7CiAqCiAqIEluIHRoaXMgZXhhbXBsZSwgaWYgeW91IHRyeSB0byB1c2UgYSBjbGFzcyBpbiB0aGUgU3ltZm9ueVxDb21wb25lbnQKICogbmFtZXNwYWNlIG9yIG9uZSBvZiBpdHMgY2hpbGRyZW4gKFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGUgZm9yIGluc3RhbmNlKSwKICogdGhlIGF1dG9sb2FkZXIgd2lsbCBmaXJzdCBsb29rIGZvciB0aGUgY2xhc3MgdW5kZXIgdGhlIGNvbXBvbmVudC8KICogZGlyZWN0b3J5LCBhbmQgaXQgd2lsbCB0aGVuIGZhbGxiYWNrIHRvIHRoZSBmcmFtZXdvcmsvIGRpcmVjdG9yeSBpZiBub3QKICogZm91bmQgYmVmb3JlIGdpdmluZyB1cC4KICoKICogVGhpcyBjbGFzcyBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZSBTeW1mb255IFVuaXZlcnNhbENsYXNzTG9hZGVyLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKiBAc2VlICAgIGh0dHBzOi8vd3d3LnBocC1maWcub3JnL3Bzci9wc3ItMC8KICogQHNlZSAgICBodHRwczovL3d3dy5waHAtZmlnLm9yZy9wc3IvcHNyLTQvCiAqLwpjbGFzcyBDbGFzc0xvYWRlcgp7CiAgICBwcml2YXRlICR2ZW5kb3JEaXI7CgogICAgLy8gUFNSLTQKICAgIHByaXZhdGUgJHByZWZpeExlbmd0aHNQc3I0ID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJHByZWZpeERpcnNQc3I0ID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJGZhbGxiYWNrRGlyc1BzcjQgPSBhcnJheSgpOwoKICAgIC8vIFBTUi0wCiAgICBwcml2YXRlICRwcmVmaXhlc1BzcjAgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkZmFsbGJhY2tEaXJzUHNyMCA9IGFycmF5KCk7CgogICAgcHJpdmF0ZSAkdXNlSW5jbHVkZVBhdGggPSBmYWxzZTsKICAgIHByaXZhdGUgJGNsYXNzTWFwID0gYXJyYXkoKTsKICAgIHByaXZhdGUgJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSA9IGZhbHNlOwogICAgcHJpdmF0ZSAkbWlzc2luZ0NsYXNzZXMgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkYXBjdVByZWZpeDsKCiAgICBwcml2YXRlIHN0YXRpYyAkcmVnaXN0ZXJlZExvYWRlcnMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdmVuZG9yRGlyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmVuZG9yRGlyID0gJHZlbmRvckRpcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZml4ZXMoKQogICAgewogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPnByZWZpeGVzUHNyMCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCdhcnJheV9tZXJnZScsIGFycmF5X3ZhbHVlcygkdGhpcy0+cHJlZml4ZXNQc3IwKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZml4ZXNQc3I0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZpeERpcnNQc3I0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGYWxsYmFja0RpcnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmFsbGJhY2tEaXJzUHNyNCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDbGFzc01hcCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jbGFzc01hcDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkY2xhc3NNYXAgQ2xhc3MgdG8gZmlsZW5hbWUgbWFwCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDbGFzc01hcChhcnJheSAkY2xhc3NNYXApCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jbGFzc01hcCkgewogICAgICAgICAgICAkdGhpcy0+Y2xhc3NNYXAgPSBhcnJheV9tZXJnZSgkdGhpcy0+Y2xhc3NNYXAsICRjbGFzc01hcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmNsYXNzTWFwID0gJGNsYXNzTWFwOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyBhIHNldCBvZiBQU1ItMCBkaXJlY3RvcmllcyBmb3IgYSBnaXZlbiBwcmVmaXgsIGVpdGhlcgogICAgICogYXBwZW5kaW5nIG9yIHByZXBlbmRpbmcgdG8gdGhlIG9uZXMgcHJldmlvdXNseSBzZXQgZm9yIHRoaXMgcHJlZml4LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHByZWZpeCAgVGhlIHByZWZpeAogICAgICogQHBhcmFtIGFycmF5fHN0cmluZyAkcGF0aHMgICBUaGUgUFNSLTAgcm9vdCBkaXJlY3RvcmllcwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkcHJlcGVuZCBXaGV0aGVyIHRvIHByZXBlbmQgdGhlIGRpcmVjdG9yaWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGQoJHByZWZpeCwgJHBhdGhzLCAkcHJlcGVuZCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyMCA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3IwLAogICAgICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkZmlyc3QgPSAkcHJlZml4WzBdOwogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnByZWZpeGVzUHNyMFskZmlyc3RdWyRwcmVmaXhdKSkgewogICAgICAgICAgICAkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKCRwcmVwZW5kKSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMsCiAgICAgICAgICAgICAgICAkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0KICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF1bJHByZWZpeF0gPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XVskcHJlZml4XSwKICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi00IGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIG5hbWVzcGFjZSwgZWl0aGVyCiAgICAgKiBhcHBlbmRpbmcgb3IgcHJlcGVuZGluZyB0byB0aGUgb25lcyBwcmV2aW91c2x5IHNldCBmb3IgdGhpcyBuYW1lc3BhY2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkcHJlZml4ICBUaGUgcHJlZml4L25hbWVzcGFjZSwgd2l0aCB0cmFpbGluZyAnXFwnCiAgICAgKiBAcGFyYW0gYXJyYXl8c3RyaW5nICRwYXRocyAgIFRoZSBQU1ItNCBiYXNlIGRpcmVjdG9yaWVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRwcmVwZW5kIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBzcjQoJHByZWZpeCwgJHBhdGhzLCAkcHJlcGVuZCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghJHByZWZpeCkgewogICAgICAgICAgICAvLyBSZWdpc3RlciBkaXJlY3RvcmllcyBmb3IgdGhlIHJvb3QgbmFtZXNwYWNlLgogICAgICAgICAgICBpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0ID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgKGFycmF5KSAkcGF0aHMsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tEaXJzUHNyNCA9IGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5mYWxsYmFja0RpcnNQc3I0LAogICAgICAgICAgICAgICAgICAgIChhcnJheSkgJHBhdGhzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCFpc3NldCgkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0pKSB7CiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGRpcmVjdG9yaWVzIGZvciBhIG5ldyBuYW1lc3BhY2UuCiAgICAgICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHByZWZpeCk7CiAgICAgICAgICAgIGlmICgnXFwnICE9PSAkcHJlZml4WyRsZW5ndGggLSAxXSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oIkEgbm9uLWVtcHR5IFBTUi00IHByZWZpeCBtdXN0IGVuZCB3aXRoIGEgbmFtZXNwYWNlIHNlcGFyYXRvci4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+cHJlZml4TGVuZ3Roc1BzcjRbJHByZWZpeFswXV1bJHByZWZpeF0gPSAkbGVuZ3RoOwogICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0gPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9IGVsc2VpZiAoJHByZXBlbmQpIHsKICAgICAgICAgICAgLy8gUHJlcGVuZCBkaXJlY3RvcmllcyBmb3IgYW4gYWxyZWFkeSByZWdpc3RlcmVkIG5hbWVzcGFjZS4KICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocywKICAgICAgICAgICAgICAgICR0aGlzLT5wcmVmaXhEaXJzUHNyNFskcHJlZml4XQogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEFwcGVuZCBkaXJlY3RvcmllcyBmb3IgYW4gYWxyZWFkeSByZWdpc3RlcmVkIG5hbWVzcGFjZS4KICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHByZWZpeF0sCiAgICAgICAgICAgICAgICAoYXJyYXkpICRwYXRocwogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyBhIHNldCBvZiBQU1ItMCBkaXJlY3RvcmllcyBmb3IgYSBnaXZlbiBwcmVmaXgsCiAgICAgKiByZXBsYWNpbmcgYW55IG90aGVycyBwcmV2aW91c2x5IHNldCBmb3IgdGhpcyBwcmVmaXguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkcHJlZml4IFRoZSBwcmVmaXgKICAgICAqIEBwYXJhbSBhcnJheXxzdHJpbmcgJHBhdGhzICBUaGUgUFNSLTAgYmFzZSBkaXJlY3RvcmllcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0KCRwcmVmaXgsICRwYXRocykKICAgIHsKICAgICAgICBpZiAoISRwcmVmaXgpIHsKICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjAgPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJlZml4ZXNQc3IwWyRwcmVmaXhbMF1dWyRwcmVmaXhdID0gKGFycmF5KSAkcGF0aHM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgc2V0IG9mIFBTUi00IGRpcmVjdG9yaWVzIGZvciBhIGdpdmVuIG5hbWVzcGFjZSwKICAgICAqIHJlcGxhY2luZyBhbnkgb3RoZXJzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIG5hbWVzcGFjZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICRwcmVmaXggVGhlIHByZWZpeC9uYW1lc3BhY2UsIHdpdGggdHJhaWxpbmcgJ1xcJwogICAgICogQHBhcmFtIGFycmF5fHN0cmluZyAkcGF0aHMgIFRoZSBQU1ItNCBiYXNlIGRpcmVjdG9yaWVzCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQc3I0KCRwcmVmaXgsICRwYXRocykKICAgIHsKICAgICAgICBpZiAoISRwcmVmaXgpIHsKICAgICAgICAgICAgJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQgPSAoYXJyYXkpICRwYXRoczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbGVuZ3RoID0gc3RybGVuKCRwcmVmaXgpOwogICAgICAgICAgICBpZiAoJ1xcJyAhPT0gJHByZWZpeFskbGVuZ3RoIC0gMV0pIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCJBIG5vbi1lbXB0eSBQU1ItNCBwcmVmaXggbXVzdCBlbmQgd2l0aCBhIG5hbWVzcGFjZSBzZXBhcmF0b3IuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPnByZWZpeExlbmd0aHNQc3I0WyRwcmVmaXhbMF1dWyRwcmVmaXhdID0gJGxlbmd0aDsKICAgICAgICAgICAgJHRoaXMtPnByZWZpeERpcnNQc3I0WyRwcmVmaXhdID0gKGFycmF5KSAkcGF0aHM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVHVybnMgb24gc2VhcmNoaW5nIHRoZSBpbmNsdWRlIHBhdGggZm9yIGNsYXNzIGZpbGVzLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICR1c2VJbmNsdWRlUGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXNlSW5jbHVkZVBhdGgoJHVzZUluY2x1ZGVQYXRoKQogICAgewogICAgICAgICR0aGlzLT51c2VJbmNsdWRlUGF0aCA9ICR1c2VJbmNsdWRlUGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIENhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoZSBhdXRvbG9hZGVyIHVzZXMgdGhlIGluY2x1ZGUgcGF0aCB0byBjaGVjawogICAgICogZm9yIGNsYXNzZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVc2VJbmNsdWRlUGF0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51c2VJbmNsdWRlUGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIFR1cm5zIG9mZiBzZWFyY2hpbmcgdGhlIHByZWZpeCBhbmQgZmFsbGJhY2sgZGlyZWN0b3JpZXMgZm9yIGNsYXNzZXMKICAgICAqIHRoYXQgaGF2ZSBub3QgYmVlbiByZWdpc3RlcmVkIHdpdGggdGhlIGNsYXNzIG1hcC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkY2xhc3NNYXBBdXRob3JpdGF0aXZlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDbGFzc01hcEF1dGhvcml0YXRpdmUoJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlID0gJGNsYXNzTWFwQXV0aG9yaXRhdGl2ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNob3VsZCBjbGFzcyBsb29rdXAgZmFpbCBpZiBub3QgZm91bmQgaW4gdGhlIGN1cnJlbnQgY2xhc3MgbWFwPwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNDbGFzc01hcEF1dGhvcml0YXRpdmUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogQVBDdSBwcmVmaXggdG8gdXNlIHRvIGNhY2hlIGZvdW5kL25vdC1mb3VuZCBjbGFzc2VzLCBpZiB0aGUgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRhcGN1UHJlZml4CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcGN1UHJlZml4KCRhcGN1UHJlZml4KQogICAgewogICAgICAgICR0aGlzLT5hcGN1UHJlZml4ID0gZnVuY3Rpb25fZXhpc3RzKCdhcGN1X2ZldGNoJykgJiYgZmlsdGVyX3ZhcihpbmlfZ2V0KCdhcGMuZW5hYmxlZCcpLCBGSUxURVJfVkFMSURBVEVfQk9PTEVBTikgPyAkYXBjdVByZWZpeCA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgQVBDdSBwcmVmaXggaW4gdXNlLCBvciBudWxsIGlmIEFQQ3UgY2FjaGluZyBpcyBub3QgZW5hYmxlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcGN1UHJlZml4KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFwY3VQcmVmaXg7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgdGhpcyBpbnN0YW5jZSBhcyBhbiBhdXRvbG9hZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRwcmVwZW5kIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgYXV0b2xvYWRlciBvciBub3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRwcmVwZW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgc3BsX2F1dG9sb2FkX3JlZ2lzdGVyKGFycmF5KCR0aGlzLCAnbG9hZENsYXNzJyksIHRydWUsICRwcmVwZW5kKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT52ZW5kb3JEaXIpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwcmVwZW5kKSB7CiAgICAgICAgICAgIHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVycyA9IGFycmF5KCR0aGlzLT52ZW5kb3JEaXIgPT4gJHRoaXMpICsgc2VsZjo6JHJlZ2lzdGVyZWRMb2FkZXJzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVuc2V0KHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyc1skdGhpcy0+dmVuZG9yRGlyXSk7CiAgICAgICAgICAgIHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyc1skdGhpcy0+dmVuZG9yRGlyXSA9ICR0aGlzOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFVucmVnaXN0ZXJzIHRoaXMgaW5zdGFuY2UgYXMgYW4gYXV0b2xvYWRlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVucmVnaXN0ZXIoKQogICAgewogICAgICAgIHNwbF9hdXRvbG9hZF91bnJlZ2lzdGVyKGFycmF5KCR0aGlzLCAnbG9hZENsYXNzJykpOwoKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnZlbmRvckRpcikgewogICAgICAgICAgICB1bnNldChzZWxmOjokcmVnaXN0ZXJlZExvYWRlcnNbJHRoaXMtPnZlbmRvckRpcl0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIExvYWRzIHRoZSBnaXZlbiBjbGFzcyBvciBpbnRlcmZhY2UuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgJGNsYXNzIFRoZSBuYW1lIG9mIHRoZSBjbGFzcwogICAgICogQHJldHVybiBib29sfG51bGwgVHJ1ZSBpZiBsb2FkZWQsIG51bGwgb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkQ2xhc3MoJGNsYXNzKQogICAgewogICAgICAgIGlmICgkZmlsZSA9ICR0aGlzLT5maW5kRmlsZSgkY2xhc3MpKSB7CiAgICAgICAgICAgIGluY2x1ZGVGaWxlKCRmaWxlKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBwYXRoIHRvIHRoZSBmaWxlIHdoZXJlIHRoZSBjbGFzcyBpcyBkZWZpbmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzIFRoZSBuYW1lIG9mIHRoZSBjbGFzcwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIFRoZSBwYXRoIGlmIGZvdW5kLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRGaWxlKCRjbGFzcykKICAgIHsKICAgICAgICAvLyBjbGFzcyBtYXAgbG9va3VwCiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5jbGFzc01hcFskY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNsYXNzTWFwWyRjbGFzc107CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+Y2xhc3NNYXBBdXRob3JpdGF0aXZlIHx8IGlzc2V0KCR0aGlzLT5taXNzaW5nQ2xhc3Nlc1skY2xhc3NdKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICAkZmlsZSA9IGFwY3VfZmV0Y2goJHRoaXMtPmFwY3VQcmVmaXguJGNsYXNzLCAkaGl0KTsKICAgICAgICAgICAgaWYgKCRoaXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGZpbGUgPSAkdGhpcy0+ZmluZEZpbGVXaXRoRXh0ZW5zaW9uKCRjbGFzcywgJy5waHAnKTsKCiAgICAgICAgLy8gU2VhcmNoIGZvciBIYWNrIGZpbGVzIGlmIHdlIGFyZSBydW5uaW5nIG9uIEhIVk0KICAgICAgICBpZiAoZmFsc2UgPT09ICRmaWxlICYmIGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgICRmaWxlID0gJHRoaXMtPmZpbmRGaWxlV2l0aEV4dGVuc2lvbigkY2xhc3MsICcuaGgnKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+YXBjdVByZWZpeCkgewogICAgICAgICAgICBhcGN1X2FkZCgkdGhpcy0+YXBjdVByZWZpeC4kY2xhc3MsICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIGlmIChmYWxzZSA9PT0gJGZpbGUpIHsKICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhhdCB0aGlzIGNsYXNzIGRvZXMgbm90IGV4aXN0LgogICAgICAgICAgICAkdGhpcy0+bWlzc2luZ0NsYXNzZXNbJGNsYXNzXSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgcmVnaXN0ZXJlZCBsb2FkZXJzIGluZGV4ZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2ZW5kb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHJldHVybiBzZWxmW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRSZWdpc3RlcmVkTG9hZGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiRyZWdpc3RlcmVkTG9hZGVyczsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbmRGaWxlV2l0aEV4dGVuc2lvbigkY2xhc3MsICRleHQpCiAgICB7CiAgICAgICAgLy8gUFNSLTQgbG9va3VwCiAgICAgICAgJGxvZ2ljYWxQYXRoUHNyNCA9IHN0cnRyKCRjbGFzcywgJ1xcJywgRElSRUNUT1JZX1NFUEFSQVRPUikgLiAkZXh0OwoKICAgICAgICAkZmlyc3QgPSAkY2xhc3NbMF07CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5wcmVmaXhMZW5ndGhzUHNyNFskZmlyc3RdKSkgewogICAgICAgICAgICAkc3ViUGF0aCA9ICRjbGFzczsKICAgICAgICAgICAgd2hpbGUgKGZhbHNlICE9PSAkbGFzdFBvcyA9IHN0cnJwb3MoJHN1YlBhdGgsICdcXCcpKSB7CiAgICAgICAgICAgICAgICAkc3ViUGF0aCA9IHN1YnN0cigkc3ViUGF0aCwgMCwgJGxhc3RQb3MpOwogICAgICAgICAgICAgICAgJHNlYXJjaCA9ICRzdWJQYXRoIC4gJ1xcJzsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+cHJlZml4RGlyc1BzcjRbJHNlYXJjaF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhdGhFbmQgPSBESVJFQ1RPUllfU0VQQVJBVE9SIC4gc3Vic3RyKCRsb2dpY2FsUGF0aFBzcjQsICRsYXN0UG9zICsgMSk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByZWZpeERpcnNQc3I0WyRzZWFyY2hdIGFzICRkaXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gJGRpciAuICRwYXRoRW5kKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBQU1ItNCBmYWxsYmFjayBkaXJzCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZhbGxiYWNrRGlyc1BzcjQgYXMgJGRpcikgewogICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUgPSAkZGlyIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRsb2dpY2FsUGF0aFBzcjQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBTUi0wIGxvb2t1cAogICAgICAgIGlmIChmYWxzZSAhPT0gJHBvcyA9IHN0cnJwb3MoJGNsYXNzLCAnXFwnKSkgewogICAgICAgICAgICAvLyBuYW1lc3BhY2VkIGNsYXNzIG5hbWUKICAgICAgICAgICAgJGxvZ2ljYWxQYXRoUHNyMCA9IHN1YnN0cigkbG9naWNhbFBhdGhQc3I0LCAwLCAkcG9zICsgMSkKICAgICAgICAgICAgICAgIC4gc3RydHIoc3Vic3RyKCRsb2dpY2FsUGF0aFBzcjQsICRwb3MgKyAxKSwgJ18nLCBESVJFQ1RPUllfU0VQQVJBVE9SKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBQRUFSLWxpa2UgY2xhc3MgbmFtZQogICAgICAgICAgICAkbG9naWNhbFBhdGhQc3IwID0gc3RydHIoJGNsYXNzLCAnXycsIERJUkVDVE9SWV9TRVBBUkFUT1IpIC4gJGV4dDsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+cHJlZml4ZXNQc3IwWyRmaXJzdF0pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wcmVmaXhlc1BzcjBbJGZpcnN0XSBhcyAkcHJlZml4ID0+ICRkaXJzKSB7CiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRjbGFzcywgJHByZWZpeCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGlycyBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlX2V4aXN0cygkZmlsZSA9ICRkaXIgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJGxvZ2ljYWxQYXRoUHNyMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUFNSLTAgZmFsbGJhY2sgZGlycwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5mYWxsYmFja0RpcnNQc3IwIGFzICRkaXIpIHsKICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gJGRpciAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkbG9naWNhbFBhdGhQc3IwKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBQU1ItMCBpbmNsdWRlIHBhdGhzLgogICAgICAgIGlmICgkdGhpcy0+dXNlSW5jbHVkZVBhdGggJiYgJGZpbGUgPSBzdHJlYW1fcmVzb2x2ZV9pbmNsdWRlX3BhdGgoJGxvZ2ljYWxQYXRoUHNyMCkpIHsKICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9CgovKioKICogU2NvcGUgaXNvbGF0ZWQgaW5jbHVkZS4KICoKICogUHJldmVudHMgYWNjZXNzIHRvICR0aGlzL3NlbGYgZnJvbSBpbmNsdWRlZCBmaWxlcy4KICovCmZ1bmN0aW9uIGluY2x1ZGVGaWxlKCRmaWxlKQp7CiAgICBpbmNsdWRlICRmaWxlOwp9Cjw/cGhwIHJldHVybiBhcnJheSAoCiAgJ3Jvb3QnID0+IAogIGFycmF5ICgKICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ2Rldi1yZWxlYXNlLTItNS0wJywKICAgICd2ZXJzaW9uJyA9PiAnZGV2LXJlbGVhc2UtMi01LTAnLAogICAgJ2FsaWFzZXMnID0+IAogICAgYXJyYXkgKAogICAgKSwKICAgICdyZWZlcmVuY2UnID0+ICc1MDA1ODBjYzc0MGU5MmEyYjkyZGMyNmVlZWM5ZjA0NmExYWNhZTZkJywKICAgICduYW1lJyA9PiAnd3AtY2xpL3dwLWNsaS1idW5kbGUnLAogICksCiAgJ3ZlcnNpb25zJyA9PiAKICBhcnJheSAoCiAgICAnY29tcG9zZXIvY2EtYnVuZGxlJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4yLjknLAogICAgICAndmVyc2lvbicgPT4gJzEuMi45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzc4YTBlMjg4ZmRjZWJmOTJhYTIzMThhOGQzNjU2MTY4ZGE2YWMxYTUnLAogICAgKSwKICAgICdjb21wb3Nlci9jb21wb3NlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzIuMC4xMycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEzLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzk4NmU4Yjg2YjdiNTcwNjMyYWQwYTkwNWMzNzI2YzMzZGQ0YzBlZmInLAogICAgKSwKICAgICdjb21wb3Nlci9tZXRhZGF0YS1taW5pZmllcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuMC4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjAuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdjNTQ5ZDIzODI5NTM2ZjBkMGU5ODRhYWFiYmYwMmFmOTFmNDQzMjA3JywKICAgICksCiAgICAnY29tcG9zZXIvc2VtdmVyJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMy4yLjQnLAogICAgICAndmVyc2lvbicgPT4gJzMuMi40LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2EwMmZkZjkzMGEzYzFjM2VkM2E0OWI1ZjYzODU5YzBjMjBlMTA0NjQnLAogICAgKSwKICAgICdjb21wb3Nlci9zcGR4LWxpY2Vuc2VzJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS41LjUnLAogICAgICAndmVyc2lvbicgPT4gJzEuNS41LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2RlMzAzMjhhN2FmODY4MGVmZGMwM2UzOTZhYWQyNGJlZmQ1MTMyMDAnLAogICAgKSwKICAgICdjb21wb3Nlci94ZGVidWctaGFuZGxlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJzEuNC42JywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjQuNi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdmMjdlMDZjZDk2NzU4MDFkZjQ0MWIzNjU2NTY5YjMyOGUwNGFhMzdjJywKICAgICksCiAgICAnZ2V0dGV4dC9nZXR0ZXh0JyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjQuOC40JywKICAgICAgJ3ZlcnNpb24nID0+ICc0LjguNC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc1OGJjMGY3ZjM3ZTc4ZWZiMGY5NzU4ZjkzZDRhMGY2NjlmMGY4NGExJywKICAgICksCiAgICAnZ2V0dGV4dC9sYW5ndWFnZXMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcyLjYuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi42LjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnMzhlYTA0ODJmNjQ5ZTA4MDJlNDc1ZjBlZDE5ZmE5OTNiY2I3YTYxOCcsCiAgICApLAogICAgJ2p1c3RpbnJhaW5ib3cvanNvbi1zY2hlbWEnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICc1LjIuMTAnLAogICAgICAndmVyc2lvbicgPT4gJzUuMi4xMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyYmE5YzhjODYyZWNkNTUxMGVkMTZjNjM0MGFhOWY2ZWFkYjRmMzFiJywKICAgICksCiAgICAnbWNrODkvcGVhc3QnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS4xMi4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcxLjEyLjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnODMzYmU3YTI5NDYyN2E4YzViMWM0ODJjYmY0ODlmNzNiZjliODA4NicsCiAgICApLAogICAgJ211c3RhY2hlL211c3RhY2hlJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMTMuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xMy4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U5NWM1YTAwOGMyM2QzMTUxZDU5ZWE3MjQ4NGQ0ZjcyMDQ5YWI3ZjQnLAogICAgKSwKICAgICduYi9veHltZWwnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MC4xLjAnLAogICAgICAndmVyc2lvbicgPT4gJzAuMS4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2NiZTYyNmVmNTVkNWM0Y2M5YjVlNmUzOTA0YjM5NTg2MWVhNzZlM2MnLAogICAgKSwKICAgICdwc3IvbG9nJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS4xLjQnLAogICAgICAndmVyc2lvbicgPT4gJzEuMS40LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2Q0OTY5NWI5MDljM2I3NjI4YjYyODlkYjU0NzlhMWMyMDQ2MDFmMTEnLAogICAgKSwKICAgICdwc3IvbG9nLWltcGxlbWVudGF0aW9uJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3Byb3ZpZGVkJyA9PiAKICAgICAgYXJyYXkgKAogICAgICAgIDAgPT4gJzEuMCcsCiAgICAgICksCiAgICApLAogICAgJ3JlYWN0L3Byb21pc2UnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi44LjAnLAogICAgICAndmVyc2lvbicgPT4gJzIuOC4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YzY2ZmOTZhMTk3MzY3MTQ1MjRjYTBkZDFkNDEzMGRlNzNkYmJiYzQnLAogICAgKSwKICAgICdybWNjdWUvcmVxdWVzdHMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS44LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuOC4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2FmYmU0NzkwZTRkZWYwMzU4MWM0YTA5NjNhMWU4YWEwMWY2MDMwZjEnLAogICAgKSwKICAgICdzZWxkL2pzb25saW50JyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAnMS44LjMnLAogICAgICAndmVyc2lvbicgPT4gJzEuOC4zLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzlhZDZjZTc5YzM0MmZiZDQ0ZGYxMGVhOTU1MTFhMWIyNGRlZTViNTcnLAogICAgKSwKICAgICdzZWxkL3BoYXItdXRpbHMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcxLjEuMScsCiAgICAgICd2ZXJzaW9uJyA9PiAnMS4xLjEuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnODY3NGIxZDg0ZmZiNDdjYzU5YTEwMWY1ZDVhM2I2MWU4N2QyMzc5NicsCiAgICApLAogICAgJ3N5bWZvbnkvY29uc29sZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhMTBiMWRhNmZjOTMwODBjMTgwYmJhNzIxOWI1ZmY1Yjc1MThmZTgxJywKICAgICksCiAgICAnc3ltZm9ueS9kZWJ1ZycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhYjQyODg5ZGU1N2ZkZmNmY2MwNzU5YWIxMDJlMmZkNGVhNzJkY2FlJywKICAgICksCiAgICAnc3ltZm9ueS9maWxlc3lzdGVtJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U1OGQ3ODQxY2RkZmVkNmU4NDY4MjkwNDBkY2EyY2NhMGViYmJiYjMnLAogICAgKSwKICAgICdzeW1mb255L2ZpbmRlcicgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YzLjQuNDcnLAogICAgICAndmVyc2lvbicgPT4gJzMuNC40Ny4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdiNmI2YWQzZGIzZWRiMWI0YjFjMTg5NmIxOTc1ZmI2ODQ5OTRkZTZlJywKICAgICksCiAgICAnc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjE5LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuMTkuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdhZWQ1OTY5MTNiNzBmYWU1N2JlNTNkODZmYWEyZTllZjg1YTIyOTdiJywKICAgICksCiAgICAnc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YxLjE5LjAnLAogICAgICAndmVyc2lvbicgPT4gJzEuMTkuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdiNWY3YjkzMmVlNmZhODAyZmM3OTJlYWJkNzdjNGM4ODA4NDUxN2NlJywKICAgICksCiAgICAnc3ltZm9ueS9wcm9jZXNzJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjMuNC40NycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMy40LjQ3LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2I4NjQ4Y2YxZDVhZjEyYTQ0YTUxZDA3ZWY5YmY5ODA5MjFmMTVmY2EnLAogICAgKSwKICAgICd3cC1jbGkvY2FjaGUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYmY1ZDNkMzM1ZGU1ZjlkOTMxODA2ODJmMTA3YzIzOGE4M2M0YjAyYycsCiAgICApLAogICAgJ3dwLWNsaS9jaGVja3N1bS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcwZjU4YWY5MTRhNGFmMzAxOGNlODM0NDk4NjkzMDBkNjVkZjlmNjEzJywKICAgICksCiAgICAnd3AtY2xpL2NvbmZpZy1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc0NmIwOTZlYWUyYzExNmJlZDMwYzhkNjQ5ZjZlMmExZDRkYjAzNWMxJywKICAgICksCiAgICAnd3AtY2xpL2NvcmUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjAuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYjdmNDRmMDNhM2EzNTE0Nzk4Y2RhMjFiNjFhNDE4ZjA4YWVjZTMyNCcsCiAgICApLAogICAgJ3dwLWNsaS9jcm9uLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjgnLAogICAgICAndmVyc2lvbicgPT4gJzIuMC44LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YwZDQ5M2ZmNGQ0ZjIwZWU2ZDZmZDU0OTVkYTFiYzE3NjBmOWRhMTUnLAogICAgKSwKICAgICd3cC1jbGkvZGItY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMTMnLAogICAgICAndmVyc2lvbicgPT4gJzIuMC4xMy4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyNjliZjI2YTY2OTE1ZDY1MjZiMTAxNWY3Yzc1OWZmZTA0Mzg2YmY3JywKICAgICksCiAgICAnd3AtY2xpL2VtYmVkLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2VjNzRmM2YzNGNiOWMwMjhmZDM5ZWJmOGNjYTNhMTUwNGZkNTk5YmEnLAogICAgKSwKICAgICd3cC1jbGkvZW50aXR5LWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjAnLAogICAgICAndmVyc2lvbicgPT4gJzIuMS4wLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzliM2MwMzBkNWIwNTZmM2Y3Yjg4MzVlMTE3MTM5ZjkyNzk5MzQwYTknLAogICAgKSwKICAgICd3cC1jbGkvZXZhbC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdkY2RhMDIxOTRiZDBjYTc3M2NlMDNkZWM2MDkzYWMwZDI3MWY4OTc2JywKICAgICksCiAgICAnd3AtY2xpL2V4cG9ydC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICdlOTRmNWY5ZTg0NzY4OTE5YWE2Y2QyMTkzZWIwYzhiOTk0ZTdmNGM5JywKICAgICksCiAgICAnd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMS4wJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjEuMC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc3YWQ0ZjljMGM5M2ExZWU3Mzc1MjFmODI1ZjE2MWQ0Yjc5YTQ2OTQ1JywKICAgICksCiAgICAnd3AtY2xpL2kxOG4tY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjIuOCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4yLjguMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnOGJjMjM0NjE3ZWRjNTMzNTkwYWMwZjQxMDgwMTY0YThkODVlYzljZScsCiAgICApLAogICAgJ3dwLWNsaS9pbXBvcnQtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNzVlNmQ0MjczYjRhOWRiZjUxMGQ2OWE0NGY5MzcxZWVlMGQwMTI5NCcsCiAgICApLAogICAgJ3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xMCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjEwLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzRjMDJlZjQzMWUyODI1ZWFjN2IwMmU1Y2Y0ODA0YzQ3MTY3YjZiYWYnLAogICAgKSwKICAgICd3cC1jbGkvbWFpbnRlbmFuY2UtbW9kZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC42JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuNi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyNmMxYzBhNzllZDExOTRjODYzY2I5NWZhMzY0YjRkYjc5MjlkN2NjJywKICAgICksCiAgICAnd3AtY2xpL21lZGlhLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjExJywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuMTEuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnMTY1YTQ2MmUyMzRlNTVkYjIxNzRmOWYwZjZmYWI3MjA0MGU5YzUxMCcsCiAgICApLAogICAgJ3dwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICcwLjYuMycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMC42LjMuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNmFhMGI0ZGE2OWNlOWU5YTJjODQwMmRhYjhkNDNjZjMyYzU4MWNjNycsCiAgICApLAogICAgJ3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4xLjEnLAogICAgICAndmVyc2lvbicgPT4gJzIuMS4xLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzJlMzQ1ZGY2YzY3ZDRmOWI0YmY0MmNlMTJhN2ZhMDdiMmI0NDM5OWQnLAogICAgKSwKICAgICd3cC1jbGkvcGhwLWNsaS10b29scycgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YwLjExLjEyJywKICAgICAgJ3ZlcnNpb24nID0+ICcwLjExLjEyLjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2U0NzJlMDg0ODlmNzUwNGQ5ZThjNWM1YTA1N2UxNDE5Y2QxYjJiM2UnLAogICAgKSwKICAgICd3cC1jbGkvcmV3cml0ZS1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc0NjgzNThlMDc5NDNhN2E4YmU3MGM5NWUyMGQ0NTQxMmQ4Mjg5OWFjJywKICAgICksCiAgICAnd3AtY2xpL3JvbGUtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNzQ2MDU2NmZlYmU4MmIxNGMzNGIxMDVjNGM2MzI2ZDNlMjNmOTI5NScsCiAgICApLAogICAgJ3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC4xNCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjE0LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2NkZTQ0NTI0ZmQwNDk5YzAzNjRhNWFlM2E2ZGM0OTI3OTZlODBlMGEnLAogICAgKSwKICAgICd3cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuMTInLAogICAgICAndmVyc2lvbicgPT4gJzIuMC4xMi4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICc3ZDkzYWJiZGZkMGMzMjM5MDJhYzIxZmMzNDE4NjA0MWJlNzQzZmQwJywKICAgICksCiAgICAnd3AtY2xpL3NlcnZlci1jb21tYW5kJyA9PiAKICAgIGFycmF5ICgKICAgICAgJ3ByZXR0eV92ZXJzaW9uJyA9PiAndjIuMC44JywKICAgICAgJ3ZlcnNpb24nID0+ICcyLjAuOC4wJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICksCiAgICAgICdyZWZlcmVuY2UnID0+ICcyOTk3NmFlZjVjMmJkZjE1OWI4NzAwZWFiMjZiYWZjOTQzZjBiZTBjJywKICAgICksCiAgICAnd3AtY2xpL3NoZWxsLWNvbW1hbmQnID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2Mi4wLjknLAogICAgICAndmVyc2lvbicgPT4gJzIuMC45LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJ2YyN2IzNGE4N2I1MTVkYTY0NmQyZTcwMThhOGFiYzEyNTQ0MTZmZWMnLAogICAgKSwKICAgICd3cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjAuNycsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4wLjcuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnYWQ0YmQ0ZTZiNmE1M2FmYTRiYTg2NjRhNmRkNjk1YmU2ZmViNjkyZScsCiAgICApLAogICAgJ3dwLWNsaS93aWRnZXQtY29tbWFuZCcgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ3YyLjEuNCcsCiAgICAgICd2ZXJzaW9uJyA9PiAnMi4xLjQuMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNWM3YjRlMTQ3Yjc3ZTNkNzY4YTlhMDM0NjkzZWJjN2JhMTk4MDcwNycsCiAgICApLAogICAgJ3dwLWNsaS93cC1jbGknID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICdkZXYtbWFzdGVyJywKICAgICAgJ3ZlcnNpb24nID0+ICdkZXYtbWFzdGVyJywKICAgICAgJ2FsaWFzZXMnID0+IAogICAgICBhcnJheSAoCiAgICAgICAgMCA9PiAnMi41LngtZGV2JywKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzBiY2YwYzU0ZjRkMzU2ODUyMTFkNDM1ZTI1MjE5Y2M3YWNiZTZkNDgnLAogICAgKSwKICAgICd3cC1jbGkvd3AtY2xpLWJ1bmRsZScgPT4gCiAgICBhcnJheSAoCiAgICAgICdwcmV0dHlfdmVyc2lvbicgPT4gJ2Rldi1yZWxlYXNlLTItNS0wJywKICAgICAgJ3ZlcnNpb24nID0+ICdkZXYtcmVsZWFzZS0yLTUtMCcsCiAgICAgICdhbGlhc2VzJyA9PiAKICAgICAgYXJyYXkgKAogICAgICApLAogICAgICAncmVmZXJlbmNlJyA9PiAnNTAwNTgwY2M3NDBlOTJhMmI5MmRjMjZlZWVjOWYwNDZhMWFjYWU2ZCcsCiAgICApLAogICAgJ3dwLWNsaS93cC1jb25maWctdHJhbnNmb3JtZXInID0+IAogICAgYXJyYXkgKAogICAgICAncHJldHR5X3ZlcnNpb24nID0+ICd2MS4yLjgnLAogICAgICAndmVyc2lvbicgPT4gJzEuMi44LjAnLAogICAgICAnYWxpYXNlcycgPT4gCiAgICAgIGFycmF5ICgKICAgICAgKSwKICAgICAgJ3JlZmVyZW5jZScgPT4gJzBiYjJiOTE2MmMzOGNhNzIzNzAzODBhZWExMWRjMDZlNDMxZTEzYTUnLAogICAgKSwKICApLAopOwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcTWV0YWRhdGFNaW5pZmllcjsKCmNsYXNzIE1ldGFkYXRhTWluaWZpZXIKewogICAgLyoqCiAgICAgKiBFeHBhbmRzIGFuIGFycmF5IG9mIG1pbmlmaWVkIHZlcnNpb25zIGJhY2sgdG8gdGhlaXIgb3JpZ2luYWwgZm9ybWF0CiAgICAgKgogICAgICogQHBhcmFtIGFycmF5W10gJHZlcnNpb25zIEEgbGlzdCBvZiBtaW5pZmllZCB2ZXJzaW9uIGFycmF5cwogICAgICogQHJldHVybiBhcnJheVtdIEEgbGlzdCBvZiB2ZXJzaW9uIGFycmF5cwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4cGFuZChhcnJheSAkdmVyc2lvbnMpCiAgICB7CiAgICAgICAgJGV4cGFuZGVkID0gYXJyYXkoKTsKICAgICAgICAkZXhwYW5kZWRWZXJzaW9uID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb25EYXRhKSB7CiAgICAgICAgICAgIGlmICghJGV4cGFuZGVkVmVyc2lvbikgewogICAgICAgICAgICAgICAgJGV4cGFuZGVkVmVyc2lvbiA9ICR2ZXJzaW9uRGF0YTsKICAgICAgICAgICAgICAgICRleHBhbmRlZFtdID0gJGV4cGFuZGVkVmVyc2lvbjsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBhZGQgYW55IGNoYW5nZXMgZnJvbSB0aGUgcHJldmlvdXMgdmVyc2lvbiB0byB0aGUgZXhwYW5kZWQgb25lCiAgICAgICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9uRGF0YSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgIGlmICgkdmFsID09PSAnX191bnNldCcpIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkZXhwYW5kZWRWZXJzaW9uWyRrZXldKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGV4cGFuZGVkVmVyc2lvblska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRleHBhbmRlZFtdID0gJGV4cGFuZGVkVmVyc2lvbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZXhwYW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBNaW5pZmllcyBhbiBhcnJheSBvZiB2ZXJzaW9ucyBpbnRvIGEgc2V0IG9mIHZlcnNpb24gZGlmZnMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXlbXSAkdmVyc2lvbnMgQSBsaXN0IG9mIHZlcnNpb24gYXJyYXlzCiAgICAgKiBAcmV0dXJuIGFycmF5W10gQSBsaXN0IG9mIHZlcnNpb25zIG1pbmlmaWVkIHdpdGggZWFjaCBhcnJheSBvbmx5IGNvbnRhaW5pbmcgdGhlIGRpZmZlcmVuY2VzIHRvIHRoZSBwcmV2aW91cyBvbmUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtaW5pZnkoYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgICRtaW5pZmllZFZlcnNpb25zID0gYXJyYXkoKTsKCiAgICAgICAgJGxhc3RLbm93blZlcnNpb25EYXRhID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkdmVyc2lvbnMgYXMgJHZlcnNpb24pIHsKICAgICAgICAgICAgaWYgKCEkbGFzdEtub3duVmVyc2lvbkRhdGEpIHsKICAgICAgICAgICAgICAgICRsYXN0S25vd25WZXJzaW9uRGF0YSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgJG1pbmlmaWVkVmVyc2lvbnNbXSA9ICR2ZXJzaW9uOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtaW5pZmllZFZlcnNpb24gPSBhcnJheSgpOwoKICAgICAgICAgICAgLy8gYWRkIGFueSBjaGFuZ2VzIGZyb20gdGhlIHByZXZpb3VzIHZlcnNpb24KICAgICAgICAgICAgZm9yZWFjaCAoJHZlcnNpb24gYXMgJGtleSA9PiAkdmFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRsYXN0S25vd25WZXJzaW9uRGF0YVska2V5XSkgfHwgJGxhc3RLbm93blZlcnNpb25EYXRhWyRrZXldICE9PSAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgJG1pbmlmaWVkVmVyc2lvblska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICAgICAgJGxhc3RLbm93blZlcnNpb25EYXRhWyRrZXldID0gJHZhbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3RvcmUgYW55IGRlbGV0aW9ucyBmcm9tIHRoZSBwcmV2aW91cyB2ZXJzaW9uIGZvciBrZXlzIG1pc3NpbmcgaW4gY3VycmVudCBvbmUKICAgICAgICAgICAgZm9yZWFjaCAoJGxhc3RLbm93blZlcnNpb25EYXRhIGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdmVyc2lvblska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkbWluaWZpZWRWZXJzaW9uWyRrZXldID0gIl9fdW5zZXQiOwogICAgICAgICAgICAgICAgICAgIHVuc2V0KCRsYXN0S25vd25WZXJzaW9uRGF0YVska2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtaW5pZmllZFZlcnNpb25zW10gPSAkbWluaWZpZWRWZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtaW5pZmllZFZlcnNpb25zOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnRJbnRlcmZhY2U7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNYXRjaEFsbENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxNdWx0aUNvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKLyoqCiAqIFZlcnNpb24gcGFyc2VyLgogKgogKiBAYXV0aG9yIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqLwpjbGFzcyBWZXJzaW9uUGFyc2VyCnsKICAgIC8qKgogICAgICogUmVnZXggdG8gbWF0Y2ggcHJlLXJlbGVhc2UgZGF0YSAoc29ydCBvZikuCiAgICAgKgogICAgICogRHVlIHRvIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5OgogICAgICogICAtIEluc3RlYWQgb2YgZW5mb3JjaW5nIGh5cGhlbiwgYW4gdW5kZXJzY29yZSwgZG90IG9yIG5vdGhpbmcgYXQgYWxsIGFyZSBhbHNvIGFjY2VwdGVkLgogICAgICogICAtIE9ubHkgc3RhYmlsaXRpZXMgYXMgcmVjb2duaXplZCBieSBDb21wb3NlciBhcmUgYWxsb3dlZCB0byBwcmVjZWRlIGEgbnVtZXJpY2FsIGlkZW50aWZpZXIuCiAgICAgKiAgIC0gTnVtZXJpY2FsLW9ubHkgcHJlLXJlbGVhc2UgaWRlbnRpZmllcnMgYXJlIG5vdCBzdXBwb3J0ZWQsIHNlZSB0ZXN0cy4KICAgICAqCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLXwKICAgICAqIFttYWpvcl0uW21pbm9yXS5bcGF0Y2hdIC1bcHJlLXJlbGVhc2VdICtbYnVpbGQtbWV0YWRhdGFdCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJG1vZGlmaWVyUmVnZXggPSAnWy5fLV0/KD86KHN0YWJsZXxiZXRhfGJ8UkN8YWxwaGF8YXxwYXRjaHxwbHxwKSgoPzpbLi1dP1xkKykqKyk/KT8oWy4tXT9kZXYpPyc7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlIHN0YXRpYyAkc3RhYmlsaXRpZXNSZWdleCA9ICdzdGFibGV8UkN8YmV0YXxhbHBoYXxkZXYnOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhYmlsaXR5IG9mIGEgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwYXJzZVN0YWJpbGl0eSgkdmVyc2lvbikKICAgIHsKICAgICAgICAkdmVyc2lvbiA9IHByZWdfcmVwbGFjZSgneyMuKyR9JywgJycsICR2ZXJzaW9uKTsKCiAgICAgICAgaWYgKHN0cnBvcygkdmVyc2lvbiwgJ2Rldi0nKSA9PT0gMCB8fCAnLWRldicgPT09IHN1YnN0cigkdmVyc2lvbiwgLTQpKSB7CiAgICAgICAgICAgIHJldHVybiAnZGV2JzsKICAgICAgICB9CgogICAgICAgIHByZWdfbWF0Y2goJ3snIC4gc2VsZjo6JG1vZGlmaWVyUmVnZXggLiAnKD86XCsuKik/JH1pJywgc3RydG9sb3dlcigkdmVyc2lvbiksICRtYXRjaCk7CgogICAgICAgIGlmICghZW1wdHkoJG1hdGNoWzNdKSkgewogICAgICAgICAgICByZXR1cm4gJ2Rldic7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsxXSkpIHsKICAgICAgICAgICAgaWYgKCdiZXRhJyA9PT0gJG1hdGNoWzFdIHx8ICdiJyA9PT0gJG1hdGNoWzFdKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJ2JldGEnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgnYWxwaGEnID09PSAkbWF0Y2hbMV0gfHwgJ2EnID09PSAkbWF0Y2hbMV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAnYWxwaGEnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgncmMnID09PSAkbWF0Y2hbMV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAnUkMnOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJ3N0YWJsZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGFiaWxpdHkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG5vcm1hbGl6ZVN0YWJpbGl0eSgkc3RhYmlsaXR5KQogICAgewogICAgICAgICRzdGFiaWxpdHkgPSBzdHJ0b2xvd2VyKCRzdGFiaWxpdHkpOwoKICAgICAgICByZXR1cm4gJHN0YWJpbGl0eSA9PT0gJ3JjJyA/ICdSQycgOiAkc3RhYmlsaXR5OwogICAgfQoKICAgIC8qKgogICAgICogTm9ybWFsaXplcyBhIHZlcnNpb24gc3RyaW5nIHRvIGJlIGFibGUgdG8gcGVyZm9ybSBjb21wYXJpc29ucyBvbiBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmdWxsVmVyc2lvbiBvcHRpb25hbCBjb21wbGV0ZSB2ZXJzaW9uIHN0cmluZyB0byBnaXZlIG1vcmUgY29udGV4dAogICAgICoKICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3JtYWxpemUoJHZlcnNpb24sICRmdWxsVmVyc2lvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJHZlcnNpb24gPSB0cmltKCR2ZXJzaW9uKTsKICAgICAgICAkb3JpZ1ZlcnNpb24gPSAkdmVyc2lvbjsKICAgICAgICBpZiAobnVsbCA9PT0gJGZ1bGxWZXJzaW9uKSB7CiAgICAgICAgICAgICRmdWxsVmVyc2lvbiA9ICR2ZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgLy8gc3RyaXAgb2ZmIGFsaWFzaW5nCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFteLFxzXSsrKSArK2FzICsrKFteLFxzXSsrKSR9JywgJHZlcnNpb24sICRtYXRjaCkpIHsKICAgICAgICAgICAgJHZlcnNpb24gPSAkbWF0Y2hbMV07CiAgICAgICAgfQoKICAgICAgICAvLyBzdHJpcCBvZmYgc3RhYmlsaXR5IGZsYWcKICAgICAgICBpZiAocHJlZ19tYXRjaCgne0AoPzonIC4gc2VsZjo6JHN0YWJpbGl0aWVzUmVnZXggLiAnKSR9aScsICR2ZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gc3Vic3RyKCR2ZXJzaW9uLCAwLCBzdHJsZW4oJHZlcnNpb24pIC0gc3RybGVuKCRtYXRjaFswXSkpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm9ybWFsaXplIG1hc3Rlci90cnVuay9kZWZhdWx0IGJyYW5jaGVzIHRvIGRldi1uYW1lIGZvciBCQyB3aXRoIDEueCBhcyB0aGVzZSB1c2VkIHRvIGJlIHZhbGlkIGNvbnN0cmFpbnRzCiAgICAgICAgaWYgKFxpbl9hcnJheSgkdmVyc2lvbiwgYXJyYXkoJ21hc3RlcicsICd0cnVuaycsICdkZWZhdWx0JyksIHRydWUpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJ2Rldi0nIC4gJHZlcnNpb247CiAgICAgICAgfQoKICAgICAgICAvLyBpZiByZXF1aXJlbWVudCBpcyBicmFuY2gtbGlrZSwgdXNlIGZ1bGwgbmFtZQogICAgICAgIGlmIChzdHJpcG9zKCR2ZXJzaW9uLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAnZGV2LScgLiBzdWJzdHIoJHZlcnNpb24sIDQpOwogICAgICAgIH0KCiAgICAgICAgLy8gc3RyaXAgb2ZmIGJ1aWxkIG1ldGFkYXRhCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFteLFxzK10rKylcK1teXHNdKyskfScsICR2ZXJzaW9uLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJG1hdGNoWzFdOwogICAgICAgIH0KCiAgICAgICAgLy8gbWF0Y2ggY2xhc3NpY2FsIHZlcnNpb25pbmcKICAgICAgICBpZiAocHJlZ19tYXRjaCgne152PyhcZHsxLDV9KShcLlxkKyspPyhcLlxkKyspPyhcLlxkKyspPycgLiBzZWxmOjokbW9kaWZpZXJSZWdleCAuICckfWknLCAkdmVyc2lvbiwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICR2ZXJzaW9uID0gJG1hdGNoZXNbMV0KICAgICAgICAgICAgICAgIC4gKCFlbXB0eSgkbWF0Y2hlc1syXSkgPyAkbWF0Y2hlc1syXSA6ICcuMCcpCiAgICAgICAgICAgICAgICAuICghZW1wdHkoJG1hdGNoZXNbM10pID8gJG1hdGNoZXNbM10gOiAnLjAnKQogICAgICAgICAgICAgICAgLiAoIWVtcHR5KCRtYXRjaGVzWzRdKSA/ICRtYXRjaGVzWzRdIDogJy4wJyk7CiAgICAgICAgICAgICRpbmRleCA9IDU7CiAgICAgICAgLy8gbWF0Y2ggZGF0ZSh0aW1lKSBiYXNlZCB2ZXJzaW9uaW5nCiAgICAgICAgfSBlbHNlaWYgKHByZWdfbWF0Y2goJ3tedj8oXGR7NH0oPzpbLjotXT9cZHsyfSl7MSw2fSg/OlsuOi1dP1xkezEsM30pPyknIC4gc2VsZjo6JG1vZGlmaWVyUmVnZXggLiAnJH1pJywgJHZlcnNpb24sICRtYXRjaGVzKSkgewogICAgICAgICAgICAkdmVyc2lvbiA9IHByZWdfcmVwbGFjZSgne1xEfScsICcuJywgJG1hdGNoZXNbMV0pOwogICAgICAgICAgICAkaW5kZXggPSAyOwogICAgICAgIH0KCiAgICAgICAgLy8gYWRkIHZlcnNpb24gbW9kaWZpZXJzIGlmIGEgdmVyc2lvbiB3YXMgbWF0Y2hlZAogICAgICAgIGlmIChpc3NldCgkaW5kZXgpKSB7CiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoZXNbJGluZGV4XSkpIHsKICAgICAgICAgICAgICAgIGlmICgnc3RhYmxlJyA9PT0gJG1hdGNoZXNbJGluZGV4XSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdmVyc2lvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2ZXJzaW9uIC49ICctJyAuICR0aGlzLT5leHBhbmRTdGFiaWxpdHkoJG1hdGNoZXNbJGluZGV4XSkgLiAoaXNzZXQoJG1hdGNoZXNbJGluZGV4ICsgMV0pICYmICcnICE9PSAkbWF0Y2hlc1skaW5kZXggKyAxXSA/IGx0cmltKCRtYXRjaGVzWyRpbmRleCArIDFdLCAnLi0nKSA6ICcnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hlc1skaW5kZXggKyAyXSkpIHsKICAgICAgICAgICAgICAgICR2ZXJzaW9uIC49ICctZGV2JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR2ZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgLy8gbWF0Y2ggZGV2IGJyYW5jaGVzCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3soLio/KVsuLV0/ZGV2JH1pJywgJHZlcnNpb24sICRtYXRjaCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRub3JtYWxpemVkID0gJHRoaXMtPm5vcm1hbGl6ZUJyYW5jaCgkbWF0Y2hbMV0pOwogICAgICAgICAgICAgICAgLy8gYSBicmFuY2ggZW5kaW5nIHdpdGggLWRldiBpcyBvbmx5IHZhbGlkIGlmIGl0IGlzIG51bWVyaWMKICAgICAgICAgICAgICAgIC8vIGlmIGl0IGdldHMgcHJlZml4ZWQgd2l0aCBkZXYtIGl0IG1lYW5zIHRoZSBicmFuY2ggbmFtZSBzaG91bGQKICAgICAgICAgICAgICAgIC8vIGhhdmUgaGFkIGEgZGV2LSBwcmVmaXggYWxyZWFkeSB3aGVuIHBhc3NlZCB0byBub3JtYWxpemUKICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJG5vcm1hbGl6ZWQsICdkZXYtJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRub3JtYWxpemVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRleHRyYU1lc3NhZ2UgPSAnJzsKICAgICAgICBpZiAocHJlZ19tYXRjaCgneyArYXMgKycgLiBwcmVnX3F1b3RlKCR2ZXJzaW9uKSAuICcoPzpAKD86Jy5zZWxmOjokc3RhYmlsaXRpZXNSZWdleC4nKSk/JH0nLCAkZnVsbFZlcnNpb24pKSB7CiAgICAgICAgICAgICRleHRyYU1lc3NhZ2UgPSAnIGluICInIC4gJGZ1bGxWZXJzaW9uIC4gJyIsIHRoZSBhbGlhcyBtdXN0IGJlIGFuIGV4YWN0IHZlcnNpb24nOwogICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCd7XicgLiBwcmVnX3F1b3RlKCR2ZXJzaW9uKSAuICcoPzpAKD86Jy5zZWxmOjokc3RhYmlsaXRpZXNSZWdleC4nKSk/ICthcyArfScsICRmdWxsVmVyc2lvbikpIHsKICAgICAgICAgICAgJGV4dHJhTWVzc2FnZSA9ICcgaW4gIicgLiAkZnVsbFZlcnNpb24gLiAnIiwgdGhlIGFsaWFzIHNvdXJjZSBtdXN0IGJlIGFuIGV4YWN0IHZlcnNpb24sIGlmIGl0IGlzIGEgYnJhbmNoIG5hbWUgeW91IHNob3VsZCBwcmVmaXggaXQgd2l0aCBkZXYtJzsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdJbnZhbGlkIHZlcnNpb24gc3RyaW5nICInIC4gJG9yaWdWZXJzaW9uIC4gJyInIC4gJGV4dHJhTWVzc2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IG51bWVyaWMgcHJlZml4IGZyb20gYWxpYXMsIGlmIGl0IGlzIGluIG51bWVyaWMgZm9ybWF0LCBzdWl0YWJsZSBmb3IgdmVyc2lvbiBjb21wYXJpc29uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJyYW5jaCBCcmFuY2ggbmFtZSAoZS5nLiAyLjEueC1kZXYpCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UgTnVtZXJpYyBwcmVmaXggaWYgcHJlc2VudCAoZS5nLiAyLjEuKSBvciBmYWxzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VOdW1lcmljQWxpYXNQcmVmaXgoJGJyYW5jaCkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oP1A8dmVyc2lvbj4oXGQrK1xcLikqXGQrKykoPzpcLngpPy1kZXYkfWknLCAkYnJhbmNoLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWyd2ZXJzaW9uJ10gLiAnLic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWxpemVzIGEgYnJhbmNoIG5hbWUgdG8gYmUgYWJsZSB0byBwZXJmb3JtIGNvbXBhcmlzb25zIG9uIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm9ybWFsaXplQnJhbmNoKCRuYW1lKQogICAgewogICAgICAgICRuYW1lID0gdHJpbSgkbmFtZSk7CgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XnY/KFxkKyspKFwuKD86XGQrK3xbeFgqXSkpPyhcLig/OlxkKyt8W3hYKl0pKT8oXC4oPzpcZCsrfFt4WCpdKSk/JH1pJywgJG5hbWUsICRtYXRjaGVzKSkgewogICAgICAgICAgICAkdmVyc2lvbiA9ICcnOwogICAgICAgICAgICBmb3IgKCRpID0gMTsgJGkgPCA1OyArKyRpKSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiAuPSBpc3NldCgkbWF0Y2hlc1skaV0pID8gc3RyX3JlcGxhY2UoYXJyYXkoJyonLCAnWCcpLCAneCcsICRtYXRjaGVzWyRpXSkgOiAnLngnOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJ3gnLCAnOTk5OTk5OScsICR2ZXJzaW9uKSAuICctZGV2JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnZGV2LScgLiAkbmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZXMgYSBkZWZhdWx0IGJyYW5jaCBuYW1lIChpLmUuIG1hc3RlciBvbiBnaXQpIHRvIDk5OTk5OTktZGV2LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm9ybWFsaXplRGVmYXVsdEJyYW5jaCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoJG5hbWUgPT09ICdkZXYtbWFzdGVyJyB8fCAkbmFtZSA9PT0gJ2Rldi1kZWZhdWx0JyB8fCAkbmFtZSA9PT0gJ2Rldi10cnVuaycpIHsKICAgICAgICAgICAgcmV0dXJuICc5OTk5OTk5LWRldic7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjb25zdHJhaW50IHN0cmluZyBpbnRvIE11bHRpQ29uc3RyYWludCBhbmQvb3IgQ29uc3RyYWludCBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN0cmFpbnRzCiAgICAgKgogICAgICogQHJldHVybiBDb25zdHJhaW50SW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUNvbnN0cmFpbnRzKCRjb25zdHJhaW50cykKICAgIHsKICAgICAgICAkcHJldHR5Q29uc3RyYWludCA9ICRjb25zdHJhaW50czsKCiAgICAgICAgJG9yQ29uc3RyYWludHMgPSBwcmVnX3NwbGl0KCd7XHMqXHxcfD9ccyp9JywgdHJpbSgkY29uc3RyYWludHMpKTsKICAgICAgICAkb3JHcm91cHMgPSBhcnJheSgpOwoKICAgICAgICBmb3JlYWNoICgkb3JDb25zdHJhaW50cyBhcyAkY29uc3RyYWludHMpIHsKICAgICAgICAgICAgJGFuZENvbnN0cmFpbnRzID0gcHJlZ19zcGxpdCgneyg/PCFefGFzfFs9PjwgLF0pICooPzwhLSlbLCBdKD8hLSkgKig/ISx8YXN8JCl9JywgJGNvbnN0cmFpbnRzKTsKICAgICAgICAgICAgaWYgKFxjb3VudCgkYW5kQ29uc3RyYWludHMpID4gMSkgewogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRPYmplY3RzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhbmRDb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYXJzZUNvbnN0cmFpbnQoJGNvbnN0cmFpbnQpIGFzICRwYXJzZWRDb25zdHJhaW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50T2JqZWN0c1tdID0gJHBhcnNlZENvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRPYmplY3RzID0gJHRoaXMtPnBhcnNlQ29uc3RyYWludCgkYW5kQ29uc3RyYWludHNbMF0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoMSA9PT0gXGNvdW50KCRjb25zdHJhaW50T2JqZWN0cykpIHsKICAgICAgICAgICAgICAgICRjb25zdHJhaW50ID0gJGNvbnN0cmFpbnRPYmplY3RzWzBdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSBuZXcgTXVsdGlDb25zdHJhaW50KCRjb25zdHJhaW50T2JqZWN0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRvckdyb3Vwc1tdID0gJGNvbnN0cmFpbnQ7CiAgICAgICAgfQoKICAgICAgICAkY29uc3RyYWludCA9IE11bHRpQ29uc3RyYWludDo6Y3JlYXRlKCRvckdyb3VwcywgZmFsc2UpOwoKICAgICAgICAkY29uc3RyYWludC0+c2V0UHJldHR5U3RyaW5nKCRwcmV0dHlDb25zdHJhaW50KTsKCiAgICAgICAgcmV0dXJuICRjb25zdHJhaW50OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3RyYWludAogICAgICoKICAgICAqIEB0aHJvd3MgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZUNvbnN0cmFpbnQoJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgLy8gc3RyaXAgb2ZmIGFsaWFzaW5nCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFteLFxzXSsrKSArK2FzICsrKFteLFxzXSsrKSR9JywgJGNvbnN0cmFpbnQsICRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkbWF0Y2hbMV07CiAgICAgICAgfQoKICAgICAgICAvLyBzdHJpcCBAc3RhYmlsaXR5IGZsYWdzLCBhbmQga2VlcCBpdCBmb3IgbGF0ZXIgdXNlCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teKFteLFxzXSo/KUAoJyAuIHNlbGY6OiRzdGFiaWxpdGllc1JlZ2V4IC4gJykkfWknLCAkY29uc3RyYWludCwgJG1hdGNoKSkgewogICAgICAgICAgICAkY29uc3RyYWludCA9ICcnICE9PSAkbWF0Y2hbMV0gPyAkbWF0Y2hbMV0gOiAnKic7CiAgICAgICAgICAgIGlmICgkbWF0Y2hbMl0gIT09ICdzdGFibGUnKSB7CiAgICAgICAgICAgICAgICAkc3RhYmlsaXR5TW9kaWZpZXIgPSAkbWF0Y2hbMl07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGdldCByaWQgb2YgI3JlZnMgYXMgdGhvc2UgYXJlIHVzZWQgYnkgY29tcG9zZXIgb25seQogICAgICAgIGlmIChwcmVnX21hdGNoKCd7XihkZXYtW14sXHNAXSs/fFteLFxzQF0rP1wueC1kZXYpIy4rJH1pJywgJGNvbnN0cmFpbnQsICRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbnN0cmFpbnQgPSAkbWF0Y2hbMV07CiAgICAgICAgfQoKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14odik/W3hYKl0oXC5beFgqXSkqJH1pJywgJGNvbnN0cmFpbnQsICRtYXRjaCkpIHsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbMV0pIHx8ICFlbXB0eSgkbWF0Y2hbMl0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkobmV3IENvbnN0cmFpbnQoJz49JywgJzAuMC4wLjAtZGV2JykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkobmV3IE1hdGNoQWxsQ29uc3RyYWludCgpKTsKICAgICAgICB9CgogICAgICAgICR2ZXJzaW9uUmVnZXggPSAndj8oXGQrKykoPzpcLihcZCsrKSk/KD86XC4oXGQrKykpPyg/OlwuKFxkKyspKT8oPzonIC4gc2VsZjo6JG1vZGlmaWVyUmVnZXggLiAnfFwuKFt4WCpdWy4tXT9kZXYpKSg/OlwrW15cc10rKT8nOwoKICAgICAgICAvLyBUaWxkZSBSYW5nZQogICAgICAgIC8vCiAgICAgICAgLy8gTGlrZSB3aWxkY2FyZCBjb25zdHJhaW50cywgdW5zdWZmaXhlZCB0aWxkZSBjb25zdHJhaW50cyBzYXkgdGhhdCB0aGV5IG11c3QgYmUgZ3JlYXRlciB0aGFuIHRoZSBwcmV2aW91cwogICAgICAgIC8vIHZlcnNpb24sIHRvIGVuc3VyZSB0aGF0IHVuc3RhYmxlIGluc3RhbmNlcyBvZiB0aGUgY3VycmVudCB2ZXJzaW9uIGFyZSBhbGxvd2VkLiBIb3dldmVyLCBpZiBhIHN0YWJpbGl0eQogICAgICAgIC8vIHN1ZmZpeCBpcyBhZGRlZCB0byB0aGUgY29uc3RyYWludCwgdGhlbiBhID49IG1hdGNoIG9uIHRoZSBjdXJyZW50IHZlcnNpb24gaXMgdXNlZCBpbnN0ZWFkLgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xn4+PycgLiAkdmVyc2lvblJlZ2V4IC4gJyR9aScsICRjb25zdHJhaW50LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkY29uc3RyYWludCwgJ34+JykgPT09IDApIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICdDb3VsZCBub3QgcGFyc2UgdmVyc2lvbiBjb25zdHJhaW50ICcgLiAkY29uc3RyYWludCAuICc6ICcgLgogICAgICAgICAgICAgICAgICAgICdJbnZhbGlkIG9wZXJhdG9yICJ+PiIsIHlvdSBwcm9iYWJseSBtZWFudCB0byB1c2UgdGhlICJ+IiBvcGVyYXRvcicKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFdvcmsgb3V0IHdoaWNoIHBvc2l0aW9uIGluIHRoZSB2ZXJzaW9uIHdlIGFyZSBvcGVyYXRpbmcgYXQKICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWzRdKSAmJiAnJyAhPT0gJG1hdGNoZXNbNF0gJiYgbnVsbCAhPT0gJG1hdGNoZXNbNF0pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDQ7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkbWF0Y2hlc1szXSkgJiYgJycgIT09ICRtYXRjaGVzWzNdICYmIG51bGwgIT09ICRtYXRjaGVzWzNdKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAzOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJG1hdGNoZXNbMl0pICYmICcnICE9PSAkbWF0Y2hlc1syXSAmJiBudWxsICE9PSAkbWF0Y2hlc1syXSkgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHdoZW4gbWF0Y2hpbmcgMi54LWRldiBvciAzLjAueC1kZXYgd2UgaGF2ZSB0byBzaGlmdCB0aGUgc2Vjb25kIG9yIHRoaXJkIG51bWJlciwgZGVzcGl0ZSBubyBzZWNvbmQvdGhpcmQgbnVtYmVyIG1hdGNoaW5nIGFib3ZlCiAgICAgICAgICAgIGlmICghZW1wdHkoJG1hdGNoZXNbOF0pKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24rKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBzdGFiaWxpdHkgc3VmZml4CiAgICAgICAgICAgICRzdGFiaWxpdHlTdWZmaXggPSAnJzsKICAgICAgICAgICAgaWYgKGVtcHR5KCRtYXRjaGVzWzVdKSAmJiBlbXB0eSgkbWF0Y2hlc1s3XSkgJiYgZW1wdHkoJG1hdGNoZXNbOF0pKSB7CiAgICAgICAgICAgICAgICAkc3RhYmlsaXR5U3VmZml4IC49ICctZGV2JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxvd1ZlcnNpb24gPSAkdGhpcy0+bm9ybWFsaXplKHN1YnN0cigkY29uc3RyYWludCAuICRzdGFiaWxpdHlTdWZmaXgsIDEpKTsKICAgICAgICAgICAgJGxvd2VyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPj0nLCAkbG93VmVyc2lvbik7CgogICAgICAgICAgICAvLyBGb3IgdXBwZXIgYm91bmQsIHdlIGluY3JlbWVudCB0aGUgcG9zaXRpb24gb2Ygb25lIG1vcmUgc2lnbmlmaWNhbmNlLAogICAgICAgICAgICAvLyBidXQgaGlnaFBvc2l0aW9uID0gMCB3b3VsZCBiZSBpbGxlZ2FsCiAgICAgICAgICAgICRoaWdoUG9zaXRpb24gPSBtYXgoMSwgJHBvc2l0aW9uIC0gMSk7CiAgICAgICAgICAgICRoaWdoVmVyc2lvbiA9ICR0aGlzLT5tYW5pcHVsYXRlVmVyc2lvblN0cmluZygkbWF0Y2hlcywgJGhpZ2hQb3NpdGlvbiwgMSkgLiAnLWRldic7CiAgICAgICAgICAgICR1cHBlckJvdW5kID0gbmV3IENvbnN0cmFpbnQoJzwnLCAkaGlnaFZlcnNpb24pOwoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgJGxvd2VyQm91bmQsCiAgICAgICAgICAgICAgICAkdXBwZXJCb3VuZCwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIC8vIENhcmV0IFJhbmdlCiAgICAgICAgLy8KICAgICAgICAvLyBBbGxvd3MgY2hhbmdlcyB0aGF0IGRvIG5vdCBtb2RpZnkgdGhlIGxlZnQtbW9zdCBub24temVybyBkaWdpdCBpbiB0aGUgW21ham9yLCBtaW5vciwgcGF0Y2hdIHR1cGxlLgogICAgICAgIC8vIEluIG90aGVyIHdvcmRzLCB0aGlzIGFsbG93cyBwYXRjaCBhbmQgbWlub3IgdXBkYXRlcyBmb3IgdmVyc2lvbnMgMS4wLjAgYW5kIGFib3ZlLCBwYXRjaCB1cGRhdGVzIGZvcgogICAgICAgIC8vIHZlcnNpb25zIDAuWCA+PTAuMS4wLCBhbmQgbm8gdXBkYXRlcyBmb3IgdmVyc2lvbnMgMC4wLlgKICAgICAgICBpZiAocHJlZ19tYXRjaCgne15cXicgLiAkdmVyc2lvblJlZ2V4IC4gJygkKX1pJywgJGNvbnN0cmFpbnQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAvLyBXb3JrIG91dCB3aGljaCBwb3NpdGlvbiBpbiB0aGUgdmVyc2lvbiB3ZSBhcmUgb3BlcmF0aW5nIGF0CiAgICAgICAgICAgIGlmICgnMCcgIT09ICRtYXRjaGVzWzFdIHx8ICcnID09PSAkbWF0Y2hlc1syXSB8fCBudWxsID09PSAkbWF0Y2hlc1syXSkgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMTsKICAgICAgICAgICAgfSBlbHNlaWYgKCcwJyAhPT0gJG1hdGNoZXNbMl0gfHwgJycgPT09ICRtYXRjaGVzWzNdIHx8IG51bGwgPT09ICRtYXRjaGVzWzNdKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBzdGFiaWxpdHkgc3VmZml4CiAgICAgICAgICAgICRzdGFiaWxpdHlTdWZmaXggPSAnJzsKICAgICAgICAgICAgaWYgKGVtcHR5KCRtYXRjaGVzWzVdKSAmJiBlbXB0eSgkbWF0Y2hlc1s3XSkgJiYgZW1wdHkoJG1hdGNoZXNbOF0pKSB7CiAgICAgICAgICAgICAgICAkc3RhYmlsaXR5U3VmZml4IC49ICctZGV2JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxvd1ZlcnNpb24gPSAkdGhpcy0+bm9ybWFsaXplKHN1YnN0cigkY29uc3RyYWludCAuICRzdGFiaWxpdHlTdWZmaXgsIDEpKTsKICAgICAgICAgICAgJGxvd2VyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPj0nLCAkbG93VmVyc2lvbik7CgogICAgICAgICAgICAvLyBGb3IgdXBwZXIgYm91bmQsIHdlIGluY3JlbWVudCB0aGUgcG9zaXRpb24gb2Ygb25lIG1vcmUgc2lnbmlmaWNhbmNlLAogICAgICAgICAgICAvLyBidXQgaGlnaFBvc2l0aW9uID0gMCB3b3VsZCBiZSBpbGxlZ2FsCiAgICAgICAgICAgICRoaWdoVmVyc2lvbiA9ICR0aGlzLT5tYW5pcHVsYXRlVmVyc2lvblN0cmluZygkbWF0Y2hlcywgJHBvc2l0aW9uLCAxKSAuICctZGV2JzsKICAgICAgICAgICAgJHVwcGVyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPCcsICRoaWdoVmVyc2lvbik7CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAkbG93ZXJCb3VuZCwKICAgICAgICAgICAgICAgICR1cHBlckJvdW5kLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gWCBSYW5nZQogICAgICAgIC8vCiAgICAgICAgLy8gQW55IG9mIFgsIHgsIG9yICogbWF5IGJlIHVzZWQgdG8gInN0YW5kIGluIiBmb3Igb25lIG9mIHRoZSBudW1lcmljIHZhbHVlcyBpbiB0aGUgW21ham9yLCBtaW5vciwgcGF0Y2hdIHR1cGxlLgogICAgICAgIC8vIEEgcGFydGlhbCB2ZXJzaW9uIHJhbmdlIGlzIHRyZWF0ZWQgYXMgYW4gWC1SYW5nZSwgc28gdGhlIHNwZWNpYWwgY2hhcmFjdGVyIGlzIGluIGZhY3Qgb3B0aW9uYWwuCiAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3tedj8oXGQrKykoPzpcLihcZCsrKSk/KD86XC4oXGQrKykpPyg/OlwuW3hYKl0pKyskfScsICRjb25zdHJhaW50LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRtYXRjaGVzWzNdKSAmJiAnJyAhPT0gJG1hdGNoZXNbM10gJiYgbnVsbCAhPT0gJG1hdGNoZXNbM10pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IDM7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkbWF0Y2hlc1syXSkgJiYgJycgIT09ICRtYXRjaGVzWzJdICYmIG51bGwgIT09ICRtYXRjaGVzWzJdKSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBvc2l0aW9uID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxvd1ZlcnNpb24gPSAkdGhpcy0+bWFuaXB1bGF0ZVZlcnNpb25TdHJpbmcoJG1hdGNoZXMsICRwb3NpdGlvbikgLiAnLWRldic7CiAgICAgICAgICAgICRoaWdoVmVyc2lvbiA9ICR0aGlzLT5tYW5pcHVsYXRlVmVyc2lvblN0cmluZygkbWF0Y2hlcywgJHBvc2l0aW9uLCAxKSAuICctZGV2JzsKCiAgICAgICAgICAgIGlmICgkbG93VmVyc2lvbiA9PT0gJzAuMC4wLjAtZGV2JykgewogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KG5ldyBDb25zdHJhaW50KCc8JywgJGhpZ2hWZXJzaW9uKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgICAgIG5ldyBDb25zdHJhaW50KCc+PScsICRsb3dWZXJzaW9uKSwKICAgICAgICAgICAgICAgIG5ldyBDb25zdHJhaW50KCc8JywgJGhpZ2hWZXJzaW9uKSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIC8vIEh5cGhlbiBSYW5nZQogICAgICAgIC8vCiAgICAgICAgLy8gU3BlY2lmaWVzIGFuIGluY2x1c2l2ZSBzZXQuIElmIGEgcGFydGlhbCB2ZXJzaW9uIGlzIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCB2ZXJzaW9uIGluIHRoZSBpbmNsdXNpdmUgcmFuZ2UsCiAgICAgICAgLy8gdGhlbiB0aGUgbWlzc2luZyBwaWVjZXMgYXJlIHJlcGxhY2VkIHdpdGggemVyb2VzLiBJZiBhIHBhcnRpYWwgdmVyc2lvbiBpcyBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIHZlcnNpb24gaW4KICAgICAgICAvLyB0aGUgaW5jbHVzaXZlIHJhbmdlLCB0aGVuIGFsbCB2ZXJzaW9ucyB0aGF0IHN0YXJ0IHdpdGggdGhlIHN1cHBsaWVkIHBhcnRzIG9mIHRoZSB0dXBsZSBhcmUgYWNjZXB0ZWQsIGJ1dAogICAgICAgIC8vIG5vdGhpbmcgdGhhdCB3b3VsZCBiZSBncmVhdGVyIHRoYW4gdGhlIHByb3ZpZGVkIHR1cGxlIHBhcnRzLgogICAgICAgIGlmIChwcmVnX21hdGNoKCd7Xig/UDxmcm9tPicgLiAkdmVyc2lvblJlZ2V4IC4gJykgKy0gKyg/UDx0bz4nIC4gJHZlcnNpb25SZWdleCAuICcpKCQpfWknLCAkY29uc3RyYWludCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgc3RhYmlsaXR5IHN1ZmZpeAogICAgICAgICAgICAkbG93U3RhYmlsaXR5U3VmZml4ID0gJyc7CiAgICAgICAgICAgIGlmIChlbXB0eSgkbWF0Y2hlc1s2XSkgJiYgZW1wdHkoJG1hdGNoZXNbOF0pICYmIGVtcHR5KCRtYXRjaGVzWzldKSkgewogICAgICAgICAgICAgICAgJGxvd1N0YWJpbGl0eVN1ZmZpeCA9ICctZGV2JzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxvd1ZlcnNpb24gPSAkdGhpcy0+bm9ybWFsaXplKCRtYXRjaGVzWydmcm9tJ10pOwogICAgICAgICAgICAkbG93ZXJCb3VuZCA9IG5ldyBDb25zdHJhaW50KCc+PScsICRsb3dWZXJzaW9uIC4gJGxvd1N0YWJpbGl0eVN1ZmZpeCk7CgogICAgICAgICAgICAkZW1wdHkgPSBmdW5jdGlvbiAoJHgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoJHggPT09IDAgfHwgJHggPT09ICcwJykgPyBmYWxzZSA6IGVtcHR5KCR4KTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGlmICgoISRlbXB0eSgkbWF0Y2hlc1sxMl0pICYmICEkZW1wdHkoJG1hdGNoZXNbMTNdKSkgfHwgIWVtcHR5KCRtYXRjaGVzWzE1XSkgfHwgIWVtcHR5KCRtYXRjaGVzWzE3XSkgfHwgIWVtcHR5KCRtYXRjaGVzWzE4XSkpIHsKICAgICAgICAgICAgICAgICRoaWdoVmVyc2lvbiA9ICR0aGlzLT5ub3JtYWxpemUoJG1hdGNoZXNbJ3RvJ10pOwogICAgICAgICAgICAgICAgJHVwcGVyQm91bmQgPSBuZXcgQ29uc3RyYWludCgnPD0nLCAkaGlnaFZlcnNpb24pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGhpZ2hNYXRjaCA9IGFycmF5KCcnLCAkbWF0Y2hlc1sxMV0sICRtYXRjaGVzWzEyXSwgJG1hdGNoZXNbMTNdLCAkbWF0Y2hlc1sxNF0pOwoKICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRvIHZlcnNpb24KICAgICAgICAgICAgICAgICR0aGlzLT5ub3JtYWxpemUoJG1hdGNoZXNbJ3RvJ10pOwoKICAgICAgICAgICAgICAgICRoaWdoVmVyc2lvbiA9ICR0aGlzLT5tYW5pcHVsYXRlVmVyc2lvblN0cmluZygkaGlnaE1hdGNoLCAkZW1wdHkoJG1hdGNoZXNbMTJdKSA/IDEgOiAyLCAxKSAuICctZGV2JzsKICAgICAgICAgICAgICAgICR1cHBlckJvdW5kID0gbmV3IENvbnN0cmFpbnQoJzwnLCAkaGlnaFZlcnNpb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAkbG93ZXJCb3VuZCwKICAgICAgICAgICAgICAgICR1cHBlckJvdW5kLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gQmFzaWMgQ29tcGFyYXRvcnMKICAgICAgICBpZiAocHJlZ19tYXRjaCgne14oPD58IT18Pj0/fDw9P3w9PT8pP1xzKiguKil9JywgJGNvbnN0cmFpbnQsICRtYXRjaGVzKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAkdmVyc2lvbiA9ICR0aGlzLT5ub3JtYWxpemUoJG1hdGNoZXNbMl0pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgIC8vIHJlY292ZXIgZnJvbSBhbiBpbnZhbGlkIGNvbnN0cmFpbnQgbGlrZSBmb29iYXItZGV2IHdoaWNoIHNob3VsZCBiZSBkZXYtZm9vYmFyCiAgICAgICAgICAgICAgICAgICAgLy8gZXhjZXB0IGlmIHRoZSBjb25zdHJhaW50IHVzZXMgYSBrbm93biBvcGVyYXRvciwgaW4gd2hpY2ggY2FzZSBpdCBtdXN0IGJlIGEgcGFyc2UgZXJyb3IKICAgICAgICAgICAgICAgICAgICBpZiAoc3Vic3RyKCRtYXRjaGVzWzJdLCAtNCkgPT09ICctZGV2JyAmJiBwcmVnX21hdGNoKCd7XlswLTlhLXpBLVotLi9dKyR9JywgJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJzaW9uID0gJHRoaXMtPm5vcm1hbGl6ZSgnZGV2LScuc3Vic3RyKCRtYXRjaGVzWzJdLCAwLCAtNCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkb3AgPSAkbWF0Y2hlc1sxXSA/OiAnPSc7CgogICAgICAgICAgICAgICAgaWYgKCRvcCAhPT0gJz09JyAmJiAkb3AgIT09ICc9JyAmJiAhZW1wdHkoJHN0YWJpbGl0eU1vZGlmaWVyKSAmJiBzZWxmOjpwYXJzZVN0YWJpbGl0eSgkdmVyc2lvbikgPT09ICdzdGFibGUnKSB7CiAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gLj0gJy0nIC4gJHN0YWJpbGl0eU1vZGlmaWVyOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCc8JyA9PT0gJG9wIHx8ICc+PScgPT09ICRvcCkgewogICAgICAgICAgICAgICAgICAgIGlmICghcHJlZ19tYXRjaCgnLy0nIC4gc2VsZjo6JG1vZGlmaWVyUmVnZXggLiAnJC8nLCBzdHJ0b2xvd2VyKCRtYXRjaGVzWzJdKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkbWF0Y2hlc1syXSwgJ2Rldi0nKSAhPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZlcnNpb24gLj0gJy1kZXYnOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheShuZXcgQ29uc3RyYWludCgkbWF0Y2hlc1sxXSA/OiAnPScsICR2ZXJzaW9uKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG1lc3NhZ2UgPSAnQ291bGQgbm90IHBhcnNlIHZlcnNpb24gY29uc3RyYWludCAnIC4gJGNvbnN0cmFpbnQ7CiAgICAgICAgaWYgKGlzc2V0KCRlKSkgewogICAgICAgICAgICAkbWVzc2FnZSAuPSAnOiAnIC4gJGUtPmdldE1lc3NhZ2UoKTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCRtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluY3JlbWVudCwgZGVjcmVtZW50LCBvciBzaW1wbHkgcGFkIGEgdmVyc2lvbiBudW1iZXIuCiAgICAgKgogICAgICogU3VwcG9ydCBmdW5jdGlvbiBmb3Ige0BsaW5rIHBhcnNlQ29uc3RyYWludCgpfQogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgJG1hdGNoZXMgICBBcnJheSB3aXRoIHZlcnNpb24gcGFydHMgaW4gYXJyYXkgaW5kZXhlcyAxLDIsMyw0CiAgICAgKiBAcGFyYW0gaW50ICAgICRwb3NpdGlvbiAgMSwyLDMsNCAtIHdoaWNoIHNlZ21lbnQgb2YgdGhlIHZlcnNpb24gdG8gaW5jcmVtZW50L2RlY3JlbWVudAogICAgICogQHBhcmFtIGludCAgICAkaW5jcmVtZW50CiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYWQgICAgICAgVGhlIHN0cmluZyB0byBwYWQgdmVyc2lvbiBwYXJ0cyBhZnRlciAkcG9zaXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBuZXcgdmVyc2lvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1hbmlwdWxhdGVWZXJzaW9uU3RyaW5nKCRtYXRjaGVzLCAkcG9zaXRpb24sICRpbmNyZW1lbnQgPSAwLCAkcGFkID0gJzAnKQogICAgewogICAgICAgIGZvciAoJGkgPSA0OyAkaSA+IDA7IC0tJGkpIHsKICAgICAgICAgICAgaWYgKCRpID4gJHBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlc1skaV0gPSAkcGFkOwogICAgICAgICAgICB9IGVsc2VpZiAoJGkgPT09ICRwb3NpdGlvbiAmJiAkaW5jcmVtZW50KSB7CiAgICAgICAgICAgICAgICAkbWF0Y2hlc1skaV0gKz0gJGluY3JlbWVudDsKICAgICAgICAgICAgICAgIC8vIElmICRtYXRjaGVzWyRpXSB3YXMgMCwgY2FycnkgdGhlIGRlY3JlbWVudAogICAgICAgICAgICAgICAgaWYgKCRtYXRjaGVzWyRpXSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlc1skaV0gPSAkcGFkOwogICAgICAgICAgICAgICAgICAgIC0tJHBvc2l0aW9uOwoKICAgICAgICAgICAgICAgICAgICAvLyBSZXR1cm4gbnVsbCBvbiBhIGNhcnJ5IG92ZXJmbG93CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYXRjaGVzWzFdIC4gJy4nIC4gJG1hdGNoZXNbMl0gLiAnLicgLiAkbWF0Y2hlc1szXSAuICcuJyAuICRtYXRjaGVzWzRdOwogICAgfQoKICAgIC8qKgogICAgICogRXhwYW5kIHNob3J0aGFuZCBzdGFiaWxpdHkgc3RyaW5nIHRvIGxvbmcgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGFiaWxpdHkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4cGFuZFN0YWJpbGl0eSgkc3RhYmlsaXR5KQogICAgewogICAgICAgICRzdGFiaWxpdHkgPSBzdHJ0b2xvd2VyKCRzdGFiaWxpdHkpOwoKICAgICAgICBzd2l0Y2ggKCRzdGFiaWxpdHkpIHsKICAgICAgICAgICAgY2FzZSAnYSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ2FscGhhJzsKICAgICAgICAgICAgY2FzZSAnYic6CiAgICAgICAgICAgICAgICByZXR1cm4gJ2JldGEnOwogICAgICAgICAgICBjYXNlICdwJzoKICAgICAgICAgICAgY2FzZSAncGwnOgogICAgICAgICAgICAgICAgcmV0dXJuICdwYXRjaCc7CiAgICAgICAgICAgIGNhc2UgJ3JjJzoKICAgICAgICAgICAgICAgIHJldHVybiAnUkMnOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuICRzdGFiaWxpdHk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CgpjbGFzcyBTZW12ZXIKewogICAgY29uc3QgU09SVF9BU0MgPSAxOwogICAgY29uc3QgU09SVF9ERVNDID0gLTE7CgogICAgLyoqIEB2YXIgVmVyc2lvblBhcnNlciAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHZlcnNpb25QYXJzZXI7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgaWYgZ2l2ZW4gdmVyc2lvbiBzYXRpc2ZpZXMgZ2l2ZW4gY29uc3RyYWludHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAkY29uc3RyYWludHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYXRpc2ZpZXMoJHZlcnNpb24sICRjb25zdHJhaW50cykKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gc2VsZjo6JHZlcnNpb25QYXJzZXIpIHsKICAgICAgICAgICAgc2VsZjo6JHZlcnNpb25QYXJzZXIgPSBuZXcgVmVyc2lvblBhcnNlcigpOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb25QYXJzZXIgPSBzZWxmOjokdmVyc2lvblBhcnNlcjsKICAgICAgICAkcHJvdmlkZXIgPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkdmVyc2lvblBhcnNlci0+bm9ybWFsaXplKCR2ZXJzaW9uKSk7CiAgICAgICAgJHBhcnNlZENvbnN0cmFpbnRzID0gJHZlcnNpb25QYXJzZXItPnBhcnNlQ29uc3RyYWludHMoJGNvbnN0cmFpbnRzKTsKCiAgICAgICAgcmV0dXJuICRwYXJzZWRDb25zdHJhaW50cy0+bWF0Y2hlcygkcHJvdmlkZXIpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFsbCB2ZXJzaW9ucyB0aGF0IHNhdGlzZnkgZ2l2ZW4gY29uc3RyYWludHMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkdmVyc2lvbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnN0cmFpbnRzCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhdGlzZmllZEJ5KGFycmF5ICR2ZXJzaW9ucywgJGNvbnN0cmFpbnRzKQogICAgewogICAgICAgICR2ZXJzaW9ucyA9IGFycmF5X2ZpbHRlcigkdmVyc2lvbnMsIGZ1bmN0aW9uICgkdmVyc2lvbikgdXNlICgkY29uc3RyYWludHMpIHsKICAgICAgICAgICAgcmV0dXJuIFNlbXZlcjo6c2F0aXNmaWVzKCR2ZXJzaW9uLCAkY29uc3RyYWludHMpOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gYXJyYXlfdmFsdWVzKCR2ZXJzaW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb3J0IGdpdmVuIGFycmF5IG9mIHZlcnNpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdmVyc2lvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc29ydChhcnJheSAkdmVyc2lvbnMpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OnVzb3J0KCR2ZXJzaW9ucywgc2VsZjo6U09SVF9BU0MpOwogICAgfQoKICAgIC8qKgogICAgICogU29ydCBnaXZlbiBhcnJheSBvZiB2ZXJzaW9ucyBpbiByZXZlcnNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdmVyc2lvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcnNvcnQoYXJyYXkgJHZlcnNpb25zKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjp1c29ydCgkdmVyc2lvbnMsIHNlbGY6OlNPUlRfREVTQyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHZlcnNpb25zCiAgICAgKiBAcGFyYW0gaW50ICAgJGRpcmVjdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdXNvcnQoYXJyYXkgJHZlcnNpb25zLCAkZGlyZWN0aW9uKQogICAgewogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokdmVyc2lvblBhcnNlcikgewogICAgICAgICAgICBzZWxmOjokdmVyc2lvblBhcnNlciA9IG5ldyBWZXJzaW9uUGFyc2VyKCk7CiAgICAgICAgfQoKICAgICAgICAkdmVyc2lvblBhcnNlciA9IHNlbGY6OiR2ZXJzaW9uUGFyc2VyOwogICAgICAgICRub3JtYWxpemVkID0gYXJyYXkoKTsKCiAgICAgICAgLy8gTm9ybWFsaXplIG91dHNpZGUgb2YgdXNvcnQoKSBzY29wZSBmb3IgbWlub3IgcGVyZm9ybWFuY2UgaW5jcmVhc2UuCiAgICAgICAgLy8gQ3JlYXRlcyBhbiBhcnJheSBvZiBhcnJheXM6IFtbbm9ybWFsaXplZCwga2V5XSwgLi4uXQogICAgICAgIGZvcmVhY2ggKCR2ZXJzaW9ucyBhcyAka2V5ID0+ICR2ZXJzaW9uKSB7CiAgICAgICAgICAgICRub3JtYWxpemVkVmVyc2lvbiA9ICR2ZXJzaW9uUGFyc2VyLT5ub3JtYWxpemUoJHZlcnNpb24pOwogICAgICAgICAgICAkbm9ybWFsaXplZFZlcnNpb24gPSAkdmVyc2lvblBhcnNlci0+bm9ybWFsaXplRGVmYXVsdEJyYW5jaCgkbm9ybWFsaXplZFZlcnNpb24pOwogICAgICAgICAgICAkbm9ybWFsaXplZFtdID0gYXJyYXkoJG5vcm1hbGl6ZWRWZXJzaW9uLCAka2V5KTsKICAgICAgICB9CgogICAgICAgIHVzb3J0KCRub3JtYWxpemVkLCBmdW5jdGlvbiAoYXJyYXkgJGxlZnQsIGFycmF5ICRyaWdodCkgdXNlICgkZGlyZWN0aW9uKSB7CiAgICAgICAgICAgIGlmICgkbGVmdFswXSA9PT0gJHJpZ2h0WzBdKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbXBhcmF0b3I6Omxlc3NUaGFuKCRsZWZ0WzBdLCAkcmlnaHRbMF0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLSRkaXJlY3Rpb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkZGlyZWN0aW9uOwogICAgICAgIH0pOwoKICAgICAgICAvLyBSZWNyZWF0ZSBpbnB1dCBhcnJheSwgdXNpbmcgdGhlIG9yaWdpbmFsIGluZGV4ZXMgd2hpY2ggYXJlIG5vdyBpbiBzb3J0ZWQgb3JkZXIuCiAgICAgICAgJHNvcnRlZCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJG5vcm1hbGl6ZWQgYXMgJGl0ZW0pIHsKICAgICAgICAgICAgJHNvcnRlZFtdID0gJHZlcnNpb25zWyRpdGVtWzFdXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkc29ydGVkOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwoKLyoqCiAqIEhlbHBlciBjbGFzcyB0byBldmFsdWF0ZSBjb25zdHJhaW50IGJ5IGNvbXBpbGluZyBhbmQgcmV1c2luZyB0aGUgY29kZSB0byBldmFsdWF0ZQogKi8KY2xhc3MgQ29tcGlsaW5nTWF0Y2hlcgp7CiAgICBwcml2YXRlIHN0YXRpYyAkY29tcGlsZWRDaGVja2VyQ2FjaGUgPSBhcnJheSgpOwogICAgcHJpdmF0ZSBzdGF0aWMgJGVuYWJsZWQ7CgogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8Q29uc3RyYWludDo6T1BfKiwgc3RyaW5nPgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkdHJhbnNPcEludCA9IGFycmF5KAogICAgICAgIENvbnN0cmFpbnQ6Ok9QX0VRID0+ICc9PScsCiAgICAgICAgQ29uc3RyYWludDo6T1BfTFQgPT4gJzwnLAogICAgICAgIENvbnN0cmFpbnQ6Ok9QX0xFID0+ICc8PScsCiAgICAgICAgQ29uc3RyYWludDo6T1BfR1QgPT4gJz4nLAogICAgICAgIENvbnN0cmFpbnQ6Ok9QX0dFID0+ICc+PScsCiAgICAgICAgQ29uc3RyYWludDo6T1BfTkUgPT4gJyE9JywKICAgICk7CgogICAgLyoqCiAgICAgKiBFdmFsdWF0ZXMgdGhlIGV4cHJlc3Npb246ICRjb25zdHJhaW50IG1hdGNoICRvcGVyYXRvciAkdmVyc2lvbgogICAgICoKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICAkb3BlcmF0b3IKICAgICAqIEBwaHBzdGFuLXBhcmFtIENvbnN0cmFpbnQ6Ok9QXyogICRvcGVyYXRvcgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgJHZlcnNpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWF0Y2goQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCwgJG9wZXJhdG9yLCAkdmVyc2lvbikKICAgIHsKICAgICAgICBpZiAoc2VsZjo6JGVuYWJsZWQgPT09IG51bGwpIHsKICAgICAgICAgICAgc2VsZjo6JGVuYWJsZWQgPSAhXGluX2FycmF5KCdldmFsJywgZXhwbG9kZSgnLCcsIGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJykpLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzZWxmOjokZW5hYmxlZCkgewogICAgICAgICAgICByZXR1cm4gJGNvbnN0cmFpbnQtPm1hdGNoZXMobmV3IENvbnN0cmFpbnQoc2VsZjo6JHRyYW5zT3BJbnRbJG9wZXJhdG9yXSwgJHZlcnNpb24pKTsKICAgICAgICB9CgogICAgICAgICRjYWNoZUtleSA9ICRvcGVyYXRvci4kY29uc3RyYWludDsKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRjb21waWxlZENoZWNrZXJDYWNoZVskY2FjaGVLZXldKSkgewogICAgICAgICAgICAkY29kZSA9ICRjb25zdHJhaW50LT5jb21waWxlKCRvcGVyYXRvcik7CiAgICAgICAgICAgIHNlbGY6OiRjb21waWxlZENoZWNrZXJDYWNoZVskY2FjaGVLZXldID0gJGZ1bmN0aW9uID0gZXZhbCgncmV0dXJuIGZ1bmN0aW9uKCR2LCAkYil7cmV0dXJuICcuJGNvZGUuJzt9OycpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmdW5jdGlvbiA9IHNlbGY6OiRjb21waWxlZENoZWNrZXJDYWNoZVskY2FjaGVLZXldOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRmdW5jdGlvbigkdmVyc2lvbiwgc3RycG9zKCR2ZXJzaW9uLCAnZGV2LScpID09PSAwKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlcjsKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50OwoKY2xhc3MgQ29tcGFyYXRvcgp7CiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xID4gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz4nLCAkdmVyc2lvbjIpOwogICAgfQoKICAgIC8qKgogICAgICogRXZhbHVhdGVzIHRoZSBleHByZXNzaW9uOiAkdmVyc2lvbjEgPj0gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz49JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xIDwgJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxlc3NUaGFuKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJzwnLCAkdmVyc2lvbjIpOwogICAgfQoKICAgIC8qKgogICAgICogRXZhbHVhdGVzIHRoZSBleHByZXNzaW9uOiAkdmVyc2lvbjEgPD0gJHZlcnNpb24yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24xCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJzw9JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xID09ICR2ZXJzaW9uMi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMQogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJz09JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xICE9ICR2ZXJzaW9uMi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMQogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBub3RFcXVhbFRvKCR2ZXJzaW9uMSwgJHZlcnNpb24yKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpjb21wYXJlKCR2ZXJzaW9uMSwgJyE9JywgJHZlcnNpb24yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV2YWx1YXRlcyB0aGUgZXhwcmVzc2lvbjogJHZlcnNpb24xICRvcGVyYXRvciAkdmVyc2lvbjIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbjEKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uMgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbXBhcmUoJHZlcnNpb24xLCAkb3BlcmF0b3IsICR2ZXJzaW9uMikKICAgIHsKICAgICAgICAkY29uc3RyYWludCA9IG5ldyBDb25zdHJhaW50KCRvcGVyYXRvciwgJHZlcnNpb24yKTsKCiAgICAgICAgcmV0dXJuICRjb25zdHJhaW50LT5tYXRjaFNwZWNpZmljKG5ldyBDb25zdHJhaW50KCc9PScsICR2ZXJzaW9uMSksIHRydWUpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CgpjbGFzcyBJbnRlcnZhbAp7CiAgICAvKiogQHZhciBDb25zdHJhaW50ICovCiAgICBwcml2YXRlICRzdGFydDsKICAgIC8qKiBAdmFyIENvbnN0cmFpbnQgKi8KICAgIHByaXZhdGUgJGVuZDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29uc3RyYWludCAkc3RhcnQsIENvbnN0cmFpbnQgJGVuZCkKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnQgPSAkc3RhcnQ7CiAgICAgICAgJHRoaXMtPmVuZCA9ICRlbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXJ0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXJ0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZW5kOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25zdHJhaW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVplcm8oKQogICAgewogICAgICAgIHN0YXRpYyAkemVybzsKCiAgICAgICAgaWYgKG51bGwgPT09ICR6ZXJvKSB7CiAgICAgICAgICAgICR6ZXJvID0gbmV3IENvbnN0cmFpbnQoJz49JywgJzAuMC4wLjAtZGV2Jyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHplcm87CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1bnRpbFBvc2l0aXZlSW5maW5pdHkoKQogICAgewogICAgICAgIHN0YXRpYyAkcG9zaXRpdmVJbmZpbml0eTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRwb3NpdGl2ZUluZmluaXR5KSB7CiAgICAgICAgICAgICRwb3NpdGl2ZUluZmluaXR5ID0gbmV3IENvbnN0cmFpbnQoJzwnLCBQSFBfSU5UX01BWC4nLjAuMC4wJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHBvc2l0aXZlSW5maW5pdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhbnkoKQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZihzZWxmOjpmcm9tWmVybygpLCBzZWxmOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5eyduYW1lcyc6IHN0cmluZ1tdLCAnZXhjbHVkZSc6IGJvb2x9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYW55RGV2KCkKICAgIHsKICAgICAgICAvLyBhbnkgPT0gZXhjbHVkZSBub3RoaW5nCiAgICAgICAgcmV0dXJuIGFycmF5KCduYW1lcycgPT4gYXJyYXkoKSwgJ2V4Y2x1ZGUnID0+IHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheXsnbmFtZXMnOiBzdHJpbmdbXSwgJ2V4Y2x1ZGUnOiBib29sfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG5vRGV2KCkKICAgIHsKICAgICAgICAvLyBub3RoaW5nID09IG5vIG5hbWVzIGluY2x1ZGVkCiAgICAgICAgcmV0dXJuIGFycmF5KCduYW1lcycgPT4gYXJyYXkoKSwgJ2V4Y2x1ZGUnID0+IGZhbHNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50OwoKLyoqCiAqIERlZmluZXMgYSBjb25qdW5jdGl2ZSBvciBkaXNqdW5jdGl2ZSBzZXQgb2YgY29uc3RyYWludHMuCiAqLwpjbGFzcyBNdWx0aUNvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIENvbnN0cmFpbnRJbnRlcmZhY2VbXSAqLwogICAgcHJvdGVjdGVkICRjb25zdHJhaW50czsKCiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlTdHJpbmc7CgogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByb3RlY3RlZCAkc3RyaW5nOwoKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByb3RlY3RlZCAkY29uanVuY3RpdmU7CgogICAgLyoqIEB2YXIgQm91bmR8bnVsbCAqLwogICAgcHJvdGVjdGVkICRsb3dlckJvdW5kOwoKICAgIC8qKiBAdmFyIEJvdW5kfG51bGwgKi8KICAgIHByb3RlY3RlZCAkdXBwZXJCb3VuZDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlW10gJGNvbnN0cmFpbnRzIEEgc2V0IG9mIGNvbnN0cmFpbnRzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICRjb25qdW5jdGl2ZSBXaGV0aGVyIHRoZSBjb25zdHJhaW50cyBzaG91bGQgYmUgdHJlYXRlZCBhcyBjb25qdW5jdGl2ZSBvciBkaXNqdW5jdGl2ZQogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiBsZXNzIHRoYW4gMiBjb25zdHJhaW50cyBhcmUgcGFzc2VkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKFxjb3VudCgkY29uc3RyYWludHMpIDwgMikgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICdNdXN0IHByb3ZpZGUgYXQgbGVhc3QgdHdvIGNvbnN0cmFpbnRzIGZvciBhIE11bHRpQ29uc3RyYWludC4gVXNlICcuCiAgICAgICAgICAgICAgICAndGhlIHJlZ3VsYXIgQ29uc3RyYWludCBjbGFzcyBmb3Igb25lIGNvbnN0cmFpbnQgb25seSBvciBNYXRjaEFsbENvbnN0cmFpbnQgZm9yIG5vbmUuIFlvdSBtYXkgdXNlICcuCiAgICAgICAgICAgICAgICAnTXVsdGlDb25zdHJhaW50OjpjcmVhdGUoKSB3aGljaCBvcHRpbWl6ZXMgYW5kIGhhbmRsZXMgdGhvc2UgY2FzZXMgYXV0b21hdGljYWxseS4nCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29uc3RyYWludHMgPSAkY29uc3RyYWludHM7CiAgICAgICAgJHRoaXMtPmNvbmp1bmN0aXZlID0gJGNvbmp1bmN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBDb25zdHJhaW50SW50ZXJmYWNlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnN0cmFpbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnN0cmFpbnRzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Nvbmp1bmN0aXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbmp1bmN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Rpc2p1bmN0aXZlKCkKICAgIHsKICAgICAgICByZXR1cm4gISR0aGlzLT5jb25qdW5jdGl2ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGlsZSgkb3RoZXJPcGVyYXRvcikKICAgIHsKICAgICAgICAkcGFydHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICAkY29kZSA9ICRjb25zdHJhaW50LT5jb21waWxlKCRvdGhlck9wZXJhdG9yKTsKICAgICAgICAgICAgaWYgKCRjb2RlID09PSAndHJ1ZScpIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmNvbmp1bmN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd0cnVlJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRjb2RlID09PSAnZmFsc2UnKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbmp1bmN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdmYWxzZSc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcGFydHNbXSA9ICcoJy4kY29kZS4nKSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghJHBhcnRzKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29uanVuY3RpdmUgPyAndHJ1ZScgOiAnZmFsc2UnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25qdW5jdGl2ZSA/IGltcGxvZGUoJyYmJywgJHBhcnRzKSA6IGltcGxvZGUoJ3x8JywgJHBhcnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hlcyhDb25zdHJhaW50SW50ZXJmYWNlICRwcm92aWRlcikKICAgIHsKICAgICAgICBpZiAoZmFsc2UgPT09ICR0aGlzLT5jb25qdW5jdGl2ZSkgewogICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgICAgIGlmICgkcHJvdmlkZXItPm1hdGNoZXMoJGNvbnN0cmFpbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb25zdHJhaW50cyBhcyAkY29uc3RyYWludCkgewogICAgICAgICAgICBpZiAoISRwcm92aWRlci0+bWF0Y2hlcygkY29uc3RyYWludCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHByZXR0eVN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJldHR5U3RyaW5nKCRwcmV0dHlTdHJpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eVN0cmluZyA9ICRwcmV0dHlTdHJpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZXR0eVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVN0cmluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoc3RyaW5nKSAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnN0cmluZyAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0cmluZzsKICAgICAgICB9CgogICAgICAgICRjb25zdHJhaW50cyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbnN0cmFpbnRzIGFzICRjb25zdHJhaW50KSB7CiAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gKHN0cmluZykgJGNvbnN0cmFpbnQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnN0cmluZyA9ICdbJyAuIGltcGxvZGUoJHRoaXMtPmNvbmp1bmN0aXZlID8gJyAnIDogJyB8fCAnLCAkY29uc3RyYWludHMpIC4gJ10nOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG93ZXJCb3VuZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4dHJhY3RCb3VuZHMoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5sb3dlckJvdW5kOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBwZXJCb3VuZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4dHJhY3RCb3VuZHMoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT51cHBlckJvdW5kOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZXMgdG8gb3B0aW1pemUgdGhlIGNvbnN0cmFpbnRzIGFzIG11Y2ggYXMgcG9zc2libGUsIG1lYW5pbmcKICAgICAqIHJlZHVjaW5nL2NvbGxhcHNpbmcgY29uZ3J1ZW50IGNvbnN0cmFpbnRzIGV0Yy4KICAgICAqIERvZXMgbm90IG5lY2Vzc2FyaWx5IHJldHVybiBhIE11bHRpQ29uc3RyYWludCBpbnN0YW5jZSBpZgogICAgICogdGhpbmdzIGNhbiBiZSByZWR1Y2VkIHRvIGEgc2ltcGxlIGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZVtdICRjb25zdHJhaW50cyBBIHNldCBvZiBjb25zdHJhaW50cwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAkY29uanVuY3RpdmUgV2hldGhlciB0aGUgY29uc3RyYWludHMgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgY29uanVuY3RpdmUgb3IgZGlzanVuY3RpdmUKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGUoYXJyYXkgJGNvbnN0cmFpbnRzLCAkY29uanVuY3RpdmUgPSB0cnVlKQogICAgewogICAgICAgIGlmICgwID09PSBcY291bnQoJGNvbnN0cmFpbnRzKSkgewogICAgICAgICAgICByZXR1cm4gbmV3IE1hdGNoQWxsQ29uc3RyYWludCgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkY29uc3RyYWludHMpKSB7CiAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludHNbMF07CiAgICAgICAgfQoKICAgICAgICAkb3B0aW1pemVkID0gc2VsZjo6b3B0aW1pemVDb25zdHJhaW50cygkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSk7CiAgICAgICAgaWYgKCRvcHRpbWl6ZWQgIT09IG51bGwpIHsKICAgICAgICAgICAgbGlzdCgkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSkgPSAkb3B0aW1pemVkOwogICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY29uc3RyYWludHNbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgc2VsZigkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gb3B0aW1pemVDb25zdHJhaW50cyhhcnJheSAkY29uc3RyYWludHMsICRjb25qdW5jdGl2ZSkKICAgIHsKICAgICAgICAvLyBwYXJzZSB0aGUgdHdvIE9SIGdyb3VwcyBhbmQgaWYgdGhleSBhcmUgY29udGlndW91cyB3ZSBjb2xsYXBzZQogICAgICAgIC8vIHRoZW0gaW50byBvbmUgY29uc3RyYWludAogICAgICAgIC8vIFs+PSAxIDwgMl0gfHwgWz49IDIgPCAzXSB8fCBbPj0gMyA8IDRdID0+IFs+PSAxIDwgNF0KICAgICAgICBpZiAoISRjb25qdW5jdGl2ZSkgewogICAgICAgICAgICAkbGVmdCA9ICRjb25zdHJhaW50c1swXTsKICAgICAgICAgICAgJG1lcmdlZENvbnN0cmFpbnRzID0gYXJyYXkoKTsKICAgICAgICAgICAgJG9wdGltaXplZCA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKCRpID0gMSwgJGwgPSBcY291bnQoJGNvbnN0cmFpbnRzKTsgJGkgPCAkbDsgJGkrKykgewogICAgICAgICAgICAgICAgJHJpZ2h0ID0gJGNvbnN0cmFpbnRzWyRpXTsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAkbGVmdCBpbnN0YW5jZW9mIHNlbGYKICAgICAgICAgICAgICAgICAgICAmJiAkbGVmdC0+Y29uanVuY3RpdmUKICAgICAgICAgICAgICAgICAgICAmJiAkcmlnaHQgaW5zdGFuY2VvZiBzZWxmCiAgICAgICAgICAgICAgICAgICAgJiYgJHJpZ2h0LT5jb25qdW5jdGl2ZQogICAgICAgICAgICAgICAgICAgICYmIFxjb3VudCgkbGVmdC0+Y29uc3RyYWludHMpID09PSAyCiAgICAgICAgICAgICAgICAgICAgJiYgXGNvdW50KCRyaWdodC0+Y29uc3RyYWludHMpID09PSAyCiAgICAgICAgICAgICAgICAgICAgJiYgKCRsZWZ0MCA9IChzdHJpbmcpICRsZWZ0LT5jb25zdHJhaW50c1swXSkKICAgICAgICAgICAgICAgICAgICAmJiAkbGVmdDBbMF0gPT09ICc+JyAmJiAkbGVmdDBbMV0gPT09ICc9JwogICAgICAgICAgICAgICAgICAgICYmICgkbGVmdDEgPSAoc3RyaW5nKSAkbGVmdC0+Y29uc3RyYWludHNbMV0pCiAgICAgICAgICAgICAgICAgICAgJiYgJGxlZnQxWzBdID09PSAnPCcKICAgICAgICAgICAgICAgICAgICAmJiAoJHJpZ2h0MCA9IChzdHJpbmcpICRyaWdodC0+Y29uc3RyYWludHNbMF0pCiAgICAgICAgICAgICAgICAgICAgJiYgJHJpZ2h0MFswXSA9PT0gJz4nICYmICRyaWdodDBbMV0gPT09ICc9JwogICAgICAgICAgICAgICAgICAgICYmICgkcmlnaHQxID0gKHN0cmluZykgJHJpZ2h0LT5jb25zdHJhaW50c1sxXSkKICAgICAgICAgICAgICAgICAgICAmJiAkcmlnaHQxWzBdID09PSAnPCcKICAgICAgICAgICAgICAgICAgICAmJiBzdWJzdHIoJGxlZnQxLCAyKSA9PT0gc3Vic3RyKCRyaWdodDAsIDMpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkb3B0aW1pemVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkbGVmdCA9IG5ldyBNdWx0aUNvbnN0cmFpbnQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxlZnQtPmNvbnN0cmFpbnRzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJpZ2h0LT5jb25zdHJhaW50c1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXJnZWRDb25zdHJhaW50c1tdID0gJGxlZnQ7CiAgICAgICAgICAgICAgICAgICAgJGxlZnQgPSAkcmlnaHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRvcHRpbWl6ZWQpIHsKICAgICAgICAgICAgICAgICRtZXJnZWRDb25zdHJhaW50c1tdID0gJGxlZnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJG1lcmdlZENvbnN0cmFpbnRzLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFRPRE86IEhlcmUncyB0aGUgcGxhY2UgdG8gcHV0IG1vcmUgb3B0aW1pemF0aW9ucwoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RCb3VuZHMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bG93ZXJCb3VuZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29uc3RyYWludHMgYXMgJGNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5sb3dlckJvdW5kICYmIG51bGwgPT09ICR0aGlzLT51cHBlckJvdW5kKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+bG93ZXJCb3VuZCA9ICRjb25zdHJhaW50LT5nZXRMb3dlckJvdW5kKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9ICRjb25zdHJhaW50LT5nZXRVcHBlckJvdW5kKCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50LT5nZXRMb3dlckJvdW5kKCktPmNvbXBhcmVUbygkdGhpcy0+bG93ZXJCb3VuZCwgJHRoaXMtPmlzQ29uanVuY3RpdmUoKSA/ICc+JyA6ICc8JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gJGNvbnN0cmFpbnQtPmdldExvd2VyQm91bmQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjb25zdHJhaW50LT5nZXRVcHBlckJvdW5kKCktPmNvbXBhcmVUbygkdGhpcy0+dXBwZXJCb3VuZCwgJHRoaXMtPmlzQ29uanVuY3RpdmUoKSA/ICc8JyA6ICc+JykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT51cHBlckJvdW5kID0gJGNvbnN0cmFpbnQtPmdldFVwcGVyQm91bmQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50OwoKLyoqCiAqIERlZmluZXMgdGhlIGFic2VuY2Ugb2YgYSBjb25zdHJhaW50LgogKgogKiBUaGlzIGNvbnN0cmFpbnQgbWF0Y2hlcyBldmVyeXRoaW5nLgogKi8KY2xhc3MgTWF0Y2hBbGxDb25zdHJhaW50IGltcGxlbWVudHMgQ29uc3RyYWludEludGVyZmFjZQp7CiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlTdHJpbmc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoZXMoQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBpbGUoJG9wZXJhdG9yKQogICAgewogICAgICAgIHJldHVybiAndHJ1ZSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHByZXR0eVN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJldHR5U3RyaW5nKCRwcmV0dHlTdHJpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eVN0cmluZyA9ICRwcmV0dHlTdHJpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZXR0eVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVN0cmluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoc3RyaW5nKSAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkKICAgIHsKICAgICAgICByZXR1cm4gJyonOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBwZXJCb3VuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIEJvdW5kOjpwb3NpdGl2ZUluZmluaXR5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb3dlckJvdW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gQm91bmQ6Onplcm8oKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50OwoKLyoqCiAqIEJsYWNraG9sZSBvZiBjb25zdHJhaW50cywgbm90aGluZyBlc2NhcGVzIGl0CiAqLwpjbGFzcyBNYXRjaE5vbmVDb25zdHJhaW50IGltcGxlbWVudHMgQ29uc3RyYWludEludGVyZmFjZQp7CiAgICAvKiogQHZhciBzdHJpbmd8bnVsbCAqLwogICAgcHJvdGVjdGVkICRwcmV0dHlTdHJpbmc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoZXMoQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjb21waWxlKCRvcGVyYXRvcikKICAgIHsKICAgICAgICByZXR1cm4gJ2ZhbHNlJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcHJldHR5U3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmV0dHlTdHJpbmcoJHByZXR0eVN0cmluZykKICAgIHsKICAgICAgICAkdGhpcy0+cHJldHR5U3RyaW5nID0gJHByZXR0eVN0cmluZzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmV0dHlTdHJpbmcoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+cHJldHR5U3RyaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJldHR5U3RyaW5nOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChzdHJpbmcpICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAnW10nOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBwZXJCb3VuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBCb3VuZCgnMC4wLjAuMC1kZXYnLCBmYWxzZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb3dlckJvdW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IEJvdW5kKCcwLjAuMC4wLWRldicsIGZhbHNlKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvc2VtdmVyLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50OwoKLyoqCiAqIERPIE5PVCBJTVBMRU1FTlQgdGhpcyBpbnRlcmZhY2UuIEl0IGlzIG9ubHkgbWVhbnQgZm9yIHVzYWdlIGFzIGEgdHlwZSBoaW50CiAqIGluIGxpYnJhcmllcyByZWx5aW5nIG9uIGNvbXBvc2VyL3NlbXZlciBidXQgY3JlYXRpbmcgeW91ciBvd24gY29uc3RyYWludCBjbGFzcwogKiB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgaXMgbm90IGEgc3VwcG9ydGVkIHVzZSBjYXNlIGFuZCB3aWxsIGNhdXNlIHRoZQogKiBjb21wb3Nlci9zZW12ZXIgY29tcG9uZW50cyB0byByZXR1cm4gdW5leHBlY3RlZCByZXN1bHRzLgogKi8KaW50ZXJmYWNlIENvbnN0cmFpbnRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gY29uc3RyYWludCBpbnRlcnNlY3RzIGluIGFueSB3YXkgd2l0aCB0aGlzIGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcGFyYW0gQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1hdGNoZXMoQ29uc3RyYWludEludGVyZmFjZSAkcHJvdmlkZXIpOwoKICAgIC8qKgogICAgICogUHJvdmlkZXMgYSBjb21waWxlZCB2ZXJzaW9uIG9mIHRoZSBjb25zdHJhaW50IGZvciB0aGUgZ2l2ZW4gb3BlcmF0b3IKICAgICAqIFRoZSBjb21waWxlZCB2ZXJzaW9uIG11c3QgYmUgYSBQSFAgZXhwcmVzc2lvbi4KICAgICAqIEV4ZWN1dG9yIG9mIGNvbXBpbGUgdmVyc2lvbiBtdXN0IHByb3ZpZGUgMiB2YXJpYWJsZXM6CiAgICAgKiAtICR2ID0gdGhlIHN0cmluZyB2ZXJzaW9uIHRvIGNvbXBhcmUgd2l0aAogICAgICogLSAkYiA9IHdoZXRoZXIgb3Igbm90IHRoZSB2ZXJzaW9uIGlzIGEgbm9uLWNvbXBhcmFibGUgYnJhbmNoIChzdGFydHMgd2l0aCAiZGV2LSIpCiAgICAgKgogICAgICogQHNlZSBDb25zdHJhaW50OjpPUF8qIGZvciB0aGUgbGlzdCBvZiBhdmFpbGFibGUgb3BlcmF0b3JzLgogICAgICogQGV4YW1wbGUgcmV0dXJuICchJGIgJiYgdmVyc2lvbl9jb21wYXJlKCR2LCAnMS4wJywgJz4nKSc7CiAgICAgKgogICAgICogQHBhcmFtIGludCAkb3BlcmF0b3Igb25lIENvbnN0cmFpbnQ6Ok9QXyoKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tcGlsZSgkb3BlcmF0b3IpOwoKICAgIC8qKgogICAgICogQHJldHVybiBCb3VuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXBwZXJCb3VuZCgpOwoKICAgIC8qKgogICAgICogQHJldHVybiBCb3VuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG93ZXJCb3VuZCgpOwoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByZXR0eVN0cmluZygpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRwcmV0dHlTdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZXR0eVN0cmluZygkcHJldHR5U3RyaW5nKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3NlbXZlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludDsKCmNsYXNzIEJvdW5kCnsKICAgIC8qKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSAkdmVyc2lvbjsKCiAgICAvKioKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcml2YXRlICRpc0luY2x1c2l2ZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24KICAgICAqIEBwYXJhbSBib29sICAgJGlzSW5jbHVzaXZlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdmVyc2lvbiwgJGlzSW5jbHVzaXZlKQogICAgewogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgJHRoaXMtPmlzSW5jbHVzaXZlID0gJGlzSW5jbHVzaXZlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbmNsdXNpdmUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNJbmNsdXNpdmU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzWmVybygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRWZXJzaW9uKCkgPT09ICcwLjAuMC4wLWRldicgJiYgJHRoaXMtPmlzSW5jbHVzaXZlKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzUG9zaXRpdmVJbmZpbml0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRWZXJzaW9uKCkgPT09IFBIUF9JTlRfTUFYLicuMC4wLjAnICYmICEkdGhpcy0+aXNJbmNsdXNpdmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbXBhcmVzIGEgYm91bmQgdG8gYW5vdGhlciB3aXRoIGEgZ2l2ZW4gb3BlcmF0b3IuCiAgICAgKgogICAgICogQHBhcmFtIEJvdW5kICAkb3RoZXIKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21wYXJlVG8oQm91bmQgJG90aGVyLCAkb3BlcmF0b3IpCiAgICB7CiAgICAgICAgaWYgKCFcaW5fYXJyYXkoJG9wZXJhdG9yLCBhcnJheSgnPCcsICc+JyksIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdEb2VzIG5vdCBzdXBwb3J0IGFueSBvdGhlciBvcGVyYXRvciBvdGhlciB0aGFuID4gb3IgPC4nKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZXkgYXJlIHRoZSBzYW1lIGl0IGRvZXNuJ3QgbWF0dGVyCiAgICAgICAgaWYgKCR0aGlzID09ICRvdGhlcikgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkY29tcGFyZVJlc3VsdCA9IHZlcnNpb25fY29tcGFyZSgkdGhpcy0+Z2V0VmVyc2lvbigpLCAkb3RoZXItPmdldFZlcnNpb24oKSk7CgogICAgICAgIC8vIE5vdCB0aGUgc2FtZSB2ZXJzaW9uIG1lYW5zIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgaWYgdGhlIGJvdW5kcyBhcmUgaW5jbHVzaXZlIG9yIG5vdAogICAgICAgIGlmICgwICE9PSAkY29tcGFyZVJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gKCgnPicgPT09ICRvcGVyYXRvcikgPyAxIDogLTEpID09PSAkY29tcGFyZVJlc3VsdDsKICAgICAgICB9CgogICAgICAgIC8vIFF1ZXN0aW9uIHdlJ3JlIGFuc3dlcmluZyBoZXJlIGlzICJhbSBJIGhpZ2hlciB0aGFuICRvdGhlcj8iCiAgICAgICAgcmV0dXJuICc+JyA9PT0gJG9wZXJhdG9yID8gJG90aGVyLT5pc0luY2x1c2l2ZSgpIDogISRvdGhlci0+aXNJbmNsdXNpdmUoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNwcmludGYoCiAgICAgICAgICAgICclcyBbJXNdJywKICAgICAgICAgICAgJHRoaXMtPmdldFZlcnNpb24oKSwKICAgICAgICAgICAgJHRoaXMtPmlzSW5jbHVzaXZlKCkgPyAnaW5jbHVzaXZlJyA6ICdleGNsdXNpdmUnCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHplcm8oKQogICAgewogICAgICAgIHJldHVybiBuZXcgQm91bmQoJzAuMC4wLjAtZGV2JywgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwb3NpdGl2ZUluZmluaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IEJvdW5kKFBIUF9JTlRfTUFYLicuMC4wLjAnLCBmYWxzZSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGNvbXBvc2VyL3NlbXZlci4KICoKICogKGMpIENvbXBvc2VyIDxodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXI+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3CiAqIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludDsKCi8qKgogKiBEZWZpbmVzIGEgY29uc3RyYWludC4KICovCmNsYXNzIENvbnN0cmFpbnQgaW1wbGVtZW50cyBDb25zdHJhaW50SW50ZXJmYWNlCnsKICAgIC8qIG9wZXJhdG9yIGludGVnZXIgdmFsdWVzICovCiAgICBjb25zdCBPUF9FUSA9IDA7CiAgICBjb25zdCBPUF9MVCA9IDE7CiAgICBjb25zdCBPUF9MRSA9IDI7CiAgICBjb25zdCBPUF9HVCA9IDM7CiAgICBjb25zdCBPUF9HRSA9IDQ7CiAgICBjb25zdCBPUF9ORSA9IDU7CgogICAgLyoqCiAgICAgKiBPcGVyYXRvciB0byBpbnRlZ2VyIHRyYW5zbGF0aW9uIHRhYmxlLgogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIHNlbGY6Ok9QXyo+CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICR0cmFuc09wU3RyID0gYXJyYXkoCiAgICAgICAgJz0nID0+IHNlbGY6Ok9QX0VRLAogICAgICAgICc9PScgPT4gc2VsZjo6T1BfRVEsCiAgICAgICAgJzwnID0+IHNlbGY6Ok9QX0xULAogICAgICAgICc8PScgPT4gc2VsZjo6T1BfTEUsCiAgICAgICAgJz4nID0+IHNlbGY6Ok9QX0dULAogICAgICAgICc+PScgPT4gc2VsZjo6T1BfR0UsCiAgICAgICAgJzw+JyA9PiBzZWxmOjpPUF9ORSwKICAgICAgICAnIT0nID0+IHNlbGY6Ok9QX05FLAogICAgKTsKCiAgICAvKioKICAgICAqIEludGVnZXIgdG8gb3BlcmF0b3IgdHJhbnNsYXRpb24gdGFibGUuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICogQHBocHN0YW4tdmFyIGFycmF5PHNlbGY6Ok9QXyosIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJHRyYW5zT3BJbnQgPSBhcnJheSgKICAgICAgICBzZWxmOjpPUF9FUSA9PiAnPT0nLAogICAgICAgIHNlbGY6Ok9QX0xUID0+ICc8JywKICAgICAgICBzZWxmOjpPUF9MRSA9PiAnPD0nLAogICAgICAgIHNlbGY6Ok9QX0dUID0+ICc+JywKICAgICAgICBzZWxmOjpPUF9HRSA9PiAnPj0nLAogICAgICAgIHNlbGY6Ok9QX05FID0+ICchPScsCiAgICApOwoKICAgIC8qKgogICAgICogQHZhciBpbnQKICAgICAqIEBwaHBzdGFuLXZhciBzZWxmOjpPUF8qCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3I7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcm90ZWN0ZWQgJHZlcnNpb247CgogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByb3RlY3RlZCAkcHJldHR5U3RyaW5nOwoKICAgIC8qKiBAdmFyIEJvdW5kICovCiAgICBwcm90ZWN0ZWQgJGxvd2VyQm91bmQ7CgogICAgLyoqIEB2YXIgQm91bmQgKi8KICAgIHByb3RlY3RlZCAkdXBwZXJCb3VuZDsKCiAgICAvKioKICAgICAqIFNldHMgb3BlcmF0b3IgYW5kIHZlcnNpb24gdG8gY29tcGFyZSB3aXRoLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJzaW9uCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGludmFsaWQgb3BlcmF0b3IgaXMgZ2l2ZW4uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb3BlcmF0b3IsICR2ZXJzaW9uKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JHRyYW5zT3BTdHJbJG9wZXJhdG9yXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdJbnZhbGlkIG9wZXJhdG9yICIlcyIgZ2l2ZW4sIGV4cGVjdGVkIG9uZSBvZjogJXMnLAogICAgICAgICAgICAgICAgJG9wZXJhdG9yLAogICAgICAgICAgICAgICAgaW1wbG9kZSgnLCAnLCBzZWxmOjpnZXRTdXBwb3J0ZWRPcGVyYXRvcnMoKSkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSBzZWxmOjokdHJhbnNPcFN0clskb3BlcmF0b3JdOwogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcnNpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjokdHJhbnNPcEludFskdGhpcy0+b3BlcmF0b3JdOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIENvbnN0cmFpbnRJbnRlcmZhY2UgJHByb3ZpZGVyCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXRjaGVzKENvbnN0cmFpbnRJbnRlcmZhY2UgJHByb3ZpZGVyKQogICAgewogICAgICAgIGlmICgkcHJvdmlkZXIgaW5zdGFuY2VvZiBzZWxmKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF0Y2hTcGVjaWZpYygkcHJvdmlkZXIpOwogICAgICAgIH0KCiAgICAgICAgLy8gdHVybiBtYXRjaGluZyBhcm91bmQgdG8gZmluZCBhIG1hdGNoCiAgICAgICAgcmV0dXJuICRwcm92aWRlci0+bWF0Y2hlcygkdGhpcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHByZXR0eVN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJldHR5U3RyaW5nKCRwcmV0dHlTdHJpbmcpCiAgICB7CiAgICAgICAgJHRoaXMtPnByZXR0eVN0cmluZyA9ICRwcmV0dHlTdHJpbmc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJldHR5U3RyaW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZXR0eVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByZXR0eVN0cmluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+X190b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGFsbCBzdXBwb3J0ZWQgY29tcGFyaXNvbiBvcGVyYXRvcnMuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFN1cHBvcnRlZE9wZXJhdG9ycygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoc2VsZjo6JHRyYW5zT3BTdHIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG9wZXJhdG9yCiAgICAgKiBAcmV0dXJuIGludAogICAgICoKICAgICAqIEBwaHBzdGFuLXJldHVybiBzZWxmOjpPUF8qCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3JDb25zdGFudCgkb3BlcmF0b3IpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiR0cmFuc09wU3RyWyRvcGVyYXRvcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvcgogICAgICogQHBhcmFtIGJvb2wgICAkY29tcGFyZUJyYW5jaGVzCiAgICAgKgogICAgICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGludmFsaWQgb3BlcmF0b3IgaXMgZ2l2ZW4uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2ZXJzaW9uQ29tcGFyZSgkYSwgJGIsICRvcGVyYXRvciwgJGNvbXBhcmVCcmFuY2hlcyA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JHRyYW5zT3BTdHJbJG9wZXJhdG9yXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICdJbnZhbGlkIG9wZXJhdG9yICIlcyIgZ2l2ZW4sIGV4cGVjdGVkIG9uZSBvZjogJXMnLAogICAgICAgICAgICAgICAgJG9wZXJhdG9yLAogICAgICAgICAgICAgICAgaW1wbG9kZSgnLCAnLCBzZWxmOjpnZXRTdXBwb3J0ZWRPcGVyYXRvcnMoKSkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAkYUlzQnJhbmNoID0gc3RycG9zKCRhLCAnZGV2LScpID09PSAwOwogICAgICAgICRiSXNCcmFuY2ggPSBzdHJwb3MoJGIsICdkZXYtJykgPT09IDA7CgogICAgICAgIGlmICgkb3BlcmF0b3IgPT09ICchPScgJiYgKCRhSXNCcmFuY2ggfHwgJGJJc0JyYW5jaCkpIHsKICAgICAgICAgICAgcmV0dXJuICRhICE9PSAkYjsKICAgICAgICB9CgogICAgICAgIGlmICgkYUlzQnJhbmNoICYmICRiSXNCcmFuY2gpIHsKICAgICAgICAgICAgcmV0dXJuICRvcGVyYXRvciA9PT0gJz09JyAmJiAkYSA9PT0gJGI7CiAgICAgICAgfQoKICAgICAgICAvLyB3aGVuIGJyYW5jaGVzIGFyZSBub3QgY29tcGFyYWJsZSwgd2UgbWFrZSBzdXJlIGRldiBicmFuY2hlcyBuZXZlciBtYXRjaCBhbnl0aGluZwogICAgICAgIGlmICghJGNvbXBhcmVCcmFuY2hlcyAmJiAoJGFJc0JyYW5jaCB8fCAkYklzQnJhbmNoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXHZlcnNpb25fY29tcGFyZSgkYSwgJGIsICRvcGVyYXRvcik7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNvbXBpbGUoJG90aGVyT3BlcmF0b3IpCiAgICB7CiAgICAgICAgaWYgKHN0cnBvcygkdGhpcy0+dmVyc2lvbiwgJ2Rldi0nKSA9PT0gMCkgewogICAgICAgICAgICBpZiAoc2VsZjo6T1BfRVEgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX0VRID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCckYiAmJiAkdiA9PT0gJXMnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX05FID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCchJGIgfHwgJHYgIT09ICVzJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAnZmFsc2UnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2VsZjo6T1BfTkUgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX0VRID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCchJGIgfHwgJHYgIT09ICVzJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3RydWUnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJ2ZhbHNlJzsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJHRoaXMtPm9wZXJhdG9yKSB7CiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCdcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCc9PVwnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNlbGY6Ok9QX05FID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyRiIHx8IFx2ZXJzaW9uX2NvbXBhcmUoJHYsICVzLCBcJyE9XCcpJywgXHZhcl9leHBvcnQoJHRoaXMtPnZlcnNpb24sIHRydWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCVzLCAkdiwgXCclc1wnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSwgc2VsZjo6JHRyYW5zT3BJbnRbJG90aGVyT3BlcmF0b3JdKTsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJHRoaXMtPm9wZXJhdG9yKSB7CiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9FUSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCckYiB8fCAoISRiICYmIFx2ZXJzaW9uX2NvbXBhcmUoJHYsICVzLCBcJyE9XCcpKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzZWxmOjpPUF9ORSA9PT0gJG90aGVyT3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiAndHJ1ZSc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6Ok9QX0xUID09PSAkdGhpcy0+b3BlcmF0b3IgfHwgc2VsZjo6T1BfTEUgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBpZiAoc2VsZjo6T1BfTFQgPT09ICRvdGhlck9wZXJhdG9yIHx8IHNlbGY6Ok9QX0xFID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6Ok9QX0dUID09PSAkdGhpcy0+b3BlcmF0b3IgfHwgc2VsZjo6T1BfR0UgPT09ICR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBpZiAoc2VsZjo6T1BfR1QgPT09ICRvdGhlck9wZXJhdG9yIHx8IHNlbGY6Ok9QX0dFID09PSAkb3RoZXJPcGVyYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICchJGInOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZjo6T1BfTkUgPT09ICRvdGhlck9wZXJhdG9yKSB7CiAgICAgICAgICAgIHJldHVybiAndHJ1ZSc7CiAgICAgICAgfQoKICAgICAgICAkY29kZUNvbXBhcmlzb24gPSBzcHJpbnRmKCdcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCclc1wnKScsIFx2YXJfZXhwb3J0KCR0aGlzLT52ZXJzaW9uLCB0cnVlKSwgc2VsZjo6JHRyYW5zT3BJbnRbJHRoaXMtPm9wZXJhdG9yXSk7CiAgICAgICAgaWYgKCR0aGlzLT5vcGVyYXRvciA9PT0gc2VsZjo6T1BfTEUpIHsKICAgICAgICAgICAgaWYgKCRvdGhlck9wZXJhdG9yID09PSBzZWxmOjpPUF9HVCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCchPVwnKSAmJiAnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpIC4gJGNvZGVDb21wYXJpc29uOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5vcGVyYXRvciA9PT0gc2VsZjo6T1BfR0UpIHsKICAgICAgICAgICAgaWYgKCRvdGhlck9wZXJhdG9yID09PSBzZWxmOjpPUF9MVCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyEkYiAmJiBcdmVyc2lvbl9jb21wYXJlKCR2LCAlcywgXCchPVwnKSAmJiAnLCBcdmFyX2V4cG9ydCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSkpIC4gJGNvZGVDb21wYXJpc29uOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZignISRiICYmICVzJywgJGNvZGVDb21wYXJpc29uKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBDb25zdHJhaW50ICRwcm92aWRlcgogICAgICogQHBhcmFtIGJvb2wgICAgICAgJGNvbXBhcmVCcmFuY2hlcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWF0Y2hTcGVjaWZpYyhDb25zdHJhaW50ICRwcm92aWRlciwgJGNvbXBhcmVCcmFuY2hlcyA9IGZhbHNlKQogICAgewogICAgICAgICRub0VxdWFsT3AgPSBzdHJfcmVwbGFjZSgnPScsICcnLCBzZWxmOjokdHJhbnNPcEludFskdGhpcy0+b3BlcmF0b3JdKTsKICAgICAgICAkcHJvdmlkZXJOb0VxdWFsT3AgPSBzdHJfcmVwbGFjZSgnPScsICcnLCBzZWxmOjokdHJhbnNPcEludFskcHJvdmlkZXItPm9wZXJhdG9yXSk7CgogICAgICAgICRpc0VxdWFsT3AgPSBzZWxmOjpPUF9FUSA9PT0gJHRoaXMtPm9wZXJhdG9yOwogICAgICAgICRpc05vbkVxdWFsT3AgPSBzZWxmOjpPUF9ORSA9PT0gJHRoaXMtPm9wZXJhdG9yOwogICAgICAgICRpc1Byb3ZpZGVyRXF1YWxPcCA9IHNlbGY6Ok9QX0VRID09PSAkcHJvdmlkZXItPm9wZXJhdG9yOwogICAgICAgICRpc1Byb3ZpZGVyTm9uRXF1YWxPcCA9IHNlbGY6Ok9QX05FID09PSAkcHJvdmlkZXItPm9wZXJhdG9yOwoKICAgICAgICAvLyAnIT0nIG9wZXJhdG9yIGlzIG1hdGNoIHdoZW4gb3RoZXIgb3BlcmF0b3IgaXMgbm90ICc9PScgb3BlcmF0b3Igb3IgdmVyc2lvbiBpcyBub3QgbWF0Y2gKICAgICAgICAvLyB0aGVzZSBraW5kcyBvZiBjb21wYXJpc29ucyBhbHdheXMgaGF2ZSBhIHNvbHV0aW9uCiAgICAgICAgaWYgKCRpc05vbkVxdWFsT3AgfHwgJGlzUHJvdmlkZXJOb25FcXVhbE9wKSB7CiAgICAgICAgICAgIGlmICgkaXNOb25FcXVhbE9wICYmICEkaXNQcm92aWRlck5vbkVxdWFsT3AgJiYgISRpc1Byb3ZpZGVyRXF1YWxPcCAmJiBzdHJwb3MoJHByb3ZpZGVyLT52ZXJzaW9uLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkaXNQcm92aWRlck5vbkVxdWFsT3AgJiYgISRpc05vbkVxdWFsT3AgJiYgISRpc0VxdWFsT3AgJiYgc3RycG9zKCR0aGlzLT52ZXJzaW9uLCAnZGV2LScpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGlzRXF1YWxPcCAmJiAhJGlzUHJvdmlkZXJFcXVhbE9wKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb25Db21wYXJlKCRwcm92aWRlci0+dmVyc2lvbiwgJHRoaXMtPnZlcnNpb24sICchPScsICRjb21wYXJlQnJhbmNoZXMpOwogICAgICAgIH0KCiAgICAgICAgLy8gYW4gZXhhbXBsZSBmb3IgdGhlIGNvbmRpdGlvbiBpcyA8PSAyLjAgJiA8IDEuMAogICAgICAgIC8vIHRoZXNlIGtpbmRzIG9mIGNvbXBhcmlzb25zIGFsd2F5cyBoYXZlIGEgc29sdXRpb24KICAgICAgICBpZiAoJHRoaXMtPm9wZXJhdG9yICE9PSBzZWxmOjpPUF9FUSAmJiAkbm9FcXVhbE9wID09PSAkcHJvdmlkZXJOb0VxdWFsT3ApIHsKICAgICAgICAgICAgcmV0dXJuICEoc3RycG9zKCR0aGlzLT52ZXJzaW9uLCAnZGV2LScpID09PSAwIHx8IHN0cnBvcygkcHJvdmlkZXItPnZlcnNpb24sICdkZXYtJykgPT09IDApOwogICAgICAgIH0KCiAgICAgICAgJHZlcnNpb24xID0gJGlzRXF1YWxPcCA/ICR0aGlzLT52ZXJzaW9uIDogJHByb3ZpZGVyLT52ZXJzaW9uOwogICAgICAgICR2ZXJzaW9uMiA9ICRpc0VxdWFsT3AgPyAkcHJvdmlkZXItPnZlcnNpb24gOiAkdGhpcy0+dmVyc2lvbjsKICAgICAgICAkb3BlcmF0b3IgPSAkaXNFcXVhbE9wID8gJHByb3ZpZGVyLT5vcGVyYXRvciA6ICR0aGlzLT5vcGVyYXRvcjsKCiAgICAgICAgaWYgKCR0aGlzLT52ZXJzaW9uQ29tcGFyZSgkdmVyc2lvbjEsICR2ZXJzaW9uMiwgc2VsZjo6JHRyYW5zT3BJbnRbJG9wZXJhdG9yXSwgJGNvbXBhcmVCcmFuY2hlcykpIHsKICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlLCBlLmcuIHJlcXVpcmUgPj0gMS4wIGFuZCBwcm92aWRlIDwgMS4wCiAgICAgICAgICAgIC8vIDEuMCA+PSAxLjAgYnV0IDEuMCBpcyBvdXRzaWRlIG9mIHRoZSBwcm92aWRlZCBpbnRlcnZhbAoKICAgICAgICAgICAgcmV0dXJuICEoc2VsZjo6JHRyYW5zT3BJbnRbJHByb3ZpZGVyLT5vcGVyYXRvcl0gPT09ICRwcm92aWRlck5vRXF1YWxPcAogICAgICAgICAgICAgICAgJiYgc2VsZjo6JHRyYW5zT3BJbnRbJHRoaXMtPm9wZXJhdG9yXSAhPT0gJG5vRXF1YWxPcAogICAgICAgICAgICAgICAgJiYgXHZlcnNpb25fY29tcGFyZSgkcHJvdmlkZXItPnZlcnNpb24sICR0aGlzLT52ZXJzaW9uLCAnPT0nKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OiR0cmFuc09wSW50WyR0aGlzLT5vcGVyYXRvcl0gLiAnICcgLiAkdGhpcy0+dmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExvd2VyQm91bmQoKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Qm91bmRzKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+bG93ZXJCb3VuZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwcGVyQm91bmQoKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Qm91bmRzKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+dXBwZXJCb3VuZDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RCb3VuZHMoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+bG93ZXJCb3VuZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBCcmFuY2hlcwogICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPnZlcnNpb24sICdkZXYtJykgPT09IDApIHsKICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBCb3VuZDo6emVybygpOwogICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IEJvdW5kOjpwb3NpdGl2ZUluZmluaXR5KCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBjYXNlIHNlbGY6Ok9QX0VROgogICAgICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBuZXcgQm91bmQoJHRoaXMtPnZlcnNpb24sIHRydWUpOwogICAgICAgICAgICAgICAgJHRoaXMtPnVwcGVyQm91bmQgPSBuZXcgQm91bmQoJHRoaXMtPnZlcnNpb24sIHRydWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6T1BfTFQ6CiAgICAgICAgICAgICAgICAkdGhpcy0+bG93ZXJCb3VuZCA9IEJvdW5kOjp6ZXJvKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IG5ldyBCb3VuZCgkdGhpcy0+dmVyc2lvbiwgZmFsc2UpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6T1BfTEU6CiAgICAgICAgICAgICAgICAkdGhpcy0+bG93ZXJCb3VuZCA9IEJvdW5kOjp6ZXJvKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IG5ldyBCb3VuZCgkdGhpcy0+dmVyc2lvbiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBzZWxmOjpPUF9HVDoKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gbmV3IEJvdW5kKCR0aGlzLT52ZXJzaW9uLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+dXBwZXJCb3VuZCA9IEJvdW5kOjpwb3NpdGl2ZUluZmluaXR5KCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBzZWxmOjpPUF9HRToKICAgICAgICAgICAgICAgICR0aGlzLT5sb3dlckJvdW5kID0gbmV3IEJvdW5kKCR0aGlzLT52ZXJzaW9uLCB0cnVlKTsKICAgICAgICAgICAgICAgICR0aGlzLT51cHBlckJvdW5kID0gQm91bmQ6OnBvc2l0aXZlSW5maW5pdHkoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHNlbGY6Ok9QX05FOgogICAgICAgICAgICAgICAgJHRoaXMtPmxvd2VyQm91bmQgPSBCb3VuZDo6emVybygpOwogICAgICAgICAgICAgICAgJHRoaXMtPnVwcGVyQm91bmQgPSBCb3VuZDo6cG9zaXRpdmVJbmZpbml0eSgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBjb21wb3Nlci9zZW12ZXIuCiAqCiAqIChjKSBDb21wb3NlciA8aHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldwogKiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgQ29tcG9zZXJcU2VtdmVyOwoKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XENvbnN0cmFpbnQ7CnVzZSBDb21wb3NlclxTZW12ZXJcQ29uc3RyYWludFxDb25zdHJhaW50SW50ZXJmYWNlOwp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hBbGxDb25zdHJhaW50Owp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbnN0cmFpbnRcTWF0Y2hOb25lQ29uc3RyYWludDsKdXNlIENvbXBvc2VyXFNlbXZlclxDb25zdHJhaW50XE11bHRpQ29uc3RyYWludDsKCi8qKgogKiBIZWxwZXIgY2xhc3MgZ2VuZXJhdGluZyBpbnRlcnZhbHMgZnJvbSBjb25zdHJhaW50cwogKgogKiBUaGlzIGNvbnRhaW5zIHV0aWxpdGllcyBmb3I6CiAqCiAqICAtIGNvbXBhY3RpbmcgYW4gZXhpc3RpbmcgY29uc3RyYWludCB3aGljaCBjYW4gYmUgdXNlZCB0byBjb21iaW5lIHNldmVyYWwgaW50byBvbmUKICogYnkgY3JlYXRpbmcgYSBNdWx0aUNvbnN0cmFpbnQgb3V0IG9mIHRoZSBtYW55IGNvbnN0cmFpbnRzIHlvdSBoYXZlLgogKgogKiAgLSBjaGVja2luZyB3aGV0aGVyIG9uZSBzdWJzZXQgaXMgYSBzdWJzZXQgb2YgYW5vdGhlci4KICoKICogTm90ZTogWW91IHNob3VsZCBjYWxsIGNsZWFyIHRvIGZyZWUgbWVtb2l6YXRpb24gbWVtb3J5ICB1c2FnZSB3aGVuIHlvdSBhcmUgZG9uZSB1c2luZyB0aGlzIGNsYXNzCiAqLwpjbGFzcyBJbnRlcnZhbHMKewogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBhcnJheXsnbnVtZXJpYyc6IEludGVydmFsW10sICdicmFuY2hlcyc6IGFycmF5eyduYW1lcyc6IHN0cmluZ1tdLCAnZXhjbHVkZSc6IGJvb2x9fT4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJGludGVydmFsc0NhY2hlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxzdHJpbmcsIGludD4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgJG9wU29ydE9yZGVyID0gYXJyYXkoCiAgICAgICAgJz49JyA9PiAtMywKICAgICAgICAnPCcgPT4gLTIsCiAgICAgICAgJz4nID0+IDIsCiAgICAgICAgJzw9JyA9PiAzLAogICAgKTsKCiAgICAvKioKICAgICAqIENsZWFycyB0aGUgbWVtb2l6YXRpb24gY2FjaGUgb25jZSB5b3UgYXJlIGRvbmUKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjbGVhcigpCiAgICB7CiAgICAgICAgc2VsZjo6JGludGVydmFsc0NhY2hlID0gYXJyYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyICRjYW5kaWRhdGUgaXMgYSBzdWJzZXQgb2YgJGNvbnN0cmFpbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc1N1YnNldE9mKENvbnN0cmFpbnRJbnRlcmZhY2UgJGNhbmRpZGF0ZSwgQ29uc3RyYWludEludGVyZmFjZSAkY29uc3RyYWludCkKICAgIHsKICAgICAgICBpZiAoJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhbmRpZGF0ZSBpbnN0YW5jZW9mIE1hdGNoTm9uZUNvbnN0cmFpbnQgfHwgJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNYXRjaE5vbmVDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRpbnRlcnNlY3Rpb25JbnRlcnZhbHMgPSBzZWxmOjpnZXQobmV3IE11bHRpQ29uc3RyYWludChhcnJheSgkY2FuZGlkYXRlLCAkY29uc3RyYWludCksIHRydWUpKTsKICAgICAgICAkY2FuZGlkYXRlSW50ZXJ2YWxzID0gc2VsZjo6Z2V0KCRjYW5kaWRhdGUpOwogICAgICAgIGlmIChcY291bnQoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddKSAhPT0gXGNvdW50KCRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddIGFzICRpbmRleCA9PiAkaW50ZXJ2YWwpIHsKICAgICAgICAgICAgaWYgKCFpc3NldCgkY2FuZGlkYXRlSW50ZXJ2YWxzWydudW1lcmljJ11bJGluZGV4XSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKChzdHJpbmcpICRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXVskaW5kZXhdLT5nZXRTdGFydCgpICE9PSAoc3RyaW5nKSAkaW50ZXJ2YWwtPmdldFN0YXJ0KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKChzdHJpbmcpICRjYW5kaWRhdGVJbnRlcnZhbHNbJ251bWVyaWMnXVskaW5kZXhdLT5nZXRFbmQoKSAhPT0gKHN0cmluZykgJGludGVydmFsLT5nZXRFbmQoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGludGVyc2VjdGlvbkludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddICE9PSAkY2FuZGlkYXRlSW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoXGNvdW50KCRpbnRlcnNlY3Rpb25JbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10pICE9PSBcY291bnQoJGNhbmRpZGF0ZUludGVydmFsc1snYnJhbmNoZXMnXVsnbmFtZXMnXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzWydicmFuY2hlcyddWyduYW1lcyddIGFzICRpbmRleCA9PiAkbmFtZSkgewogICAgICAgICAgICBpZiAoJG5hbWUgIT09ICRjYW5kaWRhdGVJbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ11bJGluZGV4XSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyICRhIGFuZCAkYiBoYXZlIGFueSBpbnRlcnNlY3Rpb24sIGVxdWl2YWxlbnQgdG8gJGEtPm1hdGNoZXMoJGIpCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaGF2ZUludGVyc2VjdGlvbnMoQ29uc3RyYWludEludGVyZmFjZSAkYSwgQ29uc3RyYWludEludGVyZmFjZSAkYikKICAgIHsKICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQgfHwgJGIgaW5zdGFuY2VvZiBNYXRjaEFsbENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGEgaW5zdGFuY2VvZiBNYXRjaE5vbmVDb25zdHJhaW50IHx8ICRiIGluc3RhbmNlb2YgTWF0Y2hOb25lQ29uc3RyYWludCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzID0gc2VsZjo6Z2VuZXJhdGVJbnRlcnZhbHMobmV3IE11bHRpQ29uc3RyYWludChhcnJheSgkYSwgJGIpLCB0cnVlKSwgdHJ1ZSk7CgogICAgICAgIHJldHVybiBcY291bnQoJGludGVyc2VjdGlvbkludGVydmFsc1snbnVtZXJpYyddKSA+IDAgfHwgJGludGVyc2VjdGlvbkludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddIHx8IFxjb3VudCgkaW50ZXJzZWN0aW9uSW50ZXJ2YWxzWydicmFuY2hlcyddWyduYW1lcyddKSA+IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBvcHRpbWl6ZSBhIE11bHRpQ29uc3RyYWludAogICAgICoKICAgICAqIFdoZW4gbWVyZ2luZyBNdWx0aUNvbnN0cmFpbnRzIHRvZ2V0aGVyIHRoZXkgY2FuIGdldCB2ZXJ5IGxhcmdlLCB0aGlzIHdpbGwKICAgICAqIGNvbXBhY3QgaXQgYnkgbG9va2luZyBhdCB0aGUgcmVhbCBpbnRlcnZhbHMgY292ZXJlZCBieSBhbGwgdGhlIGNvbnN0cmFpbnRzCiAgICAgKiBhbmQgdGhlbiBjcmVhdGVzIGEgbmV3IGNvbnN0cmFpbnQgY29udGFpbmluZyBvbmx5IHRoZSBzbWFsbGVzdCBhbW91bnQgb2YgcnVsZXMKICAgICAqIHRvIG1hdGNoIHRoZSBzYW1lIGludGVydmFscy4KICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb21wYWN0Q29uc3RyYWludChDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50KQogICAgewogICAgICAgIGlmICghJGNvbnN0cmFpbnQgaW5zdGFuY2VvZiBNdWx0aUNvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuICRjb25zdHJhaW50OwogICAgICAgIH0KCiAgICAgICAgJGludGVydmFscyA9IHNlbGY6OmdlbmVyYXRlSW50ZXJ2YWxzKCRjb25zdHJhaW50KTsKICAgICAgICAkY29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgICRoYXNOdW1lcmljTWF0Y2hBbGwgPSBmYWxzZTsKCiAgICAgICAgaWYgKFxjb3VudCgkaW50ZXJ2YWxzWydudW1lcmljJ10pID09PSAxICYmIChzdHJpbmcpICRpbnRlcnZhbHNbJ251bWVyaWMnXVswXS0+Z2V0U3RhcnQoKSA9PT0gKHN0cmluZykgSW50ZXJ2YWw6OmZyb21aZXJvKCkgJiYgKHN0cmluZykgJGludGVydmFsc1snbnVtZXJpYyddWzBdLT5nZXRFbmQoKSA9PT0gKHN0cmluZykgSW50ZXJ2YWw6OnVudGlsUG9zaXRpdmVJbmZpbml0eSgpKSB7CiAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJGludGVydmFsc1snbnVtZXJpYyddWzBdLT5nZXRTdGFydCgpOwogICAgICAgICAgICAkaGFzTnVtZXJpY01hdGNoQWxsID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yICgkaSA9IDAsICRjb3VudCA9IFxjb3VudCgkaW50ZXJ2YWxzWydudW1lcmljJ10pOyAkaSA8ICRjb3VudDsgJGkrKykgewogICAgICAgICAgICAgICAgJGludGVydmFsID0gJGludGVydmFsc1snbnVtZXJpYyddWyRpXTsKCiAgICAgICAgICAgICAgICAvLyBpZiBjdXJyZW50IGludGVydmFsIGVuZHMgd2l0aCA8IE4gYW5kIG5leHQgaW50ZXJ2YWwgYmVnaW5zIHdpdGggPiBOIHdlIGNhbiBzd2FwIHRoaXMgb3V0IGZvciAhPSBOCiAgICAgICAgICAgICAgICAvLyBidXQgdGhpcyBuZWVkcyB0byBoYXBwZW4gYXMgYSBjb25qdW5jdGl2ZSBleHByZXNzaW9uIHRvZ2V0aGVyIHdpdGggdGhlIHN0YXJ0IG9mIHRoZSBjdXJyZW50IGludGVydmFsCiAgICAgICAgICAgICAgICAvLyBhbmQgZW5kIG9mIG5leHQgaW50ZXJ2YWwsIHNvIFs+PU0sIDxOXSB8fCBbPk4sIDxQXSA9PiBbPj1NLCAhPU4sIDxQXSBidXQgTS9QIGNhbiBiZSBza2lwcGVkIGlmCiAgICAgICAgICAgICAgICAvLyB0aGV5IGFyZSB6ZXJvLytpbmYKICAgICAgICAgICAgICAgIGlmICgkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRPcGVyYXRvcigpID09PSAnPCcgJiYgJGkrMSA8ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICRuZXh0SW50ZXJ2YWwgPSAkaW50ZXJ2YWxzWydudW1lcmljJ11bJGkrMV07CiAgICAgICAgICAgICAgICAgICAgaWYgKCRpbnRlcnZhbC0+Z2V0RW5kKCktPmdldFZlcnNpb24oKSA9PT0gJG5leHRJbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpICYmICRuZXh0SW50ZXJ2YWwtPmdldFN0YXJ0KCktPmdldE9wZXJhdG9yKCkgPT09ICc+JykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IGFkZCBhIHN0YXJ0IGlmIHdlIGRpZG4ndCBhbHJlYWR5IGRvIHNvLCBjYW4gYmUgc2tpcHBlZCBpZiB3ZSdyZSBsb29raW5nIGF0IHNlY29uZAogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcnZhbCBpbiBbPj1NLCA8Tl0gfHwgWz5OLCA8UF0gfHwgWz5QLCA8UV0gd2hlcmUgdW5FcXVhbENvbnN0cmFpbnRzIGN1cnJlbnRseSBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAvLyBbPj1NLCAhPU5dIGFscmVhZHkgYW5kIHdlIG9ubHkgd2FudCB0byBhZGQgIT1QIHJpZ2h0IG5vdwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCR1bkVxdWFsQ29uc3RyYWludHMpID09PSAwICYmIChzdHJpbmcpICRpbnRlcnZhbC0+Z2V0U3RhcnQoKSAhPT0gKHN0cmluZykgSW50ZXJ2YWw6OmZyb21aZXJvKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR1bkVxdWFsQ29uc3RyYWludHNbXSA9ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzW10gPSBuZXcgQ29uc3RyYWludCgnIT0nLCAkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKFxjb3VudCgkdW5FcXVhbENvbnN0cmFpbnRzKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHdoZXJlIHRoZSBlbmQgb2YgdGhlIGZvbGxvd2luZyBpbnRlcnZhbCBvZiBhICE9IGNvbnN0cmFpbnQgaXMgYWRkZWQgYXMgZXhwbGFpbmVkIGFib3ZlCiAgICAgICAgICAgICAgICAgICAgaWYgKChzdHJpbmcpICRpbnRlcnZhbC0+Z2V0RW5kKCkgIT09IChzdHJpbmcpIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdW5FcXVhbENvbnN0cmFpbnRzW10gPSAkaW50ZXJ2YWwtPmdldEVuZCgpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gY291bnQgaXMgMSBpZiBlbnRpcmUgY29uc3RyYWludCBpcyBqdXN0IG9uZSAhPSBleHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKFxjb3VudCgkdW5FcXVhbENvbnN0cmFpbnRzKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRzW10gPSBuZXcgTXVsdGlDb25zdHJhaW50KCR1bkVxdWFsQ29uc3RyYWludHMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJHVuRXF1YWxDb25zdHJhaW50c1swXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR1bkVxdWFsQ29uc3RyYWludHMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgYmFjayA+PSB4IC0gPD0geCBpbnRlcnZhbHMgdG8gPT0geAogICAgICAgICAgICAgICAgaWYgKCRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpID09PSAkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRWZXJzaW9uKCkgJiYgJGludGVydmFsLT5nZXRTdGFydCgpLT5nZXRPcGVyYXRvcigpID09PSAnPj0nICYmICRpbnRlcnZhbC0+Z2V0RW5kKCktPmdldE9wZXJhdG9yKCkgPT09ICc8PScpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludHNbXSA9IG5ldyBDb25zdHJhaW50KCc9PScsICRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoKHN0cmluZykgJGludGVydmFsLT5nZXRTdGFydCgpID09PSAoc3RyaW5nKSBJbnRlcnZhbDo6ZnJvbVplcm8oKSkgewogICAgICAgICAgICAgICAgICAgICRjb25zdHJhaW50c1tdID0gJGludGVydmFsLT5nZXRFbmQoKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoc3RyaW5nKSAkaW50ZXJ2YWwtPmdldEVuZCgpID09PSAoc3RyaW5nKSBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29uc3RyYWludHNbXSA9ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbnN0cmFpbnRzW10gPSBuZXcgTXVsdGlDb25zdHJhaW50KGFycmF5KCRpbnRlcnZhbC0+Z2V0U3RhcnQoKSwgJGludGVydmFsLT5nZXRFbmQoKSksIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZGV2Q29uc3RyYWludHMgPSBhcnJheSgpOwoKICAgICAgICBpZiAoMCA9PT0gXGNvdW50KCRpbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10pKSB7CiAgICAgICAgICAgIGlmICgkaW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgIGlmICgkaGFzTnVtZXJpY01hdGNoQWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRjaEFsbENvbnN0cmFpbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgY29uc3RyYWludCBzaG91bGQgY29udGFpbiBhICE9IG9wZXJhdG9yIGFuZCBhbHJlYWR5IGNvdmVyIHRoaXMKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpbnRlcnZhbHNbJ2JyYW5jaGVzJ11bJ25hbWVzJ10gYXMgJGJyYW5jaE5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkaW50ZXJ2YWxzWydicmFuY2hlcyddWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAkZGV2Q29uc3RyYWludHNbXSA9IG5ldyBDb25zdHJhaW50KCchPScsICRicmFuY2hOYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGRldkNvbnN0cmFpbnRzW10gPSBuZXcgQ29uc3RyYWludCgnPT0nLCAkYnJhbmNoTmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGV4Y2x1ZGVkIGJyYW5jaGVzLCBlLmcuICE9IGRldi1mb28gYXJlIGNvbmp1bmN0aXZlIHdpdGggdGhlIGludGVydmFsLCBzbwogICAgICAgICAgICAvLyA+IDIuMCAhPSBkZXYtZm9vIG11c3QgcmV0dXJuIGEgY29uanVuY3RpdmUgY29uc3RyYWludAogICAgICAgICAgICBpZiAoJGludGVydmFsc1snYnJhbmNoZXMnXVsnZXhjbHVkZSddKSB7CiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KG5ldyBNdWx0aUNvbnN0cmFpbnQoJGNvbnN0cmFpbnRzLCBmYWxzZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAkZGV2Q29uc3RyYWludHMKICAgICAgICAgICAgICAgICAgICApLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEgJiYgKHN0cmluZykkY29uc3RyYWludHNbMF0gPT09IChzdHJpbmcpSW50ZXJ2YWw6OmZyb21aZXJvKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoXGNvdW50KCRkZXZDb25zdHJhaW50cykgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlDb25zdHJhaW50KCRkZXZDb25zdHJhaW50cywgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkZGV2Q29uc3RyYWludHNbMF07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoYXJyYXlfbWVyZ2UoJGNvbnN0cmFpbnRzLCAkZGV2Q29uc3RyYWludHMpLCB0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGRldkNvbnN0cmFpbnRzIGNvbnRhaW5zIGEgbGlzdCBvZiA9PSBvcGVyYXRvcnMgZm9yIGJyYW5jaGVzIHdoaWNoIGFyZSBkaXNqdW5jdGl2ZSB3aXRoIHRoZQogICAgICAgICAgICAvLyByZXN0IG9mIHRoZSBjb25zdHJhaW50CiAgICAgICAgICAgICRjb25zdHJhaW50cyA9IGFycmF5X21lcmdlKCRjb25zdHJhaW50cywgJGRldkNvbnN0cmFpbnRzKTsKICAgICAgICB9CgogICAgICAgIGlmIChcY291bnQoJGNvbnN0cmFpbnRzKSA+IDEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aUNvbnN0cmFpbnQoJGNvbnN0cmFpbnRzLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRjb25zdHJhaW50cykgPT09IDEpIHsKICAgICAgICAgICAgcmV0dXJuICRjb25zdHJhaW50c1swXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgTWF0Y2hOb25lQ29uc3RyYWludDsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtZXJpYyBpbnRlcnZhbHMgYW5kIGJyYW5jaCBjb25zdHJhaW50cyByZXByZXNlbnRpbmcgYSBnaXZlbiBjb25zdHJhaW50CiAgICAgKgogICAgICogaWYgdGhlIHJldHVybmVkIG51bWVyaWMgYXJyYXkgaXMgZW1wdHkgaXQgbWVhbnMgdGhlIGNvbnN0cmFpbnQgbWF0Y2hlcyBub3RoaW5nIGluIHRoZSBudW1lcmljIHJhbmdlICgwIC0gK2luZikKICAgICAqIGlmIHRoZSByZXR1cm5lZCBicmFuY2hlcyBhcnJheSBpcyBlbXB0eSBpdCBtZWFucyBubyBkZXYtKiB2ZXJzaW9ucyBhcmUgbWF0Y2hlZAogICAgICogaWYgYSBjb25zdHJhaW50IG1hdGNoZXMgYWxsIHBvc3NpYmxlIGRldi0qIHZlcnNpb25zLCBicmFuY2hlcyB3aWxsIGNvbnRhaW4gSW50ZXJ2YWw6OmFueURldigpCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5eydudW1lcmljJzogSW50ZXJ2YWxbXSwgJ2JyYW5jaGVzJzogYXJyYXl7J25hbWVzJzogc3RyaW5nW10sICdleGNsdWRlJzogYm9vbH19CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KENvbnN0cmFpbnRJbnRlcmZhY2UgJGNvbnN0cmFpbnQpCiAgICB7CiAgICAgICAgJGtleSA9IChzdHJpbmcpICRjb25zdHJhaW50OwoKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRpbnRlcnZhbHNDYWNoZVska2V5XSkpIHsKICAgICAgICAgICAgc2VsZjo6JGludGVydmFsc0NhY2hlWyRrZXldID0gc2VsZjo6Z2VuZXJhdGVJbnRlcnZhbHMoJGNvbnN0cmFpbnQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRpbnRlcnZhbHNDYWNoZVska2V5XTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXsnbnVtZXJpYyc6IEludGVydmFsW10sICdicmFuY2hlcyc6IGFycmF5eyduYW1lcyc6IHN0cmluZ1tdLCAnZXhjbHVkZSc6IGJvb2x9fQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZW5lcmF0ZUludGVydmFscyhDb25zdHJhaW50SW50ZXJmYWNlICRjb25zdHJhaW50LCAkc3RvcE9uRmlyc3RWYWxpZEludGVydmFsID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRjb25zdHJhaW50IGluc3RhbmNlb2YgTWF0Y2hBbGxDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gYXJyYXkobmV3IEludGVydmFsKEludGVydmFsOjpmcm9tWmVybygpLCBJbnRlcnZhbDo6dW50aWxQb3NpdGl2ZUluZmluaXR5KCkpKSwgJ2JyYW5jaGVzJyA9PiBJbnRlcnZhbDo6YW55RGV2KCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjb25zdHJhaW50IGluc3RhbmNlb2YgTWF0Y2hOb25lQ29uc3RyYWludCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ251bWVyaWMnID0+IGFycmF5KCksICdicmFuY2hlcycgPT4gYXJyYXkoJ25hbWVzJyA9PiBhcnJheSgpLCAnZXhjbHVkZScgPT4gZmFsc2UpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkY29uc3RyYWludCBpbnN0YW5jZW9mIENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmdlbmVyYXRlU2luZ2xlQ29uc3RyYWludEludGVydmFscygkY29uc3RyYWludCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRjb25zdHJhaW50IGluc3RhbmNlb2YgTXVsdGlDb25zdHJhaW50KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdUaGUgY29uc3RyYWludCBwYXNzZWQgaW4gc2hvdWxkIGJlIGFuIE1hdGNoQWxsQ29uc3RyYWludCwgQ29uc3RyYWludCBvciBNdWx0aUNvbnN0cmFpbnQgaW5zdGFuY2UsIGdvdCAnLlxnZXRfY2xhc3MoJGNvbnN0cmFpbnQpLicuJyk7CiAgICAgICAgfQoKICAgICAgICAkY29uc3RyYWludHMgPSAkY29uc3RyYWludC0+Z2V0Q29uc3RyYWludHMoKTsKCiAgICAgICAgJG51bWVyaWNHcm91cHMgPSBhcnJheSgpOwogICAgICAgICRjb25zdHJhaW50QnJhbmNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRjb25zdHJhaW50cyBhcyAkYykgewogICAgICAgICAgICAkcmVzID0gc2VsZjo6Z2V0KCRjKTsKICAgICAgICAgICAgJG51bWVyaWNHcm91cHNbXSA9ICRyZXNbJ251bWVyaWMnXTsKICAgICAgICAgICAgJGNvbnN0cmFpbnRCcmFuY2hlc1tdID0gJHJlc1snYnJhbmNoZXMnXTsKICAgICAgICB9CgogICAgICAgIGlmICgkY29uc3RyYWludC0+aXNEaXNqdW5jdGl2ZSgpKSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9IEludGVydmFsOjpub0RldigpOwogICAgICAgICAgICBmb3JlYWNoICgkY29uc3RyYWludEJyYW5jaGVzIGFzICRiKSB7CiAgICAgICAgICAgICAgICBpZiAoJGJbJ2V4Y2x1ZGUnXSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoZXNbJ2V4Y2x1ZGUnXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNqdW5jdGl2ZSBjb25zdHJhaW50LCBzbyBvbmx5IGV4Y2x1ZGUgd2hhdCdzIGV4Y2x1ZGVkIGluIGFsbCBjb25zdHJhaW50cwogICAgICAgICAgICAgICAgICAgICAgICAvLyAhPWEsIT1iIHx8ICE9YiwhPWMgPT4gIT1iCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X2ludGVyc2VjdCgkYnJhbmNoZXNbJ25hbWVzJ10sICRiWyduYW1lcyddKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNqdW5jdGl2ZSBjb25zdHJhaW50IHNvIGV4Y2x1ZGUgYWxsIG5hbWVzIHdoaWNoIGFyZSBub3QgZXhwbGljaXRseSBpbmNsdWRlZCBpbiB0aGUgYWx0ZXJuYXRpdmUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gKD09YiB8fCA9PWMpIHx8ICE9YSwhPWIgPT4gIT1hCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snZXhjbHVkZSddID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyduYW1lcyddID0gYXJyYXlfZGlmZigkYlsnbmFtZXMnXSwgJGJyYW5jaGVzWyduYW1lcyddKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICgkYnJhbmNoZXNbJ2V4Y2x1ZGUnXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNqdW5jdGl2ZSBjb25zdHJhaW50IHNvIGV4Y2x1ZGUgYWxsIG5hbWVzIHdoaWNoIGFyZSBub3QgZXhwbGljaXRseSBpbmNsdWRlZCBpbiB0aGUgYWx0ZXJuYXRpdmUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIT1hLCE9YiB8fCAoPT1iIHx8ID09YykgPT4gIT1hCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X2RpZmYoJGJyYW5jaGVzWyduYW1lcyddLCAkYlsnbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzanVuY3RpdmUgY29uc3RyYWludCwgc28ganVzdCBhZGQgYWxsIHRoZSBvdGhlciBicmFuY2hlcwogICAgICAgICAgICAgICAgICAgICAgICAvLyAoPT1hIHx8ID09YikgfHwgPT1jID0+ID09YSB8fCA9PWIgfHwgPT1jCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X21lcmdlKCRicmFuY2hlc1snbmFtZXMnXSwgJGJbJ25hbWVzJ10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRicmFuY2hlcyA9IEludGVydmFsOjphbnlEZXYoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbnN0cmFpbnRCcmFuY2hlcyBhcyAkYikgewogICAgICAgICAgICAgICAgaWYgKCRiWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaGVzWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uanVuY3RpdmUsIHNvIGp1c3QgYWRkIGFsbCBicmFuY2ggbmFtZXMgdG8gYmUgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIT1hICYmICE9YiA9PiAhPWEsIT1iCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X21lcmdlKCRicmFuY2hlc1snbmFtZXMnXSwgJGJbJ25hbWVzJ10pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmp1bmN0aXZlLCBzbyBvbmx5IGtlZXAgaW5jbHVkZWQgbmFtZXMgd2hpY2ggYXJlIG5vdCBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgICAgICAvLyAoPT1hfHw9PWMpICYmICE9YSwhPWIgPT4gPT1jCiAgICAgICAgICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXSA9IGFycmF5X2RpZmYoJGJyYW5jaGVzWyduYW1lcyddLCAkYlsnbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGJyYW5jaGVzWydleGNsdWRlJ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uanVuY3RpdmUsIHNvIG9ubHkga2VlcCBpbmNsdWRlZCBuYW1lcyB3aGljaCBhcmUgbm90IGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICE9YSwhPWIgJiYgKD09YXx8PT1jKSA9PiA9PWMKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWyduYW1lcyddID0gYXJyYXlfZGlmZigkYlsnbmFtZXMnXSwgJGJyYW5jaGVzWyduYW1lcyddKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGJyYW5jaGVzWydleGNsdWRlJ10gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25qdW5jdGl2ZSwgc28gb25seSBrZWVwIG5hbWVzIHRoYXQgYXJlIGluY2x1ZGVkIGluIGJvdGgKICAgICAgICAgICAgICAgICAgICAgICAgLy8gKD09YXx8PT1iKSAmJiAoPT1hfHw9PWMpID0+ID09YQogICAgICAgICAgICAgICAgICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV9pbnRlcnNlY3QoJGJyYW5jaGVzWyduYW1lcyddLCAkYlsnbmFtZXMnXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkYnJhbmNoZXNbJ25hbWVzJ10gPSBhcnJheV91bmlxdWUoJGJyYW5jaGVzWyduYW1lcyddKTsKCiAgICAgICAgaWYgKFxjb3VudCgkbnVtZXJpY0dyb3VwcykgPT09IDEpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdudW1lcmljJyA9PiAkbnVtZXJpY0dyb3Vwc1swXSwgJ2JyYW5jaGVzJyA9PiAkYnJhbmNoZXMpOwogICAgICAgIH0KCiAgICAgICAgJGJvcmRlcnMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRudW1lcmljR3JvdXBzIGFzICRncm91cCkgewogICAgICAgICAgICBmb3JlYWNoICgkZ3JvdXAgYXMgJGludGVydmFsKSB7CiAgICAgICAgICAgICAgICAkYm9yZGVyc1tdID0gYXJyYXkoJ3ZlcnNpb24nID0+ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0VmVyc2lvbigpLCAnb3BlcmF0b3InID0+ICRpbnRlcnZhbC0+Z2V0U3RhcnQoKS0+Z2V0T3BlcmF0b3IoKSwgJ3NpZGUnID0+ICdzdGFydCcpOwogICAgICAgICAgICAgICAgJGJvcmRlcnNbXSA9IGFycmF5KCd2ZXJzaW9uJyA9PiAkaW50ZXJ2YWwtPmdldEVuZCgpLT5nZXRWZXJzaW9uKCksICdvcGVyYXRvcicgPT4gJGludGVydmFsLT5nZXRFbmQoKS0+Z2V0T3BlcmF0b3IoKSwgJ3NpZGUnID0+ICdlbmQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJG9wU29ydE9yZGVyID0gc2VsZjo6JG9wU29ydE9yZGVyOwogICAgICAgIHVzb3J0KCRib3JkZXJzLCBmdW5jdGlvbiAoJGEsICRiKSB1c2UgKCRvcFNvcnRPcmRlcikgewogICAgICAgICAgICAkb3JkZXIgPSB2ZXJzaW9uX2NvbXBhcmUoJGFbJ3ZlcnNpb24nXSwgJGJbJ3ZlcnNpb24nXSk7CiAgICAgICAgICAgIGlmICgkb3JkZXIgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkb3BTb3J0T3JkZXJbJGFbJ29wZXJhdG9yJ11dIC0gJG9wU29ydE9yZGVyWyRiWydvcGVyYXRvciddXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRvcmRlcjsKICAgICAgICB9KTsKCiAgICAgICAgJGFjdGl2ZUludGVydmFscyA9IDA7CiAgICAgICAgJGludGVydmFscyA9IGFycmF5KCk7CiAgICAgICAgJGluZGV4ID0gMDsKICAgICAgICAkYWN0aXZhdGlvblRocmVzaG9sZCA9ICRjb25zdHJhaW50LT5pc0Nvbmp1bmN0aXZlKCkgPyBcY291bnQoJG51bWVyaWNHcm91cHMpIDogMTsKICAgICAgICAkYWN0aXZlID0gZmFsc2U7CiAgICAgICAgJHN0YXJ0ID0gbnVsbDsKICAgICAgICBmb3JlYWNoICgkYm9yZGVycyBhcyAkYm9yZGVyKSB7CiAgICAgICAgICAgIGlmICgkYm9yZGVyWydzaWRlJ10gPT09ICdzdGFydCcpIHsKICAgICAgICAgICAgICAgICRhY3RpdmVJbnRlcnZhbHMrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRhY3RpdmVJbnRlcnZhbHMtLTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISRhY3RpdmUgJiYgJGFjdGl2ZUludGVydmFscyA+PSAkYWN0aXZhdGlvblRocmVzaG9sZCkgewogICAgICAgICAgICAgICAgJHN0YXJ0ID0gbmV3IENvbnN0cmFpbnQoJGJvcmRlclsnb3BlcmF0b3InXSwgJGJvcmRlclsndmVyc2lvbiddKTsKICAgICAgICAgICAgICAgICRhY3RpdmUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkYWN0aXZlICYmICRhY3RpdmVJbnRlcnZhbHMgPCAkYWN0aXZhdGlvblRocmVzaG9sZCkgewogICAgICAgICAgICAgICAgJGFjdGl2ZSA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIC8vIGZpbHRlciBvdXQgaW52YWxpZCBpbnRlcnZhbHMgbGlrZSA+IHggLSA8PSB4LCBvciA+PSB4IC0gPCB4CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgdmVyc2lvbl9jb21wYXJlKCRzdGFydC0+Z2V0VmVyc2lvbigpLCAkYm9yZGVyWyd2ZXJzaW9uJ10sICc9JykKICAgICAgICAgICAgICAgICAgICAmJiAoCiAgICAgICAgICAgICAgICAgICAgICAgICgkc3RhcnQtPmdldE9wZXJhdG9yKCkgPT09ICc+JyAmJiAkYm9yZGVyWydvcGVyYXRvciddID09PSAnPD0nKQogICAgICAgICAgICAgICAgICAgICAgICB8fCAoJHN0YXJ0LT5nZXRPcGVyYXRvcigpID09PSAnPj0nICYmICRib3JkZXJbJ29wZXJhdG9yJ10gPT09ICc8JykKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkaW50ZXJ2YWxzWyRpbmRleF0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaW50ZXJ2YWxzWyRpbmRleF0gPSBuZXcgSW50ZXJ2YWwoJHN0YXJ0LCBuZXcgQ29uc3RyYWludCgkYm9yZGVyWydvcGVyYXRvciddLCAkYm9yZGVyWyd2ZXJzaW9uJ10pKTsKICAgICAgICAgICAgICAgICAgICAkaW5kZXgrKzsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdG9wT25GaXJzdFZhbGlkSW50ZXJ2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRzdGFydCA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gJGludGVydmFscywgJ2JyYW5jaGVzJyA9PiAkYnJhbmNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5eydudW1lcmljJzogSW50ZXJ2YWxbXSwgJ2JyYW5jaGVzJzogYXJyYXl7J25hbWVzJzogc3RyaW5nW10sICdleGNsdWRlJzogYm9vbH19fQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZW5lcmF0ZVNpbmdsZUNvbnN0cmFpbnRJbnRlcnZhbHMoQ29uc3RyYWludCAkY29uc3RyYWludCkKICAgIHsKICAgICAgICAkb3AgPSAkY29uc3RyYWludC0+Z2V0T3BlcmF0b3IoKTsKCiAgICAgICAgLy8gaGFuZGxlIGJyYW5jaCBjb25zdHJhaW50cyBmaXJzdAogICAgICAgIGlmIChzdHJwb3MoJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKSwgJ2Rldi0nKSA9PT0gMCkgewogICAgICAgICAgICAkaW50ZXJ2YWxzID0gYXJyYXkoKTsKICAgICAgICAgICAgJGJyYW5jaGVzID0gYXJyYXkoJ25hbWVzJyA9PiBhcnJheSgpLCAnZXhjbHVkZScgPT4gZmFsc2UpOwoKICAgICAgICAgICAgLy8gIT0gZGV2LWZvbyBtZWFucyBhbnkgbnVtZXJpYyB2ZXJzaW9uIG1heSBtYXRjaCwgd2UgdHJlYXQgPi88IGxpa2UgIT0gdGhleSBhcmUgbm90IHJlYWxseSBkZWZpbmVkIGZvciBicmFuY2hlcwogICAgICAgICAgICBpZiAoJG9wID09PSAnIT0nKSB7CiAgICAgICAgICAgICAgICAkaW50ZXJ2YWxzW10gPSBuZXcgSW50ZXJ2YWwoSW50ZXJ2YWw6OmZyb21aZXJvKCksIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSk7CiAgICAgICAgICAgICAgICAkYnJhbmNoZXMgPSBhcnJheSgnbmFtZXMnID0+IGFycmF5KCRjb25zdHJhaW50LT5nZXRWZXJzaW9uKCkpLCAnZXhjbHVkZScgPT4gdHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkb3AgPT09ICc9PScpIHsKICAgICAgICAgICAgICAgICRicmFuY2hlc1snbmFtZXMnXVtdID0gJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAgICAgJ251bWVyaWMnID0+ICRpbnRlcnZhbHMsCiAgICAgICAgICAgICAgICAnYnJhbmNoZXMnID0+ICRicmFuY2hlcywKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb3BbMF0gPT09ICc+JykgeyAvLyA+ICYgPj0KICAgICAgICAgICAgcmV0dXJuIGFycmF5KCdudW1lcmljJyA9PiBhcnJheShuZXcgSW50ZXJ2YWwoJGNvbnN0cmFpbnQsIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSkpLCAnYnJhbmNoZXMnID0+IEludGVydmFsOjpub0RldigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRvcFswXSA9PT0gJzwnKSB7IC8vIDwgJiA8PQogICAgICAgICAgICByZXR1cm4gYXJyYXkoJ251bWVyaWMnID0+IGFycmF5KG5ldyBJbnRlcnZhbChJbnRlcnZhbDo6ZnJvbVplcm8oKSwgJGNvbnN0cmFpbnQpKSwgJ2JyYW5jaGVzJyA9PiBJbnRlcnZhbDo6bm9EZXYoKSk7CiAgICAgICAgfQogICAgICAgIGlmICgkb3AgPT09ICchPScpIHsKICAgICAgICAgICAgLy8gY29udmVydCAhPXggdG8gaW50ZXJ2YWxzIG9mIDAgLSA8eCAmJiA+eCAtICtpbmYgKyBkZXYqCiAgICAgICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gYXJyYXkoCiAgICAgICAgICAgICAgICBuZXcgSW50ZXJ2YWwoSW50ZXJ2YWw6OmZyb21aZXJvKCksIG5ldyBDb25zdHJhaW50KCc8JywgJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKSkpLAogICAgICAgICAgICAgICAgbmV3IEludGVydmFsKG5ldyBDb25zdHJhaW50KCc+JywgJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKSksIEludGVydmFsOjp1bnRpbFBvc2l0aXZlSW5maW5pdHkoKSksCiAgICAgICAgICAgICksICdicmFuY2hlcycgPT4gSW50ZXJ2YWw6OmFueURldigpKTsKICAgICAgICB9CgogICAgICAgIC8vIGNvbnZlcnQgPT14IHRvIGFuIGludGVydmFsIG9mID49eCAtIDw9eAogICAgICAgIHJldHVybiBhcnJheSgnbnVtZXJpYycgPT4gYXJyYXkoCiAgICAgICAgICAgIG5ldyBJbnRlcnZhbChuZXcgQ29uc3RyYWludCgnPj0nLCAkY29uc3RyYWludC0+Z2V0VmVyc2lvbigpKSwgbmV3IENvbnN0cmFpbnQoJzw9JywgJGNvbnN0cmFpbnQtPmdldFZlcnNpb24oKSkpLAogICAgICAgICksICdicmFuY2hlcycgPT4gSW50ZXJ2YWw6Om5vRGV2KCkpOwogICAgfQp9Cjw/cGhwCgovLyBhdXRvbG9hZF9yZWFsLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgpjbGFzcyBDb21wb3NlckF1dG9sb2FkZXJJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDgKewogICAgcHJpdmF0ZSBzdGF0aWMgJGxvYWRlcjsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWRDbGFzc0xvYWRlcigkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCdDb21wb3NlclxBdXRvbG9hZFxDbGFzc0xvYWRlcicgPT09ICRjbGFzcykgewogICAgICAgICAgICByZXF1aXJlIF9fRElSX18gLiAnL0NsYXNzTG9hZGVyLnBocCc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBcQ29tcG9zZXJcQXV0b2xvYWRcQ2xhc3NMb2FkZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRMb2FkZXIoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokbG9hZGVyKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokbG9hZGVyOwogICAgICAgIH0KCiAgICAgICAgcmVxdWlyZSBfX0RJUl9fIC4gJy9wbGF0Zm9ybV9jaGVjay5waHAnOwoKICAgICAgICBzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoYXJyYXkoJ0NvbXBvc2VyQXV0b2xvYWRlckluaXRiZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkOCcsICdsb2FkQ2xhc3NMb2FkZXInKSwgdHJ1ZSwgdHJ1ZSk7CiAgICAgICAgc2VsZjo6JGxvYWRlciA9ICRsb2FkZXIgPSBuZXcgXENvbXBvc2VyXEF1dG9sb2FkXENsYXNzTG9hZGVyKFxkaXJuYW1lKFxkaXJuYW1lKF9fRklMRV9fKSkpOwogICAgICAgIHNwbF9hdXRvbG9hZF91bnJlZ2lzdGVyKGFycmF5KCdDb21wb3NlckF1dG9sb2FkZXJJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDgnLCAnbG9hZENsYXNzTG9hZGVyJykpOwoKICAgICAgICAkdXNlU3RhdGljTG9hZGVyID0gUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDAgJiYgIWRlZmluZWQoJ0hIVk1fVkVSU0lPTicpICYmICghZnVuY3Rpb25fZXhpc3RzKCd6ZW5kX2xvYWRlcl9maWxlX2VuY29kZWQnKSB8fCAhemVuZF9sb2FkZXJfZmlsZV9lbmNvZGVkKCkpOwogICAgICAgIGlmICgkdXNlU3RhdGljTG9hZGVyKSB7CiAgICAgICAgICAgIHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfc3RhdGljLnBocCc7CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYyhcQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDg6OmdldEluaXRpYWxpemVyKCRsb2FkZXIpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbWFwID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9uYW1lc3BhY2VzLnBocCc7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXAgYXMgJG5hbWVzcGFjZSA9PiAkcGF0aCkgewogICAgICAgICAgICAgICAgJGxvYWRlci0+c2V0KCRuYW1lc3BhY2UsICRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG1hcCA9IHJlcXVpcmUgX19ESVJfXyAuICcvYXV0b2xvYWRfcHNyNC5waHAnOwogICAgICAgICAgICBmb3JlYWNoICgkbWFwIGFzICRuYW1lc3BhY2UgPT4gJHBhdGgpIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPnNldFBzcjQoJG5hbWVzcGFjZSwgJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY2xhc3NNYXAgPSByZXF1aXJlIF9fRElSX18gLiAnL2F1dG9sb2FkX2NsYXNzbWFwLnBocCc7CiAgICAgICAgICAgIGlmICgkY2xhc3NNYXApIHsKICAgICAgICAgICAgICAgICRsb2FkZXItPmFkZENsYXNzTWFwKCRjbGFzc01hcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRsb2FkZXItPnJlZ2lzdGVyKHRydWUpOwoKICAgICAgICBpZiAoJHVzZVN0YXRpY0xvYWRlcikgewogICAgICAgICAgICAkaW5jbHVkZUZpbGVzID0gQ29tcG9zZXJcQXV0b2xvYWRcQ29tcG9zZXJTdGF0aWNJbml0YmYxMDllMDkxZDI5MTY2ZTA0OTQ2MTFlMjJlN2RiZDg6OiRmaWxlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaW5jbHVkZUZpbGVzID0gcmVxdWlyZSBfX0RJUl9fIC4gJy9hdXRvbG9hZF9maWxlcy5waHAnOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkaW5jbHVkZUZpbGVzIGFzICRmaWxlSWRlbnRpZmllciA9PiAkZmlsZSkgewogICAgICAgICAgICBjb21wb3NlclJlcXVpcmViZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkOCgkZmlsZUlkZW50aWZpZXIsICRmaWxlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbG9hZGVyOwogICAgfQp9CgpmdW5jdGlvbiBjb21wb3NlclJlcXVpcmViZjEwOWUwOTFkMjkxNjZlMDQ5NDYxMWUyMmU3ZGJkOCgkZmlsZUlkZW50aWZpZXIsICRmaWxlKQp7CiAgICBpZiAoZW1wdHkoJEdMT0JBTFNbJ19fY29tcG9zZXJfYXV0b2xvYWRfZmlsZXMnXVskZmlsZUlkZW50aWZpZXJdKSkgewogICAgICAgIHJlcXVpcmUgJGZpbGU7CgogICAgICAgICRHTE9CQUxTWydfX2NvbXBvc2VyX2F1dG9sb2FkX2ZpbGVzJ11bJGZpbGVJZGVudGlmaWVyXSA9IHRydWU7CiAgICB9Cn0KPD9waHAKCi8vIGF1dG9sb2FkX2ZpbGVzLnBocCBAZ2VuZXJhdGVkIGJ5IENvbXBvc2VyCgokdmVuZG9yRGlyID0gZGlybmFtZShkaXJuYW1lKF9fRklMRV9fKSk7CiRiYXNlRGlyID0gZGlybmFtZSgkdmVuZG9yRGlyKTsKCnJldHVybiBhcnJheSgKICAgICdiZTAxYjliMTY5MjVkY2IyMjE2NWM0MGI0NjY4MWFjNicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3BocC1jbGktdG9vbHMvbGliL2NsaS9jbGkucGhwJywKICAgICczOTM3ODA2MTA1Y2M4ZTIyMWI4ZmE4ZGI1YjcwZDJmMicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL211c3Rhbmdvc3Rhbmctc3B5Yy9pbmNsdWRlcy9mdW5jdGlvbnMucGhwJywKICAgICc4YTBhZDAyZGY2YTUwODdmMmMzODBmOGZkNTJkYjI3MycgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2NhY2hlLWNvbW1hbmQvY2FjaGUtY29tbWFuZC5waHAnLAogICAgJ2YzZjAxOTlhM2VjZDlmNTAxZDBhM2IzNjFiZDJmNjFjJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZW50aXR5LWNvbW1hbmQvZW50aXR5LWNvbW1hbmQucGhwJywKICAgICczZjIwMTAzM2Q1YWNlYjIyOTMzMTQyNzNiZTg4ZjdjNicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2V4dGVuc2lvbi1jb21tYW5kL2V4dGVuc2lvbi1jb21tYW5kLnBocCcsCiAgICAnYzY1Zjc1MzM3NWZhZWUzNDliN2FkYzQ4YzJlZTdjYzInID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9kYi1jb21tYW5kL2RiLWNvbW1hbmQucGhwJywKICAgICcwZTZkN2JmNGE1ODExYmZhNWNmNDBjNWNjZDZmYWU2YScgPT4gJHZlbmRvckRpciAuICcvc3ltZm9ueS9wb2x5ZmlsbC1tYnN0cmluZy9ib290c3RyYXAucGhwJywKICAgICczMjBjZGUyMmY2NmRkNGY1ZDNmZDYyMWQzZTg4Yjk4ZicgPT4gJHZlbmRvckRpciAuICcvc3ltZm9ueS9wb2x5ZmlsbC1jdHlwZS9ib290c3RyYXAucGhwJywKICAgICdhZDE1NWY4ZjFjZjBkNDE4ZmU0OWUyNDhkYjhjNjYxYicgPT4gJHZlbmRvckRpciAuICcvcmVhY3QvcHJvbWlzZS9zcmMvZnVuY3Rpb25zX2luY2x1ZGUucGhwJywKICAgICdkOTc5YzExZmU4MGJhOTZhZTMwMzdiNDM0MjlmZTU0NicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3NjYWZmb2xkLWNvbW1hbmQvc2NhZmZvbGQtY29tbWFuZC5waHAnLAogICAgJzVjNmVjNWNmZjhmOWQ2MjU3NzJjOGVkMTQ3ZjZiODk0JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZXhwb3J0LWNvbW1hbmQvZXhwb3J0LWNvbW1hbmQucGhwJywKICAgICdiNjZkMjk3NTdmY2IyZmI3YTk2MDhkMDY4ZTM3MTZiMCcgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL2NoZWNrc3VtLWNvbW1hbmQvY2hlY2tzdW0tY29tbWFuZC5waHAnLAogICAgJ2FjOTQ5Y2U0MGE5ODE4MTliYTEzMjQ3MzUxOGE5YTMxJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyL3NyYy9XUENvbmZpZ1RyYW5zZm9ybWVyLnBocCcsCiAgICAnMzBjYmI2ZTQxMjJkYzk4OGU0OTRjNmI5YzA0MzgyMzMnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9pbXBvcnQtY29tbWFuZC9pbXBvcnQtY29tbWFuZC5waHAnLAogICAgJzVlMDk5ZDNjYWM2NzdkZDJiZWMxMDAzZWE3NzA3NzQ1JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvbWVkaWEtY29tbWFuZC9tZWRpYS1jb21tYW5kLnBocCcsCiAgICAnYmEzNjZmOTZmNGZkZGJkZWY2MWFkN2E4NjJiNDRmNjEnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9wYWNrYWdlLWNvbW1hbmQvcGFja2FnZS1jb21tYW5kLnBocCcsCiAgICAnNWRlYWY2Y2U5YzhiYmRmYjY1MTA0YzdlOTM4ZDU4NzUnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9jb25maWctY29tbWFuZC9jb25maWctY29tbWFuZC5waHAnLAogICAgJzY4YzM5Yjg4MjE1YjZjZjdhMGRhMTY0MTY2NjcwZWY5JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY29yZS1jb21tYW5kL2NvcmUtY29tbWFuZC5waHAnLAogICAgJzc2NTRlMDBiZjBlNjMyNTgwNzY0NDAwYmQ4MjkzYTljJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvY3Jvbi1jb21tYW5kL2Nyb24tY29tbWFuZC5waHAnLAogICAgJzAyMWQzYTEzNDcxNTU2ZjBiNTcwMzhkNjc5ZjdmOGVhJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvZW1iZWQtY29tbWFuZC9lbWJlZC1jb21tYW5kLnBocCcsCiAgICAnZjk1OGRjYTNmNDEyZmQ3OTc1ZGExNzAwOTEyYTkzMjEnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9ldmFsLWNvbW1hbmQvZXZhbC1jb21tYW5kLnBocCcsCiAgICAnZmZiNDY1YTQ5NGMzMTAxMjE4YzQ0MTcxODBjMmM5YTInID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9pMThuLWNvbW1hbmQvaTE4bi1jb21tYW5kLnBocCcsCiAgICAnYWNlMGQyMDVkYjdmNDEzNWVjMzIxMzJhMDA3NmQ1NTUnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS9sYW5ndWFnZS1jb21tYW5kL2xhbmd1YWdlLWNvbW1hbmQucGhwJywKICAgICcxYzg4YzFlZmYwNTIxN2E4Y2FjODBjNjRjOWFjMjA4MCcgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL21haW50ZW5hbmNlLW1vZGUtY29tbWFuZC9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQucGhwJywKICAgICdmMzk5YzFjOGQwYzc4N2Q1Yzk0YzA5ODg0Y2RkOTc2MicgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3Jld3JpdGUtY29tbWFuZC9yZXdyaXRlLWNvbW1hbmQucGhwJywKICAgICcwODBmYWRkNjY3MTk1ZDA1NWM1YTIzMzg2ZjI3MDI2MScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3JvbGUtY29tbWFuZC9yb2xlLWNvbW1hbmQucGhwJywKICAgICc4ZWNiMTNmOGJiYzIyYjFiMzRkMTJiMTRlYzAxMDc3YScgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3NlYXJjaC1yZXBsYWNlLWNvbW1hbmQvc2VhcmNoLXJlcGxhY2UtY29tbWFuZC5waHAnLAogICAgJzlmMDRkZDBhYTVkNjdlYzc1YTc1Yzg4YzM0NWEwNzllJyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvc2VydmVyLWNvbW1hbmQvc2VydmVyLWNvbW1hbmQucGhwJywKICAgICcxMjlkNThmYTgxNTEzNzRhY2ViODU3MWJjYWE5NzUwNCcgPT4gJHZlbmRvckRpciAuICcvd3AtY2xpL3NoZWxsLWNvbW1hbmQvc2hlbGwtY29tbWFuZC5waHAnLAogICAgJzg1MTk3NzliYmI2NWVlYjg0MmFmMmY2MjljZTdiNmY4JyA9PiAkdmVuZG9yRGlyIC4gJy93cC1jbGkvc3VwZXItYWRtaW4tY29tbWFuZC9zdXBlci1hZG1pbi1jb21tYW5kLnBocCcsCiAgICAnMWYwNTM3MmFmY2M3ZDBjNTFhMzA1Y2VmMWQ1NmRkMDEnID0+ICR2ZW5kb3JEaXIgLiAnL3dwLWNsaS93aWRnZXQtY29tbWFuZC93aWRnZXQtY29tbWFuZC5waHAnLAopOwo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgY29tcG9zZXIvY2EtYnVuZGxlLgogKgogKiAoYykgQ29tcG9zZXIgPGh0dHBzOi8vZ2l0aHViLmNvbS9jb21wb3Nlcj4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcKICogdGhlIExJQ0VOU0UgZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIENvbXBvc2VyXENhQnVuZGxlOwoKdXNlIFBzclxMb2dcTG9nZ2VySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaHBQcm9jZXNzOwoKLyoqCiAqIEBhdXRob3IgQ2hyaXMgU21pdGggPGNocmlzQGNzMjc4Lm9yZz4KICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgQ2FCdW5kbGUKewogICAgLyoqIEB2YXIgc3RyaW5nfG51bGwgKi8KICAgIHByaXZhdGUgc3RhdGljICRjYVBhdGg7CiAgICAvKiogQHZhciBhcnJheTxzdHJpbmcsIGJvb2w+ICovCiAgICBwcml2YXRlIHN0YXRpYyAkY2FGaWxlVmFsaWRpdHkgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYm9vbHxudWxsICovCiAgICBwcml2YXRlIHN0YXRpYyAkdXNlT3BlbnNzbFBhcnNlOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3lzdGVtIENBIGJ1bmRsZSBwYXRoLCBvciBhIHBhdGggdG8gdGhlIGJ1bmRsZWQgb25lCiAgICAgKgogICAgICogVGhpcyBtZXRob2Qgd2FzIGFkYXB0ZWQgZnJvbSBTc2x1cnAuCiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vRXZhbkRvdFByby9Tc2x1cnAKICAgICAqCiAgICAgKiAoYykgRXZhbiBDb3VyeSA8bWVAZXZhbmNvdXJ5LmNvbT4KICAgICAqCiAgICAgKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2Ugc2VlIGJlbG93OgogICAgICoKICAgICAqIENvcHlyaWdodCAoYykgMjAxMywgRXZhbiBDb3VyeQogICAgICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICAgICAqCiAgICAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLAogICAgICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgogICAgICoKICAgICAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICAgICAqICAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKgogICAgICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogICAgICogICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogICAgICogICAgICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAgICAgKgogICAgICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFORAogICAgICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKICAgICAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKICAgICAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IKICAgICAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwogICAgICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOwogICAgICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OCiAgICAgKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogICAgICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMKICAgICAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogICAgICoKICAgICAqIEBwYXJhbSAgTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgb3B0aW9uYWwgbG9nZ2VyIGZvciBpbmZvcm1hdGlvbiBhYm91dCB3aGljaCBDQSBmaWxlcyB3ZXJlIGxvYWRlZAogICAgICogQHJldHVybiBzdHJpbmcgICAgICAgICAgcGF0aCB0byBhIENBIGJ1bmRsZSBmaWxlIG9yIGRpcmVjdG9yeQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFN5c3RlbUNhUm9vdEJ1bmRsZVBhdGgoTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgPSBudWxsKQogICAgewogICAgICAgIGlmIChzZWxmOjokY2FQYXRoICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokY2FQYXRoOwogICAgICAgIH0KICAgICAgICAkY2FCdW5kbGVQYXRocyA9IGFycmF5KCk7CgogICAgICAgIC8vIElmIFNTTF9DRVJUX0ZJTEUgZW52IHZhcmlhYmxlIHBvaW50cyB0byBhIHZhbGlkIGNlcnRpZmljYXRlL2J1bmRsZSwgdXNlIHRoYXQuCiAgICAgICAgLy8gVGhpcyBtaW1pY3MgaG93IE9wZW5TU0wgdXNlcyB0aGUgU1NMX0NFUlRfRklMRSBlbnYgdmFyaWFibGUuCiAgICAgICAgJGNhQnVuZGxlUGF0aHNbXSA9IHNlbGY6OmdldEVudlZhcmlhYmxlKCdTU0xfQ0VSVF9GSUxFJyk7CgogICAgICAgIC8vIElmIFNTTF9DRVJUX0RJUiBlbnYgdmFyaWFibGUgcG9pbnRzIHRvIGEgdmFsaWQgY2VydGlmaWNhdGUvYnVuZGxlLCB1c2UgdGhhdC4KICAgICAgICAvLyBUaGlzIG1pbWljcyBob3cgT3BlblNTTCB1c2VzIHRoZSBTU0xfQ0VSVF9GSUxFIGVudiB2YXJpYWJsZS4KICAgICAgICAkY2FCdW5kbGVQYXRoc1tdID0gc2VsZjo6Z2V0RW52VmFyaWFibGUoJ1NTTF9DRVJUX0RJUicpOwoKICAgICAgICAkY2FCdW5kbGVQYXRoc1tdID0gaW5pX2dldCgnb3BlbnNzbC5jYWZpbGUnKTsKICAgICAgICAkY2FCdW5kbGVQYXRoc1tdID0gaW5pX2dldCgnb3BlbnNzbC5jYXBhdGgnKTsKCiAgICAgICAgJG90aGVyTG9jYXRpb25zID0gYXJyYXkoCiAgICAgICAgICAgICcvZXRjL3BraS90bHMvY2VydHMvY2EtYnVuZGxlLmNydCcsIC8vIEZlZG9yYSwgUkhFTCwgQ2VudE9TIChjYS1jZXJ0aWZpY2F0ZXMgcGFja2FnZSkKICAgICAgICAgICAgJy9ldGMvc3NsL2NlcnRzL2NhLWNlcnRpZmljYXRlcy5jcnQnLCAvLyBEZWJpYW4sIFVidW50dSwgR2VudG9vLCBBcmNoIExpbnV4IChjYS1jZXJ0aWZpY2F0ZXMgcGFja2FnZSkKICAgICAgICAgICAgJy9ldGMvc3NsL2NhLWJ1bmRsZS5wZW0nLCAvLyBTVVNFLCBvcGVuU1VTRSAoY2EtY2VydGlmaWNhdGVzIHBhY2thZ2UpCiAgICAgICAgICAgICcvdXNyL2xvY2FsL3NoYXJlL2NlcnRzL2NhLXJvb3QtbnNzLmNydCcsIC8vIEZyZWVCU0QgKGNhX3Jvb3RfbnNzX3BhY2thZ2UpCiAgICAgICAgICAgICcvdXNyL3NzbC9jZXJ0cy9jYS1idW5kbGUuY3J0JywgLy8gQ3lnd2luCiAgICAgICAgICAgICcvb3B0L2xvY2FsL3NoYXJlL2N1cmwvY3VybC1jYS1idW5kbGUuY3J0JywgLy8gT1MgWCBtYWNwb3J0cywgY3VybC1jYS1idW5kbGUgcGFja2FnZQogICAgICAgICAgICAnL3Vzci9sb2NhbC9zaGFyZS9jdXJsL2N1cmwtY2EtYnVuZGxlLmNydCcsIC8vIERlZmF1bHQgY1VSTCBDQSBidW5kZSBwYXRoICh3aXRob3V0IC0td2l0aC1jYS1idW5kbGUgb3B0aW9uKQogICAgICAgICAgICAnL3Vzci9zaGFyZS9zc2wvY2VydHMvY2EtYnVuZGxlLmNydCcsIC8vIFJlYWxseSBvbGQgUmVkSGF0PwogICAgICAgICAgICAnL2V0Yy9zc2wvY2VydC5wZW0nLCAvLyBPcGVuQlNECiAgICAgICAgICAgICcvdXNyL2xvY2FsL2V0Yy9zc2wvY2VydC5wZW0nLCAvLyBGcmVlQlNEIDEwLngKICAgICAgICAgICAgJy91c3IvbG9jYWwvZXRjL29wZW5zc2wvY2VydC5wZW0nLCAvLyBPUyBYIGhvbWVicmV3LCBvcGVuc3NsIHBhY2thZ2UKICAgICAgICAgICAgJy91c3IvbG9jYWwvZXRjL29wZW5zc2xAMS4xL2NlcnQucGVtJywgLy8gT1MgWCBob21lYnJldywgb3BlbnNzbEAxLjEgcGFja2FnZQogICAgICAgICk7CgogICAgICAgIGZvcmVhY2goJG90aGVyTG9jYXRpb25zIGFzICRsb2NhdGlvbikgewogICAgICAgICAgICAkb3RoZXJMb2NhdGlvbnNbXSA9IGRpcm5hbWUoJGxvY2F0aW9uKTsKICAgICAgICB9CgogICAgICAgICRjYUJ1bmRsZVBhdGhzID0gYXJyYXlfbWVyZ2UoJGNhQnVuZGxlUGF0aHMsICRvdGhlckxvY2F0aW9ucyk7CgogICAgICAgIGZvcmVhY2ggKCRjYUJ1bmRsZVBhdGhzIGFzICRjYUJ1bmRsZSkgewogICAgICAgICAgICBpZiAoJGNhQnVuZGxlICYmIHNlbGY6OmNhRmlsZVVzYWJsZSgkY2FCdW5kbGUsICRsb2dnZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGNhUGF0aCA9ICRjYUJ1bmRsZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjYUJ1bmRsZSAmJiBzZWxmOjpjYURpclVzYWJsZSgkY2FCdW5kbGUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6JGNhUGF0aCA9ICRjYUJ1bmRsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRjYVBhdGggPSBzdGF0aWM6OmdldEJ1bmRsZWRDYUJ1bmRsZVBhdGgoKTsgLy8gQnVuZGxlZCBDQSBmaWxlLCBsYXN0IHJlc29ydAogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGF0aCB0byB0aGUgYnVuZGxlZCBDQSBmaWxlCiAgICAgKgogICAgICogSW4gY2FzZSB5b3UgZG9uJ3Qgd2FudCB0byB0cnVzdCB0aGUgdXNlciBvciB0aGUgc3lzdGVtLCB5b3UgY2FuIHVzZSB0aGlzIGRpcmVjdGx5CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcGF0aCB0byBhIENBIGJ1bmRsZSBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QnVuZGxlZENhQnVuZGxlUGF0aCgpCiAgICB7CiAgICAgICAgJGNhQnVuZGxlRmlsZSA9IF9fRElSX18uJy8uLi9yZXMvY2FjZXJ0LnBlbSc7CgogICAgICAgIC8vIGNVUkwgZG9lcyBub3QgdW5kZXJzdGFuZCAncGhhcjovLycgcGF0aHMKICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NhLWJ1bmRsZS9pc3N1ZXMvMTAKICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRjYUJ1bmRsZUZpbGUsICdwaGFyOi8vJykpIHsKICAgICAgICAgICAgJHRlbXBDYUJ1bmRsZUZpbGUgPSB0ZW1wbmFtKHN5c19nZXRfdGVtcF9kaXIoKSwgJ29wZW5zc2wtY2EtYnVuZGxlLScpOwogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICR0ZW1wQ2FCdW5kbGVGaWxlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBjcmVhdGUgYSB0ZW1wb3JhcnkgZmlsZSB0byBzdG9yZSB0aGUgYnVuZGxlZCBDQSBmaWxlJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKAogICAgICAgICAgICAgICAgJHRlbXBDYUJ1bmRsZUZpbGUsCiAgICAgICAgICAgICAgICBmaWxlX2dldF9jb250ZW50cygkY2FCdW5kbGVGaWxlKQogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oZnVuY3Rpb24oKSB1c2UgKCR0ZW1wQ2FCdW5kbGVGaWxlKSB7CiAgICAgICAgICAgICAgICBAdW5saW5rKCR0ZW1wQ2FCdW5kbGVGaWxlKTsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAkY2FCdW5kbGVGaWxlID0gJHRlbXBDYUJ1bmRsZUZpbGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNhQnVuZGxlRmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyBhIENBIGZpbGUgdXNpbmcgb3BlbnNsX3g1MDlfcGFyc2Ugb25seSBpZiBpdCBpcyBzYWZlIHRvIHVzZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJGZpbGVuYW1lCiAgICAgKiBAcGFyYW0gTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIgICBvcHRpb25hbCBsb2dnZXIgZm9yIGluZm9ybWF0aW9uIGFib3V0IHdoaWNoIENBIGZpbGVzIHdlcmUgbG9hZGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFsaWRhdGVDYUZpbGUoJGZpbGVuYW1lLCBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlciA9IG51bGwpCiAgICB7CiAgICAgICAgc3RhdGljICR3YXJuZWQgPSBmYWxzZTsKCiAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRjYUZpbGVWYWxpZGl0eVskZmlsZW5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGNhRmlsZVZhbGlkaXR5WyRmaWxlbmFtZV07CiAgICAgICAgfQoKICAgICAgICAkY29udGVudHMgPSBmaWxlX2dldF9jb250ZW50cygkZmlsZW5hbWUpOwoKICAgICAgICAvLyBhc3N1bWUgdGhlIENBIGlzIHZhbGlkIGlmIHBocCBpcyB2dWxuZXJhYmxlIHRvCiAgICAgICAgLy8gaHR0cHM6Ly93d3cuc2VrdGlvbmVpbnMuZGUvYWR2aXNvcmllcy9hZHZpc29yeS0wMTIwMTMtcGhwLW9wZW5zc2xfeDUwOV9wYXJzZS1tZW1vcnktY29ycnVwdGlvbi12dWxuZXJhYmlsaXR5Lmh0bWwKICAgICAgICBpZiAoIXN0YXRpYzo6aXNPcGVuc3NsUGFyc2VTYWZlKCkpIHsKICAgICAgICAgICAgaWYgKCEkd2FybmVkICYmICRsb2dnZXIpIHsKICAgICAgICAgICAgICAgICRsb2dnZXItPndhcm5pbmcoc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAnWW91ciB2ZXJzaW9uIG9mIFBIUCwgJXMsIGlzIGFmZmVjdGVkIGJ5IENWRS0yMDEzLTY0MjAgYW5kIGNhbm5vdCBzYWZlbHkgcGVyZm9ybSBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uLCB3ZSBzdHJvbmdseSBzdWdnZXN0IHlvdSB1cGdyYWRlLicsCiAgICAgICAgICAgICAgICAgICAgUEhQX1ZFUlNJT04KICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgJHdhcm5lZCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpc1ZhbGlkID0gIWVtcHR5KCRjb250ZW50cyk7CiAgICAgICAgfSBlbHNlaWYgKGlzX3N0cmluZygkY29udGVudHMpICYmIHN0cmxlbigkY29udGVudHMpID4gMCkgewogICAgICAgICAgICAkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoIi9eKFxcLSsoPzpCRUdJTnxFTkQpKVxccytUUlVTVEVEXFxzKyhDRVJUSUZJQ0FURVxcLSspXCQvbSIsICckMSAkMicsICRjb250ZW50cyk7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkY29udGVudHMpIHsKICAgICAgICAgICAgICAgIC8vIHJlZ2V4IGV4dHJhY3Rpb24gZmFpbGVkCiAgICAgICAgICAgICAgICAkaXNWYWxpZCA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGlzVmFsaWQgPSAoYm9vbCkgb3BlbnNzbF94NTA5X3BhcnNlKCRjb250ZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkaXNWYWxpZCA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRsb2dnZXIpIHsKICAgICAgICAgICAgJGxvZ2dlci0+ZGVidWcoJ0NoZWNrZWQgQ0EgZmlsZSAnLnJlYWxwYXRoKCRmaWxlbmFtZSkuJzogJy4oJGlzVmFsaWQgPyAndmFsaWQnIDogJ2ludmFsaWQnKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGNhRmlsZVZhbGlkaXR5WyRmaWxlbmFtZV0gPSAkaXNWYWxpZDsKICAgIH0KCiAgICAvKioKICAgICAqIFRlc3QgaWYgaXQgaXMgc2FmZSB0byB1c2UgdGhlIFBIUCBmdW5jdGlvbiBvcGVuc3NsX3g1MDlfcGFyc2UoKS4KICAgICAqCiAgICAgKiBUaGlzIGNoZWNrcyBpZiBPcGVuU1NMIGV4dGVuc2lvbnMgaXMgdnVsbmVyYWJsZSB0byByZW1vdGUgY29kZSBleGVjdXRpb24KICAgICAqIHZpYSB0aGUgZXhwbG9pdCBkb2N1bWVudGVkIGFzIENWRS0yMDEzLTY0MjAuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNPcGVuc3NsUGFyc2VTYWZlKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZTsKICAgICAgICB9CgogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA1MDYwMCkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBWdWxuZXJhYmxlOgogICAgICAgIC8vIFBIUCA1LjMuMCAtIFBIUCA1LjMuMjcKICAgICAgICAvLyBQSFAgNS40LjAgLSBQSFAgNS40LjIyCiAgICAgICAgLy8gUEhQIDUuNS4wIC0gUEhQIDUuNS42CiAgICAgICAgaWYgKAogICAgICAgICAgICAgICAoUEhQX1ZFUlNJT05fSUQgPCA1MDQwMCAmJiBQSFBfVkVSU0lPTl9JRCA+PSA1MDMyOCkKICAgICAgICAgICAgfHwgKFBIUF9WRVJTSU9OX0lEIDwgNTA1MDAgJiYgUEhQX1ZFUlNJT05fSUQgPj0gNTA0MjMpCiAgICAgICAgICAgIHx8IFBIUF9WRVJTSU9OX0lEID49IDUwNTA3CiAgICAgICAgKSB7CiAgICAgICAgICAgIC8vIFRoaXMgdmVyc2lvbiBvZiBQSFAgaGFzIHRoZSBmaXggZm9yIENWRS0yMDEzLTY0MjAgYXBwbGllZC4KICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRlZmluZWQoJ1BIUF9XSU5ET1dTX1ZFUlNJT05fQlVJTEQnKSkgewogICAgICAgICAgICAvLyBXaW5kb3dzIGlzIHByb2JhYmx5IGluc2VjdXJlIGluIHRoaXMgY2FzZS4KICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb21wYXJlRGlzdHJvVmVyc2lvblByZWZpeCA9IGZ1bmN0aW9uICgkcHJlZml4LCAkZml4ZWRWZXJzaW9uKSB7CiAgICAgICAgICAgICRyZWdleCA9ICd7XicucHJlZ19xdW90ZSgkcHJlZml4KS4nKFswLTldKykkfSc7CgogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcmVnZXgsIFBIUF9WRVJTSU9OLCAkbSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoKGludCkgJG1bMV0pID49ICRmaXhlZFZlcnNpb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9OwoKICAgICAgICAvLyBIYXJkIGNvZGVkIGxpc3Qgb2YgUEhQIGRpc3RyaWJ1dGlvbnMgd2l0aCB0aGUgZml4IGJhY2twb3J0ZWQuCiAgICAgICAgaWYgKAogICAgICAgICAgICAkY29tcGFyZURpc3Ryb1ZlcnNpb25QcmVmaXgoJzUuMy4zLTcrc3F1ZWV6ZScsIDE4KSAvLyBEZWJpYW4gNiAoU3F1ZWV6ZSkKICAgICAgICAgICAgfHwgJGNvbXBhcmVEaXN0cm9WZXJzaW9uUHJlZml4KCc1LjQuNC0xNCtkZWI3dScsIDcpIC8vIERlYmlhbiA3IChXaGVlenkpCiAgICAgICAgICAgIHx8ICRjb21wYXJlRGlzdHJvVmVyc2lvblByZWZpeCgnNS4zLjEwLTF1YnVudHUzLicsIDkpIC8vIFVidW50dSAxMi4wNCAoUHJlY2lzZSkKICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gU3ltZm9ueSBQcm9jZXNzIGNvbXBvbmVudCBpcyBtaXNzaW5nIHNvIHdlIGFzc3VtZSBpdCBpcyB1bnNhZmUgYXQgdGhpcyBwb2ludAogICAgICAgIGlmICghY2xhc3NfZXhpc3RzKCdTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFBocFByb2Nlc3MnKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHVzZU9wZW5zc2xQYXJzZSA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gVGhpcyBpcyB3aGVyZSB0aGluZ3MgZ2V0IGNyYXp5LCBiZWNhdXNlIGRpc3Ryb3MgYmFja3BvcnQgc2VjdXJpdHkKICAgICAgICAvLyBmaXhlcyB0aGUgY2hhbmNlcyBhcmUgb24gTklYIHN5c3RlbXMgdGhlIGZpeCBoYXMgYmVlbiBhcHBsaWVkIGJ1dAogICAgICAgIC8vIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHZlcmlmeSB0aGF0IGZyb20gdGhlIFBIUCB2ZXJzaW9uLgogICAgICAgIC8vCiAgICAgICAgLy8gVG8gdmVyaWZ5IGV4ZWMgYSBuZXcgUEhQIHByb2Nlc3MgYW5kIHJ1biB0aGUgaXNzdWUgdGVzdGNhc2Ugd2l0aAogICAgICAgIC8vIGtub3duIHNhZmUgaW5wdXQgdGhhdCByZXBsaWNhdGVzIHRoZSBidWcuCgogICAgICAgIC8vIEJhc2VkIG9uIHRlc3RjYXNlIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAvcGhwLXNyYy9jb21taXQvYzEyMjQ1NzNjNzczYjY4NDVlODM1MDVmNzE3ZmJmODIwZmMxODQxNQogICAgICAgIC8vIGNoYW5nZXMgaW4gaHR0cHM6Ly9naXRodWIuY29tL3BocC9waHAtc3JjL2NvbW1pdC83NmE3ZmQ4OTNiN2Q2MTAxMzAwY2M2NTYwNTg3MDRhNzMyNTRkNTkzCiAgICAgICAgJGNlcnQgPSAnTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVVndSRU5EUVRSNVowRjNTVUpCWjBsS1FVcDZkVGh5Tm5VMlpVSmpUVUV3UjBOVGNVZFRTV0l6UkZGRlFrSlJWVUZOU1VoRVRWRnpkME5SV1VRS1ZsRlJSMFYzU2tWU1ZFVmpUVUp2UjBFeFZVVkRRWGRVVkcwNWVWcElTbTlhVjJ4MVRGWmtiR016VW0xWlYzaHNZbXBGVVUxQk5FZEJNVlZGUW5kM1NBcFRPRTlFZDNKYWMySnFSVlZOUWtsSFFURlZSVU5uZDB4Vk1sWnlaRWRzZG1KclZuQmliazE0U0hwQlpFSm5UbFpDUVhOTlJtc3hhR0pIYkdwaFZ6a3hDbU41UWtSYVdFb3dTVVpPYkZrelVuQmlNalI0U1ZSQlprSm5UbFpDUVUxTlIwY3hhR0pIYkdwaFZ6a3hZM2sxZWxwWGREQmhWemwxV2xkc2RXTjVOV3NLV2xSRmNVMURaMGREVTNGSFUwbGlNMFJSUlVwQlVsbGlZek5TYkZwdFJuVk1iVlo2WXpKV2VWRklUbXhoTTFKd1lqSTFiR0ZYTlhwTWJWSnNUVWhWV1FwYVJFVTFUbnBCZDAxVVFYaE5SRUYzVFVSQmQxZG5RVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQkNrRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRUtRVUZCUVVGQlFWaEVWRVV3VFZSRmVVOUVSWGhOZW10NlRsWnZkMmRqVFhoRGVrRktRbWRPVmtKQldWUkJhMUpHVFZKM2QwZG5XVVJXVVZGSlJFSk9Ud3BpTTBwclkyMW9iR0ZYTkhSV01sWjZaRWRhYUdKSFZuVk5Va0YzUkdkWlJGWlJVVWhFUVdSTWR6UlFRM1J0ZUhWTlVsRjNSV2RaUkZaUlVVdEVRWFJVQ2xwWGREQmhWemwxVWxkc2RXTjZSV1pOUWpCSFFURlZSVU4zZDFkVVYwWnpZVmRPY0dJelZucEpSVTVzWTI1UloxVXlWbXBrUjJ4MlltcEZhRTFDT0VjS1FURlZSVUYzZDFsaVYwWnpZVmRPY0dJelZucE1iazVzWVROU2NHSXlOV3hoVnpWNlRHMVNiRTFUYjNkTFFWbEtTMjlhU1doMlkwNUJVV3RDUm1oMGVncGtSMVp0V1ZjMGRWcFlUbnBhV0VwQll6SldjbVJIYkhaaWJWWndZbTVOZFZwSFZYZG5aMFZwVFVFd1IwTlRjVWRUU1dJelJGRkZRa0ZSVlVGQk5FbENDa1IzUVhkblowVkxRVzlKUWtGUlJFUkJaak5vYkRkS1dUQllZMFp1YVhsRlNuQlRVMFJ4YmpCUGNVSnlObEZRTmpWMWMwcFFVblF2T0ZCaFJHOXhRblVLZDBWWlZDOU9ZU3MyWm5OblVHcERNSFZMT1VSYVoxZG5NblJJVjFkdllXNVRZbXhCVFc5Nk5WQklObG9yVXpSVFNGSmFOMlV5WkVSSmFsQnFaR2hxYUFvd2JVeG5NbFZOVHpWNWNEQldOemszUjJkek9XeE9kRFpLVW1aSU9ERk5Uakp2WWxoWGN6Uk9kSHAwVEUxMVJEWmxaM0Z3Y2poa1JHSnlNelJoVDNNNENuQnJaSFZwTlZWaGQxUmFhM041TlhCTVVFaHhOV05OYUVaSGJUQTJkalkxUTB4dk1GWXlVR1E1SzB0QmIydFFjbEJqVGpWTFRFdGxZbm8zYlV4d2F6WUtVMDFsUlZoUFMxQTBhV1JGY1hoNVVUZFBOMlpDZFVoTlpXUnpVV2gxSzNCeVdUTnphVE5DVlhsTFpsRjBVRFZEV201WU1tSndNSGRMU0hoWU1USkVXQW94Ym1aR1NYUTVSR0pIZGtoVVkzbFBkVTRyYmxwTVVFSnRNM1pYZUc1MGVVbEpkbFpCWjAxQ1FVRkhhbEZxUWtGTlFXdEhRVEZWWkVWM1VVTk5RVUYzQ2tWUldVcFpTVnBKUVZsaU5GRm5SVUpDUVZGRVFXZGxRVTFCYzBkQk1WVmtSSGRSUlVGM1NVWnZSRUZVUW1kT1ZraFRWVVZFUkVGTFFtZG5ja0puUlVZS1FsRmpSRUZxUVU1Q1oydHhhR3RwUnpsM01FSkJVVlZHUVVGUFEwRlJSVUZITUdaYVdWbERWR0prYWpGWVdXTXJNVk51YjJGUVVpdDJTVGhET0VOaFJBbzRLekJWV1doa2JubFZOR2RuWVRCQ1FXTkVjbGs1WlRrMFpVVkJkVFphY1hsalJqWkdha3h4V0Zoa1FXSnZjSEJYYjJOeU5sUTJSMFF4ZURNelEydHNDbFpCY25wSEwwdDRVVzlvUjBReVNtVnhhMmhKVFd4RWIyMTRTRTgzYTJFek9TdFBZVGhwTW5aWFRGWjVhbFU0UVZwMlYwMUJjblZJWVRSRlJVNTVSemNLYkZjeVFXRm5ZVVpMUmtOeU9WUnVXRlJtY21SNFIxWkZZblkzUzFaUk5tSmthR2MxY0RWVGFuQlhTREVyVFhFd00zVlNNMXBZVUVKWlpIbFdPRE14T1Fwdk1HeFdhakZMUmtreVJFTk1MMnhwVjJselNsSnZiMllyTVdOU016VkRkR1F3ZDFsQ1kzQkNObFJhYzJ4TlkwOVFiRGMyWkhkTGQwcG5aVXB2TWxGbkNscHpabTFqTW5aRE1TOXhUMnhPZFU1eEx6QlVlbnByVmtkMk9FVlVWRE5EWjJGVksxVllaVFJZVDFaMmEyTmpaV0pLYmpKa1p6MDlDaTB0TFMwdFJVNUVJRU5GVWxSSlJrbERRVlJGTFMwdExTMEsnOwogICAgICAgICRzY3JpcHQgPSA8PDwnRU9UJwoKZXJyb3JfcmVwb3J0aW5nKC0xKTsKJGluZm8gPSBvcGVuc3NsX3g1MDlfcGFyc2UoYmFzZTY0X2RlY29kZSgnJXMnKSk7CnZhcl9kdW1wKFBIUF9WRVJTSU9OLCAkaW5mb1snaXNzdWVyJ11bJ2VtYWlsQWRkcmVzcyddLCAkaW5mb1sndmFsaWRGcm9tX3RpbWVfdCddKTsKCkVPVDsKICAgICAgICAkc2NyaXB0ID0gJzwnLiI/cGhwXG4iLnNwcmludGYoJHNjcmlwdCwgJGNlcnQpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkcHJvY2VzcyA9IG5ldyBQaHBQcm9jZXNzKCRzY3JpcHQpOwogICAgICAgICAgICAkcHJvY2Vzcy0+bXVzdFJ1bigpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgLy8gSW4gdGhlIGNhc2Ugb2YgYW55IGV4Y2VwdGlvbnMganVzdCBhY2NlcHQgaXQgaXMgbm90IHBvc3NpYmxlIHRvCiAgICAgICAgICAgIC8vIGRldGVybWluZSB0aGUgc2FmZXR5IG9mIG9wZW5zc2xfeDUwOV9wYXJzZSBhbmQgYmFpbCBvdXQuCiAgICAgICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0ID0gcHJlZ19zcGxpdCgne1xyP1xufScsIHRyaW0oJHByb2Nlc3MtPmdldE91dHB1dCgpKSk7CiAgICAgICAgJGVycm9yT3V0cHV0ID0gdHJpbSgkcHJvY2Vzcy0+Z2V0RXJyb3JPdXRwdXQoKSk7CgogICAgICAgIGlmICgKICAgICAgICAgICAgaXNfYXJyYXkoJG91dHB1dCkKICAgICAgICAgICAgJiYgY291bnQoJG91dHB1dCkgPT09IDMKICAgICAgICAgICAgJiYgJG91dHB1dFswXSA9PT0gc3ByaW50Zignc3RyaW5nKCVkKSAiJXMiJywgc3RybGVuKFBIUF9WRVJTSU9OKSwgUEhQX1ZFUlNJT04pCiAgICAgICAgICAgICYmICRvdXRwdXRbMV0gPT09ICdzdHJpbmcoMjcpICJzdGVmYW4uZXNzZXJAc2VrdGlvbmVpbnMuZGUiJwogICAgICAgICAgICAmJiAkb3V0cHV0WzJdID09PSAnaW50KC0xKScKICAgICAgICAgICAgJiYgcHJlZ19tYXRjaCgne29wZW5zc2xfeDUwOV9wYXJzZVwoXCk6IGlsbGVnYWwgKD86QVNOMSBkYXRhIHR5cGUgZm9yfGxlbmd0aCBpbikgdGltZXN0YW1wIGluIC0gb24gbGluZSBcZCt9JywgJGVycm9yT3V0cHV0KQogICAgICAgICkgewogICAgICAgICAgICAvLyBUaGlzIFBIUCBoYXMgdGhlIGZpeCBiYWNrcG9ydGVkIHByb2JhYmx5IGJ5IGEgZGlzdHJvIHNlY3VyaXR5IHRlYW0uCiAgICAgICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokdXNlT3BlbnNzbFBhcnNlID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNldHMgdGhlIHN0YXRpYyBjYWNoZXMKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICBzZWxmOjokY2FGaWxlVmFsaWRpdHkgPSBhcnJheSgpOwogICAgICAgIHNlbGY6OiRjYVBhdGggPSBudWxsOwogICAgICAgIHNlbGY6OiR1c2VPcGVuc3NsUGFyc2UgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgJG5hbWUKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldEVudlZhcmlhYmxlKCRuYW1lKQogICAgewogICAgICAgIGlmIChpc3NldCgkX1NFUlZFUlskbmFtZV0pKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSAkX1NFUlZFUlskbmFtZV07CiAgICAgICAgfQoKICAgICAgICBpZiAoUEhQX1NBUEkgPT09ICdjbGknICYmICgkdmFsdWUgPSBnZXRlbnYoJG5hbWUpKSAhPT0gZmFsc2UgJiYgJHZhbHVlICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZ3xmYWxzZSAkY2VydEZpbGUKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjYUZpbGVVc2FibGUoJGNlcnRGaWxlLCBMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlciA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICRjZXJ0RmlsZSAmJiBAaXNfZmlsZSgkY2VydEZpbGUpICYmIEBpc19yZWFkYWJsZSgkY2VydEZpbGUpICYmIHN0YXRpYzo6dmFsaWRhdGVDYUZpbGUoJGNlcnRGaWxlLCAkbG9nZ2VyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSAgc3RyaW5nfGZhbHNlICRjZXJ0RGlyCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY2FEaXJVc2FibGUoJGNlcnREaXIpCiAgICB7CiAgICAgICAgcmV0dXJuICRjZXJ0RGlyICYmIEBpc19kaXIoJGNlcnREaXIpICYmIEBpc19yZWFkYWJsZSgkY2VydERpcikgJiYgZ2xvYigkY2VydERpciAuICcvKicpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2VzczsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFByb2Nlc3NGYWlsZWRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxQcm9jZXNzVGltZWRPdXRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlc1xQaXBlc0ludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUGlwZXNcVW5peFBpcGVzOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlc1xXaW5kb3dzUGlwZXM7CgovKioKICogUHJvY2VzcyBpcyBhIHRoaW4gd3JhcHBlciBhcm91bmQgcHJvY18qIGZ1bmN0aW9ucyB0byBlYXNpbHkKICogc3RhcnQgaW5kZXBlbmRlbnQgUEhQIHByb2Nlc3Nlcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqLwpjbGFzcyBQcm9jZXNzIGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlCnsKICAgIGNvbnN0IEVSUiA9ICdlcnInOwogICAgY29uc3QgT1VUID0gJ291dCc7CgogICAgY29uc3QgU1RBVFVTX1JFQURZID0gJ3JlYWR5JzsKICAgIGNvbnN0IFNUQVRVU19TVEFSVEVEID0gJ3N0YXJ0ZWQnOwogICAgY29uc3QgU1RBVFVTX1RFUk1JTkFURUQgPSAndGVybWluYXRlZCc7CgogICAgY29uc3QgU1RESU4gPSAwOwogICAgY29uc3QgU1RET1VUID0gMTsKICAgIGNvbnN0IFNUREVSUiA9IDI7CgogICAgLy8gVGltZW91dCBQcmVjaXNpb24gaW4gc2Vjb25kcy4KICAgIGNvbnN0IFRJTUVPVVRfUFJFQ0lTSU9OID0gMC4yOwoKICAgIGNvbnN0IElURVJfTk9OX0JMT0NLSU5HID0gMTsgLy8gQnkgZGVmYXVsdCwgaXRlcmF0aW5nIG92ZXIgb3V0cHV0cyBpcyBhIGJsb2NraW5nIGNhbGwsIHVzZSB0aGlzIGZsYWcgdG8gbWFrZSBpdCBub24tYmxvY2tpbmcKICAgIGNvbnN0IElURVJfS0VFUF9PVVRQVVQgPSAyOyAgLy8gQnkgZGVmYXVsdCwgb3V0cHV0cyBhcmUgY2xlYXJlZCB3aGlsZSBpdGVyYXRpbmcsIHVzZSB0aGlzIGZsYWcgdG8ga2VlcCB0aGVtIGluIG1lbW9yeQogICAgY29uc3QgSVRFUl9TS0lQX09VVCA9IDQ7ICAgICAvLyBVc2UgdGhpcyBmbGFnIHRvIHNraXAgU1RET1VUIHdoaWxlIGl0ZXJhdGluZwogICAgY29uc3QgSVRFUl9TS0lQX0VSUiA9IDg7ICAgICAvLyBVc2UgdGhpcyBmbGFnIHRvIHNraXAgU1RERVJSIHdoaWxlIGl0ZXJhdGluZwoKICAgIHByaXZhdGUgJGNhbGxiYWNrOwogICAgcHJpdmF0ZSAkaGFzQ2FsbGJhY2sgPSBmYWxzZTsKICAgIHByaXZhdGUgJGNvbW1hbmRsaW5lOwogICAgcHJpdmF0ZSAkY3dkOwogICAgcHJpdmF0ZSAkZW52OwogICAgcHJpdmF0ZSAkaW5wdXQ7CiAgICBwcml2YXRlICRzdGFydHRpbWU7CiAgICBwcml2YXRlICRsYXN0T3V0cHV0VGltZTsKICAgIHByaXZhdGUgJHRpbWVvdXQ7CiAgICBwcml2YXRlICRpZGxlVGltZW91dDsKICAgIHByaXZhdGUgJG9wdGlvbnMgPSBbJ3N1cHByZXNzX2Vycm9ycycgPT4gdHJ1ZV07CiAgICBwcml2YXRlICRleGl0Y29kZTsKICAgIHByaXZhdGUgJGZhbGxiYWNrU3RhdHVzID0gW107CiAgICBwcml2YXRlICRwcm9jZXNzSW5mb3JtYXRpb247CiAgICBwcml2YXRlICRvdXRwdXREaXNhYmxlZCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkc3Rkb3V0OwogICAgcHJpdmF0ZSAkc3RkZXJyOwogICAgcHJpdmF0ZSAkZW5oYW5jZVdpbmRvd3NDb21wYXRpYmlsaXR5ID0gdHJ1ZTsKICAgIHByaXZhdGUgJGVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHk7CiAgICBwcml2YXRlICRwcm9jZXNzOwogICAgcHJpdmF0ZSAkc3RhdHVzID0gc2VsZjo6U1RBVFVTX1JFQURZOwogICAgcHJpdmF0ZSAkaW5jcmVtZW50YWxPdXRwdXRPZmZzZXQgPSAwOwogICAgcHJpdmF0ZSAkaW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCA9IDA7CiAgICBwcml2YXRlICR0dHkgPSBmYWxzZTsKICAgIHByaXZhdGUgJHB0eTsKICAgIHByaXZhdGUgJGluaGVyaXRFbnYgPSBmYWxzZTsKCiAgICBwcml2YXRlICR1c2VGaWxlSGFuZGxlcyA9IGZhbHNlOwogICAgLyoqIEB2YXIgUGlwZXNJbnRlcmZhY2UgKi8KICAgIHByaXZhdGUgJHByb2Nlc3NQaXBlczsKCiAgICBwcml2YXRlICRsYXRlc3RTaWduYWw7CgogICAgcHJpdmF0ZSBzdGF0aWMgJHNpZ2NoaWxkOwoKICAgIC8qKgogICAgICogRXhpdCBjb2RlcyB0cmFuc2xhdGlvbiB0YWJsZS4KICAgICAqCiAgICAgKiBVc2VyLWRlZmluZWQgZXJyb3JzIG11c3QgdXNlIGV4aXQgY29kZXMgaW4gdGhlIDY0LTExMyByYW5nZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkZXhpdENvZGVzID0gWwogICAgICAgIDAgPT4gJ09LJywKICAgICAgICAxID0+ICdHZW5lcmFsIGVycm9yJywKICAgICAgICAyID0+ICdNaXN1c2Ugb2Ygc2hlbGwgYnVpbHRpbnMnLAoKICAgICAgICAxMjYgPT4gJ0ludm9rZWQgY29tbWFuZCBjYW5ub3QgZXhlY3V0ZScsCiAgICAgICAgMTI3ID0+ICdDb21tYW5kIG5vdCBmb3VuZCcsCiAgICAgICAgMTI4ID0+ICdJbnZhbGlkIGV4aXQgYXJndW1lbnQnLAoKICAgICAgICAvLyBzaWduYWxzCiAgICAgICAgMTI5ID0+ICdIYW5ndXAnLAogICAgICAgIDEzMCA9PiAnSW50ZXJydXB0JywKICAgICAgICAxMzEgPT4gJ1F1aXQgYW5kIGR1bXAgY29yZScsCiAgICAgICAgMTMyID0+ICdJbGxlZ2FsIGluc3RydWN0aW9uJywKICAgICAgICAxMzMgPT4gJ1RyYWNlL2JyZWFrcG9pbnQgdHJhcCcsCiAgICAgICAgMTM0ID0+ICdQcm9jZXNzIGFib3J0ZWQnLAogICAgICAgIDEzNSA9PiAnQnVzIGVycm9yOiAiYWNjZXNzIHRvIHVuZGVmaW5lZCBwb3J0aW9uIG9mIG1lbW9yeSBvYmplY3QiJywKICAgICAgICAxMzYgPT4gJ0Zsb2F0aW5nIHBvaW50IGV4Y2VwdGlvbjogImVycm9uZW91cyBhcml0aG1ldGljIG9wZXJhdGlvbiInLAogICAgICAgIDEzNyA9PiAnS2lsbCAodGVybWluYXRlIGltbWVkaWF0ZWx5KScsCiAgICAgICAgMTM4ID0+ICdVc2VyLWRlZmluZWQgMScsCiAgICAgICAgMTM5ID0+ICdTZWdtZW50YXRpb24gdmlvbGF0aW9uJywKICAgICAgICAxNDAgPT4gJ1VzZXItZGVmaW5lZCAyJywKICAgICAgICAxNDEgPT4gJ1dyaXRlIHRvIHBpcGUgd2l0aCBubyBvbmUgcmVhZGluZycsCiAgICAgICAgMTQyID0+ICdTaWduYWwgcmFpc2VkIGJ5IGFsYXJtJywKICAgICAgICAxNDMgPT4gJ1Rlcm1pbmF0aW9uIChyZXF1ZXN0IHRvIHRlcm1pbmF0ZSknLAogICAgICAgIC8vIDE0NCAtIG5vdCBkZWZpbmVkCiAgICAgICAgMTQ1ID0+ICdDaGlsZCBwcm9jZXNzIHRlcm1pbmF0ZWQsIHN0b3BwZWQgKG9yIGNvbnRpbnVlZCopJywKICAgICAgICAxNDYgPT4gJ0NvbnRpbnVlIGlmIHN0b3BwZWQnLAogICAgICAgIDE0NyA9PiAnU3RvcCBleGVjdXRpbmcgdGVtcG9yYXJpbHknLAogICAgICAgIDE0OCA9PiAnVGVybWluYWwgc3RvcCBzaWduYWwnLAogICAgICAgIDE0OSA9PiAnQmFja2dyb3VuZCBwcm9jZXNzIGF0dGVtcHRpbmcgdG8gcmVhZCBmcm9tIHR0eSAoImluIiknLAogICAgICAgIDE1MCA9PiAnQmFja2dyb3VuZCBwcm9jZXNzIGF0dGVtcHRpbmcgdG8gd3JpdGUgdG8gdHR5ICgib3V0IiknLAogICAgICAgIDE1MSA9PiAnVXJnZW50IGRhdGEgYXZhaWxhYmxlIG9uIHNvY2tldCcsCiAgICAgICAgMTUyID0+ICdDUFUgdGltZSBsaW1pdCBleGNlZWRlZCcsCiAgICAgICAgMTUzID0+ICdGaWxlIHNpemUgbGltaXQgZXhjZWVkZWQnLAogICAgICAgIDE1NCA9PiAnU2lnbmFsIHJhaXNlZCBieSB0aW1lciBjb3VudGluZyB2aXJ0dWFsIHRpbWU6ICJ2aXJ0dWFsIHRpbWVyIGV4cGlyZWQiJywKICAgICAgICAxNTUgPT4gJ1Byb2ZpbGluZyB0aW1lciBleHBpcmVkJywKICAgICAgICAvLyAxNTYgLSBub3QgZGVmaW5lZAogICAgICAgIDE1NyA9PiAnUG9sbGFibGUgZXZlbnQnLAogICAgICAgIC8vIDE1OCAtIG5vdCBkZWZpbmVkCiAgICAgICAgMTU5ID0+ICdCYWQgc3lzY2FsbCcsCiAgICBdOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAgICRjb21tYW5kbGluZSBUaGUgY29tbWFuZCBsaW5lIHRvIHJ1bgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgICRjd2QgICAgICAgICBUaGUgd29ya2luZyBkaXJlY3Rvcnkgb3IgbnVsbCB0byB1c2UgdGhlIHdvcmtpbmcgZGlyIG9mIHRoZSBjdXJyZW50IFBIUCBwcm9jZXNzCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAgICAgJGVudiAgICAgICAgIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgb3IgbnVsbCB0byB1c2UgdGhlIHNhbWUgZW52aXJvbm1lbnQgYXMgdGhlIGN1cnJlbnQgUEhQIHByb2Nlc3MKICAgICAqIEBwYXJhbSBtaXhlZHxudWxsICAgICAkaW5wdXQgICAgICAgVGhlIGlucHV0IGFzIHN0cmVhbSByZXNvdXJjZSwgc2NhbGFyIG9yIFxUcmF2ZXJzYWJsZSwgb3IgbnVsbCBmb3Igbm8gaW5wdXQKICAgICAqIEBwYXJhbSBpbnR8ZmxvYXR8bnVsbCAkdGltZW91dCAgICAgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcyBvciBudWxsIHRvIGRpc2FibGUKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAkb3B0aW9ucyAgICAgQW4gYXJyYXkgb2Ygb3B0aW9ucyBmb3IgcHJvY19vcGVuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY19vcGVuIGlzIG5vdCBpbnN0YWxsZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb21tYW5kbGluZSwgJGN3ZCA9IG51bGwsIGFycmF5ICRlbnYgPSBudWxsLCAkaW5wdXQgPSBudWxsLCAkdGltZW91dCA9IDYwLCBhcnJheSAkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCFcZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVGhlIFByb2Nlc3MgY2xhc3MgcmVsaWVzIG9uIHByb2Nfb3Blbiwgd2hpY2ggaXMgbm90IGF2YWlsYWJsZSBvbiB5b3VyIFBIUCBpbnN0YWxsYXRpb24uJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29tbWFuZGxpbmUgPSAkY29tbWFuZGxpbmU7CiAgICAgICAgJHRoaXMtPmN3ZCA9ICRjd2Q7CgogICAgICAgIC8vIG9uIFdpbmRvd3MsIGlmIHRoZSBjd2QgY2hhbmdlZCB2aWEgY2hkaXIoKSwgcHJvY19vcGVuIGRlZmF1bHRzIHRvIHRoZSBkaXIgd2hlcmUgUEhQIHdhcyBzdGFydGVkCiAgICAgICAgLy8gb24gR251L0xpbnV4LCBQSFAgYnVpbGRzIHdpdGggLS1lbmFibGUtbWFpbnRhaW5lci16dHMgYXJlIGFsc28gYWZmZWN0ZWQKICAgICAgICAvLyBAc2VlIDogaHR0cHM6Ly9idWdzLnBocC5uZXQvNTE4MDAKICAgICAgICAvLyBAc2VlIDogaHR0cHM6Ly9idWdzLnBocC5uZXQvNTA1MjQKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmN3ZCAmJiAoXGRlZmluZWQoJ1pFTkRfVEhSRUFEX1NBRkUnKSB8fCAnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikpIHsKICAgICAgICAgICAgJHRoaXMtPmN3ZCA9IGdldGN3ZCgpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCAhPT0gJGVudikgewogICAgICAgICAgICAkdGhpcy0+c2V0RW52KCRlbnYpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNldElucHV0KCRpbnB1dCk7CiAgICAgICAgJHRoaXMtPnNldFRpbWVvdXQoJHRpbWVvdXQpOwogICAgICAgICR0aGlzLT51c2VGaWxlSGFuZGxlcyA9ICdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SOwogICAgICAgICR0aGlzLT5wdHkgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSA9ICdcXCcgIT09IFxESVJFQ1RPUllfU0VQQVJBVE9SICYmICR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpOwogICAgICAgIGlmIChudWxsICE9PSAkb3B0aW9ucykgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJG9wdGlvbnMgcGFyYW1ldGVyIG9mIHRoZSAlcyBjb25zdHJ1Y3RvciBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLicsIF9fQ0xBU1NfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgICAgICR0aGlzLT5vcHRpb25zID0gYXJyYXlfcmVwbGFjZSgkdGhpcy0+b3B0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0b3AoMCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY2xvbmUoKQogICAgewogICAgICAgICR0aGlzLT5yZXNldFByb2Nlc3NEYXRhKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIFRoZSBjYWxsYmFjayByZWNlaXZlcyB0aGUgdHlwZSBvZiBvdXRwdXQgKG91dCBvciBlcnIpIGFuZAogICAgICogc29tZSBieXRlcyBmcm9tIHRoZSBvdXRwdXQgaW4gcmVhbC10aW1lLiBJdCBhbGxvd3MgdG8gaGF2ZSBmZWVkYmFjawogICAgICogZnJvbSB0aGUgaW5kZXBlbmRlbnQgcHJvY2VzcyBkdXJpbmcgZXhlY3V0aW9uLgogICAgICoKICAgICAqIFRoZSBTVERPVVQgYW5kIFNUREVSUiBhcmUgYWxzbyBhdmFpbGFibGUgYWZ0ZXIgdGhlIHByb2Nlc3MgaXMgZmluaXNoZWQKICAgICAqIHZpYSB0aGUgZ2V0T3V0cHV0KCkgYW5kIGdldEVycm9yT3V0cHV0KCkgbWV0aG9kcy4KICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkY2FsbGJhY2sgQSBQSFAgY2FsbGJhY2sgdG8gcnVuIHdoZW5ldmVyIHRoZXJlIGlzIHNvbWUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgYXZhaWxhYmxlIG9uIFNURE9VVCBvciBTVERFUlIKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgZXhpdCBzdGF0dXMgY29kZQogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIHByb2Nlc3MgY2FuJ3QgYmUgbGF1bmNoZWQKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIHByb2Nlc3Mgc3RvcHBlZCBhZnRlciByZWNlaXZpbmcgc2lnbmFsCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgSW4gY2FzZSBhIGNhbGxiYWNrIGlzIHByb3ZpZGVkIGFuZCBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqCiAgICAgKiBAZmluYWwgc2luY2UgdmVyc2lvbiAzLjMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJ1bigkY2FsbGJhY2sgPSBudWxsLyosIGFycmF5ICRlbnYgPSBbXSovKQogICAgewogICAgICAgICRlbnYgPSAxIDwgXGZ1bmNfbnVtX2FyZ3MoKSA/IGZ1bmNfZ2V0X2FyZygxKSA6IG51bGw7CiAgICAgICAgJHRoaXMtPnN0YXJ0KCRjYWxsYmFjaywgJGVudik7CgogICAgICAgIHJldHVybiAkdGhpcy0+d2FpdCgpOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBUaGlzIGlzIGlkZW50aWNhbCB0byBydW4oKSBleGNlcHQgdGhhdCBhbiBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZSBwcm9jZXNzCiAgICAgKiBleGl0cyB3aXRoIGEgbm9uLXplcm8gZXhpdCBjb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gICAgICAgaWYgUEhQIHdhcyBjb21waWxlZCB3aXRoIC0tZW5hYmxlLXNpZ2NoaWxkIGFuZCB0aGUgZW5oYW5jZWQgc2lnY2hpbGQgY29tcGF0aWJpbGl0eSBtb2RlIGlzIG5vdCBlbmFibGVkCiAgICAgKiBAdGhyb3dzIFByb2Nlc3NGYWlsZWRFeGNlcHRpb24gaWYgdGhlIHByb2Nlc3MgZGlkbid0IHRlcm1pbmF0ZSBzdWNjZXNzZnVsbHkKICAgICAqCiAgICAgKiBAZmluYWwgc2luY2UgdmVyc2lvbiAzLjMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG11c3RSdW4oY2FsbGFibGUgJGNhbGxiYWNrID0gbnVsbC8qLCBhcnJheSAkZW52ID0gW10qLykKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5ICYmICR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUaGlzIFBIUCBoYXMgYmVlbiBjb21waWxlZCB3aXRoIC0tZW5hYmxlLXNpZ2NoaWxkLiBZb3UgbXVzdCB1c2Ugc2V0RW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSgpIHRvIHVzZSB0aGlzIG1ldGhvZC4nKTsKICAgICAgICB9CiAgICAgICAgJGVudiA9IDEgPCBcZnVuY19udW1fYXJncygpID8gZnVuY19nZXRfYXJnKDEpIDogbnVsbDsKCiAgICAgICAgaWYgKDAgIT09ICR0aGlzLT5ydW4oJGNhbGxiYWNrLCAkZW52KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbigkdGhpcyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdGFydHMgdGhlIHByb2Nlc3MgYW5kIHJldHVybnMgYWZ0ZXIgd3JpdGluZyB0aGUgaW5wdXQgdG8gU1RESU4uCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgYmxvY2tzIHVudGlsIGFsbCBTVERJTiBkYXRhIGlzIHNlbnQgdG8gdGhlIHByb2Nlc3MgdGhlbiBpdAogICAgICogcmV0dXJucyB3aGlsZSB0aGUgcHJvY2VzcyBydW5zIGluIHRoZSBiYWNrZ3JvdW5kLgogICAgICoKICAgICAqIFRoZSB0ZXJtaW5hdGlvbiBvZiB0aGUgcHJvY2VzcyBjYW4gYmUgYXdhaXRlZCB3aXRoIHdhaXQoKS4KICAgICAqCiAgICAgKiBUaGUgY2FsbGJhY2sgcmVjZWl2ZXMgdGhlIHR5cGUgb2Ygb3V0cHV0IChvdXQgb3IgZXJyKSBhbmQgc29tZSBieXRlcyBmcm9tCiAgICAgKiB0aGUgb3V0cHV0IGluIHJlYWwtdGltZSB3aGlsZSB3cml0aW5nIHRoZSBzdGFuZGFyZCBpbnB1dCB0byB0aGUgcHJvY2Vzcy4KICAgICAqIEl0IGFsbG93cyB0byBoYXZlIGZlZWRiYWNrIGZyb20gdGhlIGluZGVwZW5kZW50IHByb2Nlc3MgZHVyaW5nIGV4ZWN1dGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkY2FsbGJhY2sgQSBQSFAgY2FsbGJhY2sgdG8gcnVuIHdoZW5ldmVyIHRoZXJlIGlzIHNvbWUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgYXZhaWxhYmxlIG9uIFNURE9VVCBvciBTVERFUlIKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIGNhbid0IGJlIGxhdW5jaGVkCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIGlzIGFscmVhZHkgcnVubmluZwogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiAgIEluIGNhc2UgYSBjYWxsYmFjayBpcyBwcm92aWRlZCBhbmQgb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzdGFydChjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsLyosIGFycmF5ICRlbnYgPSBbKi8pCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignUHJvY2VzcyBpcyBhbHJlYWR5IHJ1bm5pbmcuJyk7CiAgICAgICAgfQogICAgICAgIGlmICgyIDw9IFxmdW5jX251bV9hcmdzKCkpIHsKICAgICAgICAgICAgJGVudiA9IGZ1bmNfZ2V0X2FyZygxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoX19DTEFTU19fICE9PSBzdGF0aWM6OmNsYXNzKSB7CiAgICAgICAgICAgICAgICAkciA9IG5ldyBcUmVmbGVjdGlvbk1ldGhvZCgkdGhpcywgX19GVU5DVElPTl9fKTsKICAgICAgICAgICAgICAgIGlmIChfX0NMQVNTX18gIT09ICRyLT5nZXREZWNsYXJpbmdDbGFzcygpLT5nZXROYW1lKCkgJiYgKDIgPiAkci0+Z2V0TnVtYmVyT2ZQYXJhbWV0ZXJzKCkgfHwgJ2VudicgIT09ICRyLT5nZXRQYXJhbWV0ZXJzKClbMV0tPm5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzOjpzdGFydCgpIG1ldGhvZCBleHBlY3RzIGEgc2Vjb25kICIkZW52IiBhcmd1bWVudCBzaW5jZSBTeW1mb255IDMuMy4gSXQgd2lsbCBiZSBtYWRlIG1hbmRhdG9yeSBpbiA0LjAuJywgc3RhdGljOjpjbGFzcyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVudiA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cmVzZXRQcm9jZXNzRGF0YSgpOwogICAgICAgICR0aGlzLT5zdGFydHRpbWUgPSAkdGhpcy0+bGFzdE91dHB1dFRpbWUgPSBtaWNyb3RpbWUodHJ1ZSk7CiAgICAgICAgJHRoaXMtPmNhbGxiYWNrID0gJHRoaXMtPmJ1aWxkQ2FsbGJhY2soJGNhbGxiYWNrKTsKICAgICAgICAkdGhpcy0+aGFzQ2FsbGJhY2sgPSBudWxsICE9PSAkY2FsbGJhY2s7CiAgICAgICAgJGRlc2NyaXB0b3JzID0gJHRoaXMtPmdldERlc2NyaXB0b3JzKCk7CiAgICAgICAgJGluaGVyaXRFbnYgPSAkdGhpcy0+aW5oZXJpdEVudjsKCiAgICAgICAgaWYgKFxpc19hcnJheSgkY29tbWFuZGxpbmUgPSAkdGhpcy0+Y29tbWFuZGxpbmUpKSB7CiAgICAgICAgICAgICRjb21tYW5kbGluZSA9IGltcGxvZGUoJyAnLCBhcnJheV9tYXAoWyR0aGlzLCAnZXNjYXBlQXJndW1lbnQnXSwgJGNvbW1hbmRsaW5lKSk7CgogICAgICAgICAgICBpZiAoJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgICAgIC8vIGV4ZWMgaXMgbWFuZGF0b3J5IHRvIGRlYWwgd2l0aCBzZW5kaW5nIGEgc2lnbmFsIHRvIHRoZSBwcm9jZXNzCiAgICAgICAgICAgICAgICAkY29tbWFuZGxpbmUgPSAnZXhlYyAnLiRjb21tYW5kbGluZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRlbnYpIHsKICAgICAgICAgICAgJGVudiA9ICR0aGlzLT5lbnY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5lbnYpIHsKICAgICAgICAgICAgICAgICRlbnYgKz0gJHRoaXMtPmVudjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaW5oZXJpdEVudiA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGVudiAmJiAkaW5oZXJpdEVudikgewogICAgICAgICAgICAkZW52ICs9ICR0aGlzLT5nZXREZWZhdWx0RW52KCk7CiAgICAgICAgfSBlbHNlaWYgKG51bGwgIT09ICRlbnYpIHsKICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3IoJ05vdCBpbmhlcml0aW5nIGVudmlyb25tZW50IHZhcmlhYmxlcyBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGFsd2F5cyBoYXBwZW4gaW4gNC4wLiBTZXQgIlByb2Nlc3M6OmluaGVyaXRFbnZpcm9ubWVudFZhcmlhYmxlcygpIiB0byB0cnVlIGluc3RlYWQuJywgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZW52ID0gJHRoaXMtPmdldERlZmF1bHRFbnYoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SICYmICR0aGlzLT5lbmhhbmNlV2luZG93c0NvbXBhdGliaWxpdHkpIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnNbJ2J5cGFzc19zaGVsbCddID0gdHJ1ZTsKICAgICAgICAgICAgJGNvbW1hbmRsaW5lID0gJHRoaXMtPnByZXBhcmVXaW5kb3dzQ29tbWFuZExpbmUoJGNvbW1hbmRsaW5lLCAkZW52KTsKICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT51c2VGaWxlSGFuZGxlcyAmJiAkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSAmJiAkdGhpcy0+aXNTaWdjaGlsZEVuYWJsZWQoKSkgewogICAgICAgICAgICAvLyBsYXN0IGV4aXQgY29kZSBpcyBvdXRwdXQgb24gdGhlIGZvdXJ0aCBwaXBlIGFuZCBjYXVnaHQgdG8gd29yayBhcm91bmQgLS1lbmFibGUtc2lnY2hpbGQKICAgICAgICAgICAgJGRlc2NyaXB0b3JzWzNdID0gWydwaXBlJywgJ3cnXTsKCiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL3VuaXguc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzcxMjA1L2JhY2tncm91bmQtcHJvY2Vzcy1waXBlLWlucHV0CiAgICAgICAgICAgICRjb21tYW5kbGluZSA9ICd7ICgnLiRjb21tYW5kbGluZS4nKSA8JjMgMzwmLSAzPi9kZXYvbnVsbCAmIH0gMzwmMDsnOwogICAgICAgICAgICAkY29tbWFuZGxpbmUgLj0gJ3BpZD0kITsgZWNobyAkcGlkID4mMzsgd2FpdCAkcGlkOyBjb2RlPSQ/OyBlY2hvICRjb2RlID4mMzsgZXhpdCAkY29kZSc7CgogICAgICAgICAgICAvLyBXb3JrYXJvdW5kIGZvciB0aGUgYnVnLCB3aGVuIFBUUyBmdW5jdGlvbmFsaXR5IGlzIGVuYWJsZWQuCiAgICAgICAgICAgIC8vIEBzZWUgOiBodHRwczovL2J1Z3MucGhwLm5ldC82OTQ0MgogICAgICAgICAgICAkcHRzV29ya2Fyb3VuZCA9IGZvcGVuKF9fRklMRV9fLCAncicpOwogICAgICAgIH0KICAgICAgICBpZiAoXGRlZmluZWQoJ0hIVk1fVkVSU0lPTicpKSB7CiAgICAgICAgICAgICRlbnZQYWlycyA9ICRlbnY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGVudlBhaXJzID0gW107CiAgICAgICAgICAgIGZvcmVhY2ggKCRlbnYgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gJHYpIHsKICAgICAgICAgICAgICAgICAgICAkZW52UGFpcnNbXSA9ICRrLic9Jy4kdjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc19kaXIoJHRoaXMtPmN3ZCkpIHsKICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3IoJ1RoZSBwcm92aWRlZCBjd2QgZG9lcyBub3QgZXhpc3QuIENvbW1hbmQgaXMgY3VycmVudGx5IHJhbiBhZ2FpbnN0IGdldGN3ZCgpLiBUaGlzIGJlaGF2aW9yIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuJywgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5wcm9jZXNzID0gQHByb2Nfb3BlbigkY29tbWFuZGxpbmUsICRkZXNjcmlwdG9ycywgJHRoaXMtPnByb2Nlc3NQaXBlcy0+cGlwZXMsICR0aGlzLT5jd2QsICRlbnZQYWlycywgJHRoaXMtPm9wdGlvbnMpOwoKICAgICAgICBpZiAoIVxpc19yZXNvdXJjZSgkdGhpcy0+cHJvY2VzcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1VuYWJsZSB0byBsYXVuY2ggYSBuZXcgcHJvY2Vzcy4nKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnN0YXR1cyA9IHNlbGY6OlNUQVRVU19TVEFSVEVEOwoKICAgICAgICBpZiAoaXNzZXQoJGRlc2NyaXB0b3JzWzNdKSkgewogICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ3BpZCddID0gKGludCkgZmdldHMoJHRoaXMtPnByb2Nlc3NQaXBlcy0+cGlwZXNbM10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT50dHkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnVwZGF0ZVN0YXR1cyhmYWxzZSk7CiAgICAgICAgJHRoaXMtPmNoZWNrVGltZW91dCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmVzdGFydHMgdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogQmUgd2FybmVkIHRoYXQgdGhlIHByb2Nlc3MgaXMgY2xvbmVkIGJlZm9yZSBiZWluZyBzdGFydGVkLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRjYWxsYmFjayBBIFBIUCBjYWxsYmFjayB0byBydW4gd2hlbmV2ZXIgdGhlcmUgaXMgc29tZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCBhdmFpbGFibGUgb24gU1RET1VUIG9yIFNUREVSUgogICAgICoKICAgICAqIEByZXR1cm4gc3RhdGljCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY2VzcyBjYW4ndCBiZSBsYXVuY2hlZAogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY2VzcyBpcyBhbHJlYWR5IHJ1bm5pbmcKICAgICAqCiAgICAgKiBAc2VlIHN0YXJ0KCkKICAgICAqCiAgICAgKiBAZmluYWwgc2luY2UgdmVyc2lvbiAzLjMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc3RhcnQoY2FsbGFibGUgJGNhbGxiYWNrID0gbnVsbC8qLCBhcnJheSAkZW52ID0gW10qLykKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdQcm9jZXNzIGlzIGFscmVhZHkgcnVubmluZy4nKTsKICAgICAgICB9CiAgICAgICAgJGVudiA9IDEgPCBcZnVuY19udW1fYXJncygpID8gZnVuY19nZXRfYXJnKDEpIDogbnVsbDsKCiAgICAgICAgJHByb2Nlc3MgPSBjbG9uZSAkdGhpczsKICAgICAgICAkcHJvY2Vzcy0+c3RhcnQoJGNhbGxiYWNrLCAkZW52KTsKCiAgICAgICAgcmV0dXJuICRwcm9jZXNzOwogICAgfQoKICAgIC8qKgogICAgICogV2FpdHMgZm9yIHRoZSBwcm9jZXNzIHRvIHRlcm1pbmF0ZS4KICAgICAqCiAgICAgKiBUaGUgY2FsbGJhY2sgcmVjZWl2ZXMgdGhlIHR5cGUgb2Ygb3V0cHV0IChvdXQgb3IgZXJyKSBhbmQgc29tZSBieXRlcwogICAgICogZnJvbSB0aGUgb3V0cHV0IGluIHJlYWwtdGltZSB3aGlsZSB3cml0aW5nIHRoZSBzdGFuZGFyZCBpbnB1dCB0byB0aGUgcHJvY2Vzcy4KICAgICAqIEl0IGFsbG93cyB0byBoYXZlIGZlZWRiYWNrIGZyb20gdGhlIGluZGVwZW5kZW50IHByb2Nlc3MgZHVyaW5nIGV4ZWN1dGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkY2FsbGJhY2sgQSB2YWxpZCBQSFAgY2FsbGJhY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgZXhpdGNvZGUgb2YgdGhlIHByb2Nlc3MKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBwcm9jZXNzIHRpbWVkIG91dAogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gcHJvY2VzcyBzdG9wcGVkIGFmdGVyIHJlY2VpdmluZyBzaWduYWwKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBXaGVuIHByb2Nlc3MgaXMgbm90IHlldCBzdGFydGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3YWl0KGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVQcm9jZXNzSXNTdGFydGVkKF9fRlVOQ1RJT05fXyk7CgogICAgICAgICR0aGlzLT51cGRhdGVTdGF0dXMoZmFsc2UpOwoKICAgICAgICBpZiAobnVsbCAhPT0gJGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnByb2Nlc3NQaXBlcy0+aGF2ZVJlYWRTdXBwb3J0KCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdG9wKDApOwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignUGFzcyB0aGUgY2FsbGJhY2sgdG8gdGhlIFByb2Nlc3M6OnN0YXJ0IG1ldGhvZCBvciBlbmFibGVPdXRwdXQgdG8gdXNlIGEgY2FsbGJhY2sgd2l0aCBQcm9jZXNzOjp3YWl0LicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5jYWxsYmFjayA9ICR0aGlzLT5idWlsZENhbGxiYWNrKCRjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBkbyB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja1RpbWVvdXQoKTsKICAgICAgICAgICAgJHJ1bm5pbmcgPSAnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUiA/ICR0aGlzLT5pc1J1bm5pbmcoKSA6ICR0aGlzLT5wcm9jZXNzUGlwZXMtPmFyZU9wZW4oKTsKICAgICAgICAgICAgJHRoaXMtPnJlYWRQaXBlcygkcnVubmluZywgJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgfHwgISRydW5uaW5nKTsKICAgICAgICB9IHdoaWxlICgkcnVubmluZyk7CgogICAgICAgIHdoaWxlICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVGltZW91dCgpOwogICAgICAgICAgICB1c2xlZXAoMTAwMCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsnc2lnbmFsZWQnXSAmJiAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWyd0ZXJtc2lnJ10gIT09ICR0aGlzLT5sYXRlc3RTaWduYWwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlIHByb2Nlc3MgaGFzIGJlZW4gc2lnbmFsZWQgd2l0aCBzaWduYWwgIiVzIi4nLCAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWyd0ZXJtc2lnJ10pKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdGNvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBQaWQgKHByb2Nlc3MgaWRlbnRpZmllciksIGlmIGFwcGxpY2FibGUuCiAgICAgKgogICAgICogQHJldHVybiBpbnR8bnVsbCBUaGUgcHJvY2VzcyBpZCBpZiBydW5uaW5nLCBudWxsIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGlkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzUnVubmluZygpID8gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsncGlkJ10gOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogU2VuZHMgYSBQT1NJWCBzaWduYWwgdG8gdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc2lnbmFsIEEgdmFsaWQgUE9TSVggc2lnbmFsIChzZWUgaHR0cHM6Ly9waHAubmV0L3BjbnRsLmNvbnN0YW50cykKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiAgIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHJ1bm5pbmcKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIC0tZW5hYmxlLXNpZ2NoaWxkIGlzIGFjdGl2YXRlZCBhbmQgdGhlIHByb2Nlc3MgY2FuJ3QgYmUga2lsbGVkCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSBvZiBmYWlsdXJlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzaWduYWwoJHNpZ25hbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZG9TaWduYWwoJHNpZ25hbCwgdHJ1ZSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIERpc2FibGVzIGZldGNoaW5nIG91dHB1dCBhbmQgZXJyb3Igb3V0cHV0IGZyb20gdGhlIHVuZGVybHlpbmcgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgYWxyZWFkeSBydW5uaW5nCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgaWYgYW4gaWRsZSB0aW1lb3V0IGlzIHNldAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZU91dHB1dCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignRGlzYWJsaW5nIG91dHB1dCB3aGlsZSB0aGUgcHJvY2VzcyBpcyBydW5uaW5nIGlzIG5vdCBwb3NzaWJsZS4nKTsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5pZGxlVGltZW91dCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ091dHB1dCBjYW4gbm90IGJlIGRpc2FibGVkIHdoaWxlIGFuIGlkbGUgdGltZW91dCBpcyBzZXQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3V0cHV0RGlzYWJsZWQgPSB0cnVlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmFibGVzIGZldGNoaW5nIG91dHB1dCBhbmQgZXJyb3Igb3V0cHV0IGZyb20gdGhlIHVuZGVybHlpbmcgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgYWxyZWFkeSBydW5uaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVPdXRwdXQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ0VuYWJsaW5nIG91dHB1dCB3aGlsZSB0aGUgcHJvY2VzcyBpcyBydW5uaW5nIGlzIG5vdCBwb3NzaWJsZS4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXREaXNhYmxlZCA9IGZhbHNlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaW4gY2FzZSB0aGUgb3V0cHV0IGlzIGRpc2FibGVkLCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc091dHB1dERpc2FibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm91dHB1dERpc2FibGVkOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBvdXRwdXQgb2YgdGhlIHByb2Nlc3MgKFNURE9VVCkuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHByb2Nlc3Mgb3V0cHV0CiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3Qgc3RhcnRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3V0cHV0KCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVhZFBpcGVzRm9yT3V0cHV0KF9fRlVOQ1RJT05fXyk7CgogICAgICAgIGlmIChmYWxzZSA9PT0gJHJldCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPnN0ZG91dCwgLTEsIDApKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmV0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3V0cHV0IGluY3JlbWVudGFsbHkuCiAgICAgKgogICAgICogSW4gY29tcGFyaXNvbiB3aXRoIHRoZSBnZXRPdXRwdXQgbWV0aG9kIHdoaWNoIGFsd2F5cyByZXR1cm4gdGhlIHdob2xlCiAgICAgKiBvdXRwdXQsIHRoaXMgb25lIHJldHVybnMgdGhlIG5ldyBvdXRwdXQgc2luY2UgdGhlIGxhc3QgY2FsbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcHJvY2VzcyBvdXRwdXQgc2luY2UgdGhlIGxhc3QgY2FsbAogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaW4gY2FzZSB0aGUgb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHN0YXJ0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluY3JlbWVudGFsT3V0cHV0KCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVhZFBpcGVzRm9yT3V0cHV0KF9fRlVOQ1RJT05fXyk7CgogICAgICAgICRsYXRlc3QgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5zdGRvdXQsIC0xLCAkdGhpcy0+aW5jcmVtZW50YWxPdXRwdXRPZmZzZXQpOwogICAgICAgICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCA9IGZ0ZWxsKCR0aGlzLT5zdGRvdXQpOwoKICAgICAgICBpZiAoZmFsc2UgPT09ICRsYXRlc3QpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsYXRlc3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBvdXRwdXQgb2YgdGhlIHByb2Nlc3MsIHdpdGggdGhlIG91dHB1dCB0eXBlIGFzIGtleXMgKFByb2Nlc3M6Ok9VVC9FUlIpLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGZsYWdzIEEgYml0IGZpZWxkIG9mIFByb2Nlc3M6OklURVJfKiBmbGFncwogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaW4gY2FzZSB0aGUgb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgbm90IHN0YXJ0ZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIFxHZW5lcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKCRmbGFncyA9IDApCiAgICB7CiAgICAgICAgJHRoaXMtPnJlYWRQaXBlc0Zvck91dHB1dChfX0ZVTkNUSU9OX18sIGZhbHNlKTsKCiAgICAgICAgJGNsZWFyT3V0cHV0ID0gIShzZWxmOjpJVEVSX0tFRVBfT1VUUFVUICYgJGZsYWdzKTsKICAgICAgICAkYmxvY2tpbmcgPSAhKHNlbGY6OklURVJfTk9OX0JMT0NLSU5HICYgJGZsYWdzKTsKICAgICAgICAkeWllbGRPdXQgPSAhKHNlbGY6OklURVJfU0tJUF9PVVQgJiAkZmxhZ3MpOwogICAgICAgICR5aWVsZEVyciA9ICEoc2VsZjo6SVRFUl9TS0lQX0VSUiAmICRmbGFncyk7CgogICAgICAgIHdoaWxlIChudWxsICE9PSAkdGhpcy0+Y2FsbGJhY2sgfHwgKCR5aWVsZE91dCAmJiAhZmVvZigkdGhpcy0+c3Rkb3V0KSkgfHwgKCR5aWVsZEVyciAmJiAhZmVvZigkdGhpcy0+c3RkZXJyKSkpIHsKICAgICAgICAgICAgaWYgKCR5aWVsZE91dCkgewogICAgICAgICAgICAgICAgJG91dCA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPnN0ZG91dCwgLTEsICR0aGlzLT5pbmNyZW1lbnRhbE91dHB1dE9mZnNldCk7CgogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRvdXRbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjbGVhck91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2xlYXJPdXRwdXQoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxPdXRwdXRPZmZzZXQgPSBmdGVsbCgkdGhpcy0+c3Rkb3V0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHlpZWxkIHNlbGY6Ok9VVCA9PiAkb3V0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHlpZWxkRXJyKSB7CiAgICAgICAgICAgICAgICAkZXJyID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+c3RkZXJyLCAtMSwgJHRoaXMtPmluY3JlbWVudGFsRXJyb3JPdXRwdXRPZmZzZXQpOwoKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZXJyWzBdKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY2xlYXJPdXRwdXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNsZWFyRXJyb3JPdXRwdXQoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCA9IGZ0ZWxsKCR0aGlzLT5zdGRlcnIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeWllbGQgc2VsZjo6RVJSID0+ICRlcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGJsb2NraW5nICYmICFpc3NldCgkb3V0WzBdKSAmJiAhaXNzZXQoJGVyclswXSkpIHsKICAgICAgICAgICAgICAgIHlpZWxkIHNlbGY6Ok9VVCA9PiAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVGltZW91dCgpOwogICAgICAgICAgICAkdGhpcy0+cmVhZFBpcGVzRm9yT3V0cHV0KF9fRlVOQ1RJT05fXywgJGJsb2NraW5nKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhcnMgdGhlIHByb2Nlc3Mgb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyT3V0cHV0KCkKICAgIHsKICAgICAgICBmdHJ1bmNhdGUoJHRoaXMtPnN0ZG91dCwgMCk7CiAgICAgICAgZnNlZWsoJHRoaXMtPnN0ZG91dCwgMCk7CiAgICAgICAgJHRoaXMtPmluY3JlbWVudGFsT3V0cHV0T2Zmc2V0ID0gMDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBlcnJvciBvdXRwdXQgb2YgdGhlIHByb2Nlc3MgKFNUREVSUikuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHByb2Nlc3MgZXJyb3Igb3V0cHV0CiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBpbiBjYXNlIHRoZSBvdXRwdXQgaGFzIGJlZW4gZGlzYWJsZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3Qgc3RhcnRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKQogICAgewogICAgICAgICR0aGlzLT5yZWFkUGlwZXNGb3JPdXRwdXQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmV0ID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+c3RkZXJyLCAtMSwgMCkpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlcnJvck91dHB1dCBpbmNyZW1lbnRhbGx5LgogICAgICoKICAgICAqIEluIGNvbXBhcmlzb24gd2l0aCB0aGUgZ2V0RXJyb3JPdXRwdXQgbWV0aG9kIHdoaWNoIGFsd2F5cyByZXR1cm4gdGhlCiAgICAgKiB3aG9sZSBlcnJvciBvdXRwdXQsIHRoaXMgb25lIHJldHVybnMgdGhlIG5ldyBlcnJvciBvdXRwdXQgc2luY2UgdGhlIGxhc3QKICAgICAqIGNhbGwuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHByb2Nlc3MgZXJyb3Igb3V0cHV0IHNpbmNlIHRoZSBsYXN0IGNhbGwKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIGluIGNhc2UgdGhlIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZAogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCBzdGFydGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbmNyZW1lbnRhbEVycm9yT3V0cHV0KCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVhZFBpcGVzRm9yT3V0cHV0KF9fRlVOQ1RJT05fXyk7CgogICAgICAgICRsYXRlc3QgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5zdGRlcnIsIC0xLCAkdGhpcy0+aW5jcmVtZW50YWxFcnJvck91dHB1dE9mZnNldCk7CiAgICAgICAgJHRoaXMtPmluY3JlbWVudGFsRXJyb3JPdXRwdXRPZmZzZXQgPSBmdGVsbCgkdGhpcy0+c3RkZXJyKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSAkbGF0ZXN0KSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbGF0ZXN0OwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXJzIHRoZSBwcm9jZXNzIG91dHB1dC4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhckVycm9yT3V0cHV0KCkKICAgIHsKICAgICAgICBmdHJ1bmNhdGUoJHRoaXMtPnN0ZGVyciwgMCk7CiAgICAgICAgZnNlZWsoJHRoaXMtPnN0ZGVyciwgMCk7CiAgICAgICAgJHRoaXMtPmluY3JlbWVudGFsRXJyb3JPdXRwdXRPZmZzZXQgPSAwOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleGl0IGNvZGUgcmV0dXJuZWQgYnkgdGhlIHByb2Nlc3MuCiAgICAgKgogICAgICogQHJldHVybiBpbnR8bnVsbCBUaGUgZXhpdCBzdGF0dXMgY29kZSwgbnVsbCBpZiB0aGUgUHJvY2VzcyBpcyBub3QgdGVybWluYXRlZAogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIC0tZW5hYmxlLXNpZ2NoaWxkIGlzIGFjdGl2YXRlZCBhbmQgdGhlIHNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgbW9kZSBpcyBkaXNhYmxlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhpdENvZGUoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgJiYgJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1RoaXMgUEhQIGhhcyBiZWVuIGNvbXBpbGVkIHdpdGggLS1lbmFibGUtc2lnY2hpbGQuIFlvdSBtdXN0IHVzZSBzZXRFbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5KCkgdG8gdXNlIHRoaXMgbWV0aG9kLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnVwZGF0ZVN0YXR1cyhmYWxzZSk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdGNvZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciB0aGUgZXhpdCBjb2RlIHJldHVybmVkIGJ5IHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIHJlbGllcyBvbiB0aGUgVW5peCBleGl0IGNvZGUgc3RhdHVzIHN0YW5kYXJkaXphdGlvbgogICAgICogYW5kIG1pZ2h0IG5vdCBiZSByZWxldmFudCBmb3Igb3RoZXIgb3BlcmF0aW5nIHN5c3RlbXMuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBmb3IgdGhlIGV4aXQgc3RhdHVzIGNvZGUsIG51bGwgaWYgdGhlIFByb2Nlc3MgaXMgbm90IHRlcm1pbmF0ZWQKICAgICAqCiAgICAgKiBAc2VlIGh0dHA6Ly90bGRwLm9yZy9MRFAvYWJzL2h0bWwvZXhpdGNvZGVzLmh0bWwKICAgICAqIEBzZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Vbml4X3NpZ25hbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhpdENvZGVUZXh0KCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGV4aXRjb2RlID0gJHRoaXMtPmdldEV4aXRDb2RlKCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoc2VsZjo6JGV4aXRDb2Rlc1skZXhpdGNvZGVdKSA/IHNlbGY6OiRleGl0Q29kZXNbJGV4aXRjb2RlXSA6ICdVbmtub3duIGVycm9yJzsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgcHJvY2VzcyBlbmRlZCBzdWNjZXNzZnVsbHkuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHByb2Nlc3MgZW5kZWQgc3VjY2Vzc2Z1bGx5LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3VjY2Vzc2Z1bCgpCiAgICB7CiAgICAgICAgcmV0dXJuIDAgPT09ICR0aGlzLT5nZXRFeGl0Q29kZSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjaGlsZCBwcm9jZXNzIGhhcyBiZWVuIHRlcm1pbmF0ZWQgYnkgYW4gdW5jYXVnaHQgc2lnbmFsLgogICAgICoKICAgICAqIEl0IGFsd2F5cyByZXR1cm5zIGZhbHNlIG9uIFdpbmRvd3MuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgLS1lbmFibGUtc2lnY2hpbGQgaXMgYWN0aXZhdGVkCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBub3QgdGVybWluYXRlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQmVlblNpZ25hbGVkKCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWlyZVByb2Nlc3NJc1Rlcm1pbmF0ZWQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+ZW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSAmJiAkdGhpcy0+aXNTaWdjaGlsZEVuYWJsZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVGhpcyBQSFAgaGFzIGJlZW4gY29tcGlsZWQgd2l0aCAtLWVuYWJsZS1zaWdjaGlsZC4gVGVybSBzaWduYWwgY2FuIG5vdCBiZSByZXRyaWV2ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsnc2lnbmFsZWQnXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgc2lnbmFsIHRoYXQgY2F1c2VkIHRoZSBjaGlsZCBwcm9jZXNzIHRvIHRlcm1pbmF0ZSBpdHMgZXhlY3V0aW9uLgogICAgICoKICAgICAqIEl0IGlzIG9ubHkgbWVhbmluZ2Z1bCBpZiBoYXNCZWVuU2lnbmFsZWQoKSByZXR1cm5zIHRydWUuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSAtLWVuYWJsZS1zaWdjaGlsZCBpcyBhY3RpdmF0ZWQKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCB0ZXJtaW5hdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUZXJtU2lnbmFsKCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWlyZVByb2Nlc3NJc1Rlcm1pbmF0ZWQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgaWYgKCR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpICYmICghJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgfHwgLTEgPT09ICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3Rlcm1zaWcnXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1RoaXMgUEhQIGhhcyBiZWVuIGNvbXBpbGVkIHdpdGggLS1lbmFibGUtc2lnY2hpbGQuIFRlcm0gc2lnbmFsIGNhbiBub3QgYmUgcmV0cmlldmVkLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3Rlcm1zaWcnXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hpbGQgcHJvY2VzcyBoYXMgYmVlbiBzdG9wcGVkIGJ5IGEgc2lnbmFsLgogICAgICoKICAgICAqIEl0IGFsd2F5cyByZXR1cm5zIGZhbHNlIG9uIFdpbmRvd3MuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCB0ZXJtaW5hdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNCZWVuU3RvcHBlZCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnJlcXVpcmVQcm9jZXNzSXNUZXJtaW5hdGVkKF9fRlVOQ1RJT05fXyk7CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydzdG9wcGVkJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGhlIHNpZ25hbCB0aGF0IGNhdXNlZCB0aGUgY2hpbGQgcHJvY2VzcyB0byBzdG9wIGl0cyBleGVjdXRpb24uCiAgICAgKgogICAgICogSXQgaXMgb25seSBtZWFuaW5nZnVsIGlmIGhhc0JlZW5TdG9wcGVkKCkgcmV0dXJucyB0cnVlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCB0ZXJtaW5hdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdG9wU2lnbmFsKCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWlyZVByb2Nlc3NJc1Rlcm1pbmF0ZWQoX19GVU5DVElPTl9fKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3N0b3BzaWcnXTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgcHJvY2VzcyBpcyBjdXJyZW50bHkgcnVubmluZy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgcHJvY2VzcyBpcyBjdXJyZW50bHkgcnVubmluZywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1J1bm5pbmcoKQogICAgewogICAgICAgIGlmIChzZWxmOjpTVEFUVVNfU1RBUlRFRCAhPT0gJHRoaXMtPnN0YXR1cykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dXBkYXRlU3RhdHVzKGZhbHNlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3J1bm5pbmcnXTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgcHJvY2VzcyBoYXMgYmVlbiBzdGFydGVkIHdpdGggbm8gcmVnYXJkIHRvIHRoZSBjdXJyZW50IHN0YXRlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHN0YXR1cyBpcyByZWFkeSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1N0YXJ0ZWQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpTVEFUVVNfUkVBRFkgIT0gJHRoaXMtPnN0YXR1czsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgcHJvY2VzcyBpcyB0ZXJtaW5hdGVkLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHByb2Nlc3MgaXMgdGVybWluYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1Rlcm1pbmF0ZWQoKQogICAgewogICAgICAgICR0aGlzLT51cGRhdGVTdGF0dXMoZmFsc2UpOwoKICAgICAgICByZXR1cm4gc2VsZjo6U1RBVFVTX1RFUk1JTkFURUQgPT0gJHRoaXMtPnN0YXR1czsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2Nlc3Mgc3RhdHVzLgogICAgICoKICAgICAqIFRoZSBzdGF0dXMgaXMgb25lIG9mOiByZWFkeSwgc3RhcnRlZCwgdGVybWluYXRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgY3VycmVudCBwcm9jZXNzIHN0YXR1cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhdHVzKCkKICAgIHsKICAgICAgICAkdGhpcy0+dXBkYXRlU3RhdHVzKGZhbHNlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9wcyB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fGZsb2F0ICR0aW1lb3V0IFRoZSB0aW1lb3V0IGluIHNlY29uZHMKICAgICAqIEBwYXJhbSBpbnQgICAgICAgJHNpZ25hbCAgQSBQT1NJWCBzaWduYWwgdG8gc2VuZCBpbiBjYXNlIHRoZSBwcm9jZXNzIGhhcyBub3Qgc3RvcCBhdCB0aW1lb3V0LCBkZWZhdWx0IGlzIFNJR0tJTEwgKDkpCiAgICAgKgogICAgICogQHJldHVybiBpbnR8bnVsbCBUaGUgZXhpdC1jb2RlIG9mIHRoZSBwcm9jZXNzIG9yIG51bGwgaWYgaXQncyBub3QgcnVubmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RvcCgkdGltZW91dCA9IDEwLCAkc2lnbmFsID0gbnVsbCkKICAgIHsKICAgICAgICAkdGltZW91dE1pY3JvID0gbWljcm90aW1lKHRydWUpICsgJHRpbWVvdXQ7CiAgICAgICAgaWYgKCR0aGlzLT5pc1J1bm5pbmcoKSkgewogICAgICAgICAgICAvLyBnaXZlbiBgU0lHVEVSTWAgbWF5IG5vdCBiZSBkZWZpbmVkIGFuZCB0aGF0IGBwcm9jX3Rlcm1pbmF0ZWAgdXNlcyB0aGUgY29uc3RhbnQgdmFsdWUgYW5kIG5vdCB0aGUgY29uc3RhbnQgaXRzZWxmLCB3ZSB1c2UgdGhlIHNhbWUgaGVyZQogICAgICAgICAgICAkdGhpcy0+ZG9TaWduYWwoMTUsIGZhbHNlKTsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgdXNsZWVwKDEwMDApOwogICAgICAgICAgICB9IHdoaWxlICgkdGhpcy0+aXNSdW5uaW5nKCkgJiYgbWljcm90aW1lKHRydWUpIDwgJHRpbWVvdXRNaWNybyk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPmlzUnVubmluZygpKSB7CiAgICAgICAgICAgICAgICAvLyBBdm9pZCBleGNlcHRpb24gaGVyZTogcHJvY2VzcyBpcyBzdXBwb3NlZCB0byBiZSBydW5uaW5nLCBidXQgaXQgbWlnaHQgaGF2ZSBzdG9wcGVkIGp1c3QKICAgICAgICAgICAgICAgIC8vIGFmdGVyIHRoaXMgbGluZS4gSW4gYW55IGNhc2UsIGxldCdzIHNpbGVudGx5IGRpc2NhcmQgdGhlIGVycm9yLCB3ZSBjYW5ub3QgZG8gYW55dGhpbmcuCiAgICAgICAgICAgICAgICAkdGhpcy0+ZG9TaWduYWwoJHNpZ25hbCA/OiA5LCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5mYWxsYmFja1N0YXR1c1sncGlkJ10pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ3BpZCddKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0b3AoMCwgJHNpZ25hbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmNsb3NlKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmV4aXRjb2RlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIGxpbmUgdG8gdGhlIFNURE9VVCBzdHJlYW0uCiAgICAgKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBUaGUgbGluZSB0byBhcHBlbmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE91dHB1dCgkbGluZSkKICAgIHsKICAgICAgICAkdGhpcy0+bGFzdE91dHB1dFRpbWUgPSBtaWNyb3RpbWUodHJ1ZSk7CgogICAgICAgIGZzZWVrKCR0aGlzLT5zdGRvdXQsIDAsIFxTRUVLX0VORCk7CiAgICAgICAgZndyaXRlKCR0aGlzLT5zdGRvdXQsICRsaW5lKTsKICAgICAgICBmc2VlaygkdGhpcy0+c3Rkb3V0LCAkdGhpcy0+aW5jcmVtZW50YWxPdXRwdXRPZmZzZXQpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIGxpbmUgdG8gdGhlIFNUREVSUiBzdHJlYW0uCiAgICAgKgogICAgICogQGludGVybmFsCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGluZSBUaGUgbGluZSB0byBhcHBlbmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEVycm9yT3V0cHV0KCRsaW5lKQogICAgewogICAgICAgICR0aGlzLT5sYXN0T3V0cHV0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKCiAgICAgICAgZnNlZWsoJHRoaXMtPnN0ZGVyciwgMCwgXFNFRUtfRU5EKTsKICAgICAgICBmd3JpdGUoJHRoaXMtPnN0ZGVyciwgJGxpbmUpOwogICAgICAgIGZzZWVrKCR0aGlzLT5zdGRlcnIsICR0aGlzLT5pbmNyZW1lbnRhbEVycm9yT3V0cHV0T2Zmc2V0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGNvbW1hbmQgbGluZSB0byBiZSBleGVjdXRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgY29tbWFuZCB0byBleGVjdXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kTGluZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIFxpc19hcnJheSgkdGhpcy0+Y29tbWFuZGxpbmUpID8gaW1wbG9kZSgnICcsIGFycmF5X21hcChbJHRoaXMsICdlc2NhcGVBcmd1bWVudCddLCAkdGhpcy0+Y29tbWFuZGxpbmUpKSA6ICR0aGlzLT5jb21tYW5kbGluZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbW1hbmQgbGluZSB0byBiZSBleGVjdXRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRjb21tYW5kbGluZSBUaGUgY29tbWFuZCB0byBleGVjdXRlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tbWFuZExpbmUoJGNvbW1hbmRsaW5lKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kbGluZSA9ICRjb21tYW5kbGluZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvY2VzcyB0aW1lb3V0IChtYXguIHJ1bnRpbWUpLgogICAgICoKICAgICAqIEByZXR1cm4gZmxvYXR8bnVsbCBUaGUgdGltZW91dCBpbiBzZWNvbmRzIG9yIG51bGwgaWYgaXQncyBkaXNhYmxlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGltZW91dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvY2VzcyBpZGxlIHRpbWVvdXQgKG1heC4gdGltZSBzaW5jZSBsYXN0IG91dHB1dCkuCiAgICAgKgogICAgICogQHJldHVybiBmbG9hdHxudWxsIFRoZSB0aW1lb3V0IGluIHNlY29uZHMgb3IgbnVsbCBpZiBpdCdzIGRpc2FibGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZGxlVGltZW91dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZGxlVGltZW91dDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2Nlc3MgdGltZW91dCAobWF4LiBydW50aW1lKSBpbiBzZWNvbmRzLgogICAgICoKICAgICAqIFRvIGRpc2FibGUgdGhlIHRpbWVvdXQsIHNldCB0aGlzIHZhbHVlIHRvIG51bGwuCiAgICAgKgogICAgICogQHBhcmFtIGludHxmbG9hdHxudWxsICR0aW1lb3V0IFRoZSB0aW1lb3V0IGluIHNlY29uZHMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHRpbWVvdXQgaXMgbmVnYXRpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRpbWVvdXQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPnRpbWVvdXQgPSAkdGhpcy0+dmFsaWRhdGVUaW1lb3V0KCR0aW1lb3V0KTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvY2VzcyBpZGxlIHRpbWVvdXQgKG1heC4gdGltZSBzaW5jZSBsYXN0IG91dHB1dCkuCiAgICAgKgogICAgICogVG8gZGlzYWJsZSB0aGUgdGltZW91dCwgc2V0IHRoaXMgdmFsdWUgdG8gbnVsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fGZsb2F0fG51bGwgJHRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgICAgICAgICBpZiB0aGUgb3V0cHV0IGlzIGRpc2FibGVkCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdGltZW91dCBpcyBuZWdhdGl2ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SWRsZVRpbWVvdXQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aW1lb3V0ICYmICR0aGlzLT5vdXRwdXREaXNhYmxlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0lkbGUgdGltZW91dCBjYW4gbm90IGJlIHNldCB3aGlsZSB0aGUgb3V0cHV0IGlzIGRpc2FibGVkLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlkbGVUaW1lb3V0ID0gJHRoaXMtPnZhbGlkYXRlVGltZW91dCgkdGltZW91dCk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgdGhlIFRUWSBtb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICR0dHkgVHJ1ZSB0byBlbmFibGVkIGFuZCBmYWxzZSB0byBkaXNhYmxlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJbiBjYXNlIHRoZSBUVFkgbW9kZSBpcyBub3Qgc3VwcG9ydGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUdHkoJHR0eSkKICAgIHsKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgJiYgJHR0eSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVFRZIG1vZGUgaXMgbm90IHN1cHBvcnRlZCBvbiBXaW5kb3dzIHBsYXRmb3JtLicpOwogICAgICAgIH0KICAgICAgICBpZiAoJHR0eSkgewogICAgICAgICAgICBzdGF0aWMgJGlzVHR5U3VwcG9ydGVkOwoKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRpc1R0eVN1cHBvcnRlZCkgewogICAgICAgICAgICAgICAgJGlzVHR5U3VwcG9ydGVkID0gKGJvb2wpIEBwcm9jX29wZW4oJ2VjaG8gMSA+L2Rldi9udWxsJywgW1snZmlsZScsICcvZGV2L3R0eScsICdyJ10sIFsnZmlsZScsICcvZGV2L3R0eScsICd3J10sIFsnZmlsZScsICcvZGV2L3R0eScsICd3J11dLCAkcGlwZXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRpc1R0eVN1cHBvcnRlZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1RUWSBtb2RlIHJlcXVpcmVzIC9kZXYvdHR5IHRvIGJlIHJlYWQvd3JpdGFibGUuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT50dHkgPSAoYm9vbCkgJHR0eTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBUVFkgbW9kZSBpcyBlbmFibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBUVFkgbW9kZSBpcyBlbmFibGVkLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVHR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnR0eTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgUFRZIG1vZGUuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGJvb2wKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQdHkoJGJvb2wpCiAgICB7CiAgICAgICAgJHRoaXMtPnB0eSA9IChib29sKSAkYm9vbDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBQVFkgc3RhdGUuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1B0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IG9yIG51bGwgb24gZmFpbHVyZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0V29ya2luZ0RpcmVjdG9yeSgpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jd2QpIHsKICAgICAgICAgICAgLy8gZ2V0Y3dkKCkgd2lsbCByZXR1cm4gZmFsc2UgaWYgYW55IG9uZSBvZiB0aGUgcGFyZW50IGRpcmVjdG9yaWVzIGRvZXMgbm90IGhhdmUKICAgICAgICAgICAgLy8gdGhlIHJlYWRhYmxlIG9yIHNlYXJjaCBtb2RlIHNldCwgZXZlbiBpZiB0aGUgY3VycmVudCBkaXJlY3RvcnkgZG9lcwogICAgICAgICAgICByZXR1cm4gZ2V0Y3dkKCkgPzogbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Y3dkOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjd2QgVGhlIG5ldyB3b3JraW5nIGRpcmVjdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFdvcmtpbmdEaXJlY3RvcnkoJGN3ZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y3dkID0gJGN3ZDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgdmFyaWFibGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbnYoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZW52OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLgogICAgICoKICAgICAqIEVhY2ggZW52aXJvbm1lbnQgdmFyaWFibGUgdmFsdWUgc2hvdWxkIGJlIGEgc3RyaW5nLgogICAgICogSWYgaXQgaXMgYW4gYXJyYXksIHRoZSB2YXJpYWJsZSBpcyBpZ25vcmVkLgogICAgICogSWYgaXQgaXMgZmFsc2Ugb3IgbnVsbCwgaXQgd2lsbCBiZSByZW1vdmVkIHdoZW4KICAgICAqIGVudiB2YXJzIGFyZSBvdGhlcndpc2UgaW5oZXJpdGVkLgogICAgICoKICAgICAqIFRoYXQgaGFwcGVucyBpbiBQSFAgd2hlbiAnYXJndicgaXMgcmVnaXN0ZXJlZCBpbnRvCiAgICAgKiB0aGUgJF9FTlYgYXJyYXkgZm9yIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkZW52IFRoZSBuZXcgZW52aXJvbm1lbnQgdmFyaWFibGVzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RW52KGFycmF5ICRlbnYpCiAgICB7CiAgICAgICAgLy8gUHJvY2VzcyBjYW4gbm90IGhhbmRsZSBlbnYgdmFsdWVzIHRoYXQgYXJlIGFycmF5cwogICAgICAgICRlbnYgPSBhcnJheV9maWx0ZXIoJGVudiwgZnVuY3Rpb24gKCR2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gIVxpc19hcnJheSgkdmFsdWUpOwogICAgICAgIH0pOwoKICAgICAgICAkdGhpcy0+ZW52ID0gJGVudjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgUHJvY2VzcyBpbnB1dC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHJlc291cmNlfHN0cmluZ3xcSXRlcmF0b3J8bnVsbCBUaGUgUHJvY2VzcyBpbnB1dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5wdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5wdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbnB1dC4KICAgICAqCiAgICAgKiBUaGlzIGNvbnRlbnQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHVuZGVybHlpbmcgcHJvY2VzcyBzdGFuZGFyZCBpbnB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludHxmbG9hdHxib29sfHJlc291cmNlfFxUcmF2ZXJzYWJsZXxudWxsICRpbnB1dCBUaGUgY29udGVudAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIEluIGNhc2UgdGhlIHByb2Nlc3MgaXMgcnVubmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5wdXQoJGlucHV0KQogICAgewogICAgICAgIGlmICgkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdJbnB1dCBjYW4gbm90IGJlIHNldCB3aGlsZSB0aGUgcHJvY2VzcyBpcyBydW5uaW5nLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlucHV0ID0gUHJvY2Vzc1V0aWxzOjp2YWxpZGF0ZUlucHV0KF9fTUVUSE9EX18sICRpbnB1dCk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG9wdGlvbnMgZm9yIHByb2Nfb3Blbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBjdXJyZW50IG9wdGlvbnMKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25zKCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5vcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3B0aW9ucyBmb3IgcHJvY19vcGVuLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBUaGUgbmV3IG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjMsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9uczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB3aGV0aGVyIG9yIG5vdCBXaW5kb3dzIGNvbXBhdGliaWxpdHkgaXMgZW5hYmxlZC4KICAgICAqCiAgICAgKiBUaGlzIGlzIHRydWUgYnkgZGVmYXVsdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIEVuaGFuY2VkIFdpbmRvd3MgY29tcGF0aWJpbGl0eSB3aWxsIGFsd2F5cyBiZSBlbmFibGVkLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW5oYW5jZVdpbmRvd3NDb21wYXRpYmlsaXR5KCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gRW5oYW5jZWQgV2luZG93cyBjb21wYXRpYmlsaXR5IHdpbGwgYWx3YXlzIGJlIGVuYWJsZWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZW5oYW5jZVdpbmRvd3NDb21wYXRpYmlsaXR5OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIG9yIG5vdCBXaW5kb3dzIGNvbXBhdGliaWxpdHkgaXMgZW5hYmxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZW5oYW5jZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIEVuaGFuY2VkIFdpbmRvd3MgY29tcGF0aWJpbGl0eSB3aWxsIGFsd2F5cyBiZSBlbmFibGVkLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RW5oYW5jZVdpbmRvd3NDb21wYXRpYmlsaXR5KCRlbmhhbmNlKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBFbmhhbmNlZCBXaW5kb3dzIGNvbXBhdGliaWxpdHkgd2lsbCBhbHdheXMgYmUgZW5hYmxlZC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgJHRoaXMtPmVuaGFuY2VXaW5kb3dzQ29tcGF0aWJpbGl0eSA9IChib29sKSAkZW5oYW5jZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgbW9kZSBpcyBhY3RpdmF0ZWQgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4gU2lnY2hpbGQgY29tcGF0aWJpbGl0eSB3aWxsIGFsd2F5cyBiZSBlbmFibGVkLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RW5oYW5jZVNpZ2NoaWxkQ29tcGF0aWJpbGl0eSgpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzKCkgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIFNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgd2lsbCBhbHdheXMgYmUgZW5hYmxlZC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5OwogICAgfQoKICAgIC8qKgogICAgICogQWN0aXZhdGVzIHNpZ2NoaWxkIGNvbXBhdGliaWxpdHkgbW9kZS4KICAgICAqCiAgICAgKiBTaWdjaGlsZCBjb21wYXRpYmlsaXR5IG1vZGUgaXMgcmVxdWlyZWQgdG8gZ2V0IHRoZSBleGl0IGNvZGUgYW5kCiAgICAgKiBkZXRlcm1pbmUgdGhlIHN1Y2Nlc3Mgb2YgYSBwcm9jZXNzIHdoZW4gUEhQIGhhcyBiZWVuIGNvbXBpbGVkIHdpdGgKICAgICAqIHRoZSAtLWVuYWJsZS1zaWdjaGlsZCBvcHRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZW5oYW5jZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5KCRlbmhhbmNlKQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBTaWdjaGlsZCBjb21wYXRpYmlsaXR5IHdpbGwgYWx3YXlzIGJlIGVuYWJsZWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgICR0aGlzLT5lbmhhbmNlU2lnY2hpbGRDb21wYXRpYmlsaXR5ID0gKGJvb2wpICRlbmhhbmNlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpbGwgYmUgaW5oZXJpdGVkIG9yIG5vdC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkaW5oZXJpdEVudgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGluaGVyaXRFbnZpcm9ubWVudFZhcmlhYmxlcygkaW5oZXJpdEVudiA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKCEkaW5oZXJpdEVudikgewogICAgICAgICAgICBAdHJpZ2dlcl9lcnJvcignTm90IGluaGVyaXRpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYWx3YXlzIGhhcHBlbiBpbiA0LjAuIFNldCAiUHJvY2Vzczo6aW5oZXJpdEVudmlyb25tZW50VmFyaWFibGVzKCkiIHRvIHRydWUgaW5zdGVhZC4nLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmluaGVyaXRFbnYgPSAoYm9vbCkgJGluaGVyaXRFbnY7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBlbnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBiZSBpbmhlcml0ZWQgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zLCB0byBiZSByZW1vdmVkIGluIDQuMC4gRW52aXJvbm1lbnQgdmFyaWFibGVzIHdpbGwgYWx3YXlzIGJlIGluaGVyaXRlZC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyZUVudmlyb25tZW50VmFyaWFibGVzSW5oZXJpdGVkKCkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gRW52aXJvbm1lbnQgdmFyaWFibGVzIHdpbGwgYWx3YXlzIGJlIGluaGVyaXRlZC4nLCBfX01FVEhPRF9fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5pbmhlcml0RW52OwogICAgfQoKICAgIC8qKgogICAgICogUGVyZm9ybXMgYSBjaGVjayBiZXR3ZWVuIHRoZSB0aW1lb3V0IGRlZmluaXRpb24gYW5kIHRoZSB0aW1lIHRoZSBwcm9jZXNzIHN0YXJ0ZWQuCiAgICAgKgogICAgICogSW4gY2FzZSB5b3UgcnVuIGEgYmFja2dyb3VuZCBwcm9jZXNzICh3aXRoIHRoZSBzdGFydCBtZXRob2QpLCB5b3Ugc2hvdWxkCiAgICAgKiB0cmlnZ2VyIHRoaXMgbWV0aG9kIHJlZ3VsYXJseSB0byBlbnN1cmUgdGhlIHByb2Nlc3MgdGltZW91dAogICAgICoKICAgICAqIEB0aHJvd3MgUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uIEluIGNhc2UgdGhlIHRpbWVvdXQgd2FzIHJlYWNoZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrVGltZW91dCgpCiAgICB7CiAgICAgICAgaWYgKHNlbGY6OlNUQVRVU19TVEFSVEVEICE9PSAkdGhpcy0+c3RhdHVzKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+dGltZW91dCAmJiAkdGhpcy0+dGltZW91dCA8IG1pY3JvdGltZSh0cnVlKSAtICR0aGlzLT5zdGFydHRpbWUpIHsKICAgICAgICAgICAgJHRoaXMtPnN0b3AoMCk7CgogICAgICAgICAgICB0aHJvdyBuZXcgUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uKCR0aGlzLCBQcm9jZXNzVGltZWRPdXRFeGNlcHRpb246OlRZUEVfR0VORVJBTCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmlkbGVUaW1lb3V0ICYmICR0aGlzLT5pZGxlVGltZW91dCA8IG1pY3JvdGltZSh0cnVlKSAtICR0aGlzLT5sYXN0T3V0cHV0VGltZSkgewogICAgICAgICAgICAkdGhpcy0+c3RvcCgwKTsKCiAgICAgICAgICAgIHRocm93IG5ldyBQcm9jZXNzVGltZWRPdXRFeGNlcHRpb24oJHRoaXMsIFByb2Nlc3NUaW1lZE91dEV4Y2VwdGlvbjo6VFlQRV9JRExFKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgUFRZIGlzIHN1cHBvcnRlZCBvbiB0aGUgY3VycmVudCBvcGVyYXRpbmcgc3lzdGVtLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzUHR5U3VwcG9ydGVkKCkKICAgIHsKICAgICAgICBzdGF0aWMgJHJlc3VsdDsKCiAgICAgICAgaWYgKG51bGwgIT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0ID0gKGJvb2wpIEBwcm9jX29wZW4oJ2VjaG8gMSA+L2Rldi9udWxsJywgW1sncHR5J10sIFsncHR5J10sIFsncHR5J11dLCAkcGlwZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyB0aGUgZGVzY3JpcHRvcnMgbmVlZGVkIGJ5IHRoZSBwcm9jX29wZW4uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERlc2NyaXB0b3JzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmlucHV0IGluc3RhbmNlb2YgXEl0ZXJhdG9yKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnB1dC0+cmV3aW5kKCk7CiAgICAgICAgfQogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc1BpcGVzID0gbmV3IFdpbmRvd3NQaXBlcygkdGhpcy0+aW5wdXQsICEkdGhpcy0+b3V0cHV0RGlzYWJsZWQgfHwgJHRoaXMtPmhhc0NhbGxiYWNrKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+cHJvY2Vzc1BpcGVzID0gbmV3IFVuaXhQaXBlcygkdGhpcy0+aXNUdHkoKSwgJHRoaXMtPmlzUHR5KCksICR0aGlzLT5pbnB1dCwgISR0aGlzLT5vdXRwdXREaXNhYmxlZCB8fCAkdGhpcy0+aGFzQ2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzUGlwZXMtPmdldERlc2NyaXB0b3JzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZHMgdXAgdGhlIGNhbGxiYWNrIHVzZWQgYnkgd2FpdCgpLgogICAgICoKICAgICAqIFRoZSBjYWxsYmFja3MgYWRkcyBhbGwgb2NjdXJyZWQgb3V0cHV0IHRvIHRoZSBzcGVjaWZpYyBidWZmZXIgYW5kIGNhbGxzCiAgICAgKiB0aGUgdXNlciBjYWxsYmFjayAoaWYgcHJlc2VudCkgd2l0aCB0aGUgcmVjZWl2ZWQgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRjYWxsYmFjayBUaGUgdXNlciBkZWZpbmVkIFBIUCBjYWxsYmFjawogICAgICoKICAgICAqIEByZXR1cm4gXENsb3N1cmUgQSBQSFAgY2xvc3VyZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYnVpbGRDYWxsYmFjayhjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsKQogICAgewogICAgICAgIGlmICgkdGhpcy0+b3V0cHV0RGlzYWJsZWQpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkdHlwZSwgJGRhdGEpIHVzZSAoJGNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gJGNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICAgICAgXGNhbGxfdXNlcl9mdW5jKCRjYWxsYmFjaywgJHR5cGUsICRkYXRhKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgICRvdXQgPSBzZWxmOjpPVVQ7CgogICAgICAgIHJldHVybiBmdW5jdGlvbiAoJHR5cGUsICRkYXRhKSB1c2UgKCRjYWxsYmFjaywgJG91dCkgewogICAgICAgICAgICBpZiAoJG91dCA9PSAkdHlwZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZE91dHB1dCgkZGF0YSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3JPdXRwdXQoJGRhdGEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobnVsbCAhPT0gJGNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICBcY2FsbF91c2VyX2Z1bmMoJGNhbGxiYWNrLCAkdHlwZSwgJGRhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIHN0YXR1cyBvZiB0aGUgcHJvY2VzcywgcmVhZHMgcGlwZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGJsb2NraW5nIFdoZXRoZXIgdG8gdXNlIGEgYmxvY2tpbmcgcmVhZCBjYWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVTdGF0dXMoJGJsb2NraW5nKQogICAgewogICAgICAgIGlmIChzZWxmOjpTVEFUVVNfU1RBUlRFRCAhPT0gJHRoaXMtPnN0YXR1cykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uID0gcHJvY19nZXRfc3RhdHVzKCR0aGlzLT5wcm9jZXNzKTsKICAgICAgICAkcnVubmluZyA9ICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3J1bm5pbmcnXTsKCiAgICAgICAgJHRoaXMtPnJlYWRQaXBlcygkcnVubmluZyAmJiAkYmxvY2tpbmcsICdcXCcgIT09IFxESVJFQ1RPUllfU0VQQVJBVE9SIHx8ICEkcnVubmluZyk7CgogICAgICAgIGlmICgkdGhpcy0+ZmFsbGJhY2tTdGF0dXMgJiYgJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgJiYgJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkpIHsKICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvbiA9ICR0aGlzLT5mYWxsYmFja1N0YXR1cyArICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb247CiAgICAgICAgfQoKICAgICAgICBpZiAoISRydW5uaW5nKSB7CiAgICAgICAgICAgICR0aGlzLT5jbG9zZSgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBQSFAgaGFzIGJlZW4gY29tcGlsZWQgd2l0aCB0aGUgJy0tZW5hYmxlLXNpZ2NoaWxkJyBvcHRpb24gb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNTaWdjaGlsZEVuYWJsZWQoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokc2lnY2hpbGQpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRzaWdjaGlsZDsKICAgICAgICB9CgogICAgICAgIGlmICghXGZ1bmN0aW9uX2V4aXN0cygncGhwaW5mbycpIHx8IFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHNpZ2NoaWxkID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIHBocGluZm8oXElORk9fR0VORVJBTCk7CgogICAgICAgIHJldHVybiBzZWxmOjokc2lnY2hpbGQgPSBmYWxzZSAhPT0gc3RycG9zKG9iX2dldF9jbGVhbigpLCAnLS1lbmFibGUtc2lnY2hpbGQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWRzIHBpcGVzIGZvciB0aGUgZnJlc2hlc3Qgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNhbGxlciAgIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdGhhdCBuZWVkcyBmcmVzaCBvdXRwdXRzCiAgICAgKiBAcGFyYW0gYm9vbCAgICRibG9ja2luZyBXaGV0aGVyIHRvIHVzZSBibG9ja2luZyBjYWxscyBvciBub3QKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIGluIGNhc2Ugb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkIG9yIHByb2Nlc3MgaXMgbm90IHN0YXJ0ZWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZWFkUGlwZXNGb3JPdXRwdXQoJGNhbGxlciwgJGJsb2NraW5nID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXREaXNhYmxlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ091dHB1dCBoYXMgYmVlbiBkaXNhYmxlZC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZXF1aXJlUHJvY2Vzc0lzU3RhcnRlZCgkY2FsbGVyKTsKCiAgICAgICAgJHRoaXMtPnVwZGF0ZVN0YXR1cygkYmxvY2tpbmcpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIGFuZCByZXR1cm5zIHRoZSBmaWx0ZXJlZCB0aW1lb3V0LgogICAgICoKICAgICAqIEBwYXJhbSBpbnR8ZmxvYXR8bnVsbCAkdGltZW91dAogICAgICoKICAgICAqIEByZXR1cm4gZmxvYXR8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiB0aW1lb3V0IGlzIGEgbmVnYXRpdmUgbnVtYmVyCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVUaW1lb3V0KCR0aW1lb3V0KQogICAgewogICAgICAgICR0aW1lb3V0ID0gKGZsb2F0KSAkdGltZW91dDsKCiAgICAgICAgaWYgKDAuMCA9PT0gJHRpbWVvdXQpIHsKICAgICAgICAgICAgJHRpbWVvdXQgPSBudWxsOwogICAgICAgIH0gZWxzZWlmICgkdGltZW91dCA8IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIHRpbWVvdXQgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIHBvc2l0aXZlIGludGVnZXIgb3IgZmxvYXQgbnVtYmVyLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogUmVhZHMgcGlwZXMsIGV4ZWN1dGVzIGNhbGxiYWNrLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRibG9ja2luZyBXaGV0aGVyIHRvIHVzZSBibG9ja2luZyBjYWxscyBvciBub3QKICAgICAqIEBwYXJhbSBib29sICRjbG9zZSAgICBXaGV0aGVyIHRvIGNsb3NlIGZpbGUgaGFuZGxlcyBvciBub3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZWFkUGlwZXMoJGJsb2NraW5nLCAkY2xvc2UpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5wcm9jZXNzUGlwZXMtPnJlYWRBbmRXcml0ZSgkYmxvY2tpbmcsICRjbG9zZSk7CgogICAgICAgICRjYWxsYmFjayA9ICR0aGlzLT5jYWxsYmFjazsKICAgICAgICBmb3JlYWNoICgkcmVzdWx0IGFzICR0eXBlID0+ICRkYXRhKSB7CiAgICAgICAgICAgIGlmICgzICE9PSAkdHlwZSkgewogICAgICAgICAgICAgICAgJGNhbGxiYWNrKHNlbGY6OlNURE9VVCA9PT0gJHR5cGUgPyBzZWxmOjpPVVQgOiBzZWxmOjpFUlIsICRkYXRhKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCFpc3NldCgkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ3NpZ25hbGVkJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZmFsbGJhY2tTdGF0dXNbJ2V4aXRjb2RlJ10gPSAoaW50KSAkZGF0YTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsb3NlcyBwcm9jZXNzIHJlc291cmNlLCBjbG9zZXMgZmlsZSBoYW5kbGVzLCBzZXRzIHRoZSBleGl0Y29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgZXhpdGNvZGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjbG9zZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2Nlc3NQaXBlcy0+Y2xvc2UoKTsKICAgICAgICBpZiAoXGlzX3Jlc291cmNlKCR0aGlzLT5wcm9jZXNzKSkgewogICAgICAgICAgICBwcm9jX2Nsb3NlKCR0aGlzLT5wcm9jZXNzKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmV4aXRjb2RlID0gJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsnZXhpdGNvZGUnXTsKICAgICAgICAkdGhpcy0+c3RhdHVzID0gc2VsZjo6U1RBVFVTX1RFUk1JTkFURUQ7CgogICAgICAgIGlmICgtMSA9PT0gJHRoaXMtPmV4aXRjb2RlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWydzaWduYWxlZCddICYmIDAgPCAkdGhpcy0+cHJvY2Vzc0luZm9ybWF0aW9uWyd0ZXJtc2lnJ10pIHsKICAgICAgICAgICAgICAgIC8vIGlmIHByb2Nlc3MgaGFzIGJlZW4gc2lnbmFsZWQsIG5vIGV4aXRjb2RlIGJ1dCBhIHZhbGlkIHRlcm1zaWcsIGFwcGx5IFVuaXggY29udmVudGlvbgogICAgICAgICAgICAgICAgJHRoaXMtPmV4aXRjb2RlID0gMTI4ICsgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsndGVybXNpZyddOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgJiYgJHRoaXMtPmlzU2lnY2hpbGRFbmFibGVkKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb25bJ3NpZ25hbGVkJ10gPSB0cnVlOwogICAgICAgICAgICAgICAgJHRoaXMtPnByb2Nlc3NJbmZvcm1hdGlvblsndGVybXNpZyddID0gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEZyZWUgbWVtb3J5IGZyb20gc2VsZi1yZWZlcmVuY2UgY2FsbGJhY2sgY3JlYXRlZCBieSBidWlsZENhbGxiYWNrCiAgICAgICAgLy8gRG9pbmcgc28gaW4gb3RoZXIgY29udGV4dHMgbGlrZSBfX2Rlc3RydWN0IG9yIGJ5IGdhcmJhZ2UgY29sbGVjdG9yIGlzIGluZWZmZWN0aXZlCiAgICAgICAgLy8gTm93IHBpcGVzIGFyZSBjbG9zZWQsIHNvIHRoZSBjYWxsYmFjayBpcyBubyBsb25nZXIgbmVjZXNzYXJ5CiAgICAgICAgJHRoaXMtPmNhbGxiYWNrID0gbnVsbDsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5leGl0Y29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlc2V0cyBkYXRhIHJlbGF0ZWQgdG8gdGhlIGxhdGVzdCBydW4gb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVzZXRQcm9jZXNzRGF0YSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXJ0dGltZSA9IG51bGw7CiAgICAgICAgJHRoaXMtPmNhbGxiYWNrID0gbnVsbDsKICAgICAgICAkdGhpcy0+ZXhpdGNvZGUgPSBudWxsOwogICAgICAgICR0aGlzLT5mYWxsYmFja1N0YXR1cyA9IFtdOwogICAgICAgICR0aGlzLT5wcm9jZXNzSW5mb3JtYXRpb24gPSBudWxsOwogICAgICAgICR0aGlzLT5zdGRvdXQgPSBmb3BlbigncGhwOi8vdGVtcC9tYXhtZW1vcnk6Jy4oMTAyNCAqIDEwMjQpLCAndytiJyk7CiAgICAgICAgJHRoaXMtPnN0ZGVyciA9IGZvcGVuKCdwaHA6Ly90ZW1wL21heG1lbW9yeTonLigxMDI0ICogMTAyNCksICd3K2InKTsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9IG51bGw7CiAgICAgICAgJHRoaXMtPmxhdGVzdFNpZ25hbCA9IG51bGw7CiAgICAgICAgJHRoaXMtPnN0YXR1cyA9IHNlbGY6OlNUQVRVU19SRUFEWTsKICAgICAgICAkdGhpcy0+aW5jcmVtZW50YWxPdXRwdXRPZmZzZXQgPSAwOwogICAgICAgICR0aGlzLT5pbmNyZW1lbnRhbEVycm9yT3V0cHV0T2Zmc2V0ID0gMDsKICAgIH0KCiAgICAvKioKICAgICAqIFNlbmRzIGEgUE9TSVggc2lnbmFsIHRvIHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICRzaWduYWwgICAgICAgICBBIHZhbGlkIFBPU0lYIHNpZ25hbCAoc2VlIGh0dHBzOi8vcGhwLm5ldC9wY250bC5jb25zdGFudHMpCiAgICAgKiBAcGFyYW0gYm9vbCAkdGhyb3dFeGNlcHRpb24gV2hldGhlciB0byB0aHJvdyBleGNlcHRpb24gaW4gY2FzZSBzaWduYWwgZmFpbGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgdGhlIHNpZ25hbCB3YXMgc2VudCBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZQogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gICBJbiBjYXNlIHRoZSBwcm9jZXNzIGlzIG5vdCBydW5uaW5nCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSAtLWVuYWJsZS1zaWdjaGlsZCBpcyBhY3RpdmF0ZWQgYW5kIHRoZSBwcm9jZXNzIGNhbid0IGJlIGtpbGxlZAogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2Ugb2YgZmFpbHVyZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRvU2lnbmFsKCRzaWduYWwsICR0aHJvd0V4Y2VwdGlvbikKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHBpZCA9ICR0aGlzLT5nZXRQaWQoKSkgewogICAgICAgICAgICBpZiAoJHRocm93RXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0NhbiBub3Qgc2VuZCBzaWduYWwgb24gYSBub24gcnVubmluZyBwcm9jZXNzLicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgZXhlYyhzcHJpbnRmKCd0YXNra2lsbCAvRiAvVCAvUElEICVkIDI+JjEnLCAkcGlkKSwgJG91dHB1dCwgJGV4aXRDb2RlKTsKICAgICAgICAgICAgaWYgKCRleGl0Q29kZSAmJiAkdGhpcy0+aXNSdW5uaW5nKCkpIHsKICAgICAgICAgICAgICAgIGlmICgkdGhyb3dFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdVbmFibGUgdG8ga2lsbCB0aGUgcHJvY2VzcyAoJXMpLicsIGltcGxvZGUoJyAnLCAkb3V0cHV0KSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmVuaGFuY2VTaWdjaGlsZENvbXBhdGliaWxpdHkgfHwgISR0aGlzLT5pc1NpZ2NoaWxkRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAkb2sgPSBAcHJvY190ZXJtaW5hdGUoJHRoaXMtPnByb2Nlc3MsICRzaWduYWwpOwogICAgICAgICAgICB9IGVsc2VpZiAoXGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfa2lsbCcpKSB7CiAgICAgICAgICAgICAgICAkb2sgPSBAcG9zaXhfa2lsbCgkcGlkLCAkc2lnbmFsKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRvayA9IHByb2Nfb3BlbihzcHJpbnRmKCdraWxsIC0lZCAlZCcsICRzaWduYWwsICRwaWQpLCBbMiA9PiBbJ3BpcGUnLCAndyddXSwgJHBpcGVzKSkgewogICAgICAgICAgICAgICAgJG9rID0gZmFsc2UgPT09IGZnZXRzKCRwaXBlc1syXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkb2spIHsKICAgICAgICAgICAgICAgIGlmICgkdGhyb3dFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdFcnJvciB3aGlsZSBzZW5kaW5nIHNpZ25hbCBgJXNgLicsICRzaWduYWwpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5sYXRlc3RTaWduYWwgPSAoaW50KSAkc2lnbmFsOwogICAgICAgICR0aGlzLT5mYWxsYmFja1N0YXR1c1snc2lnbmFsZWQnXSA9IHRydWU7CiAgICAgICAgJHRoaXMtPmZhbGxiYWNrU3RhdHVzWydleGl0Y29kZSddID0gLTE7CiAgICAgICAgJHRoaXMtPmZhbGxiYWNrU3RhdHVzWyd0ZXJtc2lnJ10gPSAkdGhpcy0+bGF0ZXN0U2lnbmFsOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHByZXBhcmVXaW5kb3dzQ29tbWFuZExpbmUoJGNtZCwgYXJyYXkgJiRlbnYpCiAgICB7CiAgICAgICAgJHVpZCA9IHVuaXFpZCgnJywgdHJ1ZSk7CiAgICAgICAgJHZhckNvdW50ID0gMDsKICAgICAgICAkdmFyQ2FjaGUgPSBbXTsKICAgICAgICAkY21kID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAogICAgICAgICAgICAnLyIoPzooCiAgICAgICAgICAgICAgICBbXiIlIV5dKisKICAgICAgICAgICAgICAgICg/OgogICAgICAgICAgICAgICAgICAgICg/OiAhTEYhIHwgIig/OlxeWyUhXl0pPysiICkKICAgICAgICAgICAgICAgICAgICBbXiIlIV5dKisKICAgICAgICAgICAgICAgICkrKwogICAgICAgICAgICApIHwgW14iXSorICkiL3gnLAogICAgICAgICAgICBmdW5jdGlvbiAoJG0pIHVzZSAoJiRlbnYsICYkdmFyQ2FjaGUsICYkdmFyQ291bnQsICR1aWQpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJG1bMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRtWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YXJDYWNoZVskbVswXV0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YXJDYWNoZVskbVswXV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkdmFsdWUgPSAkbVsxXSwgIlwwIikpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZSgiXDAiLCAnPycsICR2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHN0cnBicmsoJHZhbHVlLCAiXCIlIVxuIikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyInLiR2YWx1ZS4nIic7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHZhbHVlID0gc3RyX3JlcGxhY2UoWychTEYhJywgJyJeISInLCAnIl4lIicsICciXl4iJywgJyIiJ10sIFsiXG4iLCAnIScsICclJywgJ14nLCAnIiddLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJyInLnByZWdfcmVwbGFjZSgnLyhcXFxcKikiLycsICckMSQxXFwiJywgJHZhbHVlKS4nIic7CiAgICAgICAgICAgICAgICAkdmFyID0gJHVpZC4rKyR2YXJDb3VudDsKCiAgICAgICAgICAgICAgICAkZW52WyR2YXJdID0gJHZhbHVlOwoKICAgICAgICAgICAgICAgIHJldHVybiAkdmFyQ2FjaGVbJG1bMF1dID0gJyEnLiR2YXIuJyEnOwogICAgICAgICAgICB9LAogICAgICAgICAgICAkY21kCiAgICAgICAgKTsKCiAgICAgICAgJGNtZCA9ICdjbWQgL1Y6T04gL0U6T04gL0QgL0MgKCcuc3RyX3JlcGxhY2UoIlxuIiwgJyAnLCAkY21kKS4nKSc7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnByb2Nlc3NQaXBlcy0+Z2V0RmlsZXMoKSBhcyAkb2Zmc2V0ID0+ICRmaWxlbmFtZSkgewogICAgICAgICAgICAkY21kIC49ICcgJy4kb2Zmc2V0Lic+IicuJGZpbGVuYW1lLiciJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY21kOwogICAgfQoKICAgIC8qKgogICAgICogRW5zdXJlcyB0aGUgcHJvY2VzcyBpcyBydW5uaW5nIG9yIHRlcm1pbmF0ZWQsIHRocm93cyBhIExvZ2ljRXhjZXB0aW9uIGlmIHRoZSBwcm9jZXNzIGhhcyBhIG5vdCBzdGFydGVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZ1bmN0aW9uTmFtZSBUaGUgZnVuY3Rpb24gbmFtZSB0aGF0IHdhcyBjYWxsZWQKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIGlmIHRoZSBwcm9jZXNzIGhhcyBub3QgcnVuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVxdWlyZVByb2Nlc3NJc1N0YXJ0ZWQoJGZ1bmN0aW9uTmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pc1N0YXJ0ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oc3ByaW50ZignUHJvY2VzcyBtdXN0IGJlIHN0YXJ0ZWQgYmVmb3JlIGNhbGxpbmcgIiVzKCkiLicsICRmdW5jdGlvbk5hbWUpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFbnN1cmVzIHRoZSBwcm9jZXNzIGlzIHRlcm1pbmF0ZWQsIHRocm93cyBhIExvZ2ljRXhjZXB0aW9uIGlmIHRoZSBwcm9jZXNzIGhhcyBhIHN0YXR1cyBkaWZmZXJlbnQgdGhhbiBgdGVybWluYXRlZGAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZnVuY3Rpb25OYW1lIFRoZSBmdW5jdGlvbiBuYW1lIHRoYXQgd2FzIGNhbGxlZAogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gaWYgdGhlIHByb2Nlc3MgaXMgbm90IHlldCB0ZXJtaW5hdGVkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVxdWlyZVByb2Nlc3NJc1Rlcm1pbmF0ZWQoJGZ1bmN0aW9uTmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pc1Rlcm1pbmF0ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oc3ByaW50ZignUHJvY2VzcyBtdXN0IGJlIHRlcm1pbmF0ZWQgYmVmb3JlIGNhbGxpbmcgIiVzKCkiLicsICRmdW5jdGlvbk5hbWUpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFc2NhcGVzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBzaGVsbCBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudCBUaGUgYXJndW1lbnQgdGhhdCB3aWxsIGJlIGVzY2FwZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZXNjYXBlZCBhcmd1bWVudAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVzY2FwZUFyZ3VtZW50KCRhcmd1bWVudCkKICAgIHsKICAgICAgICBpZiAoJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgcmV0dXJuICInIi5zdHJfcmVwbGFjZSgiJyIsICInXFwnJyIsICRhcmd1bWVudCkuIiciOwogICAgICAgIH0KICAgICAgICBpZiAoJycgPT09ICRhcmd1bWVudCA9IChzdHJpbmcpICRhcmd1bWVudCkgewogICAgICAgICAgICByZXR1cm4gJyIiJzsKICAgICAgICB9CiAgICAgICAgaWYgKGZhbHNlICE9PSBzdHJwb3MoJGFyZ3VtZW50LCAiXDAiKSkgewogICAgICAgICAgICAkYXJndW1lbnQgPSBzdHJfcmVwbGFjZSgiXDAiLCAnPycsICRhcmd1bWVudCk7CiAgICAgICAgfQogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL1tcLygpJSFeIjw+Jnxcc10vJywgJGFyZ3VtZW50KSkgewogICAgICAgICAgICByZXR1cm4gJGFyZ3VtZW50OwogICAgICAgIH0KICAgICAgICAkYXJndW1lbnQgPSBwcmVnX3JlcGxhY2UoJy8oXFxcXCspJC8nLCAnJDEkMScsICRhcmd1bWVudCk7CgogICAgICAgIHJldHVybiAnIicuc3RyX3JlcGxhY2UoWyciJywgJ14nLCAnJScsICchJywgIlxuIl0sIFsnIiInLCAnIl5eIicsICciXiUiJywgJyJeISInLCAnIUxGISddLCAkYXJndW1lbnQpLiciJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERlZmF1bHRFbnYoKQogICAgewogICAgICAgICRlbnYgPSBbXTsKCiAgICAgICAgZm9yZWFjaCAoJF9TRVJWRVIgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgaWYgKFxpc19zdHJpbmcoJHYpICYmIGZhbHNlICE9PSAkdiA9IGdldGVudigkaykpIHsKICAgICAgICAgICAgICAgICRlbnZbJGtdID0gJHY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRfRU5WIGFzICRrID0+ICR2KSB7CiAgICAgICAgICAgIGlmIChcaXNfc3RyaW5nKCR2KSkgewogICAgICAgICAgICAgICAgJGVudlska10gPSAkdjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRlbnY7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXFJ1bnRpbWVFeGNlcHRpb247CgovKioKICogUHJvdmlkZXMgYSB3YXkgdG8gY29udGludW91c2x5IHdyaXRlIHRvIHRoZSBpbnB1dCBvZiBhIFByb2Nlc3MgdW50aWwgdGhlIElucHV0U3RyZWFtIGlzIGNsb3NlZC4KICoKICogQGF1dGhvciBOaWNvbGFzIEdyZWthcyA8cEB0Y2h3b3JrLmNvbT4KICovCmNsYXNzIElucHV0U3RyZWFtIGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlCnsKICAgIC8qKiBAdmFyIGNhbGxhYmxlfG51bGwgKi8KICAgIHByaXZhdGUgJG9uRW1wdHkgPSBudWxsOwogICAgcHJpdmF0ZSAkaW5wdXQgPSBbXTsKICAgIHByaXZhdGUgJG9wZW4gPSB0cnVlOwoKICAgIC8qKgogICAgICogU2V0cyBhIGNhbGxiYWNrIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIHdyaXRlIGJ1ZmZlciBiZWNvbWVzIGVtcHR5LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25FbXB0eShjYWxsYWJsZSAkb25FbXB0eSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm9uRW1wdHkgPSAkb25FbXB0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGVuZHMgYW4gaW5wdXQgdG8gdGhlIHdyaXRlIGJ1ZmZlci4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nfGludHxmbG9hdHxib29sfFxUcmF2ZXJzYWJsZXxudWxsICRpbnB1dCBUaGUgaW5wdXQgdG8gYXBwZW5kIGFzIHNjYWxhciwKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbSByZXNvdXJjZSBvciBcVHJhdmVyc2FibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRpbnB1dCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGlucHV0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5pc0Nsb3NlZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJyIlcyIgaXMgY2xvc2VkLicsIHN0YXRpYzo6Y2xhc3MpKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlucHV0W10gPSBQcm9jZXNzVXRpbHM6OnZhbGlkYXRlSW5wdXQoX19NRVRIT0RfXywgJGlucHV0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENsb3NlcyB0aGUgd3JpdGUgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKQogICAgewogICAgICAgICR0aGlzLT5vcGVuID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZWxscyB3aGV0aGVyIHRoZSB3cml0ZSBidWZmZXIgaXMgY2xvc2VkIG9yIG5vdC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQ2xvc2VkKCkKICAgIHsKICAgICAgICByZXR1cm4gISR0aGlzLT5vcGVuOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJdGVyYXRvcigpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wZW4gPSB0cnVlOwoKICAgICAgICB3aGlsZSAoJHRoaXMtPm9wZW4gfHwgJHRoaXMtPmlucHV0KSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmlucHV0KSB7CiAgICAgICAgICAgICAgICB5aWVsZCAnJzsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjdXJyZW50ID0gYXJyYXlfc2hpZnQoJHRoaXMtPmlucHV0KTsKCiAgICAgICAgICAgIGlmICgkY3VycmVudCBpbnN0YW5jZW9mIFxJdGVyYXRvcikgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGN1cnJlbnQgYXMgJGN1cikgewogICAgICAgICAgICAgICAgICAgIHlpZWxkICRjdXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB5aWVsZCAkY3VycmVudDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoISR0aGlzLT5pbnB1dCAmJiAkdGhpcy0+b3BlbiAmJiBudWxsICE9PSAkb25FbXB0eSA9ICR0aGlzLT5vbkVtcHR5KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoJG9uRW1wdHkoJHRoaXMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwoKLyoqCiAqIFByb2Nlc3NVdGlscyBpcyBhIGJ1bmNoIG9mIHV0aWxpdHkgbWV0aG9kcy4KICoKICogVGhpcyBjbGFzcyBjb250YWlucyBzdGF0aWMgbWV0aG9kcyBvbmx5IGFuZCBpcyBub3QgbWVhbnQgdG8gYmUgaW5zdGFudGlhdGVkLgogKgogKiBAYXV0aG9yIE1hcnRpbiBIYXNvxYggPG1hcnRpbi5oYXNvbkBnbWFpbC5jb20+CiAqLwpjbGFzcyBQcm9jZXNzVXRpbHMKewogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEVzY2FwZXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIHNoZWxsIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFyZ3VtZW50IFRoZSBhcmd1bWVudCB0aGF0IHdpbGwgYmUgZXNjYXBlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBlc2NhcGVkIGFyZ3VtZW50CiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjMsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgYSBjb21tYW5kIGxpbmUgYXJyYXkgb3IgZ2l2ZSBlbnYgdmFycyB0byB0aGUgYFByb2Nlc3M6OnN0YXJ0L3J1bigpYCBtZXRob2QgaW5zdGVhZC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGVBcmd1bWVudCgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3IoJ1RoZSAnLl9fTUVUSE9EX18uJygpIG1ldGhvZCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgYSBjb21tYW5kIGxpbmUgYXJyYXkgb3IgZ2l2ZSBlbnYgdmFycyB0byB0aGUgUHJvY2Vzczo6c3RhcnQvcnVuKCkgbWV0aG9kIGluc3RlYWQuJywgXEVfVVNFUl9ERVBSRUNBVEVEKTsKCiAgICAgICAgLy9GaXggZm9yIFBIUCBidWcgIzQzNzg0IGVzY2FwZXNoZWxsYXJnIHJlbW92ZXMgJSBmcm9tIGdpdmVuIHN0cmluZwogICAgICAgIC8vRml4IGZvciBQSFAgYnVnICM0OTQ0NiBlc2NhcGVzaGVsbGFyZyBkb2Vzbid0IHdvcmsgb24gV2luZG93cwogICAgICAgIC8vQHNlZSBodHRwczovL2J1Z3MucGhwLm5ldC80Mzc4NAogICAgICAgIC8vQHNlZSBodHRwczovL2J1Z3MucGhwLm5ldC80OTQ0NgogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICBpZiAoJycgPT09ICRhcmd1bWVudCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGVzY2FwZXNoZWxsYXJnKCRhcmd1bWVudCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRlc2NhcGVkQXJndW1lbnQgPSAnJzsKICAgICAgICAgICAgJHF1b3RlID0gZmFsc2U7CiAgICAgICAgICAgIGZvcmVhY2ggKHByZWdfc3BsaXQoJy8oIikvJywgJGFyZ3VtZW50LCAtMSwgXFBSRUdfU1BMSVRfTk9fRU1QVFkgfCBcUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFKSBhcyAkcGFydCkgewogICAgICAgICAgICAgICAgaWYgKCciJyA9PT0gJHBhcnQpIHsKICAgICAgICAgICAgICAgICAgICAkZXNjYXBlZEFyZ3VtZW50IC49ICdcXCInOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKHNlbGY6OmlzU3Vycm91bmRlZEJ5KCRwYXJ0LCAnJScpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZW52aXJvbm1lbnQgdmFyaWFibGUgZXhwYW5zaW9uCiAgICAgICAgICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCAuPSAnXiUiJy5zdWJzdHIoJHBhcnQsIDEsIC0xKS4nIl4lJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZXNjYXBlIHRyYWlsaW5nIGJhY2tzbGFzaAogICAgICAgICAgICAgICAgICAgIGlmICgnXFwnID09PSBzdWJzdHIoJHBhcnQsIC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFydCAuPSAnXFwnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkcXVvdGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRlc2NhcGVkQXJndW1lbnQgLj0gJHBhcnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRxdW90ZSkgewogICAgICAgICAgICAgICAgJGVzY2FwZWRBcmd1bWVudCA9ICciJy4kZXNjYXBlZEFyZ3VtZW50LiciJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRlc2NhcGVkQXJndW1lbnQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIiciLnN0cl9yZXBsYWNlKCInIiwgIidcXCcnIiwgJGFyZ3VtZW50KS4iJyI7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgYW5kIG5vcm1hbGl6ZXMgYSBQcm9jZXNzIGlucHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNhbGxlciBUaGUgbmFtZSBvZiBtZXRob2QgY2FsbCB0aGF0IHZhbGlkYXRlcyB0aGUgaW5wdXQKICAgICAqIEBwYXJhbSBtaXhlZCAgJGlucHV0ICBUaGUgaW5wdXQgdG8gdmFsaWRhdGUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFRoZSB2YWxpZGF0ZWQgaW5wdXQKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJbiBjYXNlIHRoZSBpbnB1dCBpcyBub3QgdmFsaWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB2YWxpZGF0ZUlucHV0KCRjYWxsZXIsICRpbnB1dCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJGlucHV0KSB7CiAgICAgICAgICAgIGlmIChcaXNfcmVzb3VyY2UoJGlucHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbnB1dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoXGlzX3N0cmluZygkaW5wdXQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc19zY2FsYXIoJGlucHV0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIChzdHJpbmcpICRpbnB1dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGlucHV0IGluc3RhbmNlb2YgUHJvY2VzcykgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbnB1dC0+Z2V0SXRlcmF0b3IoJGlucHV0OjpJVEVSX1NLSVBfRVJSKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGlucHV0IGluc3RhbmNlb2YgXEl0ZXJhdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkaW5wdXQgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgXEl0ZXJhdG9ySXRlcmF0b3IoJGlucHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCciJXMiIG9ubHkgYWNjZXB0cyBzdHJpbmdzLCBUcmF2ZXJzYWJsZSBvYmplY3RzIG9yIHN0cmVhbSByZXNvdXJjZXMuJywgJGNhbGxlcikpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRpbnB1dDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc1N1cnJvdW5kZWRCeSgkYXJnLCAkY2hhcikKICAgIHsKICAgICAgICByZXR1cm4gMiA8IFxzdHJsZW4oJGFyZykgJiYgJGNoYXIgPT09ICRhcmdbMF0gJiYgJGNoYXIgPT09ICRhcmdbXHN0cmxlbigkYXJnKSAtIDFdOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlczsKCi8qKgogKiBQaXBlc0ludGVyZmFjZSBtYW5hZ2VzIGRlc2NyaXB0b3JzIGFuZCBwaXBlcyBmb3IgdGhlIHVzZSBvZiBwcm9jX29wZW4uCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KaW50ZXJmYWNlIFBpcGVzSW50ZXJmYWNlCnsKICAgIGNvbnN0IENIVU5LX1NJWkUgPSAxNjM4NDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgZGVzY3JpcHRvcnMgZm9yIHRoZSB1c2Ugb2YgcHJvY19vcGVuLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0b3JzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGZpbGVuYW1lcyBpbmRleGVkIGJ5IHRoZWlyIHJlbGF0ZWQgc3RyZWFtIGluIGNhc2UgdGhlc2UgcGlwZXMgdXNlIHRlbXBvcmFyeSBmaWxlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlcygpOwoKICAgIC8qKgogICAgICogUmVhZHMgZGF0YSBpbiBmaWxlIGhhbmRsZXMgYW5kIHBpcGVzLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRibG9ja2luZyBXaGV0aGVyIHRvIHVzZSBibG9ja2luZyBjYWxscyBvciBub3QKICAgICAqIEBwYXJhbSBib29sICRjbG9zZSAgICBXaGV0aGVyIHRvIGNsb3NlIHBpcGVzIGlmIHRoZXkndmUgcmVhY2hlZCBFT0YKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIEFuIGFycmF5IG9mIHJlYWQgZGF0YSBpbmRleGVkIGJ5IHRoZWlyIGZkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkQW5kV3JpdGUoJGJsb2NraW5nLCAkY2xvc2UgPSBmYWxzZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGlmIHRoZSBjdXJyZW50IHN0YXRlIGhhcyBvcGVuIGZpbGUgaGFuZGxlcyBvciBwaXBlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFyZU9wZW4oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgaWYgcGlwZXMgYXJlIGFibGUgdG8gcmVhZCBvdXRwdXQuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXZlUmVhZFN1cHBvcnQoKTsKCiAgICAvKioKICAgICAqIENsb3NlcyBmaWxlIGhhbmRsZXMgYW5kIHBpcGVzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUGlwZXM7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBXaW5kb3dzUGlwZXMgaW1wbGVtZW50YXRpb24gdXNlcyB0ZW1wb3JhcnkgZmlsZXMgYXMgaGFuZGxlcy4KICoKICogQHNlZSBodHRwczovL2J1Z3MucGhwLm5ldC81MTgwMAogKiBAc2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzY1NjUwCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KY2xhc3MgV2luZG93c1BpcGVzIGV4dGVuZHMgQWJzdHJhY3RQaXBlcwp7CiAgICBwcml2YXRlICRmaWxlcyA9IFtdOwogICAgcHJpdmF0ZSAkZmlsZUhhbmRsZXMgPSBbXTsKICAgIHByaXZhdGUgJGxvY2tIYW5kbGVzID0gW107CiAgICBwcml2YXRlICRyZWFkQnl0ZXMgPSBbCiAgICAgICAgUHJvY2Vzczo6U1RET1VUID0+IDAsCiAgICAgICAgUHJvY2Vzczo6U1RERVJSID0+IDAsCiAgICBdOwogICAgcHJpdmF0ZSAkaGF2ZVJlYWRTdXBwb3J0OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5wdXQsICRoYXZlUmVhZFN1cHBvcnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmhhdmVSZWFkU3VwcG9ydCA9IChib29sKSAkaGF2ZVJlYWRTdXBwb3J0OwoKICAgICAgICBpZiAoJHRoaXMtPmhhdmVSZWFkU3VwcG9ydCkgewogICAgICAgICAgICAvLyBGaXggZm9yIFBIUCBidWcgIzUxODAwOiByZWFkaW5nIGZyb20gU1RET1VUIHBpcGUgaGFuZ3MgZm9yZXZlciBvbiBXaW5kb3dzIGlmIHRoZSBvdXRwdXQgaXMgdG9vIGJpZy4KICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgdGhpcyBwcm9ibGVtIGlzIHRvIHVzZSB0ZW1wb3JhcnkgZmlsZXMgaW5zdGVhZCBvZiBwaXBlcyBvbiBXaW5kb3dzIHBsYXRmb3JtLgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBAc2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzUxODAwCiAgICAgICAgICAgICRwaXBlcyA9IFsKICAgICAgICAgICAgICAgIFByb2Nlc3M6OlNURE9VVCA9PiBQcm9jZXNzOjpPVVQsCiAgICAgICAgICAgICAgICBQcm9jZXNzOjpTVERFUlIgPT4gUHJvY2Vzczo6RVJSLAogICAgICAgICAgICBdOwogICAgICAgICAgICAkdG1wRGlyID0gc3lzX2dldF90ZW1wX2RpcigpOwogICAgICAgICAgICAkbGFzdEVycm9yID0gJ3Vua25vd24gcmVhc29uJzsKICAgICAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoZnVuY3Rpb24gKCR0eXBlLCAkbXNnKSB1c2UgKCYkbGFzdEVycm9yKSB7ICRsYXN0RXJyb3IgPSAkbXNnOyB9KTsKICAgICAgICAgICAgZm9yICgkaSA9IDA7OyArKyRpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGlwZXMgYXMgJHBpcGUgPT4gJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkZmlsZSA9IHNwcmludGYoJyVzXFxzZl9wcm9jXyUwMlguJXMnLCAkdG1wRGlyLCAkaSwgJG5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRoID0gZm9wZW4oJGZpbGUuJy5sb2NrJywgJ3cnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZV9leGlzdHMoJGZpbGUuJy5sb2NrJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdBIHRlbXBvcmFyeSBmaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQgdG8gd3JpdGUgdGhlIHByb2Nlc3Mgb3V0cHV0OiAnLiRsYXN0RXJyb3IpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoIWZsb2NrKCRoLCBcTE9DS19FWCB8IFxMT0NLX05CKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmxvY2soJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSwgXExPQ0tfVU4pOwogICAgICAgICAgICAgICAgICAgICAgICBmY2xvc2UoJHRoaXMtPmxvY2tIYW5kbGVzWyRwaXBlXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5sb2NrSGFuZGxlc1skcGlwZV0gPSAkaDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCFmY2xvc2UoZm9wZW4oJGZpbGUsICd3JykpIHx8ICEkaCA9IGZvcGVuKCRmaWxlLCAncicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsb2NrKCR0aGlzLT5sb2NrSGFuZGxlc1skcGlwZV0sIFxMT0NLX1VOKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmNsb3NlKCR0aGlzLT5sb2NrSGFuZGxlc1skcGlwZV0pOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+bG9ja0hhbmRsZXNbJHBpcGVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmZpbGVIYW5kbGVzWyRwaXBlXSA9ICRoOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5maWxlc1skcGlwZV0gPSAkZmlsZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Rlc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2xvc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0b3JzKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXZlUmVhZFN1cHBvcnQpIHsKICAgICAgICAgICAgJG51bGxzdHJlYW0gPSBmb3BlbignTlVMJywgJ2MnKTsKCiAgICAgICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICAgICBbJ3BpcGUnLCAnciddLAogICAgICAgICAgICAgICAgJG51bGxzdHJlYW0sCiAgICAgICAgICAgICAgICAkbnVsbHN0cmVhbSwKICAgICAgICAgICAgXTsKICAgICAgICB9CgogICAgICAgIC8vIFdlJ3JlIG5vdCB1c2luZyBwaXBlIG9uIFdpbmRvd3MgcGxhdGZvcm0gYXMgaXQgaGFuZ3MgKGh0dHBzOi8vYnVncy5waHAubmV0LzUxODAwKQogICAgICAgIC8vIFdlJ3JlIG5vdCB1c2luZyBmaWxlIGhhbmRsZXMgYXMgaXQgY2FuIHByb2R1Y2UgY29ycnVwdGVkIG91dHB1dCBodHRwczovL2J1Z3MucGhwLm5ldC82NTY1MAogICAgICAgIC8vIFNvIHdlIHJlZGlyZWN0IG91dHB1dCB3aXRoaW4gdGhlIGNvbW1hbmRsaW5lIGFuZCBwYXNzIHRoZSBudWwgZGV2aWNlIHRvIHRoZSBwcm9jZXNzCiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgWydwaXBlJywgJ3InXSwKICAgICAgICAgICAgWydmaWxlJywgJ05VTCcsICd3J10sCiAgICAgICAgICAgIFsnZmlsZScsICdOVUwnLCAndyddLAogICAgICAgIF07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaWxlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5maWxlczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWRBbmRXcml0ZSgkYmxvY2tpbmcsICRjbG9zZSA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT51bmJsb2NrKCk7CiAgICAgICAgJHcgPSAkdGhpcy0+d3JpdGUoKTsKICAgICAgICAkcmVhZCA9ICRyID0gJGUgPSBbXTsKCiAgICAgICAgaWYgKCRibG9ja2luZykgewogICAgICAgICAgICBpZiAoJHcpIHsKICAgICAgICAgICAgICAgIEBzdHJlYW1fc2VsZWN0KCRyLCAkdywgJGUsIDAsIFByb2Nlc3M6OlRJTUVPVVRfUFJFQ0lTSU9OICogMUU2KTsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5maWxlSGFuZGxlcykgewogICAgICAgICAgICAgICAgdXNsZWVwKFByb2Nlc3M6OlRJTUVPVVRfUFJFQ0lTSU9OICogMUU2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZmlsZUhhbmRsZXMgYXMgJHR5cGUgPT4gJGZpbGVIYW5kbGUpIHsKICAgICAgICAgICAgJGRhdGEgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRmaWxlSGFuZGxlLCAtMSwgJHRoaXMtPnJlYWRCeXRlc1skdHlwZV0pOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRkYXRhWzBdKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlYWRCeXRlc1skdHlwZV0gKz0gXHN0cmxlbigkZGF0YSk7CiAgICAgICAgICAgICAgICAkcmVhZFskdHlwZV0gPSAkZGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGNsb3NlKSB7CiAgICAgICAgICAgICAgICBmdHJ1bmNhdGUoJGZpbGVIYW5kbGUsIDApOwogICAgICAgICAgICAgICAgZmNsb3NlKCRmaWxlSGFuZGxlKTsKICAgICAgICAgICAgICAgIGZsb2NrKCR0aGlzLT5sb2NrSGFuZGxlc1skdHlwZV0sIFxMT0NLX1VOKTsKICAgICAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+bG9ja0hhbmRsZXNbJHR5cGVdKTsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5maWxlSGFuZGxlc1skdHlwZV0sICR0aGlzLT5sb2NrSGFuZGxlc1skdHlwZV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlYWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXZlUmVhZFN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGF2ZVJlYWRTdXBwb3J0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXJlT3BlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5waXBlcyAmJiAkdGhpcy0+ZmlsZUhhbmRsZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbG9zZSgpCiAgICB7CiAgICAgICAgcGFyZW50OjpjbG9zZSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5maWxlSGFuZGxlcyBhcyAkdHlwZSA9PiAkaGFuZGxlKSB7CiAgICAgICAgICAgIGZ0cnVuY2F0ZSgkaGFuZGxlLCAwKTsKICAgICAgICAgICAgZmNsb3NlKCRoYW5kbGUpOwogICAgICAgICAgICBmbG9jaygkdGhpcy0+bG9ja0hhbmRsZXNbJHR5cGVdLCBcTE9DS19VTik7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+bG9ja0hhbmRsZXNbJHR5cGVdKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmZpbGVIYW5kbGVzID0gJHRoaXMtPmxvY2tIYW5kbGVzID0gW107CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFBpcGVzOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIFJvbWFpbiBOZXV0cm9uIDxpbXByZWNAZ21haWwuY29tPgogKgogKiBAaW50ZXJuYWwKICovCmFic3RyYWN0IGNsYXNzIEFic3RyYWN0UGlwZXMgaW1wbGVtZW50cyBQaXBlc0ludGVyZmFjZQp7CiAgICBwdWJsaWMgJHBpcGVzID0gW107CgogICAgcHJpdmF0ZSAkaW5wdXRCdWZmZXIgPSAnJzsKICAgIHByaXZhdGUgJGlucHV0OwogICAgcHJpdmF0ZSAkYmxvY2tlZCA9IHRydWU7CiAgICBwcml2YXRlICRsYXN0RXJyb3I7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nfGludHxmbG9hdHxib29sfFxJdGVyYXRvcnxudWxsICRpbnB1dAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGlucHV0KQogICAgewogICAgICAgIGlmIChcaXNfcmVzb3VyY2UoJGlucHV0KSB8fCAkaW5wdXQgaW5zdGFuY2VvZiBcSXRlcmF0b3IpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgIH0gZWxzZWlmIChcaXNfc3RyaW5nKCRpbnB1dCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0QnVmZmVyID0gJGlucHV0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5pbnB1dEJ1ZmZlciA9IChzdHJpbmcpICRpbnB1dDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbG9zZSgpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBpcGVzIGFzICRwaXBlKSB7CiAgICAgICAgICAgIGZjbG9zZSgkcGlwZSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5waXBlcyA9IFtdOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGEgc3lzdGVtIGNhbGwgaGFzIGJlZW4gaW50ZXJydXB0ZWQuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNTeXN0ZW1DYWxsQmVlbkludGVycnVwdGVkKCkKICAgIHsKICAgICAgICAkbGFzdEVycm9yID0gJHRoaXMtPmxhc3RFcnJvcjsKICAgICAgICAkdGhpcy0+bGFzdEVycm9yID0gbnVsbDsKCiAgICAgICAgLy8gc3RyZWFtX3NlbGVjdCByZXR1cm5zIGZhbHNlIHdoZW4gdGhlIGBzZWxlY3RgIHN5c3RlbSBjYWxsIGlzIGludGVycnVwdGVkIGJ5IGFuIGluY29taW5nIHNpZ25hbAogICAgICAgIHJldHVybiBudWxsICE9PSAkbGFzdEVycm9yICYmIGZhbHNlICE9PSBzdHJpcG9zKCRsYXN0RXJyb3IsICdpbnRlcnJ1cHRlZCBzeXN0ZW0gY2FsbCcpOwogICAgfQoKICAgIC8qKgogICAgICogVW5ibG9ja3Mgc3RyZWFtcy4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVuYmxvY2soKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmJsb2NrZWQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBpcGVzIGFzICRwaXBlKSB7CiAgICAgICAgICAgIHN0cmVhbV9zZXRfYmxvY2tpbmcoJHBpcGUsIDApOwogICAgICAgIH0KICAgICAgICBpZiAoXGlzX3Jlc291cmNlKCR0aGlzLT5pbnB1dCkpIHsKICAgICAgICAgICAgc3RyZWFtX3NldF9ibG9ja2luZygkdGhpcy0+aW5wdXQsIDApOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmJsb2NrZWQgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyBpbnB1dCB0byBzdGRpbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFuIGlucHV0IGl0ZXJhdG9yIHlpZWxkcyBhIG5vbiBzdXBwb3J0ZWQgdmFsdWUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlKCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5waXBlc1swXSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICRpbnB1dCA9ICR0aGlzLT5pbnB1dDsKCiAgICAgICAgaWYgKCRpbnB1dCBpbnN0YW5jZW9mIFxJdGVyYXRvcikgewogICAgICAgICAgICBpZiAoISRpbnB1dC0+dmFsaWQoKSkgewogICAgICAgICAgICAgICAgJGlucHV0ID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlaWYgKFxpc19yZXNvdXJjZSgkaW5wdXQgPSAkaW5wdXQtPmN1cnJlbnQoKSkpIHsKICAgICAgICAgICAgICAgIHN0cmVhbV9zZXRfYmxvY2tpbmcoJGlucHV0LCAwKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCFpc3NldCgkdGhpcy0+aW5wdXRCdWZmZXJbMF0pKSB7CiAgICAgICAgICAgICAgICBpZiAoIVxpc19zdHJpbmcoJGlucHV0KSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNfc2NhbGFyKCRpbnB1dCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCciJXMiIHlpZWxkZWQgYSB2YWx1ZSBvZiB0eXBlICIlcyIsIGJ1dCBvbmx5IHNjYWxhcnMgYW5kIHN0cmVhbSByZXNvdXJjZXMgYXJlIHN1cHBvcnRlZC4nLCBcZ2V0X2NsYXNzKCR0aGlzLT5pbnB1dCksIFxnZXR0eXBlKCRpbnB1dCkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGlucHV0ID0gKHN0cmluZykgJGlucHV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPmlucHV0QnVmZmVyID0gJGlucHV0OwogICAgICAgICAgICAgICAgJHRoaXMtPmlucHV0LT5uZXh0KCk7CiAgICAgICAgICAgICAgICAkaW5wdXQgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGlucHV0ID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHIgPSAkZSA9IFtdOwogICAgICAgICR3ID0gWyR0aGlzLT5waXBlc1swXV07CgogICAgICAgIC8vIGxldCdzIGhhdmUgYSBsb29rIGlmIHNvbWV0aGluZyBjaGFuZ2VkIGluIHN0cmVhbXMKICAgICAgICBpZiAoZmFsc2UgPT09IEBzdHJlYW1fc2VsZWN0KCRyLCAkdywgJGUsIDAsIDApKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHcgYXMgJHN0ZGluKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+aW5wdXRCdWZmZXJbMF0pKSB7CiAgICAgICAgICAgICAgICAkd3JpdHRlbiA9IGZ3cml0ZSgkc3RkaW4sICR0aGlzLT5pbnB1dEJ1ZmZlcik7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5wdXRCdWZmZXIgPSBzdWJzdHIoJHRoaXMtPmlucHV0QnVmZmVyLCAkd3JpdHRlbik7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmlucHV0QnVmZmVyWzBdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBbJHRoaXMtPnBpcGVzWzBdXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRpbnB1dCkgewogICAgICAgICAgICAgICAgZm9yICg7OykgewogICAgICAgICAgICAgICAgICAgICRkYXRhID0gZnJlYWQoJGlucHV0LCBzZWxmOjpDSFVOS19TSVpFKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRkYXRhWzBdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHdyaXR0ZW4gPSBmd3JpdGUoJHN0ZGluLCAkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgJGRhdGEgPSBzdWJzdHIoJGRhdGEsICR3cml0dGVuKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGRhdGFbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbnB1dEJ1ZmZlciA9ICRkYXRhOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFskdGhpcy0+cGlwZXNbMF1dOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChmZW9mKCRpbnB1dCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmlucHV0IGluc3RhbmNlb2YgXEl0ZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbnB1dC0+bmV4dCgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbnB1dCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBubyBpbnB1dCB0byByZWFkIG9uIHJlc291cmNlLCBidWZmZXIgaXMgZW1wdHkKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5pbnB1dEJ1ZmZlclswXSkgJiYgISgkdGhpcy0+aW5wdXQgaW5zdGFuY2VvZiBcSXRlcmF0b3IgPyAkdGhpcy0+aW5wdXQtPnZhbGlkKCkgOiAkdGhpcy0+aW5wdXQpKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnB1dCA9IG51bGw7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+cGlwZXNbMF0pOwogICAgICAgICAgICB1bnNldCgkdGhpcy0+cGlwZXNbMF0pOwogICAgICAgIH0gZWxzZWlmICghJHcpIHsKICAgICAgICAgICAgcmV0dXJuIFskdGhpcy0+cGlwZXNbMF1dOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhbmRsZUVycm9yKCR0eXBlLCAkbXNnKQogICAgewogICAgICAgICR0aGlzLT5sYXN0RXJyb3IgPSAkbXNnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xQaXBlczsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXFByb2Nlc3M7CgovKioKICogVW5peFBpcGVzIGltcGxlbWVudGF0aW9uIHVzZXMgdW5peCBwaXBlcyBhcyBoYW5kbGVzLgogKgogKiBAYXV0aG9yIFJvbWFpbiBOZXV0cm9uIDxpbXByZWNAZ21haWwuY29tPgogKgogKiBAaW50ZXJuYWwKICovCmNsYXNzIFVuaXhQaXBlcyBleHRlbmRzIEFic3RyYWN0UGlwZXMKewogICAgcHJpdmF0ZSAkdHR5TW9kZTsKICAgIHByaXZhdGUgJHB0eU1vZGU7CiAgICBwcml2YXRlICRoYXZlUmVhZFN1cHBvcnQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR0dHlNb2RlLCAkcHR5TW9kZSwgJGlucHV0LCAkaGF2ZVJlYWRTdXBwb3J0KQogICAgewogICAgICAgICR0aGlzLT50dHlNb2RlID0gKGJvb2wpICR0dHlNb2RlOwogICAgICAgICR0aGlzLT5wdHlNb2RlID0gKGJvb2wpICRwdHlNb2RlOwogICAgICAgICR0aGlzLT5oYXZlUmVhZFN1cHBvcnQgPSAoYm9vbCkgJGhhdmVSZWFkU3VwcG9ydDsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2Rlc3RydWN0KCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2xvc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlc2NyaXB0b3JzKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXZlUmVhZFN1cHBvcnQpIHsKICAgICAgICAgICAgJG51bGxzdHJlYW0gPSBmb3BlbignL2Rldi9udWxsJywgJ2MnKTsKCiAgICAgICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICAgICBbJ3BpcGUnLCAnciddLAogICAgICAgICAgICAgICAgJG51bGxzdHJlYW0sCiAgICAgICAgICAgICAgICAkbnVsbHN0cmVhbSwKICAgICAgICAgICAgXTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+dHR5TW9kZSkgewogICAgICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAgICAgWydmaWxlJywgJy9kZXYvdHR5JywgJ3InXSwKICAgICAgICAgICAgICAgIFsnZmlsZScsICcvZGV2L3R0eScsICd3J10sCiAgICAgICAgICAgICAgICBbJ2ZpbGUnLCAnL2Rldi90dHknLCAndyddLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wdHlNb2RlICYmIFByb2Nlc3M6OmlzUHR5U3VwcG9ydGVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgICAgIFsncHR5J10sCiAgICAgICAgICAgICAgICBbJ3B0eSddLAogICAgICAgICAgICAgICAgWydwdHknXSwKICAgICAgICAgICAgXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgIFsncGlwZScsICdyJ10sCiAgICAgICAgICAgIFsncGlwZScsICd3J10sIC8vIHN0ZG91dAogICAgICAgICAgICBbJ3BpcGUnLCAndyddLCAvLyBzdGRlcnIKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmlsZXMoKQogICAgewogICAgICAgIHJldHVybiBbXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWRBbmRXcml0ZSgkYmxvY2tpbmcsICRjbG9zZSA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT51bmJsb2NrKCk7CiAgICAgICAgJHcgPSAkdGhpcy0+d3JpdGUoKTsKCiAgICAgICAgJHJlYWQgPSAkZSA9IFtdOwogICAgICAgICRyID0gJHRoaXMtPnBpcGVzOwogICAgICAgIHVuc2V0KCRyWzBdKTsKCiAgICAgICAgLy8gbGV0J3MgaGF2ZSBhIGxvb2sgaWYgc29tZXRoaW5nIGNoYW5nZWQgaW4gc3RyZWFtcwogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKFskdGhpcywgJ2hhbmRsZUVycm9yJ10pOwogICAgICAgIGlmICgoJHIgfHwgJHcpICYmIGZhbHNlID09PSBzdHJlYW1fc2VsZWN0KCRyLCAkdywgJGUsIDAsICRibG9ja2luZyA/IFByb2Nlc3M6OlRJTUVPVVRfUFJFQ0lTSU9OICogMUU2IDogMCkpIHsKICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CiAgICAgICAgICAgIC8vIGlmIGEgc3lzdGVtIGNhbGwgaGFzIGJlZW4gaW50ZXJydXB0ZWQsIGZvcmdldCBhYm91dCBpdCwgbGV0J3MgdHJ5IGFnYWluCiAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgYW4gZXJyb3Igb2NjdXJyZWQsIGxldCdzIHJlc2V0IHBpcGVzCiAgICAgICAgICAgIGlmICghJHRoaXMtPmhhc1N5c3RlbUNhbGxCZWVuSW50ZXJydXB0ZWQoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnBpcGVzID0gW107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcmVhZDsKICAgICAgICB9CiAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgIGZvcmVhY2ggKCRyIGFzICRwaXBlKSB7CiAgICAgICAgICAgIC8vIHByaW9yIFBIUCA1LjQgdGhlIGFycmF5IHBhc3NlZCB0byBzdHJlYW1fc2VsZWN0IGlzIG1vZGlmaWVkIGFuZAogICAgICAgICAgICAvLyBsb3NlIGtleSBhc3NvY2lhdGlvbiwgd2UgaGF2ZSB0byBmaW5kIGJhY2sgdGhlIGtleQogICAgICAgICAgICAkcmVhZFskdHlwZSA9IGFycmF5X3NlYXJjaCgkcGlwZSwgJHRoaXMtPnBpcGVzLCB0cnVlKV0gPSAnJzsKCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICRkYXRhID0gQGZyZWFkKCRwaXBlLCBzZWxmOjpDSFVOS19TSVpFKTsKICAgICAgICAgICAgICAgICRyZWFkWyR0eXBlXSAuPSAkZGF0YTsKICAgICAgICAgICAgfSB3aGlsZSAoaXNzZXQoJGRhdGFbMF0pICYmICgkY2xvc2UgfHwgaXNzZXQoJGRhdGFbc2VsZjo6Q0hVTktfU0laRSAtIDFdKSkpOwoKICAgICAgICAgICAgaWYgKCFpc3NldCgkcmVhZFskdHlwZV1bMF0pKSB7CiAgICAgICAgICAgICAgICB1bnNldCgkcmVhZFskdHlwZV0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGNsb3NlICYmIGZlb2YoJHBpcGUpKSB7CiAgICAgICAgICAgICAgICBmY2xvc2UoJHBpcGUpOwogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPnBpcGVzWyR0eXBlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVhZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhdmVSZWFkU3VwcG9ydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXZlUmVhZFN1cHBvcnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmVPcGVuKCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpICR0aGlzLT5waXBlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3M7CgovKioKICogQW4gZXhlY3V0YWJsZSBmaW5kZXIgc3BlY2lmaWNhbGx5IGRlc2lnbmVkIGZvciB0aGUgUEhQIGV4ZWN1dGFibGUuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgUGhwRXhlY3V0YWJsZUZpbmRlcgp7CiAgICBwcml2YXRlICRleGVjdXRhYmxlRmluZGVyOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4ZWN1dGFibGVGaW5kZXIgPSBuZXcgRXhlY3V0YWJsZUZpbmRlcigpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgVGhlIFBIUCBleGVjdXRhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpbmNsdWRlQXJncyBXaGV0aGVyIG9yIG5vdCBpbmNsdWRlIGNvbW1hbmQgYXJndW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8ZmFsc2UgVGhlIFBIUCBleGVjdXRhYmxlIHBhdGggb3IgZmFsc2UgaWYgaXQgY2Fubm90IGJlIGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5kKCRpbmNsdWRlQXJncyA9IHRydWUpCiAgICB7CiAgICAgICAgJGFyZ3MgPSAkdGhpcy0+ZmluZEFyZ3VtZW50cygpOwogICAgICAgICRhcmdzID0gJGluY2x1ZGVBcmdzICYmICRhcmdzID8gJyAnLmltcGxvZGUoJyAnLCAkYXJncykgOiAnJzsKCiAgICAgICAgLy8gSEhWTSBzdXBwb3J0CiAgICAgICAgaWYgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICByZXR1cm4gKGdldGVudignUEhQX0JJTkFSWScpID86IFxQSFBfQklOQVJZKS4kYXJnczsKICAgICAgICB9CgogICAgICAgIC8vIFBIUF9CSU5BUlkgcmV0dXJuIHRoZSBjdXJyZW50IHNhcGkgZXhlY3V0YWJsZQogICAgICAgIGlmIChcUEhQX0JJTkFSWSAmJiBcaW5fYXJyYXkoXFBIUF9TQVBJLCBbJ2NsaScsICdjbGktc2VydmVyJywgJ3BocGRiZyddLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gXFBIUF9CSU5BUlkuJGFyZ3M7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHBocCA9IGdldGVudignUEhQX1BBVEgnKSkgewogICAgICAgICAgICBpZiAoIUBpc19leGVjdXRhYmxlKCRwaHApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkcGhwOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRwaHAgPSBnZXRlbnYoJ1BIUF9QRUFSX1BIUF9CSU4nKSkgewogICAgICAgICAgICBpZiAoQGlzX2V4ZWN1dGFibGUoJHBocCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcGhwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoQGlzX2V4ZWN1dGFibGUoJHBocCA9IFxQSFBfQklORElSLignXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUiA/ICdcXHBocC5leGUnIDogJy9waHAnKSkpIHsKICAgICAgICAgICAgcmV0dXJuICRwaHA7CiAgICAgICAgfQoKICAgICAgICAkZGlycyA9IFtcUEhQX0JJTkRJUl07CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRkaXJzW10gPSAnQzpceGFtcHBccGhwXFwnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5leGVjdXRhYmxlRmluZGVyLT5maW5kKCdwaHAnLCBmYWxzZSwgJGRpcnMpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgdGhlIFBIUCBleGVjdXRhYmxlIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBQSFAgZXhlY3V0YWJsZSBhcmd1bWVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmRBcmd1bWVudHMoKQogICAgewogICAgICAgICRhcmd1bWVudHMgPSBbXTsKCiAgICAgICAgaWYgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSkgewogICAgICAgICAgICAkYXJndW1lbnRzW10gPSAnLS1waHAnOwogICAgICAgIH0gZWxzZWlmICgncGhwZGJnJyA9PT0gXFBIUF9TQVBJKSB7CiAgICAgICAgICAgICRhcmd1bWVudHNbXSA9ICctcXJyJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkYXJndW1lbnRzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2VzczsKCi8qKgogKiBHZW5lcmljIGV4ZWN1dGFibGUgZmluZGVyLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBKb2hhbm5lcyBNLiBTY2htaXR0IDxzY2htaXR0am9oQGdtYWlsLmNvbT4KICovCmNsYXNzIEV4ZWN1dGFibGVGaW5kZXIKewogICAgcHJpdmF0ZSAkc3VmZml4ZXMgPSBbJy5leGUnLCAnLmJhdCcsICcuY21kJywgJy5jb20nXTsKCiAgICAvKioKICAgICAqIFJlcGxhY2VzIGRlZmF1bHQgc3VmZml4ZXMgb2YgZXhlY3V0YWJsZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN1ZmZpeGVzKGFycmF5ICRzdWZmaXhlcykKICAgIHsKICAgICAgICAkdGhpcy0+c3VmZml4ZXMgPSAkc3VmZml4ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIG5ldyBwb3NzaWJsZSBzdWZmaXggdG8gY2hlY2sgZm9yIGV4ZWN1dGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3VmZml4CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdWZmaXgoJHN1ZmZpeCkKICAgIHsKICAgICAgICAkdGhpcy0+c3VmZml4ZXNbXSA9ICRzdWZmaXg7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5kcyBhbiBleGVjdXRhYmxlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRuYW1lICAgICAgVGhlIGV4ZWN1dGFibGUgbmFtZSAod2l0aG91dCB0aGUgZXh0ZW5zaW9uKQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRkZWZhdWx0ICAgVGhlIGRlZmF1bHQgdG8gcmV0dXJuIGlmIG5vIGV4ZWN1dGFibGUgaXMgZm91bmQKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAkZXh0cmFEaXJzIEFkZGl0aW9uYWwgZGlycyB0byBjaGVjayBpbnRvCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgZXhlY3V0YWJsZSBwYXRoIG9yIGRlZmF1bHQgdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmQoJG5hbWUsICRkZWZhdWx0ID0gbnVsbCwgYXJyYXkgJGV4dHJhRGlycyA9IFtdKQogICAgewogICAgICAgIGlmIChpbmlfZ2V0KCdvcGVuX2Jhc2VkaXInKSkgewogICAgICAgICAgICAkc2VhcmNoUGF0aCA9IGFycmF5X21lcmdlKGV4cGxvZGUoXFBBVEhfU0VQQVJBVE9SLCBpbmlfZ2V0KCdvcGVuX2Jhc2VkaXInKSksICRleHRyYURpcnMpOwogICAgICAgICAgICAkZGlycyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgkc2VhcmNoUGF0aCBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgLy8gU2lsZW5jaW5nIGFnYWluc3QgaHR0cHM6Ly9idWdzLnBocC5uZXQvNjkyNDAKICAgICAgICAgICAgICAgIGlmIChAaXNfZGlyKCRwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICRkaXJzW10gPSAkcGF0aDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2VuYW1lKCRwYXRoKSA9PSAkbmFtZSAmJiBAaXNfZXhlY3V0YWJsZSgkcGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRwYXRoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRkaXJzID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICBleHBsb2RlKFxQQVRIX1NFUEFSQVRPUiwgZ2V0ZW52KCdQQVRIJykgPzogZ2V0ZW52KCdQYXRoJykpLAogICAgICAgICAgICAgICAgJGV4dHJhRGlycwogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJHN1ZmZpeGVzID0gWycnXTsKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgJHBhdGhFeHQgPSBnZXRlbnYoJ1BBVEhFWFQnKTsKICAgICAgICAgICAgJHN1ZmZpeGVzID0gYXJyYXlfbWVyZ2UoJHBhdGhFeHQgPyBleHBsb2RlKFxQQVRIX1NFUEFSQVRPUiwgJHBhdGhFeHQpIDogJHRoaXMtPnN1ZmZpeGVzLCAkc3VmZml4ZXMpOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkc3VmZml4ZXMgYXMgJHN1ZmZpeCkgewogICAgICAgICAgICBmb3JlYWNoICgkZGlycyBhcyAkZGlyKSB7CiAgICAgICAgICAgICAgICBpZiAoQGlzX2ZpbGUoJGZpbGUgPSAkZGlyLlxESVJFQ1RPUllfU0VQQVJBVE9SLiRuYW1lLiRzdWZmaXgpICYmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUiB8fCBAaXNfZXhlY3V0YWJsZSgkZmlsZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmaWxlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvbjsKCi8qKgogKiBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gZm9yIHRoZSBQcm9jZXNzIENvbXBvbmVudC4KICoKICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICovCmNsYXNzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBleHRlbmRzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb247CgovKioKICogTG9naWNFeGNlcHRpb24gZm9yIHRoZSBQcm9jZXNzIENvbXBvbmVudC4KICoKICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICovCmNsYXNzIExvZ2ljRXhjZXB0aW9uIGV4dGVuZHMgXExvZ2ljRXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uOwoKLyoqCiAqIFJ1bnRpbWVFeGNlcHRpb24gZm9yIHRoZSBQcm9jZXNzIENvbXBvbmVudC4KICoKICogQGF1dGhvciBKb2hhbm5lcyBNLiBTY2htaXR0IDxzY2htaXR0am9oQGdtYWlsLmNvbT4KICovCmNsYXNzIFJ1bnRpbWVFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvbjsKCi8qKgogKiBNYXJrZXIgSW50ZXJmYWNlIGZvciB0aGUgUHJvY2VzcyBDb21wb25lbnQuCiAqCiAqIEBhdXRob3IgSm9oYW5uZXMgTS4gU2NobWl0dCA8c2NobWl0dGpvaEBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBFeGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhIHByb2Nlc3MgdGltZXMgb3V0LgogKgogKiBAYXV0aG9yIEpvaGFubmVzIE0uIFNjaG1pdHQgPHNjaG1pdHRqb2hAZ21haWwuY29tPgogKi8KY2xhc3MgUHJvY2Vzc1RpbWVkT3V0RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7CiAgICBjb25zdCBUWVBFX0dFTkVSQUwgPSAxOwogICAgY29uc3QgVFlQRV9JRExFID0gMjsKCiAgICBwcml2YXRlICRwcm9jZXNzOwogICAgcHJpdmF0ZSAkdGltZW91dFR5cGU7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFByb2Nlc3MgJHByb2Nlc3MsICR0aW1lb3V0VHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvY2VzcyA9ICRwcm9jZXNzOwogICAgICAgICR0aGlzLT50aW1lb3V0VHlwZSA9ICR0aW1lb3V0VHlwZTsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKAogICAgICAgICAgICAnVGhlIHByb2Nlc3MgIiVzIiBleGNlZWRlZCB0aGUgdGltZW91dCBvZiAlcyBzZWNvbmRzLicsCiAgICAgICAgICAgICRwcm9jZXNzLT5nZXRDb21tYW5kTGluZSgpLAogICAgICAgICAgICAkdGhpcy0+Z2V0RXhjZWVkZWRUaW1lb3V0KCkKICAgICAgICApKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvY2VzcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0dlbmVyYWxUaW1lb3V0KCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VFlQRV9HRU5FUkFMID09PSAkdGhpcy0+dGltZW91dFR5cGU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzSWRsZVRpbWVvdXQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpUWVBFX0lETEUgPT09ICR0aGlzLT50aW1lb3V0VHlwZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhjZWVkZWRUaW1lb3V0KCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCR0aGlzLT50aW1lb3V0VHlwZSkgewogICAgICAgICAgICBjYXNlIHNlbGY6OlRZUEVfR0VORVJBTDoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cHJvY2Vzcy0+Z2V0VGltZW91dCgpOwoKICAgICAgICAgICAgY2FzZSBzZWxmOjpUWVBFX0lETEU6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnByb2Nlc3MtPmdldElkbGVUaW1lb3V0KCk7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdVbmtub3duIHRpbWVvdXQgdHlwZSAiJWQiLicsICR0aGlzLT50aW1lb3V0VHlwZSkpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBFeGNlcHRpb24gZm9yIGZhaWxlZCBwcm9jZXNzZXMuCiAqCiAqIEBhdXRob3IgSm9oYW5uZXMgTS4gU2NobWl0dCA8c2NobWl0dGpvaEBnbWFpbC5jb20+CiAqLwpjbGFzcyBQcm9jZXNzRmFpbGVkRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7CiAgICBwcml2YXRlICRwcm9jZXNzOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQcm9jZXNzICRwcm9jZXNzKQogICAgewogICAgICAgIGlmICgkcHJvY2Vzcy0+aXNTdWNjZXNzZnVsKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignRXhwZWN0ZWQgYSBmYWlsZWQgcHJvY2VzcywgYnV0IHRoZSBnaXZlbiBwcm9jZXNzIHdhcyBzdWNjZXNzZnVsLicpOwogICAgICAgIH0KCiAgICAgICAgJGVycm9yID0gc3ByaW50ZignVGhlIGNvbW1hbmQgIiVzIiBmYWlsZWQuJy4iXG5cbkV4aXQgQ29kZTogJXMoJXMpXG5cbldvcmtpbmcgZGlyZWN0b3J5OiAlcyIsCiAgICAgICAgICAgICRwcm9jZXNzLT5nZXRDb21tYW5kTGluZSgpLAogICAgICAgICAgICAkcHJvY2Vzcy0+Z2V0RXhpdENvZGUoKSwKICAgICAgICAgICAgJHByb2Nlc3MtPmdldEV4aXRDb2RlVGV4dCgpLAogICAgICAgICAgICAkcHJvY2Vzcy0+Z2V0V29ya2luZ0RpcmVjdG9yeSgpCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCEkcHJvY2Vzcy0+aXNPdXRwdXREaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICRlcnJvciAuPSBzcHJpbnRmKCJcblxuT3V0cHV0OlxuPT09PT09PT09PT09PT09PVxuJXNcblxuRXJyb3IgT3V0cHV0OlxuPT09PT09PT09PT09PT09PVxuJXMiLAogICAgICAgICAgICAgICAgJHByb2Nlc3MtPmdldE91dHB1dCgpLAogICAgICAgICAgICAgICAgJHByb2Nlc3MtPmdldEVycm9yT3V0cHV0KCkKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGVycm9yKTsKCiAgICAgICAgJHRoaXMtPnByb2Nlc3MgPSAkcHJvY2VzczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvY2VzcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9jZXNzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2VzczsKCkB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAlcyBjbGFzcyBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy40IGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgdGhlIFByb2Nlc3MgY2xhc3MgaW5zdGVhZC4nLCBQcm9jZXNzQnVpbGRlcjo6Y2xhc3MpLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgS3JpcyBXYWxsc21pdGggPGtyaXNAc3ltZm9ueS5jb20+CiAqCiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy40LCB0byBiZSByZW1vdmVkIGluIDQuMC4gVXNlIHRoZSBQcm9jZXNzIGNsYXNzIGluc3RlYWQuCiAqLwpjbGFzcyBQcm9jZXNzQnVpbGRlcgp7CiAgICBwcml2YXRlICRhcmd1bWVudHM7CiAgICBwcml2YXRlICRjd2Q7CiAgICBwcml2YXRlICRlbnYgPSBbXTsKICAgIHByaXZhdGUgJGlucHV0OwogICAgcHJpdmF0ZSAkdGltZW91dCA9IDYwOwogICAgcHJpdmF0ZSAkb3B0aW9uczsKICAgIHByaXZhdGUgJGluaGVyaXRFbnYgPSB0cnVlOwogICAgcHJpdmF0ZSAkcHJlZml4ID0gW107CiAgICBwcml2YXRlICRvdXRwdXREaXNhYmxlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ1tdICRhcmd1bWVudHMgQW4gYXJyYXkgb2YgYXJndW1lbnRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkYXJndW1lbnRzID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50cyA9ICRhcmd1bWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgcHJvY2VzcyBidWlsZGVyIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkYXJndW1lbnRzIEFuIGFycmF5IG9mIGFyZ3VtZW50cwogICAgICoKICAgICAqIEByZXR1cm4gc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKGFycmF5ICRhcmd1bWVudHMgPSBbXSkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYW4gdW5lc2NhcGVkIGFyZ3VtZW50IHRvIHRoZSBjb21tYW5kIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudCBBIGNvbW1hbmQgYXJndW1lbnQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGQoJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudHNbXSA9ICRhcmd1bWVudDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHByZWZpeCB0byB0aGUgY29tbWFuZCBzdHJpbmcuCiAgICAgKgogICAgICogVGhlIHByZWZpeCBpcyBwcmVzZXJ2ZWQgd2hlbiByZXNldHRpbmcgYXJndW1lbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJHByZWZpeCBBIGNvbW1hbmQgcHJlZml4IG9yIGFuIGFycmF5IG9mIGNvbW1hbmQgcHJlZml4ZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcmVmaXgoJHByZWZpeCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJlZml4ID0gXGlzX2FycmF5KCRwcmVmaXgpID8gJHByZWZpeCA6IFskcHJlZml4XTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXJndW1lbnRzIG9mIHRoZSBwcm9jZXNzLgogICAgICoKICAgICAqIEFyZ3VtZW50cyBtdXN0IG5vdCBiZSBlc2NhcGVkLgogICAgICogUHJldmlvdXMgYXJndW1lbnRzIGFyZSByZW1vdmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmdbXSAkYXJndW1lbnRzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnRzKGFycmF5ICRhcmd1bWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50cyA9ICRhcmd1bWVudHM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY3dkIFRoZSB3b3JraW5nIGRpcmVjdG9yeQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFdvcmtpbmdEaXJlY3RvcnkoJGN3ZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y3dkID0gJGN3ZDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIGVudmlyb25tZW50IHZhcmlhYmxlcyB3aWxsIGJlIGluaGVyaXRlZCBvciBub3QuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGluaGVyaXRFbnYKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmhlcml0RW52aXJvbm1lbnRWYXJpYWJsZXMoJGluaGVyaXRFbnYgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5pbmhlcml0RW52ID0gJGluaGVyaXRFbnY7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuCiAgICAgKgogICAgICogU2V0dGluZyBhIHZhcmlhYmxlIG92ZXJyaWRlcyBpdHMgcHJldmlvdXMgdmFsdWUuIFVzZSBgbnVsbGAgdG8gdW5zZXQgYQogICAgICogZGVmaW5lZCBlbnZpcm9ubWVudCB2YXJpYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJG5hbWUgIFRoZSB2YXJpYWJsZSBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJHZhbHVlIFRoZSB2YXJpYWJsZSB2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVudigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT5lbnZbJG5hbWVdID0gJHZhbHVlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgc2V0IG9mIGVudmlyb25tZW50IHZhcmlhYmxlcy4KICAgICAqCiAgICAgKiBBbHJlYWR5IGV4aXN0aW5nIGVudmlyb25tZW50IHZhcmlhYmxlcyB3aXRoIHRoZSBzYW1lIG5hbWUgd2lsbCBiZQogICAgICogb3ZlcnJpZGRlbiBieSB0aGUgbmV3IHZhbHVlcyBwYXNzZWQgdG8gdGhpcyBtZXRob2QuIFBhc3MgYG51bGxgIHRvIHVuc2V0CiAgICAgKiBhIHZhcmlhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdmFyaWFibGVzIFRoZSB2YXJpYWJsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFbnZpcm9ubWVudFZhcmlhYmxlcyhhcnJheSAkdmFyaWFibGVzKQogICAgewogICAgICAgICR0aGlzLT5lbnYgPSBhcnJheV9yZXBsYWNlKCR0aGlzLT5lbnYsICR2YXJpYWJsZXMpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbnB1dCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8c3RyaW5nfGludHxmbG9hdHxib29sfFxUcmF2ZXJzYWJsZXxudWxsICRpbnB1dCBUaGUgaW5wdXQgY29udGVudAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJbiBjYXNlIHRoZSBhcmd1bWVudCBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnB1dCgkaW5wdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gUHJvY2Vzc1V0aWxzOjp2YWxpZGF0ZUlucHV0KF9fTUVUSE9EX18sICRpbnB1dCk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2Nlc3MgdGltZW91dC4KICAgICAqCiAgICAgKiBUbyBkaXNhYmxlIHRoZSB0aW1lb3V0LCBzZXQgdGhpcyB2YWx1ZSB0byBudWxsLgogICAgICoKICAgICAqIEBwYXJhbSBmbG9hdHxudWxsICR0aW1lb3V0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUaW1lb3V0KCR0aW1lb3V0KQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGltZW91dCkgewogICAgICAgICAgICAkdGhpcy0+dGltZW91dCA9IG51bGw7CgogICAgICAgICAgICByZXR1cm4gJHRoaXM7CiAgICAgICAgfQoKICAgICAgICAkdGltZW91dCA9IChmbG9hdCkgJHRpbWVvdXQ7CgogICAgICAgIGlmICgkdGltZW91dCA8IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIHRpbWVvdXQgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIHBvc2l0aXZlIGludGVnZXIgb3IgZmxvYXQgbnVtYmVyLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnRpbWVvdXQgPSAkdGltZW91dDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIHByb2Nfb3BlbiBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSAgVGhlIG9wdGlvbiBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZSBUaGUgb3B0aW9uIHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG5hbWVdID0gJHZhbHVlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNhYmxlcyBmZXRjaGluZyBvdXRwdXQgYW5kIGVycm9yIG91dHB1dCBmcm9tIHRoZSB1bmRlcmx5aW5nIHByb2Nlc3MuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZU91dHB1dCgpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dERpc2FibGVkID0gdHJ1ZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRW5hYmxlcyBmZXRjaGluZyBvdXRwdXQgYW5kIGVycm9yIG91dHB1dCBmcm9tIHRoZSB1bmRlcmx5aW5nIHByb2Nlc3MuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlT3V0cHV0KCkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0RGlzYWJsZWQgPSBmYWxzZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIFByb2Nlc3MgaW5zdGFuY2UgYW5kIHJldHVybnMgaXQuCiAgICAgKgogICAgICogQHJldHVybiBQcm9jZXNzCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIG5vIGFyZ3VtZW50cyBoYXZlIGJlZW4gcHJvdmlkZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb2Nlc3MoKQogICAgewogICAgICAgIGlmICgwID09PSBcY291bnQoJHRoaXMtPnByZWZpeCkgJiYgMCA9PT0gXGNvdW50KCR0aGlzLT5hcmd1bWVudHMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignWW91IG11c3QgYWRkKCkgY29tbWFuZCBhcmd1bWVudHMgYmVmb3JlIGNhbGxpbmcgZ2V0UHJvY2VzcygpLicpOwogICAgICAgIH0KCiAgICAgICAgJGFyZ3VtZW50cyA9IGFycmF5X21lcmdlKCR0aGlzLT5wcmVmaXgsICR0aGlzLT5hcmd1bWVudHMpOwogICAgICAgICRwcm9jZXNzID0gbmV3IFByb2Nlc3MoJGFyZ3VtZW50cywgJHRoaXMtPmN3ZCwgJHRoaXMtPmVudiwgJHRoaXMtPmlucHV0LCAkdGhpcy0+dGltZW91dCwgJHRoaXMtPm9wdGlvbnMpOwogICAgICAgIC8vIHRvIHByZXNlcnZlIHRoZSBCQyB3aXRoIHN5bWZvbnkgPDMuMywgd2UgY29udmVydCB0aGUgYXJyYXkgc3RydWN0dXJlCiAgICAgICAgLy8gdG8gYSBzdHJpbmcgc3RydWN0dXJlIHRvIGF2b2lkIHRoZSBwcmVmaXhpbmcgd2l0aCB0aGUgZXhlYyBjb21tYW5kCiAgICAgICAgJHByb2Nlc3MtPnNldENvbW1hbmRMaW5lKCRwcm9jZXNzLT5nZXRDb21tYW5kTGluZSgpKTsKCiAgICAgICAgaWYgKCR0aGlzLT5pbmhlcml0RW52KSB7CiAgICAgICAgICAgICRwcm9jZXNzLT5pbmhlcml0RW52aXJvbm1lbnRWYXJpYWJsZXMoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXREaXNhYmxlZCkgewogICAgICAgICAgICAkcHJvY2Vzcy0+ZGlzYWJsZU91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcm9jZXNzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2VzczsKCnVzZSBTeW1mb255XENvbXBvbmVudFxQcm9jZXNzXEV4Y2VwdGlvblxSdW50aW1lRXhjZXB0aW9uOwoKLyoqCiAqIFBocFByb2Nlc3MgcnVucyBhIFBIUCBzY3JpcHQgaW4gYW4gaW5kZXBlbmRlbnQgcHJvY2Vzcy4KICoKICogICAgICRwID0gbmV3IFBocFByb2Nlc3MoJzw/cGhwIGVjaG8gImZvbyI7ID8+Jyk7CiAqICAgICAkcC0+cnVuKCk7CiAqICAgICBwcmludCAkcC0+Z2V0T3V0cHV0KCkuIlxuIjsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBQaHBQcm9jZXNzIGV4dGVuZHMgUHJvY2Vzcwp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkc2NyaXB0ICBUaGUgUEhQIHNjcmlwdCB0byBydW4gKGFzIGEgc3RyaW5nKQogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRjd2QgICAgIFRoZSB3b3JraW5nIGRpcmVjdG9yeSBvciBudWxsIHRvIHVzZSB0aGUgd29ya2luZyBkaXIgb2YgdGhlIGN1cnJlbnQgUEhQIHByb2Nlc3MKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICAkZW52ICAgICBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIG9yIG51bGwgdG8gdXNlIHRoZSBzYW1lIGVudmlyb25tZW50IGFzIHRoZSBjdXJyZW50IFBIUCBwcm9jZXNzCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgJHRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gc2Vjb25kcwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICRvcHRpb25zIEFuIGFycmF5IG9mIG9wdGlvbnMgZm9yIHByb2Nfb3BlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNjcmlwdCwgJGN3ZCA9IG51bGwsIGFycmF5ICRlbnYgPSBudWxsLCAkdGltZW91dCA9IDYwLCBhcnJheSAkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgJGV4ZWN1dGFibGVGaW5kZXIgPSBuZXcgUGhwRXhlY3V0YWJsZUZpbmRlcigpOwogICAgICAgIGlmIChmYWxzZSA9PT0gJHBocCA9ICRleGVjdXRhYmxlRmluZGVyLT5maW5kKGZhbHNlKSkgewogICAgICAgICAgICAkcGhwID0gbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGhwID0gYXJyYXlfbWVyZ2UoWyRwaHBdLCAkZXhlY3V0YWJsZUZpbmRlci0+ZmluZEFyZ3VtZW50cygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCdwaHBkYmcnID09PSBcUEhQX1NBUEkpIHsKICAgICAgICAgICAgJGZpbGUgPSB0ZW1wbmFtKHN5c19nZXRfdGVtcF9kaXIoKSwgJ2RiZycpOwogICAgICAgICAgICBmaWxlX3B1dF9jb250ZW50cygkZmlsZSwgJHNjcmlwdCk7CiAgICAgICAgICAgIHJlZ2lzdGVyX3NodXRkb3duX2Z1bmN0aW9uKCd1bmxpbmsnLCAkZmlsZSk7CiAgICAgICAgICAgICRwaHBbXSA9ICRmaWxlOwogICAgICAgICAgICAkc2NyaXB0ID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKG51bGwgIT09ICRvcHRpb25zKSB7CiAgICAgICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAkb3B0aW9ucyBwYXJhbWV0ZXIgb2YgdGhlICVzIGNvbnN0cnVjdG9yIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuJywgX19DTEFTU19fKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHBocCwgJGN3ZCwgJGVudiwgJHNjcmlwdCwgJHRpbWVvdXQsICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHBhdGggdG8gdGhlIFBIUCBiaW5hcnkgdG8gdXNlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGhwQmluYXJ5KCRwaHApCiAgICB7CiAgICAgICAgJHRoaXMtPnNldENvbW1hbmRMaW5lKCRwaHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RhcnQoY2FsbGFibGUgJGNhbGxiYWNrID0gbnVsbC8qLCBhcnJheSAkZW52ID0gW10qLykKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmdldENvbW1hbmRMaW5lKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1VuYWJsZSB0byBmaW5kIHRoZSBQSFAgZXhlY3V0YWJsZS4nKTsKICAgICAgICB9CiAgICAgICAgJGVudiA9IDEgPCBcZnVuY19udW1fYXJncygpID8gZnVuY19nZXRfYXJnKDEpIDogbnVsbDsKCiAgICAgICAgcGFyZW50OjpzdGFydCgkY2FsbGJhY2ssICRlbnYpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgp1c2UgU3ltZm9ueVxQb2x5ZmlsbFxDdHlwZSBhcyBwOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX2FsbnVtJykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX2FsbnVtKCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfYWxudW0oJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9hbHBoYScpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9hbHBoYSgkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX2FscGhhKCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfY250cmwnKSkgewogICAgZnVuY3Rpb24gY3R5cGVfY250cmwoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9jbnRybCgkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX2RpZ2l0JykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX2RpZ2l0KCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfZGlnaXQoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9ncmFwaCcpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9ncmFwaCgkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX2dyYXBoKCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfbG93ZXInKSkgewogICAgZnVuY3Rpb24gY3R5cGVfbG93ZXIoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9sb3dlcigkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX3ByaW50JykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX3ByaW50KCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfcHJpbnQoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV9wdW5jdCcpKSB7CiAgICBmdW5jdGlvbiBjdHlwZV9wdW5jdCgkaW5wdXQpIHsgcmV0dXJuIHBcQ3R5cGU6OmN0eXBlX3B1bmN0KCRpbnB1dCk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfc3BhY2UnKSkgewogICAgZnVuY3Rpb24gY3R5cGVfc3BhY2UoJGlucHV0KSB7IHJldHVybiBwXEN0eXBlOjpjdHlwZV9zcGFjZSgkaW5wdXQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX3VwcGVyJykpIHsKICAgIGZ1bmN0aW9uIGN0eXBlX3VwcGVyKCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfdXBwZXIoJGlucHV0KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdjdHlwZV94ZGlnaXQnKSkgewogICAgZnVuY3Rpb24gY3R5cGVfeGRpZ2l0KCRpbnB1dCkgeyByZXR1cm4gcFxDdHlwZTo6Y3R5cGVfeGRpZ2l0KCRpbnB1dCk7IH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcUG9seWZpbGxcQ3R5cGU7CgovKioKICogQ3R5cGUgaW1wbGVtZW50YXRpb24gdGhyb3VnaCByZWdleC4KICoKICogQGludGVybmFsCiAqCiAqIEBhdXRob3IgR2VydCBkZSBQYWd0ZXIgPEJhY2tFbmRUZWFAZ21haWwuY29tPgogKi8KZmluYWwgY2xhc3MgQ3R5cGUKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgaXMgZWl0aGVyIGEgbGV0dGVyIG9yIGEgZGlnaXQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1hbG51bQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfYWxudW0oJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXkEtWmEtejAtOV0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IGlzIGEgbGV0dGVyLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtYWxwaGEKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX2FscGhhKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15BLVphLXpdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyIGZyb20gdGhlIGN1cnJlbnQgbG9jYWxlLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtY250cmwKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX2NudHJsKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15ceDAwLVx4MWZceDdmXS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgdGV4dCBpcyBhIGRlY2ltYWwgZGlnaXQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vcGhwLm5ldC9jdHlwZS1kaWdpdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfZGlnaXQoJHRleHQpCiAgICB7CiAgICAgICAgJHRleHQgPSBzZWxmOjpjb252ZXJ0X2ludF90b19jaGFyX2Zvcl9jdHlwZSgkdGV4dCk7CgogICAgICAgIHJldHVybiBcaXNfc3RyaW5nKCR0ZXh0KSAmJiAnJyAhPT0gJHRleHQgJiYgIXByZWdfbWF0Y2goJy9bXjAtOV0vJywgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBUUlVFIGlmIGV2ZXJ5IGNoYXJhY3RlciBpbiB0ZXh0IGlzIHByaW50YWJsZSBhbmQgYWN0dWFsbHkgY3JlYXRlcyB2aXNpYmxlIG91dHB1dCAobm8gd2hpdGUgc3BhY2UpLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtZ3JhcGgKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX2dyYXBoKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW14hLX5dLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBhIGxvd2VyY2FzZSBsZXR0ZXIuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtbG93ZXIKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX2xvd2VyKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15hLXpdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCB3aWxsIGFjdHVhbGx5IGNyZWF0ZSBvdXRwdXQgKGluY2x1ZGluZyBibGFua3MpLiBSZXR1cm5zIEZBTFNFIGlmIHRleHQgY29udGFpbnMgY29udHJvbCBjaGFyYWN0ZXJzIG9yIGNoYXJhY3RlcnMgdGhhdCBkbyBub3QgaGF2ZSBhbnkgb3V0cHV0IG9yIGNvbnRyb2wgZnVuY3Rpb24gYXQgYWxsLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLXByaW50CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV9wcmludCgkdGV4dCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNlbGY6OmNvbnZlcnRfaW50X3RvX2NoYXJfZm9yX2N0eXBlKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRleHQpICYmICcnICE9PSAkdGV4dCAmJiAhcHJlZ19tYXRjaCgnL1teIC1+XS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgaXMgcHJpbnRhYmxlLCBidXQgbmVpdGhlciBsZXR0ZXIsIGRpZ2l0IG9yIGJsYW5rLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3BocC5uZXQvY3R5cGUtcHVuY3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGN0eXBlX3B1bmN0KCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW14hLVwvXDotQFxbLWBcey1+XS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgY3JlYXRlcyBzb21lIHNvcnQgb2Ygd2hpdGUgc3BhY2UsIEZBTFNFIG90aGVyd2lzZS4gQmVzaWRlcyB0aGUgYmxhbmsgY2hhcmFjdGVyIHRoaXMgYWxzbyBpbmNsdWRlcyB0YWIsIHZlcnRpY2FsIHRhYiwgbGluZSBmZWVkLCBjYXJyaWFnZSByZXR1cm4gYW5kIGZvcm0gZmVlZCBjaGFyYWN0ZXJzLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLXNwYWNlCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV9zcGFjZSgkdGV4dCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNlbGY6OmNvbnZlcnRfaW50X3RvX2NoYXJfZm9yX2N0eXBlKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRleHQpICYmICcnICE9PSAkdGV4dCAmJiAhcHJlZ19tYXRjaCgnL1teXHNdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgVFJVRSBpZiBldmVyeSBjaGFyYWN0ZXIgaW4gdGV4dCBpcyBhbiB1cHBlcmNhc2UgbGV0dGVyLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLXVwcGVyCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJHRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjdHlwZV91cHBlcigkdGV4dCkKICAgIHsKICAgICAgICAkdGV4dCA9IHNlbGY6OmNvbnZlcnRfaW50X3RvX2NoYXJfZm9yX2N0eXBlKCR0ZXh0KTsKCiAgICAgICAgcmV0dXJuIFxpc19zdHJpbmcoJHRleHQpICYmICcnICE9PSAkdGV4dCAmJiAhcHJlZ19tYXRjaCgnL1teQS1aXS8nLCAkdGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIFRSVUUgaWYgZXZlcnkgY2hhcmFjdGVyIGluIHRleHQgaXMgYSBoZXhhZGVjaW1hbCAnZGlnaXQnLCB0aGF0IGlzIGEgZGVjaW1hbCBkaWdpdCBvciBhIGNoYXJhY3RlciBmcm9tIFtBLUZhLWZdICwgRkFMU0Ugb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBzZWUgaHR0cHM6Ly9waHAubmV0L2N0eXBlLXhkaWdpdAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICR0ZXh0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3R5cGVfeGRpZ2l0KCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gc2VsZjo6Y29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJHRleHQpOwoKICAgICAgICByZXR1cm4gXGlzX3N0cmluZygkdGV4dCkgJiYgJycgIT09ICR0ZXh0ICYmICFwcmVnX21hdGNoKCcvW15BLUZhLWYwLTldLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIGludGVnZXJzIHRvIHRoZWlyIGNoYXIgdmVyc2lvbnMgYWNjb3JkaW5nIHRvIG5vcm1hbCBjdHlwZSBiZWhhdmlvdXIsIGlmIG5lZWRlZC4KICAgICAqCiAgICAgKiBJZiBhbiBpbnRlZ2VyIGJldHdlZW4gLTEyOCBhbmQgMjU1IGluY2x1c2l2ZSBpcyBwcm92aWRlZCwKICAgICAqIGl0IGlzIGludGVycHJldGVkIGFzIHRoZSBBU0NJSSB2YWx1ZSBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIKICAgICAqIChuZWdhdGl2ZSB2YWx1ZXMgaGF2ZSAyNTYgYWRkZWQgaW4gb3JkZXIgdG8gYWxsb3cgY2hhcmFjdGVycyBpbiB0aGUgRXh0ZW5kZWQgQVNDSUkgcmFuZ2UpLgogICAgICogQW55IG90aGVyIGludGVnZXIgaXMgaW50ZXJwcmV0ZWQgYXMgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZGVjaW1hbCBkaWdpdHMgb2YgdGhlIGludGVnZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJGludAogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY29udmVydF9pbnRfdG9fY2hhcl9mb3JfY3R5cGUoJGludCkKICAgIHsKICAgICAgICBpZiAoIVxpc19pbnQoJGludCkpIHsKICAgICAgICAgICAgcmV0dXJuICRpbnQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGludCA8IC0xMjggfHwgJGludCA+IDI1NSkgewogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJGludDsKICAgICAgICB9CgogICAgICAgIGlmICgkaW50IDwgMCkgewogICAgICAgICAgICAkaW50ICs9IDI1NjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcY2hyKCRpbnQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbTsKCnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxGaWxlTm90Rm91bmRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxGaWxlc3lzdGVtXEV4Y2VwdGlvblxJT0V4Y2VwdGlvbjsKCi8qKgogKiBQcm92aWRlcyBiYXNpYyB1dGlsaXR5IHRvIG1hbmlwdWxhdGUgdGhlIGZpbGUgc3lzdGVtLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEZpbGVzeXN0ZW0KewogICAgcHJpdmF0ZSBzdGF0aWMgJGxhc3RFcnJvcjsKCiAgICAvKioKICAgICAqIENvcGllcyBhIGZpbGUuCiAgICAgKgogICAgICogSWYgdGhlIHRhcmdldCBmaWxlIGlzIG9sZGVyIHRoYW4gdGhlIG9yaWdpbiBmaWxlLCBpdCdzIGFsd2F5cyBvdmVyd3JpdHRlbi4KICAgICAqIElmIHRoZSB0YXJnZXQgZmlsZSBpcyBuZXdlciwgaXQgaXMgb3ZlcndyaXR0ZW4gb25seSB3aGVuIHRoZQogICAgICogJG92ZXJ3cml0ZU5ld2VyRmlsZXMgb3B0aW9uIGlzIHNldCB0byB0cnVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbkZpbGUgICAgICAgICAgVGhlIG9yaWdpbmFsIGZpbGVuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXRGaWxlICAgICAgICAgIFRoZSB0YXJnZXQgZmlsZW5hbWUKICAgICAqIEBwYXJhbSBib29sICAgJG92ZXJ3cml0ZU5ld2VyRmlsZXMgSWYgdHJ1ZSwgdGFyZ2V0IGZpbGVzIG5ld2VyIHRoYW4gb3JpZ2luIGZpbGVzIGFyZSBvdmVyd3JpdHRlbgogICAgICoKICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIFdoZW4gb3JpZ2luRmlsZSBkb2Vzbid0IGV4aXN0CiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICAgICAgICAgICBXaGVuIGNvcHkgZmFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvcHkoJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlLCAkb3ZlcndyaXRlTmV3ZXJGaWxlcyA9IGZhbHNlKQogICAgewogICAgICAgICRvcmlnaW5Jc0xvY2FsID0gc3RyZWFtX2lzX2xvY2FsKCRvcmlnaW5GaWxlKSB8fCAwID09PSBzdHJpcG9zKCRvcmlnaW5GaWxlLCAnZmlsZTovLycpOwogICAgICAgIGlmICgkb3JpZ2luSXNMb2NhbCAmJiAhaXNfZmlsZSgkb3JpZ2luRmlsZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY29weSAiJXMiIGJlY2F1c2UgZmlsZSBkb2VzIG5vdCBleGlzdC4nLCAkb3JpZ2luRmlsZSksIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5ta2RpcihcZGlybmFtZSgkdGFyZ2V0RmlsZSkpOwoKICAgICAgICAkZG9Db3B5ID0gdHJ1ZTsKICAgICAgICBpZiAoISRvdmVyd3JpdGVOZXdlckZpbGVzICYmIG51bGwgPT09IHBhcnNlX3VybCgkb3JpZ2luRmlsZSwgXFBIUF9VUkxfSE9TVCkgJiYgaXNfZmlsZSgkdGFyZ2V0RmlsZSkpIHsKICAgICAgICAgICAgJGRvQ29weSA9IGZpbGVtdGltZSgkb3JpZ2luRmlsZSkgPiBmaWxlbXRpbWUoJHRhcmdldEZpbGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRkb0NvcHkpIHsKICAgICAgICAgICAgLy8gaHR0cHM6Ly9idWdzLnBocC5uZXQvNjQ2MzQKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkc291cmNlID0gQGZvcGVuKCRvcmlnaW5GaWxlLCAncicpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNvcHkgIiVzIiB0byAiJXMiIGJlY2F1c2Ugc291cmNlIGZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBmb3IgcmVhZGluZy4nLCAkb3JpZ2luRmlsZSwgJHRhcmdldEZpbGUpLCAwLCBudWxsLCAkb3JpZ2luRmlsZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFN0cmVhbSBjb250ZXh0IGNyZWF0ZWQgdG8gYWxsb3cgZmlsZXMgb3ZlcndyaXRlIHdoZW4gdXNpbmcgRlRQIHN0cmVhbSB3cmFwcGVyIC0gZGlzYWJsZWQgYnkgZGVmYXVsdAogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICR0YXJnZXQgPSBAZm9wZW4oJHRhcmdldEZpbGUsICd3JywgbnVsbCwgc3RyZWFtX2NvbnRleHRfY3JlYXRlKFsnZnRwJyA9PiBbJ292ZXJ3cml0ZScgPT4gdHJ1ZV1dKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY29weSAiJXMiIHRvICIlcyIgYmVjYXVzZSB0YXJnZXQgZmlsZSBjb3VsZCBub3QgYmUgb3BlbmVkIGZvciB3cml0aW5nLicsICRvcmlnaW5GaWxlLCAkdGFyZ2V0RmlsZSksIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGJ5dGVzQ29waWVkID0gc3RyZWFtX2NvcHlfdG9fc3RyZWFtKCRzb3VyY2UsICR0YXJnZXQpOwogICAgICAgICAgICBmY2xvc2UoJHNvdXJjZSk7CiAgICAgICAgICAgIGZjbG9zZSgkdGFyZ2V0KTsKICAgICAgICAgICAgdW5zZXQoJHNvdXJjZSwgJHRhcmdldCk7CgogICAgICAgICAgICBpZiAoIWlzX2ZpbGUoJHRhcmdldEZpbGUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNvcHkgIiVzIiB0byAiJXMiLicsICRvcmlnaW5GaWxlLCAkdGFyZ2V0RmlsZSksIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRvcmlnaW5Jc0xvY2FsKSB7CiAgICAgICAgICAgICAgICAvLyBMaWtlIGBjcGAsIHByZXNlcnZlIGV4ZWN1dGFibGUgcGVybWlzc2lvbiBiaXRzCiAgICAgICAgICAgICAgICBAY2htb2QoJHRhcmdldEZpbGUsIGZpbGVwZXJtcygkdGFyZ2V0RmlsZSkgfCAoZmlsZXBlcm1zKCRvcmlnaW5GaWxlKSAmIDAxMTEpKTsKCiAgICAgICAgICAgICAgICBpZiAoJGJ5dGVzQ29waWVkICE9PSAkYnl0ZXNPcmlnaW4gPSBmaWxlc2l6ZSgkb3JpZ2luRmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNvcHkgdGhlIHdob2xlIGNvbnRlbnQgb2YgIiVzIiB0byAiJXMiICglZyBvZiAlZyBieXRlcyBjb3BpZWQpLicsICRvcmlnaW5GaWxlLCAkdGFyZ2V0RmlsZSwgJGJ5dGVzQ29waWVkLCAkYnl0ZXNPcmlnaW4pLCAwLCBudWxsLCAkb3JpZ2luRmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgZGlyZWN0b3J5IHJlY3Vyc2l2ZWx5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aXRlcmFibGUgJGRpcnMgVGhlIGRpcmVjdG9yeSBwYXRoCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRtb2RlIFRoZSBkaXJlY3RvcnkgbW9kZQogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gT24gYW55IGRpcmVjdG9yeSBjcmVhdGlvbiBmYWlsdXJlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBta2RpcigkZGlycywgJG1vZGUgPSAwNzc3KQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCRkaXJzKSBhcyAkZGlyKSB7CiAgICAgICAgICAgIGlmIChpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXNlbGY6OmJveCgnbWtkaXInLCAkZGlyLCAkbW9kZSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIGlmICghaXNfZGlyKCRkaXIpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGRpcmVjdG9yeSB3YXMgbm90IGNyZWF0ZWQgYnkgYSBjb25jdXJyZW50IHByb2Nlc3MuIExldCdzIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGEgZGV2ZWxvcGVyIGZyaWVuZGx5IGVycm9yIG1lc3NhZ2UgaWYgd2UgaGF2ZSBvbmUKICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZjo6JGxhc3RFcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNyZWF0ZSAiJXMiOiAnLCAkZGlyKS5zZWxmOjokbGFzdEVycm9yLCAwLCBudWxsLCAkZGlyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjcmVhdGUgIiVzIi4nLCAkZGlyKSwgMCwgbnVsbCwgJGRpcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhlIGV4aXN0ZW5jZSBvZiBmaWxlcyBvciBkaXJlY3Rvcmllcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGl0ZXJhYmxlICRmaWxlcyBBIGZpbGVuYW1lLCBhbiBhcnJheSBvZiBmaWxlcywgb3IgYSBcVHJhdmVyc2FibGUgaW5zdGFuY2UgdG8gY2hlY2sKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgZmlsZSBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhpc3RzKCRmaWxlcykKICAgIHsKICAgICAgICAkbWF4UGF0aExlbmd0aCA9IFxQSFBfTUFYUEFUSExFTiAtIDI7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCRmaWxlcykgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKFxzdHJsZW4oJGZpbGUpID4gJG1heFBhdGhMZW5ndGgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdDb3VsZCBub3QgY2hlY2sgaWYgZmlsZSBleGlzdCBiZWNhdXNlIHBhdGggbGVuZ3RoIGV4Y2VlZHMgJWQgY2hhcmFjdGVycy4nLCAkbWF4UGF0aExlbmd0aCksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkZmlsZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGFjY2VzcyBhbmQgbW9kaWZpY2F0aW9uIHRpbWUgb2YgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGl0ZXJhYmxlICRmaWxlcyBBIGZpbGVuYW1lLCBhbiBhcnJheSBvZiBmaWxlcywgb3IgYSBcVHJhdmVyc2FibGUgaW5zdGFuY2UgdG8gY3JlYXRlCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICR0aW1lICBUaGUgdG91Y2ggdGltZSBhcyBhIFVuaXggdGltZXN0YW1wLCBpZiBub3Qgc3VwcGxpZWQgdGhlIGN1cnJlbnQgc3lzdGVtIHRpbWUgaXMgdXNlZAogICAgICogQHBhcmFtIGludHxudWxsICAgICAgICAkYXRpbWUgVGhlIGFjY2VzcyB0aW1lIGFzIGEgVW5peCB0aW1lc3RhbXAsIGlmIG5vdCBzdXBwbGllZCB0aGUgY3VycmVudCBzeXN0ZW0gdGltZSBpcyB1c2VkCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHRvdWNoIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0b3VjaCgkZmlsZXMsICR0aW1lID0gbnVsbCwgJGF0aW1lID0gbnVsbCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dG9JdGVyYWJsZSgkZmlsZXMpIGFzICRmaWxlKSB7CiAgICAgICAgICAgICR0b3VjaCA9ICR0aW1lID8gQHRvdWNoKCRmaWxlLCAkdGltZSwgJGF0aW1lKSA6IEB0b3VjaCgkZmlsZSk7CiAgICAgICAgICAgIGlmICh0cnVlICE9PSAkdG91Y2gpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gdG91Y2ggIiVzIi4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgZmlsZXMgb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpdGVyYWJsZSAkZmlsZXMgQSBmaWxlbmFtZSwgYW4gYXJyYXkgb2YgZmlsZXMsIG9yIGEgXFRyYXZlcnNhYmxlIGluc3RhbmNlIHRvIHJlbW92ZQogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiByZW1vdmFsIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmUoJGZpbGVzKQogICAgewogICAgICAgIGlmICgkZmlsZXMgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgJGZpbGVzID0gaXRlcmF0b3JfdG9fYXJyYXkoJGZpbGVzLCBmYWxzZSk7CiAgICAgICAgfSBlbHNlaWYgKCFcaXNfYXJyYXkoJGZpbGVzKSkgewogICAgICAgICAgICAkZmlsZXMgPSBbJGZpbGVzXTsKICAgICAgICB9CiAgICAgICAgJGZpbGVzID0gYXJyYXlfcmV2ZXJzZSgkZmlsZXMpOwogICAgICAgIGZvcmVhY2ggKCRmaWxlcyBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoaXNfbGluaygkZmlsZSkpIHsKICAgICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2J1Z3MucGhwLm5ldC81MjE3NgogICAgICAgICAgICAgICAgaWYgKCEoc2VsZjo6Ym94KCd1bmxpbmsnLCAkZmlsZSkgfHwgJ1xcJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgfHwgc2VsZjo6Ym94KCdybWRpcicsICRmaWxlKSkgJiYgZmlsZV9leGlzdHMoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byByZW1vdmUgc3ltbGluayAiJXMiOiAnLCAkZmlsZSkuc2VsZjo6JGxhc3RFcnJvcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVtb3ZlKG5ldyBcRmlsZXN5c3RlbUl0ZXJhdG9yKCRmaWxlLCBcRmlsZXN5c3RlbUl0ZXJhdG9yOjpDVVJSRU5UX0FTX1BBVEhOQU1FIHwgXEZpbGVzeXN0ZW1JdGVyYXRvcjo6U0tJUF9ET1RTKSk7CgogICAgICAgICAgICAgICAgaWYgKCFzZWxmOjpib3goJ3JtZGlyJywgJGZpbGUpICYmIGZpbGVfZXhpc3RzKCRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gcmVtb3ZlIGRpcmVjdG9yeSAiJXMiOiAnLCAkZmlsZSkuc2VsZjo6JGxhc3RFcnJvcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICghc2VsZjo6Ym94KCd1bmxpbmsnLCAkZmlsZSkgJiYgKGZhbHNlICE9PSBzdHJwb3Moc2VsZjo6JGxhc3RFcnJvciwgJ1Blcm1pc3Npb24gZGVuaWVkJykgfHwgZmlsZV9leGlzdHMoJGZpbGUpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byByZW1vdmUgZmlsZSAiJXMiOiAnLCAkZmlsZSkuc2VsZjo6JGxhc3RFcnJvcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGFuZ2UgbW9kZSBmb3IgYW4gYXJyYXkgb2YgZmlsZXMgb3IgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpdGVyYWJsZSAkZmlsZXMgICAgIEEgZmlsZW5hbWUsIGFuIGFycmF5IG9mIGZpbGVzLCBvciBhIFxUcmF2ZXJzYWJsZSBpbnN0YW5jZSB0byBjaGFuZ2UgbW9kZQogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAkbW9kZSAgICAgIFRoZSBuZXcgbW9kZSAob2N0YWwpCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICR1bWFzayAgICAgVGhlIG1vZGUgbWFzayAob2N0YWwpCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRyZWN1cnNpdmUgV2hldGhlciBjaGFuZ2UgdGhlIG1vZCByZWN1cnNpdmVseSBvciBub3QKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gdGhlIGNoYW5nZSBmYWlscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2htb2QoJGZpbGVzLCAkbW9kZSwgJHVtYXNrID0gMDAwMCwgJHJlY3Vyc2l2ZSA9IGZhbHNlKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCRmaWxlcykgYXMgJGZpbGUpIHsKICAgICAgICAgICAgaWYgKChcUEhQX1ZFUlNJT05fSUQgPCA4MDAwMCB8fCBcaXNfaW50KCRtb2RlKSkgJiYgdHJ1ZSAhPT0gQGNobW9kKCRmaWxlLCAkbW9kZSAmIH4kdW1hc2spKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNobW9kIGZpbGUgIiVzIi4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHJlY3Vyc2l2ZSAmJiBpc19kaXIoJGZpbGUpICYmICFpc19saW5rKCRmaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNobW9kKG5ldyBcRmlsZXN5c3RlbUl0ZXJhdG9yKCRmaWxlKSwgJG1vZGUsICR1bWFzaywgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGFuZ2UgdGhlIG93bmVyIG9mIGFuIGFycmF5IG9mIGZpbGVzIG9yIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aXRlcmFibGUgJGZpbGVzICAgICBBIGZpbGVuYW1lLCBhbiBhcnJheSBvZiBmaWxlcywgb3IgYSBcVHJhdmVyc2FibGUgaW5zdGFuY2UgdG8gY2hhbmdlIG93bmVyCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAgICAgICR1c2VyICAgICAgQSB1c2VyIG5hbWUgb3IgbnVtYmVyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICRyZWN1cnNpdmUgV2hldGhlciBjaGFuZ2UgdGhlIG93bmVyIHJlY3Vyc2l2ZWx5IG9yIG5vdAogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiB0aGUgY2hhbmdlIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaG93bigkZmlsZXMsICR1c2VyLCAkcmVjdXJzaXZlID0gZmFsc2UpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvSXRlcmFibGUoJGZpbGVzKSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoJHJlY3Vyc2l2ZSAmJiBpc19kaXIoJGZpbGUpICYmICFpc19saW5rKCRmaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNob3duKG5ldyBcRmlsZXN5c3RlbUl0ZXJhdG9yKCRmaWxlKSwgJHVzZXIsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc19saW5rKCRmaWxlKSAmJiBcZnVuY3Rpb25fZXhpc3RzKCdsY2hvd24nKSkgewogICAgICAgICAgICAgICAgaWYgKHRydWUgIT09IEBsY2hvd24oJGZpbGUsICR1c2VyKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gY2hvd24gZmlsZSAiJXMiLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHRydWUgIT09IEBjaG93bigkZmlsZSwgJHVzZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjaG93biBmaWxlICIlcyIuJywgJGZpbGUpLCAwLCBudWxsLCAkZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGFuZ2UgdGhlIGdyb3VwIG9mIGFuIGFycmF5IG9mIGZpbGVzIG9yIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aXRlcmFibGUgJGZpbGVzICAgICBBIGZpbGVuYW1lLCBhbiBhcnJheSBvZiBmaWxlcywgb3IgYSBcVHJhdmVyc2FibGUgaW5zdGFuY2UgdG8gY2hhbmdlIGdyb3VwCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAgICAgICRncm91cCAgICAgQSBncm91cCBuYW1lIG9yIG51bWJlcgogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAkcmVjdXJzaXZlIFdoZXRoZXIgY2hhbmdlIHRoZSBncm91cCByZWN1cnNpdmVseSBvciBub3QKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gdGhlIGNoYW5nZSBmYWlscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hncnAoJGZpbGVzLCAkZ3JvdXAsICRyZWN1cnNpdmUgPSBmYWxzZSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+dG9JdGVyYWJsZSgkZmlsZXMpIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmICgkcmVjdXJzaXZlICYmIGlzX2RpcigkZmlsZSkgJiYgIWlzX2xpbmsoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hncnAobmV3IFxGaWxlc3lzdGVtSXRlcmF0b3IoJGZpbGUpLCAkZ3JvdXAsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc19saW5rKCRmaWxlKSAmJiBcZnVuY3Rpb25fZXhpc3RzKCdsY2hncnAnKSkgewogICAgICAgICAgICAgICAgaWYgKHRydWUgIT09IEBsY2hncnAoJGZpbGUsICRncm91cCkgfHwgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSAmJiAhcG9zaXhfZ2V0Z3JuYW0oJGdyb3VwKSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNoZ3JwIGZpbGUgIiVzIi4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh0cnVlICE9PSBAY2hncnAoJGZpbGUsICRncm91cCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIGNoZ3JwIGZpbGUgIiVzIi4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbmFtZXMgYSBmaWxlIG9yIGEgZGlyZWN0b3J5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbiAgICBUaGUgb3JpZ2luIGZpbGVuYW1lIG9yIGRpcmVjdG9yeQogICAgICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0ICAgIFRoZSBuZXcgZmlsZW5hbWUgb3IgZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gYm9vbCAgICRvdmVyd3JpdGUgV2hldGhlciB0byBvdmVyd3JpdGUgdGhlIHRhcmdldCBpZiBpdCBhbHJlYWR5IGV4aXN0cwogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiB0YXJnZXQgZmlsZSBvciBkaXJlY3RvcnkgYWxyZWFkeSBleGlzdHMKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiBvcmlnaW4gY2Fubm90IGJlIHJlbmFtZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmFtZSgkb3JpZ2luLCAkdGFyZ2V0LCAkb3ZlcndyaXRlID0gZmFsc2UpCiAgICB7CiAgICAgICAgLy8gd2UgY2hlY2sgdGhhdCB0YXJnZXQgZG9lcyBub3QgZXhpc3QKICAgICAgICBpZiAoISRvdmVyd3JpdGUgJiYgJHRoaXMtPmlzUmVhZGFibGUoJHRhcmdldCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0Nhbm5vdCByZW5hbWUgYmVjYXVzZSB0aGUgdGFyZ2V0ICIlcyIgYWxyZWFkeSBleGlzdHMuJywgJHRhcmdldCksIDAsIG51bGwsICR0YXJnZXQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRydWUgIT09IEByZW5hbWUoJG9yaWdpbiwgJHRhcmdldCkpIHsKICAgICAgICAgICAgaWYgKGlzX2Rpcigkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vYnVncy5waHAubmV0LzU0MDk3ICYgaHR0cHM6Ly9waHAubmV0L3JlbmFtZSMxMTM5NDMKICAgICAgICAgICAgICAgICR0aGlzLT5taXJyb3IoJG9yaWdpbiwgJHRhcmdldCwgbnVsbCwgWydvdmVycmlkZScgPT4gJG92ZXJ3cml0ZSwgJ2RlbGV0ZScgPT4gJG92ZXJ3cml0ZV0pOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkb3JpZ2luKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0Nhbm5vdCByZW5hbWUgIiVzIiB0byAiJXMiLicsICRvcmlnaW4sICR0YXJnZXQpLCAwLCBudWxsLCAkdGFyZ2V0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUZWxscyB3aGV0aGVyIGEgZmlsZSBleGlzdHMgYW5kIGlzIHJlYWRhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVuYW1lIFBhdGggdG8gdGhlIGZpbGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gd2luZG93cyBwYXRoIGlzIGxvbmdlciB0aGFuIDI1OCBjaGFyYWN0ZXJzCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gaXNSZWFkYWJsZSgkZmlsZW5hbWUpCiAgICB7CiAgICAgICAgJG1heFBhdGhMZW5ndGggPSBcUEhQX01BWFBBVEhMRU4gLSAyOwoKICAgICAgICBpZiAoXHN0cmxlbigkZmlsZW5hbWUpID4gJG1heFBhdGhMZW5ndGgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0NvdWxkIG5vdCBjaGVjayBpZiBmaWxlIGlzIHJlYWRhYmxlIGJlY2F1c2UgcGF0aCBsZW5ndGggZXhjZWVkcyAlZCBjaGFyYWN0ZXJzLicsICRtYXhQYXRoTGVuZ3RoKSwgMCwgbnVsbCwgJGZpbGVuYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc19yZWFkYWJsZSgkZmlsZW5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHN5bWJvbGljIGxpbmsgb3IgY29weSBhIGRpcmVjdG9yeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5EaXIgICAgIFRoZSBvcmlnaW4gZGlyZWN0b3J5IHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhcmdldERpciAgICAgVGhlIHN5bWJvbGljIGxpbmsgbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkY29weU9uV2luZG93cyBXaGV0aGVyIHRvIGNvcHkgZmlsZXMgaWYgb24gV2luZG93cwogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiBzeW1saW5rIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzeW1saW5rKCRvcmlnaW5EaXIsICR0YXJnZXREaXIsICRjb3B5T25XaW5kb3dzID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRvcmlnaW5EaXIgPSBzdHJ0cigkb3JpZ2luRGlyLCAnLycsICdcXCcpOwogICAgICAgICAgICAkdGFyZ2V0RGlyID0gc3RydHIoJHRhcmdldERpciwgJy8nLCAnXFwnKTsKCiAgICAgICAgICAgIGlmICgkY29weU9uV2luZG93cykgewogICAgICAgICAgICAgICAgJHRoaXMtPm1pcnJvcigkb3JpZ2luRGlyLCAkdGFyZ2V0RGlyKTsKCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5ta2RpcihcZGlybmFtZSgkdGFyZ2V0RGlyKSk7CgogICAgICAgIGlmIChpc19saW5rKCR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgIGlmIChyZWFkbGluaygkdGFyZ2V0RGlyKSA9PT0gJG9yaWdpbkRpcikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5yZW1vdmUoJHRhcmdldERpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXNlbGY6OmJveCgnc3ltbGluaycsICRvcmlnaW5EaXIsICR0YXJnZXREaXIpKSB7CiAgICAgICAgICAgICR0aGlzLT5saW5rRXhjZXB0aW9uKCRvcmlnaW5EaXIsICR0YXJnZXREaXIsICdzeW1ib2xpYycpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBoYXJkIGxpbmssIG9yIHNldmVyYWwgaGFyZCBsaW5rcyB0byBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAkb3JpZ2luRmlsZSAgVGhlIG9yaWdpbmFsIGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW10gJHRhcmdldEZpbGVzIFRoZSB0YXJnZXQgZmlsZShzKQogICAgICoKICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIFdoZW4gb3JpZ2luYWwgZmlsZSBpcyBtaXNzaW5nIG9yIG5vdCBhIGZpbGUKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgIFdoZW4gbGluayBmYWlscywgaW5jbHVkaW5nIGlmIGxpbmsgYWxyZWFkeSBleGlzdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhcmRsaW5rKCRvcmlnaW5GaWxlLCAkdGFyZ2V0RmlsZXMpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZXhpc3RzKCRvcmlnaW5GaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKG51bGwsIDAsIG51bGwsICRvcmlnaW5GaWxlKTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNfZmlsZSgkb3JpZ2luRmlsZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdPcmlnaW4gZmlsZSAiJXMiIGlzIG5vdCBhIGZpbGUuJywgJG9yaWdpbkZpbGUpKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b0l0ZXJhYmxlKCR0YXJnZXRGaWxlcykgYXMgJHRhcmdldEZpbGUpIHsKICAgICAgICAgICAgaWYgKGlzX2ZpbGUoJHRhcmdldEZpbGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoZmlsZWlub2RlKCRvcmlnaW5GaWxlKSA9PT0gZmlsZWlub2RlKCR0YXJnZXRGaWxlKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRoaXMtPnJlbW92ZSgkdGFyZ2V0RmlsZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghc2VsZjo6Ym94KCdsaW5rJywgJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmxpbmtFeGNlcHRpb24oJG9yaWdpbkZpbGUsICR0YXJnZXRGaWxlLCAnaGFyZCcpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmtUeXBlIE5hbWUgb2YgdGhlIGxpbmsgdHlwZSwgdHlwaWNhbGx5ICdzeW1ib2xpYycgb3IgJ2hhcmQnCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbGlua0V4Y2VwdGlvbigkb3JpZ2luLCAkdGFyZ2V0LCAkbGlua1R5cGUpCiAgICB7CiAgICAgICAgaWYgKHNlbGY6OiRsYXN0RXJyb3IpIHsKICAgICAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SICYmIGZhbHNlICE9PSBzdHJwb3Moc2VsZjo6JGxhc3RFcnJvciwgJ2Vycm9yIGNvZGUoMTMxNCknKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBjcmVhdGUgIiVzIiBsaW5rIGR1ZSB0byBlcnJvciBjb2RlIDEzMTQ6IFwnQSByZXF1aXJlZCBwcml2aWxlZ2UgaXMgbm90IGhlbGQgYnkgdGhlIGNsaWVudFwnLiBEbyB5b3UgaGF2ZSB0aGUgcmVxdWlyZWQgQWRtaW5pc3RyYXRvci1yaWdodHM/JywgJGxpbmtUeXBlKSwgMCwgbnVsbCwgJHRhcmdldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ0ZhaWxlZCB0byBjcmVhdGUgIiVzIiBsaW5rIGZyb20gIiVzIiB0byAiJXMiLicsICRsaW5rVHlwZSwgJG9yaWdpbiwgJHRhcmdldCksIDAsIG51bGwsICR0YXJnZXQpOwogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZXMgbGlua3MgaW4gcGF0aHMuCiAgICAgKgogICAgICogV2l0aCAkY2Fub25pY2FsaXplID0gZmFsc2UgKGRlZmF1bHQpCiAgICAgKiAgICAgIC0gaWYgJHBhdGggZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGEgbGluaywgcmV0dXJucyBudWxsCiAgICAgKiAgICAgIC0gaWYgJHBhdGggaXMgYSBsaW5rLCByZXR1cm5zIHRoZSBuZXh0IGRpcmVjdCB0YXJnZXQgb2YgdGhlIGxpbmsgd2l0aG91dCBjb25zaWRlcmluZyB0aGUgZXhpc3RlbmNlIG9mIHRoZSB0YXJnZXQKICAgICAqCiAgICAgKiBXaXRoICRjYW5vbmljYWxpemUgPSB0cnVlCiAgICAgKiAgICAgIC0gaWYgJHBhdGggZG9lcyBub3QgZXhpc3QsIHJldHVybnMgbnVsbAogICAgICogICAgICAtIGlmICRwYXRoIGV4aXN0cywgcmV0dXJucyBpdHMgYWJzb2x1dGUgZnVsbHkgcmVzb2x2ZWQgZmluYWwgdmVyc2lvbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggICAgICAgICBBIGZpbGVzeXN0ZW0gcGF0aAogICAgICogQHBhcmFtIGJvb2wgICAkY2Fub25pY2FsaXplIFdoZXRoZXIgb3Igbm90IHRvIHJldHVybiBhIGNhbm9uaWNhbGl6ZWQgcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWRsaW5rKCRwYXRoLCAkY2Fub25pY2FsaXplID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCEkY2Fub25pY2FsaXplICYmICFpc19saW5rKCRwYXRoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICgkY2Fub25pY2FsaXplKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmV4aXN0cygkcGF0aCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgICAgICRwYXRoID0gcmVhZGxpbmsoJHBhdGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcmVhbHBhdGgoJHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgIHJldHVybiByZWFscGF0aCgkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVhZGxpbmsoJHBhdGgpOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYW4gZXhpc3RpbmcgcGF0aCwgY29udmVydCBpdCB0byBhIHBhdGggcmVsYXRpdmUgdG8gYSBnaXZlbiBzdGFydGluZyBwYXRoLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVuZFBhdGggICBBYnNvbHV0ZSBwYXRoIG9mIHRhcmdldAogICAgICogQHBhcmFtIHN0cmluZyAkc3RhcnRQYXRoIEFic29sdXRlIHBhdGggd2hlcmUgdHJhdmVyc2FsIGJlZ2lucwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFBhdGggb2YgdGFyZ2V0IHJlbGF0aXZlIHRvIHN0YXJ0aW5nIHBhdGgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1ha2VQYXRoUmVsYXRpdmUoJGVuZFBhdGgsICRzdGFydFBhdGgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJGVuZFBhdGgpIHx8ICEkdGhpcy0+aXNBYnNvbHV0ZVBhdGgoJHN0YXJ0UGF0aCkpIHsKICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignU3VwcG9ydCBmb3IgcGFzc2luZyByZWxhdGl2ZSBwYXRocyB0byAlcygpIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CiAgICAgICAgfQoKICAgICAgICAvLyBOb3JtYWxpemUgc2VwYXJhdG9ycyBvbiBXaW5kb3dzCiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRlbmRQYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkZW5kUGF0aCk7CiAgICAgICAgICAgICRzdGFydFBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRzdGFydFBhdGgpOwogICAgICAgIH0KCiAgICAgICAgJHNwbGl0RHJpdmVMZXR0ZXIgPSBmdW5jdGlvbiAoJHBhdGgpIHsKICAgICAgICAgICAgcmV0dXJuIChcc3RybGVuKCRwYXRoKSA+IDIgJiYgJzonID09PSAkcGF0aFsxXSAmJiAnLycgPT09ICRwYXRoWzJdICYmIGN0eXBlX2FscGhhKCRwYXRoWzBdKSkKICAgICAgICAgICAgICAgID8gW3N1YnN0cigkcGF0aCwgMiksIHN0cnRvdXBwZXIoJHBhdGhbMF0pXQogICAgICAgICAgICAgICAgOiBbJHBhdGgsIG51bGxdOwogICAgICAgIH07CgogICAgICAgICRzcGxpdFBhdGggPSBmdW5jdGlvbiAoJHBhdGgsICRhYnNvbHV0ZSkgewogICAgICAgICAgICAkcmVzdWx0ID0gW107CgogICAgICAgICAgICBmb3JlYWNoIChleHBsb2RlKCcvJywgdHJpbSgkcGF0aCwgJy8nKSkgYXMgJHNlZ21lbnQpIHsKICAgICAgICAgICAgICAgIGlmICgnLi4nID09PSAkc2VnbWVudCAmJiAoJGFic29sdXRlIHx8IFxjb3VudCgkcmVzdWx0KSkpIHsKICAgICAgICAgICAgICAgICAgICBhcnJheV9wb3AoJHJlc3VsdCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJy4nICE9PSAkc2VnbWVudCAmJiAnJyAhPT0gJHNlZ21lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkc2VnbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgfTsKCiAgICAgICAgbGlzdCgkZW5kUGF0aCwgJGVuZERyaXZlTGV0dGVyKSA9ICRzcGxpdERyaXZlTGV0dGVyKCRlbmRQYXRoKTsKICAgICAgICBsaXN0KCRzdGFydFBhdGgsICRzdGFydERyaXZlTGV0dGVyKSA9ICRzcGxpdERyaXZlTGV0dGVyKCRzdGFydFBhdGgpOwoKICAgICAgICAkc3RhcnRQYXRoQXJyID0gJHNwbGl0UGF0aCgkc3RhcnRQYXRoLCBzdGF0aWM6OmlzQWJzb2x1dGVQYXRoKCRzdGFydFBhdGgpKTsKICAgICAgICAkZW5kUGF0aEFyciA9ICRzcGxpdFBhdGgoJGVuZFBhdGgsIHN0YXRpYzo6aXNBYnNvbHV0ZVBhdGgoJGVuZFBhdGgpKTsKCiAgICAgICAgaWYgKCRlbmREcml2ZUxldHRlciAmJiAkc3RhcnREcml2ZUxldHRlciAmJiAkZW5kRHJpdmVMZXR0ZXIgIT0gJHN0YXJ0RHJpdmVMZXR0ZXIpIHsKICAgICAgICAgICAgLy8gRW5kIHBhdGggaXMgb24gYW5vdGhlciBkcml2ZSwgc28gbm8gcmVsYXRpdmUgcGF0aCBleGlzdHMKICAgICAgICAgICAgcmV0dXJuICRlbmREcml2ZUxldHRlci4nOi8nLigkZW5kUGF0aEFyciA/IGltcGxvZGUoJy8nLCAkZW5kUGF0aEFycikuJy8nIDogJycpOwogICAgICAgIH0KCiAgICAgICAgLy8gRmluZCBmb3Igd2hpY2ggZGlyZWN0b3J5IHRoZSBjb21tb24gcGF0aCBzdG9wcwogICAgICAgICRpbmRleCA9IDA7CiAgICAgICAgd2hpbGUgKGlzc2V0KCRzdGFydFBhdGhBcnJbJGluZGV4XSkgJiYgaXNzZXQoJGVuZFBhdGhBcnJbJGluZGV4XSkgJiYgJHN0YXJ0UGF0aEFyclskaW5kZXhdID09PSAkZW5kUGF0aEFyclskaW5kZXhdKSB7CiAgICAgICAgICAgICsrJGluZGV4OwogICAgICAgIH0KCiAgICAgICAgLy8gRGV0ZXJtaW5lIGhvdyBkZWVwIHRoZSBzdGFydCBwYXRoIGlzIHJlbGF0aXZlIHRvIHRoZSBjb21tb24gcGF0aCAoaWUsICJ3ZWIvYnVuZGxlcyIgPSAyIGxldmVscykKICAgICAgICBpZiAoMSA9PT0gXGNvdW50KCRzdGFydFBhdGhBcnIpICYmICcnID09PSAkc3RhcnRQYXRoQXJyWzBdKSB7CiAgICAgICAgICAgICRkZXB0aCA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGRlcHRoID0gXGNvdW50KCRzdGFydFBhdGhBcnIpIC0gJGluZGV4OwogICAgICAgIH0KCiAgICAgICAgLy8gUmVwZWF0ZWQgIi4uLyIgZm9yIGVhY2ggbGV2ZWwgbmVlZCB0byByZWFjaCB0aGUgY29tbW9uIHBhdGgKICAgICAgICAkdHJhdmVyc2VyID0gc3RyX3JlcGVhdCgnLi4vJywgJGRlcHRoKTsKCiAgICAgICAgJGVuZFBhdGhSZW1haW5kZXIgPSBpbXBsb2RlKCcvJywgXGFycmF5X3NsaWNlKCRlbmRQYXRoQXJyLCAkaW5kZXgpKTsKCiAgICAgICAgLy8gQ29uc3RydWN0ICRlbmRQYXRoIGZyb20gdHJhdmVyc2luZyB0byB0aGUgY29tbW9uIHBhdGgsIHRoZW4gdG8gdGhlIHJlbWFpbmluZyAkZW5kUGF0aAogICAgICAgICRyZWxhdGl2ZVBhdGggPSAkdHJhdmVyc2VyLignJyAhPT0gJGVuZFBhdGhSZW1haW5kZXIgPyAkZW5kUGF0aFJlbWFpbmRlci4nLycgOiAnJyk7CgogICAgICAgIHJldHVybiAnJyA9PT0gJHJlbGF0aXZlUGF0aCA/ICcuLycgOiAkcmVsYXRpdmVQYXRoOwogICAgfQoKICAgIC8qKgogICAgICogTWlycm9ycyBhIGRpcmVjdG9yeSB0byBhbm90aGVyLgogICAgICoKICAgICAqIENvcGllcyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgZnJvbSB0aGUgb3JpZ2luIGRpcmVjdG9yeSBpbnRvIHRoZSB0YXJnZXQgZGlyZWN0b3J5LiBCeSBkZWZhdWx0OgogICAgICoKICAgICAqICAtIGV4aXN0aW5nIGZpbGVzIGluIHRoZSB0YXJnZXQgZGlyZWN0b3J5IHdpbGwgYmUgb3ZlcndyaXR0ZW4sIGV4Y2VwdCBpZiB0aGV5IGFyZSBuZXdlciAoc2VlIHRoZSBgb3ZlcnJpZGVgIG9wdGlvbikKICAgICAqICAtIGZpbGVzIGluIHRoZSB0YXJnZXQgZGlyZWN0b3J5IHRoYXQgZG8gbm90IGV4aXN0IGluIHRoZSBzb3VyY2UgZGlyZWN0b3J5IHdpbGwgbm90IGJlIGRlbGV0ZWQgKHNlZSB0aGUgYGRlbGV0ZWAgb3B0aW9uKQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAkb3JpZ2luRGlyIFRoZSBvcmlnaW4gZGlyZWN0b3J5CiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgJHRhcmdldERpciBUaGUgdGFyZ2V0IGRpcmVjdG9yeQogICAgICogQHBhcmFtIFxUcmF2ZXJzYWJsZXxudWxsICRpdGVyYXRvciAgSXRlcmF0b3IgdGhhdCBmaWx0ZXJzIHdoaWNoIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBjb3B5LCBpZiBudWxsIGEgcmVjdXJzaXZlIGl0ZXJhdG9yIGlzIGNyZWF0ZWQKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAkb3B0aW9ucyAgIEFuIGFycmF5IG9mIGJvb2xlYW4gb3B0aW9ucwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsaWQgb3B0aW9ucyBhcmU6CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICRvcHRpb25zWydvdmVycmlkZSddIElmIHRydWUsIHRhcmdldCBmaWxlcyBuZXdlciB0aGFuIG9yaWdpbiBmaWxlcyBhcmUgb3ZlcndyaXR0ZW4gKHNlZSBjb3B5KCksIGRlZmF1bHRzIHRvIGZhbHNlKQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAkb3B0aW9uc1snY29weV9vbl93aW5kb3dzJ10gV2hldGhlciB0byBjb3B5IGZpbGVzIGluc3RlYWQgb2YgbGlua3Mgb24gV2luZG93cyAoc2VlIHN5bWxpbmsoKSwgZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICRvcHRpb25zWydkZWxldGUnXSBXaGV0aGVyIHRvIGRlbGV0ZSBmaWxlcyB0aGF0IGFyZSBub3QgaW4gdGhlIHNvdXJjZSBkaXJlY3RvcnkgKGRlZmF1bHRzIHRvIGZhbHNlKQogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiBmaWxlIHR5cGUgaXMgdW5rbm93bgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWlycm9yKCRvcmlnaW5EaXIsICR0YXJnZXREaXIsIFxUcmF2ZXJzYWJsZSAkaXRlcmF0b3IgPSBudWxsLCAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0YXJnZXREaXIgPSBydHJpbSgkdGFyZ2V0RGlyLCAnL1xcJyk7CiAgICAgICAgJG9yaWdpbkRpciA9IHJ0cmltKCRvcmlnaW5EaXIsICcvXFwnKTsKICAgICAgICAkb3JpZ2luRGlyTGVuID0gXHN0cmxlbigkb3JpZ2luRGlyKTsKCiAgICAgICAgLy8gSXRlcmF0ZSBpbiBkZXN0aW5hdGlvbiBmb2xkZXIgdG8gcmVtb3ZlIG9ic29sZXRlIGVudHJpZXMKICAgICAgICBpZiAoJHRoaXMtPmV4aXN0cygkdGFyZ2V0RGlyKSAmJiBpc3NldCgkb3B0aW9uc1snZGVsZXRlJ10pICYmICRvcHRpb25zWydkZWxldGUnXSkgewogICAgICAgICAgICAkZGVsZXRlSXRlcmF0b3IgPSAkaXRlcmF0b3I7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkZGVsZXRlSXRlcmF0b3IpIHsKICAgICAgICAgICAgICAgICRmbGFncyA9IFxGaWxlc3lzdGVtSXRlcmF0b3I6OlNLSVBfRE9UUzsKICAgICAgICAgICAgICAgICRkZWxldGVJdGVyYXRvciA9IG5ldyBcUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcihuZXcgXFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKCR0YXJnZXREaXIsICRmbGFncyksIFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yOjpDSElMRF9GSVJTVCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRhcmdldERpckxlbiA9IFxzdHJsZW4oJHRhcmdldERpcik7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkZWxldGVJdGVyYXRvciBhcyAkZmlsZSkgewogICAgICAgICAgICAgICAgJG9yaWdpbiA9ICRvcmlnaW5EaXIuc3Vic3RyKCRmaWxlLT5nZXRQYXRobmFtZSgpLCAkdGFyZ2V0RGlyTGVuKTsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmV4aXN0cygkb3JpZ2luKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW1vdmUoJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkY29weU9uV2luZG93cyA9IGZhbHNlOwogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snY29weV9vbl93aW5kb3dzJ10pKSB7CiAgICAgICAgICAgICRjb3B5T25XaW5kb3dzID0gJG9wdGlvbnNbJ2NvcHlfb25fd2luZG93cyddOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRpdGVyYXRvcikgewogICAgICAgICAgICAkZmxhZ3MgPSAkY29weU9uV2luZG93cyA/IFxGaWxlc3lzdGVtSXRlcmF0b3I6OlNLSVBfRE9UUyB8IFxGaWxlc3lzdGVtSXRlcmF0b3I6OkZPTExPV19TWU1MSU5LUyA6IFxGaWxlc3lzdGVtSXRlcmF0b3I6OlNLSVBfRE9UUzsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKG5ldyBcUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoJG9yaWdpbkRpciwgJGZsYWdzKSwgXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OlNFTEZfRklSU1QpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5leGlzdHMoJG9yaWdpbkRpcikpIHsKICAgICAgICAgICAgJHRoaXMtPm1rZGlyKCR0YXJnZXREaXIpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGl0ZXJhdG9yIGFzICRmaWxlKSB7CiAgICAgICAgICAgICR0YXJnZXQgPSAkdGFyZ2V0RGlyLnN1YnN0cigkZmlsZS0+Z2V0UGF0aG5hbWUoKSwgJG9yaWdpbkRpckxlbik7CgogICAgICAgICAgICBpZiAoJGNvcHlPbldpbmRvd3MpIHsKICAgICAgICAgICAgICAgIGlmIChpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb3B5KCRmaWxlLCAkdGFyZ2V0LCBpc3NldCgkb3B0aW9uc1snb3ZlcnJpZGUnXSkgPyAkb3B0aW9uc1snb3ZlcnJpZGUnXSA6IGZhbHNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm1rZGlyKCR0YXJnZXQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignVW5hYmxlIHRvIGd1ZXNzICIlcyIgZmlsZSB0eXBlLicsICRmaWxlKSwgMCwgbnVsbCwgJGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGlzX2xpbmsoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnN5bWxpbmsoJGZpbGUtPmdldExpbmtUYXJnZXQoKSwgJHRhcmdldCk7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoaXNfZGlyKCRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5ta2RpcigkdGFyZ2V0KTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb3B5KCRmaWxlLCAkdGFyZ2V0LCBpc3NldCgkb3B0aW9uc1snb3ZlcnJpZGUnXSkgPyAkb3B0aW9uc1snb3ZlcnJpZGUnXSA6IGZhbHNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBndWVzcyAiJXMiIGZpbGUgdHlwZS4nLCAkZmlsZSksIDAsIG51bGwsICRmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgZmlsZSBwYXRoIGlzIGFuIGFic29sdXRlIHBhdGguCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBBIGZpbGUgcGF0aAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBYnNvbHV0ZVBhdGgoJGZpbGUpCiAgICB7CiAgICAgICAgcmV0dXJuICcnICE9PSAoc3RyaW5nKSAkZmlsZSAmJiAoc3Ryc3BuKCRmaWxlLCAnL1xcJywgMCwgMSkKICAgICAgICAgICAgfHwgKFxzdHJsZW4oJGZpbGUpID4gMyAmJiBjdHlwZV9hbHBoYSgkZmlsZVswXSkKICAgICAgICAgICAgICAgICYmICc6JyA9PT0gJGZpbGVbMV0KICAgICAgICAgICAgICAgICYmIHN0cnNwbigkZmlsZSwgJy9cXCcsIDIsIDEpCiAgICAgICAgICAgICkKICAgICAgICAgICAgfHwgbnVsbCAhPT0gcGFyc2VfdXJsKCRmaWxlLCBcUEhQX1VSTF9TQ0hFTUUpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgZmlsZSB3aXRoIHN1cHBvcnQgZm9yIGN1c3RvbSBzdHJlYW0gd3JhcHBlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZGlyICAgIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIHRlbXBvcmFyeSBmaWxlbmFtZSB3aWxsIGJlIGNyZWF0ZWQKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZWZpeCBUaGUgcHJlZml4IG9mIHRoZSBnZW5lcmF0ZWQgdGVtcG9yYXJ5IGZpbGVuYW1lCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgTm90ZTogV2luZG93cyB1c2VzIG9ubHkgdGhlIGZpcnN0IHRocmVlIGNoYXJhY3RlcnMgb2YgcHJlZml4CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIG5ldyB0ZW1wb3JhcnkgZmlsZW5hbWUgKHdpdGggcGF0aCksIG9yIHRocm93IGFuIGV4Y2VwdGlvbiBvbiBmYWlsdXJlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0ZW1wbmFtKCRkaXIsICRwcmVmaXgpCiAgICB7CiAgICAgICAgbGlzdCgkc2NoZW1lLCAkaGllcmFyY2h5KSA9ICR0aGlzLT5nZXRTY2hlbWVBbmRIaWVyYXJjaHkoJGRpcik7CgogICAgICAgIC8vIElmIG5vIHNjaGVtZSBvciBzY2hlbWUgaXMgImZpbGUiIG9yICJncyIgKEdvb2dsZSBDbG91ZCkgY3JlYXRlIHRlbXAgZmlsZSBpbiBsb2NhbCBmaWxlc3lzdGVtCiAgICAgICAgaWYgKG51bGwgPT09ICRzY2hlbWUgfHwgJ2ZpbGUnID09PSAkc2NoZW1lIHx8ICdncycgPT09ICRzY2hlbWUpIHsKICAgICAgICAgICAgJHRtcEZpbGUgPSBAdGVtcG5hbSgkaGllcmFyY2h5LCAkcHJlZml4KTsKCiAgICAgICAgICAgIC8vIElmIHRlbXBuYW0gZmFpbGVkIG9yIG5vIHNjaGVtZSByZXR1cm4gdGhlIGZpbGVuYW1lIG90aGVyd2lzZSBwcmVwZW5kIHRoZSBzY2hlbWUKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkdG1wRmlsZSkgewogICAgICAgICAgICAgICAgaWYgKG51bGwgIT09ICRzY2hlbWUgJiYgJ2dzJyAhPT0gJHNjaGVtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkc2NoZW1lLic6Ly8nLiR0bXBGaWxlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdG1wRmlsZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCdBIHRlbXBvcmFyeSBmaWxlIGNvdWxkIG5vdCBiZSBjcmVhdGVkLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gTG9vcCB1bnRpbCB3ZSBjcmVhdGUgYSB2YWxpZCB0ZW1wIGZpbGUgb3IgaGF2ZSByZWFjaGVkIDEwIGF0dGVtcHRzCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgMTA7ICsrJGkpIHsKICAgICAgICAgICAgLy8gQ3JlYXRlIGEgdW5pcXVlIGZpbGVuYW1lCiAgICAgICAgICAgICR0bXBGaWxlID0gJGRpci4nLycuJHByZWZpeC51bmlxaWQobXRfcmFuZCgpLCB0cnVlKTsKCiAgICAgICAgICAgIC8vIFVzZSBmb3BlbiBpbnN0ZWFkIG9mIGZpbGVfZXhpc3RzIGFzIHNvbWUgc3RyZWFtcyBkbyBub3Qgc3VwcG9ydCBzdGF0CiAgICAgICAgICAgIC8vIFVzZSBtb2RlICd4KycgdG8gYXRvbWljYWxseSBjaGVjayBleGlzdGVuY2UgYW5kIGNyZWF0ZSB0byBhdm9pZCBhIFRPQ1RPVSB2dWxuZXJhYmlsaXR5CiAgICAgICAgICAgICRoYW5kbGUgPSBAZm9wZW4oJHRtcEZpbGUsICd4KycpOwoKICAgICAgICAgICAgLy8gSWYgdW5zdWNjZXNzZnVsIHJlc3RhcnQgdGhlIGxvb3AKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkaGFuZGxlKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2xvc2UgdGhlIGZpbGUgaWYgaXQgd2FzIHN1Y2Nlc3NmdWxseSBvcGVuZWQKICAgICAgICAgICAgQGZjbG9zZSgkaGFuZGxlKTsKCiAgICAgICAgICAgIHJldHVybiAkdG1wRmlsZTsKICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbignQSB0ZW1wb3JhcnkgZmlsZSBjb3VsZCBub3QgYmUgY3JlYXRlZC4nKTsKICAgIH0KCiAgICAvKioKICAgICAqIEF0b21pY2FsbHkgZHVtcHMgY29udGVudCBpbnRvIGEgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZSBUaGUgZmlsZSB0byBiZSB3cml0dGVuIHRvCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50ICBUaGUgZGF0YSB0byB3cml0ZSBpbnRvIHRoZSBmaWxlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjYW5ub3QgYmUgd3JpdHRlbiB0bwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZHVtcEZpbGUoJGZpbGVuYW1lLCAkY29udGVudCkKICAgIHsKICAgICAgICAkZGlyID0gXGRpcm5hbWUoJGZpbGVuYW1lKTsKCiAgICAgICAgaWYgKCFpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgJHRoaXMtPm1rZGlyKCRkaXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc193cml0YWJsZSgkZGlyKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignVW5hYmxlIHRvIHdyaXRlIHRvIHRoZSAiJXMiIGRpcmVjdG9yeS4nLCAkZGlyKSwgMCwgbnVsbCwgJGRpcik7CiAgICAgICAgfQoKICAgICAgICAvLyBXaWxsIGNyZWF0ZSBhIHRlbXAgZmlsZSB3aXRoIDA2MDAgYWNjZXNzIHJpZ2h0cwogICAgICAgIC8vIHdoZW4gdGhlIGZpbGVzeXN0ZW0gc3VwcG9ydHMgY2htb2QuCiAgICAgICAgJHRtcEZpbGUgPSAkdGhpcy0+dGVtcG5hbSgkZGlyLCBiYXNlbmFtZSgkZmlsZW5hbWUpKTsKCiAgICAgICAgaWYgKGZhbHNlID09PSBAZmlsZV9wdXRfY29udGVudHMoJHRtcEZpbGUsICRjb250ZW50KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignRmFpbGVkIHRvIHdyaXRlIGZpbGUgIiVzIi4nLCAkZmlsZW5hbWUpLCAwLCBudWxsLCAkZmlsZW5hbWUpOwogICAgICAgIH0KCiAgICAgICAgQGNobW9kKCR0bXBGaWxlLCBmaWxlX2V4aXN0cygkZmlsZW5hbWUpID8gZmlsZXBlcm1zKCRmaWxlbmFtZSkgOiAwNjY2ICYgfnVtYXNrKCkpOwoKICAgICAgICAkdGhpcy0+cmVuYW1lKCR0bXBGaWxlLCAkZmlsZW5hbWUsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogQXBwZW5kcyBjb250ZW50IHRvIGFuIGV4aXN0aW5nIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZW5hbWUgVGhlIGZpbGUgdG8gd2hpY2ggdG8gYXBwZW5kIGNvbnRlbnQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnQgIFRoZSBjb250ZW50IHRvIGFwcGVuZAogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgdGhlIGZpbGUgaXMgbm90IHdyaXRhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcHBlbmRUb0ZpbGUoJGZpbGVuYW1lLCAkY29udGVudCkKICAgIHsKICAgICAgICAkZGlyID0gXGRpcm5hbWUoJGZpbGVuYW1lKTsKCiAgICAgICAgaWYgKCFpc19kaXIoJGRpcikpIHsKICAgICAgICAgICAgJHRoaXMtPm1rZGlyKCRkaXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc193cml0YWJsZSgkZGlyKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oc3ByaW50ZignVW5hYmxlIHRvIHdyaXRlIHRvIHRoZSAiJXMiIGRpcmVjdG9yeS4nLCAkZGlyKSwgMCwgbnVsbCwgJGRpcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgPT09IEBmaWxlX3B1dF9jb250ZW50cygkZmlsZW5hbWUsICRjb250ZW50LCBcRklMRV9BUFBFTkQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdGYWlsZWQgdG8gd3JpdGUgZmlsZSAiJXMiLicsICRmaWxlbmFtZSksIDAsIG51bGwsICRmaWxlbmFtZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG1peGVkICRmaWxlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8XFRyYXZlcnNhYmxlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdG9JdGVyYWJsZSgkZmlsZXMpCiAgICB7CiAgICAgICAgcmV0dXJuIFxpc19hcnJheSgkZmlsZXMpIHx8ICRmaWxlcyBpbnN0YW5jZW9mIFxUcmF2ZXJzYWJsZSA/ICRmaWxlcyA6IFskZmlsZXNdOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhIDItdHVwbGUgb2Ygc2NoZW1lIChtYXkgYmUgbnVsbCkgYW5kIGhpZXJhcmNoaWNhbCBwYXJ0IG9mIGEgZmlsZW5hbWUgKGUuZy4gZmlsZTovLy90bXAgLT4gW2ZpbGUsIHRtcF0pLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVuYW1lIFRoZSBmaWxlbmFtZSB0byBiZSBwYXJzZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBmaWxlbmFtZSBzY2hlbWUgYW5kIGhpZXJhcmNoaWNhbCBwYXJ0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0U2NoZW1lQW5kSGllcmFyY2h5KCRmaWxlbmFtZSkKICAgIHsKICAgICAgICAkY29tcG9uZW50cyA9IGV4cGxvZGUoJzovLycsICRmaWxlbmFtZSwgMik7CgogICAgICAgIHJldHVybiAyID09PSBcY291bnQoJGNvbXBvbmVudHMpID8gWyRjb21wb25lbnRzWzBdLCAkY29tcG9uZW50c1sxXV0gOiBbbnVsbCwgJGNvbXBvbmVudHNbMF1dOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRmdW5jCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBib3goJGZ1bmMpCiAgICB7CiAgICAgICAgc2VsZjo6JGxhc3RFcnJvciA9IG51bGw7CiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoX19DTEFTU19fLic6OmhhbmRsZUVycm9yJyk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHJlc3VsdCA9IFxjYWxsX3VzZXJfZnVuY19hcnJheSgkZnVuYywgXGFycmF5X3NsaWNlKFxmdW5jX2dldF9hcmdzKCksIDEpKTsKICAgICAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgfSBjYXRjaCAoXEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCiAgICAgICAgdGhyb3cgJGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYW5kbGVFcnJvcigkdHlwZSwgJG1zZykKICAgIHsKICAgICAgICBzZWxmOjokbGFzdEVycm9yID0gJG1zZzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW07Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbVxFeGNlcHRpb25cSU9FeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxMb2NrXFN0b3JlXEZsb2NrU3RvcmU7CnVzZSBTeW1mb255XENvbXBvbmVudFxMb2NrXFN0b3JlXFNlbWFwaG9yZVN0b3JlOwoKQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzIGNsYXNzIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSAlcyBvciAlcyBpbnN0ZWFkLicsIExvY2tIYW5kbGVyOjpjbGFzcywgU2VtYXBob3JlU3RvcmU6OmNsYXNzLCBGbG9ja1N0b3JlOjpjbGFzcyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgovKioKICogTG9ja0hhbmRsZXIgY2xhc3MgcHJvdmlkZXMgYSBzaW1wbGUgYWJzdHJhY3Rpb24gdG8gbG9jayBhbnl0aGluZyBieSBtZWFucyBvZgogKiBhIGZpbGUgbG9jay4KICoKICogQSBsb2NrZWQgZmlsZSBpcyBjcmVhdGVkIGJhc2VkIG9uIHRoZSBsb2NrIG5hbWUgd2hlbiBjYWxsaW5nIGxvY2soKS4gT3RoZXIKICogbG9jayBoYW5kbGVycyB3aWxsIG5vdCBiZSBhYmxlIHRvIGxvY2sgdGhlIHNhbWUgbmFtZSB1bnRpbCBpdCBpcyByZWxlYXNlZAogKiAoZXhwbGljaXRseSBieSBjYWxsaW5nIHJlbGVhc2UoKSBvciBpbXBsaWNpdGx5IHdoZW4gdGhlIGluc3RhbmNlIGhvbGRpbmcgdGhlCiAqIGxvY2sgaXMgZGVzdHJveWVkKS4KICoKICogQGF1dGhvciBHcsOpZ29pcmUgUGluZWF1IDxseXJpeHhAbHlyaXh4LmluZm8+CiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqIEBhdXRob3IgTmljb2xhcyBHcmVrYXMgPHBAdGNod29yay5jb20+CiAqCiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy40LCB0byBiZSByZW1vdmVkIGluIDQuMC4gVXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcU2VtYXBob3JlU3RvcmUgb3IgU3ltZm9ueVxDb21wb25lbnRcTG9ja1xTdG9yZVxGbG9ja1N0b3JlIGluc3RlYWQuCiAqLwpjbGFzcyBMb2NrSGFuZGxlcgp7CiAgICBwcml2YXRlICRmaWxlOwogICAgcHJpdmF0ZSAkaGFuZGxlOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRuYW1lICAgICBUaGUgbG9jayBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGxvY2tQYXRoIFRoZSBkaXJlY3RvcnkgdG8gc3RvcmUgdGhlIGxvY2suIERlZmF1bHQgdmFsdWVzIHdpbGwgdXNlIHRlbXBvcmFyeSBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIHRoZSBsb2NrIGRpcmVjdG9yeSBjb3VsZCBub3QgYmUgY3JlYXRlZCBvciBpcyBub3Qgd3JpdGFibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lLCAkbG9ja1BhdGggPSBudWxsKQogICAgewogICAgICAgICRsb2NrUGF0aCA9ICRsb2NrUGF0aCA/OiBzeXNfZ2V0X3RlbXBfZGlyKCk7CgogICAgICAgIGlmICghaXNfZGlyKCRsb2NrUGF0aCkpIHsKICAgICAgICAgICAgJGZzID0gbmV3IEZpbGVzeXN0ZW0oKTsKICAgICAgICAgICAgJGZzLT5ta2RpcigkbG9ja1BhdGgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc193cml0YWJsZSgkbG9ja1BhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihzcHJpbnRmKCdUaGUgZGlyZWN0b3J5ICIlcyIgaXMgbm90IHdyaXRhYmxlLicsICRsb2NrUGF0aCksIDAsIG51bGwsICRsb2NrUGF0aCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZmlsZSA9IHNwcmludGYoJyVzL3NmLiVzLiVzLmxvY2snLCAkbG9ja1BhdGgsIHByZWdfcmVwbGFjZSgnL1teYS16MC05XC5fLV0rL2knLCAnLScsICRuYW1lKSwgaGFzaCgnc2hhMjU2JywgJG5hbWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvY2sgdGhlIHJlc291cmNlLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRibG9ja2luZyBXYWl0IHVudGlsIHRoZSBsb2NrIGlzIHJlbGVhc2VkCiAgICAgKgogICAgICogQHJldHVybiBib29sIFJldHVybnMgdHJ1ZSBpZiB0aGUgbG9jayB3YXMgYWNxdWlyZWQsIGZhbHNlIG90aGVyd2lzZQogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgdGhlIGxvY2sgZmlsZSBjb3VsZCBub3QgYmUgY3JlYXRlZCBvciBvcGVuZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvY2soJGJsb2NraW5nID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5oYW5kbGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkZXJyb3IgPSBudWxsOwoKICAgICAgICAvLyBTaWxlbmNlIGVycm9yIHJlcG9ydGluZwogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGZ1bmN0aW9uICgkZXJybm8sICRtc2cpIHVzZSAoJiRlcnJvcikgewogICAgICAgICAgICAkZXJyb3IgPSAkbXNnOwogICAgICAgIH0pOwoKICAgICAgICBpZiAoISR0aGlzLT5oYW5kbGUgPSBmb3BlbigkdGhpcy0+ZmlsZSwgJ3IrJykgPzogZm9wZW4oJHRoaXMtPmZpbGUsICdyJykpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5oYW5kbGUgPSBmb3BlbigkdGhpcy0+ZmlsZSwgJ3gnKSkgewogICAgICAgICAgICAgICAgY2htb2QoJHRoaXMtPmZpbGUsIDA2NjYpOwogICAgICAgICAgICB9IGVsc2VpZiAoISR0aGlzLT5oYW5kbGUgPSBmb3BlbigkdGhpcy0+ZmlsZSwgJ3IrJykgPzogZm9wZW4oJHRoaXMtPmZpbGUsICdyJykpIHsKICAgICAgICAgICAgICAgIHVzbGVlcCgxMDApOyAvLyBHaXZlIHNvbWUgdGltZSBmb3IgY2htb2QoKSB0byBjb21wbGV0ZQogICAgICAgICAgICAgICAgJHRoaXMtPmhhbmRsZSA9IGZvcGVuKCR0aGlzLT5maWxlLCAncisnKSA/OiBmb3BlbigkdGhpcy0+ZmlsZSwgJ3InKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN0b3JlX2Vycm9yX2hhbmRsZXIoKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+aGFuZGxlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigkZXJyb3IsIDAsIG51bGwsICR0aGlzLT5maWxlKTsKICAgICAgICB9CgogICAgICAgIC8vIE9uIFdpbmRvd3MsIGV2ZW4gaWYgUEhQIGRvYyBzYXlzIHRoZSBjb250cmFyeSwgTE9DS19OQiB3b3Jrcywgc2VlCiAgICAgICAgLy8gaHR0cHM6Ly9idWdzLnBocC5uZXQvNTQxMjkKICAgICAgICBpZiAoIWZsb2NrKCR0aGlzLT5oYW5kbGUsIFxMT0NLX0VYIHwgKCRibG9ja2luZyA/IDAgOiBcTE9DS19OQikpKSB7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+aGFuZGxlKTsKICAgICAgICAgICAgJHRoaXMtPmhhbmRsZSA9IG51bGw7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbGVhc2UgdGhlIHJlc291cmNlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVsZWFzZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5oYW5kbGUpIHsKICAgICAgICAgICAgZmxvY2soJHRoaXMtPmhhbmRsZSwgXExPQ0tfVU4gfCBcTE9DS19OQik7CiAgICAgICAgICAgIGZjbG9zZSgkdGhpcy0+aGFuZGxlKTsKICAgICAgICAgICAgJHRoaXMtPmhhbmRsZSA9IG51bGw7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbVxFeGNlcHRpb247CgovKioKICogSU9FeGNlcHRpb24gaW50ZXJmYWNlIGZvciBmaWxlIGFuZCBpbnB1dC9vdXRwdXQgc3RyZWFtIHJlbGF0ZWQgZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhlIGNvbXBvbmVudC4KICoKICogQGF1dGhvciBDaHJpc3RpYW4gR8OkcnRuZXIgPGNocmlzdGlhbmdhZXJ0bmVyLmZpbG1AZ29vZ2xlbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgSU9FeGNlcHRpb25JbnRlcmZhY2UgZXh0ZW5kcyBFeGNlcHRpb25JbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhc3NvY2lhdGVkIHBhdGggZm9yIHRoZSBleGNlcHRpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBUaGUgcGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGF0aCgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbVxFeGNlcHRpb247CgovKioKICogRXhjZXB0aW9uIGNsYXNzIHRocm93biB3aGVuIGEgZmlsZSBjb3VsZG4ndCBiZSBmb3VuZC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgQ2hyaXN0aWFuIEfDpHJ0bmVyIDxjaHJpc3RpYW5nYWVydG5lci5maWxtQGdvb2dsZW1haWwuY29tPgogKi8KY2xhc3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24KewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlID0gbnVsbCwgJGNvZGUgPSAwLCBcRXhjZXB0aW9uICRwcmV2aW91cyA9IG51bGwsICRwYXRoID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJG1lc3NhZ2UpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRwYXRoKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdGaWxlIGNvdWxkIG5vdCBiZSBmb3VuZC4nOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBzcHJpbnRmKCdGaWxlICIlcyIgY291bGQgbm90IGJlIGZvdW5kLicsICRwYXRoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJGNvZGUsICRwcmV2aW91cywgJHBhdGgpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmlsZXN5c3RlbVxFeGNlcHRpb247CgovKioKICogRXhjZXB0aW9uIGludGVyZmFjZSBmb3IgYWxsIGV4Y2VwdGlvbnMgdGhyb3duIGJ5IHRoZSBjb21wb25lbnQuCiAqCiAqIEBhdXRob3IgUm9tYWluIE5ldXRyb24gPGltcHJlY0BnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbGVzeXN0ZW1cRXhjZXB0aW9uOwoKLyoqCiAqIEV4Y2VwdGlvbiBjbGFzcyB0aHJvd24gd2hlbiBhIGZpbGVzeXN0ZW0gb3BlcmF0aW9uIGZhaWx1cmUgaGFwcGVucy4KICoKICogQGF1dGhvciBSb21haW4gTmV1dHJvbiA8aW1wcmVjQGdtYWlsLmNvbT4KICogQGF1dGhvciBDaHJpc3RpYW4gR8OkcnRuZXIgPGNocmlzdGlhbmdhZXJ0bmVyLmZpbG1AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSU9FeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbiBpbXBsZW1lbnRzIElPRXhjZXB0aW9uSW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJHBhdGg7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlLCAkY29kZSA9IDAsIFxFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCwgJHBhdGggPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wYXRoID0gJHBhdGg7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRjb2RlLCAkcHJldmlvdXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGF0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXRoOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgp1c2UgU3ltZm9ueVxQb2x5ZmlsbFxNYnN0cmluZyBhcyBwOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2NvbnZlcnRfZW5jb2RpbmcnKSkgewogICAgZnVuY3Rpb24gbWJfY29udmVydF9lbmNvZGluZygkc3RyaW5nLCAkdG9fZW5jb2RpbmcsICRmcm9tX2VuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfY29udmVydF9lbmNvZGluZygkc3RyaW5nLCAkdG9fZW5jb2RpbmcsICRmcm9tX2VuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9kZWNvZGVfbWltZWhlYWRlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9kZWNvZGVfbWltZWhlYWRlcigkc3RyaW5nKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9kZWNvZGVfbWltZWhlYWRlcigkc3RyaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9lbmNvZGVfbWltZWhlYWRlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9lbmNvZGVfbWltZWhlYWRlcigkc3RyaW5nLCAkY2hhcnNldCA9IG51bGwsICR0cmFuc2Zlcl9lbmNvZGluZyA9IG51bGwsICRuZXdsaW5lID0gbnVsbCwgJGluZGVudCA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2VuY29kZV9taW1laGVhZGVyKCRzdHJpbmcsICRjaGFyc2V0LCAkdHJhbnNmZXJfZW5jb2RpbmcsICRuZXdsaW5lLCAkaW5kZW50KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9kZWNvZGVfbnVtZXJpY2VudGl0eScpKSB7CiAgICBmdW5jdGlvbiBtYl9kZWNvZGVfbnVtZXJpY2VudGl0eSgkc3RyaW5nLCAkbWFwLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9kZWNvZGVfbnVtZXJpY2VudGl0eSgkc3RyaW5nLCAkbWFwLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2VuY29kZV9udW1lcmljZW50aXR5JykpIHsKICAgIGZ1bmN0aW9uIG1iX2VuY29kZV9udW1lcmljZW50aXR5KCRzdHJpbmcsICRtYXAsICRlbmNvZGluZyA9IG51bGwsICRoZXggPSBmYWxzZSkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZW5jb2RlX251bWVyaWNlbnRpdHkoJHN0cmluZywgJG1hcCwgJGVuY29kaW5nLCAkaGV4KTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9jb252ZXJ0X2Nhc2UnKSkgewogICAgZnVuY3Rpb24gbWJfY29udmVydF9jYXNlKCRzdHJpbmcsICRtb2RlLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9jb252ZXJ0X2Nhc2UoJHN0cmluZywgJG1vZGUsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfaW50ZXJuYWxfZW5jb2RpbmcnKSkgewogICAgZnVuY3Rpb24gbWJfaW50ZXJuYWxfZW5jb2RpbmcoJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfaW50ZXJuYWxfZW5jb2RpbmcoJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9sYW5ndWFnZScpKSB7CiAgICBmdW5jdGlvbiBtYl9sYW5ndWFnZSgkbGFuZ3VhZ2UgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9sYW5ndWFnZSgkbGFuZ3VhZ2UpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2xpc3RfZW5jb2RpbmdzJykpIHsKICAgIGZ1bmN0aW9uIG1iX2xpc3RfZW5jb2RpbmdzKCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfbGlzdF9lbmNvZGluZ3MoKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9lbmNvZGluZ19hbGlhc2VzJykpIHsKICAgIGZ1bmN0aW9uIG1iX2VuY29kaW5nX2FsaWFzZXMoJGVuY29kaW5nKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9lbmNvZGluZ19hbGlhc2VzKCRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfY2hlY2tfZW5jb2RpbmcnKSkgewogICAgZnVuY3Rpb24gbWJfY2hlY2tfZW5jb2RpbmcoJHZhbHVlID0gbnVsbCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfY2hlY2tfZW5jb2RpbmcoJHZhbHVlLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2RldGVjdF9lbmNvZGluZycpKSB7CiAgICBmdW5jdGlvbiBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZywgJGVuY29kaW5ncyA9IG51bGwsICRzdHJpY3QgPSBmYWxzZSkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZGV0ZWN0X2VuY29kaW5nKCRzdHJpbmcsICRlbmNvZGluZ3MsICRzdHJpY3QpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2RldGVjdF9vcmRlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9kZXRlY3Rfb3JkZXIoJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZGV0ZWN0X29yZGVyKCRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfcGFyc2Vfc3RyJykpIHsKICAgIGZ1bmN0aW9uIG1iX3BhcnNlX3N0cigkc3RyaW5nLCAmJHJlc3VsdCA9IGFycmF5KCkpIHsgcGFyc2Vfc3RyKCRzdHJpbmcsICRyZXN1bHQpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cmxlbicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJsZW4oJHN0cmluZywgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RybGVuKCRzdHJpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RycG9zJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQgPSAwLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0LCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnRvbG93ZXInKSkgewogICAgZnVuY3Rpb24gbWJfc3RydG9sb3dlcigkc3RyaW5nLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJ0b2xvd2VyKCRzdHJpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RydG91cHBlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJ0b3VwcGVyKCRzdHJpbmcsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cnRvdXBwZXIoJHN0cmluZywgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdWJzdGl0dXRlX2NoYXJhY3RlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdWJzdGl0dXRlX2NoYXJhY3Rlcigkc3Vic3RpdHV0ZV9jaGFyYWN0ZXIgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdWJzdGl0dXRlX2NoYXJhY3Rlcigkc3Vic3RpdHV0ZV9jaGFyYWN0ZXIpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N1YnN0cicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdWJzdHIoJHN0cmluZywgJHN0YXJ0LCAkbGVuZ3RoID0gMjE0NzQ4MzY0NywgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Vic3RyKCRzdHJpbmcsICRzdGFydCwgJGxlbmd0aCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJpcG9zJykpIHsKICAgIGZ1bmN0aW9uIG1iX3N0cmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RyaXBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3RyaXN0cicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJpc3RyKCRoYXlzdGFjaywgJG5lZWRsZSwgJGJlZm9yZV9uZWVkbGUgPSBmYWxzZSwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3RyaXN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlLCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnJjaHInKSkgewogICAgZnVuY3Rpb24gbWJfc3RycmNocigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cnJjaHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkYmVmb3JlX25lZWRsZSwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJyaWNocicpKSB7CiAgICBmdW5jdGlvbiBtYl9zdHJyaWNocigkaGF5c3RhY2ssICRuZWVkbGUsICRiZWZvcmVfbmVlZGxlID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX3N0cnJpY2hyKCRoYXlzdGFjaywgJG5lZWRsZSwgJGJlZm9yZV9uZWVkbGUsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3Rycmlwb3MnKSkgewogICAgZnVuY3Rpb24gbWJfc3Rycmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Rycmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0LCAkZW5jb2RpbmcpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX3N0cnJwb3MnKSkgewogICAgZnVuY3Rpb24gbWJfc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQgPSAwLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJzdHInKSkgewogICAgZnVuY3Rpb24gbWJfc3Ryc3RyKCRoYXlzdGFjaywgJG5lZWRsZSwgJGJlZm9yZV9uZWVkbGUgPSBmYWxzZSwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Ryc3RyKCRoYXlzdGFjaywgJG5lZWRsZSwgJGJlZm9yZV9uZWVkbGUsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfZ2V0X2luZm8nKSkgewogICAgZnVuY3Rpb24gbWJfZ2V0X2luZm8oJHR5cGUgPSAnYWxsJykgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfZ2V0X2luZm8oJHR5cGUpOyB9Cn0KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2h0dHBfb3V0cHV0JykpIHsKICAgIGZ1bmN0aW9uIG1iX2h0dHBfb3V0cHV0KCRlbmNvZGluZyA9IG51bGwpIHsgcmV0dXJuIHBcTWJzdHJpbmc6Om1iX2h0dHBfb3V0cHV0KCRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfc3Ryd2lkdGgnKSkgewogICAgZnVuY3Rpb24gbWJfc3Ryd2lkdGgoJHN0cmluZywgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Ryd2lkdGgoJHN0cmluZywgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdWJzdHJfY291bnQnKSkgewogICAgZnVuY3Rpb24gbWJfc3Vic3RyX2NvdW50KCRoYXlzdGFjaywgJG5lZWRsZSwgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfc3Vic3RyX2NvdW50KCRoYXlzdGFjaywgJG5lZWRsZSwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9vdXRwdXRfaGFuZGxlcicpKSB7CiAgICBmdW5jdGlvbiBtYl9vdXRwdXRfaGFuZGxlcigkc3RyaW5nLCAkc3RhdHVzKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9vdXRwdXRfaGFuZGxlcigkc3RyaW5nLCAkc3RhdHVzKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9odHRwX2lucHV0JykpIHsKICAgIGZ1bmN0aW9uIG1iX2h0dHBfaW5wdXQoJHR5cGUgPSAnJykgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfaHR0cF9pbnB1dCgkdHlwZSk7IH0KfQoKaWYgKFBIUF9WRVJTSU9OX0lEID49IDgwMDAwKSB7CiAgICByZXF1aXJlX29uY2UgX19ESVJfXy4nL1Jlc291cmNlcy9tYl9jb252ZXJ0X3ZhcmlhYmxlcy5waHA4JzsKfSBlbHNlaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2NvbnZlcnRfdmFyaWFibGVzJykpIHsKICAgIGZ1bmN0aW9uIG1iX2NvbnZlcnRfdmFyaWFibGVzKCR0b0VuY29kaW5nLCAkZnJvbUVuY29kaW5nLCAmJGEgPSBudWxsLCAmJGIgPSBudWxsLCAmJGMgPSBudWxsLCAmJGQgPSBudWxsLCAmJGUgPSBudWxsLCAmJGYgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9jb252ZXJ0X3ZhcmlhYmxlcygkdG9FbmNvZGluZywgJGZyb21FbmNvZGluZywgJGEsICRiLCAkYywgJGQsICRlLCAkZik7IH0KfQoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX29yZCcpKSB7CiAgICBmdW5jdGlvbiBtYl9vcmQoJHN0cmluZywgJGVuY29kaW5nID0gbnVsbCkgeyByZXR1cm4gcFxNYnN0cmluZzo6bWJfb3JkKCRzdHJpbmcsICRlbmNvZGluZyk7IH0KfQppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWJfY2hyJykpIHsKICAgIGZ1bmN0aW9uIG1iX2NocigkY29kZXBvaW50LCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9jaHIoJGNvZGVwb2ludCwgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zY3J1YicpKSB7CiAgICBmdW5jdGlvbiBtYl9zY3J1Yigkc3RyaW5nLCAkZW5jb2RpbmcgPSBudWxsKSB7ICRlbmNvZGluZyA9IG51bGwgPT09ICRlbmNvZGluZyA/IG1iX2ludGVybmFsX2VuY29kaW5nKCkgOiAkZW5jb2Rpbmc7IHJldHVybiBtYl9jb252ZXJ0X2VuY29kaW5nKCRzdHJpbmcsICRlbmNvZGluZywgJGVuY29kaW5nKTsgfQp9CmlmICghZnVuY3Rpb25fZXhpc3RzKCdtYl9zdHJfc3BsaXQnKSkgewogICAgZnVuY3Rpb24gbWJfc3RyX3NwbGl0KCRzdHJpbmcsICRsZW5ndGggPSAxLCAkZW5jb2RpbmcgPSBudWxsKSB7IHJldHVybiBwXE1ic3RyaW5nOjptYl9zdHJfc3BsaXQoJHN0cmluZywgJGxlbmd0aCwgJGVuY29kaW5nKTsgfQp9CgppZiAoZXh0ZW5zaW9uX2xvYWRlZCgnbWJzdHJpbmcnKSkgewogICAgcmV0dXJuOwp9CgppZiAoIWRlZmluZWQoJ01CX0NBU0VfVVBQRVInKSkgewogICAgZGVmaW5lKCdNQl9DQVNFX1VQUEVSJywgMCk7Cn0KaWYgKCFkZWZpbmVkKCdNQl9DQVNFX0xPV0VSJykpIHsKICAgIGRlZmluZSgnTUJfQ0FTRV9MT1dFUicsIDEpOwp9CmlmICghZGVmaW5lZCgnTUJfQ0FTRV9USVRMRScpKSB7CiAgICBkZWZpbmUoJ01CX0NBU0VfVElUTEUnLCAyKTsKfQo8P3BocAoKcmV0dXJuIGFycmF5ICgKICAnQScgPT4gJ2EnLAogICdCJyA9PiAnYicsCiAgJ0MnID0+ICdjJywKICAnRCcgPT4gJ2QnLAogICdFJyA9PiAnZScsCiAgJ0YnID0+ICdmJywKICAnRycgPT4gJ2cnLAogICdIJyA9PiAnaCcsCiAgJ0knID0+ICdpJywKICAnSicgPT4gJ2onLAogICdLJyA9PiAnaycsCiAgJ0wnID0+ICdsJywKICAnTScgPT4gJ20nLAogICdOJyA9PiAnbicsCiAgJ08nID0+ICdvJywKICAnUCcgPT4gJ3AnLAogICdRJyA9PiAncScsCiAgJ1InID0+ICdyJywKICAnUycgPT4gJ3MnLAogICdUJyA9PiAndCcsCiAgJ1UnID0+ICd1JywKICAnVicgPT4gJ3YnLAogICdXJyA9PiAndycsCiAgJ1gnID0+ICd4JywKICAnWScgPT4gJ3knLAogICdaJyA9PiAneicsCiAgJ8OAJyA9PiAnw6AnLAogICfDgScgPT4gJ8OhJywKICAnw4InID0+ICfDoicsCiAgJ8ODJyA9PiAnw6MnLAogICfDhCcgPT4gJ8OkJywKICAnw4UnID0+ICfDpScsCiAgJ8OGJyA9PiAnw6YnLAogICfDhycgPT4gJ8OnJywKICAnw4gnID0+ICfDqCcsCiAgJ8OJJyA9PiAnw6knLAogICfDiicgPT4gJ8OqJywKICAnw4snID0+ICfDqycsCiAgJ8OMJyA9PiAnw6wnLAogICfDjScgPT4gJ8OtJywKICAnw44nID0+ICfDricsCiAgJ8OPJyA9PiAnw68nLAogICfDkCcgPT4gJ8OwJywKICAnw5EnID0+ICfDsScsCiAgJ8OSJyA9PiAnw7InLAogICfDkycgPT4gJ8OzJywKICAnw5QnID0+ICfDtCcsCiAgJ8OVJyA9PiAnw7UnLAogICfDlicgPT4gJ8O2JywKICAnw5gnID0+ICfDuCcsCiAgJ8OZJyA9PiAnw7knLAogICfDmicgPT4gJ8O6JywKICAnw5snID0+ICfDuycsCiAgJ8OcJyA9PiAnw7wnLAogICfDnScgPT4gJ8O9JywKICAnw54nID0+ICfDvicsCiAgJ8SAJyA9PiAnxIEnLAogICfEgicgPT4gJ8SDJywKICAnxIQnID0+ICfEhScsCiAgJ8SGJyA9PiAnxIcnLAogICfEiCcgPT4gJ8SJJywKICAnxIonID0+ICfEiycsCiAgJ8SMJyA9PiAnxI0nLAogICfEjicgPT4gJ8SPJywKICAnxJAnID0+ICfEkScsCiAgJ8SSJyA9PiAnxJMnLAogICfElCcgPT4gJ8SVJywKICAnxJYnID0+ICfElycsCiAgJ8SYJyA9PiAnxJknLAogICfEmicgPT4gJ8SbJywKICAnxJwnID0+ICfEnScsCiAgJ8SeJyA9PiAnxJ8nLAogICfEoCcgPT4gJ8ShJywKICAnxKInID0+ICfEoycsCiAgJ8SkJyA9PiAnxKUnLAogICfEpicgPT4gJ8SnJywKICAnxKgnID0+ICfEqScsCiAgJ8SqJyA9PiAnxKsnLAogICfErCcgPT4gJ8StJywKICAnxK4nID0+ICfErycsCiAgJ8SwJyA9PiAnaScsCiAgJ8SyJyA9PiAnxLMnLAogICfEtCcgPT4gJ8S1JywKICAnxLYnID0+ICfEtycsCiAgJ8S5JyA9PiAnxLonLAogICfEuycgPT4gJ8S8JywKICAnxL0nID0+ICfEvicsCiAgJ8S/JyA9PiAnxYAnLAogICfFgScgPT4gJ8WCJywKICAnxYMnID0+ICfFhCcsCiAgJ8WFJyA9PiAnxYYnLAogICfFhycgPT4gJ8WIJywKICAnxYonID0+ICfFiycsCiAgJ8WMJyA9PiAnxY0nLAogICfFjicgPT4gJ8WPJywKICAnxZAnID0+ICfFkScsCiAgJ8WSJyA9PiAnxZMnLAogICfFlCcgPT4gJ8WVJywKICAnxZYnID0+ICfFlycsCiAgJ8WYJyA9PiAnxZknLAogICfFmicgPT4gJ8WbJywKICAnxZwnID0+ICfFnScsCiAgJ8WeJyA9PiAnxZ8nLAogICfFoCcgPT4gJ8WhJywKICAnxaInID0+ICfFoycsCiAgJ8WkJyA9PiAnxaUnLAogICfFpicgPT4gJ8WnJywKICAnxagnID0+ICfFqScsCiAgJ8WqJyA9PiAnxasnLAogICfFrCcgPT4gJ8WtJywKICAnxa4nID0+ICfFrycsCiAgJ8WwJyA9PiAnxbEnLAogICfFsicgPT4gJ8WzJywKICAnxbQnID0+ICfFtScsCiAgJ8W2JyA9PiAnxbcnLAogICfFuCcgPT4gJ8O/JywKICAnxbknID0+ICfFuicsCiAgJ8W7JyA9PiAnxbwnLAogICfFvScgPT4gJ8W+JywKICAnxoEnID0+ICfJkycsCiAgJ8aCJyA9PiAnxoMnLAogICfGhCcgPT4gJ8aFJywKICAnxoYnID0+ICfJlCcsCiAgJ8aHJyA9PiAnxognLAogICfGiScgPT4gJ8mWJywKICAnxoonID0+ICfJlycsCiAgJ8aLJyA9PiAnxownLAogICfGjicgPT4gJ8edJywKICAnxo8nID0+ICfJmScsCiAgJ8aQJyA9PiAnyZsnLAogICfGkScgPT4gJ8aSJywKICAnxpMnID0+ICfJoCcsCiAgJ8aUJyA9PiAnyaMnLAogICfGlicgPT4gJ8mpJywKICAnxpcnID0+ICfJqCcsCiAgJ8aYJyA9PiAnxpknLAogICfGnCcgPT4gJ8mvJywKICAnxp0nID0+ICfJsicsCiAgJ8afJyA9PiAnybUnLAogICfGoCcgPT4gJ8ahJywKICAnxqInID0+ICfGoycsCiAgJ8akJyA9PiAnxqUnLAogICfGpicgPT4gJ8qAJywKICAnxqcnID0+ICfGqCcsCiAgJ8apJyA9PiAnyoMnLAogICfGrCcgPT4gJ8atJywKICAnxq4nID0+ICfKiCcsCiAgJ8avJyA9PiAnxrAnLAogICfGsScgPT4gJ8qKJywKICAnxrInID0+ICfKiycsCiAgJ8azJyA9PiAnxrQnLAogICfGtScgPT4gJ8a2JywKICAnxrcnID0+ICfKkicsCiAgJ8a4JyA9PiAnxrknLAogICfGvCcgPT4gJ8a9JywKICAnx4QnID0+ICfHhicsCiAgJ8eFJyA9PiAnx4YnLAogICfHhycgPT4gJ8eJJywKICAnx4gnID0+ICfHiScsCiAgJ8eKJyA9PiAnx4wnLAogICfHiycgPT4gJ8eMJywKICAnx40nID0+ICfHjicsCiAgJ8ePJyA9PiAnx5AnLAogICfHkScgPT4gJ8eSJywKICAnx5MnID0+ICfHlCcsCiAgJ8eVJyA9PiAnx5YnLAogICfHlycgPT4gJ8eYJywKICAnx5knID0+ICfHmicsCiAgJ8ebJyA9PiAnx5wnLAogICfHnicgPT4gJ8efJywKICAnx6AnID0+ICfHoScsCiAgJ8eiJyA9PiAnx6MnLAogICfHpCcgPT4gJ8elJywKICAnx6YnID0+ICfHpycsCiAgJ8eoJyA9PiAnx6knLAogICfHqicgPT4gJ8erJywKICAnx6wnID0+ICfHrScsCiAgJ8euJyA9PiAnx68nLAogICfHsScgPT4gJ8ezJywKICAnx7InID0+ICfHsycsCiAgJ8e0JyA9PiAnx7UnLAogICfHticgPT4gJ8aVJywKICAnx7cnID0+ICfGvycsCiAgJ8e4JyA9PiAnx7knLAogICfHuicgPT4gJ8e7JywKICAnx7wnID0+ICfHvScsCiAgJ8e+JyA9PiAnx78nLAogICfIgCcgPT4gJ8iBJywKICAnyIInID0+ICfIgycsCiAgJ8iEJyA9PiAnyIUnLAogICfIhicgPT4gJ8iHJywKICAnyIgnID0+ICfIiScsCiAgJ8iKJyA9PiAnyIsnLAogICfIjCcgPT4gJ8iNJywKICAnyI4nID0+ICfIjycsCiAgJ8iQJyA9PiAnyJEnLAogICfIkicgPT4gJ8iTJywKICAnyJQnID0+ICfIlScsCiAgJ8iWJyA9PiAnyJcnLAogICfImCcgPT4gJ8iZJywKICAnyJonID0+ICfImycsCiAgJ8icJyA9PiAnyJ0nLAogICfInicgPT4gJ8ifJywKICAnyKAnID0+ICfGnicsCiAgJ8iiJyA9PiAnyKMnLAogICfIpCcgPT4gJ8ilJywKICAnyKYnID0+ICfIpycsCiAgJ8ioJyA9PiAnyKknLAogICfIqicgPT4gJ8irJywKICAnyKwnID0+ICfIrScsCiAgJ8iuJyA9PiAnyK8nLAogICfIsCcgPT4gJ8ixJywKICAnyLInID0+ICfIsycsCiAgJ8i6JyA9PiAn4rGlJywKICAnyLsnID0+ICfIvCcsCiAgJ8i9JyA9PiAnxponLAogICfIvicgPT4gJ+KxpicsCiAgJ8mBJyA9PiAnyYInLAogICfJgycgPT4gJ8aAJywKICAnyYQnID0+ICfKiScsCiAgJ8mFJyA9PiAnyownLAogICfJhicgPT4gJ8mHJywKICAnyYgnID0+ICfJiScsCiAgJ8mKJyA9PiAnyYsnLAogICfJjCcgPT4gJ8mNJywKICAnyY4nID0+ICfJjycsCiAgJ82wJyA9PiAnzbEnLAogICfNsicgPT4gJ82zJywKICAnzbYnID0+ICfNtycsCiAgJ82/JyA9PiAnz7MnLAogICfOhicgPT4gJ86sJywKICAnzognID0+ICfOrScsCiAgJ86JJyA9PiAnzq4nLAogICfOiicgPT4gJ86vJywKICAnzownID0+ICfPjCcsCiAgJ86OJyA9PiAnz40nLAogICfOjycgPT4gJ8+OJywKICAnzpEnID0+ICfOsScsCiAgJ86SJyA9PiAnzrInLAogICfOkycgPT4gJ86zJywKICAnzpQnID0+ICfOtCcsCiAgJ86VJyA9PiAnzrUnLAogICfOlicgPT4gJ862JywKICAnzpcnID0+ICfOtycsCiAgJ86YJyA9PiAnzrgnLAogICfOmScgPT4gJ865JywKICAnzponID0+ICfOuicsCiAgJ86bJyA9PiAnzrsnLAogICfOnCcgPT4gJ868JywKICAnzp0nID0+ICfOvScsCiAgJ86eJyA9PiAnzr4nLAogICfOnycgPT4gJ86/JywKICAnzqAnID0+ICfPgCcsCiAgJ86hJyA9PiAnz4EnLAogICfOoycgPT4gJ8+DJywKICAnzqQnID0+ICfPhCcsCiAgJ86lJyA9PiAnz4UnLAogICfOpicgPT4gJ8+GJywKICAnzqcnID0+ICfPhycsCiAgJ86oJyA9PiAnz4gnLAogICfOqScgPT4gJ8+JJywKICAnzqonID0+ICfPiicsCiAgJ86rJyA9PiAnz4snLAogICfPjycgPT4gJ8+XJywKICAnz5gnID0+ICfPmScsCiAgJ8+aJyA9PiAnz5snLAogICfPnCcgPT4gJ8+dJywKICAnz54nID0+ICfPnycsCiAgJ8+gJyA9PiAnz6EnLAogICfPoicgPT4gJ8+jJywKICAnz6QnID0+ICfPpScsCiAgJ8+mJyA9PiAnz6cnLAogICfPqCcgPT4gJ8+pJywKICAnz6onID0+ICfPqycsCiAgJ8+sJyA9PiAnz60nLAogICfPricgPT4gJ8+vJywKICAnz7QnID0+ICfOuCcsCiAgJ8+3JyA9PiAnz7gnLAogICfPuScgPT4gJ8+yJywKICAnz7onID0+ICfPuycsCiAgJ8+9JyA9PiAnzbsnLAogICfPvicgPT4gJ828JywKICAnz78nID0+ICfNvScsCiAgJ9CAJyA9PiAn0ZAnLAogICfQgScgPT4gJ9GRJywKICAn0IInID0+ICfRkicsCiAgJ9CDJyA9PiAn0ZMnLAogICfQhCcgPT4gJ9GUJywKICAn0IUnID0+ICfRlScsCiAgJ9CGJyA9PiAn0ZYnLAogICfQhycgPT4gJ9GXJywKICAn0IgnID0+ICfRmCcsCiAgJ9CJJyA9PiAn0ZknLAogICfQiicgPT4gJ9GaJywKICAn0IsnID0+ICfRmycsCiAgJ9CMJyA9PiAn0ZwnLAogICfQjScgPT4gJ9GdJywKICAn0I4nID0+ICfRnicsCiAgJ9CPJyA9PiAn0Z8nLAogICfQkCcgPT4gJ9CwJywKICAn0JEnID0+ICfQsScsCiAgJ9CSJyA9PiAn0LInLAogICfQkycgPT4gJ9CzJywKICAn0JQnID0+ICfQtCcsCiAgJ9CVJyA9PiAn0LUnLAogICfQlicgPT4gJ9C2JywKICAn0JcnID0+ICfQtycsCiAgJ9CYJyA9PiAn0LgnLAogICfQmScgPT4gJ9C5JywKICAn0JonID0+ICfQuicsCiAgJ9CbJyA9PiAn0LsnLAogICfQnCcgPT4gJ9C8JywKICAn0J0nID0+ICfQvScsCiAgJ9CeJyA9PiAn0L4nLAogICfQnycgPT4gJ9C/JywKICAn0KAnID0+ICfRgCcsCiAgJ9ChJyA9PiAn0YEnLAogICfQoicgPT4gJ9GCJywKICAn0KMnID0+ICfRgycsCiAgJ9CkJyA9PiAn0YQnLAogICfQpScgPT4gJ9GFJywKICAn0KYnID0+ICfRhicsCiAgJ9CnJyA9PiAn0YcnLAogICfQqCcgPT4gJ9GIJywKICAn0KknID0+ICfRiScsCiAgJ9CqJyA9PiAn0YonLAogICfQqycgPT4gJ9GLJywKICAn0KwnID0+ICfRjCcsCiAgJ9CtJyA9PiAn0Y0nLAogICfQricgPT4gJ9GOJywKICAn0K8nID0+ICfRjycsCiAgJ9GgJyA9PiAn0aEnLAogICfRoicgPT4gJ9GjJywKICAn0aQnID0+ICfRpScsCiAgJ9GmJyA9PiAn0acnLAogICfRqCcgPT4gJ9GpJywKICAn0aonID0+ICfRqycsCiAgJ9GsJyA9PiAn0a0nLAogICfRricgPT4gJ9GvJywKICAn0bAnID0+ICfRsScsCiAgJ9GyJyA9PiAn0bMnLAogICfRtCcgPT4gJ9G1JywKICAn0bYnID0+ICfRtycsCiAgJ9G4JyA9PiAn0bknLAogICfRuicgPT4gJ9G7JywKICAn0bwnID0+ICfRvScsCiAgJ9G+JyA9PiAn0b8nLAogICfSgCcgPT4gJ9KBJywKICAn0oonID0+ICfSiycsCiAgJ9KMJyA9PiAn0o0nLAogICfSjicgPT4gJ9KPJywKICAn0pAnID0+ICfSkScsCiAgJ9KSJyA9PiAn0pMnLAogICfSlCcgPT4gJ9KVJywKICAn0pYnID0+ICfSlycsCiAgJ9KYJyA9PiAn0pknLAogICfSmicgPT4gJ9KbJywKICAn0pwnID0+ICfSnScsCiAgJ9KeJyA9PiAn0p8nLAogICfSoCcgPT4gJ9KhJywKICAn0qInID0+ICfSoycsCiAgJ9KkJyA9PiAn0qUnLAogICfSpicgPT4gJ9KnJywKICAn0qgnID0+ICfSqScsCiAgJ9KqJyA9PiAn0qsnLAogICfSrCcgPT4gJ9KtJywKICAn0q4nID0+ICfSrycsCiAgJ9KwJyA9PiAn0rEnLAogICfSsicgPT4gJ9KzJywKICAn0rQnID0+ICfStScsCiAgJ9K2JyA9PiAn0rcnLAogICfSuCcgPT4gJ9K5JywKICAn0ronID0+ICfSuycsCiAgJ9K8JyA9PiAn0r0nLAogICfSvicgPT4gJ9K/JywKICAn04AnID0+ICfTjycsCiAgJ9OBJyA9PiAn04InLAogICfTgycgPT4gJ9OEJywKICAn04UnID0+ICfThicsCiAgJ9OHJyA9PiAn04gnLAogICfTiScgPT4gJ9OKJywKICAn04snID0+ICfTjCcsCiAgJ9ONJyA9PiAn044nLAogICfTkCcgPT4gJ9ORJywKICAn05InID0+ICfTkycsCiAgJ9OUJyA9PiAn05UnLAogICfTlicgPT4gJ9OXJywKICAn05gnID0+ICfTmScsCiAgJ9OaJyA9PiAn05snLAogICfTnCcgPT4gJ9OdJywKICAn054nID0+ICfTnycsCiAgJ9OgJyA9PiAn06EnLAogICfToicgPT4gJ9OjJywKICAn06QnID0+ICfTpScsCiAgJ9OmJyA9PiAn06cnLAogICfTqCcgPT4gJ9OpJywKICAn06onID0+ICfTqycsCiAgJ9OsJyA9PiAn060nLAogICfTricgPT4gJ9OvJywKICAn07AnID0+ICfTsScsCiAgJ9OyJyA9PiAn07MnLAogICfTtCcgPT4gJ9O1JywKICAn07YnID0+ICfTtycsCiAgJ9O4JyA9PiAn07knLAogICfTuicgPT4gJ9O7JywKICAn07wnID0+ICfTvScsCiAgJ9O+JyA9PiAn078nLAogICfUgCcgPT4gJ9SBJywKICAn1IInID0+ICfUgycsCiAgJ9SEJyA9PiAn1IUnLAogICfUhicgPT4gJ9SHJywKICAn1IgnID0+ICfUiScsCiAgJ9SKJyA9PiAn1IsnLAogICfUjCcgPT4gJ9SNJywKICAn1I4nID0+ICfUjycsCiAgJ9SQJyA9PiAn1JEnLAogICfUkicgPT4gJ9STJywKICAn1JQnID0+ICfUlScsCiAgJ9SWJyA9PiAn1JcnLAogICfUmCcgPT4gJ9SZJywKICAn1JonID0+ICfUmycsCiAgJ9ScJyA9PiAn1J0nLAogICfUnicgPT4gJ9SfJywKICAn1KAnID0+ICfUoScsCiAgJ9SiJyA9PiAn1KMnLAogICfUpCcgPT4gJ9SlJywKICAn1KYnID0+ICfUpycsCiAgJ9SoJyA9PiAn1KknLAogICfUqicgPT4gJ9SrJywKICAn1KwnID0+ICfUrScsCiAgJ9SuJyA9PiAn1K8nLAogICfUsScgPT4gJ9WhJywKICAn1LInID0+ICfVoicsCiAgJ9SzJyA9PiAn1aMnLAogICfUtCcgPT4gJ9WkJywKICAn1LUnID0+ICfVpScsCiAgJ9S2JyA9PiAn1aYnLAogICfUtycgPT4gJ9WnJywKICAn1LgnID0+ICfVqCcsCiAgJ9S5JyA9PiAn1aknLAogICfUuicgPT4gJ9WqJywKICAn1LsnID0+ICfVqycsCiAgJ9S8JyA9PiAn1awnLAogICfUvScgPT4gJ9WtJywKICAn1L4nID0+ICfVricsCiAgJ9S/JyA9PiAn1a8nLAogICfVgCcgPT4gJ9WwJywKICAn1YEnID0+ICfVsScsCiAgJ9WCJyA9PiAn1bInLAogICfVgycgPT4gJ9WzJywKICAn1YQnID0+ICfVtCcsCiAgJ9WFJyA9PiAn1bUnLAogICfVhicgPT4gJ9W2JywKICAn1YcnID0+ICfVtycsCiAgJ9WIJyA9PiAn1bgnLAogICfViScgPT4gJ9W5JywKICAn1YonID0+ICfVuicsCiAgJ9WLJyA9PiAn1bsnLAogICfVjCcgPT4gJ9W8JywKICAn1Y0nID0+ICfVvScsCiAgJ9WOJyA9PiAn1b4nLAogICfVjycgPT4gJ9W/JywKICAn1ZAnID0+ICfWgCcsCiAgJ9WRJyA9PiAn1oEnLAogICfVkicgPT4gJ9aCJywKICAn1ZMnID0+ICfWgycsCiAgJ9WUJyA9PiAn1oQnLAogICfVlScgPT4gJ9aFJywKICAn1ZYnID0+ICfWhicsCiAgJ+GCoCcgPT4gJ+K0gCcsCiAgJ+GCoScgPT4gJ+K0gScsCiAgJ+GCoicgPT4gJ+K0gicsCiAgJ+GCoycgPT4gJ+K0gycsCiAgJ+GCpCcgPT4gJ+K0hCcsCiAgJ+GCpScgPT4gJ+K0hScsCiAgJ+GCpicgPT4gJ+K0hicsCiAgJ+GCpycgPT4gJ+K0hycsCiAgJ+GCqCcgPT4gJ+K0iCcsCiAgJ+GCqScgPT4gJ+K0iScsCiAgJ+GCqicgPT4gJ+K0iicsCiAgJ+GCqycgPT4gJ+K0iycsCiAgJ+GCrCcgPT4gJ+K0jCcsCiAgJ+GCrScgPT4gJ+K0jScsCiAgJ+GCricgPT4gJ+K0jicsCiAgJ+GCrycgPT4gJ+K0jycsCiAgJ+GCsCcgPT4gJ+K0kCcsCiAgJ+GCsScgPT4gJ+K0kScsCiAgJ+GCsicgPT4gJ+K0kicsCiAgJ+GCsycgPT4gJ+K0kycsCiAgJ+GCtCcgPT4gJ+K0lCcsCiAgJ+GCtScgPT4gJ+K0lScsCiAgJ+GCticgPT4gJ+K0licsCiAgJ+GCtycgPT4gJ+K0lycsCiAgJ+GCuCcgPT4gJ+K0mCcsCiAgJ+GCuScgPT4gJ+K0mScsCiAgJ+GCuicgPT4gJ+K0micsCiAgJ+GCuycgPT4gJ+K0mycsCiAgJ+GCvCcgPT4gJ+K0nCcsCiAgJ+GCvScgPT4gJ+K0nScsCiAgJ+GCvicgPT4gJ+K0nicsCiAgJ+GCvycgPT4gJ+K0nycsCiAgJ+GDgCcgPT4gJ+K0oCcsCiAgJ+GDgScgPT4gJ+K0oScsCiAgJ+GDgicgPT4gJ+K0oicsCiAgJ+GDgycgPT4gJ+K0oycsCiAgJ+GDhCcgPT4gJ+K0pCcsCiAgJ+GDhScgPT4gJ+K0pScsCiAgJ+GDhycgPT4gJ+K0pycsCiAgJ+GDjScgPT4gJ+K0rScsCiAgJ+GOoCcgPT4gJ+qtsCcsCiAgJ+GOoScgPT4gJ+qtsScsCiAgJ+GOoicgPT4gJ+qtsicsCiAgJ+GOoycgPT4gJ+qtsycsCiAgJ+GOpCcgPT4gJ+qttCcsCiAgJ+GOpScgPT4gJ+qttScsCiAgJ+GOpicgPT4gJ+qtticsCiAgJ+GOpycgPT4gJ+qttycsCiAgJ+GOqCcgPT4gJ+qtuCcsCiAgJ+GOqScgPT4gJ+qtuScsCiAgJ+GOqicgPT4gJ+qtuicsCiAgJ+GOqycgPT4gJ+qtuycsCiAgJ+GOrCcgPT4gJ+qtvCcsCiAgJ+GOrScgPT4gJ+qtvScsCiAgJ+GOricgPT4gJ+qtvicsCiAgJ+GOrycgPT4gJ+qtvycsCiAgJ+GOsCcgPT4gJ+qugCcsCiAgJ+GOsScgPT4gJ+qugScsCiAgJ+GOsicgPT4gJ+qugicsCiAgJ+GOsycgPT4gJ+qugycsCiAgJ+GOtCcgPT4gJ+quhCcsCiAgJ+GOtScgPT4gJ+quhScsCiAgJ+GOticgPT4gJ+quhicsCiAgJ+GOtycgPT4gJ+quhycsCiAgJ+GOuCcgPT4gJ+quiCcsCiAgJ+GOuScgPT4gJ+quiScsCiAgJ+GOuicgPT4gJ+quiicsCiAgJ+GOuycgPT4gJ+quiycsCiAgJ+GOvCcgPT4gJ+qujCcsCiAgJ+GOvScgPT4gJ+qujScsCiAgJ+GOvicgPT4gJ+qujicsCiAgJ+GOvycgPT4gJ+qujycsCiAgJ+GPgCcgPT4gJ+qukCcsCiAgJ+GPgScgPT4gJ+qukScsCiAgJ+GPgicgPT4gJ+qukicsCiAgJ+GPgycgPT4gJ+qukycsCiAgJ+GPhCcgPT4gJ+qulCcsCiAgJ+GPhScgPT4gJ+qulScsCiAgJ+GPhicgPT4gJ+qulicsCiAgJ+GPhycgPT4gJ+qulycsCiAgJ+GPiCcgPT4gJ+qumCcsCiAgJ+GPiScgPT4gJ+qumScsCiAgJ+GPiicgPT4gJ+qumicsCiAgJ+GPiycgPT4gJ+qumycsCiAgJ+GPjCcgPT4gJ+qunCcsCiAgJ+GPjScgPT4gJ+qunScsCiAgJ+GPjicgPT4gJ+qunicsCiAgJ+GPjycgPT4gJ+qunycsCiAgJ+GPkCcgPT4gJ+quoCcsCiAgJ+GPkScgPT4gJ+quoScsCiAgJ+GPkicgPT4gJ+quoicsCiAgJ+GPkycgPT4gJ+quoycsCiAgJ+GPlCcgPT4gJ+qupCcsCiAgJ+GPlScgPT4gJ+qupScsCiAgJ+GPlicgPT4gJ+qupicsCiAgJ+GPlycgPT4gJ+qupycsCiAgJ+GPmCcgPT4gJ+quqCcsCiAgJ+GPmScgPT4gJ+quqScsCiAgJ+GPmicgPT4gJ+quqicsCiAgJ+GPmycgPT4gJ+quqycsCiAgJ+GPnCcgPT4gJ+qurCcsCiAgJ+GPnScgPT4gJ+qurScsCiAgJ+GPnicgPT4gJ+quricsCiAgJ+GPnycgPT4gJ+qurycsCiAgJ+GPoCcgPT4gJ+qusCcsCiAgJ+GPoScgPT4gJ+qusScsCiAgJ+GPoicgPT4gJ+qusicsCiAgJ+GPoycgPT4gJ+qusycsCiAgJ+GPpCcgPT4gJ+qutCcsCiAgJ+GPpScgPT4gJ+qutScsCiAgJ+GPpicgPT4gJ+quticsCiAgJ+GPpycgPT4gJ+qutycsCiAgJ+GPqCcgPT4gJ+quuCcsCiAgJ+GPqScgPT4gJ+quuScsCiAgJ+GPqicgPT4gJ+quuicsCiAgJ+GPqycgPT4gJ+quuycsCiAgJ+GPrCcgPT4gJ+quvCcsCiAgJ+GPrScgPT4gJ+quvScsCiAgJ+GPricgPT4gJ+quvicsCiAgJ+GPrycgPT4gJ+quvycsCiAgJ+GPsCcgPT4gJ+GPuCcsCiAgJ+GPsScgPT4gJ+GPuScsCiAgJ+GPsicgPT4gJ+GPuicsCiAgJ+GPsycgPT4gJ+GPuycsCiAgJ+GPtCcgPT4gJ+GPvCcsCiAgJ+GPtScgPT4gJ+GPvScsCiAgJ+GykCcgPT4gJ+GDkCcsCiAgJ+GykScgPT4gJ+GDkScsCiAgJ+GykicgPT4gJ+GDkicsCiAgJ+GykycgPT4gJ+GDkycsCiAgJ+GylCcgPT4gJ+GDlCcsCiAgJ+GylScgPT4gJ+GDlScsCiAgJ+GylicgPT4gJ+GDlicsCiAgJ+GylycgPT4gJ+GDlycsCiAgJ+GymCcgPT4gJ+GDmCcsCiAgJ+GymScgPT4gJ+GDmScsCiAgJ+GymicgPT4gJ+GDmicsCiAgJ+GymycgPT4gJ+GDmycsCiAgJ+GynCcgPT4gJ+GDnCcsCiAgJ+GynScgPT4gJ+GDnScsCiAgJ+GynicgPT4gJ+GDnicsCiAgJ+GynycgPT4gJ+GDnycsCiAgJ+GyoCcgPT4gJ+GDoCcsCiAgJ+GyoScgPT4gJ+GDoScsCiAgJ+GyoicgPT4gJ+GDoicsCiAgJ+GyoycgPT4gJ+GDoycsCiAgJ+GypCcgPT4gJ+GDpCcsCiAgJ+GypScgPT4gJ+GDpScsCiAgJ+GypicgPT4gJ+GDpicsCiAgJ+GypycgPT4gJ+GDpycsCiAgJ+GyqCcgPT4gJ+GDqCcsCiAgJ+GyqScgPT4gJ+GDqScsCiAgJ+GyqicgPT4gJ+GDqicsCiAgJ+GyqycgPT4gJ+GDqycsCiAgJ+GyrCcgPT4gJ+GDrCcsCiAgJ+GyrScgPT4gJ+GDrScsCiAgJ+GyricgPT4gJ+GDricsCiAgJ+GyrycgPT4gJ+GDrycsCiAgJ+GysCcgPT4gJ+GDsCcsCiAgJ+GysScgPT4gJ+GDsScsCiAgJ+GysicgPT4gJ+GDsicsCiAgJ+GysycgPT4gJ+GDsycsCiAgJ+GytCcgPT4gJ+GDtCcsCiAgJ+GytScgPT4gJ+GDtScsCiAgJ+GyticgPT4gJ+GDticsCiAgJ+GytycgPT4gJ+GDtycsCiAgJ+GyuCcgPT4gJ+GDuCcsCiAgJ+GyuScgPT4gJ+GDuScsCiAgJ+GyuicgPT4gJ+GDuicsCiAgJ+GyvScgPT4gJ+GDvScsCiAgJ+GyvicgPT4gJ+GDvicsCiAgJ+GyvycgPT4gJ+GDvycsCiAgJ+G4gCcgPT4gJ+G4gScsCiAgJ+G4gicgPT4gJ+G4gycsCiAgJ+G4hCcgPT4gJ+G4hScsCiAgJ+G4hicgPT4gJ+G4hycsCiAgJ+G4iCcgPT4gJ+G4iScsCiAgJ+G4iicgPT4gJ+G4iycsCiAgJ+G4jCcgPT4gJ+G4jScsCiAgJ+G4jicgPT4gJ+G4jycsCiAgJ+G4kCcgPT4gJ+G4kScsCiAgJ+G4kicgPT4gJ+G4kycsCiAgJ+G4lCcgPT4gJ+G4lScsCiAgJ+G4licgPT4gJ+G4lycsCiAgJ+G4mCcgPT4gJ+G4mScsCiAgJ+G4micgPT4gJ+G4mycsCiAgJ+G4nCcgPT4gJ+G4nScsCiAgJ+G4nicgPT4gJ+G4nycsCiAgJ+G4oCcgPT4gJ+G4oScsCiAgJ+G4oicgPT4gJ+G4oycsCiAgJ+G4pCcgPT4gJ+G4pScsCiAgJ+G4picgPT4gJ+G4pycsCiAgJ+G4qCcgPT4gJ+G4qScsCiAgJ+G4qicgPT4gJ+G4qycsCiAgJ+G4rCcgPT4gJ+G4rScsCiAgJ+G4ricgPT4gJ+G4rycsCiAgJ+G4sCcgPT4gJ+G4sScsCiAgJ+G4sicgPT4gJ+G4sycsCiAgJ+G4tCcgPT4gJ+G4tScsCiAgJ+G4ticgPT4gJ+G4tycsCiAgJ+G4uCcgPT4gJ+G4uScsCiAgJ+G4uicgPT4gJ+G4uycsCiAgJ+G4vCcgPT4gJ+G4vScsCiAgJ+G4vicgPT4gJ+G4vycsCiAgJ+G5gCcgPT4gJ+G5gScsCiAgJ+G5gicgPT4gJ+G5gycsCiAgJ+G5hCcgPT4gJ+G5hScsCiAgJ+G5hicgPT4gJ+G5hycsCiAgJ+G5iCcgPT4gJ+G5iScsCiAgJ+G5iicgPT4gJ+G5iycsCiAgJ+G5jCcgPT4gJ+G5jScsCiAgJ+G5jicgPT4gJ+G5jycsCiAgJ+G5kCcgPT4gJ+G5kScsCiAgJ+G5kicgPT4gJ+G5kycsCiAgJ+G5lCcgPT4gJ+G5lScsCiAgJ+G5licgPT4gJ+G5lycsCiAgJ+G5mCcgPT4gJ+G5mScsCiAgJ+G5micgPT4gJ+G5mycsCiAgJ+G5nCcgPT4gJ+G5nScsCiAgJ+G5nicgPT4gJ+G5nycsCiAgJ+G5oCcgPT4gJ+G5oScsCiAgJ+G5oicgPT4gJ+G5oycsCiAgJ+G5pCcgPT4gJ+G5pScsCiAgJ+G5picgPT4gJ+G5pycsCiAgJ+G5qCcgPT4gJ+G5qScsCiAgJ+G5qicgPT4gJ+G5qycsCiAgJ+G5rCcgPT4gJ+G5rScsCiAgJ+G5ricgPT4gJ+G5rycsCiAgJ+G5sCcgPT4gJ+G5sScsCiAgJ+G5sicgPT4gJ+G5sycsCiAgJ+G5tCcgPT4gJ+G5tScsCiAgJ+G5ticgPT4gJ+G5tycsCiAgJ+G5uCcgPT4gJ+G5uScsCiAgJ+G5uicgPT4gJ+G5uycsCiAgJ+G5vCcgPT4gJ+G5vScsCiAgJ+G5vicgPT4gJ+G5vycsCiAgJ+G6gCcgPT4gJ+G6gScsCiAgJ+G6gicgPT4gJ+G6gycsCiAgJ+G6hCcgPT4gJ+G6hScsCiAgJ+G6hicgPT4gJ+G6hycsCiAgJ+G6iCcgPT4gJ+G6iScsCiAgJ+G6iicgPT4gJ+G6iycsCiAgJ+G6jCcgPT4gJ+G6jScsCiAgJ+G6jicgPT4gJ+G6jycsCiAgJ+G6kCcgPT4gJ+G6kScsCiAgJ+G6kicgPT4gJ+G6kycsCiAgJ+G6lCcgPT4gJ+G6lScsCiAgJ+G6nicgPT4gJ8OfJywKICAn4bqgJyA9PiAn4bqhJywKICAn4bqiJyA9PiAn4bqjJywKICAn4bqkJyA9PiAn4bqlJywKICAn4bqmJyA9PiAn4bqnJywKICAn4bqoJyA9PiAn4bqpJywKICAn4bqqJyA9PiAn4bqrJywKICAn4bqsJyA9PiAn4bqtJywKICAn4bquJyA9PiAn4bqvJywKICAn4bqwJyA9PiAn4bqxJywKICAn4bqyJyA9PiAn4bqzJywKICAn4bq0JyA9PiAn4bq1JywKICAn4bq2JyA9PiAn4bq3JywKICAn4bq4JyA9PiAn4bq5JywKICAn4bq6JyA9PiAn4bq7JywKICAn4bq8JyA9PiAn4bq9JywKICAn4bq+JyA9PiAn4bq/JywKICAn4buAJyA9PiAn4buBJywKICAn4buCJyA9PiAn4buDJywKICAn4buEJyA9PiAn4buFJywKICAn4buGJyA9PiAn4buHJywKICAn4buIJyA9PiAn4buJJywKICAn4buKJyA9PiAn4buLJywKICAn4buMJyA9PiAn4buNJywKICAn4buOJyA9PiAn4buPJywKICAn4buQJyA9PiAn4buRJywKICAn4buSJyA9PiAn4buTJywKICAn4buUJyA9PiAn4buVJywKICAn4buWJyA9PiAn4buXJywKICAn4buYJyA9PiAn4buZJywKICAn4buaJyA9PiAn4bubJywKICAn4bucJyA9PiAn4budJywKICAn4bueJyA9PiAn4bufJywKICAn4bugJyA9PiAn4buhJywKICAn4buiJyA9PiAn4bujJywKICAn4bukJyA9PiAn4bulJywKICAn4bumJyA9PiAn4bunJywKICAn4buoJyA9PiAn4bupJywKICAn4buqJyA9PiAn4burJywKICAn4busJyA9PiAn4butJywKICAn4buuJyA9PiAn4buvJywKICAn4buwJyA9PiAn4buxJywKICAn4buyJyA9PiAn4buzJywKICAn4bu0JyA9PiAn4bu1JywKICAn4bu2JyA9PiAn4bu3JywKICAn4bu4JyA9PiAn4bu5JywKICAn4bu6JyA9PiAn4bu7JywKICAn4bu8JyA9PiAn4bu9JywKICAn4bu+JyA9PiAn4bu/JywKICAn4byIJyA9PiAn4byAJywKICAn4byJJyA9PiAn4byBJywKICAn4byKJyA9PiAn4byCJywKICAn4byLJyA9PiAn4byDJywKICAn4byMJyA9PiAn4byEJywKICAn4byNJyA9PiAn4byFJywKICAn4byOJyA9PiAn4byGJywKICAn4byPJyA9PiAn4byHJywKICAn4byYJyA9PiAn4byQJywKICAn4byZJyA9PiAn4byRJywKICAn4byaJyA9PiAn4bySJywKICAn4bybJyA9PiAn4byTJywKICAn4bycJyA9PiAn4byUJywKICAn4bydJyA9PiAn4byVJywKICAn4byoJyA9PiAn4bygJywKICAn4bypJyA9PiAn4byhJywKICAn4byqJyA9PiAn4byiJywKICAn4byrJyA9PiAn4byjJywKICAn4bysJyA9PiAn4bykJywKICAn4bytJyA9PiAn4bylJywKICAn4byuJyA9PiAn4bymJywKICAn4byvJyA9PiAn4bynJywKICAn4by4JyA9PiAn4bywJywKICAn4by5JyA9PiAn4byxJywKICAn4by6JyA9PiAn4byyJywKICAn4by7JyA9PiAn4byzJywKICAn4by8JyA9PiAn4by0JywKICAn4by9JyA9PiAn4by1JywKICAn4by+JyA9PiAn4by2JywKICAn4by/JyA9PiAn4by3JywKICAn4b2IJyA9PiAn4b2AJywKICAn4b2JJyA9PiAn4b2BJywKICAn4b2KJyA9PiAn4b2CJywKICAn4b2LJyA9PiAn4b2DJywKICAn4b2MJyA9PiAn4b2EJywKICAn4b2NJyA9PiAn4b2FJywKICAn4b2ZJyA9PiAn4b2RJywKICAn4b2bJyA9PiAn4b2TJywKICAn4b2dJyA9PiAn4b2VJywKICAn4b2fJyA9PiAn4b2XJywKICAn4b2oJyA9PiAn4b2gJywKICAn4b2pJyA9PiAn4b2hJywKICAn4b2qJyA9PiAn4b2iJywKICAn4b2rJyA9PiAn4b2jJywKICAn4b2sJyA9PiAn4b2kJywKICAn4b2tJyA9PiAn4b2lJywKICAn4b2uJyA9PiAn4b2mJywKICAn4b2vJyA9PiAn4b2nJywKICAn4b6IJyA9PiAn4b6AJywKICAn4b6JJyA9PiAn4b6BJywKICAn4b6KJyA9PiAn4b6CJywKICAn4b6LJyA9PiAn4b6DJywKICAn4b6MJyA9PiAn4b6EJywKICAn4b6NJyA9PiAn4b6FJywKICAn4b6OJyA9PiAn4b6GJywKICAn4b6PJyA9PiAn4b6HJywKICAn4b6YJyA9PiAn4b6QJywKICAn4b6ZJyA9PiAn4b6RJywKICAn4b6aJyA9PiAn4b6SJywKICAn4b6bJyA9PiAn4b6TJywKICAn4b6cJyA9PiAn4b6UJywKICAn4b6dJyA9PiAn4b6VJywKICAn4b6eJyA9PiAn4b6WJywKICAn4b6fJyA9PiAn4b6XJywKICAn4b6oJyA9PiAn4b6gJywKICAn4b6pJyA9PiAn4b6hJywKICAn4b6qJyA9PiAn4b6iJywKICAn4b6rJyA9PiAn4b6jJywKICAn4b6sJyA9PiAn4b6kJywKICAn4b6tJyA9PiAn4b6lJywKICAn4b6uJyA9PiAn4b6mJywKICAn4b6vJyA9PiAn4b6nJywKICAn4b64JyA9PiAn4b6wJywKICAn4b65JyA9PiAn4b6xJywKICAn4b66JyA9PiAn4b2wJywKICAn4b67JyA9PiAn4b2xJywKICAn4b68JyA9PiAn4b6zJywKICAn4b+IJyA9PiAn4b2yJywKICAn4b+JJyA9PiAn4b2zJywKICAn4b+KJyA9PiAn4b20JywKICAn4b+LJyA9PiAn4b21JywKICAn4b+MJyA9PiAn4b+DJywKICAn4b+YJyA9PiAn4b+QJywKICAn4b+ZJyA9PiAn4b+RJywKICAn4b+aJyA9PiAn4b22JywKICAn4b+bJyA9PiAn4b23JywKICAn4b+oJyA9PiAn4b+gJywKICAn4b+pJyA9PiAn4b+hJywKICAn4b+qJyA9PiAn4b26JywKICAn4b+rJyA9PiAn4b27JywKICAn4b+sJyA9PiAn4b+lJywKICAn4b+4JyA9PiAn4b24JywKICAn4b+5JyA9PiAn4b25JywKICAn4b+6JyA9PiAn4b28JywKICAn4b+7JyA9PiAn4b29JywKICAn4b+8JyA9PiAn4b+zJywKICAn4oSmJyA9PiAnz4knLAogICfihKonID0+ICdrJywKICAn4oSrJyA9PiAnw6UnLAogICfihLInID0+ICfihY4nLAogICfihaAnID0+ICfihbAnLAogICfihaEnID0+ICfihbEnLAogICfihaInID0+ICfihbInLAogICfihaMnID0+ICfihbMnLAogICfihaQnID0+ICfihbQnLAogICfihaUnID0+ICfihbUnLAogICfihaYnID0+ICfihbYnLAogICfihacnID0+ICfihbcnLAogICfihagnID0+ICfihbgnLAogICfihaknID0+ICfihbknLAogICfihaonID0+ICfihbonLAogICfihasnID0+ICfihbsnLAogICfihawnID0+ICfihbwnLAogICfiha0nID0+ICfihb0nLAogICfiha4nID0+ICfihb4nLAogICfiha8nID0+ICfihb8nLAogICfihoMnID0+ICfihoQnLAogICfikrYnID0+ICfik5AnLAogICfikrcnID0+ICfik5EnLAogICfikrgnID0+ICfik5InLAogICfikrknID0+ICfik5MnLAogICfikronID0+ICfik5QnLAogICfikrsnID0+ICfik5UnLAogICfikrwnID0+ICfik5YnLAogICfikr0nID0+ICfik5cnLAogICfikr4nID0+ICfik5gnLAogICfikr8nID0+ICfik5knLAogICfik4AnID0+ICfik5onLAogICfik4EnID0+ICfik5snLAogICfik4InID0+ICfik5wnLAogICfik4MnID0+ICfik50nLAogICfik4QnID0+ICfik54nLAogICfik4UnID0+ICfik58nLAogICfik4YnID0+ICfik6AnLAogICfik4cnID0+ICfik6EnLAogICfik4gnID0+ICfik6InLAogICfik4knID0+ICfik6MnLAogICfik4onID0+ICfik6QnLAogICfik4snID0+ICfik6UnLAogICfik4wnID0+ICfik6YnLAogICfik40nID0+ICfik6cnLAogICfik44nID0+ICfik6gnLAogICfik48nID0+ICfik6knLAogICfisIAnID0+ICfisLAnLAogICfisIEnID0+ICfisLEnLAogICfisIInID0+ICfisLInLAogICfisIMnID0+ICfisLMnLAogICfisIQnID0+ICfisLQnLAogICfisIUnID0+ICfisLUnLAogICfisIYnID0+ICfisLYnLAogICfisIcnID0+ICfisLcnLAogICfisIgnID0+ICfisLgnLAogICfisIknID0+ICfisLknLAogICfisIonID0+ICfisLonLAogICfisIsnID0+ICfisLsnLAogICfisIwnID0+ICfisLwnLAogICfisI0nID0+ICfisL0nLAogICfisI4nID0+ICfisL4nLAogICfisI8nID0+ICfisL8nLAogICfisJAnID0+ICfisYAnLAogICfisJEnID0+ICfisYEnLAogICfisJInID0+ICfisYInLAogICfisJMnID0+ICfisYMnLAogICfisJQnID0+ICfisYQnLAogICfisJUnID0+ICfisYUnLAogICfisJYnID0+ICfisYYnLAogICfisJcnID0+ICfisYcnLAogICfisJgnID0+ICfisYgnLAogICfisJknID0+ICfisYknLAogICfisJonID0+ICfisYonLAogICfisJsnID0+ICfisYsnLAogICfisJwnID0+ICfisYwnLAogICfisJ0nID0+ICfisY0nLAogICfisJ4nID0+ICfisY4nLAogICfisJ8nID0+ICfisY8nLAogICfisKAnID0+ICfisZAnLAogICfisKEnID0+ICfisZEnLAogICfisKInID0+ICfisZInLAogICfisKMnID0+ICfisZMnLAogICfisKQnID0+ICfisZQnLAogICfisKUnID0+ICfisZUnLAogICfisKYnID0+ICfisZYnLAogICfisKcnID0+ICfisZcnLAogICfisKgnID0+ICfisZgnLAogICfisKknID0+ICfisZknLAogICfisKonID0+ICfisZonLAogICfisKsnID0+ICfisZsnLAogICfisKwnID0+ICfisZwnLAogICfisK0nID0+ICfisZ0nLAogICfisK4nID0+ICfisZ4nLAogICfisaAnID0+ICfisaEnLAogICfisaInID0+ICfJqycsCiAgJ+KxoycgPT4gJ+G1vScsCiAgJ+KxpCcgPT4gJ8m9JywKICAn4rGnJyA9PiAn4rGoJywKICAn4rGpJyA9PiAn4rGqJywKICAn4rGrJyA9PiAn4rGsJywKICAn4rGtJyA9PiAnyZEnLAogICfisa4nID0+ICfJsScsCiAgJ+KxrycgPT4gJ8mQJywKICAn4rGwJyA9PiAnyZInLAogICfisbInID0+ICfisbMnLAogICfisbUnID0+ICfisbYnLAogICfisb4nID0+ICfIvycsCiAgJ+KxvycgPT4gJ8mAJywKICAn4rKAJyA9PiAn4rKBJywKICAn4rKCJyA9PiAn4rKDJywKICAn4rKEJyA9PiAn4rKFJywKICAn4rKGJyA9PiAn4rKHJywKICAn4rKIJyA9PiAn4rKJJywKICAn4rKKJyA9PiAn4rKLJywKICAn4rKMJyA9PiAn4rKNJywKICAn4rKOJyA9PiAn4rKPJywKICAn4rKQJyA9PiAn4rKRJywKICAn4rKSJyA9PiAn4rKTJywKICAn4rKUJyA9PiAn4rKVJywKICAn4rKWJyA9PiAn4rKXJywKICAn4rKYJyA9PiAn4rKZJywKICAn4rKaJyA9PiAn4rKbJywKICAn4rKcJyA9PiAn4rKdJywKICAn4rKeJyA9PiAn4rKfJywKICAn4rKgJyA9PiAn4rKhJywKICAn4rKiJyA9PiAn4rKjJywKICAn4rKkJyA9PiAn4rKlJywKICAn4rKmJyA9PiAn4rKnJywKICAn4rKoJyA9PiAn4rKpJywKICAn4rKqJyA9PiAn4rKrJywKICAn4rKsJyA9PiAn4rKtJywKICAn4rKuJyA9PiAn4rKvJywKICAn4rKwJyA9PiAn4rKxJywKICAn4rKyJyA9PiAn4rKzJywKICAn4rK0JyA9PiAn4rK1JywKICAn4rK2JyA9PiAn4rK3JywKICAn4rK4JyA9PiAn4rK5JywKICAn4rK6JyA9PiAn4rK7JywKICAn4rK8JyA9PiAn4rK9JywKICAn4rK+JyA9PiAn4rK/JywKICAn4rOAJyA9PiAn4rOBJywKICAn4rOCJyA9PiAn4rODJywKICAn4rOEJyA9PiAn4rOFJywKICAn4rOGJyA9PiAn4rOHJywKICAn4rOIJyA9PiAn4rOJJywKICAn4rOKJyA9PiAn4rOLJywKICAn4rOMJyA9PiAn4rONJywKICAn4rOOJyA9PiAn4rOPJywKICAn4rOQJyA9PiAn4rORJywKICAn4rOSJyA9PiAn4rOTJywKICAn4rOUJyA9PiAn4rOVJywKICAn4rOWJyA9PiAn4rOXJywKICAn4rOYJyA9PiAn4rOZJywKICAn4rOaJyA9PiAn4rObJywKICAn4rOcJyA9PiAn4rOdJywKICAn4rOeJyA9PiAn4rOfJywKICAn4rOgJyA9PiAn4rOhJywKICAn4rOiJyA9PiAn4rOjJywKICAn4rOrJyA9PiAn4rOsJywKICAn4rOtJyA9PiAn4rOuJywKICAn4rOyJyA9PiAn4rOzJywKICAn6pmAJyA9PiAn6pmBJywKICAn6pmCJyA9PiAn6pmDJywKICAn6pmEJyA9PiAn6pmFJywKICAn6pmGJyA9PiAn6pmHJywKICAn6pmIJyA9PiAn6pmJJywKICAn6pmKJyA9PiAn6pmLJywKICAn6pmMJyA9PiAn6pmNJywKICAn6pmOJyA9PiAn6pmPJywKICAn6pmQJyA9PiAn6pmRJywKICAn6pmSJyA9PiAn6pmTJywKICAn6pmUJyA9PiAn6pmVJywKICAn6pmWJyA9PiAn6pmXJywKICAn6pmYJyA9PiAn6pmZJywKICAn6pmaJyA9PiAn6pmbJywKICAn6pmcJyA9PiAn6pmdJywKICAn6pmeJyA9PiAn6pmfJywKICAn6pmgJyA9PiAn6pmhJywKICAn6pmiJyA9PiAn6pmjJywKICAn6pmkJyA9PiAn6pmlJywKICAn6pmmJyA9PiAn6pmnJywKICAn6pmoJyA9PiAn6pmpJywKICAn6pmqJyA9PiAn6pmrJywKICAn6pmsJyA9PiAn6pmtJywKICAn6pqAJyA9PiAn6pqBJywKICAn6pqCJyA9PiAn6pqDJywKICAn6pqEJyA9PiAn6pqFJywKICAn6pqGJyA9PiAn6pqHJywKICAn6pqIJyA9PiAn6pqJJywKICAn6pqKJyA9PiAn6pqLJywKICAn6pqMJyA9PiAn6pqNJywKICAn6pqOJyA9PiAn6pqPJywKICAn6pqQJyA9PiAn6pqRJywKICAn6pqSJyA9PiAn6pqTJywKICAn6pqUJyA9PiAn6pqVJywKICAn6pqWJyA9PiAn6pqXJywKICAn6pqYJyA9PiAn6pqZJywKICAn6pqaJyA9PiAn6pqbJywKICAn6pyiJyA9PiAn6pyjJywKICAn6pykJyA9PiAn6pylJywKICAn6pymJyA9PiAn6pynJywKICAn6pyoJyA9PiAn6pypJywKICAn6pyqJyA9PiAn6pyrJywKICAn6pysJyA9PiAn6pytJywKICAn6pyuJyA9PiAn6pyvJywKICAn6pyyJyA9PiAn6pyzJywKICAn6py0JyA9PiAn6py1JywKICAn6py2JyA9PiAn6py3JywKICAn6py4JyA9PiAn6py5JywKICAn6py6JyA9PiAn6py7JywKICAn6py8JyA9PiAn6py9JywKICAn6py+JyA9PiAn6py/JywKICAn6p2AJyA9PiAn6p2BJywKICAn6p2CJyA9PiAn6p2DJywKICAn6p2EJyA9PiAn6p2FJywKICAn6p2GJyA9PiAn6p2HJywKICAn6p2IJyA9PiAn6p2JJywKICAn6p2KJyA9PiAn6p2LJywKICAn6p2MJyA9PiAn6p2NJywKICAn6p2OJyA9PiAn6p2PJywKICAn6p2QJyA9PiAn6p2RJywKICAn6p2SJyA9PiAn6p2TJywKICAn6p2UJyA9PiAn6p2VJywKICAn6p2WJyA9PiAn6p2XJywKICAn6p2YJyA9PiAn6p2ZJywKICAn6p2aJyA9PiAn6p2bJywKICAn6p2cJyA9PiAn6p2dJywKICAn6p2eJyA9PiAn6p2fJywKICAn6p2gJyA9PiAn6p2hJywKICAn6p2iJyA9PiAn6p2jJywKICAn6p2kJyA9PiAn6p2lJywKICAn6p2mJyA9PiAn6p2nJywKICAn6p2oJyA9PiAn6p2pJywKICAn6p2qJyA9PiAn6p2rJywKICAn6p2sJyA9PiAn6p2tJywKICAn6p2uJyA9PiAn6p2vJywKICAn6p25JyA9PiAn6p26JywKICAn6p27JyA9PiAn6p28JywKICAn6p29JyA9PiAn4bW5JywKICAn6p2+JyA9PiAn6p2/JywKICAn6p6AJyA9PiAn6p6BJywKICAn6p6CJyA9PiAn6p6DJywKICAn6p6EJyA9PiAn6p6FJywKICAn6p6GJyA9PiAn6p6HJywKICAn6p6LJyA9PiAn6p6MJywKICAn6p6NJyA9PiAnyaUnLAogICfqnpAnID0+ICfqnpEnLAogICfqnpInID0+ICfqnpMnLAogICfqnpYnID0+ICfqnpcnLAogICfqnpgnID0+ICfqnpknLAogICfqnponID0+ICfqnpsnLAogICfqnpwnID0+ICfqnp0nLAogICfqnp4nID0+ICfqnp8nLAogICfqnqAnID0+ICfqnqEnLAogICfqnqInID0+ICfqnqMnLAogICfqnqQnID0+ICfqnqUnLAogICfqnqYnID0+ICfqnqcnLAogICfqnqgnID0+ICfqnqknLAogICfqnqonID0+ICfJpicsCiAgJ+qeqycgPT4gJ8mcJywKICAn6p6sJyA9PiAnyaEnLAogICfqnq0nID0+ICfJrCcsCiAgJ+qericgPT4gJ8mqJywKICAn6p6wJyA9PiAnyp4nLAogICfqnrEnID0+ICfKhycsCiAgJ+qesicgPT4gJ8qdJywKICAn6p6zJyA9PiAn6q2TJywKICAn6p60JyA9PiAn6p61JywKICAn6p62JyA9PiAn6p63JywKICAn6p64JyA9PiAn6p65JywKICAn6p66JyA9PiAn6p67JywKICAn6p68JyA9PiAn6p69JywKICAn6p6+JyA9PiAn6p6/JywKICAn6p+CJyA9PiAn6p+DJywKICAn6p+EJyA9PiAn6p6UJywKICAn6p+FJyA9PiAnyoInLAogICfqn4YnID0+ICfhto4nLAogICfqn4cnID0+ICfqn4gnLAogICfqn4knID0+ICfqn4onLAogICfqn7UnID0+ICfqn7YnLAogICfvvKEnID0+ICfvvYEnLAogICfvvKInID0+ICfvvYInLAogICfvvKMnID0+ICfvvYMnLAogICfvvKQnID0+ICfvvYQnLAogICfvvKUnID0+ICfvvYUnLAogICfvvKYnID0+ICfvvYYnLAogICfvvKcnID0+ICfvvYcnLAogICfvvKgnID0+ICfvvYgnLAogICfvvKknID0+ICfvvYknLAogICfvvKonID0+ICfvvYonLAogICfvvKsnID0+ICfvvYsnLAogICfvvKwnID0+ICfvvYwnLAogICfvvK0nID0+ICfvvY0nLAogICfvvK4nID0+ICfvvY4nLAogICfvvK8nID0+ICfvvY8nLAogICfvvLAnID0+ICfvvZAnLAogICfvvLEnID0+ICfvvZEnLAogICfvvLInID0+ICfvvZInLAogICfvvLMnID0+ICfvvZMnLAogICfvvLQnID0+ICfvvZQnLAogICfvvLUnID0+ICfvvZUnLAogICfvvLYnID0+ICfvvZYnLAogICfvvLcnID0+ICfvvZcnLAogICfvvLgnID0+ICfvvZgnLAogICfvvLknID0+ICfvvZknLAogICfvvLonID0+ICfvvZonLAogICfwkJCAJyA9PiAn8JCQqCcsCiAgJ/CQkIEnID0+ICfwkJCpJywKICAn8JCQgicgPT4gJ/CQkKonLAogICfwkJCDJyA9PiAn8JCQqycsCiAgJ/CQkIQnID0+ICfwkJCsJywKICAn8JCQhScgPT4gJ/CQkK0nLAogICfwkJCGJyA9PiAn8JCQricsCiAgJ/CQkIcnID0+ICfwkJCvJywKICAn8JCQiCcgPT4gJ/CQkLAnLAogICfwkJCJJyA9PiAn8JCQsScsCiAgJ/CQkIonID0+ICfwkJCyJywKICAn8JCQiycgPT4gJ/CQkLMnLAogICfwkJCMJyA9PiAn8JCQtCcsCiAgJ/CQkI0nID0+ICfwkJC1JywKICAn8JCQjicgPT4gJ/CQkLYnLAogICfwkJCPJyA9PiAn8JCQtycsCiAgJ/CQkJAnID0+ICfwkJC4JywKICAn8JCQkScgPT4gJ/CQkLknLAogICfwkJCSJyA9PiAn8JCQuicsCiAgJ/CQkJMnID0+ICfwkJC7JywKICAn8JCQlCcgPT4gJ/CQkLwnLAogICfwkJCVJyA9PiAn8JCQvScsCiAgJ/CQkJYnID0+ICfwkJC+JywKICAn8JCQlycgPT4gJ/CQkL8nLAogICfwkJCYJyA9PiAn8JCRgCcsCiAgJ/CQkJknID0+ICfwkJGBJywKICAn8JCQmicgPT4gJ/CQkYInLAogICfwkJCbJyA9PiAn8JCRgycsCiAgJ/CQkJwnID0+ICfwkJGEJywKICAn8JCQnScgPT4gJ/CQkYUnLAogICfwkJCeJyA9PiAn8JCRhicsCiAgJ/CQkJ8nID0+ICfwkJGHJywKICAn8JCQoCcgPT4gJ/CQkYgnLAogICfwkJChJyA9PiAn8JCRiScsCiAgJ/CQkKInID0+ICfwkJGKJywKICAn8JCQoycgPT4gJ/CQkYsnLAogICfwkJCkJyA9PiAn8JCRjCcsCiAgJ/CQkKUnID0+ICfwkJGNJywKICAn8JCQpicgPT4gJ/CQkY4nLAogICfwkJCnJyA9PiAn8JCRjycsCiAgJ/CQkrAnID0+ICfwkJOYJywKICAn8JCSsScgPT4gJ/CQk5knLAogICfwkJKyJyA9PiAn8JCTmicsCiAgJ/CQkrMnID0+ICfwkJObJywKICAn8JCStCcgPT4gJ/CQk5wnLAogICfwkJK1JyA9PiAn8JCTnScsCiAgJ/CQkrYnID0+ICfwkJOeJywKICAn8JCStycgPT4gJ/CQk58nLAogICfwkJK4JyA9PiAn8JCToCcsCiAgJ/CQkrknID0+ICfwkJOhJywKICAn8JCSuicgPT4gJ/CQk6InLAogICfwkJK7JyA9PiAn8JCToycsCiAgJ/CQkrwnID0+ICfwkJOkJywKICAn8JCSvScgPT4gJ/CQk6UnLAogICfwkJK+JyA9PiAn8JCTpicsCiAgJ/CQkr8nID0+ICfwkJOnJywKICAn8JCTgCcgPT4gJ/CQk6gnLAogICfwkJOBJyA9PiAn8JCTqScsCiAgJ/CQk4InID0+ICfwkJOqJywKICAn8JCTgycgPT4gJ/CQk6snLAogICfwkJOEJyA9PiAn8JCTrCcsCiAgJ/CQk4UnID0+ICfwkJOtJywKICAn8JCThicgPT4gJ/CQk64nLAogICfwkJOHJyA9PiAn8JCTrycsCiAgJ/CQk4gnID0+ICfwkJOwJywKICAn8JCTiScgPT4gJ/CQk7EnLAogICfwkJOKJyA9PiAn8JCTsicsCiAgJ/CQk4snID0+ICfwkJOzJywKICAn8JCTjCcgPT4gJ/CQk7QnLAogICfwkJONJyA9PiAn8JCTtScsCiAgJ/CQk44nID0+ICfwkJO2JywKICAn8JCTjycgPT4gJ/CQk7cnLAogICfwkJOQJyA9PiAn8JCTuCcsCiAgJ/CQk5EnID0+ICfwkJO5JywKICAn8JCTkicgPT4gJ/CQk7onLAogICfwkJOTJyA9PiAn8JCTuycsCiAgJ/CQsoAnID0+ICfwkLOAJywKICAn8JCygScgPT4gJ/CQs4EnLAogICfwkLKCJyA9PiAn8JCzgicsCiAgJ/CQsoMnID0+ICfwkLODJywKICAn8JCyhCcgPT4gJ/CQs4QnLAogICfwkLKFJyA9PiAn8JCzhScsCiAgJ/CQsoYnID0+ICfwkLOGJywKICAn8JCyhycgPT4gJ/CQs4cnLAogICfwkLKIJyA9PiAn8JCziCcsCiAgJ/CQsoknID0+ICfwkLOJJywKICAn8JCyiicgPT4gJ/CQs4onLAogICfwkLKLJyA9PiAn8JCziycsCiAgJ/CQsownID0+ICfwkLOMJywKICAn8JCyjScgPT4gJ/CQs40nLAogICfwkLKOJyA9PiAn8JCzjicsCiAgJ/CQso8nID0+ICfwkLOPJywKICAn8JCykCcgPT4gJ/CQs5AnLAogICfwkLKRJyA9PiAn8JCzkScsCiAgJ/CQspInID0+ICfwkLOSJywKICAn8JCykycgPT4gJ/CQs5MnLAogICfwkLKUJyA9PiAn8JCzlCcsCiAgJ/CQspUnID0+ICfwkLOVJywKICAn8JCylicgPT4gJ/CQs5YnLAogICfwkLKXJyA9PiAn8JCzlycsCiAgJ/CQspgnID0+ICfwkLOYJywKICAn8JCymScgPT4gJ/CQs5knLAogICfwkLKaJyA9PiAn8JCzmicsCiAgJ/CQspsnID0+ICfwkLObJywKICAn8JCynCcgPT4gJ/CQs5wnLAogICfwkLKdJyA9PiAn8JCznScsCiAgJ/CQsp4nID0+ICfwkLOeJywKICAn8JCynycgPT4gJ/CQs58nLAogICfwkLKgJyA9PiAn8JCzoCcsCiAgJ/CQsqEnID0+ICfwkLOhJywKICAn8JCyoicgPT4gJ/CQs6InLAogICfwkLKjJyA9PiAn8JCzoycsCiAgJ/CQsqQnID0+ICfwkLOkJywKICAn8JCypScgPT4gJ/CQs6UnLAogICfwkLKmJyA9PiAn8JCzpicsCiAgJ/CQsqcnID0+ICfwkLOnJywKICAn8JCyqCcgPT4gJ/CQs6gnLAogICfwkLKpJyA9PiAn8JCzqScsCiAgJ/CQsqonID0+ICfwkLOqJywKICAn8JCyqycgPT4gJ/CQs6snLAogICfwkLKsJyA9PiAn8JCzrCcsCiAgJ/CQsq0nID0+ICfwkLOtJywKICAn8JCyricgPT4gJ/CQs64nLAogICfwkLKvJyA9PiAn8JCzrycsCiAgJ/CQsrAnID0+ICfwkLOwJywKICAn8JCysScgPT4gJ/CQs7EnLAogICfwkLKyJyA9PiAn8JCzsicsCiAgJ/CRoqAnID0+ICfwkaOAJywKICAn8JGioScgPT4gJ/CRo4EnLAogICfwkaKiJyA9PiAn8JGjgicsCiAgJ/CRoqMnID0+ICfwkaODJywKICAn8JGipCcgPT4gJ/CRo4QnLAogICfwkaKlJyA9PiAn8JGjhScsCiAgJ/CRoqYnID0+ICfwkaOGJywKICAn8JGipycgPT4gJ/CRo4cnLAogICfwkaKoJyA9PiAn8JGjiCcsCiAgJ/CRoqknID0+ICfwkaOJJywKICAn8JGiqicgPT4gJ/CRo4onLAogICfwkaKrJyA9PiAn8JGjiycsCiAgJ/CRoqwnID0+ICfwkaOMJywKICAn8JGirScgPT4gJ/CRo40nLAogICfwkaKuJyA9PiAn8JGjjicsCiAgJ/CRoq8nID0+ICfwkaOPJywKICAn8JGisCcgPT4gJ/CRo5AnLAogICfwkaKxJyA9PiAn8JGjkScsCiAgJ/CRorInID0+ICfwkaOSJywKICAn8JGisycgPT4gJ/CRo5MnLAogICfwkaK0JyA9PiAn8JGjlCcsCiAgJ/CRorUnID0+ICfwkaOVJywKICAn8JGiticgPT4gJ/CRo5YnLAogICfwkaK3JyA9PiAn8JGjlycsCiAgJ/CRorgnID0+ICfwkaOYJywKICAn8JGiuScgPT4gJ/CRo5knLAogICfwkaK6JyA9PiAn8JGjmicsCiAgJ/CRorsnID0+ICfwkaObJywKICAn8JGivCcgPT4gJ/CRo5wnLAogICfwkaK9JyA9PiAn8JGjnScsCiAgJ/CRor4nID0+ICfwkaOeJywKICAn8JGivycgPT4gJ/CRo58nLAogICfwlrmAJyA9PiAn8Ja5oCcsCiAgJ/CWuYEnID0+ICfwlrmhJywKICAn8Ja5gicgPT4gJ/CWuaInLAogICfwlrmDJyA9PiAn8Ja5oycsCiAgJ/CWuYQnID0+ICfwlrmkJywKICAn8Ja5hScgPT4gJ/CWuaUnLAogICfwlrmGJyA9PiAn8Ja5picsCiAgJ/CWuYcnID0+ICfwlrmnJywKICAn8Ja5iCcgPT4gJ/CWuagnLAogICfwlrmJJyA9PiAn8Ja5qScsCiAgJ/CWuYonID0+ICfwlrmqJywKICAn8Ja5iycgPT4gJ/CWuasnLAogICfwlrmMJyA9PiAn8Ja5rCcsCiAgJ/CWuY0nID0+ICfwlrmtJywKICAn8Ja5jicgPT4gJ/CWua4nLAogICfwlrmPJyA9PiAn8Ja5rycsCiAgJ/CWuZAnID0+ICfwlrmwJywKICAn8Ja5kScgPT4gJ/CWubEnLAogICfwlrmSJyA9PiAn8Ja5sicsCiAgJ/CWuZMnID0+ICfwlrmzJywKICAn8Ja5lCcgPT4gJ/CWubQnLAogICfwlrmVJyA9PiAn8Ja5tScsCiAgJ/CWuZYnID0+ICfwlrm2JywKICAn8Ja5lycgPT4gJ/CWubcnLAogICfwlrmYJyA9PiAn8Ja5uCcsCiAgJ/CWuZknID0+ICfwlrm5JywKICAn8Ja5micgPT4gJ/CWubonLAogICfwlrmbJyA9PiAn8Ja5uycsCiAgJ/CWuZwnID0+ICfwlrm8JywKICAn8Ja5nScgPT4gJ/CWub0nLAogICfwlrmeJyA9PiAn8Ja5vicsCiAgJ/CWuZ8nID0+ICfwlrm/JywKICAn8J6kgCcgPT4gJ/CepKInLAogICfwnqSBJyA9PiAn8J6koycsCiAgJ/CepIInID0+ICfwnqSkJywKICAn8J6kgycgPT4gJ/CepKUnLAogICfwnqSEJyA9PiAn8J6kpicsCiAgJ/CepIUnID0+ICfwnqSnJywKICAn8J6khicgPT4gJ/CepKgnLAogICfwnqSHJyA9PiAn8J6kqScsCiAgJ/CepIgnID0+ICfwnqSqJywKICAn8J6kiScgPT4gJ/CepKsnLAogICfwnqSKJyA9PiAn8J6krCcsCiAgJ/CepIsnID0+ICfwnqStJywKICAn8J6kjCcgPT4gJ/CepK4nLAogICfwnqSNJyA9PiAn8J6krycsCiAgJ/CepI4nID0+ICfwnqSwJywKICAn8J6kjycgPT4gJ/CepLEnLAogICfwnqSQJyA9PiAn8J6ksicsCiAgJ/CepJEnID0+ICfwnqSzJywKICAn8J6kkicgPT4gJ/CepLQnLAogICfwnqSTJyA9PiAn8J6ktScsCiAgJ/CepJQnID0+ICfwnqS2JywKICAn8J6klScgPT4gJ/CepLcnLAogICfwnqSWJyA9PiAn8J6kuCcsCiAgJ/CepJcnID0+ICfwnqS5JywKICAn8J6kmCcgPT4gJ/CepLonLAogICfwnqSZJyA9PiAn8J6kuycsCiAgJ/CepJonID0+ICfwnqS8JywKICAn8J6kmycgPT4gJ/CepL0nLAogICfwnqScJyA9PiAn8J6kvicsCiAgJ/CepJ0nID0+ICfwnqS/JywKICAn8J6knicgPT4gJ/CepYAnLAogICfwnqSfJyA9PiAn8J6lgScsCiAgJ/CepKAnID0+ICfwnqWCJywKICAn8J6koScgPT4gJ/CepYMnLAopOwo8P3BocAoKLy8gZnJvbSBDYXNlX0lnbm9yYWJsZSBpbiBodHRwczovL3VuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL0Rlcml2ZWRDb3JlUHJvcGVydGllcy50eHQKCnJldHVybiAnLyg/PCFbXHh7MDAyN31ceHswMDJFfVx4ezAwM0F9XHh7MDA1RX1ceHswMDYwfVx4ezAwQTh9XHh7MDBBRH1ceHswMEFGfVx4ezAwQjR9XHh7MDBCN31ceHswMEI4fVx4ezAyQjB9LVx4ezAyQzF9XHh7MDJDMn0tXHh7MDJDNX1ceHswMkM2fS1ceHswMkQxfVx4ezAyRDJ9LVx4ezAyREZ9XHh7MDJFMH0tXHh7MDJFNH1ceHswMkU1fS1ceHswMkVCfVx4ezAyRUN9XHh7MDJFRH1ceHswMkVFfVx4ezAyRUZ9LVx4ezAyRkZ9XHh7MDMwMH0tXHh7MDM2Rn1ceHswMzc0fVx4ezAzNzV9XHh7MDM3QX1ceHswMzg0fS1ceHswMzg1fVx4ezAzODd9XHh7MDQ4M30tXHh7MDQ4N31ceHswNDg4fS1ceHswNDg5fVx4ezA1NTl9XHh7MDU5MX0tXHh7MDVCRH1ceHswNUJGfVx4ezA1QzF9LVx4ezA1QzJ9XHh7MDVDNH0tXHh7MDVDNX1ceHswNUM3fVx4ezA1RjR9XHh7MDYwMH0tXHh7MDYwNX1ceHswNjEwfS1ceHswNjFBfVx4ezA2MUN9XHh7MDY0MH1ceHswNjRCfS1ceHswNjVGfVx4ezA2NzB9XHh7MDZENn0tXHh7MDZEQ31ceHswNkREfVx4ezA2REZ9LVx4ezA2RTR9XHh7MDZFNX0tXHh7MDZFNn1ceHswNkU3fS1ceHswNkU4fVx4ezA2RUF9LVx4ezA2RUR9XHh7MDcwRn1ceHswNzExfVx4ezA3MzB9LVx4ezA3NEF9XHh7MDdBNn0tXHh7MDdCMH1ceHswN0VCfS1ceHswN0YzfVx4ezA3RjR9LVx4ezA3RjV9XHh7MDdGQX1ceHswN0ZEfVx4ezA4MTZ9LVx4ezA4MTl9XHh7MDgxQX1ceHswODFCfS1ceHswODIzfVx4ezA4MjR9XHh7MDgyNX0tXHh7MDgyN31ceHswODI4fVx4ezA4Mjl9LVx4ezA4MkR9XHh7MDg1OX0tXHh7MDg1Qn1ceHswOEQzfS1ceHswOEUxfVx4ezA4RTJ9XHh7MDhFM30tXHh7MDkwMn1ceHswOTNBfVx4ezA5M0N9XHh7MDk0MX0tXHh7MDk0OH1ceHswOTREfVx4ezA5NTF9LVx4ezA5NTd9XHh7MDk2Mn0tXHh7MDk2M31ceHswOTcxfVx4ezA5ODF9XHh7MDlCQ31ceHswOUMxfS1ceHswOUM0fVx4ezA5Q0R9XHh7MDlFMn0tXHh7MDlFM31ceHswOUZFfVx4ezBBMDF9LVx4ezBBMDJ9XHh7MEEzQ31ceHswQTQxfS1ceHswQTQyfVx4ezBBNDd9LVx4ezBBNDh9XHh7MEE0Qn0tXHh7MEE0RH1ceHswQTUxfVx4ezBBNzB9LVx4ezBBNzF9XHh7MEE3NX1ceHswQTgxfS1ceHswQTgyfVx4ezBBQkN9XHh7MEFDMX0tXHh7MEFDNX1ceHswQUM3fS1ceHswQUM4fVx4ezBBQ0R9XHh7MEFFMn0tXHh7MEFFM31ceHswQUZBfS1ceHswQUZGfVx4ezBCMDF9XHh7MEIzQ31ceHswQjNGfVx4ezBCNDF9LVx4ezBCNDR9XHh7MEI0RH1ceHswQjU2fVx4ezBCNjJ9LVx4ezBCNjN9XHh7MEI4Mn1ceHswQkMwfVx4ezBCQ0R9XHh7MEMwMH1ceHswQzA0fVx4ezBDM0V9LVx4ezBDNDB9XHh7MEM0Nn0tXHh7MEM0OH1ceHswQzRBfS1ceHswQzREfVx4ezBDNTV9LVx4ezBDNTZ9XHh7MEM2Mn0tXHh7MEM2M31ceHswQzgxfVx4ezBDQkN9XHh7MENCRn1ceHswQ0M2fVx4ezBDQ0N9LVx4ezBDQ0R9XHh7MENFMn0tXHh7MENFM31ceHswRDAwfS1ceHswRDAxfVx4ezBEM0J9LVx4ezBEM0N9XHh7MEQ0MX0tXHh7MEQ0NH1ceHswRDREfVx4ezBENjJ9LVx4ezBENjN9XHh7MERDQX1ceHswREQyfS1ceHswREQ0fVx4ezBERDZ9XHh7MEUzMX1ceHswRTM0fS1ceHswRTNBfVx4ezBFNDZ9XHh7MEU0N30tXHh7MEU0RX1ceHswRUIxfVx4ezBFQjR9LVx4ezBFQjl9XHh7MEVCQn0tXHh7MEVCQ31ceHswRUM2fVx4ezBFQzh9LVx4ezBFQ0R9XHh7MEYxOH0tXHh7MEYxOX1ceHswRjM1fVx4ezBGMzd9XHh7MEYzOX1ceHswRjcxfS1ceHswRjdFfVx4ezBGODB9LVx4ezBGODR9XHh7MEY4Nn0tXHh7MEY4N31ceHswRjhEfS1ceHswRjk3fVx4ezBGOTl9LVx4ezBGQkN9XHh7MEZDNn1ceHsxMDJEfS1ceHsxMDMwfVx4ezEwMzJ9LVx4ezEwMzd9XHh7MTAzOX0tXHh7MTAzQX1ceHsxMDNEfS1ceHsxMDNFfVx4ezEwNTh9LVx4ezEwNTl9XHh7MTA1RX0tXHh7MTA2MH1ceHsxMDcxfS1ceHsxMDc0fVx4ezEwODJ9XHh7MTA4NX0tXHh7MTA4Nn1ceHsxMDhEfVx4ezEwOUR9XHh7MTBGQ31ceHsxMzVEfS1ceHsxMzVGfVx4ezE3MTJ9LVx4ezE3MTR9XHh7MTczMn0tXHh7MTczNH1ceHsxNzUyfS1ceHsxNzUzfVx4ezE3NzJ9LVx4ezE3NzN9XHh7MTdCNH0tXHh7MTdCNX1ceHsxN0I3fS1ceHsxN0JEfVx4ezE3QzZ9XHh7MTdDOX0tXHh7MTdEM31ceHsxN0Q3fVx4ezE3RER9XHh7MTgwQn0tXHh7MTgwRH1ceHsxODBFfVx4ezE4NDN9XHh7MTg4NX0tXHh7MTg4Nn1ceHsxOEE5fVx4ezE5MjB9LVx4ezE5MjJ9XHh7MTkyN30tXHh7MTkyOH1ceHsxOTMyfVx4ezE5Mzl9LVx4ezE5M0J9XHh7MUExN30tXHh7MUExOH1ceHsxQTFCfVx4ezFBNTZ9XHh7MUE1OH0tXHh7MUE1RX1ceHsxQTYwfVx4ezFBNjJ9XHh7MUE2NX0tXHh7MUE2Q31ceHsxQTczfS1ceHsxQTdDfVx4ezFBN0Z9XHh7MUFBN31ceHsxQUIwfS1ceHsxQUJEfVx4ezFBQkV9XHh7MUIwMH0tXHh7MUIwM31ceHsxQjM0fVx4ezFCMzZ9LVx4ezFCM0F9XHh7MUIzQ31ceHsxQjQyfVx4ezFCNkJ9LVx4ezFCNzN9XHh7MUI4MH0tXHh7MUI4MX1ceHsxQkEyfS1ceHsxQkE1fVx4ezFCQTh9LVx4ezFCQTl9XHh7MUJBQn0tXHh7MUJBRH1ceHsxQkU2fVx4ezFCRTh9LVx4ezFCRTl9XHh7MUJFRH1ceHsxQkVGfS1ceHsxQkYxfVx4ezFDMkN9LVx4ezFDMzN9XHh7MUMzNn0tXHh7MUMzN31ceHsxQzc4fS1ceHsxQzdEfVx4ezFDRDB9LVx4ezFDRDJ9XHh7MUNENH0tXHh7MUNFMH1ceHsxQ0UyfS1ceHsxQ0U4fVx4ezFDRUR9XHh7MUNGNH1ceHsxQ0Y4fS1ceHsxQ0Y5fVx4ezFEMkN9LVx4ezFENkF9XHh7MUQ3OH1ceHsxRDlCfS1ceHsxREJGfVx4ezFEQzB9LVx4ezFERjl9XHh7MURGQn0tXHh7MURGRn1ceHsxRkJEfVx4ezFGQkZ9LVx4ezFGQzF9XHh7MUZDRH0tXHh7MUZDRn1ceHsxRkREfS1ceHsxRkRGfVx4ezFGRUR9LVx4ezFGRUZ9XHh7MUZGRH0tXHh7MUZGRX1ceHsyMDBCfS1ceHsyMDBGfVx4ezIwMTh9XHh7MjAxOX1ceHsyMDI0fVx4ezIwMjd9XHh7MjAyQX0tXHh7MjAyRX1ceHsyMDYwfS1ceHsyMDY0fVx4ezIwNjZ9LVx4ezIwNkZ9XHh7MjA3MX1ceHsyMDdGfVx4ezIwOTB9LVx4ezIwOUN9XHh7MjBEMH0tXHh7MjBEQ31ceHsyMEREfS1ceHsyMEUwfVx4ezIwRTF9XHh7MjBFMn0tXHh7MjBFNH1ceHsyMEU1fS1ceHsyMEYwfVx4ezJDN0N9LVx4ezJDN0R9XHh7MkNFRn0tXHh7MkNGMX1ceHsyRDZGfVx4ezJEN0Z9XHh7MkRFMH0tXHh7MkRGRn1ceHsyRTJGfVx4ezMwMDV9XHh7MzAyQX0tXHh7MzAyRH1ceHszMDMxfS1ceHszMDM1fVx4ezMwM0J9XHh7MzA5OX0tXHh7MzA5QX1ceHszMDlCfS1ceHszMDlDfVx4ezMwOUR9LVx4ezMwOUV9XHh7MzBGQ30tXHh7MzBGRX1ceHtBMDE1fVx4e0E0Rjh9LVx4e0E0RkR9XHh7QTYwQ31ceHtBNjZGfVx4e0E2NzB9LVx4e0E2NzJ9XHh7QTY3NH0tXHh7QTY3RH1ceHtBNjdGfVx4e0E2OUN9LVx4e0E2OUR9XHh7QTY5RX0tXHh7QTY5Rn1ceHtBNkYwfS1ceHtBNkYxfVx4e0E3MDB9LVx4e0E3MTZ9XHh7QTcxN30tXHh7QTcxRn1ceHtBNzIwfS1ceHtBNzIxfVx4e0E3NzB9XHh7QTc4OH1ceHtBNzg5fS1ceHtBNzhBfVx4e0E3Rjh9LVx4e0E3Rjl9XHh7QTgwMn1ceHtBODA2fVx4e0E4MEJ9XHh7QTgyNX0tXHh7QTgyNn1ceHtBOEM0fS1ceHtBOEM1fVx4e0E4RTB9LVx4e0E4RjF9XHh7QThGRn1ceHtBOTI2fS1ceHtBOTJEfVx4e0E5NDd9LVx4e0E5NTF9XHh7QTk4MH0tXHh7QTk4Mn1ceHtBOUIzfVx4e0E5QjZ9LVx4e0E5Qjl9XHh7QTlCQ31ceHtBOUNGfVx4e0E5RTV9XHh7QTlFNn1ceHtBQTI5fS1ceHtBQTJFfVx4e0FBMzF9LVx4e0FBMzJ9XHh7QUEzNX0tXHh7QUEzNn1ceHtBQTQzfVx4e0FBNEN9XHh7QUE3MH1ceHtBQTdDfVx4e0FBQjB9XHh7QUFCMn0tXHh7QUFCNH1ceHtBQUI3fS1ceHtBQUI4fVx4e0FBQkV9LVx4e0FBQkZ9XHh7QUFDMX1ceHtBQUREfVx4e0FBRUN9LVx4e0FBRUR9XHh7QUFGM30tXHh7QUFGNH1ceHtBQUY2fVx4e0FCNUJ9XHh7QUI1Q30tXHh7QUI1Rn1ceHtBQkU1fVx4e0FCRTh9XHh7QUJFRH1ceHtGQjFFfVx4e0ZCQjJ9LVx4e0ZCQzF9XHh7RkUwMH0tXHh7RkUwRn1ceHtGRTEzfVx4e0ZFMjB9LVx4e0ZFMkZ9XHh7RkU1Mn1ceHtGRTU1fVx4e0ZFRkZ9XHh7RkYwN31ceHtGRjBFfVx4e0ZGMUF9XHh7RkYzRX1ceHtGRjQwfVx4e0ZGNzB9XHh7RkY5RX0tXHh7RkY5Rn1ceHtGRkUzfVx4e0ZGRjl9LVx4e0ZGRkJ9XHh7MTAxRkR9XHh7MTAyRTB9XHh7MTAzNzZ9LVx4ezEwMzdBfVx4ezEwQTAxfS1ceHsxMEEwM31ceHsxMEEwNX0tXHh7MTBBMDZ9XHh7MTBBMEN9LVx4ezEwQTBGfVx4ezEwQTM4fS1ceHsxMEEzQX1ceHsxMEEzRn1ceHsxMEFFNX0tXHh7MTBBRTZ9XHh7MTBEMjR9LVx4ezEwRDI3fVx4ezEwRjQ2fS1ceHsxMEY1MH1ceHsxMTAwMX1ceHsxMTAzOH0tXHh7MTEwNDZ9XHh7MTEwN0Z9LVx4ezExMDgxfVx4ezExMEIzfS1ceHsxMTBCNn1ceHsxMTBCOX0tXHh7MTEwQkF9XHh7MTEwQkR9XHh7MTEwQ0R9XHh7MTExMDB9LVx4ezExMTAyfVx4ezExMTI3fS1ceHsxMTEyQn1ceHsxMTEyRH0tXHh7MTExMzR9XHh7MTExNzN9XHh7MTExODB9LVx4ezExMTgxfVx4ezExMUI2fS1ceHsxMTFCRX1ceHsxMTFDOX0tXHh7MTExQ0N9XHh7MTEyMkZ9LVx4ezExMjMxfVx4ezExMjM0fVx4ezExMjM2fS1ceHsxMTIzN31ceHsxMTIzRX1ceHsxMTJERn1ceHsxMTJFM30tXHh7MTEyRUF9XHh7MTEzMDB9LVx4ezExMzAxfVx4ezExMzNCfS1ceHsxMTMzQ31ceHsxMTM0MH1ceHsxMTM2Nn0tXHh7MTEzNkN9XHh7MTEzNzB9LVx4ezExMzc0fVx4ezExNDM4fS1ceHsxMTQzRn1ceHsxMTQ0Mn0tXHh7MTE0NDR9XHh7MTE0NDZ9XHh7MTE0NUV9XHh7MTE0QjN9LVx4ezExNEI4fVx4ezExNEJBfVx4ezExNEJGfS1ceHsxMTRDMH1ceHsxMTRDMn0tXHh7MTE0QzN9XHh7MTE1QjJ9LVx4ezExNUI1fVx4ezExNUJDfS1ceHsxMTVCRH1ceHsxMTVCRn0tXHh7MTE1QzB9XHh7MTE1REN9LVx4ezExNUREfVx4ezExNjMzfS1ceHsxMTYzQX1ceHsxMTYzRH1ceHsxMTYzRn0tXHh7MTE2NDB9XHh7MTE2QUJ9XHh7MTE2QUR9XHh7MTE2QjB9LVx4ezExNkI1fVx4ezExNkI3fVx4ezExNzFEfS1ceHsxMTcxRn1ceHsxMTcyMn0tXHh7MTE3MjV9XHh7MTE3Mjd9LVx4ezExNzJCfVx4ezExODJGfS1ceHsxMTgzN31ceHsxMTgzOX0tXHh7MTE4M0F9XHh7MTFBMDF9LVx4ezExQTBBfVx4ezExQTMzfS1ceHsxMUEzOH1ceHsxMUEzQn0tXHh7MTFBM0V9XHh7MTFBNDd9XHh7MTFBNTF9LVx4ezExQTU2fVx4ezExQTU5fS1ceHsxMUE1Qn1ceHsxMUE4QX0tXHh7MTFBOTZ9XHh7MTFBOTh9LVx4ezExQTk5fVx4ezExQzMwfS1ceHsxMUMzNn1ceHsxMUMzOH0tXHh7MTFDM0R9XHh7MTFDM0Z9XHh7MTFDOTJ9LVx4ezExQ0E3fVx4ezExQ0FBfS1ceHsxMUNCMH1ceHsxMUNCMn0tXHh7MTFDQjN9XHh7MTFDQjV9LVx4ezExQ0I2fVx4ezExRDMxfS1ceHsxMUQzNn1ceHsxMUQzQX1ceHsxMUQzQ30tXHh7MTFEM0R9XHh7MTFEM0Z9LVx4ezExRDQ1fVx4ezExRDQ3fVx4ezExRDkwfS1ceHsxMUQ5MX1ceHsxMUQ5NX1ceHsxMUQ5N31ceHsxMUVGM30tXHh7MTFFRjR9XHh7MTZBRjB9LVx4ezE2QUY0fVx4ezE2QjMwfS1ceHsxNkIzNn1ceHsxNkI0MH0tXHh7MTZCNDN9XHh7MTZGOEZ9LVx4ezE2RjkyfVx4ezE2RjkzfS1ceHsxNkY5Rn1ceHsxNkZFMH0tXHh7MTZGRTF9XHh7MUJDOUR9LVx4ezFCQzlFfVx4ezFCQ0EwfS1ceHsxQkNBM31ceHsxRDE2N30tXHh7MUQxNjl9XHh7MUQxNzN9LVx4ezFEMTdBfVx4ezFEMTdCfS1ceHsxRDE4Mn1ceHsxRDE4NX0tXHh7MUQxOEJ9XHh7MUQxQUF9LVx4ezFEMUFEfVx4ezFEMjQyfS1ceHsxRDI0NH1ceHsxREEwMH0tXHh7MURBMzZ9XHh7MURBM0J9LVx4ezFEQTZDfVx4ezFEQTc1fVx4ezFEQTg0fVx4ezFEQTlCfS1ceHsxREE5Rn1ceHsxREFBMX0tXHh7MURBQUZ9XHh7MUUwMDB9LVx4ezFFMDA2fVx4ezFFMDA4fS1ceHsxRTAxOH1ceHsxRTAxQn0tXHh7MUUwMjF9XHh7MUUwMjN9LVx4ezFFMDI0fVx4ezFFMDI2fS1ceHsxRTAyQX1ceHsxRThEMH0tXHh7MUU4RDZ9XHh7MUU5NDR9LVx4ezFFOTRBfVx4ezFGM0ZCfS1ceHsxRjNGRn1ceHtFMDAwMX1ceHtFMDAyMH0tXHh7RTAwN0Z9XHh7RTAxMDB9LVx4e0UwMUVGfV0pKFxwTCkoXHBMKispL3UnOwo8P3BocAoKcmV0dXJuIGFycmF5ICgKICAnYScgPT4gJ0EnLAogICdiJyA9PiAnQicsCiAgJ2MnID0+ICdDJywKICAnZCcgPT4gJ0QnLAogICdlJyA9PiAnRScsCiAgJ2YnID0+ICdGJywKICAnZycgPT4gJ0cnLAogICdoJyA9PiAnSCcsCiAgJ2knID0+ICdJJywKICAnaicgPT4gJ0onLAogICdrJyA9PiAnSycsCiAgJ2wnID0+ICdMJywKICAnbScgPT4gJ00nLAogICduJyA9PiAnTicsCiAgJ28nID0+ICdPJywKICAncCcgPT4gJ1AnLAogICdxJyA9PiAnUScsCiAgJ3InID0+ICdSJywKICAncycgPT4gJ1MnLAogICd0JyA9PiAnVCcsCiAgJ3UnID0+ICdVJywKICAndicgPT4gJ1YnLAogICd3JyA9PiAnVycsCiAgJ3gnID0+ICdYJywKICAneScgPT4gJ1knLAogICd6JyA9PiAnWicsCiAgJ8K1JyA9PiAnzpwnLAogICfDoCcgPT4gJ8OAJywKICAnw6EnID0+ICfDgScsCiAgJ8OiJyA9PiAnw4InLAogICfDoycgPT4gJ8ODJywKICAnw6QnID0+ICfDhCcsCiAgJ8OlJyA9PiAnw4UnLAogICfDpicgPT4gJ8OGJywKICAnw6cnID0+ICfDhycsCiAgJ8OoJyA9PiAnw4gnLAogICfDqScgPT4gJ8OJJywKICAnw6onID0+ICfDiicsCiAgJ8OrJyA9PiAnw4snLAogICfDrCcgPT4gJ8OMJywKICAnw60nID0+ICfDjScsCiAgJ8OuJyA9PiAnw44nLAogICfDrycgPT4gJ8OPJywKICAnw7AnID0+ICfDkCcsCiAgJ8OxJyA9PiAnw5EnLAogICfDsicgPT4gJ8OSJywKICAnw7MnID0+ICfDkycsCiAgJ8O0JyA9PiAnw5QnLAogICfDtScgPT4gJ8OVJywKICAnw7YnID0+ICfDlicsCiAgJ8O4JyA9PiAnw5gnLAogICfDuScgPT4gJ8OZJywKICAnw7onID0+ICfDmicsCiAgJ8O7JyA9PiAnw5snLAogICfDvCcgPT4gJ8OcJywKICAnw70nID0+ICfDnScsCiAgJ8O+JyA9PiAnw54nLAogICfDvycgPT4gJ8W4JywKICAnxIEnID0+ICfEgCcsCiAgJ8SDJyA9PiAnxIInLAogICfEhScgPT4gJ8SEJywKICAnxIcnID0+ICfEhicsCiAgJ8SJJyA9PiAnxIgnLAogICfEiycgPT4gJ8SKJywKICAnxI0nID0+ICfEjCcsCiAgJ8SPJyA9PiAnxI4nLAogICfEkScgPT4gJ8SQJywKICAnxJMnID0+ICfEkicsCiAgJ8SVJyA9PiAnxJQnLAogICfElycgPT4gJ8SWJywKICAnxJknID0+ICfEmCcsCiAgJ8SbJyA9PiAnxJonLAogICfEnScgPT4gJ8ScJywKICAnxJ8nID0+ICfEnicsCiAgJ8ShJyA9PiAnxKAnLAogICfEoycgPT4gJ8SiJywKICAnxKUnID0+ICfEpCcsCiAgJ8SnJyA9PiAnxKYnLAogICfEqScgPT4gJ8SoJywKICAnxKsnID0+ICfEqicsCiAgJ8StJyA9PiAnxKwnLAogICfErycgPT4gJ8SuJywKICAnxLEnID0+ICdJJywKICAnxLMnID0+ICfEsicsCiAgJ8S1JyA9PiAnxLQnLAogICfEtycgPT4gJ8S2JywKICAnxLonID0+ICfEuScsCiAgJ8S8JyA9PiAnxLsnLAogICfEvicgPT4gJ8S9JywKICAnxYAnID0+ICfEvycsCiAgJ8WCJyA9PiAnxYEnLAogICfFhCcgPT4gJ8WDJywKICAnxYYnID0+ICfFhScsCiAgJ8WIJyA9PiAnxYcnLAogICfFiycgPT4gJ8WKJywKICAnxY0nID0+ICfFjCcsCiAgJ8WPJyA9PiAnxY4nLAogICfFkScgPT4gJ8WQJywKICAnxZMnID0+ICfFkicsCiAgJ8WVJyA9PiAnxZQnLAogICfFlycgPT4gJ8WWJywKICAnxZknID0+ICfFmCcsCiAgJ8WbJyA9PiAnxZonLAogICfFnScgPT4gJ8WcJywKICAnxZ8nID0+ICfFnicsCiAgJ8WhJyA9PiAnxaAnLAogICfFoycgPT4gJ8WiJywKICAnxaUnID0+ICfFpCcsCiAgJ8WnJyA9PiAnxaYnLAogICfFqScgPT4gJ8WoJywKICAnxasnID0+ICfFqicsCiAgJ8WtJyA9PiAnxawnLAogICfFrycgPT4gJ8WuJywKICAnxbEnID0+ICfFsCcsCiAgJ8WzJyA9PiAnxbInLAogICfFtScgPT4gJ8W0JywKICAnxbcnID0+ICfFticsCiAgJ8W6JyA9PiAnxbknLAogICfFvCcgPT4gJ8W7JywKICAnxb4nID0+ICfFvScsCiAgJ8W/JyA9PiAnUycsCiAgJ8aAJyA9PiAnyYMnLAogICfGgycgPT4gJ8aCJywKICAnxoUnID0+ICfGhCcsCiAgJ8aIJyA9PiAnxocnLAogICfGjCcgPT4gJ8aLJywKICAnxpInID0+ICfGkScsCiAgJ8aVJyA9PiAnx7YnLAogICfGmScgPT4gJ8aYJywKICAnxponID0+ICfIvScsCiAgJ8aeJyA9PiAnyKAnLAogICfGoScgPT4gJ8agJywKICAnxqMnID0+ICfGoicsCiAgJ8alJyA9PiAnxqQnLAogICfGqCcgPT4gJ8anJywKICAnxq0nID0+ICfGrCcsCiAgJ8awJyA9PiAnxq8nLAogICfGtCcgPT4gJ8azJywKICAnxrYnID0+ICfGtScsCiAgJ8a5JyA9PiAnxrgnLAogICfGvScgPT4gJ8a8JywKICAnxr8nID0+ICfHtycsCiAgJ8eFJyA9PiAnx4QnLAogICfHhicgPT4gJ8eEJywKICAnx4gnID0+ICfHhycsCiAgJ8eJJyA9PiAnx4cnLAogICfHiycgPT4gJ8eKJywKICAnx4wnID0+ICfHiicsCiAgJ8eOJyA9PiAnx40nLAogICfHkCcgPT4gJ8ePJywKICAnx5InID0+ICfHkScsCiAgJ8eUJyA9PiAnx5MnLAogICfHlicgPT4gJ8eVJywKICAnx5gnID0+ICfHlycsCiAgJ8eaJyA9PiAnx5knLAogICfHnCcgPT4gJ8ebJywKICAnx50nID0+ICfGjicsCiAgJ8efJyA9PiAnx54nLAogICfHoScgPT4gJ8egJywKICAnx6MnID0+ICfHoicsCiAgJ8elJyA9PiAnx6QnLAogICfHpycgPT4gJ8emJywKICAnx6knID0+ICfHqCcsCiAgJ8erJyA9PiAnx6onLAogICfHrScgPT4gJ8esJywKICAnx68nID0+ICfHricsCiAgJ8eyJyA9PiAnx7EnLAogICfHsycgPT4gJ8exJywKICAnx7UnID0+ICfHtCcsCiAgJ8e5JyA9PiAnx7gnLAogICfHuycgPT4gJ8e6JywKICAnx70nID0+ICfHvCcsCiAgJ8e/JyA9PiAnx74nLAogICfIgScgPT4gJ8iAJywKICAnyIMnID0+ICfIgicsCiAgJ8iFJyA9PiAnyIQnLAogICfIhycgPT4gJ8iGJywKICAnyIknID0+ICfIiCcsCiAgJ8iLJyA9PiAnyIonLAogICfIjScgPT4gJ8iMJywKICAnyI8nID0+ICfIjicsCiAgJ8iRJyA9PiAnyJAnLAogICfIkycgPT4gJ8iSJywKICAnyJUnID0+ICfIlCcsCiAgJ8iXJyA9PiAnyJYnLAogICfImScgPT4gJ8iYJywKICAnyJsnID0+ICfImicsCiAgJ8idJyA9PiAnyJwnLAogICfInycgPT4gJ8ieJywKICAnyKMnID0+ICfIoicsCiAgJ8ilJyA9PiAnyKQnLAogICfIpycgPT4gJ8imJywKICAnyKknID0+ICfIqCcsCiAgJ8irJyA9PiAnyKonLAogICfIrScgPT4gJ8isJywKICAnyK8nID0+ICfIricsCiAgJ8ixJyA9PiAnyLAnLAogICfIsycgPT4gJ8iyJywKICAnyLwnID0+ICfIuycsCiAgJ8i/JyA9PiAn4rG+JywKICAnyYAnID0+ICfisb8nLAogICfJgicgPT4gJ8mBJywKICAnyYcnID0+ICfJhicsCiAgJ8mJJyA9PiAnyYgnLAogICfJiycgPT4gJ8mKJywKICAnyY0nID0+ICfJjCcsCiAgJ8mPJyA9PiAnyY4nLAogICfJkCcgPT4gJ+KxrycsCiAgJ8mRJyA9PiAn4rGtJywKICAnyZInID0+ICfisbAnLAogICfJkycgPT4gJ8aBJywKICAnyZQnID0+ICfGhicsCiAgJ8mWJyA9PiAnxoknLAogICfJlycgPT4gJ8aKJywKICAnyZknID0+ICfGjycsCiAgJ8mbJyA9PiAnxpAnLAogICfJnCcgPT4gJ+qeqycsCiAgJ8mgJyA9PiAnxpMnLAogICfJoScgPT4gJ+qerCcsCiAgJ8mjJyA9PiAnxpQnLAogICfJpScgPT4gJ+qejScsCiAgJ8mmJyA9PiAn6p6qJywKICAnyagnID0+ICfGlycsCiAgJ8mpJyA9PiAnxpYnLAogICfJqicgPT4gJ+qericsCiAgJ8mrJyA9PiAn4rGiJywKICAnyawnID0+ICfqnq0nLAogICfJrycgPT4gJ8acJywKICAnybEnID0+ICfisa4nLAogICfJsicgPT4gJ8adJywKICAnybUnID0+ICfGnycsCiAgJ8m9JyA9PiAn4rGkJywKICAnyoAnID0+ICfGpicsCiAgJ8qCJyA9PiAn6p+FJywKICAnyoMnID0+ICfGqScsCiAgJ8qHJyA9PiAn6p6xJywKICAnyognID0+ICfGricsCiAgJ8qJJyA9PiAnyYQnLAogICfKiicgPT4gJ8axJywKICAnyosnID0+ICfGsicsCiAgJ8qMJyA9PiAnyYUnLAogICfKkicgPT4gJ8a3JywKICAnyp0nID0+ICfqnrInLAogICfKnicgPT4gJ+qesCcsCiAgJ82FJyA9PiAnzpknLAogICfNsScgPT4gJ82wJywKICAnzbMnID0+ICfNsicsCiAgJ823JyA9PiAnzbYnLAogICfNuycgPT4gJ8+9JywKICAnzbwnID0+ICfPvicsCiAgJ829JyA9PiAnz78nLAogICfOrCcgPT4gJ86GJywKICAnzq0nID0+ICfOiCcsCiAgJ86uJyA9PiAnzoknLAogICfOrycgPT4gJ86KJywKICAnzrEnID0+ICfOkScsCiAgJ86yJyA9PiAnzpInLAogICfOsycgPT4gJ86TJywKICAnzrQnID0+ICfOlCcsCiAgJ861JyA9PiAnzpUnLAogICfOticgPT4gJ86WJywKICAnzrcnID0+ICfOlycsCiAgJ864JyA9PiAnzpgnLAogICfOuScgPT4gJ86ZJywKICAnzronID0+ICfOmicsCiAgJ867JyA9PiAnzpsnLAogICfOvCcgPT4gJ86cJywKICAnzr0nID0+ICfOnScsCiAgJ86+JyA9PiAnzp4nLAogICfOvycgPT4gJ86fJywKICAnz4AnID0+ICfOoCcsCiAgJ8+BJyA9PiAnzqEnLAogICfPgicgPT4gJ86jJywKICAnz4MnID0+ICfOoycsCiAgJ8+EJyA9PiAnzqQnLAogICfPhScgPT4gJ86lJywKICAnz4YnID0+ICfOpicsCiAgJ8+HJyA9PiAnzqcnLAogICfPiCcgPT4gJ86oJywKICAnz4knID0+ICfOqScsCiAgJ8+KJyA9PiAnzqonLAogICfPiycgPT4gJ86rJywKICAnz4wnID0+ICfOjCcsCiAgJ8+NJyA9PiAnzo4nLAogICfPjicgPT4gJ86PJywKICAnz5AnID0+ICfOkicsCiAgJ8+RJyA9PiAnzpgnLAogICfPlScgPT4gJ86mJywKICAnz5YnID0+ICfOoCcsCiAgJ8+XJyA9PiAnz48nLAogICfPmScgPT4gJ8+YJywKICAnz5snID0+ICfPmicsCiAgJ8+dJyA9PiAnz5wnLAogICfPnycgPT4gJ8+eJywKICAnz6EnID0+ICfPoCcsCiAgJ8+jJyA9PiAnz6InLAogICfPpScgPT4gJ8+kJywKICAnz6cnID0+ICfPpicsCiAgJ8+pJyA9PiAnz6gnLAogICfPqycgPT4gJ8+qJywKICAnz60nID0+ICfPrCcsCiAgJ8+vJyA9PiAnz64nLAogICfPsCcgPT4gJ86aJywKICAnz7EnID0+ICfOoScsCiAgJ8+yJyA9PiAnz7knLAogICfPsycgPT4gJ82/JywKICAnz7UnID0+ICfOlScsCiAgJ8+4JyA9PiAnz7cnLAogICfPuycgPT4gJ8+6JywKICAn0LAnID0+ICfQkCcsCiAgJ9CxJyA9PiAn0JEnLAogICfQsicgPT4gJ9CSJywKICAn0LMnID0+ICfQkycsCiAgJ9C0JyA9PiAn0JQnLAogICfQtScgPT4gJ9CVJywKICAn0LYnID0+ICfQlicsCiAgJ9C3JyA9PiAn0JcnLAogICfQuCcgPT4gJ9CYJywKICAn0LknID0+ICfQmScsCiAgJ9C6JyA9PiAn0JonLAogICfQuycgPT4gJ9CbJywKICAn0LwnID0+ICfQnCcsCiAgJ9C9JyA9PiAn0J0nLAogICfQvicgPT4gJ9CeJywKICAn0L8nID0+ICfQnycsCiAgJ9GAJyA9PiAn0KAnLAogICfRgScgPT4gJ9ChJywKICAn0YInID0+ICfQoicsCiAgJ9GDJyA9PiAn0KMnLAogICfRhCcgPT4gJ9CkJywKICAn0YUnID0+ICfQpScsCiAgJ9GGJyA9PiAn0KYnLAogICfRhycgPT4gJ9CnJywKICAn0YgnID0+ICfQqCcsCiAgJ9GJJyA9PiAn0KknLAogICfRiicgPT4gJ9CqJywKICAn0YsnID0+ICfQqycsCiAgJ9GMJyA9PiAn0KwnLAogICfRjScgPT4gJ9CtJywKICAn0Y4nID0+ICfQricsCiAgJ9GPJyA9PiAn0K8nLAogICfRkCcgPT4gJ9CAJywKICAn0ZEnID0+ICfQgScsCiAgJ9GSJyA9PiAn0IInLAogICfRkycgPT4gJ9CDJywKICAn0ZQnID0+ICfQhCcsCiAgJ9GVJyA9PiAn0IUnLAogICfRlicgPT4gJ9CGJywKICAn0ZcnID0+ICfQhycsCiAgJ9GYJyA9PiAn0IgnLAogICfRmScgPT4gJ9CJJywKICAn0ZonID0+ICfQiicsCiAgJ9GbJyA9PiAn0IsnLAogICfRnCcgPT4gJ9CMJywKICAn0Z0nID0+ICfQjScsCiAgJ9GeJyA9PiAn0I4nLAogICfRnycgPT4gJ9CPJywKICAn0aEnID0+ICfRoCcsCiAgJ9GjJyA9PiAn0aInLAogICfRpScgPT4gJ9GkJywKICAn0acnID0+ICfRpicsCiAgJ9GpJyA9PiAn0agnLAogICfRqycgPT4gJ9GqJywKICAn0a0nID0+ICfRrCcsCiAgJ9GvJyA9PiAn0a4nLAogICfRsScgPT4gJ9GwJywKICAn0bMnID0+ICfRsicsCiAgJ9G1JyA9PiAn0bQnLAogICfRtycgPT4gJ9G2JywKICAn0bknID0+ICfRuCcsCiAgJ9G7JyA9PiAn0bonLAogICfRvScgPT4gJ9G8JywKICAn0b8nID0+ICfRvicsCiAgJ9KBJyA9PiAn0oAnLAogICfSiycgPT4gJ9KKJywKICAn0o0nID0+ICfSjCcsCiAgJ9KPJyA9PiAn0o4nLAogICfSkScgPT4gJ9KQJywKICAn0pMnID0+ICfSkicsCiAgJ9KVJyA9PiAn0pQnLAogICfSlycgPT4gJ9KWJywKICAn0pknID0+ICfSmCcsCiAgJ9KbJyA9PiAn0ponLAogICfSnScgPT4gJ9KcJywKICAn0p8nID0+ICfSnicsCiAgJ9KhJyA9PiAn0qAnLAogICfSoycgPT4gJ9KiJywKICAn0qUnID0+ICfSpCcsCiAgJ9KnJyA9PiAn0qYnLAogICfSqScgPT4gJ9KoJywKICAn0qsnID0+ICfSqicsCiAgJ9KtJyA9PiAn0qwnLAogICfSrycgPT4gJ9KuJywKICAn0rEnID0+ICfSsCcsCiAgJ9KzJyA9PiAn0rInLAogICfStScgPT4gJ9K0JywKICAn0rcnID0+ICfSticsCiAgJ9K5JyA9PiAn0rgnLAogICfSuycgPT4gJ9K6JywKICAn0r0nID0+ICfSvCcsCiAgJ9K/JyA9PiAn0r4nLAogICfTgicgPT4gJ9OBJywKICAn04QnID0+ICfTgycsCiAgJ9OGJyA9PiAn04UnLAogICfTiCcgPT4gJ9OHJywKICAn04onID0+ICfTiScsCiAgJ9OMJyA9PiAn04snLAogICfTjicgPT4gJ9ONJywKICAn048nID0+ICfTgCcsCiAgJ9ORJyA9PiAn05AnLAogICfTkycgPT4gJ9OSJywKICAn05UnID0+ICfTlCcsCiAgJ9OXJyA9PiAn05YnLAogICfTmScgPT4gJ9OYJywKICAn05snID0+ICfTmicsCiAgJ9OdJyA9PiAn05wnLAogICfTnycgPT4gJ9OeJywKICAn06EnID0+ICfToCcsCiAgJ9OjJyA9PiAn06InLAogICfTpScgPT4gJ9OkJywKICAn06cnID0+ICfTpicsCiAgJ9OpJyA9PiAn06gnLAogICfTqycgPT4gJ9OqJywKICAn060nID0+ICfTrCcsCiAgJ9OvJyA9PiAn064nLAogICfTsScgPT4gJ9OwJywKICAn07MnID0+ICfTsicsCiAgJ9O1JyA9PiAn07QnLAogICfTtycgPT4gJ9O2JywKICAn07knID0+ICfTuCcsCiAgJ9O7JyA9PiAn07onLAogICfTvScgPT4gJ9O8JywKICAn078nID0+ICfTvicsCiAgJ9SBJyA9PiAn1IAnLAogICfUgycgPT4gJ9SCJywKICAn1IUnID0+ICfUhCcsCiAgJ9SHJyA9PiAn1IYnLAogICfUiScgPT4gJ9SIJywKICAn1IsnID0+ICfUiicsCiAgJ9SNJyA9PiAn1IwnLAogICfUjycgPT4gJ9SOJywKICAn1JEnID0+ICfUkCcsCiAgJ9STJyA9PiAn1JInLAogICfUlScgPT4gJ9SUJywKICAn1JcnID0+ICfUlicsCiAgJ9SZJyA9PiAn1JgnLAogICfUmycgPT4gJ9SaJywKICAn1J0nID0+ICfUnCcsCiAgJ9SfJyA9PiAn1J4nLAogICfUoScgPT4gJ9SgJywKICAn1KMnID0+ICfUoicsCiAgJ9SlJyA9PiAn1KQnLAogICfUpycgPT4gJ9SmJywKICAn1KknID0+ICfUqCcsCiAgJ9SrJyA9PiAn1KonLAogICfUrScgPT4gJ9SsJywKICAn1K8nID0+ICfUricsCiAgJ9WhJyA9PiAn1LEnLAogICfVoicgPT4gJ9SyJywKICAn1aMnID0+ICfUsycsCiAgJ9WkJyA9PiAn1LQnLAogICfVpScgPT4gJ9S1JywKICAn1aYnID0+ICfUticsCiAgJ9WnJyA9PiAn1LcnLAogICfVqCcgPT4gJ9S4JywKICAn1aknID0+ICfUuScsCiAgJ9WqJyA9PiAn1LonLAogICfVqycgPT4gJ9S7JywKICAn1awnID0+ICfUvCcsCiAgJ9WtJyA9PiAn1L0nLAogICfVricgPT4gJ9S+JywKICAn1a8nID0+ICfUvycsCiAgJ9WwJyA9PiAn1YAnLAogICfVsScgPT4gJ9WBJywKICAn1bInID0+ICfVgicsCiAgJ9WzJyA9PiAn1YMnLAogICfVtCcgPT4gJ9WEJywKICAn1bUnID0+ICfVhScsCiAgJ9W2JyA9PiAn1YYnLAogICfVtycgPT4gJ9WHJywKICAn1bgnID0+ICfViCcsCiAgJ9W5JyA9PiAn1YknLAogICfVuicgPT4gJ9WKJywKICAn1bsnID0+ICfViycsCiAgJ9W8JyA9PiAn1YwnLAogICfVvScgPT4gJ9WNJywKICAn1b4nID0+ICfVjicsCiAgJ9W/JyA9PiAn1Y8nLAogICfWgCcgPT4gJ9WQJywKICAn1oEnID0+ICfVkScsCiAgJ9aCJyA9PiAn1ZInLAogICfWgycgPT4gJ9WTJywKICAn1oQnID0+ICfVlCcsCiAgJ9aFJyA9PiAn1ZUnLAogICfWhicgPT4gJ9WWJywKICAn4YOQJyA9PiAn4bKQJywKICAn4YORJyA9PiAn4bKRJywKICAn4YOSJyA9PiAn4bKSJywKICAn4YOTJyA9PiAn4bKTJywKICAn4YOUJyA9PiAn4bKUJywKICAn4YOVJyA9PiAn4bKVJywKICAn4YOWJyA9PiAn4bKWJywKICAn4YOXJyA9PiAn4bKXJywKICAn4YOYJyA9PiAn4bKYJywKICAn4YOZJyA9PiAn4bKZJywKICAn4YOaJyA9PiAn4bKaJywKICAn4YObJyA9PiAn4bKbJywKICAn4YOcJyA9PiAn4bKcJywKICAn4YOdJyA9PiAn4bKdJywKICAn4YOeJyA9PiAn4bKeJywKICAn4YOfJyA9PiAn4bKfJywKICAn4YOgJyA9PiAn4bKgJywKICAn4YOhJyA9PiAn4bKhJywKICAn4YOiJyA9PiAn4bKiJywKICAn4YOjJyA9PiAn4bKjJywKICAn4YOkJyA9PiAn4bKkJywKICAn4YOlJyA9PiAn4bKlJywKICAn4YOmJyA9PiAn4bKmJywKICAn4YOnJyA9PiAn4bKnJywKICAn4YOoJyA9PiAn4bKoJywKICAn4YOpJyA9PiAn4bKpJywKICAn4YOqJyA9PiAn4bKqJywKICAn4YOrJyA9PiAn4bKrJywKICAn4YOsJyA9PiAn4bKsJywKICAn4YOtJyA9PiAn4bKtJywKICAn4YOuJyA9PiAn4bKuJywKICAn4YOvJyA9PiAn4bKvJywKICAn4YOwJyA9PiAn4bKwJywKICAn4YOxJyA9PiAn4bKxJywKICAn4YOyJyA9PiAn4bKyJywKICAn4YOzJyA9PiAn4bKzJywKICAn4YO0JyA9PiAn4bK0JywKICAn4YO1JyA9PiAn4bK1JywKICAn4YO2JyA9PiAn4bK2JywKICAn4YO3JyA9PiAn4bK3JywKICAn4YO4JyA9PiAn4bK4JywKICAn4YO5JyA9PiAn4bK5JywKICAn4YO6JyA9PiAn4bK6JywKICAn4YO9JyA9PiAn4bK9JywKICAn4YO+JyA9PiAn4bK+JywKICAn4YO/JyA9PiAn4bK/JywKICAn4Y+4JyA9PiAn4Y+wJywKICAn4Y+5JyA9PiAn4Y+xJywKICAn4Y+6JyA9PiAn4Y+yJywKICAn4Y+7JyA9PiAn4Y+zJywKICAn4Y+8JyA9PiAn4Y+0JywKICAn4Y+9JyA9PiAn4Y+1JywKICAn4bKAJyA9PiAn0JInLAogICfhsoEnID0+ICfQlCcsCiAgJ+GygicgPT4gJ9CeJywKICAn4bKDJyA9PiAn0KEnLAogICfhsoQnID0+ICfQoicsCiAgJ+GyhScgPT4gJ9CiJywKICAn4bKGJyA9PiAn0KonLAogICfhsocnID0+ICfRoicsCiAgJ+GyiCcgPT4gJ+qZiicsCiAgJ+G1uScgPT4gJ+qdvScsCiAgJ+G1vScgPT4gJ+KxoycsCiAgJ+G2jicgPT4gJ+qfhicsCiAgJ+G4gScgPT4gJ+G4gCcsCiAgJ+G4gycgPT4gJ+G4gicsCiAgJ+G4hScgPT4gJ+G4hCcsCiAgJ+G4hycgPT4gJ+G4hicsCiAgJ+G4iScgPT4gJ+G4iCcsCiAgJ+G4iycgPT4gJ+G4iicsCiAgJ+G4jScgPT4gJ+G4jCcsCiAgJ+G4jycgPT4gJ+G4jicsCiAgJ+G4kScgPT4gJ+G4kCcsCiAgJ+G4kycgPT4gJ+G4kicsCiAgJ+G4lScgPT4gJ+G4lCcsCiAgJ+G4lycgPT4gJ+G4licsCiAgJ+G4mScgPT4gJ+G4mCcsCiAgJ+G4mycgPT4gJ+G4micsCiAgJ+G4nScgPT4gJ+G4nCcsCiAgJ+G4nycgPT4gJ+G4nicsCiAgJ+G4oScgPT4gJ+G4oCcsCiAgJ+G4oycgPT4gJ+G4oicsCiAgJ+G4pScgPT4gJ+G4pCcsCiAgJ+G4pycgPT4gJ+G4picsCiAgJ+G4qScgPT4gJ+G4qCcsCiAgJ+G4qycgPT4gJ+G4qicsCiAgJ+G4rScgPT4gJ+G4rCcsCiAgJ+G4rycgPT4gJ+G4ricsCiAgJ+G4sScgPT4gJ+G4sCcsCiAgJ+G4sycgPT4gJ+G4sicsCiAgJ+G4tScgPT4gJ+G4tCcsCiAgJ+G4tycgPT4gJ+G4ticsCiAgJ+G4uScgPT4gJ+G4uCcsCiAgJ+G4uycgPT4gJ+G4uicsCiAgJ+G4vScgPT4gJ+G4vCcsCiAgJ+G4vycgPT4gJ+G4vicsCiAgJ+G5gScgPT4gJ+G5gCcsCiAgJ+G5gycgPT4gJ+G5gicsCiAgJ+G5hScgPT4gJ+G5hCcsCiAgJ+G5hycgPT4gJ+G5hicsCiAgJ+G5iScgPT4gJ+G5iCcsCiAgJ+G5iycgPT4gJ+G5iicsCiAgJ+G5jScgPT4gJ+G5jCcsCiAgJ+G5jycgPT4gJ+G5jicsCiAgJ+G5kScgPT4gJ+G5kCcsCiAgJ+G5kycgPT4gJ+G5kicsCiAgJ+G5lScgPT4gJ+G5lCcsCiAgJ+G5lycgPT4gJ+G5licsCiAgJ+G5mScgPT4gJ+G5mCcsCiAgJ+G5mycgPT4gJ+G5micsCiAgJ+G5nScgPT4gJ+G5nCcsCiAgJ+G5nycgPT4gJ+G5nicsCiAgJ+G5oScgPT4gJ+G5oCcsCiAgJ+G5oycgPT4gJ+G5oicsCiAgJ+G5pScgPT4gJ+G5pCcsCiAgJ+G5pycgPT4gJ+G5picsCiAgJ+G5qScgPT4gJ+G5qCcsCiAgJ+G5qycgPT4gJ+G5qicsCiAgJ+G5rScgPT4gJ+G5rCcsCiAgJ+G5rycgPT4gJ+G5ricsCiAgJ+G5sScgPT4gJ+G5sCcsCiAgJ+G5sycgPT4gJ+G5sicsCiAgJ+G5tScgPT4gJ+G5tCcsCiAgJ+G5tycgPT4gJ+G5ticsCiAgJ+G5uScgPT4gJ+G5uCcsCiAgJ+G5uycgPT4gJ+G5uicsCiAgJ+G5vScgPT4gJ+G5vCcsCiAgJ+G5vycgPT4gJ+G5vicsCiAgJ+G6gScgPT4gJ+G6gCcsCiAgJ+G6gycgPT4gJ+G6gicsCiAgJ+G6hScgPT4gJ+G6hCcsCiAgJ+G6hycgPT4gJ+G6hicsCiAgJ+G6iScgPT4gJ+G6iCcsCiAgJ+G6iycgPT4gJ+G6iicsCiAgJ+G6jScgPT4gJ+G6jCcsCiAgJ+G6jycgPT4gJ+G6jicsCiAgJ+G6kScgPT4gJ+G6kCcsCiAgJ+G6kycgPT4gJ+G6kicsCiAgJ+G6lScgPT4gJ+G6lCcsCiAgJ+G6mycgPT4gJ+G5oCcsCiAgJ+G6oScgPT4gJ+G6oCcsCiAgJ+G6oycgPT4gJ+G6oicsCiAgJ+G6pScgPT4gJ+G6pCcsCiAgJ+G6pycgPT4gJ+G6picsCiAgJ+G6qScgPT4gJ+G6qCcsCiAgJ+G6qycgPT4gJ+G6qicsCiAgJ+G6rScgPT4gJ+G6rCcsCiAgJ+G6rycgPT4gJ+G6ricsCiAgJ+G6sScgPT4gJ+G6sCcsCiAgJ+G6sycgPT4gJ+G6sicsCiAgJ+G6tScgPT4gJ+G6tCcsCiAgJ+G6tycgPT4gJ+G6ticsCiAgJ+G6uScgPT4gJ+G6uCcsCiAgJ+G6uycgPT4gJ+G6uicsCiAgJ+G6vScgPT4gJ+G6vCcsCiAgJ+G6vycgPT4gJ+G6vicsCiAgJ+G7gScgPT4gJ+G7gCcsCiAgJ+G7gycgPT4gJ+G7gicsCiAgJ+G7hScgPT4gJ+G7hCcsCiAgJ+G7hycgPT4gJ+G7hicsCiAgJ+G7iScgPT4gJ+G7iCcsCiAgJ+G7iycgPT4gJ+G7iicsCiAgJ+G7jScgPT4gJ+G7jCcsCiAgJ+G7jycgPT4gJ+G7jicsCiAgJ+G7kScgPT4gJ+G7kCcsCiAgJ+G7kycgPT4gJ+G7kicsCiAgJ+G7lScgPT4gJ+G7lCcsCiAgJ+G7lycgPT4gJ+G7licsCiAgJ+G7mScgPT4gJ+G7mCcsCiAgJ+G7mycgPT4gJ+G7micsCiAgJ+G7nScgPT4gJ+G7nCcsCiAgJ+G7nycgPT4gJ+G7nicsCiAgJ+G7oScgPT4gJ+G7oCcsCiAgJ+G7oycgPT4gJ+G7oicsCiAgJ+G7pScgPT4gJ+G7pCcsCiAgJ+G7pycgPT4gJ+G7picsCiAgJ+G7qScgPT4gJ+G7qCcsCiAgJ+G7qycgPT4gJ+G7qicsCiAgJ+G7rScgPT4gJ+G7rCcsCiAgJ+G7rycgPT4gJ+G7ricsCiAgJ+G7sScgPT4gJ+G7sCcsCiAgJ+G7sycgPT4gJ+G7sicsCiAgJ+G7tScgPT4gJ+G7tCcsCiAgJ+G7tycgPT4gJ+G7ticsCiAgJ+G7uScgPT4gJ+G7uCcsCiAgJ+G7uycgPT4gJ+G7uicsCiAgJ+G7vScgPT4gJ+G7vCcsCiAgJ+G7vycgPT4gJ+G7vicsCiAgJ+G8gCcgPT4gJ+G8iCcsCiAgJ+G8gScgPT4gJ+G8iScsCiAgJ+G8gicgPT4gJ+G8iicsCiAgJ+G8gycgPT4gJ+G8iycsCiAgJ+G8hCcgPT4gJ+G8jCcsCiAgJ+G8hScgPT4gJ+G8jScsCiAgJ+G8hicgPT4gJ+G8jicsCiAgJ+G8hycgPT4gJ+G8jycsCiAgJ+G8kCcgPT4gJ+G8mCcsCiAgJ+G8kScgPT4gJ+G8mScsCiAgJ+G8kicgPT4gJ+G8micsCiAgJ+G8kycgPT4gJ+G8mycsCiAgJ+G8lCcgPT4gJ+G8nCcsCiAgJ+G8lScgPT4gJ+G8nScsCiAgJ+G8oCcgPT4gJ+G8qCcsCiAgJ+G8oScgPT4gJ+G8qScsCiAgJ+G8oicgPT4gJ+G8qicsCiAgJ+G8oycgPT4gJ+G8qycsCiAgJ+G8pCcgPT4gJ+G8rCcsCiAgJ+G8pScgPT4gJ+G8rScsCiAgJ+G8picgPT4gJ+G8ricsCiAgJ+G8pycgPT4gJ+G8rycsCiAgJ+G8sCcgPT4gJ+G8uCcsCiAgJ+G8sScgPT4gJ+G8uScsCiAgJ+G8sicgPT4gJ+G8uicsCiAgJ+G8sycgPT4gJ+G8uycsCiAgJ+G8tCcgPT4gJ+G8vCcsCiAgJ+G8tScgPT4gJ+G8vScsCiAgJ+G8ticgPT4gJ+G8vicsCiAgJ+G8tycgPT4gJ+G8vycsCiAgJ+G9gCcgPT4gJ+G9iCcsCiAgJ+G9gScgPT4gJ+G9iScsCiAgJ+G9gicgPT4gJ+G9iicsCiAgJ+G9gycgPT4gJ+G9iycsCiAgJ+G9hCcgPT4gJ+G9jCcsCiAgJ+G9hScgPT4gJ+G9jScsCiAgJ+G9kScgPT4gJ+G9mScsCiAgJ+G9kycgPT4gJ+G9mycsCiAgJ+G9lScgPT4gJ+G9nScsCiAgJ+G9lycgPT4gJ+G9nycsCiAgJ+G9oCcgPT4gJ+G9qCcsCiAgJ+G9oScgPT4gJ+G9qScsCiAgJ+G9oicgPT4gJ+G9qicsCiAgJ+G9oycgPT4gJ+G9qycsCiAgJ+G9pCcgPT4gJ+G9rCcsCiAgJ+G9pScgPT4gJ+G9rScsCiAgJ+G9picgPT4gJ+G9ricsCiAgJ+G9pycgPT4gJ+G9rycsCiAgJ+G9sCcgPT4gJ+G+uicsCiAgJ+G9sScgPT4gJ+G+uycsCiAgJ+G9sicgPT4gJ+G/iCcsCiAgJ+G9sycgPT4gJ+G/iScsCiAgJ+G9tCcgPT4gJ+G/iicsCiAgJ+G9tScgPT4gJ+G/iycsCiAgJ+G9ticgPT4gJ+G/micsCiAgJ+G9tycgPT4gJ+G/mycsCiAgJ+G9uCcgPT4gJ+G/uCcsCiAgJ+G9uScgPT4gJ+G/uScsCiAgJ+G9uicgPT4gJ+G/qicsCiAgJ+G9uycgPT4gJ+G/qycsCiAgJ+G9vCcgPT4gJ+G/uicsCiAgJ+G9vScgPT4gJ+G/uycsCiAgJ+G+gCcgPT4gJ+G+iCcsCiAgJ+G+gScgPT4gJ+G+iScsCiAgJ+G+gicgPT4gJ+G+iicsCiAgJ+G+gycgPT4gJ+G+iycsCiAgJ+G+hCcgPT4gJ+G+jCcsCiAgJ+G+hScgPT4gJ+G+jScsCiAgJ+G+hicgPT4gJ+G+jicsCiAgJ+G+hycgPT4gJ+G+jycsCiAgJ+G+kCcgPT4gJ+G+mCcsCiAgJ+G+kScgPT4gJ+G+mScsCiAgJ+G+kicgPT4gJ+G+micsCiAgJ+G+kycgPT4gJ+G+mycsCiAgJ+G+lCcgPT4gJ+G+nCcsCiAgJ+G+lScgPT4gJ+G+nScsCiAgJ+G+licgPT4gJ+G+nicsCiAgJ+G+lycgPT4gJ+G+nycsCiAgJ+G+oCcgPT4gJ+G+qCcsCiAgJ+G+oScgPT4gJ+G+qScsCiAgJ+G+oicgPT4gJ+G+qicsCiAgJ+G+oycgPT4gJ+G+qycsCiAgJ+G+pCcgPT4gJ+G+rCcsCiAgJ+G+pScgPT4gJ+G+rScsCiAgJ+G+picgPT4gJ+G+ricsCiAgJ+G+pycgPT4gJ+G+rycsCiAgJ+G+sCcgPT4gJ+G+uCcsCiAgJ+G+sScgPT4gJ+G+uScsCiAgJ+G+sycgPT4gJ+G+vCcsCiAgJ+G+vicgPT4gJ86ZJywKICAn4b+DJyA9PiAn4b+MJywKICAn4b+QJyA9PiAn4b+YJywKICAn4b+RJyA9PiAn4b+ZJywKICAn4b+gJyA9PiAn4b+oJywKICAn4b+hJyA9PiAn4b+pJywKICAn4b+lJyA9PiAn4b+sJywKICAn4b+zJyA9PiAn4b+8JywKICAn4oWOJyA9PiAn4oSyJywKICAn4oWwJyA9PiAn4oWgJywKICAn4oWxJyA9PiAn4oWhJywKICAn4oWyJyA9PiAn4oWiJywKICAn4oWzJyA9PiAn4oWjJywKICAn4oW0JyA9PiAn4oWkJywKICAn4oW1JyA9PiAn4oWlJywKICAn4oW2JyA9PiAn4oWmJywKICAn4oW3JyA9PiAn4oWnJywKICAn4oW4JyA9PiAn4oWoJywKICAn4oW5JyA9PiAn4oWpJywKICAn4oW6JyA9PiAn4oWqJywKICAn4oW7JyA9PiAn4oWrJywKICAn4oW8JyA9PiAn4oWsJywKICAn4oW9JyA9PiAn4oWtJywKICAn4oW+JyA9PiAn4oWuJywKICAn4oW/JyA9PiAn4oWvJywKICAn4oaEJyA9PiAn4oaDJywKICAn4pOQJyA9PiAn4pK2JywKICAn4pORJyA9PiAn4pK3JywKICAn4pOSJyA9PiAn4pK4JywKICAn4pOTJyA9PiAn4pK5JywKICAn4pOUJyA9PiAn4pK6JywKICAn4pOVJyA9PiAn4pK7JywKICAn4pOWJyA9PiAn4pK8JywKICAn4pOXJyA9PiAn4pK9JywKICAn4pOYJyA9PiAn4pK+JywKICAn4pOZJyA9PiAn4pK/JywKICAn4pOaJyA9PiAn4pOAJywKICAn4pObJyA9PiAn4pOBJywKICAn4pOcJyA9PiAn4pOCJywKICAn4pOdJyA9PiAn4pODJywKICAn4pOeJyA9PiAn4pOEJywKICAn4pOfJyA9PiAn4pOFJywKICAn4pOgJyA9PiAn4pOGJywKICAn4pOhJyA9PiAn4pOHJywKICAn4pOiJyA9PiAn4pOIJywKICAn4pOjJyA9PiAn4pOJJywKICAn4pOkJyA9PiAn4pOKJywKICAn4pOlJyA9PiAn4pOLJywKICAn4pOmJyA9PiAn4pOMJywKICAn4pOnJyA9PiAn4pONJywKICAn4pOoJyA9PiAn4pOOJywKICAn4pOpJyA9PiAn4pOPJywKICAn4rCwJyA9PiAn4rCAJywKICAn4rCxJyA9PiAn4rCBJywKICAn4rCyJyA9PiAn4rCCJywKICAn4rCzJyA9PiAn4rCDJywKICAn4rC0JyA9PiAn4rCEJywKICAn4rC1JyA9PiAn4rCFJywKICAn4rC2JyA9PiAn4rCGJywKICAn4rC3JyA9PiAn4rCHJywKICAn4rC4JyA9PiAn4rCIJywKICAn4rC5JyA9PiAn4rCJJywKICAn4rC6JyA9PiAn4rCKJywKICAn4rC7JyA9PiAn4rCLJywKICAn4rC8JyA9PiAn4rCMJywKICAn4rC9JyA9PiAn4rCNJywKICAn4rC+JyA9PiAn4rCOJywKICAn4rC/JyA9PiAn4rCPJywKICAn4rGAJyA9PiAn4rCQJywKICAn4rGBJyA9PiAn4rCRJywKICAn4rGCJyA9PiAn4rCSJywKICAn4rGDJyA9PiAn4rCTJywKICAn4rGEJyA9PiAn4rCUJywKICAn4rGFJyA9PiAn4rCVJywKICAn4rGGJyA9PiAn4rCWJywKICAn4rGHJyA9PiAn4rCXJywKICAn4rGIJyA9PiAn4rCYJywKICAn4rGJJyA9PiAn4rCZJywKICAn4rGKJyA9PiAn4rCaJywKICAn4rGLJyA9PiAn4rCbJywKICAn4rGMJyA9PiAn4rCcJywKICAn4rGNJyA9PiAn4rCdJywKICAn4rGOJyA9PiAn4rCeJywKICAn4rGPJyA9PiAn4rCfJywKICAn4rGQJyA9PiAn4rCgJywKICAn4rGRJyA9PiAn4rChJywKICAn4rGSJyA9PiAn4rCiJywKICAn4rGTJyA9PiAn4rCjJywKICAn4rGUJyA9PiAn4rCkJywKICAn4rGVJyA9PiAn4rClJywKICAn4rGWJyA9PiAn4rCmJywKICAn4rGXJyA9PiAn4rCnJywKICAn4rGYJyA9PiAn4rCoJywKICAn4rGZJyA9PiAn4rCpJywKICAn4rGaJyA9PiAn4rCqJywKICAn4rGbJyA9PiAn4rCrJywKICAn4rGcJyA9PiAn4rCsJywKICAn4rGdJyA9PiAn4rCtJywKICAn4rGeJyA9PiAn4rCuJywKICAn4rGhJyA9PiAn4rGgJywKICAn4rGlJyA9PiAnyLonLAogICfisaYnID0+ICfIvicsCiAgJ+KxqCcgPT4gJ+KxpycsCiAgJ+KxqicgPT4gJ+KxqScsCiAgJ+KxrCcgPT4gJ+KxqycsCiAgJ+KxsycgPT4gJ+KxsicsCiAgJ+KxticgPT4gJ+KxtScsCiAgJ+KygScgPT4gJ+KygCcsCiAgJ+KygycgPT4gJ+KygicsCiAgJ+KyhScgPT4gJ+KyhCcsCiAgJ+KyhycgPT4gJ+KyhicsCiAgJ+KyiScgPT4gJ+KyiCcsCiAgJ+KyiycgPT4gJ+KyiicsCiAgJ+KyjScgPT4gJ+KyjCcsCiAgJ+KyjycgPT4gJ+KyjicsCiAgJ+KykScgPT4gJ+KykCcsCiAgJ+KykycgPT4gJ+KykicsCiAgJ+KylScgPT4gJ+KylCcsCiAgJ+KylycgPT4gJ+KylicsCiAgJ+KymScgPT4gJ+KymCcsCiAgJ+KymycgPT4gJ+KymicsCiAgJ+KynScgPT4gJ+KynCcsCiAgJ+KynycgPT4gJ+KynicsCiAgJ+KyoScgPT4gJ+KyoCcsCiAgJ+KyoycgPT4gJ+KyoicsCiAgJ+KypScgPT4gJ+KypCcsCiAgJ+KypycgPT4gJ+KypicsCiAgJ+KyqScgPT4gJ+KyqCcsCiAgJ+KyqycgPT4gJ+KyqicsCiAgJ+KyrScgPT4gJ+KyrCcsCiAgJ+KyrycgPT4gJ+KyricsCiAgJ+KysScgPT4gJ+KysCcsCiAgJ+KysycgPT4gJ+KysicsCiAgJ+KytScgPT4gJ+KytCcsCiAgJ+KytycgPT4gJ+KyticsCiAgJ+KyuScgPT4gJ+KyuCcsCiAgJ+KyuycgPT4gJ+KyuicsCiAgJ+KyvScgPT4gJ+KyvCcsCiAgJ+KyvycgPT4gJ+KyvicsCiAgJ+KzgScgPT4gJ+KzgCcsCiAgJ+KzgycgPT4gJ+KzgicsCiAgJ+KzhScgPT4gJ+KzhCcsCiAgJ+KzhycgPT4gJ+KzhicsCiAgJ+KziScgPT4gJ+KziCcsCiAgJ+KziycgPT4gJ+KziicsCiAgJ+KzjScgPT4gJ+KzjCcsCiAgJ+KzjycgPT4gJ+KzjicsCiAgJ+KzkScgPT4gJ+KzkCcsCiAgJ+KzkycgPT4gJ+KzkicsCiAgJ+KzlScgPT4gJ+KzlCcsCiAgJ+KzlycgPT4gJ+KzlicsCiAgJ+KzmScgPT4gJ+KzmCcsCiAgJ+KzmycgPT4gJ+KzmicsCiAgJ+KznScgPT4gJ+KznCcsCiAgJ+KznycgPT4gJ+KznicsCiAgJ+KzoScgPT4gJ+KzoCcsCiAgJ+KzoycgPT4gJ+KzoicsCiAgJ+KzrCcgPT4gJ+KzqycsCiAgJ+KzricgPT4gJ+KzrScsCiAgJ+KzsycgPT4gJ+KzsicsCiAgJ+K0gCcgPT4gJ+GCoCcsCiAgJ+K0gScgPT4gJ+GCoScsCiAgJ+K0gicgPT4gJ+GCoicsCiAgJ+K0gycgPT4gJ+GCoycsCiAgJ+K0hCcgPT4gJ+GCpCcsCiAgJ+K0hScgPT4gJ+GCpScsCiAgJ+K0hicgPT4gJ+GCpicsCiAgJ+K0hycgPT4gJ+GCpycsCiAgJ+K0iCcgPT4gJ+GCqCcsCiAgJ+K0iScgPT4gJ+GCqScsCiAgJ+K0iicgPT4gJ+GCqicsCiAgJ+K0iycgPT4gJ+GCqycsCiAgJ+K0jCcgPT4gJ+GCrCcsCiAgJ+K0jScgPT4gJ+GCrScsCiAgJ+K0jicgPT4gJ+GCricsCiAgJ+K0jycgPT4gJ+GCrycsCiAgJ+K0kCcgPT4gJ+GCsCcsCiAgJ+K0kScgPT4gJ+GCsScsCiAgJ+K0kicgPT4gJ+GCsicsCiAgJ+K0kycgPT4gJ+GCsycsCiAgJ+K0lCcgPT4gJ+GCtCcsCiAgJ+K0lScgPT4gJ+GCtScsCiAgJ+K0licgPT4gJ+GCticsCiAgJ+K0lycgPT4gJ+GCtycsCiAgJ+K0mCcgPT4gJ+GCuCcsCiAgJ+K0mScgPT4gJ+GCuScsCiAgJ+K0micgPT4gJ+GCuicsCiAgJ+K0mycgPT4gJ+GCuycsCiAgJ+K0nCcgPT4gJ+GCvCcsCiAgJ+K0nScgPT4gJ+GCvScsCiAgJ+K0nicgPT4gJ+GCvicsCiAgJ+K0nycgPT4gJ+GCvycsCiAgJ+K0oCcgPT4gJ+GDgCcsCiAgJ+K0oScgPT4gJ+GDgScsCiAgJ+K0oicgPT4gJ+GDgicsCiAgJ+K0oycgPT4gJ+GDgycsCiAgJ+K0pCcgPT4gJ+GDhCcsCiAgJ+K0pScgPT4gJ+GDhScsCiAgJ+K0pycgPT4gJ+GDhycsCiAgJ+K0rScgPT4gJ+GDjScsCiAgJ+qZgScgPT4gJ+qZgCcsCiAgJ+qZgycgPT4gJ+qZgicsCiAgJ+qZhScgPT4gJ+qZhCcsCiAgJ+qZhycgPT4gJ+qZhicsCiAgJ+qZiScgPT4gJ+qZiCcsCiAgJ+qZiycgPT4gJ+qZiicsCiAgJ+qZjScgPT4gJ+qZjCcsCiAgJ+qZjycgPT4gJ+qZjicsCiAgJ+qZkScgPT4gJ+qZkCcsCiAgJ+qZkycgPT4gJ+qZkicsCiAgJ+qZlScgPT4gJ+qZlCcsCiAgJ+qZlycgPT4gJ+qZlicsCiAgJ+qZmScgPT4gJ+qZmCcsCiAgJ+qZmycgPT4gJ+qZmicsCiAgJ+qZnScgPT4gJ+qZnCcsCiAgJ+qZnycgPT4gJ+qZnicsCiAgJ+qZoScgPT4gJ+qZoCcsCiAgJ+qZoycgPT4gJ+qZoicsCiAgJ+qZpScgPT4gJ+qZpCcsCiAgJ+qZpycgPT4gJ+qZpicsCiAgJ+qZqScgPT4gJ+qZqCcsCiAgJ+qZqycgPT4gJ+qZqicsCiAgJ+qZrScgPT4gJ+qZrCcsCiAgJ+qagScgPT4gJ+qagCcsCiAgJ+qagycgPT4gJ+qagicsCiAgJ+qahScgPT4gJ+qahCcsCiAgJ+qahycgPT4gJ+qahicsCiAgJ+qaiScgPT4gJ+qaiCcsCiAgJ+qaiycgPT4gJ+qaiicsCiAgJ+qajScgPT4gJ+qajCcsCiAgJ+qajycgPT4gJ+qajicsCiAgJ+qakScgPT4gJ+qakCcsCiAgJ+qakycgPT4gJ+qakicsCiAgJ+qalScgPT4gJ+qalCcsCiAgJ+qalycgPT4gJ+qalicsCiAgJ+qamScgPT4gJ+qamCcsCiAgJ+qamycgPT4gJ+qamicsCiAgJ+qcoycgPT4gJ+qcoicsCiAgJ+qcpScgPT4gJ+qcpCcsCiAgJ+qcpycgPT4gJ+qcpicsCiAgJ+qcqScgPT4gJ+qcqCcsCiAgJ+qcqycgPT4gJ+qcqicsCiAgJ+qcrScgPT4gJ+qcrCcsCiAgJ+qcrycgPT4gJ+qcricsCiAgJ+qcsycgPT4gJ+qcsicsCiAgJ+qctScgPT4gJ+qctCcsCiAgJ+qctycgPT4gJ+qcticsCiAgJ+qcuScgPT4gJ+qcuCcsCiAgJ+qcuycgPT4gJ+qcuicsCiAgJ+qcvScgPT4gJ+qcvCcsCiAgJ+qcvycgPT4gJ+qcvicsCiAgJ+qdgScgPT4gJ+qdgCcsCiAgJ+qdgycgPT4gJ+qdgicsCiAgJ+qdhScgPT4gJ+qdhCcsCiAgJ+qdhycgPT4gJ+qdhicsCiAgJ+qdiScgPT4gJ+qdiCcsCiAgJ+qdiycgPT4gJ+qdiicsCiAgJ+qdjScgPT4gJ+qdjCcsCiAgJ+qdjycgPT4gJ+qdjicsCiAgJ+qdkScgPT4gJ+qdkCcsCiAgJ+qdkycgPT4gJ+qdkicsCiAgJ+qdlScgPT4gJ+qdlCcsCiAgJ+qdlycgPT4gJ+qdlicsCiAgJ+qdmScgPT4gJ+qdmCcsCiAgJ+qdmycgPT4gJ+qdmicsCiAgJ+qdnScgPT4gJ+qdnCcsCiAgJ+qdnycgPT4gJ+qdnicsCiAgJ+qdoScgPT4gJ+qdoCcsCiAgJ+qdoycgPT4gJ+qdoicsCiAgJ+qdpScgPT4gJ+qdpCcsCiAgJ+qdpycgPT4gJ+qdpicsCiAgJ+qdqScgPT4gJ+qdqCcsCiAgJ+qdqycgPT4gJ+qdqicsCiAgJ+qdrScgPT4gJ+qdrCcsCiAgJ+qdrycgPT4gJ+qdricsCiAgJ+qduicgPT4gJ+qduScsCiAgJ+qdvCcgPT4gJ+qduycsCiAgJ+qdvycgPT4gJ+qdvicsCiAgJ+qegScgPT4gJ+qegCcsCiAgJ+qegycgPT4gJ+qegicsCiAgJ+qehScgPT4gJ+qehCcsCiAgJ+qehycgPT4gJ+qehicsCiAgJ+qejCcgPT4gJ+qeiycsCiAgJ+qekScgPT4gJ+qekCcsCiAgJ+qekycgPT4gJ+qekicsCiAgJ+qelCcgPT4gJ+qfhCcsCiAgJ+qelycgPT4gJ+qelicsCiAgJ+qemScgPT4gJ+qemCcsCiAgJ+qemycgPT4gJ+qemicsCiAgJ+qenScgPT4gJ+qenCcsCiAgJ+qenycgPT4gJ+qenicsCiAgJ+qeoScgPT4gJ+qeoCcsCiAgJ+qeoycgPT4gJ+qeoicsCiAgJ+qepScgPT4gJ+qepCcsCiAgJ+qepycgPT4gJ+qepicsCiAgJ+qeqScgPT4gJ+qeqCcsCiAgJ+qetScgPT4gJ+qetCcsCiAgJ+qetycgPT4gJ+qeticsCiAgJ+qeuScgPT4gJ+qeuCcsCiAgJ+qeuycgPT4gJ+qeuicsCiAgJ+qevScgPT4gJ+qevCcsCiAgJ+qevycgPT4gJ+qevicsCiAgJ+qfgycgPT4gJ+qfgicsCiAgJ+qfiCcgPT4gJ+qfhycsCiAgJ+qfiicgPT4gJ+qfiScsCiAgJ+qfticgPT4gJ+qftScsCiAgJ+qtkycgPT4gJ+qesycsCiAgJ+qtsCcgPT4gJ+GOoCcsCiAgJ+qtsScgPT4gJ+GOoScsCiAgJ+qtsicgPT4gJ+GOoicsCiAgJ+qtsycgPT4gJ+GOoycsCiAgJ+qttCcgPT4gJ+GOpCcsCiAgJ+qttScgPT4gJ+GOpScsCiAgJ+qtticgPT4gJ+GOpicsCiAgJ+qttycgPT4gJ+GOpycsCiAgJ+qtuCcgPT4gJ+GOqCcsCiAgJ+qtuScgPT4gJ+GOqScsCiAgJ+qtuicgPT4gJ+GOqicsCiAgJ+qtuycgPT4gJ+GOqycsCiAgJ+qtvCcgPT4gJ+GOrCcsCiAgJ+qtvScgPT4gJ+GOrScsCiAgJ+qtvicgPT4gJ+GOricsCiAgJ+qtvycgPT4gJ+GOrycsCiAgJ+qugCcgPT4gJ+GOsCcsCiAgJ+qugScgPT4gJ+GOsScsCiAgJ+qugicgPT4gJ+GOsicsCiAgJ+qugycgPT4gJ+GOsycsCiAgJ+quhCcgPT4gJ+GOtCcsCiAgJ+quhScgPT4gJ+GOtScsCiAgJ+quhicgPT4gJ+GOticsCiAgJ+quhycgPT4gJ+GOtycsCiAgJ+quiCcgPT4gJ+GOuCcsCiAgJ+quiScgPT4gJ+GOuScsCiAgJ+quiicgPT4gJ+GOuicsCiAgJ+quiycgPT4gJ+GOuycsCiAgJ+qujCcgPT4gJ+GOvCcsCiAgJ+qujScgPT4gJ+GOvScsCiAgJ+qujicgPT4gJ+GOvicsCiAgJ+qujycgPT4gJ+GOvycsCiAgJ+qukCcgPT4gJ+GPgCcsCiAgJ+qukScgPT4gJ+GPgScsCiAgJ+qukicgPT4gJ+GPgicsCiAgJ+qukycgPT4gJ+GPgycsCiAgJ+qulCcgPT4gJ+GPhCcsCiAgJ+qulScgPT4gJ+GPhScsCiAgJ+qulicgPT4gJ+GPhicsCiAgJ+qulycgPT4gJ+GPhycsCiAgJ+qumCcgPT4gJ+GPiCcsCiAgJ+qumScgPT4gJ+GPiScsCiAgJ+qumicgPT4gJ+GPiicsCiAgJ+qumycgPT4gJ+GPiycsCiAgJ+qunCcgPT4gJ+GPjCcsCiAgJ+qunScgPT4gJ+GPjScsCiAgJ+qunicgPT4gJ+GPjicsCiAgJ+qunycgPT4gJ+GPjycsCiAgJ+quoCcgPT4gJ+GPkCcsCiAgJ+quoScgPT4gJ+GPkScsCiAgJ+quoicgPT4gJ+GPkicsCiAgJ+quoycgPT4gJ+GPkycsCiAgJ+qupCcgPT4gJ+GPlCcsCiAgJ+qupScgPT4gJ+GPlScsCiAgJ+qupicgPT4gJ+GPlicsCiAgJ+qupycgPT4gJ+GPlycsCiAgJ+quqCcgPT4gJ+GPmCcsCiAgJ+quqScgPT4gJ+GPmScsCiAgJ+quqicgPT4gJ+GPmicsCiAgJ+quqycgPT4gJ+GPmycsCiAgJ+qurCcgPT4gJ+GPnCcsCiAgJ+qurScgPT4gJ+GPnScsCiAgJ+quricgPT4gJ+GPnicsCiAgJ+qurycgPT4gJ+GPnycsCiAgJ+qusCcgPT4gJ+GPoCcsCiAgJ+qusScgPT4gJ+GPoScsCiAgJ+qusicgPT4gJ+GPoicsCiAgJ+qusycgPT4gJ+GPoycsCiAgJ+qutCcgPT4gJ+GPpCcsCiAgJ+qutScgPT4gJ+GPpScsCiAgJ+quticgPT4gJ+GPpicsCiAgJ+qutycgPT4gJ+GPpycsCiAgJ+quuCcgPT4gJ+GPqCcsCiAgJ+quuScgPT4gJ+GPqScsCiAgJ+quuicgPT4gJ+GPqicsCiAgJ+quuycgPT4gJ+GPqycsCiAgJ+quvCcgPT4gJ+GPrCcsCiAgJ+quvScgPT4gJ+GPrScsCiAgJ+quvicgPT4gJ+GPricsCiAgJ+quvycgPT4gJ+GPrycsCiAgJ++9gScgPT4gJ++8oScsCiAgJ++9gicgPT4gJ++8oicsCiAgJ++9gycgPT4gJ++8oycsCiAgJ++9hCcgPT4gJ++8pCcsCiAgJ++9hScgPT4gJ++8pScsCiAgJ++9hicgPT4gJ++8picsCiAgJ++9hycgPT4gJ++8pycsCiAgJ++9iCcgPT4gJ++8qCcsCiAgJ++9iScgPT4gJ++8qScsCiAgJ++9iicgPT4gJ++8qicsCiAgJ++9iycgPT4gJ++8qycsCiAgJ++9jCcgPT4gJ++8rCcsCiAgJ++9jScgPT4gJ++8rScsCiAgJ++9jicgPT4gJ++8ricsCiAgJ++9jycgPT4gJ++8rycsCiAgJ++9kCcgPT4gJ++8sCcsCiAgJ++9kScgPT4gJ++8sScsCiAgJ++9kicgPT4gJ++8sicsCiAgJ++9kycgPT4gJ++8sycsCiAgJ++9lCcgPT4gJ++8tCcsCiAgJ++9lScgPT4gJ++8tScsCiAgJ++9licgPT4gJ++8ticsCiAgJ++9lycgPT4gJ++8tycsCiAgJ++9mCcgPT4gJ++8uCcsCiAgJ++9mScgPT4gJ++8uScsCiAgJ++9micgPT4gJ++8uicsCiAgJ/CQkKgnID0+ICfwkJCAJywKICAn8JCQqScgPT4gJ/CQkIEnLAogICfwkJCqJyA9PiAn8JCQgicsCiAgJ/CQkKsnID0+ICfwkJCDJywKICAn8JCQrCcgPT4gJ/CQkIQnLAogICfwkJCtJyA9PiAn8JCQhScsCiAgJ/CQkK4nID0+ICfwkJCGJywKICAn8JCQrycgPT4gJ/CQkIcnLAogICfwkJCwJyA9PiAn8JCQiCcsCiAgJ/CQkLEnID0+ICfwkJCJJywKICAn8JCQsicgPT4gJ/CQkIonLAogICfwkJCzJyA9PiAn8JCQiycsCiAgJ/CQkLQnID0+ICfwkJCMJywKICAn8JCQtScgPT4gJ/CQkI0nLAogICfwkJC2JyA9PiAn8JCQjicsCiAgJ/CQkLcnID0+ICfwkJCPJywKICAn8JCQuCcgPT4gJ/CQkJAnLAogICfwkJC5JyA9PiAn8JCQkScsCiAgJ/CQkLonID0+ICfwkJCSJywKICAn8JCQuycgPT4gJ/CQkJMnLAogICfwkJC8JyA9PiAn8JCQlCcsCiAgJ/CQkL0nID0+ICfwkJCVJywKICAn8JCQvicgPT4gJ/CQkJYnLAogICfwkJC/JyA9PiAn8JCQlycsCiAgJ/CQkYAnID0+ICfwkJCYJywKICAn8JCRgScgPT4gJ/CQkJknLAogICfwkJGCJyA9PiAn8JCQmicsCiAgJ/CQkYMnID0+ICfwkJCbJywKICAn8JCRhCcgPT4gJ/CQkJwnLAogICfwkJGFJyA9PiAn8JCQnScsCiAgJ/CQkYYnID0+ICfwkJCeJywKICAn8JCRhycgPT4gJ/CQkJ8nLAogICfwkJGIJyA9PiAn8JCQoCcsCiAgJ/CQkYknID0+ICfwkJChJywKICAn8JCRiicgPT4gJ/CQkKInLAogICfwkJGLJyA9PiAn8JCQoycsCiAgJ/CQkYwnID0+ICfwkJCkJywKICAn8JCRjScgPT4gJ/CQkKUnLAogICfwkJGOJyA9PiAn8JCQpicsCiAgJ/CQkY8nID0+ICfwkJCnJywKICAn8JCTmCcgPT4gJ/CQkrAnLAogICfwkJOZJyA9PiAn8JCSsScsCiAgJ/CQk5onID0+ICfwkJKyJywKICAn8JCTmycgPT4gJ/CQkrMnLAogICfwkJOcJyA9PiAn8JCStCcsCiAgJ/CQk50nID0+ICfwkJK1JywKICAn8JCTnicgPT4gJ/CQkrYnLAogICfwkJOfJyA9PiAn8JCStycsCiAgJ/CQk6AnID0+ICfwkJK4JywKICAn8JCToScgPT4gJ/CQkrknLAogICfwkJOiJyA9PiAn8JCSuicsCiAgJ/CQk6MnID0+ICfwkJK7JywKICAn8JCTpCcgPT4gJ/CQkrwnLAogICfwkJOlJyA9PiAn8JCSvScsCiAgJ/CQk6YnID0+ICfwkJK+JywKICAn8JCTpycgPT4gJ/CQkr8nLAogICfwkJOoJyA9PiAn8JCTgCcsCiAgJ/CQk6knID0+ICfwkJOBJywKICAn8JCTqicgPT4gJ/CQk4InLAogICfwkJOrJyA9PiAn8JCTgycsCiAgJ/CQk6wnID0+ICfwkJOEJywKICAn8JCTrScgPT4gJ/CQk4UnLAogICfwkJOuJyA9PiAn8JCThicsCiAgJ/CQk68nID0+ICfwkJOHJywKICAn8JCTsCcgPT4gJ/CQk4gnLAogICfwkJOxJyA9PiAn8JCTiScsCiAgJ/CQk7InID0+ICfwkJOKJywKICAn8JCTsycgPT4gJ/CQk4snLAogICfwkJO0JyA9PiAn8JCTjCcsCiAgJ/CQk7UnID0+ICfwkJONJywKICAn8JCTticgPT4gJ/CQk44nLAogICfwkJO3JyA9PiAn8JCTjycsCiAgJ/CQk7gnID0+ICfwkJOQJywKICAn8JCTuScgPT4gJ/CQk5EnLAogICfwkJO6JyA9PiAn8JCTkicsCiAgJ/CQk7snID0+ICfwkJOTJywKICAn8JCzgCcgPT4gJ/CQsoAnLAogICfwkLOBJyA9PiAn8JCygScsCiAgJ/CQs4InID0+ICfwkLKCJywKICAn8JCzgycgPT4gJ/CQsoMnLAogICfwkLOEJyA9PiAn8JCyhCcsCiAgJ/CQs4UnID0+ICfwkLKFJywKICAn8JCzhicgPT4gJ/CQsoYnLAogICfwkLOHJyA9PiAn8JCyhycsCiAgJ/CQs4gnID0+ICfwkLKIJywKICAn8JCziScgPT4gJ/CQsoknLAogICfwkLOKJyA9PiAn8JCyiicsCiAgJ/CQs4snID0+ICfwkLKLJywKICAn8JCzjCcgPT4gJ/CQsownLAogICfwkLONJyA9PiAn8JCyjScsCiAgJ/CQs44nID0+ICfwkLKOJywKICAn8JCzjycgPT4gJ/CQso8nLAogICfwkLOQJyA9PiAn8JCykCcsCiAgJ/CQs5EnID0+ICfwkLKRJywKICAn8JCzkicgPT4gJ/CQspInLAogICfwkLOTJyA9PiAn8JCykycsCiAgJ/CQs5QnID0+ICfwkLKUJywKICAn8JCzlScgPT4gJ/CQspUnLAogICfwkLOWJyA9PiAn8JCylicsCiAgJ/CQs5cnID0+ICfwkLKXJywKICAn8JCzmCcgPT4gJ/CQspgnLAogICfwkLOZJyA9PiAn8JCymScsCiAgJ/CQs5onID0+ICfwkLKaJywKICAn8JCzmycgPT4gJ/CQspsnLAogICfwkLOcJyA9PiAn8JCynCcsCiAgJ/CQs50nID0+ICfwkLKdJywKICAn8JCznicgPT4gJ/CQsp4nLAogICfwkLOfJyA9PiAn8JCynycsCiAgJ/CQs6AnID0+ICfwkLKgJywKICAn8JCzoScgPT4gJ/CQsqEnLAogICfwkLOiJyA9PiAn8JCyoicsCiAgJ/CQs6MnID0+ICfwkLKjJywKICAn8JCzpCcgPT4gJ/CQsqQnLAogICfwkLOlJyA9PiAn8JCypScsCiAgJ/CQs6YnID0+ICfwkLKmJywKICAn8JCzpycgPT4gJ/CQsqcnLAogICfwkLOoJyA9PiAn8JCyqCcsCiAgJ/CQs6knID0+ICfwkLKpJywKICAn8JCzqicgPT4gJ/CQsqonLAogICfwkLOrJyA9PiAn8JCyqycsCiAgJ/CQs6wnID0+ICfwkLKsJywKICAn8JCzrScgPT4gJ/CQsq0nLAogICfwkLOuJyA9PiAn8JCyricsCiAgJ/CQs68nID0+ICfwkLKvJywKICAn8JCzsCcgPT4gJ/CQsrAnLAogICfwkLOxJyA9PiAn8JCysScsCiAgJ/CQs7InID0+ICfwkLKyJywKICAn8JGjgCcgPT4gJ/CRoqAnLAogICfwkaOBJyA9PiAn8JGioScsCiAgJ/CRo4InID0+ICfwkaKiJywKICAn8JGjgycgPT4gJ/CRoqMnLAogICfwkaOEJyA9PiAn8JGipCcsCiAgJ/CRo4UnID0+ICfwkaKlJywKICAn8JGjhicgPT4gJ/CRoqYnLAogICfwkaOHJyA9PiAn8JGipycsCiAgJ/CRo4gnID0+ICfwkaKoJywKICAn8JGjiScgPT4gJ/CRoqknLAogICfwkaOKJyA9PiAn8JGiqicsCiAgJ/CRo4snID0+ICfwkaKrJywKICAn8JGjjCcgPT4gJ/CRoqwnLAogICfwkaONJyA9PiAn8JGirScsCiAgJ/CRo44nID0+ICfwkaKuJywKICAn8JGjjycgPT4gJ/CRoq8nLAogICfwkaOQJyA9PiAn8JGisCcsCiAgJ/CRo5EnID0+ICfwkaKxJywKICAn8JGjkicgPT4gJ/CRorInLAogICfwkaOTJyA9PiAn8JGisycsCiAgJ/CRo5QnID0+ICfwkaK0JywKICAn8JGjlScgPT4gJ/CRorUnLAogICfwkaOWJyA9PiAn8JGiticsCiAgJ/CRo5cnID0+ICfwkaK3JywKICAn8JGjmCcgPT4gJ/CRorgnLAogICfwkaOZJyA9PiAn8JGiuScsCiAgJ/CRo5onID0+ICfwkaK6JywKICAn8JGjmycgPT4gJ/CRorsnLAogICfwkaOcJyA9PiAn8JGivCcsCiAgJ/CRo50nID0+ICfwkaK9JywKICAn8JGjnicgPT4gJ/CRor4nLAogICfwkaOfJyA9PiAn8JGivycsCiAgJ/CWuaAnID0+ICfwlrmAJywKICAn8Ja5oScgPT4gJ/CWuYEnLAogICfwlrmiJyA9PiAn8Ja5gicsCiAgJ/CWuaMnID0+ICfwlrmDJywKICAn8Ja5pCcgPT4gJ/CWuYQnLAogICfwlrmlJyA9PiAn8Ja5hScsCiAgJ/CWuaYnID0+ICfwlrmGJywKICAn8Ja5pycgPT4gJ/CWuYcnLAogICfwlrmoJyA9PiAn8Ja5iCcsCiAgJ/CWuaknID0+ICfwlrmJJywKICAn8Ja5qicgPT4gJ/CWuYonLAogICfwlrmrJyA9PiAn8Ja5iycsCiAgJ/CWuawnID0+ICfwlrmMJywKICAn8Ja5rScgPT4gJ/CWuY0nLAogICfwlrmuJyA9PiAn8Ja5jicsCiAgJ/CWua8nID0+ICfwlrmPJywKICAn8Ja5sCcgPT4gJ/CWuZAnLAogICfwlrmxJyA9PiAn8Ja5kScsCiAgJ/CWubInID0+ICfwlrmSJywKICAn8Ja5sycgPT4gJ/CWuZMnLAogICfwlrm0JyA9PiAn8Ja5lCcsCiAgJ/CWubUnID0+ICfwlrmVJywKICAn8Ja5ticgPT4gJ/CWuZYnLAogICfwlrm3JyA9PiAn8Ja5lycsCiAgJ/CWubgnID0+ICfwlrmYJywKICAn8Ja5uScgPT4gJ/CWuZknLAogICfwlrm6JyA9PiAn8Ja5micsCiAgJ/CWubsnID0+ICfwlrmbJywKICAn8Ja5vCcgPT4gJ/CWuZwnLAogICfwlrm9JyA9PiAn8Ja5nScsCiAgJ/CWub4nID0+ICfwlrmeJywKICAn8Ja5vycgPT4gJ/CWuZ8nLAogICfwnqSiJyA9PiAn8J6kgCcsCiAgJ/CepKMnID0+ICfwnqSBJywKICAn8J6kpCcgPT4gJ/CepIInLAogICfwnqSlJyA9PiAn8J6kgycsCiAgJ/CepKYnID0+ICfwnqSEJywKICAn8J6kpycgPT4gJ/CepIUnLAogICfwnqSoJyA9PiAn8J6khicsCiAgJ/CepKknID0+ICfwnqSHJywKICAn8J6kqicgPT4gJ/CepIgnLAogICfwnqSrJyA9PiAn8J6kiScsCiAgJ/CepKwnID0+ICfwnqSKJywKICAn8J6krScgPT4gJ/CepIsnLAogICfwnqSuJyA9PiAn8J6kjCcsCiAgJ/CepK8nID0+ICfwnqSNJywKICAn8J6ksCcgPT4gJ/CepI4nLAogICfwnqSxJyA9PiAn8J6kjycsCiAgJ/CepLInID0+ICfwnqSQJywKICAn8J6ksycgPT4gJ/CepJEnLAogICfwnqS0JyA9PiAn8J6kkicsCiAgJ/CepLUnID0+ICfwnqSTJywKICAn8J6kticgPT4gJ/CepJQnLAogICfwnqS3JyA9PiAn8J6klScsCiAgJ/CepLgnID0+ICfwnqSWJywKICAn8J6kuScgPT4gJ/CepJcnLAogICfwnqS6JyA9PiAn8J6kmCcsCiAgJ/CepLsnID0+ICfwnqSZJywKICAn8J6kvCcgPT4gJ/CepJonLAogICfwnqS9JyA9PiAn8J6kmycsCiAgJ/CepL4nID0+ICfwnqScJywKICAn8J6kvycgPT4gJ/CepJ0nLAogICfwnqWAJyA9PiAn8J6knicsCiAgJ/CepYEnID0+ICfwnqSfJywKICAn8J6lgicgPT4gJ/CepKAnLAogICfwnqWDJyA9PiAn8J6koScsCik7Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgp1c2UgU3ltZm9ueVxQb2x5ZmlsbFxNYnN0cmluZyBhcyBwOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ21iX2NvbnZlcnRfdmFyaWFibGVzJykpIHsKICAgIC8qKgogICAgICogQ29udmVydCBjaGFyYWN0ZXIgY29kZSBpbiB2YXJpYWJsZShzKQogICAgICovCiAgICBmdW5jdGlvbiBtYl9jb252ZXJ0X3ZhcmlhYmxlcygkdG9fZW5jb2RpbmcsICRmcm9tX2VuY29kaW5nLCAmJHZhciwgJi4uLiR2YXJzKQogICAgewogICAgICAgICR2YXJzID0gWyYkdmFyLCAuLi4kdmFyc107CgogICAgICAgICRvayA9IHRydWU7CiAgICAgICAgYXJyYXlfd2Fsa19yZWN1cnNpdmUoJHZhcnMsIGZ1bmN0aW9uICgmJHYpIHVzZSAoJiRvaywgJHRvX2VuY29kaW5nLCAkZnJvbV9lbmNvZGluZykgewogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICR2ID0gcFxNYnN0cmluZzo6bWJfY29udmVydF9lbmNvZGluZygkdiwgJHRvX2VuY29kaW5nLCAkZnJvbV9lbmNvZGluZykpIHsKICAgICAgICAgICAgICAgICRvayA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIHJldHVybiAkb2sgPyAkZnJvbV9lbmNvZGluZyA6IGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxQb2x5ZmlsbFxNYnN0cmluZzsKCi8qKgogKiBQYXJ0aWFsIG1ic3RyaW5nIGltcGxlbWVudGF0aW9uIGluIFBIUCwgaWNvbnYgYmFzZWQsIFVURi04IGNlbnRyaWMuCiAqCiAqIEltcGxlbWVudGVkOgogKiAtIG1iX2NociAgICAgICAgICAgICAgICAgIC0gUmV0dXJucyBhIHNwZWNpZmljIGNoYXJhY3RlciBmcm9tIGl0cyBVbmljb2RlIGNvZGUgcG9pbnQKICogLSBtYl9jb252ZXJ0X2VuY29kaW5nICAgICAtIENvbnZlcnQgY2hhcmFjdGVyIGVuY29kaW5nCiAqIC0gbWJfY29udmVydF92YXJpYWJsZXMgICAgLSBDb252ZXJ0IGNoYXJhY3RlciBjb2RlIGluIHZhcmlhYmxlKHMpCiAqIC0gbWJfZGVjb2RlX21pbWVoZWFkZXIgICAgLSBEZWNvZGUgc3RyaW5nIGluIE1JTUUgaGVhZGVyIGZpZWxkCiAqIC0gbWJfZW5jb2RlX21pbWVoZWFkZXIgICAgLSBFbmNvZGUgc3RyaW5nIGZvciBNSU1FIGhlYWRlciBYWFggTkFUSVZFIElNUExFTUVOVEFUSU9OIElTIFJFQUxMWSBCVUdHRUQKICogLSBtYl9kZWNvZGVfbnVtZXJpY2VudGl0eSAtIERlY29kZSBIVE1MIG51bWVyaWMgc3RyaW5nIHJlZmVyZW5jZSB0byBjaGFyYWN0ZXIKICogLSBtYl9lbmNvZGVfbnVtZXJpY2VudGl0eSAtIEVuY29kZSBjaGFyYWN0ZXIgdG8gSFRNTCBudW1lcmljIHN0cmluZyByZWZlcmVuY2UKICogLSBtYl9jb252ZXJ0X2Nhc2UgICAgICAgICAtIFBlcmZvcm0gY2FzZSBmb2xkaW5nIG9uIGEgc3RyaW5nCiAqIC0gbWJfZGV0ZWN0X2VuY29kaW5nICAgICAgLSBEZXRlY3QgY2hhcmFjdGVyIGVuY29kaW5nCiAqIC0gbWJfZ2V0X2luZm8gICAgICAgICAgICAgLSBHZXQgaW50ZXJuYWwgc2V0dGluZ3Mgb2YgbWJzdHJpbmcKICogLSBtYl9odHRwX2lucHV0ICAgICAgICAgICAtIERldGVjdCBIVFRQIGlucHV0IGNoYXJhY3RlciBlbmNvZGluZwogKiAtIG1iX2h0dHBfb3V0cHV0ICAgICAgICAgIC0gU2V0L0dldCBIVFRQIG91dHB1dCBjaGFyYWN0ZXIgZW5jb2RpbmcKICogLSBtYl9pbnRlcm5hbF9lbmNvZGluZyAgICAtIFNldC9HZXQgaW50ZXJuYWwgY2hhcmFjdGVyIGVuY29kaW5nCiAqIC0gbWJfbGlzdF9lbmNvZGluZ3MgICAgICAgLSBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBzdXBwb3J0ZWQgZW5jb2RpbmdzCiAqIC0gbWJfb3JkICAgICAgICAgICAgICAgICAgLSBSZXR1cm5zIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgb2YgYSBjaGFyYWN0ZXIKICogLSBtYl9vdXRwdXRfaGFuZGxlciAgICAgICAtIENhbGxiYWNrIGZ1bmN0aW9uIGNvbnZlcnRzIGNoYXJhY3RlciBlbmNvZGluZyBpbiBvdXRwdXQgYnVmZmVyCiAqIC0gbWJfc2NydWIgICAgICAgICAgICAgICAgLSBSZXBsYWNlcyBpbGwtZm9ybWVkIGJ5dGUgc2VxdWVuY2VzIHdpdGggc3Vic3RpdHV0ZSBjaGFyYWN0ZXJzCiAqIC0gbWJfc3RybGVuICAgICAgICAgICAgICAgLSBHZXQgc3RyaW5nIGxlbmd0aAogKiAtIG1iX3N0cnBvcyAgICAgICAgICAgICAgIC0gRmluZCBwb3NpdGlvbiBvZiBmaXJzdCBvY2N1cnJlbmNlIG9mIHN0cmluZyBpbiBhIHN0cmluZwogKiAtIG1iX3N0cnJwb3MgICAgICAgICAgICAgIC0gRmluZCBwb3NpdGlvbiBvZiBsYXN0IG9jY3VycmVuY2Ugb2YgYSBzdHJpbmcgaW4gYSBzdHJpbmcKICogLSBtYl9zdHJfc3BsaXQgICAgICAgICAgICAtIENvbnZlcnQgYSBzdHJpbmcgdG8gYW4gYXJyYXkKICogLSBtYl9zdHJ0b2xvd2VyICAgICAgICAgICAtIE1ha2UgYSBzdHJpbmcgbG93ZXJjYXNlCiAqIC0gbWJfc3RydG91cHBlciAgICAgICAgICAgLSBNYWtlIGEgc3RyaW5nIHVwcGVyY2FzZQogKiAtIG1iX3N1YnN0aXR1dGVfY2hhcmFjdGVyIC0gU2V0L0dldCBzdWJzdGl0dXRpb24gY2hhcmFjdGVyCiAqIC0gbWJfc3Vic3RyICAgICAgICAgICAgICAgLSBHZXQgcGFydCBvZiBzdHJpbmcKICogLSBtYl9zdHJpcG9zICAgICAgICAgICAgICAtIEZpbmRzIHBvc2l0aW9uIG9mIGZpcnN0IG9jY3VycmVuY2Ugb2YgYSBzdHJpbmcgd2l0aGluIGFub3RoZXIsIGNhc2UgaW5zZW5zaXRpdmUKICogLSBtYl9zdHJpc3RyICAgICAgICAgICAgICAtIEZpbmRzIGZpcnN0IG9jY3VycmVuY2Ugb2YgYSBzdHJpbmcgd2l0aGluIGFub3RoZXIsIGNhc2UgaW5zZW5zaXRpdmUKICogLSBtYl9zdHJyY2hyICAgICAgICAgICAgICAtIEZpbmRzIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgYSBjaGFyYWN0ZXIgaW4gYSBzdHJpbmcgd2l0aGluIGFub3RoZXIKICogLSBtYl9zdHJyaWNociAgICAgICAgICAgICAtIEZpbmRzIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgYSBjaGFyYWN0ZXIgaW4gYSBzdHJpbmcgd2l0aGluIGFub3RoZXIsIGNhc2UgaW5zZW5zaXRpdmUKICogLSBtYl9zdHJyaXBvcyAgICAgICAgICAgICAtIEZpbmRzIHBvc2l0aW9uIG9mIGxhc3Qgb2NjdXJyZW5jZSBvZiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlciwgY2FzZSBpbnNlbnNpdGl2ZQogKiAtIG1iX3N0cnN0ciAgICAgICAgICAgICAgIC0gRmluZHMgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIHN0cmluZyB3aXRoaW4gYW5vdGhlcgogKiAtIG1iX3N0cndpZHRoICAgICAgICAgICAgIC0gUmV0dXJuIHdpZHRoIG9mIHN0cmluZwogKiAtIG1iX3N1YnN0cl9jb3VudCAgICAgICAgIC0gQ291bnQgdGhlIG51bWJlciBvZiBzdWJzdHJpbmcgb2NjdXJyZW5jZXMKICoKICogTm90IGltcGxlbWVudGVkOgogKiAtIG1iX2NvbnZlcnRfa2FuYSAgICAgICAgIC0gQ29udmVydCAia2FuYSIgb25lIGZyb20gYW5vdGhlciAoInplbi1rYWt1IiwgImhhbi1rYWt1IiBhbmQgbW9yZSkKICogLSBtYl9lcmVnXyogICAgICAgICAgICAgICAtIFJlZ3VsYXIgZXhwcmVzc2lvbiB3aXRoIG11bHRpYnl0ZSBzdXBwb3J0CiAqIC0gbWJfcGFyc2Vfc3RyICAgICAgICAgICAgLSBQYXJzZSBHRVQvUE9TVC9DT09LSUUgZGF0YSBhbmQgc2V0IGdsb2JhbCB2YXJpYWJsZQogKiAtIG1iX3ByZWZlcnJlZF9taW1lX25hbWUgIC0gR2V0IE1JTUUgY2hhcnNldCBzdHJpbmcKICogLSBtYl9yZWdleF9lbmNvZGluZyAgICAgICAtIFJldHVybnMgY3VycmVudCBlbmNvZGluZyBmb3IgbXVsdGlieXRlIHJlZ2V4IGFzIHN0cmluZwogKiAtIG1iX3JlZ2V4X3NldF9vcHRpb25zICAgIC0gU2V0L0dldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBtYnJlZ2V4IGZ1bmN0aW9ucwogKiAtIG1iX3NlbmRfbWFpbCAgICAgICAgICAgIC0gU2VuZCBlbmNvZGVkIG1haWwKICogLSBtYl9zcGxpdCAgICAgICAgICAgICAgICAtIFNwbGl0IG11bHRpYnl0ZSBzdHJpbmcgdXNpbmcgcmVndWxhciBleHByZXNzaW9uCiAqIC0gbWJfc3RyY3V0ICAgICAgICAgICAgICAgLSBHZXQgcGFydCBvZiBzdHJpbmcKICogLSBtYl9zdHJpbXdpZHRoICAgICAgICAgICAtIEdldCB0cnVuY2F0ZWQgc3RyaW5nIHdpdGggc3BlY2lmaWVkIHdpZHRoCiAqCiAqIEBhdXRob3IgTmljb2xhcyBHcmVrYXMgPHBAdGNod29yay5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KZmluYWwgY2xhc3MgTWJzdHJpbmcKewogICAgY29uc3QgTUJfQ0FTRV9GT0xEID0gUEhQX0lOVF9NQVg7CgogICAgcHJpdmF0ZSBzdGF0aWMgJGVuY29kaW5nTGlzdCA9IGFycmF5KCdBU0NJSScsICdVVEYtOCcpOwogICAgcHJpdmF0ZSBzdGF0aWMgJGxhbmd1YWdlID0gJ25ldXRyYWwnOwogICAgcHJpdmF0ZSBzdGF0aWMgJGludGVybmFsRW5jb2RpbmcgPSAnVVRGLTgnOwogICAgcHJpdmF0ZSBzdGF0aWMgJGNhc2VGb2xkID0gYXJyYXkoCiAgICAgICAgYXJyYXkoJ8K1JywgJ8W/JywgIlx4Q0RceDg1IiwgJ8+CJywgIlx4Q0ZceDkwIiwgIlx4Q0ZceDkxIiwgIlx4Q0ZceDk1IiwgIlx4Q0ZceDk2IiwgIlx4Q0ZceEIwIiwgIlx4Q0ZceEIxIiwgIlx4Q0ZceEI1IiwgIlx4RTFceEJBXHg5QiIsICJceEUxXHhCRVx4QkUiKSwKICAgICAgICBhcnJheSgnzrwnLCAncycsICfOuScsICAgICAgICAnz4MnLCAnzrInLCAgICAgICAgJ864JywgICAgICAgICfPhicsICAgICAgICAnz4AnLCAgICAgICAgJ866JywgICAgICAgICfPgScsICAgICAgICAnzrUnLCAgICAgICAgIlx4RTFceEI5XHhBMSIsICfOuScpLAogICAgKTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2NvbnZlcnRfZW5jb2RpbmcoJHMsICR0b0VuY29kaW5nLCAkZnJvbUVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoXGlzX2FycmF5KCRmcm9tRW5jb2RpbmcpIHx8IGZhbHNlICE9PSBzdHJwb3MoJGZyb21FbmNvZGluZywgJywnKSkgewogICAgICAgICAgICAkZnJvbUVuY29kaW5nID0gc2VsZjo6bWJfZGV0ZWN0X2VuY29kaW5nKCRzLCAkZnJvbUVuY29kaW5nKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZnJvbUVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGZyb21FbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICAkdG9FbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCR0b0VuY29kaW5nKTsKCiAgICAgICAgaWYgKCdCQVNFNjQnID09PSAkZnJvbUVuY29kaW5nKSB7CiAgICAgICAgICAgICRzID0gYmFzZTY0X2RlY29kZSgkcyk7CiAgICAgICAgICAgICRmcm9tRW5jb2RpbmcgPSAkdG9FbmNvZGluZzsKICAgICAgICB9CgogICAgICAgIGlmICgnQkFTRTY0JyA9PT0gJHRvRW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIGJhc2U2NF9lbmNvZGUoJHMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdIVE1MLUVOVElUSUVTJyA9PT0gJHRvRW5jb2RpbmcgfHwgJ0hUTUwnID09PSAkdG9FbmNvZGluZykgewogICAgICAgICAgICBpZiAoJ0hUTUwtRU5USVRJRVMnID09PSAkZnJvbUVuY29kaW5nIHx8ICdIVE1MJyA9PT0gJGZyb21FbmNvZGluZykgewogICAgICAgICAgICAgICAgJGZyb21FbmNvZGluZyA9ICdXaW5kb3dzLTEyNTInOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgnVVRGLTgnICE9PSAkZnJvbUVuY29kaW5nKSB7CiAgICAgICAgICAgICAgICAkcyA9IGljb252KCRmcm9tRW5jb2RpbmcsICdVVEYtOC8vSUdOT1JFJywgJHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCcvW1x4ODAtXHhGRl0rLycsIGFycmF5KF9fQ0xBU1NfXywgJ2h0bWxfZW5jb2RpbmdfY2FsbGJhY2snKSwgJHMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdIVE1MLUVOVElUSUVTJyA9PT0gJGZyb21FbmNvZGluZykgewogICAgICAgICAgICAkcyA9IGh0bWxfZW50aXR5X2RlY29kZSgkcywgRU5UX0NPTVBBVCwgJ1VURi04Jyk7CiAgICAgICAgICAgICRmcm9tRW5jb2RpbmcgPSAnVVRGLTgnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGljb252KCRmcm9tRW5jb2RpbmcsICR0b0VuY29kaW5nLicvL0lHTk9SRScsICRzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2NvbnZlcnRfdmFyaWFibGVzKCR0b0VuY29kaW5nLCAkZnJvbUVuY29kaW5nLCAmJGEgPSBudWxsLCAmJGIgPSBudWxsLCAmJGMgPSBudWxsLCAmJGQgPSBudWxsLCAmJGUgPSBudWxsLCAmJGYgPSBudWxsKQogICAgewogICAgICAgICR2YXJzID0gYXJyYXkoJiRhLCAmJGIsICYkYywgJiRkLCAmJGUsICYkZik7CgogICAgICAgICRvayA9IHRydWU7CiAgICAgICAgYXJyYXlfd2Fsa19yZWN1cnNpdmUoJHZhcnMsIGZ1bmN0aW9uICgmJHYpIHVzZSAoJiRvaywgJHRvRW5jb2RpbmcsICRmcm9tRW5jb2RpbmcpIHsKICAgICAgICAgICAgaWYgKGZhbHNlID09PSAkdiA9IE1ic3RyaW5nOjptYl9jb252ZXJ0X2VuY29kaW5nKCR2LCAkdG9FbmNvZGluZywgJGZyb21FbmNvZGluZykpIHsKICAgICAgICAgICAgICAgICRvayA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIHJldHVybiAkb2sgPyAkZnJvbUVuY29kaW5nIDogZmFsc2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9kZWNvZGVfbWltZWhlYWRlcigkcykKICAgIHsKICAgICAgICByZXR1cm4gaWNvbnZfbWltZV9kZWNvZGUoJHMsIDIsIHNlbGY6OiRpbnRlcm5hbEVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2VuY29kZV9taW1laGVhZGVyKCRzLCAkY2hhcnNldCA9IG51bGwsICR0cmFuc2ZlckVuY29kaW5nID0gbnVsbCwgJGxpbmVmZWVkID0gbnVsbCwgJGluZGVudCA9IG51bGwpCiAgICB7CiAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZW5jb2RlX21pbWVoZWFkZXIoKSBpcyBidWdnZWQuIFBsZWFzZSB1c2UgaWNvbnZfbWltZV9lbmNvZGUoKSBpbnN0ZWFkJywgRV9VU0VSX1dBUk5JTkcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZGVjb2RlX251bWVyaWNlbnRpdHkoJHMsICRjb252bWFwLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkcyAmJiAhXGlzX3NjYWxhcigkcykgJiYgIShcaXNfb2JqZWN0KCRzKSAmJiBcbWV0aG9kX2V4aXN0cygkcywgJ19fdG9TdHJpbmcnKSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZGVjb2RlX251bWVyaWNlbnRpdHkoKSBleHBlY3RzIHBhcmFtZXRlciAxIHRvIGJlIHN0cmluZywgJy5cZ2V0dHlwZSgkcykuJyBnaXZlbicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGNvbnZtYXApIHx8ICEkY29udm1hcCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGVuY29kaW5nICYmICFcaXNfc2NhbGFyKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZGVjb2RlX251bWVyaWNlbnRpdHkoKSBleHBlY3RzIHBhcmFtZXRlciAzIHRvIGJlIHN0cmluZywgJy5cZ2V0dHlwZSgkcykuJyBnaXZlbicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiAnJzsgIC8vIEluc3RlYWQgb2YgbnVsbCAoY2YuIG1iX2VuY29kZV9udW1lcmljZW50aXR5KS4KICAgICAgICB9CgogICAgICAgICRzID0gKHN0cmluZykgJHM7CiAgICAgICAgaWYgKCcnID09PSAkcykgewogICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgfQoKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwoKICAgICAgICBpZiAoJ1VURi04JyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9IG51bGw7CiAgICAgICAgICAgIGlmICghcHJlZ19tYXRjaCgnLy91JywgJHMpKSB7CiAgICAgICAgICAgICAgICAkcyA9IEBpY29udignVVRGLTgnLCAnVVRGLTgvL0lHTk9SRScsICRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRzID0gaWNvbnYoJGVuY29kaW5nLCAnVVRGLTgvL0lHTk9SRScsICRzKTsKICAgICAgICB9CgogICAgICAgICRjbnQgPSBmbG9vcihcY291bnQoJGNvbnZtYXApIC8gNCkgKiA0OwoKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkY250OyAkaSArPSA0KSB7CiAgICAgICAgICAgIC8vIGNvbGxlY3Rvcl9kZWNvZGVfaHRtbG51bWVyaWNlbnRpdHkgaWdub3JlcyAkY29udm1hcFskaSArIDNdCiAgICAgICAgICAgICRjb252bWFwWyRpXSArPSAkY29udm1hcFskaSArIDJdOwogICAgICAgICAgICAkY29udm1hcFskaSArIDFdICs9ICRjb252bWFwWyRpICsgMl07CiAgICAgICAgfQoKICAgICAgICAkcyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygnLyYjKD86MCooWzAtOV0rKXx4MCooWzAtOWEtZkEtRl0rKSkoPyEmKTs/LycsIGZ1bmN0aW9uIChhcnJheSAkbSkgdXNlICgkY250LCAkY29udm1hcCkgewogICAgICAgICAgICAkYyA9IGlzc2V0KCRtWzJdKSA/IChpbnQpIGhleGRlYygkbVsyXSkgOiAkbVsxXTsKICAgICAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGNudDsgJGkgKz0gNCkgewogICAgICAgICAgICAgICAgaWYgKCRjID49ICRjb252bWFwWyRpXSAmJiAkYyA8PSAkY29udm1hcFskaSArIDFdKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1ic3RyaW5nOjptYl9jaHIoJGMgLSAkY29udm1hcFskaSArIDJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRtWzBdOwogICAgICAgIH0sICRzKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gJHM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaWNvbnYoJ1VURi04JywgJGVuY29kaW5nLicvL0lHTk9SRScsICRzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2VuY29kZV9udW1lcmljZW50aXR5KCRzLCAkY29udm1hcCwgJGVuY29kaW5nID0gbnVsbCwgJGlzX2hleCA9IGZhbHNlKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkcyAmJiAhXGlzX3NjYWxhcigkcykgJiYgIShcaXNfb2JqZWN0KCRzKSAmJiBcbWV0aG9kX2V4aXN0cygkcywgJ19fdG9TdHJpbmcnKSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZW5jb2RlX251bWVyaWNlbnRpdHkoKSBleHBlY3RzIHBhcmFtZXRlciAxIHRvIGJlIHN0cmluZywgJy5cZ2V0dHlwZSgkcykuJyBnaXZlbicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGNvbnZtYXApIHx8ICEkY29udm1hcCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJGVuY29kaW5nICYmICFcaXNfc2NhbGFyKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfZW5jb2RlX251bWVyaWNlbnRpdHkoKSBleHBlY3RzIHBhcmFtZXRlciAzIHRvIGJlIHN0cmluZywgJy5cZ2V0dHlwZSgkcykuJyBnaXZlbicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiBudWxsOyAgLy8gSW5zdGVhZCBvZiAnJyAoY2YuIG1iX2RlY29kZV9udW1lcmljZW50aXR5KS4KICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkaXNfaGV4ICYmICFcaXNfc2NhbGFyKCRpc19oZXgpKSB7CiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoJ21iX2VuY29kZV9udW1lcmljZW50aXR5KCkgZXhwZWN0cyBwYXJhbWV0ZXIgNCB0byBiZSBib29sZWFuLCAnLlxnZXR0eXBlKCRzKS4nIGdpdmVuJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkcyA9IChzdHJpbmcpICRzOwogICAgICAgIGlmICgnJyA9PT0gJHMpIHsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KCiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKCiAgICAgICAgaWYgKCdVVEYtOCcgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICAkZW5jb2RpbmcgPSBudWxsOwogICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy8vdScsICRzKSkgewogICAgICAgICAgICAgICAgJHMgPSBAaWNvbnYoJ1VURi04JywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcyA9IGljb252KCRlbmNvZGluZywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgJHVsZW5NYXNrID0gYXJyYXkoIlx4QzAiID0+IDIsICJceEQwIiA9PiAyLCAiXHhFMCIgPT4gMywgIlx4RjAiID0+IDQpOwoKICAgICAgICAkY250ID0gZmxvb3IoXGNvdW50KCRjb252bWFwKSAvIDQpICogNDsKICAgICAgICAkaSA9IDA7CiAgICAgICAgJGxlbiA9IFxzdHJsZW4oJHMpOwogICAgICAgICRyZXN1bHQgPSAnJzsKCiAgICAgICAgd2hpbGUgKCRpIDwgJGxlbikgewogICAgICAgICAgICAkdWxlbiA9ICRzWyRpXSA8ICJceDgwIiA/IDEgOiAkdWxlbk1hc2tbJHNbJGldICYgIlx4RjAiXTsKICAgICAgICAgICAgJHVjaHIgPSBzdWJzdHIoJHMsICRpLCAkdWxlbik7CiAgICAgICAgICAgICRpICs9ICR1bGVuOwogICAgICAgICAgICAkYyA9IHNlbGY6Om1iX29yZCgkdWNocik7CgogICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkY250OyAkaiArPSA0KSB7CiAgICAgICAgICAgICAgICBpZiAoJGMgPj0gJGNvbnZtYXBbJGpdICYmICRjIDw9ICRjb252bWFwWyRqICsgMV0pIHsKICAgICAgICAgICAgICAgICAgICAkY09mZnNldCA9ICgkYyArICRjb252bWFwWyRqICsgMl0pICYgJGNvbnZtYXBbJGogKyAzXTsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICRpc19oZXggPyBzcHJpbnRmKCcmI3glWDsnLCAkY09mZnNldCkgOiAnJiMnLiRjT2Zmc2V0Lic7JzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHQgLj0gJHVjaHI7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGljb252KCdVVEYtOCcsICRlbmNvZGluZy4nLy9JR05PUkUnLCAkcmVzdWx0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2NvbnZlcnRfY2FzZSgkcywgJG1vZGUsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJHMgPSAoc3RyaW5nKSAkczsKICAgICAgICBpZiAoJycgPT09ICRzKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CgogICAgICAgIGlmICgnVVRGLTgnID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgJGVuY29kaW5nID0gbnVsbDsKICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvL3UnLCAkcykpIHsKICAgICAgICAgICAgICAgICRzID0gQGljb252KCdVVEYtOCcsICdVVEYtOC8vSUdOT1JFJywgJHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHMgPSBpY29udigkZW5jb2RpbmcsICdVVEYtOC8vSUdOT1JFJywgJHMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKE1CX0NBU0VfVElUTEUgPT0gJG1vZGUpIHsKICAgICAgICAgICAgc3RhdGljICR0aXRsZVJlZ2V4cCA9IG51bGw7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkdGl0bGVSZWdleHApIHsKICAgICAgICAgICAgICAgICR0aXRsZVJlZ2V4cCA9IHNlbGY6OmdldERhdGEoJ3RpdGxlQ2FzZVJlZ2V4cCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCR0aXRsZVJlZ2V4cCwgYXJyYXkoX19DTEFTU19fLCAndGl0bGVfY2FzZScpLCAkcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKE1CX0NBU0VfVVBQRVIgPT0gJG1vZGUpIHsKICAgICAgICAgICAgICAgIHN0YXRpYyAkdXBwZXIgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICR1cHBlcikgewogICAgICAgICAgICAgICAgICAgICR1cHBlciA9IHNlbGY6OmdldERhdGEoJ3VwcGVyQ2FzZScpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1hcCA9ICR1cHBlcjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChzZWxmOjpNQl9DQVNFX0ZPTEQgPT09ICRtb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgJHMgPSBzdHJfcmVwbGFjZShzZWxmOjokY2FzZUZvbGRbMF0sIHNlbGY6OiRjYXNlRm9sZFsxXSwgJHMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHN0YXRpYyAkbG93ZXIgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09ICRsb3dlcikgewogICAgICAgICAgICAgICAgICAgICRsb3dlciA9IHNlbGY6OmdldERhdGEoJ2xvd2VyQ2FzZScpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1hcCA9ICRsb3dlcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RhdGljICR1bGVuTWFzayA9IGFycmF5KCJceEMwIiA9PiAyLCAiXHhEMCIgPT4gMiwgIlx4RTAiID0+IDMsICJceEYwIiA9PiA0KTsKCiAgICAgICAgICAgICRpID0gMDsKICAgICAgICAgICAgJGxlbiA9IFxzdHJsZW4oJHMpOwoKICAgICAgICAgICAgd2hpbGUgKCRpIDwgJGxlbikgewogICAgICAgICAgICAgICAgJHVsZW4gPSAkc1skaV0gPCAiXHg4MCIgPyAxIDogJHVsZW5NYXNrWyRzWyRpXSAmICJceEYwIl07CiAgICAgICAgICAgICAgICAkdWNociA9IHN1YnN0cigkcywgJGksICR1bGVuKTsKICAgICAgICAgICAgICAgICRpICs9ICR1bGVuOwoKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbWFwWyR1Y2hyXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdWNociA9ICRtYXBbJHVjaHJdOwogICAgICAgICAgICAgICAgICAgICRubGVuID0gXHN0cmxlbigkdWNocik7CgogICAgICAgICAgICAgICAgICAgIGlmICgkbmxlbiA9PSAkdWxlbikgewogICAgICAgICAgICAgICAgICAgICAgICAkbmxlbiA9ICRpOwogICAgICAgICAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc1stLSRubGVuXSA9ICR1Y2hyWy0tJHVsZW5dOwogICAgICAgICAgICAgICAgICAgICAgICB9IHdoaWxlICgkdWxlbik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHMgPSBzdWJzdHJfcmVwbGFjZSgkcywgJHVjaHIsICRpIC0gJHVsZW4sICR1bGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGxlbiArPSAkbmxlbiAtICR1bGVuOwogICAgICAgICAgICAgICAgICAgICAgICAkaSArPSAkbmxlbiAtICR1bGVuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gJHM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaWNvbnYoJ1VURi04JywgJGVuY29kaW5nLicvL0lHTk9SRScsICRzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2ludGVybmFsX2VuY29kaW5nKCRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGludGVybmFsRW5jb2Rpbmc7CiAgICAgICAgfQoKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwoKICAgICAgICBpZiAoJ1VURi04JyA9PT0gJGVuY29kaW5nIHx8IGZhbHNlICE9PSBAaWNvbnYoJGVuY29kaW5nLCAkZW5jb2RpbmcsICcgJykpIHsKICAgICAgICAgICAgc2VsZjo6JGludGVybmFsRW5jb2RpbmcgPSAkZW5jb2Rpbmc7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2xhbmd1YWdlKCRsYW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGxhbmcpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRsYW5ndWFnZTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoJGxhbmcgPSBzdHJ0b2xvd2VyKCRsYW5nKSkgewogICAgICAgICAgICBjYXNlICd1bmknOgogICAgICAgICAgICBjYXNlICduZXV0cmFsJzoKICAgICAgICAgICAgICAgIHNlbGY6OiRsYW5ndWFnZSA9ICRsYW5nOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfbGlzdF9lbmNvZGluZ3MoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgnVVRGLTgnKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2VuY29kaW5nX2FsaWFzZXMoJGVuY29kaW5nKQogICAgewogICAgICAgIHN3aXRjaCAoc3RydG91cHBlcigkZW5jb2RpbmcpKSB7CiAgICAgICAgICAgIGNhc2UgJ1VURjgnOgogICAgICAgICAgICBjYXNlICdVVEYtOCc6CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJ3V0ZjgnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2NoZWNrX2VuY29kaW5nKCR2YXIgPSBudWxsLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICR2YXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjokaW50ZXJuYWxFbmNvZGluZzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjptYl9kZXRlY3RfZW5jb2RpbmcoJHZhciwgYXJyYXkoJGVuY29kaW5nKSkgfHwgZmFsc2UgIT09IEBpY29udigkZW5jb2RpbmcsICRlbmNvZGluZywgJHZhcik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0ciwgJGVuY29kaW5nTGlzdCA9IG51bGwsICRzdHJpY3QgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGVuY29kaW5nTGlzdCkgewogICAgICAgICAgICAkZW5jb2RpbmdMaXN0ID0gc2VsZjo6JGVuY29kaW5nTGlzdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIVxpc19hcnJheSgkZW5jb2RpbmdMaXN0KSkgewogICAgICAgICAgICAgICAgJGVuY29kaW5nTGlzdCA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCAkZW5jb2RpbmdMaXN0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVuY29kaW5nTGlzdCA9IGFycmF5X21hcCgnc3RydG91cHBlcicsICRlbmNvZGluZ0xpc3QpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGVuY29kaW5nTGlzdCBhcyAkZW5jKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJGVuYykgewogICAgICAgICAgICAgICAgY2FzZSAnQVNDSUknOgogICAgICAgICAgICAgICAgICAgIGlmICghcHJlZ19tYXRjaCgnL1tceDgwLVx4RkZdLycsICRzdHIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZW5jOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdVVEY4JzoKICAgICAgICAgICAgICAgIGNhc2UgJ1VURi04JzoKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnLy91JywgJHN0cikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdVVEYtOCc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09IHN0cm5jbXAoJGVuYywgJ0lTTy04ODU5LScsIDkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZW5jOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZGV0ZWN0X29yZGVyKCRlbmNvZGluZ0xpc3QgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkZW5jb2RpbmdMaXN0KSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjokZW5jb2RpbmdMaXN0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGVuY29kaW5nTGlzdCkpIHsKICAgICAgICAgICAgJGVuY29kaW5nTGlzdCA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCAkZW5jb2RpbmdMaXN0KSk7CiAgICAgICAgfQogICAgICAgICRlbmNvZGluZ0xpc3QgPSBhcnJheV9tYXAoJ3N0cnRvdXBwZXInLCAkZW5jb2RpbmdMaXN0KTsKCiAgICAgICAgZm9yZWFjaCAoJGVuY29kaW5nTGlzdCBhcyAkZW5jKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJGVuYykgewogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybmNtcCgkZW5jLCAnSVNPLTg4NTktJywgOSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBubyBicmVhawogICAgICAgICAgICAgICAgY2FzZSAnQVNDSUknOgogICAgICAgICAgICAgICAgY2FzZSAnVVRGOCc6CiAgICAgICAgICAgICAgICBjYXNlICdVVEYtOCc6CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHNlbGY6OiRlbmNvZGluZ0xpc3QgPSAkZW5jb2RpbmdMaXN0OwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cmxlbigkcywgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwogICAgICAgIGlmICgnQ1A4NTAnID09PSAkZW5jb2RpbmcgfHwgJ0FTQ0lJJyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiBcc3RybGVuKCRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBAaWNvbnZfc3RybGVuKCRzLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCA9IDAsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKICAgICAgICBpZiAoJ0NQODUwJyA9PT0gJGVuY29kaW5nIHx8ICdBU0NJSScgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gc3RycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCk7CiAgICAgICAgfQoKICAgICAgICAkbmVlZGxlID0gKHN0cmluZykgJG5lZWRsZTsKICAgICAgICBpZiAoJycgPT09ICRuZWVkbGUpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcihfX01FVEhPRF9fLic6IEVtcHR5IGRlbGltaXRlcicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpY29udl9zdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0LCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQgPSAwLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZyk7CiAgICAgICAgaWYgKCdDUDg1MCcgPT09ICRlbmNvZGluZyB8fCAnQVNDSUknID09PSAkZW5jb2RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cnJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0KTsKICAgICAgICB9CgogICAgICAgIGlmICgkb2Zmc2V0ICE9IChpbnQpICRvZmZzZXQpIHsKICAgICAgICAgICAgJG9mZnNldCA9IDA7CiAgICAgICAgfSBlbHNlaWYgKCRvZmZzZXQgPSAoaW50KSAkb2Zmc2V0KSB7CiAgICAgICAgICAgIGlmICgkb2Zmc2V0IDwgMCkgewogICAgICAgICAgICAgICAgaWYgKDAgPiAkb2Zmc2V0ICs9IHNlbGY6Om1iX3N0cmxlbigkbmVlZGxlKSkgewogICAgICAgICAgICAgICAgICAgICRoYXlzdGFjayA9IHNlbGY6Om1iX3N1YnN0cigkaGF5c3RhY2ssIDAsICRvZmZzZXQsICRlbmNvZGluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkb2Zmc2V0ID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRoYXlzdGFjayA9IHNlbGY6Om1iX3N1YnN0cigkaGF5c3RhY2ssICRvZmZzZXQsIDIxNDc0ODM2NDcsICRlbmNvZGluZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRwb3MgPSBpY29udl9zdHJycG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJGVuY29kaW5nKTsKCiAgICAgICAgcmV0dXJuIGZhbHNlICE9PSAkcG9zID8gJG9mZnNldCArICRwb3MgOiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cl9zcGxpdCgkc3RyaW5nLCAkc3BsaXRfbGVuZ3RoID0gMSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHN0cmluZyAmJiAhXGlzX3NjYWxhcigkc3RyaW5nKSAmJiAhKFxpc19vYmplY3QoJHN0cmluZykgJiYgXG1ldGhvZF9leGlzdHMoJHN0cmluZywgJ19fdG9TdHJpbmcnKSkpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcignbWJfc3RyX3NwbGl0KCkgZXhwZWN0cyBwYXJhbWV0ZXIgMSB0byBiZSBzdHJpbmcsICcuXGdldHR5cGUoJHN0cmluZykuJyBnaXZlbicsIEVfVVNFUl9XQVJOSU5HKTsKCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPiAkc3BsaXRfbGVuZ3RoID0gKGludCkgJHNwbGl0X2xlbmd0aCkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdUaGUgbGVuZ3RoIG9mIGVhY2ggc2VnbWVudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvJywgRV9VU0VSX1dBUk5JTkcpOwoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICAkZW5jb2RpbmcgPSBtYl9pbnRlcm5hbF9lbmNvZGluZygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdVVEYtOCcgPT09ICRlbmNvZGluZyA9IHNlbGY6OmdldEVuY29kaW5nKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgJHJ4ID0gJy8oJzsKICAgICAgICAgICAgd2hpbGUgKDY1NTM1IDwgJHNwbGl0X2xlbmd0aCkgewogICAgICAgICAgICAgICAgJHJ4IC49ICcuezY1NTM1fSc7CiAgICAgICAgICAgICAgICAkc3BsaXRfbGVuZ3RoIC09IDY1NTM1OwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyeCAuPSAnLnsnLiRzcGxpdF9sZW5ndGguJ30pL3VzJzsKCiAgICAgICAgICAgIHJldHVybiBwcmVnX3NwbGl0KCRyeCwgJHN0cmluZywgbnVsbCwgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFIHwgUFJFR19TUExJVF9OT19FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgICAgICAkbGVuZ3RoID0gbWJfc3RybGVuKCRzdHJpbmcsICRlbmNvZGluZyk7CgogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsZW5ndGg7ICRpICs9ICRzcGxpdF9sZW5ndGgpIHsKICAgICAgICAgICAgJHJlc3VsdFtdID0gbWJfc3Vic3RyKCRzdHJpbmcsICRpLCAkc3BsaXRfbGVuZ3RoLCAkZW5jb2RpbmcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJ0b2xvd2VyKCRzLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJHMsIE1CX0NBU0VfTE9XRVIsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJ0b3VwcGVyKCRzLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJHMsIE1CX0NBU0VfVVBQRVIsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdWJzdGl0dXRlX2NoYXJhY3RlcigkYyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKDAgPT09IHN0cmNhc2VjbXAoJGMsICdub25lJykpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbCAhPT0gJGMgPyBmYWxzZSA6ICdub25lJzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N1YnN0cigkcywgJHN0YXJ0LCAkbGVuZ3RoID0gbnVsbCwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpOwogICAgICAgIGlmICgnQ1A4NTAnID09PSAkZW5jb2RpbmcgfHwgJ0FTQ0lJJyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RyaW5nKSBzdWJzdHIoJHMsICRzdGFydCwgbnVsbCA9PT0gJGxlbmd0aCA/IDIxNDc0ODM2NDcgOiAkbGVuZ3RoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkc3RhcnQgPCAwKSB7CiAgICAgICAgICAgICRzdGFydCA9IGljb252X3N0cmxlbigkcywgJGVuY29kaW5nKSArICRzdGFydDsKICAgICAgICAgICAgaWYgKCRzdGFydCA8IDApIHsKICAgICAgICAgICAgICAgICRzdGFydCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkbGVuZ3RoKSB7CiAgICAgICAgICAgICRsZW5ndGggPSAyMTQ3NDgzNjQ3OwogICAgICAgIH0gZWxzZWlmICgkbGVuZ3RoIDwgMCkgewogICAgICAgICAgICAkbGVuZ3RoID0gaWNvbnZfc3RybGVuKCRzLCAkZW5jb2RpbmcpICsgJGxlbmd0aCAtICRzdGFydDsKICAgICAgICAgICAgaWYgKCRsZW5ndGggPCAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAoc3RyaW5nKSBpY29udl9zdWJzdHIoJHMsICRzdGFydCwgJGxlbmd0aCwgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0ID0gMCwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkaGF5c3RhY2sgPSBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJGhheXN0YWNrLCBzZWxmOjpNQl9DQVNFX0ZPTEQsICRlbmNvZGluZyk7CiAgICAgICAgJG5lZWRsZSA9IHNlbGY6Om1iX2NvbnZlcnRfY2FzZSgkbmVlZGxlLCBzZWxmOjpNQl9DQVNFX0ZPTEQsICRlbmNvZGluZyk7CgogICAgICAgIHJldHVybiBzZWxmOjptYl9zdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkb2Zmc2V0LCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RyaXN0cigkaGF5c3RhY2ssICRuZWVkbGUsICRwYXJ0ID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJHBvcyA9IHNlbGY6Om1iX3N0cmlwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAwLCAkZW5jb2RpbmcpOwoKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0U3VicGFydCgkcG9zLCAkcGFydCwgJGhheXN0YWNrLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3RycmNocigkaGF5c3RhY2ssICRuZWVkbGUsICRwYXJ0ID0gZmFsc2UsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKICAgICAgICBpZiAoJ0NQODUwJyA9PT0gJGVuY29kaW5nIHx8ICdBU0NJSScgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICAkcG9zID0gc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRuZWVkbGUgPSBzZWxmOjptYl9zdWJzdHIoJG5lZWRsZSwgMCwgMSwgJGVuY29kaW5nKTsKICAgICAgICAgICAgJHBvcyA9IGljb252X3N0cnJwb3MoJGhheXN0YWNrLCAkbmVlZGxlLCAkZW5jb2RpbmcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OmdldFN1YnBhcnQoJHBvcywgJHBhcnQsICRoYXlzdGFjaywgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cnJpY2hyKCRoYXlzdGFjaywgJG5lZWRsZSwgJHBhcnQgPSBmYWxzZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICAkbmVlZGxlID0gc2VsZjo6bWJfc3Vic3RyKCRuZWVkbGUsIDAsIDEsICRlbmNvZGluZyk7CiAgICAgICAgJHBvcyA9IHNlbGY6Om1iX3N0cnJpcG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJGVuY29kaW5nKTsKCiAgICAgICAgcmV0dXJuIHNlbGY6OmdldFN1YnBhcnQoJHBvcywgJHBhcnQsICRoYXlzdGFjaywgJGVuY29kaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3N0cnJpcG9zKCRoYXlzdGFjaywgJG5lZWRsZSwgJG9mZnNldCA9IDAsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJGhheXN0YWNrID0gc2VsZjo6bWJfY29udmVydF9jYXNlKCRoYXlzdGFjaywgc2VsZjo6TUJfQ0FTRV9GT0xELCAkZW5jb2RpbmcpOwogICAgICAgICRuZWVkbGUgPSBzZWxmOjptYl9jb252ZXJ0X2Nhc2UoJG5lZWRsZSwgc2VsZjo6TUJfQ0FTRV9GT0xELCAkZW5jb2RpbmcpOwoKICAgICAgICByZXR1cm4gc2VsZjo6bWJfc3RycnBvcygkaGF5c3RhY2ssICRuZWVkbGUsICRvZmZzZXQsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9zdHJzdHIoJGhheXN0YWNrLCAkbmVlZGxlLCAkcGFydCA9IGZhbHNlLCAkZW5jb2RpbmcgPSBudWxsKQogICAgewogICAgICAgICRwb3MgPSBzdHJwb3MoJGhheXN0YWNrLCAkbmVlZGxlKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRwb3MpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoJHBhcnQpIHsKICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkaGF5c3RhY2ssIDAsICRwb3MpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN1YnN0cigkaGF5c3RhY2ssICRwb3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfZ2V0X2luZm8oJHR5cGUgPSAnYWxsJykKICAgIHsKICAgICAgICAkaW5mbyA9IGFycmF5KAogICAgICAgICAgICAnaW50ZXJuYWxfZW5jb2RpbmcnID0+IHNlbGY6OiRpbnRlcm5hbEVuY29kaW5nLAogICAgICAgICAgICAnaHR0cF9vdXRwdXQnID0+ICdwYXNzJywKICAgICAgICAgICAgJ2h0dHBfb3V0cHV0X2NvbnZfbWltZXR5cGVzJyA9PiAnXih0ZXh0L3xhcHBsaWNhdGlvbi94aHRtbFwreG1sKScsCiAgICAgICAgICAgICdmdW5jX292ZXJsb2FkJyA9PiAwLAogICAgICAgICAgICAnZnVuY19vdmVybG9hZF9saXN0JyA9PiAnbm8gb3ZlcmxvYWQnLAogICAgICAgICAgICAnbWFpbF9jaGFyc2V0JyA9PiAnVVRGLTgnLAogICAgICAgICAgICAnbWFpbF9oZWFkZXJfZW5jb2RpbmcnID0+ICdCQVNFNjQnLAogICAgICAgICAgICAnbWFpbF9ib2R5X2VuY29kaW5nJyA9PiAnQkFTRTY0JywKICAgICAgICAgICAgJ2lsbGVnYWxfY2hhcnMnID0+IDAsCiAgICAgICAgICAgICdlbmNvZGluZ190cmFuc2xhdGlvbicgPT4gJ09mZicsCiAgICAgICAgICAgICdsYW5ndWFnZScgPT4gc2VsZjo6JGxhbmd1YWdlLAogICAgICAgICAgICAnZGV0ZWN0X29yZGVyJyA9PiBzZWxmOjokZW5jb2RpbmdMaXN0LAogICAgICAgICAgICAnc3Vic3RpdHV0ZV9jaGFyYWN0ZXInID0+ICdub25lJywKICAgICAgICAgICAgJ3N0cmljdF9kZXRlY3Rpb24nID0+ICdPZmYnLAogICAgICAgICk7CgogICAgICAgIGlmICgnYWxsJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuICRpbmZvOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGluZm9bJHR5cGVdKSkgewogICAgICAgICAgICByZXR1cm4gJGluZm9bJHR5cGVdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfaHR0cF9pbnB1dCgkdHlwZSA9ICcnKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2h0dHBfb3V0cHV0KCRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIG51bGwgIT09ICRlbmNvZGluZyA/ICdwYXNzJyA9PT0gJGVuY29kaW5nIDogJ3Bhc3MnOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3Ryd2lkdGgoJHMsICRlbmNvZGluZyA9IG51bGwpCiAgICB7CiAgICAgICAgJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKTsKCiAgICAgICAgaWYgKCdVVEYtOCcgIT09ICRlbmNvZGluZykgewogICAgICAgICAgICAkcyA9IGljb252KCRlbmNvZGluZywgJ1VURi04Ly9JR05PUkUnLCAkcyk7CiAgICAgICAgfQoKICAgICAgICAkcyA9IHByZWdfcmVwbGFjZSgnL1tceHsxMTAwfS1ceHsxMTVGfVx4ezIzMjl9XHh7MjMyQX1ceHsyRTgwfS1ceHszMDNFfVx4ezMwNDB9LVx4e0E0Q0Z9XHh7QUMwMH0tXHh7RDdBM31ceHtGOTAwfS1ceHtGQUZGfVx4e0ZFMTB9LVx4e0ZFMTl9XHh7RkUzMH0tXHh7RkU2Rn1ceHtGRjAwfS1ceHtGRjYwfVx4e0ZGRTB9LVx4e0ZGRTZ9XHh7MjAwMDB9LVx4ezJGRkZEfVx4ezMwMDAwfS1ceHszRkZGRH1dL3UnLCAnJywgJHMsIC0xLCAkd2lkZSk7CgogICAgICAgIHJldHVybiAoJHdpZGUgPDwgMSkgKyBpY29udl9zdHJsZW4oJHMsICdVVEYtOCcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWJfc3Vic3RyX2NvdW50KCRoYXlzdGFjaywgJG5lZWRsZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gc3Vic3RyX2NvdW50KCRoYXlzdGFjaywgJG5lZWRsZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYl9vdXRwdXRfaGFuZGxlcigkY29udGVudHMsICRzdGF0dXMpCiAgICB7CiAgICAgICAgcmV0dXJuICRjb250ZW50czsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX2NocigkY29kZSwgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoMHg4MCA+ICRjb2RlICU9IDB4MjAwMDAwKSB7CiAgICAgICAgICAgICRzID0gXGNocigkY29kZSk7CiAgICAgICAgfSBlbHNlaWYgKDB4ODAwID4gJGNvZGUpIHsKICAgICAgICAgICAgJHMgPSBcY2hyKDB4QzAgfCAkY29kZSA+PiA2KS5cY2hyKDB4ODAgfCAkY29kZSAmIDB4M0YpOwogICAgICAgIH0gZWxzZWlmICgweDEwMDAwID4gJGNvZGUpIHsKICAgICAgICAgICAgJHMgPSBcY2hyKDB4RTAgfCAkY29kZSA+PiAxMikuXGNocigweDgwIHwgJGNvZGUgPj4gNiAmIDB4M0YpLlxjaHIoMHg4MCB8ICRjb2RlICYgMHgzRik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHMgPSBcY2hyKDB4RjAgfCAkY29kZSA+PiAxOCkuXGNocigweDgwIHwgJGNvZGUgPj4gMTIgJiAweDNGKS5cY2hyKDB4ODAgfCAkY29kZSA+PiA2ICYgMHgzRikuXGNocigweDgwIHwgJGNvZGUgJiAweDNGKTsKICAgICAgICB9CgogICAgICAgIGlmICgnVVRGLTgnICE9PSAkZW5jb2RpbmcgPSBzZWxmOjpnZXRFbmNvZGluZygkZW5jb2RpbmcpKSB7CiAgICAgICAgICAgICRzID0gbWJfY29udmVydF9lbmNvZGluZygkcywgJGVuY29kaW5nLCAnVVRGLTgnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkczsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX29yZCgkcywgJGVuY29kaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJ1VURi04JyAhPT0gJGVuY29kaW5nID0gc2VsZjo6Z2V0RW5jb2RpbmcoJGVuY29kaW5nKSkgewogICAgICAgICAgICAkcyA9IG1iX2NvbnZlcnRfZW5jb2RpbmcoJHMsICdVVEYtOCcsICRlbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoMSA9PT0gXHN0cmxlbigkcykpIHsKICAgICAgICAgICAgcmV0dXJuIFxvcmQoJHMpOwogICAgICAgIH0KCiAgICAgICAgJGNvZGUgPSAoJHMgPSB1bnBhY2soJ0MqJywgc3Vic3RyKCRzLCAwLCA0KSkpID8gJHNbMV0gOiAwOwogICAgICAgIGlmICgweEYwIDw9ICRjb2RlKSB7CiAgICAgICAgICAgIHJldHVybiAoKCRjb2RlIC0gMHhGMCkgPDwgMTgpICsgKCgkc1syXSAtIDB4ODApIDw8IDEyKSArICgoJHNbM10gLSAweDgwKSA8PCA2KSArICRzWzRdIC0gMHg4MDsKICAgICAgICB9CiAgICAgICAgaWYgKDB4RTAgPD0gJGNvZGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoJGNvZGUgLSAweEUwKSA8PCAxMikgKyAoKCRzWzJdIC0gMHg4MCkgPDwgNikgKyAkc1szXSAtIDB4ODA7CiAgICAgICAgfQogICAgICAgIGlmICgweEMwIDw9ICRjb2RlKSB7CiAgICAgICAgICAgIHJldHVybiAoKCRjb2RlIC0gMHhDMCkgPDwgNikgKyAkc1syXSAtIDB4ODA7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvZGU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0U3VicGFydCgkcG9zLCAkcGFydCwgJGhheXN0YWNrLCAkZW5jb2RpbmcpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSAkcG9zKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRwYXJ0KSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOjptYl9zdWJzdHIoJGhheXN0YWNrLCAwLCAkcG9zLCAkZW5jb2RpbmcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6Om1iX3N1YnN0cigkaGF5c3RhY2ssICRwb3MsIG51bGwsICRlbmNvZGluZyk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaHRtbF9lbmNvZGluZ19jYWxsYmFjayhhcnJheSAkbSkKICAgIHsKICAgICAgICAkaSA9IDE7CiAgICAgICAgJGVudGl0aWVzID0gJyc7CiAgICAgICAgJG0gPSB1bnBhY2soJ0MqJywgaHRtbGVudGl0aWVzKCRtWzBdLCBFTlRfQ09NUEFULCAnVVRGLTgnKSk7CgogICAgICAgIHdoaWxlIChpc3NldCgkbVskaV0pKSB7CiAgICAgICAgICAgIGlmICgweDgwID4gJG1bJGldKSB7CiAgICAgICAgICAgICAgICAkZW50aXRpZXMgLj0gXGNocigkbVskaSsrXSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoMHhGMCA8PSAkbVskaV0pIHsKICAgICAgICAgICAgICAgICRjID0gKCgkbVskaSsrXSAtIDB4RjApIDw8IDE4KSArICgoJG1bJGkrK10gLSAweDgwKSA8PCAxMikgKyAoKCRtWyRpKytdIC0gMHg4MCkgPDwgNikgKyAkbVskaSsrXSAtIDB4ODA7CiAgICAgICAgICAgIH0gZWxzZWlmICgweEUwIDw9ICRtWyRpXSkgewogICAgICAgICAgICAgICAgJGMgPSAoKCRtWyRpKytdIC0gMHhFMCkgPDwgMTIpICsgKCgkbVskaSsrXSAtIDB4ODApIDw8IDYpICsgJG1bJGkrK10gLSAweDgwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGMgPSAoKCRtWyRpKytdIC0gMHhDMCkgPDwgNikgKyAkbVskaSsrXSAtIDB4ODA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRlbnRpdGllcyAuPSAnJiMnLiRjLic7JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZW50aXRpZXM7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdGl0bGVfY2FzZShhcnJheSAkcykKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6bWJfY29udmVydF9jYXNlKCRzWzFdLCBNQl9DQVNFX1VQUEVSLCAnVVRGLTgnKS5zZWxmOjptYl9jb252ZXJ0X2Nhc2UoJHNbMl0sIE1CX0NBU0VfTE9XRVIsICdVVEYtOCcpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldERhdGEoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCRmaWxlID0gX19ESVJfXy4nL1Jlc291cmNlcy91bmlkYXRhLycuJGZpbGUuJy5waHAnKSkgewogICAgICAgICAgICByZXR1cm4gcmVxdWlyZSAkZmlsZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRFbmNvZGluZygkZW5jb2RpbmcpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JGludGVybmFsRW5jb2Rpbmc7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ1VURi04JyA9PT0gJGVuY29kaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAnVVRGLTgnOwogICAgICAgIH0KCiAgICAgICAgJGVuY29kaW5nID0gc3RydG91cHBlcigkZW5jb2RpbmcpOwoKICAgICAgICBpZiAoJzhCSVQnID09PSAkZW5jb2RpbmcgfHwgJ0JJTkFSWScgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gJ0NQODUwJzsKICAgICAgICB9CgogICAgICAgIGlmICgnVVRGOCcgPT09ICRlbmNvZGluZykgewogICAgICAgICAgICByZXR1cm4gJ1VURi04JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZW5jb2Rpbmc7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlc3RlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxBcnJheUlucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxTdHJlYW1PdXRwdXQ7CgovKioKICogRWFzZXMgdGhlIHRlc3Rpbmcgb2YgY29uc29sZSBhcHBsaWNhdGlvbnMuCiAqCiAqIFdoZW4gdGVzdGluZyBhbiBhcHBsaWNhdGlvbiwgZG9uJ3QgZm9yZ2V0IHRvIGRpc2FibGUgdGhlIGF1dG8gZXhpdCBmbGFnOgogKgogKiAgICAgJGFwcGxpY2F0aW9uID0gbmV3IEFwcGxpY2F0aW9uKCk7CiAqICAgICAkYXBwbGljYXRpb24tPnNldEF1dG9FeGl0KGZhbHNlKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBBcHBsaWNhdGlvblRlc3Rlcgp7CiAgICBwcml2YXRlICRhcHBsaWNhdGlvbjsKICAgIHByaXZhdGUgJGlucHV0OwogICAgcHJpdmF0ZSAkc3RhdHVzQ29kZTsKICAgIC8qKgogICAgICogQHZhciBPdXRwdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkb3V0cHV0OwogICAgcHJpdmF0ZSAkY2FwdHVyZVN0cmVhbXNJbmRlcGVuZGVudGx5ID0gZmFsc2U7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KEFwcGxpY2F0aW9uICRhcHBsaWNhdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+YXBwbGljYXRpb24gPSAkYXBwbGljYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQXZhaWxhYmxlIG9wdGlvbnM6CiAgICAgKgogICAgICogICogaW50ZXJhY3RpdmU6ICAgICAgICAgICAgICAgU2V0cyB0aGUgaW5wdXQgaW50ZXJhY3RpdmUgZmxhZwogICAgICogICogZGVjb3JhdGVkOiAgICAgICAgICAgICAgICAgU2V0cyB0aGUgb3V0cHV0IGRlY29yYXRlZCBmbGFnCiAgICAgKiAgKiB2ZXJib3NpdHk6ICAgICAgICAgICAgICAgICBTZXRzIHRoZSBvdXRwdXQgdmVyYm9zaXR5IGZsYWcKICAgICAqICAqIGNhcHR1cmVfc3RkZXJyX3NlcGFyYXRlbHk6IE1ha2Ugb3V0cHV0IG9mIHN0ZE91dCBhbmQgc3RkRXJyIHNlcGFyYXRlbHkgYXZhaWxhYmxlCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRpbnB1dCAgIEFuIGFycmF5IG9mIGFyZ3VtZW50cyBhbmQgb3B0aW9ucwogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zIEFuIGFycmF5IG9mIG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJ1bihhcnJheSAkaW5wdXQsICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gbmV3IEFycmF5SW5wdXQoJGlucHV0KTsKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ2ludGVyYWN0aXZlJ10pKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnB1dC0+c2V0SW50ZXJhY3RpdmUoJG9wdGlvbnNbJ2ludGVyYWN0aXZlJ10pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNhcHR1cmVTdHJlYW1zSW5kZXBlbmRlbnRseSA9IFxhcnJheV9rZXlfZXhpc3RzKCdjYXB0dXJlX3N0ZGVycl9zZXBhcmF0ZWx5JywgJG9wdGlvbnMpICYmICRvcHRpb25zWydjYXB0dXJlX3N0ZGVycl9zZXBhcmF0ZWx5J107CiAgICAgICAgaWYgKCEkdGhpcy0+Y2FwdHVyZVN0cmVhbXNJbmRlcGVuZGVudGx5KSB7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQgPSBuZXcgU3RyZWFtT3V0cHV0KGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAndycsIGZhbHNlKSk7CiAgICAgICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1snZGVjb3JhdGVkJ10pKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0LT5zZXREZWNvcmF0ZWQoJG9wdGlvbnNbJ2RlY29yYXRlZCddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbJ3ZlcmJvc2l0eSddKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPm91dHB1dC0+c2V0VmVyYm9zaXR5KCRvcHRpb25zWyd2ZXJib3NpdHknXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+b3V0cHV0ID0gbmV3IENvbnNvbGVPdXRwdXQoCiAgICAgICAgICAgICAgICBpc3NldCgkb3B0aW9uc1sndmVyYm9zaXR5J10pID8gJG9wdGlvbnNbJ3ZlcmJvc2l0eSddIDogQ29uc29sZU91dHB1dDo6VkVSQk9TSVRZX05PUk1BTCwKICAgICAgICAgICAgICAgIGlzc2V0KCRvcHRpb25zWydkZWNvcmF0ZWQnXSkgPyAkb3B0aW9uc1snZGVjb3JhdGVkJ10gOiBudWxsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAkZXJyb3JPdXRwdXQgPSBuZXcgU3RyZWFtT3V0cHV0KGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAndycsIGZhbHNlKSk7CiAgICAgICAgICAgICRlcnJvck91dHB1dC0+c2V0Rm9ybWF0dGVyKCR0aGlzLT5vdXRwdXQtPmdldEZvcm1hdHRlcigpKTsKICAgICAgICAgICAgJGVycm9yT3V0cHV0LT5zZXRWZXJib3NpdHkoJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpOwogICAgICAgICAgICAkZXJyb3JPdXRwdXQtPnNldERlY29yYXRlZCgkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpKTsKCiAgICAgICAgICAgICRyZWZsZWN0ZWRPdXRwdXQgPSBuZXcgXFJlZmxlY3Rpb25PYmplY3QoJHRoaXMtPm91dHB1dCk7CiAgICAgICAgICAgICRzdHJFcnJQcm9wZXJ0eSA9ICRyZWZsZWN0ZWRPdXRwdXQtPmdldFByb3BlcnR5KCdzdGRlcnInKTsKICAgICAgICAgICAgJHN0ckVyclByb3BlcnR5LT5zZXRBY2Nlc3NpYmxlKHRydWUpOwogICAgICAgICAgICAkc3RyRXJyUHJvcGVydHktPnNldFZhbHVlKCR0aGlzLT5vdXRwdXQsICRlcnJvck91dHB1dCk7CgogICAgICAgICAgICAkcmVmbGVjdGVkUGFyZW50ID0gJHJlZmxlY3RlZE91dHB1dC0+Z2V0UGFyZW50Q2xhc3MoKTsKICAgICAgICAgICAgJHN0cmVhbVByb3BlcnR5ID0gJHJlZmxlY3RlZFBhcmVudC0+Z2V0UHJvcGVydHkoJ3N0cmVhbScpOwogICAgICAgICAgICAkc3RyZWFtUHJvcGVydHktPnNldEFjY2Vzc2libGUodHJ1ZSk7CiAgICAgICAgICAgICRzdHJlYW1Qcm9wZXJ0eS0+c2V0VmFsdWUoJHRoaXMtPm91dHB1dCwgZm9wZW4oJ3BocDovL21lbW9yeScsICd3JywgZmFsc2UpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdHVzQ29kZSA9ICR0aGlzLT5hcHBsaWNhdGlvbi0+cnVuKCR0aGlzLT5pbnB1dCwgJHRoaXMtPm91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBkaXNwbGF5IHJldHVybmVkIGJ5IHRoZSBsYXN0IGV4ZWN1dGlvbiBvZiB0aGUgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG5vcm1hbGl6ZSBXaGV0aGVyIHRvIG5vcm1hbGl6ZSBlbmQgb2YgbGluZXMgdG8gXG4gb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGRpc3BsYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc3BsYXkoJG5vcm1hbGl6ZSA9IGZhbHNlKQogICAgewogICAgICAgIHJld2luZCgkdGhpcy0+b3V0cHV0LT5nZXRTdHJlYW0oKSk7CgogICAgICAgICRkaXNwbGF5ID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+b3V0cHV0LT5nZXRTdHJlYW0oKSk7CgogICAgICAgIGlmICgkbm9ybWFsaXplKSB7CiAgICAgICAgICAgICRkaXNwbGF5ID0gc3RyX3JlcGxhY2UoXFBIUF9FT0wsICJcbiIsICRkaXNwbGF5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGlzcGxheTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG91dHB1dCB3cml0dGVuIHRvIFNUREVSUiBieSB0aGUgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG5vcm1hbGl6ZSBXaGV0aGVyIHRvIG5vcm1hbGl6ZSBlbmQgb2YgbGluZXMgdG8gXG4gb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yT3V0cHV0KCRub3JtYWxpemUgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5jYXB0dXJlU3RyZWFtc0luZGVwZW5kZW50bHkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignVGhlIGVycm9yIG91dHB1dCBpcyBub3QgYXZhaWxhYmxlIHdoZW4gdGhlIHRlc3RlciBpcyBydW4gd2l0aG91dCAiY2FwdHVyZV9zdGRlcnJfc2VwYXJhdGVseSIgb3B0aW9uIHNldC4nKTsKICAgICAgICB9CgogICAgICAgIHJld2luZCgkdGhpcy0+b3V0cHV0LT5nZXRFcnJvck91dHB1dCgpLT5nZXRTdHJlYW0oKSk7CgogICAgICAgICRkaXNwbGF5ID0gc3RyZWFtX2dldF9jb250ZW50cygkdGhpcy0+b3V0cHV0LT5nZXRFcnJvck91dHB1dCgpLT5nZXRTdHJlYW0oKSk7CgogICAgICAgIGlmICgkbm9ybWFsaXplKSB7CiAgICAgICAgICAgICRkaXNwbGF5ID0gc3RyX3JlcGxhY2UoXFBIUF9FT0wsICJcbiIsICRkaXNwbGF5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGlzcGxheTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGlucHV0IGluc3RhbmNlIHVzZWQgYnkgdGhlIGxhc3QgZXhlY3V0aW9uIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlIFRoZSBjdXJyZW50IGlucHV0IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG91dHB1dCBpbnN0YW5jZSB1c2VkIGJ5IHRoZSBsYXN0IGV4ZWN1dGlvbiBvZiB0aGUgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRJbnRlcmZhY2UgVGhlIGN1cnJlbnQgb3V0cHV0IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgc3RhdHVzIGNvZGUgcmV0dXJuZWQgYnkgdGhlIGxhc3QgZXhlY3V0aW9uIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgc3RhdHVzIGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdHVzQ29kZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcVGVzdGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxBcnJheUlucHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XFN0cmVhbU91dHB1dDsKCi8qKgogKiBFYXNlcyB0aGUgdGVzdGluZyBvZiBjb25zb2xlIGNvbW1hbmRzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBDb21tYW5kVGVzdGVyCnsKICAgIHByaXZhdGUgJGNvbW1hbmQ7CiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJG91dHB1dDsKICAgIHByaXZhdGUgJGlucHV0cyA9IFtdOwogICAgcHJpdmF0ZSAkc3RhdHVzQ29kZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tbWFuZCAkY29tbWFuZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWFuZCA9ICRjb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQXZhaWxhYmxlIGV4ZWN1dGlvbiBvcHRpb25zOgogICAgICoKICAgICAqICAqIGludGVyYWN0aXZlOiBTZXRzIHRoZSBpbnB1dCBpbnRlcmFjdGl2ZSBmbGFnCiAgICAgKiAgKiBkZWNvcmF0ZWQ6ICAgU2V0cyB0aGUgb3V0cHV0IGRlY29yYXRlZCBmbGFnCiAgICAgKiAgKiB2ZXJib3NpdHk6ICAgU2V0cyB0aGUgb3V0cHV0IHZlcmJvc2l0eSBmbGFnCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRpbnB1dCAgIEFuIGFycmF5IG9mIGNvbW1hbmQgYXJndW1lbnRzIGFuZCBvcHRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMgQW4gYXJyYXkgb2YgZXhlY3V0aW9uIG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4ZWN1dGUoYXJyYXkgJGlucHV0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIC8vIHNldCB0aGUgY29tbWFuZCBuYW1lIGF1dG9tYXRpY2FsbHkgaWYgdGhlIGFwcGxpY2F0aW9uIHJlcXVpcmVzCiAgICAgICAgLy8gdGhpcyBhcmd1bWVudCBhbmQgbm8gY29tbWFuZCBuYW1lIHdhcyBwYXNzZWQKICAgICAgICBpZiAoIWlzc2V0KCRpbnB1dFsnY29tbWFuZCddKQogICAgICAgICAgICAmJiAobnVsbCAhPT0gJGFwcGxpY2F0aW9uID0gJHRoaXMtPmNvbW1hbmQtPmdldEFwcGxpY2F0aW9uKCkpCiAgICAgICAgICAgICYmICRhcHBsaWNhdGlvbi0+Z2V0RGVmaW5pdGlvbigpLT5oYXNBcmd1bWVudCgnY29tbWFuZCcpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRpbnB1dCA9IGFycmF5X21lcmdlKFsnY29tbWFuZCcgPT4gJHRoaXMtPmNvbW1hbmQtPmdldE5hbWUoKV0sICRpbnB1dCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+aW5wdXQgPSBuZXcgQXJyYXlJbnB1dCgkaW5wdXQpOwogICAgICAgIC8vIFVzZSBhbiBpbi1tZW1vcnkgaW5wdXQgc3RyZWFtIGV2ZW4gaWYgbm8gaW5wdXRzIGFyZSBzZXQgc28gdGhhdCBRdWVzdGlvbkhlbHBlcjo6YXNrKCkgZG9lcyBub3QgcmVseSBvbiB0aGUgYmxvY2tpbmcgU1RESU4uCiAgICAgICAgJHRoaXMtPmlucHV0LT5zZXRTdHJlYW0oc2VsZjo6Y3JlYXRlU3RyZWFtKCR0aGlzLT5pbnB1dHMpKTsKCiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydpbnRlcmFjdGl2ZSddKSkgewogICAgICAgICAgICAkdGhpcy0+aW5wdXQtPnNldEludGVyYWN0aXZlKCRvcHRpb25zWydpbnRlcmFjdGl2ZSddKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXQgPSBuZXcgU3RyZWFtT3V0cHV0KGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAndycsIGZhbHNlKSk7CiAgICAgICAgJHRoaXMtPm91dHB1dC0+c2V0RGVjb3JhdGVkKGlzc2V0KCRvcHRpb25zWydkZWNvcmF0ZWQnXSkgPyAkb3B0aW9uc1snZGVjb3JhdGVkJ10gOiBmYWxzZSk7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyd2ZXJib3NpdHknXSkpIHsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dC0+c2V0VmVyYm9zaXR5KCRvcHRpb25zWyd2ZXJib3NpdHknXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXR1c0NvZGUgPSAkdGhpcy0+Y29tbWFuZC0+cnVuKCR0aGlzLT5pbnB1dCwgJHRoaXMtPm91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBkaXNwbGF5IHJldHVybmVkIGJ5IHRoZSBsYXN0IGV4ZWN1dGlvbiBvZiB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkbm9ybWFsaXplIFdoZXRoZXIgdG8gbm9ybWFsaXplIGVuZCBvZiBsaW5lcyB0byBcbiBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZGlzcGxheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGlzcGxheSgkbm9ybWFsaXplID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5vdXRwdXQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdPdXRwdXQgbm90IGluaXRpYWxpemVkLCBkaWQgeW91IGV4ZWN1dGUgdGhlIGNvbW1hbmQgYmVmb3JlIHJlcXVlc3RpbmcgdGhlIGRpc3BsYXk/Jyk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJHRoaXMtPm91dHB1dC0+Z2V0U3RyZWFtKCkpOwoKICAgICAgICAkZGlzcGxheSA9IHN0cmVhbV9nZXRfY29udGVudHMoJHRoaXMtPm91dHB1dC0+Z2V0U3RyZWFtKCkpOwoKICAgICAgICBpZiAoJG5vcm1hbGl6ZSkgewogICAgICAgICAgICAkZGlzcGxheSA9IHN0cl9yZXBsYWNlKFxQSFBfRU9MLCAiXG4iLCAkZGlzcGxheSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRpc3BsYXk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBpbnB1dCBpbnN0YW5jZSB1c2VkIGJ5IHRoZSBsYXN0IGV4ZWN1dGlvbiBvZiB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlIFRoZSBjdXJyZW50IGlucHV0IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG91dHB1dCBpbnN0YW5jZSB1c2VkIGJ5IHRoZSBsYXN0IGV4ZWN1dGlvbiBvZiB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZSBUaGUgY3VycmVudCBvdXRwdXQgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE91dHB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBzdGF0dXMgY29kZSByZXR1cm5lZCBieSB0aGUgbGFzdCBleGVjdXRpb24gb2YgdGhlIGFwcGxpY2F0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBzdGF0dXMgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXNDb2RlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdXNlciBpbnB1dHMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRpbnB1dHMgQW4gYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgZWFjaCBpbnB1dAogICAgICogICAgICAgICAgICAgICAgICAgICAgcGFzc2VkIHRvIHRoZSBjb21tYW5kIGlucHV0IHN0cmVhbQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZFRlc3RlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5wdXRzKGFycmF5ICRpbnB1dHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0cyA9ICRpbnB1dHM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVTdHJlYW0oYXJyYXkgJGlucHV0cykKICAgIHsKICAgICAgICAkc3RyZWFtID0gZm9wZW4oJ3BocDovL21lbW9yeScsICdyKycsIGZhbHNlKTsKCiAgICAgICAgZm9yZWFjaCAoJGlucHV0cyBhcyAkaW5wdXQpIHsKICAgICAgICAgICAgZndyaXRlKCRzdHJlYW0sICRpbnB1dC5cUEhQX0VPTCk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJHN0cmVhbSk7CgogICAgICAgIHJldHVybiAkc3RyZWFtOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvbjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKCi8qKgogKiBSZXByZXNlbnRzIGEgUXVlc3Rpb24uCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgUXVlc3Rpb24KewogICAgcHJpdmF0ZSAkcXVlc3Rpb247CiAgICBwcml2YXRlICRhdHRlbXB0czsKICAgIHByaXZhdGUgJGhpZGRlbiA9IGZhbHNlOwogICAgcHJpdmF0ZSAkaGlkZGVuRmFsbGJhY2sgPSB0cnVlOwogICAgcHJpdmF0ZSAkYXV0b2NvbXBsZXRlclZhbHVlczsKICAgIHByaXZhdGUgJHZhbGlkYXRvcjsKICAgIHByaXZhdGUgJGRlZmF1bHQ7CiAgICBwcml2YXRlICRub3JtYWxpemVyOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24gVGhlIHF1ZXN0aW9uIHRvIGFzayB0byB0aGUgdXNlcgogICAgICogQHBhcmFtIG1peGVkICAkZGVmYXVsdCAgVGhlIGRlZmF1bHQgYW5zd2VyIHRvIHJldHVybiBpZiB0aGUgdXNlciBlbnRlcnMgbm90aGluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnF1ZXN0aW9uID0gJHF1ZXN0aW9uOwogICAgICAgICR0aGlzLT5kZWZhdWx0ID0gJGRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UXVlc3Rpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cXVlc3Rpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWZhdWx0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHVzZXIgcmVzcG9uc2UgbXVzdCBiZSBoaWRkZW4uCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hpZGRlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oaWRkZW47CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIHVzZXIgcmVzcG9uc2UgbXVzdCBiZSBoaWRkZW4gb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRoaWRkZW4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBJbiBjYXNlIHRoZSBhdXRvY29tcGxldGVyIGlzIGFsc28gdXNlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGlkZGVuKCRoaWRkZW4pCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5hdXRvY29tcGxldGVyVmFsdWVzKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSBoaWRkZW4gcXVlc3Rpb24gY2Fubm90IHVzZSB0aGUgYXV0b2NvbXBsZXRlci4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5oaWRkZW4gPSAoYm9vbCkgJGhpZGRlbjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogSW4gY2FzZSB0aGUgcmVzcG9uc2UgY2FuIG5vdCBiZSBoaWRkZW4sIHdoZXRoZXIgdG8gZmFsbGJhY2sgb24gbm9uLWhpZGRlbiBxdWVzdGlvbiBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hpZGRlbkZhbGxiYWNrKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhpZGRlbkZhbGxiYWNrOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIHRvIGZhbGxiYWNrIG9uIG5vbi1oaWRkZW4gcXVlc3Rpb24gaWYgdGhlIHJlc3BvbnNlIGNhbiBub3QgYmUgaGlkZGVuLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRmYWxsYmFjawogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhpZGRlbkZhbGxiYWNrKCRmYWxsYmFjaykKICAgIHsKICAgICAgICAkdGhpcy0+aGlkZGVuRmFsbGJhY2sgPSAoYm9vbCkgJGZhbGxiYWNrOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHZhbHVlcyBmb3IgdGhlIGF1dG9jb21wbGV0ZXIuCiAgICAgKgogICAgICogQHJldHVybiBpdGVyYWJsZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdXRvY29tcGxldGVyVmFsdWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF1dG9jb21wbGV0ZXJWYWx1ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHZhbHVlcyBmb3IgdGhlIGF1dG9jb21wbGV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGl0ZXJhYmxlfG51bGwgJHZhbHVlcwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXV0b2NvbXBsZXRlclZhbHVlcygkdmFsdWVzKQogICAgewogICAgICAgIGlmIChcaXNfYXJyYXkoJHZhbHVlcykpIHsKICAgICAgICAgICAgJHZhbHVlcyA9ICR0aGlzLT5pc0Fzc29jKCR2YWx1ZXMpID8gYXJyYXlfbWVyZ2UoYXJyYXlfa2V5cygkdmFsdWVzKSwgYXJyYXlfdmFsdWVzKCR2YWx1ZXMpKSA6IGFycmF5X3ZhbHVlcygkdmFsdWVzKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsICE9PSAkdmFsdWVzICYmICFcaXNfYXJyYXkoJHZhbHVlcykgJiYgISR2YWx1ZXMgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignQXV0b2NvbXBsZXRlciB2YWx1ZXMgY2FuIGJlIGVpdGhlciBhbiBhcnJheSwgYG51bGxgIG9yIGEgYFRyYXZlcnNhYmxlYCBvYmplY3QuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmhpZGRlbikgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0EgaGlkZGVuIHF1ZXN0aW9uIGNhbm5vdCB1c2UgdGhlIGF1dG9jb21wbGV0ZXIuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXV0b2NvbXBsZXRlclZhbHVlcyA9ICR2YWx1ZXM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSB2YWxpZGF0b3IgZm9yIHRoZSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWxpZGF0b3IoY2FsbGFibGUgJHZhbGlkYXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbGlkYXRvciA9ICR2YWxpZGF0b3I7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHZhbGlkYXRvciBmb3IgdGhlIHF1ZXN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbGlkYXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLgogICAgICoKICAgICAqIE51bGwgbWVhbnMgYW4gdW5saW1pdGVkIG51bWJlciBvZiBhdHRlbXB0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fG51bGwgJGF0dGVtcHRzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGluIGNhc2UgdGhlIG51bWJlciBvZiBhdHRlbXB0cyBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNYXhBdHRlbXB0cygkYXR0ZW1wdHMpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRhdHRlbXB0cykgewogICAgICAgICAgICAkYXR0ZW1wdHMgPSAoaW50KSAkYXR0ZW1wdHM7CiAgICAgICAgICAgIGlmICgkYXR0ZW1wdHMgPCAxKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdNYXhpbXVtIG51bWJlciBvZiBhdHRlbXB0cyBtdXN0IGJlIGEgcG9zaXRpdmUgdmFsdWUuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5hdHRlbXB0cyA9ICRhdHRlbXB0czsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHMuCiAgICAgKgogICAgICogTnVsbCBtZWFucyBhbiB1bmxpbWl0ZWQgbnVtYmVyIG9mIGF0dGVtcHRzLgogICAgICoKICAgICAqIEByZXR1cm4gaW50fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE1heEF0dGVtcHRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF0dGVtcHRzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIG5vcm1hbGl6ZXIgZm9yIHRoZSByZXNwb25zZS4KICAgICAqCiAgICAgKiBUaGUgbm9ybWFsaXplciBjYW4gYmUgYSBjYWxsYWJsZSAoYSBzdHJpbmcpLCBhIGNsb3N1cmUgb3IgYSBjbGFzcyBpbXBsZW1lbnRpbmcgX19pbnZva2UuCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Tm9ybWFsaXplcihjYWxsYWJsZSAkbm9ybWFsaXplcikKICAgIHsKICAgICAgICAkdGhpcy0+bm9ybWFsaXplciA9ICRub3JtYWxpemVyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBub3JtYWxpemVyIGZvciB0aGUgcmVzcG9uc2UuCiAgICAgKgogICAgICogVGhlIG5vcm1hbGl6ZXIgY2FuIGJhIGEgY2FsbGFibGUgKGEgc3RyaW5nKSwgYSBjbG9zdXJlIG9yIGEgY2xhc3MgaW1wbGVtZW50aW5nIF9faW52b2tlLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Tm9ybWFsaXplcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ub3JtYWxpemVyOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0Fzc29jKCRhcnJheSkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2wpIFxjb3VudChhcnJheV9maWx0ZXIoYXJyYXlfa2V5cygkYXJyYXkpLCAnaXNfc3RyaW5nJykpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvbjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhIGNob2ljZSBxdWVzdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBDaG9pY2VRdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKICAgIHByaXZhdGUgJGNob2ljZXM7CiAgICBwcml2YXRlICRtdWx0aXNlbGVjdCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcHJvbXB0ID0gJyA+ICc7CiAgICBwcml2YXRlICRlcnJvck1lc3NhZ2UgPSAnVmFsdWUgIiVzIiBpcyBpbnZhbGlkJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sgdG8gdGhlIHVzZXIKICAgICAqIEBwYXJhbSBhcnJheSAgJGNob2ljZXMgIFRoZSBsaXN0IG9mIGF2YWlsYWJsZSBjaG9pY2VzCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCBhbnN3ZXIgdG8gcmV0dXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcXVlc3Rpb24sIGFycmF5ICRjaG9pY2VzLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkY2hvaWNlcykgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDaG9pY2UgcXVlc3Rpb24gbXVzdCBoYXZlIGF0IGxlYXN0IDEgY2hvaWNlIGF2YWlsYWJsZS4nKTsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCk7CgogICAgICAgICR0aGlzLT5jaG9pY2VzID0gJGNob2ljZXM7CiAgICAgICAgJHRoaXMtPnNldFZhbGlkYXRvcigkdGhpcy0+Z2V0RGVmYXVsdFZhbGlkYXRvcigpKTsKICAgICAgICAkdGhpcy0+c2V0QXV0b2NvbXBsZXRlclZhbHVlcygkY2hvaWNlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGF2YWlsYWJsZSBjaG9pY2VzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENob2ljZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hvaWNlczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgbXVsdGlzZWxlY3Qgb3B0aW9uLgogICAgICoKICAgICAqIFdoZW4gbXVsdGlzZWxlY3QgaXMgc2V0IHRvIHRydWUsIG11bHRpcGxlIGNob2ljZXMgY2FuIGJlIGFuc3dlcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRtdWx0aXNlbGVjdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE11bHRpc2VsZWN0KCRtdWx0aXNlbGVjdCkKICAgIHsKICAgICAgICAkdGhpcy0+bXVsdGlzZWxlY3QgPSAkbXVsdGlzZWxlY3Q7CiAgICAgICAgJHRoaXMtPnNldFZhbGlkYXRvcigkdGhpcy0+Z2V0RGVmYXVsdFZhbGlkYXRvcigpKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjaG9pY2VzIGFyZSBtdWx0aXNlbGVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzTXVsdGlzZWxlY3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bXVsdGlzZWxlY3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9tcHQgZm9yIGNob2ljZXMuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb21wdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9tcHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9tcHQgZm9yIGNob2ljZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcHJvbXB0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvbXB0KCRwcm9tcHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb21wdCA9ICRwcm9tcHQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGVycm9yIG1lc3NhZ2UgZm9yIGludmFsaWQgdmFsdWVzLgogICAgICoKICAgICAqIFRoZSBlcnJvciBtZXNzYWdlIGhhcyBhIHN0cmluZyBwbGFjZWhvbGRlciAoJXMpIGZvciB0aGUgaW52YWxpZCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlcnJvck1lc3NhZ2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFcnJvck1lc3NhZ2UoJGVycm9yTWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JNZXNzYWdlID0gJGVycm9yTWVzc2FnZTsKICAgICAgICAkdGhpcy0+c2V0VmFsaWRhdG9yKCR0aGlzLT5nZXREZWZhdWx0VmFsaWRhdG9yKCkpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciB2YWxpZGF0b3IuCiAgICAgKgogICAgICogQHJldHVybiBjYWxsYWJsZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERlZmF1bHRWYWxpZGF0b3IoKQogICAgewogICAgICAgICRjaG9pY2VzID0gJHRoaXMtPmNob2ljZXM7CiAgICAgICAgJGVycm9yTWVzc2FnZSA9ICR0aGlzLT5lcnJvck1lc3NhZ2U7CiAgICAgICAgJG11bHRpc2VsZWN0ID0gJHRoaXMtPm11bHRpc2VsZWN0OwogICAgICAgICRpc0Fzc29jID0gJHRoaXMtPmlzQXNzb2MoJGNob2ljZXMpOwoKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCRzZWxlY3RlZCkgdXNlICgkY2hvaWNlcywgJGVycm9yTWVzc2FnZSwgJG11bHRpc2VsZWN0LCAkaXNBc3NvYykgewogICAgICAgICAgICBpZiAoJG11bHRpc2VsZWN0KSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgYSBzZXBhcmF0ZWQgY29tbWEgdmFsdWVzCiAgICAgICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eW14sXSsoPzosW14sXSspKiQvJywgJHNlbGVjdGVkLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJGVycm9yTWVzc2FnZSwgJHNlbGVjdGVkKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHNlbGVjdGVkQ2hvaWNlcyA9IGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCAkc2VsZWN0ZWQpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRzZWxlY3RlZENob2ljZXMgPSBbdHJpbSgkc2VsZWN0ZWQpXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG11bHRpc2VsZWN0Q2hvaWNlcyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgkc2VsZWN0ZWRDaG9pY2VzIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgJHJlc3VsdHMgPSBbXTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjaG9pY2VzIGFzICRrZXkgPT4gJGNob2ljZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkY2hvaWNlID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdHNbXSA9ICRrZXk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChcY291bnQoJHJlc3VsdHMpID4gMSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIHByb3ZpZGVkIGFuc3dlciBpcyBhbWJpZ3VvdXMuIFZhbHVlIHNob3VsZCBiZSBvbmUgb2YgIiVzIi4nLCBpbXBsb2RlKCciIG9yICInLCAkcmVzdWx0cykpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gYXJyYXlfc2VhcmNoKCR2YWx1ZSwgJGNob2ljZXMpOwoKICAgICAgICAgICAgICAgIGlmICghJGlzQXNzb2MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgIT09ICRyZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCA9ICRjaG9pY2VzWyRyZXN1bHRdOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkY2hvaWNlc1skdmFsdWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJGNob2ljZXNbJHZhbHVlXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoZmFsc2UgPT09ICRyZXN1bHQgJiYgaXNzZXQoJGNob2ljZXNbJHZhbHVlXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZigkZXJyb3JNZXNzYWdlLCAkdmFsdWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbXVsdGlzZWxlY3RDaG9pY2VzW10gPSAoc3RyaW5nKSAkcmVzdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG11bHRpc2VsZWN0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG11bHRpc2VsZWN0Q2hvaWNlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQoJG11bHRpc2VsZWN0Q2hvaWNlcyk7CiAgICAgICAgfTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb247CgovKioKICogUmVwcmVzZW50cyBhIHllcy9ubyBxdWVzdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBDb25maXJtYXRpb25RdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKICAgIHByaXZhdGUgJHRydWVBbnN3ZXJSZWdleDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXN0aW9uICAgICAgICBUaGUgcXVlc3Rpb24gdG8gYXNrIHRvIHRoZSB1c2VyCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0ICAgICAgICAgVGhlIGRlZmF1bHQgYW5zd2VyIHRvIHJldHVybiwgdHJ1ZSBvciBmYWxzZQogICAgICogQHBhcmFtIHN0cmluZyAkdHJ1ZUFuc3dlclJlZ2V4IEEgcmVnZXggdG8gbWF0Y2ggdGhlICJ5ZXMiIGFuc3dlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IHRydWUsICR0cnVlQW5zd2VyUmVnZXggPSAnL155L2knKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHF1ZXN0aW9uLCAoYm9vbCkgJGRlZmF1bHQpOwoKICAgICAgICAkdGhpcy0+dHJ1ZUFuc3dlclJlZ2V4ID0gJHRydWVBbnN3ZXJSZWdleDsKICAgICAgICAkdGhpcy0+c2V0Tm9ybWFsaXplcigkdGhpcy0+Z2V0RGVmYXVsdE5vcm1hbGl6ZXIoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGFuc3dlciBub3JtYWxpemVyLgogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGUKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREZWZhdWx0Tm9ybWFsaXplcigpCiAgICB7CiAgICAgICAgJGRlZmF1bHQgPSAkdGhpcy0+Z2V0RGVmYXVsdCgpOwogICAgICAgICRyZWdleCA9ICR0aGlzLT50cnVlQW5zd2VyUmVnZXg7CgogICAgICAgIHJldHVybiBmdW5jdGlvbiAoJGFuc3dlcikgdXNlICgkZGVmYXVsdCwgJHJlZ2V4KSB7CiAgICAgICAgICAgIGlmIChcaXNfYm9vbCgkYW5zd2VyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRhbnN3ZXI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRhbnN3ZXJJc1RydWUgPSAoYm9vbCkgcHJlZ19tYXRjaCgkcmVnZXgsICRhbnN3ZXIpOwogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGFuc3dlciAmJiAkYW5zd2VySXNUcnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJycgPT09ICRhbnN3ZXIgfHwgJGFuc3dlcklzVHJ1ZTsKICAgICAgICB9OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxMb2dnZXI7Cgp1c2UgUHNyXExvZ1xBYnN0cmFjdExvZ2dlcjsKdXNlIFBzclxMb2dcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgUHNyXExvZ1xMb2dMZXZlbDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogUFNSLTMgY29tcGxpYW50IGNvbnNvbGUgbG9nZ2VyLgogKgogKiBAYXV0aG9yIEvDqXZpbiBEdW5nbGFzIDxkdW5nbGFzQGdtYWlsLmNvbT4KICoKICogQHNlZSBodHRwczovL3d3dy5waHAtZmlnLm9yZy9wc3IvcHNyLTMvCiAqLwpjbGFzcyBDb25zb2xlTG9nZ2VyIGV4dGVuZHMgQWJzdHJhY3RMb2dnZXIKewogICAgY29uc3QgSU5GTyA9ICdpbmZvJzsKICAgIGNvbnN0IEVSUk9SID0gJ2Vycm9yJzsKCiAgICBwcml2YXRlICRvdXRwdXQ7CiAgICBwcml2YXRlICR2ZXJib3NpdHlMZXZlbE1hcCA9IFsKICAgICAgICBMb2dMZXZlbDo6RU1FUkdFTkNZID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX05PUk1BTCwKICAgICAgICBMb2dMZXZlbDo6QUxFUlQgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfTk9STUFMLAogICAgICAgIExvZ0xldmVsOjpDUklUSUNBTCA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9OT1JNQUwsCiAgICAgICAgTG9nTGV2ZWw6OkVSUk9SID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX05PUk1BTCwKICAgICAgICBMb2dMZXZlbDo6V0FSTklORyA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9OT1JNQUwsCiAgICAgICAgTG9nTGV2ZWw6Ok5PVElDRSA9PiBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFLAogICAgICAgIExvZ0xldmVsOjpJTkZPID0+IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSwKICAgICAgICBMb2dMZXZlbDo6REVCVUcgPT4gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfREVCVUcsCiAgICBdOwogICAgcHJpdmF0ZSAkZm9ybWF0TGV2ZWxNYXAgPSBbCiAgICAgICAgTG9nTGV2ZWw6OkVNRVJHRU5DWSA9PiBzZWxmOjpFUlJPUiwKICAgICAgICBMb2dMZXZlbDo6QUxFUlQgPT4gc2VsZjo6RVJST1IsCiAgICAgICAgTG9nTGV2ZWw6OkNSSVRJQ0FMID0+IHNlbGY6OkVSUk9SLAogICAgICAgIExvZ0xldmVsOjpFUlJPUiA9PiBzZWxmOjpFUlJPUiwKICAgICAgICBMb2dMZXZlbDo6V0FSTklORyA9PiBzZWxmOjpJTkZPLAogICAgICAgIExvZ0xldmVsOjpOT1RJQ0UgPT4gc2VsZjo6SU5GTywKICAgICAgICBMb2dMZXZlbDo6SU5GTyA9PiBzZWxmOjpJTkZPLAogICAgICAgIExvZ0xldmVsOjpERUJVRyA9PiBzZWxmOjpJTkZPLAogICAgXTsKICAgIHByaXZhdGUgJGVycm9yZWQgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIGFycmF5ICR2ZXJib3NpdHlMZXZlbE1hcCA9IFtdLCBhcnJheSAkZm9ybWF0TGV2ZWxNYXAgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gJG91dHB1dDsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXAgPSAkdmVyYm9zaXR5TGV2ZWxNYXAgKyAkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXA7CiAgICAgICAgJHRoaXMtPmZvcm1hdExldmVsTWFwID0gJGZvcm1hdExldmVsTWFwICsgJHRoaXMtPmZvcm1hdExldmVsTWFwOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9nKCRsZXZlbCwgJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gW10pCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dmVyYm9zaXR5TGV2ZWxNYXBbJGxldmVsXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgbG9nIGxldmVsICIlcyIgZG9lcyBub3QgZXhpc3QuJywgJGxldmVsKSk7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0ID0gJHRoaXMtPm91dHB1dDsKCiAgICAgICAgLy8gV3JpdGUgdG8gdGhlIGVycm9yIG91dHB1dCBpZiBuZWNlc3NhcnkgYW5kIGF2YWlsYWJsZQogICAgICAgIGlmIChzZWxmOjpFUlJPUiA9PT0gJHRoaXMtPmZvcm1hdExldmVsTWFwWyRsZXZlbF0pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+ZXJyb3JlZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyB0aGUgaWYgY29uZGl0aW9uIGNoZWNrIGlzbid0IG5lY2Vzc2FyeSAtLSBpdCdzIHRoZSBzYW1lIG9uZSB0aGF0ICRvdXRwdXQgd2lsbCBkbyBpbnRlcm5hbGx5IGFueXdheS4KICAgICAgICAvLyBXZSBvbmx5IGRvIGl0IGZvciBlZmZpY2llbmN5IGhlcmUgYXMgdGhlIG1lc3NhZ2UgZm9ybWF0dGluZyBpcyByZWxhdGl2ZWx5IGV4cGVuc2l2ZS4KICAgICAgICBpZiAoJG91dHB1dC0+Z2V0VmVyYm9zaXR5KCkgPj0gJHRoaXMtPnZlcmJvc2l0eUxldmVsTWFwWyRsZXZlbF0pIHsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCc8JTEkcz5bJTIkc10gJTMkczwvJTEkcz4nLCAkdGhpcy0+Zm9ybWF0TGV2ZWxNYXBbJGxldmVsXSwgJGxldmVsLCAkdGhpcy0+aW50ZXJwb2xhdGUoJG1lc3NhZ2UsICRjb250ZXh0KSksICR0aGlzLT52ZXJib3NpdHlMZXZlbE1hcFskbGV2ZWxdKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgd2hlbiBhbnkgbWVzc2FnZXMgaGF2ZSBiZWVuIGxvZ2dlZCBhdCBlcnJvciBsZXZlbHMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNFcnJvcmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcnBvbGF0ZXMgY29udGV4dCB2YWx1ZXMgaW50byB0aGUgbWVzc2FnZSBwbGFjZWhvbGRlcnMuCiAgICAgKgogICAgICogQGF1dGhvciBQSFAgRnJhbWV3b3JrIEludGVyb3BlcmFiaWxpdHkgR3JvdXAKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbnRlcnBvbGF0ZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSBzdHJwb3MoJG1lc3NhZ2UsICd7JykpIHsKICAgICAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgJHJlcGxhY2VtZW50cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRjb250ZXh0IGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICBpZiAobnVsbCA9PT0gJHZhbCB8fCBpc19zY2FsYXIoJHZhbCkgfHwgKFxpc19vYmplY3QoJHZhbCkgJiYgbWV0aG9kX2V4aXN0cygkdmFsLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICAgICAgJHJlcGxhY2VtZW50c1sie3ska2V5fX0iXSA9ICR2YWw7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdmFsIGluc3RhbmNlb2YgXERhdGVUaW1lSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnRzWyJ7eyRrZXl9fSJdID0gJHZhbC0+Zm9ybWF0KFxEYXRlVGltZTo6UkZDMzMzOSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChcaXNfb2JqZWN0KCR2YWwpKSB7CiAgICAgICAgICAgICAgICAkcmVwbGFjZW1lbnRzWyJ7eyRrZXl9fSJdID0gJ1tvYmplY3QgJy5cZ2V0X2NsYXNzKCR2YWwpLiddJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXBsYWNlbWVudHNbInt7JGtleX19Il0gPSAnWycuXGdldHR5cGUoJHZhbCkuJ10nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RydHIoJG1lc3NhZ2UsICRyZXBsYWNlbWVudHMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kTG9hZGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgUm9iaW4gQ2hhbGFzIDxyb2Jpbi5jaGFsYXNAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIENvbW1hbmRMb2FkZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBMb2FkcyBhIGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZAogICAgICoKICAgICAqIEB0aHJvd3MgQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGEgY29tbWFuZCBleGlzdHMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nW10gQWxsIHJlZ2lzdGVyZWQgY29tbWFuZCBuYW1lcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZExvYWRlcjsKCnVzZSBQc3JcQ29udGFpbmVyXENvbnRhaW5lckludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbjsKCi8qKgogKiBMb2FkcyBjb21tYW5kcyBmcm9tIGEgUFNSLTExIGNvbnRhaW5lci4KICoKICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBDb250YWluZXJDb21tYW5kTG9hZGVyIGltcGxlbWVudHMgQ29tbWFuZExvYWRlckludGVyZmFjZQp7CiAgICBwcml2YXRlICRjb250YWluZXI7CiAgICBwcml2YXRlICRjb21tYW5kTWFwOwoKICAgIC8qKgogICAgICogQHBhcmFtIENvbnRhaW5lckludGVyZmFjZSAkY29udGFpbmVyICBBIGNvbnRhaW5lciBmcm9tIHdoaWNoIHRvIGxvYWQgY29tbWFuZCBzZXJ2aWNlcwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgICAkY29tbWFuZE1hcCBBbiBhcnJheSB3aXRoIGNvbW1hbmQgbmFtZXMgYXMga2V5cyBhbmQgc2VydmljZSBpZHMgYXMgdmFsdWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb250YWluZXJJbnRlcmZhY2UgJGNvbnRhaW5lciwgYXJyYXkgJGNvbW1hbmRNYXApCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbnRhaW5lciA9ICRjb250YWluZXI7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRNYXAgPSAkY29tbWFuZE1hcDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24oc3ByaW50ZignQ29tbWFuZCAiJXMiIGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRhaW5lci0+Z2V0KCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXMoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSkgJiYgJHRoaXMtPmNvbnRhaW5lci0+aGFzKCR0aGlzLT5jb21tYW5kTWFwWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lcygpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJHRoaXMtPmNvbW1hbmRNYXApOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kTG9hZGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbjsKCi8qKgogKiBBIHNpbXBsZSBjb21tYW5kIGxvYWRlciB1c2luZyBmYWN0b3JpZXMgdG8gaW5zdGFudGlhdGUgY29tbWFuZHMgbGF6aWx5LgogKgogKiBAYXV0aG9yIE1heGltZSBTdGVpbmhhdXNzZXIgPG1heGltZS5zdGVpbmhhdXNzZXJAZ21haWwuY29tPgogKi8KY2xhc3MgRmFjdG9yeUNvbW1hbmRMb2FkZXIgaW1wbGVtZW50cyBDb21tYW5kTG9hZGVySW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGZhY3RvcmllczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBjYWxsYWJsZVtdICRmYWN0b3JpZXMgSW5kZXhlZCBieSBjb21tYW5kIG5hbWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZmFjdG9yaWVzKQogICAgewogICAgICAgICR0aGlzLT5mYWN0b3JpZXMgPSAkZmFjdG9yaWVzOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZmFjdG9yaWVzWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+ZmFjdG9yaWVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdDb21tYW5kICIlcyIgZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICRmYWN0b3J5ID0gJHRoaXMtPmZhY3Rvcmllc1skbmFtZV07CgogICAgICAgIHJldHVybiAkZmFjdG9yeSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9rZXlzKCR0aGlzLT5mYWN0b3JpZXMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxqZWFuZnJhbmNvaXMuc2ltb25Ac2Vuc2lvbGFicy5jb20+CiAqCiAqIEBpbnRlcm5hbAogKi8KYWJzdHJhY3QgY2xhc3MgRGVzY3JpcHRvciBpbXBsZW1lbnRzIERlc2NyaXB0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAdmFyIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwcm90ZWN0ZWQgJG91dHB1dDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwoKICAgICAgICBzd2l0Y2ggKHRydWUpIHsKICAgICAgICAgICAgY2FzZSAkb2JqZWN0IGluc3RhbmNlb2YgSW5wdXRBcmd1bWVudDoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0QXJndW1lbnQoJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIElucHV0T3B0aW9uOgogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXRPcHRpb24oJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIElucHV0RGVmaW5pdGlvbjoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0RGVmaW5pdGlvbigkb2JqZWN0LCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAkb2JqZWN0IGluc3RhbmNlb2YgQ29tbWFuZDoKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUNvbW1hbmQoJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJG9iamVjdCBpbnN0YW5jZW9mIEFwcGxpY2F0aW9uOgogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlQXBwbGljYXRpb24oJG9iamVjdCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ09iamVjdCBvZiB0eXBlICIlcyIgaXMgbm90IGRlc2NyaWJhYmxlLicsIFxnZXRfY2xhc3MoJG9iamVjdCkpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgY29udGVudCB0byBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudAogICAgICogQHBhcmFtIGJvb2wgICAkZGVjb3JhdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSgkY29udGVudCwgJGRlY29yYXRlZCA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlKCRjb250ZW50LCBmYWxzZSwgJGRlY29yYXRlZCA/IE91dHB1dEludGVyZmFjZTo6T1VUUFVUX05PUk1BTCA6IE91dHB1dEludGVyZmFjZTo6T1VUUFVUX1JBVyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYW4gSW5wdXRBcmd1bWVudCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xtaXhlZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50LCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBJbnB1dE9wdGlvbiBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xtaXhlZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBJbnB1dERlZmluaXRpb24gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bWl4ZWQKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXREZWZpbml0aW9uKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiwgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYSBDb21tYW5kIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG1peGVkCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUNvbW1hbmQoQ29tbWFuZCAkY29tbWFuZCwgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYW4gQXBwbGljYXRpb24gaW5zdGFuY2UuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bWl4ZWQKICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlclxIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogTWFya2Rvd24gZGVzY3JpcHRvci4KICoKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8Y29udGFjdEBqZnNpbW9uLmZyPgogKgogKiBAaW50ZXJuYWwKICovCmNsYXNzIE1hcmtkb3duRGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3IKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZXNjcmliZShPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJG9iamVjdCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkZGVjb3JhdGVkID0gJG91dHB1dC0+aXNEZWNvcmF0ZWQoKTsKICAgICAgICAkb3V0cHV0LT5zZXREZWNvcmF0ZWQoZmFsc2UpOwoKICAgICAgICBwYXJlbnQ6OmRlc2NyaWJlKCRvdXRwdXQsICRvYmplY3QsICRvcHRpb25zKTsKCiAgICAgICAgJG91dHB1dC0+c2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoJGNvbnRlbnQsICRkZWNvcmF0ZWQgPSB0cnVlKQogICAgewogICAgICAgIHBhcmVudDo6d3JpdGUoJGNvbnRlbnQsICRkZWNvcmF0ZWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZSgKICAgICAgICAgICAgJyMjIyMgYCcuKCRhcmd1bWVudC0+Z2V0TmFtZSgpID86ICc8bm9uZT4nKS4iYFxuXG4iCiAgICAgICAgICAgIC4oJGFyZ3VtZW50LT5nZXREZXNjcmlwdGlvbigpID8gcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICJcbiIsICRhcmd1bWVudC0+Z2V0RGVzY3JpcHRpb24oKSkuIlxuXG4iIDogJycpCiAgICAgICAgICAgIC4nKiBJcyByZXF1aXJlZDogJy4oJGFyZ3VtZW50LT5pc1JlcXVpcmVkKCkgPyAneWVzJyA6ICdubycpLiJcbiIKICAgICAgICAgICAgLicqIElzIGFycmF5OiAnLigkYXJndW1lbnQtPmlzQXJyYXkoKSA/ICd5ZXMnIDogJ25vJykuIlxuIgogICAgICAgICAgICAuJyogRGVmYXVsdDogYCcuc3RyX3JlcGxhY2UoIlxuIiwgJycsIHZhcl9leHBvcnQoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCksIHRydWUpKS4nYCcKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dE9wdGlvbihJbnB1dE9wdGlvbiAkb3B0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRuYW1lID0gJy0tJy4kb3B0aW9uLT5nZXROYW1lKCk7CiAgICAgICAgaWYgKCRvcHRpb24tPmdldFNob3J0Y3V0KCkpIHsKICAgICAgICAgICAgJG5hbWUgLj0gJ3wtJy5zdHJfcmVwbGFjZSgnfCcsICd8LScsICRvcHRpb24tPmdldFNob3J0Y3V0KCkpLicnOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPndyaXRlKAogICAgICAgICAgICAnIyMjIyBgJy4kbmFtZS4nYCcuIlxuXG4iCiAgICAgICAgICAgIC4oJG9wdGlvbi0+Z2V0RGVzY3JpcHRpb24oKSA/IHByZWdfcmVwbGFjZSgnL1xzKltcclxuXVxzKi8nLCAiXG4iLCAkb3B0aW9uLT5nZXREZXNjcmlwdGlvbigpKS4iXG5cbiIgOiAnJykKICAgICAgICAgICAgLicqIEFjY2VwdCB2YWx1ZTogJy4oJG9wdGlvbi0+YWNjZXB0VmFsdWUoKSA/ICd5ZXMnIDogJ25vJykuIlxuIgogICAgICAgICAgICAuJyogSXMgdmFsdWUgcmVxdWlyZWQ6ICcuKCRvcHRpb24tPmlzVmFsdWVSZXF1aXJlZCgpID8gJ3llcycgOiAnbm8nKS4iXG4iCiAgICAgICAgICAgIC4nKiBJcyBtdWx0aXBsZTogJy4oJG9wdGlvbi0+aXNBcnJheSgpID8gJ3llcycgOiAnbm8nKS4iXG4iCiAgICAgICAgICAgIC4nKiBEZWZhdWx0OiBgJy5zdHJfcmVwbGFjZSgiXG4iLCAnJywgdmFyX2V4cG9ydCgkb3B0aW9uLT5nZXREZWZhdWx0KCksIHRydWUpKS4nYCcKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dERlZmluaXRpb24oSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGlmICgkc2hvd0FyZ3VtZW50cyA9IFxjb3VudCgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkpID4gMCkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGUoJyMjIyBBcmd1bWVudHMnKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcblxuIik7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoJHRoaXMtPmRlc2NyaWJlSW5wdXRBcmd1bWVudCgkYXJndW1lbnQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKFxjb3VudCgkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpKSA+IDApIHsKICAgICAgICAgICAgaWYgKCRzaG93QXJndW1lbnRzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPndyaXRlKCcjIyMgT3B0aW9ucycpOwogICAgICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZSgiXG5cbiIpOwogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlKCR0aGlzLT5kZXNjcmliZUlucHV0T3B0aW9uKCRvcHRpb24pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQ29tbWFuZChDb21tYW5kICRjb21tYW5kLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRjb21tYW5kLT5nZXRTeW5vcHNpcygpOwogICAgICAgICRjb21tYW5kLT5tZXJnZUFwcGxpY2F0aW9uRGVmaW5pdGlvbihmYWxzZSk7CgogICAgICAgICR0aGlzLT53cml0ZSgKICAgICAgICAgICAgJ2AnLiRjb21tYW5kLT5nZXROYW1lKCkuImBcbiIKICAgICAgICAgICAgLnN0cl9yZXBlYXQoJy0nLCBIZWxwZXI6OnN0cmxlbigkY29tbWFuZC0+Z2V0TmFtZSgpKSArIDIpLiJcblxuIgogICAgICAgICAgICAuKCRjb21tYW5kLT5nZXREZXNjcmlwdGlvbigpID8gJGNvbW1hbmQtPmdldERlc2NyaXB0aW9uKCkuIlxuXG4iIDogJycpCiAgICAgICAgICAgIC4nIyMjIFVzYWdlJy4iXG5cbiIKICAgICAgICAgICAgLmFycmF5X3JlZHVjZShhcnJheV9tZXJnZShbJGNvbW1hbmQtPmdldFN5bm9wc2lzKCldLCAkY29tbWFuZC0+Z2V0QWxpYXNlcygpLCAkY29tbWFuZC0+Z2V0VXNhZ2VzKCkpLCBmdW5jdGlvbiAoJGNhcnJ5LCAkdXNhZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkY2FycnkuJyogYCcuJHVzYWdlLidgJy4iXG4iOwogICAgICAgICAgICB9KQogICAgICAgICk7CgogICAgICAgIGlmICgkaGVscCA9ICRjb21tYW5kLT5nZXRQcm9jZXNzZWRIZWxwKCkpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcbiIpOwogICAgICAgICAgICAkdGhpcy0+d3JpdGUoJGhlbHApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRjb21tYW5kLT5nZXROYXRpdmVEZWZpbml0aW9uKCkpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcblxuIik7CiAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0RGVmaW5pdGlvbigkY29tbWFuZC0+Z2V0TmF0aXZlRGVmaW5pdGlvbigpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUFwcGxpY2F0aW9uKEFwcGxpY2F0aW9uICRhcHBsaWNhdGlvbiwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkZGVzY3JpYmVkTmFtZXNwYWNlID0gaXNzZXQoJG9wdGlvbnNbJ25hbWVzcGFjZSddKSA/ICRvcHRpb25zWyduYW1lc3BhY2UnXSA6IG51bGw7CiAgICAgICAgJGRlc2NyaXB0aW9uID0gbmV3IEFwcGxpY2F0aW9uRGVzY3JpcHRpb24oJGFwcGxpY2F0aW9uLCAkZGVzY3JpYmVkTmFtZXNwYWNlKTsKICAgICAgICAkdGl0bGUgPSAkdGhpcy0+Z2V0QXBwbGljYXRpb25UaXRsZSgkYXBwbGljYXRpb24pOwoKICAgICAgICAkdGhpcy0+d3JpdGUoJHRpdGxlLiJcbiIuc3RyX3JlcGVhdCgnPScsIEhlbHBlcjo6c3RybGVuKCR0aXRsZSkpKTsKCiAgICAgICAgZm9yZWFjaCAoJGRlc2NyaXB0aW9uLT5nZXROYW1lc3BhY2VzKCkgYXMgJG5hbWVzcGFjZSkgewogICAgICAgICAgICBpZiAoQXBwbGljYXRpb25EZXNjcmlwdGlvbjo6R0xPQkFMX05BTUVTUEFDRSAhPT0gJG5hbWVzcGFjZVsnaWQnXSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcblxuIik7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGUoJyoqJy4kbmFtZXNwYWNlWydpZCddLic6KionKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRoaXMtPndyaXRlKCJcblxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZShpbXBsb2RlKCJcbiIsIGFycmF5X21hcChmdW5jdGlvbiAoJGNvbW1hbmROYW1lKSB1c2UgKCRkZXNjcmlwdGlvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyogW2Alc2BdKCMlcyknLCAkY29tbWFuZE5hbWUsIHN0cl9yZXBsYWNlKCc6JywgJycsICRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZCgkY29tbWFuZE5hbWUpLT5nZXROYW1lKCkpKTsKICAgICAgICAgICAgfSwgJG5hbWVzcGFjZVsnY29tbWFuZHMnXSkpKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZHMoKSBhcyAkY29tbWFuZCkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGUoIlxuXG4iKTsKICAgICAgICAgICAgJHRoaXMtPndyaXRlKCR0aGlzLT5kZXNjcmliZUNvbW1hbmQoJGNvbW1hbmQpKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRBcHBsaWNhdGlvblRpdGxlKEFwcGxpY2F0aW9uICRhcHBsaWNhdGlvbikKICAgIHsKICAgICAgICBpZiAoJ1VOS05PV04nICE9PSAkYXBwbGljYXRpb24tPmdldE5hbWUoKSkgewogICAgICAgICAgICBpZiAoJ1VOS05PV04nICE9PSAkYXBwbGljYXRpb24tPmdldFZlcnNpb24oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyVzICVzJywgJGFwcGxpY2F0aW9uLT5nZXROYW1lKCksICRhcHBsaWNhdGlvbi0+Z2V0VmVyc2lvbigpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRhcHBsaWNhdGlvbi0+Z2V0TmFtZSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICdDb25zb2xlIFRvb2wnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKCi8qKgogKiBUZXh0IGRlc2NyaXB0b3IuCiAqCiAqIEBhdXRob3IgSmVhbi1GcmFuw6dvaXMgU2ltb24gPGNvbnRhY3RAamZzaW1vbi5mcj4KICoKICogQGludGVybmFsCiAqLwpjbGFzcyBUZXh0RGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3IKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0QXJndW1lbnQoSW5wdXRBcmd1bWVudCAkYXJndW1lbnQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpICYmICghXGlzX2FycmF5KCRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpKSB8fCBcY291bnQoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkpKSkgewogICAgICAgICAgICAkZGVmYXVsdCA9IHNwcmludGYoJzxjb21tZW50PiBbZGVmYXVsdDogJXNdPC9jb21tZW50PicsICR0aGlzLT5mb3JtYXREZWZhdWx0VmFsdWUoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZGVmYXVsdCA9ICcnOwogICAgICAgIH0KCiAgICAgICAgJHRvdGFsV2lkdGggPSBpc3NldCgkb3B0aW9uc1sndG90YWxfd2lkdGgnXSkgPyAkb3B0aW9uc1sndG90YWxfd2lkdGgnXSA6IEhlbHBlcjo6c3RybGVuKCRhcmd1bWVudC0+Z2V0TmFtZSgpKTsKICAgICAgICAkc3BhY2luZ1dpZHRoID0gJHRvdGFsV2lkdGggLSBcc3RybGVuKCRhcmd1bWVudC0+Z2V0TmFtZSgpKTsKCiAgICAgICAgJHRoaXMtPndyaXRlVGV4dChzcHJpbnRmKCcgIDxpbmZvPiVzPC9pbmZvPiAgJXMlcyVzJywKICAgICAgICAgICAgJGFyZ3VtZW50LT5nZXROYW1lKCksCiAgICAgICAgICAgIHN0cl9yZXBlYXQoJyAnLCAkc3BhY2luZ1dpZHRoKSwKICAgICAgICAgICAgLy8gKyA0ID0gMiBzcGFjZXMgYmVmb3JlIDxpbmZvPiwgMiBzcGFjZXMgYWZ0ZXIgPC9pbmZvPgogICAgICAgICAgICBwcmVnX3JlcGxhY2UoJy9ccypbXHJcbl1ccyovJywgIlxuIi5zdHJfcmVwZWF0KCcgJywgJHRvdGFsV2lkdGggKyA0KSwgJGFyZ3VtZW50LT5nZXREZXNjcmlwdGlvbigpKSwKICAgICAgICAgICAgJGRlZmF1bHQKICAgICAgICApLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0T3B0aW9uKElucHV0T3B0aW9uICRvcHRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkgJiYgbnVsbCAhPT0gJG9wdGlvbi0+Z2V0RGVmYXVsdCgpICYmICghXGlzX2FycmF5KCRvcHRpb24tPmdldERlZmF1bHQoKSkgfHwgXGNvdW50KCRvcHRpb24tPmdldERlZmF1bHQoKSkpKSB7CiAgICAgICAgICAgICRkZWZhdWx0ID0gc3ByaW50ZignPGNvbW1lbnQ+IFtkZWZhdWx0OiAlc108L2NvbW1lbnQ+JywgJHRoaXMtPmZvcm1hdERlZmF1bHRWYWx1ZSgkb3B0aW9uLT5nZXREZWZhdWx0KCkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZGVmYXVsdCA9ICcnOwogICAgICAgIH0KCiAgICAgICAgJHZhbHVlID0gJyc7CiAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgJHZhbHVlID0gJz0nLnN0cnRvdXBwZXIoJG9wdGlvbi0+Z2V0TmFtZSgpKTsKCiAgICAgICAgICAgIGlmICgkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJ1snLiR2YWx1ZS4nXSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0b3RhbFdpZHRoID0gaXNzZXQoJG9wdGlvbnNbJ3RvdGFsX3dpZHRoJ10pID8gJG9wdGlvbnNbJ3RvdGFsX3dpZHRoJ10gOiAkdGhpcy0+Y2FsY3VsYXRlVG90YWxXaWR0aEZvck9wdGlvbnMoWyRvcHRpb25dKTsKICAgICAgICAkc3lub3BzaXMgPSBzcHJpbnRmKCclcyVzJywKICAgICAgICAgICAgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSA/IHNwcmludGYoJy0lcywgJywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgOiAnICAgICcsCiAgICAgICAgICAgIHNwcmludGYoJy0tJXMlcycsICRvcHRpb24tPmdldE5hbWUoKSwgJHZhbHVlKQogICAgICAgICk7CgogICAgICAgICRzcGFjaW5nV2lkdGggPSAkdG90YWxXaWR0aCAtIEhlbHBlcjo6c3RybGVuKCRzeW5vcHNpcyk7CgogICAgICAgICR0aGlzLT53cml0ZVRleHQoc3ByaW50ZignICA8aW5mbz4lczwvaW5mbz4gICVzJXMlcyVzJywKICAgICAgICAgICAgJHN5bm9wc2lzLAogICAgICAgICAgICBzdHJfcmVwZWF0KCcgJywgJHNwYWNpbmdXaWR0aCksCiAgICAgICAgICAgIC8vICsgNCA9IDIgc3BhY2VzIGJlZm9yZSA8aW5mbz4sIDIgc3BhY2VzIGFmdGVyIDwvaW5mbz4KICAgICAgICAgICAgcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICJcbiIuc3RyX3JlcGVhdCgnICcsICR0b3RhbFdpZHRoICsgNCksICRvcHRpb24tPmdldERlc2NyaXB0aW9uKCkpLAogICAgICAgICAgICAkZGVmYXVsdCwKICAgICAgICAgICAgJG9wdGlvbi0+aXNBcnJheSgpID8gJzxjb21tZW50PiAobXVsdGlwbGUgdmFsdWVzIGFsbG93ZWQpPC9jb21tZW50PicgOiAnJwogICAgICAgICksICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXREZWZpbml0aW9uKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdG90YWxXaWR0aCA9ICR0aGlzLT5jYWxjdWxhdGVUb3RhbFdpZHRoRm9yT3B0aW9ucygkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpKTsKICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICR0b3RhbFdpZHRoID0gbWF4KCR0b3RhbFdpZHRoLCBIZWxwZXI6OnN0cmxlbigkYXJndW1lbnQtPmdldE5hbWUoKSkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCc8Y29tbWVudD5Bcmd1bWVudHM6PC9jb21tZW50PicsICRvcHRpb25zKTsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXRBcmd1bWVudCgkYXJndW1lbnQsIGFycmF5X21lcmdlKCRvcHRpb25zLCBbJ3RvdGFsX3dpZHRoJyA9PiAkdG90YWxXaWR0aF0pKTsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkgJiYgJGRlZmluaXRpb24tPmdldE9wdGlvbnMoKSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkpIHsKICAgICAgICAgICAgJGxhdGVyT3B0aW9ucyA9IFtdOwoKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgnPGNvbW1lbnQ+T3B0aW9uczo8L2NvbW1lbnQ+JywgJG9wdGlvbnMpOwogICAgICAgICAgICBmb3JlYWNoICgkZGVmaW5pdGlvbi0+Z2V0T3B0aW9ucygpIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmIChcc3RybGVuKCRvcHRpb24tPmdldFNob3J0Y3V0KCkpID4gMSkgewogICAgICAgICAgICAgICAgICAgICRsYXRlck9wdGlvbnNbXSA9ICRvcHRpb247CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCJcbiIpOwogICAgICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXRPcHRpb24oJG9wdGlvbiwgYXJyYXlfbWVyZ2UoJG9wdGlvbnMsIFsndG90YWxfd2lkdGgnID0+ICR0b3RhbFdpZHRoXSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRsYXRlck9wdGlvbnMgYXMgJG9wdGlvbikgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kZXNjcmliZUlucHV0T3B0aW9uKCRvcHRpb24sIGFycmF5X21lcmdlKCRvcHRpb25zLCBbJ3RvdGFsX3dpZHRoJyA9PiAkdG90YWxXaWR0aF0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQ29tbWFuZChDb21tYW5kICRjb21tYW5kLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRjb21tYW5kLT5nZXRTeW5vcHNpcyh0cnVlKTsKICAgICAgICAkY29tbWFuZC0+Z2V0U3lub3BzaXMoZmFsc2UpOwogICAgICAgICRjb21tYW5kLT5tZXJnZUFwcGxpY2F0aW9uRGVmaW5pdGlvbihmYWxzZSk7CgogICAgICAgICR0aGlzLT53cml0ZVRleHQoJzxjb21tZW50PlVzYWdlOjwvY29tbWVudD4nLCAkb3B0aW9ucyk7CiAgICAgICAgZm9yZWFjaCAoYXJyYXlfbWVyZ2UoWyRjb21tYW5kLT5nZXRTeW5vcHNpcyh0cnVlKV0sICRjb21tYW5kLT5nZXRBbGlhc2VzKCksICRjb21tYW5kLT5nZXRVc2FnZXMoKSkgYXMgJHVzYWdlKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJyAgJy5PdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgkdXNhZ2UpLCAkb3B0aW9ucyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CgogICAgICAgICRkZWZpbml0aW9uID0gJGNvbW1hbmQtPmdldE5hdGl2ZURlZmluaXRpb24oKTsKICAgICAgICBpZiAoJGRlZmluaXRpb24tPmdldE9wdGlvbnMoKSB8fCAkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnRzKCkpIHsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXREZWZpbml0aW9uKCRkZWZpbml0aW9uLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGhlbHAgPSAkY29tbWFuZC0+Z2V0UHJvY2Vzc2VkSGVscCgpKSB7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJzxjb21tZW50PkhlbHA6PC9jb21tZW50PicsICRvcHRpb25zKTsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgnICAnLnN0cl9yZXBsYWNlKCJcbiIsICJcbiAgIiwgJGhlbHApLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVBcHBsaWNhdGlvbihBcHBsaWNhdGlvbiAkYXBwbGljYXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGRlc2NyaWJlZE5hbWVzcGFjZSA9IGlzc2V0KCRvcHRpb25zWyduYW1lc3BhY2UnXSkgPyAkb3B0aW9uc1snbmFtZXNwYWNlJ10gOiBudWxsOwogICAgICAgICRkZXNjcmlwdGlvbiA9IG5ldyBBcHBsaWNhdGlvbkRlc2NyaXB0aW9uKCRhcHBsaWNhdGlvbiwgJGRlc2NyaWJlZE5hbWVzcGFjZSk7CgogICAgICAgIGlmIChpc3NldCgkb3B0aW9uc1sncmF3X3RleHQnXSkgJiYgJG9wdGlvbnNbJ3Jhd190ZXh0J10pIHsKICAgICAgICAgICAgJHdpZHRoID0gJHRoaXMtPmdldENvbHVtbldpZHRoKCRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZHMoKSk7CgogICAgICAgICAgICBmb3JlYWNoICgkZGVzY3JpcHRpb24tPmdldENvbW1hbmRzKCkgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoc3ByaW50ZigiJS17JHdpZHRofXMgJXMiLCAkY29tbWFuZC0+Z2V0TmFtZSgpLCAkY29tbWFuZC0+Z2V0RGVzY3JpcHRpb24oKSksICRvcHRpb25zKTsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoJycgIT0gJGhlbHAgPSAkYXBwbGljYXRpb24tPmdldEhlbHAoKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiJGhlbHBcblxuIiwgJG9wdGlvbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+d3JpdGVUZXh0KCI8Y29tbWVudD5Vc2FnZTo8L2NvbW1lbnQ+XG4iLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIiAgY29tbWFuZCBbb3B0aW9uc10gW2FyZ3VtZW50c11cblxuIiwgJG9wdGlvbnMpOwoKICAgICAgICAgICAgJHRoaXMtPmRlc2NyaWJlSW5wdXREZWZpbml0aW9uKG5ldyBJbnB1dERlZmluaXRpb24oJGFwcGxpY2F0aW9uLT5nZXREZWZpbml0aW9uKCktPmdldE9wdGlvbnMoKSksICRvcHRpb25zKTsKCiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CgogICAgICAgICAgICAkY29tbWFuZHMgPSAkZGVzY3JpcHRpb24tPmdldENvbW1hbmRzKCk7CiAgICAgICAgICAgICRuYW1lc3BhY2VzID0gJGRlc2NyaXB0aW9uLT5nZXROYW1lc3BhY2VzKCk7CiAgICAgICAgICAgIGlmICgkZGVzY3JpYmVkTmFtZXNwYWNlICYmICRuYW1lc3BhY2VzKSB7CiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgYWxsIGFsaWFzIGNvbW1hbmRzIGFyZSBpbmNsdWRlZCB3aGVuIGRlc2NyaWJpbmcgYSBzcGVjaWZpYyBuYW1lc3BhY2UKICAgICAgICAgICAgICAgICRkZXNjcmliZWROYW1lc3BhY2VJbmZvID0gcmVzZXQoJG5hbWVzcGFjZXMpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRlc2NyaWJlZE5hbWVzcGFjZUluZm9bJ2NvbW1hbmRzJ10gYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZHNbJG5hbWVdID0gJGRlc2NyaXB0aW9uLT5nZXRDb21tYW5kKCRuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY2FsY3VsYXRlIG1heC4gd2lkdGggYmFzZWQgb24gYXZhaWxhYmxlIGNvbW1hbmRzIHBlciBuYW1lc3BhY2UKICAgICAgICAgICAgJHdpZHRoID0gJHRoaXMtPmdldENvbHVtbldpZHRoKFxjYWxsX3VzZXJfZnVuY19hcnJheSgnYXJyYXlfbWVyZ2UnLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRuYW1lc3BhY2UpIHVzZSAoJGNvbW1hbmRzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfaW50ZXJzZWN0KCRuYW1lc3BhY2VbJ2NvbW1hbmRzJ10sIGFycmF5X2tleXMoJGNvbW1hbmRzKSk7CiAgICAgICAgICAgIH0sIGFycmF5X3ZhbHVlcygkbmFtZXNwYWNlcykpKSk7CgogICAgICAgICAgICBpZiAoJGRlc2NyaWJlZE5hbWVzcGFjZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dChzcHJpbnRmKCc8Y29tbWVudD5BdmFpbGFibGUgY29tbWFuZHMgZm9yIHRoZSAiJXMiIG5hbWVzcGFjZTo8L2NvbW1lbnQ+JywgJGRlc2NyaWJlZE5hbWVzcGFjZSksICRvcHRpb25zKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoJzxjb21tZW50PkF2YWlsYWJsZSBjb21tYW5kczo8L2NvbW1lbnQ+JywgJG9wdGlvbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkbmFtZXNwYWNlcyBhcyAkbmFtZXNwYWNlKSB7CiAgICAgICAgICAgICAgICAkbmFtZXNwYWNlWydjb21tYW5kcyddID0gYXJyYXlfZmlsdGVyKCRuYW1lc3BhY2VbJ2NvbW1hbmRzJ10sIGZ1bmN0aW9uICgkbmFtZSkgdXNlICgkY29tbWFuZHMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJGNvbW1hbmRzWyRuYW1lXSk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBpZiAoISRuYW1lc3BhY2VbJ2NvbW1hbmRzJ10pIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoISRkZXNjcmliZWROYW1lc3BhY2UgJiYgQXBwbGljYXRpb25EZXNjcmlwdGlvbjo6R0xPQkFMX05BTUVTUEFDRSAhPT0gJG5hbWVzcGFjZVsnaWQnXSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgnIDxjb21tZW50PicuJG5hbWVzcGFjZVsnaWQnXS4nPC9jb21tZW50PicsICRvcHRpb25zKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbmFtZXNwYWNlWydjb21tYW5kcyddIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dCgiXG4iKTsKICAgICAgICAgICAgICAgICAgICAkc3BhY2luZ1dpZHRoID0gJHdpZHRoIC0gSGVscGVyOjpzdHJsZW4oJG5hbWUpOwogICAgICAgICAgICAgICAgICAgICRjb21tYW5kID0gJGNvbW1hbmRzWyRuYW1lXTsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZEFsaWFzZXMgPSAkbmFtZSA9PT0gJGNvbW1hbmQtPmdldE5hbWUoKSA/ICR0aGlzLT5nZXRDb21tYW5kQWxpYXNlc1RleHQoJGNvbW1hbmQpIDogJyc7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPndyaXRlVGV4dChzcHJpbnRmKCcgIDxpbmZvPiVzPC9pbmZvPiVzJXMnLCAkbmFtZSwgc3RyX3JlcGVhdCgnICcsICRzcGFjaW5nV2lkdGgpLCAkY29tbWFuZEFsaWFzZXMuJGNvbW1hbmQtPmdldERlc2NyaXB0aW9uKCkpLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT53cml0ZVRleHQoIlxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlVGV4dCgkY29udGVudCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGUoCiAgICAgICAgICAgIGlzc2V0KCRvcHRpb25zWydyYXdfdGV4dCddKSAmJiAkb3B0aW9uc1sncmF3X3RleHQnXSA/IHN0cmlwX3RhZ3MoJGNvbnRlbnQpIDogJGNvbnRlbnQsCiAgICAgICAgICAgIGlzc2V0KCRvcHRpb25zWydyYXdfb3V0cHV0J10pID8gISRvcHRpb25zWydyYXdfb3V0cHV0J10gOiB0cnVlCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgY29tbWFuZCBhbGlhc2VzIHRvIHNob3cgdGhlbSBpbiB0aGUgY29tbWFuZCBkZXNjcmlwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENvbW1hbmRBbGlhc2VzVGV4dChDb21tYW5kICRjb21tYW5kKQogICAgewogICAgICAgICR0ZXh0ID0gJyc7CiAgICAgICAgJGFsaWFzZXMgPSAkY29tbWFuZC0+Z2V0QWxpYXNlcygpOwoKICAgICAgICBpZiAoJGFsaWFzZXMpIHsKICAgICAgICAgICAgJHRleHQgPSAnWycuaW1wbG9kZSgnfCcsICRhbGlhc2VzKS4nXSAnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0cyBpbnB1dCBvcHRpb24vYXJndW1lbnQgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJGRlZmF1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZvcm1hdERlZmF1bHRWYWx1ZSgkZGVmYXVsdCkKICAgIHsKICAgICAgICBpZiAoXElORiA9PT0gJGRlZmF1bHQpIHsKICAgICAgICAgICAgcmV0dXJuICdJTkYnOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxpc19zdHJpbmcoJGRlZmF1bHQpKSB7CiAgICAgICAgICAgICRkZWZhdWx0ID0gT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoJGRlZmF1bHQpOwogICAgICAgIH0gZWxzZWlmIChcaXNfYXJyYXkoJGRlZmF1bHQpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkZWZhdWx0IGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoXGlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRbJGtleV0gPSBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJ1xcXFwnLCAnXFwnLCBqc29uX2VuY29kZSgkZGVmYXVsdCwgXEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBcSlNPTl9VTkVTQ0FQRURfVU5JQ09ERSkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIChDb21tYW5kfHN0cmluZylbXSAkY29tbWFuZHMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENvbHVtbldpZHRoKGFycmF5ICRjb21tYW5kcykKICAgIHsKICAgICAgICAkd2lkdGhzID0gW107CgogICAgICAgIGZvcmVhY2ggKCRjb21tYW5kcyBhcyAkY29tbWFuZCkgewogICAgICAgICAgICBpZiAoJGNvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kKSB7CiAgICAgICAgICAgICAgICAkd2lkdGhzW10gPSBIZWxwZXI6OnN0cmxlbigkY29tbWFuZC0+Z2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb21tYW5kLT5nZXRBbGlhc2VzKCkgYXMgJGFsaWFzKSB7CiAgICAgICAgICAgICAgICAgICAgJHdpZHRoc1tdID0gSGVscGVyOjpzdHJsZW4oJGFsaWFzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR3aWR0aHNbXSA9IEhlbHBlcjo6c3RybGVuKCRjb21tYW5kKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR3aWR0aHMgPyBtYXgoJHdpZHRocykgKyAyIDogMDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBJbnB1dE9wdGlvbltdICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxjdWxhdGVUb3RhbFdpZHRoRm9yT3B0aW9ucyhhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdG90YWxXaWR0aCA9IDA7CiAgICAgICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG9wdGlvbikgewogICAgICAgICAgICAvLyAiLSIgKyBzaG9ydGN1dCArICIsIC0tIiArIG5hbWUKICAgICAgICAgICAgJG5hbWVMZW5ndGggPSAxICsgbWF4KEhlbHBlcjo6c3RybGVuKCRvcHRpb24tPmdldFNob3J0Y3V0KCkpLCAxKSArIDQgKyBIZWxwZXI6OnN0cmxlbigkb3B0aW9uLT5nZXROYW1lKCkpOwoKICAgICAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZUxlbmd0aCA9IDEgKyBIZWxwZXI6OnN0cmxlbigkb3B0aW9uLT5nZXROYW1lKCkpOyAvLyA9ICsgdmFsdWUKICAgICAgICAgICAgICAgICR2YWx1ZUxlbmd0aCArPSAkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSA/IDIgOiAwOyAvLyBbICsgXQoKICAgICAgICAgICAgICAgICRuYW1lTGVuZ3RoICs9ICR2YWx1ZUxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdG90YWxXaWR0aCA9IG1heCgkdG90YWxXaWR0aCwgJG5hbWVMZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0b3RhbFdpZHRoOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBEZXNjcmlwdG9yIGludGVyZmFjZS4KICoKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8Y29udGFjdEBqZnNpbW9uLmZyPgogKi8KaW50ZXJmYWNlIERlc2NyaXB0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBEZXNjcmliZXMgYW4gb2JqZWN0IGlmIHN1cHBvcnRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gb2JqZWN0ICRvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CgovKioKICogWE1MIGRlc2NyaXB0b3IuCiAqCiAqIEBhdXRob3IgSmVhbi1GcmFuw6dvaXMgU2ltb24gPGNvbnRhY3RAamZzaW1vbi5mcj4KICoKICogQGludGVybmFsCiAqLwpjbGFzcyBYbWxEZXNjcmlwdG9yIGV4dGVuZHMgRGVzY3JpcHRvcgp7CiAgICAvKioKICAgICAqIEByZXR1cm4gXERPTURvY3VtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dERlZmluaXRpb25Eb2N1bWVudChJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24pCiAgICB7CiAgICAgICAgJGRvbSA9IG5ldyBcRE9NRG9jdW1lbnQoJzEuMCcsICdVVEYtOCcpOwogICAgICAgICRkb20tPmFwcGVuZENoaWxkKCRkZWZpbml0aW9uWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVmaW5pdGlvbicpKTsKCiAgICAgICAgJGRlZmluaXRpb25YTUwtPmFwcGVuZENoaWxkKCRhcmd1bWVudHNYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdhcmd1bWVudHMnKSk7CiAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAkdGhpcy0+YXBwZW5kRG9jdW1lbnQoJGFyZ3VtZW50c1hNTCwgJHRoaXMtPmdldElucHV0QXJndW1lbnREb2N1bWVudCgkYXJndW1lbnQpKTsKICAgICAgICB9CgogICAgICAgICRkZWZpbml0aW9uWE1MLT5hcHBlbmRDaGlsZCgkb3B0aW9uc1hNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ29wdGlvbnMnKSk7CiAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24tPmdldE9wdGlvbnMoKSBhcyAkb3B0aW9uKSB7CiAgICAgICAgICAgICR0aGlzLT5hcHBlbmREb2N1bWVudCgkb3B0aW9uc1hNTCwgJHRoaXMtPmdldElucHV0T3B0aW9uRG9jdW1lbnQoJG9wdGlvbikpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkb207CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFxET01Eb2N1bWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZERvY3VtZW50KENvbW1hbmQgJGNvbW1hbmQpCiAgICB7CiAgICAgICAgJGRvbSA9IG5ldyBcRE9NRG9jdW1lbnQoJzEuMCcsICdVVEYtOCcpOwogICAgICAgICRkb20tPmFwcGVuZENoaWxkKCRjb21tYW5kWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnY29tbWFuZCcpKTsKCiAgICAgICAgJGNvbW1hbmQtPmdldFN5bm9wc2lzKCk7CiAgICAgICAgJGNvbW1hbmQtPm1lcmdlQXBwbGljYXRpb25EZWZpbml0aW9uKGZhbHNlKTsKCiAgICAgICAgJGNvbW1hbmRYTUwtPnNldEF0dHJpYnV0ZSgnaWQnLCAkY29tbWFuZC0+Z2V0TmFtZSgpKTsKICAgICAgICAkY29tbWFuZFhNTC0+c2V0QXR0cmlidXRlKCduYW1lJywgJGNvbW1hbmQtPmdldE5hbWUoKSk7CiAgICAgICAgJGNvbW1hbmRYTUwtPnNldEF0dHJpYnV0ZSgnaGlkZGVuJywgJGNvbW1hbmQtPmlzSGlkZGVuKCkgPyAxIDogMCk7CgogICAgICAgICRjb21tYW5kWE1MLT5hcHBlbmRDaGlsZCgkdXNhZ2VzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgndXNhZ2VzJykpOwoKICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZShbJGNvbW1hbmQtPmdldFN5bm9wc2lzKCldLCAkY29tbWFuZC0+Z2V0QWxpYXNlcygpLCAkY29tbWFuZC0+Z2V0VXNhZ2VzKCkpIGFzICR1c2FnZSkgewogICAgICAgICAgICAkdXNhZ2VzWE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVFbGVtZW50KCd1c2FnZScsICR1c2FnZSkpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmRYTUwtPmFwcGVuZENoaWxkKCRkZXNjcmlwdGlvblhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2Rlc2NyaXB0aW9uJykpOwogICAgICAgICRkZXNjcmlwdGlvblhNTC0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlVGV4dE5vZGUoc3RyX3JlcGxhY2UoIlxuIiwgIlxuICIsICRjb21tYW5kLT5nZXREZXNjcmlwdGlvbigpKSkpOwoKICAgICAgICAkY29tbWFuZFhNTC0+YXBwZW5kQ2hpbGQoJGhlbHBYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdoZWxwJykpOwogICAgICAgICRoZWxwWE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZShzdHJfcmVwbGFjZSgiXG4iLCAiXG4gIiwgJGNvbW1hbmQtPmdldFByb2Nlc3NlZEhlbHAoKSkpKTsKCiAgICAgICAgJGRlZmluaXRpb25YTUwgPSAkdGhpcy0+Z2V0SW5wdXREZWZpbml0aW9uRG9jdW1lbnQoJGNvbW1hbmQtPmdldE5hdGl2ZURlZmluaXRpb24oKSk7CiAgICAgICAgJHRoaXMtPmFwcGVuZERvY3VtZW50KCRjb21tYW5kWE1MLCAkZGVmaW5pdGlvblhNTC0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ2RlZmluaXRpb24nKS0+aXRlbSgwKSk7CgogICAgICAgIHJldHVybiAkZG9tOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICRuYW1lc3BhY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIFxET01Eb2N1bWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXBwbGljYXRpb25Eb2N1bWVudChBcHBsaWNhdGlvbiAkYXBwbGljYXRpb24sICRuYW1lc3BhY2UgPSBudWxsKQogICAgewogICAgICAgICRkb20gPSBuZXcgXERPTURvY3VtZW50KCcxLjAnLCAnVVRGLTgnKTsKICAgICAgICAkZG9tLT5hcHBlbmRDaGlsZCgkcm9vdFhtbCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ3N5bWZvbnknKSk7CgogICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICRyb290WG1sLT5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAkYXBwbGljYXRpb24tPmdldE5hbWUoKSk7CiAgICAgICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0VmVyc2lvbigpKSB7CiAgICAgICAgICAgICAgICAkcm9vdFhtbC0+c2V0QXR0cmlidXRlKCd2ZXJzaW9uJywgJGFwcGxpY2F0aW9uLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkcm9vdFhtbC0+YXBwZW5kQ2hpbGQoJGNvbW1hbmRzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnY29tbWFuZHMnKSk7CgogICAgICAgICRkZXNjcmlwdGlvbiA9IG5ldyBBcHBsaWNhdGlvbkRlc2NyaXB0aW9uKCRhcHBsaWNhdGlvbiwgJG5hbWVzcGFjZSwgdHJ1ZSk7CgogICAgICAgIGlmICgkbmFtZXNwYWNlKSB7CiAgICAgICAgICAgICRjb21tYW5kc1hNTC0+c2V0QXR0cmlidXRlKCduYW1lc3BhY2UnLCAkbmFtZXNwYWNlKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZHMoKSBhcyAkY29tbWFuZCkgewogICAgICAgICAgICAkdGhpcy0+YXBwZW5kRG9jdW1lbnQoJGNvbW1hbmRzWE1MLCAkdGhpcy0+Z2V0Q29tbWFuZERvY3VtZW50KCRjb21tYW5kKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRuYW1lc3BhY2UpIHsKICAgICAgICAgICAgJHJvb3RYbWwtPmFwcGVuZENoaWxkKCRuYW1lc3BhY2VzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnbmFtZXNwYWNlcycpKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRkZXNjcmlwdGlvbi0+Z2V0TmFtZXNwYWNlcygpIGFzICRuYW1lc3BhY2VEZXNjcmlwdGlvbikgewogICAgICAgICAgICAgICAgJG5hbWVzcGFjZXNYTUwtPmFwcGVuZENoaWxkKCRuYW1lc3BhY2VBcnJheVhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ25hbWVzcGFjZScpKTsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VBcnJheVhNTC0+c2V0QXR0cmlidXRlKCdpZCcsICRuYW1lc3BhY2VEZXNjcmlwdGlvblsnaWQnXSk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5hbWVzcGFjZURlc2NyaXB0aW9uWydjb21tYW5kcyddIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgJG5hbWVzcGFjZUFycmF5WE1MLT5hcHBlbmRDaGlsZCgkY29tbWFuZFhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ2NvbW1hbmQnKSk7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmRYTUwtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZVRleHROb2RlKCRuYW1lKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkZG9tOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURvY3VtZW50KCR0aGlzLT5nZXRJbnB1dEFyZ3VtZW50RG9jdW1lbnQoJGFyZ3VtZW50KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0T3B0aW9uKElucHV0T3B0aW9uICRvcHRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRG9jdW1lbnQoJHRoaXMtPmdldElucHV0T3B0aW9uRG9jdW1lbnQoJG9wdGlvbikpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVJbnB1dERlZmluaXRpb24oSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURvY3VtZW50KCR0aGlzLT5nZXRJbnB1dERlZmluaXRpb25Eb2N1bWVudCgkZGVmaW5pdGlvbikpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVDb21tYW5kKENvbW1hbmQgJGNvbW1hbmQsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRG9jdW1lbnQoJHRoaXMtPmdldENvbW1hbmREb2N1bWVudCgkY29tbWFuZCkpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVBcHBsaWNhdGlvbihBcHBsaWNhdGlvbiAkYXBwbGljYXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRG9jdW1lbnQoJHRoaXMtPmdldEFwcGxpY2F0aW9uRG9jdW1lbnQoJGFwcGxpY2F0aW9uLCBpc3NldCgkb3B0aW9uc1snbmFtZXNwYWNlJ10pID8gJG9wdGlvbnNbJ25hbWVzcGFjZSddIDogbnVsbCkpOwogICAgfQoKICAgIC8qKgogICAgICogQXBwZW5kcyBkb2N1bWVudCBjaGlsZHJlbiB0byBwYXJlbnQgbm9kZS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhcHBlbmREb2N1bWVudChcRE9NTm9kZSAkcGFyZW50Tm9kZSwgXERPTU5vZGUgJGltcG9ydGVkUGFyZW50KQogICAgewogICAgICAgIGZvcmVhY2ggKCRpbXBvcnRlZFBhcmVudC0+Y2hpbGROb2RlcyBhcyAkY2hpbGROb2RlKSB7CiAgICAgICAgICAgICRwYXJlbnROb2RlLT5hcHBlbmRDaGlsZCgkcGFyZW50Tm9kZS0+b3duZXJEb2N1bWVudC0+aW1wb3J0Tm9kZSgkY2hpbGROb2RlLCB0cnVlKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIERPTSBkb2N1bWVudC4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZURvY3VtZW50KFxET01Eb2N1bWVudCAkZG9tKQogICAgewogICAgICAgICRkb20tPmZvcm1hdE91dHB1dCA9IHRydWU7CiAgICAgICAgJHRoaXMtPndyaXRlKCRkb20tPnNhdmVYTUwoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFxET01Eb2N1bWVudAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldElucHV0QXJndW1lbnREb2N1bWVudChJbnB1dEFyZ3VtZW50ICRhcmd1bWVudCkKICAgIHsKICAgICAgICAkZG9tID0gbmV3IFxET01Eb2N1bWVudCgnMS4wJywgJ1VURi04Jyk7CgogICAgICAgICRkb20tPmFwcGVuZENoaWxkKCRvYmplY3RYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdhcmd1bWVudCcpKTsKICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAkYXJndW1lbnQtPmdldE5hbWUoKSk7CiAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCdpc19yZXF1aXJlZCcsICRhcmd1bWVudC0+aXNSZXF1aXJlZCgpID8gMSA6IDApOwogICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnaXNfYXJyYXknLCAkYXJndW1lbnQtPmlzQXJyYXkoKSA/IDEgOiAwKTsKICAgICAgICAkb2JqZWN0WE1MLT5hcHBlbmRDaGlsZCgkZGVzY3JpcHRpb25YTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdkZXNjcmlwdGlvbicpKTsKICAgICAgICAkZGVzY3JpcHRpb25YTUwtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZVRleHROb2RlKCRhcmd1bWVudC0+Z2V0RGVzY3JpcHRpb24oKSkpOwoKICAgICAgICAkb2JqZWN0WE1MLT5hcHBlbmRDaGlsZCgkZGVmYXVsdHNYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdkZWZhdWx0cycpKTsKICAgICAgICAkZGVmYXVsdHMgPSBcaXNfYXJyYXkoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkpID8gJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkgOiAoXGlzX2Jvb2woJGFyZ3VtZW50LT5nZXREZWZhdWx0KCkpID8gW3Zhcl9leHBvcnQoJGFyZ3VtZW50LT5nZXREZWZhdWx0KCksIHRydWUpXSA6ICgkYXJndW1lbnQtPmdldERlZmF1bHQoKSA/IFskYXJndW1lbnQtPmdldERlZmF1bHQoKV0gOiBbXSkpOwogICAgICAgIGZvcmVhY2ggKCRkZWZhdWx0cyBhcyAkZGVmYXVsdCkgewogICAgICAgICAgICAkZGVmYXVsdHNYTUwtPmFwcGVuZENoaWxkKCRkZWZhdWx0WE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVmYXVsdCcpKTsKICAgICAgICAgICAgJGRlZmF1bHRYTUwtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZVRleHROb2RlKCRkZWZhdWx0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRvbTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gXERPTURvY3VtZW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0SW5wdXRPcHRpb25Eb2N1bWVudChJbnB1dE9wdGlvbiAkb3B0aW9uKQogICAgewogICAgICAgICRkb20gPSBuZXcgXERPTURvY3VtZW50KCcxLjAnLCAnVVRGLTgnKTsKCiAgICAgICAgJGRvbS0+YXBwZW5kQ2hpbGQoJG9iamVjdFhNTCA9ICRkb20tPmNyZWF0ZUVsZW1lbnQoJ29wdGlvbicpKTsKICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAnLS0nLiRvcHRpb24tPmdldE5hbWUoKSk7CiAgICAgICAgJHBvcyA9IHN0cnBvcygkb3B0aW9uLT5nZXRTaG9ydGN1dCgpLCAnfCcpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJHBvcykgewogICAgICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ3Nob3J0Y3V0JywgJy0nLnN1YnN0cigkb3B0aW9uLT5nZXRTaG9ydGN1dCgpLCAwLCAkcG9zKSk7CiAgICAgICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnc2hvcnRjdXRzJywgJy0nLnN0cl9yZXBsYWNlKCd8JywgJ3wtJywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnc2hvcnRjdXQnLCAkb3B0aW9uLT5nZXRTaG9ydGN1dCgpID8gJy0nLiRvcHRpb24tPmdldFNob3J0Y3V0KCkgOiAnJyk7CiAgICAgICAgfQogICAgICAgICRvYmplY3RYTUwtPnNldEF0dHJpYnV0ZSgnYWNjZXB0X3ZhbHVlJywgJG9wdGlvbi0+YWNjZXB0VmFsdWUoKSA/IDEgOiAwKTsKICAgICAgICAkb2JqZWN0WE1MLT5zZXRBdHRyaWJ1dGUoJ2lzX3ZhbHVlX3JlcXVpcmVkJywgJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCkgPyAxIDogMCk7CiAgICAgICAgJG9iamVjdFhNTC0+c2V0QXR0cmlidXRlKCdpc19tdWx0aXBsZScsICRvcHRpb24tPmlzQXJyYXkoKSA/IDEgOiAwKTsKICAgICAgICAkb2JqZWN0WE1MLT5hcHBlbmRDaGlsZCgkZGVzY3JpcHRpb25YTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdkZXNjcmlwdGlvbicpKTsKICAgICAgICAkZGVzY3JpcHRpb25YTUwtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZVRleHROb2RlKCRvcHRpb24tPmdldERlc2NyaXB0aW9uKCkpKTsKCiAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgJGRlZmF1bHRzID0gXGlzX2FycmF5KCRvcHRpb24tPmdldERlZmF1bHQoKSkgPyAkb3B0aW9uLT5nZXREZWZhdWx0KCkgOiAoXGlzX2Jvb2woJG9wdGlvbi0+Z2V0RGVmYXVsdCgpKSA/IFt2YXJfZXhwb3J0KCRvcHRpb24tPmdldERlZmF1bHQoKSwgdHJ1ZSldIDogKCRvcHRpb24tPmdldERlZmF1bHQoKSA/IFskb3B0aW9uLT5nZXREZWZhdWx0KCldIDogW10pKTsKICAgICAgICAgICAgJG9iamVjdFhNTC0+YXBwZW5kQ2hpbGQoJGRlZmF1bHRzWE1MID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnZGVmYXVsdHMnKSk7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRkZWZhdWx0cykpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkZWZhdWx0cyBhcyAkZGVmYXVsdCkgewogICAgICAgICAgICAgICAgICAgICRkZWZhdWx0c1hNTC0+YXBwZW5kQ2hpbGQoJGRlZmF1bHRYTUwgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCdkZWZhdWx0JykpOwogICAgICAgICAgICAgICAgICAgICRkZWZhdWx0WE1MLT5hcHBlbmRDaGlsZCgkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkZGVmYXVsdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRvbTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEFwcGxpY2F0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxDb21tYW5kTm90Rm91bmRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8amVhbmZyYW5jb2lzLnNpbW9uQHNlbnNpb2xhYnMuY29tPgogKgogKiBAaW50ZXJuYWwKICovCmNsYXNzIEFwcGxpY2F0aW9uRGVzY3JpcHRpb24KewogICAgY29uc3QgR0xPQkFMX05BTUVTUEFDRSA9ICdfZ2xvYmFsJzsKCiAgICBwcml2YXRlICRhcHBsaWNhdGlvbjsKICAgIHByaXZhdGUgJG5hbWVzcGFjZTsKICAgIHByaXZhdGUgJHNob3dIaWRkZW47CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgJG5hbWVzcGFjZXM7CgogICAgLyoqCiAgICAgKiBAdmFyIENvbW1hbmRbXQogICAgICovCiAgICBwcml2YXRlICRjb21tYW5kczsKCiAgICAvKioKICAgICAqIEB2YXIgQ29tbWFuZFtdCiAgICAgKi8KICAgIHByaXZhdGUgJGFsaWFzZXM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJG5hbWVzcGFjZQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICRzaG93SGlkZGVuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChBcHBsaWNhdGlvbiAkYXBwbGljYXRpb24sICRuYW1lc3BhY2UgPSBudWxsLCAkc2hvd0hpZGRlbiA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5hcHBsaWNhdGlvbiA9ICRhcHBsaWNhdGlvbjsKICAgICAgICAkdGhpcy0+bmFtZXNwYWNlID0gJG5hbWVzcGFjZTsKICAgICAgICAkdGhpcy0+c2hvd0hpZGRlbiA9ICRzaG93SGlkZGVuOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXNwYWNlcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5uYW1lc3BhY2VzKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnNwZWN0QXBwbGljYXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZXNwYWNlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ29tbWFuZFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kcygpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21tYW5kcykgewogICAgICAgICAgICAkdGhpcy0+aW5zcGVjdEFwcGxpY2F0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZAogICAgICoKICAgICAqIEB0aHJvd3MgQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kKCRuYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbW1hbmRzWyRuYW1lXSkgJiYgIWlzc2V0KCR0aGlzLT5hbGlhc2VzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdDb21tYW5kICIlcyIgZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+Y29tbWFuZHNbJG5hbWVdKSA/ICR0aGlzLT5jb21tYW5kc1skbmFtZV0gOiAkdGhpcy0+YWxpYXNlc1skbmFtZV07CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbnNwZWN0QXBwbGljYXRpb24oKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kcyA9IFtdOwogICAgICAgICR0aGlzLT5uYW1lc3BhY2VzID0gW107CgogICAgICAgICRhbGwgPSAkdGhpcy0+YXBwbGljYXRpb24tPmFsbCgkdGhpcy0+bmFtZXNwYWNlID8gJHRoaXMtPmFwcGxpY2F0aW9uLT5maW5kTmFtZXNwYWNlKCR0aGlzLT5uYW1lc3BhY2UpIDogbnVsbCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnNvcnRDb21tYW5kcygkYWxsKSBhcyAkbmFtZXNwYWNlID0+ICRjb21tYW5kcykgewogICAgICAgICAgICAkbmFtZXMgPSBbXTsKCiAgICAgICAgICAgIC8qKiBAdmFyIENvbW1hbmQgJGNvbW1hbmQgKi8KICAgICAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmRzIGFzICRuYW1lID0+ICRjb21tYW5kKSB7CiAgICAgICAgICAgICAgICBpZiAoISRjb21tYW5kLT5nZXROYW1lKCkgfHwgKCEkdGhpcy0+c2hvd0hpZGRlbiAmJiAkY29tbWFuZC0+aXNIaWRkZW4oKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGNvbW1hbmQtPmdldE5hbWUoKSA9PT0gJG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29tbWFuZHNbJG5hbWVdID0gJGNvbW1hbmQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hbGlhc2VzWyRuYW1lXSA9ICRjb21tYW5kOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRuYW1lc1tdID0gJG5hbWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5uYW1lc3BhY2VzWyRuYW1lc3BhY2VdID0gWydpZCcgPT4gJG5hbWVzcGFjZSwgJ2NvbW1hbmRzJyA9PiAkbmFtZXNdOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzb3J0Q29tbWFuZHMoYXJyYXkgJGNvbW1hbmRzKQogICAgewogICAgICAgICRuYW1lc3BhY2VkQ29tbWFuZHMgPSBbXTsKICAgICAgICAkZ2xvYmFsQ29tbWFuZHMgPSBbXTsKICAgICAgICAkc29ydGVkQ29tbWFuZHMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkY29tbWFuZHMgYXMgJG5hbWUgPT4gJGNvbW1hbmQpIHsKICAgICAgICAgICAgJGtleSA9ICR0aGlzLT5hcHBsaWNhdGlvbi0+ZXh0cmFjdE5hbWVzcGFjZSgkbmFtZSwgMSk7CiAgICAgICAgICAgIGlmIChcaW5fYXJyYXkoJGtleSwgWycnLCBzZWxmOjpHTE9CQUxfTkFNRVNQQUNFXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICRnbG9iYWxDb21tYW5kc1skbmFtZV0gPSAkY29tbWFuZDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VkQ29tbWFuZHNbJGtleV1bJG5hbWVdID0gJGNvbW1hbmQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkZ2xvYmFsQ29tbWFuZHMpIHsKICAgICAgICAgICAga3NvcnQoJGdsb2JhbENvbW1hbmRzKTsKICAgICAgICAgICAgJHNvcnRlZENvbW1hbmRzW3NlbGY6OkdMT0JBTF9OQU1FU1BBQ0VdID0gJGdsb2JhbENvbW1hbmRzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRuYW1lc3BhY2VkQ29tbWFuZHMpIHsKICAgICAgICAgICAga3NvcnQoJG5hbWVzcGFjZWRDb21tYW5kcyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRuYW1lc3BhY2VkQ29tbWFuZHMgYXMgJGtleSA9PiAkY29tbWFuZHNTZXQpIHsKICAgICAgICAgICAgICAgIGtzb3J0KCRjb21tYW5kc1NldCk7CiAgICAgICAgICAgICAgICAkc29ydGVkQ29tbWFuZHNbJGtleV0gPSAkY29tbWFuZHNTZXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkc29ydGVkQ29tbWFuZHM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXERlc2NyaXB0b3I7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxBcHBsaWNhdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEFyZ3VtZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dERlZmluaXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwoKLyoqCiAqIEpTT04gZGVzY3JpcHRvci4KICoKICogQGF1dGhvciBKZWFuLUZyYW7Dp29pcyBTaW1vbiA8Y29udGFjdEBqZnNpbW9uLmZyPgogKgogKiBAaW50ZXJuYWwKICovCmNsYXNzIEpzb25EZXNjcmlwdG9yIGV4dGVuZHMgRGVzY3JpcHRvcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlSW5wdXRBcmd1bWVudChJbnB1dEFyZ3VtZW50ICRhcmd1bWVudCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVEYXRhKCR0aGlzLT5nZXRJbnB1dEFyZ3VtZW50RGF0YSgkYXJndW1lbnQpLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0T3B0aW9uKElucHV0T3B0aW9uICRvcHRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRGF0YSgkdGhpcy0+Z2V0SW5wdXRPcHRpb25EYXRhKCRvcHRpb24pLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkZXNjcmliZUlucHV0RGVmaW5pdGlvbihJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlRGF0YSgkdGhpcy0+Z2V0SW5wdXREZWZpbml0aW9uRGF0YSgkZGVmaW5pdGlvbiksICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRlc2NyaWJlQ29tbWFuZChDb21tYW5kICRjb21tYW5kLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT53cml0ZURhdGEoJHRoaXMtPmdldENvbW1hbmREYXRhKCRjb21tYW5kKSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzY3JpYmVBcHBsaWNhdGlvbihBcHBsaWNhdGlvbiAkYXBwbGljYXRpb24sIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGRlc2NyaWJlZE5hbWVzcGFjZSA9IGlzc2V0KCRvcHRpb25zWyduYW1lc3BhY2UnXSkgPyAkb3B0aW9uc1snbmFtZXNwYWNlJ10gOiBudWxsOwogICAgICAgICRkZXNjcmlwdGlvbiA9IG5ldyBBcHBsaWNhdGlvbkRlc2NyaXB0aW9uKCRhcHBsaWNhdGlvbiwgJGRlc2NyaWJlZE5hbWVzcGFjZSwgdHJ1ZSk7CiAgICAgICAgJGNvbW1hbmRzID0gW107CgogICAgICAgIGZvcmVhY2ggKCRkZXNjcmlwdGlvbi0+Z2V0Q29tbWFuZHMoKSBhcyAkY29tbWFuZCkgewogICAgICAgICAgICAkY29tbWFuZHNbXSA9ICR0aGlzLT5nZXRDb21tYW5kRGF0YSgkY29tbWFuZCk7CiAgICAgICAgfQoKICAgICAgICAkZGF0YSA9IFtdOwogICAgICAgIGlmICgnVU5LTk9XTicgIT09ICRhcHBsaWNhdGlvbi0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgICRkYXRhWydhcHBsaWNhdGlvbiddWyduYW1lJ10gPSAkYXBwbGljYXRpb24tPmdldE5hbWUoKTsKICAgICAgICAgICAgaWYgKCdVTktOT1dOJyAhPT0gJGFwcGxpY2F0aW9uLT5nZXRWZXJzaW9uKCkpIHsKICAgICAgICAgICAgICAgICRkYXRhWydhcHBsaWNhdGlvbiddWyd2ZXJzaW9uJ10gPSAkYXBwbGljYXRpb24tPmdldFZlcnNpb24oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGRhdGFbJ2NvbW1hbmRzJ10gPSAkY29tbWFuZHM7CgogICAgICAgIGlmICgkZGVzY3JpYmVkTmFtZXNwYWNlKSB7CiAgICAgICAgICAgICRkYXRhWyduYW1lc3BhY2UnXSA9ICRkZXNjcmliZWROYW1lc3BhY2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGRhdGFbJ25hbWVzcGFjZXMnXSA9IGFycmF5X3ZhbHVlcygkZGVzY3JpcHRpb24tPmdldE5hbWVzcGFjZXMoKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+d3JpdGVEYXRhKCRkYXRhLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgZGF0YSBhcyBqc29uLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHdyaXRlRGF0YShhcnJheSAkZGF0YSwgYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJGZsYWdzID0gaXNzZXQoJG9wdGlvbnNbJ2pzb25fZW5jb2RpbmcnXSkgPyAkb3B0aW9uc1snanNvbl9lbmNvZGluZyddIDogMDsKCiAgICAgICAgJHRoaXMtPndyaXRlKGpzb25fZW5jb2RlKCRkYXRhLCAkZmxhZ3MpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnB1dEFyZ3VtZW50RGF0YShJbnB1dEFyZ3VtZW50ICRhcmd1bWVudCkKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnbmFtZScgPT4gJGFyZ3VtZW50LT5nZXROYW1lKCksCiAgICAgICAgICAgICdpc19yZXF1aXJlZCcgPT4gJGFyZ3VtZW50LT5pc1JlcXVpcmVkKCksCiAgICAgICAgICAgICdpc19hcnJheScgPT4gJGFyZ3VtZW50LT5pc0FycmF5KCksCiAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICcgJywgJGFyZ3VtZW50LT5nZXREZXNjcmlwdGlvbigpKSwKICAgICAgICAgICAgJ2RlZmF1bHQnID0+IFxJTkYgPT09ICRhcmd1bWVudC0+Z2V0RGVmYXVsdCgpID8gJ0lORicgOiAkYXJndW1lbnQtPmdldERlZmF1bHQoKSwKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldElucHV0T3B0aW9uRGF0YShJbnB1dE9wdGlvbiAkb3B0aW9uKQogICAgewogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICduYW1lJyA9PiAnLS0nLiRvcHRpb24tPmdldE5hbWUoKSwKICAgICAgICAgICAgJ3Nob3J0Y3V0JyA9PiAkb3B0aW9uLT5nZXRTaG9ydGN1dCgpID8gJy0nLnN0cl9yZXBsYWNlKCd8JywgJ3wtJywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgOiAnJywKICAgICAgICAgICAgJ2FjY2VwdF92YWx1ZScgPT4gJG9wdGlvbi0+YWNjZXB0VmFsdWUoKSwKICAgICAgICAgICAgJ2lzX3ZhbHVlX3JlcXVpcmVkJyA9PiAkb3B0aW9uLT5pc1ZhbHVlUmVxdWlyZWQoKSwKICAgICAgICAgICAgJ2lzX211bHRpcGxlJyA9PiAkb3B0aW9uLT5pc0FycmF5KCksCiAgICAgICAgICAgICdkZXNjcmlwdGlvbicgPT4gcHJlZ19yZXBsYWNlKCcvXHMqW1xyXG5dXHMqLycsICcgJywgJG9wdGlvbi0+Z2V0RGVzY3JpcHRpb24oKSksCiAgICAgICAgICAgICdkZWZhdWx0JyA9PiBcSU5GID09PSAkb3B0aW9uLT5nZXREZWZhdWx0KCkgPyAnSU5GJyA6ICRvcHRpb24tPmdldERlZmF1bHQoKSwKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldElucHV0RGVmaW5pdGlvbkRhdGEoSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uKQogICAgewogICAgICAgICRpbnB1dEFyZ3VtZW50cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSBhcyAkbmFtZSA9PiAkYXJndW1lbnQpIHsKICAgICAgICAgICAgJGlucHV0QXJndW1lbnRzWyRuYW1lXSA9ICR0aGlzLT5nZXRJbnB1dEFyZ3VtZW50RGF0YSgkYXJndW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgJGlucHV0T3B0aW9ucyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRkZWZpbml0aW9uLT5nZXRPcHRpb25zKCkgYXMgJG5hbWUgPT4gJG9wdGlvbikgewogICAgICAgICAgICAkaW5wdXRPcHRpb25zWyRuYW1lXSA9ICR0aGlzLT5nZXRJbnB1dE9wdGlvbkRhdGEoJG9wdGlvbik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gWydhcmd1bWVudHMnID0+ICRpbnB1dEFyZ3VtZW50cywgJ29wdGlvbnMnID0+ICRpbnB1dE9wdGlvbnNdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENvbW1hbmREYXRhKENvbW1hbmQgJGNvbW1hbmQpCiAgICB7CiAgICAgICAgJGNvbW1hbmQtPmdldFN5bm9wc2lzKCk7CiAgICAgICAgJGNvbW1hbmQtPm1lcmdlQXBwbGljYXRpb25EZWZpbml0aW9uKGZhbHNlKTsKCiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJ25hbWUnID0+ICRjb21tYW5kLT5nZXROYW1lKCksCiAgICAgICAgICAgICd1c2FnZScgPT4gYXJyYXlfbWVyZ2UoWyRjb21tYW5kLT5nZXRTeW5vcHNpcygpXSwgJGNvbW1hbmQtPmdldFVzYWdlcygpLCAkY29tbWFuZC0+Z2V0QWxpYXNlcygpKSwKICAgICAgICAgICAgJ2Rlc2NyaXB0aW9uJyA9PiAkY29tbWFuZC0+Z2V0RGVzY3JpcHRpb24oKSwKICAgICAgICAgICAgJ2hlbHAnID0+ICRjb21tYW5kLT5nZXRQcm9jZXNzZWRIZWxwKCksCiAgICAgICAgICAgICdkZWZpbml0aW9uJyA9PiAkdGhpcy0+Z2V0SW5wdXREZWZpbml0aW9uRGF0YSgkY29tbWFuZC0+Z2V0TmF0aXZlRGVmaW5pdGlvbigpKSwKICAgICAgICAgICAgJ2hpZGRlbicgPT4gJGNvbW1hbmQtPmlzSGlkZGVuKCksCiAgICAgICAgXTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqLwpjbGFzcyBPdXRwdXRGb3JtYXR0ZXJTdHlsZVN0YWNrCnsKICAgIC8qKgogICAgICogQHZhciBPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZVtdCiAgICAgKi8KICAgIHByaXZhdGUgJHN0eWxlczsKCiAgICBwcml2YXRlICRlbXB0eVN0eWxlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZSAkZW1wdHlTdHlsZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmVtcHR5U3R5bGUgPSAkZW1wdHlTdHlsZSA/OiBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoKTsKICAgICAgICAkdGhpcy0+cmVzZXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlc2V0cyBzdGFjayAoaWUuIGVtcHR5IGludGVybmFsIGFycmF5cykuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNldCgpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0eWxlcyA9IFtdOwogICAgfQoKICAgIC8qKgogICAgICogUHVzaGVzIGEgc3R5bGUgaW4gdGhlIHN0YWNrLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHVzaChPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZSAkc3R5bGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0eWxlc1tdID0gJHN0eWxlOwogICAgfQoKICAgIC8qKgogICAgICogUG9wcyBhIHN0eWxlIGZyb20gdGhlIHN0YWNrLgogICAgICoKICAgICAqIEByZXR1cm4gT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIHN0eWxlIHRhZ3MgaW5jb3JyZWN0bHkgbmVzdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwb3AoT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJHN0eWxlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPnN0eWxlcykpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lbXB0eVN0eWxlOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRzdHlsZSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfcG9wKCR0aGlzLT5zdHlsZXMpOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoYXJyYXlfcmV2ZXJzZSgkdGhpcy0+c3R5bGVzLCB0cnVlKSBhcyAkaW5kZXggPT4gJHN0YWNrZWRTdHlsZSkgewogICAgICAgICAgICBpZiAoJHN0eWxlLT5hcHBseSgnJykgPT09ICRzdGFja2VkU3R5bGUtPmFwcGx5KCcnKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnN0eWxlcyA9IFxhcnJheV9zbGljZSgkdGhpcy0+c3R5bGVzLCAwLCAkaW5kZXgpOwoKICAgICAgICAgICAgICAgIHJldHVybiAkc3RhY2tlZFN0eWxlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbmNvcnJlY3RseSBuZXN0ZWQgc3R5bGUgdGFnIGZvdW5kLicpOwogICAgfQoKICAgIC8qKgogICAgICogQ29tcHV0ZXMgY3VycmVudCBzdHlsZSB3aXRoIHN0YWNrcyB0b3AgY29kZXMuCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRGb3JtYXR0ZXJTdHlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q3VycmVudCgpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5zdHlsZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZW1wdHlTdHlsZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+c3R5bGVzW1xjb3VudCgkdGhpcy0+c3R5bGVzKSAtIDFdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RW1wdHlTdHlsZShPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZSAkZW1wdHlTdHlsZSkKICAgIHsKICAgICAgICAkdGhpcy0+ZW1wdHlTdHlsZSA9ICRlbXB0eVN0eWxlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbXB0eVN0eWxlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVtcHR5U3R5bGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogRm9ybWF0dGVyIHN0eWxlIGNsYXNzIGZvciBkZWZpbmluZyBzdHlsZXMuCiAqCiAqIEBhdXRob3IgS29uc3RhbnRpbiBLdWRyeWFzaG92IDxldmVyLnpldEBnbWFpbC5jb20+CiAqLwpjbGFzcyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSBpbXBsZW1lbnRzIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlCnsKICAgIHByaXZhdGUgc3RhdGljICRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzID0gWwogICAgICAgICdibGFjaycgPT4gWydzZXQnID0+IDMwLCAndW5zZXQnID0+IDM5XSwKICAgICAgICAncmVkJyA9PiBbJ3NldCcgPT4gMzEsICd1bnNldCcgPT4gMzldLAogICAgICAgICdncmVlbicgPT4gWydzZXQnID0+IDMyLCAndW5zZXQnID0+IDM5XSwKICAgICAgICAneWVsbG93JyA9PiBbJ3NldCcgPT4gMzMsICd1bnNldCcgPT4gMzldLAogICAgICAgICdibHVlJyA9PiBbJ3NldCcgPT4gMzQsICd1bnNldCcgPT4gMzldLAogICAgICAgICdtYWdlbnRhJyA9PiBbJ3NldCcgPT4gMzUsICd1bnNldCcgPT4gMzldLAogICAgICAgICdjeWFuJyA9PiBbJ3NldCcgPT4gMzYsICd1bnNldCcgPT4gMzldLAogICAgICAgICd3aGl0ZScgPT4gWydzZXQnID0+IDM3LCAndW5zZXQnID0+IDM5XSwKICAgICAgICAnZGVmYXVsdCcgPT4gWydzZXQnID0+IDM5LCAndW5zZXQnID0+IDM5XSwKICAgIF07CiAgICBwcml2YXRlIHN0YXRpYyAkYXZhaWxhYmxlQmFja2dyb3VuZENvbG9ycyA9IFsKICAgICAgICAnYmxhY2snID0+IFsnc2V0JyA9PiA0MCwgJ3Vuc2V0JyA9PiA0OV0sCiAgICAgICAgJ3JlZCcgPT4gWydzZXQnID0+IDQxLCAndW5zZXQnID0+IDQ5XSwKICAgICAgICAnZ3JlZW4nID0+IFsnc2V0JyA9PiA0MiwgJ3Vuc2V0JyA9PiA0OV0sCiAgICAgICAgJ3llbGxvdycgPT4gWydzZXQnID0+IDQzLCAndW5zZXQnID0+IDQ5XSwKICAgICAgICAnYmx1ZScgPT4gWydzZXQnID0+IDQ0LCAndW5zZXQnID0+IDQ5XSwKICAgICAgICAnbWFnZW50YScgPT4gWydzZXQnID0+IDQ1LCAndW5zZXQnID0+IDQ5XSwKICAgICAgICAnY3lhbicgPT4gWydzZXQnID0+IDQ2LCAndW5zZXQnID0+IDQ5XSwKICAgICAgICAnd2hpdGUnID0+IFsnc2V0JyA9PiA0NywgJ3Vuc2V0JyA9PiA0OV0sCiAgICAgICAgJ2RlZmF1bHQnID0+IFsnc2V0JyA9PiA0OSwgJ3Vuc2V0JyA9PiA0OV0sCiAgICBdOwogICAgcHJpdmF0ZSBzdGF0aWMgJGF2YWlsYWJsZU9wdGlvbnMgPSBbCiAgICAgICAgJ2JvbGQnID0+IFsnc2V0JyA9PiAxLCAndW5zZXQnID0+IDIyXSwKICAgICAgICAndW5kZXJzY29yZScgPT4gWydzZXQnID0+IDQsICd1bnNldCcgPT4gMjRdLAogICAgICAgICdibGluaycgPT4gWydzZXQnID0+IDUsICd1bnNldCcgPT4gMjVdLAogICAgICAgICdyZXZlcnNlJyA9PiBbJ3NldCcgPT4gNywgJ3Vuc2V0JyA9PiAyN10sCiAgICAgICAgJ2NvbmNlYWwnID0+IFsnc2V0JyA9PiA4LCAndW5zZXQnID0+IDI4XSwKICAgIF07CgogICAgcHJpdmF0ZSAkZm9yZWdyb3VuZDsKICAgIHByaXZhdGUgJGJhY2tncm91bmQ7CiAgICBwcml2YXRlICRvcHRpb25zID0gW107CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBvdXRwdXQgZm9ybWF0dGVyIHN0eWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZm9yZWdyb3VuZCBUaGUgc3R5bGUgZm9yZWdyb3VuZCBjb2xvciBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGJhY2tncm91bmQgVGhlIHN0eWxlIGJhY2tncm91bmQgY29sb3IgbmFtZQogICAgICogQHBhcmFtIGFycmF5ICAgICAgICRvcHRpb25zICAgIFRoZSBzdHlsZSBvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZm9yZWdyb3VuZCA9IG51bGwsICRiYWNrZ3JvdW5kID0gbnVsbCwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJGZvcmVncm91bmQpIHsKICAgICAgICAgICAgJHRoaXMtPnNldEZvcmVncm91bmQoJGZvcmVncm91bmQpOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCAhPT0gJGJhY2tncm91bmQpIHsKICAgICAgICAgICAgJHRoaXMtPnNldEJhY2tncm91bmQoJGJhY2tncm91bmQpOwogICAgICAgIH0KICAgICAgICBpZiAoXGNvdW50KCRvcHRpb25zKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0T3B0aW9ucygkb3B0aW9ucyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9yZWdyb3VuZCgkY29sb3IgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkY29sb3IpIHsKICAgICAgICAgICAgJHRoaXMtPmZvcmVncm91bmQgPSBudWxsOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldChzdGF0aWM6OiRhdmFpbGFibGVGb3JlZ3JvdW5kQ29sb3JzWyRjb2xvcl0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignSW52YWxpZCBmb3JlZ3JvdW5kIGNvbG9yIHNwZWNpZmllZDogIiVzIi4gRXhwZWN0ZWQgb25lIG9mICglcykuJywgJGNvbG9yLCBpbXBsb2RlKCcsICcsIGFycmF5X2tleXMoc3RhdGljOjokYXZhaWxhYmxlRm9yZWdyb3VuZENvbG9ycykpKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Zm9yZWdyb3VuZCA9IHN0YXRpYzo6JGF2YWlsYWJsZUZvcmVncm91bmRDb2xvcnNbJGNvbG9yXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJhY2tncm91bmQoJGNvbG9yID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJGNvbG9yKSB7CiAgICAgICAgICAgICR0aGlzLT5iYWNrZ3JvdW5kID0gbnVsbDsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoc3RhdGljOjokYXZhaWxhYmxlQmFja2dyb3VuZENvbG9yc1skY29sb3JdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0ludmFsaWQgYmFja2dyb3VuZCBjb2xvciBzcGVjaWZpZWQ6ICIlcyIuIEV4cGVjdGVkIG9uZSBvZiAoJXMpLicsICRjb2xvciwgaW1wbG9kZSgnLCAnLCBhcnJheV9rZXlzKHN0YXRpYzo6JGF2YWlsYWJsZUJhY2tncm91bmRDb2xvcnMpKSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmJhY2tncm91bmQgPSBzdGF0aWM6OiRhdmFpbGFibGVCYWNrZ3JvdW5kQ29sb3JzWyRjb2xvcl07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb24oJG9wdGlvbikKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KHN0YXRpYzo6JGF2YWlsYWJsZU9wdGlvbnNbJG9wdGlvbl0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignSW52YWxpZCBvcHRpb24gc3BlY2lmaWVkOiAiJXMiLiBFeHBlY3RlZCBvbmUgb2YgKCVzKS4nLCAkb3B0aW9uLCBpbXBsb2RlKCcsICcsIGFycmF5X2tleXMoc3RhdGljOjokYXZhaWxhYmxlT3B0aW9ucykpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVxpbl9hcnJheShzdGF0aWM6OiRhdmFpbGFibGVPcHRpb25zWyRvcHRpb25dLCAkdGhpcy0+b3B0aW9ucykpIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnNbXSA9IHN0YXRpYzo6JGF2YWlsYWJsZU9wdGlvbnNbJG9wdGlvbl07CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdW5zZXRPcHRpb24oJG9wdGlvbikKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KHN0YXRpYzo6JGF2YWlsYWJsZU9wdGlvbnNbJG9wdGlvbl0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignSW52YWxpZCBvcHRpb24gc3BlY2lmaWVkOiAiJXMiLiBFeHBlY3RlZCBvbmUgb2YgKCVzKS4nLCAkb3B0aW9uLCBpbXBsb2RlKCcsICcsIGFycmF5X2tleXMoc3RhdGljOjokYXZhaWxhYmxlT3B0aW9ucykpKSk7CiAgICAgICAgfQoKICAgICAgICAkcG9zID0gYXJyYXlfc2VhcmNoKHN0YXRpYzo6JGF2YWlsYWJsZU9wdGlvbnNbJG9wdGlvbl0sICR0aGlzLT5vcHRpb25zKTsKICAgICAgICBpZiAoZmFsc2UgIT09ICRwb3MpIHsKICAgICAgICAgICAgdW5zZXQoJHRoaXMtPm9wdGlvbnNbJHBvc10pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbnMoYXJyYXkgJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBbXTsKCiAgICAgICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG9wdGlvbikgewogICAgICAgICAgICAkdGhpcy0+c2V0T3B0aW9uKCRvcHRpb24pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFwcGx5KCR0ZXh0KQogICAgewogICAgICAgICRzZXRDb2RlcyA9IFtdOwogICAgICAgICR1bnNldENvZGVzID0gW107CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+Zm9yZWdyb3VuZCkgewogICAgICAgICAgICAkc2V0Q29kZXNbXSA9ICR0aGlzLT5mb3JlZ3JvdW5kWydzZXQnXTsKICAgICAgICAgICAgJHVuc2V0Q29kZXNbXSA9ICR0aGlzLT5mb3JlZ3JvdW5kWyd1bnNldCddOwogICAgICAgIH0KICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmJhY2tncm91bmQpIHsKICAgICAgICAgICAgJHNldENvZGVzW10gPSAkdGhpcy0+YmFja2dyb3VuZFsnc2V0J107CiAgICAgICAgICAgICR1bnNldENvZGVzW10gPSAkdGhpcy0+YmFja2dyb3VuZFsndW5zZXQnXTsKICAgICAgICB9CiAgICAgICAgaWYgKFxjb3VudCgkdGhpcy0+b3B0aW9ucykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm9wdGlvbnMgYXMgJG9wdGlvbikgewogICAgICAgICAgICAgICAgJHNldENvZGVzW10gPSAkb3B0aW9uWydzZXQnXTsKICAgICAgICAgICAgICAgICR1bnNldENvZGVzW10gPSAkb3B0aW9uWyd1bnNldCddOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoMCA9PT0gXGNvdW50KCRzZXRDb2RlcykpIHsKICAgICAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNwcmludGYoIlwwMzNbJXNtJXNcMDMzWyVzbSIsIGltcGxvZGUoJzsnLCAkc2V0Q29kZXMpLCAkdGV4dCwgaW1wbG9kZSgnOycsICR1bnNldENvZGVzKSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlcjsKCi8qKgogKiBGb3JtYXR0ZXIgaW50ZXJmYWNlIGZvciBjb25zb2xlIG91dHB1dC4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWNvcmF0ZWQgZmxhZy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVjb3JhdGVkIFdoZXRoZXIgdG8gZGVjb3JhdGUgdGhlIG1lc3NhZ2VzIG9yIG5vdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZGVjb3JhdGVkIGZsYWcuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIG91dHB1dCB3aWxsIGRlY29yYXRlIG1lc3NhZ2VzLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVjb3JhdGVkKCk7CgogICAgLyoqCiAgICAgKiBTZXRzIGEgbmV3IHN0eWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgVGhlIHN0eWxlIG5hbWUKICAgICAqIEBwYXJhbSBPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZSAkc3R5bGUgVGhlIHN0eWxlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHlsZSgkbmFtZSwgT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UgJHN0eWxlKTsKCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBvdXRwdXQgZm9ybWF0dGVyIGhhcyBzdHlsZSB3aXRoIHNwZWNpZmllZCBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1N0eWxlKCRuYW1lKTsKCiAgICAvKioKICAgICAqIEdldHMgc3R5bGUgb3B0aW9ucyBmcm9tIHN0eWxlIHdpdGggc3BlY2lmaWVkIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gT3V0cHV0Rm9ybWF0dGVyU3R5bGVJbnRlcmZhY2UKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBzdHlsZSBpc24ndCBkZWZpbmVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdHlsZSgkbmFtZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHN0eWxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIHN0eWxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHN0eWxlZCBtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmb3JtYXQoJG1lc3NhZ2UpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXI7CgovKioKICogRm9ybWF0dGVyIHN0eWxlIGludGVyZmFjZSBmb3IgZGVmaW5pbmcgc3R5bGVzLgogKgogKiBAYXV0aG9yIEtvbnN0YW50aW4gS3Vkcnlhc2hvdiA8ZXZlci56ZXRAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU2V0cyBzdHlsZSBmb3JlZ3JvdW5kIGNvbG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY29sb3IgVGhlIGNvbG9yIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZvcmVncm91bmQoJGNvbG9yID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHN0eWxlIGJhY2tncm91bmQgY29sb3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29sb3IgVGhlIGNvbG9yIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJhY2tncm91bmQoJGNvbG9yID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHNvbWUgc3BlY2lmaWMgc3R5bGUgb3B0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wdGlvbiBUaGUgb3B0aW9uIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbigkb3B0aW9uKTsKCiAgICAvKioKICAgICAqIFVuc2V0cyBzb21lIHNwZWNpZmljIHN0eWxlIG9wdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcHRpb24gVGhlIG9wdGlvbiBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB1bnNldE9wdGlvbigkb3B0aW9uKTsKCiAgICAvKioKICAgICAqIFNldHMgbXVsdGlwbGUgc3R5bGUgb3B0aW9ucyBhdCBvbmNlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9ucyhhcnJheSAkb3B0aW9ucyk7CgogICAgLyoqCiAgICAgKiBBcHBsaWVzIHRoZSBzdHlsZSB0byBhIGdpdmVuIHRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGV4dCBUaGUgdGV4dCB0byBzdHlsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcHBseSgkdGV4dCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogRm9ybWF0dGVyIGNsYXNzIGZvciBjb25zb2xlIG91dHB1dC4KICoKICogQGF1dGhvciBLb25zdGFudGluIEt1ZHJ5YXNob3YgPGV2ZXIuemV0QGdtYWlsLmNvbT4KICovCmNsYXNzIE91dHB1dEZvcm1hdHRlciBpbXBsZW1lbnRzIE91dHB1dEZvcm1hdHRlckludGVyZmFjZQp7CiAgICBwcml2YXRlICRkZWNvcmF0ZWQ7CiAgICBwcml2YXRlICRzdHlsZXMgPSBbXTsKICAgIHByaXZhdGUgJHN0eWxlU3RhY2s7CgogICAgLyoqCiAgICAgKiBFc2NhcGVzICI8IiBzcGVjaWFsIGNoYXIgaW4gZ2l2ZW4gdGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0IFRleHQgdG8gZXNjYXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgRXNjYXBlZCB0ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXNjYXBlKCR0ZXh0KQogICAgewogICAgICAgICR0ZXh0ID0gcHJlZ19yZXBsYWNlKCcvKFteXFxcXF0/KTwvJywgJyQxXFw8JywgJHRleHQpOwoKICAgICAgICByZXR1cm4gc2VsZjo6ZXNjYXBlVHJhaWxpbmdCYWNrc2xhc2goJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyB0cmFpbGluZyAiXCIgaW4gZ2l2ZW4gdGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0IFRleHQgdG8gZXNjYXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgRXNjYXBlZCB0ZXh0CiAgICAgKgogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXNjYXBlVHJhaWxpbmdCYWNrc2xhc2goJHRleHQpCiAgICB7CiAgICAgICAgaWYgKCdcXCcgPT09IHN1YnN0cigkdGV4dCwgLTEpKSB7CiAgICAgICAgICAgICRsZW4gPSBcc3RybGVuKCR0ZXh0KTsKICAgICAgICAgICAgJHRleHQgPSBydHJpbSgkdGV4dCwgJ1xcJyk7CiAgICAgICAgICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIlwwIiwgJycsICR0ZXh0KTsKICAgICAgICAgICAgJHRleHQgLj0gc3RyX3JlcGVhdCgiXDAiLCAkbGVuIC0gXHN0cmxlbigkdGV4dCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgY29uc29sZSBvdXRwdXQgZm9ybWF0dGVyLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWNvcmF0ZWQgV2hldGhlciB0aGlzIGZvcm1hdHRlciBzaG91bGQgYWN0dWFsbHkgZGVjb3JhdGUgc3RyaW5ncwogICAgICogQHBhcmFtIE91dHB1dEZvcm1hdHRlclN0eWxlSW50ZXJmYWNlW10gJHN0eWxlcyAgICBBcnJheSBvZiAibmFtZSA9PiBGb3JtYXR0ZXJTdHlsZSIgaW5zdGFuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZGVjb3JhdGVkID0gZmFsc2UsIGFycmF5ICRzdHlsZXMgPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGVjb3JhdGVkID0gKGJvb2wpICRkZWNvcmF0ZWQ7CgogICAgICAgICR0aGlzLT5zZXRTdHlsZSgnZXJyb3InLCBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoJ3doaXRlJywgJ3JlZCcpKTsKICAgICAgICAkdGhpcy0+c2V0U3R5bGUoJ2luZm8nLCBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoJ2dyZWVuJykpOwogICAgICAgICR0aGlzLT5zZXRTdHlsZSgnY29tbWVudCcsIG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgneWVsbG93JykpOwogICAgICAgICR0aGlzLT5zZXRTdHlsZSgncXVlc3Rpb24nLCBuZXcgT3V0cHV0Rm9ybWF0dGVyU3R5bGUoJ2JsYWNrJywgJ2N5YW4nKSk7CgogICAgICAgIGZvcmVhY2ggKCRzdHlsZXMgYXMgJG5hbWUgPT4gJHN0eWxlKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRTdHlsZSgkbmFtZSwgJHN0eWxlKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zdHlsZVN0YWNrID0gbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlU3RhY2soKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlY29yYXRlZCgkZGVjb3JhdGVkKQogICAgewogICAgICAgICR0aGlzLT5kZWNvcmF0ZWQgPSAoYm9vbCkgJGRlY29yYXRlZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVjb3JhdGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlY29yYXRlZDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0eWxlKCRuYW1lLCBPdXRwdXRGb3JtYXR0ZXJTdHlsZUludGVyZmFjZSAkc3R5bGUpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0eWxlc1tzdHJ0b2xvd2VyKCRuYW1lKV0gPSAkc3R5bGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNTdHlsZSgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPnN0eWxlc1tzdHJ0b2xvd2VyKCRuYW1lKV0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3R5bGUoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzU3R5bGUoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5kZWZpbmVkIHN0eWxlOiAiJXMiLicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnN0eWxlc1tzdHJ0b2xvd2VyKCRuYW1lKV07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmb3JtYXQoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgJG1lc3NhZ2UgPSAoc3RyaW5nKSAkbWVzc2FnZTsKICAgICAgICAkb2Zmc2V0ID0gMDsKICAgICAgICAkb3V0cHV0ID0gJyc7CiAgICAgICAgJHRhZ1JlZ2V4ID0gJ1thLXpdW2EtejAtOSxfPTstXSorJzsKICAgICAgICBwcmVnX21hdGNoX2FsbCgiIzwoKCR0YWdSZWdleCkgfCAvKCR0YWdSZWdleCk/KT4jaXgiLCAkbWVzc2FnZSwgJG1hdGNoZXMsIFxQUkVHX09GRlNFVF9DQVBUVVJFKTsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hlc1swXSBhcyAkaSA9PiAkbWF0Y2gpIHsKICAgICAgICAgICAgJHBvcyA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgJHRleHQgPSAkbWF0Y2hbMF07CgogICAgICAgICAgICBpZiAoMCAhPSAkcG9zICYmICdcXCcgPT0gJG1lc3NhZ2VbJHBvcyAtIDFdKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gYWRkIHRoZSB0ZXh0IHVwIHRvIHRoZSBuZXh0IHRhZwogICAgICAgICAgICAkb3V0cHV0IC49ICR0aGlzLT5hcHBseUN1cnJlbnRTdHlsZShzdWJzdHIoJG1lc3NhZ2UsICRvZmZzZXQsICRwb3MgLSAkb2Zmc2V0KSk7CiAgICAgICAgICAgICRvZmZzZXQgPSAkcG9zICsgXHN0cmxlbigkdGV4dCk7CgogICAgICAgICAgICAvLyBvcGVuaW5nIHRhZz8KICAgICAgICAgICAgaWYgKCRvcGVuID0gJy8nICE9ICR0ZXh0WzFdKSB7CiAgICAgICAgICAgICAgICAkdGFnID0gJG1hdGNoZXNbMV1bJGldWzBdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRhZyA9IGlzc2V0KCRtYXRjaGVzWzNdWyRpXVswXSkgPyAkbWF0Y2hlc1szXVskaV1bMF0gOiAnJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkb3BlbiAmJiAhJHRhZykgewogICAgICAgICAgICAgICAgLy8gPC8+CiAgICAgICAgICAgICAgICAkdGhpcy0+c3R5bGVTdGFjay0+cG9wKCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChmYWxzZSA9PT0gJHN0eWxlID0gJHRoaXMtPmNyZWF0ZVN0eWxlRnJvbVN0cmluZygkdGFnKSkgewogICAgICAgICAgICAgICAgJG91dHB1dCAuPSAkdGhpcy0+YXBwbHlDdXJyZW50U3R5bGUoJHRleHQpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9wZW4pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zdHlsZVN0YWNrLT5wdXNoKCRzdHlsZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c3R5bGVTdGFjay0+cG9wKCRzdHlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRvdXRwdXQgLj0gJHRoaXMtPmFwcGx5Q3VycmVudFN0eWxlKHN1YnN0cigkbWVzc2FnZSwgJG9mZnNldCkpOwoKICAgICAgICBpZiAoZmFsc2UgIT09IHN0cnBvcygkb3V0cHV0LCAiXDAiKSkgewogICAgICAgICAgICByZXR1cm4gc3RydHIoJG91dHB1dCwgWyJcMCIgPT4gJ1xcJywgJ1xcPCcgPT4gJzwnXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJ1xcPCcsICc8JywgJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIE91dHB1dEZvcm1hdHRlclN0eWxlU3RhY2sKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0eWxlU3RhY2soKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3R5bGVTdGFjazsKICAgIH0KCiAgICAvKioKICAgICAqIFRyaWVzIHRvIGNyZWF0ZSBuZXcgc3R5bGUgaW5zdGFuY2UgZnJvbSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBPdXRwdXRGb3JtYXR0ZXJTdHlsZXxmYWxzZSBmYWxzZSBpZiBzdHJpbmcgaXMgbm90IGZvcm1hdCBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVTdHlsZUZyb21TdHJpbmcoJHN0cmluZykKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnN0eWxlc1skc3RyaW5nXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zdHlsZXNbJHN0cmluZ107CiAgICAgICAgfQoKICAgICAgICBpZiAoIXByZWdfbWF0Y2hfYWxsKCcvKFtePV0rKT0oW147XSspKDt8JCkvJywgJHN0cmluZywgJG1hdGNoZXMsIFxQUkVHX1NFVF9PUkRFUikpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHN0eWxlID0gbmV3IE91dHB1dEZvcm1hdHRlclN0eWxlKCk7CiAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXMgYXMgJG1hdGNoKSB7CiAgICAgICAgICAgIGFycmF5X3NoaWZ0KCRtYXRjaCk7CiAgICAgICAgICAgICRtYXRjaFswXSA9IHN0cnRvbG93ZXIoJG1hdGNoWzBdKTsKCiAgICAgICAgICAgIGlmICgnZmcnID09ICRtYXRjaFswXSkgewogICAgICAgICAgICAgICAgJHN0eWxlLT5zZXRGb3JlZ3JvdW5kKHN0cnRvbG93ZXIoJG1hdGNoWzFdKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgnYmcnID09ICRtYXRjaFswXSkgewogICAgICAgICAgICAgICAgJHN0eWxlLT5zZXRCYWNrZ3JvdW5kKHN0cnRvbG93ZXIoJG1hdGNoWzFdKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgnb3B0aW9ucycgPT09ICRtYXRjaFswXSkgewogICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJyhbXiw7XSspJywgc3RydG9sb3dlcigkbWF0Y2hbMV0pLCAkb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAkb3B0aW9ucyA9IGFycmF5X3NoaWZ0KCRvcHRpb25zKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRvcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAkc3R5bGUtPnNldE9wdGlvbigkb3B0aW9uKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1Vua25vd24gc3R5bGUgb3B0aW9ucyBhcmUgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMiBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gRXhjZXB0aW9uICIlcyIuJywgJGUtPmdldE1lc3NhZ2UoKSksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0eWxlOwogICAgfQoKICAgIC8qKgogICAgICogQXBwbGllcyBjdXJyZW50IHN0eWxlIGZyb20gc3RhY2sgdG8gdGV4dCwgaWYgbXVzdCBiZSBhcHBsaWVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQgSW5wdXQgdGV4dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFN0eWxlZCB0ZXh0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYXBwbHlDdXJyZW50U3R5bGUoJHRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0RlY29yYXRlZCgpICYmIFxzdHJsZW4oJHRleHQpID4gMCA/ICR0aGlzLT5zdHlsZVN0YWNrLT5nZXRDdXJyZW50KCktPmFwcGx5KCR0ZXh0KSA6ICR0ZXh0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwoKLyoqCiAqIE91dHB1dEludGVyZmFjZSBpcyB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IGFsbCBPdXRwdXQgY2xhc3Nlcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwppbnRlcmZhY2UgT3V0cHV0SW50ZXJmYWNlCnsKICAgIGNvbnN0IFZFUkJPU0lUWV9RVUlFVCA9IDE2OwogICAgY29uc3QgVkVSQk9TSVRZX05PUk1BTCA9IDMyOwogICAgY29uc3QgVkVSQk9TSVRZX1ZFUkJPU0UgPSA2NDsKICAgIGNvbnN0IFZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UgPSAxMjg7CiAgICBjb25zdCBWRVJCT1NJVFlfREVCVUcgPSAyNTY7CgogICAgY29uc3QgT1VUUFVUX05PUk1BTCA9IDE7CiAgICBjb25zdCBPVVRQVVRfUkFXID0gMjsKICAgIGNvbnN0IE9VVFBVVF9QTEFJTiA9IDQ7CgogICAgLyoqCiAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZXMgVGhlIG1lc3NhZ2UgYXMgYW4gYXJyYXkgb2Ygc3RyaW5ncyBvciBhIHNpbmdsZSBzdHJpbmcKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5ld2xpbmUgIFdoZXRoZXIgdG8gYWRkIGEgbmV3bGluZQogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucyAgQSBiaXRtYXNrIG9mIG9wdGlvbnMgKG9uZSBvZiB0aGUgT1VUUFVUIG9yIFZFUkJPU0lUWSBjb25zdGFudHMpLCAwIGlzIGNvbnNpZGVyZWQgdGhlIHNhbWUgYXMgc2VsZjo6T1VUUFVUX05PUk1BTCB8IHNlbGY6OlZFUkJPU0lUWV9OT1JNQUwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUgPSBmYWxzZSwgJG9wdGlvbnMgPSAwKTsKCiAgICAvKioKICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIG91dHB1dCBhbmQgYWRkcyBhIG5ld2xpbmUgYXQgdGhlIGVuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlcyBUaGUgbWVzc2FnZSBhcyBhbiBhcnJheSBvZiBzdHJpbmdzIG9yIGEgc2luZ2xlIHN0cmluZwogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucyAgQSBiaXRtYXNrIG9mIG9wdGlvbnMgKG9uZSBvZiB0aGUgT1VUUFVUIG9yIFZFUkJPU0lUWSBjb25zdGFudHMpLCAwIGlzIGNvbnNpZGVyZWQgdGhlIHNhbWUgYXMgc2VsZjo6T1VUUFVUX05PUk1BTCB8IHNlbGY6OlZFUkJPU0lUWV9OT1JNQUwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlbG4oJG1lc3NhZ2VzLCAkb3B0aW9ucyA9IDApOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdmVyYm9zaXR5IG9mIHRoZSBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkbGV2ZWwgVGhlIGxldmVsIG9mIHZlcmJvc2l0eSAob25lIG9mIHRoZSBWRVJCT1NJVFkgY29uc3RhbnRzKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBvZiB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBjdXJyZW50IGxldmVsIG9mIHZlcmJvc2l0eSAob25lIG9mIHRoZSBWRVJCT1NJVFkgY29uc3RhbnRzKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyYm9zaXR5KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdmVyYm9zaXR5IGlzIHF1aWV0ICgtcSkuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdmVyYm9zaXR5IGlzIHNldCB0byBWRVJCT1NJVFlfUVVJRVQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNRdWlldCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB3aGV0aGVyIHZlcmJvc2l0eSBpcyB2ZXJib3NlICgtdikuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdmVyYm9zaXR5IGlzIHNldCB0byBWRVJCT1NJVFlfVkVSQk9TRSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB2ZXJib3NpdHkgaXMgdmVyeSB2ZXJib3NlICgtdnYpLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZlcmJvc2l0eSBpcyBzZXQgdG8gVkVSQk9TSVRZX1ZFUllfVkVSQk9TRSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcnlWZXJib3NlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdmVyYm9zaXR5IGlzIGRlYnVnICgtdnZ2KS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB2ZXJib3NpdHkgaXMgc2V0IHRvIFZFUkJPU0lUWV9ERUJVRywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0RlYnVnKCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWNvcmF0ZWQgZmxhZy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVjb3JhdGVkIFdoZXRoZXIgdG8gZGVjb3JhdGUgdGhlIG1lc3NhZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBkZWNvcmF0ZWQgZmxhZy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgb3V0cHV0IHdpbGwgZGVjb3JhdGUgbWVzc2FnZXMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0dGVyKE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgY3VycmVudCBvdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZXIoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlckludGVyZmFjZTsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBvdXRwdXQgY2xhc3Nlcy4KICoKICogVGhlcmUgYXJlIGZpdmUgbGV2ZWxzIG9mIHZlcmJvc2l0eToKICoKICogICogbm9ybWFsOiBubyBvcHRpb24gcGFzc2VkIChub3JtYWwgb3V0cHV0KQogKiAgKiB2ZXJib3NlOiAtdiAobW9yZSBvdXRwdXQpCiAqICAqIHZlcnkgdmVyYm9zZTogLXZ2IChoaWdobHkgZXh0ZW5kZWQgb3V0cHV0KQogKiAgKiBkZWJ1ZzogLXZ2diAoYWxsIGRlYnVnIG91dHB1dCkKICogICogcXVpZXQ6IC1xIChubyBvdXRwdXQpCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgT3V0cHV0IGltcGxlbWVudHMgT3V0cHV0SW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJHZlcmJvc2l0eTsKICAgIHByaXZhdGUgJGZvcm1hdHRlcjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyYm9zaXR5IFRoZSB2ZXJib3NpdHkgbGV2ZWwgKG9uZSBvZiB0aGUgVkVSQk9TSVRZIGNvbnN0YW50cyBpbiBPdXRwdXRJbnRlcmZhY2UpCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlY29yYXRlZCBXaGV0aGVyIHRvIGRlY29yYXRlIG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlciBPdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlIChudWxsIHRvIHVzZSBkZWZhdWx0IE91dHB1dEZvcm1hdHRlcikKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2ZXJib3NpdHkgPSBzZWxmOjpWRVJCT1NJVFlfTk9STUFMLCAkZGVjb3JhdGVkID0gZmFsc2UsIE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5ID0gbnVsbCA9PT0gJHZlcmJvc2l0eSA/IHNlbGY6OlZFUkJPU0lUWV9OT1JNQUwgOiAkdmVyYm9zaXR5OwogICAgICAgICR0aGlzLT5mb3JtYXR0ZXIgPSAkZm9ybWF0dGVyID86IG5ldyBPdXRwdXRGb3JtYXR0ZXIoKTsKICAgICAgICAkdGhpcy0+Zm9ybWF0dGVyLT5zZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdHRlciA9ICRmb3JtYXR0ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0dGVyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdHRlci0+c2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0dGVyLT5pc0RlY29yYXRlZCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmVyYm9zaXR5ID0gKGludCkgJGxldmVsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyYm9zaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUXVpZXQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfUVVJRVQgPT09ICR0aGlzLT52ZXJib3NpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfVkVSQk9TRSA8PSAkdGhpcy0+dmVyYm9zaXR5OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UgPD0gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWRVJCT1NJVFlfREVCVUcgPD0gJHRoaXMtPnZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlbG4oJG1lc3NhZ2VzLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPndyaXRlKCRtZXNzYWdlcywgdHJ1ZSwgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IGZhbHNlLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgJG1lc3NhZ2VzID0gKGFycmF5KSAkbWVzc2FnZXM7CgogICAgICAgICR0eXBlcyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwgfCBzZWxmOjpPVVRQVVRfUkFXIHwgc2VsZjo6T1VUUFVUX1BMQUlOOwogICAgICAgICR0eXBlID0gJHR5cGVzICYgJG9wdGlvbnMgPzogc2VsZjo6T1VUUFVUX05PUk1BTDsKCiAgICAgICAgJHZlcmJvc2l0aWVzID0gc2VsZjo6VkVSQk9TSVRZX1FVSUVUIHwgc2VsZjo6VkVSQk9TSVRZX05PUk1BTCB8IHNlbGY6OlZFUkJPU0lUWV9WRVJCT1NFIHwgc2VsZjo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSB8IHNlbGY6OlZFUkJPU0lUWV9ERUJVRzsKICAgICAgICAkdmVyYm9zaXR5ID0gJHZlcmJvc2l0aWVzICYgJG9wdGlvbnMgPzogc2VsZjo6VkVSQk9TSVRZX05PUk1BTDsKCiAgICAgICAgaWYgKCR2ZXJib3NpdHkgPiAkdGhpcy0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzIGFzICRtZXNzYWdlKSB7CiAgICAgICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfTk9STUFMOgogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJHRoaXMtPmZvcm1hdHRlci0+Zm9ybWF0KCRtZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpPVVRQVVRfUkFXOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6Ok9VVFBVVF9QTEFJTjoKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHN0cmlwX3RhZ3MoJHRoaXMtPmZvcm1hdHRlci0+Zm9ybWF0KCRtZXNzYWdlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0aGlzLT5kb1dyaXRlKCRtZXNzYWdlLCAkbmV3bGluZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgQSBtZXNzYWdlIHRvIHdyaXRlIHRvIHRoZSBvdXRwdXQKICAgICAqIEBwYXJhbSBib29sICAgJG5ld2xpbmUgV2hldGhlciB0byBhZGQgYSBuZXdsaW5lIG9yIG5vdAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Xcml0ZSgkbWVzc2FnZSwgJG5ld2xpbmUpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7CgovKioKICogQ29uc29sZU91dHB1dEludGVyZmFjZSBpcyB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IENvbnNvbGVPdXRwdXQgY2xhc3MuCiAqIFRoaXMgYWRkcyBpbmZvcm1hdGlvbiBhYm91dCBzdGRlcnIgb3V0cHV0IHN0cmVhbS4KICoKICogQGF1dGhvciBEYXJpdXN6IEfDs3JlY2tpIDxkYXJlay5rcmtAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UgZXh0ZW5kcyBPdXRwdXRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBPdXRwdXRJbnRlcmZhY2UgZm9yIGVycm9ycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXJyb3JPdXRwdXQoT3V0cHV0SW50ZXJmYWNlICRlcnJvcik7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2U7CgovKioKICogTnVsbE91dHB1dCBzdXBwcmVzc2VzIGFsbCBvdXRwdXQuCiAqCiAqICAgICAkb3V0cHV0ID0gbmV3IE51bGxPdXRwdXQoKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgVG9iaWFzIFNjaHVsdHplIDxodHRwOi8vdG9iaW9uLmRlPgogKi8KY2xhc3MgTnVsbE91dHB1dCBpbXBsZW1lbnRzIE91dHB1dEludGVyZmFjZQp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZvcm1hdHRlcihPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UgJGZvcm1hdHRlcikKICAgIHsKICAgICAgICAvLyBkbyBub3RoaW5nCiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZXIoKQogICAgewogICAgICAgIC8vIHRvIGNvbXBseSB3aXRoIHRoZSBpbnRlcmZhY2Ugd2UgbXVzdCByZXR1cm4gYSBPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UKICAgICAgICByZXR1cm4gbmV3IE91dHB1dEZvcm1hdHRlcigpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpCiAgICB7CiAgICAgICAgLy8gZG8gbm90aGluZwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZlcmJvc2l0eSgkbGV2ZWwpCiAgICB7CiAgICAgICAgLy8gZG8gbm90aGluZwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmVyYm9zaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VkVSQk9TSVRZX1FVSUVUOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNRdWlldCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyeVZlcmJvc2UoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlbG4oJG1lc3NhZ2VzLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgLy8gZG8gbm90aGluZwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IGZhbHNlLCAkb3B0aW9ucyA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgLy8gZG8gbm90aGluZwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwoKLyoqCiAqIFN0cmVhbU91dHB1dCB3cml0ZXMgdGhlIG91dHB1dCB0byBhIGdpdmVuIHN0cmVhbS4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkb3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKSk7CiAqCiAqIEFzIGBTdHJlYW1PdXRwdXRgIGNhbiB1c2UgYW55IHN0cmVhbSwgeW91IGNhbiBhbHNvIHVzZSBhIGZpbGU6CiAqCiAqICAgICAkb3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbignL3BhdGgvdG8vb3V0cHV0LmxvZycsICdhJywgZmFsc2UpKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBTdHJlYW1PdXRwdXQgZXh0ZW5kcyBPdXRwdXQKewogICAgcHJpdmF0ZSAkc3RyZWFtOwoKICAgIC8qKgogICAgICogQHBhcmFtIHJlc291cmNlICAgICAgICAgICAgICAgICAgICAgICRzdHJlYW0gICAgQSBzdHJlYW0gcmVzb3VyY2UKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAkdmVyYm9zaXR5IFRoZSB2ZXJib3NpdHkgbGV2ZWwgKG9uZSBvZiB0aGUgVkVSQk9TSVRZIGNvbnN0YW50cyBpbiBPdXRwdXRJbnRlcmZhY2UpCiAgICAgKiBAcGFyYW0gYm9vbHxudWxsICAgICAgICAgICAgICAgICAgICAgJGRlY29yYXRlZCBXaGV0aGVyIHRvIGRlY29yYXRlIG1lc3NhZ2VzIChudWxsIGZvciBhdXRvLWd1ZXNzaW5nKQogICAgICogQHBhcmFtIE91dHB1dEZvcm1hdHRlckludGVyZmFjZXxudWxsICRmb3JtYXR0ZXIgT3V0cHV0IGZvcm1hdHRlciBpbnN0YW5jZSAobnVsbCB0byB1c2UgZGVmYXVsdCBPdXRwdXRGb3JtYXR0ZXIpCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBmaXJzdCBhcmd1bWVudCBpcyBub3QgYSByZWFsIHN0cmVhbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHN0cmVhbSwgJHZlcmJvc2l0eSA9IHNlbGY6OlZFUkJPU0lUWV9OT1JNQUwsICRkZWNvcmF0ZWQgPSBudWxsLCBPdXRwdXRGb3JtYXR0ZXJJbnRlcmZhY2UgJGZvcm1hdHRlciA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCFcaXNfcmVzb3VyY2UoJHN0cmVhbSkgfHwgJ3N0cmVhbScgIT09IGdldF9yZXNvdXJjZV90eXBlKCRzdHJlYW0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBTdHJlYW1PdXRwdXQgY2xhc3MgbmVlZHMgYSBzdHJlYW0gYXMgaXRzIGZpcnN0IGFyZ3VtZW50LicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0cmVhbSA9ICRzdHJlYW07CgogICAgICAgIGlmIChudWxsID09PSAkZGVjb3JhdGVkKSB7CiAgICAgICAgICAgICRkZWNvcmF0ZWQgPSAkdGhpcy0+aGFzQ29sb3JTdXBwb3J0KCk7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCR2ZXJib3NpdHksICRkZWNvcmF0ZWQsICRmb3JtYXR0ZXIpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgc3RyZWFtIGF0dGFjaGVkIHRvIHRoaXMgU3RyZWFtT3V0cHV0IGluc3RhbmNlLgogICAgICoKICAgICAqIEByZXR1cm4gcmVzb3VyY2UgQSBzdHJlYW0gcmVzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0cmVhbSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdHJlYW07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1dyaXRlKCRtZXNzYWdlLCAkbmV3bGluZSkKICAgIHsKICAgICAgICBpZiAoJG5ld2xpbmUpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgLj0gXFBIUF9FT0w7CiAgICAgICAgfQoKICAgICAgICBAZndyaXRlKCR0aGlzLT5zdHJlYW0sICRtZXNzYWdlKTsKCiAgICAgICAgZmZsdXNoKCR0aGlzLT5zdHJlYW0pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdHJlYW0gc3VwcG9ydHMgY29sb3JpemF0aW9uLgogICAgICoKICAgICAqIENvbG9yaXphdGlvbiBpcyBkaXNhYmxlZCBpZiBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzdHJlYW06CiAgICAgKgogICAgICogVGhpcyBpcyB0cmlja3kgb24gV2luZG93cywgYmVjYXVzZSBDeWd3aW4sIE1zeXMyIGV0YyBlbXVsYXRlIHBzZXVkbwogICAgICogdGVybWluYWxzIHZpYSBuYW1lZCBwaXBlcywgc28gd2UgY2FuIG9ubHkgY2hlY2sgdGhlIGVudmlyb25tZW50LgogICAgICoKICAgICAqIFJlZmVyZW5jZTogQ29tcG9zZXJcWGRlYnVnSGFuZGxlclxQcm9jZXNzOjpzdXBwb3J0c0NvbG9yCiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vY29tcG9zZXIveGRlYnVnLWhhbmRsZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgc3RyZWFtIHN1cHBvcnRzIGNvbG9yaXphdGlvbiwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBoYXNDb2xvclN1cHBvcnQoKQogICAgewogICAgICAgIGlmICgnSHlwZXInID09PSBnZXRlbnYoJ1RFUk1fUFJPR1JBTScpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKFxESVJFQ1RPUllfU0VQQVJBVE9SID09PSAnXFwnKSB7CiAgICAgICAgICAgIHJldHVybiAoXGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQnKQogICAgICAgICAgICAgICAgJiYgQHNhcGlfd2luZG93c192dDEwMF9zdXBwb3J0KCR0aGlzLT5zdHJlYW0pKQogICAgICAgICAgICAgICAgfHwgZmFsc2UgIT09IGdldGVudignQU5TSUNPTicpCiAgICAgICAgICAgICAgICB8fCAnT04nID09PSBnZXRlbnYoJ0NvbkVtdUFOU0knKQogICAgICAgICAgICAgICAgfHwgJ3h0ZXJtJyA9PT0gZ2V0ZW52KCdURVJNJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoXGZ1bmN0aW9uX2V4aXN0cygnc3RyZWFtX2lzYXR0eScpKSB7CiAgICAgICAgICAgIHJldHVybiBAc3RyZWFtX2lzYXR0eSgkdGhpcy0+c3RyZWFtKTsKICAgICAgICB9CgogICAgICAgIGlmIChcZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9pc2F0dHknKSkgewogICAgICAgICAgICByZXR1cm4gQHBvc2l4X2lzYXR0eSgkdGhpcy0+c3RyZWFtKTsKICAgICAgICB9CgogICAgICAgICRzdGF0ID0gQGZzdGF0KCR0aGlzLT5zdHJlYW0pOwogICAgICAgIC8vIENoZWNrIGlmIGZvcm1hdHRlZCBtb2RlIGlzIFNfSUZDSFIKICAgICAgICByZXR1cm4gJHN0YXQgPyAwMDIwMDAwID09PSAoJHN0YXRbJ21vZGUnXSAmIDAxNzAwMDApIDogZmFsc2U7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dDsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqLwpjbGFzcyBCdWZmZXJlZE91dHB1dCBleHRlbmRzIE91dHB1dAp7CiAgICBwcml2YXRlICRidWZmZXIgPSAnJzsKCiAgICAvKioKICAgICAqIEVtcHRpZXMgYnVmZmVyIGFuZCByZXR1cm5zIGl0cyBjb250ZW50LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmZXRjaCgpCiAgICB7CiAgICAgICAgJGNvbnRlbnQgPSAkdGhpcy0+YnVmZmVyOwogICAgICAgICR0aGlzLT5idWZmZXIgPSAnJzsKCiAgICAgICAgcmV0dXJuICRjb250ZW50OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9Xcml0ZSgkbWVzc2FnZSwgJG5ld2xpbmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmJ1ZmZlciAuPSAkbWVzc2FnZTsKCiAgICAgICAgaWYgKCRuZXdsaW5lKSB7CiAgICAgICAgICAgICR0aGlzLT5idWZmZXIgLj0gXFBIUF9FT0w7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwoKLyoqCiAqIENvbnNvbGVPdXRwdXQgaXMgdGhlIGRlZmF1bHQgY2xhc3MgZm9yIGFsbCBDTEkgb3V0cHV0LiBJdCB1c2VzIFNURE9VVCBhbmQgU1RERVJSLgogKgogKiBUaGlzIGNsYXNzIGlzIGEgY29udmVuaWVudCB3cmFwcGVyIGFyb3VuZCBgU3RyZWFtT3V0cHV0YCBmb3IgYm90aCBTVERPVVQgYW5kIFNUREVSUi4KICoKICogICAgICRvdXRwdXQgPSBuZXcgQ29uc29sZU91dHB1dCgpOwogKgogKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG86CiAqCiAqICAgICAkb3V0cHV0ID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKSk7CiAqICAgICAkc3RkRXJyID0gbmV3IFN0cmVhbU91dHB1dChmb3BlbigncGhwOi8vc3RkZXJyJywgJ3cnKSk7CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgQ29uc29sZU91dHB1dCBleHRlbmRzIFN0cmVhbU91dHB1dCBpbXBsZW1lbnRzIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkc3RkZXJyOwoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkgVGhlIHZlcmJvc2l0eSBsZXZlbCAob25lIG9mIHRoZSBWRVJCT1NJVFkgY29uc3RhbnRzIGluIE91dHB1dEludGVyZmFjZSkKICAgICAqIEBwYXJhbSBib29sfG51bGwgICAgICAgICAgICAgICAgICAgICAkZGVjb3JhdGVkIFdoZXRoZXIgdG8gZGVjb3JhdGUgbWVzc2FnZXMgKG51bGwgZm9yIGF1dG8tZ3Vlc3NpbmcpCiAgICAgKiBAcGFyYW0gT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlfG51bGwgJGZvcm1hdHRlciBPdXRwdXQgZm9ybWF0dGVyIGluc3RhbmNlIChudWxsIHRvIHVzZSBkZWZhdWx0IE91dHB1dEZvcm1hdHRlcikKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2ZXJib3NpdHkgPSBzZWxmOjpWRVJCT1NJVFlfTk9STUFMLCAkZGVjb3JhdGVkID0gbnVsbCwgT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJHRoaXMtPm9wZW5PdXRwdXRTdHJlYW0oKSwgJHZlcmJvc2l0eSwgJGRlY29yYXRlZCwgJGZvcm1hdHRlcik7CgogICAgICAgICRhY3R1YWxEZWNvcmF0ZWQgPSAkdGhpcy0+aXNEZWNvcmF0ZWQoKTsKICAgICAgICAkdGhpcy0+c3RkZXJyID0gbmV3IFN0cmVhbU91dHB1dCgkdGhpcy0+b3BlbkVycm9yU3RyZWFtKCksICR2ZXJib3NpdHksICRkZWNvcmF0ZWQsICR0aGlzLT5nZXRGb3JtYXR0ZXIoKSk7CgogICAgICAgIGlmIChudWxsID09PSAkZGVjb3JhdGVkKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXREZWNvcmF0ZWQoJGFjdHVhbERlY29yYXRlZCAmJiAkdGhpcy0+c3RkZXJyLT5pc0RlY29yYXRlZCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWNvcmF0ZWQoJGRlY29yYXRlZCkKICAgIHsKICAgICAgICBwYXJlbnQ6OnNldERlY29yYXRlZCgkZGVjb3JhdGVkKTsKICAgICAgICAkdGhpcy0+c3RkZXJyLT5zZXREZWNvcmF0ZWQoJGRlY29yYXRlZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGb3JtYXR0ZXIoT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgcGFyZW50OjpzZXRGb3JtYXR0ZXIoJGZvcm1hdHRlcik7CiAgICAgICAgJHRoaXMtPnN0ZGVyci0+c2V0Rm9ybWF0dGVyKCRmb3JtYXR0ZXIpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICBwYXJlbnQ6OnNldFZlcmJvc2l0eSgkbGV2ZWwpOwogICAgICAgICR0aGlzLT5zdGRlcnItPnNldFZlcmJvc2l0eSgkbGV2ZWwpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JPdXRwdXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RkZXJyOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXJyb3JPdXRwdXQoT3V0cHV0SW50ZXJmYWNlICRlcnJvcikKICAgIHsKICAgICAgICAkdGhpcy0+c3RkZXJyID0gJGVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGN1cnJlbnQgZW52aXJvbm1lbnQgc3VwcG9ydHMgd3JpdGluZyBjb25zb2xlIG91dHB1dCB0bwogICAgICogU1RET1VULgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaGFzU3Rkb3V0U3VwcG9ydCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlID09PSAkdGhpcy0+aXNSdW5uaW5nT1M0MDAoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBjdXJyZW50IGVudmlyb25tZW50IHN1cHBvcnRzIHdyaXRpbmcgY29uc29sZSBvdXRwdXQgdG8KICAgICAqIFNUREVSUi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc1N0ZGVyclN1cHBvcnQoKQogICAgewogICAgICAgIHJldHVybiBmYWxzZSA9PT0gJHRoaXMtPmlzUnVubmluZ09TNDAwKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgY3VycmVudCBleGVjdXRpbmcgZW52aXJvbm1lbnQgaXMgSUJNIGlTZXJpZXMgKE9TNDAwKSwgd2hpY2gKICAgICAqIGRvZXNuJ3QgcHJvcGVybHkgY29udmVydCBjaGFyYWN0ZXItZW5jb2RpbmdzIGJldHdlZW4gQVNDSUkgdG8gRUJDRElDLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzUnVubmluZ09TNDAwKCkKICAgIHsKICAgICAgICAkY2hlY2tzID0gWwogICAgICAgICAgICBcZnVuY3Rpb25fZXhpc3RzKCdwaHBfdW5hbWUnKSA/IHBocF91bmFtZSgncycpIDogJycsCiAgICAgICAgICAgIGdldGVudignT1NUWVBFJyksCiAgICAgICAgICAgIFxQSFBfT1MsCiAgICAgICAgXTsKCiAgICAgICAgcmV0dXJuIGZhbHNlICE9PSBzdHJpcG9zKGltcGxvZGUoJzsnLCAkY2hlY2tzKSwgJ09TNDAwJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHJlc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3Blbk91dHB1dFN0cmVhbSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+aGFzU3Rkb3V0U3VwcG9ydCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmb3BlbigncGhwOi8vb3V0cHV0JywgJ3cnKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBAZm9wZW4oJ3BocDovL3N0ZG91dCcsICd3JykgPzogZm9wZW4oJ3BocDovL291dHB1dCcsICd3Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHJlc291cmNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gb3BlbkVycm9yU3RyZWFtKCkKICAgIHsKICAgICAgICByZXR1cm4gZm9wZW4oJHRoaXMtPmhhc1N0ZGVyclN1cHBvcnQoKSA/ICdwaHA6Ly9zdGRlcnInIDogJ3BocDovL291dHB1dCcsICd3Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcUHJvY2Vzc1xFeGNlcHRpb25cUHJvY2Vzc0ZhaWxlZEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFByb2Nlc3NcUHJvY2VzczsKCi8qKgogKiBUaGUgUHJvY2Vzc0hlbHBlciBjbGFzcyBwcm92aWRlcyBoZWxwZXJzIHRvIHJ1biBleHRlcm5hbCBwcm9jZXNzZXMuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgUHJvY2Vzc0hlbHBlciBleHRlbmRzIEhlbHBlcgp7CiAgICAvKioKICAgICAqIFJ1bnMgYW4gZXh0ZXJuYWwgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICAgICAgJG91dHB1dCAgICBBbiBPdXRwdXRJbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXl8UHJvY2VzcyAkY21kICAgICAgIEFuIGluc3RhbmNlIG9mIFByb2Nlc3Mgb3IgYW4gYXJyYXkgb2YgYXJndW1lbnRzIHRvIGVzY2FwZSBhbmQgcnVuIG9yIGEgY29tbWFuZCB0byBydW4KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAgICAgICAkZXJyb3IgICAgIEFuIGVycm9yIG1lc3NhZ2UgdGhhdCBtdXN0IGJlIGRpc3BsYXllZCBpZiBzb21ldGhpbmcgd2VudCB3cm9uZwogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgICAgICAgICRjYWxsYmFjayAgQSBQSFAgY2FsbGJhY2sgdG8gcnVuIHdoZW5ldmVyIHRoZXJlIGlzIHNvbWUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCBhdmFpbGFibGUgb24gU1RET1VUIG9yIFNUREVSUgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICAgICR2ZXJib3NpdHkgVGhlIHRocmVzaG9sZCBmb3IgdmVyYm9zaXR5CiAgICAgKgogICAgICogQHJldHVybiBQcm9jZXNzIFRoZSBwcm9jZXNzIHRoYXQgcmFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBydW4oT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRjbWQsICRlcnJvciA9IG51bGwsIGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwsICR2ZXJib3NpdHkgPSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJZX1ZFUkJPU0UpCiAgICB7CiAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoUHJvY2Vzczo6Y2xhc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ1RoZSBQcm9jZXNzSGVscGVyIGNhbm5vdCBiZSBydW4gYXMgdGhlIFByb2Nlc3MgY29tcG9uZW50IGlzIG5vdCBpbnN0YWxsZWQuIFRyeSBydW5uaW5nICJjb21wb3NlIHJlcXVpcmUgc3ltZm9ueS9wcm9jZXNzIi4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgQ29uc29sZU91dHB1dEludGVyZmFjZSkgewogICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgICRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0SGVscGVyU2V0KCktPmdldCgnZGVidWdfZm9ybWF0dGVyJyk7CgogICAgICAgIGlmICgkY21kIGluc3RhbmNlb2YgUHJvY2VzcykgewogICAgICAgICAgICAkcHJvY2VzcyA9ICRjbWQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHByb2Nlc3MgPSBuZXcgUHJvY2VzcygkY21kKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdmVyYm9zaXR5IDw9ICRvdXRwdXQtPmdldFZlcmJvc2l0eSgpKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRmb3JtYXR0ZXItPnN0YXJ0KHNwbF9vYmplY3RfaGFzaCgkcHJvY2VzcyksICR0aGlzLT5lc2NhcGVTdHJpbmcoJHByb2Nlc3MtPmdldENvbW1hbmRMaW5lKCkpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG91dHB1dC0+aXNEZWJ1ZygpKSB7CiAgICAgICAgICAgICRjYWxsYmFjayA9ICR0aGlzLT53cmFwQ2FsbGJhY2soJG91dHB1dCwgJHByb2Nlc3MsICRjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICAkcHJvY2Vzcy0+cnVuKCRjYWxsYmFjayk7CgogICAgICAgIGlmICgkdmVyYm9zaXR5IDw9ICRvdXRwdXQtPmdldFZlcmJvc2l0eSgpKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpID8gJ0NvbW1hbmQgcmFuIHN1Y2Nlc3NmdWxseScgOiBzcHJpbnRmKCclcyBDb21tYW5kIGRpZCBub3QgcnVuIHN1Y2Nlc3NmdWxseScsICRwcm9jZXNzLT5nZXRFeGl0Q29kZSgpKTsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoJGZvcm1hdHRlci0+c3RvcChzcGxfb2JqZWN0X2hhc2goJHByb2Nlc3MpLCAkbWVzc2FnZSwgJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRwcm9jZXNzLT5pc1N1Y2Nlc3NmdWwoKSAmJiBudWxsICE9PSAkZXJyb3IpIHsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCc8ZXJyb3I+JXM8L2Vycm9yPicsICR0aGlzLT5lc2NhcGVTdHJpbmcoJGVycm9yKSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcm9jZXNzOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyB0aGUgcHJvY2Vzcy4KICAgICAqCiAgICAgKiBUaGlzIGlzIGlkZW50aWNhbCB0byBydW4oKSBleGNlcHQgdGhhdCBhbiBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZSBwcm9jZXNzCiAgICAgKiBleGl0cyB3aXRoIGEgbm9uLXplcm8gZXhpdCBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCAgIEFuIE91dHB1dEludGVyZmFjZSBpbnN0YW5jZQogICAgICogQHBhcmFtIHN0cmluZ3xQcm9jZXNzICAkY21kICAgICAgQW4gaW5zdGFuY2Ugb2YgUHJvY2VzcyBvciBhIGNvbW1hbmQgdG8gcnVuCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICRlcnJvciAgICBBbiBlcnJvciBtZXNzYWdlIHRoYXQgbXVzdCBiZSBkaXNwbGF5ZWQgaWYgc29tZXRoaW5nIHdlbnQgd3JvbmcKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICAgJGNhbGxiYWNrIEEgUEhQIGNhbGxiYWNrIHRvIHJ1biB3aGVuZXZlciB0aGVyZSBpcyBzb21lCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgYXZhaWxhYmxlIG9uIFNURE9VVCBvciBTVERFUlIKICAgICAqCiAgICAgKiBAcmV0dXJuIFByb2Nlc3MgVGhlIHByb2Nlc3MgdGhhdCByYW4KICAgICAqCiAgICAgKiBAdGhyb3dzIFByb2Nlc3NGYWlsZWRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAc2VlIHJ1bigpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtdXN0UnVuKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkY21kLCAkZXJyb3IgPSBudWxsLCBjYWxsYWJsZSAkY2FsbGJhY2sgPSBudWxsKQogICAgewogICAgICAgICRwcm9jZXNzID0gJHRoaXMtPnJ1bigkb3V0cHV0LCAkY21kLCAkZXJyb3IsICRjYWxsYmFjayk7CgogICAgICAgIGlmICghJHByb2Nlc3MtPmlzU3VjY2Vzc2Z1bCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBQcm9jZXNzRmFpbGVkRXhjZXB0aW9uKCRwcm9jZXNzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvY2VzczsKICAgIH0KCiAgICAvKioKICAgICAqIFdyYXBzIGEgUHJvY2VzcyBjYWxsYmFjayB0byBhZGQgZGVidWdnaW5nIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQgICBBbiBPdXRwdXRJbnRlcmZhY2UgaW50ZXJmYWNlCiAgICAgKiBAcGFyYW0gUHJvY2VzcyAgICAgICAgICRwcm9jZXNzICBUaGUgUHJvY2VzcwogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgICAkY2FsbGJhY2sgQSBQSFAgY2FsbGFibGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cmFwQ2FsbGJhY2soT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFByb2Nlc3MgJHByb2Nlc3MsIGNhbGxhYmxlICRjYWxsYmFjayA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRvdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRvdXRwdXQgPSAkb3V0cHV0LT5nZXRFcnJvck91dHB1dCgpOwogICAgICAgIH0KCiAgICAgICAgJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRIZWxwZXJTZXQoKS0+Z2V0KCdkZWJ1Z19mb3JtYXR0ZXInKTsKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkdHlwZSwgJGJ1ZmZlcikgdXNlICgkb3V0cHV0LCAkcHJvY2VzcywgJGNhbGxiYWNrLCAkZm9ybWF0dGVyKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRmb3JtYXR0ZXItPnByb2dyZXNzKHNwbF9vYmplY3RfaGFzaCgkcHJvY2VzcyksICR0aGlzLT5lc2NhcGVTdHJpbmcoJGJ1ZmZlciksIFByb2Nlc3M6OkVSUiA9PT0gJHR5cGUpKTsKCiAgICAgICAgICAgIGlmIChudWxsICE9PSAkY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIFxjYWxsX3VzZXJfZnVuYygkY2FsbGJhY2ssICR0eXBlLCAkYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBlc2NhcGVTdHJpbmcoJHN0cikKICAgIHsKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJzwnLCAnXFw8JywgJHN0cik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3Byb2Nlc3MnOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxDaG9pY2VRdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cQ29uZmlybWF0aW9uUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXFF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxTdHlsZVxTeW1mb255U3R5bGU7CgovKioKICogU3ltZm9ueSBTdHlsZSBHdWlkZSBjb21wbGlhbnQgcXVlc3Rpb24gaGVscGVyLgogKgogKiBAYXV0aG9yIEtldmluIEJvbmQgPGtldmluYm9uZEBnbWFpbC5jb20+CiAqLwpjbGFzcyBTeW1mb255UXVlc3Rpb25IZWxwZXIgZXh0ZW5kcyBRdWVzdGlvbkhlbHBlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBUbyBiZSByZW1vdmVkIGluIDQuMAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHF1ZXN0aW9uLT5nZXRWYWxpZGF0b3IoKTsKICAgICAgICAkcXVlc3Rpb24tPnNldFZhbGlkYXRvcihmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCR2YWxpZGF0b3IpIHsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICR2YWxpZGF0b3IpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR2YWxpZGF0b3IoJHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIG1ha2UgcmVxdWlyZWQKICAgICAgICAgICAgICAgIGlmICghXGlzX2FycmF5KCR2YWx1ZSkgJiYgIVxpc19ib29sKCR2YWx1ZSkgJiYgMCA9PT0gXHN0cmxlbigkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3IoJ1RoZSBkZWZhdWx0IHF1ZXN0aW9uIHZhbGlkYXRvciBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIG5vdCBiZSB1c2VkIGFueW1vcmUgaW4gdmVyc2lvbiA0LjAuIFNldCBhIGN1c3RvbSBxdWVzdGlvbiB2YWxpZGF0b3IgaWYgbmVlZGVkLicsIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSB2YWx1ZSBpcyByZXF1aXJlZC4nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIHBhcmVudDo6YXNrKCRpbnB1dCwgJG91dHB1dCwgJHF1ZXN0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlUHJvbXB0KE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBRdWVzdGlvbiAkcXVlc3Rpb24pCiAgICB7CiAgICAgICAgJHRleHQgPSBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZVRyYWlsaW5nQmFja3NsYXNoKCRxdWVzdGlvbi0+Z2V0UXVlc3Rpb24oKSk7CiAgICAgICAgJGRlZmF1bHQgPSAkcXVlc3Rpb24tPmdldERlZmF1bHQoKTsKCiAgICAgICAgc3dpdGNoICh0cnVlKSB7CiAgICAgICAgICAgIGNhc2UgbnVsbCA9PT0gJGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkdGV4dCA9IHNwcmludGYoJyA8aW5mbz4lczwvaW5mbz46JywgJHRleHQpOwoKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAkcXVlc3Rpb24gaW5zdGFuY2VvZiBDb25maXJtYXRpb25RdWVzdGlvbjoKICAgICAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignIDxpbmZvPiVzICh5ZXMvbm8pPC9pbmZvPiBbPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+XTonLCAkdGV4dCwgJGRlZmF1bHQgPyAneWVzJyA6ICdubycpOwoKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAkcXVlc3Rpb24gaW5zdGFuY2VvZiBDaG9pY2VRdWVzdGlvbiAmJiAkcXVlc3Rpb24tPmlzTXVsdGlzZWxlY3QoKToKICAgICAgICAgICAgICAgICRjaG9pY2VzID0gJHF1ZXN0aW9uLT5nZXRDaG9pY2VzKCk7CiAgICAgICAgICAgICAgICAkZGVmYXVsdCA9IGV4cGxvZGUoJywnLCAkZGVmYXVsdCk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGRlZmF1bHQgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkZGVmYXVsdFska2V5XSA9ICRjaG9pY2VzW3RyaW0oJHZhbHVlKV07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRleHQgPSBzcHJpbnRmKCcgPGluZm8+JXM8L2luZm8+IFs8Y29tbWVudD4lczwvY29tbWVudD5dOicsICR0ZXh0LCBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZShpbXBsb2RlKCcsICcsICRkZWZhdWx0KSkpOwoKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAkcXVlc3Rpb24gaW5zdGFuY2VvZiBDaG9pY2VRdWVzdGlvbjoKICAgICAgICAgICAgICAgICRjaG9pY2VzID0gJHF1ZXN0aW9uLT5nZXRDaG9pY2VzKCk7CiAgICAgICAgICAgICAgICAkdGV4dCA9IHNwcmludGYoJyA8aW5mbz4lczwvaW5mbz4gWzxjb21tZW50PiVzPC9jb21tZW50Pl06JywgJHRleHQsIE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlKGlzc2V0KCRjaG9pY2VzWyRkZWZhdWx0XSkgPyAkY2hvaWNlc1skZGVmYXVsdF0gOiAkZGVmYXVsdCkpOwoKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICR0ZXh0ID0gc3ByaW50ZignIDxpbmZvPiVzPC9pbmZvPiBbPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+XTonLCAkdGV4dCwgT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoJGRlZmF1bHQpKTsKICAgICAgICB9CgogICAgICAgICRvdXRwdXQtPndyaXRlbG4oJHRleHQpOwoKICAgICAgICAkcHJvbXB0ID0gJyA+ICc7CgogICAgICAgIGlmICgkcXVlc3Rpb24gaW5zdGFuY2VvZiBDaG9pY2VRdWVzdGlvbikgewogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCR0aGlzLT5mb3JtYXRDaG9pY2VRdWVzdGlvbkNob2ljZXMoJHF1ZXN0aW9uLCAnY29tbWVudCcpKTsKCiAgICAgICAgICAgICRwcm9tcHQgPSAkcXVlc3Rpb24tPmdldFByb21wdCgpOwogICAgICAgIH0KCiAgICAgICAgJG91dHB1dC0+d3JpdGUoJHByb21wdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZUVycm9yKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBcRXhjZXB0aW9uICRlcnJvcikKICAgIHsKICAgICAgICBpZiAoJG91dHB1dCBpbnN0YW5jZW9mIFN5bWZvbnlTdHlsZSkgewogICAgICAgICAgICAkb3V0cHV0LT5uZXdMaW5lKCk7CiAgICAgICAgICAgICRvdXRwdXQtPmVycm9yKCRlcnJvci0+Z2V0TWVzc2FnZSgpKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHBhcmVudDo6d3JpdGVFcnJvcigkb3V0cHV0LCAkZXJyb3IpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwoKLyoqCiAqIEhlbHBlciBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIGhlbHBlciBjbGFzc2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmFic3RyYWN0IGNsYXNzIEhlbHBlciBpbXBsZW1lbnRzIEhlbHBlckludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGhlbHBlclNldCA9IG51bGw7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIZWxwZXJTZXQoSGVscGVyU2V0ICRoZWxwZXJTZXQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5oZWxwZXJTZXQgPSAkaGVscGVyU2V0OwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyU2V0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmhlbHBlclNldDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiBhIHN0cmluZywgdXNpbmcgbWJfc3Ryd2lkdGggaWYgaXQgaXMgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGNoZWNrIGl0cyBsZW5ndGgKICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzdHJsZW4oJHN0cmluZykKICAgIHsKICAgICAgICBpZiAoZmFsc2UgPT09ICRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZygkc3RyaW5nLCBudWxsLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gXHN0cmxlbigkc3RyaW5nKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBtYl9zdHJ3aWR0aCgkc3RyaW5nLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3Vic2V0IG9mIGEgc3RyaW5nLCB1c2luZyBtYl9zdWJzdHIgaWYgaXQgaXMgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkc3RyaW5nIFN0cmluZyB0byBzdWJzZXQKICAgICAqIEBwYXJhbSBpbnQgICAgICAkZnJvbSAgIFN0YXJ0IG9mZnNldAogICAgICogQHBhcmFtIGludHxudWxsICRsZW5ndGggTGVuZ3RoIHRvIHJlYWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgc3RyaW5nIHN1YnNldAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHN1YnN0cigkc3RyaW5nLCAkZnJvbSwgJGxlbmd0aCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGZhbHNlID09PSAkZW5jb2RpbmcgPSBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZywgbnVsbCwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkc3RyaW5nLCAkZnJvbSwgJGxlbmd0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbWJfc3Vic3RyKCRzdHJpbmcsICRmcm9tLCAkbGVuZ3RoLCAkZW5jb2RpbmcpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0VGltZSgkc2VjcykKICAgIHsKICAgICAgICBzdGF0aWMgJHRpbWVGb3JtYXRzID0gWwogICAgICAgICAgICBbMCwgJzwgMSBzZWMnXSwKICAgICAgICAgICAgWzEsICcxIHNlYyddLAogICAgICAgICAgICBbMiwgJ3NlY3MnLCAxXSwKICAgICAgICAgICAgWzYwLCAnMSBtaW4nXSwKICAgICAgICAgICAgWzEyMCwgJ21pbnMnLCA2MF0sCiAgICAgICAgICAgIFszNjAwLCAnMSBociddLAogICAgICAgICAgICBbNzIwMCwgJ2hycycsIDM2MDBdLAogICAgICAgICAgICBbODY0MDAsICcxIGRheSddLAogICAgICAgICAgICBbMTcyODAwLCAnZGF5cycsIDg2NDAwXSwKICAgICAgICBdOwoKICAgICAgICBmb3JlYWNoICgkdGltZUZvcm1hdHMgYXMgJGluZGV4ID0+ICRmb3JtYXQpIHsKICAgICAgICAgICAgaWYgKCRzZWNzID49ICRmb3JtYXRbMF0pIHsKICAgICAgICAgICAgICAgIGlmICgoaXNzZXQoJHRpbWVGb3JtYXRzWyRpbmRleCArIDFdKSAmJiAkc2VjcyA8ICR0aW1lRm9ybWF0c1skaW5kZXggKyAxXVswXSkKICAgICAgICAgICAgICAgICAgICB8fCAkaW5kZXggPT0gXGNvdW50KCR0aW1lRm9ybWF0cykgLSAxCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoMiA9PSBcY291bnQoJGZvcm1hdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmb3JtYXRbMV07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmxvb3IoJHNlY3MgLyAkZm9ybWF0WzJdKS4nICcuJGZvcm1hdFsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdE1lbW9yeSgkbWVtb3J5KQogICAgewogICAgICAgIGlmICgkbWVtb3J5ID49IDEwMjQgKiAxMDI0ICogMTAyNCkgewogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignJS4xZiBHaUInLCAkbWVtb3J5IC8gMTAyNCAvIDEwMjQgLyAxMDI0KTsKICAgICAgICB9CgogICAgICAgIGlmICgkbWVtb3J5ID49IDEwMjQgKiAxMDI0KSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCclLjFmIE1pQicsICRtZW1vcnkgLyAxMDI0IC8gMTAyNCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG1lbW9yeSA+PSAxMDI0KSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCclZCBLaUInLCAkbWVtb3J5IC8gMTAyNCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3ByaW50ZignJWQgQicsICRtZW1vcnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3RybGVuV2l0aG91dERlY29yYXRpb24oT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIsICRzdHJpbmcpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OnN0cmxlbihzZWxmOjpyZW1vdmVEZWNvcmF0aW9uKCRmb3JtYXR0ZXIsICRzdHJpbmcpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJlbW92ZURlY29yYXRpb24oT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlICRmb3JtYXR0ZXIsICRzdHJpbmcpCiAgICB7CiAgICAgICAgJGlzRGVjb3JhdGVkID0gJGZvcm1hdHRlci0+aXNEZWNvcmF0ZWQoKTsKICAgICAgICAkZm9ybWF0dGVyLT5zZXREZWNvcmF0ZWQoZmFsc2UpOwogICAgICAgIC8vIHJlbW92ZSA8Li4uPiBmb3JtYXR0aW5nCiAgICAgICAgJHN0cmluZyA9ICRmb3JtYXR0ZXItPmZvcm1hdCgkc3RyaW5nKTsKICAgICAgICAvLyByZW1vdmUgYWxyZWFkeSBmb3JtYXR0ZWQgY2hhcmFjdGVycwogICAgICAgICRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoIi9cMDMzXFtbXm1dKm0vIiwgJycsICRzdHJpbmcpOwogICAgICAgICRmb3JtYXR0ZXItPnNldERlY29yYXRlZCgkaXNEZWNvcmF0ZWQpOwoKICAgICAgICByZXR1cm4gJHN0cmluZzsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBQcm92aWRlcyBoZWxwZXJzIHRvIGRpc3BsYXkgYSB0YWJsZS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3Ig0KHQsNGI0LAg0KHRgtCw0LzQtdC90LrQvtCy0LjRmyA8dW1waXJza3lAZ21haWwuY29tPgogKiBAYXV0aG9yIEFiZGVsbGF0aWYgQWl0IGJvdWRhZCA8YS5haXRib3VkYWRAZ21haWwuY29tPgogKiBAYXV0aG9yIE1heCBHcmlnb3JpYW4gPG1heGFrYXdpemFyZEBnbWFpbC5jb20+CiAqLwpjbGFzcyBUYWJsZQp7CiAgICAvKioKICAgICAqIFRhYmxlIGhlYWRlcnMuCiAgICAgKi8KICAgIHByaXZhdGUgJGhlYWRlcnMgPSBbXTsKCiAgICAvKioKICAgICAqIFRhYmxlIHJvd3MuCiAgICAgKi8KICAgIHByaXZhdGUgJHJvd3MgPSBbXTsKCiAgICAvKioKICAgICAqIENvbHVtbiB3aWR0aHMgY2FjaGUuCiAgICAgKi8KICAgIHByaXZhdGUgJGVmZmVjdGl2ZUNvbHVtbldpZHRocyA9IFtdOwoKICAgIC8qKgogICAgICogTnVtYmVyIG9mIGNvbHVtbnMgY2FjaGUuCiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJpdmF0ZSAkbnVtYmVyT2ZDb2x1bW5zOwoKICAgIC8qKgogICAgICogQHZhciBPdXRwdXRJbnRlcmZhY2UKICAgICAqLwogICAgcHJpdmF0ZSAkb3V0cHV0OwoKICAgIC8qKgogICAgICogQHZhciBUYWJsZVN0eWxlCiAgICAgKi8KICAgIHByaXZhdGUgJHN0eWxlOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRjb2x1bW5TdHlsZXMgPSBbXTsKCiAgICAvKioKICAgICAqIFVzZXIgc2V0IGNvbHVtbiB3aWR0aHMuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlICRjb2x1bW5XaWR0aHMgPSBbXTsKCiAgICBwcml2YXRlIHN0YXRpYyAkc3R5bGVzOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0ID0gJG91dHB1dDsKCiAgICAgICAgaWYgKCFzZWxmOjokc3R5bGVzKSB7CiAgICAgICAgICAgIHNlbGY6OiRzdHlsZXMgPSBzZWxmOjppbml0U3R5bGVzKCk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0U3R5bGUoJ2RlZmF1bHQnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBzdHlsZSBkZWZpbml0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICRuYW1lICBUaGUgc3R5bGUgbmFtZQogICAgICogQHBhcmFtIFRhYmxlU3R5bGUgJHN0eWxlIEEgVGFibGVTdHlsZSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldFN0eWxlRGVmaW5pdGlvbigkbmFtZSwgVGFibGVTdHlsZSAkc3R5bGUpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokc3R5bGVzKSB7CiAgICAgICAgICAgIHNlbGY6OiRzdHlsZXMgPSBzZWxmOjppbml0U3R5bGVzKCk7CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokc3R5bGVzWyRuYW1lXSA9ICRzdHlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgYSBzdHlsZSBkZWZpbml0aW9uIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgc3R5bGUgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gVGFibGVTdHlsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFN0eWxlRGVmaW5pdGlvbigkbmFtZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRzdHlsZXMpIHsKICAgICAgICAgICAgc2VsZjo6JHN0eWxlcyA9IHNlbGY6OmluaXRTdHlsZXMoKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldChzZWxmOjokc3R5bGVzWyRuYW1lXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRzdHlsZXNbJG5hbWVdOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdTdHlsZSAiJXMiIGlzIG5vdCBkZWZpbmVkLicsICRuYW1lKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRhYmxlIHN0eWxlLgogICAgICoKICAgICAqIEBwYXJhbSBUYWJsZVN0eWxlfHN0cmluZyAkbmFtZSBUaGUgc3R5bGUgbmFtZSBvciBhIFRhYmxlU3R5bGUgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHlsZSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+c3R5bGUgPSAkdGhpcy0+cmVzb2x2ZVN0eWxlKCRuYW1lKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY3VycmVudCB0YWJsZSBzdHlsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRhYmxlU3R5bGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0eWxlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0eWxlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0YWJsZSBjb2x1bW4gc3R5bGUuCiAgICAgKgogICAgICogQHBhcmFtIGludCAgICAgICAgICAgICAgICRjb2x1bW5JbmRleCBDb2x1bW4gaW5kZXgKICAgICAqIEBwYXJhbSBUYWJsZVN0eWxlfHN0cmluZyAkbmFtZSAgICAgICAgVGhlIHN0eWxlIG5hbWUgb3IgYSBUYWJsZVN0eWxlIGluc3RhbmNlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29sdW1uU3R5bGUoJGNvbHVtbkluZGV4LCAkbmFtZSkKICAgIHsKICAgICAgICAkY29sdW1uSW5kZXggPSAoaW50KSAkY29sdW1uSW5kZXg7CgogICAgICAgICR0aGlzLT5jb2x1bW5TdHlsZXNbJGNvbHVtbkluZGV4XSA9ICR0aGlzLT5yZXNvbHZlU3R5bGUoJG5hbWUpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHN0eWxlIGZvciBhIGNvbHVtbi4KICAgICAqCiAgICAgKiBJZiBzdHlsZSB3YXMgbm90IHNldCwgaXQgcmV0dXJucyB0aGUgZ2xvYmFsIHRhYmxlIHN0eWxlLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGNvbHVtbkluZGV4IENvbHVtbiBpbmRleAogICAgICoKICAgICAqIEByZXR1cm4gVGFibGVTdHlsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29sdW1uU3R5bGUoJGNvbHVtbkluZGV4KQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+Y29sdW1uU3R5bGVzWyRjb2x1bW5JbmRleF0pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29sdW1uU3R5bGVzWyRjb2x1bW5JbmRleF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFN0eWxlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIHdpZHRoIG9mIGEgY29sdW1uLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGNvbHVtbkluZGV4IENvbHVtbiBpbmRleAogICAgICogQHBhcmFtIGludCAkd2lkdGggICAgICAgTWluaW11bSBjb2x1bW4gd2lkdGggaW4gY2hhcmFjdGVycwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbHVtbldpZHRoKCRjb2x1bW5JbmRleCwgJHdpZHRoKQogICAgewogICAgICAgICR0aGlzLT5jb2x1bW5XaWR0aHNbKGludCkgJGNvbHVtbkluZGV4XSA9IChpbnQpICR3aWR0aDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWluaW11bSB3aWR0aCBvZiBhbGwgY29sdW1ucy4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb2x1bW5XaWR0aHMoYXJyYXkgJHdpZHRocykKICAgIHsKICAgICAgICAkdGhpcy0+Y29sdW1uV2lkdGhzID0gW107CiAgICAgICAgZm9yZWFjaCAoJHdpZHRocyBhcyAkaW5kZXggPT4gJHdpZHRoKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRDb2x1bW5XaWR0aCgkaW5kZXgsICR3aWR0aCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEhlYWRlcnMoYXJyYXkgJGhlYWRlcnMpCiAgICB7CiAgICAgICAgJGhlYWRlcnMgPSBhcnJheV92YWx1ZXMoJGhlYWRlcnMpOwogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcnMpICYmICFcaXNfYXJyYXkoJGhlYWRlcnNbMF0pKSB7CiAgICAgICAgICAgICRoZWFkZXJzID0gWyRoZWFkZXJzXTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5oZWFkZXJzID0gJGhlYWRlcnM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Um93cyhhcnJheSAkcm93cykKICAgIHsKICAgICAgICAkdGhpcy0+cm93cyA9IFtdOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZFJvd3MoJHJvd3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSb3dzKGFycmF5ICRyb3dzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRyb3dzIGFzICRyb3cpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZFJvdygkcm93KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUm93KCRyb3cpCiAgICB7CiAgICAgICAgaWYgKCRyb3cgaW5zdGFuY2VvZiBUYWJsZVNlcGFyYXRvcikgewogICAgICAgICAgICAkdGhpcy0+cm93c1tdID0gJHJvdzsKCiAgICAgICAgICAgIHJldHVybiAkdGhpczsKICAgICAgICB9CgogICAgICAgIGlmICghXGlzX2FycmF5KCRyb3cpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0Egcm93IG11c3QgYmUgYW4gYXJyYXkgb3IgYSBUYWJsZVNlcGFyYXRvciBpbnN0YW5jZS4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yb3dzW10gPSBhcnJheV92YWx1ZXMoJHJvdyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Um93KCRjb2x1bW4sIGFycmF5ICRyb3cpCiAgICB7CiAgICAgICAgJHRoaXMtPnJvd3NbJGNvbHVtbl0gPSAkcm93OwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXJzIHRhYmxlIHRvIG91dHB1dC4KICAgICAqCiAgICAgKiBFeGFtcGxlOgogICAgICoKICAgICAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAqICAgICB8IElTQk4gICAgICAgICAgfCBUaXRsZSAgICAgICAgICAgICAgICAgfCBBdXRob3IgICAgICAgICAgIHwKICAgICAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAqICAgICB8IDk5OTIxLTU4LTEwLTcgfCBEaXZpbmUgQ29tZWR5ICAgICAgICAgfCBEYW50ZSBBbGlnaGllcmkgIHwKICAgICAqICAgICB8IDk5NzEtNS0wMjEwLTAgfCBBIFRhbGUgb2YgVHdvIENpdGllcyAgfCBDaGFybGVzIERpY2tlbnMgIHwKICAgICAqICAgICB8IDk2MC00MjUtMDU5LTAgfCBUaGUgTG9yZCBvZiB0aGUgUmluZ3MgfCBKLiBSLiBSLiBUb2xraWVuIHwKICAgICAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcigpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhbGN1bGF0ZU51bWJlck9mQ29sdW1ucygpOwogICAgICAgICRyb3dzID0gJHRoaXMtPmJ1aWxkVGFibGVSb3dzKCR0aGlzLT5yb3dzKTsKICAgICAgICAkaGVhZGVycyA9ICR0aGlzLT5idWlsZFRhYmxlUm93cygkdGhpcy0+aGVhZGVycyk7CgogICAgICAgICR0aGlzLT5jYWxjdWxhdGVDb2x1bW5zV2lkdGgoYXJyYXlfbWVyZ2UoJGhlYWRlcnMsICRyb3dzKSk7CgogICAgICAgICR0aGlzLT5yZW5kZXJSb3dTZXBhcmF0b3IoKTsKICAgICAgICBpZiAoIWVtcHR5KCRoZWFkZXJzKSkgewogICAgICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyUm93KCRoZWFkZXIsICR0aGlzLT5zdHlsZS0+Z2V0Q2VsbEhlYWRlckZvcm1hdCgpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJSb3dTZXBhcmF0b3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkcm93cyBhcyAkcm93KSB7CiAgICAgICAgICAgIGlmICgkcm93IGluc3RhbmNlb2YgVGFibGVTZXBhcmF0b3IpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJSb3dTZXBhcmF0b3IoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJSb3coJHJvdywgJHRoaXMtPnN0eWxlLT5nZXRDZWxsUm93Rm9ybWF0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghZW1wdHkoJHJvd3MpKSB7CiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJSb3dTZXBhcmF0b3IoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jbGVhbnVwKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXJzIGhvcml6b250YWwgaGVhZGVyIHNlcGFyYXRvci4KICAgICAqCiAgICAgKiBFeGFtcGxlOgogICAgICoKICAgICAqICAgICArLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLSsKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZW5kZXJSb3dTZXBhcmF0b3IoKQogICAgewogICAgICAgIGlmICgwID09PSAkY291bnQgPSAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghJHRoaXMtPnN0eWxlLT5nZXRIb3Jpem9udGFsQm9yZGVyQ2hhcigpICYmICEkdGhpcy0+c3R5bGUtPmdldENyb3NzaW5nQ2hhcigpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRtYXJrdXAgPSAkdGhpcy0+c3R5bGUtPmdldENyb3NzaW5nQ2hhcigpOwogICAgICAgIGZvciAoJGNvbHVtbiA9IDA7ICRjb2x1bW4gPCAkY291bnQ7ICsrJGNvbHVtbikgewogICAgICAgICAgICAkbWFya3VwIC49IHN0cl9yZXBlYXQoJHRoaXMtPnN0eWxlLT5nZXRIb3Jpem9udGFsQm9yZGVyQ2hhcigpLCAkdGhpcy0+ZWZmZWN0aXZlQ29sdW1uV2lkdGhzWyRjb2x1bW5dKS4kdGhpcy0+c3R5bGUtPmdldENyb3NzaW5nQ2hhcigpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCR0aGlzLT5zdHlsZS0+Z2V0Qm9yZGVyRm9ybWF0KCksICRtYXJrdXApKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgdmVydGljYWwgY29sdW1uIHNlcGFyYXRvci4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiByZW5kZXJDb2x1bW5TZXBhcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiBzcHJpbnRmKCR0aGlzLT5zdHlsZS0+Z2V0Qm9yZGVyRm9ybWF0KCksICR0aGlzLT5zdHlsZS0+Z2V0VmVydGljYWxCb3JkZXJDaGFyKCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVycyB0YWJsZSByb3cuCiAgICAgKgogICAgICogRXhhbXBsZToKICAgICAqCiAgICAgKiAgICAgfCA5OTcxLTUtMDIxMC0wIHwgQSBUYWxlIG9mIFR3byBDaXRpZXMgIHwgQ2hhcmxlcyBEaWNrZW5zICB8CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2VsbEZvcm1hdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbmRlclJvdyhhcnJheSAkcm93LCAkY2VsbEZvcm1hdCkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJHJvdykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHJvd0NvbnRlbnQgPSAkdGhpcy0+cmVuZGVyQ29sdW1uU2VwYXJhdG9yKCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldFJvd0NvbHVtbnMoJHJvdykgYXMgJGNvbHVtbikgewogICAgICAgICAgICAkcm93Q29udGVudCAuPSAkdGhpcy0+cmVuZGVyQ2VsbCgkcm93LCAkY29sdW1uLCAkY2VsbEZvcm1hdCk7CiAgICAgICAgICAgICRyb3dDb250ZW50IC49ICR0aGlzLT5yZW5kZXJDb2x1bW5TZXBhcmF0b3IoKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGVsbigkcm93Q29udGVudCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXJzIHRhYmxlIGNlbGwgd2l0aCBwYWRkaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgICAgJGNvbHVtbgogICAgICogQHBhcmFtIHN0cmluZyAkY2VsbEZvcm1hdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbmRlckNlbGwoYXJyYXkgJHJvdywgJGNvbHVtbiwgJGNlbGxGb3JtYXQpCiAgICB7CiAgICAgICAgJGNlbGwgPSBpc3NldCgkcm93WyRjb2x1bW5dKSA/ICRyb3dbJGNvbHVtbl0gOiAnJzsKICAgICAgICAkd2lkdGggPSAkdGhpcy0+ZWZmZWN0aXZlQ29sdW1uV2lkdGhzWyRjb2x1bW5dOwogICAgICAgIGlmICgkY2VsbCBpbnN0YW5jZW9mIFRhYmxlQ2VsbCAmJiAkY2VsbC0+Z2V0Q29sc3BhbigpID4gMSkgewogICAgICAgICAgICAvLyBhZGQgdGhlIHdpZHRoIG9mIHRoZSBmb2xsb3dpbmcgY29sdW1ucyhudW1iZXJzIG9mIGNvbHNwYW4pLgogICAgICAgICAgICBmb3JlYWNoIChyYW5nZSgkY29sdW1uICsgMSwgJGNvbHVtbiArICRjZWxsLT5nZXRDb2xzcGFuKCkgLSAxKSBhcyAkbmV4dENvbHVtbikgewogICAgICAgICAgICAgICAgJHdpZHRoICs9ICR0aGlzLT5nZXRDb2x1bW5TZXBhcmF0b3JXaWR0aCgpICsgJHRoaXMtPmVmZmVjdGl2ZUNvbHVtbldpZHRoc1skbmV4dENvbHVtbl07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHN0cl9wYWQgd29uJ3Qgd29yayBwcm9wZXJseSB3aXRoIG11bHRpLWJ5dGUgc3RyaW5ncywgd2UgbmVlZCB0byBmaXggdGhlIHBhZGRpbmcKICAgICAgICBpZiAoZmFsc2UgIT09ICRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZygkY2VsbCwgbnVsbCwgdHJ1ZSkpIHsKICAgICAgICAgICAgJHdpZHRoICs9IFxzdHJsZW4oJGNlbGwpIC0gbWJfc3Ryd2lkdGgoJGNlbGwsICRlbmNvZGluZyk7CiAgICAgICAgfQoKICAgICAgICAkc3R5bGUgPSAkdGhpcy0+Z2V0Q29sdW1uU3R5bGUoJGNvbHVtbik7CgogICAgICAgIGlmICgkY2VsbCBpbnN0YW5jZW9mIFRhYmxlU2VwYXJhdG9yKSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCRzdHlsZS0+Z2V0Qm9yZGVyRm9ybWF0KCksIHN0cl9yZXBlYXQoJHN0eWxlLT5nZXRIb3Jpem9udGFsQm9yZGVyQ2hhcigpLCAkd2lkdGgpKTsKICAgICAgICB9CgogICAgICAgICR3aWR0aCArPSBIZWxwZXI6OnN0cmxlbigkY2VsbCkgLSBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCR0aGlzLT5vdXRwdXQtPmdldEZvcm1hdHRlcigpLCAkY2VsbCk7CiAgICAgICAgJGNvbnRlbnQgPSBzcHJpbnRmKCRzdHlsZS0+Z2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoKSwgJGNlbGwpOwoKICAgICAgICByZXR1cm4gc3ByaW50ZigkY2VsbEZvcm1hdCwgc3RyX3BhZCgkY29udGVudCwgJHdpZHRoLCAkc3R5bGUtPmdldFBhZGRpbmdDaGFyKCksICRzdHlsZS0+Z2V0UGFkVHlwZSgpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxjdWxhdGUgbnVtYmVyIG9mIGNvbHVtbnMgZm9yIHRoaXMgdGFibGUuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2FsY3VsYXRlTnVtYmVyT2ZDb2x1bW5zKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPm51bWJlck9mQ29sdW1ucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkY29sdW1ucyA9IFswXTsKICAgICAgICBmb3JlYWNoIChhcnJheV9tZXJnZSgkdGhpcy0+aGVhZGVycywgJHRoaXMtPnJvd3MpIGFzICRyb3cpIHsKICAgICAgICAgICAgaWYgKCRyb3cgaW5zdGFuY2VvZiBUYWJsZVNlcGFyYXRvcikgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb2x1bW5zW10gPSAkdGhpcy0+Z2V0TnVtYmVyT2ZDb2x1bW5zKCRyb3cpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm51bWJlck9mQ29sdW1ucyA9IG1heCgkY29sdW1ucyk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZFRhYmxlUm93cygkcm93cykKICAgIHsKICAgICAgICAkdW5tZXJnZWRSb3dzID0gW107CiAgICAgICAgZm9yICgkcm93S2V5ID0gMDsgJHJvd0tleSA8IFxjb3VudCgkcm93cyk7ICsrJHJvd0tleSkgewogICAgICAgICAgICAkcm93cyA9ICR0aGlzLT5maWxsTmV4dFJvd3MoJHJvd3MsICRyb3dLZXkpOwoKICAgICAgICAgICAgLy8gUmVtb3ZlIGFueSBuZXcgbGluZSBicmVha3MgYW5kIHJlcGxhY2UgaXQgd2l0aCBhIG5ldyBsaW5lCiAgICAgICAgICAgIGZvcmVhY2ggKCRyb3dzWyRyb3dLZXldIGFzICRjb2x1bW4gPT4gJGNlbGwpIHsKICAgICAgICAgICAgICAgIGlmICghc3Ryc3RyKCRjZWxsLCAiXG4iKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGxpbmVzID0gZXhwbG9kZSgiXG4iLCBzdHJfcmVwbGFjZSgiXG4iLCAiPGZnPWRlZmF1bHQ7Ymc9ZGVmYXVsdD5cbjwvPiIsICRjZWxsKSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGxpbmVLZXkgPT4gJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSBuZXcgVGFibGVDZWxsKCRsaW5lLCBbJ2NvbHNwYW4nID0+ICRjZWxsLT5nZXRDb2xzcGFuKCldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09ICRsaW5lS2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyb3dzWyRyb3dLZXldWyRjb2x1bW5dID0gJGxpbmU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHVubWVyZ2VkUm93c1skcm93S2V5XVskbGluZUtleV1bJGNvbHVtbl0gPSAkbGluZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0YWJsZVJvd3MgPSBbXTsKICAgICAgICBmb3JlYWNoICgkcm93cyBhcyAkcm93S2V5ID0+ICRyb3cpIHsKICAgICAgICAgICAgJHRhYmxlUm93c1tdID0gJHRoaXMtPmZpbGxDZWxscygkcm93KTsKICAgICAgICAgICAgaWYgKGlzc2V0KCR1bm1lcmdlZFJvd3NbJHJvd0tleV0pKSB7CiAgICAgICAgICAgICAgICAkdGFibGVSb3dzID0gYXJyYXlfbWVyZ2UoJHRhYmxlUm93cywgJHVubWVyZ2VkUm93c1skcm93S2V5XSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGFibGVSb3dzOwogICAgfQoKICAgIC8qKgogICAgICogZmlsbCByb3dzIHRoYXQgY29udGFpbnMgcm93c3BhbiA+IDEuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkbGluZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZpbGxOZXh0Um93cyhhcnJheSAkcm93cywgJGxpbmUpCiAgICB7CiAgICAgICAgJHVubWVyZ2VkUm93cyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRyb3dzWyRsaW5lXSBhcyAkY29sdW1uID0+ICRjZWxsKSB7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAkY2VsbCAmJiAhJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwgJiYgIWlzX3NjYWxhcigkY2VsbCkgJiYgIShcaXNfb2JqZWN0KCRjZWxsKSAmJiBtZXRob2RfZXhpc3RzKCRjZWxsLCAnX190b1N0cmluZycpKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdBIGNlbGwgbXVzdCBiZSBhIFRhYmxlQ2VsbCwgYSBzY2FsYXIgb3IgYW4gb2JqZWN0IGltcGxlbWVudGluZyAiX190b1N0cmluZygpIiwgIiVzIiBnaXZlbi4nLCBcZ2V0dHlwZSgkY2VsbCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwgJiYgJGNlbGwtPmdldFJvd3NwYW4oKSA+IDEpIHsKICAgICAgICAgICAgICAgICRuYkxpbmVzID0gJGNlbGwtPmdldFJvd3NwYW4oKSAtIDE7CiAgICAgICAgICAgICAgICAkbGluZXMgPSBbJGNlbGxdOwogICAgICAgICAgICAgICAgaWYgKHN0cnN0cigkY2VsbCwgIlxuIikpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsIHN0cl9yZXBsYWNlKCJcbiIsICI8Zmc9ZGVmYXVsdDtiZz1kZWZhdWx0PlxuPC8+IiwgJGNlbGwpKTsKICAgICAgICAgICAgICAgICAgICAkbmJMaW5lcyA9IFxjb3VudCgkbGluZXMpID4gJG5iTGluZXMgPyBzdWJzdHJfY291bnQoJGNlbGwsICJcbiIpIDogJG5iTGluZXM7CgogICAgICAgICAgICAgICAgICAgICRyb3dzWyRsaW5lXVskY29sdW1uXSA9IG5ldyBUYWJsZUNlbGwoJGxpbmVzWzBdLCBbJ2NvbHNwYW4nID0+ICRjZWxsLT5nZXRDb2xzcGFuKCldKTsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkbGluZXNbMF0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIHR3byBkaW1lbnNpb25hbCBhcnJheSAocm93c3BhbiB4IGNvbHNwYW4pCiAgICAgICAgICAgICAgICAkdW5tZXJnZWRSb3dzID0gYXJyYXlfcmVwbGFjZV9yZWN1cnNpdmUoYXJyYXlfZmlsbCgkbGluZSArIDEsICRuYkxpbmVzLCBbXSksICR1bm1lcmdlZFJvd3MpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHVubWVyZ2VkUm93cyBhcyAkdW5tZXJnZWRSb3dLZXkgPT4gJHVubWVyZ2VkUm93KSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gaXNzZXQoJGxpbmVzWyR1bm1lcmdlZFJvd0tleSAtICRsaW5lXSkgPyAkbGluZXNbJHVubWVyZ2VkUm93S2V5IC0gJGxpbmVdIDogJyc7CiAgICAgICAgICAgICAgICAgICAgJHVubWVyZ2VkUm93c1skdW5tZXJnZWRSb3dLZXldWyRjb2x1bW5dID0gbmV3IFRhYmxlQ2VsbCgkdmFsdWUsIFsnY29sc3BhbicgPT4gJGNlbGwtPmdldENvbHNwYW4oKV0pOwogICAgICAgICAgICAgICAgICAgIGlmICgkbmJMaW5lcyA9PT0gJHVubWVyZ2VkUm93S2V5IC0gJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdW5tZXJnZWRSb3dzIGFzICR1bm1lcmdlZFJvd0tleSA9PiAkdW5tZXJnZWRSb3cpIHsKICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBrbm93IGlmICR1bm1lcmdlZFJvdyB3aWxsIGJlIG1lcmdlZCBvciBpbnNlcnRlZCBpbnRvICRyb3dzCiAgICAgICAgICAgIGlmIChpc3NldCgkcm93c1skdW5tZXJnZWRSb3dLZXldKSAmJiBcaXNfYXJyYXkoJHJvd3NbJHVubWVyZ2VkUm93S2V5XSkgJiYgKCR0aGlzLT5nZXROdW1iZXJPZkNvbHVtbnMoJHJvd3NbJHVubWVyZ2VkUm93S2V5XSkgKyAkdGhpcy0+Z2V0TnVtYmVyT2ZDb2x1bW5zKCR1bm1lcmdlZFJvd3NbJHVubWVyZ2VkUm93S2V5XSkgPD0gJHRoaXMtPm51bWJlck9mQ29sdW1ucykpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR1bm1lcmdlZFJvdyBhcyAkY2VsbEtleSA9PiAkY2VsbCkgewogICAgICAgICAgICAgICAgICAgIC8vIGluc2VydCBjZWxsIGludG8gcm93IGF0IGNlbGxLZXkgcG9zaXRpb24KICAgICAgICAgICAgICAgICAgICBhcnJheV9zcGxpY2UoJHJvd3NbJHVubWVyZ2VkUm93S2V5XSwgJGNlbGxLZXksIDAsIFskY2VsbF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJvdyA9ICR0aGlzLT5jb3B5Um93KCRyb3dzLCAkdW5tZXJnZWRSb3dLZXkgLSAxKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR1bm1lcmdlZFJvdyBhcyAkY29sdW1uID0+ICRjZWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkY2VsbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJvd1skY29sdW1uXSA9ICR1bm1lcmdlZFJvd1skY29sdW1uXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhcnJheV9zcGxpY2UoJHJvd3MsICR1bm1lcmdlZFJvd0tleSwgMCwgWyRyb3ddKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyb3dzOwogICAgfQoKICAgIC8qKgogICAgICogZmlsbCBjZWxscyBmb3IgYSByb3cgdGhhdCBjb250YWlucyBjb2xzcGFuID4gMS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmlsbENlbGxzKCRyb3cpCiAgICB7CiAgICAgICAgJG5ld1JvdyA9IFtdOwogICAgICAgIGZvcmVhY2ggKCRyb3cgYXMgJGNvbHVtbiA9PiAkY2VsbCkgewogICAgICAgICAgICAkbmV3Um93W10gPSAkY2VsbDsKICAgICAgICAgICAgaWYgKCRjZWxsIGluc3RhbmNlb2YgVGFibGVDZWxsICYmICRjZWxsLT5nZXRDb2xzcGFuKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoIChyYW5nZSgkY29sdW1uICsgMSwgJGNvbHVtbiArICRjZWxsLT5nZXRDb2xzcGFuKCkgLSAxKSBhcyAkcG9zaXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAvLyBpbnNlcnQgZW1wdHkgdmFsdWUgYXQgY29sdW1uIHBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgJG5ld1Jvd1tdID0gJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbmV3Um93ID86ICRyb3c7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNvcHlSb3coYXJyYXkgJHJvd3MsICRsaW5lKQogICAgewogICAgICAgICRyb3cgPSAkcm93c1skbGluZV07CiAgICAgICAgZm9yZWFjaCAoJHJvdyBhcyAkY2VsbEtleSA9PiAkY2VsbFZhbHVlKSB7CiAgICAgICAgICAgICRyb3dbJGNlbGxLZXldID0gJyc7CiAgICAgICAgICAgIGlmICgkY2VsbFZhbHVlIGluc3RhbmNlb2YgVGFibGVDZWxsKSB7CiAgICAgICAgICAgICAgICAkcm93WyRjZWxsS2V5XSA9IG5ldyBUYWJsZUNlbGwoJycsIFsnY29sc3BhbicgPT4gJGNlbGxWYWx1ZS0+Z2V0Q29sc3BhbigpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcm93OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBudW1iZXIgb2YgY29sdW1ucyBieSByb3cuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXROdW1iZXJPZkNvbHVtbnMoYXJyYXkgJHJvdykKICAgIHsKICAgICAgICAkY29sdW1ucyA9IFxjb3VudCgkcm93KTsKICAgICAgICBmb3JlYWNoICgkcm93IGFzICRjb2x1bW4pIHsKICAgICAgICAgICAgJGNvbHVtbnMgKz0gJGNvbHVtbiBpbnN0YW5jZW9mIFRhYmxlQ2VsbCA/ICgkY29sdW1uLT5nZXRDb2xzcGFuKCkgLSAxKSA6IDA7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbHVtbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGxpc3Qgb2YgY29sdW1ucyBmb3IgdGhlIGdpdmVuIHJvdy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Um93Q29sdW1ucyhhcnJheSAkcm93KQogICAgewogICAgICAgICRjb2x1bW5zID0gcmFuZ2UoMCwgJHRoaXMtPm51bWJlck9mQ29sdW1ucyAtIDEpOwogICAgICAgIGZvcmVhY2ggKCRyb3cgYXMgJGNlbGxLZXkgPT4gJGNlbGwpIHsKICAgICAgICAgICAgaWYgKCRjZWxsIGluc3RhbmNlb2YgVGFibGVDZWxsICYmICRjZWxsLT5nZXRDb2xzcGFuKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAvLyBleGNsdWRlIGdyb3VwZWQgY29sdW1ucy4KICAgICAgICAgICAgICAgICRjb2x1bW5zID0gYXJyYXlfZGlmZigkY29sdW1ucywgcmFuZ2UoJGNlbGxLZXkgKyAxLCAkY2VsbEtleSArICRjZWxsLT5nZXRDb2xzcGFuKCkgLSAxKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29sdW1uczsKICAgIH0KCiAgICAvKioKICAgICAqIENhbGN1bGF0ZXMgY29sdW1ucyB3aWR0aHMuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2FsY3VsYXRlQ29sdW1uc1dpZHRoKGFycmF5ICRyb3dzKQogICAgewogICAgICAgIGZvciAoJGNvbHVtbiA9IDA7ICRjb2x1bW4gPCAkdGhpcy0+bnVtYmVyT2ZDb2x1bW5zOyArKyRjb2x1bW4pIHsKICAgICAgICAgICAgJGxlbmd0aHMgPSBbXTsKICAgICAgICAgICAgZm9yZWFjaCAoJHJvd3MgYXMgJHJvdykgewogICAgICAgICAgICAgICAgaWYgKCRyb3cgaW5zdGFuY2VvZiBUYWJsZVNlcGFyYXRvcikgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRyb3cgYXMgJGkgPT4gJGNlbGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNlbGwgaW5zdGFuY2VvZiBUYWJsZUNlbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHRDb250ZW50ID0gSGVscGVyOjpyZW1vdmVEZWNvcmF0aW9uKCR0aGlzLT5vdXRwdXQtPmdldEZvcm1hdHRlcigpLCAkY2VsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXh0TGVuZ3RoID0gSGVscGVyOjpzdHJsZW4oJHRleHRDb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0ZXh0TGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnRDb2x1bW5zID0gc3RyX3NwbGl0KCR0ZXh0Q29udGVudCwgY2VpbCgkdGV4dExlbmd0aCAvICRjZWxsLT5nZXRDb2xzcGFuKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjb250ZW50Q29sdW1ucyBhcyAkcG9zaXRpb24gPT4gJGNvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcm93WyRpICsgJHBvc2l0aW9uXSA9ICRjb250ZW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRsZW5ndGhzW10gPSAkdGhpcy0+Z2V0Q2VsbFdpZHRoKCRyb3csICRjb2x1bW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+ZWZmZWN0aXZlQ29sdW1uV2lkdGhzWyRjb2x1bW5dID0gbWF4KCRsZW5ndGhzKSArIEhlbHBlcjo6c3RybGVuKCR0aGlzLT5zdHlsZS0+Z2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoKSkgLSAyOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgY29sdW1uIHdpZHRoLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0Q29sdW1uU2VwYXJhdG9yV2lkdGgoKQogICAgewogICAgICAgIHJldHVybiBIZWxwZXI6OnN0cmxlbihzcHJpbnRmKCR0aGlzLT5zdHlsZS0+Z2V0Qm9yZGVyRm9ybWF0KCksICR0aGlzLT5zdHlsZS0+Z2V0VmVydGljYWxCb3JkZXJDaGFyKCkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgY2VsbCB3aWR0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRjb2x1bW4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldENlbGxXaWR0aChhcnJheSAkcm93LCAkY29sdW1uKQogICAgewogICAgICAgICRjZWxsV2lkdGggPSAwOwoKICAgICAgICBpZiAoaXNzZXQoJHJvd1skY29sdW1uXSkpIHsKICAgICAgICAgICAgJGNlbGwgPSAkcm93WyRjb2x1bW5dOwogICAgICAgICAgICAkY2VsbFdpZHRoID0gSGVscGVyOjpzdHJsZW5XaXRob3V0RGVjb3JhdGlvbigkdGhpcy0+b3V0cHV0LT5nZXRGb3JtYXR0ZXIoKSwgJGNlbGwpOwogICAgICAgIH0KCiAgICAgICAgJGNvbHVtbldpZHRoID0gaXNzZXQoJHRoaXMtPmNvbHVtbldpZHRoc1skY29sdW1uXSkgPyAkdGhpcy0+Y29sdW1uV2lkdGhzWyRjb2x1bW5dIDogMDsKCiAgICAgICAgcmV0dXJuIG1heCgkY2VsbFdpZHRoLCAkY29sdW1uV2lkdGgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlcmluZyB0byBjbGVhbnVwIGNhY2hlIGRhdGEuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2xlYW51cCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmVmZmVjdGl2ZUNvbHVtbldpZHRocyA9IFtdOwogICAgICAgICR0aGlzLT5udW1iZXJPZkNvbHVtbnMgPSBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXRTdHlsZXMoKQogICAgewogICAgICAgICRib3JkZXJsZXNzID0gbmV3IFRhYmxlU3R5bGUoKTsKICAgICAgICAkYm9yZGVybGVzcwogICAgICAgICAgICAtPnNldEhvcml6b250YWxCb3JkZXJDaGFyKCc9JykKICAgICAgICAgICAgLT5zZXRWZXJ0aWNhbEJvcmRlckNoYXIoJyAnKQogICAgICAgICAgICAtPnNldENyb3NzaW5nQ2hhcignICcpCiAgICAgICAgOwoKICAgICAgICAkY29tcGFjdCA9IG5ldyBUYWJsZVN0eWxlKCk7CiAgICAgICAgJGNvbXBhY3QKICAgICAgICAgICAgLT5zZXRIb3Jpem9udGFsQm9yZGVyQ2hhcignJykKICAgICAgICAgICAgLT5zZXRWZXJ0aWNhbEJvcmRlckNoYXIoJyAnKQogICAgICAgICAgICAtPnNldENyb3NzaW5nQ2hhcignJykKICAgICAgICAgICAgLT5zZXRDZWxsUm93Q29udGVudEZvcm1hdCgnJXMnKQogICAgICAgIDsKCiAgICAgICAgJHN0eWxlR3VpZGUgPSBuZXcgVGFibGVTdHlsZSgpOwogICAgICAgICRzdHlsZUd1aWRlCiAgICAgICAgICAgIC0+c2V0SG9yaXpvbnRhbEJvcmRlckNoYXIoJy0nKQogICAgICAgICAgICAtPnNldFZlcnRpY2FsQm9yZGVyQ2hhcignICcpCiAgICAgICAgICAgIC0+c2V0Q3Jvc3NpbmdDaGFyKCcgJykKICAgICAgICAgICAgLT5zZXRDZWxsSGVhZGVyRm9ybWF0KCclcycpCiAgICAgICAgOwoKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnZGVmYXVsdCcgPT4gbmV3IFRhYmxlU3R5bGUoKSwKICAgICAgICAgICAgJ2JvcmRlcmxlc3MnID0+ICRib3JkZXJsZXNzLAogICAgICAgICAgICAnY29tcGFjdCcgPT4gJGNvbXBhY3QsCiAgICAgICAgICAgICdzeW1mb255LXN0eWxlLWd1aWRlJyA9PiAkc3R5bGVHdWlkZSwKICAgICAgICBdOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVzb2x2ZVN0eWxlKCRuYW1lKQogICAgewogICAgICAgIGlmICgkbmFtZSBpbnN0YW5jZW9mIFRhYmxlU3R5bGUpIHsKICAgICAgICAgICAgcmV0dXJuICRuYW1lOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzc2V0KHNlbGY6OiRzdHlsZXNbJG5hbWVdKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHN0eWxlc1skbmFtZV07CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1N0eWxlICIlcyIgaXMgbm90IGRlZmluZWQuJywgJG5hbWUpKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBd2FyZUludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CgovKioKICogQW4gaW1wbGVtZW50YXRpb24gb2YgSW5wdXRBd2FyZUludGVyZmFjZSBmb3IgSGVscGVycy4KICoKICogQGF1dGhvciBXb3V0ZXIgSiA8d2FsZGlvLndlYmRlc2lnbkBnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBJbnB1dEF3YXJlSGVscGVyIGV4dGVuZHMgSGVscGVyIGltcGxlbWVudHMgSW5wdXRBd2FyZUludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGlucHV0OwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5wdXQoSW5wdXRJbnRlcmZhY2UgJGlucHV0KQogICAgewogICAgICAgICR0aGlzLT5pbnB1dCA9ICRpbnB1dDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxEZXNjcmlwdG9ySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yXEpzb25EZXNjcmlwdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxEZXNjcmlwdG9yXE1hcmtkb3duRGVzY3JpcHRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxUZXh0RGVzY3JpcHRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRGVzY3JpcHRvclxYbWxEZXNjcmlwdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIFRoaXMgY2xhc3MgYWRkcyBoZWxwZXIgbWV0aG9kIHRvIGRlc2NyaWJlIG9iamVjdHMgaW4gdmFyaW91cyBmb3JtYXRzLgogKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqLwpjbGFzcyBEZXNjcmlwdG9ySGVscGVyIGV4dGVuZHMgSGVscGVyCnsKICAgIC8qKgogICAgICogQHZhciBEZXNjcmlwdG9ySW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkZGVzY3JpcHRvcnMgPSBbXTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+cmVnaXN0ZXIoJ3R4dCcsIG5ldyBUZXh0RGVzY3JpcHRvcigpKQogICAgICAgICAgICAtPnJlZ2lzdGVyKCd4bWwnLCBuZXcgWG1sRGVzY3JpcHRvcigpKQogICAgICAgICAgICAtPnJlZ2lzdGVyKCdqc29uJywgbmV3IEpzb25EZXNjcmlwdG9yKCkpCiAgICAgICAgICAgIC0+cmVnaXN0ZXIoJ21kJywgbmV3IE1hcmtkb3duRGVzY3JpcHRvcigpKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIERlc2NyaWJlcyBhbiBvYmplY3QgaWYgc3VwcG9ydGVkLgogICAgICoKICAgICAqIEF2YWlsYWJsZSBvcHRpb25zIGFyZToKICAgICAqICogZm9ybWF0OiBzdHJpbmcsIHRoZSBvdXRwdXQgZm9ybWF0IG5hbWUKICAgICAqICogcmF3X3RleHQ6IGJvb2xlYW4sIHNldHMgb3V0cHV0IHR5cGUgYXMgcmF3CiAgICAgKgogICAgICogQHBhcmFtIG9iamVjdCAkb2JqZWN0CiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiB0aGUgZ2l2ZW4gZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlc2NyaWJlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkb2JqZWN0LCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zID0gYXJyYXlfbWVyZ2UoWwogICAgICAgICAgICAncmF3X3RleHQnID0+IGZhbHNlLAogICAgICAgICAgICAnZm9ybWF0JyA9PiAndHh0JywKICAgICAgICBdLCAkb3B0aW9ucyk7CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmRlc2NyaXB0b3JzWyRvcHRpb25zWydmb3JtYXQnXV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVW5zdXBwb3J0ZWQgZm9ybWF0ICIlcyIuJywgJG9wdGlvbnNbJ2Zvcm1hdCddKSk7CiAgICAgICAgfQoKICAgICAgICAkZGVzY3JpcHRvciA9ICR0aGlzLT5kZXNjcmlwdG9yc1skb3B0aW9uc1snZm9ybWF0J11dOwogICAgICAgICRkZXNjcmlwdG9yLT5kZXNjcmliZSgkb3V0cHV0LCAkb2JqZWN0LCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBkZXNjcmlwdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCRmb3JtYXQsIERlc2NyaXB0b3JJbnRlcmZhY2UgJGRlc2NyaXB0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlc2NyaXB0b3JzWyRmb3JtYXRdID0gJGRlc2NyaXB0b3I7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAnZGVzY3JpcHRvcic7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCi8qKgogKiBIZWxwcyBvdXRwdXR0aW5nIGRlYnVnIGluZm9ybWF0aW9uIHdoZW4gcnVubmluZyBhbiBleHRlcm5hbCBwcm9ncmFtIGZyb20gYSBjb21tYW5kLgogKgogKiBBbiBleHRlcm5hbCBwcm9ncmFtIGNhbiBiZSBhIFByb2Nlc3MsIGFuIEhUVFAgcmVxdWVzdCwgb3IgYW55dGhpbmcgZWxzZS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBEZWJ1Z0Zvcm1hdHRlckhlbHBlciBleHRlbmRzIEhlbHBlcgp7CiAgICBwcml2YXRlICRjb2xvcnMgPSBbJ2JsYWNrJywgJ3JlZCcsICdncmVlbicsICd5ZWxsb3cnLCAnYmx1ZScsICdtYWdlbnRhJywgJ2N5YW4nLCAnd2hpdGUnLCAnZGVmYXVsdCddOwogICAgcHJpdmF0ZSAkc3RhcnRlZCA9IFtdOwogICAgcHJpdmF0ZSAkY291bnQgPSAtMTsKCiAgICAvKioKICAgICAqIFN0YXJ0cyBhIGRlYnVnIGZvcm1hdHRpbmcgc2Vzc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZCAgICAgIFRoZSBpZCBvZiB0aGUgZm9ybWF0dGluZyBzZXNzaW9uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByZWZpeCAgVGhlIHByZWZpeCB0byB1c2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RhcnQoJGlkLCAkbWVzc2FnZSwgJHByZWZpeCA9ICdSVU4nKQogICAgewogICAgICAgICR0aGlzLT5zdGFydGVkWyRpZF0gPSBbJ2JvcmRlcicgPT4gKyskdGhpcy0+Y291bnQgJSBcY291bnQoJHRoaXMtPmNvbG9ycyldOwoKICAgICAgICByZXR1cm4gc3ByaW50ZigiJXM8Ymc9Ymx1ZTtmZz13aGl0ZT4gJXMgPC8+IDxmZz1ibHVlPiVzPC8+XG4iLCAkdGhpcy0+Z2V0Qm9yZGVyKCRpZCksICRwcmVmaXgsICRtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgcHJvZ3Jlc3MgdG8gYSBmb3JtYXR0aW5nIHNlc3Npb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgICAgICAgVGhlIGlkIG9mIHRoZSBmb3JtYXR0aW5nIHNlc3Npb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJGJ1ZmZlciAgICAgIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKICAgICAqIEBwYXJhbSBib29sICAgJGVycm9yICAgICAgIFdoZXRoZXIgdG8gY29uc2lkZXIgdGhlIGJ1ZmZlciBhcyBlcnJvcgogICAgICogQHBhcmFtIHN0cmluZyAkcHJlZml4ICAgICAgVGhlIHByZWZpeCBmb3Igb3V0cHV0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRlcnJvclByZWZpeCBUaGUgcHJlZml4IGZvciBlcnJvciBvdXRwdXQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3MoJGlkLCAkYnVmZmVyLCAkZXJyb3IgPSBmYWxzZSwgJHByZWZpeCA9ICdPVVQnLCAkZXJyb3JQcmVmaXggPSAnRVJSJykKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICcnOwoKICAgICAgICBpZiAoJGVycm9yKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+c3RhcnRlZFskaWRdWydvdXQnXSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcbiI7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+c3RhcnRlZFskaWRdWydvdXQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+c3RhcnRlZFskaWRdWydlcnInXSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49IHNwcmludGYoJyVzPGJnPXJlZDtmZz13aGl0ZT4gJXMgPC8+ICcsICR0aGlzLT5nZXRCb3JkZXIoJGlkKSwgJGVycm9yUHJlZml4KTsKICAgICAgICAgICAgICAgICR0aGlzLT5zdGFydGVkWyRpZF1bJ2VyciddID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG1lc3NhZ2UgLj0gc3RyX3JlcGxhY2UoIlxuIiwgc3ByaW50ZigiXG4lczxiZz1yZWQ7Zmc9d2hpdGU+ICVzIDwvPiAiLCAkdGhpcy0+Z2V0Qm9yZGVyKCRpZCksICRlcnJvclByZWZpeCksICRidWZmZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+c3RhcnRlZFskaWRdWydlcnInXSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcbiI7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+c3RhcnRlZFskaWRdWydlcnInXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+c3RhcnRlZFskaWRdWydvdXQnXSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49IHNwcmludGYoJyVzPGJnPWdyZWVuO2ZnPXdoaXRlPiAlcyA8Lz4gJywgJHRoaXMtPmdldEJvcmRlcigkaWQpLCAkcHJlZml4KTsKICAgICAgICAgICAgICAgICR0aGlzLT5zdGFydGVkWyRpZF1bJ291dCddID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG1lc3NhZ2UgLj0gc3RyX3JlcGxhY2UoIlxuIiwgc3ByaW50ZigiXG4lczxiZz1ncmVlbjtmZz13aGl0ZT4gJXMgPC8+ICIsICR0aGlzLT5nZXRCb3JkZXIoJGlkKSwgJHByZWZpeCksICRidWZmZXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgfQoKICAgIC8qKgogICAgICogU3RvcHMgYSBmb3JtYXR0aW5nIHNlc3Npb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgICAgICAgICBUaGUgaWQgb2YgdGhlIGZvcm1hdHRpbmcgc2Vzc2lvbgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSAgICBUaGUgbWVzc2FnZSB0byBkaXNwbGF5CiAgICAgKiBAcGFyYW0gYm9vbCAgICRzdWNjZXNzZnVsIFdoZXRoZXIgdG8gY29uc2lkZXIgdGhlIHJlc3VsdCBhcyBzdWNjZXNzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcmVmaXggICAgIFRoZSBwcmVmaXggZm9yIHRoZSBlbmQgb3V0cHV0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0b3AoJGlkLCAkbWVzc2FnZSwgJHN1Y2Nlc3NmdWwsICRwcmVmaXggPSAnUkVTJykKICAgIHsKICAgICAgICAkdHJhaWxpbmdFT0wgPSBpc3NldCgkdGhpcy0+c3RhcnRlZFskaWRdWydvdXQnXSkgfHwgaXNzZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnZXJyJ10pID8gIlxuIiA6ICcnOwoKICAgICAgICBpZiAoJHN1Y2Nlc3NmdWwpIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIiVzJXM8Ymc9Z3JlZW47Zmc9d2hpdGU+ICVzIDwvPiA8Zmc9Z3JlZW4+JXM8Lz5cbiIsICR0cmFpbGluZ0VPTCwgJHRoaXMtPmdldEJvcmRlcigkaWQpLCAkcHJlZml4LCAkbWVzc2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoIiVzJXM8Ymc9cmVkO2ZnPXdoaXRlPiAlcyA8Lz4gPGZnPXJlZD4lczwvPlxuIiwgJHRyYWlsaW5nRU9MLCAkdGhpcy0+Z2V0Qm9yZGVyKCRpZCksICRwcmVmaXgsICRtZXNzYWdlKTsKCiAgICAgICAgdW5zZXQoJHRoaXMtPnN0YXJ0ZWRbJGlkXVsnb3V0J10sICR0aGlzLT5zdGFydGVkWyRpZF1bJ2VyciddKTsKCiAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQgVGhlIGlkIG9mIHRoZSBmb3JtYXR0aW5nIHNlc3Npb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEJvcmRlcigkaWQpCiAgICB7CiAgICAgICAgcmV0dXJuIHNwcmludGYoJzxiZz0lcz4gPC8+JywgJHRoaXMtPmNvbG9yc1skdGhpcy0+c3RhcnRlZFskaWRdWydib3JkZXInXV0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICdkZWJ1Z19mb3JtYXR0ZXInOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CgovKioKICogRGVmaW5lcyB0aGUgc3R5bGVzIGZvciBhIFRhYmxlLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICogQGF1dGhvciDQodCw0YjQsCDQodGC0LDQvNC10L3QutC+0LLQuNGbIDx1bXBpcnNreUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUYWJsZVN0eWxlCnsKICAgIHByaXZhdGUgJHBhZGRpbmdDaGFyID0gJyAnOwogICAgcHJpdmF0ZSAkaG9yaXpvbnRhbEJvcmRlckNoYXIgPSAnLSc7CiAgICBwcml2YXRlICR2ZXJ0aWNhbEJvcmRlckNoYXIgPSAnfCc7CiAgICBwcml2YXRlICRjcm9zc2luZ0NoYXIgPSAnKyc7CiAgICBwcml2YXRlICRjZWxsSGVhZGVyRm9ybWF0ID0gJzxpbmZvPiVzPC9pbmZvPic7CiAgICBwcml2YXRlICRjZWxsUm93Rm9ybWF0ID0gJyVzJzsKICAgIHByaXZhdGUgJGNlbGxSb3dDb250ZW50Rm9ybWF0ID0gJyAlcyAnOwogICAgcHJpdmF0ZSAkYm9yZGVyRm9ybWF0ID0gJyVzJzsKICAgIHByaXZhdGUgJHBhZFR5cGUgPSBcU1RSX1BBRF9SSUdIVDsKCiAgICAvKioKICAgICAqIFNldHMgcGFkZGluZyBjaGFyYWN0ZXIsIHVzZWQgZm9yIGNlbGwgcGFkZGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYWRkaW5nQ2hhcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhZGRpbmdDaGFyKCRwYWRkaW5nQ2hhcikKICAgIHsKICAgICAgICBpZiAoISRwYWRkaW5nQ2hhcikgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1RoZSBwYWRkaW5nIGNoYXIgbXVzdCBub3QgYmUgZW1wdHkuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cGFkZGluZ0NoYXIgPSAkcGFkZGluZ0NoYXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgcGFkZGluZyBjaGFyYWN0ZXIsIHVzZWQgZm9yIGNlbGwgcGFkZGluZy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFkZGluZ0NoYXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGFkZGluZ0NoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGhvcml6b250YWwgYm9yZGVyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRob3Jpem9udGFsQm9yZGVyQ2hhcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhvcml6b250YWxCb3JkZXJDaGFyKCRob3Jpem9udGFsQm9yZGVyQ2hhcikKICAgIHsKICAgICAgICAkdGhpcy0+aG9yaXpvbnRhbEJvcmRlckNoYXIgPSAkaG9yaXpvbnRhbEJvcmRlckNoYXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgaG9yaXpvbnRhbCBib3JkZXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIb3Jpem9udGFsQm9yZGVyQ2hhcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ob3Jpem9udGFsQm9yZGVyQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdmVydGljYWwgYm9yZGVyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2ZXJ0aWNhbEJvcmRlckNoYXIKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWZXJ0aWNhbEJvcmRlckNoYXIoJHZlcnRpY2FsQm9yZGVyQ2hhcikKICAgIHsKICAgICAgICAkdGhpcy0+dmVydGljYWxCb3JkZXJDaGFyID0gJHZlcnRpY2FsQm9yZGVyQ2hhcjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB2ZXJ0aWNhbCBib3JkZXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJ0aWNhbEJvcmRlckNoYXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmVydGljYWxCb3JkZXJDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBjcm9zc2luZyBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY3Jvc3NpbmdDaGFyCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q3Jvc3NpbmdDaGFyKCRjcm9zc2luZ0NoYXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmNyb3NzaW5nQ2hhciA9ICRjcm9zc2luZ0NoYXI7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgY3Jvc3NpbmcgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDcm9zc2luZ0NoYXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y3Jvc3NpbmdDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBoZWFkZXIgY2VsbCBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2VsbEhlYWRlckZvcm1hdAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENlbGxIZWFkZXJGb3JtYXQoJGNlbGxIZWFkZXJGb3JtYXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNlbGxIZWFkZXJGb3JtYXQgPSAkY2VsbEhlYWRlckZvcm1hdDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBoZWFkZXIgY2VsbCBmb3JtYXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENlbGxIZWFkZXJGb3JtYXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2VsbEhlYWRlckZvcm1hdDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgcm93IGNlbGwgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNlbGxSb3dGb3JtYXQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDZWxsUm93Rm9ybWF0KCRjZWxsUm93Rm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5jZWxsUm93Rm9ybWF0ID0gJGNlbGxSb3dGb3JtYXQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgcm93IGNlbGwgZm9ybWF0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDZWxsUm93Rm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNlbGxSb3dGb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHJvdyBjZWxsIGNvbnRlbnQgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNlbGxSb3dDb250ZW50Rm9ybWF0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoJGNlbGxSb3dDb250ZW50Rm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5jZWxsUm93Q29udGVudEZvcm1hdCA9ICRjZWxsUm93Q29udGVudEZvcm1hdDsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyByb3cgY2VsbCBjb250ZW50IGZvcm1hdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2VsbFJvd0NvbnRlbnRGb3JtYXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2VsbFJvd0NvbnRlbnRGb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRhYmxlIGJvcmRlciBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYm9yZGVyRm9ybWF0CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9yZGVyRm9ybWF0KCRib3JkZXJGb3JtYXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmJvcmRlckZvcm1hdCA9ICRib3JkZXJGb3JtYXQ7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGFibGUgYm9yZGVyIGZvcm1hdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9yZGVyRm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvcmRlckZvcm1hdDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgY2VsbCBwYWRkaW5nIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkcGFkVHlwZSBTVFJfUEFEXyoKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQYWRUeXBlKCRwYWRUeXBlKQogICAgewogICAgICAgIGlmICghXGluX2FycmF5KCRwYWRUeXBlLCBbXFNUUl9QQURfTEVGVCwgXFNUUl9QQURfUklHSFQsIFxTVFJfUEFEX0JPVEhdLCB0cnVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIHBhZGRpbmcgdHlwZS4gRXhwZWN0ZWQgb25lIG9mIChTVFJfUEFEX0xFRlQsIFNUUl9QQURfUklHSFQsIFNUUl9QQURfQk9USCkuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cGFkVHlwZSA9ICRwYWRUeXBlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGNlbGwgcGFkZGluZyB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYWRUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhZFR5cGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogQGF1dGhvciBBYmRlbGxhdGlmIEFpdCBib3VkYWQgPGEuYWl0Ym91ZGFkQGdtYWlsLmNvbT4KICovCmNsYXNzIFRhYmxlQ2VsbAp7CiAgICBwcml2YXRlICR2YWx1ZTsKICAgIHByaXZhdGUgJG9wdGlvbnMgPSBbCiAgICAgICAgJ3Jvd3NwYW4nID0+IDEsCiAgICAgICAgJ2NvbHNwYW4nID0+IDEsCiAgICBdOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2YWx1ZSA9ICcnLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGlmIChpc19udW1lcmljKCR2YWx1ZSkgJiYgIVxpc19zdHJpbmcoJHZhbHVlKSkgewogICAgICAgICAgICAkdmFsdWUgPSAoc3RyaW5nKSAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdmFsdWU7CgogICAgICAgIC8vIGNoZWNrIG9wdGlvbiBuYW1lcwogICAgICAgIGlmICgkZGlmZiA9IGFycmF5X2RpZmYoYXJyYXlfa2V5cygkb3B0aW9ucyksIGFycmF5X2tleXMoJHRoaXMtPm9wdGlvbnMpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSBUYWJsZUNlbGwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgZm9sbG93aW5nIG9wdGlvbnM6IFwnJXNcJy4nLCBpbXBsb2RlKCdcJywgXCcnLCAkZGlmZikpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vcHRpb25zID0gYXJyYXlfbWVyZ2UoJHRoaXMtPm9wdGlvbnMsICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNlbGwgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIG51bWJlciBvZiBjb2xzcGFuLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb2xzcGFuKCkKICAgIHsKICAgICAgICByZXR1cm4gKGludCkgJHRoaXMtPm9wdGlvbnNbJ2NvbHNwYW4nXTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgbnVtYmVyIG9mIHJvd3NwYW4uCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJvd3NwYW4oKQogICAgewogICAgICAgIHJldHVybiAoaW50KSAkdGhpcy0+b3B0aW9uc1sncm93c3BhbiddOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7CgovKioKICogSGVscGVySW50ZXJmYWNlIGlzIHRoZSBpbnRlcmZhY2UgYWxsIGhlbHBlcnMgbXVzdCBpbXBsZW1lbnQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KaW50ZXJmYWNlIEhlbHBlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFNldHMgdGhlIGhlbHBlciBzZXQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGVscGVyLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVscGVyU2V0KEhlbHBlclNldCAkaGVscGVyU2V0ID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBoZWxwZXIgc2V0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhlbHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIEhlbHBlclNldCBBIEhlbHBlclNldCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyU2V0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGlzIGhlbHBlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgY2Fub25pY2FsIG5hbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXFJ1bnRpbWVFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEZvcm1hdHRlclxPdXRwdXRGb3JtYXR0ZXJTdHlsZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XFN0cmVhbWFibGVJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XENvbnNvbGVPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENob2ljZVF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxRdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcVGVybWluYWw7CgovKioKICogVGhlIFF1ZXN0aW9uSGVscGVyIGNsYXNzIHByb3ZpZGVzIGhlbHBlcnMgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgdXNlci4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBRdWVzdGlvbkhlbHBlciBleHRlbmRzIEhlbHBlcgp7CiAgICBwcml2YXRlICRpbnB1dFN0cmVhbTsKICAgIHByaXZhdGUgc3RhdGljICRzaGVsbDsKICAgIHByaXZhdGUgc3RhdGljICRzdHR5ID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEFza3MgYSBxdWVzdGlvbiB0byB0aGUgdXNlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFRoZSB1c2VyIGFuc3dlcgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBJZiB0aGVyZSBpcyBubyBkYXRhIHRvIHJlYWQgaW4gdGhlIGlucHV0IHN0cmVhbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICBpZiAoJG91dHB1dCBpbnN0YW5jZW9mIENvbnNvbGVPdXRwdXRJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJG91dHB1dCA9ICRvdXRwdXQtPmdldEVycm9yT3V0cHV0KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISRpbnB1dC0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICRkZWZhdWx0ID0gJHF1ZXN0aW9uLT5nZXREZWZhdWx0KCk7CgogICAgICAgICAgICBpZiAobnVsbCA9PT0gJGRlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR2YWxpZGF0b3IgPSAkcXVlc3Rpb24tPmdldFZhbGlkYXRvcigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXGNhbGxfdXNlcl9mdW5jKCRxdWVzdGlvbi0+Z2V0VmFsaWRhdG9yKCksICRkZWZhdWx0KTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRxdWVzdGlvbiBpbnN0YW5jZW9mIENob2ljZVF1ZXN0aW9uKSB7CiAgICAgICAgICAgICAgICAkY2hvaWNlcyA9ICRxdWVzdGlvbi0+Z2V0Q2hvaWNlcygpOwoKICAgICAgICAgICAgICAgIGlmICghJHF1ZXN0aW9uLT5pc011bHRpc2VsZWN0KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJGNob2ljZXNbJGRlZmF1bHRdKSA/ICRjaG9pY2VzWyRkZWZhdWx0XSA6ICRkZWZhdWx0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRkZWZhdWx0ID0gZXhwbG9kZSgnLCcsICRkZWZhdWx0KTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkZWZhdWx0IGFzICRrID0+ICR2KSB7CiAgICAgICAgICAgICAgICAgICAgJHYgPSB0cmltKCR2KTsKICAgICAgICAgICAgICAgICAgICAkZGVmYXVsdFska10gPSBpc3NldCgkY2hvaWNlc1skdl0pID8gJGNob2ljZXNbJHZdIDogJHY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgICAgICB9CgogICAgICAgIGlmICgkaW5wdXQgaW5zdGFuY2VvZiBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2UgJiYgJHN0cmVhbSA9ICRpbnB1dC0+Z2V0U3RyZWFtKCkpIHsKICAgICAgICAgICAgJHRoaXMtPmlucHV0U3RyZWFtID0gJHN0cmVhbTsKICAgICAgICB9CgogICAgICAgIGlmICghJHF1ZXN0aW9uLT5nZXRWYWxpZGF0b3IoKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvQXNrKCRvdXRwdXQsICRxdWVzdGlvbik7CiAgICAgICAgfQoKICAgICAgICAkaW50ZXJ2aWV3ZXIgPSBmdW5jdGlvbiAoKSB1c2UgKCRvdXRwdXQsICRxdWVzdGlvbikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRvQXNrKCRvdXRwdXQsICRxdWVzdGlvbik7CiAgICAgICAgfTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT52YWxpZGF0ZUF0dGVtcHRzKCRpbnRlcnZpZXdlciwgJG91dHB1dCwgJHF1ZXN0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20gd2hlbiBpbnRlcmFjdGluZyB3aXRoIHRoZSB1c2VyLgogICAgICoKICAgICAqIFRoaXMgaXMgbWFpbmx5IHVzZWZ1bCBmb3IgdGVzdGluZyBwdXJwb3NlLgogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4yLCB0byBiZSByZW1vdmVkIGluIDQuMC4gVXNlCiAgICAgKiAgICAgICAgICAgICBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U6OnNldFN0cmVhbSgpIGluc3RlYWQuCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlICRzdHJlYW0gVGhlIGlucHV0IHN0cmVhbQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIEluIGNhc2UgdGhlIHN0cmVhbSBpcyBub3QgYSByZXNvdXJjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SW5wdXRTdHJlYW0oJHN0cmVhbSkKICAgIHsKICAgICAgICBAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgJXMoKSBtZXRob2QgaXMgZGVwcmVjYXRlZCBzaW5jZSBTeW1mb255IDMuMiBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDQuMC4gVXNlICVzOjpzZXRTdHJlYW0oKSBpbnN0ZWFkLicsIF9fTUVUSE9EX18sIFN0cmVhbWFibGVJbnB1dEludGVyZmFjZTo6Y2xhc3MpLCBcRV9VU0VSX0RFUFJFQ0FURUQpOwoKICAgICAgICBpZiAoIVxpc19yZXNvdXJjZSgkc3RyZWFtKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnB1dCBzdHJlYW0gbXVzdCBiZSBhIHZhbGlkIHJlc291cmNlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmlucHV0U3RyZWFtID0gJHN0cmVhbTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGhlbHBlcidzIGlucHV0IHN0cmVhbS4KICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMiwgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZQogICAgICogICAgICAgICAgICAgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlOjpnZXRTdHJlYW0oKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEByZXR1cm4gcmVzb3VyY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElucHV0U3RyZWFtKCkKICAgIHsKICAgICAgICBpZiAoMCA9PT0gXGZ1bmNfbnVtX2FyZ3MoKSB8fCBmdW5jX2dldF9hcmcoMCkpIHsKICAgICAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICVzKCkgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgc2luY2UgU3ltZm9ueSAzLjIgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSAlczo6Z2V0U3RyZWFtKCkgaW5zdGVhZC4nLCBfX01FVEhPRF9fLCBTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U6OmNsYXNzKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aW5wdXRTdHJlYW07CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3F1ZXN0aW9uJzsKICAgIH0KCiAgICAvKioKICAgICAqIFByZXZlbnRzIHVzYWdlIG9mIHN0dHkuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZGlzYWJsZVN0dHkoKQogICAgewogICAgICAgIHNlbGY6OiRzdHR5ID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBBc2tzIHRoZSBxdWVzdGlvbiB0byB0aGUgdXNlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8bWl4ZWR8c3RyaW5nfG51bGwKICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSB0aGUgZmFsbGJhY2sgaXMgZGVhY3RpdmF0ZWQgYW5kIHRoZSByZXNwb25zZSBjYW5ub3QgYmUgaGlkZGVuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZG9Bc2soT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+d3JpdGVQcm9tcHQoJG91dHB1dCwgJHF1ZXN0aW9uKTsKCiAgICAgICAgJGlucHV0U3RyZWFtID0gJHRoaXMtPmlucHV0U3RyZWFtID86IFxTVERJTjsKICAgICAgICAkYXV0b2NvbXBsZXRlID0gJHF1ZXN0aW9uLT5nZXRBdXRvY29tcGxldGVyVmFsdWVzKCk7CgogICAgICAgIGlmIChcZnVuY3Rpb25fZXhpc3RzKCdzYXBpX3dpbmRvd3NfY3Bfc2V0JykpIHsKICAgICAgICAgICAgLy8gQ29kZXBhZ2UgdXNlZCBieSBjbWQuZXhlIG9uIFdpbmRvd3MgdG8gYWxsb3cgc3BlY2lhbCBjaGFyYWN0ZXJzICjDqcOgw7zDsSkuCiAgICAgICAgICAgIEBzYXBpX3dpbmRvd3NfY3Bfc2V0KDEyNTIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRhdXRvY29tcGxldGUgfHwgIXNlbGY6OiRzdHR5IHx8ICFUZXJtaW5hbDo6aGFzU3R0eUF2YWlsYWJsZSgpKSB7CiAgICAgICAgICAgICRyZXQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCRxdWVzdGlvbi0+aXNIaWRkZW4oKSkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAkcmV0ID0gdHJpbSgkdGhpcy0+Z2V0SGlkZGVuUmVzcG9uc2UoJG91dHB1dCwgJGlucHV0U3RyZWFtKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkcXVlc3Rpb24tPmlzSGlkZGVuRmFsbGJhY2soKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHJldCkgewogICAgICAgICAgICAgICAgJHJldCA9IGZnZXRzKCRpbnB1dFN0cmVhbSwgNDA5Nik7CiAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXQpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignQWJvcnRlZC4nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXQgPSB0cmltKCRyZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJldCA9IHRyaW0oJHRoaXMtPmF1dG9jb21wbGV0ZSgkb3V0cHV0LCAkcXVlc3Rpb24sICRpbnB1dFN0cmVhbSwgXGlzX2FycmF5KCRhdXRvY29tcGxldGUpID8gJGF1dG9jb21wbGV0ZSA6IGl0ZXJhdG9yX3RvX2FycmF5KCRhdXRvY29tcGxldGUsIGZhbHNlKSkpOwogICAgICAgIH0KCiAgICAgICAgJHJldCA9IFxzdHJsZW4oJHJldCkgPiAwID8gJHJldCA6ICRxdWVzdGlvbi0+Z2V0RGVmYXVsdCgpOwoKICAgICAgICBpZiAoJG5vcm1hbGl6ZXIgPSAkcXVlc3Rpb24tPmdldE5vcm1hbGl6ZXIoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vcm1hbGl6ZXIoJHJldCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJldDsKICAgIH0KCiAgICAvKioKICAgICAqIE91dHB1dHMgdGhlIHF1ZXN0aW9uIHByb21wdC4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlUHJvbXB0KE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBRdWVzdGlvbiAkcXVlc3Rpb24pCiAgICB7CiAgICAgICAgJG1lc3NhZ2UgPSAkcXVlc3Rpb24tPmdldFF1ZXN0aW9uKCk7CgogICAgICAgIGlmICgkcXVlc3Rpb24gaW5zdGFuY2VvZiBDaG9pY2VRdWVzdGlvbikgewogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKGFycmF5X21lcmdlKFsKICAgICAgICAgICAgICAgICRxdWVzdGlvbi0+Z2V0UXVlc3Rpb24oKSwKICAgICAgICAgICAgXSwgJHRoaXMtPmZvcm1hdENob2ljZVF1ZXN0aW9uQ2hvaWNlcygkcXVlc3Rpb24sICdpbmZvJykpKTsKCiAgICAgICAgICAgICRtZXNzYWdlID0gJHF1ZXN0aW9uLT5nZXRQcm9tcHQoKTsKICAgICAgICB9CgogICAgICAgICRvdXRwdXQtPndyaXRlKCRtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhZwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGZvcm1hdENob2ljZVF1ZXN0aW9uQ2hvaWNlcyhDaG9pY2VRdWVzdGlvbiAkcXVlc3Rpb24sICR0YWcpCiAgICB7CiAgICAgICAgJG1lc3NhZ2VzID0gW107CgogICAgICAgICRtYXhXaWR0aCA9IG1heChhcnJheV9tYXAoJ3NlbGY6OnN0cmxlbicsIGFycmF5X2tleXMoJGNob2ljZXMgPSAkcXVlc3Rpb24tPmdldENob2ljZXMoKSkpKTsKCiAgICAgICAgZm9yZWFjaCAoJGNob2ljZXMgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJHBhZGRpbmcgPSBzdHJfcmVwZWF0KCcgJywgJG1heFdpZHRoIC0gc2VsZjo6c3RybGVuKCRrZXkpKTsKCiAgICAgICAgICAgICRtZXNzYWdlc1tdID0gc3ByaW50ZigiICBbPCR0YWc+JXMkcGFkZGluZzwvJHRhZz5dICVzIiwgJGtleSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWVzc2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBPdXRwdXRzIGFuIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZUVycm9yKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBcRXhjZXB0aW9uICRlcnJvcikKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmdldEhlbHBlclNldCgpICYmICR0aGlzLT5nZXRIZWxwZXJTZXQoKS0+aGFzKCdmb3JtYXR0ZXInKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICR0aGlzLT5nZXRIZWxwZXJTZXQoKS0+Z2V0KCdmb3JtYXR0ZXInKS0+Zm9ybWF0QmxvY2soJGVycm9yLT5nZXRNZXNzYWdlKCksICdlcnJvcicpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gJzxlcnJvcj4nLiRlcnJvci0+Z2V0TWVzc2FnZSgpLic8L2Vycm9yPic7CiAgICAgICAgfQoKICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCRtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEF1dG9jb21wbGV0ZXMgYSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJGlucHV0U3RyZWFtCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhdXRvY29tcGxldGUoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsIFF1ZXN0aW9uICRxdWVzdGlvbiwgJGlucHV0U3RyZWFtLCBhcnJheSAkYXV0b2NvbXBsZXRlKQogICAgewogICAgICAgICRmdWxsQ2hvaWNlID0gJyc7CiAgICAgICAgJHJldCA9ICcnOwoKICAgICAgICAkaSA9IDA7CiAgICAgICAgJG9mcyA9IC0xOwogICAgICAgICRtYXRjaGVzID0gJGF1dG9jb21wbGV0ZTsKICAgICAgICAkbnVtTWF0Y2hlcyA9IFxjb3VudCgkbWF0Y2hlcyk7CgogICAgICAgICRzdHR5TW9kZSA9IHNoZWxsX2V4ZWMoJ3N0dHkgLWcnKTsKCiAgICAgICAgLy8gRGlzYWJsZSBpY2Fub24gKHNvIHdlIGNhbiBmcmVhZCBlYWNoIGtleXByZXNzKSBhbmQgZWNobyAod2UnbGwgZG8gZWNob2luZyBoZXJlIGluc3RlYWQpCiAgICAgICAgc2hlbGxfZXhlYygnc3R0eSAtaWNhbm9uIC1lY2hvJyk7CgogICAgICAgIC8vIEFkZCBoaWdobGlnaHRlZCB0ZXh0IHN0eWxlCiAgICAgICAgJG91dHB1dC0+Z2V0Rm9ybWF0dGVyKCktPnNldFN0eWxlKCdobCcsIG5ldyBPdXRwdXRGb3JtYXR0ZXJTdHlsZSgnYmxhY2snLCAnd2hpdGUnKSk7CgogICAgICAgIC8vIFJlYWQgYSBrZXlwcmVzcwogICAgICAgIHdoaWxlICghZmVvZigkaW5wdXRTdHJlYW0pKSB7CiAgICAgICAgICAgICRjID0gZnJlYWQoJGlucHV0U3RyZWFtLCAxKTsKCiAgICAgICAgICAgIC8vIGFzIG9wcG9zZWQgdG8gZmdldHMoKSwgZnJlYWQoKSByZXR1cm5zIGFuIGVtcHR5IHN0cmluZyB3aGVuIHRoZSBzdHJlYW0gY29udGVudCBpcyBlbXB0eSwgbm90IGZhbHNlLgogICAgICAgICAgICBpZiAoZmFsc2UgPT09ICRjIHx8ICgnJyA9PT0gJHJldCAmJiAnJyA9PT0gJGMgJiYgbnVsbCA9PT0gJHF1ZXN0aW9uLT5nZXREZWZhdWx0KCkpKSB7CiAgICAgICAgICAgICAgICBzaGVsbF9leGVjKHNwcmludGYoJ3N0dHkgJXMnLCAkc3R0eU1vZGUpKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdBYm9ydGVkLicpOwogICAgICAgICAgICB9IGVsc2VpZiAoIlwxNzciID09PSAkYykgeyAvLyBCYWNrc3BhY2UgQ2hhcmFjdGVyCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJG51bU1hdGNoZXMgJiYgMCAhPT0gJGkpIHsKICAgICAgICAgICAgICAgICAgICAtLSRpOwogICAgICAgICAgICAgICAgICAgICRmdWxsQ2hvaWNlID0gc2VsZjo6c3Vic3RyKCRmdWxsQ2hvaWNlLCAwLCAkaSk7CiAgICAgICAgICAgICAgICAgICAgLy8gTW92ZSBjdXJzb3IgYmFja3dhcmRzCiAgICAgICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoIlwwMzNbMUQiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJGkpIHsKICAgICAgICAgICAgICAgICAgICAkb2ZzID0gLTE7CiAgICAgICAgICAgICAgICAgICAgJG1hdGNoZXMgPSAkYXV0b2NvbXBsZXRlOwogICAgICAgICAgICAgICAgICAgICRudW1NYXRjaGVzID0gXGNvdW50KCRtYXRjaGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG51bU1hdGNoZXMgPSAwOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFBvcCB0aGUgbGFzdCBjaGFyYWN0ZXIgb2ZmIHRoZSBlbmQgb2Ygb3VyIHN0cmluZwogICAgICAgICAgICAgICAgJHJldCA9IHNlbGY6OnN1YnN0cigkcmV0LCAwLCAkaSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgiXDAzMyIgPT09ICRjKSB7CiAgICAgICAgICAgICAgICAvLyBEaWQgd2UgcmVhZCBhbiBlc2NhcGUgc2VxdWVuY2U/CiAgICAgICAgICAgICAgICAkYyAuPSBmcmVhZCgkaW5wdXRTdHJlYW0sIDIpOwoKICAgICAgICAgICAgICAgIC8vIEEgPSBVcCBBcnJvdy4gQiA9IERvd24gQXJyb3cKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkY1syXSkgJiYgKCdBJyA9PT0gJGNbMl0gfHwgJ0InID09PSAkY1syXSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJ0EnID09PSAkY1syXSAmJiAtMSA9PT0gJG9mcykgewogICAgICAgICAgICAgICAgICAgICAgICAkb2ZzID0gMDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgwID09PSAkbnVtTWF0Y2hlcykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRvZnMgKz0gKCdBJyA9PT0gJGNbMl0pID8gLTEgOiAxOwogICAgICAgICAgICAgICAgICAgICRvZnMgPSAoJG51bU1hdGNoZXMgKyAkb2ZzKSAlICRudW1NYXRjaGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoXG9yZCgkYykgPCAzMikgewogICAgICAgICAgICAgICAgaWYgKCJcdCIgPT09ICRjIHx8ICJcbiIgPT09ICRjKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRudW1NYXRjaGVzID4gMCAmJiAtMSAhPT0gJG9mcykgewogICAgICAgICAgICAgICAgICAgICAgICAkcmV0ID0gJG1hdGNoZXNbJG9mc107CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVjaG8gb3V0IHJlbWFpbmluZyBjaGFycyBmb3IgY3VycmVudCBtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAkcmVtYWluaW5nQ2hhcmFjdGVycyA9IHN1YnN0cigkcmV0LCBcc3RybGVuKHRyaW0oJHRoaXMtPm1vc3RSZWNlbnRseUVudGVyZWRWYWx1ZSgkZnVsbENob2ljZSkpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRyZW1haW5pbmdDaGFyYWN0ZXJzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGZ1bGxDaG9pY2UgLj0gJHJlbWFpbmluZ0NoYXJhY3RlcnM7CiAgICAgICAgICAgICAgICAgICAgICAgICRpID0gc2VsZjo6c3RybGVuKCRmdWxsQ2hvaWNlKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgiXG4iID09PSAkYykgewogICAgICAgICAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgkYyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJG51bU1hdGNoZXMgPSAwOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCJceDgwIiA8PSAkYykgewogICAgICAgICAgICAgICAgICAgICRjIC49IGZyZWFkKCRpbnB1dFN0cmVhbSwgWyJceEMwIiA9PiAxLCAiXHhEMCIgPT4gMSwgIlx4RTAiID0+IDIsICJceEYwIiA9PiAzXVskYyAmICJceEYwIl0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlKCRjKTsKICAgICAgICAgICAgICAgICRyZXQgLj0gJGM7CiAgICAgICAgICAgICAgICAkZnVsbENob2ljZSAuPSAkYzsKICAgICAgICAgICAgICAgICsrJGk7CgogICAgICAgICAgICAgICAgJHRlbXBSZXQgPSAkcmV0OwoKICAgICAgICAgICAgICAgIGlmICgkcXVlc3Rpb24gaW5zdGFuY2VvZiBDaG9pY2VRdWVzdGlvbiAmJiAkcXVlc3Rpb24tPmlzTXVsdGlzZWxlY3QoKSkgewogICAgICAgICAgICAgICAgICAgICR0ZW1wUmV0ID0gJHRoaXMtPm1vc3RSZWNlbnRseUVudGVyZWRWYWx1ZSgkZnVsbENob2ljZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG51bU1hdGNoZXMgPSAwOwogICAgICAgICAgICAgICAgJG9mcyA9IDA7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGF1dG9jb21wbGV0ZSBhcyAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJZiB0eXBlZCBjaGFyYWN0ZXJzIG1hdGNoIHRoZSBiZWdpbm5pbmcgY2h1bmsgb2YgdmFsdWUgKGUuZy4gW0FjbWVEZV1tb0J1bmRsZSkKICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCR2YWx1ZSwgJHRlbXBSZXQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtYXRjaGVzWyRudW1NYXRjaGVzKytdID0gJHZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRXJhc2UgY2hhcmFjdGVycyBmcm9tIGN1cnNvciB0byBlbmQgb2YgbGluZQogICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgiXDAzM1tLIik7CgogICAgICAgICAgICBpZiAoJG51bU1hdGNoZXMgPiAwICYmIC0xICE9PSAkb2ZzKSB7CiAgICAgICAgICAgICAgICAvLyBTYXZlIGN1cnNvciBwb3NpdGlvbgogICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoIlwwMzM3Iik7CiAgICAgICAgICAgICAgICAvLyBXcml0ZSBoaWdobGlnaHRlZCB0ZXh0LCBjb21wbGV0ZSB0aGUgcGFydGlhbGx5IGVudGVyZWQgcmVzcG9uc2UKICAgICAgICAgICAgICAgICRjaGFyYWN0ZXJzRW50ZXJlZCA9IFxzdHJsZW4odHJpbSgkdGhpcy0+bW9zdFJlY2VudGx5RW50ZXJlZFZhbHVlKCRmdWxsQ2hvaWNlKSkpOwogICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGUoJzxobD4nLk91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlVHJhaWxpbmdCYWNrc2xhc2goc3Vic3RyKCRtYXRjaGVzWyRvZnNdLCAkY2hhcmFjdGVyc0VudGVyZWQpKS4nPC9obD4nKTsKICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgY3Vyc29yIHBvc2l0aW9uCiAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZSgiXDAzMzgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUmVzZXQgc3R0eSBzbyBpdCBiZWhhdmVzIG5vcm1hbGx5IGFnYWluCiAgICAgICAgc2hlbGxfZXhlYyhzcHJpbnRmKCdzdHR5ICVzJywgJHN0dHlNb2RlKSk7CgogICAgICAgIHJldHVybiAkZnVsbENob2ljZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1vc3RSZWNlbnRseUVudGVyZWRWYWx1ZSgkZW50ZXJlZCkKICAgIHsKICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIG1vc3QgcmVjZW50IHZhbHVlIHRoYXQgdGhlIHVzZXIgZW50ZXJlZAogICAgICAgIGlmIChmYWxzZSA9PT0gc3RycG9zKCRlbnRlcmVkLCAnLCcpKSB7CiAgICAgICAgICAgIHJldHVybiAkZW50ZXJlZDsKICAgICAgICB9CgogICAgICAgICRjaG9pY2VzID0gZXhwbG9kZSgnLCcsICRlbnRlcmVkKTsKICAgICAgICBpZiAoXHN0cmxlbigkbGFzdENob2ljZSA9IHRyaW0oJGNob2ljZXNbXGNvdW50KCRjaG9pY2VzKSAtIDFdKSkgPiAwKSB7CiAgICAgICAgICAgIHJldHVybiAkbGFzdENob2ljZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZW50ZXJlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgYSBoaWRkZW4gcmVzcG9uc2UgZnJvbSB1c2VyLgogICAgICoKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCAgICAgIEFuIE91dHB1dCBpbnN0YW5jZQogICAgICogQHBhcmFtIHJlc291cmNlICAgICAgICAkaW5wdXRTdHJlYW0gVGhlIGhhbmRsZXIgcmVzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgYW5zd2VyCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIEluIGNhc2UgdGhlIGZhbGxiYWNrIGlzIGRlYWN0aXZhdGVkIGFuZCB0aGUgcmVzcG9uc2UgY2Fubm90IGJlIGhpZGRlbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEhpZGRlblJlc3BvbnNlKE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkaW5wdXRTdHJlYW0pCiAgICB7CiAgICAgICAgaWYgKCdcXCcgPT09IFxESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgICAgICRleGUgPSBfX0RJUl9fLicvLi4vUmVzb3VyY2VzL2Jpbi9oaWRkZW5pbnB1dC5leGUnOwoKICAgICAgICAgICAgLy8gaGFuZGxlIGNvZGUgcnVubmluZyBmcm9tIGEgcGhhcgogICAgICAgICAgICBpZiAoJ3BoYXI6JyA9PT0gc3Vic3RyKF9fRklMRV9fLCAwLCA1KSkgewogICAgICAgICAgICAgICAgJHRtcEV4ZSA9IHN5c19nZXRfdGVtcF9kaXIoKS4nL2hpZGRlbmlucHV0LmV4ZSc7CiAgICAgICAgICAgICAgICBjb3B5KCRleGUsICR0bXBFeGUpOwogICAgICAgICAgICAgICAgJGV4ZSA9ICR0bXBFeGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR2YWx1ZSA9IHJ0cmltKHNoZWxsX2V4ZWMoJGV4ZSkpOwogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCcnKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkdG1wRXhlKSkgewogICAgICAgICAgICAgICAgdW5saW5rKCR0bXBFeGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGY6OiRzdHR5ICYmIFRlcm1pbmFsOjpoYXNTdHR5QXZhaWxhYmxlKCkpIHsKICAgICAgICAgICAgJHN0dHlNb2RlID0gc2hlbGxfZXhlYygnc3R0eSAtZycpOwoKICAgICAgICAgICAgc2hlbGxfZXhlYygnc3R0eSAtZWNobycpOwogICAgICAgICAgICAkdmFsdWUgPSBmZ2V0cygkaW5wdXRTdHJlYW0sIDQwOTYpOwogICAgICAgICAgICBzaGVsbF9leGVjKHNwcmludGYoJ3N0dHkgJXMnLCAkc3R0eU1vZGUpKTsKCiAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignQWJvcnRlZC4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZhbHVlID0gdHJpbSgkdmFsdWUpOwogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCcnKTsKCiAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgIT09ICRzaGVsbCA9ICR0aGlzLT5nZXRTaGVsbCgpKSB7CiAgICAgICAgICAgICRyZWFkQ21kID0gJ2NzaCcgPT09ICRzaGVsbCA/ICdzZXQgbXlwYXNzd29yZCA9ICQ8JyA6ICdyZWFkIC1yIG15cGFzc3dvcmQnOwogICAgICAgICAgICAkY29tbWFuZCA9IHNwcmludGYoIi91c3IvYmluL2VudiAlcyAtYyAnc3R0eSAtZWNobzsgJXM7IHN0dHkgZWNobzsgZWNobyBcJG15cGFzc3dvcmQnIiwgJHNoZWxsLCAkcmVhZENtZCk7CiAgICAgICAgICAgICR2YWx1ZSA9IHJ0cmltKHNoZWxsX2V4ZWMoJGNvbW1hbmQpKTsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbignJyk7CgogICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ1VuYWJsZSB0byBoaWRlIHRoZSByZXNwb25zZS4nKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyBhbiBhdHRlbXB0LgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAgICAgICAgJGludGVydmlld2VyIEEgY2FsbGFibGUgdGhhdCB3aWxsIGFzayBmb3IgYSBxdWVzdGlvbiBhbmQgcmV0dXJuIHRoZSByZXN1bHQKICAgICAqIEBwYXJhbSBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCAgICAgIEFuIE91dHB1dCBpbnN0YW5jZQogICAgICogQHBhcmFtIFF1ZXN0aW9uICAgICAgICAkcXVlc3Rpb24gICAgQSBRdWVzdGlvbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQgVGhlIHZhbGlkYXRlZCByZXNwb25zZQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiBJbiBjYXNlIHRoZSBtYXggbnVtYmVyIG9mIGF0dGVtcHRzIGhhcyBiZWVuIHJlYWNoZWQgYW5kIG5vIHZhbGlkIHJlc3BvbnNlIGhhcyBiZWVuIGdpdmVuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVBdHRlbXB0cyhjYWxsYWJsZSAkaW50ZXJ2aWV3ZXIsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBRdWVzdGlvbiAkcXVlc3Rpb24pCiAgICB7CiAgICAgICAgJGVycm9yID0gbnVsbDsKICAgICAgICAkYXR0ZW1wdHMgPSAkcXVlc3Rpb24tPmdldE1heEF0dGVtcHRzKCk7CiAgICAgICAgd2hpbGUgKG51bGwgPT09ICRhdHRlbXB0cyB8fCAkYXR0ZW1wdHMtLSkgewogICAgICAgICAgICBpZiAobnVsbCAhPT0gJGVycm9yKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d3JpdGVFcnJvcigkb3V0cHV0LCAkZXJyb3IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIFxjYWxsX3VzZXJfZnVuYygkcXVlc3Rpb24tPmdldFZhbGlkYXRvcigpLCAkaW50ZXJ2aWV3ZXIoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlcnJvcikgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0aHJvdyAkZXJyb3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdmFsaWQgdW5peCBzaGVsbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xib29sIFRoZSB2YWxpZCBzaGVsbCBuYW1lLCBmYWxzZSBpbiBjYXNlIG5vIHZhbGlkIHNoZWxsIGlzIGZvdW5kCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0U2hlbGwoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokc2hlbGwpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OiRzaGVsbDsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRzaGVsbCA9IGZhbHNlOwoKICAgICAgICBpZiAoZmlsZV9leGlzdHMoJy91c3IvYmluL2VudicpKSB7CiAgICAgICAgICAgIC8vIGhhbmRsZSBvdGhlciBPU3Mgd2l0aCBiYXNoL3pzaC9rc2gvY3NoIGlmIGF2YWlsYWJsZSB0byBoaWRlIHRoZSBhbnN3ZXIKICAgICAgICAgICAgJHRlc3QgPSAiL3Vzci9iaW4vZW52ICVzIC1jICdlY2hvIE9LJyAyPiAvZGV2L251bGwiOwogICAgICAgICAgICBmb3JlYWNoIChbJ2Jhc2gnLCAnenNoJywgJ2tzaCcsICdjc2gnXSBhcyAkc2gpIHsKICAgICAgICAgICAgICAgIGlmICgnT0snID09PSBydHJpbShzaGVsbF9leGVjKHNwcmludGYoJHRlc3QsICRzaCkpKSkgewogICAgICAgICAgICAgICAgICAgIHNlbGY6OiRzaGVsbCA9ICRzaDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiRzaGVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKCi8qKgogKiBUaGUgRm9ybWF0dGVyIGNsYXNzIHByb3ZpZGVzIGhlbHBlcnMgdG8gZm9ybWF0IG1lc3NhZ2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEZvcm1hdHRlckhlbHBlciBleHRlbmRzIEhlbHBlcgp7CiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGhpbiBhIHNlY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2VjdGlvbiBUaGUgc2VjdGlvbiBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBtZXNzYWdlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHlsZSAgIFRoZSBzdHlsZSB0byBhcHBseSB0byB0aGUgc2VjdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBmb3JtYXQgc2VjdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZm9ybWF0U2VjdGlvbigkc2VjdGlvbiwgJG1lc3NhZ2UsICRzdHlsZSA9ICdpbmZvJykKICAgIHsKICAgICAgICByZXR1cm4gc3ByaW50ZignPCVzPlslc108LyVzPiAlcycsICRzdHlsZSwgJHNlY3Rpb24sICRzdHlsZSwgJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIG1lc3NhZ2UgYXMgYSBibG9jayBvZiB0ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2VzIFRoZSBtZXNzYWdlIHRvIHdyaXRlIGluIHRoZSBibG9jawogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkc3R5bGUgICAgVGhlIHN0eWxlIHRvIGFwcGx5IHRvIHRoZSB3aG9sZSBibG9jawogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkbGFyZ2UgICAgV2hldGhlciB0byByZXR1cm4gYSBsYXJnZSBibG9jawogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBmb3JtYXR0ZXIgbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZm9ybWF0QmxvY2soJG1lc3NhZ2VzLCAkc3R5bGUsICRsYXJnZSA9IGZhbHNlKQogICAgewogICAgICAgIGlmICghXGlzX2FycmF5KCRtZXNzYWdlcykpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzID0gWyRtZXNzYWdlc107CiAgICAgICAgfQoKICAgICAgICAkbGVuID0gMDsKICAgICAgICAkbGluZXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkbWVzc2FnZXMgYXMgJG1lc3NhZ2UpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSBPdXRwdXRGb3JtYXR0ZXI6OmVzY2FwZSgkbWVzc2FnZSk7CiAgICAgICAgICAgICRsaW5lc1tdID0gc3ByaW50ZigkbGFyZ2UgPyAnICAlcyAgJyA6ICcgJXMgJywgJG1lc3NhZ2UpOwogICAgICAgICAgICAkbGVuID0gbWF4KHNlbGY6OnN0cmxlbigkbWVzc2FnZSkgKyAoJGxhcmdlID8gNCA6IDIpLCAkbGVuKTsKICAgICAgICB9CgogICAgICAgICRtZXNzYWdlcyA9ICRsYXJnZSA/IFtzdHJfcmVwZWF0KCcgJywgJGxlbildIDogW107CiAgICAgICAgZm9yICgkaSA9IDA7IGlzc2V0KCRsaW5lc1skaV0pOyArKyRpKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1tdID0gJGxpbmVzWyRpXS5zdHJfcmVwZWF0KCcgJywgJGxlbiAtIHNlbGY6OnN0cmxlbigkbGluZXNbJGldKSk7CiAgICAgICAgfQogICAgICAgIGlmICgkbGFyZ2UpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSBzdHJfcmVwZWF0KCcgJywgJGxlbik7CiAgICAgICAgfQoKICAgICAgICBmb3IgKCRpID0gMDsgaXNzZXQoJG1lc3NhZ2VzWyRpXSk7ICsrJGkpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzWyRpXSA9IHNwcmludGYoJzwlcz4lczwvJXM+JywgJHN0eWxlLCAkbWVzc2FnZXNbJGldLCAkc3R5bGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGltcGxvZGUoIlxuIiwgJG1lc3NhZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRydW5jYXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGdpdmVuIGxlbmd0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gaW50ICAgICRsZW5ndGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1ZmZpeAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0cnVuY2F0ZSgkbWVzc2FnZSwgJGxlbmd0aCwgJHN1ZmZpeCA9ICcuLi4nKQogICAgewogICAgICAgICRjb21wdXRlZExlbmd0aCA9ICRsZW5ndGggLSBzZWxmOjpzdHJsZW4oJHN1ZmZpeCk7CgogICAgICAgIGlmICgkY29tcHV0ZWRMZW5ndGggPiBzZWxmOjpzdHJsZW4oJG1lc3NhZ2UpKSB7CiAgICAgICAgICAgIHJldHVybiAkbWVzc2FnZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjpzdWJzdHIoJG1lc3NhZ2UsIDAsICRsZW5ndGgpLiRzdWZmaXg7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2Zvcm1hdHRlcic7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBIZWxwZXJTZXQgcmVwcmVzZW50cyBhIHNldCBvZiBoZWxwZXJzIHRvIGJlIHVzZWQgd2l0aCBhIGNvbW1hbmQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSGVscGVyU2V0IGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlCnsKICAgIC8qKgogICAgICogQHZhciBIZWxwZXJbXQogICAgICovCiAgICBwcml2YXRlICRoZWxwZXJzID0gW107CiAgICBwcml2YXRlICRjb21tYW5kOwoKICAgIC8qKgogICAgICogQHBhcmFtIEhlbHBlcltdICRoZWxwZXJzIEFuIGFycmF5IG9mIGhlbHBlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGhlbHBlcnMgPSBbXSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkaGVscGVycyBhcyAkYWxpYXMgPT4gJGhlbHBlcikgewogICAgICAgICAgICAkdGhpcy0+c2V0KCRoZWxwZXIsIFxpc19pbnQoJGFsaWFzKSA/IG51bGwgOiAkYWxpYXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBoZWxwZXIuCiAgICAgKgogICAgICogQHBhcmFtIEhlbHBlckludGVyZmFjZSAkaGVscGVyIFRoZSBoZWxwZXIgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgJGFsaWFzICBBbiBhbGlhcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0KEhlbHBlckludGVyZmFjZSAkaGVscGVyLCAkYWxpYXMgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5oZWxwZXJzWyRoZWxwZXItPmdldE5hbWUoKV0gPSAkaGVscGVyOwogICAgICAgIGlmIChudWxsICE9PSAkYWxpYXMpIHsKICAgICAgICAgICAgJHRoaXMtPmhlbHBlcnNbJGFsaWFzXSA9ICRoZWxwZXI7CiAgICAgICAgfQoKICAgICAgICAkaGVscGVyLT5zZXRIZWxwZXJTZXQoJHRoaXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBoZWxwZXIgaWYgZGVmaW5lZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBoZWxwZXIgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBoZWxwZXIgaXMgZGVmaW5lZCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXMoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5oZWxwZXJzWyRuYW1lXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGEgaGVscGVyIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGhlbHBlciBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBIZWxwZXJJbnRlcmZhY2UgVGhlIGhlbHBlciBpbnN0YW5jZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBoZWxwZXIgaXMgbm90IGRlZmluZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIGhlbHBlciAiJXMiIGlzIG5vdCBkZWZpbmVkLicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmhlbHBlcnNbJG5hbWVdOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21tYW5kKENvbW1hbmQgJGNvbW1hbmQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kID0gJGNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb21tYW5kIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhlbHBlciBzZXQuCiAgICAgKgogICAgICogQHJldHVybiBDb21tYW5kIEEgQ29tbWFuZCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWFuZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBIZWxwZXJbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiBuZXcgXEFycmF5SXRlcmF0b3IoJHRoaXMtPmhlbHBlcnMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXI7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxUZXJtaW5hbDsKCi8qKgogKiBUaGUgUHJvZ3Jlc3NCYXIgcHJvdmlkZXMgaGVscGVycyB0byBkaXNwbGF5IHByb2dyZXNzIG91dHB1dC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgQ2hyaXMgSm9uZXMgPGxlZWtlZEBnbWFpbC5jb20+CiAqLwpmaW5hbCBjbGFzcyBQcm9ncmVzc0Jhcgp7CiAgICBwcml2YXRlICRiYXJXaWR0aCA9IDI4OwogICAgcHJpdmF0ZSAkYmFyQ2hhcjsKICAgIHByaXZhdGUgJGVtcHR5QmFyQ2hhciA9ICctJzsKICAgIHByaXZhdGUgJHByb2dyZXNzQ2hhciA9ICc+JzsKICAgIHByaXZhdGUgJGZvcm1hdDsKICAgIHByaXZhdGUgJGludGVybmFsRm9ybWF0OwogICAgcHJpdmF0ZSAkcmVkcmF3RnJlcSA9IDE7CiAgICBwcml2YXRlICRvdXRwdXQ7CiAgICBwcml2YXRlICRzdGVwID0gMDsKICAgIHByaXZhdGUgJG1heDsKICAgIHByaXZhdGUgJHN0YXJ0VGltZTsKICAgIHByaXZhdGUgJHN0ZXBXaWR0aDsKICAgIHByaXZhdGUgJHBlcmNlbnQgPSAwLjA7CiAgICBwcml2YXRlICRmb3JtYXRMaW5lQ291bnQ7CiAgICBwcml2YXRlICRtZXNzYWdlcyA9IFtdOwogICAgcHJpdmF0ZSAkb3ZlcndyaXRlID0gdHJ1ZTsKICAgIHByaXZhdGUgJHRlcm1pbmFsOwogICAgcHJpdmF0ZSAkZmlyc3RSdW4gPSB0cnVlOwoKICAgIHByaXZhdGUgc3RhdGljICRmb3JtYXR0ZXJzOwogICAgcHJpdmF0ZSBzdGF0aWMgJGZvcm1hdHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQgQW4gT3V0cHV0SW50ZXJmYWNlIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICRtYXggICAgTWF4aW11bSBzdGVwcyAoMCBpZiB1bmtub3duKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRtYXggPSAwKQogICAgewogICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgQ29uc29sZU91dHB1dEludGVyZmFjZSkgewogICAgICAgICAgICAkb3V0cHV0ID0gJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwogICAgICAgICR0aGlzLT5zZXRNYXhTdGVwcygkbWF4KTsKICAgICAgICAkdGhpcy0+dGVybWluYWwgPSBuZXcgVGVybWluYWwoKTsKCiAgICAgICAgaWYgKCEkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpKSB7CiAgICAgICAgICAgIC8vIGRpc2FibGUgb3ZlcndyaXRlIHdoZW4gb3V0cHV0IGRvZXMgbm90IHN1cHBvcnQgQU5TSSBjb2Rlcy4KICAgICAgICAgICAgJHRoaXMtPm92ZXJ3cml0ZSA9IGZhbHNlOwoKICAgICAgICAgICAgLy8gc2V0IGEgcmVhc29uYWJsZSByZWRyYXcgZnJlcXVlbmN5IHNvIG91dHB1dCBpc24ndCBmbG9vZGVkCiAgICAgICAgICAgICR0aGlzLT5zZXRSZWRyYXdGcmVxdWVuY3koJG1heCAvIDEwKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zdGFydFRpbWUgPSB0aW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgcGxhY2Vob2xkZXIgZm9ybWF0dGVyIGZvciBhIGdpdmVuIG5hbWUuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgYWxzbyBhbGxvdyB5b3UgdG8gb3ZlcnJpZGUgYW4gZXhpc3RpbmcgcGxhY2Vob2xkZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRuYW1lICAgICBUaGUgcGxhY2Vob2xkZXIgbmFtZSAoaW5jbHVkaW5nIHRoZSBkZWxpbWl0ZXIgY2hhciBsaWtlICUpCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGNhbGxhYmxlIEEgUEhQIGNhbGxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0UGxhY2Vob2xkZXJGb3JtYXR0ZXJEZWZpbml0aW9uKCRuYW1lLCBjYWxsYWJsZSAkY2FsbGFibGUpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokZm9ybWF0dGVycykgewogICAgICAgICAgICBzZWxmOjokZm9ybWF0dGVycyA9IHNlbGY6OmluaXRQbGFjZWhvbGRlckZvcm1hdHRlcnMoKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRmb3JtYXR0ZXJzWyRuYW1lXSA9ICRjYWxsYWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHBsYWNlaG9sZGVyIGZvcm1hdHRlciBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHBsYWNlaG9sZGVyIG5hbWUgKGluY2x1ZGluZyB0aGUgZGVsaW1pdGVyIGNoYXIgbGlrZSAlKQogICAgICoKICAgICAqIEByZXR1cm4gY2FsbGFibGV8bnVsbCBBIFBIUCBjYWxsYWJsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsYWNlaG9sZGVyRm9ybWF0dGVyRGVmaW5pdGlvbigkbmFtZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRmb3JtYXR0ZXJzKSB7CiAgICAgICAgICAgIHNlbGY6OiRmb3JtYXR0ZXJzID0gc2VsZjo6aW5pdFBsYWNlaG9sZGVyRm9ybWF0dGVycygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KHNlbGY6OiRmb3JtYXR0ZXJzWyRuYW1lXSkgPyBzZWxmOjokZm9ybWF0dGVyc1skbmFtZV0gOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIGZvcm1hdCBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGFsc28gYWxsb3cgeW91IHRvIG92ZXJyaWRlIGFuIGV4aXN0aW5nIGZvcm1hdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgVGhlIGZvcm1hdCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQgQSBmb3JtYXQgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0Rm9ybWF0RGVmaW5pdGlvbigkbmFtZSwgJGZvcm1hdCkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRmb3JtYXRzKSB7CiAgICAgICAgICAgIHNlbGY6OiRmb3JtYXRzID0gc2VsZjo6aW5pdEZvcm1hdHMoKTsKICAgICAgICB9CgogICAgICAgIHNlbGY6OiRmb3JtYXRzWyRuYW1lXSA9ICRmb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBmb3JtYXQgZm9yIGEgZ2l2ZW4gbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBmb3JtYXQgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgQSBmb3JtYXQgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Rm9ybWF0RGVmaW5pdGlvbigkbmFtZSkKICAgIHsKICAgICAgICBpZiAoIXNlbGY6OiRmb3JtYXRzKSB7CiAgICAgICAgICAgIHNlbGY6OiRmb3JtYXRzID0gc2VsZjo6aW5pdEZvcm1hdHMoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc3NldChzZWxmOjokZm9ybWF0c1skbmFtZV0pID8gc2VsZjo6JGZvcm1hdHNbJG5hbWVdIDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEFzc29jaWF0ZXMgYSB0ZXh0IHdpdGggYSBuYW1lZCBwbGFjZWhvbGRlci4KICAgICAqCiAgICAgKiBUaGUgdGV4dCBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgcHJvZ3Jlc3MgYmFyIGlzIHJlbmRlcmVkIGJ1dCBvbmx5CiAgICAgKiB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIHBsYWNlaG9sZGVyIGlzIHBhcnQgb2YgdGhlIGN1c3RvbSBmb3JtYXQgbGluZQogICAgICogKGJ5IHdyYXBwaW5nIHRoZSBuYW1lIHdpdGggJSkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgdGV4dCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgcGxhY2Vob2xkZXIKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgICAgVGhlIG5hbWUgb2YgdGhlIHBsYWNlaG9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNZXNzYWdlKCRtZXNzYWdlLCAkbmFtZSA9ICdtZXNzYWdlJykKICAgIHsKICAgICAgICAkdGhpcy0+bWVzc2FnZXNbJG5hbWVdID0gJG1lc3NhZ2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE1lc3NhZ2UoJG5hbWUgPSAnbWVzc2FnZScpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tZXNzYWdlc1skbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9ncmVzcyBiYXIgc3RhcnQgdGltZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgcHJvZ3Jlc3MgYmFyIHN0YXJ0IHRpbWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXJ0VGltZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFydFRpbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcm9ncmVzcyBiYXIgbWF4aW1hbCBzdGVwcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgcHJvZ3Jlc3MgYmFyIG1heCBzdGVwcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TWF4U3RlcHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWF4OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY3VycmVudCBzdGVwIHBvc2l0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBwcm9ncmVzcyBiYXIgc3RlcAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvZ3Jlc3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RlcDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2dyZXNzIGJhciBzdGVwIHdpZHRoLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBwcm9ncmVzcyBiYXIgc3RlcCB3aWR0aAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFN0ZXBXaWR0aCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGVwV2lkdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHByb2dyZXNzIGJhciBwZXJjZW50LgogICAgICoKICAgICAqIEByZXR1cm4gZmxvYXQgVGhlIGN1cnJlbnQgcHJvZ3Jlc3MgYmFyIHBlcmNlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb2dyZXNzUGVyY2VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wZXJjZW50OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIHdpZHRoLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHNpemUgVGhlIHByb2dyZXNzIGJhciBzaXplCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCYXJXaWR0aCgkc2l6ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmFyV2lkdGggPSBtYXgoMSwgKGludCkgJHNpemUpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcHJvZ3Jlc3MgYmFyIHdpZHRoLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBwcm9ncmVzcyBiYXIgc2l6ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QmFyV2lkdGgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YmFyV2lkdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBiYXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNoYXIgQSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJhckNoYXJhY3RlcigkY2hhcikKICAgIHsKICAgICAgICAkdGhpcy0+YmFyQ2hhciA9ICRjaGFyOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgYmFyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGNoYXJhY3RlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QmFyQ2hhcmFjdGVyKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmJhckNoYXIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYXggPyAnPScgOiAkdGhpcy0+ZW1wdHlCYXJDaGFyOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5iYXJDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZW1wdHkgYmFyIGNoYXJhY3Rlci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyIEEgY2hhcmFjdGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbXB0eUJhckNoYXJhY3RlcigkY2hhcikKICAgIHsKICAgICAgICAkdGhpcy0+ZW1wdHlCYXJDaGFyID0gJGNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBlbXB0eSBiYXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEEgY2hhcmFjdGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbXB0eUJhckNoYXJhY3RlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lbXB0eUJhckNoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9ncmVzcyBiYXIgY2hhcmFjdGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNoYXIgQSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb2dyZXNzQ2hhcmFjdGVyKCRjaGFyKQogICAgewogICAgICAgICR0aGlzLT5wcm9ncmVzc0NoYXIgPSAkY2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByb2dyZXNzIGJhciBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgQSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFByb2dyZXNzQ2hhcmFjdGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb2dyZXNzQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybWF0IFRoZSBmb3JtYXQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZvcm1hdCgkZm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5mb3JtYXQgPSBudWxsOwogICAgICAgICR0aGlzLT5pbnRlcm5hbEZvcm1hdCA9ICRmb3JtYXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSByZWRyYXcgZnJlcXVlbmN5LgogICAgICoKICAgICAqIEBwYXJhbSBpbnR8ZmxvYXQgJGZyZXEgVGhlIGZyZXF1ZW5jeSBpbiBzdGVwcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVkcmF3RnJlcXVlbmN5KCRmcmVxKQogICAgewogICAgICAgICR0aGlzLT5yZWRyYXdGcmVxID0gbWF4KChpbnQpICRmcmVxLCAxKTsKICAgIH0KCiAgICAvKioKICAgICAqIFN0YXJ0cyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAkbWF4IE51bWJlciBvZiBzdGVwcyB0byBjb21wbGV0ZSB0aGUgYmFyICgwIGlmIGluZGV0ZXJtaW5hdGUpLCBudWxsIHRvIGxlYXZlIHVuY2hhbmdlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RhcnQoJG1heCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXJ0VGltZSA9IHRpbWUoKTsKICAgICAgICAkdGhpcy0+c3RlcCA9IDA7CiAgICAgICAgJHRoaXMtPnBlcmNlbnQgPSAwLjA7CgogICAgICAgIGlmIChudWxsICE9PSAkbWF4KSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRNYXhTdGVwcygkbWF4KTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5kaXNwbGF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZHZhbmNlcyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0IFggc3RlcHMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc3RlcCBOdW1iZXIgb2Ygc3RlcHMgdG8gYWR2YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWR2YW5jZSgkc3RlcCA9IDEpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldFByb2dyZXNzKCR0aGlzLT5zdGVwICsgJHN0ZXApOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIHRvIG92ZXJ3cml0ZSB0aGUgcHJvZ3Jlc3NiYXIsIGZhbHNlIGZvciBuZXcgbGluZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkb3ZlcndyaXRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPdmVyd3JpdGUoJG92ZXJ3cml0ZSkKICAgIHsKICAgICAgICAkdGhpcy0+b3ZlcndyaXRlID0gKGJvb2wpICRvdmVyd3JpdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHByb2dyZXNzLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJHN0ZXAgVGhlIGN1cnJlbnQgcHJvZ3Jlc3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb2dyZXNzKCRzdGVwKQogICAgewogICAgICAgICRzdGVwID0gKGludCkgJHN0ZXA7CgogICAgICAgIGlmICgkdGhpcy0+bWF4ICYmICRzdGVwID4gJHRoaXMtPm1heCkgewogICAgICAgICAgICAkdGhpcy0+bWF4ID0gJHN0ZXA7CiAgICAgICAgfSBlbHNlaWYgKCRzdGVwIDwgMCkgewogICAgICAgICAgICAkc3RlcCA9IDA7CiAgICAgICAgfQoKICAgICAgICAkcHJldlBlcmlvZCA9IChpbnQpICgkdGhpcy0+c3RlcCAvICR0aGlzLT5yZWRyYXdGcmVxKTsKICAgICAgICAkY3VyclBlcmlvZCA9IChpbnQpICgkc3RlcCAvICR0aGlzLT5yZWRyYXdGcmVxKTsKICAgICAgICAkdGhpcy0+c3RlcCA9ICRzdGVwOwogICAgICAgICR0aGlzLT5wZXJjZW50ID0gJHRoaXMtPm1heCA/IChmbG9hdCkgJHRoaXMtPnN0ZXAgLyAkdGhpcy0+bWF4IDogMDsKICAgICAgICBpZiAoJHByZXZQZXJpb2QgIT09ICRjdXJyUGVyaW9kIHx8ICR0aGlzLT5tYXggPT09ICRzdGVwKSB7CiAgICAgICAgICAgICR0aGlzLT5kaXNwbGF5KCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRmluaXNoZXMgdGhlIHByb2dyZXNzIG91dHB1dC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmlzaCgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+bWF4KSB7CiAgICAgICAgICAgICR0aGlzLT5tYXggPSAkdGhpcy0+c3RlcDsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+c3RlcCA9PT0gJHRoaXMtPm1heCAmJiAhJHRoaXMtPm92ZXJ3cml0ZSkgewogICAgICAgICAgICAvLyBwcmV2ZW50IGRvdWJsZSAxMDAlIG91dHB1dAogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0UHJvZ3Jlc3MoJHRoaXMtPm1heCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBPdXRwdXRzIHRoZSBjdXJyZW50IHByb2dyZXNzIHN0cmluZy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc3BsYXkoKQogICAgewogICAgICAgIGlmIChPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCA9PT0gJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5mb3JtYXQpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFJlYWxGb3JtYXQoJHRoaXMtPmludGVybmFsRm9ybWF0ID86ICR0aGlzLT5kZXRlcm1pbmVCZXN0Rm9ybWF0KCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm92ZXJ3cml0ZSgkdGhpcy0+YnVpbGRMaW5lKCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgcHJvZ3Jlc3MgYmFyIGZyb20gdGhlIGN1cnJlbnQgbGluZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIHVzZWZ1bCBpZiB5b3Ugd2lzaCB0byB3cml0ZSBzb21lIG91dHB1dAogICAgICogd2hpbGUgYSBwcm9ncmVzcyBiYXIgaXMgcnVubmluZy4KICAgICAqIENhbGwgZGlzcGxheSgpIHRvIHNob3cgdGhlIHByb2dyZXNzIGJhciBhZ2Fpbi4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5vdmVyd3JpdGUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5mb3JtYXQpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFJlYWxGb3JtYXQoJHRoaXMtPmludGVybmFsRm9ybWF0ID86ICR0aGlzLT5kZXRlcm1pbmVCZXN0Rm9ybWF0KCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm92ZXJ3cml0ZSgnJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9ncmVzcyBiYXIgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm1hdCBUaGUgZm9ybWF0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0UmVhbEZvcm1hdCgkZm9ybWF0KQogICAgewogICAgICAgIC8vIHRyeSB0byB1c2UgdGhlIF9ub21heCB2YXJpYW50IGlmIGF2YWlsYWJsZQogICAgICAgIGlmICghJHRoaXMtPm1heCAmJiBudWxsICE9PSBzZWxmOjpnZXRGb3JtYXREZWZpbml0aW9uKCRmb3JtYXQuJ19ub21heCcpKSB7CiAgICAgICAgICAgICR0aGlzLT5mb3JtYXQgPSBzZWxmOjpnZXRGb3JtYXREZWZpbml0aW9uKCRmb3JtYXQuJ19ub21heCcpOwogICAgICAgIH0gZWxzZWlmIChudWxsICE9PSBzZWxmOjpnZXRGb3JtYXREZWZpbml0aW9uKCRmb3JtYXQpKSB7CiAgICAgICAgICAgICR0aGlzLT5mb3JtYXQgPSBzZWxmOjpnZXRGb3JtYXREZWZpbml0aW9uKCRmb3JtYXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5mb3JtYXQgPSAkZm9ybWF0OwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZvcm1hdExpbmVDb3VudCA9IHN1YnN0cl9jb3VudCgkdGhpcy0+Zm9ybWF0LCAiXG4iKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBtYXhpbWFsIHN0ZXBzLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJG1heCBUaGUgcHJvZ3Jlc3MgYmFyIG1heCBzdGVwcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldE1heFN0ZXBzKCRtYXgpCiAgICB7CiAgICAgICAgJHRoaXMtPm1heCA9IG1heCgwLCAoaW50KSAkbWF4KTsKICAgICAgICAkdGhpcy0+c3RlcFdpZHRoID0gJHRoaXMtPm1heCA/IEhlbHBlcjo6c3RybGVuKCR0aGlzLT5tYXgpIDogNDsKICAgIH0KCiAgICAvKioKICAgICAqIE92ZXJ3cml0ZXMgYSBwcmV2aW91cyBtZXNzYWdlIHRvIHRoZSBvdXRwdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBUaGUgbWVzc2FnZQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG92ZXJ3cml0ZSgkbWVzc2FnZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPm92ZXJ3cml0ZSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5maXJzdFJ1bikgewogICAgICAgICAgICAgICAgLy8gRXJhc2UgcHJldmlvdXMgbGluZXMKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Zm9ybWF0TGluZUNvdW50ID4gMCkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlID0gc3RyX3JlcGVhdCgiXHgxQlsxQVx4MUJbMksiLCAkdGhpcy0+Zm9ybWF0TGluZUNvdW50KS4kbWVzc2FnZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZSBhbmQgZXJhc2UgdGhlIGxpbmUKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gIlx4MERceDFCWzJLJG1lc3NhZ2UiOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5zdGVwID4gMCkgewogICAgICAgICAgICAkbWVzc2FnZSA9IFxQSFBfRU9MLiRtZXNzYWdlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZpcnN0UnVuID0gZmFsc2U7CgogICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlKCRtZXNzYWdlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRldGVybWluZUJlc3RGb3JtYXQoKQogICAgewogICAgICAgIHN3aXRjaCAoJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgLy8gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfUVVJRVQ6IGRpc3BsYXkgaXMgZGlzYWJsZWQgYW55d2F5CiAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSQk9TRToKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF4ID8gJ3ZlcmJvc2UnIDogJ3ZlcmJvc2Vfbm9tYXgnOwogICAgICAgICAgICBjYXNlIE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRToKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF4ID8gJ3ZlcnlfdmVyYm9zZScgOiAndmVyeV92ZXJib3NlX25vbWF4JzsKICAgICAgICAgICAgY2FzZSBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9ERUJVRzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bWF4ID8gJ2RlYnVnJyA6ICdkZWJ1Z19ub21heCc7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPm1heCA/ICdub3JtYWwnIDogJ25vcm1hbF9ub21heCc7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXRQbGFjZWhvbGRlckZvcm1hdHRlcnMoKQogICAgewogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdiYXInID0+IGZ1bmN0aW9uIChzZWxmICRiYXIsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KSB7CiAgICAgICAgICAgICAgICAkY29tcGxldGVCYXJzID0gZmxvb3IoJGJhci0+Z2V0TWF4U3RlcHMoKSA+IDAgPyAkYmFyLT5nZXRQcm9ncmVzc1BlcmNlbnQoKSAqICRiYXItPmdldEJhcldpZHRoKCkgOiAkYmFyLT5nZXRQcm9ncmVzcygpICUgJGJhci0+Z2V0QmFyV2lkdGgoKSk7CiAgICAgICAgICAgICAgICAkZGlzcGxheSA9IHN0cl9yZXBlYXQoJGJhci0+Z2V0QmFyQ2hhcmFjdGVyKCksICRjb21wbGV0ZUJhcnMpOwogICAgICAgICAgICAgICAgaWYgKCRjb21wbGV0ZUJhcnMgPCAkYmFyLT5nZXRCYXJXaWR0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVtcHR5QmFycyA9ICRiYXItPmdldEJhcldpZHRoKCkgLSAkY29tcGxldGVCYXJzIC0gSGVscGVyOjpzdHJsZW5XaXRob3V0RGVjb3JhdGlvbigkb3V0cHV0LT5nZXRGb3JtYXR0ZXIoKSwgJGJhci0+Z2V0UHJvZ3Jlc3NDaGFyYWN0ZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgJGRpc3BsYXkgLj0gJGJhci0+Z2V0UHJvZ3Jlc3NDaGFyYWN0ZXIoKS5zdHJfcmVwZWF0KCRiYXItPmdldEVtcHR5QmFyQ2hhcmFjdGVyKCksICRlbXB0eUJhcnMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkZGlzcGxheTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ2VsYXBzZWQnID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBIZWxwZXI6OmZvcm1hdFRpbWUodGltZSgpIC0gJGJhci0+Z2V0U3RhcnRUaW1lKCkpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAncmVtYWluaW5nJyA9PiBmdW5jdGlvbiAoc2VsZiAkYmFyKSB7CiAgICAgICAgICAgICAgICBpZiAoISRiYXItPmdldE1heFN0ZXBzKCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1VuYWJsZSB0byBkaXNwbGF5IHRoZSByZW1haW5pbmcgdGltZSBpZiB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc3RlcHMgaXMgbm90IHNldC4nKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoISRiYXItPmdldFByb2dyZXNzKCkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVtYWluaW5nID0gMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHJlbWFpbmluZyA9IHJvdW5kKCh0aW1lKCkgLSAkYmFyLT5nZXRTdGFydFRpbWUoKSkgLyAkYmFyLT5nZXRQcm9ncmVzcygpICogKCRiYXItPmdldE1heFN0ZXBzKCkgLSAkYmFyLT5nZXRQcm9ncmVzcygpKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6Zm9ybWF0VGltZSgkcmVtYWluaW5nKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ2VzdGltYXRlZCcgPT4gZnVuY3Rpb24gKHNlbGYgJGJhcikgewogICAgICAgICAgICAgICAgaWYgKCEkYmFyLT5nZXRNYXhTdGVwcygpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKCdVbmFibGUgdG8gZGlzcGxheSB0aGUgZXN0aW1hdGVkIHRpbWUgaWYgdGhlIG1heGltdW0gbnVtYmVyIG9mIHN0ZXBzIGlzIG5vdCBzZXQuJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEkYmFyLT5nZXRQcm9ncmVzcygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVzdGltYXRlZCA9IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRlc3RpbWF0ZWQgPSByb3VuZCgodGltZSgpIC0gJGJhci0+Z2V0U3RhcnRUaW1lKCkpIC8gJGJhci0+Z2V0UHJvZ3Jlc3MoKSAqICRiYXItPmdldE1heFN0ZXBzKCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBIZWxwZXI6OmZvcm1hdFRpbWUoJGVzdGltYXRlZCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdtZW1vcnknID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBIZWxwZXI6OmZvcm1hdE1lbW9yeShtZW1vcnlfZ2V0X3VzYWdlKHRydWUpKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ2N1cnJlbnQnID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcGFkKCRiYXItPmdldFByb2dyZXNzKCksICRiYXItPmdldFN0ZXBXaWR0aCgpLCAnICcsIFxTVFJfUEFEX0xFRlQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAnbWF4JyA9PiBmdW5jdGlvbiAoc2VsZiAkYmFyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGJhci0+Z2V0TWF4U3RlcHMoKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ3BlcmNlbnQnID0+IGZ1bmN0aW9uIChzZWxmICRiYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmbG9vcigkYmFyLT5nZXRQcm9ncmVzc1BlcmNlbnQoKSAqIDEwMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpbml0Rm9ybWF0cygpCiAgICB7CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJ25vcm1hbCcgPT4gJyAlY3VycmVudCUvJW1heCUgWyViYXIlXSAlcGVyY2VudDozcyUlJywKICAgICAgICAgICAgJ25vcm1hbF9ub21heCcgPT4gJyAlY3VycmVudCUgWyViYXIlXScsCgogICAgICAgICAgICAndmVyYm9zZScgPT4gJyAlY3VycmVudCUvJW1heCUgWyViYXIlXSAlcGVyY2VudDozcyUlICVlbGFwc2VkOjZzJScsCiAgICAgICAgICAgICd2ZXJib3NlX25vbWF4JyA9PiAnICVjdXJyZW50JSBbJWJhciVdICVlbGFwc2VkOjZzJScsCgogICAgICAgICAgICAndmVyeV92ZXJib3NlJyA9PiAnICVjdXJyZW50JS8lbWF4JSBbJWJhciVdICVwZXJjZW50OjNzJSUgJWVsYXBzZWQ6NnMlLyVlc3RpbWF0ZWQ6LTZzJScsCiAgICAgICAgICAgICd2ZXJ5X3ZlcmJvc2Vfbm9tYXgnID0+ICcgJWN1cnJlbnQlIFslYmFyJV0gJWVsYXBzZWQ6NnMlJywKCiAgICAgICAgICAgICdkZWJ1ZycgPT4gJyAlY3VycmVudCUvJW1heCUgWyViYXIlXSAlcGVyY2VudDozcyUlICVlbGFwc2VkOjZzJS8lZXN0aW1hdGVkOi02cyUgJW1lbW9yeTo2cyUnLAogICAgICAgICAgICAnZGVidWdfbm9tYXgnID0+ICcgJWN1cnJlbnQlIFslYmFyJV0gJWVsYXBzZWQ6NnMlICVtZW1vcnk6NnMlJywKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZExpbmUoKQogICAgewogICAgICAgICRyZWdleCA9ICJ7JShbYS16XC1fXSspKD86XDooW14lXSspKT8lfWkiOwogICAgICAgICRjYWxsYmFjayA9IGZ1bmN0aW9uICgkbWF0Y2hlcykgewogICAgICAgICAgICBpZiAoJGZvcm1hdHRlciA9ICR0aGlzOjpnZXRQbGFjZWhvbGRlckZvcm1hdHRlckRlZmluaXRpb24oJG1hdGNoZXNbMV0pKSB7CiAgICAgICAgICAgICAgICAkdGV4dCA9IFxjYWxsX3VzZXJfZnVuYygkZm9ybWF0dGVyLCAkdGhpcywgJHRoaXMtPm91dHB1dCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkdGhpcy0+bWVzc2FnZXNbJG1hdGNoZXNbMV1dKSkgewogICAgICAgICAgICAgICAgJHRleHQgPSAkdGhpcy0+bWVzc2FnZXNbJG1hdGNoZXNbMV1dOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbMl0pKSB7CiAgICAgICAgICAgICAgICAkdGV4dCA9IHNwcmludGYoJyUnLiRtYXRjaGVzWzJdLCAkdGV4dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdGV4dDsKICAgICAgICB9OwogICAgICAgICRsaW5lID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRyZWdleCwgJGNhbGxiYWNrLCAkdGhpcy0+Zm9ybWF0KTsKCiAgICAgICAgLy8gZ2V0cyBzdHJpbmcgbGVuZ3RoIGZvciBlYWNoIHN1YiBsaW5lIHdpdGggbXVsdGlsaW5lIGZvcm1hdAogICAgICAgICRsaW5lc0xlbmd0aCA9IGFycmF5X21hcChmdW5jdGlvbiAoJHN1YkxpbmUpIHsKICAgICAgICAgICAgcmV0dXJuIEhlbHBlcjo6c3RybGVuV2l0aG91dERlY29yYXRpb24oJHRoaXMtPm91dHB1dC0+Z2V0Rm9ybWF0dGVyKCksIHJ0cmltKCRzdWJMaW5lLCAiXHIiKSk7CiAgICAgICAgfSwgZXhwbG9kZSgiXG4iLCAkbGluZSkpOwoKICAgICAgICAkbGluZXNXaWR0aCA9IG1heCgkbGluZXNMZW5ndGgpOwoKICAgICAgICAkdGVybWluYWxXaWR0aCA9ICR0aGlzLT50ZXJtaW5hbC0+Z2V0V2lkdGgoKTsKICAgICAgICBpZiAoJGxpbmVzV2lkdGggPD0gJHRlcm1pbmFsV2lkdGgpIHsKICAgICAgICAgICAgcmV0dXJuICRsaW5lOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNldEJhcldpZHRoKCR0aGlzLT5iYXJXaWR0aCAtICRsaW5lc1dpZHRoICsgJHRlcm1pbmFsV2lkdGgpOwoKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCRyZWdleCwgJGNhbGxiYWNrLCAkdGhpcy0+Zm9ybWF0KTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEBhdXRob3IgS2V2aW4gQm9uZCA8a2V2aW5ib25kQGdtYWlsLmNvbT4KICovCmNsYXNzIFByb2dyZXNzSW5kaWNhdG9yCnsKICAgIHByaXZhdGUgJG91dHB1dDsKICAgIHByaXZhdGUgJHN0YXJ0VGltZTsKICAgIHByaXZhdGUgJGZvcm1hdDsKICAgIHByaXZhdGUgJG1lc3NhZ2U7CiAgICBwcml2YXRlICRpbmRpY2F0b3JWYWx1ZXM7CiAgICBwcml2YXRlICRpbmRpY2F0b3JDdXJyZW50OwogICAgcHJpdmF0ZSAkaW5kaWNhdG9yQ2hhbmdlSW50ZXJ2YWw7CiAgICBwcml2YXRlICRpbmRpY2F0b3JVcGRhdGVUaW1lOwogICAgcHJpdmF0ZSAkc3RhcnRlZCA9IGZhbHNlOwoKICAgIHByaXZhdGUgc3RhdGljICRmb3JtYXR0ZXJzOwogICAgcHJpdmF0ZSBzdGF0aWMgJGZvcm1hdHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGZvcm1hdCAgICAgICAgICAgICAgICAgIEluZGljYXRvciBmb3JtYXQKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkaW5kaWNhdG9yQ2hhbmdlSW50ZXJ2YWwgQ2hhbmdlIGludGVydmFsIGluIG1pbGxpc2Vjb25kcwogICAgICogQHBhcmFtIGFycmF5fG51bGwgICRpbmRpY2F0b3JWYWx1ZXMgICAgICAgICBBbmltYXRlZCBpbmRpY2F0b3IgY2hhcmFjdGVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQsICRmb3JtYXQgPSBudWxsLCAkaW5kaWNhdG9yQ2hhbmdlSW50ZXJ2YWwgPSAxMDAsICRpbmRpY2F0b3JWYWx1ZXMgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQgPSAkb3V0cHV0OwoKICAgICAgICBpZiAobnVsbCA9PT0gJGZvcm1hdCkgewogICAgICAgICAgICAkZm9ybWF0ID0gJHRoaXMtPmRldGVybWluZUJlc3RGb3JtYXQoKTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkaW5kaWNhdG9yVmFsdWVzKSB7CiAgICAgICAgICAgICRpbmRpY2F0b3JWYWx1ZXMgPSBbJy0nLCAnXFwnLCAnfCcsICcvJ107CiAgICAgICAgfQoKICAgICAgICAkaW5kaWNhdG9yVmFsdWVzID0gYXJyYXlfdmFsdWVzKCRpbmRpY2F0b3JWYWx1ZXMpOwoKICAgICAgICBpZiAoMiA+IFxjb3VudCgkaW5kaWNhdG9yVmFsdWVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdNdXN0IGhhdmUgYXQgbGVhc3QgMiBpbmRpY2F0b3IgdmFsdWUgY2hhcmFjdGVycy4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5mb3JtYXQgPSBzZWxmOjpnZXRGb3JtYXREZWZpbml0aW9uKCRmb3JtYXQpOwogICAgICAgICR0aGlzLT5pbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbCA9ICRpbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbDsKICAgICAgICAkdGhpcy0+aW5kaWNhdG9yVmFsdWVzID0gJGluZGljYXRvclZhbHVlczsKICAgICAgICAkdGhpcy0+c3RhcnRUaW1lID0gdGltZSgpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY3VycmVudCBpbmRpY2F0b3IgbWVzc2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1lc3NhZ2UoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPm1lc3NhZ2UgPSAkbWVzc2FnZTsKCiAgICAgICAgJHRoaXMtPmRpc3BsYXkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFN0YXJ0cyB0aGUgaW5kaWNhdG9yIG91dHB1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0YXJ0KCRtZXNzYWdlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c3RhcnRlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1Byb2dyZXNzIGluZGljYXRvciBhbHJlYWR5IHN0YXJ0ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bWVzc2FnZSA9ICRtZXNzYWdlOwogICAgICAgICR0aGlzLT5zdGFydGVkID0gdHJ1ZTsKICAgICAgICAkdGhpcy0+c3RhcnRUaW1lID0gdGltZSgpOwogICAgICAgICR0aGlzLT5pbmRpY2F0b3JVcGRhdGVUaW1lID0gJHRoaXMtPmdldEN1cnJlbnRUaW1lSW5NaWxsaXNlY29uZHMoKSArICR0aGlzLT5pbmRpY2F0b3JDaGFuZ2VJbnRlcnZhbDsKICAgICAgICAkdGhpcy0+aW5kaWNhdG9yQ3VycmVudCA9IDA7CgogICAgICAgICR0aGlzLT5kaXNwbGF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZHZhbmNlcyB0aGUgaW5kaWNhdG9yLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWR2YW5jZSgpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+c3RhcnRlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1Byb2dyZXNzIGluZGljYXRvciBoYXMgbm90IHlldCBiZWVuIHN0YXJ0ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGN1cnJlbnRUaW1lID0gJHRoaXMtPmdldEN1cnJlbnRUaW1lSW5NaWxsaXNlY29uZHMoKTsKCiAgICAgICAgaWYgKCRjdXJyZW50VGltZSA8ICR0aGlzLT5pbmRpY2F0b3JVcGRhdGVUaW1lKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5pbmRpY2F0b3JVcGRhdGVUaW1lID0gJGN1cnJlbnRUaW1lICsgJHRoaXMtPmluZGljYXRvckNoYW5nZUludGVydmFsOwogICAgICAgICsrJHRoaXMtPmluZGljYXRvckN1cnJlbnQ7CgogICAgICAgICR0aGlzLT5kaXNwbGF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaW5pc2ggdGhlIGluZGljYXRvciB3aXRoIG1lc3NhZ2UuCiAgICAgKgogICAgICogQHBhcmFtICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaW5pc2goJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+c3RhcnRlZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ1Byb2dyZXNzIGluZGljYXRvciBoYXMgbm90IHlldCBiZWVuIHN0YXJ0ZWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bWVzc2FnZSA9ICRtZXNzYWdlOwogICAgICAgICR0aGlzLT5kaXNwbGF5KCk7CiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGVsbignJyk7CiAgICAgICAgJHRoaXMtPnN0YXJ0ZWQgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGZvcm1hdCBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGZvcm1hdCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbCBBIGZvcm1hdCBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRGb3JtYXREZWZpbml0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghc2VsZjo6JGZvcm1hdHMpIHsKICAgICAgICAgICAgc2VsZjo6JGZvcm1hdHMgPSBzZWxmOjppbml0Rm9ybWF0cygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KHNlbGY6OiRmb3JtYXRzWyRuYW1lXSkgPyBzZWxmOjokZm9ybWF0c1skbmFtZV0gOiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIHBsYWNlaG9sZGVyIGZvcm1hdHRlciBmb3IgYSBnaXZlbiBuYW1lLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGFsc28gYWxsb3cgeW91IHRvIG92ZXJyaWRlIGFuIGV4aXN0aW5nIHBsYWNlaG9sZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkbmFtZSAgICAgVGhlIHBsYWNlaG9sZGVyIG5hbWUgKGluY2x1ZGluZyB0aGUgZGVsaW1pdGVyIGNoYXIgbGlrZSAlKQogICAgICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYWJsZSBBIFBIUCBjYWxsYWJsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNldFBsYWNlaG9sZGVyRm9ybWF0dGVyRGVmaW5pdGlvbigkbmFtZSwgJGNhbGxhYmxlKQogICAgewogICAgICAgIGlmICghc2VsZjo6JGZvcm1hdHRlcnMpIHsKICAgICAgICAgICAgc2VsZjo6JGZvcm1hdHRlcnMgPSBzZWxmOjppbml0UGxhY2Vob2xkZXJGb3JtYXR0ZXJzKCk7CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokZm9ybWF0dGVyc1skbmFtZV0gPSAkY2FsbGFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwbGFjZWhvbGRlciBmb3JtYXR0ZXIgZm9yIGEgZ2l2ZW4gbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBwbGFjZWhvbGRlciBuYW1lIChpbmNsdWRpbmcgdGhlIGRlbGltaXRlciBjaGFyIGxpa2UgJSkKICAgICAqCiAgICAgKiBAcmV0dXJuIGNhbGxhYmxlfG51bGwgQSBQSFAgY2FsbGFibGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRQbGFjZWhvbGRlckZvcm1hdHRlckRlZmluaXRpb24oJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokZm9ybWF0dGVycykgewogICAgICAgICAgICBzZWxmOjokZm9ybWF0dGVycyA9IHNlbGY6OmluaXRQbGFjZWhvbGRlckZvcm1hdHRlcnMoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc3NldChzZWxmOjokZm9ybWF0dGVyc1skbmFtZV0pID8gc2VsZjo6JGZvcm1hdHRlcnNbJG5hbWVdIDogbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRpc3BsYXkoKQogICAgewogICAgICAgIGlmIChPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCA9PT0gJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHNlbGYgPSAkdGhpczsKCiAgICAgICAgJHRoaXMtPm92ZXJ3cml0ZShwcmVnX3JlcGxhY2VfY2FsbGJhY2soInslKFthLXpcLV9dKykoPzpcOihbXiVdKykpPyV9aSIsIGZ1bmN0aW9uICgkbWF0Y2hlcykgdXNlICgkc2VsZikgewogICAgICAgICAgICBpZiAoJGZvcm1hdHRlciA9ICRzZWxmOjpnZXRQbGFjZWhvbGRlckZvcm1hdHRlckRlZmluaXRpb24oJG1hdGNoZXNbMV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXGNhbGxfdXNlcl9mdW5jKCRmb3JtYXR0ZXIsICRzZWxmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWzBdOwogICAgICAgIH0sICR0aGlzLT5mb3JtYXQpKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGRldGVybWluZUJlc3RGb3JtYXQoKQogICAgewogICAgICAgIHN3aXRjaCAoJHRoaXMtPm91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgLy8gT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfUVVJRVQ6IGRpc3BsYXkgaXMgZGlzYWJsZWQgYW55d2F5CiAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSQk9TRToKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpID8gJ3ZlcmJvc2UnIDogJ3ZlcmJvc2Vfbm9fYW5zaSc7CiAgICAgICAgICAgIGNhc2UgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSWV9WRVJCT1NFOgogICAgICAgICAgICBjYXNlIE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX0RFQlVHOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkgPyAndmVyeV92ZXJib3NlJyA6ICd2ZXJ5X3ZlcmJvc2Vfbm9fYW5zaSc7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPm91dHB1dC0+aXNEZWNvcmF0ZWQoKSA/ICdub3JtYWwnIDogJ25vcm1hbF9ub19hbnNpJzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBPdmVyd3JpdGVzIGEgcHJldmlvdXMgbWVzc2FnZSB0byB0aGUgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UgVGhlIG1lc3NhZ2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBvdmVyd3JpdGUoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5vdXRwdXQtPmlzRGVjb3JhdGVkKCkpIHsKICAgICAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoIlx4MERceDFCWzJLIik7CiAgICAgICAgICAgICR0aGlzLT5vdXRwdXQtPndyaXRlKCRtZXNzYWdlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZWxuKCRtZXNzYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDdXJyZW50VGltZUluTWlsbGlzZWNvbmRzKCkKICAgIHsKICAgICAgICByZXR1cm4gcm91bmQobWljcm90aW1lKHRydWUpICogMTAwMCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdFBsYWNlaG9sZGVyRm9ybWF0dGVycygpCiAgICB7CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJ2luZGljYXRvcicgPT4gZnVuY3Rpb24gKHNlbGYgJGluZGljYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbmRpY2F0b3ItPmluZGljYXRvclZhbHVlc1skaW5kaWNhdG9yLT5pbmRpY2F0b3JDdXJyZW50ICUgXGNvdW50KCRpbmRpY2F0b3ItPmluZGljYXRvclZhbHVlcyldOwogICAgICAgICAgICB9LAogICAgICAgICAgICAnbWVzc2FnZScgPT4gZnVuY3Rpb24gKHNlbGYgJGluZGljYXRvcikgewogICAgICAgICAgICAgICAgcmV0dXJuICRpbmRpY2F0b3ItPm1lc3NhZ2U7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdlbGFwc2VkJyA9PiBmdW5jdGlvbiAoc2VsZiAkaW5kaWNhdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gSGVscGVyOjpmb3JtYXRUaW1lKHRpbWUoKSAtICRpbmRpY2F0b3ItPnN0YXJ0VGltZSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdtZW1vcnknID0+IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBIZWxwZXI6OmZvcm1hdE1lbW9yeShtZW1vcnlfZ2V0X3VzYWdlKHRydWUpKTsKICAgICAgICAgICAgfSwKICAgICAgICBdOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXRGb3JtYXRzKCkKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAnbm9ybWFsJyA9PiAnICVpbmRpY2F0b3IlICVtZXNzYWdlJScsCiAgICAgICAgICAgICdub3JtYWxfbm9fYW5zaScgPT4gJyAlbWVzc2FnZSUnLAoKICAgICAgICAgICAgJ3ZlcmJvc2UnID0+ICcgJWluZGljYXRvciUgJW1lc3NhZ2UlICglZWxhcHNlZDo2cyUpJywKICAgICAgICAgICAgJ3ZlcmJvc2Vfbm9fYW5zaScgPT4gJyAlbWVzc2FnZSUgKCVlbGFwc2VkOjZzJSknLAoKICAgICAgICAgICAgJ3ZlcnlfdmVyYm9zZScgPT4gJyAlaW5kaWNhdG9yJSAlbWVzc2FnZSUgKCVlbGFwc2VkOjZzJSwgJW1lbW9yeTo2cyUpJywKICAgICAgICAgICAgJ3ZlcnlfdmVyYm9zZV9ub19hbnNpJyA9PiAnICVtZXNzYWdlJSAoJWVsYXBzZWQ6NnMlLCAlbWVtb3J5OjZzJSknLAogICAgICAgIF07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEhlbHBlcjsKCi8qKgogKiBNYXJrcyBhIHJvdyBhcyBiZWluZyBhIHNlcGFyYXRvci4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBUYWJsZVNlcGFyYXRvciBleHRlbmRzIFRhYmxlQ2VsbAp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCcnLCAkb3B0aW9ucyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlOwoKY2xhc3MgVGVybWluYWwKewogICAgcHJpdmF0ZSBzdGF0aWMgJHdpZHRoOwogICAgcHJpdmF0ZSBzdGF0aWMgJGhlaWdodDsKICAgIHByaXZhdGUgc3RhdGljICRzdHR5OwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGVybWluYWwgd2lkdGguCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFdpZHRoKCkKICAgIHsKICAgICAgICAkd2lkdGggPSBnZXRlbnYoJ0NPTFVNTlMnKTsKICAgICAgICBpZiAoZmFsc2UgIT09ICR3aWR0aCkgewogICAgICAgICAgICByZXR1cm4gKGludCkgdHJpbSgkd2lkdGgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09IHNlbGY6OiR3aWR0aCkgewogICAgICAgICAgICBzZWxmOjppbml0RGltZW5zaW9ucygpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY6OiR3aWR0aCA/OiA4MDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHRlcm1pbmFsIGhlaWdodC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVpZ2h0KCkKICAgIHsKICAgICAgICAkaGVpZ2h0ID0gZ2V0ZW52KCdMSU5FUycpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJGhlaWdodCkgewogICAgICAgICAgICByZXR1cm4gKGludCkgdHJpbSgkaGVpZ2h0KTsKICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSBzZWxmOjokaGVpZ2h0KSB7CiAgICAgICAgICAgIHNlbGY6OmluaXREaW1lbnNpb25zKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2VsZjo6JGhlaWdodCA/OiA1MDsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGhhc1N0dHlBdmFpbGFibGUoKQogICAgewogICAgICAgIGlmIChudWxsICE9PSBzZWxmOjokc3R0eSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6JHN0dHk7CiAgICAgICAgfQoKICAgICAgICAvLyBza2lwIGNoZWNrIGlmIGV4ZWMgZnVuY3Rpb24gaXMgZGlzYWJsZWQKICAgICAgICBpZiAoIVxmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBleGVjKCdzdHR5IDI+JjEnLCAkb3V0cHV0LCAkZXhpdGNvZGUpOwoKICAgICAgICByZXR1cm4gc2VsZjo6JHN0dHkgPSAwID09PSAkZXhpdGNvZGU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaW5pdERpbWVuc2lvbnMoKQogICAgewogICAgICAgIGlmICgnXFwnID09PSBcRElSRUNUT1JZX1NFUEFSQVRPUikgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oXGQrKXgoXGQrKSg/OiBcKChcZCspeChcZCspXCkpPyQvJywgdHJpbShnZXRlbnYoJ0FOU0lDT04nKSksICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgLy8gZXh0cmFjdCBbdywgSF0gZnJvbSAid3hoIChXeEgpIgogICAgICAgICAgICAgICAgLy8gb3IgW3csIGhdIGZyb20gInd4aCIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IGlzc2V0KCRtYXRjaGVzWzRdKSA/IChpbnQpICRtYXRjaGVzWzRdIDogKGludCkgJG1hdGNoZXNbMl07CiAgICAgICAgICAgIH0gZWxzZWlmICghc2VsZjo6aGFzVnQxMDBTdXBwb3J0KCkgJiYgc2VsZjo6aGFzU3R0eUF2YWlsYWJsZSgpKSB7CiAgICAgICAgICAgICAgICAvLyBvbmx5IHVzZSBzdHR5IG9uIFdpbmRvd3MgaWYgdGhlIHRlcm1pbmFsIGRvZXMgbm90IHN1cHBvcnQgdnQxMDAgKGUuZy4gV2luZG93cyA3ICsgZ2l0LWJhc2gpCiAgICAgICAgICAgICAgICAvLyB0ZXN0aW5nIGZvciBzdHR5IGluIGEgV2luZG93cyAxMCB2dDEwMC1lbmFibGVkIGNvbnNvbGUgd2lsbCBpbXBsaWNpdGx5IGRpc2FibGUgdnQxMDAgc3VwcG9ydCBvbiBTVERPVVQKICAgICAgICAgICAgICAgIHNlbGY6OmluaXREaW1lbnNpb25zVXNpbmdTdHR5KCk7CiAgICAgICAgICAgIH0gZWxzZWlmIChudWxsICE9PSAkZGltZW5zaW9ucyA9IHNlbGY6OmdldENvbnNvbGVNb2RlKCkpIHsKICAgICAgICAgICAgICAgIC8vIGV4dHJhY3QgW3csIGhdIGZyb20gInd4aCIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRkaW1lbnNpb25zWzBdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRkaW1lbnNpb25zWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZjo6aW5pdERpbWVuc2lvbnNVc2luZ1N0dHkoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgU1RET1VUIGhhcyB2dDEwMCBzdXBwb3J0IChzb21lIFdpbmRvd3MgMTArIGNvbmZpZ3VyYXRpb25zKS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaGFzVnQxMDBTdXBwb3J0KCkKICAgIHsKICAgICAgICByZXR1cm4gXGZ1bmN0aW9uX2V4aXN0cygnc2FwaV93aW5kb3dzX3Z0MTAwX3N1cHBvcnQnKSAmJiBzYXBpX3dpbmRvd3NfdnQxMDBfc3VwcG9ydChmb3BlbigncGhwOi8vc3Rkb3V0JywgJ3cnKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyBkaW1lbnNpb25zIHVzaW5nIHRoZSBvdXRwdXQgb2YgYW4gc3R0eSBjb2x1bW5zIGxpbmUuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGluaXREaW1lbnNpb25zVXNpbmdTdHR5KCkKICAgIHsKICAgICAgICBpZiAoJHN0dHlTdHJpbmcgPSBzZWxmOjpnZXRTdHR5Q29sdW1ucygpKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvcm93cy4oXGQrKTsuY29sdW1ucy4oXGQrKTsvaScsICRzdHR5U3RyaW5nLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgIC8vIGV4dHJhY3QgW3csIGhdIGZyb20gInJvd3MgaDsgY29sdW1ucyB3OyIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzJdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgnLzsuKFxkKykucm93czsuKFxkKykuY29sdW1ucy9pJywgJHN0dHlTdHJpbmcsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgLy8gZXh0cmFjdCBbdywgaF0gZnJvbSAiOyBoIHJvd3M7IHcgY29sdW1ucyIKICAgICAgICAgICAgICAgIHNlbGY6OiR3aWR0aCA9IChpbnQpICRtYXRjaGVzWzJdOwogICAgICAgICAgICAgICAgc2VsZjo6JGhlaWdodCA9IChpbnQpICRtYXRjaGVzWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUnVucyBhbmQgcGFyc2VzIG1vZGUgQ09OIGlmIGl0J3MgYXZhaWxhYmxlLCBzdXBwcmVzc2luZyBhbnkgZXJyb3Igb3V0cHV0LgogICAgICoKICAgICAqIEByZXR1cm4gaW50W118bnVsbCBBbiBhcnJheSBjb21wb3NlZCBvZiB0aGUgd2lkdGggYW5kIHRoZSBoZWlnaHQgb3IgbnVsbCBpZiBpdCBjb3VsZCBub3QgYmUgcGFyc2VkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldENvbnNvbGVNb2RlKCkKICAgIHsKICAgICAgICAkaW5mbyA9IHNlbGY6OnJlYWRGcm9tUHJvY2VzcygnbW9kZSBDT04nKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICRpbmZvIHx8ICFwcmVnX21hdGNoKCcvLS0tLS0tLS0rXHI/XG4uKz8oXGQrKVxyP1xuLis/KFxkKylccj9cbi8nLCAkaW5mbywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFsoaW50KSAkbWF0Y2hlc1syXSwgKGludCkgJG1hdGNoZXNbMV1dOwogICAgfQoKICAgIC8qKgogICAgICogUnVucyBhbmQgcGFyc2VzIHN0dHkgLWEgaWYgaXQncyBhdmFpbGFibGUsIHN1cHByZXNzaW5nIGFueSBlcnJvciBvdXRwdXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRTdHR5Q29sdW1ucygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OnJlYWRGcm9tUHJvY2Vzcygnc3R0eSAtYSB8IGdyZXAgY29sdW1ucycpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkY29tbWFuZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gcmVhZEZyb21Qcm9jZXNzKCRjb21tYW5kKQogICAgewogICAgICAgIGlmICghXGZ1bmN0aW9uX2V4aXN0cygncHJvY19vcGVuJykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkZGVzY3JpcHRvcnNwZWMgPSBbCiAgICAgICAgICAgIDEgPT4gWydwaXBlJywgJ3cnXSwKICAgICAgICAgICAgMiA9PiBbJ3BpcGUnLCAndyddLAogICAgICAgIF07CgogICAgICAgICRwcm9jZXNzID0gcHJvY19vcGVuKCRjb21tYW5kLCAkZGVzY3JpcHRvcnNwZWMsICRwaXBlcywgbnVsbCwgbnVsbCwgWydzdXBwcmVzc19lcnJvcnMnID0+IHRydWVdKTsKICAgICAgICBpZiAoIVxpc19yZXNvdXJjZSgkcHJvY2VzcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkaW5mbyA9IHN0cmVhbV9nZXRfY29udGVudHMoJHBpcGVzWzFdKTsKICAgICAgICBmY2xvc2UoJHBpcGVzWzFdKTsKICAgICAgICBmY2xvc2UoJHBpcGVzWzJdKTsKICAgICAgICBwcm9jX2Nsb3NlKCRwcm9jZXNzKTsKCiAgICAgICAgcmV0dXJuICRpbmZvOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXERlc2NyaXB0b3JIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIExpc3RDb21tYW5kIGRpc3BsYXlzIHRoZSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY29tbWFuZHMgZm9yIHRoZSBhcHBsaWNhdGlvbi4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBMaXN0Q29tbWFuZCBleHRlbmRzIENvbW1hbmQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmUoKQogICAgewogICAgICAgICR0aGlzCiAgICAgICAgICAgIC0+c2V0TmFtZSgnbGlzdCcpCiAgICAgICAgICAgIC0+c2V0RGVmaW5pdGlvbigkdGhpcy0+Y3JlYXRlRGVmaW5pdGlvbigpKQogICAgICAgICAgICAtPnNldERlc2NyaXB0aW9uKCdMaXN0cyBjb21tYW5kcycpCiAgICAgICAgICAgIC0+c2V0SGVscCg8PDwnRU9GJwpUaGUgPGluZm8+JWNvbW1hbmQubmFtZSU8L2luZm8+IGNvbW1hbmQgbGlzdHMgYWxsIGNvbW1hbmRzOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJTwvaW5mbz4KCllvdSBjYW4gYWxzbyBkaXNwbGF5IHRoZSBjb21tYW5kcyBmb3IgYSBzcGVjaWZpYyBuYW1lc3BhY2U6CgogIDxpbmZvPnBocCAlY29tbWFuZC5mdWxsX25hbWUlIHRlc3Q8L2luZm8+CgpZb3UgY2FuIGFsc28gb3V0cHV0IHRoZSBpbmZvcm1hdGlvbiBpbiBvdGhlciBmb3JtYXRzIGJ5IHVzaW5nIHRoZSA8Y29tbWVudD4tLWZvcm1hdDwvY29tbWVudD4gb3B0aW9uOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSAtLWZvcm1hdD14bWw8L2luZm8+CgpJdCdzIGFsc28gcG9zc2libGUgdG8gZ2V0IHJhdyBsaXN0IG9mIGNvbW1hbmRzICh1c2VmdWwgZm9yIGVtYmVkZGluZyBjb21tYW5kIHJ1bm5lcik6CgogIDxpbmZvPnBocCAlY29tbWFuZC5mdWxsX25hbWUlIC0tcmF3PC9pbmZvPgpFT0YKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hdGl2ZURlZmluaXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y3JlYXRlRGVmaW5pdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgICRoZWxwZXIgPSBuZXcgRGVzY3JpcHRvckhlbHBlcigpOwogICAgICAgICRoZWxwZXItPmRlc2NyaWJlKCRvdXRwdXQsICR0aGlzLT5nZXRBcHBsaWNhdGlvbigpLCBbCiAgICAgICAgICAgICdmb3JtYXQnID0+ICRpbnB1dC0+Z2V0T3B0aW9uKCdmb3JtYXQnKSwKICAgICAgICAgICAgJ3Jhd190ZXh0JyA9PiAkaW5wdXQtPmdldE9wdGlvbigncmF3JyksCiAgICAgICAgICAgICduYW1lc3BhY2UnID0+ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ25hbWVzcGFjZScpLAogICAgICAgIF0pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZURlZmluaXRpb24oKQogICAgewogICAgICAgIHJldHVybiBuZXcgSW5wdXREZWZpbml0aW9uKFsKICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ25hbWVzcGFjZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIG5hbWVzcGFjZSBuYW1lJyksCiAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbigncmF3JywgbnVsbCwgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdUbyBvdXRwdXQgcmF3IGNvbW1hbmQgbGlzdCcpLAogICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1RoZSBvdXRwdXQgZm9ybWF0ICh0eHQsIHhtbCwganNvbiwgb3IgbWQpJywgJ3R4dCcpLAogICAgICAgIF0pOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQXBwbGljYXRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxFeGNlcHRpb25JbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlclNldDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRBcmd1bWVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXREZWZpbml0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRPcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQmFzZSBjbGFzcyBmb3IgYWxsIGNvbW1hbmRzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIENvbW1hbmQKewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsIFRoZSBkZWZhdWx0IGNvbW1hbmQgbmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRkZWZhdWx0TmFtZTsKCiAgICBwcml2YXRlICRhcHBsaWNhdGlvbjsKICAgIHByaXZhdGUgJG5hbWU7CiAgICBwcml2YXRlICRwcm9jZXNzVGl0bGU7CiAgICBwcml2YXRlICRhbGlhc2VzID0gW107CiAgICBwcml2YXRlICRkZWZpbml0aW9uOwogICAgcHJpdmF0ZSAkaGlkZGVuID0gZmFsc2U7CiAgICBwcml2YXRlICRoZWxwID0gJyc7CiAgICBwcml2YXRlICRkZXNjcmlwdGlvbiA9ICcnOwogICAgcHJpdmF0ZSAkaWdub3JlVmFsaWRhdGlvbkVycm9ycyA9IGZhbHNlOwogICAgcHJpdmF0ZSAkYXBwbGljYXRpb25EZWZpbml0aW9uTWVyZ2VkID0gZmFsc2U7CiAgICBwcml2YXRlICRhcHBsaWNhdGlvbkRlZmluaXRpb25NZXJnZWRXaXRoQXJncyA9IGZhbHNlOwogICAgcHJpdmF0ZSAkY29kZTsKICAgIHByaXZhdGUgJHN5bm9wc2lzID0gW107CiAgICBwcml2YXRlICR1c2FnZXMgPSBbXTsKICAgIHByaXZhdGUgJGhlbHBlclNldDsKCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIGRlZmF1bHQgY29tbWFuZCBuYW1lIG9yIG51bGwgd2hlbiBubyBkZWZhdWx0IG5hbWUgaXMgc2V0CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVmYXVsdE5hbWUoKQogICAgewogICAgICAgICRjbGFzcyA9IHN0YXRpYzo6Y2xhc3M7CiAgICAgICAgJHIgPSBuZXcgXFJlZmxlY3Rpb25Qcm9wZXJ0eSgkY2xhc3MsICdkZWZhdWx0TmFtZScpOwoKICAgICAgICByZXR1cm4gJGNsYXNzID09PSAkci0+Y2xhc3MgPyBzdGF0aWM6OiRkZWZhdWx0TmFtZSA6IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJG5hbWUgVGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQ7IHBhc3NpbmcgbnVsbCBtZWFucyBpdCBtdXN0IGJlIHNldCBpbiBjb25maWd1cmUoKQogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gV2hlbiB0aGUgY29tbWFuZCBuYW1lIGlzIGVtcHR5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlZmluaXRpb24gPSBuZXcgSW5wdXREZWZpbml0aW9uKCk7CgogICAgICAgIGlmIChudWxsICE9PSAkbmFtZSB8fCBudWxsICE9PSAkbmFtZSA9IHN0YXRpYzo6Z2V0RGVmYXVsdE5hbWUoKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0TmFtZSgkbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29uZmlndXJlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJZ25vcmVzIHZhbGlkYXRpb24gZXJyb3JzLgogICAgICoKICAgICAqIFRoaXMgaXMgbWFpbmx5IHVzZWZ1bCBmb3IgdGhlIGhlbHAgY29tbWFuZC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlnbm9yZVZhbGlkYXRpb25FcnJvcnMoKQogICAgewogICAgICAgICR0aGlzLT5pZ25vcmVWYWxpZGF0aW9uRXJyb3JzID0gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXBwbGljYXRpb24oQXBwbGljYXRpb24gJGFwcGxpY2F0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+YXBwbGljYXRpb24gPSAkYXBwbGljYXRpb247CiAgICAgICAgaWYgKCRhcHBsaWNhdGlvbikgewogICAgICAgICAgICAkdGhpcy0+c2V0SGVscGVyU2V0KCRhcHBsaWNhdGlvbi0+Z2V0SGVscGVyU2V0KCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5oZWxwZXJTZXQgPSBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVscGVyU2V0KEhlbHBlclNldCAkaGVscGVyU2V0KQogICAgewogICAgICAgICR0aGlzLT5oZWxwZXJTZXQgPSAkaGVscGVyU2V0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgaGVscGVyIHNldC4KICAgICAqCiAgICAgKiBAcmV0dXJuIEhlbHBlclNldHxudWxsIEEgSGVscGVyU2V0IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWxwZXJTZXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGVscGVyU2V0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgYXBwbGljYXRpb24gaW5zdGFuY2UgZm9yIHRoaXMgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIEFwcGxpY2F0aW9ufG51bGwgQW4gQXBwbGljYXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFwcGxpY2F0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFwcGxpY2F0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGNvbW1hbmQgaXMgZW5hYmxlZCBvciBub3QgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKgogICAgICogT3ZlcnJpZGUgdGhpcyB0byBjaGVjayBmb3IgeCBvciB5IGFuZCByZXR1cm4gZmFsc2UgaWYgdGhlIGNvbW1hbmQgY2FuIG5vdAogICAgICogcnVuIHByb3Blcmx5IHVuZGVyIHRoZSBjdXJyZW50IGNvbmRpdGlvbnMuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0VuYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQ29uZmlndXJlcyB0aGUgY3VycmVudCBjb21tYW5kLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSBjdXJyZW50IGNvbW1hbmQuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgaXMgbm90IGFic3RyYWN0IGJlY2F1c2UgeW91IGNhbiB1c2UgdGhpcyBjbGFzcwogICAgICogYXMgYSBjb25jcmV0ZSBjbGFzcy4gSW4gdGhpcyBjYXNlLCBpbnN0ZWFkIG9mIGRlZmluaW5nIHRoZQogICAgICogZXhlY3V0ZSgpIG1ldGhvZCwgeW91IHNldCB0aGUgY29kZSB0byBleGVjdXRlIGJ5IHBhc3NpbmcKICAgICAqIGEgQ2xvc3VyZSB0byB0aGUgc2V0Q29kZSgpIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxudWxsIG51bGwgb3IgMCBpZiBldmVyeXRoaW5nIHdlbnQgZmluZSwgb3IgYW4gZXJyb3IgY29kZQogICAgICoKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gV2hlbiB0aGlzIGFic3RyYWN0IG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQKICAgICAqCiAgICAgKiBAc2VlIHNldENvZGUoKQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY3V0ZShJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignWW91IG11c3Qgb3ZlcnJpZGUgdGhlIGV4ZWN1dGUoKSBtZXRob2QgaW4gdGhlIGNvbmNyZXRlIGNvbW1hbmQgY2xhc3MuJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcmFjdHMgd2l0aCB0aGUgdXNlci4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBleGVjdXRlZCBiZWZvcmUgdGhlIElucHV0RGVmaW5pdGlvbiBpcyB2YWxpZGF0ZWQuCiAgICAgKiBUaGlzIG1lYW5zIHRoYXQgdGhpcyBpcyB0aGUgb25seSBwbGFjZSB3aGVyZSB0aGUgY29tbWFuZCBjYW4KICAgICAqIGludGVyYWN0aXZlbHkgYXNrIGZvciB2YWx1ZXMgb2YgbWlzc2luZyByZXF1aXJlZCBhcmd1bWVudHMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbnRlcmFjdChJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbW1hbmQgYWZ0ZXIgdGhlIGlucHV0IGhhcyBiZWVuIGJvdW5kIGFuZCBiZWZvcmUgdGhlIGlucHV0CiAgICAgKiBpcyB2YWxpZGF0ZWQuCiAgICAgKgogICAgICogVGhpcyBpcyBtYWlubHkgdXNlZnVsIHdoZW4gYSBsb3Qgb2YgY29tbWFuZHMgZXh0ZW5kcyBvbmUgbWFpbiBjb21tYW5kCiAgICAgKiB3aGVyZSBzb21lIHRoaW5ncyBuZWVkIHRvIGJlIGluaXRpYWxpemVkIGJhc2VkIG9uIHRoZSBpbnB1dCBhcmd1bWVudHMgYW5kIG9wdGlvbnMuCiAgICAgKgogICAgICogQHNlZSBJbnB1dEludGVyZmFjZTo6YmluZCgpCiAgICAgKiBAc2VlIElucHV0SW50ZXJmYWNlOjp2YWxpZGF0ZSgpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbml0aWFsaXplKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIFRoZSBjb2RlIHRvIGV4ZWN1dGUgaXMgZWl0aGVyIGRlZmluZWQgZGlyZWN0bHkgd2l0aCB0aGUKICAgICAqIHNldENvZGUoKSBtZXRob2Qgb3IgYnkgb3ZlcnJpZGluZyB0aGUgZXhlY3V0ZSgpIG1ldGhvZAogICAgICogaW4gYSBzdWItY2xhc3MuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIGNvbW1hbmQgZXhpdCBjb2RlCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIFdoZW4gYmluZGluZyBpbnB1dCBmYWlscy4gQnlwYXNzIHRoaXMgYnkgY2FsbGluZyB7QGxpbmsgaWdub3JlVmFsaWRhdGlvbkVycm9ycygpfS4KICAgICAqCiAgICAgKiBAc2VlIHNldENvZGUoKQogICAgICogQHNlZSBleGVjdXRlKCkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJ1bihJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIC8vIGZvcmNlIHRoZSBjcmVhdGlvbiBvZiB0aGUgc3lub3BzaXMgYmVmb3JlIHRoZSBtZXJnZSB3aXRoIHRoZSBhcHAgZGVmaW5pdGlvbgogICAgICAgICR0aGlzLT5nZXRTeW5vcHNpcyh0cnVlKTsKICAgICAgICAkdGhpcy0+Z2V0U3lub3BzaXMoZmFsc2UpOwoKICAgICAgICAvLyBhZGQgdGhlIGFwcGxpY2F0aW9uIGFyZ3VtZW50cyBhbmQgb3B0aW9ucwogICAgICAgICR0aGlzLT5tZXJnZUFwcGxpY2F0aW9uRGVmaW5pdGlvbigpOwoKICAgICAgICAvLyBiaW5kIHRoZSBpbnB1dCBhZ2FpbnN0IHRoZSBjb21tYW5kIHNwZWNpZmljIGFyZ3VtZW50cy9vcHRpb25zCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGlucHV0LT5iaW5kKCR0aGlzLT5kZWZpbml0aW9uKTsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb25JbnRlcmZhY2UgJGUpIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aWdub3JlVmFsaWRhdGlvbkVycm9ycykgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+cHJvY2Vzc1RpdGxlKSB7CiAgICAgICAgICAgIGlmIChcZnVuY3Rpb25fZXhpc3RzKCdjbGlfc2V0X3Byb2Nlc3NfdGl0bGUnKSkgewogICAgICAgICAgICAgICAgaWYgKCFAY2xpX3NldF9wcm9jZXNzX3RpdGxlKCR0aGlzLT5wcm9jZXNzVGl0bGUpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCdEYXJ3aW4nID09PSBcUEhQX09TKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJzxjb21tZW50PlJ1bm5pbmcgImNsaV9zZXRfcHJvY2Vzc190aXRsZSIgYXMgYW4gdW5wcml2aWxlZ2VkIHVzZXIgaXMgbm90IHN1cHBvcnRlZCBvbiBNYWNPUy48L2NvbW1lbnQ+JywgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSWV9WRVJCT1NFKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjbGlfc2V0X3Byb2Nlc3NfdGl0bGUoJHRoaXMtPnByb2Nlc3NUaXRsZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoXGZ1bmN0aW9uX2V4aXN0cygnc2V0cHJvY3RpdGxlJykpIHsKICAgICAgICAgICAgICAgIHNldHByb2N0aXRsZSgkdGhpcy0+cHJvY2Vzc1RpdGxlKTsKICAgICAgICAgICAgfSBlbHNlaWYgKE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSA9PT0gJG91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJzxjb21tZW50Pkluc3RhbGwgdGhlIHByb2N0aXRsZSBQRUNMIHRvIGJlIGFibGUgdG8gY2hhbmdlIHRoZSBwcm9jZXNzIHRpdGxlLjwvY29tbWVudD4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRpbnB1dC0+aXNJbnRlcmFjdGl2ZSgpKSB7CiAgICAgICAgICAgICR0aGlzLT5pbnRlcmFjdCgkaW5wdXQsICRvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgLy8gVGhlIGNvbW1hbmQgbmFtZSBhcmd1bWVudCBpcyBvZnRlbiBvbWl0dGVkIHdoZW4gYSBjb21tYW5kIGlzIGV4ZWN1dGVkIGRpcmVjdGx5IHdpdGggaXRzIHJ1bigpIG1ldGhvZC4KICAgICAgICAvLyBJdCB3b3VsZCBmYWlsIHRoZSB2YWxpZGF0aW9uIGlmIHdlIGRpZG4ndCBtYWtlIHN1cmUgdGhlIGNvbW1hbmQgYXJndW1lbnQgaXMgcHJlc2VudCwKICAgICAgICAvLyBzaW5jZSBpdCdzIHJlcXVpcmVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4KICAgICAgICBpZiAoJGlucHV0LT5oYXNBcmd1bWVudCgnY29tbWFuZCcpICYmIG51bGwgPT09ICRpbnB1dC0+Z2V0QXJndW1lbnQoJ2NvbW1hbmQnKSkgewogICAgICAgICAgICAkaW5wdXQtPnNldEFyZ3VtZW50KCdjb21tYW5kJywgJHRoaXMtPmdldE5hbWUoKSk7CiAgICAgICAgfQoKICAgICAgICAkaW5wdXQtPnZhbGlkYXRlKCk7CgogICAgICAgIGlmICgkdGhpcy0+Y29kZSkgewogICAgICAgICAgICAkc3RhdHVzQ29kZSA9IFxjYWxsX3VzZXJfZnVuYygkdGhpcy0+Y29kZSwgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc3RhdHVzQ29kZSA9ICR0aGlzLT5leGVjdXRlKCRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNfbnVtZXJpYygkc3RhdHVzQ29kZSkgPyAoaW50KSAkc3RhdHVzQ29kZSA6IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb2RlIHRvIGV4ZWN1dGUgd2hlbiBydW5uaW5nIHRoaXMgY29tbWFuZC4KICAgICAqCiAgICAgKiBJZiB0aGlzIG1ldGhvZCBpcyB1c2VkLCBpdCBvdmVycmlkZXMgdGhlIGNvZGUgZGVmaW5lZAogICAgICogaW4gdGhlIGV4ZWN1dGUoKSBtZXRob2QuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRjb2RlIEEgY2FsbGFibGUoSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAc2VlIGV4ZWN1dGUoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29kZShjYWxsYWJsZSAkY29kZSkKICAgIHsKICAgICAgICBpZiAoJGNvZGUgaW5zdGFuY2VvZiBcQ2xvc3VyZSkgewogICAgICAgICAgICAkciA9IG5ldyBcUmVmbGVjdGlvbkZ1bmN0aW9uKCRjb2RlKTsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRyLT5nZXRDbG9zdXJlVGhpcygpKSB7CiAgICAgICAgICAgICAgICBpZiAoXFBIUF9WRVJTSU9OX0lEIDwgNzAwMDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBCdWcgaW4gUEhQNTogaHR0cHM6Ly9idWdzLnBocC5uZXQvNjQ3NjEKICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIG1lYW5zIHRoYXQgd2UgY2Fubm90IGJpbmQgc3RhdGljIGNsb3N1cmVzIGFuZCB0aGVyZWZvcmUgd2UgbXVzdAogICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBhbnkgZXJyb3JzIGhlcmUuICBUaGVyZSBpcyBubyB3YXkgdG8gdGVzdCBpZiB0aGUgY2xvc3VyZSBpcwogICAgICAgICAgICAgICAgICAgIC8vIGJpbmRhYmxlLgogICAgICAgICAgICAgICAgICAgICRjb2RlID0gQFxDbG9zdXJlOjpiaW5kKCRjb2RlLCAkdGhpcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjb2RlID0gXENsb3N1cmU6OmJpbmQoJGNvZGUsICR0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvZGUgPSAkY29kZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIHRoZSBhcHBsaWNhdGlvbiBkZWZpbml0aW9uIHdpdGggdGhlIGNvbW1hbmQgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBub3QgcGFydCBvZiBwdWJsaWMgQVBJIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgZGlyZWN0bHkuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG1lcmdlQXJncyBXaGV0aGVyIHRvIG1lcmdlIG9yIG5vdCB0aGUgQXBwbGljYXRpb24gZGVmaW5pdGlvbiBhcmd1bWVudHMgdG8gQ29tbWFuZCBkZWZpbml0aW9uIGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWVyZ2VBcHBsaWNhdGlvbkRlZmluaXRpb24oJG1lcmdlQXJncyA9IHRydWUpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5hcHBsaWNhdGlvbiB8fCAodHJ1ZSA9PT0gJHRoaXMtPmFwcGxpY2F0aW9uRGVmaW5pdGlvbk1lcmdlZCAmJiAoJHRoaXMtPmFwcGxpY2F0aW9uRGVmaW5pdGlvbk1lcmdlZFdpdGhBcmdzIHx8ICEkbWVyZ2VBcmdzKSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmRlZmluaXRpb24tPmFkZE9wdGlvbnMoJHRoaXMtPmFwcGxpY2F0aW9uLT5nZXREZWZpbml0aW9uKCktPmdldE9wdGlvbnMoKSk7CgogICAgICAgICR0aGlzLT5hcHBsaWNhdGlvbkRlZmluaXRpb25NZXJnZWQgPSB0cnVlOwoKICAgICAgICBpZiAoJG1lcmdlQXJncykgewogICAgICAgICAgICAkY3VycmVudEFyZ3VtZW50cyA9ICR0aGlzLT5kZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKTsKICAgICAgICAgICAgJHRoaXMtPmRlZmluaXRpb24tPnNldEFyZ3VtZW50cygkdGhpcy0+YXBwbGljYXRpb24tPmdldERlZmluaXRpb24oKS0+Z2V0QXJndW1lbnRzKCkpOwogICAgICAgICAgICAkdGhpcy0+ZGVmaW5pdGlvbi0+YWRkQXJndW1lbnRzKCRjdXJyZW50QXJndW1lbnRzKTsKCiAgICAgICAgICAgICR0aGlzLT5hcHBsaWNhdGlvbkRlZmluaXRpb25NZXJnZWRXaXRoQXJncyA9IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhbiBhcnJheSBvZiBhcmd1bWVudCBhbmQgb3B0aW9uIGluc3RhbmNlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXl8SW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uIEFuIGFycmF5IG9mIGFyZ3VtZW50IGFuZCBvcHRpb24gaW5zdGFuY2VzIG9yIGEgZGVmaW5pdGlvbiBpbnN0YW5jZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlZmluaXRpb24oJGRlZmluaXRpb24pCiAgICB7CiAgICAgICAgaWYgKCRkZWZpbml0aW9uIGluc3RhbmNlb2YgSW5wdXREZWZpbml0aW9uKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWZpbml0aW9uID0gJGRlZmluaXRpb247CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPmRlZmluaXRpb24tPnNldERlZmluaXRpb24oJGRlZmluaXRpb24pOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFwcGxpY2F0aW9uRGVmaW5pdGlvbk1lcmdlZCA9IGZhbHNlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBJbnB1dERlZmluaXRpb24gYXR0YWNoZWQgdG8gdGhpcyBDb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXREZWZpbml0aW9uIEFuIElucHV0RGVmaW5pdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5kZWZpbml0aW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdDb21tYW5kIGNsYXNzICIlcyIgaXMgbm90IGNvcnJlY3RseSBpbml0aWFsaXplZC4gWW91IHByb2JhYmx5IGZvcmdvdCB0byBjYWxsIHRoZSBwYXJlbnQgY29uc3RydWN0b3IuJywgc3RhdGljOjpjbGFzcykpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWZpbml0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgSW5wdXREZWZpbml0aW9uIHRvIGJlIHVzZWQgdG8gY3JlYXRlIHJlcHJlc2VudGF0aW9ucyBvZiB0aGlzIENvbW1hbmQuCiAgICAgKgogICAgICogQ2FuIGJlIG92ZXJyaWRkZW4gdG8gcHJvdmlkZSB0aGUgb3JpZ2luYWwgY29tbWFuZCByZXByZXNlbnRhdGlvbiB3aGVuIGl0IHdvdWxkIG90aGVyd2lzZQogICAgICogYmUgY2hhbmdlZCBieSBtZXJnaW5nIHdpdGggdGhlIGFwcGxpY2F0aW9uIElucHV0RGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBub3QgcGFydCBvZiBwdWJsaWMgQVBJIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgZGlyZWN0bHkuCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dERlZmluaXRpb24gQW4gSW5wdXREZWZpbml0aW9uIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYXRpdmVEZWZpbml0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldERlZmluaXRpb24oKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYW4gYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICRuYW1lICAgICAgICBUaGUgYXJndW1lbnQgbmFtZQogICAgICogQHBhcmFtIGludHxudWxsICAgICAgICAgICAgICRtb2RlICAgICAgICBUaGUgYXJndW1lbnQgbW9kZTogSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQgb3IgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAkZGVzY3JpcHRpb24gQSBkZXNjcmlwdGlvbiB0ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfG51bGwgJGRlZmF1bHQgICAgIFRoZSBkZWZhdWx0IHZhbHVlIChmb3IgSW5wdXRBcmd1bWVudDo6T1BUSU9OQUwgbW9kZSBvbmx5KQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYXJndW1lbnQgbW9kZSBpcyBub3QgdmFsaWQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRBcmd1bWVudCgkbmFtZSwgJG1vZGUgPSBudWxsLCAkZGVzY3JpcHRpb24gPSAnJywgJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5kZWZpbml0aW9uLT5hZGRBcmd1bWVudChuZXcgSW5wdXRBcmd1bWVudCgkbmFtZSwgJG1vZGUsICRkZXNjcmlwdGlvbiwgJGRlZmF1bHQpKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhbiBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRuYW1lICAgICAgICBUaGUgb3B0aW9uIG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXl8bnVsbCAgICAgICAgICAgICAkc2hvcnRjdXQgICAgVGhlIHNob3J0Y3V0cywgY2FuIGJlIG51bGwsIGEgc3RyaW5nIG9mIHNob3J0Y3V0cyBkZWxpbWl0ZWQgYnkgfCBvciBhbiBhcnJheSBvZiBzaG9ydGN1dHMKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAgICAgICAgICAgICAgICAgICAgICAkbW9kZSAgICAgICAgVGhlIG9wdGlvbiBtb2RlOiBPbmUgb2YgdGhlIElucHV0T3B0aW9uOjpWQUxVRV8qIGNvbnN0YW50cwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW118aW50fGJvb2x8bnVsbCAkZGVmYXVsdCAgICAgVGhlIGRlZmF1bHQgdmFsdWUgKG11c3QgYmUgbnVsbCBmb3IgSW5wdXRPcHRpb246OlZBTFVFX05PTkUpCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgb3B0aW9uIG1vZGUgaXMgaW52YWxpZCBvciBpbmNvbXBhdGlibGUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRPcHRpb24oJG5hbWUsICRzaG9ydGN1dCA9IG51bGwsICRtb2RlID0gbnVsbCwgJGRlc2NyaXB0aW9uID0gJycsICRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGVmaW5pdGlvbi0+YWRkT3B0aW9uKG5ldyBJbnB1dE9wdGlvbigkbmFtZSwgJHNob3J0Y3V0LCAkbW9kZSwgJGRlc2NyaXB0aW9uLCAkZGVmYXVsdCkpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGNhbiBzZXQgYm90aCB0aGUgbmFtZXNwYWNlIGFuZCB0aGUgbmFtZSBpZgogICAgICogeW91IHNlcGFyYXRlIHRoZW0gYnkgYSBjb2xvbiAoOikKICAgICAqCiAgICAgKiAgICAgJGNvbW1hbmQtPnNldE5hbWUoJ2ZvbzpiYXInKTsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBjb21tYW5kIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUgbmFtZSBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT52YWxpZGF0ZU5hbWUoJG5hbWUpOwoKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9jZXNzIHRpdGxlIG9mIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIFRoaXMgZmVhdHVyZSBzaG91bGQgYmUgdXNlZCBvbmx5IHdoZW4gY3JlYXRpbmcgYSBsb25nIHByb2Nlc3MgY29tbWFuZCwKICAgICAqIGxpa2UgYSBkYWVtb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdGl0bGUgVGhlIHByb2Nlc3MgdGl0bGUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9jZXNzVGl0bGUoJHRpdGxlKQogICAgewogICAgICAgICR0aGlzLT5wcm9jZXNzVGl0bGUgPSAkdGl0bGU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1hbmQgbmFtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkaGlkZGVuIFdoZXRoZXIgb3Igbm90IHRoZSBjb21tYW5kIHNob3VsZCBiZSBoaWRkZW4gZnJvbSB0aGUgbGlzdCBvZiBjb21tYW5kcwogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZCBUaGUgY3VycmVudCBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGlkZGVuKCRoaWRkZW4pCiAgICB7CiAgICAgICAgJHRoaXMtPmhpZGRlbiA9IChib29sKSAkaGlkZGVuOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wgd2hldGhlciB0aGUgY29tbWFuZCBzaG91bGQgYmUgcHVibGljbHkgc2hvd24gb3Igbm90CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hpZGRlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oaWRkZW47CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZGVzY3JpcHRpb24gVGhlIGRlc2NyaXB0aW9uIGZvciB0aGUgY29tbWFuZAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlc2NyaXB0aW9uKCRkZXNjcmlwdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+ZGVzY3JpcHRpb24gPSAkZGVzY3JpcHRpb247CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIGZvciB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgZGVzY3JpcHRpb24gZm9yIHRoZSBjb21tYW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGhlbHAgZm9yIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGhlbHAgVGhlIGhlbHAgZm9yIHRoZSBjb21tYW5kCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGVscCgkaGVscCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVscCA9ICRoZWxwOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBoZWxwIGZvciB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgaGVscCBmb3IgdGhlIGNvbW1hbmQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlbHAoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aGVscDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb2Nlc3NlZCBoZWxwIGZvciB0aGUgY29tbWFuZCByZXBsYWNpbmcgdGhlICVjb21tYW5kLm5hbWUlIGFuZAogICAgICogJWNvbW1hbmQuZnVsbF9uYW1lJSBwYXR0ZXJucyB3aXRoIHRoZSByZWFsIHZhbHVlcyBkeW5hbWljYWxseS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgcHJvY2Vzc2VkIGhlbHAgZm9yIHRoZSBjb21tYW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9jZXNzZWRIZWxwKCkKICAgIHsKICAgICAgICAkbmFtZSA9ICR0aGlzLT5uYW1lOwogICAgICAgICRpc1NpbmdsZUNvbW1hbmQgPSAkdGhpcy0+YXBwbGljYXRpb24gJiYgJHRoaXMtPmFwcGxpY2F0aW9uLT5pc1NpbmdsZUNvbW1hbmQoKTsKCiAgICAgICAgJHBsYWNlaG9sZGVycyA9IFsKICAgICAgICAgICAgJyVjb21tYW5kLm5hbWUlJywKICAgICAgICAgICAgJyVjb21tYW5kLmZ1bGxfbmFtZSUnLAogICAgICAgIF07CiAgICAgICAgJHJlcGxhY2VtZW50cyA9IFsKICAgICAgICAgICAgJG5hbWUsCiAgICAgICAgICAgICRpc1NpbmdsZUNvbW1hbmQgPyAkX1NFUlZFUlsnUEhQX1NFTEYnXSA6ICRfU0VSVkVSWydQSFBfU0VMRiddLicgJy4kbmFtZSwKICAgICAgICBdOwoKICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJHBsYWNlaG9sZGVycywgJHJlcGxhY2VtZW50cywgJHRoaXMtPmdldEhlbHAoKSA/OiAkdGhpcy0+Z2V0RGVzY3JpcHRpb24oKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhbGlhc2VzIGZvciB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGFsaWFzZXMgQW4gYXJyYXkgb2YgYWxpYXNlcyBmb3IgdGhlIGNvbW1hbmQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBhbiBhbGlhcyBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBbGlhc2VzKCRhbGlhc2VzKQogICAgewogICAgICAgIGlmICghXGlzX2FycmF5KCRhbGlhc2VzKSAmJiAhJGFsaWFzZXMgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignJGFsaWFzZXMgbXVzdCBiZSBhbiBhcnJheSBvciBhbiBpbnN0YW5jZSBvZiBcVHJhdmVyc2FibGUuJyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkYWxpYXNlcyBhcyAkYWxpYXMpIHsKICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlTmFtZSgkYWxpYXMpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFsaWFzZXMgPSAkYWxpYXNlczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWxpYXNlcyBmb3IgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBBbiBhcnJheSBvZiBhbGlhc2VzIGZvciB0aGUgY29tbWFuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxpYXNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbGlhc2VzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3lub3BzaXMgZm9yIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRzaG9ydCBXaGV0aGVyIHRvIHNob3cgdGhlIHNob3J0IHZlcnNpb24gb2YgdGhlIHN5bm9wc2lzICh3aXRoIG9wdGlvbnMgZm9sZGVkKSBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgc3lub3BzaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN5bm9wc2lzKCRzaG9ydCA9IGZhbHNlKQogICAgewogICAgICAgICRrZXkgPSAkc2hvcnQgPyAnc2hvcnQnIDogJ2xvbmcnOwoKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5zeW5vcHNpc1ska2V5XSkpIHsKICAgICAgICAgICAgJHRoaXMtPnN5bm9wc2lzWyRrZXldID0gdHJpbShzcHJpbnRmKCclcyAlcycsICR0aGlzLT5uYW1lLCAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0U3lub3BzaXMoJHNob3J0KSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5zeW5vcHNpc1ska2V5XTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIGNvbW1hbmQgdXNhZ2UgZXhhbXBsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1c2FnZSBUaGUgdXNhZ2UsIGl0J2xsIGJlIHByZWZpeGVkIHdpdGggdGhlIGNvbW1hbmQgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFVzYWdlKCR1c2FnZSkKICAgIHsKICAgICAgICBpZiAoMCAhPT0gc3RycG9zKCR1c2FnZSwgJHRoaXMtPm5hbWUpKSB7CiAgICAgICAgICAgICR1c2FnZSA9IHNwcmludGYoJyVzICVzJywgJHRoaXMtPm5hbWUsICR1c2FnZSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dXNhZ2VzW10gPSAkdXNhZ2U7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWx0ZXJuYXRpdmUgdXNhZ2VzIG9mIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVzYWdlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51c2FnZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGEgaGVscGVyIGluc3RhbmNlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgaGVscGVyIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkIFRoZSBoZWxwZXIgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uICAgICAgICAgICBpZiBubyBIZWxwZXJTZXQgaXMgZGVmaW5lZAogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGhlbHBlciBpcyBub3QgZGVmaW5lZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyKCRuYW1lKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+aGVscGVyU2V0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdDYW5ub3QgcmV0cmlldmUgaGVscGVyICIlcyIgYmVjYXVzZSB0aGVyZSBpcyBubyBIZWxwZXJTZXQgZGVmaW5lZC4gRGlkIHlvdSBmb3JnZXQgdG8gYWRkIHlvdXIgY29tbWFuZCB0byB0aGUgYXBwbGljYXRpb24gb3IgdG8gc2V0IHRoZSBhcHBsaWNhdGlvbiBvbiB0aGUgY29tbWFuZCB1c2luZyB0aGUgc2V0QXBwbGljYXRpb24oKSBtZXRob2Q/IFlvdSBjYW4gYWxzbyBzZXQgdGhlIEhlbHBlclNldCBkaXJlY3RseSB1c2luZyB0aGUgc2V0SGVscGVyU2V0KCkgbWV0aG9kLicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmhlbHBlclNldC0+Z2V0KCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyBhIGNvbW1hbmQgbmFtZS4KICAgICAqCiAgICAgKiBJdCBtdXN0IGJlIG5vbi1lbXB0eSBhbmQgcGFydHMgY2FuIG9wdGlvbmFsbHkgYmUgc2VwYXJhdGVkIGJ5ICI6Ii4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUgbmFtZSBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdmFsaWRhdGVOYW1lKCRuYW1lKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL15bXlw6XSsrKFw6W15cOl0rKykqJC8nLCAkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdDb21tYW5kIG5hbWUgIiVzIiBpcyBpbnZhbGlkLicsICRuYW1lKSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXERlc2NyaXB0b3JIZWxwZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dE9wdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBIZWxwQ29tbWFuZCBkaXNwbGF5cyB0aGUgaGVscCBmb3IgYSBnaXZlbiBjb21tYW5kLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEhlbHBDb21tYW5kIGV4dGVuZHMgQ29tbWFuZAp7CiAgICBwcml2YXRlICRjb21tYW5kOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uZmlndXJlKCkKICAgIHsKICAgICAgICAkdGhpcy0+aWdub3JlVmFsaWRhdGlvbkVycm9ycygpOwoKICAgICAgICAkdGhpcwogICAgICAgICAgICAtPnNldE5hbWUoJ2hlbHAnKQogICAgICAgICAgICAtPnNldERlZmluaXRpb24oWwogICAgICAgICAgICAgICAgbmV3IElucHV0QXJndW1lbnQoJ2NvbW1hbmRfbmFtZScsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAnVGhlIGNvbW1hbmQgbmFtZScsICdoZWxwJyksCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRPcHRpb24oJ2Zvcm1hdCcsIG51bGwsIElucHV0T3B0aW9uOjpWQUxVRV9SRVFVSVJFRCwgJ1RoZSBvdXRwdXQgZm9ybWF0ICh0eHQsIHhtbCwganNvbiwgb3IgbWQpJywgJ3R4dCcpLAogICAgICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCdyYXcnLCBudWxsLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ1RvIG91dHB1dCByYXcgY29tbWFuZCBoZWxwJyksCiAgICAgICAgICAgIF0pCiAgICAgICAgICAgIC0+c2V0RGVzY3JpcHRpb24oJ0Rpc3BsYXlzIGhlbHAgZm9yIGEgY29tbWFuZCcpCiAgICAgICAgICAgIC0+c2V0SGVscCg8PDwnRU9GJwpUaGUgPGluZm8+JWNvbW1hbmQubmFtZSU8L2luZm8+IGNvbW1hbmQgZGlzcGxheXMgaGVscCBmb3IgYSBnaXZlbiBjb21tYW5kOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSBsaXN0PC9pbmZvPgoKWW91IGNhbiBhbHNvIG91dHB1dCB0aGUgaGVscCBpbiBvdGhlciBmb3JtYXRzIGJ5IHVzaW5nIHRoZSA8Y29tbWVudD4tLWZvcm1hdDwvY29tbWVudD4gb3B0aW9uOgoKICA8aW5mbz5waHAgJWNvbW1hbmQuZnVsbF9uYW1lJSAtLWZvcm1hdD14bWwgbGlzdDwvaW5mbz4KClRvIGRpc3BsYXkgdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIGNvbW1hbmRzLCBwbGVhc2UgdXNlIHRoZSA8aW5mbz5saXN0PC9pbmZvPiBjb21tYW5kLgpFT0YKICAgICAgICAgICAgKQogICAgICAgIDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tbWFuZChDb21tYW5kICRjb21tYW5kKQogICAgewogICAgICAgICR0aGlzLT5jb21tYW5kID0gJGNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBleGVjdXRlKElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5jb21tYW5kKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21tYW5kID0gJHRoaXMtPmdldEFwcGxpY2F0aW9uKCktPmZpbmQoJGlucHV0LT5nZXRBcmd1bWVudCgnY29tbWFuZF9uYW1lJykpOwogICAgICAgIH0KCiAgICAgICAgJGhlbHBlciA9IG5ldyBEZXNjcmlwdG9ySGVscGVyKCk7CiAgICAgICAgJGhlbHBlci0+ZGVzY3JpYmUoJG91dHB1dCwgJHRoaXMtPmNvbW1hbmQsIFsKICAgICAgICAgICAgJ2Zvcm1hdCcgPT4gJGlucHV0LT5nZXRPcHRpb24oJ2Zvcm1hdCcpLAogICAgICAgICAgICAncmF3X3RleHQnID0+ICRpbnB1dC0+Z2V0T3B0aW9uKCdyYXcnKSwKICAgICAgICBdKTsKCiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSBudWxsOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcRmFjdG9yeTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcTG9jazsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcRmxvY2tTdG9yZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XExvY2tcU3RvcmVcU2VtYXBob3JlU3RvcmU7CgovKioKICogQmFzaWMgbG9jayBmZWF0dXJlIGZvciBjb21tYW5kcy4KICoKICogQGF1dGhvciBHZW9mZnJleSBCcmllciA8Z2VvZmZyZXkuYnJpZXJAZ21haWwuY29tPgogKi8KdHJhaXQgTG9ja2FibGVUcmFpdAp7CiAgICAvKiogQHZhciBMb2NrICovCiAgICBwcml2YXRlICRsb2NrOwoKICAgIC8qKgogICAgICogTG9ja3MgYSBjb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGxvY2soJG5hbWUgPSBudWxsLCAkYmxvY2tpbmcgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIWNsYXNzX2V4aXN0cyhTZW1hcGhvcmVTdG9yZTo6Y2xhc3MpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCdUbyBlbmFibGUgdGhlIGxvY2tpbmcgZmVhdHVyZSB5b3UgbXVzdCBpbnN0YWxsIHRoZSBzeW1mb255L2xvY2sgY29tcG9uZW50LicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5sb2NrKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSBsb2NrIGlzIGFscmVhZHkgaW4gcGxhY2UuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoU2VtYXBob3JlU3RvcmU6OmlzU3VwcG9ydGVkKCRibG9ja2luZykpIHsKICAgICAgICAgICAgJHN0b3JlID0gbmV3IFNlbWFwaG9yZVN0b3JlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHN0b3JlID0gbmV3IEZsb2NrU3RvcmUoKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5sb2NrID0gKG5ldyBGYWN0b3J5KCRzdG9yZSkpLT5jcmVhdGVMb2NrKCRuYW1lID86ICR0aGlzLT5nZXROYW1lKCkpOwogICAgICAgIGlmICghJHRoaXMtPmxvY2stPmFjcXVpcmUoJGJsb2NraW5nKSkgewogICAgICAgICAgICAkdGhpcy0+bG9jayA9IG51bGw7CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbGVhc2VzIHRoZSBjb21tYW5kIGxvY2sgaWYgdGhlcmUgaXMgb25lLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbGVhc2UoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+bG9jaykgewogICAgICAgICAgICAkdGhpcy0+bG9jay0+cmVsZWFzZSgpOwogICAgICAgICAgICAkdGhpcy0+bG9jayA9IG51bGw7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZTsKCi8qKgogKiBDb250YWlucyBhbGwgZXZlbnRzIGRpc3BhdGNoZWQgYnkgYW4gQXBwbGljYXRpb24uCiAqCiAqIEBhdXRob3IgRnJhbmNlc2NvIExldm9yYXRvIDxnaXRAZmxldm91ci5uZXQ+CiAqLwpmaW5hbCBjbGFzcyBDb25zb2xlRXZlbnRzCnsKICAgIC8qKgogICAgICogVGhlIENPTU1BTkQgZXZlbnQgYWxsb3dzIHlvdSB0byBhdHRhY2ggbGlzdGVuZXJzIGJlZm9yZSBhbnkgY29tbWFuZCBpcwogICAgICogZXhlY3V0ZWQgYnkgdGhlIGNvbnNvbGUuIEl0IGFsc28gYWxsb3dzIHlvdSB0byBtb2RpZnkgdGhlIGNvbW1hbmQsIGlucHV0IGFuZCBvdXRwdXQKICAgICAqIGJlZm9yZSB0aGV5IGFyZSBoYW5kbGVkIHRvIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEBFdmVudCgiU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlQ29tbWFuZEV2ZW50IikKICAgICAqLwogICAgY29uc3QgQ09NTUFORCA9ICdjb25zb2xlLmNvbW1hbmQnOwoKICAgIC8qKgogICAgICogVGhlIFRFUk1JTkFURSBldmVudCBhbGxvd3MgeW91IHRvIGF0dGFjaCBsaXN0ZW5lcnMgYWZ0ZXIgYSBjb21tYW5kIGlzCiAgICAgKiBleGVjdXRlZCBieSB0aGUgY29uc29sZS4KICAgICAqCiAgICAgKiBARXZlbnQoIlN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZVRlcm1pbmF0ZUV2ZW50IikKICAgICAqLwogICAgY29uc3QgVEVSTUlOQVRFID0gJ2NvbnNvbGUudGVybWluYXRlJzsKCiAgICAvKioKICAgICAqIFRoZSBFWENFUFRJT04gZXZlbnQgb2NjdXJzIHdoZW4gYW4gdW5jYXVnaHQgZXhjZXB0aW9uIGFwcGVhcnMKICAgICAqIHdoaWxlIGV4ZWN1dGluZyBDb21tYW5kI3J1bigpLgogICAgICoKICAgICAqIFRoaXMgZXZlbnQgYWxsb3dzIHlvdSB0byBkZWFsIHdpdGggdGhlIGV4Y2VwdGlvbiBvcgogICAgICogdG8gbW9kaWZ5IHRoZSB0aHJvd24gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBFdmVudCgiU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlRXhjZXB0aW9uRXZlbnQiKQogICAgICoKICAgICAqIEBkZXByZWNhdGVkIFRoZSBjb25zb2xlLmV4Y2VwdGlvbiBldmVudCBpcyBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgdGhlIGNvbnNvbGUuZXJyb3IgZXZlbnQgaW5zdGVhZC4KICAgICAqLwogICAgY29uc3QgRVhDRVBUSU9OID0gJ2NvbnNvbGUuZXhjZXB0aW9uJzsKCiAgICAvKioKICAgICAqIFRoZSBFUlJPUiBldmVudCBvY2N1cnMgd2hlbiBhbiB1bmNhdWdodCBleGNlcHRpb24gb3IgZXJyb3IgYXBwZWFycy4KICAgICAqCiAgICAgKiBUaGlzIGV2ZW50IGFsbG93cyB5b3UgdG8gZGVhbCB3aXRoIHRoZSBleGNlcHRpb24vZXJyb3Igb3IKICAgICAqIHRvIG1vZGlmeSB0aGUgdGhyb3duIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBARXZlbnQoIlN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZUVycm9yRXZlbnQiKQogICAgICovCiAgICBjb25zdCBFUlJPUiA9ICdjb25zb2xlLmVycm9yJzsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcU3R5bGU7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXEhlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFByb2dyZXNzQmFyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcU3ltZm9ueVF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcVGFibGU7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQnVmZmVyZWRPdXRwdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFF1ZXN0aW9uXENob2ljZVF1ZXN0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxRdWVzdGlvblxDb25maXJtYXRpb25RdWVzdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcUXVlc3Rpb25cUXVlc3Rpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFRlcm1pbmFsOwoKLyoqCiAqIE91dHB1dCBkZWNvcmF0b3IgaGVscGVycyBmb3IgdGhlIFN5bWZvbnkgU3R5bGUgR3VpZGUuCiAqCiAqIEBhdXRob3IgS2V2aW4gQm9uZCA8a2V2aW5ib25kQGdtYWlsLmNvbT4KICovCmNsYXNzIFN5bWZvbnlTdHlsZSBleHRlbmRzIE91dHB1dFN0eWxlCnsKICAgIGNvbnN0IE1BWF9MSU5FX0xFTkdUSCA9IDEyMDsKCiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJHF1ZXN0aW9uSGVscGVyOwogICAgcHJpdmF0ZSAkcHJvZ3Jlc3NCYXI7CiAgICBwcml2YXRlICRsaW5lTGVuZ3RoOwogICAgcHJpdmF0ZSAkYnVmZmVyZWRPdXRwdXQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgICR0aGlzLT5idWZmZXJlZE91dHB1dCA9IG5ldyBCdWZmZXJlZE91dHB1dCgkb3V0cHV0LT5nZXRWZXJib3NpdHkoKSwgZmFsc2UsIGNsb25lICRvdXRwdXQtPmdldEZvcm1hdHRlcigpKTsKICAgICAgICAvLyBXaW5kb3dzIGNtZCB3cmFwcyBsaW5lcyBhcyBzb29uIGFzIHRoZSB0ZXJtaW5hbCB3aWR0aCBpcyByZWFjaGVkLCB3aGV0aGVyIHRoZXJlIGFyZSBmb2xsb3dpbmcgY2hhcnMgb3Igbm90LgogICAgICAgICR3aWR0aCA9IChuZXcgVGVybWluYWwoKSktPmdldFdpZHRoKCkgPzogc2VsZjo6TUFYX0xJTkVfTEVOR1RIOwogICAgICAgICR0aGlzLT5saW5lTGVuZ3RoID0gbWluKCR3aWR0aCAtIChpbnQpIChcRElSRUNUT1JZX1NFUEFSQVRPUiA9PT0gJ1xcJyksIHNlbGY6Ok1BWF9MSU5FX0xFTkdUSCk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG91dHB1dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSBhcyBhIGJsb2NrIG9mIHRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZXMgVGhlIG1lc3NhZ2UgdG8gd3JpdGUgaW4gdGhlIGJsb2NrCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgICR0eXBlICAgICBUaGUgYmxvY2sgdHlwZSAoYWRkZWQgaW4gW10gb24gZmlyc3QgbGluZSkKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgJHN0eWxlICAgIFRoZSBzdHlsZSB0byBhcHBseSB0byB0aGUgd2hvbGUgYmxvY2sKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHByZWZpeCAgIFRoZSBwcmVmaXggZm9yIHRoZSBibG9jawogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkcGFkZGluZyAgV2hldGhlciB0byBhZGQgdmVydGljYWwgcGFkZGluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkZXNjYXBlICAgV2hldGhlciB0byBlc2NhcGUgdGhlIG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGJsb2NrKCRtZXNzYWdlcywgJHR5cGUgPSBudWxsLCAkc3R5bGUgPSBudWxsLCAkcHJlZml4ID0gJyAnLCAkcGFkZGluZyA9IGZhbHNlLCAkZXNjYXBlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBcaXNfYXJyYXkoJG1lc3NhZ2VzKSA/IGFycmF5X3ZhbHVlcygkbWVzc2FnZXMpIDogWyRtZXNzYWdlc107CgogICAgICAgICR0aGlzLT5hdXRvUHJlcGVuZEJsb2NrKCk7CiAgICAgICAgJHRoaXMtPndyaXRlbG4oJHRoaXMtPmNyZWF0ZUJsb2NrKCRtZXNzYWdlcywgJHR5cGUsICRzdHlsZSwgJHByZWZpeCwgJHBhZGRpbmcsICRlc2NhcGUpKTsKICAgICAgICAkdGhpcy0+bmV3TGluZSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdGl0bGUoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmF1dG9QcmVwZW5kQmxvY2soKTsKICAgICAgICAkdGhpcy0+d3JpdGVsbihbCiAgICAgICAgICAgIHNwcmludGYoJzxjb21tZW50PiVzPC8+JywgT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGVUcmFpbGluZ0JhY2tzbGFzaCgkbWVzc2FnZSkpLAogICAgICAgICAgICBzcHJpbnRmKCc8Y29tbWVudD4lczwvPicsIHN0cl9yZXBlYXQoJz0nLCBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCR0aGlzLT5nZXRGb3JtYXR0ZXIoKSwgJG1lc3NhZ2UpKSksCiAgICAgICAgXSk7CiAgICAgICAgJHRoaXMtPm5ld0xpbmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlY3Rpb24oJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmF1dG9QcmVwZW5kQmxvY2soKTsKICAgICAgICAkdGhpcy0+d3JpdGVsbihbCiAgICAgICAgICAgIHNwcmludGYoJzxjb21tZW50PiVzPC8+JywgT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGVUcmFpbGluZ0JhY2tzbGFzaCgkbWVzc2FnZSkpLAogICAgICAgICAgICBzcHJpbnRmKCc8Y29tbWVudD4lczwvPicsIHN0cl9yZXBlYXQoJy0nLCBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCR0aGlzLT5nZXRGb3JtYXR0ZXIoKSwgJG1lc3NhZ2UpKSksCiAgICAgICAgXSk7CiAgICAgICAgJHRoaXMtPm5ld0xpbmUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxpc3RpbmcoYXJyYXkgJGVsZW1lbnRzKQogICAgewogICAgICAgICR0aGlzLT5hdXRvUHJlcGVuZFRleHQoKTsKICAgICAgICAkZWxlbWVudHMgPSBhcnJheV9tYXAoZnVuY3Rpb24gKCRlbGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiBzcHJpbnRmKCcgKiAlcycsICRlbGVtZW50KTsKICAgICAgICB9LCAkZWxlbWVudHMpOwoKICAgICAgICAkdGhpcy0+d3JpdGVsbigkZWxlbWVudHMpOwogICAgICAgICR0aGlzLT5uZXdMaW5lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0ZXh0KCRtZXNzYWdlKQogICAgewogICAgICAgICR0aGlzLT5hdXRvUHJlcGVuZFRleHQoKTsKCiAgICAgICAgJG1lc3NhZ2VzID0gXGlzX2FycmF5KCRtZXNzYWdlKSA/IGFycmF5X3ZhbHVlcygkbWVzc2FnZSkgOiBbJG1lc3NhZ2VdOwogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICAkdGhpcy0+d3JpdGVsbihzcHJpbnRmKCcgJXMnLCAkbWVzc2FnZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBjb21tYW5kIGNvbW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29tbWVudCgkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmxvY2soJG1lc3NhZ2UsIG51bGwsIG51bGwsICc8Zmc9ZGVmYXVsdDtiZz1kZWZhdWx0PiAvLyA8Lz4nLCBmYWxzZSwgZmFsc2UpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3VjY2VzcygkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmxvY2soJG1lc3NhZ2UsICdPSycsICdmZz1ibGFjaztiZz1ncmVlbicsICcgJywgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmxvY2soJG1lc3NhZ2UsICdFUlJPUicsICdmZz13aGl0ZTtiZz1yZWQnLCAnICcsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmxvY2soJG1lc3NhZ2UsICdXQVJOSU5HJywgJ2ZnPXdoaXRlO2JnPXJlZCcsICcgJywgdHJ1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RlKCRtZXNzYWdlKQogICAgewogICAgICAgICR0aGlzLT5ibG9jaygkbWVzc2FnZSwgJ05PVEUnLCAnZmc9eWVsbG93JywgJyAhICcpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2F1dGlvbigkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+YmxvY2soJG1lc3NhZ2UsICdDQVVUSU9OJywgJ2ZnPXdoaXRlO2JnPXJlZCcsICcgISAnLCB0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRhYmxlKGFycmF5ICRoZWFkZXJzLCBhcnJheSAkcm93cykKICAgIHsKICAgICAgICAkc3R5bGUgPSBjbG9uZSBUYWJsZTo6Z2V0U3R5bGVEZWZpbml0aW9uKCdzeW1mb255LXN0eWxlLWd1aWRlJyk7CiAgICAgICAgJHN0eWxlLT5zZXRDZWxsSGVhZGVyRm9ybWF0KCc8aW5mbz4lczwvaW5mbz4nKTsKCiAgICAgICAgJHRhYmxlID0gbmV3IFRhYmxlKCR0aGlzKTsKICAgICAgICAkdGFibGUtPnNldEhlYWRlcnMoJGhlYWRlcnMpOwogICAgICAgICR0YWJsZS0+c2V0Um93cygkcm93cyk7CiAgICAgICAgJHRhYmxlLT5zZXRTdHlsZSgkc3R5bGUpOwoKICAgICAgICAkdGFibGUtPnJlbmRlcigpOwogICAgICAgICR0aGlzLT5uZXdMaW5lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwsICR2YWxpZGF0b3IgPSBudWxsKQogICAgewogICAgICAgICRxdWVzdGlvbiA9IG5ldyBRdWVzdGlvbigkcXVlc3Rpb24sICRkZWZhdWx0KTsKICAgICAgICAkcXVlc3Rpb24tPnNldFZhbGlkYXRvcigkdmFsaWRhdG9yKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5hc2tRdWVzdGlvbigkcXVlc3Rpb24pOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrSGlkZGVuKCRxdWVzdGlvbiwgJHZhbGlkYXRvciA9IG51bGwpCiAgICB7CiAgICAgICAgJHF1ZXN0aW9uID0gbmV3IFF1ZXN0aW9uKCRxdWVzdGlvbik7CgogICAgICAgICRxdWVzdGlvbi0+c2V0SGlkZGVuKHRydWUpOwogICAgICAgICRxdWVzdGlvbi0+c2V0VmFsaWRhdG9yKCR2YWxpZGF0b3IpOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmFza1F1ZXN0aW9uKCRxdWVzdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25maXJtKCRxdWVzdGlvbiwgJGRlZmF1bHQgPSB0cnVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXNrUXVlc3Rpb24obmV3IENvbmZpcm1hdGlvblF1ZXN0aW9uKCRxdWVzdGlvbiwgJGRlZmF1bHQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNob2ljZSgkcXVlc3Rpb24sIGFycmF5ICRjaG9pY2VzLCAkZGVmYXVsdCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgICR2YWx1ZXMgPSBhcnJheV9mbGlwKCRjaG9pY2VzKTsKICAgICAgICAgICAgJGRlZmF1bHQgPSBpc3NldCgkdmFsdWVzWyRkZWZhdWx0XSkgPyAkdmFsdWVzWyRkZWZhdWx0XSA6ICRkZWZhdWx0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5hc2tRdWVzdGlvbihuZXcgQ2hvaWNlUXVlc3Rpb24oJHF1ZXN0aW9uLCAkY2hvaWNlcywgJGRlZmF1bHQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzU3RhcnQoJG1heCA9IDApCiAgICB7CiAgICAgICAgJHRoaXMtPnByb2dyZXNzQmFyID0gJHRoaXMtPmNyZWF0ZVByb2dyZXNzQmFyKCRtYXgpOwogICAgICAgICR0aGlzLT5wcm9ncmVzc0Jhci0+c3RhcnQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzQWR2YW5jZSgkc3RlcCA9IDEpCiAgICB7CiAgICAgICAgJHRoaXMtPmdldFByb2dyZXNzQmFyKCktPmFkdmFuY2UoJHN0ZXApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3NGaW5pc2goKQogICAgewogICAgICAgICR0aGlzLT5nZXRQcm9ncmVzc0JhcigpLT5maW5pc2goKTsKICAgICAgICAkdGhpcy0+bmV3TGluZSgyKTsKICAgICAgICAkdGhpcy0+cHJvZ3Jlc3NCYXIgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlUHJvZ3Jlc3NCYXIoJG1heCA9IDApCiAgICB7CiAgICAgICAgJHByb2dyZXNzQmFyID0gcGFyZW50OjpjcmVhdGVQcm9ncmVzc0JhcigkbWF4KTsKCiAgICAgICAgaWYgKCdcXCcgIT09IFxESVJFQ1RPUllfU0VQQVJBVE9SIHx8ICdIeXBlcicgPT09IGdldGVudignVEVSTV9QUk9HUkFNJykpIHsKICAgICAgICAgICAgJHByb2dyZXNzQmFyLT5zZXRFbXB0eUJhckNoYXJhY3Rlcign4paRJyk7IC8vIGxpZ2h0IHNoYWRlIGNoYXJhY3RlciBcdTI1OTEKICAgICAgICAgICAgJHByb2dyZXNzQmFyLT5zZXRQcm9ncmVzc0NoYXJhY3RlcignJyk7CiAgICAgICAgICAgICRwcm9ncmVzc0Jhci0+c2V0QmFyQ2hhcmFjdGVyKCfilpMnKTsgLy8gZGFyayBzaGFkZSBjaGFyYWN0ZXIgXHUyNTkzCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHByb2dyZXNzQmFyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNrUXVlc3Rpb24oUXVlc3Rpb24gJHF1ZXN0aW9uKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aW5wdXQtPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAkdGhpcy0+YXV0b1ByZXBlbmRCbG9jaygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEkdGhpcy0+cXVlc3Rpb25IZWxwZXIpIHsKICAgICAgICAgICAgJHRoaXMtPnF1ZXN0aW9uSGVscGVyID0gbmV3IFN5bWZvbnlRdWVzdGlvbkhlbHBlcigpOwogICAgICAgIH0KCiAgICAgICAgJGFuc3dlciA9ICR0aGlzLT5xdWVzdGlvbkhlbHBlci0+YXNrKCR0aGlzLT5pbnB1dCwgJHRoaXMsICRxdWVzdGlvbik7CgogICAgICAgIGlmICgkdGhpcy0+aW5wdXQtPmlzSW50ZXJhY3RpdmUoKSkgewogICAgICAgICAgICAkdGhpcy0+bmV3TGluZSgpOwogICAgICAgICAgICAkdGhpcy0+YnVmZmVyZWRPdXRwdXQtPndyaXRlKCJcbiIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhbnN3ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZWxuKCRtZXNzYWdlcywgJHR5cGUgPSBzZWxmOjpPVVRQVVRfTk9STUFMKQogICAgewogICAgICAgIHBhcmVudDo6d3JpdGVsbigkbWVzc2FnZXMsICR0eXBlKTsKICAgICAgICAkdGhpcy0+YnVmZmVyZWRPdXRwdXQtPndyaXRlbG4oJHRoaXMtPnJlZHVjZUJ1ZmZlcigkbWVzc2FnZXMpLCAkdHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkbWVzc2FnZXMsICRuZXdsaW5lID0gZmFsc2UsICR0eXBlID0gc2VsZjo6T1VUUFVUX05PUk1BTCkKICAgIHsKICAgICAgICBwYXJlbnQ6OndyaXRlKCRtZXNzYWdlcywgJG5ld2xpbmUsICR0eXBlKTsKICAgICAgICAkdGhpcy0+YnVmZmVyZWRPdXRwdXQtPndyaXRlKCR0aGlzLT5yZWR1Y2VCdWZmZXIoJG1lc3NhZ2VzKSwgJG5ld2xpbmUsICR0eXBlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5ld0xpbmUoJGNvdW50ID0gMSkKICAgIHsKICAgICAgICBwYXJlbnQ6Om5ld0xpbmUoJGNvdW50KTsKICAgICAgICAkdGhpcy0+YnVmZmVyZWRPdXRwdXQtPndyaXRlKHN0cl9yZXBlYXQoIlxuIiwgJGNvdW50KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIHdoaWNoIG1ha2VzIHVzZSBvZiBzdGRlcnIgaWYgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JTdHlsZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBzZWxmKCR0aGlzLT5pbnB1dCwgJHRoaXMtPmdldEVycm9yT3V0cHV0KCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBQcm9ncmVzc0JhcgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFByb2dyZXNzQmFyKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5wcm9ncmVzc0JhcikgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignVGhlIFByb2dyZXNzQmFyIGlzIG5vdCBzdGFydGVkLicpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9ncmVzc0JhcjsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGF1dG9QcmVwZW5kQmxvY2soKQogICAgewogICAgICAgICRjaGFycyA9IHN1YnN0cihzdHJfcmVwbGFjZShcUEhQX0VPTCwgIlxuIiwgJHRoaXMtPmJ1ZmZlcmVkT3V0cHV0LT5mZXRjaCgpKSwgLTIpOwoKICAgICAgICBpZiAoIWlzc2V0KCRjaGFyc1swXSkpIHsKICAgICAgICAgICAgJHRoaXMtPm5ld0xpbmUoKTsgLy9lbXB0eSBoaXN0b3J5LCBzbyB3ZSBzaG91bGQgc3RhcnQgd2l0aCBhIG5ldyBsaW5lLgoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvL1ByZXBlbmQgbmV3IGxpbmUgZm9yIGVhY2ggbm9uIExGIGNoYXJzIChUaGlzIG1lYW5zIG5vIGJsYW5rIGxpbmUgd2FzIG91dHB1dCBiZWZvcmUpCiAgICAgICAgJHRoaXMtPm5ld0xpbmUoMiAtIHN1YnN0cl9jb3VudCgkY2hhcnMsICJcbiIpKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGF1dG9QcmVwZW5kVGV4dCgpCiAgICB7CiAgICAgICAgJGZldGNoZWQgPSAkdGhpcy0+YnVmZmVyZWRPdXRwdXQtPmZldGNoKCk7CiAgICAgICAgLy9QcmVwZW5kIG5ldyBsaW5lIGlmIGxhc3QgY2hhciBpc24ndCBFT0w6CiAgICAgICAgaWYgKCJcbiIgIT09IHN1YnN0cigkZmV0Y2hlZCwgLTEpKSB7CiAgICAgICAgICAgICR0aGlzLT5uZXdMaW5lKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVkdWNlQnVmZmVyKCRtZXNzYWdlcykKICAgIHsKICAgICAgICAvLyBXZSBuZWVkIHRvIGtub3cgaWYgdGhlIHR3byBsYXN0IGNoYXJzIGFyZSBQSFBfRU9MCiAgICAgICAgLy8gUHJlc2VydmUgdGhlIGxhc3QgNCBjaGFycyBpbnNlcnRlZCAoUEhQX0VPTCBvbiB3aW5kb3dzIGlzIHR3byBjaGFycykgaW4gdGhlIGhpc3RvcnkgYnVmZmVyCiAgICAgICAgcmV0dXJuIGFycmF5X21hcChmdW5jdGlvbiAoJHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHZhbHVlLCAtNCk7CiAgICAgICAgfSwgYXJyYXlfbWVyZ2UoWyR0aGlzLT5idWZmZXJlZE91dHB1dC0+ZmV0Y2goKV0sIChhcnJheSkgJG1lc3NhZ2VzKSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVCbG9jaygkbWVzc2FnZXMsICR0eXBlID0gbnVsbCwgJHN0eWxlID0gbnVsbCwgJHByZWZpeCA9ICcgJywgJHBhZGRpbmcgPSBmYWxzZSwgJGVzY2FwZSA9IGZhbHNlKQogICAgewogICAgICAgICRpbmRlbnRMZW5ndGggPSAwOwogICAgICAgICRwcmVmaXhMZW5ndGggPSBIZWxwZXI6OnN0cmxlbldpdGhvdXREZWNvcmF0aW9uKCR0aGlzLT5nZXRGb3JtYXR0ZXIoKSwgJHByZWZpeCk7CiAgICAgICAgJGxpbmVzID0gW107CgogICAgICAgIGlmIChudWxsICE9PSAkdHlwZSkgewogICAgICAgICAgICAkdHlwZSA9IHNwcmludGYoJ1slc10gJywgJHR5cGUpOwogICAgICAgICAgICAkaW5kZW50TGVuZ3RoID0gXHN0cmxlbigkdHlwZSk7CiAgICAgICAgICAgICRsaW5lSW5kZW50YXRpb24gPSBzdHJfcmVwZWF0KCcgJywgJGluZGVudExlbmd0aCk7CiAgICAgICAgfQoKICAgICAgICAvLyB3cmFwIGFuZCBhZGQgbmV3bGluZXMgZm9yIGVhY2ggZWxlbWVudAogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAka2V5ID0+ICRtZXNzYWdlKSB7CiAgICAgICAgICAgIGlmICgkZXNjYXBlKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlKCRtZXNzYWdlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpbmVzID0gYXJyYXlfbWVyZ2UoJGxpbmVzLCBleHBsb2RlKFxQSFBfRU9MLCB3b3Jkd3JhcCgkbWVzc2FnZSwgJHRoaXMtPmxpbmVMZW5ndGggLSAkcHJlZml4TGVuZ3RoIC0gJGluZGVudExlbmd0aCwgXFBIUF9FT0wsIHRydWUpKSk7CgogICAgICAgICAgICBpZiAoXGNvdW50KCRtZXNzYWdlcykgPiAxICYmICRrZXkgPCBcY291bnQoJG1lc3NhZ2VzKSAtIDEpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRmaXJzdExpbmVJbmRleCA9IDA7CiAgICAgICAgaWYgKCRwYWRkaW5nICYmICR0aGlzLT5pc0RlY29yYXRlZCgpKSB7CiAgICAgICAgICAgICRmaXJzdExpbmVJbmRleCA9IDE7CiAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGxpbmVzLCAnJyk7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyc7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGkgPT4gJiRsaW5lKSB7CiAgICAgICAgICAgIGlmIChudWxsICE9PSAkdHlwZSkgewogICAgICAgICAgICAgICAgJGxpbmUgPSAkZmlyc3RMaW5lSW5kZXggPT09ICRpID8gJHR5cGUuJGxpbmUgOiAkbGluZUluZGVudGF0aW9uLiRsaW5lOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGluZSA9ICRwcmVmaXguJGxpbmU7CiAgICAgICAgICAgICRsaW5lIC49IHN0cl9yZXBlYXQoJyAnLCAkdGhpcy0+bGluZUxlbmd0aCAtIEhlbHBlcjo6c3RybGVuV2l0aG91dERlY29yYXRpb24oJHRoaXMtPmdldEZvcm1hdHRlcigpLCAkbGluZSkpOwoKICAgICAgICAgICAgaWYgKCRzdHlsZSkgewogICAgICAgICAgICAgICAgJGxpbmUgPSBzcHJpbnRmKCc8JXM+JXM8Lz4nLCAkc3R5bGUsICRsaW5lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRsaW5lczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcU3R5bGU7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxGb3JtYXR0ZXJcT3V0cHV0Rm9ybWF0dGVySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUHJvZ3Jlc3NCYXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIERlY29yYXRlcyBvdXRwdXQgdG8gYWRkIGNvbnNvbGUgc3R5bGUgZ3VpZGUgaGVscGVycy4KICoKICogQGF1dGhvciBLZXZpbiBCb25kIDxrZXZpbmJvbmRAZ21haWwuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgT3V0cHV0U3R5bGUgaW1wbGVtZW50cyBPdXRwdXRJbnRlcmZhY2UsIFN0eWxlSW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJG91dHB1dDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dCA9ICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBuZXdMaW5lKCRjb3VudCA9IDEpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoc3RyX3JlcGVhdChcUEhQX0VPTCwgJGNvdW50KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRtYXgKICAgICAqCiAgICAgKiBAcmV0dXJuIFByb2dyZXNzQmFyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVQcm9ncmVzc0JhcigkbWF4ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFByb2dyZXNzQmFyKCR0aGlzLT5vdXRwdXQsICRtYXgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSA9IGZhbHNlLCAkdHlwZSA9IHNlbGY6Ok9VVFBVVF9OT1JNQUwpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dC0+d3JpdGUoJG1lc3NhZ2VzLCAkbmV3bGluZSwgJHR5cGUpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGVsbigkbWVzc2FnZXMsICR0eXBlID0gc2VsZjo6T1VUUFVUX05PUk1BTCkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0LT53cml0ZWxuKCRtZXNzYWdlcywgJHR5cGUpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmVyYm9zaXR5KCRsZXZlbCkKICAgIHsKICAgICAgICAkdGhpcy0+b3V0cHV0LT5zZXRWZXJib3NpdHkoJGxldmVsKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFZlcmJvc2l0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldFZlcmJvc2l0eSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPm91dHB1dC0+c2V0RGVjb3JhdGVkKCRkZWNvcmF0ZWQpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEZWNvcmF0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5pc0RlY29yYXRlZCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0dGVyKE91dHB1dEZvcm1hdHRlckludGVyZmFjZSAkZm9ybWF0dGVyKQogICAgewogICAgICAgICR0aGlzLT5vdXRwdXQtPnNldEZvcm1hdHRlcigkZm9ybWF0dGVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZvcm1hdHRlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldEZvcm1hdHRlcigpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNRdWlldCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzUXVpZXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzVmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzVmVyYm9zZSgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWZXJ5VmVyYm9zZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmlzVmVyeVZlcmJvc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRGVidWcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0LT5pc0RlYnVnKCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEVycm9yT3V0cHV0KCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5vdXRwdXQgaW5zdGFuY2VvZiBDb25zb2xlT3V0cHV0SW50ZXJmYWNlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+b3V0cHV0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQtPmdldEVycm9yT3V0cHV0KCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXFN0eWxlOwoKLyoqCiAqIE91dHB1dCBzdHlsZSBoZWxwZXJzLgogKgogKiBAYXV0aG9yIEtldmluIEJvbmQgPGtldmluYm9uZEBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgU3R5bGVJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgY29tbWFuZCB0aXRsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0aXRsZSgkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgc2VjdGlvbiB0aXRsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZWN0aW9uKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBsaXN0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbGlzdGluZyhhcnJheSAkZWxlbWVudHMpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBpbmZvcm1hdGlvbmFsIHRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdGV4dCgkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgc3VjY2VzcyByZXN1bHQgYmFyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN1Y2Nlc3MoJG1lc3NhZ2UpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhbiBlcnJvciByZXN1bHQgYmFyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYW4gd2FybmluZyByZXN1bHQgYmFyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UpOwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIG5vdGUgYWRtb25pdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RlKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBjYXV0aW9uIGFkbW9uaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2F1dGlvbigkbWVzc2FnZSk7CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgdGFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0YWJsZShhcnJheSAkaGVhZGVycywgYXJyYXkgJHJvd3MpOwoKICAgIC8qKgogICAgICogQXNrcyBhIHF1ZXN0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICRxdWVzdGlvbgogICAgICogQHBhcmFtIHN0cmluZ3xudWxsICAgJGRlZmF1bHQKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICR2YWxpZGF0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2soJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwsICR2YWxpZGF0b3IgPSBudWxsKTsKCiAgICAvKioKICAgICAqIEFza3MgYSBxdWVzdGlvbiB3aXRoIHRoZSB1c2VyIGlucHV0IGhpZGRlbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAkcXVlc3Rpb24KICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICR2YWxpZGF0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhc2tIaWRkZW4oJHF1ZXN0aW9uLCAkdmFsaWRhdG9yID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBBc2tzIGZvciBjb25maXJtYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcXVlc3Rpb24KICAgICAqIEBwYXJhbSBib29sICAgJGRlZmF1bHQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbmZpcm0oJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IHRydWUpOwoKICAgIC8qKgogICAgICogQXNrcyBhIGNob2ljZSBxdWVzdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRxdWVzdGlvbgogICAgICogQHBhcmFtIHN0cmluZ3xpbnR8bnVsbCAkZGVmYXVsdAogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNob2ljZSgkcXVlc3Rpb24sIGFycmF5ICRjaG9pY2VzLCAkZGVmYXVsdCA9IG51bGwpOwoKICAgIC8qKgogICAgICogQWRkIG5ld2xpbmUocykuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkY291bnQgVGhlIG51bWJlciBvZiBuZXdsaW5lcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV3TGluZSgkY291bnQgPSAxKTsKCiAgICAvKioKICAgICAqIFN0YXJ0cyB0aGUgcHJvZ3Jlc3Mgb3V0cHV0LgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJG1heCBNYXhpbXVtIHN0ZXBzICgwIGlmIHVua25vd24pCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzc1N0YXJ0KCRtYXggPSAwKTsKCiAgICAvKioKICAgICAqIEFkdmFuY2VzIHRoZSBwcm9ncmVzcyBvdXRwdXQgWCBzdGVwcy4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRzdGVwIE51bWJlciBvZiBzdGVwcyB0byBhZHZhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzc0FkdmFuY2UoJHN0ZXAgPSAxKTsKCiAgICAvKioKICAgICAqIEZpbmlzaGVzIHRoZSBwcm9ncmVzcyBvdXRwdXQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzc0ZpbmlzaCgpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhbiBpbmNvcnJlY3QgY29tbWFuZCBuYW1lIHR5cGVkIGluIHRoZSBjb25zb2xlLgogKgogKiBAYXV0aG9yIErDqXLDtG1lIFRhbWFyZWxsZSA8amVyb21lQHRhbWFyZWxsZS5uZXQ+CiAqLwpjbGFzcyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJGFsdGVybmF0aXZlczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICRtZXNzYWdlICAgICAgRXhjZXB0aW9uIG1lc3NhZ2UgdG8gdGhyb3cKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICRhbHRlcm5hdGl2ZXMgTGlzdCBvZiBzaW1pbGFyIGRlZmluZWQgbmFtZXMKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICRjb2RlICAgICAgICAgRXhjZXB0aW9uIGNvZGUKICAgICAqIEBwYXJhbSBcRXhjZXB0aW9uICRwcmV2aW91cyAgICAgUHJldmlvdXMgZXhjZXB0aW9uIHVzZWQgZm9yIHRoZSBleGNlcHRpb24gY2hhaW5pbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlLCBhcnJheSAkYWx0ZXJuYXRpdmVzID0gW10sICRjb2RlID0gMCwgXEV4Y2VwdGlvbiAkcHJldmlvdXMgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRjb2RlLCAkcHJldmlvdXMpOwoKICAgICAgICAkdGhpcy0+YWx0ZXJuYXRpdmVzID0gJGFsdGVybmF0aXZlczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkgQSBsaXN0IG9mIHNpbWlsYXIgZGVmaW5lZCBuYW1lcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWx0ZXJuYXRpdmVzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsdGVybmF0aXZlczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgSsOpcsO0bWUgVGFtYXJlbGxlIDxqZXJvbWVAdGFtYXJlbGxlLm5ldD4KICovCmNsYXNzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBleHRlbmRzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogQGF1dGhvciBKw6lyw7RtZSBUYW1hcmVsbGUgPGplcm9tZUB0YW1hcmVsbGUubmV0PgogKi8KY2xhc3MgTG9naWNFeGNlcHRpb24gZXh0ZW5kcyBcTG9naWNFeGNlcHRpb24gaW1wbGVtZW50cyBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhbiBpbmNvcnJlY3Qgb3B0aW9uIG5hbWUgdHlwZWQgaW4gdGhlIGNvbnNvbGUuCiAqCiAqIEBhdXRob3IgSsOpcsO0bWUgVGFtYXJlbGxlIDxqZXJvbWVAdGFtYXJlbGxlLm5ldD4KICovCmNsYXNzIEludmFsaWRPcHRpb25FeGNlcHRpb24gZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uOwoKLyoqCiAqIEBhdXRob3IgSsOpcsO0bWUgVGFtYXJlbGxlIDxqZXJvbWVAdGFtYXJlbGxlLm5ldD4KICovCmNsYXNzIFJ1bnRpbWVFeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvbjsKCi8qKgogKiBFeGNlcHRpb25JbnRlcmZhY2UuCiAqCiAqIEBhdXRob3IgSsOpcsO0bWUgVGFtYXJlbGxlIDxqZXJvbWVAdGFtYXJlbGxlLm5ldD4KICovCmludGVyZmFjZSBFeGNlcHRpb25JbnRlcmZhY2UKewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZTsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxIZWxwQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxMaXN0Q29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZExvYWRlclxDb21tYW5kTG9hZGVySW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlQ29tbWFuZEV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlRXJyb3JFdmVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnRcQ29uc29sZUV4Y2VwdGlvbkV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlVGVybWluYXRlRXZlbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxDb21tYW5kTm90Rm91bmRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxFeGNlcHRpb25JbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxMb2dpY0V4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRm9ybWF0dGVyXE91dHB1dEZvcm1hdHRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXERlYnVnRm9ybWF0dGVySGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcRm9ybWF0dGVySGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcSGVscGVyU2V0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxIZWxwZXJcUHJvY2Vzc0hlbHBlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSGVscGVyXFF1ZXN0aW9uSGVscGVyOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxBcmd2SW5wdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XEFycmF5SW5wdXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXJndW1lbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0QXdhcmVJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0RGVmaW5pdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0T3B0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxTdHJlYW1hYmxlSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxDb25zb2xlT3V0cHV0Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcQ29uc29sZU91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XERlYnVnXEVycm9ySGFuZGxlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XERlYnVnXEV4Y2VwdGlvblxGYXRhbFRocm93YWJsZUVycm9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRXZlbnREaXNwYXRjaGVyXEV2ZW50RGlzcGF0Y2hlckludGVyZmFjZTsKCi8qKgogKiBBbiBBcHBsaWNhdGlvbiBpcyB0aGUgY29udGFpbmVyIGZvciBhIGNvbGxlY3Rpb24gb2YgY29tbWFuZHMuCiAqCiAqIEl0IGlzIHRoZSBtYWluIGVudHJ5IHBvaW50IG9mIGEgQ29uc29sZSBhcHBsaWNhdGlvbi4KICoKICogVGhpcyBjbGFzcyBpcyBvcHRpbWl6ZWQgZm9yIGEgc3RhbmRhcmQgQ0xJIGVudmlyb25tZW50LgogKgogKiBVc2FnZToKICoKICogICAgICRhcHAgPSBuZXcgQXBwbGljYXRpb24oJ215YXBwJywgJzEuMCAoc3RhYmxlKScpOwogKiAgICAgJGFwcC0+YWRkKG5ldyBTaW1wbGVDb21tYW5kKCkpOwogKiAgICAgJGFwcC0+cnVuKCk7CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgQXBwbGljYXRpb24KewogICAgcHJpdmF0ZSAkY29tbWFuZHMgPSBbXTsKICAgIHByaXZhdGUgJHdhbnRIZWxwcyA9IGZhbHNlOwogICAgcHJpdmF0ZSAkcnVubmluZ0NvbW1hbmQ7CiAgICBwcml2YXRlICRuYW1lOwogICAgcHJpdmF0ZSAkdmVyc2lvbjsKICAgIHByaXZhdGUgJGNvbW1hbmRMb2FkZXI7CiAgICBwcml2YXRlICRjYXRjaEV4Y2VwdGlvbnMgPSB0cnVlOwogICAgcHJpdmF0ZSAkYXV0b0V4aXQgPSB0cnVlOwogICAgcHJpdmF0ZSAkZGVmaW5pdGlvbjsKICAgIHByaXZhdGUgJGhlbHBlclNldDsKICAgIHByaXZhdGUgJGRpc3BhdGNoZXI7CiAgICBwcml2YXRlICR0ZXJtaW5hbDsKICAgIHByaXZhdGUgJGRlZmF1bHRDb21tYW5kOwogICAgcHJpdmF0ZSAkc2luZ2xlQ29tbWFuZCA9IGZhbHNlOwogICAgcHJpdmF0ZSAkaW5pdGlhbGl6ZWQ7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgIFRoZSBuYW1lIG9mIHRoZSBhcHBsaWNhdGlvbgogICAgICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBUaGUgdmVyc2lvbiBvZiB0aGUgYXBwbGljYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lID0gJ1VOS05PV04nLCAkdmVyc2lvbiA9ICdVTktOT1dOJykKICAgIHsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT52ZXJzaW9uID0gJHZlcnNpb247CiAgICAgICAgJHRoaXMtPnRlcm1pbmFsID0gbmV3IFRlcm1pbmFsKCk7CiAgICAgICAgJHRoaXMtPmRlZmF1bHRDb21tYW5kID0gJ2xpc3QnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXNwYXRjaGVyKEV2ZW50RGlzcGF0Y2hlckludGVyZmFjZSAkZGlzcGF0Y2hlcikKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzcGF0Y2hlciA9ICRkaXNwYXRjaGVyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb21tYW5kTG9hZGVyKENvbW1hbmRMb2FkZXJJbnRlcmZhY2UgJGNvbW1hbmRMb2FkZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRMb2FkZXIgPSAkY29tbWFuZExvYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1bnMgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBpbnQgMCBpZiBldmVyeXRoaW5nIHdlbnQgZmluZSwgb3IgYW4gZXJyb3IgY29kZQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbiBXaGVuIHJ1bm5pbmcgZmFpbHMuIEJ5cGFzcyB0aGlzIHdoZW4ge0BsaW5rIHNldENhdGNoRXhjZXB0aW9ucygpfS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJ1bihJbnB1dEludGVyZmFjZSAkaW5wdXQgPSBudWxsLCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCA9IG51bGwpCiAgICB7CiAgICAgICAgcHV0ZW52KCdMSU5FUz0nLiR0aGlzLT50ZXJtaW5hbC0+Z2V0SGVpZ2h0KCkpOwogICAgICAgIHB1dGVudignQ09MVU1OUz0nLiR0aGlzLT50ZXJtaW5hbC0+Z2V0V2lkdGgoKSk7CgogICAgICAgIGlmIChudWxsID09PSAkaW5wdXQpIHsKICAgICAgICAgICAgJGlucHV0ID0gbmV3IEFyZ3ZJbnB1dCgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG51bGwgPT09ICRvdXRwdXQpIHsKICAgICAgICAgICAgJG91dHB1dCA9IG5ldyBDb25zb2xlT3V0cHV0KCk7CiAgICAgICAgfQoKICAgICAgICAkcmVuZGVyRXhjZXB0aW9uID0gZnVuY3Rpb24gKCRlKSB1c2UgKCRvdXRwdXQpIHsKICAgICAgICAgICAgaWYgKCEkZSBpbnN0YW5jZW9mIFxFeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICRlID0gY2xhc3NfZXhpc3RzKEZhdGFsVGhyb3dhYmxlRXJyb3I6OmNsYXNzKSA/IG5ldyBGYXRhbFRocm93YWJsZUVycm9yKCRlKSA6IG5ldyBcRXJyb3JFeGNlcHRpb24oJGUtPmdldE1lc3NhZ2UoKSwgJGUtPmdldENvZGUoKSwgXEVfRVJST1IsICRlLT5nZXRGaWxlKCksICRlLT5nZXRMaW5lKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkb3V0cHV0IGluc3RhbmNlb2YgQ29uc29sZU91dHB1dEludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlckV4Y2VwdGlvbigkZSwgJG91dHB1dC0+Z2V0RXJyb3JPdXRwdXQoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyRXhjZXB0aW9uKCRlLCAkb3V0cHV0KTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgaWYgKCRwaHBIYW5kbGVyID0gc2V0X2V4Y2VwdGlvbl9oYW5kbGVyKCRyZW5kZXJFeGNlcHRpb24pKSB7CiAgICAgICAgICAgIHJlc3RvcmVfZXhjZXB0aW9uX2hhbmRsZXIoKTsKICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJHBocEhhbmRsZXIpIHx8ICEkcGhwSGFuZGxlclswXSBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikgewogICAgICAgICAgICAgICAgJGRlYnVnSGFuZGxlciA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZGVidWdIYW5kbGVyID0gJHBocEhhbmRsZXJbMF0tPnNldEV4Y2VwdGlvbkhhbmRsZXIoJHJlbmRlckV4Y2VwdGlvbikpIHsKICAgICAgICAgICAgICAgICRwaHBIYW5kbGVyWzBdLT5zZXRFeGNlcHRpb25IYW5kbGVyKCRkZWJ1Z0hhbmRsZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPmRpc3BhdGNoZXIgJiYgJHRoaXMtPmRpc3BhdGNoZXItPmhhc0xpc3RlbmVycyhDb25zb2xlRXZlbnRzOjpFWENFUFRJT04pKSB7CiAgICAgICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAiQ29uc29sZUV2ZW50czo6RVhDRVBUSU9OIiBldmVudCBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBMaXN0ZW4gdG8gdGhlICJDb25zb2xlRXZlbnRzOjpFUlJPUiIgZXZlbnQgaW5zdGVhZC4nKSwgXEVfVVNFUl9ERVBSRUNBVEVEKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb25maWd1cmVJTygkaW5wdXQsICRvdXRwdXQpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAkZXhpdENvZGUgPSAkdGhpcy0+ZG9SdW4oJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmNhdGNoRXhjZXB0aW9ucykgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRyZW5kZXJFeGNlcHRpb24oJGUpOwoKICAgICAgICAgICAgJGV4aXRDb2RlID0gJGUtPmdldENvZGUoKTsKICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoJGV4aXRDb2RlKSkgewogICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gKGludCkgJGV4aXRDb2RlOwogICAgICAgICAgICAgICAgaWYgKDAgPT09ICRleGl0Q29kZSkgewogICAgICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgLy8gaWYgdGhlIGV4Y2VwdGlvbiBoYW5kbGVyIGNoYW5nZWQsIGtlZXAgaXQKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCB1bnJlZ2lzdGVyICRyZW5kZXJFeGNlcHRpb24KICAgICAgICAgICAgaWYgKCEkcGhwSGFuZGxlcikgewogICAgICAgICAgICAgICAgaWYgKHNldF9leGNlcHRpb25faGFuZGxlcigkcmVuZGVyRXhjZXB0aW9uKSA9PT0gJHJlbmRlckV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHJlc3RvcmVfZXhjZXB0aW9uX2hhbmRsZXIoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJlc3RvcmVfZXhjZXB0aW9uX2hhbmRsZXIoKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCEkZGVidWdIYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAkZmluYWxIYW5kbGVyID0gJHBocEhhbmRsZXJbMF0tPnNldEV4Y2VwdGlvbkhhbmRsZXIobnVsbCk7CiAgICAgICAgICAgICAgICBpZiAoJGZpbmFsSGFuZGxlciAhPT0gJHJlbmRlckV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgICRwaHBIYW5kbGVyWzBdLT5zZXRFeGNlcHRpb25IYW5kbGVyKCRmaW5hbEhhbmRsZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmF1dG9FeGl0KSB7CiAgICAgICAgICAgIGlmICgkZXhpdENvZGUgPiAyNTUpIHsKICAgICAgICAgICAgICAgICRleGl0Q29kZSA9IDI1NTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZXhpdCgkZXhpdENvZGUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1bnMgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBpbnQgMCBpZiBldmVyeXRoaW5nIHdlbnQgZmluZSwgb3IgYW4gZXJyb3IgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG9SdW4oSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICBpZiAodHJ1ZSA9PT0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oWyctLXZlcnNpb24nLCAnLVYnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbigkdGhpcy0+Z2V0TG9uZ1ZlcnNpb24oKSk7CgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIE1ha2VzIEFyZ3ZJbnB1dDo6Z2V0Rmlyc3RBcmd1bWVudCgpIGFibGUgdG8gZGlzdGluZ3Vpc2ggYW4gb3B0aW9uIGZyb20gYW4gYXJndW1lbnQuCiAgICAgICAgICAgICRpbnB1dC0+YmluZCgkdGhpcy0+Z2V0RGVmaW5pdGlvbigpKTsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb25JbnRlcmZhY2UgJGUpIHsKICAgICAgICAgICAgLy8gRXJyb3JzIG11c3QgYmUgaWdub3JlZCwgZnVsbCBiaW5kaW5nL3ZhbGlkYXRpb24gaGFwcGVucyBsYXRlciB3aGVuIHRoZSBjb21tYW5kIGlzIGtub3duLgogICAgICAgIH0KCiAgICAgICAgJG5hbWUgPSAkdGhpcy0+Z2V0Q29tbWFuZE5hbWUoJGlucHV0KTsKICAgICAgICBpZiAodHJ1ZSA9PT0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oWyctLWhlbHAnLCAnLWgnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgaWYgKCEkbmFtZSkgewogICAgICAgICAgICAgICAgJG5hbWUgPSAnaGVscCc7CiAgICAgICAgICAgICAgICAkaW5wdXQgPSBuZXcgQXJyYXlJbnB1dChbJ2NvbW1hbmRfbmFtZScgPT4gJHRoaXMtPmRlZmF1bHRDb21tYW5kXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+d2FudEhlbHBzID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCEkbmFtZSkgewogICAgICAgICAgICAkbmFtZSA9ICR0aGlzLT5kZWZhdWx0Q29tbWFuZDsKICAgICAgICAgICAgJGRlZmluaXRpb24gPSAkdGhpcy0+Z2V0RGVmaW5pdGlvbigpOwogICAgICAgICAgICAkZGVmaW5pdGlvbi0+c2V0QXJndW1lbnRzKGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJGRlZmluaXRpb24tPmdldEFyZ3VtZW50cygpLAogICAgICAgICAgICAgICAgWwogICAgICAgICAgICAgICAgICAgICdjb21tYW5kJyA9PiBuZXcgSW5wdXRBcmd1bWVudCgnY29tbWFuZCcsIElucHV0QXJndW1lbnQ6Ok9QVElPTkFMLCAkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnQoJ2NvbW1hbmQnKS0+Z2V0RGVzY3JpcHRpb24oKSwgJG5hbWUpLAogICAgICAgICAgICAgICAgXQogICAgICAgICAgICApKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRlID0gJHRoaXMtPnJ1bm5pbmdDb21tYW5kID0gbnVsbDsKICAgICAgICAgICAgLy8gdGhlIGNvbW1hbmQgbmFtZSBNVVNUIGJlIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoZSBpbnB1dAogICAgICAgICAgICAkY29tbWFuZCA9ICR0aGlzLT5maW5kKCRuYW1lKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZSkgewogICAgICAgIH0KICAgICAgICBpZiAobnVsbCAhPT0gJGUpIHsKICAgICAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5kaXNwYXRjaGVyKSB7CiAgICAgICAgICAgICAgICAkZXZlbnQgPSBuZXcgQ29uc29sZUVycm9yRXZlbnQoJGlucHV0LCAkb3V0cHV0LCAkZSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzcGF0Y2hlci0+ZGlzcGF0Y2goQ29uc29sZUV2ZW50czo6RVJST1IsICRldmVudCk7CiAgICAgICAgICAgICAgICAkZSA9ICRldmVudC0+Z2V0RXJyb3IoKTsKCiAgICAgICAgICAgICAgICBpZiAoMCA9PT0gJGV2ZW50LT5nZXRFeGl0Q29kZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnJ1bm5pbmdDb21tYW5kID0gJGNvbW1hbmQ7CiAgICAgICAgJGV4aXRDb2RlID0gJHRoaXMtPmRvUnVuQ29tbWFuZCgkY29tbWFuZCwgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkdGhpcy0+cnVubmluZ0NvbW1hbmQgPSBudWxsOwoKICAgICAgICByZXR1cm4gJGV4aXRDb2RlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIZWxwZXJTZXQoSGVscGVyU2V0ICRoZWxwZXJTZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmhlbHBlclNldCA9ICRoZWxwZXJTZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGhlbHBlciBzZXQgYXNzb2NpYXRlZCB3aXRoIHRoZSBjb21tYW5kLgogICAgICoKICAgICAqIEByZXR1cm4gSGVscGVyU2V0IFRoZSBIZWxwZXJTZXQgaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29tbWFuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscGVyU2V0KCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oZWxwZXJTZXQpIHsKICAgICAgICAgICAgJHRoaXMtPmhlbHBlclNldCA9ICR0aGlzLT5nZXREZWZhdWx0SGVscGVyU2V0KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmhlbHBlclNldDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVmaW5pdGlvbihJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmRlZmluaXRpb24gPSAkZGVmaW5pdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIElucHV0RGVmaW5pdGlvbiByZWxhdGVkIHRvIHRoaXMgQXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dERlZmluaXRpb24gVGhlIElucHV0RGVmaW5pdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbikgewogICAgICAgICAgICAkdGhpcy0+ZGVmaW5pdGlvbiA9ICR0aGlzLT5nZXREZWZhdWx0SW5wdXREZWZpbml0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnNpbmdsZUNvbW1hbmQpIHsKICAgICAgICAgICAgJGlucHV0RGVmaW5pdGlvbiA9ICR0aGlzLT5kZWZpbml0aW9uOwogICAgICAgICAgICAkaW5wdXREZWZpbml0aW9uLT5zZXRBcmd1bWVudHMoKTsKCiAgICAgICAgICAgIHJldHVybiAkaW5wdXREZWZpbml0aW9uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWZpbml0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgaGVscCBtZXNzYWdlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIEEgaGVscCBtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRIZWxwKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldExvbmdWZXJzaW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHdoZXRoZXIgdG8gY2F0Y2ggZXhjZXB0aW9ucyBvciBub3QgZHVyaW5nIGNvbW1hbmRzIGV4ZWN1dGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0byBjYXRjaCBleGNlcHRpb25zIG9yIG5vdCBkdXJpbmcgY29tbWFuZHMgZXhlY3V0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcmVFeGNlcHRpb25zQ2F1Z2h0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNhdGNoRXhjZXB0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgd2hldGhlciB0byBjYXRjaCBleGNlcHRpb25zIG9yIG5vdCBkdXJpbmcgY29tbWFuZHMgZXhlY3V0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRib29sZWFuIFdoZXRoZXIgdG8gY2F0Y2ggZXhjZXB0aW9ucyBvciBub3QgZHVyaW5nIGNvbW1hbmRzIGV4ZWN1dGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2F0Y2hFeGNlcHRpb25zKCRib29sZWFuKQogICAgewogICAgICAgICR0aGlzLT5jYXRjaEV4Y2VwdGlvbnMgPSAoYm9vbCkgJGJvb2xlYW47CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHdoZXRoZXIgdG8gYXV0b21hdGljYWxseSBleGl0IGFmdGVyIGEgY29tbWFuZCBleGVjdXRpb24gb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRvIGF1dG9tYXRpY2FsbHkgZXhpdCBhZnRlciBhIGNvbW1hbmQgZXhlY3V0aW9uIG9yIG5vdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNBdXRvRXhpdEVuYWJsZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXV0b0V4aXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHdoZXRoZXIgdG8gYXV0b21hdGljYWxseSBleGl0IGFmdGVyIGEgY29tbWFuZCBleGVjdXRpb24gb3Igbm90LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRib29sZWFuIFdoZXRoZXIgdG8gYXV0b21hdGljYWxseSBleGl0IGFmdGVyIGEgY29tbWFuZCBleGVjdXRpb24gb3Igbm90CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdXRvRXhpdCgkYm9vbGVhbikKICAgIHsKICAgICAgICAkdGhpcy0+YXV0b0V4aXQgPSAoYm9vbCkgJGJvb2xlYW47CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBhcHBsaWNhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBUaGUgYXBwbGljYXRpb24gbmFtZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXBwbGljYXRpb24gbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBhcHBsaWNhdGlvbiBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBhcHBsaWNhdGlvbiB2ZXJzaW9uLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBhcHBsaWNhdGlvbiB2ZXJzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWZXJzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZlcnNpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhcHBsaWNhdGlvbiB2ZXJzaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gVGhlIGFwcGxpY2F0aW9uIHZlcnNpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZlcnNpb24oJHZlcnNpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnZlcnNpb24gPSAkdmVyc2lvbjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvbmcgdmVyc2lvbiBvZiB0aGUgYXBwbGljYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGxvbmcgYXBwbGljYXRpb24gdmVyc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9uZ1ZlcnNpb24oKQogICAgewogICAgICAgIGlmICgnVU5LTk9XTicgIT09ICR0aGlzLT5nZXROYW1lKCkpIHsKICAgICAgICAgICAgaWYgKCdVTktOT1dOJyAhPT0gJHRoaXMtPmdldFZlcnNpb24oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJyVzIDxpbmZvPiVzPC9pbmZvPicsICR0aGlzLT5nZXROYW1lKCksICR0aGlzLT5nZXRWZXJzaW9uKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldE5hbWUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnQ29uc29sZSBUb29sJzsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyBhIG5ldyBjb21tYW5kLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGNvbW1hbmQgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gQ29tbWFuZCBUaGUgbmV3bHkgY3JlYXRlZCBjb21tYW5kCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWdpc3RlcigkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZChuZXcgQ29tbWFuZCgkbmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhbiBhcnJheSBvZiBjb21tYW5kIG9iamVjdHMuCiAgICAgKgogICAgICogSWYgYSBDb21tYW5kIGlzIG5vdCBlbmFibGVkIGl0IHdpbGwgbm90IGJlIGFkZGVkLgogICAgICoKICAgICAqIEBwYXJhbSBDb21tYW5kW10gJGNvbW1hbmRzIEFuIGFycmF5IG9mIGNvbW1hbmRzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb21tYW5kcyhhcnJheSAkY29tbWFuZHMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmRzIGFzICRjb21tYW5kKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGQoJGNvbW1hbmQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBjb21tYW5kIG9iamVjdC4KICAgICAqCiAgICAgKiBJZiBhIGNvbW1hbmQgd2l0aCB0aGUgc2FtZSBuYW1lIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIG92ZXJyaWRkZW4uCiAgICAgKiBJZiB0aGUgY29tbWFuZCBpcyBub3QgZW5hYmxlZCBpdCB3aWxsIG5vdCBiZSBhZGRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1hbmR8bnVsbCBUaGUgcmVnaXN0ZXJlZCBjb21tYW5kIGlmIGVuYWJsZWQgb3IgbnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkKENvbW1hbmQgJGNvbW1hbmQpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXQoKTsKCiAgICAgICAgJGNvbW1hbmQtPnNldEFwcGxpY2F0aW9uKCR0aGlzKTsKCiAgICAgICAgaWYgKCEkY29tbWFuZC0+aXNFbmFibGVkKCkpIHsKICAgICAgICAgICAgJGNvbW1hbmQtPnNldEFwcGxpY2F0aW9uKG51bGwpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvLyBXaWxsIHRocm93IGlmIHRoZSBjb21tYW5kIGlzIG5vdCBjb3JyZWN0bHkgaW5pdGlhbGl6ZWQuCiAgICAgICAgJGNvbW1hbmQtPmdldERlZmluaXRpb24oKTsKCiAgICAgICAgaWYgKCEkY29tbWFuZC0+Z2V0TmFtZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbihzcHJpbnRmKCdUaGUgY29tbWFuZCBkZWZpbmVkIGluICIlcyIgY2Fubm90IGhhdmUgYW4gZW1wdHkgbmFtZS4nLCBcZ2V0X2NsYXNzKCRjb21tYW5kKSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvbW1hbmRzWyRjb21tYW5kLT5nZXROYW1lKCldID0gJGNvbW1hbmQ7CgogICAgICAgIGZvcmVhY2ggKCRjb21tYW5kLT5nZXRBbGlhc2VzKCkgYXMgJGFsaWFzKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21tYW5kc1skYWxpYXNdID0gJGNvbW1hbmQ7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcmVnaXN0ZXJlZCBjb21tYW5kIGJ5IG5hbWUgb3IgYWxpYXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgY29tbWFuZCBuYW1lIG9yIGFsaWFzCiAgICAgKgogICAgICogQHJldHVybiBDb21tYW5kIEEgQ29tbWFuZCBvYmplY3QKICAgICAqCiAgICAgKiBAdGhyb3dzIENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbiBXaGVuIGdpdmVuIGNvbW1hbmQgbmFtZSBkb2VzIG5vdCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0KCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5pbml0KCk7CgogICAgICAgIGlmICghJHRoaXMtPmhhcygkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgY29tbWFuZCAiJXMiIGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXaGVuIHRoZSBjb21tYW5kIGhhcyBhIGRpZmZlcmVudCBuYW1lIHRoYW4gdGhlIG9uZSB1c2VkIGF0IHRoZSBjb21tYW5kIGxvYWRlciBsZXZlbAogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbW1hbmRzWyRuYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBjb21tYW5kIGNhbm5vdCBiZSBmb3VuZCBiZWNhdXNlIGl0IGlzIHJlZ2lzdGVyZWQgdW5kZXIgbXVsdGlwbGUgbmFtZXMuIE1ha2Ugc3VyZSB5b3UgZG9uXCd0IHNldCBhIGRpZmZlcmVudCBuYW1lIHZpYSBjb25zdHJ1Y3RvciBvciAic2V0TmFtZSgpIi4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmQgPSAkdGhpcy0+Y29tbWFuZHNbJG5hbWVdOwoKICAgICAgICBpZiAoJHRoaXMtPndhbnRIZWxwcykgewogICAgICAgICAgICAkdGhpcy0+d2FudEhlbHBzID0gZmFsc2U7CgogICAgICAgICAgICAkaGVscENvbW1hbmQgPSAkdGhpcy0+Z2V0KCdoZWxwJyk7CiAgICAgICAgICAgICRoZWxwQ29tbWFuZC0+c2V0Q29tbWFuZCgkY29tbWFuZCk7CgogICAgICAgICAgICByZXR1cm4gJGhlbHBDb21tYW5kOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb21tYW5kIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGNvbW1hbmQgbmFtZSBvciBhbGlhcwogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBjb21tYW5kIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXMoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXQoKTsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5jb21tYW5kc1skbmFtZV0pIHx8ICgkdGhpcy0+Y29tbWFuZExvYWRlciAmJiAkdGhpcy0+Y29tbWFuZExvYWRlci0+aGFzKCRuYW1lKSAmJiAkdGhpcy0+YWRkKCR0aGlzLT5jb21tYW5kTG9hZGVyLT5nZXQoJG5hbWUpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCB1bmlxdWUgbmFtZXNwYWNlcyB1c2VkIGJ5IGN1cnJlbnRseSByZWdpc3RlcmVkIGNvbW1hbmRzLgogICAgICoKICAgICAqIEl0IGRvZXMgbm90IHJldHVybiB0aGUgZ2xvYmFsIG5hbWVzcGFjZSB3aGljaCBhbHdheXMgZXhpc3RzLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10gQW4gYXJyYXkgb2YgbmFtZXNwYWNlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXNwYWNlcygpCiAgICB7CiAgICAgICAgJG5hbWVzcGFjZXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWxsKCkgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgaWYgKCRjb21tYW5kLT5pc0hpZGRlbigpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5hbWVzcGFjZXMgPSBhcnJheV9tZXJnZSgkbmFtZXNwYWNlcywgJHRoaXMtPmV4dHJhY3RBbGxOYW1lc3BhY2VzKCRjb21tYW5kLT5nZXROYW1lKCkpKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKCRjb21tYW5kLT5nZXRBbGlhc2VzKCkgYXMgJGFsaWFzKSB7CiAgICAgICAgICAgICAgICAkbmFtZXNwYWNlcyA9IGFycmF5X21lcmdlKCRuYW1lc3BhY2VzLCAkdGhpcy0+ZXh0cmFjdEFsbE5hbWVzcGFjZXMoJGFsaWFzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV92YWx1ZXMoYXJyYXlfdW5pcXVlKGFycmF5X2ZpbHRlcigkbmFtZXNwYWNlcykpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIGEgcmVnaXN0ZXJlZCBuYW1lc3BhY2UgYnkgYSBuYW1lIG9yIGFuIGFiYnJldmlhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lc3BhY2UgQSBuYW1lc3BhY2Ugb3IgYWJicmV2aWF0aW9uIHRvIHNlYXJjaCBmb3IKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIHJlZ2lzdGVyZWQgbmFtZXNwYWNlCiAgICAgKgogICAgICogQHRocm93cyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24gV2hlbiBuYW1lc3BhY2UgaXMgaW5jb3JyZWN0IG9yIGFtYmlndW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZE5hbWVzcGFjZSgkbmFtZXNwYWNlKQogICAgewogICAgICAgICRhbGxOYW1lc3BhY2VzID0gJHRoaXMtPmdldE5hbWVzcGFjZXMoKTsKICAgICAgICAkZXhwciA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygneyhbXjpdK3wpfScsIGZ1bmN0aW9uICgkbWF0Y2hlcykgeyByZXR1cm4gcHJlZ19xdW90ZSgkbWF0Y2hlc1sxXSkuJ1teOl0qJzsgfSwgJG5hbWVzcGFjZSk7CiAgICAgICAgJG5hbWVzcGFjZXMgPSBwcmVnX2dyZXAoJ3teJy4kZXhwci4nfScsICRhbGxOYW1lc3BhY2VzKTsKCiAgICAgICAgaWYgKGVtcHR5KCRuYW1lc3BhY2VzKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoJ1RoZXJlIGFyZSBubyBjb21tYW5kcyBkZWZpbmVkIGluIHRoZSAiJXMiIG5hbWVzcGFjZS4nLCAkbmFtZXNwYWNlKTsKCiAgICAgICAgICAgIGlmICgkYWx0ZXJuYXRpdmVzID0gJHRoaXMtPmZpbmRBbHRlcm5hdGl2ZXMoJG5hbWVzcGFjZSwgJGFsbE5hbWVzcGFjZXMpKSB7CiAgICAgICAgICAgICAgICBpZiAoMSA9PSBcY291bnQoJGFsdGVybmF0aXZlcykpIHsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiXG5cbkRpZCB5b3UgbWVhbiB0aGlzP1xuICAgICI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblxuRGlkIHlvdSBtZWFuIG9uZSBvZiB0aGVzZT9cbiAgICAiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRtZXNzYWdlIC49IGltcGxvZGUoIlxuICAgICIsICRhbHRlcm5hdGl2ZXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgQ29tbWFuZE5vdEZvdW5kRXhjZXB0aW9uKCRtZXNzYWdlLCAkYWx0ZXJuYXRpdmVzKTsKICAgICAgICB9CgogICAgICAgICRleGFjdCA9IFxpbl9hcnJheSgkbmFtZXNwYWNlLCAkbmFtZXNwYWNlcywgdHJ1ZSk7CiAgICAgICAgaWYgKFxjb3VudCgkbmFtZXNwYWNlcykgPiAxICYmICEkZXhhY3QpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCJUaGUgbmFtZXNwYWNlIFwiJXNcIiBpcyBhbWJpZ3VvdXMuXG5EaWQgeW91IG1lYW4gb25lIG9mIHRoZXNlP1xuJXMuIiwgJG5hbWVzcGFjZSwgJHRoaXMtPmdldEFiYnJldmlhdGlvblN1Z2dlc3Rpb25zKGFycmF5X3ZhbHVlcygkbmFtZXNwYWNlcykpKSwgYXJyYXlfdmFsdWVzKCRuYW1lc3BhY2VzKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGV4YWN0ID8gJG5hbWVzcGFjZSA6IHJlc2V0KCRuYW1lc3BhY2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIGEgY29tbWFuZCBieSBuYW1lIG9yIGFsaWFzLgogICAgICoKICAgICAqIENvbnRyYXJ5IHRvIGdldCwgdGhpcyBjb21tYW5kIHRyaWVzIHRvIGZpbmQgdGhlIGJlc3QKICAgICAqIG1hdGNoIGlmIHlvdSBnaXZlIGl0IGFuIGFiYnJldmlhdGlvbiBvZiBhIG5hbWUgb3IgYWxpYXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBBIGNvbW1hbmQgbmFtZSBvciBhIGNvbW1hbmQgYWxpYXMKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1hbmQgQSBDb21tYW5kIGluc3RhbmNlCiAgICAgKgogICAgICogQHRocm93cyBDb21tYW5kTm90Rm91bmRFeGNlcHRpb24gV2hlbiBjb21tYW5kIG5hbWUgaXMgaW5jb3JyZWN0IG9yIGFtYmlndW91cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZCgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdCgpOwoKICAgICAgICAkYWxpYXNlcyA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29tbWFuZHMgYXMgJGNvbW1hbmQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmQtPmdldEFsaWFzZXMoKSBhcyAkYWxpYXMpIHsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmhhcygkYWxpYXMpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1hbmRzWyRhbGlhc10gPSAkY29tbWFuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRuYW1lKTsKICAgICAgICB9CgogICAgICAgICRhbGxDb21tYW5kcyA9ICR0aGlzLT5jb21tYW5kTG9hZGVyID8gYXJyYXlfbWVyZ2UoJHRoaXMtPmNvbW1hbmRMb2FkZXItPmdldE5hbWVzKCksIGFycmF5X2tleXMoJHRoaXMtPmNvbW1hbmRzKSkgOiBhcnJheV9rZXlzKCR0aGlzLT5jb21tYW5kcyk7CiAgICAgICAgJGV4cHIgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJ3soW146XSt8KX0nLCBmdW5jdGlvbiAoJG1hdGNoZXMpIHsgcmV0dXJuIHByZWdfcXVvdGUoJG1hdGNoZXNbMV0pLidbXjpdKic7IH0sICRuYW1lKTsKICAgICAgICAkY29tbWFuZHMgPSBwcmVnX2dyZXAoJ3teJy4kZXhwci4nfScsICRhbGxDb21tYW5kcyk7CgogICAgICAgIGlmIChlbXB0eSgkY29tbWFuZHMpKSB7CiAgICAgICAgICAgICRjb21tYW5kcyA9IHByZWdfZ3JlcCgne14nLiRleHByLid9aScsICRhbGxDb21tYW5kcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBubyBjb21tYW5kcyBtYXRjaGVkIG9yIHdlIGp1c3QgbWF0Y2hlZCBuYW1lc3BhY2VzCiAgICAgICAgaWYgKGVtcHR5KCRjb21tYW5kcykgfHwgXGNvdW50KHByZWdfZ3JlcCgne14nLiRleHByLickfWknLCAkY29tbWFuZHMpKSA8IDEpIHsKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkcG9zID0gc3RycnBvcygkbmFtZSwgJzonKSkgewogICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYSBuYW1lc3BhY2UgZXhpc3RzIGFuZCBjb250YWlucyBjb21tYW5kcwogICAgICAgICAgICAgICAgJHRoaXMtPmZpbmROYW1lc3BhY2Uoc3Vic3RyKCRuYW1lLCAwLCAkcG9zKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlID0gc3ByaW50ZignQ29tbWFuZCAiJXMiIGlzIG5vdCBkZWZpbmVkLicsICRuYW1lKTsKCiAgICAgICAgICAgIGlmICgkYWx0ZXJuYXRpdmVzID0gJHRoaXMtPmZpbmRBbHRlcm5hdGl2ZXMoJG5hbWUsICRhbGxDb21tYW5kcykpIHsKICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBoaWRkZW4gY29tbWFuZHMKICAgICAgICAgICAgICAgICRhbHRlcm5hdGl2ZXMgPSBhcnJheV9maWx0ZXIoJGFsdGVybmF0aXZlcywgZnVuY3Rpb24gKCRuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEkdGhpcy0+Z2V0KCRuYW1lKS0+aXNIaWRkZW4oKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGlmICgxID09IFxjb3VudCgkYWx0ZXJuYXRpdmVzKSkgewogICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICJcblxuRGlkIHlvdSBtZWFuIHRoaXM/XG4gICAgIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gIlxuXG5EaWQgeW91IG1lYW4gb25lIG9mIHRoZXNlP1xuICAgICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSBpbXBsb2RlKCJcbiAgICAiLCAkYWx0ZXJuYXRpdmVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbigkbWVzc2FnZSwgYXJyYXlfdmFsdWVzKCRhbHRlcm5hdGl2ZXMpKTsKICAgICAgICB9CgogICAgICAgIC8vIGZpbHRlciBvdXQgYWxpYXNlcyBmb3IgY29tbWFuZHMgd2hpY2ggYXJlIGFscmVhZHkgb24gdGhlIGxpc3QKICAgICAgICBpZiAoXGNvdW50KCRjb21tYW5kcykgPiAxKSB7CiAgICAgICAgICAgICRjb21tYW5kTGlzdCA9ICR0aGlzLT5jb21tYW5kTG9hZGVyID8gYXJyYXlfbWVyZ2UoYXJyYXlfZmxpcCgkdGhpcy0+Y29tbWFuZExvYWRlci0+Z2V0TmFtZXMoKSksICR0aGlzLT5jb21tYW5kcykgOiAkdGhpcy0+Y29tbWFuZHM7CiAgICAgICAgICAgICRjb21tYW5kcyA9IGFycmF5X3VuaXF1ZShhcnJheV9maWx0ZXIoJGNvbW1hbmRzLCBmdW5jdGlvbiAoJG5hbWVPckFsaWFzKSB1c2UgKCYkY29tbWFuZExpc3QsICRjb21tYW5kcywgJiRhbGlhc2VzKSB7CiAgICAgICAgICAgICAgICBpZiAoISRjb21tYW5kTGlzdFskbmFtZU9yQWxpYXNdIGluc3RhbmNlb2YgQ29tbWFuZCkgewogICAgICAgICAgICAgICAgICAgICRjb21tYW5kTGlzdFskbmFtZU9yQWxpYXNdID0gJHRoaXMtPmNvbW1hbmRMb2FkZXItPmdldCgkbmFtZU9yQWxpYXMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRjb21tYW5kTmFtZSA9ICRjb21tYW5kTGlzdFskbmFtZU9yQWxpYXNdLT5nZXROYW1lKCk7CgogICAgICAgICAgICAgICAgJGFsaWFzZXNbJG5hbWVPckFsaWFzXSA9ICRjb21tYW5kTmFtZTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJGNvbW1hbmROYW1lID09PSAkbmFtZU9yQWxpYXMgfHwgIVxpbl9hcnJheSgkY29tbWFuZE5hbWUsICRjb21tYW5kcyk7CiAgICAgICAgICAgIH0pKTsKICAgICAgICB9CgogICAgICAgICRleGFjdCA9IFxpbl9hcnJheSgkbmFtZSwgJGNvbW1hbmRzLCB0cnVlKSB8fCBpc3NldCgkYWxpYXNlc1skbmFtZV0pOwogICAgICAgIGlmIChcY291bnQoJGNvbW1hbmRzKSA+IDEgJiYgISRleGFjdCkgewogICAgICAgICAgICAkdXNhYmxlV2lkdGggPSAkdGhpcy0+dGVybWluYWwtPmdldFdpZHRoKCkgLSAxMDsKICAgICAgICAgICAgJGFiYnJldnMgPSBhcnJheV92YWx1ZXMoJGNvbW1hbmRzKTsKICAgICAgICAgICAgJG1heExlbiA9IDA7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhYmJyZXZzIGFzICRhYmJyZXYpIHsKICAgICAgICAgICAgICAgICRtYXhMZW4gPSBtYXgoSGVscGVyOjpzdHJsZW4oJGFiYnJldiksICRtYXhMZW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRhYmJyZXZzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkY21kKSB1c2UgKCRjb21tYW5kTGlzdCwgJHVzYWJsZVdpZHRoLCAkbWF4TGVuKSB7CiAgICAgICAgICAgICAgICBpZiAoJGNvbW1hbmRMaXN0WyRjbWRdLT5pc0hpZGRlbigpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRhYmJyZXYgPSBzdHJfcGFkKCRjbWQsICRtYXhMZW4sICcgJykuJyAnLiRjb21tYW5kTGlzdFskY21kXS0+Z2V0RGVzY3JpcHRpb24oKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gSGVscGVyOjpzdHJsZW4oJGFiYnJldikgPiAkdXNhYmxlV2lkdGggPyBIZWxwZXI6OnN1YnN0cigkYWJicmV2LCAwLCAkdXNhYmxlV2lkdGggLSAzKS4nLi4uJyA6ICRhYmJyZXY7CiAgICAgICAgICAgIH0sIGFycmF5X3ZhbHVlcygkY29tbWFuZHMpKTsKICAgICAgICAgICAgJHN1Z2dlc3Rpb25zID0gJHRoaXMtPmdldEFiYnJldmlhdGlvblN1Z2dlc3Rpb25zKGFycmF5X2ZpbHRlcigkYWJicmV2cykpOwoKICAgICAgICAgICAgdGhyb3cgbmV3IENvbW1hbmROb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKCJDb21tYW5kIFwiJXNcIiBpcyBhbWJpZ3VvdXMuXG5EaWQgeW91IG1lYW4gb25lIG9mIHRoZXNlP1xuJXMuIiwgJG5hbWUsICRzdWdnZXN0aW9ucyksIGFycmF5X3ZhbHVlcygkY29tbWFuZHMpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0KCRleGFjdCA/ICRuYW1lIDogcmVzZXQoJGNvbW1hbmRzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb21tYW5kcyAocmVnaXN0ZXJlZCBpbiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIGlmIHByb3ZpZGVkKS4KICAgICAqCiAgICAgKiBUaGUgYXJyYXkga2V5cyBhcmUgdGhlIGZ1bGwgbmFtZXMgYW5kIHRoZSB2YWx1ZXMgdGhlIGNvbW1hbmQgaW5zdGFuY2VzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWVzcGFjZSBBIG5hbWVzcGFjZSBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBDb21tYW5kW10gQW4gYXJyYXkgb2YgQ29tbWFuZCBpbnN0YW5jZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFsbCgkbmFtZXNwYWNlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdCgpOwoKICAgICAgICBpZiAobnVsbCA9PT0gJG5hbWVzcGFjZSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5jb21tYW5kTG9hZGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29tbWFuZHMgPSAkdGhpcy0+Y29tbWFuZHM7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jb21tYW5kTG9hZGVyLT5nZXROYW1lcygpIGFzICRuYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRjb21tYW5kc1skbmFtZV0pICYmICR0aGlzLT5oYXMoJG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvbW1hbmRzWyRuYW1lXSA9ICR0aGlzLT5nZXQoJG5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGNvbW1hbmRzOwogICAgICAgIH0KCiAgICAgICAgJGNvbW1hbmRzID0gW107CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbW1hbmRzIGFzICRuYW1lID0+ICRjb21tYW5kKSB7CiAgICAgICAgICAgIGlmICgkbmFtZXNwYWNlID09PSAkdGhpcy0+ZXh0cmFjdE5hbWVzcGFjZSgkbmFtZSwgc3Vic3RyX2NvdW50KCRuYW1lc3BhY2UsICc6JykgKyAxKSkgewogICAgICAgICAgICAgICAgJGNvbW1hbmRzWyRuYW1lXSA9ICRjb21tYW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmNvbW1hbmRMb2FkZXIpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbW1hbmRMb2FkZXItPmdldE5hbWVzKCkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNvbW1hbmRzWyRuYW1lXSkgJiYgJG5hbWVzcGFjZSA9PT0gJHRoaXMtPmV4dHJhY3ROYW1lc3BhY2UoJG5hbWUsIHN1YnN0cl9jb3VudCgkbmFtZXNwYWNlLCAnOicpICsgMSkgJiYgJHRoaXMtPmhhcygkbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZHNbJG5hbWVdID0gJHRoaXMtPmdldCgkbmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tbWFuZHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHBvc3NpYmxlIGFiYnJldmlhdGlvbnMgZ2l2ZW4gYSBzZXQgb2YgbmFtZXMuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRuYW1lcyBBbiBhcnJheSBvZiBuYW1lcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgYWJicmV2aWF0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEFiYnJldmlhdGlvbnMoJG5hbWVzKQogICAgewogICAgICAgICRhYmJyZXZzID0gW107CiAgICAgICAgZm9yZWFjaCAoJG5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgIGZvciAoJGxlbiA9IFxzdHJsZW4oJG5hbWUpOyAkbGVuID4gMDsgLS0kbGVuKSB7CiAgICAgICAgICAgICAgICAkYWJicmV2ID0gc3Vic3RyKCRuYW1lLCAwLCAkbGVuKTsKICAgICAgICAgICAgICAgICRhYmJyZXZzWyRhYmJyZXZdW10gPSAkbmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRhYmJyZXZzOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVycyBhIGNhdWdodCBleGNlcHRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXJFeGNlcHRpb24oXEV4Y2VwdGlvbiAkZSwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJG91dHB1dC0+d3JpdGVsbignJywgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfUVVJRVQpOwoKICAgICAgICAkdGhpcy0+ZG9SZW5kZXJFeGNlcHRpb24oJGUsICRvdXRwdXQpOwoKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnJ1bm5pbmdDb21tYW5kKSB7CiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oc3ByaW50ZignPGluZm8+JXM8L2luZm8+Jywgc3ByaW50ZigkdGhpcy0+cnVubmluZ0NvbW1hbmQtPmdldFN5bm9wc2lzKCksICR0aGlzLT5nZXROYW1lKCkpKSwgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfUVVJRVQpOwogICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCcnLCBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCk7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBkb1JlbmRlckV4Y2VwdGlvbihcRXhjZXB0aW9uICRlLCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCkKICAgIHsKICAgICAgICBkbyB7CiAgICAgICAgICAgICRtZXNzYWdlID0gdHJpbSgkZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgaWYgKCcnID09PSAkbWVzc2FnZSB8fCBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFIDw9ICRvdXRwdXQtPmdldFZlcmJvc2l0eSgpKSB7CiAgICAgICAgICAgICAgICAkdGl0bGUgPSBzcHJpbnRmKCcgIFslcyVzXSAgJywgXGdldF9jbGFzcygkZSksIDAgIT09ICgkY29kZSA9ICRlLT5nZXRDb2RlKCkpID8gJyAoJy4kY29kZS4nKScgOiAnJyk7CiAgICAgICAgICAgICAgICAkbGVuID0gSGVscGVyOjpzdHJsZW4oJHRpdGxlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRsZW4gPSAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkd2lkdGggPSAkdGhpcy0+dGVybWluYWwtPmdldFdpZHRoKCkgPyAkdGhpcy0+dGVybWluYWwtPmdldFdpZHRoKCkgLSAxIDogXFBIUF9JTlRfTUFYOwogICAgICAgICAgICAvLyBISFZNIG9ubHkgYWNjZXB0cyAzMiBiaXRzIGludGVnZXIgaW4gc3RyX3NwbGl0LCBldmVuIHdoZW4gUEhQX0lOVF9NQVggaXMgYSA2NCBiaXQgaW50ZWdlcjogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2hodm0vaXNzdWVzLzEzMjcKICAgICAgICAgICAgaWYgKFxkZWZpbmVkKCdISFZNX1ZFUlNJT04nKSAmJiAkd2lkdGggPiAxIDw8IDMxKSB7CiAgICAgICAgICAgICAgICAkd2lkdGggPSAxIDw8IDMxOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lcyA9IFtdOwogICAgICAgICAgICBmb3JlYWNoICgnJyAhPT0gJG1lc3NhZ2UgPyBwcmVnX3NwbGl0KCcvXHI/XG4vJywgJG1lc3NhZ2UpIDogW10gYXMgJGxpbmUpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5zcGxpdFN0cmluZ0J5V2lkdGgoJGxpbmUsICR3aWR0aCAtIDQpIGFzICRsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcHJlLWZvcm1hdCBsaW5lcyB0byBnZXQgdGhlIHJpZ2h0IHN0cmluZyBsZW5ndGgKICAgICAgICAgICAgICAgICAgICAkbGluZUxlbmd0aCA9IEhlbHBlcjo6c3RybGVuKCRsaW5lKSArIDQ7CiAgICAgICAgICAgICAgICAgICAgJGxpbmVzW10gPSBbJGxpbmUsICRsaW5lTGVuZ3RoXTsKCiAgICAgICAgICAgICAgICAgICAgJGxlbiA9IG1heCgkbGluZUxlbmd0aCwgJGxlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlcyA9IFtdOwogICAgICAgICAgICBpZiAoISRlIGluc3RhbmNlb2YgRXhjZXB0aW9uSW50ZXJmYWNlIHx8IE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUkJPU0UgPD0gJG91dHB1dC0+Z2V0VmVyYm9zaXR5KCkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlc1tdID0gc3ByaW50ZignPGNvbW1lbnQ+JXM8L2NvbW1lbnQ+JywgT3V0cHV0Rm9ybWF0dGVyOjplc2NhcGUoc3ByaW50ZignSW4gJXMgbGluZSAlczonLCBiYXNlbmFtZSgkZS0+Z2V0RmlsZSgpKSA/OiAnbi9hJywgJGUtPmdldExpbmUoKSA/OiAnbi9hJykpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbWVzc2FnZXNbXSA9ICRlbXB0eUxpbmUgPSBzcHJpbnRmKCc8ZXJyb3I+JXM8L2Vycm9yPicsIHN0cl9yZXBlYXQoJyAnLCAkbGVuKSk7CiAgICAgICAgICAgIGlmICgnJyA9PT0gJG1lc3NhZ2UgfHwgT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSQk9TRSA8PSAkb3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSBzcHJpbnRmKCc8ZXJyb3I+JXMlczwvZXJyb3I+JywgJHRpdGxlLCBzdHJfcmVwZWF0KCcgJywgbWF4KDAsICRsZW4gLSBIZWxwZXI6OnN0cmxlbigkdGl0bGUpKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSBzcHJpbnRmKCc8ZXJyb3I+ICAlcyAgJXM8L2Vycm9yPicsIE91dHB1dEZvcm1hdHRlcjo6ZXNjYXBlKCRsaW5lWzBdKSwgc3RyX3JlcGVhdCgnICcsICRsZW4gLSAkbGluZVsxXSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRtZXNzYWdlc1tdID0gJGVtcHR5TGluZTsKICAgICAgICAgICAgJG1lc3NhZ2VzW10gPSAnJzsKCiAgICAgICAgICAgICRvdXRwdXQtPndyaXRlbG4oJG1lc3NhZ2VzLCBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCk7CgogICAgICAgICAgICBpZiAoT3V0cHV0SW50ZXJmYWNlOjpWRVJCT1NJVFlfVkVSQk9TRSA8PSAkb3V0cHV0LT5nZXRWZXJib3NpdHkoKSkgewogICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbignPGNvbW1lbnQ+RXhjZXB0aW9uIHRyYWNlOjwvY29tbWVudD4nLCBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCk7CgogICAgICAgICAgICAgICAgLy8gZXhjZXB0aW9uIHJlbGF0ZWQgcHJvcGVydGllcwogICAgICAgICAgICAgICAgJHRyYWNlID0gJGUtPmdldFRyYWNlKCk7CgogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkdHJhY2UsIFsKICAgICAgICAgICAgICAgICAgICAnZnVuY3Rpb24nID0+ICcnLAogICAgICAgICAgICAgICAgICAgICdmaWxlJyA9PiAkZS0+Z2V0RmlsZSgpID86ICduL2EnLAogICAgICAgICAgICAgICAgICAgICdsaW5lJyA9PiAkZS0+Z2V0TGluZSgpID86ICduL2EnLAogICAgICAgICAgICAgICAgICAgICdhcmdzJyA9PiBbXSwKICAgICAgICAgICAgICAgIF0pOwoKICAgICAgICAgICAgICAgIGZvciAoJGkgPSAwLCAkY291bnQgPSBcY291bnQoJHRyYWNlKTsgJGkgPCAkY291bnQ7ICsrJGkpIHsKICAgICAgICAgICAgICAgICAgICAkY2xhc3MgPSBpc3NldCgkdHJhY2VbJGldWydjbGFzcyddKSA/ICR0cmFjZVskaV1bJ2NsYXNzJ10gOiAnJzsKICAgICAgICAgICAgICAgICAgICAkdHlwZSA9IGlzc2V0KCR0cmFjZVskaV1bJ3R5cGUnXSkgPyAkdHJhY2VbJGldWyd0eXBlJ10gOiAnJzsKICAgICAgICAgICAgICAgICAgICAkZnVuY3Rpb24gPSBpc3NldCgkdHJhY2VbJGldWydmdW5jdGlvbiddKSA/ICR0cmFjZVskaV1bJ2Z1bmN0aW9uJ10gOiAnJzsKICAgICAgICAgICAgICAgICAgICAkZmlsZSA9IGlzc2V0KCR0cmFjZVskaV1bJ2ZpbGUnXSkgPyAkdHJhY2VbJGldWydmaWxlJ10gOiAnbi9hJzsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9IGlzc2V0KCR0cmFjZVskaV1bJ2xpbmUnXSkgPyAkdHJhY2VbJGldWydsaW5lJ10gOiAnbi9hJzsKCiAgICAgICAgICAgICAgICAgICAgJG91dHB1dC0+d3JpdGVsbihzcHJpbnRmKCcgJXMlcyBhdCA8aW5mbz4lczolczwvaW5mbz4nLCAkY2xhc3MsICRmdW5jdGlvbiA/ICR0eXBlLiRmdW5jdGlvbi4nKCknIDogJycsICRmaWxlLCAkbGluZSksIE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1FVSUVUKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkb3V0cHV0LT53cml0ZWxuKCcnLCBPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IHdoaWxlICgkZSA9ICRlLT5nZXRQcmV2aW91cygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRyaWVzIHRvIGZpZ3VyZSBvdXQgdGhlIHRlcm1pbmFsIHdpZHRoIGluIHdoaWNoIHRoaXMgYXBwbGljYXRpb24gcnVucy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxudWxsCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjIsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBDcmVhdGUgYSBUZXJtaW5hbCBpbnN0YW5jZSBpbnN0ZWFkLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0VGVybWluYWxXaWR0aCgpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICIlcygpIiBtZXRob2QgaXMgZGVwcmVjYXRlZCBhcyBvZiAzLjIgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIENyZWF0ZSBhIFRlcm1pbmFsIGluc3RhbmNlIGluc3RlYWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVybWluYWwtPmdldFdpZHRoKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUcmllcyB0byBmaWd1cmUgb3V0IHRoZSB0ZXJtaW5hbCBoZWlnaHQgaW4gd2hpY2ggdGhpcyBhcHBsaWNhdGlvbiBydW5zLgogICAgICoKICAgICAqIEByZXR1cm4gaW50fG51bGwKICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMiwgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIENyZWF0ZSBhIFRlcm1pbmFsIGluc3RhbmNlIGluc3RlYWQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRUZXJtaW5hbEhlaWdodCgpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICIlcygpIiBtZXRob2QgaXMgZGVwcmVjYXRlZCBhcyBvZiAzLjIgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIENyZWF0ZSBhIFRlcm1pbmFsIGluc3RhbmNlIGluc3RlYWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+dGVybWluYWwtPmdldEhlaWdodCgpOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZXMgdG8gZmlndXJlIG91dCB0aGUgdGVybWluYWwgZGltZW5zaW9ucyBiYXNlZCBvbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFycmF5IGNvbnRhaW5pbmcgd2lkdGggYW5kIGhlaWdodAogICAgICoKICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMy4yLCB0byBiZSByZW1vdmVkIGluIDQuMC4gQ3JlYXRlIGEgVGVybWluYWwgaW5zdGFuY2UgaW5zdGVhZC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlcm1pbmFsRGltZW5zaW9ucygpCiAgICB7CiAgICAgICAgQHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignVGhlICIlcygpIiBtZXRob2QgaXMgZGVwcmVjYXRlZCBhcyBvZiAzLjIgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiA0LjAuIENyZWF0ZSBhIFRlcm1pbmFsIGluc3RhbmNlIGluc3RlYWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIHJldHVybiBbJHRoaXMtPnRlcm1pbmFsLT5nZXRXaWR0aCgpLCAkdGhpcy0+dGVybWluYWwtPmdldEhlaWdodCgpXTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGVybWluYWwgZGltZW5zaW9ucy4KICAgICAqCiAgICAgKiBDYW4gYmUgdXNlZnVsIHRvIGZvcmNlIHRlcm1pbmFsIGRpbWVuc2lvbnMgZm9yIGZ1bmN0aW9uYWwgdGVzdHMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkd2lkdGggIFRoZSB3aWR0aAogICAgICogQHBhcmFtIGludCAkaGVpZ2h0IFRoZSBoZWlnaHQKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAzLjIsIHRvIGJlIHJlbW92ZWQgaW4gNC4wLiBTZXQgdGhlIENPTFVNTlMgYW5kIExJTkVTIGVudiB2YXJzIGluc3RlYWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZXJtaW5hbERpbWVuc2lvbnMoJHdpZHRoLCAkaGVpZ2h0KQogICAgewogICAgICAgIEB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ1RoZSAiJXMoKSIgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYXMgb2YgMy4yIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBTZXQgdGhlIENPTFVNTlMgYW5kIExJTkVTIGVudiB2YXJzIGluc3RlYWQuJywgX19NRVRIT0RfXyksIFxFX1VTRVJfREVQUkVDQVRFRCk7CgogICAgICAgIHB1dGVudignQ09MVU1OUz0nLiR3aWR0aCk7CiAgICAgICAgcHV0ZW52KCdMSU5FUz0nLiRoZWlnaHQpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25maWd1cmVzIHRoZSBpbnB1dCBhbmQgb3V0cHV0IGluc3RhbmNlcyBiYXNlZCBvbiB0aGUgdXNlciBhcmd1bWVudHMgYW5kIG9wdGlvbnMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25maWd1cmVJTyhJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0KQogICAgewogICAgICAgIGlmICh0cnVlID09PSAkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbihbJy0tYW5zaSddLCB0cnVlKSkgewogICAgICAgICAgICAkb3V0cHV0LT5zZXREZWNvcmF0ZWQodHJ1ZSk7CiAgICAgICAgfSBlbHNlaWYgKHRydWUgPT09ICRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKFsnLS1uby1hbnNpJ10sIHRydWUpKSB7CiAgICAgICAgICAgICRvdXRwdXQtPnNldERlY29yYXRlZChmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAodHJ1ZSA9PT0gJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oWyctLW5vLWludGVyYWN0aW9uJywgJy1uJ10sIHRydWUpKSB7CiAgICAgICAgICAgICRpbnB1dC0+c2V0SW50ZXJhY3RpdmUoZmFsc2UpOwogICAgICAgIH0gZWxzZWlmIChcZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9pc2F0dHknKSkgewogICAgICAgICAgICAkaW5wdXRTdHJlYW0gPSBudWxsOwoKICAgICAgICAgICAgaWYgKCRpbnB1dCBpbnN0YW5jZW9mIFN0cmVhbWFibGVJbnB1dEludGVyZmFjZSkgewogICAgICAgICAgICAgICAgJGlucHV0U3RyZWFtID0gJGlucHV0LT5nZXRTdHJlYW0oKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhpcyBjaGVjayBlbnN1cmVzIHRoYXQgY2FsbGluZyBRdWVzdGlvbkhlbHBlcjo6c2V0SW5wdXRTdHJlYW0oKSB3b3JrcwogICAgICAgICAgICAvLyBUbyBiZSByZW1vdmVkIGluIDQuMCAoaW4gdGhlIHNhbWUgdGltZSBhcyBRdWVzdGlvbkhlbHBlcjo6c2V0SW5wdXRTdHJlYW0pCiAgICAgICAgICAgIGlmICghJGlucHV0U3RyZWFtICYmICR0aGlzLT5nZXRIZWxwZXJTZXQoKS0+aGFzKCdxdWVzdGlvbicpKSB7CiAgICAgICAgICAgICAgICAkaW5wdXRTdHJlYW0gPSAkdGhpcy0+Z2V0SGVscGVyU2V0KCktPmdldCgncXVlc3Rpb24nKS0+Z2V0SW5wdXRTdHJlYW0oZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIUBwb3NpeF9pc2F0dHkoJGlucHV0U3RyZWFtKSAmJiBmYWxzZSA9PT0gZ2V0ZW52KCdTSEVMTF9JTlRFUkFDVElWRScpKSB7CiAgICAgICAgICAgICAgICAkaW5wdXQtPnNldEludGVyYWN0aXZlKGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3dpdGNoICgkc2hlbGxWZXJib3NpdHkgPSAoaW50KSBnZXRlbnYoJ1NIRUxMX1ZFUkJPU0lUWScpKSB7CiAgICAgICAgICAgIGNhc2UgLTE6ICRvdXRwdXQtPnNldFZlcmJvc2l0eShPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9RVUlFVCk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDE6ICRvdXRwdXQtPnNldFZlcmJvc2l0eShPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFKTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjogJG91dHB1dC0+c2V0VmVyYm9zaXR5KE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDM6ICRvdXRwdXQtPnNldFZlcmJvc2l0eShPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9ERUJVRyk7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAkc2hlbGxWZXJib3NpdHkgPSAwOyBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICh0cnVlID09PSAkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbihbJy0tcXVpZXQnLCAnLXEnXSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJG91dHB1dC0+c2V0VmVyYm9zaXR5KE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1FVSUVUKTsKICAgICAgICAgICAgJHNoZWxsVmVyYm9zaXR5ID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCRpbnB1dC0+aGFzUGFyYW1ldGVyT3B0aW9uKCctdnZ2JywgdHJ1ZSkgfHwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZT0zJywgdHJ1ZSkgfHwgMyA9PT0gJGlucHV0LT5nZXRQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZScsIGZhbHNlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJG91dHB1dC0+c2V0VmVyYm9zaXR5KE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX0RFQlVHKTsKICAgICAgICAgICAgICAgICRzaGVsbFZlcmJvc2l0eSA9IDM7CiAgICAgICAgICAgIH0gZWxzZWlmICgkaW5wdXQtPmhhc1BhcmFtZXRlck9wdGlvbignLXZ2JywgdHJ1ZSkgfHwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZT0yJywgdHJ1ZSkgfHwgMiA9PT0gJGlucHV0LT5nZXRQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZScsIGZhbHNlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJG91dHB1dC0+c2V0VmVyYm9zaXR5KE91dHB1dEludGVyZmFjZTo6VkVSQk9TSVRZX1ZFUllfVkVSQk9TRSk7CiAgICAgICAgICAgICAgICAkc2hlbGxWZXJib3NpdHkgPSAyOwogICAgICAgICAgICB9IGVsc2VpZiAoJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy12JywgdHJ1ZSkgfHwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZT0xJywgdHJ1ZSkgfHwgJGlucHV0LT5oYXNQYXJhbWV0ZXJPcHRpb24oJy0tdmVyYm9zZScsIHRydWUpIHx8ICRpbnB1dC0+Z2V0UGFyYW1ldGVyT3B0aW9uKCctLXZlcmJvc2UnLCBmYWxzZSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICRvdXRwdXQtPnNldFZlcmJvc2l0eShPdXRwdXRJbnRlcmZhY2U6OlZFUkJPU0lUWV9WRVJCT1NFKTsKICAgICAgICAgICAgICAgICRzaGVsbFZlcmJvc2l0eSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgtMSA9PT0gJHNoZWxsVmVyYm9zaXR5KSB7CiAgICAgICAgICAgICRpbnB1dC0+c2V0SW50ZXJhY3RpdmUoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcHV0ZW52KCdTSEVMTF9WRVJCT1NJVFk9Jy4kc2hlbGxWZXJib3NpdHkpOwogICAgICAgICRfRU5WWydTSEVMTF9WRVJCT1NJVFknXSA9ICRzaGVsbFZlcmJvc2l0eTsKICAgICAgICAkX1NFUlZFUlsnU0hFTExfVkVSQk9TSVRZJ10gPSAkc2hlbGxWZXJib3NpdHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW5zIHRoZSBjdXJyZW50IGNvbW1hbmQuCiAgICAgKgogICAgICogSWYgYW4gZXZlbnQgZGlzcGF0Y2hlciBoYXMgYmVlbiBhdHRhY2hlZCB0byB0aGUgYXBwbGljYXRpb24sCiAgICAgKiBldmVudHMgYXJlIGFsc28gZGlzcGF0Y2hlZCBkdXJpbmcgdGhlIGxpZmUtY3ljbGUgb2YgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgMCBpZiBldmVyeXRoaW5nIHdlbnQgZmluZSwgb3IgYW4gZXJyb3IgY29kZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG9SdW5Db21tYW5kKENvbW1hbmQgJGNvbW1hbmQsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGNvbW1hbmQtPmdldEhlbHBlclNldCgpIGFzICRoZWxwZXIpIHsKICAgICAgICAgICAgaWYgKCRoZWxwZXIgaW5zdGFuY2VvZiBJbnB1dEF3YXJlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICAgICAkaGVscGVyLT5zZXRJbnB1dCgkaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmRpc3BhdGNoZXIpIHsKICAgICAgICAgICAgcmV0dXJuICRjb21tYW5kLT5ydW4oJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIC8vIGJpbmQgYmVmb3JlIHRoZSBjb25zb2xlLmNvbW1hbmQgZXZlbnQsIHNvIHRoZSBsaXN0ZW5lcnMgaGF2ZSBhY2Nlc3MgdG8gaW5wdXQgb3B0aW9ucy9hcmd1bWVudHMKICAgICAgICB0cnkgewogICAgICAgICAgICAkY29tbWFuZC0+bWVyZ2VBcHBsaWNhdGlvbkRlZmluaXRpb24oKTsKICAgICAgICAgICAgJGlucHV0LT5iaW5kKCRjb21tYW5kLT5nZXREZWZpbml0aW9uKCkpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbkludGVyZmFjZSAkZSkgewogICAgICAgICAgICAvLyBpZ25vcmUgaW52YWxpZCBvcHRpb25zL2FyZ3VtZW50cyBmb3Igbm93LCB0byBhbGxvdyB0aGUgZXZlbnQgbGlzdGVuZXJzIHRvIGN1c3RvbWl6ZSB0aGUgSW5wdXREZWZpbml0aW9uCiAgICAgICAgfQoKICAgICAgICAkZXZlbnQgPSBuZXcgQ29uc29sZUNvbW1hbmRFdmVudCgkY29tbWFuZCwgJGlucHV0LCAkb3V0cHV0KTsKICAgICAgICAkZSA9IG51bGw7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5kaXNwYXRjaGVyLT5kaXNwYXRjaChDb25zb2xlRXZlbnRzOjpDT01NQU5ELCAkZXZlbnQpOwoKICAgICAgICAgICAgaWYgKCRldmVudC0+Y29tbWFuZFNob3VsZFJ1bigpKSB7CiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSAkY29tbWFuZC0+cnVuKCRpbnB1dCwgJG91dHB1dCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZXhpdENvZGUgPSBDb25zb2xlQ29tbWFuZEV2ZW50OjpSRVRVUk5fQ09ERV9ESVNBQkxFRDsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgfQogICAgICAgIGlmIChudWxsICE9PSAkZSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmRpc3BhdGNoZXItPmhhc0xpc3RlbmVycyhDb25zb2xlRXZlbnRzOjpFWENFUFRJT04pKSB7CiAgICAgICAgICAgICAgICAkeCA9ICRlIGluc3RhbmNlb2YgXEV4Y2VwdGlvbiA/ICRlIDogbmV3IEZhdGFsVGhyb3dhYmxlRXJyb3IoJGUpOwogICAgICAgICAgICAgICAgJGV2ZW50ID0gbmV3IENvbnNvbGVFeGNlcHRpb25FdmVudCgkY29tbWFuZCwgJGlucHV0LCAkb3V0cHV0LCAkeCwgJHgtPmdldENvZGUoKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZGlzcGF0Y2hlci0+ZGlzcGF0Y2goQ29uc29sZUV2ZW50czo6RVhDRVBUSU9OLCAkZXZlbnQpOwoKICAgICAgICAgICAgICAgIGlmICgkeCAhPT0gJGV2ZW50LT5nZXRFeGNlcHRpb24oKSkgewogICAgICAgICAgICAgICAgICAgICRlID0gJGV2ZW50LT5nZXRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkZXZlbnQgPSBuZXcgQ29uc29sZUVycm9yRXZlbnQoJGlucHV0LCAkb3V0cHV0LCAkZSwgJGNvbW1hbmQpOwogICAgICAgICAgICAkdGhpcy0+ZGlzcGF0Y2hlci0+ZGlzcGF0Y2goQ29uc29sZUV2ZW50czo6RVJST1IsICRldmVudCk7CiAgICAgICAgICAgICRlID0gJGV2ZW50LT5nZXRFcnJvcigpOwoKICAgICAgICAgICAgaWYgKDAgPT09ICRleGl0Q29kZSA9ICRldmVudC0+Z2V0RXhpdENvZGUoKSkgewogICAgICAgICAgICAgICAgJGUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkZXZlbnQgPSBuZXcgQ29uc29sZVRlcm1pbmF0ZUV2ZW50KCRjb21tYW5kLCAkaW5wdXQsICRvdXRwdXQsICRleGl0Q29kZSk7CiAgICAgICAgJHRoaXMtPmRpc3BhdGNoZXItPmRpc3BhdGNoKENvbnNvbGVFdmVudHM6OlRFUk1JTkFURSwgJGV2ZW50KTsKCiAgICAgICAgaWYgKG51bGwgIT09ICRlKSB7CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRldmVudC0+Z2V0RXhpdENvZGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQgYmFzZWQgb24gaW5wdXQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q29tbWFuZE5hbWUoSW5wdXRJbnRlcmZhY2UgJGlucHV0KQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2luZ2xlQ29tbWFuZCA/ICR0aGlzLT5kZWZhdWx0Q29tbWFuZCA6ICRpbnB1dC0+Z2V0Rmlyc3RBcmd1bWVudCgpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZGVmYXVsdCBpbnB1dCBkZWZpbml0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXREZWZpbml0aW9uIEFuIElucHV0RGVmaW5pdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0RGVmYXVsdElucHV0RGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBJbnB1dERlZmluaXRpb24oWwogICAgICAgICAgICBuZXcgSW5wdXRBcmd1bWVudCgnY29tbWFuZCcsIElucHV0QXJndW1lbnQ6OlJFUVVJUkVELCAnVGhlIGNvbW1hbmQgdG8gZXhlY3V0ZScpLAoKICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCctLWhlbHAnLCAnLWgnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc3BsYXkgdGhpcyBoZWxwIG1lc3NhZ2UnKSwKICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCctLXF1aWV0JywgJy1xJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEbyBub3Qgb3V0cHV0IGFueSBtZXNzYWdlJyksCiAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignLS12ZXJib3NlJywgJy12fHZ2fHZ2dicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnSW5jcmVhc2UgdGhlIHZlcmJvc2l0eSBvZiBtZXNzYWdlczogMSBmb3Igbm9ybWFsIG91dHB1dCwgMiBmb3IgbW9yZSB2ZXJib3NlIG91dHB1dCBhbmQgMyBmb3IgZGVidWcnKSwKICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCctLXZlcnNpb24nLCAnLVYnLCBJbnB1dE9wdGlvbjo6VkFMVUVfTk9ORSwgJ0Rpc3BsYXkgdGhpcyBhcHBsaWNhdGlvbiB2ZXJzaW9uJyksCiAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignLS1hbnNpJywgJycsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRm9yY2UgQU5TSSBvdXRwdXQnKSwKICAgICAgICAgICAgbmV3IElucHV0T3B0aW9uKCctLW5vLWFuc2knLCAnJywgSW5wdXRPcHRpb246OlZBTFVFX05PTkUsICdEaXNhYmxlIEFOU0kgb3V0cHV0JyksCiAgICAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignLS1uby1pbnRlcmFjdGlvbicsICctbicsIElucHV0T3B0aW9uOjpWQUxVRV9OT05FLCAnRG8gbm90IGFzayBhbnkgaW50ZXJhY3RpdmUgcXVlc3Rpb24nKSwKICAgICAgICBdKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRlZmF1bHQgY29tbWFuZHMgdGhhdCBzaG91bGQgYWx3YXlzIGJlIGF2YWlsYWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1hbmRbXSBBbiBhcnJheSBvZiBkZWZhdWx0IENvbW1hbmQgaW5zdGFuY2VzCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXREZWZhdWx0Q29tbWFuZHMoKQogICAgewogICAgICAgIHJldHVybiBbbmV3IEhlbHBDb21tYW5kKCksIG5ldyBMaXN0Q29tbWFuZCgpXTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRlZmF1bHQgaGVscGVyIHNldCB3aXRoIHRoZSBoZWxwZXJzIHRoYXQgc2hvdWxkIGFsd2F5cyBiZSBhdmFpbGFibGUuCiAgICAgKgogICAgICogQHJldHVybiBIZWxwZXJTZXQgQSBIZWxwZXJTZXQgaW5zdGFuY2UKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldERlZmF1bHRIZWxwZXJTZXQoKQogICAgewogICAgICAgIHJldHVybiBuZXcgSGVscGVyU2V0KFsKICAgICAgICAgICAgbmV3IEZvcm1hdHRlckhlbHBlcigpLAogICAgICAgICAgICBuZXcgRGVidWdGb3JtYXR0ZXJIZWxwZXIoKSwKICAgICAgICAgICAgbmV3IFByb2Nlc3NIZWxwZXIoKSwKICAgICAgICAgICAgbmV3IFF1ZXN0aW9uSGVscGVyKCksCiAgICAgICAgXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFiYnJldmlhdGVkIHN1Z2dlc3Rpb25zIGluIHN0cmluZyBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhYmJyZXZzIEFiYnJldmlhdGVkIHN1Z2dlc3Rpb25zIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGZvcm1hdHRlZCBzdHJpbmcgb2YgYWJicmV2aWF0ZWQgc3VnZ2VzdGlvbnMKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRBYmJyZXZpYXRpb25TdWdnZXN0aW9ucygkYWJicmV2cykKICAgIHsKICAgICAgICByZXR1cm4gJyAgICAnLmltcGxvZGUoIlxuICAgICIsICRhYmJyZXZzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBwYXJ0IG9mIHRoZSBjb21tYW5kIG5hbWUuCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgaXMgbm90IHBhcnQgb2YgcHVibGljIEFQSSBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGRpcmVjdGx5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIFRoZSBmdWxsIG5hbWUgb2YgdGhlIGNvbW1hbmQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbWl0IFRoZSBtYXhpbXVtIG51bWJlciBvZiBwYXJ0cyBvZiB0aGUgbmFtZXNwYWNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIG5hbWVzcGFjZSBvZiB0aGUgY29tbWFuZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXh0cmFjdE5hbWVzcGFjZSgkbmFtZSwgJGxpbWl0ID0gbnVsbCkKICAgIHsKICAgICAgICAkcGFydHMgPSBleHBsb2RlKCc6JywgJG5hbWUsIC0xKTsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoJzonLCBudWxsID09PSAkbGltaXQgPyAkcGFydHMgOiBcYXJyYXlfc2xpY2UoJHBhcnRzLCAwLCAkbGltaXQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIGFsdGVybmF0aXZlIG9mICRuYW1lIGFtb25nICRjb2xsZWN0aW9uLAogICAgICogaWYgbm90aGluZyBpcyBmb3VuZCBpbiAkY29sbGVjdGlvbiwgdHJ5IGluICRhYmJyZXZzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkbmFtZSAgICAgICBUaGUgc3RyaW5nCiAgICAgKiBAcGFyYW0gaXRlcmFibGUgJGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdIEEgc29ydGVkIGFycmF5IG9mIHNpbWlsYXIgc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZmluZEFsdGVybmF0aXZlcygkbmFtZSwgJGNvbGxlY3Rpb24pCiAgICB7CiAgICAgICAgJHRocmVzaG9sZCA9IDFlMzsKICAgICAgICAkYWx0ZXJuYXRpdmVzID0gW107CgogICAgICAgICRjb2xsZWN0aW9uUGFydHMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkY29sbGVjdGlvbiBhcyAkaXRlbSkgewogICAgICAgICAgICAkY29sbGVjdGlvblBhcnRzWyRpdGVtXSA9IGV4cGxvZGUoJzonLCAkaXRlbSk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoIChleHBsb2RlKCc6JywgJG5hbWUpIGFzICRpID0+ICRzdWJuYW1lKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb2xsZWN0aW9uUGFydHMgYXMgJGNvbGxlY3Rpb25OYW1lID0+ICRwYXJ0cykgewogICAgICAgICAgICAgICAgJGV4aXN0cyA9IGlzc2V0KCRhbHRlcm5hdGl2ZXNbJGNvbGxlY3Rpb25OYW1lXSk7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRwYXJ0c1skaV0pICYmICRleGlzdHMpIHsKICAgICAgICAgICAgICAgICAgICAkYWx0ZXJuYXRpdmVzWyRjb2xsZWN0aW9uTmFtZV0gKz0gJHRocmVzaG9sZDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICghaXNzZXQoJHBhcnRzWyRpXSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbGV2ID0gbGV2ZW5zaHRlaW4oJHN1Ym5hbWUsICRwYXJ0c1skaV0pOwogICAgICAgICAgICAgICAgaWYgKCRsZXYgPD0gXHN0cmxlbigkc3VibmFtZSkgLyAzIHx8ICcnICE9PSAkc3VibmFtZSAmJiBmYWxzZSAhPT0gc3RycG9zKCRwYXJ0c1skaV0sICRzdWJuYW1lKSkgewogICAgICAgICAgICAgICAgICAgICRhbHRlcm5hdGl2ZXNbJGNvbGxlY3Rpb25OYW1lXSA9ICRleGlzdHMgPyAkYWx0ZXJuYXRpdmVzWyRjb2xsZWN0aW9uTmFtZV0gKyAkbGV2IDogJGxldjsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkZXhpc3RzKSB7CiAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0aXZlc1skY29sbGVjdGlvbk5hbWVdICs9ICR0aHJlc2hvbGQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRjb2xsZWN0aW9uIGFzICRpdGVtKSB7CiAgICAgICAgICAgICRsZXYgPSBsZXZlbnNodGVpbigkbmFtZSwgJGl0ZW0pOwogICAgICAgICAgICBpZiAoJGxldiA8PSBcc3RybGVuKCRuYW1lKSAvIDMgfHwgZmFsc2UgIT09IHN0cnBvcygkaXRlbSwgJG5hbWUpKSB7CiAgICAgICAgICAgICAgICAkYWx0ZXJuYXRpdmVzWyRpdGVtXSA9IGlzc2V0KCRhbHRlcm5hdGl2ZXNbJGl0ZW1dKSA/ICRhbHRlcm5hdGl2ZXNbJGl0ZW1dIC0gJGxldiA6ICRsZXY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRhbHRlcm5hdGl2ZXMgPSBhcnJheV9maWx0ZXIoJGFsdGVybmF0aXZlcywgZnVuY3Rpb24gKCRsZXYpIHVzZSAoJHRocmVzaG9sZCkgeyByZXR1cm4gJGxldiA8IDIgKiAkdGhyZXNob2xkOyB9KTsKICAgICAgICBrc29ydCgkYWx0ZXJuYXRpdmVzLCBcU09SVF9OQVRVUkFMIHwgXFNPUlRfRkxBR19DQVNFKTsKCiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJGFsdGVybmF0aXZlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IENvbW1hbmQgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tYW5kTmFtZSAgICAgVGhlIENvbW1hbmQgbmFtZQogICAgICogQHBhcmFtIGJvb2wgICAkaXNTaW5nbGVDb21tYW5kIFNldCB0byB0cnVlIGlmIHRoZXJlIGlzIG9ubHkgb25lIGNvbW1hbmQgaW4gdGhpcyBhcHBsaWNhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVmYXVsdENvbW1hbmQoJGNvbW1hbmROYW1lLCAkaXNTaW5nbGVDb21tYW5kID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlZmF1bHRDb21tYW5kID0gJGNvbW1hbmROYW1lOwoKICAgICAgICBpZiAoJGlzU2luZ2xlQ29tbWFuZCkgewogICAgICAgICAgICAvLyBFbnN1cmUgdGhlIGNvbW1hbmQgZXhpc3QKICAgICAgICAgICAgJHRoaXMtPmZpbmQoJGNvbW1hbmROYW1lKTsKCiAgICAgICAgICAgICR0aGlzLT5zaW5nbGVDb21tYW5kID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNTaW5nbGVDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNpbmdsZUNvbW1hbmQ7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBzcGxpdFN0cmluZ0J5V2lkdGgoJHN0cmluZywgJHdpZHRoKQogICAgewogICAgICAgIC8vIHN0cl9zcGxpdCBpcyBub3Qgc3VpdGFibGUgZm9yIG11bHRpLWJ5dGUgY2hhcmFjdGVycywgd2Ugc2hvdWxkIHVzZSBwcmVnX3NwbGl0IHRvIGdldCBjaGFyIGFycmF5IHByb3Blcmx5LgogICAgICAgIC8vIGFkZGl0aW9uYWxseSwgYXJyYXlfc2xpY2UoKSBpcyBub3QgZW5vdWdoIGFzIHNvbWUgY2hhcmFjdGVyIGhhcyBkb3VibGVkIHdpZHRoLgogICAgICAgIC8vIHdlIG5lZWQgYSBmdW5jdGlvbiB0byBzcGxpdCBzdHJpbmcgbm90IGJ5IGNoYXJhY3RlciBjb3VudCBidXQgYnkgc3RyaW5nIHdpZHRoCiAgICAgICAgaWYgKGZhbHNlID09PSAkZW5jb2RpbmcgPSBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZywgbnVsbCwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cl9zcGxpdCgkc3RyaW5nLCAkd2lkdGgpOwogICAgICAgIH0KCiAgICAgICAgJHV0ZjhTdHJpbmcgPSBtYl9jb252ZXJ0X2VuY29kaW5nKCRzdHJpbmcsICd1dGY4JywgJGVuY29kaW5nKTsKICAgICAgICAkbGluZXMgPSBbXTsKICAgICAgICAkbGluZSA9ICcnOwogICAgICAgIGZvcmVhY2ggKHByZWdfc3BsaXQoJy8vdScsICR1dGY4U3RyaW5nKSBhcyAkY2hhcikgewogICAgICAgICAgICAvLyB0ZXN0IGlmICRjaGFyIGNvdWxkIGJlIGFwcGVuZGVkIHRvIGN1cnJlbnQgbGluZQogICAgICAgICAgICBpZiAobWJfc3Ryd2lkdGgoJGxpbmUuJGNoYXIsICd1dGY4JykgPD0gJHdpZHRoKSB7CiAgICAgICAgICAgICAgICAkbGluZSAuPSAkY2hhcjsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGlmIG5vdCwgcHVzaCBjdXJyZW50IGxpbmUgdG8gYXJyYXkgYW5kIG1ha2UgbmV3IGxpbmUKICAgICAgICAgICAgJGxpbmVzW10gPSBzdHJfcGFkKCRsaW5lLCAkd2lkdGgpOwogICAgICAgICAgICAkbGluZSA9ICRjaGFyOwogICAgICAgIH0KCiAgICAgICAgJGxpbmVzW10gPSBcY291bnQoJGxpbmVzKSA/IHN0cl9wYWQoJGxpbmUsICR3aWR0aCkgOiAkbGluZTsKCiAgICAgICAgbWJfY29udmVydF92YXJpYWJsZXMoJGVuY29kaW5nLCAndXRmOCcsICRsaW5lcyk7CgogICAgICAgIHJldHVybiAkbGluZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBuYW1lc3BhY2VzIG9mIHRoZSBjb21tYW5kIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgZnVsbCBuYW1lIG9mIHRoZSBjb21tYW5kCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXSBUaGUgbmFtZXNwYWNlcyBvZiB0aGUgY29tbWFuZAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3RBbGxOYW1lc3BhY2VzKCRuYW1lKQogICAgewogICAgICAgIC8vIC0xIGFzIHRoaXJkIGFyZ3VtZW50IGlzIG5lZWRlZCB0byBza2lwIHRoZSBjb21tYW5kIHNob3J0IG5hbWUgd2hlbiBleHBsb2RpbmcKICAgICAgICAkcGFydHMgPSBleHBsb2RlKCc6JywgJG5hbWUsIC0xKTsKICAgICAgICAkbmFtZXNwYWNlcyA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkcGFydHMgYXMgJHBhcnQpIHsKICAgICAgICAgICAgaWYgKFxjb3VudCgkbmFtZXNwYWNlcykpIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VzW10gPSBlbmQoJG5hbWVzcGFjZXMpLic6Jy4kcGFydDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRuYW1lc3BhY2VzW10gPSAkcGFydDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRuYW1lc3BhY2VzOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaW5pdCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pbml0aWFsaXplZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICR0aGlzLT5pbml0aWFsaXplZCA9IHRydWU7CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXREZWZhdWx0Q29tbWFuZHMoKSBhcyAkY29tbWFuZCkgewogICAgICAgICAgICAkdGhpcy0+YWRkKCRjb21tYW5kKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXERlcGVuZGVuY3lJbmplY3Rpb247Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRMb2FkZXJcQ29udGFpbmVyQ29tbWFuZExvYWRlcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XERlcGVuZGVuY3lJbmplY3Rpb25cQ29tcGlsZXJcQ29tcGlsZXJQYXNzSW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRGVwZW5kZW5jeUluamVjdGlvblxDb21waWxlclxTZXJ2aWNlTG9jYXRvclRhZ1Bhc3M7CnVzZSBTeW1mb255XENvbXBvbmVudFxEZXBlbmRlbmN5SW5qZWN0aW9uXENvbnRhaW5lckJ1aWxkZXI7CnVzZSBTeW1mb255XENvbXBvbmVudFxEZXBlbmRlbmN5SW5qZWN0aW9uXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxEZXBlbmRlbmN5SW5qZWN0aW9uXFR5cGVkUmVmZXJlbmNlOwoKLyoqCiAqIFJlZ2lzdGVycyBjb25zb2xlIGNvbW1hbmRzLgogKgogKiBAYXV0aG9yIEdyw6lnb2lyZSBQaW5lYXUgPGx5cml4eEBseXJpeHguaW5mbz4KICovCmNsYXNzIEFkZENvbnNvbGVDb21tYW5kUGFzcyBpbXBsZW1lbnRzIENvbXBpbGVyUGFzc0ludGVyZmFjZQp7CiAgICBwcml2YXRlICRjb21tYW5kTG9hZGVyU2VydmljZUlkOwogICAgcHJpdmF0ZSAkY29tbWFuZFRhZzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvbW1hbmRMb2FkZXJTZXJ2aWNlSWQgPSAnY29uc29sZS5jb21tYW5kX2xvYWRlcicsICRjb21tYW5kVGFnID0gJ2NvbnNvbGUuY29tbWFuZCcpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmRMb2FkZXJTZXJ2aWNlSWQgPSAkY29tbWFuZExvYWRlclNlcnZpY2VJZDsKICAgICAgICAkdGhpcy0+Y29tbWFuZFRhZyA9ICRjb21tYW5kVGFnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9jZXNzKENvbnRhaW5lckJ1aWxkZXIgJGNvbnRhaW5lcikKICAgIHsKICAgICAgICAkY29tbWFuZFNlcnZpY2VzID0gJGNvbnRhaW5lci0+ZmluZFRhZ2dlZFNlcnZpY2VJZHMoJHRoaXMtPmNvbW1hbmRUYWcsIHRydWUpOwogICAgICAgICRsYXp5Q29tbWFuZE1hcCA9IFtdOwogICAgICAgICRsYXp5Q29tbWFuZFJlZnMgPSBbXTsKICAgICAgICAkc2VydmljZUlkcyA9IFtdOwogICAgICAgICRsYXp5U2VydmljZUlkcyA9IFtdOwoKICAgICAgICBmb3JlYWNoICgkY29tbWFuZFNlcnZpY2VzIGFzICRpZCA9PiAkdGFncykgewogICAgICAgICAgICAkZGVmaW5pdGlvbiA9ICRjb250YWluZXItPmdldERlZmluaXRpb24oJGlkKTsKICAgICAgICAgICAgJGNsYXNzID0gJGNvbnRhaW5lci0+Z2V0UGFyYW1ldGVyQmFnKCktPnJlc29sdmVWYWx1ZSgkZGVmaW5pdGlvbi0+Z2V0Q2xhc3MoKSk7CgogICAgICAgICAgICAkY29tbWFuZElkID0gJ2NvbnNvbGUuY29tbWFuZC4nLnN0cnRvbG93ZXIoc3RyX3JlcGxhY2UoJ1xcJywgJ18nLCAkY2xhc3MpKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkdGFnc1swXVsnY29tbWFuZCddKSkgewogICAgICAgICAgICAgICAgJGNvbW1hbmROYW1lID0gJHRhZ3NbMF1bJ2NvbW1hbmQnXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICghJHIgPSAkY29udGFpbmVyLT5nZXRSZWZsZWN0aW9uQ2xhc3MoJGNsYXNzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQ2xhc3MgIiVzIiB1c2VkIGZvciBzZXJ2aWNlICIlcyIgY2Fubm90IGJlIGZvdW5kLicsICRjbGFzcywgJGlkKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoISRyLT5pc1N1YmNsYXNzT2YoQ29tbWFuZDo6Y2xhc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgc2VydmljZSAiJXMiIHRhZ2dlZCAiJXMiIG11c3QgYmUgYSBzdWJjbGFzcyBvZiAiJXMiLicsICRpZCwgJHRoaXMtPmNvbW1hbmRUYWcsIENvbW1hbmQ6OmNsYXNzKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29tbWFuZE5hbWUgPSAkY2xhc3M6OmdldERlZmF1bHROYW1lKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudWxsID09PSAkY29tbWFuZE5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkc2VydmljZUlkc1skY29tbWFuZElkXSkgfHwgJGNvbnRhaW5lci0+aGFzQWxpYXMoJGNvbW1hbmRJZCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tbWFuZElkID0gJGNvbW1hbmRJZC4nXycuJGlkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCEkZGVmaW5pdGlvbi0+aXNQdWJsaWMoKSB8fCAkZGVmaW5pdGlvbi0+aXNQcml2YXRlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29udGFpbmVyLT5zZXRBbGlhcygkY29tbWFuZElkLCAkaWQpLT5zZXRQdWJsaWModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgJGlkID0gJGNvbW1hbmRJZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRzZXJ2aWNlSWRzWyRjb21tYW5kSWRdID0gJGlkOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc2VydmljZUlkc1skY29tbWFuZElkXSA9ICRpZDsKICAgICAgICAgICAgJGxhenlTZXJ2aWNlSWRzWyRpZF0gPSB0cnVlOwogICAgICAgICAgICB1bnNldCgkdGFnc1swXSk7CiAgICAgICAgICAgICRsYXp5Q29tbWFuZE1hcFskY29tbWFuZE5hbWVdID0gJGlkOwogICAgICAgICAgICAkbGF6eUNvbW1hbmRSZWZzWyRpZF0gPSBuZXcgVHlwZWRSZWZlcmVuY2UoJGlkLCAkY2xhc3MpOwogICAgICAgICAgICAkYWxpYXNlcyA9IFtdOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHRhZ3MgYXMgJHRhZykgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0YWdbJ2NvbW1hbmQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkYWxpYXNlc1tdID0gJHRhZ1snY29tbWFuZCddOwogICAgICAgICAgICAgICAgICAgICRsYXp5Q29tbWFuZE1hcFskdGFnWydjb21tYW5kJ11dID0gJGlkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkZGVmaW5pdGlvbi0+YWRkTWV0aG9kQ2FsbCgnc2V0TmFtZScsIFskY29tbWFuZE5hbWVdKTsKCiAgICAgICAgICAgIGlmICgkYWxpYXNlcykgewogICAgICAgICAgICAgICAgJGRlZmluaXRpb24tPmFkZE1ldGhvZENhbGwoJ3NldEFsaWFzZXMnLCBbJGFsaWFzZXNdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJGNvbnRhaW5lcgogICAgICAgICAgICAtPnJlZ2lzdGVyKCR0aGlzLT5jb21tYW5kTG9hZGVyU2VydmljZUlkLCBDb250YWluZXJDb21tYW5kTG9hZGVyOjpjbGFzcykKICAgICAgICAgICAgLT5zZXRQdWJsaWModHJ1ZSkKICAgICAgICAgICAgLT5zZXRBcmd1bWVudHMoW1NlcnZpY2VMb2NhdG9yVGFnUGFzczo6cmVnaXN0ZXIoJGNvbnRhaW5lciwgJGxhenlDb21tYW5kUmVmcyksICRsYXp5Q29tbWFuZE1hcF0pOwoKICAgICAgICAkY29udGFpbmVyLT5zZXRQYXJhbWV0ZXIoJ2NvbnNvbGUuY29tbWFuZC5pZHMnLCAkc2VydmljZUlkcyk7CiAgICAgICAgJGNvbnRhaW5lci0+c2V0UGFyYW1ldGVyKCdjb25zb2xlLmxhenlfY29tbWFuZC5pZHMnLCAkbGF6eVNlcnZpY2VJZHMpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbW1hbmRcQ29tbWFuZDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXRcSW5wdXRJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXE91dHB1dFxPdXRwdXRJbnRlcmZhY2U7CgovKioKICogQWxsb3dzIHRvIGhhbmRsZSB0aHJvd2FibGVzIHRocm93biB3aGlsZSBydW5uaW5nIGEgY29tbWFuZC4KICoKICogQGF1dGhvciBXb3V0ZXIgZGUgSm9uZyA8d291dGVyQHdvdXRlcmoubmw+CiAqLwpmaW5hbCBjbGFzcyBDb25zb2xlRXJyb3JFdmVudCBleHRlbmRzIENvbnNvbGVFdmVudAp7CiAgICBwcml2YXRlICRlcnJvcjsKICAgIHByaXZhdGUgJGV4aXRDb2RlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCAkZXJyb3IsIENvbW1hbmQgJGNvbW1hbmQgPSBudWxsKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGNvbW1hbmQsICRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgICR0aGlzLT5zZXRFcnJvcigkZXJyb3IpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGhyb3duIGVycm9yL2V4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIFxUaHJvd2FibGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgdGhlIHRocm93biBlcnJvci9leGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIFxUaHJvd2FibGUgJGVycm9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFcnJvcigkZXJyb3IpCiAgICB7CiAgICAgICAgaWYgKCEkZXJyb3IgaW5zdGFuY2VvZiBcVGhyb3dhYmxlICYmICEkZXJyb3IgaW5zdGFuY2VvZiBcRXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlIGVycm9yIHBhc3NlZCB0byBDb25zb2xlRXJyb3JFdmVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFxUaHJvd2FibGUgb3IgXEV4Y2VwdGlvbiwgIiVzIiB3YXMgcGFzc2VkIGluc3RlYWQuJywgXGlzX29iamVjdCgkZXJyb3IpID8gXGdldF9jbGFzcygkZXJyb3IpIDogXGdldHR5cGUoJGVycm9yKSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmVycm9yID0gJGVycm9yOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhpdCBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGV4aXRDb2RlIFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhpdENvZGUoJGV4aXRDb2RlKQogICAgewogICAgICAgICR0aGlzLT5leGl0Q29kZSA9IChpbnQpICRleGl0Q29kZTsKCiAgICAgICAgJHIgPSBuZXcgXFJlZmxlY3Rpb25Qcm9wZXJ0eSgkdGhpcy0+ZXJyb3IsICdjb2RlJyk7CiAgICAgICAgJHItPnNldEFjY2Vzc2libGUodHJ1ZSk7CiAgICAgICAgJHItPnNldFZhbHVlKCR0aGlzLT5lcnJvciwgJHRoaXMtPmV4aXRDb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGV4aXQgY29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4aXRDb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gbnVsbCAhPT0gJHRoaXMtPmV4aXRDb2RlID8gJHRoaXMtPmV4aXRDb2RlIDogKFxpc19pbnQoJHRoaXMtPmVycm9yLT5nZXRDb2RlKCkpICYmIDAgIT09ICR0aGlzLT5lcnJvci0+Z2V0Q29kZSgpID8gJHRoaXMtPmVycm9yLT5nZXRDb2RlKCkgOiAxKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXZlbnQ7CgpAdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdUaGUgIiVzIiBjbGFzcyBpcyBkZXByZWNhdGVkIHNpbmNlIFN5bWZvbnkgMy4zIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gNC4wLiBVc2UgdGhlIENvbnNvbGVFcnJvckV2ZW50IGluc3RlYWQuJywgQ29uc29sZUV4Y2VwdGlvbkV2ZW50OjpjbGFzcyksIFxFX1VTRVJfREVQUkVDQVRFRCk7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxDb21tYW5kXENvbW1hbmQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0XElucHV0SW50ZXJmYWNlOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxPdXRwdXRcT3V0cHV0SW50ZXJmYWNlOwoKLyoqCiAqIEFsbG93cyB0byBoYW5kbGUgZXhjZXB0aW9uIHRocm93biBpbiBhIGNvbW1hbmQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuIFVzZSBDb25zb2xlRXJyb3JFdmVudCBpbnN0ZWFkLgogKi8KY2xhc3MgQ29uc29sZUV4Y2VwdGlvbkV2ZW50IGV4dGVuZHMgQ29uc29sZUV2ZW50CnsKICAgIHByaXZhdGUgJGV4Y2VwdGlvbjsKICAgIHByaXZhdGUgJGV4aXRDb2RlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDb21tYW5kICRjb21tYW5kLCBJbnB1dEludGVyZmFjZSAkaW5wdXQsIE91dHB1dEludGVyZmFjZSAkb3V0cHV0LCBcRXhjZXB0aW9uICRleGNlcHRpb24sICRleGl0Q29kZSkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRjb21tYW5kLCAkaW5wdXQsICRvdXRwdXQpOwoKICAgICAgICAkdGhpcy0+c2V0RXhjZXB0aW9uKCRleGNlcHRpb24pOwogICAgICAgICR0aGlzLT5leGl0Q29kZSA9IChpbnQpICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRocm93biBleGNlcHRpb24uCiAgICAgKgogICAgICogQHJldHVybiBcRXhjZXB0aW9uIFRoZSB0aHJvd24gZXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeGNlcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhjZXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgdGhlIHRocm93biBleGNlcHRpb24uCiAgICAgKgogICAgICogVGhpcyBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgbm8gcmVzcG9uc2UgaXMgc2V0IGluIHRoZSBldmVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gXEV4Y2VwdGlvbiAkZXhjZXB0aW9uIFRoZSB0aHJvd24gZXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeGNlcHRpb24oXEV4Y2VwdGlvbiAkZXhjZXB0aW9uKQogICAgewogICAgICAgICR0aGlzLT5leGNlcHRpb24gPSAkZXhjZXB0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZXhpdCBjb2RlLgogICAgICoKICAgICAqIEByZXR1cm4gaW50IFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhpdENvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhpdENvZGU7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50OwoKLyoqCiAqIEFsbG93cyB0byBkbyB0aGluZ3MgYmVmb3JlIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkLCBsaWtlIHNraXBwaW5nIHRoZSBjb21tYW5kIG9yIGNoYW5naW5nIHRoZSBpbnB1dC4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBDb25zb2xlQ29tbWFuZEV2ZW50IGV4dGVuZHMgQ29uc29sZUV2ZW50CnsKICAgIC8qKgogICAgICogVGhlIHJldHVybiBjb2RlIGZvciBza2lwcGVkIGNvbW1hbmRzLCB0aGlzIHdpbGwgYWxzbyBiZSBwYXNzZWQgaW50byB0aGUgdGVybWluYXRlIGV2ZW50LgogICAgICovCiAgICBjb25zdCBSRVRVUk5fQ09ERV9ESVNBQkxFRCA9IDExMzsKCiAgICAvKioKICAgICAqIEluZGljYXRlcyBpZiB0aGUgY29tbWFuZCBzaG91bGQgYmUgcnVuIG9yIHNraXBwZWQuCiAgICAgKi8KICAgIHByaXZhdGUgJGNvbW1hbmRTaG91bGRSdW4gPSB0cnVlOwoKICAgIC8qKgogICAgICogRGlzYWJsZXMgdGhlIGNvbW1hbmQsIHNvIGl0IHdvbid0IGJlIHJ1bi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGVDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRTaG91bGRSdW4gPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZXMgdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRTaG91bGRSdW4gPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb21tYW5kIGlzIHJ1bm5hYmxlLCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21tYW5kU2hvdWxkUnVuKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmRTaG91bGRSdW47CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEV2ZW50RGlzcGF0Y2hlclxFdmVudDsKCi8qKgogKiBBbGxvd3MgdG8gaW5zcGVjdCBpbnB1dCBhbmQgb3V0cHV0IG9mIGEgY29tbWFuZC4KICoKICogQGF1dGhvciBGcmFuY2VzY28gTGV2b3JhdG8gPGdpdEBmbGV2b3VyLm5ldD4KICovCmNsYXNzIENvbnNvbGVFdmVudCBleHRlbmRzIEV2ZW50CnsKICAgIHByb3RlY3RlZCAkY29tbWFuZDsKCiAgICBwcml2YXRlICRpbnB1dDsKICAgIHByaXZhdGUgJG91dHB1dDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tbWFuZCAkY29tbWFuZCA9IG51bGwsIElucHV0SW50ZXJmYWNlICRpbnB1dCwgT3V0cHV0SW50ZXJmYWNlICRvdXRwdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbW1hbmQgPSAkY29tbWFuZDsKICAgICAgICAkdGhpcy0+aW5wdXQgPSAkaW5wdXQ7CiAgICAgICAgJHRoaXMtPm91dHB1dCA9ICRvdXRwdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb21tYW5kIHRoYXQgaXMgZXhlY3V0ZWQuCiAgICAgKgogICAgICogQHJldHVybiBDb21tYW5kfG51bGwgQSBDb21tYW5kIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1hbmQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBpbnB1dCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0SW50ZXJmYWNlIEFuIElucHV0SW50ZXJmYWNlIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnB1dDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIG91dHB1dCBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIE91dHB1dEludGVyZmFjZSBBbiBPdXRwdXRJbnRlcmZhY2UgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE91dHB1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vdXRwdXQ7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcQ29tbWFuZFxDb21tYW5kOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dFxJbnB1dEludGVyZmFjZTsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcT3V0cHV0XE91dHB1dEludGVyZmFjZTsKCi8qKgogKiBBbGxvd3MgdG8gbWFuaXB1bGF0ZSB0aGUgZXhpdCBjb2RlIG9mIGEgY29tbWFuZCBhZnRlciBpdHMgZXhlY3V0aW9uLgogKgogKiBAYXV0aG9yIEZyYW5jZXNjbyBMZXZvcmF0byA8Z2l0QGZsZXZvdXIubmV0PgogKi8KY2xhc3MgQ29uc29sZVRlcm1pbmF0ZUV2ZW50IGV4dGVuZHMgQ29uc29sZUV2ZW50CnsKICAgIC8qKgogICAgICogVGhlIGV4aXQgY29kZSBvZiB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcml2YXRlICRleGl0Q29kZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ29tbWFuZCAkY29tbWFuZCwgSW5wdXRJbnRlcmZhY2UgJGlucHV0LCBPdXRwdXRJbnRlcmZhY2UgJG91dHB1dCwgJGV4aXRDb2RlKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGNvbW1hbmQsICRpbnB1dCwgJG91dHB1dCk7CgogICAgICAgICR0aGlzLT5zZXRFeGl0Q29kZSgkZXhpdENvZGUpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhpdCBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGV4aXRDb2RlIFRoZSBjb21tYW5kIGV4aXQgY29kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhpdENvZGUoJGV4aXRDb2RlKQogICAgewogICAgICAgICR0aGlzLT5leGl0Q29kZSA9IChpbnQpICRleGl0Q29kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGV4aXQgY29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBUaGUgY29tbWFuZCBleGl0IGNvZGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4aXRDb2RlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4aXRDb2RlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CgovKioKICogU3RyaW5nSW5wdXQgcmVwcmVzZW50cyBhbiBpbnB1dCBwcm92aWRlZCBhcyBhIHN0cmluZy4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkaW5wdXQgPSBuZXcgU3RyaW5nSW5wdXQoJ2ZvbyAtLWJhcj0iZm9vYmFyIicpOwogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIFN0cmluZ0lucHV0IGV4dGVuZHMgQXJndklucHV0CnsKICAgIGNvbnN0IFJFR0VYX1NUUklORyA9ICcoW15cc10rPykoPzpcc3woPzwhXFxcXCkifCg/PCFcXFxcKVwnfCQpJzsKICAgIGNvbnN0IFJFR0VYX1FVT1RFRF9TVFJJTkcgPSAnKD86IihbXiJcXFxcXSooPzpcXFxcLlteIlxcXFxdKikqKSJ8XCcoW15cJ1xcXFxdKig/OlxcXFwuW15cJ1xcXFxdKikqKVwnKSc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlcnMgZnJvbSB0aGUgQ0xJCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5wdXQpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChbXSk7CgogICAgICAgICR0aGlzLT5zZXRUb2tlbnMoJHRoaXMtPnRva2VuaXplKCRpbnB1dCkpOwogICAgfQoKICAgIC8qKgogICAgICogVG9rZW5pemVzIGEgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlucHV0IFRoZSBpbnB1dCB0byB0b2tlbml6ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkgQW4gYXJyYXkgb2YgdG9rZW5zCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiB1bmFibGUgdG8gcGFyc2UgaW5wdXQgKHNob3VsZCBuZXZlciBoYXBwZW4pCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gdG9rZW5pemUoJGlucHV0KQogICAgewogICAgICAgICR0b2tlbnMgPSBbXTsKICAgICAgICAkbGVuZ3RoID0gXHN0cmxlbigkaW5wdXQpOwogICAgICAgICRjdXJzb3IgPSAwOwogICAgICAgIHdoaWxlICgkY3Vyc29yIDwgJGxlbmd0aCkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL1xzKy9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvKFtePSJcJ1xzXSs/KSg9PykoJy5zZWxmOjpSRUdFWF9RVU9URURfU1RSSU5HLicrKS9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgICAgICAkdG9rZW5zW10gPSAkbWF0Y2hbMV0uJG1hdGNoWzJdLnN0cmlwY3NsYXNoZXMoc3RyX3JlcGxhY2UoWyciXCcnLCAnXCciJywgJ1wnXCcnLCAnIiInXSwgJycsIHN1YnN0cigkbWF0Y2hbM10sIDEsIFxzdHJsZW4oJG1hdGNoWzNdKSAtIDIpKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvJy5zZWxmOjpSRUdFWF9RVU9URURfU1RSSU5HLicvQScsICRpbnB1dCwgJG1hdGNoLCBudWxsLCAkY3Vyc29yKSkgewogICAgICAgICAgICAgICAgJHRva2Vuc1tdID0gc3RyaXBjc2xhc2hlcyhzdWJzdHIoJG1hdGNoWzBdLCAxLCBcc3RybGVuKCRtYXRjaFswXSkgLSAyKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChwcmVnX21hdGNoKCcvJy5zZWxmOjpSRUdFWF9TVFJJTkcuJy9BJywgJGlucHV0LCAkbWF0Y2gsIG51bGwsICRjdXJzb3IpKSB7CiAgICAgICAgICAgICAgICAkdG9rZW5zW10gPSBzdHJpcGNzbGFzaGVzKCRtYXRjaFsxXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1VuYWJsZSB0byBwYXJzZSBpbnB1dCBuZWFyICIuLi4gJXMgLi4uIi4nLCBzdWJzdHIoJGlucHV0LCAkY3Vyc29yLCAxMCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGN1cnNvciArPSBcc3RybGVuKCRtYXRjaFswXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRva2VuczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBJbnB1dEludGVyZmFjZSBpcyB0aGUgaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IGFsbCBpbnB1dCBjbGFzc2VzLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmludGVyZmFjZSBJbnB1dEludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGZyb20gdGhlIHJhdyBwYXJhbWV0ZXJzIChub3QgcGFyc2VkKS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsIFRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgYXJndW1lbnQgb3IgbnVsbCBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0QXJndW1lbnQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmF3IHBhcmFtZXRlcnMgKG5vdCBwYXJzZWQpIGNvbnRhaW4gYSB2YWx1ZS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0byBiZSB1c2VkIHRvIGludHJvc3BlY3QgdGhlIGlucHV0IHBhcmFtZXRlcnMKICAgICAqIGJlZm9yZSB0aGV5IGhhdmUgYmVlbiB2YWxpZGF0ZWQuIEl0IG11c3QgYmUgdXNlZCBjYXJlZnVsbHkuCiAgICAgKiBEb2VzIG5vdCBuZWNlc3NhcmlseSByZXR1cm4gdGhlIGNvcnJlY3QgcmVzdWx0IGZvciBzaG9ydCBvcHRpb25zCiAgICAgKiB3aGVuIG11bHRpcGxlIGZsYWdzIGFyZSBjb21iaW5lZCBpbiB0aGUgc2FtZSBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkdmFsdWVzICAgICBUaGUgdmFsdWVzIHRvIGxvb2sgZm9yIGluIHRoZSByYXcgcGFyYW1ldGVycyAoY2FuIGJlIGFuIGFycmF5KQogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkb25seVBhcmFtcyBPbmx5IGNoZWNrIHJlYWwgcGFyYW1ldGVycywgc2tpcCB0aG9zZSBmb2xsb3dpbmcgYW4gZW5kIG9mIG9wdGlvbnMgKC0tKSBzaWduYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgaXMgY29udGFpbmVkIGluIHRoZSByYXcgcGFyYW1ldGVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRvbmx5UGFyYW1zID0gZmFsc2UpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSByYXcgb3B0aW9uIChub3QgcGFyc2VkKS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0byBiZSB1c2VkIHRvIGludHJvc3BlY3QgdGhlIGlucHV0IHBhcmFtZXRlcnMKICAgICAqIGJlZm9yZSB0aGV5IGhhdmUgYmVlbiB2YWxpZGF0ZWQuIEl0IG11c3QgYmUgdXNlZCBjYXJlZnVsbHkuCiAgICAgKiBEb2VzIG5vdCBuZWNlc3NhcmlseSByZXR1cm4gdGhlIGNvcnJlY3QgcmVzdWx0IGZvciBzaG9ydCBvcHRpb25zCiAgICAgKiB3aGVuIG11bHRpcGxlIGZsYWdzIGFyZSBjb21iaW5lZCBpbiB0aGUgc2FtZSBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkdmFsdWVzICAgICBUaGUgdmFsdWUocykgdG8gbG9vayBmb3IgaW4gdGhlIHJhdyBwYXJhbWV0ZXJzIChjYW4gYmUgYW4gYXJyYXkpCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICRkZWZhdWx0ICAgIFRoZSBkZWZhdWx0IHZhbHVlIHRvIHJldHVybiBpZiBubyByZXN1bHQgaXMgZm91bmQKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG9ubHlQYXJhbXMgT25seSBjaGVjayByZWFsIHBhcmFtZXRlcnMsIHNraXAgdGhvc2UgZm9sbG93aW5nIGFuIGVuZCBvZiBvcHRpb25zICgtLSkgc2lnbmFsCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBUaGUgb3B0aW9uIHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJPcHRpb24oJHZhbHVlcywgJGRlZmF1bHQgPSBmYWxzZSwgJG9ubHlQYXJhbXMgPSBmYWxzZSk7CgogICAgLyoqCiAgICAgKiBCaW5kcyB0aGUgY3VycmVudCBJbnB1dCBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMgYW5kIG9wdGlvbnMuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBiaW5kKElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbik7CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGlucHV0LgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIG5vdCBlbm91Z2ggYXJndW1lbnRzIGFyZSBnaXZlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIHRoZSBnaXZlbiBhcmd1bWVudHMgbWVyZ2VkIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJndW1lbnQgdmFsdWUgZm9yIGEgZ2l2ZW4gYXJndW1lbnQgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8c3RyaW5nW118bnVsbCBUaGUgYXJndW1lbnQgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFyZ3VtZW50IGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCRuYW1lKTsKCiAgICAvKioKICAgICAqIFNldHMgYW4gYXJndW1lbnQgdmFsdWUgYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJG5hbWUgIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfG51bGwgJHZhbHVlIFRoZSBhcmd1bWVudCB2YWx1ZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gYXJndW1lbnQgZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRBcmd1bWVudCBvYmplY3QgZXhpc3RzIGJ5IG5hbWUgb3IgcG9zaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJG5hbWUgVGhlIElucHV0QXJndW1lbnQgbmFtZSBvciBwb3NpdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBJbnB1dEFyZ3VtZW50IG9iamVjdCBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQXJndW1lbnQoJG5hbWUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgdGhlIGdpdmVuIG9wdGlvbnMgbWVyZ2VkIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbiB2YWx1ZSBmb3IgYSBnaXZlbiBvcHRpb24gbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBvcHRpb24gbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfHN0cmluZ1tdfGJvb2x8bnVsbCBUaGUgb3B0aW9uIHZhbHVlCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRuYW1lKTsKCiAgICAvKioKICAgICAqIFNldHMgYW4gb3B0aW9uIHZhbHVlIGJ5IG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgJG5hbWUgIFRoZSBvcHRpb24gbmFtZQogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXXxib29sfG51bGwgJHZhbHVlIFRoZSBvcHRpb24gdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb24oJG5hbWUsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cyBieSBuYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIElucHV0T3B0aW9uIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNPcHRpb24oJG5hbWUpOwoKICAgIC8qKgogICAgICogSXMgdGhpcyBpbnB1dCBtZWFucyBpbnRlcmFjdGl2ZT8KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUoKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlucHV0IGludGVyYWN0aXZpdHkuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJGludGVyYWN0aXZlIElmIHRoZSBpbnB1dCBzaG91bGQgYmUgaW50ZXJhY3RpdmUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEludGVyYWN0aXZlKCRpbnRlcmFjdGl2ZSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwoKLyoqCiAqIEEgSW5wdXREZWZpbml0aW9uIHJlcHJlc2VudHMgYSBzZXQgb2YgdmFsaWQgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBhbmQgb3B0aW9ucy4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkZGVmaW5pdGlvbiA9IG5ldyBJbnB1dERlZmluaXRpb24oWwogKiAgICAgICAgIG5ldyBJbnB1dEFyZ3VtZW50KCduYW1lJywgSW5wdXRBcmd1bWVudDo6UkVRVUlSRUQpLAogKiAgICAgICAgIG5ldyBJbnB1dE9wdGlvbignZm9vJywgJ2YnLCBJbnB1dE9wdGlvbjo6VkFMVUVfUkVRVUlSRUQpLAogKiAgICAgXSk7CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSW5wdXREZWZpbml0aW9uCnsKICAgIHByaXZhdGUgJGFyZ3VtZW50czsKICAgIHByaXZhdGUgJHJlcXVpcmVkQ291bnQ7CiAgICBwcml2YXRlICRoYXNBbkFycmF5QXJndW1lbnQgPSBmYWxzZTsKICAgIHByaXZhdGUgJGhhc09wdGlvbmFsOwogICAgcHJpdmF0ZSAkb3B0aW9uczsKICAgIHByaXZhdGUgJHNob3J0Y3V0czsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkZGVmaW5pdGlvbiBBbiBhcnJheSBvZiBJbnB1dEFyZ3VtZW50IGFuZCBJbnB1dE9wdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGRlZmluaXRpb24gPSBbXSkKICAgIHsKICAgICAgICAkdGhpcy0+c2V0RGVmaW5pdGlvbigkZGVmaW5pdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBpbnB1dC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlZmluaXRpb24oYXJyYXkgJGRlZmluaXRpb24pCiAgICB7CiAgICAgICAgJGFyZ3VtZW50cyA9IFtdOwogICAgICAgICRvcHRpb25zID0gW107CiAgICAgICAgZm9yZWFjaCAoJGRlZmluaXRpb24gYXMgJGl0ZW0pIHsKICAgICAgICAgICAgaWYgKCRpdGVtIGluc3RhbmNlb2YgSW5wdXRPcHRpb24pIHsKICAgICAgICAgICAgICAgICRvcHRpb25zW10gPSAkaXRlbTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRhcmd1bWVudHNbXSA9ICRpdGVtOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0QXJndW1lbnRzKCRhcmd1bWVudHMpOwogICAgICAgICR0aGlzLT5zZXRPcHRpb25zKCRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIElucHV0QXJndW1lbnQgb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5wdXRBcmd1bWVudFtdICRhcmd1bWVudHMgQW4gYXJyYXkgb2YgSW5wdXRBcmd1bWVudCBvYmplY3RzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudHMoJGFyZ3VtZW50cyA9IFtdKQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudHMgPSBbXTsKICAgICAgICAkdGhpcy0+cmVxdWlyZWRDb3VudCA9IDA7CiAgICAgICAgJHRoaXMtPmhhc09wdGlvbmFsID0gZmFsc2U7CiAgICAgICAgJHRoaXMtPmhhc0FuQXJyYXlBcmd1bWVudCA9IGZhbHNlOwogICAgICAgICR0aGlzLT5hZGRBcmd1bWVudHMoJGFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGFuIGFycmF5IG9mIElucHV0QXJndW1lbnQgb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5wdXRBcmd1bWVudFtdICRhcmd1bWVudHMgQW4gYXJyYXkgb2YgSW5wdXRBcmd1bWVudCBvYmplY3RzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRBcmd1bWVudHMoJGFyZ3VtZW50cyA9IFtdKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkYXJndW1lbnRzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRhcmd1bWVudHMgYXMgJGFyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkQXJndW1lbnQoJGFyZ3VtZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgTG9naWNFeGNlcHRpb24gV2hlbiBpbmNvcnJlY3QgYXJndW1lbnQgaXMgZ2l2ZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEFyZ3VtZW50KElucHV0QXJndW1lbnQgJGFyZ3VtZW50KQogICAgewogICAgICAgIGlmIChpc3NldCgkdGhpcy0+YXJndW1lbnRzWyRhcmd1bWVudC0+Z2V0TmFtZSgpXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKHNwcmludGYoJ0FuIGFyZ3VtZW50IHdpdGggbmFtZSAiJXMiIGFscmVhZHkgZXhpc3RzLicsICRhcmd1bWVudC0+Z2V0TmFtZSgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmhhc0FuQXJyYXlBcmd1bWVudCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0Nhbm5vdCBhZGQgYW4gYXJndW1lbnQgYWZ0ZXIgYW4gYXJyYXkgYXJndW1lbnQuJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGFyZ3VtZW50LT5pc1JlcXVpcmVkKCkgJiYgJHRoaXMtPmhhc09wdGlvbmFsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQ2Fubm90IGFkZCBhIHJlcXVpcmVkIGFyZ3VtZW50IGFmdGVyIGFuIG9wdGlvbmFsIG9uZS4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkYXJndW1lbnQtPmlzQXJyYXkoKSkgewogICAgICAgICAgICAkdGhpcy0+aGFzQW5BcnJheUFyZ3VtZW50ID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICgkYXJndW1lbnQtPmlzUmVxdWlyZWQoKSkgewogICAgICAgICAgICArKyR0aGlzLT5yZXF1aXJlZENvdW50OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5oYXNPcHRpb25hbCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXJndW1lbnRzWyRhcmd1bWVudC0+Z2V0TmFtZSgpXSA9ICRhcmd1bWVudDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gSW5wdXRBcmd1bWVudCBieSBuYW1lIG9yIGJ5IHBvc2l0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICRuYW1lIFRoZSBJbnB1dEFyZ3VtZW50IG5hbWUgb3IgcG9zaXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0QXJndW1lbnQgQW4gSW5wdXRBcmd1bWVudCBvYmplY3QKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFyZ3VtZW50IGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmhhc0FyZ3VtZW50KCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIGFyZ3VtZW50IGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAkYXJndW1lbnRzID0gXGlzX2ludCgkbmFtZSkgPyBhcnJheV92YWx1ZXMoJHRoaXMtPmFyZ3VtZW50cykgOiAkdGhpcy0+YXJndW1lbnRzOwoKICAgICAgICByZXR1cm4gJGFyZ3VtZW50c1skbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRBcmd1bWVudCBvYmplY3QgZXhpc3RzIGJ5IG5hbWUgb3IgcG9zaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xpbnQgJG5hbWUgVGhlIElucHV0QXJndW1lbnQgbmFtZSBvciBwb3NpdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSBJbnB1dEFyZ3VtZW50IG9iamVjdCBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQXJndW1lbnQoJG5hbWUpCiAgICB7CiAgICAgICAgJGFyZ3VtZW50cyA9IFxpc19pbnQoJG5hbWUpID8gYXJyYXlfdmFsdWVzKCR0aGlzLT5hcmd1bWVudHMpIDogJHRoaXMtPmFyZ3VtZW50czsKCiAgICAgICAgcmV0dXJuIGlzc2V0KCRhcmd1bWVudHNbJG5hbWVdKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGFycmF5IG9mIElucHV0QXJndW1lbnQgb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0QXJndW1lbnRbXSBBbiBhcnJheSBvZiBJbnB1dEFyZ3VtZW50IG9iamVjdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hcmd1bWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgSW5wdXRBcmd1bWVudHMuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIG51bWJlciBvZiBJbnB1dEFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRDb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYXNBbkFycmF5QXJndW1lbnQgPyBcUEhQX0lOVF9NQVggOiBcY291bnQoJHRoaXMtPmFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcmVxdWlyZWQgSW5wdXRBcmd1bWVudHMuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIG51bWJlciBvZiByZXF1aXJlZCBJbnB1dEFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRSZXF1aXJlZENvdW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlcXVpcmVkQ291bnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFuIGFycmF5IG9mIGRlZmF1bHQgdmFsdWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudERlZmF1bHRzKCkKICAgIHsKICAgICAgICAkdmFsdWVzID0gW107CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmFyZ3VtZW50cyBhcyAkYXJndW1lbnQpIHsKICAgICAgICAgICAgJHZhbHVlc1skYXJndW1lbnQtPmdldE5hbWUoKV0gPSAkYXJndW1lbnQtPmdldERlZmF1bHQoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWVzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgSW5wdXRPcHRpb24gb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gSW5wdXRPcHRpb25bXSAkb3B0aW9ucyBBbiBhcnJheSBvZiBJbnB1dE9wdGlvbiBvYmplY3RzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcHRpb25zKCRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSBbXTsKICAgICAgICAkdGhpcy0+c2hvcnRjdXRzID0gW107CiAgICAgICAgJHRoaXMtPmFkZE9wdGlvbnMoJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhbiBhcnJheSBvZiBJbnB1dE9wdGlvbiBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBJbnB1dE9wdGlvbltdICRvcHRpb25zIEFuIGFycmF5IG9mIElucHV0T3B0aW9uIG9iamVjdHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE9wdGlvbnMoJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBmb3JlYWNoICgkb3B0aW9ucyBhcyAkb3B0aW9uKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRPcHRpb24oJG9wdGlvbik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBhbHJlYWR5IGV4aXN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRPcHRpb24oSW5wdXRPcHRpb24gJG9wdGlvbikKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm9wdGlvbnNbJG9wdGlvbi0+Z2V0TmFtZSgpXSkgJiYgISRvcHRpb24tPmVxdWFscygkdGhpcy0+b3B0aW9uc1skb3B0aW9uLT5nZXROYW1lKCldKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oc3ByaW50ZignQW4gb3B0aW9uIG5hbWVkICIlcyIgYWxyZWFkeSBleGlzdHMuJywgJG9wdGlvbi0+Z2V0TmFtZSgpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgewogICAgICAgICAgICBmb3JlYWNoIChleHBsb2RlKCd8JywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgYXMgJHNob3J0Y3V0KSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnNob3J0Y3V0c1skc2hvcnRjdXRdKSAmJiAhJG9wdGlvbi0+ZXF1YWxzKCR0aGlzLT5vcHRpb25zWyR0aGlzLT5zaG9ydGN1dHNbJHNob3J0Y3V0XV0pKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2ljRXhjZXB0aW9uKHNwcmludGYoJ0FuIG9wdGlvbiB3aXRoIHNob3J0Y3V0ICIlcyIgYWxyZWFkeSBleGlzdHMuJywgJHNob3J0Y3V0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5vcHRpb25zWyRvcHRpb24tPmdldE5hbWUoKV0gPSAkb3B0aW9uOwogICAgICAgIGlmICgkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJ3wnLCAkb3B0aW9uLT5nZXRTaG9ydGN1dCgpKSBhcyAkc2hvcnRjdXQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zaG9ydGN1dHNbJHNob3J0Y3V0XSA9ICRvcHRpb24tPmdldE5hbWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gSW5wdXRPcHRpb24gYnkgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBJbnB1dE9wdGlvbiBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBJbnB1dE9wdGlvbiBBIElucHV0T3B0aW9uIG9iamVjdAogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gb3B0aW9uIGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbigkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5oYXNPcHRpb24oJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+b3B0aW9uc1skbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cyBieSBuYW1lLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGNhbid0IGJlIHVzZWQgdG8gY2hlY2sgaWYgdGhlIHVzZXIgaW5jbHVkZWQgdGhlIG9wdGlvbiB3aGVuCiAgICAgKiBleGVjdXRpbmcgdGhlIGNvbW1hbmQgKHVzZSBnZXRPcHRpb24oKSBpbnN0ZWFkKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBJbnB1dE9wdGlvbiBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIElucHV0T3B0aW9uIG9iamVjdCBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzT3B0aW9uKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+b3B0aW9uc1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgYXJyYXkgb2YgSW5wdXRPcHRpb24gb2JqZWN0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIElucHV0T3B0aW9uW10gQW4gYXJyYXkgb2YgSW5wdXRPcHRpb24gb2JqZWN0cwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGFuIElucHV0T3B0aW9uIG9iamVjdCBleGlzdHMgYnkgc2hvcnRjdXQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgSW5wdXRPcHRpb24gc2hvcnRjdXQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgSW5wdXRPcHRpb24gb2JqZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNTaG9ydGN1dCgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPnNob3J0Y3V0c1skbmFtZV0pOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbiBJbnB1dE9wdGlvbiBieSBzaG9ydGN1dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzaG9ydGN1dCBUaGUgU2hvcnRjdXQgbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gSW5wdXRPcHRpb24gQW4gSW5wdXRPcHRpb24gb2JqZWN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb25Gb3JTaG9ydGN1dCgkc2hvcnRjdXQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRPcHRpb24oJHRoaXMtPnNob3J0Y3V0VG9OYW1lKCRzaG9ydGN1dCkpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbiBhcnJheSBvZiBkZWZhdWx0IHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IEFuIGFycmF5IG9mIGFsbCBkZWZhdWx0IHZhbHVlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uRGVmYXVsdHMoKQogICAgewogICAgICAgICR2YWx1ZXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+b3B0aW9ucyBhcyAkb3B0aW9uKSB7CiAgICAgICAgICAgICR2YWx1ZXNbJG9wdGlvbi0+Z2V0TmFtZSgpXSA9ICRvcHRpb24tPmdldERlZmF1bHQoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgSW5wdXRPcHRpb24gbmFtZSBnaXZlbiBhIHNob3J0Y3V0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNob3J0Y3V0IFRoZSBzaG9ydGN1dAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBJbnB1dE9wdGlvbiBuYW1lCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lcyBub3QgZXhpc3QKICAgICAqCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3J0Y3V0VG9OYW1lKCRzaG9ydGN1dCkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5zaG9ydGN1dHNbJHNob3J0Y3V0XSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0lcyIgb3B0aW9uIGRvZXMgbm90IGV4aXN0LicsICRzaG9ydGN1dCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5zaG9ydGN1dHNbJHNob3J0Y3V0XTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHN5bm9wc2lzLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRzaG9ydCBXaGV0aGVyIHRvIHJldHVybiB0aGUgc2hvcnQgdmVyc2lvbiAod2l0aCBvcHRpb25zIGZvbGRlZCkgb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHN5bm9wc2lzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTeW5vcHNpcygkc2hvcnQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkZWxlbWVudHMgPSBbXTsKCiAgICAgICAgaWYgKCRzaG9ydCAmJiAkdGhpcy0+Z2V0T3B0aW9ucygpKSB7CiAgICAgICAgICAgICRlbGVtZW50c1tdID0gJ1tvcHRpb25zXSc7CiAgICAgICAgfSBlbHNlaWYgKCEkc2hvcnQpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldE9wdGlvbnMoKSBhcyAkb3B0aW9uKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAnJzsKICAgICAgICAgICAgICAgIGlmICgkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJyAlcyVzJXMnLAogICAgICAgICAgICAgICAgICAgICAgICAkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSA/ICdbJyA6ICcnLAogICAgICAgICAgICAgICAgICAgICAgICBzdHJ0b3VwcGVyKCRvcHRpb24tPmdldE5hbWUoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICRvcHRpb24tPmlzVmFsdWVPcHRpb25hbCgpID8gJ10nIDogJycKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRzaG9ydGN1dCA9ICRvcHRpb24tPmdldFNob3J0Y3V0KCkgPyBzcHJpbnRmKCctJXN8JywgJG9wdGlvbi0+Z2V0U2hvcnRjdXQoKSkgOiAnJzsKICAgICAgICAgICAgICAgICRlbGVtZW50c1tdID0gc3ByaW50ZignWyVzLS0lcyVzXScsICRzaG9ydGN1dCwgJG9wdGlvbi0+Z2V0TmFtZSgpLCAkdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoXGNvdW50KCRlbGVtZW50cykgJiYgJHRoaXMtPmdldEFyZ3VtZW50cygpKSB7CiAgICAgICAgICAgICRlbGVtZW50c1tdID0gJ1stLV0nOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldEFyZ3VtZW50cygpIGFzICRhcmd1bWVudCkgewogICAgICAgICAgICAkZWxlbWVudCA9ICc8Jy4kYXJndW1lbnQtPmdldE5hbWUoKS4nPic7CiAgICAgICAgICAgIGlmICghJGFyZ3VtZW50LT5pc1JlcXVpcmVkKCkpIHsKICAgICAgICAgICAgICAgICRlbGVtZW50ID0gJ1snLiRlbGVtZW50LiddJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRhcmd1bWVudC0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgICAgICAkZWxlbWVudCAuPSAnICgnLiRlbGVtZW50LicpJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRhcmd1bWVudC0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgICAgICAkZWxlbWVudCAuPSAnLi4uJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAkZWxlbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgJywgJGVsZW1lbnRzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7CgovKioKICogU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlIGlzIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgYWxsIGlucHV0IGNsYXNzZXMKICogdGhhdCBoYXZlIGFuIGlucHV0IHN0cmVhbS4KICoKICogQGF1dGhvciBSb2JpbiBDaGFsYXMgPHJvYmluLmNoYWxhc0BnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlIGV4dGVuZHMgSW5wdXRJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tIHdoZW4gaW50ZXJhY3Rpbmcgd2l0aCB0aGUgdXNlci4KICAgICAqCiAgICAgKiBUaGlzIGlzIG1haW5seSB1c2VmdWwgZm9yIHRlc3RpbmcgcHVycG9zZS4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgJHN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJlYW0oJHN0cmVhbSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnB1dCBzdHJlYW0uCiAgICAgKgogICAgICogQHJldHVybiByZXNvdXJjZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdHJlYW0oKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBJbnB1dCBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIGNvbmNyZXRlIElucHV0IGNsYXNzZXMuCiAqCiAqIFRocmVlIGNvbmNyZXRlIGNsYXNzZXMgYXJlIHByb3ZpZGVkIGJ5IGRlZmF1bHQ6CiAqCiAqICAqIGBBcmd2SW5wdXRgOiBUaGUgaW5wdXQgY29tZXMgZnJvbSB0aGUgQ0xJIGFyZ3VtZW50cyAoYXJndikKICogICogYFN0cmluZ0lucHV0YDogVGhlIGlucHV0IGlzIHByb3ZpZGVkIGFzIGEgc3RyaW5nCiAqICAqIGBBcnJheUlucHV0YDogVGhlIGlucHV0IGlzIHByb3ZpZGVkIGFzIGFuIGFycmF5CiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgSW5wdXQgaW1wbGVtZW50cyBJbnB1dEludGVyZmFjZSwgU3RyZWFtYWJsZUlucHV0SW50ZXJmYWNlCnsKICAgIHByb3RlY3RlZCAkZGVmaW5pdGlvbjsKICAgIHByb3RlY3RlZCAkc3RyZWFtOwogICAgcHJvdGVjdGVkICRvcHRpb25zID0gW107CiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50cyA9IFtdOwogICAgcHJvdGVjdGVkICRpbnRlcmFjdGl2ZSA9IHRydWU7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRkZWZpbml0aW9uKSB7CiAgICAgICAgICAgICR0aGlzLT5kZWZpbml0aW9uID0gbmV3IElucHV0RGVmaW5pdGlvbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5iaW5kKCRkZWZpbml0aW9uKTsKICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYmluZChJbnB1dERlZmluaXRpb24gJGRlZmluaXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50cyA9IFtdOwogICAgICAgICR0aGlzLT5vcHRpb25zID0gW107CiAgICAgICAgJHRoaXMtPmRlZmluaXRpb24gPSAkZGVmaW5pdGlvbjsKCiAgICAgICAgJHRoaXMtPnBhcnNlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzZXMgY29tbWFuZCBsaW5lIGFyZ3VtZW50cy4KICAgICAqLwogICAgYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlKCk7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZSgpCiAgICB7CiAgICAgICAgJGRlZmluaXRpb24gPSAkdGhpcy0+ZGVmaW5pdGlvbjsKICAgICAgICAkZ2l2ZW5Bcmd1bWVudHMgPSAkdGhpcy0+YXJndW1lbnRzOwoKICAgICAgICAkbWlzc2luZ0FyZ3VtZW50cyA9IGFycmF5X2ZpbHRlcihhcnJheV9rZXlzKCRkZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKSksIGZ1bmN0aW9uICgkYXJndW1lbnQpIHVzZSAoJGRlZmluaXRpb24sICRnaXZlbkFyZ3VtZW50cykgewogICAgICAgICAgICByZXR1cm4gIVxhcnJheV9rZXlfZXhpc3RzKCRhcmd1bWVudCwgJGdpdmVuQXJndW1lbnRzKSAmJiAkZGVmaW5pdGlvbi0+Z2V0QXJndW1lbnQoJGFyZ3VtZW50KS0+aXNSZXF1aXJlZCgpOwogICAgICAgIH0pOwoKICAgICAgICBpZiAoXGNvdW50KCRtaXNzaW5nQXJndW1lbnRzKSA+IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignTm90IGVub3VnaCBhcmd1bWVudHMgKG1pc3Npbmc6ICIlcyIpLicsIGltcGxvZGUoJywgJywgJG1pc3NpbmdBcmd1bWVudHMpKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNJbnRlcmFjdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbnRlcmFjdGl2ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEludGVyYWN0aXZlKCRpbnRlcmFjdGl2ZSkKICAgIHsKICAgICAgICAkdGhpcy0+aW50ZXJhY3RpdmUgPSAoYm9vbCkgJGludGVyYWN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfbWVyZ2UoJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50RGVmYXVsdHMoKSwgJHRoaXMtPmFyZ3VtZW50cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudCgkbmFtZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5kZWZpbml0aW9uLT5oYXNBcmd1bWVudCgkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBhcmd1bWVudCBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5hcmd1bWVudHNbJG5hbWVdKSA/ICR0aGlzLT5hcmd1bWVudHNbJG5hbWVdIDogJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50KCRuYW1lKS0+Z2V0RGVmYXVsdCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5kZWZpbml0aW9uLT5oYXNBcmd1bWVudCgkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBhcmd1bWVudCBkb2VzIG5vdCBleGlzdC4nLCAkbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFyZ3VtZW50c1skbmFtZV0gPSAkdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNBcmd1bWVudCgkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9tZXJnZSgkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uRGVmYXVsdHMoKSwgJHRoaXMtPm9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRuYW1lKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc09wdGlvbigkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJHRoaXMtPm9wdGlvbnMpID8gJHRoaXMtPm9wdGlvbnNbJG5hbWVdIDogJHRoaXMtPmRlZmluaXRpb24tPmdldE9wdGlvbigkbmFtZSktPmdldERlZmF1bHQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wdGlvbigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc09wdGlvbigkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5vcHRpb25zWyRuYW1lXSA9ICR2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc09wdGlvbigkbmFtZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmluaXRpb24tPmhhc09wdGlvbigkbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFc2NhcGVzIGEgdG9rZW4gdGhyb3VnaCBlc2NhcGVzaGVsbGFyZyBpZiBpdCBjb250YWlucyB1bnNhZmUgY2hhcnMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdG9rZW4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXNjYXBlVG9rZW4oJHRva2VuKQogICAgewogICAgICAgIHJldHVybiBwcmVnX21hdGNoKCd7Xltcdy1dKyR9JywgJHRva2VuKSA/ICR0b2tlbiA6IGVzY2FwZXNoZWxsYXJnKCR0b2tlbik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJlYW0oJHN0cmVhbSkKICAgIHsKICAgICAgICAkdGhpcy0+c3RyZWFtID0gJHN0cmVhbTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0cmVhbSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdHJlYW07CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0OwoKLyoqCiAqIElucHV0QXdhcmVJbnRlcmZhY2Ugc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IGNsYXNzZXMgdGhhdCBkZXBlbmRzIG9uIHRoZQogKiBDb25zb2xlIElucHV0LgogKgogKiBAYXV0aG9yIFdvdXRlciBKIDx3YWxkaW8ud2ViZGVzaWduQGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBJbnB1dEF3YXJlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU2V0cyB0aGUgQ29uc29sZSBJbnB1dC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElucHV0KElucHV0SW50ZXJmYWNlICRpbnB1dCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXElucHV0OwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcRXhjZXB0aW9uXExvZ2ljRXhjZXB0aW9uOwoKLyoqCiAqIFJlcHJlc2VudHMgYSBjb21tYW5kIGxpbmUgYXJndW1lbnQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSW5wdXRBcmd1bWVudAp7CiAgICBjb25zdCBSRVFVSVJFRCA9IDE7CiAgICBjb25zdCBPUFRJT05BTCA9IDI7CiAgICBjb25zdCBJU19BUlJBWSA9IDQ7CgogICAgcHJpdmF0ZSAkbmFtZTsKICAgIHByaXZhdGUgJG1vZGU7CiAgICBwcml2YXRlICRkZWZhdWx0OwogICAgcHJpdmF0ZSAkZGVzY3JpcHRpb247CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgJG5hbWUgICAgICAgIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICAgICAgJG1vZGUgICAgICAgIFRoZSBhcmd1bWVudCBtb2RlOiBzZWxmOjpSRVFVSVJFRCBvciBzZWxmOjpPUFRJT05BTAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW118bnVsbCAkZGVmYXVsdCAgICAgVGhlIGRlZmF1bHQgdmFsdWUgKGZvciBzZWxmOjpPUFRJT05BTCBtb2RlIG9ubHkpCiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gV2hlbiBhcmd1bWVudCBtb2RlIGlzIG5vdCB2YWxpZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRtb2RlID0gbnVsbCwgJGRlc2NyaXB0aW9uID0gJycsICRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJG1vZGUpIHsKICAgICAgICAgICAgJG1vZGUgPSBzZWxmOjpPUFRJT05BTDsKICAgICAgICB9IGVsc2VpZiAoIVxpc19pbnQoJG1vZGUpIHx8ICRtb2RlID4gNyB8fCAkbW9kZSA8IDEpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdBcmd1bWVudCBtb2RlICIlcyIgaXMgbm90IHZhbGlkLicsICRtb2RlKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT5tb2RlID0gJG1vZGU7CiAgICAgICAgJHRoaXMtPmRlc2NyaXB0aW9uID0gJGRlc2NyaXB0aW9uOwoKICAgICAgICAkdGhpcy0+c2V0RGVmYXVsdCgkZGVmYXVsdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhcmd1bWVudCBuYW1lLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBhcmd1bWVudCBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGFyZ3VtZW50IGlzIHJlcXVpcmVkLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHBhcmFtZXRlciBtb2RlIGlzIHNlbGY6OlJFUVVJUkVELCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUmVxdWlyZWQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpSRVFVSVJFRCA9PT0gKHNlbGY6OlJFUVVJUkVEICYgJHRoaXMtPm1vZGUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBhcmd1bWVudCBjYW4gdGFrZSBtdWx0aXBsZSB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgbW9kZSBpcyBzZWxmOjpJU19BUlJBWSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6SVNfQVJSQVkgPT09IChzZWxmOjpJU19BUlJBWSAmICR0aGlzLT5tb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXXxudWxsICRkZWZhdWx0IFRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKgogICAgICogQHRocm93cyBMb2dpY0V4Y2VwdGlvbiBXaGVuIGluY29ycmVjdCBkZWZhdWx0IHZhbHVlIGlzIGdpdmVuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREZWZhdWx0KCRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoc2VsZjo6UkVRVUlSRUQgPT09ICR0aGlzLT5tb2RlICYmIG51bGwgIT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQ2Fubm90IHNldCBhIGRlZmF1bHQgdmFsdWUgZXhjZXB0IGZvciBJbnB1dEFyZ3VtZW50OjpPUFRJT05BTCBtb2RlLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5pc0FycmF5KCkpIHsKICAgICAgICAgICAgaWYgKG51bGwgPT09ICRkZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAkZGVmYXVsdCA9IFtdOwogICAgICAgICAgICB9IGVsc2VpZiAoIVxpc19hcnJheSgkZGVmYXVsdCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignQSBkZWZhdWx0IHZhbHVlIGZvciBhbiBhcnJheSBhcmd1bWVudCBtdXN0IGJlIGFuIGFycmF5LicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZGVmYXVsdCA9ICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xzdHJpbmdbXXxudWxsIFRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWZhdWx0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiB0ZXh0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBkZXNjcmlwdGlvbiB0ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXNjcmlwdGlvbjsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cTG9naWNFeGNlcHRpb247CgovKioKICogUmVwcmVzZW50cyBhIGNvbW1hbmQgbGluZSBvcHRpb24uCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgSW5wdXRPcHRpb24KewogICAgY29uc3QgVkFMVUVfTk9ORSA9IDE7CiAgICBjb25zdCBWQUxVRV9SRVFVSVJFRCA9IDI7CiAgICBjb25zdCBWQUxVRV9PUFRJT05BTCA9IDQ7CiAgICBjb25zdCBWQUxVRV9JU19BUlJBWSA9IDg7CgogICAgcHJpdmF0ZSAkbmFtZTsKICAgIHByaXZhdGUgJHNob3J0Y3V0OwogICAgcHJpdmF0ZSAkbW9kZTsKICAgIHByaXZhdGUgJGRlZmF1bHQ7CiAgICBwcml2YXRlICRkZXNjcmlwdGlvbjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAkbmFtZSAgICAgICAgVGhlIG9wdGlvbiBuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5fG51bGwgICAgICAgICAgICAgJHNob3J0Y3V0ICAgIFRoZSBzaG9ydGN1dHMsIGNhbiBiZSBudWxsLCBhIHN0cmluZyBvZiBzaG9ydGN1dHMgZGVsaW1pdGVkIGJ5IHwgb3IgYW4gYXJyYXkgb2Ygc2hvcnRjdXRzCiAgICAgKiBAcGFyYW0gaW50fG51bGwgICAgICAgICAgICAgICAgICAgICAgJG1vZGUgICAgICAgIFRoZSBvcHRpb24gbW9kZTogT25lIG9mIHRoZSBWQUxVRV8qIGNvbnN0YW50cwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICRkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmd8c3RyaW5nW118aW50fGJvb2x8bnVsbCAkZGVmYXVsdCAgICAgVGhlIGRlZmF1bHQgdmFsdWUgKG11c3QgYmUgbnVsbCBmb3Igc2VsZjo6VkFMVUVfTk9ORSkKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiBvcHRpb24gbW9kZSBpcyBpbnZhbGlkIG9yIGluY29tcGF0aWJsZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRzaG9ydGN1dCA9IG51bGwsICRtb2RlID0gbnVsbCwgJGRlc2NyaXB0aW9uID0gJycsICRkZWZhdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoMCA9PT0gc3RycG9zKCRuYW1lLCAnLS0nKSkgewogICAgICAgICAgICAkbmFtZSA9IHN1YnN0cigkbmFtZSwgMik7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0FuIG9wdGlvbiBuYW1lIGNhbm5vdCBiZSBlbXB0eS4nKTsKICAgICAgICB9CgogICAgICAgIGlmIChlbXB0eSgkc2hvcnRjdXQpKSB7CiAgICAgICAgICAgICRzaG9ydGN1dCA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCAhPT0gJHNob3J0Y3V0KSB7CiAgICAgICAgICAgIGlmIChcaXNfYXJyYXkoJHNob3J0Y3V0KSkgewogICAgICAgICAgICAgICAgJHNob3J0Y3V0ID0gaW1wbG9kZSgnfCcsICRzaG9ydGN1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHNob3J0Y3V0cyA9IHByZWdfc3BsaXQoJ3soXHwpLT99JywgbHRyaW0oJHNob3J0Y3V0LCAnLScpKTsKICAgICAgICAgICAgJHNob3J0Y3V0cyA9IGFycmF5X2ZpbHRlcigkc2hvcnRjdXRzKTsKICAgICAgICAgICAgJHNob3J0Y3V0ID0gaW1wbG9kZSgnfCcsICRzaG9ydGN1dHMpOwoKICAgICAgICAgICAgaWYgKGVtcHR5KCRzaG9ydGN1dCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0FuIG9wdGlvbiBzaG9ydGN1dCBjYW5ub3QgYmUgZW1wdHkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChudWxsID09PSAkbW9kZSkgewogICAgICAgICAgICAkbW9kZSA9IHNlbGY6OlZBTFVFX05PTkU7CiAgICAgICAgfSBlbHNlaWYgKCFcaXNfaW50KCRtb2RlKSB8fCAkbW9kZSA+IDE1IHx8ICRtb2RlIDwgMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ09wdGlvbiBtb2RlICIlcyIgaXMgbm90IHZhbGlkLicsICRtb2RlKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgICR0aGlzLT5zaG9ydGN1dCA9ICRzaG9ydGN1dDsKICAgICAgICAkdGhpcy0+bW9kZSA9ICRtb2RlOwogICAgICAgICR0aGlzLT5kZXNjcmlwdGlvbiA9ICRkZXNjcmlwdGlvbjsKCiAgICAgICAgaWYgKCR0aGlzLT5pc0FycmF5KCkgJiYgISR0aGlzLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ltcG9zc2libGUgdG8gaGF2ZSBhbiBvcHRpb24gbW9kZSBWQUxVRV9JU19BUlJBWSBpZiB0aGUgb3B0aW9uIGRvZXMgbm90IGFjY2VwdCBhIHZhbHVlLicpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNldERlZmF1bHQoJGRlZmF1bHQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3B0aW9uIHNob3J0Y3V0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwgVGhlIHNob3J0Y3V0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTaG9ydGN1dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zaG9ydGN1dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbiBuYW1lLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9wdGlvbiBhY2NlcHRzIGEgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdmFsdWUgbW9kZSBpcyBub3Qgc2VsZjo6VkFMVUVfTk9ORSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1ZhbHVlUmVxdWlyZWQoKSB8fCAkdGhpcy0+aXNWYWx1ZU9wdGlvbmFsKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9wdGlvbiByZXF1aXJlcyBhIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZhbHVlIG1vZGUgaXMgc2VsZjo6VkFMVUVfUkVRVUlSRUQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWx1ZVJlcXVpcmVkKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VkFMVUVfUkVRVUlSRUQgPT09IChzZWxmOjpWQUxVRV9SRVFVSVJFRCAmICR0aGlzLT5tb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3B0aW9uIHRha2VzIGFuIG9wdGlvbmFsIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHZhbHVlIG1vZGUgaXMgc2VsZjo6VkFMVUVfT1BUSU9OQUwsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWx1ZU9wdGlvbmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6VkFMVUVfT1BUSU9OQUwgPT09IChzZWxmOjpWQUxVRV9PUFRJT05BTCAmICR0aGlzLT5tb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3B0aW9uIGNhbiB0YWtlIG11bHRpcGxlIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiBtb2RlIGlzIHNlbGY6OlZBTFVFX0lTX0FSUkFZLCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpWQUxVRV9JU19BUlJBWSA9PT0gKHNlbGY6OlZBTFVFX0lTX0FSUkFZICYgJHRoaXMtPm1vZGUpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfHN0cmluZ1tdfGludHxib29sfG51bGwgJGRlZmF1bHQgVGhlIGRlZmF1bHQgdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIExvZ2ljRXhjZXB0aW9uIFdoZW4gaW5jb3JyZWN0IGRlZmF1bHQgdmFsdWUgaXMgZ2l2ZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlZmF1bHQoJGRlZmF1bHQgPSBudWxsKQogICAgewogICAgICAgIGlmIChzZWxmOjpWQUxVRV9OT05FID09PSAoc2VsZjo6VkFMVUVfTk9ORSAmICR0aGlzLT5tb2RlKSAmJiBudWxsICE9PSAkZGVmYXVsdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0Nhbm5vdCBzZXQgYSBkZWZhdWx0IHZhbHVlIHdoZW4gdXNpbmcgSW5wdXRPcHRpb246OlZBTFVFX05PTkUgbW9kZS4nKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aXNBcnJheSgpKSB7CiAgICAgICAgICAgIGlmIChudWxsID09PSAkZGVmYXVsdCkgewogICAgICAgICAgICAgICAgJGRlZmF1bHQgPSBbXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCFcaXNfYXJyYXkoJGRlZmF1bHQpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naWNFeGNlcHRpb24oJ0EgZGVmYXVsdCB2YWx1ZSBmb3IgYW4gYXJyYXkgb3B0aW9uIG11c3QgYmUgYW4gYXJyYXkuJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5kZWZhdWx0ID0gJHRoaXMtPmFjY2VwdFZhbHVlKCkgPyAkZGVmYXVsdCA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xzdHJpbmdbXXxpbnR8Ym9vbHxudWxsIFRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWZhdWx0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlZmF1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiB0ZXh0LgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBkZXNjcmlwdGlvbiB0ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBvcHRpb24gZXF1YWxzIHRoaXMgb25lLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXF1YWxzKHNlbGYgJG9wdGlvbikKICAgIHsKICAgICAgICByZXR1cm4gJG9wdGlvbi0+Z2V0TmFtZSgpID09PSAkdGhpcy0+Z2V0TmFtZSgpCiAgICAgICAgICAgICYmICRvcHRpb24tPmdldFNob3J0Y3V0KCkgPT09ICR0aGlzLT5nZXRTaG9ydGN1dCgpCiAgICAgICAgICAgICYmICRvcHRpb24tPmdldERlZmF1bHQoKSA9PT0gJHRoaXMtPmdldERlZmF1bHQoKQogICAgICAgICAgICAmJiAkb3B0aW9uLT5pc0FycmF5KCkgPT09ICR0aGlzLT5pc0FycmF5KCkKICAgICAgICAgICAgJiYgJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCkgPT09ICR0aGlzLT5pc1ZhbHVlUmVxdWlyZWQoKQogICAgICAgICAgICAmJiAkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSA9PT0gJHRoaXMtPmlzVmFsdWVPcHRpb25hbCgpCiAgICAgICAgOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxJbnB1dDsKCnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV4Y2VwdGlvblxJbnZhbGlkT3B0aW9uRXhjZXB0aW9uOwoKLyoqCiAqIEFycmF5SW5wdXQgcmVwcmVzZW50cyBhbiBpbnB1dCBwcm92aWRlZCBhcyBhbiBhcnJheS4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkaW5wdXQgPSBuZXcgQXJyYXlJbnB1dChbJ2NvbW1hbmQnID0+ICdmb286YmFyJywgJ2ZvbycgPT4gJ2JhcicsICctLWJhcicgPT4gJ2Zvb2JhciddKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBBcnJheUlucHV0IGV4dGVuZHMgSW5wdXQKewogICAgcHJpdmF0ZSAkcGFyYW1ldGVyczsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHBhcmFtZXRlcnMsIElucHV0RGVmaW5pdGlvbiAkZGVmaW5pdGlvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhcmFtZXRlcnMgPSAkcGFyYW1ldGVyczsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkZGVmaW5pdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaXJzdEFyZ3VtZW50KCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFyYW1ldGVycyBhcyAkcGFyYW0gPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICgkcGFyYW0gJiYgXGlzX3N0cmluZygkcGFyYW0pICYmICctJyA9PT0gJHBhcmFtWzBdKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRvbmx5UGFyYW1zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHZhbHVlcyA9IChhcnJheSkgJHZhbHVlczsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhcmFtZXRlcnMgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgaWYgKCFcaXNfaW50KCRrKSkgewogICAgICAgICAgICAgICAgJHYgPSAkazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRvbmx5UGFyYW1zICYmICctLScgPT09ICR2KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChcaW5fYXJyYXkoJHYsICR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRkZWZhdWx0ID0gZmFsc2UsICRvbmx5UGFyYW1zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHZhbHVlcyA9IChhcnJheSkgJHZhbHVlczsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnBhcmFtZXRlcnMgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgaWYgKCRvbmx5UGFyYW1zICYmICgnLS0nID09PSAkayB8fCAoXGlzX2ludCgkaykgJiYgJy0tJyA9PT0gJHYpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoXGlzX2ludCgkaykpIHsKICAgICAgICAgICAgICAgIGlmIChcaW5fYXJyYXkoJHYsICR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChcaW5fYXJyYXkoJGssICR2YWx1ZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGVmYXVsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzdHJpbmdpZmllZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJncyBwYXNzZWQgdG8gdGhlIGNvbW1hbmQuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgICRwYXJhbXMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cGFyYW1ldGVycyBhcyAkcGFyYW0gPT4gJHZhbCkgewogICAgICAgICAgICBpZiAoJHBhcmFtICYmIFxpc19zdHJpbmcoJHBhcmFtKSAmJiAnLScgPT09ICRwYXJhbVswXSkgewogICAgICAgICAgICAgICAgaWYgKFxpc19hcnJheSgkdmFsKSkgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2YWwgYXMgJHYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmFtc1tdID0gJHBhcmFtLignJyAhPSAkdiA/ICc9Jy4kdGhpcy0+ZXNjYXBlVG9rZW4oJHYpIDogJycpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHBhcmFtc1tdID0gJHBhcmFtLignJyAhPSAkdmFsID8gJz0nLiR0aGlzLT5lc2NhcGVUb2tlbigkdmFsKSA6ICcnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwYXJhbXNbXSA9IFxpc19hcnJheSgkdmFsKSA/IGltcGxvZGUoJyAnLCBhcnJheV9tYXAoWyR0aGlzLCAnZXNjYXBlVG9rZW4nXSwgJHZhbCkpIDogJHRoaXMtPmVzY2FwZVRva2VuKCR2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaW1wbG9kZSgnICcsICRwYXJhbXMpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2UoKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5wYXJhbWV0ZXJzIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICgnLS0nID09PSAka2V5KSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKDAgPT09IHN0cnBvcygka2V5LCAnLS0nKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZExvbmdPcHRpb24oc3Vic3RyKCRrZXksIDIpLCAkdmFsdWUpOwogICAgICAgICAgICB9IGVsc2VpZiAoMCA9PT0gc3RycG9zKCRrZXksICctJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRTaG9ydE9wdGlvbihzdWJzdHIoJGtleSwgMSksICR2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkQXJndW1lbnQoJGtleSwgJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBzaG9ydCBvcHRpb24gdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2hvcnRjdXQgVGhlIHNob3J0IG9wdGlvbiBrZXkKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlICAgIFRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZE9wdGlvbkV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkU2hvcnRPcHRpb24oJHNob3J0Y3V0LCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzU2hvcnRjdXQoJHNob3J0Y3V0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wdGlvbkV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0lcyIgb3B0aW9uIGRvZXMgbm90IGV4aXN0LicsICRzaG9ydGN1dCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFkZExvbmdPcHRpb24oJHRoaXMtPmRlZmluaXRpb24tPmdldE9wdGlvbkZvclNob3J0Y3V0KCRzaG9ydGN1dCktPmdldE5hbWUoKSwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBsb25nIG9wdGlvbiB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICBUaGUgbG9uZyBvcHRpb24ga2V5CiAgICAgKiBAcGFyYW0gbWl4ZWQgICR2YWx1ZSBUaGUgdmFsdWUgZm9yIHRoZSBvcHRpb24KICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRPcHRpb25FeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICogQHRocm93cyBJbnZhbGlkT3B0aW9uRXhjZXB0aW9uIFdoZW4gYSByZXF1aXJlZCB2YWx1ZSBpcyBtaXNzaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkTG9uZ09wdGlvbigkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc09wdGlvbigkbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcHRpb25FeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gZG9lcyBub3QgZXhpc3QuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgICRvcHRpb24gPSAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uKCRuYW1lKTsKCiAgICAgICAgaWYgKG51bGwgPT09ICR2YWx1ZSkgewogICAgICAgICAgICBpZiAoJG9wdGlvbi0+aXNWYWx1ZVJlcXVpcmVkKCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3B0aW9uRXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLS0lcyIgb3B0aW9uIHJlcXVpcmVzIGEgdmFsdWUuJywgJG5hbWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkb3B0aW9uLT5pc1ZhbHVlT3B0aW9uYWwoKSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG5hbWVdID0gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhbiBhcmd1bWVudCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICBUaGUgYXJndW1lbnQgbmFtZQogICAgICogQHBhcmFtIG1peGVkICAkdmFsdWUgVGhlIHZhbHVlIGZvciB0aGUgYXJndW1lbnQKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIGFyZ3VtZW50IGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRBcmd1bWVudCgkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRuYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiJXMiIGFyZ3VtZW50IGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+YXJndW1lbnRzWyRuYW1lXSA9ICR2YWx1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XENvbnNvbGVcSW5wdXQ7Cgp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKCi8qKgogKiBBcmd2SW5wdXQgcmVwcmVzZW50cyBhbiBpbnB1dCBjb21pbmcgZnJvbSB0aGUgQ0xJIGFyZ3VtZW50cy4KICoKICogVXNhZ2U6CiAqCiAqICAgICAkaW5wdXQgPSBuZXcgQXJndklucHV0KCk7CiAqCiAqIEJ5IGRlZmF1bHQsIHRoZSBgJF9TRVJWRVJbJ2FyZ3YnXWAgYXJyYXkgaXMgdXNlZCBmb3IgdGhlIGlucHV0IHZhbHVlcy4KICoKICogVGhpcyBjYW4gYmUgb3ZlcnJpZGRlbiBieSBleHBsaWNpdGx5IHBhc3NpbmcgdGhlIGlucHV0IHZhbHVlcyBpbiB0aGUgY29uc3RydWN0b3I6CiAqCiAqICAgICAkaW5wdXQgPSBuZXcgQXJndklucHV0KCRfU0VSVkVSWydhcmd2J10pOwogKgogKiBJZiB5b3UgcGFzcyBpdCB5b3Vyc2VsZiwgZG9uJ3QgZm9yZ2V0IHRoYXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIGFycmF5CiAqIGlzIHRoZSBuYW1lIG9mIHRoZSBydW5uaW5nIGFwcGxpY2F0aW9uLgogKgogKiBXaGVuIHBhc3NpbmcgYW4gYXJndW1lbnQgdG8gdGhlIGNvbnN0cnVjdG9yLCBiZSBzdXJlIHRoYXQgaXQgcmVzcGVjdHMKICogdGhlIHNhbWUgcnVsZXMgYXMgdGhlIGFyZ3Ygb25lLiBJdCdzIGFsbW9zdCBhbHdheXMgYmV0dGVyIHRvIHVzZSB0aGUKICogYFN0cmluZ0lucHV0YCB3aGVuIHlvdSB3YW50IHRvIHByb3ZpZGUgeW91ciBvd24gaW5wdXQuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBAc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9saWJjL21hbnVhbC9odG1sX25vZGUvQXJndW1lbnQtU3ludGF4Lmh0bWwKICogQHNlZSBodHRwOi8vd3d3Lm9wZW5ncm91cC5vcmcvb25saW5lcHVicy8wMDk2OTUzOTkvYmFzZWRlZnMveGJkX2NoYXAxMi5odG1sI3RhZ18xMl8wMgogKi8KY2xhc3MgQXJndklucHV0IGV4dGVuZHMgSW5wdXQKewogICAgcHJpdmF0ZSAkdG9rZW5zOwogICAgcHJpdmF0ZSAkcGFyc2VkOwoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5fG51bGwgICAgICAgICAgICRhcmd2ICAgICAgIEFuIGFycmF5IG9mIHBhcmFtZXRlcnMgZnJvbSB0aGUgQ0xJIChpbiB0aGUgYXJndiBmb3JtYXQpCiAgICAgKiBAcGFyYW0gSW5wdXREZWZpbml0aW9ufG51bGwgJGRlZmluaXRpb24gQSBJbnB1dERlZmluaXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRhcmd2ID0gbnVsbCwgSW5wdXREZWZpbml0aW9uICRkZWZpbml0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkYXJndiA9IG51bGwgIT09ICRhcmd2ID8gJGFyZ3YgOiAoaXNzZXQoJF9TRVJWRVJbJ2FyZ3YnXSkgPyAkX1NFUlZFUlsnYXJndiddIDogW10pOwoKICAgICAgICAvLyBzdHJpcCB0aGUgYXBwbGljYXRpb24gbmFtZQogICAgICAgIGFycmF5X3NoaWZ0KCRhcmd2KTsKCiAgICAgICAgJHRoaXMtPnRva2VucyA9ICRhcmd2OwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRkZWZpbml0aW9uKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0VG9rZW5zKGFycmF5ICR0b2tlbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnRva2VucyA9ICR0b2tlbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZSgpCiAgICB7CiAgICAgICAgJHBhcnNlT3B0aW9ucyA9IHRydWU7CiAgICAgICAgJHRoaXMtPnBhcnNlZCA9ICR0aGlzLT50b2tlbnM7CiAgICAgICAgd2hpbGUgKG51bGwgIT09ICR0b2tlbiA9IGFycmF5X3NoaWZ0KCR0aGlzLT5wYXJzZWQpKSB7CiAgICAgICAgICAgIGlmICgkcGFyc2VPcHRpb25zICYmICcnID09ICR0b2tlbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlQXJndW1lbnQoJHRva2VuKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRwYXJzZU9wdGlvbnMgJiYgJy0tJyA9PSAkdG9rZW4pIHsKICAgICAgICAgICAgICAgICRwYXJzZU9wdGlvbnMgPSBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRwYXJzZU9wdGlvbnMgJiYgMCA9PT0gc3RycG9zKCR0b2tlbiwgJy0tJykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUxvbmdPcHRpb24oJHRva2VuKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRwYXJzZU9wdGlvbnMgJiYgJy0nID09PSAkdG9rZW5bMF0gJiYgJy0nICE9PSAkdG9rZW4pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZVNob3J0T3B0aW9uKCR0b2tlbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cGFyc2VBcmd1bWVudCgkdG9rZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgc2hvcnQgb3B0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRva2VuIFRoZSBjdXJyZW50IHRva2VuCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcGFyc2VTaG9ydE9wdGlvbigkdG9rZW4pCiAgICB7CiAgICAgICAgJG5hbWUgPSBzdWJzdHIoJHRva2VuLCAxKTsKCiAgICAgICAgaWYgKFxzdHJsZW4oJG5hbWUpID4gMSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmRlZmluaXRpb24tPmhhc1Nob3J0Y3V0KCRuYW1lWzBdKSAmJiAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uRm9yU2hvcnRjdXQoJG5hbWVbMF0pLT5hY2NlcHRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICAvLyBhbiBvcHRpb24gd2l0aCBhIHZhbHVlICh3aXRoIG5vIHNwYWNlKQogICAgICAgICAgICAgICAgJHRoaXMtPmFkZFNob3J0T3B0aW9uKCRuYW1lWzBdLCBzdWJzdHIoJG5hbWUsIDEpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZVNob3J0T3B0aW9uU2V0KCRuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRTaG9ydE9wdGlvbigkbmFtZSwgbnVsbCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgc2hvcnQgb3B0aW9uIHNldC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBjdXJyZW50IHRva2VuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gb3B0aW9uIGdpdmVuIGRvZXNuJ3QgZXhpc3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZVNob3J0T3B0aW9uU2V0KCRuYW1lKQogICAgewogICAgICAgICRsZW4gPSBcc3RybGVuKCRuYW1lKTsKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkbGVuOyArKyRpKSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmRlZmluaXRpb24tPmhhc1Nob3J0Y3V0KCRuYW1lWyRpXSkpIHsKICAgICAgICAgICAgICAgICRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZygkbmFtZSwgbnVsbCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0lcyIgb3B0aW9uIGRvZXMgbm90IGV4aXN0LicsIGZhbHNlID09PSAkZW5jb2RpbmcgPyAkbmFtZVskaV0gOiBtYl9zdWJzdHIoJG5hbWUsICRpLCAxLCAkZW5jb2RpbmcpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRvcHRpb24gPSAkdGhpcy0+ZGVmaW5pdGlvbi0+Z2V0T3B0aW9uRm9yU2hvcnRjdXQoJG5hbWVbJGldKTsKICAgICAgICAgICAgaWYgKCRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRMb25nT3B0aW9uKCRvcHRpb24tPmdldE5hbWUoKSwgJGkgPT09ICRsZW4gLSAxID8gbnVsbCA6IHN1YnN0cigkbmFtZSwgJGkgKyAxKSk7CgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbigkb3B0aW9uLT5nZXROYW1lKCksIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbG9uZyBvcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdG9rZW4gVGhlIGN1cnJlbnQgdG9rZW4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZUxvbmdPcHRpb24oJHRva2VuKQogICAgewogICAgICAgICRuYW1lID0gc3Vic3RyKCR0b2tlbiwgMik7CgogICAgICAgIGlmIChmYWxzZSAhPT0gJHBvcyA9IHN0cnBvcygkbmFtZSwgJz0nKSkgewogICAgICAgICAgICBpZiAoMCA9PT0gXHN0cmxlbigkdmFsdWUgPSBzdWJzdHIoJG5hbWUsICRwb3MgKyAxKSkpIHsKICAgICAgICAgICAgICAgIC8vIGlmIG5vIHZhbHVlIGFmdGVyICI9IiB0aGVuIHN1YnN0cigpIHJldHVybnMgIiIgc2luY2UgcGhwNyBvbmx5LCBmYWxzZSBiZWZvcmUKICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL3BocC5uZXQvbWlncmF0aW9uNzAuaW5jb21wYXRpYmxlLnBocCMxMTkxNTEKICAgICAgICAgICAgICAgIGlmIChcUEhQX1ZFUlNJT05fSUQgPCA3MDAwMCAmJiBmYWxzZSA9PT0gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhcnJheV91bnNoaWZ0KCR0aGlzLT5wYXJzZWQsICR2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmFkZExvbmdPcHRpb24oc3Vic3RyKCRuYW1lLCAwLCAkcG9zKSwgJHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+YWRkTG9uZ09wdGlvbigkbmFtZSwgbnVsbCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRva2VuIFRoZSBjdXJyZW50IHRva2VuCiAgICAgKgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gdG9vIG1hbnkgYXJndW1lbnRzIGFyZSBnaXZlbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhcnNlQXJndW1lbnQoJHRva2VuKQogICAgewogICAgICAgICRjID0gXGNvdW50KCR0aGlzLT5hcmd1bWVudHMpOwoKICAgICAgICAvLyBpZiBpbnB1dCBpcyBleHBlY3RpbmcgYW5vdGhlciBhcmd1bWVudCwgYWRkIGl0CiAgICAgICAgaWYgKCR0aGlzLT5kZWZpbml0aW9uLT5oYXNBcmd1bWVudCgkYykpIHsKICAgICAgICAgICAgJGFyZyA9ICR0aGlzLT5kZWZpbml0aW9uLT5nZXRBcmd1bWVudCgkYyk7CiAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudHNbJGFyZy0+Z2V0TmFtZSgpXSA9ICRhcmctPmlzQXJyYXkoKSA/IFskdG9rZW5dIDogJHRva2VuOwoKICAgICAgICAvLyBpZiBsYXN0IGFyZ3VtZW50IGlzQXJyYXkoKSwgYXBwZW5kIHRva2VuIHRvIGxhc3QgYXJndW1lbnQKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmRlZmluaXRpb24tPmhhc0FyZ3VtZW50KCRjIC0gMSkgJiYgJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50KCRjIC0gMSktPmlzQXJyYXkoKSkgewogICAgICAgICAgICAkYXJnID0gJHRoaXMtPmRlZmluaXRpb24tPmdldEFyZ3VtZW50KCRjIC0gMSk7CiAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudHNbJGFyZy0+Z2V0TmFtZSgpXVtdID0gJHRva2VuOwoKICAgICAgICAvLyB1bmV4cGVjdGVkIGFyZ3VtZW50CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGFsbCA9ICR0aGlzLT5kZWZpbml0aW9uLT5nZXRBcmd1bWVudHMoKTsKICAgICAgICAgICAgaWYgKFxjb3VudCgkYWxsKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVG9vIG1hbnkgYXJndW1lbnRzLCBleHBlY3RlZCBhcmd1bWVudHMgIiVzIi4nLCBpbXBsb2RlKCciICInLCBhcnJheV9rZXlzKCRhbGwpKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdObyBhcmd1bWVudHMgZXhwZWN0ZWQsIGdvdCAiJXMiLicsICR0b2tlbikpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBzaG9ydCBvcHRpb24gdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2hvcnRjdXQgVGhlIHNob3J0IG9wdGlvbiBrZXkKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlICAgIFRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBXaGVuIG9wdGlvbiBnaXZlbiBkb2Vzbid0IGV4aXN0CiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gYWRkU2hvcnRPcHRpb24oJHNob3J0Y3V0LCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZGVmaW5pdGlvbi0+aGFzU2hvcnRjdXQoJHNob3J0Y3V0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIi0lcyIgb3B0aW9uIGRvZXMgbm90IGV4aXN0LicsICRzaG9ydGN1dCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFkZExvbmdPcHRpb24oJHRoaXMtPmRlZmluaXRpb24tPmdldE9wdGlvbkZvclNob3J0Y3V0KCRzaG9ydGN1dCktPmdldE5hbWUoKSwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBsb25nIG9wdGlvbiB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lICBUaGUgbG9uZyBvcHRpb24ga2V5CiAgICAgKiBAcGFyYW0gbWl4ZWQgICR2YWx1ZSBUaGUgdmFsdWUgZm9yIHRoZSBvcHRpb24KICAgICAqCiAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gV2hlbiBvcHRpb24gZ2l2ZW4gZG9lc24ndCBleGlzdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFkZExvbmdPcHRpb24oJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5kZWZpbml0aW9uLT5oYXNPcHRpb24oJG5hbWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNwcmludGYoJ1RoZSAiLS0lcyIgb3B0aW9uIGRvZXMgbm90IGV4aXN0LicsICRuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAkb3B0aW9uID0gJHRoaXMtPmRlZmluaXRpb24tPmdldE9wdGlvbigkbmFtZSk7CgogICAgICAgIGlmIChudWxsICE9PSAkdmFsdWUgJiYgISRvcHRpb24tPmFjY2VwdFZhbHVlKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gZG9lcyBub3QgYWNjZXB0IGEgdmFsdWUuJywgJG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIGlmIChcaW5fYXJyYXkoJHZhbHVlLCBbJycsIG51bGxdLCB0cnVlKSAmJiAkb3B0aW9uLT5hY2NlcHRWYWx1ZSgpICYmIFxjb3VudCgkdGhpcy0+cGFyc2VkKSkgewogICAgICAgICAgICAvLyBpZiBvcHRpb24gYWNjZXB0cyBhbiBvcHRpb25hbCBvciBtYW5kYXRvcnkgYXJndW1lbnQKICAgICAgICAgICAgLy8gbGV0J3Mgc2VlIGlmIHRoZXJlIGlzIG9uZSBwcm92aWRlZAogICAgICAgICAgICAkbmV4dCA9IGFycmF5X3NoaWZ0KCR0aGlzLT5wYXJzZWQpOwogICAgICAgICAgICBpZiAoKGlzc2V0KCRuZXh0WzBdKSAmJiAnLScgIT09ICRuZXh0WzBdKSB8fCBcaW5fYXJyYXkoJG5leHQsIFsnJywgbnVsbF0sIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkbmV4dDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJHRoaXMtPnBhcnNlZCwgJG5leHQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHZhbHVlKSB7CiAgICAgICAgICAgIGlmICgkb3B0aW9uLT5pc1ZhbHVlUmVxdWlyZWQoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc3ByaW50ZignVGhlICItLSVzIiBvcHRpb24gcmVxdWlyZXMgYSB2YWx1ZS4nLCAkbmFtZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISRvcHRpb24tPmlzQXJyYXkoKSAmJiAhJG9wdGlvbi0+aXNWYWx1ZU9wdGlvbmFsKCkpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkb3B0aW9uLT5pc0FycmF5KCkpIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG5hbWVdW10gPSAkdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPm9wdGlvbnNbJG5hbWVdID0gJHZhbHVlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0QXJndW1lbnQoKQogICAgewogICAgICAgICRpc09wdGlvbiA9IGZhbHNlOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50b2tlbnMgYXMgJGkgPT4gJHRva2VuKSB7CiAgICAgICAgICAgIGlmICgkdG9rZW4gJiYgJy0nID09PSAkdG9rZW5bMF0pIHsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSAhPT0gc3RycG9zKCR0b2tlbiwgJz0nKSB8fCAhaXNzZXQoJHRoaXMtPnRva2Vuc1skaSArIDFdKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIElmIGl0J3MgYSBsb25nIG9wdGlvbiwgY29uc2lkZXIgdGhhdCBldmVyeXRoaW5nIGFmdGVyICItLSIgaXMgdGhlIG9wdGlvbiBuYW1lLgogICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB1c2UgdGhlIGxhc3QgY2hhciAoaWYgaXQncyBhIHNob3J0IG9wdGlvbiBzZXQsIG9ubHkgdGhlIGxhc3Qgb25lIGNhbiB0YWtlIGEgdmFsdWUgd2l0aCBzcGFjZSBzZXBhcmF0b3IpCiAgICAgICAgICAgICAgICAkbmFtZSA9ICctJyA9PT0gJHRva2VuWzFdID8gc3Vic3RyKCR0b2tlbiwgMikgOiBzdWJzdHIoJHRva2VuLCAtMSk7CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5vcHRpb25zWyRuYW1lXSkgJiYgISR0aGlzLT5kZWZpbml0aW9uLT5oYXNTaG9ydGN1dCgkbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBub29wCiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoKGlzc2V0KCR0aGlzLT5vcHRpb25zWyRuYW1lXSkgfHwgaXNzZXQoJHRoaXMtPm9wdGlvbnNbJG5hbWUgPSAkdGhpcy0+ZGVmaW5pdGlvbi0+c2hvcnRjdXRUb05hbWUoJG5hbWUpXSkpICYmICR0aGlzLT50b2tlbnNbJGkgKyAxXSA9PT0gJHRoaXMtPm9wdGlvbnNbJG5hbWVdKSB7CiAgICAgICAgICAgICAgICAgICAgJGlzT3B0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRpc09wdGlvbikgewogICAgICAgICAgICAgICAgJGlzT3B0aW9uID0gZmFsc2U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGFyYW1ldGVyT3B0aW9uKCR2YWx1ZXMsICRvbmx5UGFyYW1zID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHZhbHVlcyA9IChhcnJheSkgJHZhbHVlczsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRva2VucyBhcyAkdG9rZW4pIHsKICAgICAgICAgICAgaWYgKCRvbmx5UGFyYW1zICYmICctLScgPT09ICR0b2tlbikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZXMgYXMgJHZhbHVlKSB7CiAgICAgICAgICAgICAgICAvLyBPcHRpb25zIHdpdGggdmFsdWVzOgogICAgICAgICAgICAgICAgLy8gICBGb3IgbG9uZyBvcHRpb25zLCB0ZXN0IGZvciAnLS1vcHRpb249JyBhdCBiZWdpbm5pbmcKICAgICAgICAgICAgICAgIC8vICAgRm9yIHNob3J0IG9wdGlvbnMsIHRlc3QgZm9yICctbycgYXQgYmVnaW5uaW5nCiAgICAgICAgICAgICAgICAkbGVhZGluZyA9IDAgPT09IHN0cnBvcygkdmFsdWUsICctLScpID8gJHZhbHVlLic9JyA6ICR2YWx1ZTsKICAgICAgICAgICAgICAgIGlmICgkdG9rZW4gPT09ICR2YWx1ZSB8fCAnJyAhPT0gJGxlYWRpbmcgJiYgMCA9PT0gc3RycG9zKCR0b2tlbiwgJGxlYWRpbmcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhcmFtZXRlck9wdGlvbigkdmFsdWVzLCAkZGVmYXVsdCA9IGZhbHNlLCAkb25seVBhcmFtcyA9IGZhbHNlKQogICAgewogICAgICAgICR2YWx1ZXMgPSAoYXJyYXkpICR2YWx1ZXM7CiAgICAgICAgJHRva2VucyA9ICR0aGlzLT50b2tlbnM7CgogICAgICAgIHdoaWxlICgwIDwgXGNvdW50KCR0b2tlbnMpKSB7CiAgICAgICAgICAgICR0b2tlbiA9IGFycmF5X3NoaWZ0KCR0b2tlbnMpOwogICAgICAgICAgICBpZiAoJG9ubHlQYXJhbXMgJiYgJy0tJyA9PT0gJHRva2VuKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGRlZmF1bHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZXMgYXMgJHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRva2VuID09PSAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfc2hpZnQoJHRva2Vucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBPcHRpb25zIHdpdGggdmFsdWVzOgogICAgICAgICAgICAgICAgLy8gICBGb3IgbG9uZyBvcHRpb25zLCB0ZXN0IGZvciAnLS1vcHRpb249JyBhdCBiZWdpbm5pbmcKICAgICAgICAgICAgICAgIC8vICAgRm9yIHNob3J0IG9wdGlvbnMsIHRlc3QgZm9yICctbycgYXQgYmVnaW5uaW5nCiAgICAgICAgICAgICAgICAkbGVhZGluZyA9IDAgPT09IHN0cnBvcygkdmFsdWUsICctLScpID8gJHZhbHVlLic9JyA6ICR2YWx1ZTsKICAgICAgICAgICAgICAgIGlmICgnJyAhPT0gJGxlYWRpbmcgJiYgMCA9PT0gc3RycG9zKCR0b2tlbiwgJGxlYWRpbmcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkdG9rZW4sIFxzdHJsZW4oJGxlYWRpbmcpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRkZWZhdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZ2lmaWVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcmdzIHBhc3NlZCB0byB0aGUgY29tbWFuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgJHRva2VucyA9IGFycmF5X21hcChmdW5jdGlvbiAoJHRva2VuKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCd7XigtW149XSs9KSguKyl9JywgJHRva2VuLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoWzFdLiR0aGlzLT5lc2NhcGVUb2tlbigkbWF0Y2hbMl0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRva2VuICYmICctJyAhPT0gJHRva2VuWzBdKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVzY2FwZVRva2VuKCR0b2tlbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdG9rZW47CiAgICAgICAgfSwgJHRoaXMtPnRva2Vucyk7CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgJywgJHRva2Vucyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50TGlzdGVuZXI7Cgp1c2UgUHNyXExvZ1xMb2dnZXJJbnRlcmZhY2U7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXENvbnNvbGVFdmVudHM7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50XENvbnNvbGVFcnJvckV2ZW50Owp1c2UgU3ltZm9ueVxDb21wb25lbnRcQ29uc29sZVxFdmVudFxDb25zb2xlRXZlbnQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxDb25zb2xlXEV2ZW50XENvbnNvbGVUZXJtaW5hdGVFdmVudDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEV2ZW50RGlzcGF0Y2hlclxFdmVudFN1YnNjcmliZXJJbnRlcmZhY2U7CgovKioKICogQGF1dGhvciBKYW1lcyBIYWxzYWxsIDxqYW1lcy50LmhhbHNhbGxAZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgUm9iaW4gQ2hhbGFzIDxyb2Jpbi5jaGFsYXNAZ21haWwuY29tPgogKi8KY2xhc3MgRXJyb3JMaXN0ZW5lciBpbXBsZW1lbnRzIEV2ZW50U3Vic2NyaWJlckludGVyZmFjZQp7CiAgICBwcml2YXRlICRsb2dnZXI7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KExvZ2dlckludGVyZmFjZSAkbG9nZ2VyID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nZ2VyID0gJGxvZ2dlcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gb25Db25zb2xlRXJyb3IoQ29uc29sZUVycm9yRXZlbnQgJGV2ZW50KQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+bG9nZ2VyKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRlcnJvciA9ICRldmVudC0+Z2V0RXJyb3IoKTsKCiAgICAgICAgaWYgKCEkaW5wdXRTdHJpbmcgPSAkdGhpcy0+Z2V0SW5wdXRTdHJpbmcoJGV2ZW50KSkgewogICAgICAgICAgICAkdGhpcy0+bG9nZ2VyLT5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdXNpbmcgdGhlIGNvbnNvbGUuIE1lc3NhZ2U6ICJ7bWVzc2FnZX0iJywgWydleGNlcHRpb24nID0+ICRlcnJvciwgJ21lc3NhZ2UnID0+ICRlcnJvci0+Z2V0TWVzc2FnZSgpXSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bG9nZ2VyLT5lcnJvcignRXJyb3IgdGhyb3duIHdoaWxlIHJ1bm5pbmcgY29tbWFuZCAie2NvbW1hbmR9Ii4gTWVzc2FnZTogInttZXNzYWdlfSInLCBbJ2V4Y2VwdGlvbicgPT4gJGVycm9yLCAnY29tbWFuZCcgPT4gJGlucHV0U3RyaW5nLCAnbWVzc2FnZScgPT4gJGVycm9yLT5nZXRNZXNzYWdlKCldKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gb25Db25zb2xlVGVybWluYXRlKENvbnNvbGVUZXJtaW5hdGVFdmVudCAkZXZlbnQpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICR0aGlzLT5sb2dnZXIpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGV4aXRDb2RlID0gJGV2ZW50LT5nZXRFeGl0Q29kZSgpOwoKICAgICAgICBpZiAoMCA9PT0gJGV4aXRDb2RlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghJGlucHV0U3RyaW5nID0gJHRoaXMtPmdldElucHV0U3RyaW5nKCRldmVudCkpIHsKICAgICAgICAgICAgJHRoaXMtPmxvZ2dlci0+ZGVidWcoJ1RoZSBjb25zb2xlIGV4aXRlZCB3aXRoIGNvZGUgIntjb2RlfSInLCBbJ2NvZGUnID0+ICRleGl0Q29kZV0pOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxvZ2dlci0+ZGVidWcoJ0NvbW1hbmQgIntjb21tYW5kfSIgZXhpdGVkIHdpdGggY29kZSAie2NvZGV9IicsIFsnY29tbWFuZCcgPT4gJGlucHV0U3RyaW5nLCAnY29kZScgPT4gJGV4aXRDb2RlXSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRTdWJzY3JpYmVkRXZlbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICBDb25zb2xlRXZlbnRzOjpFUlJPUiA9PiBbJ29uQ29uc29sZUVycm9yJywgLTEyOF0sCiAgICAgICAgICAgIENvbnNvbGVFdmVudHM6OlRFUk1JTkFURSA9PiBbJ29uQ29uc29sZVRlcm1pbmF0ZScsIC0xMjhdLAogICAgICAgIF07CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0SW5wdXRTdHJpbmcoQ29uc29sZUV2ZW50ICRldmVudCkKICAgIHsKICAgICAgICAkY29tbWFuZE5hbWUgPSAkZXZlbnQtPmdldENvbW1hbmQoKSA/ICRldmVudC0+Z2V0Q29tbWFuZCgpLT5nZXROYW1lKCkgOiBudWxsOwogICAgICAgICRpbnB1dCA9ICRldmVudC0+Z2V0SW5wdXQoKTsKCiAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJGlucHV0LCAnX190b1N0cmluZycpKSB7CiAgICAgICAgICAgIGlmICgkY29tbWFuZE5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZShbIickY29tbWFuZE5hbWUnIiwgIlwiJGNvbW1hbmROYW1lXCIiXSwgJGNvbW1hbmROYW1lLCAoc3RyaW5nKSAkaW5wdXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJGlucHV0OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb21tYW5kTmFtZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlcjsKCi8qKgogKiBHbG9iIG1hdGNoZXMgZ2xvYmJpbmcgcGF0dGVybnMgYWdhaW5zdCB0ZXh0LgogKgogKiAgICAgaWYgbWF0Y2hfZ2xvYigiZm9vLioiLCAiZm9vLmJhciIpIGVjaG8gIm1hdGNoZWRcbiI7CiAqCiAqICAgICAvLyBwcmludHMgZm9vLmJhciBhbmQgZm9vLmJhegogKiAgICAgJHJlZ2V4ID0gZ2xvYl90b19yZWdleCgiZm9vLioiKTsKICogICAgIGZvciAoWydmb28uYmFyJywgJ2Zvby5iYXonLCAnZm9vJywgJ2JhciddIGFzICR0KQogKiAgICAgewogKiAgICAgICAgIGlmICgvJHJlZ2V4LykgZWNobyAibWF0Y2hlZDogJGNhclxuIjsKICogICAgIH0KICoKICogR2xvYiBpbXBsZW1lbnRzIGdsb2IoMykgc3R5bGUgbWF0Y2hpbmcgdGhhdCBjYW4gYmUgdXNlZCB0byBtYXRjaAogKiBhZ2FpbnN0IHRleHQsIHJhdGhlciB0aGFuIGZldGNoaW5nIG5hbWVzIGZyb20gYSBmaWxlc3lzdGVtLgogKgogKiBCYXNlZCBvbiB0aGUgUGVybCBUZXh0OjpHbG9iIG1vZHVsZS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+IFBIUCBwb3J0CiAqIEBhdXRob3IgICAgIFJpY2hhcmQgQ2xhbXAgPHJpY2hhcmRjQHVuaXhiZWFyZC5uZXQ+IFBlcmwgdmVyc2lvbgogKiBAY29weXJpZ2h0ICAyMDA0LTIwMDUgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAY29weXJpZ2h0ICAyMDAyIFJpY2hhcmQgQ2xhbXAgPHJpY2hhcmRjQHVuaXhiZWFyZC5uZXQ+CiAqLwpjbGFzcyBHbG9iCnsKICAgIC8qKgogICAgICogUmV0dXJucyBhIHJlZ2V4cCB3aGljaCBpcyB0aGUgZXF1aXZhbGVudCBvZiB0aGUgZ2xvYiBwYXR0ZXJuLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGdsb2IgICAgICAgICAgICAgICAgVGhlIGdsb2IgcGF0dGVybgogICAgICogQHBhcmFtIGJvb2wgICAkc3RyaWN0TGVhZGluZ0RvdAogICAgICogQHBhcmFtIGJvb2wgICAkc3RyaWN0V2lsZGNhcmRTbGFzaAogICAgICogQHBhcmFtIHN0cmluZyAkZGVsaW1pdGVyICAgICAgICAgICBPcHRpb25hbCBkZWxpbWl0ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyByZWdleCBUaGUgcmVnZXhwCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9SZWdleCgkZ2xvYiwgJHN0cmljdExlYWRpbmdEb3QgPSB0cnVlLCAkc3RyaWN0V2lsZGNhcmRTbGFzaCA9IHRydWUsICRkZWxpbWl0ZXIgPSAnIycpCiAgICB7CiAgICAgICAgJGZpcnN0Qnl0ZSA9IHRydWU7CiAgICAgICAgJGVzY2FwaW5nID0gZmFsc2U7CiAgICAgICAgJGluQ3VybGllcyA9IDA7CiAgICAgICAgJHJlZ2V4ID0gJyc7CiAgICAgICAgJHNpemVHbG9iID0gXHN0cmxlbigkZ2xvYik7CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJHNpemVHbG9iOyArKyRpKSB7CiAgICAgICAgICAgICRjYXIgPSAkZ2xvYlskaV07CiAgICAgICAgICAgIGlmICgkZmlyc3RCeXRlICYmICRzdHJpY3RMZWFkaW5nRG90ICYmICcuJyAhPT0gJGNhcikgewogICAgICAgICAgICAgICAgJHJlZ2V4IC49ICcoPz1bXlwuXSknOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZmlyc3RCeXRlID0gJy8nID09PSAkY2FyOwoKICAgICAgICAgICAgaWYgKCRmaXJzdEJ5dGUgJiYgJHN0cmljdFdpbGRjYXJkU2xhc2ggJiYgaXNzZXQoJGdsb2JbJGkgKyAyXSkgJiYgJyoqJyA9PT0gJGdsb2JbJGkgKyAxXS4kZ2xvYlskaSArIDJdICYmICghaXNzZXQoJGdsb2JbJGkgKyAzXSkgfHwgJy8nID09PSAkZ2xvYlskaSArIDNdKSkgewogICAgICAgICAgICAgICAgJGNhciA9ICdbXi9dKysvJzsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGdsb2JbJGkgKyAzXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY2FyIC49ICc/JzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHN0cmljdExlYWRpbmdEb3QpIHsKICAgICAgICAgICAgICAgICAgICAkY2FyID0gJyg/PVteXC5dKScuJGNhcjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkY2FyID0gJy8oPzonLiRjYXIuJykqJzsKICAgICAgICAgICAgICAgICRpICs9IDIgKyBpc3NldCgkZ2xvYlskaSArIDNdKTsKCiAgICAgICAgICAgICAgICBpZiAoJy8nID09PSAkZGVsaW1pdGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJGNhciA9IHN0cl9yZXBsYWNlKCcvJywgJ1xcLycsICRjYXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJGRlbGltaXRlciA9PT0gJGNhciB8fCAnLicgPT09ICRjYXIgfHwgJygnID09PSAkY2FyIHx8ICcpJyA9PT0gJGNhciB8fCAnfCcgPT09ICRjYXIgfHwgJysnID09PSAkY2FyIHx8ICdeJyA9PT0gJGNhciB8fCAnJCcgPT09ICRjYXIpIHsKICAgICAgICAgICAgICAgICRyZWdleCAuPSAiXFwkY2FyIjsKICAgICAgICAgICAgfSBlbHNlaWYgKCcqJyA9PT0gJGNhcikgewogICAgICAgICAgICAgICAgJHJlZ2V4IC49ICRlc2NhcGluZyA/ICdcXConIDogKCRzdHJpY3RXaWxkY2FyZFNsYXNoID8gJ1teL10qJyA6ICcuKicpOwogICAgICAgICAgICB9IGVsc2VpZiAoJz8nID09PSAkY2FyKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGVzY2FwaW5nID8gJ1xcPycgOiAoJHN0cmljdFdpbGRjYXJkU2xhc2ggPyAnW14vXScgOiAnLicpOwogICAgICAgICAgICB9IGVsc2VpZiAoJ3snID09PSAkY2FyKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGVzY2FwaW5nID8gJ1xceycgOiAnKCc7CiAgICAgICAgICAgICAgICBpZiAoISRlc2NhcGluZykgewogICAgICAgICAgICAgICAgICAgICsrJGluQ3VybGllczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCd9JyA9PT0gJGNhciAmJiAkaW5DdXJsaWVzKSB7CiAgICAgICAgICAgICAgICAkcmVnZXggLj0gJGVzY2FwaW5nID8gJ30nIDogJyknOwogICAgICAgICAgICAgICAgaWYgKCEkZXNjYXBpbmcpIHsKICAgICAgICAgICAgICAgICAgICAtLSRpbkN1cmxpZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgnLCcgPT09ICRjYXIgJiYgJGluQ3VybGllcykgewogICAgICAgICAgICAgICAgJHJlZ2V4IC49ICRlc2NhcGluZyA/ICcsJyA6ICd8JzsKICAgICAgICAgICAgfSBlbHNlaWYgKCdcXCcgPT09ICRjYXIpIHsKICAgICAgICAgICAgICAgIGlmICgkZXNjYXBpbmcpIHsKICAgICAgICAgICAgICAgICAgICAkcmVnZXggLj0gJ1xcXFwnOwogICAgICAgICAgICAgICAgICAgICRlc2NhcGluZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZXNjYXBpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJlZ2V4IC49ICRjYXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVzY2FwaW5nID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRlbGltaXRlci4nXicuJHJlZ2V4LickJy4kZGVsaW1pdGVyOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxjb250YWN0QGpmc2ltb24uZnI+CiAqCiAqIEBkZXByZWNhdGVkIHNpbmNlIDMuMywgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAqLwppbnRlcmZhY2UgRXhjZXB0aW9uSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogQHJldHVybiBcU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEFkYXB0ZXJcQWRhcHRlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWRhcHRlcigpOwp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEV4Y2VwdGlvbjsKCi8qKgogKiBAYXV0aG9yIEplYW4tRnJhbsOnb2lzIFNpbW9uIDxqZWFuZnJhbmNvaXMuc2ltb25Ac2Vuc2lvbGFicy5jb20+CiAqLwpjbGFzcyBBY2Nlc3NEZW5pZWRFeGNlcHRpb24gZXh0ZW5kcyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCi8qKgogKiBQYXRoRmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSBwYXRoIHBhdHRlcm5zIChlLmcuIHNvbWUvc3BlY2lhbC9kaXIpLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBhdXRob3IgV8WCb2R6aW1pZXJ6IEdhamRhIDxnYWpkYXdAZ2FqZGF3LnBsPgogKi8KY2xhc3MgUGF0aEZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgTXVsdGlwbGVQY3JlRmlsdGVySXRlcmF0b3IKewogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgJGZpbGVuYW1lID0gJHRoaXMtPmN1cnJlbnQoKS0+Z2V0UmVsYXRpdmVQYXRobmFtZSgpOwoKICAgICAgICBpZiAoJ1xcJyA9PT0gXERJUkVDVE9SWV9TRVBBUkFUT1IpIHsKICAgICAgICAgICAgJGZpbGVuYW1lID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkZmlsZW5hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0FjY2VwdGVkKCRmaWxlbmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBzdHJpbmdzIHRvIHJlZ2V4cC4KICAgICAqCiAgICAgKiBQQ1JFIHBhdHRlcm5zIGFyZSBsZWZ0IHVuY2hhbmdlZC4KICAgICAqCiAgICAgKiBEZWZhdWx0IGNvbnZlcnNpb246CiAgICAgKiAgICAgJ2xvcmVtL2lwc3VtL2RvbG9yJyA9PT4gICdsb3JlbVwvaXBzdW1cL2RvbG9yLycKICAgICAqCiAgICAgKiBVc2Ugb25seSAvIGFzIGRpcmVjdG9yeSBzZXBhcmF0b3IgKG9uIFdpbmRvd3MgYWxzbykuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyIFBhdHRlcm46IHJlZ2V4cCBvciBkaXJuYW1lCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBzdHJpbmcgb3IgcmVnZXhwCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB0b1JlZ2V4KCRzdHIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1JlZ2V4KCRzdHIpID8gJHN0ciA6ICcvJy5wcmVnX3F1b3RlKCRzdHIsICcvJykuJy8nOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEZpbGVUeXBlRmlsdGVySXRlcmF0b3Igb25seSBrZWVwcyBmaWxlcywgZGlyZWN0b3JpZXMsIG9yIGJvdGguCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRmlsZVR5cGVGaWx0ZXJJdGVyYXRvciBleHRlbmRzIEZpbHRlckl0ZXJhdG9yCnsKICAgIGNvbnN0IE9OTFlfRklMRVMgPSAxOwogICAgY29uc3QgT05MWV9ESVJFQ1RPUklFUyA9IDI7CgogICAgcHJpdmF0ZSAkbW9kZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBcSXRlcmF0b3IgJGl0ZXJhdG9yIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgJG1vZGUgICAgIFRoZSBtb2RlIChzZWxmOjpPTkxZX0ZJTEVTIG9yIHNlbGY6Ok9OTFlfRElSRUNUT1JJRVMpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCAkbW9kZSkKICAgIHsKICAgICAgICAkdGhpcy0+bW9kZSA9ICRtb2RlOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgJGZpbGVpbmZvID0gJHRoaXMtPmN1cnJlbnQoKTsKICAgICAgICBpZiAoc2VsZjo6T05MWV9ESVJFQ1RPUklFUyA9PT0gKHNlbGY6Ok9OTFlfRElSRUNUT1JJRVMgJiAkdGhpcy0+bW9kZSkgJiYgJGZpbGVpbmZvLT5pc0ZpbGUoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6Ok9OTFlfRklMRVMgPT09IChzZWxmOjpPTkxZX0ZJTEVTICYgJHRoaXMtPm1vZGUpICYmICRmaWxlaW5mby0+aXNEaXIoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcQ29tcGFyYXRvclxEYXRlQ29tcGFyYXRvcjsKCi8qKgogKiBEYXRlUmFuZ2VGaWx0ZXJJdGVyYXRvciBmaWx0ZXJzIG91dCBmaWxlcyB0aGF0IGFyZSBub3QgaW4gdGhlIGdpdmVuIGRhdGUgcmFuZ2UgKGxhc3QgbW9kaWZpZWQgZGF0ZXMpLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIERhdGVSYW5nZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJpdmF0ZSAkY29tcGFyYXRvcnMgPSBbXTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBcSXRlcmF0b3IgICAgICAgICRpdGVyYXRvciAgICBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gRGF0ZUNvbXBhcmF0b3JbXSAkY29tcGFyYXRvcnMgQW4gYXJyYXkgb2YgRGF0ZUNvbXBhcmF0b3IgaW5zdGFuY2VzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkY29tcGFyYXRvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbXBhcmF0b3JzID0gJGNvbXBhcmF0b3JzOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgJGZpbGVpbmZvID0gJHRoaXMtPmN1cnJlbnQoKTsKCiAgICAgICAgaWYgKCFmaWxlX2V4aXN0cygkZmlsZWluZm8tPmdldFBhdGhuYW1lKCkpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRmaWxlZGF0ZSA9ICRmaWxlaW5mby0+Z2V0TVRpbWUoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y29tcGFyYXRvcnMgYXMgJGNvbXBhcmUpIHsKICAgICAgICAgICAgaWYgKCEkY29tcGFyZS0+dGVzdCgkZmlsZWRhdGUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxFeGNlcHRpb25cQWNjZXNzRGVuaWVkRXhjZXB0aW9uOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXFNwbEZpbGVJbmZvOwoKLyoqCiAqIEV4dGVuZHMgdGhlIFxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvciB0byBzdXBwb3J0IHJlbGF0aXZlIHBhdGhzLgogKgogKiBAYXV0aG9yIFZpY3RvciBCZXJjaGV0IDx2aWN0b3JAc3V1bWl0LmNvbT4KICovCmNsYXNzIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yIGV4dGVuZHMgXFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yCnsKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJGlnbm9yZVVucmVhZGFibGVEaXJzOwoKICAgIC8qKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByaXZhdGUgJHJld2luZGFibGU7CgogICAgLy8gdGhlc2UgMyBwcm9wZXJ0aWVzIHRha2UgcGFydCBvZiB0aGUgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIHRvIGF2b2lkIHJlZG9pbmcgdGhlIHNhbWUgd29yayBpbiBhbGwgaXRlcmF0aW9ucwogICAgcHJpdmF0ZSAkcm9vdFBhdGg7CiAgICBwcml2YXRlICRzdWJQYXRoOwogICAgcHJpdmF0ZSAkZGlyZWN0b3J5U2VwYXJhdG9yID0gJy8nOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICogQHBhcmFtIGludCAgICAkZmxhZ3MKICAgICAqIEBwYXJhbSBib29sICAgJGlnbm9yZVVucmVhZGFibGVEaXJzCiAgICAgKgogICAgICogQHRocm93cyBcUnVudGltZUV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHBhdGgsICRmbGFncywgJGlnbm9yZVVucmVhZGFibGVEaXJzID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRmbGFncyAmIChzZWxmOjpDVVJSRU5UX0FTX1BBVEhOQU1FIHwgc2VsZjo6Q1VSUkVOVF9BU19TRUxGKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoaXMgaXRlcmF0b3Igb25seSBzdXBwb3J0IHJldHVybmluZyBjdXJyZW50IGFzIGZpbGVpbmZvLicpOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkcGF0aCwgJGZsYWdzKTsKICAgICAgICAkdGhpcy0+aWdub3JlVW5yZWFkYWJsZURpcnMgPSAkaWdub3JlVW5yZWFkYWJsZURpcnM7CiAgICAgICAgJHRoaXMtPnJvb3RQYXRoID0gJHBhdGg7CiAgICAgICAgaWYgKCcvJyAhPT0gXERJUkVDVE9SWV9TRVBBUkFUT1IgJiYgISgkZmxhZ3MgJiBzZWxmOjpVTklYX1BBVEhTKSkgewogICAgICAgICAgICAkdGhpcy0+ZGlyZWN0b3J5U2VwYXJhdG9yID0gXERJUkVDVE9SWV9TRVBBUkFUT1I7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIFNwbEZpbGVJbmZvIHdpdGggc3VwcG9ydCBmb3IgcmVsYXRpdmUgcGF0aHMuCiAgICAgKgogICAgICogQHJldHVybiBTcGxGaWxlSW5mbyBGaWxlIGluZm9ybWF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjdXJyZW50KCkKICAgIHsKICAgICAgICAvLyB0aGUgbG9naWMgaGVyZSBhdm9pZHMgcmVkb2luZyB0aGUgc2FtZSB3b3JrIGluIGFsbCBpdGVyYXRpb25zCgogICAgICAgIGlmIChudWxsID09PSAkc3ViUGF0aG5hbWUgPSAkdGhpcy0+c3ViUGF0aCkgewogICAgICAgICAgICAkc3ViUGF0aG5hbWUgPSAkdGhpcy0+c3ViUGF0aCA9IChzdHJpbmcpICR0aGlzLT5nZXRTdWJQYXRoKCk7CiAgICAgICAgfQogICAgICAgIGlmICgnJyAhPT0gJHN1YlBhdGhuYW1lKSB7CiAgICAgICAgICAgICRzdWJQYXRobmFtZSAuPSAkdGhpcy0+ZGlyZWN0b3J5U2VwYXJhdG9yOwogICAgICAgIH0KICAgICAgICAkc3ViUGF0aG5hbWUgLj0gJHRoaXMtPmdldEZpbGVuYW1lKCk7CgogICAgICAgIGlmICgnLycgIT09ICRiYXNlUGF0aCA9ICR0aGlzLT5yb290UGF0aCkgewogICAgICAgICAgICAkYmFzZVBhdGggLj0gJHRoaXMtPmRpcmVjdG9yeVNlcGFyYXRvcjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgU3BsRmlsZUluZm8oJGJhc2VQYXRoLiRzdWJQYXRobmFtZSwgJHRoaXMtPnN1YlBhdGgsICRzdWJQYXRobmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFxSZWN1cnNpdmVJdGVyYXRvcgogICAgICoKICAgICAqIEB0aHJvd3MgQWNjZXNzRGVuaWVkRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGlsZHJlbigpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGNoaWxkcmVuID0gcGFyZW50OjpnZXRDaGlsZHJlbigpOwoKICAgICAgICAgICAgaWYgKCRjaGlsZHJlbiBpbnN0YW5jZW9mIHNlbGYpIHsKICAgICAgICAgICAgICAgIC8vIHBhcmVudCBtZXRob2Qgd2lsbCBjYWxsIHRoZSBjb25zdHJ1Y3RvciB3aXRoIGRlZmF1bHQgYXJndW1lbnRzLCBzbyB1bnJlYWRhYmxlIGRpcnMgd29uJ3QgYmUgaWdub3JlZCBhbnltb3JlCiAgICAgICAgICAgICAgICAkY2hpbGRyZW4tPmlnbm9yZVVucmVhZGFibGVEaXJzID0gJHRoaXMtPmlnbm9yZVVucmVhZGFibGVEaXJzOwoKICAgICAgICAgICAgICAgIC8vIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiB0byBhdm9pZCByZWRvaW5nIHRoZSBzYW1lIHdvcmsgaW4gYWxsIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAkY2hpbGRyZW4tPnJld2luZGFibGUgPSAmJHRoaXMtPnJld2luZGFibGU7CiAgICAgICAgICAgICAgICAkY2hpbGRyZW4tPnJvb3RQYXRoID0gJHRoaXMtPnJvb3RQYXRoOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGNoaWxkcmVuOwogICAgICAgIH0gY2F0Y2ggKFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5pZ25vcmVVbnJlYWRhYmxlRGlycykgewogICAgICAgICAgICAgICAgLy8gSWYgZGlyZWN0b3J5IGlzIHVucmVhZGFibGUgYW5kIGZpbmRlciBpcyBzZXQgdG8gaWdub3JlIGl0LCBhIGZha2UgZW1wdHkgY29udGVudCBpcyByZXR1cm5lZC4KICAgICAgICAgICAgICAgIHJldHVybiBuZXcgXFJlY3Vyc2l2ZUFycmF5SXRlcmF0b3IoW10pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFjY2Vzc0RlbmllZEV4Y2VwdGlvbigkZS0+Z2V0TWVzc2FnZSgpLCAkZS0+Z2V0Q29kZSgpLCAkZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEbyBub3RoaW5nIGZvciBub24gcmV3aW5kYWJsZSBzdHJlYW0uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKQogICAgewogICAgICAgIGlmIChmYWxzZSA9PT0gJHRoaXMtPmlzUmV3aW5kYWJsZSgpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIEBzZWUgaHR0cHM6Ly9idWdzLnBocC5uZXQvNjg1NTcKICAgICAgICBpZiAoXFBIUF9WRVJTSU9OX0lEIDwgNTA1MjMgfHwgXFBIUF9WRVJTSU9OX0lEID49IDUwNjAwICYmIFxQSFBfVkVSU0lPTl9JRCA8IDUwNjA3KSB7CiAgICAgICAgICAgIHBhcmVudDo6bmV4dCgpOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpyZXdpbmQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgc3RyZWFtIGlzIHJld2luZGFibGUuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgd2hlbiB0aGUgc3RyZWFtIGlzIHJld2luZGFibGUsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSZXdpbmRhYmxlKCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnJld2luZGFibGUpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXdpbmRhYmxlOwogICAgICAgIH0KCiAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgYW4gSEhWTSBidWcsIHNob3VsZCBiZSByZW1vdmVkIHdoZW4gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2hodm0vaXNzdWVzLzcyODEgaXMgZml4ZWQKICAgICAgICBpZiAoJycgPT09ICR0aGlzLT5nZXRQYXRoKCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXdpbmRhYmxlID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmFsc2UgIT09ICRzdHJlYW0gPSBAb3BlbmRpcigkdGhpcy0+Z2V0UGF0aCgpKSkgewogICAgICAgICAgICAkaW5mb3MgPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkc3RyZWFtKTsKICAgICAgICAgICAgY2xvc2VkaXIoJHN0cmVhbSk7CgogICAgICAgICAgICBpZiAoJGluZm9zWydzZWVrYWJsZSddKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJld2luZGFibGUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnJld2luZGFibGUgPSBmYWxzZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCi8qKgogKiBEZXB0aFJhbmdlRmlsdGVySXRlcmF0b3IgbGltaXRzIHRoZSBkaXJlY3RvcnkgZGVwdGguCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgRGVwdGhSYW5nZUZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgRmlsdGVySXRlcmF0b3IKewogICAgcHJpdmF0ZSAkbWluRGVwdGggPSAwOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yICRpdGVyYXRvciBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICAgICAgICAgJG1pbkRlcHRoIFRoZSBtaW4gZGVwdGgKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAkbWF4RGVwdGggVGhlIG1heCBkZXB0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IgJGl0ZXJhdG9yLCAkbWluRGVwdGggPSAwLCAkbWF4RGVwdGggPSBcUEhQX0lOVF9NQVgpCiAgICB7CiAgICAgICAgJHRoaXMtPm1pbkRlcHRoID0gJG1pbkRlcHRoOwogICAgICAgICRpdGVyYXRvci0+c2V0TWF4RGVwdGgoXFBIUF9JTlRfTUFYID09PSAkbWF4RGVwdGggPyAtMSA6ICRtYXhEZXB0aCk7CgogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJGl0ZXJhdG9yKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldElubmVySXRlcmF0b3IoKS0+Z2V0RGVwdGgoKSA+PSAkdGhpcy0+bWluRGVwdGg7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3I7CgovKioKICogQ3VzdG9tRmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSBhcHBseWluZyBhbm9ueW1vdXMgZnVuY3Rpb25zLgogKgogKiBUaGUgYW5vbnltb3VzIGZ1bmN0aW9uIHJlY2VpdmVzIGEgXFNwbEZpbGVJbmZvIGFuZCBtdXN0IHJldHVybiBmYWxzZQogKiB0byByZW1vdmUgZmlsZXMuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgQ3VzdG9tRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBGaWx0ZXJJdGVyYXRvcgp7CiAgICBwcml2YXRlICRmaWx0ZXJzID0gW107CgogICAgLyoqCiAgICAgKiBAcGFyYW0gXEl0ZXJhdG9yICAkaXRlcmF0b3IgVGhlIEl0ZXJhdG9yIHRvIGZpbHRlcgogICAgICogQHBhcmFtIGNhbGxhYmxlW10gJGZpbHRlcnMgIEFuIGFycmF5IG9mIFBIUCBjYWxsYmFja3MKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KFxJdGVyYXRvciAkaXRlcmF0b3IsIGFycmF5ICRmaWx0ZXJzKQogICAgewogICAgICAgIGZvcmVhY2ggKCRmaWx0ZXJzIGFzICRmaWx0ZXIpIHsKICAgICAgICAgICAgaWYgKCFcaXNfY2FsbGFibGUoJGZpbHRlcikpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIFBIUCBjYWxsYmFjay4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+ZmlsdGVycyA9ICRmaWx0ZXJzOwoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIHRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgJGZpbGVpbmZvID0gJHRoaXMtPmN1cnJlbnQoKTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbHRlcnMgYXMgJGZpbHRlcikgewogICAgICAgICAgICBpZiAoZmFsc2UgPT09IFxjYWxsX3VzZXJfZnVuYygkZmlsdGVyLCAkZmlsZWluZm8pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSB0aGVpciBjb250ZW50cyB1c2luZyBwYXR0ZXJucyAocmVnZXhwcyBvciBzdHJpbmdzKS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyICA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKiBAYXV0aG9yIFfFgm9kemltaWVyeiBHYWpkYSA8Z2FqZGF3QGdhamRhdy5wbD4KICovCmNsYXNzIEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBNdWx0aXBsZVBjcmVGaWx0ZXJJdGVyYXRvcgp7CiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5tYXRjaFJlZ2V4cHMgJiYgISR0aGlzLT5ub01hdGNoUmVnZXhwcykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgICRmaWxlaW5mbyA9ICR0aGlzLT5jdXJyZW50KCk7CgogICAgICAgIGlmICgkZmlsZWluZm8tPmlzRGlyKCkgfHwgISRmaWxlaW5mby0+aXNSZWFkYWJsZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRjb250ZW50ID0gJGZpbGVpbmZvLT5nZXRDb250ZW50cygpOwogICAgICAgIGlmICghJGNvbnRlbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0FjY2VwdGVkKCRjb250ZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIHN0cmluZyB0byByZWdleHAgaWYgbmVjZXNzYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBQYXR0ZXJuOiBzdHJpbmcgb3IgcmVnZXhwCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBzdHJpbmcgb3IgcmVnZXhwCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB0b1JlZ2V4KCRzdHIpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1JlZ2V4KCRzdHIpID8gJHN0ciA6ICcvJy5wcmVnX3F1b3RlKCRzdHIsICcvJykuJy8nOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIEV4Y2x1ZGVEaXJlY3RvcnlGaWx0ZXJJdGVyYXRvciBmaWx0ZXJzIG91dCBkaXJlY3Rvcmllcy4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBFeGNsdWRlRGlyZWN0b3J5RmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBGaWx0ZXJJdGVyYXRvciBpbXBsZW1lbnRzIFxSZWN1cnNpdmVJdGVyYXRvcgp7CiAgICBwcml2YXRlICRpdGVyYXRvcjsKICAgIHByaXZhdGUgJGlzUmVjdXJzaXZlOwogICAgcHJpdmF0ZSAkZXhjbHVkZWREaXJzID0gW107CiAgICBwcml2YXRlICRleGNsdWRlZFBhdHRlcm47CgogICAgLyoqCiAgICAgKiBAcGFyYW0gXEl0ZXJhdG9yICRpdGVyYXRvciAgICBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gICRkaXJlY3RvcmllcyBBbiBhcnJheSBvZiBkaXJlY3RvcmllcyB0byBleGNsdWRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkZGlyZWN0b3JpZXMpCiAgICB7CiAgICAgICAgJHRoaXMtPml0ZXJhdG9yID0gJGl0ZXJhdG9yOwogICAgICAgICR0aGlzLT5pc1JlY3Vyc2l2ZSA9ICRpdGVyYXRvciBpbnN0YW5jZW9mIFxSZWN1cnNpdmVJdGVyYXRvcjsKICAgICAgICAkcGF0dGVybnMgPSBbXTsKICAgICAgICBmb3JlYWNoICgkZGlyZWN0b3JpZXMgYXMgJGRpcmVjdG9yeSkgewogICAgICAgICAgICAkZGlyZWN0b3J5ID0gcnRyaW0oJGRpcmVjdG9yeSwgJy8nKTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+aXNSZWN1cnNpdmUgfHwgZmFsc2UgIT09IHN0cnBvcygkZGlyZWN0b3J5LCAnLycpKSB7CiAgICAgICAgICAgICAgICAkcGF0dGVybnNbXSA9IHByZWdfcXVvdGUoJGRpcmVjdG9yeSwgJyMnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5leGNsdWRlZERpcnNbJGRpcmVjdG9yeV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkcGF0dGVybnMpIHsKICAgICAgICAgICAgJHRoaXMtPmV4Y2x1ZGVkUGF0dGVybiA9ICcjKD86XnwvKSg/OicuaW1wbG9kZSgnfCcsICRwYXR0ZXJucykuJykoPzovfCQpIyc7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRpdGVyYXRvcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB2YWx1ZXMuCiAgICAgKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBrZXB0LCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFjY2VwdCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pc1JlY3Vyc2l2ZSAmJiBpc3NldCgkdGhpcy0+ZXhjbHVkZWREaXJzWyR0aGlzLT5nZXRGaWxlbmFtZSgpXSkgJiYgJHRoaXMtPmlzRGlyKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5leGNsdWRlZFBhdHRlcm4pIHsKICAgICAgICAgICAgJHBhdGggPSAkdGhpcy0+aXNEaXIoKSA/ICR0aGlzLT5jdXJyZW50KCktPmdldFJlbGF0aXZlUGF0aG5hbWUoKSA6ICR0aGlzLT5jdXJyZW50KCktPmdldFJlbGF0aXZlUGF0aCgpOwogICAgICAgICAgICAkcGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJHBhdGgpOwoKICAgICAgICAgICAgcmV0dXJuICFwcmVnX21hdGNoKCR0aGlzLT5leGNsdWRlZFBhdHRlcm4sICRwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNDaGlsZHJlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc1JlY3Vyc2l2ZSAmJiAkdGhpcy0+aXRlcmF0b3ItPmhhc0NoaWxkcmVuKCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENoaWxkcmVuKCkKICAgIHsKICAgICAgICAkY2hpbGRyZW4gPSBuZXcgc2VsZigkdGhpcy0+aXRlcmF0b3ItPmdldENoaWxkcmVuKCksIFtdKTsKICAgICAgICAkY2hpbGRyZW4tPmV4Y2x1ZGVkRGlycyA9ICR0aGlzLT5leGNsdWRlZERpcnM7CiAgICAgICAgJGNoaWxkcmVuLT5leGNsdWRlZFBhdHRlcm4gPSAkdGhpcy0+ZXhjbHVkZWRQYXR0ZXJuOwoKICAgICAgICByZXR1cm4gJGNoaWxkcmVuOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxHbG9iOwoKLyoqCiAqIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyBieSBwYXR0ZXJucyAoYSByZWdleHAsIGEgZ2xvYiwgb3IgYSBzdHJpbmcpLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBNdWx0aXBsZVBjcmVGaWx0ZXJJdGVyYXRvcgp7CiAgICAvKioKICAgICAqIEZpbHRlcnMgdGhlIGl0ZXJhdG9yIHZhbHVlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgdHJ1ZSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIGtlcHQsIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWNjZXB0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlzQWNjZXB0ZWQoJHRoaXMtPmN1cnJlbnQoKS0+Z2V0RmlsZW5hbWUoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBnbG9iIHRvIHJlZ2V4cC4KICAgICAqCiAgICAgKiBQQ1JFIHBhdHRlcm5zIGFyZSBsZWZ0IHVuY2hhbmdlZC4KICAgICAqIEdsb2Igc3RyaW5ncyBhcmUgdHJhbnNmb3JtZWQgd2l0aCBHbG9iOjp0b1JlZ2V4KCkuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyIFBhdHRlcm46IGdsb2Igb3IgcmVnZXhwCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgcmVnZXhwIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBnbG9iIG9yIHJlZ2V4cAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9SZWdleCgkc3RyKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aXNSZWdleCgkc3RyKSA/ICRzdHIgOiBHbG9iOjp0b1JlZ2V4KCRzdHIpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yOwoKLyoqCiAqIFNvcnRhYmxlSXRlcmF0b3IgYXBwbGllcyBhIHNvcnQgb24gYSBnaXZlbiBJdGVyYXRvci4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBTb3J0YWJsZUl0ZXJhdG9yIGltcGxlbWVudHMgXEl0ZXJhdG9yQWdncmVnYXRlCnsKICAgIGNvbnN0IFNPUlRfQllfTkFNRSA9IDE7CiAgICBjb25zdCBTT1JUX0JZX1RZUEUgPSAyOwogICAgY29uc3QgU09SVF9CWV9BQ0NFU1NFRF9USU1FID0gMzsKICAgIGNvbnN0IFNPUlRfQllfQ0hBTkdFRF9USU1FID0gNDsKICAgIGNvbnN0IFNPUlRfQllfTU9ESUZJRURfVElNRSA9IDU7CgogICAgcHJpdmF0ZSAkaXRlcmF0b3I7CiAgICBwcml2YXRlICRzb3J0OwoKICAgIC8qKgogICAgICogQHBhcmFtIFxUcmF2ZXJzYWJsZSAkaXRlcmF0b3IgVGhlIEl0ZXJhdG9yIHRvIGZpbHRlcgogICAgICogQHBhcmFtIGludHxjYWxsYWJsZSAkc29ydCAgICAgVGhlIHNvcnQgdHlwZSAoU09SVF9CWV9OQU1FLCBTT1JUX0JZX1RZUEUsIG9yIGEgUEhQIGNhbGxiYWNrKQogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoXFRyYXZlcnNhYmxlICRpdGVyYXRvciwgJHNvcnQpCiAgICB7CiAgICAgICAgJHRoaXMtPml0ZXJhdG9yID0gJGl0ZXJhdG9yOwoKICAgICAgICBpZiAoc2VsZjo6U09SVF9CWV9OQU1FID09PSAkc29ydCkgewogICAgICAgICAgICAkdGhpcy0+c29ydCA9IHN0YXRpYyBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhLT5nZXRSZWFsUGF0aCgpID86ICRhLT5nZXRQYXRobmFtZSgpLCAkYi0+Z2V0UmVhbFBhdGgoKSA/OiAkYi0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6OlNPUlRfQllfVFlQRSA9PT0gJHNvcnQpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSBzdGF0aWMgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICAgICAgaWYgKCRhLT5pc0RpcigpICYmICRiLT5pc0ZpbGUoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkYS0+aXNGaWxlKCkgJiYgJGItPmlzRGlyKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhLT5nZXRSZWFsUGF0aCgpID86ICRhLT5nZXRQYXRobmFtZSgpLCAkYi0+Z2V0UmVhbFBhdGgoKSA/OiAkYi0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6OlNPUlRfQllfQUNDRVNTRURfVElNRSA9PT0gJHNvcnQpIHsKICAgICAgICAgICAgJHRoaXMtPnNvcnQgPSBzdGF0aWMgZnVuY3Rpb24gKCRhLCAkYikgewogICAgICAgICAgICAgICAgcmV0dXJuICRhLT5nZXRBVGltZSgpIC0gJGItPmdldEFUaW1lKCk7CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlaWYgKHNlbGY6OlNPUlRfQllfQ0hBTkdFRF9USU1FID09PSAkc29ydCkgewogICAgICAgICAgICAkdGhpcy0+c29ydCA9IHN0YXRpYyBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGEtPmdldENUaW1lKCkgLSAkYi0+Z2V0Q1RpbWUoKTsKICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2VpZiAoc2VsZjo6U09SVF9CWV9NT0RJRklFRF9USU1FID09PSAkc29ydCkgewogICAgICAgICAgICAkdGhpcy0+c29ydCA9IHN0YXRpYyBmdW5jdGlvbiAoJGEsICRiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGEtPmdldE1UaW1lKCkgLSAkYi0+Z2V0TVRpbWUoKTsKICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2VpZiAoXGlzX2NhbGxhYmxlKCRzb3J0KSkgewogICAgICAgICAgICAkdGhpcy0+c29ydCA9ICRzb3J0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGUgU29ydGFibGVJdGVyYXRvciB0YWtlcyBhIFBIUCBjYWxsYWJsZSBvciBhIHZhbGlkIGJ1aWx0LWluIHNvcnQgYWxnb3JpdGhtIGFzIGFuIGFyZ3VtZW50LicpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKQogICAgewogICAgICAgICRhcnJheSA9IGl0ZXJhdG9yX3RvX2FycmF5KCR0aGlzLT5pdGVyYXRvciwgdHJ1ZSk7CiAgICAgICAgdWFzb3J0KCRhcnJheSwgJHRoaXMtPnNvcnQpOwoKICAgICAgICByZXR1cm4gbmV3IFxBcnJheUl0ZXJhdG9yKCRhcnJheSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3I7CgovKioKICogTXVsdGlwbGVQY3JlRmlsdGVySXRlcmF0b3IgZmlsdGVycyBmaWxlcyB1c2luZyBwYXR0ZXJucyAocmVnZXhwcywgZ2xvYnMgb3Igc3RyaW5ncykuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgTXVsdGlwbGVQY3JlRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBGaWx0ZXJJdGVyYXRvcgp7CiAgICBwcm90ZWN0ZWQgJG1hdGNoUmVnZXhwcyA9IFtdOwogICAgcHJvdGVjdGVkICRub01hdGNoUmVnZXhwcyA9IFtdOwoKICAgIC8qKgogICAgICogQHBhcmFtIFxJdGVyYXRvciAkaXRlcmF0b3IgICAgICAgIFRoZSBJdGVyYXRvciB0byBmaWx0ZXIKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJG1hdGNoUGF0dGVybnMgICBBbiBhcnJheSBvZiBwYXR0ZXJucyB0aGF0IG5lZWQgdG8gbWF0Y2gKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJG5vTWF0Y2hQYXR0ZXJucyBBbiBhcnJheSBvZiBwYXR0ZXJucyB0aGF0IG5lZWQgdG8gbm90IG1hdGNoCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChcSXRlcmF0b3IgJGl0ZXJhdG9yLCBhcnJheSAkbWF0Y2hQYXR0ZXJucywgYXJyYXkgJG5vTWF0Y2hQYXR0ZXJucykKICAgIHsKICAgICAgICBmb3JlYWNoICgkbWF0Y2hQYXR0ZXJucyBhcyAkcGF0dGVybikgewogICAgICAgICAgICAkdGhpcy0+bWF0Y2hSZWdleHBzW10gPSAkdGhpcy0+dG9SZWdleCgkcGF0dGVybik7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkbm9NYXRjaFBhdHRlcm5zIGFzICRwYXR0ZXJuKSB7CiAgICAgICAgICAgICR0aGlzLT5ub01hdGNoUmVnZXhwc1tdID0gJHRoaXMtPnRvUmVnZXgoJHBhdHRlcm4pOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaXRlcmF0b3IpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHN0cmluZyBpcyBhY2NlcHRlZCBieSB0aGUgcmVnZXggZmlsdGVycy4KICAgICAqCiAgICAgKiBJZiB0aGVyZSBpcyBubyByZWdleHBzIGRlZmluZWQgaW4gdGhlIGNsYXNzLCB0aGlzIG1ldGhvZCB3aWxsIGFjY2VwdCB0aGUgc3RyaW5nLgogICAgICogU3VjaCBjYXNlIGNhbiBiZSBoYW5kbGVkIGJ5IGNoaWxkIGNsYXNzZXMgYmVmb3JlIGNhbGxpbmcgdGhlIG1ldGhvZCBpZiB0aGV5IHdhbnQgdG8KICAgICAqIGFwcGx5IGEgZGlmZmVyZW50IGJlaGF2aW9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGJlIG1hdGNoZWQgYWdhaW5zdCBmaWx0ZXJzCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpc0FjY2VwdGVkKCRzdHJpbmcpCiAgICB7CiAgICAgICAgLy8gc2hvdWxkIGF0IGxlYXN0IG5vdCBtYXRjaCBvbmUgcnVsZSB0byBleGNsdWRlCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5vTWF0Y2hSZWdleHBzIGFzICRyZWdleCkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcmVnZXgsICRzdHJpbmcpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHNob3VsZCBhdCBsZWFzdCBtYXRjaCBvbmUgcnVsZQogICAgICAgIGlmICgkdGhpcy0+bWF0Y2hSZWdleHBzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5tYXRjaFJlZ2V4cHMgYXMgJHJlZ2V4KSB7CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkcmVnZXgsICRzdHJpbmcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIG1hdGNoIHJ1bGVzLCB0aGUgZmlsZSBpcyBhY2NlcHRlZAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHN0cmluZyBpcyBhIHJlZ2V4LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYSByZWdleAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNSZWdleCgkc3RyKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXiguezMsfT8pW2ltc3h1QURVXSokLycsICRzdHIsICRtKSkgewogICAgICAgICAgICAkc3RhcnQgPSBzdWJzdHIoJG1bMV0sIDAsIDEpOwogICAgICAgICAgICAkZW5kID0gc3Vic3RyKCRtWzFdLCAtMSk7CgogICAgICAgICAgICBpZiAoJHN0YXJ0ID09PSAkZW5kKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIXByZWdfbWF0Y2goJy9bKj9bOmFsbnVtOl0gXFxcXF0vJywgJHN0YXJ0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yZWFjaCAoW1sneycsICd9J10sIFsnKCcsICcpJ10sIFsnWycsICddJ10sIFsnPCcsICc+J11dIGFzICRkZWxpbWl0ZXJzKSB7CiAgICAgICAgICAgICAgICBpZiAoJHN0YXJ0ID09PSAkZGVsaW1pdGVyc1swXSAmJiAkZW5kID09PSAkZGVsaW1pdGVyc1sxXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBzdHJpbmcgaW50byByZWdleHAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyIFBhdHRlcm4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyByZWdleHAgY29ycmVzcG9uZGluZyB0byBhIGdpdmVuIHN0cmluZwogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gdG9SZWdleCgkc3RyKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCi8qKgogKiBUaGlzIGl0ZXJhdG9yIGp1c3Qgb3ZlcnJpZGVzIHRoZSByZXdpbmQgbWV0aG9kIGluIG9yZGVyIHRvIGNvcnJlY3QgYSBQSFAgYnVnLAogKiB3aGljaCBleGlzdGVkIGJlZm9yZSB2ZXJzaW9uIDUuNS4yMy81LjYuNy4KICoKICogQHNlZSBodHRwczovL2J1Z3MucGhwLm5ldC82ODU1NwogKgogKiBAYXV0aG9yIEFsZXggQm9nb21hem92CiAqCiAqIEBkZXByZWNhdGVkIHNpbmNlIDMuNCwgdG8gYmUgcmVtb3ZlZCBpbiA0LjAuCiAqLwphYnN0cmFjdCBjbGFzcyBGaWx0ZXJJdGVyYXRvciBleHRlbmRzIFxGaWx0ZXJJdGVyYXRvcgp7CiAgICAvKioKICAgICAqIFRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciB0aGUgcHJvYmxlbSB3aXRoIFxGaWx0ZXJJdGVyYXRvciBsZWF2aW5nIGlubmVyIFxGaWxlc3lzdGVtSXRlcmF0b3IgaW4gd3Jvbmcgc3RhdGUgYWZ0ZXIKICAgICAqIHJld2luZCBpbiBzb21lIGNhc2VzLgogICAgICoKICAgICAqIEBzZWUgRmlsdGVySXRlcmF0b3I6OnJld2luZCgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKQogICAgewogICAgICAgIGlmIChcUEhQX1ZFUlNJT05fSUQgPiA1MDYwNyB8fCAoXFBIUF9WRVJTSU9OX0lEID4gNTA1MjMgJiYgXFBIUF9WRVJTSU9OX0lEIDwgNTA2MDApKSB7CiAgICAgICAgICAgIHBhcmVudDo6cmV3aW5kKCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkaXRlcmF0b3IgPSAkdGhpczsKICAgICAgICB3aGlsZSAoJGl0ZXJhdG9yIGluc3RhbmNlb2YgXE91dGVySXRlcmF0b3IpIHsKICAgICAgICAgICAgJGlubmVySXRlcmF0b3IgPSAkaXRlcmF0b3ItPmdldElubmVySXRlcmF0b3IoKTsKCiAgICAgICAgICAgIGlmICgkaW5uZXJJdGVyYXRvciBpbnN0YW5jZW9mIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAvLyB0aGlzIGNvbmRpdGlvbiBpcyBuZWNlc3NhcnkgZm9yIGl0ZXJhdG9ycyB0byB3b3JrIHByb3Blcmx5IHdpdGggbm9uLWxvY2FsIGZpbGVzeXN0ZW1zIGxpa2UgZnRwCiAgICAgICAgICAgICAgICBpZiAoJGlubmVySXRlcmF0b3ItPmlzUmV3aW5kYWJsZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGlubmVySXRlcmF0b3ItPm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAkaW5uZXJJdGVyYXRvci0+cmV3aW5kKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgkaW5uZXJJdGVyYXRvciBpbnN0YW5jZW9mIFxGaWxlc3lzdGVtSXRlcmF0b3IpIHsKICAgICAgICAgICAgICAgICRpbm5lckl0ZXJhdG9yLT5uZXh0KCk7CiAgICAgICAgICAgICAgICAkaW5uZXJJdGVyYXRvci0+cmV3aW5kKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpdGVyYXRvciA9ICRpbm5lckl0ZXJhdG9yOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpyZXdpbmQoKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvcjsKCnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcQ29tcGFyYXRvclxOdW1iZXJDb21wYXJhdG9yOwoKLyoqCiAqIFNpemVSYW5nZUZpbHRlckl0ZXJhdG9yIGZpbHRlcnMgb3V0IGZpbGVzIHRoYXQgYXJlIG5vdCBpbiB0aGUgZ2l2ZW4gc2l6ZSByYW5nZS4KICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBTaXplUmFuZ2VGaWx0ZXJJdGVyYXRvciBleHRlbmRzIEZpbHRlckl0ZXJhdG9yCnsKICAgIHByaXZhdGUgJGNvbXBhcmF0b3JzID0gW107CgogICAgLyoqCiAgICAgKiBAcGFyYW0gXEl0ZXJhdG9yICAgICAgICAgICRpdGVyYXRvciAgICBUaGUgSXRlcmF0b3IgdG8gZmlsdGVyCiAgICAgKiBAcGFyYW0gTnVtYmVyQ29tcGFyYXRvcltdICRjb21wYXJhdG9ycyBBbiBhcnJheSBvZiBOdW1iZXJDb21wYXJhdG9yIGluc3RhbmNlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoXEl0ZXJhdG9yICRpdGVyYXRvciwgYXJyYXkgJGNvbXBhcmF0b3JzKQogICAgewogICAgICAgICR0aGlzLT5jb21wYXJhdG9ycyA9ICRjb21wYXJhdG9yczsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaXRlcmF0b3IpOwogICAgfQoKICAgIC8qKgogICAgICogRmlsdGVycyB0aGUgaXRlcmF0b3IgdmFsdWVzLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCB0cnVlIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUga2VwdCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhY2NlcHQoKQogICAgewogICAgICAgICRmaWxlaW5mbyA9ICR0aGlzLT5jdXJyZW50KCk7CiAgICAgICAgaWYgKCEkZmlsZWluZm8tPmlzRmlsZSgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJGZpbGVzaXplID0gJGZpbGVpbmZvLT5nZXRTaXplKCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbXBhcmF0b3JzIGFzICRjb21wYXJlKSB7CiAgICAgICAgICAgIGlmICghJGNvbXBhcmUtPnRlc3QoJGZpbGVzaXplKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFN5bWZvbnkgcGFja2FnZS4KICoKICogKGMpIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yOwoKLyoqCiAqIENvbXBhcmF0b3IuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgQ29tcGFyYXRvcgp7CiAgICBwcml2YXRlICR0YXJnZXQ7CiAgICBwcml2YXRlICRvcGVyYXRvciA9ICc9PSc7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0YXJnZXQgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIHRhcmdldCB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFyZ2V0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRhcmdldDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRhcmdldCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YXJnZXQgVGhlIHRhcmdldCB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGFyZ2V0KCR0YXJnZXQpCiAgICB7CiAgICAgICAgJHRoaXMtPnRhcmdldCA9ICR0YXJnZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb21wYXJpc29uIG9wZXJhdG9yLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBvcGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb21wYXJpc29uIG9wZXJhdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIEEgdmFsaWQgb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wZXJhdG9yKCRvcGVyYXRvcikKICAgIHsKICAgICAgICBpZiAoISRvcGVyYXRvcikgewogICAgICAgICAgICAkb3BlcmF0b3IgPSAnPT0nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFcaW5fYXJyYXkoJG9wZXJhdG9yLCBbJz4nLCAnPCcsICc+PScsICc8PScsICc9PScsICchPSddKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdJbnZhbGlkIG9wZXJhdG9yICIlcyIuJywgJG9wZXJhdG9yKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSAkb3BlcmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZXN0cyBhZ2FpbnN0IHRoZSB0YXJnZXQuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICR0ZXN0IEEgdGVzdCB2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdGVzdCgkdGVzdCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBjYXNlICc+JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGVzdCA+ICR0aGlzLT50YXJnZXQ7CiAgICAgICAgICAgIGNhc2UgJz49JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGVzdCA+PSAkdGhpcy0+dGFyZ2V0OwogICAgICAgICAgICBjYXNlICc8JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGVzdCA8ICR0aGlzLT50YXJnZXQ7CiAgICAgICAgICAgIGNhc2UgJzw9JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGVzdCA8PSAkdGhpcy0+dGFyZ2V0OwogICAgICAgICAgICBjYXNlICchPSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRlc3QgIT0gJHRoaXMtPnRhcmdldDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGVzdCA9PSAkdGhpcy0+dGFyZ2V0OwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXENvbXBhcmF0b3I7CgovKioKICogTnVtYmVyQ29tcGFyYXRvciBjb21waWxlcyBhIHNpbXBsZSBjb21wYXJpc29uIHRvIGFuIGFub255bW91cwogKiBzdWJyb3V0aW5lLCB3aGljaCB5b3UgY2FuIGNhbGwgd2l0aCBhIHZhbHVlIHRvIGJlIHRlc3RlZCBhZ2Fpbi4KICoKICogTm93IHRoaXMgd291bGQgYmUgdmVyeSBwb2ludGxlc3MsIGlmIE51bWJlckNvbXBhcmUgZGlkbid0IHVuZGVyc3RhbmQKICogbWFnbml0dWRlcy4KICoKICogVGhlIHRhcmdldCB2YWx1ZSBtYXkgdXNlIG1hZ25pdHVkZXMgb2Yga2lsb2J5dGVzIChrLCBraSksCiAqIG1lZ2FieXRlcyAobSwgbWkpLCBvciBnaWdhYnl0ZXMgKGcsIGdpKS4gIFRob3NlIHN1ZmZpeGVkCiAqIHdpdGggYW4gaSB1c2UgdGhlIGFwcHJvcHJpYXRlIDIqKm4gdmVyc2lvbiBpbiBhY2NvcmRhbmNlIHdpdGggdGhlCiAqIElFQyBzdGFuZGFyZDogaHR0cDovL3BoeXNpY3MubmlzdC5nb3YvY3V1L1VuaXRzL2JpbmFyeS5odG1sCiAqCiAqIEJhc2VkIG9uIHRoZSBQZXJsIE51bWJlcjo6Q29tcGFyZSBtb2R1bGUuCiAqCiAqIEBhdXRob3IgICAgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPiBQSFAgcG9ydAogKiBAYXV0aG9yICAgIFJpY2hhcmQgQ2xhbXAgPHJpY2hhcmRjQHVuaXhiZWFyZC5uZXQ+IFBlcmwgdmVyc2lvbgogKiBAY29weXJpZ2h0IDIwMDQtMjAwNSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqIEBjb3B5cmlnaHQgMjAwMiBSaWNoYXJkIENsYW1wIDxyaWNoYXJkY0B1bml4YmVhcmQubmV0PgogKgogKiBAc2VlIGh0dHA6Ly9waHlzaWNzLm5pc3QuZ292L2N1dS9Vbml0cy9iaW5hcnkuaHRtbAogKi8KY2xhc3MgTnVtYmVyQ29tcGFyYXRvciBleHRlbmRzIENvbXBhcmF0b3IKewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGludCAkdGVzdCBBIGNvbXBhcmlzb24gc3RyaW5nIG9yIGFuIGludGVnZXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHRlc3QgaXMgbm90IHVuZGVyc3Rvb2QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR0ZXN0KQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnI15ccyooPT18IT18Wzw+XT0/KT9ccyooWzAtOVwuXSspXHMqKFtrbWddaT8pP1xzKiQjaScsICR0ZXN0LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignRG9uXCd0IHVuZGVyc3RhbmQgIiVzIiBhcyBhIG51bWJlciB0ZXN0LicsICR0ZXN0KSk7CiAgICAgICAgfQoKICAgICAgICAkdGFyZ2V0ID0gJG1hdGNoZXNbMl07CiAgICAgICAgaWYgKCFpc19udW1lcmljKCR0YXJnZXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJ0ludmFsaWQgbnVtYmVyICIlcyIuJywgJHRhcmdldCkpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJG1hdGNoZXNbM10pKSB7CiAgICAgICAgICAgIC8vIG1hZ25pdHVkZQogICAgICAgICAgICBzd2l0Y2ggKHN0cnRvbG93ZXIoJG1hdGNoZXNbM10pKSB7CiAgICAgICAgICAgICAgICBjYXNlICdrJzoKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ICo9IDEwMDA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdraSc6CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCAqPSAxMDI0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnbSc6CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCAqPSAxMDAwMDAwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnbWknOgogICAgICAgICAgICAgICAgICAgICR0YXJnZXQgKj0gMTAyNCAqIDEwMjQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdnJzoKICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ICo9IDEwMDAwMDAwMDA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdnaSc6CiAgICAgICAgICAgICAgICAgICAgJHRhcmdldCAqPSAxMDI0ICogMTAyNCAqIDEwMjQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXRUYXJnZXQoJHRhcmdldCk7CiAgICAgICAgJHRoaXMtPnNldE9wZXJhdG9yKGlzc2V0KCRtYXRjaGVzWzFdKSA/ICRtYXRjaGVzWzFdIDogJz09Jyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBTeW1mb255IHBhY2thZ2UuCiAqCiAqIChjKSBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcQ29tcGFyYXRvcjsKCi8qKgogKiBEYXRlQ29tcGFyZSBjb21waWxlcyBkYXRlIGNvbXBhcmlzb25zLgogKgogKiBAYXV0aG9yIEZhYmllbiBQb3RlbmNpZXIgPGZhYmllbkBzeW1mb255LmNvbT4KICovCmNsYXNzIERhdGVDb21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRlc3QgQSBjb21wYXJpc29uIHN0cmluZwogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdGVzdCBpcyBub3QgdW5kZXJzdG9vZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHRlc3QpCiAgICB7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcjXlxzKig9PXwhPXxbPD5dPT98YWZ0ZXJ8c2luY2V8YmVmb3JlfHVudGlsKT9ccyooLis/KVxzKiQjaScsICR0ZXN0LCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignRG9uXCd0IHVuZGVyc3RhbmQgIiVzIiBhcyBhIGRhdGUgdGVzdC4nLCAkdGVzdCkpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGRhdGUgPSBuZXcgXERhdGVUaW1lKCRtYXRjaGVzWzJdKTsKICAgICAgICAgICAgJHRhcmdldCA9ICRkYXRlLT5mb3JtYXQoJ1UnKTsKICAgICAgICB9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKHNwcmludGYoJyIlcyIgaXMgbm90IGEgdmFsaWQgZGF0ZS4nLCAkbWF0Y2hlc1syXSkpOwogICAgICAgIH0KCiAgICAgICAgJG9wZXJhdG9yID0gaXNzZXQoJG1hdGNoZXNbMV0pID8gJG1hdGNoZXNbMV0gOiAnPT0nOwogICAgICAgIGlmICgnc2luY2UnID09PSAkb3BlcmF0b3IgfHwgJ2FmdGVyJyA9PT0gJG9wZXJhdG9yKSB7CiAgICAgICAgICAgICRvcGVyYXRvciA9ICc+JzsKICAgICAgICB9CgogICAgICAgIGlmICgndW50aWwnID09PSAkb3BlcmF0b3IgfHwgJ2JlZm9yZScgPT09ICRvcGVyYXRvcikgewogICAgICAgICAgICAkb3BlcmF0b3IgPSAnPCc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0T3BlcmF0b3IoJG9wZXJhdG9yKTsKICAgICAgICAkdGhpcy0+c2V0VGFyZ2V0KCR0YXJnZXQpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyOwoKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxDb21wYXJhdG9yXERhdGVDb21wYXJhdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXENvbXBhcmF0b3JcTnVtYmVyQ29tcGFyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvclxDdXN0b21GaWx0ZXJJdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvclxEYXRlUmFuZ2VGaWx0ZXJJdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvclxEZXB0aFJhbmdlRmlsdGVySXRlcmF0b3I7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3JcRXhjbHVkZURpcmVjdG9yeUZpbHRlckl0ZXJhdG9yOwp1c2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyXEl0ZXJhdG9yXEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3I7CnVzZSBTeW1mb255XENvbXBvbmVudFxGaW5kZXJcSXRlcmF0b3JcRmlsZW5hbWVGaWx0ZXJJdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvclxTaXplUmFuZ2VGaWx0ZXJJdGVyYXRvcjsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XEZpbmRlclxJdGVyYXRvclxTb3J0YWJsZUl0ZXJhdG9yOwoKLyoqCiAqIEZpbmRlciBhbGxvd3MgdG8gYnVpbGQgcnVsZXMgdG8gZmluZCBmaWxlcyBhbmQgZGlyZWN0b3JpZXMuCiAqCiAqIEl0IGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBzZXZlcmFsIHNwZWNpYWxpemVkIGl0ZXJhdG9yIGNsYXNzZXMuCiAqCiAqIEFsbCBydWxlcyBtYXkgYmUgaW52b2tlZCBzZXZlcmFsIHRpbWVzLgogKgogKiBBbGwgbWV0aG9kcyByZXR1cm4gdGhlIGN1cnJlbnQgRmluZGVyIG9iamVjdCB0byBhbGxvdyBjaGFpbmluZzoKICoKICogICAgICRmaW5kZXIgPSBGaW5kZXI6OmNyZWF0ZSgpLT5maWxlcygpLT5uYW1lKCcqLnBocCcpLT5pbihfX0RJUl9fKTsKICoKICogQGF1dGhvciBGYWJpZW4gUG90ZW5jaWVyIDxmYWJpZW5Ac3ltZm9ueS5jb20+CiAqLwpjbGFzcyBGaW5kZXIgaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGUsIFxDb3VudGFibGUKewogICAgY29uc3QgSUdOT1JFX1ZDU19GSUxFUyA9IDE7CiAgICBjb25zdCBJR05PUkVfRE9UX0ZJTEVTID0gMjsKCiAgICBwcml2YXRlICRtb2RlID0gMDsKICAgIHByaXZhdGUgJG5hbWVzID0gW107CiAgICBwcml2YXRlICRub3ROYW1lcyA9IFtdOwogICAgcHJpdmF0ZSAkZXhjbHVkZSA9IFtdOwogICAgcHJpdmF0ZSAkZmlsdGVycyA9IFtdOwogICAgcHJpdmF0ZSAkZGVwdGhzID0gW107CiAgICBwcml2YXRlICRzaXplcyA9IFtdOwogICAgcHJpdmF0ZSAkZm9sbG93TGlua3MgPSBmYWxzZTsKICAgIHByaXZhdGUgJHNvcnQgPSBmYWxzZTsKICAgIHByaXZhdGUgJGlnbm9yZSA9IDA7CiAgICBwcml2YXRlICRkaXJzID0gW107CiAgICBwcml2YXRlICRkYXRlcyA9IFtdOwogICAgcHJpdmF0ZSAkaXRlcmF0b3JzID0gW107CiAgICBwcml2YXRlICRjb250YWlucyA9IFtdOwogICAgcHJpdmF0ZSAkbm90Q29udGFpbnMgPSBbXTsKICAgIHByaXZhdGUgJHBhdGhzID0gW107CiAgICBwcml2YXRlICRub3RQYXRocyA9IFtdOwogICAgcHJpdmF0ZSAkaWdub3JlVW5yZWFkYWJsZURpcnMgPSBmYWxzZTsKCiAgICBwcml2YXRlIHN0YXRpYyAkdmNzUGF0dGVybnMgPSBbJy5zdm4nLCAnX3N2bicsICdDVlMnLCAnX2RhcmNzJywgJy5hcmNoLXBhcmFtcycsICcubW9ub3RvbmUnLCAnLmJ6cicsICcuZ2l0JywgJy5oZyddOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmlnbm9yZSA9IHN0YXRpYzo6SUdOT1JFX1ZDU19GSUxFUyB8IHN0YXRpYzo6SUdOT1JFX0RPVF9GSUxFUzsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgRmluZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygpOwogICAgfQoKICAgIC8qKgogICAgICogUmVzdHJpY3RzIHRoZSBtYXRjaGluZyB0byBkaXJlY3RvcmllcyBvbmx5LgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpcmVjdG9yaWVzKCkKICAgIHsKICAgICAgICAkdGhpcy0+bW9kZSA9IEl0ZXJhdG9yXEZpbGVUeXBlRmlsdGVySXRlcmF0b3I6Ok9OTFlfRElSRUNUT1JJRVM7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlc3RyaWN0cyB0aGUgbWF0Y2hpbmcgdG8gZmlsZXMgb25seS4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWxlcygpCiAgICB7CiAgICAgICAgJHRoaXMtPm1vZGUgPSBJdGVyYXRvclxGaWxlVHlwZUZpbHRlckl0ZXJhdG9yOjpPTkxZX0ZJTEVTOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHRlc3RzIGZvciB0aGUgZGlyZWN0b3J5IGRlcHRoLgogICAgICoKICAgICAqIFVzYWdlOgogICAgICoKICAgICAqICAgICAkZmluZGVyLT5kZXB0aCgnPiAxJykgLy8gdGhlIEZpbmRlciB3aWxsIHN0YXJ0IG1hdGNoaW5nIGF0IGxldmVsIDEuCiAgICAgKiAgICAgJGZpbmRlci0+ZGVwdGgoJzwgMycpIC8vIHRoZSBGaW5kZXIgd2lsbCBkZXNjZW5kIGF0IG1vc3QgMyBsZXZlbHMgb2YgZGlyZWN0b3JpZXMgYmVsb3cgdGhlIHN0YXJ0aW5nIHBvaW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICRsZXZlbCBUaGUgZGVwdGggbGV2ZWwgZXhwcmVzc2lvbgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIERlcHRoUmFuZ2VGaWx0ZXJJdGVyYXRvcgogICAgICogQHNlZSBOdW1iZXJDb21wYXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZXB0aCgkbGV2ZWwpCiAgICB7CiAgICAgICAgJHRoaXMtPmRlcHRoc1tdID0gbmV3IENvbXBhcmF0b3JcTnVtYmVyQ29tcGFyYXRvcigkbGV2ZWwpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHRlc3RzIGZvciBmaWxlIGRhdGVzIChsYXN0IG1vZGlmaWVkKS4KICAgICAqCiAgICAgKiBUaGUgZGF0ZSBtdXN0IGJlIHNvbWV0aGluZyB0aGF0IHN0cnRvdGltZSgpIGlzIGFibGUgdG8gcGFyc2U6CiAgICAgKgogICAgICogICAgICRmaW5kZXItPmRhdGUoJ3NpbmNlIHllc3RlcmRheScpOwogICAgICogICAgICRmaW5kZXItPmRhdGUoJ3VudGlsIDIgZGF5cyBhZ28nKTsKICAgICAqICAgICAkZmluZGVyLT5kYXRlKCc+IG5vdyAtIDIgaG91cnMnKTsKICAgICAqICAgICAkZmluZGVyLT5kYXRlKCc+PSAyMDA1LTEwLTE1Jyk7CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZGF0ZSBBIGRhdGUgcmFuZ2Ugc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgc3RydG90aW1lCiAgICAgKiBAc2VlIERhdGVSYW5nZUZpbHRlckl0ZXJhdG9yCiAgICAgKiBAc2VlIERhdGVDb21wYXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkYXRlKCRkYXRlKQogICAgewogICAgICAgICR0aGlzLT5kYXRlc1tdID0gbmV3IENvbXBhcmF0b3JcRGF0ZUNvbXBhcmF0b3IoJGRhdGUpOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIHJ1bGVzIHRoYXQgZmlsZXMgbXVzdCBtYXRjaC4KICAgICAqCiAgICAgKiBZb3UgY2FuIHVzZSBwYXR0ZXJucyAoZGVsaW1pdGVkIHdpdGggLyBzaWduKSwgZ2xvYnMgb3Igc2ltcGxlIHN0cmluZ3MuCiAgICAgKgogICAgICogICAgICRmaW5kZXItPm5hbWUoJyoucGhwJykKICAgICAqICAgICAkZmluZGVyLT5uYW1lKCcvXC5waHAkLycpIC8vIHNhbWUgYXMgYWJvdmUKICAgICAqICAgICAkZmluZGVyLT5uYW1lKCd0ZXN0LnBocCcpCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBBIHBhdHRlcm4gKGEgcmVnZXhwLCBhIGdsb2IsIG9yIGEgc3RyaW5nKQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5hbWUoJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWVzW10gPSAkcGF0dGVybjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBydWxlcyB0aGF0IGZpbGVzIG11c3Qgbm90IG1hdGNoLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdHRlcm4gQSBwYXR0ZXJuIChhIHJlZ2V4cCwgYSBnbG9iLCBvciBhIHN0cmluZykKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHNlZSBGaWxlbmFtZUZpbHRlckl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3ROYW1lKCRwYXR0ZXJuKQogICAgewogICAgICAgICR0aGlzLT5ub3ROYW1lc1tdID0gJHBhdHRlcm47CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgdGVzdHMgdGhhdCBmaWxlIGNvbnRlbnRzIG11c3QgbWF0Y2guCiAgICAgKgogICAgICogU3RyaW5ncyBvciBQQ1JFIHBhdHRlcm5zIGNhbiBiZSB1c2VkOgogICAgICoKICAgICAqICAgICAkZmluZGVyLT5jb250YWlucygnTG9yZW0gaXBzdW0nKQogICAgICogICAgICRmaW5kZXItPmNvbnRhaW5zKCcvTG9yZW0gaXBzdW0vaScpCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBBIHBhdHRlcm4gKHN0cmluZyBvciByZWdleHApCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgRmlsZWNvbnRlbnRGaWx0ZXJJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29udGFpbnMoJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbnRhaW5zW10gPSAkcGF0dGVybjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyB0ZXN0cyB0aGF0IGZpbGUgY29udGVudHMgbXVzdCBub3QgbWF0Y2guCiAgICAgKgogICAgICogU3RyaW5ncyBvciBQQ1JFIHBhdHRlcm5zIGNhbiBiZSB1c2VkOgogICAgICoKICAgICAqICAgICAkZmluZGVyLT5ub3RDb250YWlucygnTG9yZW0gaXBzdW0nKQogICAgICogICAgICRmaW5kZXItPm5vdENvbnRhaW5zKCcvTG9yZW0gaXBzdW0vaScpCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBBIHBhdHRlcm4gKHN0cmluZyBvciByZWdleHApCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgRmlsZWNvbnRlbnRGaWx0ZXJJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm90Q29udGFpbnMoJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPm5vdENvbnRhaW5zW10gPSAkcGF0dGVybjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBydWxlcyB0aGF0IGZpbGVuYW1lcyBtdXN0IG1hdGNoLgogICAgICoKICAgICAqIFlvdSBjYW4gdXNlIHBhdHRlcm5zIChkZWxpbWl0ZWQgd2l0aCAvIHNpZ24pIG9yIHNpbXBsZSBzdHJpbmdzLgogICAgICoKICAgICAqICAgICAkZmluZGVyLT5wYXRoKCdzb21lL3NwZWNpYWwvZGlyJykKICAgICAqICAgICAkZmluZGVyLT5wYXRoKCcvc29tZVwvc3BlY2lhbFwvZGlyLycpIC8vIHNhbWUgYXMgYWJvdmUKICAgICAqCiAgICAgKiBVc2Ugb25seSAvIGFzIGRpcm5hbWUgc2VwYXJhdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdHRlcm4gQSBwYXR0ZXJuIChhIHJlZ2V4cCBvciBhIHN0cmluZykKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHNlZSBGaWxlbmFtZUZpbHRlckl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXRoKCRwYXR0ZXJuKQogICAgewogICAgICAgICR0aGlzLT5wYXRoc1tdID0gJHBhdHRlcm47CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgcnVsZXMgdGhhdCBmaWxlbmFtZXMgbXVzdCBub3QgbWF0Y2guCiAgICAgKgogICAgICogWW91IGNhbiB1c2UgcGF0dGVybnMgKGRlbGltaXRlZCB3aXRoIC8gc2lnbikgb3Igc2ltcGxlIHN0cmluZ3MuCiAgICAgKgogICAgICogICAgICRmaW5kZXItPm5vdFBhdGgoJ3NvbWUvc3BlY2lhbC9kaXInKQogICAgICogICAgICRmaW5kZXItPm5vdFBhdGgoJy9zb21lXC9zcGVjaWFsXC9kaXIvJykgLy8gc2FtZSBhcyBhYm92ZQogICAgICoKICAgICAqIFVzZSBvbmx5IC8gYXMgZGlybmFtZSBzZXBhcmF0b3IuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBBIHBhdHRlcm4gKGEgcmVnZXhwIG9yIGEgc3RyaW5nKQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIEZpbGVuYW1lRmlsdGVySXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdFBhdGgoJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPm5vdFBhdGhzW10gPSAkcGF0dGVybjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyB0ZXN0cyBmb3IgZmlsZSBzaXplcy4KICAgICAqCiAgICAgKiAgICAgJGZpbmRlci0+c2l6ZSgnPiAxMEsnKTsKICAgICAqICAgICAkZmluZGVyLT5zaXplKCc8PSAxS2knKTsKICAgICAqICAgICAkZmluZGVyLT5zaXplKDQpOwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8aW50ICRzaXplIEEgc2l6ZSByYW5nZSBzdHJpbmcgb3IgYW4gaW50ZWdlcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIFNpemVSYW5nZUZpbHRlckl0ZXJhdG9yCiAgICAgKiBAc2VlIE51bWJlckNvbXBhcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNpemUoJHNpemUpCiAgICB7CiAgICAgICAgJHRoaXMtPnNpemVzW10gPSBuZXcgQ29tcGFyYXRvclxOdW1iZXJDb21wYXJhdG9yKCRzaXplKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhjbHVkZXMgZGlyZWN0b3JpZXMuCiAgICAgKgogICAgICogRGlyZWN0b3JpZXMgcGFzc2VkIGFzIGFyZ3VtZW50IG11c3QgYmUgcmVsYXRpdmUgdG8gdGhlIG9uZXMgZGVmaW5lZCB3aXRoIHRoZSBgaW4oKWAgbWV0aG9kLiBGb3IgZXhhbXBsZToKICAgICAqCiAgICAgKiAgICAgJGZpbmRlci0+aW4oX19ESVJfXyktPmV4Y2x1ZGUoJ3J1YnknKTsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRkaXJzIEEgZGlyZWN0b3J5IHBhdGggb3IgYW4gYXJyYXkgb2YgZGlyZWN0b3JpZXMKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHNlZSBFeGNsdWRlRGlyZWN0b3J5RmlsdGVySXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4Y2x1ZGUoJGRpcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmV4Y2x1ZGUgPSBhcnJheV9tZXJnZSgkdGhpcy0+ZXhjbHVkZSwgKGFycmF5KSAkZGlycyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEV4Y2x1ZGVzICJoaWRkZW4iIGRpcmVjdG9yaWVzIGFuZCBmaWxlcyAoc3RhcnRpbmcgd2l0aCBhIGRvdCkuCiAgICAgKgogICAgICogVGhpcyBvcHRpb24gaXMgZW5hYmxlZCBieSBkZWZhdWx0LgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpZ25vcmVEb3RGaWxlcyBXaGV0aGVyIHRvIGV4Y2x1ZGUgImhpZGRlbiIgZmlsZXMgb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgRXhjbHVkZURpcmVjdG9yeUZpbHRlckl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpZ25vcmVEb3RGaWxlcygkaWdub3JlRG90RmlsZXMpCiAgICB7CiAgICAgICAgaWYgKCRpZ25vcmVEb3RGaWxlcykgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlIHw9IHN0YXRpYzo6SUdOT1JFX0RPVF9GSUxFUzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlICY9IH5zdGF0aWM6OklHTk9SRV9ET1RfRklMRVM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JjZXMgdGhlIGZpbmRlciB0byBpZ25vcmUgdmVyc2lvbiBjb250cm9sIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIFRoaXMgb3B0aW9uIGlzIGVuYWJsZWQgYnkgZGVmYXVsdC4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkaWdub3JlVkNTIFdoZXRoZXIgdG8gZXhjbHVkZSBWQ1MgZmlsZXMgb3Igbm90CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgRXhjbHVkZURpcmVjdG9yeUZpbHRlckl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpZ25vcmVWQ1MoJGlnbm9yZVZDUykKICAgIHsKICAgICAgICBpZiAoJGlnbm9yZVZDUykgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlIHw9IHN0YXRpYzo6SUdOT1JFX1ZDU19GSUxFUzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+aWdub3JlICY9IH5zdGF0aWM6OklHTk9SRV9WQ1NfRklMRVM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIFZDUyBwYXR0ZXJucy4KICAgICAqCiAgICAgKiBAc2VlIGlnbm9yZVZDUygpCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkcGF0dGVybiBWQ1MgcGF0dGVybnMgdG8gaWdub3JlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWRkVkNTUGF0dGVybigkcGF0dGVybikKICAgIHsKICAgICAgICBmb3JlYWNoICgoYXJyYXkpICRwYXR0ZXJuIGFzICRwKSB7CiAgICAgICAgICAgIHNlbGY6OiR2Y3NQYXR0ZXJuc1tdID0gJHA7CiAgICAgICAgfQoKICAgICAgICBzZWxmOjokdmNzUGF0dGVybnMgPSBhcnJheV91bmlxdWUoc2VsZjo6JHZjc1BhdHRlcm5zKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNvcnRzIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBieSBhbiBhbm9ueW1vdXMgZnVuY3Rpb24uCiAgICAgKgogICAgICogVGhlIGFub255bW91cyBmdW5jdGlvbiByZWNlaXZlcyB0d28gXFNwbEZpbGVJbmZvIGluc3RhbmNlcyB0byBjb21wYXJlLgogICAgICoKICAgICAqIFRoaXMgY2FuIGJlIHNsb3cgYXMgYWxsIHRoZSBtYXRjaGluZyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgbXVzdCBiZSByZXRyaWV2ZWQgZm9yIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgU29ydGFibGVJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc29ydChcQ2xvc3VyZSAkY2xvc3VyZSkKICAgIHsKICAgICAgICAkdGhpcy0+c29ydCA9ICRjbG9zdXJlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb3J0cyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgYnkgbmFtZS4KICAgICAqCiAgICAgKiBUaGlzIGNhbiBiZSBzbG93IGFzIGFsbCB0aGUgbWF0Y2hpbmcgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIG11c3QgYmUgcmV0cmlldmVkIGZvciBjb21wYXJpc29uLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIFNvcnRhYmxlSXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNvcnRCeU5hbWUoKQogICAgewogICAgICAgICR0aGlzLT5zb3J0ID0gSXRlcmF0b3JcU29ydGFibGVJdGVyYXRvcjo6U09SVF9CWV9OQU1FOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb3J0cyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgYnkgdHlwZSAoZGlyZWN0b3JpZXMgYmVmb3JlIGZpbGVzKSwgdGhlbiBieSBuYW1lLgogICAgICoKICAgICAqIFRoaXMgY2FuIGJlIHNsb3cgYXMgYWxsIHRoZSBtYXRjaGluZyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgbXVzdCBiZSByZXRyaWV2ZWQgZm9yIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgU29ydGFibGVJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc29ydEJ5VHlwZSgpCiAgICB7CiAgICAgICAgJHRoaXMtPnNvcnQgPSBJdGVyYXRvclxTb3J0YWJsZUl0ZXJhdG9yOjpTT1JUX0JZX1RZUEU7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNvcnRzIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBieSB0aGUgbGFzdCBhY2Nlc3NlZCB0aW1lLgogICAgICoKICAgICAqIFRoaXMgaXMgdGhlIHRpbWUgdGhhdCB0aGUgZmlsZSB3YXMgbGFzdCBhY2Nlc3NlZCwgcmVhZCBvciB3cml0dGVuIHRvLgogICAgICoKICAgICAqIFRoaXMgY2FuIGJlIHNsb3cgYXMgYWxsIHRoZSBtYXRjaGluZyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgbXVzdCBiZSByZXRyaWV2ZWQgZm9yIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEBzZWUgU29ydGFibGVJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc29ydEJ5QWNjZXNzZWRUaW1lKCkKICAgIHsKICAgICAgICAkdGhpcy0+c29ydCA9IEl0ZXJhdG9yXFNvcnRhYmxlSXRlcmF0b3I6OlNPUlRfQllfQUNDRVNTRURfVElNRTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU29ydHMgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGJ5IHRoZSBsYXN0IGlub2RlIGNoYW5nZWQgdGltZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIHRoZSB0aW1lIHRoYXQgdGhlIGlub2RlIGluZm9ybWF0aW9uIHdhcyBsYXN0IG1vZGlmaWVkIChwZXJtaXNzaW9ucywgb3duZXIsIGdyb3VwIG9yIG90aGVyIG1ldGFkYXRhKS4KICAgICAqCiAgICAgKiBPbiBXaW5kb3dzLCBzaW5jZSBpbm9kZSBpcyBub3QgYXZhaWxhYmxlLCBjaGFuZ2VkIHRpbWUgaXMgYWN0dWFsbHkgdGhlIGZpbGUgY3JlYXRpb24gdGltZS4KICAgICAqCiAgICAgKiBUaGlzIGNhbiBiZSBzbG93IGFzIGFsbCB0aGUgbWF0Y2hpbmcgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIG11c3QgYmUgcmV0cmlldmVkIGZvciBjb21wYXJpc29uLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIFNvcnRhYmxlSXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNvcnRCeUNoYW5nZWRUaW1lKCkKICAgIHsKICAgICAgICAkdGhpcy0+c29ydCA9IEl0ZXJhdG9yXFNvcnRhYmxlSXRlcmF0b3I6OlNPUlRfQllfQ0hBTkdFRF9USU1FOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb3J0cyBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgYnkgdGhlIGxhc3QgbW9kaWZpZWQgdGltZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIHRoZSBsYXN0IHRpbWUgdGhlIGFjdHVhbCBjb250ZW50cyBvZiB0aGUgZmlsZSB3ZXJlIGxhc3QgbW9kaWZpZWQuCiAgICAgKgogICAgICogVGhpcyBjYW4gYmUgc2xvdyBhcyBhbGwgdGhlIG1hdGNoaW5nIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBtdXN0IGJlIHJldHJpZXZlZCBmb3IgY29tcGFyaXNvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHNlZSBTb3J0YWJsZUl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzb3J0QnlNb2RpZmllZFRpbWUoKQogICAgewogICAgICAgICR0aGlzLT5zb3J0ID0gSXRlcmF0b3JcU29ydGFibGVJdGVyYXRvcjo6U09SVF9CWV9NT0RJRklFRF9USU1FOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBpdGVyYXRvciB3aXRoIGFuIGFub255bW91cyBmdW5jdGlvbi4KICAgICAqCiAgICAgKiBUaGUgYW5vbnltb3VzIGZ1bmN0aW9uIHJlY2VpdmVzIGEgXFNwbEZpbGVJbmZvIGFuZCBtdXN0IHJldHVybiBmYWxzZQogICAgICogdG8gcmVtb3ZlIGZpbGVzLgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAc2VlIEN1c3RvbUZpbHRlckl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoXENsb3N1cmUgJGNsb3N1cmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmZpbHRlcnNbXSA9ICRjbG9zdXJlOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JjZXMgdGhlIGZvbGxvd2luZyBvZiBzeW1saW5rcy4KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmb2xsb3dMaW5rcygpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvbGxvd0xpbmtzID0gdHJ1ZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogVGVsbHMgZmluZGVyIHRvIGlnbm9yZSB1bnJlYWRhYmxlIGRpcmVjdG9yaWVzLgogICAgICoKICAgICAqIEJ5IGRlZmF1bHQsIHNjYW5uaW5nIHVucmVhZGFibGUgZGlyZWN0b3JpZXMgY29udGVudCB0aHJvd3MgYW4gQWNjZXNzRGVuaWVkRXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRpZ25vcmUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpZ25vcmVVbnJlYWRhYmxlRGlycygkaWdub3JlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+aWdub3JlVW5yZWFkYWJsZURpcnMgPSAoYm9vbCkgJGlnbm9yZTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoZXMgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHdoaWNoIG1hdGNoIGRlZmluZWQgcnVsZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZ3xzdHJpbmdbXSAkZGlycyBBIGRpcmVjdG9yeSBwYXRoIG9yIGFuIGFycmF5IG9mIGRpcmVjdG9yaWVzCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICoKICAgICAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlIGRpcmVjdG9yaWVzIGRvZXMgbm90IGV4aXN0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbigkZGlycykKICAgIHsKICAgICAgICAkcmVzb2x2ZWREaXJzID0gW107CgogICAgICAgIGZvcmVhY2ggKChhcnJheSkgJGRpcnMgYXMgJGRpcikgewogICAgICAgICAgICBpZiAoaXNfZGlyKCRkaXIpKSB7CiAgICAgICAgICAgICAgICAkcmVzb2x2ZWREaXJzW10gPSAkdGhpcy0+bm9ybWFsaXplRGlyKCRkaXIpOwogICAgICAgICAgICB9IGVsc2VpZiAoJGdsb2IgPSBnbG9iKCRkaXIsIChcZGVmaW5lZCgnR0xPQl9CUkFDRScpID8gXEdMT0JfQlJBQ0UgOiAwKSB8IFxHTE9CX09OTFlESVIgfCBcR0xPQl9OT1NPUlQpKSB7CiAgICAgICAgICAgICAgICBzb3J0KCRnbG9iKTsKICAgICAgICAgICAgICAgICRyZXNvbHZlZERpcnMgPSBhcnJheV9tZXJnZSgkcmVzb2x2ZWREaXJzLCBhcnJheV9tYXAoWyR0aGlzLCAnbm9ybWFsaXplRGlyJ10sICRnbG9iKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgIiVzIiBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QuJywgJGRpcikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZGlycyA9IGFycmF5X21lcmdlKCR0aGlzLT5kaXJzLCAkcmVzb2x2ZWREaXJzKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBJdGVyYXRvciBmb3IgdGhlIGN1cnJlbnQgRmluZGVyIGNvbmZpZ3VyYXRpb24uCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgSXRlcmF0b3JBZ2dyZWdhdGUgaW50ZXJmYWNlLgogICAgICoKICAgICAqIEByZXR1cm4gXEl0ZXJhdG9yfFNwbEZpbGVJbmZvW10gQW4gaXRlcmF0b3IKICAgICAqCiAgICAgKiBAdGhyb3dzIFxMb2dpY0V4Y2VwdGlvbiBpZiB0aGUgaW4oKSBtZXRob2QgaGFzIG5vdCBiZWVuIGNhbGxlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKQogICAgewogICAgICAgIGlmICgwID09PSBcY291bnQoJHRoaXMtPmRpcnMpICYmIDAgPT09IFxjb3VudCgkdGhpcy0+aXRlcmF0b3JzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXExvZ2ljRXhjZXB0aW9uKCdZb3UgbXVzdCBjYWxsIG9uZSBvZiBpbigpIG9yIGFwcGVuZCgpIG1ldGhvZHMgYmVmb3JlIGl0ZXJhdGluZyBvdmVyIGEgRmluZGVyLicpOwogICAgICAgIH0KCiAgICAgICAgaWYgKDEgPT09IFxjb3VudCgkdGhpcy0+ZGlycykgJiYgMCA9PT0gXGNvdW50KCR0aGlzLT5pdGVyYXRvcnMpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c2VhcmNoSW5EaXJlY3RvcnkoJHRoaXMtPmRpcnNbMF0pOwogICAgICAgIH0KCiAgICAgICAgJGl0ZXJhdG9yID0gbmV3IFxBcHBlbmRJdGVyYXRvcigpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5kaXJzIGFzICRkaXIpIHsKICAgICAgICAgICAgJGl0ZXJhdG9yLT5hcHBlbmQoJHRoaXMtPnNlYXJjaEluRGlyZWN0b3J5KCRkaXIpKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5pdGVyYXRvcnMgYXMgJGl0KSB7CiAgICAgICAgICAgICRpdGVyYXRvci0+YXBwZW5kKCRpdCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGl0ZXJhdG9yOwogICAgfQoKICAgIC8qKgogICAgICogQXBwZW5kcyBhbiBleGlzdGluZyBzZXQgb2YgZmlsZXMvZGlyZWN0b3JpZXMgdG8gdGhlIGZpbmRlci4KICAgICAqCiAgICAgKiBUaGUgc2V0IGNhbiBiZSBhbm90aGVyIEZpbmRlciwgYW4gSXRlcmF0b3IsIGFuIEl0ZXJhdG9yQWdncmVnYXRlLCBvciBldmVuIGEgcGxhaW4gYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtIGl0ZXJhYmxlICRpdGVyYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbm90IGl0ZXJhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhcHBlbmQoJGl0ZXJhdG9yKQogICAgewogICAgICAgIGlmICgkaXRlcmF0b3IgaW5zdGFuY2VvZiBcSXRlcmF0b3JBZ2dyZWdhdGUpIHsKICAgICAgICAgICAgJHRoaXMtPml0ZXJhdG9yc1tdID0gJGl0ZXJhdG9yLT5nZXRJdGVyYXRvcigpOwogICAgICAgIH0gZWxzZWlmICgkaXRlcmF0b3IgaW5zdGFuY2VvZiBcSXRlcmF0b3IpIHsKICAgICAgICAgICAgJHRoaXMtPml0ZXJhdG9yc1tdID0gJGl0ZXJhdG9yOwogICAgICAgIH0gZWxzZWlmICgkaXRlcmF0b3IgaW5zdGFuY2VvZiBcVHJhdmVyc2FibGUgfHwgXGlzX2FycmF5KCRpdGVyYXRvcikpIHsKICAgICAgICAgICAgJGl0ID0gbmV3IFxBcnJheUl0ZXJhdG9yKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRpdGVyYXRvciBhcyAkZmlsZSkgewogICAgICAgICAgICAgICAgJGl0LT5hcHBlbmQoJGZpbGUgaW5zdGFuY2VvZiBcU3BsRmlsZUluZm8gPyAkZmlsZSA6IG5ldyBcU3BsRmlsZUluZm8oJGZpbGUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+aXRlcmF0b3JzW10gPSAkaXQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ZpbmRlcjo6YXBwZW5kKCkgbWV0aG9kIHdyb25nIGFyZ3VtZW50IHR5cGUuJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiBhbnkgcmVzdWx0cyB3ZXJlIGZvdW5kLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUmVzdWx0cygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldEl0ZXJhdG9yKCkgYXMgJF8pIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb3VudHMgYWxsIHRoZSByZXN1bHRzIGNvbGxlY3RlZCBieSB0aGUgaXRlcmF0b3JzLgogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yX2NvdW50KCR0aGlzLT5nZXRJdGVyYXRvcigpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpcgogICAgICoKICAgICAqIEByZXR1cm4gXEl0ZXJhdG9yCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2VhcmNoSW5EaXJlY3RvcnkoJGRpcikKICAgIHsKICAgICAgICAkZXhjbHVkZSA9ICR0aGlzLT5leGNsdWRlOwogICAgICAgICRub3RQYXRocyA9ICR0aGlzLT5ub3RQYXRoczsKCiAgICAgICAgaWYgKHN0YXRpYzo6SUdOT1JFX1ZDU19GSUxFUyA9PT0gKHN0YXRpYzo6SUdOT1JFX1ZDU19GSUxFUyAmICR0aGlzLT5pZ25vcmUpKSB7CiAgICAgICAgICAgICRleGNsdWRlID0gYXJyYXlfbWVyZ2UoJGV4Y2x1ZGUsIHNlbGY6OiR2Y3NQYXR0ZXJucyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RhdGljOjpJR05PUkVfRE9UX0ZJTEVTID09PSAoc3RhdGljOjpJR05PUkVfRE9UX0ZJTEVTICYgJHRoaXMtPmlnbm9yZSkpIHsKICAgICAgICAgICAgJG5vdFBhdGhzW10gPSAnIyhefC8pXC4uKygvfCQpIyc7CiAgICAgICAgfQoKICAgICAgICAkbWluRGVwdGggPSAwOwogICAgICAgICRtYXhEZXB0aCA9IFxQSFBfSU5UX01BWDsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmRlcHRocyBhcyAkY29tcGFyYXRvcikgewogICAgICAgICAgICBzd2l0Y2ggKCRjb21wYXJhdG9yLT5nZXRPcGVyYXRvcigpKSB7CiAgICAgICAgICAgICAgICBjYXNlICc+JzoKICAgICAgICAgICAgICAgICAgICAkbWluRGVwdGggPSAkY29tcGFyYXRvci0+Z2V0VGFyZ2V0KCkgKyAxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnPj0nOgogICAgICAgICAgICAgICAgICAgICRtaW5EZXB0aCA9ICRjb21wYXJhdG9yLT5nZXRUYXJnZXQoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJzwnOgogICAgICAgICAgICAgICAgICAgICRtYXhEZXB0aCA9ICRjb21wYXJhdG9yLT5nZXRUYXJnZXQoKSAtIDE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICc8PSc6CiAgICAgICAgICAgICAgICAgICAgJG1heERlcHRoID0gJGNvbXBhcmF0b3ItPmdldFRhcmdldCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAkbWluRGVwdGggPSAkbWF4RGVwdGggPSAkY29tcGFyYXRvci0+Z2V0VGFyZ2V0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRmbGFncyA9IFxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6U0tJUF9ET1RTOwoKICAgICAgICBpZiAoJHRoaXMtPmZvbGxvd0xpbmtzKSB7CiAgICAgICAgICAgICRmbGFncyB8PSBcUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3I6OkZPTExPV19TWU1MSU5LUzsKICAgICAgICB9CgogICAgICAgICRpdGVyYXRvciA9IG5ldyBJdGVyYXRvclxSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkZGlyLCAkZmxhZ3MsICR0aGlzLT5pZ25vcmVVbnJlYWRhYmxlRGlycyk7CgogICAgICAgIGlmICgkZXhjbHVkZSkgewogICAgICAgICAgICAkaXRlcmF0b3IgPSBuZXcgSXRlcmF0b3JcRXhjbHVkZURpcmVjdG9yeUZpbHRlckl0ZXJhdG9yKCRpdGVyYXRvciwgJGV4Y2x1ZGUpOwogICAgICAgIH0KCiAgICAgICAgJGl0ZXJhdG9yID0gbmV3IFxSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKCRpdGVyYXRvciwgXFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OlNFTEZfRklSU1QpOwoKICAgICAgICBpZiAoJG1pbkRlcHRoID4gMCB8fCAkbWF4RGVwdGggPCBcUEhQX0lOVF9NQVgpIHsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEl0ZXJhdG9yXERlcHRoUmFuZ2VGaWx0ZXJJdGVyYXRvcigkaXRlcmF0b3IsICRtaW5EZXB0aCwgJG1heERlcHRoKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bW9kZSkgewogICAgICAgICAgICAkaXRlcmF0b3IgPSBuZXcgSXRlcmF0b3JcRmlsZVR5cGVGaWx0ZXJJdGVyYXRvcigkaXRlcmF0b3IsICR0aGlzLT5tb2RlKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+bmFtZXMgfHwgJHRoaXMtPm5vdE5hbWVzKSB7CiAgICAgICAgICAgICRpdGVyYXRvciA9IG5ldyBJdGVyYXRvclxGaWxlbmFtZUZpbHRlckl0ZXJhdG9yKCRpdGVyYXRvciwgJHRoaXMtPm5hbWVzLCAkdGhpcy0+bm90TmFtZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5jb250YWlucyB8fCAkdGhpcy0+bm90Q29udGFpbnMpIHsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEl0ZXJhdG9yXEZpbGVjb250ZW50RmlsdGVySXRlcmF0b3IoJGl0ZXJhdG9yLCAkdGhpcy0+Y29udGFpbnMsICR0aGlzLT5ub3RDb250YWlucyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPnNpemVzKSB7CiAgICAgICAgICAgICRpdGVyYXRvciA9IG5ldyBJdGVyYXRvclxTaXplUmFuZ2VGaWx0ZXJJdGVyYXRvcigkaXRlcmF0b3IsICR0aGlzLT5zaXplcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmRhdGVzKSB7CiAgICAgICAgICAgICRpdGVyYXRvciA9IG5ldyBJdGVyYXRvclxEYXRlUmFuZ2VGaWx0ZXJJdGVyYXRvcigkaXRlcmF0b3IsICR0aGlzLT5kYXRlcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPmZpbHRlcnMpIHsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEl0ZXJhdG9yXEN1c3RvbUZpbHRlckl0ZXJhdG9yKCRpdGVyYXRvciwgJHRoaXMtPmZpbHRlcnMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wYXRocyB8fCAkbm90UGF0aHMpIHsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gbmV3IEl0ZXJhdG9yXFBhdGhGaWx0ZXJJdGVyYXRvcigkaXRlcmF0b3IsICR0aGlzLT5wYXRocywgJG5vdFBhdGhzKTsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+c29ydCkgewogICAgICAgICAgICAkaXRlcmF0b3JBZ2dyZWdhdGUgPSBuZXcgSXRlcmF0b3JcU29ydGFibGVJdGVyYXRvcigkaXRlcmF0b3IsICR0aGlzLT5zb3J0KTsKICAgICAgICAgICAgJGl0ZXJhdG9yID0gJGl0ZXJhdG9yQWdncmVnYXRlLT5nZXRJdGVyYXRvcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRpdGVyYXRvcjsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZXMgZ2l2ZW4gZGlyZWN0b3J5IG5hbWVzIGJ5IHJlbW92aW5nIHRyYWlsaW5nIHNsYXNoZXMuCiAgICAgKgogICAgICogRXhjbHVkaW5nOiAocylmdHA6Ly8gb3Igc3NoMi4ocylmdHA6Ly8gd3JhcHBlcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gbm9ybWFsaXplRGlyKCRkaXIpCiAgICB7CiAgICAgICAgaWYgKCcvJyA9PT0gJGRpcikgewogICAgICAgICAgICByZXR1cm4gJGRpcjsKICAgICAgICB9CgogICAgICAgICRkaXIgPSBydHJpbSgkZGlyLCAnLycuXERJUkVDVE9SWV9TRVBBUkFUT1IpOwoKICAgICAgICBpZiAocHJlZ19tYXRjaCgnI14oc3NoMlwuKT9zP2Z0cDovLyMnLCAkZGlyKSkgewogICAgICAgICAgICAkZGlyIC49ICcvJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkZGlyOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgU3ltZm9ueSBwYWNrYWdlLgogKgogKiAoYykgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU3ltZm9ueVxDb21wb25lbnRcRmluZGVyOwoKLyoqCiAqIEV4dGVuZHMgXFNwbEZpbGVJbmZvIHRvIHN1cHBvcnQgcmVsYXRpdmUgcGF0aHMuCiAqCiAqIEBhdXRob3IgRmFiaWVuIFBvdGVuY2llciA8ZmFiaWVuQHN5bWZvbnkuY29tPgogKi8KY2xhc3MgU3BsRmlsZUluZm8gZXh0ZW5kcyBcU3BsRmlsZUluZm8KewogICAgcHJpdmF0ZSAkcmVsYXRpdmVQYXRoOwogICAgcHJpdmF0ZSAkcmVsYXRpdmVQYXRobmFtZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgICAgICAgICAgICAgVGhlIGZpbGUgbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkcmVsYXRpdmVQYXRoICAgICBUaGUgcmVsYXRpdmUgcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkcmVsYXRpdmVQYXRobmFtZSBUaGUgcmVsYXRpdmUgcGF0aCBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZmlsZSwgJHJlbGF0aXZlUGF0aCwgJHJlbGF0aXZlUGF0aG5hbWUpCiAgICB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkZmlsZSk7CiAgICAgICAgJHRoaXMtPnJlbGF0aXZlUGF0aCA9ICRyZWxhdGl2ZVBhdGg7CiAgICAgICAgJHRoaXMtPnJlbGF0aXZlUGF0aG5hbWUgPSAkcmVsYXRpdmVQYXRobmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlbGF0aXZlIHBhdGguCiAgICAgKgogICAgICogVGhpcyBwYXRoIGRvZXMgbm90IGNvbnRhaW4gdGhlIGZpbGUgbmFtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyB0aGUgcmVsYXRpdmUgcGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVsYXRpdmVQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbGF0aXZlUGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlbGF0aXZlIHBhdGggbmFtZS4KICAgICAqCiAgICAgKiBUaGlzIHBhdGggY29udGFpbnMgdGhlIGZpbGUgbmFtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyB0aGUgcmVsYXRpdmUgcGF0aCBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZWxhdGl2ZVBhdGhuYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJlbGF0aXZlUGF0aG5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUKICAgICAqCiAgICAgKiBAdGhyb3dzIFxSdW50aW1lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZW50cygpCiAgICB7CiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoZnVuY3Rpb24gKCR0eXBlLCAkbXNnKSB1c2UgKCYkZXJyb3IpIHsgJGVycm9yID0gJG1zZzsgfSk7CiAgICAgICAgJGNvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+Z2V0UGF0aG5hbWUoKSk7CiAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CiAgICAgICAgaWYgKGZhbHNlID09PSAkY29udGVudCkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJGVycm9yKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29udGVudDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgUHJvbWlzZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFRyYW5zZm9ybXMgYSBwcm9taXNlJ3MgdmFsdWUgYnkgYXBwbHlpbmcgYSBmdW5jdGlvbiB0byB0aGUgcHJvbWlzZSdzIGZ1bGZpbGxtZW50CiAgICAgKiBvciByZWplY3Rpb24gdmFsdWUuIFJldHVybnMgYSBuZXcgcHJvbWlzZSBmb3IgdGhlIHRyYW5zZm9ybWVkIHJlc3VsdC4KICAgICAqCiAgICAgKiBUaGUgYHRoZW4oKWAgbWV0aG9kIHJlZ2lzdGVycyBuZXcgZnVsZmlsbGVkIGFuZCByZWplY3Rpb24gaGFuZGxlcnMgd2l0aCBhIHByb21pc2UKICAgICAqIChhbGwgcGFyYW1ldGVycyBhcmUgb3B0aW9uYWwpOgogICAgICoKICAgICAqICAqIGAkb25GdWxmaWxsZWRgIHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZSBwcm9taXNlIGlzIGZ1bGZpbGxlZCBhbmQgcGFzc2VkCiAgICAgKiAgICAgdGhlIHJlc3VsdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuCiAgICAgKiAgKiBgJG9uUmVqZWN0ZWRgIHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkIGFuZCBwYXNzZWQgdGhlCiAgICAgKiAgICAgcmVhc29uIGFzIHRoZSBmaXJzdCBhcmd1bWVudC4KICAgICAqICAqIGAkb25Qcm9ncmVzc2AgKGRlcHJlY2F0ZWQpIHdpbGwgYmUgaW52b2tlZCB3aGVuZXZlciB0aGUgcHJvZHVjZXIgb2YgdGhlIHByb21pc2UKICAgICAqICAgICB0cmlnZ2VycyBwcm9ncmVzcyBub3RpZmljYXRpb25zIGFuZCBwYXNzZWQgYSBzaW5nbGUgYXJndW1lbnQgKHdoYXRldmVyIGl0CiAgICAgKiAgICAgd2FudHMpIHRvIGluZGljYXRlIHByb2dyZXNzLgogICAgICoKICAgICAqIEl0IHJldHVybnMgYSBuZXcgcHJvbWlzZSB0aGF0IHdpbGwgZnVsZmlsbCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgZWl0aGVyCiAgICAgKiBgJG9uRnVsZmlsbGVkYCBvciBgJG9uUmVqZWN0ZWRgLCB3aGljaGV2ZXIgaXMgY2FsbGVkLCBvciB3aWxsIHJlamVjdCB3aXRoCiAgICAgKiB0aGUgdGhyb3duIGV4Y2VwdGlvbiBpZiBlaXRoZXIgdGhyb3dzLgogICAgICoKICAgICAqIEEgcHJvbWlzZSBtYWtlcyB0aGUgZm9sbG93aW5nIGd1YXJhbnRlZXMgYWJvdXQgaGFuZGxlcnMgcmVnaXN0ZXJlZCBpbgogICAgICogdGhlIHNhbWUgY2FsbCB0byBgdGhlbigpYDoKICAgICAqCiAgICAgKiAgMS4gT25seSBvbmUgb2YgYCRvbkZ1bGZpbGxlZGAgb3IgYCRvblJlamVjdGVkYCB3aWxsIGJlIGNhbGxlZCwKICAgICAqICAgICAgbmV2ZXIgYm90aC4KICAgICAqICAyLiBgJG9uRnVsZmlsbGVkYCBhbmQgYCRvblJlamVjdGVkYCB3aWxsIG5ldmVyIGJlIGNhbGxlZCBtb3JlCiAgICAgKiAgICAgIHRoYW4gb25jZS4KICAgICAqICAzLiBgJG9uUHJvZ3Jlc3NgIChkZXByZWNhdGVkKSBtYXkgYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzLgogICAgICoKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRvbkZ1bGZpbGxlZAogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uUmVqZWN0ZWQKICAgICAqIEBwYXJhbSBjYWxsYWJsZXxudWxsICRvblByb2dyZXNzIFRoaXMgYXJndW1lbnQgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGFueW1vcmUuCiAgICAgKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRoZW4oY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCi8qKgogKiBAZGVwcmVjYXRlZCAyLjguMCBFeHRlcm5hbCB1c2FnZSBvZiBSZWplY3RlZFByb21pc2UgaXMgZGVwcmVjYXRlZCwgdXNlIGByZWplY3QoKWAgaW5zdGVhZC4KICovCmNsYXNzIFJlamVjdGVkUHJvbWlzZSBpbXBsZW1lbnRzIEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZSwgQ2FuY2VsbGFibGVQcm9taXNlSW50ZXJmYWNlCnsKICAgIHByaXZhdGUgJHJlYXNvbjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlYXNvbiA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRyZWFzb24gaW5zdGFuY2VvZiBQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdZb3UgY2Fubm90IGNyZWF0ZSBSZWFjdFxQcm9taXNlXFJlamVjdGVkUHJvbWlzZSB3aXRoIGEgcHJvbWlzZS4gVXNlIFJlYWN0XFByb21pc2VccmVqZWN0KCRwcm9taXNlT3JWYWx1ZSkgaW5zdGVhZC4nKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5yZWFzb24gPSAkcmVhc29uOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB0aGVuKGNhbGxhYmxlICRvbkZ1bGZpbGxlZCA9IG51bGwsIGNhbGxhYmxlICRvblJlamVjdGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUHJvZ3Jlc3MgPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkb25SZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXM7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25SZWplY3RlZCgkdGhpcy0+cmVhc29uKSk7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVqZWN0ZWRQcm9taXNlKCRleGNlcHRpb24pOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkZXhjZXB0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvblJlamVjdGVkKSB7CiAgICAgICAgICAgIHRocm93IFVuaGFuZGxlZFJlamVjdGlvbkV4Y2VwdGlvbjo6cmVzb2x2ZSgkdGhpcy0+cmVhc29uKTsKICAgICAgICB9CgogICAgICAgICRyZXN1bHQgPSAkb25SZWplY3RlZCgkdGhpcy0+cmVhc29uKTsKCiAgICAgICAgaWYgKCRyZXN1bHQgaW5zdGFuY2VvZiBzZWxmKSB7CiAgICAgICAgICAgIHRocm93IFVuaGFuZGxlZFJlamVjdGlvbkV4Y2VwdGlvbjo6cmVzb2x2ZSgkcmVzdWx0LT5yZWFzb24pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXN1bHQgaW5zdGFuY2VvZiBFeHRlbmRlZFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgJHJlc3VsdC0+ZG9uZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gb3RoZXJ3aXNlKGNhbGxhYmxlICRvblJlamVjdGVkKQogICAgewogICAgICAgIGlmICghX2NoZWNrVHlwZWhpbnQoJG9uUmVqZWN0ZWQsICR0aGlzLT5yZWFzb24pKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpczsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+dGhlbihudWxsLCAkb25SZWplY3RlZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFsd2F5cyhjYWxsYWJsZSAkb25GdWxmaWxsZWRPclJlamVjdGVkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGhlbihudWxsLCBmdW5jdGlvbiAoJHJlYXNvbikgdXNlICgkb25GdWxmaWxsZWRPclJlamVjdGVkKSB7CiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQoKSktPnRoZW4oZnVuY3Rpb24gKCkgdXNlICgkcmVhc29uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkcmVhc29uKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKGNhbGxhYmxlICRvblByb2dyZXNzKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FuY2VsKCkKICAgIHsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgpjbGFzcyBVbmhhbmRsZWRSZWplY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBcUnVudGltZUV4Y2VwdGlvbgp7CiAgICBwcml2YXRlICRyZWFzb247CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZXNvbHZlKCRyZWFzb24pCiAgICB7CiAgICAgICAgaWYgKCRyZWFzb24gaW5zdGFuY2VvZiBcRXhjZXB0aW9uIHx8ICRyZWFzb24gaW5zdGFuY2VvZiBcVGhyb3dhYmxlKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVhc29uOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBzdGF0aWMoJHJlYXNvbik7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRyZWFzb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnJlYXNvbiA9ICRyZWFzb247CgogICAgICAgICRtZXNzYWdlID0gXHNwcmludGYoJ1VuaGFuZGxlZCBSZWplY3Rpb246ICVzJywgXGpzb25fZW5jb2RlKCRyZWFzb24pKTsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkbWVzc2FnZSwgMCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlYXNvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZWFzb247CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBSZWFjdFxQcm9taXNlOwoKLyoqCiAqIEBkZXByZWNhdGVkIDIuOC4wIExhenlQcm9taXNlIGlzIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBub3QgYmUgdXNlZCBhbnltb3JlLgogKi8KY2xhc3MgTGF6eVByb21pc2UgaW1wbGVtZW50cyBFeHRlbmRlZFByb21pc2VJbnRlcmZhY2UsIENhbmNlbGxhYmxlUHJvbWlzZUludGVyZmFjZQp7CiAgICBwcml2YXRlICRmYWN0b3J5OwogICAgcHJpdmF0ZSAkcHJvbWlzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoY2FsbGFibGUgJGZhY3RvcnkpCiAgICB7CiAgICAgICAgJHRoaXMtPmZhY3RvcnkgPSAkZmFjdG9yeTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdGhlbihjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByb21pc2UoKS0+dGhlbigkb25GdWxmaWxsZWQsICRvblJlamVjdGVkLCAkb25Qcm9ncmVzcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlKCktPmRvbmUoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBvdGhlcndpc2UoY2FsbGFibGUgJG9uUmVqZWN0ZWQpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlKCktPm90aGVyd2lzZSgkb25SZWplY3RlZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFsd2F5cyhjYWxsYWJsZSAkb25GdWxmaWxsZWRPclJlamVjdGVkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZSgpLT5hbHdheXMoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKGNhbGxhYmxlICRvblByb2dyZXNzKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZSgpLT5wcm9ncmVzcygkb25Qcm9ncmVzcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNhbmNlbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9taXNlKCktPmNhbmNlbCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGludGVybmFsCiAgICAgKiBAc2VlIFByb21pc2U6OnNldHRsZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9taXNlKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnByb21pc2UpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICR0aGlzLT5wcm9taXNlID0gcmVzb2x2ZShcY2FsbF91c2VyX2Z1bmMoJHRoaXMtPmZhY3RvcnkpKTsKICAgICAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cHJvbWlzZSA9IG5ldyBSZWplY3RlZFByb21pc2UoJGV4Y2VwdGlvbik7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgJHRoaXMtPnByb21pc2UgPSBuZXcgUmVqZWN0ZWRQcm9taXNlKCRleGNlcHRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnByb21pc2U7CiAgICB9Cn0KPD9waHAKCmlmICghXGZ1bmN0aW9uX2V4aXN0cygnUmVhY3RcUHJvbWlzZVxyZXNvbHZlJykpIHsKICAgIHJlcXVpcmUgX19ESVJfXy4nL2Z1bmN0aW9ucy5waHAnOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCmNsYXNzIERlZmVycmVkIGltcGxlbWVudHMgUHJvbWlzb3JJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkcHJvbWlzZTsKICAgIHByaXZhdGUgJHJlc29sdmVDYWxsYmFjazsKICAgIHByaXZhdGUgJHJlamVjdENhbGxiYWNrOwogICAgcHJpdmF0ZSAkbm90aWZ5Q2FsbGJhY2s7CiAgICBwcml2YXRlICRjYW5jZWxsZXI7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGNhbGxhYmxlICRjYW5jZWxsZXIgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5jYW5jZWxsZXIgPSAkY2FuY2VsbGVyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9taXNlKCkKICAgIHsKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPnByb21pc2UpIHsKICAgICAgICAgICAgJHRoaXMtPnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZXNvbHZlQ2FsbGJhY2sgPSAkcmVzb2x2ZTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZWplY3RDYWxsYmFjayAgPSAkcmVqZWN0OwogICAgICAgICAgICAgICAgJHRoaXMtPm5vdGlmeUNhbGxiYWNrICA9ICRub3RpZnk7CiAgICAgICAgICAgIH0sICR0aGlzLT5jYW5jZWxsZXIpOwogICAgICAgICAgICAkdGhpcy0+Y2FuY2VsbGVyID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cHJvbWlzZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzb2x2ZSgkdmFsdWUgPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wcm9taXNlKCk7CgogICAgICAgIFxjYWxsX3VzZXJfZnVuYygkdGhpcy0+cmVzb2x2ZUNhbGxiYWNrLCAkdmFsdWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZWplY3QoJHJlYXNvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPnByb21pc2UoKTsKCiAgICAgICAgXGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5yZWplY3RDYWxsYmFjaywgJHJlYXNvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGVwcmVjYXRlZCAyLjYuMCBQcm9ncmVzcyBzdXBwb3J0IGlzIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBub3QgYmUgdXNlZCBhbnltb3JlLgogICAgICogQHBhcmFtIG1peGVkICR1cGRhdGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGlmeSgkdXBkYXRlID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvbWlzZSgpOwoKICAgICAgICBcY2FsbF91c2VyX2Z1bmMoJHRoaXMtPm5vdGlmeUNhbGxiYWNrLCAkdXBkYXRlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXByZWNhdGVkIDIuMi4wCiAgICAgKiBAc2VlIERlZmVycmVkOjpub3RpZnkoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3MoJHVwZGF0ZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm5vdGlmeSgkdXBkYXRlKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgovKioKICogQ3JlYXRlcyBhIHByb21pc2UgZm9yIHRoZSBzdXBwbGllZCBgJHByb21pc2VPclZhbHVlYC4KICoKICogSWYgYCRwcm9taXNlT3JWYWx1ZWAgaXMgYSB2YWx1ZSwgaXQgd2lsbCBiZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSBvZiB0aGUKICogcmV0dXJuZWQgcHJvbWlzZS4KICoKICogSWYgYCRwcm9taXNlT3JWYWx1ZWAgaXMgYSB0aGVuYWJsZSAoYW55IG9iamVjdCB0aGF0IHByb3ZpZGVzIGEgYHRoZW4oKWAgbWV0aG9kKSwKICogYSB0cnVzdGVkIHByb21pc2UgdGhhdCBmb2xsb3dzIHRoZSBzdGF0ZSBvZiB0aGUgdGhlbmFibGUgaXMgcmV0dXJuZWQuCiAqCiAqIElmIGAkcHJvbWlzZU9yVmFsdWVgIGlzIGEgcHJvbWlzZSwgaXQgd2lsbCBiZSByZXR1cm5lZCBhcyBpcy4KICoKICogQHBhcmFtIG1peGVkICRwcm9taXNlT3JWYWx1ZQogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIHJlc29sdmUoJHByb21pc2VPclZhbHVlID0gbnVsbCkKewogICAgaWYgKCRwcm9taXNlT3JWYWx1ZSBpbnN0YW5jZW9mIEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgIHJldHVybiAkcHJvbWlzZU9yVmFsdWU7CiAgICB9CgogICAgLy8gQ2hlY2sgaXNfb2JqZWN0KCkgZmlyc3QgdG8gYXZvaWQgbWV0aG9kX2V4aXN0cygpIHRyaWdnZXJpbmcKICAgIC8vIGNsYXNzIGF1dG9sb2FkZXJzIGlmICRwcm9taXNlT3JWYWx1ZSBpcyBhIHN0cmluZy4KICAgIGlmIChcaXNfb2JqZWN0KCRwcm9taXNlT3JWYWx1ZSkgJiYgXG1ldGhvZF9leGlzdHMoJHByb21pc2VPclZhbHVlLCAndGhlbicpKSB7CiAgICAgICAgJGNhbmNlbGxlciA9IG51bGw7CgogICAgICAgIGlmIChcbWV0aG9kX2V4aXN0cygkcHJvbWlzZU9yVmFsdWUsICdjYW5jZWwnKSkgewogICAgICAgICAgICAkY2FuY2VsbGVyID0gWyRwcm9taXNlT3JWYWx1ZSwgJ2NhbmNlbCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgdXNlICgkcHJvbWlzZU9yVmFsdWUpIHsKICAgICAgICAgICAgJHByb21pc2VPclZhbHVlLT50aGVuKCRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KTsKICAgICAgICB9LCAkY2FuY2VsbGVyKTsKICAgIH0KCiAgICByZXR1cm4gbmV3IEZ1bGZpbGxlZFByb21pc2UoJHByb21pc2VPclZhbHVlKTsKfQoKLyoqCiAqIENyZWF0ZXMgYSByZWplY3RlZCBwcm9taXNlIGZvciB0aGUgc3VwcGxpZWQgYCRwcm9taXNlT3JWYWx1ZWAuCiAqCiAqIElmIGAkcHJvbWlzZU9yVmFsdWVgIGlzIGEgdmFsdWUsIGl0IHdpbGwgYmUgdGhlIHJlamVjdGlvbiB2YWx1ZSBvZiB0aGUKICogcmV0dXJuZWQgcHJvbWlzZS4KICoKICogSWYgYCRwcm9taXNlT3JWYWx1ZWAgaXMgYSBwcm9taXNlLCBpdHMgY29tcGxldGlvbiB2YWx1ZSB3aWxsIGJlIHRoZSByZWplY3RlZAogKiB2YWx1ZSBvZiB0aGUgcmV0dXJuZWQgcHJvbWlzZS4KICoKICogVGhpcyBjYW4gYmUgdXNlZnVsIGluIHNpdHVhdGlvbnMgd2hlcmUgeW91IG5lZWQgdG8gcmVqZWN0IGEgcHJvbWlzZSB3aXRob3V0CiAqIHRocm93aW5nIGFuIGV4Y2VwdGlvbi4gRm9yIGV4YW1wbGUsIGl0IGFsbG93cyB5b3UgdG8gcHJvcGFnYXRlIGEgcmVqZWN0aW9uIHdpdGgKICogdGhlIHZhbHVlIG9mIGFub3RoZXIgcHJvbWlzZS4KICoKICogQHBhcmFtIG1peGVkICRwcm9taXNlT3JWYWx1ZQogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIHJlamVjdCgkcHJvbWlzZU9yVmFsdWUgPSBudWxsKQp7CiAgICBpZiAoJHByb21pc2VPclZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZUludGVyZmFjZSkgewogICAgICAgIHJldHVybiByZXNvbHZlKCRwcm9taXNlT3JWYWx1ZSktPnRoZW4oZnVuY3Rpb24gKCR2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkdmFsdWUpOwogICAgICAgIH0pOwogICAgfQoKICAgIHJldHVybiBuZXcgUmVqZWN0ZWRQcm9taXNlKCRwcm9taXNlT3JWYWx1ZSk7Cn0KCi8qKgogKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgcmVzb2x2ZSBvbmx5IG9uY2UgYWxsIHRoZSBpdGVtcyBpbgogKiBgJHByb21pc2VzT3JWYWx1ZXNgIGhhdmUgcmVzb2x2ZWQuIFRoZSByZXNvbHV0aW9uIHZhbHVlIG9mIHRoZSByZXR1cm5lZCBwcm9taXNlCiAqIHdpbGwgYmUgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcmVzb2x1dGlvbiB2YWx1ZXMgb2YgZWFjaCBvZiB0aGUgaXRlbXMgaW4KICogYCRwcm9taXNlc09yVmFsdWVzYC4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEByZXR1cm4gUHJvbWlzZUludGVyZmFjZQogKi8KZnVuY3Rpb24gYWxsKCRwcm9taXNlc09yVmFsdWVzKQp7CiAgICByZXR1cm4gbWFwKCRwcm9taXNlc09yVmFsdWVzLCBmdW5jdGlvbiAoJHZhbCkgewogICAgICAgIHJldHVybiAkdmFsOwogICAgfSk7Cn0KCi8qKgogKiBJbml0aWF0ZXMgYSBjb21wZXRpdGl2ZSByYWNlIHRoYXQgYWxsb3dzIG9uZSB3aW5uZXIuIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIGlzCiAqIHJlc29sdmVkIGluIHRoZSBzYW1lIHdheSB0aGUgZmlyc3Qgc2V0dGxlZCBwcm9taXNlIHJlc29sdmVzLgogKgogKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGJlY29tZSAqKmluZmluaXRlbHkgcGVuZGluZyoqIGlmICBgJHByb21pc2VzT3JWYWx1ZXNgCiAqIGNvbnRhaW5zIDAgaXRlbXMuCiAqCiAqIEBwYXJhbSBhcnJheSAkcHJvbWlzZXNPclZhbHVlcwogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIHJhY2UoJHByb21pc2VzT3JWYWx1ZXMpCnsKICAgICRjYW5jZWxsYXRpb25RdWV1ZSA9IG5ldyBDYW5jZWxsYXRpb25RdWV1ZSgpOwogICAgJGNhbmNlbGxhdGlvblF1ZXVlLT5lbnF1ZXVlKCRwcm9taXNlc09yVmFsdWVzKTsKCiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKCRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB1c2UgKCRwcm9taXNlc09yVmFsdWVzLCAkY2FuY2VsbGF0aW9uUXVldWUpIHsKICAgICAgICByZXNvbHZlKCRwcm9taXNlc09yVmFsdWVzKQogICAgICAgICAgICAtPmRvbmUoZnVuY3Rpb24gKCRhcnJheSkgdXNlICgkY2FuY2VsbGF0aW9uUXVldWUsICRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX2FycmF5KCRhcnJheSkgfHwgISRhcnJheSkgewogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAkcHJvbWlzZU9yVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VPclZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sICRyZWplY3QsICRub3RpZnkpOwogICAgfSwgJGNhbmNlbGxhdGlvblF1ZXVlKTsKfQoKLyoqCiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdoZW4gYW55IG9uZSBvZiB0aGUgaXRlbXMgaW4KICogYCRwcm9taXNlc09yVmFsdWVzYCByZXNvbHZlcy4gVGhlIHJlc29sdXRpb24gdmFsdWUgb2YgdGhlIHJldHVybmVkIHByb21pc2UKICogd2lsbCBiZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSBvZiB0aGUgdHJpZ2dlcmluZyBpdGVtLgogKgogKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIG9ubHkgcmVqZWN0IGlmICphbGwqIGl0ZW1zIGluIGAkcHJvbWlzZXNPclZhbHVlc2AgYXJlCiAqIHJlamVjdGVkLiBUaGUgcmVqZWN0aW9uIHZhbHVlIHdpbGwgYmUgYW4gYXJyYXkgb2YgYWxsIHJlamVjdGlvbiByZWFzb25zLgogKgogKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGFsc28gcmVqZWN0IHdpdGggYSBgUmVhY3RcUHJvbWlzZVxFeGNlcHRpb25cTGVuZ3RoRXhjZXB0aW9uYAogKiBpZiBgJHByb21pc2VzT3JWYWx1ZXNgIGNvbnRhaW5zIDAgaXRlbXMuCiAqCiAqIEBwYXJhbSBhcnJheSAkcHJvbWlzZXNPclZhbHVlcwogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIGFueSgkcHJvbWlzZXNPclZhbHVlcykKewogICAgcmV0dXJuIHNvbWUoJHByb21pc2VzT3JWYWx1ZXMsIDEpCiAgICAgICAgLT50aGVuKGZ1bmN0aW9uICgkdmFsKSB7CiAgICAgICAgICAgIHJldHVybiBcYXJyYXlfc2hpZnQoJHZhbCk7CiAgICAgICAgfSk7Cn0KCi8qKgogKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgcmVzb2x2ZSB3aGVuIGAkaG93TWFueWAgb2YgdGhlIHN1cHBsaWVkIGl0ZW1zIGluCiAqIGAkcHJvbWlzZXNPclZhbHVlc2AgcmVzb2x2ZS4gVGhlIHJlc29sdXRpb24gdmFsdWUgb2YgdGhlIHJldHVybmVkIHByb21pc2UKICogd2lsbCBiZSBhbiBhcnJheSBvZiBsZW5ndGggYCRob3dNYW55YCBjb250YWluaW5nIHRoZSByZXNvbHV0aW9uIHZhbHVlcyBvZiB0aGUKICogdHJpZ2dlcmluZyBpdGVtcy4KICoKICogVGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCByZWplY3QgaWYgaXQgYmVjb21lcyBpbXBvc3NpYmxlIGZvciBgJGhvd01hbnlgIGl0ZW1zCiAqIHRvIHJlc29sdmUgKHRoYXQgaXMsIHdoZW4gYChjb3VudCgkcHJvbWlzZXNPclZhbHVlcykgLSAkaG93TWFueSkgKyAxYCBpdGVtcwogKiByZWplY3QpLiBUaGUgcmVqZWN0aW9uIHZhbHVlIHdpbGwgYmUgYW4gYXJyYXkgb2YKICogYChjb3VudCgkcHJvbWlzZXNPclZhbHVlcykgLSAkaG93TWFueSkgKyAxYCByZWplY3Rpb24gcmVhc29ucy4KICoKICogVGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBhbHNvIHJlamVjdCB3aXRoIGEgYFJlYWN0XFByb21pc2VcRXhjZXB0aW9uXExlbmd0aEV4Y2VwdGlvbmAKICogaWYgYCRwcm9taXNlc09yVmFsdWVzYCBjb250YWlucyBsZXNzIGl0ZW1zIHRoYW4gYCRob3dNYW55YC4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEBwYXJhbSBpbnQgJGhvd01hbnkKICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAqLwpmdW5jdGlvbiBzb21lKCRwcm9taXNlc09yVmFsdWVzLCAkaG93TWFueSkKewogICAgJGNhbmNlbGxhdGlvblF1ZXVlID0gbmV3IENhbmNlbGxhdGlvblF1ZXVlKCk7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VzT3JWYWx1ZXMpOwoKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHVzZSAoJHByb21pc2VzT3JWYWx1ZXMsICRob3dNYW55LCAkY2FuY2VsbGF0aW9uUXVldWUpIHsKICAgICAgICByZXNvbHZlKCRwcm9taXNlc09yVmFsdWVzKQogICAgICAgICAgICAtPmRvbmUoZnVuY3Rpb24gKCRhcnJheSkgdXNlICgkaG93TWFueSwgJGNhbmNlbGxhdGlvblF1ZXVlLCAkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgewogICAgICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGFycmF5KSB8fCAkaG93TWFueSA8IDEpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzb2x2ZShbXSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRsZW4gPSBcY291bnQoJGFycmF5KTsKCiAgICAgICAgICAgICAgICBpZiAoJGxlbiA8ICRob3dNYW55KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvblxMZW5ndGhFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIFxzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lucHV0IGFycmF5IG11c3QgY29udGFpbiBhdCBsZWFzdCAlZCBpdGVtJXMgYnV0IGNvbnRhaW5zIG9ubHkgJXMgaXRlbSVzLicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaG93TWFueSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgPT09ICRob3dNYW55ID8gJycgOiAncycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMSA9PT0gJGxlbiA/ICcnIDogJ3MnCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0b1Jlc29sdmUgPSAkaG93TWFueTsKICAgICAgICAgICAgICAgICR0b1JlamVjdCAgPSAoJGxlbiAtICR0b1Jlc29sdmUpICsgMTsKICAgICAgICAgICAgICAgICR2YWx1ZXMgICAgPSBbXTsKICAgICAgICAgICAgICAgICRyZWFzb25zICAgPSBbXTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGkgPT4gJHByb21pc2VPclZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgJGZ1bGZpbGxlciA9IGZ1bmN0aW9uICgkdmFsKSB1c2UgKCRpLCAmJHZhbHVlcywgJiR0b1Jlc29sdmUsICR0b1JlamVjdCwgJHJlc29sdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0b1Jlc29sdmUgPCAxIHx8ICR0b1JlamVjdCA8IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlc1skaV0gPSAkdmFsOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT09IC0tJHRvUmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc29sdmUoJHZhbHVlcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICAkcmVqZWN0ZXIgPSBmdW5jdGlvbiAoJHJlYXNvbikgdXNlICgkaSwgJiRyZWFzb25zLCAmJHRvUmVqZWN0LCAkdG9SZXNvbHZlLCAkcmVqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdG9SZXNvbHZlIDwgMSB8fCAkdG9SZWplY3QgPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICRyZWFzb25zWyRpXSA9ICRyZWFzb247CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gLS0kdG9SZWplY3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZWplY3QoJHJlYXNvbnMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICAgICAgJGNhbmNlbGxhdGlvblF1ZXVlLT5lbnF1ZXVlKCRwcm9taXNlT3JWYWx1ZSk7CgogICAgICAgICAgICAgICAgICAgIHJlc29sdmUoJHByb21pc2VPclZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAtPmRvbmUoJGZ1bGZpbGxlciwgJHJlamVjdGVyLCAkbm90aWZ5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgJHJlamVjdCwgJG5vdGlmeSk7CiAgICB9LCAkY2FuY2VsbGF0aW9uUXVldWUpOwp9CgovKioKICogVHJhZGl0aW9uYWwgbWFwIGZ1bmN0aW9uLCBzaW1pbGFyIHRvIGBhcnJheV9tYXAoKWAsIGJ1dCBhbGxvd3MgaW5wdXQgdG8gY29udGFpbgogKiBwcm9taXNlcyBhbmQvb3IgdmFsdWVzLCBhbmQgYCRtYXBGdW5jYCBtYXkgcmV0dXJuIGVpdGhlciBhIHZhbHVlIG9yIGEgcHJvbWlzZS4KICoKICogVGhlIG1hcCBmdW5jdGlvbiByZWNlaXZlcyBlYWNoIGl0ZW0gYXMgYXJndW1lbnQsIHdoZXJlIGl0ZW0gaXMgYSBmdWxseSByZXNvbHZlZAogKiB2YWx1ZSBvZiBhIHByb21pc2Ugb3IgdmFsdWUgaW4gYCRwcm9taXNlc09yVmFsdWVzYC4KICoKICogQHBhcmFtIGFycmF5ICRwcm9taXNlc09yVmFsdWVzCiAqIEBwYXJhbSBjYWxsYWJsZSAkbWFwRnVuYwogKiBAcmV0dXJuIFByb21pc2VJbnRlcmZhY2UKICovCmZ1bmN0aW9uIG1hcCgkcHJvbWlzZXNPclZhbHVlcywgY2FsbGFibGUgJG1hcEZ1bmMpCnsKICAgICRjYW5jZWxsYXRpb25RdWV1ZSA9IG5ldyBDYW5jZWxsYXRpb25RdWV1ZSgpOwogICAgJGNhbmNlbGxhdGlvblF1ZXVlLT5lbnF1ZXVlKCRwcm9taXNlc09yVmFsdWVzKTsKCiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKCRyZXNvbHZlLCAkcmVqZWN0LCAkbm90aWZ5KSB1c2UgKCRwcm9taXNlc09yVmFsdWVzLCAkbWFwRnVuYywgJGNhbmNlbGxhdGlvblF1ZXVlKSB7CiAgICAgICAgcmVzb2x2ZSgkcHJvbWlzZXNPclZhbHVlcykKICAgICAgICAgICAgLT5kb25lKGZ1bmN0aW9uICgkYXJyYXkpIHVzZSAoJG1hcEZ1bmMsICRjYW5jZWxsYXRpb25RdWV1ZSwgJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHsKICAgICAgICAgICAgICAgIGlmICghXGlzX2FycmF5KCRhcnJheSkgfHwgISRhcnJheSkgewogICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKFtdKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRvUmVzb2x2ZSA9IFxjb3VudCgkYXJyYXkpOwogICAgICAgICAgICAgICAgJHZhbHVlcyAgICA9IFtdOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAkaSA9PiAkcHJvbWlzZU9yVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VPclZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWVzWyRpXSA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHJlc29sdmUoJHByb21pc2VPclZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAtPnRoZW4oJG1hcEZ1bmMpCiAgICAgICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgkbWFwcGVkKSB1c2UgKCRpLCAmJHZhbHVlcywgJiR0b1Jlc29sdmUsICRyZXNvbHZlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlc1skaV0gPSAkbWFwcGVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA9PT0gLS0kdG9SZXNvbHZlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXNvbHZlKCR2YWx1ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vdGlmeQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCAkcmVqZWN0LCAkbm90aWZ5KTsKICAgIH0sICRjYW5jZWxsYXRpb25RdWV1ZSk7Cn0KCi8qKgogKiBUcmFkaXRpb25hbCByZWR1Y2UgZnVuY3Rpb24sIHNpbWlsYXIgdG8gYGFycmF5X3JlZHVjZSgpYCwgYnV0IGlucHV0IG1heSBjb250YWluCiAqIHByb21pc2VzIGFuZC9vciB2YWx1ZXMsIGFuZCBgJHJlZHVjZUZ1bmNgIG1heSByZXR1cm4gZWl0aGVyIGEgdmFsdWUgb3IgYQogKiBwcm9taXNlLCAqYW5kKiBgJGluaXRpYWxWYWx1ZWAgbWF5IGJlIGEgcHJvbWlzZSBvciBhIHZhbHVlIGZvciB0aGUgc3RhcnRpbmcKICogdmFsdWUuCiAqCiAqIEBwYXJhbSBhcnJheSAkcHJvbWlzZXNPclZhbHVlcwogKiBAcGFyYW0gY2FsbGFibGUgJHJlZHVjZUZ1bmMKICogQHBhcmFtIG1peGVkICRpbml0aWFsVmFsdWUKICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAqLwpmdW5jdGlvbiByZWR1Y2UoJHByb21pc2VzT3JWYWx1ZXMsIGNhbGxhYmxlICRyZWR1Y2VGdW5jLCAkaW5pdGlhbFZhbHVlID0gbnVsbCkKewogICAgJGNhbmNlbGxhdGlvblF1ZXVlID0gbmV3IENhbmNlbGxhdGlvblF1ZXVlKCk7CiAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJHByb21pc2VzT3JWYWx1ZXMpOwoKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpIHVzZSAoJHByb21pc2VzT3JWYWx1ZXMsICRyZWR1Y2VGdW5jLCAkaW5pdGlhbFZhbHVlLCAkY2FuY2VsbGF0aW9uUXVldWUpIHsKICAgICAgICByZXNvbHZlKCRwcm9taXNlc09yVmFsdWVzKQogICAgICAgICAgICAtPmRvbmUoZnVuY3Rpb24gKCRhcnJheSkgdXNlICgkcmVkdWNlRnVuYywgJGluaXRpYWxWYWx1ZSwgJGNhbmNlbGxhdGlvblF1ZXVlLCAkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgewogICAgICAgICAgICAgICAgaWYgKCFcaXNfYXJyYXkoJGFycmF5KSkgewogICAgICAgICAgICAgICAgICAgICRhcnJheSA9IFtdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0b3RhbCA9IFxjb3VudCgkYXJyYXkpOwogICAgICAgICAgICAgICAgJGkgPSAwOwoKICAgICAgICAgICAgICAgIC8vIFdyYXAgdGhlIHN1cHBsaWVkICRyZWR1Y2VGdW5jIHdpdGggb25lIHRoYXQgaGFuZGxlcyBwcm9taXNlcyBhbmQgdGhlbgogICAgICAgICAgICAgICAgLy8gZGVsZWdhdGVzIHRvIHRoZSBzdXBwbGllZC4KICAgICAgICAgICAgICAgICR3cmFwcGVkUmVkdWNlRnVuYyA9IGZ1bmN0aW9uICgkY3VycmVudCwgJHZhbCkgdXNlICgkcmVkdWNlRnVuYywgJGNhbmNlbGxhdGlvblF1ZXVlLCAkdG90YWwsICYkaSkgewogICAgICAgICAgICAgICAgICAgICRjYW5jZWxsYXRpb25RdWV1ZS0+ZW5xdWV1ZSgkdmFsKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRjdXJyZW50CiAgICAgICAgICAgICAgICAgICAgICAgIC0+dGhlbihmdW5jdGlvbiAoJGMpIHVzZSAoJHJlZHVjZUZ1bmMsICR0b3RhbCwgJiRpLCAkdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkdmFsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+dGhlbihmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCRyZWR1Y2VGdW5jLCAkdG90YWwsICYkaSwgJGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRyZWR1Y2VGdW5jKCRjLCAkdmFsdWUsICRpKyssICR0b3RhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICAkY2FuY2VsbGF0aW9uUXVldWUtPmVucXVldWUoJGluaXRpYWxWYWx1ZSk7CgogICAgICAgICAgICAgICAgXGFycmF5X3JlZHVjZSgkYXJyYXksICR3cmFwcGVkUmVkdWNlRnVuYywgcmVzb2x2ZSgkaW5pdGlhbFZhbHVlKSkKICAgICAgICAgICAgICAgICAgICAtPmRvbmUoJHJlc29sdmUsICRyZWplY3QsICRub3RpZnkpOwogICAgICAgICAgICB9LCAkcmVqZWN0LCAkbm90aWZ5KTsKICAgIH0sICRjYW5jZWxsYXRpb25RdWV1ZSk7Cn0KCi8qKgogKiBAaW50ZXJuYWwKICovCmZ1bmN0aW9uIF9jaGVja1R5cGVoaW50KGNhbGxhYmxlICRjYWxsYmFjaywgJG9iamVjdCkKewogICAgaWYgKCFcaXNfb2JqZWN0KCRvYmplY3QpKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgaWYgKFxpc19hcnJheSgkY2FsbGJhY2spKSB7CiAgICAgICAgJGNhbGxiYWNrUmVmbGVjdGlvbiA9IG5ldyBcUmVmbGVjdGlvbk1ldGhvZCgkY2FsbGJhY2tbMF0sICRjYWxsYmFja1sxXSk7CiAgICB9IGVsc2VpZiAoXGlzX29iamVjdCgkY2FsbGJhY2spICYmICEkY2FsbGJhY2sgaW5zdGFuY2VvZiBcQ2xvc3VyZSkgewogICAgICAgICRjYWxsYmFja1JlZmxlY3Rpb24gPSBuZXcgXFJlZmxlY3Rpb25NZXRob2QoJGNhbGxiYWNrLCAnX19pbnZva2UnKTsKICAgIH0gZWxzZSB7CiAgICAgICAgJGNhbGxiYWNrUmVmbGVjdGlvbiA9IG5ldyBcUmVmbGVjdGlvbkZ1bmN0aW9uKCRjYWxsYmFjayk7CiAgICB9CgogICAgJHBhcmFtZXRlcnMgPSAkY2FsbGJhY2tSZWZsZWN0aW9uLT5nZXRQYXJhbWV0ZXJzKCk7CgogICAgaWYgKCFpc3NldCgkcGFyYW1ldGVyc1swXSkpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAkZXhwZWN0ZWRFeGNlcHRpb24gPSAkcGFyYW1ldGVyc1swXTsKCiAgICBpZiAoISRleHBlY3RlZEV4Y2VwdGlvbi0+Z2V0Q2xhc3MoKSkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHJldHVybiAkZXhwZWN0ZWRFeGNlcHRpb24tPmdldENsYXNzKCktPmlzSW5zdGFuY2UoJG9iamVjdCk7Cn0KPD9waHAKCm5hbWVzcGFjZSBSZWFjdFxQcm9taXNlOwoKaW50ZXJmYWNlIFByb21pc29ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvbWlzZSBvZiB0aGUgZGVmZXJyZWQuCiAgICAgKgogICAgICogQHJldHVybiBQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9taXNlKCk7Cn0KPD9waHAKCm5hbWVzcGFjZSBSZWFjdFxQcm9taXNlOwoKLyoqCiAqIEBkZXByZWNhdGVkIDIuOC4wIEV4dGVybmFsIHVzYWdlIG9mIEZ1bGZpbGxlZFByb21pc2UgaXMgZGVwcmVjYXRlZCwgdXNlIGByZXNvbHZlKClgIGluc3RlYWQuCiAqLwpjbGFzcyBGdWxmaWxsZWRQcm9taXNlIGltcGxlbWVudHMgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlLCBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkdmFsdWU7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR2YWx1ZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCR2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2VJbnRlcmZhY2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1lvdSBjYW5ub3QgY3JlYXRlIFJlYWN0XFByb21pc2VcRnVsZmlsbGVkUHJvbWlzZSB3aXRoIGEgcHJvbWlzZS4gVXNlIFJlYWN0XFByb21pc2VccmVzb2x2ZSgkcHJvbWlzZU9yVmFsdWUpIGluc3RlYWQuJyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdmFsdWU7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRoZW4oY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvbkZ1bGZpbGxlZCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXM7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWQoJHRoaXMtPnZhbHVlKSk7CiAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVqZWN0ZWRQcm9taXNlKCRleGNlcHRpb24pOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkZXhjZXB0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgPT09ICRvbkZ1bGZpbGxlZCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkcmVzdWx0ID0gJG9uRnVsZmlsbGVkKCR0aGlzLT52YWx1ZSk7CgogICAgICAgIGlmICgkcmVzdWx0IGluc3RhbmNlb2YgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmRvbmUoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG90aGVyd2lzZShjYWxsYWJsZSAkb25SZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFsd2F5cyhjYWxsYWJsZSAkb25GdWxmaWxsZWRPclJlamVjdGVkKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGhlbihmdW5jdGlvbiAoJHZhbHVlKSB1c2UgKCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCgpKS0+dGhlbihmdW5jdGlvbiAoKSB1c2UgKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKGNhbGxhYmxlICRvblByb2dyZXNzKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2FuY2VsKCkKICAgIHsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgpjbGFzcyBQcm9taXNlIGltcGxlbWVudHMgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlLCBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UKewogICAgcHJpdmF0ZSAkY2FuY2VsbGVyOwogICAgcHJpdmF0ZSAkcmVzdWx0OwoKICAgIHByaXZhdGUgJGhhbmRsZXJzID0gW107CiAgICBwcml2YXRlICRwcm9ncmVzc0hhbmRsZXJzID0gW107CgogICAgcHJpdmF0ZSAkcmVxdWlyZWRDYW5jZWxSZXF1ZXN0cyA9IDA7CiAgICBwcml2YXRlICRjYW5jZWxSZXF1ZXN0cyA9IDA7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGNhbGxhYmxlICRyZXNvbHZlciwgY2FsbGFibGUgJGNhbmNlbGxlciA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9ICRjYW5jZWxsZXI7CgogICAgICAgIC8vIEV4cGxpY2l0bHkgb3ZlcndyaXRlIGFyZ3VtZW50cyB3aXRoIG51bGwgdmFsdWVzIGJlZm9yZSBpbnZva2luZwogICAgICAgIC8vIHJlc29sdmVyIGZ1bmN0aW9uLiBUaGlzIGVuc3VyZSB0aGF0IHRoZXNlIGFyZ3VtZW50cyBkbyBub3Qgc2hvdyB1cAogICAgICAgIC8vIGluIHRoZSBzdGFjayB0cmFjZSBpbiBQSFAgNysgb25seS4KICAgICAgICAkY2IgPSAkcmVzb2x2ZXI7CiAgICAgICAgJHJlc29sdmVyID0gJGNhbmNlbGxlciA9IG51bGw7CiAgICAgICAgJHRoaXMtPmNhbGwoJGNiKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdGhlbihjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAobnVsbCAhPT0gJHRoaXMtPnJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3VsdC0+dGhlbigkb25GdWxmaWxsZWQsICRvblJlamVjdGVkLCAkb25Qcm9ncmVzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAobnVsbCA9PT0gJHRoaXMtPmNhbmNlbGxlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkdGhpcy0+cmVzb2x2ZXIoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpKTsKICAgICAgICB9CgogICAgICAgIC8vIFRoaXMgcHJvbWlzZSBoYXMgYSBjYW5jZWxsZXIsIHNvIHdlIGNyZWF0ZSBhIG5ldyBjaGlsZCBwcm9taXNlIHdoaWNoCiAgICAgICAgLy8gaGFzIGEgY2FuY2VsbGVyIHRoYXQgaW52b2tlcyB0aGUgcGFyZW50IGNhbmNlbGxlciBpZiBhbGwgb3RoZXIKICAgICAgICAvLyBmb2xsb3dlcnMgYXJlIGFsc28gY2FuY2VsbGVkLiBXZSBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoaXMgcHJvbWlzZQogICAgICAgIC8vIGluc3RhbmNlIGZvciB0aGUgc3RhdGljIGNhbmNlbGxlciBmdW5jdGlvbiBhbmQgY2xlYXIgdGhpcyB0byBhdm9pZAogICAgICAgIC8vIGtlZXBpbmcgYSBjeWNsaWMgcmVmZXJlbmNlIGJldHdlZW4gcGFyZW50IGFuZCBmb2xsb3dlci4KICAgICAgICAkcGFyZW50ID0gJHRoaXM7CiAgICAgICAgKyskcGFyZW50LT5yZXF1aXJlZENhbmNlbFJlcXVlc3RzOwoKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygKICAgICAgICAgICAgJHRoaXMtPnJlc29sdmVyKCRvbkZ1bGZpbGxlZCwgJG9uUmVqZWN0ZWQsICRvblByb2dyZXNzKSwKICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgpIHVzZSAoJiRwYXJlbnQpIHsKICAgICAgICAgICAgICAgIGlmICgrKyRwYXJlbnQtPmNhbmNlbFJlcXVlc3RzID49ICRwYXJlbnQtPnJlcXVpcmVkQ2FuY2VsUmVxdWVzdHMpIHsKICAgICAgICAgICAgICAgICAgICAkcGFyZW50LT5jYW5jZWwoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKG51bGwgIT09ICR0aGlzLT5yZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXN1bHQtPmRvbmUoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCwgJG9uUHJvZ3Jlc3MpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmhhbmRsZXJzW10gPSBzdGF0aWMgZnVuY3Rpb24gKEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZSAkcHJvbWlzZSkgdXNlICgkb25GdWxmaWxsZWQsICRvblJlamVjdGVkKSB7CiAgICAgICAgICAgICRwcm9taXNlCiAgICAgICAgICAgICAgICAtPmRvbmUoJG9uRnVsZmlsbGVkLCAkb25SZWplY3RlZCk7CiAgICAgICAgfTsKCiAgICAgICAgaWYgKCRvblByb2dyZXNzKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9ncmVzc0hhbmRsZXJzW10gPSAkb25Qcm9ncmVzczsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG90aGVyd2lzZShjYWxsYWJsZSAkb25SZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgc3RhdGljIGZ1bmN0aW9uICgkcmVhc29uKSB1c2UgKCRvblJlamVjdGVkKSB7CiAgICAgICAgICAgIGlmICghX2NoZWNrVHlwZWhpbnQoJG9uUmVqZWN0ZWQsICRyZWFzb24pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlamVjdGVkUHJvbWlzZSgkcmVhc29uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRvblJlamVjdGVkKCRyZWFzb24pOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4oc3RhdGljIGZ1bmN0aW9uICgkdmFsdWUpIHVzZSAoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWRPclJlamVjdGVkKCkpLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgICAgICAgICB9KTsKICAgICAgICB9LCBzdGF0aWMgZnVuY3Rpb24gKCRyZWFzb24pIHVzZSAoJG9uRnVsZmlsbGVkT3JSZWplY3RlZCkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgkb25GdWxmaWxsZWRPclJlamVjdGVkKCkpLT50aGVuKGZ1bmN0aW9uICgpIHVzZSAoJHJlYXNvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWplY3RlZFByb21pc2UoJHJlYXNvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcyhjYWxsYWJsZSAkb25Qcm9ncmVzcykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRoZW4obnVsbCwgbnVsbCwgJG9uUHJvZ3Jlc3MpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjYW5jZWwoKQogICAgewogICAgICAgIGlmIChudWxsID09PSAkdGhpcy0+Y2FuY2VsbGVyIHx8IG51bGwgIT09ICR0aGlzLT5yZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJGNhbmNlbGxlciA9ICR0aGlzLT5jYW5jZWxsZXI7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9IG51bGw7CgogICAgICAgICR0aGlzLT5jYWxsKCRjYW5jZWxsZXIpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVzb2x2ZXIoY2FsbGFibGUgJG9uRnVsZmlsbGVkID0gbnVsbCwgY2FsbGFibGUgJG9uUmVqZWN0ZWQgPSBudWxsLCBjYWxsYWJsZSAkb25Qcm9ncmVzcyA9IG51bGwpCiAgICB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgkcmVzb2x2ZSwgJHJlamVjdCwgJG5vdGlmeSkgdXNlICgkb25GdWxmaWxsZWQsICRvblJlamVjdGVkLCAkb25Qcm9ncmVzcykgewogICAgICAgICAgICBpZiAoJG9uUHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICRwcm9ncmVzc0hhbmRsZXIgPSBzdGF0aWMgZnVuY3Rpb24gKCR1cGRhdGUpIHVzZSAoJG5vdGlmeSwgJG9uUHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAkbm90aWZ5KCRvblByb2dyZXNzKCR1cGRhdGUpKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChcVGhyb3dhYmxlICRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRub3RpZnkoJGUpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vdGlmeSgkZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwcm9ncmVzc0hhbmRsZXIgPSAkbm90aWZ5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+aGFuZGxlcnNbXSA9IHN0YXRpYyBmdW5jdGlvbiAoRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlICRwcm9taXNlKSB1c2UgKCRvbkZ1bGZpbGxlZCwgJG9uUmVqZWN0ZWQsICRyZXNvbHZlLCAkcmVqZWN0LCAkcHJvZ3Jlc3NIYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAkcHJvbWlzZQogICAgICAgICAgICAgICAgICAgIC0+dGhlbigkb25GdWxmaWxsZWQsICRvblJlamVjdGVkKQogICAgICAgICAgICAgICAgICAgIC0+ZG9uZSgkcmVzb2x2ZSwgJHJlamVjdCwgJHByb2dyZXNzSGFuZGxlcik7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAkdGhpcy0+cHJvZ3Jlc3NIYW5kbGVyc1tdID0gJHByb2dyZXNzSGFuZGxlcjsKICAgICAgICB9OwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVqZWN0KCRyZWFzb24gPSBudWxsKQogICAgewogICAgICAgIGlmIChudWxsICE9PSAkdGhpcy0+cmVzdWx0KSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5zZXR0bGUocmVqZWN0KCRyZWFzb24pKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldHRsZShFeHRlbmRlZFByb21pc2VJbnRlcmZhY2UgJHByb21pc2UpCiAgICB7CiAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+dW53cmFwKCRwcm9taXNlKTsKCiAgICAgICAgaWYgKCRwcm9taXNlID09PSAkdGhpcykgewogICAgICAgICAgICAkcHJvbWlzZSA9IG5ldyBSZWplY3RlZFByb21pc2UoCiAgICAgICAgICAgICAgICBuZXcgXExvZ2ljRXhjZXB0aW9uKCdDYW5ub3QgcmVzb2x2ZSBhIHByb21pc2Ugd2l0aCBpdHNlbGYuJykKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRoYW5kbGVycyA9ICR0aGlzLT5oYW5kbGVyczsKCiAgICAgICAgJHRoaXMtPnByb2dyZXNzSGFuZGxlcnMgPSAkdGhpcy0+aGFuZGxlcnMgPSBbXTsKICAgICAgICAkdGhpcy0+cmVzdWx0ID0gJHByb21pc2U7CiAgICAgICAgJHRoaXMtPmNhbmNlbGxlciA9IG51bGw7CgogICAgICAgIGZvcmVhY2ggKCRoYW5kbGVycyBhcyAkaGFuZGxlcikgewogICAgICAgICAgICAkaGFuZGxlcigkcHJvbWlzZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdW53cmFwKCRwcm9taXNlKQogICAgewogICAgICAgICRwcm9taXNlID0gJHRoaXMtPmV4dHJhY3QoJHByb21pc2UpOwoKICAgICAgICB3aGlsZSAoJHByb21pc2UgaW5zdGFuY2VvZiBzZWxmICYmIG51bGwgIT09ICRwcm9taXNlLT5yZXN1bHQpIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkdGhpcy0+ZXh0cmFjdCgkcHJvbWlzZS0+cmVzdWx0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcHJvbWlzZTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGV4dHJhY3QoJHByb21pc2UpCiAgICB7CiAgICAgICAgaWYgKCRwcm9taXNlIGluc3RhbmNlb2YgTGF6eVByb21pc2UpIHsKICAgICAgICAgICAgJHByb21pc2UgPSAkcHJvbWlzZS0+cHJvbWlzZSgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwcm9taXNlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gY2FsbChjYWxsYWJsZSAkY2IpCiAgICB7CiAgICAgICAgLy8gRXhwbGljaXRseSBvdmVyd3JpdGUgYXJndW1lbnQgd2l0aCBudWxsIHZhbHVlLiBUaGlzIGVuc3VyZSB0aGF0IHRoaXMKICAgICAgICAvLyBhcmd1bWVudCBkb2VzIG5vdCBzaG93IHVwIGluIHRoZSBzdGFjayB0cmFjZSBpbiBQSFAgNysgb25seS4KICAgICAgICAkY2FsbGJhY2sgPSAkY2I7CiAgICAgICAgJGNiID0gbnVsbDsKCiAgICAgICAgLy8gVXNlIHJlZmxlY3Rpb24gdG8gaW5zcGVjdCBudW1iZXIgb2YgYXJndW1lbnRzIGV4cGVjdGVkIGJ5IHRoaXMgY2FsbGJhY2suCiAgICAgICAgLy8gV2UgZGlkIHNvbWUgY2FyZWZ1bCBiZW5jaG1hcmtpbmcgaGVyZTogVXNpbmcgcmVmbGVjdGlvbiB0byBhdm9pZCB1bm5lZWRlZAogICAgICAgIC8vIGZ1bmN0aW9uIGFyZ3VtZW50cyBpcyBhY3R1YWxseSBmYXN0ZXIgdGhhbiBibGluZGx5IHBhc3NpbmcgdGhlbS4KICAgICAgICAvLyBBbHNvLCB0aGlzIGhlbHBzIGF2b2lkaW5nIHVubmVjZXNzYXJ5IGZ1bmN0aW9uIGFyZ3VtZW50cyBpbiB0aGUgY2FsbCBzdGFjawogICAgICAgIC8vIGlmIHRoZSBjYWxsYmFjayBjcmVhdGVzIGFuIEV4Y2VwdGlvbiAoY3JlYXRpbmcgZ2FyYmFnZSBjeWNsZXMpLgogICAgICAgIGlmIChcaXNfYXJyYXkoJGNhbGxiYWNrKSkgewogICAgICAgICAgICAkcmVmID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCRjYWxsYmFja1swXSwgJGNhbGxiYWNrWzFdKTsKICAgICAgICB9IGVsc2VpZiAoXGlzX29iamVjdCgkY2FsbGJhY2spICYmICEkY2FsbGJhY2sgaW5zdGFuY2VvZiBcQ2xvc3VyZSkgewogICAgICAgICAgICAkcmVmID0gbmV3IFxSZWZsZWN0aW9uTWV0aG9kKCRjYWxsYmFjaywgJ19faW52b2tlJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJlZiA9IG5ldyBcUmVmbGVjdGlvbkZ1bmN0aW9uKCRjYWxsYmFjayk7CiAgICAgICAgfQogICAgICAgICRhcmdzID0gJHJlZi0+Z2V0TnVtYmVyT2ZQYXJhbWV0ZXJzKCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICgkYXJncyA9PT0gMCkgewogICAgICAgICAgICAgICAgJGNhbGxiYWNrKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBLZWVwIHJlZmVyZW5jZXMgdG8gdGhpcyBwcm9taXNlIGluc3RhbmNlIGZvciB0aGUgc3RhdGljIHJlc29sdmUvcmVqZWN0IGZ1bmN0aW9ucy4KICAgICAgICAgICAgICAgIC8vIEJ5IHVzaW5nIHN0YXRpYyBjYWxsYmFja3MgdGhhdCBhcmUgbm90IGJvdW5kIHRvIHRoaXMgaW5zdGFuY2UKICAgICAgICAgICAgICAgIC8vIGFuZCBwYXNzaW5nIHRoZSB0YXJnZXQgcHJvbWlzZSBpbnN0YW5jZSBieSByZWZlcmVuY2UsIHdlIGNhbgogICAgICAgICAgICAgICAgLy8gc3RpbGwgZXhlY3V0ZSBpdHMgcmVzb2x2aW5nIGxvZ2ljIGFuZCBzdGlsbCBjbGVhciB0aGlzCiAgICAgICAgICAgICAgICAvLyByZWZlcmVuY2Ugd2hlbiBzZXR0bGluZyB0aGUgcHJvbWlzZS4gVGhpcyBoZWxwcyBhdm9pZGluZwogICAgICAgICAgICAgICAgLy8gZ2FyYmFnZSBjeWNsZXMgaWYgYW55IGNhbGxiYWNrIGNyZWF0ZXMgYW4gRXhjZXB0aW9uLgogICAgICAgICAgICAgICAgLy8gVGhlc2UgYXNzdW1wdGlvbnMgYXJlIGNvdmVyZWQgYnkgdGhlIHRlc3Qgc3VpdGUsIHNvIGlmIHlvdSBldmVyIGZlZWwgbGlrZQogICAgICAgICAgICAgICAgLy8gcmVmYWN0b3JpbmcgdGhpcywgZ28gYWhlYWQsIGFueSBhbHRlcm5hdGl2ZSBzdWdnZXN0aW9ucyBhcmUgd2VsY29tZSEKICAgICAgICAgICAgICAgICR0YXJnZXQgPSYgJHRoaXM7CiAgICAgICAgICAgICAgICAkcHJvZ3Jlc3NIYW5kbGVycyA9JiAkdGhpcy0+cHJvZ3Jlc3NIYW5kbGVyczsKCiAgICAgICAgICAgICAgICAkY2FsbGJhY2soCiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgkdmFsdWUgPSBudWxsKSB1c2UgKCYkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0LT5zZXR0bGUocmVzb2x2ZSgkdmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YXJnZXQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZnVuY3Rpb24gKCRyZWFzb24gPSBudWxsKSB1c2UgKCYkdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdGFyZ2V0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0LT5yZWplY3QoJHJlYXNvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGZ1bmN0aW9uICgkdXBkYXRlID0gbnVsbCkgdXNlICgmJHByb2dyZXNzSGFuZGxlcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHByb2dyZXNzSGFuZGxlcnMgYXMgJGhhbmRsZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRoYW5kbGVyKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxUaHJvd2FibGUgJGUpIHsKICAgICAgICAgICAgJHRhcmdldCA9IG51bGw7CiAgICAgICAgICAgICR0aGlzLT5yZWplY3QoJGUpOwogICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRhcmdldCA9IG51bGw7CiAgICAgICAgICAgICR0aGlzLT5yZWplY3QoJGUpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2U7CgppbnRlcmZhY2UgRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlIGV4dGVuZHMgUHJvbWlzZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBwcm9taXNlJ3MgdWx0aW1hdGUgdmFsdWUgaWYgdGhlIHByb21pc2UgZnVsZmlsbHMsIG9yIGhhbmRsZXMgdGhlCiAgICAgKiB1bHRpbWF0ZSBlcnJvci4KICAgICAqCiAgICAgKiBJdCB3aWxsIGNhdXNlIGEgZmF0YWwgZXJyb3IgaWYgZWl0aGVyIGAkb25GdWxmaWxsZWRgIG9yCiAgICAgKiBgJG9uUmVqZWN0ZWRgIHRocm93IG9yIHJldHVybiBhIHJlamVjdGVkIHByb21pc2UuCiAgICAgKgogICAgICogU2luY2UgdGhlIHB1cnBvc2Ugb2YgYGRvbmUoKWAgaXMgY29uc3VtcHRpb24gcmF0aGVyIHRoYW4gdHJhbnNmb3JtYXRpb24sCiAgICAgKiBgZG9uZSgpYCBhbHdheXMgcmV0dXJucyBgbnVsbGAuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uRnVsZmlsbGVkCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkb25SZWplY3RlZAogICAgICogQHBhcmFtIGNhbGxhYmxlfG51bGwgJG9uUHJvZ3Jlc3MgVGhpcyBhcmd1bWVudCBpcyBkZXByZWNhdGVkIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYW55bW9yZS4KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG9uZShjYWxsYWJsZSAkb25GdWxmaWxsZWQgPSBudWxsLCBjYWxsYWJsZSAkb25SZWplY3RlZCA9IG51bGwsIGNhbGxhYmxlICRvblByb2dyZXNzID0gbnVsbCk7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSByZWplY3Rpb24gaGFuZGxlciBmb3IgcHJvbWlzZS4gSXQgaXMgYSBzaG9ydGN1dCBmb3I6CiAgICAgKgogICAgICogYGBgcGhwCiAgICAgKiAkcHJvbWlzZS0+dGhlbihudWxsLCAkb25SZWplY3RlZCk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBBZGRpdGlvbmFsbHksIHlvdSBjYW4gdHlwZSBoaW50IHRoZSBgJHJlYXNvbmAgYXJndW1lbnQgb2YgYCRvblJlamVjdGVkYCB0byBjYXRjaAogICAgICogb25seSBzcGVjaWZpYyBlcnJvcnMuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRvblJlamVjdGVkCiAgICAgKiBAcmV0dXJuIEV4dGVuZGVkUHJvbWlzZUludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb3RoZXJ3aXNlKGNhbGxhYmxlICRvblJlamVjdGVkKTsKCiAgICAvKioKICAgICAqIEFsbG93cyB5b3UgdG8gZXhlY3V0ZSAiY2xlYW51cCIgdHlwZSB0YXNrcyBpbiBhIHByb21pc2UgY2hhaW4uCiAgICAgKgogICAgICogSXQgYXJyYW5nZXMgZm9yIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCB0byBiZSBjYWxsZWQsIHdpdGggbm8gYXJndW1lbnRzLAogICAgICogd2hlbiB0aGUgcHJvbWlzZSBpcyBlaXRoZXIgZnVsZmlsbGVkIG9yIHJlamVjdGVkLgogICAgICoKICAgICAqICogSWYgYCRwcm9taXNlYCBmdWxmaWxscywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCByZXR1cm5zIHN1Y2Nlc3NmdWxseSwKICAgICAqICAgIGAkbmV3UHJvbWlzZWAgd2lsbCBmdWxmaWxsIHdpdGggdGhlIHNhbWUgdmFsdWUgYXMgYCRwcm9taXNlYC4KICAgICAqICogSWYgYCRwcm9taXNlYCBmdWxmaWxscywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCB0aHJvd3Mgb3IgcmV0dXJucyBhCiAgICAgKiAgICByZWplY3RlZCBwcm9taXNlLCBgJG5ld1Byb21pc2VgIHdpbGwgcmVqZWN0IHdpdGggdGhlIHRocm93biBleGNlcHRpb24gb3IKICAgICAqICAgIHJlamVjdGVkIHByb21pc2UncyByZWFzb24uCiAgICAgKiAqIElmIGAkcHJvbWlzZWAgcmVqZWN0cywgYW5kIGAkb25GdWxmaWxsZWRPclJlamVjdGVkYCByZXR1cm5zIHN1Y2Nlc3NmdWxseSwKICAgICAqICAgIGAkbmV3UHJvbWlzZWAgd2lsbCByZWplY3Qgd2l0aCB0aGUgc2FtZSByZWFzb24gYXMgYCRwcm9taXNlYC4KICAgICAqICogSWYgYCRwcm9taXNlYCByZWplY3RzLCBhbmQgYCRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWRgIHRocm93cyBvciByZXR1cm5zIGEKICAgICAqICAgIHJlamVjdGVkIHByb21pc2UsIGAkbmV3UHJvbWlzZWAgd2lsbCByZWplY3Qgd2l0aCB0aGUgdGhyb3duIGV4Y2VwdGlvbiBvcgogICAgICogICAgcmVqZWN0ZWQgcHJvbWlzZSdzIHJlYXNvbi4KICAgICAqCiAgICAgKiBgYWx3YXlzKClgIGJlaGF2ZXMgc2ltaWxhcmx5IHRvIHRoZSBzeW5jaHJvbm91cyBmaW5hbGx5IHN0YXRlbWVudC4gV2hlbiBjb21iaW5lZAogICAgICogd2l0aCBgb3RoZXJ3aXNlKClgLCBgYWx3YXlzKClgIGFsbG93cyB5b3UgdG8gd3JpdGUgY29kZSB0aGF0IGlzIHNpbWlsYXIgdG8gdGhlIGZhbWlsaWFyCiAgICAgKiBzeW5jaHJvbm91cyBjYXRjaC9maW5hbGx5IHBhaXIuCiAgICAgKgogICAgICogQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBzeW5jaHJvbm91cyBjb2RlOgogICAgICoKICAgICAqIGBgYHBocAogICAgICogdHJ5IHsKICAgICAqICAgICByZXR1cm4gZG9Tb21ldGhpbmcoKTsKICAgICAqIH0gY2F0Y2goXEV4Y2VwdGlvbiAkZSkgewogICAgICogICAgIHJldHVybiBoYW5kbGVFcnJvcigkZSk7CiAgICAgKiB9IGZpbmFsbHkgewogICAgICogICAgIGNsZWFudXAoKTsKICAgICAqIH0KICAgICAqIGBgYAogICAgICoKICAgICAqIFNpbWlsYXIgYXN5bmNocm9ub3VzIGNvZGUgKHdpdGggYGRvU29tZXRoaW5nKClgIHRoYXQgcmV0dXJucyBhIHByb21pc2UpIGNhbiBiZQogICAgICogd3JpdHRlbjoKICAgICAqCiAgICAgKiBgYGBwaHAKICAgICAqIHJldHVybiBkb1NvbWV0aGluZygpCiAgICAgKiAgICAgLT5vdGhlcndpc2UoJ2hhbmRsZUVycm9yJykKICAgICAqICAgICAtPmFsd2F5cygnY2xlYW51cCcpOwogICAgICogYGBgCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRvbkZ1bGZpbGxlZE9yUmVqZWN0ZWQKICAgICAqIEByZXR1cm4gRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbHdheXMoY2FsbGFibGUgJG9uRnVsZmlsbGVkT3JSZWplY3RlZCk7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBoYW5kbGVyIGZvciBwcm9ncmVzcyB1cGRhdGVzIGZyb20gcHJvbWlzZS4gSXQgaXMgYSBzaG9ydGN1dCBmb3I6CiAgICAgKgogICAgICogYGBgcGhwCiAgICAgKiAkcHJvbWlzZS0+dGhlbihudWxsLCBudWxsLCAkb25Qcm9ncmVzcyk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJG9uUHJvZ3Jlc3MKICAgICAqIEByZXR1cm4gRXh0ZW5kZWRQcm9taXNlSW50ZXJmYWNlCiAgICAgKiBAZGVwcmVjYXRlZCAyLjYuMCBQcm9ncmVzcyBzdXBwb3J0IGlzIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBub3QgYmUgdXNlZCBhbnltb3JlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3MoY2FsbGFibGUgJG9uUHJvZ3Jlc3MpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCmludGVyZmFjZSBDYW5jZWxsYWJsZVByb21pc2VJbnRlcmZhY2UgZXh0ZW5kcyBQcm9taXNlSW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogVGhlIGBjYW5jZWwoKWAgbWV0aG9kIG5vdGlmaWVzIHRoZSBjcmVhdG9yIG9mIHRoZSBwcm9taXNlIHRoYXQgdGhlcmUgaXMgbm8KICAgICAqIGZ1cnRoZXIgaW50ZXJlc3QgaW4gdGhlIHJlc3VsdHMgb2YgdGhlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBPbmNlIGEgcHJvbWlzZSBpcyBzZXR0bGVkIChlaXRoZXIgZnVsZmlsbGVkIG9yIHJlamVjdGVkKSwgY2FsbGluZyBgY2FuY2VsKClgIG9uCiAgICAgKiBhIHByb21pc2UgaGFzIG5vIGVmZmVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNhbmNlbCgpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUmVhY3RcUHJvbWlzZTsKCmNsYXNzIENhbmNlbGxhdGlvblF1ZXVlCnsKICAgIHByaXZhdGUgJHN0YXJ0ZWQgPSBmYWxzZTsKICAgIHByaXZhdGUgJHF1ZXVlID0gW107CgogICAgcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnN0YXJ0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnN0YXJ0ZWQgPSB0cnVlOwogICAgICAgICR0aGlzLT5kcmFpbigpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBlbnF1ZXVlKCRjYW5jZWxsYWJsZSkKICAgIHsKICAgICAgICBpZiAoIVxpc19vYmplY3QoJGNhbmNlbGxhYmxlKSB8fCAhXG1ldGhvZF9leGlzdHMoJGNhbmNlbGxhYmxlLCAndGhlbicpIHx8ICFcbWV0aG9kX2V4aXN0cygkY2FuY2VsbGFibGUsICdjYW5jZWwnKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAkbGVuZ3RoID0gXGFycmF5X3B1c2goJHRoaXMtPnF1ZXVlLCAkY2FuY2VsbGFibGUpOwoKICAgICAgICBpZiAoJHRoaXMtPnN0YXJ0ZWQgJiYgMSA9PT0gJGxlbmd0aCkgewogICAgICAgICAgICAkdGhpcy0+ZHJhaW4oKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBkcmFpbigpCiAgICB7CiAgICAgICAgZm9yICgkaSA9IGtleSgkdGhpcy0+cXVldWUpOyBpc3NldCgkdGhpcy0+cXVldWVbJGldKTsgJGkrKykgewogICAgICAgICAgICAkY2FuY2VsbGFibGUgPSAkdGhpcy0+cXVldWVbJGldOwoKICAgICAgICAgICAgJGV4Y2VwdGlvbiA9IG51bGw7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGNhbmNlbGxhYmxlLT5jYW5jZWwoKTsKICAgICAgICAgICAgfSBjYXRjaCAoXFRocm93YWJsZSAkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGV4Y2VwdGlvbikgewogICAgICAgICAgICB9CgogICAgICAgICAgICB1bnNldCgkdGhpcy0+cXVldWVbJGldKTsKCiAgICAgICAgICAgIGlmICgkZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZXhjZXB0aW9uOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+cXVldWUgPSBbXTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIFJlYWN0XFByb21pc2VcRXhjZXB0aW9uOwoKY2xhc3MgTGVuZ3RoRXhjZXB0aW9uIGV4dGVuZHMgXExlbmd0aEV4Y2VwdGlvbgp7Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9lbnRpdHlfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfZW50aXR5X2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfZW50aXR5X2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb21tZW50JywgJ0NvbW1lbnRfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvbW1lbnQgbWV0YScsICdDb21tZW50X01ldGFfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ21lbnUnLCAnTWVudV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnbWVudSBpdGVtJywgJ01lbnVfSXRlbV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnbWVudSBsb2NhdGlvbicsICdNZW51X0xvY2F0aW9uX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoCgknbmV0d29yayBtZXRhJywKCSdOZXR3b3JrX01ldGFfQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24gKCkgewoJCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQkJfQoJCX0sCgkpCik7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdvcHRpb24nLCAnT3B0aW9uX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdwb3N0JywgJ1Bvc3RfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3Bvc3QgbWV0YScsICdQb3N0X01ldGFfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3Bvc3QgdGVybScsICdQb3N0X1Rlcm1fQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3Bvc3QtdHlwZScsICdQb3N0X1R5cGVfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3NpdGUnLCAnU2l0ZV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ3NpdGUgbWV0YScsCgknU2l0ZV9NZXRhX0NvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uKCkgewoJCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQkJfQoJCQlpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAnaXNfc2l0ZV9tZXRhX3N1cHBvcnRlZCcgKSB8fCAhIGlzX3NpdGVfbWV0YV9zdXBwb3J0ZWQoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdUaGUgJXMgdGFibGUgaXMgbm90IGluc3RhbGxlZC4gUGxlYXNlIHJ1biB0aGUgbmV0d29yayBkYXRhYmFzZSB1cGdyYWRlLicsICRHTE9CQUxTWyd3cGRiJ10tPmJsb2dtZXRhICkgKTsKCQkJfQoJCX0sCgkpCik7CldQX0NMSTo6YWRkX2NvbW1hbmQoCgknc2l0ZSBvcHRpb24nLAoJJ1NpdGVfT3B0aW9uX0NvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uKCkgewoJCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQkJfQoJCX0sCgkpCik7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0YXhvbm9teScsICdUYXhvbm9teV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAndGVybScsICdUZXJtX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoCgkndGVybSBtZXRhJywKCSdUZXJtX01ldGFfQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24oKSB7CgkJCWlmICggXFdQX0NMSVxVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdSZXF1aXJlcyBXb3JkUHJlc3MgNC40IG9yIGdyZWF0ZXIuJyApOwoJCQl9CgkJfSwKCSkKKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3VzZXInLCAnVXNlcl9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAndXNlciBtZXRhJywgJ1VzZXJfTWV0YV9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKAoJJ3VzZXIgc2Vzc2lvbicsCgknVXNlcl9TZXNzaW9uX0NvbW1hbmQnLAoJYXJyYXkoCgkJJ2JlZm9yZV9pbnZva2UnID0+IGZ1bmN0aW9uKCkgewoJCQlpZiAoIFxXUF9DTElcVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC4wJywgJzwnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUmVxdWlyZXMgV29yZFByZXNzIDQuMCBvciBncmVhdGVyLicgKTsKCQkJfQoJCX0sCgkpCik7CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAndXNlciB0ZXJtJywgJ1VzZXJfVGVybV9Db21tYW5kJyApOwoKaWYgKCBjbGFzc19leGlzdHMoICdXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlJyApICkgewoJV1BfQ0xJOjphZGRfY29tbWFuZCggJ25ldHdvcmsnLCAnTmV0d29ya19OYW1lc3BhY2UnICk7Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhNZXRhOwoKLyoqCiAqIEFkZHMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBsaXN0cyB0ZXJtIGN1c3RvbSBmaWVsZHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCB0ZXJtIG1ldGEKICogICAgICQgd3AgdGVybSBtZXRhIHNldCAxMjMgYmlvICJNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KICoKICogICAgICMgR2V0IHRlcm0gbWV0YQogKiAgICAgJCB3cCB0ZXJtIG1ldGEgZ2V0IDEyMyBiaW8KICogICAgIE1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLgogKgogKiAgICAgIyBVcGRhdGUgdGVybSBtZXRhCiAqICAgICAkIHdwIHRlcm0gbWV0YSB1cGRhdGUgMTIzIGJpbyAiTWFyeSBpcyBhbiBhd2Vzb21lIFdvcmRQcmVzcyBkZXZlbG9wZXIuIgogKiAgICAgU3VjY2VzczogVXBkYXRlZCBjdXN0b20gZmllbGQgJ2JpbycuCiAqCiAqICAgICAjIERlbGV0ZSB0ZXJtIG1ldGEKICogICAgICQgd3AgdGVybSBtZXRhIGRlbGV0ZSAxMjMgYmlvCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGN1c3RvbSBmaWVsZC4KICovCmNsYXNzIFRlcm1fTWV0YV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhNZXRhIHsKCXByb3RlY3RlZCAkbWV0YV90eXBlID0gJ3Rlcm0nOwoKCS8qKgoJICogQ2hlY2sgdGhhdCB0aGUgdGVybSBJRCBleGlzdHMKCSAqCgkgKiBAcGFyYW0gaW50CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKSB7CgkJJHRlcm0gPSBnZXRfdGVybSggJG9iamVjdF9pZCApOwoJCWlmICggISAkdGVybSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBmaW5kIHRoZSB0ZXJtIHdpdGggSUQgeyRvYmplY3RfaWR9LiIgKTsKCQl9CgkJcmV0dXJuICR0ZXJtLT50ZXJtX2lkOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGFkZF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBib29sICAgJHVuaXF1ZSAgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIFdoZXRoZXIgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4gSWYgdHJ1ZSwgYW5kIHRoZSBvYmplY3QgYWxyZWFkeSBoYXMgYQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRhZGF0YSBrZXksIG5vIGNoYW5nZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIG1hZGUuCgkgKgoJICogQHJldHVybiBpbnR8ZmFsc2UgVGhlIG1ldGEgSUQgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSA9IGZhbHNlICkgewoJCXJldHVybiBhZGRfdGVybV9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgdXBkYXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIG1peGVkICAkcHJldl92YWx1ZSBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCBvbmx5IHVwZGF0ZSBleGlzdGluZwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB1cGRhdGUgYWxsIGVudHJpZXMuCgkgKgoJICogQHJldHVybiBpbnR8Ym9vbCBNZXRhIElEIGlmIHRoZSBrZXkgZGlkbid0IGV4aXN0LCB0cnVlIG9uIHN1Y2Nlc3NmdWwKCSAqICAgICAgICAgICAgICAgICAgdXBkYXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSA9ICcnICkgewoJCXJldHVybiB1cGRhdGVfdGVybV9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGdldF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgT3B0aW9uYWwuIE1ldGFkYXRhIGtleS4gSWYgbm90IHNwZWNpZmllZCwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZSBhbGwgbWV0YWRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgoJICogQHBhcmFtIGJvb2wgICAkc2luZ2xlICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBJZiB0cnVlLCByZXR1cm4gb25seQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LiBUaGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QgaWYgbWV0YV9rZXkgaXMgbm90CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQgU2luZ2xlIG1ldGFkYXRhIHZhbHVlLCBvciBhcnJheSBvZiB2YWx1ZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSA9ICcnLCAkc2luZ2xlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGdldF90ZXJtX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNpbmdsZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGRlbGV0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCBtZXRhZGF0YSBpcyBmb3IKCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJG1ldGFfdmFsdWUgIE9wdGlvbmFsLiBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm9uLXNjYWxhci4gSWYgc3BlY2lmaWVkLCBvbmx5IGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhpcyB2YWx1ZS4gT3RoZXJ3aXNlLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWxsIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzIGBudWxsLCBgZmFsc2VgLCBvciBhbiBlbXB0eSBzdHJpbmcgdG8gc2tpcAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGNoZWNrLiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaXQgaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHBvc3NpYmxlIHRvIHBhc3MgYW4gZW1wdHkgc3RyaW5nIHRvIGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aG9zZSBlbnRyaWVzIHdpdGggYW4gZW1wdHkgc3RyaW5nIGZvciBhIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3NmdWwgZGVsZXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIGRlbGV0ZV90ZXJtX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHJlZ2lzdGVyZWQgdGF4b25vbWllcy4KICoKICogU2VlIHJlZmVyZW5jZXMgZm9yIFtidWlsdC1pbiB0YXhvbm9taWVzXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9iYXNpY3MvY2F0ZWdvcmllcy10YWdzLWN1c3RvbS10YXhvbm9taWVzLykgYW5kIFtjdXN0b20gdGF4b25vbWllc10oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9wbHVnaW5zL3RheG9ub21pZXMvd29ya2luZy13aXRoLWN1c3RvbS10YXhvbm9taWVzLykuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgYWxsIHRheG9ub21pZXMgd2l0aCAncG9zdCcgb2JqZWN0IHR5cGUuCiAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1vYmplY3RfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCiAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICogICAgIHwgbmFtZSAgICAgICAgfCBwdWJsaWMgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCiAqICAgICB8IGNhdGVnb3J5ICAgIHwgMSAgICAgIHwKICogICAgIHwgcG9zdF90YWcgICAgfCAxICAgICAgfAogKiAgICAgfCBwb3N0X2Zvcm1hdCB8IDEgICAgICB8CiAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICoKICogICAgICMgR2V0IGNhcGFiaWxpdGllcyBvZiAncG9zdF90YWcnIHRheG9ub215LgogKiAgICAgJCB3cCB0YXhvbm9teSBnZXQgcG9zdF90YWcgLS1maWVsZD1jYXAKICogICAgIHsibWFuYWdlX3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJlZGl0X3Rlcm1zIjoibWFuYWdlX2NhdGVnb3JpZXMiLCJkZWxldGVfdGVybXMiOiJtYW5hZ2VfY2F0ZWdvcmllcyIsImFzc2lnbl90ZXJtcyI6ImVkaXRfcG9zdHMifQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFRheG9ub215X0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gYXJyYXkoCgkJJ25hbWUnLAoJCSdsYWJlbCcsCgkJJ2Rlc2NyaXB0aW9uJywKCQknb2JqZWN0X3R5cGUnLAoJCSdzaG93X3RhZ2Nsb3VkJywKCQknaGllcmFyY2hpY2FsJywKCQkncHVibGljJywKCSk7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggMy43LCAnPCcgKSApIHsKCQkJLy8gcmVtb3ZlIGRlc2NyaXB0aW9uIGZvciB3cCA8PSAzLjcKCQkJJHRoaXMtPmZpZWxkcyA9IGFycmF5X3ZhbHVlcyggYXJyYXlfZGlmZiggJHRoaXMtPmZpZWxkcywgYXJyYXkoICdkZXNjcmlwdGlvbicgKSApICk7CgkJfQoKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB0ZXJtIGNvdW50cyBmb3IgZWFjaCBzdXBwbGllZCB0YXhvbm9teS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHRheG9ub21pZXMgVGF4b25vbWllcyB0byBmZXRjaCBjb3VudHMgZm9yLgoJICogQHJldHVybiBhcnJheSBBc3NvY2lhdGl2ZSBhcnJheSBvZiB0ZXJtIGNvdW50cyBrZXllZCBieSB0YXhvbm9teS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9jb3VudHMoICR0YXhvbm9taWVzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBjb3VudCggJHRheG9ub21pZXMgKSA8PSAwICkgewoJCQlyZXR1cm4gW107CgkJfQoKCQkkcXVlcnkgPSAkd3BkYi0+cHJlcGFyZSgKCQkJIlNFTEVDVCBgdGF4b25vbXlgLCBDT1VOVCgqKSBBUyBgY291bnRgCgkJCUZST00gJHdwZGItPnRlcm1fdGF4b25vbXkKCQkJV0hFUkUgYHRheG9ub215YCBJTiAoIiAuIGltcGxvZGUoICcsJywgYXJyYXlfZmlsbCggMCwgY291bnQoICR0YXhvbm9taWVzICksICclcycgKSApIC4gJykKCQkJR1JPVVAgQlkgYHRheG9ub215YCcsCgkJCSR0YXhvbm9taWVzCgkJKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tICRxdWVyeSBpcyBhbHJlYWR5IHByZXBhcmVkIGFib3ZlLgoJCSRjb3VudHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICRxdWVyeSApOwoKCQkvLyBNYWtlIHN1cmUgdGhlcmUncyBhIGNvdW50IGZvciBldmVyeSBpdGVtLgoJCSRjb3VudHMgPSBhcnJheV9tZXJnZSgKCQkJYXJyYXlfZmlsbF9rZXlzKCAkdGF4b25vbWllcywgMCApLAoJCQl3cF9saXN0X3BsdWNrKCAkY291bnRzLCAnY291bnQnLCAndGF4b25vbXknICkKCQkpOwoKCQlyZXR1cm4gJGNvdW50czsKCX0KCgkvKioKCSAqIExpc3RzIHJlZ2lzdGVyZWQgdGF4b25vbWllcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgZ2V0X3RheG9ub21pZXMoKSBmaXJzdCBwYXJhbWV0ZXIgZm9yIGEgbGlzdCBvZiBhdmFpbGFibGUgZmllbGRzKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHRheG9ub215LgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyB0YXhvbm9teSBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHRlcm06CgkgKgoJICogKiBuYW1lCgkgKiAqIGxhYmVsCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIG9iamVjdF90eXBlCgkgKiAqIHNob3dfdGFnY2xvdWQKCSAqICogaGllcmFyY2hpY2FsCgkgKiAqIHB1YmxpYwoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb3VudAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhbGwgdGF4b25vbWllcy4KCSAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbmFtZSxsYWJlbCxkZXNjcmlwdGlvbixvYmplY3RfdHlwZSxzaG93X3RhZ2Nsb3VkLGhpZXJhcmNoaWNhbCxwdWJsaWMKCSAqICAgICBjYXRlZ29yeSxDYXRlZ29yaWVzLCxwb3N0LDEsMSwxCgkgKiAgICAgcG9zdF90YWcsVGFncywscG9zdCwxLCwxCgkgKiAgICAgbmF2X21lbnUsIk5hdmlnYXRpb24gTWVudXMiLCxuYXZfbWVudV9pdGVtLCwsCgkgKiAgICAgbGlua19jYXRlZ29yeSwiTGluayBDYXRlZ29yaWVzIiwsbGluaywxLCwKCSAqICAgICBwb3N0X2Zvcm1hdCxGb3JtYXQsLHBvc3QsLCwxCgkgKgoJICogICAgICMgTGlzdCBhbGwgdGF4b25vbWllcyB3aXRoICdwb3N0JyBvYmplY3QgdHlwZS4KCSAqICAgICAkIHdwIHRheG9ub215IGxpc3QgLS1vYmplY3RfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICB8IHB1YmxpYyB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBjYXRlZ29yeSAgICB8IDEgICAgICB8CgkgKiAgICAgfCBwb3N0X3RhZyAgICB8IDEgICAgICB8CgkgKiAgICAgfCBwb3N0X2Zvcm1hdCB8IDEgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddICkgKSB7CgkJCSRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddID0gYXJyYXkoICRhc3NvY19hcmdzWydvYmplY3RfdHlwZSddICk7CgkJfQoKCQkkZmllbGRzICAgICA9ICRmb3JtYXR0ZXItPmZpZWxkczsKCQkkdGF4b25vbWllcyA9IGdldF90YXhvbm9taWVzKCAkYXNzb2NfYXJncywgJ29iamVjdHMnICk7CgkJJGNvdW50cyAgICAgPSBbXTsKCgkJaWYgKCBjb3VudCggJHRheG9ub21pZXMgKSA+IDAgJiYgaW5fYXJyYXkoICdjb3VudCcsICRmaWVsZHMsIHRydWUgKSApIHsKCQkJJGNvdW50cyA9ICR0aGlzLT5nZXRfY291bnRzKCB3cF9saXN0X3BsdWNrKCAkdGF4b25vbWllcywgJ25hbWUnICkgKTsKCQl9CgoJCSR0YXhvbm9taWVzID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJHRheG9ub215ICkgdXNlICggJGNvdW50cyApIHsKCQkJCQkkdGF4b25vbXktPm9iamVjdF90eXBlID0gaW1wbG9kZSggJywgJywgJHRheG9ub215LT5vYmplY3RfdHlwZSApOwoJCQkJCSR0YXhvbm9teS0+Y291bnQgICAgICAgPSBpc3NldCggJGNvdW50c1sgJHRheG9ub215LT5uYW1lIF0gKSA/ICRjb3VudHNbICR0YXhvbm9teS0+bmFtZSBdIDogMDsKCQkJCQlyZXR1cm4gJHRheG9ub215OwoJCQl9LAoJCQkkdGF4b25vbWllcwoJCSk7CgoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICR0YXhvbm9taWVzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGRldGFpbHMgYWJvdXQgYSByZWdpc3RlcmVkIHRheG9ub215LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGF4b25vbXk+CgkgKiA6IFRheG9ub215IHNsdWcuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogSW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIHdob2xlIHRheG9ub215LCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIHRoZSBzcGVjaWZpZWQgdGF4b25vbXk6CgkgKgoJICogKiBuYW1lCgkgKiAqIGxhYmVsCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIG9iamVjdF90eXBlCgkgKiAqIHNob3dfdGFnY2xvdWQKCSAqICogaGllcmFyY2hpY2FsCgkgKiAqIHB1YmxpYwoJICogKiBsYWJlbHMKCSAqICogY2FwCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGNvdW50CgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgZGV0YWlscyBvZiBgY2F0ZWdvcnlgIHRheG9ub215LgoJICogICAgICQgd3AgdGF4b25vbXkgZ2V0IGNhdGVnb3J5IC0tZmllbGRzPW5hbWUsbGFiZWwsb2JqZWN0X3R5cGUKCSAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBGaWVsZCAgICAgICB8IFZhbHVlICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgIHwgY2F0ZWdvcnkgICB8CgkgKiAgICAgfCBsYWJlbCAgICAgICB8IENhdGVnb3JpZXMgfAoJICogICAgIHwgb2JqZWN0X3R5cGUgfCBbInBvc3QiXSAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgR2V0IGNhcGFiaWxpdGllcyBvZiAncG9zdF90YWcnIHRheG9ub215LgoJICogICAgICQgd3AgdGF4b25vbXkgZ2V0IHBvc3RfdGFnIC0tZmllbGQ9Y2FwCgkgKiAgICAgeyJtYW5hZ2VfdGVybXMiOiJtYW5hZ2VfY2F0ZWdvcmllcyIsImVkaXRfdGVybXMiOiJtYW5hZ2VfY2F0ZWdvcmllcyIsImRlbGV0ZV90ZXJtcyI6Im1hbmFnZV9jYXRlZ29yaWVzIiwiYXNzaWduX3Rlcm1zIjoiZWRpdF9wb3N0cyJ9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGF4b25vbXkgPSBnZXRfdGF4b25vbXkoICRhcmdzWzBdICk7CgoJCWlmICggISAkdGF4b25vbXkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUYXhvbm9teSB7JGFyZ3NbMF19IGRvZXNuJ3QgZXhpc3QuIiApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRkZWZhdWx0X2ZpZWxkcyA9IGFycmF5X21lcmdlKAoJCQkJJHRoaXMtPmZpZWxkcywKCQkJCWFycmF5KAoJCQkJCSdsYWJlbHMnLAoJCQkJCSdjYXAnLAoJCQkJKQoJCQkpOwoKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJGRlZmF1bHRfZmllbGRzOwoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmaWVsZHMgICAgPSAkZm9ybWF0dGVyLT5maWVsZHM7CgkJJGNvdW50ICAgICA9IDA7CgoJCWlmICggaW5fYXJyYXkoICdjb3VudCcsICRmaWVsZHMsIHRydWUgKSApIHsKCQkJJGNvdW50ID0gJHRoaXMtPmdldF9jb3VudHMoIFsgJHRheG9ub215LT5uYW1lIF0gKTsKCQkJJGNvdW50ID0gJGNvdW50WyAkdGF4b25vbXktPm5hbWUgXTsKCQl9CgoJCSRkYXRhID0gYXJyYXkoCgkJCSduYW1lJyAgICAgICAgICA9PiAkdGF4b25vbXktPm5hbWUsCgkJCSdsYWJlbCcgICAgICAgICA9PiAkdGF4b25vbXktPmxhYmVsLAoJCQknZGVzY3JpcHRpb24nICAgPT4gJHRheG9ub215LT5kZXNjcmlwdGlvbiwKCQkJJ29iamVjdF90eXBlJyAgID0+ICR0YXhvbm9teS0+b2JqZWN0X3R5cGUsCgkJCSdzaG93X3RhZ2Nsb3VkJyA9PiAkdGF4b25vbXktPnNob3dfdGFnY2xvdWQsCgkJCSdoaWVyYXJjaGljYWwnICA9PiAkdGF4b25vbXktPmhpZXJhcmNoaWNhbCwKCQkJJ3B1YmxpYycgICAgICAgID0+ICR0YXhvbm9teS0+cHVibGljLAoJCQknbGFiZWxzJyAgICAgICAgPT4gJHRheG9ub215LT5sYWJlbHMsCgkJCSdjYXAnICAgICAgICAgICA9PiAkdGF4b25vbXktPmNhcCwKCQkJJ2NvdW50JyAgICAgICAgID0+ICRjb3VudCwKCQkpOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJGRhdGEgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICd0YXhvbm9teScgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2U7CgovKioKICogUGVyZm9ybSBuZXR3b3JrLXdpZGUgb3BlcmF0aW9ucy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgR2V0IGEgbGlzdCBvZiBzdXBlci1hZG1pbnMKICogICAgICQgd3AgbmV0d29yayBtZXRhIGdldCAxIHNpdGVfYWRtaW5zCiAqICAgICBhcnJheSAoCiAqICAgICAgIDAgPT4gJ3N1cGVydmlzb3InLAogKiAgICAgKQogKi8KY2xhc3MgTmV0d29ya19OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhEQk9iamVjdDsKdXNlIFdQX0NMSVxGZXRjaGVyc1xDb21tZW50IGFzIENvbW1lbnRGZXRjaGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIENyZWF0ZXMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBtb2RlcmF0ZXMgY29tbWVudHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBjb21tZW50LgogKiAgICAgJCB3cCBjb21tZW50IGNyZWF0ZSAtLWNvbW1lbnRfcG9zdF9JRD0xNSAtLWNvbW1lbnRfY29udGVudD0iaGVsbG8gYmxvZyIgLS1jb21tZW50X2F1dGhvcj0id3AtY2xpIgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCBjb21tZW50IDkzMi4KICoKICogICAgICMgVXBkYXRlIGFuIGV4aXN0aW5nIGNvbW1lbnQuCiAqICAgICAkIHdwIGNvbW1lbnQgdXBkYXRlIDEyMyAtLWNvbW1lbnRfYXV0aG9yPSdUaGF0IEd1eScKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY29tbWVudCAxMjMuCiAqCiAqICAgICAjIERlbGV0ZSBhbiBleGlzdGluZyBjb21tZW50LgogKiAgICAgJCB3cCBjb21tZW50IGRlbGV0ZSAxMzM3IC0tZm9yY2UKICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY29tbWVudCAxMzM3LgogKgogKiAgICAgIyBEZWxldGUgYWxsIHNwYW0gY29tbWVudHMuCiAqICAgICAkIHdwIGNvbW1lbnQgZGVsZXRlICQod3AgY29tbWVudCBsaXN0IC0tc3RhdHVzPXNwYW0gLS1mb3JtYXQ9aWRzKQogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjb21tZW50IDI2NC4KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY29tbWVudCAyNjIuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ29tbWVudF9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhEQk9iamVjdCB7CgoJcHJvdGVjdGVkICRvYmpfdHlwZSAgID0gJ2NvbW1lbnQnOwoJcHJvdGVjdGVkICRvYmpfaWRfa2V5ID0gJ2NvbW1lbnRfSUQnOwoJcHJvdGVjdGVkICRvYmpfZmllbGRzID0gWwoJCSdjb21tZW50X0lEJywKCQknY29tbWVudF9wb3N0X0lEJywKCQknY29tbWVudF9kYXRlJywKCQknY29tbWVudF9hcHByb3ZlZCcsCgkJJ2NvbW1lbnRfYXV0aG9yJywKCQknY29tbWVudF9hdXRob3JfZW1haWwnLAoJXTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgQ29tbWVudEZldGNoZXIoKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgY29tbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBBc3NvY2lhdGl2ZSBhcmdzIGZvciB0aGUgbmV3IGNvbW1lbnQuIFNlZSB3cF9pbnNlcnRfY29tbWVudCgpLgoJICoKCSAqIFstLXBvcmNlbGFpbl0KCSAqIDogT3V0cHV0IGp1c3QgdGhlIG5ldyBjb21tZW50IGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IGNyZWF0ZSAtLWNvbW1lbnRfcG9zdF9JRD0xNSAtLWNvbW1lbnRfY29udGVudD0iaGVsbG8gYmxvZyIgLS1jb21tZW50X2F1dGhvcj0id3AtY2xpIgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgY29tbWVudCA5MzIuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjcmVhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X2NyZWF0ZSgKCQkJJGFyZ3MsCgkJCSRhc3NvY19hcmdzLAoJCQlmdW5jdGlvbiAoICRwYXJhbXMgKSB7CgkJCQlpZiAoIGlzc2V0KCAkcGFyYW1zWydjb21tZW50X3Bvc3RfSUQnXSApICkgewoJCQkJCSRwb3N0X2lkID0gJHBhcmFtc1snY29tbWVudF9wb3N0X0lEJ107CgkJCQkJJHBvc3QgICAgPSBnZXRfcG9zdCggJHBvc3RfaWQgKTsKCQkJCQlpZiAoICEgJHBvc3QgKSB7CgkJCQkJCXJldHVybiBuZXcgV1BfRXJyb3IoICdub19wb3N0JywgIkNhbid0IGZpbmQgcG9zdCB7JHBvc3RfaWR9LiIgKTsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCS8vIE1ha2Ugc3VyZSBpdCdzIHNldCBmb3Igb2xkZXIgV1AgdmVyc2lvbnMgZWxzZSBnZXQgdW5kZWZpbmVkIFBIUCBub3RpY2UuCgkJCQkJJHBhcmFtc1snY29tbWVudF9wb3N0X0lEJ10gPSAwOwoJCQkJfQoKCQkJCS8vIFdlIHVzZSB3cF9pbnNlcnRfY29tbWVudCgpIGluc3RlYWQgb2Ygd3BfbmV3X2NvbW1lbnQoKSB0byBzdGF5IGF0IGEgbG93IGxldmVsIGFuZAoJCQkJLy8gYXZvaWQgd3BfZGllKCkgZm9ybWF0dGVkIG1lc3NhZ2VzIG9yIG5vdGlmaWNhdGlvbnMKCQkJCSRjb21tZW50X2lkID0gd3BfaW5zZXJ0X2NvbW1lbnQoICRwYXJhbXMgKTsKCgkJCQlpZiAoICEgJGNvbW1lbnRfaWQgKSB7CgkJCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2RiX2Vycm9yJywgJ0NvdWxkIG5vdCBjcmVhdGUgY29tbWVudC4nICk7CgkJCQl9CgoJCQkJcmV0dXJuICRjb21tZW50X2lkOwoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgb25lIG9yIG1vcmUgY29tbWVudHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogT25lIG9yIG1vcmUgSURzIG9mIGNvbW1lbnRzIHRvIHVwZGF0ZS4KCSAqCgkgKiAtLTxmaWVsZD49PHZhbHVlPgoJICogOiBPbmUgb3IgbW9yZSBmaWVsZHMgdG8gdXBkYXRlLiBTZWUgd3BfdXBkYXRlX2NvbW1lbnQoKS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCB1cGRhdGUgMTIzIC0tY29tbWVudF9hdXRob3I9J1RoYXQgR3V5JwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY29tbWVudCAxMjMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X3VwZGF0ZSgKCQkJJGFyZ3MsCgkJCSRhc3NvY19hcmdzLAoJCQlmdW5jdGlvbiAoICRwYXJhbXMgKSB7CgkJCQlpZiAoICEgd3BfdXBkYXRlX2NvbW1lbnQoICRwYXJhbXMgKSApIHsKCQkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnQ291bGQgbm90IHVwZGF0ZSBjb21tZW50LicgKTsKCQkJCX0KCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgc29tZSBudW1iZXIgb2YgbmV3IGR1bW15IGNvbW1lbnRzLgoJICoKCSAqIENyZWF0ZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIG5ldyBjb21tZW50cyB3aXRoIGR1bW15IGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWNvdW50PTxudW1iZXI+XQoJICogOiBIb3cgbWFueSBjb21tZW50cyB0byBnZW5lcmF0ZT8KCSAqIC0tLQoJICogZGVmYXVsdDogMTAwCgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X2lkPTxwb3N0LWlkPl0KCSAqIDogQXNzaWduIGNvbW1lbnRzIHRvIGEgc3BlY2lmaWMgcG9zdC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogcHJvZ3Jlc3MKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcHJvZ3Jlc3MKCSAqICAgLSBpZHMKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgY29tbWVudHMgZm9yIHRoZSBnaXZlbiBwb3N0LgoJICogICAgICQgd3AgY29tbWVudCBnZW5lcmF0ZSAtLWZvcm1hdD1pZHMgLS1jb3VudD0zIC0tcG9zdF9pZD0xMjMKCSAqICAgICAxMzggMTM5IDE0MAoJICoKCSAqICAgICAjIEFkZCBtZXRhIHRvIGV2ZXJ5IGdlbmVyYXRlZCBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCBnZW5lcmF0ZSAtLWZvcm1hdD1pZHMgLS1jb3VudD0zIHwgeGFyZ3MgLWQgJyAnIC1JICUgd3AgY29tbWVudCBtZXRhIGFkZCAlIGZvbyBiYXIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdlbmVyYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknY291bnQnICAgPT4gMTAwLAoJCQkncG9zdF9pZCcgPT4gMCwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcsICdwcm9ncmVzcycgKTsKCgkJJG5vdGlmeSA9IGZhbHNlOwoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeSA9IFV0aWxzXG1ha2VfcHJvZ3Jlc3NfYmFyKCAnR2VuZXJhdGluZyBjb21tZW50cycsICRhc3NvY19hcmdzWydjb3VudCddICk7CgkJfQoKCQkkY29tbWVudF9jb3VudCA9IHdwX2NvdW50X2NvbW1lbnRzKCk7CgkJJHRvdGFsICAgICAgICAgPSAoaW50KSAkY29tbWVudF9jb3VudC0+dG90YWxfY29tbWVudHM7CgkJJGxpbWl0ICAgICAgICAgPSAkdG90YWwgKyAkYXNzb2NfYXJnc1snY291bnQnXTsKCgkJZm9yICggJGluZGV4ID0gJHRvdGFsOyAkaW5kZXggPCAkbGltaXQ7ICRpbmRleCsrICkgewoJCQkkY29tbWVudF9pZCA9IHdwX2luc2VydF9jb21tZW50KAoJCQkJWwoJCQkJCSdjb21tZW50X2NvbnRlbnQnID0+ICJDb21tZW50IHskaW5kZXh9IiwKCQkJCQknY29tbWVudF9wb3N0X0lEJyA9PiAkYXNzb2NfYXJnc1sncG9zdF9pZCddLAoJCQkJXQoJCQkpOwoJCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCQkkbm90aWZ5LT50aWNrKCk7CgkJCX0gZWxzZWlmICggJ2lkcycgPT09ICRmb3JtYXQgKSB7CgkJCQllY2hvICRjb21tZW50X2lkOwoJCQkJaWYgKCAkaW5kZXggPCAkbGltaXQgLSAxICkgewoJCQkJCWVjaG8gJyAnOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCSRub3RpZnktPmZpbmlzaCgpOwoJCX0KCgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBkYXRhIG9mIGEgc2luZ2xlIGNvbW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIGNvbW1lbnQgdG8gZ2V0LgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSBjb21tZW50LCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCBnZXQgMjEgLS1maWVsZD1jb250ZW50CgkgKiAgICAgVGhhbmtzIGZvciBhbGwgdGhlIGNvbW1lbnRzLCBldmVyeW9uZSEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRjb21tZW50X2lkID0gKGludCkgJGFyZ3NbMF07CgkJJGNvbW1lbnQgICAgPSBnZXRfY29tbWVudCggJGNvbW1lbnRfaWQgKTsKCQlpZiAoIGVtcHR5KCAkY29tbWVudCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBjb21tZW50IElELicgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkY29tbWVudF9hcnJheSAgICAgICAgPSBnZXRfb2JqZWN0X3ZhcnMoICRjb21tZW50ICk7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IGFycmF5X2tleXMoICRjb21tZW50X2FycmF5ICk7CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtKCAkY29tbWVudCApOwoJfQoKCS8qKgoJICogR2V0cyBhIGxpc3Qgb2YgY29tbWVudHMuCgkgKgoJICogRGlzcGxheSBjb21tZW50cyBiYXNlZCBvbiBhbGwgYXJndW1lbnRzIHN1cHBvcnRlZCBieQoJICogW1dQX0NvbW1lbnRfUXVlcnkoKV0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9yZWZlcmVuY2UvY2xhc3Nlcy9XUF9Db21tZW50X1F1ZXJ5L19fY29uc3RydWN0LykuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogT25lIG9yIG1vcmUgYXJncyB0byBwYXNzIHRvIFdQX0NvbW1lbnRfUXVlcnkuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBjb21tZW50LgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGlkcwoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBjb21tZW50OgoJICoKCSAqICogY29tbWVudF9JRAoJICogKiBjb21tZW50X3Bvc3RfSUQKCSAqICogY29tbWVudF9kYXRlCgkgKiAqIGNvbW1lbnRfYXBwcm92ZWQKCSAqICogY29tbWVudF9hdXRob3IKCSAqICogY29tbWVudF9hdXRob3JfZW1haWwKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogY29tbWVudF9hdXRob3JfdXJsCgkgKiAqIGNvbW1lbnRfYXV0aG9yX0lQCgkgKiAqIGNvbW1lbnRfZGF0ZV9nbXQKCSAqICogY29tbWVudF9jb250ZW50CgkgKiAqIGNvbW1lbnRfa2FybWEKCSAqICogY29tbWVudF9hZ2VudAoJICogKiBjb21tZW50X3R5cGUKCSAqICogY29tbWVudF9wYXJlbnQKCSAqICogdXNlcl9pZAoJICogKiB1cmwKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgY29tbWVudCBJRHMuCgkgKiAgICAgJCB3cCBjb21tZW50IGxpc3QgLS1maWVsZD1JRAoJICogICAgIDIyCgkgKiAgICAgMjMKCSAqICAgICAyNAoJICoKCSAqICAgICAjIExpc3QgY29tbWVudHMgb2YgYSBwb3N0LgoJICogICAgICQgd3AgY29tbWVudCBsaXN0IC0tcG9zdF9pZD0xIC0tZmllbGRzPUlELGNvbW1lbnRfZGF0ZSxjb21tZW50X2F1dGhvcgoJICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBjb21tZW50X0lEIHwgY29tbWVudF9kYXRlICAgICAgICB8IGNvbW1lbnRfYXV0aG9yIHwKCSAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMSAgICAgICAgICB8IDIwMTUtMDYtMjAgMDk6MDA6MTAgfCBNciBXb3JkUHJlc3MgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBMaXN0IGFwcHJvdmVkIGNvbW1lbnRzLgoJICogICAgICQgd3AgY29tbWVudCBsaXN0IC0tbnVtYmVyPTMgLS1zdGF0dXM9YXBwcm92ZSAtLWZpZWxkcz1JRCxjb21tZW50X2RhdGUsY29tbWVudF9hdXRob3IKCSAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgY29tbWVudF9JRCB8IGNvbW1lbnRfZGF0ZSAgICAgICAgfCBjb21tZW50X2F1dGhvciB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IDEgICAgICAgICAgfCAyMDE1LTA2LTIwIDA5OjAwOjEwIHwgTXIgV29yZFByZXNzICAgfAoJICogICAgIHwgMzAgICAgICAgICB8IDIwMTMtMDMtMTQgMTI6MzU6MDcgfCBKb2huIERvZSAgICAgICB8CgkgKiAgICAgfCAyOSAgICAgICAgIHwgMjAxMy0wMy0xNCAxMTo1NjowOCB8IEphbmUgRG9lICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoKCQlpZiAoICdpZHMnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9ICdjb21tZW50X0lEJzsKCQl9CgoJCSRhc3NvY19hcmdzID0gc2VsZjo6cHJvY2Vzc19jc3ZfYXJndW1lbnRzX3RvX2FycmF5cyggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAnY291bnQnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCSRhc3NvY19hcmdzWydjb3VudCddID0gdHJ1ZTsKCQl9CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2NvbW1lbnRfX2luJ10gKQoJCQkmJiAhIGVtcHR5KCAkYXNzb2NfYXJnc1snb3JkZXJieSddICkKCQkJJiYgJ2NvbW1lbnRfX2luJyA9PT0gJGFzc29jX2FyZ3NbJ29yZGVyYnknXQoJCQkmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJJGNvbW1lbnRzID0gW107CgkJCWZvcmVhY2ggKCAkYXNzb2NfYXJnc1snY29tbWVudF9faW4nXSBhcyAkY29tbWVudF9pZCApIHsKCQkJCSRjb21tZW50ID0gZ2V0X2NvbW1lbnQoICRjb21tZW50X2lkICk7CgkJCQlpZiAoICRjb21tZW50ICkgewoJCQkJCSRjb21tZW50c1tdID0gJGNvbW1lbnQ7CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkludmFsaWQgY29tbWVudCB7JGNvbW1lbnRfaWR9LiIgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSRxdWVyeSAgICA9IG5ldyBXUF9Db21tZW50X1F1ZXJ5KCk7CgkJCSRjb21tZW50cyA9ICRxdWVyeS0+cXVlcnkoICRhc3NvY19hcmdzICk7CgkJfQoKCQlpZiAoICdjb3VudCcgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJZWNobyAkY29tbWVudHM7CgkJfSBlbHNlIHsKCQkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkJJGNvbW1lbnRzID0gd3BfbGlzdF9wbHVjayggJGNvbW1lbnRzLCAnY29tbWVudF9JRCcgKTsKCQkJfSBlbHNlaWYgKCBpc19hcnJheSggJGNvbW1lbnRzICkgKSB7CgkJCQkkY29tbWVudHMgPSBhcnJheV9tYXAoCgkJCQkJZnVuY3Rpb24oICRjb21tZW50ICkgewoJCQkJCQkJJGNvbW1lbnQtPnVybCA9IGdldF9jb21tZW50X2xpbmsoICRjb21tZW50LT5jb21tZW50X0lEICk7CgkJCQkJCQlyZXR1cm4gJGNvbW1lbnQ7CgkJCQkJfSwKCQkJCQkkY29tbWVudHMKCQkJCSk7CgkJCX0KCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGNvbW1lbnRzICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhIGNvbW1lbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogT25lIG9yIG1vcmUgSURzIG9mIGNvbW1lbnRzIHRvIGRlbGV0ZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogU2tpcCB0aGUgdHJhc2ggYmluLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IGRlbGV0ZSAxMzM3IC0tZm9yY2UKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIGNvbW1lbnQgMTMzNy4KCSAqCgkgKiAgICAgIyBEZWxldGUgbXVsdGlwbGUgY29tbWVudHMuCgkgKiAgICAgJCB3cCBjb21tZW50IGRlbGV0ZSAxMzM3IDIzNDEgLS1mb3JjZQoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY29tbWVudCAxMzM3LgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY29tbWVudCAyMzQxLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50OjpfZGVsZXRlKAoJCQkkYXJncywKCQkJJGFzc29jX2FyZ3MsCgkJCWZ1bmN0aW9uICggJGNvbW1lbnRfaWQsICRhc3NvY19hcmdzICkgewoJCQkJJGZvcmNlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICk7CgoJCQkJJHN0YXR1cyA9IHdwX2dldF9jb21tZW50X3N0YXR1cyggJGNvbW1lbnRfaWQgKTsKCQkJCSRyZXN1bHQgPSB3cF9kZWxldGVfY29tbWVudCggJGNvbW1lbnRfaWQsICRmb3JjZSApOwoKCQkJCWlmICggISAkcmVzdWx0ICkgewoJCQkJCXJldHVybiBbICdlcnJvcicsICJGYWlsZWQgZGVsZXRpbmcgY29tbWVudCB7JGNvbW1lbnRfaWR9LiIgXTsKCQkJCX0KCgkJCQkkdmVyYiA9ICggJGZvcmNlIHx8ICd0cmFzaCcgPT09ICRzdGF0dXMgKSA/ICdEZWxldGVkJyA6ICdUcmFzaGVkJzsKCQkJCXJldHVybiBbICdzdWNjZXNzJywgInskdmVyYn0gY29tbWVudCB7JGNvbW1lbnRfaWR9LiIgXTsKCQkJfQoJCSk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjYWxsKCAkYXJncywgJHN0YXR1cywgJHN1Y2Nlc3MsICRmYWlsdXJlICkgewoJCSRjb21tZW50X2lkID0gYWJzaW50KCAkYXJncyApOwoKCQkkZnVuYyA9ICJ3cF97JHN0YXR1c31fY29tbWVudCI7CgoJCWlmICggISAkZnVuYyggJGNvbW1lbnRfaWQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJGZhaWx1cmUsICJjb21tZW50IHskY29tbWVudF9pZH0iICkgKTsKCQl9CgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkc3VjY2VzcywgImNvbW1lbnQgeyRjb21tZW50X2lkfSIgKSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc2V0X3N0YXR1cyggJGFyZ3MsICRzdGF0dXMsICRzdWNjZXNzICkgewoJCSRjb21tZW50ID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3MgKTsKCgkJJHJlc3VsdCA9IHdwX3NldF9jb21tZW50X3N0YXR1cyggJGNvbW1lbnQtPmNvbW1lbnRfSUQsICRzdGF0dXMsIHRydWUgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0ICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJ7JHN1Y2Nlc3N9IGNvbW1lbnQgeyRjb21tZW50LT5jb21tZW50X0lEfS4iICk7Cgl9CgoJLyoqCgkgKiBXYXJucyBpZiBgJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ11gIG5vdCBzZXQgYXMgdXNlZCBpbiBlbWFpbCBmcm9tLWFkZHJlc3Mgc2VudCB0byBwb3N0IGF1dGhvciBpbiBgd3Bfbm90aWZ5X3Bvc3RhdXRob3IoKWAuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfc2VydmVyX25hbWUoKSB7CgkJaWYgKCBlbXB0eSggJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnU2l0ZSB1cmwgbm90IHNldCAtIGRlZmF1bHRpbmcgdG8gXCdleGFtcGxlLmNvbVwnLiBBbnkgbm90aWZpY2F0aW9uIGVtYWlscyBzZW50IHRvIHBvc3QgYXV0aG9yIG1heSBhcHBlYXIgdG8gY29tZSBmcm9tIFwnZXhhbXBsZS5jb21cJy4nICk7CgkJCSRfU0VSVkVSWydTRVJWRVJfTkFNRSddID0gJ2V4YW1wbGUuY29tJzsKCQl9Cgl9CgoJLyoqCgkgKiBUcmFzaGVzIGEgY29tbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBUaGUgSURzIG9mIHRoZSBjb21tZW50cyB0byB0cmFzaC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFRyYXNoIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IHRyYXNoIDEzMzcKCSAqICAgICBTdWNjZXNzOiBUcmFzaGVkIGNvbW1lbnQgMTMzNy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRyYXNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRpZCApIHsKCQkJJHRoaXMtPmNhbGwoICRpZCwgX19GVU5DVElPTl9fLCAnVHJhc2hlZCAlcy4nLCAnRmFpbGVkIHRyYXNoaW5nICVzLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBVbnRyYXNoZXMgYSBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IFRoZSBJRHMgb2YgdGhlIGNvbW1lbnRzIHRvIHVudHJhc2guCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVbnRyYXNoIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IHVudHJhc2ggMTMzNwoJICogICAgIFN1Y2Nlc3M6IFVudHJhc2hlZCBjb21tZW50IDEzMzcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bnRyYXNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoaXMtPmNoZWNrX3NlcnZlcl9uYW1lKCk7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRpZCApIHsKCQkJJHRoaXMtPmNhbGwoICRpZCwgX19GVU5DVElPTl9fLCAnVW50cmFzaGVkICVzLicsICdGYWlsZWQgdW50cmFzaGluZyAlcy4nICk7CgkJfQoJfQoKCS8qKgoJICogTWFya3MgYSBjb21tZW50IGFzIHNwYW0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogVGhlIElEcyBvZiB0aGUgY29tbWVudHMgdG8gbWFyayBhcyBzcGFtLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU3BhbSBjb21tZW50LgoJICogICAgICQgd3AgY29tbWVudCBzcGFtIDEzMzcKCSAqICAgICBTdWNjZXNzOiBNYXJrZWQgYXMgc3BhbSBjb21tZW50IDEzMzcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzcGFtKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRpZCApIHsKCQkJJHRoaXMtPmNhbGwoICRpZCwgX19GVU5DVElPTl9fLCAnTWFya2VkICVzIGFzIHNwYW0uJywgJ0ZhaWxlZCBtYXJraW5nICVzIGFzIHNwYW0uJyApOwoJCX0KCX0KCgkvKioKCSAqIFVubWFya3MgYSBjb21tZW50IGFzIHNwYW0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4uLi4KCSAqIDogVGhlIElEcyBvZiB0aGUgY29tbWVudHMgdG8gdW5tYXJrIGFzIHNwYW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVbnNwYW0gY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgdW5zcGFtIDEzMzcKCSAqICAgICBTdWNjZXNzOiBVbnNwYW1tZWQgY29tbWVudCAxMzM3LgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zcGFtKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoaXMtPmNoZWNrX3NlcnZlcl9uYW1lKCk7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRpZCApIHsKCQkJJHRoaXMtPmNhbGwoICRpZCwgX19GVU5DVElPTl9fLCAnVW5zcGFtbWVkICVzLicsICdGYWlsZWQgdW5zcGFtbWluZyAlcy4nICk7CgkJfQoJfQoKCS8qKgoJICogQXBwcm92ZXMgYSBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IFRoZSBJRHMgb2YgdGhlIGNvbW1lbnRzIHRvIGFwcHJvdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBcHByb3ZlIGNvbW1lbnQuCgkgKiAgICAgJCB3cCBjb21tZW50IGFwcHJvdmUgMTMzNwoJICogICAgIFN1Y2Nlc3M6IEFwcHJvdmVkIGNvbW1lbnQgMTMzNy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFwcHJvdmUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+Y2hlY2tfc2VydmVyX25hbWUoKTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQkkdGhpcy0+c2V0X3N0YXR1cyggJGlkLCAnYXBwcm92ZScsICdBcHByb3ZlZCcgKTsKCQl9Cgl9CgoJLyoqCgkgKiBVbmFwcHJvdmVzIGEgY29tbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBUaGUgSURzIG9mIHRoZSBjb21tZW50cyB0byB1bmFwcHJvdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVbmFwcHJvdmUgY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgdW5hcHByb3ZlIDEzMzcKCSAqICAgICBTdWNjZXNzOiBVbmFwcHJvdmVkIGNvbW1lbnQgMTMzNy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuYXBwcm92ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0aGlzLT5jaGVja19zZXJ2ZXJfbmFtZSgpOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkaWQgKSB7CgkJCSR0aGlzLT5zZXRfc3RhdHVzKCAkaWQsICdob2xkJywgJ1VuYXBwcm92ZWQnICk7CgkJfQoJfQoKCS8qKgoJICogQ291bnRzIGNvbW1lbnRzLCBvbiB3aG9sZSBibG9nIG9yIG9uIGEgZ2l2ZW4gcG9zdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwb3N0LWlkPl0KCSAqIDogVGhlIElEIG9mIHRoZSBwb3N0IHRvIGNvdW50IGNvbW1lbnRzIGluLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ291bnQgY29tbWVudHMgb24gd2hvbGUgYmxvZy4KCSAqICAgICAkIHdwIGNvbW1lbnQgY291bnQKCSAqICAgICBhcHByb3ZlZDogICAgICAgIDMzCgkgKiAgICAgc3BhbTogICAgICAgICAgICAzCgkgKiAgICAgdHJhc2g6ICAgICAgICAgICAxCgkgKiAgICAgcG9zdC10cmFzaGVkOiAgICAwCgkgKiAgICAgYWxsOiAgICAgICAgICAgICAzNAoJICogICAgIG1vZGVyYXRlZDogICAgICAgMQoJICogICAgIHRvdGFsX2NvbW1lbnRzOiAgMzcKCSAqCgkgKiAgICAgIyBDb3VudCBjb21tZW50cyBpbiBhIHBvc3QuCgkgKiAgICAgJCB3cCBjb21tZW50IGNvdW50IDQyCgkgKiAgICAgYXBwcm92ZWQ6ICAgICAgICAxOQoJICogICAgIHNwYW06ICAgICAgICAgICAgMAoJICogICAgIHRyYXNoOiAgICAgICAgICAgMAoJICogICAgIHBvc3QtdHJhc2hlZDogICAgMAoJICogICAgIGFsbDogICAgICAgICAgICAgMTkKCSAqICAgICBtb2RlcmF0ZWQ6ICAgICAgIDAKCSAqICAgICB0b3RhbF9jb21tZW50czogIDE5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjb3VudCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRwb3N0X2lkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAwLCAwICk7CgoJCSRjb3VudCA9IHdwX2NvdW50X2NvbW1lbnRzKCAkcG9zdF9pZCApOwoKCQkvLyBNb3ZlIHRvdGFsX2NvbW1lbnRzIHRvIHRoZSBlbmQgb2YgdGhlIG9iamVjdAoJCSR0b3RhbCA9ICRjb3VudC0+dG90YWxfY29tbWVudHM7CgkJdW5zZXQoICRjb3VudC0+dG90YWxfY29tbWVudHMgKTsKCQkkY291bnQtPnRvdGFsX2NvbW1lbnRzID0gJHRvdGFsOwoKCQlmb3JlYWNoICggJGNvdW50IGFzICRzdGF0dXMgPT4gJGNvdW50ICkgewoJCQlXUF9DTEk6OmxpbmUoIHN0cl9wYWQoICIkc3RhdHVzOiIsIDE3ICkgLiAkY291bnQgKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZWNhbGN1bGF0ZXMgdGhlIGNvbW1lbnRfY291bnQgdmFsdWUgZm9yIG9uZSBvciBtb3JlIHBvc3RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IElEcyBmb3Igb25lIG9yIG1vcmUgcG9zdHMgdG8gdXBkYXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVjb3VudCBjb21tZW50IGZvciB0aGUgcG9zdC4KCSAqICAgICAkIHdwIGNvbW1lbnQgcmVjb3VudCAxMjMKCSAqICAgICBVcGRhdGVkIHBvc3QgMTIzIGNvbW1lbnQgY291bnQgdG8gNjcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZWNvdW50KCAkYXJncyApIHsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGlkICkgewoJCQl3cF91cGRhdGVfY29tbWVudF9jb3VudCggJGlkICk7CgkJCSRwb3N0ID0gZ2V0X3Bvc3QoICRpZCApOwoJCQlpZiAoICRwb3N0ICkgewoJCQkJV1BfQ0xJOjpsb2coICJVcGRhdGVkIHBvc3QgeyRwb3N0LT5JRH0gY29tbWVudCBjb3VudCB0byB7JHBvc3QtPmNvbW1lbnRfY291bnR9LiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlBvc3QgeyRwb3N0LT5JRH0gZG9lc24ndCBleGlzdC4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBzdGF0dXMgb2YgYSBjb21tZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgY29tbWVudCB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBzdGF0dXMgb2YgY29tbWVudC4KCSAqICAgICAkIHdwIGNvbW1lbnQgc3RhdHVzIDEzMzcKCSAqICAgICBhcHByb3ZlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGNvbW1lbnRfaWQgKSA9ICRhcmdzOwoKCQkkc3RhdHVzID0gd3BfZ2V0X2NvbW1lbnRfc3RhdHVzKCAkY29tbWVudF9pZCApOwoKCQlpZiAoIGZhbHNlID09PSAkc3RhdHVzICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGNoZWNrIHN0YXR1cyBvZiBjb21tZW50IHskY29tbWVudF9pZH0uIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bGluZSggJHN0YXR1cyApOwoJCX0KCX0KCgkvKioKCSAqIFZlcmlmaWVzIHdoZXRoZXIgYSBjb21tZW50IGV4aXN0cy4KCSAqCgkgKiBEaXNwbGF5cyBhIHN1Y2Nlc3MgbWVzc2FnZSBpZiB0aGUgY29tbWVudCBkb2VzIGV4aXN0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgY29tbWVudCB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgY29tbWVudCBleGlzdHMuCgkgKiAgICAgJCB3cCBjb21tZW50IGV4aXN0cyAxMzM3CgkgKiAgICAgU3VjY2VzczogQ29tbWVudCB3aXRoIElEIDEzMzcgZXhpc3RzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXhpc3RzKCAkYXJncyApIHsKCQlpZiAoICR0aGlzLT5mZXRjaGVyLT5nZXQoICRhcmdzWzBdICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkNvbW1lbnQgd2l0aCBJRCB7JGFyZ3NbMF19IGV4aXN0cy4iICk7CgkJfQoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoTWV0YTsKdXNlIFdQX0NMSVxGZXRjaGVyc1xDb21tZW50IGFzIENvbW1lbnRGZXRjaGVyOwoKLyoqCiAqIEFkZHMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBsaXN0cyBjb21tZW50IGN1c3RvbSBmaWVsZHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCBjb21tZW50IG1ldGEKICogICAgICQgd3AgY29tbWVudCBtZXRhIHNldCAxMjMgZGVzY3JpcHRpb24gIk1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdkZXNjcmlwdGlvbicuCiAqCiAqICAgICAjIEdldCBjb21tZW50IG1ldGEKICogICAgICQgd3AgY29tbWVudCBtZXRhIGdldCAxMjMgZGVzY3JpcHRpb24KICogICAgIE1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLgogKgogKiAgICAgIyBVcGRhdGUgY29tbWVudCBtZXRhCiAqICAgICAkIHdwIGNvbW1lbnQgbWV0YSB1cGRhdGUgMTIzIGRlc2NyaXB0aW9uICJNYXJ5IGlzIGFuIGF3ZXNvbWUgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnZGVzY3JpcHRpb24nLgogKgogKiAgICAgIyBEZWxldGUgY29tbWVudCBtZXRhCiAqICAgICAkIHdwIGNvbW1lbnQgbWV0YSBkZWxldGUgMTIzIGRlc2NyaXB0aW9uCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGN1c3RvbSBmaWVsZC4KICovCmNsYXNzIENvbW1lbnRfTWV0YV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhNZXRhIHsKCXByb3RlY3RlZCAkbWV0YV90eXBlID0gJ2NvbW1lbnQnOwoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGFkZF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBib29sICAgJHVuaXF1ZSAgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIFdoZXRoZXIgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4gSWYgdHJ1ZSwgYW5kIHRoZSBvYmplY3QgYWxyZWFkeSBoYXMgYQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRhZGF0YSBrZXksIG5vIGNoYW5nZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIG1hZGUuCgkgKgoJICogQHJldHVybiBpbnR8ZmFsc2UgVGhlIG1ldGEgSUQgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSA9IGZhbHNlICkgewoJCXJldHVybiBhZGRfY29tbWVudF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgdXBkYXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIG1peGVkICAkcHJldl92YWx1ZSBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCBvbmx5IHVwZGF0ZSBleGlzdGluZwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB1cGRhdGUgYWxsIGVudHJpZXMuCgkgKgoJICogQHJldHVybiBpbnR8Ym9vbCBNZXRhIElEIGlmIHRoZSBrZXkgZGlkbid0IGV4aXN0LCB0cnVlIG9uIHN1Y2Nlc3NmdWwKCSAqICAgICAgICAgICAgICAgICAgdXBkYXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSA9ICcnICkgewoJCXJldHVybiB1cGRhdGVfY29tbWVudF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGdldF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgT3B0aW9uYWwuIE1ldGFkYXRhIGtleS4gSWYgbm90IHNwZWNpZmllZCwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZSBhbGwgbWV0YWRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgoJICogQHBhcmFtIGJvb2wgICAkc2luZ2xlICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBJZiB0cnVlLCByZXR1cm4gb25seQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LiBUaGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QgaWYgbWV0YV9rZXkgaXMgbm90CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQgU2luZ2xlIG1ldGFkYXRhIHZhbHVlLCBvciBhcnJheSBvZiB2YWx1ZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSA9ICcnLCAkc2luZ2xlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGdldF9jb21tZW50X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNpbmdsZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGRlbGV0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCBtZXRhZGF0YSBpcyBmb3IKCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJG1ldGFfdmFsdWUgIE9wdGlvbmFsLiBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm9uLXNjYWxhci4gSWYgc3BlY2lmaWVkLCBvbmx5IGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhpcyB2YWx1ZS4gT3RoZXJ3aXNlLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWxsIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzIGBudWxsLCBgZmFsc2VgLCBvciBhbiBlbXB0eSBzdHJpbmcgdG8gc2tpcAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGNoZWNrLiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaXQgaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHBvc3NpYmxlIHRvIHBhc3MgYW4gZW1wdHkgc3RyaW5nIHRvIGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aG9zZSBlbnRyaWVzIHdpdGggYW4gZW1wdHkgc3RyaW5nIGZvciBhIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3NmdWwgZGVsZXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIGRlbGV0ZV9jb21tZW50X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCX0KCgkvKioKCSAqIENoZWNrIHRoYXQgdGhlIGNvbW1lbnQgSUQgZXhpc3RzCgkgKgoJICogQHBhcmFtIGludAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICkgewoJCSRmZXRjaGVyID0gbmV3IENvbW1lbnRGZXRjaGVyKCk7CgkJJGNvbW1lbnQgPSAkZmV0Y2hlci0+Z2V0X2NoZWNrKCAkb2JqZWN0X2lkICk7CgkJcmV0dXJuICRjb21tZW50LT5jb21tZW50X0lEOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoREJPYmplY3Q7CnVzZSBXUF9DTElcRW50aXR5XFV0aWxzIGFzIEVudGl0eVV0aWxzOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFNpdGUgYXMgU2l0ZUZldGNoZXI7CnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcSXRlcmF0b3JzXENTViBhcyBDc3ZJdGVyYXRvcjsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBNYW5hZ2VzIHVzZXJzLCBhbG9uZyB3aXRoIHRoZWlyIHJvbGVzLCBjYXBhYmlsaXRpZXMsIGFuZCBtZXRhLgogKgogKiBTZWUgcmVmZXJlbmNlcyBmb3IgW1JvbGVzIGFuZCBDYXBhYmlsaXRpZXNdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9Sb2xlc19hbmRfQ2FwYWJpbGl0aWVzKSBhbmQgW1dQIFVzZXIgY2xhc3NdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfVXNlcikuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgdXNlciBJRHMKICogICAgICQgd3AgdXNlciBsaXN0IC0tZmllbGQ9SUQKICogICAgIDEKICoKICogICAgICMgQ3JlYXRlIGEgbmV3IHVzZXIuCiAqICAgICAkIHdwIHVzZXIgY3JlYXRlIGJvYiBib2JAZXhhbXBsZS5jb20gLS1yb2xlPWF1dGhvcgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCB1c2VyIDMuCiAqICAgICBQYXNzd29yZDogazkqKiZJNHZOSCgmCiAqCiAqICAgICAjIFVwZGF0ZSBhbiBleGlzdGluZyB1c2VyLgogKiAgICAgJCB3cCB1c2VyIHVwZGF0ZSAxMjMgLS1kaXNwbGF5X25hbWU9TWFyeSAtLXVzZXJfcGFzcz1tYXJ5cGFzcwogKiAgICAgU3VjY2VzczogVXBkYXRlZCB1c2VyIDEyMy4KICoKICogICAgICMgRGVsZXRlIHVzZXIgMTIzIGFuZCByZWFzc2lnbiBwb3N0cyB0byB1c2VyIDU2NwogKiAgICAgJCB3cCB1c2VyIGRlbGV0ZSAxMjMgLS1yZWFzc2lnbj01NjcKICogICAgIFN1Y2Nlc3M6IFJlbW92ZWQgdXNlciAxMjMgZnJvbSBodHRwOi8vZXhhbXBsZS5jb20KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBVc2VyX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAndXNlcic7Cglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ0lEJywKCQkndXNlcl9sb2dpbicsCgkJJ2Rpc3BsYXlfbmFtZScsCgkJJ3VzZXJfZW1haWwnLAoJCSd1c2VyX3JlZ2lzdGVyZWQnLAoJCSdyb2xlcycsCgldOwoKCXByaXZhdGUgJGNhcF9maWVsZHMgPSBbCgkJJ25hbWUnLAoJXTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgICAgID0gbmV3IFVzZXJGZXRjaGVyKCk7CgkJJHRoaXMtPnNpdGVmZXRjaGVyID0gbmV3IFNpdGVGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBMaXN0cyB1c2Vycy4KCSAqCgkgKiBEaXNwbGF5IFdvcmRQcmVzcyB1c2VycyBiYXNlZCBvbiBhbGwgYXJndW1lbnRzIHN1cHBvcnRlZCBieQoJICogW1dQX1VzZXJfUXVlcnkoKV0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy9yZWZlcmVuY2UvY2xhc3Nlcy93cF91c2VyX3F1ZXJ5L3ByZXBhcmVfcXVlcnkvKS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tcm9sZT08cm9sZT5dCgkgKiA6IE9ubHkgZGlzcGxheSB1c2VycyB3aXRoIGEgY2VydGFpbiByb2xlLgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogQ29udHJvbCBvdXRwdXQgYnkgb25lIG9yIG1vcmUgYXJndW1lbnRzIG9mIFdQX1VzZXJfUXVlcnkoKS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBMaXN0IGFsbCB1c2VycyBpbiB0aGUgbmV0d29yayBmb3IgbXVsdGlzaXRlLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggdXNlci4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggdXNlcjoKCSAqCgkgKiAqIElECgkgKiAqIHVzZXJfbG9naW4KCSAqICogZGlzcGxheV9uYW1lCgkgKiAqIHVzZXJfZW1haWwKCSAqICogdXNlcl9yZWdpc3RlcmVkCgkgKiAqIHJvbGVzCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHVzZXJfcGFzcwoJICogKiB1c2VyX25pY2VuYW1lCgkgKiAqIHVzZXJfdXJsCgkgKiAqIHVzZXJfYWN0aXZhdGlvbl9rZXkKCSAqICogdXNlcl9zdGF0dXMKCSAqICogc3BhbQoJICogKiBkZWxldGVkCgkgKiAqIGNhcHMKCSAqICogY2FwX2tleQoJICogKiBhbGxjYXBzCgkgKiAqIGZpbHRlcgoJICogKiB1cmwKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciBJRHMKCSAqICAgICAkIHdwIHVzZXIgbGlzdCAtLWZpZWxkPUlECgkgKiAgICAgMQoJICoKCSAqICAgICAjIExpc3QgdXNlcnMgd2l0aCBhZG1pbmlzdHJhdG9yIHJvbGUKCSAqICAgICAkIHdwIHVzZXIgbGlzdCAtLXJvbGU9YWRtaW5pc3RyYXRvciAtLWZvcm1hdD1jc3YKCSAqICAgICBJRCx1c2VyX2xvZ2luLGRpc3BsYXlfbmFtZSx1c2VyX2VtYWlsLHVzZXJfcmVnaXN0ZXJlZCxyb2xlcwoJICogICAgIDEsc3VwZXJ2aXNvcixzdXBlcnZpc29yLHN1cGVydmlzb3JAZ21haWwuY29tLCIyMDE2LTA2LTAzIDA0OjM3OjAwIixhZG1pbmlzdHJhdG9yCgkgKgoJICogICAgICMgTGlzdCB1c2VycyB3aXRoIG9ubHkgZ2l2ZW4gZmllbGRzCgkgKiAgICAgJCB3cCB1c2VyIGxpc3QgLS1maWVsZHM9ZGlzcGxheV9uYW1lLHVzZXJfZW1haWwgLS1mb3JtYXQ9anNvbgoJICogICAgIFt7ImRpc3BsYXlfbmFtZSI6InN1cGVydmlzb3IiLCJ1c2VyX2VtYWlsIjoic3VwZXJ2aXNvckBnbWFpbC5jb20ifV0KCSAqCgkgKiAgICAgIyBMaXN0IHVzZXJzIG9yZGVyZWQgYnkgdGhlICdsYXN0X2FjdGl2aXR5JyBtZXRhIHZhbHVlLgoJICogICAgICQgd3AgdXNlciBsaXN0IC0tbWV0YV9rZXk9bGFzdF9hY3Rpdml0eSAtLW9yZGVyYnk9bWV0YV92YWx1ZV9udW0KCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkgKSB7CgkJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCQl9CgkJCSRhc3NvY19hcmdzWydibG9nX2lkJ10gPSAwOwoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJCSRmaWVsZHMgICAgICAgICAgICAgICA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJCQkkYXNzb2NfYXJnc1snZmllbGRzJ10gPSBhcnJheV9kaWZmKCAkZmllbGRzLCBbICdyb2xlcycgXSApOwoJCQl9IGVsc2UgewoJCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gYXJyYXlfZGlmZiggJHRoaXMtPm9ial9maWVsZHMsIFsgJ3JvbGVzJyBdICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpbl9hcnJheSggJGZvcm1hdHRlci0+Zm9ybWF0LCBbICdpZHMnLCAnY291bnQnIF0sIHRydWUgKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJfSBlbHNlIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJ2FsbF93aXRoX21ldGEnOwoJCX0KCgkJJGFzc29jX2FyZ3NbJ2NvdW50X3RvdGFsJ10gPSBmYWxzZTsKCQkkYXNzb2NfYXJncyAgICAgICAgICAgICAgICA9IHNlbGY6OnByb2Nlc3NfY3N2X2FyZ3VtZW50c190b19hcnJheXMoICRhc3NvY19hcmdzICk7CgkJJHVzZXJzICAgICAgICAgICAgICAgICAgICAgPSBnZXRfdXNlcnMoICRhc3NvY19hcmdzICk7CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJZWNobyBpbXBsb2RlKCAnICcsICR1c2VycyApOwoJCX0gZWxzZWlmICggJ2NvdW50JyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdXNlcnMgKTsKCQl9IGVsc2UgewoJCQkkaXRlcmF0b3IgPSBVdGlsc1xpdGVyYXRvcl9tYXAoCgkJCQkkdXNlcnMsCgkJCQlmdW5jdGlvbiAoICR1c2VyICkgewoJCQkJCWlmICggISBpc19vYmplY3QoICR1c2VyICkgKSB7CgkJCQkJCXJldHVybiAkdXNlcjsKCQkJCQl9CgoJCQkJCSR1c2VyLT5yb2xlcyA9IGltcGxvZGUoICcsJywgJHVzZXItPnJvbGVzICk7CgkJCQkJJHVzZXItPnVybCAgID0gZ2V0X2F1dGhvcl9wb3N0c191cmwoICR1c2VyLT5JRCwgJHVzZXItPnVzZXJfbmljZW5hbWUgKTsKCQkJCQlyZXR1cm4gJHVzZXI7CgkJCQl9CgkJCSk7CgoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlcmF0b3IgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGRldGFpbHMgYWJvdXQgYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgdXNlciBsb2dpbi4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBJbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgd2hvbGUgdXNlciwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBHZXQgYSBzcGVjaWZpYyBzdWJzZXQgb2YgdGhlIHVzZXIncyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHVzZXIKCSAqICAgICAkIHdwIHVzZXIgZ2V0IDEyIC0tZmllbGQ9bG9naW4KCSAqICAgICBzdXBlcnZpc29yCgkgKgoJICogICAgICMgR2V0IHVzZXIgYW5kIGV4cG9ydCB0byBKU09OIGZpbGUKCSAqICAgICAkIHdwIHVzZXIgZ2V0IGJvYiAtLWZvcm1hdD1qc29uID4gYm9iLmpzb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyICAgICAgICAgICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSR1c2VyX2RhdGEgICAgICAgICAgPSAkdXNlci0+dG9fYXJyYXkoKTsKCQkkdXNlcl9kYXRhWydyb2xlcyddID0gaW1wbG9kZSggJywgJywgJHVzZXItPnJvbGVzICk7CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICR1c2VyX2RhdGEgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgb25lIG9yIG1vcmUgdXNlcnMgZnJvbSB0aGUgY3VycmVudCBzaXRlLgoJICoKCSAqIE9uIG11bHRpc2l0ZSwgYHdwIHVzZXIgZGVsZXRlYCBvbmx5IHJlbW92ZXMgdGhlIHVzZXIgZnJvbSB0aGUgY3VycmVudAoJICogc2l0ZS4gSW5jbHVkZSBgLS1uZXR3b3JrYCB0byBhbHNvIHJlbW92ZSB0aGUgdXNlciBmcm9tIHRoZSBkYXRhYmFzZSwgYnV0CgkgKiBtYWtlIHN1cmUgdG8gcmVhc3NpZ24gdGhlaXIgcG9zdHMgcHJpb3IgdG8gZGVsZXRpbmcgdGhlIHVzZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPi4uLgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlcihzKSB0byBkZWxldGUuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogT24gbXVsdGlzaXRlLCBkZWxldGUgdGhlIHVzZXIgZnJvbSB0aGUgZW50aXJlIG5ldHdvcmsuCgkgKgoJICogWy0tcmVhc3NpZ249PHVzZXItaWQ+XQoJICogOiBVc2VyIElEIHRvIHJlYXNzaWduIHRoZSBwb3N0cyB0by4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gYW55IGNvbmZpcm1hdGlvbiBwcm9tcHRzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHVzZXIgMTIzIGFuZCByZWFzc2lnbiBwb3N0cyB0byB1c2VyIDU2NwoJICogICAgICQgd3AgdXNlciBkZWxldGUgMTIzIC0tcmVhc3NpZ249NTY3CgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCB1c2VyIDEyMyBmcm9tIGh0dHA6Ly9leGFtcGxlLmNvbQoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgY29udHJpYnV0b3JzIGFuZCByZWFzc2lnbiB0aGVpciBwb3N0cyB0byB1c2VyIDIKCSAqICAgICAkIHdwIHVzZXIgZGVsZXRlICQod3AgdXNlciBsaXN0IC0tcm9sZT1jb250cmlidXRvciAtLWZpZWxkPUlEKSAtLXJlYXNzaWduPTIKCSAqICAgICBTdWNjZXNzOiBSZW1vdmVkIHVzZXIgODEzIGZyb20gaHR0cDovL2V4YW1wbGUuY29tCgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCB1c2VyIDU3OCBmcm9tIGh0dHA6Ly9leGFtcGxlLmNvbQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG5ldHdvcmsgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKSAmJiBpc19tdWx0aXNpdGUoKTsKCQkkcmVhc3NpZ24gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWFzc2lnbicgKTsKCgkJaWYgKCAkbmV0d29yayAmJiAkcmVhc3NpZ24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSZWFzc2lnbmluZyBjb250ZW50IHRvIGEgZGlmZmVyZW50IHVzZXIgaXMgbm90IHN1cHBvcnRlZCBvbiBtdWx0aXNpdGUuJyApOwoJCX0KCgkJaWYgKCAhICRyZWFzc2lnbiApIHsKCQkJV1BfQ0xJOjpjb25maXJtKCAnLS1yZWFzc2lnbiBwYXJhbWV0ZXIgbm90IHBhc3NlZC4gQWxsIGFzc29jaWF0ZWQgcG9zdHMgd2lsbCBiZSBkZWxldGVkLiBQcm9jZWVkPycsICRhc3NvY19hcmdzICk7CgkJfQoKCQkkdXNlcnMgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgoJCXBhcmVudDo6X2RlbGV0ZSgKCQkJJHVzZXJzLAoJCQkkYXNzb2NfYXJncywKCQkJZnVuY3Rpb24gKCAkdXNlciApIHVzZSAoICRuZXR3b3JrLCAkcmVhc3NpZ24gKSB7CgkJCQkkdXNlcl9pZCA9ICR1c2VyLT5JRDsKCgkJCQlpZiAoICRuZXR3b3JrICkgewoJCQkJCSRyZXN1bHQgID0gd3BtdV9kZWxldGVfdXNlciggJHVzZXJfaWQgKTsKCQkJCQkkbWVzc2FnZSA9ICJEZWxldGVkIHVzZXIgeyR1c2VyX2lkfS4iOwoJCQkJfSBlbHNlIHsKCQkJCQkkcmVzdWx0ICA9IHdwX2RlbGV0ZV91c2VyKCAkdXNlcl9pZCwgJHJlYXNzaWduICk7CgkJCQkJJG1lc3NhZ2UgPSAiUmVtb3ZlZCB1c2VyIHskdXNlcl9pZH0gZnJvbSAiIC4gaG9tZV91cmwoKSAuICcuJzsKCQkJCX0KCgkJCQlpZiAoICEgJHJlc3VsdCApIHsKCQkJCQlyZXR1cm4gWyAnZXJyb3InLCAiRmFpbGVkIGRlbGV0aW5nIHVzZXIgeyR1c2VyX2lkfS4iIF07CgkJCQl9CgoJCQkJcmV0dXJuIFsgJ3N1Y2Nlc3MnLCAkbWVzc2FnZSBdOwoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXItbG9naW4+CgkgKiA6IFRoZSBsb2dpbiBvZiB0aGUgdXNlciB0byBjcmVhdGUuCgkgKgoJICogPHVzZXItZW1haWw+CgkgKiA6IFRoZSBlbWFpbCBhZGRyZXNzIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZS4KCSAqCgkgKiBbLS1yb2xlPTxyb2xlPl0KCSAqIDogVGhlIHJvbGUgb2YgdGhlIHVzZXIgdG8gY3JlYXRlLiBEZWZhdWx0OiBkZWZhdWx0IHJvbGUuIFBvc3NpYmxlIHZhbHVlcwoJICogaW5jbHVkZSAnYWRtaW5pc3RyYXRvcicsICdlZGl0b3InLCAnYXV0aG9yJywgJ2NvbnRyaWJ1dG9yJywgJ3N1YnNjcmliZXInLgoJICoKCSAqIFstLXVzZXJfcGFzcz08cGFzc3dvcmQ+XQoJICogOiBUaGUgdXNlciBwYXNzd29yZC4gRGVmYXVsdDogcmFuZG9tbHkgZ2VuZXJhdGVkLgoJICoKCSAqIFstLXVzZXJfcmVnaXN0ZXJlZD08eXl5eS1tbS1kZC1oaC1paS1zcz5dCgkgKiA6IFRoZSBkYXRlIHRoZSB1c2VyIHJlZ2lzdGVyZWQuIERlZmF1bHQ6IGN1cnJlbnQgZGF0ZS4KCSAqCgkgKiBbLS1kaXNwbGF5X25hbWU9PG5hbWU+XQoJICogOiBUaGUgZGlzcGxheSBuYW1lLgoJICoKCSAqIFstLXVzZXJfbmljZW5hbWU9PG5pY2VfbmFtZT5dCgkgKiA6IEEgc3RyaW5nIHRoYXQgY29udGFpbnMgYSBVUkwtZnJpZW5kbHkgbmFtZSBmb3IgdGhlIHVzZXIuIFRoZSBkZWZhdWx0IGlzIHRoZSB1c2VyJ3MgdXNlcm5hbWUuCgkgKgoJICogWy0tdXNlcl91cmw9PHVybD5dCgkgKiA6IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIncyBVUkwgZm9yIHRoZSB1c2VyJ3Mgd2ViIHNpdGUuCgkgKgoJICogWy0tbmlja25hbWU9PG5pY2tuYW1lPl0KCSAqIDogVGhlIHVzZXIncyBuaWNrbmFtZSwgZGVmYXVsdHMgdG8gdGhlIHVzZXIncyB1c2VybmFtZS4KCSAqCgkgKiBbLS1maXJzdF9uYW1lPTxmaXJzdF9uYW1lPl0KCSAqIDogVGhlIHVzZXIncyBmaXJzdCBuYW1lLgoJICoKCSAqIFstLWxhc3RfbmFtZT08bGFzdF9uYW1lPl0KCSAqIDogVGhlIHVzZXIncyBsYXN0IG5hbWUuCgkgKgoJICogWy0tZGVzY3JpcHRpb249PGRlc2NyaXB0aW9uPl0KCSAqIDogQSBzdHJpbmcgY29udGFpbmluZyBjb250ZW50IGFib3V0IHRoZSB1c2VyLgoJICoKCSAqIFstLXJpY2hfZWRpdGluZz08cmljaF9lZGl0aW5nPl0KCSAqIDogQSBzdHJpbmcgZm9yIHdoZXRoZXIgdG8gZW5hYmxlIHRoZSByaWNoIGVkaXRvciBvciBub3QuIEZhbHNlIGlmIG5vdCBlbXB0eS4KCSAqCgkgKiBbLS1zZW5kLWVtYWlsXQoJICogOiBTZW5kIGFuIGVtYWlsIHRvIHRoZSB1c2VyIHdpdGggdGhlaXIgbmV3IGFjY291bnQgZGV0YWlscy4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgdXNlciBpZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSB1c2VyCgkgKiAgICAgJCB3cCB1c2VyIGNyZWF0ZSBib2IgYm9iQGV4YW1wbGUuY29tIC0tcm9sZT1hdXRob3IKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHVzZXIgMy4KCSAqICAgICBQYXNzd29yZDogazkqKiZJNHZOSCgmCgkgKgoJICogICAgICMgQ3JlYXRlIHVzZXIgd2l0aG91dCBzaG93aW5nIHBhc3N3b3JkIHVwb24gc3VjY2VzcwoJICogICAgICQgd3AgdXNlciBjcmVhdGUgYW5uIGFubkBleGFtcGxlLmNvbSAtLXBvcmNlbGFpbgoJICogICAgIDQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gbmV3IHN0ZENsYXNzKCk7CgoJCWxpc3QoICR1c2VyLT51c2VyX2xvZ2luLCAkdXNlci0+dXNlcl9lbWFpbCApID0gJGFyZ3M7CgoJCSRhc3NvY19hcmdzID0gd3Bfc2xhc2goICRhc3NvY19hcmdzICk7CgoJCWlmICggdXNlcm5hbWVfZXhpc3RzKCAkdXNlci0+dXNlcl9sb2dpbiApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICd7JHVzZXItPnVzZXJfbG9naW59JyB1c2VybmFtZSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuIiApOwoJCX0KCgkJaWYgKCAhIGlzX2VtYWlsKCAkdXNlci0+dXNlcl9lbWFpbCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICd7JHVzZXItPnVzZXJfZW1haWx9JyBlbWFpbCBhZGRyZXNzIGlzIGludmFsaWQuIiApOwoJCX0KCgkJJHVzZXItPnVzZXJfcmVnaXN0ZXJlZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKAoJCQkkYXNzb2NfYXJncywKCQkJJ3VzZXJfcmVnaXN0ZXJlZCcsCgkJCXN0cmZ0aW1lKCAnJUYgJVQnLCBjdXJyZW50X3RpbWUoICd0aW1lc3RhbXAnICkgKSAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLkN1cnJlbnRUaW1lVGltZXN0YW1wCgkJKTsKCgkJJHVzZXItPmRpc3BsYXlfbmFtZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc3BsYXlfbmFtZScsIGZhbHNlICk7CgoJCSR1c2VyLT5maXJzdF9uYW1lID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZmlyc3RfbmFtZScsIGZhbHNlICk7CgoJCSR1c2VyLT5sYXN0X25hbWUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsYXN0X25hbWUnLCBmYWxzZSApOwoKCQkkdXNlci0+ZGVzY3JpcHRpb24gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZXNjcmlwdGlvbicsIGZhbHNlICk7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd1c2VyX3Bhc3MnXSApICkgewoJCQkkdXNlci0+dXNlcl9wYXNzID0gJGFzc29jX2FyZ3NbJ3VzZXJfcGFzcyddOwoJCX0gZWxzZSB7CgkJCSR1c2VyLT51c2VyX3Bhc3MgPSB3cF9nZW5lcmF0ZV9wYXNzd29yZCggMjQgKTsKCQkJJGdlbmVyYXRlZF9wYXNzICA9IHRydWU7CgkJfQoKCQkkdXNlci0+cm9sZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3JvbGUnLCBnZXRfb3B0aW9uKCAnZGVmYXVsdF9yb2xlJyApICk7CgkJc2VsZjo6dmFsaWRhdGVfcm9sZSggJHVzZXItPnJvbGUgKTsKCgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NlbmQtZW1haWwnICkgKSB7CgkJCWFkZF9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQkJYWRkX2ZpbHRlciggJ3NlbmRfZW1haWxfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCX0KCgkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJJHJlc3VsdCA9IHdwbXVfdmFsaWRhdGVfdXNlcl9zaWdudXAoICR1c2VyLT51c2VyX2xvZ2luLCAkdXNlci0+dXNlcl9lbWFpbCApOwoJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0WydlcnJvcnMnXSApICYmICEgZW1wdHkoICRyZXN1bHRbJ2Vycm9ycyddLT5lcnJvcnMgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRyZXN1bHRbJ2Vycm9ycyddICk7CgkJCX0KCQkJJHVzZXJfaWQgPSB3cG11X2NyZWF0ZV91c2VyKCAkdXNlci0+dXNlcl9sb2dpbiwgJHVzZXItPnVzZXJfcGFzcywgJHVzZXItPnVzZXJfZW1haWwgKTsKCQkJaWYgKCAhICR1c2VyX2lkICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1Vua25vd24gZXJyb3IgY3JlYXRpbmcgbmV3IHVzZXIuJyApOwoJCQl9CgkJCSR1c2VyLT5JRCA9ICR1c2VyX2lkOwoJCQkkdXNlcl9pZCAgPSB3cF91cGRhdGVfdXNlciggJHVzZXIgKTsKCQkJaWYgKCBpc193cF9lcnJvciggJHVzZXJfaWQgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICR1c2VyX2lkICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkdXNlcl9pZCA9IHdwX2luc2VydF91c2VyKCAkdXNlciApOwoJCX0KCgkJaWYgKCAhICR1c2VyX2lkIHx8IGlzX3dwX2Vycm9yKCAkdXNlcl9pZCApICkgewoJCQlpZiAoICEgJHVzZXJfaWQgKSB7CgkJCQkkdXNlcl9pZCA9ICdVbmtub3duIGVycm9yIGNyZWF0aW5nIG5ldyB1c2VyLic7CgkJCX0KCQkJV1BfQ0xJOjplcnJvciggJHVzZXJfaWQgKTsKCQl9IGVsc2UgewoJCQlpZiAoIGZhbHNlID09PSAkdXNlci0+cm9sZSApIHsKCQkJCWRlbGV0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICdjYXBhYmlsaXRpZXMnICk7CgkJCQlkZWxldGVfdXNlcl9vcHRpb24oICR1c2VyX2lkLCAndXNlcl9sZXZlbCcgKTsKCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzZW5kLWVtYWlsJyApICkgewoJCQlzZWxmOjp3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkdXNlci0+dXNlcl9wYXNzICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKSApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkdXNlcl9pZCApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkNyZWF0ZWQgdXNlciB7JHVzZXJfaWR9LiIgKTsKCQkJaWYgKCBpc3NldCggJGdlbmVyYXRlZF9wYXNzICkgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICJQYXNzd29yZDogeyR1c2VyLT51c2VyX3Bhc3N9IiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyBhbiBleGlzdGluZyB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4uLi4KCSAqIDogVGhlIHVzZXIgbG9naW4sIHVzZXIgZW1haWwgb3IgdXNlciBJRCBvZiB0aGUgdXNlcihzKSB0byB1cGRhdGUuCgkgKgoJICogWy0tdXNlcl9wYXNzPTxwYXNzd29yZD5dCgkgKiA6IEEgc3RyaW5nIHRoYXQgY29udGFpbnMgdGhlIHBsYWluIHRleHQgcGFzc3dvcmQgZm9yIHRoZSB1c2VyLgoJICoKCSAqIFstLXVzZXJfbmljZW5hbWU9PG5pY2VfbmFtZT5dCgkgKiA6IEEgc3RyaW5nIHRoYXQgY29udGFpbnMgYSBVUkwtZnJpZW5kbHkgbmFtZSBmb3IgdGhlIHVzZXIuIFRoZSBkZWZhdWx0IGlzIHRoZSB1c2VyJ3MgdXNlcm5hbWUuCgkgKgoJICogWy0tdXNlcl91cmw9PHVybD5dCgkgKiA6IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIncyBVUkwgZm9yIHRoZSB1c2VyJ3Mgd2ViIHNpdGUuCgkgKgoJICogWy0tdXNlcl9lbWFpbD08ZW1haWw+XQoJICogOiBBIHN0cmluZyBjb250YWluaW5nIHRoZSB1c2VyJ3MgZW1haWwgYWRkcmVzcy4KCSAqCgkgKiBbLS1kaXNwbGF5X25hbWU9PGRpc3BsYXlfbmFtZT5dCgkgKiA6IEEgc3RyaW5nIHRoYXQgd2lsbCBiZSBzaG93biBvbiB0aGUgc2l0ZS4gRGVmYXVsdHMgdG8gdXNlcidzIHVzZXJuYW1lLgoJICoKCSAqIFstLW5pY2tuYW1lPTxuaWNrbmFtZT5dCgkgKiA6IFRoZSB1c2VyJ3Mgbmlja25hbWUsIGRlZmF1bHRzIHRvIHRoZSB1c2VyJ3MgdXNlcm5hbWUuCgkgKgoJICogWy0tZmlyc3RfbmFtZT08Zmlyc3RfbmFtZT5dCgkgKiA6IFRoZSB1c2VyJ3MgZmlyc3QgbmFtZS4KCSAqCgkgKiBbLS1sYXN0X25hbWU9PGxhc3RfbmFtZT5dCgkgKiA6IFRoZSB1c2VyJ3MgbGFzdCBuYW1lLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IEEgc3RyaW5nIGNvbnRhaW5pbmcgY29udGVudCBhYm91dCB0aGUgdXNlci4KCSAqCgkgKiBbLS1yaWNoX2VkaXRpbmc9PHJpY2hfZWRpdGluZz5dCgkgKiA6IEEgc3RyaW5nIGZvciB3aGV0aGVyIHRvIGVuYWJsZSB0aGUgcmljaCBlZGl0b3Igb3Igbm90LiBGYWxzZSBpZiBub3QgZW1wdHkuCgkgKgoJICogWy0tdXNlcl9yZWdpc3RlcmVkPTx5eXl5LW1tLWRkLWhoLWlpLXNzPl0KCSAqIDogVGhlIGRhdGUgdGhlIHVzZXIgcmVnaXN0ZXJlZC4KCSAqCgkgKiBbLS1yb2xlPTxyb2xlPl0KCSAqIDogQSBzdHJpbmcgdXNlZCB0byBzZXQgdGhlIHVzZXIncyByb2xlLgoJICoKCSAqIC0tPGZpZWxkPj08dmFsdWU+CgkgKiA6IE9uZSBvciBtb3JlIGZpZWxkcyB0byB1cGRhdGUuIEZvciBhY2NlcHRlZCBmaWVsZHMsIHNlZSB3cF91cGRhdGVfdXNlcigpLgoJICoKCSAqIFstLXNraXAtZW1haWxdCgkgKiA6IERvbid0IHNlbmQgYW4gZW1haWwgbm90aWZpY2F0aW9uIHRvIHRoZSB1c2VyLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVXBkYXRlIHVzZXIKCSAqICAgICAkIHdwIHVzZXIgdXBkYXRlIDEyMyAtLWRpc3BsYXlfbmFtZT1NYXJ5IC0tdXNlcl9wYXNzPW1hcnlwYXNzCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCB1c2VyIDEyMy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd1c2VyX2xvZ2luJ10gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVXNlciBsb2dpbnMgY2FuJ3QgYmUgY2hhbmdlZC4iICk7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1sndXNlcl9sb2dpbiddICk7CgkJfQoKCQkkdXNlcl9pZHMgPSBbXTsKCQlmb3JlYWNoICggJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApIGFzICR1c2VyICkgewoJCQkkdXNlcl9pZHNbXSA9ICR1c2VyLT5JRDsKCQl9CgoJCSRza2lwX2VtYWlsID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1lbWFpbCcgKTsKCQlpZiAoICRza2lwX2VtYWlsICkgewoJCQlhZGRfZmlsdGVyKCAnc2VuZF9lbWFpbF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgkJCWFkZF9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQl9CgoJCSRhc3NvY19hcmdzID0gd3Bfc2xhc2goICRhc3NvY19hcmdzICk7CgkJcGFyZW50OjpfdXBkYXRlKCAkdXNlcl9pZHMsICRhc3NvY19hcmdzLCAnd3BfdXBkYXRlX3VzZXInICk7CgoJCWlmICggJHNraXBfZW1haWwgKSB7CgkJCXJlbW92ZV9maWx0ZXIoICdzZW5kX2VtYWlsX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQkJcmVtb3ZlX2ZpbHRlciggJ3NlbmRfcGFzc3dvcmRfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzb21lIHVzZXJzLgoJICoKCSAqIENyZWF0ZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIG5ldyB1c2VycyB3aXRoIGR1bW15IGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWNvdW50PTxudW1iZXI+XQoJICogOiBIb3cgbWFueSB1c2VycyB0byBnZW5lcmF0ZT8KCSAqIC0tLQoJICogZGVmYXVsdDogMTAwCgkgKiAtLS0KCSAqCgkgKiBbLS1yb2xlPTxyb2xlPl0KCSAqIDogVGhlIHJvbGUgb2YgdGhlIGdlbmVyYXRlZCB1c2Vycy4gRGVmYXVsdDogZGVmYXVsdCByb2xlIGZyb20gV1AKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogcHJvZ3Jlc3MKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcHJvZ3Jlc3MKCSAqICAgLSBpZHMKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWRkIG1ldGEgdG8gZXZlcnkgZ2VuZXJhdGVkIHVzZXJzLgoJICogICAgICQgd3AgdXNlciBnZW5lcmF0ZSAtLWZvcm1hdD1pZHMgLS1jb3VudD0zIHwgeGFyZ3MgLWQgJyAnIC1JICUgd3AgdXNlciBtZXRhIGFkZCAlIGZvbyBiYXIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdlbmVyYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICRibG9nX2lkOwoKCQkkZGVmYXVsdHMgICA9IFsKCQkJJ2NvdW50JyA9PiAxMDAsCgkJCSdyb2xlJyAgPT4gZ2V0X29wdGlvbiggJ2RlZmF1bHRfcm9sZScgKSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJHJvbGUgPSAkYXNzb2NfYXJnc1sncm9sZSddOwoKCQlpZiAoICEgZW1wdHkoICRyb2xlICkgKSB7CgkJCXNlbGY6OnZhbGlkYXRlX3JvbGUoICRyb2xlICk7CgkJfQoKCQkkdXNlcl9jb3VudCA9IGNvdW50X3VzZXJzKCk7CgkJJHRvdGFsICAgICAgPSAkdXNlcl9jb3VudFsndG90YWxfdXNlcnMnXTsKCQkkbGltaXQgICAgICA9ICRhc3NvY19hcmdzWydjb3VudCddICsgJHRvdGFsOwoKCQkkZm9ybWF0ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JywgJ3Byb2dyZXNzJyApOwoKCQkkbm90aWZ5ID0gZmFsc2U7CgkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkkbm90aWZ5ID0gVXRpbHNcbWFrZV9wcm9ncmVzc19iYXIoICdHZW5lcmF0aW5nIHVzZXJzJywgJGFzc29jX2FyZ3NbJ2NvdW50J10gKTsKCQl9CgoJCWZvciAoICRpbmRleCA9ICR0b3RhbDsgJGluZGV4IDwgJGxpbWl0OyAkaW5kZXgrKyApIHsKCQkJJGxvZ2luID0gInVzZXJfeyRibG9nX2lkfV97JGluZGV4fSI7CgkJCSRuYW1lICA9ICJVc2VyIHskaW5kZXh9IjsKCgkJCSR1c2VyX2lkID0gd3BfaW5zZXJ0X3VzZXIoCgkJCQlbCgkJCQkJJ3VzZXJfbG9naW4nICAgPT4gJGxvZ2luLAoJCQkJCSd1c2VyX3Bhc3MnICAgID0+ICRsb2dpbiwKCQkJCQknbmlja25hbWUnICAgICA9PiAkbmFtZSwKCQkJCQknZGlzcGxheV9uYW1lJyA9PiAkbmFtZSwKCQkJCQkncm9sZScgICAgICAgICA9PiAkcm9sZSwKCQkJCV0KCQkJKTsKCgkJCWlmICggZmFsc2UgPT09ICRyb2xlICkgewoJCQkJZGVsZXRlX3VzZXJfb3B0aW9uKCAkdXNlcl9pZCwgJ2NhcGFiaWxpdGllcycgKTsKCQkJCWRlbGV0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICd1c2VyX2xldmVsJyApOwoJCQl9CgoJCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCQkkbm90aWZ5LT50aWNrKCk7CgkJCX0gZWxzZWlmICggJ2lkcycgPT09ICRmb3JtYXQgKSB7CgkJCQllY2hvICR1c2VyX2lkOwoJCQkJaWYgKCAkaW5kZXggPCAkbGltaXQgLSAxICkgewoJCQkJCWVjaG8gJyAnOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCSRub3RpZnktPmZpbmlzaCgpOwoJCX0KCX0KCgkvKioKCSAqIFNldHMgdGhlIHVzZXIgcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIHVzZXIgbG9naW4uCgkgKgoJICogWzxyb2xlPl0KCSAqIDogTWFrZSB0aGUgdXNlciBoYXZlIHRoZSBzcGVjaWZpZWQgcm9sZS4gSWYgbm90IHBhc3NlZCwgdGhlIGRlZmF1bHQgcm9sZSBpcwoJICogdXNlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgc2V0LXJvbGUgMTIgYXV0aG9yCgkgKiAgICAgU3VjY2VzczogQWRkZWQgam9obmRvZSAoMTIpIHRvIGh0dHA6Ly9leGFtcGxlLmNvbSBhcyBhdXRob3IuCgkgKgoJICogQHN1YmNvbW1hbmQgc2V0LXJvbGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9yb2xlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHVzZXIgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQkkcm9sZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXJncywgMSwgZ2V0X29wdGlvbiggJ2RlZmF1bHRfcm9sZScgKSApOwoKCQlzZWxmOjp2YWxpZGF0ZV9yb2xlKCAkcm9sZSApOwoKCQkvLyBNdWx0aXNpdGUKCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ2FkZF91c2VyX3RvX2Jsb2cnICkgKSB7CgkJCWFkZF91c2VyX3RvX2Jsb2coIGdldF9jdXJyZW50X2Jsb2dfaWQoKSwgJHVzZXItPklELCAkcm9sZSApOwoJCX0gZWxzZSB7CgkJCSR1c2VyLT5zZXRfcm9sZSggJHJvbGUgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KSB0byAiIC4gc2l0ZV91cmwoKSAuICIgYXMgeyRyb2xlfS4iICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgcm9sZSBmb3IgYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgdXNlciBsb2dpbi4KCSAqCgkgKiA8cm9sZT4KCSAqIDogQWRkIHRoZSBzcGVjaWZpZWQgcm9sZSB0byB0aGUgdXNlci4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgYWRkLXJvbGUgMTIgYXV0aG9yCgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ2F1dGhvcicgcm9sZSBmb3Igam9obmRvZSAoMTIpLgoJICoKCSAqIEBzdWJjb21tYW5kIGFkZC1yb2xlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfcm9sZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJJHJvbGUgPSAkYXJnc1sxXTsKCgkJc2VsZjo6dmFsaWRhdGVfcm9sZSggJHJvbGUgKTsKCgkJJHVzZXItPmFkZF9yb2xlKCAkcm9sZSApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJBZGRlZCAneyRyb2xlfScgcm9sZSBmb3IgeyR1c2VyLT51c2VyX2xvZ2lufSAoeyR1c2VyLT5JRH0pLiIgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYSB1c2VyJ3Mgcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFVzZXIgSUQsIHVzZXIgZW1haWwsIG9yIHVzZXIgbG9naW4uCgkgKgoJICogWzxyb2xlPl0KCSAqIDogQSBzcGVjaWZpYyByb2xlIHRvIHJlbW92ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgcmVtb3ZlLXJvbGUgMTIgYXV0aG9yCgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCAnYXV0aG9yJyByb2xlIGZvciBqb2huZG9lICgxMikuCgkgKgoJICogQHN1YmNvbW1hbmQgcmVtb3ZlLXJvbGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlbW92ZV9yb2xlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHVzZXIgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQlpZiAoIGlzc2V0KCAkYXJnc1sxXSApICkgewoJCQkkcm9sZSA9ICRhcmdzWzFdOwoKCQkJc2VsZjo6dmFsaWRhdGVfcm9sZSggJHJvbGUgKTsKCgkJCSR1c2VyLT5yZW1vdmVfcm9sZSggJHJvbGUgKTsKCgkJCVdQX0NMSTo6c3VjY2VzcyggIlJlbW92ZWQgJ3skcm9sZX0nIHJvbGUgZm9yIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KS4iICk7CgkJfSBlbHNlIHsKCQkJLy8gTXVsdGlzaXRlCgkJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAncmVtb3ZlX3VzZXJfZnJvbV9ibG9nJyApICkgewoJCQkJcmVtb3ZlX3VzZXJfZnJvbV9ibG9nKCAkdXNlci0+SUQsIGdldF9jdXJyZW50X2Jsb2dfaWQoKSApOwoJCQl9IGVsc2UgewoJCQkJJHVzZXItPnJlbW92ZV9hbGxfY2FwcygpOwoJCQl9CgoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJSZW1vdmVkIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KSBmcm9tICIgLiBzaXRlX3VybCgpIC4gJy4nICk7CgkJfQoJfQoKCS8qKgoJICogQWRkcyBhIGNhcGFiaWxpdHkgdG8gYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgdXNlciBsb2dpbi4KCSAqCgkgKiA8Y2FwPgoJICogOiBUaGUgY2FwYWJpbGl0eSB0byBhZGQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBZGQgYSBjYXBhYmlsaXR5IGZvciBhIHVzZXIKCSAqICAgICAkIHdwIHVzZXIgYWRkLWNhcCBqb2huIGNyZWF0ZV9wcmVtaXVtX2l0ZW0KCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnY3JlYXRlX3ByZW1pdW1faXRlbScgY2FwYWJpbGl0eSBmb3Igam9obiAoMTYpLgoJICoKCSAqICAgICAjIEFkZCBhIGNhcGFiaWxpdHkgZm9yIGEgdXNlcgoJICogICAgICQgd3AgdXNlciBhZGQtY2FwIDE1IGVkaXRfcHJvZHVjdAoJICogICAgIFN1Y2Nlc3M6IEFkZGVkICdlZGl0X3Byb2R1Y3QnIGNhcGFiaWxpdHkgZm9yIGpvaG5kb2UgKDE1KS4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtY2FwCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfY2FwKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHVzZXIgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCWlmICggJHVzZXIgKSB7CgkJCSRjYXAgPSAkYXJnc1sxXTsKCQkJJHVzZXItPmFkZF9jYXAoICRjYXAgKTsKCgkJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkICd7JGNhcH0nIGNhcGFiaWxpdHkgZm9yIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KS4iICk7CgkJfQoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIHVzZXIncyBjYXBhYmlsaXR5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgdXNlciBsb2dpbi4KCSAqCgkgKiA8Y2FwPgoJICogOiBUaGUgY2FwYWJpbGl0eSB0byBiZSByZW1vdmVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdXNlciByZW1vdmUtY2FwIDExIHB1Ymxpc2hfbmV3c2xldHRlcnMKCSAqICAgICBTdWNjZXNzOiBSZW1vdmVkICdwdWJsaXNoX25ld3NsZXR0ZXJzJyBjYXAgZm9yIHN1cGVydmlzb3IgKDExKS4KCSAqCgkgKiAgICAgJCB3cCB1c2VyIHJlbW92ZS1jYXAgMTEgcHVibGlzaF9wb3N0cwoJICogICAgIEVycm9yOiBUaGUgJ3B1Ymxpc2hfcG9zdHMnIGNhcCBmb3Igc3VwZXJ2aXNvciAoMTEpIGlzIGluaGVyaXRlZCBmcm9tIGEgcm9sZS4KCSAqCgkgKiAgICAgJCB3cCB1c2VyIHJlbW92ZS1jYXAgMTEgbm9uZXhpc3RlbnRfY2FwCgkgKiAgICAgRXJyb3I6IE5vIHN1Y2ggJ25vbmV4aXN0ZW50X2NhcCcgY2FwIGZvciBzdXBlcnZpc29yICgxMSkuCgkgKgoJICogQHN1YmNvbW1hbmQgcmVtb3ZlLWNhcAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlX2NhcCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQlpZiAoICR1c2VyICkgewoJCQkkY2FwID0gJGFyZ3NbMV07CgkJCWlmICggISBpc3NldCggJHVzZXItPmNhcHNbICRjYXAgXSApICkgewoJCQkJaWYgKCBpc3NldCggJHVzZXItPmFsbGNhcHNbICRjYXAgXSApICkgewoJCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgJ3skY2FwfScgY2FwIGZvciB7JHVzZXItPnVzZXJfbG9naW59ICh7JHVzZXItPklEfSkgaXMgaW5oZXJpdGVkIGZyb20gYSByb2xlLiIgKTsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICJObyBzdWNoICd7JGNhcH0nIGNhcCBmb3IgeyR1c2VyLT51c2VyX2xvZ2lufSAoeyR1c2VyLT5JRH0pLiIgKTsKCQkJfQoJCQkkdXNlci0+cmVtb3ZlX2NhcCggJGNhcCApOwoKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUmVtb3ZlZCAneyRjYXB9JyBjYXAgZm9yIHskdXNlci0+dXNlcl9sb2dpbn0gKHskdXNlci0+SUR9KS4iICk7CgkJfQoJfQoKCS8qKgoJICogTGlzdHMgYWxsIGNhcGFiaWxpdGllcyBmb3IgYSB1c2VyLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4KCSAqIDogVXNlciBJRCwgdXNlciBlbWFpbCwgb3IgbG9naW4uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGxpc3QKCSAqIG9wdGlvbnM6CgkgKiAgIC0gbGlzdAoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB1c2VyIGxpc3QtY2FwcyAyMQoJICogICAgIGVkaXRfcHJvZHVjdAoJICogICAgIGNyZWF0ZV9wcmVtaXVtX2l0ZW0KCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0LWNhcHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfY2FwcyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJaWYgKCAkdXNlciApIHsKCQkJJHVzZXItPmdldF9yb2xlX2NhcHMoKTsKCgkJCSR1c2VyX2NhcHNfbGlzdCA9ICR1c2VyLT5hbGxjYXBzOwoKCQkJJGFjdGl2ZV91c2VyX2NhcF9saXN0ID0gW107CgoJCQlmb3JlYWNoICggJHVzZXJfY2Fwc19saXN0IGFzICRjYXAgPT4gJGFjdGl2ZSApIHsKCQkJCWlmICggJGFjdGl2ZSApIHsKCQkJCQkkYWN0aXZlX3VzZXJfY2FwX2xpc3RbXSA9ICRjYXA7CgkJCQl9CgkJCX0KCgkJCWlmICggJ2xpc3QnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCQlmb3JlYWNoICggJGFjdGl2ZV91c2VyX2NhcF9saXN0IGFzICRjYXAgKSB7CgkJCQkJV1BfQ0xJOjpsaW5lKCAkY2FwICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQkkb3V0cHV0X2NhcHMgPSBbXTsKCQkJCWZvcmVhY2ggKCAkYWN0aXZlX3VzZXJfY2FwX2xpc3QgYXMgJGNhcCApIHsKCQkJCQkkb3V0cHV0X2NhcCA9IG5ldyBzdGRDbGFzcygpOwoKCQkJCQkkb3V0cHV0X2NhcC0+bmFtZSA9ICRjYXA7CgoJCQkJCSRvdXRwdXRfY2Fwc1tdID0gJG91dHB1dF9jYXA7CgkJCQl9CgkJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5jYXBfZmllbGRzICk7CgkJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkb3V0cHV0X2NhcHMgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEltcG9ydHMgdXNlcnMgZnJvbSBhIENTViBmaWxlLgoJICoKCSAqIElmIHRoZSB1c2VyIGFscmVhZHkgZXhpc3RzIChtYXRjaGluZyB0aGUgZW1haWwgYWRkcmVzcyBvciBsb2dpbiksIHRoZW4KCSAqIHRoZSB1c2VyIGlzIHVwZGF0ZWQgdW5sZXNzIHRoZSBgLS1za2lwLXVwZGF0ZWAgZmxhZyBpcyB1c2VkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8ZmlsZT4KCSAqIDogVGhlIGxvY2FsIG9yIHJlbW90ZSBDU1YgZmlsZSBvZiB1c2VycyB0byBpbXBvcnQuIElmICctJywgdGhlbiByZWFkcyBmcm9tIFNURElOLgoJICoKCSAqIFstLXNlbmQtZW1haWxdCgkgKiA6IFNlbmQgYW4gZW1haWwgdG8gbmV3IHVzZXJzIHdpdGggdGhlaXIgYWNjb3VudCBkZXRhaWxzLgoJICoKCSAqIFstLXNraXAtdXBkYXRlXQoJICogOiBEb24ndCB1cGRhdGUgdXNlcnMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgSW1wb3J0IHVzZXJzIGZyb20gbG9jYWwgQ1NWIGZpbGUKCSAqICAgICAkIHdwIHVzZXIgaW1wb3J0LWNzdiAvcGF0aC90by91c2Vycy5jc3YKCSAqICAgICBTdWNjZXNzOiBib2Jqb25lcyBjcmVhdGVkCgkgKiAgICAgU3VjY2VzczogbmV3dXNlcjEgY3JlYXRlZAoJICogICAgIFN1Y2Nlc3M6IGV4aXN0aW5ndXNlciBjcmVhdGVkCgkgKgoJICogICAgICMgSW1wb3J0IHVzZXJzIGZyb20gcmVtb3RlIENTViBmaWxlCgkgKiAgICAgJCB3cCB1c2VyIGltcG9ydC1jc3YgaHR0cDovL2V4YW1wbGUuY29tL3VzZXJzLmNzdgoJICoKCSAqICAgICBTYW1wbGUgdXNlcnMuY3N2IGZpbGU6CgkgKgoJICogICAgIHVzZXJfbG9naW4sdXNlcl9lbWFpbCxkaXNwbGF5X25hbWUscm9sZQoJICogICAgIGJvYmpvbmVzLGJvYmpvbmVzQGV4YW1wbGUuY29tLEJvYiBKb25lcyxjb250cmlidXRvcgoJICogICAgIG5ld3VzZXIxLG5ld3VzZXIxQGV4YW1wbGUuY29tLE5ldyBVc2VyLGF1dGhvcgoJICogICAgIGV4aXN0aW5ndXNlcixleGlzdGluZ3VzZXJAZXhhbXBsZS5jb20sRXhpc3RpbmcgVXNlcixhZG1pbmlzdHJhdG9yCgkgKgoJICogQHN1YmNvbW1hbmQgaW1wb3J0LWNzdgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW1wb3J0X2NzdiggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkYmxvZ191c2VycyA9IGdldF91c2VycygpOwoKCQkkZmlsZW5hbWUgPSAkYXJnc1swXTsKCgkJaWYgKCAwID09PSBzdHJpcG9zKCAkZmlsZW5hbWUsICdodHRwOi8vJyApIHx8IDAgPT09IHN0cmlwb3MoICRmaWxlbmFtZSwgJ2h0dHBzOi8vJyApICkgewoJCQkkcmVzcG9uc2UgICAgICA9IHdwX3JlbW90ZV9oZWFkKCAkZmlsZW5hbWUgKTsKCQkJJHJlc3BvbnNlX2NvZGUgPSAoc3RyaW5nKSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHJlc3BvbnNlICk7CgkJCWlmICggaW5fYXJyYXkoIChpbnQpICRyZXNwb25zZV9jb2RlWzBdLCBbIDQsIDUgXSwgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGFjY2VzcyByZW1vdGUgQ1NWIGZpbGUgKEhUVFAgeyRyZXNwb25zZV9jb2RlfSByZXNwb25zZSkuIiApOwoJCQl9CgkJfSBlbHNlaWYgKCAnLScgPT09ICRmaWxlbmFtZSApIHsKCQkJaWYgKCAhIEVudGl0eVV0aWxzOjpoYXNfc3RkaW4oKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdVbmFibGUgdG8gcmVhZCBjb250ZW50IGZyb20gU1RESU4uJyApOwoJCQl9CgkJfSBlbHNlaWYgKCAhIGZpbGVfZXhpc3RzKCAkZmlsZW5hbWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIk1pc3NpbmcgZmlsZTogeyRmaWxlbmFtZX0iICk7CgkJfQoKCQkvLyBEb24ndCBzZW5kIGNvcmUncyBlbWFpbHMgZHVyaW5nIHRoZSBjcmVhdGlvbiAvIHVwZGF0ZSBwcm9jZXNzCgkJYWRkX2ZpbHRlciggJ3NlbmRfcGFzc3dvcmRfY2hhbmdlX2VtYWlsJywgJ19fcmV0dXJuX2ZhbHNlJyApOwoJCWFkZF9maWx0ZXIoICdzZW5kX2VtYWlsX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCgkJaWYgKCAnLScgPT09ICRmaWxlbmFtZSApIHsKCQkJJGZpbGVfb2JqZWN0ID0gbmV3IE5vUmV3aW5kSXRlcmF0b3IoIG5ldyBTcGxGaWxlT2JqZWN0KCAncGhwOi8vc3RkaW4nICkgKTsKCQkJJGZpbGVfb2JqZWN0LT5zZXRGbGFncyggU3BsRmlsZU9iamVjdDo6UkVBRF9DU1YgKTsKCQkJJGNzdl9kYXRhID0gW107CgkJCSRpbmRleGVzICA9IFtdOwoJCQlmb3JlYWNoICggJGZpbGVfb2JqZWN0IGFzICRsaW5lICkgewoJCQkJaWYgKCBlbXB0eSggJGxpbmVbMF0gKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoIGVtcHR5KCAkaW5kZXhlcyApICkgewoJCQkJCSRpbmRleGVzID0gJGxpbmU7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJZm9yZWFjaCAoICRpbmRleGVzIGFzICRuID0+ICRrZXkgKSB7CgkJCQkJJGRhdGFbICRrZXkgXSA9ICRsaW5lWyAkbiBdOwoJCQkJfQoKCQkJCSRjc3ZfZGF0YVtdID0gJGRhdGE7CgkJCX0KCQl9IGVsc2UgewoJCQkkY3N2X2RhdGEgPSBuZXcgQ3N2SXRlcmF0b3IoICRmaWxlbmFtZSApOwoJCX0KCgkJZm9yZWFjaCAoICRjc3ZfZGF0YSBhcyAkbmV3X3VzZXIgKSB7CgkJCSRkZWZhdWx0cyA9IFsKCQkJCSdyb2xlJyAgICAgICAgICAgID0+IGdldF9vcHRpb24oICdkZWZhdWx0X3JvbGUnICksCgkJCQkndXNlcl9wYXNzJyAgICAgICA9PiB3cF9nZW5lcmF0ZV9wYXNzd29yZCgpLAoJCQkJJ3VzZXJfcmVnaXN0ZXJlZCcgPT4gc3RyZnRpbWUoICclRiAlVCcsIHRpbWUoKSApLAoJCQkJJ2Rpc3BsYXlfbmFtZScgICAgPT4gZmFsc2UsCgkJCV07CgkJCSRuZXdfdXNlciA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRuZXdfdXNlciApOwoKCQkJJHNlY29uZGFyeV9yb2xlcyA9IFtdOwoJCQlpZiAoICEgZW1wdHkoICRuZXdfdXNlclsncm9sZXMnXSApICkgewoJCQkJJHJvbGVzICAgICAgICA9IGFycmF5X21hcCggJ3RyaW0nLCBleHBsb2RlKCAnLCcsICRuZXdfdXNlclsncm9sZXMnXSApICk7CgkJCQkkaW52YWxpZF9yb2xlID0gZmFsc2U7CgkJCQlmb3JlYWNoICggJHJvbGVzIGFzICRyb2xlICkgewoJCQkJCWlmICggbnVsbCA9PT0gZ2V0X3JvbGUoICRyb2xlICkgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggInskbmV3X3VzZXJbJ3VzZXJfbG9naW4nXX0gaGFzIGFuIGludmFsaWQgcm9sZS4iICk7CgkJCQkJCSRpbnZhbGlkX3JvbGUgPSB0cnVlOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoICRpbnZhbGlkX3JvbGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkbmV3X3VzZXJbJ3JvbGUnXSA9IGFycmF5X3NoaWZ0KCAkcm9sZXMgKTsKCQkJCSRzZWNvbmRhcnlfcm9sZXMgID0gJHJvbGVzOwoJCQl9IGVsc2VpZiAoICdub25lJyA9PT0gJG5ld191c2VyWydyb2xlJ10gKSB7CgkJCQkkbmV3X3VzZXJbJ3JvbGUnXSA9IGZhbHNlOwoJCQl9IGVsc2VpZiAoIG51bGwgPT09IGdldF9yb2xlKCAkbmV3X3VzZXJbJ3JvbGUnXSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRuZXdfdXNlclsndXNlcl9sb2dpbiddfSBoYXMgYW4gaW52YWxpZCByb2xlLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBVc2VyIGFscmVhZHkgZXhpc3RzIGFuZCB3ZSBqdXN0IG5lZWQgdG8gYWRkIHRoZW0gdG8gdGhlIHNpdGUgaWYgdGhleSBhcmVuJ3QgYWxyZWFkeSB0aGVyZQoJCQkkZXhpc3RpbmdfdXNlciA9IGdldF91c2VyX2J5KCAnZW1haWwnLCAkbmV3X3VzZXJbJ3VzZXJfZW1haWwnXSApOwoKCQkJaWYgKCAhICRleGlzdGluZ191c2VyICkgewoJCQkJJGV4aXN0aW5nX3VzZXIgPSBnZXRfdXNlcl9ieSggJ2xvZ2luJywgJG5ld191c2VyWyd1c2VyX2xvZ2luJ10gKTsKCQkJfQoKCQkJaWYgKCAkZXhpc3RpbmdfdXNlciAmJiBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXVwZGF0ZScgKSApIHsKCgkJCQlXUF9DTEk6OmxvZyggInskZXhpc3RpbmdfdXNlci0+dXNlcl9sb2dpbn0gZXhpc3RzIGFuZCBoYXMgYmVlbiBza2lwcGVkLiIgKTsKCQkJCWNvbnRpbnVlOwoKCQkJfQoKCQkJaWYgKCAkZXhpc3RpbmdfdXNlciApIHsKCQkJCSRuZXdfdXNlclsnSUQnXSA9ICRleGlzdGluZ191c2VyLT5JRDsKCQkJCSR1c2VyX2lkICAgICAgICA9IHdwX3VwZGF0ZV91c2VyKCAkbmV3X3VzZXIgKTsKCgkJCQlpZiAoICEgaW5fYXJyYXkoICRleGlzdGluZ191c2VyLT51c2VyX2xvZ2luLCB3cF9saXN0X3BsdWNrKCAkYmxvZ191c2VycywgJ3VzZXJfbG9naW4nICksIHRydWUgKSAmJiBpc19tdWx0aXNpdGUoKSAmJiAkbmV3X3VzZXJbJ3JvbGUnXSApIHsKCQkJCQlhZGRfdXNlcl90b19ibG9nKCBnZXRfY3VycmVudF9ibG9nX2lkKCksICRleGlzdGluZ191c2VyLT5JRCwgJG5ld191c2VyWydyb2xlJ10gKTsKCQkJCQlXUF9DTEk6OmxvZyggInskZXhpc3RpbmdfdXNlci0+dXNlcl9sb2dpbn0gYWRkZWQgYXMgeyRuZXdfdXNlclsncm9sZSddfS4iICk7CgkJCQl9CgoJCQkJLy8gQ3JlYXRlIHRoZSB1c2VyCgkJCX0gZWxzZSB7CgkJCQl1bnNldCggJG5ld191c2VyWydJRCddICk7IC8vIFVuc2V0IGVsc2UgaXQgd2lsbCBqdXN0IHJldHVybiB0aGUgSUQKCgkJCQlpZiAoIGlzX211bHRpc2l0ZSgpICkgewoJCQkJCSRyZXN1bHQgPSB3cG11X3ZhbGlkYXRlX3VzZXJfc2lnbnVwKCAkbmV3X3VzZXJbJ3VzZXJfbG9naW4nXSwgJG5ld191c2VyWyd1c2VyX2VtYWlsJ10gKTsKCQkJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0WydlcnJvcnMnXSApICYmICEgZW1wdHkoICRyZXN1bHRbJ2Vycm9ycyddLT5lcnJvcnMgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkcmVzdWx0WydlcnJvcnMnXSApOwoJCQkJCQljb250aW51ZTsKCQkJCQl9CgkJCQkJJHVzZXJfaWQgPSB3cG11X2NyZWF0ZV91c2VyKCAkbmV3X3VzZXJbJ3VzZXJfbG9naW4nXSwgJG5ld191c2VyWyd1c2VyX3Bhc3MnXSwgJG5ld191c2VyWyd1c2VyX2VtYWlsJ10gKTsKCQkJCQlpZiAoICEgJHVzZXJfaWQgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggJ1Vua25vd24gZXJyb3IgY3JlYXRpbmcgbmV3IHVzZXIuJyApOwoJCQkJCQljb250aW51ZTsKCQkJCQl9CgkJCQkJJG5ld191c2VyWydJRCddID0gJHVzZXJfaWQ7CgkJCQkJJHVzZXJfaWQgICAgICAgID0gd3BfdXBkYXRlX3VzZXIoICRuZXdfdXNlciApOwoJCQkJCWlmICggaXNfd3BfZXJyb3IoICR1c2VyX2lkICkgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggJHVzZXJfaWQgKTsKCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQkkdXNlcl9pZCA9IHdwX2luc2VydF91c2VyKCAkbmV3X3VzZXIgKTsKCQkJCX0KCgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NlbmQtZW1haWwnICkgKSB7CgkJCQkJc2VsZjo6d3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uKCAkdXNlcl9pZCwgJG5ld191c2VyWyd1c2VyX3Bhc3MnXSApOwoJCQkJfQoJCQl9CgoJCQlpZiAoIGlzX3dwX2Vycm9yKCAkdXNlcl9pZCApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkdXNlcl9pZCApOwoJCQkJY29udGludWU7CgoJCQl9CgoJCQlpZiAoIGZhbHNlID09PSAkbmV3X3VzZXJbJ3JvbGUnXSApIHsKCQkJCWRlbGV0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICdjYXBhYmlsaXRpZXMnICk7CgkJCQlkZWxldGVfdXNlcl9vcHRpb24oICR1c2VyX2lkLCAndXNlcl9sZXZlbCcgKTsKCQkJfQoKCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2lkJywgJHVzZXJfaWQgKTsKCQkJZm9yZWFjaCAoICRzZWNvbmRhcnlfcm9sZXMgYXMgJHNlY29uZGFyeV9yb2xlICkgewoJCQkJJHVzZXItPmFkZF9yb2xlKCAkc2Vjb25kYXJ5X3JvbGUgKTsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkZXhpc3RpbmdfdXNlciApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAkbmV3X3VzZXJbJ3VzZXJfbG9naW4nXSAuICcgdXBkYXRlZC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICRuZXdfdXNlclsndXNlcl9sb2dpbiddIC4gJyBjcmVhdGVkLicgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFJlc2V0cyB0aGUgcGFzc3dvcmQgZm9yIG9uZSBvciBtb3JlIHVzZXJzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4uLi4KCSAqIDogb25lIG9yIG1vcmUgdXNlciBsb2dpbnMgb3IgSURzLgoJICoKCSAqIFstLXNraXAtZW1haWxdCgkgKiA6IERvbid0IHNlbmQgYW4gZW1haWwgbm90aWZpY2F0aW9uIHRvIHRoZSBhZmZlY3RlZCB1c2VyKHMpLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVzZXQgdGhlIHBhc3N3b3JkIGZvciB0d28gdXNlcnMgYW5kIHNlbmQgdGhlbSB0aGUgY2hhbmdlIGVtYWlsLgoJICogICAgICQgd3AgdXNlciByZXNldC1wYXNzd29yZCBhZG1pbiBlZGl0b3IKCSAqICAgICBSZXNldCBwYXNzd29yZCBmb3IgYWRtaW4uCgkgKiAgICAgUmVzZXQgcGFzc3dvcmQgZm9yIGVkaXRvci4KCSAqICAgICBTdWNjZXNzOiBQYXNzd29yZHMgcmVzZXQgZm9yIDIgdXNlcnMuCgkgKgoJICogQHN1YmNvbW1hbmQgcmVzZXQtcGFzc3dvcmQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlc2V0X3Bhc3N3b3JkKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHNraXBfZW1haWwgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWVtYWlsJyApOwoJCWlmICggJHNraXBfZW1haWwgKSB7CgkJCWFkZF9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQl9CgkJJGZldGNoZXIgPSBuZXcgVXNlckZldGNoZXIoKTsKCQkkdXNlcnMgICA9ICRmZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQlmb3JlYWNoICggJHVzZXJzIGFzICR1c2VyICkgewoJCQl3cF91cGRhdGVfdXNlcigKCQkJCVsKCQkJCQknSUQnICAgICAgICA9PiAkdXNlci0+SUQsCgkJCQkJJ3VzZXJfcGFzcycgPT4gd3BfZ2VuZXJhdGVfcGFzc3dvcmQoKSwKCQkJCV0KCQkJKTsKCQkJV1BfQ0xJOjpsb2coICJSZXNldCBwYXNzd29yZCBmb3IgeyR1c2VyLT51c2VyX2xvZ2lufS4iICk7CgkJfQoJCWlmICggJHNraXBfZW1haWwgKSB7CgkJCXJlbW92ZV9maWx0ZXIoICdzZW5kX3Bhc3N3b3JkX2NoYW5nZV9lbWFpbCcsICdfX3JldHVybl9mYWxzZScgKTsKCQl9CgoJCSRyZXNldF91c2VyX2NvdW50ID0gY291bnQoICR1c2VycyApOwoJCWlmICggMSA9PT0gJHJlc2V0X3VzZXJfY291bnQgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlBhc3N3b3JkIHJlc2V0IGZvciB7JHJlc2V0X3VzZXJfY291bnR9IHVzZXIuIiApOwoJCX0gZWxzZWlmICggJHJlc2V0X3VzZXJfY291bnQgPiAxICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJQYXNzd29yZHMgcmVzZXQgZm9yIHskcmVzZXRfdXNlcl9jb3VudH0gdXNlcnMuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyB1c2VyIGZvdW5kIHRvIHJlc2V0IHBhc3N3b3JkLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciB0aGUgcm9sZSBpcyB2YWxpZAoJICoKCSAqIEBwYXJhbSBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdmFsaWRhdGVfcm9sZSggJHJvbGUgKSB7CgoJCWlmICggISBlbXB0eSggJHJvbGUgKSAmJiBudWxsID09PSBnZXRfcm9sZSggJHJvbGUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlJvbGUgZG9lc24ndCBleGlzdDogeyRyb2xlfSIgKTsKCQl9CgoJfQoKCS8qKgoJICogQWNjb21tb2RhdGVzIHRocmVlIGRpZmZlcmVudCBiZWhhdmlvcnMgZm9yIHdwX25ld191c2VyX25vdGlmaWNhdGlvbigpCgkgKiAtIDQuMy4xIGFuZCBhYm92ZTogZXhwZWN0IHNlY29uZCBhcmd1bWVudCB0byBiZSBkZXByZWNhdGVkCgkgKiAtIDQuMzogU2Vjb25kIGFyZ3VtZW50IHdhcyByZXB1cnBvc2VkIGFzICRub3RpZnkKCSAqIC0gQmVsb3cgNC4zOiBTZW5kIHRoZSBwYXNzd29yZCBpbiB0aGUgbm90aWZpY2F0aW9uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXNlcl9pZAoJICogQHBhcmFtIHN0cmluZyAkcGFzc3dvcmQKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkcGFzc3dvcmQgKSB7CgkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjMuMScsICc+PScgKSApIHsKCQkJd3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uKCAkdXNlcl9pZCwgbnVsbCwgJ2JvdGgnICk7CgkJfSBlbHNlaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjMnLCAnPj0nICkgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuRGVwcmVjYXRlZFBhcmFtZXRlcnMuV3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uUGFyYW0yRm91bmQgLS0gT25seSBjYWxsZWQgaW4gdmFsaWQgY29uZGl0aW9ucy4KCQkJd3BfbmV3X3VzZXJfbm90aWZpY2F0aW9uKCAkdXNlcl9pZCwgJ2JvdGgnICk7CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkUGFyYW1ldGVycy5XcF9uZXdfdXNlcl9ub3RpZmljYXRpb25QYXJhbTJGb3VuZCAtLSBPbmx5IGNhbGxlZCBpbiB2YWxpZCBjb25kaXRpb25zLgoJCQl3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkcGFzc3dvcmQgKTsKCQl9Cgl9CgoJLyoqCgkgKiBNYXJrcyBvbmUgb3IgbW9yZSB1c2VycyBhcyBzcGFtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiB1c2VycyB0byBtYXJrIGFzIHNwYW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB1c2VyIHNwYW0gMTIzCgkgKiAgICAgVXNlciAxMjMgbWFya2VkIGFzIHNwYW0uCgkgKiAgICAgU3VjY2VzczogU3BhbWVkIDEgb2YgMSB1c2Vycy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNwYW0oICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfbXN1c2VyX3N0YXR1cyggJGFyZ3MsICdzcGFtJywgJzEnICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIG9uZSBvciBtb3JlIHVzZXJzIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgdXNlcnMgdG8gcmVtb3ZlIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHVzZXIgdW5zcGFtIDEyMwoJICogICAgIFVzZXIgMTIzIHJlbW92ZWQgZnJvbSBzcGFtLgoJICogICAgIFN1Y2Nlc3M6IFVuc3BhbWVkIDEgb2YgMSB1c2Vycy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuc3BhbSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9tc3VzZXJfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAnMCcgKTsKCX0KCgkvKioKCSAqIENvbW1vbiBjb21tYW5kIGZvciB1cGRhdGluZyB1c2VyIGRhdGEuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdXBkYXRlX21zdXNlcl9zdGF0dXMoICR1c2VyX2lkcywgJHByZWYsICR2YWx1ZSApIHsKCgkJLy8gSWYgc2l0ZSBpcyBub3QgbXVsdGlzaXRlLCB0aGVuIHN0b3AgZXhlY3V0aW9uLgoJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJfQoKCQlpZiAoICdzcGFtJyA9PT0gJHByZWYgKSB7CgkJCSRhY3Rpb24gPSAoaW50KSAkdmFsdWUgPyAnbWFya2VkIGFzIHNwYW0nIDogJ3JlbW92ZWQgZnJvbSBzcGFtJzsKCQkJJHZlcmIgICA9IChpbnQpICR2YWx1ZSA/ICdzcGFtJyA6ICd1bnNwYW0nOwoJCX0KCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJJHVzZXJzICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJHVzZXJfaWRzICk7CgkJaWYgKCBjb3VudCggJHVzZXJzICkgPCBjb3VudCggJHVzZXJfaWRzICkgKSB7CgkJCSRlcnJvcnMgPSBjb3VudCggJHVzZXJfaWRzICkgLSBjb3VudCggJHVzZXJzICk7CgkJfQoKCQlmb3JlYWNoICggJHVzZXJfaWRzIGFzICR1c2VyX2lkICkgewoKCQkJJHVzZXIgPSBnZXRfdXNlcmRhdGEoICR1c2VyX2lkICk7CgoJCQkvLyBJZiBubyB1c2VyIGZvdW5kLCB0aGVuIHNob3cgd2FybmluZy4KCQkJaWYgKCBlbXB0eSggJHVzZXIgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlVzZXIgeyR1c2VyX2lkfSBkb2Vzbid0IGV4aXN0LiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBTdXBlciBhZG1pbiBzaG91bGQgbm90IGJlIG1hcmtlZCBhcyBzcGFtLgoJCQlpZiAoIGlzX3N1cGVyX2FkbWluKCAkdXNlci0+SUQgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlVzZXIgY2Fubm90IGJlIG1vZGlmaWVkLiBUaGUgdXNlciB7JHVzZXItPklEfSBpcyBhIG5ldHdvcmsgYWRtaW5pc3RyYXRvci4iICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gU2tpcCBpZiB1c2VyIGlzIGFscmVhZHkgbWFya2VkIGFzIHNwYW0gYW5kIHNob3cgd2FybmluZy4KCQkJaWYgKCAkdmFsdWUgPT09ICR1c2VyLT5zcGFtICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVXNlciB7JHVzZXJfaWR9IGFscmVhZHkgeyRhY3Rpb259LiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBNYWtlIHRoYXQgdXNlcidzIGJsb2cgYXMgc3BhbSB0b28uCgkJCSRibG9ncyA9IChhcnJheSkgZ2V0X2Jsb2dzX29mX3VzZXIoICR1c2VyX2lkLCB0cnVlICk7CgkJCWZvcmVhY2ggKCAkYmxvZ3MgYXMgJGRldGFpbHMgKSB7CgkJCQkkc2l0ZSA9ICR0aGlzLT5zaXRlZmV0Y2hlci0+Z2V0X2NoZWNrKCAkZGV0YWlscy0+c2l0ZV9pZCApOwoKCQkJCS8vIE1haW4gYmxvZyBzaG91bGRuJ3QgYSBzcGFtICEKCQkJCWlmICggJGRldGFpbHMtPnVzZXJibG9nX2lkICE9PSAkc2l0ZS0+YmxvZ19pZCApIHsKCQkJCQl1cGRhdGVfYmxvZ19zdGF0dXMoICRkZXRhaWxzLT51c2VyYmxvZ19pZCwgJHByZWYsICR2YWx1ZSApOwoJCQkJfQoJCQl9CgoJCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzUuMycsICc8JyApICkgewoJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLnVwZGF0ZV91c2VyX3N0YXR1c0ZvdW5kIC0tIEZhbGxiYWNrIGZvciBvbGRlciB2ZXJzaW9ucy4KCQkJCXVwZGF0ZV91c2VyX3N0YXR1cyggJHVzZXJfaWQsICRwcmVmLCAkdmFsdWUgKTsKCQkJfSBlbHNlIHsKCQkJCXdwX3VwZGF0ZV91c2VyKAoJCQkJCVsKCQkJCQkJJ0lEJyAgPT4gJHVzZXJfaWQsCgkJCQkJCSRwcmVmID0+ICR2YWx1ZSwKCQkJCQldCgkJCQkpOwoJCQl9CgoJCQlXUF9DTEk6OmxvZyggIlVzZXIgeyR1c2VyX2lkfSB7JGFjdGlvbn0uIiApOwoJCQkkc3VjY2Vzc2VzKys7CgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICd1c2VyJywgJHZlcmIsIGNvdW50KCAkdXNlcl9pZHMgKSwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgdXNlcidzIHBhc3N3b3JkIGlzIHZhbGlkIG9yIG5vdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsIG9yIHVzZXIgSUQgb2YgdGhlIHVzZXIgdG8gY2hlY2sgY3JlZGVudGlhbHMgZm9yLgoJICoKCSAqIDx1c2VyX3Bhc3M+CgkgKiA6IEEgc3RyaW5nIHRoYXQgY29udGFpbnMgdGhlIHBsYWluIHRleHQgcGFzc3dvcmQgZm9yIHRoZSB1c2VyLgoJICoKCSAqIFstLWVzY2FwZS1jaGFyc10KCSAqIDogRXNjYXBlIHBhc3N3b3JkIHdpdGggYHdwX3NsYXNoKClgIHRvIG1pbWljIHRoZSBzYW1lIGJlaGF2aW9yIGFzIGB3cC1sb2dpbi5waHBgLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgd2hldGhlciBnaXZlbiBjcmVkZW50aWFscyBhcmUgdmFsaWQ7IGV4aXQgc3RhdHVzIDAgaWYgdmFsaWQsIG90aGVyd2lzZSAxCgkgKiAgICAgJCB3cCB1c2VyIGNoZWNrLXBhc3N3b3JkIGFkbWluIGFkbWlucGFzcwoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiAgICAgIyBCYXNoIHNjcmlwdCBmb3IgY2hlY2tpbmcgd2hldGhlciBnaXZlbiBjcmVkZW50aWFscyBhcmUgdmFsaWQgb3Igbm90CgkgKiAgICAgaWYgISAkKHdwIHVzZXIgY2hlY2stcGFzc3dvcmQgYWRtaW4gYWRtaW5wYXNzKTsgdGhlbgoJICogICAgICBub3RpZnktc2VuZCAiSW52YWxpZCBDcmVkZW50aWFscyI7CgkgKiAgICAgZmkKCSAqCgkgKiBAc3ViY29tbWFuZCBjaGVjay1wYXNzd29yZAoJICovCglwdWJsaWMgZnVuY3Rpb24gY2hlY2tfcGFzc3dvcmQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZXNjYXBlX2NoYXJzID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZXNjYXBlLWNoYXJzJywgZmFsc2UgKTsKCgkJaWYgKCAhICRlc2NhcGVfY2hhcnMgJiYgd3Bfc2xhc2goIHdwX3Vuc2xhc2goICRhcmdzWzFdICkgKSAhPT0gJGFyZ3NbMV0gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1Bhc3N3b3JkIGNvbnRhaW5zIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVzY2FwZWQuIFBsZWFzZSBlc2NhcGUgdGhlbSBtYW51YWxseSBvciB1c2UgdGhlIGAtLWVzY2FwZS1jaGFyc2Agb3B0aW9uLicgKTsKCQl9CgoJCSR1c2VyICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSR1c2VyX3Bhc3MgPSAkZXNjYXBlX2NoYXJzID8gd3Bfc2xhc2goICRhcmdzWzFdICkgOiAkYXJnc1sxXTsKCgkJaWYgKCB3cF9jaGVja19wYXNzd29yZCggJHVzZXJfcGFzcywgJHVzZXItPmRhdGEtPnVzZXJfcGFzcywgJHVzZXItPklEICkgKSB7CgkJCVdQX0NMSTo6aGFsdCggMCApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KCn0KPD9waHAKCnVzZSBXUF9DTElcRW50aXR5XFJlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXI7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEVudGl0eVxVdGlscyBhcyBFbnRpdHlVdGlsczsKCi8qKgogKiBSZXRyaWV2ZXMgYW5kIHNldHMgc2l0ZSBvcHRpb25zLCBpbmNsdWRpbmcgcGx1Z2luIGFuZCBXb3JkUHJlc3Mgc2V0dGluZ3MuCiAqCiAqIFNlZSB0aGUgW1BsdWdpbiBTZXR0aW5ncyBBUEldKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcGx1Z2lucy9zZXR0aW5ncy9zZXR0aW5ncy1hcGkvKSBhbmQgdGhlIFtUaGVtZSBPcHRpb25zXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9jdXN0b21pemUtYXBpLykgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gYWRkaW5nIGN1c3RvbWl6ZWQgb3B0aW9ucy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgR2V0IHNpdGUgVVJMLgogKiAgICAgJCB3cCBvcHRpb24gZ2V0IHNpdGV1cmwKICogICAgIGh0dHA6Ly9leGFtcGxlLmNvbQogKgogKiAgICAgIyBBZGQgb3B0aW9uLgogKiAgICAgJCB3cCBvcHRpb24gYWRkIG15X29wdGlvbiBmb29iYXIKICogICAgIFN1Y2Nlc3M6IEFkZGVkICdteV9vcHRpb24nIG9wdGlvbi4KICoKICogICAgICMgVXBkYXRlIG9wdGlvbi4KICogICAgICQgd3Agb3B0aW9uIHVwZGF0ZSBteV9vcHRpb24gJ3siZm9vIjogImJhciJ9JyAtLWZvcm1hdD1qc29uCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdteV9vcHRpb24nIG9wdGlvbi4KICoKICogICAgICMgRGVsZXRlIG9wdGlvbi4KICogICAgICQgd3Agb3B0aW9uIGRlbGV0ZSBteV9vcHRpb24KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ215X29wdGlvbicgb3B0aW9uLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIE9wdGlvbl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogR2V0cyB0aGUgdmFsdWUgZm9yIGFuIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgb3B0aW9uLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogR2V0IHZhbHVlIGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHZhcl9leHBvcnQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdmFyX2V4cG9ydAoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBvcHRpb24uCgkgKiAgICAgJCB3cCBvcHRpb24gZ2V0IGhvbWUKCSAqICAgICBodHRwOi8vZXhhbXBsZS5jb20KCSAqCgkgKiAgICAgIyBHZXQgYmxvZyBkZXNjcmlwdGlvbi4KCSAqICAgICAkIHdwIG9wdGlvbiBnZXQgYmxvZ2Rlc2NyaXB0aW9uCgkgKiAgICAgQSByYW5kb20gYmxvZyBkZXNjcmlwdGlvbgoJICoKCSAqICAgICAjIEdldCBibG9nIG5hbWUKCSAqICAgICAkIHdwIG9wdGlvbiBnZXQgYmxvZ25hbWUKCSAqICAgICBBIHJhbmRvbSBibG9nIG5hbWUKCSAqCgkgKiAgICAgIyBHZXQgYWRtaW4gZW1haWwuCgkgKiAgICAgJCB3cCBvcHRpb24gZ2V0IGFkbWluX2VtYWlsCgkgKiAgICAgc29tZW9uZUBleGFtcGxlLmNvbQoJICoKCSAqICAgICAjIEdldCBvcHRpb24gaW4gSlNPTiBmb3JtYXQuCgkgKiAgICAgJCB3cCBvcHRpb24gZ2V0IGFjdGl2ZV9wbHVnaW5zIC0tZm9ybWF0PWpzb24KCSAqICAgICB7IjAiOiJkeW5hbWljYWxseS1keW5hbWljLXNpZGViYXJcL2R5bmFtaWNhbGx5LWR5bmFtaWMtc2lkZWJhci5waHAiLCIxIjoibW9uc3Rlci13aWRnZXRcL21vbnN0ZXItd2lkZ2V0LnBocCIsIjIiOiJzaG93LWN1cnJlbnQtdGVtcGxhdGVcL3Nob3ctY3VycmVudC10ZW1wbGF0ZS5waHAiLCIzIjoidGhlbWUtY2hlY2tcL3RoZW1lLWNoZWNrLnBocCIsIjUiOiJ3b3JkcHJlc3MtaW1wb3J0ZXJcL3dvcmRwcmVzcy1pbXBvcnRlci5waHAifQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSApID0gJGFyZ3M7CgoJCSR2YWx1ZSA9IGdldF9vcHRpb24oICRrZXkgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGdldCAneyRrZXl9JyBvcHRpb24uIERvZXMgaXQgZXhpc3Q/IiApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogQWRkcyBhIG5ldyBvcHRpb24gdmFsdWUuCgkgKgoJICogRXJyb3JzIGlmIHRoZSBvcHRpb24gYWxyZWFkeSBleGlzdHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBvcHRpb24gdG8gYWRkLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgdmFsdWUgb2YgdGhlIG9wdGlvbiB0byBhZGQuIElmIG9tbWl0ZWQsIHRoZSB2YWx1ZSBpcyByZWFkIGZyb20gU1RESU4uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqIFstLWF1dG9sb2FkPTxhdXRvbG9hZD5dCgkgKiA6IFNob3VsZCB0aGlzIG9wdGlvbiBiZSBhdXRvbWF0aWNhbGx5IGxvYWRlZC4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSAneWVzJwoJICogICAtICdubycKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIGFuIG9wdGlvbiBieSByZWFkaW5nIGEgSlNPTiBmaWxlLgoJICogICAgICQgd3Agb3B0aW9uIGFkZCBteV9vcHRpb24gLS1mb3JtYXQ9anNvbiA8IGNvbmZpZy5qc29uCgkgKiAgICAgU3VjY2VzczogQWRkZWQgJ215X29wdGlvbicgb3B0aW9uLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGtleSA9ICRhcmdzWzBdOwoKCQkkdmFsdWUgPSBXUF9DTEk6OmdldF92YWx1ZV9mcm9tX2FyZ19vcl9zdGRpbiggJGFyZ3MsIDEgKTsKCQkkdmFsdWUgPSBXUF9DTEk6OnJlYWRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhdXRvbG9hZCcgKSA9PT0gJ25vJyApIHsKCQkJJGF1dG9sb2FkID0gJ25vJzsKCQl9IGVsc2UgewoJCQkkYXV0b2xvYWQgPSAneWVzJzsKCQl9CgoJCWlmICggISBhZGRfb3B0aW9uKCAka2V5LCAkdmFsdWUsICcnLCAkYXV0b2xvYWQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBhZGQgb3B0aW9uICd7JGtleX0nLiBEb2VzIGl0IGFscmVhZHkgZXhpc3Q/IiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkICd7JGtleX0nIG9wdGlvbi4iICk7CgkJfQoJfQoKCS8qKgoJICogTGlzdHMgb3B0aW9ucyBhbmQgdGhlaXIgdmFsdWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1zZWFyY2g9PHBhdHRlcm4+XQoJICogOiBVc2Ugd2lsZGNhcmRzICggKiBhbmQgPyApIHRvIG1hdGNoIG9wdGlvbiBuYW1lLgoJICoKCSAqIFstLWV4Y2x1ZGU9PHBhdHRlcm4+XQoJICogOiBQYXR0ZXJuIHRvIGV4Y2x1ZGUuIFVzZSB3aWxkY2FyZHMgKCAqIGFuZCA/ICkgdG8gbWF0Y2ggb3B0aW9uIG5hbWUuCgkgKgoJICogWy0tYXV0b2xvYWQ9PHZhbHVlPl0KCSAqIDogTWF0Y2ggb25seSBhdXRvbG9hZCBvcHRpb25zIHdoZW4gdmFsdWUgaXMgb24sIGFuZCBvbmx5IG5vdC1hdXRvbG9hZCBvcHRpb24gd2hlbiBvZmYuCgkgKgoJICogWy0tdHJhbnNpZW50c10KCSAqIDogTGlzdCBvbmx5IHRyYW5zaWVudHMuIFVzZSBgLS1uby10cmFuc2llbnRzYCB0byBpZ25vcmUgYWxsIHRyYW5zaWVudHMuCgkgKgoJICogWy0tdW5zZXJpYWxpemVdCgkgKiA6IFVuc2VyaWFsaXplIG9wdGlvbiB2YWx1ZXMgaW4gb3V0cHV0LgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4gdG90YWxfYnl0ZXMgZGlzcGxheXMgdGhlIHRvdGFsIHNpemUgb2YgbWF0Y2hpbmcgb3B0aW9ucyBpbiBieXRlcy4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBqc29uCgkgKiAgIC0gY3N2CgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAgIC0gdG90YWxfYnl0ZXMKCSAqIC0tLQoJICoKCSAqIFstLW9yZGVyYnk9PGZpZWxkcz5dCgkgKiA6IFNldCBvcmRlcmJ5IHdoaWNoIGZpZWxkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBvcHRpb25faWQKCSAqIG9wdGlvbnM6CgkgKiAgLSBvcHRpb25faWQKCSAqICAtIG9wdGlvbl9uYW1lCgkgKiAgLSBvcHRpb25fdmFsdWUKCSAqIC0tLQoJICoKCSAqIFstLW9yZGVyPTxvcmRlcj5dCgkgKiA6IFNldCBhc2NlbmRpbmcgb3IgZGVzY2VuZGluZyBvcmRlci4KCSAqIC0tLQoJICogZGVmYXVsdDogYXNjCgkgKiBvcHRpb25zOgoJICogIC0gYXNjCgkgKiAgLSBkZXNjCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhpcyBmaWVsZCB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIG1hdGNoaW5nIG9wdGlvbjoKCSAqCgkgKiAqIG9wdGlvbl9uYW1lCgkgKiAqIG9wdGlvbl92YWx1ZQoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBhdXRvbG9hZAoJICogKiBzaXplX2J5dGVzCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgdGhlIHRvdGFsIHNpemUgb2YgYWxsIGF1dG9sb2FkIG9wdGlvbnMuCgkgKiAgICAgJCB3cCBvcHRpb24gbGlzdCAtLWF1dG9sb2FkPW9uIC0tZm9ybWF0PXRvdGFsX2J5dGVzCgkgKiAgICAgMzMxOTgKCSAqCgkgKiAgICAgIyBGaW5kIGJpZ2dlc3QgdHJhbnNpZW50cy4KCSAqICAgICAkIHdwIG9wdGlvbiBsaXN0IC0tc2VhcmNoPSIqX3RyYW5zaWVudF8qIiAtLWZpZWxkcz1vcHRpb25fbmFtZSxzaXplX2J5dGVzIHwgc29ydCAtbiAtayAyIHwgdGFpbAoJICogICAgIG9wdGlvbl9uYW1lIHNpemVfYnl0ZXMKCSAqICAgICBfc2l0ZV90cmFuc2llbnRfdGltZW91dF90aGVtZV9yb290cyAxMAoJICogICAgIF9zaXRlX3RyYW5zaWVudF90aGVtZV9yb290cyA3NgoJICogICAgIF9zaXRlX3RyYW5zaWVudF91cGRhdGVfdGhlbWVzICAgMTgxCgkgKiAgICAgX3NpdGVfdHJhbnNpZW50X3VwZGF0ZV9jb3JlIDgwOAoJICogICAgIF9zaXRlX3RyYW5zaWVudF91cGRhdGVfcGx1Z2lucyAgNjY0NQoJICoKCSAqICAgICAjIExpc3QgYWxsIG9wdGlvbnMgYmVnaW5uaW5nIHdpdGggImkyZl8iLgoJICogICAgICQgd3Agb3B0aW9uIGxpc3QgLS1zZWFyY2g9ImkyZl8qIgoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgb3B0aW9uX25hbWUgfCBvcHRpb25fdmFsdWUgfAoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgaTJmX3ZlcnNpb24gfCAwLjEuMCAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgb3B0aW9ucyBiZWdpbm5pbmcgd2l0aCAidGhlbWVfbW9kc18iLgoJICogICAgICQgd3Agb3B0aW9uIGxpc3QgLS1zZWFyY2g9InRoZW1lX21vZHNfKiIgLS1maWVsZD1vcHRpb25fbmFtZSB8IHhhcmdzIC1JICUgd3Agb3B0aW9uIGRlbGV0ZSAlCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAndGhlbWVfbW9kc190d2VudHlzaXh0ZWVuJyBvcHRpb24uCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAndGhlbWVfbW9kc190d2VudHlmaWZ0ZWVuJyBvcHRpb24uCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAndGhlbWVfbW9kc190d2VudHlmb3VydGVlbicgb3B0aW9uLgoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWdsb2JhbCAkd3BkYjsKCQkkcGF0dGVybiAgICAgICAgPSAnJSc7CgkJJGV4Y2x1ZGUgICAgICAgID0gJyc7CgkJJGZpZWxkcyAgICAgICAgID0gYXJyYXkoICdvcHRpb25fbmFtZScsICdvcHRpb25fdmFsdWUnICk7CgkJJHNpemVfcXVlcnkgICAgID0gJyxMRU5HVEgob3B0aW9uX3ZhbHVlKSBBUyBgc2l6ZV9ieXRlc2AnOwoJCSRhdXRvbG9hZF9xdWVyeSA9ICcnOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKSApIHsKCQkJJHBhdHRlcm4gPSBzZWxmOjplc2NfbGlrZSggJGFzc29jX2FyZ3NbJ3NlYXJjaCddICk7CgkJCS8vIHN1YnN0aXR1dGUgd2lsZGNhcmRzCgkJCSRwYXR0ZXJuID0gc3RyX3JlcGxhY2UoICcqJywgJyUnLCAkcGF0dGVybiApOwoJCQkkcGF0dGVybiA9IHN0cl9yZXBsYWNlKCAnPycsICdfJywgJHBhdHRlcm4gKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydleGNsdWRlJ10gKSApIHsKCQkJJGV4Y2x1ZGUgPSBzZWxmOjplc2NfbGlrZSggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGUnXSApOwoJCQkkZXhjbHVkZSA9IHN0cl9yZXBsYWNlKCAnKicsICclJywgJGV4Y2x1ZGUgKTsKCQkJJGV4Y2x1ZGUgPSBzdHJfcmVwbGFjZSggJz8nLCAnXycsICRleGNsdWRlICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJGZpZWxkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ3RvdGFsX2J5dGVzJyApIHsKCQkJJGZpZWxkcyAgICAgPSBhcnJheSggJ3NpemVfYnl0ZXMnICk7CgkJCSRzaXplX3F1ZXJ5ID0gJyxTVU0oTEVOR1RIKG9wdGlvbl92YWx1ZSkpIEFTIGBzaXplX2J5dGVzYCc7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snYXV0b2xvYWQnXSApICkgewoJCQlpZiAoICdvbicgPT09ICRhc3NvY19hcmdzWydhdXRvbG9hZCddICkgewoJCQkJJGF1dG9sb2FkX3F1ZXJ5ID0gIiBBTkQgYXV0b2xvYWQ9J3llcyciOwoJCQl9IGVsc2VpZiAoICdvZmYnID09PSAkYXNzb2NfYXJnc1snYXV0b2xvYWQnXSApIHsKCQkJCSRhdXRvbG9hZF9xdWVyeSA9ICIgQU5EIGF1dG9sb2FkPSdubyciOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggIlZhbHVlIG9mICctLWF1dG9sb2FkJyBzaG91bGQgYmUgb24gb3Igb2ZmLiIgKTsKCQkJfQoJCX0KCgkJLy8gQnkgZGVmYXVsdCB3ZSBkb24ndCB3YW50IHRvIGRpc3BsYXkgdHJhbnNpZW50cy4KCQkkc2hvd190cmFuc2llbnRzID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndHJhbnNpZW50cycsIGZhbHNlICk7CgoJCWlmICggJHNob3dfdHJhbnNpZW50cyApIHsKCQkJJHRyYW5zaWVudHNfcXVlcnkgPSAiIEFORCBvcHRpb25fbmFtZSBMSUtFICdcX3RyYW5zaWVudFxfJScKCQkJT1Igb3B0aW9uX25hbWUgTElLRSAnXF9zaXRlXF90cmFuc2llbnRcXyUnIjsKCQl9IGVsc2UgewoJCQkkdHJhbnNpZW50c19xdWVyeSA9ICIgQU5EIG9wdGlvbl9uYW1lIE5PVCBMSUtFICdcX3RyYW5zaWVudFxfJScKCQkJQU5EIG9wdGlvbl9uYW1lIE5PVCBMSUtFICdcX3NpdGVcX3RyYW5zaWVudFxfJSciOwoJCX0KCgkJJHdoZXJlID0gJyc7CgkJaWYgKCAkcGF0dGVybiApIHsKCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKCAnV0hFUkUgYG9wdGlvbl9uYW1lYCBMSUtFICVzJywgJHBhdHRlcm4gKTsKCQl9CgoJCWlmICggJGV4Y2x1ZGUgKSB7CgkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSggJyBBTkQgYG9wdGlvbl9uYW1lYCBOT1QgTElLRSAlcycsICRleGNsdWRlICk7CgkJfQoJCSR3aGVyZSAuPSAkYXV0b2xvYWRfcXVlcnkgLiAkdHJhbnNpZW50c19xdWVyeTsKCgkJLy8gcGhwY3M6ZGlzYWJsZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwgLS0gSGFyZGNvZGVkIHF1ZXJ5IHBhcnRzIHdpdGhvdXQgdXNlciBpbnB1dC4KCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cygKCQkJJ1NFTEVDVCBgb3B0aW9uX25hbWVgLGBvcHRpb25fdmFsdWVgLGBhdXRvbG9hZGAnIC4gJHNpemVfcXVlcnkKCQkJLiAiIEZST00gYCR3cGRiLT5vcHRpb25zYCB7JHdoZXJlfSIKCQkpOwoJCS8vIHBocGNzOmVuYWJsZQoKCQkkb3JkZXJieSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ29yZGVyYnknICk7CgkJJG9yZGVyICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdvcmRlcicgKTsKCgkJLy8gU29ydCByZXN1bHQuCgkJaWYgKCAnb3B0aW9uX2lkJyAhPT0gJG9yZGVyYnkgKSB7CgkJCXVzb3J0KAoJCQkJJHJlc3VsdHMsCgkJCQlmdW5jdGlvbiAoICRhLCAkYiApIHVzZSAoICRvcmRlcmJ5LCAkb3JkZXIgKSB7CgkJCQkJLy8gU29ydCBhcnJheS4KCQkJCQlyZXR1cm4gJ2FzYycgPT09ICRvcmRlcgoJCQkJCQk/ICRhLT4kb3JkZXJieSA+ICRiLT4kb3JkZXJieQoJCQkJCQk6ICRhLT4kb3JkZXJieSA8ICRiLT4kb3JkZXJieTsKCQkJCX0KCQkJKTsKCQl9IGVsc2VpZiAoICdvcHRpb25faWQnID09PSAkb3JkZXJieSAmJiAnZGVzYycgPT09ICRvcmRlciApIHsgLy8gU29ydCBieSBkZWZhdWx0IGRlc2NlbmRpbmcuCgkJCWtyc29ydCggJHJlc3VsdHMgKTsKCQl9CgoJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndW5zZXJpYWxpemUnLCBudWxsICkgKSB7CgkJCWZvcmVhY2ggKCAkcmVzdWx0cyBhcyAkayA9PiAmJHYgKSB7CgkJCQlpZiAoICEgZW1wdHkoICR2LT5vcHRpb25fdmFsdWUgKSApIHsKCQkJCQkkdi0+b3B0aW9uX3ZhbHVlID0gbWF5YmVfdW5zZXJpYWxpemUoICR2LT5vcHRpb25fdmFsdWUgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICd0b3RhbF9ieXRlcycgKSB7CgkJCVdQX0NMSTo6bGluZSggJHJlc3VsdHNbMF0tPnNpemVfYnl0ZXMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcigKCQkJCSRhc3NvY19hcmdzLAoJCQkJJGZpZWxkcwoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkcmVzdWx0cyApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgYW4gb3B0aW9uIHZhbHVlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgb3B0aW9uIHRvIHVwZGF0ZS4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21taXRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1hdXRvbG9hZD08YXV0b2xvYWQ+XQoJICogOiBSZXF1aXJlcyBXUCA0LjIuIFNob3VsZCB0aGlzIG9wdGlvbiBiZSBhdXRvbWF0aWNhbGx5IGxvYWRlZC4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSAneWVzJwoJICogICAtICdubycKCSAqIC0tLQoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBhbiBvcHRpb24gYnkgcmVhZGluZyBmcm9tIGEgZmlsZS4KCSAqICAgICAkIHdwIG9wdGlvbiB1cGRhdGUgbXlfb3B0aW9uIDwgdmFsdWUudHh0CgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnbXlfb3B0aW9uJyBvcHRpb24uCgkgKgoJICogICAgICMgVXBkYXRlIG9uZSBvcHRpb24gb24gbXVsdGlwbGUgc2l0ZXMgdXNpbmcgeGFyZ3MuCgkgKiAgICAgJCB3cCBzaXRlIGxpc3QgLS1maWVsZD11cmwgfCB4YXJncyAtbjEgLUkge30gc2ggLWMgJ3dwIC0tdXJsPXt9IG9wdGlvbiB1cGRhdGUgbXlfb3B0aW9uIG15X3ZhbHVlJwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ215X29wdGlvbicgb3B0aW9uLgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgJ215X29wdGlvbicgb3B0aW9uLgoJICoKCSAqICAgICAjIFVwZGF0ZSBzaXRlIGJsb2cgbmFtZS4KCSAqICAgICAkIHdwIG9wdGlvbiB1cGRhdGUgYmxvZ25hbWUgIlJhbmRvbSBibG9nIG5hbWUiCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnYmxvZ25hbWUnIG9wdGlvbi4KCSAqCgkgKiAgICAgIyBVcGRhdGUgc2l0ZSBibG9nIGRlc2NyaXB0aW9uLgoJICogICAgICQgd3Agb3B0aW9uIHVwZGF0ZSBibG9nZGVzY3JpcHRpb24gIlNvbWUgcmFuZG9tIGJsb2cgZGVzY3JpcHRpb24iCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnYmxvZ2Rlc2NyaXB0aW9uJyBvcHRpb24uCgkgKgoJICogICAgICMgVXBkYXRlIGFkbWluIGVtYWlsIGFkZHJlc3MuCgkgKiAgICAgJCB3cCBvcHRpb24gdXBkYXRlIGFkbWluX2VtYWlsIHNvbWVvbmVAZXhhbXBsZS5jb20KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdhZG1pbl9lbWFpbCcgb3B0aW9uLgoJICoKCSAqICAgICAjIFNldCB0aGUgZGVmYXVsdCByb2xlLgoJICogICAgICQgd3Agb3B0aW9uIHVwZGF0ZSBkZWZhdWx0X3JvbGUgYXV0aG9yCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAnZGVmYXVsdF9yb2xlJyBvcHRpb24uCgkgKgoJICogICAgICMgU2V0IHRoZSB0aW1lem9uZSBzdHJpbmcuCgkgKiAgICAgJCB3cCBvcHRpb24gdXBkYXRlIHRpbWV6b25lX3N0cmluZyAiQW1lcmljYS9OZXdfWW9yayIKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICd0aW1lem9uZV9zdHJpbmcnIG9wdGlvbi4KCSAqCgkgKiBAYWxpYXMgc2V0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkka2V5ID0gJGFyZ3NbMF07CgoJCSR2YWx1ZSA9IFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgMSApOwoJCSR2YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoKCQkkYXV0b2xvYWQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhdXRvbG9hZCcgKTsKCQlpZiAoICEgaW5fYXJyYXkoICRhdXRvbG9hZCwgWyAneWVzJywgJ25vJyBdLCB0cnVlICkgKSB7CgkJCSRhdXRvbG9hZCA9IG51bGw7CgkJfQoKCQkkdmFsdWUgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksICR2YWx1ZSApOwoJCS8vIFNhbml0aXphdGlvbiBXb3JkUHJlc3Mgbm9ybWFsbHkgcGVyZm9ybXMgd2hlbiBnZXR0aW5nIGFuIG9wdGlvbgoJCWlmICggaW5fYXJyYXkoICRrZXksIFsgJ3NpdGV1cmwnLCAnaG9tZScsICdjYXRlZ29yeV9iYXNlJywgJ3RhZ19iYXNlJyBdLCB0cnVlICkgKSB7CgkJCSR2YWx1ZSA9IHVudHJhaWxpbmdzbGFzaGl0KCAkdmFsdWUgKTsKCQl9CgkJJG9sZF92YWx1ZSA9IHNhbml0aXplX29wdGlvbiggJGtleSwgZ2V0X29wdGlvbiggJGtleSApICk7CgoJCWlmICggJHZhbHVlID09PSAkb2xkX3ZhbHVlICYmIG51bGwgPT09ICRhdXRvbG9hZCApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVmFsdWUgcGFzc2VkIGZvciAneyRrZXl9JyBvcHRpb24gaXMgdW5jaGFuZ2VkLiIgKTsKCQl9IGVsc2UgewoJCQlpZiAoIHVwZGF0ZV9vcHRpb24oICRrZXksICR2YWx1ZSwgJGF1dG9sb2FkICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkICd7JGtleX0nIG9wdGlvbi4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHVwZGF0ZSBvcHRpb24gJ3ska2V5fScuIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhbiBvcHRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+Li4uCgkgKiA6IEtleSBmb3IgdGhlIG9wdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBhbiBvcHRpb24uCgkgKiAgICAgJCB3cCBvcHRpb24gZGVsZXRlIG15X29wdGlvbgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ215X29wdGlvbicgb3B0aW9uLgoJICoKCSAqICAgICAjIERlbGV0ZSBtdWx0aXBsZSBvcHRpb25zLgoJICogICAgICQgd3Agb3B0aW9uIGRlbGV0ZSBvcHRpb25fb25lIG9wdGlvbl90d28gb3B0aW9uX3RocmVlCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAnb3B0aW9uX29uZScgb3B0aW9uLgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ29wdGlvbl90d28nIG9wdGlvbi4KCSAqICAgICBXYXJuaW5nOiBDb3VsZCBub3QgZGVsZXRlICdvcHRpb25fdGhyZWUnIG9wdGlvbi4gRG9lcyBpdCBleGlzdD8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MgKSB7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCWlmICggISBkZWxldGVfb3B0aW9uKCAkYXJnICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJDb3VsZCBub3QgZGVsZXRlICd7JGFyZ30nIG9wdGlvbi4gRG9lcyBpdCBleGlzdD8iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJEZWxldGVkICd7JGFyZ30nIG9wdGlvbi4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbmVzdGVkIHZhbHVlIGZyb20gYW4gb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgb3B0aW9uIG5hbWUuCgkgKgoJICogPGtleS1wYXRoPi4uLgoJICogOiBUaGUgbmFtZShzKSBvZiB0aGUga2V5cyB3aXRoaW4gdGhlIHZhbHVlIHRvIGxvY2F0ZSB0aGUgdmFsdWUgdG8gcGx1Y2suCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgb3V0cHV0IGZvcm1hdCBvZiB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwbHVjayggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXkgKSA9ICRhcmdzOwoKCQkkdmFsdWUgPSBnZXRfb3B0aW9uKCAka2V5ICk7CgoJCWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoKCQkka2V5X3BhdGggPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAka2V5ICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgJiYgKCAoc3RyaW5nKSBpbnR2YWwoICRrZXkgKSA9PT0gJGtleSApICkgewoJCQkJCXJldHVybiAoaW50KSAka2V5OwoJCQkJfQoJCQkJCXJldHVybiAka2V5OwoJCQl9LAoJCQlhcnJheV9zbGljZSggJGFyZ3MsIDEgKQoJCSk7CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJHZhbHVlICk7CgoJCXRyeSB7CgkJCSR2YWx1ZSA9ICR0cmF2ZXJzZXItPmdldCggJGtleV9wYXRoICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlkaWUoIDEgKTsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgYSBuZXN0ZWQgdmFsdWUgaW4gYW4gb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8YWN0aW9uPgoJICogOiBQYXRjaCBhY3Rpb24gdG8gcGVyZm9ybS4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBpbnNlcnQKCSAqICAgLSB1cGRhdGUKCSAqICAgLSBkZWxldGUKCSAqIC0tLQoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBvcHRpb24gbmFtZS4KCSAqCgkgKiA8a2V5LXBhdGg+Li4uCgkgKiA6IFRoZSBuYW1lKHMpIG9mIHRoZSBrZXlzIHdpdGhpbiB0aGUgdmFsdWUgdG8gbG9jYXRlIHRoZSB2YWx1ZSB0byBwYXRjaC4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21pdHRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXRjaCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRhY3Rpb24sICRrZXkgKSA9ICRhcmdzOwoJCSRrZXlfcGF0aCAgICAgICAgICAgICA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRrZXkgKSB7CgkJCQlpZiAoIGlzX251bWVyaWMoICRrZXkgKSAmJiAoIChzdHJpbmcpIGludHZhbCggJGtleSApID09PSAka2V5ICkgKSB7CgkJCQkJcmV0dXJuIChpbnQpICRrZXk7CgkJCQl9CgkJCQkJcmV0dXJuICRrZXk7CgkJCX0sCgkJCWFycmF5X3NsaWNlKCAkYXJncywgMiApCgkJKTsKCgkJaWYgKCAnZGVsZXRlJyA9PT0gJGFjdGlvbiApIHsKCQkJJHBhdGNoX3ZhbHVlID0gbnVsbDsKCQl9IGVsc2UgewoJCQkkc3RkaW5fdmFsdWUgPSBFbnRpdHlVdGlsczo6aGFzX3N0ZGluKCkKCQkJCT8gdHJpbSggV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAtMSApICkKCQkJCTogbnVsbDsKCQkJJHBhdGNoX3ZhbHVlID0gISBlbXB0eSggJHN0ZGluX3ZhbHVlICkKCQkJCT8gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkc3RkaW5fdmFsdWUsICRhc3NvY19hcmdzICkKCQkJCTogV1BfQ0xJOjpyZWFkX3ZhbHVlKCBhcnJheV9wb3AoICRrZXlfcGF0aCApLCAkYXNzb2NfYXJncyApOwoJCX0KCgkJLyogTmVlZCB0byBtYWtlIGEgY29weSBvZiAkY3VycmVudF92YWx1ZSBoZXJlIGFzIGl0IGlzIG1vZGlmaWVkIGJ5IHJlZmVyZW5jZSAqLwoJCSRvbGRfdmFsdWUgICAgID0gc2FuaXRpemVfb3B0aW9uKCAka2V5LCBnZXRfb3B0aW9uKCAka2V5ICkgKTsKCQkkY3VycmVudF92YWx1ZSA9ICRvbGRfdmFsdWU7CgkJaWYgKCBpc19vYmplY3QoICRjdXJyZW50X3ZhbHVlICkgKSB7CgkJCSRvbGRfdmFsdWUgPSBjbG9uZSAkY3VycmVudF92YWx1ZTsKCQl9CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJGN1cnJlbnRfdmFsdWUgKTsKCgkJdHJ5IHsKCQkJJHRyYXZlcnNlci0+JGFjdGlvbiggJGtleV9wYXRoLCAkcGF0Y2hfdmFsdWUgKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJJHBhdGNoZWRfdmFsdWUgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksICR0cmF2ZXJzZXItPnZhbHVlKCkgKTsKCgkJaWYgKCAkcGF0Y2hlZF92YWx1ZSA9PT0gJG9sZF92YWx1ZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVmFsdWUgcGFzc2VkIGZvciAneyRrZXl9JyBvcHRpb24gaXMgdW5jaGFuZ2VkLiIgKTsKCQl9IGVsc2UgewoJCQlpZiAoIHVwZGF0ZV9vcHRpb24oICRrZXksICRwYXRjaGVkX3ZhbHVlICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkICd7JGtleX0nIG9wdGlvbi4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHVwZGF0ZSBvcHRpb24gJ3ska2V5fScuIiApOwoJCQl9CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGVzY19saWtlKCAkb2xkICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJLy8gUmVtb3ZlIG5vdGljZXMgaW4gNC4wIGFuZCBzdXBwb3J0IGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5CgkJaWYgKCBtZXRob2RfZXhpc3RzKCAkd3BkYiwgJ2VzY19saWtlJyApICkgewoJCQkvLyA0LjAKCQkJJG9sZCA9ICR3cGRiLT5lc2NfbGlrZSggJG9sZCApOwoJCX0gZWxzZSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuRGVwcmVjYXRlZEZ1bmN0aW9ucy5saWtlX2VzY2FwZUZvdW5kIC0tIGNhbGxlZCBpbiBXb3JkUHJlc3MgMy45IG9yIGxlc3MuCgkJCSRvbGQgPSBsaWtlX2VzY2FwZSggZXNjX3NxbCggJG9sZCApICk7CgkJfQoKCQlyZXR1cm4gJG9sZDsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aE1ldGE7CnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCBkZWxldGVzLCBhbmQgbGlzdHMgdXNlciBjdXN0b20gZmllbGRzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBZGQgdXNlciBtZXRhCiAqICAgICAkIHdwIHVzZXIgbWV0YSBhZGQgMTIzIGJpbyAiTWFyeSBpcyBhbiBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KICoKICogICAgICMgTGlzdCB1c2VyIG1ldGEKICogICAgICQgd3AgdXNlciBtZXRhIGxpc3QgMTIzIC0ta2V5cz1uaWNrbmFtZSxkZXNjcmlwdGlvbix3cF9jYXBhYmlsaXRpZXMKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICB8IHVzZXJfaWQgfCBtZXRhX2tleSAgICAgICAgfCBtZXRhX3ZhbHVlICAgICAgICAgICAgICAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgMTIzICAgICB8IG5pY2tuYW1lICAgICAgICB8IHN1cGVydmlzb3IgICAgICAgICAgICAgICAgICAgICB8CiAqICAgICB8IDEyMyAgICAgfCBkZXNjcmlwdGlvbiAgICAgfCBNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4gfAogKiAgICAgfCAxMjMgICAgIHwgd3BfY2FwYWJpbGl0aWVzIHwgeyJhZG1pbmlzdHJhdG9yIjp0cnVlfSAgICAgICAgIHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqCiAqICAgICAjIFVwZGF0ZSB1c2VyIG1ldGEKICogICAgICQgd3AgdXNlciBtZXRhIHVwZGF0ZSAxMjMgYmlvICJNYXJ5IGlzIGFuIGF3ZXNvbWUgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KICoKICogICAgICMgRGVsZXRlIHVzZXIgbWV0YQogKiAgICAgJCB3cCB1c2VyIG1ldGEgZGVsZXRlIDEyMyBiaW8KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY3VzdG9tIGZpZWxkLgogKi8KY2xhc3MgVXNlcl9NZXRhX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aE1ldGEgewoJcHJvdGVjdGVkICRtZXRhX3R5cGUgPSAndXNlcic7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFVzZXJGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBMaXN0cyBhbGwgbWV0YWRhdGEgYXNzb2NpYXRlZCB3aXRoIGEgdXNlci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsLCBvciB1c2VyIElEIG9mIHRoZSB1c2VyIHRvIGdldCBtZXRhZGF0YSBmb3IuCgkgKgoJICogWy0ta2V5cz08a2V5cz5dCgkgKiA6IExpbWl0IG91dHB1dCB0byBtZXRhZGF0YSBvZiBzcGVjaWZpYyBrZXlzLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyByb3cgZmllbGRzLiBEZWZhdWx0cyB0byBpZCxtZXRhX2tleSxtZXRhX3ZhbHVlLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqIFstLW9yZGVyYnk9PGZpZWxkcz5dCgkgKiA6IFNldCBvcmRlcmJ5IHdoaWNoIGZpZWxkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBpZAoJICogb3B0aW9uczoKCSAqICAtIGlkCgkgKiAgLSBtZXRhX2tleQoJICogIC0gbWV0YV92YWx1ZQoJICogLS0tCgkgKgoJICogWy0tb3JkZXI9PG9yZGVyPl0KCSAqIDogU2V0IGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhc2MKCSAqIG9wdGlvbnM6CgkgKiAgLSBhc2MKCSAqICAtIGRlc2MKCSAqIC0tLQoJICoKCSAqIFstLXVuc2VyaWFsaXplXQoJICogOiBVbnNlcmlhbGl6ZSBtZXRhX3ZhbHVlIG91dHB1dC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciBtZXRhCgkgKiAgICAgJCB3cCB1c2VyIG1ldGEgbGlzdCAxMjMgLS1rZXlzPW5pY2tuYW1lLGRlc2NyaXB0aW9uLHdwX2NhcGFiaWxpdGllcwoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCB1c2VyX2lkIHwgbWV0YV9rZXkgICAgICAgIHwgbWV0YV92YWx1ZSAgICAgICAgICAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMTIzICAgICB8IG5pY2tuYW1lICAgICAgICB8IHN1cGVydmlzb3IgICAgICAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCAxMjMgICAgIHwgZGVzY3JpcHRpb24gICAgIHwgTWFyeSBpcyBhIFdvcmRQcmVzcyBkZXZlbG9wZXIuIHwKCSAqICAgICB8IDEyMyAgICAgfCB3cF9jYXBhYmlsaXRpZXMgfCB7ImFkbWluaXN0cmF0b3IiOnRydWV9ICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCQlwYXJlbnQ6Omxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEdldHMgbWV0YSBmaWVsZCB2YWx1ZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsLCBvciB1c2VyIElEIG9mIHRoZSB1c2VyIHRvIGdldCBtZXRhZGF0YSBmb3IuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG1ldGFkYXRhIGtleS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgdXNlciBtZXRhCgkgKiAgICAgJCB3cCB1c2VyIG1ldGEgZ2V0IDEyMyBiaW8KCSAqICAgICBNYXJ5IGlzIGFuIFdvcmRQcmVzcyBkZXZlbG9wZXIuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCQlwYXJlbnQ6OmdldCggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsLCBvciB1c2VyIElEIG9mIHRoZSB1c2VyIHRvIGRlbGV0ZSBtZXRhZGF0YSBmcm9tLgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBtZXRhZGF0YSBrZXkuCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSB2YWx1ZSB0byBkZWxldGUuIElmIG9taXR0ZWQsIGFsbCByb3dzIHdpdGgga2V5IHdpbGwgZGVsZXRlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSB1c2VyIG1ldGEKCSAqICAgICAkIHdwIHVzZXIgbWV0YSBkZWxldGUgMTIzIGJpbwoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgY3VzdG9tIGZpZWxkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFyZ3MgPSAkdGhpcy0+cmVwbGFjZV9sb2dpbl93aXRoX3VzZXJfaWQoICRhcmdzICk7CgkJcGFyZW50OjpkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogQWRkcyBhIG1ldGEgZmllbGQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBUaGUgdXNlciBsb2dpbiwgdXNlciBlbWFpbCwgb3IgdXNlciBJRCBvZiB0aGUgdXNlciB0byBhZGQgbWV0YWRhdGEgZm9yLgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBtZXRhZGF0YSBrZXkuCgkgKgoJICogPHZhbHVlPgoJICogOiBUaGUgbmV3IG1ldGFkYXRhIHZhbHVlLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCB1c2VyIG1ldGEKCSAqICAgICAkIHdwIHVzZXIgbWV0YSBhZGQgMTIzIGJpbyAiTWFyeSBpcyBhbiBXb3JkUHJlc3MgZGV2ZWxvcGVyLiIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJncyA9ICR0aGlzLT5yZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKTsKCQlwYXJlbnQ6OmFkZCggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVzZXI+CgkgKiA6IFRoZSB1c2VyIGxvZ2luLCB1c2VyIGVtYWlsLCBvciB1c2VyIElEIG9mIHRoZSB1c2VyIHRvIHVwZGF0ZSBtZXRhZGF0YSBmb3IuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG1ldGFkYXRhIGtleS4KCSAqCgkgKiA8dmFsdWU+CgkgKiA6IFRoZSBuZXcgbWV0YWRhdGEgdmFsdWUuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVXBkYXRlIHVzZXIgbWV0YQoJICogICAgICQgd3AgdXNlciBtZXRhIHVwZGF0ZSAxMjMgYmlvICJNYXJ5IGlzIGFuIGF3ZXNvbWUgV29yZFByZXNzIGRldmVsb3Blci4iCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBjdXN0b20gZmllbGQgJ2JpbycuCgkgKgoJICogQGFsaWFzIHNldAoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFyZ3MgPSAkdGhpcy0+cmVwbGFjZV9sb2dpbl93aXRoX3VzZXJfaWQoICRhcmdzICk7CgkJcGFyZW50Ojp1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGFkZF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBib29sICAgJHVuaXF1ZSAgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIFdoZXRoZXIgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4gSWYgdHJ1ZSwgYW5kIHRoZSBvYmplY3QgYWxyZWFkeSBoYXMgYQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRhZGF0YSBrZXksIG5vIGNoYW5nZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIG1hZGUuCgkgKgoJICogQHJldHVybiBpbnR8ZmFsc2UgVGhlIG1ldGEgSUQgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSA9IGZhbHNlICkgewoJCXJldHVybiBhZGRfdXNlcl9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgdXBkYXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIG1peGVkICAkcHJldl92YWx1ZSBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCBvbmx5IHVwZGF0ZSBleGlzdGluZwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB1cGRhdGUgYWxsIGVudHJpZXMuCgkgKgoJICogQHJldHVybiBpbnR8Ym9vbCBNZXRhIElEIGlmIHRoZSBrZXkgZGlkbid0IGV4aXN0LCB0cnVlIG9uIHN1Y2Nlc3NmdWwKCSAqICAgICAgICAgICAgICAgICAgdXBkYXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSA9ICcnICkgewoJCXJldHVybiB1cGRhdGVfdXNlcl9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGdldF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgT3B0aW9uYWwuIE1ldGFkYXRhIGtleS4gSWYgbm90IHNwZWNpZmllZCwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZSBhbGwgbWV0YWRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgoJICogQHBhcmFtIGJvb2wgICAkc2luZ2xlICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBJZiB0cnVlLCByZXR1cm4gb25seQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LiBUaGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QgaWYgbWV0YV9rZXkgaXMgbm90CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQgU2luZ2xlIG1ldGFkYXRhIHZhbHVlLCBvciBhcnJheSBvZiB2YWx1ZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSA9ICcnLCAkc2luZ2xlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGdldF91c2VyX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNpbmdsZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGRlbGV0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCBtZXRhZGF0YSBpcyBmb3IKCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJG1ldGFfdmFsdWUgIE9wdGlvbmFsLiBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm9uLXNjYWxhci4gSWYgc3BlY2lmaWVkLCBvbmx5IGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhpcyB2YWx1ZS4gT3RoZXJ3aXNlLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWxsIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzIGBudWxsLCBgZmFsc2VgLCBvciBhbiBlbXB0eSBzdHJpbmcgdG8gc2tpcAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGNoZWNrLiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaXQgaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHBvc3NpYmxlIHRvIHBhc3MgYW4gZW1wdHkgc3RyaW5nIHRvIGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aG9zZSBlbnRyaWVzIHdpdGggYW4gZW1wdHkgc3RyaW5nIGZvciBhIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3NmdWwgZGVsZXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIGRlbGV0ZV91c2VyX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCX0KCgkvKioKCSAqIFJlcGxhY2VzIHVzZXJfbG9naW4gdmFsdWUgd2l0aCB1c2VyIElECgkgKiB1c2VyIG1ldGEgaXMgYSBzcGVjaWFsIGNhc2UgdGhhdCBhbHNvIHN1cHBvcnRzIHVzZXJfbG9naW4KCSAqCgkgKiBAcGFyYW0gYXJyYXkKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZXBsYWNlX2xvZ2luX3dpdGhfdXNlcl9pZCggJGFyZ3MgKSB7CgkJJHVzZXIgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSRhcmdzWzBdID0gJHVzZXItPklEOwoJCXJldHVybiAkYXJnczsKCX0KCn0KPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIEFzc2lnbnMsIHJlbW92ZXMsIGFuZCBsaXN0cyBhIG1lbnUncyBsb2NhdGlvbnMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgYXZhaWxhYmxlIG1lbnUgbG9jYXRpb25zCiAqICAgICAkIHdwIG1lbnUgbG9jYXRpb24gbGlzdAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbG9jYXRpb24gfCBkZXNjcmlwdGlvbiAgICAgICB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBwcmltYXJ5ICB8IFByaW1hcnkgTWVudSAgICAgIHwKICogICAgIHwgc29jaWFsICAgfCBTb2NpYWwgTGlua3MgTWVudSB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKgogKiAgICAgIyBBc3NpZ24gdGhlICdwcmltYXJ5LW1lbnUnIG1lbnUgdG8gdGhlICdwcmltYXJ5JyBsb2NhdGlvbgogKiAgICAgJCB3cCBtZW51IGxvY2F0aW9uIGFzc2lnbiBwcmltYXJ5LW1lbnUgcHJpbWFyeQogKiAgICAgU3VjY2VzczogQXNzaWduZWQgbG9jYXRpb24gdG8gbWVudS4KICoKICogICAgICMgUmVtb3ZlIHRoZSAncHJpbWFyeS1tZW51JyBtZW51IGZyb20gdGhlICdwcmltYXJ5JyBsb2NhdGlvbgogKiAgICAgJCB3cCBtZW51IGxvY2F0aW9uIHJlbW92ZSBwcmltYXJ5LW1lbnUgcHJpbWFyeQogKiAgICAgU3VjY2VzczogUmVtb3ZlZCBsb2NhdGlvbiBmcm9tIG1lbnUuCiAqLwpjbGFzcyBNZW51X0xvY2F0aW9uX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBMaXN0cyBsb2NhdGlvbnMgZm9yIHRoZSBjdXJyZW50IHRoZW1lLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAgIC0gaWRzCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggbG9jYXRpb246CgkgKgoJICogKiBuYW1lCgkgKiAqIGRlc2NyaXB0aW9uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGxvY2F0aW9uIGxpc3QKCSAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbG9jYXRpb24gfCBkZXNjcmlwdGlvbiAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IHByaW1hcnkgIHwgUHJpbWFyeSBNZW51ICAgICAgfAoJICogICAgIHwgc29jaWFsICAgfCBTb2NpYWwgTGlua3MgTWVudSB8CgkgKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkbG9jYXRpb25zICAgICA9IGdldF9yZWdpc3RlcmVkX25hdl9tZW51cygpOwoJCSRsb2NhdGlvbl9vYmpzID0gW107CgkJZm9yZWFjaCAoICRsb2NhdGlvbnMgYXMgJGxvY2F0aW9uID0+ICRkZXNjcmlwdGlvbiApIHsKCQkJJGxvY2F0aW9uX29iaiAgICAgICAgICAgICAgPSBuZXcgc3RkQ2xhc3MoKTsKCQkJJGxvY2F0aW9uX29iai0+bG9jYXRpb24gICAgPSAkbG9jYXRpb247CgkJCSRsb2NhdGlvbl9vYmotPmRlc2NyaXB0aW9uID0gJGRlc2NyaXB0aW9uOwoJCQkkbG9jYXRpb25fb2Jqc1tdICAgICAgICAgICA9ICRsb2NhdGlvbl9vYmo7CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIFsgJ2xvY2F0aW9uJywgJ2Rlc2NyaXB0aW9uJyBdICk7CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJGlkcyA9IGFycmF5X21hcCgKCQkJCWZ1bmN0aW9uKCAkbyApIHsKCQkJCQlyZXR1cm4gJG8tPmxvY2F0aW9uOwoJCQkJfSwKCQkJCSRsb2NhdGlvbl9vYmpzCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpZHMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkbG9jYXRpb25fb2JqcyApOwoJCX0KCX0KCgkvKioKCSAqIEFzc2lnbnMgYSBsb2NhdGlvbiB0byBhIG1lbnUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxtZW51PgoJICogOiBUaGUgbmFtZSwgc2x1Zywgb3IgdGVybSBJRCBmb3IgdGhlIG1lbnUuCgkgKgoJICogPGxvY2F0aW9uPgoJICogOiBMb2NhdGlvbidzIHNsdWcuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGxvY2F0aW9uIGFzc2lnbiBwcmltYXJ5LW1lbnUgcHJpbWFyeQoJICogICAgIFN1Y2Nlc3M6IEFzc2lnbmVkIGxvY2F0aW9uIHByaW1hcnkgdG8gbWVudSBwcmltYXJ5LW1lbnUuCgkgKgoJICogQHN1YmNvbW1hbmQgYXNzaWduCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhc3NpZ24oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJG1lbnUsICRsb2NhdGlvbiApID0gJGFyZ3M7CgoJCSRtZW51X29iaiA9IHdwX2dldF9uYXZfbWVudV9vYmplY3QoICRtZW51ICk7CgkJaWYgKCAhICRtZW51X29iaiApIHsKCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgbWVudSB7JG1lbnV9LiIgKTsKCQl9CgoJCSRsb2NhdGlvbnMgPSBnZXRfcmVnaXN0ZXJlZF9uYXZfbWVudXMoKTsKCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJGxvY2F0aW9uLCAkbG9jYXRpb25zICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIGxvY2F0aW9uIHskbG9jYXRpb259LiIgKTsKCQl9CgoJCSRsb2NhdGlvbnMgICAgICAgICAgICAgID0gZ2V0X25hdl9tZW51X2xvY2F0aW9ucygpOwoJCSRsb2NhdGlvbnNbICRsb2NhdGlvbiBdID0gJG1lbnVfb2JqLT50ZXJtX2lkOwoKCQlzZXRfdGhlbWVfbW9kKCAnbmF2X21lbnVfbG9jYXRpb25zJywgJGxvY2F0aW9ucyApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJBc3NpZ25lZCBsb2NhdGlvbiB7JGxvY2F0aW9ufSB0byBtZW51IHskbWVudX0uIiApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIGxvY2F0aW9uIGZyb20gYSBtZW51LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51LgoJICoKCSAqIDxsb2NhdGlvbj4KCSAqIDogTG9jYXRpb24ncyBzbHVnLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBsb2NhdGlvbiByZW1vdmUgcHJpbWFyeS1tZW51IHByaW1hcnkKCSAqICAgICBTdWNjZXNzOiBSZW1vdmVkIGxvY2F0aW9uIGZyb20gbWVudS4KCSAqCgkgKiBAc3ViY29tbWFuZCByZW1vdmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlbW92ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkbWVudSwgJGxvY2F0aW9uICkgPSAkYXJnczsKCgkJJG1lbnUgPSB3cF9nZXRfbmF2X21lbnVfb2JqZWN0KCAkbWVudSApOwoJCWlmICggISAkbWVudSB8fCBpc193cF9lcnJvciggJG1lbnUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgbWVudS4nICk7CgkJfQoKCQkkbG9jYXRpb25zID0gZ2V0X25hdl9tZW51X2xvY2F0aW9ucygpOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRsb2NhdGlvbnMsICRsb2NhdGlvbiApICE9PSAkbWVudS0+dGVybV9pZCApIHsKCQkJV1BfQ0xJOjplcnJvciggIk1lbnUgaXNuJ3QgYXNzaWduZWQgdG8gbG9jYXRpb24uIiApOwoJCX0KCgkJJGxvY2F0aW9uc1sgJGxvY2F0aW9uIF0gPSAwOwoJCXNldF90aGVtZV9tb2QoICduYXZfbWVudV9sb2NhdGlvbnMnLCAkbG9jYXRpb25zICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1JlbW92ZWQgbG9jYXRpb24gZnJvbSBtZW51LicgKTsKCgl9Cgp9Cjw/cGhwCgp1c2UgV1BfQ0xJXEVudGl0eVxSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxFbnRpdHlcVXRpbHMgYXMgRW50aXR5VXRpbHM7CgovKioKICogQWRkcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIGxpc3RzIHNpdGUgb3B0aW9ucyBpbiBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEdldCBzaXRlIHJlZ2lzdHJhdGlvbgogKiAgICAgJCB3cCBzaXRlIG9wdGlvbiBnZXQgcmVnaXN0cmF0aW9uCiAqICAgICBub25lCiAqCiAqICAgICAjIEFkZCBzaXRlIG9wdGlvbgogKiAgICAgJCB3cCBzaXRlIG9wdGlvbiBhZGQgbXlfb3B0aW9uIGZvb2JhcgogKiAgICAgU3VjY2VzczogQWRkZWQgJ215X29wdGlvbicgc2l0ZSBvcHRpb24uCiAqCiAqICAgICAjIFVwZGF0ZSBzaXRlIG9wdGlvbgogKiAgICAgJCB3cCBzaXRlIG9wdGlvbiB1cGRhdGUgbXlfb3B0aW9uICd7ImZvbyI6ICJiYXIifScgLS1mb3JtYXQ9anNvbgogKiAgICAgU3VjY2VzczogVXBkYXRlZCAnbXlfb3B0aW9uJyBzaXRlIG9wdGlvbi4KICoKICogICAgICMgRGVsZXRlIHNpdGUgb3B0aW9uCiAqICAgICAkIHdwIHNpdGUgb3B0aW9uIGRlbGV0ZSBteV9vcHRpb24KICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ215X29wdGlvbicgc2l0ZSBvcHRpb24uCiAqLwpjbGFzcyBTaXRlX09wdGlvbl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogR2V0cyBhIHNpdGUgb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSBzaXRlIG9wdGlvbi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IEdldCB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB2YXJfZXhwb3J0CgkgKiBvcHRpb25zOgoJICogICAtIHZhcl9leHBvcnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgc2l0ZSB1cGxvYWQgZmlsZXR5cGVzCgkgKiAgICAgJCB3cCBzaXRlIG9wdGlvbiBnZXQgdXBsb2FkX2ZpbGV0eXBlcwoJICogICAgIGpwZyBqcGVnIHBuZyBnaWYgbW92IGF2aSBtcGcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXkgKSA9ICRhcmdzOwoKCQkkdmFsdWUgPSBnZXRfc2l0ZV9vcHRpb24oICRrZXkgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEFkZHMgYSBzaXRlIG9wdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIHNpdGUgb3B0aW9uIHRvIGFkZC4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIHZhbHVlIG9mIHRoZSBzaXRlIG9wdGlvbiB0byBhZGQuIElmIG9tbWl0ZWQsIHRoZSB2YWx1ZSBpcyByZWFkIGZyb20gU1RESU4uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIGEgc2l0ZSBvcHRpb24gYnkgcmVhZGluZyBhIEpTT04gZmlsZQoJICogICAgICQgd3Agc2l0ZSBvcHRpb24gYWRkIG15X29wdGlvbiAtLWZvcm1hdD1qc29uIDwgY29uZmlnLmpzb24KCSAqICAgICBTdWNjZXNzOiBBZGRlZCAnbXlfb3B0aW9uJyBzaXRlIG9wdGlvbi4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRrZXkgPSAkYXJnc1swXTsKCgkJJHZhbHVlID0gV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAxICk7CgkJJHZhbHVlID0gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7CgoJCWlmICggISBhZGRfc2l0ZV9vcHRpb24oICRrZXksICR2YWx1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGFkZCBzaXRlIG9wdGlvbiAneyRrZXl9Jy4gRG9lcyBpdCBhbHJlYWR5IGV4aXN0PyIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJBZGRlZCAneyRrZXl9JyBzaXRlIG9wdGlvbi4iICk7CgkJfQoJfQoKCS8qKgoJICogTGlzdHMgc2l0ZSBvcHRpb25zLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1zZWFyY2g9PHBhdHRlcm4+XQoJICogOiBVc2Ugd2lsZGNhcmRzICggKiBhbmQgPyApIHRvIG1hdGNoIG9wdGlvbiBuYW1lLgoJICoKCSAqIFstLXNpdGVfaWQ9PGlkPl0KCSAqIDogTGltaXQgb3B0aW9ucyB0byB0aG9zZSBvZiBhIHBhcnRpY3VsYXIgc2l0ZSBpZC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuIHRvdGFsX2J5dGVzIGRpc3BsYXlzIHRoZSB0b3RhbCBzaXplIG9mIG1hdGNoaW5nIG9wdGlvbnMgaW4gYnl0ZXMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0ganNvbgoJICogICAtIGNzdgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogICAtIHRvdGFsX2J5dGVzCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhpcyBmaWVsZCB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIG1hdGNoaW5nIG9wdGlvbjoKCSAqCgkgKiAqIG1ldGFfa2V5CgkgKiAqIG1ldGFfdmFsdWUKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogbWV0YV9pZAoJICogKiBzaXRlX2lkCgkgKiAqIHNpemVfYnl0ZXMKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgYWxsIHNpdGUgb3B0aW9ucyBiZWdpbmluZyB3aXRoICJpMmZfIgoJICogICAgICQgd3Agc2l0ZSBvcHRpb24gbGlzdCAtLXNlYXJjaD0iaTJmXyoiCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBtZXRhX2tleSAgICB8IG1ldGFfdmFsdWUgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBpMmZfdmVyc2lvbiB8IDAuMS4wICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJZ2xvYmFsICR3cGRiOwoJCSRwYXR0ZXJuICAgID0gJyUnOwoJCSRmaWVsZHMgICAgID0gWyAnbWV0YV9rZXknLCAnbWV0YV92YWx1ZScgXTsKCQkkc2l6ZV9xdWVyeSA9ICcsTEVOR1RIKG1ldGFfdmFsdWUpIEFTIGBzaXplX2J5dGVzYCc7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydzZWFyY2gnXSApICkgewoJCQkkcGF0dGVybiA9IHNlbGY6OmVzY19saWtlKCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKTsKCQkJLy8gc3Vic3RpdHV0ZSB3aWxkY2FyZHMKCQkJJHBhdHRlcm4gPSBzdHJfcmVwbGFjZSggJyonLCAnJScsICRwYXR0ZXJuICk7CgkJCSRwYXR0ZXJuID0gc3RyX3JlcGxhY2UoICc/JywgJ18nLCAkcGF0dGVybiApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRmaWVsZHMgPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydmaWVsZHMnXSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICkgPT09ICd0b3RhbF9ieXRlcycgKSB7CgkJCSRmaWVsZHMgICAgID0gWyAnc2l6ZV9ieXRlcycgXTsKCQkJJHNpemVfcXVlcnkgPSAnLFNVTShMRU5HVEgobWV0YV92YWx1ZSkpIEFTIGBzaXplX2J5dGVzYCc7CgkJfQoKCQkkcXVlcnkgPSAkd3BkYi0+cHJlcGFyZSgKCQkJJ1NFTEVDVCBgbWV0YV9pZGAsIGBzaXRlX2lkYCwgYG1ldGFfa2V5YCxgbWV0YV92YWx1ZWAnCgkJCQkuICRzaXplX3F1ZXJ5IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gSGFyZC1jb2RlZCBwYXJ0aWFsIHF1ZXJ5IHdpdGhvdXQgdXNlciBpbnB1dC4KCQkJCS4gIiBGUk9NIGAkd3BkYi0+c2l0ZW1ldGFgIFdIRVJFIGBtZXRhX2tleWAgTElLRSAlcyIsCgkJCSRwYXR0ZXJuCgkJKTsKCgkJJHNpdGVfaWQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzaXRlX2lkJyApOwoJCWlmICggJHNpdGVfaWQgKSB7CgkJCSRxdWVyeSAuPSAkd3BkYi0+cHJlcGFyZSggJyBBTkQgc2l0ZV9pZD0lZCcsICRzaXRlX2lkICk7CgkJfQoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gJHF1ZXJ5IGlzIGFscmVhZHkgcHJlcGFyZWQgYWJvdmUuCgkJJHJlc3VsdHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICRxdWVyeSApOwoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKSA9PT0gJ3RvdGFsX2J5dGVzJyApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkcmVzdWx0c1swXS0+c2l6ZV9ieXRlcyApOwoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQkkZmllbGRzCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRyZXN1bHRzICk7CgkJfQoJfQoKCS8qKgoJICogVXBkYXRlcyBhIHNpdGUgb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgc2l0ZSBvcHRpb24gdG8gdXBkYXRlLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgbmV3IHZhbHVlLiBJZiBvbW1pdGVkLCB0aGUgdmFsdWUgaXMgcmVhZCBmcm9tIFNURElOLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogVGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGZvciB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBhIHNpdGUgb3B0aW9uIGJ5IHJlYWRpbmcgZnJvbSBhIGZpbGUKCSAqICAgICAkIHdwIHNpdGUgb3B0aW9uIHVwZGF0ZSBteV9vcHRpb24gPCB2YWx1ZS50eHQKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkICdteV9vcHRpb24nIHNpdGUgb3B0aW9uLgoJICoKCSAqIEBhbGlhcyBzZXQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRrZXkgPSAkYXJnc1swXTsKCgkJJHZhbHVlID0gV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAxICk7CgkJJHZhbHVlID0gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7CgoJCSR2YWx1ZSAgICAgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksICR2YWx1ZSApOwoJCSRvbGRfdmFsdWUgPSBzYW5pdGl6ZV9vcHRpb24oICRrZXksIGdldF9zaXRlX29wdGlvbiggJGtleSApICk7CgoJCWlmICggJHZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yICd7JGtleX0nIHNpdGUgb3B0aW9uIGlzIHVuY2hhbmdlZC4iICk7CgkJfSBlbHNlIHsKCQkJaWYgKCB1cGRhdGVfc2l0ZV9vcHRpb24oICRrZXksICR2YWx1ZSApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVXBkYXRlZCAneyRrZXl9JyBzaXRlIG9wdGlvbi4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHVwZGF0ZSBzaXRlIG9wdGlvbiAneyRrZXl9Jy4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGEgc2l0ZSBvcHRpb24uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IEtleSBmb3IgdGhlIHNpdGUgb3B0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBvcHRpb24gZGVsZXRlIG15X29wdGlvbgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgJ215X29wdGlvbicgc2l0ZSBvcHRpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzICkgewoJCWxpc3QoICRrZXkgKSA9ICRhcmdzOwoKCQlpZiAoICEgZGVsZXRlX3NpdGVfb3B0aW9uKCAka2V5ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgZGVsZXRlICd7JGtleX0nIHNpdGUgb3B0aW9uLiBEb2VzIGl0IGV4aXN0PyIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJEZWxldGVkICd7JGtleX0nIHNpdGUgb3B0aW9uLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbmVzdGVkIHZhbHVlIGZyb20gYW4gb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBUaGUgb3B0aW9uIG5hbWUuCgkgKgoJICogPGtleS1wYXRoPi4uLgoJICogOiBUaGUgbmFtZShzKSBvZiB0aGUga2V5cyB3aXRoaW4gdGhlIHZhbHVlIHRvIGxvY2F0ZSB0aGUgdmFsdWUgdG8gcGx1Y2suCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgb3V0cHV0IGZvcm1hdCBvZiB0aGUgdmFsdWUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHBsYWludGV4dAoJICogb3B0aW9uczoKCSAqICAgLSBwbGFpbnRleHQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICovCglwdWJsaWMgZnVuY3Rpb24gcGx1Y2soICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5ICkgPSAkYXJnczsKCgkJJHZhbHVlID0gZ2V0X3NpdGVfb3B0aW9uKCAka2V5ICk7CgoJCWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJfQoKCQkka2V5X3BhdGggPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAka2V5ICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgJiYgKCAoc3RyaW5nKSBpbnR2YWwoICRrZXkgKSA9PT0gJGtleSApICkgewoJCQkJCXJldHVybiAoaW50KSAka2V5OwoJCQkJfQoJCQkJCXJldHVybiAka2V5OwoJCQl9LAoJCQlhcnJheV9zbGljZSggJGFyZ3MsIDEgKQoJCSk7CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJHZhbHVlICk7CgoJCXRyeSB7CgkJCSR2YWx1ZSA9ICR0cmF2ZXJzZXItPmdldCggJGtleV9wYXRoICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlkaWUoIDEgKTsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgYSBuZXN0ZWQgdmFsdWUgaW4gYW4gb3B0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8YWN0aW9uPgoJICogOiBQYXRjaCBhY3Rpb24gdG8gcGVyZm9ybS4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBpbnNlcnQKCSAqICAgLSB1cGRhdGUKCSAqICAgLSBkZWxldGUKCSAqIC0tLQoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBvcHRpb24gbmFtZS4KCSAqCgkgKiA8a2V5LXBhdGg+Li4uCgkgKiA6IFRoZSBuYW1lKHMpIG9mIHRoZSBrZXlzIHdpdGhpbiB0aGUgdmFsdWUgdG8gbG9jYXRlIHRoZSB2YWx1ZSB0byBwYXRjaC4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21pdHRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXRjaCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRhY3Rpb24sICRrZXkgKSA9ICRhcmdzOwoJCSRrZXlfcGF0aCAgICAgICAgICAgICA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRrZXkgKSB7CgkJCQlpZiAoIGlzX251bWVyaWMoICRrZXkgKSAmJiAoIChzdHJpbmcpIGludHZhbCggJGtleSApID09PSAka2V5ICkgKSB7CgkJCQkJcmV0dXJuIChpbnQpICRrZXk7CgkJCQl9CgkJCQkJcmV0dXJuICRrZXk7CgkJCX0sCgkJCWFycmF5X3NsaWNlKCAkYXJncywgMiApCgkJKTsKCgkJaWYgKCAnZGVsZXRlJyA9PT0gJGFjdGlvbiApIHsKCQkJJHBhdGNoX3ZhbHVlID0gbnVsbDsKCQl9IGVsc2UgewoJCQkkc3RkaW5fdmFsdWUgPSBFbnRpdHlVdGlsczo6aGFzX3N0ZGluKCkKCQkJCT8gdHJpbSggV1BfQ0xJOjpnZXRfdmFsdWVfZnJvbV9hcmdfb3Jfc3RkaW4oICRhcmdzLCAtMSApICkKCQkJCTogbnVsbDsKCQkJJHBhdGNoX3ZhbHVlID0gISBlbXB0eSggJHN0ZGluX3ZhbHVlICkKCQkJCT8gV1BfQ0xJOjpyZWFkX3ZhbHVlKCAkc3RkaW5fdmFsdWUsICRhc3NvY19hcmdzICkKCQkJCTogV1BfQ0xJOjpyZWFkX3ZhbHVlKCBhcnJheV9wb3AoICRrZXlfcGF0aCApLCAkYXNzb2NfYXJncyApOwoJCX0KCgkJLyogTmVlZCB0byBtYWtlIGEgY29weSBvZiAkY3VycmVudF92YWx1ZSBoZXJlIGFzIGl0IGlzIG1vZGlmaWVkIGJ5IHJlZmVyZW5jZSAqLwoJCSRvbGRfdmFsdWUgICAgID0gc2FuaXRpemVfb3B0aW9uKCAka2V5LCBnZXRfc2l0ZV9vcHRpb24oICRrZXkgKSApOwoJCSRjdXJyZW50X3ZhbHVlID0gJG9sZF92YWx1ZTsKCQlpZiAoIGlzX29iamVjdCggJGN1cnJlbnRfdmFsdWUgKSApIHsKCQkJJG9sZF92YWx1ZSA9IGNsb25lICRjdXJyZW50X3ZhbHVlOwoJCX0KCgkJJHRyYXZlcnNlciA9IG5ldyBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyKCAkY3VycmVudF92YWx1ZSApOwoKCQl0cnkgewoJCQkkdHJhdmVyc2VyLT4kYWN0aW9uKCAka2V5X3BhdGgsICRwYXRjaF92YWx1ZSApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQkkcGF0Y2hlZF92YWx1ZSA9IHNhbml0aXplX29wdGlvbiggJGtleSwgJHRyYXZlcnNlci0+dmFsdWUoKSApOwoKCQlpZiAoICRwYXRjaGVkX3ZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yICd7JGtleX0nIHNpdGUgb3B0aW9uIGlzIHVuY2hhbmdlZC4iICk7CgkJfSBlbHNlIHsKCQkJaWYgKCB1cGRhdGVfc2l0ZV9vcHRpb24oICRrZXksICRwYXRjaGVkX3ZhbHVlICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkICd7JGtleX0nIHNpdGUgb3B0aW9uLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgdXBkYXRlIHNpdGUgb3B0aW9uICd7JGtleX0nLiIgKTsKCQkJfQoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBlc2NfbGlrZSggJG9sZCApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIFJlbW92ZSBub3RpY2VzIGluIDQuMCBhbmQgc3VwcG9ydCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQoJCWlmICggbWV0aG9kX2V4aXN0cyggJHdwZGIsICdlc2NfbGlrZScgKSApIHsKCQkJLy8gNC4wCgkJCSRvbGQgPSAkd3BkYi0+ZXNjX2xpa2UoICRvbGQgKTsKCQl9IGVsc2UgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkRlcHJlY2F0ZWRGdW5jdGlvbnMubGlrZV9lc2NhcGVGb3VuZCAtLSBjYWxsZWQgaW4gV29yZFByZXNzIDMuOSBvciBsZXNzLgoJCQkkb2xkID0gbGlrZV9lc2NhcGUoIGVzY19zcWwoICRvbGQgKSApOwoJCX0KCgkJcmV0dXJuICRvbGQ7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIE1hbmFnZXMgdGF4b25vbXkgdGVybXMgYW5kIHRlcm0gbWV0YSwgd2l0aCBjcmVhdGUsIGRlbGV0ZSwgYW5kIGxpc3QgY29tbWFuZHMuCiAqCiAqIFNlZSByZWZlcmVuY2UgZm9yIFt0YXhvbm9taWVzIGFuZCB0aGVpciB0ZXJtc10oaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1RheG9ub21pZXMpLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBDcmVhdGUgYSBuZXcgdGVybS4KICogICAgICQgd3AgdGVybSBjcmVhdGUgY2F0ZWdvcnkgQXBwbGUgLS1kZXNjcmlwdGlvbj0iQSB0eXBlIG9mIGZydWl0IgogKiAgICAgU3VjY2VzczogQ3JlYXRlZCBjYXRlZ29yeSAxOTkuCiAqCiAqICAgICAjIEdldCBkZXRhaWxzIGFib3V0IGEgdGVybS4KICogICAgICQgd3AgdGVybSBnZXQgY2F0ZWdvcnkgMTk5IC0tZm9ybWF0PWpzb24gLS1maWVsZHM9dGVybV9pZCxuYW1lLHNsdWcsY291bnQKICogICAgIHsidGVybV9pZCI6MTk5LCJuYW1lIjoiQXBwbGUiLCJzbHVnIjoiYXBwbGUiLCJjb3VudCI6MX0KICoKICogICAgICMgVXBkYXRlIGFuIGV4aXN0aW5nIHRlcm0uCiAqICAgICAkIHdwIHRlcm0gdXBkYXRlIGNhdGVnb3J5IDE1IC0tbmFtZT1BcHBsZQogKiAgICAgU3VjY2VzczogVGVybSB1cGRhdGVkLgogKgogKiAgICAgIyBHZXQgdGhlIHRlcm0ncyBVUkwuCiAqICAgICAkIHdwIHRlcm0gbGlzdCBwb3N0X3RhZyAtLWluY2x1ZGU9MTIzIC0tZmllbGQ9dXJsCiAqICAgICBodHRwOi8vZXhhbXBsZS5jb20vdGFnL3RpcHMtYW5kLXRyaWNrcwogKgogKiAgICAgIyBEZWxldGUgcG9zdCBjYXRlZ29yeQogKiAgICAgJCB3cCB0ZXJtIGRlbGV0ZSBjYXRlZ29yeSAxNQogKiAgICAgU3VjY2VzczogRGVsZXRlZCBjYXRlZ29yeSAxNS4KICoKICogICAgICMgUmVjb3VudCBwb3N0cyBhc3NpZ25lZCB0byBlYWNoIGNhdGVnb3JpZXMgYW5kIHRhZ3MKICogICAgICQgd3AgdGVybSByZWNvdW50IGNhdGVnb3J5IHBvc3RfdGFnCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGNhdGVnb3J5IHRlcm0gY291bnQKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdF90YWcgdGVybSBjb3VudAogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFRlcm1fQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBbCgkJJ3Rlcm1faWQnLAoJCSd0ZXJtX3RheG9ub215X2lkJywKCQknbmFtZScsCgkJJ3NsdWcnLAoJCSdkZXNjcmlwdGlvbicsCgkJJ3BhcmVudCcsCgkJJ2NvdW50JywKCV07CgoJLyoqCgkgKiBMaXN0cyB0ZXJtcyBpbiBhIHRheG9ub215LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGF4b25vbXk+Li4uCgkgKiA6IExpc3QgdGVybXMgb2Ygb25lIG9yIG1vcmUgdGF4b25vbWllcwoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmlsdGVyIGJ5IG9uZSBvciBtb3JlIGZpZWxkcyAoc2VlIGdldF90ZXJtcygpICRhcmdzIHBhcmFtZXRlciBmb3IgYSBsaXN0IG9mIGZpZWxkcykuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB0ZXJtLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB0ZXJtOgoJICoKCSAqICogdGVybV9pZAoJICogKiB0ZXJtX3RheG9ub215X2lkCgkgKiAqIG5hbWUKCSAqICogc2x1ZwoJICogKiBkZXNjcmlwdGlvbgoJICogKiBwYXJlbnQKCSAqICogY291bnQKCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogdXJsCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3QgY2F0ZWdvcmllcwoJICogICAgICQgd3AgdGVybSBsaXN0IGNhdGVnb3J5IC0tZm9ybWF0PWNzdgoJICogICAgIHRlcm1faWQsdGVybV90YXhvbm9teV9pZCxuYW1lLHNsdWcsZGVzY3JpcHRpb24scGFyZW50LGNvdW50CgkgKiAgICAgMiwyLGFjaWZvcm0sYWNpZm9ybSwsMCwxCgkgKiAgICAgMywzLGFudGlxdWFyaWFuaXNtLGFudGlxdWFyaWFuaXNtLCwwLDEKCSAqICAgICA0LDQsYXJyYW5nZW1lbnQsYXJyYW5nZW1lbnQsLDAsMQoJICogICAgIDUsNSxhc21vZGV1cyxhc21vZGV1cywsMCwxCgkgKgoJICogICAgICMgTGlzdCBwb3N0IHRhZ3MKCSAqICAgICAkIHdwIHRlcm0gbGlzdCBwb3N0X3RhZyAtLWZpZWxkcz1uYW1lLHNsdWcKCSAqICAgICArLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICB8IHNsdWcgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IDhCSVQgICAgICB8IDhiaXQgICAgICAgIHwKCSAqICAgICB8IGFsaWdubWVudCB8IGFsaWdubWVudC0yIHwKCSAqICAgICB8IEFydGljbGVzICB8IGFydGljbGVzICAgIHwKCSAqICAgICB8IGFzaWRlICAgICB8IGFzaWRlICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWZvcmVhY2ggKCAkYXJncyBhcyAkdGF4b25vbXkgKSB7CgkJCWlmICggISB0YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIlRheG9ub215IHskdGF4b25vbXl9IGRvZXNuJ3QgZXhpc3QuIiApOwoJCQl9CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknaGlkZV9lbXB0eScgPT4gZmFsc2UsCgkJXTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ3Rlcm1faWQnXSApICkgewoJCQkkdGVybSAgPSBnZXRfdGVybV9ieSggJ2lkJywgJGFzc29jX2FyZ3NbJ3Rlcm1faWQnXSwgJGFyZ3NbMF0gKTsKCQkJJHRlcm1zID0gWyAkdGVybSBdOwoJCX0gZWxzZWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2luY2x1ZGUnXSApCgkJCSYmICEgZW1wdHkoICRhc3NvY19hcmdzWydvcmRlcmJ5J10gKQoJCQkmJiAnaW5jbHVkZScgPT09ICRhc3NvY19hcmdzWydvcmRlcmJ5J10KCQkJJiYgVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC43JywgJzwnICkgKSB7CgkJCSR0ZXJtcyAgICA9IFtdOwoJCQkkdGVybV9pZHMgPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydpbmNsdWRlJ10gKTsKCQkJZm9yZWFjaCAoICR0ZXJtX2lkcyBhcyAkdGVybV9pZCApIHsKCQkJCSR0ZXJtID0gZ2V0X3Rlcm1fYnkoICdpZCcsICR0ZXJtX2lkLCAkYXJnc1swXSApOwoJCQkJaWYgKCAkdGVybSAmJiAhIGlzX3dwX2Vycm9yKCAkdGVybSApICkgewoJCQkJCSR0ZXJtc1tdID0gJHRlcm07CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkludmFsaWQgdGVybSB7JHRlcm1faWR9LiIgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSR0ZXJtcyA9IGdldF90ZXJtcyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJfQoKCQkkdGVybXMgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAkdGVybSApIHsKCQkJCQkkdGVybS0+Y291bnQgID0gKGludCkgJHRlcm0tPmNvdW50OwoJCQkJCSR0ZXJtLT5wYXJlbnQgPSAoaW50KSAkdGVybS0+cGFyZW50OwoJCQkJCSR0ZXJtLT51cmwgICAgPSBnZXRfdGVybV9saW5rKCAkdGVybSApOwoJCQkJCXJldHVybiAkdGVybTsKCQkJfSwKCQkJJHRlcm1zCgkJKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkkdGVybXMgPSB3cF9saXN0X3BsdWNrKCAkdGVybXMsICd0ZXJtX2lkJyApOwoJCQllY2hvIGltcGxvZGUoICcgJywgJHRlcm1zICk7CgkJfSBlbHNlIHsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHRlcm1zICk7CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyB0ZXJtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGF4b25vbXk+CgkgKiA6IFRheG9ub215IGZvciB0aGUgbmV3IHRlcm0uCgkgKgoJICogPHRlcm0+CgkgKiA6IEEgbmFtZSBmb3IgdGhlIG5ldyB0ZXJtLgoJICoKCSAqIFstLXNsdWc9PHNsdWc+XQoJICogOiBBIHVuaXF1ZSBzbHVnIGZvciB0aGUgbmV3IHRlcm0uIERlZmF1bHRzIHRvIHNhbml0aXplZCB2ZXJzaW9uIG9mIG5hbWUuCgkgKgoJICogWy0tZGVzY3JpcHRpb249PGRlc2NyaXB0aW9uPl0KCSAqIDogQSBkZXNjcmlwdGlvbiBmb3IgdGhlIG5ldyB0ZXJtLgoJICoKCSAqIFstLXBhcmVudD08dGVybS1pZD5dCgkgKiA6IEEgcGFyZW50IGZvciB0aGUgbmV3IHRlcm0uCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQganVzdCB0aGUgbmV3IHRlcm0gaWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDcmVhdGUgYSBuZXcgY2F0ZWdvcnkgIkFwcGxlIiB3aXRoIGEgZGVzY3JpcHRpb24uCgkgKiAgICAgJCB3cCB0ZXJtIGNyZWF0ZSBjYXRlZ29yeSBBcHBsZSAtLWRlc2NyaXB0aW9uPSJBIHR5cGUgb2YgZnJ1aXQiCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBjYXRlZ29yeSAxOTkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjcmVhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJHRheG9ub215LCAkdGVybSApID0gJGFyZ3M7CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknc2x1ZycgICAgICAgID0+IHNhbml0aXplX3RpdGxlKCAkdGVybSApLAoJCQknZGVzY3JpcHRpb24nID0+ICcnLAoJCQkncGFyZW50JyAgICAgID0+IDAsCgkJXTsKCQkkYXNzb2NfYXJncyA9IHdwX3BhcnNlX2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJJHBvcmNlbGFpbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKTsKCQl1bnNldCggJGFzc29jX2FyZ3NbJ3BvcmNlbGFpbiddICk7CgoJCS8vIENvbXBhdGliaWxpdHkgZm9yIDwgV1AgNC4wCgkJaWYgKCAkYXNzb2NfYXJnc1sncGFyZW50J10gPiAwICYmICEgdGVybV9leGlzdHMoIChpbnQpICRhc3NvY19hcmdzWydwYXJlbnQnXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUGFyZW50IHRlcm0gZG9lcyBub3QgZXhpc3QuJyApOwoJCX0KCgkJJGFzc29jX2FyZ3MgPSB3cF9zbGFzaCggJGFzc29jX2FyZ3MgKTsKCQkkdGVybSAgICAgICA9IHdwX3NsYXNoKCAkdGVybSApOwoJCSRyZXN1bHQgICAgID0gd3BfaW5zZXJ0X3Rlcm0oICR0ZXJtLCAkdGF4b25vbXksICRhc3NvY19hcmdzICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJHJlc3VsdC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0gZWxzZSB7CgkJCWlmICggJHBvcmNlbGFpbiApIHsKCQkJCVdQX0NMSTo6bGluZSggJHJlc3VsdFsndGVybV9pZCddICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDcmVhdGVkIHskdGF4b25vbXl9IHskcmVzdWx0Wyd0ZXJtX2lkJ119LiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdldHMgZGV0YWlscyBhYm91dCBhIHRlcm0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGF4b25vbXkgb2YgdGhlIHRlcm0gdG8gZ2V0CgkgKgoJICogPHRlcm0+CgkgKiA6IElEIG9yIHNsdWcgb2YgdGhlIHRlcm0gdG8gZ2V0CgkgKgoJICogWy0tYnk9PGZpZWxkPl0KCSAqIDogRXhwbGljaXRseSBoYW5kbGUgdGhlIHRlcm0gdmFsdWUgYXMgYSBzbHVnIG9yIGlkLgoJICogLS0tCgkgKiBkZWZhdWx0OiBpZAoJICogb3B0aW9uczoKCSAqICAgLSBzbHVnCgkgKiAgIC0gaWQKCSAqIC0tLQoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IEluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSB3aG9sZSB0ZXJtLCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBkZXRhaWxzIGFib3V0IGEgY2F0ZWdvcnkgd2l0aCBpZCAxOTkuCgkgKiAgICAgJCB3cCB0ZXJtIGdldCBjYXRlZ29yeSAxOTkgLS1mb3JtYXQ9anNvbgoJICogICAgIHsidGVybV9pZCI6MTk5LCJuYW1lIjoiQXBwbGUiLCJzbHVnIjoiYXBwbGUiLCJ0ZXJtX2dyb3VwIjowLCJ0ZXJtX3RheG9ub215X2lkIjoxOTksInRheG9ub215IjoiY2F0ZWdvcnkiLCJkZXNjcmlwdGlvbiI6IkEgdHlwZSBvZiBmcnVpdCIsInBhcmVudCI6MCwiY291bnQiOjAsImZpbHRlciI6InJhdyJ9CgkgKgoJICogICAgICMgR2V0IGRldGFpbHMgYWJvdXQgYSBjYXRlZ29yeSB3aXRoIHNsdWcgYXBwbGUuCgkgKiAgICAgJCB3cCB0ZXJtIGdldCBjYXRlZ29yeSBhcHBsZSAtLWJ5PXNsdWcgLS1mb3JtYXQ9anNvbgoJICogICAgIHsidGVybV9pZCI6MTk5LCJuYW1lIjoiQXBwbGUiLCJzbHVnIjoiYXBwbGUiLCJ0ZXJtX2dyb3VwIjowLCJ0ZXJtX3RheG9ub215X2lkIjoxOTksInRheG9ub215IjoiY2F0ZWdvcnkiLCJkZXNjcmlwdGlvbiI6IkEgdHlwZSBvZiBmcnVpdCIsInBhcmVudCI6MCwiY291bnQiOjAsImZpbHRlciI6InJhdyJ9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJHRheG9ub215LCAkdGVybSApID0gJGFyZ3M7CgoJCSR0ZXJtID0gZ2V0X3Rlcm1fYnkoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApLCAkdGVybSwgJHRheG9ub215ICk7CgoJCWlmICggISAkdGVybSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRlcm0gZG9lc24ndCBleGlzdC4iICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJHRlcm1fYXJyYXkgICAgICAgICAgID0gZ2V0X29iamVjdF92YXJzKCAkdGVybSApOwoJCQkkYXNzb2NfYXJnc1snZmllbGRzJ10gPSBhcnJheV9rZXlzKCAkdGVybV9hcnJheSApOwoJCX0KCgkJJHRlcm0tPmNvdW50ICA9IChpbnQpICR0ZXJtLT5jb3VudDsKCQkkdGVybS0+cGFyZW50ID0gKGludCkgJHRlcm0tPnBhcmVudDsKCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJHRlcm0gKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgYW4gZXhpc3RpbmcgdGVybS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRheG9ub215PgoJICogOiBUYXhvbm9teSBvZiB0aGUgdGVybSB0byB1cGRhdGUuCgkgKgoJICogPHRlcm0+CgkgKiA6IElEIG9yIHNsdWcgZm9yIHRoZSB0ZXJtIHRvIHVwZGF0ZS4KCSAqCgkgKiBbLS1ieT08ZmllbGQ+XQoJICogOiBFeHBsaWNpdGx5IGhhbmRsZSB0aGUgdGVybSB2YWx1ZSBhcyBhIHNsdWcgb3IgaWQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGlkCgkgKiBvcHRpb25zOgoJICogICAtIHNsdWcKCSAqICAgLSBpZAoJICogLS0tCgkgKgoJICogWy0tbmFtZT08bmFtZT5dCgkgKiA6IEEgbmV3IG5hbWUgZm9yIHRoZSB0ZXJtLgoJICoKCSAqIFstLXNsdWc9PHNsdWc+XQoJICogOiBBIG5ldyBzbHVnIGZvciB0aGUgdGVybS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBBIG5ldyBkZXNjcmlwdGlvbiBmb3IgdGhlIHRlcm0uCgkgKgoJICogWy0tcGFyZW50PTx0ZXJtLWlkPl0KCSAqIDogQSBuZXcgcGFyZW50IGZvciB0aGUgdGVybS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoYW5nZSBjYXRlZ29yeSB3aXRoIGlkIDE1IHRvIHVzZSB0aGUgbmFtZSAiQXBwbGUiCgkgKiAgICAgJCB3cCB0ZXJtIHVwZGF0ZSBjYXRlZ29yeSAxNSAtLW5hbWU9QXBwbGUKCSAqICAgICBTdWNjZXNzOiBUZXJtIHVwZGF0ZWQuCgkgKgoJICogICAgICMgQ2hhbmdlIGNhdGVnb3J5IHdpdGggc2x1ZyBhcHBsZSB0byB1c2UgdGhlIG5hbWUgIkFwcGxlIgoJICogICAgICQgd3AgdGVybSB1cGRhdGUgY2F0ZWdvcnkgYXBwbGUgLS1ieT1zbHVnIC0tbmFtZT1BcHBsZQoJICogICAgIFN1Y2Nlc3M6IFRlcm0gdXBkYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkdGF4b25vbXksICR0ZXJtICkgPSAkYXJnczsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSduYW1lJyAgICAgICAgPT4gbnVsbCwKCQkJJ3NsdWcnICAgICAgICA9PiBudWxsLAoJCQknZGVzY3JpcHRpb24nID0+IG51bGwsCgkJCSdwYXJlbnQnICAgICAgPT4gbnVsbCwKCQldOwoJCSRhc3NvY19hcmdzID0gd3BfcGFyc2VfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQlmb3JlYWNoICggJGFzc29jX2FyZ3MgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCWlmICggbnVsbCA9PT0gJHZhbHVlICkgewoJCQkJdW5zZXQoICRhc3NvY19hcmdzWyAka2V5IF0gKTsKCQkJfQoJCX0KCgkJJGFzc29jX2FyZ3MgPSB3cF9zbGFzaCggJGFzc29jX2FyZ3MgKTsKCgkJJHRlcm0gPSBnZXRfdGVybV9ieSggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYnknICksICR0ZXJtLCAkdGF4b25vbXkgKTsKCgkJaWYgKCAhICR0ZXJtICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGVybSBkb2Vzbid0IGV4aXN0LiIgKTsKCQl9CgoJCS8vIFVwZGF0ZSB0ZXJtLgoJCSRyZXN1bHQgPSB3cF91cGRhdGVfdGVybSggJHRlcm0tPnRlcm1faWQsICR0YXhvbm9teSwgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnVGVybSB1cGRhdGVkLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIGFuIGV4aXN0aW5nIHRlcm0uCgkgKgoJICogRXJyb3JzIGlmIHRoZSB0ZXJtIGRvZXNuJ3QgZXhpc3QsIG9yIHRoZXJlIHdhcyBhIHByb2JsZW0gaW4gZGVsZXRpbmcgaXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGF4b25vbXkgb2YgdGhlIHRlcm0gdG8gZGVsZXRlLgoJICoKCSAqIDx0ZXJtPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb3Igc2x1Z3Mgb2YgdGVybXMgdG8gZGVsZXRlLgoJICoKCSAqIFstLWJ5PTxmaWVsZD5dCgkgKiA6IEV4cGxpY2l0bHkgaGFuZGxlIHRoZSB0ZXJtIHZhbHVlIGFzIGEgc2x1ZyBvciBpZC4KCSAqIC0tLQoJICogZGVmYXVsdDogaWQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gc2x1ZwoJICogICAtIGlkCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBwb3N0IGNhdGVnb3J5IGJ5IGlkCgkgKiAgICAgJCB3cCB0ZXJtIGRlbGV0ZSBjYXRlZ29yeSAxNQoJICogICAgIERlbGV0ZWQgY2F0ZWdvcnkgMTUuCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAxIG9mIDEgdGVybXMuCgkgKgoJICogICAgICMgRGVsZXRlIHBvc3QgY2F0ZWdvcnkgYnkgc2x1ZwoJICogICAgICQgd3AgdGVybSBkZWxldGUgY2F0ZWdvcnkgYXBwbGUgLS1ieT1zbHVnCgkgKiAgICAgRGVsZXRlZCBjYXRlZ29yeSAxNS4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDEgb2YgMSB0ZXJtcy4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHBvc3QgdGFncwoJICogICAgICQgd3AgdGVybSBsaXN0IHBvc3RfdGFnIC0tZmllbGQ9dGVybV9pZCB8IHhhcmdzIHdwIHRlcm0gZGVsZXRlIHBvc3RfdGFnCgkgKiAgICAgRGVsZXRlZCBwb3N0X3RhZyAxNTkuCgkgKiAgICAgRGVsZXRlZCBwb3N0X3RhZyAxNjAuCgkgKiAgICAgRGVsZXRlZCBwb3N0X3RhZyAxNjEuCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAzIG9mIDMgdGVybXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGF4b25vbXkgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJZm9yZWFjaCAoICRhcmdzIGFzICR0ZXJtX2lkICkgewoKCQkJJHRlcm0gPSAkdGVybV9pZDsKCgkJCS8vIEdldCB0ZXJtIGJ5IHNwZWNpZmllZCBhcmd1bWVudCBvdGhlcndpc2UgZ2V0IHRlcm0gYnkgaWQuCgkJCSRmaWVsZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApOwoJCQlpZiAoICdzbHVnJyA9PT0gJGZpZWxkICkgewoKCQkJCS8vIEdldCB0ZXJtIGJ5IHNsdWcuCgkJCQkkdGVybSA9IGdldF90ZXJtX2J5KCAkZmllbGQsICR0ZXJtLCAkdGF4b25vbXkgKTsKCgkJCQkvLyBJZiB0ZXJtIG5vdCBmb3VuZCwgdGhlbiBzaG93IGVycm9yIG1lc3NhZ2UgYW5kIHNraXAgdGhlIGl0ZXJhdGlvbi4KCQkJCWlmICggISAkdGVybSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJ7JHRheG9ub215fSB7JHRlcm1faWR9IGRvZXNuJ3QgZXhpc3QuIiApOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCS8vIEdldCB0aGUgdGVybSBpZDsKCQkJCSR0ZXJtX2lkID0gJHRlcm0tPnRlcm1faWQ7CgoJCQl9CgoJCQkkcmVzdWx0ID0gd3BfZGVsZXRlX3Rlcm0oICR0ZXJtX2lkLCAkdGF4b25vbXkgKTsKCgkJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJHJlc3VsdCApOwoJCQkJJGVycm9ycysrOwoJCQl9IGVsc2VpZiAoICRyZXN1bHQgKSB7CgkJCQlXUF9DTEk6OmxvZyggIkRlbGV0ZWQgeyR0YXhvbm9teX0geyR0ZXJtX2lkfS4iICk7CgkJCQkkc3VjY2Vzc2VzKys7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJ7JHRheG9ub215fSB7JHRlcm1faWR9IGRvZXNuJ3QgZXhpc3QuIiApOwoJCQl9CgkJfQoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3Rlcm0nLCAnZGVsZXRlJywgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzb21lIHRlcm1zLgoJICoKCSAqIENyZWF0ZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIG5ldyB0ZXJtcyB3aXRoIGR1bW15IGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGhlIHRheG9ub215IGZvciB0aGUgZ2VuZXJhdGVkIHRlcm1zLgoJICoKCSAqIFstLWNvdW50PTxudW1iZXI+XQoJICogOiBIb3cgbWFueSB0ZXJtcyB0byBnZW5lcmF0ZT8KCSAqIC0tLQoJICogZGVmYXVsdDogMTAwCgkgKiAtLS0KCSAqCgkgKiBbLS1tYXhfZGVwdGg9PG51bWJlcj5dCgkgKiA6IEdlbmVyYXRlIGNoaWxkIHRlcm1zIGRvd24gdG8gYSBjZXJ0YWluIGRlcHRoLgoJICogLS0tCgkgKiBkZWZhdWx0OiAxCgkgKiAtLS0KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogcHJvZ3Jlc3MKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcHJvZ3Jlc3MKCSAqICAgLSBpZHMKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgcG9zdCBjYXRlZ29yaWVzLgoJICogICAgICQgd3AgdGVybSBnZW5lcmF0ZSBjYXRlZ29yeSAtLWNvdW50PTEwCgkgKiAgICAgR2VuZXJhdGluZyB0ZXJtcyAgMTAwJSBbPT09PT09PT09XSAwOjAyIC8gMDowMgoJICoKCSAqICAgICAjIEFkZCBtZXRhIHRvIGV2ZXJ5IGdlbmVyYXRlZCB0ZXJtLgoJICogICAgICQgd3AgdGVybSBnZW5lcmF0ZSBjYXRlZ29yeSAtLWZvcm1hdD1pZHMgLS1jb3VudD0zIHwgeGFyZ3MgLWQgJyAnIC1JICUgd3AgdGVybSBtZXRhIGFkZCAlIGZvbyBiYXIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdlbmVyYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQlsaXN0ICggJHRheG9ub215ICkgPSAkYXJnczsKCgkJJGRlZmF1bHRzID0gWwoJCQknY291bnQnICAgICA9PiAxMDAsCgkJCSdtYXhfZGVwdGgnID0+IDEsCgkJXTsKCgkJJGZpbmFsX2FyZ3MgPSBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoJCSRjb3VudCAgICAgID0gJGZpbmFsX2FyZ3NbJ2NvdW50J107CgkJJG1heF9kZXB0aCAgPSAkZmluYWxfYXJnc1snbWF4X2RlcHRoJ107CgoJCWlmICggISB0YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiJ3skdGF4b25vbXl9JyBpcyBub3QgYSByZWdpc3RlcmVkIHRheG9ub215LiIgKTsKCQl9CgoJCSRsYWJlbCA9IGdldF90YXhvbm9teSggJHRheG9ub215ICktPmxhYmVscy0+c2luZ3VsYXJfbmFtZTsKCQkkc2x1ZyAgPSBzYW5pdGl6ZV90aXRsZV93aXRoX2Rhc2hlcyggJGxhYmVsICk7CgoJCSRoaWVyYXJjaGljYWwgPSBnZXRfdGF4b25vbXkoICR0YXhvbm9teSApLT5oaWVyYXJjaGljYWw7CgoJCSRmb3JtYXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnLCAncHJvZ3Jlc3MnICk7CgoJCSRub3RpZnkgPSBmYWxzZTsKCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCSRub3RpZnkgPSBVdGlsc1xtYWtlX3Byb2dyZXNzX2JhciggJ0dlbmVyYXRpbmcgdGVybXMnLCAkY291bnQgKTsKCQl9CgoJCSRwcmV2aW91c190ZXJtX2lkID0gMDsKCQkkY3VycmVudF9wYXJlbnQgICA9IDA7CgkJJGN1cnJlbnRfZGVwdGggICAgPSAxOwoKCQkkbWF4X2lkID0gKGludCkgJHdwZGItPmdldF92YXIoICJTRUxFQ1QgdGVybV90YXhvbm9teV9pZCBGUk9NIHskd3BkYi0+dGVybV90YXhvbm9teX0gT1JERVIgQlkgdGVybV90YXhvbm9teV9pZCBERVNDIExJTUlUIDEiICk7CgoJCSRzdXNwZW5kX2NhY2hlX2ludmFsaWRhdGlvbiA9IHdwX3N1c3BlbmRfY2FjaGVfaW52YWxpZGF0aW9uKCB0cnVlICk7CgkJJGNyZWF0ZWQgICAgICAgICAgICAgICAgICAgID0gW107CgoJCWZvciAoICRpbmRleCA9ICRtYXhfaWQgKyAxOyAkaW5kZXggPD0gJG1heF9pZCArICRjb3VudDsgJGluZGV4KysgKSB7CgoJCQlpZiAoICRoaWVyYXJjaGljYWwgKSB7CgoJCQkJaWYgKCAkcHJldmlvdXNfdGVybV9pZCAmJiAkdGhpcy0+bWF5YmVfbWFrZV9jaGlsZCgpICYmICRjdXJyZW50X2RlcHRoIDwgJG1heF9kZXB0aCApIHsKCgkJCQkJJGN1cnJlbnRfcGFyZW50ID0gJHByZXZpb3VzX3Rlcm1faWQ7CgkJCQkJJGN1cnJlbnRfZGVwdGgrKzsKCgkJCQl9IGVsc2VpZiAoICR0aGlzLT5tYXliZV9yZXNldF9kZXB0aCgpICkgewoKCQkJCQkkY3VycmVudF9wYXJlbnQgPSAwOwoJCQkJCSRjdXJyZW50X2RlcHRoICA9IDE7CgoJCQkJfQoJCQl9CgoJCQkkYXJncyA9IFsKCQkJCSdwYXJlbnQnID0+ICRjdXJyZW50X3BhcmVudCwKCQkJCSdzbHVnJyAgID0+ICRzbHVnIC4gIi17JGluZGV4fSIsCgkJCV07CgoJCQkkbmFtZSA9ICJ7JGxhYmVsfSB7JGluZGV4fSI7CgkJCSR0ZXJtID0gd3BfaW5zZXJ0X3Rlcm0oICRuYW1lLCAkdGF4b25vbXksICRhcmdzICk7CgkJCWlmICggaXNfd3BfZXJyb3IoICR0ZXJtICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICR0ZXJtICk7CgkJCX0gZWxzZSB7CgkJCQkkY3JlYXRlZFtdICAgICAgICA9ICR0ZXJtWyd0ZXJtX2lkJ107CgkJCQkkcHJldmlvdXNfdGVybV9pZCA9ICR0ZXJtWyd0ZXJtX2lkJ107CgkJCQlpZiAoICdpZHMnID09PSAkZm9ybWF0ICkgewoJCQkJCWVjaG8gJHRlcm1bJ3Rlcm1faWQnXTsKCQkJCQlpZiAoICRpbmRleCA8ICRtYXhfaWQgKyAkY291bnQgKSB7CgkJCQkJCWVjaG8gJyAnOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkJJG5vdGlmeS0+dGljaygpOwoJCQl9CgkJfQoKCQl3cF9zdXNwZW5kX2NhY2hlX2ludmFsaWRhdGlvbiggJHN1c3BlbmRfY2FjaGVfaW52YWxpZGF0aW9uICk7CgkJY2xlYW5fdGVybV9jYWNoZSggJGNyZWF0ZWQsICR0YXhvbm9teSApOwoKCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCSRub3RpZnktPmZpbmlzaCgpOwoJCX0KCX0KCgkvKioKCSAqIFJlY2FsY3VsYXRlcyBudW1iZXIgb2YgcG9zdHMgYXNzaWduZWQgdG8gZWFjaCB0ZXJtLgoJICoKCSAqIEluIGluc3RhbmNlcyB3aGVyZSBtYW51YWwgdXBkYXRlcyBhcmUgbWFkZSB0byB0aGUgdGVybXMgYXNzaWduZWQgdG8KCSAqIHBvc3RzIGluIHRoZSBkYXRhYmFzZSwgdGhlIG51bWJlciBvZiBwb3N0cyBhc3NvY2lhdGVkIHdpdGggYSB0ZXJtCgkgKiBjYW4gYmVjb21lIG91dC1vZi1zeW5jIHdpdGggdGhlIGFjdHVhbCBudW1iZXIgb2YgcG9zdHMuCgkgKgoJICogVGhpcyBjb21tYW5kIHJ1bnMgd3BfdXBkYXRlX3Rlcm1fY291bnQoKSBvbiB0aGUgdGF4b25vbXkncyB0ZXJtcwoJICogdG8gYnJpbmcgdGhlIGNvdW50IGJhY2sgdG8gdGhlIGNvcnJlY3QgdmFsdWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0YXhvbm9teT4uLi4KCSAqIDogT25lIG9yIG1vcmUgdGF4b25vbWllcyB0byByZWNhbGN1bGF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFJlY291bnQgcG9zdHMgYXNzaWduZWQgdG8gZWFjaCBjYXRlZ29yaWVzIGFuZCB0YWdzCgkgKiAgICAgJCB3cCB0ZXJtIHJlY291bnQgY2F0ZWdvcnkgcG9zdF90YWcKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGNhdGVnb3J5IHRlcm0gY291bnQuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0X3RhZyB0ZXJtIGNvdW50LgoJICoKCSAqICAgICAjIFJlY291bnQgYWxsIGxpc3RlZCB0YXhvbm9taWVzCgkgKiAgICAgJCB3cCB0YXhvbm9teSBsaXN0IC0tZmllbGQ9bmFtZSB8IHhhcmdzIHdwIHRlcm0gcmVjb3VudAoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY2F0ZWdvcnkgdGVybSBjb3VudC4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIHBvc3RfdGFnIHRlcm0gY291bnQuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCBuYXZfbWVudSB0ZXJtIGNvdW50LgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgbGlua19jYXRlZ29yeSB0ZXJtIGNvdW50LgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdF9mb3JtYXQgdGVybSBjb3VudC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlY291bnQoICRhcmdzICkgewoJCWZvcmVhY2ggKCAkYXJncyBhcyAkdGF4b25vbXkgKSB7CgoJCQlpZiAoICEgdGF4b25vbXlfZXhpc3RzKCAkdGF4b25vbXkgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlRheG9ub215IHskdGF4b25vbXl9IGRvZXMgbm90IGV4aXN0LiIgKTsKCQkJfSBlbHNlIHsKCgkJCQkkdGVybXMgICAgICAgICAgICAgPSBnZXRfdGVybXMoICR0YXhvbm9teSwgWyAnaGlkZV9lbXB0eScgPT4gZmFsc2UgXSApOwoJCQkJJHRlcm1fdGF4b25vbXlfaWRzID0gd3BfbGlzdF9wbHVjayggJHRlcm1zLCAndGVybV90YXhvbm9teV9pZCcgKTsKCgkJCQl3cF91cGRhdGVfdGVybV9jb3VudCggJHRlcm1fdGF4b25vbXlfaWRzLCAkdGF4b25vbXkgKTsKCgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkIHskdGF4b25vbXl9IHRlcm0gY291bnQuIiApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogTWlncmF0ZSBhIHRlcm0gb2YgYSB0YXhvbm9teSB0byBhbm90aGVyIHRheG9ub215LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGVybT4KCSAqIDogU2x1ZyBvciBJRCBvZiB0aGUgdGVybSB0byBtaWdyYXRlLgoJICoKCSAqIFstLWJ5PTxmaWVsZD5dCgkgKiA6IEV4cGxpY2l0bHkgaGFuZGxlIHRoZSB0ZXJtIHZhbHVlIGFzIGEgc2x1ZyBvciBpZC4KCSAqIC0tLQoJICogZGVmYXVsdDogaWQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gc2x1ZwoJICogICAtIGlkCgkgKiAtLS0KCSAqCgkgKiBbLS1mcm9tPTx0YXhvbm9teT5dCgkgKiA6IFRheG9ub215IHNsdWcgb2YgdGhlIHRlcm0gdG8gbWlncmF0ZS4KCSAqCgkgKiBbLS10bz08dGF4b25vbXk+XQoJICogOiBUYXhvbm9teSBzbHVnIHRvIG1pZ3JhdGUgdG8uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBNaWdyYXRlIGEgY2F0ZWdvcnkncyB0ZXJtICh2aWRlbykgdG8gdGFnIHRheG9ub215LgoJICogICAgICQgd3AgdGVybSBtaWdyYXRlIDkxOTAgLS1mcm9tPWNhdGVnb3J5IC0tdG89cG9zdF90YWcKCSAqICAgICBUZXJtICc5MTkwJyBtaWdyYXRlZCEKCSAqICAgICBPbGQgaW5zdGFuY2Ugb2YgdGVybSAnOTE5MCcgcmVtb3ZlZCBmcm9tIGl0cyBvcmlnaW5hbCB0YXhvbm9teS4KCSAqICAgICBTdWNjZXNzOiBNaWdyYXRlZCB0aGUgdGVybSAnOTE5MCcgZnJvbSB0YXhvbm9teSAnY2F0ZWdvcnknIHRvIHRheG9ub215ICdwb3N0X3RhZycgZm9yIDEgcG9zdHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG1pZ3JhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGVybV9yZWZlcmVuY2UgICAgICAgPSAkYXJnc1swXTsKCQkkb3JpZ2luYWxfdGF4b25vbXkgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmcm9tJyApOwoJCSRkZXN0aW5hdGlvbl90YXhvbm9teSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3RvJyApOwoKCQkkdGVybSA9IGdldF90ZXJtX2J5KCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdieScgKSwgJHRlcm1fcmVmZXJlbmNlLCAkb3JpZ2luYWxfdGF4b25vbXkgKTsKCgkJaWYgKCAhICR0ZXJtICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGF4b25vbXkgdGVybSAneyR0ZXJtX3JlZmVyZW5jZX0nIGZvciB0YXhvbm9teSAneyRvcmlnaW5hbF90YXhvbm9teX0nIGRvZXNuJ3QgZXhpc3QuIiApOwoJCX0KCgkJJG9yaWdpbmFsX3RheG9ub215ID0gZ2V0X3RheG9ub215KCAkb3JpZ2luYWxfdGF4b25vbXkgKTsKCgkJJGlkID0gd3BfaW5zZXJ0X3Rlcm0oCgkJCSR0ZXJtLT5uYW1lLAoJCQkkZGVzdGluYXRpb25fdGF4b25vbXksCgkJCVsKCQkJCSdzbHVnJyAgICAgICAgPT4gJHRlcm0tPnNsdWcsCgkJCQkncGFyZW50JyAgICAgID0+IDAsCgkJCQknZGVzY3JpcHRpb24nID0+ICR0ZXJtLT5kZXNjcmlwdGlvbiwKCQkJXQoJCSk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRpZCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkaWQtPmdldF9lcnJvcl9tZXNzYWdlKCkgKTsKCQl9CgoJCSRwb3N0X2lkcyA9IGdldF9vYmplY3RzX2luX3Rlcm0oICR0ZXJtLT50ZXJtX2lkLCAkb3JpZ2luYWxfdGF4b25vbXktPm5hbWUgKTsKCgkJZm9yZWFjaCAoICRwb3N0X2lkcyBhcyAkcG9zdF9pZCApIHsKCQkJJHR5cGUgPSBnZXRfcG9zdF90eXBlKCAkcG9zdF9pZCApOwoJCQlpZiAoIGluX2FycmF5KCAkdHlwZSwgJG9yaWdpbmFsX3RheG9ub215LT5vYmplY3RfdHlwZSwgdHJ1ZSApICkgewoJCQkJJHRlcm1fdGF4b25vbXlfaWQgPSB3cF9zZXRfb2JqZWN0X3Rlcm1zKCAkcG9zdF9pZCwgJGlkWyd0ZXJtX2lkJ10sICRkZXN0aW5hdGlvbl90YXhvbm9teSwgdHJ1ZSApOwoKCQkJCWlmICggaXNfd3BfZXJyb3IoICR0ZXJtX3RheG9ub215X2lkICkgKSB7CgkJCQkJV1BfQ0xJOjplcnJvciggIkZhaWxlZCB0byBhc3NpZ24gdGhlIHRlcm0gJ3skdGVybS0+c2x1Z30nIHRvIHRoZSBwb3N0IHskcG9zdF9pZH0uIFJlYXNvbjogIiAuICR0ZXJtX3RheG9ub215X2lkLT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJCQl9CgoJCQkJV1BfQ0xJOjpsb2coICJUZXJtICd7JHRlcm0tPnNsdWd9JyBhc3NpZ25lZCB0byBwb3N0IHskcG9zdF9pZH0uIiApOwoJCQl9CgoJCQljbGVhbl9wb3N0X2NhY2hlKCAkcG9zdF9pZCApOwoJCX0KCgkJY2xlYW5fdGVybV9jYWNoZSggJHRlcm0tPnRlcm1faWQgKTsKCgkJV1BfQ0xJOjpsb2coICJUZXJtICd7JHRlcm0tPnNsdWd9JyBtaWdyYXRlZC4iICk7CgoJCSRkZWwgPSB3cF9kZWxldGVfdGVybSggJHRlcm0tPnRlcm1faWQsICRvcmlnaW5hbF90YXhvbm9teS0+bmFtZSApOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkZGVsICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gZGVsZXRlIHRoZSB0ZXJtICd7JHRlcm0tPnNsdWd9Jy4gUmVhc29uOiAiIC4gJGRlbC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0KCgkJV1BfQ0xJOjpsb2coICJPbGQgaW5zdGFuY2Ugb2YgdGVybSAneyR0ZXJtLT5zbHVnfScgcmVtb3ZlZCBmcm9tIGl0cyBvcmlnaW5hbCB0YXhvbm9teS4iICk7CgkJJHBvc3RfY291bnQgID0gY291bnQoICRwb3N0X2lkcyApOwoJCSRwb3N0X3BsdXJhbCA9IFV0aWxzXHBsdXJhbGl6ZSggJ3Bvc3QnLCAkcG9zdF9jb3VudCApOwoJCVdQX0NMSTo6c3VjY2VzcyggIk1pZ3JhdGVkIHRoZSB0ZXJtICd7JHRlcm0tPnNsdWd9JyBmcm9tIHRheG9ub215ICd7JG9yaWdpbmFsX3RheG9ub215LT5uYW1lfScgdG8gdGF4b25vbXkgJ3skZGVzdGluYXRpb25fdGF4b25vbXl9JyBmb3IgeyRwb3N0X2NvdW50fSB7JHBvc3RfcGx1cmFsfS4iICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9tYWtlX2NoaWxkKCkgewoJCS8vIDUwJSBjaGFuY2Ugb2YgbWFraW5nIGNoaWxkIHRlcm0uCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMiApID09PSAxICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9yZXNldF9kZXB0aCgpIHsKCQkvLyAxMCUgY2hhbmNlIG9mIHJlc2V0aW5nIHRvIHJvb3QgZGVwdGguCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMTAgKSA9PT0gNyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcywgJ3Rlcm0nICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIExpc3QsIGFkZCwgYW5kIGRlbGV0ZSBpdGVtcyBhc3NvY2lhdGVkIHdpdGggYSBtZW51LgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBZGQgYW4gZXhpc3RpbmcgcG9zdCB0byBhbiBleGlzdGluZyBtZW51CiAqICAgICAkIHdwIG1lbnUgaXRlbSBhZGQtcG9zdCBzaWRlYmFyLW1lbnUgMzMgLS10aXRsZT0iQ3VzdG9tIFRlc3QgUG9zdCIKICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KICoKICogICAgICMgQ3JlYXRlIGEgbmV3IG1lbnUgbGluayBpdGVtCiAqICAgICAkIHdwIG1lbnUgaXRlbSBhZGQtY3VzdG9tIHNpZGViYXItbWVudSBBcHBsZSBodHRwOi8vYXBwbGUuY29tCiAqICAgICBTdWNjZXNzOiBNZW51IGl0ZW0gYWRkZWQuCiAqCiAqICAgICAjIERlbGV0ZSBtZW51IGl0ZW0KICogICAgICQgd3AgbWVudSBpdGVtIGRlbGV0ZSA0NQogKiAgICAgU3VjY2VzczogMSBtZW51IGl0ZW0gZGVsZXRlZC4KICovCmNsYXNzIE1lbnVfSXRlbV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsKCQknZGJfaWQnLAoJCSd0eXBlJywKCQkndGl0bGUnLAoJCSdsaW5rJywKCQkncG9zaXRpb24nLAoJXTsKCgkvKioKCSAqIEdldHMgYSBsaXN0IG9mIGl0ZW1zIGFzc29jaWF0ZWQgd2l0aCBhIG1lbnUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxtZW51PgoJICogOiBUaGUgbmFtZSwgc2x1Zywgb3IgdGVybSBJRCBmb3IgdGhlIG1lbnUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0gaWRzCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIG1lbnUgaXRlbToKCSAqCgkgKiAqIGRiX2lkCgkgKiAqIHR5cGUKCSAqICogdGl0bGUKCSAqICogbGluawoJICogKiBwb3NpdGlvbgoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBtZW51X2l0ZW1fcGFyZW50CgkgKiAqIG9iamVjdF9pZAoJICogKiBvYmplY3QKCSAqICogdHlwZQoJICogKiB0eXBlX2xhYmVsCgkgKiAqIHRhcmdldAoJICogKiBhdHRyX3RpdGxlCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIGNsYXNzZXMKCSAqICogeGZuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gbGlzdCBtYWluLW1lbnUKCSAqICAgICArLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgZGJfaWQgfCB0eXBlICAgICAgfCB0aXRsZSAgICAgICB8IGxpbmsgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBwb3NpdGlvbiB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IDUgICAgIHwgY3VzdG9tICAgIHwgSG9tZSAgICAgICAgfCBodHRwOi8vZXhhbXBsZS5jb20gICAgICAgICAgICAgIHwgMSAgICAgICAgfAoJICogICAgIHwgNiAgICAgfCBwb3N0X3R5cGUgfCBTYW1wbGUgUGFnZSB8IGh0dHA6Ly9leGFtcGxlLmNvbS9zYW1wbGUtcGFnZS8gfCAyICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkaXRlbXMgPSB3cF9nZXRfbmF2X21lbnVfaXRlbXMoICRhcmdzWzBdICk7CgkJaWYgKCBmYWxzZSA9PT0gJGl0ZW1zIHx8IGlzX3dwX2Vycm9yKCAkaXRlbXMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgbWVudS4nICk7CgkJfQoKCQkvLyBDb3JyZWN0IHBvc2l0aW9uIGluY29uc2lzdGVuY3kgYW5kCgkJLy8gcHJvdGVjdGVkIGB1cmxgIHBhcmFtIGluIFdQLUNMSQoJCSRpdGVtcyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRpdGVtICkgewoJCQkJCSRpdGVtLT5wb3NpdGlvbiA9ICRpdGVtLT5tZW51X29yZGVyOwoJCQkJCSRpdGVtLT5saW5rICAgICA9ICRpdGVtLT51cmw7CgkJCQkJcmV0dXJuICRpdGVtOwoJCQl9LAoJCQkkaXRlbXMKCQkpOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmICdpZHMnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCSRpdGVtcyA9IGFycmF5X21hcCgKCQkJCWZ1bmN0aW9uKCAkaXRlbSApIHsKCQkJCQkJcmV0dXJuICRpdGVtLT5kYl9pZDsKCQkJCX0sCgkJCQkkaXRlbXMKCQkJKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlbXMgKTsKCgl9CgoJLyoqCgkgKiBBZGRzIGEgcG9zdCBhcyBhIG1lbnUgaXRlbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnU+CgkgKiA6IFRoZSBuYW1lLCBzbHVnLCBvciB0ZXJtIElEIGZvciB0aGUgbWVudS4KCSAqCgkgKiA8cG9zdC1pZD4KCSAqIDogUG9zdCBJRCB0byBhZGQgdG8gdGhlIG1lbnUuCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWxpbms9PGxpbms+XQoJICogOiBTZXQgYSBjdXN0b20gdXJsIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IFNldCBhIGN1c3RvbSBkZXNjcmlwdGlvbiBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1hdHRyLXRpdGxlPTxhdHRyLXRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGF0dHJpYnV0ZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS10YXJnZXQ9PHRhcmdldD5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIHRhcmdldCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1jbGFzc2VzPTxjbGFzc2VzPl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgY2xhc3NlcyBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3NpdGlvbj08cG9zaXRpb24+XQoJICogOiBTcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGlzIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wYXJlbnQtaWQ9PHBhcmVudC1pZD5dCgkgKiA6IE1ha2UgdGhpcyBtZW51IGl0ZW0gYSBjaGlsZCBvZiBhbm90aGVyIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpdGVtIGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBpdGVtIGFkZC1wb3N0IHNpZGViYXItbWVudSAzMyAtLXRpdGxlPSJDdXN0b20gVGVzdCBQb3N0IgoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtcG9zdAoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX3Bvc3QoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJHBvc3QgPSBnZXRfcG9zdCggJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddICk7CgkJaWYgKCAhICRwb3N0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBwb3N0LicgKTsKCQl9CgkJJGFzc29jX2FyZ3NbJ29iamVjdCddID0gJHBvc3QtPnBvc3RfdHlwZTsKCgkJJHRoaXMtPmFkZF9vcl91cGRhdGVfaXRlbSggJ2FkZCcsICdwb3N0X3R5cGUnLCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEFkZHMgYSB0YXhvbm9teSB0ZXJtIGFzIGEgbWVudSBpdGVtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51LgoJICoKCSAqIDx0YXhvbm9teT4KCSAqIDogVGF4b25vbXkgb2YgdGhlIHRlcm0gdG8gYmUgYWRkZWQuCgkgKgoJICogPHRlcm0taWQ+CgkgKiA6IFRlcm0gSUQgb2YgdGhlIHRlcm0gdG8gYmUgYWRkZWQuCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWxpbms9PGxpbms+XQoJICogOiBTZXQgYSBjdXN0b20gdXJsIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWRlc2NyaXB0aW9uPTxkZXNjcmlwdGlvbj5dCgkgKiA6IFNldCBhIGN1c3RvbSBkZXNjcmlwdGlvbiBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1hdHRyLXRpdGxlPTxhdHRyLXRpdGxlPl0KCSAqIDogU2V0IGEgY3VzdG9tIHRpdGxlIGF0dHJpYnV0ZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS10YXJnZXQ9PHRhcmdldD5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIHRhcmdldCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1jbGFzc2VzPTxjbGFzc2VzPl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgY2xhc3NlcyBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3NpdGlvbj08cG9zaXRpb24+XQoJICogOiBTcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGlzIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wYXJlbnQtaWQ9PHBhcmVudC1pZD5dCgkgKiA6IE1ha2UgdGhpcyBtZW51IGl0ZW0gYSBjaGlsZCBvZiBhbm90aGVyIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpdGVtIGlkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBpdGVtIGFkZC10ZXJtIHNpZGViYXItbWVudSBwb3N0X3RhZyAyNAoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtdGVybQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkX3Rlcm0oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGFzc29jX2FyZ3NbJ29iamVjdCddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddID0gJGFyZ3NbMl07CgkJdW5zZXQoICRhcmdzWzJdICk7CgoJCWlmICggISBnZXRfdGVybV9ieSggJ2lkJywgJGFzc29jX2FyZ3NbJ29iamVjdC1pZCddLCAkYXNzb2NfYXJnc1snb2JqZWN0J10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgdGVybS4nICk7CgkJfQoKCQkkdGhpcy0+YWRkX29yX3VwZGF0ZV9pdGVtKCAnYWRkJywgJ3RheG9ub215JywgJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgY3VzdG9tIG1lbnUgaXRlbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnU+CgkgKiA6IFRoZSBuYW1lLCBzbHVnLCBvciB0ZXJtIElEIGZvciB0aGUgbWVudS4KCSAqCgkgKiA8dGl0bGU+CgkgKiA6IFRpdGxlIGZvciB0aGUgbGluay4KCSAqCgkgKiA8bGluaz4KCSAqIDogVGFyZ2V0IFVSTCBmb3IgdGhlIGxpbmsuCgkgKgoJICogWy0tZGVzY3JpcHRpb249PGRlc2NyaXB0aW9uPl0KCSAqIDogU2V0IGEgY3VzdG9tIGRlc2NyaXB0aW9uIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWF0dHItdGl0bGU9PGF0dHItdGl0bGU+XQoJICogOiBTZXQgYSBjdXN0b20gdGl0bGUgYXR0cmlidXRlIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXRhcmdldD08dGFyZ2V0Pl0KCSAqIDogU2V0IGEgY3VzdG9tIGxpbmsgdGFyZ2V0IGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLWNsYXNzZXM9PGNsYXNzZXM+XQoJICogOiBTZXQgYSBjdXN0b20gbGluayBjbGFzc2VzIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXBvc2l0aW9uPTxwb3NpdGlvbj5dCgkgKiA6IFNwZWNpZnkgdGhlIHBvc2l0aW9uIG9mIHRoaXMgbWVudSBpdGVtLgoJICoKCSAqIFstLXBhcmVudC1pZD08cGFyZW50LWlkPl0KCSAqIDogTWFrZSB0aGlzIG1lbnUgaXRlbSBhIGNoaWxkIG9mIGFub3RoZXIgbWVudSBpdGVtLgoJICoKCSAqIFstLXBvcmNlbGFpbl0KCSAqIDogT3V0cHV0IGp1c3QgdGhlIG5ldyBtZW51IGl0ZW0gaWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gYWRkLWN1c3RvbSBzaWRlYmFyLW1lbnUgQXBwbGUgaHR0cDovL2FwcGxlLmNvbQoJICogICAgIFN1Y2Nlc3M6IE1lbnUgaXRlbSBhZGRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQtY3VzdG9tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGRfY3VzdG9tKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRhc3NvY19hcmdzWyd0aXRsZSddID0gJGFyZ3NbMV07CgkJdW5zZXQoICRhcmdzWzFdICk7CgkJJGFzc29jX2FyZ3NbJ2xpbmsnXSA9ICRhcmdzWzJdOwoJCXVuc2V0KCAkYXJnc1syXSApOwoJCSR0aGlzLT5hZGRfb3JfdXBkYXRlX2l0ZW0oICdhZGQnLCAnY3VzdG9tJywgJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIGEgbWVudSBpdGVtLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8ZGItaWQ+CgkgKiA6IERhdGFiYXNlIElEIGZvciB0aGUgbWVudSBpdGVtLgoJICoKCSAqIFstLXRpdGxlPTx0aXRsZT5dCgkgKiA6IFNldCBhIGN1c3RvbSB0aXRsZSBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1saW5rPTxsaW5rPl0KCSAqIDogU2V0IGEgY3VzdG9tIHVybCBmb3IgdGhlIG1lbnUgaXRlbS4KCSAqCgkgKiBbLS1kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBTZXQgYSBjdXN0b20gZGVzY3JpcHRpb24gZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tYXR0ci10aXRsZT08YXR0ci10aXRsZT5dCgkgKiA6IFNldCBhIGN1c3RvbSB0aXRsZSBhdHRyaWJ1dGUgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tdGFyZ2V0PTx0YXJnZXQ+XQoJICogOiBTZXQgYSBjdXN0b20gbGluayB0YXJnZXQgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tY2xhc3Nlcz08Y2xhc3Nlcz5dCgkgKiA6IFNldCBhIGN1c3RvbSBsaW5rIGNsYXNzZXMgZm9yIHRoZSBtZW51IGl0ZW0uCgkgKgoJICogWy0tcG9zaXRpb249PHBvc2l0aW9uPl0KCSAqIDogU3BlY2lmeSB0aGUgcG9zaXRpb24gb2YgdGhpcyBtZW51IGl0ZW0uCgkgKgoJICogWy0tcGFyZW50LWlkPTxwYXJlbnQtaWQ+XQoJICogOiBNYWtlIHRoaXMgbWVudSBpdGVtIGEgY2hpbGQgb2YgYW5vdGhlciBtZW51IGl0ZW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGl0ZW0gdXBkYXRlIDQ1IC0tdGl0bGU9V29yZFByZXNzIC0tbGluaz0naHR0cDovL3dvcmRwcmVzcy5vcmcnIC0tdGFyZ2V0PV9ibGFuayAtLXBvc2l0aW9uPTIKCSAqICAgICBTdWNjZXNzOiBNZW51IGl0ZW0gdXBkYXRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkvLyBTaHVmZmxlIHRoZSBwb3NpdGlvbiBvZiB0aGVzZS4KCQkkYXJnc1sxXSA9ICRhcmdzWzBdOwoJCSR0ZXJtcyAgID0gZ2V0X3RoZV90ZXJtcyggJGFyZ3NbMV0sICduYXZfbWVudScgKTsKCQlpZiAoICR0ZXJtcyAmJiAhIGlzX3dwX2Vycm9yKCAkdGVybXMgKSApIHsKCQkJJGFyZ3NbMF0gPSAoaW50KSAkdGVybXNbMF0tPnRlcm1faWQ7CgkJfSBlbHNlIHsKCQkJJGFyZ3NbMF0gPSAwOwoJCX0KCQkkdHlwZSA9IGdldF9wb3N0X21ldGEoICRhcmdzWzFdLCAnX21lbnVfaXRlbV90eXBlJywgdHJ1ZSApOwoJCSR0aGlzLT5hZGRfb3JfdXBkYXRlX2l0ZW0oICd1cGRhdGUnLCAkdHlwZSwgJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJfQoKCS8qKgoJICogRGVsZXRlcyBvbmUgb3IgbW9yZSBpdGVtcyBmcm9tIGEgbWVudS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGRiLWlkPi4uLgoJICogOiBEYXRhYmFzZSBJRCBmb3IgdGhlIG1lbnUgaXRlbShzKS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1lbnUgaXRlbSBkZWxldGUgNDUKCSAqICAgICBTdWNjZXNzOiAxIG1lbnUgaXRlbSBkZWxldGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGRlbGV0ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkY291bnQgID0gMDsKCQkkZXJyb3JzID0gMDsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgoJCQkkcGFyZW50X21lbnVfaWQgPSAoaW50KSBnZXRfcG9zdF9tZXRhKCAkYXJnLCAnX21lbnVfaXRlbV9tZW51X2l0ZW1fcGFyZW50JywgdHJ1ZSApOwoJCQkkcmVzdWx0ICAgICAgICAgPSB3cF9kZWxldGVfcG9zdCggJGFyZywgdHJ1ZSApOwoJCQlpZiAoICEgJHJlc3VsdCApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGRlbGV0ZSBtZW51IGl0ZW0geyRhcmd9LiIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJfSBlbHNlaWYgKCAkcGFyZW50X21lbnVfaWQgKSB7CgkJCQkkY2hpbGRyZW4gPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUIHBvc3RfaWQgRlJPTSAkd3BkYi0+cG9zdG1ldGEgV0hFUkUgbWV0YV9rZXk9J19tZW51X2l0ZW1fbWVudV9pdGVtX3BhcmVudCcgQU5EIG1ldGFfdmFsdWU9JXMiLCAoaW50KSAkYXJnICkgKTsKCQkJCWlmICggJGNoaWxkcmVuICkgewoJCQkJCSRjaGlsZHJlbl9xdWVyeSA9ICR3cGRiLT5wcmVwYXJlKCAiVVBEQVRFICR3cGRiLT5wb3N0bWV0YSBTRVQgbWV0YV92YWx1ZSA9ICVkIFdIRVJFIG1ldGFfa2V5ID0gJ19tZW51X2l0ZW1fbWVudV9pdGVtX3BhcmVudCcgQU5EIG1ldGFfdmFsdWU9JXMiLCAkcGFyZW50X21lbnVfaWQsIChpbnQpICRhcmcgKTsKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tICRjaGlsZHJlbl9xdWVyeSBpcyBhbHJlYWR5IHByZXBhcmVkIGFib3ZlLgoJCQkJCSR3cGRiLT5xdWVyeSggJGNoaWxkcmVuX3F1ZXJ5ICk7CgkJCQkJZm9yZWFjaCAoICRjaGlsZHJlbiBhcyAkY2hpbGQgKSB7CgkJCQkJCWNsZWFuX3Bvc3RfY2FjaGUoICRjaGlsZCApOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuU3RyaWN0Q29tcGFyaXNvbnMuTG9vc2VDb21wYXJpc29uIC0tIFdpbGwgaW5jcmVhc2UgY291bnQgZm9yIG5vbiBleGlzdGVudCBtZW51LgoJCQlpZiAoIGZhbHNlICE9ICRyZXN1bHQgKSB7CgkJCQkkY291bnQrKzsKCQkJfQoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnbWVudSBpdGVtJywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIFdvcmtlciBtZXRob2QgdG8gY3JlYXRlIG5ldyBpdGVtcyBvciB1cGRhdGUgZXhpc3Rpbmcgb25lcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBhZGRfb3JfdXBkYXRlX2l0ZW0oICRtZXRob2QsICR0eXBlLCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRtZW51ICAgICAgICAgICAgPSAkYXJnc1swXTsKCQkkbWVudV9pdGVtX2RiX2lkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAxLCAwICk7CgoJCSRtZW51ID0gd3BfZ2V0X25hdl9tZW51X29iamVjdCggJG1lbnUgKTsKCQlpZiAoICEgJG1lbnUgfHwgaXNfd3BfZXJyb3IoICRtZW51ICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIG1lbnUuJyApOwoJCX0KCgkJLy8gYHVybGAgaXMgcHJvdGVjdGVkIGluIFdQLUNMSSwgc28gd2UgdXNlIGBsaW5rYCBpbnN0ZWFkCgkJJGFzc29jX2FyZ3NbJ3VybCddID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGluaycgKTsKCgkJLy8gTmVlZCB0byBwZXJzaXN0IHRoZSBtZW51IGl0ZW0gZGF0YS4gU2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzI4MTM4CgkJaWYgKCAndXBkYXRlJyA9PT0gJG1ldGhvZCApIHsKCgkJCSRtZW51X2l0ZW1fb2JqID0gZ2V0X3Bvc3QoICRtZW51X2l0ZW1fZGJfaWQgKTsKCQkJJG1lbnVfaXRlbV9vYmogPSB3cF9zZXR1cF9uYXZfbWVudV9pdGVtKCAkbWVudV9pdGVtX29iaiApOwoKCQkJLy8gQ29ycmVjdCB0aGUgbWVudSBwb3NpdGlvbiBpZiB0aGlzIHdhcyB0aGUgZmlyc3QgaXRlbS4gU2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzI4MTQwCgkJCSRwb3NpdGlvbiA9ICggMCA9PT0gJG1lbnVfaXRlbV9vYmotPm1lbnVfb3JkZXIgKSA/IDEgOiAkbWVudV9pdGVtX29iai0+bWVudV9vcmRlcjsKCgkJCSRkZWZhdWx0X2FyZ3MgPSBbCgkJCQkncG9zaXRpb24nICAgID0+ICRwb3NpdGlvbiwKCQkJCSd0aXRsZScgICAgICAgPT4gJG1lbnVfaXRlbV9vYmotPnRpdGxlLAoJCQkJJ3VybCcgICAgICAgICA9PiAkbWVudV9pdGVtX29iai0+dXJsLAoJCQkJJ2Rlc2NyaXB0aW9uJyA9PiAkbWVudV9pdGVtX29iai0+ZGVzY3JpcHRpb24sCgkJCQknb2JqZWN0JyAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT5vYmplY3QsCgkJCQknb2JqZWN0LWlkJyAgID0+ICRtZW51X2l0ZW1fb2JqLT5vYmplY3RfaWQsCgkJCQkncGFyZW50LWlkJyAgID0+ICRtZW51X2l0ZW1fb2JqLT5tZW51X2l0ZW1fcGFyZW50LAoJCQkJJ2F0dHItdGl0bGUnICA9PiAkbWVudV9pdGVtX29iai0+YXR0cl90aXRsZSwKCQkJCSd0YXJnZXQnICAgICAgPT4gJG1lbnVfaXRlbV9vYmotPnRhcmdldCwKCQkJCSdjbGFzc2VzJyAgICAgPT4gaW1wbG9kZSggJyAnLCAkbWVudV9pdGVtX29iai0+Y2xhc3NlcyApLCAvLyBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlIGFzIGFycmF5CgkJCQkneGZuJyAgICAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT54Zm4sCgkJCQknc3RhdHVzJyAgICAgID0+ICRtZW51X2l0ZW1fb2JqLT5wb3N0X3N0YXR1cywKCQkJXTsKCgkJfSBlbHNlIHsKCgkJCSRkZWZhdWx0X2FyZ3MgPSBbCgkJCQkncG9zaXRpb24nICAgID0+IDAsCgkJCQkndGl0bGUnICAgICAgID0+ICcnLAoJCQkJJ3VybCcgICAgICAgICA9PiAnJywKCQkJCSdkZXNjcmlwdGlvbicgPT4gJycsCgkJCQknb2JqZWN0JyAgICAgID0+ICcnLAoJCQkJJ29iamVjdC1pZCcgICA9PiAwLAoJCQkJJ3BhcmVudC1pZCcgICA9PiAwLAoJCQkJJ2F0dHItdGl0bGUnICA9PiAnJywKCQkJCSd0YXJnZXQnICAgICAgPT4gJycsCgkJCQknY2xhc3NlcycgICAgID0+ICcnLAoJCQkJJ3hmbicgICAgICAgICA9PiAnJywKCQkJCS8vIENvcmUgb2RkbHkgZGVmYXVsdHMgdG8gJ2RyYWZ0JyBmb3IgY3JlYXRlLAoJCQkJLy8gYW5kICdwdWJsaXNoJyBmb3IgdXBkYXRlCgkJCQkvLyBFYXNpZXN0IHRvIGFsd2F5cyB3b3JrIHdpdGggcHVibGlzaAoJCQkJJ3N0YXR1cycgICAgICA9PiAncHVibGlzaCcsCgkJCV07CgoJCX0KCgkJJG1lbnVfaXRlbV9hcmdzID0gW107CgkJZm9yZWFjaCAoICRkZWZhdWx0X2FyZ3MgYXMgJGtleSA9PiAkZGVmYXVsdF92YWx1ZSApIHsKCQkJLy8gd3BfdXBkYXRlX25hdl9tZW51X2l0ZW0oKSBoYXMgYSB3ZWlyZCBhcmd1bWVudCBwcmVmaXgKCQkJJG5ld19rZXkgICAgICAgICAgICAgICAgICAgID0gJ21lbnUtaXRlbS0nIC4gJGtleTsKCQkJJG1lbnVfaXRlbV9hcmdzWyAkbmV3X2tleSBdID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAka2V5LCAkZGVmYXVsdF92YWx1ZSApOwoJCX0KCgkJJG1lbnVfaXRlbV9hcmdzWydtZW51LWl0ZW0tdHlwZSddID0gJHR5cGU7CgkJJHJlc3VsdCAgICAgICAgICAgICAgICAgICAgICAgICAgID0gd3BfdXBkYXRlX25hdl9tZW51X2l0ZW0oICRtZW51LT50ZXJtX2lkLCAkbWVudV9pdGVtX2RiX2lkLCAkbWVudV9pdGVtX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJfSBlbHNlaWYgKCAhICRyZXN1bHQgKSB7CgkJCWlmICggJ2FkZCcgPT09ICRtZXRob2QgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgYWRkIG1lbnUgaXRlbS4iICk7CgkJCX0gZWxzZWlmICggJ3VwZGF0ZScgPT09ICRtZXRob2QgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgdXBkYXRlIG1lbnUgaXRlbS4iICk7CgkJCX0KCQl9IGVsc2UgewoKCQkJLyoqCgkJCSAqIFNldCB0aGUgbWVudQoJCQkgKgoJCQkgKiB3cF91cGRhdGVfbmF2X21lbnVfaXRlbSgpICpzaG91bGQqIHRha2UgY2FyZSBvZiB0aGlzLCBidXQKCQkJICogZGVwZW5kcyBvbiB3cF9pbnNlcnRfcG9zdCgpJ3MgInRheF9pbnB1dCIgYXJndW1lbnQsIHdoaWNoCgkJCSAqIGlzIGlnbm9yZWQgaWYgdGhlIHVzZXIgY2FuJ3QgZWRpdCB0aGUgdGF4b25vbXkKCQkJICoKCQkJICogQHNlZSBodHRwczovL2NvcmUudHJhYy53b3JkcHJlc3Mub3JnL3RpY2tldC8yNzExMwoJCQkgKi8KCQkJaWYgKCAhIGlzX29iamVjdF9pbl90ZXJtKCAkcmVzdWx0LCAnbmF2X21lbnUnLCAoaW50KSAkbWVudS0+dGVybV9pZCApICkgewoJCQkJd3Bfc2V0X29iamVjdF90ZXJtcyggJHJlc3VsdCwgWyAoaW50KSAkbWVudS0+dGVybV9pZCBdLCAnbmF2X21lbnUnICk7CgkJCX0KCgkJCWlmICggJ2FkZCcgPT09ICRtZXRob2QgJiYgISBlbXB0eSggJGFzc29jX2FyZ3NbJ3BvcmNlbGFpbiddICkgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICRyZXN1bHQgKTsKCQkJfSBlbHNlIHsKCQkJCWlmICggJ2FkZCcgPT09ICRtZXRob2QgKSB7CgkJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnTWVudSBpdGVtIGFkZGVkLicgKTsKCQkJCX0gZWxzZWlmICggJ3VwZGF0ZScgPT09ICRtZXRob2QgKSB7CgkJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnTWVudSBpdGVtIHVwZGF0ZWQuJyApOwoJCQkJfQoJCQl9CgkJfQoKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPm9ial9maWVsZHMgKTsKCX0KCn0KPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwoKLyoqCiAqIFJldHJpZXZlcyBkZXRhaWxzIG9uIHRoZSBzaXRlJ3MgcmVnaXN0ZXJlZCBwb3N0IHR5cGVzLgogKgogKiBHZXQgaW5mb3JtYXRpb24gb24gV29yZFByZXNzJyBidWlsdC1pbiBhbmQgdGhlIHNpdGUncyBbY3VzdG9tIHBvc3QgdHlwZXNdKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcGx1Z2lucy9wb3N0LXR5cGVzLykuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEdldCBkZXRhaWxzIGFib3V0IGEgcG9zdCB0eXBlCiAqICAgICAkIHdwIHBvc3QtdHlwZSBnZXQgcGFnZSAtLWZpZWxkcz1uYW1lLGxhYmVsLGhpZXJhcmNoaWNhbCAtLWZvcm1hdD1qc29uCiAqICAgICB7Im5hbWUiOiJwYWdlIiwibGFiZWwiOiJQYWdlcyIsImhpZXJhcmNoaWNhbCI6dHJ1ZX0KICoKICogICAgICMgTGlzdCBwb3N0IHR5cGVzIHdpdGggJ3Bvc3QnIGNhcGFiaWxpdHkgdHlwZQogKiAgICAgJCB3cCBwb3N0LXR5cGUgbGlzdCAtLWNhcGFiaWxpdHlfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCiAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICAgICAgIHwgcHVibGljIHwKICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCiAqICAgICB8IHBvc3QgICAgICAgICAgfCAxICAgICAgfAogKiAgICAgfCBhdHRhY2htZW50ICAgIHwgMSAgICAgIHwKICogICAgIHwgcmV2aXNpb24gICAgICB8ICAgICAgICB8CiAqICAgICB8IG5hdl9tZW51X2l0ZW0gfCAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBQb3N0X1R5cGVfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBhcnJheSgKCQknbmFtZScsCgkJJ2xhYmVsJywKCQknZGVzY3JpcHRpb24nLAoJCSdoaWVyYXJjaGljYWwnLAoJCSdwdWJsaWMnLAoJCSdjYXBhYmlsaXR5X3R5cGUnLAoJKTsKCgkvKioKCSAqIEdldHMgdGhlIHBvc3QgY291bnRzIGZvciBlYWNoIHN1cHBsaWVkIHBvc3QgdHlwZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHBvc3RfdHlwZXMgUG9zdCB0eXBlcyB0byBmZXRjaCBjb3VudHMgZm9yLgoJICogQHJldHVybiBhcnJheSBBc3NvY2lhdGl2ZSBhcnJheSBvZiBwb3N0IGNvdW50cyBrZXllZCBieSBwb3N0IHR5cGUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfY291bnRzKCAkcG9zdF90eXBlcyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCWlmICggY291bnQoICRwb3N0X3R5cGVzICkgPD0gMCApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJHF1ZXJ5ID0gJHdwZGItPnByZXBhcmUoCgkJCSJTRUxFQ1QgYHBvc3RfdHlwZWAsIENPVU5UKCopIEFTIGBjb3VudGAKCQkJRlJPTSAkd3BkYi0+cG9zdHMKCQkJV0hFUkUgYHBvc3RfdHlwZWAgSU4gKCIgLiBpbXBsb2RlKCAnLCcsIGFycmF5X2ZpbGwoIDAsIGNvdW50KCAkcG9zdF90eXBlcyApLCAnJXMnICkgKSAuICcpCgkJCUdST1VQIEJZIGBwb3N0X3R5cGVgJywKCQkJJHBvc3RfdHlwZXMKCQkpOwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gJHF1ZXJ5IGlzIGFscmVhZHkgcHJlcGFyZWQgYWJvdmUuCgkJJGNvdW50cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHF1ZXJ5ICk7CgoJCS8vIE1ha2Ugc3VyZSB0aGVyZSdzIGEgY291bnQgZm9yIGV2ZXJ5IGl0ZW0uCgkJJGNvdW50cyA9IGFycmF5X21lcmdlKAoJCQlhcnJheV9maWxsX2tleXMoICRwb3N0X3R5cGVzLCAwICksCgkJCXdwX2xpc3RfcGx1Y2soICRjb3VudHMsICdjb3VudCcsICdwb3N0X3R5cGUnICkKCQkpOwoKCQlyZXR1cm4gJGNvdW50czsKCX0KCgkvKioKCSAqIExpc3RzIHJlZ2lzdGVyZWQgcG9zdCB0eXBlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgZ2V0X3Bvc3RfdHlwZXMoKSBmaXJzdCBwYXJhbWV0ZXIgZm9yIGEgbGlzdCBvZiBhdmFpbGFibGUgZmllbGRzKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHBvc3QgdHlwZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgcG9zdCB0eXBlIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggcG9zdCB0eXBlOgoJICoKCSAqICogbmFtZQoJICogKiBsYWJlbAoJICogKiBkZXNjcmlwdGlvbgoJICogKiBoaWVyYXJjaGljYWwKCSAqICogcHVibGljCgkgKiAqIGNhcGFiaWxpdHlfdHlwZQoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjb3VudAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCByZWdpc3RlcmVkIHBvc3QgdHlwZXMKCSAqICAgICAkIHdwIHBvc3QtdHlwZSBsaXN0IC0tZm9ybWF0PWNzdgoJICogICAgIG5hbWUsbGFiZWwsZGVzY3JpcHRpb24saGllcmFyY2hpY2FsLHB1YmxpYyxjYXBhYmlsaXR5X3R5cGUKCSAqICAgICBwb3N0LFBvc3RzLCwsMSxwb3N0CgkgKiAgICAgcGFnZSxQYWdlcywsMSwxLHBhZ2UKCSAqICAgICBhdHRhY2htZW50LE1lZGlhLCwsMSxwb3N0CgkgKiAgICAgcmV2aXNpb24sUmV2aXNpb25zLCwsLHBvc3QKCSAqICAgICBuYXZfbWVudV9pdGVtLCJOYXZpZ2F0aW9uIE1lbnUgSXRlbXMiLCwsLHBvc3QKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3QgdHlwZXMgd2l0aCAncG9zdCcgY2FwYWJpbGl0eSB0eXBlCgkgKiAgICAgJCB3cCBwb3N0LXR5cGUgbGlzdCAtLWNhcGFiaWxpdHlfdHlwZT1wb3N0IC0tZmllbGRzPW5hbWUscHVibGljCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgfCBwdWJsaWMgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBwb3N0ICAgICAgICAgIHwgMSAgICAgIHwKCSAqICAgICB8IGF0dGFjaG1lbnQgICAgfCAxICAgICAgfAoJICogICAgIHwgcmV2aXNpb24gICAgICB8ICAgICAgICB8CgkgKiAgICAgfCBuYXZfbWVudV9pdGVtIHwgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoKCQkkZmllbGRzID0gJGZvcm1hdHRlci0+ZmllbGRzOwoJCSR0eXBlcyAgPSBnZXRfcG9zdF90eXBlcyggJGFzc29jX2FyZ3MsICdvYmplY3RzJyApOwoJCSRjb3VudHMgPSBbXTsKCgkJaWYgKCBjb3VudCggJHR5cGVzICkgPiAwICYmIGluX2FycmF5KCAnY291bnQnLCAkZmllbGRzLCB0cnVlICkgKSB7CgkJCSRjb3VudHMgPSAkdGhpcy0+Z2V0X2NvdW50cyggd3BfbGlzdF9wbHVjayggJHR5cGVzLCAnbmFtZScgKSApOwoJCX0KCgkJJHR5cGVzID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJHR5cGUgKSB1c2UgKCAkY291bnRzICkgewoJCQkJCSR0eXBlLT5jb3VudCA9IGlzc2V0KCAkY291bnRzWyAkdHlwZS0+bmFtZSBdICkgPyAkY291bnRzWyAkdHlwZS0+bmFtZSBdIDogMDsKCQkJCQlyZXR1cm4gJHR5cGU7CgkJCX0sCgkJCSR0eXBlcwoJCSk7CgoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICR0eXBlcyApOwoJfQoKCS8qKgoJICogR2V0cyBkZXRhaWxzIGFib3V0IGEgcmVnaXN0ZXJlZCBwb3N0IHR5cGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwb3N0LXR5cGU+CgkgKiA6IFBvc3QgdHlwZSBzbHVnCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogSW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIHdob2xlIHRheG9ub215LCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIHRoZSBzcGVjaWZpZWQgcG9zdCB0eXBlOgoJICoKCSAqICogbmFtZQoJICogKiBsYWJlbAoJICogKiBkZXNjcmlwdGlvbgoJICogKiBoaWVyYXJjaGljYWwKCSAqICogcHVibGljCgkgKiAqIGNhcGFiaWxpdHlfdHlwZQoJICogKiBsYWJlbHMKCSAqICogY2FwCgkgKiAqIHN1cHBvcnRzCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGNvdW50CgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgZGV0YWlscyBhYm91dCB0aGUgJ3BhZ2UnIHBvc3QgdHlwZS4KCSAqICAgICAkIHdwIHBvc3QtdHlwZSBnZXQgcGFnZSAtLWZpZWxkcz1uYW1lLGxhYmVsLGhpZXJhcmNoaWNhbCAtLWZvcm1hdD1qc29uCgkgKiAgICAgeyJuYW1lIjoicGFnZSIsImxhYmVsIjoiUGFnZXMiLCJoaWVyYXJjaGljYWwiOnRydWV9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcG9zdF90eXBlID0gZ2V0X3Bvc3RfdHlwZV9vYmplY3QoICRhcmdzWzBdICk7CgoJCWlmICggISAkcG9zdF90eXBlICkgewoJCQlXUF9DTEk6OmVycm9yKCAiUG9zdCB0eXBlIHskYXJnc1swXX0gZG9lc24ndCBleGlzdC4iICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJGRlZmF1bHRfZmllbGRzID0gYXJyYXlfbWVyZ2UoCgkJCQkkdGhpcy0+ZmllbGRzLAoJCQkJYXJyYXkoCgkJCQkJJ2xhYmVscycsCgkJCQkJJ2NhcCcsCgkJCQkJJ3N1cHBvcnRzJywKCQkJCSkKCQkJKTsKCgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9ICRkZWZhdWx0X2ZpZWxkczsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZmllbGRzICAgID0gJGZvcm1hdHRlci0+ZmllbGRzOwoJCSRjb3VudCAgICAgPSAwOwoKCQlpZiAoIGluX2FycmF5KCAnY291bnQnLCAkZmllbGRzLCB0cnVlICkgKSB7CgkJCSRjb3VudCA9ICR0aGlzLT5nZXRfY291bnRzKCBbICRwb3N0X3R5cGUtPm5hbWUgXSApOwoJCQkkY291bnQgPSAkY291bnRbICRwb3N0X3R5cGUtPm5hbWUgXTsKCQl9CgoJCSRkYXRhID0gYXJyYXkoCgkJCSduYW1lJyAgICAgICAgICAgID0+ICRwb3N0X3R5cGUtPm5hbWUsCgkJCSdsYWJlbCcgICAgICAgICAgID0+ICRwb3N0X3R5cGUtPmxhYmVsLAoJCQknZGVzY3JpcHRpb24nICAgICA9PiAkcG9zdF90eXBlLT5kZXNjcmlwdGlvbiwKCQkJJ2hpZXJhcmNoaWNhbCcgICAgPT4gJHBvc3RfdHlwZS0+aGllcmFyY2hpY2FsLAoJCQkncHVibGljJyAgICAgICAgICA9PiAkcG9zdF90eXBlLT5wdWJsaWMsCgkJCSdjYXBhYmlsaXR5X3R5cGUnID0+ICRwb3N0X3R5cGUtPmNhcGFiaWxpdHlfdHlwZSwKCQkJJ2xhYmVscycgICAgICAgICAgPT4gJHBvc3RfdHlwZS0+bGFiZWxzLAoJCQknY2FwJyAgICAgICAgICAgICA9PiAkcG9zdF90eXBlLT5jYXAsCgkJCSdzdXBwb3J0cycgICAgICAgID0+IGdldF9hbGxfcG9zdF90eXBlX3N1cHBvcnRzKCAkcG9zdF90eXBlLT5uYW1lICksCgkJCSdjb3VudCcgICAgICAgICAgID0+ICRjb3VudCwKCQkpOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbSggJGRhdGEgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICdwb3N0LXR5cGUnICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogRGVzdHJveXMgYW5kIGxpc3RzIGEgdXNlcidzIHNlc3Npb25zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGEgdXNlcidzIHNlc3Npb25zLgogKiAgICAgJCB3cCB1c2VyIHNlc3Npb24gbGlzdCBhZG1pbkBleGFtcGxlLmNvbSAtLWZvcm1hdD1jc3YKICogICAgIGxvZ2luX3RpbWUsZXhwaXJhdGlvbl90aW1lLGlwLHVhCiAqICAgICAiMjAxNi0wMS0wMSAxMjozNDo1NiIsIjIwMTYtMDItMDEgMTI6MzQ6NTYiLDEyNy4wLjAuMSwiTW96aWxsYS81LjAuLi4iCiAqCiAqICAgICAjIERlc3Ryb3kgdGhlIG1vc3QgcmVjZW50IHNlc3Npb24gb2YgdGhlIGdpdmVuIHVzZXIuCiAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluCiAqICAgICBTdWNjZXNzOiBEZXN0cm95ZWQgc2Vzc2lvbi4gMyBzZXNzaW9ucyByZW1haW5pbmcuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgVXNlcl9TZXNzaW9uX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gWwoJCSd0b2tlbicsCgkJJ2xvZ2luX3RpbWUnLAoJCSdleHBpcmF0aW9uX3RpbWUnLAoJCSdpcCcsCgkJJ3VhJywKCV07CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFVzZXJGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBEZXN0cm95IGEgc2Vzc2lvbiBmb3IgdGhlIGdpdmVuIHVzZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFs8dG9rZW4+XQoJICogOiBUaGUgdG9rZW4gb2YgdGhlIHNlc3Npb24gdG8gZGVzdHJveS4gRGVmYXVsdHMgdG8gdGhlIG1vc3QgcmVjZW50bHkgY3JlYXRlZCBzZXNzaW9uLgoJICoKCSAqIFstLWFsbF0KCSAqIDogRGVzdHJveSBhbGwgb2YgdGhlIHVzZXIncyBzZXNzaW9ucy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlc3Ryb3kgdGhlIG1vc3QgcmVjZW50IHNlc3Npb24gb2YgdGhlIGdpdmVuIHVzZXIuCgkgKiAgICAgJCB3cCB1c2VyIHNlc3Npb24gZGVzdHJveSBhZG1pbgoJICogICAgIFN1Y2Nlc3M6IERlc3Ryb3llZCBzZXNzaW9uLiAzIHNlc3Npb25zIHJlbWFpbmluZy4KCSAqCgkgKiAgICAgIyBEZXN0cm95IGEgc3BlY2lmaWMgc2Vzc2lvbiBvZiB0aGUgZ2l2ZW4gdXNlci4KCSAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluIGUwNzNhZDg1NDBhOWMyLi4uCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIHNlc3Npb24uIDIgc2Vzc2lvbnMgcmVtYWluaW5nLgoJICoKCSAqICAgICAjIERlc3Ryb3kgYWxsIHRoZSBzZXNzaW9ucyBvZiB0aGUgZ2l2ZW4gdXNlci4KCSAqICAgICAkIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IGFkbWluIC0tYWxsCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIGFsbCBzZXNzaW9ucy4KCSAqCgkgKiAgICAgIyBEZXN0cm95IGFsbCBzZXNzaW9ucyBmb3IgYWxsIHVzZXJzLgoJICogICAgICQgd3AgdXNlciBsaXN0IC0tZmllbGQ9SUQgfCB4YXJncyAtbiAxIHdwIHVzZXIgc2Vzc2lvbiBkZXN0cm95IC0tYWxsCgkgKiAgICAgU3VjY2VzczogRGVzdHJveWVkIGFsbCBzZXNzaW9ucy4KCSAqICAgICBTdWNjZXNzOiBEZXN0cm95ZWQgYWxsIHNlc3Npb25zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVzdHJveSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR1c2VyICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkdG9rZW4gICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXJncywgMSwgbnVsbCApOwoJCSRhbGwgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkbWFuYWdlciA9IFdQX1Nlc3Npb25fVG9rZW5zOjpnZXRfaW5zdGFuY2UoICR1c2VyLT5JRCApOwoKCQlpZiAoICR0b2tlbiAmJiAkYWxsICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIC0tYWxsIGZsYWcgY2Fubm90IGJlIHNwZWNpZmllZCBhbG9uZyB3aXRoIGEgc2Vzc2lvbiB0b2tlbi4nICk7CgkJfQoKCQlpZiAoICRhbGwgKSB7CgkJCSRtYW5hZ2VyLT5kZXN0cm95X2FsbCgpOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdEZXN0cm95ZWQgYWxsIHNlc3Npb25zLicgKTsKCQkJcmV0dXJuOwoJCX0KCgkJJHNlc3Npb25zID0gJHRoaXMtPmdldF9hbGxfc2Vzc2lvbnMoICRtYW5hZ2VyICk7CgoJCWlmICggISAkdG9rZW4gKSB7CgkJCWlmICggZW1wdHkoICRzZXNzaW9ucyApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnTm8gc2Vzc2lvbnMgdG8gZGVzdHJveS4nICk7CgkJCX0KCQkJJGxhc3QgID0gZW5kKCAkc2Vzc2lvbnMgKTsKCQkJJHRva2VuID0gJGxhc3RbJ3Rva2VuJ107CgkJfQoKCQlpZiAoICEgaXNzZXQoICRzZXNzaW9uc1sgJHRva2VuIF0gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1Nlc3Npb24gbm90IGZvdW5kLicgKTsKCQl9CgoJCSR0aGlzLT5kZXN0cm95X3Nlc3Npb24oICRtYW5hZ2VyLCAkdG9rZW4gKTsKCQkkcmVtYWluaW5nID0gY291bnQoICRtYW5hZ2VyLT5nZXRfYWxsKCkgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiRGVzdHJveWVkIHNlc3Npb24uIHskcmVtYWluaW5nfSByZW1haW5pbmcuIiApOwoJfQoKCS8qKgoJICogTGlzdCBzZXNzaW9ucyBmb3IgdGhlIGdpdmVuIHVzZXIuCgkgKgoJICogTm90ZTogVGhlIGB0b2tlbmAgZmllbGQgZG9lcyBub3QgcmV0dXJuIHRoZSBhY3R1YWwgdG9rZW4sIGJ1dCBhIGhhc2ggb2YKCSAqIGl0LiBUaGUgcmVhbCB0b2tlbiBpcyBub3QgcGVyc2lzdGVkIGFuZCBjYW4gb25seSBiZSBmb3VuZCBpbiB0aGUKCSAqIGNvcnJlc3BvbmRpbmcgY29va2llcyBvbiB0aGUgY2xpZW50IHNpZGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPgoJICogOiBVc2VyIElELCB1c2VyIGVtYWlsLCBvciB1c2VyIGxvZ2luLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqICAgLSBjb3VudAoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHNlc3Npb246CgkgKgoJICogKiB0b2tlbgoJICogKiBsb2dpbl90aW1lCgkgKiAqIGV4cGlyYXRpb25fdGltZQoJICogKiBpcAoJICogKiB1YQoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBleHBpcmF0aW9uCgkgKiAqIGxvZ2luCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGEgdXNlcidzIHNlc3Npb25zLgoJICogICAgICQgd3AgdXNlciBzZXNzaW9uIGxpc3QgYWRtaW5AZXhhbXBsZS5jb20gLS1mb3JtYXQ9Y3N2CgkgKiAgICAgbG9naW5fdGltZSxleHBpcmF0aW9uX3RpbWUsaXAsdWEKCSAqICAgICAiMjAxNi0wMS0wMSAxMjozNDo1NiIsIjIwMTYtMDItMDEgMTI6MzQ6NTYiLDEyNy4wLjAuMSwiTW96aWxsYS81LjAuLi4iCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXNlciAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJG1hbmFnZXIgICA9IFdQX1Nlc3Npb25fVG9rZW5zOjpnZXRfaW5zdGFuY2UoICR1c2VyLT5JRCApOwoJCSRzZXNzaW9ucyAgPSAkdGhpcy0+Z2V0X2FsbF9zZXNzaW9ucyggJG1hbmFnZXIgKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQllY2hvIGltcGxvZGUoICcgJywgYXJyYXlfa2V5cyggJHNlc3Npb25zICkgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkc2Vzc2lvbnMgKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9hbGxfc2Vzc2lvbnMoIFdQX1Nlc3Npb25fVG9rZW5zICRtYW5hZ2VyICkgewoJCS8vIE1ha2UgdGhlIHByaXZhdGUgc2Vzc2lvbiBkYXRhIGFjY2Vzc2libGUgdG8gV1AtQ0xJCgkJJGdldF9zZXNzaW9ucyA9IG5ldyBSZWZsZWN0aW9uTWV0aG9kKCAkbWFuYWdlciwgJ2dldF9zZXNzaW9ucycgKTsKCQkkZ2V0X3Nlc3Npb25zLT5zZXRBY2Nlc3NpYmxlKCB0cnVlICk7CgkJJHNlc3Npb25zID0gJGdldF9zZXNzaW9ucy0+aW52b2tlKCAkbWFuYWdlciApOwoKCQlhcnJheV93YWxrKAoJCQkkc2Vzc2lvbnMsCgkJCWZ1bmN0aW9uKCAmJHNlc3Npb24sICR0b2tlbiApIHsKCQkJCSRzZXNzaW9uWyd0b2tlbiddICAgICAgICAgICA9ICR0b2tlbjsKCQkJCSRzZXNzaW9uWydsb2dpbl90aW1lJ10gICAgICA9IGRhdGUoICdZLW0tZCBIOmk6cycsICRzZXNzaW9uWydsb2dpbiddICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkJCSRzZXNzaW9uWydleHBpcmF0aW9uX3RpbWUnXSA9IGRhdGUoICdZLW0tZCBIOmk6cycsICRzZXNzaW9uWydleHBpcmF0aW9uJ10gKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCQl9CgkJKTsKCgkJcmV0dXJuICRzZXNzaW9uczsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVzdHJveV9zZXNzaW9uKCBXUF9TZXNzaW9uX1Rva2VucyAkbWFuYWdlciwgJHRva2VuICkgewoJCSR1cGRhdGVfc2Vzc2lvbiA9IG5ldyBSZWZsZWN0aW9uTWV0aG9kKCAkbWFuYWdlciwgJ3VwZGF0ZV9zZXNzaW9uJyApOwoJCSR1cGRhdGVfc2Vzc2lvbi0+c2V0QWNjZXNzaWJsZSggdHJ1ZSApOwoJCXJldHVybiAkdXBkYXRlX3Nlc3Npb24tPmludm9rZSggJG1hbmFnZXIsICR0b2tlbiwgbnVsbCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcyApOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTGlzdHMsIGNyZWF0ZXMsIGFzc2lnbnMsIGFuZCBkZWxldGVzIHRoZSBhY3RpdmUgdGhlbWUncyBuYXZpZ2F0aW9uIG1lbnVzLgogKgogKiBTZWUgdGhlIFtOYXZpZ2F0aW9uIE1lbnVzXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9mdW5jdGlvbmFsaXR5L25hdmlnYXRpb24tbWVudXMvKSByZWZlcmVuY2UgaW4gdGhlIFRoZW1lIEhhbmRib29rLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBDcmVhdGUgYSBuZXcgbWVudQogKiAgICAgJCB3cCBtZW51IGNyZWF0ZSAiTXkgTWVudSIKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgbWVudSAyMDAuCiAqCiAqICAgICAjIExpc3QgZXhpc3RpbmcgbWVudXMKICogICAgICQgd3AgbWVudSBsaXN0CiAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tKwogKiAgICAgfCB0ZXJtX2lkIHwgbmFtZSAgICAgfCBzbHVnICAgICB8IGxvY2F0aW9ucyB8IGNvdW50IHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0rCiAqICAgICB8IDIwMCAgICAgfCBNeSBNZW51ICB8IG15LW1lbnUgIHwgICAgICAgICAgIHwgMCAgICAgfAogKiAgICAgfCAxNzcgICAgIHwgVG9wIE1lbnUgfCB0b3AtbWVudSB8IHByaW1hcnkgICB8IDcgICAgIHwKICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0rCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBtZW51IGxpbmsgaXRlbQogKiAgICAgJCB3cCBtZW51IGl0ZW0gYWRkLWN1c3RvbSBteS1tZW51IEFwcGxlIGh0dHA6Ly9hcHBsZS5jb20gLS1wb3JjZWxhaW4KICogICAgIDE5MjIKICoKICogICAgICMgQXNzaWduIHRoZSAnbXktbWVudScgbWVudSB0byB0aGUgJ3ByaW1hcnknIGxvY2F0aW9uCiAqICAgICAkIHdwIG1lbnUgbG9jYXRpb24gYXNzaWduIG15LW1lbnUgcHJpbWFyeQogKiAgICAgU3VjY2VzczogQXNzaWduZWQgbG9jYXRpb24gdG8gbWVudS4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBNZW51X0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJvdGVjdGVkICRvYmpfdHlwZSAgID0gJ25hdl9tZW51JzsKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsKCQkndGVybV9pZCcsCgkJJ25hbWUnLAoJCSdzbHVnJywKCQknbG9jYXRpb25zJywKCQknY291bnQnLAoJXTsKCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgbWVudS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG1lbnUtbmFtZT4KCSAqIDogQSBkZXNjcmlwdGl2ZSBuYW1lIGZvciB0aGUgbWVudS4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgbWVudSBpZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1lbnUgY3JlYXRlICJNeSBNZW51IgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgbWVudSAyMDAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjcmVhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJG1lbnVfaWQgPSB3cF9jcmVhdGVfbmF2X21lbnUoICRhcmdzWzBdICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRtZW51X2lkICkgKSB7CgoJCQlXUF9DTEk6OmVycm9yKCAkbWVudV9pZC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoKCQl9IGVsc2UgewoKCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICRtZW51X2lkICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDcmVhdGVkIG1lbnUgeyRtZW51X2lkfS4iICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGVzIG9uZSBvciBtb3JlIG1lbnVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bWVudT4uLi4KCSAqIDogVGhlIG5hbWUsIHNsdWcsIG9yIHRlcm0gSUQgZm9yIHRoZSBtZW51KHMpLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWVudSBkZWxldGUgIk15IE1lbnUiCgkgKiAgICAgU3VjY2VzczogMSBtZW51IGRlbGV0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvdW50ICA9IDA7CgkJJGVycm9ycyA9IDA7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCSRyZXQgPSB3cF9kZWxldGVfbmF2X21lbnUoICRhcmcgKTsKCQkJaWYgKCAhICRyZXQgfHwgaXNfd3BfZXJyb3IoICRyZXQgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGRlbGV0ZSBtZW51ICd7JGFyZ30nLiIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCBtZW51ICd7JGFyZ30nLiIgKTsKCQkJCSRjb3VudCsrOwoJCQl9CgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdtZW51JywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIEdldHMgYSBsaXN0IG9mIG1lbnVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSBpZHMKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggbWVudToKCSAqCgkgKiAqIHRlcm1faWQKCSAqICogbmFtZQoJICogKiBzbHVnCgkgKiAqIGNvdW50CgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHRlcm1fZ3JvdXAKCSAqICogdGVybV90YXhvbm9teV9pZAoJICogKiB0YXhvbm9teQoJICogKiBkZXNjcmlwdGlvbgoJICogKiBwYXJlbnQKCSAqICogbG9jYXRpb25zCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBtZW51IGxpc3QKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tKwoJICogICAgIHwgdGVybV9pZCB8IG5hbWUgICAgIHwgc2x1ZyAgICAgfCBsb2NhdGlvbnMgfCBjb3VudCB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqICAgICB8IDIwMCAgICAgfCBNeSBNZW51ICB8IG15LW1lbnUgIHwgICAgICAgICAgIHwgMCAgICAgfAoJICogICAgIHwgMTc3ICAgICB8IFRvcCBNZW51IHwgdG9wLW1lbnUgfCBwcmltYXJ5ICAgfCA3ICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkbWVudXMgPSB3cF9nZXRfbmF2X21lbnVzKCk7CgoJCSRtZW51X2xvY2F0aW9ucyA9IGdldF9uYXZfbWVudV9sb2NhdGlvbnMoKTsKCQlmb3JlYWNoICggJG1lbnVzIGFzICYkbWVudSApIHsKCgkJCSRtZW51LT5sb2NhdGlvbnMgPSBbXTsKCQkJZm9yZWFjaCAoICRtZW51X2xvY2F0aW9ucyBhcyAkbG9jYXRpb24gPT4gJHRlcm1faWQgKSB7CgoJCQkJaWYgKCAkdGVybV9pZCA9PT0gJG1lbnUtPnRlcm1faWQgKSB7CgkJCQkJJG1lbnUtPmxvY2F0aW9uc1tdID0gJGxvY2F0aW9uOwoJCQkJfQoJCQl9CgoJCQkvLyBOb3JtYWxpemUgdGhlIGRhdGEgZm9yIHNvbWUgb3V0cHV0IGZvcm1hdHMuCgkJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgfHwgaW5fYXJyYXkoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgWyAnY3N2JywgJ3RhYmxlJyBdLCB0cnVlICkgKSB7CgkJCQkkbWVudS0+bG9jYXRpb25zID0gaW1wbG9kZSggJywnLCAkbWVudS0+bG9jYXRpb25zICk7CgkJCX0KCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQkkaWRzID0gYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24oICRvICkgewoJCQkJCXJldHVybiAkby0+dGVybV9pZDsKCQkJCX0sCgkJCQkkbWVudXMKCQkJKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGlkcyApOwoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRtZW51cyApOwoJCX0KCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPm9ial9maWVsZHMsICR0aGlzLT5vYmpfdHlwZSApOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aFRlcm1zOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFBvc3QgYXMgUG9zdEZldGNoZXI7CgovKioKICogQWRkcywgdXBkYXRlcywgcmVtb3ZlcywgYW5kIGxpc3RzIHBvc3QgdGVybXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCBwb3N0IHRlcm1zCiAqICAgICAkIHdwIHBvc3QgdGVybSBzZXQgMTIzIHRlc3QgY2F0ZWdvcnkKICogICAgIFN1Y2Nlc3M6IFNldCB0ZXJtcy4KICovCmNsYXNzIFBvc3RfVGVybV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhUZXJtcyB7Cglwcm90ZWN0ZWQgJG9ial90eXBlID0gJ3Bvc3QnOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQkkdGhpcy0+ZmV0Y2hlciA9IG5ldyBQb3N0RmV0Y2hlcigpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfb2JqZWN0X3R5cGUoKSB7CgkJJHBvc3QgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkdGhpcy0+Z2V0X29ial9pZCgpICk7CgoJCXJldHVybiAkcG9zdC0+cG9zdF90eXBlOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVudGl0eTsKCmNsYXNzIFV0aWxzIHsKCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYW55IGlucHV0IGlzIHBhc3NlZCB0byBTVERJTi4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYXNfc3RkaW4oKSB7CgkJJGhhbmRsZSAgPSBmb3BlbiggJ3BocDovL3N0ZGluJywgJ3InICk7CgkJJHJlYWQgICAgPSBhcnJheSggJGhhbmRsZSApOwoJCSR3cml0ZSAgID0gbnVsbDsKCQkkZXhjZXB0ICA9IG51bGw7CgkJJHN0cmVhbXMgPSBzdHJlYW1fc2VsZWN0KCAkcmVhZCwgJHdyaXRlLCAkZXhjZXB0LCAwICk7CgkJZmNsb3NlKCAkaGFuZGxlICk7CgoJCXJldHVybiAxID09PSAkc3RyZWFtczsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxFbnRpdHk7Cgp1c2UgVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uOwoKY2xhc3MgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciB7CgoJLyoqCgkgKiBAdmFyIG1peGVkIFRoZSBkYXRhIHRvIHRyYXZlcnNlIHNldCBieSByZWZlcmVuY2UuCgkgKi8KCXByb3RlY3RlZCAkZGF0YTsKCgkvKioKCSAqIEB2YXIgbnVsbHxzdHJpbmcgVGhlIGtleSB0aGUgZGF0YSBiZWxvbmdzIHRvIGluIHRoZSBwYXJlbnQncyBkYXRhLgoJICovCglwcm90ZWN0ZWQgJGtleTsKCgkvKioKCSAqIEB2YXIgbnVsbHxzdGF0aWMgVGhlIHBhcmVudCBpbnN0YW5jZSBvZiB0aGUgdHJhdmVyc2VyLgoJICovCglwcm90ZWN0ZWQgJHBhcmVudDsKCgkvKioKCSAqIFJlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXIgY29uc3RydWN0b3IuCgkgKgoJICogQHBhcmFtIG1peGVkICRkYXRhIFRoZSBkYXRhIHRvIHJlYWQvbWFuaXB1bGF0ZSBieSByZWZlcmVuY2UuCgkgKiBAcGFyYW0gc3RyaW5nfGludCAka2V5IFRoZSBrZXkvcHJvcGVydHkgdGhlIGRhdGEgYmVsb25ncyB0by4KCSAqIEBwYXJhbSBzdGF0aWMgJHBhcmVudAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICYkZGF0YSwgJGtleSA9IG51bGwsICRwYXJlbnQgPSBudWxsICkgewoJCSR0aGlzLT5kYXRhICAgPSYgJGRhdGE7CgkJJHRoaXMtPmtleSAgICA9ICRrZXk7CgkJJHRoaXMtPnBhcmVudCA9ICRwYXJlbnQ7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIG5lc3RlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4ga2V5IHBhdGguCgkgKgoJICogQHBhcmFtIHN0cmluZ3xpbnR8YXJyYXkgJGtleV9wYXRoCgkgKgoJICogQHJldHVybiBzdGF0aWMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGtleV9wYXRoICkgewoJCXJldHVybiAkdGhpcy0+dHJhdmVyc2VfdG8oIChhcnJheSkgJGtleV9wYXRoICktPnZhbHVlKCk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGN1cnJlbnQgZGF0YS4KCSAqCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB2YWx1ZSgpIHsKCQlyZXR1cm4gJHRoaXMtPmRhdGE7Cgl9CgoJLyoqCgkgKiBVcGRhdGUgYSBuZXN0ZWQgdmFsdWUgYXQgdGhlIGdpdmVuIGtleSBwYXRoLgoJICoKCSAqIEBwYXJhbSBzdHJpbmd8aW50fGFycmF5ICRrZXlfcGF0aAoJICogQHBhcmFtIG1peGVkICR2YWx1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAka2V5X3BhdGgsICR2YWx1ZSApIHsKCQkkdGhpcy0+dHJhdmVyc2VfdG8oIChhcnJheSkgJGtleV9wYXRoICktPnNldF92YWx1ZSggJHZhbHVlICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGUgdGhlIGN1cnJlbnQgZGF0YSB3aXRoIHRoZSBnaXZlbiB2YWx1ZS4KCSAqCgkgKiBUaGlzIHdpbGwgbXV0YXRlIHRoZSB2YXJpYWJsZSB3aGljaCB3YXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yCgkgKiBhcyB0aGUgZGF0YSBpcyBzZXQgYW5kIHRyYXZlcnNlZCBieSByZWZlcmVuY2UuCgkgKgoJICogQHBhcmFtIG1peGVkICR2YWx1ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0X3ZhbHVlKCAkdmFsdWUgKSB7CgkJJHRoaXMtPmRhdGEgPSAkdmFsdWU7Cgl9CgoJLyoqCgkgKiBVbnNldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGtleSBwYXRoLgoJICoKCSAqIEBwYXJhbSAka2V5X3BhdGgKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGtleV9wYXRoICkgewoJCSR0aGlzLT50cmF2ZXJzZV90byggKGFycmF5KSAka2V5X3BhdGggKS0+dW5zZXRfb25fcGFyZW50KCk7Cgl9CgoJLyoqCgkgKiBEZWZpbmUgYSBuZXN0ZWQgdmFsdWUgd2hpbGUgY3JlYXRpbmcga2V5cyBpZiB0aGV5IGRvIG5vdCBleGlzdC4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGtleV9wYXRoCgkgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbnNlcnQoICRrZXlfcGF0aCwgJHZhbHVlICkgewoJCXRyeSB7CgkJCSR0aGlzLT51cGRhdGUoICRrZXlfcGF0aCwgJHZhbHVlICk7CgkJfSBjYXRjaCAoIE5vbkV4aXN0ZW50S2V5RXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCSRleGNlcHRpb24tPmdldF90cmF2ZXJzZXIoKS0+Y3JlYXRlX2tleSgpOwoJCQkkdGhpcy0+aW5zZXJ0KCAka2V5X3BhdGgsICR2YWx1ZSApOwoJCX0KCX0KCgkvKioKCSAqIERlbGV0ZSB0aGUga2V5IG9uIHRoZSBwYXJlbnQncyBkYXRhIHRoYXQgcmVmZXJlbmNlcyB0aGlzIGRhdGEuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bnNldF9vbl9wYXJlbnQoKSB7CgkJJHRoaXMtPnBhcmVudC0+ZGVsZXRlX2J5X2tleSggJHRoaXMtPmtleSApOwoJfQoKCS8qKgoJICogRGVsZXRlIHRoZSBnaXZlbiBrZXkgZnJvbSB0aGUgZGF0YS4KCSAqCgkgKiBAcGFyYW0gJGtleQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlX2J5X2tleSggJGtleSApIHsKCQlpZiAoIGlzX2FycmF5KCAkdGhpcy0+ZGF0YSApICkgewoJCQl1bnNldCggJHRoaXMtPmRhdGFbICRrZXkgXSApOwoJCX0gZWxzZSB7CgkJCXVuc2V0KCAkdGhpcy0+ZGF0YS0+JGtleSApOwoJCX0KCX0KCgkvKioKCSAqIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgdHJhdmVyc2VyIGZvciB0aGUgZ2l2ZW4gaGllcmFyY2hpY2FsIGtleS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGtleV9wYXRoIEhpZXJhcmNoaWNhbCBrZXkgcGF0aCB3aXRoaW4gdGhlIGN1cnJlbnQgZGF0YSB0byB0cmF2ZXJzZSB0by4KCSAqCgkgKiBAdGhyb3dzIE5vbkV4aXN0ZW50S2V5RXhjZXB0aW9uCgkgKgoJICogQHJldHVybiBzdGF0aWMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRyYXZlcnNlX3RvKCBhcnJheSAka2V5X3BhdGggKSB7CgkJJGN1cnJlbnQgPSBhcnJheV9zaGlmdCggJGtleV9wYXRoICk7CgoJCWlmICggbnVsbCA9PT0gJGN1cnJlbnQgKSB7CgkJCXJldHVybiAkdGhpczsKCQl9CgoJCWlmICggISAkdGhpcy0+ZXhpc3RzKCAkY3VycmVudCApICkgewoJCQkkZXhjZXB0aW9uID0gbmV3IE5vbkV4aXN0ZW50S2V5RXhjZXB0aW9uKCAiTm8gZGF0YSBleGlzdHMgZm9yIGtleSBcInskY3VycmVudH1cIiIgKTsKCQkJJGV4Y2VwdGlvbi0+c2V0X3RyYXZlcnNlciggbmV3IHN0YXRpYyggJHRoaXMtPmRhdGEsICRjdXJyZW50LCAkdGhpcy0+cGFyZW50ICkgKTsKCQkJdGhyb3cgJGV4Y2VwdGlvbjsKCQl9CgoJCWZvcmVhY2ggKCAkdGhpcy0+ZGF0YSBhcyAka2V5ID0+ICYka2V5X2RhdGEgKSB7CgkJCWlmICggJGtleSA9PT0gJGN1cnJlbnQgKSB7CgkJCQkkdHJhdmVyc2VyID0gbmV3IHN0YXRpYyggJGtleV9kYXRhLCAka2V5LCAkdGhpcyApOwoJCQkJcmV0dXJuICR0cmF2ZXJzZXItPnRyYXZlcnNlX3RvKCAka2V5X3BhdGggKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIENyZWF0ZSB0aGUga2V5IG9uIHRoZSBjdXJyZW50IGRhdGEuCgkgKgoJICogQHRocm93cyBVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZV9rZXkoKSB7CgkJaWYgKCBpc19hcnJheSggJHRoaXMtPmRhdGEgKSApIHsKCQkJJHRoaXMtPmRhdGFbICR0aGlzLT5rZXkgXSA9IG51bGw7CgkJfSBlbHNlaWYgKCBpc19vYmplY3QoICR0aGlzLT5kYXRhICkgKSB7CgkJCSR0aGlzLT5kYXRhLT57JHRoaXMtPmtleX0gPSBudWxsOwoJCX0gZWxzZSB7CgkJCSR0eXBlID0gZ2V0dHlwZSggJHRoaXMtPmRhdGEgKTsKCQkJdGhyb3cgbmV3IFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbigKCQkJCSJDYW5ub3QgY3JlYXRlIGtleSBcInskdGhpcy0+a2V5fVwiIG9uIGRhdGEgdHlwZSB7JHR5cGV9IgoJCQkpOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrIGlmIHRoZSBnaXZlbiBrZXkgZXhpc3RzIG9uIHRoZSBjdXJyZW50IGRhdGEuCgkgKgoJICogQHBhcmFtIHN0cmluZyAka2V5CgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBleGlzdHMoICRrZXkgKSB7CgkJcmV0dXJuICggaXNfYXJyYXkoICR0aGlzLT5kYXRhICkgJiYgYXJyYXlfa2V5X2V4aXN0cyggJGtleSwgJHRoaXMtPmRhdGEgKSApIHx8CgkJCSggaXNfb2JqZWN0KCAkdGhpcy0+ZGF0YSApICYmIHByb3BlcnR5X2V4aXN0cyggJHRoaXMtPmRhdGEsICRrZXkgKSApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVudGl0eTsKCnVzZSBPdXRPZkJvdW5kc0V4Y2VwdGlvbjsKCmNsYXNzIE5vbkV4aXN0ZW50S2V5RXhjZXB0aW9uIGV4dGVuZHMgT3V0T2ZCb3VuZHNFeGNlcHRpb24gewoJLyoqIEB2YXIgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciAqLwoJcHJvdGVjdGVkICR0cmF2ZXJzZXI7CgoJLyoqCgkgKiBAcGFyYW0gUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciAkdHJhdmVyc2VyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfdHJhdmVyc2VyKCAkdHJhdmVyc2VyICkgewoJCSR0aGlzLT50cmF2ZXJzZXIgPSAkdHJhdmVyc2VyOwoJfQoKCS8qKgoJICogQHJldHVybiBSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRfdHJhdmVyc2VyKCkgewoJCXJldHVybiAkdGhpcy0+dHJhdmVyc2VyOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfQ0xJXEVudGl0eVxSZWN1cnNpdmVEYXRhU3RydWN0dXJlVHJhdmVyc2VyOwp1c2UgV1BfQ0xJXEVudGl0eVxVdGlscyBhcyBFbnRpdHlVdGlsczsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBXUC1DTEkgY29tbWFuZHMgdGhhdCBkZWFsIHdpdGggbWV0YWRhdGEKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwphYnN0cmFjdCBjbGFzcyBDb21tYW5kV2l0aE1ldGEgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJvdGVjdGVkICRtZXRhX3R5cGU7CgoJLyoqCgkgKiBMaXN0IGFsbCBtZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGggYW4gb2JqZWN0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IElEIGZvciB0aGUgb2JqZWN0LgoJICoKCSAqIFstLWtleXM9PGtleXM+XQoJICogOiBMaW1pdCBvdXRwdXQgdG8gbWV0YWRhdGEgb2Ygc3BlY2lmaWMga2V5cy4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgcm93IGZpZWxkcy4gRGVmYXVsdHMgdG8gaWQsbWV0YV9rZXksbWV0YV92YWx1ZS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogICAtIGNvdW50CgkgKiAtLS0KCSAqCgkgKiBbLS1vcmRlcmJ5PTxmaWVsZHM+XQoJICogOiBTZXQgb3JkZXJieSB3aGljaCBmaWVsZC4KCSAqIC0tLQoJICogZGVmYXVsdDogaWQKCSAqIG9wdGlvbnM6CgkgKiAgLSBpZAoJICogIC0gbWV0YV9rZXkKCSAqICAtIG1ldGFfdmFsdWUKCSAqIC0tLQoJICoKCSAqIFstLW9yZGVyPTxvcmRlcj5dCgkgKiA6IFNldCBhc2NlbmRpbmcgb3IgZGVzY2VuZGluZyBvcmRlci4KCSAqIC0tLQoJICogZGVmYXVsdDogYXNjCgkgKiBvcHRpb25zOgoJICogIC0gYXNjCgkgKiAgLSBkZXNjCgkgKiAtLS0KCSAqCgkgKiBbLS11bnNlcmlhbGl6ZV0KCSAqIDogVW5zZXJpYWxpemUgbWV0YV92YWx1ZSBvdXRwdXQuCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJG9iamVjdF9pZCApID0gJGFyZ3M7CgoJCSRrZXlzID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ2tleXMnXSApID8gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1sna2V5cyddICkgOiBbXTsKCgkJJG9iamVjdF9pZCA9ICR0aGlzLT5jaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKTsKCgkJJG1ldGFkYXRhID0gJHRoaXMtPmdldF9tZXRhZGF0YSggJG9iamVjdF9pZCApOwoJCWlmICggISAkbWV0YWRhdGEgKSB7CgkJCSRtZXRhZGF0YSA9IFtdOwoJCX0KCgkJJGl0ZW1zID0gW107CgkJZm9yZWFjaCAoICRtZXRhZGF0YSBhcyAka2V5ID0+ICR2YWx1ZXMgKSB7CgoJCQkvLyBTa2lwIGlmIG5vdCByZXF1ZXN0ZWQKCQkJaWYgKCAhIGVtcHR5KCAka2V5cyApICYmICEgaW5fYXJyYXkoICRrZXksICRrZXlzLCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJZm9yZWFjaCAoICR2YWx1ZXMgYXMgJGl0ZW1fdmFsdWUgKSB7CgoJCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd1bnNlcmlhbGl6ZScgKSApIHsKCQkJCQkkaXRlbV92YWx1ZSA9IG1heWJlX3Vuc2VyaWFsaXplKCAkaXRlbV92YWx1ZSApOwoJCQkJfQoKCQkJCSRpdGVtc1tdID0gKG9iamVjdCkgWwoJCQkJCSJ7JHRoaXMtPm1ldGFfdHlwZX1faWQiID0+ICRvYmplY3RfaWQsCgkJCQkJJ21ldGFfa2V5JyAgICAgICAgICAgICAgPT4gJGtleSwKCQkJCQknbWV0YV92YWx1ZScgICAgICAgICAgICA9PiAkaXRlbV92YWx1ZSwKCQkJCV07CgkJCX0KCQl9CgoJCSRvcmRlciAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnb3JkZXInICk7CgkJJG9yZGVyYnkgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdvcmRlcmJ5JyApOwoKCQlpZiAoICdpZCcgIT09ICRvcmRlcmJ5ICkgewoKCQkJdXNvcnQoCgkJCQkkaXRlbXMsCgkJCQlmdW5jdGlvbiAoICRhLCAkYiApIHVzZSAoICRvcmRlcmJ5LCAkb3JkZXIgKSB7CgkJCQkJLy8gU29ydCBhcnJheS4KCQkJCQlyZXR1cm4gJ2FzYycgPT09ICRvcmRlcgoJCQkJCQk/ICRhLT4kb3JkZXJieSA+ICRiLT4kb3JkZXJieQoJCQkJCQk6ICRhLT4kb3JkZXJieSA8ICRiLT4kb3JkZXJieTsKCQkJCX0KCQkJKTsKCgkJfSBlbHNlaWYgKCAnaWQnID09PSAkb3JkZXJieSAmJiAnZGVzYycgPT09ICRvcmRlciApIHsgLy8gU29ydCBieSBkZWZhdWx0IGRlc2NlbmRpbmcuCgkJCWtyc29ydCggJGl0ZW1zICk7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkZmllbGRzID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9IGVsc2UgewoJCQkkZmllbGRzID0gJHRoaXMtPmdldF9maWVsZHMoKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJGZpZWxkcywgJHRoaXMtPm1ldGFfdHlwZSApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpdGVtcyApOwoKCX0KCgkvKioKCSAqIEdldCBtZXRhIGZpZWxkIHZhbHVlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgb2JqZWN0LgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBtZXRhIGZpZWxkIHRvIGdldC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IEdldCB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB2YXJfZXhwb3J0CgkgKiBvcHRpb25zOgoJICogICAtIHZhcl9leHBvcnQKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkb2JqZWN0X2lkLCAkbWV0YV9rZXkgKSA9ICRhcmdzOwoKCQkkb2JqZWN0X2lkID0gJHRoaXMtPmNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApOwoKCQkkdmFsdWUgPSAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksIHRydWUgKTsKCgkJaWYgKCAnJyA9PT0gJHZhbHVlICkgewoJCQlkaWUoIDEgKTsKCQl9CgoJCVdQX0NMSTo6cHJpbnRfdmFsdWUoICR2YWx1ZSwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIERlbGV0ZSBhIG1ldGEgZmllbGQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogWzxrZXk+XQoJICogOiBUaGUgbmFtZSBvZiB0aGUgbWV0YSBmaWVsZCB0byBkZWxldGUuCgkgKgoJICogWzx2YWx1ZT5dCgkgKiA6IFRoZSB2YWx1ZSB0byBkZWxldGUuIElmIG9taXR0ZWQsIGFsbCByb3dzIHdpdGgga2V5IHdpbGwgZGVsZXRlZC4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IERlbGV0ZSBhbGwgbWV0YSBmb3IgdGhlIG9iamVjdC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRvYmplY3RfaWQgKSA9ICRhcmdzOwoKCQkkbWV0YV9rZXkgICA9ICEgZW1wdHkoICRhcmdzWzFdICkgPyAkYXJnc1sxXSA6ICcnOwoJCSRtZXRhX3ZhbHVlID0gISBlbXB0eSggJGFyZ3NbMl0gKSA/ICRhcmdzWzJdIDogJyc7CgoJCWlmICggZW1wdHkoICRtZXRhX2tleSApICYmICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgYSBtZXRhIGtleSwgb3IgdXNlIHRoZSAtLWFsbCBmbGFnLicgKTsKCQl9CgoJCSRvYmplY3RfaWQgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQkkZXJyb3JzID0gZmFsc2U7CgkJCWZvcmVhY2ggKCAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkICkgYXMgJG1ldGFfa2V5ID0+ICR2YWx1ZXMgKSB7CgkJCQkkc3VjY2VzcyA9ICR0aGlzLT5kZWxldGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSApOwoJCQkJaWYgKCAkc3VjY2VzcyApIHsKCQkJCQlXUF9DTEk6OmxvZyggIkRlbGV0ZWQgJ3skbWV0YV9rZXl9JyBjdXN0b20gZmllbGQuIiApOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJGYWlsZWQgdG8gZGVsZXRlICd7JG1ldGFfa2V5fScgY3VzdG9tIGZpZWxkLiIgKTsKCQkJCQkkZXJyb3JzID0gdHJ1ZTsKCQkJCX0KCQkJfQoJCQlpZiAoICRlcnJvcnMgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIGRlbGV0ZSBhbGwgY3VzdG9tIGZpZWxkcy4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdEZWxldGVkIGFsbCBjdXN0b20gZmllbGRzLicgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRzdWNjZXNzID0gJHRoaXMtPmRlbGV0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSApOwoJCQlpZiAoICRzdWNjZXNzICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnRGVsZXRlZCBjdXN0b20gZmllbGQuJyApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggJ0ZhaWxlZCB0byBkZWxldGUgY3VzdG9tIGZpZWxkLicgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEFkZCBhIG1ldGEgZmllbGQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPGtleT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIG1ldGEgZmllbGQgdG8gY3JlYXRlLgoJICoKCSAqIFs8dmFsdWU+XQoJICogOiBUaGUgdmFsdWUgb2YgdGhlIG1ldGEgZmllbGQuIElmIG9taXR0ZWQsIHRoZSB2YWx1ZSBpcyByZWFkIGZyb20gU1RESU4uCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqIC0tLQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJG9iamVjdF9pZCwgJG1ldGFfa2V5ICkgPSAkYXJnczsKCgkJJG1ldGFfdmFsdWUgPSBXUF9DTEk6OmdldF92YWx1ZV9mcm9tX2FyZ19vcl9zdGRpbiggJGFyZ3MsIDIgKTsKCQkkbWV0YV92YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJG1ldGFfdmFsdWUsICRhc3NvY19hcmdzICk7CgoJCSRvYmplY3RfaWQgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgoJCSRtZXRhX3ZhbHVlID0gd3Bfc2xhc2goICRtZXRhX3ZhbHVlICk7CgkJJHN1Y2Nlc3MgICAgPSAkdGhpcy0+YWRkX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlICk7CgoJCWlmICggJHN1Y2Nlc3MgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ0FkZGVkIGN1c3RvbSBmaWVsZC4nICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ZhaWxlZCB0byBhZGQgY3VzdG9tIGZpZWxkLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBVcGRhdGUgYSBtZXRhIGZpZWxkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgb2JqZWN0LgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBtZXRhIGZpZWxkIHRvIHVwZGF0ZS4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21pdHRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogQGFsaWFzIHNldAoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJG9iamVjdF9pZCwgJG1ldGFfa2V5ICkgPSAkYXJnczsKCgkJJG1ldGFfdmFsdWUgPSBXUF9DTEk6OmdldF92YWx1ZV9mcm9tX2FyZ19vcl9zdGRpbiggJGFyZ3MsIDIgKTsKCQkkbWV0YV92YWx1ZSA9IFdQX0NMSTo6cmVhZF92YWx1ZSggJG1ldGFfdmFsdWUsICRhc3NvY19hcmdzICk7CgoJCSRvYmplY3RfaWQgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgoJCSRtZXRhX3ZhbHVlID0gc2FuaXRpemVfbWV0YSggJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHRoaXMtPm1ldGFfdHlwZSApOwoJCSRvbGRfdmFsdWUgID0gc2FuaXRpemVfbWV0YSggJG1ldGFfa2V5LCAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksIHRydWUgKSwgJHRoaXMtPm1ldGFfdHlwZSApOwoKCQlpZiAoICRtZXRhX3ZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nIGlzIHVuY2hhbmdlZC4iICk7CgkJfSBlbHNlIHsKCQkJJG1ldGFfdmFsdWUgPSB3cF9zbGFzaCggJG1ldGFfdmFsdWUgKTsKCQkJJHN1Y2Nlc3MgICAgPSAkdGhpcy0+dXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlICk7CgoJCQlpZiAoICRzdWNjZXNzICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiVXBkYXRlZCBjdXN0b20gZmllbGQgJ3skbWV0YV9rZXl9Jy4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiRmFpbGVkIHRvIHVwZGF0ZSBjdXN0b20gZmllbGQgJ3skbWV0YV9rZXl9Jy4iICk7CgkJCX0KCQl9CgoJfQoKCS8qKgoJICogR2V0IGEgbmVzdGVkIHZhbHVlIGZyb20gYSBtZXRhIGZpZWxkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgb2JqZWN0LgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBtZXRhIGZpZWxkIHRvIGdldC4KCSAqCgkgKiA8a2V5LXBhdGg+Li4uCgkgKiA6IFRoZSBuYW1lKHMpIG9mIHRoZSBrZXlzIHdpdGhpbiB0aGUgdmFsdWUgdG8gbG9jYXRlIHRoZSB2YWx1ZSB0byBwbHVjay4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBvdXRwdXQgZm9ybWF0IG9mIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogcGxhaW50ZXh0CgkgKiBvcHRpb25zOgoJICogICAtIHBsYWludGV4dAoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwbHVjayggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRvYmplY3RfaWQsICRtZXRhX2tleSApID0gJGFyZ3M7CgkJJG9iamVjdF9pZCAgICAgICAgICAgICAgICAgICAgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgkJJGtleV9wYXRoICAgICAgICAgICAgICAgICAgICAgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uICggJGtleSApIHsKCQkJCWlmICggaXNfbnVtZXJpYyggJGtleSApICYmICggKHN0cmluZykgaW50dmFsKCAka2V5ICkgPT09ICRrZXkgKSApIHsKCQkJCQlyZXR1cm4gKGludCkgJGtleTsKCQkJCX0KCQkJCXJldHVybiAka2V5OwoJCQl9LAoJCQlhcnJheV9zbGljZSggJGFyZ3MsIDIgKQoJCSk7CgoJCSR2YWx1ZSA9ICR0aGlzLT5nZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgdHJ1ZSApOwoKCQkkdHJhdmVyc2VyID0gbmV3IFJlY3Vyc2l2ZURhdGFTdHJ1Y3R1cmVUcmF2ZXJzZXIoICR2YWx1ZSApOwoKCQl0cnkgewoJCQkkdmFsdWUgPSAkdHJhdmVyc2VyLT5nZXQoICRrZXlfcGF0aCApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJZGllKCAxICk7CgkJfQoKCQlXUF9DTEk6OnByaW50X3ZhbHVlKCAkdmFsdWUsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGUgYSBuZXN0ZWQgdmFsdWUgZm9yIGEgbWV0YSBmaWVsZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGFjdGlvbj4KCSAqIDogUGF0Y2ggYWN0aW9uIHRvIHBlcmZvcm0uCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gaW5zZXJ0CgkgKiAgIC0gdXBkYXRlCgkgKiAgIC0gZGVsZXRlCgkgKiAtLS0KCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgb2JqZWN0LgoJICoKCSAqIDxrZXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSBtZXRhIGZpZWxkIHRvIHVwZGF0ZS4KCSAqCgkgKiA8a2V5LXBhdGg+Li4uCgkgKiA6IFRoZSBuYW1lKHMpIG9mIHRoZSBrZXlzIHdpdGhpbiB0aGUgdmFsdWUgdG8gbG9jYXRlIHRoZSB2YWx1ZSB0byBwYXRjaC4KCSAqCgkgKiBbPHZhbHVlPl0KCSAqIDogVGhlIG5ldyB2YWx1ZS4gSWYgb21pdHRlZCwgdGhlIHZhbHVlIGlzIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBmb3IgdGhlIHZhbHVlLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwbGFpbnRleHQKCSAqIG9wdGlvbnM6CgkgKiAgIC0gcGxhaW50ZXh0CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwYXRjaCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRhY3Rpb24sICRvYmplY3RfaWQsICRtZXRhX2tleSApID0gJGFyZ3M7CgkJJG9iamVjdF9pZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAkdGhpcy0+Y2hlY2tfb2JqZWN0X2lkKCAkb2JqZWN0X2lkICk7CgkJJGtleV9wYXRoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhcnJheV9tYXAoCgkJCWZ1bmN0aW9uKCAka2V5ICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgJiYgKCAoc3RyaW5nKSBpbnR2YWwoICRrZXkgKSA9PT0gJGtleSApICkgewoJCQkJCXJldHVybiAoaW50KSAka2V5OwoJCQkJfQoJCQkJCXJldHVybiAka2V5OwoJCQl9LAoJCQlhcnJheV9zbGljZSggJGFyZ3MsIDMgKQoJCSk7CgoJCWlmICggJ2RlbGV0ZScgPT09ICRhY3Rpb24gKSB7CgkJCSRwYXRjaF92YWx1ZSA9IG51bGw7CgkJfSBlbHNlIHsKCQkJJHN0ZGluX3ZhbHVlID0gRW50aXR5VXRpbHM6Omhhc19zdGRpbigpCgkJCQk/IHRyaW0oIFdQX0NMSTo6Z2V0X3ZhbHVlX2Zyb21fYXJnX29yX3N0ZGluKCAkYXJncywgLTEgKSApCgkJCQk6IG51bGw7CgkJCSRwYXRjaF92YWx1ZSA9ICEgZW1wdHkoICRzdGRpbl92YWx1ZSApCgkJCQk/IFdQX0NMSTo6cmVhZF92YWx1ZSggJHN0ZGluX3ZhbHVlLCAkYXNzb2NfYXJncyApCgkJCQk6IFdQX0NMSTo6cmVhZF92YWx1ZSggYXJyYXlfcG9wKCAka2V5X3BhdGggKSwgJGFzc29jX2FyZ3MgKTsKCQl9CgoJCS8qIE5lZWQgdG8gbWFrZSBhIGNvcHkgb2YgJGN1cnJlbnRfbWV0YV92YWx1ZSBoZXJlIGFzIGl0IGlzIG1vZGlmaWVkIGJ5IHJlZmVyZW5jZSAqLwoJCSRjdXJyZW50X21ldGFfdmFsdWUgPSBzYW5pdGl6ZV9tZXRhKCAkbWV0YV9rZXksICR0aGlzLT5nZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgdHJ1ZSApLCAkdGhpcy0+bWV0YV90eXBlICk7CgkJJG9sZF9tZXRhX3ZhbHVlICAgICA9ICRjdXJyZW50X21ldGFfdmFsdWU7CgkJaWYgKCBpc19vYmplY3QoICRjdXJyZW50X21ldGFfdmFsdWUgKSApIHsKCQkJJG9sZF9tZXRhX3ZhbHVlID0gY2xvbmUgJGN1cnJlbnRfbWV0YV92YWx1ZTsKCQl9CgoJCSR0cmF2ZXJzZXIgPSBuZXcgUmVjdXJzaXZlRGF0YVN0cnVjdHVyZVRyYXZlcnNlciggJGN1cnJlbnRfbWV0YV92YWx1ZSApOwoKCQl0cnkgewoJCQkkdHJhdmVyc2VyLT4kYWN0aW9uKCAka2V5X3BhdGgsICRwYXRjaF92YWx1ZSApOwoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggJGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQkkcGF0Y2hlZF9tZXRhX3ZhbHVlID0gc2FuaXRpemVfbWV0YSggJG1ldGFfa2V5LCAkdHJhdmVyc2VyLT52YWx1ZSgpLCAkdGhpcy0+bWV0YV90eXBlICk7CgoJCWlmICggJHBhdGNoZWRfbWV0YV92YWx1ZSA9PT0gJG9sZF9tZXRhX3ZhbHVlICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJWYWx1ZSBwYXNzZWQgZm9yIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nIGlzIHVuY2hhbmdlZC4iICk7CgkJfSBlbHNlIHsKCQkJJHNsYXNoZWQgPSB3cF9zbGFzaCggJHBhdGNoZWRfbWV0YV92YWx1ZSApOwoJCQkkc3VjY2VzcyA9ICR0aGlzLT51cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNsYXNoZWQgKTsKCgkJCWlmICggJHN1Y2Nlc3MgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJVcGRhdGVkIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gdXBkYXRlIGN1c3RvbSBmaWVsZCAneyRtZXRhX2tleX0nLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBhZGRfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gYm9vbCAgICR1bmlxdWUgICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBXaGV0aGVyIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbWV0YWRhdGEga2V5IHNob3VsZCBiZSB1bmlxdWUgZm9yIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuIElmIHRydWUsIGFuZCB0aGUgb2JqZWN0IGFscmVhZHkgaGFzIGEKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgbWV0YWRhdGEga2V5LCBubyBjaGFuZ2UKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBtYWRlLgoJICoKCSAqIEByZXR1cm4gaW50fGZhbHNlIFRoZSBtZXRhIElEIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBhZGRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgPSBmYWxzZSApIHsKCQlyZXR1cm4gYWRkX21ldGFkYXRhKCAkdGhpcy0+bWV0YV90eXBlLCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgdXBkYXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIG1peGVkICAkcHJldl92YWx1ZSBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCBvbmx5IHVwZGF0ZSBleGlzdGluZwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB1cGRhdGUgYWxsIGVudHJpZXMuCgkgKgoJICogQHJldHVybiBpbnR8Ym9vbCBNZXRhIElEIGlmIHRoZSBrZXkgZGlkbid0IGV4aXN0LCB0cnVlIG9uIHN1Y2Nlc3NmdWwKCSAqICAgICAgICAgICAgICAgICAgdXBkYXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSA9ICcnICkgewoJCXJldHVybiB1cGRhdGVfbWV0YWRhdGEoICR0aGlzLT5tZXRhX3R5cGUsICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZ2V0X21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICBPcHRpb25hbC4gTWV0YWRhdGEga2V5LiBJZiBub3Qgc3BlY2lmaWVkLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHJpZXZlIGFsbCBtZXRhZGF0YSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCgkgKiBAcGFyYW0gYm9vbCAgICRzaW5nbGUgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIElmIHRydWUsIHJldHVybiBvbmx5CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuIFRoaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiBtZXRhX2tleSBpcyBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQuCgkgKgoJICogQHJldHVybiBtaXhlZCBTaW5nbGUgbWV0YWRhdGEgdmFsdWUsIG9yIGFycmF5IG9mIHZhbHVlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ID0gJycsICRzaW5nbGUgPSBmYWxzZSApIHsKCQlyZXR1cm4gZ2V0X21ldGFkYXRhKCAkdGhpcy0+bWV0YV90eXBlLCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRzaW5nbGUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciBkZWxldGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgbWV0YWRhdGEgaXMgZm9yCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleQoJICogQHBhcmFtIG1peGVkICRtZXRhX3ZhbHVlICBPcHRpb25hbC4gTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vbi1zY2FsYXIuIElmIHNwZWNpZmllZCwgb25seSBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgZW50cmllcyB3aXRoIHRoaXMgdmFsdWUuIE90aGVyd2lzZSwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFsbCBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCBtZXRhX2tleS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFzcyBgbnVsbCwgYGZhbHNlYCwgb3IgYW4gZW1wdHkgc3RyaW5nIHRvIHNraXAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBjaGVjay4gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIGl0IGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBwb3NzaWJsZSB0byBwYXNzIGFuIGVtcHR5IHN0cmluZyB0byBkZWxldGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhvc2UgZW50cmllcyB3aXRoIGFuIGVtcHR5IHN0cmluZyBmb3IgYSB2YWx1ZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBvbiBzdWNjZXNzZnVsIGRlbGV0ZSwgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGRlbGV0ZV9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSA9ICcnICkgewoJCXJldHVybiBkZWxldGVfbWV0YWRhdGEoICR0aGlzLT5tZXRhX3R5cGUsICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsIGZhbHNlICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGZpZWxkcyBmb3IgdGhpcyBvYmplY3QncyBtZXRhCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9maWVsZHMoKSB7CgkJcmV0dXJuIFsKCQkJInskdGhpcy0+bWV0YV90eXBlfV9pZCIsCgkJCSdtZXRhX2tleScsCgkJCSdtZXRhX3ZhbHVlJywKCQldOwoJfQoKCS8qKgoJICogQ2hlY2sgdGhhdCB0aGUgb2JqZWN0IElEIGV4aXN0cwoJICoKCSAqIEBwYXJhbSBpbnQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29iamVjdF9pZCggJG9iamVjdF9pZCApIHsKCQkvLyBOZWVkcyB0byBiZSBzZXQgaW4gc3ViY2xhc3MKCQlyZXR1cm4gJG9iamVjdF9pZDsKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJX0NvbW1hbmQ7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQmFzZSBjbGFzcyBmb3IgV1AtQ0xJIGNvbW1hbmRzIHRoYXQgZGVhbCB3aXRoIHRlcm1zCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KYWJzdHJhY3QgY2xhc3MgQ29tbWFuZFdpdGhUZXJtcyBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIEB2YXIgc3RyaW5nICRvYmplY3RfdHlwZSBXb3JkUHJlc3MnIGV4cGVjdGVkIG5hbWUgZm9yIHRoZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCAkb2JqX3R5cGU7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyAkb2JqZWN0X2lkIFdvcmRQcmVzcycgb2JqZWN0IGlkLgoJICovCglwcm90ZWN0ZWQgJG9ial9pZDsKCgkvKioKCSAqIEB2YXIgYXJyYXkgJG9ial9maWVsZHMgRGVmYXVsdCBmaWVsZHMgdG8gZGlzcGxheSBmb3IgZWFjaCBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IFsKCQkndGVybV9pZCcsCgkJJ25hbWUnLAoJCSdzbHVnJywKCQkndGF4b25vbXknLAoJXTsKCgkvKioKCSAqIExpc3QgYWxsIHRlcm1zIGFzc29jaWF0ZWQgd2l0aCBhbiBvYmplY3QuCgkgKgoJICogPGlkPgoJICogOiBJRCBmb3IgdGhlIG9iamVjdC4KCSAqCgkgKiA8dGF4b25vbXk+Li4uCgkgKiA6IE9uZSBvciBtb3JlIHRheG9ub21pZXMgdG8gbGlzdC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHRlcm0uCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIHJvdyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqICAgLSBjb3VudAoJICogICAtIGlkcwoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHRlcm06CgkgKgoJICogKiB0ZXJtX2lkCgkgKiAqIG5hbWUKCSAqICogc2x1ZwoJICogKiB0YXhvbm9teQoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiB0ZXJtX3RheG9ub215X2lkCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIHRlcm1fZ3JvdXAKCSAqICogcGFyZW50CgkgKiAqIGNvdW50CgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdmb3JtYXQnID0+ICd0YWJsZScsCgkJXTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRvYmplY3RfaWQgICAgICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0YXhvbm9teV9uYW1lcyA9ICRhcmdzOwoJCSR0YXhvbm9teV9hcmdzICA9IFtdOwoKCQkkdGhpcy0+c2V0X29ial9pZCggJG9iamVjdF9pZCApOwoKCQlmb3JlYWNoICggJHRheG9ub215X25hbWVzIGFzICR0YXhvbm9teSApIHsKCQkJJHRoaXMtPnRheG9ub215X2V4aXN0cyggJHRheG9ub215ICk7CgkJfQoKCQlpZiAoICdpZHMnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCSR0YXhvbm9teV9hcmdzWydmaWVsZHMnXSA9ICdpZHMnOwoJCX0KCgkJJGl0ZW1zID0gd3BfZ2V0X29iamVjdF90ZXJtcyggJG9iamVjdF9pZCwgJHRheG9ub215X25hbWVzLCAkdGF4b25vbXlfYXJncyApOwoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGl0ZW1zICk7CgoJfQoKCgkvKioKCSAqIFJlbW92ZSBhIHRlcm0gZnJvbSBhbiBvYmplY3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBvYmplY3QuCgkgKgoJICogPHRheG9ub215PgoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGVybSdzIHRheG9ub215LgoJICoKCSAqIFs8dGVybT4uLi5dCgkgKiA6IFRoZSBuYW1lIG9mIHRoZSB0ZXJtIG9yIHRlcm1zIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGUgb2JqZWN0LgoJICoKCSAqIFstLWJ5PTxmaWVsZD5dCgkgKiA6IEV4cGxpY2l0bHkgaGFuZGxlIHRoZSB0ZXJtIHZhbHVlIGFzIGEgc2x1ZyBvciBpZC4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBzbHVnCgkgKiAgIC0gaWQKCSAqIC0tLQoJICoKCSAqIFstLWFsbF0KCSAqIDogUmVtb3ZlIGFsbCB0ZXJtcyBmcm9tIHRoZSBvYmplY3QuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkb2JqZWN0X2lkID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRheG9ub215ICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0ZXJtcyAgICAgPSAkYXJnczsKCgkJJHRoaXMtPnNldF9vYmpfaWQoICRvYmplY3RfaWQgKTsKCgkJJHRoaXMtPnRheG9ub215X2V4aXN0cyggJHRheG9ub215ICk7CgoJCSRmaWVsZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApOwoJCWlmICggJGZpZWxkICkgewoJCQkkdGVybXMgPSAkdGhpcy0+cHJlcGFyZV90ZXJtcyggJGZpZWxkLCAkdGVybXMsICR0YXhvbm9teSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgoJCQkvLyBObyBuZWVkIHRvIHNwZWNpZnkgdGVybXMgd2hpbGUgcmVtb3ZpbmcgYWxsIHRlcm1zLgoJCQlpZiAoICR0ZXJtcyApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdObyBuZWVkIHRvIHNwZWNpZnkgdGVybXMgd2hpbGUgcmVtb3ZpbmcgYWxsIHRlcm1zLicgKTsKCQkJfQoKCQkJLy8gUmVtb3ZlIGFsbCBzZXQgY2F0ZWdvcmllcyBmcm9tIHBvc3QuCgkJCSRyZXN1bHQgPSB3cF9kZWxldGVfb2JqZWN0X3Rlcm1fcmVsYXRpb25zaGlwcyggJG9iamVjdF9pZCwgJHRheG9ub215ICk7CgoJCQkkbWVzc2FnZSA9ICdSZW1vdmVkIGFsbCB0ZXJtcy4nOwoJCQlpZiAoICdjYXRlZ29yeScgPT09ICR0YXhvbm9teSApIHsKCgkJCQkvLyBTZXQgZGVmYXVsdCBjYXRlZ29yeSB0byBwb3N0LgoJCQkJJGRlZmF1bHRfY2F0ZWdvcnkgPSAoaW50KSBnZXRfb3B0aW9uKCAnZGVmYXVsdF9jYXRlZ29yeScgKTsKCQkJCSRkZWZhdWx0X2NhdGVnb3J5ID0gKCAhIGVtcHR5KCAkZGVmYXVsdF9jYXRlZ29yeSApICkgPyAkZGVmYXVsdF9jYXRlZ29yeSA6IDE7CgkJCQkkZGVmYXVsdF9jYXRlZ29yeSA9IHdwX3NldF9vYmplY3RfdGVybXMoICRvYmplY3RfaWQsIFsgJGRlZmF1bHRfY2F0ZWdvcnkgXSwgJHRheG9ub215LCB0cnVlICk7CgoJCQkJaWYgKCBpc193cF9lcnJvciggJGRlZmF1bHRfY2F0ZWdvcnkgKSApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIHNldCBkZWZhdWx0IHRlcm0uJyApOwoJCQkJfQoKCQkJCSRtZXNzYWdlID0gJ1JlbW92ZWQgYWxsIHRlcm1zIGFuZCBzZXQgZGVmYXVsdCB0ZXJtLic7CgkJCX0KCgkJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdGYWlsZWQgdG8gcmVtb3ZlIGFsbCB0ZXJtcy4nICk7CgkJCX0KCgkJCVdQX0NMSTo6c3VjY2VzcyggJG1lc3NhZ2UgKTsKCgkJCXJldHVybjsKCQl9CgoJCS8vIEFib3J0IGlmIG5vIHRlcm1zIGFyZSBzcGVjaWZpZWQuCgkJaWYgKCAhICR0ZXJtcyApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IG9uZSBvciBtb3JlIHRlcm1zLCBvciB1c2UgLS1hbGwuJyApOwoJCX0KCgkJLy8gUmVtb3ZlIHRlcm0gZnJvbSBwb3N0LgoJCSRyZXN1bHQgPSB3cF9yZW1vdmVfb2JqZWN0X3Rlcm1zKCAkb2JqZWN0X2lkLCAkdGVybXMsICR0YXhvbm9teSApOwoKCQkkbGFiZWwgPSBjb3VudCggJHRlcm1zICkgPiAxID8gJ3Rlcm1zJyA6ICd0ZXJtJzsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiRmFpbGVkIHRvIHJlbW92ZSB7JGxhYmVsfS4iICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJSZW1vdmVkIHskbGFiZWx9LiIgKTsKCX0KCgkvKioKCSAqIEFkZCBhIHRlcm0gdG8gYW4gb2JqZWN0LgoJICoKCSAqIEFwcGVuZCB0aGUgdGVybSB0byB0aGUgZXhpc3Rpbmcgc2V0IG9mIHRlcm1zIG9uIHRoZSBvYmplY3QuCgkgKgoJICogPGlkPgoJICogOiBUaGUgSUQgb2YgdGhlIG9iamVjdC4KCSAqCgkgKiA8dGF4b25vbXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSB0YXhvbm9teSB0eXBlIHRvIGJlIGFkZGVkLgoJICoKCSAqIDx0ZXJtPi4uLgoJICogOiBUaGUgc2x1ZyBvZiB0aGUgdGVybSBvciB0ZXJtcyB0byBiZSBhZGRlZC4KCSAqCgkgKiBbLS1ieT08ZmllbGQ+XQoJICogOiBFeHBsaWNpdGx5IGhhbmRsZSB0aGUgdGVybSB2YWx1ZSBhcyBhIHNsdWcgb3IgaWQuCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0gc2x1ZwoJICogICAtIGlkCgkgKiAtLS0KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRvYmplY3RfaWQgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkdGF4b25vbXkgID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRlcm1zICAgICA9ICRhcmdzOwoKCQkkdGhpcy0+c2V0X29ial9pZCggJG9iamVjdF9pZCApOwoKCQkkdGhpcy0+dGF4b25vbXlfZXhpc3RzKCAkdGF4b25vbXkgKTsKCgkJJGZpZWxkID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYnknICk7CgkJaWYgKCAkZmllbGQgKSB7CgkJCSR0ZXJtcyA9ICR0aGlzLT5wcmVwYXJlX3Rlcm1zKCAkZmllbGQsICR0ZXJtcywgJHRheG9ub215ICk7CgkJfQoJCSRyZXN1bHQgPSB3cF9zZXRfb2JqZWN0X3Rlcm1zKCAkb2JqZWN0X2lkLCAkdGVybXMsICR0YXhvbm9teSwgdHJ1ZSApOwoKCQkkbGFiZWwgPSBjb3VudCggJHRlcm1zICkgPiAxID8gJ3Rlcm1zJyA6ICd0ZXJtJzsKCQlpZiAoICEgaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQWRkZWQgeyRsYWJlbH0uIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gYWRkIHskbGFiZWx9LiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBTZXQgb2JqZWN0IHRlcm1zLgoJICoKCSAqIFJlcGxhY2VzIGV4aXN0aW5nIHRlcm1zIG9uIHRoZSBvYmplY3QuCgkgKgoJICogPGlkPgoJICogOiBUaGUgSUQgb2YgdGhlIG9iamVjdC4KCSAqCgkgKiA8dGF4b25vbXk+CgkgKiA6IFRoZSBuYW1lIG9mIHRoZSB0YXhvbm9teSB0eXBlIHRvIGJlIHVwZGF0ZWQuCgkgKgoJICogPHRlcm0+Li4uCgkgKiA6IFRoZSBzbHVnIG9mIHRoZSB0ZXJtIG9yIHRlcm1zIHRvIGJlIHVwZGF0ZWQuCgkgKgoJICogWy0tYnk9PGZpZWxkPl0KCSAqIDogRXhwbGljaXRseSBoYW5kbGUgdGhlIHRlcm0gdmFsdWUgYXMgYSBzbHVnIG9yIGlkLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIHNsdWcKCSAqICAgLSBpZAoJICogLS0tCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkb2JqZWN0X2lkID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRheG9ub215ICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSR0ZXJtcyAgICAgPSAkYXJnczsKCgkJJHRoaXMtPnNldF9vYmpfaWQoICRvYmplY3RfaWQgKTsKCgkJJHRoaXMtPnRheG9ub215X2V4aXN0cyggJHRheG9ub215ICk7CgoJCSRmaWVsZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2J5JyApOwoJCWlmICggJGZpZWxkICkgewoJCQkkdGVybXMgPSAkdGhpcy0+cHJlcGFyZV90ZXJtcyggJGZpZWxkLCAkdGVybXMsICR0YXhvbm9teSApOwoJCX0KCQkkcmVzdWx0ID0gd3Bfc2V0X29iamVjdF90ZXJtcyggJG9iamVjdF9pZCwgJHRlcm1zLCAkdGF4b25vbXksIGZhbHNlICk7CgoJCSRsYWJlbCA9IGNvdW50KCAkdGVybXMgKSA+IDEgPyAndGVybXMnIDogJ3Rlcm0nOwoJCWlmICggISBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJTZXQgeyRsYWJlbH0uIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gc2V0IHskbGFiZWx9LiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiB0YXhvbm9teSBleGlzdHMKCSAqCgkgKiBAcGFyYW0gJHRheG9ub215CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB0YXhvbm9teV9leGlzdHMoICR0YXhvbm9teSApIHsKCgkJJHRheG9ub215X25hbWVzID0gZ2V0X29iamVjdF90YXhvbm9taWVzKCAkdGhpcy0+Z2V0X29iamVjdF90eXBlKCkgKTsKCgkJaWYgKCAhIGluX2FycmF5KCAkdGF4b25vbXksICR0YXhvbm9teV9uYW1lcywgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB0YXhvbm9teSB7JHRheG9ub215fS4iICk7CgkJfQoJfQoKCS8qKgoJICogUHJlcGFyZSB0ZXJtcyBpZiBgLS1ieT08ZmllbGQ+YCBmbGFnIGlzIHVzZWQKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHRlcm1zCgkgKiBAcGFyYW0gc3RyaW5nICRmaWVsZAoJICogQHBhcmFtIHN0cmluZyAkdGF4b25vbXkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHByZXBhcmVfdGVybXMoICRmaWVsZCwgJHRlcm1zLCAkdGF4b25vbXkgKSB7CgkJaWYgKCAnaWQnID09PSAkZmllbGQgKSB7CgkJCSRuZXdfdGVybXMgPSBbXTsKCQkJZm9yZWFjaCAoICR0ZXJtcyBhcyAkdGVybV9pZCApIHsKCQkJCSR0ZXJtID0gZ2V0X3Rlcm1fYnkoICd0ZXJtX2lkJywgJHRlcm1faWQsICR0YXhvbm9teSApOwoJCQkJaWYgKCAkdGVybSApIHsKCQkJCQkkbmV3X3Rlcm1zW10gPSAkdGVybS0+c2x1ZzsKCQkJCX0KCQkJfQoJCQkkdGVybXMgPSAkbmV3X3Rlcm1zOwoJCX0KCQlyZXR1cm4gJHRlcm1zOwoJfQoKCS8qKgoJICogU2V0IG9ial9pZCBDbGFzcyB2YXJpYWJsZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG9ial9pZAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0X29ial9pZCggJG9ial9pZCApIHsKCQkkdGhpcy0+b2JqX2lkID0gJG9ial9pZDsKCX0KCgkvKioKCSAqIEdldCBvYmpfaWQgQ2xhc3MgdmFyaWFibGUKCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X29ial9pZCgpIHsKCQlyZXR1cm4gJHRoaXMtPm9ial9pZDsKCX0KCgoJLyoqCgkgKiBHZXQgb2JqX3R5cGUgQ2xhc3MgdmFyaWFibGUKCSAqCgkgKiBAcmV0dXJuIHN0cmluZyAkb2JqX3R5cGUKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9vYmplY3RfdHlwZSgpIHsKCQlyZXR1cm4gJHRoaXMtPm9ial90eXBlOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICoKCSAqIEByZXR1cm4gV1BfQ0xJXEZvcm1hdHRlcgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPm9ial9maWVsZHMsICR0aGlzLT5vYmpfdHlwZSApOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElfQ29tbWFuZDsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0Vycm9yOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcyB0aGF0IGRlYWwgd2l0aCBkYXRhYmFzZSBvYmplY3RzLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmFic3RyYWN0IGNsYXNzIENvbW1hbmRXaXRoREJPYmplY3QgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBAdmFyIHN0cmluZyAkb2JqZWN0X3R5cGUgV29yZFByZXNzJyBleHBlY3RlZCBuYW1lIGZvciB0aGUgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgJG9ial90eXBlOwoKCS8qKgoJICogQHZhciBzdHJpbmcgJG9ial9pZF9rZXkgS2V5IHJlcHJlc2VudGluZyBvYmplY3QncyBQSyBmaWVsZCBpbiBkYi4KCSAqLwoJcHJvdGVjdGVkICRvYmpfaWRfa2V5ID0gJ0lEJzsKCgkvKioKCSAqIEB2YXIgYXJyYXkgJG9ial9maWVsZHMgRGVmYXVsdCBmaWVsZHMgdG8gZGlzcGxheSBmb3IgZWFjaCBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCAkb2JqX2ZpZWxkczsKCgkvKioKCSAqIENyZWF0ZSBhIGdpdmVuIGRhdGFiYXNlIG9iamVjdC4KCSAqIEV4aXRzIHdpdGggc3RhdHVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBBcmd1bWVudHMgcGFzc2VkIHRvIGNvbW1hbmQuIEdlbmVyYWxseSB1bnVzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZCB0byBiZSBwYXNzZWQgdG8gY2FsbGJhY2suCgkgKiBAcGFyYW0gc3RyaW5nICRjYWxsYmFjayBGdW5jdGlvbiB1c2VkIHRvIGNyZWF0ZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfY3JlYXRlKCAkYXJncywgJGFzc29jX2FyZ3MsICRjYWxsYmFjayApIHsKCQl1bnNldCggJGFzc29jX2FyZ3NbICR0aGlzLT5vYmpfaWRfa2V5IF0gKTsKCgkJJG9ial9pZCA9ICRjYWxsYmFjayggJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJG9ial9pZCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkb2JqX2lkICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKSApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkb2JqX2lkICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiQ3JlYXRlZCB7JHRoaXMtPm9ial90eXBlfSB7JG9ial9pZH0uIiApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZSBhIGdpdmVuIGRhdGFiYXNlIG9iamVjdC4KCSAqIEV4aXRzIHdpdGggc3RhdHVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBDb2xsZWN0aW9uIG9mIG9uZSBvciBtb3JlIG9iamVjdCBpZHMgdG8gdXBkYXRlLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEZpZWxkcyA9PiB2YWx1ZXMgdG8gdXBkYXRlIG9uIGVhY2ggb2JqZWN0LgoJICogQHBhcmFtIHN0cmluZyAkY2FsbGJhY2sgRnVuY3Rpb24gdXNlZCB0byB1cGRhdGUgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gX3VwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzLCAkY2FsbGJhY2sgKSB7CgkJJHN0YXR1cyA9IDA7CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdOZWVkIHNvbWUgZmllbGRzIHRvIHVwZGF0ZS4nICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RlZmVyLXRlcm0tY291bnRpbmcnICkgKSB7CgkJCXdwX2RlZmVyX3Rlcm1fY291bnRpbmcoIHRydWUgKTsKCQl9CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkb2JqX2lkICkgewoJCQkkcGFyYW1zID0gYXJyYXlfbWVyZ2UoICRhc3NvY19hcmdzLCBbICR0aGlzLT5vYmpfaWRfa2V5ID0+ICRvYmpfaWQgXSApOwoKCQkJJHN0YXR1cyA9ICR0aGlzLT5zdWNjZXNzX29yX2ZhaWx1cmUoCgkJCQkkdGhpcy0+d3BfZXJyb3JfdG9fcmVzcCgKCQkJCQkkY2FsbGJhY2soICRwYXJhbXMgKSwKCQkJCQkiVXBkYXRlZCB7JHRoaXMtPm9ial90eXBlfSB7JG9ial9pZH0uIgoJCQkJKQoJCQkpOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZWZlci10ZXJtLWNvdW50aW5nJyApICkgewoJCQl3cF9kZWZlcl90ZXJtX2NvdW50aW5nKCBmYWxzZSApOwoJCX0KCgkJZXhpdCggJHN0YXR1cyApOwoJfQoKCS8qKgoJICogVHJhbnNmb3JtcyBhcmd1bWVudHMgd2l0aCAnX18nIGZyb20gQ1NWIGludG8gZXhwZWN0ZWQgYXJyYXlzCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcHJvY2Vzc19jc3ZfYXJndW1lbnRzX3RvX2FycmF5cyggJGFzc29jX2FyZ3MgKSB7CgkJZm9yZWFjaCAoICRhc3NvY19hcmdzIGFzICRrID0+ICR2ICkgewoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICRrLCAnX18nICkgKSB7CgkJCQkkYXNzb2NfYXJnc1sgJGsgXSA9IGV4cGxvZGUoICcsJywgJHYgKTsKCQkJfQoJCX0KCQlyZXR1cm4gJGFzc29jX2FyZ3M7Cgl9CgoJLyoqCgkgKiBEZWxldGUgYSBnaXZlbiBkYXRhYmFzZSBvYmplY3QuCgkgKiBFeGl0cyB3aXRoIHN0YXR1cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgQ29sbGVjdGlvbiBvZiBvbmUgb3IgbW9yZSBvYmplY3QgaWRzIHRvIGRlbGV0ZS4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBbnkgYXJndW1lbnRzIG5lZWRlZCBmb3IgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLgoJICogQHBhcmFtIGNhbGxhYmxlICRjYWxsYmFjayBGdW5jdGlvbiB1c2VkIHRvIGRlbGV0ZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MsICRjYWxsYmFjayApIHsKCQkkc3RhdHVzID0gMDsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZWZlci10ZXJtLWNvdW50aW5nJyApICkgewoJCQl3cF9kZWZlcl90ZXJtX2NvdW50aW5nKCB0cnVlICk7CgkJfQoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJG9ial9pZCApIHsKCQkJJHJlc3VsdCA9ICRjYWxsYmFjayggJG9ial9pZCwgJGFzc29jX2FyZ3MgKTsKCQkJJHN0YXR1cyA9ICR0aGlzLT5zdWNjZXNzX29yX2ZhaWx1cmUoICRyZXN1bHQgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVmZXItdGVybS1jb3VudGluZycgKSApIHsKCQkJd3BfZGVmZXJfdGVybV9jb3VudGluZyggZmFsc2UgKTsKCQl9CgoJCWV4aXQoICRzdGF0dXMgKTsKCX0KCgkvKioKCSAqIEZvcm1hdCBjYWxsYmFjayByZXNwb25zZSB0byBjb25zaXN0ZW50IGZvcm1hdC4KCSAqCgkgKiBAcGFyYW0gV1BfRXJyb3J8dHJ1ZSAkcmVzcG9uc2UgUmVzcG9uc2UgZnJvbSBDUlVEIGNhbGxiYWNrLgoJICogQHBhcmFtIHN0cmluZyAgICAgICAgJHN1Y2Nlc3NfbXNnCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB3cF9lcnJvcl90b19yZXNwKCAkcmVzcG9uc2UsICRzdWNjZXNzX21zZyApIHsKCQlyZXR1cm4gaXNfd3BfZXJyb3IoICRyZXNwb25zZSApCgkJCT8gWyAnZXJyb3InLCAkcmVzcG9uc2UtPmdldF9lcnJvcl9tZXNzYWdlKCkgXQoJCQk6IFsgJ3N1Y2Nlc3MnLCAkc3VjY2Vzc19tc2cgXTsKCX0KCgkvKioKCSAqIERpc3BsYXkgc3VjY2VzcyBvciB3YXJuaW5nIGJhc2VkIG9uIHJlc3BvbnNlOyByZXR1cm4gcHJvcGVyIGV4aXQgY29kZS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJHJlc3BvbnNlIEZvcm1hdHRlZCBmcm9tIGEgQ1JVRCBjYWxsYmFjay4KCSAqIEByZXR1cm4gaW50ICRzdGF0dXMKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHN1Y2Nlc3Nfb3JfZmFpbHVyZSggJHJlc3BvbnNlICkgewoJCWxpc3QoICR0eXBlLCAkbXNnICkgPSAkcmVzcG9uc2U7CgoJCWlmICggJ3N1Y2Nlc3MnID09PSAkdHlwZSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAkbXNnICk7CgkJCSRzdGF0dXMgPSAwOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6d2FybmluZyggJG1zZyApOwoJCQkkc3RhdHVzID0gMTsKCQl9CgoJCXJldHVybiAkc3RhdHVzOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICogQHJldHVybiBGb3JtYXR0ZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJaWYgKCBpc19zdHJpbmcoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkJJGZpZWxkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJCX0gZWxzZSB7CgkJCQkkZmllbGRzID0gJGFzc29jX2FyZ3NbJ2ZpZWxkcyddOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGZpZWxkcyA9ICR0aGlzLT5vYmpfZmllbGRzOwoJCX0KCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICRmaWVsZHMsICR0aGlzLT5vYmpfdHlwZSApOwoJfQoKCS8qKgoJICogR2l2ZW4gYSBjYWxsYmFjaywgZGlzcGxheSB0aGUgVVJMIGZvciBvbmUgb3IgbW9yZSBvYmplY3RzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyBPbmUgb3IgbW9yZSBvYmplY3QgcmVmZXJlbmNlcy4KCSAqIEBwYXJhbSBzdHJpbmcgJGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGdldCBVUkwgZm9yIHRoZSBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBfdXJsKCAkYXJncywgJGNhbGxiYWNrICkgewoJCWZvcmVhY2ggKCAkYXJncyBhcyAkb2JqX2lkICkgewoJCQkkb2JqZWN0ID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJG9ial9pZCApOwoJCQlXUF9DTEk6OmxpbmUoICRjYWxsYmFjayggJG9iamVjdC0+eyR0aGlzLT5vYmpfaWRfa2V5fSApICk7CgkJfQoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXENvbW1hbmRXaXRoTWV0YTsKdXNlIFdQX0NMSVxGZXRjaGVyc1xTaXRlIGFzIFNpdGVGZXRjaGVyOwoKLyoqCiAqIEFkZHMsIHVwZGF0ZXMsIGRlbGV0ZXMsIGFuZCBsaXN0cyBzaXRlIGN1c3RvbSBmaWVsZHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCBzaXRlIG1ldGEKICogICAgICQgd3Agc2l0ZSBtZXRhIHNldCAxMjMgYmlvICJNYXJ5IGlzIGEgV29yZFByZXNzIGRldmVsb3Blci4iCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnYmlvJy4KICoKICogICAgICMgR2V0IHNpdGUgbWV0YQogKiAgICAgJCB3cCBzaXRlIG1ldGEgZ2V0IDEyMyBiaW8KICogICAgIE1hcnkgaXMgYSBXb3JkUHJlc3MgZGV2ZWxvcGVyLgogKgogKiAgICAgIyBVcGRhdGUgc2l0ZSBtZXRhCiAqICAgICAkIHdwIHNpdGUgbWV0YSB1cGRhdGUgMTIzIGJpbyAiTWFyeSBpcyBhbiBhd2Vzb21lIFdvcmRQcmVzcyBkZXZlbG9wZXIuIgogKiAgICAgU3VjY2VzczogVXBkYXRlZCBjdXN0b20gZmllbGQgJ2JpbycuCiAqCiAqICAgICAjIERlbGV0ZSBzaXRlIG1ldGEKICogICAgICQgd3Agc2l0ZSBtZXRhIGRlbGV0ZSAxMjMgYmlvCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGN1c3RvbSBmaWVsZC4KICovCmNsYXNzIFNpdGVfTWV0YV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhNZXRhIHsKCXByb3RlY3RlZCAkbWV0YV90eXBlID0gJ2Jsb2cnOwoKCS8qKgoJICogQ2hlY2sgdGhhdCB0aGUgc2l0ZSBJRCBleGlzdHMKCSAqCgkgKiBAcGFyYW0gaW50CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKSB7CgkJJGZldGNoZXIgPSBuZXcgU2l0ZUZldGNoZXIoKTsKCQkkc2l0ZSAgICA9ICRmZXRjaGVyLT5nZXRfY2hlY2soICRvYmplY3RfaWQgKTsKCQlyZXR1cm4gJHNpdGUtPmJsb2dfaWQ7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgYWRkX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIGJvb2wgICAkdW5pcXVlICAgICBPcHRpb25hbCwgZGVmYXVsdCBpcyBmYWxzZS4gV2hldGhlciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSBzaG91bGQgYmUgdW5pcXVlIGZvciB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LiBJZiB0cnVlLCBhbmQgdGhlIG9iamVjdCBhbHJlYWR5IGhhcyBhCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGFkYXRhIGtleSwgbm8gY2hhbmdlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgbWFkZS4KCSAqCgkgKiBAcmV0dXJuIGludHxmYWxzZSBUaGUgbWV0YSBJRCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYWRkX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGFkZF9zaXRlX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICR1bmlxdWUgKTsKCX0KCgkvKioKCSAqIFdyYXBwZXIgbWV0aG9kIGZvciB1cGRhdGVfbWV0YWRhdGEgdGhhdCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWIgY2xhc3Nlcy4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRvYmplY3RfaWQgIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5IHRvIHVzZS4KCSAqIEBwYXJhbSBtaXhlZCAgJG1ldGFfdmFsdWUgTWV0YWRhdGEgdmFsdWUuIE11c3QgYmUgc2VyaWFsaXphYmxlIGlmCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1zY2FsYXIuCgkgKiBAcGFyYW0gbWl4ZWQgICRwcmV2X3ZhbHVlIE9wdGlvbmFsLiBJZiBzcGVjaWZpZWQsIG9ubHkgdXBkYXRlIGV4aXN0aW5nCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHVwZGF0ZSBhbGwgZW50cmllcy4KCSAqCgkgKiBAcmV0dXJuIGludHxib29sIE1ldGEgSUQgaWYgdGhlIGtleSBkaWRuJ3QgZXhpc3QsIHRydWUgb24gc3VjY2Vzc2Z1bAoJICogICAgICAgICAgICAgICAgICB1cGRhdGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1cGRhdGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIHVwZGF0ZV9zaXRlX21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUsICRwcmV2X3ZhbHVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZ2V0X21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkIElEIG9mIHRoZSBvYmplY3QgdGhlIG1ldGFkYXRhIGlzIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICBPcHRpb25hbC4gTWV0YWRhdGEga2V5LiBJZiBub3Qgc3BlY2lmaWVkLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHJpZXZlIGFsbCBtZXRhZGF0YSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCgkgKiBAcGFyYW0gYm9vbCAgICRzaW5nbGUgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIElmIHRydWUsIHJldHVybiBvbmx5CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuIFRoaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiBtZXRhX2tleSBpcyBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQuCgkgKgoJICogQHJldHVybiBtaXhlZCBTaW5nbGUgbWV0YWRhdGEgdmFsdWUsIG9yIGFycmF5IG9mIHZhbHVlcy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5ID0gJycsICRzaW5nbGUgPSBmYWxzZSApIHsKCQlyZXR1cm4gZ2V0X3NpdGVfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkc2luZ2xlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgZGVsZXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IG1ldGFkYXRhIGlzIGZvcgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkKCSAqIEBwYXJhbSBtaXhlZCAkbWV0YV92YWx1ZSAgT3B0aW9uYWwuIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub24tc2NhbGFyLiBJZiBzcGVjaWZpZWQsIG9ubHkgZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIGVudHJpZXMgd2l0aCB0aGlzIHZhbHVlLiBPdGhlcndpc2UsCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhbGwgZW50cmllcyB3aXRoIHRoZSBzcGVjaWZpZWQgbWV0YV9rZXkuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3MgYG51bGwsIGBmYWxzZWAsIG9yIGFuIGVtcHR5IHN0cmluZyB0byBza2lwCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgY2hlY2suIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBpdCBpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgcG9zc2libGUgdG8gcGFzcyBhbiBlbXB0eSBzdHJpbmcgdG8gZGVsZXRlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRob3NlIGVudHJpZXMgd2l0aCBhbiBlbXB0eSBzdHJpbmcgZm9yIGEgdmFsdWUuCgkgKgoJICogQHJldHVybiBib29sIFRydWUgb24gc3VjY2Vzc2Z1bCBkZWxldGUsIGZhbHNlIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBkZWxldGVfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgPSAnJyApIHsKCQlyZXR1cm4gZGVsZXRlX3NpdGVfbWV0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSApOwoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aE1ldGE7CgovKioKICogR2V0cywgYWRkcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIGxpc3RzIG5ldHdvcmsgY3VzdG9tIGZpZWxkcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgR2V0IGEgbGlzdCBvZiBzdXBlci1hZG1pbnMKICogICAgICQgd3AgbmV0d29yayBtZXRhIGdldCAxIHNpdGVfYWRtaW5zCiAqICAgICBhcnJheSAoCiAqICAgICAgIDAgPT4gJ3N1cGVydmlzb3InLAogKiAgICAgKQogKi8KY2xhc3MgTmV0d29ya19NZXRhX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aE1ldGEgewoJcHJvdGVjdGVkICRtZXRhX3R5cGUgPSAnc2l0ZSc7Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhUZXJtczsKCi8qKgogKiBBZGRzLCB1cGRhdGVzLCByZW1vdmVzLCBhbmQgbGlzdHMgdXNlciB0ZXJtcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHVzZXIgdGVybXMKICogICAgICQgd3AgdXNlciB0ZXJtIHNldCAxMjMgdGVzdCBjYXRlZ29yeQogKiAgICAgU3VjY2VzczogU2V0IHRlcm1zLgogKi8KY2xhc3MgVXNlcl9UZXJtX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aFRlcm1zIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAndXNlcic7Cn0KPD9waHAKCnVzZSBXUF9DTElcQ29tbWFuZFdpdGhNZXRhOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFBvc3QgYXMgUG9zdEZldGNoZXI7CgovKioKICogQWRkcywgdXBkYXRlcywgZGVsZXRlcywgYW5kIGxpc3RzIHBvc3QgY3VzdG9tIGZpZWxkcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHBvc3QgbWV0YQogKiAgICAgJCB3cCBwb3N0IG1ldGEgc2V0IDEyMyBfd3BfcGFnZV90ZW1wbGF0ZSBhYm91dC5waHAKICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgY3VzdG9tIGZpZWxkICdfd3BfcGFnZV90ZW1wbGF0ZScuCiAqCiAqICAgICAjIEdldCBwb3N0IG1ldGEKICogICAgICQgd3AgcG9zdCBtZXRhIGdldCAxMjMgX3dwX3BhZ2VfdGVtcGxhdGUKICogICAgIGFib3V0LnBocAogKgogKiAgICAgIyBVcGRhdGUgcG9zdCBtZXRhCiAqICAgICAkIHdwIHBvc3QgbWV0YSB1cGRhdGUgMTIzIF93cF9wYWdlX3RlbXBsYXRlIGNvbnRhY3QucGhwCiAqICAgICBTdWNjZXNzOiBVcGRhdGVkIGN1c3RvbSBmaWVsZCAnX3dwX3BhZ2VfdGVtcGxhdGUnLgogKgogKiAgICAgIyBEZWxldGUgcG9zdCBtZXRhCiAqICAgICAkIHdwIHBvc3QgbWV0YSBkZWxldGUgMTIzIF93cF9wYWdlX3RlbXBsYXRlCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIGN1c3RvbSBmaWVsZC4KICovCmNsYXNzIFBvc3RfTWV0YV9Db21tYW5kIGV4dGVuZHMgQ29tbWFuZFdpdGhNZXRhIHsKCXByb3RlY3RlZCAkbWV0YV90eXBlID0gJ3Bvc3QnOwoKCS8qKgoJICogQ2hlY2sgdGhhdCB0aGUgcG9zdCBJRCBleGlzdHMKCSAqCgkgKiBAcGFyYW0gaW50CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja19vYmplY3RfaWQoICRvYmplY3RfaWQgKSB7CgkJJGZldGNoZXIgPSBuZXcgUG9zdEZldGNoZXIoKTsKCQkkcG9zdCAgICA9ICRmZXRjaGVyLT5nZXRfY2hlY2soICRvYmplY3RfaWQgKTsKCQlyZXR1cm4gJHBvc3QtPklEOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGFkZF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCB0aGUgbWV0YWRhdGEgaXMgZm9yLgoJICogQHBhcmFtIHN0cmluZyAkbWV0YV9rZXkgICBNZXRhZGF0YSBrZXkgdG8gdXNlLgoJICogQHBhcmFtIG1peGVkICAkbWV0YV92YWx1ZSBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUgaWYKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLXNjYWxhci4KCSAqIEBwYXJhbSBib29sICAgJHVuaXF1ZSAgICAgT3B0aW9uYWwsIGRlZmF1bHQgaXMgZmFsc2UuIFdoZXRoZXIgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4gSWYgdHJ1ZSwgYW5kIHRoZSBvYmplY3QgYWxyZWFkeSBoYXMgYQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRhZGF0YSBrZXksIG5vIGNoYW5nZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIG1hZGUuCgkgKgoJICogQHJldHVybiBpbnR8ZmFsc2UgVGhlIG1ldGEgSUQgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZF9tZXRhZGF0YSggJG9iamVjdF9pZCwgJG1ldGFfa2V5LCAkbWV0YV92YWx1ZSwgJHVuaXF1ZSA9IGZhbHNlICkgewoJCXJldHVybiBhZGRfcG9zdF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkdW5pcXVlICk7Cgl9CgoJLyoqCgkgKiBXcmFwcGVyIG1ldGhvZCBmb3IgdXBkYXRlX21ldGFkYXRhIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gaW4gc3ViIGNsYXNzZXMuCgkgKgoJICogQHBhcmFtIGludCAgICAkb2JqZWN0X2lkICBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgIE1ldGFkYXRhIGtleSB0byB1c2UuCgkgKiBAcGFyYW0gbWl4ZWQgICRtZXRhX3ZhbHVlIE1ldGFkYXRhIHZhbHVlLiBNdXN0IGJlIHNlcmlhbGl6YWJsZSBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBub24tc2NhbGFyLgoJICogQHBhcmFtIG1peGVkICAkcHJldl92YWx1ZSBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCBvbmx5IHVwZGF0ZSBleGlzdGluZwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB1cGRhdGUgYWxsIGVudHJpZXMuCgkgKgoJICogQHJldHVybiBpbnR8Ym9vbCBNZXRhIElEIGlmIHRoZSBrZXkgZGlkbid0IGV4aXN0LCB0cnVlIG9uIHN1Y2Nlc3NmdWwKCSAqICAgICAgICAgICAgICAgICAgdXBkYXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSA9ICcnICkgewoJCXJldHVybiB1cGRhdGVfcG9zdF9tZXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlLCAkcHJldl92YWx1ZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGdldF9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCBJRCBvZiB0aGUgb2JqZWN0IHRoZSBtZXRhZGF0YSBpcyBmb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXRhX2tleSAgT3B0aW9uYWwuIE1ldGFkYXRhIGtleS4gSWYgbm90IHNwZWNpZmllZCwKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZSBhbGwgbWV0YWRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgoJICogQHBhcmFtIGJvb2wgICAkc2luZ2xlICAgIE9wdGlvbmFsLCBkZWZhdWx0IGlzIGZhbHNlLiBJZiB0cnVlLCByZXR1cm4gb25seQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LiBUaGlzCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QgaWYgbWV0YV9rZXkgaXMgbm90CgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQgU2luZ2xlIG1ldGFkYXRhIHZhbHVlLCBvciBhcnJheSBvZiB2YWx1ZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfbWV0YWRhdGEoICRvYmplY3RfaWQsICRtZXRhX2tleSA9ICcnLCAkc2luZ2xlID0gZmFsc2UgKSB7CgkJcmV0dXJuIGdldF9wb3N0X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJHNpbmdsZSApOwoJfQoKCS8qKgoJICogV3JhcHBlciBtZXRob2QgZm9yIGRlbGV0ZV9tZXRhZGF0YSB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGluIHN1YiBjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJG9iamVjdF9pZCAgSUQgb2YgdGhlIG9iamVjdCBtZXRhZGF0YSBpcyBmb3IKCSAqIEBwYXJhbSBzdHJpbmcgJG1ldGFfa2V5ICAgTWV0YWRhdGEga2V5CgkgKiBAcGFyYW0gbWl4ZWQgJG1ldGFfdmFsdWUgIE9wdGlvbmFsLiBNZXRhZGF0YSB2YWx1ZS4gTXVzdCBiZSBzZXJpYWxpemFibGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm9uLXNjYWxhci4gSWYgc3BlY2lmaWVkLCBvbmx5IGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSBlbnRyaWVzIHdpdGggdGhpcyB2YWx1ZS4gT3RoZXJ3aXNlLAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWxsIGVudHJpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIG1ldGFfa2V5LgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzIGBudWxsLCBgZmFsc2VgLCBvciBhbiBlbXB0eSBzdHJpbmcgdG8gc2tpcAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGNoZWNrLiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaXQgaXMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90IHBvc3NpYmxlIHRvIHBhc3MgYW4gZW1wdHkgc3RyaW5nIHRvIGRlbGV0ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aG9zZSBlbnRyaWVzIHdpdGggYW4gZW1wdHkgc3RyaW5nIGZvciBhIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBUcnVlIG9uIHN1Y2Nlc3NmdWwgZGVsZXRlLCBmYWxzZSBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX21ldGFkYXRhKCAkb2JqZWN0X2lkLCAkbWV0YV9rZXksICRtZXRhX3ZhbHVlID0gJycgKSB7CgkJcmV0dXJuIGRlbGV0ZV9wb3N0X21ldGEoICRvYmplY3RfaWQsICRtZXRhX2tleSwgJG1ldGFfdmFsdWUgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aERCT2JqZWN0Owp1c2UgV1BfQ0xJXEVudGl0eVxVdGlscyBhcyBFbnRpdHlVdGlsczsKdXNlIFdQX0NMSVxGZXRjaGVyc1xQb3N0IGFzIFBvc3RGZXRjaGVyOwp1c2UgV1BfQ0xJXEZldGNoZXJzXFVzZXIgYXMgVXNlckZldGNoZXI7CnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTWFuYWdlcyBwb3N0cywgY29udGVudCwgYW5kIG1ldGEuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBwb3N0LgogKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAtLXBvc3RfdHlwZT1wb3N0IC0tcG9zdF90aXRsZT0nQSBzYW1wbGUgcG9zdCcKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgcG9zdCAxMjMuCiAqCiAqICAgICAjIFVwZGF0ZSBhbiBleGlzdGluZyBwb3N0LgogKiAgICAgJCB3cCBwb3N0IHVwZGF0ZSAxMjMgLS1wb3N0X3N0YXR1cz1kcmFmdAogKiAgICAgU3VjY2VzczogVXBkYXRlZCBwb3N0IDEyMy4KICoKICogICAgICMgRGVsZXRlIGFuIGV4aXN0aW5nIHBvc3QuCiAqICAgICAkIHdwIHBvc3QgZGVsZXRlIDEyMwogKiAgICAgU3VjY2VzczogVHJhc2hlZCBwb3N0IDEyMy4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBQb3N0X0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aERCT2JqZWN0IHsKCglwcm90ZWN0ZWQgJG9ial90eXBlICAgPSAncG9zdCc7Cglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBbCgkJJ0lEJywKCQkncG9zdF90aXRsZScsCgkJJ3Bvc3RfbmFtZScsCgkJJ3Bvc3RfZGF0ZScsCgkJJ3Bvc3Rfc3RhdHVzJywKCV07CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFBvc3RGZXRjaGVyKCk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHBvc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXBvc3RfYXV0aG9yPTxwb3N0X2F1dGhvcj5dCgkgKiA6IFRoZSBJRCBvZiB0aGUgdXNlciB3aG8gYWRkZWQgdGhlIHBvc3QuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdXNlciBJRC4KCSAqCgkgKiBbLS1wb3N0X2RhdGU9PHBvc3RfZGF0ZT5dCgkgKiA6IFRoZSBkYXRlIG9mIHRoZSBwb3N0LiBEZWZhdWx0IGlzIHRoZSBjdXJyZW50IHRpbWUuCgkgKgoJICogWy0tcG9zdF9kYXRlX2dtdD08cG9zdF9kYXRlX2dtdD5dCgkgKiA6IFRoZSBkYXRlIG9mIHRoZSBwb3N0IGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIHZhbHVlIG9mICRwb3N0X2RhdGUuCgkgKgoJICogWy0tcG9zdF9jb250ZW50PTxwb3N0X2NvbnRlbnQ+XQoJICogOiBUaGUgcG9zdCBjb250ZW50LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfY29udGVudF9maWx0ZXJlZD08cG9zdF9jb250ZW50X2ZpbHRlcmVkPl0KCSAqIDogVGhlIGZpbHRlcmVkIHBvc3QgY29udGVudC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1wb3N0X3RpdGxlPTxwb3N0X3RpdGxlPl0KCSAqIDogVGhlIHBvc3QgdGl0bGUuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9leGNlcnB0PTxwb3N0X2V4Y2VycHQ+XQoJICogOiBUaGUgcG9zdCBleGNlcnB0LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3Rfc3RhdHVzPTxwb3N0X3N0YXR1cz5dCgkgKiA6IFRoZSBwb3N0IHN0YXR1cy4gRGVmYXVsdCAnZHJhZnQnLgoJICoKCSAqIFstLXBvc3RfdHlwZT08cG9zdF90eXBlPl0KCSAqIDogVGhlIHBvc3QgdHlwZS4gRGVmYXVsdCAncG9zdCcuCgkgKgoJICogWy0tY29tbWVudF9zdGF0dXM9PGNvbW1lbnRfc3RhdHVzPl0KCSAqIDogV2hldGhlciB0aGUgcG9zdCBjYW4gYWNjZXB0IGNvbW1lbnRzLiBBY2NlcHRzICdvcGVuJyBvciAnY2xvc2VkJy4gRGVmYXVsdCBpcyB0aGUgdmFsdWUgb2YgJ2RlZmF1bHRfY29tbWVudF9zdGF0dXMnIG9wdGlvbi4KCSAqCgkgKiBbLS1waW5nX3N0YXR1cz08cGluZ19zdGF0dXM+XQoJICogOiBXaGV0aGVyIHRoZSBwb3N0IGNhbiBhY2NlcHQgcGluZ3MuIEFjY2VwdHMgJ29wZW4nIG9yICdjbG9zZWQnLiBEZWZhdWx0IGlzIHRoZSB2YWx1ZSBvZiAnZGVmYXVsdF9waW5nX3N0YXR1cycgb3B0aW9uLgoJICoKCSAqIFstLXBvc3RfcGFzc3dvcmQ9PHBvc3RfcGFzc3dvcmQ+XQoJICogOiBUaGUgcGFzc3dvcmQgdG8gYWNjZXNzIHRoZSBwb3N0LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfbmFtZT08cG9zdF9uYW1lPl0KCSAqIDogVGhlIHBvc3QgbmFtZS4gRGVmYXVsdCBpcyB0aGUgc2FuaXRpemVkIHBvc3QgdGl0bGUgd2hlbiBjcmVhdGluZyBhIG5ldyBwb3N0LgoJICoKCSAqIFstLWZyb20tcG9zdD08cG9zdF9pZD5dCgkgKiA6IFBvc3QgaWQgb2YgYSBwb3N0IHRvIGJlIGR1cGxpY2F0ZWQuCgkgKgoJICogWy0tdG9fcGluZz08dG9fcGluZz5dCgkgKiA6IFNwYWNlIG9yIGNhcnJpYWdlIHJldHVybi1zZXBhcmF0ZWQgbGlzdCBvZiBVUkxzIHRvIHBpbmcuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcGluZ2VkPTxwaW5nZWQ+XQoJICogOiBTcGFjZSBvciBjYXJyaWFnZSByZXR1cm4tc2VwYXJhdGVkIGxpc3Qgb2YgVVJMcyB0aGF0IGhhdmUgYmVlbiBwaW5nZWQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9tb2RpZmllZD08cG9zdF9tb2RpZmllZD5dCgkgKiA6IFRoZSBkYXRlIHdoZW4gdGhlIHBvc3Qgd2FzIGxhc3QgbW9kaWZpZWQuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X21vZGlmaWVkX2dtdD08cG9zdF9tb2RpZmllZF9nbXQ+XQoJICogOiBUaGUgZGF0ZSB3aGVuIHRoZSBwb3N0IHdhcyBsYXN0IG1vZGlmaWVkIGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X3BhcmVudD08cG9zdF9wYXJlbnQ+XQoJICogOiBTZXQgdGhpcyBmb3IgdGhlIHBvc3QgaXQgYmVsb25ncyB0bywgaWYgYW55LiBEZWZhdWx0IDAuCgkgKgoJICogWy0tbWVudV9vcmRlcj08bWVudV9vcmRlcj5dCgkgKiA6IFRoZSBvcmRlciB0aGUgcG9zdCBzaG91bGQgYmUgZGlzcGxheWVkIGluLiBEZWZhdWx0IDAuCgkgKgoJICogWy0tcG9zdF9taW1lX3R5cGU9PHBvc3RfbWltZV90eXBlPl0KCSAqIDogVGhlIG1pbWUgdHlwZSBvZiB0aGUgcG9zdC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1ndWlkPTxndWlkPl0KCSAqIDogR2xvYmFsIFVuaXF1ZSBJRCBmb3IgcmVmZXJlbmNpbmcgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jYXRlZ29yeT08cG9zdF9jYXRlZ29yeT5dCgkgKiA6IEFycmF5IG9mIGNhdGVnb3J5IG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0cyB0byB2YWx1ZSBvZiB0aGUgJ2RlZmF1bHRfY2F0ZWdvcnknIG9wdGlvbi4KCSAqCgkgKiBbLS10YWdzX2lucHV0PTx0YWdzX2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGFnIG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXRheF9pbnB1dD08dGF4X2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGF4b25vbXkgdGVybXMga2V5ZWQgYnkgdGhlaXIgdGF4b25vbXkgbmFtZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1tZXRhX2lucHV0PTxtZXRhX2lucHV0Pl0KCSAqIDogQXJyYXkgaW4gSlNPTiBmb3JtYXQgb2YgcG9zdCBtZXRhIHZhbHVlcyBrZXllZCBieSB0aGVpciBwb3N0IG1ldGEga2V5LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFs8ZmlsZT5dCgkgKiA6IFJlYWQgcG9zdCBjb250ZW50IGZyb20gPGZpbGU+LiBJZiB0aGlzIHZhbHVlIGlzIHByZXNlbnQsIHRoZQoJICogICAgIGAtLXBvc3RfY29udGVudGAgYXJndW1lbnQgd2lsbCBiZSBpZ25vcmVkLgoJICoKCSAqICAgUGFzc2luZyBgLWAgYXMgdGhlIGZpbGVuYW1lIHdpbGwgY2F1c2UgcG9zdCBjb250ZW50IHRvCgkgKiAgIGJlIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEFzc29jaWF0aXZlIGFyZ3MgZm9yIHRoZSBuZXcgcG9zdC4gU2VlIHdwX2luc2VydF9wb3N0KCkuCgkgKgoJICogWy0tZWRpdF0KCSAqIDogSW1tZWRpYXRlbHkgb3BlbiBzeXN0ZW0ncyBlZGl0b3IgdG8gd3JpdGUgb3IgZWRpdCBwb3N0IGNvbnRlbnQuCgkgKgoJICogICBJZiBjb250ZW50IGlzIHJlYWQgZnJvbSBhIGZpbGUsIGZyb20gU1RESU4sIG9yIGZyb20gdGhlIGAtLXBvc3RfY29udGVudGAKCSAqICAgYXJndW1lbnQsIHRoYXQgdGV4dCB3aWxsIGJlIGxvYWRlZCBpbnRvIHRoZSBlZGl0b3IuCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBPdXRwdXQganVzdCB0aGUgbmV3IHBvc3QgaWQuCgkgKgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIHBvc3QgYW5kIHNjaGVkdWxlIGZvciBmdXR1cmUKCSAqICAgICAkIHdwIHBvc3QgY3JlYXRlIC0tcG9zdF90eXBlPXBhZ2UgLS1wb3N0X3RpdGxlPSdBIGZ1dHVyZSBwb3N0JyAtLXBvc3Rfc3RhdHVzPWZ1dHVyZSAtLXBvc3RfZGF0ZT0nMjAyMC0xMi0wMSAwNzowMDowMCcKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMTkyMS4KCSAqCgkgKiAgICAgIyBDcmVhdGUgcG9zdCB3aXRoIGNvbnRlbnQgZnJvbSBnaXZlbiBmaWxlCgkgKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAuL3Bvc3QtY29udGVudC50eHQgLS1wb3N0X2NhdGVnb3J5PTIwMSwzNDUgLS1wb3N0X3RpdGxlPSdQb3N0IGZyb20gZmlsZScKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMTkyMi4KCSAqCgkgKiAgICAgIyBDcmVhdGUgYSBwb3N0IHdpdGggbXVsdGlwbGUgbWV0YSB2YWx1ZXMuCgkgKiAgICAgJCB3cCBwb3N0IGNyZWF0ZSAtLXBvc3RfdGl0bGU9J0EgcG9zdCcgLS1wb3N0X2NvbnRlbnQ9J0p1c3QgYSBzbWFsbCBwb3N0LicgLS1tZXRhX2lucHV0PSd7ImtleTEiOiJ2YWx1ZTEiLCJrZXkyIjoidmFsdWUyIn0nCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCBwb3N0IDE5MjMuCgkgKgoJICogICAgICMgQ3JlYXRlIGEgZHVwbGljYXRlIHBvc3QgZnJvbSBleGlzdGluZyBwb3N0cy4KCSAqICAgICAkIHdwIHBvc3QgY3JlYXRlIC0tZnJvbS1wb3N0PTEyMyAtLXBvc3RfdGl0bGU9J0RpZmZlcmVudCBUaXRsZScKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBvc3QgMjM1MC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBlbXB0eSggJGFyZ3NbMF0gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfY29udGVudCddID0gJHRoaXMtPnJlYWRfZnJvbV9maWxlX29yX3N0ZGluKCAkYXJnc1swXSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdlZGl0JyApICkgewoJCQkkaW5wdXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3N0X2NvbnRlbnQnLCAnJyApOwoKCQkJJG91dHB1dCA9ICR0aGlzLT5fZWRpdCggJGlucHV0LCAnV1AtQ0xJOiBOZXcgUG9zdCcgKTsKCQkJaWYgKCAkb3V0cHV0ICkgewoJCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfY29udGVudCddID0gJG91dHB1dDsKCQkJfSBlbHNlIHsKCQkJCSRhc3NvY19hcmdzWydwb3N0X2NvbnRlbnQnXSA9ICRpbnB1dDsKCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bvc3RfY2F0ZWdvcnknXSApICkgewoJCQkkYXNzb2NfYXJnc1sncG9zdF9jYXRlZ29yeSddID0gJHRoaXMtPmdldF9jYXRlZ29yeV9pZHMoICRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gKSAmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGhlICdtZXRhX2lucHV0JyBmaWVsZCB3YXMgb25seSBpbnRyb2R1Y2VkIGluIFdvcmRQcmVzcyA0LjQgc28gd2lsbCBoYXZlIG5vIGVmZmVjdC4iICk7CgkJfQoKCQkkYXJyYXlfYXJndW1lbnRzID0gWyAnbWV0YV9pbnB1dCcgXTsKCQkkYXNzb2NfYXJncyAgICAgID0gVXRpbHNccGFyc2Vfc2hlbGxfYXJyYXlzKCAkYXNzb2NfYXJncywgJGFycmF5X2FyZ3VtZW50cyApOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZnJvbS1wb3N0J10gKSApIHsKCQkJJHBvc3QgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFzc29jX2FyZ3NbJ2Zyb20tcG9zdCddICk7CgkJCSRwb3N0X2FyciA9IGdldF9vYmplY3RfdmFycyggJHBvc3QgKTsKCQkJJHBvc3RfaWQgID0gJHBvc3RfYXJyWydJRCddOwoJCQl1bnNldCggJHBvc3RfYXJyWydwb3N0X2RhdGUnXSApOwoJCQl1bnNldCggJHBvc3RfYXJyWydwb3N0X2RhdGVfZ210J10gKTsKCQkJdW5zZXQoICRwb3N0X2FyclsnZ3VpZCddICk7CgkJCXVuc2V0KCAkcG9zdF9hcnJbJ0lEJ10gKTsKCgkJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gKSApIHsKCQkJCSRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gPSAkdGhpcy0+Z2V0X21ldGFkYXRhKCAkcG9zdF9pZCApOwoJCQl9CgkJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gKSApIHsKCQkJCSRwb3N0X2FyclsncG9zdF9jYXRlZ29yeSddID0gJHRoaXMtPmdldF9jYXRlZ29yeSggJHBvc3RfaWQgKTsKCQkJfQoJCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1sndGFnc19pbnB1dCddICkgKSB7CgkJCQkkcG9zdF9hcnJbJ3RhZ3NfaW5wdXQnXSA9ICR0aGlzLT5nZXRfdGFncyggJHBvc3RfaWQgKTsKCQkJfQoJCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkcG9zdF9hcnIsICRhc3NvY19hcmdzICk7CgkJfQoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X2NyZWF0ZSgKCQkJJGFyZ3MsCgkJCSRhc3NvY19hcmdzLAoJCQlmdW5jdGlvbiAoICRwYXJhbXMgKSB7CgkJCQlyZXR1cm4gd3BfaW5zZXJ0X3Bvc3QoICRwYXJhbXMsIHRydWUgKTsKCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIG9uZSBvciBtb3JlIGV4aXN0aW5nIHBvc3RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBwb3N0cyB0byB1cGRhdGUuCgkgKgoJICogWy0tcG9zdF9hdXRob3I9PHBvc3RfYXV0aG9yPl0KCSAqIDogVGhlIElEIG9mIHRoZSB1c2VyIHdobyBhZGRlZCB0aGUgcG9zdC4gRGVmYXVsdCBpcyB0aGUgY3VycmVudCB1c2VyIElELgoJICoKCSAqIFstLXBvc3RfZGF0ZT08cG9zdF9kYXRlPl0KCSAqIDogVGhlIGRhdGUgb2YgdGhlIHBvc3QuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X2RhdGVfZ210PTxwb3N0X2RhdGVfZ210Pl0KCSAqIDogVGhlIGRhdGUgb2YgdGhlIHBvc3QgaW4gdGhlIEdNVCB0aW1lem9uZS4gRGVmYXVsdCBpcyB0aGUgdmFsdWUgb2YgJHBvc3RfZGF0ZS4KCSAqCgkgKiBbLS1wb3N0X2NvbnRlbnQ9PHBvc3RfY29udGVudD5dCgkgKiA6IFRoZSBwb3N0IGNvbnRlbnQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jb250ZW50X2ZpbHRlcmVkPTxwb3N0X2NvbnRlbnRfZmlsdGVyZWQ+XQoJICogOiBUaGUgZmlsdGVyZWQgcG9zdCBjb250ZW50LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXBvc3RfdGl0bGU9PHBvc3RfdGl0bGU+XQoJICogOiBUaGUgcG9zdCB0aXRsZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1wb3N0X2V4Y2VycHQ9PHBvc3RfZXhjZXJwdD5dCgkgKiA6IFRoZSBwb3N0IGV4Y2VycHQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9zdGF0dXM9PHBvc3Rfc3RhdHVzPl0KCSAqIDogVGhlIHBvc3Qgc3RhdHVzLiBEZWZhdWx0ICdkcmFmdCcuCgkgKgoJICogWy0tcG9zdF90eXBlPTxwb3N0X3R5cGU+XQoJICogOiBUaGUgcG9zdCB0eXBlLiBEZWZhdWx0ICdwb3N0Jy4KCSAqCgkgKiBbLS1jb21tZW50X3N0YXR1cz08Y29tbWVudF9zdGF0dXM+XQoJICogOiBXaGV0aGVyIHRoZSBwb3N0IGNhbiBhY2NlcHQgY29tbWVudHMuIEFjY2VwdHMgJ29wZW4nIG9yICdjbG9zZWQnLiBEZWZhdWx0IGlzIHRoZSB2YWx1ZSBvZiAnZGVmYXVsdF9jb21tZW50X3N0YXR1cycgb3B0aW9uLgoJICoKCSAqIFstLXBpbmdfc3RhdHVzPTxwaW5nX3N0YXR1cz5dCgkgKiA6IFdoZXRoZXIgdGhlIHBvc3QgY2FuIGFjY2VwdCBwaW5ncy4gQWNjZXB0cyAnb3Blbicgb3IgJ2Nsb3NlZCcuIERlZmF1bHQgaXMgdGhlIHZhbHVlIG9mICdkZWZhdWx0X3Bpbmdfc3RhdHVzJyBvcHRpb24uCgkgKgoJICogWy0tcG9zdF9wYXNzd29yZD08cG9zdF9wYXNzd29yZD5dCgkgKiA6IFRoZSBwYXNzd29yZCB0byBhY2Nlc3MgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9uYW1lPTxwb3N0X25hbWU+XQoJICogOiBUaGUgcG9zdCBuYW1lLiBEZWZhdWx0IGlzIHRoZSBzYW5pdGl6ZWQgcG9zdCB0aXRsZSB3aGVuIGNyZWF0aW5nIGEgbmV3IHBvc3QuCgkgKgoJICogWy0tdG9fcGluZz08dG9fcGluZz5dCgkgKiA6IFNwYWNlIG9yIGNhcnJpYWdlIHJldHVybi1zZXBhcmF0ZWQgbGlzdCBvZiBVUkxzIHRvIHBpbmcuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcGluZ2VkPTxwaW5nZWQ+XQoJICogOiBTcGFjZSBvciBjYXJyaWFnZSByZXR1cm4tc2VwYXJhdGVkIGxpc3Qgb2YgVVJMcyB0aGF0IGhhdmUgYmVlbiBwaW5nZWQuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9tb2RpZmllZD08cG9zdF9tb2RpZmllZD5dCgkgKiA6IFRoZSBkYXRlIHdoZW4gdGhlIHBvc3Qgd2FzIGxhc3QgbW9kaWZpZWQuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X21vZGlmaWVkX2dtdD08cG9zdF9tb2RpZmllZF9nbXQ+XQoJICogOiBUaGUgZGF0ZSB3aGVuIHRoZSBwb3N0IHdhcyBsYXN0IG1vZGlmaWVkIGluIHRoZSBHTVQgdGltZXpvbmUuIERlZmF1bHQgaXMgdGhlIGN1cnJlbnQgdGltZS4KCSAqCgkgKiBbLS1wb3N0X3BhcmVudD08cG9zdF9wYXJlbnQ+XQoJICogOiBTZXQgdGhpcyBmb3IgdGhlIHBvc3QgaXQgYmVsb25ncyB0bywgaWYgYW55LiBEZWZhdWx0IDAuCgkgKgoJICogWy0tbWVudV9vcmRlcj08bWVudV9vcmRlcj5dCgkgKiA6IFRoZSBvcmRlciB0aGUgcG9zdCBzaG91bGQgYmUgZGlzcGxheWVkIGluLiBEZWZhdWx0IDAuCgkgKgoJICogWy0tcG9zdF9taW1lX3R5cGU9PHBvc3RfbWltZV90eXBlPl0KCSAqIDogVGhlIG1pbWUgdHlwZSBvZiB0aGUgcG9zdC4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1ndWlkPTxndWlkPl0KCSAqIDogR2xvYmFsIFVuaXF1ZSBJRCBmb3IgcmVmZXJlbmNpbmcgdGhlIHBvc3QuIERlZmF1bHQgZW1wdHkuCgkgKgoJICogWy0tcG9zdF9jYXRlZ29yeT08cG9zdF9jYXRlZ29yeT5dCgkgKiA6IEFycmF5IG9mIGNhdGVnb3J5IG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0cyB0byB2YWx1ZSBvZiB0aGUgJ2RlZmF1bHRfY2F0ZWdvcnknIG9wdGlvbi4KCSAqCgkgKiBbLS10YWdzX2lucHV0PTx0YWdzX2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGFnIG5hbWVzLCBzbHVncywgb3IgSURzLiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFstLXRheF9pbnB1dD08dGF4X2lucHV0Pl0KCSAqIDogQXJyYXkgb2YgdGF4b25vbXkgdGVybXMga2V5ZWQgYnkgdGhlaXIgdGF4b25vbXkgbmFtZS4gRGVmYXVsdCBlbXB0eS4KCSAqCgkgKiBbLS1tZXRhX2lucHV0PTxtZXRhX2lucHV0Pl0KCSAqIDogQXJyYXkgaW4gSlNPTiBmb3JtYXQgb2YgcG9zdCBtZXRhIHZhbHVlcyBrZXllZCBieSB0aGVpciBwb3N0IG1ldGEga2V5LiBEZWZhdWx0IGVtcHR5LgoJICoKCSAqIFs8ZmlsZT5dCgkgKiA6IFJlYWQgcG9zdCBjb250ZW50IGZyb20gPGZpbGU+LiBJZiB0aGlzIHZhbHVlIGlzIHByZXNlbnQsIHRoZQoJICogICAgIGAtLXBvc3RfY29udGVudGAgYXJndW1lbnQgd2lsbCBiZSBpZ25vcmVkLgoJICoKCSAqICAgUGFzc2luZyBgLWAgYXMgdGhlIGZpbGVuYW1lIHdpbGwgY2F1c2UgcG9zdCBjb250ZW50IHRvCgkgKiAgIGJlIHJlYWQgZnJvbSBTVERJTi4KCSAqCgkgKiAtLTxmaWVsZD49PHZhbHVlPgoJICogOiBPbmUgb3IgbW9yZSBmaWVsZHMgdG8gdXBkYXRlLiBTZWUgd3BfaW5zZXJ0X3Bvc3QoKS4KCSAqCgkgKiBbLS1kZWZlci10ZXJtLWNvdW50aW5nXQoJICogOiBSZWNhbGN1bGF0ZSB0ZXJtIGNvdW50IGluIGJhdGNoLCBmb3IgYSBwZXJmb3JtYW5jZSBib29zdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBvc3QgdXBkYXRlIDEyMyAtLXBvc3RfbmFtZT1zb21ldGhpbmcgLS1wb3N0X3N0YXR1cz1kcmFmdAoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdCAxMjMuCgkgKgoJICogICAgICMgVXBkYXRlIGEgcG9zdCB3aXRoIG11bHRpcGxlIG1ldGEgdmFsdWVzLgoJICogICAgICQgd3AgcG9zdCB1cGRhdGUgMTIzIC0tbWV0YV9pbnB1dD0neyJrZXkxIjoidmFsdWUxIiwia2V5MiI6InZhbHVlMiJ9JwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgcG9zdCAxMjMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRrZXkgPT4gJGFyZyApIHsKCQkJaWYgKCBpc19udW1lcmljKCAkYXJnICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfY29udGVudCddID0gJHRoaXMtPnJlYWRfZnJvbV9maWxlX29yX3N0ZGluKCAkYXJnICk7CgkJCXVuc2V0KCAkYXJnc1sgJGtleSBdICk7CgkJCWJyZWFrOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bvc3RfY2F0ZWdvcnknXSApICkgewoJCQkkYXNzb2NfYXJnc1sncG9zdF9jYXRlZ29yeSddID0gJHRoaXMtPmdldF9jYXRlZ29yeV9pZHMoICRhc3NvY19hcmdzWydwb3N0X2NhdGVnb3J5J10gKTsKCQl9CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydtZXRhX2lucHV0J10gKSAmJiBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGhlICdtZXRhX2lucHV0JyBmaWVsZCB3YXMgb25seSBpbnRyb2R1Y2VkIGluIFdvcmRQcmVzcyA0LjQgc28gd2lsbCBoYXZlIG5vIGVmZmVjdC4iICk7CgkJfQoKCQkkYXJyYXlfYXJndW1lbnRzID0gWyAnbWV0YV9pbnB1dCcgXTsKCQkkYXNzb2NfYXJncyAgICAgID0gVXRpbHNccGFyc2Vfc2hlbGxfYXJyYXlzKCAkYXNzb2NfYXJncywgJGFycmF5X2FyZ3VtZW50cyApOwoKCQkkYXNzb2NfYXJncyA9IHdwX3NsYXNoKCAkYXNzb2NfYXJncyApOwoJCXBhcmVudDo6X3VwZGF0ZSgKCQkJJGFyZ3MsCgkJCSRhc3NvY19hcmdzLAoJCQlmdW5jdGlvbiAoICRwYXJhbXMgKSB7CgkJCQlyZXR1cm4gd3BfdXBkYXRlX3Bvc3QoICRwYXJhbXMsIHRydWUgKTsKCQkJfQoJCSk7Cgl9CgoJLyoqCgkgKiBMYXVuY2hlcyBzeXN0ZW0gZWRpdG9yIHRvIGVkaXQgcG9zdCBjb250ZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+CgkgKiA6IFRoZSBJRCBvZiB0aGUgcG9zdCB0byBlZGl0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGF1bmNoIHN5c3RlbSBlZGl0b3IgdG8gZWRpdCBwb3N0CgkgKiAgICAgJCB3cCBwb3N0IGVkaXQgMTIzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlZGl0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBvc3QgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQkkcmVzdWx0ID0gJHRoaXMtPl9lZGl0KCAkcG9zdC0+cG9zdF9jb250ZW50LCAiV1AtQ0xJIHBvc3QgeyRwb3N0LT5JRH0iICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ05vIGNoYW5nZSBtYWRlIHRvIHBvc3QgY29udGVudC4nLCAnQWJvcnRlZCcgKTsKCQl9IGVsc2UgewoJCQkkdGhpcy0+dXBkYXRlKCAkYXJncywgWyAncG9zdF9jb250ZW50JyA9PiAkcmVzdWx0IF0gKTsKCQl9Cgl9CgoJLy8gcGhwY3M6aWdub3JlIFBTUjIuTWV0aG9kcy5NZXRob2REZWNsYXJhdGlvbi5VbmRlcnNjb3JlIC0tIFdoaXRlbGlzdGluZyB0byBwcm92aWRlIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgdG8gY2xhc3NlcyBwb3NzaWJseSBleHRlbmRpbmcgdGhpcyBjbGFzcy4KCXByb3RlY3RlZCBmdW5jdGlvbiBfZWRpdCggJGNvbnRlbnQsICR0aXRsZSApIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCSRjb250ZW50ID0gYXBwbHlfZmlsdGVycyggJ3RoZV9lZGl0b3JfY29udGVudCcsICRjb250ZW50ICk7CgkJJG91dHB1dCAgPSBVdGlsc1xsYXVuY2hfZWRpdG9yX2Zvcl9pbnB1dCggJGNvbnRlbnQsICR0aXRsZSApOwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJcmV0dXJuICggaXNfc3RyaW5nKCAkb3V0cHV0ICkgKSA/IGFwcGx5X2ZpbHRlcnMoICdjb250ZW50X3NhdmVfcHJlJywgJG91dHB1dCApIDogJG91dHB1dDsKCX0KCgkvKioKCSAqIEdldHMgZGV0YWlscyBhYm91dCBhIHBvc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBwb3N0IHRvIGdldC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBJbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgd2hvbGUgcG9zdCwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTYXZlIHRoZSBwb3N0IGNvbnRlbnQgdG8gYSBmaWxlCgkgKiAgICAgJCB3cCBwb3N0IGdldCAxMjMgLS1maWVsZD1jb250ZW50ID4gZmlsZS50eHQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRwb3N0ID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJJHBvc3RfYXJyID0gZ2V0X29iamVjdF92YXJzKCAkcG9zdCApOwoJCXVuc2V0KCAkcG9zdF9hcnJbJ2ZpbHRlciddICk7CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkYXNzb2NfYXJnc1snZmllbGRzJ10gPSBhcnJheV9rZXlzKCAkcG9zdF9hcnIgKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICRwb3N0X2FyciApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBhbiBleGlzdGluZyBwb3N0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBwb3N0cyB0byBkZWxldGUuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IFNraXAgdGhlIHRyYXNoIGJpbi4KCSAqCgkgKiBbLS1kZWZlci10ZXJtLWNvdW50aW5nXQoJICogOiBSZWNhbGN1bGF0ZSB0ZXJtIGNvdW50IGluIGJhdGNoLCBmb3IgYSBwZXJmb3JtYW5jZSBib29zdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBwb3N0IHNraXBwaW5nIHRyYXNoCgkgKiAgICAgJCB3cCBwb3N0IGRlbGV0ZSAxMjMgLS1mb3JjZQoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgcG9zdCAxMjMuCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCBwYWdlcwoJICogICAgICQgd3AgcG9zdCBkZWxldGUgJCh3cCBwb3N0IGxpc3QgLS1wb3N0X3R5cGU9J3BhZ2UnIC0tZm9ybWF0PWlkcykKCSAqICAgICBTdWNjZXNzOiBUcmFzaGVkIHBvc3QgMTE2NC4KCSAqICAgICBTdWNjZXNzOiBUcmFzaGVkIHBvc3QgMTE4Ni4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHBvc3RzIGluIHRoZSB0cmFzaAoJICogICAgICQgd3AgcG9zdCBkZWxldGUgJCh3cCBwb3N0IGxpc3QgLS1wb3N0X3N0YXR1cz10cmFzaCAtLWZvcm1hdD1pZHMpCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBwb3N0IDEyNjguCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCBwb3N0IDEyOTQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZGVmYXVsdHMgICA9IFsgJ2ZvcmNlJyA9PiBmYWxzZSBdOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJcGFyZW50OjpfZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MsIFsgJHRoaXMsICdkZWxldGVfY2FsbGJhY2snIF0gKTsKCX0KCgkvKioKCSAqIENhbGxiYWNrIHVzZWQgdG8gZGVsZXRlIGEgcG9zdC4KCSAqCgkgKiBAcGFyYW0gJHBvc3RfaWQKCSAqIEBwYXJhbSAkYXNzb2NfYXJncwoJICogQHJldHVybiBhcnJheQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZGVsZXRlX2NhbGxiYWNrKCAkcG9zdF9pZCwgJGFzc29jX2FyZ3MgKSB7CgkJJHN0YXR1cyAgICA9IGdldF9wb3N0X3N0YXR1cyggJHBvc3RfaWQgKTsKCQkkcG9zdF90eXBlID0gZ2V0X3Bvc3RfdHlwZSggJHBvc3RfaWQgKTsKCgkJaWYgKCAhICRhc3NvY19hcmdzWydmb3JjZSddCgkJCSYmICggJ3Bvc3QnICE9PSAkcG9zdF90eXBlICYmICdwYWdlJyAhPT0gJHBvc3RfdHlwZSApICkgewoJCQlyZXR1cm4gWwoJCQkJJ2Vycm9yJywKCQkJCSJQb3N0cyBvZiB0eXBlICd7JHBvc3RfdHlwZX0nIGRvIG5vdCBzdXBwb3J0IGJlaW5nIHNlbnQgdG8gdHJhc2guXG4iCgkJCQkuICdQbGVhc2UgdXNlIHRoZSAtLWZvcmNlIGZsYWcgdG8gc2tpcCB0cmFzaCBhbmQgZGVsZXRlIHRoZW0gcGVybWFuZW50bHkuJywKCQkJXTsKCQl9CgoJCWlmICggISB3cF9kZWxldGVfcG9zdCggJHBvc3RfaWQsICRhc3NvY19hcmdzWydmb3JjZSddICkgKSB7CgkJCXJldHVybiBbICdlcnJvcicsICJGYWlsZWQgZGVsZXRpbmcgcG9zdCB7JHBvc3RfaWR9LiIgXTsKCQl9CgoJCSRhY3Rpb24gPSAkYXNzb2NfYXJnc1snZm9yY2UnXSB8fCAndHJhc2gnID09PSAkc3RhdHVzIHx8ICdyZXZpc2lvbicgPT09ICRwb3N0X3R5cGUgPyAnRGVsZXRlZCcgOiAnVHJhc2hlZCc7CgoJCXJldHVybiBbICdzdWNjZXNzJywgInskYWN0aW9ufSBwb3N0IHskcG9zdF9pZH0uIiBdOwoJfQoKCS8qKgoJICogR2V0cyBhIGxpc3Qgb2YgcG9zdHMuCgkgKgoJICogRGlzcGxheSBwb3N0cyBiYXNlZCBvbiBhbGwgYXJndW1lbnRzIHN1cHBvcnRlZCBieQoJICogW1dQX1F1ZXJ5KCldKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcmVmZXJlbmNlL2NsYXNzZXMvd3BfcXVlcnkvKS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBPbmUgb3IgbW9yZSBhcmdzIHRvIHBhc3MgdG8gV1BfUXVlcnkuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBwb3N0LgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBwb3N0OgoJICoKCSAqICogSUQKCSAqICogcG9zdF90aXRsZQoJICogKiBwb3N0X25hbWUKCSAqICogcG9zdF9kYXRlCgkgKiAqIHBvc3Rfc3RhdHVzCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHBvc3RfYXV0aG9yCgkgKiAqIHBvc3RfZGF0ZV9nbXQKCSAqICogcG9zdF9jb250ZW50CgkgKiAqIHBvc3RfZXhjZXJwdAoJICogKiBjb21tZW50X3N0YXR1cwoJICogKiBwaW5nX3N0YXR1cwoJICogKiBwb3N0X3Bhc3N3b3JkCgkgKiAqIHRvX3BpbmcKCSAqICogcGluZ2VkCgkgKiAqIHBvc3RfbW9kaWZpZWQKCSAqICogcG9zdF9tb2RpZmllZF9nbXQKCSAqICogcG9zdF9jb250ZW50X2ZpbHRlcmVkCgkgKiAqIHBvc3RfcGFyZW50CgkgKiAqIGd1aWQKCSAqICogbWVudV9vcmRlcgoJICogKiBwb3N0X3R5cGUKCSAqICogcG9zdF9taW1lX3R5cGUKCSAqICogY29tbWVudF9jb3VudAoJICogKiBmaWx0ZXIKCSAqICogdXJsCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3QKCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLWZpZWxkPUlECgkgKiAgICAgNTY4CgkgKiAgICAgODI5CgkgKiAgICAgMTMyOQoJICogICAgIDE2OTUKCSAqCgkgKiAgICAgIyBMaXN0IHBvc3RzIGluIEpTT04KCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLXBvc3RfdHlwZT1wb3N0IC0tcG9zdHNfcGVyX3BhZ2U9NSAtLWZvcm1hdD1qc29uCgkgKiAgICAgW3siSUQiOjEsInBvc3RfdGl0bGUiOiJIZWxsbyB3b3JsZCEiLCJwb3N0X25hbWUiOiJoZWxsby13b3JsZCIsInBvc3RfZGF0ZSI6IjIwMTUtMDYtMjAgMDk6MDA6MTAiLCJwb3N0X3N0YXR1cyI6InB1Ymxpc2gifSx7IklEIjoxMTc4LCJwb3N0X3RpdGxlIjoiTWFya3VwOiBIVE1MIFRhZ3MgYW5kIEZvcm1hdHRpbmciLCJwb3N0X25hbWUiOiJtYXJrdXAtaHRtbC10YWdzLWFuZC1mb3JtYXR0aW5nIiwicG9zdF9kYXRlIjoiMjAxMy0wMS0xMSAyMDoyMjoxOSIsInBvc3Rfc3RhdHVzIjoiZHJhZnQifV0KCSAqCgkgKiAgICAgIyBMaXN0IGFsbCBwYWdlcwoJICogICAgICQgd3AgcG9zdCBsaXN0IC0tcG9zdF90eXBlPXBhZ2UgLS1maWVsZHM9cG9zdF90aXRsZSxwb3N0X3N0YXR1cwoJICogICAgICstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBwb3N0X3RpdGxlICB8IHBvc3Rfc3RhdHVzIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgU2FtcGxlIFBhZ2UgfCBwdWJsaXNoICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBMaXN0IGlkcyBvZiBhbGwgcGFnZXMgYW5kIHBvc3RzCgkgKiAgICAgJCB3cCBwb3N0IGxpc3QgLS1wb3N0X3R5cGU9cGFnZSxwb3N0IC0tZm9ybWF0PWlkcwoJICogICAgIDE1IDI1IDM0IDM3IDE5OAoJICoKCSAqICAgICAjIExpc3QgZ2l2ZW4gcG9zdHMKCSAqICAgICAkIHdwIHBvc3QgbGlzdCAtLXBvc3RfX2luPTEsMwoJICogICAgICstLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBJRCB8IHBvc3RfdGl0bGUgICB8IHBvc3RfbmFtZSAgIHwgcG9zdF9kYXRlICAgICAgICAgICB8IHBvc3Rfc3RhdHVzIHwKCSAqICAgICArLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgMyAgfCBMb3JlbSBJcHN1bSAgfCBsb3JlbS1pcHN1bSB8IDIwMTYtMDYtMDEgMTQ6MzQ6MzYgfCBwdWJsaXNoICAgICB8CgkgKiAgICAgfCAxICB8IEhlbGxvIHdvcmxkISB8IGhlbGxvLXdvcmxkIHwgMjAxNi0wNi0wMSAxNDozMToxMiB8IHB1Ymxpc2ggICAgIHwKCSAqICAgICArLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoKCQkkZGVmYXVsdHMgICA9IFsKCQkJJ3Bvc3RzX3Blcl9wYWdlJyA9PiAtMSwKCQkJJ3Bvc3Rfc3RhdHVzJyAgICA9PiAnYW55JywKCQldOwoJCSRxdWVyeV9hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCQkkcXVlcnlfYXJncyA9IHNlbGY6OnByb2Nlc3NfY3N2X2FyZ3VtZW50c190b19hcnJheXMoICRxdWVyeV9hcmdzICk7CgkJaWYgKCBpc3NldCggJHF1ZXJ5X2FyZ3NbJ3Bvc3RfdHlwZSddICkgJiYgJ2FueScgIT09ICRxdWVyeV9hcmdzWydwb3N0X3R5cGUnXSApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ3Bvc3RfdHlwZSddID0gZXhwbG9kZSggJywnLCAkcXVlcnlfYXJnc1sncG9zdF90eXBlJ10gKTsKCQl9CgoJCWlmICggJ2lkcycgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJCSRxdWVyeSAgICAgICAgICAgICAgICA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJZWNobyBpbXBsb2RlKCAnICcsICRxdWVyeS0+cG9zdHMgKTsKCQl9IGVsc2VpZiAoICdjb3VudCcgPT09ICRmb3JtYXR0ZXItPmZvcm1hdCApIHsKCQkJJHF1ZXJ5X2FyZ3NbJ2ZpZWxkcyddID0gJ2lkcyc7CgkJCSRxdWVyeSAgICAgICAgICAgICAgICA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHF1ZXJ5LT5wb3N0cyApOwoJCX0gZWxzZSB7CgkJCSRxdWVyeSA9IG5ldyBXUF9RdWVyeSggJHF1ZXJ5X2FyZ3MgKTsKCQkJJHBvc3RzID0gYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24oICRwb3N0ICkgewoJCQkJCQkkcG9zdC0+dXJsID0gZ2V0X3Blcm1hbGluayggJHBvc3QtPklEICk7CgkJCQkJCXJldHVybiAkcG9zdDsKCQkJCX0sCgkJCQkkcXVlcnktPnBvc3RzCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRwb3N0cyApOwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzb21lIHBvc3RzLgoJICoKCSAqIENyZWF0ZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIG5ldyBwb3N0cyB3aXRoIGR1bW15IGRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWNvdW50PTxudW1iZXI+XQoJICogOiBIb3cgbWFueSBwb3N0cyB0byBnZW5lcmF0ZT8KCSAqIC0tLQoJICogZGVmYXVsdDogMTAwCgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3R5cGU9PHR5cGU+XQoJICogOiBUaGUgdHlwZSBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwb3N0CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3N0YXR1cz08c3RhdHVzPl0KCSAqIDogVGhlIHN0YXR1cyBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBwdWJsaXNoCgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3RpdGxlPTxwb3N0X3RpdGxlPl0KCSAqIDogVGhlIHBvc3QgdGl0bGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X2F1dGhvcj08bG9naW4+XQoJICogOiBUaGUgYXV0aG9yIG9mIHRoZSBnZW5lcmF0ZWQgcG9zdHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X2RhdGU9PHl5eXktbW0tZGQtaGgtaWktc3M+XQoJICogOiBUaGUgZGF0ZSBvZiB0aGUgZ2VuZXJhdGVkIHBvc3RzLiBEZWZhdWx0OiBjdXJyZW50IGRhdGUKCSAqCgkgKiBbLS1wb3N0X2RhdGVfZ210PTx5eXl5LW1tLWRkLWhoLWlpLXNzPl0KCSAqIDogVGhlIEdNVCBkYXRlIG9mIHRoZSBnZW5lcmF0ZWQgcG9zdHMuIERlZmF1bHQ6IHZhbHVlIG9mIHBvc3RfZGF0ZSAob3IgY3VycmVudCBkYXRlIGlmIGl0J3Mgbm90IHNldCkKCSAqCgkgKiBbLS1wb3N0X2NvbnRlbnRdCgkgKiA6IElmIHNldCwgdGhlIGNvbW1hbmQgcmVhZHMgdGhlIHBvc3RfY29udGVudCBmcm9tIFNURElOLgoJICoKCSAqIFstLW1heF9kZXB0aD08bnVtYmVyPl0KCSAqIDogRm9yIGhpZXJhcmNoaWNhbCBwb3N0IHR5cGVzLCBnZW5lcmF0ZSBjaGlsZCBwb3N0cyBkb3duIHRvIGEgY2VydGFpbiBkZXB0aC4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHByb2dyZXNzCgkgKiBvcHRpb25zOgoJICogICAtIHByb2dyZXNzCgkgKiAgIC0gaWRzCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIHBvc3RzLgoJICogICAgICQgd3AgcG9zdCBnZW5lcmF0ZSAtLWNvdW50PTEwIC0tcG9zdF90eXBlPXBhZ2UgLS1wb3N0X2RhdGU9MTk5OS0wMS0wNAoJICogICAgIEdlbmVyYXRpbmcgcG9zdHMgIDEwMCUgWz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PV0gMDowMSAvIDA6MDQKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBwb3N0cyB3aXRoIGZldGNoZWQgY29udGVudC4KCSAqICAgICAkIGN1cmwgLU4gaHR0cDovL2xvcmlwc3VtLm5ldC9hcGkvNSB8IHdwIHBvc3QgZ2VuZXJhdGUgLS1wb3N0X2NvbnRlbnQgLS1jb3VudD0xMAoJICogICAgICAgJSBUb3RhbCAgICAlIFJlY2VpdmVkICUgWGZlcmQgIEF2ZXJhZ2UgU3BlZWQgICBUaW1lICAgIFRpbWUgICAgIFRpbWUgIEN1cnJlbnQKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEbG9hZCAgVXBsb2FkICAgVG90YWwgICBTcGVudCAgICBMZWZ0ICBTcGVlZAoJICogICAgIDEwMCAgMjUwOSAgMTAwICAyNTA5ICAgIDAgICAgIDAgICAgNjE2ICAgICAgMCAgMDowMDowNCAgMDowMDowNCAtLTotLTotLSAgIDYxNgoJICogICAgIEdlbmVyYXRpbmcgcG9zdHMgIDEwMCUgWz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PV0gMDowMSAvIDA6MDQKCSAqCgkgKiAgICAgIyBBZGQgbWV0YSB0byBldmVyeSBnZW5lcmF0ZWQgcG9zdHMuCgkgKiAgICAgJCB3cCBwb3N0IGdlbmVyYXRlIC0tZm9ybWF0PWlkcyB8IHhhcmdzIC1kICcgJyAtSSAlIHdwIHBvc3QgbWV0YSBhZGQgJSBmb28gYmFyCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICogICAgIFN1Y2Nlc3M6IEFkZGVkIGN1c3RvbSBmaWVsZC4KCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJGRlZmF1bHRzID0gWwoJCQknY291bnQnICAgICAgICAgPT4gMTAwLAoJCQknbWF4X2RlcHRoJyAgICAgPT4gMSwKCQkJJ3Bvc3RfdHlwZScgICAgID0+ICdwb3N0JywKCQkJJ3Bvc3Rfc3RhdHVzJyAgID0+ICdwdWJsaXNoJywKCQkJJ3Bvc3RfYXV0aG9yJyAgID0+IGZhbHNlLAoJCQkncG9zdF9kYXRlJyAgICAgPT4gZmFsc2UsCgkJCSdwb3N0X2RhdGVfZ210JyA9PiBmYWxzZSwKCQkJJ3Bvc3RfY29udGVudCcgID0+ICcnLAoJCQkncG9zdF90aXRsZScgICAgPT4gJycsCgkJXTsKCgkJJHBvc3RfZGF0YSA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRjYWxsX3RpbWUgPSBjdXJyZW50X3RpbWUoICdteXNxbCcgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHBvc3RfZGF0YVsncG9zdF9kYXRlX2dtdCddICkgewoJCQkkcG9zdF9kYXRhWydwb3N0X2RhdGVfZ210J10gPSAkcG9zdF9kYXRhWydwb3N0X2RhdGUnXSA/OiAkY2FsbF90aW1lOwoJCX0KCgkJaWYgKCBmYWxzZSA9PT0gJHBvc3RfZGF0YVsncG9zdF9kYXRlJ10gKSB7CgkJCSRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZSddID0gJHBvc3RfZGF0YVsncG9zdF9kYXRlX2dtdCddID86ICRjYWxsX3RpbWU7CgkJfQoKCQlpZiAoICEgcG9zdF90eXBlX2V4aXN0cyggJHBvc3RfZGF0YVsncG9zdF90eXBlJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIid7JHBvc3RfZGF0YVsncG9zdF90eXBlJ119JyBpcyBub3QgYSByZWdpc3RlcmVkIHBvc3QgdHlwZS4iICk7CgkJfQoKCQlpZiAoICRwb3N0X2RhdGFbJ3Bvc3RfYXV0aG9yJ10gKSB7CgkJCSR1c2VyX2ZldGNoZXIgICAgICAgICAgICAgPSBuZXcgVXNlckZldGNoZXIoKTsKCQkJJHBvc3RfZGF0YVsncG9zdF9hdXRob3InXSA9ICR1c2VyX2ZldGNoZXItPmdldF9jaGVjayggJHBvc3RfZGF0YVsncG9zdF9hdXRob3InXSApLT5JRDsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncG9zdF9jb250ZW50JyApICkgewoJCQlpZiAoICEgRW50aXR5VXRpbHM6Omhhc19zdGRpbigpICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBwYXJhbWV0ZXIgYHBvc3RfY29udGVudGAgcmVhZHMgZnJvbSBTVERJTi4nICk7CgkJCX0KCgkJCSRwb3N0X2RhdGFbJ3Bvc3RfY29udGVudCddID0gZmlsZV9nZXRfY29udGVudHMoICdwaHA6Ly9zdGRpbicgKTsKCQl9CgoJCS8vIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIHBvc3RzLgoJCSR0b3RhbCA9ICR3cGRiLT5nZXRfdmFyKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCBDT1VOVCgqKSBGUk9NICR3cGRiLT5wb3N0cyBXSEVSRSBwb3N0X3R5cGUgPSAlcyIsICRwb3N0X2RhdGFbJ3Bvc3RfdHlwZSddICkgKTsKCgkJJGxhYmVsID0gISBlbXB0eSggJHBvc3RfZGF0YVsncG9zdF90aXRsZSddICkKCQkJPyAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10KCQkJOiBnZXRfcG9zdF90eXBlX29iamVjdCggJHBvc3RfZGF0YVsncG9zdF90eXBlJ10gKS0+bGFiZWxzLT5zaW5ndWxhcl9uYW1lOwoKCQkkaGllcmFyY2hpY2FsID0gZ2V0X3Bvc3RfdHlwZV9vYmplY3QoICRwb3N0X2RhdGFbJ3Bvc3RfdHlwZSddICktPmhpZXJhcmNoaWNhbDsKCgkJJGxpbWl0ID0gJHBvc3RfZGF0YVsnY291bnQnXSArICR0b3RhbDsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcsICdwcm9ncmVzcycgKTsKCgkJJG5vdGlmeSA9IGZhbHNlOwoJCWlmICggJ3Byb2dyZXNzJyA9PT0gJGZvcm1hdCApIHsKCQkJJG5vdGlmeSA9IFV0aWxzXG1ha2VfcHJvZ3Jlc3NfYmFyKCAnR2VuZXJhdGluZyBwb3N0cycsICRwb3N0X2RhdGFbJ2NvdW50J10gKTsKCQl9CgoJCSRwcmV2aW91c19wb3N0X2lkID0gMDsKCQkkY3VycmVudF9kZXB0aCAgICA9IDE7CgkJJGN1cnJlbnRfcGFyZW50ICAgPSAwOwoKCQlmb3IgKCAkaW5kZXggPSAkdG90YWw7ICRpbmRleCA8ICRsaW1pdDsgJGluZGV4KysgKSB7CgoJCQlpZiAoICRoaWVyYXJjaGljYWwgKSB7CgoJCQkJaWYgKCAkdGhpcy0+bWF5YmVfbWFrZV9jaGlsZCgpICYmICRjdXJyZW50X2RlcHRoIDwgJHBvc3RfZGF0YVsnbWF4X2RlcHRoJ10gKSB7CgoJCQkJCSRjdXJyZW50X3BhcmVudCA9ICRwcmV2aW91c19wb3N0X2lkOwoJCQkJCSRjdXJyZW50X2RlcHRoKys7CgoJCQkJfSBlbHNlaWYgKCAkdGhpcy0+bWF5YmVfcmVzZXRfZGVwdGgoKSApIHsKCgkJCQkJJGN1cnJlbnRfZGVwdGggID0gMTsKCQkJCQkkY3VycmVudF9wYXJlbnQgPSAwOwoKCQkJCX0KCQkJfQoKCQkJJGFyZ3MgPSBbCgkJCQkncG9zdF90eXBlJyAgICAgPT4gJHBvc3RfZGF0YVsncG9zdF90eXBlJ10sCgkJCQkncG9zdF90aXRsZScgICAgPT4gKCAhIGVtcHR5KCAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10gKSAmJiAkaW5kZXggPT09ICR0b3RhbCApCgkJCQkJPyAkbGFiZWwKCQkJCQk6ICJ7JGxhYmVsfSB7JGluZGV4fSIsCgkJCQkncG9zdF9zdGF0dXMnICAgPT4gJHBvc3RfZGF0YVsncG9zdF9zdGF0dXMnXSwKCQkJCSdwb3N0X2F1dGhvcicgICA9PiAkcG9zdF9kYXRhWydwb3N0X2F1dGhvciddLAoJCQkJJ3Bvc3RfcGFyZW50JyAgID0+ICRjdXJyZW50X3BhcmVudCwKCQkJCSdwb3N0X25hbWUnICAgICA9PiAhIGVtcHR5KCAkcG9zdF9kYXRhWydwb3N0X3RpdGxlJ10gKQoJCQkJCT8gc2FuaXRpemVfdGl0bGUoICRwb3N0X2RhdGFbJ3Bvc3RfdGl0bGUnXSAuICggJGluZGV4ID09PSAkdG90YWwgPyAnJyA6ICIteyRpbmRleH0iICkgKQoJCQkJCTogInBvc3QteyRpbmRleH0iLAoJCQkJJ3Bvc3RfZGF0ZScgICAgID0+ICRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZSddLAoJCQkJJ3Bvc3RfZGF0ZV9nbXQnID0+ICRwb3N0X2RhdGFbJ3Bvc3RfZGF0ZV9nbXQnXSwKCQkJCSdwb3N0X2NvbnRlbnQnICA9PiAkcG9zdF9kYXRhWydwb3N0X2NvbnRlbnQnXSwKCQkJXTsKCgkJCSRwb3N0X2lkID0gd3BfaW5zZXJ0X3Bvc3QoICRhcmdzLCB0cnVlICk7CgkJCWlmICggaXNfd3BfZXJyb3IoICRwb3N0X2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRwb3N0X2lkICk7CgkJCX0gZWxzZSB7CgkJCQkkcHJldmlvdXNfcG9zdF9pZCA9ICRwb3N0X2lkOwoJCQkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdCApIHsKCQkJCQllY2hvICRwb3N0X2lkOwoJCQkJCWlmICggJGluZGV4IDwgJGxpbWl0IC0gMSApIHsKCQkJCQkJZWNobyAnICc7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoICdwcm9ncmVzcycgPT09ICRmb3JtYXQgKSB7CgkJCQkkbm90aWZ5LT50aWNrKCk7CgkJCX0KCQl9CgkJaWYgKCAncHJvZ3Jlc3MnID09PSAkZm9ybWF0ICkgewoJCQkkbm90aWZ5LT5maW5pc2goKTsKCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9tYWtlX2NoaWxkKCkgewoJCS8vIDUwJSBjaGFuY2Ugb2YgbWFraW5nIGNoaWxkIHBvc3QuCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMiApID09PSAxICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBtYXliZV9yZXNldF9kZXB0aCgpIHsKCQkvLyAxMCUgY2hhbmNlIG9mIHJlc2V0aW5nIHRvIHJvb3QgZGVwdGgsCgkJcmV0dXJuICggd3BfcmFuZCggMSwgMTAgKSA9PT0gNyApOwoJfQoKCS8qKgoJICogUmVhZCBwb3N0IGNvbnRlbnQgZnJvbSBmaWxlIG9yIFNURElOCgkgKgoJICogQHBhcmFtIHN0cmluZyAkYXJnIFN1cHBsaWVkIGFyZ3VtZW50CgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlYWRfZnJvbV9maWxlX29yX3N0ZGluKCAkYXJnICkgewoJCWlmICggJy0nICE9PSAkYXJnICkgewoJCQkkcmVhZGZpbGUgPSAkYXJnOwoJCQlpZiAoICEgZmlsZV9leGlzdHMoICRyZWFkZmlsZSApIHx8ICEgaXNfZmlsZSggJHJlYWRmaWxlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiVW5hYmxlIHRvIHJlYWQgY29udGVudCBmcm9tICd7JHJlYWRmaWxlfScuIiApOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHJlYWRmaWxlID0gJ3BocDovL3N0ZGluJzsKCQl9CgkJcmV0dXJuIGZpbGVfZ2V0X2NvbnRlbnRzKCAkcmVhZGZpbGUgKTsKCX0KCgkvKioKCSAqIFJlc29sdmVzIHBvc3RfY2F0ZWdvcnkgYXJnIGludG8gYW4gYXJyYXkgb2YgY2F0ZWdvcnkgaWRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGFyZyBTdXBwbGllZCBhcmd1bWVudC4KCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY2F0ZWdvcnlfaWRzKCAkYXJnICkgewoKCQkkY2F0ZWdvcmllcyAgID0gZXhwbG9kZSggJywnLCAkYXJnICk7CgkJJGNhdGVnb3J5X2lkcyA9IFtdOwoJCWZvcmVhY2ggKCAkY2F0ZWdvcmllcyBhcyAkcG9zdF9jYXRlZ29yeSApIHsKCQkJaWYgKCB0cmltKCAkcG9zdF9jYXRlZ29yeSApICkgewoJCQkJaWYgKCBpc19udW1lcmljKCAkcG9zdF9jYXRlZ29yeSApICYmIChpbnQpICRwb3N0X2NhdGVnb3J5ICkgewoJCQkJCSRjYXRlZ29yeV9pZCA9IGNhdGVnb3J5X2V4aXN0cyggKGludCkgJHBvc3RfY2F0ZWdvcnkgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGNhdGVnb3J5X2lkID0gY2F0ZWdvcnlfZXhpc3RzKCAkcG9zdF9jYXRlZ29yeSApOwoJCQkJfQoJCQkJaWYgKCAhICRjYXRlZ29yeV9pZCApIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAiTm8gc3VjaCBwb3N0IGNhdGVnb3J5ICd7JHBvc3RfY2F0ZWdvcnl9Jy4iICk7CgkJCQl9CgkJCQkkY2F0ZWdvcnlfaWRzW10gPSAkY2F0ZWdvcnlfaWQ7CgkJCX0KCQl9CgkJLy8gSWYgbm8gY2F0ZWdvcnkgaWRzIGZvdW5kLCByZXR1cm4gZXhwbG9kZWQgYXJyYXkgZm9yIGNvbXBhdCB3aXRoIHByZXZpb3VzIFdQLUNMSSB2ZXJzaW9ucy4KCQlyZXR1cm4gJGNhdGVnb3J5X2lkcyA/OiAkY2F0ZWdvcmllczsKCX0KCgkvKioKCSAqIEdldCBwb3N0IG1ldGFkYXRhLgoJICoKCSAqIEBwYXJhbSAkcG9zdF9pZCBJRCBvZiB0aGUgcG9zdC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X21ldGFkYXRhKCAkcG9zdF9pZCApIHsKCQkkbWV0YWRhdGEgPSBnZXRfbWV0YWRhdGEoICdwb3N0JywgJHBvc3RfaWQgKTsKCQkkaXRlbXMgICAgPSBbXTsKCQlmb3JlYWNoICggJG1ldGFkYXRhIGFzICRrZXkgPT4gJHZhbHVlcyApIHsKCQkJZm9yZWFjaCAoICR2YWx1ZXMgYXMgJGl0ZW1fdmFsdWUgKSB7CgkJCQkkaXRlbV92YWx1ZSAgICA9IG1heWJlX3Vuc2VyaWFsaXplKCAkaXRlbV92YWx1ZSApOwoJCQkJJGl0ZW1zWyAka2V5IF0gPSAkaXRlbV92YWx1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuICRpdGVtczsKCX0KCgkvKioKCSAqIEdldCBDYXRlZ29yaWVzIG9mIGEgcG9zdC4KCSAqCgkgKiBAcGFyYW0gJHBvc3RfaWQgSUQgb2YgdGhlIHBvc3QuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jYXRlZ29yeSggJHBvc3RfaWQgKSB7CgkJJGNhdGVnb3J5X2RhdGEgPSBnZXRfdGhlX2NhdGVnb3J5KCAkcG9zdF9pZCApOwoJCSRjYXRlZ29yeV9hcnIgID0gW107CgkJZm9yZWFjaCAoICRjYXRlZ29yeV9kYXRhIGFzICRjYXQgKSB7CgkJCWFycmF5X3B1c2goICRjYXRlZ29yeV9hcnIsICRjYXQtPnRlcm1faWQgKTsKCQl9CgoJCXJldHVybiAkY2F0ZWdvcnlfYXJyOwoJfQoKCS8qKgoJICogR2V0IFRhZ3Mgb2YgYSBwb3N0LgoJICoKCSAqIEBwYXJhbSAkcG9zdF9pZCBJRCBvZiB0aGUgcG9zdC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3RhZ3MoICRwb3N0X2lkICkgewoJCSR0YWdfZGF0YSA9IGdldF90aGVfdGFncyggJHBvc3RfaWQgKTsKCQkkdGFnX2FyciAgPSBbXTsKCQlpZiAoICR0YWdfZGF0YSApIHsKCQkJZm9yZWFjaCAoICR0YWdfZGF0YSBhcyAkdGFnICkgewoJCQkJYXJyYXlfcHVzaCggJHRhZ19hcnIsICR0YWctPnNsdWcgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICR0YWdfYXJyOwoJfQoKCS8qKgoJICogVmVyaWZpZXMgd2hldGhlciBhIHBvc3QgZXhpc3RzLgoJICoKCSAqIERpc3BsYXlzIGEgc3VjY2VzcyBtZXNzYWdlIGlmIHRoZSBwb3N0IGRvZXMgZXhpc3QuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxpZD4KCSAqIDogVGhlIElEIG9mIHRoZSBwb3N0IHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVGhlIHBvc3QgZXhpc3RzLgoJICogICAgICQgd3AgcG9zdCBleGlzdHMgMQoJICogICAgIFN1Y2Nlc3M6IFBvc3Qgd2l0aCBJRCAxMzM3IGV4aXN0cy4KCSAqICAgICAkIGVjaG8gJD8KCSAqICAgICAwCgkgKgoJICogICAgICMgVGhlIHBvc3QgZG9lcyBub3QgZXhpc3QuCgkgKiAgICAgJCB3cCBwb3N0IGV4aXN0cyAxMDAwMAoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGV4aXN0cyggJGFyZ3MgKSB7CgkJaWYgKCAkdGhpcy0+ZmV0Y2hlci0+Z2V0KCAkYXJnc1swXSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJQb3N0IHdpdGggSUQgeyRhcmdzWzBdfSBleGlzdHMuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aERCT2JqZWN0Owp1c2UgV1BfQ0xJXEZldGNoZXJzXFNpdGUgYXMgU2l0ZUZldGNoZXI7CnVzZSBXUF9DTElcSXRlcmF0b3JzXFF1ZXJ5IGFzIFF1ZXJ5SXRlcmF0b3I7CnVzZSBXUF9DTElcSXRlcmF0b3JzXFRhYmxlIGFzIFRhYmxlSXRlcmF0b3I7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwoKLyoqCiAqIENyZWF0ZXMsIGRlbGV0ZXMsIGVtcHRpZXMsIG1vZGVyYXRlcywgYW5kIGxpc3RzIG9uZSBvciBtb3JlIHNpdGVzIG9uIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgQ3JlYXRlIHNpdGUKICogICAgICQgd3Agc2l0ZSBjcmVhdGUgLS1zbHVnPWV4YW1wbGUKICogICAgIFN1Y2Nlc3M6IFNpdGUgMyBjcmVhdGVkOiB3d3cuZXhhbXBsZS5jb20vZXhhbXBsZS8KICoKICogICAgICMgT3V0cHV0IGEgc2ltcGxlIGxpc3Qgb2Ygc2l0ZSBVUkxzCiAqICAgICAkIHdwIHNpdGUgbGlzdCAtLWZpZWxkPXVybAogKiAgICAgaHR0cDovL3d3dy5leGFtcGxlLmNvbS8KICogICAgIGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vc3ViZGlyLwogKgogKiAgICAgIyBEZWxldGUgc2l0ZQogKiAgICAgJCB3cCBzaXRlIGRlbGV0ZSAxMjMKICogICAgIEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlICdodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGUnIHNpdGU/IFt5L25dIHkKICogICAgIFN1Y2Nlc3M6IFRoZSBzaXRlIGF0ICdodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGUnIHdhcyBkZWxldGVkLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFNpdGVfQ29tbWFuZCBleHRlbmRzIENvbW1hbmRXaXRoREJPYmplY3QgewoKCXByb3RlY3RlZCAkb2JqX3R5cGUgICA9ICdzaXRlJzsKCXByb3RlY3RlZCAkb2JqX2lkX2tleSA9ICdibG9nX2lkJzsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgU2l0ZUZldGNoZXIoKTsKCX0KCgkvKioKCSAqIERlbGV0ZSBjb21tZW50cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBlbXB0eV9jb21tZW50cygpIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIEVtcHR5IGNvbW1lbnRzIGFuZCBjb21tZW50IGNhY2hlCgkJJGNvbW1lbnRfaWRzID0gJHdwZGItPmdldF9jb2woICJTRUxFQ1QgY29tbWVudF9JRCBGUk9NICR3cGRiLT5jb21tZW50cyIgKTsKCQlmb3JlYWNoICggJGNvbW1lbnRfaWRzIGFzICRjb21tZW50X2lkICkgewoJCQl3cF9jYWNoZV9kZWxldGUoICRjb21tZW50X2lkLCAnY29tbWVudCcgKTsKCQkJd3BfY2FjaGVfZGVsZXRlKCAkY29tbWVudF9pZCwgJ2NvbW1lbnRfbWV0YScgKTsKCQl9CgkJJHdwZGItPnF1ZXJ5KCAiVFJVTkNBVEUgJHdwZGItPmNvbW1lbnRzIiApOwoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT5jb21tZW50bWV0YSIgKTsKCX0KCgkvKioKCSAqIERlbGV0ZSBhbGwgcG9zdHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZW1wdHlfcG9zdHMoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBFbXB0eSBwb3N0cyBhbmQgcG9zdCBjYWNoZQoJCSRwb3N0c19xdWVyeSA9ICJTRUxFQ1QgSUQgRlJPTSAkd3BkYi0+cG9zdHMiOwoJCSRwb3N0cyAgICAgICA9IG5ldyBRdWVyeUl0ZXJhdG9yKCAkcG9zdHNfcXVlcnksIDEwMDAwICk7CgoJCSR0YXhvbm9taWVzID0gZ2V0X3RheG9ub21pZXMoKTsKCgkJd2hpbGUgKCAkcG9zdHMtPnZhbGlkKCkgKSB7CgkJCSRwb3N0X2lkID0gJHBvc3RzLT5jdXJyZW50KCktPklEOwoKCQkJd3BfY2FjaGVfZGVsZXRlKCAkcG9zdF9pZCwgJ3Bvc3RzJyApOwoJCQl3cF9jYWNoZV9kZWxldGUoICRwb3N0X2lkLCAncG9zdF9tZXRhJyApOwoJCQlmb3JlYWNoICggJHRheG9ub21pZXMgYXMgJHRheG9ub215ICkgewoJCQkJd3BfY2FjaGVfZGVsZXRlKCAkcG9zdF9pZCwgInskdGF4b25vbXl9X3JlbGF0aW9uc2hpcHMiICk7CgkJCX0KCQkJd3BfY2FjaGVfZGVsZXRlKCAkd3BkYi0+YmxvZ2lkIC4gJy0nIC4gJHBvc3RfaWQsICdnbG9iYWwtcG9zdHMnICk7CgoJCQkkcG9zdHMtPm5leHQoKTsKCQl9CgkJJHdwZGItPnF1ZXJ5KCAiVFJVTkNBVEUgJHdwZGItPnBvc3RzIiApOwoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT5wb3N0bWV0YSIgKTsKCX0KCgkvKioKCSAqIERlbGV0ZSB0ZXJtcywgdGF4b25vbWllcywgYW5kIHRheCByZWxhdGlvbnNoaXBzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGVtcHR5X3RheG9ub21pZXMoKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBFbXB0eSB0YXhvbm9taWVzIGFuZCB0ZXJtcwoJCSR0ZXJtcyAgICAgID0gJHdwZGItPmdldF9yZXN1bHRzKCAiU0VMRUNUIHRlcm1faWQsIHRheG9ub215IEZST00gJHdwZGItPnRlcm1fdGF4b25vbXkiICk7CgkJJHRheG9ub21pZXMgPSBbXTsKCQlmb3JlYWNoICggKGFycmF5KSAkdGVybXMgYXMgJHRlcm0gKSB7CgkJCSR0YXhvbm9taWVzW10gPSAkdGVybS0+dGF4b25vbXk7CgkJCXdwX2NhY2hlX2RlbGV0ZSggJHRlcm0tPnRlcm1faWQsICR0ZXJtLT50YXhvbm9teSApOwoJCX0KCgkJJHRheG9ub21pZXMgPSBhcnJheV91bmlxdWUoICR0YXhvbm9taWVzICk7CgkJJGNsZWFuZWQgICAgPSBbXTsKCQlmb3JlYWNoICggJHRheG9ub21pZXMgYXMgJHRheG9ub215ICkgewoJCQlpZiAoIGlzc2V0KCAkY2xlYW5lZFsgJHRheG9ub215IF0gKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCSRjbGVhbmVkWyAkdGF4b25vbXkgXSA9IHRydWU7CgoJCQl3cF9jYWNoZV9kZWxldGUoICdhbGxfaWRzJywgJHRheG9ub215ICk7CgkJCXdwX2NhY2hlX2RlbGV0ZSggJ2dldCcsICR0YXhvbm9teSApOwoJCQlkZWxldGVfb3B0aW9uKCAieyR0YXhvbm9teX1fY2hpbGRyZW4iICk7CgkJfQoJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT50ZXJtcyIgKTsKCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+dGVybV90YXhvbm9teSIgKTsKCQkkd3BkYi0+cXVlcnkoICJUUlVOQ0FURSAkd3BkYi0+dGVybV9yZWxhdGlvbnNoaXBzIiApOwoJCWlmICggISBlbXB0eSggJHdwZGItPnRlcm1tZXRhICkgKSB7CgkJCSR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR3cGRiLT50ZXJtbWV0YSIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEZWxldGUgYWxsIGxpbmtzLCBsaW5rX2NhdGVnb3J5IHRlcm1zLCBhbmQgcmVsYXRlZCBjYWNoZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBlbXB0eV9saW5rcygpIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIFJlbW92ZSBsaW5rcyBhbmQgcmVsYXRlZCBjYWNoZWQgZGF0YS4KCQkkbGlua3NfcXVlcnkgPSAiU0VMRUNUIGxpbmtfaWQgRlJPTSB7JHdwZGItPmxpbmtzfSI7CgkJJGxpbmtzICAgICAgID0gbmV3IFF1ZXJ5SXRlcmF0b3IoICRsaW5rc19xdWVyeSwgMTAwMDAgKTsKCgkJLy8gUmVtb3ZlIGJvb2ttYXJrcyBjYWNoZSBncm91cC4KCQl3cF9jYWNoZV9kZWxldGUoICdnZXRfYm9va21hcmtzJywgJ2Jvb2ttYXJrJyApOwoKCQl3aGlsZSAoICRsaW5rcy0+dmFsaWQoKSApIHsKCQkJJGxpbmtfaWQgPSAkbGlua3MtPmN1cnJlbnQoKS0+bGlua19pZDsKCgkJCS8vIFJlbW92ZSBjYWNoZSBmb3IgdGhlIGxpbmsuCgkJCXdwX2RlbGV0ZV9vYmplY3RfdGVybV9yZWxhdGlvbnNoaXBzKCAkbGlua19pZCwgJ2xpbmtfY2F0ZWdvcnknICk7CgkJCXdwX2NhY2hlX2RlbGV0ZSggJGxpbmtfaWQsICdib29rbWFyaycgKTsKCQkJY2xlYW5fb2JqZWN0X3Rlcm1fY2FjaGUoICRsaW5rX2lkLCAnbGluaycgKTsKCgkJCSRsaW5rcy0+bmV4dCgpOwoJCX0KCgkJLy8gRW1wdHkgdGhlIHRhYmxlIG9uY2UgbGluayByZWxhdGVkIGNhY2hlIGFuZCB0ZXJtIGlzIHJlbW92ZWQuCgkJJHdwZGItPnF1ZXJ5KCAiVFJVTkNBVEUgeyR3cGRiLT5saW5rc30iICk7Cgl9CgoJLyoqCgkgKiBJbnNlcnQgZGVmYXVsdCB0ZXJtcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpbnNlcnRfZGVmYXVsdF90ZXJtcygpIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIERlZmF1bHQgY2F0ZWdvcnkKCQkkY2F0X25hbWUgPSBfXyggJ1VuY2F0ZWdvcml6ZWQnICk7CgoJCS8qIHRyYW5zbGF0b3JzOiBEZWZhdWx0IGNhdGVnb3J5IHNsdWcgKi8KCQkkY2F0X3NsdWcgPSBzYW5pdGl6ZV90aXRsZSggX3goICdVbmNhdGVnb3JpemVkJywgJ0RlZmF1bHQgY2F0ZWdvcnkgc2x1ZycgKSApOwoKCQlpZiAoIGdsb2JhbF90ZXJtc19lbmFibGVkKCkgKSB7CgkJCSRjYXRfaWQgPSAkd3BkYi0+Z2V0X3ZhciggJHdwZGItPnByZXBhcmUoICJTRUxFQ1QgY2F0X0lEIEZST00geyR3cGRiLT5zaXRlY2F0ZWdvcmllc30gV0hFUkUgY2F0ZWdvcnlfbmljZW5hbWUgPSAlcyIsICRjYXRfc2x1ZyApICk7CgkJCWlmICggbnVsbCA9PT0gJGNhdF9pZCApIHsKCQkJCSR3cGRiLT5pbnNlcnQoCgkJCQkJJHdwZGItPnNpdGVjYXRlZ29yaWVzLAoJCQkJCVsKCQkJCQkJJ2NhdF9JRCcgICAgICAgICAgICA9PiAwLAoJCQkJCQknY2F0X25hbWUnICAgICAgICAgID0+ICRjYXRfbmFtZSwKCQkJCQkJJ2NhdGVnb3J5X25pY2VuYW1lJyA9PiAkY2F0X3NsdWcsCgkJCQkJCSdsYXN0X3VwZGF0ZWQnICAgICAgPT4gY3VycmVudF90aW1lKAoJCQkJCQkJJ215c3FsJywKCQkJCQkJCXRydWUKCQkJCQkJKSwKCQkJCQldCgkJCQkpOwoJCQkJJGNhdF9pZCA9ICR3cGRiLT5pbnNlcnRfaWQ7CgkJCX0KCQkJdXBkYXRlX29wdGlvbiggJ2RlZmF1bHRfY2F0ZWdvcnknLCAkY2F0X2lkICk7CgkJfSBlbHNlIHsKCQkJJGNhdF9pZCA9IDE7CgkJfQoKCQkkd3BkYi0+aW5zZXJ0KAoJCQkkd3BkYi0+dGVybXMsCgkJCVsKCQkJCSd0ZXJtX2lkJyAgICA9PiAkY2F0X2lkLAoJCQkJJ25hbWUnICAgICAgID0+ICRjYXRfbmFtZSwKCQkJCSdzbHVnJyAgICAgICA9PiAkY2F0X3NsdWcsCgkJCQkndGVybV9ncm91cCcgPT4gMCwKCQkJXQoJCSk7CgkJJHdwZGItPmluc2VydCgKCQkJJHdwZGItPnRlcm1fdGF4b25vbXksCgkJCVsKCQkJCSd0ZXJtX2lkJyAgICAgPT4gJGNhdF9pZCwKCQkJCSd0YXhvbm9teScgICAgPT4gJ2NhdGVnb3J5JywKCQkJCSdkZXNjcmlwdGlvbicgPT4gJycsCgkJCQkncGFyZW50JyAgICAgID0+IDAsCgkJCQknY291bnQnICAgICAgID0+IDAsCgkJCV0KCQkpOwoJfQoKCS8qKgoJICogUmVzZXQgb3B0aW9uIHZhbHVlcyB0byBkZWZhdWx0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlc2V0X29wdGlvbnMoKSB7CgkJLy8gUmVzZXQgUHJpdmFjeSBQb2xpY3kgdmFsdWUgdG8gcHJldmVudCBlcnJvci4KCQl1cGRhdGVfb3B0aW9uKCAnd3BfcGFnZV9mb3JfcHJpdmFjeV9wb2xpY3knLCAwICk7CgoJCS8vIFJlc2V0IHN0aWNreSBwb3N0cyBvcHRpb24uCgkJdXBkYXRlX29wdGlvbiggJ3N0aWNreV9wb3N0cycsIFtdICk7Cgl9CgoJLyoqCgkgKiBFbXB0aWVzIGEgc2l0ZSBvZiBpdHMgY29udGVudCAocG9zdHMsIGNvbW1lbnRzLCB0ZXJtcywgYW5kIG1ldGEpLgoJICoKCSAqIFRydW5jYXRlcyBwb3N0cywgY29tbWVudHMsIGFuZCB0ZXJtcyB0YWJsZXMgdG8gZW1wdHkgYSBzaXRlIG9mIGl0cwoJICogY29udGVudC4gRG9lc24ndCBhZmZlY3Qgc2l0ZSBjb25maWd1cmF0aW9uIChvcHRpb25zKSBvciB1c2Vycy4KCSAqCgkgKiBJZiBydW5uaW5nIGEgcGVyc2lzdGVudCBvYmplY3QgY2FjaGUsIG1ha2Ugc3VyZSB0byBmbHVzaCB0aGUgY2FjaGUKCSAqIGFmdGVyIGVtcHR5aW5nIHRoZSBzaXRlLCBhcyB0aGUgY2FjaGUgdmFsdWVzIHdpbGwgYmUgaW52YWxpZCBvdGhlcndpc2UuCgkgKgoJICogVG8gYWxzbyBlbXB0eSBjdXN0b20gZGF0YWJhc2UgdGFibGVzLCB5b3UnbGwgbmVlZCB0byBob29rIGludG8gY29tbWFuZAoJICogZXhlY3V0aW9uOgoJICoKCSAqIGBgYAoJICogV1BfQ0xJOjphZGRfaG9vayggJ2FmdGVyX2ludm9rZTpzaXRlIGVtcHR5JywgZnVuY3Rpb24oKXsKCSAqICAgICBnbG9iYWwgJHdwZGI7CgkgKiAgICAgZm9yZWFjaCggYXJyYXkoICdwMnAnLCAncDJwbWV0YScgKSBhcyAkdGFibGUgKSB7CgkgKiAgICAgICAgICR0YWJsZSA9ICR3cGRiLT4kdGFibGU7CgkgKiAgICAgICAgICR3cGRiLT5xdWVyeSggIlRSVU5DQVRFICR0YWJsZSIgKTsKCSAqICAgICB9CgkgKiB9KTsKCSAqIGBgYAoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS11cGxvYWRzXQoJICogOiBBbHNvIGRlbGV0ZSAqYWxsKiBmaWxlcyBpbiB0aGUgc2l0ZSdzIHVwbG9hZHMgZGlyZWN0b3J5LgoJICoKCSAqIFstLXllc10KCSAqIDogUHJvY2VlZCB0byBlbXB0eSB0aGUgc2l0ZSB3aXRob3V0IGEgY29uZmlybWF0aW9uIHByb21wdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgZW1wdHkKCSAqICAgICBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZW1wdHkgdGhlIHNpdGUgYXQgaHR0cDovL3d3dy5leGFtcGxlLmNvbSBvZiBhbGwgcG9zdHMsIGxpbmtzLCBjb21tZW50cywgYW5kIHRlcm1zPyBbeS9uXSB5CgkgKiAgICAgU3VjY2VzczogVGhlIHNpdGUgYXQgJ2h0dHA6Ly93d3cuZXhhbXBsZS5jb20nIHdhcyBlbXB0aWVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGVtcHR5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlbXB0eV8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJHVwbG9hZF9tZXNzYWdlID0gJyc7CgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd1cGxvYWRzJyApICkgewoJCQkkdXBsb2FkX21lc3NhZ2UgPSAnLCBhbmQgZGVsZXRlIGl0cyB1cGxvYWRzIGRpcmVjdG9yeSc7CgkJfQoKCQlXUF9DTEk6OmNvbmZpcm0oICJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZW1wdHkgdGhlIHNpdGUgYXQgJyIgLiBzaXRlX3VybCgpIC4gIicgb2YgYWxsIHBvc3RzLCBsaW5rcywgY29tbWVudHMsIGFuZCB0ZXJtcyIgLiAkdXBsb2FkX21lc3NhZ2UgLiAnPycsICRhc3NvY19hcmdzICk7CgoJCSR0aGlzLT5lbXB0eV9wb3N0cygpOwoJCSR0aGlzLT5lbXB0eV9saW5rcygpOwoJCSR0aGlzLT5lbXB0eV9jb21tZW50cygpOwoJCSR0aGlzLT5lbXB0eV90YXhvbm9taWVzKCk7CgkJJHRoaXMtPmluc2VydF9kZWZhdWx0X3Rlcm1zKCk7CgkJJHRoaXMtPnJlc2V0X29wdGlvbnMoKTsKCgkJaWYgKCAhIGVtcHR5KCAkdXBsb2FkX21lc3NhZ2UgKSApIHsKCQkJJHVwbG9hZF9kaXIgPSB3cF91cGxvYWRfZGlyKCk7CgkJCSRmaWxlcyAgICAgID0gbmV3IFJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3IoCgkJCQluZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoICR1cGxvYWRfZGlyWydiYXNlZGlyJ10sIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMgKSwKCQkJCVJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUCgkJCSk7CgoJCQkkZmlsZXNfdG9fdW5saW5rICAgICAgID0gW107CgkJCSRkaXJlY3Rvcmllc190b19kZWxldGUgPSBbXTsKCQkJJGlzX21haW5fc2l0ZSAgICAgICAgICA9IGlzX21haW5fc2l0ZSgpOwoJCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlaW5mbyApIHsKCQkJCSRyZWFscGF0aCA9ICRmaWxlaW5mby0+Z2V0UmVhbFBhdGgoKTsKCQkJCS8vIERvbid0IGNsb2JiZXIgc3Vic2l0ZXMgd2hlbiBvcGVyYXRpbmcgb24gdGhlIG1haW4gc2l0ZQoJCQkJaWYgKCAkaXNfbWFpbl9zaXRlICYmIGZhbHNlICE9PSBzdHJpcG9zKCAkcmVhbHBhdGgsICcvc2l0ZXMvJyApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJaWYgKCAkZmlsZWluZm8tPmlzRGlyKCkgKSB7CgkJCQkJJGRpcmVjdG9yaWVzX3RvX2RlbGV0ZVtdID0gJHJlYWxwYXRoOwoJCQkJfSBlbHNlIHsKCQkJCQkkZmlsZXNfdG9fdW5saW5rW10gPSAkcmVhbHBhdGg7CgkJCQl9CgkJCX0KCQkJZm9yZWFjaCAoICRmaWxlc190b191bmxpbmsgYXMgJGZpbGUgKSB7CgkJCQl1bmxpbmsoICRmaWxlICk7CgkJCX0KCQkJZm9yZWFjaCAoICRkaXJlY3Rvcmllc190b19kZWxldGUgYXMgJGRpcmVjdG9yeSApIHsKCQkJCS8vIERpcmVjdG9yeSBjb3VsZCBiZSBtYWluIHNpdGVzIGRpcmVjdG9yeSAnL3NpdGVzJyB3aGljaCBtYXkgYmUgbm9uLWVtcHR5LgoJCQkJQHJtZGlyKCAkZGlyZWN0b3J5ICk7CgkJCX0KCQkJLy8gTWF5IGJlIG5vbi1lbXB0eSBpZiAnL3NpdGVzJyBzdGlsbCBhcm91bmQuCgkJCUBybWRpciggJHVwbG9hZF9kaXJbJ2Jhc2VkaXInXSApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiVGhlIHNpdGUgYXQgJyIgLiBzaXRlX3VybCgpIC4gIicgd2FzIGVtcHRpZWQuIiApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBhIHNpdGUgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHNpdGUtaWQ+XQoJICogOiBUaGUgaWQgb2YgdGhlIHNpdGUgdG8gZGVsZXRlLiBJZiBub3QgcHJvdmlkZWQsIHlvdSBtdXN0IHNldCB0aGUgLS1zbHVnIHBhcmFtZXRlci4KCSAqCgkgKiBbLS1zbHVnPTxzbHVnPl0KCSAqIDogUGF0aCBvZiB0aGUgYmxvZyB0byBiZSBkZWxldGVkLiBTdWJkb21haW4gb24gc3ViZG9tYWluIGluc3RhbGxzLCBkaXJlY3Rvcnkgb24gc3ViZGlyZWN0b3J5IGluc3RhbGxzLgoJICoKCSAqIFstLXllc10KCSAqIDogQW5zd2VyIHllcyB0byB0aGUgY29uZmlybWF0aW9uIG1lc3NhZ2UuCgkgKgoJICogWy0ta2VlcC10YWJsZXNdCgkgKiA6IERlbGV0ZSB0aGUgYmxvZyBmcm9tIHRoZSBsaXN0LCBidXQgZG9uJ3QgZHJvcCBpdCdzIHRhYmxlcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgZGVsZXRlIDEyMwoJICogICAgIEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZSBzaXRlPyBbeS9uXSB5CgkgKiAgICAgU3VjY2VzczogVGhlIHNpdGUgYXQgJ2h0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZScgd2FzIGRlbGV0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3NsdWcnXSApICkgewoJCQkkYmxvZyA9IGdldF9ibG9nX2RldGFpbHMoIHRyaW0oICRhc3NvY19hcmdzWydzbHVnJ10sICcvJyApICk7CgkJfSBlbHNlIHsKCQkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdOZWVkIHRvIHNwZWNpZnkgYSBibG9nIGlkLicgKTsKCQkJfQoKCQkJJGJsb2dfaWQgPSAkYXJnc1swXTsKCgkJCWlmICggaXNfbWFpbl9zaXRlKCAkYmxvZ19pZCApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1lvdSBjYW5ub3QgZGVsZXRlIHRoZSByb290IHNpdGUuJyApOwoJCQl9CgoJCQkkYmxvZyA9IGdldF9ibG9nX2RldGFpbHMoICRibG9nX2lkICk7CgkJfQoKCQlpZiAoICEgJGJsb2cgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdTaXRlIG5vdCBmb3VuZC4nICk7CgkJfQoKCQkkc2l0ZV91cmwgPSB0cmFpbGluZ3NsYXNoaXQoICRibG9nLT5zaXRldXJsICk7CgoJCVdQX0NMSTo6Y29uZmlybSggIkFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlICd7JHNpdGVfdXJsfScgc2l0ZT8iLCAkYXNzb2NfYXJncyApOwoKCQl3cG11X2RlbGV0ZV9ibG9nKCAkYmxvZy0+YmxvZ19pZCwgISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdrZWVwLXRhYmxlcycgKSApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICJUaGUgc2l0ZSBhdCAneyRzaXRlX3VybH0nIHdhcyBkZWxldGVkLiIgKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBzaXRlIGluIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogLS1zbHVnPTxzbHVnPgoJICogOiBQYXRoIGZvciB0aGUgbmV3IHNpdGUuIFN1YmRvbWFpbiBvbiBzdWJkb21haW4gaW5zdGFsbHMsIGRpcmVjdG9yeSBvbiBzdWJkaXJlY3RvcnkgaW5zdGFsbHMuCgkgKgoJICogWy0tdGl0bGU9PHRpdGxlPl0KCSAqIDogVGl0bGUgb2YgdGhlIG5ldyBzaXRlLiBEZWZhdWx0OiBwcmV0dGlmaWVkIHNsdWcuCgkgKgoJICogWy0tZW1haWw9PGVtYWlsPl0KCSAqIDogRW1haWwgZm9yIEFkbWluIHVzZXIuIFVzZXIgd2lsbCBiZSBjcmVhdGVkIGlmIG5vbmUgZXhpc3RzLiBBc3NpZ25lbWVudCB0byBTdXBlciBBZG1pbiBpZiBub3QgaW5jbHVkZWQuCgkgKgoJICogWy0tbmV0d29ya19pZD08bmV0d29yay1pZD5dCgkgKiA6IE5ldHdvcmsgdG8gYXNzb2NpYXRlIG5ldyBzaXRlIHdpdGguIERlZmF1bHRzIHRvIGN1cnJlbnQgbmV0d29yayAodHlwaWNhbGx5IDEpLgoJICoKCSAqIFstLXByaXZhdGVdCgkgKiA6IElmIHNldCwgdGhlIG5ldyBzaXRlIHdpbGwgYmUgbm9uLXB1YmxpYyAobm90IGluZGV4ZWQpCgkgKgoJICogWy0tcG9yY2VsYWluXQoJICogOiBJZiBzZXQsIG9ubHkgdGhlIHNpdGUgaWQgd2lsbCBiZSBvdXRwdXQgb24gc3VjY2Vzcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgY3JlYXRlIC0tc2x1Zz1leGFtcGxlCgkgKiAgICAgU3VjY2VzczogU2l0ZSAzIGNyZWF0ZWQ6IGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZS8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJfQoKCQlnbG9iYWwgJHdwZGIsICRjdXJyZW50X3NpdGU7CgoJCSRiYXNlICA9ICRhc3NvY19hcmdzWydzbHVnJ107CgkJJHRpdGxlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndGl0bGUnLCB1Y2ZpcnN0KCAkYmFzZSApICk7CgoJCSRlbWFpbCA9IGVtcHR5KCAkYXNzb2NfYXJnc1snZW1haWwnXSApID8gJycgOiAkYXNzb2NfYXJnc1snZW1haWwnXTsKCgkJLy8gTmV0d29yawoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ25ldHdvcmtfaWQnXSApICkgewoJCQkkbmV0d29yayA9ICR0aGlzLT5nZXRfbmV0d29yayggJGFzc29jX2FyZ3NbJ25ldHdvcmtfaWQnXSApOwoJCQlpZiAoIGZhbHNlID09PSAkbmV0d29yayApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJOZXR3b3JrIHdpdGggaWQgeyRhc3NvY19hcmdzWyduZXR3b3JrX2lkJ119IGRvZXMgbm90IGV4aXN0LiIgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRuZXR3b3JrID0gJGN1cnJlbnRfc2l0ZTsKCQl9CgoJCSRwdWJsaWMgPSAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ByaXZhdGUnICk7CgoJCS8vIFNhbml0aXplCgkJaWYgKCBwcmVnX21hdGNoKCAnfF4oW2EtekEtWjAtOS1dKSskfCcsICRiYXNlICkgKSB7CgkJCSRiYXNlID0gc3RydG9sb3dlciggJGJhc2UgKTsKCQl9CgoJCS8vIElmIG5vdCBhIHN1YmRvbWFpbiBpbnN0YWxsLCBtYWtlIHN1cmUgdGhlIGRvbWFpbiBpc24ndCBhIHJlc2VydmVkIHdvcmQKCQlpZiAoICEgaXNfc3ViZG9tYWluX2luc3RhbGwoKSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIFdvcmRQcmVzcyBuYXRpdmUgaG9vay4KCQkJJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcyA9IGFwcGx5X2ZpbHRlcnMoICdzdWJkaXJlY3RvcnlfcmVzZXJ2ZWRfbmFtZXMnLCBbICdwYWdlJywgJ2NvbW1lbnRzJywgJ2Jsb2cnLCAnZmlsZXMnLCAnZmVlZCcgXSApOwoJCQlpZiAoIGluX2FycmF5KCAkYmFzZSwgJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcywgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoZSBmb2xsb3dpbmcgd29yZHMgYXJlIHJlc2VydmVkIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBibG9nIG5hbWVzOiAnIC4gaW1wbG9kZSggJywgJywgJHN1YmRpcmVjdG9yeV9yZXNlcnZlZF9uYW1lcyApICk7CgkJCX0KCQl9CgoJCS8vIENoZWNrIGZvciB2YWxpZCBlbWFpbCwgaWYgbm90LCB1c2UgdGhlIGZpcnN0IFN1cGVyIEFkbWluIGZvdW5kCgkJLy8gUHJvYmFibHkgYSBtb3JlIGVmZmljaWVudCB3YXkgdG8gZG8gdGhpcyBzbyB3ZSBkb250IHF1ZXJ5IGZvciB0aGUKCQkvLyBVc2VyIHR3aWNlIGlmIHN1cGVyIGFkbWluCgkJJGVtYWlsID0gc2FuaXRpemVfZW1haWwoICRlbWFpbCApOwoJCWlmICggZW1wdHkoICRlbWFpbCApIHx8ICEgaXNfZW1haWwoICRlbWFpbCApICkgewoJCQkkc3VwZXJfYWRtaW5zID0gZ2V0X3N1cGVyX2FkbWlucygpOwoJCQkkZW1haWwgICAgICAgID0gJyc7CgkJCWlmICggISBlbXB0eSggJHN1cGVyX2FkbWlucyApICYmIGlzX2FycmF5KCAkc3VwZXJfYWRtaW5zICkgKSB7CgkJCQkvLyBKdXN0IGdldCB0aGUgZmlyc3Qgb25lCgkJCQkkc3VwZXJfbG9naW4gPSAkc3VwZXJfYWRtaW5zWzBdOwoJCQkJJHN1cGVyX3VzZXIgID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRzdXBlcl9sb2dpbiApOwoJCQkJaWYgKCAkc3VwZXJfdXNlciApIHsKCQkJCQkkZW1haWwgPSAkc3VwZXJfdXNlci0+dXNlcl9lbWFpbDsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCBpc19zdWJkb21haW5faW5zdGFsbCgpICkgewoJCQkkbmV3ZG9tYWluID0gJGJhc2UgLiAnLicgLiBwcmVnX3JlcGxhY2UoICd8Xnd3d1wufCcsICcnLCAkY3VycmVudF9zaXRlLT5kb21haW4gKTsKCQkJJHBhdGggICAgICA9ICRjdXJyZW50X3NpdGUtPnBhdGg7CgkJfSBlbHNlIHsKCQkJJG5ld2RvbWFpbiA9ICRjdXJyZW50X3NpdGUtPmRvbWFpbjsKCQkJJHBhdGggICAgICA9ICRjdXJyZW50X3NpdGUtPnBhdGggLiAkYmFzZSAuICcvJzsKCQl9CgoJCSR1c2VyX2lkID0gZW1haWxfZXhpc3RzKCAkZW1haWwgKTsKCQlpZiAoICEgJHVzZXJfaWQgKSB7IC8vIENyZWF0ZSBhIG5ldyB1c2VyIHdpdGggYSByYW5kb20gcGFzc3dvcmQKCQkJJHBhc3N3b3JkID0gd3BfZ2VuZXJhdGVfcGFzc3dvcmQoIDEyLCBmYWxzZSApOwoJCQkkdXNlcl9pZCAgPSB3cG11X2NyZWF0ZV91c2VyKCAkYmFzZSwgJHBhc3N3b3JkLCAkZW1haWwgKTsKCQkJaWYgKCBmYWxzZSA9PT0gJHVzZXJfaWQgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ2FuJ3QgY3JlYXRlIHVzZXIuIiApOwoJCQl9IGVsc2UgewoJCQkJVXNlcl9Db21tYW5kOjp3cF9uZXdfdXNlcl9ub3RpZmljYXRpb24oICR1c2VyX2lkLCAkcGFzc3dvcmQgKTsKCQkJfQoJCX0KCgkJJHdwZGItPmhpZGVfZXJyb3JzKCk7CgkJJHRpdGxlID0gd3Bfc2xhc2goICR0aXRsZSApOwoJCSRpZCAgICA9IHdwbXVfY3JlYXRlX2Jsb2coICRuZXdkb21haW4sICRwYXRoLCAkdGl0bGUsICR1c2VyX2lkLCBbICdwdWJsaWMnID0+ICRwdWJsaWMgXSwgJG5ldHdvcmstPmlkICk7CgkJJHdwZGItPnNob3dfZXJyb3JzKCk7CgkJaWYgKCAhIGlzX3dwX2Vycm9yKCAkaWQgKSApIHsKCQkJaWYgKCAhIGlzX3N1cGVyX2FkbWluKCAkdXNlcl9pZCApICYmICEgZ2V0X3VzZXJfb3B0aW9uKCAncHJpbWFyeV9ibG9nJywgJHVzZXJfaWQgKSApIHsKCQkJCXVwZGF0ZV91c2VyX29wdGlvbiggJHVzZXJfaWQsICdwcmltYXJ5X2Jsb2cnLCAkaWQsIHRydWUgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRpZC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwb3JjZWxhaW4nICkgKSB7CgkJCVdQX0NMSTo6bGluZSggJGlkICk7CgkJfSBlbHNlIHsKCQkJJHNpdGVfdXJsID0gdHJhaWxpbmdzbGFzaGl0KCBnZXRfc2l0ZV91cmwoICRpZCApICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlNpdGUgeyRpZH0gY3JlYXRlZDogeyRzaXRlX3VybH0iICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBuZXR3b3JrIGRhdGEgZm9yIGEgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIGludCAgICAgJG5ldHdvcmtfaWQKCSAqIEByZXR1cm4gYm9vbHxhcnJheSBGYWxzZSBpZiBubyBuZXR3b3JrIGZvdW5kIHdpdGggZ2l2ZW4gaWQsIGFycmF5IG90aGVyd2lzZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9uZXR3b3JrKCAkbmV0d29ya19pZCApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIExvYWQgbmV0d29yayBkYXRhCgkJJG5ldHdvcmtzID0gJHdwZGItPmdldF9yZXN1bHRzKAoJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCSJTRUxFQ1QgKiBGUk9NICR3cGRiLT5zaXRlIFdIRVJFIGlkID0gJWQiLAoJCQkJJG5ldHdvcmtfaWQKCQkJKQoJCSk7CgoJCWlmICggISBlbXB0eSggJG5ldHdvcmtzICkgKSB7CgkJCS8vIE9ubHkgY2FyZSBhYm91dCBkb21haW4gYW5kIHBhdGggd2hpY2ggYXJlIHNldCBoZXJlCgkJCXJldHVybiAkbmV0d29ya3NbMF07CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBMaXN0cyBhbGwgc2l0ZXMgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1uZXR3b3JrPTxpZD5dCgkgKiA6IFRoZSBuZXR3b3JrIHRvIHdoaWNoIHRoZSBzaXRlcyBiZWxvbmcuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgYnkgb25lIG9yIG1vcmUgZmllbGRzIChzZWUgIkF2YWlsYWJsZSBGaWVsZHMiIHNlY3Rpb24pLiBIb3dldmVyLAoJICogJ3VybCcgaXNuJ3QgYW4gYXZhaWxhYmxlIGZpbHRlciwgYmVjYXVzZSBpdCdzIGNyZWF0ZWQgZnJvbSBkb21haW4gKyBwYXRoLgoJICoKCSAqIFstLXNpdGVfX2luPTx2YWx1ZT5dCgkgKiA6IE9ubHkgbGlzdCB0aGUgc2l0ZXMgd2l0aCB0aGVzZSBibG9nX2lkIHZhbHVlcyAoY29tbWEtc2VwYXJhdGVkKS4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHNpdGUuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBmaWVsZHMgdG8gc2hvdy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBjb3VudAoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggc2l0ZToKCSAqCgkgKiAqIGJsb2dfaWQKCSAqICogdXJsCgkgKiAqIGxhc3RfdXBkYXRlZAoJICogKiByZWdpc3RlcmVkCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHNpdGVfaWQKCSAqICogZG9tYWluCgkgKiAqIHBhdGgKCSAqICogcHVibGljCgkgKiAqIGFyY2hpdmVkCgkgKiAqIG1hdHVyZQoJICogKiBzcGFtCgkgKiAqIGRlbGV0ZWQKCSAqICogbGFuZ19pZAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgT3V0cHV0IGEgc2ltcGxlIGxpc3Qgb2Ygc2l0ZSBVUkxzCgkgKiAgICAgJCB3cCBzaXRlIGxpc3QgLS1maWVsZD11cmwKCSAqICAgICBodHRwOi8vd3d3LmV4YW1wbGUuY29tLwoJICogICAgIGh0dHA6Ly93d3cuZXhhbXBsZS5jb20vc3ViZGlyLwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgKSB7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IHByZWdfc3BsaXQoICcvLFsgXHRdKi8nLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKTsKCQl9CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknZm9ybWF0JyA9PiAndGFibGUnLAoJCQknZmllbGRzJyA9PiBbICdibG9nX2lkJywgJ3VybCcsICdsYXN0X3VwZGF0ZWQnLCAncmVnaXN0ZXJlZCcgXSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJHdoZXJlICA9IFtdOwoJCSRhcHBlbmQgPSAnJzsKCgkJJHNpdGVfY29scyA9IFsgJ2Jsb2dfaWQnLCAnbGFzdF91cGRhdGVkJywgJ3JlZ2lzdGVyZWQnLCAnc2l0ZV9pZCcsICdkb21haW4nLCAncGF0aCcsICdwdWJsaWMnLCAnYXJjaGl2ZWQnLCAnbWF0dXJlJywgJ3NwYW0nLCAnZGVsZXRlZCcsICdsYW5nX2lkJyBdOwoJCWZvcmVhY2ggKCAkc2l0ZV9jb2xzIGFzICRjb2wgKSB7CgkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkY29sIF0gKSApIHsKCQkJCSR3aGVyZVsgJGNvbCBdID0gJGFzc29jX2FyZ3NbICRjb2wgXTsKCQkJfQoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3NpdGVfX2luJ10gKSApIHsKCQkJJHdoZXJlWydibG9nX2lkJ10gPSBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydzaXRlX19pbiddICk7CgkJCSRhcHBlbmQgICAgICAgICAgID0gJ09SREVSIEJZIEZJRUxEKCBibG9nX2lkLCAnIC4gaW1wbG9kZSggJywnLCBhcnJheV9tYXAoICdpbnR2YWwnLCAkd2hlcmVbJ2Jsb2dfaWQnXSApICkgLiAnICknOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ25ldHdvcmsnXSApICkgewoJCQkkd2hlcmVbJ3NpdGVfaWQnXSA9ICRhc3NvY19hcmdzWyduZXR3b3JrJ107CgkJfQoKCQkkaXRlcmF0b3JfYXJncyA9IFsKCQkJJ3RhYmxlJyAgPT4gJHdwZGItPmJsb2dzLAoJCQknd2hlcmUnICA9PiAkd2hlcmUsCgkJCSdhcHBlbmQnID0+ICRhcHBlbmQsCgkJXTsKCgkJJGl0ZXJhdG9yID0gbmV3IFRhYmxlSXRlcmF0b3IoICRpdGVyYXRvcl9hcmdzICk7CgoJCSRpdGVyYXRvciA9IFV0aWxzXGl0ZXJhdG9yX21hcCgKCQkJJGl0ZXJhdG9yLAoJCQlmdW5jdGlvbiggJGJsb2cgKSB7CgkJCQkkYmxvZy0+dXJsID0gdHJhaWxpbmdzbGFzaGl0KCBnZXRfc2l0ZV91cmwoICRibG9nLT5ibG9nX2lkICkgKTsKCQkJCXJldHVybiAkYmxvZzsKCQkJfQoJCSk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgJiYgJ2lkcycgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJJHNpdGVzICAgICA9IGl0ZXJhdG9yX3RvX2FycmF5KCAkaXRlcmF0b3IgKTsKCQkJJGlkcyAgICAgICA9IHdwX2xpc3RfcGx1Y2soICRzaXRlcywgJ2Jsb2dfaWQnICk7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgbnVsbCwgJ3NpdGUnICk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpZHMgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIG51bGwsICdzaXRlJyApOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkaXRlcmF0b3IgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBcmNoaXZlcyBvbmUgb3IgbW9yZSBzaXRlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gYXJjaGl2ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgYXJjaGl2ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyBhcmNoaXZlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFyY2hpdmUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnYXJjaGl2ZWQnLCAxICk7Cgl9CgoJLyoqCgkgKiBVbmFyY2hpdmVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byB1bmFyY2hpdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIHVuYXJjaGl2ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyB1bmFyY2hpdmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5hcmNoaXZlKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ2FyY2hpdmVkJywgMCApOwoJfQoKCS8qKgoJICogQWN0aXZhdGVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBhY3RpdmF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgYWN0aXZhdGUgMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgYWN0aXZhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnZGVsZXRlZCcsIDAgKTsKCX0KCgkvKioKCSAqIERlYWN0aXZhdGVzIG9uZSBvciBtb3JlIHNpdGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBkZWFjdGl2YXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBkZWFjdGl2YXRlIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIGRlYWN0aXZhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9zaXRlX3N0YXR1cyggJGFyZ3MsICdkZWxldGVkJywgMSApOwoJfQoKCS8qKgoJICogTWFya3Mgb25lIG9yIG1vcmUgc2l0ZXMgYXMgc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gYmUgbWFya2VkIGFzIHNwYW0uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBzaXRlIHNwYW0gMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgbWFya2VkIGFzIHNwYW0uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzcGFtKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAxICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIG9uZSBvciBtb3JlIHNpdGVzIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gcmVtb3ZlIGZyb20gc3BhbS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgdW5zcGFtIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIHJlbW92ZWQgZnJvbSBzcGFtLgoJICoKCSAqIEBzdWJjb21tYW5kIHVuc3BhbQoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zcGFtKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ3NwYW0nLCAwICk7Cgl9CgoJLyoqCgkgKiBTZXRzIG9uZSBvciBtb3JlIHNpdGVzIGFzIG1hdHVyZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gc2V0IGFzIG1hdHVyZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgbWF0dXJlIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIG1hcmtlZCBhcyBtYXR1cmUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtYXR1cmUoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAnbWF0dXJlJywgMSApOwoJfQoKCS8qKgoJICogU2V0cyBvbmUgb3IgbW9yZSBzaXRlcyBhcyBpbW1hdHVyZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGlkPi4uLgoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2Ygc2l0ZXMgdG8gc2V0IGFzIHVubWF0dXJlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBnZW5lcmFsIDEyMwoJICogICAgIFN1Y2Nlc3M6IFNpdGUgMTIzIG1hcmtlZCBhcyB1bm1hdHVyZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVubWF0dXJlKCAkYXJncyApIHsKCQkkdGhpcy0+dXBkYXRlX3NpdGVfc3RhdHVzKCAkYXJncywgJ21hdHVyZScsIDAgKTsKCX0KCgkvKioKCSAqIFNldHMgb25lIG9yIG1vcmUgc2l0ZXMgYXMgcHVibGljLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBzZXQgYXMgcHVibGljLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBwdWJsaWMgMTIzCgkgKiAgICAgU3VjY2VzczogU2l0ZSAxMjMgbWFya2VkIGFzIHB1YmxpYy4KCSAqCgkgKiBAc3ViY29tbWFuZCBwdWJsaWMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldF9wdWJsaWMoICRhcmdzICkgewoJCSR0aGlzLT51cGRhdGVfc2l0ZV9zdGF0dXMoICRhcmdzLCAncHVibGljJywgMSApOwoJfQoKCS8qKgoJICogU2V0cyBvbmUgb3IgbW9yZSBzaXRlcyBhcyBwcml2YXRlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aWQ+Li4uCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiBzaXRlcyB0byBzZXQgYXMgcHJpdmF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpdGUgcHJpdmF0ZSAxMjMKCSAqICAgICBTdWNjZXNzOiBTaXRlIDEyMyBtYXJrZWQgYXMgcHJpdmF0ZS4KCSAqCgkgKiBAc3ViY29tbWFuZCBwcml2YXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRfcHJpdmF0ZSggJGFyZ3MgKSB7CgkJJHRoaXMtPnVwZGF0ZV9zaXRlX3N0YXR1cyggJGFyZ3MsICdwdWJsaWMnLCAwICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB1cGRhdGVfc2l0ZV9zdGF0dXMoICRpZHMsICRwcmVmLCAkdmFsdWUgKSB7CgkJJHZhbHVlID0gKGludCkgJHZhbHVlOwoKCQlzd2l0Y2ggKCAkcHJlZiApIHsKCQkJY2FzZSAnYXJjaGl2ZWQnOgoJCQkJJGFjdGlvbiA9ICR2YWx1ZSA/ICdhcmNoaXZlZCcgOiAndW5hcmNoaXZlZCc7CgkJCQlicmVhazsKCQkJY2FzZSAnZGVsZXRlZCc6CgkJCQkkYWN0aW9uID0gJHZhbHVlID8gJ2RlYWN0aXZhdGVkJyA6ICdhY3RpdmF0ZWQnOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ21hdHVyZSc6CgkJCQkkYWN0aW9uID0gJHZhbHVlID8gJ21hcmtlZCBhcyBtYXR1cmUnIDogJ21hcmtlZCBhcyB1bm1hdHVyZSc7CgkJCQlicmVhazsKCQkJY2FzZSAncHVibGljJzoKCQkJCSRhY3Rpb24gPSAkdmFsdWUgPyAnbWFya2VkIGFzIHB1YmxpYycgOiAnbWFya2VkIGFzIHByaXZhdGUnOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ3NwYW0nOgoJCQkJJGFjdGlvbiA9ICR2YWx1ZSA/ICdtYXJrZWQgYXMgc3BhbScgOiAncmVtb3ZlZCBmcm9tIHNwYW0nOwoJCQkJYnJlYWs7CgkJfQoKCQlmb3JlYWNoICggJGlkcyBhcyAkc2l0ZV9pZCApIHsKCQkJJHNpdGUgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkc2l0ZV9pZCApOwoKCQkJaWYgKCBpc19tYWluX3NpdGUoICRzaXRlLT5ibG9nX2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdZb3UgYXJlIG5vdCBhbGxvd2VkIHRvIGNoYW5nZSB0aGUgbWFpbiBzaXRlLicgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkb2xkX3ZhbHVlID0gKGludCkgZ2V0X2Jsb2dfc3RhdHVzKCAkc2l0ZS0+YmxvZ19pZCwgJHByZWYgKTsKCgkJCWlmICggJHZhbHVlID09PSAkb2xkX3ZhbHVlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiU2l0ZSB7JHNpdGUtPmJsb2dfaWR9IGFscmVhZHkgeyRhY3Rpb259LiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQl1cGRhdGVfYmxvZ19zdGF0dXMoICRzaXRlLT5ibG9nX2lkLCAkcHJlZiwgJHZhbHVlICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlNpdGUgeyRzaXRlLT5ibG9nX2lkfSB7JGFjdGlvbn0uIiApOwoJCX0KCX0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2V4dGVuc2lvbl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9leHRlbnNpb25fYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9leHRlbnNpb25fYXV0b2xvYWRlcjsKfQoKJHdwY2xpX2V4dGVuc2lvbl9yZXF1aXJlc193cF81XzUgPSBbCgknYmVmb3JlX2ludm9rZScgPT4gc3RhdGljIGZ1bmN0aW9uICgpIHsKCQlpZiAoIFdQX0NMSVxVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc1LjUnLCAnPCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1JlcXVpcmVzIFdvcmRQcmVzcyA1LjUgb3IgZ3JlYXRlci4nICk7CgkJfQoJfSwKXTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdwbHVnaW4nLCAnUGx1Z2luX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdwbHVnaW4gYXV0by11cGRhdGVzJywgJ1BsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kJywgJHdwY2xpX2V4dGVuc2lvbl9yZXF1aXJlc193cF81XzUgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3RoZW1lJywgJ1RoZW1lX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0aGVtZSBhdXRvLXVwZGF0ZXMnLCAnVGhlbWVfQXV0b1VwZGF0ZXNfQ29tbWFuZCcsICR3cGNsaV9leHRlbnNpb25fcmVxdWlyZXNfd3BfNV81ICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICd0aGVtZSBtb2QnLCAnVGhlbWVfTW9kX0NvbW1hbmQnICk7Cjw/cGhwCgp1c2UgV1BfQ0xJXEZldGNoZXJzXFRoZW1lOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxQYXJzZVRoZW1lTmFtZUlucHV0Owp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIE1hbmFnZXMgdGhlbWUgYXV0by11cGRhdGVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBFbmFibGUgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZW5hYmxlIGFjdGl2YXRlIHR3ZW50eXNpeHRlZW4KICogICAgIFRoZW1lIGF1dG8tdXBkYXRlcyBmb3IgJ3R3ZW50eXNpeHRlZW4nIGVuYWJsZWQuCiAqICAgICBTdWNjZXNzOiBFbmFibGVkIDEgb2YgMSB0aGVtZSBhdXRvLXVwZGF0ZXMuCiAqCiAqICAgICAjIERpc2FibGUgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZQogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZGlzYWJsZSBhY3RpdmF0ZSB0d2VudHlzaXh0ZWVuCiAqICAgICBUaGVtZSBhdXRvLXVwZGF0ZXMgZm9yICd0d2VudHlzaXh0ZWVuJyBkaXNhYmxlZC4KICogICAgIFN1Y2Nlc3M6IERpc2FibGVkIDEgb2YgMSB0aGVtZSBhdXRvLXVwZGF0ZXMuCiAqCiAqICAgICAjIEdldCB0aGUgc3RhdHVzIG9mIHRoZW1lIGF1dG8tdXBkYXRlcwogKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIHR3ZW50eXNpeHRlZW4KICogICAgIEF1dG8tdXBkYXRlcyBmb3IgdGhlbWUgJ3R3ZW50eXNpeHRlZW4nIGFyZSBkaXNhYmxlZC4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBUaGVtZV9BdXRvVXBkYXRlc19Db21tYW5kIHsKCgl1c2UgUGFyc2VUaGVtZU5hbWVJbnB1dDsKCgkvKioKCSAqIFNpdGUgb3B0aW9uIHRoYXQgc3RvcmVzIHRoZSBzdGF0dXMgb2YgdGhlbWUgYXV0by11cGRhdGVzLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCWNvbnN0IFNJVEVfT1BUSU9OID0gJ2F1dG9fdXBkYXRlX3RoZW1lcyc7CgoJLyoqCgkgKiBUaGVtZSBmZXRjaGVyIGluc3RhbmNlLgoJICoKCSAqIEB2YXIgVGhlbWUKCSAqLwoJcHJvdGVjdGVkICRmZXRjaGVyOwoKCS8qKgoJICogVGhlbWVfQXV0b1VwZGF0ZXNfQ29tbWFuZCBjb25zdHJ1Y3Rvci4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFRoZW1lKCk7Cgl9CgoJLyoqCgkgKiBFbmFibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gZW5hYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGVuYWJsZWQgZm9yIGFsbCB0aGVtZXMuCgkgKgoJICogWy0tZGlzYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBkaXNhYmxlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEVuYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZW5hYmxlIGFjdGl2YXRlIHR3ZW50eXNpeHRlZW4KCSAqICAgICBUaGVtZSBhdXRvLXVwZGF0ZXMgZm9yICd0d2VudHlzaXh0ZWVuJyBlbmFibGVkLgoJICogICAgIFN1Y2Nlc3M6IEVuYWJsZWQgMSBvZiAxIHRoZW1lIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVuYWJsZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZGlzYWJsZWRfb25seSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2FibGVkLW9ubHknLCBmYWxzZSApOwoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkdGhlbWVzICAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCSRhdXRvX3VwZGF0ZXMgPSBnZXRfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGF1dG9fdXBkYXRlcyApIHsKCQkJJGF1dG9fdXBkYXRlcyA9IFtdOwoJCX0KCgkJJGNvdW50ICAgICA9IDA7CgkJJHN1Y2Nlc3NlcyA9IDA7CgoJCWZvcmVhY2ggKCAkdGhlbWVzIGFzICR0aGVtZSApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHRoZW1lLT5zdHlsZXNoZWV0LCAkYXV0b191cGRhdGVzLCB0cnVlICk7CgoJCQlpZiAoICRkaXNhYmxlZF9vbmx5ICYmICRlbmFibGVkICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRjb3VudCsrOwoKCQkJaWYgKCAkZW5hYmxlZCApIHsKCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkiQXV0by11cGRhdGVzIGFscmVhZHkgZW5hYmxlZCBmb3IgdGhlbWUgeyR0aGVtZS0+c3R5bGVzaGVldH0uIgoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCSRhdXRvX3VwZGF0ZXNbXSA9ICR0aGVtZS0+c3R5bGVzaGVldDsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gdGhlbWVzIHByb3ZpZGVkIHRvIGVuYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLicKCQkJKTsKCQl9CgoJCXVwZGF0ZV9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiwgJGF1dG9fdXBkYXRlcyApOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSd0aGVtZSBhdXRvLXVwZGF0ZScsCgkJCSdlbmFibGUnLAoJCQkkY291bnQsCgkJCSRzdWNjZXNzZXMsCgkJCSRjb3VudCAtICRzdWNjZXNzZXMKCQkpOwoJfQoKCS8qKgoJICogRGlzYWJsZXMgdGhlIGF1dG8tdXBkYXRlcyBmb3IgYSB0aGVtZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHRoZW1lcyB0byBkaXNhYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGRpc2FibGVkIGZvciBhbGwgdGhlbWVzLgoJICoKCSAqIFstLWVuYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgZGlzYWJsZSBhY3RpdmF0ZSB0d2VudHlzaXh0ZWVuCgkgKiAgICAgVGhlbWUgYXV0by11cGRhdGVzIGZvciAndHdlbnR5c2l4dGVlbicgZGlzYWJsZWQuCgkgKiAgICAgU3VjY2VzczogRGlzYWJsZWQgMSBvZiAxIHRoZW1lIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHRoZW1lcyAgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQkkYXV0b191cGRhdGVzID0gZ2V0X3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgoJCWlmICggZmFsc2UgPT09ICRhdXRvX3VwZGF0ZXMgKSB7CgkJCSRhdXRvX3VwZGF0ZXMgPSBbXTsKCQl9CgoJCSRjb3VudCAgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoKCQlmb3JlYWNoICggJHRoZW1lcyBhcyAkdGhlbWUgKSB7CgkJCSRlbmFibGVkID0gaW5fYXJyYXkoICR0aGVtZS0+c3R5bGVzaGVldCwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICEgJGVuYWJsZWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIkF1dG8tdXBkYXRlcyBhbHJlYWR5IGRpc2FibGVkIGZvciB0aGVtZSB7JHRoZW1lLT5zdHlsZXNoZWV0fS4iCgkJCQkpOwoJCQl9IGVsc2UgewoJCQkJJGF1dG9fdXBkYXRlcyA9IGFycmF5X2RpZmYoICRhdXRvX3VwZGF0ZXMsIFsgJHRoZW1lLT5zdHlsZXNoZWV0IF0gKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gdGhlbWVzIHByb3ZpZGVkIHRvIGRpc2FibGUgYXV0by11cGRhdGVzIGZvci4nCgkJCSk7CgkJfQoKCQlpZiAoIGNvdW50KCAkYXV0b191cGRhdGVzICkgPiAwICkgewoJCQl1cGRhdGVfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04sICRhdXRvX3VwZGF0ZXMgKTsKCQl9IGVsc2UgewoJCQlkZWxldGVfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cygKCQkJJ3RoZW1lIGF1dG8tdXBkYXRlJywKCQkJJ2Rpc2FibGUnLAoJCQkkY291bnQsCgkJCSRzdWNjZXNzZXMsCgkJCSRjb3VudCAtICRzdWNjZXNzZXMKCQkpOwoJfQoKCS8qKgoJICogU2hvd3MgdGhlIHN0YXR1cyBvZiBhdXRvLXVwZGF0ZXMgZm9yIGEgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gc2hvdyB0aGUgc3RhdHVzIG9mIHRoZSBhdXRvLXVwZGF0ZXMgb2YuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIHRoZSBzdGF0dXMgb2YgYXV0by11cGRhdGVzIGZvciBhbGwgdGhlbWVzIHdpbGwgYmUgc2hvd24uCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiB0aGVtZXMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGVuYWJsZWQuCgkgKgoJICogWy0tZGlzYWJsZWQtb25seV0KCSAqIDogSWYgc2V0LCBmaWx0ZXJzIGxpc3Qgb2YgdGhlbWVzIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBkaXNhYmxlZC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBPbmx5IHNob3cgdGhlIHByb3ZpZGVkIGZpZWxkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHRoZSBzdGF0dXMgb2YgdGhlbWUgYXV0by11cGRhdGVzCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIHR3ZW50eXNpeHRlZW4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgIHwgc3RhdHVzICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IHR3ZW50eXNpeHRlZW4gfCBkaXNhYmxlZCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIEdldCB0aGUgbGlzdCBvZiB0aGVtZXMgdGhhdCBoYXZlIGF1dG8tdXBkYXRlcyBlbmFibGVkCgkgKiAgICAgJCB3cCB0aGVtZSBhdXRvLXVwZGF0ZXMgc3RhdHVzIC0tYWxsIC0tZW5hYmxlZC1vbmx5IC0tZmllbGQ9bmFtZQoJICogICAgIHR3ZW50eXNpeHRlZW4KCSAqICAgICB0d2VudHlzZXZlbnRlZW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN0YXR1cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2VuYWJsZWQtb25seScsIGZhbHNlICk7CgkJJGRpc2FibGVkX29ubHkgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNhYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICRkaXNhYmxlZF9vbmx5ICkgewoJCQlXUF9DTEk6OmVycm9yKAoJCQkJJy0tZW5hYmxlZC1vbmx5IGFuZCAtLWRpc2FibGVkLW9ubHkgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSBhbmQgJwoJCQkJLiAnY2Fubm90IGJlIHVzZWQgYXQgdGhlIHNhbWUgdGltZS4nCgkJCSk7CgkJfQoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkdGhlbWVzICAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCSRhdXRvX3VwZGF0ZXMgPSBnZXRfc2l0ZV9vcHRpb24oIHN0YXRpYzo6U0lURV9PUFRJT04gKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGF1dG9fdXBkYXRlcyApIHsKCQkJJGF1dG9fdXBkYXRlcyA9IFtdOwoJCX0KCgkJJHJlc3VsdHMgPSBbXTsKCgkJZm9yZWFjaCAoICR0aGVtZXMgYXMgJHRoZW1lICkgewoJCQkkZW5hYmxlZCA9IGluX2FycmF5KCAkdGhlbWUtPnN0eWxlc2hlZXQsICRhdXRvX3VwZGF0ZXMsIHRydWUgKTsKCgkJCWlmICggJGVuYWJsZWRfb25seSAmJiAhICRlbmFibGVkICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggJGRpc2FibGVkX29ubHkgJiYgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdHNbXSA9IFsKCQkJCSduYW1lJyAgID0+ICR0aGVtZS0+c3R5bGVzaGVldCwKCQkJCSduYW1lCgkJCScgICAgICAgICAgICA9PiAkdGhlbWUtPnN0eWxlc2hlZXQsCgkJCQknc3RhdHVzJyA9PiAkZW5hYmxlZCA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCcsCgkJCV07CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIFsgJ25hbWUnLCAnc3RhdHVzJyBdLCAndGhlbWUnICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHJlc3VsdHMgKTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxDb21tYW5kV2l0aFVwZ3JhZGU7CnVzZSBXUF9DTElcUGFyc2VUaGVtZU5hbWVJbnB1dDsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBNYW5hZ2VzIHRoZW1lcywgaW5jbHVkaW5nIGluc3RhbGxzLCBhY3RpdmF0aW9ucywgYW5kIHVwZGF0ZXMuCiAqCiAqIFNlZSB0aGUgV29yZFByZXNzIFtUaGVtZSBIYW5kYm9va10oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy90aGVtZXMvKSBkZXZlbG9wZXIgcmVzb3VyY2UgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlbWVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiBhIHRoZW1lIGZyb20gd29yZHByZXNzLm9yZyBhbmQgYWN0aXZhdGUKICogICAgICQgd3AgdGhlbWUgaW5zdGFsbCB0d2VudHlzaXh0ZWVuIC0tYWN0aXZhdGUKICogICAgIEluc3RhbGxpbmcgVHdlbnR5IFNpeHRlZW4gKDEuMikKICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHA6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS90d2VudHlzaXh0ZWVuLjEuMi56aXAuLi4KICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgogKiAgICAgSW5zdGFsbGluZyB0aGUgdGhlbWUuLi4KICogICAgIFRoZW1lIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuCiAqICAgICBBY3RpdmF0aW5nICd0d2VudHlzaXh0ZWVuJy4uLgogKiAgICAgU3VjY2VzczogU3dpdGNoZWQgdG8gJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KICoKICogICAgICMgR2V0IGRldGFpbHMgb2YgYW4gaW5zdGFsbGVkIHRoZW1lCiAqICAgICAkIHdwIHRoZW1lIGdldCB0d2VudHlzaXh0ZWVuIC0tZmllbGRzPW5hbWUsdGl0bGUsdmVyc2lvbgogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBGaWVsZCAgIHwgVmFsdWUgICAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgIHwgVHdlbnR5IFNpeHRlZW4gfAogKiAgICAgfCB0aXRsZSAgIHwgVHdlbnR5IFNpeHRlZW4gfAogKiAgICAgfCB2ZXJzaW9uIHwgMS4yICAgICAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwogKgogKiAgICAgIyBHZXQgc3RhdHVzIG9mIHRoZW1lCiAqICAgICAkIHdwIHRoZW1lIHN0YXR1cyB0d2VudHlzaXh0ZWVuCiAqICAgICBUaGVtZSB0d2VudHlzaXh0ZWVuIGRldGFpbHM6CiAqICAgICAgICAgIE5hbWU6IFR3ZW50eSBTaXh0ZWVuCiAqICAgICAgICAgIFN0YXR1czogQWN0aXZlCiAqICAgICAgICAgIFZlcnNpb246IDEuMgogKiAgICAgICAgICBBdXRob3I6IHRoZSBXb3JkUHJlc3MgdGVhbQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFRoZW1lX0NvbW1hbmQgZXh0ZW5kcyBDb21tYW5kV2l0aFVwZ3JhZGUgewoKCXVzZSBQYXJzZVRoZW1lTmFtZUlucHV0OwoKCXByb3RlY3RlZCAkaXRlbV90eXBlICAgICAgICAgPSAndGhlbWUnOwoJcHJvdGVjdGVkICR1cGdyYWRlX3JlZnJlc2ggICA9ICd3cF91cGRhdGVfdGhlbWVzJzsKCXByb3RlY3RlZCAkdXBncmFkZV90cmFuc2llbnQgPSAndXBkYXRlX3RoZW1lcyc7CgoJcHJvdGVjdGVkICRvYmpfZmllbGRzID0gWyAnbmFtZScsICdzdGF0dXMnLCAndXBkYXRlJywgJ3ZlcnNpb24nIF07CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSR0aGlzLT5vYmpfZmllbGRzW10gPSAnZW5hYmxlZCc7CgkJfQoJCXBhcmVudDo6X19jb25zdHJ1Y3QoKTsKCgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgV1BfQ0xJXEZldGNoZXJzXFRoZW1lKCk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF91cGdyYWRlcl9jbGFzcyggJGZvcmNlICkgewoJCXJldHVybiAkZm9yY2UgPyAnXFxXUF9DTElcXERlc3RydWN0aXZlVGhlbWVVcGdyYWRlcicgOiAnVGhlbWVfVXBncmFkZXInOwoJfQoKCS8qKgoJICogUmV2ZWFscyB0aGUgc3RhdHVzIG9mIG9uZSBvciBhbGwgdGhlbWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHRoZW1lPl0KCSAqIDogQSBwYXJ0aWN1bGFyIHRoZW1lIHRvIHNob3cgdGhlIHN0YXR1cyBmb3IuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0aGVtZSBzdGF0dXMgdHdlbnR5c2l4dGVlbgoJICogICAgIFRoZW1lIHR3ZW50eXNpeHRlZW4gZGV0YWlsczoKCSAqICAgICAgICAgIE5hbWU6IFR3ZW50eSBTaXh0ZWVuCgkgKiAgICAgICAgICBTdGF0dXM6IEluYWN0aXZlCgkgKiAgICAgICAgICBWZXJzaW9uOiAxLjIKCSAqICAgICAgICAgIEF1dGhvcjogdGhlIFdvcmRQcmVzcyB0ZWFtCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzdGF0dXMoICRhcmdzICkgewoJCWlmICggaXNzZXQoICRhcmdzWzBdICkgKSB7CgkJCSR0aGVtZSAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCQkkZXJyb3JzID0gJHRoZW1lLT5lcnJvcnMoKTsKCQkJaWYgKCBpc193cF9lcnJvciggJGVycm9ycyApICkgewoJCQkJJG1lc3NhZ2UgPSAkZXJyb3JzLT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJCQkJV1BfQ0xJOjplcnJvciggJG1lc3NhZ2UgKTsKCQkJfQoJCX0KCgkJcGFyZW50OjpzdGF0dXMoICRhcmdzICk7Cgl9CgoJLyoqCgkgKiBTZWFyY2hlcyB0aGUgV29yZFByZXNzLm9yZyB0aGVtZSBkaXJlY3RvcnkuCgkgKgoJICogRGlzcGxheXMgdGhlbWVzIGluIHRoZSBXb3JkUHJlc3Mub3JnIHRoZW1lIGRpcmVjdG9yeSBtYXRjaGluZyBhIGdpdmVuCgkgKiBzZWFyY2ggcXVlcnkuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzZWFyY2g+CgkgKiA6IFRoZSBzdHJpbmcgdG8gc2VhcmNoIGZvci4KCSAqCgkgKiBbLS1wYWdlPTxwYWdlPl0KCSAqIDogT3B0aW9uYWwgcGFnZSB0byBkaXNwbGF5LgoJICogLS0tCgkgKiBkZWZhdWx0OiAxCgkgKiAtLS0KCSAqCgkgKiBbLS1wZXItcGFnZT08cGVyLXBhZ2U+XQoJICogOiBPcHRpb25hbCBudW1iZXIgb2YgcmVzdWx0cyB0byBkaXNwbGF5LiBEZWZhdWx0cyB0byAxMC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHRoZW1lLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogQXNrIGZvciBzcGVjaWZpYyBmaWVsZHMgZnJvbSB0aGUgQVBJLiBEZWZhdWx0cyB0byBuYW1lLHNsdWcsYXV0aG9yLHJhdGluZy4gQWNjZXB0YWJsZSB2YWx1ZXM6CgkgKgoJICogICAgICoqbmFtZSoqOiBUaGVtZSBOYW1lCgkgKiAgICAgKipzbHVnKio6IFRoZW1lIFNsdWcKCSAqICAgICAqKnZlcnNpb24qKjogQ3VycmVudCBWZXJzaW9uIE51bWJlcgoJICogICAgICoqYXV0aG9yKio6IFRoZW1lIEF1dGhvcgoJICogICAgICoqcHJldmlld191cmwqKjogVGhlbWUgUHJldmlldyBVUkwKCSAqICAgICAqKnNjcmVlbnNob3RfdXJsKio6IFRoZW1lIFNjcmVlbnNob3QgVVJMCgkgKiAgICAgKipyYXRpbmcqKjogVGhlbWUgUmF0aW5nCgkgKiAgICAgKipudW1fcmF0aW5ncyoqOiBOdW1iZXIgb2YgVGhlbWUgUmF0aW5ncwoJICogICAgICoqaG9tZXBhZ2UqKjogVGhlbWUgQXV0aG9yJ3MgSG9tZXBhZ2UKCSAqICAgICAqKmRlc2NyaXB0aW9uKio6IFRoZW1lIERlc2NyaXB0aW9uCgkgKiAgICAgKip1cmwqKjogVGhlbWUncyBVUkwgb24gd29yZHByZXNzLm9yZwoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdGhlbWUgc2VhcmNoIHBob3RvIC0tcGVyLXBhZ2U9NgoJICogICAgIFN1Y2Nlc3M6IFNob3dpbmcgNiBvZiAyMDMgdGhlbWVzLgoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgICAgICAgICAgICB8IHNsdWcgICAgICAgICAgICAgICAgIHwgcmF0aW5nIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tKwoJICogICAgIHwgUGhvdG9zICAgICAgICAgICAgICAgfCBwaG90b3MgICAgICAgICAgICAgICB8IDEwMCAgICB8CgkgKiAgICAgfCBJbmZpbml0ZSBQaG90b2dyYXBoeSB8IGluZmluaXRlLXBob3RvZ3JhcGh5IHwgMTAwICAgIHwKCSAqICAgICB8IFBob3RvQm9vayAgICAgICAgICAgIHwgcGhvdG9ib29rICAgICAgICAgICAgfCAxMDAgICAgfAoJICogICAgIHwgQkcgUGhvdG8gRnJhbWUgICAgICAgfCBiZy1waG90by1mcmFtZSAgICAgICB8IDAgICAgICB8CgkgKiAgICAgfCBmUGhvdG9ncmFwaHkgICAgICAgICB8IGZwaG90b2dyYXBoeSAgICAgICAgIHwgMCAgICAgIHwKCSAqICAgICB8IFBob3RvIFBlcmZlY3QgICAgICAgIHwgcGhvdG8tcGVyZmVjdCAgICAgICAgfCA5OCAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZWFyY2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlwYXJlbnQ6Ol9zZWFyY2goICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBzdGF0dXNfc2luZ2xlKCAkYXJncyApIHsKCQkkdGhlbWUgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoKCQkkc3RhdHVzID0gJHRoaXMtPmZvcm1hdF9zdGF0dXMoICR0aGlzLT5nZXRfc3RhdHVzKCAkdGhlbWUgKSwgJ2xvbmcnICk7CgoJCSR2ZXJzaW9uID0gJHRoZW1lLT5nZXQoICdWZXJzaW9uJyApOwoJCWlmICggJHRoaXMtPmhhc191cGRhdGUoICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSApICkgewoJCQkkdmVyc2lvbiAuPSAnICglZ1VwZGF0ZSBhdmFpbGFibGUlbiknOwoJCX0KCgkJZWNobyBXUF9DTEk6OmNvbG9yaXplKAoJCQlVdGlsc1xtdXN0YWNoZV9yZW5kZXIoCgkJCQlzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJ3RoZW1lLXN0YXR1cy5tdXN0YWNoZScgKSwKCQkJCVsKCQkJCQknc2x1ZycgICAgPT4gJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpLAoJCQkJCSdzdGF0dXMnICA9PiAkc3RhdHVzLAoJCQkJCSd2ZXJzaW9uJyA9PiAkdmVyc2lvbiwKCQkJCQknbmFtZScgICAgPT4gJHRoZW1lLT5nZXQoICdOYW1lJyApLAoJCQkJCSdhdXRob3InICA9PiAkdGhlbWUtPmdldCggJ0F1dGhvcicgKSwKCQkJCV0KCQkJKQoJCSk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9hbGxfaXRlbXMoKSB7CgkJcmV0dXJuICR0aGlzLT5nZXRfaXRlbV9saXN0KCk7Cgl9CgoJLyoqCgkgKiBBY3RpdmF0ZXMgYSB0aGVtZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRoZW1lPgoJICogOiBUaGUgdGhlbWUgdG8gYWN0aXZhdGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0aGVtZSBhY3RpdmF0ZSB0d2VudHlzaXh0ZWVuCgkgKiAgICAgU3VjY2VzczogU3dpdGNoZWQgdG8gJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFjdGl2YXRlKCAkYXJncyA9IGFycmF5KCkgKSB7CgkJJHRoZW1lID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJJGVycm9ycyA9ICR0aGVtZS0+ZXJyb3JzKCk7CgkJaWYgKCBpc193cF9lcnJvciggJGVycm9ycyApICkgewoJCQkkbWVzc2FnZSA9ICRlcnJvcnMtPmdldF9lcnJvcl9tZXNzYWdlKCk7CgkJCVdQX0NMSTo6ZXJyb3IoICRtZXNzYWdlICk7CgkJfQoKCQkkbmFtZSA9ICR0aGVtZS0+Z2V0KCAnTmFtZScgKTsKCgkJaWYgKCAnYWN0aXZlJyA9PT0gJHRoaXMtPmdldF9zdGF0dXMoICR0aGVtZSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJyRuYW1lJyB0aGVtZSBpcyBhbHJlYWR5IGFjdGl2ZS4iICk7CgkJCXJldHVybjsKCQl9CgoJCWlmICggJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpICE9PSAkdGhlbWUtPmdldF90ZW1wbGF0ZSgpICYmICEgJHRoaXMtPmZldGNoZXItPmdldCggJHRoZW1lLT5nZXRfdGVtcGxhdGUoKSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICd7JHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpfScgdGhlbWUgY2Fubm90IGJlIGFjdGl2YXRlZCB3aXRob3V0IGl0cyBwYXJlbnQsICd7JHRoZW1lLT5nZXRfdGVtcGxhdGUoKX0nLiIgKTsKCQl9CgoJCXN3aXRjaF90aGVtZSggJHRoZW1lLT5nZXRfdGVtcGxhdGUoKSwgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpICk7CgoJCWlmICggJHRoaXMtPmlzX2FjdGl2ZV90aGVtZSggJHRoZW1lICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlN3aXRjaGVkIHRvICckbmFtZScgdGhlbWUuIiApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3Qgc3dpdGNoIHRvICckbmFtZScgdGhlbWUuIiApOwoJCX0KCX0KCgkvKioKCSAqIEVuYWJsZXMgYSB0aGVtZSBvbiBhIFdvcmRQcmVzcyBtdWx0aXNpdGUgaW5zdGFsbC4KCSAqCgkgKiBQZXJtaXRzIHRoZW1lIHRvIGJlIGFjdGl2YXRlZCBmcm9tIHRoZSBkYXNoYm9hcmQgb2YgYSBzaXRlIG9uIGEgV29yZFByZXNzCgkgKiBtdWx0aXNpdGUgaW5zdGFsbC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHRoZW1lPgoJICogOiBUaGUgdGhlbWUgdG8gZW5hYmxlLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IElmIHNldCwgdGhlIHRoZW1lIGlzIGVuYWJsZWQgZm9yIHRoZSBlbnRpcmUgbmV0d29yawoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBJZiBzZXQsIHRoZSB0aGVtZSBpcyBhY3RpdmF0ZWQgZm9yIHRoZSBjdXJyZW50IHNpdGUuIE5vdGUgdGhhdAoJICogdGhlICJuZXR3b3JrIiBmbGFnIGhhcyBubyBpbmZsdWVuY2Ugb24gdGhpcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEVuYWJsZSB0aGVtZQoJICogICAgICQgd3AgdGhlbWUgZW5hYmxlIHR3ZW50eXNpeHRlZW4KCSAqICAgICBTdWNjZXNzOiBFbmFibGVkIHRoZSAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICoKCSAqICAgICAjIE5ldHdvcmsgZW5hYmxlIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBlbmFibGUgdHdlbnR5c2l4dGVlbiAtLW5ldHdvcmsKCSAqICAgICBTdWNjZXNzOiBOZXR3b3JrIGVuYWJsZWQgdGhlICdUd2VudHkgU2l4dGVlbicgdGhlbWUuCgkgKgoJICogICAgICMgTmV0d29yayBlbmFibGUgYW5kIGFjdGl2YXRlIHRoZW1lIGZvciBjdXJyZW50IHNpdGUKCSAqICAgICAkIHdwIHRoZW1lIGVuYWJsZSB0d2VudHlzaXh0ZWVuIC0tYWN0aXZhdGUKCSAqICAgICBTdWNjZXNzOiBFbmFibGVkIHRoZSAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICogICAgIFN1Y2Nlc3M6IFN3aXRjaGVkIHRvICdUd2VudHkgU2l4dGVlbicgdGhlbWUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlbmFibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGlzIGlzIG5vdCBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCX0KCgkJJHRoZW1lID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkkbmFtZSAgPSAkdGhlbWUtPmdldCggJ05hbWUnICk7CgoJCSMgSWYgdGhlIC0tbmV0d29yayBmbGFnIGlzIHNldCwgd2UnbGwgYmUgY2FsbGluZyB0aGUgKGdldHx1cGRhdGUpX3NpdGVfb3B0aW9uIGZ1bmN0aW9ucwoJCSRfc2l0ZSA9ICEgZW1wdHkoICRhc3NvY19hcmdzWyduZXR3b3JrJ10gKSA/ICdfc2l0ZScgOiAnJzsKCgkJIyBBZGQgdGhlIGN1cnJlbnQgdGhlbWUgdG8gdGhlIGFsbG93ZWQgdGhlbWVzIG9wdGlvbiBvciBzaXRlIG9wdGlvbgoJCSRhbGxvd2VkX3RoZW1lcyA9IGNhbGxfdXNlcl9mdW5jKCAiZ2V0eyRfc2l0ZX1fb3B0aW9uIiwgJ2FsbG93ZWR0aGVtZXMnICk7CgkJaWYgKCBlbXB0eSggJGFsbG93ZWRfdGhlbWVzICkgKSB7CgkJCSRhbGxvd2VkX3RoZW1lcyA9IGFycmF5KCk7CgkJfQoJCSRhbGxvd2VkX3RoZW1lc1sgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpIF0gPSB0cnVlOwoJCWNhbGxfdXNlcl9mdW5jKCAidXBkYXRleyRfc2l0ZX1fb3B0aW9uIiwgJ2FsbG93ZWR0aGVtZXMnLCAkYWxsb3dlZF90aGVtZXMgKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snbmV0d29yayddICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIk5ldHdvcmsgZW5hYmxlZCB0aGUgJyRuYW1lJyB0aGVtZS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiRW5hYmxlZCB0aGUgJyRuYW1lJyB0aGVtZS4iICk7CgkJfQoKCQkjIElmIHRoZSAtLWFjdGl2YXRlIGZsYWcgaXMgc2V0LCBhY3RpdmF0ZSB0aGUgdGhlbWUgZm9yIHRoZSBjdXJyZW50IHNpdGUKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydhY3RpdmF0ZSddICkgKSB7CgkJCSR0aGlzLT5hY3RpdmF0ZSggJGFyZ3MgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEaXNhYmxlcyBhIHRoZW1lIG9uIGEgV29yZFByZXNzIG11bHRpc2l0ZSBpbnN0YWxsLgoJICoKCSAqIFJlbW92ZXMgYWJpbGl0eSBmb3IgYSB0aGVtZSB0byBiZSBhY3RpdmF0ZWQgZnJvbSB0aGUgZGFzaGJvYXJkIG9mIGEgc2l0ZQoJICogb24gYSBXb3JkUHJlc3MgbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlIHRoZW1lIHRvIGRpc2FibGUuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogSWYgc2V0LCB0aGUgdGhlbWUgaXMgZGlzYWJsZWQgb24gdGhlIG5ldHdvcmsgbGV2ZWwuIE5vdGUgdGhhdAoJICogaW5kaXZpZHVhbCBzaXRlcyBtYXkgc3RpbGwgaGF2ZSB0aGlzIHRoZW1lIGVuYWJsZWQgaWYgaXQgd2FzCgkgKiBlbmFibGVkIGZvciB0aGVtIGluZGVwZW5kZW50bHkuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEaXNhYmxlIHRoZW1lCgkgKiAgICAgJCB3cCB0aGVtZSBkaXNhYmxlIHR3ZW50eXNpeHRlZW4KCSAqICAgICBTdWNjZXNzOiBEaXNhYmxlZCB0aGUgJ1R3ZW50eSBTaXh0ZWVuJyB0aGVtZS4KCSAqCgkgKiAgICAgIyBEaXNhYmxlIHRoZW1lIGluIG5ldHdvcmsgbGV2ZWwKCSAqICAgICAkIHdwIHRoZW1lIGRpc2FibGUgdHdlbnR5c2l4dGVlbiAtLW5ldHdvcmsKCSAqICAgICBTdWNjZXNzOiBOZXR3b3JrIGRpc2FibGVkIHRoZSAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGlzYWJsZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgaXMgbm90IGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4nICk7CgkJfQoKCQkkdGhlbWUgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSRuYW1lICA9ICR0aGVtZS0+Z2V0KCAnTmFtZScgKTsKCgkJIyBJZiB0aGUgLS1uZXR3b3JrIGZsYWcgaXMgc2V0LCB3ZSdsbCBiZSBjYWxsaW5nIHRoZSAoZ2V0fHVwZGF0ZSlfc2l0ZV9vcHRpb24gZnVuY3Rpb25zCgkJJF9zaXRlID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ25ldHdvcmsnXSApID8gJ19zaXRlJyA6ICcnOwoKCQkjIEFkZCB0aGUgY3VycmVudCB0aGVtZSB0byB0aGUgYWxsb3dlZCB0aGVtZXMgb3B0aW9uIG9yIHNpdGUgb3B0aW9uCgkJJGFsbG93ZWRfdGhlbWVzID0gY2FsbF91c2VyX2Z1bmMoICJnZXR7JF9zaXRlfV9vcHRpb24iLCAnYWxsb3dlZHRoZW1lcycgKTsKCQlpZiAoICEgZW1wdHkoICRhbGxvd2VkX3RoZW1lc1sgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpIF0gKSApIHsKCQkJdW5zZXQoICRhbGxvd2VkX3RoZW1lc1sgJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpIF0gKTsKCQl9CgkJY2FsbF91c2VyX2Z1bmMoICJ1cGRhdGV7JF9zaXRlfV9vcHRpb24iLCAnYWxsb3dlZHRoZW1lcycsICRhbGxvd2VkX3RoZW1lcyApOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWyduZXR3b3JrJ10gKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiTmV0d29yayBkaXNhYmxlZCB0aGUgJyRuYW1lJyB0aGVtZS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiRGlzYWJsZWQgdGhlICckbmFtZScgdGhlbWUuIiApOwoJCX0KCX0KCgkvKioKCSAqIEdldHMgdGhlIHBhdGggdG8gYSB0aGVtZSBvciB0byB0aGUgdGhlbWUgZGlyZWN0b3J5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHRoZW1lPl0KCSAqIDogVGhlIHRoZW1lIHRvIGdldCB0aGUgcGF0aCB0by4gUGF0aCBpbmNsdWRlcyAic3R5bGUuY3NzIiBmaWxlLgoJICogSWYgbm90IHNldCwgd2lsbCByZXR1cm4gdGhlIHBhdGggdG8gdGhlIHRoZW1lcyBkaXJlY3RvcnkuCgkgKgoJICogWy0tZGlyXQoJICogOiBJZiBzZXQsIGdldCB0aGUgcGF0aCB0byB0aGUgY2xvc2VzdCBwYXJlbnQgZGlyZWN0b3J5LCBpbnN0ZWFkIG9mIHRoZQoJICogdGhlbWUncyAic3R5bGUuY3NzIiBmaWxlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHRoZW1lIHBhdGgKCSAqICAgICAkIHdwIHRoZW1lIHBhdGgKCSAqICAgICAvdmFyL3d3dy9leGFtcGxlLmNvbS9wdWJsaWNfaHRtbC93cC1jb250ZW50L3RoZW1lcwoJICoKCSAqICAgICAjIENoYW5nZSBkaXJlY3RvcnkgdG8gdGhlbWUgcGF0aAoJICogICAgICQgY2QgJCh3cCB0aGVtZSBwYXRoKQoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0aCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCSRwYXRoID0gV1BfQ09OVEVOVF9ESVIgLiAnL3RoZW1lcyc7CgkJfSBlbHNlIHsKCQkJJHRoZW1lID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCgkJCSRwYXRoID0gJHRoZW1lLT5nZXRfc3R5bGVzaGVldF9kaXJlY3RvcnkoKTsKCgkJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXInICkgKSB7CgkJCQkkcGF0aCAuPSAnL3N0eWxlLmNzcyc7CgkJCX0KCQl9CgoJCVdQX0NMSTo6bGluZSggJHBhdGggKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gaW5zdGFsbF9mcm9tX3JlcG8oICRzbHVnLCAkYXNzb2NfYXJncyApIHsKCQkkYXBpID0gdGhlbWVzX2FwaSggJ3RoZW1lX2luZm9ybWF0aW9uJywgYXJyYXkoICdzbHVnJyA9PiAkc2x1ZyApICk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRhcGkgKSApIHsKCQkJcmV0dXJuICRhcGk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndmVyc2lvbiddICkgKSB7CgkJCXNlbGY6OmFsdGVyX2FwaV9yZXNwb25zZSggJGFwaSwgJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApOwoJCX0KCgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgewoJCQkkdGhlbWUgPSB3cF9nZXRfdGhlbWUoICRzbHVnICk7CgkJCWlmICggJHRoZW1lLT5leGlzdHMoKSApIHsKCQkJCS8vIFdlIGtub3cgdGhpcyB3aWxsIGZhaWwsIHNvIGF2b2lkIGEgbmVlZGxlc3MgZG93bmxvYWQgb2YgdGhlIHBhY2thZ2UuCgkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnYWxyZWFkeV9pbnN0YWxsZWQnLCAnVGhlbWUgYWxyZWFkeSBpbnN0YWxsZWQuJyApOwoJCQl9CgkJCS8vIENsZWFyIGNhY2hlIHNvIFdQX1RoZW1lIGRvZXNuJ3QgY3JlYXRlIGEgIm1pc3NpbmcgdGhlbWUiIG9iamVjdC4KCQkJJGNhY2hlX2hhc2ggPSBtZDUoICR0aGVtZS0+dGhlbWVfcm9vdCAuICcvJyAuICR0aGVtZS0+c3R5bGVzaGVldCApOwoJCQlmb3JlYWNoICggWyAndGhlbWUnLCAnc2NyZWVuc2hvdCcsICdoZWFkZXJzJywgJ3BhZ2VfdGVtcGxhdGVzJyBdIGFzICRrZXkgKSB7CgkJCQl3cF9jYWNoZV9kZWxldGUoICRrZXkgLiAnLScgLiAkY2FjaGVfaGFzaCwgJ3RoZW1lcycgKTsKCQkJfQoJCX0KCgkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdJbnN0YWxsaW5nICVzICglcyknLCBodG1sX2VudGl0eV9kZWNvZGUoICRhcGktPm5hbWUsIEVOVF9RVU9URVMgKSwgJGFwaS0+dmVyc2lvbiApICk7CgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2ZXJzaW9uJyApICE9PSAnZGV2JyApIHsKCQkJV1BfQ0xJOjpnZXRfaHR0cF9jYWNoZV9tYW5hZ2VyKCktPndoaXRlbGlzdF9wYWNrYWdlKCAkYXBpLT5kb3dubG9hZF9saW5rLCAkdGhpcy0+aXRlbV90eXBlLCAkYXBpLT5zbHVnLCAkYXBpLT52ZXJzaW9uICk7CgkJfQoKCQkvLyBJZ25vcmUgZmFpbHVyZXMgb24gYWNjZXNzaW5nIFNTTCAiaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy90aGVtZXMvdXBkYXRlLWNoZWNrLzEuMS8iIGluIGB3cF91cGRhdGVfdGhlbWVzKClgIHdoaWNoIHNlZW0gdG8gb2NjdXIgaW50ZXJtaXR0ZW50bHkuCgkJc2V0X2Vycm9yX2hhbmRsZXIoIGFycmF5KCBfX0NMQVNTX18sICdlcnJvcl9oYW5kbGVyJyApLCBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UgKTsKCgkJJHJlc3VsdCA9ICR0aGlzLT5nZXRfdXBncmFkZXIoICRhc3NvY19hcmdzICktPmluc3RhbGwoICRhcGktPmRvd25sb2FkX2xpbmsgKTsKCgkJcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfaXRlbV9saXN0KCkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2FsbF90aGVtZXMoKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZmlsdGVyX2l0ZW1fbGlzdCggJGl0ZW1zLCAkYXJncyApIHsKCQkkdGhlbWVfZmlsZXMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkYXJnICkgewoJCQkkdGhlbWVfZmlsZXNbXSA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmcgKS0+Z2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCk7CgkJfQoKCQlyZXR1cm4gVXRpbHNccGlja19maWVsZHMoICRpdGVtcywgJHRoZW1lX2ZpbGVzICk7Cgl9CgoJLyoqCgkgKiBJbnN0YWxscyBvbmUgb3IgbW9yZSB0aGVtZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZXx6aXB8dXJsPi4uLgoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gaW5zdGFsbC4gQWNjZXB0cyBhIHRoZW1lIHNsdWcsIHRoZSBwYXRoIHRvIGEgbG9jYWwgemlwIGZpbGUsIG9yIGEgVVJMIHRvIGEgcmVtb3RlIHppcCBmaWxlLgoJICoKCSAqIFstLXZlcnNpb249PHZlcnNpb24+XQoJICogOiBJZiBzZXQsIGdldCB0aGF0IHBhcnRpY3VsYXIgdmVyc2lvbiBmcm9tIHdvcmRwcmVzcy5vcmcsIGluc3RlYWQgb2YgdGhlCgkgKiBzdGFibGUgdmVyc2lvbi4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogSWYgc2V0LCB0aGUgY29tbWFuZCB3aWxsIG92ZXJ3cml0ZSBhbnkgaW5zdGFsbGVkIHZlcnNpb24gb2YgdGhlIHRoZW1lLCB3aXRob3V0IHByb21wdGluZwoJICogZm9yIGNvbmZpcm1hdGlvbi4KCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogSWYgc2V0LCB0aGUgdGhlbWUgd2lsbCBiZSBhY3RpdmF0ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaW5zdGFsbC4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluc3RhbGwgdGhlIGxhdGVzdCB2ZXJzaW9uIGZyb20gd29yZHByZXNzLm9yZyBhbmQgYWN0aXZhdGUKCSAqICAgICAkIHdwIHRoZW1lIGluc3RhbGwgdHdlbnR5c2l4dGVlbiAtLWFjdGl2YXRlCgkgKiAgICAgSW5zdGFsbGluZyBUd2VudHkgU2l4dGVlbiAoMS4yKQoJICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHA6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS90d2VudHlzaXh0ZWVuLjEuMi56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSB0aGVtZS4uLgoJICogICAgIFRoZW1lIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgQWN0aXZhdGluZyAndHdlbnR5c2l4dGVlbicuLi4KCSAqICAgICBTdWNjZXNzOiBTd2l0Y2hlZCB0byAnVHdlbnR5IFNpeHRlZW4nIHRoZW1lLgoJICoKCSAqICAgICAjIEluc3RhbGwgZnJvbSBhIGxvY2FsIHppcCBmaWxlCgkgKiAgICAgJCB3cCB0aGVtZSBpbnN0YWxsIC4uL215LXRoZW1lLnppcAoJICoKCSAqICAgICAjIEluc3RhbGwgZnJvbSBhIHJlbW90ZSB6aXAgZmlsZQoJICogICAgICQgd3AgdGhlbWUgaW5zdGFsbCBodHRwOi8vczMuYW1hem9uYXdzLmNvbS9idWNrZXRuYW1lL215LXRoZW1lLnppcD9BV1NBY2Nlc3NLZXlJZD0xMjMmRXhwaXJlcz00NTYmU2lnbmF0dXJlPWFiY2RlZgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkdGhlbWVfcm9vdCA9IGdldF90aGVtZV9yb290KCk7CgkJaWYgKCAkdGhlbWVfcm9vdCAmJiAhIGlzX2RpciggJHRoZW1lX3Jvb3QgKSApIHsKCQkJd3BfbWtkaXJfcCggJHRoZW1lX3Jvb3QgKTsKCQkJcmVnaXN0ZXJfdGhlbWVfZGlyZWN0b3J5KCAkdGhlbWVfcm9vdCApOwoJCX0KCgkJcGFyZW50OjppbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEdldHMgZGV0YWlscyBhYm91dCBhIHRoZW1lLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWU+CgkgKiA6IFRoZSB0aGVtZSB0byBnZXQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogSW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIHdob2xlIHRoZW1lLCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHRoZW1lIGdldCB0d2VudHlzaXh0ZWVuIC0tZmllbGRzPW5hbWUsdGl0bGUsdmVyc2lvbgoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IEZpZWxkICAgfCBWYWx1ZSAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICB8IFR3ZW50eSBTaXh0ZWVuIHwKCSAqICAgICB8IHRpdGxlICAgfCBUd2VudHkgU2l4dGVlbiB8CgkgKiAgICAgfCB2ZXJzaW9uIHwgMS4yICAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0aGVtZSA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgoJCSRlcnJvcnMgPSAkdGhlbWUtPmVycm9ycygpOwoJCWlmICggaXNfd3BfZXJyb3IoICRlcnJvcnMgKSApIHsKCQkJJG1lc3NhZ2UgPSAkZXJyb3JzLT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJCQlXUF9DTEk6OmVycm9yKCAkbWVzc2FnZSApOwoJCX0KCgkJLy8gV1BfVGhlbWUgb2JqZWN0IGVtcGxveXMgbWFnaWMgZ2V0dGVyLCB1bmZvcnR1bmF0ZWx5LgoJCSR0aGVtZV92YXJzID0gWwoJCQknbmFtZScsCgkJCSd0aXRsZScsCgkJCSd2ZXJzaW9uJywKCQkJJ3N0YXR1cycsCgkJCSdwYXJlbnRfdGhlbWUnLAoJCQkndGVtcGxhdGVfZGlyJywKCQkJJ3N0eWxlc2hlZXRfZGlyJywKCQkJJ3RlbXBsYXRlJywKCQkJJ3N0eWxlc2hlZXQnLAoJCQknc2NyZWVuc2hvdCcsCgkJCSdkZXNjcmlwdGlvbicsCgkJCSdhdXRob3InLAoJCQkndGFncycsCgkJCSd0aGVtZV9yb290JywKCQkJJ3RoZW1lX3Jvb3RfdXJpJywKCQldOwoJCSR0aGVtZV9vYmogID0gbmV3IHN0ZENsYXNzKCk7CgkJZm9yZWFjaCAoICR0aGVtZV92YXJzIGFzICR2YXIgKSB7CgkJCSR0aGVtZV9vYmotPiR2YXIgPSAkdGhlbWUtPiR2YXI7CgkJfQoKCQkkdGhlbWVfb2JqLT5zdGF0dXMgICAgICA9ICR0aGlzLT5nZXRfc3RhdHVzKCAkdGhlbWUgKTsKCQkkdGhlbWVfb2JqLT5kZXNjcmlwdGlvbiA9IHdvcmR3cmFwKCAkdGhlbWVfb2JqLT5kZXNjcmlwdGlvbiApOwoKCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2ZpZWxkcyddID0gJHRoZW1lX3ZhcnM7CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtKCAkdGhlbWVfb2JqICk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIG9uZSBvciBtb3JlIHRoZW1lcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHRoZW1lcyB0byB1cGRhdGUuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCB0aGVtZXMgdGhhdCBoYXZlIHVwZGF0ZXMgd2lsbCBiZSB1cGRhdGVkLgoJICoKCSAqIFstLWV4Y2x1ZGU9PHRoZW1lLW5hbWVzPl0KCSAqIDogQ29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgdGhlbWUgbmFtZXMgdGhhdCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSB1cGRhdGluZy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gc3VtbWFyeQoJICogLS0tCgkgKgoJICogWy0tdmVyc2lvbj08dmVyc2lvbj5dCgkgKiA6IElmIHNldCwgdGhlIHRoZW1lIHdpbGwgYmUgdXBkYXRlZCB0byB0aGUgc3BlY2lmaWVkIHZlcnNpb24uCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogUHJldmlldyB3aGljaCB0aGVtZXMgd291bGQgYmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSBtdWx0aXBsZSB0aGVtZXMKCSAqICAgICAkIHdwIHRoZW1lIHVwZGF0ZSB0d2VudHlmaWZ0ZWVuIHR3ZW50eXNpeHRlZW4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RoZW1lL3R3ZW50eWZpZnRlZW4uMS41LnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHRoZW1lLi4uCgkgKiAgICAgVGhlbWUgdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy90aGVtZS90d2VudHlzaXh0ZWVuLjEuMi56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSB0aGVtZS4uLgoJICogICAgIFRoZW1lIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgICstLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgfCBvbGRfdmVyc2lvbiB8IG5ld192ZXJzaW9uIHwgc3RhdHVzICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgdHdlbnR5ZmlmdGVlbiB8IDEuNCAgICAgICAgIHwgMS41ICAgICAgICAgfCBVcGRhdGVkIHwKCSAqICAgICB8IHR3ZW50eXNpeHRlZW4gfCAxLjEgICAgICAgICB8IDEuMiAgICAgICAgIHwgVXBkYXRlZCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgMiBvZiAyIHRoZW1lcy4KCSAqCgkgKiAgICAgIyBFeGNsdWRlIHRoZW1lcyB1cGRhdGVzIHdoZW4gYnVsayB1cGRhdGluZyB0aGUgdGhlbWVzCgkgKiAgICAgJCB3cCB0aGVtZSB1cGRhdGUgLS1hbGwgLS1leGNsdWRlPXR3ZW50eWZpZnRlZW4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RoZW1lL2FzdHJhLjEuMC41LjEuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgdGhlbWUuLi4KCSAqICAgICBUaGVtZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RoZW1lL3R3ZW50eXNldmVudGVlbi4xLjIuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgdGhlbWUuLi4KCSAqICAgICBUaGVtZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgICB8IHN0YXR1cyAgIHwgdmVyc2lvbiB8IHVwZGF0ZV92ZXJzaW9uIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGFzdHJhICAgICAgICAgICB8IGluYWN0aXZlIHwgMS4wLjEgICB8IDEuMC41LjEgICAgICAgIHwKCSAqICAgICB8IHR3ZW50eXNldmVudGVlbiB8IGluYWN0aXZlIHwgMS4xICAgICB8IDEuMiAgICAgICAgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIDIgb2YgMiB0aGVtZXMuCgkgKgoJICogICAgICMgVXBkYXRlIGFsbCB0aGVtZXMKCSAqICAgICAkIHdwIHRoZW1lIHVwZGF0ZSAtLWFsbAoJICoKCSAqIEBhbGlhcyB1cGdyYWRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICYmIGlzc2V0KCAkYXNzb2NfYXJnc1snZHJ5LXJ1biddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICctLWRyeS1ydW4gY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCAtLXZlcnNpb24uJyApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICkgewoJCQlmb3JlYWNoICggJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApIGFzICR0aGVtZSApIHsKCQkJCSRyID0gZGVsZXRlX3RoZW1lKCAkdGhlbWUtPnN0eWxlc2hlZXQgKTsKCQkJCWlmICggaXNfd3BfZXJyb3IoICRyICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkciApOwoJCQkJfSBlbHNlIHsKCQkJCQkkYXNzb2NfYXJnc1snZm9yY2UnXSA9IHRydWU7CgkJCQkJJHRoaXMtPmluc3RhbGwoIGFycmF5KCAkdGhlbWUtPnN0eWxlc2hlZXQgKSwgJGFzc29jX2FyZ3MgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCXBhcmVudDo6dXBkYXRlX21hbnkoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyBpZiBhIGdpdmVuIHRoZW1lIGlzIGluc3RhbGxlZC4KCSAqCgkgKiBSZXR1cm5zIGV4aXQgY29kZSAwIHdoZW4gaW5zdGFsbGVkLCAxIHdoZW4gdW5pbnN0YWxsZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlIHRoZW1lIHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgd2hldGhlciB0aGVtZSBpcyBpbnN0YWxsZWQ7IGV4aXQgc3RhdHVzIDAgaWYgaW5zdGFsbGVkLCBvdGhlcndpc2UgMQoJICogICAgICQgd3AgdGhlbWUgaXMtaW5zdGFsbGVkIGhlbGxvCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWluc3RhbGxlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfaW5zdGFsbGVkKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSR0aGVtZSA9IHdwX2dldF90aGVtZSggJGFyZ3NbMF0gKTsKCgkJaWYgKCAkdGhlbWUtPmV4aXN0cygpICkgewoJCQlXUF9DTEk6OmhhbHQoIDAgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSBnaXZlbiB0aGVtZSBpcyBhY3RpdmUuCgkgKgoJICogUmV0dXJucyBleGl0IGNvZGUgMCB3aGVuIGFjdGl2ZSwgMSB3aGVuIG5vdCBhY3RpdmUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlIHBsdWdpbiB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgdGhlbWUgaXMgQWN0aXZlOyBleGl0IHN0YXR1cyAwIGlmIGFjdGl2ZSwgb3RoZXJ3aXNlIDEKCSAqICAgICAkIHdwIHRoZW1lIGlzLWFjdGl2ZSB0d2VudHlmaWZ0ZWVuCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWFjdGl2ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfYWN0aXZlKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSR0aGVtZSA9IHdwX2dldF90aGVtZSggJGFyZ3NbMF0gKTsKCgkJaWYgKCAhICR0aGVtZS0+ZXhpc3RzKCkgKSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCgkJJHRoaXMtPmlzX2FjdGl2ZV90aGVtZSggJHRoZW1lICkgPyBXUF9DTEk6OmhhbHQoIDAgKSA6IFdQX0NMSTo6aGFsdCggMSApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBvbmUgb3IgbW9yZSB0aGVtZXMuCgkgKgoJICogUmVtb3ZlcyB0aGUgdGhlbWUgb3IgdGhlbWVzIGZyb20gdGhlIGZpbGVzeXN0ZW0uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGhlbWU+Li4uXQoJICogOiBPbmUgb3IgbW9yZSB0aGVtZXMgdG8gZGVsZXRlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgdGhlbWVzIHdpbGwgYmUgZGVsZXRlZCBleGNlcHQgYWN0aXZlIHRoZW1lLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBUbyBkZWxldGUgYWN0aXZlIHRoZW1lIHVzZSB0aGlzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgdGhlbWUgZGVsZXRlIHR3ZW50eXR3ZWx2ZQoJICogICAgIERlbGV0ZWQgJ3R3ZW50eXR3ZWx2ZScgdGhlbWUuCgkgKiAgICAgU3VjY2VzczogRGVsZXRlZCAxIG9mIDEgdGhlbWVzLgoJICoKCSAqIEBhbGlhcyB1bmluc3RhbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkYWxsID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCwgJ2RlbGV0ZScgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRmb3JjZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJywgZmFsc2UgKTsKCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJZm9yZWFjaCAoICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKSBhcyAkdGhlbWUgKSB7CgkJCSR0aGVtZV9zbHVnID0gJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpOwoKCQkJaWYgKCAkdGhpcy0+aXNfYWN0aXZlX3RoZW1lKCAkdGhlbWUgKSAmJiAhICRmb3JjZSApIHsKCQkJCWlmICggISAkYWxsICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkNhbid0IGRlbGV0ZSB0aGUgY3VycmVudGx5IGFjdGl2ZSB0aGVtZTogJHRoZW1lX3NsdWciICk7CgkJCQkJJGVycm9ycysrOwoJCQkJfQoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyID0gZGVsZXRlX3RoZW1lKCAkdGhlbWVfc2x1ZyApOwoKCQkJaWYgKCBpc193cF9lcnJvciggJHIgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJHIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiRGVsZXRlZCAnJHRoZW1lX3NsdWcnIHRoZW1lLiIgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCQlpZiAoICEgJHRoaXMtPmNoYWluZWRfY29tbWFuZCApIHsKCQkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAndGhlbWUnLCAnZGVsZXRlJywgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiB0aGVtZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmlsdGVyIHJlc3VsdHMgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGEgZmllbGQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCB0aGVtZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiBbLS1zdGF0dXM9PHN0YXR1cz5dCgkgKiA6IEZpbHRlciB0aGUgb3V0cHV0IGJ5IHRoZW1lIHN0YXR1cy4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBhY3RpdmUKCSAqICAgLSBwYXJlbnQKCSAqICAgLSBpbmFjdGl2ZQoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHRoZW1lOgoJICoKCSAqICogbmFtZQoJICogKiBzdGF0dXMKCSAqICogdXBkYXRlCgkgKiAqIHZlcnNpb24KCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogdXBkYXRlX3ZlcnNpb24KCSAqICogdXBkYXRlX3BhY2thZ2UKCSAqICogdXBkYXRlX2lkCgkgKiAqIHRpdGxlCgkgKiAqIGRlc2NyaXB0aW9uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IHRoZW1lcwoJICogICAgICQgd3AgdGhlbWUgbGlzdCAtLXN0YXR1cz1pbmFjdGl2ZSAtLWZvcm1hdD1jc3YKCSAqICAgICBuYW1lLHN0YXR1cyx1cGRhdGUsdmVyc2lvbgoJICogICAgIHR3ZW50eWZvdXJ0ZWVuLGluYWN0aXZlLG5vbmUsMS43CgkgKiAgICAgdHdlbnR5c2l4dGVlbixpbmFjdGl2ZSxhdmFpbGFibGUsMS4xCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRfLCAkYXNzb2NfYXJncyApIHsKCQlwYXJlbnQ6Ol9saXN0KCAkXywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHRlbXBsYXRlIHBhdGggYmFzZWQgb24gaW5zdGFsbGF0aW9uIHR5cGUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF90ZW1wbGF0ZV9wYXRoKCAkdGVtcGxhdGUgKSB7CgkJJGNvbW1hbmRfcm9vdCAgPSBVdGlsc1xwaGFyX3NhZmVfcGF0aCggZGlybmFtZSggX19ESVJfXyApICk7CgkJJHRlbXBsYXRlX3BhdGggPSAieyRjb21tYW5kX3Jvb3R9L3RlbXBsYXRlcy97JHRlbXBsYXRlfSI7CgoJCWlmICggISBmaWxlX2V4aXN0cyggJHRlbXBsYXRlX3BhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGZpbmQgeyR0ZW1wbGF0ZX0iICk7CgkJfQoKCQlyZXR1cm4gJHRlbXBsYXRlX3BhdGg7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcRmV0Y2hlcnNcUGx1Z2luOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKdXNlIFdQX0NMSVxQYXJzZVBsdWdpbk5hbWVJbnB1dDsKdXNlIFdQX0NMSVxVdGlsczsKCi8qKgogKiBNYW5hZ2VzIHBsdWdpbiBhdXRvLXVwZGF0ZXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEVuYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGVuYWJsZSBhY3RpdmF0ZSBoZWxsbwogKiAgICAgUGx1Z2luIGF1dG8tdXBkYXRlcyBmb3IgJ2hlbGxvJyBlbmFibGVkLgogKiAgICAgU3VjY2VzczogRW5hYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KICoKICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGRpc2FibGUgYWN0aXZhdGUgaGVsbG8KICogICAgIFBsdWdpbiBhdXRvLXVwZGF0ZXMgZm9yICdoZWxsbycgZGlzYWJsZWQuCiAqICAgICBTdWNjZXNzOiBEaXNhYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KICoKICogICAgICMgR2V0IHRoZSBzdGF0dXMgb2YgcGx1Z2luIGF1dG8tdXBkYXRlcwogKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIHN0YXR1cyBoZWxsbwogKiAgICAgQXV0by11cGRhdGVzIGZvciBwbHVnaW4gJ2hlbGxvJyBhcmUgZGlzYWJsZWQuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgUGx1Z2luX0F1dG9VcGRhdGVzX0NvbW1hbmQgewoKCXVzZSBQYXJzZVBsdWdpbk5hbWVJbnB1dDsKCgkvKioKCSAqIFNpdGUgb3B0aW9uIHRoYXQgc3RvcmVzIHRoZSBzdGF0dXMgb2YgcGx1Z2luIGF1dG8tdXBkYXRlcy4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBTSVRFX09QVElPTiA9ICdhdXRvX3VwZGF0ZV9wbHVnaW5zJzsKCgkvKioKCSAqIFBsdWdpbiBmZXRjaGVyIGluc3RhbmNlLgoJICoKCSAqIEB2YXIgUGx1Z2luCgkgKi8KCXByb3RlY3RlZCAkZmV0Y2hlcjsKCgkvKioKCSAqIFBsdWdpbl9BdXRvVXBkYXRlc19Db21tYW5kIGNvbnN0cnVjdG9yLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgUGx1Z2luKCk7Cgl9CgoJLyoqCgkgKiBFbmFibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gZW5hYmxlIGF1dG8tdXBkYXRlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF1dG8tdXBkYXRlcyB3aWxsIGJlIGVuYWJsZWQgZm9yIGFsbCBwbHVnaW5zLgoJICoKCSAqIFstLWRpc2FibGVkLW9ubHldCgkgKiA6IElmIHNldCwgZmlsdGVycyBsaXN0IG9mIHBsdWdpbnMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGRpc2FibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRW5hYmxlIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luCgkgKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIGVuYWJsZSBhY3RpdmF0ZSBoZWxsbwoJICogICAgIFBsdWdpbiBhdXRvLXVwZGF0ZXMgZm9yICdoZWxsbycgZW5hYmxlZC4KCSAqICAgICBTdWNjZXNzOiBFbmFibGVkIDEgb2YgMSBwbHVnaW4gYXV0by11cGRhdGVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZW5hYmxlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoJCSRkaXNhYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGlzYWJsZWQtb25seScsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRwbHVnaW5zICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJJGF1dG9fdXBkYXRlcyA9IGdldF9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiApOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b191cGRhdGVzICkgewoJCQkkYXV0b191cGRhdGVzID0gW107CgkJfQoKCQkkY291bnQgICAgID0gMDsKCQkkc3VjY2Vzc2VzID0gMDsKCgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW4gKSB7CgkJCSRlbmFibGVkID0gaW5fYXJyYXkoICRwbHVnaW4tPmZpbGUsICRhdXRvX3VwZGF0ZXMsIHRydWUgKTsKCgkJCWlmICggJGRpc2FibGVkX29ubHkgJiYgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICRlbmFibGVkICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCSJBdXRvLXVwZGF0ZXMgYWxyZWFkeSBlbmFibGVkIGZvciBwbHVnaW4geyRwbHVnaW4tPm5hbWV9LiIKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkkYXV0b191cGRhdGVzW10gPSAkcGx1Z2luLT5maWxlOwoJCQkJJHN1Y2Nlc3NlcysrOwoJCQl9CgkJfQoKCQlpZiAoIDAgPT09ICRjb3VudCApIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSdObyBwbHVnaW5zIHByb3ZpZGVkIHRvIGVuYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLicKCQkJKTsKCQl9CgoJCXVwZGF0ZV9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiwgJGF1dG9fdXBkYXRlcyApOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4gYXV0by11cGRhdGUnLAoJCQknZW5hYmxlJywKCQkJJGNvdW50LAoJCQkkc3VjY2Vzc2VzLAoJCQkkY291bnQgLSAkc3VjY2Vzc2VzCgkJKTsKCX0KCgkvKioKCSAqIERpc2FibGVzIHRoZSBhdXRvLXVwZGF0ZXMgZm9yIGEgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHBsdWdpbnMgdG8gZGlzYWJsZSBhdXRvLXVwZGF0ZXMgZm9yLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhdXRvLXVwZGF0ZXMgd2lsbCBiZSBkaXNhYmxlZCBmb3IgYWxsIHBsdWdpbnMuCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiBwbHVnaW5zIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzYWJsZSB0aGUgYXV0by11cGRhdGVzIGZvciBhIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIGF1dG8tdXBkYXRlcyBkaXNhYmxlIGFjdGl2YXRlIGhlbGxvCgkgKiAgICAgUGx1Z2luIGF1dG8tdXBkYXRlcyBmb3IgJ2hlbGxvJyBkaXNhYmxlZC4KCSAqICAgICBTdWNjZXNzOiBEaXNhYmxlZCAxIG9mIDEgcGx1Z2luIGF1dG8tdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc2FibGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCQkkZW5hYmxlZF9vbmx5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGFsbCApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHBsdWdpbnMgICAgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQkkYXV0b191cGRhdGVzID0gZ2V0X3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgoJCWlmICggZmFsc2UgPT09ICRhdXRvX3VwZGF0ZXMgKSB7CgkJCSRhdXRvX3VwZGF0ZXMgPSBbXTsKCQl9CgoJCSRjb3VudCAgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHBsdWdpbi0+ZmlsZSwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGNvdW50Kys7CgoJCQlpZiAoICEgJGVuYWJsZWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoCgkJCQkJIkF1dG8tdXBkYXRlcyBhbHJlYWR5IGRpc2FibGVkIGZvciBwbHVnaW4geyRwbHVnaW4tPm5hbWV9LiIKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQkkYXV0b191cGRhdGVzID0gYXJyYXlfZGlmZiggJGF1dG9fdXBkYXRlcywgWyAkcGx1Z2luLT5maWxlIF0gKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0KCgkJaWYgKCAwID09PSAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknTm8gcGx1Z2lucyBwcm92aWRlZCB0byBkaXNhYmxlIGF1dG8tdXBkYXRlcyBmb3IuJwoJCQkpOwoJCX0KCgkJaWYgKCBjb3VudCggJGF1dG9fdXBkYXRlcyApID4gMCApIHsKCQkJdXBkYXRlX3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OLCAkYXV0b191cGRhdGVzICk7CgkJfSBlbHNlIHsKCQkJZGVsZXRlX3NpdGVfb3B0aW9uKCBzdGF0aWM6OlNJVEVfT1BUSU9OICk7CgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4gYXV0by11cGRhdGUnLAoJCQknZGlzYWJsZScsCgkJCSRjb3VudCwKCQkJJHN1Y2Nlc3NlcywKCQkJJGNvdW50IC0gJHN1Y2Nlc3NlcwoJCSk7Cgl9CgoJLyoqCgkgKiBTaG93cyB0aGUgc3RhdHVzIG9mIGF1dG8tdXBkYXRlcyBmb3IgYSBwbHVnaW4uCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byBzaG93IHRoZSBzdGF0dXMgb2YgdGhlIGF1dG8tdXBkYXRlcyBvZi4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgdGhlIHN0YXR1cyBvZiBhdXRvLXVwZGF0ZXMgZm9yIGFsbCBwbHVnaW5zIHdpbGwgYmUgc2hvd24uCgkgKgoJICogWy0tZW5hYmxlZC1vbmx5XQoJICogOiBJZiBzZXQsIGZpbHRlcnMgbGlzdCBvZiBwbHVnaW5zIHRvIG9ubHkgaW5jbHVkZSB0aGUgb25lcyB0aGF0IGhhdmUKCSAqIGF1dG8tdXBkYXRlcyBlbmFibGVkLgoJICoKCSAqIFstLWRpc2FibGVkLW9ubHldCgkgKiA6IElmIHNldCwgZmlsdGVycyBsaXN0IG9mIHBsdWdpbnMgdG8gb25seSBpbmNsdWRlIHRoZSBvbmVzIHRoYXQgaGF2ZQoJICogYXV0by11cGRhdGVzIGRpc2FibGVkLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IE9ubHkgc2hvdyB0aGUgcHJvdmlkZWQgZmllbGQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgdGhlIHN0YXR1cyBvZiBwbHVnaW4gYXV0by11cGRhdGVzCgkgKiAgICAgJCB3cCBwbHVnaW4gYXV0by11cGRhdGVzIHN0YXR1cyBoZWxsbwoJICogICAgICstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICB8IHN0YXR1cyAgIHwKCSAqICAgICArLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgaGVsbG8gfCBkaXNhYmxlZCB8CgkgKiAgICAgKy0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBHZXQgdGhlIGxpc3Qgb2YgcGx1Z2lucyB0aGF0IGhhdmUgYXV0by11cGRhdGVzIGVuYWJsZWQKCSAqICAgICAkIHdwIHBsdWdpbiBhdXRvLXVwZGF0ZXMgc3RhdHVzIC0tYWxsIC0tZW5hYmxlZC1vbmx5IC0tZmllbGQ9bmFtZQoJICogICAgIGFraXNtZXQKCSAqICAgICBkdXBsaWNhdGUtcG9zdAoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoJCSRlbmFibGVkX29ubHkgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZW5hYmxlZC1vbmx5JywgZmFsc2UgKTsKCQkkZGlzYWJsZWRfb25seSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Rpc2FibGVkLW9ubHknLCBmYWxzZSApOwoKCQlpZiAoICRlbmFibGVkX29ubHkgJiYgJGRpc2FibGVkX29ubHkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQknLS1lbmFibGVkLW9ubHkgYW5kIC0tZGlzYWJsZWQtb25seSBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGFuZCAnCgkJCQkuICdjYW5ub3QgYmUgdXNlZCBhdCB0aGUgc2FtZSB0aW1lLicKCQkJKTsKCQl9CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRwbHVnaW5zICAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJJGF1dG9fdXBkYXRlcyA9IGdldF9zaXRlX29wdGlvbiggc3RhdGljOjpTSVRFX09QVElPTiApOwoKCQlpZiAoIGZhbHNlID09PSAkYXV0b191cGRhdGVzICkgewoJCQkkYXV0b191cGRhdGVzID0gW107CgkJfQoKCQkkcmVzdWx0cyA9IFtdOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJGVuYWJsZWQgPSBpbl9hcnJheSggJHBsdWdpbi0+ZmlsZSwgJGF1dG9fdXBkYXRlcywgdHJ1ZSApOwoKCQkJaWYgKCAkZW5hYmxlZF9vbmx5ICYmICEgJGVuYWJsZWQgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAkZGlzYWJsZWRfb25seSAmJiAkZW5hYmxlZCApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkcmVzdWx0c1tdID0gWwoJCQkJJ25hbWUnICAgPT4gJHBsdWdpbi0+bmFtZSwKCQkJCSdmaWxlJyAgID0+ICRwbHVnaW4tPmZpbGUsCgkJCQknc3RhdHVzJyA9PiAkZW5hYmxlZCA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCcsCgkJCV07CgkJfQoKCQkkZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsIFsgJ25hbWUnLCAnc3RhdHVzJyBdLCAncGx1Z2luJyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRyZXN1bHRzICk7Cgl9Cn0KPD9waHAKCi8qKgogKiBTZXRzLCBnZXRzLCBhbmQgcmVtb3ZlcyB0aGVtZSBtb2RzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBTZXQgdGhlICdiYWNrZ3JvdW5kX2NvbG9yJyB0aGVtZSBtb2QgdG8gJzAwMDAwMCcuCiAqICAgICAkIHdwIHRoZW1lIG1vZCBzZXQgYmFja2dyb3VuZF9jb2xvciAwMDAwMDAKICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZCBiYWNrZ3JvdW5kX2NvbG9yIHNldCB0byAwMDAwMDAKICoKICogICAgICMgR2V0IHNpbmdsZSB0aGVtZSBtb2QgaW4gSlNPTiBmb3JtYXQuCiAqICAgICAkIHdwIHRoZW1lIG1vZCBnZXQgYmFja2dyb3VuZF9jb2xvciAtLWZvcm1hdD1qc29uCiAqICAgICBbeyJrZXkiOiJiYWNrZ3JvdW5kX2NvbG9yIiwidmFsdWUiOiJkZDMzMzMifV0KICoKICogICAgICMgUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgogKiAgICAgJCB3cCB0aGVtZSBtb2QgcmVtb3ZlIC0tYWxsCiAqICAgICBTdWNjZXNzOiBUaGVtZSBtb2RzIHJlbW92ZWQuCiAqLwpjbGFzcyBUaGVtZV9Nb2RfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBbICdrZXknLCAndmFsdWUnIF07CgoJLyoqCgkgKiBHZXRzIG9uZSBvciBtb3JlIHRoZW1lIG1vZHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8bW9kPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgbW9kcyB0byBnZXQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tYWxsXQoJICogOiBMaXN0IGFsbCB0aGVtZSBtb2RzCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0ganNvbgoJICogICAtIGNzdgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IGFsbCB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCAtLWFsbAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwga2V5ICAgICAgICAgICAgICB8IHZhbHVlICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYmFja2dyb3VuZF9jb2xvciB8IGRkMzMzMyAgfAoJICogICAgIHwgbGlua19jb2xvciAgICAgICB8ICNkZDk5MzMgfAoJICogICAgIHwgbWFpbl90ZXh0X2NvbG9yICB8ICM4MjI0ZTMgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIEdldCBzaW5nbGUgdGhlbWUgbW9kIGluIEpTT04gZm9ybWF0LgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCBiYWNrZ3JvdW5kX2NvbG9yIC0tZm9ybWF0PWpzb24KCSAqICAgICBbeyJrZXkiOiJiYWNrZ3JvdW5kX2NvbG9yIiwidmFsdWUiOiJkZDMzMzMifV0KCSAqCgkgKiAgICAgIyBHZXQgdmFsdWUgb2YgYSBzaW5nbGUgdGhlbWUgbW9kLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGdldCBiYWNrZ3JvdW5kX2NvbG9yIC0tZmllbGQ9dmFsdWUKCSAqICAgICBkZDMzMzMKCSAqCgkgKiAgICAgIyBHZXQgbXVsdGlwbGUgdGhlbWUgbW9kcy4KCSAqICAgICAkIHdwIHRoZW1lIG1vZCBnZXQgYmFja2dyb3VuZF9jb2xvciBoZWFkZXJfdGV4dGNvbG9yCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKiAgICAgfCBiYWNrZ3JvdW5kX2NvbG9yIHwgZGQzMzMzIHwKCSAqICAgICB8IGhlYWRlcl90ZXh0Y29sb3IgfCAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzID0gYXJyYXkoKSwgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoKCQlpZiAoICEgXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdZb3UgbXVzdCBzcGVjaWZ5IGF0IGxlYXN0IG9uZSBtb2Qgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCWlmICggXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgKSB7CgkJCSRhcmdzID0gYXJyYXkoKTsKCQl9CgoJCSRsaXN0ID0gYXJyYXkoKTsKCQkkbW9kcyA9IGdldF90aGVtZV9tb2RzKCk7CgkJaWYgKCAhIGlzX2FycmF5KCAkbW9kcyApICkgewoJCQkvLyBJZiBubyBtb2RzIGFyZSBzZXQgKHBlcmhhcHMgbmV3IHRoZW1lKSwgbWFrZSBzdXJlIGZvcmVhY2ggc3RpbGwgd29ya3MuCgkJCSRtb2RzID0gYXJyYXkoKTsKCQl9CgkJZm9yZWFjaCAoICRtb2RzIGFzICRrID0+ICR2ICkgewoJCQkvLyBJZiBtb2RzIHdlcmUgZ2l2ZW4sIHNraXAgdGhlIG90aGVycy4KCQkJaWYgKCAhIGVtcHR5KCAkYXJncyApICYmICEgaW5fYXJyYXkoICRrLCAkYXJncywgdHJ1ZSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggaXNfYXJyYXkoICR2ICkgKSB7CgkJCQkkbGlzdFtdID0gWwoJCQkJCSdrZXknICAgPT4gJGssCgkJCQkJJ3ZhbHVlJyA9PiAnPT4nLAoJCQkJXTsKCQkJCWZvcmVhY2ggKCAkdiBhcyAkX2sgPT4gJF92ICkgewoJCQkJCSRsaXN0W10gPSBbCgkJCQkJCSdrZXknICAgPT4gIiAgICAkX2siLAoJCQkJCQkndmFsdWUnID0+ICRfdiwKCQkJCQldOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJGxpc3RbXSA9IFsKCQkJCQkna2V5JyAgID0+ICRrLAoJCQkJCSd2YWx1ZScgPT4gJHYsCgkJCQldOwoJCQl9CgkJfQoKCQkvLyBGb3IgdW5zZXQgbW9kcywgc2hvdyBibGFuayB2YWx1ZS4KCQlmb3JlYWNoICggJGFyZ3MgYXMgJG1vZCApIHsKCQkJaWYgKCAhIGlzc2V0KCAkbW9kc1sgJG1vZCBdICkgKSB7CgkJCQkkbGlzdFtdID0gWwoJCQkJCSdrZXknICAgPT4gJG1vZCwKCQkJCQkndmFsdWUnID0+ICcnLAoJCQkJXTsKCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICd0aGVtZW1vZHMnICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGxpc3QgKTsKCgl9CgoJLyoqCgkgKiBHZXRzIGEgbGlzdCBvZiB0aGVtZSBtb2RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBqc29uCgkgKiAgIC0gY3N2CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXRzIGEgbGlzdCBvZiB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIGxpc3QKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IGJhY2tncm91bmRfY29sb3IgfCBkZDMzMzMgIHwKCSAqICAgICB8IGxpbmtfY29sb3IgICAgICAgfCAjZGQ5OTMzIHwKCSAqICAgICB8IG1haW5fdGV4dF9jb2xvciAgfCAjODIyNGUzIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MgPSBhcnJheSgpLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgoJCSRhc3NvY19hcmdzWydhbGwnXSA9IDE7CgoJCSR0aGlzLT5nZXQoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBvbmUgb3IgbW9yZSB0aGVtZSBtb2RzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPG1vZD4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIG1vZHMgdG8gcmVtb3ZlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVtb3ZlIGFsbCB0aGVtZSBtb2RzLgoJICogICAgICQgd3AgdGhlbWUgbW9kIHJlbW92ZSAtLWFsbAoJICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZHMgcmVtb3ZlZC4KCSAqCgkgKiAgICAgIyBSZW1vdmUgc2luZ2xlIHRoZW1lIG1vZC4KCSAqICAgICAkIHdwIHRoZW1lIG1vZCByZW1vdmUgYmFja2dyb3VuZF9jb2xvcgoJICogICAgIFN1Y2Nlc3M6IDEgbW9kIHJlbW92ZWQuCgkgKgoJICogICAgICMgUmVtb3ZlIG11bHRpcGxlIHRoZW1lIG1vZHMuCgkgKiAgICAgJCB3cCB0aGVtZSBtb2QgcmVtb3ZlIGJhY2tncm91bmRfY29sb3IgaGVhZGVyX3RleHRjb2xvcgoJICogICAgIFN1Y2Nlc3M6IDIgbW9kcyByZW1vdmVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAkYXJncyA9IGFycmF5KCksICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCgkJaWYgKCAhIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICYmIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnWW91IG11c3Qgc3BlY2lmeSBhdCBsZWFzdCBvbmUgbW9kIG9yIHVzZSAtLWFsbC4nICk7CgkJfQoKCQlpZiAoIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQlyZW1vdmVfdGhlbWVfbW9kcygpOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUaGVtZSBtb2RzIHJlbW92ZWQuJyApOwoJCQlyZXR1cm47CgkJfQoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJG1vZCApIHsKCQkJcmVtb3ZlX3RoZW1lX21vZCggJG1vZCApOwoJCX0KCgkJJGNvdW50ICAgICAgICAgICA9IGNvdW50KCAkYXJncyApOwoJCSRzdWNjZXNzX21lc3NhZ2UgPSAoIDEgPT09ICRjb3VudCApID8gJyVkIG1vZCByZW1vdmVkLicgOiAnJWQgbW9kcyByZW1vdmVkLic7CgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkc3VjY2Vzc19tZXNzYWdlLCAkY291bnQgKSApOwoKCX0KCgkvKioKCSAqIFNldHMgdGhlIHZhbHVlIG9mIGEgdGhlbWUgbW9kLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bW9kPgoJICogOiBUaGUgbmFtZSBvZiB0aGUgdGhlbWUgbW9kIHRvIHNldCBvciB1cGRhdGUuCgkgKgoJICogPHZhbHVlPgoJICogOiBUaGUgbmV3IHZhbHVlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2V0IHRoZW1lIG1vZAoJICogICAgICQgd3AgdGhlbWUgbW9kIHNldCBiYWNrZ3JvdW5kX2NvbG9yIDAwMDAwMAoJICogICAgIFN1Y2Nlc3M6IFRoZW1lIG1vZCBiYWNrZ3JvdW5kX2NvbG9yIHNldCB0byAwMDAwMDAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldCggJGFyZ3MgPSBhcnJheSgpLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJbGlzdCggJG1vZCwgJHZhbHVlICkgPSAkYXJnczsKCgkJc2V0X3RoZW1lX21vZCggJG1vZCwgJHZhbHVlICk7CgoJCWlmICggZ2V0X3RoZW1lX21vZCggJG1vZCApID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggIlRoZW1lIG1vZCB7JG1vZH0gc2V0IHRvIHskdmFsdWV9LiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDb3VsZCBub3QgdXBkYXRlIHRoZW1lIG1vZCB7JG1vZH0uIiApOwoJCX0KCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogQSBwbHVnaW4gdXBncmFkZXIgY2xhc3MgdGhhdCBjbGVhcnMgdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4KICovCmNsYXNzIERlc3RydWN0aXZlUGx1Z2luVXBncmFkZXIgZXh0ZW5kcyBcUGx1Z2luX1VwZ3JhZGVyIHsKCglwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbF9wYWNrYWdlKCAkYXJncyA9IGFycmF5KCkgKSB7CgkJcGFyZW50Ojp1cGdyYWRlX3N0cmluZ3MoKTsgLy8gTmVlZGVkIGZvciB0aGUgJ3JlbW92ZV9vbGQnIHN0cmluZy4KCgkJJGFyZ3NbJ2NsZWFyX2Rlc3RpbmF0aW9uJ10gICAgICAgICAgID0gdHJ1ZTsKCQkkYXJnc1snYWJvcnRfaWZfZGVzdGluYXRpb25fZXhpc3RzJ10gPSBmYWxzZTsKCQlyZXR1cm4gcGFyZW50OjppbnN0YWxsX3BhY2thZ2UoICRhcmdzICk7Cgl9Cn0KCjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEZldGNoZXJzOwoKLyoqCiAqIEZldGNoIGEgV29yZFByZXNzIHBsdWdpbiBiYXNlZCBvbiBvbmUgb2YgaXRzIGF0dHJpYnV0ZXMuCiAqLwpjbGFzcyBQbHVnaW4gZXh0ZW5kcyBCYXNlIHsKCgkvKioKCSAqIEB2YXIgc3RyaW5nICRtc2cgRXJyb3IgbWVzc2FnZSB0byB1c2Ugd2hlbiBpbnZhbGlkIGRhdGEgaXMgcHJvdmlkZWQKCSAqLwoJcHJvdGVjdGVkICRtc2cgPSAiVGhlICclcycgcGx1Z2luIGNvdWxkIG5vdCBiZSBmb3VuZC4iOwoKCS8qKgoJICogR2V0IGEgcGx1Z2luIG9iamVjdCBieSBuYW1lCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICogQHJldHVybiBvYmplY3R8ZmFsc2UKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJG5hbWUgKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQlmb3JlYWNoICggYXBwbHlfZmlsdGVycyggJ2FsbF9wbHVnaW5zJywgZ2V0X3BsdWdpbnMoKSApIGFzICRmaWxlID0+ICRfICkgewoJCQlpZiAoICIkbmFtZS5waHAiID09PSAkZmlsZSB8fAoJCQkJKCAkbmFtZSAmJiAkZmlsZSA9PT0gJG5hbWUgKSB8fAoJCQkJKCBkaXJuYW1lKCAkZmlsZSApID09PSAkbmFtZSAmJiAnLicgIT09ICRuYW1lICkgKSB7CgkJCQlyZXR1cm4gKG9iamVjdCkgY29tcGFjdCggJ25hbWUnLCAnZmlsZScgKTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQp9Cgo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxGZXRjaGVyczsKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgdGhlbWUgYmFzZWQgb24gb25lIG9mIGl0cyBhdHRyaWJ1dGVzLgogKi8KY2xhc3MgVGhlbWUgZXh0ZW5kcyBCYXNlIHsKCgkvKioKCSAqIEB2YXIgc3RyaW5nICRtc2cgRXJyb3IgbWVzc2FnZSB0byB1c2Ugd2hlbiBpbnZhbGlkIGRhdGEgaXMgcHJvdmlkZWQKCSAqLwoJcHJvdGVjdGVkICRtc2cgPSAiVGhlICclcycgdGhlbWUgY291bGQgbm90IGJlIGZvdW5kLiI7CgoJLyoqCgkgKiBHZXQgYSB0aGVtZSBvYmplY3QgYnkgbmFtZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKCSAqIEByZXR1cm4gb2JqZWN0fGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRuYW1lICkgewoJCS8vIFdvcmthcm91bmQgdG8gZXF1YWxpemUgZm9sZGVyIG5hbWluZyBjb252ZW50aW9ucyBhY3Jvc3MgV2luL01hYy9MaW51eC4KCQkvLyBSZXR1cm5zIGZhbHNlIGlmIHRoZW1lIHN0eWxlc2hlZXQgZG9lc24ndCBleGFjdGx5IG1hdGNoIGV4aXN0aW5nIHRoZW1lcy4KCQkkZXhpc3RpbmdfdGhlbWVzICAgICAgPSB3cF9nZXRfdGhlbWVzKCBhcnJheSggJ2Vycm9ycycgPT4gbnVsbCApICk7CgkJJGV4aXN0aW5nX3N0eWxlc2hlZXRzID0gYXJyYXlfa2V5cyggJGV4aXN0aW5nX3RoZW1lcyApOwoJCWlmICggISBpbl9hcnJheSggJG5hbWUsICRleGlzdGluZ19zdHlsZXNoZWV0cywgdHJ1ZSApICkgewoJCQkkaW5leGFjdF9tYXRjaCA9ICR0aGlzLT5maW5kX2luZXhhY3RfbWF0Y2goICRuYW1lLCAkZXhpc3RpbmdfdGhlbWVzICk7CgkJCWlmICggZmFsc2UgIT09ICRpbmV4YWN0X21hdGNoICkgewoJCQkJJHRoaXMtPm1zZyAuPSBzcHJpbnRmKCAiIERpZCB5b3UgbWVhbiAnJXMnPyIsICRpbmV4YWN0X21hdGNoICk7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoZW1lID0gJGV4aXN0aW5nX3RoZW1lc1sgJG5hbWUgXTsKCgkJcmV0dXJuICR0aGVtZTsKCX0KCgkvKioKCSAqIEZpbmQgYW5kIHJldHVybiB0aGUga2V5IGluICRleGlzdGluZ190aGVtZXMgdGhhdCBtYXRjaGVzICRuYW1lIHdpdGgKCSAqIGEgY2FzZSBpbnNlbnNpdGl2ZSBzdHJpbmcgY29tcGFyaXNvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIE5hbWUgb2YgdGhlbWUgcmVjZWl2ZWQgYnkgY29tbWFuZC4KCSAqIEBwYXJhbSBhcnJheSAgJGV4aXN0aW5nX3RoZW1lcyBLZXkvdmFsdWUgcGFpciBvZiBleGlzdGluZyB0aGVtZXMsIGtleSBpcwoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY2FzZSBzZW5zaXRpdmUgbmFtZS4KCSAqIEByZXR1cm4gc3RyaW5nfGJvb2xlYW4gQ2FzZSBzZW5zaXRpdmUgbmFtZSBpZiBtYXRjaCBmb3VuZCwgb3RoZXJ3aXNlIGZhbHNlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGZpbmRfaW5leGFjdF9tYXRjaCggJG5hbWUsICRleGlzdGluZ190aGVtZXMgKSB7CgkJJHRhcmdldCA9IHN0cnRvbG93ZXIoICRuYW1lICk7CgkJJHRoZW1lcyA9IGFycmF5X21hcCggJ3N0cnRvbG93ZXInLCBhcnJheV9rZXlzKCAkZXhpc3RpbmdfdGhlbWVzICkgKTsKCgkJaWYgKCBpbl9hcnJheSggJHRhcmdldCwgJHRoZW1lcywgdHJ1ZSApICkgewoJCQlyZXR1cm4gJHRhcmdldDsKCQl9CgoJCSRzdWdnZXN0aW9uID0gVXRpbHNcZ2V0X3N1Z2dlc3Rpb24oICR0YXJnZXQsICR0aGVtZXMgKTsKCgkJaWYgKCAnJyAhPT0gJHN1Z2dlc3Rpb24gKSB7CgkJCXJldHVybiAkc3VnZ2VzdGlvbjsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KfQoKPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgQ29tcG9zZXJcU2VtdmVyXENvbXBhcmF0b3I7CnVzZSBFeGNlcHRpb247CnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcRmV0Y2hlcnM7CnVzZSBXUF9DTElcTG9nZ2VyczsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0Vycm9yOwoKYWJzdHJhY3QgY2xhc3MgQ29tbWFuZFdpdGhVcGdyYWRlIGV4dGVuZHMgXFdQX0NMSV9Db21tYW5kIHsKCglwcm90ZWN0ZWQgJGl0ZW1fdHlwZTsKCXByb3RlY3RlZCAkb2JqX2ZpZWxkczsKCglwcm90ZWN0ZWQgJHVwZ3JhZGVfcmVmcmVzaDsKCXByb3RlY3RlZCAkdXBncmFkZV90cmFuc2llbnQ7CgoJcHJvdGVjdGVkICRjaGFpbmVkX2NvbW1hbmQgPSBmYWxzZTsKCgkvLyBJbnZhbGlkIHZlcnNpb24gbWVzc2FnZS4KCWNvbnN0IElOVkFMSURfVkVSU0lPTl9NRVNTQUdFID0gJ3ZlcnNpb24gaGlnaGVyIHRoYW4gZXhwZWN0ZWQnOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCgkJLy8gRG8gbm90IGF1dG9tYXRpY2FsbHkgY2hlY2sgdHJhbnNsYXRpb25zIHVwZGF0ZXMgYWZ0ZXIgdXBkYXRpbmcgcGx1Z2lucy90aGVtZXMuCgkJYWRkX2FjdGlvbigKCQkJJ3VwZ3JhZGVyX3Byb2Nlc3NfY29tcGxldGUnLAoJCQlmdW5jdGlvbigpIHsKCQkJCXJlbW92ZV9hY3Rpb24oICd1cGdyYWRlcl9wcm9jZXNzX2NvbXBsZXRlJywgWyAnTGFuZ3VhZ2VfUGFja19VcGdyYWRlcicsICdhc3luY191cGdyYWRlJyBdLCAyMCApOwoJCQl9LAoJCQkxCgkJKTsKCgkJYWRkX2ZpbHRlcigKCQkJJ2h0dHBfcmVxdWVzdF90aW1lb3V0JywKCQkJZnVuY3Rpb24gKCkgewoJCQkJcmV0dXJuIDEgKiBNSU5VVEVfSU5fU0VDT05EUzsKCQkJfSwKCQkJOTk5CgkJKTsKCgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgRmV0Y2hlcnNcUGx1Z2luKCk7Cgl9CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF91cGdyYWRlcl9jbGFzcyggJGZvcmNlICk7CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9pdGVtX2xpc3QoKTsKCgkvKioKCSAqIEBwYXJhbSBhcnJheSBMaXN0IG9mIHVwZGF0ZSBjYW5kaWRhdGVzCgkgKiBAcGFyYW0gYXJyYXkgTGlzdCBvZiBpdGVtIG5hbWVzCgkgKiBAcmV0dXJuIGFycmF5IExpc3Qgb2YgdXBkYXRlIGNhbmRpZGF0ZXMKCSAqLwoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbHRlcl9pdGVtX2xpc3QoICRpdGVtcywgJGFyZ3MgKTsKCglhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2FsbF9pdGVtcygpOwoKCWFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBnZXRfc3RhdHVzKCAkZmlsZSApOwoKCWFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBzdGF0dXNfc2luZ2xlKCAkYXJncyApOwoKCWFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBpbnN0YWxsX2Zyb21fcmVwbyggJHNsdWcsICRhc3NvY19hcmdzICk7CgoJcHVibGljIGZ1bmN0aW9uIHN0YXR1cyggJGFyZ3MgKSB7CgkJLy8gRm9yY2UgV29yZFByZXNzIHRvIGNoZWNrIGZvciB1cGRhdGVzLgoJCWNhbGxfdXNlcl9mdW5jKCAkdGhpcy0+dXBncmFkZV9yZWZyZXNoICk7CgoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCSR0aGlzLT5zdGF0dXNfYWxsKCk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPnN0YXR1c19zaW5nbGUoICRhcmdzICk7CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc3RhdHVzX2FsbCgpIHsKCQkkaXRlbXMgPSAkdGhpcy0+Z2V0X2FsbF9pdGVtcygpOwoKCQkkbiA9IGNvdW50KCAkaXRlbXMgKTsKCgkJV1BfQ0xJOjpsb2coCgkJCXNwcmludGYoICclZCBpbnN0YWxsZWQgJXM6JywgJG4sIFV0aWxzXHBsdXJhbGl6ZSggJHRoaXMtPml0ZW1fdHlwZSwgYWJzaW50KCAkbiApICkgKQoJCSk7CgoJCSRwYWRkaW5nID0gJHRoaXMtPmdldF9wYWRkaW5nKCAkaXRlbXMgKTsKCgkJZm9yZWFjaCAoICRpdGVtcyBhcyAkZmlsZSA9PiAkZGV0YWlscyApIHsKCQkJaWYgKCAkZGV0YWlsc1sndXBkYXRlJ10gKSB7CgkJCQkkbGluZSA9ICcgJXlVJW4nOwoJCQl9IGVsc2UgewoJCQkJJGxpbmUgPSAnICAnOwoJCQl9CgoJCQkkbGluZSAuPSAkdGhpcy0+Zm9ybWF0X3N0YXR1cyggJGRldGFpbHNbJ3N0YXR1cyddLCAnc2hvcnQnICk7CgkJCSRsaW5lIC49ICcgJyAuIHN0cl9wYWQoICRkZXRhaWxzWyduYW1lJ10sICRwYWRkaW5nICkgLiAnJW4nOwoJCQlpZiAoICEgZW1wdHkoICRkZXRhaWxzWyd2ZXJzaW9uJ10gKSApIHsKCQkJCSRsaW5lIC49ICcgJyAuICRkZXRhaWxzWyd2ZXJzaW9uJ107CgkJCX0KCgkJCVdQX0NMSTo6bGluZSggV1BfQ0xJOjpjb2xvcml6ZSggJGxpbmUgKSApOwoJCX0KCgkJV1BfQ0xJOjpsaW5lKCk7CgoJCSR0aGlzLT5zaG93X2xlZ2VuZCggJGl0ZW1zICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcGFkZGluZyggJGl0ZW1zICkgewoJCSRtYXhfbGVuID0gMDsKCgkJZm9yZWFjaCAoICRpdGVtcyBhcyAkZGV0YWlscyApIHsKCQkJJGxlbiA9IHN0cmxlbiggJGRldGFpbHNbJ25hbWUnXSApOwoKCQkJaWYgKCAkbGVuID4gJG1heF9sZW4gKSB7CgkJCQkkbWF4X2xlbiA9ICRsZW47CgkJCX0KCQl9CgoJCXJldHVybiAkbWF4X2xlbjsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHNob3dfbGVnZW5kKCAkaXRlbXMgKSB7CgkJJHN0YXR1c2VzID0gYXJyYXlfdW5pcXVlKCB3cF9saXN0X3BsdWNrKCAkaXRlbXMsICdzdGF0dXMnICkgKTsKCgkJJGxlZ2VuZF9saW5lID0gYXJyYXkoKTsKCgkJZm9yZWFjaCAoICRzdGF0dXNlcyBhcyAkc3RhdHVzICkgewoJCQkkbGVnZW5kX2xpbmVbXSA9IHNwcmludGYoCgkJCQknJXMlcyA9ICVzJSVuJywKCQkJCSR0aGlzLT5nZXRfY29sb3IoICRzdGF0dXMgKSwKCQkJCSR0aGlzLT5tYXBbJ3Nob3J0J11bICRzdGF0dXMgXSwKCQkJCSR0aGlzLT5tYXBbJ2xvbmcnXVsgJHN0YXR1cyBdCgkJCSk7CgkJfQoKCQlpZiAoIGluX2FycmF5KCB0cnVlLCB3cF9saXN0X3BsdWNrKCAkaXRlbXMsICd1cGRhdGUnICksIHRydWUgKSApIHsKCQkJJGxlZ2VuZF9saW5lW10gPSAnJXlVID0gVXBkYXRlIEF2YWlsYWJsZSVuJzsKCQl9CgoJCVdQX0NMSTo6bGluZSggJ0xlZ2VuZDogJyAuIFdQX0NMSTo6Y29sb3JpemUoIGltcGxvZGUoICcsICcsICRsZWdlbmRfbGluZSApICkgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHNsdWcgKSB7CgoJCQlpZiAoIGVtcHR5KCAkc2x1ZyApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAnSWdub3JpbmcgYW1iaWd1b3VzIGVtcHR5IHNsdWcgdmFsdWUuJyApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyZXN1bHQgPSBmYWxzZTsKCgkJCSRpc19yZW1vdGUgPSBmYWxzZSAhPT0gc3RycG9zKCAkc2x1ZywgJzovLycgKTsKCgkJCS8vIENoZWNrIGlmIGEgVVJMIHRvIGEgcmVtb3RlIG9yIGxvY2FsIHppcCBoYXMgYmVlbiBzcGVjaWZpZWQuCgkJCWlmICggJGlzX3JlbW90ZSB8fCAoIHBhdGhpbmZvKCAkc2x1ZywgUEFUSElORk9fRVhURU5TSU9OICkgPT09ICd6aXAnICYmIGlzX2ZpbGUoICRzbHVnICkgKSApIHsKCQkJCS8vIEluc3RhbGwgZnJvbSBsb2NhbCBvciByZW1vdGUgemlwIGZpbGUuCgkJCQkkZmlsZV91cGdyYWRlciA9ICR0aGlzLT5nZXRfdXBncmFkZXIoICRhc3NvY19hcmdzICk7CgoJCQkJJGZpbHRlciA9IGZhbHNlOwoJCQkJLy8gSWYgYSBHaXRIdWIgVVJMLCBkbyBzb21lIGd1ZXNzaW5nIGFzIHRvIHRoZSBjb3JyZWN0IHBsdWdpbi90aGVtZSBkaXJlY3RvcnkuCgkJCQlpZiAoICRpc19yZW1vdGUgJiYgJ2dpdGh1Yi5jb20nID09PSAkdGhpcy0+cGFyc2VfdXJsX2hvc3RfY29tcG9uZW50KCAkc2x1ZywgUEhQX1VSTF9IT1NUICkKCQkJCQkJLy8gRG9uJ3QgYXR0ZW1wdCB0byByZW5hbWUgWklQcyB1cGxvYWRlZCB0byB0aGUgcmVsZWFzZXMgcGFnZSBvciBjb21pbmcgZnJvbSBhIHJhdyBzb3VyY2UuCgkJCQkJCSYmICEgcHJlZ19tYXRjaCggJyNnaXRodWJcLmNvbS9bXi9dKy9bXi9dKy8oPzpyZWxlYXNlcy9kb3dubG9hZHxyYXcpLyMnLCAkc2x1ZyApICkgewoKCQkJCQkkZmlsdGVyID0gZnVuY3Rpb24oICRzb3VyY2UsICRyZW1vdGVfc291cmNlLCAkdXBncmFkZXIgKSB1c2UgKCAkc2x1ZyApIHsKCgkJCQkJCSRzbHVnX2RpciA9IFV0aWxzXGJhc2VuYW1lKCAkdGhpcy0+cGFyc2VfdXJsX2hvc3RfY29tcG9uZW50KCAkc2x1ZywgUEhQX1VSTF9QQVRIICksICcuemlwJyApOwoKCQkJCQkJLy8gRG9uJ3QgdXNlIHRoZSB6aXAgbmFtZSBpZiBhcmNoaXZlIGF0dGFjaGVkIHRvIHJlbGVhc2UsIGFzIG5hbWUgbGlrZWx5IHRvIGNvbnRhaW4gdmVyc2lvbiB0YWcvYnJhbmNoLgoJCQkJCQlpZiAoIHByZWdfbWF0Y2goICcjZ2l0aHViXC5jb20vW14vXSsvKFteL10rKS9hcmNoaXZlLyMnLCAkc2x1ZywgJG1hdGNoZXMgKSApIHsKCQkJCQkJCS8vIE5vdGUgdGhpcyB3aWxsIGJlIHdyb25nIGlmIHRoZSBwcm9qZWN0IG5hbWUgaXNuJ3QgdGhlIHNhbWUgYXMgdGhlIHBsdWdpbi90aGVtZSBzbHVnIG5hbWUuCgkJCQkJCQkkc2x1Z19kaXIgPSAkbWF0Y2hlc1sxXTsKCQkJCQkJfQoKCQkJCQkJJHNvdXJjZV9kaXIgPSBVdGlsc1xiYXNlbmFtZSggJHNvdXJjZSApOyAvLyBgJHNvdXJjZWAgaXMgdHJhaWxpbmctc2xhc2hlZCBwYXRoIHRvIHRoZSB1bnppcHBlZCBhcmNoaXZlIGRpcmVjdG9yeSwgc28gYmFzZW5hbWUgcmV0dXJucyB0aGUgdW5zbGFzaGVkIGRpcmVjdG9yeS4KCQkJCQkJaWYgKCAkc291cmNlX2RpciA9PT0gJHNsdWdfZGlyICkgewoJCQkJCQkJcmV0dXJuICRzb3VyY2U7CgkJCQkJCX0KCQkJCQkJJG5ld19wYXRoID0gc3Vic3RyX3JlcGxhY2UoICRzb3VyY2UsICRzbHVnX2Rpciwgc3RycnBvcyggJHNvdXJjZSwgJHNvdXJjZV9kaXIgKSwgc3RybGVuKCAkc291cmNlX2RpciApICk7CgoJCQkJCQlpZiAoICRHTE9CQUxTWyd3cF9maWxlc3lzdGVtJ10tPm1vdmUoICRzb3VyY2UsICRuZXdfcGF0aCApICkgewoJCQkJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICJSZW5hbWVkIEdpdGh1Yi1iYXNlZCBwcm9qZWN0IGZyb20gJyVzJyB0byAnJXMnLiIsICRzb3VyY2VfZGlyLCAkc2x1Z19kaXIgKSApOwoJCQkJCQkJcmV0dXJuICRuZXdfcGF0aDsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ3dwY2xpX2luc3RhbGxfZ2l0aHViJywgIkNvdWxkbid0IG1vdmUgR2l0aHViLWJhc2VkIHByb2plY3QgdG8gYXBwcm9wcmlhdGUgZGlyZWN0b3J5LiIgKTsKCQkJCQl9OwoJCQkJCWFkZF9maWx0ZXIoICd1cGdyYWRlcl9zb3VyY2Vfc2VsZWN0aW9uJywgJGZpbHRlciwgMTAsIDMgKTsKCQkJCX0KCgkJCQlpZiAoICRmaWxlX3VwZ3JhZGVyLT5pbnN0YWxsKCAkc2x1ZyApICkgewoJCQkJCSRzbHVnICAgPSAkZmlsZV91cGdyYWRlci0+cmVzdWx0WydkZXN0aW5hdGlvbl9uYW1lJ107CgkJCQkJJHJlc3VsdCA9IHRydWU7CgkJCQkJaWYgKCAkZmlsdGVyICkgewoJCQkJCQlyZW1vdmVfZmlsdGVyKCAndXBncmFkZXJfc291cmNlX3NlbGVjdGlvbicsICRmaWx0ZXIsIDEwICk7CgkJCQkJfQoJCQkJCSRzdWNjZXNzZXMrKzsKCQkJCX0gZWxzZSB7CgkJCQkJJGVycm9ycysrOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJLy8gQXNzdW1lIGEgcGx1Z2luL3RoZW1lIHNsdWcgZnJvbSB0aGUgV29yZFByZXNzLm9yZyByZXBvc2l0b3J5IGhhcyBiZWVuIHNwZWNpZmllZC4KCQkJCSRyZXN1bHQgPSAkdGhpcy0+aW5zdGFsbF9mcm9tX3JlcG8oICRzbHVnLCAkYXNzb2NfYXJncyApOwoKCQkJCWlmICggaXNfbnVsbCggJHJlc3VsdCApICkgewoJCQkJCSRlcnJvcnMrKzsKCQkJCX0gZWxzZWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJCQkka2V5ID0gJHJlc3VsdC0+Z2V0X2Vycm9yX2NvZGUoKTsKCQkJCQlpZiAoIGluX2FycmF5KCAka2V5LCBbICdwbHVnaW5zX2FwaV9mYWlsZWQnLCAndGhlbWVzX2FwaV9mYWlsZWQnIF0sIHRydWUgKQoJCQkJCQkmJiAhIGVtcHR5KCAkcmVzdWx0LT5lcnJvcl9kYXRhWyAka2V5IF0gKSAmJiBpbl9hcnJheSggJHJlc3VsdC0+ZXJyb3JfZGF0YVsgJGtleSBdLCBbICdOOycsICdiOjA7JyBdLCB0cnVlICkgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGZpbmQgJyRzbHVnJyBpbiB0aGUgV29yZFByZXNzLm9yZyB7JHRoaXMtPml0ZW1fdHlwZX0gZGlyZWN0b3J5LiIgKTsKCQkJCQkJJGVycm9ycysrOwoJCQkJCX0gZWxzZSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggIiRzbHVnOiAiIC4gJHJlc3VsdC0+Z2V0X2Vycm9yX21lc3NhZ2UoKSApOwoJCQkJCQlpZiAoICdhbHJlYWR5X2luc3RhbGxlZCcgIT09ICRrZXkgKSB7CgkJCQkJCQkkZXJyb3JzKys7CgkJCQkJCX0KCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCSRzdWNjZXNzZXMrKzsKCQkJCX0KCQkJfQoKCQkJLy8gQ2hlY2sgZXh0ZW5zaW9uIGlzIGF2YWlsYWJsZSBvciBub3QuCgkJCSRleHRlbnNpb24gPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoIGFycmF5KCAkc2x1ZyApICk7CgoJCQkvLyBJZiBpbnN0YWxsYXRpb24gZ29lcyB3ZWxsICRyZXN1bHQgd2lsbCBiZSB0cnVlLgoJCQkkYWxsb3dfYWN0aXZhdGlvbiA9ICRyZXN1bHQ7CgoJCQkvLyBBbGxvdyBpbnN0YWxsYXRpb24gZm9yIGluc3RhbGxlZCBleHRlbnNpb24uCgkJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSAmJiAnYWxyZWFkeV9pbnN0YWxsZWQnID09PSAkcmVzdWx0LT5nZXRfZXJyb3JfY29kZSgpICkgewoJCQkJJGFsbG93X2FjdGl2YXRpb24gPSB0cnVlOwoJCQl9CgoJCQlpZiAoIHRydWUgPT09ICRhbGxvd19hY3RpdmF0aW9uICYmIGNvdW50KCAkZXh0ZW5zaW9uICkgPiAwICkgewoJCQkJJHRoaXMtPmNoYWluZWRfY29tbWFuZCA9IHRydWU7CgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FjdGl2YXRlLW5ldHdvcmsnICkgKSB7CgkJCQkJV1BfQ0xJOjpsb2coICJOZXR3b3JrLWFjdGl2YXRpbmcgJyRzbHVnJy4uLiIgKTsKCQkJCQkkdGhpcy0+YWN0aXZhdGUoIGFycmF5KCAkc2x1ZyApLCBhcnJheSggJ25ldHdvcmsnID0+IHRydWUgKSApOwoJCQkJfQoKCQkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWN0aXZhdGUnICkgKSB7CgkJCQkJV1BfQ0xJOjpsb2coICJBY3RpdmF0aW5nICckc2x1ZycuLi4iICk7CgkJCQkJJHRoaXMtPmFjdGl2YXRlKCBhcnJheSggJHNsdWcgKSApOwoJCQkJfQoJCQkJJHRoaXMtPmNoYWluZWRfY29tbWFuZCA9IGZhbHNlOwoJCQl9CgkJfQoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJHRoaXMtPml0ZW1fdHlwZSwgJ2luc3RhbGwnLCBjb3VudCggJGFyZ3MgKSwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJfQoKCS8qKgoJICogUHJlcGFyZSBhbiBBUEkgcmVzcG9uc2UgZm9yIGRvd25sb2FkaW5nIGEgcGFydGljdWxhciB2ZXJzaW9uIG9mIGFuIGl0ZW0uCgkgKgoJICogQHBhcmFtIG9iamVjdCAkcmVzcG9uc2Ugd29yZHByZXNzLm9yZyBBUEkgcmVzcG9uc2UKCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gVGhlIGRlc2lyZWQgdmVyc2lvbiBvZiB0aGUgcGFja2FnZQoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGFsdGVyX2FwaV9yZXNwb25zZSggJHJlc3BvbnNlLCAkdmVyc2lvbiApIHsKCQlpZiAoICRyZXNwb25zZS0+dmVyc2lvbiA9PT0gJHZlcnNpb24gKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIFdvcmRQcmVzcy5vcmcgZm9yY2VzIGh0dHBzLCBidXQgc3RpbGwgc29tZXRpbWVzIHJldHVybnMgaHR0cAoJCS8vIFNlZSBodHRwczovL3R3aXR0ZXIuY29tL25hY2luL3N0YXR1cy81MTIzNjI2OTQyMDUxNDA5OTIKCQkkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmsgPSBzdHJfcmVwbGFjZSggJ2h0dHA6Ly8nLCAnaHR0cHM6Ly8nLCAkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmsgKTsKCgkJbGlzdCggJGxpbmsgKSA9IGV4cGxvZGUoICRyZXNwb25zZS0+c2x1ZywgJHJlc3BvbnNlLT5kb3dubG9hZF9saW5rICk7CgoJCWlmICggZmFsc2UgIT09IHN0cnBvcyggJHJlc3BvbnNlLT5kb3dubG9hZF9saW5rLCAnL3RoZW1lLycgKSApIHsKCQkJJGRvd25sb2FkX3R5cGUgPSAndGhlbWUnOwoJCX0gZWxzZWlmICggZmFsc2UgIT09IHN0cnBvcyggJHJlc3BvbnNlLT5kb3dubG9hZF9saW5rLCAnL3BsdWdpbi8nICkgKSB7CgkJCSRkb3dubG9hZF90eXBlID0gJ3BsdWdpbic7CgkJfSBlbHNlIHsKCQkJJGRvd25sb2FkX3R5cGUgPSAncGx1Z2luL3RoZW1lJzsKCQl9CgoJCWlmICggJ2RldicgPT09ICR2ZXJzaW9uICkgewoJCQkkcmVzcG9uc2UtPmRvd25sb2FkX2xpbmsgPSAkbGluayAuICRyZXNwb25zZS0+c2x1ZyAuICcuemlwJzsKCQkJJHJlc3BvbnNlLT52ZXJzaW9uICAgICAgID0gJ0RldmVsb3BtZW50IFZlcnNpb24nOwoJCX0gZWxzZSB7CgkJCSRyZXNwb25zZS0+ZG93bmxvYWRfbGluayA9ICRsaW5rIC4gJHJlc3BvbnNlLT5zbHVnIC4gJy4nIC4gJHZlcnNpb24gLiAnLnppcCc7CgkJCSRyZXNwb25zZS0+dmVyc2lvbiAgICAgICA9ICR2ZXJzaW9uOwoKCQkJLy8gQ2hlY2sgaWYgdGhlIHJlcXVlc3RlZCB2ZXJzaW9uIGV4aXN0cy4KCQkJJHJlc3BvbnNlICAgICAgPSB3cF9yZW1vdGVfaGVhZCggJHJlc3BvbnNlLT5kb3dubG9hZF9saW5rICk7CgkJCSRyZXNwb25zZV9jb2RlID0gd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX2NvZGUoICRyZXNwb25zZSApOwoJCQlpZiAoIDIwMCAhPT0gKGludCkgJHJlc3BvbnNlX2NvZGUgKSB7CgkJCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzcG9uc2UgKSApIHsKCQkJCQkkZXJyb3JfbXNnID0gJHJlc3BvbnNlLT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJCQkJfSBlbHNlIHsKCQkJCQkkZXJyb3JfbXNnID0gc3ByaW50ZiggJ0hUVFAgY29kZSAlZCcsICRyZXNwb25zZV9jb2RlICk7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKAoJCQkJCXNwcmludGYoCgkJCQkJCSJDYW4ndCBmaW5kIHRoZSByZXF1ZXN0ZWQgJXMncyB2ZXJzaW9uICVzIGluIHRoZSBXb3JkUHJlc3Mub3JnICVzIHJlcG9zaXRvcnkgKCVzKS4iLAoJCQkJCQkkZG93bmxvYWRfdHlwZSwKCQkJCQkJJHZlcnNpb24sCgkJCQkJCSRkb3dubG9hZF90eXBlLAoJCQkJCQkkZXJyb3JfbXNnCgkJCQkJKQoJCQkJKTsKCQkJfQoJCX0KCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3VwZ3JhZGVyKCAkYXNzb2NfYXJncyApIHsKCQkkZm9yY2UgICAgICAgICAgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnLCBmYWxzZSApOwoJCSRpbnNlY3VyZSAgICAgICA9IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbnNlY3VyZScsIGZhbHNlICk7CgkJJHVwZ3JhZGVyX2NsYXNzID0gJHRoaXMtPmdldF91cGdyYWRlcl9jbGFzcyggJGZvcmNlICk7CgkJcmV0dXJuIFV0aWxzXGdldF91cGdyYWRlciggJHVwZ3JhZGVyX2NsYXNzLCAkaW5zZWN1cmUgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gdXBkYXRlX21hbnkoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQljYWxsX3VzZXJfZnVuYyggJHRoaXMtPnVwZ3JhZGVfcmVmcmVzaCApOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmIGluX2FycmF5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10sIFsgJ2pzb24nLCAnY3N2JyBdLCB0cnVlICkgKSB7CgkJCSRsb2dnZXIgPSBuZXcgTG9nZ2Vyc1xRdWlldCgpOwoJCQlXUF9DTEk6OnNldF9sb2dnZXIoICRsb2dnZXIgKTsKCQl9CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSB7JHRoaXMtPml0ZW1fdHlwZX1zLCBvciB1c2UgLS1hbGwuIiApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdtaW5vcicgKSAmJiBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwYXRjaCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJy0tbWlub3IgYW5kIC0tcGF0Y2ggY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIuJyApOwoJCX0KCgkJJGl0ZW1zID0gJHRoaXMtPmdldF9pdGVtX2xpc3QoKTsKCgkJJGVycm9ycyA9IDA7CgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSApIHsKCQkJJGl0ZW1zICA9ICR0aGlzLT5maWx0ZXJfaXRlbV9saXN0KCAkaXRlbXMsICRhcmdzICk7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkaXRlbXMgKTsKCQl9CgoJCSRpdGVtc190b191cGRhdGUgPSB3cF9saXN0X2ZpbHRlciggJGl0ZW1zLCBbICd1cGRhdGUnID0+IHRydWUgXSApOwoKCQkkbWlub3IgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbWlub3InLCBmYWxzZSApOwoJCSRwYXRjaCA9IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwYXRjaCcsIGZhbHNlICk7CgoJCWlmICggJ3BsdWdpbicgPT09ICR0aGlzLT5pdGVtX3R5cGUKCQkJJiYgKCAkbWlub3IgfHwgJHBhdGNoICkgKSB7CgkJCSR0eXBlICAgICA9ICRtaW5vciA/ICdtaW5vcicgOiAncGF0Y2gnOwoJCQkkaW5zZWN1cmUgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApOwoKCQkJJGl0ZW1zX3RvX3VwZGF0ZSA9IHNlbGY6OmdldF9taW5vcl9vcl9wYXRjaF91cGRhdGVzKCAkaXRlbXNfdG9fdXBkYXRlLCAkdHlwZSwgJGluc2VjdXJlICk7CgkJfQoKCQkkZXhjbHVkZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2V4Y2x1ZGUnICk7CgkJaWYgKCBpc3NldCggJGV4Y2x1ZGUgKSApIHsKCQkJJGV4Y2x1ZGVfaXRlbXMgPSBleHBsb2RlKCAnLCcsIHRyaW0oICRhc3NvY19hcmdzWydleGNsdWRlJ10sICcsJyApICk7CgkJCXVuc2V0KCAkYXNzb2NfYXJnc1snZXhjbHVkZSddICk7CgkJCWZvcmVhY2ggKCAkZXhjbHVkZV9pdGVtcyBhcyAkaXRlbSApIHsKCQkJCWlmICggJ3BsdWdpbicgPT09ICR0aGlzLT5pdGVtX3R5cGUgKSB7CgkJCQkJJHBsdWdpbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXQoICRpdGVtICk7CgkJCQkJdW5zZXQoICRpdGVtc190b191cGRhdGVbICRwbHVnaW4tPmZpbGUgXSApOwoJCQkJfSBlbHNlaWYgKCAndGhlbWUnID09PSAkdGhpcy0+aXRlbV90eXBlICkgewoJCQkJCSR0aGVtZV9yb290ID0gZ2V0X3RoZW1lX3Jvb3QoKSAuICcvJyAuICRpdGVtOwoJCQkJCXVuc2V0KCAkaXRlbXNfdG9fdXBkYXRlWyAkdGhlbWVfcm9vdCBdICk7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIENoZWNrIGZvciBpdGVtcyB0byB1cGRhdGUgYW5kIHJlbW92ZSBleHRlbnNpb25zIHRoYXQgaGF2ZSB2ZXJzaW9uIGhpZ2hlciB0aGFuIGV4cGVjdGVkLgoJCWZvcmVhY2ggKCAkaXRlbXNfdG9fdXBkYXRlIGFzICRpdGVtX2tleSA9PiAkaXRlbV9pbmZvICkgewoJCQlpZiAoIHN0YXRpYzo6SU5WQUxJRF9WRVJTSU9OX01FU1NBR0UgPT09ICRpdGVtX2luZm9bJ3VwZGF0ZSddICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRpdGVtX2luZm9bJ25hbWUnXX06ICIgLiBzdGF0aWM6OklOVkFMSURfVkVSU0lPTl9NRVNTQUdFIC4gJy4nICk7CgkJCQkkZXJyb3JzKys7CgkJCQl1bnNldCggJGl0ZW1zX3RvX3VwZGF0ZVsgJGl0ZW1fa2V5IF0gKTsKCQkJfQoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkcnktcnVuJyApICkgewoJCQlpZiAoIGVtcHR5KCAkaXRlbXNfdG9fdXBkYXRlICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIk5vIHskdGhpcy0+aXRlbV90eXBlfSB1cGRhdGVzIGF2YWlsYWJsZS4iICk7CgoJCQkJaWYgKCBudWxsICE9PSAkZXhjbHVkZSApIHsKCQkJCQlXUF9DTEk6OmxvZyggIlNraXBwZWQgdXBkYXRlcyBmb3I6ICRleGNsdWRlIiApOwoJCQkJfQoKCQkJCXJldHVybjsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiBpbl9hcnJheSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCBbICdqc29uJywgJ2NzdicgXSwgdHJ1ZSApICkgewoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAkYXNzb2NfYXJnc1snZm9ybWF0J10sICRpdGVtc190b191cGRhdGUsIFsgJ25hbWUnLCAnc3RhdHVzJywgJ3ZlcnNpb24nLCAndXBkYXRlX3ZlcnNpb24nIF0gKTsKCQkJfSBlbHNlaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiAnc3VtbWFyeScgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJCVdQX0NMSTo6bG9nKCAiQXZhaWxhYmxlIHskdGhpcy0+aXRlbV90eXBlfSB1cGRhdGVzOiIgKTsKCQkJCWZvcmVhY2ggKCAkaXRlbXNfdG9fdXBkYXRlIGFzICRpdGVtX3RvX3VwZGF0ZSA9PiAkaW5mbyApIHsKCQkJCQlXUF9DTEk6OmxvZyggInskaW5mb1sndGl0bGUnXX0gdXBkYXRlIGZyb20gdmVyc2lvbiB7JGluZm9bJ3ZlcnNpb24nXX0gdG8gdmVyc2lvbiB7JGluZm9bJ3VwZGF0ZV92ZXJzaW9uJ119IiApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICJBdmFpbGFibGUgeyR0aGlzLT5pdGVtX3R5cGV9IHVwZGF0ZXM6IiApOwoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAndGFibGUnLCAkaXRlbXNfdG9fdXBkYXRlLCBbICduYW1lJywgJ3N0YXR1cycsICd2ZXJzaW9uJywgJ3VwZGF0ZV92ZXJzaW9uJyBdICk7CgkJCX0KCgkJCWlmICggbnVsbCAhPT0gJGV4Y2x1ZGUgKSB7CgkJCQlXUF9DTEk6OmxvZyggIlNraXBwZWQgdXBkYXRlcyBmb3I6ICRleGNsdWRlIiApOwoJCQl9CgoJCQlyZXR1cm47CgkJfQoKCQkkcmVzdWx0ID0gYXJyYXkoKTsKCgkJLy8gT25seSBhdHRlbXB0IHRvIHVwZGF0ZSBpZiB0aGVyZSBpcyBzb21ldGhpbmcgdG8gdXBkYXRlLgoJCWlmICggISBlbXB0eSggJGl0ZW1zX3RvX3VwZGF0ZSApICkgewoJCQkkY2FjaGVfbWFuYWdlciA9IFdQX0NMSTo6Z2V0X2h0dHBfY2FjaGVfbWFuYWdlcigpOwoJCQlmb3JlYWNoICggJGl0ZW1zX3RvX3VwZGF0ZSBhcyAkaXRlbSApIHsKCQkJCSRjYWNoZV9tYW5hZ2VyLT53aGl0ZWxpc3RfcGFja2FnZSggJGl0ZW1bJ3VwZGF0ZV9wYWNrYWdlJ10sICR0aGlzLT5pdGVtX3R5cGUsICRpdGVtWyduYW1lJ10sICRpdGVtWyd1cGRhdGVfdmVyc2lvbiddICk7CgkJCX0KCQkJJHVwZ3JhZGVyID0gJHRoaXMtPmdldF91cGdyYWRlciggJGFzc29jX2FyZ3MgKTsKCQkJLy8gRW5zdXJlIHRoZSB1cGdyYWRlciB1c2VzIHRoZSBkb3dubG9hZCBvZmZlciBwcmVzZW50IGluIGVhY2ggaXRlbS4KCQkJJHRyYW5zaWVudF9maWx0ZXIgPSBmdW5jdGlvbiggJHRyYW5zaWVudCApIHVzZSAoICRpdGVtc190b191cGRhdGUgKSB7CgkJCQlmb3JlYWNoICggJGl0ZW1zX3RvX3VwZGF0ZSBhcyAkbmFtZSA9PiAkaXRlbV9kYXRhICkgewoJCQkJCWlmICggaXNzZXQoICR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdICkgKSB7CgkJCQkJCSR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdLT5uZXdfdmVyc2lvbiA9ICRpdGVtX2RhdGFbJ3VwZGF0ZV92ZXJzaW9uJ107CgkJCQkJCSR0cmFuc2llbnQtPnJlc3BvbnNlWyAkbmFtZSBdLT5wYWNrYWdlICAgICA9ICRpdGVtX2RhdGFbJ3VwZGF0ZV9wYWNrYWdlJ107CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuICR0cmFuc2llbnQ7CgkJCX07CgkJCWFkZF9maWx0ZXIoICdzaXRlX3RyYW5zaWVudF8nIC4gJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50LCAkdHJhbnNpZW50X2ZpbHRlciwgOTk5ICk7CgkJCSRyZXN1bHQgPSAkdXBncmFkZXItPmJ1bGtfdXBncmFkZSggd3BfbGlzdF9wbHVjayggJGl0ZW1zX3RvX3VwZGF0ZSwgJ3VwZGF0ZV9pZCcgKSApOwoJCQlyZW1vdmVfZmlsdGVyKCAnc2l0ZV90cmFuc2llbnRfJyAuICR0aGlzLT51cGdyYWRlX3RyYW5zaWVudCwgJHRyYW5zaWVudF9maWx0ZXIsIDk5OSApOwoJCX0KCgkJLy8gTGV0IHRoZSB1c2VyIGtub3cgdGhlIHJlc3VsdHMuCgkJJG51bV90b191cGRhdGUgPSBjb3VudCggJGl0ZW1zX3RvX3VwZGF0ZSApOwoJCSRudW1fdXBkYXRlZCAgID0gY291bnQoIGFycmF5X2ZpbHRlciggJHJlc3VsdCApICk7CgoJCWlmICggJG51bV90b191cGRhdGUgPiAwICkgewoJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmICdzdW1tYXJ5JyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQkJZm9yZWFjaCAoICRpdGVtc190b191cGRhdGUgYXMgJGl0ZW1fdG9fdXBkYXRlID0+ICRpbmZvICkgewoJCQkJCSRtZXNzYWdlID0gbnVsbCAhPT0gJHJlc3VsdFsgJGluZm9bJ3VwZGF0ZV9pZCddIF0gPyAndXBkYXRlZCBzdWNjZXNzZnVsbHknIDogJ2RpZCBub3QgdXBkYXRlJzsKCQkJCQlXUF9DTEk6OmxvZyggInskaW5mb1sndGl0bGUnXX0geyRtZXNzYWdlfSBmcm9tIHZlcnNpb24geyRpbmZvWyd2ZXJzaW9uJ119IHRvIHZlcnNpb24geyRpbmZvWyd1cGRhdGVfdmVyc2lvbiddfSIgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCSRzdGF0dXMgPSBhcnJheSgpOwoJCQkJZm9yZWFjaCAoICRpdGVtc190b191cGRhdGUgYXMgJGl0ZW1fdG9fdXBkYXRlID0+ICRpbmZvICkgewoJCQkJCSRzdGF0dXNbICRpdGVtX3RvX3VwZGF0ZSBdID0gWwoJCQkJCQknbmFtZScgICAgICAgID0+ICRpbmZvWyduYW1lJ10sCgkJCQkJCSdvbGRfdmVyc2lvbicgPT4gJGluZm9bJ3ZlcnNpb24nXSwKCQkJCQkJJ25ld192ZXJzaW9uJyA9PiAkaW5mb1sndXBkYXRlX3ZlcnNpb24nXSwKCQkJCQkJJ3N0YXR1cycgICAgICA9PiBudWxsICE9PSAkcmVzdWx0WyAkaW5mb1sndXBkYXRlX2lkJ10gXSA/ICdVcGRhdGVkJyA6ICdFcnJvcicsCgkJCQkJXTsKCQkJCQlpZiAoIG51bGwgPT09ICRyZXN1bHRbICRpbmZvWyd1cGRhdGVfaWQnXSBdICkgewoJCQkJCQkkZXJyb3JzKys7CgkJCQkJfQoJCQkJfQoKCQkJCSRmb3JtYXQgPSAndGFibGUnOwoJCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSAmJiBpbl9hcnJheSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCBbICdqc29uJywgJ2NzdicgXSwgdHJ1ZSApICkgewoJCQkJCSRmb3JtYXQgPSAkYXNzb2NfYXJnc1snZm9ybWF0J107CgkJCQl9CgoJCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAkZm9ybWF0LCAkc3RhdHVzLCBbICduYW1lJywgJ29sZF92ZXJzaW9uJywgJ25ld192ZXJzaW9uJywgJ3N0YXR1cycgXSApOwoJCQl9CgkJfQoKCQkkdG90YWxfdXBkYXRlZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSA/ICRudW1fdG9fdXBkYXRlIDogY291bnQoICRhcmdzICk7CgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAkdGhpcy0+aXRlbV90eXBlLCAndXBkYXRlJywgJHRvdGFsX3VwZGF0ZWQsICRudW1fdXBkYXRlZCwgJGVycm9ycyApOwoJCWlmICggbnVsbCAhPT0gJGV4Y2x1ZGUgKSB7CgkJCVdQX0NMSTo6bG9nKCAiU2tpcHBlZCB1cGRhdGVzIGZvcjogJGV4Y2x1ZGUiICk7CgkJfQoJfQoKCS8vIHBocGNzOmlnbm9yZSBQU1IyLk1ldGhvZHMuTWV0aG9kRGVjbGFyYXRpb24uVW5kZXJzY29yZSAtLSBXaGl0ZWxpc3RpbmcgdG8gcHJvdmlkZSBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHRvIGNsYXNzZXMgcG9zc2libHkgZXh0ZW5kaW5nIHRoaXMgY2xhc3MuCglwcm90ZWN0ZWQgZnVuY3Rpb24gX2xpc3QoICRfLCAkYXNzb2NfYXJncyApIHsKCQkvLyBGb3JjZSBXb3JkUHJlc3MgdG8gY2hlY2sgZm9yIHVwZGF0ZXMKCQljYWxsX3VzZXJfZnVuYyggJHRoaXMtPnVwZ3JhZGVfcmVmcmVzaCApOwoKCQkkYWxsX2l0ZW1zID0gJHRoaXMtPmdldF9hbGxfaXRlbXMoKTsKCgkJaWYgKCAhIGlzX2FycmF5KCAkYWxsX2l0ZW1zICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyB7JHRoaXMtPml0ZW1fdHlwZX1zIGZvdW5kLiIgKTsKCQl9CgoJCWZvcmVhY2ggKCAkYWxsX2l0ZW1zIGFzICRrZXkgPT4gJiRpdGVtICkgewoKCQkJaWYgKCBlbXB0eSggJGl0ZW1bJ3ZlcnNpb24nXSApICkgewoJCQkJJGl0ZW1bJ3ZlcnNpb24nXSA9ICcnOwoJCQl9CgoJCQlmb3JlYWNoICggJGl0ZW0gYXMgJGZpZWxkID0+ICYkdmFsdWUgKSB7CgkJCQlpZiAoIHRydWUgPT09ICR2YWx1ZSApIHsKCQkJCQkkdmFsdWUgPSAnYXZhaWxhYmxlJzsKCQkJCX0gZWxzZWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJCQkkdmFsdWUgPSAnbm9uZSc7CgkJCQl9CgkJCX0KCgkJCWZvcmVhY2ggKCAkdGhpcy0+b2JqX2ZpZWxkcyBhcyAkZmllbGQgKSB7CgkJCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJGZpZWxkLCAkYXNzb2NfYXJncyApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCS8vIFRoaXMgY2FuIGJlIGVpdGhlciBhIHZhbHVlIHRvIGZpbHRlciBieSBvciBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIHZhbHVlcy4KCQkJCS8vIEFsc28sIGl0IGlzIG5vdCBmb3JiaWRkZW4gZm9yIGEgdmFsdWUgdG8gY29udGFpbiBhIGNvbW1hIChpbiB3aGljaCBjYXNlIHdlIGNhbiBmaWx0ZXIgb25seSBieSBvbmUpLgoJCQkJJGZpZWxkX2ZpbHRlciA9ICRhc3NvY19hcmdzWyAkZmllbGQgXTsKCQkJCWlmICgKCQkJCQkkaXRlbVsgJGZpZWxkIF0gIT09ICRmaWVsZF9maWx0ZXIKCQkJCQkmJiAhIGluX2FycmF5KCAkaXRlbVsgJGZpZWxkIF0sIGFycmF5X21hcCggJ3RyaW0nLCBleHBsb2RlKCAnLCcsICRmaWVsZF9maWx0ZXIgKSApLCB0cnVlICkKCQkJCSkgewoJCQkJCXVuc2V0KCAkYWxsX2l0ZW1zWyAka2V5IF0gKTsKCQkJCX0KCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRhbGxfaXRlbXMgKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYW4gaXRlbSBoYXMgYW4gdXBkYXRlIGF2YWlsYWJsZSBvciBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBUaGUgcGx1Z2luL3RoZW1lIHNsdWcKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGhhc191cGRhdGUoICRzbHVnICkgewoJCSR1cGRhdGVfbGlzdCA9IGdldF9zaXRlX3RyYW5zaWVudCggJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50ICk7CgoJCXJldHVybiBpc3NldCggJHVwZGF0ZV9saXN0LT5yZXNwb25zZVsgJHNsdWcgXSApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhdmFpbGFibGUgdXBkYXRlIGluZm8KCSAqCgkgKiBAcmV0dXJuIG1peGVkCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBkYXRlX2luZm8oKSB7CgkJcmV0dXJuIGdldF9zaXRlX3RyYW5zaWVudCggJHRoaXMtPnVwZ3JhZGVfdHJhbnNpZW50ICk7Cgl9CgoJcHJpdmF0ZSAkbWFwID0gWwoJCSdzaG9ydCcgPT4gWwoJCQknaW5hY3RpdmUnICAgICAgID0+ICdJJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnQScsCgkJCSdhY3RpdmUtbmV0d29yaycgPT4gJ04nLAoJCQknbXVzdC11c2UnICAgICAgID0+ICdNJywKCQkJJ3BhcmVudCcgICAgICAgICA9PiAnUCcsCgkJCSdkcm9waW4nICAgICAgICAgPT4gJ0QnLAoJCV0sCgkJJ2xvbmcnICA9PiBbCgkJCSdpbmFjdGl2ZScgICAgICAgPT4gJ0luYWN0aXZlJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnQWN0aXZlJywKCQkJJ2FjdGl2ZS1uZXR3b3JrJyA9PiAnTmV0d29yayBBY3RpdmUnLAoJCQknbXVzdC11c2UnICAgICAgID0+ICdNdXN0IFVzZScsCgkJCSdwYXJlbnQnICAgICAgICAgPT4gJ1BhcmVudCcsCgkJCSdkcm9waW4nICAgICAgICAgPT4gJ0Ryb3AtSW4nLAoJCV0sCgldOwoKCXByb3RlY3RlZCBmdW5jdGlvbiBmb3JtYXRfc3RhdHVzKCAkc3RhdHVzLCAkZm9ybWF0ICkgewoJCXJldHVybiAkdGhpcy0+Z2V0X2NvbG9yKCAkc3RhdHVzICkgLiAkdGhpcy0+bWFwWyAkZm9ybWF0IF1bICRzdGF0dXMgXTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb2xvciggJHN0YXR1cyApIHsKCQlzdGF0aWMgJGNvbG9ycyA9IFsKCQkJJ2luYWN0aXZlJyAgICAgICA9PiAnJywKCQkJJ2FjdGl2ZScgICAgICAgICA9PiAnJWcnLAoJCQknYWN0aXZlLW5ldHdvcmsnID0+ICclZycsCgkJCSdtdXN0LXVzZScgICAgICAgPT4gJyVjJywKCQkJJ3BhcmVudCcgICAgICAgICA9PiAnJXAnLAoJCQknZHJvcGluJyAgICAgICAgID0+ICclQicsCgkJXTsKCgkJcmV0dXJuICRjb2xvcnNbICRzdGF0dXMgXTsKCX0KCgkvKioKCSAqIEdldCB0aGUgbWlub3Igb3IgcGF0Y2ggdmVyc2lvbiBmb3IgcGx1Z2lucyB3aXRoIGF2YWlsYWJsZSB1cGRhdGVzCgkgKgoJICogQHBhcmFtIGFycmF5ICAkaXRlbXMgICAgUGx1Z2lucyB3aXRoIHVwZGF0ZXMuCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlICAgICBFaXRoZXIgJ21pbm9yJyBvciAncGF0Y2gnLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgV2hldGhlciB0byByZXRyeSB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gb24gVExTIGhhbmRzaGFrZSBmYWlsdXJlLgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9taW5vcl9vcl9wYXRjaF91cGRhdGVzKCAkaXRlbXMsICR0eXBlLCAkaW5zZWN1cmUgKSB7CgkJJHdwX29yZ19hcGkgPSBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApOwoJCWZvcmVhY2ggKCAkaXRlbXMgYXMgJGkgPT4gJGl0ZW0gKSB7CgkJCXRyeSB7CgkJCQkkZGF0YSA9ICR3cF9vcmdfYXBpLT5nZXRfcGx1Z2luX2luZm8oICRpdGVtWyduYW1lJ10gKTsKCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJLy8gTm8gbWlub3Igb3IgcGF0Y2ggdmVyc2lvbnMgdG8gYWNjZXNzLgoJCQlpZiAoIGVtcHR5KCAkZGF0YVsndmVyc2lvbnMnXSApICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJJHVwZGF0ZV92ZXJzaW9uID0gZmFsc2U7CgkJCSR1cGRhdGVfcGFja2FnZSA9IGZhbHNlOwoJCQlmb3JlYWNoICggJGRhdGFbJ3ZlcnNpb25zJ10gYXMgJHZlcnNpb24gPT4gJGRvd25sb2FkX2xpbmsgKSB7CgkJCQkkdXBkYXRlX3R5cGUgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJHZlcnNpb24sICRpdGVtWyd2ZXJzaW9uJ10gKTsKCQkJCS8vIENvbXBhcmVkIHZlcnNpb24gbXVzdCBiZSBvbGRlci4KCQkJCWlmICggISAkdXBkYXRlX3R5cGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkvLyBPbmx5IHBlcm1pdCAncGF0Y2gnIGZvciAncGF0Y2gnLgoJCQkJaWYgKCAncGF0Y2gnID09PSAkdHlwZSAmJiAncGF0Y2gnICE9PSAkdXBkYXRlX3R5cGUgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkvLyBQZXJtaXQgJ21pbm9yJyBvciAncGF0Y2gnIGZvciAnbWlub3InIHBocGNzOmlnbm9yZSBTcXVpei5QSFAuQ29tbWVudGVkT3V0Q29kZS5Gb3VuZCAtLSBGYWxzZSBwb3NpdGl2ZS4KCQkJCWlmICggJ21pbm9yJyA9PT0gJHR5cGUgJiYgISBpbl9hcnJheSggJHVwZGF0ZV90eXBlLCBhcnJheSggJ21pbm9yJywgJ3BhdGNoJyApLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlpZiAoICR1cGRhdGVfdmVyc2lvbiAmJiAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkdmVyc2lvbiwgJHVwZGF0ZV92ZXJzaW9uICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQkkdXBkYXRlX3ZlcnNpb24gPSAkdmVyc2lvbjsKCQkJCSR1cGRhdGVfcGFja2FnZSA9ICRkb3dubG9hZF9saW5rOwoJCQl9CgkJCS8vIElmIHRoZXJlJ3Mgbm90IGEgbWF0Y2hpbmcgdmVyc2lvbiwgYmFpbCBvbiB1cGRhdGVzLgoJCQlpZiAoICEgJHVwZGF0ZV92ZXJzaW9uICkgewoJCQkJdW5zZXQoICRpdGVtc1sgJGkgXSApOwoJCQkJY29udGludWU7CgkJCX0KCQkJJGl0ZW1zWyAkaSBdWyd1cGRhdGVfdmVyc2lvbiddID0gJHVwZGF0ZV92ZXJzaW9uOwoJCQkkaXRlbXNbICRpIF1bJ3VwZGF0ZV9wYWNrYWdlJ10gPSAkdXBkYXRlX3BhY2thZ2U7CgkJfQoJCXJldHVybiAkaXRlbXM7Cgl9CgoJLyoqCgkgKiBTZWFyY2ggd29yZHByZXNzLm9yZyByZXBvLgoJICoKCSAqIEBwYXJhbSAgYXJyYXkgJGFyZ3MgICAgICAgQSBhcmd1bWVudHMgYXJyYXkgY29udGFpbmluZyB0aGUgc2VhcmNoIHRlcm0gaW4gdGhlIGZpcnN0IGVsZW1lbnQuCgkgKiBAcGFyYW0gIGFycmF5ICRhc3NvY19hcmdzIERhdGEgcGFzc2VkIGluIGZyb20gY29tbWFuZC4KCSAqLwoJLy8gcGhwY3M6aWdub3JlIFBTUjIuTWV0aG9kcy5NZXRob2REZWNsYXJhdGlvbi5VbmRlcnNjb3JlIC0tIFdoaXRlbGlzdGluZyB0byBwcm92aWRlIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgdG8gY2xhc3NlcyBwb3NzaWJseSBleHRlbmRpbmcgdGhpcyBjbGFzcy4KCXByb3RlY3RlZCBmdW5jdGlvbiBfc2VhcmNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRlcm0gPSAkYXJnc1swXTsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdwZXItcGFnZScgPT4gMTAsCgkJCSdwYWdlJyAgICAgPT4gMSwKCQkJJ2ZpZWxkcycgICA9PiBpbXBsb2RlKCAnLCcsIFsgJ25hbWUnLCAnc2x1ZycsICdyYXRpbmcnIF0gKSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCQkkZmllbGRzICAgICA9IGFycmF5KCk7CgkJZm9yZWFjaCAoIGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICkgYXMgJGZpZWxkICkgewoJCQkkZmllbGRzWyAkZmllbGQgXSA9IHRydWU7CgkJfQoKCQkkZm9ybWF0ICAgID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgPyAkYXNzb2NfYXJnc1snZm9ybWF0J10gOiAndGFibGUnOwoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJGFwaV9hcmdzID0gWwoJCQkncGVyX3BhZ2UnID0+IChpbnQpICRhc3NvY19hcmdzWydwZXItcGFnZSddLAoJCQkncGFnZScgICAgID0+IChpbnQpICRhc3NvY19hcmdzWydwYWdlJ10sCgkJCSdzZWFyY2gnICAgPT4gJHRlcm0sCgkJCSdmaWVsZHMnICAgPT4gJGZpZWxkcywKCQldOwoKCQlpZiAoICdwbHVnaW4nID09PSAkdGhpcy0+aXRlbV90eXBlICkgewoJCQkkYXBpID0gcGx1Z2luc19hcGkoICdxdWVyeV9wbHVnaW5zJywgJGFwaV9hcmdzICk7CgkJfSBlbHNlIHsKCQkJJGFwaSA9IHRoZW1lc19hcGkoICdxdWVyeV90aGVtZXMnLCAkYXBpX2FyZ3MgKTsKCQl9CgoJCWlmICggaXNfd3BfZXJyb3IoICRhcGkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGFwaS0+Z2V0X2Vycm9yX21lc3NhZ2UoKSAuIF9fKCAnIFRyeSBhZ2FpbicgKSApOwoJCX0KCgkJJHBsdXJhbCA9ICR0aGlzLT5pdGVtX3R5cGUgLiAncyc7CgoJCWlmICggISBpc3NldCggJGFwaS0+JHBsdXJhbCApICkgewoJCQlXUF9DTEk6OmVycm9yKCBfXyggJ0FQSSBlcnJvci4gVHJ5IEFnYWluLicgKSApOwoJCX0KCgkJJGl0ZW1zID0gJGFwaS0+JHBsdXJhbDsKCgkJLy8gQWRkIGB1cmxgIGZvciBwbHVnaW4gb3IgdGhlbWUgb24gd29yZHByZXNzLm9yZy4KCQlmb3JlYWNoICggJGl0ZW1zIGFzICRpbmRleCA9PiAkaXRlbV9vYmplY3QgKSB7CgkJCWlmICggJGl0ZW1fb2JqZWN0IGluc3RhbmNlb2YgXHN0ZENsYXNzICkgewoJCQkJJGl0ZW1fb2JqZWN0LT51cmwgPSAiaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3skcGx1cmFsfS97JGl0ZW1fb2JqZWN0LT5zbHVnfS8iOwoJCQl9CgkJfQoKCQlpZiAoICd0YWJsZScgPT09ICRmb3JtYXQgKSB7CgkJCSRjb3VudCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXBpLT5pbmZvLCAncmVzdWx0cycsICd1bmtub3duJyApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICdTaG93aW5nICVzIG9mICVzICVzLicsIGNvdW50KCAkaXRlbXMgKSwgJGNvdW50LCAkcGx1cmFsICkgKTsKCQl9CgoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRpdGVtcyApOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5vYmpfZmllbGRzLCAkdGhpcy0+aXRlbV90eXBlICk7Cgl9CgoJLyoqCgkgKiBFcnJvciBoYW5kbGVyIHRvIGlnbm9yZSBmYWlsdXJlcyBvbiBhY2Nlc3NpbmcgU1NMICJodHRwczovL2FwaS53b3JkcHJlc3Mub3JnL3RoZW1lcy91cGRhdGUtY2hlY2svMS4xLyIgaW4gYHdwX3VwZGF0ZV90aGVtZXMoKWAKCSAqIGFuZCAiaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy9wbHVnaW5zL3VwZGF0ZS1jaGVjay8xLjEvIiBpbiBgd3BfdXBkYXRlX3BsdWdpbnMoKWAgd2hpY2ggc2VlbSB0byBvY2N1ciBpbnRlcm1pdHRlbnRseS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBlcnJvcl9oYW5kbGVyKCAkZXJybm8sICRlcnJzdHIsICRlcnJmaWxlLCAkZXJybGluZSwgJGVycmNvbnRleHQgPSBudWxsICkgewoJCS8vIElmIGlnbm9yaW5nIEVfVVNFUl9XQVJOSU5HIHwgRV9VU0VSX05PVElDRSwgZGVmYXVsdC4KCQlpZiAoICEgKCBlcnJvcl9yZXBvcnRpbmcoKSAmICRlcnJubyApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCS8vIElmIG5vdCBpbiAid3AtaW5jbHVkZXMvdXBkYXRlLnBocCIsIGRlZmF1bHQuCgkJJHVwZGF0ZV9waHAgPSAnd3AtaW5jbHVkZXMvdXBkYXRlLnBocCc7CgkJaWYgKCAwICE9PSBzdWJzdHJfY29tcGFyZSggJGVycmZpbGUsICR1cGRhdGVfcGhwLCAtc3RybGVuKCAkdXBkYXRlX3BocCApICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJLy8gRWxzZSBhc3N1bWUgaXQncyBpbiBgd3BfdXBkYXRlX3RoZW1lcygpYCBvciBgd3BfdXBkYXRlX3BsdWdpbnMoKWAgYW5kIGp1c3QgaWdub3JlIGl0LgoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUmV0cmlldmVzIFBIUF9VUkxfSE9TVCBjb21wb25lbnQgZnJvbSBVUkwuCgkgKgoJICogQHBhcmFtIGludCAkY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gcmV0cmlldmUuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZV91cmxfaG9zdF9jb21wb25lbnQoICR1cmwsICRjb21wb25lbnQgKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5BbHRlcm5hdGl2ZUZ1bmN0aW9ucy5wYXJzZV91cmxfcGFyc2VfdXJsIC0tIHBhcnNlX3VybCB3aWxsIG9ubHkgYmUgdXNlZCBpbiBhYnNlbmNlIG9mIHdwX3BhcnNlX3VybC4KCQlyZXR1cm4gZnVuY3Rpb25fZXhpc3RzKCAnd3BfcGFyc2VfdXJsJyApID8gd3BfcGFyc2VfdXJsKCAkdXJsLCAkY29tcG9uZW50ICkgOiBwYXJzZV91cmwoICR1cmwsICRjb21wb25lbnQgKTsKCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwoKdHJhaXQgUGFyc2VQbHVnaW5OYW1lSW5wdXQgewoKCS8qKgoJICogSWYgaGF2ZSBvcHRpb25hbCBhcmdzIChbPHBsdWdpbj4uLi5dKSBhbmQgYW4gYWxsIG9wdGlvbiwgdGhlbiBjaGVjayBoYXZlIHNvbWV0aGluZyB0byBkby4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRhcmdzIFBhc3NlZC1pbiBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYm9vbCAgICRhbGwgQWxsIGZsYWcuCgkgKiBAcGFyYW0gc3RyaW5nICR2ZXJiIE9wdGlvbmFsLiBWZXJiIHRvIHVzZS4gRGVmYXVsdHMgdG8gJ2luc3RhbGwnLgoJICogQHJldHVybiBhcnJheSBTYW1lIGFzICRhcmdzIGlmIG5vdCBhbGwsIG90aGVyd2lzZSBhbGwgc2x1Z3MuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgbmVpdGhlciBwbHVnaW4gbmFtZSBub3IgLS1hbGwgd2VyZSBwcm92aWRlZC4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwsICR2ZXJiID0gJ2luc3RhbGwnICkgewoJCWlmICggJGFsbCApIHsKCQkJJGFyZ3MgPSBhcnJheV9tYXAoCgkJCQknXFdQX0NMSVxVdGlsc1xnZXRfcGx1Z2luX25hbWUnLAoJCQkJYXJyYXlfa2V5cyggJHRoaXMtPmdldF9hbGxfcGx1Z2lucygpICkKCQkJKTsKCQl9CgoJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCWlmICggISAkYWxsICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IG9uZSBvciBtb3JlIHBsdWdpbnMsIG9yIHVzZSAtLWFsbC4nICk7CgkJCX0KCgkJCSRwYXN0X3RlbnNlX3ZlcmIgPSBVdGlsc1xwYXN0X3RlbnNlX3ZlcmIoICR2ZXJiICk7CgkJCVdQX0NMSTo6c3VjY2VzcyggIk5vIHBsdWdpbnMgeyRwYXN0X3RlbnNlX3ZlcmJ9LiIgKTsgLy8gRG9uJ3QgZXJyb3IgaWYgLS1hbGwgZ2l2ZW4gZm9yIEJDLgoJCX0KCgkJcmV0dXJuICRhcmdzOwoJfQoKCS8qKgoJICogR2V0cyBhbGwgYXZhaWxhYmxlIHBsdWdpbnMuCgkgKgoJICogVXNlcyB0aGUgc2FtZSBmaWx0ZXIgY29yZSB1c2VzIGluIHBsdWdpbnMucGhwIHRvIGRldGVybWluZSB3aGljaCBwbHVnaW5zCgkgKiBzaG91bGQgYmUgYXZhaWxhYmxlIHRvIG1hbmFnZSB0aHJvdWdoIHRoZSBXUF9QbHVnaW5zX0xpc3RfVGFibGUgY2xhc3MuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9hbGxfcGx1Z2lucygpIHsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCXJldHVybiBhcHBseV9maWx0ZXJzKCAnYWxsX3BsdWdpbnMnLCBnZXRfcGx1Z2lucygpICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7Cgp1c2UgV1BfQ0xJOwoKdHJhaXQgUGFyc2VUaGVtZU5hbWVJbnB1dCB7CgoJLyoqCgkgKiBJZiBoYXZlIG9wdGlvbmFsIGFyZ3MgKFs8dGhlbWU+Li4uXSkgYW5kIGFuIGFsbCBvcHRpb24sIHRoZW4gY2hlY2sgaGF2ZSBzb21ldGhpbmcgdG8gZG8uCgkgKgoJICogQHBhcmFtIGFycmF5ICAkYXJncyBQYXNzZWQtaW4gYXJndW1lbnRzLgoJICogQHBhcmFtIGJvb2wgICAkYWxsIEFsbCBmbGFnLgoJICogQHBhcmFtIHN0cmluZyAkdmVyYiBPcHRpb25hbC4gVmVyYiB0byB1c2UuIERlZmF1bHRzIHRvICdpbnN0YWxsJy4KCSAqIEByZXR1cm4gYXJyYXkgU2FtZSBhcyAkYXJncyBpZiBub3QgYWxsLCBvdGhlcndpc2UgYWxsIHNsdWdzLgoJICogQHRocm93cyBFeGl0RXhjZXB0aW9uIElmIG5laXRoZXIgcGx1Z2luIG5hbWUgbm9yIC0tYWxsIHdlcmUgcHJvdmlkZWQuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBjaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsLCAkdmVyYiA9ICdpbnN0YWxsJyApIHsKCQlpZiAoICRhbGwgKSB7CgkJCSRhcmdzID0gYXJyYXlfbWFwKAoJCQkJJ1xXUF9DTElcVXRpbHNcZ2V0X3RoZW1lX25hbWUnLAoJCQkJYXJyYXlfa2V5cyggJHRoaXMtPmdldF9hbGxfdGhlbWVzKCkgKQoJCQkpOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJaWYgKCAhICRhbGwgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgb25lIG9yIG1vcmUgdGhlbWVzLCBvciB1c2UgLS1hbGwuJyApOwoJCQl9CgoJCQkkcGFzdF90ZW5zZV92ZXJiID0gVXRpbHNccGFzdF90ZW5zZV92ZXJiKCAkdmVyYiApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJObyB0aGVtZXMgeyRwYXN0X3RlbnNlX3ZlcmJ9LiIgKTsgLy8gRG9uJ3QgZXJyb3IgaWYgLS1hbGwgZ2l2ZW4gZm9yIEJDLgoJCX0KCgkJcmV0dXJuICRhcmdzOwoJfQoKCS8qKgoJICogR2V0cyBhbGwgYXZhaWxhYmxlIHRoZW1lcy4KCSAqCgkgKiBVc2VzIHRoZSBzYW1lIGZpbHRlciBjb3JlIHVzZXMgaW4gdGhlbWVzLnBocCB0byBkZXRlcm1pbmUgd2hpY2ggdGhlbWVzCgkgKiBzaG91bGQgYmUgYXZhaWxhYmxlIHRvIG1hbmFnZSB0aHJvdWdoIHRoZSBXUF9UaGVtZXNfTGlzdF9UYWJsZSBjbGFzcy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2FsbF90aGVtZXMoKSB7CgkJJGl0ZW1zICAgICAgICAgICAgICA9IGFycmF5KCk7CgkJJHRoZW1lX3ZlcnNpb25faW5mbyA9IGFycmF5KCk7CgoJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCSRzaXRlX2VuYWJsZWQgPSBnZXRfb3B0aW9uKCAnYWxsb3dlZHRoZW1lcycgKTsKCQkJaWYgKCBlbXB0eSggJHNpdGVfZW5hYmxlZCApICkgewoJCQkJJHNpdGVfZW5hYmxlZCA9IGFycmF5KCk7CgkJCX0KCgkJCSRuZXR3b3JrX2VuYWJsZWQgPSBnZXRfc2l0ZV9vcHRpb24oICdhbGxvd2VkdGhlbWVzJyApOwoJCQlpZiAoIGVtcHR5KCAkbmV0d29ya19lbmFibGVkICkgKSB7CgkJCQkkbmV0d29ya19lbmFibGVkID0gYXJyYXkoKTsKCQkJfQoJCX0KCgkJJGFsbF91cGRhdGVfaW5mbyA9ICR0aGlzLT5nZXRfdXBkYXRlX2luZm8oKTsKCQkkY2hlY2tlZF90aGVtZXMgID0gaXNzZXQoICRhbGxfdXBkYXRlX2luZm8tPmNoZWNrZWQgKSA/ICRhbGxfdXBkYXRlX2luZm8tPmNoZWNrZWQgOiBhcnJheSgpOwoKCQlpZiAoICEgZW1wdHkoICRjaGVja2VkX3RoZW1lcyApICkgewoJCQlmb3JlYWNoICggJGNoZWNrZWRfdGhlbWVzIGFzICRzbHVnID0+ICR2ZXJzaW9uICkgewoJCQkJJHRoZW1lX3ZlcnNpb25faW5mb1sgJHNsdWcgXSA9ICR0aGlzLT5pc190aGVtZV92ZXJzaW9uX3ZhbGlkKCAkc2x1ZywgJHZlcnNpb24gKTsKCQkJfQoJCX0KCgkJZm9yZWFjaCAoIHdwX2dldF90aGVtZXMoKSBhcyAka2V5ID0+ICR0aGVtZSApIHsKCQkJJGZpbGUgPSAkdGhlbWUtPmdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpOwoKCQkJJHVwZGF0ZV9pbmZvID0gKCBpc3NldCggJGFsbF91cGRhdGVfaW5mby0+cmVzcG9uc2VbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdICkgJiYgbnVsbCAhPT0gJGFsbF91cGRhdGVfaW5mby0+cmVzcG9uc2VbICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXQoKSBdICkgPyAoYXJyYXkpICRhbGxfdXBkYXRlX2luZm8tPnJlc3BvbnNlWyAkdGhlbWUtPmdldF9zdHlsZXNoZWV0KCkgXSA6IG51bGw7CgoJCQkkaXRlbXNbICRmaWxlIF0gPSBbCgkJCQknbmFtZScgICAgICAgICAgID0+ICRrZXksCgkJCQknc3RhdHVzJyAgICAgICAgID0+ICR0aGlzLT5nZXRfc3RhdHVzKCAkdGhlbWUgKSwKCQkJCSd1cGRhdGUnICAgICAgICAgPT4gKGJvb2wpICR1cGRhdGVfaW5mbywKCQkJCSd1cGRhdGVfdmVyc2lvbicgPT4gaXNzZXQoICR1cGRhdGVfaW5mb1snbmV3X3ZlcnNpb24nXSApID8gJHVwZGF0ZV9pbmZvWyduZXdfdmVyc2lvbiddIDogbnVsbCwKCQkJCSd1cGRhdGVfcGFja2FnZScgPT4gaXNzZXQoICR1cGRhdGVfaW5mb1sncGFja2FnZSddICkgPyAkdXBkYXRlX2luZm9bJ3BhY2thZ2UnXSA6IG51bGwsCgkJCQkndmVyc2lvbicgICAgICAgID0+ICR0aGVtZS0+Z2V0KCAnVmVyc2lvbicgKSwKCQkJCSd1cGRhdGVfaWQnICAgICAgPT4gJHRoZW1lLT5nZXRfc3R5bGVzaGVldCgpLAoJCQkJJ3RpdGxlJyAgICAgICAgICA9PiAkdGhlbWUtPmdldCggJ05hbWUnICksCgkJCQknZGVzY3JpcHRpb24nICAgID0+IHdvcmR3cmFwKCAkdGhlbWUtPmdldCggJ0Rlc2NyaXB0aW9uJyApICksCgkJCQknYXV0aG9yJyAgICAgICAgID0+ICR0aGVtZS0+Z2V0KCAnQXV0aG9yJyApLAoJCQldOwoKCQkJLy8gQ29tcGFyZSB2ZXJzaW9uIGFuZCB1cGRhdGUgaW5mb3JtYXRpb24gaW4gdGhlbWUgbGlzdC4KCQkJaWYgKCBpc3NldCggJHRoZW1lX3ZlcnNpb25faW5mb1sgJGtleSBdICkgJiYgZmFsc2UgPT09ICR0aGVtZV92ZXJzaW9uX2luZm9bICRrZXkgXSApIHsKCQkJCSRpdGVtc1sgJGZpbGUgXVsndXBkYXRlJ10gPSAndmVyc2lvbiBoaWdoZXIgdGhhbiBleHBlY3RlZCc7CgkJCX0KCgkJCWlmICggaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRzaXRlX2VuYWJsZWRbICRrZXkgXSApICYmICEgZW1wdHkoICRuZXR3b3JrX2VuYWJsZWRbICRrZXkgXSApICkgewoJCQkJCSRpdGVtc1sgJGZpbGUgXVsnZW5hYmxlZCddID0gJ25ldHdvcmssc2l0ZSc7CgkJCQl9IGVsc2VpZiAoICEgZW1wdHkoICRuZXR3b3JrX2VuYWJsZWRbICRrZXkgXSApICkgewoJCQkJCSRpdGVtc1sgJGZpbGUgXVsnZW5hYmxlZCddID0gJ25ldHdvcmsnOwoJCQkJfSBlbHNlaWYgKCAhIGVtcHR5KCAkc2l0ZV9lbmFibGVkWyAka2V5IF0gKSApIHsKCQkJCQkkaXRlbXNbICRmaWxlIF1bJ2VuYWJsZWQnXSA9ICdzaXRlJzsKCQkJCX0gZWxzZSB7CgkJCQkJJGl0ZW1zWyAkZmlsZSBdWydlbmFibGVkJ10gPSAnbm8nOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gJGl0ZW1zOwoJfQoKCS8qKgoJICogQ2hlY2sgaWYgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0aGVtZSBpcyBoaWdoZXIgdGhhbiB0aGUgb25lIGF2YWlsYWJsZSBhdCBXUC5vcmcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2x1ZyBUaGVtZSBzbHVnLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBUaGVtZSBjdXJyZW50IHZlcnNpb24uCgkgKgoJICogQHJldHVybiBib29sfHN0cmluZwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gaXNfdGhlbWVfdmVyc2lvbl92YWxpZCggJHNsdWcsICR2ZXJzaW9uICkgewoJCS8vIEdldCBUaGVtZSBJbmZvLgoJCSR0aGVtZV9pbmZvID0gdGhlbWVzX2FwaSggJ3RoZW1lX2luZm9ybWF0aW9uJywgYXJyYXkoICdzbHVnJyA9PiAkc2x1ZyApICk7CgoJCS8vIFJldHVybiBlbXB0eSBzdHJpbmcgZm9yIHRoZW1lcyBub3Qgb24gV1Aub3JnLgoJCWlmICggaXNfd3BfZXJyb3IoICR0aGVtZV9pbmZvICkgKSB7CgkJCXJldHVybiAnJzsKCQl9CgoJCS8vIENvbXBhcmUgdGhlbWUgdmVyc2lvbiBpbmZvLgoJCXJldHVybiAhIHZlcnNpb25fY29tcGFyZSggJHZlcnNpb24sICR0aGVtZV9pbmZvLT52ZXJzaW9uLCAnPicgKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgc3RhdHVzIGZvciBhIGdpdmVuIHRoZW1lLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRoZW1lIFRoZW1lIHRvIGdldCB0aGUgc3RhdHVzIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBTdGF0dXMgb2YgdGhlIHRoZW1lLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3N0YXR1cyggJHRoZW1lICkgewoJCWlmICggJHRoaXMtPmlzX2FjdGl2ZV90aGVtZSggJHRoZW1lICkgKSB7CgkJCXJldHVybiAnYWN0aXZlJzsKCQl9CgoJCWlmICggJHRoZW1lLT5nZXRfc3R5bGVzaGVldF9kaXJlY3RvcnkoKSA9PT0gZ2V0X3RlbXBsYXRlX2RpcmVjdG9yeSgpICkgewoJCQlyZXR1cm4gJ3BhcmVudCc7CgkJfQoKCQlyZXR1cm4gJ2luYWN0aXZlJzsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiB0aGVtZSBpcyB0aGUgYWN0aXZlIHRoZW1lLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRoZW1lIFRoZW1lIHRvIGNoZWNrLgoJICoKCSAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBwcm92aWRlZCB0aGVtZSBpcyB0aGUgYWN0aXZlIHRoZW1lLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gaXNfYWN0aXZlX3RoZW1lKCAkdGhlbWUgKSB7CgkJcmV0dXJuICR0aGVtZS0+Z2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCkgPT09IGdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhdmFpbGFibGUgdXBkYXRlIGluZm8uCgkgKgoJICogQHJldHVybiBtaXhlZCBBdmFpbGFibGUgdXBkYXRlIGluZm8uCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfdXBkYXRlX2luZm8oKSB7CgkJcmV0dXJuIGdldF9zaXRlX3RyYW5zaWVudCggJ3VwZGF0ZV90aGVtZXMnICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTEk7CgovKioKICogQSB0aGVtZSB1cGdyYWRlciBjbGFzcyB0aGF0IGNsZWFycyB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5LgogKi8KY2xhc3MgRGVzdHJ1Y3RpdmVUaGVtZVVwZ3JhZGVyIGV4dGVuZHMgXFRoZW1lX1VwZ3JhZGVyIHsKCglwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbF9wYWNrYWdlKCAkYXJncyA9IGFycmF5KCkgKSB7CgkJcGFyZW50Ojp1cGdyYWRlX3N0cmluZ3MoKTsgLy8gTmVlZGVkIGZvciB0aGUgJ3JlbW92ZV9vbGQnIHN0cmluZy4KCgkJJGFyZ3NbJ2NsZWFyX2Rlc3RpbmF0aW9uJ10gICAgICAgICAgID0gdHJ1ZTsKCQkkYXJnc1snYWJvcnRfaWZfZGVzdGluYXRpb25fZXhpc3RzJ10gPSBmYWxzZTsKCQlyZXR1cm4gcGFyZW50OjppbnN0YWxsX3BhY2thZ2UoICRhcmdzICk7Cgl9Cn0KCjw/cGhwCgp1c2UgV1BfQ0xJXFBhcnNlUGx1Z2luTmFtZUlucHV0Owp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIE1hbmFnZXMgcGx1Z2lucywgaW5jbHVkaW5nIGluc3RhbGxzLCBhY3RpdmF0aW9ucywgYW5kIHVwZGF0ZXMuCiAqCiAqIFNlZSB0aGUgV29yZFByZXNzIFtQbHVnaW4gSGFuZGJvb2tdKGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcGx1Z2lucy8pIGRldmVsb3BlciByZXNvdXJjZSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBwbHVnaW5zLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBBY3RpdmF0ZSBwbHVnaW4KICogICAgICQgd3AgcGx1Z2luIGFjdGl2YXRlIGhlbGxvCiAqICAgICBQbHVnaW4gJ2hlbGxvJyBhY3RpdmF0ZWQuCiAqICAgICBTdWNjZXNzOiBBY3RpdmF0ZWQgMSBvZiAxIHBsdWdpbnMuCiAqCiAqICAgICAjIERlYWN0aXZhdGUgcGx1Z2luCiAqICAgICAkIHdwIHBsdWdpbiBkZWFjdGl2YXRlIGhlbGxvCiAqICAgICBQbHVnaW4gJ2hlbGxvJyBkZWFjdGl2YXRlZC4KICogICAgIFN1Y2Nlc3M6IERlYWN0aXZhdGVkIDEgb2YgMSBwbHVnaW5zLgogKgogKiAgICAgIyBEZWxldGUgcGx1Z2luCiAqICAgICAkIHdwIHBsdWdpbiBkZWxldGUgaGVsbG8KICogICAgIERlbGV0ZWQgJ2hlbGxvJyBwbHVnaW4uCiAqICAgICBTdWNjZXNzOiBEZWxldGVkIDEgb2YgMSBwbHVnaW5zLgogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgdmVyc2lvbiBmcm9tIHdvcmRwcmVzcy5vcmcgYW5kIGFjdGl2YXRlCiAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsIGJicHJlc3MgLS1hY3RpdmF0ZQogKiAgICAgSW5zdGFsbGluZyBiYlByZXNzICgyLjUuOSkKICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcGx1Z2luL2JicHJlc3MuMi41LjkuemlwLi4uCiAqICAgICBVc2luZyBjYWNoZWQgZmlsZSAnL2hvbWUvdmFncmFudC8ud3AtY2xpL2NhY2hlL3BsdWdpbi9iYnByZXNzLTIuNS45LnppcCcuLi4KICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgogKiAgICAgSW5zdGFsbGluZyB0aGUgcGx1Z2luLi4uCiAqICAgICBQbHVnaW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4KICogICAgIEFjdGl2YXRpbmcgJ2JicHJlc3MnLi4uCiAqICAgICBQbHVnaW4gJ2JicHJlc3MnIGFjdGl2YXRlZC4KICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgcGx1Z2lucy4KICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBQbHVnaW5fQ29tbWFuZCBleHRlbmRzIFxXUF9DTElcQ29tbWFuZFdpdGhVcGdyYWRlIHsKCgl1c2UgUGFyc2VQbHVnaW5OYW1lSW5wdXQ7CgoJcHJvdGVjdGVkICRpdGVtX3R5cGUgICAgICAgICA9ICdwbHVnaW4nOwoJcHJvdGVjdGVkICR1cGdyYWRlX3JlZnJlc2ggICA9ICd3cF91cGRhdGVfcGx1Z2lucyc7Cglwcm90ZWN0ZWQgJHVwZ3JhZGVfdHJhbnNpZW50ID0gJ3VwZGF0ZV9wbHVnaW5zJzsKCglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBhcnJheSgKCQknbmFtZScsCgkJJ3N0YXR1cycsCgkJJ3VwZGF0ZScsCgkJJ3ZlcnNpb24nLAoJKTsKCgkvKioKCSAqIFBsdWdpbiBmZXRjaGVyIGluc3RhbmNlLgoJICoKCSAqIEB2YXIgXFdQX0NMSVxGZXRjaGVyc1xQbHVnaW4KCSAqLwoJcHJvdGVjdGVkICRmZXRjaGVyOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9wbHVnaW4ucGhwJzsKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9wbHVnaW4taW5zdGFsbC5waHAnOwoKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCk7CgoJCSR0aGlzLT5mZXRjaGVyID0gbmV3IFdQX0NMSVxGZXRjaGVyc1xQbHVnaW4oKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3VwZ3JhZGVyX2NsYXNzKCAkZm9yY2UgKSB7CgkJcmV0dXJuICRmb3JjZSA/ICdcXFdQX0NMSVxcRGVzdHJ1Y3RpdmVQbHVnaW5VcGdyYWRlcicgOiAnUGx1Z2luX1VwZ3JhZGVyJzsKCX0KCgkvKioKCSAqIFJldmVhbHMgdGhlIHN0YXR1cyBvZiBvbmUgb3IgYWxsIHBsdWdpbnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPl0KCSAqIDogQSBwYXJ0aWN1bGFyIHBsdWdpbiB0byBzaG93IHRoZSBzdGF0dXMgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzcGxheXMgc3RhdHVzIG9mIGFsbCBwbHVnaW5zCgkgKiAgICAgJCB3cCBwbHVnaW4gc3RhdHVzCgkgKiAgICAgNSBpbnN0YWxsZWQgcGx1Z2luczoKCSAqICAgICAgIEkgYWtpc21ldCAgICAgICAgICAgICAgICAzLjEuMTEKCSAqICAgICAgIEkgZWFzeS1kaWdpdGFsLWRvd25sb2FkcyAyLjUuMTYKCSAqICAgICAgIEEgdGhlbWUtY2hlY2sgICAgICAgICAgICAyMDE2MDUyMy4xCgkgKiAgICAgICBJIHdlbi1sb2dvLXNsaWRlciAgICAgICAgMi4wLjMKCSAqICAgICAgIE0gbnMtcGFjayAgICAgICAgICAgICAgICAxLjAuMAoJICogICAgIExlZ2VuZDogSSA9IEluYWN0aXZlLCBBID0gQWN0aXZlLCBNID0gTXVzdCBVc2UKCSAqCgkgKiAgICAgIyBEaXNwbGF5cyBzdGF0dXMgb2YgYSBwbHVnaW4KCSAqICAgICAkIHdwIHBsdWdpbiBzdGF0dXMgdGhlbWUtY2hlY2sKCSAqICAgICBQbHVnaW4gdGhlbWUtY2hlY2sgZGV0YWlsczoKCSAqICAgICAgICAgTmFtZTogVGhlbWUgQ2hlY2sKCSAqICAgICAgICAgU3RhdHVzOiBBY3RpdmUKCSAqICAgICAgICAgVmVyc2lvbjogMjAxNjA1MjMuMQoJICogICAgICAgICBBdXRob3I6IE90dG80MiwgcHJvc3MKCSAqICAgICAgICAgRGVzY3JpcHRpb246IEEgc2ltcGxlIGFuZCBlYXN5IHdheSB0byB0ZXN0IHlvdXIgdGhlbWUgZm9yIGFsbCB0aGUgbGF0ZXN0IFdvcmRQcmVzcyBzdGFuZGFyZHMgYW5kIHByYWN0aWNlcy4gQSBncmVhdCB0aGVtZSBkZXZlbG9wbWVudCB0b29sIQoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RhdHVzKCAkYXJncyApIHsKCQlwYXJlbnQ6OnN0YXR1cyggJGFyZ3MgKTsKCX0KCgkvKioKCSAqIFNlYXJjaGVzIHRoZSBXb3JkUHJlc3Mub3JnIHBsdWdpbiBkaXJlY3RvcnkuCgkgKgoJICogRGlzcGxheXMgcGx1Z2lucyBpbiB0aGUgV29yZFByZXNzLm9yZyBwbHVnaW4gZGlyZWN0b3J5IG1hdGNoaW5nIGEgZ2l2ZW4KCSAqIHNlYXJjaCBxdWVyeS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNlYXJjaD4KCSAqIDogVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLgoJICoKCSAqIFstLXBhZ2U9PHBhZ2U+XQoJICogOiBPcHRpb25hbCBwYWdlIHRvIGRpc3BsYXkuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDEKCSAqIC0tLQoJICoKCSAqIFstLXBlci1wYWdlPTxwZXItcGFnZT5dCgkgKiA6IE9wdGlvbmFsIG51bWJlciBvZiByZXN1bHRzIHRvIGRpc3BsYXkuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDEwCgkgKiAtLS0KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHBsdWdpbi4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IEFzayBmb3Igc3BlY2lmaWMgZmllbGRzIGZyb20gdGhlIEFQSS4gRGVmYXVsdHMgdG8gbmFtZSxzbHVnLGF1dGhvcl9wcm9maWxlLHJhdGluZy4gQWNjZXB0YWJsZSB2YWx1ZXM6CgkgKgoJICogICAgICoqbmFtZSoqOiBQbHVnaW4gTmFtZQoJICogICAgICoqc2x1ZyoqOiBQbHVnaW4gU2x1ZwoJICogICAgICoqdmVyc2lvbioqOiBDdXJyZW50IFZlcnNpb24gTnVtYmVyCgkgKiAgICAgKiphdXRob3IqKjogUGx1Z2luIEF1dGhvcgoJICogICAgICoqYXV0aG9yX3Byb2ZpbGUqKjogUGx1Z2luIEF1dGhvciBQcm9maWxlCgkgKiAgICAgKipjb250cmlidXRvcnMqKjogUGx1Z2luIENvbnRyaWJ1dG9ycwoJICogICAgICoqcmVxdWlyZXMqKjogUGx1Z2luIE1pbmltdW0gUmVxdWlyZW1lbnRzCgkgKiAgICAgKip0ZXN0ZWQqKjogUGx1Z2luIFRlc3RlZCBVcCBUbwoJICogICAgICoqY29tcGF0aWJpbGl0eSoqOiBQbHVnaW4gQ29tcGF0aWJsZSBXaXRoCgkgKiAgICAgKipyYXRpbmcqKjogUGx1Z2luIFJhdGluZyBpbiBQZXJjZW50IGFuZCBUb3RhbCBOdW1iZXIKCSAqICAgICAqKnJhdGluZ3MqKjogUGx1Z2luIFJhdGluZ3MgZm9yIGVhY2ggc3RhciAoMS01KQoJICogICAgICoqbnVtX3JhdGluZ3MqKjogTnVtYmVyIG9mIFBsdWdpbiBSYXRpbmdzCgkgKiAgICAgKipob21lcGFnZSoqOiBQbHVnaW4gQXV0aG9yJ3MgSG9tZXBhZ2UKCSAqICAgICAqKmRlc2NyaXB0aW9uKio6IFBsdWdpbidzIERlc2NyaXB0aW9uCgkgKiAgICAgKipzaG9ydF9kZXNjcmlwdGlvbioqOiBQbHVnaW4ncyBTaG9ydCBEZXNjcmlwdGlvbgoJICogICAgICoqc2VjdGlvbnMqKjogUGx1Z2luIFJlYWRtZSBTZWN0aW9uczogZGVzY3JpcHRpb24sIGluc3RhbGxhdGlvbiwgRkFRLCBzY3JlZW5zaG90cywgb3RoZXIgbm90ZXMsIGFuZCBjaGFuZ2Vsb2cKCSAqICAgICAqKmRvd25sb2FkZWQqKjogUGx1Z2luIERvd25sb2FkIENvdW50CgkgKiAgICAgKipsYXN0X3VwZGF0ZWQqKjogUGx1Z2luJ3MgTGFzdCBVcGRhdGUKCSAqICAgICAqKmFkZGVkKio6IFBsdWdpbidzIERhdGUgQWRkZWQgdG8gd29yZHByZXNzLm9yZyBSZXBvc2l0b3J5CgkgKiAgICAgKip0YWdzKio6IFBsdWdpbidzIFRhZ3MKCSAqICAgICAqKnZlcnNpb25zKio6IFBsdWdpbidzIEF2YWlsYWJsZSBWZXJzaW9ucyB3aXRoIEQvTCBMaW5rCgkgKiAgICAgKipkb25hdGVfbGluayoqOiBQbHVnaW4ncyBEb25hdGlvbiBMaW5rCgkgKiAgICAgKipiYW5uZXJzKio6IFBsdWdpbidzIEJhbm5lciBJbWFnZSBMaW5rCgkgKiAgICAgKippY29ucyoqOiBQbHVnaW4ncyBJY29uIEltYWdlIExpbmsKCSAqICAgICAqKmFjdGl2ZV9pbnN0YWxscyoqOiBQbHVnaW4ncyBOdW1iZXIgb2YgQWN0aXZlIEluc3RhbGxzCgkgKiAgICAgKipjb250cmlidXRvcnMqKjogUGx1Z2luJ3MgTGlzdCBvZiBDb250cmlidXRvcnMKCSAqICAgICAqKnVybCoqOiBQbHVnaW4ncyBVUkwgb24gd29yZHByZXNzLm9yZwoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGNvdW50CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcGx1Z2luIHNlYXJjaCBkc2dud3JrcyAtLXBlci1wYWdlPTIwIC0tZm9ybWF0PWpzb24KCSAqICAgICBTdWNjZXNzOiBTaG93aW5nIDMgb2YgMyBwbHVnaW5zLgoJICogICAgIFt7Im5hbWUiOiJEc2duV3JrcyBJbnN0YWdyYW0gSW1wb3J0ZXIgRGVidWciLCJzbHVnIjoiZHNnbndya3MtaW5zdGFncmFtLWltcG9ydGVyLWRlYnVnIiwicmF0aW5nIjowfSx7Im5hbWUiOiJEc2duV3JrcyBJbnN0YWdyYW0gSW1wb3J0ZXIiLCJzbHVnIjoiZHNnbndya3MtaW5zdGFncmFtLWltcG9ydGVyIiwicmF0aW5nIjo4NH0seyJuYW1lIjoiRHNnbldya3MgVHdpdHRlciBJbXBvcnRlciIsInNsdWciOiJkc2dud3Jrcy10d2l0dGVyLWltcG9ydGVyIiwicmF0aW5nIjo4MH1dCgkgKgoJICogICAgICQgd3AgcGx1Z2luIHNlYXJjaCBkc2dud3JrcyAtLWZpZWxkcz1uYW1lLHZlcnNpb24sc2x1ZyxyYXRpbmcsbnVtX3JhdGluZ3MKCSAqICAgICBTdWNjZXNzOiBTaG93aW5nIDMgb2YgMyBwbHVnaW5zLgoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHZlcnNpb24gfCBzbHVnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCByYXRpbmcgfCBudW1fcmF0aW5ncyB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgRHNnbldya3MgSW5zdGFncmFtIEltcG9ydGVyIERlYnVnIHwgMC4xLjYgICB8IGRzZ253cmtzLWluc3RhZ3JhbS1pbXBvcnRlci1kZWJ1ZyB8IDAgICAgICB8IDAgICAgICAgICAgIHwKCSAqICAgICB8IERzZ25XcmtzIEluc3RhZ3JhbSBJbXBvcnRlciAgICAgICB8IDEuMy43ICAgfCBkc2dud3Jrcy1pbnN0YWdyYW0taW1wb3J0ZXIgICAgICAgfCA4NCAgICAgfCAyMyAgICAgICAgICB8CgkgKiAgICAgfCBEc2duV3JrcyBUd2l0dGVyIEltcG9ydGVyICAgICAgICAgfCAxLjEuMSAgIHwgZHNnbndya3MtdHdpdHRlci1pbXBvcnRlciAgICAgICAgIHwgODAgICAgIHwgMSAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNlYXJjaCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCXBhcmVudDo6X3NlYXJjaCggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIHN0YXR1c19zaW5nbGUoICRhcmdzICkgewoJCSRwbHVnaW4gPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X2NoZWNrKCAkYXJnc1swXSApOwoJCSRmaWxlICAgPSAkcGx1Z2luLT5maWxlOwoKCQkkZGV0YWlscyA9ICR0aGlzLT5nZXRfZGV0YWlscyggJGZpbGUgKTsKCgkJJHN0YXR1cyA9ICR0aGlzLT5mb3JtYXRfc3RhdHVzKCAkdGhpcy0+Z2V0X3N0YXR1cyggJGZpbGUgKSwgJ2xvbmcnICk7CgoJCSR2ZXJzaW9uID0gJGRldGFpbHNbJ1ZlcnNpb24nXTsKCgkJaWYgKCAkdGhpcy0+aGFzX3VwZGF0ZSggJGZpbGUgKSApIHsKCQkJJHZlcnNpb24gLj0gJyAoJWdVcGRhdGUgYXZhaWxhYmxlJW4pJzsKCQl9CgoJCWVjaG8gV1BfQ0xJOjpjb2xvcml6ZSgKCQkJVXRpbHNcbXVzdGFjaGVfcmVuZGVyKAoJCQkJc2VsZjo6Z2V0X3RlbXBsYXRlX3BhdGgoICdwbHVnaW4tc3RhdHVzLm11c3RhY2hlJyApLAoJCQkJWwoJCQkJCSdzbHVnJyAgICAgICAgPT4gVXRpbHNcZ2V0X3BsdWdpbl9uYW1lKCAkZmlsZSApLAoJCQkJCSdzdGF0dXMnICAgICAgPT4gJHN0YXR1cywKCQkJCQkndmVyc2lvbicgICAgID0+ICR2ZXJzaW9uLAoJCQkJCSduYW1lJyAgICAgICAgPT4gJGRldGFpbHNbJ05hbWUnXSwKCQkJCQknYXV0aG9yJyAgICAgID0+ICRkZXRhaWxzWydBdXRob3InXSwKCQkJCQknZGVzY3JpcHRpb24nID0+ICRkZXRhaWxzWydEZXNjcmlwdGlvbiddLAoJCQkJXQoJCQkpCgkJKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2FsbF9pdGVtcygpIHsKCQkkaXRlbXMgPSAkdGhpcy0+Z2V0X2l0ZW1fbGlzdCgpOwoKCQlmb3JlYWNoICggZ2V0X211X3BsdWdpbnMoKSBhcyAkZmlsZSA9PiAkbXVfcGx1Z2luICkgewoJCQkkbXVfdmVyc2lvbiA9ICcnOwoJCQlpZiAoICEgZW1wdHkoICRtdV9wbHVnaW5bJ1ZlcnNpb24nXSApICkgewoJCQkJJG11X3ZlcnNpb24gPSAkbXVfcGx1Z2luWydWZXJzaW9uJ107CgkJCX0KCgkJCSRpdGVtc1sgJGZpbGUgXSA9IGFycmF5KAoJCQkJJ25hbWUnICAgICAgICAgICA9PiBVdGlsc1xnZXRfcGx1Z2luX25hbWUoICRmaWxlICksCgkJCQknc3RhdHVzJyAgICAgICAgID0+ICdtdXN0LXVzZScsCgkJCQkndXBkYXRlJyAgICAgICAgID0+IGZhbHNlLAoJCQkJJ3VwZGF0ZV92ZXJzaW9uJyA9PiBudWxsLAoJCQkJJ3VwZGF0ZV9wYWNrYWdlJyA9PiBudWxsLAoJCQkJJ3ZlcnNpb24nICAgICAgICA9PiAkbXVfdmVyc2lvbiwKCQkJCSd1cGRhdGVfaWQnICAgICAgPT4gJycsCgkJCQkndGl0bGUnICAgICAgICAgID0+ICcnLAoJCQkJJ2Rlc2NyaXB0aW9uJyAgICA9PiAnJywKCQkJCSdmaWxlJyAgICAgICAgICAgPT4gJGZpbGUsCgkJCSk7CgkJfQoKCQkkcmF3X2l0ZW1zID0gZ2V0X2Ryb3BpbnMoKTsKCQkkcmF3X2RhdGEgID0gX2dldF9kcm9waW5zKCk7CgkJZm9yZWFjaCAoICRyYXdfaXRlbXMgYXMgJG5hbWUgPT4gJGl0ZW1fZGF0YSApIHsKCQkJJGRlc2NyaXB0aW9uICAgID0gISBlbXB0eSggJHJhd19kYXRhWyAkbmFtZSBdWzBdICkgPyAkcmF3X2RhdGFbICRuYW1lIF1bMF0gOiAnJzsKCQkJJGl0ZW1zWyAkbmFtZSBdID0gWwoJCQkJJ25hbWUnICAgICAgICAgICA9PiAkbmFtZSwKCQkJCSd0aXRsZScgICAgICAgICAgPT4gJGl0ZW1fZGF0YVsnVGl0bGUnXSwKCQkJCSdkZXNjcmlwdGlvbicgICAgPT4gJGRlc2NyaXB0aW9uLAoJCQkJJ3N0YXR1cycgICAgICAgICA9PiAnZHJvcGluJywKCQkJCSd1cGRhdGUnICAgICAgICAgPT4gZmFsc2UsCgkJCQkndXBkYXRlX3ZlcnNpb24nID0+IG51bGwsCgkJCQkndXBkYXRlX3BhY2thZ2UnID0+IG51bGwsCgkJCQkndXBkYXRlX2lkJyAgICAgID0+ICcnLAoJCQkJJ2ZpbGUnICAgICAgICAgICA9PiAkbmFtZSwKCQkJXTsKCQl9CgoJCXJldHVybiAkaXRlbXM7Cgl9CgoJLyoqCgkgKiBBY3RpdmF0ZXMgb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIGFjdGl2YXRlLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgcGx1Z2lucyB3aWxsIGJlIGFjdGl2YXRlZC4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSBhY3RpdmF0ZWQgZm9yIHRoZSBlbnRpcmUgbXVsdGlzaXRlIG5ldHdvcmsuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBBY3RpdmF0ZSBwbHVnaW4KCSAqICAgICAkIHdwIHBsdWdpbiBhY3RpdmF0ZSBoZWxsbwoJICogICAgIFBsdWdpbiAnaGVsbG8nIGFjdGl2YXRlZC4KCSAqICAgICBTdWNjZXNzOiBBY3RpdmF0ZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgQWN0aXZhdGUgcGx1Z2luIGluIGVudGlyZSBtdWx0aXNpdGUgbmV0d29yawoJICogICAgICQgd3AgcGx1Z2luIGFjdGl2YXRlIGhlbGxvIC0tbmV0d29yawoJICogICAgIFBsdWdpbiAnaGVsbG8nIG5ldHdvcmsgYWN0aXZhdGVkLgoJICogICAgIFN1Y2Nlc3M6IE5ldHdvcmsgYWN0aXZhdGVkIDEgb2YgMSBwbHVnaW5zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJG5ldHdvcmtfd2lkZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICk7CgkJJGFsbCAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwgKTsKCQlpZiAoICEgJGFyZ3MgKSB7CgkJCXJldHVybjsKCQl9CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRwbHVnaW5zICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJaWYgKCBjb3VudCggJHBsdWdpbnMgKSA8IGNvdW50KCAkYXJncyApICkgewoJCQkkZXJyb3JzID0gY291bnQoICRhcmdzICkgLSBjb3VudCggJHBsdWdpbnMgKTsKCQl9CgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW4gKSB7CgkJCSRzdGF0dXMgPSAkdGhpcy0+Z2V0X3N0YXR1cyggJHBsdWdpbi0+ZmlsZSApOwoJCQlpZiAoICRhbGwgJiYgaW5fYXJyYXkoICRzdGF0dXMsIFsgJ2FjdGl2ZScsICdhY3RpdmUtbmV0d29yaycgXSwgdHJ1ZSApICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJLy8gTmV0d29yay1hY3RpdmUgaXMgdGhlIGhpZ2hlc3QgbGV2ZWwgb2YgYWN0aXZhdGlvbiBzdGF0dXMuCgkJCWlmICggJ2FjdGl2ZS1uZXR3b3JrJyA9PT0gJHN0YXR1cyApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlBsdWdpbiAneyRwbHVnaW4tPm5hbWV9JyBpcyBhbHJlYWR5IG5ldHdvcmsgYWN0aXZlLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCS8vIERvbid0IHJlYWN0aXZhdGUgYWN0aXZlIHBsdWdpbnMsIGJ1dCBkbyBsZXQgdGhlbSBiZWNvbWUgbmV0d29yay1hY3RpdmUuCgkJCWlmICggISAkbmV0d29ya193aWRlICYmICdhY3RpdmUnID09PSAkc3RhdHVzICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUGx1Z2luICd7JHBsdWdpbi0+bmFtZX0nIGlzIGFscmVhZHkgYWN0aXZlLiIgKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBQbHVnaW5zIG5lZWQgdG8gYmUgZGVhY3RpdmF0ZWQgYmVmb3JlIGJlaW5nIG5ldHdvcmsgYWN0aXZhdGVkLgoJCQlpZiAoICRuZXR3b3JrX3dpZGUgJiYgJ2FjdGl2ZScgPT09ICRzdGF0dXMgKSB7CgkJCQlkZWFjdGl2YXRlX3BsdWdpbnMoICRwbHVnaW4tPmZpbGUsIGZhbHNlLCBmYWxzZSApOwoJCQl9CgoJCQkkcmVzdWx0ID0gYWN0aXZhdGVfcGx1Z2luKCAkcGx1Z2luLT5maWxlLCAnJywgJG5ldHdvcmtfd2lkZSApOwoKCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQkJJG1lc3NhZ2UgPSAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpOwoJCQkJJG1lc3NhZ2UgPSBwcmVnX3JlcGxhY2UoICcvPGFcc1tePl0rPi4qPFwvYT4vaW0nLCAnJywgJG1lc3NhZ2UgKTsKCQkJCSRtZXNzYWdlID0gd3Bfc3RyaXBfYWxsX3RhZ3MoICRtZXNzYWdlICk7CgkJCQkkbWVzc2FnZSA9IHN0cl9yZXBsYWNlKCAnRXJyb3I6ICcsICcnLCAkbWVzc2FnZSApOwoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiRmFpbGVkIHRvIGFjdGl2YXRlIHBsdWdpbi4geyRtZXNzYWdlfSIgKTsKCQkJfSBlbHNlIHsKCQkJCSR0aGlzLT5hY3RpdmVfb3V0cHV0KCAkcGx1Z2luLT5uYW1lLCAkcGx1Z2luLT5maWxlLCAkbmV0d29ya193aWRlLCAnYWN0aXZhdGUnICk7CgkJCQkkc3VjY2Vzc2VzKys7CgkJCX0KCQl9CgoJCWlmICggISAkdGhpcy0+Y2hhaW5lZF9jb21tYW5kICkgewoJCQkkdmVyYiA9ICRuZXR3b3JrX3dpZGUgPyAnbmV0d29yayBhY3RpdmF0ZScgOiAnYWN0aXZhdGUnOwoJCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdwbHVnaW4nLCAkdmVyYiwgY291bnQoICRhcmdzICksICRzdWNjZXNzZXMsICRlcnJvcnMgKTsKCQl9CgoJfQoKCS8qKgoJICogRGVhY3RpdmF0ZXMgb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIGRlYWN0aXZhdGUuCgkgKgoJICogWy0tdW5pbnN0YWxsXQoJICogOiBVbmluc3RhbGwgdGhlIHBsdWdpbiBhZnRlciBkZWFjdGl2YXRpb24uCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgZGVhY3RpdmF0ZWQuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogSWYgc2V0LCB0aGUgcGx1Z2luIHdpbGwgYmUgZGVhY3RpdmF0ZWQgZm9yIHRoZSBlbnRpcmUgbXVsdGlzaXRlIG5ldHdvcmsuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWFjdGl2YXRlIHBsdWdpbgoJICogICAgICQgd3AgcGx1Z2luIGRlYWN0aXZhdGUgaGVsbG8KCSAqICAgICBQbHVnaW4gJ2hlbGxvJyBkZWFjdGl2YXRlZC4KCSAqICAgICBTdWNjZXNzOiBEZWFjdGl2YXRlZCAxIG9mIDEgcGx1Z2lucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlYWN0aXZhdGUoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJG5ldHdvcmtfd2lkZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICk7CgkJJGRpc2FibGVfYWxsICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKTsKCgkJJGFyZ3MgPSAkdGhpcy0+Y2hlY2tfb3B0aW9uYWxfYXJnc19hbmRfYWxsKCAkYXJncywgJGRpc2FibGVfYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkcGx1Z2lucyAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCWlmICggY291bnQoICRwbHVnaW5zICkgPCBjb3VudCggJGFyZ3MgKSApIHsKCQkJJGVycm9ycyA9IGNvdW50KCAkYXJncyApIC0gY291bnQoICRwbHVnaW5zICk7CgkJfQoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCgkJCSRzdGF0dXMgPSAkdGhpcy0+Z2V0X3N0YXR1cyggJHBsdWdpbi0+ZmlsZSApOwoJCQlpZiAoICRkaXNhYmxlX2FsbCAmJiAhIGluX2FycmF5KCAkc3RhdHVzLCBbICdhY3RpdmUnLCAnYWN0aXZlLW5ldHdvcmsnIF0sIHRydWUgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvLyBOZXR3b3JrIGFjdGl2ZSBwbHVnaW5zIG11c3QgYmUgZXhwbGljaXRseSBkZWFjdGl2YXRlZC4KCQkJaWYgKCAhICRuZXR3b3JrX3dpZGUgJiYgJ2FjdGl2ZS1uZXR3b3JrJyA9PT0gJHN0YXR1cyApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIlBsdWdpbiAneyRwbHVnaW4tPm5hbWV9JyBpcyBuZXR3b3JrIGFjdGl2ZSBhbmQgbXVzdCBiZSBkZWFjdGl2YXRlZCB3aXRoIC0tbmV0d29yayBmbGFnLiIgKTsKCQkJCSRlcnJvcnMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgaW5fYXJyYXkoICRzdGF0dXMsIFsgJ2FjdGl2ZScsICdhY3RpdmUtbmV0d29yaycgXSwgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUGx1Z2luICd7JHBsdWdpbi0+bmFtZX0nIGlzbid0IGFjdGl2ZS4iICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJZGVhY3RpdmF0ZV9wbHVnaW5zKCAkcGx1Z2luLT5maWxlLCBmYWxzZSwgJG5ldHdvcmtfd2lkZSApOwoKCQkJaWYgKCAhIGlzX25ldHdvcmtfYWRtaW4oKSApIHsKCQkJCXVwZGF0ZV9vcHRpb24oCgkJCQkJJ3JlY2VudGx5X2FjdGl2YXRlZCcsCgkJCQkJYXJyYXkoICRwbHVnaW4tPmZpbGUgPT4gdGltZSgpICkgKyAoYXJyYXkpIGdldF9vcHRpb24oICdyZWNlbnRseV9hY3RpdmF0ZWQnICkKCQkJCSk7CgkJCX0gZWxzZSB7CgkJCQl1cGRhdGVfc2l0ZV9vcHRpb24oCgkJCQkJJ3JlY2VudGx5X2FjdGl2YXRlZCcsCgkJCQkJYXJyYXkoICRwbHVnaW4tPmZpbGUgPT4gdGltZSgpICkgKyAoYXJyYXkpIGdldF9zaXRlX29wdGlvbiggJ3JlY2VudGx5X2FjdGl2YXRlZCcgKQoJCQkJKTsKCQkJfQoKCQkJJHRoaXMtPmFjdGl2ZV9vdXRwdXQoICRwbHVnaW4tPm5hbWUsICRwbHVnaW4tPmZpbGUsICRuZXR3b3JrX3dpZGUsICdkZWFjdGl2YXRlJyApOwoJCQkkc3VjY2Vzc2VzKys7CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3VuaW5zdGFsbCcgKSApIHsKCQkJCVdQX0NMSTo6bG9nKCAiVW5pbnN0YWxsaW5nICd7JHBsdWdpbi0+bmFtZX0nLi4uIiApOwoJCQkJJHRoaXMtPmNoYWluZWRfY29tbWFuZCA9IHRydWU7CgkJCQkkdGhpcy0+dW5pbnN0YWxsKCBhcnJheSggJHBsdWdpbi0+bmFtZSApICk7CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gZmFsc2U7CgkJCX0KCQl9CgoJCWlmICggISAkdGhpcy0+Y2hhaW5lZF9jb21tYW5kICkgewoJCQkkdmVyYiA9ICRuZXR3b3JrX3dpZGUgPyAnbmV0d29yayBkZWFjdGl2YXRlJyA6ICdkZWFjdGl2YXRlJzsKCQkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAncGx1Z2luJywgJHZlcmIsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7CgkJfQoKCX0KCgkvKioKCSAqIFRvZ2dsZXMgYSBwbHVnaW4ncyBhY3RpdmF0aW9uIHN0YXRlLgoJICoKCSAqIElmIHRoZSBwbHVnaW4gaXMgYWN0aXZlLCB0aGVuIGl0IHdpbGwgYmUgZGVhY3RpdmF0ZWQuIElmIHRoZSBwbHVnaW4gaXMKCSAqIGluYWN0aXZlLCB0aGVuIGl0IHdpbGwgYmUgYWN0aXZhdGVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cGx1Z2luPi4uLgoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIHRvZ2dsZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBJZiBzZXQsIHRoZSBwbHVnaW4gd2lsbCBiZSB0b2dnbGVkIGZvciB0aGUgZW50aXJlIG11bHRpc2l0ZSBuZXR3b3JrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQWtpc21ldCBpcyBjdXJyZW50bHkgYWN0aXZhdGVkCgkgKiAgICAgJCB3cCBwbHVnaW4gdG9nZ2xlIGFraXNtZXQKCSAqICAgICBQbHVnaW4gJ2FraXNtZXQnIGRlYWN0aXZhdGVkLgoJICogICAgIFN1Y2Nlc3M6IFRvZ2dsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgQWtpc21ldCBpcyBjdXJyZW50bHkgZGVhY3RpdmF0ZWQKCSAqICAgICAkIHdwIHBsdWdpbiB0b2dnbGUgYWtpc21ldAoJICogICAgIFBsdWdpbiAnYWtpc21ldCcgYWN0aXZhdGVkLgoJICogICAgIFN1Y2Nlc3M6IFRvZ2dsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0b2dnbGUoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJG5ldHdvcmtfd2lkZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICk7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRwbHVnaW5zICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJaWYgKCBjb3VudCggJHBsdWdpbnMgKSA8IGNvdW50KCAkYXJncyApICkgewoJCQkkZXJyb3JzID0gY291bnQoICRhcmdzICkgLSBjb3VudCggJHBsdWdpbnMgKTsKCQl9CgkJJHRoaXMtPmNoYWluZWRfY29tbWFuZCA9IHRydWU7CgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW4gKSB7CgkJCWlmICggJHRoaXMtPmNoZWNrX2FjdGl2ZSggJHBsdWdpbi0+ZmlsZSwgJG5ldHdvcmtfd2lkZSApICkgewoJCQkJJHRoaXMtPmRlYWN0aXZhdGUoIGFycmF5KCAkcGx1Z2luLT5uYW1lICksICRhc3NvY19hcmdzICk7CgkJCX0gZWxzZSB7CgkJCQkkdGhpcy0+YWN0aXZhdGUoIGFycmF5KCAkcGx1Z2luLT5uYW1lICksICRhc3NvY19hcmdzICk7CgkJCX0KCQkJJHN1Y2Nlc3NlcysrOwoJCX0KCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gZmFsc2U7CgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAncGx1Z2luJywgJ3RvZ2dsZScsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBwYXRoIHRvIGEgcGx1Z2luIG9yIHRvIHRoZSBwbHVnaW4gZGlyZWN0b3J5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj5dCgkgKiA6IFRoZSBwbHVnaW4gdG8gZ2V0IHRoZSBwYXRoIHRvLiBJZiBub3Qgc2V0LCB3aWxsIHJldHVybiB0aGUgcGF0aCB0byB0aGUKCSAqIHBsdWdpbnMgZGlyZWN0b3J5LgoJICoKCSAqIFstLWRpcl0KCSAqIDogSWYgc2V0LCBnZXQgdGhlIHBhdGggdG8gdGhlIGNsb3Nlc3QgcGFyZW50IGRpcmVjdG9yeSwgaW5zdGVhZCBvZiB0aGUKCSAqIHBsdWdpbiBmaWxlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgY2QgJCh3cCBwbHVnaW4gcGF0aCkgJiYgcHdkCgkgKiAgICAgL3Zhci93d3cvd29yZHByZXNzL3dwLWNvbnRlbnQvcGx1Z2lucwoJICovCglwdWJsaWMgZnVuY3Rpb24gcGF0aCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRwYXRoID0gdW50cmFpbGluZ3NsYXNoaXQoIFdQX1BMVUdJTl9ESVIgKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICkgewoJCQkkcGx1Z2luID0gJHRoaXMtPmZldGNoZXItPmdldF9jaGVjayggJGFyZ3NbMF0gKTsKCQkJJHBhdGggIC49ICcvJyAuICRwbHVnaW4tPmZpbGU7CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RpcicgKSApIHsKCQkJCSRwYXRoID0gZGlybmFtZSggJHBhdGggKTsKCQkJfQoJCX0KCgkJV1BfQ0xJOjpsaW5lKCAkcGF0aCApOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBpbnN0YWxsX2Zyb21fcmVwbyggJHNsdWcsICRhc3NvY19hcmdzICkgewoJCSRhcGkgPSBwbHVnaW5zX2FwaSggJ3BsdWdpbl9pbmZvcm1hdGlvbicsIGFycmF5KCAnc2x1ZycgPT4gJHNsdWcgKSApOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkYXBpICkgKSB7CgkJCXJldHVybiAkYXBpOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICkgewoJCQlzZWxmOjphbHRlcl9hcGlfcmVzcG9uc2UoICRhcGksICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKTsKCQl9CgoJCSRzdGF0dXMgPSBpbnN0YWxsX3BsdWdpbl9pbnN0YWxsX3N0YXR1cyggJGFwaSApOwoKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICkgJiYgJ2luc3RhbGwnICE9PSAkc3RhdHVzWydzdGF0dXMnXSApIHsKCQkJLy8gV2Uga25vdyB0aGlzIHdpbGwgZmFpbCwgc28gYXZvaWQgYSBuZWVkbGVzcyBkb3dubG9hZCBvZiB0aGUgcGFja2FnZS4KCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2FscmVhZHlfaW5zdGFsbGVkJywgJ1BsdWdpbiBhbHJlYWR5IGluc3RhbGxlZC4nICk7CgkJfQoKCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ0luc3RhbGxpbmcgJXMgKCVzKScsIGh0bWxfZW50aXR5X2RlY29kZSggJGFwaS0+bmFtZSwgRU5UX1FVT1RFUyApLCAkYXBpLT52ZXJzaW9uICkgKTsKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ZlcnNpb24nICkgIT09ICdkZXYnICkgewoJCQlXUF9DTEk6OmdldF9odHRwX2NhY2hlX21hbmFnZXIoKS0+d2hpdGVsaXN0X3BhY2thZ2UoICRhcGktPmRvd25sb2FkX2xpbmssICR0aGlzLT5pdGVtX3R5cGUsICRhcGktPnNsdWcsICRhcGktPnZlcnNpb24gKTsKCQl9CgoJCS8vIElnbm9yZSBmYWlsdXJlcyBvbiBhY2Nlc3NpbmcgU1NMICJodHRwczovL2FwaS53b3JkcHJlc3Mub3JnL3BsdWdpbnMvdXBkYXRlLWNoZWNrLzEuMS8iIGluIGB3cF91cGRhdGVfcGx1Z2lucygpYCB3aGljaCBzZWVtIHRvIG9jY3VyIGludGVybWl0dGVudGx5LgoJCXNldF9lcnJvcl9oYW5kbGVyKCBhcnJheSggX19DTEFTU19fLCAnZXJyb3JfaGFuZGxlcicgKSwgRV9VU0VSX1dBUk5JTkcgfCBFX1VTRVJfTk9USUNFICk7CgoJCSRyZXN1bHQgPSAkdGhpcy0+Z2V0X3VwZ3JhZGVyKCAkYXNzb2NfYXJncyApLT5pbnN0YWxsKCAkYXBpLT5kb3dubG9hZF9saW5rICk7CgoJCXJlc3RvcmVfZXJyb3JfaGFuZGxlcigpOwoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIHVwZGF0ZS4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgYWxsIHBsdWdpbnMgdGhhdCBoYXZlIHVwZGF0ZXMgd2lsbCBiZSB1cGRhdGVkLgoJICoKCSAqIFstLWV4Y2x1ZGU9PG5hbWU+XQoJICogOiBDb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBwbHVnaW4gbmFtZXMgdGhhdCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSB1cGRhdGluZy4KCSAqCgkgKiBbLS1taW5vcl0KCSAqIDogT25seSBwZXJmb3JtIHVwZGF0ZXMgZm9yIG1pbm9yIHJlbGVhc2VzIChlLmcuIGZyb20gMS4zIHRvIDEuNCBpbnN0ZWFkIG9mIDIuMCkKCSAqCgkgKiBbLS1wYXRjaF0KCSAqIDogT25seSBwZXJmb3JtIHVwZGF0ZXMgZm9yIHBhdGNoIHJlbGVhc2VzIChlLmcuIGZyb20gMS4zIHRvIDEuMy4zIGluc3RlYWQgb2YgMS40KQoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBzdW1tYXJ5CgkgKiAtLS0KCSAqCgkgKiBbLS12ZXJzaW9uPTx2ZXJzaW9uPl0KCSAqIDogSWYgc2V0LCB0aGUgcGx1Z2luIHdpbGwgYmUgdXBkYXRlZCB0byB0aGUgc3BlY2lmaWVkIHZlcnNpb24uCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogUHJldmlldyB3aGljaCBwbHVnaW5zIHdvdWxkIGJlIHVwZGF0ZWQuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkcyB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gdXBkYXRlIGJicHJlc3MgLS12ZXJzaW9uPWRldgoJICogICAgIEluc3RhbGxpbmcgYmJQcmVzcyAoRGV2ZWxvcG1lbnQgVmVyc2lvbikKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9iYnByZXNzLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUGx1Z2luIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIFN1Y2Nlc3M6IFVwZGF0ZWQgMSBvZiAyIHBsdWdpbnMuCgkgKgoJICogICAgICQgd3AgcGx1Z2luIHVwZGF0ZSAtLWFsbAoJICogICAgIEVuYWJsaW5nIE1haW50ZW5hbmNlIG1vZGUuLi4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9ha2lzbWV0LjMuMS4xMS56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgRG93bmxvYWRpbmcgdXBkYXRlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4vbmdpbngtY2hhbXB1cnUuMy4yLjAuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFJlbW92aW5nIHRoZSBvbGQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUGx1Z2luIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIERpc2FibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgbmFtZSAgICAgICAgICAgICAgICAgICB8IG9sZF92ZXJzaW9uIHwgbmV3X3ZlcnNpb24gfCBzdGF0dXMgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBha2lzbWV0ICAgICAgICAgICAgICAgIHwgMy4xLjMgICAgICAgfCAzLjEuMTEgICAgICB8IFVwZGF0ZWQgfAoJICogICAgIHwgbmdpbngtY2FjaGUtY29udHJvbGxlciB8IDMuMS4xICAgICAgIHwgMy4yLjAgICAgICAgfCBVcGRhdGVkIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAyIG9mIDIgcGx1Z2lucy4KCSAqCgkgKiAgICAgJCB3cCBwbHVnaW4gdXBkYXRlIC0tYWxsIC0tZXhjbHVkZT1ha2lzbWV0CgkgKiAgICAgRW5hYmxpbmcgTWFpbnRlbmFuY2UgbW9kZS4uLgoJICogICAgIERvd25sb2FkaW5nIHVwZGF0ZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcGx1Z2luL25naW54LWNoYW1wdXJ1LjMuMi4wLnppcC4uLgoJICogICAgIFVucGFja2luZyB0aGUgdXBkYXRlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgbGF0ZXN0IHZlcnNpb24uLi4KCSAqICAgICBSZW1vdmluZyB0aGUgb2xkIHZlcnNpb24gb2YgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBEaXNhYmxpbmcgTWFpbnRlbmFuY2UgbW9kZS4uLgoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICAgfCBvbGRfdmVyc2lvbiB8IG5ld192ZXJzaW9uIHwgc3RhdHVzICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgbmdpbngtY2FjaGUtY29udHJvbGxlciB8IDMuMS4xICAgICAgIHwgMy4yLjAgICAgICAgfCBVcGRhdGVkIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rCgkgKgoJICogQGFsaWFzIHVwZ3JhZGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndmVyc2lvbiddICkgKSB7CgkJCWZvcmVhY2ggKCAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICkgYXMgJHBsdWdpbiApIHsKCQkJCSRhc3NvY19hcmdzWydmb3JjZSddID0gMTsKCQkJCSR0aGlzLT5pbnN0YWxsKCBhcnJheSggJHBsdWdpbi0+bmFtZSApLCAkYXNzb2NfYXJncyApOwoJCQl9CgkJfSBlbHNlIHsKCQkJcGFyZW50Ojp1cGRhdGVfbWFueSggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJfQoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfaXRlbV9saXN0KCkgewoJCSRpdGVtcyAgICAgICAgICAgPSBbXTsKCQkkZHVwbGljYXRlX25hbWVzID0gW107CgoJCWZvcmVhY2ggKCAkdGhpcy0+Z2V0X2FsbF9wbHVnaW5zKCkgYXMgJGZpbGUgPT4gJGRldGFpbHMgKSB7CgkJCSRhbGxfdXBkYXRlX2luZm8gPSAkdGhpcy0+Z2V0X3VwZGF0ZV9pbmZvKCk7CgkJCSR1cGRhdGVfaW5mbyAgICAgPSAoIGlzc2V0KCAkYWxsX3VwZGF0ZV9pbmZvLT5yZXNwb25zZVsgJGZpbGUgXSApICYmIG51bGwgIT09ICRhbGxfdXBkYXRlX2luZm8tPnJlc3BvbnNlWyAkZmlsZSBdICkgPyAoYXJyYXkpICRhbGxfdXBkYXRlX2luZm8tPnJlc3BvbnNlWyAkZmlsZSBdIDogbnVsbDsKCQkJJG5hbWUgICAgICAgICAgICA9IFV0aWxzXGdldF9wbHVnaW5fbmFtZSggJGZpbGUgKTsKCgkJCWlmICggISBpc3NldCggJGR1cGxpY2F0ZV9uYW1lc1sgJG5hbWUgXSApICkgewoJCQkJJGR1cGxpY2F0ZV9uYW1lc1sgJG5hbWUgXSA9IGFycmF5KCk7CgkJCX0KCgkJCSRkdXBsaWNhdGVfbmFtZXNbICRuYW1lIF1bXSA9ICRmaWxlOwoJCQkkaXRlbXNbICRmaWxlIF0gICAgICAgICAgICAgPSBbCgkJCQknbmFtZScgICAgICAgICAgID0+ICRuYW1lLAoJCQkJJ3N0YXR1cycgICAgICAgICA9PiAkdGhpcy0+Z2V0X3N0YXR1cyggJGZpbGUgKSwKCQkJCSd1cGRhdGUnICAgICAgICAgPT4gKGJvb2wpICR1cGRhdGVfaW5mbywKCQkJCSd1cGRhdGVfdmVyc2lvbicgPT4gaXNzZXQoICR1cGRhdGVfaW5mbyApICYmIGlzc2V0KCAkdXBkYXRlX2luZm9bJ25ld192ZXJzaW9uJ10gKSA/ICR1cGRhdGVfaW5mb1snbmV3X3ZlcnNpb24nXSA6IG51bGwsCgkJCQkndXBkYXRlX3BhY2thZ2UnID0+IGlzc2V0KCAkdXBkYXRlX2luZm8gKSAmJiBpc3NldCggJHVwZGF0ZV9pbmZvWydwYWNrYWdlJ10gKSA/ICR1cGRhdGVfaW5mb1sncGFja2FnZSddIDogbnVsbCwKCQkJCSd2ZXJzaW9uJyAgICAgICAgPT4gJGRldGFpbHNbJ1ZlcnNpb24nXSwKCQkJCSd1cGRhdGVfaWQnICAgICAgPT4gJGZpbGUsCgkJCQkndGl0bGUnICAgICAgICAgID0+ICRkZXRhaWxzWydOYW1lJ10sCgkJCQknZGVzY3JpcHRpb24nICAgID0+IHdvcmR3cmFwKCAkZGV0YWlsc1snRGVzY3JpcHRpb24nXSApLAoJCQkJJ2ZpbGUnICAgICAgICAgICA9PiAkZmlsZSwKCQkJXTsKCgkJCWlmICggbnVsbCA9PT0gJHVwZGF0ZV9pbmZvICkgewoKCQkJCS8vIEdldCBpbmZvIGZvciBhbGwgcGx1Z2lucyB0aGF0IGRvbid0IGhhdmUgYW4gdXBkYXRlLgoJCQkJJHBsdWdpbl91cGRhdGVfaW5mbyA9IGlzc2V0KCAkYWxsX3VwZGF0ZV9pbmZvLT5ub191cGRhdGVbICRmaWxlIF0gKSA/ICRhbGxfdXBkYXRlX2luZm8tPm5vX3VwZGF0ZVsgJGZpbGUgXSA6IG51bGw7CgoJCQkJLy8gQ29tcGFyZSB2ZXJzaW9uIGFuZCB1cGRhdGUgaW5mb3JtYXRpb24gaW4gcGx1Z2luIGxpc3QuCgkJCQlpZiAoIG51bGwgIT09ICRwbHVnaW5fdXBkYXRlX2luZm8gJiYgdmVyc2lvbl9jb21wYXJlKCAkZGV0YWlsc1snVmVyc2lvbiddLCAkcGx1Z2luX3VwZGF0ZV9pbmZvLT5uZXdfdmVyc2lvbiwgJz4nICkgKSB7CgkJCQkJJGl0ZW1zWyAkZmlsZSBdWyd1cGRhdGUnXSA9IHN0YXRpYzo6SU5WQUxJRF9WRVJTSU9OX01FU1NBR0U7CgkJCQl9CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkZHVwbGljYXRlX25hbWVzIGFzICRuYW1lID0+ICRmaWxlcyApIHsKCQkJaWYgKCBjb3VudCggJGZpbGVzICkgPD0gMSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCQkkaXRlbXNbICRmaWxlIF1bJ25hbWUnXSA9IHN0cl9yZXBsYWNlKCAnLicgLiBwYXRoaW5mbyggJGZpbGUsIFBBVEhJTkZPX0VYVEVOU0lPTiApLCAnJywgJGZpbGUgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRpdGVtczsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZmlsdGVyX2l0ZW1fbGlzdCggJGl0ZW1zLCAkYXJncyApIHsKCQkkYmFzZW5hbWVzID0gd3BfbGlzdF9wbHVjayggJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApLCAnZmlsZScgKTsKCQlyZXR1cm4gVXRpbHNccGlja19maWVsZHMoICRpdGVtcywgJGJhc2VuYW1lcyApOwoJfQoKCS8qKgoJICogSW5zdGFsbHMgb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBsdWdpbnx6aXB8dXJsPi4uLgoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIGluc3RhbGwuIEFjY2VwdHMgYSBwbHVnaW4gc2x1ZywgdGhlIHBhdGggdG8gYSBsb2NhbCB6aXAgZmlsZSwgb3IgYSBVUkwgdG8gYSByZW1vdGUgemlwIGZpbGUuCgkgKgoJICogWy0tdmVyc2lvbj08dmVyc2lvbj5dCgkgKiA6IElmIHNldCwgZ2V0IHRoYXQgcGFydGljdWxhciB2ZXJzaW9uIGZyb20gd29yZHByZXNzLm9yZywgaW5zdGVhZCBvZiB0aGUKCSAqIHN0YWJsZSB2ZXJzaW9uLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBJZiBzZXQsIHRoZSBjb21tYW5kIHdpbGwgb3ZlcndyaXRlIGFueSBpbnN0YWxsZWQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLCB3aXRob3V0IHByb21wdGluZwoJICogZm9yIGNvbmZpcm1hdGlvbi4KCSAqCgkgKiBbLS1hY3RpdmF0ZV0KCSAqIDogSWYgc2V0LCB0aGUgcGx1Z2luIHdpbGwgYmUgYWN0aXZhdGVkIGltbWVkaWF0ZWx5IGFmdGVyIGluc3RhbGwuCgkgKgoJICogWy0tYWN0aXZhdGUtbmV0d29ya10KCSAqIDogSWYgc2V0LCB0aGUgcGx1Z2luIHdpbGwgYmUgbmV0d29yayBhY3RpdmF0ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaW5zdGFsbAoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBkb3dubG9hZHMgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGlmIFRMUyBoYW5kc2hha2UgZmFpbHMuIE5vdGU6IFRoaXMgbWFrZXMgdGhlIHJlcXVlc3QgdnVsbmVyYWJsZSB0byBhIE1JVE0gYXR0YWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgSW5zdGFsbCB0aGUgbGF0ZXN0IHZlcnNpb24gZnJvbSB3b3JkcHJlc3Mub3JnIGFuZCBhY3RpdmF0ZQoJICogICAgICQgd3AgcGx1Z2luIGluc3RhbGwgYmJwcmVzcyAtLWFjdGl2YXRlCgkgKiAgICAgSW5zdGFsbGluZyBiYlByZXNzICgyLjUuOSkKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3BsdWdpbi9iYnByZXNzLjIuNS45LnppcC4uLgoJICogICAgIFVzaW5nIGNhY2hlZCBmaWxlICcvaG9tZS92YWdyYW50Ly53cC1jbGkvY2FjaGUvcGx1Z2luL2JicHJlc3MtMi41LjkuemlwJy4uLgoJICogICAgIFVucGFja2luZyB0aGUgcGFja2FnZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIHBsdWdpbi4uLgoJICogICAgIFBsdWdpbiBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIEFjdGl2YXRpbmcgJ2JicHJlc3MnLi4uCgkgKiAgICAgUGx1Z2luICdiYnByZXNzJyBhY3RpdmF0ZWQuCgkgKiAgICAgU3VjY2VzczogSW5zdGFsbGVkIDEgb2YgMSBwbHVnaW5zLgoJICoKCSAqICAgICAjIEluc3RhbGwgdGhlIGRldmVsb3BtZW50IHZlcnNpb24gZnJvbSB3b3JkcHJlc3Mub3JnCgkgKiAgICAgJCB3cCBwbHVnaW4gaW5zdGFsbCBiYnByZXNzIC0tdmVyc2lvbj1kZXYKCSAqICAgICBJbnN0YWxsaW5nIGJiUHJlc3MgKERldmVsb3BtZW50IFZlcnNpb24pCgkgKiAgICAgRG93bmxvYWRpbmcgaW5zdGFsbCBwYWNrYWdlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4vYmJwcmVzcy56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgSW5zdGFsbCBmcm9tIGEgbG9jYWwgemlwIGZpbGUKCSAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsIC4uL215LXBsdWdpbi56aXAKCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgSW5zdGFsbCBmcm9tIGEgcmVtb3RlIHppcCBmaWxlCgkgKiAgICAgJCB3cCBwbHVnaW4gaW5zdGFsbCBodHRwOi8vczMuYW1hem9uYXdzLmNvbS9idWNrZXRuYW1lL215LXBsdWdpbi56aXA/QVdTQWNjZXNzS2V5SWQ9MTIzJkV4cGlyZXM9NDU2JlNpZ25hdHVyZT1hYmNkZWYKCSAqICAgICBEb3dubG9hZGluZyBpbnN0YWxsIHBhY2thZ2UgZnJvbSBodHRwOi8vczMuYW1hem9uYXdzLmNvbS9idWNrZXRuYW1lL215LXBsdWdpbi56aXA/QVdTQWNjZXNzS2V5SWQ9MTIzJkV4cGlyZXM9NDU2JlNpZ25hdHVyZT1hYmNkZWYKCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgVXBkYXRlIGZyb20gYSByZW1vdGUgemlwIGZpbGUKCSAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsIGh0dHBzOi8vZ2l0aHViLmNvbS9lbnZhdG8vd3AtZW52YXRvLW1hcmtldC9hcmNoaXZlL21hc3Rlci56aXAgLS1mb3JjZQoJICogICAgIERvd25sb2FkaW5nIGluc3RhbGwgcGFja2FnZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9lbnZhdG8vd3AtZW52YXRvLW1hcmtldC9hcmNoaXZlL21hc3Rlci56aXAKCSAqICAgICBVbnBhY2tpbmcgdGhlIHBhY2thZ2UuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBwbHVnaW4uLi4KCSAqICAgICBSZW5hbWVkIEdpdGh1Yi1iYXNlZCBwcm9qZWN0IGZyb20gJ3dwLWVudmF0by1tYXJrZXQtbWFzdGVyJyB0byAnd3AtZW52YXRvLW1hcmtldCcuCgkgKiAgICAgUGx1Z2luIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5CgkgKiAgICAgU3VjY2VzczogSW5zdGFsbGVkIDEgb2YgMSBwbHVnaW5zLgoJICoKCSAqICAgICAjIEZvcmNlZnVsbHkgcmUtaW5zdGFsbCBhbGwgaW5zdGFsbGVkIHBsdWdpbnMKCSAqICAgICAkIHdwIHBsdWdpbiBpbnN0YWxsICQod3AgcGx1Z2luIGxpc3QgLS1maWVsZD1uYW1lKSAtLWZvcmNlCgkgKiAgICAgSW5zdGFsbGluZyBBa2lzbWV0ICgzLjEuMTEpCgkgKiAgICAgRG93bmxvYWRpbmcgaW5zdGFsbCBwYWNrYWdlIGZyb20gaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4vYWtpc21ldC4zLjEuMTEuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSBwYWNrYWdlLi4uCgkgKiAgICAgSW5zdGFsbGluZyB0aGUgcGx1Z2luLi4uCgkgKiAgICAgUmVtb3ZpbmcgdGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBwbHVnaW4uLi4KCSAqICAgICBQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHkKCSAqICAgICBTdWNjZXNzOiBJbnN0YWxsZWQgMSBvZiAxIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWlmICggISBpc19kaXIoIFdQX1BMVUdJTl9ESVIgKSApIHsKCQkJd3BfbWtkaXJfcCggV1BfUExVR0lOX0RJUiApOwoJCX0KCgkJcGFyZW50OjppbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEdldHMgZGV0YWlscyBhYm91dCBhbiBpbnN0YWxsZWQgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cGx1Z2luPgoJICogOiBUaGUgcGx1Z2luIHRvIGdldC4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBJbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgd2hvbGUgcGx1Z2luLCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZC4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBsdWdpbiBnZXQgYmJwcmVzcyAtLWZvcm1hdD1qc29uCgkgKiAgICAgeyJuYW1lIjoiYmJwcmVzcyIsInRpdGxlIjoiYmJQcmVzcyIsImF1dGhvciI6IlRoZSBiYlByZXNzIENvbnRyaWJ1dG9ycyIsInZlcnNpb24iOiIyLjYtYWxwaGEiLCJkZXNjcmlwdGlvbiI6ImJiUHJlc3MgaXMgZm9ydW0gc29mdHdhcmUgd2l0aCBhIHR3aXN0IGZyb20gdGhlIGNyZWF0b3JzIG9mIFdvcmRQcmVzcy4iLCJzdGF0dXMiOiJhY3RpdmUifQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBsdWdpbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfY2hlY2soICRhcmdzWzBdICk7CgkJJGZpbGUgICA9ICRwbHVnaW4tPmZpbGU7CgoJCSRwbHVnaW5fZGF0YSA9IGdldF9wbHVnaW5fZGF0YSggV1BfUExVR0lOX0RJUiAuICcvJyAuICRmaWxlLCBmYWxzZSwgZmFsc2UgKTsKCgkJJHBsdWdpbl9vYmogPSAob2JqZWN0KSBbCgkJCSduYW1lJyAgICAgICAgPT4gVXRpbHNcZ2V0X3BsdWdpbl9uYW1lKCAkZmlsZSApLAoJCQkndGl0bGUnICAgICAgID0+ICRwbHVnaW5fZGF0YVsnTmFtZSddLAoJCQknYXV0aG9yJyAgICAgID0+ICRwbHVnaW5fZGF0YVsnQXV0aG9yJ10sCgkJCSd2ZXJzaW9uJyAgICAgPT4gJHBsdWdpbl9kYXRhWydWZXJzaW9uJ10sCgkJCSdkZXNjcmlwdGlvbicgPT4gd29yZHdyYXAoICRwbHVnaW5fZGF0YVsnRGVzY3JpcHRpb24nXSApLAoJCQknc3RhdHVzJyAgICAgID0+ICR0aGlzLT5nZXRfc3RhdHVzKCAkZmlsZSApLAoJCV07CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmaWVsZHMnXSApICkgewoJCQkkcGx1Z2luX2FycmF5ICAgICAgICAgPSBnZXRfb2JqZWN0X3ZhcnMoICRwbHVnaW5fb2JqICk7CgkJCSRhc3NvY19hcmdzWydmaWVsZHMnXSA9IGFycmF5X2tleXMoICRwbHVnaW5fYXJyYXkgKTsKCQl9CgoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW0oICRwbHVnaW5fb2JqICk7Cgl9CgoJLyoqCgkgKiBVbmluc3RhbGxzIG9uZSBvciBtb3JlIHBsdWdpbnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byB1bmluc3RhbGwuCgkgKgoJICogWy0tZGVhY3RpdmF0ZV0KCSAqIDogRGVhY3RpdmF0ZSB0aGUgcGx1Z2luIGJlZm9yZSB1bmluc3RhbGxpbmcuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gd2FybiBhbmQgc2tpcCBpZiB0aGUgcGx1Z2luIGlzIGFjdGl2ZS4KCSAqCgkgKiBbLS1za2lwLWRlbGV0ZV0KCSAqIDogSWYgc2V0LCB0aGUgcGx1Z2luIGZpbGVzIHdpbGwgbm90IGJlIGRlbGV0ZWQuIE9ubHkgdGhlIHVuaW5zdGFsbCBwcm9jZWR1cmUKCSAqIHdpbGwgYmUgcnVuLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBhbGwgcGx1Z2lucyB3aWxsIGJlIHVuaW5zdGFsbGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcGx1Z2luIHVuaW5zdGFsbCBoZWxsbwoJICogICAgIFVuaW5zdGFsbGVkIGFuZCBkZWxldGVkICdoZWxsbycgcGx1Z2luLgoJICogICAgIFN1Y2Nlc3M6IFVuaW5zdGFsbGVkIDEgb2YgMSBwbHVnaW5zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoKCQkkYWxsID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCgkJLy8gQ2hlY2sgaWYgcGx1Z2luIG5hbWVzIG9yIC0tYWxsIGlzIHBhc3NlZC4KCQkkYXJncyA9ICR0aGlzLT5jaGVja19vcHRpb25hbF9hcmdzX2FuZF9hbGwoICRhcmdzLCAkYWxsLCAndW5pbnN0YWxsJyApOwoJCWlmICggISAkYXJncyApIHsKCQkJcmV0dXJuOwoJCX0KCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJJHBsdWdpbnMgICA9ICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKTsKCQlpZiAoIGNvdW50KCAkcGx1Z2lucyApIDwgY291bnQoICRhcmdzICkgKSB7CgkJCSRlcnJvcnMgPSBjb3VudCggJGFyZ3MgKSAtIGNvdW50KCAkcGx1Z2lucyApOwoJCX0KCgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW4gKSB7CgkJCWlmICggaXNfcGx1Z2luX2FjdGl2ZSggJHBsdWdpbi0+ZmlsZSApICYmICEgV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RlYWN0aXZhdGUnICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ3skcGx1Z2luLT5uYW1lfScgcGx1Z2luIGlzIGFjdGl2ZS4iICk7CgkJCQkkZXJyb3JzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkZWFjdGl2YXRlJyApICkgewoJCQkJV1BfQ0xJOjpsb2coICJEZWFjdGl2YXRpbmcgJ3skcGx1Z2luLT5uYW1lfScuLi4iICk7CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gdHJ1ZTsKCQkJCSR0aGlzLT5kZWFjdGl2YXRlKCBhcnJheSggJHBsdWdpbi0+bmFtZSApICk7CgkJCQkkdGhpcy0+Y2hhaW5lZF9jb21tYW5kID0gZmFsc2U7CgkJCX0KCgkJCXVuaW5zdGFsbF9wbHVnaW4oICRwbHVnaW4tPmZpbGUgKTsKCgkJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWRlbGV0ZScgKSAmJiAkdGhpcy0+ZGVsZXRlX3BsdWdpbiggJHBsdWdpbiApICkgewoJCQkJV1BfQ0xJOjpsb2coICJVbmluc3RhbGxlZCBhbmQgZGVsZXRlZCAnJHBsdWdpbi0+bmFtZScgcGx1Z2luLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiUmFuIHVuaW5zdGFsbCBwcm9jZWR1cmUgZm9yICckcGx1Z2luLT5uYW1lJyBwbHVnaW4gd2l0aG91dCBkZWxldGluZy4iICk7CgkJCX0KCQkJJHN1Y2Nlc3NlcysrOwoJCX0KCQlpZiAoICEgJHRoaXMtPmNoYWluZWRfY29tbWFuZCApIHsKCQkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAncGx1Z2luJywgJ3VuaW5zdGFsbCcsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7CgkJfQoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgZ2l2ZW4gcGx1Z2luIGlzIGluc3RhbGxlZC4KCSAqCgkgKiBSZXR1cm5zIGV4aXQgY29kZSAwIHdoZW4gaW5zdGFsbGVkLCAxIHdoZW4gdW5pbnN0YWxsZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwbHVnaW4+CgkgKiA6IFRoZSBwbHVnaW4gdG8gY2hlY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIHBsdWdpbiBpcyBpbnN0YWxsZWQ7IGV4aXQgc3RhdHVzIDAgaWYgaW5zdGFsbGVkLCBvdGhlcndpc2UgMQoJICogICAgICQgd3AgcGx1Z2luIGlzLWluc3RhbGxlZCBoZWxsbwoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1pbnN0YWxsZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2luc3RhbGxlZCggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQlpZiAoICR0aGlzLT5mZXRjaGVyLT5nZXQoICRhcmdzWzBdICkgKSB7CgkJCVdQX0NMSTo6aGFsdCggMCApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyBpZiBhIGdpdmVuIHBsdWdpbiBpcyBhY3RpdmUuCgkgKgoJICogUmV0dXJucyBleGl0IGNvZGUgMCB3aGVuIGFjdGl2ZSwgMSB3aGVuIG5vdCBhY3RpdmUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwbHVnaW4+CgkgKiA6IFRoZSBwbHVnaW4gdG8gY2hlY2suCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogSWYgc2V0LCBjaGVjayBpZiBwbHVnaW4gaXMgbmV0d29yay1hY3RpdmF0ZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIHBsdWdpbiBpcyBBY3RpdmU7IGV4aXQgc3RhdHVzIDAgaWYgYWN0aXZlLCBvdGhlcndpc2UgMQoJICogICAgICQgd3AgcGx1Z2luIGlzLWFjdGl2ZSBoZWxsbwoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1hY3RpdmUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2FjdGl2ZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkbmV0d29ya193aWRlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKTsKCgkJJHBsdWdpbiA9ICR0aGlzLT5mZXRjaGVyLT5nZXQoICRhcmdzWzBdICk7CgoJCWlmICggISAkcGx1Z2luICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9CgoJCSR0aGlzLT5jaGVja19hY3RpdmUoICRwbHVnaW4tPmZpbGUsICRuZXR3b3JrX3dpZGUgKSA/IFdQX0NMSTo6aGFsdCggMCApIDogV1BfQ0xJOjpoYWx0KCAxICk7Cgl9CgoJLyoqCgkgKiBEZWxldGVzIHBsdWdpbiBmaWxlcyB3aXRob3V0IGRlYWN0aXZhdGluZyBvciB1bmluc3RhbGxpbmcuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byBkZWxldGUuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgZGVsZXRlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlbGV0ZSBwbHVnaW4KCSAqICAgICAkIHdwIHBsdWdpbiBkZWxldGUgaGVsbG8KCSAqICAgICBEZWxldGVkICdoZWxsbycgcGx1Z2luLgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHBsdWdpbnMuCgkgKgoJICogICAgICMgRGVsZXRlIGluYWN0aXZlIHBsdWdpbnMKCSAqICAgICAkIHdwIHBsdWdpbiBkZWxldGUgJCh3cCBwbHVnaW4gbGlzdCAtLXN0YXR1cz1pbmFjdGl2ZSAtLWZpZWxkPW5hbWUpCgkgKiAgICAgRGVsZXRlZCAndGlueW1jZS10ZW1wbGF0ZXMnIHBsdWdpbi4KCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDEgb2YgMSBwbHVnaW5zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSRhbGwgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQkvLyBDaGVjayBpZiBwbHVnaW4gbmFtZXMgb3IgLS1hbGwgaXMgcGFzc2VkLgoJCSRhcmdzID0gJHRoaXMtPmNoZWNrX29wdGlvbmFsX2FyZ3NfYW5kX2FsbCggJGFyZ3MsICRhbGwsICdkZWxldGUnICk7CgkJaWYgKCAhICRhcmdzICkgewoJCQlyZXR1cm47CgkJfQoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCgkJZm9yZWFjaCAoICR0aGlzLT5mZXRjaGVyLT5nZXRfbWFueSggJGFyZ3MgKSBhcyAkcGx1Z2luICkgewoJCQlpZiAoICR0aGlzLT5kZWxldGVfcGx1Z2luKCAkcGx1Z2luICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIkRlbGV0ZWQgJ3skcGx1Z2luLT5uYW1lfScgcGx1Z2luLiIgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfSBlbHNlIHsKCQkJCSRlcnJvcnMrKzsKCQkJfQoJCX0KCQlpZiAoICEgJHRoaXMtPmNoYWluZWRfY29tbWFuZCApIHsKCQkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAncGx1Z2luJywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7CgkJfQoJfQoKCS8qKgoJICogR2V0cyBhIGxpc3Qgb2YgcGx1Z2lucy4KCSAqCgkgKiBEaXNwbGF5cyBhIGxpc3Qgb2YgdGhlIHBsdWdpbnMgaW5zdGFsbGVkIG9uIHRoZSBzaXRlIHdpdGggYWN0aXZhdGlvbgoJICogc3RhdHVzLCB3aGV0aGVyIG9yIG5vdCB0aGVyZSdzIGFuIHVwZGF0ZSBhdmFpbGFibGUsIGV0Yy4KCSAqCgkgKiBVc2UgYC0tc3RhdHVzPWRyb3BpbmAgdG8gbGlzdCBpbnN0YWxsZWQgZHJvcGlucyAoZS5nLiBgb2JqZWN0LWNhY2hlLnBocGApLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEZpbHRlciByZXN1bHRzIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBhIGZpZWxkLgoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IFByaW50cyB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQgZm9yIGVhY2ggcGx1Z2luLgoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGNvdW50CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqIFstLXN0YXR1cz08c3RhdHVzPl0KCSAqIDogRmlsdGVyIHRoZSBvdXRwdXQgYnkgcGx1Z2luIHN0YXR1cy4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBhY3RpdmUKCSAqICAgLSBhY3RpdmUtbmV0d29yawoJICogICAtIGRyb3BpbgoJICogICAtIGluYWN0aXZlCgkgKiAgIC0gbXVzdC11c2UKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBwbHVnaW46CgkgKgoJICogKiBuYW1lCgkgKiAqIHN0YXR1cwoJICogKiB1cGRhdGUKCSAqICogdmVyc2lvbgoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiB1cGRhdGVfdmVyc2lvbgoJICogKiB1cGRhdGVfcGFja2FnZQoJICogKiB1cGRhdGVfaWQKCSAqICogdGl0bGUKCSAqICogZGVzY3JpcHRpb24KCSAqICogZmlsZQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhY3RpdmUgcGx1Z2lucyBvbiB0aGUgc2l0ZS4KCSAqICAgICAkIHdwIHBsdWdpbiBsaXN0IC0tc3RhdHVzPWFjdGl2ZSAtLWZvcm1hdD1qc29uCgkgKiAgICAgW3sibmFtZSI6ImR5bmFtaWMtaG9zdG5hbWUiLCJzdGF0dXMiOiJhY3RpdmUiLCJ1cGRhdGUiOiJub25lIiwidmVyc2lvbiI6IjAuNC4yIn0seyJuYW1lIjoidGlueW1jZS10ZW1wbGF0ZXMiLCJzdGF0dXMiOiJhY3RpdmUiLCJ1cGRhdGUiOiJub25lIiwidmVyc2lvbiI6IjQuNC4zIn0seyJuYW1lIjoid3AtbXVsdGlieXRlLXBhdGNoIiwic3RhdHVzIjoiYWN0aXZlIiwidXBkYXRlIjoibm9uZSIsInZlcnNpb24iOiIyLjQifSx7Im5hbWUiOiJ3cC10b3RhbC1oYWNrcyIsInN0YXR1cyI6ImFjdGl2ZSIsInVwZGF0ZSI6Im5vbmUiLCJ2ZXJzaW9uIjoiMi4wLjEifV0KCSAqCgkgKiAgICAgIyBMaXN0IHBsdWdpbnMgb24gZWFjaCBzaXRlIGluIGEgbmV0d29yay4KCSAqICAgICAkIHdwIHNpdGUgbGlzdCAtLWZpZWxkPXVybCB8IHhhcmdzIC1JICUgd3AgcGx1Z2luIGxpc3QgLS11cmw9JQoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgIHwgc3RhdHVzICAgICAgICAgfCB1cGRhdGUgfCB2ZXJzaW9uIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYWtpc21ldCB8IGFjdGl2ZS1uZXR3b3JrIHwgbm9uZSAgIHwgMy4xLjExICB8CgkgKiAgICAgfCBoZWxsbyAgIHwgaW5hY3RpdmUgICAgICAgfCBub25lICAgfCAxLjYgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgICstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgIHwgc3RhdHVzICAgICAgICAgfCB1cGRhdGUgfCB2ZXJzaW9uIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICogICAgIHwgYWtpc21ldCB8IGFjdGl2ZS1uZXR3b3JrIHwgbm9uZSAgIHwgMy4xLjExICB8CgkgKiAgICAgfCBoZWxsbyAgIHwgaW5hY3RpdmUgICAgICAgfCBub25lICAgfCAxLjYgICAgIHwKCSAqICAgICArLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tKwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJcGFyZW50OjpfbGlzdCggJF8sICRhc3NvY19hcmdzICk7Cgl9CgoJLyogUFJJVkFURVMgKi8KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2FjdGl2ZSggJGZpbGUsICRuZXR3b3JrX3dpZGUgKSB7CgkJJHJlcXVpcmVkID0gJG5ldHdvcmtfd2lkZSA/ICdhY3RpdmUtbmV0d29yaycgOiAnYWN0aXZlJzsKCgkJcmV0dXJuICRyZXF1aXJlZCA9PT0gJHRoaXMtPmdldF9zdGF0dXMoICRmaWxlICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhY3RpdmVfb3V0cHV0KCAkbmFtZSwgJGZpbGUsICRuZXR3b3JrX3dpZGUsICRhY3Rpb24gKSB7CgkJJG5ldHdvcmtfd2lkZSA9ICRuZXR3b3JrX3dpZGUgfHwgKCBpc19tdWx0aXNpdGUoKSAmJiBpc19uZXR3b3JrX29ubHlfcGx1Z2luKCAkZmlsZSApICk7CgoJCSRjaGVjayA9ICR0aGlzLT5jaGVja19hY3RpdmUoICRmaWxlLCAkbmV0d29ya193aWRlICk7CgoJCWlmICggKCAnYWN0aXZhdGUnID09PSAkYWN0aW9uICkgPyAkY2hlY2sgOiAhICRjaGVjayApIHsKCQkJaWYgKCAkbmV0d29ya193aWRlICkgewoJCQkJV1BfQ0xJOjpsb2coICJQbHVnaW4gJ3skbmFtZX0nIG5ldHdvcmsgeyRhY3Rpb259ZC4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmxvZyggIlBsdWdpbiAneyRuYW1lfScgeyRhY3Rpb259ZC4iICk7CgkJCX0KCQl9IGVsc2UgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJDb3VsZCBub3QgeyRhY3Rpb259IHRoZSAneyRuYW1lfScgcGx1Z2luLiIgKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9zdGF0dXMoICRmaWxlICkgewoJCWlmICggaXNfcGx1Z2luX2FjdGl2ZV9mb3JfbmV0d29yayggJGZpbGUgKSApIHsKCQkJcmV0dXJuICdhY3RpdmUtbmV0d29yayc7CgkJfQoKCQlpZiAoIGlzX3BsdWdpbl9hY3RpdmUoICRmaWxlICkgKSB7CgkJCXJldHVybiAnYWN0aXZlJzsKCQl9CgoJCXJldHVybiAnaW5hY3RpdmUnOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgdGVtcGxhdGUgcGF0aCBiYXNlZCBvbiBpbnN0YWxsYXRpb24gdHlwZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3RlbXBsYXRlX3BhdGgoICR0ZW1wbGF0ZSApIHsKCQkkY29tbWFuZF9yb290ICA9IFV0aWxzXHBoYXJfc2FmZV9wYXRoKCBkaXJuYW1lKCBfX0RJUl9fICkgKTsKCQkkdGVtcGxhdGVfcGF0aCA9ICJ7JGNvbW1hbmRfcm9vdH0vdGVtcGxhdGVzL3skdGVtcGxhdGV9IjsKCgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkdGVtcGxhdGVfcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZmluZCB7JHRlbXBsYXRlfSIgKTsKCQl9CgoJCXJldHVybiAkdGVtcGxhdGVfcGF0aDsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGRldGFpbHMgb2YgYSBwbHVnaW4uCgkgKgoJICogQHBhcmFtIG9iamVjdAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9kZXRhaWxzKCAkZmlsZSApIHsKCQkkcGx1Z2luX2ZvbGRlciA9IGdldF9wbHVnaW5zKCAnLycgLiBwbHVnaW5fYmFzZW5hbWUoIGRpcm5hbWUoICRmaWxlICkgKSApOwoJCSRwbHVnaW5fZmlsZSAgID0gVXRpbHNcYmFzZW5hbWUoICRmaWxlICk7CgoJCXJldHVybiAkcGx1Z2luX2ZvbGRlclsgJHBsdWdpbl9maWxlIF07Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBkZWxldGVfcGx1Z2luKCAkcGx1Z2luICkgewoJCSRwbHVnaW5fZGlyID0gZGlybmFtZSggJHBsdWdpbi0+ZmlsZSApOwoJCWlmICggJy4nID09PSAkcGx1Z2luX2RpciApIHsKCQkJJHBsdWdpbl9kaXIgPSAkcGx1Z2luLT5maWxlOwoJCX0KCgkJJHBhdGggPSBwYXRoX2pvaW4oIFdQX1BMVUdJTl9ESVIsICRwbHVnaW5fZGlyICk7CgoJCWlmICggVXRpbHNcaXNfd2luZG93cygpICkgewoJCQkvLyBIYW5kbGVzIHBsdWdpbnMgdGhhdCBhcmUgbm90IGluIG93biBmb2xkZXJzCgkJCS8vIGUuZy4gSGVsbG8gRG9sbHkgLT4gcGx1Z2lucy9oZWxsby5waHAKCQkJaWYgKCBpc19maWxlKCAkcGF0aCApICkgewoJCQkJJGNvbW1hbmQgPSAnZGVsIC9mIC9xICc7CgkJCX0gZWxzZSB7CgkJCQkkY29tbWFuZCA9ICdyZCAvcyAvcSAnOwoJCQl9CgkJCSRwYXRoID0gc3RyX3JlcGxhY2UoICcvJywgJ1xcJywgJHBhdGggKTsKCQl9IGVsc2UgewoJCQkkY29tbWFuZCA9ICdybSAtcmYgJzsKCQl9CgoJCXJldHVybiAhIFdQX0NMSTo6bGF1bmNoKCAkY29tbWFuZCAuIGVzY2FwZXNoZWxsYXJnKCAkcGF0aCApICk7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9pbXBvcnRfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfaW1wb3J0X2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfaW1wb3J0X2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdpbXBvcnQnLCAnSW1wb3J0X0NvbW1hbmQnICk7Cjw/cGhwCgpjbGFzcyBJbXBvcnRfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwdWJsaWMgJHByb2Nlc3NlZF9wb3N0cyA9IGFycmF5KCk7CgoJLyoqCgkgKiBJbXBvcnRzIGNvbnRlbnQgZnJvbSBhIGdpdmVuIFdYUiBmaWxlLgoJICoKCSAqIFByb3ZpZGVzIGEgY29tbWFuZCBsaW5lIGludGVyZmFjZSB0byB0aGUgV29yZFByZXNzIEltcG9ydGVyIHBsdWdpbiwgZm9yCgkgKiBwZXJmb3JtaW5nIGRhdGEgbWlncmF0aW9ucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGZpbGU+Li4uCgkgKiA6IFBhdGggdG8gb25lIG9yIG1vcmUgdmFsaWQgV1hSIGZpbGVzIGZvciBpbXBvcnRpbmcuIERpcmVjdG9yaWVzIGFyZSBhbHNvIGFjY2VwdGVkLgoJICoKCSAqIC0tYXV0aG9ycz08YXV0aG9ycz4KCSAqIDogSG93IHRoZSBhdXRob3IgbWFwcGluZyBzaG91bGQgYmUgaGFuZGxlZC4gT3B0aW9ucyBhcmUgJ2NyZWF0ZScsICdtYXBwaW5nLmNzdicsIG9yICdza2lwJy4gVGhlIGZpcnN0IHdpbGwgY3JlYXRlIGFueSBub24tZXhpc3RlbnQgdXNlcnMgZnJvbSB0aGUgV1hSIGZpbGUuIFRoZSBzZWNvbmQgd2lsbCByZWFkIGF1dGhvciBtYXBwaW5nIGFzc29jaWF0aW9ucyBmcm9tIGEgQ1NWLCBvciBjcmVhdGUgYSBDU1YgZm9yIGVkaXRpbmcgaWYgdGhlIGZpbGUgcGF0aCBkb2Vzbid0IGV4aXN0LiBUaGUgQ1NWIHJlcXVpcmVzIHR3byBjb2x1bW5zLCBhbmQgYSBoZWFkZXIgcm93IGxpa2UgIm9sZF91c2VyX2xvZ2luLG5ld191c2VyX2xvZ2luIi4gVGhlIGxhc3Qgb3B0aW9uIHdpbGwgc2tpcCBhbnkgYXV0aG9yIG1hcHBpbmcuCgkgKgoJICogWy0tc2tpcD08ZGF0YS10eXBlPl0KCSAqIDogU2tpcCBpbXBvcnRpbmcgc3BlY2lmaWMgZGF0YS4gU3VwcG9ydGVkIG9wdGlvbnMgYXJlOiAnYXR0YWNobWVudCcgYW5kICdpbWFnZV9yZXNpemUnIChza2lwIHRpbWUtY29uc3VtaW5nIHRodW1ibmFpbCBnZW5lcmF0aW9uKS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEltcG9ydCBjb250ZW50IGZyb20gYSBXWFIgZmlsZQoJICogICAgICQgd3AgaW1wb3J0IGV4YW1wbGUud29yZHByZXNzLjIwMTYtMDYtMjEueG1sIC0tYXV0aG9ycz1jcmVhdGUKCSAqICAgICBTdGFydGluZyB0aGUgaW1wb3J0IHByb2Nlc3MuLi4KCSAqICAgICBQcm9jZXNzaW5nIHBvc3QgIzEgKCJIZWxsbyB3b3JsZCEiKSAocG9zdF90eXBlOiBwb3N0KQoJICogICAgIC0tIDEgb2YgMQoJICogICAgIC0tIFR1ZSwgMjEgSnVuIDIwMTYgMDU6MzE6MTIgKzAwMDAKCSAqICAgICAtLSBJbXBvcnRlZCBwb3N0IGFzIHBvc3RfaWQgIzEKCSAqICAgICBTdWNjZXNzOiBGaW5pc2hlZCBpbXBvcnRpbmcgZnJvbSAnZXhhbXBsZS53b3JkcHJlc3MuMjAxNi0wNi0yMS54bWwnIGZpbGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRkZWZhdWx0cyAgID0gYXJyYXkoCgkJCSdhdXRob3JzJyA9PiBudWxsLAoJCQknc2tpcCcgICAgPT4gYXJyYXkoKSwKCQkpOwoJCSRhc3NvY19hcmdzID0gd3BfcGFyc2VfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQlpZiAoICEgaXNfYXJyYXkoICRhc3NvY19hcmdzWydza2lwJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ3NraXAnXSA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ3NraXAnXSApOwoJCX0KCgkJJGltcG9ydGVyID0gJHRoaXMtPmlzX2ltcG9ydGVyX2F2YWlsYWJsZSgpOwoJCWlmICggaXNfd3BfZXJyb3IoICRpbXBvcnRlciApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkaW1wb3J0ZXIgKTsKCQl9CgoJCSR0aGlzLT5hZGRfd3hyX2ZpbHRlcnMoKTsKCgkJV1BfQ0xJOjpsb2coICdTdGFydGluZyB0aGUgaW1wb3J0IHByb2Nlc3MuLi4nICk7CgoJCSRuZXdfYXJncyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRhcmcgKSB7CgkJCWlmICggaXNfZGlyKCAkYXJnICkgKSB7CgkJCQkkZGlyICAgPSBXUF9DTElcVXRpbHNcdHJhaWxpbmdzbGFzaGl0KCAkYXJnICk7CgkJCQkkZmlsZXMgPSBnbG9iKCAkZGlyIC4gJyoud3hyJyApOwoJCQkJaWYgKCAhIGVtcHR5KCAkZmlsZXMgKSApIHsKCQkJCQkkbmV3X2FyZ3MgPSBhcnJheV9tZXJnZSggJG5ld19hcmdzLCAkZmlsZXMgKTsKCQkJCX0KCgkJCQkkZmlsZXMgPSBnbG9iKCAkZGlyIC4gJyoueG1sJyApOwoJCQkJaWYgKCAhIGVtcHR5KCAkZmlsZXMgKSApIHsKCQkJCQkkbmV3X2FyZ3MgPSBhcnJheV9tZXJnZSggJG5ld19hcmdzLCAkZmlsZXMgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICggZmlsZV9leGlzdHMoICRhcmcgKSApIHsKCQkJCQkkbmV3X2FyZ3NbXSA9ICRhcmc7CgkJCQl9CgkJCX0KCQl9CgkJJGFyZ3MgPSAkbmV3X2FyZ3M7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkZmlsZSApIHsKCQkJaWYgKCAhIGlzX3JlYWRhYmxlKCAkZmlsZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ2FuJ3QgcmVhZCAnJGZpbGUnIGZpbGUuIiApOwoJCQl9CgoJCQkkcmV0ID0gJHRoaXMtPmltcG9ydF93eHIoICRmaWxlLCAkYXNzb2NfYXJncyApOwoKCQkJaWYgKCBpc193cF9lcnJvciggJHJldCApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJHJldCApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICcnICk7IC8vIFdYUiBpbXBvcnQgZW5kcyB3aXRoIEhUTUwsIHNvIG1ha2Ugc3VyZSBtZXNzYWdlIGlzIG9uIG5leHQgbGluZQoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiRmluaXNoZWQgaW1wb3J0aW5nIGZyb20gJyRmaWxlJyBmaWxlLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEltcG9ydHMgYSBXWFIgZmlsZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpbXBvcnRfd3hyKCAkZmlsZSwgJGFyZ3MgKSB7CgoJCSR3cF9pbXBvcnQgICAgICAgICAgICAgICAgICA9IG5ldyBXUF9JbXBvcnQoKTsKCQkkd3BfaW1wb3J0LT5wcm9jZXNzZWRfcG9zdHMgPSAkdGhpcy0+cHJvY2Vzc2VkX3Bvc3RzOwoJCSRpbXBvcnRfZGF0YSAgICAgICAgICAgICAgICA9ICR3cF9pbXBvcnQtPnBhcnNlKCAkZmlsZSApOwoJCWlmICggaXNfd3BfZXJyb3IoICRpbXBvcnRfZGF0YSApICkgewoJCQlyZXR1cm4gJGltcG9ydF9kYXRhOwoJCX0KCgkJLy8gUHJlcGFyZSB0aGUgZGF0YSB0byBiZSB1c2VkIGluIHByb2Nlc3NfYXV0aG9yX21hcHBpbmcoKTsKCQkkd3BfaW1wb3J0LT5nZXRfYXV0aG9yc19mcm9tX2ltcG9ydCggJGltcG9ydF9kYXRhICk7CgoJCS8vIFdlIG5vIGxvbmdlciBuZWVkIHRoZSBvcmlnaW5hbCBkYXRhLCBzbyB1bnNldCB0byBhdm9pZCB1c2luZyBleGNlc3MKCQkvLyBtZW1vcnkuCgkJdW5zZXQoICRpbXBvcnRfZGF0YSApOwoKCQkkYXV0aG9yX2RhdGEgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkd3BfaW1wb3J0LT5hdXRob3JzIGFzICR3eHJfYXV0aG9yICkgewoJCQkkYXV0aG9yID0gbmV3IFxzdGRDbGFzcygpOwoJCQkvLyBBbHdheXMgaW4gdGhlIFdYUgoJCQkkYXV0aG9yLT51c2VyX2xvZ2luID0gJHd4cl9hdXRob3JbJ2F1dGhvcl9sb2dpbiddOwoKCQkJLy8gU2hvdWxkIGJlIGluIHRoZSBXWFI7IG5vIGd1YXJhbnRlZXMKCQkJaWYgKCBpc3NldCggJHd4cl9hdXRob3JbJ2F1dGhvcl9lbWFpbCddICkgKSB7CgkJCQkkYXV0aG9yLT51c2VyX2VtYWlsID0gJHd4cl9hdXRob3JbJ2F1dGhvcl9lbWFpbCddOwoJCQl9CgkJCWlmICggaXNzZXQoICR3eHJfYXV0aG9yWydhdXRob3JfZGlzcGxheV9uYW1lJ10gKSApIHsKCQkJCSRhdXRob3ItPmRpc3BsYXlfbmFtZSA9ICR3eHJfYXV0aG9yWydhdXRob3JfZGlzcGxheV9uYW1lJ107CgkJCX0KCQkJaWYgKCBpc3NldCggJHd4cl9hdXRob3JbJ2F1dGhvcl9maXJzdF9uYW1lJ10gKSApIHsKCQkJCSRhdXRob3ItPmZpcnN0X25hbWUgPSAkd3hyX2F1dGhvclsnYXV0aG9yX2ZpcnN0X25hbWUnXTsKCQkJfQoJCQlpZiAoIGlzc2V0KCAkd3hyX2F1dGhvclsnYXV0aG9yX2xhc3RfbmFtZSddICkgKSB7CgkJCQkkYXV0aG9yLT5sYXN0X25hbWUgPSAkd3hyX2F1dGhvclsnYXV0aG9yX2xhc3RfbmFtZSddOwoJCQl9CgoJCQkkYXV0aG9yX2RhdGFbXSA9ICRhdXRob3I7CgkJfQoKCQkvLyBCdWlsZCB0aGUgYXV0aG9yIG1hcHBpbmcKCQkkYXV0aG9yX21hcHBpbmcgPSAkdGhpcy0+cHJvY2Vzc19hdXRob3JfbWFwcGluZyggJGFyZ3NbJ2F1dGhvcnMnXSwgJGF1dGhvcl9kYXRhICk7CgkJaWYgKCBpc193cF9lcnJvciggJGF1dGhvcl9tYXBwaW5nICkgKSB7CgkJCXJldHVybiAkYXV0aG9yX21hcHBpbmc7CgkJfQoKCQkkYXV0aG9yX2luICA9IHdwX2xpc3RfcGx1Y2soICRhdXRob3JfbWFwcGluZywgJ29sZF91c2VyX2xvZ2luJyApOwoJCSRhdXRob3Jfb3V0ID0gd3BfbGlzdF9wbHVjayggJGF1dGhvcl9tYXBwaW5nLCAnbmV3X3VzZXJfbG9naW4nICk7CgkJdW5zZXQoICRhdXRob3JfbWFwcGluZywgJGF1dGhvcl9kYXRhICk7CgoJCS8vICR1c2VyX3NlbGVjdCBuZWVkcyB0byBiZSBhbiBhcnJheSBvZiB1c2VyIElEcwoJCSR1c2VyX3NlbGVjdCAgICAgICAgID0gYXJyYXkoKTsKCQkkaW52YWxpZF91c2VyX3NlbGVjdCA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRhdXRob3Jfb3V0IGFzICRhdXRob3JfbG9naW4gKSB7CgkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRhdXRob3JfbG9naW4gKTsKCQkJaWYgKCAkdXNlciApIHsKCQkJCSR1c2VyX3NlbGVjdFtdID0gJHVzZXItPklEOwoJCQl9IGVsc2UgewoJCQkJJGludmFsaWRfdXNlcl9zZWxlY3RbXSA9ICRhdXRob3JfbG9naW47CgkJCX0KCQl9CgkJaWYgKCAhIGVtcHR5KCAkaW52YWxpZF91c2VyX3NlbGVjdCApICkgewoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnaW52YWxpZC1hdXRob3ItbWFwcGluZycsIHNwcmludGYoICdUaGVzZSB1c2VyX2xvZ2lucyBhcmUgaW52YWxpZDogJXMnLCBpbXBsb2RlKCAnLCcsICRpbnZhbGlkX3VzZXJfc2VsZWN0ICkgKSApOwoJCX0KCgkJdW5zZXQoICRhdXRob3Jfb3V0ICk7CgoJCS8vIERyaXZlIHRoZSBpbXBvcnQKCQkkd3BfaW1wb3J0LT5mZXRjaF9hdHRhY2htZW50cyA9ICEgaW5fYXJyYXkoICdhdHRhY2htZW50JywgJGFyZ3NbJ3NraXAnXSwgdHJ1ZSApOwoKCQkkX0dFVCAgPSBhcnJheSgKCQkJJ2ltcG9ydCcgPT4gJ3dvcmRwcmVzcycsCgkJCSdzdGVwJyAgID0+IDIsCgkJKTsKCQkkX1BPU1QgPSBhcnJheSgKCQkJJ2ltcG9ydGVkX2F1dGhvcnMnICA9PiAkYXV0aG9yX2luLAoJCQkndXNlcl9tYXAnICAgICAgICAgID0+ICR1c2VyX3NlbGVjdCwKCQkJJ2ZldGNoX2F0dGFjaG1lbnRzJyA9PiAkd3BfaW1wb3J0LT5mZXRjaF9hdHRhY2htZW50cywKCQkpOwoKCQlpZiAoIGluX2FycmF5KCAnaW1hZ2VfcmVzaXplJywgJGFyZ3NbJ3NraXAnXSwgdHJ1ZSApICkgewoJCQlhZGRfZmlsdGVyKCAnaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzX2FkdmFuY2VkJywgYXJyYXkoICR0aGlzLCAnZmlsdGVyX3NldF9pbWFnZV9zaXplcycgKSApOwoJCX0KCgkJJEdMT0JBTFNbJ3dwY2xpX2ltcG9ydF9jdXJyZW50X2ZpbGUnXSA9IGJhc2VuYW1lKCAkZmlsZSApOwoJCSR3cF9pbXBvcnQtPmltcG9ydCggJGZpbGUgKTsKCQkkdGhpcy0+cHJvY2Vzc2VkX3Bvc3RzICs9ICR3cF9pbXBvcnQtPnByb2Nlc3NlZF9wb3N0czsKCgkJcmV0dXJuIHRydWU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGZpbHRlcl9zZXRfaW1hZ2Vfc2l6ZXMoICRzaXplcyApIHsKCQkvLyBSZXR1cm4gbnVsbCBoZXJlIHRvIHByZXZlbnQgdGhlIGNvcmUgaW1hZ2UgcmVzaXppbmcgbG9naWMgZnJvbSBydW5uaW5nLgoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogRGVmaW5lcyB1c2VmdWwgdmVyYm9zaXR5IGZpbHRlcnMgZm9yIHRoZSBXWFIgaW1wb3J0ZXIuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYWRkX3d4cl9maWx0ZXJzKCkgewoKCQlhZGRfZmlsdGVyKAoJCQknd3BfaW1wb3J0X3Bvc3RzJywKCQkJZnVuY3Rpb24oICRwb3N0cyApIHsKCQkJCWdsb2JhbCAkd3BjbGlfaW1wb3J0X2NvdW50czsKCQkJCSR3cGNsaV9pbXBvcnRfY291bnRzWydjdXJyZW50X3Bvc3QnXSA9IDA7CgkJCQkkd3BjbGlfaW1wb3J0X2NvdW50c1sndG90YWxfcG9zdHMnXSAgPSBjb3VudCggJHBvc3RzICk7CgkJCQlyZXR1cm4gJHBvc3RzOwoJCQl9LAoJCQkxMAoJCSk7CgoJCWFkZF9maWx0ZXIoCgkJCSd3cF9pbXBvcnRfcG9zdF9jb21tZW50cycsCgkJCWZ1bmN0aW9uKCAkY29tbWVudHMsICRwb3N0X2lkLCAkcG9zdCApIHsKCQkJCWdsb2JhbCAkd3BjbGlfaW1wb3J0X2NvdW50czsKCQkJCSR3cGNsaV9pbXBvcnRfY291bnRzWydjdXJyZW50X2NvbW1lbnQnXSA9IDA7CgkJCQkkd3BjbGlfaW1wb3J0X2NvdW50c1sndG90YWxfY29tbWVudHMnXSAgPSBjb3VudCggJGNvbW1lbnRzICk7CgkJCQlyZXR1cm4gJGNvbW1lbnRzOwoJCQl9LAoJCQkxMCwKCQkJMwoJCSk7CgoJCWFkZF9maWx0ZXIoCgkJCSd3cF9pbXBvcnRfcG9zdF9kYXRhX3JhdycsCgkJCWZ1bmN0aW9uKCAkcG9zdCApIHsKCQkJCWdsb2JhbCAkd3BjbGlfaW1wb3J0X2NvdW50cywgJHdwY2xpX2ltcG9ydF9jdXJyZW50X2ZpbGU7CgoJCQkJJHdwY2xpX2ltcG9ydF9jb3VudHNbJ2N1cnJlbnRfcG9zdCddKys7CgkJCQlXUF9DTEk6OmxvZyggJycgKTsKCQkJCVdQX0NMSTo6bG9nKCAnJyApOwoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdQcm9jZXNzaW5nIHBvc3QgIyVkICgiJXMiKSAocG9zdF90eXBlOiAlcyknLCAkcG9zdFsncG9zdF9pZCddLCAkcG9zdFsncG9zdF90aXRsZSddLCAkcG9zdFsncG9zdF90eXBlJ10gKSApOwoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICctLSAlcyBvZiAlcyAoaW4gZmlsZSAlcyknLCBudW1iZXJfZm9ybWF0KCAkd3BjbGlfaW1wb3J0X2NvdW50c1snY3VycmVudF9wb3N0J10gKSwgbnVtYmVyX2Zvcm1hdCggJHdwY2xpX2ltcG9ydF9jb3VudHNbJ3RvdGFsX3Bvc3RzJ10gKSwgJHdwY2xpX2ltcG9ydF9jdXJyZW50X2ZpbGUgKSApOwoJCQkJV1BfQ0xJOjpsb2coICctLSAnIC4gZGF0ZSggJ3InICkgKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoKCQkJCXJldHVybiAkcG9zdDsKCQkJfQoJCSk7CgoJCWFkZF9hY3Rpb24oCgkJCSd3cF9pbXBvcnRfaW5zZXJ0X3Bvc3QnLAoJCQlmdW5jdGlvbiggJHBvc3RfaWQsICRvcmlnaW5hbF9wb3N0X2lkLCAkcG9zdCwgJHBvc3RkYXRhICkgewoJCQkJZ2xvYmFsICR3cGNsaV9pbXBvcnRfY291bnRzOwoJCQkJaWYgKCBpc193cF9lcnJvciggJHBvc3RfaWQgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICctLSBFcnJvciBpbXBvcnRpbmcgcG9zdDogJyAuICRwb3N0X2lkLT5nZXRfZXJyb3JfY29kZSgpICk7CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6bG9nKCAiLS0gSW1wb3J0ZWQgcG9zdCBhcyBwb3N0X2lkICN7JHBvc3RfaWR9IiApOwoJCQkJfQoKCQkJCWlmICggMCA9PT0gKCAkd3BjbGlfaW1wb3J0X2NvdW50c1snY3VycmVudF9wb3N0J10gJSA1MDAgKSApIHsKCQkJCQlXUF9DTElcVXRpbHNcd3BfY2xlYXJfb2JqZWN0X2NhY2hlKCk7CgkJCQkJV1BfQ0xJOjpsb2coICctLSBDbGVhcmVkIG9iamVjdCBjYWNoZS4nICk7CgkJCQl9CgoJCQl9LAoJCQkxMCwKCQkJNAoJCSk7CgoJCWFkZF9hY3Rpb24oCgkJCSd3cF9pbXBvcnRfaW5zZXJ0X3Rlcm0nLAoJCQlmdW5jdGlvbiggJHQsICRpbXBvcnRfdGVybSwgJHBvc3RfaWQsICRwb3N0ICkgewoJCQkJV1BfQ0xJOjpsb2coICItLSBDcmVhdGVkIHRlcm0gXCJ7JGltcG9ydF90ZXJtWyduYW1lJ119XCIiICk7CgkJCX0sCgkJCTEwLAoJCQk0CgkJKTsKCgkJYWRkX2FjdGlvbigKCQkJJ3dwX2ltcG9ydF9zZXRfcG9zdF90ZXJtcycsCgkJCWZ1bmN0aW9uKCAkdHRfaWRzLCAkdGVybV9pZHMsICR0YXhvbm9teSwgJHBvc3RfaWQsICRwb3N0ICkgewoJCQkJV1BfQ0xJOjpsb2coICctLSBBZGRlZCB0ZXJtcyAoJyAuIGltcGxvZGUoICcsJywgJHRlcm1faWRzICkgLiAiKSBmb3IgdGF4b25vbXkgXCJ7JHRheG9ub215fVwiIiApOwoJCQl9LAoJCQkxMCwKCQkJNQoJCSk7CgoJCWFkZF9hY3Rpb24oCgkJCSd3cF9pbXBvcnRfaW5zZXJ0X2NvbW1lbnQnLAoJCQlmdW5jdGlvbiggJGNvbW1lbnRfaWQsICRjb21tZW50LCAkY29tbWVudF9wb3N0X2lkLCAkcG9zdCApIHsKCQkJCWdsb2JhbCAkd3BjbGlfaW1wb3J0X2NvdW50czsKCQkJCSR3cGNsaV9pbXBvcnRfY291bnRzWydjdXJyZW50X2NvbW1lbnQnXSsrOwoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICctLSBBZGRlZCBjb21tZW50ICMlZCAoJXMgb2YgJXMpJywgJGNvbW1lbnRfaWQsIG51bWJlcl9mb3JtYXQoICR3cGNsaV9pbXBvcnRfY291bnRzWydjdXJyZW50X2NvbW1lbnQnXSApLCBudW1iZXJfZm9ybWF0KCAkd3BjbGlfaW1wb3J0X2NvdW50c1sndG90YWxfY29tbWVudHMnXSApICkgKTsKCQkJfSwKCQkJMTAsCgkJCTQKCQkpOwoKCQlhZGRfYWN0aW9uKAoJCQknaW1wb3J0X3Bvc3RfbWV0YScsCgkJCWZ1bmN0aW9uKCAkcG9zdF9pZCwgJGtleSwgJHZhbHVlICkgewoJCQkJV1BfQ0xJOjpsb2coICItLSBBZGRlZCBwb3N0X21ldGEgJGtleSIgKTsKCQkJfSwKCQkJMTAsCgkJCTMKCQkpOwoKCX0KCgkvKioKCSAqIERldGVybWluZXMgd2hldGhlciB0aGUgcmVxdWVzdGVkIGltcG9ydGVyIGlzIGF2YWlsYWJsZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpc19pbXBvcnRlcl9hdmFpbGFibGUoKSB7CgkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvcGx1Z2luLnBocCc7CgoJCWlmICggY2xhc3NfZXhpc3RzKCAnV1BfSW1wb3J0JyApICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRwbHVnaW5zICAgICAgICAgICAgPSBnZXRfcGx1Z2lucygpOwoJCSR3b3JkcHJlc3NfaW1wb3J0ZXIgPSAnd29yZHByZXNzLWltcG9ydGVyL3dvcmRwcmVzcy1pbXBvcnRlci5waHAnOwoJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJHdvcmRwcmVzc19pbXBvcnRlciwgJHBsdWdpbnMgKSApIHsKCQkJJGVycm9yX21zZyA9ICJXb3JkUHJlc3MgSW1wb3J0ZXIgbmVlZHMgdG8gYmUgYWN0aXZhdGVkLiBUcnkgJ3dwIHBsdWdpbiBhY3RpdmF0ZSB3b3JkcHJlc3MtaW1wb3J0ZXInLiI7CgkJfSBlbHNlIHsKCQkJJGVycm9yX21zZyA9ICJXb3JkUHJlc3MgSW1wb3J0ZXIgbmVlZHMgdG8gYmUgaW5zdGFsbGVkLiBUcnkgJ3dwIHBsdWdpbiBpbnN0YWxsIHdvcmRwcmVzcy1pbXBvcnRlciAtLWFjdGl2YXRlJy4iOwoJCX0KCgkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2ltcG9ydGVyLW1pc3NpbmcnLCAkZXJyb3JfbXNnICk7Cgl9CgoJLyoqCgkgKiBQcm9jZXNzZXMgaG93IHRoZSBhdXRob3JzIHNob3VsZCBiZSBtYXBwZWQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgJGF1dGhvcnNfYXJnICAgICAgVGhlIGAtLWF1dGhvcmAgYXJndW1lbnQgb3JpZ2luYWxseSBwYXNzZWQgdG8gY29tbWFuZAoJICogQHBhcmFtIGFycmF5ICAgICAgICAgICAgICRhdXRob3JfZGF0YSAgICAgIEFuIGFycmF5IG9mIFdQX1VzZXItZXNxdWUgYXV0aG9yIG9iamVjdHMKCSAqIEByZXR1cm4gYXJyYXl8V1BfRXJyb3IgICAkYXV0aG9yX21hcHBpbmcgICBBdXRob3IgbWFwcGluZyBhcnJheSBpZiBzdWNjZXNzZnVsLCBXUF9FcnJvciBpZiBzb21ldGhpbmcgYmFkIGhhcHBlbmVkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcHJvY2Vzc19hdXRob3JfbWFwcGluZyggJGF1dGhvcnNfYXJnLCAkYXV0aG9yX2RhdGEgKSB7CgoJCS8vIFByb3ZpZGVkIGFuIGF1dGhvciBtYXBwaW5nIGZpbGUgKG1ldGhvZCBjaGVja3MgdmFsaWRpdHkpCgkJaWYgKCBmaWxlX2V4aXN0cyggJGF1dGhvcnNfYXJnICkgKSB7CgkJCXJldHVybiAkdGhpcy0+cmVhZF9hdXRob3JfbWFwcGluZ19maWxlKCAkYXV0aG9yc19hcmcgKTsKCQl9CgoJCS8vIFByb3ZpZGVkIGEgZmlsZSByZWZlcmVuY2UsIGJ1dCB0aGUgZmlsZSBkb2Vzbid0IHlldCBleGlzdAoJCWlmICggZmFsc2UgIT09IHN0cmlwb3MoICRhdXRob3JzX2FyZywgJy5jc3YnICkgKSB7CgkJCXJldHVybiAkdGhpcy0+Y3JlYXRlX2F1dGhvcl9tYXBwaW5nX2ZpbGUoICRhdXRob3JzX2FyZywgJGF1dGhvcl9kYXRhICk7CgkJfQoKCQlzd2l0Y2ggKCAkYXV0aG9yc19hcmcgKSB7CgkJCS8vIENyZWF0ZSBhdXRob3JzIGlmIHRoZXkgZG9uJ3QgeWV0IGV4aXN0OyBtYXliZSBtYXRjaCBvbiBlbWFpbCBvciB1c2VyX2xvZ2luCgkJCWNhc2UgJ2NyZWF0ZSc6CgkJCQlyZXR1cm4gJHRoaXMtPmNyZWF0ZV9hdXRob3JzX2Zvcl9tYXBwaW5nKCAkYXV0aG9yX2RhdGEgKTsKCgkJCS8vIFNraXAgYW55IHNvcnQgb2YgYXV0aG9yIG1hcHBpbmcKCQkJY2FzZSAnc2tpcCc6CgkJCQlyZXR1cm4gYXJyYXkoKTsKCgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnaW52YWxpZC1hcmd1bWVudCcsICInYXV0aG9ycycgYXJndW1lbnQgaXMgaW52YWxpZC4iICk7CgkJfQoJfQoKCS8qKgoJICogUmVhZHMgYW4gYXV0aG9yIG1hcHBpbmcgZmlsZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZWFkX2F1dGhvcl9tYXBwaW5nX2ZpbGUoICRmaWxlICkgewoJCSRhdXRob3JfbWFwcGluZyA9IGFycmF5KCk7CgoJCWZvcmVhY2ggKCBuZXcgXFdQX0NMSVxJdGVyYXRvcnNcQ1NWKCAkZmlsZSApIGFzICRpID0+ICRhdXRob3IgKSB7CgkJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAnb2xkX3VzZXJfbG9naW4nLCAkYXV0aG9yICkgfHwgISBhcnJheV9rZXlfZXhpc3RzKCAnbmV3X3VzZXJfbG9naW4nLCAkYXV0aG9yICkgKSB7CgkJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnaW52YWxpZC1hdXRob3ItbWFwcGluZycsICJBdXRob3IgbWFwcGluZyBmaWxlIGlzbid0IHByb3Blcmx5IGZvcm1hdHRlZC4iICk7CgkJCX0KCgkJCSRhdXRob3JfbWFwcGluZ1tdID0gJGF1dGhvcjsKCQl9CgoJCXJldHVybiAkYXV0aG9yX21hcHBpbmc7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGFuIGF1dGhvciBtYXBwaW5nIGZpbGUsIGJhc2VkIG9uIHByb3ZpZGVkIGF1dGhvciBkYXRhLgoJICoKCSAqIEByZXR1cm4gV1BfRXJyb3IgICAgICBUaGUgZmlsZSB3YXMganVzdCBub3cgY3JlYXRlZCwgc28gc29tZSBhY3Rpb24gbmVlZHMgdG8gYmUgdGFrZW4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjcmVhdGVfYXV0aG9yX21hcHBpbmdfZmlsZSggJGZpbGUsICRhdXRob3JfZGF0YSApIHsKCgkJaWYgKCB0b3VjaCggJGZpbGUgKSApIHsKCQkJJGF1dGhvcl9tYXBwaW5nID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoICRhdXRob3JfZGF0YSBhcyAkYXV0aG9yICkgewoJCQkJJGF1dGhvcl9tYXBwaW5nW10gPSBhcnJheSgKCQkJCQknb2xkX3VzZXJfbG9naW4nID0+ICRhdXRob3ItPnVzZXJfbG9naW4sCgkJCQkJJ25ld191c2VyX2xvZ2luJyA9PiAkdGhpcy0+c3VnZ2VzdF91c2VyKCAkYXV0aG9yLT51c2VyX2xvZ2luLCAkYXV0aG9yLT51c2VyX2VtYWlsICksCgkJCQkpOwoJCQl9CgkJCSRmaWxlX3Jlc291cmNlID0gZm9wZW4oICRmaWxlLCAndycgKTsKCQkJXFdQX0NMSVx1dGlsc1x3cml0ZV9jc3YoICRmaWxlX3Jlc291cmNlLCAkYXV0aG9yX21hcHBpbmcsIGFycmF5KCAnb2xkX3VzZXJfbG9naW4nLCAnbmV3X3VzZXJfbG9naW4nICkgKTsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2F1dGhvci1tYXBwaW5nLWVycm9yJywgc3ByaW50ZiggJ1BsZWFzZSB1cGRhdGUgYXV0aG9yIG1hcHBpbmcgZmlsZSBiZWZvcmUgY29udGludWluZzogJXMnLCAkZmlsZSApICk7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2F1dGhvci1tYXBwaW5nLWVycm9yJywgIkNvdWxkbid0IGNyZWF0ZSBhdXRob3IgbWFwcGluZyBmaWxlLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIHVzZXJzIGlmIHRoZXkgZG9uJ3QgZXhpc3QsIGFuZCBidWlsZCBhbiBhdXRob3IgbWFwcGluZyBmaWxlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZV9hdXRob3JzX2Zvcl9tYXBwaW5nKCAkYXV0aG9yX2RhdGEgKSB7CgoJCSRhdXRob3JfbWFwcGluZyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRhdXRob3JfZGF0YSBhcyAkYXV0aG9yICkgewoKCQkJaWYgKCBpc3NldCggJGF1dGhvci0+dXNlcl9lbWFpbCApICkgewoJCQkJJHVzZXIgPSBnZXRfdXNlcl9ieSggJ2VtYWlsJywgJGF1dGhvci0+dXNlcl9lbWFpbCApOwoJCQkJaWYgKCAkdXNlciBpbnN0YW5jZW9mIFdQX1VzZXIgKSB7CgkJCQkJJGF1dGhvcl9tYXBwaW5nW10gPSBhcnJheSgKCQkJCQkJJ29sZF91c2VyX2xvZ2luJyA9PiAkYXV0aG9yLT51c2VyX2xvZ2luLAoJCQkJCQknbmV3X3VzZXJfbG9naW4nID0+ICR1c2VyLT51c2VyX2xvZ2luLAoJCQkJCSk7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCX0KCgkJCSR1c2VyID0gZ2V0X3VzZXJfYnkoICdsb2dpbicsICRhdXRob3ItPnVzZXJfbG9naW4gKTsKCQkJaWYgKCAkdXNlciBpbnN0YW5jZW9mIFdQX1VzZXIgKSB7CgkJCQkkYXV0aG9yX21hcHBpbmdbXSA9IGFycmF5KAoJCQkJCSdvbGRfdXNlcl9sb2dpbicgPT4gJGF1dGhvci0+dXNlcl9sb2dpbiwKCQkJCQknbmV3X3VzZXJfbG9naW4nID0+ICR1c2VyLT51c2VyX2xvZ2luLAoJCQkJKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdXNlciA9IGFycmF5KAoJCQkJJ3VzZXJfbG9naW4nID0+ICcnLAoJCQkJJ3VzZXJfZW1haWwnID0+ICcnLAoJCQkJJ3VzZXJfcGFzcycgID0+IHdwX2dlbmVyYXRlX3Bhc3N3b3JkKCksCgkJCSk7CgkJCSR1c2VyID0gYXJyYXlfbWVyZ2UoICR1c2VyLCAoYXJyYXkpICRhdXRob3IgKTsKCgkJCSR1c2VyX2lkID0gd3BfaW5zZXJ0X3VzZXIoICR1c2VyICk7CgkJCWlmICggaXNfd3BfZXJyb3IoICR1c2VyX2lkICkgKSB7CgkJCQlyZXR1cm4gJHVzZXJfaWQ7CgkJCX0KCgkJCSR1c2VyICAgICAgICAgICAgID0gZ2V0X3VzZXJfYnkoICdpZCcsICR1c2VyX2lkICk7CgkJCSRhdXRob3JfbWFwcGluZ1tdID0gYXJyYXkoCgkJCQknb2xkX3VzZXJfbG9naW4nID0+ICRhdXRob3ItPnVzZXJfbG9naW4sCgkJCQknbmV3X3VzZXJfbG9naW4nID0+ICR1c2VyLT51c2VyX2xvZ2luLAoJCQkpOwoJCX0KCQlyZXR1cm4gJGF1dGhvcl9tYXBwaW5nOwoKCX0KCgkvKioKCSAqIFN1Z2dlc3RzIGEgYmxvZyB1c2VyIGJhc2VkIG9uIHRoZSBsZXZlbnNodGVpbiBkaXN0YW5jZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzdWdnZXN0X3VzZXIoICRhdXRob3JfdXNlcl9sb2dpbiwgJGF1dGhvcl91c2VyX2VtYWlsID0gJycgKSB7CgoJCWlmICggISBpc3NldCggJHRoaXMtPmJsb2dfdXNlcnMgKSApIHsKCQkJJHRoaXMtPmJsb2dfdXNlcnMgPSBnZXRfdXNlcnMoKTsKCQl9CgoJCSRzaG9ydGVzdCAgICA9IC0xOwoJCSRzaG9ydGVzdGF2ZyA9IGFycmF5KCk7CgoJCSR0aHJlc2hvbGQgPSBmbG9vciggKCBzdHJsZW4oICRhdXRob3JfdXNlcl9sb2dpbiApIC8gMTAwICkgKiAxMCApOyAvLyAxMCAlIG9mIHRoZSBzdHJsZW4gYXJlIHZhbGlkCgkJJGNsb3Nlc3QgICA9ICcnOwoJCWZvcmVhY2ggKCAkdGhpcy0+YmxvZ191c2VycyBhcyAkdXNlciApIHsKCQkJLy8gQmVmb3JlIHdlIHJlc29ydCB0byBhbiBhbGdvcml0aG0sIGxldCdzIHRyeSBmb3IgYW4gZXhhY3QgbWF0Y2gKCQkJaWYgKCAkYXV0aG9yX3VzZXJfZW1haWwgJiYgJHVzZXItPnVzZXJfZW1haWwgPT09ICRhdXRob3JfdXNlcl9lbWFpbCApIHsKCQkJCXJldHVybiAkdXNlci0+dXNlcl9sb2dpbjsKCQkJfQoKCQkJJGxldnMgICAgICAgID0gYXJyYXkoKTsKCQkJJGxldnNbXSAgICAgID0gbGV2ZW5zaHRlaW4oICRhdXRob3JfdXNlcl9sb2dpbiwgJHVzZXItPmRpc3BsYXlfbmFtZSApOwoJCQkkbGV2c1tdICAgICAgPSBsZXZlbnNodGVpbiggJGF1dGhvcl91c2VyX2xvZ2luLCAkdXNlci0+dXNlcl9sb2dpbiApOwoJCQkkbGV2c1tdICAgICAgPSBsZXZlbnNodGVpbiggJGF1dGhvcl91c2VyX2xvZ2luLCAkdXNlci0+dXNlcl9lbWFpbCApOwoJCQkkZW1haWxfcGFydHMgPSBleHBsb2RlKCAnQCcsICR1c2VyLT51c2VyX2VtYWlsICk7CgkJCSRlbWFpbF9sb2dpbiA9IGFycmF5X3NoaWZ0KCAkZW1haWxfcGFydHMgKTsKCQkJJGxldnNbXSAgICAgID0gbGV2ZW5zaHRlaW4oICRhdXRob3JfdXNlcl9sb2dpbiwgJGVtYWlsX2xvZ2luICk7CgkJCXJzb3J0KCAkbGV2cyApOwoJCQkkbGV2ID0gYXJyYXlfcG9wKCAkbGV2cyApOwoJCQlpZiAoIDAgPT09ICRsZXYgKSB7CgkJCQkkY2xvc2VzdCAgPSAkdXNlci0+dXNlcl9sb2dpbjsKCQkJCSRzaG9ydGVzdCA9IDA7CgkJCQlicmVhazsKCQkJfQoKCQkJaWYgKCAoICRsZXYgPD0gJHNob3J0ZXN0IHx8ICRzaG9ydGVzdCA8IDAgKSAmJiAkbGV2IDw9ICR0aHJlc2hvbGQgKSB7CgkJCQkkY2xvc2VzdCAgPSAkdXNlci0+dXNlcl9sb2dpbjsKCQkJCSRzaG9ydGVzdCA9ICRsZXY7CgkJCX0KCQkJJHNob3J0ZXN0YXZnW10gPSAkbGV2OwoJCX0KCQkvLyBpbiBjYXNlIGFsbCB1c2VybmFtZXMgaGF2ZSBhIGNvbW1vbiBwYXR0ZXJuCgkJaWYgKCAkc2hvcnRlc3QgPiAoIGFycmF5X3N1bSggJHNob3J0ZXN0YXZnICkgLyBjb3VudCggJHNob3J0ZXN0YXZnICkgKSApIHsKCQkJcmV0dXJuICcnOwoJCX0KCgkJcmV0dXJuICRjbG9zZXN0OwoJfQoKfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX3NlcnZlcl9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9zZXJ2ZXJfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9zZXJ2ZXJfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdzZXJ2ZXInLAoJJ1NlcnZlcl9Db21tYW5kJywKCWFycmF5KAoJCSdiZWZvcmVfaW52b2tlJyA9PiBmdW5jdGlvbigpIHsKCQkJJG1pbl92ZXJzaW9uID0gJzUuNCc7CgkJCWlmICggdmVyc2lvbl9jb21wYXJlKCBQSFBfVkVSU0lPTiwgJG1pbl92ZXJzaW9uLCAnPCcgKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgYHdwIHNlcnZlcmAgY29tbWFuZCByZXF1aXJlcyBQSFAgeyRtaW5fdmVyc2lvbn0gb3IgbmV3ZXIuIiApOwoJCQl9CgkJfSwKCSkKKTsKPD9waHAKLy8gVXNlZCBieSBgd3Agc2VydmVyYCB0byByb3V0ZSByZXF1ZXN0cy4KCm5hbWVzcGFjZSBXUF9DTElcUm91dGVyOwoKLyoqCiAqIFRoaXMgaXMgYSBjb3B5IG9mIFdvcmRQcmVzcydzIGFkZF9maWx0ZXIoKSBmdW5jdGlvbi4KICoKICogV2UgZHVwbGljYXRlIGl0IGJlY2F1c2UgV29yZFByZXNzIGlzIG5vdCBsb2FkZWQgeWV0LgogKi8KZnVuY3Rpb24gYWRkX2ZpbHRlciggJHRhZywgJGZ1bmN0aW9uX3RvX2FkZCwgJHByaW9yaXR5ID0gMTAsICRhY2NlcHRlZF9hcmdzID0gMSApIHsKCWdsb2JhbCAkd3BfZmlsdGVyLCAkbWVyZ2VkX2ZpbHRlcnM7CgoJJGlkeCA9IF93cF9maWx0ZXJfYnVpbGRfdW5pcXVlX2lkKCAkdGFnLCAkZnVuY3Rpb25fdG9fYWRkLCAkcHJpb3JpdHkgKTsKCgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQKCSR3cF9maWx0ZXJbICR0YWcgXVsgJHByaW9yaXR5IF1bICRpZHggXSA9IGFycmF5KAoJCSdmdW5jdGlvbicgICAgICA9PiAkZnVuY3Rpb25fdG9fYWRkLAoJCSdhY2NlcHRlZF9hcmdzJyA9PiAkYWNjZXB0ZWRfYXJncywKCSk7Cgl1bnNldCggJG1lcmdlZF9maWx0ZXJzWyAkdGFnIF0gKTsKCXJldHVybiB0cnVlOwp9CgovKioKICogVGhpcyBpcyBhIGNvcHkgb2YgV29yZFByZXNzJ3MgX3dwX2ZpbHRlcl9idWlsZF91bmlxdWVfaWQoKSBmdW5jdGlvbi4KICoKICogV2UgZHVwbGljYXRlIGl0IGJlY2F1c2UgV29yZFByZXNzIGlzIG5vdCBsb2FkZWQgeWV0LgogKi8KZnVuY3Rpb24gX3dwX2ZpbHRlcl9idWlsZF91bmlxdWVfaWQoICR0YWcsICRmdW5jdGlvbiwgJHByaW9yaXR5ICkgewoJZ2xvYmFsICR3cF9maWx0ZXI7CglzdGF0aWMgJGZpbHRlcl9pZF9jb3VudCA9IDA7CgoJaWYgKCBpc19zdHJpbmcoICRmdW5jdGlvbiApICkgewoJCXJldHVybiAkZnVuY3Rpb247Cgl9CgoJaWYgKCBpc19vYmplY3QoICRmdW5jdGlvbiApICkgewoJCS8vIENsb3N1cmVzIGFyZSBjdXJyZW50bHkgaW1wbGVtZW50ZWQgYXMgb2JqZWN0cwoJCSRmdW5jdGlvbiA9IGFycmF5KCAkZnVuY3Rpb24sICcnICk7Cgl9IGVsc2UgewoJCSRmdW5jdGlvbiA9IChhcnJheSkgJGZ1bmN0aW9uOwoJfQoKCWlmICggaXNfb2JqZWN0KCAkZnVuY3Rpb25bMF0gKSApIHsKCQkvLyBPYmplY3QgQ2xhc3MgQ2FsbGluZwoJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnc3BsX29iamVjdF9oYXNoJyApICkgewoJCQlyZXR1cm4gc3BsX29iamVjdF9oYXNoKCAkZnVuY3Rpb25bMF0gKSAuICRmdW5jdGlvblsxXTsKCQl9IGVsc2UgewoJCQkkb2JqX2lkeCA9IGdldF9jbGFzcyggJGZ1bmN0aW9uWzBdICkgLiAkZnVuY3Rpb25bMV07CgkJCWlmICggISBpc3NldCggJGZ1bmN0aW9uWzBdLT53cF9maWx0ZXJfaWQgKSApIHsKCQkJCWlmICggZmFsc2UgPT09ICRwcmlvcml0eSApIHsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCQkkb2JqX2lkeCAuPSBpc3NldCggJHdwX2ZpbHRlclsgJHRhZyBdWyAkcHJpb3JpdHkgXSApCgkJCQkJPyBjb3VudCggKGFycmF5KSAkd3BfZmlsdGVyWyAkdGFnIF1bICRwcmlvcml0eSBdICkKCQkJCQk6ICRmaWx0ZXJfaWRfY291bnQ7CgoJCQkJJGZ1bmN0aW9uWzBdLT53cF9maWx0ZXJfaWQgPSAkZmlsdGVyX2lkX2NvdW50OwoJCQkJKyskZmlsdGVyX2lkX2NvdW50OwoJCQl9IGVsc2UgewoJCQkJJG9ial9pZHggLj0gJGZ1bmN0aW9uWzBdLT53cF9maWx0ZXJfaWQ7CgkJCX0KCgkJCXJldHVybiAkb2JqX2lkeDsKCQl9Cgl9IGVsc2VpZiAoIGlzX3N0cmluZyggJGZ1bmN0aW9uWzBdICkgKSB7CgkJLy8gU3RhdGljIENhbGxpbmcKCQlyZXR1cm4gJGZ1bmN0aW9uWzBdIC4gJzo6JyAuICRmdW5jdGlvblsxXTsKCX0KfQoKZnVuY3Rpb24gX2dldF9mdWxsX2hvc3QoICR1cmwgKSB7CgkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwKCSRwYXJzZWRfdXJsID0gcGFyc2VfdXJsKCAkdXJsICk7CgoJJGhvc3QgPSAkcGFyc2VkX3VybFsnaG9zdCddOwoJaWYgKCBpc3NldCggJHBhcnNlZF91cmxbJ3BvcnQnXSApICYmIDgwICE9PSAkcGFyc2VkX3VybFsncG9ydCddICkgewoJCSRob3N0IC49ICc6JyAuICRwYXJzZWRfdXJsWydwb3J0J107Cgl9CgoJcmV0dXJuICRob3N0Owp9CgovLyBXZSBuZWVkIHRvIHRyaWNrIFdvcmRQcmVzcyBpbnRvIHVzaW5nIHRoZSBVUkwgc2V0IGJ5IGB3cCBzZXJ2ZXJgLCBlc3BlY2lhbGx5IG9uIG11bHRpc2l0ZS4KYWRkX2ZpbHRlcigKCSdvcHRpb25faG9tZScsCglmdW5jdGlvbiAoICR1cmwgKSB7CgkJJEdMT0JBTFNbJ3dwY2xpX3NlcnZlcl9vcmlnaW5hbF91cmwnXSA9ICR1cmw7CgoJCXJldHVybiAnaHR0cDovLycgLiAkX1NFUlZFUlsnSFRUUF9IT1NUJ107Cgl9LAoJMjAKKTsKCmFkZF9maWx0ZXIoCgknb3B0aW9uX3NpdGV1cmwnLAoJZnVuY3Rpb24gKCAkdXJsICkgewoJCWlmICggISBpc3NldCggJEdMT0JBTFNbJ3dwY2xpX3NlcnZlcl9vcmlnaW5hbF91cmwnXSApICkgewoJCQlnZXRfb3B0aW9uKCAnaG9tZScgKTsgIC8vIHRyaWdnZXIgdGhlIG9wdGlvbl9ob21lIGZpbHRlcgoJCX0KCgkJJGhvbWVfdXJsX2hvc3QgPSBfZ2V0X2Z1bGxfaG9zdCggJEdMT0JBTFNbJ3dwY2xpX3NlcnZlcl9vcmlnaW5hbF91cmwnXSApOwoJCSRzaXRlX3VybF9ob3N0ID0gX2dldF9mdWxsX2hvc3QoICR1cmwgKTsKCgkJaWYgKCAkc2l0ZV91cmxfaG9zdCA9PT0gJGhvbWVfdXJsX2hvc3QgKSB7CgkJCSR1cmwgPSBzdHJfcmVwbGFjZSggJHNpdGVfdXJsX2hvc3QsICRfU0VSVkVSWydIVFRQX0hPU1QnXSwgJHVybCApOwoJCX0KCgkJcmV0dXJuICR1cmw7Cgl9LAoJMjAKKTsKCiRfU0VSVkVSWydTRVJWRVJfQUREUiddID0gZ2V0aG9zdGJ5bmFtZSggJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gKTsKJHdwY2xpX3NlcnZlcl9yb290ICAgICAgPSAkX1NFUlZFUlsnRE9DVU1FTlRfUk9PVCddOwovLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwKJHdwY2xpX3NlcnZlcl9wYXRoID0gJy8nIC4gbHRyaW0oIHBhcnNlX3VybCggdXJsZGVjb2RlKCAkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSApIClbJ3BhdGgnXSwgJy8nICk7CgppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfc2VydmVyX3Jvb3QgLiAkd3BjbGlfc2VydmVyX3BhdGggKSApIHsKCWlmICggaXNfZGlyKCAkd3BjbGlfc2VydmVyX3Jvb3QgLiAkd3BjbGlfc2VydmVyX3BhdGggKSAmJiBzdWJzdHIoICR3cGNsaV9zZXJ2ZXJfcGF0aCwgLTEgKSAhPT0gJy8nICkgewoJCWhlYWRlciggIkxvY2F0aW9uOiAkd3BjbGlfc2VydmVyX3BhdGgvIiApOwoJCWV4aXQ7Cgl9CgoJaWYgKCBzdHJwb3MoICR3cGNsaV9zZXJ2ZXJfcGF0aCwgJy5waHAnICkgIT09IGZhbHNlICkgewoJCWNoZGlyKCBkaXJuYW1lKCAkd3BjbGlfc2VydmVyX3Jvb3QgLiAkd3BjbGlfc2VydmVyX3BhdGggKSApOwoJCXJlcXVpcmVfb25jZSAkd3BjbGlfc2VydmVyX3Jvb3QgLiAkd3BjbGlfc2VydmVyX3BhdGg7Cgl9IGVsc2UgewoJCXJldHVybiBmYWxzZTsKCX0KfSBlbHNlIHsKCWNoZGlyKCAkd3BjbGlfc2VydmVyX3Jvb3QgKTsKCXJlcXVpcmVfb25jZSAnaW5kZXgucGhwJzsKfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCmNsYXNzIFNlcnZlcl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTGF1bmNoZXMgUEhQJ3MgYnVpbHQtaW4gd2ViIHNlcnZlciBmb3IgYSBzcGVjaWZpYyBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uLgoJICoKCSAqIFVzZXMgYHBocCAtU2AgdG8gbGF1bmNoIGEgd2ViIHNlcnZlciBzZXJ2aW5nIHRoZSBXb3JkUHJlc3Mgd2Vicm9vdC4KCSAqIDxodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZmVhdHVyZXMuY29tbWFuZGxpbmUud2Vic2VydmVyLnBocD4KCSAqCgkgKiBJbXBvcnRhbnRseSwgUEhQJ3MgYnVpbHQtaW4gd2ViIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgYC5odGFjY2Vzc2AgZmlsZXMuCgkgKiBJZiB0aGlzIGlzIGEgcmVxdWlyZW1lbnQsIHBsZWFzZSB1c2UgYSBtb3JlIGFkdmFuY2VkIHdlYiBzZXJ2ZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWhvc3Q9PGhvc3Q+XQoJICogOiBUaGUgaG9zdG5hbWUgdG8gYmluZCB0aGUgc2VydmVyIHRvLgoJICogLS0tCgkgKiBkZWZhdWx0OiBsb2NhbGhvc3QKCSAqIC0tLQoJICoKCSAqIFstLXBvcnQ9PHBvcnQ+XQoJICogOiBUaGUgcG9ydCBudW1iZXIgdG8gYmluZCB0aGUgc2VydmVyIHRvLgoJICogLS0tCgkgKiBkZWZhdWx0OiA4MDgwCgkgKiAtLS0KCSAqCgkgKiBbLS1kb2Nyb290PTxwYXRoPl0KCSAqIDogVGhlIHBhdGggdG8gdXNlIGFzIHRoZSBkb2N1bWVudCByb290LiBJZiB0aGUgcGF0aCBnbG9iYWwgcGFyYW1ldGVyIGlzCgkgKiBzZXQsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGl0LgoJICoKCSAqIFstLWNvbmZpZz08ZmlsZT5dCgkgKiA6IENvbmZpZ3VyZSB0aGUgc2VydmVyIHdpdGggYSBzcGVjaWZpYyAuaW5pIGZpbGUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBNYWtlIHRoZSBpbnN0YW5jZSBhdmFpbGFibGUgb24gYW55IGFkZHJlc3MgKHdpdGggcG9ydCA4MDgwKQoJICogICAgICQgd3Agc2VydmVyIC0taG9zdD0wLjAuMC4wCgkgKiAgICAgUEhQIDUuNi45IERldmVsb3BtZW50IFNlcnZlciBzdGFydGVkIGF0IFR1ZSBNYXkgMjQgMDE6Mjc6MTEgMjAxNgoJICogICAgIExpc3RlbmluZyBvbiBodHRwOi8vMC4wLjAuMDo4MDgwCgkgKiAgICAgRG9jdW1lbnQgcm9vdCBpcyAvCgkgKiAgICAgUHJlc3MgQ3RybC1DIHRvIHF1aXQuCgkgKgoJICogICAgICMgUnVuIG9uIHBvcnQgODAgKGZvciBtdWx0aXNpdGUpCgkgKiAgICAgJCB3cCBzZXJ2ZXIgLS1ob3N0PWxvY2FsaG9zdC5sb2NhbGRvbWFpbiAtLXBvcnQ9ODAKCSAqICAgICBQSFAgNS42LjkgRGV2ZWxvcG1lbnQgU2VydmVyIHN0YXJ0ZWQgYXQgVHVlIE1heSAyNCAwMTozMDowNiAyMDE2CgkgKiAgICAgTGlzdGVuaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3QxLmxvY2FsZG9tYWluMTo4MAoJICogICAgIERvY3VtZW50IHJvb3QgaXMgLwoJICogICAgIFByZXNzIEN0cmwtQyB0byBxdWl0LgoJICoKCSAqICAgICAjIENvbmZpZ3VyZSB0aGUgc2VydmVyIHdpdGggYSBzcGVjaWZpYyAuaW5pIGZpbGUKCSAqICAgICAkIHdwIHNlcnZlciAtLWNvbmZpZz1kZXZlbG9wbWVudC5pbmkKCSAqICAgICBQSFAgNy4wLjkgRGV2ZWxvcG1lbnQgU2VydmVyIHN0YXJ0ZWQgYXQgTW9uIEF1ZyAyMiAxMjowOTowNCAyMDE2CgkgKiAgICAgTGlzdGVuaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MAoJICogICAgIERvY3VtZW50IHJvb3QgaXMgLwoJICogICAgIFByZXNzIEN0cmwtQyB0byBxdWl0LgoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJF8sICRhc3NvY19hcmdzICkgewoJCSRkZWZhdWx0cyAgID0gYXJyYXkoCgkJCSdob3N0JyAgICA9PiAnbG9jYWxob3N0JywKCQkJJ3BvcnQnICAgID0+IDgwODAsCgkJCSdkb2Nyb290JyA9PiAhIGlzX251bGwoIFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5jb25maWdbJ3BhdGgnXSApID8gV1BfQ0xJOjpnZXRfcnVubmVyKCktPmNvbmZpZ1sncGF0aCddIDogZmFsc2UsCgkJCSdjb25maWcnICA9PiBnZXRfY2ZnX3ZhciggJ2NmZ19maWxlX3BhdGgnICksCgkJKTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRkb2Nyb290ID0gJGFzc29jX2FyZ3NbJ2RvY3Jvb3QnXTsKCgkJaWYgKCAhICRkb2Nyb290ICkgewoJCQkkY29uZmlnX3BhdGggPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+cHJvamVjdF9jb25maWdfcGF0aDsKCgkJCWlmICggISAkY29uZmlnX3BhdGggKSB7CgkJCQkkZG9jcm9vdCA9IEFCU1BBVEg7CgkJCX0gZWxzZSB7CgkJCQkkZG9jcm9vdCA9IGRpcm5hbWUoICRjb25maWdfcGF0aCApOwoJCQl9CgkJfQoKCQkvLyBHZXQgdGhlIHBhdGggdG8gdGhlIHJvdXRlciBmaWxlCgkJJGNvbW1hbmRfcm9vdCA9IFV0aWxzXHBoYXJfc2FmZV9wYXRoKCBkaXJuYW1lKCBfX0RJUl9fICkgKTsKCQkkcm91dGVyX3BhdGggID0gJGNvbW1hbmRfcm9vdCAuICcvcm91dGVyLnBocCc7CgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkcm91dGVyX3BhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGZpbmQgcm91dGVyLnBocCIgKTsKCQl9CgkJJGNtZCA9IFV0aWxzXGVzY19jbWQoCgkJCSclcyAtUyAlcyAtdCAlcyAtYyAlcyAlcycsCgkJCVdQX0NMSTo6Z2V0X3BocF9iaW5hcnkoKSwKCQkJJGFzc29jX2FyZ3NbJ2hvc3QnXSAuICc6JyAuICRhc3NvY19hcmdzWydwb3J0J10sCgkJCSRkb2Nyb290LAoJCQkkYXNzb2NfYXJnc1snY29uZmlnJ10sCgkJCVV0aWxzXGV4dHJhY3RfZnJvbV9waGFyKCAkcm91dGVyX3BhdGggKQoJCSk7CgoJCSRkZXNjcmlwdG9ycyA9IGFycmF5KCBTVERJTiwgU1RET1VULCBTVERFUlIgKTsKCgkJLy8gaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD02MDE4MQoJCSRvcHRpb25zID0gYXJyYXkoKTsKCQlpZiAoIFV0aWxzXGlzX3dpbmRvd3MoKSApIHsKCQkJJG9wdGlvbnNbJ2J5cGFzc19zaGVsbCddID0gdHJ1ZTsKCQl9CgoJCWV4aXQoIHByb2NfY2xvc2UoIHByb2Nfb3BlbiggJGNtZCwgJGRlc2NyaXB0b3JzLCAkcGlwZXMsIG51bGwsIG51bGwsICRvcHRpb25zICkgKSApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfZGJfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfZGJfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9kYl9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnZGInLCAnREJfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIFBlcmZvcm1zIGJhc2ljIGRhdGFiYXNlIG9wZXJhdGlvbnMgdXNpbmcgY3JlZGVudGlhbHMgc3RvcmVkIGluIHdwLWNvbmZpZy5waHAuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIG5ldyBkYXRhYmFzZS4KICogICAgICQgd3AgZGIgY3JlYXRlCiAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBjcmVhdGVkLgogKgogKiAgICAgIyBEcm9wIGFuIGV4aXN0aW5nIGRhdGFiYXNlLgogKiAgICAgJCB3cCBkYiBkcm9wIC0teWVzCiAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBkcm9wcGVkLgogKgogKiAgICAgIyBSZXNldCB0aGUgY3VycmVudCBkYXRhYmFzZS4KICogICAgICQgd3AgZGIgcmVzZXQgLS15ZXMKICogICAgIFN1Y2Nlc3M6IERhdGFiYXNlIHJlc2V0LgogKgogKiAgICAgIyBFeGVjdXRlIGEgU1FMIHF1ZXJ5IHN0b3JlZCBpbiBhIGZpbGUuCiAqICAgICAkIHdwIGRiIHF1ZXJ5IDwgZGVidWcuc3FsCiAqCiAqIEB3aGVuIGFmdGVyX3dwX2NvbmZpZ19sb2FkCiAqLwpjbGFzcyBEQl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogQSBsaXN0IG9mIGluY29tcGF0aWJsZSBTUUwgbW9kZXMuCgkgKgoJICogQ29waWVkIG92ZXIgZnJvbSBXb3JkUHJlc3MgQ29yZSBjb2RlLgoJICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzL3dvcmRwcmVzcy1kZXZlbG9wL2Jsb2IvNS40LjAvc3JjL3dwLWluY2x1ZGVzL3dwLWRiLnBocCNMNTU5LUw1NzIKCSAqCgkgKiBAdmFyIHN0cmluZ1tdIEFycmF5IG9mIFNRTCBtb2RlIG5hbWVzIHRoYXQgYXJlIGluY29tcGF0aWJsZSB3aXRoIFdvcmRQcmVzcy4KCSAqLwoJcHJvdGVjdGVkICRzcWxfaW5jb21wYXRpYmxlX21vZGVzID0gWwoJCSdOT19aRVJPX0RBVEUnLAoJCSdPTkxZX0ZVTExfR1JPVVBfQlknLAoJCSdTVFJJQ1RfVFJBTlNfVEFCTEVTJywKCQknU1RSSUNUX0FMTF9UQUJMRVMnLAoJCSdUUkFESVRJT05BTCcsCgkJJ0FOU0knLAoJXTsKCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgQ1JFQVRFX0RBVEFCQVNFYCBTUUwgc3RhdGVtZW50IHVzaW5nIGBEQl9IT1NUYCwgYERCX05BTUVgLAoJICogYERCX1VTRVJgIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzIHNwZWNpZmllZCBpbgoJICogd3AtY29uZmlnLnBocC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgY3JlYXRlCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgY3JlYXRlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSggJF8sICRhc3NvY19hcmdzICkgewoKCQkkdGhpcy0+cnVuX3F1ZXJ5KCBzZWxmOjpnZXRfY3JlYXRlX3F1ZXJ5KCksIHNlbGY6OmdldF9kYnVzZXJfZGJwYXNzX2FyZ3MoICRhc3NvY19hcmdzICkgKTsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAnRGF0YWJhc2UgY3JlYXRlZC4nICk7Cgl9CgoJLyoqCgkgKiBEZWxldGVzIHRoZSBleGlzdGluZyBkYXRhYmFzZS4KCSAqCgkgKiBSdW5zIGBEUk9QX0RBVEFCQVNFYCBTUUwgc3RhdGVtZW50IHVzaW5nIGBEQl9IT1NUYCwgYERCX05BTUVgLAoJICogYERCX1VTRVJgIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzIHNwZWNpZmllZCBpbgoJICogd3AtY29uZmlnLnBocC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLXllc10KCSAqIDogQW5zd2VyIHllcyB0byB0aGUgY29uZmlybWF0aW9uIG1lc3NhZ2UuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBkYiBkcm9wIC0teWVzCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgZHJvcHBlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRyb3AoICRfLCAkYXNzb2NfYXJncyApIHsKCQlXUF9DTEk6OmNvbmZpcm0oICJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZHJvcCB0aGUgJyIgLiBEQl9OQU1FIC4gIicgZGF0YWJhc2U/IiwgJGFzc29jX2FyZ3MgKTsKCgkJJHRoaXMtPnJ1bl9xdWVyeSggc3ByaW50ZiggJ0RST1AgREFUQUJBU0UgYCVzYCcsIERCX05BTUUgKSwgc2VsZjo6Z2V0X2RidXNlcl9kYnBhc3NfYXJncyggJGFzc29jX2FyZ3MgKSApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEYXRhYmFzZSBkcm9wcGVkLicgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYWxsIHRhYmxlcyBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBSdW5zIGBEUk9QX0RBVEFCQVNFYCBhbmQgYENSRUFURV9EQVRBQkFTRWAgU1FMIHN0YXRlbWVudHMgdXNpbmcKCSAqIGBEQl9IT1NUYCwgYERCX05BTUVgLCBgREJfVVNFUmAgYW5kIGBEQl9QQVNTV09SRGAgZGF0YWJhc2UgY3JlZGVudGlhbHMKCSAqIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kYnVzZXI9PHZhbHVlPl0KCSAqIDogVXNlcm5hbWUgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbC4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0teWVzXQoJICogOiBBbnN3ZXIgeWVzIHRvIHRoZSBjb25maXJtYXRpb24gbWVzc2FnZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIHJlc2V0IC0teWVzCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgcmVzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXNldCggJF8sICRhc3NvY19hcmdzICkgewoJCVdQX0NMSTo6Y29uZmlybSggIkFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZXNldCB0aGUgJyIgLiBEQl9OQU1FIC4gIicgZGF0YWJhc2U/IiwgJGFzc29jX2FyZ3MgKTsKCgkJJG15c3FsX2FyZ3MgPSBzZWxmOjpnZXRfZGJ1c2VyX2RicGFzc19hcmdzKCAkYXNzb2NfYXJncyApOwoKCQkkdGhpcy0+cnVuX3F1ZXJ5KCBzcHJpbnRmKCAnRFJPUCBEQVRBQkFTRSBJRiBFWElTVFMgYCVzYCcsIERCX05BTUUgKSwgJG15c3FsX2FyZ3MgKTsKCQkkdGhpcy0+cnVuX3F1ZXJ5KCBzZWxmOjpnZXRfY3JlYXRlX3F1ZXJ5KCksICRteXNxbF9hcmdzICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0RhdGFiYXNlIHJlc2V0LicgKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYWxsIHRhYmxlcyB3aXRoIGAkdGFibGVfcHJlZml4YCBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBSdW5zIGBEUk9QX1RBQkxFYCBmb3IgZWFjaCB0YWJsZSB0aGF0IGhhcyBhIGAkdGFibGVfcHJlZml4YCBhcyBzcGVjaWZpZWQKCSAqIGluIHdwLWNvbmZpZy5waHAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS15ZXNdCgkgKiA6IEFuc3dlciB5ZXMgdG8gdGhlIGNvbmZpcm1hdGlvbiBtZXNzYWdlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgY3VycmVudCBzaXRlIHByZWZpeC4KCSAqICAgICAkIHdwIGRiIGNsZWFuIC0teWVzCgkgKiAgICAgU3VjY2VzczogVGFibGVzIGRyb3BwZWQuCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gY2xlYW4oICRfLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCVdQX0NMSTo6Y29uZmlybSgKCQkJc3ByaW50ZigKCQkJCSJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZHJvcCBhbGwgdGhlIHRhYmxlcyBvbiAnJXMnIHRoYXQgdXNlIHRoZSBjdXJyZW50IHNpdGUncyBkYXRhYmFzZSBwcmVmaXggKCclcycpPyIsCgkJCQlEQl9OQU1FLAoJCQkJJHdwZGItPmdldF9ibG9nX3ByZWZpeCgpCgkJCSksCgkJCSRhc3NvY19hcmdzCgkJKTsKCgkJJG15c3FsX2FyZ3MgPSBzZWxmOjpnZXRfZGJ1c2VyX2RicGFzc19hcmdzKCAkYXNzb2NfYXJncyApOwoKCQkkdGFibGVzID0gVXRpbHNcd3BfZ2V0X3RhYmxlX25hbWVzKAoJCQlbXSwKCQkJWyAnYWxsLXRhYmxlcy13aXRoLXByZWZpeCcgPT4gdHJ1ZSBdCgkJKTsKCgkJZm9yZWFjaCAoICR0YWJsZXMgYXMgJHRhYmxlICkgewoJCQkkdGhpcy0+cnVuX3F1ZXJ5KAoJCQkJc3ByaW50ZigKCQkJCQknRFJPUCBUQUJMRSBJRiBFWElTVFMgYCVzYC5gJXNgJywKCQkJCQlEQl9OQU1FLAoJCQkJCSR0YWJsZQoJCQkJKSwKCQkJCSRteXNxbF9hcmdzCgkJCSk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdUYWJsZXMgZHJvcHBlZC4nICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBSdW5zIGBteXNxbGNoZWNrYCB1dGlsaXR5IHdpdGggYC0tY2hlY2tgIHVzaW5nIGBEQl9IT1NUYCwKCSAqIGBEQl9OQU1FYCwgYERCX1VTRVJgIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzCgkgKiBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4KCSAqCgkgKiBbU2VlIGRvY3NdKGh0dHA6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS43L2VuL2NoZWNrLXRhYmxlLmh0bWwpCgkgKiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBgQ0hFQ0sgVEFCTEVgIHN0YXRlbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIG15c3FsY2hlY2suIFtSZWZlciB0byBteXNxbGNoZWNrIGRvY3NdKGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvZW4vbXlzcWxjaGVjay5odG1sKS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgY2hlY2sKCSAqICAgICBTdWNjZXNzOiBEYXRhYmFzZSBjaGVja2VkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gY2hlY2soICRfLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbW1hbmQgPSBzcHJpbnRmKCAnL3Vzci9iaW4vZW52IG15c3FsY2hlY2slcyAlcycsICR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICksICclcycgKTsKCQlXUF9DTEk6OmRlYnVnKCAiUnVubmluZyBzaGVsbCBjb21tYW5kOiB7JGNvbW1hbmR9IiwgJ2RiJyApOwoKCQkkYXNzb2NfYXJnc1snY2hlY2snXSA9IHRydWU7CgkJc2VsZjo6cnVuKAoJCQlVdGlsc1xlc2NfY21kKCAkY29tbWFuZCwgREJfTkFNRSApLAoJCQkkYXNzb2NfYXJncwoJCSk7CgoJCVdQX0NMSTo6ZGVidWcoICdBc3NvY2lhdGl2ZSBhcmd1bWVudHM6ICcgLiBqc29uX2VuY29kZSggJGFzc29jX2FyZ3MgKSwgJ2RiJyApOwoJCVdQX0NMSTo6c3VjY2VzcyggJ0RhdGFiYXNlIGNoZWNrZWQuJyApOwoJfQoKCS8qKgoJICogT3B0aW1pemVzIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBSdW5zIGBteXNxbGNoZWNrYCB1dGlsaXR5IHdpdGggYC0tb3B0aW1pemU9dHJ1ZWAgdXNpbmcgYERCX0hPU1RgLAoJICogYERCX05BTUVgLCBgREJfVVNFUmAgYW5kIGBEQl9QQVNTV09SRGAgZGF0YWJhc2UgY3JlZGVudGlhbHMKCSAqIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICoKCSAqIFtTZWUgZG9jc10oaHR0cDovL2Rldi5teXNxbC5jb20vZG9jL3JlZm1hbi81LjcvZW4vb3B0aW1pemUtdGFibGUuaHRtbCkKCSAqIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGBPUFRJTUlaRSBUQUJMRWAgc3RhdGVtZW50LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kYnVzZXI9PHZhbHVlPl0KCSAqIDogVXNlcm5hbWUgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsY2hlY2suIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRXh0cmEgYXJndW1lbnRzIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gW1JlZmVyIHRvIG15c3FsY2hlY2sgZG9jc10oaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9lbi9teXNxbGNoZWNrLmh0bWwpLgoJICoKCSAqIFstLWRlZmF1bHRzXQoJICogOiBMb2FkcyB0aGUgZW52aXJvbm1lbnQncyBNeVNRTCBvcHRpb24gZmlsZXMuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gc2tpcCBsb2FkaW5nIHRoZW0gdG8gYXZvaWQgZmFpbHVyZXMgZHVlIHRvIG1pc2NvbmZpZ3VyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBkYiBvcHRpbWl6ZQoJICogICAgIFN1Y2Nlc3M6IERhdGFiYXNlIG9wdGltaXplZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9wdGltaXplKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb21tYW5kID0gc3ByaW50ZiggJy91c3IvYmluL2VudiBteXNxbGNoZWNrJXMgJXMnLCAkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApLCAnJXMnICk7CgkJV1BfQ0xJOjpkZWJ1ZyggIlJ1bm5pbmcgc2hlbGwgY29tbWFuZDogeyRjb21tYW5kfSIsICdkYicgKTsKCgkJJGFzc29jX2FyZ3NbJ29wdGltaXplJ10gPSB0cnVlOwoJCXNlbGY6OnJ1bigKCQkJVXRpbHNcZXNjX2NtZCggJGNvbW1hbmQsIERCX05BTUUgKSwKCQkJJGFzc29jX2FyZ3MKCQkpOwoKCQlXUF9DTEk6OmRlYnVnKCAnQXNzb2NpYXRpdmUgYXJndW1lbnRzOiAnIC4ganNvbl9lbmNvZGUoICRhc3NvY19hcmdzICksICdkYicgKTsKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEYXRhYmFzZSBvcHRpbWl6ZWQuJyApOwoJfQoKCS8qKgoJICogUmVwYWlycyB0aGUgZGF0YWJhc2UuCgkgKgoJICogUnVucyBgbXlzcWxjaGVja2AgdXRpbGl0eSB3aXRoIGAtLXJlcGFpcj10cnVlYCB1c2luZyBgREJfSE9TVGAsCgkgKiBgREJfTkFNRWAsIGBEQl9VU0VSYCBhbmQgYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscwoJICogc3BlY2lmaWVkIGluIHdwLWNvbmZpZy5waHAuCgkgKgoJICogW1NlZSBkb2NzXShodHRwOi8vZGV2Lm15c3FsLmNvbS9kb2MvcmVmbWFuLzUuNy9lbi9yZXBhaXItdGFibGUuaHRtbCkgZm9yCgkgKiBtb3JlIGRldGFpbHMgb24gdGhlIGBSRVBBSVIgVEFCTEVgIHN0YXRlbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWxjaGVjay4gRGVmYXVsdHMgdG8gREJfVVNFUi4KCSAqCgkgKiBbLS1kYnBhc3M9PHZhbHVlPl0KCSAqIDogUGFzc3dvcmQgdG8gcGFzcyB0byBteXNxbGNoZWNrLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIG15c3FsY2hlY2suIFtSZWZlciB0byBteXNxbGNoZWNrIGRvY3NdKGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvZW4vbXlzcWxjaGVjay5odG1sKS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgcmVwYWlyCgkgKiAgICAgU3VjY2VzczogRGF0YWJhc2UgcmVwYWlyZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXBhaXIoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbW1hbmQgPSBzcHJpbnRmKCAnL3Vzci9iaW4vZW52IG15c3FsY2hlY2slcyAlcycsICR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICksICclcycgKTsKCQlXUF9DTEk6OmRlYnVnKCAiUnVubmluZyBzaGVsbCBjb21tYW5kOiB7JGNvbW1hbmR9IiwgJ2RiJyApOwoKCQkkYXNzb2NfYXJnc1sncmVwYWlyJ10gPSB0cnVlOwoJCXNlbGY6OnJ1bigKCQkJVXRpbHNcZXNjX2NtZCggJGNvbW1hbmQsIERCX05BTUUgKSwKCQkJJGFzc29jX2FyZ3MKCQkpOwoKCQlXUF9DTEk6OmRlYnVnKCAnQXNzb2NpYXRpdmUgYXJndW1lbnRzOiAnIC4ganNvbl9lbmNvZGUoICRhc3NvY19hcmdzICksICdkYicgKTsKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEYXRhYmFzZSByZXBhaXJlZC4nICk7Cgl9CgoJLyoqCgkgKiBPcGVucyBhIE15U1FMIGNvbnNvbGUgdXNpbmcgY3JlZGVudGlhbHMgZnJvbSB3cC1jb25maWcucGhwCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWRhdGFiYXNlPTxkYXRhYmFzZT5dCgkgKiA6IFVzZSBhIHNwZWNpZmljIGRhdGFiYXNlLiBEZWZhdWx0cyB0byBEQl9OQU1FLgoJICoKCSAqIFstLWRlZmF1bHQtY2hhcmFjdGVyLXNldD08Y2hhcmFjdGVyLXNldD5dCgkgKiA6IFVzZSBhIHNwZWNpZmljIGNoYXJhY3RlciBzZXQuIERlZmF1bHRzIHRvIERCX0NIQVJTRVQgd2hlbiBkZWZpbmVkLgoJICoKCSAqIFstLWRidXNlcj08dmFsdWU+XQoJICogOiBVc2VybmFtZSB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsLiBEZWZhdWx0cyB0byBEQl9QQVNTV09SRC4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEV4dHJhIGFyZ3VtZW50cyB0byBwYXNzIHRvIG15c3FsLiBbUmVmZXIgdG8gbXlzcWwgZG9jc10oaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9lbi9teXNxbC1jb21tYW5kLW9wdGlvbnMuaHRtbCkuCgkgKgoJICogWy0tZGVmYXVsdHNdCgkgKiA6IExvYWRzIHRoZSBlbnZpcm9ubWVudCdzIE15U1FMIG9wdGlvbiBmaWxlcy4gRGVmYXVsdCBiZWhhdmlvciBpcyB0byBza2lwIGxvYWRpbmcgdGhlbSB0byBhdm9pZCBmYWlsdXJlcyBkdWUgdG8gbWlzY29uZmlndXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIE9wZW4gTXlTUUwgY29uc29sZQoJICogICAgICQgd3AgZGIgY2xpCgkgKiAgICAgbXlzcWw+CgkgKgoJICogQGFsaWFzIGNvbm5lY3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNsaSggJF8sICRhc3NvY19hcmdzICkgewoKCQkkY29tbWFuZCA9IHNwcmludGYoICcvdXNyL2Jpbi9lbnYgbXlzcWwlcyAtLW5vLWF1dG8tcmVoYXNoJywgJHRoaXMtPmdldF9kZWZhdWx0c19mbGFnX3N0cmluZyggJGFzc29jX2FyZ3MgKSApOwoJCVdQX0NMSTo6ZGVidWcoICJSdW5uaW5nIHNoZWxsIGNvbW1hbmQ6IHskY29tbWFuZH0iLCAnZGInICk7CgoJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ2RhdGFiYXNlJ10gKSApIHsKCQkJJGFzc29jX2FyZ3NbJ2RhdGFiYXNlJ10gPSBEQl9OQU1FOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgkJc2VsZjo6cnVuKCAkY29tbWFuZCwgJGFzc29jX2FyZ3MsIG51bGwsIHRydWUgKTsKCX0KCgkvKioKCSAqIEV4ZWN1dGVzIGEgU1FMIHF1ZXJ5IGFnYWluc3QgdGhlIGRhdGFiYXNlLgoJICoKCSAqIEV4ZWN1dGVzIGFuIGFyYml0cmFyeSBTUUwgcXVlcnkgdXNpbmcgYERCX0hPU1RgLCBgREJfTkFNRWAsIGBEQl9VU0VSYAoJICogIGFuZCBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHNxbD5dCgkgKiA6IEEgU1FMIHF1ZXJ5LiBJZiBub3QgcGFzc2VkLCB3aWxsIHRyeSB0byByZWFkIGZyb20gU1RESU4uCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRXh0cmEgYXJndW1lbnRzIHRvIHBhc3MgdG8gbXlzcWwuIFtSZWZlciB0byBteXNxbCBkb2NzXShodHRwczovL2Rldi5teXNxbC5jb20vZG9jL2VuL215c3FsLWNvbW1hbmQtb3B0aW9ucy5odG1sKS4KCSAqCgkgKiBbLS1kZWZhdWx0c10KCSAqIDogTG9hZHMgdGhlIGVudmlyb25tZW50J3MgTXlTUUwgb3B0aW9uIGZpbGVzLiBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHNraXAgbG9hZGluZyB0aGVtIHRvIGF2b2lkIGZhaWx1cmVzIGR1ZSB0byBtaXNjb25maWd1cmF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRXhlY3V0ZSBhIHF1ZXJ5IHN0b3JlZCBpbiBhIGZpbGUKCSAqICAgICAkIHdwIGRiIHF1ZXJ5IDwgZGVidWcuc3FsCgkgKgoJICogICAgICMgQ2hlY2sgYWxsIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UKCSAqICAgICAkIHdwIGRiIHF1ZXJ5ICJDSEVDSyBUQUJMRSAkKHdwIGRiIHRhYmxlcyB8IHBhc3RlIC1zIC1kLCAtKTsiCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IFRhYmxlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPcCAgICB8IE1zZ190eXBlIHwgTXNnX3RleHQgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfdXNlcnMgICAgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF91c2VybWV0YSAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX3Bvc3RzICAgICAgICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfY29tbWVudHMgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF9saW5rcyAgICAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX29wdGlvbnMgICAgICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfcG9zdG1ldGEgICAgICAgICAgIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF90ZXJtcyAgICAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX3Rlcm1fdGF4b25vbXkgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgfCB3b3JkcHJlc3NfZGJhc2Uud3BfdGVybV9yZWxhdGlvbnNoaXBzIHwgY2hlY2sgfCBzdGF0dXMgICB8IE9LICAgICAgIHwKCSAqICAgICB8IHdvcmRwcmVzc19kYmFzZS53cF90ZXJtbWV0YSAgICAgICAgICAgfCBjaGVjayB8IHN0YXR1cyAgIHwgT0sgICAgICAgfAoJICogICAgIHwgd29yZHByZXNzX2RiYXNlLndwX2NvbW1lbnRtZXRhICAgICAgICB8IGNoZWNrIHwgc3RhdHVzICAgfCBPSyAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBQYXNzIGV4dHJhIGFyZ3VtZW50cyB0aHJvdWdoIHRvIE15U1FMCgkgKiAgICAgJCB3cCBkYiBxdWVyeSAnU0VMRUNUICogRlJPTSB3cF9vcHRpb25zIFdIRVJFIG9wdGlvbl9uYW1lPSJob21lIicgLS1za2lwLWNvbHVtbi1uYW1lcwoJICogICAgICstLS0rLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLSsKCSAqICAgICB8IDIgfCBob21lIHwgaHR0cDovL3dvcmRwcmVzcy1kZXZlbG9wLmRldiB8IHllcyB8CgkgKiAgICAgKy0tLSstLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tKwoJICovCglwdWJsaWMgZnVuY3Rpb24gcXVlcnkoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvbW1hbmQgPSBzcHJpbnRmKCAnL3Vzci9iaW4vZW52IG15c3FsJXMgLS1uby1hdXRvLXJlaGFzaCcsICR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkgKTsKCQlXUF9DTEk6OmRlYnVnKCAiUnVubmluZyBzaGVsbCBjb21tYW5kOiB7JGNvbW1hbmR9IiwgJ2RiJyApOwoKCQkkYXNzb2NfYXJnc1snZGF0YWJhc2UnXSA9IERCX05BTUU7CgoJCS8vIFRoZSBxdWVyeSBtaWdodCBjb21lIGZyb20gU1RESU4uCgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICkgewoJCQkkYXNzb2NfYXJnc1snZXhlY3V0ZSddID0gJGFyZ3NbMF07CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZXhlY3V0ZSddICkgKSB7CgkJCS8vIEVuc3VyZSB0aGF0IHRoZSBTUUwgbW9kZSBpcyBjb21wYXRpYmxlIHdpdGggV1BEQi4KCQkJJGFzc29jX2FyZ3NbJ2V4ZWN1dGUnXSA9ICR0aGlzLT5nZXRfc3FsX21vZGVfcXVlcnkoICRhc3NvY19hcmdzICkgLiAkYXNzb2NfYXJnc1snZXhlY3V0ZSddOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgkJc2VsZjo6cnVuKCAkY29tbWFuZCwgJGFzc29jX2FyZ3MgKTsKCX0KCgkvKioKCSAqIEV4cG9ydHMgdGhlIGRhdGFiYXNlIHRvIGEgZmlsZSBvciB0byBTVERPVVQuCgkgKgoJICogUnVucyBgbXlzcWxkdW1wYCB1dGlsaXR5IHVzaW5nIGBEQl9IT1NUYCwgYERCX05BTUVgLCBgREJfVVNFUmAgYW5kCgkgKiBgREJfUEFTU1dPUkRgIGRhdGFiYXNlIGNyZWRlbnRpYWxzIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLiBBY2NlcHRzIGFueSB2YWxpZCBgbXlzcWxkdW1wYCBmbGFncy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxmaWxlPl0KCSAqIDogVGhlIG5hbWUgb2YgdGhlIFNRTCBmaWxlIHRvIGV4cG9ydC4gSWYgJy0nLCB0aGVuIG91dHB1dHMgdG8gU1RET1VULiBJZgoJICogb21pdHRlZCwgaXQgd2lsbCBiZSAne2RibmFtZX0te1ktbS1kfS17cmFuZG9tLWhhc2h9LnNxbCcuCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWxkdW1wLiBEZWZhdWx0cyB0byBEQl9VU0VSLgoJICoKCSAqIFstLWRicGFzcz08dmFsdWU+XQoJICogOiBQYXNzd29yZCB0byBwYXNzIHRvIG15c3FsZHVtcC4gRGVmYXVsdHMgdG8gREJfUEFTU1dPUkQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byBteXNxbGR1bXAuIFtSZWZlciB0byBteXNxbGR1bXAgZG9jc10oaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9lbi9teXNxbGR1bXAuaHRtbCNteXNxbGR1bXAtb3B0aW9uLXN1bW1hcnkpLgoJICoKCSAqIFstLXRhYmxlcz08dGFibGVzPl0KCSAqIDogVGhlIGNvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHNwZWNpZmljIHRhYmxlcyB0byBleHBvcnQuIEV4Y2x1ZGluZyB0aGlzIHBhcmFtZXRlciB3aWxsIGV4cG9ydCBhbGwgdGFibGVzIGluIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBbLS1leGNsdWRlX3RhYmxlcz08dGFibGVzPl0KCSAqIDogVGhlIGNvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHNwZWNpZmljIHRhYmxlcyB0aGF0IHNob3VsZCBiZSBza2lwcGVkIGZyb20gZXhwb3J0aW5nLiBFeGNsdWRpbmcgdGhpcyBwYXJhbWV0ZXIgd2lsbCBleHBvcnQgYWxsIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UuCgkgKgoJICogWy0taW5jbHVkZS10YWJsZXNwYWNlc10KCSAqIDogU2tpcHMgYWRkaW5nIHRoZSBkZWZhdWx0IC0tbm8tdGFibGVzcGFjZXMgb3B0aW9uIHRvIG15c3FsZHVtcC4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBmaWxlbmFtZSBmb3IgdGhlIGV4cG9ydGVkIGRhdGFiYXNlLgoJICoKCSAqIFstLWRlZmF1bHRzXQoJICogOiBMb2FkcyB0aGUgZW52aXJvbm1lbnQncyBNeVNRTCBvcHRpb24gZmlsZXMuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gc2tpcCBsb2FkaW5nIHRoZW0gdG8gYXZvaWQgZmFpbHVyZXMgZHVlIHRvIG1pc2NvbmZpZ3VyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBFeHBvcnQgZGF0YWJhc2Ugd2l0aCBkcm9wIHF1ZXJ5IGluY2x1ZGVkCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS1hZGQtZHJvcC10YWJsZQoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIEV4cG9ydCBjZXJ0YWluIHRhYmxlcwoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tdGFibGVzPXdwX29wdGlvbnMsd3BfdXNlcnMKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBFeHBvcnQgYWxsIHRhYmxlcyBtYXRjaGluZyBhIHdpbGRjYXJkCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS10YWJsZXM9JCh3cCBkYiB0YWJsZXMgJ3dwX3VzZXIqJyAtLWZvcm1hdD1jc3YpCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgRXhwb3J0IGFsbCB0YWJsZXMgbWF0Y2hpbmcgcHJlZml4CgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS10YWJsZXM9JCh3cCBkYiB0YWJsZXMgLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4IC0tZm9ybWF0PWNzdikKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBFeHBvcnQgY2VydGFpbiBwb3N0cyB3aXRob3V0IGNyZWF0ZSB0YWJsZSBzdGF0ZW1lbnRzCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS1uby1jcmVhdGUtaW5mbz10cnVlIC0tdGFibGVzPXdwX3Bvc3RzIC0td2hlcmU9IklEIGluICgxMDAsMTAxLDEwMikiCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgRXhwb3J0IHJlbGF0aW5nIG1ldGEgZm9yIGNlcnRhaW4gcG9zdHMgd2l0aG91dCBjcmVhdGUgdGFibGUgc3RhdGVtZW50cwoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tbm8tY3JlYXRlLWluZm89dHJ1ZSAtLXRhYmxlcz13cF9wb3N0bWV0YSAtLXdoZXJlPSJwb3N0X2lkIGluICgxMDAsMTAxLDEwMikiCgkgKiAgICAgU3VjY2VzczogRXhwb3J0ZWQgdG8gJ3dvcmRwcmVzc19kYmFzZS1kYjcyYmI1LnNxbCcuCgkgKgoJICogICAgICMgU2tpcCBjZXJ0YWluIHRhYmxlcyBmcm9tIHRoZSBleHBvcnRlZCBkYXRhYmFzZQoJICogICAgICQgd3AgZGIgZXhwb3J0IC0tZXhjbHVkZV90YWJsZXM9d3Bfb3B0aW9ucyx3cF91c2VycwoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIFNraXAgYWxsIHRhYmxlcyBtYXRjaGluZyBhIHdpbGRjYXJkIGZyb20gdGhlIGV4cG9ydGVkIGRhdGFiYXNlCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS1leGNsdWRlX3RhYmxlcz0kKHdwIGRiIHRhYmxlcyAnd3BfdXNlcionIC0tZm9ybWF0PWNzdikKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byAnd29yZHByZXNzX2RiYXNlLWRiNzJiYjUuc3FsJy4KCSAqCgkgKiAgICAgIyBTa2lwIGFsbCB0YWJsZXMgbWF0Y2hpbmcgcHJlZml4IGZyb20gdGhlIGV4cG9ydGVkIGRhdGFiYXNlCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS1leGNsdWRlX3RhYmxlcz0kKHdwIGRiIHRhYmxlcyAtLWFsbC10YWJsZXMtd2l0aC1wcmVmaXggLS1mb3JtYXQ9Y3N2KQoJICogICAgIFN1Y2Nlc3M6IEV4cG9ydGVkIHRvICd3b3JkcHJlc3NfZGJhc2UtZGI3MmJiNS5zcWwnLgoJICoKCSAqICAgICAjIEV4cG9ydCBkYXRhYmFzZSB0byBTVERPVVQuCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLQoJICogICAgIC0tIE15U1FMIGR1bXAgMTAuMTMgIERpc3RyaWIgNS43LjE5LCBmb3Igb3N4MTAuMTIgKHg4Nl82NCkKCSAqICAgICAtLQoJICogICAgIC0tIEhvc3Q6IGxvY2FsaG9zdCAgICBEYXRhYmFzZTogd3BkZXYKCSAqICAgICAtLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCSAqICAgICAtLSBTZXJ2ZXIgdmVyc2lvbiAgICA1LjcuMTkKCSAqICAgICAuLi4KCSAqCgkgKiBAYWxpYXMgZHVtcAoJICovCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGVtcHR5KCAkYXJnc1swXSApICkgewoJCQkkcmVzdWx0X2ZpbGUgPSAkYXJnc1swXTsKCQl9IGVsc2UgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnJhbmRfbXRfcmFuZCAtLSBXb3JkUHJlc3MgaXMgbm90IGxvYWRlZC4KCQkJJGhhc2ggICAgICAgID0gc3Vic3RyKCBtZDUoIG10X3JhbmQoKSApLCAwLCA3ICk7CgkJCSRyZXN1bHRfZmlsZSA9IHNwcmludGYoICclcy0lcy0lcy5zcWwnLCBEQl9OQU1FLCBkYXRlKCAnWS1tLWQnICksICRoYXNoICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCgkJfQoJCSRzdGRvdXQgICAgPSAoICctJyA9PT0gJHJlc3VsdF9maWxlICk7CgkJJHBvcmNlbGFpbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKTsKCgkJLy8gQmFpbCBpZiBib3RoIHBvcmNlbGFpbiBhbmQgU1RET1VUIGFyZSBzZXQuCgkJaWYgKCAkc3Rkb3V0ICYmICRwb3JjZWxhaW4gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQb3JjZWxhaW4gaXMgbm90IGFsbG93ZWQgd2hlbiBvdXRwdXQgbW9kZSBpcyBTVERPVVQuJyApOwoJCX0KCgkJaWYgKCAhICRzdGRvdXQgKSB7CgkJCSRhc3NvY19hcmdzWydyZXN1bHQtZmlsZSddID0gJHJlc3VsdF9maWxlOwoJCX0KCgkJJG15c3FsZHVtcF9iaW5hcnkgPSBVdGlsc1xmb3JjZV9lbnZfb25fbml4X3N5c3RlbXMoICdteXNxbGR1bXAnICk7CgoJCSRzdXBwb3J0X2NvbHVtbl9zdGF0aXN0aWNzID0gZXhlYyggJG15c3FsZHVtcF9iaW5hcnkgLiAnIC0taGVscCB8IGdyZXAgImNvbHVtbi1zdGF0aXN0aWNzIicgKTsKCgkJJGluaXRpYWxfY29tbWFuZCA9IHNwcmludGYoICJ7JG15c3FsZHVtcF9iaW5hcnl9JXMgIiwgJHRoaXMtPmdldF9kZWZhdWx0c19mbGFnX3N0cmluZyggJGFzc29jX2FyZ3MgKSApOwoJCVdQX0NMSTo6ZGVidWcoICJSdW5uaW5nIGluaXRpYWwgc2hlbGwgY29tbWFuZDogeyRpbml0aWFsX2NvbW1hbmR9IiwgJ2RiJyApOwoKCQkkZGVmYXVsdF9hcmd1bWVudHMgPSBbICclcycgXTsKCgkJaWYgKCAkc3VwcG9ydF9jb2x1bW5fc3RhdGlzdGljcyApIHsKCQkJJGRlZmF1bHRfYXJndW1lbnRzW10gPSAnLS1za2lwLWNvbHVtbi1zdGF0aXN0aWNzJzsKCQl9CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbmNsdWRlLXRhYmxlc3BhY2VzJywgZmFsc2UgKSApIHsKCQkJJGRlZmF1bHRfYXJndW1lbnRzW10gPSAnLS1uby10YWJsZXNwYWNlcyc7CgkJfQoKCQkkY29tbWFuZCA9ICRpbml0aWFsX2NvbW1hbmQgLiBpbXBsb2RlKCAnICcsICRkZWZhdWx0X2FyZ3VtZW50cyApOwoKCQkkY29tbWFuZF9lc2NfYXJncyA9IFsgREJfTkFNRSBdOwoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndGFibGVzJ10gKSApIHsKCQkJJHRhYmxlcyA9IGV4cGxvZGUoICcsJywgdHJpbSggJGFzc29jX2FyZ3NbJ3RhYmxlcyddLCAnLCcgKSApOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ3RhYmxlcyddICk7CgkJCSRjb21tYW5kIC49ICcgLS10YWJsZXMnOwoJCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgkJCQkkY29tbWFuZCAgICAgICAgICAgLj0gJyAlcyc7CgkJCQkkY29tbWFuZF9lc2NfYXJnc1tdID0gdHJpbSggJHRhYmxlICk7CgkJCX0KCQl9CgoJCSRleGNsdWRlX3RhYmxlcyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2V4Y2x1ZGVfdGFibGVzJyApOwoJCWlmICggaXNzZXQoICRleGNsdWRlX3RhYmxlcyApICkgewoJCQkkdGFibGVzID0gZXhwbG9kZSggJywnLCB0cmltKCAkYXNzb2NfYXJnc1snZXhjbHVkZV90YWJsZXMnXSwgJywnICkgKTsKCQkJdW5zZXQoICRhc3NvY19hcmdzWydleGNsdWRlX3RhYmxlcyddICk7CgkJCWZvcmVhY2ggKCAkdGFibGVzIGFzICR0YWJsZSApIHsKCQkJCSRjb21tYW5kICAgICAgICAgICAuPSAnIC0taWdub3JlLXRhYmxlJzsKCQkJCSRjb21tYW5kICAgICAgICAgICAuPSAnICVzJzsKCQkJCSRjb21tYW5kX2VzY19hcmdzW10gPSB0cmltKCBEQl9OQU1FIC4gJy4nIC4gJHRhYmxlICk7CgkJCX0KCQl9CgoJCSRlc2NhcGVkX2NvbW1hbmQgPSBjYWxsX3VzZXJfZnVuY19hcnJheSggJ1xXUF9DTElcVXRpbHNcZXNjX2NtZCcsIGFycmF5X21lcmdlKCBbICRjb21tYW5kIF0sICRjb21tYW5kX2VzY19hcmdzICkgKTsKCgkJLy8gUmVtb3ZlIHBhcmFtZXRlcnMgbm90IG5lZWRlZCBmb3IgU1FMIHJ1bi4KCQl1bnNldCggJGFzc29jX2FyZ3NbJ3BvcmNlbGFpbiddICk7CgoJCVdQX0NMSTo6ZGVidWcoICdBc3NvY2lhdGl2ZSBhcmd1bWVudHM6ICcgLiBqc29uX2VuY29kZSggJGFzc29jX2FyZ3MgKSwgJ2RiJyApOwoJCXNlbGY6OnJ1biggJGVzY2FwZWRfY29tbWFuZCwgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCAkcG9yY2VsYWluICkgewoJCQlXUF9DTEk6OmxpbmUoICRyZXN1bHRfZmlsZSApOwoJCX0gZWxzZWlmICggISAkc3Rkb3V0ICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICJFeHBvcnRlZCB0byAnJXMnLiIsICRyZXN1bHRfZmlsZSApICk7CgkJfQoJfQoKCS8qKgoJICogSW1wb3J0cyBhIGRhdGFiYXNlIGZyb20gYSBmaWxlIG9yIGZyb20gU1RESU4uCgkgKgoJICogUnVucyBTUUwgcXVlcmllcyB1c2luZyBgREJfSE9TVGAsIGBEQl9OQU1FYCwgYERCX1VTRVJgIGFuZAoJICogYERCX1BBU1NXT1JEYCBkYXRhYmFzZSBjcmVkZW50aWFscyBzcGVjaWZpZWQgaW4gd3AtY29uZmlnLnBocC4gVGhpcwoJICogZG9lcyBub3QgY3JlYXRlIGRhdGFiYXNlIGJ5IGl0c2VsZiBhbmQgb25seSBwZXJmb3JtcyB3aGF0ZXZlciB0YXNrcyBhcmUKCSAqIGRlZmluZWQgaW4gdGhlIFNRTC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxmaWxlPl0KCSAqIDogVGhlIG5hbWUgb2YgdGhlIFNRTCBmaWxlIHRvIGltcG9ydC4gSWYgJy0nLCB0aGVuIHJlYWRzIGZyb20gU1RESU4uIElmIG9taXR0ZWQsIGl0IHdpbGwgbG9vayBmb3IgJ3tkYm5hbWV9LnNxbCcuCgkgKgoJICogWy0tZGJ1c2VyPTx2YWx1ZT5dCgkgKiA6IFVzZXJuYW1lIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1VTRVIuCgkgKgoJICogWy0tZGJwYXNzPTx2YWx1ZT5dCgkgKiA6IFBhc3N3b3JkIHRvIHBhc3MgdG8gbXlzcWwuIERlZmF1bHRzIHRvIERCX1BBU1NXT1JELgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRXh0cmEgYXJndW1lbnRzIHRvIHBhc3MgdG8gbXlzcWwuIFtSZWZlciB0byBteXNxbCBiaW5hcnkgZG9jc10oaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vOC4wL2VuL215c3FsLWNvbW1hbmQtb3B0aW9ucy5odG1sKS4KCSAqCgkgKiBbLS1za2lwLW9wdGltaXphdGlvbl0KCSAqIDogV2hlbiB1c2luZyBhbiBTUUwgZmlsZSwgZG8gbm90IGluY2x1ZGUgc3BlZWQgb3B0aW1pemF0aW9uIHN1Y2ggYXMgZGlzYWJsaW5nIGF1dG8tY29tbWl0IGFuZCBrZXkgY2hlY2tzLgoJICoKCSAqIFstLWRlZmF1bHRzXQoJICogOiBMb2FkcyB0aGUgZW52aXJvbm1lbnQncyBNeVNRTCBvcHRpb24gZmlsZXMuIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gc2tpcCBsb2FkaW5nIHRoZW0gdG8gYXZvaWQgZmFpbHVyZXMgZHVlIHRvIG1pc2NvbmZpZ3VyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbXBvcnQgTXlTUUwgZnJvbSBhIGZpbGUuCgkgKiAgICAgJCB3cCBkYiBpbXBvcnQgd29yZHByZXNzX2RiYXNlLnNxbAoJICogICAgIFN1Y2Nlc3M6IEltcG9ydGVkIGZyb20gJ3dvcmRwcmVzc19kYmFzZS5zcWwnLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaW1wb3J0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAhIGVtcHR5KCAkYXJnc1swXSApICkgewoJCQkkcmVzdWx0X2ZpbGUgPSAkYXJnc1swXTsKCQl9IGVsc2UgewoJCQkkcmVzdWx0X2ZpbGUgPSBzcHJpbnRmKCAnJXMuc3FsJywgREJfTkFNRSApOwoJCX0KCgkJJG15c3FsX2FyZ3MgPSBbCgkJCSdkYXRhYmFzZScgPT4gREJfTkFNRSwKCQldOwoJCSRteXNxbF9hcmdzID0gYXJyYXlfbWVyZ2UoIHNlbGY6OmdldF9kYnVzZXJfZGJwYXNzX2FyZ3MoICRhc3NvY19hcmdzICksICRteXNxbF9hcmdzICk7CgoJCWlmICggJy0nICE9PSAkcmVzdWx0X2ZpbGUgKSB7CgkJCWlmICggISBpc19yZWFkYWJsZSggJHJlc3VsdF9maWxlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnSW1wb3J0IGZpbGUgbWlzc2luZyBvciBub3QgcmVhZGFibGU6ICVzJywgJHJlc3VsdF9maWxlICkgKTsKCQkJfQoKCQkJJHF1ZXJ5ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1vcHRpbWl6YXRpb24nICkKCQkJCT8gJ1NPVVJDRSAlczsnCgkJCQk6ICdTRVQgYXV0b2NvbW1pdCA9IDA7IFNFVCB1bmlxdWVfY2hlY2tzID0gMDsgU0VUIGZvcmVpZ25fa2V5X2NoZWNrcyA9IDA7IFNPVVJDRSAlczsgQ09NTUlUOyc7CgoJCQkkcXVlcnkgPSAkdGhpcy0+Z2V0X3NxbF9tb2RlX3F1ZXJ5KCAkYXNzb2NfYXJncyApIC4gJHF1ZXJ5OwoKCQkJJG15c3FsX2FyZ3NbJ2V4ZWN1dGUnXSA9IHNwcmludGYoICRxdWVyeSwgJHJlc3VsdF9maWxlICk7CgkJfSBlbHNlIHsKCQkJJHJlc3VsdF9maWxlID0gJ1NURElOJzsKCQl9CgkJLy8gQ2hlY2sgaWYgYW55IG15c3FsIG9wdGlvbiBwYXNzLgoJCSRteXNxbF9hcmdzID0gYXJyYXlfbWVyZ2UoICRteXNxbF9hcmdzLCBzZWxmOjpnZXRfbXlzcWxfYXJncyggJGFzc29jX2FyZ3MgKSApOwoKCQkkY29tbWFuZCA9IHNwcmludGYoICcvdXNyL2Jpbi9lbnYgbXlzcWwlcyAtLW5vLWF1dG8tcmVoYXNoJywgJHRoaXMtPmdldF9kZWZhdWx0c19mbGFnX3N0cmluZyggJGFzc29jX2FyZ3MgKSApOwoJCVdQX0NMSTo6ZGVidWcoICJSdW5uaW5nIHNoZWxsIGNvbW1hbmQ6IHskY29tbWFuZH0iLCAnZGInICk7CgkJV1BfQ0xJOjpkZWJ1ZyggJ0Fzc29jaWF0aXZlIGFyZ3VtZW50czogJyAuIGpzb25fZW5jb2RlKCAkYXNzb2NfYXJncyApLCAnZGInICk7CgoJCXNlbGY6OnJ1biggJGNvbW1hbmQsICRteXNxbF9hcmdzICk7CgoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggIkltcG9ydGVkIGZyb20gJyVzJy4iLCAkcmVzdWx0X2ZpbGUgKSApOwoJfQoKCS8qKgoJICogTGlzdHMgdGhlIGRhdGFiYXNlIHRhYmxlcy4KCSAqCgkgKiBEZWZhdWx0cyB0byBhbGwgdGFibGVzIHJlZ2lzdGVyZWQgdG8gdGhlICR3cGRiIGRhdGFiYXNlIGhhbmRsZXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGFibGU+Li4uXQoJICogOiBMaXN0IHRhYmxlcyBiYXNlZCBvbiB3aWxkY2FyZCBzZWFyY2gsIGUuZy4gJ3dwXypfb3B0aW9ucycgb3IgJ3dwX3Bvc3Q/Jy4KCSAqCgkgKiBbLS1zY29wZT08c2NvcGU+XQoJICogOiBDYW4gYmUgYWxsLCBnbG9iYWwsIG1zX2dsb2JhbCwgYmxvZywgb3Igb2xkIHRhYmxlcy4gRGVmYXVsdHMgdG8gYWxsLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IExpc3QgYWxsIHRoZSB0YWJsZXMgaW4gYSBtdWx0aXNpdGUgaW5zdGFsbC4KCSAqCgkgKiBbLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4XQoJICogOiBMaXN0IGFsbCB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgdGFibGUgcHJlZml4IGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE92ZXJyaWRlcyAtLW5ldHdvcmsuCgkgKgoJICogWy0tYWxsLXRhYmxlc10KCSAqIDogTGlzdCBhbGwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUgcHJlZml4LCBhbmQgZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT3ZlcnJpZGVzIC0tYWxsLXRhYmxlcy13aXRoLXByZWZpeC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogbGlzdAoJICogb3B0aW9uczoKCSAqICAgLSBsaXN0CgkgKiAgIC0gY3N2CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdGFibGVzIGZvciBhIHNpbmdsZSBzaXRlLCB3aXRob3V0IHNoYXJlZCB0YWJsZXMgbGlrZSAnd3BfdXNlcnMnCgkgKiAgICAgJCB3cCBkYiB0YWJsZXMgLS1zY29wZT1ibG9nIC0tdXJsPXN1Yi5leGFtcGxlLmNvbQoJICogICAgIHdwXzNfcG9zdHMKCSAqICAgICB3cF8zX2NvbW1lbnRzCgkgKiAgICAgd3BfM19vcHRpb25zCgkgKiAgICAgd3BfM19wb3N0bWV0YQoJICogICAgIHdwXzNfdGVybXMKCSAqICAgICB3cF8zX3Rlcm1fdGF4b25vbXkKCSAqICAgICB3cF8zX3Rlcm1fcmVsYXRpb25zaGlwcwoJICogICAgIHdwXzNfdGVybW1ldGEKCSAqICAgICB3cF8zX2NvbW1lbnRtZXRhCgkgKgoJICogICAgICMgRXhwb3J0IG9ubHkgdGFibGVzIGZvciBhIHNpbmdsZSBzaXRlCgkgKiAgICAgJCB3cCBkYiBleHBvcnQgLS10YWJsZXM9JCh3cCBkYiB0YWJsZXMgLS11cmw9c3ViLmV4YW1wbGUuY29tIC0tZm9ybWF0PWNzdikKCSAqICAgICBTdWNjZXNzOiBFeHBvcnRlZCB0byB3b3JkcHJlc3NfZGJhc2Uuc3FsCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gdGFibGVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRmb3JtYXQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JtYXQnICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWydmb3JtYXQnXSApOwoKCQlpZiAoIGVtcHR5KCAkYXJncyApICYmIGVtcHR5KCAkYXNzb2NfYXJncyApICkgewoJCQkkYXNzb2NfYXJnc1snc2NvcGUnXSA9ICdhbGwnOwoJCX0KCgkJJHRhYmxlcyA9IFV0aWxzXHdwX2dldF90YWJsZV9uYW1lcyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJCWlmICggJ2NzdicgPT09ICRmb3JtYXQgKSB7CgkJCVdQX0NMSTo6bGluZSggaW1wbG9kZSggJywnLCAkdGFibGVzICkgKTsKCQl9IGVsc2UgewoJCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICR0YWJsZSApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogRGlzcGxheXMgdGhlIGRhdGFiYXNlIG5hbWUgYW5kIHNpemUuCgkgKgoJICogRGlzcGxheSB0aGUgZGF0YWJhc2UgbmFtZSBhbmQgc2l6ZSBmb3IgYERCX05BTUVgIHNwZWNpZmllZCBpbiB3cC1jb25maWcucGhwLgoJICogVGhlIHNpemUgZGVmYXVsdHMgdG8gYSBodW1hbi1yZWFkYWJsZSBudW1iZXIuCgkgKgoJICogQXZhaWxhYmxlIHNpemUgZm9ybWF0cyBpbmNsdWRlOgoJICogKiBiIChieXRlcykKCSAqICoga2IgKGtpbG9ieXRlcykKCSAqICogbWIgKG1lZ2FieXRlcykKCSAqICogZ2IgKGdpZ2FieXRlcykKCSAqICogdGIgKHRlcmFieXRlcykKCSAqICogQiAgIChJU08gQnl0ZSBzZXR0aW5nLCB3aXRoIG5vIGNvbnZlcnNpb24pCgkgKiAqIEtCICAoSVNPIEtpbG9ieXRlIHNldHRpbmcsIHdpdGggMSBLQiAgPSAxLDAwMCBCKQoJICogKiBLaUIgKElTTyBLaWJpYnl0ZSBzZXR0aW5nLCB3aXRoIDEgS2lCID0gMSwwMjQgQikKCSAqICogTUIgIChJU08gTWVnYWJ5dGUgc2V0dGluZywgd2l0aCAxIE1CICA9IDEsMDAwIEtCKQoJICogKiBNaUIgKElTTyBNZWJpYnl0ZSBzZXR0aW5nLCB3aXRoIDEgTWlCID0gMSwwMjQgS2lCKQoJICogKiBHQiAgKElTTyBHaWdhYnl0ZSBzZXR0aW5nLCB3aXRoIDEgR0IgID0gMSwwMDAgTUIpCgkgKiAqIEdpQiAoSVNPIEdpYmlieXRlIHNldHRpbmcsIHdpdGggMSBHaUIgPSAxLDAyNCBNaUIpCgkgKiAqIFRCICAoSVNPIFRlcmFieXRlIHNldHRpbmcsIHdpdGggMSBUQiAgPSAxLDAwMCBHQikKCSAqICogVGlCIChJU08gVGViaWJ5dGUgc2V0dGluZywgd2l0aCAxIFRpQiA9IDEsMDI0IEdpQikKCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tc2l6ZV9mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IERpc3BsYXkgdGhlIGRhdGFiYXNlIHNpemUgb25seSwgYXMgYSBiYXJlIG51bWJlci4KCSAqIC0tLQoJICogb3B0aW9uczoKCSAqICAgLSBiCgkgKiAgIC0ga2IKCSAqICAgLSBtYgoJICogICAtIGdiCgkgKiAgIC0gdGIKCSAqICAgLSBCCgkgKiAgIC0gS0IKCSAqICAgLSBLaUIKCSAqICAgLSBNQgoJICogICAtIE1pQgoJICogICAtIEdCCgkgKiAgIC0gR2lCCgkgKiAgIC0gVEIKCSAqICAgLSBUaUIKCSAqIC0tLQoJICoKCSAqIFstLXRhYmxlc10KCSAqIDogRGlzcGxheSBlYWNoIHRhYmxlIG5hbWUgYW5kIHNpemUgaW5zdGVhZCBvZiB0aGUgZGF0YWJhc2Ugc2l6ZS4KCSAqCgkgKiBbLS1odW1hbi1yZWFkYWJsZV0KCSAqIDogRGlzcGxheSBkYXRhYmFzZSBzaXplcyBpbiBodW1hbiByZWFkYWJsZSBmb3JtYXRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqIFstLXNjb3BlPTxzY29wZT5dCgkgKiA6IENhbiBiZSBhbGwsIGdsb2JhbCwgbXNfZ2xvYmFsLCBibG9nLCBvciBvbGQgdGFibGVzLiBEZWZhdWx0cyB0byBhbGwuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogTGlzdCBhbGwgdGhlIHRhYmxlcyBpbiBhIG11bHRpc2l0ZSBpbnN0YWxsLgoJICoKCSAqIFstLWFsbC10YWJsZXMtd2l0aC1wcmVmaXhdCgkgKiA6IExpc3QgYWxsIHRhYmxlcyB0aGF0IG1hdGNoIHRoZSB0YWJsZSBwcmVmaXggZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT3ZlcnJpZGVzIC0tbmV0d29yay4KCSAqCgkgKiBbLS1hbGwtdGFibGVzXQoJICogOiBMaXN0IGFsbCB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlLCByZWdhcmRsZXNzIG9mIHRoZSBwcmVmaXgsIGFuZCBldmVuIGlmIG5vdCByZWdpc3RlcmVkIG9uICR3cGRiLiBPdmVycmlkZXMgLS1hbGwtdGFibGVzLXdpdGgtcHJlZml4LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgZGIgc2l6ZQoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLSsKCSAqICAgICB8IE5hbWUgICAgICAgICAgICAgIHwgU2l6ZSB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tKwoJICogICAgIHwgd29yZHByZXNzX2RlZmF1bHQgfCA2IE1CIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0rCgkgKgoJICogICAgICQgd3AgZGIgc2l6ZSAtLXRhYmxlcwoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKwoJICogICAgIHwgTmFtZSAgICAgICAgICAgICAgICAgIHwgU2l6ZSAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKwoJICogICAgIHwgd3BfdXNlcnMgICAgICAgICAgICAgIHwgNjQgS0IgfAoJICogICAgIHwgd3BfdXNlcm1ldGEgICAgICAgICAgIHwgNDggS0IgfAoJICogICAgIHwgd3BfcG9zdHMgICAgICAgICAgICAgIHwgODAgS0IgfAoJICogICAgIHwgd3BfY29tbWVudHMgICAgICAgICAgIHwgOTYgS0IgfAoJICogICAgIHwgd3BfbGlua3MgICAgICAgICAgICAgIHwgMzIgS0IgfAoJICogICAgIHwgd3Bfb3B0aW9ucyAgICAgICAgICAgIHwgMzIgS0IgfAoJICogICAgIHwgd3BfcG9zdG1ldGEgICAgICAgICAgIHwgNDggS0IgfAoJICogICAgIHwgd3BfdGVybXMgICAgICAgICAgICAgIHwgNDggS0IgfAoJICogICAgIHwgd3BfdGVybV90YXhvbm9teSAgICAgIHwgNDggS0IgfAoJICogICAgIHwgd3BfdGVybV9yZWxhdGlvbnNoaXBzIHwgMzIgS0IgfAoJICogICAgIHwgd3BfdGVybW1ldGEgICAgICAgICAgIHwgNDggS0IgfAoJICogICAgIHwgd3BfY29tbWVudG1ldGEgICAgICAgIHwgNDggS0IgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKwoJICoKCSAqICAgICAkIHdwIGRiIHNpemUgLS1zaXplX2Zvcm1hdD1iCgkgKiAgICAgNTg2NTQ3MgoJICoKCSAqICAgICAkIHdwIGRiIHNpemUgLS1zaXplX2Zvcm1hdD1rYgoJICogICAgIDU3MjgKCSAqCgkgKiAgICAgJCB3cCBkYiBzaXplIC0tc2l6ZV9mb3JtYXQ9bWIKCSAqICAgICA2CgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gc2l6ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlnbG9iYWwgJHdwZGI7CgoJCSRmb3JtYXQgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9ybWF0JyApOwoJCSRzaXplX2Zvcm1hdCAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2l6ZV9mb3JtYXQnICk7CgkJJGh1bWFuX3JlYWRhYmxlICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdodW1hbi1yZWFkYWJsZScsIGZhbHNlICk7CgkJJHRhYmxlcyAgICAgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd0YWJsZXMnICk7CgkJJHRhYmxlcyAgICAgICAgICAgICAgICAgPSAhIGVtcHR5KCAkdGFibGVzICk7CgkJJGFsbF90YWJsZXMgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwtdGFibGVzJyApOwoJCSRhbGxfdGFibGVzX3dpdGhfcHJlZml4ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsLXRhYmxlcy13aXRoLXByZWZpeCcgKTsKCgkJaWYgKCAhIGlzX251bGwoICRzaXplX2Zvcm1hdCApICYmICRodW1hbl9yZWFkYWJsZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0Nhbm5vdCB1c2UgLS1zaXplX2Zvcm1hdCBhbmQgLS1odW1hbi1yZWFkYWJsZSBhcmd1bWVudHMgYXQgdGhlIHNhbWUgdGltZS4nICk7CgkJfQoKCQl1bnNldCggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWydzaXplX2Zvcm1hdCddICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWydodW1hbi1yZWFkYWJsZSddICk7CgkJdW5zZXQoICRhc3NvY19hcmdzWyd0YWJsZXMnXSApOwoKCQlpZiAoIGVtcHR5KCAkYXJncyApICYmIGVtcHR5KCAkYXNzb2NfYXJncyApICkgewoJCQkkYXNzb2NfYXJnc1snc2NvcGUnXSA9ICdhbGwnOwoJCX0KCgkJLy8gQnVpbGQgcm93cyBmb3IgdGhlIGZvcm1hdHRlci4KCQkkcm93cyAgID0gW107CgkJJGZpZWxkcyA9IFsgJ05hbWUnLCAnU2l6ZScgXTsKCgkJJGRlZmF1bHRfdW5pdCA9ICggZW1wdHkoICRzaXplX2Zvcm1hdCApICYmICEgJGh1bWFuX3JlYWRhYmxlICkgPyAnIEInIDogJyc7CgoJCWlmICggJHRhYmxlcyB8fCAkYWxsX3RhYmxlcyB8fCAkYWxsX3RhYmxlc193aXRoX3ByZWZpeCApIHsKCgkJCS8vIEFkZCBhbGwgb2YgdGhlIHRhYmxlIHNpemVzLgoJCQlmb3JlYWNoICggVXRpbHNcd3BfZ2V0X3RhYmxlX25hbWVzKCAkYXJncywgJGFzc29jX2FyZ3MgKSBhcyAkdGFibGVfbmFtZSApIHsKCgkJCQkvLyBHZXQgdGhlIHRhYmxlIHNpemUuCgkJCQkkdGFibGVfYnl0ZXMgPSAkd3BkYi0+Z2V0X3ZhcigKCQkJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCQkJJ1NFTEVDVCBTVU0oZGF0YV9sZW5ndGggKyBpbmRleF9sZW5ndGgpIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlRBQkxFUyB3aGVyZSB0YWJsZV9zY2hlbWEgPSAlcyBhbmQgVGFibGVfTmFtZSA9ICVzIEdST1VQIEJZIFRhYmxlX05hbWUgTElNSVQgMScsCgkJCQkJCURCX05BTUUsCgkJCQkJCSR0YWJsZV9uYW1lCgkJCQkJKQoJCQkJKTsKCgkJCQkvLyBBZGQgdGhlIHRhYmxlIHNpemUgdG8gdGhlIGxpc3QuCgkJCQkkcm93c1tdID0gWwoJCQkJCSdOYW1lJyA9PiAkdGFibGVfbmFtZSwKCQkJCQknU2l6ZScgPT4gc3RydG91cHBlciggJHRhYmxlX2J5dGVzICkgLiAkZGVmYXVsdF91bml0LAoJCQkJXTsKCQkJfQoJCX0gZWxzZSB7CgoJCQkvLyBHZXQgdGhlIGRhdGFiYXNlIHNpemUuCgkJCSRkYl9ieXRlcyA9ICR3cGRiLT5nZXRfdmFyKAoJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJJ1NFTEVDVCBTVU0oZGF0YV9sZW5ndGggKyBpbmRleF9sZW5ndGgpIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlRBQkxFUyB3aGVyZSB0YWJsZV9zY2hlbWEgPSAlcyBHUk9VUCBCWSB0YWJsZV9zY2hlbWE7JywKCQkJCQlEQl9OQU1FCgkJCQkpCgkJCSk7CgoJCQkvLyBBZGQgdGhlIGRhdGFiYXNlIHNpemUgdG8gdGhlIGxpc3QuCgkJCSRyb3dzW10gPSBbCgkJCQknTmFtZScgPT4gREJfTkFNRSwKCQkJCSdTaXplJyA9PiBzdHJ0b3VwcGVyKCAkZGJfYnl0ZXMgKSAuICRkZWZhdWx0X3VuaXQsCgkJCV07CgkJfQoKCQlpZiAoICEgZW1wdHkoICRzaXplX2Zvcm1hdCApIHx8ICRodW1hbl9yZWFkYWJsZSApIHsKCQkJZm9yZWFjaCAoICRyb3dzIGFzICRpbmRleCA9PiAkcm93ICkgewoJCQkJLy8gcGhwY3M6ZGlzYWJsZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQgLS0gQmFja2ZpbGxpbmcgV1AgbmF0aXZlIGNvbnN0YW50cy4KCQkJCWlmICggISBkZWZpbmVkKCAnS0JfSU5fQllURVMnICkgKSB7CgkJCQkJZGVmaW5lKCAnS0JfSU5fQllURVMnLCAxMDI0ICk7CgkJCQl9CgkJCQlpZiAoICEgZGVmaW5lZCggJ01CX0lOX0JZVEVTJyApICkgewoJCQkJCWRlZmluZSggJ01CX0lOX0JZVEVTJywgMTAyNCAqIEtCX0lOX0JZVEVTICk7CgkJCQl9CgkJCQlpZiAoICEgZGVmaW5lZCggJ0dCX0lOX0JZVEVTJyApICkgewoJCQkJCWRlZmluZSggJ0dCX0lOX0JZVEVTJywgMTAyNCAqIE1CX0lOX0JZVEVTICk7CgkJCQl9CgkJCQlpZiAoICEgZGVmaW5lZCggJ1RCX0lOX0JZVEVTJyApICkgewoJCQkJCWRlZmluZSggJ1RCX0lOX0JZVEVTJywgMTAyNCAqIEdCX0lOX0JZVEVTICk7CgkJCQl9CgkJCQkvLyBwaHBjczplbmFibGUKCgkJCQlpZiAoICRodW1hbl9yZWFkYWJsZSApIHsKCQkJCQkkc2l6ZV9rZXkgPSBmbG9vciggbG9nKCAkcm93WydTaXplJ10gKSAvIGxvZyggMTAwMCApICk7CgkJCQkJJHNpemVzICAgID0gWyAnQicsICdLQicsICdNQicsICdHQicsICdUQicgXTsKCgkJCQkJJHNpemVfZm9ybWF0ID0gaXNzZXQoICRzaXplc1sgJHNpemVfa2V5IF0gKSA/ICRzaXplc1sgJHNpemVfa2V5IF0gOiAkc2l6ZXNbMF07CgkJCQl9CgoJCQkJLy8gRGlzcGxheSB0aGUgZGF0YWJhc2Ugc2l6ZSBhcyBhIG51bWJlci4KCQkJCXN3aXRjaCAoICRzaXplX2Zvcm1hdCApIHsKCQkJCQljYXNlICdUQic6CgkJCQkJCSRkaXZpc29yID0gcG93KCAxMDAwLCA0ICk7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdHQic6CgkJCQkJCSRkaXZpc29yID0gcG93KCAxMDAwLCAzICk7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdNQic6CgkJCQkJCSRkaXZpc29yID0gcG93KCAxMDAwLCAyICk7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdLQic6CgkJCQkJCSRkaXZpc29yID0gMTAwMDsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ3RiJzoKCQkJCQljYXNlICdUaUInOgoJCQkJCQkkZGl2aXNvciA9IFRCX0lOX0JZVEVTOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnZ2InOgoJCQkJCWNhc2UgJ0dpQic6CgkJCQkJCSRkaXZpc29yID0gR0JfSU5fQllURVM7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdtYic6CgkJCQkJY2FzZSAnTWlCJzoKCQkJCQkJJGRpdmlzb3IgPSBNQl9JTl9CWVRFUzsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ2tiJzoKCQkJCQljYXNlICdLaUInOgoJCQkJCQkkZGl2aXNvciA9IEtCX0lOX0JZVEVTOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSAnYic6CgkJCQkJY2FzZSAnQic6CgkJCQkJZGVmYXVsdDoKCQkJCQkJJGRpdmlzb3IgPSAxOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJCQkkc2l6ZV9mb3JtYXRfZGlzcGxheSA9IHByZWdfcmVwbGFjZSggJy9JQiQvdScsICdpQicsIHN0cnRvdXBwZXIoICRzaXplX2Zvcm1hdCApICk7CgoJCQkJCSRyb3dzWyAkaW5kZXggXVsnU2l6ZSddID0gY2VpbCggJHJvd1snU2l6ZSddIC8gJGRpdmlzb3IgKSAuICcgJyAuICRzaXplX2Zvcm1hdF9kaXNwbGF5OwoJCQl9CgkJfQoKCQlpZiAoICEgZW1wdHkoICRzaXplX2Zvcm1hdCApICYmICEgJHRhYmxlcyAmJiAhICRmb3JtYXQgJiYgISAkaHVtYW5fcmVhZGFibGUgJiYgdHJ1ZSAhPT0gJGFsbF90YWJsZXMgJiYgdHJ1ZSAhPT0gJGFsbF90YWJsZXNfd2l0aF9wcmVmaXggKSB7CgkJCVdQX0NMSTo6bGluZSggZmlsdGVyX3ZhciggJHJvd3NbMF1bJ1NpemUnXSwgRklMVEVSX1NBTklUSVpFX05VTUJFUl9JTlQgKSApOwoJCX0gZWxzZSB7CgkJCS8vIERpc3BsYXkgdGhlIHJvd3MuCgkJCSRhcmdzID0gWwoJCQkJJ2Zvcm1hdCcgPT4gJGZvcm1hdCwKCQkJXTsKCgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXJncywgJGZpZWxkcyApOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkcm93cyApOwoJCX0KCX0KCgkvKioKCSAqIERpc3BsYXlzIHRoZSBkYXRhYmFzZSB0YWJsZSBwcmVmaXguCgkgKgoJICogRGlzcGxheSB0aGUgZGF0YWJhc2UgdGFibGUgcHJlZml4LCBhcyBkZWZpbmVkIGJ5IHRoZSBkYXRhYmFzZSBoYW5kbGVyJ3MgaW50ZXJwcmV0YXRpb24gb2YgdGhlIGN1cnJlbnQgc2l0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGRiIHByZWZpeAoJICogICAgIHdwXwoJICoKCSAqIEB3aGVuIGFmdGVyX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByZWZpeCgpIHsKCQlnbG9iYWwgJHdwZGI7CgoJCVdQX0NMSTo6bG9nKCAkd3BkYi0+cHJlZml4ICk7Cgl9CgoJLyoqCgkgKiBGaW5kcyBhIHN0cmluZyBpbiB0aGUgZGF0YWJhc2UuCgkgKgoJICogU2VhcmNoZXMgdGhyb3VnaCBhbGwgb2YgdGhlIHRleHQgY29sdW1ucyBpbiBhIHNlbGVjdGlvbiBvZiBkYXRhYmFzZSB0YWJsZXMgZm9yIGEgZ2l2ZW4gc3RyaW5nLCBPdXRwdXRzIGNvbG9yaXplZCByZWZlcmVuY2VzIHRvIHRoZSBzdHJpbmcuCgkgKgoJICogRGVmYXVsdHMgdG8gc2VhcmNoaW5nIHRocm91Z2ggYWxsIHRhYmxlcyByZWdpc3RlcmVkIHRvICR3cGRiLiBPbiBtdWx0aXNpdGUsIHRoaXMgZGVmYXVsdCBpcyBsaW1pdGVkIHRvIHRoZSB0YWJsZXMgZm9yIHRoZSBjdXJyZW50IHNpdGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzZWFyY2g+CgkgKiA6IFN0cmluZyB0byBzZWFyY2ggZm9yLiBUaGUgc2VhcmNoIGlzIGNhc2UtaW5zZW5zaXRpdmUgYnkgZGVmYXVsdC4KCSAqCgkgKiBbPHRhYmxlcz4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHRhYmxlcyB0byBzZWFyY2ggdGhyb3VnaCBmb3IgdGhlIHN0cmluZy4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBTZWFyY2ggdGhyb3VnaCBhbGwgdGhlIHRhYmxlcyByZWdpc3RlcmVkIHRvICR3cGRiIGluIGEgbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogWy0tYWxsLXRhYmxlcy13aXRoLXByZWZpeF0KCSAqIDogU2VhcmNoIHRocm91Z2ggYWxsIHRhYmxlcyB0aGF0IG1hdGNoIHRoZSByZWdpc3RlcmVkIHRhYmxlIHByZWZpeCwgZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCBvbiAkd3BkYi4gT24gb25lIGhhbmQsIHNvbWV0aW1lcyBwbHVnaW5zIHVzZSB0YWJsZXMgd2l0aG91dCByZWdpc3RlcmluZyB0aGVtIHRvICR3cGRiLiBPbiBhbm90aGVyIGhhbmQsIHRoaXMgY291bGQgcmV0dXJuIHRhYmxlcyB5b3UgZG9uJ3QgZXhwZWN0LiBPdmVycmlkZXMgLS1uZXR3b3JrLgoJICoKCSAqIFstLWFsbC10YWJsZXNdCgkgKiA6IFNlYXJjaCB0aHJvdWdoIEFMTCB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlLCByZWdhcmRsZXNzIG9mIHRoZSBwcmVmaXgsIGFuZCBldmVuIGlmIG5vdCByZWdpc3RlcmVkIG9uICR3cGRiLiBPdmVycmlkZXMgLS1uZXR3b3JrIGFuZCAtLWFsbC10YWJsZXMtd2l0aC1wcmVmaXguCgkgKgoJICogWy0tYmVmb3JlX2NvbnRleHQ9PG51bT5dCgkgKiA6IE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGRpc3BsYXkgYmVmb3JlIHRoZSBtYXRjaC4KCSAqIC0tLQoJICogZGVmYXVsdDogNDAKCSAqIC0tLQoJICoKCSAqIFstLWFmdGVyX2NvbnRleHQ9PG51bT5dCgkgKiA6IE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGRpc3BsYXkgYWZ0ZXIgdGhlIG1hdGNoLgoJICogLS0tCgkgKiBkZWZhdWx0OiA0MAoJICogLS0tCgkgKgoJICogWy0tcmVnZXhdCgkgKiA6IFJ1bnMgdGhlIHNlYXJjaCBhcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiAod2l0aG91dCBkZWxpbWl0ZXJzKS4gVGhlIHNlYXJjaCBiZWNvbWVzIGNhc2Utc2Vuc2l0aXZlIChpLmUuIG5vIFBDUkUgZmxhZ3MgYXJlIGFkZGVkKS4gRGVsaW1pdGVycyBtdXN0IGJlIGVzY2FwZWQgaWYgdGhleSBvY2N1ciBpbiB0aGUgZXhwcmVzc2lvbi4gQmVjYXVzZSB0aGUgc2VhcmNoIGlzIHJ1biBvbiBpbmRpdmlkdWFsIGNvbHVtbnMsIHlvdSBjYW4gdXNlIHRoZSBgXmAgYW5kIGAkYCB0b2tlbnMgdG8gbWFyayB0aGUgc3RhcnQgYW5kIGVuZCBvZiBhIG1hdGNoLCByZXNwZWN0aXZlbHkuCgkgKgoJICogWy0tcmVnZXgtZmxhZ3M9PHJlZ2V4LWZsYWdzPl0KCSAqIDogUGFzcyBQQ1JFIG1vZGlmaWVycyB0byB0aGUgcmVnZXggc2VhcmNoIChlLmcuICdpJyBmb3IgY2FzZS1pbnNlbnNpdGl2aXR5KS4KCSAqCgkgKiBbLS1yZWdleC1kZWxpbWl0ZXI9PHJlZ2V4LWRlbGltaXRlcj5dCgkgKiA6IFRoZSBkZWxpbWl0ZXIgdG8gdXNlIGZvciB0aGUgcmVnZXguIEl0IG11c3QgYmUgZXNjYXBlZCBpZiBpdCBhcHBlYXJzIGluIHRoZSBzZWFyY2ggc3RyaW5nLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgcmVzdWx0IG9mIGBjaHIoMSlgLgoJICoKCSAqIFstLXRhYmxlX2NvbHVtbl9vbmNlXQoJICogOiBPdXRwdXQgdGhlICd0YWJsZTpjb2x1bW4nIGxpbmUgb25jZSBiZWZvcmUgYWxsIG1hdGNoaW5nIHJvdyBsaW5lcyBpbiB0aGUgdGFibGUgY29sdW1uIHJhdGhlciB0aGFuIGJlZm9yZSBlYWNoIG1hdGNoaW5nIHJvdy4KCSAqCgkgKiBbLS1vbmVfbGluZV0KCSAqIDogUGxhY2UgdGhlICd0YWJsZTpjb2x1bW4nIG91dHB1dCBvbiB0aGUgc2FtZSBsaW5lIGFzIHRoZSByb3cgaWQgYW5kIG1hdGNoICgndGFibGU6Y29sdW1uOmlkOm1hdGNoJykuIE92ZXJyaWRlcyAtLXRhYmxlX2NvbHVtbl9vbmNlLgoJICoKCSAqIFstLW1hdGNoZXNfb25seV0KCSAqIDogT25seSBvdXRwdXQgdGhlIHN0cmluZyBtYXRjaGVzIChpbmNsdWRpbmcgY29udGV4dCkuIE5vICd0YWJsZTpjb2x1bW4ncyBvciByb3cgaWRzIGFyZSBvdXRwdXR0ZWQuCgkgKgoJICogWy0tc3RhdHNdCgkgKiA6IE91dHB1dCBzdGF0cyBvbiB0aGUgbnVtYmVyIG9mIG1hdGNoZXMgZm91bmQsIHRpbWUgdGFrZW4sIHRhYmxlcy9jb2x1bW5zL3Jvd3Mgc2VhcmNoZWQsIHRhYmxlcyBza2lwcGVkLgoJICoKCSAqIFstLXRhYmxlX2NvbHVtbl9jb2xvcj08Y29sb3JfY29kZT5dCgkgKiA6IFBlcmNlbnQgY29sb3IgY29kZSB0byB1c2UgZm9yIHRoZSAndGFibGU6Y29sdW1uJyBvdXRwdXQuIEZvciBhIGxpc3Qgb2YgYXZhaWxhYmxlIHBlcmNlbnQgY29sb3IgY29kZXMsIHNlZSBiZWxvdy4gRGVmYXVsdCAnJUcnIChicmlnaHQgZ3JlZW4pLgoJICoKCSAqIFstLWlkX2NvbG9yPTxjb2xvcl9jb2RlPl0KCSAqIDogUGVyY2VudCBjb2xvciBjb2RlIHRvIHVzZSBmb3IgdGhlIHJvdyBpZCBvdXRwdXQuIEZvciBhIGxpc3Qgb2YgYXZhaWxhYmxlIHBlcmNlbnQgY29sb3IgY29kZXMsIHNlZSBiZWxvdy4gRGVmYXVsdCAnJVknIChicmlnaHQgeWVsbG93KS4KCSAqCgkgKiBbLS1tYXRjaF9jb2xvcj08Y29sb3JfY29kZT5dCgkgKiA6IFBlcmNlbnQgY29sb3IgY29kZSB0byB1c2UgZm9yIHRoZSBtYXRjaCAodW5sZXNzIGJvdGggYmVmb3JlIGFuZCBhZnRlciBjb250ZXh0IGFyZSAwLCB3aGVuIG5vIGNvbG9yIGNvZGUgaXMgdXNlZCkuIEZvciBhIGxpc3Qgb2YgYXZhaWxhYmxlIHBlcmNlbnQgY29sb3IgY29kZXMsIHNlZSBiZWxvdy4gRGVmYXVsdCAnJTMlaycgKGJsYWNrIG9uIGEgbXVzdGFyZCBiYWNrZ3JvdW5kKS4KCSAqCgkgKiBUaGUgcGVyY2VudCBjb2xvciBjb2RlcyBhdmFpbGFibGUgYXJlOgoJICoKCSAqIHwgQ29kZSB8IENvbG9yCgkgKiB8IC0tLS0gfCAtLS0tLQoJICogfCAgJXkgIHwgWWVsbG93IChkYXJrKSAobXVzdGFyZCkKCSAqIHwgICVnICB8IEdyZWVuIChkYXJrKQoJICogfCAgJWIgIHwgQmx1ZSAoZGFyaykKCSAqIHwgICVyICB8IFJlZCAoZGFyaykKCSAqIHwgICVtICB8IE1hZ2VudGEgKGRhcmspCgkgKiB8ICAlYyAgfCBDeWFuIChkYXJrKQoJICogfCAgJXcgIHwgV2hpdGUgKGRhcmspIChsaWdodCBncmF5KQoJICogfCAgJWsgIHwgQmxhY2sKCSAqIHwgICVZICB8IFllbGxvdyAoYnJpZ2h0KQoJICogfCAgJUcgIHwgR3JlZW4gKGJyaWdodCkKCSAqIHwgICVCICB8IEJsdWUgKGJyaWdodCkKCSAqIHwgICVSICB8IFJlZCAoYnJpZ2h0KQoJICogfCAgJU0gIHwgTWFnZW50YSAoYnJpZ2h0KQoJICogfCAgJUMgIHwgQ3lhbiAoYnJpZ2h0KQoJICogfCAgJVcgIHwgV2hpdGUKCSAqIHwgICVLICB8IEJsYWNrIChicmlnaHQpIChkYXJrIGdyYXkpCgkgKiB8ICAlMyAgfCBZZWxsb3cgYmFja2dyb3VuZCAoZGFyaykgKG11c3RhcmQpCgkgKiB8ICAlMiAgfCBHcmVlbiBiYWNrZ3JvdW5kIChkYXJrKQoJICogfCAgJTQgIHwgQmx1ZSBiYWNrZ3JvdW5kIChkYXJrKQoJICogfCAgJTEgIHwgUmVkIGJhY2tncm91bmQgKGRhcmspCgkgKiB8ICAlNSAgfCBNYWdlbnRhIGJhY2tncm91bmQgKGRhcmspCgkgKiB8ICAlNiAgfCBDeWFuIGJhY2tncm91bmQgKGRhcmspCgkgKiB8ICAlNyAgfCBXaGl0ZSBiYWNrZ3JvdW5kIChkYXJrKSAobGlnaHQgZ3JheSkKCSAqIHwgICUwICB8IEJsYWNrIGJhY2tncm91bmQKCSAqIHwgICU4ICB8IFJldmVyc2UKCSAqIHwgICVVICB8IFVuZGVybGluZQoJICogfCAgJUYgIHwgQmxpbmsgKHVubGlrZWx5IHRvIHdvcmspCgkgKgoJICogVGhleSBjYW4gYmUgY29uY2F0ZW5hdGVkLiBGb3IgaW5zdGFuY2UsIHRoZSBkZWZhdWx0IG1hdGNoIGNvbG9yIG9mIGJsYWNrIG9uIGEgbXVzdGFyZCAoZGFyayB5ZWxsb3cpIGJhY2tncm91bmQgYCUzJWtgIGNhbiBiZSBtYWRlIGJsYWNrIG9uIGEgYnJpZ2h0IHllbGxvdyBiYWNrZ3JvdW5kIHdpdGggYCVZJTAlOGAuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTZWFyY2ggdGhyb3VnaCB0aGUgZGF0YWJhc2UgZm9yIHRoZSAnd29yZHByZXNzLWRldmVsb3AnIHN0cmluZwoJICogICAgICQgd3AgZGIgc2VhcmNoIHdvcmRwcmVzcy1kZXZlbG9wCgkgKiAgICAgd3Bfb3B0aW9uczpvcHRpb25fdmFsdWUKCSAqICAgICAxOmh0dHA6Ly93b3JkcHJlc3MtZGV2ZWxvcC5kZXYKCSAqICAgICB3cF9vcHRpb25zOm9wdGlvbl92YWx1ZQoJICogICAgIDE6aHR0cDovL2V4YW1wbGUuY29tL2ZvbwoJICogICAgICAgICAuLi4KCSAqCgkgKiAgICAgIyBTZWFyY2ggdGhyb3VnaCBhIG11bHRpc2l0ZSBkYXRhYmFzZSBvbiB0aGUgc3Vic2l0ZSAnZm9vJyBmb3IgdGhlICdleGFtcGxlLmNvbScgc3RyaW5nCgkgKiAgICAgJCB3cCBkYiBzZWFyY2ggZXhhbXBsZS5jb20gLS11cmw9ZXhhbXBsZS5jb20vZm9vCgkgKiAgICAgd3BfMl9jb21tZW50czpjb21tZW50X2F1dGhvcl91cmwKCSAqICAgICAxOmh0dHA6Ly9leGFtcGxlLmNvbS8KCSAqICAgICB3cF8yX29wdGlvbnM6b3B0aW9uX3ZhbHVlCgkgKiAgICAgICAgIC4uLgoJICoKCSAqICAgICAjIFNlYXJjaCB0aHJvdWdoIHRoZSBkYXRhYmFzZSBmb3IgdGhlICdodHRwcz86Ly8nIHJlZ3VsYXIgZXhwcmVzc2lvbiwgcHJpbnRpbmcgc3RhdHMuCgkgKiAgICAgJCB3cCBkYiBzZWFyY2ggJ2h0dHBzPzovLycgLS1yZWdleCAtLXN0YXRzCgkgKiAgICAgd3BfY29tbWVudHM6Y29tbWVudF9hdXRob3JfdXJsCgkgKiAgICAgMTpodHRwczovL3dvcmRwcmVzcy5vcmcvCgkgKiAgICAgICAgIC4uLgoJICogICAgIFN1Y2Nlc3M6IEZvdW5kIDk5MTQ2IG1hdGNoZXMgaW4gMTAuNzUycyAoMTAuNTU5cyBzZWFyY2hpbmcpLiBTZWFyY2hlZCAxMiB0YWJsZXMsIDUzIGNvbHVtbnMsIDEzNTg5MDcgcm93cy4gMSB0YWJsZSBza2lwcGVkOiB3cF90ZXJtX3JlbGF0aW9uc2hpcHMuCgkgKgoJICogICAgICMgU1FMIHNlYXJjaCBkYXRhYmFzZSB0YWJsZSAnd3Bfb3B0aW9ucycgd2hlcmUgJ29wdGlvbl9uYW1lJyBtYXRjaCAnZm9vJwoJICogICAgIHdwIGRiIHF1ZXJ5ICdTRUxFQ1QgKiBGUk9NIHdwX29wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgbGlrZSAiJWZvbyUiJyAtLXNraXAtY29sdW1uLW5hbWVzCgkgKiAgICAgKy0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rCgkgKiAgICAgfCA5OCB8IGZvb19vcHRpb25zICB8IGE6MTp7czoxMjoiX211bHRpd2lkZ2V0IjtpOjE7fSB8IHllcyB8CgkgKiAgICAgfCA5OSB8IGZvb19zZXR0aW5ncyB8IGE6MDp7fSAgICAgICAgICAgICAgICAgICAgICAgICB8IHllcyB8CgkgKiAgICAgKy0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rCgkgKgoJICogICAgICMgU1FMIHNlYXJjaCBhbmQgZGVsZXRlIHJlY29yZHMgZnJvbSBkYXRhYmFzZSB0YWJsZSAnd3Bfb3B0aW9ucycgd2hlcmUgJ29wdGlvbl9uYW1lJyBtYXRjaCAnZm9vJwoJICogICAgIHdwIGRiIHF1ZXJ5ICJERUxFVEUgZnJvbSB3cF9vcHRpb25zIHdoZXJlIG9wdGlvbl9pZCBpbiAoJCh3cCBkYiBxdWVyeSAiU0VMRUNUIEdST1VQX0NPTkNBVChvcHRpb25faWQgU0VQQVJBVE9SICcsJykgZnJvbSB3cF9vcHRpb25zIHdoZXJlIG9wdGlvbl9uYW1lIGxpa2UgJyVmb28lJzsiIC0tc2lsZW50IC0tc2tpcC1jb2x1bW4tbmFtZXMpKSIKCSAqCgkgKiBAd2hlbiBhZnRlcl93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZWFyY2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSRzdGFydF9ydW5fdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoKCQkkc2VhcmNoID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgoJCSRiZWZvcmVfY29udGV4dCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2JlZm9yZV9jb250ZXh0JywgNDAgKTsKCQkkYmVmb3JlX2NvbnRleHQgPSAnJyA9PT0gJGJlZm9yZV9jb250ZXh0ID8gJGJlZm9yZV9jb250ZXh0IDogKGludCkgJGJlZm9yZV9jb250ZXh0OwoKCQkkYWZ0ZXJfY29udGV4dCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FmdGVyX2NvbnRleHQnLCA0MCApOwoJCSRhZnRlcl9jb250ZXh0ID0gJycgPT09ICRhZnRlcl9jb250ZXh0ID8gJGFmdGVyX2NvbnRleHQgOiAoaW50KSAkYWZ0ZXJfY29udGV4dDsKCgkJJHJlZ2V4ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgnLCBmYWxzZSApOwoJCWlmICggZmFsc2UgIT09ICRyZWdleCApIHsKCQkJJHJlZ2V4X2ZsYWdzICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZmxhZ3MnLCBmYWxzZSApOwoJCQkkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgPSBmYWxzZTsKCQkJJHJlZ2V4X2RlbGltaXRlciAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZGVsaW1pdGVyJywgJycgKTsKCQkJaWYgKCAnJyA9PT0gJHJlZ2V4X2RlbGltaXRlciApIHsKCQkJCSRyZWdleF9kZWxpbWl0ZXIgICAgICAgICA9IGNociggMSApOwoJCQkJJGRlZmF1bHRfcmVnZXhfZGVsaW1pdGVyID0gdHJ1ZTsKCQkJfQoJCX0KCgkJJGNvbG9ycyA9IHNlbGY6OmdldF9jb2xvcnMoCgkJCSRhc3NvY19hcmdzLAoJCQlbCgkJCQkndGFibGVfY29sdW1uJyA9PiAnJUcnLAoJCQkJJ2lkJyAgICAgICAgICAgPT4gJyVZJywKCQkJCSdtYXRjaCcgICAgICAgID0+ICRiZWZvcmVfY29udGV4dCB8fCAkYWZ0ZXJfY29udGV4dCA/ICclMyVrJyA6ICcnLAoJCQldCgkJKTsKCgkJJHRhYmxlX2NvbHVtbl9vbmNlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndGFibGVfY29sdW1uX29uY2UnLCBmYWxzZSApOwoJCSRvbmVfbGluZSAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ29uZV9saW5lJywgZmFsc2UgKTsKCQkkbWF0Y2hlc19vbmx5ICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdtYXRjaGVzX29ubHknLCBmYWxzZSApOwoJCSRzdGF0cyAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0YXRzJywgZmFsc2UgKTsKCgkJJGNvbHVtbl9jb3VudCA9IDA7CgkJJHJvd19jb3VudCAgICA9IDA7CgkJJG1hdGNoX2NvdW50ICA9IDA7CgkJJHNraXBwZWQgICAgICA9IFtdOwoKCQlpZiAoICRyZWdleCApIHsKCQkJLy8gTm90ZSB0aGUgdXNlciBtdXN0IGVzY2FwZSB0aGUgZGVsaW1pdGVyIGluIHRoZSBzZWFyY2guCgkJCSRzZWFyY2hfcmVnZXggPSAkcmVnZXhfZGVsaW1pdGVyIC4gJHNlYXJjaCAuICRyZWdleF9kZWxpbWl0ZXI7CgkJCWlmICggJHJlZ2V4X2ZsYWdzICkgewoJCQkJJHNlYXJjaF9yZWdleCAuPSAkcmVnZXhfZmxhZ3M7CgkJCX0KCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5QSFAuTm9TaWxlbmNlZEVycm9ycy5EaXNjb3VyYWdlZCAtLSBVbnN1cmUgd2h5IHRoaXMgaXMgbmVlZGVkLCBsZWF2aW5nIGluIGZvciBub3cuCgkJCWlmICggZmFsc2UgPT09IEBwcmVnX21hdGNoKCAkc2VhcmNoX3JlZ2V4LCAnJyApICkgewoJCQkJaWYgKCAkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgKSB7CgkJCQkJJGZsYWdzX21zZyA9ICRyZWdleF9mbGFncyA/ICJmbGFncyAnJHJlZ2V4X2ZsYWdzJyIgOiAnbm8gZmxhZ3MnOwoJCQkJCSRtc2cgICAgICAgPSAiVGhlIHJlZ2V4IHBhdHRlcm4gJyRzZWFyY2gnIHdpdGggZGVmYXVsdCBkZWxpbWl0ZXIgJ2NocigxKScgYW5kIHskZmxhZ3NfbXNnfSBmYWlscy4iOwoJCQkJfSBlbHNlIHsKCQkJCQkkbXNnID0gIlRoZSByZWdleCAnJHNlYXJjaF9yZWdleCcgZmFpbHMuIjsKCQkJCX0KCQkJCVdQX0NMSTo6ZXJyb3IoICRtc2cgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRzZWFyY2hfcmVnZXggICAgPSAnIycgLiBwcmVnX3F1b3RlKCAkc2VhcmNoLCAnIycgKSAuICcjaSc7CgkJCSRlc2NfbGlrZV9zZWFyY2ggPSAnJScgLiBVdGlsc1xlc2NfbGlrZSggJHNlYXJjaCApIC4gJyUnOwoJCX0KCgkJJGVuY29kaW5nID0gbnVsbDsKCQlpZiAoIDAgPT09IHN0cnBvcyggJHdwZGItPmNoYXJzZXQsICd1dGY4JyApICkgewoJCQkkZW5jb2RpbmcgPSAnVVRGLTgnOwoJCX0KCgkJJHRhYmxlcyA9IFV0aWxzXHdwX2dldF90YWJsZV9uYW1lcyggJGFyZ3MsICRhc3NvY19hcmdzICk7CgoJCSRzdGFydF9zZWFyY2hfdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoKCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgkJCWxpc3QoICRwcmltYXJ5X2tleXMsICR0ZXh0X2NvbHVtbnMsICRhbGxfY29sdW1ucyApID0gc2VsZjo6Z2V0X2NvbHVtbnMoICR0YWJsZSApOwoJCQlpZiAoICEgJGFsbF9jb2x1bW5zICkgewoJCQkJV1BfQ0xJOjplcnJvciggIk5vIHN1Y2ggdGFibGUgJyR0YWJsZScuIiApOwoJCQl9CgkJCWlmICggISAkdGV4dF9jb2x1bW5zICkgewoJCQkJaWYgKCAkc3RhdHMgKSB7CgkJCQkJJHNraXBwZWRbXSA9ICR0YWJsZTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gRG9uJ3QgYm90aGVyIHdhcm5pbmcgZm9yIHRlcm0gcmVsYXRpb25zaGlwcyAod2hpY2ggaXMganVzdCAzIGludCBjb2x1bW5zKS4KCQkJCQlpZiAoICEgcHJlZ19tYXRjaCggJy9fdGVybV9yZWxhdGlvbnNoaXBzJC8nLCAkdGFibGUgKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkcHJpbWFyeV9rZXlzID8gIk5vIHRleHQgY29sdW1ucyBmb3IgdGFibGUgJyR0YWJsZScgLSBza2lwcGVkLiIgOiAiTm8gcHJpbWFyeSBrZXkgb3IgdGV4dCBjb2x1bW5zIGZvciB0YWJsZSAnJHRhYmxlJyAtIHNraXBwZWQuIiApOwoJCQkJCX0KCQkJCX0KCQkJCWNvbnRpbnVlOwoJCQl9CgkJCSR0YWJsZV9zcWwgICAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJHRhYmxlICk7CgkJCSRjb2x1bW5fY291bnQgKz0gY291bnQoICR0ZXh0X2NvbHVtbnMgKTsKCQkJaWYgKCAhICRwcmltYXJ5X2tleXMgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJObyBwcmltYXJ5IGtleSBmb3IgdGFibGUgJyR0YWJsZScuIE5vIHJvdyBpZHMgd2lsbCBiZSBvdXRwdXR0ZWQuIiApOwoJCQkJJHByaW1hcnlfa2V5ICAgICA9ICcnOwoJCQkJJHByaW1hcnlfa2V5X3NxbCA9ICcnOwoJCQl9IGVsc2UgewoJCQkJJHByaW1hcnlfa2V5ICAgICA9IGFycmF5X3NoaWZ0KCAkcHJpbWFyeV9rZXlzICk7CgkJCQkkcHJpbWFyeV9rZXlfc3FsID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJHByaW1hcnlfa2V5ICkgLiAnLCAnOwoJCQl9CgoJCQlmb3JlYWNoICggJHRleHRfY29sdW1ucyBhcyAkY29sdW1uICkgewoJCQkJJGNvbHVtbl9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkY29sdW1uICk7CgkJCQlpZiAoICRyZWdleCApIHsKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIEVzY2FwZWQgdGhyb3VnaCBlc2Nfc3FsX2lkZW50L2VzY19saWtlLgoJCQkJCSRyZXN1bHRzID0gJHdwZGItPmdldF9yZXN1bHRzKCAiU0VMRUNUIHskcHJpbWFyeV9rZXlfc3FsfXskY29sdW1uX3NxbH0gRlJPTSB7JHRhYmxlX3NxbH0iICk7CgkJCQl9IGVsc2UgewoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gRXNjYXBlZCB0aHJvdWdoIGVzY19zcWxfaWRlbnQvZXNjX2xpa2UuCgkJCQkJJHJlc3VsdHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUIHskcHJpbWFyeV9rZXlfc3FsfXskY29sdW1uX3NxbH0gRlJPTSB7JHRhYmxlX3NxbH0gV0hFUkUgeyRjb2x1bW5fc3FsfSBMSUtFICVzOyIsICRlc2NfbGlrZV9zZWFyY2ggKSApOwoJCQkJfQoJCQkJaWYgKCAkcmVzdWx0cyApIHsKCQkJCQkkcm93X2NvdW50ICAgICAgICAgICAgICAgICAgKz0gY291bnQoICRyZXN1bHRzICk7CgkJCQkJJHRhYmxlX2NvbHVtbl92YWwgICAgICAgICAgICA9ICRjb2xvcnNbJ3RhYmxlX2NvbHVtbiddWzBdIC4gInskdGFibGV9OnskY29sdW1ufSIgLiAkY29sb3JzWyd0YWJsZV9jb2x1bW4nXVsxXTsKCQkJCQkkb3V0cHV0dGVkX3RhYmxlX2NvbHVtbl9vbmNlID0gZmFsc2U7CgkJCQkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRyZXN1bHQgKSB7CgkJCQkJCSRjb2xfdmFsID0gJHJlc3VsdC0+JGNvbHVtbjsKCQkJCQkJaWYgKCBwcmVnX21hdGNoX2FsbCggJHNlYXJjaF9yZWdleCwgJGNvbF92YWwsICRtYXRjaGVzLCBQUkVHX09GRlNFVF9DQVBUVVJFICkgKSB7CgkJCQkJCQlpZiAoICEgJG1hdGNoZXNfb25seSAmJiAoICEgJHRhYmxlX2NvbHVtbl9vbmNlIHx8ICEgJG91dHB1dHRlZF90YWJsZV9jb2x1bW5fb25jZSApICYmICEgJG9uZV9saW5lICkgewoJCQkJCQkJCVdQX0NMSTo6bG9nKCAkdGFibGVfY29sdW1uX3ZhbCApOwoJCQkJCQkJCSRvdXRwdXR0ZWRfdGFibGVfY29sdW1uX29uY2UgPSB0cnVlOwoJCQkJCQkJfQoJCQkJCQkJJHBrX3ZhbCA9ICRwcmltYXJ5X2tleSA/ICggJGNvbG9yc1snaWQnXVswXSAuICRyZXN1bHQtPiRwcmltYXJ5X2tleSAuICRjb2xvcnNbJ2lkJ11bMV0gLiAnOicgKSA6ICcnOwoKCQkJCQkJCSRiaXRzICAgICAgICAgPSBbXTsKCQkJCQkJCSRjb2xfZW5jb2RpbmcgPSAkZW5jb2Rpbmc7CgkJCQkJCQlpZiAoICEgJGNvbF9lbmNvZGluZyAmJiAoICRiZWZvcmVfY29udGV4dCB8fCAkYWZ0ZXJfY29udGV4dCApICYmIGZ1bmN0aW9uX2V4aXN0cyggJ21iX2RldGVjdF9lbmNvZGluZycgKSApIHsKCQkJCQkJCQkkY29sX2VuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCAkY29sX3ZhbCwgbnVsbCwgdHJ1ZSAvKnN0cmljdCovICk7CgkJCQkJCQl9CgkJCQkJCQkkYXBwZW5kX25leHQgPSBmYWxzZTsKCQkJCQkJCSRsYXN0X29mZnNldCA9IDA7CgkJCQkJCQkkbWF0Y2hfY250ICAgPSBjb3VudCggJG1hdGNoZXNbMF0gKTsKCQkJCQkJCWZvciAoICRpID0gMDsgJGkgPCAkbWF0Y2hfY250OyAkaSsrICkgewoJCQkJCQkJCSRtYXRjaCAgICAgICAgICAgPSAkbWF0Y2hlc1swXVsgJGkgXVswXTsKCQkJCQkJCQkkb2Zmc2V0ICAgICAgICAgID0gJG1hdGNoZXNbMF1bICRpIF1bMV07CgkJCQkJCQkJJGxvZyAgICAgICAgICAgICA9ICRjb2xvcnNbJ21hdGNoJ11bMF0gLiAkbWF0Y2ggLiAkY29sb3JzWydtYXRjaCddWzFdOwoJCQkJCQkJCSRiZWZvcmUgICAgICAgICAgPSAnJzsKCQkJCQkJCQkkYWZ0ZXIgICAgICAgICAgID0gJyc7CgkJCQkJCQkJJGFmdGVyX3Nob3J0ZW5lZCA9IGZhbHNlOwoKCQkJCQkJCQkvLyBPZmZzZXRzIGFyZSBpbiBieXRlcywgc28gbmVlZCB0byB1c2UgYHN0cmxlbigpYCBhbmQgYHN1YnN0cigpYCBiZWZvcmUgdXNpbmcgYHNhZmVfc3Vic3RyKClgLgoJCQkJCQkJCWlmICggJGJlZm9yZV9jb250ZXh0ICYmICRvZmZzZXQgJiYgISAkYXBwZW5kX25leHQgKSB7CgkJCQkJCQkJCSRiZWZvcmUgPSBcY2xpXHNhZmVfc3Vic3RyKCBzdWJzdHIoICRjb2xfdmFsLCAkbGFzdF9vZmZzZXQsICRvZmZzZXQgLSAkbGFzdF9vZmZzZXQgKSwgLSRiZWZvcmVfY29udGV4dCwgbnVsbCAvKmxlbmd0aCovLCBmYWxzZSAvKmlzX3dpZHRoKi8sICRjb2xfZW5jb2RpbmcgKTsKCQkJCQkJCQl9CgkJCQkJCQkJaWYgKCAkYWZ0ZXJfY29udGV4dCApIHsKCQkJCQkJCQkJJGVuZF9vZmZzZXQgPSAkb2Zmc2V0ICsgc3RybGVuKCAkbWF0Y2ggKTsKCQkJCQkJCQkJJGFmdGVyICAgICAgPSBcY2xpXHNhZmVfc3Vic3RyKCBzdWJzdHIoICRjb2xfdmFsLCAkZW5kX29mZnNldCApLCAwLCAkYWZ0ZXJfY29udGV4dCwgZmFsc2UgLyppc193aWR0aCovLCAkY29sX2VuY29kaW5nICk7CgkJCQkJCQkJCS8vIFRvIGxlc3NlbiBjb250ZXh0IGR1cGxpY2F0aW9uIGluIG91dHB1dCwgc2hvcnRlbiB0aGUgYWZ0ZXIgY29udGV4dCBpZiBpdCBvdmVybGFwcyB3aXRoIHRoZSBuZXh0IG1hdGNoLgoJCQkJCQkJCQlpZiAoICRpICsgMSA8ICRtYXRjaF9jbnQgJiYgJGVuZF9vZmZzZXQgKyBzdHJsZW4oICRhZnRlciApID4gJG1hdGNoZXNbMF1bICRpICsgMSBdWzFdICkgewoJCQkJCQkJCQkJJGFmdGVyICAgICAgICAgICA9IHN1YnN0ciggJGFmdGVyLCAwLCAkbWF0Y2hlc1swXVsgJGkgKyAxIF1bMV0gLSAkZW5kX29mZnNldCApOwoJCQkJCQkJCQkJJGFmdGVyX3Nob3J0ZW5lZCA9IHRydWU7CgkJCQkJCQkJCQkvLyBPbiB0aGUgbmV4dCBpdGVyYXRpb24sIHdpbGwgYXBwZW5kIHdpdGggbm8gYmVmb3JlIGNvbnRleHQuCgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQkJaWYgKCAkYXBwZW5kX25leHQgKSB7CgkJCQkJCQkJCSRjbnQgICAgICAgICAgICAgICA9IGNvdW50KCAkYml0cyApOwoJCQkJCQkJCQkkYml0c1sgJGNudCAtIDEgXSAuPSAkbG9nIC4gJGFmdGVyOwoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCSRiaXRzW10gPSAkYmVmb3JlIC4gJGxvZyAuICRhZnRlcjsKCQkJCQkJCQl9CgkJCQkJCQkJJGFwcGVuZF9uZXh0ID0gJGFmdGVyX3Nob3J0ZW5lZDsKCQkJCQkJCQkkbGFzdF9vZmZzZXQgPSAkb2Zmc2V0OwoJCQkJCQkJfQoJCQkJCQkJJG1hdGNoX2NvdW50ICs9ICRtYXRjaF9jbnQ7CgkJCQkJCQkkY29sX3ZhbCAgICAgID0gaW1wbG9kZSggJyBbLi4uXSAnLCAkYml0cyApOwoKCQkJCQkJCVdQX0NMSTo6bG9nKCAkbWF0Y2hlc19vbmx5ID8gJGNvbF92YWwgOiAoICRvbmVfbGluZSA/ICJ7JHRhYmxlX2NvbHVtbl92YWx9OnskcGtfdmFsfXskY29sX3ZhbH0iIDogInskcGtfdmFsfXskY29sX3ZhbH0iICkgKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAkc3RhdHMgKSB7CgkJCSR0YWJsZV9jb3VudCAgID0gY291bnQoICR0YWJsZXMgKTsKCQkJJHNraXBwZWRfY291bnQgPSBjb3VudCggJHNraXBwZWQgKTsKCQkJJG1hdGNoX3N0ciAgICAgPSAxID09PSAkbWF0Y2hfY291bnQgPyAnbWF0Y2gnIDogJ21hdGNoZXMnOwoJCQkkdGFibGVfc3RyICAgICA9IDEgPT09ICR0YWJsZV9jb3VudCA/ICd0YWJsZScgOiAndGFibGVzJzsKCQkJJGNvbHVtbl9zdHIgICAgPSAxID09PSAkY29sdW1uX2NvdW50ID8gJ2NvbHVtbicgOiAnY29sdW1ucyc7CgkJCSRyb3dfc3RyICAgICAgID0gMSA9PT0gJHJvd19jb3VudCA/ICdyb3cnIDogJ3Jvd3MnOwoJCQkkc2tpcHBlZF9zdHIgICA9IDEgPT09ICRza2lwcGVkX2NvdW50ID8gJ3RhYmxlIHNraXBwZWQnIDogJ3RhYmxlcyBza2lwcGVkJzsKCQkJaWYgKCAwICE9PSAkc2tpcHBlZF9jb3VudCApIHsKCQkJCSRza2lwcGVkX3N0ciAuPSAnOiAnIC4gaW1wbG9kZSggJywgJywgJHNraXBwZWQgKTsKCQkJfQoJCQkkZW5kX3RpbWUgICAgPSBtaWNyb3RpbWUoIHRydWUgKTsKCQkJJHJ1bl90aW1lICAgID0gJGVuZF90aW1lIC0gJHN0YXJ0X3J1bl90aW1lOwoJCQkkc2VhcmNoX3RpbWUgPSAkZW5kX3RpbWUgLSAkc3RhcnRfc2VhcmNoX3RpbWU7CgkJCSRzdGF0c19tc2cgICA9IHNwcmludGYoCgkJCQknRm91bmQgJWQgJXMgaW4gJS4zZnMgKCUuM2ZzIHNlYXJjaGluZykuIFNlYXJjaGVkICVkICVzLCAlZCAlcywgJWQgJXMuICVkICVzLicsCgkJCQkkbWF0Y2hfY291bnQsCgkJCQkkbWF0Y2hfc3RyLAoJCQkJJHJ1bl90aW1lLAoJCQkJJHNlYXJjaF90aW1lLAoJCQkJJHRhYmxlX2NvdW50LAoJCQkJJHRhYmxlX3N0ciwKCQkJCSRjb2x1bW5fY291bnQsCgkJCQkkY29sdW1uX3N0ciwKCQkJCSRyb3dfY291bnQsCgkJCQkkcm93X3N0ciwKCQkJCSRza2lwcGVkX2NvdW50LAoJCQkJJHNraXBwZWRfc3RyCgkJCSk7CgkJCVdQX0NMSTo6c3VjY2VzcyggJHN0YXRzX21zZyApOwoJCX0KCX0KCgkvKioKCSAqIERpc3BsYXlzIGluZm9ybWF0aW9uIGFib3V0IGEgZ2l2ZW4gdGFibGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8dGFibGU+XQoJICogOiBOYW1lIG9mIHRoZSBkYXRhYmFzZSB0YWJsZS4KCSAqCgkgKiBbLS1mb3JtYXRdCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBkYiBjb2x1bW5zIHdwX3Bvc3RzCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0rLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCAgICAgICAgIEZpZWxkICAgICAgICAgfCAgICAgICAgVHlwZSAgICAgICAgIHwgTnVsbCB8IEtleSB8ICAgICAgIERlZmF1bHQgICAgICAgfCAgICAgRXh0cmEgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0rLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBJRCAgICAgICAgICAgICAgICAgICAgfCBiaWdpbnQoMjApIHVuc2lnbmVkIHwgTk8gICB8IFBSSSB8ICAgICAgICAgICAgICAgICAgICAgfCBhdXRvX2luY3JlbWVudCB8CgkgKiAgICAgfCBwb3N0X2F1dGhvciAgICAgICAgICAgfCBiaWdpbnQoMjApIHVuc2lnbmVkIHwgTk8gICB8IE1VTCB8IDAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X2RhdGUgICAgICAgICAgICAgfCBkYXRldGltZSAgICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAwMDAtMDAtMDAgMDA6MDA6MDAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X2RhdGVfZ210ICAgICAgICAgfCBkYXRldGltZSAgICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAwMDAtMDAtMDAgMDA6MDA6MDAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X2NvbnRlbnQgICAgICAgICAgfCBsb25ndGV4dCAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X3RpdGxlICAgICAgICAgICAgfCB0ZXh0ICAgICAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X2V4Y2VycHQgICAgICAgICAgfCB0ZXh0ICAgICAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X3N0YXR1cyAgICAgICAgICAgfCB2YXJjaGFyKDIwKSAgICAgICAgIHwgTk8gICB8ICAgICB8IHB1Ymxpc2ggICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBjb21tZW50X3N0YXR1cyAgICAgICAgfCB2YXJjaGFyKDIwKSAgICAgICAgIHwgTk8gICB8ICAgICB8IG9wZW4gICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwaW5nX3N0YXR1cyAgICAgICAgICAgfCB2YXJjaGFyKDIwKSAgICAgICAgIHwgTk8gICB8ICAgICB8IG9wZW4gICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X3Bhc3N3b3JkICAgICAgICAgfCB2YXJjaGFyKDI1NSkgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X25hbWUgICAgICAgICAgICAgfCB2YXJjaGFyKDIwMCkgICAgICAgIHwgTk8gICB8IE1VTCB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCB0b19waW5nICAgICAgICAgICAgICAgfCB0ZXh0ICAgICAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwaW5nZWQgICAgICAgICAgICAgICAgfCB0ZXh0ICAgICAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X21vZGlmaWVkICAgICAgICAgfCBkYXRldGltZSAgICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAwMDAtMDAtMDAgMDA6MDA6MDAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X21vZGlmaWVkX2dtdCAgICAgfCBkYXRldGltZSAgICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAwMDAtMDAtMDAgMDA6MDA6MDAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X2NvbnRlbnRfZmlsdGVyZWQgfCBsb25ndGV4dCAgICAgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X3BhcmVudCAgICAgICAgICAgfCBiaWdpbnQoMjApIHVuc2lnbmVkIHwgTk8gICB8IE1VTCB8IDAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBndWlkICAgICAgICAgICAgICAgICAgfCB2YXJjaGFyKDI1NSkgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBtZW51X29yZGVyICAgICAgICAgICAgfCBpbnQoMTEpICAgICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X3R5cGUgICAgICAgICAgICAgfCB2YXJjaGFyKDIwKSAgICAgICAgIHwgTk8gICB8IE1VTCB8IHBvc3QgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBwb3N0X21pbWVfdHlwZSAgICAgICAgfCB2YXJjaGFyKDEwMCkgICAgICAgIHwgTk8gICB8ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgfCBjb21tZW50X2NvdW50ICAgICAgICAgfCBiaWdpbnQoMjApICAgICAgICAgIHwgTk8gICB8ICAgICB8IDAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0rLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHdoZW4gYWZ0ZXJfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gY29sdW1ucyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJGZvcm1hdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKTsKCgkJVXRpbHNcd3BfZ2V0X3RhYmxlX25hbWVzKCBbICRhcmdzWzBdIF0sIFtdICk7CgoJCSRjb2x1bW5zID0gJHdwZGItPmdldF9yZXN1bHRzKAoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIEFzc2VydGVkIHRvIGJlIGEgdmFsaWQgdGFibGUgbmFtZSB0aHJvdWdoIHdwX2dldF90YWJsZV9uYW1lcy4KCQkJJ1NIT1cgQ09MVU1OUyBGUk9NICcgLiAkYXJnc1swXQoJCSk7CgoJCSRmb3JtYXR0ZXJfZmllbGRzID0gWyAnRmllbGQnLCAnVHlwZScsICdOdWxsJywgJ0tleScsICdEZWZhdWx0JywgJ0V4dHJhJyBdOwoJCSRmb3JtYXR0ZXJfYXJncyAgID0gWwoJCQknZm9ybWF0JyA9PiAkZm9ybWF0LAoJCV07CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkZm9ybWF0dGVyX2FyZ3MsICRmb3JtYXR0ZXJfZmllbGRzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJGNvbHVtbnMgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfY3JlYXRlX3F1ZXJ5KCkgewoKCQkkY3JlYXRlX3F1ZXJ5ID0gc3ByaW50ZiggJ0NSRUFURSBEQVRBQkFTRSAlcycsIHNlbGY6OmVzY19zcWxfaWRlbnQoIERCX05BTUUgKSApOwoJCWlmICggZGVmaW5lZCggJ0RCX0NIQVJTRVQnICkgJiYgY29uc3RhbnQoICdEQl9DSEFSU0VUJyApICkgewoJCQkkY3JlYXRlX3F1ZXJ5IC49IHNwcmludGYoICcgREVGQVVMVCBDSEFSU0VUICVzJywgc2VsZjo6ZXNjX3NxbF9pZGVudCggREJfQ0hBUlNFVCApICk7CgkJfQoJCWlmICggZGVmaW5lZCggJ0RCX0NPTExBVEUnICkgJiYgY29uc3RhbnQoICdEQl9DT0xMQVRFJyApICkgewoJCQkkY3JlYXRlX3F1ZXJ5IC49IHNwcmludGYoICcgREVGQVVMVCBDT0xMQVRFICVzJywgc2VsZjo6ZXNjX3NxbF9pZGVudCggREJfQ09MTEFURSApICk7CgkJfQoJCXJldHVybiAkY3JlYXRlX3F1ZXJ5OwoJfQoKCS8qKgoJICogUnVuIGEgc2luZ2xlIHF1ZXJ5IHZpYSB0aGUgJ215c3FsJyBiaW5hcnkuCgkgKgoJICogVGhpcyBpbmNsdWRlcyB0aGUgbmVjZXNzYXJ5IHNldHVwIHRvIG1ha2Ugc3VyZSB0aGUgcXVlcmllcyBiZWhhdmUgc2ltaWxhcgoJICogdG8gd2hhdCBXUERCIHByb2R1Y2VzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHF1ZXJ5ICAgICAgUXVlcnkgdG8gZXhlY3V0ZS4KCSAqIEBwYXJhbSBhcnJheSAgJGFzc29jX2FyZ3MgT3B0aW9uYWwuIEFzc29jaWF0aXZlIGFycmF5IG9mIGFyZ3VtZW50cy4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIHJ1bl9xdWVyeSggJHF1ZXJ5LCAkYXNzb2NfYXJncyA9IFtdICkgewoJCS8vIEVuc3VyZSB0aGF0IHRoZSBTUUwgbW9kZSBpcyBjb21wYXRpYmxlIHdpdGggV1BEQi4KCQkkcXVlcnkgPSAkdGhpcy0+Z2V0X3NxbF9tb2RlX3F1ZXJ5KCAkYXNzb2NfYXJncyApIC4gJHF1ZXJ5OwoKCQlXUF9DTEk6OmRlYnVnKCAiUXVlcnk6IHskcXVlcnl9IiwgJ2RiJyApOwoKCQlzZWxmOjpydW4oCgkJCXNwcmludGYoCgkJCQknL3Vzci9iaW4vZW52IG15c3FsJXMgLS1uby1hdXRvLXJlaGFzaCcsCgkJCQkkdGhpcy0+Z2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAkYXNzb2NfYXJncyApCgkJCSksCgkJCWFycmF5X21lcmdlKCAkYXNzb2NfYXJncywgWyAnZXhlY3V0ZScgPT4gJHF1ZXJ5IF0gKQoJCSk7Cgl9CgoJLyoqCgkgKiBSdW4gYSBNeVNRTCBjb21tYW5kIGFuZCBvcHRpb25hbGx5IHJldHVybiB0aGUgb3V0cHV0LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNtZCAgICAgICAgICAgQ29tbWFuZCB0byBydW4uCgkgKiBAcGFyYW0gYXJyYXkgICRhc3NvY19hcmdzICAgIE9wdGlvbmFsLiBBc3NvY2lhdGl2ZSBhcnJheSBvZiBhcmd1bWVudHMgdG8KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLgoJICogQHBhcmFtIGJvb2wgICAkc2VuZF90b19zaGVsbCBPcHRpb25hbC4gV2hldGhlciB0byBzZW5kIFNURE9VVCBhbmQgU1RERVJSCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZWx5IHRvIHRoZSBzaGVsbC4gRGVmYXVsdHMgdG8gdHJ1ZS4KCSAqIEBwYXJhbSBib29sICAgJGludGVyYWN0aXZlICAgT3B0aW9uYWwuIFdoZXRoZXIgTXlTUUwgaXMgbWVhbnQgdG8gYmUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZWQgYXMgYW4gaW50ZXJhY3RpdmUgcHJvY2Vzcy4gRGVmYXVsdHMKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZmFsc2UuCgkgKgoJICogQHJldHVybiBhcnJheSB7CgkgKiAgICAgQXNzb2NpYXRpdmUgYXJyYXkgY29udGFpbmluZyBTVERPVVQgYW5kIFNUREVSUiBvdXRwdXQuCgkgKgoJICogICAgIEB0eXBlIHN0cmluZyAkc3Rkb3V0ICAgIE91dHB1dCB0aGF0IHdhcyBzZW50IHRvIFNURE9VVC4KCSAqICAgICBAdHlwZSBzdHJpbmcgJHN0ZGVyciAgICBPdXRwdXQgdGhhdCB3YXMgc2VudCB0byBTVERFUlIuCgkgKiAgICAgQHR5cGUgaW50ICAgICRleGl0X2NvZGUgRXhpdCBjb2RlIG9mIHRoZSBwcm9jZXNzLgoJICogfQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBydW4oICRjbWQsICRhc3NvY19hcmdzID0gW10sICRzZW5kX3RvX3NoZWxsID0gdHJ1ZSwgJGludGVyYWN0aXZlID0gZmFsc2UgKSB7CgkJJHJlcXVpcmVkID0gWwoJCQknaG9zdCcgPT4gREJfSE9TVCwKCQkJJ3VzZXInID0+IERCX1VTRVIsCgkJCSdwYXNzJyA9PiBEQl9QQVNTV09SRCwKCQldOwoKCQlpZiAoICEgaXNzZXQoICRhc3NvY19hcmdzWydkZWZhdWx0LWNoYXJhY3Rlci1zZXQnXSApCgkJCSYmIGRlZmluZWQoICdEQl9DSEFSU0VUJyApICYmIGNvbnN0YW50KCAnREJfQ0hBUlNFVCcgKSApIHsKCQkJJHJlcXVpcmVkWydkZWZhdWx0LWNoYXJhY3Rlci1zZXQnXSA9IGNvbnN0YW50KCAnREJfQ0hBUlNFVCcgKTsKCQl9CgoJCS8vIFVzaW5nICdkYnVzZXInIGFzIG9wdGlvbiBuYW1lIHRvIHdvcmthcm91bmQgY2xhc2ggd2l0aCBXUC1DTEkncyBnbG9iYWwgV1AgJ3VzZXInIHBhcmFtZXRlciwgd2l0aCAnZGJwYXNzJyBhbHNvIGF2YWlsYWJsZSBmb3IgdGlkeW5lc3MuCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2RidXNlciddICkgKSB7CgkJCSRyZXF1aXJlZFsndXNlciddID0gJGFzc29jX2FyZ3NbJ2RidXNlciddOwoJCQl1bnNldCggJGFzc29jX2FyZ3NbJ2RidXNlciddICk7CgkJfQoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydkYnBhc3MnXSApICkgewoJCQkkcmVxdWlyZWRbJ3Bhc3MnXSA9ICRhc3NvY19hcmdzWydkYnBhc3MnXTsKCQkJdW5zZXQoICRhc3NvY19hcmdzWydkYnBhc3MnXSwgJGFzc29jX2FyZ3NbJ3Bhc3N3b3JkJ10gKTsKCQl9CgoJCSRmaW5hbF9hcmdzID0gYXJyYXlfbWVyZ2UoICRhc3NvY19hcmdzLCAkcmVxdWlyZWQgKTsKCgkJcmV0dXJuIFV0aWxzXHJ1bl9teXNxbF9jb21tYW5kKCAkY21kLCAkZmluYWxfYXJncywgbnVsbCwgJHNlbmRfdG9fc2hlbGwsICRpbnRlcmFjdGl2ZSApOwoJfQoKCS8qKgoJICogSGVscGVyIHRvIHBsdWNrICdkYnVzZXInIGFuZCAnZGJwYXNzJyBmcm9tIGFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IHdpdGggYGRidXNlcicgYW5kICdkYnBhc3MnIHNldCBpZiBpbiBwYXNzZWQtaW4gYXNzb2NpYXRpdmUgYXJncyBhcnJheS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2RidXNlcl9kYnBhc3NfYXJncyggJGFzc29jX2FyZ3MgKSB7CgkJJG15c3FsX2FyZ3MgPSBbXTsKCQkkZGJ1c2VyICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RidXNlcicgKTsKCQlpZiAoIG51bGwgIT09ICRkYnVzZXIgKSB7CgkJCSRteXNxbF9hcmdzWydkYnVzZXInXSA9ICRkYnVzZXI7CgkJfQoJCSRkYnBhc3MgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkYnBhc3MnICk7CgkJaWYgKCBudWxsICE9PSAkZGJwYXNzICkgewoJCQkkbXlzcWxfYXJnc1snZGJwYXNzJ10gPSAkZGJwYXNzOwoJCX0KCQlyZXR1cm4gJG15c3FsX2FyZ3M7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBjb2x1bW4gbmFtZXMgb2YgYSBkYiB0YWJsZSBkaWZmZXJlbnRpYXRlZCBpbnRvIGtleSBjb2x1bW5zIGFuZCB0ZXh0IGNvbHVtbnMgYW5kIGFsbCBjb2x1bW5zLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHRhYmxlIFRoZSB0YWJsZSBuYW1lLgoJICogQHJldHVybiBhcnJheSBBIDMgZWxlbWVudCBhcnJheSBjb25zaXN0aW5nIG9mIGFuIGFycmF5IG9mIHByaW1hcnkga2V5IGNvbHVtbiBuYW1lcywgYW4gYXJyYXkgb2YgdGV4dCBjb2x1bW4gbmFtZXMsIGFuZCBhbiBhcnJheSBjb250YWluaW5nIGFsbCBjb2x1bW4gbmFtZXMuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9jb2x1bW5zKCAkdGFibGUgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkdGFibGVfc3FsICAgICAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJHRhYmxlICk7CgkJJHByaW1hcnlfa2V5cyAgICA9IFtdOwoJCSR0ZXh0X2NvbHVtbnMgICAgPSBbXTsKCQkkYWxsX2NvbHVtbnMgICAgID0gW107CgkJJHN1cHByZXNzX2Vycm9ycyA9ICR3cGRiLT5zdXBwcmVzc19lcnJvcnMoKTsKCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCAtLSBFc2NhcGVkIHRocm91Z2ggZXNjX3NxbF9pZGVudC9lc2NfbGlrZS4KCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIkRFU0NSSUJFICR0YWJsZV9zcWwiICk7CgkJaWYgKCAkcmVzdWx0cyApIHsKCQkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRjb2wgKSB7CgkJCQkvLyBwaHBjczpkaXNhYmxlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZFZhcmlhYmxlTmFtZS5Vc2VkUHJvcGVydHlOb3RTbmFrZUNhc2UgLS0gUHJvcGVydHkgbmFtZXMgY29tZSBmcm9tIGRhdGFiYXNlLgoJCQkJaWYgKCAnUFJJJyA9PT0gJGNvbC0+S2V5ICkgewoJCQkJCSRwcmltYXJ5X2tleXNbXSA9ICRjb2wtPkZpZWxkOwoJCQkJfQoJCQkJaWYgKCBzZWxmOjppc190ZXh0X2NvbCggJGNvbC0+VHlwZSApICkgewoJCQkJCSR0ZXh0X2NvbHVtbnNbXSA9ICRjb2wtPkZpZWxkOwoJCQkJfQoJCQkJJGFsbF9jb2x1bW5zW10gPSAkY29sLT5GaWVsZDsKCQkJCS8vIHBocGNzOmVuYWJsZQoJCQl9CgkJfQoJCSR3cGRiLT5zdXBwcmVzc19lcnJvcnMoICRzdXBwcmVzc19lcnJvcnMgKTsKCQlyZXR1cm4gWyAkcHJpbWFyeV9rZXlzLCAkdGV4dF9jb2x1bW5zLCAkYWxsX2NvbHVtbnMgXTsKCX0KCgkvKioKCSAqIERldGVybWluZXMgd2hldGhlciBhIGNvbHVtbiBpcyBjb25zaWRlcmVkIHRleHQgb3Igbm90LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgQ29sdW1uIHR5cGUuCgkgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiB0ZXh0IGNvbHVtbiwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc190ZXh0X2NvbCggJHR5cGUgKSB7CgkJZm9yZWFjaCAoIFsgJ3RleHQnLCAndmFyY2hhcicgXSBhcyAkdG9rZW4gKSB7CgkJCWlmICggZmFsc2UgIT09IHN0cnBvcyggJHR5cGUsICR0b2tlbiApICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEVzY2FwZXMgKGJhY2t0aWNrcykgTXlTUUwgaWRlbnRpZmllcnMgKGFrYSBzY2hlbWEgb2JqZWN0IG5hbWVzKSAtIGkuZS4gY29sdW1uIG5hbWVzLCB0YWJsZSBuYW1lcywgYW5kIGRhdGFiYXNlL2luZGV4L2FsaWFzL3ZpZXcgZXRjIG5hbWVzLgoJICogU2VlIGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvcmVmbWFuLzUuNS9lbi9pZGVudGlmaWVycy5odG1sCgkgKgoJICogQHBhcmFtIHN0cmluZ3xhcnJheSAkaWRlbnRzIEEgc2luZ2xlIGlkZW50aWZpZXIgb3IgYW4gYXJyYXkgb2YgaWRlbnRpZmllcnMuCgkgKiBAcmV0dXJuIHN0cmluZ3xhcnJheSBBbiBlc2NhcGVkIHN0cmluZyBpZiBnaXZlbiBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2YgZXNjYXBlZCBzdHJpbmdzIGlmIGdpdmVuIGFuIGFycmF5IG9mIHN0cmluZ3MuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGVzY19zcWxfaWRlbnQoICRpZGVudHMgKSB7CgkJJGJhY2t0aWNrID0gZnVuY3Rpb24gKCAkdiApIHsKCQkJLy8gRXNjYXBlIGFueSBiYWNrdGlja3MgaW4gdGhlIGlkZW50aWZpZXIgYnkgZG91YmxpbmcuCgkJCXJldHVybiAnYCcgLiBzdHJfcmVwbGFjZSggJ2AnLCAnYGAnLCAkdiApIC4gJ2AnOwoJCX07CgkJaWYgKCBpc19zdHJpbmcoICRpZGVudHMgKSApIHsKCQkJcmV0dXJuICRiYWNrdGljayggJGlkZW50cyApOwoJCX0KCQlyZXR1cm4gYXJyYXlfbWFwKCAkYmFja3RpY2ssICRpZGVudHMgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIGNvbG9yIGNvZGVzIGZyb20gdGhlIG9wdGlvbnMgaWYgYW55LCBhbmQgcmV0dXJucyB0aGUgcGFzc2VkIGluIGFycmF5IGNvbG9yaXplZCB3aXRoIDIgZWxlbWVudHMgcGVyIGVudHJ5LCBhIGNvbG9yIGNvZGUgKG9yICcnKSBhbmQgYSByZXNldCAob3IgJycpLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBUaGUgYXNzb2NpYXRpdmUgYXJndW1lbnQgYXJyYXkgcGFzc2VkIHRvIHRoZSBjb21tYW5kLgoJICogQHBhcmFtIGFycmF5ICRjb2xvcnMgQXJyYXkgb2YgZGVmYXVsdCBwZXJjZW50IGNvbG9yIGNvZGUgc3RyaW5ncyBrZXllZCBieSB0aGUgMyBjb2xvciBjb250ZXh0cyAndGFibGVfY29sdW1uJywgJ2lkJywgJ21hdGNoJy4KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgY29udGFpbmluZyAzIDItZWxlbWVudCBhcnJheXMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbG9ycyggJGFzc29jX2FyZ3MsICRjb2xvcnMgKSB7CgkJJGNvbG9yX3Jlc2V0ID0gV1BfQ0xJOjpjb2xvcml6ZSggJyVuJyApOwoKCQkkY29sb3JfY29kZXMgPSBpbXBsb2RlKAoJCQknJywKCQkJYXJyYXlfbWFwKAoJCQkJZnVuY3Rpb24gKCAkdiApIHsKCQkJCQlyZXR1cm4gc3Vic3RyKCAkdiwgMSApOwoJCQkJfSwKCQkJCWFycmF5X2tleXMoIFxjbGlcQ29sb3JzOjpnZXRDb2xvcnMoKSApCgkJCSkKCQkpOwoKCQkkY29sb3JfY29kZXNfcmVnZXggPSAnL14oPzolWycgLiAkY29sb3JfY29kZXMgLiAnXSkqJC8nOwoKCQlmb3JlYWNoICggYXJyYXlfa2V5cyggJGNvbG9ycyApIGFzICRjb2xvcl9jb2wgKSB7CgkJCSRjb2xfY29sb3JfZmxhZyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJGNvbG9yX2NvbCAuICdfY29sb3InLCBmYWxzZSApOwoJCQlpZiAoIGZhbHNlICE9PSAkY29sX2NvbG9yX2ZsYWcgKSB7CgkJCQlpZiAoICEgcHJlZ19tYXRjaCggJGNvbG9yX2NvZGVzX3JlZ2V4LCAkY29sX2NvbG9yX2ZsYWcsICRtYXRjaGVzICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVW5yZWNvZ25pemVkIHBlcmNlbnQgY29sb3IgY29kZSAnJGNvbF9jb2xvcl9mbGFnJyBmb3IgJ3skY29sb3JfY29sfV9jb2xvcicuIiApOwoJCQkJfSBlbHNlIHsKCQkJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkbWF0Y2hlc1swXTsKCQkJCX0KCQkJfQoJCQkkY29sb3JzWyAkY29sb3JfY29sIF0gPSAkY29sb3JzWyAkY29sb3JfY29sIF0gPyBbIFdQX0NMSTo6Y29sb3JpemUoICRjb2xvcnNbICRjb2xvcl9jb2wgXSApLCAkY29sb3JfcmVzZXQgXSA6IFsgJycsICcnIF07CgkJfQoKCQlyZXR1cm4gJGNvbG9yczsKCX0KCgkvKioKCSAqIEhlbHBlciB0byBwbHVjayBgbXlzcWxgIG9wdGlvbnMgZnJvbSBhc3NvY2lhdGl2ZSBhcmdzIGFycmF5LgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBBc3NvY2lhdGl2ZSBhcmdzIGFycmF5LgoJICogQHJldHVybiBhcnJheSBBcnJheSB3aXRoIGBteXNxbGAgb3B0aW9ucyBzZXQgaWYgaW4gcGFzc2VkLWluIGFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9teXNxbF9hcmdzKCAkYXNzb2NfYXJncyApIHsKCgkJJGFsbG93ZWRfbXlzcWxfb3B0aW9ucyA9IFsKCQkJJ2F1dG8tcmVoYXNoJywKCQkJJ2F1dG8tdmVydGljYWwtb3V0cHV0JywKCQkJJ2JhdGNoJywKCQkJJ2JpbmFyeS1hcy1oZXgnLAoJCQknYmluYXJ5LW1vZGUnLAoJCQknYmluZC1hZGRyZXNzJywKCQkJJ2NoYXJhY3Rlci1zZXRzLWRpcicsCgkJCSdjb2x1bW4tbmFtZXMnLAoJCQknY29sdW1uLXR5cGUtaW5mbycsCgkJCSdjb21tZW50cycsCgkJCSdjb21wcmVzcycsCgkJCSdjb25uZWN0LWV4cGlyZWQtcGFzc3dvcmQnLAoJCQknY29ubmVjdF90aW1lb3V0JywKCQkJJ2RhdGFiYXNlJywKCQkJJ2RlYnVnJywKCQkJJ2RlYnVnLWNoZWNrJywKCQkJJ2RlYnVnLWluZm8nLAoJCQknZGVmYXVsdC1hdXRoJywKCQkJJ2RlZmF1bHQtY2hhcmFjdGVyLXNldCcsCgkJCSdkZWZhdWx0cy1leHRyYS1maWxlJywKCQkJJ2RlZmF1bHRzLWZpbGUnLAoJCQknZGVmYXVsdHMtZ3JvdXAtc3VmZml4JywKCQkJJ2RlbGltaXRlcicsCgkJCSdlbmFibGUtY2xlYXJ0ZXh0LXBsdWdpbicsCgkJCSdleGVjdXRlJywKCQkJJ2ZvcmNlJywKCQkJJ2dldC1zZXJ2ZXItcHVibGljLWtleScsCgkJCSdoZWxwJywKCQkJJ2hpc3RpZ25vcmUnLAoJCQknaG9zdCcsCgkJCSdodG1sJywKCQkJJ2lnbm9yZS1zcGFjZXMnLAoJCQknaW5pdC1jb21tYW5kJywKCQkJJ2xpbmUtbnVtYmVycycsCgkJCSdsb2NhbC1pbmZpbGUnLAoJCQknbG9naW4tcGF0aCcsCgkJCSdtYXhfYWxsb3dlZF9wYWNrZXQnLAoJCQknbWF4X2pvaW5fc2l6ZScsCgkJCSduYW1lZC1jb21tYW5kcycsCgkJCSduZXRfYnVmZmVyX2xlbmd0aCcsCgkJCSduby1iZWVwJywKCQkJJ29uZS1kYXRhYmFzZScsCgkJCSdwYWdlcicsCgkJCSdwaXBlJywKCQkJJ3BsdWdpbi1kaXInLAoJCQkncG9ydCcsCgkJCSdwcmludC1kZWZhdWx0cycsCgkJCSdwcm90b2NvbCcsCgkJCSdxdWljaycsCgkJCSdyYXcnLAoJCQkncmVjb25uZWN0JywKCQkJJ2ktYW0tYS1kdW1teScsCgkJCSdzYWZlLXVwZGF0ZXMnLAoJCQknc2VjdXJlLWF1dGgnLAoJCQknc2VsZWN0X2xpbWl0JywKCQkJJ3NlcnZlci1wdWJsaWMta2V5LXBhdGgnLAoJCQknc2hhcmVkLW1lbW9yeS1iYXNlLW5hbWUnLAoJCQknc2hvdy13YXJuaW5ncycsCgkJCSdzaWdpbnQtaWdub3JlJywKCQkJJ3NpbGVudCcsCgkJCSdza2lwLWF1dG8tcmVoYXNoJywKCQkJJ3NraXAtY29sdW1uLW5hbWVzJywKCQkJJ3NraXAtbGluZS1udW1iZXJzJywKCQkJJ3NraXAtbmFtZWQtY29tbWFuZHMnLAoJCQknc2tpcC1wYWdlcicsCgkJCSdza2lwLXJlY29ubmVjdCcsCgkJCSdzb2NrZXQnLAoJCQknc3NsLWNhJywKCQkJJ3NzbC1jYXBhdGgnLAoJCQknc3NsLWNlcnQnLAoJCQknc3NsLWNpcGhlcicsCgkJCSdzc2wtY3JsJywKCQkJJ3NzbC1jcmxwYXRoJywKCQkJJ3NzbC1maXBzLW1vZGUnLAoJCQknc3NsLWtleScsCgkJCSdzc2wtbW9kZScsCgkJCSdzeXNsb2cnLAoJCQkndGFibGUnLAoJCQkndGVlJywKCQkJJ3Rscy12ZXJzaW9uJywKCQkJJ3VuYnVmZmVyZWQnLAoJCQkndmVyYm9zZScsCgkJCSd2ZXJzaW9uJywKCQkJJ3ZlcnRpY2FsJywKCQkJJ3dhaXQnLAoJCQkneG1sJywKCQldOwoKCQkkbXlzcWxfYXJncyA9IFtdOwoKCQlmb3JlYWNoICggJGFzc29jX2FyZ3MgYXMgJG15c3FsX29wdGlvbl9rZXkgPT4gJG15c3FsX29wdGlvbl92YWx1ZSApIHsKCQkJLy8gQ2hlY2sgZmxhZ3MgdG8gbWFrZSBzdXJlIHRoZXkgb25seSBjb250YWluIHZhbGlkIG9wdGlvbnMuCgkJCWlmICggaW5fYXJyYXkoICRteXNxbF9vcHRpb25fa2V5LCAkYWxsb3dlZF9teXNxbF9vcHRpb25zLCB0cnVlICkgJiYgISBlbXB0eSggJG15c3FsX29wdGlvbl92YWx1ZSApICkgewoJCQkJJG15c3FsX2FyZ3NbICRteXNxbF9vcHRpb25fa2V5IF0gPSAkbXlzcWxfb3B0aW9uX3ZhbHVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gJG15c3FsX2FyZ3M7Cgl9CgoJLyoqCgkgKiBXcml0ZXMgb3V0IHRoZSBgLS1uby1kZWZhdWx0c2AgZmxhZyBmb3IgTXlTUUwgY29tbWFuZHMgdW5sZXNzIHRoZSAtLWRlZmF1bHRzIGZsYWcgaXMgc3BlY2lmaWVkIGZvciB0aGUgV1BfQ0xJIGNvbW1hbmQuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3MgYXJyYXkuCgkgKiBAcmV0dXJuIHN0cmluZyBFaXRoZXIgdGhlICctLW5vLWRlZmF1bHRzJyBmbGFnIGZvciB1c2UgaW4gdGhlIGNvbW1hbmQgb3IgYW4gZW1wdHkgc3RyaW5nLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2RlZmF1bHRzX2ZsYWdfc3RyaW5nKCAmJGFzc29jX2FyZ3MgKSB7CgoJCSRmbGFnX3N0cmluZyA9ICcgLS1uby1kZWZhdWx0cyc7CgoJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJ2RlZmF1bHRzJywgJGFzc29jX2FyZ3MgKSApIHsKCgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGVmYXVsdHMnICkgKSB7CgkJCQkkZmxhZ19zdHJpbmcgPSAnJzsKCQkJfQoKCQkJdW5zZXQoICRhc3NvY19hcmdzWydkZWZhdWx0cyddICk7CgoJCX0KCgkJcmV0dXJuICRmbGFnX3N0cmluZzsKCX0KCgkvKioKCSAqIEdldCB0aGUgcXVlcnkgdG8gY2hhbmdlIHRoZSBjdXJyZW50IFNRTCBtb2RlLCBhbmQgZW5zdXJlIGl0cyBXb3JkUHJlc3MgY29tcGF0aWJpbGl0eS4KCSAqCgkgKiBJZiBubyBtb2RlcyBhcmUgcGFzc2VkLCBpdCB3aWxsIGVuc3VyZSB0aGUgY3VycmVudCBNeVNRTCBzZXJ2ZXIgbW9kZXMgYXJlCgkgKiBjb21wYXRpYmxlLgoJICoKCSAqIENvcGllZCBhbmQgYWRhcHRlZCBmcm9tIFdvcmRQcmVzcyBDb3JlIGNvZGUuCgkgKgoJICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzL3dvcmRwcmVzcy1kZXZlbG9wL2Jsb2IvNS40LjAvc3JjL3dwLWluY2x1ZGVzL3dwLWRiLnBocCNMODE3LUw4ODAKCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgVGhlIGFzc29jaWF0aXZlIGFyZ3VtZW50IGFycmF5IHBhc3NlZCB0byB0aGUgY29tbWFuZC4KCSAqIEBwYXJhbSBhcnJheSAkbW9kZXMgICAgICBPcHRpb25hbC4gQSBsaXN0IG9mIFNRTCBtb2RlcyB0byBzZXQuCgkgKiBAcmV0dXJuIHN0cmluZyBRdWVyeSBzdHJpbmcgdG8gdXNlIGZvciBzZXR0aW5nIHRoZSBTUUwgbW9kZXMgdG8gYQoJICogICAgICAgICAgICAgICAgY29tcGF0aWJsZSBzdGF0ZS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9zcWxfbW9kZV9xdWVyeSggJGFzc29jX2FyZ3MsICRtb2RlcyA9IFtdICkgewoJCWlmICggZW1wdHkoICRtb2RlcyApICkgewoJCQkkbW9kZXMgPSAkdGhpcy0+Z2V0X2N1cnJlbnRfc3FsX21vZGVzKCAkYXNzb2NfYXJncyApOwoJCX0KCgkJJG1vZGVzID0gYXJyYXlfY2hhbmdlX2tleV9jYXNlKCAkbW9kZXMsIENBU0VfVVBQRVIgKTsKCgkJJGlzX21vZGVfYWRhcHRhdGlvbl9uZWVkZWQgPSBmYWxzZTsKCQlmb3JlYWNoICggJG1vZGVzIGFzICRpID0+ICRtb2RlICkgewoJCQlpZiAoIGluX2FycmF5KCAkbW9kZSwgJHRoaXMtPnNxbF9pbmNvbXBhdGlibGVfbW9kZXMsIHRydWUgKSApIHsKCQkJCXVuc2V0KCAkbW9kZXNbICRpIF0gKTsKCQkJCSRpc19tb2RlX2FkYXB0YXRpb25fbmVlZGVkID0gdHJ1ZTsKCQkJfQoJCX0KCgkJaWYgKCAhICRpc19tb2RlX2FkYXB0YXRpb25fbmVlZGVkICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknU1FMIG1vZGVzIGxvb2sgZmluZTogJXMnLAoJCQkJCWpzb25fZW5jb2RlKCAkbW9kZXMgKQoJCQkJKQoJCQkpOwoJCQlyZXR1cm4gJyc7CgkJfQoKCQlXUF9DTEk6OmRlYnVnKAoJCQlzcHJpbnRmKAoJCQkJJ1NRTCBtb2RlIGFkYXB0YXRpb24gaXMgbmVlZGVkOiAlcyA9PiAlcycsCgkJCQlqc29uX2VuY29kZSggJHRoaXMtPmdldF9jdXJyZW50X3NxbF9tb2RlcyggJGFzc29jX2FyZ3MgKSApLAoJCQkJanNvbl9lbmNvZGUoICRtb2RlcyApCgkJCSkKCQkpOwoKCQkkbW9kZXNfc3RyID0gaW1wbG9kZSggJywnLCAkbW9kZXMgKTsKCgkJcmV0dXJuICJTRVQgU0VTU0lPTiBzcWxfbW9kZT0neyRtb2Rlc19zdHJ9JzsiOwoJfQoKCS8qKgoJICogR2V0IHRoZSBsaXN0IG9mIGN1cnJlbnQgU1FMIG1vZGVzLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBUaGUgYXNzb2NpYXRpdmUgYXJndW1lbnQgYXJyYXkgcGFzc2VkIHRvIHRoZSBjb21tYW5kLgoJICogQHJldHVybiBzdHJpbmdbXSBBcnJheSBvZiBTUUwgbW9kZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfY3VycmVudF9zcWxfbW9kZXMoICRhc3NvY19hcmdzICkgewoJCXN0YXRpYyAkbW9kZXMgPSBudWxsOwoKCQkvLyBNYWtlIHN1cmUgdGhlIHByb3ZpZGVkIGFyZ3VtZW50cyBkb24ndCBpbnRlcmZlcmUgd2l0aCB0aGUgZXhwZWN0ZWQKCQkvLyBvdXRwdXQgaGVyZS4KCQkkYXJncyA9IFtdOwoJCWZvcmVhY2ggKCBbXSBhcyAkYXJnICkgewoJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJGFyZyBdICkgKSB7CgkJCQkkYXJnc1sgJGFyZyBdID0gJGFzc29jX2FyZ3NbICRhcmcgXTsKCQkJfQoJCX0KCgkJaWYgKCBudWxsID09PSAkbW9kZXMgKSB7CgkJCSRtb2RlcyA9IFtdOwoKCQkJbGlzdCggJHN0ZG91dCwgJHN0ZGVyciwgJGV4aXRfY29kZSApID0gc2VsZjo6cnVuKAoJCQkJc3ByaW50ZigKCQkJCQknL3Vzci9iaW4vZW52IG15c3FsJXMgLS1uby1hdXRvLXJlaGFzaCAtLWJhdGNoIC0tc2tpcC1jb2x1bW4tbmFtZXMnLAoJCQkJCSR0aGlzLT5nZXRfZGVmYXVsdHNfZmxhZ19zdHJpbmcoICRhc3NvY19hcmdzICkKCQkJCSksCgkJCQlhcnJheV9tZXJnZSggJGFyZ3MsIFsgJ2V4ZWN1dGUnID0+ICdTRUxFQ1QgQEBTRVNTSU9OLnNxbF9tb2RlJyBdICksCgkJCQlmYWxzZQoJCQkpOwoKCQkJaWYgKCAkZXhpdF9jb2RlICkgewoJCQkJV1BfQ0xJOjplcnJvcigKCQkJCQknRmFpbGVkIHRvIGdldCBjdXJyZW50IFNRTCBtb2Rlcy4nCgkJCQkJLiAoICEgZW1wdHkoICRzdGRlcnIgKSA/ICIgUmVhc29uOiB7JHN0ZGVycn0iIDogJycgKSwKCQkJCQkkZXhpdF9jb2RlCgkJCQkpOwoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRzdGRvdXQgKSApIHsKCQkJCSRtb2RlcyA9IGFycmF5X2ZpbHRlcigKCQkJCQlhcnJheV9tYXAoCgkJCQkJCSd0cmltJywKCQkJCQkJcHJlZ19zcGxpdCggIi9cclxufFxufFxyfCwvIiwgJHN0ZG91dCApCgkJCQkJKQoJCQkJKTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJG1vZGVzICkgewoJCQkJJG1vZGVzID0gW107CgkJCX0KCQl9CgoJCXJldHVybiAkbW9kZXM7Cgl9Cn0KPD9waHAKCi8qKgogKiBUcmFuc2Zvcm1zIGEgd3AtY29uZmlnLnBocCBmaWxlLgogKi8KY2xhc3MgV1BDb25maWdUcmFuc2Zvcm1lciB7CgkvKioKCSAqIEFwcGVuZCB0byBlbmQgb2YgZmlsZQoJICovCgljb25zdCBBTkNIT1JfRU9GID0gJ0VPRic7CgoJLyoqCgkgKiBQYXRoIHRvIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICR3cF9jb25maWdfcGF0aDsKCgkvKioKCSAqIE9yaWdpbmFsIHNvdXJjZSBvZiB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkd3BfY29uZmlnX3NyYzsKCgkvKioKCSAqIEFycmF5IG9mIHBhcnNlZCBjb25maWdzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICR3cF9jb25maWdzID0gYXJyYXkoKTsKCgkvKioKCSAqIEluc3RhbnRpYXRlcyB0aGUgY2xhc3Mgd2l0aCBhIHZhbGlkIHdwLWNvbmZpZy5waHAuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHdwLWNvbmZpZy5waHAgZmlsZSBpcyBtaXNzaW5nLgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHdwLWNvbmZpZy5waHAgZmlsZSBpcyBub3Qgd3JpdGFibGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd3BfY29uZmlnX3BhdGggUGF0aCB0byBhIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkd3BfY29uZmlnX3BhdGggKSB7CgkJJGJhc2VuYW1lID0gYmFzZW5hbWUoICR3cF9jb25maWdfcGF0aCApOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICR3cF9jb25maWdfcGF0aCApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAieyRiYXNlbmFtZX0gZG9lcyBub3QgZXhpc3QuIiApOwoJCX0KCgkJaWYgKCAhIGlzX3dyaXRhYmxlKCAkd3BfY29uZmlnX3BhdGggKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggInskYmFzZW5hbWV9IGlzIG5vdCB3cml0YWJsZS4iICk7CgkJfQoKCQkkdGhpcy0+d3BfY29uZmlnX3BhdGggPSAkd3BfY29uZmlnX3BhdGg7Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgYSBjb25maWcgZXhpc3RzIGluIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHdwLWNvbmZpZy5waHAgZmlsZSBpcyBlbXB0eS4KCSAqIEB0aHJvd3MgRXhjZXB0aW9uIElmIHRoZSByZXF1ZXN0ZWQgY29uZmlnIHR5cGUgaXMgaW52YWxpZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlIENvbmZpZyB0eXBlIChjb25zdGFudCBvciB2YXJpYWJsZSkuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIENvbmZpZyBuYW1lLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gZXhpc3RzKCAkdHlwZSwgJG5hbWUgKSB7CgkJJHdwX2NvbmZpZ19zcmMgPSBmaWxlX2dldF9jb250ZW50cyggJHRoaXMtPndwX2NvbmZpZ19wYXRoICk7CgoJCWlmICggISB0cmltKCAkd3BfY29uZmlnX3NyYyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnQ29uZmlnIGZpbGUgaXMgZW1wdHkuJyApOwoJCX0KCQkvLyBOb3JtYWxpemUgdGhlIG5ld2xpbmUgdG8gcHJldmVudCBhbiBpc3N1ZSBjb21pbmcgZnJvbSBPU1guCgkJJHRoaXMtPndwX2NvbmZpZ19zcmMgPSBzdHJfcmVwbGFjZSggYXJyYXkoICJcblxyIiwgIlxyIiApLCAiXG4iLCAkd3BfY29uZmlnX3NyYyApOwoJCSR0aGlzLT53cF9jb25maWdzICAgID0gJHRoaXMtPnBhcnNlX3dwX2NvbmZpZyggJHRoaXMtPndwX2NvbmZpZ19zcmMgKTsKCgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+d3BfY29uZmlnc1sgJHR5cGUgXSApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiQ29uZmlnIHR5cGUgJ3skdHlwZX0nIGRvZXMgbm90IGV4aXN0LiIgKTsKCQl9CgoJCXJldHVybiBpc3NldCggJHRoaXMtPndwX2NvbmZpZ3NbICR0eXBlIF1bICRuYW1lIF0gKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgb2YgYSBjb25maWcgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbiBJZiB0aGUgd3AtY29uZmlnLnBocCBmaWxlIGlzIGVtcHR5LgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHJlcXVlc3RlZCBjb25maWcgdHlwZSBpcyBpbnZhbGlkLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgQ29uZmlnIHR5cGUgKGNvbnN0YW50IG9yIHZhcmlhYmxlKS4KCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgQ29uZmlnIG5hbWUuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X3ZhbHVlKCAkdHlwZSwgJG5hbWUgKSB7CgkJJHdwX2NvbmZpZ19zcmMgPSBmaWxlX2dldF9jb250ZW50cyggJHRoaXMtPndwX2NvbmZpZ19wYXRoICk7CgoJCWlmICggISB0cmltKCAkd3BfY29uZmlnX3NyYyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnQ29uZmlnIGZpbGUgaXMgZW1wdHkuJyApOwoJCX0KCgkJJHRoaXMtPndwX2NvbmZpZ19zcmMgPSAkd3BfY29uZmlnX3NyYzsKCQkkdGhpcy0+d3BfY29uZmlncyAgICA9ICR0aGlzLT5wYXJzZV93cF9jb25maWcoICR0aGlzLT53cF9jb25maWdfc3JjICk7CgoJCWlmICggISBpc3NldCggJHRoaXMtPndwX2NvbmZpZ3NbICR0eXBlIF0gKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggIkNvbmZpZyB0eXBlICd7JHR5cGV9JyBkb2VzIG5vdCBleGlzdC4iICk7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPndwX2NvbmZpZ3NbICR0eXBlIF1bICRuYW1lIF1bJ3ZhbHVlJ107Cgl9CgoJLyoqCgkgKiBBZGRzIGEgY29uZmlnIHRvIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIGNvbmZpZyB2YWx1ZSBwcm92aWRlZCBpcyBub3QgYSBzdHJpbmcuCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbiBJZiB0aGUgY29uZmlnIHBsYWNlbWVudCBhbmNob3IgY291bGQgbm90IGJlIGxvY2F0ZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdHlwZSAgICBDb25maWcgdHlwZSAoY29uc3RhbnQgb3IgdmFyaWFibGUpLgoJICogQHBhcmFtIHN0cmluZyAkbmFtZSAgICBDb25maWcgbmFtZS4KCSAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlICAgQ29uZmlnIHZhbHVlLgoJICogQHBhcmFtIGFycmF5ICAkb3B0aW9ucyAob3B0aW9uYWwpIEFycmF5IG9mIHNwZWNpYWwgYmVoYXZpb3Igb3B0aW9ucy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJHR5cGUsICRuYW1lLCAkdmFsdWUsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSApIHsKCQlpZiAoICEgaXNfc3RyaW5nKCAkdmFsdWUgKSApIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbiggJ0NvbmZpZyB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nLicgKTsKCQl9CgoJCWlmICggJHRoaXMtPmV4aXN0cyggJHR5cGUsICRuYW1lICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRkZWZhdWx0cyA9IGFycmF5KAoJCQkncmF3JyAgICAgICA9PiBmYWxzZSwgLy8gRGlzcGxheSB2YWx1ZSBpbiByYXcgZm9ybWF0IHdpdGhvdXQgcXVvdGVzLgoJCQknYW5jaG9yJyAgICA9PiAiLyogVGhhdCdzIGFsbCwgc3RvcCBlZGl0aW5nISIsIC8vIENvbmZpZyBwbGFjZW1lbnQgYW5jaG9yIHN0cmluZy4KCQkJJ3NlcGFyYXRvcicgPT4gUEhQX0VPTCwgLy8gU2VwYXJhdG9yIGJldHdlZW4gY29uZmlnIGRlZmluaXRpb24gYW5kIGFuY2hvciBzdHJpbmcuCgkJCSdwbGFjZW1lbnQnID0+ICdiZWZvcmUnLCAvLyBDb25maWcgcGxhY2VtZW50IGRpcmVjdGlvbiAoaW5zZXJ0IGJlZm9yZSBvciBhZnRlcikuCgkJKTsKCgkJbGlzdCggJHJhdywgJGFuY2hvciwgJHNlcGFyYXRvciwgJHBsYWNlbWVudCApID0gYXJyYXlfdmFsdWVzKCBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkb3B0aW9ucyApICk7CgoJCSRyYXcgICAgICAgPSAoYm9vbCkgJHJhdzsKCQkkYW5jaG9yICAgID0gKHN0cmluZykgJGFuY2hvcjsKCQkkc2VwYXJhdG9yID0gKHN0cmluZykgJHNlcGFyYXRvcjsKCQkkcGxhY2VtZW50ID0gKHN0cmluZykgJHBsYWNlbWVudDsKCgkJaWYgKCBzZWxmOjpBTkNIT1JfRU9GID09PSAkYW5jaG9yICkgewoJCQkkY29udGVudHMgPSAkdGhpcy0+d3BfY29uZmlnX3NyYyAuICR0aGlzLT5ub3JtYWxpemUoICR0eXBlLCAkbmFtZSwgJHRoaXMtPmZvcm1hdF92YWx1ZSggJHZhbHVlLCAkcmF3ICkgKTsKCQl9IGVsc2UgewoJCQlpZiAoIGZhbHNlID09PSBzdHJwb3MoICR0aGlzLT53cF9jb25maWdfc3JjLCAkYW5jaG9yICkgKSB7CgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnVW5hYmxlIHRvIGxvY2F0ZSBwbGFjZW1lbnQgYW5jaG9yLicgKTsKCQkJfQoKCQkJJG5ld19zcmMgID0gJHRoaXMtPm5vcm1hbGl6ZSggJHR5cGUsICRuYW1lLCAkdGhpcy0+Zm9ybWF0X3ZhbHVlKCAkdmFsdWUsICRyYXcgKSApOwoJCQkkbmV3X3NyYyAgPSAoICdhZnRlcicgPT09ICRwbGFjZW1lbnQgKSA/ICRhbmNob3IgLiAkc2VwYXJhdG9yIC4gJG5ld19zcmMgOiAkbmV3X3NyYyAuICRzZXBhcmF0b3IgLiAkYW5jaG9yOwoJCQkkY29udGVudHMgPSBzdHJfcmVwbGFjZSggJGFuY2hvciwgJG5ld19zcmMsICR0aGlzLT53cF9jb25maWdfc3JjICk7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPnNhdmUoICRjb250ZW50cyApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBhbiBleGlzdGluZyBjb25maWcgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbiBJZiB0aGUgY29uZmlnIHZhbHVlIHByb3ZpZGVkIGlzIG5vdCBhIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlICAgIENvbmZpZyB0eXBlIChjb25zdGFudCBvciB2YXJpYWJsZSkuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgIENvbmZpZyBuYW1lLgoJICogQHBhcmFtIHN0cmluZyAkdmFsdWUgICBDb25maWcgdmFsdWUuCgkgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zIChvcHRpb25hbCkgQXJyYXkgb2Ygc3BlY2lhbCBiZWhhdmlvciBvcHRpb25zLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gdXBkYXRlKCAkdHlwZSwgJG5hbWUsICR2YWx1ZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpICkgewoJCWlmICggISBpc19zdHJpbmcoICR2YWx1ZSApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnQ29uZmlnIHZhbHVlIG11c3QgYmUgYSBzdHJpbmcuJyApOwoJCX0KCgkJJGRlZmF1bHRzID0gYXJyYXkoCgkJCSdhZGQnICAgICAgID0+IHRydWUsIC8vIEFkZCB0aGUgY29uZmlnIGlmIG1pc3NpbmcuCgkJCSdyYXcnICAgICAgID0+IGZhbHNlLCAvLyBEaXNwbGF5IHZhbHVlIGluIHJhdyBmb3JtYXQgd2l0aG91dCBxdW90ZXMuCgkJCSdub3JtYWxpemUnID0+IGZhbHNlLCAvLyBOb3JtYWxpemUgY29uZmlnIG91dHB1dCB1c2luZyBXUCBDb2RpbmcgU3RhbmRhcmRzLgoJCSk7CgoJCWxpc3QoICRhZGQsICRyYXcsICRub3JtYWxpemUgKSA9IGFycmF5X3ZhbHVlcyggYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJG9wdGlvbnMgKSApOwoKCQkkYWRkICAgICAgID0gKGJvb2wpICRhZGQ7CgkJJHJhdyAgICAgICA9IChib29sKSAkcmF3OwoJCSRub3JtYWxpemUgPSAoYm9vbCkgJG5vcm1hbGl6ZTsKCgkJaWYgKCAhICR0aGlzLT5leGlzdHMoICR0eXBlLCAkbmFtZSApICkgewoJCQlyZXR1cm4gKCAkYWRkICkgPyAkdGhpcy0+YWRkKCAkdHlwZSwgJG5hbWUsICR2YWx1ZSwgJG9wdGlvbnMgKSA6IGZhbHNlOwoJCX0KCgkJJG9sZF9zcmMgICA9ICR0aGlzLT53cF9jb25maWdzWyAkdHlwZSBdWyAkbmFtZSBdWydzcmMnXTsKCQkkb2xkX3ZhbHVlID0gJHRoaXMtPndwX2NvbmZpZ3NbICR0eXBlIF1bICRuYW1lIF1bJ3ZhbHVlJ107CgkJJG5ld192YWx1ZSA9ICR0aGlzLT5mb3JtYXRfdmFsdWUoICR2YWx1ZSwgJHJhdyApOwoKCQlpZiAoICRub3JtYWxpemUgKSB7CgkJCSRuZXdfc3JjID0gJHRoaXMtPm5vcm1hbGl6ZSggJHR5cGUsICRuYW1lLCAkbmV3X3ZhbHVlICk7CgkJfSBlbHNlIHsKCQkJJG5ld19wYXJ0cyAgICA9ICR0aGlzLT53cF9jb25maWdzWyAkdHlwZSBdWyAkbmFtZSBdWydwYXJ0cyddOwoJCQkkbmV3X3BhcnRzWzFdID0gc3RyX3JlcGxhY2UoICRvbGRfdmFsdWUsICRuZXdfdmFsdWUsICRuZXdfcGFydHNbMV0gKTsgLy8gT25seSBlZGl0IHRoZSB2YWx1ZSBwYXJ0LgoJCQkkbmV3X3NyYyAgICAgID0gaW1wbG9kZSggJycsICRuZXdfcGFydHMgKTsKCQl9CgoJCSRjb250ZW50cyA9IHByZWdfcmVwbGFjZSgKCQkJc3ByaW50ZiggJy8oPzw9Xnw7fDxcP3BocFxzfDxcP1xzKShccyo/KSVzL20nLCBwcmVnX3F1b3RlKCB0cmltKCAkb2xkX3NyYyApLCAnLycgKSApLAoJCQknJDEnIC4gc3RyX3JlcGxhY2UoICckJywgJ1wkJywgdHJpbSggJG5ld19zcmMgKSApLAoJCQkkdGhpcy0+d3BfY29uZmlnX3NyYwoJCSk7CgoJCXJldHVybiAkdGhpcy0+c2F2ZSggJGNvbnRlbnRzICk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgY29uZmlnIGZyb20gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlIENvbmZpZyB0eXBlIChjb25zdGFudCBvciB2YXJpYWJsZSkuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIENvbmZpZyBuYW1lLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAkdHlwZSwgJG5hbWUgKSB7CgkJaWYgKCAhICR0aGlzLT5leGlzdHMoICR0eXBlLCAkbmFtZSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkcGF0dGVybiAgPSBzcHJpbnRmKCAnLyg/PD1efDt8PFw/cGhwXHN8PFw/XHMpJXNccyooXFN8JCkvbScsIHByZWdfcXVvdGUoICR0aGlzLT53cF9jb25maWdzWyAkdHlwZSBdWyAkbmFtZSBdWydzcmMnXSwgJy8nICkgKTsKCQkkY29udGVudHMgPSBwcmVnX3JlcGxhY2UoICRwYXR0ZXJuLCAnJDEnLCAkdGhpcy0+d3BfY29uZmlnX3NyYyApOwoKCQlyZXR1cm4gJHRoaXMtPnNhdmUoICRjb250ZW50cyApOwoJfQoKCS8qKgoJICogQXBwbGllcyBmb3JtYXR0aW5nIHRvIGEgY29uZmlnIHZhbHVlLgoJICoKCSAqIEB0aHJvd3MgRXhjZXB0aW9uIFdoZW4gYSByYXcgdmFsdWUgaXMgcmVxdWVzdGVkIGZvciBhbiBlbXB0eSBzdHJpbmcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdmFsdWUgQ29uZmlnIHZhbHVlLgoJICogQHBhcmFtIGJvb2wgICAkcmF3ICAgRGlzcGxheSB2YWx1ZSBpbiByYXcgZm9ybWF0IHdpdGhvdXQgcXVvdGVzLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGZvcm1hdF92YWx1ZSggJHZhbHVlLCAkcmF3ICkgewoJCWlmICggJHJhdyAmJiAnJyA9PT0gdHJpbSggJHZhbHVlICkgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICdSYXcgdmFsdWUgZm9yIGVtcHR5IHN0cmluZyBub3Qgc3VwcG9ydGVkLicgKTsKCQl9CgoJCXJldHVybiAoICRyYXcgKSA/ICR2YWx1ZSA6IHZhcl9leHBvcnQoICR2YWx1ZSwgdHJ1ZSApOwoJfQoKCS8qKgoJICogTm9ybWFsaXplcyB0aGUgc291cmNlIG91dHB1dCBmb3IgYSBuYW1lL3ZhbHVlIHBhaXIuCgkgKgoJICogQHRocm93cyBFeGNlcHRpb24gSWYgdGhlIHJlcXVlc3RlZCBjb25maWcgdHlwZSBkb2VzIG5vdCBzdXBwb3J0IG5vcm1hbGl6YXRpb24uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdHlwZSAgQ29uZmlnIHR5cGUgKGNvbnN0YW50IG9yIHZhcmlhYmxlKS4KCSAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgIENvbmZpZyBuYW1lLgoJICogQHBhcmFtIG1peGVkICAkdmFsdWUgQ29uZmlnIHZhbHVlLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBub3JtYWxpemUoICR0eXBlLCAkbmFtZSwgJHZhbHVlICkgewoJCWlmICggJ2NvbnN0YW50JyA9PT0gJHR5cGUgKSB7CgkJCSRwbGFjZWhvbGRlciA9ICJkZWZpbmUoICclcycsICVzICk7IjsKCQl9IGVsc2VpZiAoICd2YXJpYWJsZScgPT09ICR0eXBlICkgewoJCQkkcGxhY2Vob2xkZXIgPSAnJCVzID0gJXM7JzsKCQl9IGVsc2UgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAiVW5hYmxlIHRvIG5vcm1hbGl6ZSBjb25maWcgdHlwZSAneyR0eXBlfScuIiApOwoJCX0KCgkJcmV0dXJuIHNwcmludGYoICRwbGFjZWhvbGRlciwgJG5hbWUsICR2YWx1ZSApOwoJfQoKCS8qKgoJICogUGFyc2VzIHRoZSBzb3VyY2Ugb2YgYSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc3JjIENvbmZpZyBmaWxlIHNvdXJjZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZV93cF9jb25maWcoICRzcmMgKSB7CgkJJGNvbmZpZ3MgICAgICAgICAgICAgPSBhcnJheSgpOwoJCSRjb25maWdzWydjb25zdGFudCddID0gYXJyYXkoKTsKCQkkY29uZmlnc1sndmFyaWFibGUnXSA9IGFycmF5KCk7CgoJCS8vIFN0cmlwIGNvbW1lbnRzLgoJCWZvcmVhY2ggKCB0b2tlbl9nZXRfYWxsKCAkc3JjICkgYXMgJHRva2VuICkgewoJCQlpZiAoIGluX2FycmF5KCAkdG9rZW5bMF0sIGFycmF5KCBUX0NPTU1FTlQsIFRfRE9DX0NPTU1FTlQgKSwgdHJ1ZSApICkgewoJCQkJJHNyYyA9IHN0cl9yZXBsYWNlKCAkdG9rZW5bMV0sICcnLCAkc3JjICk7CgkJCX0KCQl9CgoJCXByZWdfbWF0Y2hfYWxsKCAnLyg/PD1efDt8PFw/cGhwXHN8PFw/XHMpKFxoKmRlZmluZVxzKlwoXHMqW1wnIl0oXHcqPylbXCciXVxzKikoLFxzKihcJ1wnfCIifFwnLio/W15cXFxcXVwnfCIuKj9bXlxcXFxdInwuKj8pXHMqKSgoPzosXHMqKD86dHJ1ZXxmYWxzZSlccyopP1wpXHMqOykvaW1zJywgJHNyYywgJGNvbnN0YW50cyApOwoJCXByZWdfbWF0Y2hfYWxsKCAnLyg/PD1efDt8PFw/cGhwXHN8PFw/XHMpKFxoKlwkKFx3Kylccyo9KShccyooXCdcJ3wiInxcJy4qP1teXFxcXF1cJ3wiLio/W15cXFxcXSJ8Lio/KVxzKjspL2ltcycsICRzcmMsICR2YXJpYWJsZXMgKTsKCgkJaWYgKCAhIGVtcHR5KCAkY29uc3RhbnRzWzBdICkgJiYgISBlbXB0eSggJGNvbnN0YW50c1sxXSApICYmICEgZW1wdHkoICRjb25zdGFudHNbMl0gKSAmJiAhIGVtcHR5KCAkY29uc3RhbnRzWzNdICkgJiYgISBlbXB0eSggJGNvbnN0YW50c1s0XSApICYmICEgZW1wdHkoICRjb25zdGFudHNbNV0gKSApIHsKCQkJZm9yZWFjaCAoICRjb25zdGFudHNbMl0gYXMgJGluZGV4ID0+ICRuYW1lICkgewoJCQkJJGNvbmZpZ3NbJ2NvbnN0YW50J11bICRuYW1lIF0gPSBhcnJheSgKCQkJCQknc3JjJyAgID0+ICRjb25zdGFudHNbMF1bICRpbmRleCBdLAoJCQkJCSd2YWx1ZScgPT4gJGNvbnN0YW50c1s0XVsgJGluZGV4IF0sCgkJCQkJJ3BhcnRzJyA9PiBhcnJheSgKCQkJCQkJJGNvbnN0YW50c1sxXVsgJGluZGV4IF0sCgkJCQkJCSRjb25zdGFudHNbM11bICRpbmRleCBdLAoJCQkJCQkkY29uc3RhbnRzWzVdWyAkaW5kZXggXSwKCQkJCQkpLAoJCQkJKTsKCQkJfQoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkdmFyaWFibGVzWzBdICkgJiYgISBlbXB0eSggJHZhcmlhYmxlc1sxXSApICYmICEgZW1wdHkoICR2YXJpYWJsZXNbMl0gKSAmJiAhIGVtcHR5KCAkdmFyaWFibGVzWzNdICkgJiYgISBlbXB0eSggJHZhcmlhYmxlc1s0XSApICkgewoJCQkvLyBSZW1vdmUgZHVwbGljYXRlKHMpLCBsYXN0IGRlZmluaXRpb24gd2lucy4KCQkJJHZhcmlhYmxlc1syXSA9IGFycmF5X3JldmVyc2UoIGFycmF5X3VuaXF1ZSggYXJyYXlfcmV2ZXJzZSggJHZhcmlhYmxlc1syXSwgdHJ1ZSApICksIHRydWUgKTsKCQkJZm9yZWFjaCAoICR2YXJpYWJsZXNbMl0gYXMgJGluZGV4ID0+ICRuYW1lICkgewoJCQkJJGNvbmZpZ3NbJ3ZhcmlhYmxlJ11bICRuYW1lIF0gPSBhcnJheSgKCQkJCQknc3JjJyAgID0+ICR2YXJpYWJsZXNbMF1bICRpbmRleCBdLAoJCQkJCSd2YWx1ZScgPT4gJHZhcmlhYmxlc1s0XVsgJGluZGV4IF0sCgkJCQkJJ3BhcnRzJyA9PiBhcnJheSgKCQkJCQkJJHZhcmlhYmxlc1sxXVsgJGluZGV4IF0sCgkJCQkJCSR2YXJpYWJsZXNbM11bICRpbmRleCBdLAoJCQkJCSksCgkJCQkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGNvbmZpZ3M7Cgl9CgoJLyoqCgkgKiBTYXZlcyBuZXcgY29udGVudHMgdG8gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbiBJZiB0aGUgY29uZmlnIGZpbGUgY29udGVudCBwcm92aWRlZCBpcyBlbXB0eS4KCSAqIEB0aHJvd3MgRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgZmFpbHVyZSB3aGVuIHNhdmluZyB0aGUgd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbnRlbnRzIE5ldyBjb25maWcgY29udGVudHMuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzYXZlKCAkY29udGVudHMgKSB7CgkJaWYgKCAhIHRyaW0oICRjb250ZW50cyApICkgewoJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCAnQ2Fubm90IHNhdmUgdGhlIGNvbmZpZyBmaWxlIHdpdGggZW1wdHkgY29udGVudHMuJyApOwoJCX0KCgkJaWYgKCAkY29udGVudHMgPT09ICR0aGlzLT53cF9jb25maWdfc3JjICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkcmVzdWx0ID0gZmlsZV9wdXRfY29udGVudHMoICR0aGlzLT53cF9jb25maWdfcGF0aCwgJGNvbnRlbnRzLCBMT0NLX0VYICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICdGYWlsZWQgdG8gdXBkYXRlIHRoZSBjb25maWcgZmlsZS4nICk7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9tZWRpYV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9tZWRpYV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX21lZGlhX2F1dG9sb2FkZXI7Cn0KCi8qKgogKiBDaGVjayBmb3IgSW1hZ2ljayBhbmQgR0QgZXh0ZW5zaW9ucyBhdmFpbGFiaWxpdHkuCiAqCiAqIEB0aHJvd3MgXFdQX0NMSVxFeGl0RXhjZXB0aW9uCiAqLwokd3BjbGlfbWVkaWFfYXNzZXJ0X2ltYWdlX2VkaXRvcl9zdXBwb3J0ID0gZnVuY3Rpb24gKCkgewoJaWYgKCAhIHdwX2ltYWdlX2VkaXRvcl9zdXBwb3J0cygpICkgewoJCVdQX0NMSTo6ZXJyb3IoCgkJCSdObyBzdXBwb3J0IGZvciBnZW5lcmF0aW5nIGltYWdlcyBmb3VuZC4gJwoJCQkuICdQbGVhc2UgaW5zdGFsbCB0aGUgSW1hZ2ljayBvciBHRCBQSFAgZXh0ZW5zaW9ucy4nCgkJKTsKCX0KfTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoCgknbWVkaWEnLAoJJ01lZGlhX0NvbW1hbmQnLAoJWyAnYmVmb3JlX2ludm9rZScgPT4gJHdwY2xpX21lZGlhX2Fzc2VydF9pbWFnZV9lZGl0b3Jfc3VwcG9ydCBdCik7Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwoKLyoqCiAqIEltcG9ydHMgZmlsZXMgYXMgYXR0YWNobWVudHMsIHJlZ2VuZXJhdGVzIHRodW1ibmFpbHMsIG9yIGxpc3RzIHJlZ2lzdGVyZWQgaW1hZ2Ugc2l6ZXMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFJlLWdlbmVyYXRlIGFsbCB0aHVtYm5haWxzLCB3aXRob3V0IGNvbmZpcm1hdGlvbi4KICogICAgICQgd3AgbWVkaWEgcmVnZW5lcmF0ZSAtLXllcwogKiAgICAgRm91bmQgMyBpbWFnZXMgdG8gcmVnZW5lcmF0ZS4KICogICAgIDEvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiU3lkbmV5IEhhcmJvciBCcmlkZ2UiIChJRCA3NjApLgogKiAgICAgMi8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJCb2FyZHdhbGsiIChJRCA3NTcpLgogKiAgICAgMy8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJTdW5idXJzdCBPdmVyIFJpdmVyIiAoSUQgNzU2KS4KICogICAgIFN1Y2Nlc3M6IFJlZ2VuZXJhdGVkIDMgb2YgMyBpbWFnZXMuCiAqCiAqICAgICAjIEltcG9ydCBhIGxvY2FsIGltYWdlIGFuZCBzZXQgaXQgdG8gYmUgdGhlIGZlYXR1cmVkIGltYWdlIGZvciBhIHBvc3QuCiAqICAgICAkIHdwIG1lZGlhIGltcG9ydCB+L0Rvd25sb2Fkcy9pbWFnZS5wbmcgLS1wb3N0X2lkPTEyMyAtLXRpdGxlPSJBIGRvd25sb2FkZWQgcGljdHVyZSIgLS1mZWF0dXJlZF9pbWFnZQogKiAgICAgU3VjY2VzczogSW1wb3J0ZWQgZmlsZSAnL2hvbWUvcGVyc29uL0Rvd25sb2Fkcy9pbWFnZS5wbmcnIGFzIGF0dGFjaG1lbnQgSUQgMTc1MyBhbmQgYXR0YWNoZWQgdG8gcG9zdCAxMjMgYXMgZmVhdHVyZWQgaW1hZ2UuCiAqCiAqICAgICAjIExpc3QgYWxsIHJlZ2lzdGVyZWQgaW1hZ2Ugc2l6ZXMKICogICAgICQgd3AgbWVkaWEgaW1hZ2Utc2l6ZQogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tKy0tLS0tLS0rCiAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICAgICAgfCB3aWR0aCB8IGhlaWdodCB8IGNyb3AgIHwKICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKwogKiAgICAgfCBmdWxsICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfCAgICAgICAgfCBOL0EgICB8CiAqICAgICB8IHR3ZW50eWZvdXJ0ZWVuLWZ1bGwtd2lkdGggfCAxMDM4ICB8IDU3NiAgICB8IGhhcmQgIHwKICogICAgIHwgbGFyZ2UgICAgICAgICAgICAgICAgICAgICB8IDEwMjQgIHwgMTAyNCAgIHwgc29mdCAgfAogKiAgICAgfCBtZWRpdW1fbGFyZ2UgICAgICAgICAgICAgIHwgNzY4ICAgfCAwICAgICAgfCBzb2Z0ICB8CiAqICAgICB8IG1lZGl1bSAgICAgICAgICAgICAgICAgICAgfCAzMDAgICB8IDMwMCAgICB8IHNvZnQgIHwKICogICAgIHwgdGh1bWJuYWlsICAgICAgICAgICAgICAgICB8IDE1MCAgIHwgMTUwICAgIHwgaGFyZCAgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tKy0tLS0tLS0rCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgTWVkaWFfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIENsZWFyIHRoZSBXUCBvYmplY3QgY2FjaGUgYWZ0ZXIgdGhpcyBtYW55IHJlZ2VuZXJhdGlvbnMvaW1wb3J0cy4KCSAqCgkgKiBAdmFyIGludGVnZXIKCSAqLwoJY29uc3QgV1BfQ0xFQVJfT0JKRUNUX0NBQ0hFX0lOVEVSVkFMID0gNTAwOwoKCS8qKgoJICogUmVnZW5lcmF0ZXMgdGh1bWJuYWlscyBmb3Igb25lIG9yIG1vcmUgYXR0YWNobWVudHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8YXR0YWNobWVudC1pZD4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIElEcyBvZiB0aGUgYXR0YWNobWVudHMgdG8gcmVnZW5lcmF0ZS4KCSAqCgkgKiBbLS1pbWFnZV9zaXplPTxpbWFnZV9zaXplPl0KCSAqIDogTmFtZSBvZiB0aGUgaW1hZ2Ugc2l6ZSB0byByZWdlbmVyYXRlLiBPbmx5IHRodW1ibmFpbHMgb2YgdGhpcyBpbWFnZSBzaXplIHdpbGwgYmUgcmVnZW5lcmF0ZWQsIHRodW1ibmFpbHMgb2Ygb3RoZXIgaW1hZ2Ugc2l6ZXMgd2lsbCBub3QuCgkgKgoJICogWy0tc2tpcC1kZWxldGVdCgkgKiA6IFNraXAgZGVsZXRpb24gb2YgdGhlIG9yaWdpbmFsIHRodW1ibmFpbHMuIElmIHlvdXIgdGh1bWJuYWlscyBhcmUgbGlua2VkIGZyb20gc291cmNlcyBvdXRzaWRlIHlvdXIgY29udHJvbCwgaXQncyBsaWtlbHkgYmVzdCB0byBsZWF2ZSB0aGVtIGFyb3VuZC4gRGVmYXVsdHMgdG8gZmFsc2UuCgkgKgoJICogWy0tb25seS1taXNzaW5nXQoJICogOiBPbmx5IGdlbmVyYXRlIHRodW1ibmFpbHMgZm9yIGltYWdlcyBtaXNzaW5nIGltYWdlIHNpemVzLgoJICoKCSAqIFstLXllc10KCSAqIDogQW5zd2VyIHllcyB0byB0aGUgY29uZmlybWF0aW9uIG1lc3NhZ2UuIENvbmZpcm1hdGlvbiBvbmx5IHNob3dzIHdoZW4gbm8gSURzIHBhc3NlZCBhcyBhcmd1bWVudHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZWdlbmVyYXRlIHRodW1ibmFpbHMgZm9yIGdpdmVuIGF0dGFjaG1lbnQgSURzLgoJICogICAgICQgd3AgbWVkaWEgcmVnZW5lcmF0ZSAxMjMgMTI0IDEyNQoJICogICAgIEZvdW5kIDMgaW1hZ2VzIHRvIHJlZ2VuZXJhdGUuCgkgKiAgICAgMS8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJWZXJ0aWNhbCBJbWFnZSIgKElEIDEyMykuCgkgKiAgICAgMi8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJIb3Jpem9udGFsIEltYWdlIiAoSUQgMTI0KS4KCSAqICAgICAzLzMgUmVnZW5lcmF0ZWQgdGh1bWJuYWlscyBmb3IgIkJlYXV0aWZ1bCBQaWN0dXJlIiAoSUQgMTI1KS4KCSAqICAgICBTdWNjZXNzOiBSZWdlbmVyYXRlZCAzIG9mIDMgaW1hZ2VzLgoJICoKCSAqICAgICAjIFJlZ2VuZXJhdGUgYWxsIHRodW1ibmFpbHMsIHdpdGhvdXQgY29uZmlybWF0aW9uLgoJICogICAgICQgd3AgbWVkaWEgcmVnZW5lcmF0ZSAtLXllcwoJICogICAgIEZvdW5kIDMgaW1hZ2VzIHRvIHJlZ2VuZXJhdGUuCgkgKiAgICAgMS8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJTeWRuZXkgSGFyYm9yIEJyaWRnZSIgKElEIDc2MCkuCgkgKiAgICAgMi8zIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJCb2FyZHdhbGsiIChJRCA3NTcpLgoJICogICAgIDMvMyBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiU3VuYnVyc3QgT3ZlciBSaXZlciIgKElEIDc1NikuCgkgKiAgICAgU3VjY2VzczogUmVnZW5lcmF0ZWQgMyBvZiAzIGltYWdlcy4KCSAqCgkgKiAgICAgIyBSZS1nZW5lcmF0ZSBhbGwgdGh1bWJuYWlscyB0aGF0IGhhdmUgSURzIGJldHdlZW4gMTAwMCBhbmQgMjAwMC4KCSAqICAgICAkIHNlcSAxMDAwIDIwMDAgfCB4YXJncyB3cCBtZWRpYSByZWdlbmVyYXRlCgkgKiAgICAgRm91bmQgNCBpbWFnZXMgdG8gcmVnZW5lcmF0ZS4KCSAqICAgICAxLzQgUmVnZW5lcmF0ZWQgdGh1bWJuYWlscyBmb3IgIlZlcnRpY2FsIEZlYXR1cmVkIEltYWdlIiAoSUQgMTAyNykuCgkgKiAgICAgMi80IFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJIb3Jpem9udGFsIEZlYXR1cmVkIEltYWdlIiAoSUQgMTAyMikuCgkgKiAgICAgMy80IFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICJVbmljb3JuIFdhbGxwYXBlciIgKElEIDEwNDUpLgoJICogICAgIDQvNCBSZWdlbmVyYXRlZCB0aHVtYm5haWxzIGZvciAiSSBBbSBXb3J0aCBMb3ZpbmcgV2FsbHBhcGVyIiAoSUQgMTAyMykuCgkgKiAgICAgU3VjY2VzczogUmVnZW5lcmF0ZWQgNCBvZiA0IGltYWdlcy4KCSAqCgkgKiAgICAgIyBSZS1nZW5lcmF0ZSBvbmx5IHRoZSB0aHVtYm5haWxzIG9mICJsYXJnZSIgaW1hZ2Ugc2l6ZSBmb3IgYWxsIGltYWdlcy4KCSAqICAgICAkIHdwIG1lZGlhIHJlZ2VuZXJhdGUgLS1pbWFnZV9zaXplPWxhcmdlCgkgKiAgICAgRG8geW91IHJlYWxseSB3YW50IHRvIHJlZ2VuZXJhdGUgdGhlICJsYXJnZSIgaW1hZ2Ugc2l6ZSBmb3IgYWxsIGltYWdlcz8gW3kvbl0geQoJICogICAgIEZvdW5kIDMgaW1hZ2VzIHRvIHJlZ2VuZXJhdGUuCgkgKiAgICAgMS8zIFJlZ2VuZXJhdGVkICJsYXJnZSIgdGh1bWJuYWlsIGZvciAiU3lkbmV5IEhhcmJvciBCcmlkZ2UiIChJRCA3NjApLgoJICogICAgIDIvMyBObyAibGFyZ2UiIHRodW1ibmFpbCByZWdlbmVyYXRpb24gbmVlZGVkIGZvciAiQm9hcmR3YWxrIiAoSUQgNzU3KS4KCSAqICAgICAzLzMgUmVnZW5lcmF0ZWQgImxhcmdlIiB0aHVtYm5haWwgZm9yICJTdW5idXJzdCBPdmVyIFJpdmVyIiAoSUQgNzU2KS4KCSAqICAgICBTdWNjZXNzOiBSZWdlbmVyYXRlZCAzIG9mIDMgaW1hZ2VzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVnZW5lcmF0ZSggJGFyZ3MsICRhc3NvY19hcmdzID0gYXJyYXkoKSApIHsKCQkkYXNzb2NfYXJncyA9IHdwX3BhcnNlX2FyZ3MoCgkJCSRhc3NvY19hcmdzLAoJCQlbICdpbWFnZV9zaXplJyA9PiAnJyBdCgkJKTsKCgkJJGltYWdlX3NpemUgPSAkYXNzb2NfYXJnc1snaW1hZ2Vfc2l6ZSddOwoJCWlmICggJGltYWdlX3NpemUgJiYgISBpbl9hcnJheSggJGltYWdlX3NpemUsIGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMoKSwgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnVW5rbm93biBpbWFnZSBzaXplICIlcyIuJywgJGltYWdlX3NpemUgKSApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJaWYgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJCVdQX0NMSTo6Y29uZmlybSggc3ByaW50ZiggJ0RvIHlvdSByZWFsbHkgd2FudCB0byByZWdlbmVyYXRlIHRoZSAiJXMiIGltYWdlIHNpemUgZm9yIGFsbCBpbWFnZXM/JywgJGltYWdlX3NpemUgKSwgJGFzc29jX2FyZ3MgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6Y29uZmlybSggJ0RvIHlvdSByZWFsbHkgd2FudCB0byByZWdlbmVyYXRlIGFsbCBpbWFnZXM/JywgJGFzc29jX2FyZ3MgKTsKCQkJfQoJCX0KCgkJJHNraXBfZGVsZXRlICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtZGVsZXRlJyApOwoJCSRvbmx5X21pc3NpbmcgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdvbmx5LW1pc3NpbmcnICk7CgkJaWYgKCAkb25seV9taXNzaW5nICkgewoJCQkkc2tpcF9kZWxldGUgPSB0cnVlOwoJCX0KCgkJJGFkZGl0aW9uYWxfbWltZV90eXBlcyA9IGFycmF5KCk7CgoJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC43JywgJz49JyApICkgewoJCQkkYWRkaXRpb25hbF9taW1lX3R5cGVzW10gPSAnYXBwbGljYXRpb24vcGRmJzsKCQl9CgoJCSRpbWFnZXMgPSAkdGhpcy0+Z2V0X2ltYWdlcyggJGFyZ3MsICRhZGRpdGlvbmFsX21pbWVfdHlwZXMgKTsKCQkkY291bnQgID0gJGltYWdlcy0+cG9zdF9jb3VudDsKCgkJaWYgKCAhICRjb3VudCApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnTm8gaW1hZ2VzIGZvdW5kLicgKTsKCQkJcmV0dXJuOwoJCX0KCgkJV1BfQ0xJOjpsb2coCgkJCXNwcmludGYoCgkJCQknRm91bmQgJTEkZCAlMiRzIHRvIHJlZ2VuZXJhdGUuJywKCQkJCSRjb3VudCwKCQkJCV9uKCAnaW1hZ2UnLCAnaW1hZ2VzJywgJGNvdW50ICkKCQkJKQoJCSk7CgoJCWlmICggJGltYWdlX3NpemUgKSB7CgkJCSRpbWFnZV9zaXplX2ZpbHRlcnMgPSAkdGhpcy0+YWRkX2ltYWdlX3NpemVfZmlsdGVycyggJGltYWdlX3NpemUgKTsKCQl9CgoJCSRudW1iZXIgICAgPSAwOwoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRza2lwcyAgICAgPSAwOwoJCWZvcmVhY2ggKCAkaW1hZ2VzLT5wb3N0cyBhcyAkcG9zdCApIHsKCQkJJG51bWJlcisrOwoJCQlpZiAoIDAgPT09ICRudW1iZXIgJSBzZWxmOjpXUF9DTEVBUl9PQkpFQ1RfQ0FDSEVfSU5URVJWQUwgKSB7CgkJCQlVdGlsc1x3cF9jbGVhcl9vYmplY3RfY2FjaGUoKTsKCQkJfQoJCQkkdGhpcy0+cHJvY2Vzc19yZWdlbmVyYXRpb24oICRwb3N0LT5JRCwgJHNraXBfZGVsZXRlLCAkb25seV9taXNzaW5nLCAkaW1hZ2Vfc2l6ZSwgJG51bWJlciAuICcvJyAuICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJHNraXBzICk7CgkJfQoKCQlpZiAoICRpbWFnZV9zaXplICkgewoJCQkkdGhpcy0+cmVtb3ZlX2ltYWdlX3NpemVfZmlsdGVycyggJGltYWdlX3NpemVfZmlsdGVycyApOwoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnaW1hZ2UnLCAncmVnZW5lcmF0ZScsICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJHNraXBzICk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGF0dGFjaG1lbnRzIGZyb20gbG9jYWwgZmlsZXMgb3IgVVJMcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGZpbGU+Li4uCgkgKiA6IFBhdGggdG8gZmlsZSBvciBmaWxlcyB0byBiZSBpbXBvcnRlZC4gU3VwcG9ydHMgdGhlIGdsb2IoMykgY2FwYWJpbGl0aWVzIG9mIHRoZSBjdXJyZW50IHNoZWxsLgoJICogICAgIElmIGZpbGUgaXMgcmVjb2duaXplZCBhcyBhIFVSTCAoZm9yIGV4YW1wbGUsIHdpdGggYSBzY2hlbWUgb2YgaHR0cCBvciBmdHApLCB0aGUgZmlsZSB3aWxsIGJlCgkgKiAgICAgZG93bmxvYWRlZCB0byBhIHRlbXAgZmlsZSBiZWZvcmUgYmVpbmcgc2lkZWxvYWRlZC4KCSAqCgkgKiBbLS1wb3N0X2lkPTxwb3N0X2lkPl0KCSAqIDogSUQgb2YgdGhlIHBvc3QgdG8gYXR0YWNoIHRoZSBpbXBvcnRlZCBmaWxlcyB0by4KCSAqCgkgKiBbLS10aXRsZT08dGl0bGU+XQoJICogOiBBdHRhY2htZW50IHRpdGxlIChwb3N0IHRpdGxlIGZpZWxkKS4KCSAqCgkgKiBbLS1jYXB0aW9uPTxjYXB0aW9uPl0KCSAqIDogQ2FwdGlvbiBmb3IgYXR0YWNoZW50IChwb3N0IGV4Y2VycHQgZmllbGQpLgoJICoKCSAqIFstLWFsdD08YWx0X3RleHQ+XQoJICogOiBBbHQgdGV4dCBmb3IgaW1hZ2UgKHNhdmVkIGFzIHBvc3QgbWV0YSkuCgkgKgoJICogWy0tZGVzYz08ZGVzY3JpcHRpb24+XQoJICogOiAiRGVzY3JpcHRpb24iIGZpZWxkIChwb3N0IGNvbnRlbnQpIG9mIGF0dGFjaG1lbnQgcG9zdC4KCSAqCgkgKiBbLS1za2lwLWNvcHldCgkgKiA6IElmIHNldCwgbWVkaWEgZmlsZXMgKGxvY2FsIG9ubHkpIGFyZSBpbXBvcnRlZCB0byB0aGUgbGlicmFyeSBidXQgbm90IG1vdmVkIG9uIGRpc2suCgkgKiBGaWxlIG5hbWVzIHdpbGwgbm90IGJlIHJ1biB0aHJvdWdoIHdwX3VuaXF1ZV9maWxlbmFtZSgpIHdpdGggdGhpcyBzZXQuCgkgKgoJICogWy0tcHJlc2VydmUtZmlsZXRpbWVdCgkgKiA6IFVzZSB0aGUgZmlsZSBtb2RpZmllZCB0aW1lIGFzIHRoZSBwb3N0IHB1Ymxpc2hlZCAmIG1vZGlmaWVkIGRhdGVzLgoJICogUmVtb3RlIGZpbGVzIHdpbGwgYWx3YXlzIHVzZSB0aGUgY3VycmVudCB0aW1lLgoJICoKCSAqIFstLWZlYXR1cmVkX2ltYWdlXQoJICogOiBJZiBzZXQsIHNldCB0aGUgaW1wb3J0ZWQgaW1hZ2UgYXMgdGhlIEZlYXR1cmVkIEltYWdlIG9mIHRoZSBwb3N0IGl0cyBhdHRhY2hlZCB0by4KCSAqCgkgKiBbLS1wb3JjZWxhaW5dCgkgKiA6IE91dHB1dCBqdXN0IHRoZSBuZXcgYXR0YWNobWVudCBJRC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEltcG9ydCBhbGwganBncyBpbiB0aGUgY3VycmVudCB1c2VyJ3MgIlBpY3R1cmVzIiBkaXJlY3RvcnksIG5vdCBhdHRhY2hlZCB0byBhbnkgcG9zdC4KCSAqICAgICAkIHdwIG1lZGlhIGltcG9ydCB+L1BpY3R1cmVzLyoqXC8qLmpwZwoJICogICAgIEltcG9ydGVkIGZpbGUgJy9ob21lL3BlcnNvbi9QaWN0dXJlcy9sYW5kc2NhcGUtcGhvdG8uanBnJyBhcyBhdHRhY2htZW50IElEIDE3NTEuCgkgKiAgICAgSW1wb3J0ZWQgZmlsZSAnL2hvbWUvcGVyc29uL1BpY3R1cmVzL2Zhc2hpb24taWNvbi5qcGcnIGFzIGF0dGFjaG1lbnQgSUQgMTc1Mi4KCSAqICAgICBTdWNjZXNzOiBJbXBvcnRlZCAyIG9mIDIgaXRlbXMuCgkgKgoJICogICAgICMgSW1wb3J0IGEgbG9jYWwgaW1hZ2UgYW5kIHNldCBpdCB0byBiZSB0aGUgcG9zdCB0aHVtYm5haWwgZm9yIGEgcG9zdC4KCSAqICAgICAkIHdwIG1lZGlhIGltcG9ydCB+L0Rvd25sb2Fkcy9pbWFnZS5wbmcgLS1wb3N0X2lkPTEyMyAtLXRpdGxlPSJBIGRvd25sb2FkZWQgcGljdHVyZSIgLS1mZWF0dXJlZF9pbWFnZQoJICogICAgIEltcG9ydGVkIGZpbGUgJy9ob21lL3BlcnNvbi9Eb3dubG9hZHMvaW1hZ2UucG5nJyBhcyBhdHRhY2htZW50IElEIDE3NTMgYW5kIGF0dGFjaGVkIHRvIHBvc3QgMTIzIGFzIGZlYXR1cmVkIGltYWdlLgoJICogICAgIFN1Y2Nlc3M6IEltcG9ydGVkIDEgb2YgMSBpbWFnZXMuCgkgKgoJICogICAgICMgSW1wb3J0IGEgbG9jYWwgaW1hZ2UsIGJ1dCBzZXQgaXQgYXMgdGhlIGZlYXR1cmVkIGltYWdlIGZvciBhbGwgcG9zdHMuCgkgKiAgICAgIyAxLiBJbXBvcnQgdGhlIGltYWdlIGFuZCBnZXQgaXRzIGF0dGFjaG1lbnQgSUQuCgkgKiAgICAgIyAyLiBBc3NpZ24gdGhlIGF0dGFjaG1lbnQgSUQgYXMgdGhlIGZlYXR1cmVkIGltYWdlIGZvciBhbGwgcG9zdHMuCgkgKiAgICAgJCBBVFRBQ0hNRU5UX0lEPSIkKHdwIG1lZGlhIGltcG9ydCB+L0Rvd25sb2Fkcy9pbWFnZS5wbmcgLS1wb3JjZWxhaW4pIgoJICogICAgICQgd3AgcG9zdCBsaXN0IC0tcG9zdF90eXBlPXBvc3QgLS1mb3JtYXQ9aWRzIHwgeGFyZ3MgLWQgJyAnIC1JICUgd3AgcG9zdCBtZXRhIGFkZCAlIF90aHVtYm5haWxfaWQgJEFUVEFDSE1FTlRfSUQKCSAqICAgICBTdWNjZXNzOiBBZGRlZCBjdXN0b20gZmllbGQuCgkgKiAgICAgU3VjY2VzczogQWRkZWQgY3VzdG9tIGZpZWxkLgoJICoKCSAqICAgICAjIEltcG9ydCBhbiBpbWFnZSBmcm9tIHRoZSB3ZWIuCgkgKiAgICAgJCB3cCBtZWRpYSBpbXBvcnQgaHR0cDovL3Mud29yZHByZXNzLm9yZy9zdHlsZS9pbWFnZXMvd3AtaGVhZGVyLWxvZ28ucG5nIC0tdGl0bGU9J1RoZSBXb3JkUHJlc3MgbG9nbycgLS1hbHQ9IlNlbWFudGljIHBlcnNvbmFsIHB1Ymxpc2hpbmciCgkgKiAgICAgSW1wb3J0ZWQgZmlsZSAnaHR0cDovL3Mud29yZHByZXNzLm9yZy9zdHlsZS9pbWFnZXMvd3AtaGVhZGVyLWxvZ28ucG5nJyBhcyBhdHRhY2htZW50IElEIDE3NTUuCgkgKiAgICAgU3VjY2VzczogSW1wb3J0ZWQgMSBvZiAxIGltYWdlcy4KCSAqCgkgKiAgICAgIyBHZXQgdGhlIFVSTCBmb3IgYW4gYXR0YWNobWVudCBhZnRlciBpbXBvcnQuCgkgKiAgICAgJCB3cCBtZWRpYSBpbXBvcnQgaHR0cDovL3Mud29yZHByZXNzLm9yZy9zdHlsZS9pbWFnZXMvd3AtaGVhZGVyLWxvZ28ucG5nIC0tcG9yY2VsYWluIHwgeGFyZ3MgLUkge30gd3AgcG9zdCBsaXN0IC0tcG9zdF9faW49e30gLS1maWVsZD11cmwgLS1wb3N0X3R5cGU9YXR0YWNobWVudAoJICogICAgIGh0dHA6Ly93b3JkcHJlc3MtZGV2ZWxvcC5kZXYvd3AtaGVhZGVyLWxvZ28vCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbXBvcnQoICRhcmdzLCAkYXNzb2NfYXJncyA9IGFycmF5KCkgKSB7CgkJJGFzc29jX2FyZ3MgPSB3cF9wYXJzZV9hcmdzKAoJCQkkYXNzb2NfYXJncywKCQkJYXJyYXkoCgkJCQkndGl0bGUnICAgPT4gJycsCgkJCQknY2FwdGlvbicgPT4gJycsCgkJCQknYWx0JyAgICAgPT4gJycsCgkJCQknZGVzYycgICAgPT4gJycsCgkJCSkKCQkpOwoKCQkvLyBBc3N1bWUgdGhlIG1vc3QgZ2VuZXJpYyB0ZXJtCgkJJG5vdW4gPSAnaXRlbSc7CgoJCS8vIEN1cnJlbnQgc2l0ZSdzIHRpbWV6b25lIG9mZnNldC4KCQkkZ210X29mZnNldCA9IGdldF9vcHRpb24oICdnbXRfb2Zmc2V0JyApOwoKCQkvLyBVc2UgdGhlIG5vdW4gYGltYWdlYCB3aGVuIHN1cmUgdGhlIG1lZGlhIGZpbGUgaXMgYW4gaW1hZ2UKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZlYXR1cmVkX2ltYWdlJyApIHx8ICRhc3NvY19hcmdzWydhbHQnXSApIHsKCQkJJG5vdW4gPSAnaW1hZ2UnOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSApICkgewoJCQlpZiAoICEgZ2V0X3Bvc3QoICRhc3NvY19hcmdzWydwb3N0X2lkJ10gKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ0ludmFsaWQgLS1wb3N0X2lkJyApOwoJCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSA9IGZhbHNlOwoJCQl9CgkJfSBlbHNlIHsKCQkJJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSA9IGZhbHNlOwoJCX0KCgkJJG51bWJlciAgICA9IDA7CgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRmaWxlICkgewoJCQkkbnVtYmVyKys7CgkJCWlmICggMCA9PT0gJG51bWJlciAlIHNlbGY6OldQX0NMRUFSX09CSkVDVF9DQUNIRV9JTlRFUlZBTCApIHsKCQkJCVV0aWxzXHdwX2NsZWFyX29iamVjdF9jYWNoZSgpOwoJCQl9CgoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkFsdGVybmF0aXZlRnVuY3Rpb25zLnBhcnNlX3VybF9wYXJzZV91cmwgLS0gcGFyc2VfdXJsIHdpbGwgb25seSBiZSB1c2VkIGluIGFic2VuY2Ugb2Ygd3BfcGFyc2VfdXJsLgoJCQkkaXNfZmlsZV9yZW1vdGUgPSBmdW5jdGlvbl9leGlzdHMoICd3cF9wYXJzZV91cmwnICkgPyB3cF9wYXJzZV91cmwoICRmaWxlLCBQSFBfVVJMX0hPU1QgKSA6IHBhcnNlX3VybCggJGZpbGUsIFBIUF9VUkxfSE9TVCApOwoJCQkkb3JpZ19maWxlbmFtZSAgPSAkZmlsZTsKCQkJJGZpbGVfdGltZSAgICAgID0gJyc7CgoJCQlpZiAoIGVtcHR5KCAkaXNfZmlsZV9yZW1vdGUgKSApIHsKCQkJCWlmICggISBmaWxlX2V4aXN0cyggJGZpbGUgKSApIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICJVbmFibGUgdG8gaW1wb3J0IGZpbGUgJyRmaWxlJy4gUmVhc29uOiBGaWxlIGRvZXNuJ3QgZXhpc3QuIiApOwoJCQkJCSRlcnJvcnMrKzsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jb3B5JyApICkgewoJCQkJCSR0ZW1wZmlsZSA9ICRmaWxlOwoJCQkJfSBlbHNlIHsKCQkJCQkkdGVtcGZpbGUgPSAkdGhpcy0+bWFrZV9jb3B5KCAkZmlsZSApOwoJCQkJfQoJCQkJJG5hbWUgPSBVdGlsc1xiYXNlbmFtZSggJGZpbGUgKTsKCgkJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ByZXNlcnZlLWZpbGV0aW1lJyApICkgewoJCQkJCSRmaWxlX3RpbWUgPSBAZmlsZW10aW1lKCAkZmlsZSApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJHRlbXBmaWxlID0gZG93bmxvYWRfdXJsKCAkZmlsZSApOwoJCQkJaWYgKCBpc193cF9lcnJvciggJHRlbXBmaWxlICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCQlzcHJpbnRmKAoJCQkJCQkJIlVuYWJsZSB0byBpbXBvcnQgZmlsZSAnJXMnLiBSZWFzb246ICVzIiwKCQkJCQkJCSRmaWxlLAoJCQkJCQkJaW1wbG9kZSggJywgJywgJHRlbXBmaWxlLT5nZXRfZXJyb3JfbWVzc2FnZXMoKSApCgkJCQkJCSkKCQkJCQkpOwoJCQkJCSRlcnJvcnMrKzsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCSRuYW1lID0gc3RydG9rKCBVdGlsc1xiYXNlbmFtZSggJGZpbGUgKSwgJz8nICk7CgkJCX0KCgkJCSRmaWxlX2FycmF5ID0gYXJyYXkoCgkJCQkndG1wX25hbWUnID0+ICR0ZW1wZmlsZSwKCQkJCSduYW1lJyAgICAgPT4gJG5hbWUsCgkJCSk7CgoJCQkkcG9zdF9hcnJheSA9IGFycmF5KAoJCQkJJ3Bvc3RfdGl0bGUnICAgPT4gJGFzc29jX2FyZ3NbJ3RpdGxlJ10sCgkJCQkncG9zdF9leGNlcnB0JyA9PiAkYXNzb2NfYXJnc1snY2FwdGlvbiddLAoJCQkJJ3Bvc3RfY29udGVudCcgPT4gJGFzc29jX2FyZ3NbJ2Rlc2MnXSwKCQkJKTsKCgkJCWlmICggISBlbXB0eSggJGZpbGVfdGltZSApICkgewoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfZGF0ZSddICAgICAgICAgPSBnbWRhdGUoICdZLW0tZCBIOmk6cycsICRmaWxlX3RpbWUgKyAoICRnbXRfb2Zmc2V0ICogSE9VUl9JTl9TRUNPTkRTICkgKTsKCQkJCSRwb3N0X2FycmF5Wydwb3N0X2RhdGVfZ210J10gICAgID0gZ21kYXRlKCAnWS1tLWQgSDppOnMnLCAkZmlsZV90aW1lICk7CgkJCQkkcG9zdF9hcnJheVsncG9zdF9tb2RpZmllZCddICAgICA9IGdtZGF0ZSggJ1ktbS1kIEg6aTpzJywgJGZpbGVfdGltZSArICggJGdtdF9vZmZzZXQgKiBIT1VSX0lOX1NFQ09ORFMgKSApOwoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3RfbW9kaWZpZWRfZ210J10gPSBnbWRhdGUoICdZLW0tZCBIOmk6cycsICRmaWxlX3RpbWUgKTsKCQkJfQoKCQkJJHBvc3RfYXJyYXkgPSB3cF9zbGFzaCggJHBvc3RfYXJyYXkgKTsKCgkJCS8vIHVzZSBpbWFnZSBleGlmL2lwdGMgZGF0YSBmb3IgdGl0bGUgYW5kIGNhcHRpb24gZGVmYXVsdHMgaWYgcG9zc2libGUKCQkJaWYgKCBlbXB0eSggJHBvc3RfYXJyYXlbJ3Bvc3RfdGl0bGUnXSApIHx8IGVtcHR5KCAkcG9zdF9hcnJheVsncG9zdF9leGNlcnB0J10gKSApIHsKCQkJCS8vIEBjb2RpbmdTdGFuZGFyZHNJZ25vcmVTdGFydAoJCQkJJGltYWdlX21ldGEgPSBAd3BfcmVhZF9pbWFnZV9tZXRhZGF0YSggJHRlbXBmaWxlICk7CgkJCQkvLyBAY29kaW5nU3RhbmRhcmRzSWdub3JlRW5kCgkJCQlpZiAoICEgZW1wdHkoICRpbWFnZV9tZXRhICkgKSB7CgkJCQkJaWYgKCBlbXB0eSggJHBvc3RfYXJyYXlbJ3Bvc3RfdGl0bGUnXSApICYmIHRyaW0oICRpbWFnZV9tZXRhWyd0aXRsZSddICkgJiYgISBpc19udW1lcmljKCBzYW5pdGl6ZV90aXRsZSggJGltYWdlX21ldGFbJ3RpdGxlJ10gKSApICkgewoJCQkJCQkkcG9zdF9hcnJheVsncG9zdF90aXRsZSddID0gJGltYWdlX21ldGFbJ3RpdGxlJ107CgkJCQkJfQoKCQkJCQlpZiAoIGVtcHR5KCAkcG9zdF9hcnJheVsncG9zdF9leGNlcnB0J10gKSAmJiB0cmltKCAkaW1hZ2VfbWV0YVsnY2FwdGlvbiddICkgKSB7CgkJCQkJCSRwb3N0X2FycmF5Wydwb3N0X2V4Y2VycHQnXSA9ICRpbWFnZV9tZXRhWydjYXB0aW9uJ107CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoIGVtcHR5KCAkcG9zdF9hcnJheVsncG9zdF90aXRsZSddICkgKSB7CgkJCQkkcG9zdF9hcnJheVsncG9zdF90aXRsZSddID0gcHJlZ19yZXBsYWNlKCAnL1wuW14uXSskLycsICcnLCBVdGlsc1xiYXNlbmFtZSggJGZpbGUgKSApOwoJCQl9CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtY29weScgKSApIHsKCQkJCSR3cF9maWxldHlwZSAgICAgICAgICAgICAgICAgID0gd3BfY2hlY2tfZmlsZXR5cGUoICRmaWxlLCBudWxsICk7CgkJCQkkcG9zdF9hcnJheVsncG9zdF9taW1lX3R5cGUnXSA9ICR3cF9maWxldHlwZVsndHlwZSddOwoJCQkJJHBvc3RfYXJyYXlbJ3Bvc3Rfc3RhdHVzJ10gICAgPSAnaW5oZXJpdCc7CgoJCQkJJHN1Y2Nlc3MgPSB3cF9pbnNlcnRfYXR0YWNobWVudCggJHBvc3RfYXJyYXksICRmaWxlLCAkYXNzb2NfYXJnc1sncG9zdF9pZCddICk7CgkJCQlpZiAoIGlzX3dwX2Vycm9yKCAkc3VjY2VzcyApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQkJc3ByaW50ZigKCQkJCQkJCSJVbmFibGUgdG8gaW5zZXJ0IGZpbGUgJyVzJy4gUmVhc29uOiAlcyIsCgkJCQkJCQkkb3JpZ19maWxlbmFtZSwKCQkJCQkJCWltcGxvZGUoICcsICcsICRzdWNjZXNzLT5nZXRfZXJyb3JfbWVzc2FnZXMoKSApCgkJCQkJCSkKCQkJCQkpOwoJCQkJCSRlcnJvcnMrKzsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCXdwX3VwZGF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCAkc3VjY2Vzcywgd3BfZ2VuZXJhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJHN1Y2Nlc3MsICRmaWxlICkgKTsKCQkJfSBlbHNlIHsKCQkJCS8vIERlbGV0ZXMgdGhlIHRlbXBvcmFyeSBmaWxlLgoJCQkJJHN1Y2Nlc3MgPSBtZWRpYV9oYW5kbGVfc2lkZWxvYWQoICRmaWxlX2FycmF5LCAkYXNzb2NfYXJnc1sncG9zdF9pZCddLCAkYXNzb2NfYXJnc1sndGl0bGUnXSwgJHBvc3RfYXJyYXkgKTsKCQkJCWlmICggaXNfd3BfZXJyb3IoICRzdWNjZXNzICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCQlzcHJpbnRmKAoJCQkJCQkJIlVuYWJsZSB0byBpbXBvcnQgZmlsZSAnJXMnLiBSZWFzb246ICVzIiwKCQkJCQkJCSRvcmlnX2ZpbGVuYW1lLAoJCQkJCQkJaW1wbG9kZSggJywgJywgJHN1Y2Nlc3MtPmdldF9lcnJvcl9tZXNzYWdlcygpICkKCQkJCQkJKQoJCQkJCSk7CgkJCQkJJGVycm9ycysrOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQl9CgoJCQkvLyBTZXQgYWx0IHRleHQKCQkJaWYgKCAkYXNzb2NfYXJnc1snYWx0J10gKSB7CgkJCQl1cGRhdGVfcG9zdF9tZXRhKCAkc3VjY2VzcywgJ193cF9hdHRhY2htZW50X2ltYWdlX2FsdCcsIHdwX3NsYXNoKCAkYXNzb2NfYXJnc1snYWx0J10gKSApOwoJCQl9CgoJCQkvLyBTZXQgYXMgZmVhdHVyZWQgaW1hZ2UsIGlmIC0tcG9zdF9pZCBhbmQgLS1mZWF0dXJlZF9pbWFnZSBhcmUgc2V0CgkJCWlmICggJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSAmJiBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmZWF0dXJlZF9pbWFnZScgKSApIHsKCQkJCXVwZGF0ZV9wb3N0X21ldGEoICRhc3NvY19hcmdzWydwb3N0X2lkJ10sICdfdGh1bWJuYWlsX2lkJywgJHN1Y2Nlc3MgKTsKCQkJfQoKCQkJJGF0dGFjaG1lbnRfc3VjY2Vzc190ZXh0ID0gJyc7CgkJCWlmICggJGFzc29jX2FyZ3NbJ3Bvc3RfaWQnXSApIHsKCQkJCSRhdHRhY2htZW50X3N1Y2Nlc3NfdGV4dCA9ICIgYW5kIGF0dGFjaGVkIHRvIHBvc3QgeyRhc3NvY19hcmdzWydwb3N0X2lkJ119IjsKCQkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZmVhdHVyZWRfaW1hZ2UnICkgKSB7CgkJCQkJJGF0dGFjaG1lbnRfc3VjY2Vzc190ZXh0IC49ICcgYXMgZmVhdHVyZWQgaW1hZ2UnOwoJCQkJfQoJCQl9CgoJCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKSApIHsKCQkJCVdQX0NMSTo6bGluZSggJHN1Y2Nlc3MgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKAoJCQkJCXNwcmludGYoCgkJCQkJCSJJbXBvcnRlZCBmaWxlICclcycgYXMgYXR0YWNobWVudCBJRCAlZCVzLiIsCgkJCQkJCSRvcmlnX2ZpbGVuYW1lLAoJCQkJCQkkc3VjY2VzcywKCQkJCQkJJGF0dGFjaG1lbnRfc3VjY2Vzc190ZXh0CgkJCQkJKQoJCQkJKTsKCQkJfQoJCQkkc3VjY2Vzc2VzKys7CgkJfQoKCQkvLyBSZXBvcnQgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uCgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BvcmNlbGFpbicgKSApIHsKCQkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAkbm91biwgJ2ltcG9ydCcsIGNvdW50KCAkYXJncyApLCAkc3VjY2Vzc2VzLCAkZXJyb3JzICk7CgkJfSBlbHNlaWYgKCAkZXJyb3JzICkgewoJCQlXUF9DTEk6OmhhbHQoIDEgKTsKCQl9Cgl9CgoJLyoqCgkgKiBMaXN0cyBpbWFnZSBzaXplcyByZWdpc3RlcmVkIHdpdGggV29yZFByZXNzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgZmllbGRzLiBEZWZhdWx0cyB0byBhbGwgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHNwZWNpZmljIGZvcm1hdAoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGpzb24KCSAqICAgLSBjc3YKCSAqICAgLSB5YW1sCgkgKiAgIC0gY291bnQKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBpbWFnZSBzaXplOgoJICogKiBuYW1lCgkgKiAqIHdpZHRoCgkgKiAqIGhlaWdodAoJICogKiBjcm9wCgkgKiAqIHJhdGlvCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGFsbCByZWdpc3RlcmVkIGltYWdlIHNpemVzCgkgKiAgICAgJCB3cCBtZWRpYSBpbWFnZS1zaXplCgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tKy0tLS0tLS0rLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICAgICAgfCB3aWR0aCB8IGhlaWdodCB8IGNyb3AgIHwgcmF0aW8gfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0rCgkgKiAgICAgfCBmdWxsICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfCAgICAgICAgfCBOL0EgICB8IE4vQSAgIHwKCSAqICAgICB8IHR3ZW50eWZvdXJ0ZWVuLWZ1bGwtd2lkdGggfCAxMDM4ICB8IDU3NiAgICB8IGhhcmQgIHwgMTczOjk2fAoJICogICAgIHwgbGFyZ2UgICAgICAgICAgICAgICAgICAgICB8IDEwMjQgIHwgMTAyNCAgIHwgc29mdCAgfCBOL0EgICB8CgkgKiAgICAgfCBtZWRpdW1fbGFyZ2UgICAgICAgICAgICAgIHwgNzY4ICAgfCAwICAgICAgfCBzb2Z0ICB8IE4vQSAgIHwKCSAqICAgICB8IG1lZGl1bSAgICAgICAgICAgICAgICAgICAgfCAzMDAgICB8IDMwMCAgICB8IHNvZnQgIHwgTi9BICAgfAoJICogICAgIHwgdGh1bWJuYWlsICAgICAgICAgICAgICAgICB8IDE1MCAgIHwgMTUwICAgIHwgaGFyZCAgfCAxOjEgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tKy0tLS0tLS0rLS0tLS0tLSsKCSAqCgkgKiBAc3ViY29tbWFuZCBpbWFnZS1zaXplCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbWFnZV9zaXplKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFzc29jX2FyZ3MgPSBhcnJheV9tZXJnZSgKCQkJYXJyYXkoCgkJCQknZmllbGRzJyA9PiAnbmFtZSx3aWR0aCxoZWlnaHQsY3JvcCxyYXRpbycsCgkJCSksCgkJCSRhc3NvY19hcmdzCgkJKTsKCgkJJHNpemVzID0gJHRoaXMtPmdldF9yZWdpc3RlcmVkX2ltYWdlX3NpemVzKCk7CgoJCXVzb3J0KAoJCQkkc2l6ZXMsCgkJCWZ1bmN0aW9uKCAkYSwgJGIgKSB7CgkJCQlpZiAoICRhWyd3aWR0aCddID09PSAkYlsnd2lkdGgnXSApIHsKCQkJCQlyZXR1cm4gMDsKCQkJCX0KCQkJCXJldHVybiAoICRhWyd3aWR0aCddIDwgJGJbJ3dpZHRoJ10gKSA/IDEgOiAtMTsKCQkJfQoJCSk7CgkJYXJyYXlfdW5zaGlmdCgKCQkJJHNpemVzLAoJCQlhcnJheSgKCQkJCSduYW1lJyAgID0+ICdmdWxsJywKCQkJCSd3aWR0aCcgID0+ICcnLAoJCQkJJ2hlaWdodCcgPT4gJycsCgkJCQknY3JvcCcgICA9PiAnTi9BJywKCQkJCSdyYXRpbycgID0+ICdOL0EnLAoJCQkpCgkJKTsKCQlXUF9DTElcVXRpbHNcZm9ybWF0X2l0ZW1zKCAkYXNzb2NfYXJnc1snZm9ybWF0J10sICRzaXplcywgZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3JhdGlvKCAkd2lkdGgsICRoZWlnaHQgKSB7CgkJaWYgKCAwID09PSAkaGVpZ2h0ICkgewoJCQlyZXR1cm4gIjA6eyR3aWR0aH0iOwoJCX0KCgkJaWYgKCAwID09PSAkd2lkdGggKSB7CgkJCXJldHVybiAieyRoZWlnaHR9OjAiOwoJCX0KCgkJJGdjZCAgICAgICAgICA9ICR0aGlzLT5nY2QoICR3aWR0aCwgJGhlaWdodCApOwoJCSR3aWR0aF9yYXRpbyAgPSAkd2lkdGggLyAkZ2NkOwoJCSRoZWlnaHRfcmF0aW8gPSAkaGVpZ2h0IC8gJGdjZDsKCgkJcmV0dXJuICJ7JHdpZHRoX3JhdGlvfTp7JGhlaWdodF9yYXRpb30iOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2NkKCAkbnVtMSwgJG51bTIgKSB7CgkJd2hpbGUgKCAwICE9PSAkbnVtMiApIHsKCQkJJHQgICAgPSAkbnVtMSAlICRudW0yOwoJCQkkbnVtMSA9ICRudW0yOwoJCQkkbnVtMiA9ICR0OwoJCX0KCQlyZXR1cm4gJG51bTE7Cgl9CgoJLy8gd3BfdGVtcG5hbSgpIGluZXhwbGljYWJseSBmb3JjZXMgYSAudG1wIGV4dGVuc2lvbiwgd2hpY2ggc3BvaWxzIE1JTUUgdHlwZSBkZXRlY3Rpb24KCXByaXZhdGUgZnVuY3Rpb24gbWFrZV9jb3B5KCAkcGF0aCApIHsKCQkkZGlyICAgICAgPSBnZXRfdGVtcF9kaXIoKTsKCQkkZmlsZW5hbWUgPSBVdGlsc1xiYXNlbmFtZSggJHBhdGggKTsKCQlpZiAoIGVtcHR5KCAkZmlsZW5hbWUgKSApIHsKCQkJJGZpbGVuYW1lID0gdGltZSgpOwoJCX0KCgkJJGZpbGVuYW1lID0gJGRpciAuIHdwX3VuaXF1ZV9maWxlbmFtZSggJGRpciwgJGZpbGVuYW1lICk7CgkJaWYgKCAhIGNvcHkoICRwYXRoLCAkZmlsZW5hbWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUgZm9yICRwYXRoLiIgKTsKCQl9CgoJCXJldHVybiAkZmlsZW5hbWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBwcm9jZXNzX3JlZ2VuZXJhdGlvbiggJGlkLCAkc2tpcF9kZWxldGUsICRvbmx5X21pc3NpbmcsICRpbWFnZV9zaXplLCAkcHJvZ3Jlc3MsICYkc3VjY2Vzc2VzLCAmJGVycm9ycywgJiRza2lwcyApIHsKCgkJJHRpdGxlID0gZ2V0X3RoZV90aXRsZSggJGlkICk7CgkJaWYgKCAnJyA9PT0gJHRpdGxlICkgewoJCQkvLyBJZiBhdWRpbyBvciB2aWRlbyBjb3ZlciBhcnQgdGhlbiB0aGUgaWQgaXMgdGhlIHN1YiBhdHRhY2htZW50IGlkLCB3aGljaCBoYXMgbm8gdGl0bGUuCgkJCWlmICggbWV0YWRhdGFfZXhpc3RzKCAncG9zdCcsICRpZCwgJ19jb3Zlcl9oYXNoJyApICkgewoJCQkJLy8gVW5mb3J0dW5hdGVseSB0aGUgb25seSB3YXkgdG8gZ2V0IHRoZSBhdHRhY2htZW50IHRpdGxlIHdvdWxkIGJlIHRvIGRvIGEgbm9uLWluZGV4ZWQgcXVlcnkgYWdhaW5zdCB0aGUgbWV0YSB2YWx1ZSBvZiBgX3RodW1ibmFpbF9pZGAuIFNvIGRvbid0LgoJCQkJJGF0dF9kZXNjID0gc3ByaW50ZiggJ2NvdmVyIGF0dGFjaG1lbnQgKElEICVkKScsICRpZCApOwoJCQl9IGVsc2UgewoJCQkJJGF0dF9kZXNjID0gc3ByaW50ZiggJyIobm8gdGl0bGUpIiAoSUQgJWQpJywgJGlkICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkYXR0X2Rlc2MgPSBzcHJpbnRmKCAnIiUxJHMiIChJRCAlMiRkKScsICR0aXRsZSwgJGlkICk7CgkJfQoJCSR0aHVtYm5haWxfZGVzYyA9ICRpbWFnZV9zaXplID8gc3ByaW50ZiggJyIlcyIgdGh1bWJuYWlsJywgJGltYWdlX3NpemUgKSA6ICd0aHVtYm5haWwnOwoKCQkkZnVsbHNpemVwYXRoID0gJHRoaXMtPmdldF9hdHRhY2hlZF9maWxlKCAkaWQgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJGZ1bGxzaXplcGF0aCB8fCAhIGZpbGVfZXhpc3RzKCAkZnVsbHNpemVwYXRoICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggIkNhbid0IGZpbmQgJGF0dF9kZXNjLiIgKTsKCQkJJGVycm9ycysrOwoJCQlyZXR1cm47CgkJfQoKCQkkaXNfcGRmID0gJ2FwcGxpY2F0aW9uL3BkZicgPT09IGdldF9wb3N0X21pbWVfdHlwZSggJGlkICk7CgoJCSRuZWVkc19yZWdlbmVyYXRpb24gPSAkdGhpcy0+bmVlZHNfcmVnZW5lcmF0aW9uKCAkaWQsICRmdWxsc2l6ZXBhdGgsICRpc19wZGYsICRpbWFnZV9zaXplLCAkc2tpcF9kZWxldGUsICRza2lwX2l0ICk7CgoJCWlmICggJHNraXBfaXQgKSB7CgkJCVdQX0NMSTo6bG9nKCAiJHByb2dyZXNzIFNraXBwZWQgJHRodW1ibmFpbF9kZXNjIHJlZ2VuZXJhdGlvbiBmb3IgJGF0dF9kZXNjLiIgKTsKCQkJJHNraXBzKys7CgkJCXJldHVybjsKCQl9CgoJCWlmICggJG9ubHlfbWlzc2luZyAmJiAhICRuZWVkc19yZWdlbmVyYXRpb24gKSB7CgkJCVdQX0NMSTo6bG9nKCAiJHByb2dyZXNzIE5vICR0aHVtYm5haWxfZGVzYyByZWdlbmVyYXRpb24gbmVlZGVkIGZvciAkYXR0X2Rlc2MuIiApOwoJCQkkc3VjY2Vzc2VzKys7CgkJCXJldHVybjsKCQl9CgoJCSRtZXRhZGF0YSA9IHdwX2dlbmVyYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCwgJGZ1bGxzaXplcGF0aCApOwoJCWlmICggaXNfd3BfZXJyb3IoICRtZXRhZGF0YSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICclcyAoSUQgJWQpJywgJG1ldGFkYXRhLT5nZXRfZXJyb3JfbWVzc2FnZSgpLCAkaWQgKSApOwoJCQlXUF9DTEk6OmxvZyggIiRwcm9ncmVzcyBDb3VsZG4ndCByZWdlbmVyYXRlIHRodW1ibmFpbHMgZm9yICRhdHRfZGVzYy4iICk7CgkJCSRlcnJvcnMrKzsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gTm90ZSBpdCdzIHBvc3NpYmxlIGZvciBubyBtZXRhZGF0YSB0byBiZSBnZW5lcmF0ZWQgZm9yIFBERnMgaWYgcmVzdHJpY3RlZCB0byBhIHNwZWNpZmljIGltYWdlIHNpemUuCgkJaWYgKCBlbXB0eSggJG1ldGFkYXRhICkgJiYgISAoICRpc19wZGYgJiYgJGltYWdlX3NpemUgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnTm8gbWV0YWRhdGEuIChJRCAlZCknLCAkaWQgKSApOwoJCQlXUF9DTEk6OmxvZyggIiRwcm9ncmVzcyBDb3VsZG4ndCByZWdlbmVyYXRlIHRodW1ibmFpbHMgZm9yICRhdHRfZGVzYy4iICk7CgkJCSRlcnJvcnMrKzsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJaWYgKCAkdGhpcy0+dXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGFfZm9yX2ltYWdlX3NpemUoICRpZCwgJG1ldGFkYXRhLCAkaW1hZ2Vfc2l6ZSApICkgewoJCQkJV1BfQ0xJOjpsb2coICIkcHJvZ3Jlc3MgUmVnZW5lcmF0ZWQgJHRodW1ibmFpbF9kZXNjIGZvciAkYXR0X2Rlc2MuIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICIkcHJvZ3Jlc3MgTm8gJHRodW1ibmFpbF9kZXNjIHJlZ2VuZXJhdGlvbiBuZWVkZWQgZm9yICRhdHRfZGVzYy4iICk7CgkJCX0KCQl9IGVsc2UgewoJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkbWV0YWRhdGEgKTsKCgkJCVdQX0NMSTo6bG9nKCAiJHByb2dyZXNzIFJlZ2VuZXJhdGVkIHRodW1ibmFpbHMgZm9yICRhdHRfZGVzYy4iICk7CgkJfQoJCSRzdWNjZXNzZXMrKzsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHJlbW92ZV9vbGRfaW1hZ2VzKCAkbWV0YWRhdGEsICRmdWxsc2l6ZXBhdGgsICRpbWFnZV9zaXplICkgewoKCQlpZiAoIGVtcHR5KCAkbWV0YWRhdGFbJ3NpemVzJ10gKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJaWYgKCBlbXB0eSggJG1ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdICkgKSB7CgkJCQlyZXR1cm47CgkJCX0KCQkJJG1ldGFkYXRhWydzaXplcyddID0gYXJyYXkoICRpbWFnZV9zaXplID0+ICRtZXRhZGF0YVsnc2l6ZXMnXVsgJGltYWdlX3NpemUgXSApOwoJCX0KCgkJJGRpcl9wYXRoID0gZGlybmFtZSggJGZ1bGxzaXplcGF0aCApIC4gJy8nOwoKCQlmb3JlYWNoICggJG1ldGFkYXRhWydzaXplcyddIGFzICRzaXplX2luZm8gKSB7CgkJCSRpbnRlcm1lZGlhdGVfcGF0aCA9ICRkaXJfcGF0aCAuICRzaXplX2luZm9bJ2ZpbGUnXTsKCgkJCWlmICggJGludGVybWVkaWF0ZV9wYXRoID09PSAkZnVsbHNpemVwYXRoICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggZmlsZV9leGlzdHMoICRpbnRlcm1lZGlhdGVfcGF0aCApICkgewoJCQkJdW5saW5rKCAkaW50ZXJtZWRpYXRlX3BhdGggKTsKCQkJfQoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIG5lZWRzX3JlZ2VuZXJhdGlvbiggJGF0dF9pZCwgJGZ1bGxzaXplcGF0aCwgJGlzX3BkZiwgJGltYWdlX3NpemUsICRza2lwX2RlbGV0ZSwgJiRza2lwX2l0ICkgewoKCQkvLyBBc3N1bWUgbm90IHNraXBwaW5nLgoJCSRza2lwX2l0ID0gZmFsc2U7CgoJCS8vIE5vdGU6IHplcm8tbGVuZ3RoIHN0cmluZyByZXR1cm5lZCBpZiBubyBtZXRhZGF0YSwgZm9yIGluc3RhbmNlIGlmIFBERiBvciBub24tc3RhbmRhcmQgaW1hZ2UgKGVnIGFuIFNWRykuCgkJJG1ldGFkYXRhID0gd3BfZ2V0X2F0dGFjaG1lbnRfbWV0YWRhdGEoICRhdHRfaWQgKTsKCgkJJGltYWdlX3NpemVzID0gJHRoaXMtPmdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXNfZm9yX2F0dGFjaG1lbnQoICRmdWxsc2l6ZXBhdGgsICRpc19wZGYsICRtZXRhZGF0YSApOwoKCQkvLyBGaXJzdCBjaGVjayBpZiBubyBhcHBsaWNhYmxlIGVkaXRvciBjdXJyZW50bHkgYXZhaWxhYmxlIChub24tZGVzdHJ1Y3RpdmUgLSBpZSBvbGQgdGh1bWJuYWlscyBub3QgcmVtb3ZlZCkuCgkJaWYgKCBpc193cF9lcnJvciggJGltYWdlX3NpemVzICkgJiYgJ2ltYWdlX25vX2VkaXRvcicgPT09ICRpbWFnZV9zaXplcy0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCQkJLy8gV2FybiB1bmxlc3MgUERGIG9yIG5vbi1zdGFuZGFyZCBpbWFnZS4KCQkJaWYgKCAhICRpc19wZGYgJiYgaXNfYXJyYXkoICRtZXRhZGF0YSApICYmICEgZW1wdHkoICRtZXRhZGF0YVsnc2l6ZXMnXSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnJXMgKElEICVkKScsICRpbWFnZV9zaXplcy0+Z2V0X2Vycm9yX21lc3NhZ2UoKSwgJGF0dF9pZCApICk7CgkJCX0KCQkJJHNraXBfaXQgPSB0cnVlOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBJZiB1cGxvYWRlZCB3aGVuIGFwcGxpY2FibGUgaW1hZ2UgZWRpdG9yIHN1Y2ggYXMgSW1hZ2ljayB1bmF2YWlsYWJsZSwgdGhlIG1ldGFkYXRhIG9yIHNpemVzIG1ldGFkYXRhIG1heSBub3QgZXhpc3QuCgkJaWYgKCAhIGlzX2FycmF5KCAkbWV0YWRhdGEgKSApIHsKCQkJJG1ldGFkYXRhID0gYXJyYXkoKTsKCQl9CgkJLy8gSWYgc2V0IGAkbWV0YWRhdGFbJ3NpemVzJ11gIHNob3VsZCBiZSBhcnJheSBidXQgZXhwbGljaXRseSBjaGVjayBhcyBmb2xsb3dpbmcgY29kZSBkZXBlbmRzIG9uIGl0LgoJCWlmICggISBpc3NldCggJG1ldGFkYXRhWydzaXplcyddICkgfHwgISBpc19hcnJheSggJG1ldGFkYXRhWydzaXplcyddICkgKSB7CgkJCSRtZXRhZGF0YVsnc2l6ZXMnXSA9IGFycmF5KCk7CgkJfQoKCQkvLyBSZW1vdmUgYW55IG9sZCB0aHVtYm5haWxzIChzbyBub3cgZGVzdHJ1Y3RpdmUpLgoJCWlmICggISAkc2tpcF9kZWxldGUgKSB7CgkJCSR0aGlzLT5yZW1vdmVfb2xkX2ltYWdlcyggJG1ldGFkYXRhLCAkZnVsbHNpemVwYXRoLCAkaW1hZ2Vfc2l6ZSApOwoJCX0KCgkJLy8gQ2hlY2sgZm9yIGFueSBvdGhlciBlcnJvciAoc3VjaCBhcyBsb2FkIGVycm9yKSBhcGFydCBmcm9tIG5vIGVkaXRvciBhdmFpbGFibGUuCgkJaWYgKCBpc193cF9lcnJvciggJGltYWdlX3NpemVzICkgKSB7CgkJCS8vIFdhcm4gYnV0IGFzc3VtZSBpdCBtYXkgYmUgcG9zc2libGUgdG8gcmVnZW5lcmF0ZSBhbmQgYWxsb3cgcHJvY2Vzc2luZyB0byBjb250aW51ZSBhbmQgcG9zc2libHkgZmFpbC4KCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnJXMgKElEICVkKScsICRpbWFnZV9zaXplcy0+Z2V0X2Vycm9yX21lc3NhZ2UoKSwgJGF0dF9pZCApICk7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gSGF2ZSBzaXplcyAtIGNoZWNrIHdoZXRoZXIgdGhlcmUncmUgbmV3IG9uZXMgb3IgdGhleSd2ZSBjaGFuZ2VkLiBOb3RlIHRoYXQgYW4gYXR0YWNobWVudCBjYW4gaGF2ZSBubyBzaXplcyBpZiBpdCdzIG9uIG9yIGJlbG93IHRoZSB0aHVtYm5haWwgdGhyZXNob2xkLgoKCQlpZiAoICRpbWFnZV9zaXplICkgewoJCQlpZiAoIGVtcHR5KCAkaW1hZ2Vfc2l6ZXNbICRpbWFnZV9zaXplIF0gKSApIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQlpZiAoIGVtcHR5KCAkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gKSApIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJCSRtZXRhZGF0YVsnc2l6ZXMnXSA9IGFycmF5KCAkaW1hZ2Vfc2l6ZSA9PiAkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gKTsKCQl9CgoJCWlmICggJHRoaXMtPmltYWdlX3NpemVzX2RpZmZlciggJGltYWdlX3NpemVzLCAkbWV0YWRhdGFbJ3NpemVzJ10gKSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkZGlyX3BhdGggPSBkaXJuYW1lKCAkZnVsbHNpemVwYXRoICkgLiAnLyc7CgoJCS8vIENoZWNrIHRoYXQgdGhlIHRodW1ibmFpbCBmaWxlcyBleGlzdC4KCQlmb3JlYWNoICggJG1ldGFkYXRhWydzaXplcyddIGFzICRzaXplX2luZm8gKSB7CgkJCSRpbnRlcm1lZGlhdGVfcGF0aCA9ICRkaXJfcGF0aCAuICRzaXplX2luZm9bJ2ZpbGUnXTsKCgkJCWlmICggJGludGVybWVkaWF0ZV9wYXRoID09PSAkZnVsbHNpemVwYXRoICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCWlmICggISBmaWxlX2V4aXN0cyggJGludGVybWVkaWF0ZV9wYXRoICkgKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLy8gV2hldGhlciB0aGVyZSdzIG5ldyBpbWFnZSBzaXplcyBvciB0aGUgd2lkdGgvaGVpZ2h0IG9mIGV4aXN0aW5nIGltYWdlIHNpemVzIGhhdmUgY2hhbmdlZC4KCXByaXZhdGUgZnVuY3Rpb24gaW1hZ2Vfc2l6ZXNfZGlmZmVyKCAkaW1hZ2Vfc2l6ZXMsICRtZXRhX3NpemVzICkgewoJCS8vIENoZWNrIGlmIGhhdmUgbmV3IGltYWdlIHNpemUocykuCgkJaWYgKCBhcnJheV9kaWZmKCBhcnJheV9rZXlzKCAkaW1hZ2Vfc2l6ZXMgKSwgYXJyYXlfa2V5cyggJG1ldGFfc2l6ZXMgKSApICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJLy8gQ2hlY2sgaWYgaW1hZ2Ugc2l6ZXMgaGF2ZSBjaGFuZ2VkLgoJCWZvcmVhY2ggKCAkaW1hZ2Vfc2l6ZXMgYXMgJG5hbWUgPT4gJGltYWdlX3NpemUgKSB7CgkJCWlmICggJGltYWdlX3NpemVbJ3dpZHRoJ10gIT09ICRtZXRhX3NpemVzWyAkbmFtZSBdWyd3aWR0aCddIHx8ICRpbWFnZV9zaXplWydoZWlnaHQnXSAhPT0gJG1ldGFfc2l6ZXNbICRuYW1lIF1bJ2hlaWdodCddICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8vIExpa2UgV1AncyBnZXRfaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzKCksIGJ1dCByZW1vdmVzIHNpemVzIHRoYXQgd29uJ3QgYmUgZ2VuZXJhdGVkIGZvciBhIHBhcnRpY3VsYXIgYXR0YWNobWVudCBkdWUgdG8gaXRzIGJlaW5nIG9uIG9yIGJlbG93IHRoZWlyIHRocmVzaG9sZHMsCgkvLyBhbmQgcmV0dXJucyBhc3NvY2lhdGl2ZSBhcnJheSB3aXRoIHNpemUgbmFtZSA9PiB3aWR0aC9oZWlnaHQgZW50cmllcywgcmVzb2x2ZWQgdG8gY3JvcCB2YWx1ZXMgaWYgYXBwbGljYWJsZS4KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2ludGVybWVkaWF0ZV9pbWFnZV9zaXplc19mb3JfYXR0YWNobWVudCggJGZ1bGxzaXplcGF0aCwgJGlzX3BkZiwgJG1ldGFkYXRhICkgewoKCQkvLyBOZWVkIHRvIGdldCB3aWR0aCwgaGVpZ2h0IG9mIGF0dGFjaG1lbnQgZm9yIGltYWdlX3Jlc2l6ZV9kaW1lbnNpb25zKCkuCgkJJGVkaXRvciA9IHdwX2dldF9pbWFnZV9lZGl0b3IoICRmdWxsc2l6ZXBhdGggKTsKCQlpZiAoIGlzX3dwX2Vycm9yKCAkZWRpdG9yICkgKSB7CgkJCXJldHVybiAkZWRpdG9yOwoJCX0KCQkkcmVzdWx0ID0gJGVkaXRvci0+bG9hZCgpOwoJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJdW5zZXQoICRlZGl0b3IgKTsKCQkJcmV0dXJuICRyZXN1bHQ7CgkJfQoJCWxpc3QoICR3aWR0aCwgJGhlaWdodCApID0gYXJyYXlfdmFsdWVzKCAkZWRpdG9yLT5nZXRfc2l6ZSgpICk7CgkJdW5zZXQoICRlZGl0b3IgKTsKCgkJJHNpemVzID0gYXJyYXkoKTsKCQlmb3JlYWNoICggJHRoaXMtPmdldF9pbnRlcm1lZGlhdGVfc2l6ZXMoICRpc19wZGYsICRtZXRhZGF0YSApIGFzICRuYW1lID0+ICRzaXplICkgewoJCQkvLyBOZWVkIHRvIGNoZWNrIGRlc3RpbmF0aW9uIGFuZCBvcmlnaW5hbCB3aWR0aCBvciBoZWlnaHQgZGlmZmVyIGJlZm9yZSBjYWxsaW5nIGltYWdlX3Jlc2l6ZV9kaW1lbnNpb25zKCksIG90aGVyd2lzZSBpdCB3aWxsIHJldHVybiBub24tZmFsc2UuCgkJCSRkaW1zID0gaW1hZ2VfcmVzaXplX2RpbWVuc2lvbnMoICR3aWR0aCwgJGhlaWdodCwgJHNpemVbJ3dpZHRoJ10sICRzaXplWydoZWlnaHQnXSwgJHNpemVbJ2Nyb3AnXSApOwoJCQlpZiAoICggJHdpZHRoICE9PSAkc2l6ZVsnd2lkdGgnXSB8fCAkaGVpZ2h0ICE9PSAkc2l6ZVsnaGVpZ2h0J10gKSAmJiAkZGltcyApIHsKCQkJCWxpc3QoICRkc3RfeCwgJGRzdF95LCAkc3JjX3gsICRzcmNfeSwgJGRzdF93LCAkZHN0X2gsICRzcmNfdywgJHNyY19oICkgPSAkZGltczsKCQkJCSRzaXplc1sgJG5hbWUgXSA9IGFycmF5KAoJCQkJCSd3aWR0aCcgID0+ICRkc3RfdywKCQkJCQknaGVpZ2h0JyA9PiAkZHN0X2gsCgkJCQkpOwoJCQl9CgkJfQoJCXJldHVybiAkc2l6ZXM7Cgl9CgoJLy8gTGlrZSBXUCdzIGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMoKSwgYnV0IHJldHVybnMgYXNzb2NpYXRpdmUgYXJyYXkgd2l0aCBuYW1lID0+IHNpemUgaW5mbyBlbnRyaWVzIChhbmQgY2F0ZXJzIGZvciBQREZzIGFsc28pLgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfaW50ZXJtZWRpYXRlX3NpemVzKCAkaXNfcGRmLCAkbWV0YWRhdGEgKSB7CgkJaWYgKCAkaXNfcGRmICkgewoJCQkvLyBDb3BpZWQgZnJvbSB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCkgaW4gIndwLWFkbWluL2luY2x1ZGVzL2ltYWdlLnBocCIuCgkJCSRmYWxsYmFja19zaXplcyA9IGFycmF5KAoJCQkJJ3RodW1ibmFpbCcsCgkJCQknbWVkaXVtJywKCQkJCSdsYXJnZScsCgkJCSk7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJCSRpbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMgPSBhcHBseV9maWx0ZXJzKCAnZmFsbGJhY2tfaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzJywgJGZhbGxiYWNrX3NpemVzLCAkbWV0YWRhdGEgKTsKCQl9IGVsc2UgewoJCQkkaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzID0gZ2V0X2ludGVybWVkaWF0ZV9pbWFnZV9zaXplcygpOwoJCX0KCgkJLy8gQWRhcHRlZCBmcm9tIHdwX2dlbmVyYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoKSBpbiAid3AtYWRtaW4vaW5jbHVkZXMvaW1hZ2UucGhwIi4KCgkJaWYgKCBmdW5jdGlvbl9leGlzdHMoICd3cF9nZXRfYWRkaXRpb25hbF9pbWFnZV9zaXplcycgKSApIHsKCQkJJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzID0gd3BfZ2V0X2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMoKTsKCQl9IGVsc2UgewoJCQkvLyBGb3IgV1AgPCA0LjcuMC4KCQkJZ2xvYmFsICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplczsKCQkJaWYgKCAhICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplcyApIHsKCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBVc2VkIGFzIGEgZmFsbGJhY2sgZm9yIFdvcmRQcmVzcyB2ZXJzaW9uIGxlc3MgdGhhbiA0LjcuMCBhcyBmdW5jdGlvbiB3cF9nZXRfYWRkaXRpb25hbF9pbWFnZV9zaXplcyBkaWRuJ3QgZXhpc3QgdGhlbi4KCQkJCSRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplcyA9IGFycmF5KCk7CgkJCX0KCQl9CgoJCSRzaXplcyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICRpbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMgYXMgJHMgKSB7CgkJCWlmICggaXNzZXQoICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplc1sgJHMgXVsnd2lkdGgnXSApICkgewoJCQkJJHNpemVzWyAkcyBdWyd3aWR0aCddID0gKGludCkgJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzWyAkcyBdWyd3aWR0aCddOwoJCQl9IGVsc2UgewoJCQkJJHNpemVzWyAkcyBdWyd3aWR0aCddID0gKGludCkgZ2V0X29wdGlvbiggInskc31fc2l6ZV93IiApOwoJCQl9CgoJCQlpZiAoIGlzc2V0KCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXNbICRzIF1bJ2hlaWdodCddICkgKSB7CgkJCQkkc2l6ZXNbICRzIF1bJ2hlaWdodCddID0gKGludCkgJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzWyAkcyBdWydoZWlnaHQnXTsKCQkJfSBlbHNlIHsKCQkJCSRzaXplc1sgJHMgXVsnaGVpZ2h0J10gPSAoaW50KSBnZXRfb3B0aW9uKCAieyRzfV9zaXplX2giICk7CgkJCX0KCgkJCWlmICggaXNzZXQoICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplc1sgJHMgXVsnY3JvcCddICkgKSB7CgkJCQkkc2l6ZXNbICRzIF1bJ2Nyb3AnXSA9IChib29sKSAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXNbICRzIF1bJ2Nyb3AnXTsKCQkJfSBlbHNlIHsKCQkJCS8vIEZvcmNlIFBERiB0aHVtYm5haWxzIHRvIGJlIHNvZnQgY3JvcHMuCgkJCQlpZiAoICRpc19wZGYgJiYgJ3RodW1ibmFpbCcgPT09ICRzICkgewoJCQkJCSRzaXplc1sgJHMgXVsnY3JvcCddID0gZmFsc2U7CgkJCQl9IGVsc2UgewoJCQkJCSRzaXplc1sgJHMgXVsnY3JvcCddID0gKGJvb2wpIGdldF9vcHRpb24oICJ7JHN9X2Nyb3AiICk7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIENoZWNrIGhlcmUgdGhhdCBub3QgUERGIChhcyBmaWx0ZXIgbm90IGFwcGxpZWQgaW4gY29yZSBpZiBpcykgYW5kIGAkbWV0YWRhdGFgIGlzIGFycmF5IChhcyBtYXkgbm90IGJlIGFuZCBmaWx0ZXIgb25seSBhcHBsaWVkIGluIGNvcmUgd2hlbiBpcykuCgkJaWYgKCAhICRpc19wZGYgJiYgaXNfYXJyYXkoICRtZXRhZGF0YSApICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkkc2l6ZXMgPSBhcHBseV9maWx0ZXJzKCAnaW50ZXJtZWRpYXRlX2ltYWdlX3NpemVzX2FkdmFuY2VkJywgJHNpemVzLCAkbWV0YWRhdGEgKTsKCQl9CgoJCXJldHVybiAkc2l6ZXM7Cgl9CgoJLy8gQWRkIGZpbHRlcnMgdG8gb25seSBwcm9jZXNzIGEgcGFydGljdWxhciBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZSBpbiB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCkuCglwcml2YXRlIGZ1bmN0aW9uIGFkZF9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplICkgewoJCSRpbWFnZV9zaXplX2ZpbHRlcnMgPSBhcnJheSgpOwoKCQkvLyBGb3IgaW1hZ2VzLgoJCSRpbWFnZV9zaXplX2ZpbHRlcnNbJ2ludGVybWVkaWF0ZV9pbWFnZV9zaXplc19hZHZhbmNlZCddID0gZnVuY3Rpb24gKCAkc2l6ZXMgKSB1c2UgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJLy8gJHNpemVzIGlzIGFzc29jaWF0aXZlIGFycmF5IG9mIG5hbWUgPT4gc2l6ZSBpbmZvIGVudHJpZXMuCgkJCWlmICggaXNzZXQoICRzaXplc1sgJGltYWdlX3NpemUgXSApICkgewoJCQkJcmV0dXJuIGFycmF5KCAkaW1hZ2Vfc2l6ZSA9PiAkc2l6ZXNbICRpbWFnZV9zaXplIF0gKTsKCQkJfQoJCQlyZXR1cm4gYXJyYXkoKTsKCQl9OwoKCQkvLyBGb3IgUERGIHByZXZpZXdzLgoJCSRpbWFnZV9zaXplX2ZpbHRlcnNbJ2ZhbGxiYWNrX2ludGVybWVkaWF0ZV9pbWFnZV9zaXplcyddID0gZnVuY3Rpb24gKCAkZmFsbGJhY2tfc2l6ZXMgKSB1c2UgKCAkaW1hZ2Vfc2l6ZSApIHsKCQkJLy8gJGZhbGxiYWNrX3NpemVzIGlzIGluZGV4ZWQgYXJyYXkgb2Ygc2l6ZSBuYW1lcy4KCQkJaWYgKCBpbl9hcnJheSggJGltYWdlX3NpemUsICRmYWxsYmFja19zaXplcywgdHJ1ZSApICkgewoJCQkJcmV0dXJuIGFycmF5KCAkaW1hZ2Vfc2l6ZSApOwoJCQl9CgkJCXJldHVybiBhcnJheSgpOwoJCX07CgoJCWZvcmVhY2ggKCAkaW1hZ2Vfc2l6ZV9maWx0ZXJzIGFzICRuYW1lID0+ICRmaWx0ZXIgKSB7CgkJCWFkZF9maWx0ZXIoICRuYW1lLCAkZmlsdGVyLCBQSFBfSU5UX01BWCApOwoJCX0KCgkJcmV0dXJuICRpbWFnZV9zaXplX2ZpbHRlcnM7Cgl9CgoJLy8gUmVtb3ZlIGFib3ZlIGludGVybWVkaWF0ZSBpbWFnZSBzaXplIGZpbHRlcnMuCglwcml2YXRlIGZ1bmN0aW9uIHJlbW92ZV9pbWFnZV9zaXplX2ZpbHRlcnMoICRpbWFnZV9zaXplX2ZpbHRlcnMgKSB7CgkJZm9yZWFjaCAoICRpbWFnZV9zaXplX2ZpbHRlcnMgYXMgJG5hbWUgPT4gJGZpbHRlciApIHsKCQkJcmVtb3ZlX2ZpbHRlciggJG5hbWUsICRmaWx0ZXIsIFBIUF9JTlRfTUFYICk7CgkJfQoJfQoKCS8vIFVwZGF0ZSBhdHRhY2htZW50IHNpemVzIG1ldGFkYXRhIGp1c3QgZm9yIGEgcGFydGljdWxhciBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZS4KCXByaXZhdGUgZnVuY3Rpb24gdXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGFfZm9yX2ltYWdlX3NpemUoICRpZCwgJG5ld19tZXRhZGF0YSwgJGltYWdlX3NpemUgKSB7CgkJJG1ldGFkYXRhID0gd3BfZ2V0X2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCApOwoKCQlpZiAoICEgaXNfYXJyYXkoICRtZXRhZGF0YSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBJZiBoYXZlIG1ldGFkYXRhIGZvciBpbWFnZV9zaXplLgoJCWlmICggISBlbXB0eSggJG5ld19tZXRhZGF0YVsnc2l6ZXMnXVsgJGltYWdlX3NpemUgXSApICkgewoJCQkkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gPSAkbmV3X21ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdOwoJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkbWV0YWRhdGEgKTsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBFbHNlIHJlbW92ZSB1bnVzZWQgbWV0YWRhdGEgaWYgYW55LgoJCWlmICggISBlbXB0eSggJG1ldGFkYXRhWydzaXplcyddWyAkaW1hZ2Vfc2l6ZSBdICkgKSB7CgkJCXVuc2V0KCAkbWV0YWRhdGFbJ3NpemVzJ11bICRpbWFnZV9zaXplIF0gKTsKCQkJd3BfdXBkYXRlX2F0dGFjaG1lbnRfbWV0YWRhdGEoICRpZCwgJG1ldGFkYXRhICk7CgkJCS8vIFRyZWF0IHJlbW92aW5nIHVudXNlZCBtZXRhZGF0YSBhcyBubyBjaGFuZ2UuCgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEdldCBpbWFnZXMgZnJvbSB0aGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyAgICAgICAgICAgICAgICAgIFRoZSBxdWVyeSBhcmd1bWVudHMgdG8gdXNlLiBPcHRpb25hbC4KCSAqIEBwYXJhbSBhcnJheSAkYWRkaXRpb25hbF9taW1lX3R5cGVzIFRoZSBhZGRpdGlvbmFsIG1pbWUgdHlwZXMgdG8gc2VhcmNoIGZvci4gT3B0aW9uYWwuCgkgKgoJICogQHJldHVybiBXUF9RdWVyeSBUaGUgcXVlcnkgcmVzdWx0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9pbWFnZXMoICRhcmdzID0gYXJyYXkoKSwgJGFkZGl0aW9uYWxfbWltZV90eXBlcyA9IGFycmF5KCkgKSB7CgkJJG1pbWVfdHlwZXMgPSBhcnJheV9tZXJnZSggYXJyYXkoICdpbWFnZScgKSwgJGFkZGl0aW9uYWxfbWltZV90eXBlcyApOwoKCQkkcXVlcnlfYXJncyA9IGFycmF5KAoJCQkncG9zdF90eXBlJyAgICAgID0+ICdhdHRhY2htZW50JywKCQkJJ3Bvc3RfX2luJyAgICAgICA9PiAkYXJncywKCQkJJ3Bvc3RfbWltZV90eXBlJyA9PiAkbWltZV90eXBlcywKCQkJJ3Bvc3Rfc3RhdHVzJyAgICA9PiAnYW55JywKCQkJJ3Bvc3RzX3Blcl9wYWdlJyA9PiAtMSwKCQkpOwoKCQlyZXR1cm4gbmV3IFdQX1F1ZXJ5KCAkcXVlcnlfYXJncyApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBtZXRhZGF0YSBmb3IgdGhlIHBhc3NlZCBpbnRlcm1lZGlhdGUgaW1hZ2Ugc2l6ZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzaXplIFRoZSBpbWFnZSBzaXplIHRvIGdldCB0aGUgbWV0YWRhdGEgZm9yLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgVGhlIGltYWdlIHNpemUgbWV0YWRhdGEuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2ludGVybWVkaWF0ZV9zaXplX21ldGFkYXRhKCAkc2l6ZSApIHsKCQkkd2lkdGggID0gaW50dmFsKCBnZXRfb3B0aW9uKCAieyRzaXplfV9zaXplX3ciICkgKTsKCQkkaGVpZ2h0ID0gaW50dmFsKCBnZXRfb3B0aW9uKCAieyRzaXplfV9zaXplX2giICkgKTsKCQkkY3JvcCAgID0gZ2V0X29wdGlvbiggInskc2l6ZX1fY3JvcCIgKTsKCgkJcmV0dXJuIGFycmF5KAoJCQknbmFtZScgICA9PiAkc2l6ZSwKCQkJJ3dpZHRoJyAgPT4gJHdpZHRoLAoJCQknaGVpZ2h0JyA9PiAkaGVpZ2h0LAoJCQknY3JvcCcgICA9PiBmYWxzZSAhPT0gJGNyb3AgPyAnaGFyZCcgOiAnc29mdCcsCgkJCSdyYXRpbycgID0+IGZhbHNlICE9PSAkY3JvcCA/ICR0aGlzLT5nZXRfcmF0aW8oICR3aWR0aCwgJGhlaWdodCApIDogJ04vQScsCgkJKTsKCX0KCgkvKioKCSAqIEdldCBhbGwgdGhlIHJlZ2lzdGVyZWQgaW1hZ2Ugc2l6ZXMgYWxvbmcgd2l0aCB0aGVpciBkaW1lbnNpb25zLgoJICoKCSAqIEBnbG9iYWwgYXJyYXkgJF93cF9hZGRpdGlvbmFsX2ltYWdlX3NpemVzIFRoZSBhZGRpdGlvbmFsIGltYWdlIHNpemVzIHRvIHBhcnNlLgoJICoKCSAqIEBsaW5rIGh0dHBzOi8vd29yZHByZXNzLnN0YWNrZXhjaGFuZ2UuY29tL2EvMjUxNjAyIE9yaWdpbmFsIHNvbHV0aW9uLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgJGltYWdlX3NpemVzIFRoZSBpbWFnZSBzaXplcwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9yZWdpc3RlcmVkX2ltYWdlX3NpemVzKCkgewoJCWdsb2JhbCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXM7CgoJCSRpbWFnZV9zaXplcyAgICAgICAgID0gYXJyYXkoKTsKCQkkZGVmYXVsdF9pbWFnZV9zaXplcyA9IGdldF9pbnRlcm1lZGlhdGVfaW1hZ2Vfc2l6ZXMoKTsKCgkJZm9yZWFjaCAoICRkZWZhdWx0X2ltYWdlX3NpemVzIGFzICRzaXplICkgewoJCQkkaW1hZ2Vfc2l6ZXNbXSA9ICR0aGlzLT5nZXRfaW50ZXJtZWRpYXRlX3NpemVfbWV0YWRhdGEoICRzaXplICk7CgkJfQoKCQlpZiAoIGlzX2FycmF5KCAkX3dwX2FkZGl0aW9uYWxfaW1hZ2Vfc2l6ZXMgKSApIHsKCQkJZm9yZWFjaCAoICRfd3BfYWRkaXRpb25hbF9pbWFnZV9zaXplcyBhcyAkc2l6ZSA9PiAkc2l6ZV9hcmdzICkgewoJCQkJJGNyb3AgICAgICAgICAgPSBmaWx0ZXJfdmFyKCAkc2l6ZV9hcmdzWydjcm9wJ10sIEZJTFRFUl9WQUxJREFURV9CT09MRUFOICk7CgkJCQkkaW1hZ2Vfc2l6ZXNbXSA9IGFycmF5KAoJCQkJCSduYW1lJyAgID0+ICRzaXplLAoJCQkJCSd3aWR0aCcgID0+ICRzaXplX2FyZ3NbJ3dpZHRoJ10sCgkJCQkJJ2hlaWdodCcgPT4gJHNpemVfYXJnc1snaGVpZ2h0J10sCgkJCQkJJ2Nyb3AnICAgPT4gZW1wdHkoICRjcm9wICkgfHwgaXNfYXJyYXkoICRzaXplX2FyZ3NbJ2Nyb3AnXSApID8gJ3NvZnQnIDogJ2hhcmQnLAoJCQkJCSdyYXRpbycgID0+IGVtcHR5KCAkY3JvcCApIHx8IGlzX2FycmF5KCAkc2l6ZV9hcmdzWydjcm9wJ10gKSA/ICdOL0EnIDogJHRoaXMtPmdldF9yYXRpbyggJHNpemVfYXJnc1snd2lkdGgnXSwgJHNpemVfYXJnc1snaGVpZ2h0J10gKSwKCQkJCSk7CgkJCX0KCQl9CgoJCXJldHVybiAkaW1hZ2Vfc2l6ZXM7Cgl9CgoJLyoqCgkgKiBGaXggaW1hZ2Ugb3JpZW50YXRpb24gZm9yIG9uZSBvciBtb3JlIGF0dGFjaG1lbnRzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPGF0dGFjaG1lbnQtaWQ+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBJRHMgb2YgdGhlIGF0dGFjaG1lbnRzIHRvIHJlZ2VuZXJhdGUuCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogQ2hlY2sgaW1hZ2VzIG5lZWRpbmcgb3JpZW50YXRpb24gd2l0aG91dCBwZXJmb3JtaW5nIHRoZSBvcGVyYXRpb24uCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBGaXggb3JpZW50YXRpb24gZm9yIGFsbCBpbWFnZXMuCgkgKiAgICAgJCB3cCBtZWRpYSBmaXgtb3JpZW50YXRpb24KCSAqICAgICAxLzMgRml4aW5nIG9yaWVudGF0aW9uIGZvciAiTGFuZHNjYXBlXzQiIChJRCA2MikuCgkgKiAgICAgMi8zIEZpeGluZyBvcmllbnRhdGlvbiBmb3IgIkxhbmRzY2FwZV8zIiAoSUQgNjEpLgoJICogICAgIDMvMyBGaXhpbmcgb3JpZW50YXRpb24gZm9yICJMYW5kc2NhcGVfMiIgKElEIDYwKS4KCSAqICAgICBTdWNjZXNzOiBGaXhlZCAzIG9mIDMgaW1hZ2VzLgoJICoKCSAqICAgICAjIEZpeCBvcmllbnRhdGlvbiBkcnkgcnVuLgoJICogICAgICQgd3AgbWVkaWEgZml4LW9yaWVudGF0aW9uIDYzIC1kcnkgcnVuCgkgKiAgICAgMS8xICJQb3J0cmFpdF82IiAoSUQgNjMpIHdpbGwgYmUgYWZmZWN0ZWQuCgkgKiAgICAgU3VjY2VzczogMSBvZiAxIGltYWdlIHdpbGwgYmUgYWZmZWN0ZWQuCgkgKgoJICogICAgICMgRml4IG9yaWVudGF0aW9uIGZvciBzcGVjaWZpYyBpbWFnZXMuCgkgKiAgICAgJCB3cCBtZWRpYSBmaXgtb3JpZW50YXRpb24gNjMKCSAqICAgICAxLzEgRml4aW5nIG9yaWVudGF0aW9uIGZvciAiUG9ydHJhaXRfNiIgKElEIDYzKS4KCSAqICAgICBTdWNjZXNzOiBGaXhlZCAxIG9mIDEgaW1hZ2VzLgoJICoKCSAqIEBzdWJjb21tYW5kIGZpeC1vcmllbnRhdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gZml4X29yaWVudGF0aW9uKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCS8vIEVYSUYgaXMgcmVxdWlyZWQgdG8gcmVhZCBpbWFnZSBtZXRhZGF0YSBmb3Igb3JpZW50YXRpb24uCgkJaWYgKCAhIGV4dGVuc2lvbl9sb2FkZWQoICdleGlmJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiJ0VYSUYnIGV4dGVuc2lvbiBpcyBub3QgbG9hZGVkLCBpdCBpcyByZXF1aXJlZCBmb3IgdGhpcyBvcGVyYXRpb24uIiApOwoJCX0gZWxzZWlmICggISBmdW5jdGlvbl9leGlzdHMoICdleGlmX3JlYWRfZGF0YScgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkZ1bmN0aW9uICdleGlmX3JlYWRfZGF0YScgZG9lcyBub3QgZXhpc3QsIGl0IGlzIHJlcXVpcmVkIGZvciB0aGlzIG9wZXJhdGlvbi4iICk7CgkJfQoKCQkkaW1hZ2VzICA9ICR0aGlzLT5nZXRfaW1hZ2VzKCAkYXJncyApOwoJCSRjb3VudCAgID0gJGltYWdlcy0+cG9zdF9jb3VudDsKCQkkZHJ5X3J1biA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RyeS1ydW4nICk7CgoJCWlmICggISAkY291bnQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyBpbWFnZXMgZm91bmQuJyApOwoJCX0KCgkJJG51bWJlciAgICA9IDA7CgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJZm9yZWFjaCAoICRpbWFnZXMtPnBvc3RzIGFzICRwb3N0ICkgewoJCQkkbnVtYmVyKys7CgkJCWlmICggMCA9PT0gJG51bWJlciAlIHNlbGY6OldQX0NMRUFSX09CSkVDVF9DQUNIRV9JTlRFUlZBTCApIHsKCQkJCVV0aWxzXHdwX2NsZWFyX29iamVjdF9jYWNoZSgpOwoJCQl9CgkJCSR0aGlzLT5wcm9jZXNzX29yaWVudGF0aW9uX2ZpeCggJHBvc3QtPklELCAieyRudW1iZXJ9L3skY291bnR9IiwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJGRyeV9ydW4gKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKSApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAnJXMgb2YgJXMgJXMgd2lsbCBiZSBhZmZlY3RlZC4nLCAkc3VjY2Vzc2VzLCAkY291bnQsIFV0aWxzXHBsdXJhbGl6ZSggJ2ltYWdlJywgJGNvdW50ICkgKSApOwoJCX0gZWxzZSB7CgkJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ2ltYWdlJywgJ2ZpeCcsICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycyApOwoJCX0KCX0KCgkvKioKCSAqIFBlcmZvcm0gb3JpZW50YXRpb24gZml4IG9uIGF0dGFjaG1lbnRzLgoJICoKCSAqIEBwYXJhbSBpbnQgICAgJGlkICAgICAgICBBdHRhY2htZW50IElkLgoJICogQHBhcmFtIHN0cmluZyAkcHJvZ3Jlc3MgIEN1cnJlbnQgcHJvZ3Jlc3Mgc3RyaW5nLgoJICogQHBhcmFtIGludCAgICAkc3VjY2Vzc2VzIENvdW50IG9mIHN1Y2Nlc3MgaW4gY3VycmVudCBvcGVyYXRpb24uCgkgKiBAcGFyYW0gaW50ICAgICRlcnJvcnMgICAgQ291bnQgb2YgZXJyb3JzIGluIGN1cnJlbnQgb3BlcmF0aW9uLgoJICogQHBhcmFtIGJvb2wgICAkZHJ5X3J1biAgIElzIHRoaXMgYSBkcnkgcnVuPwoJICovCglwcml2YXRlIGZ1bmN0aW9uIHByb2Nlc3Nfb3JpZW50YXRpb25fZml4KCAkaWQsICRwcm9ncmVzcywgJiRzdWNjZXNzZXMsICYkZXJyb3JzLCAkZHJ5X3J1biApIHsKCQkkdGl0bGUgPSBnZXRfdGhlX3RpdGxlKCAkaWQgKTsKCQlpZiAoICcnID09PSAkdGl0bGUgKSB7CgkJCS8vIElmIGF1ZGlvIG9yIHZpZGVvIGNvdmVyIGFydCB0aGVuIHRoZSBpZCBpcyB0aGUgc3ViIGF0dGFjaG1lbnQgaWQsIHdoaWNoIGhhcyBubyB0aXRsZS4KCQkJaWYgKCBtZXRhZGF0YV9leGlzdHMoICdwb3N0JywgJGlkLCAnX2NvdmVyX2hhc2gnICkgKSB7CgkJCQkvLyBVbmZvcnR1bmF0ZWx5IHRoZSBvbmx5IHdheSB0byBnZXQgdGhlIGF0dGFjaG1lbnQgdGl0bGUgd291bGQgYmUgdG8gZG8gYSBub24taW5kZXhlZCBxdWVyeSBhZ2FpbnN0IHRoZSBtZXRhIHZhbHVlIG9mIGBfdGh1bWJuYWlsX2lkYC4gU28gZG9uJ3QuCgkJCQkkYXR0X2Rlc2MgPSBzcHJpbnRmKCAnY292ZXIgYXR0YWNobWVudCAoSUQgJWQpJywgJGlkICk7CgkJCX0gZWxzZSB7CgkJCQkkYXR0X2Rlc2MgPSBzcHJpbnRmKCAnIihubyB0aXRsZSkiIChJRCAlZCknLCAkaWQgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRhdHRfZGVzYyA9IHNwcmludGYoICciJTEkcyIgKElEICUyJGQpJywgJHRpdGxlLCAkaWQgKTsKCQl9CgoJCSRmdWxsX3NpemVfcGF0aCA9ICR0aGlzLT5nZXRfYXR0YWNoZWRfZmlsZSggJGlkICk7CgoJCWlmICggZmFsc2UgPT09ICRmdWxsX3NpemVfcGF0aCB8fCAhIGZpbGVfZXhpc3RzKCAkZnVsbF9zaXplX3BhdGggKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ2FuJ3QgZmluZCB7JGF0dF9kZXNjfS4iICk7CgkJCSRlcnJvcnMrKzsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gR2V0IGN1cnJlbnQgbWV0YWRhdGEgb2YgdGhlIGF0dGFjaG1lbnQuCgkJJG1ldGFkYXRhICAgPSB3cF9nZW5lcmF0ZV9hdHRhY2htZW50X21ldGFkYXRhKCAkaWQsICRmdWxsX3NpemVfcGF0aCApOwoJCSRpbWFnZV9tZXRhID0gISBlbXB0eSggJG1ldGFkYXRhWydpbWFnZV9tZXRhJ10gKSA/ICRtZXRhZGF0YVsnaW1hZ2VfbWV0YSddIDogW107CgoJCWlmICggaXNzZXQoICRpbWFnZV9tZXRhWydvcmllbnRhdGlvbiddICkgJiYgYWJzaW50KCAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApID4gMSApIHsKCQkJaWYgKCAhICRkcnlfcnVuICkgewoJCQkJV1BfQ0xJOjpsb2coICJ7JHByb2dyZXNzfSBGaXhpbmcgb3JpZW50YXRpb24gZm9yIHskYXR0X2Rlc2N9LiIgKTsKCQkJCWlmICggZmFsc2UgIT09ICR0aGlzLT5mbGlwX3JvdGF0ZV9pbWFnZSggJGlkLCAkbWV0YWRhdGEsICRpbWFnZV9tZXRhLCAkZnVsbF9zaXplX3BhdGggKSApIHsKCQkJCQkkc3VjY2Vzc2VzKys7CgkJCQl9IGVsc2UgewoJCQkJCSRlcnJvcnMrKzsKCQkJCQlXUF9DTEk6OmxvZyggIkNvdWxkbid0IGZpeCBvcmllbnRhdGlvbiBmb3IgeyRhdHRfZGVzY30uIiApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coICJ7JHByb2dyZXNzfSB7JGF0dF9kZXNjfSB3aWxsIGJlIGFmZmVjdGVkLiIgKTsKCQkJCSRzdWNjZXNzZXMrKzsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6bG9nKCAieyRwcm9ncmVzc30gTm8gb3JpZW50YXRpb24gZml4IHJlcXVpcmVkIGZvciB7JGF0dF9kZXNjfS4iICk7CgkJfQoJfQoKCS8qKgoJICogUGVyZm9ybSBpbWFnZSByb3RhdGUgb3BlcmF0aW9ucyBvbiB0aGUgaW1hZ2UuCgkgKgoJICogQHBhcmFtIGludCAgICAkaWQgICAgICAgICAgICAgQXR0YWNobWVudCBJZC4KCSAqIEBwYXJhbSBhcnJheSAgJG1ldGFkYXRhICAgICAgIEF0dGFjaG1lbnQgTWV0YWRhdGEuCgkgKiBAcGFyYW0gYXJyYXkgICRpbWFnZV9tZXRhICAgICBgaW1hZ2VfbWV0YWAgaW5mb3JtYXRpb24gZm9yIHRoZSBhdHRhY2htZW50LgoJICogQHBhcmFtIHN0cmluZyAkZnVsbF9zaXplX3BhdGggUGF0aCB0byBvcmlnaW5hbCBpbWFnZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgaW1hZ2Ugcm90YXRpb24gb3BlcmF0aW9uIHN1Y2NlZWRlZC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBmbGlwX3JvdGF0ZV9pbWFnZSggJGlkLCAkbWV0YWRhdGEsICRpbWFnZV9tZXRhLCAkZnVsbF9zaXplX3BhdGggKSB7CgkJJGVkaXRvciA9IHdwX2dldF9pbWFnZV9lZGl0b3IoICRmdWxsX3NpemVfcGF0aCApOwoKCQlpZiAoICEgaXNfd3BfZXJyb3IoICRlZGl0b3IgKSApIHsKCQkJJG9wZXJhdGlvbnMgPSAkdGhpcy0+Y2FsY3VsYXRlX3RyYW5zZm9ybWF0aW9uKCAoaW50KSAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApOwoKCQkJLy8gUm90YXRlIGltYWdlIGlmIHJlcXVpcmVkLgoJCQlpZiAoIHRydWUgPT09ICRvcGVyYXRpb25zWydyb3RhdGUnXSApIHsKCQkJCSRlZGl0b3ItPnJvdGF0ZSggJG9wZXJhdGlvbnNbJ2RlZ3JlZSddICk7CgkJCX0KCgkJCS8vIEZsaXAgaW1hZ2UgaWYgcmVxdWlyZWQuCgkJCWlmICggZmFsc2UgIT09ICRvcGVyYXRpb25zWydmbGlwJ10gKSB7CgkJCQkkZWRpdG9yLT5mbGlwKCAkb3BlcmF0aW9uc1snZmxpcCddWzBdLCAkb3BlcmF0aW9uc1snZmxpcCddWzFdICk7CgkJCX0KCgkJCS8vIFNhdmUgdGhlIGltYWdlIGFuZCBnZW5lcmF0ZSBtZXRhZGF0YS4KCQkJJGVkaXRvci0+c2F2ZSggJGZ1bGxfc2l6ZV9wYXRoICk7CgkJCSRtZXRhZGF0YSAgID0gd3BfZ2VuZXJhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkZnVsbF9zaXplX3BhdGggKTsKCQkJJGltYWdlX21ldGEgPSBlbXB0eSggJG1ldGFkYXRhWydpbWFnZV9tZXRhJ10gKSA/IFtdIDogJG1ldGFkYXRhWydpbWFnZV9tZXRhJ107CgoJCQkvLyBVcGRhdGUgYXR0YWNobWVudCBtZXRhZGF0YSB3aXRoIG5ld2x5IGdlbmVyYXRlZCBkYXRhLgoJCQl3cF91cGRhdGVfYXR0YWNobWVudF9tZXRhZGF0YSggJGlkLCAkbWV0YWRhdGEgKTsKCgkJCWlmICggaXNzZXQoICRpbWFnZV9tZXRhWydvcmllbnRhdGlvbiddICkgJiYgYWJzaW50KCAkaW1hZ2VfbWV0YVsnb3JpZW50YXRpb24nXSApID09PSAwICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJldHVybiBhcnJheSBvZiBvcGVyYXRpb25zIHRvIGJlIGRvbmUgZm9yIHByb3ZpZGVkIG9yaWVudGF0aW9uIHZhbHVlLgoJICoKCSAqIEBwYXJhbSBpbnQgJG9yaWVudGF0aW9uIEVYSUYgb3JpZW50YXRpb24gdmFsdWUuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNhbGN1bGF0ZV90cmFuc2Zvcm1hdGlvbiggJG9yaWVudGF0aW9uICkgewoJCSRyb3RhdGUgPSBmYWxzZTsKCQkkZmxpcCAgID0gZmFsc2U7CgkJJGRlZ3JlZSA9IDA7CgkJc3dpdGNoICggJG9yaWVudGF0aW9uICkgewoJCQljYXNlIDI6CgkJCQkkZmxpcCA9IFsgZmFsc2UsIHRydWUgXTsgLy8gJGZsaXAgaW1hZ2UgYWxvbmcgZ2l2ZW4gYXhpcyBbIGhvcml6b250YWwsIHZlcnRpY2FsIF0KCQkJCWJyZWFrOwoJCQljYXNlIDM6CgkJCQkkZmxpcCA9IFsgdHJ1ZSwgdHJ1ZSBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDoKCQkJCSRmbGlwID0gWyB0cnVlLCBmYWxzZSBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgNToKCQkJCSRkZWdyZWUgPSAtOTA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCSRmbGlwICAgPSBbIGZhbHNlLCB0cnVlIF07CgkJCQlicmVhazsKCQkJY2FzZSA2OgoJCQkJJGRlZ3JlZSA9IC05MDsKCQkJCSRyb3RhdGUgPSB0cnVlOwoJCQkJYnJlYWs7CgkJCWNhc2UgNzoKCQkJCSRkZWdyZWUgPSA5MDsKCQkJCSRyb3RhdGUgPSB0cnVlOwoJCQkJJGZsaXAgICA9IFsgZmFsc2UsIHRydWUgXTsKCQkJCWJyZWFrOwoJCQljYXNlIDg6CgkJCQkkZGVncmVlID0gOTA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJJGRlZ3JlZSA9IDA7CgkJCQkkcm90YXRlID0gdHJ1ZTsKCQkJCWJyZWFrOwoJCX0KCgkJcmV0dXJuIFsKCQkJJ2ZsaXAnICAgPT4gJGZsaXAsCgkJCSdkZWdyZWUnID0+ICRkZWdyZWUsCgkJCSdyb3RhdGUnID0+ICRyb3RhdGUsCgkJXTsKCX0KCgkvKioKCSAqIEFkZCBjb21wYXRpYmlsaXR5IGluZGlyZWN0aW9uIHRvIGdldF9hdHRhY2hlZF9maWxlKCkuCgkgKgoJICogSW4gV29yZFByZXNzIDUuMywgYmVoYXZpb3IgY2hhbmdlZCB0byBhY2NvdW50IGZvciBhdXRvbWF0aWMgcmVzaXppbmcgb2YKCSAqIGJpZyBpbWFnZSBmaWxlcy4KCSAqCgkgKiBAc2VlIGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzQ3ODczCgkgKgoJICogQHBhcmFtIGludCAkYXR0YWNobWVudF9pZCBJRCBvZiB0aGUgYXR0YWNobWVudCB0byBnZXQgdGhlIGZpbGVwYXRoIGZvci4KCSAqIEByZXR1cm4gc3RyaW5nfGZhbHNlIEZpbGVwYXRoIG9mIHRoZSBhdHRhY2htZW50LCBvciBmYWxzZSBpZiBub3QgZm91bmQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2F0dGFjaGVkX2ZpbGUoICRhdHRhY2htZW50X2lkICkgewoJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnd3BfZ2V0X29yaWdpbmFsX2ltYWdlX3BhdGgnICkgKSB7CgkJCSRmaWxlcGF0aCA9IHdwX2dldF9vcmlnaW5hbF9pbWFnZV9wYXRoKCAkYXR0YWNobWVudF9pZCApOwoKCQkJaWYgKCBmYWxzZSAhPT0gJGZpbGVwYXRoICkgewoJCQkJcmV0dXJuICRmaWxlcGF0aDsKCQkJfQoJCX0KCgkJcmV0dXJuIGdldF9hdHRhY2hlZF9maWxlKCAkYXR0YWNobWVudF9pZCApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfbWFpbnRlbmFuY2VfbW9kZV9hdXRvbG9hZGVyID0gX19ESVJfXyAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CgppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfbWFpbnRlbmFuY2VfbW9kZV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX21haW50ZW5hbmNlX21vZGVfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ21haW50ZW5hbmNlLW1vZGUnLCAnXFdQX0NMSVxNYWludGVuYW5jZU1vZGVcTWFpbnRlbmFuY2VNb2RlQ29tbWFuZCcgKTsKPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcTWFpbnRlbmFuY2VNb2RlOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfVXBncmFkZXI7CnVzZSBXUF9GaWxlc3lzdGVtX0Jhc2U7CgovKioKICogQWN0aXZhdGVzLCBkZWFjdGl2YXRlcyBvciBjaGVja3MgdGhlIHN0YXR1cyBvZiB0aGUgbWFpbnRlbmFuY2UgbW9kZSBvZiBhIHNpdGUuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEFjdGl2YXRlIE1haW50ZW5hbmNlIG1vZGUuCiAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgYWN0aXZhdGUKICogICAgIEVuYWJsaW5nIE1haW50ZW5hbmNlIG1vZGUuLi4KICogICAgIFN1Y2Nlc3M6IEFjdGl2YXRlZCBNYWludGVuYW5jZSBtb2RlLgogKgogKiAgICAgIyBEZWFjdGl2YXRlIE1haW50ZW5hbmNlIG1vZGUuCiAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgZGVhY3RpdmF0ZQogKiAgICAgRGlzYWJsaW5nIE1haW50ZW5hbmNlIG1vZGUuLi4KICogICAgIFN1Y2Nlc3M6IERlYWN0aXZhdGVkIE1haW50ZW5hbmNlIG1vZGUuCiAqCiAqICAgICAjIERpc3BsYXkgTWFpbnRlbmFuY2UgbW9kZSBzdGF0dXMuCiAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgc3RhdHVzCiAqICAgICBNYWludGVuYW5jZSBtb2RlIGlzIGFjdGl2ZS4KICoKICogICAgICMgR2V0IE1haW50ZW5hbmNlIG1vZGUgc3RhdHVzIGZvciBzY3JpcHRpbmcgcHVycG9zZS4KICogICAgICQgd3AgbWFpbnRlbmFuY2UtbW9kZSBpcy1hY3RpdmUKICogICAgICQgZWNobyAkPwogKiAgICAgMQogKgogKiBAd2hlbiAgICBhZnRlcl93cF9sb2FkCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgTWFpbnRlbmFuY2VNb2RlQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgoJLyoqCgkgKiBJbnN0YW5jZSBvZiBXUF9VcGdyYWRlci4KCSAqCgkgKiBAdmFyIFdQX1VwZ3JhZGVyCgkgKi8KCXByaXZhdGUgJHVwZ3JhZGVyOwoKCS8qKgoJICogSW5zdGFudGlhdGUgYSBNYWludGVuYW5jZU1vZGVDb21tYW5kIG9iamVjdC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkgewoJCWlmICggISBjbGFzc19leGlzdHMoICdXUF9VcGdyYWRlcicgKSApIHsKCQkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvY2xhc3Mtd3AtdXBncmFkZXIucGhwJzsKCQl9CgkJJHRoaXMtPnVwZ3JhZGVyID0gbmV3IFdQX1VwZ3JhZGVyKCBuZXcgV1BfQ0xJXFVwZ3JhZGVyU2tpbigpICk7CgkJJHRoaXMtPnVwZ3JhZGVyLT5pbml0KCk7Cgl9CgoJLyoqCgkgKiBBY3RpdmF0ZXMgbWFpbnRlbmFuY2UgbW9kZS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogRm9yY2UgbWFpbnRlbmFuY2UgbW9kZSBhY3RpdmF0aW9uIG9wZXJhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgYWN0aXZhdGUKCSAqICAgICBFbmFibGluZyBNYWludGVuYW5jZSBtb2RlLi4uCgkgKiAgICAgU3VjY2VzczogQWN0aXZhdGVkIE1haW50ZW5hbmNlIG1vZGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhY3RpdmF0ZSggJF8sICRhc3NvY19hcmdzICkgewoJCWlmICggJHRoaXMtPmdldF9tYWludGVuYW5jZV9tb2RlX3N0YXR1cygpICYmICEgV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTWFpbnRlbmFuY2UgbW9kZSBhbHJlYWR5IGFjdGl2YXRlZC4nICk7CgkJfQoKCQkkdGhpcy0+dXBncmFkZXItPm1haW50ZW5hbmNlX21vZGUoIHRydWUgKTsKCQlXUF9DTEk6OnN1Y2Nlc3MoICdBY3RpdmF0ZWQgTWFpbnRlbmFuY2UgbW9kZS4nICk7Cgl9CgoJLyoqCgkgKiBEZWFjdGl2YXRlcyBtYWludGVuYW5jZSBtb2RlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWFpbnRlbmFuY2UtbW9kZSBkZWFjdGl2YXRlCgkgKiAgICAgRGlzYWJsaW5nIE1haW50ZW5hbmNlIG1vZGUuLi4KCSAqICAgICBTdWNjZXNzOiBEZWFjdGl2YXRlZCBNYWludGVuYW5jZSBtb2RlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVhY3RpdmF0ZSgpIHsKCQlpZiAoICEgJHRoaXMtPmdldF9tYWludGVuYW5jZV9tb2RlX3N0YXR1cygpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTWFpbnRlbmFuY2UgbW9kZSBhbHJlYWR5IGRlYWN0aXZhdGVkLicgKTsKCQl9CgoJCSR0aGlzLT51cGdyYWRlci0+bWFpbnRlbmFuY2VfbW9kZSggZmFsc2UgKTsKCQlXUF9DTEk6OnN1Y2Nlc3MoICdEZWFjdGl2YXRlZCBNYWludGVuYW5jZSBtb2RlLicgKTsKCX0KCgkvKioKCSAqIERpc3BsYXlzIG1haW50ZW5hbmNlIG1vZGUgc3RhdHVzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbWFpbnRlbmFuY2UtbW9kZSBzdGF0dXMKCSAqICAgICBNYWludGVuYW5jZSBtb2RlIGlzIGFjdGl2ZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHN0YXR1cygpIHsKCQkkc3RhdHVzID0gJHRoaXMtPmdldF9tYWludGVuYW5jZV9tb2RlX3N0YXR1cygpID8gJ2FjdGl2ZScgOiAnbm90IGFjdGl2ZSc7CgkJV1BfQ0xJOjpsaW5lKCAiTWFpbnRlbmFuY2UgbW9kZSBpcyB7JHN0YXR1c30uIiApOwoJfQoKCS8qKgoJICogRGV0ZWN0cyBtYWludGVuYW5jZSBtb2RlIHN0YXR1cy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIG1haW50ZW5hbmNlLW1vZGUgaXMtYWN0aXZlCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWFjdGl2ZQoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfYWN0aXZlKCkgewoJCVdQX0NMSTo6aGFsdCggJHRoaXMtPmdldF9tYWludGVuYW5jZV9tb2RlX3N0YXR1cygpID8gMCA6IDEgKTsKCX0KCgkvKioKCSAqIFJldHVybnMgc3RhdHVzIG9mIG1haW50ZW5hbmNlIG1vZGUuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X21haW50ZW5hbmNlX21vZGVfc3RhdHVzKCkgewoJCSR3cF9maWxlc3lzdGVtID0gJHRoaXMtPmluaXRfd3BfZmlsZXN5c3RlbSgpOwoKCQkkbWFpbnRlbmFuY2VfZmlsZSA9IHRyYWlsaW5nc2xhc2hpdCggJHdwX2ZpbGVzeXN0ZW0tPmFic3BhdGgoKSApIC4gJy5tYWludGVuYW5jZSc7CgoJCXJldHVybiAkd3BfZmlsZXN5c3RlbS0+ZXhpc3RzKCAkbWFpbnRlbmFuY2VfZmlsZSApOwoJfQoKCS8qKgoJICogSW5pdGlhbGl6ZXMgV1BfRmlsZXN5c3RlbS4KCSAqCgkgKiBAcmV0dXJuIFdQX0ZpbGVzeXN0ZW1fQmFzZQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdF93cF9maWxlc3lzdGVtKCkgewoJCWdsb2JhbCAkd3BfZmlsZXN5c3RlbTsKCQlXUF9GaWxlc3lzdGVtKCk7CgoJCXJldHVybiAkd3BfZmlsZXN5c3RlbTsKCX0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2VtYmVkX2F1dG9sb2FkZXIgPSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9lbWJlZF9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2VtYmVkX2F1dG9sb2FkZXI7Cn0KCmlmICggY2xhc3NfZXhpc3RzKCAnV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZScgKSApIHsKCVdQX0NMSTo6YWRkX2NvbW1hbmQoICdlbWJlZCcsICdcV1BfQ0xJXEVtYmVkc1xFbWJlZHNfTmFtZXNwYWNlJyApOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnZW1iZWQgZmV0Y2gnLCAnXFdQX0NMSVxFbWJlZHNcRmV0Y2hfQ29tbWFuZCcgKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdlbWJlZCBwcm92aWRlcicsICdcV1BfQ0xJXEVtYmVkc1xQcm92aWRlcl9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2VtYmVkIGhhbmRsZXInLCAnXFdQX0NMSVxFbWJlZHNcSGFuZGxlcl9Db21tYW5kJyApOwoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2VtYmVkIGNhY2hlJywgJ1xXUF9DTElcRW1iZWRzXENhY2hlX0NvbW1hbmQnICk7Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVtYmVkczsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJX0NvbW1hbmQ7CgovKioKICogUmV0cmlldmVzIG9FbWJlZCBwcm92aWRlcnMuCiAqLwpjbGFzcyBQcm92aWRlcl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoJcHJvdGVjdGVkICRkZWZhdWx0X2ZpZWxkcyA9IGFycmF5KAoJCSdmb3JtYXQnLAoJCSdlbmRwb2ludCcsCgkpOwoKCS8qKgoJICogTGlzdHMgYWxsIGF2YWlsYWJsZSBvRW1iZWQgcHJvdmlkZXJzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBEaXNwbGF5IHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZAoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRhYmxlCgkgKiBvcHRpb25zOgoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogLS0tCgkgKgoJICogWy0tZm9yY2UtcmVnZXhdCgkgKiA6IFR1cm4gdGhlIGFzdGVyaXNrLXR5cGUgcHJvdmlkZXIgVVJMcyBpbnRvIHJlZ2V4ZXMuCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHByb3ZpZGVyOgoJICoKCSAqICogZm9ybWF0CgkgKiAqIGVuZHBvaW50CgkgKgoJICogVGhpcyBmaWVsZCBpcyBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIHJlZ2V4CgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGZvcm1hdCxlbmRwb2ludCBmaWVsZHMgb2YgYXZhaWxhYmxlIHByb3ZpZGVycy4KCSAqICAgICAkIHdwIGVtYmVkIHByb3ZpZGVyIGxpc3QgLS1maWVsZHM9Zm9ybWF0LGVuZHBvaW50CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGZvcm1hdCAgICAgICAgICAgICAgICAgICAgICAgfCBlbmRwb2ludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCAjaHR0cHM/Oi8veW91dHVcLmJlLy4qI2kgICAgIHwgaHR0cHM6Ly93d3cueW91dHViZS5jb20vb2VtYmVkICAgICAgICAgIHwKCSAqICAgICB8ICNodHRwcz86Ly9mbGljXC5rci8uKiNpICAgICAgfCBodHRwczovL3d3dy5mbGlja3IuY29tL3NlcnZpY2VzL29lbWJlZC8gfAoJICogICAgIHwgI2h0dHBzPzovL3dvcmRwcmVzc1wudHYvLiojaSB8IGh0dHBzOi8vd29yZHByZXNzLnR2L29lbWJlZC8gICAgICAgICAgICB8CgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF9wcm92aWRlcnMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJG9lbWJlZCA9IG5ldyBvRW1iZWQoKTsKCgkJJGZvcmNlX3JlZ2V4ID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UtcmVnZXgnICk7CgoJCSRwcm92aWRlcnMgPSBhcnJheSgpOwoKCQlmb3JlYWNoICggKGFycmF5KSAkb2VtYmVkLT5wcm92aWRlcnMgYXMgJG1hdGNobWFzayA9PiAkZGF0YSApIHsKCQkJbGlzdCggJHByb3ZpZGVydXJsLCAkcmVnZXggKSA9ICRkYXRhOwoKCQkJLy8gVHVybiB0aGUgYXN0ZXJpc2stdHlwZSBwcm92aWRlciBVUkxzIGludG8gcmVnZXgKCQkJaWYgKCAkZm9yY2VfcmVnZXggJiYgISAkcmVnZXggKSB7CgkJCQkkbWF0Y2htYXNrID0gJyMnIC4gc3RyX3JlcGxhY2UoICdfX193aWxkY2FyZF9fXycsICcoLispJywgcHJlZ19xdW90ZSggc3RyX3JlcGxhY2UoICcqJywgJ19fX3dpbGRjYXJkX19fJywgJG1hdGNobWFzayApLCAnIycgKSApIC4gJyNpJzsKCQkJCSRtYXRjaG1hc2sgPSBwcmVnX3JlcGxhY2UoICd8XiNodHRwXFxcOi8vfCcsICcjaHR0cHM/XDovLycsICRtYXRjaG1hc2sgKTsKCQkJfQoKCQkJJHByb3ZpZGVyc1tdID0gYXJyYXkoCgkJCQknZm9ybWF0JyAgID0+ICRtYXRjaG1hc2ssCgkJCQknZW5kcG9pbnQnID0+ICRwcm92aWRlcnVybCwKCQkJCSdyZWdleCcgICAgPT4gJHJlZ2V4ID8gJzEnIDogJzAnLAoJCQkpOwoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRwcm92aWRlcnMgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIG1hdGNoaW5nIHByb3ZpZGVyIGZvciBhIGdpdmVuIFVSTC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHVybD4KCSAqIDogVVJMIHRvIHJldHJpZXZlIHByb3ZpZGVyIGZvci4KCSAqCgkgKiBbLS1kaXNjb3Zlcl0KCSAqIDogV2hldGhlciB0byB1c2Ugb0VtYmVkIGRpc2NvdmVyeSBvciBub3QuIERlZmF1bHRzIHRvIHRydWUuCgkgKgoJICogWy0tbGltaXQtcmVzcG9uc2Utc2l6ZT08c2l6ZT5dCgkgKiA6IExpbWl0IHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgSFRNTCB3aGVuIHVzaW5nIGRpc2NvdmVyeS4gRGVmYXVsdCAxNTAgS0IgKHRoZSBzdGFuZGFyZCBXb3JkUHJlc3MgbGltaXQpLiBOb3QgY29tcGF0aWJsZSB3aXRoICduby1kaXNjb3ZlcicuCgkgKgoJICogWy0tbGluay10eXBlPTxqc29ufHhtbD5dCgkgKiA6IFdoZXRoZXIgdG8gYWNjZXB0IG9ubHkgYSBjZXJ0YWluIGxpbmsgdHlwZSB3aGVuIHVzaW5nIGRpc2NvdmVyeS4gRGVmYXVsdHMgdG8gYW55IChqc29uIG9yIHhtbCksIHByZWZlcnJpbmcganNvbi4gTm90IGNvbXBhdGlibGUgd2l0aCAnbm8tZGlzY292ZXInLgoJICogLS0tCgkgKiBvcHRpb25zOgoJICogICAtIGpzb24KCSAqICAgLSB4bWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHRoZSBtYXRjaGluZyBwcm92aWRlciBmb3IgdGhlIFVSTC4KCSAqICAgICAkIHdwIGVtYmVkIHByb3ZpZGVyIG1hdGNoIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EKCSAqICAgICBodHRwczovL3d3dy55b3V0dWJlLmNvbS9vZW1iZWQKCSAqCgkgKiBAc3ViY29tbWFuZCBtYXRjaAoJICovCglwdWJsaWMgZnVuY3Rpb24gbWF0Y2hfcHJvdmlkZXIoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkb2VtYmVkID0gbmV3IG9FbWJlZCgpOwoKCQkkdXJsICAgICAgICAgICAgICAgICA9ICRhcmdzWzBdOwoJCSRkaXNjb3ZlciAgICAgICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNjb3ZlcicsIHRydWUgKTsKCQkkcmVzcG9uc2Vfc2l6ZV9saW1pdCA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGltaXQtcmVzcG9uc2Utc2l6ZScgKTsKCQkkbGlua190eXBlICAgICAgICAgICA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbGluay10eXBlJyApOwoKCQlpZiAoICEgJGRpc2NvdmVyICYmICggbnVsbCAhPT0gJHJlc3BvbnNlX3NpemVfbGltaXQgfHwgbnVsbCAhPT0gJGxpbmtfdHlwZSApICkgewoJCQlpZiAoIG51bGwgIT09ICRyZXNwb25zZV9zaXplX2xpbWl0ICYmIG51bGwgIT09ICRsaW5rX3R5cGUgKSB7CgkJCQkkbXNnID0gIlRoZSAnbGltaXQtcmVzcG9uc2Utc2l6ZScgYW5kICdsaW5rLXR5cGUnIG9wdGlvbnMgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIGRpc2NvdmVyeS4iOwoJCQl9IGVsc2VpZiAoIG51bGwgIT09ICRyZXNwb25zZV9zaXplX2xpbWl0ICkgewoJCQkJJG1zZyA9ICJUaGUgJ2xpbWl0LXJlc3BvbnNlLXNpemUnIG9wdGlvbiBjYW4gb25seSBiZSB1c2VkIHdpdGggZGlzY292ZXJ5LiI7CgkJCX0gZWxzZSB7CgkJCQkkbXNnID0gIlRoZSAnbGluay10eXBlJyBvcHRpb24gY2FuIG9ubHkgYmUgdXNlZCB3aXRoIGRpc2NvdmVyeS4iOwoJCQl9CgkJCVdQX0NMSTo6ZXJyb3IoICRtc2cgKTsKCQl9CgoJCWlmICggJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC4wJywgJzwnICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ2xpbWl0LXJlc3BvbnNlLXNpemUnIG9wdGlvbiBvbmx5IHdvcmtzIGZvciBXb3JkUHJlc3MgNC4wIG9ud2FyZHMuIiApOwoJCQkJLy8gRmFsbCB0aHJvdWdoIGFueXdheS4uLgoJCQl9CgkJCWFkZF9maWx0ZXIoCgkJCQknb2VtYmVkX3JlbW90ZV9nZXRfYXJncycsCgkJCQlmdW5jdGlvbiAoICRhcmdzICkgdXNlICggJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCQkJJGFyZ3NbJ2xpbWl0X3Jlc3BvbnNlX3NpemUnXSA9ICRyZXNwb25zZV9zaXplX2xpbWl0OwoJCQkJCXJldHVybiAkYXJnczsKCQkJCX0KCQkJKTsKCQl9CgoJCWlmICggJGxpbmtfdHlwZSApIHsKCQkJLy8gRmlsdGVyIGRpc2NvdmVyeSByZXNwb25zZS4KCQkJYWRkX2ZpbHRlcigKCQkJCSdvZW1iZWRfbGlua3R5cGVzJywKCQkJCWZ1bmN0aW9uICggJGxpbmt0eXBlcyApIHVzZSAoICRsaW5rX3R5cGUgKSB7CgkJCQkJZm9yZWFjaCAoICRsaW5rdHlwZXMgYXMgJG1pbWVfdHlwZSA9PiAkbGlua3R5cGVfZm9ybWF0ICkgewoJCQkJCQlpZiAoICRsaW5rX3R5cGUgIT09ICRsaW5rdHlwZV9mb3JtYXQgKSB7CgkJCQkJCQl1bnNldCggJGxpbmt0eXBlc1sgJG1pbWVfdHlwZSBdICk7CgkJCQkJCX0KCQkJCQl9CgkJCQkJcmV0dXJuICRsaW5rdHlwZXM7CgkJCQl9CgkJCSk7CgkJfQoKCQkkb2VtYmVkX2FyZ3MgPSBhcnJheSgKCQkJJ2Rpc2NvdmVyJyA9PiAkZGlzY292ZXIsCgkJKTsKCgkJJHByb3ZpZGVyID0gJG9lbWJlZC0+Z2V0X3Byb3ZpZGVyKCAkdXJsLCAkb2VtYmVkX2FyZ3MgKTsKCgkJaWYgKCAhICRwcm92aWRlciApIHsKCQkJaWYgKCAhICRkaXNjb3ZlciApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdObyBvRW1iZWQgcHJvdmlkZXIgZm91bmQgZm9yIGdpdmVuIFVSTC4gTWF5YmUgdHJ5IGRpc2NvdmVyeT8nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnTm8gb0VtYmVkIHByb3ZpZGVyIGZvdW5kIGZvciBnaXZlbiBVUkwuJyApOwoJCQl9CgkJfQoKCQlXUF9DTEk6OmxpbmUoICRwcm92aWRlciApOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICogQHJldHVybiBcV1BfQ0xJXEZvcm1hdHRlcgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmRlZmF1bHRfZmllbGRzICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRW1iZWRzOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElfQ29tbWFuZDsKCi8qKgogKiBSZXRyaWV2ZXMgZW1iZWQgaGFuZGxlcnMuCiAqLwpjbGFzcyBIYW5kbGVyX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7Cglwcm90ZWN0ZWQgJGRlZmF1bHRfZmllbGRzID0gYXJyYXkoCgkJJ2lkJywKCQkncmVnZXgnLAoJKTsKCgkvKioKCSAqIExpc3RzIGFsbCBhdmFpbGFibGUgZW1iZWQgaGFuZGxlcnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IERpc3BsYXkgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggaGFuZGxlcjoKCSAqCgkgKiAqIGlkCgkgKiAqIHJlZ2V4CgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqCgkgKiAqIGNhbGxiYWNrCgkgKiAqIHByaW9yaXR5CgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGlkLHJlZ2V4LHByaW9yaXR5IGZpZWxkcyBvZiBhdmFpbGFibGUgaGFuZGxlcnMuCgkgKiAgICAgJCB3cCBlbWJlZCBoYW5kbGVyIGxpc3QgLS1maWVsZHM9cHJpb3JpdHksaWQKCSAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwoJICogICAgIHwgcHJpb3JpdHkgfCBpZCAgICAgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IDEwICAgICAgIHwgeW91dHViZV9lbWJlZF91cmwgfAoJICogICAgIHwgOTk5OSAgICAgfCBhdWRpbyAgICAgICAgICAgICB8CgkgKiAgICAgfCA5OTk5ICAgICB8IHZpZGVvICAgICAgICAgICAgIHwKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0X2hhbmRsZXJzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLyoqIEB2YXIgXFdQX0VtYmVkICR3cF9lbWJlZCAqLwoJCWdsb2JhbCAkd3BfZW1iZWQ7CgoJCSRhbGxfaGFuZGxlcnMgPSBhcnJheSgpOwoKCQlrc29ydCggJHdwX2VtYmVkLT5oYW5kbGVycyApOwoJCWZvcmVhY2ggKCAkd3BfZW1iZWQtPmhhbmRsZXJzIGFzICRwcmlvcml0eSA9PiAkaGFuZGxlcnMgKSB7CgkJCWZvcmVhY2ggKCAkaGFuZGxlcnMgYXMgJGlkID0+ICRoYW5kbGVyICkgewoJCQkJJGFsbF9oYW5kbGVyc1tdID0gYXJyYXkoCgkJCQkJJ2lkJyAgICAgICA9PiAkaWQsCgkJCQkJJ3JlZ2V4JyAgICA9PiAkaGFuZGxlclsncmVnZXgnXSwKCQkJCQknY2FsbGJhY2snID0+ICRoYW5kbGVyWydjYWxsYmFjayddLAoJCQkJCSdwcmlvcml0eScgPT4gJHByaW9yaXR5LAoJCQkJKTsKCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRhbGxfaGFuZGxlcnMgKTsKCX0KCgkvKioKCSAqIEdldCBGb3JtYXR0ZXIgb2JqZWN0IGJhc2VkIG9uIHN1cHBsaWVkIHBhcmFtZXRlcnMuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFBhcmFtZXRlcnMgcGFzc2VkIHRvIGNvbW1hbmQuIERldGVybWluZXMgZm9ybWF0dGluZy4KCSAqIEByZXR1cm4gXFdQX0NMSVxGb3JtYXR0ZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5kZWZhdWx0X2ZpZWxkcyApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVtYmVkczsKCmlmICggISBjbGFzc19leGlzdHMoICdcV1Bfb0VtYmVkJyApICkgewoJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiBXUElOQyAuICcvY2xhc3Mtb2VtYmVkLnBocCc7Cn0KCi8qKgogKiBQb2x5ZmlsbCBmb3Igb2xkZXIgV1AgdmVyc2lvbnMuCiAqLwpjbGFzcyBvRW1iZWQgZXh0ZW5kcyBcV1Bfb0VtYmVkIHsKCgkvKioKCSAqIFRha2VzIGEgVVJMIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIG9FbWJlZCBwcm92aWRlcidzIFVSTCwgaWYgdGhlcmUgaXMgb25lLgoJICoKCSAqIEBzaW5jZSA0LjAuMAoJICoKCSAqIEBzZWUgV1Bfb0VtYmVkOjpkaXNjb3ZlcigpCgkgKgoJICogQHBhcmFtIHN0cmluZyAgICAgICAgJHVybCAgVGhlIFVSTCB0byB0aGUgY29udGVudC4KCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgICRhcmdzIE9wdGlvbmFsIHByb3ZpZGVyIGFyZ3VtZW50cy4KCSAqIEByZXR1cm4gZmFsc2V8c3RyaW5nIEZhbHNlIG9uIGZhaWx1cmUsIG90aGVyd2lzZSB0aGUgb0VtYmVkIHByb3ZpZGVyIFVSTC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldF9wcm92aWRlciggJHVybCwgJGFyZ3MgPSAnJyApIHsKCQlpZiAoIG1ldGhvZF9leGlzdHMoICdXUF9vRW1iZWQnLCAnZ2V0X3Byb3ZpZGVyJyApICkgewoJCQlyZXR1cm4gcGFyZW50OjpnZXRfcHJvdmlkZXIoICR1cmwsICRhcmdzICk7CgkJfQoKCQkkYXJncyA9IHdwX3BhcnNlX2FyZ3MoICRhcmdzICk7CgoJCSRwcm92aWRlciA9IGZhbHNlOwoKCQlpZiAoICEgaXNzZXQoICRhcmdzWydkaXNjb3ZlciddICkgKSB7CgkJCSRhcmdzWydkaXNjb3ZlciddID0gdHJ1ZTsKCQl9CgoJCWZvcmVhY2ggKCAkdGhpcy0+cHJvdmlkZXJzIGFzICRtYXRjaG1hc2sgPT4gJGRhdGEgKSB7CgkJCWxpc3QoICRwcm92aWRlcnVybCwgJHJlZ2V4ICkgPSAkZGF0YTsKCgkJCS8vIFR1cm4gdGhlIGFzdGVyaXNrLXR5cGUgcHJvdmlkZXIgVVJMcyBpbnRvIHJlZ2V4CgkJCWlmICggISAkcmVnZXggKSB7CgkJCQkkbWF0Y2htYXNrID0gJyMnIC4gc3RyX3JlcGxhY2UoICdfX193aWxkY2FyZF9fXycsICcoLispJywgcHJlZ19xdW90ZSggc3RyX3JlcGxhY2UoICcqJywgJ19fX3dpbGRjYXJkX19fJywgJG1hdGNobWFzayApLCAnIycgKSApIC4gJyNpJzsKCQkJCSRtYXRjaG1hc2sgPSBwcmVnX3JlcGxhY2UoICd8XiNodHRwXFxcOi8vfCcsICcjaHR0cHM/XDovLycsICRtYXRjaG1hc2sgKTsKCQkJfQoKCQkJaWYgKCBwcmVnX21hdGNoKCAkbWF0Y2htYXNrLCAkdXJsICkgKSB7CgkJCQkkcHJvdmlkZXIgPSBzdHJfcmVwbGFjZSggJ3tmb3JtYXR9JywgJ2pzb24nLCAkcHJvdmlkZXJ1cmwgKTsgLy8gSlNPTiBpcyBlYXNpZXIgdG8gZGVhbCB3aXRoIHRoYW4gWE1MCgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCAhICRwcm92aWRlciAmJiAkYXJnc1snZGlzY292ZXInXSApIHsKCQkJJHByb3ZpZGVyID0gJHRoaXMtPmRpc2NvdmVyKCAkdXJsICk7CgkJfQoKCQlyZXR1cm4gJHByb3ZpZGVyOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVtYmVkczsKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIEluc3BlY3RzIG9FbWJlZCBwcm92aWRlcnMsIGNsZWFycyBlbWJlZCBjYWNoZSwgYW5kIG1vcmUuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgRW1iZWRzX05hbWVzcGFjZSBleHRlbmRzIENvbW1hbmROYW1lc3BhY2Ugewp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVtYmVkczsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElfQ29tbWFuZDsKCmNsYXNzIEZldGNoX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgkvKioKCSAqIEF0dGVtcHRzIHRvIGNvbnZlcnQgYSBVUkwgaW50byBlbWJlZCBIVE1MLgoJICoKCSAqIEluIG5vbi1yYXcgbW9kZSwgc3RhcnRzIGJ5IGNoZWNraW5nIHRoZSBVUkwgYWdhaW5zdCB0aGUgcmVnZXggb2YgdGhlIHJlZ2lzdGVyZWQgZW1iZWQgaGFuZGxlcnMuCgkgKiBJZiBub25lIG9mIHRoZSByZWdleCBtYXRjaGVzIGFuZCBpdCdzIGVuYWJsZWQsIHRoZW4gdGhlIFVSTCB3aWxsIGJlIGdpdmVuIHRvIHRoZSBXUF9vRW1iZWQgY2xhc3MuCgkgKgoJICogSW4gcmF3IG1vZGUsIGNoZWNrcyB0aGUgcHJvdmlkZXJzIGRpcmVjdGx5IGFuZCByZXR1cm5zIHRoZSBkYXRhLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXJsPgoJICogOiBVUkwgdG8gcmV0cmlldmUgb0VtYmVkIGRhdGEgZm9yLgoJICoKCSAqIFstLXdpZHRoPTx3aWR0aD5dCgkgKiA6IFdpZHRoIG9mIHRoZSBlbWJlZCBpbiBwaXhlbHMuCgkgKgoJICogWy0taGVpZ2h0PTxoZWlnaHQ+XQoJICogOiBIZWlnaHQgb2YgdGhlIGVtYmVkIGluIHBpeGVscy4KCSAqCgkgKiBbLS1wb3N0LWlkPTxpZD5dCgkgKiA6IENhY2hlIG9FbWJlZCByZXNwb25zZSBmb3IgYSBnaXZlbiBwb3N0LgoJICoKCSAqIFstLWRpc2NvdmVyXQoJICogOiBFbmFibGUgb0VtYmVkIGRpc2NvdmVyeS4gRGVmYXVsdHMgdG8gdHJ1ZS4KCSAqCgkgKiBbLS1za2lwLWNhY2hlXQoJICogOiBJZ25vcmUgYWxyZWFkeSBjYWNoZWQgb0VtYmVkIHJlc3BvbnNlcy4gSGFzIG5vIGVmZmVjdCBpZiB1c2luZyB0aGUgJ3Jhdycgb3B0aW9uLCB3aGljaCBkb2Vzbid0IHVzZSB0aGUgY2FjaGUuCgkgKgoJICogWy0tc2tpcC1zYW5pdGl6YXRpb25dCgkgKiA6IFJlbW92ZSB0aGUgZmlsdGVyIHRoYXQgV29yZFByZXNzIGZyb20gNC40IG9ud2FyZHMgdXNlcyB0byBzYW5pdGl6ZSBvRW1iZWQgcmVzcG9uc2VzLiBIYXMgbm8gZWZmZWN0IGlmIHVzaW5nIHRoZSAncmF3JyBvcHRpb24sIHdoaWNoIGJ5LXBhc3NlcyBzYW5pdGl6YXRpb24uCgkgKgoJICogWy0tZG8tc2hvcnRjb2RlXQoJICogOiBJZiB0aGUgVVJMIGlzIGhhbmRsZWQgYnkgYSByZWdpc3RlcmVkIGVtYmVkIGhhbmRsZXIgYW5kIHJldHVybnMgYSBzaG9ydGNvZGUsIGRvIHNob3J0Y29kZSBhbmQgcmV0dXJuIHJlc3VsdC4gSGFzIG5vIGVmZmVjdCBpZiB1c2luZyB0aGUgJ3Jhdycgb3B0aW9uLCB3aGljaCBieS1wYXNzZXMgaGFuZGxlcnMuCgkgKgoJICogWy0tbGltaXQtcmVzcG9uc2Utc2l6ZT08c2l6ZT5dCgkgKiA6IExpbWl0IHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgSFRNTCB3aGVuIHVzaW5nIGRpc2NvdmVyeS4gRGVmYXVsdCAxNTAgS0IgKHRoZSBzdGFuZGFyZCBXb3JkUHJlc3MgbGltaXQpLiBOb3QgY29tcGF0aWJsZSB3aXRoICduby1kaXNjb3ZlcicuCgkgKgoJICogWy0tcmF3XQoJICogOiBSZXR1cm4gdGhlIHJhdyBvRW1iZWQgcmVzcG9uc2UgaW5zdGVhZCBvZiB0aGUgcmVzdWx0aW5nIEhUTUwuIElnbm9yZXMgdGhlIGNhY2hlIGFuZCBkb2VzIG5vdCBzYW5pdGl6ZSByZXNwb25zZXMgb3IgdXNlIHJlZ2lzdGVyZWQgZW1iZWQgaGFuZGxlcnMuCgkgKgoJICogWy0tcmF3LWZvcm1hdD08anNvbnx4bWw+XQoJICogOiBSZW5kZXIgcmF3IG9FbWJlZCBkYXRhIGluIGEgcGFydGljdWxhciBmb3JtYXQuIERlZmF1bHRzIHRvIGpzb24uIENhbiBvbmx5IGJlIHNwZWNpZmllZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSAncmF3JyBvcHRpb24uCgkgKiAtLS0KCSAqIG9wdGlvbnM6CgkgKiAgIC0ganNvbgoJICogICAtIHhtbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgZW1iZWQgSFRNTCBmb3IgYSBnaXZlbiBVUkwuCgkgKiAgICAgJCB3cCBlbWJlZCBmZXRjaCBodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PWRRdzR3OVdnWGNRCgkgKiAgICAgPGlmcmFtZSB3aWR0aD0iNTI1IiBoZWlnaHQ9IjI5NSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9kUXc0dzlXZ1hjUT9mZWF0dXJlPW9lbWJlZCIgLi4uCgkgKgoJICogICAgICMgR2V0IHJhdyBvRW1iZWQgZGF0YSBmb3IgYSBnaXZlbiBVUkwuCgkgKiAgICAgJCB3cCBlbWJlZCBmZXRjaCBodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PWRRdzR3OVdnWGNRIC0tcmF3CgkgKiAgICAgeyJhdXRob3JfdXJsIjoiaHR0cHM6XC9cL3d3dy55b3V0dWJlLmNvbVwvdXNlclwvUmlja0FzdGxleVZFVk8iLCJ3aWR0aCI6NTI1LCJ2ZXJzaW9uIjoiMS4wIiwgLi4uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCS8qKiBAdmFyIFxXUF9FbWJlZCAkd3BfZW1iZWQgKi8KCQlnbG9iYWwgJHdwX2VtYmVkOwoKCQkkdXJsICAgICAgICAgICAgICAgICA9ICRhcmdzWzBdOwoJCSRyYXcgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmF3JyApOwoJCSRyYXdfZm9ybWF0ICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmF3LWZvcm1hdCcgKTsKCQkkcG9zdF9pZCAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3Bvc3QtaWQnICk7CgkJJGRpc2NvdmVyICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkaXNjb3ZlcicgKTsKCQkkcmVzcG9uc2Vfc2l6ZV9saW1pdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2xpbWl0LXJlc3BvbnNlLXNpemUnICk7CgkJJHdpZHRoICAgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd3aWR0aCcgKTsKCQkkaGVpZ2h0ICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2hlaWdodCcgKTsKCgkJLy8gVGhlIGAka2V5X3N1ZmZpeGAgdXNlZCBmb3IgY2FjaGluZyBpcyBwYXJ0IGJhc2VkIG9uIHNlcmlhbGl6aW5nIHRoZSBhdHRyaWJ1dGVzIGFycmF5IHdpdGhvdXQgbm9ybWFsaXppbmcgaXQgZmlyc3Qgc28gbmVlZCB0byB0cnkgdG8gcmVwbGljYXRlIHRoYXQuCgkJJG9lbWJlZF9hcmdzID0gYXJyYXkoKTsKCgkJaWYgKCBudWxsICE9PSAkd2lkdGggKSB7CgkJCSRvZW1iZWRfYXJnc1snd2lkdGgnXSA9ICR3aWR0aDsgLy8gS2VlcCBhcyBzdHJpbmcgYXMgaWYgZnJvbSBhIHNob3J0Y29kZSBhdHRyaWJ1dGUuCgkJfQoJCWlmICggbnVsbCAhPT0gJGhlaWdodCApIHsKCQkJJG9lbWJlZF9hcmdzWydoZWlnaHQnXSA9ICRoZWlnaHQ7IC8vIEtlZXAgYXMgc3RyaW5nIGFzIGlmIGZyb20gYSBzaG9ydGNvZGUgYXR0cmlidXRlLgoJCX0KCQlpZiAoIG51bGwgIT09ICRkaXNjb3ZlciApIHsKCQkJJG9lbWJlZF9hcmdzWydkaXNjb3ZlciddID0gJGRpc2NvdmVyID8gJzEnIDogJzAnOyAvLyBNYWtlIGl0IGEgc3RyaW5nIGFzIGlmIGZyb20gYSBzaG9ydGNvZGUgYXR0cmlidXRlLgoJCX0KCgkJJGRpc2NvdmVyID0gbnVsbCA9PT0gJGRpc2NvdmVyID8gdHJ1ZSA6IChib29sKSAkZGlzY292ZXI7IC8vIFdpbGwgdXNlIHRvIHNldCBgJG9lbWJlZF9hcmdzWydkaXNjb3ZlciddYCB3aGVuIG5vdCBjYWxsaW5nIGBXUF9FbWJlZDo6c2hvcnRjb2RlKClgLgoKCQlpZiAoICEgJGRpc2NvdmVyICYmIG51bGwgIT09ICRyZXNwb25zZV9zaXplX2xpbWl0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICdsaW1pdC1yZXNwb25zZS1zaXplJyBvcHRpb24gY2FuIG9ubHkgYmUgdXNlZCB3aXRoIGRpc2NvdmVyeS4iICk7CgkJfQoKCQlpZiAoICEgJHJhdyAmJiBudWxsICE9PSAkcmF3X2Zvcm1hdCApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRoZSAncmF3LWZvcm1hdCcgb3B0aW9uIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCB0aGUgJ3Jhdycgb3B0aW9uLiIgKTsKCQl9CgoJCWlmICggJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAnNC4wJywgJzwnICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ2xpbWl0LXJlc3BvbnNlLXNpemUnIG9wdGlvbiBvbmx5IHdvcmtzIGZvciBXb3JkUHJlc3MgNC4wIG9ud2FyZHMuIiApOwoJCQkJLy8gRmFsbCB0aHJvdWdoIGFueXdheS4uLgoJCQl9CgkJCWFkZF9maWx0ZXIoCgkJCQknb2VtYmVkX3JlbW90ZV9nZXRfYXJncycsCgkJCQlmdW5jdGlvbiAoICRhcmdzICkgdXNlICggJHJlc3BvbnNlX3NpemVfbGltaXQgKSB7CgkJCQkJJGFyZ3NbJ2xpbWl0X3Jlc3BvbnNlX3NpemUnXSA9ICRyZXNwb25zZV9zaXplX2xpbWl0OwoKCQkJCQlyZXR1cm4gJGFyZ3M7CgkJCQl9LAoJCQkJUEhQX0lOVF9NQVgKCQkJKTsKCQl9CgoJCS8vIElmIHJhdywgcXVlcnkgcHJvdmlkZXJzIGRpcmVjdGx5LCBieS1wYXNzaW5nIGNhY2hlLgoJCWlmICggJHJhdyApIHsKCQkJJG9lbWJlZCA9IG5ldyBvRW1iZWQoKTsgLy8gTmVlZHMgdG8gYmUgaGVyZSB0byBtYWtlIHN1cmUgYF93cF9vZW1iZWRfZ2V0X29iamVjdCgpYCBkZWZpbmVkIChpbiAid3AtaW5jbHVkZXMvY2xhc3Mtb2VtYmVkLnBocCIgZm9yIFdQIDwgNC43KS4KCgkJCSRvZW1iZWRfYXJnc1snZGlzY292ZXInXSA9ICRkaXNjb3ZlcjsKCgkJCS8vIE1ha2UgJ29lbWJlZF9kYXRhcGFyc2UnIGZpbHRlciBhIG5vLW9wIHNvIGdldCByYXcgdW5zYW5pdGl6ZWQgZGF0YS4KCQkJcmVtb3ZlX2FsbF9maWx0ZXJzKCAnb2VtYmVkX2RhdGFwYXJzZScgKTsgLy8gU2F2ZSBhIGZldyBjeWNsZXMuCgkJCWFkZF9maWx0ZXIoCgkJCQknb2VtYmVkX2RhdGFwYXJzZScsCgkJCQlmdW5jdGlvbiAoICRyZXR1cm4sICRkYXRhLCAkdXJsICkgewoJCQkJCXJldHVybiAkZGF0YTsKCQkJCX0sCgkJCQlQSFBfSU5UX01BWCwKCQkJCTMKCQkJKTsKCgkJCS8vIEFsbG93IGB3cF9maWx0ZXJfcHJlX29lbWJlZF9yZXN1bHQoKWAgdG8gcHJvdmlkZSBsb2NhbCBVUkxzIChXUCA+PSA0LjUuMykuCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gVXNpbmcgV1AgQ29yZSBob29rLgoJCQkkZGF0YSA9IGFwcGx5X2ZpbHRlcnMoICdwcmVfb2VtYmVkX3Jlc3VsdCcsIG51bGwsICR1cmwsICRvZW1iZWRfYXJncyApOwoKCQkJaWYgKCBudWxsID09PSAkZGF0YSApIHsKCQkJCSRwcm92aWRlciA9ICRvZW1iZWQtPmdldF9wcm92aWRlciggJHVybCwgJG9lbWJlZF9hcmdzICk7CgoJCQkJaWYgKCAhICRwcm92aWRlciApIHsKCQkJCQlpZiAoICEgJGRpc2NvdmVyICkgewoJCQkJCQlXUF9DTEk6OmVycm9yKCAnTm8gb0VtYmVkIHByb3ZpZGVyIGZvdW5kIGZvciBnaXZlbiBVUkwuIE1heWJlIHRyeSBkaXNjb3Zlcnk/JyApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICdObyBvRW1iZWQgcHJvdmlkZXIgZm91bmQgZm9yIGdpdmVuIFVSTC4nICk7CgkJCQkJfQoJCQkJfQoKCQkJCSRkYXRhID0gJG9lbWJlZC0+ZmV0Y2goICRwcm92aWRlciwgJHVybCwgJG9lbWJlZF9hcmdzICk7CgkJCX0KCgkJCWlmICggZmFsc2UgPT09ICRkYXRhICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RoZXJlIHdhcyBhbiBlcnJvciBmZXRjaGluZyB0aGUgb0VtYmVkIGRhdGEuJyApOwoJCQl9CgoJCQlpZiAoICd4bWwnID09PSAkcmF3X2Zvcm1hdCApIHsKCQkJCWlmICggISBjbGFzc19leGlzdHMoICdTaW1wbGVYTUxFbGVtZW50JyApICkgewoJCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgUEhQIGV4dGVuc2lvbiAnU2ltcGxlWE1MRWxlbWVudCcgaXMgbm90IGF2YWlsYWJsZSBidXQgaXMgcmVxdWlyZWQgZm9yIFhNTC1mb3JtYXR0ZWQgb3V0cHV0LiIgKTsKCQkJCX0KCQkJCVdQX0NMSTo6bG9nKCAkdGhpcy0+b2VtYmVkX2NyZWF0ZV94bWwoIChhcnJheSkgJGRhdGEgKSApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpsb2coIGpzb25fZW5jb2RlKCAkZGF0YSApICk7CgkJCX0KCgkJCXJldHVybjsKCQl9CgoJCWlmICggJHBvc3RfaWQgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSB0aGUgcmVxdWVzdCBpcyBhc2tpbmcgZm9yIGEgcG9zdCBpZCBkaXJlY3RseSBzbyBuZWVkIHRvIG92ZXJyaWRlIHRoZSBnbG9iYWwuCgkJCSRHTE9CQUxTWydwb3N0J10gPSBnZXRfcG9zdCggJHBvc3RfaWQgKTsKCQkJaWYgKCBudWxsID09PSAkR0xPQkFMU1sncG9zdCddICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiUG9zdCBpZCAnJXMnIG5vdCBmb3VuZC4iLCAkcG9zdF9pZCApICk7CgkJCX0KCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1zYW5pdGl6YXRpb24nICkgKSB7CgkJCXJlbW92ZV9maWx0ZXIoICdvZW1iZWRfZGF0YXBhcnNlJywgJ3dwX2ZpbHRlcl9vZW1iZWRfcmVzdWx0JywgMTAsIDMgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jYWNoZScgKSApIHsKCQkJJHdwX2VtYmVkLT51c2VjYWNoZSA9IGZhbHNlOwoJCQkvLyBJbiBvcmRlciB0byBza2lwIGNhY2hpbmcsIGFsc28gbmVlZCBgJGNhY2hlZF9yZWNlbnRseWAgdG8gYmUgZmFsc2UgaW4gYFdQX0VtYmVkOjpzaG9ydGNvZGUoKWAsIHNvIHNldCBUVEwgdG8gemVyby4KCQkJYWRkX2ZpbHRlciggJ29lbWJlZF90dGwnLCAnX19yZXR1cm5femVybycsIFBIUF9JTlRfTUFYICk7CgkJfSBlbHNlIHsKCQkJJHdwX2VtYmVkLT51c2VjYWNoZSA9IHRydWU7CgkJfQoKCQkvLyBgV1BfRW1iZWQ6OnNob3J0Y29kZSgpYCBzZXRzIHRoZSAnZGlzY292ZXInIGF0dHJpYnV0ZSBiYXNlZCBvbiAnZW1iZWRfb2VtYmVkX2Rpc2NvdmVyJyBmaWx0ZXIsIG5vIG1hdHRlciB3aGF0J3MgcGFzc2VkIHRvIGl0LgoJCWFkZF9maWx0ZXIoICdlbWJlZF9vZW1iZWRfZGlzY292ZXInLCAkZGlzY292ZXIgPyAnX19yZXR1cm5fdHJ1ZScgOiAnX19yZXR1cm5fZmFsc2UnLCBQSFBfSU5UX01BWCApOwoKCQkvLyBGb3IgV1AgPCA0LjksIGBXUF9FbWJlZDo6c2hvcnRjb2RlKClgIHdvbid0IGNoZWNrIHByb3ZpZGVycyBpZiBubyBwb3N0X2lkIHN1cHBsaWVkLCBzbyBzZXQgYG1heWJlX21ha2VfbGluaygpYCB0byByZXR1cm4gZmFsc2Ugc28gY2FuIGNoZWNrIGFuZCBkbyBpdCBvdXJzZWx2ZXMuCgkJLy8gQWxzbyBzZXQgaWYgV1AgPCA0LjQgYW5kIGRvbid0IGhhdmUgJ3VuZmlsdGVyZWRfaHRtbCcgcHJpdmlsZWdlcyBvbiBwb3N0LgoJCSRjaGVja19wcm92aWRlcnMgPSBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjknLCAnPCcgKSAmJiAoICEgJHBvc3RfaWQgfHwgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICc0LjQnLCAnPCcgKSAmJiAhIGF1dGhvcl9jYW4oICRwb3N0X2lkLCAndW5maWx0ZXJlZF9odG1sJyApICkgKTsKCQlpZiAoICRjaGVja19wcm92aWRlcnMgKSB7CgkJCWFkZF9maWx0ZXIoICdlbWJlZF9tYXliZV9tYWtlX2xpbmsnLCAnX19yZXR1cm5fZmFsc2UnLCBQSFBfSU5UX01BWCApOwoJCX0KCgkJJGh0bWwgPSAkd3BfZW1iZWQtPnNob3J0Y29kZSggJG9lbWJlZF9hcmdzLCAkdXJsICk7CgoJCWlmICggZmFsc2UgPT09ICRodG1sICYmICRjaGVja19wcm92aWRlcnMgKSB7CgoJCQkvLyBDaGVjayBwcm92aWRlcnMuCgkJCSRvZW1iZWRfYXJnc1snZGlzY292ZXInXSA9ICRkaXNjb3ZlcjsKCQkJJGh0bWwgICAgICAgICAgICAgICAgICAgID0gd3Bfb2VtYmVkX2dldCggJHVybCwgJG9lbWJlZF9hcmdzICk7CgoJCQkvLyBgd3Bfb2VtYmVkX2dldCgpYCByZXR1cm5zIHplcm8tbGVuZ3RoIHN0cmluZyBpbnN0ZWFkIG9mIGZhbHNlIG9uIGZhaWx1cmUgZHVlIHRvIGBfc3RyaXBfbmV3bGluZXMoKWAgJ29lbWJlZF9kYXRhcGFyc2UnIGZpbHRlciBzbyBtYWtlIHN1cmUgZmFsc2UuCgkJCWlmICggJycgPT09ICRodG1sICkgewoJCQkJJGh0bWwgPSBmYWxzZTsKCQkJfQoJCX0KCgkJaWYgKCBmYWxzZSAhPT0gJGh0bWwgJiYgJ1snID09PSBzdWJzdHIoICRodG1sLCAwLCAxICkgJiYgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZG8tc2hvcnRjb2RlJyApICkgewoJCQkkaHRtbCA9IGRvX3Nob3J0Y29kZSggJGh0bWwsIHRydWUgKTsKCQl9CgoJCWlmICggZmFsc2UgPT09ICRodG1sICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlcmUgd2FzIGFuIGVycm9yIGZldGNoaW5nIHRoZSBvRW1iZWQgZGF0YS4nICk7CgkJfQoKCQlXUF9DTEk6OmxvZyggJGh0bWwgKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgYW4gWE1MIHN0cmluZyBmcm9tIGEgZ2l2ZW4gYXJyYXkuCgkgKgoJICogU2FtZSBhcyBgXF9vZW1iZWRfY3JlYXRlX3htbCgpYCBpbiAid3AtaW5jbHVkZXNcZW1iZWQucGhwIiBpbnRyb2R1Y2VkIGluIFdQIDQuNC4wLiBQb2x5ZmlsbGVkIGFzIG1hcmtlZCBwcml2YXRlIChhbmQgYWxzbyB0byBjYXRlciBmb3Igb2xkZXIgV1AgdmVyc2lvbnMpLgoJICoKCSAqIEBzZWUgX29lbWJlZF9jcmVhdGVfeG1sKCkKCSAqCgkgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAkZGF0YSBUaGUgb3JpZ2luYWwgb0VtYmVkIHJlc3BvbnNlIGRhdGEuCgkgKiBAcGFyYW0gXFNpbXBsZVhNTEVsZW1lbnQgJG5vZGUgT3B0aW9uYWwuIFhNTCBub2RlIHRvIGFwcGVuZCB0aGUgcmVzdWx0IHRvIHJlY3Vyc2l2ZWx5LgoJICogQHJldHVybiBzdHJpbmd8ZmFsc2UgWE1MIHN0cmluZyBvbiBzdWNjZXNzLCBmYWxzZSBvbiBlcnJvci4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIG9lbWJlZF9jcmVhdGVfeG1sKCAkZGF0YSwgJG5vZGUgPSBudWxsICkgewoJCWlmICggISBpc19hcnJheSggJGRhdGEgKSB8fCBlbXB0eSggJGRhdGEgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCBudWxsID09PSAkbm9kZSApIHsKCQkJJG5vZGUgPSBuZXcgXFNpbXBsZVhNTEVsZW1lbnQoICc8b2VtYmVkPjwvb2VtYmVkPicgKTsKCQl9CgoJCWZvcmVhY2ggKCAkZGF0YSBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJaWYgKCBpc19udW1lcmljKCAka2V5ICkgKSB7CgkJCQkka2V5ID0gJ29lbWJlZCc7CgkJCX0KCgkJCWlmICggaXNfYXJyYXkoICR2YWx1ZSApICkgewoJCQkJJGl0ZW0gPSAkbm9kZS0+YWRkQ2hpbGQoICRrZXkgKTsKCQkJCSR0aGlzLT5vZW1iZWRfY3JlYXRlX3htbCggJHZhbHVlLCAkaXRlbSApOwoJCQl9IGVsc2UgewoJCQkJJG5vZGUtPmFkZENoaWxkKCAka2V5LCBlc2NfaHRtbCggJHZhbHVlICkgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRub2RlLT5hc1hNTCgpOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEVtYmVkczsKCnVzZSBXUF9DTEk7CnVzZSBXUF9DTElcUHJvY2VzczsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElfQ29tbWFuZDsKCi8qKgogKiBGaW5kcywgdHJpZ2dlcnMsIGFuZCBkZWxldGVzIG9FbWJlZCBjYWNoZXMuCiAqLwpjbGFzcyBDYWNoZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogRGVsZXRlcyBhbGwgb0VtYmVkIGNhY2hlcyBmb3IgYSBnaXZlbiBwb3N0LgoJICoKCSAqIG9FbWJlZCBjYWNoZXMgZm9yIGEgcG9zdCBhcmUgc3RvcmVkIGluIHRoZSBwb3N0J3MgbWV0YWRhdGEuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwb3N0X2lkPgoJICogOiBJRCBvZiB0aGUgcG9zdCB0byBjbGVhciB0aGUgY2FjaGUgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2xlYXIgY2FjaGUgZm9yIGEgcG9zdAoJICogICAgICQgd3AgZW1iZWQgY2FjaGUgY2xlYXIgMTIzCgkgKiAgICAgU3VjY2VzczogQ2xlYXJlZCBvRW1iZWQgY2FjaGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbGVhciggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCS8qKiBAdmFyIFxXUF9FbWJlZCAkd3BfZW1iZWQgKi8KCQlnbG9iYWwgJHdwX2VtYmVkOwoKCQkkcG9zdF9pZCA9ICRhcmdzWzBdOwoKCQkkcG9zdF9tZXRhcyA9IGdldF9wb3N0X2N1c3RvbV9rZXlzKCAkcG9zdF9pZCApOwoKCQlpZiAoICRwb3N0X21ldGFzICkgewoJCQkkcG9zdF9tZXRhcyA9IGFycmF5X2ZpbHRlcigKCQkJCSRwb3N0X21ldGFzLAoJCQkJZnVuY3Rpb24gKCAkdiApIHsKCQkJCQlyZXR1cm4gJ19vZW1iZWRfJyA9PT0gc3Vic3RyKCAkdiwgMCwgOCApOwoJCQkJfQoJCQkpOwoJCX0KCgkJaWYgKCBlbXB0eSggJHBvc3RfbWV0YXMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vIGNhY2hlIHRvIGNsZWFyIScgKTsKCQl9CgoJCSR3cF9lbWJlZC0+ZGVsZXRlX29lbWJlZF9jYWNoZXMoICRwb3N0X2lkICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0NsZWFyZWQgb0VtYmVkIGNhY2hlLicgKTsKCX0KCgkvKioKCSAqIEZpbmRzIGFuIG9FbWJlZCBjYWNoZSBwb3N0IElEIGZvciBhIGdpdmVuIFVSTC4KCSAqCgkgKiBTdGFydGluZyB3aXRoIFdvcmRQcmVzcyA0LjksIGVtYmVkcyB0aGF0IGFyZW4ndCBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpYyBwb3N0IHdpbGwgYmUgY2FjaGVkIGluCgkgKiBhIG5ldyBvZW1iZWRfY2FjaGUgcG9zdCB0eXBlLiBUaGVyZSBjYW4gYmUgbW9yZSB0aGFuIG9uZSBzdWNoIGVudHJ5IGZvciBhIHVybCBkZXBlbmRpbmcgb24gYXR0cmlidXRlcyBhbmQgY29udGV4dC4KCSAqCgkgKiBOb3QgdG8gYmUgY29uZnVzZWQgd2l0aCBvRW1iZWQgY2FjaGVzIGZvciBhIGdpdmVuIHBvc3Qgd2hpY2ggYXJlIHN0b3JlZCBpbiB0aGUgcG9zdCdzIG1ldGFkYXRhLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXJsPgoJICogOiBVUkwgdG8gcmV0cmlldmUgb0VtYmVkIGRhdGEgZm9yLgoJICoKCSAqIFstLXdpZHRoPTx3aWR0aD5dCgkgKiA6IFdpZHRoIG9mIHRoZSBlbWJlZCBpbiBwaXhlbHMuIFBhcnQgb2YgY2FjaGUga2V5IHNvIG11c3QgbWF0Y2guIERlZmF1bHRzIHRvIGBjb250ZW50X3dpZHRoYCBpZiBzZXQgZWxzZSA1MDBweCwgc28gaXMgdGhlbWUgYW5kIGNvbnRleHQgZGVwZW5kZW50LgoJICoKCSAqIFstLWhlaWdodD08aGVpZ2h0Pl0KCSAqIDogSGVpZ2h0IG9mIHRoZSBlbWJlZCBpbiBwaXhlbHMuIFBhcnQgb2YgY2FjaGUga2V5IHNvIG11c3QgbWF0Y2guIERlZmF1bHRzIHRvIDEuNSAqIGRlZmF1bHQgd2lkdGggKGBjb250ZW50X3dpZHRoYCBvciA1MDBweCksIHRvIGEgbWF4aW11bSBvZiAxMDAwcHguCgkgKgoJICogWy0tZGlzY292ZXJdCgkgKiA6IFdoZXRoZXIgdG8gc2VhcmNoIHdpdGggdGhlIGRpc2NvdmVyIGF0dHJpYnV0ZSBzZXQgb3Igbm90LiBQYXJ0IG9mIGNhY2hlIGtleSBzbyBtdXN0IG1hdGNoLiBJZiBub3QgZ2l2ZW4sIHdpbGwgc2VhcmNoIHdpdGggYXR0cmlidXRlOiB1bnNldCwgJzEnLCAnMCcsIHJldHVybmluZyBmaXJzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEZpbmQgY2FjaGUgcG9zdCBJRCBmb3IgYSBnaXZlbiBVUkwuCgkgKiAgICAgJCB3cCBlbWJlZCBjYWNoZSBmaW5kIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EgLS13aWR0aD01MDAKCSAqICAgICAxMjMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbmQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuOScsICc8JyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUmVxdWlyZXMgV29yZFByZXNzIDQuOSBvciBncmVhdGVyLicgKTsKCQl9CgoJCS8qKiBAdmFyIFxXUF9FbWJlZCAkd3BfZW1iZWQgKi8KCQlnbG9iYWwgJHdwX2VtYmVkOwoKCQkkdXJsICAgICAgPSAkYXJnc1swXTsKCQkkd2lkdGggICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd3aWR0aCcgKTsKCQkkaGVpZ2h0ICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoZWlnaHQnICk7CgkJJGRpc2NvdmVyID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGlzY292ZXInICk7CgoJCS8vIFRoZSBgJGtleV9zdWZmaXhgIHVzZWQgZm9yIGNhY2hpbmcgaXMgcGFydCBiYXNlZCBvbiBzZXJpYWxpemluZyB0aGUgYXR0cmlidXRlcyBhcnJheSB3aXRob3V0IG5vcm1hbGl6aW5nIGl0IGZpcnN0IHNvIG5lZWQgdG8gdHJ5IHRvIHJlcGxpY2F0ZSB0aGF0LgoJCSRvZW1iZWRfYXJncyA9IGFycmF5KCk7CgoJCWlmICggbnVsbCAhPT0gJHdpZHRoICkgewoJCQkkb2VtYmVkX2FyZ3NbJ3dpZHRoJ10gPSAkd2lkdGg7IC8vIEtlZXAgYXMgc3RyaW5nIGFzIGlmIGZyb20gYSBzaG9ydGNvZGUgYXR0cmlidXRlLgoJCX0KCQlpZiAoIG51bGwgIT09ICRoZWlnaHQgKSB7CgkJCSRvZW1iZWRfYXJnc1snaGVpZ2h0J10gPSAkaGVpZ2h0OyAvLyBLZWVwIGFzIHN0cmluZyBhcyBpZiBmcm9tIGEgc2hvcnRjb2RlIGF0dHJpYnV0ZS4KCQl9CgkJaWYgKCBudWxsICE9PSAkZGlzY292ZXIgKSB7CgkJCSRkaXNjb3ZlcnMgPSBhcnJheSggKCAkZGlzY292ZXIgKSA/ICcxJyA6ICcwJyApOwoJCX0gZWxzZSB7CgkJCSRkaXNjb3ZlcnMgPSBhcnJheSggbnVsbCwgJzEnLCAnMCcgKTsKCQl9CgoJCSRhdHRyID0gd3BfcGFyc2VfYXJncyggJG9lbWJlZF9hcmdzLCB3cF9lbWJlZF9kZWZhdWx0cyggJHVybCApICk7CgoJCWZvcmVhY2ggKCAkZGlzY292ZXJzIGFzICRkaXNjb3ZlciApIHsKCQkJaWYgKCBudWxsICE9PSAkZGlzY292ZXIgKSB7CgkJCQkkYXR0clsnZGlzY292ZXInXSA9ICRkaXNjb3ZlcjsKCQkJfQoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5EaXNjb3VyYWdlZFBIUEZ1bmN0aW9ucy5zZXJpYWxpemVfc2VyaWFsaXplIC0tIG5lZWRlZCB0byBtaW1pYyBXUCBDb3JlIGJlaGF2aW9yLiBTZWU6IFxXUF9FbWJlZDo6c2hvcnRjb2RlLgoJCQkka2V5X3N1ZmZpeCA9IG1kNSggJHVybCAuIHNlcmlhbGl6ZSggJGF0dHIgKSApOwoKCQkJJGNhY2hlZF9wb3N0X2lkID0gJHdwX2VtYmVkLT5maW5kX29lbWJlZF9wb3N0X2lkKCAka2V5X3N1ZmZpeCApOwoKCQkJaWYgKCAkY2FjaGVkX3Bvc3RfaWQgKSB7CgkJCQlXUF9DTEk6OmxpbmUoICRjYWNoZWRfcG9zdF9pZCApOwoKCQkJCXJldHVybjsKCQkJfQoJCX0KCgkJV1BfQ0xJOjplcnJvciggJ05vIGNhY2hlIHBvc3QgSUQgZm91bmQhJyApOwoJfQoKCS8qKgoJICogVHJpZ2dlcnMgdGhlIGNhY2hpbmcgb2YgYWxsIG9FbWJlZCByZXN1bHRzIGZvciBhIGdpdmVuIHBvc3QuCgkgKgoJICogb0VtYmVkIGNhY2hlcyBmb3IgYSBwb3N0IGFyZSBzdG9yZWQgaW4gdGhlIHBvc3QncyBtZXRhZGF0YS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBvc3RfaWQ+CgkgKiA6IElEIG9mIHRoZSBwb3N0IHRvIGRvIHRoZSBjYWNoaW5nIGZvci4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFRyaWdnZXJzIGNhY2hlIGZvciBhIHBvc3QKCSAqICAgICAkIHdwIGVtYmVkIGNhY2hlIHRyaWdnZXIgNDU2CgkgKiAgICAgU3VjY2VzczogQ2FjaGluZyB0cmlnZ2VyZWQhCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0cmlnZ2VyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLyoqIEB2YXIgXFdQX0VtYmVkICR3cF9lbWJlZCAqLwoJCWdsb2JhbCAkd3BfZW1iZWQ7CgoJCSRwb3N0X2lkICAgID0gJGFyZ3NbMF07CgkJJHBvc3QgICAgICAgPSBnZXRfcG9zdCggJHBvc3RfaWQgKTsKCQkkcG9zdF90eXBlcyA9IGdldF9wb3N0X3R5cGVzKCBhcnJheSggJ3Nob3dfdWknID0+IHRydWUgKSApOwoKCQlpZiAoIGVtcHR5KCAkcG9zdC0+SUQgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiUG9zdCBpZCAnJXMnIG5vdCBmb3VuZC4iLCAkcG9zdF9pZCApICk7CgoJCQlyZXR1cm47CgkJfQoKCQkvKiogVGhpcyBmaWx0ZXIgaXMgZG9jdW1lbnRlZCBpbiB3cC1pbmNsdWRlcy9jbGFzcy13cC1lbWJlZC5waHAgKi8KCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFVzaW5nIFdQIENvcmUgaG9vay4KCQlpZiAoICEgaW5fYXJyYXkoICRwb3N0LT5wb3N0X3R5cGUsIGFwcGx5X2ZpbHRlcnMoICdlbWJlZF9jYWNoZV9vZW1iZWRfdHlwZXMnLCAkcG9zdF90eXBlcyApLCB0cnVlICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIkNhbm5vdCBjYWNoZSBvRW1iZWQgcmVzdWx0cyBmb3IgJyVzJyBwb3N0IHR5cGUiLCAkcG9zdC0+cG9zdF90eXBlICkgKTsKCgkJCXJldHVybjsKCQl9CgoJCSR3cF9lbWJlZC0+Y2FjaGVfb2VtYmVkKCAkcG9zdF9pZCApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdDYWNoaW5nIHRyaWdnZXJlZCEnICk7Cgl9Cn0KPD9waHAKLyoqCiAgICogU3B5YyAtLSBBIFNpbXBsZSBQSFAgWUFNTCBDbGFzcwogICAqIEB2ZXJzaW9uIDAuNi4yCiAgICogQGF1dGhvciBWbGFkIEFuZGVyc2VuIDx2bGFkLmFuZGVyc2VuQGdtYWlsLmNvbT4KICAgKiBAYXV0aG9yIENocmlzIFdhbnN0cmF0aCA8Y2hyaXNAb3ptbS5vcmc+CiAgICogQGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL211c3Rhbmdvc3Rhbmcvc3B5Yy8KICAgKiBAY29weXJpZ2h0IENvcHlyaWdodCAyMDA1LTIwMDYgQ2hyaXMgV2Fuc3RyYXRoLCAyMDA2LTIwMTEgVmxhZCBBbmRlcnNlbgogICAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIE1JVCBMaWNlbnNlCiAgICogQHBhY2thZ2UgU3B5YwogICAqLwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfbG9hZCcpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFlBTUwgc3RyaW5nLgogICAqIEByZXR1cm4gYXJyYXkKICAgKi8KICBmdW5jdGlvbiBzcHljX2xvYWQgKCRzdHJpbmcpIHsKICAgIHJldHVybiBTcHljOjpZQU1MTG9hZFN0cmluZygkc3RyaW5nKTsKICB9Cn0KCmlmICghZnVuY3Rpb25fZXhpc3RzKCdzcHljX2xvYWRfZmlsZScpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBQYXRoIHRvIFlBTUwgZmlsZS4KICAgKiBAcmV0dXJuIGFycmF5CiAgICovCiAgZnVuY3Rpb24gc3B5Y19sb2FkX2ZpbGUgKCRmaWxlKSB7CiAgICByZXR1cm4gU3B5Yzo6WUFNTExvYWQoJGZpbGUpOwogIH0KfQoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfZHVtcCcpKSB7CiAgLyoqCiAgICogRHVtcHMgYXJyYXkgdG8gWUFNTC4KICAgKiBAcGFyYW0gYXJyYXkgJGRhdGEgQXJyYXkuCiAgICogQHJldHVybiBzdHJpbmcKICAgKi8KICBmdW5jdGlvbiBzcHljX2R1bXAgKCRkYXRhKSB7CiAgICByZXR1cm4gU3B5Yzo6WUFNTER1bXAoJGRhdGEsIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7CiAgfQp9Cjw/cGhwCi8qKgogICAqIFNweWMgLS0gQSBTaW1wbGUgUEhQIFlBTUwgQ2xhc3MKICAgKiBAdmVyc2lvbiAwLjYuMgogICAqIEBhdXRob3IgVmxhZCBBbmRlcnNlbiA8dmxhZC5hbmRlcnNlbkBnbWFpbC5jb20+CiAgICogQGF1dGhvciBDaHJpcyBXYW5zdHJhdGggPGNocmlzQG96bW0ub3JnPgogICAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9tdXN0YW5nb3N0YW5nL3NweWMvCiAgICogQGNvcHlyaWdodCBDb3B5cmlnaHQgMjAwNS0yMDA2IENocmlzIFdhbnN0cmF0aCwgMjAwNi0yMDExIFZsYWQgQW5kZXJzZW4KICAgKiBAbGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBNSVQgTGljZW5zZQogICAqIEBwYWNrYWdlIFNweWMKICAgKi8KCmlmICghY2xhc3NfZXhpc3RzKCdNdXN0YW5nb3N0YW5nXFNweWMnKSkgewogIHJlcXVpcmVfb25jZSBkaXJuYW1lKF9fRklMRV9fKSAuICcvc3JjL1NweWMucGhwJzsKfQoKY2xhc3NfYWxpYXMoJ011c3Rhbmdvc3RhbmdcU3B5YycsICdTcHljJyk7CgpyZXF1aXJlX29uY2UgZGlybmFtZShfX0ZJTEVfXykgLiAnL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAnOwoKLy8gRW5hYmxlIHVzZSBvZiBTcHljIGZyb20gY29tbWFuZCBsaW5lCi8vIFRoZSBzeW50YXggaXMgdGhlIGZvbGxvd2luZzogcGhwIFNweWMucGhwIHNweWMueWFtbApkbyB7CiAgaWYgKFBIUF9TQVBJICE9ICdjbGknKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydhcmdjJ10pIHx8ICRfU0VSVkVSWydhcmdjJ10gPCAyKSBicmVhazsKICBpZiAoZW1wdHkgKCRfU0VSVkVSWydQSFBfU0VMRiddKSB8fCBGQUxTRSA9PT0gc3RycG9zICgkX1NFUlZFUlsnUEhQX1NFTEYnXSwgJ1NweWMucGhwJykgKSBicmVhazsKICAkZmlsZSA9ICRhcmd2WzFdOwogIGVjaG8ganNvbl9lbmNvZGUgKHNweWNfbG9hZF9maWxlICgkZmlsZSkpOwp9IHdoaWxlICgwKTsKPD9waHAKCnBocDV0bzQgKCIuLi9zcHljLnBocCIsICdzcHljLWxhdGVzdC5waHA0Jyk7CgpmdW5jdGlvbiBwaHA1dG80ICgkc3JjLCAkZGVzdCkgewogICRjb2RlID0gZmlsZV9nZXRfY29udGVudHMgKCRzcmMpOwogICRjb2RlID0gcHJlZ19yZXBsYWNlICgnIyhwdWJsaWN8cHJpdmF0ZXxwcm90ZWN0ZWQpXHMrXCQjaScsICd2YXIgXCQnLCAkY29kZSk7CiAgJGNvZGUgPSBwcmVnX3JlcGxhY2UgKCcjKHB1YmxpY3xwcml2YXRlfHByb3RlY3RlZClccytzdGF0aWNccytcJCNpJywgJ3ZhciBcJCcsICRjb2RlKTsKICAkY29kZSA9IHByZWdfcmVwbGFjZSAoJyMocHVibGljfHByaXZhdGV8cHJvdGVjdGVkKVxzK2Z1bmN0aW9uI2knLCAnZnVuY3Rpb24nLCAkY29kZSk7CiAgJGNvZGUgPSBwcmVnX3JlcGxhY2UgKCcjKHB1YmxpY3xwcml2YXRlfHByb3RlY3RlZClccytzdGF0aWNccytmdW5jdGlvbiNpJywgJ2Z1bmN0aW9uJywgJGNvZGUpOwogICRjb2RlID0gcHJlZ19yZXBsYWNlICgnI3Rocm93IG5ldyBFeGNlcHRpb25cXCgoW14pXSopXFwpI2knLCAndHJpZ2dlcl9lcnJvcigkMSxFX1VTRVJfRVJST1IpJywgJGNvZGUpOwogICRjb2RlID0gc3RyX3JlcGxhY2UgKCdzZWxmOjonLCAnJHRoaXMtPicsICRjb2RlKTsKICAkZiA9IGZvcGVuICgkZGVzdCwgJ3cnKTsKICBmd3JpdGUoJGYsICRjb2RlKTsKICBmY2xvc2UgKCRmKTsKICBwcmludCAiV3JpdHRlbiB0byAkZGVzdC5cbiI7Cn08P3BocAovKioKICAgKiBTcHljIC0tIEEgU2ltcGxlIFBIUCBZQU1MIENsYXNzCiAgICogQHZlcnNpb24gMC40LjUKICAgKiBAYXV0aG9yIFZsYWQgQW5kZXJzZW4gPHZsYWQuYW5kZXJzZW5AZ21haWwuY29tPgogICAqIEBhdXRob3IgQ2hyaXMgV2Fuc3RyYXRoIDxjaHJpc0Bvem1tLm9yZz4KICAgKiBAbGluayBodHRwOi8vY29kZS5nb29nbGUuY29tL3Avc3B5Yy8KICAgKiBAY29weXJpZ2h0IENvcHlyaWdodCAyMDA1LTIwMDYgQ2hyaXMgV2Fuc3RyYXRoLCAyMDA2LTIwMDkgVmxhZCBBbmRlcnNlbgogICAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIE1JVCBMaWNlbnNlCiAgICogQHBhY2thZ2UgU3B5YwogICAqLwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NweWNfbG9hZCcpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFlBTUwgc3RyaW5nLgogICAqIEByZXR1cm4gYXJyYXkKICAgKi8KICBmdW5jdGlvbiBzcHljX2xvYWQgKCRzdHJpbmcpIHsKICAgIHJldHVybiBTcHljOjpZQU1MTG9hZFN0cmluZygkc3RyaW5nKTsKICB9Cn0KCmlmICghZnVuY3Rpb25fZXhpc3RzKCdzcHljX2xvYWRfZmlsZScpKSB7CiAgLyoqCiAgICogUGFyc2VzIFlBTUwgdG8gYXJyYXkuCiAgICogQHBhcmFtIHN0cmluZyAkZmlsZSBQYXRoIHRvIFlBTUwgZmlsZS4KICAgKiBAcmV0dXJuIGFycmF5CiAgICovCiAgZnVuY3Rpb24gc3B5Y19sb2FkX2ZpbGUgKCRmaWxlKSB7CiAgICByZXR1cm4gU3B5Yzo6WUFNTExvYWQoJGZpbGUpOwogIH0KfQoKLyoqCiAgICogVGhlIFNpbXBsZSBQSFAgWUFNTCBDbGFzcy4KICAgKgogICAqIFRoaXMgY2xhc3MgY2FuIGJlIHVzZWQgdG8gcmVhZCBhIFlBTUwgZmlsZSBhbmQgY29udmVydCBpdHMgY29udGVudHMKICAgKiBpbnRvIGEgUEhQIGFycmF5LiAgSXQgY3VycmVudGx5IHN1cHBvcnRzIGEgdmVyeSBsaW1pdGVkIHN1YnNlY3Rpb24gb2YKICAgKiB0aGUgWUFNTCBzcGVjLgogICAqCiAgICogVXNhZ2U6CiAgICogPGNvZGU+CiAgICogICAkU3B5YyAgPSBuZXcgU3B5YzsKICAgKiAgICRhcnJheSA9ICRTcHljLT5sb2FkKCRmaWxlKTsKICAgKiA8L2NvZGU+CiAgICogb3I6CiAgICogPGNvZGU+CiAgICogICAkYXJyYXkgPSBTcHljOjpZQU1MTG9hZCgkZmlsZSk7CiAgICogPC9jb2RlPgogICAqIG9yOgogICAqIDxjb2RlPgogICAqICAgJGFycmF5ID0gc3B5Y19sb2FkX2ZpbGUoJGZpbGUpOwogICAqIDwvY29kZT4KICAgKiBAcGFja2FnZSBTcHljCiAgICovCmNsYXNzIFNweWMgewoKICAvLyBTRVRUSU5HUwoKICAvKioKICAgKiBTZXR0aW5nIHRoaXMgdG8gdHJ1ZSB3aWxsIGZvcmNlIFlBTUxEdW1wIHRvIGVuY2xvc2UgYW55IHN0cmluZyB2YWx1ZSBpbgogICAqIHF1b3Rlcy4gIEZhbHNlIGJ5IGRlZmF1bHQuCiAgICogCiAgICogQHZhciBib29sCiAgICovCiAgdmFyICRzZXR0aW5nX2R1bXBfZm9yY2VfcXVvdGVzID0gZmFsc2U7CgogIC8qKgogICAqIFNldHRpbmcgdGhpcyB0byB0cnVlIHdpbGwgZm9yc2UgWUFNTExvYWQgdG8gdXNlIHN5Y2tfbG9hZCBmdW5jdGlvbiB3aGVuCiAgICogcG9zc2libGUuIEZhbHNlIGJ5IGRlZmF1bHQuCiAgICogQHZhciBib29sCiAgICovCiAgdmFyICRzZXR0aW5nX3VzZV9zeWNrX2lzX3Bvc3NpYmxlID0gZmFsc2U7CgoKCiAgLyoqI0ArCiAgKiBAYWNjZXNzIHByaXZhdGUKICAqIEB2YXIgbWl4ZWQKICAqLwogIHZhciAkX2R1bXBJbmRlbnQ7CiAgdmFyICRfZHVtcFdvcmRXcmFwOwogIHZhciAkX2NvbnRhaW5zR3JvdXBBbmNob3IgPSBmYWxzZTsKICB2YXIgJF9jb250YWluc0dyb3VwQWxpYXMgPSBmYWxzZTsKICB2YXIgJHBhdGg7CiAgdmFyICRyZXN1bHQ7CiAgdmFyICRMaXRlcmFsUGxhY2VIb2xkZXIgPSAnX19fWUFNTF9MaXRlcmFsX0Jsb2NrX19fJzsKICB2YXIgJFNhdmVkR3JvdXBzID0gYXJyYXkoKTsKICB2YXIgJGluZGVudDsKICAvKioKICAgKiBQYXRoIG1vZGlmaWVyIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYWZ0ZXIgYWRkaW5nIGN1cnJlbnQgZWxlbWVudC4KICAgKiBAdmFyIGFycmF5CiAgICovCiAgdmFyICRkZWxheWVkUGF0aCA9IGFycmF5KCk7CgogIC8qKiNAKwogICogQGFjY2VzcyBwdWJsaWMKICAqIEB2YXIgbWl4ZWQKICAqLwogIHZhciAkX25vZGVJZDsKCi8qKgogKiBMb2FkIGEgdmFsaWQgWUFNTCBzdHJpbmcgdG8gU3B5Yy4KICogQHBhcmFtIHN0cmluZyAkaW5wdXQKICogQHJldHVybiBhcnJheQogKi8KICBmdW5jdGlvbiBsb2FkICgkaW5wdXQpIHsKICAgIHJldHVybiAkdGhpcy0+X19sb2FkU3RyaW5nKCRpbnB1dCk7CiAgfQoKIC8qKgogKiBMb2FkIGEgdmFsaWQgWUFNTCBmaWxlIHRvIFNweWMuCiAqIEBwYXJhbSBzdHJpbmcgJGZpbGUKICogQHJldHVybiBhcnJheQogKi8KICBmdW5jdGlvbiBsb2FkRmlsZSAoJGZpbGUpIHsKICAgIHJldHVybiAkdGhpcy0+X19sb2FkKCRmaWxlKTsKICB9CgogIC8qKgogICAgICogTG9hZCBZQU1MIGludG8gYSBQSFAgYXJyYXkgc3RhdGljYWxseQogICAgICoKICAgICAqIFRoZSBsb2FkIG1ldGhvZCwgd2hlbiBzdXBwbGllZCB3aXRoIGEgWUFNTCBzdHJlYW0gKHN0cmluZyBvciBmaWxlKSwKICAgICAqIHdpbGwgZG8gaXRzIGJlc3QgdG8gY29udmVydCBZQU1MIGluIGEgZmlsZSBpbnRvIGEgUEhQIGFycmF5LiAgUHJldHR5CiAgICAgKiBzaW1wbGUuCiAgICAgKiAgVXNhZ2U6CiAgICAgKiAgPGNvZGU+CiAgICAgKiAgICRhcnJheSA9IFNweWM6OllBTUxMb2FkKCdsdWNreS55YW1sJyk7CiAgICAgKiAgIHByaW50X3IoJGFycmF5KTsKICAgICAqICA8L2NvZGU+CiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBhcmFtIHN0cmluZyAkaW5wdXQgUGF0aCBvZiBZQU1MIGZpbGUgb3Igc3RyaW5nIGNvbnRhaW5pbmcgWUFNTAogICAgICovCiAgZnVuY3Rpb24gWUFNTExvYWQoJGlucHV0KSB7CiAgICAkU3B5YyA9IG5ldyBTcHljOwogICAgcmV0dXJuICRTcHljLT5fX2xvYWQoJGlucHV0KTsKICB9CgogIC8qKgogICAgICogTG9hZCBhIHN0cmluZyBvZiBZQU1MIGludG8gYSBQSFAgYXJyYXkgc3RhdGljYWxseQogICAgICoKICAgICAqIFRoZSBsb2FkIG1ldGhvZCwgd2hlbiBzdXBwbGllZCB3aXRoIGEgWUFNTCBzdHJpbmcsIHdpbGwgZG8gaXRzIGJlc3QgCiAgICAgKiB0byBjb252ZXJ0IFlBTUwgaW4gYSBzdHJpbmcgaW50byBhIFBIUCBhcnJheS4gIFByZXR0eSBzaW1wbGUuCiAgICAgKgogICAgICogTm90ZTogdXNlIHRoaXMgZnVuY3Rpb24gaWYgeW91IGRvbid0IHdhbnQgZmlsZXMgZnJvbSB0aGUgZmlsZSBzeXN0ZW0KICAgICAqIGxvYWRlZCBhbmQgcHJvY2Vzc2VkIGFzIFlBTUwuICBUaGlzIGlzIG9mIGludGVyZXN0IHRvIHBlb3BsZSBjb25jZXJuZWQKICAgICAqIGFib3V0IHNlY3VyaXR5IHdob3NlIGlucHV0IGlzIGZyb20gYSBzdHJpbmcuCiAgICAgKgogICAgICogIFVzYWdlOgogICAgICogIDxjb2RlPgogICAgICogICAkYXJyYXkgPSBTcHljOjpZQU1MTG9hZFN0cmluZygiLS0tXG4wOiBoZWxsbyB3b3JsZFxuIik7CiAgICAgKiAgIHByaW50X3IoJGFycmF5KTsKICAgICAqICA8L2NvZGU+CiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBhcnJheQogICAgICogQHBhcmFtIHN0cmluZyAkaW5wdXQgU3RyaW5nIGNvbnRhaW5pbmcgWUFNTAogICAgICovCiAgZnVuY3Rpb24gWUFNTExvYWRTdHJpbmcoJGlucHV0KSB7CiAgICAkU3B5YyA9IG5ldyBTcHljOwogICAgcmV0dXJuICRTcHljLT5fX2xvYWRTdHJpbmcoJGlucHV0KTsKICB9CgogIC8qKgogICAgICogRHVtcCBZQU1MIGZyb20gUEhQIGFycmF5IHN0YXRpY2FsbHkKICAgICAqCiAgICAgKiBUaGUgZHVtcCBtZXRob2QsIHdoZW4gc3VwcGxpZWQgd2l0aCBhbiBhcnJheSwgd2lsbCBkbyBpdHMgYmVzdAogICAgICogdG8gY29udmVydCB0aGUgYXJyYXkgaW50byBmcmllbmRseSBZQU1MLiAgUHJldHR5IHNpbXBsZS4gIEZlZWwgZnJlZSB0bwogICAgICogc2F2ZSB0aGUgcmV0dXJuZWQgc3RyaW5nIGFzIG5vdGhpbmcueWFtbCBhbmQgcGFzcyBpdCBhcm91bmQuCiAgICAgKgogICAgICogT2gsIGFuZCB5b3UgY2FuIGRlY2lkZSBob3cgYmlnIHRoZSBpbmRlbnQgaXMgYW5kIHdoYXQgdGhlIHdvcmR3cmFwCiAgICAgKiBmb3IgZm9sZGluZyBpcy4gIFByZXR0eSBjb29sIC0tIGp1c3QgcGFzcyBpbiAnZmFsc2UnIGZvciBlaXRoZXIgaWYKICAgICAqIHlvdSB3YW50IHRvIHVzZSB0aGUgZGVmYXVsdC4KICAgICAqCiAgICAgKiBJbmRlbnQncyBkZWZhdWx0IGlzIDIgc3BhY2VzLCB3b3Jkd3JhcCdzIGRlZmF1bHQgaXMgNDAgY2hhcmFjdGVycy4gIEFuZAogICAgICogeW91IGNhbiB0dXJuIG9mZiB3b3Jkd3JhcCBieSBwYXNzaW5nIGluIDAuCiAgICAgKgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gYXJyYXkgJGFycmF5IFBIUCBhcnJheQogICAgICogQHBhcmFtIGludCAkaW5kZW50IFBhc3MgaW4gZmFsc2UgdG8gdXNlIHRoZSBkZWZhdWx0LCB3aGljaCBpcyAyCiAgICAgKiBAcGFyYW0gaW50ICR3b3Jkd3JhcCBQYXNzIGluIDAgZm9yIG5vIHdvcmR3cmFwLCBmYWxzZSBmb3IgZGVmYXVsdCAoNDApCiAgICAgKi8KICBmdW5jdGlvbiBZQU1MRHVtcCgkYXJyYXksJGluZGVudCA9IGZhbHNlLCR3b3Jkd3JhcCA9IGZhbHNlKSB7CiAgICAkc3B5YyA9IG5ldyBTcHljOwogICAgcmV0dXJuICRzcHljLT5kdW1wKCRhcnJheSwkaW5kZW50LCR3b3Jkd3JhcCk7CiAgfQoKCiAgLyoqCiAgICAgKiBEdW1wIFBIUCBhcnJheSB0byBZQU1MCiAgICAgKgogICAgICogVGhlIGR1bXAgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYW4gYXJyYXksIHdpbGwgZG8gaXRzIGJlc3QKICAgICAqIHRvIGNvbnZlcnQgdGhlIGFycmF5IGludG8gZnJpZW5kbHkgWUFNTC4gIFByZXR0eSBzaW1wbGUuICBGZWVsIGZyZWUgdG8KICAgICAqIHNhdmUgdGhlIHJldHVybmVkIHN0cmluZyBhcyB0YXN0ZWZ1bC55YW1sIGFuZCBwYXNzIGl0IGFyb3VuZC4KICAgICAqCiAgICAgKiBPaCwgYW5kIHlvdSBjYW4gZGVjaWRlIGhvdyBiaWcgdGhlIGluZGVudCBpcyBhbmQgd2hhdCB0aGUgd29yZHdyYXAKICAgICAqIGZvciBmb2xkaW5nIGlzLiAgUHJldHR5IGNvb2wgLS0ganVzdCBwYXNzIGluICdmYWxzZScgZm9yIGVpdGhlciBpZgogICAgICogeW91IHdhbnQgdG8gdXNlIHRoZSBkZWZhdWx0LgogICAgICoKICAgICAqIEluZGVudCdzIGRlZmF1bHQgaXMgMiBzcGFjZXMsIHdvcmR3cmFwJ3MgZGVmYXVsdCBpcyA0MCBjaGFyYWN0ZXJzLiAgQW5kCiAgICAgKiB5b3UgY2FuIHR1cm4gb2ZmIHdvcmR3cmFwIGJ5IHBhc3NpbmcgaW4gMC4KICAgICAqCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyYXkgUEhQIGFycmF5CiAgICAgKiBAcGFyYW0gaW50ICRpbmRlbnQgUGFzcyBpbiBmYWxzZSB0byB1c2UgdGhlIGRlZmF1bHQsIHdoaWNoIGlzIDIKICAgICAqIEBwYXJhbSBpbnQgJHdvcmR3cmFwIFBhc3MgaW4gMCBmb3Igbm8gd29yZHdyYXAsIGZhbHNlIGZvciBkZWZhdWx0ICg0MCkKICAgICAqLwogIGZ1bmN0aW9uIGR1bXAoJGFycmF5LCRpbmRlbnQgPSBmYWxzZSwkd29yZHdyYXAgPSBmYWxzZSkgewogICAgLy8gRHVtcHMgdG8gc29tZSB2ZXJ5IGNsZWFuIFlBTUwuICBXZSdsbCBoYXZlIHRvIGFkZCBzb21lIG1vcmUgZmVhdHVyZXMKICAgIC8vIGFuZCBvcHRpb25zIHNvb24uICBBbmQgYmV0dGVyIHN1cHBvcnQgZm9yIGZvbGRpbmcuCgogICAgLy8gTmV3IGZlYXR1cmVzIGFuZCBvcHRpb25zLgogICAgaWYgKCRpbmRlbnQgPT09IGZhbHNlIG9yICFpc19udW1lcmljKCRpbmRlbnQpKSB7CiAgICAgICR0aGlzLT5fZHVtcEluZGVudCA9IDI7CiAgICB9IGVsc2UgewogICAgICAkdGhpcy0+X2R1bXBJbmRlbnQgPSAkaW5kZW50OwogICAgfQoKICAgIGlmICgkd29yZHdyYXAgPT09IGZhbHNlIG9yICFpc19udW1lcmljKCR3b3Jkd3JhcCkpIHsKICAgICAgJHRoaXMtPl9kdW1wV29yZFdyYXAgPSA0MDsKICAgIH0gZWxzZSB7CiAgICAgICR0aGlzLT5fZHVtcFdvcmRXcmFwID0gJHdvcmR3cmFwOwogICAgfQoKICAgIC8vIE5ldyBZQU1MIGRvY3VtZW50CiAgICAkc3RyaW5nID0gIi0tLVxuIjsKCiAgICAvLyBTdGFydCBhdCB0aGUgYmFzZSBvZiB0aGUgYXJyYXkgYW5kIG1vdmUgdGhyb3VnaCBpdC4KICAgIGlmICgkYXJyYXkpIHsKICAgICAgJGFycmF5ID0gKGFycmF5KSRhcnJheTsKICAgICAgJGZpcnN0X2tleSA9IGtleSgkYXJyYXkpOwogICAgICAKICAgICAgJHByZXZpb3VzX2tleSA9IC0xOwogICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZSgka2V5LCR2YWx1ZSwwLCRwcmV2aW91c19rZXksICRmaXJzdF9rZXkpOwogICAgICAgICRwcmV2aW91c19rZXkgPSAka2V5OwogICAgICB9CiAgICB9CiAgICByZXR1cm4gJHN0cmluZzsKICB9CgogIC8qKgogICAgICogQXR0ZW1wdHMgdG8gY29udmVydCBhIGtleSAvIHZhbHVlIGFycmF5IGl0ZW0gdG8gWUFNTAogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtICRrZXkgVGhlIG5hbWUgb2YgdGhlIGtleQogICAgICogQHBhcmFtICR2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGl0ZW0KICAgICAqIEBwYXJhbSAkaW5kZW50IFRoZSBpbmRlbnQgb2YgdGhlIGN1cnJlbnQgbm9kZQogICAgICovCiAgZnVuY3Rpb24gX3lhbWxpemUoJGtleSwkdmFsdWUsJGluZGVudCwgJHByZXZpb3VzX2tleSA9IC0xLCAkZmlyc3Rfa2V5ID0gMCkgewogICAgaWYgKGlzX2FycmF5KCR2YWx1ZSkpIHsKICAgICAgaWYgKGVtcHR5ICgkdmFsdWUpKQogICAgICAgIHJldHVybiAkdGhpcy0+X2R1bXBOb2RlKCRrZXksIGFycmF5KCksICRpbmRlbnQsICRwcmV2aW91c19rZXksICRmaXJzdF9rZXkpOwogICAgICAvLyBJdCBoYXMgY2hpbGRyZW4uICBXaGF0IHRvIGRvPwogICAgICAvLyBNYWtlIGl0IHRoZSByaWdodCBraW5kIG9mIGl0ZW0KICAgICAgJHN0cmluZyA9ICR0aGlzLT5fZHVtcE5vZGUoJGtleSwgTlVMTCwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSk7CiAgICAgIC8vIEFkZCB0aGUgaW5kZW50CiAgICAgICRpbmRlbnQgKz0gJHRoaXMtPl9kdW1wSW5kZW50OwogICAgICAvLyBZYW1saXplIHRoZSBhcnJheQogICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZUFycmF5KCR2YWx1ZSwkaW5kZW50KTsKICAgIH0gZWxzZWlmICghaXNfYXJyYXkoJHZhbHVlKSkgewogICAgICAvLyBJdCBkb2Vzbid0IGhhdmUgY2hpbGRyZW4uICBZaXAuCiAgICAgICRzdHJpbmcgPSAkdGhpcy0+X2R1bXBOb2RlKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSk7CiAgICB9CiAgICByZXR1cm4gJHN0cmluZzsKICB9CgogIC8qKgogICAgICogQXR0ZW1wdHMgdG8gY29udmVydCBhbiBhcnJheSB0byBZQU1MCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGFycmF5IFRoZSBhcnJheSB5b3Ugd2FudCB0byBjb252ZXJ0CiAgICAgKiBAcGFyYW0gJGluZGVudCBUaGUgaW5kZW50IG9mIHRoZSBjdXJyZW50IGxldmVsCiAgICAgKi8KICBmdW5jdGlvbiBfeWFtbGl6ZUFycmF5KCRhcnJheSwkaW5kZW50KSB7CiAgICBpZiAoaXNfYXJyYXkoJGFycmF5KSkgewogICAgICAkc3RyaW5nID0gJyc7CiAgICAgICRwcmV2aW91c19rZXkgPSAtMTsKICAgICAgJGZpcnN0X2tleSA9IGtleSgkYXJyYXkpOwogICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZSgka2V5LCAkdmFsdWUsICRpbmRlbnQsICRwcmV2aW91c19rZXksICRmaXJzdF9rZXkpOwogICAgICAgICRwcmV2aW91c19rZXkgPSAka2V5OwogICAgICB9CiAgICAgIHJldHVybiAkc3RyaW5nOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH0KCiAgLyoqCiAgICAgKiBSZXR1cm5zIFlBTUwgZnJvbSBhIGtleSBhbmQgYSB2YWx1ZQogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQHBhcmFtICRrZXkgVGhlIG5hbWUgb2YgdGhlIGtleQogICAgICogQHBhcmFtICR2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGl0ZW0KICAgICAqIEBwYXJhbSAkaW5kZW50IFRoZSBpbmRlbnQgb2YgdGhlIGN1cnJlbnQgbm9kZQogICAgICovCiAgZnVuY3Rpb24gX2R1bXBOb2RlKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSA9IC0xLCAkZmlyc3Rfa2V5ID0gMCkgewogICAgLy8gZG8gc29tZSBmb2xkaW5nIGhlcmUsIGZvciBibG9ja3MKICAgIGlmIChpc19zdHJpbmcgKCR2YWx1ZSkgJiYgKChzdHJwb3MoJHZhbHVlLCJcbiIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCI6ICIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCItICIpICE9PSBmYWxzZSB8fAogICAgICBzdHJwb3MoJHZhbHVlLCIqIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIiMiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiPCIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCI+IikgIT09IGZhbHNlIHx8CiAgICAgIHN0cnBvcygkdmFsdWUsIlsiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiXSIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCJ7IikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIn0iKSAhPT0gZmFsc2UpIHx8IHN1YnN0ciAoJHZhbHVlLCAtMSwgMSkgPT0gJzonKSkgewogICAgICAkdmFsdWUgPSAkdGhpcy0+X2RvTGl0ZXJhbEJsb2NrKCR2YWx1ZSwkaW5kZW50KTsKICAgIH0gZWxzZSB7CiAgICAgICR2YWx1ZSAgPSAkdGhpcy0+X2RvRm9sZGluZygkdmFsdWUsJGluZGVudCk7CiAgICAgIGlmIChpc19ib29sKCR2YWx1ZSkpIHsKICAgICAgICAkdmFsdWUgPSAoJHZhbHVlKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoJHZhbHVlID09PSBhcnJheSgpKSAkdmFsdWUgPSAnWyBdJzsKCiAgICAkc3BhY2VzID0gc3RyX3JlcGVhdCgnICcsJGluZGVudCk7CgogICAgaWYgKGlzX2ludCgka2V5KSAmJiAka2V5IC0gMSA9PSAkcHJldmlvdXNfa2V5ICYmICRmaXJzdF9rZXk9PT0wKSB7CiAgICAgIC8vIEl0J3MgYSBzZXF1ZW5jZQogICAgICAkc3RyaW5nID0gJHNwYWNlcy4nLSAnLiR2YWx1ZS4iXG4iOwogICAgfSBlbHNlIHsKICAgICAgaWYgKCRmaXJzdF9rZXk9PT0wKSAgdGhyb3cgbmV3IEV4Y2VwdGlvbignS2V5cyBhcmUgYWxsIHNjcmV3eS4gIFRoZSBmaXJzdCBvbmUgd2FzIHplcm8sIG5vdyBpdFwncyAiJy4gJGtleSAuJyInKTsKICAgICAgLy8gSXQncyBtYXBwZWQKICAgICAgaWYgKHN0cnBvcygka2V5LCAiOiIpICE9PSBmYWxzZSkgeyAka2V5ID0gJyInIC4gJGtleSAuICciJzsgfQogICAgICAkc3RyaW5nID0gJHNwYWNlcy4ka2V5Lic6ICcuJHZhbHVlLiJcbiI7CiAgICB9CiAgICByZXR1cm4gJHN0cmluZzsKICB9CgogIC8qKgogICAgICogQ3JlYXRlcyBhIGxpdGVyYWwgYmxvY2sgZm9yIGR1bXBpbmcKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkdmFsdWUKICAgICAqIEBwYXJhbSAkaW5kZW50IGludCBUaGUgdmFsdWUgb2YgdGhlIGluZGVudAogICAgICovCiAgZnVuY3Rpb24gX2RvTGl0ZXJhbEJsb2NrKCR2YWx1ZSwkaW5kZW50KSB7CiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgIlxuIikgPT09IGZhbHNlICYmIHN0cnBvcygkdmFsdWUsICInIikgPT09IGZhbHNlKSB7CiAgICAgIHJldHVybiBzcHJpbnRmICgiJyVzJyIsICR2YWx1ZSk7CiAgICB9CiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgIlxuIikgPT09IGZhbHNlICYmIHN0cnBvcygkdmFsdWUsICciJykgPT09IGZhbHNlKSB7CiAgICAgIHJldHVybiBzcHJpbnRmICgnIiVzIicsICR2YWx1ZSk7CiAgICB9CiAgICAkZXhwbG9kZWQgPSBleHBsb2RlKCJcbiIsJHZhbHVlKTsKICAgICRuZXdWYWx1ZSA9ICd8JzsKICAgICRpbmRlbnQgICs9ICR0aGlzLT5fZHVtcEluZGVudDsKICAgICRzcGFjZXMgICA9IHN0cl9yZXBlYXQoJyAnLCRpbmRlbnQpOwogICAgZm9yZWFjaCAoJGV4cGxvZGVkIGFzICRsaW5lKSB7CiAgICAgICRuZXdWYWx1ZSAuPSAiXG4iIC4gJHNwYWNlcyAuIHRyaW0oJGxpbmUpOwogICAgfQogICAgcmV0dXJuICRuZXdWYWx1ZTsKICB9CgogIC8qKgogICAgICogRm9sZHMgYSBzdHJpbmcgb2YgdGV4dCwgaWYgbmVjZXNzYXJ5CiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSBzdHJpbmcgeW91IHdpc2ggdG8gZm9sZAogICAgICovCiAgZnVuY3Rpb24gX2RvRm9sZGluZygkdmFsdWUsJGluZGVudCkgewogICAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgd29yZHdyYXAgaXMgc2V0IHRvIDAKCiAgICBpZiAoJHRoaXMtPl9kdW1wV29yZFdyYXAgIT09IDAgJiYgaXNfc3RyaW5nICgkdmFsdWUpICYmIHN0cmxlbigkdmFsdWUpID4gJHRoaXMtPl9kdW1wV29yZFdyYXApIHsKICAgICAgJGluZGVudCArPSAkdGhpcy0+X2R1bXBJbmRlbnQ7CiAgICAgICRpbmRlbnQgPSBzdHJfcmVwZWF0KCcgJywkaW5kZW50KTsKICAgICAgJHdyYXBwZWQgPSB3b3Jkd3JhcCgkdmFsdWUsJHRoaXMtPl9kdW1wV29yZFdyYXAsIlxuJGluZGVudCIpOwogICAgICAkdmFsdWUgICA9ICI+XG4iLiRpbmRlbnQuJHdyYXBwZWQ7CiAgICB9IGVsc2UgewogICAgICBpZiAoJHRoaXMtPnNldHRpbmdfZHVtcF9mb3JjZV9xdW90ZXMgJiYgaXNfc3RyaW5nICgkdmFsdWUpKQogICAgICAgICR2YWx1ZSA9ICciJyAuICR2YWx1ZSAuICciJzsKICAgIH0KCgogICAgcmV0dXJuICR2YWx1ZTsKICB9CgovLyBMT0FESU5HIEZVTkNUSU9OUwoKICBmdW5jdGlvbiBfX2xvYWQoJGlucHV0KSB7CiAgICAkU291cmNlID0gJHRoaXMtPmxvYWRGcm9tU291cmNlKCRpbnB1dCk7CiAgICByZXR1cm4gJHRoaXMtPmxvYWRXaXRoU291cmNlKCRTb3VyY2UpOwogIH0KCiAgZnVuY3Rpb24gX19sb2FkU3RyaW5nKCRpbnB1dCkgewogICAgJFNvdXJjZSA9ICR0aGlzLT5sb2FkRnJvbVN0cmluZygkaW5wdXQpOwogICAgcmV0dXJuICR0aGlzLT5sb2FkV2l0aFNvdXJjZSgkU291cmNlKTsKICB9CgogIGZ1bmN0aW9uIGxvYWRXaXRoU291cmNlKCRTb3VyY2UpIHsKICAgIGlmIChlbXB0eSAoJFNvdXJjZSkpIHJldHVybiBhcnJheSgpOwogICAgaWYgKCR0aGlzLT5zZXR0aW5nX3VzZV9zeWNrX2lzX3Bvc3NpYmxlICYmIGZ1bmN0aW9uX2V4aXN0cyAoJ3N5Y2tfbG9hZCcpKSB7CiAgICAgICRhcnJheSA9IHN5Y2tfbG9hZCAoaW1wbG9kZSAoJycsICRTb3VyY2UpKTsKICAgICAgcmV0dXJuIGlzX2FycmF5KCRhcnJheSkgPyAkYXJyYXkgOiBhcnJheSgpOwogICAgfQoKICAgICR0aGlzLT5wYXRoID0gYXJyYXkoKTsKICAgICR0aGlzLT5yZXN1bHQgPSBhcnJheSgpOwoKICAgICRjbnQgPSBjb3VudCgkU291cmNlKTsKICAgIGZvciAoJGkgPSAwOyAkaSA8ICRjbnQ7ICRpKyspIHsKICAgICAgJGxpbmUgPSAkU291cmNlWyRpXTsKICAgICAgCiAgICAgICR0aGlzLT5pbmRlbnQgPSBzdHJsZW4oJGxpbmUpIC0gc3RybGVuKGx0cmltKCRsaW5lKSk7CiAgICAgICR0ZW1wUGF0aCA9ICR0aGlzLT5nZXRQYXJlbnRQYXRoQnlJbmRlbnQoJHRoaXMtPmluZGVudCk7CiAgICAgICRsaW5lID0gJHRoaXMtPnN0cmlwSW5kZW50KCRsaW5lLCAkdGhpcy0+aW5kZW50KTsKICAgICAgaWYgKCR0aGlzLT5pc0NvbW1lbnQoJGxpbmUpKSBjb250aW51ZTsKICAgICAgaWYgKCR0aGlzLT5pc0VtcHR5KCRsaW5lKSkgY29udGludWU7CiAgICAgICR0aGlzLT5wYXRoID0gJHRlbXBQYXRoOwoKICAgICAgJGxpdGVyYWxCbG9ja1N0eWxlID0gJHRoaXMtPnN0YXJ0c0xpdGVyYWxCbG9jaygkbGluZSk7CiAgICAgIGlmICgkbGl0ZXJhbEJsb2NrU3R5bGUpIHsKICAgICAgICAkbGluZSA9IHJ0cmltICgkbGluZSwgJGxpdGVyYWxCbG9ja1N0eWxlIC4gIiBcbiIpOwogICAgICAgICRsaXRlcmFsQmxvY2sgPSAnJzsKICAgICAgICAkbGluZSAuPSAkdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyOwoKICAgICAgICB3aGlsZSAoKyskaSA8ICRjbnQgJiYgJHRoaXMtPmxpdGVyYWxCbG9ja0NvbnRpbnVlcygkU291cmNlWyRpXSwgJHRoaXMtPmluZGVudCkpIHsKICAgICAgICAgICRsaXRlcmFsQmxvY2sgPSAkdGhpcy0+YWRkTGl0ZXJhbExpbmUoJGxpdGVyYWxCbG9jaywgJFNvdXJjZVskaV0sICRsaXRlcmFsQmxvY2tTdHlsZSk7CiAgICAgICAgfQogICAgICAgICRpLS07CiAgICAgIH0KCiAgICAgIHdoaWxlICgrKyRpIDwgJGNudCAmJiAkdGhpcy0+Z3JlZWRpbHlOZWVkTmV4dExpbmUoJGxpbmUpKSB7CiAgICAgICAgJGxpbmUgPSBydHJpbSAoJGxpbmUsICIgXG5cdFxyIikgLiAnICcgLiBsdHJpbSAoJFNvdXJjZVskaV0sICIgXHQiKTsKICAgICAgfQogICAgICAkaS0tOwoKCgogICAgICBpZiAoc3RycG9zICgkbGluZSwgJyMnKSkgewogICAgICAgIGlmIChzdHJwb3MgKCRsaW5lLCAnIicpID09PSBmYWxzZSAmJiBzdHJwb3MgKCRsaW5lLCAiJyIpID09PSBmYWxzZSkKICAgICAgICAgICRsaW5lID0gcHJlZ19yZXBsYWNlKCcvXHMrIyguKykkLycsJycsJGxpbmUpOwogICAgICB9CgogICAgICAkbGluZUFycmF5ID0gJHRoaXMtPl9wYXJzZUxpbmUoJGxpbmUpOwoKICAgICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSkKICAgICAgICAkbGluZUFycmF5ID0gJHRoaXMtPnJldmVydExpdGVyYWxQbGFjZUhvbGRlciAoJGxpbmVBcnJheSwgJGxpdGVyYWxCbG9jayk7CgogICAgICAkdGhpcy0+YWRkQXJyYXkoJGxpbmVBcnJheSwgJHRoaXMtPmluZGVudCk7CgogICAgICBmb3JlYWNoICgkdGhpcy0+ZGVsYXllZFBhdGggYXMgJGluZGVudCA9PiAkZGVsYXllZFBhdGgpCiAgICAgICAgJHRoaXMtPnBhdGhbJGluZGVudF0gPSAkZGVsYXllZFBhdGg7CgogICAgICAkdGhpcy0+ZGVsYXllZFBhdGggPSBhcnJheSgpOwoKICAgIH0KICAgIHJldHVybiAkdGhpcy0+cmVzdWx0OwogIH0KCiAgZnVuY3Rpb24gbG9hZEZyb21Tb3VyY2UgKCRpbnB1dCkgewogICAgaWYgKCFlbXB0eSgkaW5wdXQpICYmIHN0cnBvcygkaW5wdXQsICJcbiIpID09PSBmYWxzZSAmJiBmaWxlX2V4aXN0cygkaW5wdXQpKQogICAgcmV0dXJuIGZpbGUoJGlucHV0KTsKCiAgICByZXR1cm4gJHRoaXMtPmxvYWRGcm9tU3RyaW5nKCRpbnB1dCk7CiAgfQoKICBmdW5jdGlvbiBsb2FkRnJvbVN0cmluZyAoJGlucHV0KSB7CiAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsJGlucHV0KTsKICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkayA9PiAkXykgewogICAgICAkbGluZXNbJGtdID0gcnRyaW0gKCRfLCAiXHIiKTsKICAgIH0KICAgIHJldHVybiAkbGluZXM7CiAgfQoKICAvKioKICAgICAqIFBhcnNlcyBZQU1MIGNvZGUgYW5kIHJldHVybnMgYW4gYXJyYXkgZm9yIGEgbm9kZQogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIEEgbGluZSBmcm9tIHRoZSBZQU1MIGZpbGUKICAgICAqLwogIGZ1bmN0aW9uIF9wYXJzZUxpbmUoJGxpbmUpIHsKICAgIGlmICghJGxpbmUpIHJldHVybiBhcnJheSgpOwogICAgJGxpbmUgPSB0cmltKCRsaW5lKTsKCiAgICBpZiAoISRsaW5lKSByZXR1cm4gYXJyYXkoKTsKICAgICRhcnJheSA9IGFycmF5KCk7CgogICAgJGdyb3VwID0gJHRoaXMtPm5vZGVDb250YWluc0dyb3VwKCRsaW5lKTsKICAgIGlmICgkZ3JvdXApIHsKICAgICAgJHRoaXMtPmFkZEdyb3VwKCRsaW5lLCAkZ3JvdXApOwogICAgICAkbGluZSA9ICR0aGlzLT5zdHJpcEdyb3VwICgkbGluZSwgJGdyb3VwKTsKICAgIH0KCiAgICBpZiAoJHRoaXMtPnN0YXJ0c01hcHBlZFNlcXVlbmNlKCRsaW5lKSkKICAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5NYXBwZWRTZXF1ZW5jZSgkbGluZSk7CgogICAgaWYgKCR0aGlzLT5zdGFydHNNYXBwZWRWYWx1ZSgkbGluZSkpCiAgICAgIHJldHVybiAkdGhpcy0+cmV0dXJuTWFwcGVkVmFsdWUoJGxpbmUpOwoKICAgIGlmICgkdGhpcy0+aXNBcnJheUVsZW1lbnQoJGxpbmUpKQogICAgIHJldHVybiAkdGhpcy0+cmV0dXJuQXJyYXlFbGVtZW50KCRsaW5lKTsKCiAgICBpZiAoJHRoaXMtPmlzUGxhaW5BcnJheSgkbGluZSkpCiAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5QbGFpbkFycmF5KCRsaW5lKTsgCiAgICAgCiAgICAgCiAgICByZXR1cm4gJHRoaXMtPnJldHVybktleVZhbHVlUGFpcigkbGluZSk7CgogIH0KCiAgLyoqCiAgICAgKiBGaW5kcyB0aGUgdHlwZSBvZiB0aGUgcGFzc2VkIHZhbHVlLCByZXR1cm5zIHRoZSB2YWx1ZSBhcyB0aGUgbmV3IHR5cGUuCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICBmdW5jdGlvbiBfdG9UeXBlKCR2YWx1ZSkgewogICAgaWYgKCR2YWx1ZSA9PT0gJycpIHJldHVybiBudWxsOwogICAgJGZpcnN0X2NoYXJhY3RlciA9ICR2YWx1ZVswXTsKICAgICRsYXN0X2NoYXJhY3RlciA9IHN1YnN0cigkdmFsdWUsIC0xLCAxKTsKCiAgICAkaXNfcXVvdGVkID0gZmFsc2U7CiAgICBkbyB7CiAgICAgIGlmICghJHZhbHVlKSBicmVhazsKICAgICAgaWYgKCRmaXJzdF9jaGFyYWN0ZXIgIT0gJyInICYmICRmaXJzdF9jaGFyYWN0ZXIgIT0gIiciKSBicmVhazsKICAgICAgaWYgKCRsYXN0X2NoYXJhY3RlciAhPSAnIicgJiYgJGxhc3RfY2hhcmFjdGVyICE9ICInIikgYnJlYWs7CiAgICAgICRpc19xdW90ZWQgPSB0cnVlOwogICAgfSB3aGlsZSAoMCk7CgogICAgaWYgKCRpc19xdW90ZWQpCiAgICAgIHJldHVybiBzdHJ0cihzdWJzdHIgKCR2YWx1ZSwgMSwgLTEpLCBhcnJheSAoJ1xcIicgPT4gJyInLCAnXCdcJycgPT4gJ1wnJywgJ1xcXCcnID0+ICdcJycpKTsKICAgIAogICAgaWYgKHN0cnBvcygkdmFsdWUsICcgIycpICE9PSBmYWxzZSkKICAgICAgJHZhbHVlID0gcHJlZ19yZXBsYWNlKCcvXHMrIyguKykkLycsJycsJHZhbHVlKTsKCiAgICBpZiAoJGZpcnN0X2NoYXJhY3RlciA9PSAnWycgJiYgJGxhc3RfY2hhcmFjdGVyID09ICddJykgewogICAgICAvLyBUYWtlIG91dCBzdHJpbmdzIHNlcXVlbmNlcyBhbmQgbWFwcGluZ3MKICAgICAgJGlubmVyVmFsdWUgPSB0cmltKHN1YnN0ciAoJHZhbHVlLCAxLCAtMSkpOwogICAgICBpZiAoJGlubmVyVmFsdWUgPT09ICcnKSByZXR1cm4gYXJyYXkoKTsKICAgICAgJGV4cGxvZGUgPSAkdGhpcy0+X2lubGluZUVzY2FwZSgkaW5uZXJWYWx1ZSk7CiAgICAgIC8vIFByb3BhZ2F0ZSB2YWx1ZSBhcnJheQogICAgICAkdmFsdWUgID0gYXJyYXkoKTsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJHYpIHsKICAgICAgICAkdmFsdWVbXSA9ICR0aGlzLT5fdG9UeXBlKCR2KTsKICAgICAgfQogICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIGlmIChzdHJwb3MoJHZhbHVlLCc6ICcpIT09ZmFsc2UgJiYgJGZpcnN0X2NoYXJhY3RlciAhPSAneycpIHsKICAgICAgJGFycmF5ID0gZXhwbG9kZSgnOiAnLCR2YWx1ZSk7CiAgICAgICRrZXkgICA9IHRyaW0oJGFycmF5WzBdKTsKICAgICAgYXJyYXlfc2hpZnQoJGFycmF5KTsKICAgICAgJHZhbHVlID0gdHJpbShpbXBsb2RlKCc6ICcsJGFycmF5KSk7CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5fdG9UeXBlKCR2YWx1ZSk7CiAgICAgIHJldHVybiBhcnJheSgka2V5ID0+ICR2YWx1ZSk7CiAgICB9CiAgICAKICAgIGlmICgkZmlyc3RfY2hhcmFjdGVyID09ICd7JyAmJiAkbGFzdF9jaGFyYWN0ZXIgPT0gJ30nKSB7CiAgICAgICRpbm5lclZhbHVlID0gdHJpbShzdWJzdHIgKCR2YWx1ZSwgMSwgLTEpKTsKICAgICAgaWYgKCRpbm5lclZhbHVlID09PSAnJykgcmV0dXJuIGFycmF5KCk7CiAgICAgIC8vIElubGluZSBNYXBwaW5nCiAgICAgIC8vIFRha2Ugb3V0IHN0cmluZ3Mgc2VxdWVuY2VzIGFuZCBtYXBwaW5ncwogICAgICAkZXhwbG9kZSA9ICR0aGlzLT5faW5saW5lRXNjYXBlKCRpbm5lclZhbHVlKTsKICAgICAgLy8gUHJvcGFnYXRlIHZhbHVlIGFycmF5CiAgICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICR2KSB7CiAgICAgICAgJFN1YkFyciA9ICR0aGlzLT5fdG9UeXBlKCR2KTsKICAgICAgICBpZiAoZW1wdHkoJFN1YkFycikpIGNvbnRpbnVlOwogICAgICAgIGlmIChpc19hcnJheSAoJFN1YkFycikpIHsKICAgICAgICAgICRhcnJheVtrZXkoJFN1YkFycildID0gJFN1YkFycltrZXkoJFN1YkFycildOyBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJGFycmF5W10gPSAkU3ViQXJyOwogICAgICB9CiAgICAgIHJldHVybiAkYXJyYXk7CiAgICB9CgogICAgaWYgKCR2YWx1ZSA9PSAnbnVsbCcgfHwgJHZhbHVlID09ICdOVUxMJyB8fCAkdmFsdWUgPT0gJ051bGwnIHx8ICR2YWx1ZSA9PSAnJyB8fCAkdmFsdWUgPT0gJ34nKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIGlmIChpbnR2YWwoJGZpcnN0X2NoYXJhY3RlcikgPiAwICYmIHByZWdfbWF0Y2ggKCcvXlsxLTldK1swLTldKiQvJywgJHZhbHVlKSkgewogICAgICAkaW50dmFsdWUgPSAoaW50KSR2YWx1ZTsKICAgICAgaWYgKCRpbnR2YWx1ZSAhPSBQSFBfSU5UX01BWCkKICAgICAgICAkdmFsdWUgPSAkaW50dmFsdWU7CiAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgaWYgKGluX2FycmF5KCR2YWx1ZSwKICAgICAgICAgICAgICAgICBhcnJheSgndHJ1ZScsICdvbicsICcrJywgJ3llcycsICd5JywgJ1RydWUnLCAnVFJVRScsICdPbicsICdPTicsICdZRVMnLCAnWWVzJywgJ1knKSkpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgaWYgKGluX2FycmF5KHN0cnRvbG93ZXIoJHZhbHVlKSwKICAgICAgICAgICAgICAgICBhcnJheSgnZmFsc2UnLCAnb2ZmJywgJy0nLCAnbm8nLCAnbicpKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSkgewogICAgICBpZiAoJHZhbHVlID09PSAnMCcpIHJldHVybiAwOwogICAgICBpZiAodHJpbSAoJHZhbHVlLCAwKSA9PT0gJHZhbHVlKQogICAgICAgICR2YWx1ZSA9IChmbG9hdCkkdmFsdWU7CiAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CiAgICAKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICAvKioKICAgICAqIFVzZWQgaW4gaW5saW5lcyB0byBjaGVjayBmb3IgbW9yZSBpbmxpbmVzIG9yIHF1b3RlZCBzdHJpbmdzCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogIGZ1bmN0aW9uIF9pbmxpbmVFc2NhcGUoJGlubGluZSkgewogICAgLy8gVGhlcmUncyBnb3R0YSBiZSBhIGNsZWFuZXIgd2F5IHRvIGRvIHRoaXMuLi4KICAgIC8vIFdoaWxlIHB1cmUgc2VxdWVuY2VzIHNlZW0gdG8gYmUgbmVzdGluZyBqdXN0IGZpbmUsCiAgICAvLyBwdXJlIG1hcHBpbmdzIGFuZCBtYXBwaW5ncyB3aXRoIHNlcXVlbmNlcyBpbnNpZGUgY2FuJ3QgZ28gdmVyeQogICAgLy8gZGVlcC4gIFRoaXMgbmVlZHMgdG8gYmUgZml4ZWQuCgogICAgJHNlcXMgPSBhcnJheSgpOwogICAgJG1hcHMgPSBhcnJheSgpOwogICAgJHNhdmVkX3N0cmluZ3MgPSBhcnJheSgpOwoKICAgIC8vIENoZWNrIGZvciBzdHJpbmdzCiAgICAkcmVnZXggPSAnLyg/OigiKXwoPzpcJykpKCg/KDEpW14iXSt8W15cJ10rKSkoPygxKSJ8XCcpLyc7CiAgICBpZiAocHJlZ19tYXRjaF9hbGwoJHJlZ2V4LCRpbmxpbmUsJHN0cmluZ3MpKSB7CiAgICAgICRzYXZlZF9zdHJpbmdzID0gJHN0cmluZ3NbMF07CiAgICAgICRpbmxpbmUgID0gcHJlZ19yZXBsYWNlKCRyZWdleCwnWUFNTFN0cmluZycsJGlubGluZSk7CiAgICB9CiAgICB1bnNldCgkcmVnZXgpOwoKICAgICRpID0gMDsKICAgIGRvIHsKCiAgICAvLyBDaGVjayBmb3Igc2VxdWVuY2VzCiAgICB3aGlsZSAocHJlZ19tYXRjaCgnL1xbKFtee31cW1xdXSspXF0vVScsJGlubGluZSwkbWF0Y2hzZXFzKSkgewogICAgICAkc2Vxc1tdID0gJG1hdGNoc2Vxc1swXTsKICAgICAgJGlubGluZSA9IHByZWdfcmVwbGFjZSgnL1xbKFtee31cW1xdXSspXF0vVScsICgnWUFNTFNlcScgLiAoY291bnQoJHNlcXMpIC0gMSkgLiAncycpLCAkaW5saW5lLCAxKTsKICAgIH0KCiAgICAvLyBDaGVjayBmb3IgbWFwcGluZ3MKICAgIHdoaWxlIChwcmVnX21hdGNoKCcveyhbXlxbXF17fV0rKX0vVScsJGlubGluZSwkbWF0Y2htYXBzKSkgewogICAgICAkbWFwc1tdID0gJG1hdGNobWFwc1swXTsKICAgICAgJGlubGluZSA9IHByZWdfcmVwbGFjZSgnL3soW15cW1xde31dKyl9L1UnLCAoJ1lBTUxNYXAnIC4gKGNvdW50KCRtYXBzKSAtIDEpIC4gJ3MnKSwgJGlubGluZSwgMSk7CiAgICB9CgogICAgaWYgKCRpKysgPj0gMTApIGJyZWFrOwoKICAgIH0gd2hpbGUgKHN0cnBvcyAoJGlubGluZSwgJ1snKSAhPT0gZmFsc2UgfHwgc3RycG9zICgkaW5saW5lLCAneycpICE9PSBmYWxzZSk7CgogICAgJGV4cGxvZGUgPSBleHBsb2RlKCcsICcsJGlubGluZSk7CiAgICAkc3RyaW5naSA9IDA7ICRpID0gMDsKCiAgICB3aGlsZSAoMSkgewoKICAgIC8vIFJlLWFkZCB0aGUgc2VxdWVuY2VzCiAgICBpZiAoIWVtcHR5KCRzZXFzKSkgewogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU2VxJykgIT09IGZhbHNlKSB7CiAgICAgICAgICBmb3JlYWNoICgkc2VxcyBhcyAkc2VxayA9PiAkc2VxKSB7CiAgICAgICAgICAgICRleHBsb2RlWyRrZXldID0gc3RyX3JlcGxhY2UoKCdZQU1MU2VxJy4kc2Vxay4ncycpLCRzZXEsJHZhbHVlKTsKICAgICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8gUmUtYWRkIHRoZSBtYXBwaW5ncwogICAgaWYgKCFlbXB0eSgkbWFwcykpIHsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTE1hcCcpICE9PSBmYWxzZSkgewogICAgICAgICAgZm9yZWFjaCAoJG1hcHMgYXMgJG1hcGsgPT4gJG1hcCkgewogICAgICAgICAgICAkZXhwbG9kZVska2V5XSA9IHN0cl9yZXBsYWNlKCgnWUFNTE1hcCcuJG1hcGsuJ3MnKSwgJG1hcCwgJHZhbHVlKTsKICAgICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgoKICAgIC8vIFJlLWFkZCB0aGUgc3RyaW5ncwogICAgaWYgKCFlbXB0eSgkc2F2ZWRfc3RyaW5ncykpIHsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICB3aGlsZSAoc3RycG9zKCR2YWx1ZSwnWUFNTFN0cmluZycpICE9PSBmYWxzZSkgewogICAgICAgICAgJGV4cGxvZGVbJGtleV0gPSBwcmVnX3JlcGxhY2UoJy9ZQU1MU3RyaW5nLycsJHNhdmVkX3N0cmluZ3NbJHN0cmluZ2ldLCR2YWx1ZSwgMSk7CiAgICAgICAgICB1bnNldCgkc2F2ZWRfc3RyaW5nc1skc3RyaW5naV0pOwogICAgICAgICAgKyskc3RyaW5naTsKICAgICAgICAgICR2YWx1ZSA9ICRleHBsb2RlWyRrZXldOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgICRmaW5pc2hlZCA9IHRydWU7CiAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTFNlcScpICE9PSBmYWxzZSkgewogICAgICAgICRmaW5pc2hlZCA9IGZhbHNlOyBicmVhazsKICAgICAgfQogICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTE1hcCcpICE9PSBmYWxzZSkgewogICAgICAgICRmaW5pc2hlZCA9IGZhbHNlOyBicmVhazsKICAgICAgfQogICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTFN0cmluZycpICE9PSBmYWxzZSkgewogICAgICAgICRmaW5pc2hlZCA9IGZhbHNlOyBicmVhazsKICAgICAgfQogICAgfQogICAgaWYgKCRmaW5pc2hlZCkgYnJlYWs7CgogICAgJGkrKzsKICAgIGlmICgkaSA+IDEwKSAKICAgICAgYnJlYWs7IC8vIFByZXZlbnQgaW5maW5pdGUgbG9vcHMuCiAgICB9CgogICAgcmV0dXJuICRleHBsb2RlOwogIH0KCiAgZnVuY3Rpb24gbGl0ZXJhbEJsb2NrQ29udGludWVzICgkbGluZSwgJGxpbmVJbmRlbnQpIHsKICAgIGlmICghdHJpbSgkbGluZSkpIHJldHVybiB0cnVlOwogICAgaWYgKHN0cmxlbigkbGluZSkgLSBzdHJsZW4obHRyaW0oJGxpbmUpKSA+ICRsaW5lSW5kZW50KSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIGZ1bmN0aW9uIHJlZmVyZW5jZUNvbnRlbnRzQnlBbGlhcyAoJGFsaWFzKSB7CiAgICBkbyB7CiAgICAgIGlmICghaXNzZXQoJHRoaXMtPlNhdmVkR3JvdXBzWyRhbGlhc10pKSB7IGVjaG8gIkJhZCBncm91cCBuYW1lOiAkYWxpYXMuIjsgYnJlYWs7IH0KICAgICAgJGdyb3VwUGF0aCA9ICR0aGlzLT5TYXZlZEdyb3Vwc1skYWxpYXNdOwogICAgICAkdmFsdWUgPSAkdGhpcy0+cmVzdWx0OwogICAgICBmb3JlYWNoICgkZ3JvdXBQYXRoIGFzICRrKSB7CiAgICAgICAgJHZhbHVlID0gJHZhbHVlWyRrXTsKICAgICAgfQogICAgfSB3aGlsZSAoZmFsc2UpOwogICAgcmV0dXJuICR2YWx1ZTsKICB9CgogIGZ1bmN0aW9uIGFkZEFycmF5SW5saW5lICgkYXJyYXksICRpbmRlbnQpIHsKICAgICAgJENvbW1vbkdyb3VwUGF0aCA9ICR0aGlzLT5wYXRoOwogICAgICBpZiAoZW1wdHkgKCRhcnJheSkpIHJldHVybiBmYWxzZTsKICAgICAgCiAgICAgIGZvcmVhY2ggKCRhcnJheSBhcyAkayA9PiAkXykgewogICAgICAgICR0aGlzLT5hZGRBcnJheShhcnJheSgkayA9PiAkXyksICRpbmRlbnQpOwogICAgICAgICR0aGlzLT5wYXRoID0gJENvbW1vbkdyb3VwUGF0aDsKICAgICAgfQogICAgICByZXR1cm4gdHJ1ZTsKICB9CgogIGZ1bmN0aW9uIGFkZEFycmF5ICgkaW5jb21pbmdfZGF0YSwgJGluY29taW5nX2luZGVudCkgewoKICAgLy8gcHJpbnRfciAoJGluY29taW5nX2RhdGEpOwoKICAgIGlmIChjb3VudCAoJGluY29taW5nX2RhdGEpID4gMSkKICAgICAgcmV0dXJuICR0aGlzLT5hZGRBcnJheUlubGluZSAoJGluY29taW5nX2RhdGEsICRpbmNvbWluZ19pbmRlbnQpOwogICAgCiAgICAka2V5ID0ga2V5ICgkaW5jb21pbmdfZGF0YSk7CiAgICAkdmFsdWUgPSBpc3NldCgkaW5jb21pbmdfZGF0YVska2V5XSkgPyAkaW5jb21pbmdfZGF0YVska2V5XSA6IG51bGw7CiAgICBpZiAoJGtleSA9PT0gJ19fIVlBTUxaZXJvJykgJGtleSA9ICcwJzsKCiAgICBpZiAoJGluY29taW5nX2luZGVudCA9PSAwICYmICEkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcyAmJiAhJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yKSB7IC8vIFNob3J0Y3V0IGZvciByb290LWxldmVsIHZhbHVlcy4KICAgICAgaWYgKCRrZXkgfHwgJGtleSA9PT0gJycgfHwgJGtleSA9PT0gJzAnKSB7CiAgICAgICAgJHRoaXMtPnJlc3VsdFska2V5XSA9ICR2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICAkdGhpcy0+cmVzdWx0W10gPSAkdmFsdWU7IGVuZCAoJHRoaXMtPnJlc3VsdCk7ICRrZXkgPSBrZXkgKCR0aGlzLT5yZXN1bHQpOwogICAgICB9CiAgICAgICR0aGlzLT5wYXRoWyRpbmNvbWluZ19pbmRlbnRdID0gJGtleTsKICAgICAgcmV0dXJuOwogICAgfQoKCiAgICAKICAgICRoaXN0b3J5ID0gYXJyYXkoKTsKICAgIC8vIFVuZm9sZGluZyBpbm5lciBhcnJheSB0cmVlLgogICAgJGhpc3RvcnlbXSA9ICRfYXJyID0gJHRoaXMtPnJlc3VsdDsKICAgIGZvcmVhY2ggKCR0aGlzLT5wYXRoIGFzICRrKSB7CiAgICAgICRoaXN0b3J5W10gPSAkX2FyciA9ICRfYXJyWyRrXTsKICAgIH0KCiAgICBpZiAoJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMpIHsKICAgICAgJHZhbHVlID0gJHRoaXMtPnJlZmVyZW5jZUNvbnRlbnRzQnlBbGlhcygkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcyk7CiAgICAgICR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzID0gZmFsc2U7CiAgICB9CgoKICAgIC8vIEFkZGluZyBzdHJpbmcgb3IgbnVtZXJpYyBrZXkgdG8gdGhlIGlubmVybW9zdCBsZXZlbCBvciAkdGhpcy0+YXJyLgogICAgaWYgKGlzX3N0cmluZygka2V5KSAmJiAka2V5ID09ICc8PCcpIHsKICAgICAgaWYgKCFpc19hcnJheSAoJF9hcnIpKSB7ICRfYXJyID0gYXJyYXkgKCk7IH0KICAgICAgJF9hcnIgPSBhcnJheV9tZXJnZSAoJF9hcnIsICR2YWx1ZSk7CiAgICB9IGVsc2UgaWYgKCRrZXkgfHwgJGtleSA9PT0gJycgfHwgJGtleSA9PT0gJzAnKSB7CiAgICAgICRfYXJyWyRrZXldID0gJHZhbHVlOwogICAgfSBlbHNlIHsKICAgICAgaWYgKCFpc19hcnJheSAoJF9hcnIpKSB7ICRfYXJyID0gYXJyYXkgKCR2YWx1ZSk7ICRrZXkgPSAwOyB9CiAgICAgIGVsc2UgeyAkX2FycltdID0gJHZhbHVlOyBlbmQgKCRfYXJyKTsgJGtleSA9IGtleSAoJF9hcnIpOyB9CiAgICB9CgogICAgJHJldmVyc2VfcGF0aCA9IGFycmF5X3JldmVyc2UoJHRoaXMtPnBhdGgpOwogICAgJHJldmVyc2VfaGlzdG9yeSA9IGFycmF5X3JldmVyc2UgKCRoaXN0b3J5KTsKICAgICRyZXZlcnNlX2hpc3RvcnlbMF0gPSAkX2FycjsKICAgICRjbnQgPSBjb3VudCgkcmV2ZXJzZV9oaXN0b3J5KSAtIDE7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkY250OyAkaSsrKSB7CiAgICAgICRyZXZlcnNlX2hpc3RvcnlbJGkrMV1bJHJldmVyc2VfcGF0aFskaV1dID0gJHJldmVyc2VfaGlzdG9yeVskaV07CiAgICB9CiAgICAkdGhpcy0+cmVzdWx0ID0gJHJldmVyc2VfaGlzdG9yeVskY250XTsKCiAgICAkdGhpcy0+cGF0aFskaW5jb21pbmdfaW5kZW50XSA9ICRrZXk7CgogICAgaWYgKCR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvcikgewogICAgICAkdGhpcy0+U2F2ZWRHcm91cHNbJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yXSA9ICR0aGlzLT5wYXRoOwogICAgICBpZiAoaXNfYXJyYXkgKCR2YWx1ZSkpIHsKICAgICAgICAkayA9IGtleSAoJHZhbHVlKTsKICAgICAgICBpZiAoIWlzX2ludCAoJGspKSB7CiAgICAgICAgICAkdGhpcy0+U2F2ZWRHcm91cHNbJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yXVskaW5jb21pbmdfaW5kZW50ICsgMl0gPSAkazsKICAgICAgICB9CiAgICAgIH0KICAgICAgJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yID0gZmFsc2U7CiAgICB9CgogIH0KCiAgZnVuY3Rpb24gc3RhcnRzTGl0ZXJhbEJsb2NrICgkbGluZSkgewogICAgJGxhc3RDaGFyID0gc3Vic3RyICh0cmltKCRsaW5lKSwgLTEpOwogICAgaWYgKCRsYXN0Q2hhciAhPSAnPicgJiYgJGxhc3RDaGFyICE9ICd8JykgcmV0dXJuIGZhbHNlOwogICAgaWYgKCRsYXN0Q2hhciA9PSAnfCcpIHJldHVybiAkbGFzdENoYXI7CiAgICAvLyBIVE1MIHRhZ3Mgc2hvdWxkIG5vdCBiZSBjb3VudGVkIGFzIGxpdGVyYWwgYmxvY2tzLgogICAgaWYgKHByZWdfbWF0Y2ggKCcjPC4qPz4kIycsICRsaW5lKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuICRsYXN0Q2hhcjsKICB9CgogIGZ1bmN0aW9uIGdyZWVkaWx5TmVlZE5leHRMaW5lKCRsaW5lKSB7CiAgICAkbGluZSA9IHRyaW0gKCRsaW5lKTsKICAgIGlmICghc3RybGVuKCRsaW5lKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnXScpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGluZVswXSA9PSAnWycpIHJldHVybiB0cnVlOwogICAgaWYgKHByZWdfbWF0Y2ggKCcjXlteOl0rPzpccypcWyMnLCAkbGluZSkpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgZnVuY3Rpb24gYWRkTGl0ZXJhbExpbmUgKCRsaXRlcmFsQmxvY2ssICRsaW5lLCAkbGl0ZXJhbEJsb2NrU3R5bGUpIHsKICAgICRsaW5lID0gJHRoaXMtPnN0cmlwSW5kZW50KCRsaW5lKTsKICAgICRsaW5lID0gcnRyaW0gKCRsaW5lLCAiXHJcblx0ICIpIC4gIlxuIjsKICAgIGlmICgkbGl0ZXJhbEJsb2NrU3R5bGUgPT0gJ3wnKSB7CiAgICAgIHJldHVybiAkbGl0ZXJhbEJsb2NrIC4gJGxpbmU7CiAgICB9CiAgICBpZiAoc3RybGVuKCRsaW5lKSA9PSAwKQogICAgICByZXR1cm4gcnRyaW0oJGxpdGVyYWxCbG9jaywgJyAnKSAuICJcbiI7CiAgICBpZiAoJGxpbmUgPT0gIlxuIiAmJiAkbGl0ZXJhbEJsb2NrU3R5bGUgPT0gJz4nKSB7CiAgICAgIHJldHVybiBydHJpbSAoJGxpdGVyYWxCbG9jaywgIiBcdCIpIC4gIlxuIjsKICAgIH0KICAgIGlmICgkbGluZSAhPSAiXG4iKQogICAgICAkbGluZSA9IHRyaW0gKCRsaW5lLCAiXHJcbiAiKSAuICIgIjsKICAgIHJldHVybiAkbGl0ZXJhbEJsb2NrIC4gJGxpbmU7CiAgfQoKICAgZnVuY3Rpb24gcmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkbGluZUFycmF5LCAkbGl0ZXJhbEJsb2NrKSB7CiAgICAgZm9yZWFjaCAoJGxpbmVBcnJheSBhcyAkayA9PiAkXykgewogICAgICBpZiAoaXNfYXJyYXkoJF8pKQogICAgICAgICRsaW5lQXJyYXlbJGtdID0gJHRoaXMtPnJldmVydExpdGVyYWxQbGFjZUhvbGRlciAoJF8sICRsaXRlcmFsQmxvY2spOwogICAgICBlbHNlIGlmIChzdWJzdHIoJF8sIC0xICogc3RybGVuICgkdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyKSkgPT0gJHRoaXMtPkxpdGVyYWxQbGFjZUhvbGRlcikKCSAgICAgICAkbGluZUFycmF5WyRrXSA9IHJ0cmltICgkbGl0ZXJhbEJsb2NrLCAiIFxyXG4iKTsKICAgICB9CiAgICAgcmV0dXJuICRsaW5lQXJyYXk7CiAgIH0KCiAgZnVuY3Rpb24gc3RyaXBJbmRlbnQgKCRsaW5lLCAkaW5kZW50ID0gLTEpIHsKICAgIGlmICgkaW5kZW50ID09IC0xKSAkaW5kZW50ID0gc3RybGVuKCRsaW5lKSAtIHN0cmxlbihsdHJpbSgkbGluZSkpOwogICAgcmV0dXJuIHN1YnN0ciAoJGxpbmUsICRpbmRlbnQpOwogIH0KCiAgZnVuY3Rpb24gZ2V0UGFyZW50UGF0aEJ5SW5kZW50ICgkaW5kZW50KSB7CiAgICBpZiAoJGluZGVudCA9PSAwKSByZXR1cm4gYXJyYXkoKTsKICAgICRsaW5lUGF0aCA9ICR0aGlzLT5wYXRoOwogICAgZG8gewogICAgICBlbmQoJGxpbmVQYXRoKTsgJGxhc3RJbmRlbnRJblBhcmVudFBhdGggPSBrZXkoJGxpbmVQYXRoKTsKICAgICAgaWYgKCRpbmRlbnQgPD0gJGxhc3RJbmRlbnRJblBhcmVudFBhdGgpIGFycmF5X3BvcCAoJGxpbmVQYXRoKTsKICAgIH0gd2hpbGUgKCRpbmRlbnQgPD0gJGxhc3RJbmRlbnRJblBhcmVudFBhdGgpOwogICAgcmV0dXJuICRsaW5lUGF0aDsKICB9CgoKICBmdW5jdGlvbiBjbGVhckJpZ2dlclBhdGhWYWx1ZXMgKCRpbmRlbnQpIHsKCgogICAgaWYgKCRpbmRlbnQgPT0gMCkgJHRoaXMtPnBhdGggPSBhcnJheSgpOwogICAgaWYgKGVtcHR5ICgkdGhpcy0+cGF0aCkpIHJldHVybiB0cnVlOwoKICAgIGZvcmVhY2ggKCR0aGlzLT5wYXRoIGFzICRrID0+ICRfKSB7CiAgICAgIGlmICgkayA+ICRpbmRlbnQpIHVuc2V0ICgkdGhpcy0+cGF0aFska10pOwogICAgfQoKICAgIHJldHVybiB0cnVlOwogIH0KCgogIGZ1bmN0aW9uIGlzQ29tbWVudCAoJGxpbmUpIHsKICAgIGlmICghJGxpbmUpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGluZVswXSA9PSAnIycpIHJldHVybiB0cnVlOwogICAgaWYgKHRyaW0oJGxpbmUsICIgXHJcblx0IikgPT0gJy0tLScpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgZnVuY3Rpb24gaXNFbXB0eSAoJGxpbmUpIHsKICAgIHJldHVybiAodHJpbSAoJGxpbmUpID09PSAnJyk7CiAgfQoKCiAgZnVuY3Rpb24gaXNBcnJheUVsZW1lbnQgKCRsaW5lKSB7CiAgICBpZiAoISRsaW5lKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJGxpbmVbMF0gIT0gJy0nKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoc3RybGVuICgkbGluZSkgPiAzKQogICAgICBpZiAoc3Vic3RyKCRsaW5lLDAsMykgPT0gJy0tLScpIHJldHVybiBmYWxzZTsKICAgIAogICAgcmV0dXJuIHRydWU7CiAgfQoKICBmdW5jdGlvbiBpc0hhc2hFbGVtZW50ICgkbGluZSkgewogICAgcmV0dXJuIHN0cnBvcygkbGluZSwgJzonKTsKICB9CgogIGZ1bmN0aW9uIGlzTGl0ZXJhbCAoJGxpbmUpIHsKICAgIGlmICgkdGhpcy0+aXNBcnJheUVsZW1lbnQoJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJHRoaXMtPmlzSGFzaEVsZW1lbnQoJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgoKICBmdW5jdGlvbiB1bnF1b3RlICgkdmFsdWUpIHsKICAgIGlmICghJHZhbHVlKSByZXR1cm4gJHZhbHVlOwogICAgaWYgKCFpc19zdHJpbmcoJHZhbHVlKSkgcmV0dXJuICR2YWx1ZTsKICAgIGlmICgkdmFsdWVbMF0gPT0gJ1wnJykgcmV0dXJuIHRyaW0gKCR2YWx1ZSwgJ1wnJyk7CiAgICBpZiAoJHZhbHVlWzBdID09ICciJykgcmV0dXJuIHRyaW0gKCR2YWx1ZSwgJyInKTsKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICBmdW5jdGlvbiBzdGFydHNNYXBwZWRTZXF1ZW5jZSAoJGxpbmUpIHsKICAgIHJldHVybiAoJGxpbmVbMF0gPT0gJy0nICYmIHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnOicpOwogIH0KCiAgZnVuY3Rpb24gcmV0dXJuTWFwcGVkU2VxdWVuY2UgKCRsaW5lKSB7CiAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgJGtleSAgICAgICAgID0gJHRoaXMtPnVucXVvdGUodHJpbShzdWJzdHIoJGxpbmUsMSwtMSkpKTsKICAgICRhcnJheVska2V5XSA9IGFycmF5KCk7CiAgICAkdGhpcy0+ZGVsYXllZFBhdGggPSBhcnJheShzdHJwb3MgKCRsaW5lLCAka2V5KSArICR0aGlzLT5pbmRlbnQgPT4gJGtleSk7CiAgICByZXR1cm4gYXJyYXkoJGFycmF5KTsKICB9CgogIGZ1bmN0aW9uIHJldHVybk1hcHBlZFZhbHVlICgkbGluZSkgewogICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICRrZXkgICAgICAgICA9ICR0aGlzLT51bnF1b3RlICh0cmltKHN1YnN0cigkbGluZSwwLC0xKSkpOwogICAgJGFycmF5WyRrZXldID0gJyc7CiAgICByZXR1cm4gJGFycmF5OwogIH0KCiAgZnVuY3Rpb24gc3RhcnRzTWFwcGVkVmFsdWUgKCRsaW5lKSB7CiAgICByZXR1cm4gKHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnOicpOwogIH0KICAKICBmdW5jdGlvbiBpc1BsYWluQXJyYXkgKCRsaW5lKSB7CiAgICByZXR1cm4gKCRsaW5lWzBdID09ICdbJyAmJiBzdWJzdHIgKCRsaW5lLCAtMSwgMSkgPT0gJ10nKTsKICB9CiAgCiAgZnVuY3Rpb24gcmV0dXJuUGxhaW5BcnJheSAoJGxpbmUpIHsKICAgIHJldHVybiAkdGhpcy0+X3RvVHlwZSgkbGluZSk7IAogIH0gIAoKICBmdW5jdGlvbiByZXR1cm5LZXlWYWx1ZVBhaXIgKCRsaW5lKSB7CiAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgJGtleSA9ICcnOwogICAgaWYgKHN0cnBvcyAoJGxpbmUsICc6JykpIHsKICAgICAgLy8gSXQncyBhIGtleS92YWx1ZSBwYWlyIG1vc3QgbGlrZWx5CiAgICAgIC8vIElmIHRoZSBrZXkgaXMgaW4gZG91YmxlIHF1b3RlcyBwdWxsIGl0IG91dAogICAgICBpZiAoKCRsaW5lWzBdID09ICciJyB8fCAkbGluZVswXSA9PSAiJyIpICYmIHByZWdfbWF0Y2goJy9eKFsiXCddKC4qKVsiXCddKFxzKSo6KS8nLCRsaW5lLCRtYXRjaGVzKSkgewogICAgICAgICR2YWx1ZSA9IHRyaW0oc3RyX3JlcGxhY2UoJG1hdGNoZXNbMV0sJycsJGxpbmUpKTsKICAgICAgICAka2V5ICAgPSAkbWF0Y2hlc1syXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBEbyBzb21lIGd1ZXNzd29yayBhcyB0byB0aGUga2V5IGFuZCB0aGUgdmFsdWUKICAgICAgICAkZXhwbG9kZSA9IGV4cGxvZGUoJzonLCRsaW5lKTsKICAgICAgICAka2V5ICAgICA9IHRyaW0oJGV4cGxvZGVbMF0pOwogICAgICAgIGFycmF5X3NoaWZ0KCRleHBsb2RlKTsKICAgICAgICAkdmFsdWUgICA9IHRyaW0oaW1wbG9kZSgnOicsJGV4cGxvZGUpKTsKICAgICAgfQogICAgICAvLyBTZXQgdGhlIHR5cGUgb2YgdGhlIHZhbHVlLiAgSW50LCBzdHJpbmcsIGV0YwogICAgICAkdmFsdWUgPSAkdGhpcy0+X3RvVHlwZSgkdmFsdWUpOwogICAgICBpZiAoJGtleSA9PT0gJzAnKSAka2V5ID0gJ19fIVlBTUxaZXJvJzsKICAgICAgJGFycmF5WyRrZXldID0gJHZhbHVlOwogICAgfSBlbHNlIHsKICAgICAgJGFycmF5ID0gYXJyYXkgKCRsaW5lKTsKICAgIH0KICAgIHJldHVybiAkYXJyYXk7CgogIH0KCgogIGZ1bmN0aW9uIHJldHVybkFycmF5RWxlbWVudCAoJGxpbmUpIHsKICAgICBpZiAoc3RybGVuKCRsaW5lKSA8PSAxKSByZXR1cm4gYXJyYXkoYXJyYXkoKSk7IC8vIFdlaXJkICUpCiAgICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICAkdmFsdWUgICA9IHRyaW0oc3Vic3RyKCRsaW5lLDEpKTsKICAgICAkdmFsdWUgICA9ICR0aGlzLT5fdG9UeXBlKCR2YWx1ZSk7CiAgICAgJGFycmF5W10gPSAkdmFsdWU7CiAgICAgcmV0dXJuICRhcnJheTsKICB9CgoKICBmdW5jdGlvbiBub2RlQ29udGFpbnNHcm91cCAoJGxpbmUpIHsgICAgCiAgICAkc3ltYm9sc0ZvclJlZmVyZW5jZSA9ICdBLXowLTlfXC0nOwogICAgaWYgKHN0cnBvcygkbGluZSwgJyYnKSA9PT0gZmFsc2UgJiYgc3RycG9zKCRsaW5lLCAnKicpID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlOyAvLyBQbGVhc2UgZGllIGZhc3QgOy0pCiAgICBpZiAoJGxpbmVbMF0gPT0gJyYnICYmIHByZWdfbWF0Y2goJy9eKCZbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmICgkbGluZVswXSA9PSAnKicgJiYgcHJlZ19tYXRjaCgnL14oXCpbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoKCcvKCZbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspJC8nLCAkbGluZSwgJG1hdGNoZXMpKSByZXR1cm4gJG1hdGNoZXNbMV07CiAgICBpZiAocHJlZ19tYXRjaCgnLyhcKlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKyQpLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoICgnI15ccyo8PFxzKjpccyooXCpbXlxzXSspLiokIycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIHJldHVybiBmYWxzZTsKCiAgfQoKICBmdW5jdGlvbiBhZGRHcm91cCAoJGxpbmUsICRncm91cCkgewogICAgaWYgKCRncm91cFswXSA9PSAnJicpICR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvciA9IHN1YnN0ciAoJGdyb3VwLCAxKTsKICAgIGlmICgkZ3JvdXBbMF0gPT0gJyonKSAkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcyA9IHN1YnN0ciAoJGdyb3VwLCAxKTsKICAgIC8vcHJpbnRfciAoJHRoaXMtPnBhdGgpOwogIH0KCiAgZnVuY3Rpb24gc3RyaXBHcm91cCAoJGxpbmUsICRncm91cCkgewogICAgJGxpbmUgPSB0cmltKHN0cl9yZXBsYWNlKCRncm91cCwgJycsICRsaW5lKSk7CiAgICByZXR1cm4gJGxpbmU7CiAgfQp9CgovLyBFbmFibGUgdXNlIG9mIFNweWMgZnJvbSBjb21tYW5kIGxpbmUKLy8gVGhlIHN5bnRheCBpcyB0aGUgZm9sbG93aW5nOiBwaHAgc3B5Yy5waHAgc3B5Yy55YW1sCgpkZWZpbmUgKCdTUFlDX0ZST01fQ09NTUFORF9MSU5FJywgZmFsc2UpOwoKZG8gewogIGlmICghU1BZQ19GUk9NX0NPTU1BTkRfTElORSkgYnJlYWs7CiAgaWYgKGVtcHR5ICgkX1NFUlZFUlsnYXJnYyddKSB8fCAkX1NFUlZFUlsnYXJnYyddIDwgMikgYnJlYWs7CiAgaWYgKGVtcHR5ICgkX1NFUlZFUlsnUEhQX1NFTEYnXSkgfHwgJF9TRVJWRVJbJ1BIUF9TRUxGJ10gIT0gJ3NweWMucGhwJykgYnJlYWs7CiAgJGZpbGUgPSAkYXJndlsxXTsKICBwcmludGYgKCJTcHljIGxvYWRpbmcgZmlsZTogJXNcbiIsICRmaWxlKTsKICBwcmludF9yIChzcHljX2xvYWRfZmlsZSAoJGZpbGUpKTsKfSB3aGlsZSAoMCk7PD9waHAKIwojICAgIFMgUCBZIEMKIyAgICAgIGEgc2ltcGxlIHBocCB5YW1sIGNsYXNzCiMgICB2MC4zCiMKIyBhdXRob3I6IFtjaHJpcyB3YW5zdHJhdGgsIGNocmlzQG96bW0ub3JnXQojIHdlYnNpdGVzOiBbaHR0cDovL3d3dy55YW1sLm9yZywgaHR0cDovL3NweWMuc291cmNlZm9yZ2UubmV0L10KIyBsaWNlbnNlOiBbTUlUIExpY2Vuc2UsIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXQojIGNvcHlyaWdodDogKGMpIDIwMDUtMjAwNiBDaHJpcyBXYW5zdHJhdGgKIwojIFdlJ3JlIGdvbm5hIGxvYWQgYSBmaWxlIGludG8gbWVtb3J5IGFuZCBzZWUgaWYgd2UgZ2V0IHdoYXQgd2UgZXhwZWN0LgojIElmIG5vdCwgd2UncmUgZ29ubmEgY29tcGxhaW4uCiMKIyBQcmV0dHkgbG8tZmkuICBMZXQncyBzZWUgaWYgd2UgY2FuJ3QgZ2V0IHNvbWUgdW5pdCB0ZXN0aW5nIGdvaW5nIGluIHRoZSBuZXh0LAojIEkgZHVubm8sIDIwIG1vbnRocz8gIEFscmlnaHQuICBHbyB0ZWFtLgojCgplcnJvcl9yZXBvcnRpbmcoRV9BTEwpOwoKaW5jbHVkZSgnc3B5Yy5waHA0Jyk7CgokeWFtbCA9IFNweWM6OllBTUxMb2FkKCcuLi9zcHljLnlhbWwnKTsKCi8vIHByaW50X3IgKCR5YW1sKTsKCiMgQWRkZWQgaW4gLjIKaWYgKCR5YW1sWzEwNDBdICE9ICJPb28sIGEgbnVtZXJpYyBrZXkhIikKCWRpZSgnS2V5OiAxMDQwIGZhaWxlZCcpOwoKIyBUZXN0IG1hcHBpbmdzIC8gdHlwZXMKaWYgKCR5YW1sWydTdHJpbmcnXSAhPSAiQW55b25lJ3MgbmFtZSwgcmVhbGx5LiIpCglkaWUoJ0tleTogU3RyaW5nIGZhaWxlZCcpOwoKaWYgKCR5YW1sWydJbnQnXSAhPT0gMTMpCglkaWUoJ0tleTogSW50IGZhaWxlZCcpOwoKaWYgKCR5YW1sWydUcnVlJ10gIT09IHRydWUpCglkaWUoJ0tleTogVHJ1ZSBmYWlsZWQnKTsKCmlmICgkeWFtbFsnRmFsc2UnXSAhPT0gZmFsc2UpCglkaWUoJ0tleTogRmFsc2UgZmFpbGVkJyk7CgppZiAoJHlhbWxbJ1plcm8nXSAhPT0gMCkKCWRpZSgnS2V5OiBaZXJvIGZhaWxlZCcpOwoKaWYgKGlzc2V0KCR5YW1sWydOdWxsJ10pKQoJZGllKCdLZXk6IE51bGwgZmFpbGVkJyk7CgppZiAoJHlhbWxbJ0Zsb2F0J10gIT09IDUuMzQpCglkaWUoJ0tleTogRmxvYXQgZmFpbGVkJyk7CgoKIyBUZXN0IHNlcXVlbmNlcwppZiAoJHlhbWxbMF0gIT0gIlBIUCBDbGFzcyIpCglkaWUoJ1NlcXVlbmNlIDAgZmFpbGVkJyk7CgppZiAoJHlhbWxbMV0gIT0gIkJhc2ljIFlBTUwgTG9hZGVyIikKCWRpZSgnU2VxdWVuY2UgMSBmYWlsZWQnKTsKCmlmICgkeWFtbFsyXSAhPSAiVmVyeSBCYXNpYyBZQU1MIER1bXBlciIpCglkaWUoJ1NlcXVlbmNlIDIgZmFpbGVkJyk7CgojIEEgc2VxdWVuY2Ugb2YgYSBzZXF1ZW5jZQppZiAoJHlhbWxbM10gIT0gYXJyYXkoIllBTUwgaXMgc28gZWFzeSB0byBsZWFybi4iLAoJCQkJCQkJCQkJCSJZb3VyIGNvbmZpZyBmaWxlcyB3aWxsIG5ldmVyIGJlIHRoZSBzYW1lLiIpKQoJZGllKCdTZXF1ZW5jZSAzIGZhaWxlZCcpOwoKIyBTZXF1ZW5jZSBvZiBtYXBwaW5ncwppZiAoJHlhbWxbNF0gIT0gYXJyYXkoImNwdSIgPT4gIjEuNWdoeiIsICJyYW0iID0+ICIxIGdpZyIsCgkJCQkJCQkJCQkJIm9zIiA9PiAib3MgeCAxMC40LjEiKSkKCWRpZSgnU2VxdWVuY2UgNCBmYWlsZWQnKTsKCiMgTWFwcGVkIHNlcXVlbmNlCmlmICgkeWFtbFsnZG9tYWlucyddICE9IGFycmF5KCJ5YW1sLm9yZyIsICJwaHAubmV0IikpCglkaWUoIktleTogJ2RvbWFpbnMnIGZhaWxlZCIpOwoKIyBBIHNlcXVlbmNlIGxpa2UgdGhpcy4KaWYgKCR5YW1sWzVdICE9IGFycmF5KCJwcm9ncmFtIiA9PiAiQWRpdW0iLCAicGxhdGZvcm0iID0+ICJPUyBYIiwKCQkJCQkJCQkJCQkidHlwZSIgPT4gIkNoYXQgQ2xpZW50IikpCglkaWUoJ1NlcXVlbmNlIDUgZmFpbGVkJyk7CgojIEEgZm9sZGVkIGJsb2NrIGFzIGEgbWFwcGVkIHZhbHVlCmlmICgkeWFtbFsnbm8gdGltZSddICE9ICJUaGVyZSBpc24ndCBhbnkgdGltZSBmb3IgeW91ciB0cmlja3MhXG5EbyB5b3UgdW5kZXJzdGFuZD8iKQoJZGllKCJLZXk6ICdubyB0aW1lJyBmYWlsZWQiKTsKCiMgQSBsaXRlcmFsIGJsb2NrIGFzIGEgbWFwcGVkIHZhbHVlCmlmICgkeWFtbFsnc29tZSB0aW1lJ10gIT0gIlRoZXJlIGlzIG5vdGhpbmcgYnV0IHRpbWVcbmZvciB5b3VyIHRyaWNrcy4iKQoJZGllKCJLZXk6ICdzb21lIHRpbWUnIGZhaWxlZCIpOwoKIyBDcmF6eSBjb21iaW5hdGlvbnMKaWYgKCR5YW1sWydkYXRhYmFzZXMnXSAhPSBhcnJheSggYXJyYXkoIm5hbWUiID0+ICJzcGFydGFuIiwgIm5vdGVzIiA9PgoJCQkJCQkJCQkJCQkJCQkJCQkJYXJyYXkoICJOZWVkcyB0byBiZSBiYWNrZWQgdXAiLAoJCQkJCQkJCQkJCQkJCQkJCQkJCQkJICJOZWVkcyB0byBiZSBub3JtYWxpemVkIiApLAoJCQkJCQkJCQkJCQkJCQkJCQkJICJ0eXBlIiA9PiAibXlzcWwiICkpKQogIGRpZSgiS2V5OiAnZGF0YWJhc2VzJyBmYWlsZWQiKTsKCiMgWW91IGNhbiBiZSBhIGJpdCB0cmlja3kKaWYgKCR5YW1sWyJpZjogeW91J2QiXSAhPSAibGlrZSIpCglkaWUoIktleTogJ2lmOiB5b3VcJ2QnIGZhaWxlZCIpOwoKIyBJbmxpbmUgc2VxdWVuY2VzCmlmICgkeWFtbFs2XSAhPSBhcnJheSgiT25lIiwgIlR3byIsICJUaHJlZSIsICJGb3VyIikpCglkaWUoIlNlcXVlbmNlIDYgZmFpbGVkIik7CgojIE5lc3RlZCBJbmxpbmUgU2VxdWVuY2VzCmlmICgkeWFtbFs3XSAhPSBhcnJheSgiT25lIiwgYXJyYXkoIlR3byIsICJBbmQiLCAiVGhyZWUiKSwgIkZvdXIiLCAiRml2ZSIpKQoJZGllKCJTZXF1ZW5jZSA3IGZhaWxlZCIpOwoKIyBOZXN0ZWQgTmVzdGVkIElubGluZSBTZXF1ZW5jZXMKaWYgKCR5YW1sWzhdICE9IGFycmF5KCAiVGhpcyIsIGFycmF5KCJJcyIsICJHZXR0aW5nIiwgYXJyYXkoIlJpZGljdWxvdXMiLCAiR3V5cyIpKSwKCQkJCQkJCQkJIlNlcmlvdXNseSIsIGFycmF5KCJTaG93IiwgIk1lcmN5IikpKQoJZGllKCJTZXF1ZW5jZSA4IGZhaWxlZCIpOwoKIyBJbmxpbmUgbWFwcGluZ3MKaWYgKCR5YW1sWzldICE9IGFycmF5KCJuYW1lIiA9PiAiY2hyaXMiLCAiYWdlIiA9PiAieW91bmciLCAiYnJhbmQiID0+ICJsdWNreSBzdHJpa2UiKSkKCWRpZSgiU2VxdWVuY2UgOSBmYWlsZWQiKTsKCiMgTmVzdGVkIGlubGluZSBtYXBwaW5ncwppZiAoJHlhbWxbMTBdICE9IGFycmF5KCJuYW1lIiA9PiAibWFyayIsICJhZ2UiID0+ICJvbGRlciB0aGFuIGNocmlzIiwKCQkJCQkJCQkJCQkgImJyYW5kIiA9PiBhcnJheSgibWFybGJvcm8iLCAibHVja3kgc3RyaWtlIikpKQoJZGllKCJTZXF1ZW5jZSAxMCBmYWlsZWQiKTsKCiMgUmVmZXJlbmNlcyAtLSB0aGV5J3JlIHNoYWt5LCBidXQgZnVuY3Rpb25hbAppZiAoJHlhbWxbJ2R5bmFtaWMgbGFuZ3VhZ2VzJ10gIT0gYXJyYXkoJ1BlcmwnLCAnUHl0aG9uJywgJ1BIUCcsICdSdWJ5JykpCglkaWUoIktleTogJ2R5bmFtaWMgbGFuZ3VhZ2VzJyBmYWlsZWQiKTsKCmlmICgkeWFtbFsnY29tcGlsZWQgbGFuZ3VhZ2VzJ10gIT0gYXJyYXkoJ0MvQysrJywgJ0phdmEnKSkKCWRpZSgiS2V5OiAnY29tcGlsZWQgbGFuZ3VhZ2VzJyBmYWlsZWQiKTsKCmlmICgkeWFtbFsnYWxsIGxhbmd1YWdlcyddICE9IGFycmF5KAoJCQkJCQkJCQkJCQkJCQkJCQlhcnJheSgnUGVybCcsICdQeXRob24nLCAnUEhQJywgJ1J1YnknKSwKCQkJCQkJCQkJCQkJCQkJCQkJYXJyYXkoJ0MvQysrJywgJ0phdmEnKQoJCQkJCQkJCQkJCQkJCQkJCSApKQoJZGllKCJLZXk6ICdhbGwgbGFuZ3VhZ2VzJyBmYWlsZWQiKTsKCiMgQWRkZWQgaW4gLjIuMjogRXNjYXBlZCBxdW90ZXMKaWYgKCR5YW1sWzExXSAhPSAieW91IGtub3csIHRoaXMgc2hvdWxkbid0IHdvcmsuICBidXQgaXQgZG9lcy4iKQoJZGllKCJTZXF1ZW5jZSAxMSBmYWlsZWQuIik7CgppZiAoJHlhbWxbMTJdICE9ICJ0aGF0J3MgbXkgdmFsdWUuIikKCWRpZSgiU2VxdWVuY2UgMTIgZmFpbGVkLiIpOwoKaWYgKCR5YW1sWzEzXSAhPSAiYWdhaW4sIHRoYXQncyBteSB2YWx1ZS4iKQoJZGllKCJTZXF1ZW5jZSAxMyBmYWlsZWQuIik7CgppZiAoJHlhbWxbMTRdICE9ICJoZXJlJ3MgdG8gXCJxdW90ZXNcIiwgYm9zcy4iKQoJZGllKCJTZXF1ZW5jZSAxNCBmYWlsZWQuIik7CgppZiAoJHlhbWxbMTVdICE9IGFycmF5KCAnbmFtZScgPT4gIkZvbywgQmFyJ3MiLCAnYWdlJyA9PiAyMCkpCglkaWUoIlNlcXVlbmNlIDE1IGZhaWxlZC4iKTsKCmlmICgkeWFtbFsxNl0gIT0gYXJyYXkoIDAgPT4gImEiLCAxID0+IGFycmF5ICgwID0+IDEsIDEgPT4gMiksIDIgPT4gImIiKSkKCWRpZSgiU2VxdWVuY2UgMTYgZmFpbGVkLiIpOwoKaWYgKCR5YW1sWydlbmRsb29wJ10gIT0gIkRvZXMgdGhpcyBsaW5lIGluIHRoZSBlbmQgaW5kZWVkIG1ha2UgU3B5YyBnbyB0byBhbiBpbmZpbml0ZSBsb29wPyIpCglkaWUoIltlbmRsb29wXSBmYWlsZWQuIik7CgoKcHJpbnQgInNweWMueWFtbCBwYXJzZWQgY29ycmVjdGx5XG4iOwoKPz48P3BocCBuYW1lc3BhY2UgTXVzdGFuZ29zdGFuZzsKLyoqCiAgICogU3B5YyAtLSBBIFNpbXBsZSBQSFAgWUFNTCBDbGFzcwogICAqIEB2ZXJzaW9uIDAuNi4yCiAgICogQGF1dGhvciBWbGFkIEFuZGVyc2VuIDx2bGFkLmFuZGVyc2VuQGdtYWlsLmNvbT4KICAgKiBAYXV0aG9yIENocmlzIFdhbnN0cmF0aCA8Y2hyaXNAb3ptbS5vcmc+CiAgICogQGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL211c3Rhbmdvc3Rhbmcvc3B5Yy8KICAgKiBAY29weXJpZ2h0IENvcHlyaWdodCAyMDA1LTIwMDYgQ2hyaXMgV2Fuc3RyYXRoLCAyMDA2LTIwMTEgVmxhZCBBbmRlcnNlbgogICAqIEBsaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIE1JVCBMaWNlbnNlCiAgICogQHBhY2thZ2UgU3B5YwogICAqLwoKLyoqCiAgICogVGhlIFNpbXBsZSBQSFAgWUFNTCBDbGFzcy4KICAgKgogICAqIFRoaXMgY2xhc3MgY2FuIGJlIHVzZWQgdG8gcmVhZCBhIFlBTUwgZmlsZSBhbmQgY29udmVydCBpdHMgY29udGVudHMKICAgKiBpbnRvIGEgUEhQIGFycmF5LiAgSXQgY3VycmVudGx5IHN1cHBvcnRzIGEgdmVyeSBsaW1pdGVkIHN1YnNlY3Rpb24gb2YKICAgKiB0aGUgWUFNTCBzcGVjLgogICAqCiAgICogVXNhZ2U6CiAgICogPGNvZGU+CiAgICogICAkU3B5YyAgPSBuZXcgU3B5YzsKICAgKiAgICRhcnJheSA9ICRTcHljLT5sb2FkKCRmaWxlKTsKICAgKiA8L2NvZGU+CiAgICogb3I6CiAgICogPGNvZGU+CiAgICogICAkYXJyYXkgPSBTcHljOjpZQU1MTG9hZCgkZmlsZSk7CiAgICogPC9jb2RlPgogICAqIG9yOgogICAqIDxjb2RlPgogICAqICAgJGFycmF5ID0gc3B5Y19sb2FkX2ZpbGUoJGZpbGUpOwogICAqIDwvY29kZT4KICAgKiBAcGFja2FnZSBTcHljCiAgICovCmNsYXNzIFNweWMgewoKICAvLyBTRVRUSU5HUwoKICBjb25zdCBSRU1QVFkgPSAiXDBcMFwwXDBcMCI7CgogIC8qKgogICAqIFNldHRpbmcgdGhpcyB0byB0cnVlIHdpbGwgZm9yY2UgWUFNTER1bXAgdG8gZW5jbG9zZSBhbnkgc3RyaW5nIHZhbHVlIGluCiAgICogcXVvdGVzLiAgRmFsc2UgYnkgZGVmYXVsdC4KICAgKgogICAqIEB2YXIgYm9vbAogICAqLwogIHB1YmxpYyAkc2V0dGluZ19kdW1wX2ZvcmNlX3F1b3RlcyA9IGZhbHNlOwoKICAvKioKICAgKiBTZXR0aW5nIHRoaXMgdG8gdHJ1ZSB3aWxsIGZvcnNlIFlBTUxMb2FkIHRvIHVzZSBzeWNrX2xvYWQgZnVuY3Rpb24gd2hlbgogICAqIHBvc3NpYmxlLiBGYWxzZSBieSBkZWZhdWx0LgogICAqIEB2YXIgYm9vbAogICAqLwogIHB1YmxpYyAkc2V0dGluZ191c2Vfc3lja19pc19wb3NzaWJsZSA9IGZhbHNlOwoKCgogIC8qKiNAKwogICogQGFjY2VzcyBwcml2YXRlCiAgKiBAdmFyIG1peGVkCiAgKi8KICBwcml2YXRlICRfZHVtcEluZGVudDsKICBwcml2YXRlICRfZHVtcFdvcmRXcmFwOwogIHByaXZhdGUgJF9jb250YWluc0dyb3VwQW5jaG9yID0gZmFsc2U7CiAgcHJpdmF0ZSAkX2NvbnRhaW5zR3JvdXBBbGlhcyA9IGZhbHNlOwogIHByaXZhdGUgJHBhdGg7CiAgcHJpdmF0ZSAkcmVzdWx0OwogIHByaXZhdGUgJExpdGVyYWxQbGFjZUhvbGRlciA9ICdfX19ZQU1MX0xpdGVyYWxfQmxvY2tfX18nOwogIHByaXZhdGUgJFNhdmVkR3JvdXBzID0gYXJyYXkoKTsKICBwcml2YXRlICRpbmRlbnQ7CiAgLyoqCiAgICogUGF0aCBtb2RpZmllciB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIGFkZGluZyBjdXJyZW50IGVsZW1lbnQuCiAgICogQHZhciBhcnJheQogICAqLwogIHByaXZhdGUgJGRlbGF5ZWRQYXRoID0gYXJyYXkoKTsKCiAgLyoqI0ArCiAgKiBAYWNjZXNzIHB1YmxpYwogICogQHZhciBtaXhlZAogICovCiAgcHVibGljICRfbm9kZUlkOwoKLyoqCiAqIExvYWQgYSB2YWxpZCBZQU1MIHN0cmluZyB0byBTcHljLgogKiBAcGFyYW0gc3RyaW5nICRpbnB1dAogKiBAcmV0dXJuIGFycmF5CiAqLwogIHB1YmxpYyBmdW5jdGlvbiBsb2FkICgkaW5wdXQpIHsKICAgIHJldHVybiAkdGhpcy0+X2xvYWRTdHJpbmcoJGlucHV0KTsKICB9CgogLyoqCiAqIExvYWQgYSB2YWxpZCBZQU1MIGZpbGUgdG8gU3B5Yy4KICogQHBhcmFtIHN0cmluZyAkZmlsZQogKiBAcmV0dXJuIGFycmF5CiAqLwogIHB1YmxpYyBmdW5jdGlvbiBsb2FkRmlsZSAoJGZpbGUpIHsKICAgIHJldHVybiAkdGhpcy0+X2xvYWQoJGZpbGUpOwogIH0KCiAgLyoqCiAgICAgKiBMb2FkIFlBTUwgaW50byBhIFBIUCBhcnJheSBzdGF0aWNhbGx5CiAgICAgKgogICAgICogVGhlIGxvYWQgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYSBZQU1MIHN0cmVhbSAoc3RyaW5nIG9yIGZpbGUpLAogICAgICogd2lsbCBkbyBpdHMgYmVzdCB0byBjb252ZXJ0IFlBTUwgaW4gYSBmaWxlIGludG8gYSBQSFAgYXJyYXkuICBQcmV0dHkKICAgICAqIHNpbXBsZS4KICAgICAqICBVc2FnZToKICAgICAqICA8Y29kZT4KICAgICAqICAgJGFycmF5ID0gU3B5Yzo6WUFNTExvYWQoJ2x1Y2t5LnlhbWwnKTsKICAgICAqICAgcHJpbnRfcigkYXJyYXkpOwogICAgICogIDwvY29kZT4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBQYXRoIG9mIFlBTUwgZmlsZSBvciBzdHJpbmcgY29udGFpbmluZyBZQU1MCiAgICAgKi8KICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIFlBTUxMb2FkKCRpbnB1dCkgewogICAgJFNweWMgPSBuZXcgU3B5YzsKICAgIHJldHVybiAkU3B5Yy0+X2xvYWQoJGlucHV0KTsKICB9CgogIC8qKgogICAgICogTG9hZCBhIHN0cmluZyBvZiBZQU1MIGludG8gYSBQSFAgYXJyYXkgc3RhdGljYWxseQogICAgICoKICAgICAqIFRoZSBsb2FkIG1ldGhvZCwgd2hlbiBzdXBwbGllZCB3aXRoIGEgWUFNTCBzdHJpbmcsIHdpbGwgZG8gaXRzIGJlc3QKICAgICAqIHRvIGNvbnZlcnQgWUFNTCBpbiBhIHN0cmluZyBpbnRvIGEgUEhQIGFycmF5LiAgUHJldHR5IHNpbXBsZS4KICAgICAqCiAgICAgKiBOb3RlOiB1c2UgdGhpcyBmdW5jdGlvbiBpZiB5b3UgZG9uJ3Qgd2FudCBmaWxlcyBmcm9tIHRoZSBmaWxlIHN5c3RlbQogICAgICogbG9hZGVkIGFuZCBwcm9jZXNzZWQgYXMgWUFNTC4gIFRoaXMgaXMgb2YgaW50ZXJlc3QgdG8gcGVvcGxlIGNvbmNlcm5lZAogICAgICogYWJvdXQgc2VjdXJpdHkgd2hvc2UgaW5wdXQgaXMgZnJvbSBhIHN0cmluZy4KICAgICAqCiAgICAgKiAgVXNhZ2U6CiAgICAgKiAgPGNvZGU+CiAgICAgKiAgICRhcnJheSA9IFNweWM6OllBTUxMb2FkU3RyaW5nKCItLS1cbjA6IGhlbGxvIHdvcmxkXG4iKTsKICAgICAqICAgcHJpbnRfcigkYXJyYXkpOwogICAgICogIDwvY29kZT4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRpbnB1dCBTdHJpbmcgY29udGFpbmluZyBZQU1MCiAgICAgKi8KICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIFlBTUxMb2FkU3RyaW5nKCRpbnB1dCkgewogICAgJFNweWMgPSBuZXcgU3B5YzsKICAgIHJldHVybiAkU3B5Yy0+X2xvYWRTdHJpbmcoJGlucHV0KTsKICB9CgogIC8qKgogICAgICogRHVtcCBZQU1MIGZyb20gUEhQIGFycmF5IHN0YXRpY2FsbHkKICAgICAqCiAgICAgKiBUaGUgZHVtcCBtZXRob2QsIHdoZW4gc3VwcGxpZWQgd2l0aCBhbiBhcnJheSwgd2lsbCBkbyBpdHMgYmVzdAogICAgICogdG8gY29udmVydCB0aGUgYXJyYXkgaW50byBmcmllbmRseSBZQU1MLiAgUHJldHR5IHNpbXBsZS4gIEZlZWwgZnJlZSB0bwogICAgICogc2F2ZSB0aGUgcmV0dXJuZWQgc3RyaW5nIGFzIG5vdGhpbmcueWFtbCBhbmQgcGFzcyBpdCBhcm91bmQuCiAgICAgKgogICAgICogT2gsIGFuZCB5b3UgY2FuIGRlY2lkZSBob3cgYmlnIHRoZSBpbmRlbnQgaXMgYW5kIHdoYXQgdGhlIHdvcmR3cmFwCiAgICAgKiBmb3IgZm9sZGluZyBpcy4gIFByZXR0eSBjb29sIC0tIGp1c3QgcGFzcyBpbiAnZmFsc2UnIGZvciBlaXRoZXIgaWYKICAgICAqIHlvdSB3YW50IHRvIHVzZSB0aGUgZGVmYXVsdC4KICAgICAqCiAgICAgKiBJbmRlbnQncyBkZWZhdWx0IGlzIDIgc3BhY2VzLCB3b3Jkd3JhcCdzIGRlZmF1bHQgaXMgNDAgY2hhcmFjdGVycy4gIEFuZAogICAgICogeW91IGNhbiB0dXJuIG9mZiB3b3Jkd3JhcCBieSBwYXNzaW5nIGluIDAuCiAgICAgKgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gYXJyYXl8XHN0ZENsYXNzICRhcnJheSBQSFAgYXJyYXkKICAgICAqIEBwYXJhbSBpbnQgJGluZGVudCBQYXNzIGluIGZhbHNlIHRvIHVzZSB0aGUgZGVmYXVsdCwgd2hpY2ggaXMgMgogICAgICogQHBhcmFtIGludCAkd29yZHdyYXAgUGFzcyBpbiAwIGZvciBubyB3b3Jkd3JhcCwgZmFsc2UgZm9yIGRlZmF1bHQgKDQwKQogICAgICogQHBhcmFtIGJvb2wgJG5vX29wZW5pbmdfZGFzaGVzIERvIG5vdCBzdGFydCBZQU1MIGZpbGUgd2l0aCAiLS0tXG4iCiAgICAgKi8KICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIFlBTUxEdW1wKCRhcnJheSwgJGluZGVudCA9IGZhbHNlLCAkd29yZHdyYXAgPSBmYWxzZSwgJG5vX29wZW5pbmdfZGFzaGVzID0gZmFsc2UpIHsKICAgICRzcHljID0gbmV3IFNweWM7CiAgICByZXR1cm4gJHNweWMtPmR1bXAoJGFycmF5LCAkaW5kZW50LCAkd29yZHdyYXAsICRub19vcGVuaW5nX2Rhc2hlcyk7CiAgfQoKCiAgLyoqCiAgICAgKiBEdW1wIFBIUCBhcnJheSB0byBZQU1MCiAgICAgKgogICAgICogVGhlIGR1bXAgbWV0aG9kLCB3aGVuIHN1cHBsaWVkIHdpdGggYW4gYXJyYXksIHdpbGwgZG8gaXRzIGJlc3QKICAgICAqIHRvIGNvbnZlcnQgdGhlIGFycmF5IGludG8gZnJpZW5kbHkgWUFNTC4gIFByZXR0eSBzaW1wbGUuICBGZWVsIGZyZWUgdG8KICAgICAqIHNhdmUgdGhlIHJldHVybmVkIHN0cmluZyBhcyB0YXN0ZWZ1bC55YW1sIGFuZCBwYXNzIGl0IGFyb3VuZC4KICAgICAqCiAgICAgKiBPaCwgYW5kIHlvdSBjYW4gZGVjaWRlIGhvdyBiaWcgdGhlIGluZGVudCBpcyBhbmQgd2hhdCB0aGUgd29yZHdyYXAKICAgICAqIGZvciBmb2xkaW5nIGlzLiAgUHJldHR5IGNvb2wgLS0ganVzdCBwYXNzIGluICdmYWxzZScgZm9yIGVpdGhlciBpZgogICAgICogeW91IHdhbnQgdG8gdXNlIHRoZSBkZWZhdWx0LgogICAgICoKICAgICAqIEluZGVudCdzIGRlZmF1bHQgaXMgMiBzcGFjZXMsIHdvcmR3cmFwJ3MgZGVmYXVsdCBpcyA0MCBjaGFyYWN0ZXJzLiAgQW5kCiAgICAgKiB5b3UgY2FuIHR1cm4gb2ZmIHdvcmR3cmFwIGJ5IHBhc3NpbmcgaW4gMC4KICAgICAqCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyYXkgUEhQIGFycmF5CiAgICAgKiBAcGFyYW0gaW50ICRpbmRlbnQgUGFzcyBpbiBmYWxzZSB0byB1c2UgdGhlIGRlZmF1bHQsIHdoaWNoIGlzIDIKICAgICAqIEBwYXJhbSBpbnQgJHdvcmR3cmFwIFBhc3MgaW4gMCBmb3Igbm8gd29yZHdyYXAsIGZhbHNlIGZvciBkZWZhdWx0ICg0MCkKICAgICAqLwogIHB1YmxpYyBmdW5jdGlvbiBkdW1wKCRhcnJheSwkaW5kZW50ID0gZmFsc2UsJHdvcmR3cmFwID0gZmFsc2UsICRub19vcGVuaW5nX2Rhc2hlcyA9IGZhbHNlKSB7CiAgICAvLyBEdW1wcyB0byBzb21lIHZlcnkgY2xlYW4gWUFNTC4gIFdlJ2xsIGhhdmUgdG8gYWRkIHNvbWUgbW9yZSBmZWF0dXJlcwogICAgLy8gYW5kIG9wdGlvbnMgc29vbi4gIEFuZCBiZXR0ZXIgc3VwcG9ydCBmb3IgZm9sZGluZy4KCiAgICAvLyBOZXcgZmVhdHVyZXMgYW5kIG9wdGlvbnMuCiAgICBpZiAoJGluZGVudCA9PT0gZmFsc2Ugb3IgIWlzX251bWVyaWMoJGluZGVudCkpIHsKICAgICAgJHRoaXMtPl9kdW1wSW5kZW50ID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICR0aGlzLT5fZHVtcEluZGVudCA9ICRpbmRlbnQ7CiAgICB9CgogICAgaWYgKCR3b3Jkd3JhcCA9PT0gZmFsc2Ugb3IgIWlzX251bWVyaWMoJHdvcmR3cmFwKSkgewogICAgICAkdGhpcy0+X2R1bXBXb3JkV3JhcCA9IDQwOwogICAgfSBlbHNlIHsKICAgICAgJHRoaXMtPl9kdW1wV29yZFdyYXAgPSAkd29yZHdyYXA7CiAgICB9CgogICAgLy8gTmV3IFlBTUwgZG9jdW1lbnQKICAgICRzdHJpbmcgPSAiIjsKICAgIGlmICghJG5vX29wZW5pbmdfZGFzaGVzKSAkc3RyaW5nID0gIi0tLVxuIjsKCiAgICAvLyBTdGFydCBhdCB0aGUgYmFzZSBvZiB0aGUgYXJyYXkgYW5kIG1vdmUgdGhyb3VnaCBpdC4KICAgIGlmICgkYXJyYXkpIHsKICAgICAgJGFycmF5ID0gKGFycmF5KSRhcnJheTsKICAgICAgJHByZXZpb3VzX2tleSA9IC0xOwogICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoIWlzc2V0KCRmaXJzdF9rZXkpKSAkZmlyc3Rfa2V5ID0gJGtleTsKICAgICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZSgka2V5LCR2YWx1ZSwwLCRwcmV2aW91c19rZXksICRmaXJzdF9rZXksICRhcnJheSk7CiAgICAgICAgJHByZXZpb3VzX2tleSA9ICRrZXk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiAkc3RyaW5nOwogIH0KCiAgLyoqCiAgICAgKiBBdHRlbXB0cyB0byBjb252ZXJ0IGEga2V5IC8gdmFsdWUgYXJyYXkgaXRlbSB0byBZQU1MCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGtleSBUaGUgbmFtZSBvZiB0aGUga2V5CiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgaXRlbQogICAgICogQHBhcmFtICRpbmRlbnQgVGhlIGluZGVudCBvZiB0aGUgY3VycmVudCBub2RlCiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF95YW1saXplKCRrZXksJHZhbHVlLCRpbmRlbnQsICRwcmV2aW91c19rZXkgPSAtMSwgJGZpcnN0X2tleSA9IDAsICRzb3VyY2VfYXJyYXkgPSBudWxsKSB7CiAgICBpZihpc19vYmplY3QoJHZhbHVlKSkgJHZhbHVlID0gKGFycmF5KSR2YWx1ZTsKICAgIGlmIChpc19hcnJheSgkdmFsdWUpKSB7CiAgICAgIGlmIChlbXB0eSAoJHZhbHVlKSkKICAgICAgICByZXR1cm4gJHRoaXMtPl9kdW1wTm9kZSgka2V5LCBhcnJheSgpLCAkaW5kZW50LCAkcHJldmlvdXNfa2V5LCAkZmlyc3Rfa2V5LCAkc291cmNlX2FycmF5KTsKICAgICAgLy8gSXQgaGFzIGNoaWxkcmVuLiAgV2hhdCB0byBkbz8KICAgICAgLy8gTWFrZSBpdCB0aGUgcmlnaHQga2luZCBvZiBpdGVtCiAgICAgICRzdHJpbmcgPSAkdGhpcy0+X2R1bXBOb2RlKCRrZXksIHNlbGY6OlJFTVBUWSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSwgJHNvdXJjZV9hcnJheSk7CiAgICAgIC8vIEFkZCB0aGUgaW5kZW50CiAgICAgICRpbmRlbnQgKz0gJHRoaXMtPl9kdW1wSW5kZW50OwogICAgICAvLyBZYW1saXplIHRoZSBhcnJheQogICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZUFycmF5KCR2YWx1ZSwkaW5kZW50KTsKICAgIH0gZWxzZWlmICghaXNfYXJyYXkoJHZhbHVlKSkgewogICAgICAvLyBJdCBkb2Vzbid0IGhhdmUgY2hpbGRyZW4uICBZaXAuCiAgICAgICRzdHJpbmcgPSAkdGhpcy0+X2R1bXBOb2RlKCRrZXksICR2YWx1ZSwgJGluZGVudCwgJHByZXZpb3VzX2tleSwgJGZpcnN0X2tleSwgJHNvdXJjZV9hcnJheSk7CiAgICB9CiAgICByZXR1cm4gJHN0cmluZzsKICB9CgogIC8qKgogICAgICogQXR0ZW1wdHMgdG8gY29udmVydCBhbiBhcnJheSB0byBZQU1MCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGFycmF5IFRoZSBhcnJheSB5b3Ugd2FudCB0byBjb252ZXJ0CiAgICAgKiBAcGFyYW0gJGluZGVudCBUaGUgaW5kZW50IG9mIHRoZSBjdXJyZW50IGxldmVsCiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF95YW1saXplQXJyYXkoJGFycmF5LCRpbmRlbnQpIHsKICAgIGlmIChpc19hcnJheSgkYXJyYXkpKSB7CiAgICAgICRzdHJpbmcgPSAnJzsKICAgICAgJHByZXZpb3VzX2tleSA9IC0xOwogICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoIWlzc2V0KCRmaXJzdF9rZXkpKSAkZmlyc3Rfa2V5ID0gJGtleTsKICAgICAgICAkc3RyaW5nIC49ICR0aGlzLT5feWFtbGl6ZSgka2V5LCAkdmFsdWUsICRpbmRlbnQsICRwcmV2aW91c19rZXksICRmaXJzdF9rZXksICRhcnJheSk7CiAgICAgICAgJHByZXZpb3VzX2tleSA9ICRrZXk7CiAgICAgIH0KICAgICAgcmV0dXJuICRzdHJpbmc7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICAvKioKICAgICAqIFJldHVybnMgWUFNTCBmcm9tIGEga2V5IGFuZCBhIHZhbHVlCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gJGtleSBUaGUgbmFtZSBvZiB0aGUga2V5CiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgaXRlbQogICAgICogQHBhcmFtICRpbmRlbnQgVGhlIGluZGVudCBvZiB0aGUgY3VycmVudCBub2RlCiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF9kdW1wTm9kZSgka2V5LCAkdmFsdWUsICRpbmRlbnQsICRwcmV2aW91c19rZXkgPSAtMSwgJGZpcnN0X2tleSA9IDAsICRzb3VyY2VfYXJyYXkgPSBudWxsKSB7CiAgICAvLyBkbyBzb21lIGZvbGRpbmcgaGVyZSwgZm9yIGJsb2NrcwogICAgaWYgKGlzX3N0cmluZyAoJHZhbHVlKSAmJiAoKHN0cnBvcygkdmFsdWUsIlxuIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIjogIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIi0gIikgIT09IGZhbHNlIHx8CiAgICAgIHN0cnBvcygkdmFsdWUsIioiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwiIyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCI8IikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsIj4iKSAhPT0gZmFsc2UgfHwgc3RycG9zICgkdmFsdWUsICclJykgIT09IGZhbHNlIHx8IHN0cnBvcyAoJHZhbHVlLCAnICAnKSAhPT0gZmFsc2UgfHwKICAgICAgc3RycG9zKCR2YWx1ZSwiWyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCJdIikgIT09IGZhbHNlIHx8IHN0cnBvcygkdmFsdWUsInsiKSAhPT0gZmFsc2UgfHwgc3RycG9zKCR2YWx1ZSwifSIpICE9PSBmYWxzZSkgfHwgc3RycG9zKCR2YWx1ZSwiJiIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCAiJyIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJHZhbHVlLCAiISIpID09PSAwIHx8CiAgICAgIHN1YnN0ciAoJHZhbHVlLCAtMSwgMSkgPT0gJzonKQogICAgKSB7CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5fZG9MaXRlcmFsQmxvY2soJHZhbHVlLCRpbmRlbnQpOwogICAgfSBlbHNlIHsKICAgICAgJHZhbHVlICA9ICR0aGlzLT5fZG9Gb2xkaW5nKCR2YWx1ZSwkaW5kZW50KTsKICAgIH0KCiAgICBpZiAoJHZhbHVlID09PSBhcnJheSgpKSAkdmFsdWUgPSAnWyBdJzsKICAgIGlmICgkdmFsdWUgPT09ICIiKSAkdmFsdWUgPSAnIiInOwogICAgaWYgKHNlbGY6OmlzVHJhbnNsYXRpb25Xb3JkKCR2YWx1ZSkpIHsKICAgICAgJHZhbHVlID0gJHRoaXMtPl9kb0xpdGVyYWxCbG9jaygkdmFsdWUsICRpbmRlbnQpOwogICAgfQogICAgaWYgKHRyaW0gKCR2YWx1ZSkgIT0gJHZhbHVlKQogICAgICAgJHZhbHVlID0gJHRoaXMtPl9kb0xpdGVyYWxCbG9jaygkdmFsdWUsJGluZGVudCk7CgogICAgaWYgKGlzX2Jvb2woJHZhbHVlKSkgewogICAgICAgJHZhbHVlID0gJHZhbHVlID8gInRydWUiIDogImZhbHNlIjsKICAgIH0KCiAgICBpZiAoJHZhbHVlID09PSBudWxsKSAkdmFsdWUgPSAnbnVsbCc7CiAgICBpZiAoJHZhbHVlID09PSAiJyIgLiBzZWxmOjpSRU1QVFkgLiAiJyIpICR2YWx1ZSA9IG51bGw7CgogICAgJHNwYWNlcyA9IHN0cl9yZXBlYXQoJyAnLCRpbmRlbnQpOwoKICAgIC8vaWYgKGlzX2ludCgka2V5KSAmJiAka2V5IC0gMSA9PSAkcHJldmlvdXNfa2V5ICYmICRmaXJzdF9rZXk9PT0wKSB7CiAgICBpZiAoaXNfYXJyYXkgKCRzb3VyY2VfYXJyYXkpICYmIGFycmF5X2tleXMoJHNvdXJjZV9hcnJheSkgPT09IHJhbmdlKDAsIGNvdW50KCRzb3VyY2VfYXJyYXkpIC0gMSkpIHsKICAgICAgLy8gSXQncyBhIHNlcXVlbmNlCiAgICAgICRzdHJpbmcgPSAkc3BhY2VzLictICcuJHZhbHVlLiJcbiI7CiAgICB9IGVsc2UgewogICAgICAvLyBpZiAoJGZpcnN0X2tleT09PTApICB0aHJvdyBuZXcgXEV4Y2VwdGlvbignS2V5cyBhcmUgYWxsIHNjcmV3eS4gIFRoZSBmaXJzdCBvbmUgd2FzIHplcm8sIG5vdyBpdFwncyAiJy4gJGtleSAuJyInKTsKICAgICAgLy8gSXQncyBtYXBwZWQKICAgICAgaWYgKHN0cnBvcygka2V5LCAiOiIpICE9PSBmYWxzZSB8fCBzdHJwb3MoJGtleSwgIiMiKSAhPT0gZmFsc2UpIHsgJGtleSA9ICciJyAuICRrZXkgLiAnIic7IH0KICAgICAgJHN0cmluZyA9IHJ0cmltICgkc3BhY2VzLiRrZXkuJzogJy4kdmFsdWUpLiJcbiI7CiAgICB9CiAgICByZXR1cm4gJHN0cmluZzsKICB9CgogIC8qKgogICAgICogQ3JlYXRlcyBhIGxpdGVyYWwgYmxvY2sgZm9yIGR1bXBpbmcKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkdmFsdWUKICAgICAqIEBwYXJhbSAkaW5kZW50IGludCBUaGUgdmFsdWUgb2YgdGhlIGluZGVudAogICAgICovCiAgcHJpdmF0ZSBmdW5jdGlvbiBfZG9MaXRlcmFsQmxvY2soJHZhbHVlLCRpbmRlbnQpIHsKICAgIGlmICgkdmFsdWUgPT09ICJcbiIpIHJldHVybiAnXG4nOwogICAgaWYgKHN0cnBvcygkdmFsdWUsICJcbiIpID09PSBmYWxzZSAmJiBzdHJwb3MoJHZhbHVlLCAiJyIpID09PSBmYWxzZSkgewogICAgICByZXR1cm4gc3ByaW50ZiAoIiclcyciLCAkdmFsdWUpOwogICAgfQogICAgaWYgKHN0cnBvcygkdmFsdWUsICJcbiIpID09PSBmYWxzZSAmJiBzdHJwb3MoJHZhbHVlLCAnIicpID09PSBmYWxzZSkgewogICAgICByZXR1cm4gc3ByaW50ZiAoJyIlcyInLCAkdmFsdWUpOwogICAgfQogICAgJGV4cGxvZGVkID0gZXhwbG9kZSgiXG4iLCR2YWx1ZSk7CiAgICAkbmV3VmFsdWUgPSAnfCc7CiAgICBpZiAoaXNzZXQoJGV4cGxvZGVkWzBdKSAmJiAoJGV4cGxvZGVkWzBdID09ICJ8IiB8fCAkZXhwbG9kZWRbMF0gPT0gInwtIiB8fCAkZXhwbG9kZWRbMF0gPT0gIj4iKSkgewogICAgICAgICRuZXdWYWx1ZSA9ICRleHBsb2RlZFswXTsKICAgICAgICB1bnNldCgkZXhwbG9kZWRbMF0pOwogICAgfQogICAgJGluZGVudCArPSAkdGhpcy0+X2R1bXBJbmRlbnQ7CiAgICAkc3BhY2VzICAgPSBzdHJfcmVwZWF0KCcgJywkaW5kZW50KTsKICAgIGZvcmVhY2ggKCRleHBsb2RlZCBhcyAkbGluZSkgewogICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgICBpZiAoc3RycG9zKCRsaW5lLCAnIicpID09PSAwICYmIHN0cnJwb3MoJGxpbmUsICciJykgPT0gKHN0cmxlbigkbGluZSktMSkgfHwgc3RycG9zKCRsaW5lLCAiJyIpID09PSAwICYmIHN0cnJwb3MoJGxpbmUsICInIikgPT0gKHN0cmxlbigkbGluZSktMSkpIHsKICAgICAgICAkbGluZSA9IHN1YnN0cigkbGluZSwgMSwgLTEpOwogICAgICB9CiAgICAgICRuZXdWYWx1ZSAuPSAiXG4iIC4gJHNwYWNlcyAuICgkbGluZSk7CiAgICB9CiAgICByZXR1cm4gJG5ld1ZhbHVlOwogIH0KCiAgLyoqCiAgICAgKiBGb2xkcyBhIHN0cmluZyBvZiB0ZXh0LCBpZiBuZWNlc3NhcnkKICAgICAqIEBhY2Nlc3MgcHJpdmF0ZQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBwYXJhbSAkdmFsdWUgVGhlIHN0cmluZyB5b3Ugd2lzaCB0byBmb2xkCiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF9kb0ZvbGRpbmcoJHZhbHVlLCRpbmRlbnQpIHsKICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHdvcmR3cmFwIGlzIHNldCB0byAwCgogICAgaWYgKCR0aGlzLT5fZHVtcFdvcmRXcmFwICE9PSAwICYmIGlzX3N0cmluZyAoJHZhbHVlKSAmJiBzdHJsZW4oJHZhbHVlKSA+ICR0aGlzLT5fZHVtcFdvcmRXcmFwKSB7CiAgICAgICRpbmRlbnQgKz0gJHRoaXMtPl9kdW1wSW5kZW50OwogICAgICAkaW5kZW50ID0gc3RyX3JlcGVhdCgnICcsJGluZGVudCk7CiAgICAgICR3cmFwcGVkID0gd29yZHdyYXAoJHZhbHVlLCR0aGlzLT5fZHVtcFdvcmRXcmFwLCJcbiRpbmRlbnQiKTsKICAgICAgJHZhbHVlICAgPSAiPlxuIi4kaW5kZW50LiR3cmFwcGVkOwogICAgfSBlbHNlIHsKICAgICAgaWYgKCR0aGlzLT5zZXR0aW5nX2R1bXBfZm9yY2VfcXVvdGVzICYmIGlzX3N0cmluZyAoJHZhbHVlKSAmJiAkdmFsdWUgIT09IHNlbGY6OlJFTVBUWSkKICAgICAgICAkdmFsdWUgPSAnIicgLiAkdmFsdWUgLiAnIic7CiAgICAgIGlmIChpc19udW1lcmljKCR2YWx1ZSkgJiYgaXNfc3RyaW5nKCR2YWx1ZSkpCiAgICAgICAgJHZhbHVlID0gJyInIC4gJHZhbHVlIC4gJyInOwogICAgfQoKCiAgICByZXR1cm4gJHZhbHVlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBpc1RydWVXb3JkKCR2YWx1ZSkgewogICAgJHdvcmRzID0gc2VsZjo6Z2V0VHJhbnNsYXRpb25zKGFycmF5KCd0cnVlJywgJ29uJywgJ3llcycsICd5JykpOwogICAgcmV0dXJuIGluX2FycmF5KCR2YWx1ZSwgJHdvcmRzLCB0cnVlKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNGYWxzZVdvcmQoJHZhbHVlKSB7CiAgICAkd29yZHMgPSBzZWxmOjpnZXRUcmFuc2xhdGlvbnMoYXJyYXkoJ2ZhbHNlJywgJ29mZicsICdubycsICduJykpOwogICAgcmV0dXJuIGluX2FycmF5KCR2YWx1ZSwgJHdvcmRzLCB0cnVlKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNOdWxsV29yZCgkdmFsdWUpIHsKICAgICR3b3JkcyA9IHNlbGY6OmdldFRyYW5zbGF0aW9ucyhhcnJheSgnbnVsbCcsICd+JykpOwogICAgcmV0dXJuIGluX2FycmF5KCR2YWx1ZSwgJHdvcmRzLCB0cnVlKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNUcmFuc2xhdGlvbldvcmQoJHZhbHVlKSB7CiAgICByZXR1cm4gKAogICAgICBzZWxmOjppc1RydWVXb3JkKCR2YWx1ZSkgIHx8CiAgICAgIHNlbGY6OmlzRmFsc2VXb3JkKCR2YWx1ZSkgfHwKICAgICAgc2VsZjo6aXNOdWxsV29yZCgkdmFsdWUpCiAgICApOwogIH0KCiAgLyoqCiAgICAgKiBDb2VyY2UgYSBzdHJpbmcgaW50byBhIG5hdGl2ZSB0eXBlCiAgICAgKiBSZWZlcmVuY2U6IGh0dHA6Ly95YW1sLm9yZy90eXBlL2Jvb2wuaHRtbAogICAgICogVE9ETzogVXNlIG9ubHkgd29yZHMgZnJvbSB0aGUgWUFNTCBzcGVjLgogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSB0byBjb2VyY2UKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gY29lcmNlVmFsdWUoJiR2YWx1ZSkgewogICAgaWYgKHNlbGY6OmlzVHJ1ZVdvcmQoJHZhbHVlKSkgewogICAgICAkdmFsdWUgPSB0cnVlOwogICAgfSBlbHNlIGlmIChzZWxmOjppc0ZhbHNlV29yZCgkdmFsdWUpKSB7CiAgICAgICR2YWx1ZSA9IGZhbHNlOwogICAgfSBlbHNlIGlmIChzZWxmOjppc051bGxXb3JkKCR2YWx1ZSkpIHsKICAgICAgJHZhbHVlID0gbnVsbDsKICAgIH0KICB9CgogIC8qKgogICAgICogR2l2ZW4gYSBzZXQgb2Ygd29yZHMsIHBlcmZvcm0gdGhlIGFwcHJvcHJpYXRlIHRyYW5zbGF0aW9ucyBvbiB0aGVtIHRvCiAgICAgKiBtYXRjaCB0aGUgWUFNTCAxLjEgc3BlY2lmaWNhdGlvbiBmb3IgdHlwZSBjb2VyY2luZy4KICAgICAqIEBwYXJhbSAkd29yZHMgVGhlIHdvcmRzIHRvIHRyYW5zbGF0ZQogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKi8KICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbnMoYXJyYXkgJHdvcmRzKSB7CiAgICAkcmVzdWx0ID0gYXJyYXkoKTsKICAgIGZvcmVhY2ggKCR3b3JkcyBhcyAkaSkgewogICAgICAkcmVzdWx0ID0gYXJyYXlfbWVyZ2UoJHJlc3VsdCwgYXJyYXkodWNmaXJzdCgkaSksIHN0cnRvdXBwZXIoJGkpLCBzdHJ0b2xvd2VyKCRpKSkpOwogICAgfQogICAgcmV0dXJuICRyZXN1bHQ7CiAgfQoKLy8gTE9BRElORyBGVU5DVElPTlMKCiAgcHJpdmF0ZSBmdW5jdGlvbiBfbG9hZCgkaW5wdXQpIHsKICAgICRTb3VyY2UgPSAkdGhpcy0+bG9hZEZyb21Tb3VyY2UoJGlucHV0KTsKICAgIHJldHVybiAkdGhpcy0+bG9hZFdpdGhTb3VyY2UoJFNvdXJjZSk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIF9sb2FkU3RyaW5nKCRpbnB1dCkgewogICAgJFNvdXJjZSA9ICR0aGlzLT5sb2FkRnJvbVN0cmluZygkaW5wdXQpOwogICAgcmV0dXJuICR0aGlzLT5sb2FkV2l0aFNvdXJjZSgkU291cmNlKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gbG9hZFdpdGhTb3VyY2UoJFNvdXJjZSkgewogICAgaWYgKGVtcHR5ICgkU291cmNlKSkgcmV0dXJuIGFycmF5KCk7CiAgICBpZiAoJHRoaXMtPnNldHRpbmdfdXNlX3N5Y2tfaXNfcG9zc2libGUgJiYgZnVuY3Rpb25fZXhpc3RzICgnc3lja19sb2FkJykpIHsKICAgICAgJGFycmF5ID0gc3lja19sb2FkIChpbXBsb2RlICgiXG4iLCAkU291cmNlKSk7CiAgICAgIHJldHVybiBpc19hcnJheSgkYXJyYXkpID8gJGFycmF5IDogYXJyYXkoKTsKICAgIH0KCiAgICAkdGhpcy0+cGF0aCA9IGFycmF5KCk7CiAgICAkdGhpcy0+cmVzdWx0ID0gYXJyYXkoKTsKCiAgICAkY250ID0gY291bnQoJFNvdXJjZSk7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkY250OyAkaSsrKSB7CiAgICAgICRsaW5lID0gJFNvdXJjZVskaV07CgogICAgICAkdGhpcy0+aW5kZW50ID0gc3RybGVuKCRsaW5lKSAtIHN0cmxlbihsdHJpbSgkbGluZSkpOwogICAgICAkdGVtcFBhdGggPSAkdGhpcy0+Z2V0UGFyZW50UGF0aEJ5SW5kZW50KCR0aGlzLT5pbmRlbnQpOwogICAgICAkbGluZSA9IHNlbGY6OnN0cmlwSW5kZW50KCRsaW5lLCAkdGhpcy0+aW5kZW50KTsKICAgICAgaWYgKHNlbGY6OmlzQ29tbWVudCgkbGluZSkpIGNvbnRpbnVlOwogICAgICBpZiAoc2VsZjo6aXNFbXB0eSgkbGluZSkpIGNvbnRpbnVlOwogICAgICAkdGhpcy0+cGF0aCA9ICR0ZW1wUGF0aDsKCiAgICAgICRsaXRlcmFsQmxvY2tTdHlsZSA9IHNlbGY6OnN0YXJ0c0xpdGVyYWxCbG9jaygkbGluZSk7CiAgICAgIGlmICgkbGl0ZXJhbEJsb2NrU3R5bGUpIHsKICAgICAgICAkbGluZSA9IHJ0cmltICgkbGluZSwgJGxpdGVyYWxCbG9ja1N0eWxlIC4gIiBcbiIpOwogICAgICAgICRsaXRlcmFsQmxvY2sgPSAnJzsKICAgICAgICAkbGluZSAuPSAnICcuJHRoaXMtPkxpdGVyYWxQbGFjZUhvbGRlcjsKICAgICAgICAkbGl0ZXJhbF9ibG9ja19pbmRlbnQgPSBzdHJsZW4oJFNvdXJjZVskaSsxXSkgLSBzdHJsZW4obHRyaW0oJFNvdXJjZVskaSsxXSkpOwogICAgICAgIHdoaWxlICgrKyRpIDwgJGNudCAmJiAkdGhpcy0+bGl0ZXJhbEJsb2NrQ29udGludWVzKCRTb3VyY2VbJGldLCAkdGhpcy0+aW5kZW50KSkgewogICAgICAgICAgJGxpdGVyYWxCbG9jayA9ICR0aGlzLT5hZGRMaXRlcmFsTGluZSgkbGl0ZXJhbEJsb2NrLCAkU291cmNlWyRpXSwgJGxpdGVyYWxCbG9ja1N0eWxlLCAkbGl0ZXJhbF9ibG9ja19pbmRlbnQpOwogICAgICAgIH0KICAgICAgICAkaS0tOwogICAgICB9CgogICAgICAvLyBTdHJpcCBvdXQgY29tbWVudHMKICAgICAgaWYgKHN0cnBvcyAoJGxpbmUsICcjJykpIHsKICAgICAgICAgICRsaW5lID0gcHJlZ19yZXBsYWNlKCcvXHMqIyhbXiJcJ10rKSQvJywnJywkbGluZSk7CiAgICAgIH0KCiAgICAgIHdoaWxlICgrKyRpIDwgJGNudCAmJiBzZWxmOjpncmVlZGlseU5lZWROZXh0TGluZSgkbGluZSkpIHsKICAgICAgICAkbGluZSA9IHJ0cmltICgkbGluZSwgIiBcblx0XHIiKSAuICcgJyAuIGx0cmltICgkU291cmNlWyRpXSwgIiBcdCIpOwogICAgICB9CiAgICAgICRpLS07CgogICAgICAkbGluZUFycmF5ID0gJHRoaXMtPl9wYXJzZUxpbmUoJGxpbmUpOwoKICAgICAgaWYgKCRsaXRlcmFsQmxvY2tTdHlsZSkKICAgICAgICAkbGluZUFycmF5ID0gJHRoaXMtPnJldmVydExpdGVyYWxQbGFjZUhvbGRlciAoJGxpbmVBcnJheSwgJGxpdGVyYWxCbG9jayk7CgogICAgICAkdGhpcy0+YWRkQXJyYXkoJGxpbmVBcnJheSwgJHRoaXMtPmluZGVudCk7CgogICAgICBmb3JlYWNoICgkdGhpcy0+ZGVsYXllZFBhdGggYXMgJGluZGVudCA9PiAkZGVsYXllZFBhdGgpCiAgICAgICAgJHRoaXMtPnBhdGhbJGluZGVudF0gPSAkZGVsYXllZFBhdGg7CgogICAgICAkdGhpcy0+ZGVsYXllZFBhdGggPSBhcnJheSgpOwoKICAgIH0KICAgIHJldHVybiAkdGhpcy0+cmVzdWx0OwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkRnJvbVNvdXJjZSAoJGlucHV0KSB7CiAgICBpZiAoIWVtcHR5KCRpbnB1dCkgJiYgc3RycG9zKCRpbnB1dCwgIlxuIikgPT09IGZhbHNlICYmIGZpbGVfZXhpc3RzKCRpbnB1dCkpCiAgICAgICRpbnB1dCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRpbnB1dCk7CgogICAgcmV0dXJuICR0aGlzLT5sb2FkRnJvbVN0cmluZygkaW5wdXQpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBsb2FkRnJvbVN0cmluZyAoJGlucHV0KSB7CiAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsJGlucHV0KTsKICAgIGZvcmVhY2ggKCRsaW5lcyBhcyAkayA9PiAkXykgewogICAgICAkbGluZXNbJGtdID0gcnRyaW0gKCRfLCAiXHIiKTsKICAgIH0KICAgIHJldHVybiAkbGluZXM7CiAgfQoKICAvKioKICAgICAqIFBhcnNlcyBZQU1MIGNvZGUgYW5kIHJldHVybnMgYW4gYXJyYXkgZm9yIGEgbm9kZQogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIEEgbGluZSBmcm9tIHRoZSBZQU1MIGZpbGUKICAgICAqLwogIHByaXZhdGUgZnVuY3Rpb24gX3BhcnNlTGluZSgkbGluZSkgewogICAgaWYgKCEkbGluZSkgcmV0dXJuIGFycmF5KCk7CiAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwogICAgaWYgKCEkbGluZSkgcmV0dXJuIGFycmF5KCk7CgogICAgJGFycmF5ID0gYXJyYXkoKTsKCiAgICAkZ3JvdXAgPSAkdGhpcy0+bm9kZUNvbnRhaW5zR3JvdXAoJGxpbmUpOwogICAgaWYgKCRncm91cCkgewogICAgICAkdGhpcy0+YWRkR3JvdXAoJGxpbmUsICRncm91cCk7CiAgICAgICRsaW5lID0gJHRoaXMtPnN0cmlwR3JvdXAgKCRsaW5lLCAkZ3JvdXApOwogICAgfQoKICAgIGlmICgkdGhpcy0+c3RhcnRzTWFwcGVkU2VxdWVuY2UoJGxpbmUpKQogICAgICByZXR1cm4gJHRoaXMtPnJldHVybk1hcHBlZFNlcXVlbmNlKCRsaW5lKTsKCiAgICBpZiAoJHRoaXMtPnN0YXJ0c01hcHBlZFZhbHVlKCRsaW5lKSkKICAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5NYXBwZWRWYWx1ZSgkbGluZSk7CgogICAgaWYgKCR0aGlzLT5pc0FycmF5RWxlbWVudCgkbGluZSkpCiAgICAgcmV0dXJuICR0aGlzLT5yZXR1cm5BcnJheUVsZW1lbnQoJGxpbmUpOwoKICAgIGlmICgkdGhpcy0+aXNQbGFpbkFycmF5KCRsaW5lKSkKICAgICByZXR1cm4gJHRoaXMtPnJldHVyblBsYWluQXJyYXkoJGxpbmUpOwoKCiAgICByZXR1cm4gJHRoaXMtPnJldHVybktleVZhbHVlUGFpcigkbGluZSk7CgogIH0KCiAgLyoqCiAgICAgKiBGaW5kcyB0aGUgdHlwZSBvZiB0aGUgcGFzc2VkIHZhbHVlLCByZXR1cm5zIHRoZSB2YWx1ZSBhcyB0aGUgbmV3IHR5cGUuCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF90b1R5cGUoJHZhbHVlKSB7CiAgICBpZiAoJHZhbHVlID09PSAnJykgcmV0dXJuICIiOwogICAgJGZpcnN0X2NoYXJhY3RlciA9ICR2YWx1ZVswXTsKICAgICRsYXN0X2NoYXJhY3RlciA9IHN1YnN0cigkdmFsdWUsIC0xLCAxKTsKCiAgICAkaXNfcXVvdGVkID0gZmFsc2U7CiAgICBkbyB7CiAgICAgIGlmICghJHZhbHVlKSBicmVhazsKICAgICAgaWYgKCRmaXJzdF9jaGFyYWN0ZXIgIT0gJyInICYmICRmaXJzdF9jaGFyYWN0ZXIgIT0gIiciKSBicmVhazsKICAgICAgaWYgKCRsYXN0X2NoYXJhY3RlciAhPSAnIicgJiYgJGxhc3RfY2hhcmFjdGVyICE9ICInIikgYnJlYWs7CiAgICAgICRpc19xdW90ZWQgPSB0cnVlOwogICAgfSB3aGlsZSAoMCk7CgogICAgaWYgKCRpc19xdW90ZWQpIHsKICAgICAgJHZhbHVlID0gc3RyX3JlcGxhY2UoJ1xuJywgIlxuIiwgJHZhbHVlKTsKICAgICAgaWYgKCRmaXJzdF9jaGFyYWN0ZXIgPT0gIiciKQogICAgICAgIHJldHVybiBzdHJ0cihzdWJzdHIgKCR2YWx1ZSwgMSwgLTEpLCBhcnJheSAoJ1wnXCcnID0+ICdcJycsICdcXFwnJz0+ICdcJycpKTsKICAgICAgcmV0dXJuIHN0cnRyKHN1YnN0ciAoJHZhbHVlLCAxLCAtMSksIGFycmF5ICgnXFwiJyA9PiAnIicsICdcXFwnJz0+ICdcJycpKTsKICAgIH0KCiAgICBpZiAoc3RycG9zKCR2YWx1ZSwgJyAjJykgIT09IGZhbHNlICYmICEkaXNfcXVvdGVkKQogICAgICAkdmFsdWUgPSBwcmVnX3JlcGxhY2UoJy9ccysjKC4rKSQvJywnJywkdmFsdWUpOwoKICAgIGlmICgkZmlyc3RfY2hhcmFjdGVyID09ICdbJyAmJiAkbGFzdF9jaGFyYWN0ZXIgPT0gJ10nKSB7CiAgICAgIC8vIFRha2Ugb3V0IHN0cmluZ3Mgc2VxdWVuY2VzIGFuZCBtYXBwaW5ncwogICAgICAkaW5uZXJWYWx1ZSA9IHRyaW0oc3Vic3RyICgkdmFsdWUsIDEsIC0xKSk7CiAgICAgIGlmICgkaW5uZXJWYWx1ZSA9PT0gJycpIHJldHVybiBhcnJheSgpOwogICAgICAkZXhwbG9kZSA9ICR0aGlzLT5faW5saW5lRXNjYXBlKCRpbm5lclZhbHVlKTsKICAgICAgLy8gUHJvcGFnYXRlIHZhbHVlIGFycmF5CiAgICAgICR2YWx1ZSAgPSBhcnJheSgpOwogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAkdikgewogICAgICAgICR2YWx1ZVtdID0gJHRoaXMtPl90b1R5cGUoJHYpOwogICAgICB9CiAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgaWYgKHN0cnBvcygkdmFsdWUsJzogJykhPT1mYWxzZSAmJiAkZmlyc3RfY2hhcmFjdGVyICE9ICd7JykgewogICAgICAkYXJyYXkgPSBleHBsb2RlKCc6ICcsJHZhbHVlKTsKICAgICAgJGtleSAgID0gdHJpbSgkYXJyYXlbMF0pOwogICAgICBhcnJheV9zaGlmdCgkYXJyYXkpOwogICAgICAkdmFsdWUgPSB0cmltKGltcGxvZGUoJzogJywkYXJyYXkpKTsKICAgICAgJHZhbHVlID0gJHRoaXMtPl90b1R5cGUoJHZhbHVlKTsKICAgICAgcmV0dXJuIGFycmF5KCRrZXkgPT4gJHZhbHVlKTsKICAgIH0KCiAgICBpZiAoJGZpcnN0X2NoYXJhY3RlciA9PSAneycgJiYgJGxhc3RfY2hhcmFjdGVyID09ICd9JykgewogICAgICAkaW5uZXJWYWx1ZSA9IHRyaW0oc3Vic3RyICgkdmFsdWUsIDEsIC0xKSk7CiAgICAgIGlmICgkaW5uZXJWYWx1ZSA9PT0gJycpIHJldHVybiBhcnJheSgpOwogICAgICAvLyBJbmxpbmUgTWFwcGluZwogICAgICAvLyBUYWtlIG91dCBzdHJpbmdzIHNlcXVlbmNlcyBhbmQgbWFwcGluZ3MKICAgICAgJGV4cGxvZGUgPSAkdGhpcy0+X2lubGluZUVzY2FwZSgkaW5uZXJWYWx1ZSk7CiAgICAgIC8vIFByb3BhZ2F0ZSB2YWx1ZSBhcnJheQogICAgICAkYXJyYXkgPSBhcnJheSgpOwogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAkdikgewogICAgICAgICRTdWJBcnIgPSAkdGhpcy0+X3RvVHlwZSgkdik7CiAgICAgICAgaWYgKGVtcHR5KCRTdWJBcnIpKSBjb250aW51ZTsKICAgICAgICBpZiAoaXNfYXJyYXkgKCRTdWJBcnIpKSB7CiAgICAgICAgICAkYXJyYXlba2V5KCRTdWJBcnIpXSA9ICRTdWJBcnJba2V5KCRTdWJBcnIpXTsgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRhcnJheVtdID0gJFN1YkFycjsKICAgICAgfQogICAgICByZXR1cm4gJGFycmF5OwogICAgfQoKICAgIGlmICgkdmFsdWUgPT0gJ251bGwnIHx8ICR2YWx1ZSA9PSAnTlVMTCcgfHwgJHZhbHVlID09ICdOdWxsJyB8fCAkdmFsdWUgPT0gJycgfHwgJHZhbHVlID09ICd+JykgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBpZiAoIGlzX251bWVyaWMoJHZhbHVlKSAmJiBwcmVnX21hdGNoICgnL14oLXwpWzEtOV0rWzAtOV0qJC8nLCAkdmFsdWUpICl7CiAgICAgICRpbnR2YWx1ZSA9IChpbnQpJHZhbHVlOwogICAgICBpZiAoJGludHZhbHVlICE9IFBIUF9JTlRfTUFYICYmICRpbnR2YWx1ZSAhPSB+UEhQX0lOVF9NQVgpCiAgICAgICAgJHZhbHVlID0gJGludHZhbHVlOwogICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIGlmICggaXNfc3RyaW5nKCR2YWx1ZSkgJiYgcHJlZ19tYXRjaCgnL14wW3hYXVswLTlhLWZBLUZdKyQvJywgJHZhbHVlKSkgewogICAgICAvLyBIZXhhZGVjaW1hbCB2YWx1ZS4KICAgICAgcmV0dXJuIGhleGRlYygkdmFsdWUpOwogICAgfQoKICAgICR0aGlzLT5jb2VyY2VWYWx1ZSgkdmFsdWUpOwoKICAgIGlmIChpc19udW1lcmljKCR2YWx1ZSkpIHsKICAgICAgaWYgKCR2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDsKICAgICAgaWYgKHJ0cmltICgkdmFsdWUsIDApID09PSAkdmFsdWUpCiAgICAgICAgJHZhbHVlID0gKGZsb2F0KSR2YWx1ZTsKICAgICAgcmV0dXJuICR2YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gJHZhbHVlOwogIH0KCiAgLyoqCiAgICAgKiBVc2VkIGluIGlubGluZXMgdG8gY2hlY2sgZm9yIG1vcmUgaW5saW5lcyBvciBxdW90ZWQgc3RyaW5ncwogICAgICogQGFjY2VzcyBwcml2YXRlCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICBwcml2YXRlIGZ1bmN0aW9uIF9pbmxpbmVFc2NhcGUoJGlubGluZSkgewogICAgLy8gVGhlcmUncyBnb3R0YSBiZSBhIGNsZWFuZXIgd2F5IHRvIGRvIHRoaXMuLi4KICAgIC8vIFdoaWxlIHB1cmUgc2VxdWVuY2VzIHNlZW0gdG8gYmUgbmVzdGluZyBqdXN0IGZpbmUsCiAgICAvLyBwdXJlIG1hcHBpbmdzIGFuZCBtYXBwaW5ncyB3aXRoIHNlcXVlbmNlcyBpbnNpZGUgY2FuJ3QgZ28gdmVyeQogICAgLy8gZGVlcC4gIFRoaXMgbmVlZHMgdG8gYmUgZml4ZWQuCgogICAgJHNlcXMgPSBhcnJheSgpOwogICAgJG1hcHMgPSBhcnJheSgpOwogICAgJHNhdmVkX3N0cmluZ3MgPSBhcnJheSgpOwogICAgJHNhdmVkX2VtcHRpZXMgPSBhcnJheSgpOwoKICAgIC8vIENoZWNrIGZvciBlbXB0eSBzdHJpbmdzCiAgICAkcmVnZXggPSAnLygiIil8KFwnXCcpLyc7CiAgICBpZiAocHJlZ19tYXRjaF9hbGwoJHJlZ2V4LCRpbmxpbmUsJHN0cmluZ3MpKSB7CiAgICAgICRzYXZlZF9lbXB0aWVzID0gJHN0cmluZ3NbMF07CiAgICAgICRpbmxpbmUgID0gcHJlZ19yZXBsYWNlKCRyZWdleCwnWUFNTEVtcHR5JywkaW5saW5lKTsKICAgIH0KICAgIHVuc2V0KCRyZWdleCk7CgogICAgLy8gQ2hlY2sgZm9yIHN0cmluZ3MKICAgICRyZWdleCA9ICcvKD86KCIpfCg/OlwnKSkoKD8oMSlbXiJdK3xbXlwnXSspKSg/KDEpInxcJykvJzsKICAgIGlmIChwcmVnX21hdGNoX2FsbCgkcmVnZXgsJGlubGluZSwkc3RyaW5ncykpIHsKICAgICAgJHNhdmVkX3N0cmluZ3MgPSAkc3RyaW5nc1swXTsKICAgICAgJGlubGluZSAgPSBwcmVnX3JlcGxhY2UoJHJlZ2V4LCdZQU1MU3RyaW5nJywkaW5saW5lKTsKICAgIH0KICAgIHVuc2V0KCRyZWdleCk7CgogICAgLy8gZWNobyAkaW5saW5lOwoKICAgICRpID0gMDsKICAgIGRvIHsKCiAgICAvLyBDaGVjayBmb3Igc2VxdWVuY2VzCiAgICB3aGlsZSAocHJlZ19tYXRjaCgnL1xbKFtee31cW1xdXSspXF0vVScsJGlubGluZSwkbWF0Y2hzZXFzKSkgewogICAgICAkc2Vxc1tdID0gJG1hdGNoc2Vxc1swXTsKICAgICAgJGlubGluZSA9IHByZWdfcmVwbGFjZSgnL1xbKFtee31cW1xdXSspXF0vVScsICgnWUFNTFNlcScgLiAoY291bnQoJHNlcXMpIC0gMSkgLiAncycpLCAkaW5saW5lLCAxKTsKICAgIH0KCiAgICAvLyBDaGVjayBmb3IgbWFwcGluZ3MKICAgIHdoaWxlIChwcmVnX21hdGNoKCcveyhbXlxbXF17fV0rKX0vVScsJGlubGluZSwkbWF0Y2htYXBzKSkgewogICAgICAkbWFwc1tdID0gJG1hdGNobWFwc1swXTsKICAgICAgJGlubGluZSA9IHByZWdfcmVwbGFjZSgnL3soW15cW1xde31dKyl9L1UnLCAoJ1lBTUxNYXAnIC4gKGNvdW50KCRtYXBzKSAtIDEpIC4gJ3MnKSwgJGlubGluZSwgMSk7CiAgICB9CgogICAgaWYgKCRpKysgPj0gMTApIGJyZWFrOwoKICAgIH0gd2hpbGUgKHN0cnBvcyAoJGlubGluZSwgJ1snKSAhPT0gZmFsc2UgfHwgc3RycG9zICgkaW5saW5lLCAneycpICE9PSBmYWxzZSk7CgogICAgJGV4cGxvZGUgPSBleHBsb2RlKCcsJywkaW5saW5lKTsKICAgICRleHBsb2RlID0gYXJyYXlfbWFwKCd0cmltJywgJGV4cGxvZGUpOwogICAgJHN0cmluZ2kgPSAwOyAkaSA9IDA7CgogICAgd2hpbGUgKDEpIHsKCiAgICAvLyBSZS1hZGQgdGhlIHNlcXVlbmNlcwogICAgaWYgKCFlbXB0eSgkc2VxcykpIHsKICAgICAgZm9yZWFjaCAoJGV4cGxvZGUgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoc3RycG9zKCR2YWx1ZSwnWUFNTFNlcScpICE9PSBmYWxzZSkgewogICAgICAgICAgZm9yZWFjaCAoJHNlcXMgYXMgJHNlcWsgPT4gJHNlcSkgewogICAgICAgICAgICAkZXhwbG9kZVska2V5XSA9IHN0cl9yZXBsYWNlKCgnWUFNTFNlcScuJHNlcWsuJ3MnKSwkc2VxLCR2YWx1ZSk7CiAgICAgICAgICAgICR2YWx1ZSA9ICRleHBsb2RlWyRrZXldOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIFJlLWFkZCB0aGUgbWFwcGluZ3MKICAgIGlmICghZW1wdHkoJG1hcHMpKSB7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgaWYgKHN0cnBvcygkdmFsdWUsJ1lBTUxNYXAnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgIGZvcmVhY2ggKCRtYXBzIGFzICRtYXBrID0+ICRtYXApIHsKICAgICAgICAgICAgJGV4cGxvZGVbJGtleV0gPSBzdHJfcmVwbGFjZSgoJ1lBTUxNYXAnLiRtYXBrLidzJyksICRtYXAsICR2YWx1ZSk7CiAgICAgICAgICAgICR2YWx1ZSA9ICRleHBsb2RlWyRrZXldOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKCiAgICAvLyBSZS1hZGQgdGhlIHN0cmluZ3MKICAgIGlmICghZW1wdHkoJHNhdmVkX3N0cmluZ3MpKSB7CiAgICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgd2hpbGUgKHN0cnBvcygkdmFsdWUsJ1lBTUxTdHJpbmcnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICRleHBsb2RlWyRrZXldID0gcHJlZ19yZXBsYWNlKCcvWUFNTFN0cmluZy8nLCRzYXZlZF9zdHJpbmdzWyRzdHJpbmdpXSwkdmFsdWUsIDEpOwogICAgICAgICAgdW5zZXQoJHNhdmVkX3N0cmluZ3NbJHN0cmluZ2ldKTsKICAgICAgICAgICsrJHN0cmluZ2k7CiAgICAgICAgICAkdmFsdWUgPSAkZXhwbG9kZVska2V5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCgogICAgLy8gUmUtYWRkIHRoZSBlbXB0aWVzCiAgICBpZiAoIWVtcHR5KCRzYXZlZF9lbXB0aWVzKSkgewogICAgICBmb3JlYWNoICgkZXhwbG9kZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgIHdoaWxlIChzdHJwb3MoJHZhbHVlLCdZQU1MRW1wdHknKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICRleHBsb2RlWyRrZXldID0gcHJlZ19yZXBsYWNlKCcvWUFNTEVtcHR5LycsICcnLCAkdmFsdWUsIDEpOwogICAgICAgICAgJHZhbHVlID0gJGV4cGxvZGVbJGtleV07CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgJGZpbmlzaGVkID0gdHJ1ZTsKICAgIGZvcmVhY2ggKCRleHBsb2RlIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU2VxJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MTWFwJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MU3RyaW5nJykgIT09IGZhbHNlKSB7CiAgICAgICAgJGZpbmlzaGVkID0gZmFsc2U7IGJyZWFrOwogICAgICB9CiAgICAgIGlmIChzdHJwb3MoJHZhbHVlLCdZQU1MRW1wdHknKSAhPT0gZmFsc2UpIHsKICAgICAgICAkZmluaXNoZWQgPSBmYWxzZTsgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmICgkZmluaXNoZWQpIGJyZWFrOwoKICAgICRpKys7CiAgICBpZiAoJGkgPiAxMCkKICAgICAgYnJlYWs7IC8vIFByZXZlbnQgaW5maW5pdGUgbG9vcHMuCiAgICB9CgoKICAgIHJldHVybiAkZXhwbG9kZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gbGl0ZXJhbEJsb2NrQ29udGludWVzICgkbGluZSwgJGxpbmVJbmRlbnQpIHsKICAgIGlmICghdHJpbSgkbGluZSkpIHJldHVybiB0cnVlOwogICAgaWYgKHN0cmxlbigkbGluZSkgLSBzdHJsZW4obHRyaW0oJGxpbmUpKSA+ICRsaW5lSW5kZW50KSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gcmVmZXJlbmNlQ29udGVudHNCeUFsaWFzICgkYWxpYXMpIHsKICAgIGRvIHsKICAgICAgaWYgKCFpc3NldCgkdGhpcy0+U2F2ZWRHcm91cHNbJGFsaWFzXSkpIHsgZWNobyAiQmFkIGdyb3VwIG5hbWU6ICRhbGlhcy4iOyBicmVhazsgfQogICAgICAkZ3JvdXBQYXRoID0gJHRoaXMtPlNhdmVkR3JvdXBzWyRhbGlhc107CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5yZXN1bHQ7CiAgICAgIGZvcmVhY2ggKCRncm91cFBhdGggYXMgJGspIHsKICAgICAgICAkdmFsdWUgPSAkdmFsdWVbJGtdOwogICAgICB9CiAgICB9IHdoaWxlIChmYWxzZSk7CiAgICByZXR1cm4gJHZhbHVlOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBhZGRBcnJheUlubGluZSAoJGFycmF5LCAkaW5kZW50KSB7CiAgICAgICRDb21tb25Hcm91cFBhdGggPSAkdGhpcy0+cGF0aDsKICAgICAgaWYgKGVtcHR5ICgkYXJyYXkpKSByZXR1cm4gZmFsc2U7CgogICAgICBmb3JlYWNoICgkYXJyYXkgYXMgJGsgPT4gJF8pIHsKICAgICAgICAkdGhpcy0+YWRkQXJyYXkoYXJyYXkoJGsgPT4gJF8pLCAkaW5kZW50KTsKICAgICAgICAkdGhpcy0+cGF0aCA9ICRDb21tb25Hcm91cFBhdGg7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGFkZEFycmF5ICgkaW5jb21pbmdfZGF0YSwgJGluY29taW5nX2luZGVudCkgewoKICAgLy8gcHJpbnRfciAoJGluY29taW5nX2RhdGEpOwoKICAgIGlmIChjb3VudCAoJGluY29taW5nX2RhdGEpID4gMSkKICAgICAgcmV0dXJuICR0aGlzLT5hZGRBcnJheUlubGluZSAoJGluY29taW5nX2RhdGEsICRpbmNvbWluZ19pbmRlbnQpOwoKICAgICRrZXkgPSBrZXkgKCRpbmNvbWluZ19kYXRhKTsKICAgICR2YWx1ZSA9IGlzc2V0KCRpbmNvbWluZ19kYXRhWyRrZXldKSA/ICRpbmNvbWluZ19kYXRhWyRrZXldIDogbnVsbDsKICAgIGlmICgka2V5ID09PSAnX18hWUFNTFplcm8nKSAka2V5ID0gJzAnOwoKICAgIGlmICgkaW5jb21pbmdfaW5kZW50ID09IDAgJiYgISR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzICYmICEkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3IpIHsgLy8gU2hvcnRjdXQgZm9yIHJvb3QtbGV2ZWwgdmFsdWVzLgogICAgICBpZiAoJGtleSB8fCAka2V5ID09PSAnJyB8fCAka2V5ID09PSAnMCcpIHsKICAgICAgICAkdGhpcy0+cmVzdWx0WyRrZXldID0gJHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgICR0aGlzLT5yZXN1bHRbXSA9ICR2YWx1ZTsgZW5kICgkdGhpcy0+cmVzdWx0KTsgJGtleSA9IGtleSAoJHRoaXMtPnJlc3VsdCk7CiAgICAgIH0KICAgICAgJHRoaXMtPnBhdGhbJGluY29taW5nX2luZGVudF0gPSAka2V5OwogICAgICByZXR1cm47CiAgICB9CgoKCiAgICAkaGlzdG9yeSA9IGFycmF5KCk7CiAgICAvLyBVbmZvbGRpbmcgaW5uZXIgYXJyYXkgdHJlZS4KICAgICRoaXN0b3J5W10gPSAkX2FyciA9ICR0aGlzLT5yZXN1bHQ7CiAgICBmb3JlYWNoICgkdGhpcy0+cGF0aCBhcyAkaykgewogICAgICAkaGlzdG9yeVtdID0gJF9hcnIgPSAkX2Fyclska107CiAgICB9CgogICAgaWYgKCR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzKSB7CiAgICAgICR2YWx1ZSA9ICR0aGlzLT5yZWZlcmVuY2VDb250ZW50c0J5QWxpYXMoJHRoaXMtPl9jb250YWluc0dyb3VwQWxpYXMpOwogICAgICAkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbGlhcyA9IGZhbHNlOwogICAgfQoKCiAgICAvLyBBZGRpbmcgc3RyaW5nIG9yIG51bWVyaWMga2V5IHRvIHRoZSBpbm5lcm1vc3QgbGV2ZWwgb3IgJHRoaXMtPmFyci4KICAgIGlmIChpc19zdHJpbmcoJGtleSkgJiYgJGtleSA9PSAnPDwnKSB7CiAgICAgIGlmICghaXNfYXJyYXkgKCRfYXJyKSkgeyAkX2FyciA9IGFycmF5ICgpOyB9CgogICAgICAkX2FyciA9IGFycmF5X21lcmdlICgkX2FyciwgJHZhbHVlKTsKICAgIH0gZWxzZSBpZiAoJGtleSB8fCAka2V5ID09PSAnJyB8fCAka2V5ID09PSAnMCcpIHsKICAgICAgaWYgKCFpc19hcnJheSAoJF9hcnIpKQogICAgICAgICRfYXJyID0gYXJyYXkgKCRrZXk9PiR2YWx1ZSk7CiAgICAgIGVsc2UKICAgICAgICAkX2Fyclska2V5XSA9ICR2YWx1ZTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICghaXNfYXJyYXkgKCRfYXJyKSkgeyAkX2FyciA9IGFycmF5ICgkdmFsdWUpOyAka2V5ID0gMDsgfQogICAgICBlbHNlIHsgJF9hcnJbXSA9ICR2YWx1ZTsgZW5kICgkX2Fycik7ICRrZXkgPSBrZXkgKCRfYXJyKTsgfQogICAgfQoKICAgICRyZXZlcnNlX3BhdGggPSBhcnJheV9yZXZlcnNlKCR0aGlzLT5wYXRoKTsKICAgICRyZXZlcnNlX2hpc3RvcnkgPSBhcnJheV9yZXZlcnNlICgkaGlzdG9yeSk7CiAgICAkcmV2ZXJzZV9oaXN0b3J5WzBdID0gJF9hcnI7CiAgICAkY250ID0gY291bnQoJHJldmVyc2VfaGlzdG9yeSkgLSAxOwogICAgZm9yICgkaSA9IDA7ICRpIDwgJGNudDsgJGkrKykgewogICAgICAkcmV2ZXJzZV9oaXN0b3J5WyRpKzFdWyRyZXZlcnNlX3BhdGhbJGldXSA9ICRyZXZlcnNlX2hpc3RvcnlbJGldOwogICAgfQogICAgJHRoaXMtPnJlc3VsdCA9ICRyZXZlcnNlX2hpc3RvcnlbJGNudF07CgogICAgJHRoaXMtPnBhdGhbJGluY29taW5nX2luZGVudF0gPSAka2V5OwoKICAgIGlmICgkdGhpcy0+X2NvbnRhaW5zR3JvdXBBbmNob3IpIHsKICAgICAgJHRoaXMtPlNhdmVkR3JvdXBzWyR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvcl0gPSAkdGhpcy0+cGF0aDsKICAgICAgaWYgKGlzX2FycmF5ICgkdmFsdWUpKSB7CiAgICAgICAgJGsgPSBrZXkgKCR2YWx1ZSk7CiAgICAgICAgaWYgKCFpc19pbnQgKCRrKSkgewogICAgICAgICAgJHRoaXMtPlNhdmVkR3JvdXBzWyR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvcl1bJGluY29taW5nX2luZGVudCArIDJdID0gJGs7CiAgICAgICAgfQogICAgICB9CiAgICAgICR0aGlzLT5fY29udGFpbnNHcm91cEFuY2hvciA9IGZhbHNlOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHN0YXJ0c0xpdGVyYWxCbG9jayAoJGxpbmUpIHsKICAgICRsYXN0Q2hhciA9IHN1YnN0ciAodHJpbSgkbGluZSksIC0xKTsKICAgIGlmICgkbGFzdENoYXIgIT0gJz4nICYmICRsYXN0Q2hhciAhPSAnfCcpIHJldHVybiBmYWxzZTsKICAgIGlmICgkbGFzdENoYXIgPT0gJ3wnKSByZXR1cm4gJGxhc3RDaGFyOwogICAgLy8gSFRNTCB0YWdzIHNob3VsZCBub3QgYmUgY291bnRlZCBhcyBsaXRlcmFsIGJsb2Nrcy4KICAgIGlmIChwcmVnX21hdGNoICgnIzwuKj8+JCMnLCAkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiAkbGFzdENoYXI7CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBncmVlZGlseU5lZWROZXh0TGluZSgkbGluZSkgewogICAgJGxpbmUgPSB0cmltICgkbGluZSk7CiAgICBpZiAoIXN0cmxlbigkbGluZSkpIHJldHVybiBmYWxzZTsKICAgIGlmIChzdWJzdHIgKCRsaW5lLCAtMSwgMSkgPT0gJ10nKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJGxpbmVbMF0gPT0gJ1snKSByZXR1cm4gdHJ1ZTsKICAgIGlmIChwcmVnX21hdGNoICgnI15bXjpdKz86XHMqXFsjJywgJGxpbmUpKSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gYWRkTGl0ZXJhbExpbmUgKCRsaXRlcmFsQmxvY2ssICRsaW5lLCAkbGl0ZXJhbEJsb2NrU3R5bGUsICRpbmRlbnQgPSAtMSkgewogICAgJGxpbmUgPSBzZWxmOjpzdHJpcEluZGVudCgkbGluZSwgJGluZGVudCk7CiAgICBpZiAoJGxpdGVyYWxCbG9ja1N0eWxlICE9PSAnfCcpIHsKICAgICAgICAkbGluZSA9IHNlbGY6OnN0cmlwSW5kZW50KCRsaW5lKTsKICAgIH0KICAgICRsaW5lID0gcnRyaW0gKCRsaW5lLCAiXHJcblx0ICIpIC4gIlxuIjsKICAgIGlmICgkbGl0ZXJhbEJsb2NrU3R5bGUgPT0gJ3wnKSB7CiAgICAgIHJldHVybiAkbGl0ZXJhbEJsb2NrIC4gJGxpbmU7CiAgICB9CiAgICBpZiAoc3RybGVuKCRsaW5lKSA9PSAwKQogICAgICByZXR1cm4gcnRyaW0oJGxpdGVyYWxCbG9jaywgJyAnKSAuICJcbiI7CiAgICBpZiAoJGxpbmUgPT0gIlxuIiAmJiAkbGl0ZXJhbEJsb2NrU3R5bGUgPT0gJz4nKSB7CiAgICAgIHJldHVybiBydHJpbSAoJGxpdGVyYWxCbG9jaywgIiBcdCIpIC4gIlxuIjsKICAgIH0KICAgIGlmICgkbGluZSAhPSAiXG4iKQogICAgICAkbGluZSA9IHRyaW0gKCRsaW5lLCAiXHJcbiAiKSAuICIgIjsKICAgIHJldHVybiAkbGl0ZXJhbEJsb2NrIC4gJGxpbmU7CiAgfQoKICAgZnVuY3Rpb24gcmV2ZXJ0TGl0ZXJhbFBsYWNlSG9sZGVyICgkbGluZUFycmF5LCAkbGl0ZXJhbEJsb2NrKSB7CiAgICAgZm9yZWFjaCAoJGxpbmVBcnJheSBhcyAkayA9PiAkXykgewogICAgICBpZiAoaXNfYXJyYXkoJF8pKQogICAgICAgICRsaW5lQXJyYXlbJGtdID0gJHRoaXMtPnJldmVydExpdGVyYWxQbGFjZUhvbGRlciAoJF8sICRsaXRlcmFsQmxvY2spOwogICAgICBlbHNlIGlmIChzdWJzdHIoJF8sIC0xICogc3RybGVuICgkdGhpcy0+TGl0ZXJhbFBsYWNlSG9sZGVyKSkgPT0gJHRoaXMtPkxpdGVyYWxQbGFjZUhvbGRlcikKCSAgICAgICAkbGluZUFycmF5WyRrXSA9IHJ0cmltICgkbGl0ZXJhbEJsb2NrLCAiIFxyXG4iKTsKICAgICB9CiAgICAgcmV0dXJuICRsaW5lQXJyYXk7CiAgIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gc3RyaXBJbmRlbnQgKCRsaW5lLCAkaW5kZW50ID0gLTEpIHsKICAgIGlmICgkaW5kZW50ID09IC0xKSAkaW5kZW50ID0gc3RybGVuKCRsaW5lKSAtIHN0cmxlbihsdHJpbSgkbGluZSkpOwogICAgcmV0dXJuIHN1YnN0ciAoJGxpbmUsICRpbmRlbnQpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQYXJlbnRQYXRoQnlJbmRlbnQgKCRpbmRlbnQpIHsKICAgIGlmICgkaW5kZW50ID09IDApIHJldHVybiBhcnJheSgpOwogICAgJGxpbmVQYXRoID0gJHRoaXMtPnBhdGg7CiAgICBkbyB7CiAgICAgIGVuZCgkbGluZVBhdGgpOyAkbGFzdEluZGVudEluUGFyZW50UGF0aCA9IGtleSgkbGluZVBhdGgpOwogICAgICBpZiAoJGluZGVudCA8PSAkbGFzdEluZGVudEluUGFyZW50UGF0aCkgYXJyYXlfcG9wICgkbGluZVBhdGgpOwogICAgfSB3aGlsZSAoJGluZGVudCA8PSAkbGFzdEluZGVudEluUGFyZW50UGF0aCk7CiAgICByZXR1cm4gJGxpbmVQYXRoOwogIH0KCgogIHByaXZhdGUgZnVuY3Rpb24gY2xlYXJCaWdnZXJQYXRoVmFsdWVzICgkaW5kZW50KSB7CgoKICAgIGlmICgkaW5kZW50ID09IDApICR0aGlzLT5wYXRoID0gYXJyYXkoKTsKICAgIGlmIChlbXB0eSAoJHRoaXMtPnBhdGgpKSByZXR1cm4gdHJ1ZTsKCiAgICBmb3JlYWNoICgkdGhpcy0+cGF0aCBhcyAkayA9PiAkXykgewogICAgICBpZiAoJGsgPiAkaW5kZW50KSB1bnNldCAoJHRoaXMtPnBhdGhbJGtdKTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKICB9CgoKICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBpc0NvbW1lbnQgKCRsaW5lKSB7CiAgICBpZiAoISRsaW5lKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJGxpbmVbMF0gPT0gJyMnKSByZXR1cm4gdHJ1ZTsKICAgIGlmICh0cmltKCRsaW5lLCAiIFxyXG5cdCIpID09ICctLS0nKSByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzRW1wdHkgKCRsaW5lKSB7CiAgICByZXR1cm4gKHRyaW0gKCRsaW5lKSA9PT0gJycpOwogIH0KCgogIHByaXZhdGUgZnVuY3Rpb24gaXNBcnJheUVsZW1lbnQgKCRsaW5lKSB7CiAgICBpZiAoISRsaW5lIHx8ICFpc19zY2FsYXIoJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoc3Vic3RyKCRsaW5lLCAwLCAyKSAhPSAnLSAnKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoc3RybGVuICgkbGluZSkgPiAzKQogICAgICBpZiAoc3Vic3RyKCRsaW5lLDAsMykgPT0gJy0tLScpIHJldHVybiBmYWxzZTsKCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gaXNIYXNoRWxlbWVudCAoJGxpbmUpIHsKICAgIHJldHVybiBzdHJwb3MoJGxpbmUsICc6Jyk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGlzTGl0ZXJhbCAoJGxpbmUpIHsKICAgIGlmICgkdGhpcy0+aXNBcnJheUVsZW1lbnQoJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoJHRoaXMtPmlzSGFzaEVsZW1lbnQoJGxpbmUpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgoKICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB1bnF1b3RlICgkdmFsdWUpIHsKICAgIGlmICghJHZhbHVlKSByZXR1cm4gJHZhbHVlOwogICAgaWYgKCFpc19zdHJpbmcoJHZhbHVlKSkgcmV0dXJuICR2YWx1ZTsKICAgIGlmICgkdmFsdWVbMF0gPT0gJ1wnJykgcmV0dXJuIHRyaW0gKCR2YWx1ZSwgJ1wnJyk7CiAgICBpZiAoJHZhbHVlWzBdID09ICciJykgcmV0dXJuIHRyaW0gKCR2YWx1ZSwgJyInKTsKICAgIHJldHVybiAkdmFsdWU7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0c01hcHBlZFNlcXVlbmNlICgkbGluZSkgewogICAgcmV0dXJuIChzdWJzdHIoJGxpbmUsIDAsIDIpID09ICctICcgJiYgc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICc6Jyk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHJldHVybk1hcHBlZFNlcXVlbmNlICgkbGluZSkgewogICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICRrZXkgICAgICAgICA9IHNlbGY6OnVucXVvdGUodHJpbShzdWJzdHIoJGxpbmUsMSwtMSkpKTsKICAgICRhcnJheVska2V5XSA9IGFycmF5KCk7CiAgICAkdGhpcy0+ZGVsYXllZFBhdGggPSBhcnJheShzdHJwb3MgKCRsaW5lLCAka2V5KSArICR0aGlzLT5pbmRlbnQgPT4gJGtleSk7CiAgICByZXR1cm4gYXJyYXkoJGFycmF5KTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tLZXlzSW5WYWx1ZSgkdmFsdWUpIHsKICAgIGlmIChzdHJjaHIoJ1t7IlwnJywgJHZhbHVlWzBdKSA9PT0gZmFsc2UpIHsKICAgICAgaWYgKHN0cmNocigkdmFsdWUsICc6ICcpICE9PSBmYWxzZSkgewogICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oJ1RvbyBtYW55IGtleXM6ICcuJHZhbHVlKTsKICAgICAgfQogICAgfQogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiByZXR1cm5NYXBwZWRWYWx1ZSAoJGxpbmUpIHsKICAgICR0aGlzLT5jaGVja0tleXNJblZhbHVlKCRsaW5lKTsKICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAka2V5ICAgICAgICAgPSBzZWxmOjp1bnF1b3RlICh0cmltKHN1YnN0cigkbGluZSwwLC0xKSkpOwogICAgJGFycmF5WyRrZXldID0gJyc7CiAgICByZXR1cm4gJGFycmF5OwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiBzdGFydHNNYXBwZWRWYWx1ZSAoJGxpbmUpIHsKICAgIHJldHVybiAoc3Vic3RyICgkbGluZSwgLTEsIDEpID09ICc6Jyk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGlzUGxhaW5BcnJheSAoJGxpbmUpIHsKICAgIHJldHVybiAoJGxpbmVbMF0gPT0gJ1snICYmIHN1YnN0ciAoJGxpbmUsIC0xLCAxKSA9PSAnXScpOwogIH0KCiAgcHJpdmF0ZSBmdW5jdGlvbiByZXR1cm5QbGFpbkFycmF5ICgkbGluZSkgewogICAgcmV0dXJuICR0aGlzLT5fdG9UeXBlKCRsaW5lKTsKICB9CgogIHByaXZhdGUgZnVuY3Rpb24gcmV0dXJuS2V5VmFsdWVQYWlyICgkbGluZSkgewogICAgJGFycmF5ID0gYXJyYXkoKTsKICAgICRrZXkgPSAnJzsKICAgIGlmIChzdHJwb3MgKCRsaW5lLCAnOiAnKSkgewogICAgICAvLyBJdCdzIGEga2V5L3ZhbHVlIHBhaXIgbW9zdCBsaWtlbHkKICAgICAgLy8gSWYgdGhlIGtleSBpcyBpbiBkb3VibGUgcXVvdGVzIHB1bGwgaXQgb3V0CiAgICAgIGlmICgoJGxpbmVbMF0gPT0gJyInIHx8ICRsaW5lWzBdID09ICInIikgJiYgcHJlZ19tYXRjaCgnL14oWyJcJ10oLiopWyJcJ10oXHMpKjopLycsJGxpbmUsJG1hdGNoZXMpKSB7CiAgICAgICAgJHZhbHVlID0gdHJpbShzdHJfcmVwbGFjZSgkbWF0Y2hlc1sxXSwnJywkbGluZSkpOwogICAgICAgICRrZXkgICA9ICRtYXRjaGVzWzJdOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIERvIHNvbWUgZ3Vlc3N3b3JrIGFzIHRvIHRoZSBrZXkgYW5kIHRoZSB2YWx1ZQogICAgICAgICRleHBsb2RlID0gZXhwbG9kZSgnOiAnLCAkbGluZSk7CiAgICAgICAgJGtleSAgICAgPSB0cmltKGFycmF5X3NoaWZ0KCRleHBsb2RlKSk7CiAgICAgICAgJHZhbHVlICAgPSB0cmltKGltcGxvZGUoJzogJywgJGV4cGxvZGUpKTsKICAgICAgICAkdGhpcy0+Y2hlY2tLZXlzSW5WYWx1ZSgkdmFsdWUpOwogICAgICB9CiAgICAgIC8vIFNldCB0aGUgdHlwZSBvZiB0aGUgdmFsdWUuICBJbnQsIHN0cmluZywgZXRjCiAgICAgICR2YWx1ZSA9ICR0aGlzLT5fdG9UeXBlKCR2YWx1ZSk7CiAgICAgIGlmICgka2V5ID09PSAnMCcpICRrZXkgPSAnX18hWUFNTFplcm8nOwogICAgICAkYXJyYXlbJGtleV0gPSAkdmFsdWU7CiAgICB9IGVsc2UgewogICAgICAkYXJyYXkgPSBhcnJheSAoJGxpbmUpOwogICAgfQogICAgcmV0dXJuICRhcnJheTsKCiAgfQoKCiAgcHJpdmF0ZSBmdW5jdGlvbiByZXR1cm5BcnJheUVsZW1lbnQgKCRsaW5lKSB7CiAgICAgaWYgKHN0cmxlbigkbGluZSkgPD0gMSkgcmV0dXJuIGFycmF5KGFycmF5KCkpOyAvLyBXZWlyZCAlKQogICAgICRhcnJheSA9IGFycmF5KCk7CiAgICAgJHZhbHVlICAgPSB0cmltKHN1YnN0cigkbGluZSwxKSk7CiAgICAgJHZhbHVlICAgPSAkdGhpcy0+X3RvVHlwZSgkdmFsdWUpOwogICAgIGlmICgkdGhpcy0+aXNBcnJheUVsZW1lbnQoJHZhbHVlKSkgewogICAgICAgJHZhbHVlID0gJHRoaXMtPnJldHVybkFycmF5RWxlbWVudCgkdmFsdWUpOwogICAgIH0KICAgICAkYXJyYXlbXSA9ICR2YWx1ZTsKICAgICByZXR1cm4gJGFycmF5OwogIH0KCgogIHByaXZhdGUgZnVuY3Rpb24gbm9kZUNvbnRhaW5zR3JvdXAgKCRsaW5lKSB7CiAgICAkc3ltYm9sc0ZvclJlZmVyZW5jZSA9ICdBLXowLTlfXC0nOwogICAgaWYgKHN0cnBvcygkbGluZSwgJyYnKSA9PT0gZmFsc2UgJiYgc3RycG9zKCRsaW5lLCAnKicpID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlOyAvLyBQbGVhc2UgZGllIGZhc3QgOy0pCiAgICBpZiAoJGxpbmVbMF0gPT0gJyYnICYmIHByZWdfbWF0Y2goJy9eKCZbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmICgkbGluZVswXSA9PSAnKicgJiYgcHJlZ19tYXRjaCgnL14oXCpbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoKCcvKCZbJy4kc3ltYm9sc0ZvclJlZmVyZW5jZS4nXSspJC8nLCAkbGluZSwgJG1hdGNoZXMpKSByZXR1cm4gJG1hdGNoZXNbMV07CiAgICBpZiAocHJlZ19tYXRjaCgnLyhcKlsnLiRzeW1ib2xzRm9yUmVmZXJlbmNlLiddKyQpLycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIGlmIChwcmVnX21hdGNoICgnI15ccyo8PFxzKjpccyooXCpbXlxzXSspLiokIycsICRsaW5lLCAkbWF0Y2hlcykpIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgIHJldHVybiBmYWxzZTsKCiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIGFkZEdyb3VwICgkbGluZSwgJGdyb3VwKSB7CiAgICBpZiAoJGdyb3VwWzBdID09ICcmJykgJHRoaXMtPl9jb250YWluc0dyb3VwQW5jaG9yID0gc3Vic3RyICgkZ3JvdXAsIDEpOwogICAgaWYgKCRncm91cFswXSA9PSAnKicpICR0aGlzLT5fY29udGFpbnNHcm91cEFsaWFzID0gc3Vic3RyICgkZ3JvdXAsIDEpOwogICAgLy9wcmludF9yICgkdGhpcy0+cGF0aCk7CiAgfQoKICBwcml2YXRlIGZ1bmN0aW9uIHN0cmlwR3JvdXAgKCRsaW5lLCAkZ3JvdXApIHsKICAgICRsaW5lID0gdHJpbShzdHJfcmVwbGFjZSgkZ3JvdXAsICcnLCAkbGluZSkpOwogICAgcmV0dXJuICRsaW5lOwogIH0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2kxOG5fYXV0b2xvYWRlciA9IF9fRElSX18gLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwoKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX2kxOG5fYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9pMThuX2F1dG9sb2FkZXI7Cn0KCmlmICggY2xhc3NfZXhpc3RzKCAnV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZScgKSApIHsKCVdQX0NMSTo6YWRkX2NvbW1hbmQoICdpMThuJywgJ1xXUF9DTElcSTE4blxDb21tYW5kTmFtZXNwYWNlJyApOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnaTE4biBtYWtlLXBvdCcsICdcV1BfQ0xJXEkxOG5cTWFrZVBvdENvbW1hbmQnICk7CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnaTE4biBtYWtlLWpzb24nLCAnXFdQX0NMSVxJMThuXE1ha2VKc29uQ29tbWFuZCcgKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoICdpMThuIG1ha2UtbW8nLCAnXFdQX0NMSVxJMThuXE1ha2VNb0NvbW1hbmQnICk7Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgUmVjdXJzaXZlQ2FsbGJhY2tGaWx0ZXJJdGVyYXRvcjsKdXNlIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOwp1c2UgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjsKdXNlIFNwbEZpbGVJbmZvOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwoKdHJhaXQgSXRlcmFibGVDb2RlRXh0cmFjdG9yIHsKCglwcml2YXRlIHN0YXRpYyAkZGlyID0gJyc7CgoJLyoqCgkgKiBFeHRyYWN0IHRoZSB0cmFuc2xhdGlvbnMgZnJvbSBhIGZpbGUuCgkgKgoJICogQHBhcmFtIGFycmF5fHN0cmluZyAkZmlsZV9vcl9maWxlcyBBIHBhdGggb2YgYSBmaWxlIG9yIGZpbGVzCgkgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMgIFRoZSB0cmFuc2xhdGlvbnMgaW5zdGFuY2UgdG8gYXBwZW5kIHRoZSBuZXcgdHJhbnNsYXRpb25zLgoJICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucyAgICAgIHsKCSAqICAgICBPcHRpb25hbC4gQW4gYXJyYXkgb2Ygb3B0aW9ucyBwYXNzZWQgZG93biB0byBzdGF0aWM6OmZyb21TdHJpbmcoKQoJICoKCSAqICAgICBAdHlwZSBib29sICAkd3BFeHRyYWN0VGVtcGxhdGVzIEV4dHJhY3QgJ1RlbXBsYXRlIE5hbWUnIGhlYWRlcnMgaW4gdGhlbWUgZmlsZXMuIERlZmF1bHQgJ2ZhbHNlJy4KCSAqICAgICBAdHlwZSBhcnJheSAkcmVzdHJpY3RGaWxlTmFtZXMgIFNraXAgYWxsIGZpbGVzIHdoaWNoIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhpcyBhcnJheS4KCSAqIH0KCSAqIEByZXR1cm4gbnVsbAoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlKCAkZmlsZV9vcl9maWxlcywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJZm9yZWFjaCAoIHN0YXRpYzo6Z2V0RmlsZXMoICRmaWxlX29yX2ZpbGVzICkgYXMgJGZpbGUgKSB7CgkJCWlmICggISBlbXB0eSggJG9wdGlvbnNbJ3Jlc3RyaWN0RmlsZU5hbWVzJ10gKSApIHsKCQkJCSRiYXNlbmFtZSA9IFV0aWxzXGJhc2VuYW1lKCAkZmlsZSApOwoJCQkJaWYgKCAhIGluX2FycmF5KCAkYmFzZW5hbWUsICRvcHRpb25zWydyZXN0cmljdEZpbGVOYW1lcyddLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCX0KCgkJCS8vIE1ha2Ugc3VyZSBhIHJlbGF0aXZlIGZpbGUgcGF0aCBpcyBhZGRlZCBhcyBhIGNvbW1lbnQuCgkJCSRvcHRpb25zWydmaWxlJ10gPSBsdHJpbSggc3RyX3JlcGxhY2UoIHN0YXRpYzo6JGRpciwgJycsIFV0aWxzXG5vcm1hbGl6ZV9wYXRoKCAkZmlsZSApICksICcvJyApOwoKCQkJJHN0cmluZyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkZmlsZSApOwoKCQkJaWYgKCAhICRzdHJpbmcgKSB7CgkJCQlXUF9DTEk6OmRlYnVnKAoJCQkJCXNwcmludGYoCgkJCQkJCSdDb3VsZCBub3QgbG9hZCBmaWxlICUxcycsCgkJCQkJCSRmaWxlCgkJCQkJKSwKCQkJCQknbWFrZS1wb3QnCgkJCQkpOwoKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgZW1wdHkoICRvcHRpb25zWyd3cEV4dHJhY3RUZW1wbGF0ZXMnXSApICkgewoJCQkJJGhlYWRlcnMgPSBNYWtlUG90Q29tbWFuZDo6Z2V0X2ZpbGVfZGF0YV9mcm9tX3N0cmluZyggJHN0cmluZywgWyAnVGVtcGxhdGUgTmFtZScgPT4gJ1RlbXBsYXRlIE5hbWUnIF0gKTsKCgkJCQlpZiAoICEgZW1wdHkoICRoZWFkZXJzWydUZW1wbGF0ZSBOYW1lJ10gKSApIHsKCQkJCQkkdHJhbnNsYXRpb24gPSBuZXcgVHJhbnNsYXRpb24oICcnLCAkaGVhZGVyc1snVGVtcGxhdGUgTmFtZSddICk7CgkJCQkJJHRyYW5zbGF0aW9uLT5hZGRFeHRyYWN0ZWRDb21tZW50KCAnVGVtcGxhdGUgTmFtZSBvZiB0aGUgdGhlbWUnICk7CgoJCQkJCSR0cmFuc2xhdGlvbnNbXSA9ICR0cmFuc2xhdGlvbjsKCQkJCX0KCQkJfQoKCQkJc3RhdGljOjpmcm9tU3RyaW5nKCAkc3RyaW5nLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyApOwoJCX0KCX0KCgkvKioKCSAqIEV4dHJhY3QgdGhlIHRyYW5zbGF0aW9ucyBmcm9tIGEgZmlsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRkaXIgICAgICAgICAgICAgICAgUm9vdCBwYXRoIHRvIHN0YXJ0IHRoZSByZWN1cnNpdmUgdHJhdmVyc2FsIGluLgoJICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zIFRoZSB0cmFuc2xhdGlvbnMgaW5zdGFuY2UgdG8gYXBwZW5kIHRoZSBuZXcgdHJhbnNsYXRpb25zLgoJICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucyAgICAgIHsKCSAqICAgICBPcHRpb25hbC4gQW4gYXJyYXkgb2Ygb3B0aW9ucyBwYXNzZWQgZG93biB0byBzdGF0aWM6OmZyb21TdHJpbmcoKQoJICoKCSAqICAgICBAdHlwZSBib29sICR3cEV4dHJhY3RUZW1wbGF0ZXMgRXh0cmFjdCAnVGVtcGxhdGUgTmFtZScgaGVhZGVycyBpbiB0aGVtZSBmaWxlcy4gRGVmYXVsdCAnZmFsc2UnLgoJICogICAgIEB0eXBlIGFycmF5ICRleGNsdWRlICAgICAgICAgICBBIGxpc3Qgb2YgcGF0aCB0byBleGNsdWRlLiBEZWZhdWx0IFtdLgoJICogICAgIEB0eXBlIGFycmF5ICRleHRlbnNpb25zICAgICAgICBBIGxpc3Qgb2YgZXh0ZW5zaW9ucyB0byBwcm9jZXNzLiBEZWZhdWx0IFtdLgoJICogfQoJICogQHJldHVybiBudWxsCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbURpcmVjdG9yeSggJGRpciwgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJJGRpciA9IFV0aWxzXG5vcm1hbGl6ZV9wYXRoKCAkZGlyICk7CgoJCXN0YXRpYzo6JGRpciA9ICRkaXI7CgoJCSRpbmNsdWRlID0gaXNzZXQoICRvcHRpb25zWydpbmNsdWRlJ10gKSA/ICRvcHRpb25zWydpbmNsdWRlJ10gOiBbXTsKCQkkZXhjbHVkZSA9IGlzc2V0KCAkb3B0aW9uc1snZXhjbHVkZSddICkgPyAkb3B0aW9uc1snZXhjbHVkZSddIDogW107CgoJCSRmaWxlcyA9IHN0YXRpYzo6Z2V0RmlsZXNGcm9tRGlyZWN0b3J5KCAkZGlyLCAkaW5jbHVkZSwgJGV4Y2x1ZGUsICRvcHRpb25zWydleHRlbnNpb25zJ10gKTsKCgkJaWYgKCAhIGVtcHR5KCAkZmlsZXMgKSApIHsKCQkJc3RhdGljOjpmcm9tRmlsZSggJGZpbGVzLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyApOwoJCX0KCgkJc3RhdGljOjokZGlyID0gJyc7Cgl9CgoJLyoqCgkgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBmaWxlIGlzIHZhbGlkIGJhc2VkIG9uIGdpdmVuIG1hdGNoZXJzLgoJICoKCSAqIEBwYXJhbSBTcGxGaWxlSW5mbyAkZmlsZSAgICAgRmlsZSBvciBkaXJlY3RvcnkuCgkgKiBAcGFyYW0gYXJyYXkgICAgICAgJG1hdGNoZXJzIExpc3Qgb2YgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHRvIG1hdGNoLgoJICogQHJldHVybiBpbnQgSG93IHN0cm9uZ2x5IHRoZSBmaWxlIGlzIG1hdGNoZWQuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gY2FsY3VsYXRlTWF0Y2hTY29yZSggU3BsRmlsZUluZm8gJGZpbGUsIGFycmF5ICRtYXRjaGVycyA9IFtdICkgewoJCWlmICggZW1wdHkoICRtYXRjaGVycyApICkgewoJCQlyZXR1cm4gMDsKCQl9CgoJCWlmICggaW5fYXJyYXkoICRmaWxlLT5nZXRCYXNlbmFtZSgpLCAkbWF0Y2hlcnMsIHRydWUgKSApIHsKCQkJcmV0dXJuIDEwOwoJCX0KCgkJLy8gQ2hlY2sgZm9yIG1vcmUgY29tcGxleCBwYXRocywgZS5nLiAvc29tZS9zdWIvZm9sZGVyLgoJCSRyb290X3JlbGF0aXZlX3BhdGggPSBzdHJfcmVwbGFjZSggc3RhdGljOjokZGlyLCAnJywgJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCgkJZm9yZWFjaCAoICRtYXRjaGVycyBhcyAkcGF0aF9vcl9maWxlICkgewoJCQkkcGF0dGVybiA9IHByZWdfcXVvdGUoIHN0cl9yZXBsYWNlKCAnKicsICdfX3dpbGRjYXJkX18nLCAkcGF0aF9vcl9maWxlICksICcvJyApOwoJCQkkcGF0dGVybiA9ICcoXnwvKScgLiBzdHJfcmVwbGFjZSggJ19fd2lsZGNhcmRfXycsICcoLispJywgJHBhdHRlcm4gKTsKCgkJCS8vIEJhc2Ugc2NvcmUgaXMgdGhlIGFtb3VudCBvZiBuZXN0ZWQgZGlyZWN0b3JpZXMsIGRpc2NvdW50aW5nIHdpbGRjYXJkcy4KCQkJJGJhc2Vfc2NvcmUgPSBjb3VudCgKCQkJCWFycmF5X2ZpbHRlcigKCQkJCQlleHBsb2RlKCAnLycsICRwYXRoX29yX2ZpbGUgKSwKCQkJCQlzdGF0aWMgZnVuY3Rpb24gKCAkY29tcG9uZW50ICkgewoJCQkJCQlyZXR1cm4gJyonICE9PSAkY29tcG9uZW50OwoJCQkJCX0KCQkJCSkKCQkJKTsKCQkJaWYgKCAwID09PSAkYmFzZV9zY29yZSApIHsKCQkJCS8vIElmIHRoZSBtYXRjaGVyIGlzIHNpbXBseSAqIGl0IGdldHMgYSBzY29yZSBhYm92ZSB0aGUgaW1wbGljaXQgc2NvcmUgYnV0IGJlbG93IDEuCgkJCQkkYmFzZV9zY29yZSA9IDAuMjsKCQkJfQoKCQkJLy8gSWYgdGhlIG1hdGNoZXIgY29udGFpbnMgbm8gd2lsZGNhcmRzIGFuZCBtYXRjaGVzIHRoZSBlbmQgb2YgdGhlIHBhdGguCgkJCWlmICgKCQkJCWZhbHNlID09PSBzdHJwb3MoICRwYXRoX29yX2ZpbGUsICcqJyApICYmCgkJCQlmYWxzZSAhPT0gbWJfZXJlZyggJHBhdHRlcm4gLiAnJCcsICRyb290X3JlbGF0aXZlX3BhdGggKQoJCQkpIHsKCQkJCXJldHVybiAkYmFzZV9zY29yZSAqIDEwOwoJCQl9CgoJCQkvLyBJZiB0aGUgbWF0Y2hlciBtYXRjaGVzIHRoZSBlbmQgb2YgdGhlIHBhdGggb3IgYSBmdWxsIGRpcmVjdG9yeSBjb250YWluZWQuCgkJCWlmICggZmFsc2UgIT09IG1iX2VyZWcoICRwYXR0ZXJuIC4gJygvfCQpJywgJHJvb3RfcmVsYXRpdmVfcGF0aCApICkgewoJCQkJcmV0dXJuICRiYXNlX3Njb3JlOwoJCQl9CgkJfQoKCQlyZXR1cm4gMDsKCX0KCgkvKioKCSAqIERldGVybWluZXMgd2hldGhlciBvciBub3QgYSBkaXJlY3RvcnkgaGFzIGNoaWxkcmVuIHRoYXQgbWF5IGJlIG1hdGNoZWQuCgkgKgoJICogQHBhcmFtIFNwbEZpbGVJbmZvICRkaXIgICAgICBEaXJlY3RvcnkuCgkgKiBAcGFyYW0gYXJyYXkgICAgICAgJG1hdGNoZXJzIExpc3Qgb2YgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHRvIG1hdGNoLgoJICogQHJldHVybiBib29sIFdoZXRoZXIgb3Igbm90IHRoZXJlIGFyZSBhbnkgbWF0Y2hlcnMgZm9yIGNoaWxkcmVuIG9mIHRoaXMgZGlyZWN0b3J5LgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGNvbnRhaW5zTWF0Y2hpbmdDaGlsZHJlbiggU3BsRmlsZUluZm8gJGRpciwgYXJyYXkgJG1hdGNoZXJzID0gW10gKSB7CgkJaWYgKCBlbXB0eSggJG1hdGNoZXJzICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qKiBAdmFyIHN0cmluZyAkcm9vdF9yZWxhdGl2ZV9wYXRoICovCgkJJHJvb3RfcmVsYXRpdmVfcGF0aCA9IHN0cl9yZXBsYWNlKCBzdGF0aWM6OiRkaXIsICcnLCAkZGlyLT5nZXRQYXRobmFtZSgpICk7CgoJCWZvcmVhY2ggKCAkbWF0Y2hlcnMgYXMgJHBhdGhfb3JfZmlsZSApIHsKCQkJLy8gSWYgdGhlIG1hdGNoZXIgY29udGFpbnMgbm8gd2lsZGNhcmRzIGFuZCB0aGUgcGF0aCBtYXRjaGVzIHRoZSBzdGFydCBvZiB0aGUgbWF0Y2hlci4KCQkJaWYgKAoJCQkJJycgIT09ICRyb290X3JlbGF0aXZlX3BhdGggJiYKCQkJCWZhbHNlID09PSBzdHJwb3MoICRwYXRoX29yX2ZpbGUsICcqJyApICYmCgkJCQkwID09PSBzdHJwb3MoICRwYXRoX29yX2ZpbGUgLiAnLycsICRyb290X3JlbGF0aXZlX3BhdGggKQoJCQkpIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgoJCQkkYmFzZSA9IGN1cnJlbnQoIGV4cGxvZGUoICcqJywgJHBhdGhfb3JfZmlsZSApICk7CgoJCQkvLyBJZiBzdGFydCBvZiB0aGUgcGF0aCBtYXRjaGVzIHRoZSBzdGFydCBvZiB0aGUgbWF0Y2hlciB1bnRpbCB0aGUgZmlyc3Qgd2lsZGNhcmQuCgkJCS8vIE9yIHRoZSBzdGFydCBvZiB0aGUgbWF0Y2hlciB1bnRpbCB0aGUgZmlyc3Qgd2lsZGNhcmQgbWF0Y2hlcyB0aGUgc3RhcnQgb2YgdGhlIHBhdGguCgkJCWlmICgKCQkJCSggJycgIT09ICRyb290X3JlbGF0aXZlX3BhdGggJiYgMCA9PT0gc3RycG9zKCAkYmFzZSwgJHJvb3RfcmVsYXRpdmVfcGF0aCApICkgfHwKCQkJCSggJycgIT09ICRiYXNlICYmIDAgPT09IHN0cnBvcyggJHJvb3RfcmVsYXRpdmVfcGF0aCwgJGJhc2UgKSApCgkJCSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJlY3Vyc2l2ZWx5IGdldHMgYWxsIFBIUCBmaWxlcyB3aXRoaW4gYSBkaXJlY3RvcnkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZGlyIEEgcGF0aCBvZiBhIGRpcmVjdG9yeS4KCSAqIEBwYXJhbSBhcnJheSAkaW5jbHVkZSBMaXN0IG9mIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBpbmNsdWRlLgoJICogQHBhcmFtIGFycmF5ICRleGNsdWRlIExpc3Qgb2YgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHRvIHNraXAuCgkgKiBAcGFyYW0gYXJyYXkgJGV4dGVuc2lvbnMgTGlzdCBvZiBmaWxlbmFtZSBleHRlbnNpb25zIHRvIHByb2Nlc3MuCgkgKgoJICogQHJldHVybiBhcnJheSBGaWxlIGxpc3QuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RmlsZXNGcm9tRGlyZWN0b3J5KCAkZGlyLCBhcnJheSAkaW5jbHVkZSA9IFtdLCBhcnJheSAkZXhjbHVkZSA9IFtdLCAkZXh0ZW5zaW9ucyA9IFtdICkgewoJCSRmaWx0ZXJlZF9maWxlcyA9IFtdOwoKCQkkZmlsZXMgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigKCQkJbmV3IFJlY3Vyc2l2ZUNhbGxiYWNrRmlsdGVySXRlcmF0b3IoCgkJCQluZXcgUmVjdXJzaXZlRGlyZWN0b3J5SXRlcmF0b3IoICRkaXIsIFJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMgfCBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcjo6VU5JWF9QQVRIUyApLAoJCQkJc3RhdGljIGZ1bmN0aW9uICggJGZpbGUsICRrZXksICRpdGVyYXRvciApIHVzZSAoICRpbmNsdWRlLCAkZXhjbHVkZSwgJGV4dGVuc2lvbnMgKSB7CgkJCQkJLyoqIEB2YXIgUmVjdXJzaXZlQ2FsbGJhY2tGaWx0ZXJJdGVyYXRvciAkaXRlcmF0b3IgKi8KCQkJCQkvKiogQHZhciBTcGxGaWxlSW5mbyAkZmlsZSAqLwoKCQkJCQkvLyBOb3JtYWxpemUgaW5jbHVkZSBhbmQgZXhjbHVkZSBwYXRocy4KCQkJCQkkaW5jbHVkZSA9IGFycmF5X21hcCggJ3N0YXRpYzo6dHJpbV9sZWFkaW5nX3NsYXNoJywgJGluY2x1ZGUgKTsKCQkJCQkkZXhjbHVkZSA9IGFycmF5X21hcCggJ3N0YXRpYzo6dHJpbV9sZWFkaW5nX3NsYXNoJywgJGV4Y2x1ZGUgKTsKCgkJCQkJLy8gSWYgbm8gJGluY2x1ZGUgaXMgcGFzc2VkIGV2ZXJ5dGhpbmcgZ2V0cyB0aGUgd2Vha2VzdCBwb3NzaWJsZSBtYXRjaGluZyBzY29yZS4KCQkJCQkkaW5jbHVzaW9uX3Njb3JlID0gZW1wdHkoICRpbmNsdWRlICkgPyAwLjEgOiBzdGF0aWM6OmNhbGN1bGF0ZU1hdGNoU2NvcmUoICRmaWxlLCAkaW5jbHVkZSApOwoJCQkJCSRleGNsdXNpb25fc2NvcmUgPSBzdGF0aWM6OmNhbGN1bGF0ZU1hdGNoU2NvcmUoICRmaWxlLCAkZXhjbHVkZSApOwoKCQkJCQkvLyBBbHdheXMgaW5jbHVkZSBkaXJlY3RvcmllcyB0aGF0IGFyZW4ndCBleGNsdWRlZC4KCQkJCQlpZiAoIDAgPT09ICRleGNsdXNpb25fc2NvcmUgJiYgJGl0ZXJhdG9yLT5oYXNDaGlsZHJlbigpICkgewoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQl9CgoJCQkJCWlmICggKCAwID09PSAkaW5jbHVzaW9uX3Njb3JlIHx8ICRleGNsdXNpb25fc2NvcmUgPiAkaW5jbHVzaW9uX3Njb3JlICkgJiYgJGl0ZXJhdG9yLT5oYXNDaGlsZHJlbigpICkgewoJCQkJCQkvLyBBbHdheXMgaW5jbHVkZSBkaXJlY3RvcmllcyB0aGF0IG1heSBoYXZlIG1hdGNoaW5nIGNoaWxkcmVuIGV2ZW4gaWYgdGhleSBhcmUgZXhjbHVkZWQuCgkJCQkJCXJldHVybiBzdGF0aWM6OmNvbnRhaW5zTWF0Y2hpbmdDaGlsZHJlbiggJGZpbGUsICRpbmNsdWRlICk7CgkJCQkJfQoKCQkJCQlyZXR1cm4gKCAoICRpbmNsdXNpb25fc2NvcmUgPj0gJGV4Y2x1c2lvbl9zY29yZSApICYmICRmaWxlLT5pc0ZpbGUoKSAmJiBpbl9hcnJheSggJGZpbGUtPmdldEV4dGVuc2lvbigpLCAkZXh0ZW5zaW9ucywgdHJ1ZSApICk7CgkJCQl9CgkJCSksCgkJCVJlY3Vyc2l2ZUl0ZXJhdG9ySXRlcmF0b3I6OkNISUxEX0ZJUlNUCgkJKTsKCgkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZSApIHsKCQkJLyoqIEB2YXIgU3BsRmlsZUluZm8gJGZpbGUgKi8KCQkJaWYgKCAhICRmaWxlLT5pc0ZpbGUoKSB8fCAhIGluX2FycmF5KCAkZmlsZS0+Z2V0RXh0ZW5zaW9uKCksICRleHRlbnNpb25zLCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbHRlcmVkX2ZpbGVzW10gPSBVdGlsc1xub3JtYWxpemVfcGF0aCggJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCQl9CgoJCXNvcnQoICRmaWx0ZXJlZF9maWxlcywgU09SVF9OQVRVUkFMIHwgU09SVF9GTEFHX0NBU0UgKTsKCgkJcmV0dXJuICRmaWx0ZXJlZF9maWxlczsKCX0KCgkvKioKCSAqIFRyaW0gbGVhZGluZyBzbGFzaCBmcm9tIGEgcGF0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFBhdGggdG8gdHJpbS4KCSAqIEByZXR1cm4gc3RyaW5nIFRyaW1tZWQgcGF0aC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gdHJpbV9sZWFkaW5nX3NsYXNoKCAkcGF0aCApIHsKCQlyZXR1cm4gbHRyaW0oICRwYXRoLCAnLycgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcR2VuZXJhdG9yc1xKZWQ7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogSmVkIGZpbGUgZ2VuZXJhdG9yLgogKgogKiBBZGRzIHNvbWUgbW9yZSBtZXRhIGRhdGEgdG8gSkVEIHRyYW5zbGF0aW9uIGZpbGVzIHRoYW4gdGhlIGRlZmF1bHQgZ2VuZXJhdG9yLgogKi8KY2xhc3MgSmVkR2VuZXJhdG9yIGV4dGVuZHMgSmVkIHsKCS8qKgoJICoge0BwYXJlbnREb2N9LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSApIHsKCQkkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoJCSRkb21haW4gICA9ICR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpID86ICdtZXNzYWdlcyc7CgkJJG1lc3NhZ2VzID0gc3RhdGljOjpidWlsZE1lc3NhZ2VzKCAkdHJhbnNsYXRpb25zICk7CgoJCSRjb25maWd1cmF0aW9uID0gWwoJCQknJyA9PiBbCgkJCQknZG9tYWluJyAgICAgICA9PiAkZG9tYWluLAoJCQkJJ2xhbmcnICAgICAgICAgPT4gJHRyYW5zbGF0aW9ucy0+Z2V0TGFuZ3VhZ2UoKSA/OiAnZW4nLAoJCQkJJ3BsdXJhbC1mb3JtcycgPT4gJHRyYW5zbGF0aW9ucy0+Z2V0SGVhZGVyKCAnUGx1cmFsLUZvcm1zJyApID86ICducGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7JywKCQkJXSwKCQldOwoKCQkkZGF0YSA9IFsKCQkJJ3RyYW5zbGF0aW9uLXJldmlzaW9uLWRhdGUnID0+ICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlciggJ1BPLVJldmlzaW9uLURhdGUnICksCgkJCSdnZW5lcmF0b3InICAgICAgICAgICAgICAgICA9PiAnV1AtQ0xJLycgLiBXUF9DTElfVkVSU0lPTiwKCQkJJ3NvdXJjZScgICAgICAgICAgICAgICAgICAgID0+ICRvcHRpb25zWydzb3VyY2UnXSwKCQkJJ2RvbWFpbicgICAgICAgICAgICAgICAgICAgID0+ICRkb21haW4sCgkJCSdsb2NhbGVfZGF0YScgICAgICAgICAgICAgICA9PiBbCgkJCQkkZG9tYWluID0+ICRjb25maWd1cmF0aW9uICsgJG1lc3NhZ2VzLAoJCQldLAoJCV07CgoJCXJldHVybiBqc29uX2VuY29kZSggJGRhdGEsICRvcHRpb25zWydqc29uJ10gKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBhbiBhcnJheSB3aXRoIGFsbCB0cmFuc2xhdGlvbnMuCgkgKgoJICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJ1aWxkTWVzc2FnZXMoIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zICkgewoJCSRwbHVyYWxfZm9ybXMgICAgICA9ICR0cmFuc2xhdGlvbnMtPmdldFBsdXJhbEZvcm1zKCk7CgkJJG51bWJlcl9vZl9wbHVyYWxzID0gaXNfYXJyYXkoICRwbHVyYWxfZm9ybXMgKSA/ICggJHBsdXJhbF9mb3Jtc1swXSAtIDEgKSA6IG51bGw7CgkJJG1lc3NhZ2VzICAgICAgICAgID0gW107CgkJJGNvbnRleHRfZ2x1ZSAgICAgID0gY2hyKCA0ICk7CgoJCWZvcmVhY2ggKCAkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbiApIHsKCQkJLyoqIEB2YXIgVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uICovCgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aXNEaXNhYmxlZCgpICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRrZXkgPSAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCk7CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzQ29udGV4dCgpICkgewoJCQkJJGtleSA9ICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpIC4gJGNvbnRleHRfZ2x1ZSAuICRrZXk7CgkJCX0KCgkJCWlmICggJHRyYW5zbGF0aW9uLT5oYXNQbHVyYWxUcmFuc2xhdGlvbnMoIHRydWUgKSApIHsKCQkJCSRtZXNzYWdlID0gJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWxUcmFuc2xhdGlvbnMoICRudW1iZXJfb2ZfcGx1cmFscyApOwoJCQkJYXJyYXlfdW5zaGlmdCggJG1lc3NhZ2UsICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSApOwoJCQl9IGVsc2UgewoJCQkJJG1lc3NhZ2UgPSBbICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSBdOwoJCQl9CgoJCQkkbWVzc2FnZXNbICRrZXkgXSA9ICRtZXNzYWdlOwoJCX0KCgkJcmV0dXJuICRtZXNzYWdlczsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xKc0NvZGU7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFBlYXN0XFN5bnRheFxFeGNlcHRpb24gYXMgUGVhc3RFeGNlcHRpb247CnVzZSBXUF9DTEk7CgpmaW5hbCBjbGFzcyBKc0NvZGVFeHRyYWN0b3IgZXh0ZW5kcyBKc0NvZGUgewoJdXNlIEl0ZXJhYmxlQ29kZUV4dHJhY3RvcjsKCglwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwoJCSdleHRyYWN0Q29tbWVudHMnID0+IFsgJ3RyYW5zbGF0b3JzJywgJ1RyYW5zbGF0b3JzJyBdLAoJCSdjb25zdGFudHMnICAgICAgID0+IFtdLAoJCSdmdW5jdGlvbnMnICAgICAgID0+IFsKCQkJJ19fJyAgPT4gJ3RleHRfZG9tYWluJywKCQkJJ194JyAgPT4gJ3RleHRfY29udGV4dF9kb21haW4nLAoJCQknX24nICA9PiAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJywKCQkJJ19ueCcgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2NvbnRleHRfZG9tYWluJywKCQldLAoJXTsKCglwcm90ZWN0ZWQgc3RhdGljICRmdW5jdGlvbnNTY2FubmVyQ2xhc3MgPSAnV1BfQ0xJXEkxOG5cSnNGdW5jdGlvbnNTY2FubmVyJzsKCgkvKioKCSAqIEBpbmhlcml0ZG9jCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZyggJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJV1BfQ0xJOjpkZWJ1ZyggIlBhcnNpbmcgZmlsZSB7JG9wdGlvbnNbJ2ZpbGUnXX0iLCAnbWFrZS1wb3QnICk7CgoJCXRyeSB7CgkJCXN0YXRpYzo6ZnJvbVN0cmluZ011bHRpcGxlKCAkc3RyaW5nLCBbICR0cmFuc2xhdGlvbnMgXSwgJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggUGVhc3RFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCXNwcmludGYoCgkJCQkJJ0NvdWxkIG5vdCBwYXJzZSBmaWxlICUxJHM6ICUyJHMgKGxpbmUgJTMkZCwgY29sdW1uICU0JGQpJywKCQkJCQkkb3B0aW9uc1snZmlsZSddLAoJCQkJCSRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRQb3NpdGlvbigpLT5nZXRMaW5lKCksCgkJCQkJJGV4Y2VwdGlvbi0+Z2V0UG9zaXRpb24oKS0+Z2V0Q29sdW1uKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknQ291bGQgbm90IHBhcnNlIGZpbGUgJTEkczogJTIkcycsCgkJCQkJJG9wdGlvbnNbJ2ZpbGUnXSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfQoJfQoKCS8qKgoJICogQGluaGVyaXREb2MKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoICRzdHJpbmcsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10gKSB7CgkJJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCgkJLyoqIEB2YXIgSnNGdW5jdGlvbnNTY2FubmVyICRmdW5jdGlvbnMgKi8KCQkkZnVuY3Rpb25zID0gbmV3IHN0YXRpYzo6JGZ1bmN0aW9uc1NjYW5uZXJDbGFzcyggJHN0cmluZyApOwoJCSRmdW5jdGlvbnMtPmVuYWJsZUNvbW1lbnRzRXh0cmFjdGlvbiggJG9wdGlvbnNbJ2V4dHJhY3RDb21tZW50cyddICk7CgkJJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoICR0cmFuc2xhdGlvbnMsICRvcHRpb25zICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBEaXJlY3RvcnlJdGVyYXRvcjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgSXRlcmF0b3JJdGVyYXRvcjsKdXNlIFNwbEZpbGVJbmZvOwp1c2UgV1BfQ0xJOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJX0NvbW1hbmQ7CgpjbGFzcyBNYWtlTW9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoJLyoqCgkgKiBDcmVhdGUgTU8gZmlsZXMgZnJvbSBQTyBmaWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNvdXJjZT4KCSAqIDogUGF0aCB0byBhbiBleGlzdGluZyBQTyBmaWxlIG9yIGEgZGlyZWN0b3J5IGNvbnRhaW5pbmcgbXVsdGlwbGUgUE8gZmlsZXMuCgkgKgoJICogWzxkZXN0aW5hdGlvbj5dCgkgKiA6IFBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdGhlIHJlc3VsdGluZyBNTyBmaWxlcy4gRGVmYXVsdHMgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnkuCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRzb3VyY2UgPSByZWFscGF0aCggJGFyZ3NbMF0gKTsKCQlpZiAoICEgJHNvdXJjZSB8fCAoICEgaXNfZmlsZSggJHNvdXJjZSApICYmICEgaXNfZGlyKCAkc291cmNlICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1NvdXJjZSBmaWxlIG9yIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdCEnICk7CgkJfQoKCQkkZGVzdGluYXRpb24gPSBpc19maWxlKCAkc291cmNlICkgPyBkaXJuYW1lKCAkc291cmNlICkgOiAkc291cmNlOwoJCWlmICggaXNzZXQoICRhcmdzWzFdICkgKSB7CgkJCSRkZXN0aW5hdGlvbiA9ICRhcmdzWzFdOwoJCX0KCgkJLy8gVHdvIGlzX2RpcigpIGNoZWNrcyBpbiBjYXNlIG9mIGEgcmFjZSBjb25kaXRpb24uCgkJaWYgKCAhIGlzX2RpciggJGRlc3RpbmF0aW9uICkKCQkJJiYgISBta2RpciggJGRlc3RpbmF0aW9uLCAwNzc3LCB0cnVlICkKCQkJJiYgISBpc19kaXIoICRkZXN0aW5hdGlvbiApCgkJKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdDb3VsZCBub3QgY3JlYXRlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSEnICk7CgkJfQoKCQlpZiAoIGlzX2ZpbGUoICRzb3VyY2UgKSApIHsKCQkJJGZpbGVzID0gWyBuZXcgU3BsRmlsZUluZm8oICRzb3VyY2UgKSBdOwoJCX0gZWxzZSB7CgkJCSRmaWxlcyA9IG5ldyBJdGVyYXRvckl0ZXJhdG9yKCBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRzb3VyY2UgKSApOwoJCX0KCgkJJHJlc3VsdF9jb3VudCA9IDA7CgkJLyoqIEB2YXIgRGlyZWN0b3J5SXRlcmF0b3IgJGZpbGUgKi8KCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQlpZiAoICdwbycgIT09ICRmaWxlLT5nZXRFeHRlbnNpb24oKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoICEgJGZpbGUtPmlzRmlsZSgpIHx8ICEgJGZpbGUtPmlzUmVhZGFibGUoKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0NvdWxkIG5vdCByZWFkIGZpbGUgJXMnLCAkZmlsZS0+Z2V0RmlsZW5hbWUoKSApICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbGVfYmFzZW5hbWUgICAgPSBiYXNlbmFtZSggJGZpbGUtPmdldEZpbGVuYW1lKCksICcucG8nICk7CgkJCSRkZXN0aW5hdGlvbl9maWxlID0gInskZGVzdGluYXRpb259L3skZmlsZV9iYXNlbmFtZX0ubW8iOwoKCQkJJHRyYW5zbGF0aW9ucyA9IFRyYW5zbGF0aW9uczo6ZnJvbVBvRmlsZSggJGZpbGUtPmdldFBhdGhuYW1lKCkgKTsKCQkJaWYgKCAhICR0cmFuc2xhdGlvbnMtPnRvTW9GaWxlKCAkZGVzdGluYXRpb25fZmlsZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnQ291bGQgbm90IGNyZWF0ZSBmaWxlICVzJywgJGRlc3RpbmF0aW9uX2ZpbGUgKSApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyZXN1bHRfY291bnQrKzsKCQl9CgoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggJ0NyZWF0ZWQgJWQgJXMuJywgJHJlc3VsdF9jb3VudCwgVXRpbHNccGx1cmFsaXplKCAnZmlsZScsICRyZXN1bHRfY291bnQgKSApICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlIGFzIEJhc2VDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIFByb3ZpZGVzIGludGVybmF0aW9uYWxpemF0aW9uIHRvb2xzIGZvciBXb3JkUHJlc3MgcHJvamVjdHMuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIENyZWF0ZSBhIFBPVCBmaWxlIGZvciB0aGUgV29yZFByZXNzIHBsdWdpbi90aGVtZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkKICogICAgICQgd3AgaTE4biBtYWtlLXBvdCAuIGxhbmd1YWdlcy9teS1wbHVnaW4ucG90CiAqCiAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCiAqLwpjbGFzcyBDb21tYW5kTmFtZXNwYWNlIGV4dGVuZHMgQmFzZUNvbW1hbmROYW1lc3BhY2Ugewp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXFBvOwp1c2UgR2V0dGV4dFxNZXJnZTsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgRGlyZWN0b3J5SXRlcmF0b3I7CnVzZSBJdGVyYXRvckl0ZXJhdG9yOwoKY2xhc3MgTWFrZVBvdENvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgkvKioKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkc291cmNlOwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkZXN0aW5hdGlvbjsKCgkvKioKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRtZXJnZSA9IFtdOwoKCS8qKgoJICogQHZhciBUcmFuc2xhdGlvbnMKCSAqLwoJcHJvdGVjdGVkICRleGNlcHRpb25zOwoKCS8qKgoJICogQHZhciBhcnJheQoJICovCglwcm90ZWN0ZWQgJGluY2x1ZGUgPSBbXTsKCgkvKioKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJvdGVjdGVkICRleGNsdWRlID0gWyAnbm9kZV9tb2R1bGVzJywgJy5naXQnLCAnLnN2bicsICcuQ1ZTJywgJy5oZycsICd2ZW5kb3InLCAnR3J1bnRmaWxlLmpzJywgJ3dlYnBhY2suY29uZmlnLmpzJywgJyoubWluLmpzJyBdOwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRzbHVnOwoKCS8qKgoJICogQHZhciBhcnJheQoJICovCglwcm90ZWN0ZWQgJG1haW5fZmlsZV9kYXRhID0gW107CgoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRza2lwX2pzID0gZmFsc2U7CgoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRza2lwX3BocCA9IGZhbHNlOwoKCS8qKgoJICogQHZhciBib29sCgkgKi8KCXByb3RlY3RlZCAkc2tpcF9ibG9ja19qc29uID0gZmFsc2U7CgoJLyoqCgkgKiBAdmFyIGJvb2wKCSAqLwoJcHJvdGVjdGVkICRza2lwX2F1ZGl0ID0gZmFsc2U7CgoJLyoqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByb3RlY3RlZCAkaGVhZGVycyA9IFtdOwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRkb21haW47CgoJLyoqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcm90ZWN0ZWQgJHBhY2thZ2VfbmFtZTsKCgkvKioKCSAqIEB2YXIgc3RyaW5nCgkgKi8KCXByb3RlY3RlZCAkZmlsZV9jb21tZW50OwoKCS8qKgoJICogQHZhciBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkICRwcm9qZWN0X3R5cGUgPSAnZ2VuZXJpYyc7CgoJLyoqCgkgKiBUaGVzZSBSZWdleGVzIGNvcGllZCBmcm9tIGh0dHA6Ly9waHAubmV0L21hbnVhbC9lbi9mdW5jdGlvbi5zcHJpbnRmLnBocCM5MzU1MgoJICogYW5kIGFkanVzdGVkIGZvciBiZXR0ZXIgcHJlY2lzaW9uIGFuZCB1cGRhdGVkIHNwZWNzLgoJICovCgljb25zdCBTUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYID0gJy8oPzoKCQkoPzwhJSkgICAgICAgICAgICAgICAgICAgICAjIERvblwndCBtYXRjaCBhIGxpdGVyYWwgJSAoJSUpLgoJCSgKCQkJJSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBTdGFydCBvZiBwbGFjZWhvbGRlci4KCQkJKD86WzAtOV0rXCQpPyAgICAgICAgICAgICAgIyBPcHRpb25hbCBvcmRlcmluZyBvZiB0aGUgcGxhY2Vob2xkZXJzLgoJCQlbKy1dPyAgICAgICAgICAgICAgICAgICAgICAjIE9wdGlvbmFsIHNpZ24gc3BlY2lmaWVyLgoJCQkoPzoKCQkJCSg/OjB8XCcuKT8gICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgcGFkZGluZyBzcGVjaWZpZXIgLSBleGNsdWRpbmcgdGhlIHNwYWNlLgoJCQkJLT8gICAgICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBhbGlnbm1lbnQgc3BlY2lmaWVyLgoJCQkJWzAtOV0qICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCB3aWR0aCBzcGVjaWZpZXIuCgkJCQkoPzpcLig/OlsgMF18XCcuKT9bMC05XSspPyAjIE9wdGlvbmFsIHByZWNpc2lvbiBzcGVjaWZpZXIgd2l0aCBvcHRpb25hbCBwYWRkaW5nIGNoYXJhY3Rlci4KCQkJCXwgICAgICAgICAgICAgICAgICAgICAgIyBPbmx5IHJlY29nbml6ZSB0aGUgc3BhY2UgYXMgcGFkZGluZyBpbiBjb21iaW5hdGlvbiB3aXRoIGEgd2lkdGggc3BlY2lmaWVyLgoJCQkJKD86WyBdKT8gICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzcGFjZSBwYWRkaW5nIHNwZWNpZmllci4KCQkJCS0/ICAgICAgICAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgYWxpZ25tZW50IHNwZWNpZmllci4KCQkJCVswLTldKyAgICAgICAgICAgICAgICAgICAgICMgV2lkdGggc3BlY2lmaWVyLgoJCQkJKD86XC4oPzpbIDBdfFwnLik/WzAtOV0rKT8gIyBPcHRpb25hbCBwcmVjaXNpb24gc3BlY2lmaWVyIHdpdGggb3B0aW9uYWwgcGFkZGluZyBjaGFyYWN0ZXIuCgkJCSkKCQkJW2JjZGVFZkZnR29zdXhYXSAgICAgICAgICAgIyBUeXBlIHNwZWNpZmllci4KCQkpCgkpL3gnOwoKCS8qKgoJICogIlVub3JkZXJlZCIgbWVhbnMgdGhlcmUncyBubyBwb3NpdGlvbiBzcGVjaWZpZXI6ICclcycsIG5vdCAnJTIkcycuCgkgKi8KCWNvbnN0IFVOT1JERVJFRF9TUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYID0gJy8oPzoKCQkoPzwhJSkgICAgICAgICAgICAgICAgICAgICAjIERvblwndCBtYXRjaCBhIGxpdGVyYWwgJSAoJSUpLgoJCSUgICAgICAgICAgICAgICAgICAgICAgICAgICMgU3RhcnQgb2YgcGxhY2Vob2xkZXIuCgkJWystXT8gICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzaWduIHNwZWNpZmllci4KCQkoPzoKCQkJKD86MHxcJy4pPyAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBwYWRkaW5nIHNwZWNpZmllciAtIGV4Y2x1ZGluZyB0aGUgc3BhY2UuCgkJCS0/ICAgICAgICAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWwgYWxpZ25tZW50IHNwZWNpZmllci4KCQkJWzAtOV0qICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCB3aWR0aCBzcGVjaWZpZXIuCgkJCSg/OlwuKD86WyAwXXxcJy4pP1swLTldKyk/ICMgT3B0aW9uYWwgcHJlY2lzaW9uIHNwZWNpZmllciB3aXRoIG9wdGlvbmFsIHBhZGRpbmcgY2hhcmFjdGVyLgoJCQl8ICAgICAgICAgICAgICAgICAgICAgICMgT25seSByZWNvZ25pemUgdGhlIHNwYWNlIGFzIHBhZGRpbmcgaW4gY29tYmluYXRpb24gd2l0aCBhIHdpZHRoIHNwZWNpZmllci4KCQkJKD86WyBdKT8gICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBzcGFjZSBwYWRkaW5nIHNwZWNpZmllci4KCQkJLT8gICAgICAgICAgICAgICAgICAgICAgICAgIyBPcHRpb25hbCBhbGlnbm1lbnQgc3BlY2lmaWVyLgoJCQlbMC05XSsgICAgICAgICAgICAgICAgICAgICAjIFdpZHRoIHNwZWNpZmllci4KCQkJKD86XC4oPzpbIDBdfFwnLik/WzAtOV0rKT8gIyBPcHRpb25hbCBwcmVjaXNpb24gc3BlY2lmaWVyIHdpdGggb3B0aW9uYWwgcGFkZGluZyBjaGFyYWN0ZXIuCgkJKQoJCVtiY2RlRWZGZ0dvc3V4WF0gICAgICAgICAgICMgVHlwZSBzcGVjaWZpZXIuCgkpL3gnOwoKCS8qKgoJICogQ3JlYXRlIGEgUE9UIGZpbGUgZm9yIGEgV29yZFByZXNzIHByb2plY3QuCgkgKgoJICogU2NhbnMgUEhQIGFuZCBKYXZhU2NyaXB0IGZpbGVzIGZvciB0cmFuc2xhdGFibGUgc3RyaW5ncywgYXMgd2VsbCBhcyB0aGVtZSBzdHlsZXNoZWV0cyBhbmQgcGx1Z2luIGZpbGVzCgkgKiBpZiB0aGUgc291cmNlIGRpcmVjdG9yeSBpcyBkZXRlY3RlZCBhcyBlaXRoZXIgYSBwbHVnaW4gb3IgdGhlbWUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzb3VyY2U+CgkgKiA6IERpcmVjdG9yeSB0byBzY2FuIGZvciBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqCgkgKiBbPGRlc3RpbmF0aW9uPl0KCSAqIDogTmFtZSBvZiB0aGUgcmVzdWx0aW5nIFBPVCBmaWxlLgoJICoKCSAqIFstLXNsdWc9PHNsdWc+XQoJICogOiBQbHVnaW4gb3IgdGhlbWUgc2x1Zy4gRGVmYXVsdHMgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnkncyBiYXNlbmFtZS4KCSAqCgkgKiBbLS1kb21haW49PGRvbWFpbj5dCgkgKiA6IFRleHQgZG9tYWluIHRvIGxvb2sgZm9yIGluIHRoZSBzb3VyY2UgY29kZSwgdW5sZXNzIHRoZSBgLS1pZ25vcmUtZG9tYWluYCBvcHRpb24gaXMgdXNlZC4KCSAqIEJ5IGRlZmF1bHQsIHRoZSAiVGV4dCBEb21haW4iIGhlYWRlciBvZiB0aGUgcGx1Z2luIG9yIHRoZW1lIGlzIHVzZWQuCgkgKiBJZiBub25lIGlzIHByb3ZpZGVkLCBpdCBmYWxscyBiYWNrIHRvIHRoZSBwcm9qZWN0IHNsdWcuCgkgKgoJICogWy0taWdub3JlLWRvbWFpbl0KCSAqIDogSWdub3JlIHRoZSB0ZXh0IGRvbWFpbiBjb21wbGV0ZWx5IGFuZCBleHRyYWN0IHN0cmluZ3Mgd2l0aCBhbnkgdGV4dCBkb21haW4uCgkgKgoJICogWy0tbWVyZ2VbPTxwYXRocz5dXQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBQT1QgZmlsZXMgd2hvc2UgY29udGVudHMgc2hvdWxkIGJlIG1lcmdlZCB3aXRoIHRoZSBleHRyYWN0ZWQgc3RyaW5ncy4KCSAqIElmIGxlZnQgZW1wdHksIGRlZmF1bHRzIHRvIHRoZSBkZXN0aW5hdGlvbiBQT1QgZmlsZS4gUE9UIGZpbGUgaGVhZGVycyB3aWxsIGJlIGlnbm9yZWQuCgkgKgoJICogWy0tc3VidHJhY3Q9PHBhdGhzPl0KCSAqIDogQ29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgUE9UIGZpbGVzIHdob3NlIGNvbnRlbnRzIHNob3VsZCBhY3QgYXMgc29tZSBzb3J0IG9mIGJsYWNrbGlzdCBmb3Igc3RyaW5nIGV4dHJhY3Rpb24uCgkgKiBBbnkgc3RyaW5nIHdoaWNoIGlzIGZvdW5kIG9uIHRoYXQgYmxhY2tsaXN0IHdpbGwgbm90IGJlIGV4dHJhY3RlZC4KCSAqIFRoaXMgY2FuIGJlIHVzZWZ1bCB3aGVuIHlvdSB3YW50IHRvIGNyZWF0ZSBtdWx0aXBsZSBQT1QgZmlsZXMgZnJvbSB0aGUgc2FtZSBzb3VyY2UgZGlyZWN0b3J5IHdpdGggc2xpZ2h0bHkKCSAqIGRpZmZlcmVudCBjb250ZW50IGFuZCBubyBkdXBsaWNhdGUgc3RyaW5ncyBiZXR3ZWVuIHRoZW0uCgkgKgoJICogWy0taW5jbHVkZT08cGF0aHM+XQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBmaWxlcyBhbmQgcGF0aHMgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3Igc3RyaW5nIGV4dHJhY3Rpb24uCgkgKiBJZiBwcm92aWRlZCwgb25seSB0aGVzZSBmaWxlcyBhbmQgZm9sZGVycyB3aWxsIGJlIHRha2VuIGludG8gYWNjb3VudCBmb3Igc3RyaW5nIGV4dHJhY3Rpb24uCgkgKiBGb3IgZXhhbXBsZSwgYC0taW5jbHVkZT0ic3JjLG15LWZpbGUucGhwYCB3aWxsIGlnbm9yZSBhbnl0aGluZyBiZXNpZGVzIGBteS1maWxlLnBocGAgYW5kIGZpbGVzIGluIHRoZSBgc3JjYAoJICogZGlyZWN0b3J5LiBTaW1wbGUgZ2xvYiBwYXR0ZXJucyBjYW4gYmUgdXNlZCwgaS5lLiBgLS1pbmNsdWRlPWZvby0qLnBocGAgaW5jbHVkZXMgYW55IFBIUCBmaWxlIHdpdGggdGhlIGBmb28tYAoJICogcHJlZml4LiBMZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzIGFyZSBpZ25vcmVkLCBpLmUuIGAvbXkvZGlyZWN0b3J5L2AgaXMgdGhlIHNhbWUgYXMgYG15L2RpcmVjdG9yeWAuCgkgKgoJICogWy0tZXhjbHVkZT08cGF0aHM+XQoJICogOiBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBmaWxlcyBhbmQgcGF0aHMgdGhhdCBzaG91bGQgYmUgc2tpcHBlZCBmb3Igc3RyaW5nIGV4dHJhY3Rpb24uCgkgKiBGb3IgZXhhbXBsZSwgYC0tZXhjbHVkZT0iLmdpdGh1YixteWZpbGUucGhwYCB3b3VsZCBpZ25vcmUgYW55IHN0cmluZ3MgZm91bmQgd2l0aGluIGBteWZpbGUucGhwYCBvciB0aGUgYC5naXRodWJgCgkgKiBmb2xkZXIuIFNpbXBsZSBnbG9iIHBhdHRlcm5zIGNhbiBiZSB1c2VkLCBpLmUuIGAtLWV4Y2x1ZGU9Zm9vLSoucGhwYCBleGNsdWRlcyBhbnkgUEhQIGZpbGUgd2l0aCB0aGUgYGZvby1gCgkgKiBwcmVmaXguIExlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgYXJlIGlnbm9yZWQsIGkuZS4gYC9teS9kaXJlY3RvcnkvYCBpcyB0aGUgc2FtZSBhcyBgbXkvZGlyZWN0b3J5YC4gVGhlCgkgKiBmb2xsb3dpbmcgZmlsZXMgYW5kIGZvbGRlcnMgYXJlIGFsd2F5cyBleGNsdWRlZDogbm9kZV9tb2R1bGVzLCAuZ2l0LCAuc3ZuLCAuQ1ZTLCAuaGcsIHZlbmRvciwgKi5taW4uanMuCgkgKgoJICogWy0taGVhZGVycz08aGVhZGVycz5dCgkgKiA6IEFycmF5IGluIEpTT04gZm9ybWF0IG9mIGN1c3RvbSBoZWFkZXJzIHdoaWNoIHdpbGwgYmUgYWRkZWQgdG8gdGhlIFBPVCBmaWxlLiBEZWZhdWx0cyB0byBlbXB0eSBhcnJheS4KCSAqCgkgKiBbLS1za2lwLWpzXQoJICogOiBTa2lwcyBKYXZhU2NyaXB0IHN0cmluZyBleHRyYWN0aW9uLiBVc2VmdWwgd2hlbiB0aGlzIGlzIGRvbmUgaW4gYW5vdGhlciBidWlsZCBzdGVwLCBlLmcuIHRocm91Z2ggQmFiZWwuCgkgKgoJICogWy0tc2tpcC1waHBdCgkgKiA6IFNraXBzIFBIUCBzdHJpbmcgZXh0cmFjdGlvbi4KCSAqCgkgKiBbLS1za2lwLWJsb2NrLWpzb25dCgkgKiA6IFNraXBzIHN0cmluZyBleHRyYWN0aW9uIGZyb20gYmxvY2suanNvbiBmaWxlcy4KCSAqCgkgKiBbLS1za2lwLWF1ZGl0XQoJICogOiBTa2lwcyBzdHJpbmcgYXVkaXQgd2hlcmUgaXQgdHJpZXMgdG8gZmluZCBwb3NzaWJsZSBtaXN0YWtlcyBpbiB0cmFuc2xhdGFibGUgc3RyaW5ncy4gVXNlZnVsIHdoZW4gcnVubmluZyBpbiBhbgoJICogYXV0b21hdGVkIGVudmlyb25tZW50LgoJICoKCSAqIFstLWZpbGUtY29tbWVudD08ZmlsZS1jb21tZW50Pl0KCSAqIDogU3RyaW5nIHRoYXQgc2hvdWxkIGJlIGFkZGVkIGFzIGEgY29tbWVudCB0byB0aGUgdG9wIG9mIHRoZSByZXN1bHRpbmcgUE9UIGZpbGUuCgkgKiBCeSBkZWZhdWx0LCBhIGNvcHlyaWdodCBjb21tZW50IGlzIGFkZGVkIGZvciBXb3JkUHJlc3MgcGx1Z2lucyBhbmQgdGhlbWVzIGluIHRoZSBmb2xsb3dpbmcgbWFubmVyOgoJICoKCSAqICAgICAgYGBgCgkgKiAgICAgIENvcHlyaWdodCAoQykgMjAxOCBFeGFtcGxlIFBsdWdpbiBBdXRob3IKCSAqICAgICAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBzYW1lIGxpY2Vuc2UgYXMgdGhlIEV4YW1wbGUgUGx1Z2luIHBhY2thZ2UuCgkgKiAgICAgIGBgYAoJICoKCSAqICAgICAgSWYgYSBwbHVnaW4gb3IgdGhlbWUgc3BlY2lmaWVzIGEgbGljZW5zZSBpbiB0aGVpciBtYWluIHBsdWdpbiBmaWxlIG9yIHN0eWxlc2hlZXQsIHRoZSBjb21tZW50IGxvb2tzIGxpa2UKCSAqICAgICAgdGhpczoKCSAqCgkgKiAgICAgIGBgYAoJICogICAgICBDb3B5cmlnaHQgKEMpIDIwMTggRXhhbXBsZSBQbHVnaW4gQXV0aG9yCgkgKiAgICAgIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgR1BMdjIuCgkgKiAgICAgIGBgYAoJICoKCSAqIFstLXBhY2thZ2UtbmFtZT08bmFtZT5dCgkgKiA6IE5hbWUgdG8gdXNlIGZvciBwYWNrYWdlIG5hbWUgaW4gdGhlIHJlc3VsdGluZyBQT1QgZmlsZSdzIGBQcm9qZWN0LUlkLVZlcnNpb25gIGhlYWRlci4KCSAqIE92ZXJyaWRlcyBwbHVnaW4gb3IgdGhlbWUgbmFtZSwgaWYgYXBwbGljYWJsZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSBhIFBPVCBmaWxlIGZvciB0aGUgV29yZFByZXNzIHBsdWdpbi90aGVtZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkKCSAqICAgICAkIHdwIGkxOG4gbWFrZS1wb3QgLiBsYW5ndWFnZXMvbXktcGx1Z2luLnBvdAoJICoKCSAqICAgICAjIENyZWF0ZSBhIFBPVCBmaWxlIGZvciB0aGUgY29udGluZW50cyBhbmQgY2l0aWVzIGxpc3QgaW4gV29yZFByZXNzIGNvcmUuCgkgKiAgICAgJCB3cCBpMThuIG1ha2UtcG90IC4gY29udGluZW50cy1hbmQtY2l0aWVzLnBvdCAtLWluY2x1ZGU9IndwLWFkbWluL2luY2x1ZGVzL2NvbnRpbmVudHMtY2l0aWVzLnBocCIKCSAqICAgICAtLWlnbm9yZS1kb21haW4KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICoKCSAqIEB0aHJvd3MgV1BfQ0xJXEV4aXRFeGNlcHRpb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoaXMtPmhhbmRsZV9hcmd1bWVudHMoICRhcmdzLCAkYXNzb2NfYXJncyApOwoKCQkkdHJhbnNsYXRpb25zID0gJHRoaXMtPmV4dHJhY3Rfc3RyaW5ncygpOwoKCQlpZiAoICEgJHRyYW5zbGF0aW9ucyApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnTm8gc3RyaW5ncyBmb3VuZCcgKTsKCQl9CgoJCSR0cmFuc2xhdGlvbnNfY291bnQgPSBjb3VudCggJHRyYW5zbGF0aW9ucyApOwoKCQlpZiAoIDEgPT09ICR0cmFuc2xhdGlvbnNfY291bnQgKSB7CgkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdFeHRyYWN0ZWQgJWQgc3RyaW5nJywgJHRyYW5zbGF0aW9uc19jb3VudCApLCAnbWFrZS1wb3QnICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0V4dHJhY3RlZCAlZCBzdHJpbmdzJywgJHRyYW5zbGF0aW9uc19jb3VudCApLCAnbWFrZS1wb3QnICk7CgkJfQoKCQlpZiAoICEgUG90R2VuZXJhdG9yOjp0b0ZpbGUoICR0cmFuc2xhdGlvbnMsICR0aGlzLT5kZXN0aW5hdGlvbiApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnQ291bGQgbm90IGdlbmVyYXRlIGEgUE9UIGZpbGUhJyApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAnUE9UIGZpbGUgc3VjY2Vzc2Z1bGx5IGdlbmVyYXRlZCEnICk7Cgl9CgoJLyoqCgkgKiBQcm9jZXNzIGFyZ3VtZW50cyBmcm9tIGNvbW1hbmQtbGluZSBpbiBhIHJldXNhYmxlIHdheS4KCSAqCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIENvbW1hbmQgYXJndW1lbnRzLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIEFzc29jaWF0aXZlIGFyZ3VtZW50cy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGhhbmRsZV9hcmd1bWVudHMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYXJyYXlfYXJndW1lbnRzID0gYXJyYXkoICdoZWFkZXJzJyApOwoJCSRhc3NvY19hcmdzICAgICAgPSBVdGlsc1xwYXJzZV9zaGVsbF9hcnJheXMoICRhc3NvY19hcmdzLCAkYXJyYXlfYXJndW1lbnRzICk7CgoJCSR0aGlzLT5zb3VyY2UgICAgICAgICAgPSByZWFscGF0aCggJGFyZ3NbMF0gKTsKCQkkdGhpcy0+c2x1ZyAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2x1ZycsIFV0aWxzXGJhc2VuYW1lKCAkdGhpcy0+c291cmNlICkgKTsKCQkkdGhpcy0+c2tpcF9qcyAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1qcycsICR0aGlzLT5za2lwX2pzICk7CgkJJHRoaXMtPnNraXBfcGhwICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtcGhwJywgJHRoaXMtPnNraXBfcGhwICk7CgkJJHRoaXMtPnNraXBfYmxvY2tfanNvbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtYmxvY2stanNvbicsICR0aGlzLT5za2lwX2Jsb2NrX2pzb24gKTsKCQkkdGhpcy0+c2tpcF9hdWRpdCAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1hdWRpdCcsICR0aGlzLT5za2lwX2F1ZGl0ICk7CgkJJHRoaXMtPmhlYWRlcnMgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2hlYWRlcnMnLCAkdGhpcy0+aGVhZGVycyApOwoJCSR0aGlzLT5maWxlX2NvbW1lbnQgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmaWxlLWNvbW1lbnQnICk7CgkJJHRoaXMtPnBhY2thZ2VfbmFtZSAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3BhY2thZ2UtbmFtZScgKTsKCgkJJGlnbm9yZV9kb21haW4gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpZ25vcmUtZG9tYWluJywgZmFsc2UgKTsKCgkJaWYgKCAhICR0aGlzLT5zb3VyY2UgfHwgISBpc19kaXIoICR0aGlzLT5zb3VyY2UgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ05vdCBhIHZhbGlkIHNvdXJjZSBkaXJlY3RvcnkhJyApOwoJCX0KCgkJJHRoaXMtPm1haW5fZmlsZV9kYXRhID0gJHRoaXMtPmdldF9tYWluX2ZpbGVfZGF0YSgpOwoKCQlpZiAoICRpZ25vcmVfZG9tYWluICkgewoJCQlXUF9DTEk6OmRlYnVnKCAnRXh0cmFjdGluZyBhbGwgc3RyaW5ncyByZWdhcmRsZXNzIG9mIHRleHQgZG9tYWluJywgJ21ha2UtcG90JyApOwoJCX0KCgkJaWYgKCAhICRpZ25vcmVfZG9tYWluICkgewoJCQkkdGhpcy0+ZG9tYWluID0gJHRoaXMtPnNsdWc7CgoJCQlpZiAoICEgZW1wdHkoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGV4dCBEb21haW4nXSApICkgewoJCQkJJHRoaXMtPmRvbWFpbiA9ICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGV4dCBEb21haW4nXTsKCQkJfQoKCQkJJHRoaXMtPmRvbWFpbiA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2RvbWFpbicsICR0aGlzLT5kb21haW4gKTsKCgkJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdFeHRyYWN0aW5nIGFsbCBzdHJpbmdzIHdpdGggdGV4dCBkb21haW4gIiVzIicsICR0aGlzLT5kb21haW4gKSwgJ21ha2UtcG90JyApOwoJCX0KCgkJLy8gRGV0ZXJtaW5lIGRlc3RpbmF0aW9uLgoJCSR0aGlzLT5kZXN0aW5hdGlvbiA9ICJ7JHRoaXMtPnNvdXJjZX0veyR0aGlzLT5zbHVnfS5wb3QiOwoKCQlpZiAoICEgZW1wdHkoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnRG9tYWluIFBhdGgnXSApICkgewoJCQkvLyBEb21haW4gUGF0aCBpbnNpZGUgc291cmNlIGZvbGRlci4KCQkJJHRoaXMtPmRlc3RpbmF0aW9uID0gc3ByaW50ZigKCQkJCSclcy8lcy8lcy5wb3QnLAoJCQkJJHRoaXMtPnNvdXJjZSwKCQkJCSR0aGlzLT51bnNsYXNoaXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnRG9tYWluIFBhdGgnXSApLAoJCQkJJHRoaXMtPnNsdWcKCQkJKTsKCQl9CgoJCWlmICggaXNzZXQoICRhcmdzWzFdICkgKSB7CgkJCSR0aGlzLT5kZXN0aW5hdGlvbiA9ICRhcmdzWzFdOwoJCX0KCgkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0Rlc3RpbmF0aW9uOiAlcycsICR0aGlzLT5kZXN0aW5hdGlvbiApLCAnbWFrZS1wb3QnICk7CgoJCS8vIFR3byBpc19kaXIoKSBjaGVja3MgaW4gY2FzZSBvZiBhIHJhY2UgY29uZGl0aW9uLgoJCWlmICggISBpc19kaXIoIGRpcm5hbWUoICR0aGlzLT5kZXN0aW5hdGlvbiApICkKCQkJJiYgISBta2RpciggZGlybmFtZSggJHRoaXMtPmRlc3RpbmF0aW9uICksIDA3NzcsIHRydWUgKQoJCQkmJiAhIGlzX2RpciggZGlybmFtZSggJHRoaXMtPmRlc3RpbmF0aW9uICkgKQoJCSkgewoJCQlXUF9DTEk6OmVycm9yKCAnQ291bGQgbm90IGNyZWF0ZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkhJyApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ21lcmdlJ10gKSApIHsKCQkJaWYgKCB0cnVlID09PSAkYXNzb2NfYXJnc1snbWVyZ2UnXSApIHsKCQkJCSR0aGlzLT5tZXJnZSA9IFsgJHRoaXMtPmRlc3RpbmF0aW9uIF07CgkJCX0gZWxzZWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ21lcmdlJ10gKSApIHsKCQkJCSR0aGlzLT5tZXJnZSA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ21lcmdlJ10gKTsKCQkJfQoKCQkJJHRoaXMtPm1lcmdlID0gYXJyYXlfZmlsdGVyKAoJCQkJJHRoaXMtPm1lcmdlLAoJCQkJZnVuY3Rpb24gKCAkZmlsZSApIHsKCQkJCQlpZiAoICEgZmlsZV9leGlzdHMoICRmaWxlICkgKSB7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0ludmFsaWQgZmlsZSBwcm92aWRlZCB0byAtLW1lcmdlOiAlcycsICRmaWxlICkgKTsKCgkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQl9CgoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQkpOwoKCQkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+bWVyZ2UgKSApIHsKCQkJCVdQX0NMSTo6ZGVidWcoCgkJCQkJc3ByaW50ZigKCQkJCQkJJ01lcmdpbmcgd2l0aCBleGlzdGluZyBQT1QgJXM6ICVzJywKCQkJCQkJV1BfQ0xJXFV0aWxzXHBsdXJhbGl6ZSggJ2ZpbGUnLCBjb3VudCggJHRoaXMtPm1lcmdlICkgKSwKCQkJCQkJaW1wbG9kZSggJywnLCAkdGhpcy0+bWVyZ2UgKQoJCQkJCSksCgkJCQkJJ21ha2UtcG90JwoJCQkJKTsKCQkJfQoJCX0KCgkJJHRoaXMtPmV4Y2VwdGlvbnMgPSBuZXcgVHJhbnNsYXRpb25zKCk7CgoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydzdWJ0cmFjdCddICkgKSB7CgkJCSRleGNlcHRpb25zID0gZXhwbG9kZSggJywnLCAkYXNzb2NfYXJnc1snc3VidHJhY3QnXSApOwoKCQkJJGV4Y2VwdGlvbnMgPSBhcnJheV9maWx0ZXIoCgkJCQkkZXhjZXB0aW9ucywKCQkJCWZ1bmN0aW9uICggJGV4Y2VwdGlvbiApIHsKCQkJCQlpZiAoICEgZmlsZV9leGlzdHMoICRleGNlcHRpb24gKSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnSW52YWxpZCBmaWxlIHByb3ZpZGVkIHRvIC0tc3VidHJhY3Q6ICVzJywgJGV4Y2VwdGlvbiApICk7CgoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoKCQkJCQkkZXhjZXB0aW9uX3RyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoKTsKCgkJCQkJUG86OmZyb21GaWxlKCAkZXhjZXB0aW9uLCAkZXhjZXB0aW9uX3RyYW5zbGF0aW9ucyApOwoJCQkJCSR0aGlzLT5leGNlcHRpb25zLT5tZXJnZVdpdGgoICRleGNlcHRpb25fdHJhbnNsYXRpb25zICk7CgoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQkpOwoKCQkJaWYgKCAhIGVtcHR5KCAkZXhjZXB0aW9ucyApICkgewoJCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ0lnbm9yaW5nIGFueSBzdHJpbmcgYWxyZWFkeSBleGlzdGluZyBpbjogJXMnLCBpbXBsb2RlKCAnLCcsICRleGNlcHRpb25zICkgKSwgJ21ha2UtcG90JyApOwoJCQl9CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snaW5jbHVkZSddICkgKSB7CgkJCSR0aGlzLT5pbmNsdWRlID0gYXJyYXlfZmlsdGVyKCBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydpbmNsdWRlJ10gKSApOwoJCQkkdGhpcy0+aW5jbHVkZSA9IGFycmF5X21hcCggWyAkdGhpcywgJ3Vuc2xhc2hpdCcgXSwgJHRoaXMtPmluY2x1ZGUgKTsKCQkJJHRoaXMtPmluY2x1ZGUgPSBhcnJheV91bmlxdWUoICR0aGlzLT5pbmNsdWRlICk7CgoJCQlXUF9DTEk6OmRlYnVnKCBzcHJpbnRmKCAnT25seSBpbmNsdWRpbmcgdGhlIGZvbGxvd2luZyBmaWxlczogJXMnLCBpbXBsb2RlKCAnLCcsICR0aGlzLT5pbmNsdWRlICkgKSwgJ21ha2UtcG90JyApOwoJCX0KCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGUnXSApICkgewoJCQkkdGhpcy0+ZXhjbHVkZSA9IGFycmF5X2ZpbHRlciggYXJyYXlfbWVyZ2UoICR0aGlzLT5leGNsdWRlLCBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydleGNsdWRlJ10gKSApICk7CgkJCSR0aGlzLT5leGNsdWRlID0gYXJyYXlfbWFwKCBbICR0aGlzLCAndW5zbGFzaGl0JyBdLCAkdGhpcy0+ZXhjbHVkZSApOwoJCQkkdGhpcy0+ZXhjbHVkZSA9IGFycmF5X3VuaXF1ZSggJHRoaXMtPmV4Y2x1ZGUgKTsKCQl9CgoJCVdQX0NMSTo6ZGVidWcoIHNwcmludGYoICdFeGNsdWRpbmcgdGhlIGZvbGxvd2luZyBmaWxlczogJXMnLCBpbXBsb2RlKCAnLCcsICR0aGlzLT5leGNsdWRlICkgKSwgJ21ha2UtcG90JyApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzIG9mIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBXaGF0IHRvIGFkZCBhbmQgcmVtb3ZlIHNsYXNoZXMgZnJvbS4KCSAqIEByZXR1cm4gc3RyaW5nIFN0cmluZyB3aXRob3V0IGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiB1bnNsYXNoaXQoICRzdHJpbmcgKSB7CgkJcmV0dXJuIGx0cmltKCBydHJpbSggdHJpbSggJHN0cmluZyApLCAnL1xcJyApLCAnL1xcJyApOwoJfQoKCS8qKgoJICogUmV0cmlldmVzIHRoZSBtYWluIGZpbGUgZGF0YSBvZiB0aGUgcGx1Z2luIG9yIHRoZW1lLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9tYWluX2ZpbGVfZGF0YSgpIHsKCQkkZmlsZXMgPSBuZXcgSXRlcmF0b3JJdGVyYXRvciggbmV3IERpcmVjdG9yeUl0ZXJhdG9yKCAkdGhpcy0+c291cmNlICkgKTsKCgkJLyoqIEB2YXIgRGlyZWN0b3J5SXRlcmF0b3IgJGZpbGUgKi8KCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQkvLyB3cC1jb250ZW50L3RoZW1lcy9teS10aGVtZS9zdHlsZS5jc3MKCQkJaWYgKCAkZmlsZS0+aXNGaWxlKCkgJiYgJ3N0eWxlJyA9PT0gJGZpbGUtPmdldEJhc2VuYW1lKCAnLmNzcycgKSAmJiAkZmlsZS0+aXNSZWFkYWJsZSgpICkgewoJCQkJJHRoZW1lX2RhdGEgPSBzdGF0aWM6OmdldF9maWxlX2RhdGEoICRmaWxlLT5nZXRSZWFsUGF0aCgpLCBhcnJheV9jb21iaW5lKCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJ3RoZW1lJyApLCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJ3RoZW1lJyApICkgKTsKCgkJCQkvLyBTdG9wIHdoZW4gaXQgY29udGFpbnMgYSB2YWxpZCBUaGVtZSBOYW1lIGhlYWRlci4KCQkJCWlmICggISBlbXB0eSggJHRoZW1lX2RhdGFbJ1RoZW1lIE5hbWUnXSApICkgewoJCQkJCVdQX0NMSTo6bG9nKCAnVGhlbWUgc3R5bGVzaGVldCBkZXRlY3RlZC4nICk7CgkJCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ1RoZW1lIHN0eWxlc2hlZXQ6ICVzJywgJGZpbGUtPmdldFJlYWxQYXRoKCkgKSwgJ21ha2UtcG90JyApOwoKCQkJCQkkdGhpcy0+cHJvamVjdF90eXBlID0gJ3RoZW1lJzsKCgkJCQkJcmV0dXJuICR0aGVtZV9kYXRhOwoJCQkJfQoJCQl9CgoJCQkvLyB3cC1jb250ZW50L3RoZW1lcy9teS10aGVtZXMvdGhlbWUtYS9zdHlsZS5jc3MKCQkJaWYgKCAkZmlsZS0+aXNEaXIoKSAmJiAhICRmaWxlLT5pc0RvdCgpICYmIGlzX3JlYWRhYmxlKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSAuICcvc3R5bGUuY3NzJyApICkgewoJCQkJJHRoZW1lX2RhdGEgPSBzdGF0aWM6OmdldF9maWxlX2RhdGEoICRmaWxlLT5nZXRSZWFsUGF0aCgpIC4gJy9zdHlsZS5jc3MnLCBhcnJheV9jb21iaW5lKCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJ3RoZW1lJyApLCAkdGhpcy0+Z2V0X2ZpbGVfaGVhZGVycyggJ3RoZW1lJyApICkgKTsKCgkJCQkvLyBTdG9wIHdoZW4gaXQgY29udGFpbnMgYSB2YWxpZCBUaGVtZSBOYW1lIGhlYWRlci4KCQkJCWlmICggISBlbXB0eSggJHRoZW1lX2RhdGFbJ1RoZW1lIE5hbWUnXSApICkgewoJCQkJCVdQX0NMSTo6bG9nKCAnVGhlbWUgc3R5bGVzaGVldCBkZXRlY3RlZC4nICk7CgkJCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ1RoZW1lIHN0eWxlc2hlZXQ6ICVzJywgJGZpbGUtPmdldFJlYWxQYXRoKCkgLiAnL3N0eWxlLmNzcycgKSwgJ21ha2UtcG90JyApOwoKCQkJCQkkdGhpcy0+cHJvamVjdF90eXBlID0gJ3RoZW1lJzsKCgkJCQkJcmV0dXJuICR0aGVtZV9kYXRhOwoJCQkJfQoJCQl9CgoJCQkvLyB3cC1jb250ZW50L3BsdWdpbnMvbXktcGx1Z2luL215LXBsdWdpbi5waHAKCQkJaWYgKCAkZmlsZS0+aXNGaWxlKCkgJiYgJGZpbGUtPmlzUmVhZGFibGUoKSAmJiAncGhwJyA9PT0gJGZpbGUtPmdldEV4dGVuc2lvbigpICkgewoJCQkJJHBsdWdpbl9kYXRhID0gc3RhdGljOjpnZXRfZmlsZV9kYXRhKCAkZmlsZS0+Z2V0UmVhbFBhdGgoKSwgYXJyYXlfY29tYmluZSggJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICdwbHVnaW4nICksICR0aGlzLT5nZXRfZmlsZV9oZWFkZXJzKCAncGx1Z2luJyApICkgKTsKCgkJCQkvLyBTdG9wIHdoZW4gd2UgZmluZCBhIGZpbGUgd2l0aCBhIHZhbGlkIFBsdWdpbiBOYW1lIGhlYWRlci4KCQkJCWlmICggISBlbXB0eSggJHBsdWdpbl9kYXRhWydQbHVnaW4gTmFtZSddICkgKSB7CgkJCQkJV1BfQ0xJOjpsb2coICdQbHVnaW4gZmlsZSBkZXRlY3RlZC4nICk7CgkJCQkJV1BfQ0xJOjpkZWJ1Zyggc3ByaW50ZiggJ1BsdWdpbiBmaWxlOiAlcycsICRmaWxlLT5nZXRSZWFsUGF0aCgpICksICdtYWtlLXBvdCcgKTsKCgkJCQkJJHRoaXMtPnByb2plY3RfdHlwZSA9ICdwbHVnaW4nOwoKCQkJCQlyZXR1cm4gJHBsdWdpbl9kYXRhOwoJCQkJfQoJCQl9CgkJfQoKCQlXUF9DTEk6OmRlYnVnKCAnTm8gdmFsaWQgdGhlbWUgc3R5bGVzaGVldCBvciBwbHVnaW4gZmlsZSBmb3VuZCwgdHJlYXRpbmcgYXMgYSByZWd1bGFyIHByb2plY3QuJywgJ21ha2UtcG90JyApOwoKCQlyZXR1cm4gW107Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBmaWxlIGhlYWRlcnMgZm9yIHRoZW1lcyBhbmQgcGx1Z2lucy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlIFNvdXJjZSB0eXBlLCBlaXRoZXIgdGhlbWUgb3IgcGx1Z2luLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgTGlzdCBvZiBmaWxlIGhlYWRlcnMuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfZmlsZV9oZWFkZXJzKCAkdHlwZSApIHsKCQlzd2l0Y2ggKCAkdHlwZSApIHsKCQkJY2FzZSAncGx1Z2luJzoKCQkJCXJldHVybiBbCgkJCQkJJ1BsdWdpbiBOYW1lJywKCQkJCQknUGx1Z2luIFVSSScsCgkJCQkJJ0Rlc2NyaXB0aW9uJywKCQkJCQknQXV0aG9yJywKCQkJCQknQXV0aG9yIFVSSScsCgkJCQkJJ1ZlcnNpb24nLAoJCQkJCSdMaWNlbnNlJywKCQkJCQknRG9tYWluIFBhdGgnLAoJCQkJCSdUZXh0IERvbWFpbicsCgkJCQldOwoJCQljYXNlICd0aGVtZSc6CgkJCQlyZXR1cm4gWwoJCQkJCSdUaGVtZSBOYW1lJywKCQkJCQknVGhlbWUgVVJJJywKCQkJCQknRGVzY3JpcHRpb24nLAoJCQkJCSdBdXRob3InLAoJCQkJCSdBdXRob3IgVVJJJywKCQkJCQknVmVyc2lvbicsCgkJCQkJJ0xpY2Vuc2UnLAoJCQkJCSdEb21haW4gUGF0aCcsCgkJCQkJJ1RleHQgRG9tYWluJywKCQkJCV07CgkJCWRlZmF1bHQ6CgkJCQlyZXR1cm4gW107CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIFBPVCBmaWxlIGFuZCBzdG9yZXMgaXQgb24gZGlzay4KCSAqCgkgKiBAdGhyb3dzIFdQX0NMSVxFeGl0RXhjZXB0aW9uCgkgKgoJICogQHJldHVybiBUcmFuc2xhdGlvbnMgQSBUcmFuc2xhdGlvbiBzZXQuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBleHRyYWN0X3N0cmluZ3MoKSB7CgkJJHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoKTsKCgkJLy8gQWRkIGV4aXN0aW5nIHN0cmluZ3MgZmlyc3QgYnV0IGRvbid0IGtlZXAgaGVhZGVycy4KCQlpZiAoICEgZW1wdHkoICR0aGlzLT5tZXJnZSApICkgewoJCQkkZXhpc3RpbmdfdHJhbnNsYXRpb25zID0gbmV3IFRyYW5zbGF0aW9ucygpOwoJCQlQbzo6ZnJvbUZpbGUoICR0aGlzLT5tZXJnZSwgJGV4aXN0aW5nX3RyYW5zbGF0aW9ucyApOwoJCQkkdHJhbnNsYXRpb25zLT5tZXJnZVdpdGgoICRleGlzdGluZ190cmFuc2xhdGlvbnMsIE1lcmdlOjpBREQgfCBNZXJnZTo6UkVNT1ZFICk7CgkJfQoKCQlQb3RHZW5lcmF0b3I6OnNldENvbW1lbnRCZWZvcmVIZWFkZXJzKCAkdGhpcy0+Z2V0X2ZpbGVfY29tbWVudCgpICk7CgoJCSR0aGlzLT5zZXRfZGVmYXVsdF9oZWFkZXJzKCAkdHJhbnNsYXRpb25zICk7CgoJCS8vIFBPVCBmaWxlcyBoYXZlIG5vIExhbmd1YWdlIGhlYWRlci4KCQkkdHJhbnNsYXRpb25zLT5kZWxldGVIZWFkZXIoIFRyYW5zbGF0aW9uczo6SEVBREVSX0xBTkdVQUdFICk7CgoJCS8vIE9ubHkgcmVsZXZhbnQgZm9yIFBPIGZpbGVzLCBub3QgUE9UIGZpbGVzLgoJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJ1BPLVJldmlzaW9uLURhdGUnLCAnWUVBUi1NTy1EQSBITzpNSStaT05FJyApOwoKCQlpZiAoICR0aGlzLT5kb21haW4gKSB7CgkJCSR0cmFuc2xhdGlvbnMtPnNldERvbWFpbiggJHRoaXMtPmRvbWFpbiApOwoJCX0KCgkJdW5zZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVmVyc2lvbiddLCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0xpY2Vuc2UnXSwgJHRoaXMtPm1haW5fZmlsZV9kYXRhWydEb21haW4gUGF0aCddLCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1RleHQgRG9tYWluJ10gKTsKCgkJLy8gU2V0IGVudHJpZXMgZnJvbSBtYWluIGZpbGUgZGF0YS4KCQlmb3JlYWNoICggJHRoaXMtPm1haW5fZmlsZV9kYXRhIGFzICRoZWFkZXIgPT4gJGRhdGEgKSB7CgkJCWlmICggZW1wdHkoICRkYXRhICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHRyYW5zbGF0aW9uID0gbmV3IFRyYW5zbGF0aW9uKCAnJywgJGRhdGEgKTsKCgkJCWlmICggaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGhlbWUgTmFtZSddICkgKSB7CgkJCQkkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoIHNwcmludGYoICclcyBvZiB0aGUgdGhlbWUnLCAkaGVhZGVyICkgKTsKCQkJfSBlbHNlIHsKCQkJCSR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCggc3ByaW50ZiggJyVzIG9mIHRoZSBwbHVnaW4nLCAkaGVhZGVyICkgKTsKCQkJfQoKCQkJJHRyYW5zbGF0aW9uc1tdID0gJHRyYW5zbGF0aW9uOwoJCX0KCgkJdHJ5IHsKCQkJaWYgKCAhICR0aGlzLT5za2lwX3BocCApIHsKCQkJCSRvcHRpb25zID0gWwoJCQkJCS8vIEV4dHJhY3QgJ1RlbXBsYXRlIE5hbWUnIGhlYWRlcnMgaW4gdGhlbWUgZmlsZXMuCgkJCQkJJ3dwRXh0cmFjdFRlbXBsYXRlcycgPT4gaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGhlbWUgTmFtZSddICksCgkJCQkJJ2luY2x1ZGUnICAgICAgICAgICAgPT4gJHRoaXMtPmluY2x1ZGUsCgkJCQkJJ2V4Y2x1ZGUnICAgICAgICAgICAgPT4gJHRoaXMtPmV4Y2x1ZGUsCgkJCQkJJ2V4dGVuc2lvbnMnICAgICAgICAgPT4gWyAncGhwJyBdLAoJCQkJXTsKCQkJCVBocENvZGVFeHRyYWN0b3I6OmZyb21EaXJlY3RvcnkoICR0aGlzLT5zb3VyY2UsICR0cmFuc2xhdGlvbnMsICRvcHRpb25zICk7CgkJCX0KCgkJCWlmICggISAkdGhpcy0+c2tpcF9qcyApIHsKCQkJCUpzQ29kZUV4dHJhY3Rvcjo6ZnJvbURpcmVjdG9yeSgKCQkJCQkkdGhpcy0+c291cmNlLAoJCQkJCSR0cmFuc2xhdGlvbnMsCgkJCQkJWwoJCQkJCQknaW5jbHVkZScgICAgPT4gJHRoaXMtPmluY2x1ZGUsCgkJCQkJCSdleGNsdWRlJyAgICA9PiAkdGhpcy0+ZXhjbHVkZSwKCQkJCQkJJ2V4dGVuc2lvbnMnID0+IFsgJ2pzJywgJ2pzeCcgXSwKCQkJCQldCgkJCQkpOwoKCQkJCU1hcENvZGVFeHRyYWN0b3I6OmZyb21EaXJlY3RvcnkoCgkJCQkJJHRoaXMtPnNvdXJjZSwKCQkJCQkkdHJhbnNsYXRpb25zLAoJCQkJCVsKCQkJCQkJJ2luY2x1ZGUnICAgID0+ICR0aGlzLT5pbmNsdWRlLAoJCQkJCQknZXhjbHVkZScgICAgPT4gJHRoaXMtPmV4Y2x1ZGUsCgkJCQkJCSdleHRlbnNpb25zJyA9PiBbICdtYXAnIF0sCgkJCQkJXQoJCQkJKTsKCQkJfQoKCQkJaWYgKCAhICR0aGlzLT5za2lwX2Jsb2NrX2pzb24gKSB7CgkJCQlCbG9ja0V4dHJhY3Rvcjo6ZnJvbURpcmVjdG9yeSgKCQkJCQkkdGhpcy0+c291cmNlLAoJCQkJCSR0cmFuc2xhdGlvbnMsCgkJCQkJWwoJCQkJCQkvLyBPbmx5IGxvb2sgZm9yIGJsb2NrLmpzb24gZmlsZXMsIG5vdGhpbmcgZWxzZS4KCQkJCQkJJ3Jlc3RyaWN0RmlsZU5hbWVzJyA9PiBbICdibG9jay5qc29uJyBdLAoJCQkJCQknaW5jbHVkZScgICAgICAgICAgID0+ICR0aGlzLT5pbmNsdWRlLAoJCQkJCQknZXhjbHVkZScgICAgICAgICAgID0+ICR0aGlzLT5leGNsdWRlLAoJCQkJCQknZXh0ZW5zaW9ucycgICAgICAgID0+IFsgJ2pzb24nIF0sCgkJCQkJXQoJCQkJKTsKCQkJfQoJCX0gY2F0Y2ggKCBcRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQlmb3JlYWNoICggJHRoaXMtPmV4Y2VwdGlvbnMgYXMgJHRyYW5zbGF0aW9uICkgewoJCQlpZiAoICR0cmFuc2xhdGlvbnMtPmZpbmQoICR0cmFuc2xhdGlvbiApICkgewoJCQkJdW5zZXQoICR0cmFuc2xhdGlvbnNbICR0cmFuc2xhdGlvbi0+Z2V0SWQoKSBdICk7CgkJCX0KCQl9CgoJCWlmICggISAkdGhpcy0+c2tpcF9hdWRpdCApIHsKCQkJJHRoaXMtPmF1ZGl0X3N0cmluZ3MoICR0cmFuc2xhdGlvbnMgKTsKCQl9CgoJCXJldHVybiAkdHJhbnNsYXRpb25zOwoJfQoKCS8qKgoJICogQXVkaXRzIHN0cmluZ3MuCgkgKgoJICogR29lcyB0aHJvdWdoIGFsbCBleHRyYWN0ZWQgc3RyaW5ncyB0byBmaW5kIHBvc3NpYmxlIG1pc3Rha2VzLgoJICoKCSAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyBUcmFuc2xhdGlvbnMgb2JqZWN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYXVkaXRfc3RyaW5ncyggJHRyYW5zbGF0aW9ucyApIHsKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCS8qKiBAdmFyIFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbiAqLwoKCQkJJHJlZmVyZW5jZXMgPSAkdHJhbnNsYXRpb24tPmdldFJlZmVyZW5jZXMoKTsKCgkJCS8vIEZpbGUgaGVhZGVycyBkb24ndCBoYXZlIGFueSBmaWxlIHJlZmVyZW5jZXMuCgkJCSRsb2NhdGlvbiA9ICR0cmFuc2xhdGlvbi0+aGFzUmVmZXJlbmNlcygpID8gJygnIC4gaW1wbG9kZSggJzonLCBhcnJheV9zaGlmdCggJHJlZmVyZW5jZXMgKSApIC4gJyknIDogJyc7CgoJCQkvLyBDaGVjayAxOiBGbGFnIHN0cmluZ3Mgd2l0aCBwbGFjZWhvbGRlcnMgdGhhdCBzaG91bGQgaGF2ZSB0cmFuc2xhdG9yIGNvbW1lbnRzLgoJCQlpZiAoCgkJCQkhICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSAmJgoJCQkJcHJlZ19tYXRjaCggc2VsZjo6U1BSSU5URl9QTEFDRUhPTERFUl9SRUdFWCwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkcGxhY2Vob2xkZXJzICkgPj0gMQoJCQkpIHsKCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQknVGhlIHN0cmluZyAiJTEkcyIgY29udGFpbnMgcGxhY2Vob2xkZXJzIGJ1dCBoYXMgbm8gInRyYW5zbGF0b3JzOiIgY29tbWVudCB0byBjbGFyaWZ5IHRoZWlyIG1lYW5pbmcuICUyJHMnLAoJCQkJCSR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKSwKCQkJCQkkbG9jYXRpb24KCQkJCSk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRtZXNzYWdlICk7CgkJCX0KCgkJCS8vIENoZWNrIDI6IEZsYWcgc3RyaW5ncyB3aXRoIGRpZmZlcmVudCB0cmFuc2xhdG9yIGNvbW1lbnRzLgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSApIHsKCQkJCSRjb21tZW50cyA9ICR0cmFuc2xhdGlvbi0+Z2V0RXh0cmFjdGVkQ29tbWVudHMoKTsKCgkJCQkvLyBSZW1vdmUgcGx1Z2luIGhlYWRlciBpbmZvcm1hdGlvbiBmcm9tIGNvbW1lbnRzLgoJCQkJJGNvbW1lbnRzID0gYXJyYXlfZmlsdGVyKAoJCQkJCSRjb21tZW50cywKCQkJCQlmdW5jdGlvbiAoICRjb21tZW50ICkgewoJCQkJCQkvKiogQHZhciBzdHJpbmcgJGNvbW1lbnQgKi8KCQkJCQkJLyoqIEB2YXIgc3RyaW5nICRmaWxlX2hlYWRlciAqLwoJCQkJCQlmb3JlYWNoICggJHRoaXMtPmdldF9maWxlX2hlYWRlcnMoICR0aGlzLT5wcm9qZWN0X3R5cGUgKSBhcyAkZmlsZV9oZWFkZXIgKSB7CgkJCQkJCQlpZiAoIDAgPT09IHN0cnBvcyggJGNvbW1lbnQsICRmaWxlX2hlYWRlciApICkgewoJCQkJCQkJCXJldHVybiBudWxsOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gJGNvbW1lbnQ7CgkJCQkJfQoJCQkJKTsKCgkJCQkkY29tbWVudHNfY291bnQgPSBjb3VudCggJGNvbW1lbnRzICk7CgoJCQkJaWYgKCAkY29tbWVudHNfY291bnQgPiAxICkgewoJCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQkJJ1RoZSBzdHJpbmcgIiUxJHMiIGhhcyAlMiRkIGRpZmZlcmVudCB0cmFuc2xhdG9yIGNvbW1lbnRzLiAlMyRzJywKCQkJCQkJJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLAoJCQkJCQkkY29tbWVudHNfY291bnQsCgkJCQkJCSRsb2NhdGlvbgoJCQkJCSk7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkbWVzc2FnZSApOwoJCQkJfQoJCQl9CgoJCQkkbm9uX3BsYWNlaG9sZGVyX2NvbnRlbnQgPSB0cmltKCBwcmVnX3JlcGxhY2UoICdgXihbXCciXSkoLiopXDEkYERzJywgJyQyJywgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpICkgKTsKCQkJJG5vbl9wbGFjZWhvbGRlcl9jb250ZW50ID0gcHJlZ19yZXBsYWNlKCBzZWxmOjpTUFJJTlRGX1BMQUNFSE9MREVSX1JFR0VYLCAnJywgJG5vbl9wbGFjZWhvbGRlcl9jb250ZW50ICk7CgoJCQkvLyBDaGVjayAzOiBGbGFnIGVtcHR5IHN0cmluZ3Mgd2l0aG91dCBhbnkgdHJhbnNsYXRhYmxlIGNvbnRlbnQuCgkJCWlmICggJycgPT09ICRub25fcGxhY2Vob2xkZXJfY29udGVudCApIHsKCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQknRm91bmQgc3RyaW5nIHdpdGhvdXQgdHJhbnNsYXRhYmxlIGNvbnRlbnQuICVzJywKCQkJCQkkbG9jYXRpb24KCQkJCSk7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICRtZXNzYWdlICk7CgkJCX0KCgkJCS8vIENoZWNrIDQ6IEZsYWcgc3RyaW5ncyB3aXRoIG11bHRpcGxlIHVub3JkZXJlZCBwbGFjZWhvbGRlcnMgKCVzICVzICVzIHZzLiAlMSRzICUyJHMgJTMkcykuCgkJCSR1bm9yZGVyZWRfbWF0Y2hlc19jb3VudCA9IHByZWdfbWF0Y2hfYWxsKCBzZWxmOjpVTk9SREVSRURfU1BSSU5URl9QTEFDRUhPTERFUl9SRUdFWCwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkdW5vcmRlcmVkX21hdGNoZXMgKTsKCQkJJHVub3JkZXJlZF9tYXRjaGVzICAgICAgID0gJHVub3JkZXJlZF9tYXRjaGVzWzBdOwoKCQkJaWYgKCAkdW5vcmRlcmVkX21hdGNoZXNfY291bnQgPj0gMiApIHsKCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQknTXVsdGlwbGUgcGxhY2Vob2xkZXJzIHNob3VsZCBiZSBvcmRlcmVkLiAlcycsCgkJCQkJJGxvY2F0aW9uCgkJCQkpOwoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAkbWVzc2FnZSApOwoJCQl9CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsKCkgKSB7CgkJCQlwcmVnX21hdGNoX2FsbCggc2VsZjo6U1BSSU5URl9QTEFDRUhPTERFUl9SRUdFWCwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkc2luZ2xlX3BsYWNlaG9sZGVycyApOwoJCQkJJHNpbmdsZV9wbGFjZWhvbGRlcnMgPSAkc2luZ2xlX3BsYWNlaG9sZGVyc1swXTsKCgkJCQlwcmVnX21hdGNoX2FsbCggc2VsZjo6U1BSSU5URl9QTEFDRUhPTERFUl9SRUdFWCwgJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWwoKSwgJHBsdXJhbF9wbGFjZWhvbGRlcnMgKTsKCQkJCSRwbHVyYWxfcGxhY2Vob2xkZXJzID0gJHBsdXJhbF9wbGFjZWhvbGRlcnNbMF07CgoJCQkJLy8gc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLndvcmRwcmVzcy5vcmcvcGx1Z2lucy9pbnRlcm5hdGlvbmFsaXphdGlvbi9ob3ctdG8taW50ZXJuYXRpb25hbGl6ZS15b3VyLXBsdWdpbi8jcGx1cmFscwoJCQkJaWYgKCBjb3VudCggJHNpbmdsZV9wbGFjZWhvbGRlcnMgKSA8IGNvdW50KCAkcGx1cmFsX3BsYWNlaG9sZGVycyApICkgewoJCQkJCS8vIENoZWNrIDU6IEZsYWcgdGhpbmdzIGxpa2UgX24oICdPbmUgY29tbWVudCcsICclcyBDb21tZW50cycgKQoJCQkJCSRtZXNzYWdlID0gc3ByaW50ZigKCQkJCQkJJ01pc3Npbmcgc2luZ3VsYXIgcGxhY2Vob2xkZXIsIG5lZWRlZCBmb3Igc29tZSBsYW5ndWFnZXMuIFNlZSBodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3BsdWdpbnMvaW50ZXJuYXRpb25hbGl6YXRpb24vaG93LXRvLWludGVybmF0aW9uYWxpemUteW91ci1wbHVnaW4vI3BsdXJhbHMgJXMnLAoJCQkJCQkkbG9jYXRpb24KCQkJCQkpOwoJCQkJCVdQX0NMSTo6d2FybmluZyggJG1lc3NhZ2UgKTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gUmVvcmRlcmluZyBpcyBmaW5lLCBidXQgbWlzbWF0Y2hlZCBwbGFjZWhvbGRlcnMgaXMgcHJvYmFibHkgd3JvbmcuCgkJCQkJc29ydCggJHNpbmdsZV9wbGFjZWhvbGRlcnMgKTsKCQkJCQlzb3J0KCAkcGx1cmFsX3BsYWNlaG9sZGVycyApOwoKCQkJCQkvLyBDaGVjayA2OiBGbGFnIHRoaW5ncyBsaWtlIF9uKCAnJXMgQ29tbWVudCAoJWQpJywgJyVzIENvbW1lbnRzICglcyknICkKCQkJCQlpZiAoICRzaW5nbGVfcGxhY2Vob2xkZXJzICE9PSAkcGx1cmFsX3BsYWNlaG9sZGVycyApIHsKCQkJCQkJJG1lc3NhZ2UgPSBzcHJpbnRmKAoJCQkJCQkJJ01pc21hdGNoZWQgcGxhY2Vob2xkZXJzIGZvciBzaW5ndWxhciBhbmQgcGx1cmFsIHN0cmluZy4gJXMnLAoJCQkJCQkJJGxvY2F0aW9uCgkJCQkJCSk7CgkJCQkJCVdQX0NMSTo6d2FybmluZyggJG1lc3NhZ2UgKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBjb3B5cmlnaHQgY29tbWVudCBmb3IgdGhlIGdpdmVuIHBhY2thZ2UuCgkgKgoJICogQHJldHVybiBzdHJpbmcgRmlsZSBjb21tZW50LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2ZpbGVfY29tbWVudCgpIHsKCQlpZiAoICcnID09PSAkdGhpcy0+ZmlsZV9jb21tZW50ICkgewoJCQlyZXR1cm4gJyc7CgkJfQoKCQlpZiAoIGlzc2V0KCAkdGhpcy0+ZmlsZV9jb21tZW50ICkgKSB7CgkJCXJldHVybiBpbXBsb2RlKCAiXG4iLCBleHBsb2RlKCAnXG4nLCAkdGhpcy0+ZmlsZV9jb21tZW50ICkgKTsKCQl9CgoJCWlmICggaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGhlbWUgTmFtZSddICkgKSB7CgkJCWlmICggaXNzZXQoICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnTGljZW5zZSddICkgKSB7CgkJCQlyZXR1cm4gc3ByaW50ZigKCQkJCQkiQ29weXJpZ2h0IChDKSAlMVwkcyAlMlwkc1xuVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSAlM1wkcy4iLAoJCQkJCWRhdGUoICdZJyApLCAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydBdXRob3InXSwKCQkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0xpY2Vuc2UnXQoJCQkJKTsKCQkJfQoKCQkJcmV0dXJuIHNwcmludGYoCgkJCQkiQ29weXJpZ2h0IChDKSAlMVwkcyAlMlwkc1xuVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBzYW1lIGxpY2Vuc2UgYXMgdGhlICUzXCRzIHRoZW1lLiIsCgkJCQlkYXRlKCAnWScgKSwgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydBdXRob3InXSwKCQkJCSR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGhlbWUgTmFtZSddCgkJCSk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1BsdWdpbiBOYW1lJ10gKSApIHsKCQkJaWYgKCBpc3NldCggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydMaWNlbnNlJ10gKSAmJiAhIGVtcHR5KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0xpY2Vuc2UnXSApICkgewoJCQkJcmV0dXJuIHNwcmludGYoCgkJCQkJIkNvcHlyaWdodCAoQykgJTFcJHMgJTJcJHNcblRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgJTNcJHMuIiwKCQkJCQlkYXRlKCAnWScgKSwgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCQkJCSR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnQXV0aG9yJ10sCgkJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydMaWNlbnNlJ10KCQkJCSk7CgkJCX0KCgkJCXJldHVybiBzcHJpbnRmKAoJCQkJIkNvcHlyaWdodCAoQykgJTFcJHMgJTJcJHNcblRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgc2FtZSBsaWNlbnNlIGFzIHRoZSAlM1wkcyBwbHVnaW4uIiwKCQkJCWRhdGUoICdZJyApLCAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJCQkkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ0F1dGhvciddLAoJCQkJJHRoaXMtPm1haW5fZmlsZV9kYXRhWydQbHVnaW4gTmFtZSddCgkJCSk7CgkJfQoKCQlyZXR1cm4gJyc7Cgl9CgoJLyoqCgkgKiBTZXRzIGRlZmF1bHQgUE9UIGZpbGUgaGVhZGVycyBmb3IgdGhlIHByb2plY3QuCgkgKgoJICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zIFRyYW5zbGF0aW9ucyBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRfZGVmYXVsdF9oZWFkZXJzKCAkdHJhbnNsYXRpb25zICkgewoJCSRuYW1lICAgICAgICAgPSBudWxsOwoJCSR2ZXJzaW9uICAgICAgPSAkdGhpcy0+Z2V0X3dwX3ZlcnNpb24oKTsKCQkkYnVnc19hZGRyZXNzID0gbnVsbDsKCgkJaWYgKCAhICR2ZXJzaW9uICYmIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1ZlcnNpb24nXSApICkgewoJCQkkdmVyc2lvbiA9ICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVmVyc2lvbiddOwoJCX0KCgkJaWYgKCBpc3NldCggJHRoaXMtPm1haW5fZmlsZV9kYXRhWydUaGVtZSBOYW1lJ10gKSApIHsKCQkJJG5hbWUgICAgICAgICA9ICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnVGhlbWUgTmFtZSddOwoJCQkkYnVnc19hZGRyZXNzID0gc3ByaW50ZiggJ2h0dHBzOi8vd29yZHByZXNzLm9yZy9zdXBwb3J0L3RoZW1lLyVzJywgJHRoaXMtPnNsdWcgKTsKCQl9IGVsc2VpZiAoIGlzc2V0KCAkdGhpcy0+bWFpbl9maWxlX2RhdGFbJ1BsdWdpbiBOYW1lJ10gKSApIHsKCQkJJG5hbWUgICAgICAgICA9ICR0aGlzLT5tYWluX2ZpbGVfZGF0YVsnUGx1Z2luIE5hbWUnXTsKCQkJJGJ1Z3NfYWRkcmVzcyA9IHNwcmludGYoICdodHRwczovL3dvcmRwcmVzcy5vcmcvc3VwcG9ydC9wbHVnaW4vJXMnLCAkdGhpcy0+c2x1ZyApOwoJCX0KCgkJaWYgKCBudWxsICE9PSAkdGhpcy0+cGFja2FnZV9uYW1lICkgewoJCQkkbmFtZSA9ICR0aGlzLT5wYWNrYWdlX25hbWU7CgkJfQoKCQlpZiAoIG51bGwgIT09ICRuYW1lICkgewoJCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICdQcm9qZWN0LUlkLVZlcnNpb24nLCAkbmFtZSAuICggJHZlcnNpb24gPyAnICcgLiAkdmVyc2lvbiA6ICcnICkgKTsKCQl9CgoJCWlmICggbnVsbCAhPT0gJGJ1Z3NfYWRkcmVzcyApIHsKCQkJJHRyYW5zbGF0aW9ucy0+c2V0SGVhZGVyKCAnUmVwb3J0LU1zZ2lkLUJ1Z3MtVG8nLCAkYnVnc19hZGRyZXNzICk7CgkJfQoKCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICdMYXN0LVRyYW5zbGF0b3InLCAnRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPicgKTsKCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICdMYW5ndWFnZS1UZWFtJywgJ0xBTkdVQUdFIDxMTEBsaS5vcmc+JyApOwoJCSR0cmFuc2xhdGlvbnMtPnNldEhlYWRlciggJ1gtR2VuZXJhdG9yJywgJ1dQLUNMSSAnIC4gV1BfQ0xJX1ZFUlNJT04gKTsKCgkJZm9yZWFjaCAoICR0aGlzLT5oZWFkZXJzIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoICRrZXksICR2YWx1ZSApOwoJCX0KCX0KCgkvKioKCSAqIEV4dHJhY3RzIHRoZSBXb3JkUHJlc3MgdmVyc2lvbiBudW1iZXIgZnJvbSB3cC1pbmNsdWRlcy92ZXJzaW9uLnBocC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBWZXJzaW9uIG51bWJlciBvbiBzdWNjZXNzLCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBnZXRfd3BfdmVyc2lvbigpIHsKCQkkdmVyc2lvbl9waHAgPSAkdGhpcy0+c291cmNlIC4gJy93cC1pbmNsdWRlcy92ZXJzaW9uLnBocCc7CgkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkdmVyc2lvbl9waHAgKSB8fCAhIGlzX3JlYWRhYmxlKCAkdmVyc2lvbl9waHAgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuIHByZWdfbWF0Y2goICcvXCR3cF92ZXJzaW9uXHMqPVxzKlwnKC4qPylcJzsvJywgZmlsZV9nZXRfY29udGVudHMoICR2ZXJzaW9uX3BocCApLCAkbWF0Y2hlcyApID8gJG1hdGNoZXNbMV0gOiBmYWxzZTsKCX0KCgkvKioKCSAqIFJldHJpZXZlcyBtZXRhZGF0YSBmcm9tIGEgZmlsZS4KCSAqCgkgKiBTZWFyY2hlcyBmb3IgbWV0YWRhdGEgaW4gdGhlIGZpcnN0IDhraUIgb2YgYSBmaWxlLCBzdWNoIGFzIGEgcGx1Z2luIG9yIHRoZW1lLgoJICogRWFjaCBwaWVjZSBvZiBtZXRhZGF0YSBtdXN0IGJlIG9uIGl0cyBvd24gbGluZS4gRmllbGRzIGNhbiBub3Qgc3BhbiBtdWx0aXBsZQoJICogbGluZXMsIHRoZSB2YWx1ZSB3aWxsIGdldCBjdXQgYXQgdGhlIGVuZCBvZiB0aGUgZmlyc3QgbGluZS4KCSAqCgkgKiBJZiB0aGUgZmlsZSBkYXRhIGlzIG5vdCB3aXRoaW4gdGhhdCBmaXJzdCA4a2lCLCB0aGVuIHRoZSBhdXRob3Igc2hvdWxkIGNvcnJlY3QKCSAqIHRoZWlyIHBsdWdpbiBmaWxlIGFuZCBtb3ZlIHRoZSBkYXRhIGhlYWRlcnMgdG8gdGhlIHRvcC4KCSAqCgkgKiBAc2VlIGdldF9maWxlX2RhdGEoKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgUGF0aCB0byB0aGUgZmlsZS4KCSAqIEBwYXJhbSBhcnJheSAkaGVhZGVycyBMaXN0IG9mIGhlYWRlcnMsIGluIHRoZSBmb3JtYXQgYXJyYXkoJ0hlYWRlcktleScgPT4gJ0hlYWRlciBOYW1lJykuCgkgKgoJICogQHJldHVybiBhcnJheSBBcnJheSBvZiBmaWxlIGhlYWRlcnMgaW4gYEhlYWRlcktleSA9PiBIZWFkZXIgVmFsdWVgIGZvcm1hdC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRfZmlsZV9kYXRhKCAkZmlsZSwgJGhlYWRlcnMgKSB7CgkJLy8gV2UgZG9uJ3QgbmVlZCB0byB3cml0ZSB0byB0aGUgZmlsZSwgc28ganVzdCBvcGVuIGZvciByZWFkaW5nLgoJCSRmcCA9IGZvcGVuKCAkZmlsZSwgJ3JiJyApOwoKCQkvLyBQdWxsIG9ubHkgdGhlIGZpcnN0IDhraUIgb2YgdGhlIGZpbGUgaW4uCgkJJGZpbGVfZGF0YSA9IGZyZWFkKCAkZnAsIDgxOTIgKTsKCgkJLy8gUEhQIHdpbGwgY2xvc2UgZmlsZSBoYW5kbGUsIGJ1dCB3ZSBhcmUgZ29vZCBjaXRpemVucy4KCQlmY2xvc2UoICRmcCApOwoKCQkvLyBNYWtlIHN1cmUgd2UgY2F0Y2ggQ1Itb25seSBsaW5lIGVuZGluZ3MuCgkJJGZpbGVfZGF0YSA9IHN0cl9yZXBsYWNlKCAiXHIiLCAiXG4iLCAkZmlsZV9kYXRhICk7CgoJCXJldHVybiBzdGF0aWM6OmdldF9maWxlX2RhdGFfZnJvbV9zdHJpbmcoICRmaWxlX2RhdGEsICRoZWFkZXJzICk7Cgl9CgoJLyoqCgkgKiBSZXRyaWV2ZXMgbWV0YWRhdGEgZnJvbSBhIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgU3RyaW5nIHRvIGxvb2sgZm9yIG1ldGFkYXRhIGluLgoJICogQHBhcmFtIGFycmF5ICRoZWFkZXJzIExpc3Qgb2YgaGVhZGVycy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIGZpbGUgaGVhZGVycyBpbiBgSGVhZGVyS2V5ID0+IEhlYWRlciBWYWx1ZWAgZm9ybWF0LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldF9maWxlX2RhdGFfZnJvbV9zdHJpbmcoICRzdHJpbmcsICRoZWFkZXJzICkgewoJCWZvcmVhY2ggKCAkaGVhZGVycyBhcyAkZmllbGQgPT4gJHJlZ2V4ICkgewoJCQlpZiAoIHByZWdfbWF0Y2goICcvXlsgXHRcLyojQF0qJyAuIHByZWdfcXVvdGUoICRyZWdleCwgJy8nICkgLiAnOiguKikkL21pJywgJHN0cmluZywgJG1hdGNoICkgJiYgJG1hdGNoWzFdICkgewoJCQkJJGhlYWRlcnNbICRmaWVsZCBdID0gc3RhdGljOjpfY2xlYW51cF9oZWFkZXJfY29tbWVudCggJG1hdGNoWzFdICk7CgkJCX0gZWxzZSB7CgkJCQkkaGVhZGVyc1sgJGZpZWxkIF0gPSAnJzsKCQkJfQoJCX0KCgkJcmV0dXJuICRoZWFkZXJzOwoJfQoKCS8qKgoJICogU3RyaXAgY2xvc2UgY29tbWVudCBhbmQgY2xvc2UgcGhwIHRhZ3MgZnJvbSBmaWxlIGhlYWRlcnMgdXNlZCBieSBXUC4KCSAqCgkgKiBAc2VlIF9jbGVhbnVwX2hlYWRlcl9jb21tZW50KCkKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHIgSGVhZGVyIGNvbW1lbnQgdG8gY2xlYW4gdXAuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBfY2xlYW51cF9oZWFkZXJfY29tbWVudCggJHN0ciApIHsgLy8gcGhwY3M6aWdub3JlIFBTUjIuTWV0aG9kcy5NZXRob2REZWNsYXJhdGlvbi5VbmRlcnNjb3JlIC0tIE5vdCBjaGFuZ2luZyBiZWNhdXNlIHRoaXJkLXBhcnR5IGNvbW1hbmRzIG1pZ2h0IHVzZS9leHRlbmQuCgkJcmV0dXJuIHRyaW0oIHByZWdfcmVwbGFjZSggJy9ccyooPzpcKlwvfFw/PikuKi8nLCAnJywgJHN0ciApICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBHZXR0ZXh0XFV0aWxzXFBocEZ1bmN0aW9uc1NjYW5uZXIgYXMgR2V0dGV4dFBocEZ1bmN0aW9uc1NjYW5uZXI7CgpjbGFzcyBQaHBGdW5jdGlvbnNTY2FubmVyIGV4dGVuZHMgR2V0dGV4dFBocEZ1bmN0aW9uc1NjYW5uZXIgewoKCS8qKgoJICoge0Bpbmhlcml0ZG9jfQoJICovCglwdWJsaWMgZnVuY3Rpb24gc2F2ZUdldHRleHRGdW5jdGlvbnMoICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zICkgewoJCS8vIElnbm9yZSBtdWx0aXBsZSB0cmFuc2xhdGlvbnMgZm9yIG5vdy4KCQkvLyBAdG9kbyBBZGQgcHJvcGVyIHN1cHBvcnQgZm9yIG11bHRpcGxlIHRyYW5zbGF0aW9ucy4KCQlpZiAoIGlzX2FycmF5KCAkdHJhbnNsYXRpb25zICkgKSB7CgkJCSR0cmFuc2xhdGlvbnMgPSAkdHJhbnNsYXRpb25zWzBdOwoJCX0KCgkJJGZ1bmN0aW9ucyA9ICRvcHRpb25zWydmdW5jdGlvbnMnXTsKCQkkZmlsZSAgICAgID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCgkJZm9yZWFjaCAoICR0aGlzLT5nZXRGdW5jdGlvbnMoICRvcHRpb25zWydjb25zdGFudHMnXSApIGFzICRmdW5jdGlvbiApIHsKCQkJbGlzdCggJG5hbWUsICRsaW5lLCAkYXJncyApID0gJGZ1bmN0aW9uOwoKCQkJaWYgKCAhIGlzc2V0KCAkZnVuY3Rpb25zWyAkbmFtZSBdICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJG9yaWdpbmFsID0gbnVsbDsKCQkJJGRvbWFpbiAgID0gbnVsbDsKCQkJJGNvbnRleHQgID0gbnVsbDsKCQkJJHBsdXJhbCAgID0gbnVsbDsKCgkJCXN3aXRjaCAoICRmdW5jdGlvbnNbICRuYW1lIF0gKSB7CgkJCQljYXNlICd0ZXh0X2RvbWFpbic6CgkJCQljYXNlICdnZXR0ZXh0JzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDIsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICd0ZXh0X2NvbnRleHRfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCAzLCBudWxsICk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRudW1iZXIsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDQsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICdzaW5nbGVfcGx1cmFsX251bWJlcl9jb250ZXh0X2RvbWFpbic6CgkJCQkJbGlzdCggJG9yaWdpbmFsLCAkcGx1cmFsLCAkbnVtYmVyLCAkY29udGV4dCwgJGRvbWFpbiApID0gYXJyYXlfcGFkKCAkYXJncywgNSwgbnVsbCApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgJ3NpbmdsZV9wbHVyYWxfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDMsIG51bGwgKTsKCQkJCQlicmVhazsKCgkJCQljYXNlICdzaW5nbGVfcGx1cmFsX2NvbnRleHRfZG9tYWluJzoKCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCA0LCBudWxsICk7CgkJCQkJYnJlYWs7CgoJCQkJZGVmYXVsdDoKCQkJCQkvLyBTaG91bGQgbmV2ZXIgaGFwcGVuLgoJCQkJCVxXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW50ZXJuYWwgZXJyb3I6IHVua25vd24gZnVuY3Rpb24gbWFwICclcycgZm9yICclcycuIiwgJGZ1bmN0aW9uc1sgJG5hbWUgXSwgJG5hbWUgKSApOwoJCQl9CgoJCQlpZiAoICcnID09PSAoc3RyaW5nKSAkb3JpZ2luYWwgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAkZG9tYWluICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSAmJiBudWxsICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb25zLT5pbnNlcnQoICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwgKTsKCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5hZGRSZWZlcmVuY2UoICRmaWxlLCAkbGluZSApOwoKCQkJaWYgKCBpc3NldCggJGZ1bmN0aW9uWzNdICkgKSB7CgkJCQlmb3JlYWNoICggJGZ1bmN0aW9uWzNdIGFzICRleHRyYWN0ZWRfY29tbWVudCApIHsKCQkJCQkkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoICRleHRyYWN0ZWRfY29tbWVudCApOwoJCQkJfQoJCQl9CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXEpzQ29kZTsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgUGVhc3RcU3ludGF4XEV4Y2VwdGlvbiBhcyBQZWFzdEV4Y2VwdGlvbjsKdXNlIFdQX0NMSTsKCmZpbmFsIGNsYXNzIE1hcENvZGVFeHRyYWN0b3IgZXh0ZW5kcyBKc0NvZGUgewoJdXNlIEl0ZXJhYmxlQ29kZUV4dHJhY3RvcjsKCglwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwoJCSdleHRyYWN0Q29tbWVudHMnID0+IFsgJ3RyYW5zbGF0b3JzJywgJ1RyYW5zbGF0b3JzJyBdLAoJCSdjb25zdGFudHMnICAgICAgID0+IFtdLAoJCSdmdW5jdGlvbnMnICAgICAgID0+IFsKCQkJJ19fJyAgPT4gJ3RleHRfZG9tYWluJywKCQkJJ194JyAgPT4gJ3RleHRfY29udGV4dF9kb21haW4nLAoJCQknX24nICA9PiAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJywKCQkJJ19ueCcgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2NvbnRleHRfZG9tYWluJywKCQldLAoJXTsKCgkvKioKCSAqIHtAaW5oZXJpdGRvY30KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCAkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSApIHsKCQlpZiAoICEgYXJyYXlfa2V5X2V4aXN0cyggJ2ZpbGUnLCAkb3B0aW9ucyApIHx8IHN1YnN0ciggJG9wdGlvbnNbJ2ZpbGUnXSwgLTcgKSAhPT0gJy5qcy5tYXAnICkgewoJCQlyZXR1cm47CgkJfQoJCSRvcHRpb25zWydmaWxlJ10gPSBzdWJzdHIoICRvcHRpb25zWydmaWxlJ10sIDAsIC03ICkgLiAnLmpzJzsKCgkJdHJ5IHsKCQkJJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCgkJCSRtYXBfb2JqZWN0ID0ganNvbl9kZWNvZGUoICRzdHJpbmcgKTsKCgkJCWlmICggISBpc3NldCggJG1hcF9vYmplY3QtPnNvdXJjZXNDb250ZW50ICkgfHwgISBpc19hcnJheSggJG1hcF9vYmplY3QtPnNvdXJjZXNDb250ZW50ICkgKSB7CgkJCQlyZXR1cm47CgkJCX0KCgkJCSRzdHJpbmcgPSBpbXBsb2RlKCAiXG4iLCAkbWFwX29iamVjdC0+c291cmNlc0NvbnRlbnQgKTsKCgkJCVdQX0NMSTo6ZGVidWcoICJQYXJzaW5nIGZpbGUgeyRvcHRpb25zWydmaWxlJ119IiwgJ21ha2UtcG90JyApOwoKCQkJJGZ1bmN0aW9ucyA9IG5ldyBKc0Z1bmN0aW9uc1NjYW5uZXIoICRzdHJpbmcgKTsKCgkJCSRmdW5jdGlvbnMtPmVuYWJsZUNvbW1lbnRzRXh0cmFjdGlvbiggJG9wdGlvbnNbJ2V4dHJhY3RDb21tZW50cyddICk7CgkJCSRmdW5jdGlvbnMtPnNhdmVHZXR0ZXh0RnVuY3Rpb25zKCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyApOwoJCX0gY2F0Y2ggKCBQZWFzdEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjpkZWJ1ZygKCQkJCXNwcmludGYoCgkJCQkJJ0NvdWxkIG5vdCBwYXJzZSBmaWxlICUxJHMubWFwOiAlMiRzIChsaW5lICUzJGQsIGNvbHVtbiAlNCRkIGluIHRoZSBjb25jYXRlbmF0ZWQgc291cmNlc0NvbnRlbnQpJywKCQkJCQkkb3B0aW9uc1snZmlsZSddLAoJCQkJCSRlLT5nZXRNZXNzYWdlKCksCgkJCQkJJGUtPmdldFBvc2l0aW9uKCktPmdldExpbmUoKSwKCQkJCQkkZS0+Z2V0UG9zaXRpb24oKS0+Z2V0Q29sdW1uKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxVdGlsc1xKc0Z1bmN0aW9uc1NjYW5uZXIgYXMgR2V0dGV4dEpzRnVuY3Rpb25zU2Nhbm5lcjsKdXNlIEdldHRleHRcVXRpbHNcUGFyc2VkQ29tbWVudDsKdXNlIFBlYXN0XFBlYXN0Owp1c2UgUGVhc3RcU3ludGF4XE5vZGU7CnVzZSBQZWFzdFxUcmF2ZXJzZXI7CgpmaW5hbCBjbGFzcyBKc0Z1bmN0aW9uc1NjYW5uZXIgZXh0ZW5kcyBHZXR0ZXh0SnNGdW5jdGlvbnNTY2FubmVyIHsKCgkvKioKCSAqIElmIG5vdCBmYWxzZSwgY29tbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQuCgkgKgoJICogQHZhciBzdHJpbmd8ZmFsc2V8YXJyYXkKCSAqLwoJcHJpdmF0ZSAkZXh0cmFjdF9jb21tZW50cyA9IGZhbHNlOwoKCS8qKgoJICogRW5hYmxlIGV4dHJhY3RpbmcgY29tbWVudHMgdGhhdCBzdGFydCB3aXRoIGEgdGFnIChpZiAkdGFnIGlzIGVtcHR5IGFsbCB0aGUgY29tbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQpLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAkdGFnCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlbmFibGVDb21tZW50c0V4dHJhY3Rpb24oICR0YWcgPSAnJyApIHsKCQkkdGhpcy0+ZXh0cmFjdF9jb21tZW50cyA9ICR0YWc7Cgl9CgoJLyoqCgkgKiBEaXNhYmxlIGNvbW1lbnRzIGV4dHJhY3Rpb24uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlQ29tbWVudHNFeHRyYWN0aW9uKCkgewoJCSR0aGlzLT5leHRyYWN0X2NvbW1lbnRzID0gZmFsc2U7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXRkb2N9CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzYXZlR2V0dGV4dEZ1bmN0aW9ucyggJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgKSB7CgkJLy8gSWdub3JlIG11bHRpcGxlIHRyYW5zbGF0aW9ucyBmb3Igbm93LgoJCS8vIEB0b2RvIEFkZCBwcm9wZXIgc3VwcG9ydCBmb3IgbXVsdGlwbGUgdHJhbnNsYXRpb25zLgoJCWlmICggaXNfYXJyYXkoICR0cmFuc2xhdGlvbnMgKSApIHsKCQkJJHRyYW5zbGF0aW9ucyA9ICR0cmFuc2xhdGlvbnNbMF07CgkJfQoKCQkkY29kZSA9ICR0aGlzLT5jb2RlOwoJCS8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbWNrODkvcGVhc3QvaXNzdWVzLzcKCQkvLyBUZW1wb3Jhcnkgd29ya2Fyb3VuZCB0byBmaXggZHluYW1pYyBpbXBvcnRzLiBUaGUgz4QgaXMgYSBncmVlayBsZXR0ZXIuCgkJLy8gVGhpcyB3aWxsIHRyaWNrIHRoZSBwYXJzZXIgaW50byB0aGlua2luZyB0aGF0IGl0IGlzIGEgbm9ybWFsIG1ldGhvZCBjYWxsLgoJCSRjb2RlID0gcHJlZ19yZXBsYWNlKCAnL2ltcG9ydChcXHMqXFwoKS8nLCAnaW1wb3LPhCQxJywgJGNvZGUgKTsKCgkJJHBlYXN0X29wdGlvbnMgPSBbCgkJCSdzb3VyY2VUeXBlJyA9PiBQZWFzdDo6U09VUkNFX1RZUEVfTU9EVUxFLAoJCQknY29tbWVudHMnICAgPT4gZmFsc2UgIT09ICR0aGlzLT5leHRyYWN0X2NvbW1lbnRzLAoJCQknanN4JyAgICAgICAgPT4gdHJ1ZSwKCQldOwoJCSRhc3QgICAgICAgICAgID0gUGVhc3Q6OmxhdGVzdCggJGNvZGUsICRwZWFzdF9vcHRpb25zICktPnBhcnNlKCk7CgoJCSR0cmF2ZXJzZXIgPSBuZXcgVHJhdmVyc2VyKCk7CgoJCSRhbGxfY29tbWVudHMgPSBbXTsKCgkJLyoqCgkJICogVHJhdmVyc2UgdGhyb3VnaCBKUyBjb2RlIHRvIGZpbmQgYW5kIGV4dHJhY3QgZ2V0dGV4dCBmdW5jdGlvbnMuCgkJICoKCQkgKiBNYWtlIHN1cmUgdHJhbnNsYXRvciBjb21tZW50cyBpbiBmcm9udCBvZiB2YXJpYWJsZSBkZWNsYXJhdGlvbnMKCQkgKiBhbmQgaW5zaWRlIG5lc3RlZCBjYWxsIGV4cHJlc3Npb25zIGFyZSBhdmFpbGFibGUgd2hlbiBwYXJzaW5nIHRoZSBmdW5jdGlvbiBjYWxsLgoJCSAqLwoJCSR0cmF2ZXJzZXItPmFkZEZ1bmN0aW9uKAoJCQlmdW5jdGlvbiAoICRub2RlICkgdXNlICggJiR0cmFuc2xhdGlvbnMsICRvcHRpb25zLCAmJGFsbF9jb21tZW50cyApIHsKCQkJCSRmdW5jdGlvbnMgPSAkb3B0aW9uc1snZnVuY3Rpb25zJ107CgkJCQkkZmlsZSAgICAgID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCgkJCQkvKiogQHZhciBOb2RlXE5vZGUgJG5vZGUgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0TGVhZGluZ0NvbW1lbnRzKCkgYXMgJGNvbW1lbnQgKSB7CgkJCQkJJGFsbF9jb21tZW50c1tdID0gJGNvbW1lbnQ7CgkJCQl9CgoJCQkJLyoqIEB2YXIgTm9kZVxDYWxsRXhwcmVzc2lvbiAkbm9kZSAqLwoJCQkJaWYgKCAnQ2FsbEV4cHJlc3Npb24nICE9PSAkbm9kZS0+Z2V0VHlwZSgpICkgewoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQkkY2FsbGVlID0gJHRoaXMtPnJlc29sdmVFeHByZXNzaW9uQ2FsbGVlKCAkbm9kZSApOwoKCQkJCWlmICggISAkY2FsbGVlIHx8ICEgaXNzZXQoICRmdW5jdGlvbnNbICRjYWxsZWVbJ25hbWUnXSBdICkgKSB7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCS8qKiBAdmFyIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCS8vIFN1cHBvcnQgbmVzdGVkIGZ1bmN0aW9uIGNhbGxzLgoJCQkJCSRhcmd1bWVudC0+c2V0TGVhZGluZ0NvbW1lbnRzKCAkYXJndW1lbnQtPmdldExlYWRpbmdDb21tZW50cygpICsgJG5vZGUtPmdldExlYWRpbmdDb21tZW50cygpICk7CgkJCQl9CgoJCQkJZm9yZWFjaCAoICRjYWxsZWVbJ2NvbW1lbnRzJ10gYXMgJGNvbW1lbnQgKSB7CgkJCQkJJGFsbF9jb21tZW50c1tdID0gJGNvbW1lbnQ7CgkJCQl9CgoJCQkJJGRvbWFpbiAgID0gbnVsbDsKCQkJCSRvcmlnaW5hbCA9IG51bGw7CgkJCQkkY29udGV4dCAgPSBudWxsOwoJCQkJJHBsdXJhbCAgID0gbnVsbDsKCQkJCSRhcmdzICAgICA9IFtdOwoKCQkJCS8qKiBAdmFyIE5vZGVcTm9kZSAkYXJndW1lbnQgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCWZvcmVhY2ggKCAkYXJndW1lbnQtPmdldExlYWRpbmdDb21tZW50cygpIGFzICRjb21tZW50ICkgewoJCQkJCQkkYWxsX2NvbW1lbnRzW10gPSAkY29tbWVudDsKCQkJCQl9CgoJCQkJCWlmICggJ0lkZW50aWZpZXInID09PSAkYXJndW1lbnQtPmdldFR5cGUoKSApIHsKCQkJCQkJJGFyZ3NbXSA9ICcnOyAvLyBUaGUgdmFsdWUgZG9lc24ndCBtYXR0ZXIgYXMgaXQncyB1bnVzZWQuCgkJCQkJfQoKCQkJCQlpZiAoICdMaXRlcmFsJyA9PT0gJGFyZ3VtZW50LT5nZXRUeXBlKCkgKSB7CgkJCQkJCS8qKiBAdmFyIE5vZGVcTGl0ZXJhbCAkYXJndW1lbnQgKi8KCQkJCQkJJGFyZ3NbXSA9ICRhcmd1bWVudC0+Z2V0VmFsdWUoKTsKCQkJCQl9CgkJCQl9CgoJCQkJc3dpdGNoICggJGZ1bmN0aW9uc1sgJGNhbGxlZVsnbmFtZSddIF0gKSB7CgkJCQkJY2FzZSAndGV4dF9kb21haW4nOgoJCQkJCWNhc2UgJ2dldHRleHQnOgoJCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDIsIG51bGwgKTsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ3RleHRfY29udGV4dF9kb21haW4nOgoJCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRjb250ZXh0LCAkZG9tYWluICkgPSBhcnJheV9wYWQoICRhcmdzLCAzLCBudWxsICk7CgkJCQkJCWJyZWFrOwoKCQkJCQljYXNlICdzaW5nbGVfcGx1cmFsX251bWJlcl9kb21haW4nOgoJCQkJCQlsaXN0KCAkb3JpZ2luYWwsICRwbHVyYWwsICRudW1iZXIsICRkb21haW4gKSA9IGFycmF5X3BhZCggJGFyZ3MsIDQsIG51bGwgKTsKCQkJCQkJYnJlYWs7CgoJCQkJCWNhc2UgJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2NvbnRleHRfZG9tYWluJzoKCQkJCQkJbGlzdCggJG9yaWdpbmFsLCAkcGx1cmFsLCAkbnVtYmVyLCAkY29udGV4dCwgJGRvbWFpbiApID0gYXJyYXlfcGFkKCAkYXJncywgNSwgbnVsbCApOwoJCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoICcnID09PSAoc3RyaW5nKSAkb3JpZ2luYWwgKSB7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCWlmICggJGRvbWFpbiAhPT0gJHRyYW5zbGF0aW9ucy0+Z2V0RG9tYWluKCkgJiYgbnVsbCAhPT0gJHRyYW5zbGF0aW9ucy0+Z2V0RG9tYWluKCkgKSB7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCWlmICggaXNzZXQoICRvcHRpb25zWydsaW5lJ10gKSApIHsKCQkJCQkkbGluZSA9ICRvcHRpb25zWydsaW5lJ107CgkJCQl9IGVsc2UgewoJCQkJCSRsaW5lID0gJG5vZGUtPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCktPmdldExpbmUoKTsKCQkJCX0KCgkJCQkkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb25zLT5pbnNlcnQoICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwgKTsKCQkJCSR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCAkZmlsZSwgJGxpbmUgKTsKCgkJCQkvKiogQHZhciBOb2RlXENvbW1lbnQgJGNvbW1lbnQgKi8KCQkJCWZvcmVhY2ggKCAkYWxsX2NvbW1lbnRzIGFzICRjb21tZW50ICkgewoJCQkJCS8vIENvbW1lbnRzIHNob3VsZCBiZSBiZWZvcmUgdGhlIHRyYW5zbGF0aW9uLgoJCQkJCWlmICggISAkdGhpcy0+Y29tbWVudFByZWNlZGVzTm9kZSggJGNvbW1lbnQsICRub2RlICkgKSB7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCgkJCQkJJHBhcnNlZF9jb21tZW50ID0gUGFyc2VkQ29tbWVudDo6Y3JlYXRlKCAkY29tbWVudC0+Z2V0UmF3VGV4dCgpLCAkY29tbWVudC0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKS0+Z2V0TGluZSgpICk7CgkJCQkJJHByZWZpeGVzICAgICAgID0gYXJyYXlfZmlsdGVyKCAoYXJyYXkpICR0aGlzLT5leHRyYWN0X2NvbW1lbnRzICk7CgoJCQkJCWlmICggJHBhcnNlZF9jb21tZW50LT5jaGVja1ByZWZpeGVzKCAkcHJlZml4ZXMgKSApIHsKCQkJCQkJJHRyYW5zbGF0aW9uLT5hZGRFeHRyYWN0ZWRDb21tZW50KCAkcGFyc2VkX2NvbW1lbnQtPmdldENvbW1lbnQoKSApOwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoIGlzc2V0KCAkcGFyc2VkX2NvbW1lbnQgKSApIHsKCQkJCQkkYWxsX2NvbW1lbnRzID0gW107CgkJCQl9CgkJCX0KCQkpOwoKCQkvKioKCQkgKiBUcmF2ZXJzZSB0aHJvdWdoIEpTIGNvZGUgY29udGFpbmVkIHdpdGhpbiBldmFsKCkgdG8gZmluZCBhbmQgZXh0cmFjdCBnZXR0ZXh0IGZ1bmN0aW9ucy4KCQkgKi8KCQkkc2Nhbm5lciA9ICR0aGlzOwoJCSR0cmF2ZXJzZXItPmFkZEZ1bmN0aW9uKAoJCQlmdW5jdGlvbiAoICRub2RlICkgdXNlICggJiR0cmFuc2xhdGlvbnMsICRvcHRpb25zLCAkc2Nhbm5lciApIHsKCQkJCS8qKiBAdmFyIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgKi8KCQkJCWlmICggJ0NhbGxFeHByZXNzaW9uJyAhPT0gJG5vZGUtPmdldFR5cGUoKSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJJGNhbGxlZSA9ICR0aGlzLT5yZXNvbHZlRXhwcmVzc2lvbkNhbGxlZSggJG5vZGUgKTsKCgkJCQlpZiAoICEgJGNhbGxlZSB8fCAnZXZhbCcgIT09ICRjYWxsZWVbJ25hbWUnXSApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJJGV2YWxfY29udGVudHMgPSAnJzsKCQkJCS8qKiBAdmFyIE5vZGVcTm9kZSAkYXJndW1lbnQgKi8KCQkJCWZvcmVhY2ggKCAkbm9kZS0+Z2V0QXJndW1lbnRzKCkgYXMgJGFyZ3VtZW50ICkgewoJCQkJCWlmICggJ0xpdGVyYWwnID09PSAkYXJndW1lbnQtPmdldFR5cGUoKSApIHsKCQkJCQkJLyoqIEB2YXIgTm9kZVxMaXRlcmFsICRhcmd1bWVudCAqLwoJCQkJCQkkZXZhbF9jb250ZW50cyA9ICRhcmd1bWVudC0+Z2V0VmFsdWUoKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoKCQkJCWlmICggISAkZXZhbF9jb250ZW50cyApIHsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJLy8gT3ZlcnJpZGUgdGhlIGxpbmUgbG9jYXRpb24gdG8gYmUgdGhhdCBvZiB0aGUgZXZhbCgpLgoJCQkJJG9wdGlvbnNbJ2xpbmUnXSA9ICRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRMaW5lKCk7CgoJCQkJJGNsYXNzID0gZ2V0X2NsYXNzKCAkc2Nhbm5lciApOwoJCQkJJGV2YWxzID0gbmV3ICRjbGFzcyggJGV2YWxfY29udGVudHMgKTsKCQkJCSRldmFscy0+ZW5hYmxlQ29tbWVudHNFeHRyYWN0aW9uKCAkb3B0aW9uc1snZXh0cmFjdENvbW1lbnRzJ10gKTsKCQkJCSRldmFscy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoICR0cmFuc2xhdGlvbnMsICRvcHRpb25zICk7CgkJCX0KCQkpOwoKCQkkdHJhdmVyc2VyLT50cmF2ZXJzZSggJGFzdCApOwoJfQoKCS8qKgoJICogUmVzb2x2ZSB0aGUgY2FsbGVlIG9mIGEgY2FsbCBleHByZXNzaW9uIHVzaW5nIGtub3duIGZvcm1hdHMuCgkgKgoJICogQHBhcmFtIE5vZGVcQ2FsbEV4cHJlc3Npb24gJG5vZGUgVGhlIGNhbGwgZXhwcmVzc2lvbiB3aG9zZSBjYWxsZWUgdG8gcmVzb2x2ZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5fGJvb2wgQXJyYXkgY29udGFpbmluZyB0aGUgbmFtZSBhbmQgY29tbWVudHMgb2YgdGhlIGlkZW50aWZpZXIgaWYgcmVzb2x2ZWQuIEZhbHNlIGlmIG5vdC4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiByZXNvbHZlRXhwcmVzc2lvbkNhbGxlZSggTm9kZVxDYWxsRXhwcmVzc2lvbiAkbm9kZSApIHsKCQkkY2FsbGVlID0gJG5vZGUtPmdldENhbGxlZSgpOwoKCQkvLyBJZiB0aGUgY2FsbGVlIGlzIGEgc2ltcGxlIGlkZW50aWZpZXIgaXQgY2FuIHNpbXBseSBiZSByZXR1cm5lZC4KCQkvLyBGb3IgZXhhbXBsZTogX18oICJ0cmFuc2xhdGlvbiIgKS4KCQlpZiAoICdJZGVudGlmaWVyJyA9PT0gJGNhbGxlZS0+Z2V0VHlwZSgpICkgewoJCQlyZXR1cm4gWwoJCQkJJ25hbWUnICAgICA9PiAkY2FsbGVlLT5nZXROYW1lKCksCgkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldExlYWRpbmdDb21tZW50cygpLAoJCQldOwoJCX0KCgkJLy8gSWYgdGhlIGNhbGxlZSBpcyBhIG1lbWJlciBleHByZXNzaW9uIHJlc29sdmUgaXQgdG8gdGhlIHByb3BlcnR5LgoJCS8vIEZvciBleGFtcGxlOiB3cC5pMThuLl9fKCAidHJhbnNsYXRpb24iICkgb3IgdS5fXyggInRyYW5zbGF0aW9uIiApLgoJCWlmICgKCQkJJ01lbWJlckV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRUeXBlKCkgJiYKCQkJJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRQcm9wZXJ0eSgpLT5nZXRUeXBlKCkKCQkpIHsKCQkJLy8gTWFrZSBzdXJlIHRvIHVucGFjayB3cC5pMThuIHdoaWNoIGlzIGEgbmVzdGVkIE1lbWJlckV4cHJlc3Npb24uCgkJCSRjb21tZW50cyA9ICdNZW1iZXJFeHByZXNzaW9uJyA9PT0gJGNhbGxlZS0+Z2V0T2JqZWN0KCktPmdldFR5cGUoKQoJCQkJPyAkY2FsbGVlLT5nZXRPYmplY3QoKS0+Z2V0T2JqZWN0KCktPmdldExlYWRpbmdDb21tZW50cygpCgkJCQk6ICRjYWxsZWUtPmdldE9iamVjdCgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKTsKCgkJCXJldHVybiBbCgkJCQknbmFtZScgICAgID0+ICRjYWxsZWUtPmdldFByb3BlcnR5KCktPmdldE5hbWUoKSwKCQkJCSdjb21tZW50cycgPT4gJGNvbW1lbnRzLAoJCQldOwoJCX0KCgkJLy8gSWYgdGhlIGNhbGxlZSBpcyBhIGNhbGwgZXhwcmVzc2lvbiBhcyBjcmVhdGVkIGJ5IFdlYnBhY2sgcmVzb2x2ZSBpdC4KCQkvLyBGb3IgZXhhbXBsZTogT2JqZWN0KHUuX18pKCAidHJhbnNsYXRpb24iICkuCgkJaWYgKAoJCQknQ2FsbEV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRUeXBlKCkgJiYKCQkJJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRDYWxsZWUoKS0+Z2V0VHlwZSgpICYmCgkJCSdPYmplY3QnID09PSAkY2FsbGVlLT5nZXRDYWxsZWUoKS0+Z2V0TmFtZSgpICYmCgkJCVtdICE9PSAkY2FsbGVlLT5nZXRBcmd1bWVudHMoKSAmJgoJCQknTWVtYmVyRXhwcmVzc2lvbicgPT09ICRjYWxsZWUtPmdldEFyZ3VtZW50cygpWzBdLT5nZXRUeXBlKCkKCQkpIHsKCQkJJHByb3BlcnR5ID0gJGNhbGxlZS0+Z2V0QXJndW1lbnRzKClbMF0tPmdldFByb3BlcnR5KCk7CgoJCQkvLyBNYXRjaGVzIG1pbmlmaWVkIHdlYnBhY2sgc3RhdGVtZW50czogT2JqZWN0KHUuX18pKCAidHJhbnNsYXRpb24iICkuCgkJCWlmICggJ0lkZW50aWZpZXInID09PSAkcHJvcGVydHktPmdldFR5cGUoKSApIHsKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkcHJvcGVydHktPmdldE5hbWUoKSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldENhbGxlZSgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCV07CgkJCX0KCgkJCS8vIE1hdGNoZXMgdW5taW5pZmllZCB3ZWJwYWNrIHN0YXRlbWVudHM6CgkJCS8vIE9iamVjdChfd29yZHByZXNzX2kxOG5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzdfX1siX18iXSkoICJ0cmFuc2xhdGlvbiIgKTsKCQkJaWYgKCAnTGl0ZXJhbCcgPT09ICRwcm9wZXJ0eS0+Z2V0VHlwZSgpICkgewoJCQkJJG5hbWUgPSAkcHJvcGVydHktPmdldFZhbHVlKCk7CgoJCQkJLy8gTWF0Y2hlcyBtYW5nbGVkIHdlYnBhY2sgc3RhdGVtZW50OgoJCQkJLy8gT2JqZWN0KF93b3JkcHJlc3NfaTE4bl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfN19fWy8qIF9fICovICJhIl0pKCAidHJhbnNsYXRpb24iICk7CgkJCQkkbGVhZGluZ19wcm9wZXJ0eV9jb21tZW50cyA9ICRwcm9wZXJ0eS0+Z2V0TGVhZGluZ0NvbW1lbnRzKCk7CgkJCQlpZiAoIGNvdW50KCAkbGVhZGluZ19wcm9wZXJ0eV9jb21tZW50cyApID09PSAxICYmICRsZWFkaW5nX3Byb3BlcnR5X2NvbW1lbnRzWzBdLT5nZXRLaW5kKCkgPT09ICdtdWx0aWxpbmUnICkgewoJCQkJCSRuYW1lID0gdHJpbSggJGxlYWRpbmdfcHJvcGVydHlfY29tbWVudHNbMF0tPmdldFRleHQoKSApOwoJCQkJfQoKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkbmFtZSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldENhbGxlZSgpLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCV07CgkJCX0KCQl9CgoJCS8vIElmIHRoZSBjYWxsZWUgaXMgYW4gaW5kaXJlY3QgZnVuY3Rpb24gY2FsbCBhcyBjcmVhdGVkIGJ5IGJhYmVsLCByZXNvbHZlIGl0LgoJCS8vIEZvciBleGFtcGxlOiBgKDAsIHUuX18pKCAidHJhbnNsYXRpb24iIClgLgoJCWlmICgKCQkJJ1BhcmVudGhlc2l6ZWRFeHByZXNzaW9uJyA9PT0gJGNhbGxlZS0+Z2V0VHlwZSgpCgkJCSYmICdTZXF1ZW5jZUV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldFR5cGUoKQoJCQkmJiAyID09PSBjb3VudCggJGNhbGxlZS0+Z2V0RXhwcmVzc2lvbigpLT5nZXRFeHByZXNzaW9ucygpICkKCQkJJiYgJ0xpdGVyYWwnID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMF0tPmdldFR5cGUoKQoJCQkmJiBbXSAhPT0gJG5vZGUtPmdldEFyZ3VtZW50cygpCgkJKSB7CgkJCS8vIE1hdGNoZXMgYW55IGdlbmVyYWwgaW5kaXJlY3QgZnVuY3Rpb24gY2FsbDogYCgwLCBfXykoICJ0cmFuc2xhdGlvbiIgKWAuCgkJCWlmICggJ0lkZW50aWZpZXInID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldFR5cGUoKSApIHsKCQkJCXJldHVybiBbCgkJCQkJJ25hbWUnICAgICA9PiAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldE5hbWUoKSwKCQkJCQknY29tbWVudHMnID0+ICRjYWxsZWUtPmdldExlYWRpbmdDb21tZW50cygpLAoJCQkJXTsKCQkJfQoKCQkJLy8gTWF0Y2hlcyBpbmRpcmVjdCBmdW5jdGlvbiBjYWxscyB1c2VkIGJ5IGJhYmVsIGZvciBtb2R1bGUgaW1wb3J0czogYCgwLCBfaTE4bi5fXykoICJ0cmFuc2xhdGlvbiIgKWAuCgkJCWlmICggJ01lbWJlckV4cHJlc3Npb24nID09PSAkY2FsbGVlLT5nZXRFeHByZXNzaW9uKCktPmdldEV4cHJlc3Npb25zKClbMV0tPmdldFR5cGUoKSApIHsKCQkJCSRwcm9wZXJ0eSA9ICRjYWxsZWUtPmdldEV4cHJlc3Npb24oKS0+Z2V0RXhwcmVzc2lvbnMoKVsxXS0+Z2V0UHJvcGVydHkoKTsKCgkJCQlpZiAoICdJZGVudGlmaWVyJyA9PT0gJHByb3BlcnR5LT5nZXRUeXBlKCkgKSB7CgkJCQkJcmV0dXJuIFsKCQkJCQkJJ25hbWUnICAgICA9PiAkcHJvcGVydHktPmdldE5hbWUoKSwKCQkJCQkJJ2NvbW1lbnRzJyA9PiAkY2FsbGVlLT5nZXRMZWFkaW5nQ29tbWVudHMoKSwKCQkJCQldOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBVbmtub3duIGZvcm1hdC4KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHdldGhlciBvciBub3QgYSBjb21tZW50IHByZWNlZGVzIGEgbm9kZS4KCSAqIFRoZSBjb21tZW50IG11c3QgYmUgYmVmb3JlIHRoZSBub2RlIGFuZCBvbiB0aGUgc2FtZSBsaW5lIG9yIHRoZSBvbmUgYmVmb3JlLgoJICoKCSAqIEBwYXJhbSBOb2RlXENvbW1lbnQgJGNvbW1lbnQgVGhlIGNvbW1lbnQuCgkgKiBAcGFyYW0gTm9kZVxOb2RlICAgICRub2RlICAgIFRoZSBub2RlLgoJICoKCSAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIG9yIG5vdCB0aGUgY29tbWVudCBwcmVjZWRlcyB0aGUgbm9kZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjb21tZW50UHJlY2VkZXNOb2RlKCBOb2RlXENvbW1lbnQgJGNvbW1lbnQsIE5vZGVcTm9kZSAkbm9kZSApIHsKCQkvLyBDb21tZW50cyBzaG91bGQgYmUgb24gdGhlIHNhbWUgb3IgYW4gZWFybGllciBsaW5lIHRoYW4gdGhlIHRyYW5zbGF0aW9uLgoJCWlmICggJG5vZGUtPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCktPmdldExpbmUoKSAtICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0TGluZSgpID4gMSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gQ29tbWVudHMgb24gdGhlIHNhbWUgbGluZSBzaG91bGQgYmUgYmVmb3JlIHRoZSB0cmFuc2xhdGlvbi4KCQlpZiAoCgkJCSRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRMaW5lKCkgPT09ICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0TGluZSgpICYmCgkJCSRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRDb2x1bW4oKSA8ICRjb21tZW50LT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpLT5nZXRDb2x1bW4oKQoJCSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEdldHRleHRcR2VuZXJhdG9yc1xQbyBhcyBQb0dlbmVyYXRvcjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKLyoqCiAqIFBPVCBmaWxlIGdlbmVyYXRvci4KICoKICogVGhlIG9ubHkgZGlmZmVyZW5jZSB0byB0aGUgZXhpc3RpbmcgUE8gZmlsZSBnZW5lcmF0b3IgaXMgdGhhdCB0aGlzCiAqIGFkZHMgc29tZSBjb21tZW50cyBhdCB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUuCiAqLwpjbGFzcyBQb3RHZW5lcmF0b3IgZXh0ZW5kcyBQb0dlbmVyYXRvciB7Cglwcm90ZWN0ZWQgc3RhdGljICRjb21tZW50c19iZWZvcmVfaGVhZGVycyA9IFtdOwoKCS8qKgoJICogVGV4dCB0byBpbmNsdWRlIGFzIGEgY29tbWVudCBiZWZvcmUgdGhlIHN0YXJ0IG9mIHRoZSBQTyBjb250ZW50cwoJICoKCSAqIERvZXNuJ3QgbmVlZCB0byBpbmNsdWRlICMgaW4gdGhlIGJlZ2lubmluZyBvZiBsaW5lcywgdGhlc2UgYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29tbWVudCBGaWxlIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2V0Q29tbWVudEJlZm9yZUhlYWRlcnMoICRjb21tZW50ICkgewoJCSRjb21tZW50cyA9IGV4cGxvZGUoICJcbiIsICRjb21tZW50ICk7CgoJCWZvcmVhY2ggKCAkY29tbWVudHMgYXMgJGxpbmUgKSB7CgkJCWlmICggJycgIT09IHRyaW0oICRsaW5lICkgKSB7CgkJCQlzdGF0aWM6OiRjb21tZW50c19iZWZvcmVfaGVhZGVyc1tdID0gJyMgJyAuICRsaW5lOwoJCQl9CgkJfQoJfQoKCS8qKgoJICoge0BwYXJlbnREb2N9LgoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSApIHsKCQkkbGluZXMgICA9IHN0YXRpYzo6JGNvbW1lbnRzX2JlZm9yZV9oZWFkZXJzOwoJCSRsaW5lc1tdID0gJ21zZ2lkICIiJzsKCQkkbGluZXNbXSA9ICdtc2dzdHIgIiInOwoKCQkkcGx1cmFsX2Zvcm0gPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwoJCSRwbHVyYWxfc2l6ZSA9IGlzX2FycmF5KCAkcGx1cmFsX2Zvcm0gKSA/ICggJHBsdXJhbF9mb3JtWzBdIC0gMSApIDogMTsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUgKSB7CgkJCSRsaW5lc1tdID0gc3ByaW50ZiggJyIlczogJXNcXG4iJywgJG5hbWUsICR2YWx1ZSApOwoJCX0KCgkJJGxpbmVzW10gPSAnJzsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uICkgewoJCQkvKiogQHZhciBcR2V0dGV4dFxUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24gKi8KCQkJaWYgKCAkdHJhbnNsYXRpb24tPmhhc0NvbW1lbnRzKCkgKSB7CgkJCQlmb3JlYWNoICggJHRyYW5zbGF0aW9uLT5nZXRDb21tZW50cygpIGFzICRjb21tZW50ICkgewoJCQkJCSRsaW5lc1tdID0gJyMgJyAuICRjb21tZW50OwoJCQkJfQoJCQl9CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzRXh0cmFjdGVkQ29tbWVudHMoKSApIHsKCQkJCWZvcmVhY2ggKCAkdHJhbnNsYXRpb24tPmdldEV4dHJhY3RlZENvbW1lbnRzKCkgYXMgJGNvbW1lbnQgKSB7CgkJCQkJJGxpbmVzW10gPSAnIy4gJyAuICRjb21tZW50OwoJCQkJfQoJCQl9CgoJCQlmb3JlYWNoICggJHRyYW5zbGF0aW9uLT5nZXRSZWZlcmVuY2VzKCkgYXMgJHJlZmVyZW5jZSApIHsKCQkJCSRsaW5lc1tdID0gJyM6ICcgLiAkcmVmZXJlbmNlWzBdIC4gKCBudWxsICE9PSAkcmVmZXJlbmNlWzFdID8gJzonIC4gJHJlZmVyZW5jZVsxXSA6ICcnICk7CgkJCX0KCgkJCWlmICggJHRyYW5zbGF0aW9uLT5oYXNGbGFncygpICkgewoJCQkJJGxpbmVzW10gPSAnIywgJyAuIGltcGxvZGUoICcsJywgJHRyYW5zbGF0aW9uLT5nZXRGbGFncygpICk7CgkJCX0KCgkJCSRwcmVmaXggPSAkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSA/ICcjfiAnIDogJyc7CgoJCQlpZiAoICR0cmFuc2xhdGlvbi0+aGFzQ29udGV4dCgpICkgewoJCQkJJGxpbmVzW10gPSAkcHJlZml4IC4gJ21zZ2N0eHQgJyAuIHNlbGY6OmNvbnZlcnRTdHJpbmcoICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpICk7CgkJCX0KCgkJCXNlbGY6OmFkZExpbmVzKCAkbGluZXMsICRwcmVmaXggLiAnbXNnaWQnLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCkgKTsKCgkJCWlmICggJHRyYW5zbGF0aW9uLT5oYXNQbHVyYWwoKSApIHsKCQkJCXNlbGY6OmFkZExpbmVzKCAkbGluZXMsICRwcmVmaXggLiAnbXNnaWRfcGx1cmFsJywgJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWwoKSApOwoKCQkJCWZvciAoICRpID0gMDsgJGkgPD0gJHBsdXJhbF9zaXplOyAkaSArKyApIHsKCQkJCQlzZWxmOjphZGRMaW5lcyggJGxpbmVzLCAkcHJlZml4IC4gJ21zZ3N0clsnIC4gJGkgLiAnXScsICcnICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlzZWxmOjphZGRMaW5lcyggJGxpbmVzLCAkcHJlZml4IC4gJ21zZ3N0cicsICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSApOwoJCQl9CgoJCQkkbGluZXNbXSA9ICcnOwoJCX0KCgkJcmV0dXJuIGltcGxvZGUoICJcbiIsICRsaW5lcyApOwoJfQoKCS8qKgoJICogRXNjYXBlcyBhbmQgYWRkcyBkb3VibGUgcXVvdGVzIHRvIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZyBNdWx0aWxpbmUgc3RyaW5nLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nW10KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBtdWx0aWxpbmVRdW90ZSggJHN0cmluZyApIHsKCQkkbGluZXMgPSBleHBsb2RlKCAiXG4iLCAkc3RyaW5nICk7CgkJJGxhc3QgID0gY291bnQoICRsaW5lcyApIC0gMTsKCgkJZm9yZWFjaCAoICRsaW5lcyBhcyAkayA9PiAkbGluZSApIHsKCQkJaWYgKCAkayA9PT0gJGxhc3QgKSB7CgkJCQkkbGluZXNbICRrIF0gPSBzZWxmOjpjb252ZXJ0U3RyaW5nKCAkbGluZSApOwoJCQl9IGVsc2UgewoJCQkJJGxpbmVzWyAkayBdID0gc2VsZjo6Y29udmVydFN0cmluZyggJGxpbmUgLiAiXG4iICk7CgkJCX0KCQl9CgoJCXJldHVybiAkbGluZXM7Cgl9CgoJLyoqCgkgKiBBZGQgb25lIG9yIG1vcmUgbGluZXMgZGVwZW5kaW5nIHdoZXRoZXIgdGhlIHN0cmluZyBpcyBtdWx0aWxpbmUgb3Igbm90LgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJiRsaW5lcyBBcnJheSBsaW5lcyBzaG91bGQgYmUgYWRkZWQgdG8uCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgTmFtZSBvZiB0aGUgbGluZSwgZS5nLiBtc2dzdHIgb3IgbXNnaWRfcGx1cmFsLgoJICogQHBhcmFtIHN0cmluZyAkdmFsdWUgIFRoZSBsaW5lIHRvIGFkZC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBhZGRMaW5lcyggYXJyYXkgJiRsaW5lcywgJG5hbWUsICR2YWx1ZSApIHsKCQkkbmV3bGluZXMgPSBzZWxmOjptdWx0aWxpbmVRdW90ZSggJHZhbHVlICk7CgoJCWlmICggY291bnQoICRuZXdsaW5lcyApID09PSAxICkgewoJCQkkbGluZXNbXSA9ICRuYW1lIC4gJyAnIC4gJG5ld2xpbmVzWzBdOwoJCX0gZWxzZSB7CgkJCSRsaW5lc1tdID0gJG5hbWUgLiAnICIiJzsKCgkJCWZvcmVhY2ggKCAkbmV3bGluZXMgYXMgJGxpbmUgKSB7CgkJCQkkbGluZXNbXSA9ICRsaW5lOwoJCQl9CgkJfQoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJXEkxOG47Cgp1c2UgR2V0dGV4dFxFeHRyYWN0b3JzXEV4dHJhY3RvcjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xFeHRyYWN0b3JJbnRlcmZhY2U7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFdQX0NMSTsKCmZpbmFsIGNsYXNzIEJsb2NrRXh0cmFjdG9yIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlIHsKCXVzZSBJdGVyYWJsZUNvZGVFeHRyYWN0b3I7CgoJLyoqCgkgKiBAaW5oZXJpdGRvYwoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoICRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCSRmaWxlID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCQlXUF9DTEk6OmRlYnVnKCAiUGFyc2luZyBmaWxlIHskZmlsZX0iLCAnbWFrZS1wb3QnICk7CgoJCSRmaWxlX2RhdGEgPSBqc29uX2RlY29kZSggJHN0cmluZywgdHJ1ZSApOwoKCQlpZiAoIG51bGwgPT09ICRmaWxlX2RhdGEgKSB7CgkJCVdQX0NMSTo6ZGVidWcoCgkJCQlzcHJpbnRmKAoJCQkJCSdDb3VsZCBub3QgcGFyc2UgZmlsZSAlMSRzOiBlcnJvciBjb2RlICUyJHMnLAoJCQkJCSRmaWxlLAoJCQkJCWpzb25fbGFzdF9lcnJvcigpCgkJCQkpLAoJCQkJJ21ha2UtcG90JwoJCQkpOwoKCQkJcmV0dXJuOwoJCX0KCgkJJGRvbWFpbiA9IGlzc2V0KCAkZmlsZV9kYXRhWyd0ZXh0ZG9tYWluJ10gKSA/ICRmaWxlX2RhdGFbJ3RleHRkb21haW4nXSA6IG51bGw7CgoJCS8vIEFsbG93IG1pc3NpbmcgZG9tYWluLCBidXQgc2tpcCBpZiB0aGV5IGRvbid0IG1hdGNoLgoJCWlmICggbnVsbCAhPT0gJGRvbWFpbiAmJiAkZG9tYWluICE9PSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJZm9yZWFjaCAoICRmaWxlX2RhdGEgYXMgJGtleSA9PiAkb3JpZ2luYWwgKSB7CgkJCXN3aXRjaCAoICRrZXkgKSB7CgkJCQljYXNlICd0aXRsZSc6CgkJCQljYXNlICdkZXNjcmlwdGlvbic6CgkJCQkJJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCBzcHJpbnRmKCAnYmxvY2sgJXMnLCAka2V5ICksICRvcmlnaW5hbCApOwoJCQkJCSR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCAkZmlsZSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAna2V5d29yZHMnOgoJCQkJCWlmICggISBpc19hcnJheSggJG9yaWdpbmFsICkgKSB7CgkJCQkJCWNvbnRpbnVlIDI7CgkJCQkJfQoKCQkJCQlmb3JlYWNoICggJG9yaWdpbmFsIGFzICRtc2cgKSB7CgkJCQkJCSR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCggJ2Jsb2NrIGtleXdvcmQnLCAkbXNnICk7CgkJCQkJCSR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCAkZmlsZSApOwoJCQkJCX0KCgkJCQkJYnJlYWs7CgkJCQljYXNlICdzdHlsZXMnOgoJCQkJCWlmICggISBpc19hcnJheSggJG9yaWdpbmFsICkgKSB7CgkJCQkJCWNvbnRpbnVlIDI7CgkJCQkJfQoKCQkJCQlmb3JlYWNoICggJG9yaWdpbmFsIGFzICRtc2cgKSB7CgkJCQkJCSR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCggJ2Jsb2NrIHN0eWxlIGxhYmVsJywgJG1zZ1snbGFiZWwnXSApOwoJCQkJCQkkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSggJGZpbGUgKTsKCQkJCQl9CgkJCX0KCQl9Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcSTE4bjsKCnVzZSBHZXR0ZXh0XEV4dHJhY3RvcnNcUG8gYXMgUG9FeHRyYWN0b3I7CnVzZSBHZXR0ZXh0XEdlbmVyYXRvcnNcUG8gYXMgUG9HZW5lcmF0b3I7CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBXUF9DTEk7CnVzZSBXUF9DTElfQ29tbWFuZDsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIERpcmVjdG9yeUl0ZXJhdG9yOwp1c2UgSXRlcmF0b3JJdGVyYXRvcjsKdXNlIFNwbEZpbGVJbmZvOwoKY2xhc3MgTWFrZUpzb25Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoJLyoqCgkgKiBPcHRpb25zIHBhc3NlZCB0byBqc29uX2VuY29kZSgpLgoJICoKCSAqIEB2YXIgaW50IEpTT04gb3B0aW9ucy4KCSAqLwoJcHJvdGVjdGVkICRqc29uX29wdGlvbnMgPSAwOwoKCS8qKgoJICogRXh0cmFjdCBKYXZhU2NyaXB0IHN0cmluZ3MgZnJvbSBQTyBmaWxlcyBhbmQgYWRkIHRoZW0gdG8gaW5kaXZpZHVhbCBKU09OIGZpbGVzLgoJICoKCSAqIEZvciBKYXZhU2NyaXB0IGludGVybmF0aW9uYWxpemF0aW9uIHB1cnBvc2VzLCBXb3JkUHJlc3MgcmVxdWlyZXMgdHJhbnNsYXRpb25zIHRvIGJlIHNwbGl0IHVwIGludG8KCSAqIG9uZSBKZWQtZm9ybWF0dGVkIEpTT04gZmlsZSBwZXIgSmF2YVNjcmlwdCBzb3VyY2UgZmlsZS4KCSAqCgkgKiBTZWUgaHR0cHM6Ly9tYWtlLndvcmRwcmVzcy5vcmcvY29yZS8yMDE4LzExLzA5L25ldy1qYXZhc2NyaXB0LWkxOG4tc3VwcG9ydC1pbi13b3JkcHJlc3MvIHRvIGxlYXJuIG1vcmUKCSAqIGFib3V0IFdvcmRQcmVzcyBKYXZhU2NyaXB0IGludGVybmF0aW9uYWxpemF0aW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c291cmNlPgoJICogOiBQYXRoIHRvIGFuIGV4aXN0aW5nIFBPIGZpbGUgb3IgYSBkaXJlY3RvcnkgY29udGFpbmluZyBtdWx0aXBsZSBQTyBmaWxlcy4KCSAqCgkgKiBbPGRlc3RpbmF0aW9uPl0KCSAqIDogUGF0aCB0byB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IGZvciB0aGUgcmVzdWx0aW5nIEpTT04gZmlsZXMuIERlZmF1bHRzIHRvIHRoZSBzb3VyY2UgZGlyZWN0b3J5LgoJICoKCSAqIFstLXB1cmdlXQoJICogOiBXaGV0aGVyIHRvIHB1cmdlIHRoZSBzdHJpbmdzIHRoYXQgd2VyZSBleHRyYWN0ZWQgZnJvbSB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUuIERlZmF1bHRzIHRvIHRydWUsIHVzZSBgLS1uby1wdXJnZWAgdG8gc2tpcCB0aGUgcmVtb3ZhbC4KCSAqCgkgKiBbLS1wcmV0dHktcHJpbnRdCgkgKiA6IFByZXR0eS1wcmludCByZXN1bHRpbmcgSlNPTiBmaWxlcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyZWF0ZSBKU09OIGZpbGVzIGZvciBhbGwgUE8gZmlsZXMgaW4gdGhlIGxhbmd1YWdlcyBkaXJlY3RvcnkKCSAqICAgICAkIHdwIGkxOG4gbWFrZS1qc29uIGxhbmd1YWdlcwoJICoKCSAqICAgICAjIENyZWF0ZSBKU09OIGZpbGVzIGZvciBteS1wbHVnaW4tZGVfREUucG8gYW5kIGxlYXZlIHRoZSBQTyBmaWxlIHVudG91Y2hlZC4KCSAqICAgICAkIHdwIGkxOG4gbWFrZS1qc29uIG15LXBsdWdpbi1kZV9ERS5wbyAvdG1wIC0tbm8tcHVyZ2UKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICoKCSAqIEB0aHJvd3MgV1BfQ0xJXEV4aXRFeGNlcHRpb24KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHB1cmdlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncHVyZ2UnLCB0cnVlICk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncHJldHR5LXByaW50JywgZmFsc2UgKSApIHsKCQkJJHRoaXMtPmpzb25fb3B0aW9ucyB8PSBKU09OX1BSRVRUWV9QUklOVDsKCQl9CgoJCSRzb3VyY2UgPSByZWFscGF0aCggJGFyZ3NbMF0gKTsKCgkJaWYgKCAhICRzb3VyY2UgfHwgKCAhIGlzX2ZpbGUoICRzb3VyY2UgKSAmJiAhIGlzX2RpciggJHNvdXJjZSApICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdTb3VyY2UgZmlsZSBvciBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3QhJyApOwoJCX0KCgkJJGRlc3RpbmF0aW9uID0gaXNfZmlsZSggJHNvdXJjZSApID8gZGlybmFtZSggJHNvdXJjZSApIDogJHNvdXJjZTsKCgkJaWYgKCBpc3NldCggJGFyZ3NbMV0gKSApIHsKCQkJJGRlc3RpbmF0aW9uID0gJGFyZ3NbMV07CgkJfQoKCQkvLyBUd28gaXNfZGlyKCkgY2hlY2tzIGluIGNhc2Ugb2YgYSByYWNlIGNvbmRpdGlvbi4KCQlpZiAoICEgaXNfZGlyKCAkZGVzdGluYXRpb24gKQoJCQkmJiAhIG1rZGlyKCAkZGVzdGluYXRpb24sIDA3NzcsIHRydWUgKQoJCQkmJiAhIGlzX2RpciggJGRlc3RpbmF0aW9uICkKCQkpIHsKCQkJV1BfQ0xJOjplcnJvciggJ0NvdWxkIG5vdCBjcmVhdGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IScgKTsKCQl9CgoJCSRyZXN1bHRfY291bnQgPSAwOwoKCQlpZiAoIGlzX2ZpbGUoICRzb3VyY2UgKSApIHsKCQkJJGZpbGVzID0gWyBuZXcgU3BsRmlsZUluZm8oICRzb3VyY2UgKSBdOwoJCX0gZWxzZSB7CgkJCSRmaWxlcyA9IG5ldyBJdGVyYXRvckl0ZXJhdG9yKCBuZXcgRGlyZWN0b3J5SXRlcmF0b3IoICRzb3VyY2UgKSApOwoJCX0KCgkJLyoqIEB2YXIgRGlyZWN0b3J5SXRlcmF0b3IgJGZpbGUgKi8KCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQlpZiAoICRmaWxlLT5pc0ZpbGUoKSAmJiAkZmlsZS0+aXNSZWFkYWJsZSgpICYmICdwbycgPT09ICRmaWxlLT5nZXRFeHRlbnNpb24oKSApIHsKCQkJCSRyZXN1bHQgICAgICAgID0gJHRoaXMtPm1ha2VfanNvbiggJGZpbGUtPmdldFJlYWxQYXRoKCksICRkZXN0aW5hdGlvbiApOwoJCQkJJHJlc3VsdF9jb3VudCArPSBjb3VudCggJHJlc3VsdCApOwoKCQkJCWlmICggJHB1cmdlICkgewoJCQkJCSRyZW1vdmVkID0gJHRoaXMtPnJlbW92ZV9qc19zdHJpbmdzX2Zyb21fcG9fZmlsZSggJGZpbGUtPmdldFJlYWxQYXRoKCkgKTsKCgkJCQkJaWYgKCAhICRyZW1vdmVkICkgewoJCQkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdDb3VsZCBub3QgdXBkYXRlIGZpbGUgJXMnLCBiYXNlbmFtZSggJHNvdXJjZSApICkgKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCVdQX0NMSTo6c3VjY2Vzcyggc3ByaW50ZiggJ0NyZWF0ZWQgJWQgJXMuJywgJHJlc3VsdF9jb3VudCwgVXRpbHNccGx1cmFsaXplKCAnZmlsZScsICRyZXN1bHRfY291bnQgKSApICk7Cgl9CgoJLyoqCgkgKiBTcGxpdHMgYSBzaW5nbGUgUE8gZmlsZSBpbnRvIG11bHRpcGxlIEpTT04gZmlsZXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc291cmNlX2ZpbGUgUGF0aCB0byB0aGUgc291cmNlIGZpbGUuCgkgKiBAcGFyYW0gc3RyaW5nICRkZXN0aW5hdGlvbiBQYXRoIHRvIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuCgkgKiBAcmV0dXJuIGFycmF5IExpc3Qgb2YgY3JlYXRlZCBKU09OIGZpbGVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gbWFrZV9qc29uKCAkc291cmNlX2ZpbGUsICRkZXN0aW5hdGlvbiApIHsKCQkvKiogQHZhciBUcmFuc2xhdGlvbnNbXSAkbWFwcGluZyAqLwoJCSRtYXBwaW5nICAgICAgPSBbXTsKCQkkdHJhbnNsYXRpb25zID0gbmV3IFRyYW5zbGF0aW9ucygpOwoJCSRyZXN1bHQgICAgICAgPSBbXTsKCgkJUG9FeHRyYWN0b3I6OmZyb21GaWxlKCAkc291cmNlX2ZpbGUsICR0cmFuc2xhdGlvbnMgKTsKCgkJJGJhc2VfZmlsZV9uYW1lID0gYmFzZW5hbWUoICRzb3VyY2VfZmlsZSwgJy5wbycgKTsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMgYXMgJGluZGV4ID0+ICR0cmFuc2xhdGlvbiApIHsKCQkJLyoqIEB2YXIgVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uICovCgoJCQkvLyBGaW5kIGFsbCB1bmlxdWUgc291cmNlcyB0aGlzIHRyYW5zbGF0aW9uIG9yaWdpbmF0ZXMgZnJvbS4KCQkJJHNvdXJjZXMgPSBhcnJheV9tYXAoCgkJCQlmdW5jdGlvbiAoICRyZWZlcmVuY2UgKSB7CgkJCQkJJGZpbGUgPSAkcmVmZXJlbmNlWzBdOwoKCQkJCQlpZiAoIHN1YnN0ciggJGZpbGUsIC0gNyApID09PSAnLm1pbi5qcycgKSB7CgkJCQkJCXJldHVybiBzdWJzdHIoICRmaWxlLCAwLCAtIDcgKSAuICcuanMnOwoJCQkJCX0KCgkJCQkJaWYgKCBzdWJzdHIoICRmaWxlLCAtIDMgKSA9PT0gJy5qcycgKSB7CgkJCQkJCXJldHVybiAkZmlsZTsKCQkJCQl9CgoJCQkJCXJldHVybiBudWxsOwoJCQkJfSwKCQkJCSR0cmFuc2xhdGlvbi0+Z2V0UmVmZXJlbmNlcygpCgkJCSk7CgoJCQkkc291cmNlcyA9IGFycmF5X3VuaXF1ZSggYXJyYXlfZmlsdGVyKCAkc291cmNlcyApICk7CgoJCQlmb3JlYWNoICggJHNvdXJjZXMgYXMgJHNvdXJjZSApIHsKCQkJCWlmICggISBpc3NldCggJG1hcHBpbmdbICRzb3VyY2UgXSApICkgewoJCQkJCSRtYXBwaW5nWyAkc291cmNlIF0gPSBuZXcgVHJhbnNsYXRpb25zKCk7CgoJCQkJCS8vIHBocGNzOmlnbm9yZSBTcXVpei5QSFAuQ29tbWVudGVkT3V0Q29kZS5Gb3VuZCAtLSBQcm92aWRlIGNvZGUgdGhhdCBpcyBtZWFudCB0byBiZSB1c2VkIG9uY2UgdGhlIGJ1ZyBpcyBmaXhlZC4KCQkJCQkvLyBTZWUgaHR0cHM6Ly9jb3JlLnRyYWMud29yZHByZXNzLm9yZy90aWNrZXQvNDU0NDEKCQkJCQkvLyAkbWFwcGluZ1sgJHNvdXJjZSBdLT5zZXREb21haW4oICR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpICk7CgoJCQkJCSRtYXBwaW5nWyAkc291cmNlIF0tPnNldEhlYWRlciggJ0xhbmd1YWdlJywgJHRyYW5zbGF0aW9ucy0+Z2V0TGFuZ3VhZ2UoKSApOwoJCQkJCSRtYXBwaW5nWyAkc291cmNlIF0tPnNldEhlYWRlciggJ1BPLVJldmlzaW9uLURhdGUnLCAkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXIoICdQTy1SZXZpc2lvbi1EYXRlJyApICk7CgoJCQkJCSRwbHVyYWxfZm9ybXMgPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwoKCQkJCQlpZiAoICRwbHVyYWxfZm9ybXMgKSB7CgkJCQkJCWxpc3QoICRjb3VudCwgJHJ1bGUgKSA9ICRwbHVyYWxfZm9ybXM7CgkJCQkJCSRtYXBwaW5nWyAkc291cmNlIF0tPnNldFBsdXJhbEZvcm1zKCAkY291bnQsICRydWxlICk7CgkJCQkJfQoJCQkJfQoKCQkJCSRtYXBwaW5nWyAkc291cmNlIF1bXSA9ICR0cmFuc2xhdGlvbjsKCQkJfQoJCX0KCgkJJHJlc3VsdCArPSAkdGhpcy0+YnVpbGRfanNvbl9maWxlcyggJG1hcHBpbmcsICRiYXNlX2ZpbGVfbmFtZSwgJGRlc3RpbmF0aW9uICk7CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogQnVpbGRzIGEgbWFwcGluZyBvZiBKUyBmaWxlIG5hbWVzIHRvIHRyYW5zbGF0aW9uIGVudHJpZXMuCgkgKgoJICogRXhwb3J0cyB0cmFuc2xhdGlvbnMgZm9yIGVhY2ggSlMgZmlsZSB0byBhIHNlcGFyYXRlIHRyYW5zbGF0aW9uIGZpbGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkbWFwcGluZyAgICAgICAgQSBtYXBwaW5nIG9mIGZpbGVzIHRvIHRyYW5zbGF0aW9uIGVudHJpZXMuCgkgKiBAcGFyYW0gc3RyaW5nICRiYXNlX2ZpbGVfbmFtZSBCYXNlIGZpbGUgbmFtZSBmb3IgSlNPTiBmaWxlcy4KCSAqIEBwYXJhbSBzdHJpbmcgJGRlc3RpbmF0aW9uICAgIFBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IExpc3Qgb2YgY3JlYXRlZCBKU09OIGZpbGVzLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gYnVpbGRfanNvbl9maWxlcyggJG1hcHBpbmcsICRiYXNlX2ZpbGVfbmFtZSwgJGRlc3RpbmF0aW9uICkgewoJCSRyZXN1bHQgPSBbXTsKCgkJZm9yZWFjaCAoICRtYXBwaW5nIGFzICRmaWxlID0+ICR0cmFuc2xhdGlvbnMgKSB7CgkJCS8qKiBAdmFyIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zICovCgoJCQkkaGFzaCAgICAgICAgICAgICA9IG1kNSggJGZpbGUgKTsKCQkJJGRlc3RpbmF0aW9uX2ZpbGUgPSAiJHtkZXN0aW5hdGlvbn0veyRiYXNlX2ZpbGVfbmFtZX0teyRoYXNofS5qc29uIjsKCgkJCSRzdWNjZXNzID0gSmVkR2VuZXJhdG9yOjp0b0ZpbGUoCgkJCQkkdHJhbnNsYXRpb25zLAoJCQkJJGRlc3RpbmF0aW9uX2ZpbGUsCgkJCQlbCgkJCQkJJ2pzb24nICAgPT4gJHRoaXMtPmpzb25fb3B0aW9ucywKCQkJCQknc291cmNlJyA9PiAkZmlsZSwKCQkJCV0KCQkJKTsKCgkJCWlmICggISAkc3VjY2VzcyApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggJ0NvdWxkIG5vdCBjcmVhdGUgZmlsZSAlcycsIGJhc2VuYW1lKCAkZGVzdGluYXRpb25fZmlsZSwgJy5qc29uJyApICkgKTsKCgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJlc3VsdFtdID0gJGRlc3RpbmF0aW9uX2ZpbGU7CgkJfQoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIFJlbW92ZXMgc3RyaW5ncyBmcm9tIFBPIGZpbGUgdGhhdCBvbmx5IG9jY3VyIGluIEphdmFTY3JpcHQgZmlsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzb3VyY2VfZmlsZSBQYXRoIHRvIHRoZSBQTyBmaWxlLgoJICogQHJldHVybiBib29sIFRydWUgb24gc3VjY2VzcywgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gcmVtb3ZlX2pzX3N0cmluZ3NfZnJvbV9wb19maWxlKCAkc291cmNlX2ZpbGUgKSB7CgkJLyoqIEB2YXIgVHJhbnNsYXRpb25zW10gJG1hcHBpbmcgKi8KCQkkdHJhbnNsYXRpb25zID0gbmV3IFRyYW5zbGF0aW9ucygpOwoKCQlQb0V4dHJhY3Rvcjo6ZnJvbUZpbGUoICRzb3VyY2VfZmlsZSwgJHRyYW5zbGF0aW9ucyApOwoKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucy0+Z2V0QXJyYXlDb3B5KCkgYXMgJHRyYW5zbGF0aW9uICkgewoJCQkvKiogQHZhciBUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24gKi8KCgkJCWlmICggISAkdHJhbnNsYXRpb24tPmhhc1JlZmVyZW5jZXMoKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlmb3JlYWNoICggJHRyYW5zbGF0aW9uLT5nZXRSZWZlcmVuY2VzKCkgYXMgJHJlZmVyZW5jZSApIHsKCQkJCSRmaWxlID0gJHJlZmVyZW5jZVswXTsKCgkJCQlpZiAoIHN1YnN0ciggJGZpbGUsIC0gMyApICE9PSAnLmpzJyApIHsKCQkJCQljb250aW51ZSAyOwoJCQkJfQoJCQl9CgoJCQl1bnNldCggJHRyYW5zbGF0aW9uc1sgJHRyYW5zbGF0aW9uLT5nZXRJZCgpIF0gKTsKCQl9CgoJCXJldHVybiBQb0dlbmVyYXRvcjo6dG9GaWxlKCAkdHJhbnNsYXRpb25zLCAkc291cmNlX2ZpbGUgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSVxJMThuOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcRXh0cmFjdG9yc1xQaHBDb2RlOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBXUF9DTEk7CgpmaW5hbCBjbGFzcyBQaHBDb2RlRXh0cmFjdG9yIGV4dGVuZHMgUGhwQ29kZSB7Cgl1c2UgSXRlcmFibGVDb2RlRXh0cmFjdG9yOwoKCXB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCgkJJ2V4dHJhY3RDb21tZW50cycgPT4gWyAndHJhbnNsYXRvcnMnLCAnVHJhbnNsYXRvcnMnIF0sCgkJJ2NvbnN0YW50cycgICAgICAgPT4gW10sCgkJJ2Z1bmN0aW9ucycgICAgICAgPT4gWwoJCQknX18nICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2F0dHJfXycgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfXycgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX3htbF9fJyAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX2UnICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2F0dHJfZScgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfZScgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknZXNjX3htbF9lJyAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX3gnICAgICAgICAgICAgICA9PiAndGV4dF9jb250ZXh0X2RvbWFpbicsCgkJCSdfZXgnICAgICAgICAgICAgID0+ICd0ZXh0X2NvbnRleHRfZG9tYWluJywKCQkJJ2VzY19hdHRyX3gnICAgICAgPT4gJ3RleHRfY29udGV4dF9kb21haW4nLAoJCQknZXNjX2h0bWxfeCcgICAgICA9PiAndGV4dF9jb250ZXh0X2RvbWFpbicsCgkJCSdlc2NfeG1sX3gnICAgICAgID0+ICd0ZXh0X2NvbnRleHRfZG9tYWluJywKCQkJJ19uJyAgICAgICAgICAgICAgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbicsCgkJCSdfbngnICAgICAgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX251bWJlcl9jb250ZXh0X2RvbWFpbicsCgkJCSdfbl9ub29wJyAgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX2RvbWFpbicsCgkJCSdfbnhfbm9vcCcgICAgICAgID0+ICdzaW5nbGVfcGx1cmFsX2NvbnRleHRfZG9tYWluJywKCgkJCS8vIENvbXBhdC4KCQkJJ18nICAgICAgICAgICAgICAgPT4gJ2dldHRleHQnLCAvLyBTYW1lIGFzICd0ZXh0X2RvbWFpbicuCgoJCQkvLyBEZXByZWNhdGVkLgoJCQknX2MnICAgICAgICAgICAgICA9PiAndGV4dF9kb21haW4nLAoJCQknX25jJyAgICAgICAgICAgICA9PiAnc2luZ2xlX3BsdXJhbF9udW1iZXJfZG9tYWluJywKCQkJJ19fbmdldHRleHQnICAgICAgPT4gJ3NpbmdsZV9wbHVyYWxfbnVtYmVyX2RvbWFpbicsCgkJCSdfX25nZXR0ZXh0X25vb3AnID0+ICdzaW5nbGVfcGx1cmFsX2RvbWFpbicsCgkJXSwKCV07CgoJcHJvdGVjdGVkIHN0YXRpYyAkZnVuY3Rpb25zU2Nhbm5lckNsYXNzID0gJ1dQX0NMSVxJMThuXFBocEZ1bmN0aW9uc1NjYW5uZXInOwoKCS8qKgoJICoge0Bpbmhlcml0ZG9jfQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoICRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdICkgewoJCVdQX0NMSTo6ZGVidWcoICJQYXJzaW5nIGZpbGUgeyRvcHRpb25zWydmaWxlJ119IiwgJ21ha2UtcG90JyApOwoKCQl0cnkgewoJCQlzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZSggJHN0cmluZywgWyAkdHJhbnNsYXRpb25zIF0sICRvcHRpb25zICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmRlYnVnKAoJCQkJc3ByaW50ZigKCQkJCQknQ291bGQgbm90IHBhcnNlIGZpbGUgJTEkczogJTIkcycsCgkJCQkJJG9wdGlvbnNbJ2ZpbGUnXSwKCQkJCQkkZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCkKCQkJCSksCgkJCQknbWFrZS1wb3QnCgkJCSk7CgkJfQoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfcm9sZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9yb2xlX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfcm9sZV9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY2FwJywgJ0NhcGFiaWxpdGllc19Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAncm9sZScsICdSb2xlX0NvbW1hbmQnICk7Cjw/cGhwCgp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBBZGRzLCByZW1vdmVzLCBhbmQgbGlzdHMgY2FwYWJpbGl0aWVzIG9mIGEgdXNlciByb2xlLgogKgogKiBTZWUgcmVmZXJlbmNlcyBmb3IgW1JvbGVzIGFuZCBDYXBhYmlsaXRpZXNdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9Sb2xlc19hbmRfQ2FwYWJpbGl0aWVzKSBhbmQgW1dQIFVzZXIgY2xhc3NdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfVXNlcikuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEFkZCAnc3BlY3RhdGUnIGNhcGFiaWxpdHkgdG8gJ2F1dGhvcicgcm9sZS4KICogICAgICQgd3AgY2FwIGFkZCAnYXV0aG9yJyAnc3BlY3RhdGUnCiAqICAgICBTdWNjZXNzOiBBZGRlZCAxIGNhcGFiaWxpdHkgdG8gJ2F1dGhvcicgcm9sZS4KICoKICogICAgICMgQWRkIGFsbCBjYXBzIGZyb20gJ2VkaXRvcicgcm9sZSB0byAnYXV0aG9yJyByb2xlLgogKiAgICAgJCB3cCBjYXAgbGlzdCAnZWRpdG9yJyB8IHhhcmdzIHdwIGNhcCBhZGQgJ2F1dGhvcicKICogICAgIFN1Y2Nlc3M6IEFkZGVkIDI0IGNhcGFiaWxpdGllcyB0byAnYXV0aG9yJyByb2xlLgogKgogKiAgICAgIyBSZW1vdmUgYWxsIGNhcHMgZnJvbSAnZWRpdG9yJyByb2xlIHRoYXQgYWxzbyBhcHBlYXIgaW4gJ2F1dGhvcicgcm9sZS4KICogICAgICQgd3AgY2FwIGxpc3QgJ2F1dGhvcicgfCB4YXJncyB3cCBjYXAgcmVtb3ZlICdlZGl0b3InCiAqICAgICBTdWNjZXNzOiBSZW1vdmVkIDM0IGNhcGFiaWxpdGllcyBmcm9tICdlZGl0b3InIHJvbGUuCiAqLwpjbGFzcyBDYXBhYmlsaXRpZXNfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIExpc3Qgb2YgYXZhaWxhYmxlIGZpZWxkcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGZpZWxkcyA9IFsgJ25hbWUnIF07CgoJLyoqCgkgKiBMaXN0cyBjYXBhYmlsaXRpZXMgZm9yIGEgZ2l2ZW4gcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHJvbGU+CgkgKiA6IEtleSBmb3IgdGhlIHJvbGUuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGxpc3QKCSAqIG9wdGlvbnM6CgkgKiAgIC0gbGlzdAoJICogICAtIHRhYmxlCgkgKiAgIC0gY3N2CgkgKiAgIC0ganNvbgoJICogICAtIGNvdW50CgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tc2hvdy1ncmFudF0KCSAqIDogRGlzcGxheSBhbGwgY2FwYWJpbGl0aWVzIGRlZmluZWQgZm9yIGEgcm9sZSBpbmNsdWRpbmcgZ3JhbnQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGZhbHNlCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERpc3BsYXkgYWxwaGFiZXRpY2FsIGxpc3Qgb2YgQ29udHJpYnV0b3IgY2FwYWJpbGl0aWVzLgoJICogICAgICQgd3AgY2FwIGxpc3QgJ2NvbnRyaWJ1dG9yJyB8IHNvcnQKCSAqICAgICBkZWxldGVfcG9zdHMKCSAqICAgICBlZGl0X3Bvc3RzCgkgKiAgICAgbGV2ZWxfMAoJICogICAgIGxldmVsXzEKCSAqICAgICByZWFkCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcm9sZV9vYmogPSBzZWxmOjpnZXRfcm9sZSggJGFyZ3NbMF0gKTsKCgkJJHNob3dfZ3JhbnQgPSAhIGVtcHR5KCAkYXNzb2NfYXJnc1snc2hvdy1ncmFudCddICk7CgoJCWlmICggJHNob3dfZ3JhbnQgKSB7CgkJCWFycmF5X3B1c2goICR0aGlzLT5maWVsZHMsICdncmFudCcgKTsKCQkJJGNhcGFiaWxpdGllcyA9ICRyb2xlX29iai0+Y2FwYWJpbGl0aWVzOwoJCX0gZWxzZSB7CgkJCSRjYXBhYmlsaXRpZXMgPSBhcnJheV9maWx0ZXIoICRyb2xlX29iai0+Y2FwYWJpbGl0aWVzICk7CgkJfQoKCQkkb3V0cHV0X2NhcHMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkY2FwYWJpbGl0aWVzIGFzICRjYXAgPT4gJGdyYW50ICkgewoJCQkkb3V0cHV0X2NhcCA9IG5ldyBzdGRDbGFzcygpOwoKCQkJJG91dHB1dF9jYXAtPm5hbWUgID0gJGNhcDsKCQkJJG91dHB1dF9jYXAtPmdyYW50ID0gJGdyYW50ID8gJ3RydWUnIDogJ2ZhbHNlJzsKCgkJCSRvdXRwdXRfY2Fwc1tdID0gJG91dHB1dF9jYXA7CgkJfQoKCQlpZiAoICdsaXN0JyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQlmb3JlYWNoICggJG91dHB1dF9jYXBzIGFzICRjYXAgKSB7CgkJCQlpZiAoICRzaG93X2dyYW50ICkgewoJCQkJCVdQX0NMSTo6bGluZSggaW1wbG9kZSggJywnLCBhcnJheSggJGNhcC0+bmFtZSwgJGNhcC0+Z3JhbnQgKSApICk7CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6bGluZSggJGNhcC0+bmFtZSApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzICk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRvdXRwdXRfY2FwcyApOwoJCX0KCX0KCgkvKioKCSAqIEFkZHMgY2FwYWJpbGl0aWVzIHRvIGEgZ2l2ZW4gcm9sZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHJvbGU+CgkgKiA6IEtleSBmb3IgdGhlIHJvbGUuCgkgKgoJICogPGNhcD4uLi4KCSAqIDogT25lIG9yIG1vcmUgY2FwYWJpbGl0aWVzIHRvIGFkZC4KCSAqCgkgKiBbLS1ncmFudF0KCSAqIDogQWRkcyB0aGUgY2FwYWJpbGl0eSBhcyBhbiBleHBsaWNpdCBib29sZWFuIHZhbHVlLCBpbnN0ZWFkIG9mIGltcGxpY2l0bHkgZGVmYXVsdGluZyB0byBgdHJ1ZWAuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRydWUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdHJ1ZQoJICogICAtIGZhbHNlCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCAnc3BlY3RhdGUnIGNhcGFiaWxpdHkgdG8gJ2F1dGhvcicgcm9sZS4KCSAqICAgICAkIHdwIGNhcCBhZGQgYXV0aG9yIHNwZWN0YXRlCgkgKiAgICAgU3VjY2VzczogQWRkZWQgMSBjYXBhYmlsaXR5IHRvICdhdXRob3InIHJvbGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlzZWxmOjpwZXJzaXN0ZW5jZV9jaGVjaygpOwoKCQkkcm9sZSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQkkcm9sZV9vYmogPSBzZWxmOjpnZXRfcm9sZSggJHJvbGUgKTsKCgkJJGdyYW50ID0gISBpc3NldCggJGFzc29jX2FyZ3NbJ2dyYW50J10gKSB8fCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZ3JhbnQnXSApOwoKCQkkY291bnQgPSAwOwoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGNhcCApIHsKCQkJaWYgKCB0cnVlID09PSAkZ3JhbnQgJiYgJHJvbGVfb2JqLT5oYXNfY2FwKCAkY2FwICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJGdyYW50ICYmIGlzc2V0KCAkcm9sZV9vYmotPmNhcGFiaWxpdGllc1sgJGNhcCBdICkgJiYgZmFsc2UgPT09ICRyb2xlX29iai0+Y2FwYWJpbGl0aWVzWyAkY2FwIF0gKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJvbGVfb2JqLT5hZGRfY2FwKCAkY2FwLCAkZ3JhbnQgKTsKCgkJCSRjb3VudCsrOwoJCX0KCgkJJGNhcGFiaWxpdHkgICAgICAgICAgPSBXUF9DTElcVXRpbHNccGx1cmFsaXplKCAnY2FwYWJpbGl0eScsICRjb3VudCApOwoJCSRncmFudF9xdWFsaWZpY2F0aW9uID0gJGdyYW50ID8gJycgOiAnIGFzIGZhbHNlJzsKCgkJV1BfQ0xJOjpzdWNjZXNzKCAiQWRkZWQgeyRjb3VudH0geyRjYXBhYmlsaXR5fSB0byAneyRyb2xlfScgcm9sZXskZ3JhbnRfcXVhbGlmaWNhdGlvbn0uIiApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBjYXBhYmlsaXRpZXMgZnJvbSBhIGdpdmVuIHJvbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxyb2xlPgoJICogOiBLZXkgZm9yIHRoZSByb2xlLgoJICoKCSAqIDxjYXA+Li4uCgkgKiA6IE9uZSBvciBtb3JlIGNhcGFiaWxpdGllcyB0byByZW1vdmUuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZW1vdmUgJ3NwZWN0YXRlJyBjYXBhYmlsaXR5IGZyb20gJ2F1dGhvcicgcm9sZS4KCSAqICAgICAkIHdwIGNhcCByZW1vdmUgYXV0aG9yIHNwZWN0YXRlCgkgKiAgICAgU3VjY2VzczogUmVtb3ZlZCAxIGNhcGFiaWxpdHkgZnJvbSAnYXV0aG9yJyByb2xlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCAkYXJncyApIHsKCQlzZWxmOjpwZXJzaXN0ZW5jZV9jaGVjaygpOwoKCQkkcm9sZSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQkkcm9sZV9vYmogPSBzZWxmOjpnZXRfcm9sZSggJHJvbGUgKTsKCgkJJGNvdW50ID0gMDsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRjYXAgKSB7CgkJCWlmICggISBpc3NldCggJHJvbGVfb2JqLT5jYXBhYmlsaXRpZXNbICRjYXAgXSApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRyb2xlX29iai0+cmVtb3ZlX2NhcCggJGNhcCApOwoKCQkJJGNvdW50Kys7CgkJfQoKCQkkY2FwYWJpbGl0eSA9IFdQX0NMSVxVdGlsc1xwbHVyYWxpemUoICdjYXBhYmlsaXR5JywgJGNvdW50ICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggIlJlbW92ZWQgeyRjb3VudH0geyRjYXBhYmlsaXR5fSBmcm9tICd7JHJvbGV9JyByb2xlLiIgKTsKCX0KCgkvKioKCSAqIFJldHJpZXZlIGEgc3BlY2lmaWMgcm9sZSBmcm9tIHRoZSBzeXN0ZW0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcm9sZSBSb2xlIHRvIHJldHJpZXZlLgoJICogQHJldHVybiBXUF9Sb2xlIFJlcXVlc3RlZCByb2xlLgoJICogQHRocm93cyBcV1BfQ0xJXEV4aXRFeGNlcHRpb24gSWYgdGhlIHJvbGUgY291bGQgbm90IGJlIGZvdW5kLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfcm9sZSggJHJvbGUgKSB7CgkJZ2xvYmFsICR3cF9yb2xlczsKCgkJJHJvbGVfb2JqID0gJHdwX3JvbGVzLT5nZXRfcm9sZSggJHJvbGUgKTsKCgkJaWYgKCAhICRyb2xlX29iaiApIHsKCQkJV1BfQ0xJOjplcnJvciggIid7JHJvbGV9JyByb2xlIG5vdCBmb3VuZC4iICk7CgkJfQoKCQlyZXR1cm4gJHJvbGVfb2JqOwoJfQoKCS8qKgoJICogQXNzZXJ0IHRoYXQgdGhlIHJvbGVzIGFyZSBwZXJzaXN0ZWQgdG8gdGhlIGRhdGFiYXNlLgoJICoKCSAqIEB0aHJvd3MgXFdQX0NMSVxFeGl0RXhjZXB0aW9uIElmIHRoZSByb2xlcyBhcmUgbm90IHBlcnNpc3RlZCB0byB0aGUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFiYXNlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBwZXJzaXN0ZW5jZV9jaGVjaygpIHsKCQlnbG9iYWwgJHdwX3JvbGVzOwoKCQlpZiAoICEgJHdwX3JvbGVzLT51c2VfZGIgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSb2xlIGRlZmluaXRpb25zIGFyZSBub3QgcGVyc2lzdGVudC4nICk7CgkJfQoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEZvcm1hdHRlcjsKCi8qKgogKiBNYW5hZ2VzIHVzZXIgcm9sZXMsIGluY2x1ZGluZyBjcmVhdGluZyBuZXcgcm9sZXMgYW5kIHJlc2V0dGluZyB0byBkZWZhdWx0cy4KICoKICogU2VlIHJlZmVyZW5jZXMgZm9yIFtSb2xlcyBhbmQgQ2FwYWJpbGl0aWVzXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvUm9sZXNfYW5kX0NhcGFiaWxpdGllcykgYW5kIFtXUCBVc2VyIGNsYXNzXShodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvQ2xhc3NfUmVmZXJlbmNlL1dQX1VzZXIpLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IHJvbGVzLgogKiAgICAgJCB3cCByb2xlIGxpc3QgLS1maWVsZHM9cm9sZSAtLWZvcm1hdD1jc3YKICogICAgIHJvbGUKICogICAgIGFkbWluaXN0cmF0b3IKICogICAgIGVkaXRvcgogKiAgICAgYXV0aG9yCiAqICAgICBjb250cmlidXRvcgogKiAgICAgc3Vic2NyaWJlcgogKgogKiAgICAgIyBDaGVjayB0byBzZWUgaWYgYSByb2xlIGV4aXN0cy4KICogICAgICQgd3Agcm9sZSBleGlzdHMgZWRpdG9yCiAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGggSUQgJ2VkaXRvcicgZXhpc3RzLgogKgogKiAgICAgIyBDcmVhdGUgYSBuZXcgcm9sZS4KICogICAgICQgd3Agcm9sZSBjcmVhdGUgYXBwcm92ZXIgQXBwcm92ZXIKICogICAgIFN1Y2Nlc3M6IFJvbGUgd2l0aCBrZXkgJ2FwcHJvdmVyJyBjcmVhdGVkLgogKgogKiAgICAgIyBEZWxldGUgYW4gZXhpc3Rpbmcgcm9sZS4KICogICAgICQgd3Agcm9sZSBkZWxldGUgYXBwcm92ZXIKICogICAgIFN1Y2Nlc3M6IFJvbGUgd2l0aCBrZXkgJ2FwcHJvdmVyJyBkZWxldGVkLgogKgogKiAgICAgIyBSZXNldCBleGlzdGluZyByb2xlcyB0byB0aGVpciBkZWZhdWx0IGNhcGFiaWxpdGllcy4KICogICAgICQgd3Agcm9sZSByZXNldCBhZG1pbmlzdHJhdG9yIGF1dGhvciBjb250cmlidXRvcgogKiAgICAgU3VjY2VzczogUmVzZXQgMy8zIHJvbGVzLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFJvbGVfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIExpc3Qgb2YgYXZhaWxhYmxlIGZpZWxkcy4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGZpZWxkcyA9IFsgJ25hbWUnLCAncm9sZScgXTsKCgkvKioKCSAqIERlZmF1bHQgcm9sZXMgYXMgcHJvdmlkZWQgYnkgV29yZFByZXNzIENvcmUuCgkgKgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRyb2xlcyA9IFsgJ2FkbWluaXN0cmF0b3InLCAnZWRpdG9yJywgJ2F1dGhvcicsICdjb250cmlidXRvcicsICdzdWJzY3JpYmVyJyBdOwoKCS8qKgoJICogTGlzdHMgYWxsIHJvbGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCByb2xlOgoJICoKCSAqICogbmFtZQoJICogKiByb2xlCgkgKgoJICogVGhlcmUgYXJlIG5vIG9wdGlvbmFsIGZpZWxkcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3Qgcm9sZXMuCgkgKiAgICAgJCB3cCByb2xlIGxpc3QgLS1maWVsZHM9cm9sZSAtLWZvcm1hdD1jc3YKCSAqICAgICByb2xlCgkgKiAgICAgYWRtaW5pc3RyYXRvcgoJICogICAgIGVkaXRvcgoJICogICAgIGF1dGhvcgoJICogICAgIGNvbnRyaWJ1dG9yCgkgKiAgICAgc3Vic2NyaWJlcgoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cF9yb2xlczsKCgkJJG91dHB1dF9yb2xlcyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoICR3cF9yb2xlcy0+cm9sZXMgYXMgJGtleSA9PiAkcm9sZSApIHsKCQkJJG91dHB1dF9yb2xlID0gbmV3IHN0ZENsYXNzKCk7CgoJCQkkb3V0cHV0X3JvbGUtPm5hbWUgPSAkcm9sZVsnbmFtZSddOwoJCQkkb3V0cHV0X3JvbGUtPnJvbGUgPSAka2V5OwoKCQkJJG91dHB1dF9yb2xlc1tdID0gJG91dHB1dF9yb2xlOwoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJG91dHB1dF9yb2xlcyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgcm9sZSBleGlzdHMuCgkgKgoJICogRXhpdHMgd2l0aCByZXR1cm4gY29kZSAwIGlmIHRoZSByb2xlIGV4aXN0cywgMSBpZiBpdCBkb2VzIG5vdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHJvbGUta2V5PgoJICogOiBUaGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgcm9sZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIGlmIGEgcm9sZSBleGlzdHMuCgkgKiAgICAgJCB3cCByb2xlIGV4aXN0cyBlZGl0b3IKCSAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGggSUQgJ2VkaXRvcicgZXhpc3RzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZXhpc3RzKCAkYXJncyApIHsKCQlnbG9iYWwgJHdwX3JvbGVzOwoKCQlpZiAoICEgaW5fYXJyYXkoICRhcmdzWzBdLCBhcnJheV9rZXlzKCAkd3Bfcm9sZXMtPnJvbGVzICksIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlJvbGUgd2l0aCBJRCAneyRhcmdzWzBdfScgZG9lcyBub3QgZXhpc3QuIiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiUm9sZSB3aXRoIElEICd7JGFyZ3NbMF19JyBleGlzdHMuIiApOwoJfQoKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyByb2xlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cm9sZS1rZXk+CgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSByb2xlLgoJICoKCSAqIDxyb2xlLW5hbWU+CgkgKiA6IFRoZSBwdWJsaWNseSB2aXNpYmxlIG5hbWUgb2YgdGhlIHJvbGUuCgkgKgoJICogWy0tY2xvbmU9PHJvbGU+XQoJICogOiBDbG9uZSBjYXBhYmlsaXRpZXMgZnJvbSBhbiBleGlzdGluZyByb2xlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ3JlYXRlIHJvbGUgZm9yIEFwcHJvdmVyLgoJICogICAgICQgd3Agcm9sZSBjcmVhdGUgYXBwcm92ZXIgQXBwcm92ZXIKCSAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGgga2V5ICdhcHByb3ZlcicgY3JlYXRlZC4KCSAqCgkgKiAgICAgIyBDcmVhdGUgcm9sZSBmb3IgUHJvZHVjdCBBZG1pbmlzdHJhdG9yLgoJICogICAgICQgd3Agcm9sZSBjcmVhdGUgcHJvZHVjdGFkbWluICJQcm9kdWN0IEFkbWluaXN0cmF0b3IiCgkgKiAgICAgU3VjY2VzczogUm9sZSB3aXRoIGtleSAncHJvZHVjdGFkbWluJyBjcmVhdGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gY3JlYXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cF9yb2xlczsKCgkJc2VsZjo6cGVyc2lzdGVuY2VfY2hlY2soKTsKCgkJJHJvbGVfa2V5ICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSRyb2xlX25hbWUgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCgkJaWYgKCBlbXB0eSggJHJvbGVfa2V5ICkgfHwgZW1wdHkoICRyb2xlX25hbWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNhbid0IGNyZWF0ZSByb2xlLCBpbnN1ZmZpY2llbnQgaW5mb3JtYXRpb24gcHJvdmlkZWQuIiApOwoJCX0KCgkJJGNhcGFiaWxpdGllcyA9IGZhbHNlOwoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Nsb25lJ10gKSApIHsKCQkJJHJvbGVfb2JqID0gJHdwX3JvbGVzLT5nZXRfcm9sZSggJGFzc29jX2FyZ3NbJ2Nsb25lJ10gKTsKCQkJaWYgKCAhICRyb2xlX29iaiApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICIneyRhc3NvY19hcmdzWydjbG9uZSddfScgcm9sZSBub3QgZm91bmQuIiApOwoJCQl9CgkJCSRjYXBhYmlsaXRpZXMgPSBhcnJheV9rZXlzKCAkcm9sZV9vYmotPmNhcGFiaWxpdGllcyApOwoJCX0KCgkJaWYgKCBhZGRfcm9sZSggJHJvbGVfa2V5LCAkcm9sZV9uYW1lICkgKSB7CgkJCWlmICggISBlbXB0eSggJGNhcGFiaWxpdGllcyApICkgewoJCQkJJHJvbGVfb2JqID0gJHdwX3JvbGVzLT5nZXRfcm9sZSggJHJvbGVfa2V5ICk7CgkJCQlmb3JlYWNoICggJGNhcGFiaWxpdGllcyBhcyAkY2FwICkgewoJCQkJCSRyb2xlX29iai0+YWRkX2NhcCggJGNhcCApOwoJCQkJfQoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUm9sZSB3aXRoIGtleSAneyRyb2xlX2tleX0nIGNyZWF0ZWQuIENsb25lZCBjYXBhYmlsaXRpZXMgZnJvbSAneyRhc3NvY19hcmdzWydjbG9uZSddfScuIiApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAiUm9sZSB3aXRoIGtleSAneyRyb2xlX2tleX0nIGNyZWF0ZWQuIiApOwoJCQl9CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIlJvbGUgY291bGRuJ3QgYmUgY3JlYXRlZC4iICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhbiBleGlzdGluZyByb2xlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cm9sZS1rZXk+CgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSByb2xlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFwcHJvdmVyIHJvbGUuCgkgKiAgICAgJCB3cCByb2xlIGRlbGV0ZSBhcHByb3ZlcgoJICogICAgIFN1Y2Nlc3M6IFJvbGUgd2l0aCBrZXkgJ2FwcHJvdmVyJyBkZWxldGVkLgoJICoKCSAqICAgICAjIERlbGV0ZSBwcm9kdWN0YWRtaW4gcm9sZS4KCSAqICAgICB3cCByb2xlIGRlbGV0ZSBwcm9kdWN0YWRtaW4KCSAqICAgICBTdWNjZXNzOiBSb2xlIHdpdGgga2V5ICdwcm9kdWN0YWRtaW4nIGRlbGV0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzICkgewoJCWdsb2JhbCAkd3Bfcm9sZXM7CgoJCXNlbGY6OnBlcnNpc3RlbmNlX2NoZWNrKCk7CgoJCSRyb2xlX2tleSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQlpZiAoIGVtcHR5KCAkcm9sZV9rZXkgKSB8fCAhIGlzc2V0KCAkd3Bfcm9sZXMtPnJvbGVzWyAkcm9sZV9rZXkgXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUm9sZSBrZXkgbm90IHByb3ZpZGVkLCBvciBpcyBpbnZhbGlkLicgKTsKCQl9CgoJCXJlbW92ZV9yb2xlKCAkcm9sZV9rZXkgKTsKCgkJLy8gTm90ZTogcmVtb3ZlX3JvbGUoKSBkb2Vzbid0IGluZGljYXRlIHN1Y2Nlc3Mgb3Igb3RoZXJ3aXNlLCBzbyB3ZSBoYXZlIHRvCgkJLy8gY2hlY2sgb3Vyc2VsdmVzCgkJaWYgKCAhIGlzc2V0KCAkd3Bfcm9sZXMtPnJvbGVzWyAkcm9sZV9rZXkgXSApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJSb2xlIHdpdGgga2V5ICd7JHJvbGVfa2V5fScgZGVsZXRlZC4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIlJvbGUgd2l0aCBrZXkgJ3skcm9sZV9rZXl9JyBjb3VsZCBub3QgYmUgZGVsZXRlZC4iICk7CgkJfQoKCX0KCgkvKioKCSAqIFJlc2V0cyBhbnkgZGVmYXVsdCByb2xlIHRvIGRlZmF1bHQgY2FwYWJpbGl0aWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHJvbGUta2V5Pi4uLl0KCSAqIDogVGhlIGludGVybmFsIG5hbWUgb2Ygb25lIG9yIG1vcmUgcm9sZXMgdG8gcmVzZXQuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBkZWZhdWx0IHJvbGVzIHdpbGwgYmUgcmVzZXQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSZXNldCByb2xlLgoJICogICAgICQgd3Agcm9sZSByZXNldCBhZG1pbmlzdHJhdG9yIGF1dGhvciBjb250cmlidXRvcgoJICogICAgIFN1Y2Nlc3M6IFJlc2V0IDEvMyByb2xlcy4KCSAqCgkgKiAgICAgIyBSZXNldCBhbGwgZGVmYXVsdCByb2xlcy4KCSAqICAgICAkIHdwIHJvbGUgcmVzZXQgLS1hbGwKCSAqICAgICBTdWNjZXNzOiBBbGwgZGVmYXVsdCByb2xlcyByZXNldC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlc2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCXNlbGY6OnBlcnNpc3RlbmNlX2NoZWNrKCk7CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnICkgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdSb2xlIGtleSBub3QgcHJvdmlkZWQsIG9yIGlzIGludmFsaWQuJyApOwoJCX0KCgkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3BvcHVsYXRlX3JvbGVzJyApICkgewoJCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy9zY2hlbWEucGhwJzsKCQl9CgoJCWdsb2JhbCAkd3Bfcm9sZXM7CgkJJGFsbF9yb2xlcyAgICAgPSBhcnJheV9rZXlzKCAkd3Bfcm9sZXMtPnJvbGVzICk7CgkJJHByZXNlcnZlX2FyZ3MgPSAkYXJnczsKCgkJLy8gR2V0IG91ciBkZWZhdWx0IHJvbGVzLgoJCSRkZWZhdWx0X3JvbGVzID0gJHRoaXMtPnJvbGVzOwoJCSRwcmVzZXJ2ZSAgICAgID0gJHRoaXMtPnJvbGVzOwoJCSRiZWZvcmUgICAgICAgID0gW107CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQlmb3JlYWNoICggJGRlZmF1bHRfcm9sZXMgYXMgJHJvbGUgKSB7CgkJCQkkYmVmb3JlWyAkcm9sZSBdID0gZ2V0X3JvbGUoICRyb2xlICk7CgkJCQlyZW1vdmVfcm9sZSggJHJvbGUgKTsKCQkJCSRhcmdzW10gPSAkcm9sZTsKCQkJfQoJCQlwb3B1bGF0ZV9yb2xlcygpOwoJCQkkbm90X2FmZmVjdGVkX3JvbGVzID0gYXJyYXlfZGlmZiggJGFsbF9yb2xlcywgJGRlZmF1bHRfcm9sZXMgKTsKCQkJaWYgKCAhIGVtcHR5KCAkbm90X2FmZmVjdGVkX3JvbGVzICkgKSB7CgkJCQlmb3JlYWNoICggJG5vdF9hZmZlY3RlZF9yb2xlcyBhcyAkbm90X2FmZmVjdGVkX3JvbGUgKSB7CgkJCQkJV1BfQ0xJOjpsb2coICJDdXN0b20gcm9sZSAneyRub3RfYWZmZWN0ZWRfcm9sZX0nIG5vdCBhZmZlY3RlZC4iICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoKCQkJZm9yZWFjaCAoICRhcmdzIGFzICRrID0+ICRyb2xlX2tleSApIHsKCQkJCSRrZXkgPSBhcnJheV9zZWFyY2goICRyb2xlX2tleSwgJGRlZmF1bHRfcm9sZXMsIHRydWUgKTsKCQkJCWlmICggZmFsc2UgIT09ICRrZXkgKSB7CgkJCQkJdW5zZXQoICRwcmVzZXJ2ZVsgJGtleSBdICk7CgkJCQkJJGJlZm9yZVsgJHJvbGVfa2V5IF0gPSBnZXRfcm9sZSggJHJvbGVfa2V5ICk7CgkJCQkJcmVtb3ZlX3JvbGUoICRyb2xlX2tleSApOwoJCQkJfSBlbHNlIHsKCQkJCQl1bnNldCggJGFyZ3NbICRrIF0gKTsKCQkJCX0KCQkJfQoKCQkJJG5vdF9hZmZlY3RlZF9yb2xlcyA9IGFycmF5X2RpZmYoICRwcmVzZXJ2ZV9hcmdzLCAkZGVmYXVsdF9yb2xlcyApOwoJCQlpZiAoICEgZW1wdHkoICRub3RfYWZmZWN0ZWRfcm9sZXMgKSApIHsKCQkJCWZvcmVhY2ggKCAkbm90X2FmZmVjdGVkX3JvbGVzIGFzICRub3RfYWZmZWN0ZWRfcm9sZSApIHsKCQkJCQlXUF9DTEk6OmxvZyggIkN1c3RvbSByb2xlICd7JG5vdF9hZmZlY3RlZF9yb2xlfScgbm90IGFmZmVjdGVkLiIgKTsKCQkJCX0KCQkJfQoKCQkJLy8gTm8gcm9sZXMgd2VyZSB1bnNldCwgYmFpbC4KCQkJaWYgKCBjb3VudCggJGRlZmF1bHRfcm9sZXMgKSA9PT0gY291bnQoICRwcmVzZXJ2ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ011c3Qgc3BlY2lmeSBhIGRlZmF1bHQgcm9sZSB0byByZXNldC4nICk7CgkJCX0KCgkJCS8vIEZvciB0aGUgcm9sZXMgd2UncmUgbm90IHJlc2V0dGluZy4KCQkJZm9yZWFjaCAoICRwcmVzZXJ2ZSBhcyAkayA9PiAkcm9sZSApIHsKCQkJCS8qIHNhdmUgcm9sZXMKCQkJCSAqIGlmIGdldF9yb2xlIGlzIG51bGwKCQkJCSAqIHNhdmUgcm9sZSBuYW1lIGZvciByZS1yZW1vdmFsCgkJCQkgKi8KCQkJCSRyb2xlb2JqICAgICAgICA9IGdldF9yb2xlKCAkcm9sZSApOwoJCQkJJHByZXNlcnZlWyAkayBdID0gaXNfbnVsbCggJHJvbGVvYmogKSA/ICRyb2xlIDogJHJvbGVvYmo7CgoJCQkJcmVtb3ZlX3JvbGUoICRyb2xlICk7CgkJCX0KCgkJCS8vIFB1dCBiYWNrIGFsbCBkZWZhdWx0IHJvbGVzIGFuZCBjYXBhYmlsaXRpZXMuCgkJCXBvcHVsYXRlX3JvbGVzKCk7CgoJCQkvLyBSZXN0b3JlIHRoZSBwcmVzZXJ2ZWQgcm9sZXMuCgkJCWZvcmVhY2ggKCAkcHJlc2VydmUgYXMgJGsgPT4gJHJvbGVvYmogKSB7CgkJCQkvLyBSZS1yZW1vdmUgYWZ0ZXIgcG9wdWxhdGluZy4KCQkJCWlmICggaXNfYSggJHJvbGVvYmosICdXUF9Sb2xlJyApICkgewoJCQkJCXJlbW92ZV9yb2xlKCAkcm9sZW9iai0+bmFtZSApOwoJCQkJCWFkZF9yb2xlKCAkcm9sZW9iai0+bmFtZSwgdWN3b3JkcyggJHJvbGVvYmotPm5hbWUgKSwgJHJvbGVvYmotPmNhcGFiaWxpdGllcyApOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyBXaGVuIG5vdCBhbiBvYmplY3QsIHRoYXQgbWVhbnMgdGhlIHJvbGUgZGlkbid0IGV4aXN0IGJlZm9yZS4KCQkJCQlyZW1vdmVfcm9sZSggJHJvbGVvYmogKTsKCQkJCX0KCQkJfQoJCX0KCgkJJG51bV9yZXNldCAgICA9IDA7CgkJJGFyZ3MgICAgICAgICA9IGFycmF5X3VuaXF1ZSggJGFyZ3MgKTsKCQkkbnVtX3RvX3Jlc2V0ID0gY291bnQoICRhcmdzICk7CgkJZm9yZWFjaCAoICRhcmdzIGFzICRyb2xlX2tleSApIHsKCQkJJGFmdGVyWyAkcm9sZV9rZXkgXSA9IGdldF9yb2xlKCAkcm9sZV9rZXkgKTsKCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuUEhQLlN0cmljdENvbXBhcmlzb25zLkxvb3NlQ29tcGFyaXNvbiAtLSBPYmplY3QgaW5zdGFuY2VzIHdvbid0IGJlIHNhbWUsIHN0cmljdCBjaGVjayB3aWxsIGZhaWwgaGVyZS4KCQkJaWYgKCAkYWZ0ZXJbICRyb2xlX2tleSBdICE9ICRiZWZvcmVbICRyb2xlX2tleSBdICkgewoJCQkJKyskbnVtX3Jlc2V0OwoJCQkJJHJlc3RvcmVkX2NhcCAgICAgICA9IGFycmF5X2RpZmZfa2V5KCAkYWZ0ZXJbICRyb2xlX2tleSBdLT5jYXBhYmlsaXRpZXMsICRiZWZvcmVbICRyb2xlX2tleSBdLT5jYXBhYmlsaXRpZXMgKTsKCQkJCSRyZW1vdmVkX2NhcCAgICAgICAgPSBhcnJheV9kaWZmX2tleSggJGJlZm9yZVsgJHJvbGVfa2V5IF0tPmNhcGFiaWxpdGllcywgJGFmdGVyWyAkcm9sZV9rZXkgXS0+Y2FwYWJpbGl0aWVzICk7CgkJCQkkcmVzdG9yZWRfY2FwX2NvdW50ID0gY291bnQoICRyZXN0b3JlZF9jYXAgKTsKCQkJCSRyZW1vdmVkX2NhcF9jb3VudCAgPSBjb3VudCggJHJlbW92ZWRfY2FwICk7CgkJCQkkcmVzdG9yZWRfdGV4dCAgICAgID0gKCAxID09PSAkcmVzdG9yZWRfY2FwX2NvdW50ICkgPyAnJWQgY2FwYWJpbGl0eScgOiAnJWQgY2FwYWJpbGl0aWVzJzsKCQkJCSRyZW1vdmVkX3RleHQgICAgICAgPSAoIDEgPT09ICRyZW1vdmVkX2NhcF9jb3VudCApID8gJyVkIGNhcGFiaWxpdHknIDogJyVkIGNhcGFiaWxpdGllcyc7CgkJCQkkbWVzc2FnZSAgICAgICAgICAgID0gIlJlc3RvcmVkIHskcmVzdG9yZWRfdGV4dH0gdG8gYW5kIHJlbW92ZWQgeyRyZW1vdmVkX3RleHR9IGZyb20gJyVzJyByb2xlLiI7CgkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJG1lc3NhZ2UsICRyZXN0b3JlZF9jYXBfY291bnQsICRyZW1vdmVkX2NhcF9jb3VudCwgJHJvbGVfa2V5ICkgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAiTm8gY2hhbmdlcyBuZWNlc3NhcnkgZm9yICd7JHJvbGVfa2V5fScgcm9sZS4iICk7CgkJCX0KCQl9CgkJaWYgKCAkbnVtX3Jlc2V0ICkgewoJCQlpZiAoIDEgPT09IGNvdW50KCAkYXJncyApICkgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnUm9sZSByZXNldC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJ7JG51bV9yZXNldH0gb2YgeyRudW1fdG9fcmVzZXR9IHJvbGVzIHJlc2V0LiIgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICggMSA9PT0gY291bnQoICRhcmdzICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdSb2xlIGRpZG5cJ3QgbmVlZCByZXNldHRpbmcuJyApOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnTm8gcm9sZXMgbmVlZGVkIHJlc2V0dGluZy4nICk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBBc3NlcnQgdGhhdCB0aGUgcm9sZXMgYXJlIHBlcnNpc3RlZCB0byB0aGUgZGF0YWJhc2UuCgkgKgoJICogQHRocm93cyBcV1BfQ0xJXEV4aXRFeGNlcHRpb24gSWYgdGhlIHJvbGVzIGFyZSBub3QgcGVyc2lzdGVkIHRvIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YWJhc2UuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBlcnNpc3RlbmNlX2NoZWNrKCkgewoJCWdsb2JhbCAkd3Bfcm9sZXM7CgoJCWlmICggISAkd3Bfcm9sZXMtPnVzZV9kYiApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1JvbGUgZGVmaW5pdGlvbnMgYXJlIG5vdCBwZXJzaXN0ZW50LicgKTsKCQl9Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9yZXdyaXRlX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX3Jld3JpdGVfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9yZXdyaXRlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdyZXdyaXRlJywgJ1Jld3JpdGVfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogTGlzdHMgb3IgZmx1c2hlcyB0aGUgc2l0ZSdzIHJld3JpdGUgcnVsZXMsIHVwZGF0ZXMgdGhlIHBlcm1hbGluayBzdHJ1Y3R1cmUuCiAqCiAqIFNlZSB0aGUgV29yZFByZXNzIFtSZXdyaXRlIEFQSV0oaHR0cHM6Ly9jb2RleC53b3JkcHJlc3Mub3JnL1Jld3JpdGVfQVBJKSBhbmQKICogW1dQIFJld3JpdGVdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfUmV3cml0ZSkgY2xhc3MgcmVmZXJlbmNlLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBGbHVzaCByZXdyaXRlIHJ1bGVzCiAqICAgICAkIHdwIHJld3JpdGUgZmx1c2gKICogICAgIFN1Y2Nlc3M6IFJld3JpdGUgcnVsZXMgZmx1c2hlZC4KICoKICogICAgICMgVXBkYXRlIHBlcm1hbGluayBzdHJ1Y3R1cmUKICogICAgICQgd3AgcmV3cml0ZSBzdHJ1Y3R1cmUgJy8leWVhciUvJW1vbnRobnVtJS8lcG9zdG5hbWUlJwogKiAgICAgU3VjY2VzczogUmV3cml0ZSBzdHJ1Y3R1cmUgc2V0LgogKgogKiAgICAgIyBMaXN0IHJld3JpdGUgcnVsZXMKICogICAgICQgd3AgcmV3cml0ZSBsaXN0IC0tZm9ybWF0PWNzdgogKiAgICAgbWF0Y2gscXVlcnksc291cmNlCiAqICAgICBed3AtanNvbi8/JCxpbmRleC5waHA/cmVzdF9yb3V0ZT0vLG90aGVyCiAqICAgICBed3AtanNvbi8oLiopPyxpbmRleC5waHA/cmVzdF9yb3V0ZT0vJG1hdGNoZXNbMV0sb3RoZXIKICogICAgIGNhdGVnb3J5LyguKz8pL2ZlZWQvKGZlZWR8cmRmfHJzc3xyc3MyfGF0b20pLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmZlZWQ9JG1hdGNoZXNbMl0sY2F0ZWdvcnkKICogICAgIGNhdGVnb3J5LyguKz8pLyhmZWVkfHJkZnxyc3N8cnNzMnxhdG9tKS8/JCxpbmRleC5waHA/Y2F0ZWdvcnlfbmFtZT0kbWF0Y2hlc1sxXSZmZWVkPSRtYXRjaGVzWzJdLGNhdGVnb3J5CiAqICAgICBjYXRlZ29yeS8oLis/KS9lbWJlZC8/JCxpbmRleC5waHA/Y2F0ZWdvcnlfbmFtZT0kbWF0Y2hlc1sxXSZlbWJlZD10cnVlLGNhdGVnb3J5CiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KCmNsYXNzIFJld3JpdGVfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIEZsdXNoZXMgcmV3cml0ZSBydWxlcy4KCSAqCgkgKiBSZXNldHMgV29yZFByZXNzJyByZXdyaXRlIHJ1bGVzIGJhc2VkIG9uIHJlZ2lzdGVyZWQgcG9zdCB0eXBlcywgZXRjLgoJICoKCSAqIFRvIHJlZ2VuZXJhdGUgYSAuaHRhY2Nlc3MgZmlsZSB3aXRoIFdQLUNMSSwgeW91J2xsIG5lZWQgdG8gYWRkIHRoZSBtb2RfcmV3cml0ZSBtb2R1bGUKCSAqIHRvIHlvdXIgd3AtY2xpLnltbCBvciBjb25maWcueW1sLiBGb3IgZXhhbXBsZToKCSAqCgkgKiBgYGAKCSAqIGFwYWNoZV9tb2R1bGVzOgoJICogICAtIG1vZF9yZXdyaXRlCgkgKiBgYGAKCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0taGFyZF0KCSAqIDogUGVyZm9ybSBhIGhhcmQgZmx1c2ggLSB1cGRhdGUgYC5odGFjY2Vzc2AgcnVsZXMgYXMgd2VsbCBhcyByZXdyaXRlIHJ1bGVzIGluIGRhdGFiYXNlLiBXb3JrcyBvbmx5IG9uIHNpbmdsZSBzaXRlIGluc3RhbGxzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcmV3cml0ZSBmbHVzaAoJICogICAgIFN1Y2Nlc3M6IFJld3JpdGUgcnVsZXMgZmx1c2hlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZsdXNoKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLy8gbWFrZSBzdXJlIHdlIGRldGVjdCBtb2RfcmV3cml0ZSBpZiBjb25maWd1cmVkIGluIGFwYWNoZV9tb2R1bGVzIGluIGNvbmZpZwoJCXNlbGY6OmFwYWNoZV9tb2R1bGVzKCk7CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaGFyZCcgKSAmJiAhIGluX2FycmF5KCAnbW9kX3Jld3JpdGUnLCAoYXJyYXkpIFdQX0NMSTo6Z2V0X2NvbmZpZyggJ2FwYWNoZV9tb2R1bGVzJyApLCB0cnVlICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1JlZ2VuZXJhdGluZyBhIC5odGFjY2VzcyBmaWxlIHJlcXVpcmVzIHNwZWNpYWwgY29uZmlndXJhdGlvbi4gU2VlIHVzYWdlIGRvY3MuJyApOwoJCX0KCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoYXJkJyApICYmIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJXb3JkUHJlc3MgY2FuJ3QgZ2VuZXJhdGUgLmh0YWNjZXNzIGZpbGUgZm9yIGEgbXVsdGlzaXRlIGluc3RhbGwuIiApOwoJCX0KCgkJc2VsZjo6Y2hlY2tfc2tpcF9wbHVnaW5zX3RoZW1lcygpOwoKCQlmbHVzaF9yZXdyaXRlX3J1bGVzKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdoYXJkJyApICk7CgoJCWlmICggISBnZXRfb3B0aW9uKCAncmV3cml0ZV9ydWxlcycgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiUmV3cml0ZSBydWxlcyBhcmUgZW1wdHksIHBvc3NpYmx5IGJlY2F1c2Ugb2YgYSBtaXNzaW5nIHBlcm1hbGlua19zdHJ1Y3R1cmUgb3B0aW9uLiBVc2UgJ3dwIHJld3JpdGUgbGlzdCcgdG8gdmVyaWZ5LCBvciAnd3AgcmV3cml0ZSBzdHJ1Y3R1cmUnIHRvIHVwZGF0ZSBwZXJtYWxpbmtfc3RydWN0dXJlLiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdSZXdyaXRlIHJ1bGVzIGZsdXNoZWQuJyApOwoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgdGhlIHBlcm1hbGluayBzdHJ1Y3R1cmUuCgkgKgoJICogU2V0cyB0aGUgcG9zdCBwZXJtYWxpbmsgc3RydWN0dXJlIHRvIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KCSAqCgkgKiBUbyByZWdlbmVyYXRlIGEgLmh0YWNjZXNzIGZpbGUgd2l0aCBXUC1DTEksIHlvdSdsbCBuZWVkIHRvIGFkZAoJICogdGhlIG1vZF9yZXdyaXRlIG1vZHVsZSB0byB5b3VyIFtXUC1DTEkgY29uZmlnXShodHRwczovL21ha2Uud29yZHByZXNzLm9yZy9jbGkvaGFuZGJvb2svY29uZmlnLyNjb25maWctZmlsZXMpLgoJICogRm9yIGV4YW1wbGU6CgkgKgoJICogYGBgCgkgKiBhcGFjaGVfbW9kdWxlczoKCSAqICAgLSBtb2RfcmV3cml0ZQoJICogYGBgCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwZXJtYXN0cnVjdD4KCSAqIDogVGhlIG5ldyBwZXJtYWxpbmsgc3RydWN0dXJlIHRvIGFwcGx5LgoJICoKCSAqIFstLWNhdGVnb3J5LWJhc2U9PGJhc2U+XQoJICogOiBTZXQgdGhlIGJhc2UgZm9yIGNhdGVnb3J5IHBlcm1hbGlua3MsIGkuZS4gJy9jYXRlZ29yeS8nLgoJICoKCSAqIFstLXRhZy1iYXNlPTxiYXNlPl0KCSAqIDogU2V0IHRoZSBiYXNlIGZvciB0YWcgcGVybWFsaW5rcywgaS5lLiAnL3RhZy8nLgoJICoKCSAqIFstLWhhcmRdCgkgKiA6IFBlcmZvcm0gYSBoYXJkIGZsdXNoIC0gdXBkYXRlIGAuaHRhY2Nlc3NgIHJ1bGVzIGFzIHdlbGwgYXMgcmV3cml0ZSBydWxlcyBpbiBkYXRhYmFzZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHJld3JpdGUgc3RydWN0dXJlICcvJXllYXIlLyVtb250aG51bSUvJXBvc3RuYW1lJS8nCgkgKiAgICAgU3VjY2VzczogUmV3cml0ZSBzdHJ1Y3R1cmUgc2V0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gc3RydWN0dXJlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cF9yZXdyaXRlOwoKCQkvLyBjb3B5cGFzdGEgZnJvbSAvd3AtYWRtaW4vb3B0aW9ucy1wZXJtYWxpbmsucGhwCgoJCSRibG9nX3ByZWZpeCA9ICcnOwoJCSRwcmVmaXggICAgICA9ICRibG9nX3ByZWZpeDsKCQlpZiAoIGlzX211bHRpc2l0ZSgpICYmICEgaXNfc3ViZG9tYWluX2luc3RhbGwoKSAmJiBpc19tYWluX3NpdGUoKSApIHsKCQkJJGJsb2dfcHJlZml4ID0gJy9ibG9nJzsKCQl9CgoJCSRwZXJtYWxpbmtfc3RydWN0dXJlID0gKCAnZGVmYXVsdCcgPT09ICRhcmdzWzBdICkgPyAnJyA6ICRhcmdzWzBdOwoKCQlpZiAoICEgZW1wdHkoICRwZXJtYWxpbmtfc3RydWN0dXJlICkgKSB7CgkJCSRwZXJtYWxpbmtfc3RydWN0dXJlID0gcHJlZ19yZXBsYWNlKCAnIy8rIycsICcvJywgJy8nIC4gc3RyX3JlcGxhY2UoICcjJywgJycsICRwZXJtYWxpbmtfc3RydWN0dXJlICkgKTsKCQkJaWYgKCAkcHJlZml4ICYmICRibG9nX3ByZWZpeCApIHsKCQkJCSRwZXJtYWxpbmtfc3RydWN0dXJlID0gJHByZWZpeCAuIHByZWdfcmVwbGFjZSggJyNeLz9pbmRleFwucGhwIycsICcnLCAkcGVybWFsaW5rX3N0cnVjdHVyZSApOwoJCQl9IGVsc2UgewoJCQkJJHBlcm1hbGlua19zdHJ1Y3R1cmUgPSAkYmxvZ19wcmVmaXggLiAkcGVybWFsaW5rX3N0cnVjdHVyZTsKCQkJfQoJCX0KCQkkd3BfcmV3cml0ZS0+c2V0X3Blcm1hbGlua19zdHJ1Y3R1cmUoICRwZXJtYWxpbmtfc3RydWN0dXJlICk7CgoJCS8vIFVwZGF0ZSBjYXRlZ29yeSBvciB0YWcgYmFzZXMKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snY2F0ZWdvcnktYmFzZSddICkgKSB7CgoJCQkkY2F0ZWdvcnlfYmFzZSA9ICRhc3NvY19hcmdzWydjYXRlZ29yeS1iYXNlJ107CgkJCWlmICggISBlbXB0eSggJGNhdGVnb3J5X2Jhc2UgKSApIHsKCQkJCSRjYXRlZ29yeV9iYXNlID0gJGJsb2dfcHJlZml4IC4gcHJlZ19yZXBsYWNlKCAnIy8rIycsICcvJywgJy8nIC4gc3RyX3JlcGxhY2UoICcjJywgJycsICRjYXRlZ29yeV9iYXNlICkgKTsKCQkJfQoJCQkkd3BfcmV3cml0ZS0+c2V0X2NhdGVnb3J5X2Jhc2UoICRjYXRlZ29yeV9iYXNlICk7CgkJfQoKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sndGFnLWJhc2UnXSApICkgewoKCQkJJHRhZ19iYXNlID0gJGFzc29jX2FyZ3NbJ3RhZy1iYXNlJ107CgkJCWlmICggISBlbXB0eSggJHRhZ19iYXNlICkgKSB7CgkJCQkkdGFnX2Jhc2UgPSAkYmxvZ19wcmVmaXggLiBwcmVnX3JlcGxhY2UoICcjLysjJywgJy8nLCAnLycgLiBzdHJfcmVwbGFjZSggJyMnLCAnJywgJHRhZ19iYXNlICkgKTsKCQkJfQoJCQkkd3BfcmV3cml0ZS0+c2V0X3RhZ19iYXNlKCAkdGFnX2Jhc2UgKTsKCQl9CgoJCS8vIG1ha2Ugc3VyZSB3ZSBkZXRlY3QgbW9kX3Jld3JpdGUgaWYgY29uZmlndXJlZCBpbiBhcGFjaGVfbW9kdWxlcyBpbiBjb25maWcKCQlzZWxmOjphcGFjaGVfbW9kdWxlcygpOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdSZXdyaXRlIHN0cnVjdHVyZSBzZXQuJyApOwoKCQkvLyBMYXVuY2ggYSBuZXcgcHJvY2VzcyB0byBmbHVzaCByZXdyaXRlcyBiZWNhdXNlIGNvcmUgZXhwZWN0cyBmbHVzaAoJCS8vIHRvIGhhcHBlbiBhZnRlciByZXdyaXRlcyBhcmUgc2V0CgkJJG5ld19hc3NvY19hcmdzID0gW107CgkJJGNtZCAgICAgICAgICAgID0gJ3Jld3JpdGUgZmx1c2gnOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaGFyZCcgKSApIHsKCQkJJGNtZCAgICAgICAgICAgICAgICAgICAuPSAnIC0taGFyZCc7CgkJCSRuZXdfYXNzb2NfYXJnc1snaGFyZCddID0gdHJ1ZTsKCQkJaWYgKCAhIGluX2FycmF5KCAnbW9kX3Jld3JpdGUnLCAoYXJyYXkpIFdQX0NMSTo6Z2V0X2NvbmZpZyggJ2FwYWNoZV9tb2R1bGVzJyApLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICdSZWdlbmVyYXRpbmcgYSAuaHRhY2Nlc3MgZmlsZSByZXF1aXJlcyBzcGVjaWFsIGNvbmZpZ3VyYXRpb24uIFNlZSB1c2FnZSBkb2NzLicgKTsKCQkJfQoJCX0KCgkJJHByb2Nlc3NfcnVuID0gV1BfQ0xJOjpydW5jb21tYW5kKCAkY21kICk7CgkJaWYgKCAhIGVtcHR5KCAkcHJvY2Vzc19ydW4tPnN0ZGVyciApICkgewoJCQkvLyBTdHJpcCAiV2FybmluZzogIgoJCQlXUF9DTEk6Ondhcm5pbmcoIHN1YnN0ciggJHByb2Nlc3NfcnVuLT5zdGRlcnIsIDkgKSApOwoJCX0KCX0KCgkvKioKCSAqIEdldHMgYSBsaXN0IG9mIHRoZSBjdXJyZW50IHJld3JpdGUgcnVsZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLW1hdGNoPTx1cmw+XQoJICogOiBTaG93IHJld3JpdGUgcnVsZXMgbWF0Y2hpbmcgYSBwYXJ0aWN1bGFyIFVSTC4KCSAqCgkgKiBbLS1zb3VyY2U9PHNvdXJjZT5dCgkgKiA6IFNob3cgcmV3cml0ZSBydWxlcyBmcm9tIGEgcGFydGljdWxhciBzb3VyY2UuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gbWF0Y2gscXVlcnksc291cmNlLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgcmV3cml0ZSBsaXN0IC0tZm9ybWF0PWNzdgoJICogICAgIG1hdGNoLHF1ZXJ5LHNvdXJjZQoJICogICAgIF53cC1qc29uLz8kLGluZGV4LnBocD9yZXN0X3JvdXRlPS8sb3RoZXIKCSAqICAgICBed3AtanNvbi8oLiopPyxpbmRleC5waHA/cmVzdF9yb3V0ZT0vJG1hdGNoZXNbMV0sb3RoZXIKCSAqICAgICBjYXRlZ29yeS8oLis/KS9mZWVkLyhmZWVkfHJkZnxyc3N8cnNzMnxhdG9tKS8/JCxpbmRleC5waHA/Y2F0ZWdvcnlfbmFtZT0kbWF0Y2hlc1sxXSZmZWVkPSRtYXRjaGVzWzJdLGNhdGVnb3J5CgkgKiAgICAgY2F0ZWdvcnkvKC4rPykvKGZlZWR8cmRmfHJzc3xyc3MyfGF0b20pLz8kLGluZGV4LnBocD9jYXRlZ29yeV9uYW1lPSRtYXRjaGVzWzFdJmZlZWQ9JG1hdGNoZXNbMl0sY2F0ZWdvcnkKCSAqICAgICBjYXRlZ29yeS8oLis/KS9lbWJlZC8/JCxpbmRleC5waHA/Y2F0ZWdvcnlfbmFtZT0kbWF0Y2hlc1sxXSZlbWJlZD10cnVlLGNhdGVnb3J5CgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwX3Jld3JpdGU7CgoJCSRydWxlcyA9IGdldF9vcHRpb24oICdyZXdyaXRlX3J1bGVzJyApOwoJCWlmICggISAkcnVsZXMgKSB7CgkJCSRydWxlcyA9IFtdOwoJCQlXUF9DTEk6Ondhcm5pbmcoICdObyByZXdyaXRlIHJ1bGVzLicgKTsKCQl9CgoJCXNlbGY6OmNoZWNrX3NraXBfcGx1Z2luc190aGVtZXMoKTsKCgkJJGRlZmF1bHRzICAgPSBbCgkJCSdzb3VyY2UnID0+ICcnLAoJCQknbWF0Y2gnICA9PiAnJywKCQkJJ2Zvcm1hdCcgPT4gJ3RhYmxlJywKCQkJJ2ZpZWxkcycgPT4gJ21hdGNoLHF1ZXJ5LHNvdXJjZScsCgkJXTsKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZSAgICAgICAgICAgICA9IFtdOwoJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsncG9zdCddICAgICA9ICR3cF9yZXdyaXRlLT5nZW5lcmF0ZV9yZXdyaXRlX3J1bGVzKCAkd3BfcmV3cml0ZS0+cGVybWFsaW5rX3N0cnVjdHVyZSwgRVBfUEVSTUFMSU5LICk7CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydkYXRlJ10gICAgID0gJHdwX3Jld3JpdGUtPmdlbmVyYXRlX3Jld3JpdGVfcnVsZXMoICR3cF9yZXdyaXRlLT5nZXRfZGF0ZV9wZXJtYXN0cnVjdCgpLCBFUF9EQVRFICk7CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydyb290J10gICAgID0gJHdwX3Jld3JpdGUtPmdlbmVyYXRlX3Jld3JpdGVfcnVsZXMoICR3cF9yZXdyaXRlLT5yb290IC4gJy8nLCBFUF9ST09UICk7CgkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWydjb21tZW50cyddID0gJHdwX3Jld3JpdGUtPmdlbmVyYXRlX3Jld3JpdGVfcnVsZXMoICR3cF9yZXdyaXRlLT5yb290IC4gJHdwX3Jld3JpdGUtPmNvbW1lbnRzX2Jhc2UsIEVQX0NPTU1FTlRTLCB0cnVlLCB0cnVlLCB0cnVlLCBmYWxzZSApOwoJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsnc2VhcmNoJ10gICA9ICR3cF9yZXdyaXRlLT5nZW5lcmF0ZV9yZXdyaXRlX3J1bGVzKCAkd3BfcmV3cml0ZS0+Z2V0X3NlYXJjaF9wZXJtYXN0cnVjdCgpLCBFUF9TRUFSQ0ggKTsKCQkkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2VbJ2F1dGhvciddICAgPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHdwX3Jld3JpdGUtPmdldF9hdXRob3JfcGVybWFzdHJ1Y3QoKSwgRVBfQVVUSE9SUyApOwoJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsncGFnZSddICAgICA9ICR3cF9yZXdyaXRlLT5wYWdlX3Jld3JpdGVfcnVsZXMoKTsKCgkJLy8gRXh0cmEgcGVybWFzdHJ1Y3RzIGluY2x1ZGluZyB0YWdzLCBjYXRlZ29yaWVzLCBldGMuCgkJZm9yZWFjaCAoICR3cF9yZXdyaXRlLT5leHRyYV9wZXJtYXN0cnVjdHMgYXMgJHBlcm1hc3RydWN0bmFtZSA9PiAkcGVybWFzdHJ1Y3QgKSB7CgkJCWlmICggaXNfYXJyYXkoICRwZXJtYXN0cnVjdCApICkgewoJCQkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWyAkcGVybWFzdHJ1Y3RuYW1lIF0gPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHBlcm1hc3RydWN0WydzdHJ1Y3QnXSwgJHBlcm1hc3RydWN0WydlcF9tYXNrJ10sICRwZXJtYXN0cnVjdFsncGFnZWQnXSwgJHBlcm1hc3RydWN0WydmZWVkJ10sICRwZXJtYXN0cnVjdFsnZm9yY29tbWVudHMnXSwgJHBlcm1hc3RydWN0Wyd3YWxrX2RpcnMnXSwgJHBlcm1hc3RydWN0WydlbmRwb2ludHMnXSApOwoJCQl9IGVsc2UgewoJCQkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWyAkcGVybWFzdHJ1Y3RuYW1lIF0gPSAkd3BfcmV3cml0ZS0+Z2VuZXJhdGVfcmV3cml0ZV9ydWxlcyggJHBlcm1hc3RydWN0LCBFUF9OT05FICk7CgkJCX0KCQl9CgoJCS8vIEFwcGx5IHRoZSBmaWx0ZXJzIHVzZWQgaW4gY29yZSBqdXN0IGluIGNhc2UKCQlmb3JlYWNoICggJHJld3JpdGVfcnVsZXNfYnlfc291cmNlIGFzICRzb3VyY2UgPT4gJHNvdXJjZV9ydWxlcyApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLkR5bmFtaWNIb29rbmFtZUZvdW5kIC0tIENhbid0IHByZWZpeCBkeW5hbWljIGhvb2tzIGhlcmUsIGNhbGxpbmcgaG9va3MgZm9yIGN1c3RvbSBwZXJtYXN0cnVjdHMuCgkJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsgJHNvdXJjZSBdID0gYXBwbHlfZmlsdGVycyggJHNvdXJjZSAuICdfcmV3cml0ZV9ydWxlcycsICRzb3VyY2VfcnVsZXMgKTsKCQkJaWYgKCAncG9zdF90YWcnID09PSAkc291cmNlICkgewoJCQkJaWYgKCBVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoICczLjEuMCcsICc+PScgKSApIHsKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkJCSRyZXdyaXRlX3J1bGVzX2J5X3NvdXJjZVsgJHNvdXJjZSBdID0gYXBwbHlfZmlsdGVycyggJ3Bvc3RfdGFnX3Jld3JpdGVfcnVsZXMnLCAkc291cmNlX3J1bGVzICk7CgkJCQl9IGVsc2UgewoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gQ2FsbGluZyBuYXRpdmUgV29yZFByZXNzIGhvb2suCgkJCQkJJHJld3JpdGVfcnVsZXNfYnlfc291cmNlWyAkc291cmNlIF0gPSBhcHBseV9maWx0ZXJzKCAndGFnX3Jld3JpdGVfcnVsZXMnLCAkc291cmNlX3J1bGVzICk7CgkJCQl9CgkJCX0KCQl9CgoJCSRydWxlX2xpc3QgPSBbXTsKCQlmb3JlYWNoICggJHJ1bGVzIGFzICRtYXRjaCA9PiAkcXVlcnkgKSB7CgoJCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydtYXRjaCddICkgJiYgISBwcmVnX21hdGNoKCAiIV4kbWF0Y2ghIiwgdHJpbSggJGFzc29jX2FyZ3NbJ21hdGNoJ10sICcvJyApICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHNvdXJjZSA9ICdvdGhlcic7CgkJCWZvcmVhY2ggKCAkcmV3cml0ZV9ydWxlc19ieV9zb3VyY2UgYXMgJHJ1bGVzX3NvdXJjZSA9PiAkc291cmNlX3J1bGVzICkgewoJCQkJaWYgKCBhcnJheV9rZXlfZXhpc3RzKCAkbWF0Y2gsICRzb3VyY2VfcnVsZXMgKSApIHsKCQkJCQkkc291cmNlID0gJHJ1bGVzX3NvdXJjZTsKCQkJCX0KCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snc291cmNlJ10gKSAmJiAkc291cmNlICE9PSAkYXNzb2NfYXJnc1snc291cmNlJ10gKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHJ1bGVfbGlzdFtdID0gY29tcGFjdCggJ21hdGNoJywgJ3F1ZXJ5JywgJ3NvdXJjZScgKTsKCQl9CgoJCVV0aWxzXGZvcm1hdF9pdGVtcyggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCAkcnVsZV9saXN0LCBleHBsb2RlKCAnLCcsICRhc3NvY19hcmdzWydmaWVsZHMnXSApICk7Cgl9CgoJLyoqCgkgKiBFeHBvc2VzIGFwYWNoZSBtb2R1bGVzIGlmIHByZXNlbnQgaW4gY29uZmlnCgkgKgoJICogSW1wbGVtZW50YXRpb24gTm90ZXM6IFRoaXMgZnVuY3Rpb24gZXhwb3NlcyBhIGdsb2JhbCBmdW5jdGlvbgoJICogYXBhY2hlX2dldF9tb2R1bGVzIGFuZCBhbHNvIHNldHMgdGhlICRpc19hcGFjaGUgZ2xvYmFsIHZhcmlhYmxlLgoJICoKCSAqIFRoaXMgaXMgc28gdGhhdCBmbHVzaF9yZXdyaXRlX3J1bGVzIHdpbGwgYWN0dWFsbHkgd3JpdGUgb3V0IHRoZQoJICogLmh0YWNjZXNzIGZpbGUgZm9yIGFwYWNoZSBXb3JkUHJlc3MgaW5zdGFsbGF0aW9ucy4gVGhlcmUgaXMgYSBjaGVjawoJICogdG8gc2VlOgoJICoKCSAqIDEuIGlmIHRoZSAkaXNfYXBhY2hlIHZhcmlhYmxlIGlzIHNldC4KCSAqIDIuIGlmIHRoZSBtb2RfcmV3cml0ZSBtb2R1bGUgaXMgcmV0dXJuZWQgZnJvbSB0aGUgYXBhY2hlX2dldF9tb2R1bGVzCgkgKiAgICBmdW5jdGlvbi4KCSAqCgkgKiBUbyBnZXQgdGhpcyB0byB3b3JrIHdpdGggd3AtY2xpIHlvdSdsbCBuZWVkIHRvIGFkZCB0aGUgbW9kX3Jld3JpdGUgbW9kdWxlCgkgKiB0byB5b3VyIGNvbmZpZy55bWwuIEZvciBleGFtcGxlCgkgKgoJICogYGBgCgkgKiBhcGFjaGVfbW9kdWxlczoKCSAqICAgLSBtb2RfcmV3cml0ZQoJICogYGBgCgkgKgoJICogSWYgdGhpcyBpc24ndCBkb25lIHRoZW4gdGhlIC5odGFjY2VzcyByZXdyaXRlIHJ1bGVzIHdvbid0IGJlIGZsdXNoZWQgb3V0CgkgKiB0byBkaXNrLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBhcGFjaGVfbW9kdWxlcygpIHsKCQkkbW9kcyA9IFdQX0NMSTo6Z2V0X2NvbmZpZyggJ2FwYWNoZV9tb2R1bGVzJyApOwoJCWlmICggISBlbXB0eSggJG1vZHMgKSAmJiAhIGZ1bmN0aW9uX2V4aXN0cyggJ2FwYWNoZV9nZXRfbW9kdWxlcycgKSApIHsKCQkJZ2xvYmFsICRpc19hcGFjaGU7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZAoJCQkkaXNfYXBhY2hlID0gdHJ1ZTsKCgkJCS8vIG5lZWRlZCBmb3IgZ2V0X2hvbWVfcGF0aCgpIGFuZCAuaHRhY2Nlc3MgbG9jYXRpb24KCQkJJF9TRVJWRVJbJ1NDUklQVF9GSUxFTkFNRSddID0gQUJTUEFUSDsKCgkJCWZ1bmN0aW9uIGFwYWNoZV9nZXRfbW9kdWxlcygpIHsKCQkJCXJldHVybiBXUF9DTEk6OmdldF9jb25maWcoICdhcGFjaGVfbW9kdWxlcycgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIERpc3BsYXlzIGEgd2FybmluZyBpZiAtLXNraXAtcGx1Z2lucyBvciAtLXNraXAtdGhlbWVzIGFyZSBpbiB1c2UuCgkgKgoJICogU2tpcHBpbmcgdGhlIGxvYWRpbmcgb2YgcGx1Z2lucyBvciB0aGVtZXMgY2FuIG1lYW4gc29tZSByZXdyaXRlIHJ1bGVzCgkgKiBhcmUgdW5yZWdpc3RlcmVkLCB3aGljaCBtYXkgY2F1c2UgZXJyb25lb3VzIGJlaGF2aW9yLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjaGVja19za2lwX3BsdWdpbnNfdGhlbWVzKCkgewoJCSRza2lwcGVkID0gW107CgkJaWYgKCBXUF9DTEk6OmdldF9jb25maWcoICdza2lwLXBsdWdpbnMnICkgKSB7CgkJCSRza2lwcGVkW10gPSAncGx1Z2lucyc7CgkJfQoJCWlmICggV1BfQ0xJOjpnZXRfY29uZmlnKCAnc2tpcC10aGVtZXMnICkgKSB7CgkJCSRza2lwcGVkW10gPSAndGhlbWVzJzsKCQl9CgkJaWYgKCBlbXB0eSggJHNraXBwZWQgKSApIHsKCQkJcmV0dXJuOwoJCX0KCQkkc2tpcHBlZCA9IGltcGxvZGUoICcgYW5kICcsICRza2lwcGVkICk7CgkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiU29tZSByZXdyaXRlIHJ1bGVzIG1heSBiZSBtaXNzaW5nIGJlY2F1c2UgJXMgd2VyZW4ndCBsb2FkZWQuIiwgJHNraXBwZWQgKSApOwoJfQp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAncmV3cml0ZScsICdSZXdyaXRlX0NvbW1hbmQnICk7Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfc2NhZmZvbGRfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfc2NhZmZvbGRfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9zY2FmZm9sZF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2NhZmZvbGQnLCAnU2NhZmZvbGRfQ29tbWFuZCcgKTsKPD9waHAKLyoqCiAqIEZ1bmN0aW9ucyB0byByZWdpc3RlciBjbGllbnQtc2lkZSBhc3NldHMgKHNjcmlwdHMgYW5kIHN0eWxlc2hlZXRzKSBmb3IgdGhlCiAqIEd1dGVuYmVyZyBibG9jay4KICoKICogQHBhY2thZ2Uge3tuYW1lc3BhY2V9fQogKi8KCi8qKgogKiBSZWdpc3RlcnMgYWxsIGJsb2NrIGFzc2V0cyBzbyB0aGF0IHRoZXkgY2FuIGJlIGVucXVldWVkIHRocm91Z2ggR3V0ZW5iZXJnIGluCiAqIHRoZSBjb3JyZXNwb25kaW5nIGNvbnRleHQuCiAqCiAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL3R1dG9yaWFscy9ibG9jay10dXRvcmlhbC9hcHBseWluZy1zdHlsZXMtd2l0aC1zdHlsZXNoZWV0cy8KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1fYmxvY2tfaW5pdCgpIHsKCS8vIFNraXAgYmxvY2sgcmVnaXN0cmF0aW9uIGlmIEd1dGVuYmVyZyBpcyBub3QgZW5hYmxlZC9tZXJnZWQuCglpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAncmVnaXN0ZXJfYmxvY2tfdHlwZScgKSApIHsKCQlyZXR1cm47Cgl9Cgl7eyNwbHVnaW59fQoJJGRpciA9IGRpcm5hbWUoIF9fRklMRV9fICk7Cgl7ey9wbHVnaW59fQoJe3sjdGhlbWV9fQoJJGRpciA9IGdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpIC4gJy9ibG9ja3MnOwoJe3svdGhlbWV9fQoKCSRpbmRleF9qcyA9ICd7e3NsdWd9fS9pbmRleC5qcyc7Cgl3cF9yZWdpc3Rlcl9zY3JpcHQoCgkJJ3t7c2x1Z319LWJsb2NrLWVkaXRvcicsCgkJe3sjcGx1Z2lufX0KCQlwbHVnaW5zX3VybCggJGluZGV4X2pzLCBfX0ZJTEVfXyApLAoJCXt7L3BsdWdpbn19CgkJe3sjdGhlbWV9fQoJCWdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeV91cmkoKSAuICIvYmxvY2tzL3skaW5kZXhfanN9IiwKCQl7ey90aGVtZX19CgkJWwoJCQknd3AtYmxvY2tzJywKCQkJJ3dwLWkxOG4nLAoJCQknd3AtZWxlbWVudCcsCgkJXSwKCQlmaWxlbXRpbWUoICJ7JGRpcn0veyRpbmRleF9qc30iICkKCSk7CgoJJGVkaXRvcl9jc3MgPSAne3tzbHVnfX0vZWRpdG9yLmNzcyc7Cgl3cF9yZWdpc3Rlcl9zdHlsZSgKCQkne3tzbHVnfX0tYmxvY2stZWRpdG9yJywKCQl7eyNwbHVnaW59fQoJCXBsdWdpbnNfdXJsKCAkZWRpdG9yX2NzcywgX19GSUxFX18gKSwKCQl7ey9wbHVnaW59fQoJCXt7I3RoZW1lfX0KCQlnZXRfc3R5bGVzaGVldF9kaXJlY3RvcnlfdXJpKCkgLiAiL2Jsb2Nrcy97JGVkaXRvcl9jc3N9IiwKCQl7ey90aGVtZX19CgkJW10sCgkJZmlsZW10aW1lKCAieyRkaXJ9L3skZWRpdG9yX2Nzc30iICkKCSk7CgoJJHN0eWxlX2NzcyA9ICd7e3NsdWd9fS9zdHlsZS5jc3MnOwoJd3BfcmVnaXN0ZXJfc3R5bGUoCgkJJ3t7c2x1Z319LWJsb2NrJywKCQl7eyNwbHVnaW59fQoJCXBsdWdpbnNfdXJsKCAkc3R5bGVfY3NzLCBfX0ZJTEVfXyApLAoJCXt7L3BsdWdpbn19CgkJe3sjdGhlbWV9fQoJCWdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeV91cmkoKSAuICIvYmxvY2tzL3skc3R5bGVfY3NzfSIsCgkJe3svdGhlbWV9fQoJCVtdLAoJCWZpbGVtdGltZSggInskZGlyfS97JHN0eWxlX2Nzc30iICkKCSk7CgoJcmVnaXN0ZXJfYmxvY2tfdHlwZSggJ3t7bmFtZXNwYWNlfX0ve3tzbHVnfX0nLCBbCgkJJ2VkaXRvcl9zY3JpcHQnID0+ICd7e3NsdWd9fS1ibG9jay1lZGl0b3InLAoJCSdlZGl0b3Jfc3R5bGUnICA9PiAne3tzbHVnfX0tYmxvY2stZWRpdG9yJywKCQknc3R5bGUnICAgICAgICAgPT4gJ3t7c2x1Z319LWJsb2NrJywKCV0gKTsKfQoKYWRkX2FjdGlvbiggJ2luaXQnLCAne3ttYWNoaW5lX25hbWV9fV9ibG9ja19pbml0JyApOwo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxJbmZsZWN0b3I7CgovKioKICogR2VuZXJhdGVzIGNvZGUgZm9yIHBvc3QgdHlwZXMsIHRheG9ub21pZXMsIHBsdWdpbnMsIGNoaWxkIHRoZW1lcywgZXRjLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBHZW5lcmF0ZSBhIG5ldyBwbHVnaW4gd2l0aCB1bml0IHRlc3RzCiAqICAgICAkIHdwIHNjYWZmb2xkIHBsdWdpbiBzYW1wbGUtcGx1Z2luCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBsdWdpbiBmaWxlcy4KICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgdGVzdCBmaWxlcy4KICoKICogICAgICMgR2VuZXJhdGUgdGhlbWUgYmFzZWQgb24gX3MKICogICAgICQgd3Agc2NhZmZvbGQgX3Mgc2FtcGxlLXRoZW1lIC0tdGhlbWVfbmFtZT0iU2FtcGxlIFRoZW1lIiAtLWF1dGhvcj0iSm9obiBEb2UiCiAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHRoZW1lICdTYW1wbGUgVGhlbWUnLgogKgogKiAgICAgIyBHZW5lcmF0ZSBjb2RlIGZvciBwb3N0IHR5cGUgcmVnaXN0cmF0aW9uIGluIGdpdmVuIHRoZW1lCiAqICAgICAkIHdwIHNjYWZmb2xkIHBvc3QtdHlwZSBtb3ZpZSAtLWxhYmVsPU1vdmllIC0tdGhlbWU9c2ltcGxlLWxpZmUKICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgL3Zhci93d3cvZXhhbXBsZS5jb20vcHVibGljX2h0bWwvd3AtY29udGVudC90aGVtZXMvc2ltcGxlLWxpZmUvcG9zdC10eXBlcy9tb3ZpZS5waHAKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwpjbGFzcyBTY2FmZm9sZF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogR2VuZXJhdGVzIFBIUCBjb2RlIGZvciByZWdpc3RlcmluZyBhIGN1c3RvbSBwb3N0IHR5cGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzbHVnPgoJICogOiBUaGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgcG9zdCB0eXBlLgoJICoKCSAqIFstLWxhYmVsPTxsYWJlbD5dCgkgKiA6IFRoZSB0ZXh0IHVzZWQgdG8gdHJhbnNsYXRlIHRoZSB1cGRhdGUgbWVzc2FnZXMuCgkgKgoJICogWy0tdGV4dGRvbWFpbj08dGV4dGRvbWFpbj5dCgkgKiA6IFRoZSB0ZXh0ZG9tYWluIHRvIHVzZSBmb3IgdGhlIGxhYmVscy4KCSAqCgkgKiBbLS1kYXNoaWNvbj08ZGFzaGljb24+XQoJICogOiBUaGUgZGFzaGljb24gdG8gdXNlIGluIHRoZSBtZW51LgoJICoKCSAqIFstLXRoZW1lXQoJICogOiBDcmVhdGUgYSBmaWxlIGluIHRoZSBhY3RpdmUgdGhlbWUgZGlyZWN0b3J5LCBpbnN0ZWFkIG9mIHNlbmRpbmcgdG8KCSAqIFNURE9VVC4gU3BlY2lmeSBhIHRoZW1lIHdpdGggYC0tdGhlbWU9PHRoZW1lPmAgdG8gaGF2ZSB0aGUgZmlsZSBwbGFjZWQgaW4gdGhhdCB0aGVtZS4KCSAqCgkgKiBbLS1wbHVnaW49PHBsdWdpbj5dCgkgKiA6IENyZWF0ZSBhIGZpbGUgaW4gdGhlIGdpdmVuIHBsdWdpbidzIGRpcmVjdG9yeSwgaW5zdGVhZCBvZiBzZW5kaW5nIHRvIFNURE9VVC4KCSAqCgkgKiBbLS1yYXddCgkgKiA6IEp1c3QgZ2VuZXJhdGUgdGhlIGByZWdpc3Rlcl9wb3N0X3R5cGUoKWAgY2FsbCBhbmQgbm90aGluZyBlbHNlLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgYSAnbW92aWUnIHBvc3QgdHlwZSBmb3IgdGhlICdzaW1wbGUtbGlmZScgdGhlbWUKCSAqICAgICAkIHdwIHNjYWZmb2xkIHBvc3QtdHlwZSBtb3ZpZSAtLWxhYmVsPU1vdmllIC0tdGhlbWU9c2ltcGxlLWxpZmUKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkICcvdmFyL3d3dy9leGFtcGxlLmNvbS9wdWJsaWNfaHRtbC93cC1jb250ZW50L3RoZW1lcy9zaW1wbGUtbGlmZS9wb3N0LXR5cGVzL21vdmllLnBocCcuCgkgKgoJICogQHN1YmNvbW1hbmQgcG9zdC10eXBlCgkgKgoJICogQGFsaWFzICAgICAgY3B0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwb3N0X3R5cGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJaWYgKCBzdHJsZW4oICRhcmdzWzBdICkgPiAyMCApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1Bvc3QgdHlwZSBzbHVncyBjYW5ub3QgZXhjZWVkIDIwIGNoYXJhY3RlcnMgaW4gbGVuZ3RoLicgKTsKCQl9CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RleHRkb21haW4nID0+ICcnLAoJCQknZGFzaGljb24nICAgPT4gJ2FkbWluLXBvc3QnLAoJCV07CgoJCSR0ZW1wbGF0ZXMgPSBbCgkJCSdwb3N0X3R5cGUubXVzdGFjaGUnLAoJCQkncG9zdF90eXBlX2V4dGVuZGVkLm11c3RhY2hlJywKCQldOwoKCQkkdGhpcy0+c2NhZmZvbGQoICRhcmdzWzBdLCAkYXNzb2NfYXJncywgJGRlZmF1bHRzLCAnL3Bvc3QtdHlwZXMvJywgJHRlbXBsYXRlcyApOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIFBIUCBjb2RlIGZvciByZWdpc3RlcmluZyBhIGN1c3RvbSB0YXhvbm9teS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNsdWc+CgkgKiA6IFRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSB0YXhvbm9teS4KCSAqCgkgKiBbLS1wb3N0X3R5cGVzPTxwb3N0LXR5cGVzPl0KCSAqIDogUG9zdCB0eXBlcyB0byByZWdpc3RlciBmb3IgdXNlIHdpdGggdGhlIHRheG9ub215LgoJICoKCSAqIFstLWxhYmVsPTxsYWJlbD5dCgkgKiA6IFRoZSB0ZXh0IHVzZWQgdG8gdHJhbnNsYXRlIHRoZSB1cGRhdGUgbWVzc2FnZXMuCgkgKgoJICogWy0tdGV4dGRvbWFpbj08dGV4dGRvbWFpbj5dCgkgKiA6IFRoZSB0ZXh0ZG9tYWluIHRvIHVzZSBmb3IgdGhlIGxhYmVscy4KCSAqCgkgKiBbLS10aGVtZV0KCSAqIDogQ3JlYXRlIGEgZmlsZSBpbiB0aGUgYWN0aXZlIHRoZW1lIGRpcmVjdG9yeSwgaW5zdGVhZCBvZiBzZW5kaW5nIHRvCgkgKiBTVERPVVQuIFNwZWNpZnkgYSB0aGVtZSB3aXRoIGAtLXRoZW1lPTx0aGVtZT5gIHRvIGhhdmUgdGhlIGZpbGUgcGxhY2VkIGluIHRoYXQgdGhlbWUuCgkgKgoJICogWy0tcGx1Z2luPTxwbHVnaW4+XQoJICogOiBDcmVhdGUgYSBmaWxlIGluIHRoZSBnaXZlbiBwbHVnaW4ncyBkaXJlY3RvcnksIGluc3RlYWQgb2Ygc2VuZGluZyB0byBTVERPVVQuCgkgKgoJICogWy0tcmF3XQoJICogOiBKdXN0IGdlbmVyYXRlIHRoZSBgcmVnaXN0ZXJfdGF4b25vbXkoKWAgY2FsbCBhbmQgbm90aGluZyBlbHNlLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgUEhQIGNvZGUgZm9yIHJlZ2lzdGVyaW5nIGEgY3VzdG9tIHRheG9ub215IGFuZCBzYXZlIGluIGEgZmlsZQoJICogICAgICQgd3Agc2NhZmZvbGQgdGF4b25vbXkgdmVudWUgLS1wb3N0X3R5cGVzPWV2ZW50LHByZXNlbnRhdGlvbiA+IHRheG9ub215LnBocAoJICoKCSAqIEBzdWJjb21tYW5kIHRheG9ub215CgkgKgoJICogQGFsaWFzICAgICAgdGF4CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0YXhvbm9teSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RleHRkb21haW4nID0+ICcnLAoJCQkncG9zdF90eXBlcycgPT4gIidwb3N0JyIsCgkJXTsKCgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3Bvc3RfdHlwZXMnXSApICkgewoJCQkkYXNzb2NfYXJnc1sncG9zdF90eXBlcyddID0gJHRoaXMtPnF1b3RlX2NvbW1hX2xpc3RfZWxlbWVudHMoICRhc3NvY19hcmdzWydwb3N0X3R5cGVzJ10gKTsKCQl9CgoJCSR0ZW1wbGF0ZXMgPSBbCgkJCSd0YXhvbm9teS5tdXN0YWNoZScsCgkJCSd0YXhvbm9teV9leHRlbmRlZC5tdXN0YWNoZScsCgkJXTsKCgkJJHRoaXMtPnNjYWZmb2xkKCAkYXJnc1swXSwgJGFzc29jX2FyZ3MsICRkZWZhdWx0cywgJy90YXhvbm9taWVzLycsICR0ZW1wbGF0ZXMgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHNjYWZmb2xkKCAkc2x1ZywgJGFzc29jX2FyZ3MsICRkZWZhdWx0cywgJHN1YmRpciwgJHRlbXBsYXRlcyApIHsKCQkkd3BfZmlsZXN5c3RlbSA9ICR0aGlzLT5pbml0X3dwX2ZpbGVzeXN0ZW0oKTsKCgkJJGNvbnRyb2xfZGVmYXVsdHMgPSBbCgkJCSdsYWJlbCcgID0+IHByZWdfcmVwbGFjZSggJy9ffC0vJywgJyAnLCBzdHJ0b2xvd2VyKCAkc2x1ZyApICksCgkJCSd0aGVtZScgID0+IGZhbHNlLAoJCQkncGx1Z2luJyA9PiBmYWxzZSwKCQkJJ3JhdycgICAgPT4gZmFsc2UsCgkJXTsKCQkkY29udHJvbF9hcmdzICAgICA9ICR0aGlzLT5leHRyYWN0X2FyZ3MoICRhc3NvY19hcmdzLCAkY29udHJvbF9kZWZhdWx0cyApOwoKCQkkdmFycyA9ICR0aGlzLT5leHRyYWN0X2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJJGRhc2hpY29uID0gJHRoaXMtPmV4dHJhY3RfZGFzaGljb24oICRhc3NvY19hcmdzICk7CgkJaWYgKCAkZGFzaGljb24gKSB7CgkJCSR2YXJzWydkYXNoaWNvbiddID0gJGRhc2hpY29uOwoJCX0KCgkJJHZhcnNbJ3NsdWcnXSA9ICRzbHVnOwoKCQkkdmFyc1sndGV4dGRvbWFpbiddID0gJHRoaXMtPmdldF90ZXh0ZG9tYWluKCAkdmFyc1sndGV4dGRvbWFpbiddLCAkY29udHJvbF9hcmdzICk7CgoJCSR2YXJzWydsYWJlbCddID0gJGNvbnRyb2xfYXJnc1snbGFiZWwnXTsKCgkJJHZhcnNbJ2xhYmVsX3VjZmlyc3QnXSAgICAgICAgPSB1Y2ZpcnN0KCAkdmFyc1snbGFiZWwnXSApOwoJCSR2YXJzWydsYWJlbF9wbHVyYWwnXSAgICAgICAgID0gJHRoaXMtPnBsdXJhbGl6ZSggJHZhcnNbJ2xhYmVsJ10gKTsKCQkkdmFyc1snbGFiZWxfcGx1cmFsX3VjZmlyc3QnXSA9IHVjZmlyc3QoICR2YXJzWydsYWJlbF9wbHVyYWwnXSApOwoKCQkkbWFjaGluZV9uYW1lICAgICAgICA9ICR0aGlzLT5nZW5lcmF0ZV9tYWNoaW5lX25hbWUoICRzbHVnICk7CgkJJG1hY2hpbmVfbmFtZV9wbHVyYWwgPSAkdGhpcy0+cGx1cmFsaXplKCAkc2x1ZyApOwoKCQlsaXN0KCAkcmF3X3RlbXBsYXRlLCAkZXh0ZW5kZWRfdGVtcGxhdGUgKSA9ICR0ZW1wbGF0ZXM7CgoJCSRyYXdfb3V0cHV0ID0gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAkcmF3X3RlbXBsYXRlLCAkdmFycyApOwoKCQlpZiAoICEgJGNvbnRyb2xfYXJnc1sncmF3J10gKSB7CgkJCSR2YXJzWydtYWNoaW5lX25hbWUnXSA9ICRtYWNoaW5lX25hbWU7CgkJCSR2YXJzWydvdXRwdXQnXSAgICAgICA9ICRyYXdfb3V0cHV0OwoKCQkJJGZpbmFsX291dHB1dCA9IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJGV4dGVuZGVkX3RlbXBsYXRlLCAkdmFycyApOwoJCX0gZWxzZSB7CgkJCSRmaW5hbF9vdXRwdXQgPSAkcmF3X291dHB1dDsKCQl9CgoJCSRwYXRoID0gJHRoaXMtPmdldF9vdXRwdXRfcGF0aCggJGNvbnRyb2xfYXJncywgJHN1YmRpciApOwoJCWlmICggaXNfc3RyaW5nKCAkcGF0aCApICYmICEgZW1wdHkoICRwYXRoICkgKSB7CgkJCSRmaWxlbmFtZSA9ICJ7JHBhdGh9eyRzbHVnfS5waHAiOwoKCQkJJGZvcmNlICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApOwoJCQkkZmlsZXNfd3JpdHRlbiAgID0gJHRoaXMtPmNyZWF0ZV9maWxlcyggWyAkZmlsZW5hbWUgPT4gJGZpbmFsX291dHB1dCBdLCAkZm9yY2UgKTsKCQkJJHNraXBfbWVzc2FnZSAgICA9ICJTa2lwcGVkIGNyZWF0aW5nICd7JGZpbGVuYW1lfScuIjsKCQkJJHN1Y2Nlc3NfbWVzc2FnZSA9ICJDcmVhdGVkICd7JGZpbGVuYW1lfScuIjsKCQkJJHRoaXMtPmxvZ193aGV0aGVyX2ZpbGVzX3dyaXR0ZW4oICRmaWxlc193cml0dGVuLCAkc2tpcF9tZXNzYWdlLCAkc3VjY2Vzc19tZXNzYWdlICk7CgoJCX0gZWxzZSB7CgkJCS8vIFNURE9VVAoJCQllY2hvICRmaW5hbF9vdXRwdXQ7CgkJfQoJfQoKCS8qKgoJICogR2VuZXJhdGVzIFBIUCwgSlMgYW5kIENTUyBjb2RlIGZvciByZWdpc3RlcmluZyBhIEd1dGVuYmVyZyBibG9jayBmb3IgYSBwbHVnaW4gb3IgdGhlbWUuCgkgKgoJICogQmxvY2tzIGFyZSB0aGUgZnVuZGFtZW50YWwgZWxlbWVudCBvZiB0aGUgR3V0ZW5iZXJnIGVkaXRvci4gVGhleSBhcmUgdGhlIHByaW1hcnkgd2F5IGluIHdoaWNoIHBsdWdpbnMgYW5kIHRoZW1lcyBjYW4gcmVnaXN0ZXIgdGhlaXIgb3duIGZ1bmN0aW9uYWxpdHkgYW5kIGV4dGVuZCB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBlZGl0b3IuCgkgKgoJICogVmlzaXQgdGhlIFtHdXRlbmJlcmcgaGFuZGJvb2tdKGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svYmxvY2stYXBpLykgdG8gbGVhcm4gbW9yZSBhYm91dCBCbG9jayBBUEkuCgkgKgoJICogV2hlbiB5b3Ugc2NhZmZvbGQgYSBibG9jayB5b3UgbXVzdCB1c2UgZWl0aGVyIHRoZSB0aGVtZSBvciBwbHVnaW4gb3B0aW9uLiBUaGUgbGF0dGVyIGlzIHJlY29tbWVuZGVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2x1Zz4KCSAqIDogVGhlIGludGVybmFsIG5hbWUgb2YgdGhlIGJsb2NrLgoJICoKCSAqIFstLXRpdGxlPTx0aXRsZT5dCgkgKiA6IFRoZSBkaXNwbGF5IHRpdGxlIGZvciB5b3VyIGJsb2NrLgoJICoKCSAqIFstLWRhc2hpY29uPTxkYXNoaWNvbj5dCgkgKiA6IFRoZSBkYXNoaWNvbiB0byBtYWtlIGl0IGVhc2llciB0byBpZGVudGlmeSB5b3VyIGJsb2NrLgoJICoKCSAqIFstLWNhdGVnb3J5PTxjYXRlZ29yeT5dCgkgKiA6IFRoZSBjYXRlZ29yeSBuYW1lIHRvIGhlbHAgdXNlcnMgYnJvd3NlIGFuZCBkaXNjb3ZlciB5b3VyIGJsb2NrLgoJICogLS0tCgkgKiBkZWZhdWx0OiB3aWRnZXRzCgkgKiBvcHRpb25zOgoJICogICAtIGNvbW1vbgoJICogICAtIGVtYmVkCgkgKiAgIC0gZm9ybWF0dGluZwoJICogICAtIGxheW91dAoJICogICAtIHdpZGdldHMKCSAqIC0tLQoJICoKCSAqIFstLXRoZW1lXQoJICogOiBDcmVhdGUgZmlsZXMgaW4gdGhlIGFjdGl2ZSB0aGVtZSBkaXJlY3RvcnkuIFNwZWNpZnkgYSB0aGVtZSB3aXRoIGAtLXRoZW1lPTx0aGVtZT5gIHRvIGhhdmUgdGhlIGZpbGUgcGxhY2VkIGluIHRoYXQgdGhlbWUuCgkgKgoJICogWy0tcGx1Z2luPTxwbHVnaW4+XQoJICogOiBDcmVhdGUgZmlsZXMgaW4gdGhlIGdpdmVuIHBsdWdpbidzIGRpcmVjdG9yeS4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogT3ZlcndyaXRlIGZpbGVzIHRoYXQgYWxyZWFkeSBleGlzdC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdlbmVyYXRlIGEgJ21vdmllJyBibG9jayBmb3IgdGhlICdtb3ZpZXMnIHBsdWdpbgoJICogICAgICQgd3Agc2NhZmZvbGQgYmxvY2sgbW92aWUgLS10aXRsZT0iTW92aWUgYmxvY2siIC0tcGx1Z2luPW1vdmllcwoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgYmxvY2sgJ01vdmllIGJsb2NrJy4KCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBhICdtb3ZpZScgYmxvY2sgZm9yIHRoZSAnc2ltcGxlLWxpZmUnIHRoZW1lCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBibG9jayBtb3ZpZSAtLXRpdGxlPSJNb3ZpZSBibG9jayIgLS10aGVtZT1zaW1wbGUtbGlmZQoJICogICAgICBTdWNjZXNzOiBDcmVhdGVkIGJsb2NrICdNb3ZpZSBibG9jaycuCgkgKgoJICogICAgICMgQ3JlYXRlIGEgbmV3IHBsdWdpbiBhbmQgYWRkIHR3byBibG9ja3MKCSAqICAgICAjIENyZWF0ZSBwbHVnaW4gY2FsbGVkIGJvb2tzCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBwbHVnaW4gYm9va3MKCSAqICAgICAjIEFkZCBhIGJsb2NrIGNhbGxlZCBib29rIHRvIHBsdWdpbiBib29rcwoJICogICAgICQgd3Agc2NhZmZvbGQgYmxvY2sgYm9vayAtLXRpdGxlPSJCb29rIiAtLXBsdWdpbj1ib29rcwoJICogICAgICMgQWRkIGEgc2Vjb25kIGJsb2NrIHRvIHBsdWdpbiBjYWxsZWQgYm9va3MuCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBibG9jayBib29rcyAtLXRpdGxlPSJCb29rIExpc3QiIC0tcGx1Z2luPWJvb2tzCgkgKgoJICogQHN1YmNvbW1hbmQgYmxvY2sKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGJsb2NrKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRzbHVnID0gJGFyZ3NbMF07CgkJaWYgKCAhIHByZWdfbWF0Y2goICcvXlthLXpdW2EtejAtOVwtXSokLycsICRzbHVnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIGJsb2NrIHNsdWcgc3BlY2lmaWVkLiBCbG9jayBzbHVncyBjYW4gY29udGFpbiBvbmx5IGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciBkYXNoZXMsIGFuZCBzdGFydCB3aXRoIGEgbGV0dGVyLicgKTsKCQl9CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RpdGxlJyAgICA9PiBzdHJfcmVwbGFjZSggJy0nLCAnICcsICRzbHVnICksCgkJCSdjYXRlZ29yeScgPT4gJ3dpZGdldHMnLAoJCV07CgkJJGRhdGEgICAgID0gJHRoaXMtPmV4dHJhY3RfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQkkZGF0YVsnc2x1ZyddICAgICAgICAgICAgID0gJHNsdWc7CgkJJGRhdGFbJ3RpdGxlX3VjZmlyc3QnXSAgICA9IHVjZmlyc3QoICRkYXRhWyd0aXRsZSddICk7CgkJJGRhdGFbJ3RpdGxlX3VjZmlyc3RfanMnXSA9IGVzY19qcyggJGRhdGFbJ3RpdGxlX3VjZmlyc3QnXSApOwoKCQkkZGFzaGljb24gPSAkdGhpcy0+ZXh0cmFjdF9kYXNoaWNvbiggJGFzc29jX2FyZ3MgKTsKCQlpZiAoICRkYXNoaWNvbiApIHsKCQkJJGRhdGFbJ2Rhc2hpY29uJ10gPSAkZGFzaGljb247CgkJfQoKCQkkY29udHJvbF9kZWZhdWx0cyA9IFsKCQkJJ2ZvcmNlJyAgPT4gZmFsc2UsCgkJCSdwbHVnaW4nID0+IGZhbHNlLAoJCQkndGhlbWUnICA9PiBmYWxzZSwKCQldOwoJCSRjb250cm9sX2FyZ3MgICAgID0gJHRoaXMtPmV4dHJhY3RfYXJncyggJGFzc29jX2FyZ3MsICRjb250cm9sX2RlZmF1bHRzICk7CgoJCWlmICggaXNzZXQoICRjb250cm9sX2FyZ3NbJ3BsdWdpbiddICkgKSB7CgkJCWlmICggISBwcmVnX21hdGNoKCAnL15bQS1aYS16MC05XC1dKiQvJywgJGNvbnRyb2xfYXJnc1sncGx1Z2luJ10gKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIHBsdWdpbiBuYW1lIHNwZWNpZmllZC4gVGhlIGJsb2NrIGVkaXRvciBjYW4gb25seSByZWdpc3RlciBibG9ja3MgZm9yIHBsdWdpbnMgdGhhdCBoYXZlIG5vdGhpbmcgYnV0IGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciBkYXNoZXMgaW4gdGhlaXIgc2x1Zy4nICk7CgkJCX0KCQl9CgoJCSRkYXRhWyduYW1lc3BhY2UnXSAgICA9ICRjb250cm9sX2FyZ3NbJ3BsdWdpbiddID8gJGNvbnRyb2xfYXJnc1sncGx1Z2luJ10gOiAkdGhpcy0+Z2V0X3RoZW1lX25hbWUoICRjb250cm9sX2FyZ3NbJ3RoZW1lJ10gKTsKCQkkZGF0YVsnbWFjaGluZV9uYW1lJ10gPSAkdGhpcy0+Z2VuZXJhdGVfbWFjaGluZV9uYW1lKCAkc2x1ZyApOwoJCSRkYXRhWydwbHVnaW4nXSAgICAgICA9ICRjb250cm9sX2FyZ3NbJ3BsdWdpbiddID8gdHJ1ZSA6IGZhbHNlOwoJCSRkYXRhWyd0aGVtZSddICAgICAgICA9ICEgJGRhdGFbJ3BsdWdpbiddOwoKCQkkYmxvY2tfZGlyID0gJHRoaXMtPmdldF9vdXRwdXRfcGF0aCggJGNvbnRyb2xfYXJncywgJy9ibG9ja3MnICk7CgkJaWYgKCAhICRibG9ja19kaXIgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyBwbHVnaW4gb3IgdGhlbWUgc2VsZWN0ZWQuJyApOwoJCX0KCgkJJGZpbGVzX3RvX2NyZWF0ZSA9IFsKCQkJInskYmxvY2tfZGlyfS97JHNsdWd9LnBocCIgICAgICAgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ2Jsb2NrLXBocC5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JGJsb2NrX2Rpcn0veyRzbHVnfS9pbmRleC5qcyIgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdibG9jay1pbmRleC1qcy5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JGJsb2NrX2Rpcn0veyRzbHVnfS9lZGl0b3IuY3NzIiA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdibG9jay1lZGl0b3ItY3NzLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJInskYmxvY2tfZGlyfS97JHNsdWd9L3N0eWxlLmNzcyIgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ2Jsb2NrLXN0eWxlLWNzcy5tdXN0YWNoZScsICRkYXRhICksCgkJXTsKCQkkZmlsZXNfd3JpdHRlbiAgID0gJHRoaXMtPmNyZWF0ZV9maWxlcyggJGZpbGVzX3RvX2NyZWF0ZSwgJGNvbnRyb2xfYXJnc1snZm9yY2UnXSApOwoJCSRza2lwX21lc3NhZ2UgICAgPSAnQWxsIGJsb2NrIGZpbGVzIHdlcmUgc2tpcHBlZC4nOwoJCSRzdWNjZXNzX21lc3NhZ2UgPSAiQ3JlYXRlZCBibG9jayAneyRkYXRhWyd0aXRsZV91Y2ZpcnN0J119Jy4iOwoJCSR0aGlzLT5sb2dfd2hldGhlcl9maWxlc193cml0dGVuKCAkZmlsZXNfd3JpdHRlbiwgJHNraXBfbWVzc2FnZSwgJHN1Y2Nlc3NfbWVzc2FnZSApOwoJfQoKCS8qKgoJICogR2VuZXJhdGVzIHN0YXJ0ZXIgY29kZSBmb3IgYSB0aGVtZSBiYXNlZCBvbiBfcy4KCSAqCgkgKiBTZWUgdGhlIFtVbmRlcnNjb3JlcyB3ZWJzaXRlXShodHRwczovL3VuZGVyc2NvcmVzLm1lLykgZm9yIG1vcmUgZGV0YWlscy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHNsdWc+CgkgKiA6IFRoZSBzbHVnIGZvciB0aGUgbmV3IHRoZW1lLCB1c2VkIGZvciBwcmVmaXhpbmcgZnVuY3Rpb25zLgoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBBY3RpdmF0ZSB0aGUgbmV3bHkgZG93bmxvYWRlZCB0aGVtZS4KCSAqCgkgKiBbLS1lbmFibGUtbmV0d29ya10KCSAqIDogRW5hYmxlIHRoZSBuZXdseSBkb3dubG9hZGVkIHRoZW1lIGZvciB0aGUgZW50aXJlIG5ldHdvcmsuCgkgKgoJICogWy0tdGhlbWVfbmFtZT08dGl0bGU+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ1RoZW1lIE5hbWU6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tYXV0aG9yPTxmdWxsLW5hbWU+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvcjonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS1hdXRob3JfdXJpPTx1cmk+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvciBVUkk6JyBoZWFkZXIgaW4gJ3N0eWxlLmNzcycuCgkgKgoJICogWy0tc2Fzc2lmeV0KCSAqIDogSW5jbHVkZSBzdHlsZXNoZWV0cyBhcyBTQVNTLgoJICoKCSAqIFstLXdvb2NvbW1lcmNlXQoJICogOiBJbmNsdWRlIFdvb0NvbW1lcmNlIGJvaWxlcnBsYXRlIGZpbGVzLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2VuZXJhdGUgYSB0aGVtZSB3aXRoIG5hbWUgIlNhbXBsZSBUaGVtZSIgYW5kIGF1dGhvciAiSm9obiBEb2UiCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBfcyBzYW1wbGUtdGhlbWUgLS10aGVtZV9uYW1lPSJTYW1wbGUgVGhlbWUiIC0tYXV0aG9yPSJKb2huIERvZSIKCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHRoZW1lICdTYW1wbGUgVGhlbWUnLgoJICoKCSAqIEBhbGlhcyBfcwoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5kZXJzY29yZXMoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJHRoZW1lX3NsdWcgPSAkYXJnc1swXTsKCQkkdGhlbWVfcGF0aCA9IFdQX0NPTlRFTlRfRElSIC4gJy90aGVtZXMnOwoJCSR1cmwgICAgICAgID0gJ2h0dHBzOi8vdW5kZXJzY29yZXMubWUnOwoJCSR0aW1lb3V0ICAgID0gMzA7CgoJCWlmICggISBwcmVnX21hdGNoKCAnL15bYS16X11cdyskL2knLCBzdHJfcmVwbGFjZSggJy0nLCAnXycsICR0aGVtZV9zbHVnICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0ludmFsaWQgdGhlbWUgc2x1ZyBzcGVjaWZpZWQuIFRoZW1lIHNsdWdzIGNhbiBvbmx5IGNvbnRhaW4gbGV0dGVycywgbnVtYmVycywgdW5kZXJzY29yZXMgYW5kIGh5cGhlbnMsIGFuZCBjYW4gb25seSBzdGFydCB3aXRoIGEgbGV0dGVyIG9yIHVuZGVyc2NvcmUuJyApOwoJCX0KCgkJJGRlZmF1bHRzID0gWwoJCQkndGhlbWVfbmFtZScgPT4gdWNmaXJzdCggJHRoZW1lX3NsdWcgKSwKCQkJJ2F1dGhvcicgICAgID0+ICdNZScsCgkJCSdhdXRob3JfdXJpJyA9PiAnJywKCQldOwoJCSRkYXRhICAgICA9IHdwX3BhcnNlX2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJJF9zX3RoZW1lX3BhdGggPSAiJHRoZW1lX3BhdGgvJGRhdGFbdGhlbWVfbmFtZV0iOwoKCQkkZXJyb3JfbXNnID0gJHRoaXMtPmNoZWNrX3RhcmdldF9kaXJlY3RvcnkoICd0aGVtZScsICRfc190aGVtZV9wYXRoICk7CgkJaWYgKCAhIGVtcHR5KCAkZXJyb3JfbXNnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIHRoZW1lIHNsdWcgc3BlY2lmaWVkLiB7JGVycm9yX21zZ30iICk7CgkJfQoKCQkkZm9yY2UgICAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCQkkc2hvdWxkX3dyaXRlX2ZpbGUgPSAkdGhpcy0+cHJvbXB0X2lmX2ZpbGVzX3dpbGxfYmVfb3ZlcndyaXR0ZW4oICRfc190aGVtZV9wYXRoLCAkZm9yY2UgKTsKCQlpZiAoICEgJHNob3VsZF93cml0ZV9maWxlICkgewoJCQlXUF9DTEk6OmxvZyggJ05vIGZpbGVzIGNyZWF0ZWQnICk7CgkJCWRpZTsKCQl9CgoJCSR0aGVtZV9kZXNjcmlwdGlvbiA9ICJDdXN0b20gdGhlbWU6IHskZGF0YVsndGhlbWVfbmFtZSddfSwgZGV2ZWxvcGVkIGJ5IHskZGF0YVsnYXV0aG9yJ119IjsKCgkJJGJvZHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBbXTsKCQkkYm9keVsndW5kZXJzY29yZXNtZV9uYW1lJ10gICAgICAgICAgICA9ICRkYXRhWyd0aGVtZV9uYW1lJ107CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfc2x1ZyddICAgICAgICAgICAgPSAkdGhlbWVfc2x1ZzsKCQkkYm9keVsndW5kZXJzY29yZXNtZV9hdXRob3InXSAgICAgICAgICA9ICRkYXRhWydhdXRob3InXTsKCQkkYm9keVsndW5kZXJzY29yZXNtZV9hdXRob3JfdXJpJ10gICAgICA9ICRkYXRhWydhdXRob3JfdXJpJ107CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfZGVzY3JpcHRpb24nXSAgICAgPSAkdGhlbWVfZGVzY3JpcHRpb247CgkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfZ2VuZXJhdGVfc3VibWl0J10gPSAnR2VuZXJhdGUnOwoJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX2dlbmVyYXRlJ10gICAgICAgID0gJzEnOwoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2Fzc2lmeScgKSApIHsKCQkJJGJvZHlbJ3VuZGVyc2NvcmVzbWVfc2FzcyddID0gMTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnd29vY29tbWVyY2UnICkgKSB7CgkJCSRib2R5Wyd1bmRlcnNjb3Jlc21lX3dvb2NvbW1lcmNlJ10gPSAxOwoJCX0KCgkJJHRtcGZuYW1lICA9IHdwX3RlbXBuYW0oICR1cmwgKTsKCQkkcG9zdF9hcmdzID0gWwoJCQkndGltZW91dCcgID0+ICR0aW1lb3V0LAoJCQknYm9keScgICAgID0+ICRib2R5LAoJCQknc3RyZWFtJyAgID0+IHRydWUsCgkJCSdmaWxlbmFtZScgPT4gJHRtcGZuYW1lLAoJCV07CgoJCSRyZXNwb25zZSA9IHdwX3JlbW90ZV9wb3N0KCAkdXJsLCAkcG9zdF9hcmdzICk7CgoJCS8vIFdvcmthcm91bmQgdG8gZ2V0IHNjYWZmb2xkaW5nIHRvIHdvcmsgd2l0aGluIFRyYXZpcyBDSS4KCQkvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL2lzc3Vlcy8xODEKCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzcG9uc2UgKQoJCQkmJiBmYWxzZSAhPT0gc3RycG9zKCAkcmVzcG9uc2UtPmdldF9lcnJvcl9tZXNzYWdlKCksICdnbnV0bHNfaGFuZHNoYWtlKCkgZmFpbGVkJyApCgkJKSB7CgkJCS8vIENlcnRpZmljYXRlIHByb2JsZW0sIGZhbGxpbmcgYmFjayB0byB1bnNlY3VyZWQgcmVxdWVzdCBpbnN0ZWFkLgoJCQkkYWx0X3VybCA9IHN0cl9yZXBsYWNlKCAnaHR0cHM6Ly8nLCAnaHR0cDovLycsICR1cmwgKTsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiU2VjdXJlZCByZXF1ZXN0IHRvIHskdXJsfSBmYWlsZWQsIHVzaW5nIHskYWx0X3VybH0gYXMgYSBmYWxsYmFjay4iICk7CgkJCSRyZXNwb25zZSA9IHdwX3JlbW90ZV9wb3N0KCAkYWx0X3VybCwgJHBvc3RfYXJncyApOwoJCX0KCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRyZXNwb25zZSApOwoJCX0KCgkJJHJlc3BvbnNlX2NvZGUgPSB3cF9yZW1vdGVfcmV0cmlldmVfcmVzcG9uc2VfY29kZSggJHJlc3BvbnNlICk7CgkJaWYgKCAyMDAgIT09IChpbnQpICRyZXNwb25zZV9jb2RlICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgY3JlYXRlIHRoZW1lIChyZWNlaXZlZCB7JHJlc3BvbnNlX2NvZGV9IHJlc3BvbnNlKS4iICk7CgkJfQoKCQkkdGhpcy0+bWF5YmVfY3JlYXRlX3RoZW1lc19kaXIoKTsKCgkJJHRoaXMtPmluaXRfd3BfZmlsZXN5c3RlbSgpOwoKCQkkdW56aXBfcmVzdWx0ID0gdW56aXBfZmlsZSggJHRtcGZuYW1lLCAkdGhlbWVfcGF0aCApOwoJCXVubGluayggJHRtcGZuYW1lICk7CgoJCWlmICggdHJ1ZSA9PT0gJHVuemlwX3Jlc3VsdCApIHsKCQkJJGZpbGVzX3RvX2NyZWF0ZSA9IFsKCQkJCSJ7JHRoZW1lX3BhdGh9L3skdGhlbWVfc2x1Z30vLmVkaXRvcmNvbmZpZyIgPT4gZmlsZV9nZXRfY29udGVudHMoIHNlbGY6OmdldF90ZW1wbGF0ZV9wYXRoKCAnLmVkaXRvcmNvbmZpZycgKSApLAoJCQldOwoJCQkkdGhpcy0+Y3JlYXRlX2ZpbGVzKCAkZmlsZXNfdG9fY3JlYXRlLCBmYWxzZSApOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJDcmVhdGVkIHRoZW1lICd7JGRhdGFbJ3RoZW1lX25hbWUnXX0nLiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGRlY29tcHJlc3MgeW91ciB0aGVtZSBmaWxlcyAoJ3skdG1wZm5hbWV9JykgYXQgJ3skdGhlbWVfcGF0aH0nOiB7JHVuemlwX3Jlc3VsdC0+Z2V0X2Vycm9yX21lc3NhZ2UoKX0iICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FjdGl2YXRlJyApICkgewoJCQlXUF9DTEk6OnJ1bl9jb21tYW5kKCBbICd0aGVtZScsICdhY3RpdmF0ZScsICR0aGVtZV9zbHVnIF0gKTsKCQl9IGVsc2VpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2VuYWJsZS1uZXR3b3JrJyApICkgewoJCQlXUF9DTEk6OnJ1bl9jb21tYW5kKCBbICd0aGVtZScsICdlbmFibGUnLCAkdGhlbWVfc2x1ZyBdLCBbICduZXR3b3JrJyA9PiB0cnVlIF0gKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgY2hpbGQgdGhlbWUgYmFzZWQgb24gYW4gZXhpc3RpbmcgdGhlbWUuCgkgKgoJICogQ3JlYXRlcyBhIGNoaWxkIHRoZW1lIGZvbGRlciB3aXRoIGBmdW5jdGlvbnMucGhwYCBhbmQgYHN0eWxlLmNzc2AgZmlsZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzbHVnPgoJICogOiBUaGUgc2x1ZyBmb3IgdGhlIG5ldyBjaGlsZCB0aGVtZS4KCSAqCgkgKiAtLXBhcmVudF90aGVtZT08c2x1Zz4KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdUZW1wbGF0ZTonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS10aGVtZV9uYW1lPTx0aXRsZT5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnVGhlbWUgTmFtZTonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS1hdXRob3I9PGZ1bGwtbmFtZT5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnQXV0aG9yOicgaGVhZGVyIGluICdzdHlsZS5jc3MnLgoJICoKCSAqIFstLWF1dGhvcl91cmk9PHVyaT5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnQXV0aG9yIFVSSTonIGhlYWRlciBpbiAnc3R5bGUuY3NzJy4KCSAqCgkgKiBbLS10aGVtZV91cmk9PHVyaT5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnVGhlbWUgVVJJOicgaGVhZGVyIGluICdzdHlsZS5jc3MnLgoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBBY3RpdmF0ZSB0aGUgbmV3bHkgY3JlYXRlZCBjaGlsZCB0aGVtZS4KCSAqCgkgKiBbLS1lbmFibGUtbmV0d29ya10KCSAqIDogRW5hYmxlIHRoZSBuZXdseSBjcmVhdGVkIGNoaWxkIHRoZW1lIGZvciB0aGUgZW50aXJlIG5ldHdvcmsuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZSBmaWxlcyB0aGF0IGFscmVhZHkgZXhpc3QuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSBhICdzYW1wbGUtdGhlbWUnIGNoaWxkIHRoZW1lIGJhc2VkIG9uIFR3ZW50eVNpeHRlZW4KCSAqICAgICAkIHdwIHNjYWZmb2xkIGNoaWxkLXRoZW1lIHNhbXBsZS10aGVtZSAtLXBhcmVudF90aGVtZT10d2VudHlzaXh0ZWVuCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCAnL3Zhci93d3cvZXhhbXBsZS5jb20vcHVibGljX2h0bWwvd3AtY29udGVudC90aGVtZXMvc2FtcGxlLXRoZW1lJy4KCSAqCgkgKiBAc3ViY29tbWFuZCBjaGlsZC10aGVtZQoJICovCglwdWJsaWMgZnVuY3Rpb24gY2hpbGRfdGhlbWUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhlbWVfc2x1ZyA9ICRhcmdzWzBdOwoKCQlpZiAoIGluX2FycmF5KCAkdGhlbWVfc2x1ZywgWyAnLicsICcuLicgXSwgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB0aGVtZSBzbHVnIHNwZWNpZmllZC4gVGhlIHNsdWcgY2Fubm90IGJlICcuJyBvciAnLi4nLiIgKTsKCQl9CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RoZW1lX25hbWUnID0+IHVjZmlyc3QoICR0aGVtZV9zbHVnICksCgkJCSdhdXRob3InICAgICA9PiAnTWUnLAoJCQknYXV0aG9yX3VyaScgPT4gJycsCgkJCSd0aGVtZV91cmknICA9PiAnJywKCQldOwoKCQkkZGF0YSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHdwX3BhcnNlX2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCQkkZGF0YVsnc2x1ZyddICAgICAgICAgICAgICAgICAgICAgICA9ICR0aGVtZV9zbHVnOwoJCSRkYXRhWydwYXJlbnRfdGhlbWVfZnVuY3Rpb25fc2FmZSddID0gc3RyX3JlcGxhY2UoIFsgJyAnLCAnLScgXSwgJ18nLCAkZGF0YVsncGFyZW50X3RoZW1lJ10gKTsKCQkkZGF0YVsnZGVzY3JpcHRpb24nXSAgICAgICAgICAgICAgICA9IHVjZmlyc3QoICRkYXRhWydwYXJlbnRfdGhlbWUnXSApIC4gJyBjaGlsZCB0aGVtZS4nOwoKCQkkdGhlbWVfZGlyID0gV1BfQ09OVEVOVF9ESVIgLiAiL3RoZW1lcy97JHRoZW1lX3NsdWd9IjsKCgkJJGVycm9yX21zZyA9ICR0aGlzLT5jaGVja190YXJnZXRfZGlyZWN0b3J5KCAndGhlbWUnLCAkdGhlbWVfZGlyICk7CgkJaWYgKCAhIGVtcHR5KCAkZXJyb3JfbXNnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIHRoZW1lIHNsdWcgc3BlY2lmaWVkLiB7JGVycm9yX21zZ30iICk7CgkJfQoKCQkkdGhlbWVfc3R5bGVfcGF0aCAgICAgPSAieyR0aGVtZV9kaXJ9L3N0eWxlLmNzcyI7CgkJJHRoZW1lX2Z1bmN0aW9uc19wYXRoID0gInskdGhlbWVfZGlyfS9mdW5jdGlvbnMucGhwIjsKCgkJJHRoaXMtPm1heWJlX2NyZWF0ZV90aGVtZXNfZGlyKCk7CgoJCSRmaWxlc190b19jcmVhdGUgPSBbCgkJCSR0aGVtZV9zdHlsZV9wYXRoICAgICAgICAgICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAnY2hpbGRfdGhlbWUubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkkdGhlbWVfZnVuY3Rpb25zX3BhdGggICAgICAgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ2NoaWxkX3RoZW1lX2Z1bmN0aW9ucy5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JHRoZW1lX2Rpcn0vLmVkaXRvcmNvbmZpZyIgPT4gZmlsZV9nZXRfY29udGVudHMoIHNlbGY6OmdldF90ZW1wbGF0ZV9wYXRoKCAnLmVkaXRvcmNvbmZpZycgKSApLAoJCV07CgkJJGZvcmNlICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJyApOwoJCSRmaWxlc193cml0dGVuICAgPSAkdGhpcy0+Y3JlYXRlX2ZpbGVzKCAkZmlsZXNfdG9fY3JlYXRlLCAkZm9yY2UgKTsKCQkkc2tpcF9tZXNzYWdlICAgID0gJ0FsbCB0aGVtZSBmaWxlcyB3ZXJlIHNraXBwZWQuJzsKCQkkc3VjY2Vzc19tZXNzYWdlID0gIkNyZWF0ZWQgJ3skdGhlbWVfZGlyfScuIjsKCQkkdGhpcy0+bG9nX3doZXRoZXJfZmlsZXNfd3JpdHRlbiggJGZpbGVzX3dyaXR0ZW4sICRza2lwX21lc3NhZ2UsICRzdWNjZXNzX21lc3NhZ2UgKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhY3RpdmF0ZScgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAndGhlbWUnLCAnYWN0aXZhdGUnLCAkdGhlbWVfc2x1ZyBdICk7CgkJfSBlbHNlaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdlbmFibGUtbmV0d29yaycgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAndGhlbWUnLCAnZW5hYmxlJywgJHRoZW1lX3NsdWcgXSwgWyAnbmV0d29yaycgPT4gdHJ1ZSBdICk7CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X291dHB1dF9wYXRoKCAkYXNzb2NfYXJncywgJHN1YmRpciApIHsKCQlpZiAoICRhc3NvY19hcmdzWyd0aGVtZSddICkgewoJCQkkdGhlbWUgPSAkYXNzb2NfYXJnc1sndGhlbWUnXTsKCQkJaWYgKCBpc19zdHJpbmcoICR0aGVtZSApICkgewoJCQkJJHBhdGggPSBnZXRfdGhlbWVfcm9vdCggJHRoZW1lICkgLiAiL3skdGhlbWV9IjsKCQkJfSBlbHNlIHsKCQkJCSRwYXRoID0gZ2V0X3N0eWxlc2hlZXRfZGlyZWN0b3J5KCk7CgkJCX0KCQkJaWYgKCAhIGlzX2RpciggJHBhdGggKSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDYW4ndCBmaW5kICd7JHRoZW1lfScgdGhlbWUuIiApOwoJCQl9CgkJfSBlbHNlaWYgKCAkYXNzb2NfYXJnc1sncGx1Z2luJ10gKSB7CgkJCSRwbHVnaW4gPSAkYXNzb2NfYXJnc1sncGx1Z2luJ107CgkJCSRwYXRoICAgPSBXUF9QTFVHSU5fRElSIC4gIi97JHBsdWdpbn0iOwoJCQlpZiAoICEgaXNfZGlyKCAkcGF0aCApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkNhbid0IGZpbmQgJ3skcGx1Z2lufScgcGx1Z2luLiIgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSRwYXRoIC49ICRzdWJkaXI7CgoJCXJldHVybiAkcGF0aDsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBzdGFydGVyIGNvZGUgZm9yIGEgcGx1Z2luLgoJICoKCSAqIFRoZSBmb2xsb3dpbmcgZmlsZXMgYXJlIGFsd2F5cyBnZW5lcmF0ZWQ6CgkgKgoJICogKiBgcGx1Z2luLXNsdWcucGhwYCBpcyB0aGUgbWFpbiBQSFAgcGx1Z2luIGZpbGUuCgkgKiAqIGByZWFkbWUudHh0YCBpcyB0aGUgcmVhZG1lIGZpbGUgZm9yIHRoZSBwbHVnaW4uCgkgKiAqIGBwYWNrYWdlLmpzb25gIG5lZWRlZCBieSBOUE0gaG9sZHMgdmFyaW91cyBtZXRhZGF0YSByZWxldmFudCB0byB0aGUgcHJvamVjdC4gUGFja2FnZXM6IGBncnVudGAsIGBncnVudC13cC1pMThuYCBhbmQgYGdydW50LXdwLXJlYWRtZS10by1tYXJrZG93bmAuIFNjcmlwdHM6IGBzdGFydGAsIGByZWFkbWVgLCBgaTE4bmAuCgkgKiAqIGBHcnVudGZpbGUuanNgIGlzIHRoZSBKUyBmaWxlIGNvbnRhaW5pbmcgR3J1bnQgdGFza3MuIFRhc2tzOiBgaTE4bmAgY29udGFpbmluZyBgYWRkdGV4dGRvbWFpbmAgYW5kIGBtYWtlcG90YCwgYHJlYWRtZWAgY29udGFpbmluZyBgd3BfcmVhZG1lX3RvX21hcmtkb3duYC4KCSAqICogYC5lZGl0b3Jjb25maWdgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIEVkaXRvci4KCSAqICogYC5naXRpZ25vcmVgIHRlbGxzIHdoaWNoIGZpbGVzIChvciBwYXR0ZXJucykgZ2l0IHNob3VsZCBpZ25vcmUuCgkgKiAqIGAuZGlzdGlnbm9yZWAgdGVsbHMgd2hpY2ggZmlsZXMgYW5kIGZvbGRlcnMgc2hvdWxkIGJlIGlnbm9yZWQgaW4gZGlzdHJpYnV0aW9uLgoJICoKCSAqIFRoZSBmb2xsb3dpbmcgZmlsZXMgYXJlIGFsc28gaW5jbHVkZWQgdW5sZXNzIHRoZSBgLS1za2lwLXRlc3RzYCBpcyB1c2VkOgoJICoKCSAqICogYHBocHVuaXQueG1sLmRpc3RgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIFBIUFVuaXQuCgkgKiAqIGAudHJhdmlzLnltbGAgaXMgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgVHJhdmlzIENJLiBVc2UgYC0tY2k9PHByb3ZpZGVyPmAgdG8gc2VsZWN0IGEgZGlmZmVyZW50IHNlcnZpY2UuCgkgKiAqIGBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaGAgY29uZmlndXJlcyB0aGUgV29yZFByZXNzIHRlc3Qgc3VpdGUgYW5kIGEgdGVzdCBkYXRhYmFzZS4KCSAqICogYHRlc3RzL2Jvb3RzdHJhcC5waHBgIGlzIHRoZSBmaWxlIHRoYXQgbWFrZXMgdGhlIGN1cnJlbnQgcGx1Z2luIGFjdGl2ZSB3aGVuIHJ1bm5pbmcgdGhlIHRlc3Qgc3VpdGUuCgkgKiAqIGB0ZXN0cy90ZXN0LXNhbXBsZS5waHBgIGlzIGEgc2FtcGxlIGZpbGUgY29udGFpbmluZyB0ZXN0IGNhc2VzLgoJICogKiBgLnBocGNzLnhtbC5kaXN0YCBpcyBhIGNvbGxlY3Rpb24gb2YgUEhQX0NvZGVTbmlmZmVyIHJ1bGVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8c2x1Zz4KCSAqIDogVGhlIGludGVybmFsIG5hbWUgb2YgdGhlIHBsdWdpbi4KCSAqCgkgKiBbLS1kaXI9PGRpcm5hbWU+XQoJICogOiBQdXQgdGhlIG5ldyBwbHVnaW4gaW4gc29tZSBhcmJpdHJhcnkgZGlyZWN0b3J5IHBhdGguIFBsdWdpbiBkaXJlY3Rvcnkgd2lsbCBiZSBwYXRoIHBsdXMgc3VwcGxpZWQgc2x1Zy4KCSAqCgkgKiBbLS1wbHVnaW5fbmFtZT08dGl0bGU+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ1BsdWdpbiBOYW1lOicgaGVhZGVyLgoJICoKCSAqIFstLXBsdWdpbl9kZXNjcmlwdGlvbj08ZGVzY3JpcHRpb24+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0Rlc2NyaXB0aW9uOicgaGVhZGVyLgoJICoKCSAqIFstLXBsdWdpbl9hdXRob3I9PGF1dGhvcj5dCgkgKiA6IFdoYXQgdG8gcHV0IGluIHRoZSAnQXV0aG9yOicgaGVhZGVyLgoJICoKCSAqIFstLXBsdWdpbl9hdXRob3JfdXJpPTx1cmw+XQoJICogOiBXaGF0IHRvIHB1dCBpbiB0aGUgJ0F1dGhvciBVUkk6JyBoZWFkZXIuCgkgKgoJICogWy0tcGx1Z2luX3VyaT08dXJsPl0KCSAqIDogV2hhdCB0byBwdXQgaW4gdGhlICdQbHVnaW4gVVJJOicgaGVhZGVyLgoJICoKCSAqIFstLXNraXAtdGVzdHNdCgkgKiA6IERvbid0IGdlbmVyYXRlIGZpbGVzIGZvciB1bml0IHRlc3RpbmcuCgkgKgoJICogWy0tY2k9PHByb3ZpZGVyPl0KCSAqIDogQ2hvb3NlIGEgY29uZmlndXJhdGlvbiBmaWxlIGZvciBhIGNvbnRpbnVvdXMgaW50ZWdyYXRpb24gcHJvdmlkZXIuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IHRyYXZpcwoJICogb3B0aW9uczoKCSAqICAgLSB0cmF2aXMKCSAqICAgLSBjaXJjbGUKCSAqICAgLSBnaXRsYWIKCSAqIC0tLQoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBBY3RpdmF0ZSB0aGUgbmV3bHkgZ2VuZXJhdGVkIHBsdWdpbi4KCSAqCgkgKiBbLS1hY3RpdmF0ZS1uZXR3b3JrXQoJICogOiBOZXR3b3JrIGFjdGl2YXRlIHRoZSBuZXdseSBnZW5lcmF0ZWQgcGx1Z2luLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBPdmVyd3JpdGUgZmlsZXMgdGhhdCBhbHJlYWR5IGV4aXN0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2NhZmZvbGQgcGx1Z2luIHNhbXBsZS1wbHVnaW4KCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHBsdWdpbiBmaWxlcy4KCSAqICAgICBTdWNjZXNzOiBDcmVhdGVkIHRlc3QgZmlsZXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBwbHVnaW4oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGx1Z2luX3NsdWcgICAgPSAkYXJnc1swXTsKCQkkcGx1Z2luX25hbWUgICAgPSB1Y3dvcmRzKCBzdHJfcmVwbGFjZSggJy0nLCAnICcsICRwbHVnaW5fc2x1ZyApICk7CgkJJHBsdWdpbl9wYWNrYWdlID0gc3RyX3JlcGxhY2UoICcgJywgJ18nLCAkcGx1Z2luX25hbWUgKTsKCgkJaWYgKCBpbl9hcnJheSggJHBsdWdpbl9zbHVnLCBbICcuJywgJy4uJyBdLCB0cnVlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJJbnZhbGlkIHBsdWdpbiBzbHVnIHNwZWNpZmllZC4gVGhlIHNsdWcgY2Fubm90IGJlICcuJyBvciAnLi4nLiIgKTsKCQl9CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3BsdWdpbl9zbHVnJyAgICAgICAgID0+ICRwbHVnaW5fc2x1ZywKCQkJJ3BsdWdpbl9uYW1lJyAgICAgICAgID0+ICRwbHVnaW5fbmFtZSwKCQkJJ3BsdWdpbl9wYWNrYWdlJyAgICAgID0+ICRwbHVnaW5fcGFja2FnZSwKCQkJJ3BsdWdpbl9kZXNjcmlwdGlvbicgID0+ICdQTFVHSU4gREVTQ1JJUFRJT04gSEVSRScsCgkJCSdwbHVnaW5fYXV0aG9yJyAgICAgICA9PiAnWU9VUiBOQU1FIEhFUkUnLAoJCQkncGx1Z2luX2F1dGhvcl91cmknICAgPT4gJ1lPVVIgU0lURSBIRVJFJywKCQkJJ3BsdWdpbl91cmknICAgICAgICAgID0+ICdQTFVHSU4gU0lURSBIRVJFJywKCQkJJ3BsdWdpbl90ZXN0ZWRfdXBfdG8nID0+IGdldF9ibG9naW5mbyggJ3ZlcnNpb24nICksCgkJXTsKCQkkZGF0YSAgICAgPSB3cF9wYXJzZV9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICk7CgoJCSRkYXRhWyd0ZXh0ZG9tYWluJ10gPSAkcGx1Z2luX3NsdWc7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2RpciddICkgKSB7CgkJCWlmICggISBpc19kaXIoICRhc3NvY19hcmdzWydkaXInXSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkNhbm5vdCBjcmVhdGUgcGx1Z2luIGluIGRpcmVjdG9yeSB0aGF0IGRvZXNuJ3QgZXhpc3QuIiApOwoJCQl9CgkJCSRwbHVnaW5fZGlyID0gInskYXNzb2NfYXJnc1snZGlyJ119L3skcGx1Z2luX3NsdWd9IjsKCQl9IGVsc2UgewoJCQkkcGx1Z2luX2RpciA9IFdQX1BMVUdJTl9ESVIgLiAiL3skcGx1Z2luX3NsdWd9IjsKCQkJJHRoaXMtPm1heWJlX2NyZWF0ZV9wbHVnaW5zX2RpcigpOwoKCQkJJGVycm9yX21zZyA9ICR0aGlzLT5jaGVja190YXJnZXRfZGlyZWN0b3J5KCAncGx1Z2luJywgJHBsdWdpbl9kaXIgKTsKCQkJaWYgKCAhIGVtcHR5KCAkZXJyb3JfbXNnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCBwbHVnaW4gc2x1ZyBzcGVjaWZpZWQuIHskZXJyb3JfbXNnfSIgKTsKCQkJfQoJCX0KCgkJJHBsdWdpbl9wYXRoICAgICAgICA9ICJ7JHBsdWdpbl9kaXJ9L3skcGx1Z2luX3NsdWd9LnBocCI7CgkJJHBsdWdpbl9yZWFkbWVfcGF0aCA9ICJ7JHBsdWdpbl9kaXJ9L3JlYWRtZS50eHQiOwoKCQkkZmlsZXNfdG9fY3JlYXRlID0gWwoJCQkkcGx1Z2luX3BhdGggICAgICAgICAgICAgICAgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4ubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkkcGx1Z2luX3JlYWRtZV9wYXRoICAgICAgICAgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tcmVhZG1lLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJInskcGx1Z2luX2Rpcn0vcGFja2FnZS5qc29uIiAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLXBhY2thZ2VzLm11c3RhY2hlJywgJGRhdGEgKSwKCQkJInskcGx1Z2luX2Rpcn0vR3J1bnRmaWxlLmpzIiAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAncGx1Z2luLWdydW50ZmlsZS5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JHBsdWdpbl9kaXJ9Ly5naXRpZ25vcmUiICAgID0+IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ3BsdWdpbi1naXRpZ25vcmUubXVzdGFjaGUnLCAkZGF0YSApLAoJCQkieyRwbHVnaW5fZGlyfS8uZGlzdGlnbm9yZSIgICA9PiBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tZGlzdGlnbm9yZS5tdXN0YWNoZScsICRkYXRhICksCgkJCSJ7JHBsdWdpbl9kaXJ9Ly5lZGl0b3Jjb25maWciID0+IGZpbGVfZ2V0X2NvbnRlbnRzKCBzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJy5lZGl0b3Jjb25maWcnICkgKSwKCQldOwoJCSRmb3JjZSAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCQkkZmlsZXNfd3JpdHRlbiAgID0gJHRoaXMtPmNyZWF0ZV9maWxlcyggJGZpbGVzX3RvX2NyZWF0ZSwgJGZvcmNlICk7CgoJCSRza2lwX21lc3NhZ2UgICAgPSAnQWxsIHBsdWdpbiBmaWxlcyB3ZXJlIHNraXBwZWQuJzsKCQkkc3VjY2Vzc19tZXNzYWdlID0gJ0NyZWF0ZWQgcGx1Z2luIGZpbGVzLic7CgkJJHRoaXMtPmxvZ193aGV0aGVyX2ZpbGVzX3dyaXR0ZW4oICRmaWxlc193cml0dGVuLCAkc2tpcF9tZXNzYWdlLCAkc3VjY2Vzc19tZXNzYWdlICk7CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXRlc3RzJyApICkgewoJCQkkY29tbWFuZF9hcmdzID0gWwoJCQkJJ2RpcicgICA9PiAkcGx1Z2luX2RpciwKCQkJCSdjaScgICAgPT4gZW1wdHkoICRhc3NvY19hcmdzWydjaSddICkgPyAnJyA6ICRhc3NvY19hcmdzWydjaSddLAoJCQkJJ2ZvcmNlJyA9PiAkZm9yY2UsCgkJCV07CgkJCVdQX0NMSTo6cnVuX2NvbW1hbmQoIFsgJ3NjYWZmb2xkJywgJ3BsdWdpbi10ZXN0cycsICRwbHVnaW5fc2x1ZyBdLCAkY29tbWFuZF9hcmdzICk7CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FjdGl2YXRlJyApICkgewoJCQlXUF9DTEk6OnJ1bl9jb21tYW5kKCBbICdwbHVnaW4nLCAnYWN0aXZhdGUnLCAkcGx1Z2luX3NsdWcgXSApOwoJCX0gZWxzZWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWN0aXZhdGUtbmV0d29yaycgKSApIHsKCQkJV1BfQ0xJOjpydW5fY29tbWFuZCggWyAncGx1Z2luJywgJ2FjdGl2YXRlJywgJHBsdWdpbl9zbHVnIF0sIFsgJ25ldHdvcmsnID0+IHRydWUgXSApOwoJCX0KCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBmaWxlcyBuZWVkZWQgZm9yIHJ1bm5pbmcgUEhQVW5pdCB0ZXN0cyBpbiBhIHBsdWdpbi4KCSAqCgkgKiBUaGUgZm9sbG93aW5nIGZpbGVzIGFyZSBnZW5lcmF0ZWQgYnkgZGVmYXVsdDoKCSAqCgkgKiAqIGBwaHB1bml0LnhtbC5kaXN0YCBpcyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGZvciBQSFBVbml0LgoJICogKiBgLnRyYXZpcy55bWxgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIFRyYXZpcyBDSS4gVXNlIGAtLWNpPTxwcm92aWRlcj5gIHRvIHNlbGVjdCBhIGRpZmZlcmVudCBzZXJ2aWNlLgoJICogKiBgYmluL2luc3RhbGwtd3AtdGVzdHMuc2hgIGNvbmZpZ3VyZXMgdGhlIFdvcmRQcmVzcyB0ZXN0IHN1aXRlIGFuZCBhIHRlc3QgZGF0YWJhc2UuCgkgKiAqIGB0ZXN0cy9ib290c3RyYXAucGhwYCBpcyB0aGUgZmlsZSB0aGF0IG1ha2VzIHRoZSBjdXJyZW50IHBsdWdpbiBhY3RpdmUgd2hlbiBydW5uaW5nIHRoZSB0ZXN0IHN1aXRlLgoJICogKiBgdGVzdHMvdGVzdC1zYW1wbGUucGhwYCBpcyBhIHNhbXBsZSBmaWxlIGNvbnRhaW5pbmcgdGhlIGFjdHVhbCB0ZXN0cy4KCSAqICogYC5waHBjcy54bWwuZGlzdGAgaXMgYSBjb2xsZWN0aW9uIG9mIFBIUF9Db2RlU25pZmZlciBydWxlcy4KCSAqCgkgKiBMZWFybiBtb3JlIGZyb20gdGhlIFtwbHVnaW4gdW5pdCB0ZXN0cyBkb2N1bWVudGF0aW9uXShodHRwczovL21ha2Uud29yZHByZXNzLm9yZy9jbGkvaGFuZGJvb2svcGx1Z2luLXVuaXQtdGVzdHMvKS4KCSAqCgkgKiAjIyBFTlZJUk9OTUVOVAoJICoKCSAqIFRoZSBgdGVzdHMvYm9vdHN0cmFwLnBocGAgZmlsZSBsb29rcyBmb3IgdGhlIFdQX1RFU1RTX0RJUiBlbnZpcm9ubWVudAoJICogdmFyaWFibGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPl0KCSAqIDogVGhlIG5hbWUgb2YgdGhlIHBsdWdpbiB0byBnZW5lcmF0ZSB0ZXN0IGZpbGVzIGZvci4KCSAqCgkgKiBbLS1kaXI9PGRpcm5hbWU+XQoJICogOiBHZW5lcmF0ZSB0ZXN0IGZpbGVzIGZvciBhIG5vbi1zdGFuZGFyZCBwbHVnaW4gcGF0aC4gSWYgbm8gcGx1Z2luIHNsdWcgaXMgc3BlY2lmaWVkLCB0aGUgZGlyZWN0b3J5IG5hbWUgaXMgdXNlZC4KCSAqCgkgKiBbLS1jaT08cHJvdmlkZXI+XQoJICogOiBDaG9vc2UgYSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIGEgY29udGludW91cyBpbnRlZ3JhdGlvbiBwcm92aWRlci4KCSAqIC0tLQoJICogZGVmYXVsdDogdHJhdmlzCgkgKiBvcHRpb25zOgoJICogICAtIHRyYXZpcwoJICogICAtIGNpcmNsZQoJICogICAtIGdpdGxhYgoJICogICAtIGJpdGJ1Y2tldAoJICogLS0tCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZSBmaWxlcyB0aGF0IGFscmVhZHkgZXhpc3QuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSB1bml0IHRlc3QgZmlsZXMgZm9yIHBsdWdpbiAnc2FtcGxlLXBsdWdpbicuCgkgKiAgICAgJCB3cCBzY2FmZm9sZCBwbHVnaW4tdGVzdHMgc2FtcGxlLXBsdWdpbgoJICogICAgIFN1Y2Nlc3M6IENyZWF0ZWQgdGVzdCBmaWxlcy4KCSAqCgkgKiBAc3ViY29tbWFuZCBwbHVnaW4tdGVzdHMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBsdWdpbl90ZXN0cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0aGlzLT5zY2FmZm9sZF9wbHVnaW5fdGhlbWVfdGVzdHMoICRhcmdzLCAkYXNzb2NfYXJncywgJ3BsdWdpbicgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBmaWxlcyBuZWVkZWQgZm9yIHJ1bm5pbmcgUEhQVW5pdCB0ZXN0cyBpbiBhIHRoZW1lLgoJICoKCSAqIFRoZSBmb2xsb3dpbmcgZmlsZXMgYXJlIGdlbmVyYXRlZCBieSBkZWZhdWx0OgoJICoKCSAqICogYHBocHVuaXQueG1sLmRpc3RgIGlzIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIFBIUFVuaXQuCgkgKiAqIGAudHJhdmlzLnltbGAgaXMgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgVHJhdmlzIENJLiBVc2UgYC0tY2k9PHByb3ZpZGVyPmAgdG8gc2VsZWN0IGEgZGlmZmVyZW50IHNlcnZpY2UuCgkgKiAqIGBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaGAgY29uZmlndXJlcyB0aGUgV29yZFByZXNzIHRlc3Qgc3VpdGUgYW5kIGEgdGVzdCBkYXRhYmFzZS4KCSAqICogYHRlc3RzL2Jvb3RzdHJhcC5waHBgIGlzIHRoZSBmaWxlIHRoYXQgbWFrZXMgdGhlIGN1cnJlbnQgdGhlbWUgYWN0aXZlIHdoZW4gcnVubmluZyB0aGUgdGVzdCBzdWl0ZS4KCSAqICogYHRlc3RzL3Rlc3Qtc2FtcGxlLnBocGAgaXMgYSBzYW1wbGUgZmlsZSBjb250YWluaW5nIHRoZSBhY3R1YWwgdGVzdHMuCgkgKiAqIGAucGhwY3MueG1sLmRpc3RgIGlzIGEgY29sbGVjdGlvbiBvZiBQSFBfQ29kZVNuaWZmZXIgcnVsZXMuCgkgKgoJICogTGVhcm4gbW9yZSBmcm9tIHRoZSBbcGx1Z2luIHVuaXQgdGVzdHMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9tYWtlLndvcmRwcmVzcy5vcmcvY2xpL2hhbmRib29rL3BsdWdpbi11bml0LXRlc3RzLykuCgkgKgoJICogIyMgRU5WSVJPTk1FTlQKCSAqCgkgKiBUaGUgYHRlc3RzL2Jvb3RzdHJhcC5waHBgIGZpbGUgbG9va3MgZm9yIHRoZSBXUF9URVNUU19ESVIgZW52aXJvbm1lbnQKCSAqIHZhcmlhYmxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHRoZW1lPl0KCSAqIDogVGhlIG5hbWUgb2YgdGhlIHRoZW1lIHRvIGdlbmVyYXRlIHRlc3QgZmlsZXMgZm9yLgoJICoKCSAqIFstLWRpcj08ZGlybmFtZT5dCgkgKiA6IEdlbmVyYXRlIHRlc3QgZmlsZXMgZm9yIGEgbm9uLXN0YW5kYXJkIHRoZW1lIHBhdGguIElmIG5vIHRoZW1lIHNsdWcgaXMgc3BlY2lmaWVkLCB0aGUgZGlyZWN0b3J5IG5hbWUgaXMgdXNlZC4KCSAqCgkgKiBbLS1jaT08cHJvdmlkZXI+XQoJICogOiBDaG9vc2UgYSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIGEgY29udGludW91cyBpbnRlZ3JhdGlvbiBwcm92aWRlci4KCSAqIC0tLQoJICogZGVmYXVsdDogdHJhdmlzCgkgKiBvcHRpb25zOgoJICogICAtIHRyYXZpcwoJICogICAtIGNpcmNsZQoJICogICAtIGdpdGxhYgoJICogICAtIGJpdGJ1Y2tldAoJICogLS0tCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZSBmaWxlcyB0aGF0IGFscmVhZHkgZXhpc3QuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZW5lcmF0ZSB1bml0IHRlc3QgZmlsZXMgZm9yIHRoZW1lICd0d2VudHlzaXh0ZWVuY2hpbGQnLgoJICogICAgICQgd3Agc2NhZmZvbGQgdGhlbWUtdGVzdHMgdHdlbnR5c2l4dGVlbmNoaWxkCgkgKiAgICAgU3VjY2VzczogQ3JlYXRlZCB0ZXN0IGZpbGVzLgoJICoKCSAqIEBzdWJjb21tYW5kIHRoZW1lLXRlc3RzCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0aGVtZV90ZXN0cyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSR0aGlzLT5zY2FmZm9sZF9wbHVnaW5fdGhlbWVfdGVzdHMoICRhcmdzLCAkYXNzb2NfYXJncywgJ3RoZW1lJyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc2NhZmZvbGRfcGx1Z2luX3RoZW1lX3Rlc3RzKCAkYXJncywgJGFzc29jX2FyZ3MsICR0eXBlICkgewoJCSR3cF9maWxlc3lzdGVtID0gJHRoaXMtPmluaXRfd3BfZmlsZXN5c3RlbSgpOwoKCQlpZiAoICEgZW1wdHkoICRhcmdzWzBdICkgKSB7CgkJCSRzbHVnID0gJGFyZ3NbMF07CgkJCWlmICggaW5fYXJyYXkoICRzbHVnLCBbICcuJywgJy4uJyBdLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB7JHR5cGV9IHNsdWcgc3BlY2lmaWVkLiBUaGUgc2x1ZyBjYW5ub3QgYmUgJy4nIG9yICcuLicuIiApOwoJCQl9CgkJCWlmICggJ3RoZW1lJyA9PT0gJHR5cGUgKSB7CgkJCQkkdGhlbWUgPSB3cF9nZXRfdGhlbWUoICRzbHVnICk7CgkJCQlpZiAoICR0aGVtZS0+ZXhpc3RzKCkgKSB7CgkJCQkJJHRhcmdldF9kaXIgPSAkdGhlbWUtPmdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeSgpOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB7JHR5cGV9IHNsdWcgc3BlY2lmaWVkLiBUaGUgdGhlbWUgJ3skc2x1Z30nIGRvZXMgbm90IGV4aXN0LiIgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCSR0YXJnZXRfZGlyID0gV1BfUExVR0lOX0RJUiAuICIveyRzbHVnfSI7CgkJCX0KCQkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2RpciddICkgJiYgISBpc19kaXIoICR0YXJnZXRfZGlyICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB7JHR5cGV9IHNsdWcgc3BlY2lmaWVkLiBObyBzdWNoIHRhcmdldCBkaXJlY3RvcnkgJ3skdGFyZ2V0X2Rpcn0nLiIgKTsKCQkJfQoKCQkJJGVycm9yX21zZyA9ICR0aGlzLT5jaGVja190YXJnZXRfZGlyZWN0b3J5KCAkdHlwZSwgJHRhcmdldF9kaXIgKTsKCQkJaWYgKCAhIGVtcHR5KCAkZXJyb3JfbXNnICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB7JHR5cGV9IHNsdWcgc3BlY2lmaWVkLiB7JGVycm9yX21zZ30iICk7CgkJCX0KCQl9CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2RpciddICkgKSB7CgkJCSR0YXJnZXRfZGlyID0gJGFzc29jX2FyZ3NbJ2RpciddOwoJCQlpZiAoICEgaXNfZGlyKCAkdGFyZ2V0X2RpciApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkludmFsaWQgeyR0eXBlfSBkaXJlY3Rvcnkgc3BlY2lmaWVkLiBObyBzdWNoIGRpcmVjdG9yeSAneyR0YXJnZXRfZGlyfScuIiApOwoJCQl9CgkJCWlmICggZW1wdHkoICRzbHVnICkgKSB7CgkJCQkkc2x1ZyA9IFV0aWxzXGJhc2VuYW1lKCAkdGFyZ2V0X2RpciApOwoJCQl9CgkJfQoKCQlpZiAoIGVtcHR5KCAkc2x1ZyApIHx8IGVtcHR5KCAkdGFyZ2V0X2RpciApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiSW52YWxpZCB7JHR5cGV9IHNwZWNpZmllZC4iICk7CgkJfQoKCQkkbmFtZSAgICA9IHVjd29yZHMoIHN0cl9yZXBsYWNlKCAnLScsICcgJywgJHNsdWcgKSApOwoJCSRwYWNrYWdlID0gc3RyX3JlcGxhY2UoICcgJywgJ18nLCAkbmFtZSApOwoKCQkkdGVzdHNfZGlyID0gInskdGFyZ2V0X2Rpcn0vdGVzdHMiOwoJCSRiaW5fZGlyICAgPSAieyR0YXJnZXRfZGlyfS9iaW4iOwoKCQkkd3BfZmlsZXN5c3RlbS0+bWtkaXIoICR0ZXN0c19kaXIgKTsKCQkkd3BfZmlsZXN5c3RlbS0+bWtkaXIoICRiaW5fZGlyICk7CgoJCSR3cF92ZXJzaW9uc190b190ZXN0ID0gW107CgkJLy8gUGFyc2UgcGx1Z2luIHJlYWRtZS50eHQKCQlpZiAoIGZpbGVfZXhpc3RzKCAieyR0YXJnZXRfZGlyfS9yZWFkbWUudHh0IiApICkgewoJCQkkcmVhZG1lX2NvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cyggInskdGFyZ2V0X2Rpcn0vcmVhZG1lLnR4dCIgKTsKCgkJCXByZWdfbWF0Y2goICcvUmVxdWlyZXMgYXQgbGVhc3RcOiguKilcbi9tJywgJHJlYWRtZV9jb250ZW50LCAkbWF0Y2hlcyApOwoJCQlpZiAoIGlzc2V0KCAkbWF0Y2hlc1sxXSApICYmICRtYXRjaGVzWzFdICkgewoJCQkJJHdwX3ZlcnNpb25zX3RvX3Rlc3RbXSA9IHRyaW0oICRtYXRjaGVzWzFdICk7CgkJCX0KCQl9CgkJJHdwX3ZlcnNpb25zX3RvX3Rlc3RbXSA9ICdsYXRlc3QnOwoJCSR3cF92ZXJzaW9uc190b190ZXN0W10gPSAndHJ1bmsnOwoKCQkkdGVtcGxhdGVfZGF0YSA9IFsKCQkJInskdHlwZX1fc2x1ZyIgICAgPT4gJHNsdWcsCgkJCSJ7JHR5cGV9X3BhY2thZ2UiID0+ICRwYWNrYWdlLAoJCV07CgoJCSRmb3JjZSAgICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdmb3JjZScgKTsKCQkkZmlsZXNfdG9fY3JlYXRlID0gWwoJCQkieyR0ZXN0c19kaXJ9L2Jvb3RzdHJhcC5waHAiICAgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAieyR0eXBlfS1ib290c3RyYXAubXVzdGFjaGUiLCAkdGVtcGxhdGVfZGF0YSApLAoJCQkieyR0ZXN0c19kaXJ9L3Rlc3Qtc2FtcGxlLnBocCIgPT4gc2VsZjo6bXVzdGFjaGVfcmVuZGVyKCAieyR0eXBlfS10ZXN0LXNhbXBsZS5tdXN0YWNoZSIsICR0ZW1wbGF0ZV9kYXRhICksCgkJXTsKCQlpZiAoICd0cmF2aXMnID09PSAkYXNzb2NfYXJnc1snY2knXSApIHsKCQkJJGZpbGVzX3RvX2NyZWF0ZVsgInskdGFyZ2V0X2Rpcn0vLnRyYXZpcy55bWwiIF0gPSBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tdHJhdmlzLm11c3RhY2hlJywgY29tcGFjdCggJ3dwX3ZlcnNpb25zX3RvX3Rlc3QnICkgKTsKCQl9IGVsc2VpZiAoICdjaXJjbGUnID09PSAkYXNzb2NfYXJnc1snY2knXSApIHsKCQkJJGZpbGVzX3RvX2NyZWF0ZVsgInskdGFyZ2V0X2Rpcn0vLmNpcmNsZWNpL2NvbmZpZy55bWwiIF0gPSBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tY2lyY2xlLm11c3RhY2hlJywgY29tcGFjdCggJ3dwX3ZlcnNpb25zX3RvX3Rlc3QnICkgKTsKCQl9IGVsc2VpZiAoICdnaXRsYWInID09PSAkYXNzb2NfYXJnc1snY2knXSApIHsKCQkJJGZpbGVzX3RvX2NyZWF0ZVsgInskdGFyZ2V0X2Rpcn0vLmdpdGxhYi1jaS55bWwiIF0gPSBzZWxmOjptdXN0YWNoZV9yZW5kZXIoICdwbHVnaW4tZ2l0bGFiLm11c3RhY2hlJyApOwoJCX0gZWxzZWlmICggJ2JpdGJ1Y2tldCcgPT09ICRhc3NvY19hcmdzWydjaSddICkgewoJCQkkZmlsZXNfdG9fY3JlYXRlWyAieyR0YXJnZXRfZGlyfS9iaXRidWNrZXQtcGlwZWxpbmVzLnltbCIgXSA9IHNlbGY6Om11c3RhY2hlX3JlbmRlciggJ3BsdWdpbi1iaXRidWNrZXQubXVzdGFjaGUnICk7CgkJfQoKCQkkZmlsZXNfd3JpdHRlbiA9ICR0aGlzLT5jcmVhdGVfZmlsZXMoICRmaWxlc190b19jcmVhdGUsICRmb3JjZSApOwoKCQkkdG9fY29weSA9IFsKCQkJJ2luc3RhbGwtd3AtdGVzdHMuc2gnID0+ICRiaW5fZGlyLAoJCQkncGhwdW5pdC54bWwuZGlzdCcgICAgPT4gJHRhcmdldF9kaXIsCgkJCScucGhwY3MueG1sLmRpc3QnICAgICA9PiAkdGFyZ2V0X2RpciwKCQldOwoKCQlmb3JlYWNoICggJHRvX2NvcHkgYXMgJGZpbGUgPT4gJGRpciApIHsKCQkJJGZpbGVfbmFtZSAgICAgICAgID0gInskZGlyfS97JGZpbGV9IjsKCQkJJGZvcmNlICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICk7CgkJCSRzaG91bGRfd3JpdGVfZmlsZSA9ICR0aGlzLT5wcm9tcHRfaWZfZmlsZXNfd2lsbF9iZV9vdmVyd3JpdHRlbiggJGZpbGVfbmFtZSwgJGZvcmNlICk7CgkJCWlmICggISAkc2hvdWxkX3dyaXRlX2ZpbGUgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkZmlsZXNfd3JpdHRlbltdID0gJGZpbGVfbmFtZTsKCgkJCSR3cF9maWxlc3lzdGVtLT5jb3B5KCBzZWxmOjpnZXRfdGVtcGxhdGVfcGF0aCggJGZpbGUgKSwgJGZpbGVfbmFtZSwgdHJ1ZSApOwoJCQlpZiAoICdpbnN0YWxsLXdwLXRlc3RzLnNoJyA9PT0gJGZpbGUgKSB7CgkJCQlpZiAoICEgJHdwX2ZpbGVzeXN0ZW0tPmNobW9kKCAieyRkaXJ9L3skZmlsZX0iLCAwNzU1ICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGRuJ3QgbWFyayAnaW5zdGFsbC13cC10ZXN0cy5zaCcgYXMgZXhlY3V0YWJsZS4iICk7CgkJCQl9CgkJCX0KCQl9CgoJCSRza2lwX21lc3NhZ2UgICAgPSAnQWxsIHRlc3QgZmlsZXMgd2VyZSBza2lwcGVkLic7CgkJJHN1Y2Nlc3NfbWVzc2FnZSA9ICdDcmVhdGVkIHRlc3QgZmlsZXMuJzsKCQkkdGhpcy0+bG9nX3doZXRoZXJfZmlsZXNfd3JpdHRlbiggJGZpbGVzX3dyaXR0ZW4sICRza2lwX21lc3NhZ2UsICRzdWNjZXNzX21lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB0aGF0IHRoZSBgJHRhcmdldF9kaXJgIGlzIGEgY2hpbGQgZGlyZWN0b3J5IG9mIHRoZSBXUCB0aGVtZXMgb3IgcGx1Z2lucyBkaXJlY3RvcnksIGRlcGVuZGluZyBvbiBgJHR5cGVgLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgICAgICAgInRoZW1lIiBvciAicGx1Z2luIgoJICogQHBhcmFtIHN0cmluZyAkdGFyZ2V0X2RpciBUaGUgdGhlbWUvcGx1Z2luIGRpcmVjdG9yeSB0byBjaGVjay4KCSAqCgkgKiBAcmV0dXJuIG51bGx8c3RyaW5nIFJldHVybnMgbnVsbCBvbiBzdWNjZXNzLCBlcnJvciBtZXNzYWdlIG9uIGVycm9yLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX3RhcmdldF9kaXJlY3RvcnkoICR0eXBlLCAkdGFyZ2V0X2RpciApIHsKCQkkcGFyZW50X2RpciA9IGRpcm5hbWUoIHNlbGY6OmNhbm9uaWNhbGl6ZV9wYXRoKCBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCAkdGFyZ2V0X2RpciApICkgKTsKCgkJaWYgKCAndGhlbWUnID09PSAkdHlwZSAmJiBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCBXUF9DT05URU5UX0RJUiAuICcvdGhlbWVzJyApICE9PSAkcGFyZW50X2RpciApIHsKCQkJcmV0dXJuIHNwcmludGYoICdUaGUgdGFyZ2V0IGRpcmVjdG9yeSBcJyUxJHNcJyBpcyBub3QgaW4gXCclMiRzXCcuJywgJHRhcmdldF9kaXIsIFdQX0NPTlRFTlRfRElSIC4gJy90aGVtZXMnICk7CgkJfQoKCQlpZiAoICdwbHVnaW4nID09PSAkdHlwZSAmJiBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCBXUF9QTFVHSU5fRElSICkgIT09ICRwYXJlbnRfZGlyICkgewoJCQlyZXR1cm4gc3ByaW50ZiggJ1RoZSB0YXJnZXQgZGlyZWN0b3J5IFwnJTEkc1wnIGlzIG5vdCBpbiBcJyUyJHNcJy4nLCAkdGFyZ2V0X2RpciwgV1BfUExVR0lOX0RJUiApOwoJCX0KCgkJLy8gU3VjY2Vzcy4KCQlyZXR1cm4gbnVsbDsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gY3JlYXRlX2ZpbGVzKCAkZmlsZXNfYW5kX2NvbnRlbnRzLCAkZm9yY2UgKSB7CgkJJHdwX2ZpbGVzeXN0ZW0gPSAkdGhpcy0+aW5pdF93cF9maWxlc3lzdGVtKCk7CgkJJHdyb3RlX2ZpbGVzICAgPSBbXTsKCgkJZm9yZWFjaCAoICRmaWxlc19hbmRfY29udGVudHMgYXMgJGZpbGVuYW1lID0+ICRjb250ZW50cyApIHsKCQkJJHNob3VsZF93cml0ZV9maWxlID0gJHRoaXMtPnByb21wdF9pZl9maWxlc193aWxsX2JlX292ZXJ3cml0dGVuKCAkZmlsZW5hbWUsICRmb3JjZSApOwoJCQlpZiAoICEgJHNob3VsZF93cml0ZV9maWxlICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSR3cF9maWxlc3lzdGVtLT5ta2RpciggZGlybmFtZSggJGZpbGVuYW1lICkgKTsKCgkJCWlmICggISAkd3BfZmlsZXN5c3RlbS0+cHV0X2NvbnRlbnRzKCAkZmlsZW5hbWUsICRjb250ZW50cyApICkgewoJCQkJV1BfQ0xJOjplcnJvciggIkVycm9yIGNyZWF0aW5nIGZpbGU6IHskZmlsZW5hbWV9IiApOwoJCQl9IGVsc2VpZiAoICRzaG91bGRfd3JpdGVfZmlsZSApIHsKCQkJCSR3cm90ZV9maWxlc1tdID0gJGZpbGVuYW1lOwoJCQl9CgkJfQoJCXJldHVybiAkd3JvdGVfZmlsZXM7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIHByb21wdF9pZl9maWxlc193aWxsX2JlX292ZXJ3cml0dGVuKCAkZmlsZW5hbWUsICRmb3JjZSApIHsKCQkkc2hvdWxkX3dyaXRlX2ZpbGUgPSB0cnVlOwoJCWlmICggISBmaWxlX2V4aXN0cyggJGZpbGVuYW1lICkgKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJV1BfQ0xJOjp3YXJuaW5nKCAnRmlsZSBhbHJlYWR5IGV4aXN0cy4nICk7CgkJV1BfQ0xJOjpsb2coICRmaWxlbmFtZSApOwoJCWlmICggISAkZm9yY2UgKSB7CgkJCWRvIHsKCQkJCSRhbnN3ZXIgICAgICA9IGNsaVxwcm9tcHQoCgkJCQkJJ1NraXAgdGhpcyBmaWxlLCBvciByZXBsYWNlIGl0IHdpdGggc2NhZmZvbGRpbmc/JywKCQkJCQkkZGVmYXVsdCA9IGZhbHNlLAoJCQkJCSRtYXJrZXIgID0gJ1tzL3JdOiAnCgkJCQkpOwoJCQl9IHdoaWxlICggISBpbl9hcnJheSggJGFuc3dlciwgWyAncycsICdyJyBdLCB0cnVlICkgKTsKCQkJJHNob3VsZF93cml0ZV9maWxlID0gJ3InID09PSAkYW5zd2VyOwoJCX0KCgkJJG91dGNvbWUgPSAkc2hvdWxkX3dyaXRlX2ZpbGUgPyAnUmVwbGFjaW5nJyA6ICdTa2lwcGluZyc7CgkJV1BfQ0xJOjpsb2coICRvdXRjb21lIC4gUEhQX0VPTCApOwoKCQlyZXR1cm4gJHNob3VsZF93cml0ZV9maWxlOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBsb2dfd2hldGhlcl9maWxlc193cml0dGVuKCAkZmlsZXNfd3JpdHRlbiwgJHNraXBfbWVzc2FnZSwgJHN1Y2Nlc3NfbWVzc2FnZSApIHsKCQlpZiAoIGVtcHR5KCAkZmlsZXNfd3JpdHRlbiApICkgewoJCQlXUF9DTEk6OmxvZyggJHNraXBfbWVzc2FnZSApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJHN1Y2Nlc3NfbWVzc2FnZSApOwoJCX0KCX0KCgkvKioKCSAqIEV4dHJhY3RzIGRhc2hpY29uIG5hbWUgd2hlbiBwcm92aWRlZCBvciByZXR1cm4gbnVsbCBvdGhlcndpc2UuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzCgkgKiBAcmV0dXJuIHN0cmluZ3xudWxsCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZXh0cmFjdF9kYXNoaWNvbiggJGFzc29jX2FyZ3MgKSB7CgkJJGRhc2hpY29uID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZGFzaGljb24nICk7CgkJaWYgKCAhICRkYXNoaWNvbiApIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoJCXJldHVybiBwcmVnX3JlcGxhY2UoICcvZGFzaGljb24oLXxzLSkvJywgJycsICRkYXNoaWNvbiApOwoJfQoKCS8qKgoJICogSWYgeW91J3JlIHdyaXRpbmcgeW91ciBmaWxlcyB0byB5b3VyIHRoZW1lIGRpcmVjdG9yeSB5b3VyIHRleHRkb21haW4gYWxzbyBuZWVkcyB0byBiZSB0aGUgc2FtZSBhcyB5b3VyIHRoZW1lLgoJICogU2FtZSBnb2VzIGZvciB3aGVuIHBsdWdpbiBpcyBiZWluZyB1c2VkLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF90ZXh0ZG9tYWluKCAkdGV4dGRvbWFpbiwgJGFyZ3MgKSB7CgkJaWYgKCBzdHJsZW4oICR0ZXh0ZG9tYWluICkgKSB7CgkJCXJldHVybiAkdGV4dGRvbWFpbjsKCQl9CgoJCWlmICggJGFyZ3NbJ3RoZW1lJ10gKSB7CgkJCXJldHVybiAkdGhpcy0+Z2V0X3RoZW1lX25hbWUoICRhcmdzWyd0aGVtZSddICk7CgkJfQoKCQlpZiAoICRhcmdzWydwbHVnaW4nXSAmJiB0cnVlICE9PSAkYXJnc1sncGx1Z2luJ10gKSB7CgkJCXJldHVybiAkYXJnc1sncGx1Z2luJ107CgkJfQoKCQlyZXR1cm4gJ1lPVVItVEVYVERPTUFJTic7Cgl9CgoJLyoqCgkgKiBHZW5lcmF0ZXMgdGhlIG1hY2hpbmUgbmFtZSBmb3IgZnVuY3Rpb24gZGVjbGFyYXRpb25zLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHNsdWcgU2x1ZyBuYW1lIHRvIGNvbnZlcnQuCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdlbmVyYXRlX21hY2hpbmVfbmFtZSggJHNsdWcgKSB7CgkJcmV0dXJuIHN0cl9yZXBsYWNlKCAnLScsICdfJywgJHNsdWcgKTsKCX0KCgkvKioKCSAqIFBsdXJhbGl6ZXMgYSBub3VuLgoJICoKCSAqIEBzZWUgICAgSW5mbGVjdG9yOjpwbHVyYWxpemUoKQoJICogQHBhcmFtICBzdHJpbmcgJHdvcmQgV29yZCB0byBiZSBwbHVyYWxpemVkLgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwbHVyYWxpemUoICR3b3JkICkgewoJCXJldHVybiBJbmZsZWN0b3I6OnBsdXJhbGl6ZSggJHdvcmQgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gZXh0cmFjdF9hcmdzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRzICkgewoJCSRvdXQgPSBbXTsKCgkJZm9yZWFjaCAoICRkZWZhdWx0cyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJJG91dFsgJGtleSBdID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAka2V5LCAkdmFsdWUgKTsKCQl9CgoJCXJldHVybiAkb3V0OwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBxdW90ZV9jb21tYV9saXN0X2VsZW1lbnRzKCAkY29tbWFfbGlzdCApIHsKCQlyZXR1cm4gIiciIC4gaW1wbG9kZSggIicsICciLCBleHBsb2RlKCAnLCcsICRjb21tYV9saXN0ICkgKSAuICInIjsKCX0KCgkvKioKCSAqIENyZWF0ZXMgdGhlIHRoZW1lcyBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gbWF5YmVfY3JlYXRlX3RoZW1lc19kaXIoKSB7CgoJCSR0aGVtZXNfZGlyID0gV1BfQ09OVEVOVF9ESVIgLiAnL3RoZW1lcyc7CgkJaWYgKCAhIGlzX2RpciggJHRoZW1lc19kaXIgKSApIHsKCQkJd3BfbWtkaXJfcCggJHRoZW1lc19kaXIgKTsKCQl9CgoJfQoKCS8qKgoJICogQ3JlYXRlcyB0aGUgcGx1Z2lucyBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gbWF5YmVfY3JlYXRlX3BsdWdpbnNfZGlyKCkgewoKCQlpZiAoICEgaXNfZGlyKCBXUF9QTFVHSU5fRElSICkgKSB7CgkJCXdwX21rZGlyX3AoIFdQX1BMVUdJTl9ESVIgKTsKCQl9CgoJfQoKCS8qKgoJICogSW5pdGlhbGl6ZXMgV1BfRmlsZXN5c3RlbS4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGluaXRfd3BfZmlsZXN5c3RlbSgpIHsKCQlnbG9iYWwgJHdwX2ZpbGVzeXN0ZW07CgkJV1BfRmlsZXN5c3RlbSgpOwoKCQlyZXR1cm4gJHdwX2ZpbGVzeXN0ZW07Cgl9CgoJLyoqCgkgKiBMb2NhbGl6ZXMgdGhlIHRlbXBsYXRlIHBhdGguCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIG11c3RhY2hlX3JlbmRlciggJHRlbXBsYXRlLCAkZGF0YSA9IFtdICkgewoJCXJldHVybiBVdGlsc1xtdXN0YWNoZV9yZW5kZXIoIGRpcm5hbWUoIGRpcm5hbWUoIF9fRklMRV9fICkgKSAuICIvdGVtcGxhdGVzL3skdGVtcGxhdGV9IiwgJGRhdGEgKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHRlbXBsYXRlIHBhdGggYmFzZWQgb24gaW5zdGFsbGF0aW9uIHR5cGUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF90ZW1wbGF0ZV9wYXRoKCAkdGVtcGxhdGUgKSB7CgkJJGNvbW1hbmRfcm9vdCAgPSBVdGlsc1xwaGFyX3NhZmVfcGF0aCggZGlybmFtZSggX19ESVJfXyApICk7CgkJJHRlbXBsYXRlX3BhdGggPSAieyRjb21tYW5kX3Jvb3R9L3RlbXBsYXRlcy97JHRlbXBsYXRlfSI7CgoJCWlmICggISBmaWxlX2V4aXN0cyggJHRlbXBsYXRlX3BhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGZpbmQgeyR0ZW1wbGF0ZX0iICk7CgkJfQoKCQlyZXR1cm4gJHRlbXBsYXRlX3BhdGg7Cgl9CgoJLyoKCSAqIFJldHVybnMgdGhlIGNhbm9uaWNhbGl6ZWQgcGF0aCwgd2l0aCBkb3QgYW5kIGRvdWJsZSBkb3Qgc2VnbWVudHMgcmVzb2x2ZWQuCgkgKgoJICogQ29waWVkIGZyb20gU3ltZm9ueVxDb21wb25lbnRcRG9tQ3Jhd2xlclxBYnN0cmFjdFVyaUVsZW1lbnQ6OmNhbm9uaWNhbGl6ZVBhdGgoKS4KCSAqIEltcGxlbWVudHMgUkZDIDM5ODYsIHNlY3Rpb24gNS4yLjQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBUaGUgcGF0aCB0byBtYWtlIGNhbm9uaWNhbC4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgY2Fub25pY2FsaXplZCBwYXRoLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBjYW5vbmljYWxpemVfcGF0aCggJHBhdGggKSB7CgkJaWYgKCAnJyA9PT0gJHBhdGggfHwgJy8nID09PSAkcGF0aCApIHsKCQkJcmV0dXJuICRwYXRoOwoJCX0KCgkJaWYgKCAnLicgPT09IHN1YnN0ciggJHBhdGgsIC0xICkgKSB7CgkJCSRwYXRoIC49ICcvJzsKCQl9CgoJCSRvdXRwdXQgPSBbXTsKCgkJZm9yZWFjaCAoIGV4cGxvZGUoICcvJywgJHBhdGggKSBhcyAkc2VnbWVudCApIHsKCQkJaWYgKCAnLi4nID09PSAkc2VnbWVudCApIHsKCQkJCWFycmF5X3BvcCggJG91dHB1dCApOwoJCQl9IGVsc2VpZiAoICcuJyAhPT0gJHNlZ21lbnQgKSB7CgkJCQkkb3V0cHV0W10gPSAkc2VnbWVudDsKCQkJfQoJCX0KCgkJcmV0dXJuIGltcGxvZGUoICcvJywgJG91dHB1dCApOwoJfQoKCS8qKgoJICogR2V0cyBhbiBhY3RpdmUgdGhlbWUncyBuYW1lIHdoZW4gdHJ1ZSBwcm92aWRlZCBvciB0aGUgc2FtZSBuYW1lIG90aGVyd2lzZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGJvb2wgJHRoZW1lIFRoZW1lIG5hbWUgb3IgdHJ1ZS4KCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3RoZW1lX25hbWUoICR0aGVtZSApIHsKCQlpZiAoIHRydWUgPT09ICR0aGVtZSApIHsKCQkJJHRoZW1lID0gd3BfZ2V0X3RoZW1lKCktPnRlbXBsYXRlOwoJCX0KCQlyZXR1cm4gc3RydG9sb3dlciggJHRoZW1lICk7Cgl9Cn0KPD9waHAKCi8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEZ1bmN0aW9uRm91bmQgLS0gUmVuYW1pbmcgYnJlYWtzIFBoYXIgY29tcGF0LgpmdW5jdGlvbiB3cF9leHBvcnQoICRhcmdzID0gYXJyYXkoKSApIHsKCSRkZWZhdWx0cyAgICAgPSBhcnJheSgKCQknZmlsdGVycycgICAgID0+IGFycmF5KCksCgkJJ2Zvcm1hdCcgICAgICA9PiAnV1BfRXhwb3J0X1dYUl9Gb3JtYXR0ZXInLAoJCSd3cml0ZXInICAgICAgPT4gJ1dQX0V4cG9ydF9SZXR1cm5lcicsCgkJJ3dyaXRlcl9hcmdzJyA9PiBudWxsLAoJKTsKCSRhcmdzICAgICAgICAgPSB3cF9wYXJzZV9hcmdzKCAkYXJncywgJGRlZmF1bHRzICk7CgkkZXhwb3J0X3F1ZXJ5ID0gbmV3IFdQX0V4cG9ydF9RdWVyeSggJGFyZ3NbJ2ZpbHRlcnMnXSApOwoJJGZvcm1hdHRlciAgICA9IG5ldyAkYXJnc1snZm9ybWF0J10oICRleHBvcnRfcXVlcnkgKTsKCSR3cml0ZXIgICAgICAgPSBuZXcgJGFyZ3NbJ3dyaXRlciddKCAkZm9ybWF0dGVyLCAkYXJnc1snd3JpdGVyX2FyZ3MnXSApOwoJdHJ5IHsKCQlyZXR1cm4gJHdyaXRlci0+ZXhwb3J0KCk7Cgl9IGNhdGNoICggV1BfRXhwb3J0X0V4Y2VwdGlvbiAkZSApIHsKCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnd3AtZXhwb3J0LWVycm9yJywgJGUtPmdldE1lc3NhZ2UoKSApOwoJfQp9CgovLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRGdW5jdGlvbkZvdW5kLFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZEZ1bmN0aW9uTmFtZS5GdW5jdGlvbk5hbWVJbnZhbGlkIC0tIFJlbmFtaW5nIGJyZWFrcyBQaGFyIGNvbXBhdC4KZnVuY3Rpb24gX3dwX2V4cG9ydF9idWlsZF9JTl9jb25kaXRpb24oICRjb2x1bW5fbmFtZSwgJHZhbHVlcywgJGZvcm1hdCA9ICclcycgKSB7CglnbG9iYWwgJHdwZGI7CgoJaWYgKCAhIGlzX2FycmF5KCAkdmFsdWVzICkgfHwgZW1wdHkoICR2YWx1ZXMgKSApIHsKCQlyZXR1cm4gJyc7Cgl9CgkkZm9ybWF0cyA9IGltcGxvZGUoICcsICcsIGFycmF5X2ZpbGwoIDAsIGNvdW50KCAkdmFsdWVzICksICRmb3JtYXQgKSApOwoJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCxXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUxQbGFjZWhvbGRlcnMuVW5maW5pc2hlZFByZXBhcmUgLS0gJGNvbHVtbl9uYW1lX3NxbCBlc2NhcGVkIGFzIGlkZW50LCAkZm9ybWF0cyBoYXJkY29kZWQgdmFsdWUuCglyZXR1cm4gJHdwZGItPnByZXBhcmUoICJ7JGNvbHVtbl9uYW1lfSBJTiAoeyRmb3JtYXRzfSkiLCAkdmFsdWVzICk7Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9leHBvcnRfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfZXhwb3J0X2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfZXhwb3J0X2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdleHBvcnQnLCAnRXhwb3J0X0NvbW1hbmQnICk7Cjw/cGhwCgpjbGFzcyBXUF9Qb3N0X0lEc19JdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yIHsKCXByaXZhdGUgJGxpbWl0ID0gMTAwOwoJcHJpdmF0ZSAkcG9zdF9pZHM7Cglwcml2YXRlICRpZHNfbGVmdDsKCXByaXZhdGUgJHJlc3VsdHMgPSBhcnJheSgpOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJHBvc3RfaWRzLCAkbGltaXQgPSBudWxsICkgewoJCSR0aGlzLT5kYiAgICAgICA9ICRHTE9CQUxTWyd3cGRiJ107CgkJJHRoaXMtPnBvc3RfaWRzID0gJHBvc3RfaWRzOwoJCSR0aGlzLT5pZHNfbGVmdCA9ICRwb3N0X2lkczsKCQlpZiAoICEgaXNfbnVsbCggJGxpbWl0ICkgKSB7CgkJCSR0aGlzLT5saW1pdCA9ICRsaW1pdDsKCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJcmV0dXJuICR0aGlzLT5yZXN1bHRzWyAkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cyBdOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBrZXkoKSB7CgkJcmV0dXJuICR0aGlzLT5nbG9iYWxfaW5kZXg7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG5leHQoKSB7CgkJJHRoaXMtPmluZGV4X2luX3Jlc3VsdHMrKzsKCQkkdGhpcy0+Z2xvYmFsX2luZGV4Kys7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHJld2luZCgpIHsKCQkkdGhpcy0+cmVzdWx0cyAgICAgICAgICA9IGFycmF5KCk7CgkJJHRoaXMtPmdsb2JhbF9pbmRleCAgICAgPSAwOwoJCSR0aGlzLT5pbmRleF9pbl9yZXN1bHRzID0gMDsKCQkkdGhpcy0+aWRzX2xlZnQgICAgICAgICA9ICR0aGlzLT5wb3N0X2lkczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKSB7CgkJaWYgKCBpc3NldCggJHRoaXMtPnJlc3VsdHNbICR0aGlzLT5pbmRleF9pbl9yZXN1bHRzIF0gKSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCWlmICggZW1wdHkoICR0aGlzLT5pZHNfbGVmdCApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSRoYXNfcG9zdHMgPSAkdGhpcy0+bG9hZF9uZXh0X3Bvc3RzX2Zyb21fZGIoKTsKCQlpZiAoICEgJGhhc19wb3N0cyApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkdGhpcy0+aW5kZXhfaW5fcmVzdWx0cyA9IDA7CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBsb2FkX25leHRfcG9zdHNfZnJvbV9kYigpIHsKCQkkbmV4dF9iYXRjaF9wb3N0X2lkcyA9IGFycmF5X3NwbGljZSggJHRoaXMtPmlkc19sZWZ0LCAwLCAkdGhpcy0+bGltaXQgKTsKCQkkaW5fcG9zdF9pZHNfc3FsICAgICA9IF93cF9leHBvcnRfYnVpbGRfSU5fY29uZGl0aW9uKCAnSUQnLCAkbmV4dF9iYXRjaF9wb3N0X2lkcyApOwoJCSR0aGlzLT5yZXN1bHRzICAgICAgID0gJHRoaXMtPmRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCAqIEZST00geyR0aGlzLT5kYi0+cG9zdHN9IFdIRVJFIHskaW5fcG9zdF9pZHNfc3FsfSIgKTsKCQlpZiAoICEgJHRoaXMtPnJlc3VsdHMgKSB7CgkJCWlmICggJHRoaXMtPmRiLT5sYXN0X2Vycm9yICkgewoJCQkJdGhyb3cgbmV3IFdQX0l0ZXJhdG9yX0V4Y2VwdGlvbiggIkRhdGFiYXNlIGVycm9yOiB7JHRoaXMtPmRiLT5sYXN0X2Vycm9yfSIgKTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKY2xhc3MgV1BfRXhwb3J0X0ZpbGVfV3JpdGVyIGV4dGVuZHMgV1BfRXhwb3J0X0Jhc2VfV3JpdGVyIHsKCXByaXZhdGUgJGY7Cglwcml2YXRlICRmaWxlX25hbWU7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZm9ybWF0dGVyLCAkZmlsZV9uYW1lICkgewoJCXBhcmVudDo6X19jb25zdHJ1Y3QoICRmb3JtYXR0ZXIgKTsKCQkkdGhpcy0+ZmlsZV9uYW1lID0gJGZpbGVfbmFtZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCkgewoJCSR0aGlzLT5mID0gZm9wZW4oICR0aGlzLT5maWxlX25hbWUsICd3JyApOwoJCWlmICggISAkdGhpcy0+ZiApIHsKCQkJdGhyb3cgbmV3IFdQX0V4cG9ydF9FeGNlcHRpb24oICJXUCBFeHBvcnQ6IGVycm9yIG9wZW5pbmcgeyR0aGlzLT5maWxlX25hbWV9IGZvciB3cml0aW5nLiIgKTsKCQl9CgoJCXRyeSB7CgkJCXBhcmVudDo6ZXhwb3J0KCk7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9FeGNlcHRpb24gJGUgKSB7CgkJCWZjbG9zZSggJHRoaXMtPmYgKTsKCQkJdGhyb3cgJGU7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9UZXJtX0V4Y2VwdGlvbiAkZSApIHsKCQkJZmNsb3NlKCAkdGhpcy0+ZiApOwoJCQl0aHJvdyAkZTsKCQl9CgoJCWZjbG9zZSggJHRoaXMtPmYgKTsKCX0KCglwcm90ZWN0ZWQgZnVuY3Rpb24gd3JpdGUoICR4bWwgKSB7CgkJJHJlcyA9IGZ3cml0ZSggJHRoaXMtPmYsICR4bWwgKTsKCQlpZiAoIGZhbHNlID09PSAkcmVzICkgewoJCQl0aHJvdyBuZXcgV1BfRXhwb3J0X0V4Y2VwdGlvbiggJ1dQIEV4cG9ydDogZXJyb3Igd3JpdGluZyB0byBleHBvcnQgZmlsZS4nICk7CgkJfQoJfQp9Cjw/cGhwCgpjbGFzcyBXUF9FeHBvcnRfRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Cn0KPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogUmVwcmVzZW50cyBhIHNldCBvZiBwb3N0cyBhbmQgb3RoZXIgc2l0ZSBkYXRhIHRvIGJlIGV4cG9ydGVkLgogKgogKiBBbiBpbW11dGFibGUgb2JqZWN0LCB3aGljaCBnYXRoZXJzIGFsbCBkYXRhIG5lZWRlZCBmb3IgdGhlIGV4cG9ydC4KICovCmNsYXNzIFdQX0V4cG9ydF9RdWVyeSB7Cgljb25zdCBRVUVSWV9DSFVOSyA9IDEwMDsKCglwcml2YXRlIHN0YXRpYyAkZGVmYXVsdHMgPSBbCgkJJ3Bvc3RfaWRzJyAgICAgID0+IG51bGwsCgkJJ3Bvc3RfdHlwZScgICAgID0+IG51bGwsCgkJJ3N0YXR1cycgICAgICAgID0+IG51bGwsCgkJJ2F1dGhvcicgICAgICAgID0+IG51bGwsCgkJJ3N0YXJ0X2RhdGUnICAgID0+IG51bGwsCgkJJ2VuZF9kYXRlJyAgICAgID0+IG51bGwsCgkJJ3N0YXJ0X2lkJyAgICAgID0+IG51bGwsCgkJJ21heF9udW1fcG9zdHMnID0+IG51bGwsCgkJJ2NhdGVnb3J5JyAgICAgID0+IG51bGwsCgldOwoKCXByaXZhdGUgJHBvc3RfaWRzOwoJcHJpdmF0ZSAkZmlsdGVyczsKCglwcml2YXRlICR3aGVyZXMgPSBbXTsKCXByaXZhdGUgJGpvaW5zICA9IFtdOwoKCXByaXZhdGUgJGF1dGhvcjsKCXByaXZhdGUgJGNhdGVnb3J5OwoKCXB1YmxpYyAkbWlzc2luZ19wYXJlbnRzID0gZmFsc2U7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZmlsdGVycyA9IFtdICkgewoJCSR0aGlzLT5maWx0ZXJzICA9IHdwX3BhcnNlX2FyZ3MoICRmaWx0ZXJzLCBzZWxmOjokZGVmYXVsdHMgKTsKCQkkdGhpcy0+cG9zdF9pZHMgPSAkdGhpcy0+Y2FsY3VsYXRlX3Bvc3RfaWRzKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHBvc3RfaWRzKCkgewoJCXJldHVybiAkdGhpcy0+cG9zdF9pZHM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNoYXJzZXQoKSB7CgkJcmV0dXJuIGdldF9ibG9naW5mbyggJ2NoYXJzZXQnICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHNpdGVfbWV0YWRhdGEoKSB7CgkJJG1ldGFkYXRhID0gWwoJCQknbmFtZScgICAgICAgID0+ICR0aGlzLT5ibG9naW5mb19yc3MoICduYW1lJyApLAoJCQkndXJsJyAgICAgICAgID0+ICR0aGlzLT5ibG9naW5mb19yc3MoICd1cmwnICksCgkJCSdsYW5ndWFnZScgICAgPT4gJHRoaXMtPmJsb2dpbmZvX3JzcyggJ2xhbmd1YWdlJyApLAoJCQknZGVzY3JpcHRpb24nID0+ICR0aGlzLT5ibG9naW5mb19yc3MoICdkZXNjcmlwdGlvbicgKSwKCQkJJ3B1YkRhdGUnICAgICA9PiBkYXRlKCAnRCwgZCBNIFkgSDppOnMgKzAwMDAnICksIC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkJJ3NpdGVfdXJsJyAgICA9PiBpc19tdWx0aXNpdGUoKSA/IG5ldHdvcmtfaG9tZV91cmwoKSA6ICR0aGlzLT5ibG9naW5mb19yc3MoICd1cmwnICksCgkJCSdibG9nX3VybCcgICAgPT4gJHRoaXMtPmJsb2dpbmZvX3JzcyggJ3VybCcgKSwKCQldOwoJCXJldHVybiAkbWV0YWRhdGE7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHdwX2dlbmVyYXRvcl90YWcoKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQlyZXR1cm4gYXBwbHlfZmlsdGVycyggJ3RoZV9nZW5lcmF0b3InLCBnZXRfdGhlX2dlbmVyYXRvciggJ2V4cG9ydCcgKSwgJ2V4cG9ydCcgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gYXV0aG9ycygpIHsKCQlnbG9iYWwgJHdwZGI7CgkJJGF1dGhvcnMgICAgPSBbXTsKCQkkYXV0aG9yX2lkcyA9IChhcnJheSkgJHdwZGItPmdldF9jb2woICJTRUxFQ1QgRElTVElOQ1QgcG9zdF9hdXRob3IgRlJPTSAkd3BkYi0+cG9zdHMgV0hFUkUgcG9zdF9zdGF0dXMgIT0gJ2F1dG8tZHJhZnQnIiApOwoJCWZvcmVhY2ggKCAkYXV0aG9yX2lkcyBhcyAkYXV0aG9yX2lkICkgewoJCQkkYXV0aG9yc1tdID0gZ2V0X3VzZXJkYXRhKCAkYXV0aG9yX2lkICk7CgkJfQoJCSRhdXRob3JzID0gYXJyYXlfZmlsdGVyKCAkYXV0aG9ycyApOwoJCXJldHVybiAkYXV0aG9yczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY2F0ZWdvcmllcygpIHsKCQlpZiAoICR0aGlzLT5jYXRlZ29yeSApIHsKCQkJcmV0dXJuIFsgJHRoaXMtPmNhdGVnb3J5IF07CgkJfQoJCWlmICggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddICkgewoJCQlyZXR1cm4gW107CgkJfQoJCSRjYXRlZ29yaWVzID0gKGFycmF5KSBnZXRfY2F0ZWdvcmllcyggWyAnZ2V0JyA9PiAnYWxsJyBdICk7CgoJCSR0aGlzLT5jaGVja19mb3Jfb3JwaGFuZWRfdGVybXMoICRjYXRlZ29yaWVzICk7CgoJCSRjYXRlZ29yaWVzID0gc2VsZjo6dG9wb2xvZ2ljYWxseV9zb3J0X3Rlcm1zKCAkY2F0ZWdvcmllcyApOwoKCQlyZXR1cm4gJGNhdGVnb3JpZXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHRhZ3MoKSB7CgkJaWYgKCAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gKSB7CgkJCXJldHVybiBbXTsKCQl9CgkJJHRhZ3MgPSAoYXJyYXkpIGdldF90YWdzKCBbICdnZXQnID0+ICdhbGwnIF0gKTsKCgkJJHRoaXMtPmNoZWNrX2Zvcl9vcnBoYW5lZF90ZXJtcyggJHRhZ3MgKTsKCgkJcmV0dXJuICR0YWdzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjdXN0b21fdGF4b25vbWllc190ZXJtcygpIHsKCQlpZiAoICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCQkkY3VzdG9tX3RheG9ub21pZXMgPSBnZXRfdGF4b25vbWllcyggWyAnX2J1aWx0aW4nID0+IGZhbHNlIF0gKTsKCQkkY3VzdG9tX3Rlcm1zICAgICAgPSAoYXJyYXkpIGdldF90ZXJtcyggJGN1c3RvbV90YXhvbm9taWVzLCBbICdnZXQnID0+ICdhbGwnIF0gKTsKCQkkdGhpcy0+Y2hlY2tfZm9yX29ycGhhbmVkX3Rlcm1zKCAkY3VzdG9tX3Rlcm1zICk7CgkJJGN1c3RvbV90ZXJtcyA9IHNlbGY6OnRvcG9sb2dpY2FsbHlfc29ydF90ZXJtcyggJGN1c3RvbV90ZXJtcyApOwoJCXJldHVybiAkY3VzdG9tX3Rlcm1zOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBuYXZfbWVudV90ZXJtcygpIHsKCQkkbmF2X21lbnVzID0gd3BfZ2V0X25hdl9tZW51cygpOwoJCWZvcmVhY2ggKCAkbmF2X21lbnVzIGFzICR0ZXJtICkgewoJCQkkdGVybS0+ZGVzY3JpcHRpb24gPSAnJzsKCQl9CgkJcmV0dXJuICRuYXZfbWVudXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydGlmeV9wb3N0KCAkcG9zdCApIHsKCQkkR0xPQkFMU1snd3BfcXVlcnknXS0+aW5fdGhlX2xvb3AgPSB0cnVlOwoJCSRwcmV2aW91c19nbG9iYWxfcG9zdCAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkR0xPQkFMUywgJ3Bvc3QnICk7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkIC0tIFRlbXBvcmFyeSBvdmVycmlkZS4KCQkkR0xPQkFMU1sncG9zdCddID0gJHBvc3Q7CgkJc2V0dXBfcG9zdGRhdGEoICRwb3N0ICk7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQkkcG9zdC0+cG9zdF9jb250ZW50ID0gYXBwbHlfZmlsdGVycyggJ3RoZV9jb250ZW50X2V4cG9ydCcsICRwb3N0LT5wb3N0X2NvbnRlbnQgKTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCSRwb3N0LT5wb3N0X2V4Y2VycHQgPSBhcHBseV9maWx0ZXJzKCAndGhlX2V4Y2VycHRfZXhwb3J0JywgJHBvc3QtPnBvc3RfZXhjZXJwdCApOwoJCSRwb3N0LT5pc19zdGlja3kgICAgPSBpc19zdGlja3koICRwb3N0LT5JRCApID8gMSA6IDA7CgkJJHBvc3QtPnRlcm1zICAgICAgICA9IHNlbGY6OmdldF90ZXJtc19mb3JfcG9zdCggJHBvc3QgKTsKCQkkcG9zdC0+bWV0YSAgICAgICAgID0gc2VsZjo6Z2V0X21ldGFfZm9yX3Bvc3QoICRwb3N0ICk7CgkJJHBvc3QtPmNvbW1lbnRzICAgICA9ICR0aGlzLT5nZXRfY29tbWVudHNfZm9yX3Bvc3QoICRwb3N0ICk7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkIC0tIFJldmVydCBiYWNrIHRvIG9yaWdpbmFsLgoJCSRHTE9CQUxTWydwb3N0J10gPSAkcHJldmlvdXNfZ2xvYmFsX3Bvc3Q7CgkJcmV0dXJuICRwb3N0OwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBwb3N0cygpIHsKCQkkcG9zdHNfaXRlcmF0b3IgPSBuZXcgV1BfUG9zdF9JRHNfSXRlcmF0b3IoICR0aGlzLT5wb3N0X2lkcywgc2VsZjo6UVVFUllfQ0hVTksgKTsKCQlyZXR1cm4gbmV3IFdQX01hcF9JdGVyYXRvciggJHBvc3RzX2l0ZXJhdG9yLCBbICR0aGlzLCAnZXhwb3J0aWZ5X3Bvc3QnIF0gKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNhbGN1bGF0ZV9wb3N0X2lkcygpIHsKCQlnbG9iYWwgJHdwZGI7CgkJaWYgKCBpc19hcnJheSggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfaWRzJ10gKSApIHsKCQkJaWYgKCAkdGhpcy0+ZmlsdGVyc1snd2l0aF9hdHRhY2htZW50cyddICkgewoJCQkJJGF0dGFjaG1lbnRfcG9zdF9pZHMgICAgICAgPSAkdGhpcy0+aW5jbHVkZV9hdHRhY2htZW50X2lkcyggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfaWRzJ10gKTsKCQkJCSR0aGlzLT5maWx0ZXJzWydwb3N0X2lkcyddID0gYXJyYXlfbWVyZ2UoICR0aGlzLT5maWx0ZXJzWydwb3N0X2lkcyddLCAkYXR0YWNobWVudF9wb3N0X2lkcyApOwoJCQl9CgkJCXJldHVybiAkdGhpcy0+ZmlsdGVyc1sncG9zdF9pZHMnXTsKCQl9CgkJJHRoaXMtPnBvc3RfdHlwZV93aGVyZSgpOwoJCSR0aGlzLT5zdGF0dXNfd2hlcmUoKTsKCQkkdGhpcy0+YXV0aG9yX3doZXJlKCk7CgkJJHRoaXMtPnN0YXJ0X2RhdGVfd2hlcmUoKTsKCQkkdGhpcy0+ZW5kX2RhdGVfd2hlcmUoKTsKCQkkdGhpcy0+c3RhcnRfaWRfd2hlcmUoKTsKCQkkdGhpcy0+Y2F0ZWdvcnlfd2hlcmUoKTsKCgkJJHdoZXJlID0gaW1wbG9kZSggJyBBTkQgJywgYXJyYXlfZmlsdGVyKCAkdGhpcy0+d2hlcmVzICkgKTsKCQlpZiAoICR3aGVyZSApIHsKCQkJJHdoZXJlID0gIldIRVJFICR3aGVyZSI7CgkJfQoJCSRqb2luID0gaW1wbG9kZSggJyAnLCBhcnJheV9maWx0ZXIoICR0aGlzLT5qb2lucyApICk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gSW5kaXZpZHVhbCB3aGVyZSBjbGF1c2VzIHJ1biB0aHJvdWdoICR3cGRiLT5wcmVwYXJlKCkuCgkJJHBvc3RfaWRzID0gJHdwZGItPmdldF9jb2woICJTRUxFQ1QgSUQgRlJPTSB7JHdwZGItPnBvc3RzfSBBUyBwIHskam9pbn0geyR3aGVyZX0geyR0aGlzLT5tYXhfbnVtX3Bvc3RzKCl9IiApOwoJCWlmICggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddICkgewoJCQkkcG9zdF9pZHMgPSBhcnJheV9tZXJnZSggJHBvc3RfaWRzLCAkdGhpcy0+aW5jbHVkZV9hdHRhY2htZW50X2lkcyggJHBvc3RfaWRzICkgKTsKCQl9CgkJcmV0dXJuICRwb3N0X2lkczsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHBvc3RfdHlwZV93aGVyZSgpIHsKCQkkcG9zdF90eXBlc19maWx0ZXJzID0gWyAnY2FuX2V4cG9ydCcgPT4gdHJ1ZSBdOwoJCWlmICggJHRoaXMtPmZpbHRlcnNbJ3Bvc3RfdHlwZSddICkgewoJCQkkcG9zdF90eXBlcyA9ICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXTsKCgkJCS8vIEZsYXR0ZW4gc2luZ2xlIHBvc3QgdHlwZXMKCQkJaWYgKCBpc19hcnJheSggJHBvc3RfdHlwZXMgKSAmJiAxID09PSBjb3VudCggJHBvc3RfdHlwZXMgKSApIHsKCQkJCSRwb3N0X3R5cGVzID0gYXJyYXlfc2hpZnQoICRwb3N0X3R5cGVzICk7CgkJCX0KCQkJJHBvc3RfdHlwZXNfZmlsdGVycyA9IGFycmF5X21lcmdlKCAkcG9zdF90eXBlc19maWx0ZXJzLCBbICduYW1lJyA9PiAkcG9zdF90eXBlcyBdICk7CgkJfQoKCQkvLyBNdWx0aXBsZSBwb3N0IHR5cGVzCgkJaWYgKCBpc3NldCggJHBvc3RfdHlwZXNfZmlsdGVyc1snbmFtZSddICkgJiYgaXNfYXJyYXkoICRwb3N0X3R5cGVzX2ZpbHRlcnNbJ25hbWUnXSApICkgewoJCQkkcG9zdF90eXBlcyA9IFtdOwoJCQlmb3JlYWNoICggJHBvc3RfdHlwZXNfZmlsdGVyc1snbmFtZSddIGFzICRwb3N0X3R5cGUgKSB7CgkJCQlpZiAoIHBvc3RfdHlwZV9leGlzdHMoICRwb3N0X3R5cGUgKSApIHsKCQkJCQkkcG9zdF90eXBlc1tdID0gJHBvc3RfdHlwZTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCSRwb3N0X3R5cGVzID0gZ2V0X3Bvc3RfdHlwZXMoICRwb3N0X3R5cGVzX2ZpbHRlcnMgKTsKCQl9CgoJCWlmICggISAkcG9zdF90eXBlcyApIHsKCQkJJHRoaXMtPndoZXJlc1tdID0gJ3AucG9zdF90eXBlIElTIE5VTEwnOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoIGZhbHNlID09PSAkdGhpcy0+ZmlsdGVyc1snd2l0aF9hdHRhY2htZW50cyddICYmICggISAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gfHwgISBpbl9hcnJheSggJ2F0dGFjaG1lbnQnLCAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10sIHRydWUgKSApICkgewoJCQl1bnNldCggJHBvc3RfdHlwZXNbJ2F0dGFjaG1lbnQnXSApOwoJCX0KCgkJJHRoaXMtPndoZXJlc1tdID0gX3dwX2V4cG9ydF9idWlsZF9JTl9jb25kaXRpb24oICdwLnBvc3RfdHlwZScsICRwb3N0X3R5cGVzICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzdGF0dXNfd2hlcmUoKSB7CgkJZ2xvYmFsICR3cGRiOwoJCWlmICggISAkdGhpcy0+ZmlsdGVyc1snc3RhdHVzJ10gKSB7CgkJCSR0aGlzLT53aGVyZXNbXSA9ICJwLnBvc3Rfc3RhdHVzICE9ICdhdXRvLWRyYWZ0JyI7CgkJCXJldHVybjsKCQl9CgkJJHRoaXMtPndoZXJlc1tdID0gJHdwZGItPnByZXBhcmUoICdwLnBvc3Rfc3RhdHVzID0gJXMnLCAkdGhpcy0+ZmlsdGVyc1snc3RhdHVzJ10gKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGF1dGhvcl93aGVyZSgpIHsKCQlnbG9iYWwgJHdwZGI7CgkJJHVzZXIgPSAkdGhpcy0+ZmluZF91c2VyX2Zyb21fYW55X29iamVjdCggJHRoaXMtPmZpbHRlcnNbJ2F1dGhvciddICk7CgkJaWYgKCAhICR1c2VyIHx8IGlzX3dwX2Vycm9yKCAkdXNlciApICkgewoJCQlyZXR1cm47CgkJfQoJCSR0aGlzLT5hdXRob3IgICA9ICR1c2VyOwoJCSR0aGlzLT53aGVyZXNbXSA9ICR3cGRiLT5wcmVwYXJlKCAncC5wb3N0X2F1dGhvciA9ICVkJywgJHVzZXItPklEICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBzdGFydF9kYXRlX3doZXJlKCkgewoJCWdsb2JhbCAkd3BkYjsKCQkkdGltZXN0YW1wID0gc3RydG90aW1lKCAkdGhpcy0+ZmlsdGVyc1snc3RhcnRfZGF0ZSddICk7CgkJaWYgKCAhICR0aW1lc3RhbXAgKSB7CgkJCXJldHVybjsKCQl9CgkJJHRoaXMtPndoZXJlc1tdID0gJHdwZGItPnByZXBhcmUoICdwLnBvc3RfZGF0ZSA+PSAlcycsIGRhdGUoICdZLW0tZCAwMDowMDowMCcsICR0aW1lc3RhbXAgKSApOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBlbmRfZGF0ZV93aGVyZSgpIHsKCQlnbG9iYWwgJHdwZGI7CgkJaWYgKCBwcmVnX21hdGNoKCAnL15cZHs0fS1cZHsyfSQvJywgJHRoaXMtPmZpbHRlcnNbJ2VuZF9kYXRlJ10gKSApIHsKCQkJJHRpbWVzdGFtcCA9ICR0aGlzLT5nZXRfdGltZXN0YW1wX2Zvcl90aGVfbGFzdF9kYXlfb2ZfYV9tb250aCggJHRoaXMtPmZpbHRlcnNbJ2VuZF9kYXRlJ10gKTsKCQl9IGVsc2UgewoJCQkkdGltZXN0YW1wID0gc3RydG90aW1lKCAkdGhpcy0+ZmlsdGVyc1snZW5kX2RhdGUnXSApOwoJCX0KCQlpZiAoICEgJHRpbWVzdGFtcCApIHsKCQkJcmV0dXJuOwoJCX0KCQkkdGhpcy0+d2hlcmVzW10gPSAkd3BkYi0+cHJlcGFyZSggJ3AucG9zdF9kYXRlIDw9ICVzJywgZGF0ZSggJ1ktbS1kIDIzOjU5OjU5JywgJHRpbWVzdGFtcCApICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHN0YXJ0X2lkX3doZXJlKCkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJHN0YXJ0X2lkID0gYWJzaW50KCAkdGhpcy0+ZmlsdGVyc1snc3RhcnRfaWQnXSApOwoJCWlmICggMCA9PT0gJHN0YXJ0X2lkICkgewoJCQlyZXR1cm47CgkJfQoJCSR0aGlzLT53aGVyZXNbXSA9ICR3cGRiLT5wcmVwYXJlKCAncC5JRCA+PSAlZCcsICRzdGFydF9pZCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3RpbWVzdGFtcF9mb3JfdGhlX2xhc3RfZGF5X29mX2FfbW9udGgoICR5eXl5X21tICkgewoJCXJldHVybiBzdHJ0b3RpbWUoICIkeXl5eV9tbSArMW1vbnRoIC0xZGF5IiApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2F0ZWdvcnlfd2hlcmUoKSB7CgkJZ2xvYmFsICR3cGRiOwoJCWlmICggJ3Bvc3QnICE9PSAkdGhpcy0+ZmlsdGVyc1sncG9zdF90eXBlJ10gJiYgISBpbl9hcnJheSggJ3Bvc3QnLCAoYXJyYXkpICR0aGlzLT5maWx0ZXJzWydwb3N0X3R5cGUnXSwgdHJ1ZSApICkgewoJCQlyZXR1cm47CgkJfQoJCSRjYXRlZ29yeSA9ICR0aGlzLT5maW5kX2NhdGVnb3J5X2Zyb21fYW55X29iamVjdCggJHRoaXMtPmZpbHRlcnNbJ2NhdGVnb3J5J10gKTsKCQlpZiAoICEgJGNhdGVnb3J5ICkgewoJCQlyZXR1cm47CgkJfQoJCSR0aGlzLT5jYXRlZ29yeSA9ICRjYXRlZ29yeTsKCQkkdGhpcy0+am9pbnNbXSAgPSAiSU5ORVIgSk9JTiB7JHdwZGItPnRlcm1fcmVsYXRpb25zaGlwc30gQVMgdHIgT04gKHAuSUQgPSB0ci5vYmplY3RfaWQpIjsKCQkkdGhpcy0+d2hlcmVzW10gPSAkd3BkYi0+cHJlcGFyZSggJ3RyLnRlcm1fdGF4b25vbXlfaWQgPSAlZCcsICRjYXRlZ29yeS0+dGVybV90YXhvbm9teV9pZCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gbWF4X251bV9wb3N0cygpIHsKCQlpZiAoICR0aGlzLT5maWx0ZXJzWydtYXhfbnVtX3Bvc3RzJ10gPiAwICkgewoJCQlyZXR1cm4gIkxJTUlUIHskdGhpcy0+ZmlsdGVyc1snbWF4X251bV9wb3N0cyddfSI7CgkJfSBlbHNlIHsKCQkJcmV0dXJuICcnOwoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIGluY2x1ZGVfYXR0YWNobWVudF9pZHMoICRwb3N0X2lkcyApIHsKCQlnbG9iYWwgJHdwZGI7CgkJaWYgKCAhICRwb3N0X2lkcyApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCQkkYXR0YWNobWVudF9pZHMgPSBbXTsKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkNvZGVBbmFseXNpcy5Bc3NpZ25tZW50SW5Db25kaXRpb24uRm91bmRJbldoaWxlQ29uZGl0aW9uIC0tIEFzc2lnbWVudCBpcyBwYXJ0IG9mIHRoZSBicmVhayBjb25kaXRpb24uCgkJd2hpbGUgKCAkYmF0Y2hfb2ZfcG9zdF9pZHMgPSBhcnJheV9zcGxpY2UoICRwb3N0X2lkcywgMCwgc2VsZjo6UVVFUllfQ0hVTksgKSApIHsKCQkJJHBvc3RfcGFyZW50X2NvbmRpdGlvbiA9IF93cF9leHBvcnRfYnVpbGRfSU5fY29uZGl0aW9uKCAncG9zdF9wYXJlbnQnLCAkYmF0Y2hfb2ZfcG9zdF9pZHMgKTsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCAtLSBFc2NhcGVkIGluIHdwY2xpX2V4cG9ydF9idWlsZF9pbl9jb25kaXRpb24oKSBmdW5jdGlvbi4KCQkJJGF0dGFjaG1lbnRfaWRzID0gYXJyYXlfbWVyZ2UoICRhdHRhY2htZW50X2lkcywgKGFycmF5KSAkd3BkYi0+Z2V0X2NvbCggIlNFTEVDVCBJRCBGUk9NIHskd3BkYi0+cG9zdHN9IFdIRVJFIHBvc3RfdHlwZSA9ICdhdHRhY2htZW50JyBBTkQgeyRwb3N0X3BhcmVudF9jb25kaXRpb259IiApICk7CgkJfQoJCXJldHVybiBhcnJheV9tYXAoICdpbnR2YWwnLCAkYXR0YWNobWVudF9pZHMgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGJsb2dpbmZvX3JzcyggJHNlY3Rpb24gKSB7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQlyZXR1cm4gYXBwbHlfZmlsdGVycyggJ2Jsb2dpbmZvX3JzcycsIGdldF9ibG9naW5mb19yc3MoICRzZWN0aW9uICksICRzZWN0aW9uICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBmaW5kX3VzZXJfZnJvbV9hbnlfb2JqZWN0KCAkdXNlciApIHsKCQlpZiAoIGlzX251bWVyaWMoICR1c2VyICkgKSB7CgkJCXJldHVybiBnZXRfdXNlcl9ieSggJ2lkJywgJHVzZXIgKTsKCQl9IGVsc2VpZiAoIGlzX3N0cmluZyggJHVzZXIgKSApIHsKCQkJcmV0dXJuIGdldF91c2VyX2J5KCAnbG9naW4nLCAkdXNlciApOwoJCX0gZWxzZWlmICggaXNzZXQoICR1c2VyLT5JRCApICkgewoJCQlyZXR1cm4gZ2V0X3VzZXJfYnkoICdpZCcsICR1c2VyLT5JRCApOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBmaW5kX2NhdGVnb3J5X2Zyb21fYW55X29iamVjdCggJGNhdGVnb3J5ICkgewoJCWlmICggaXNfbnVtZXJpYyggJGNhdGVnb3J5ICkgKSB7CgkJCXJldHVybiBnZXRfdGVybSggJGNhdGVnb3J5LCAnY2F0ZWdvcnknICk7CgkJfSBlbHNlaWYgKCBpc19zdHJpbmcoICRjYXRlZ29yeSApICkgewoJCQkkdGVybSA9IHRlcm1fZXhpc3RzKCAkY2F0ZWdvcnksICdjYXRlZ29yeScgKTsKCQkJcmV0dXJuIGlzc2V0KCAkdGVybVsndGVybV9pZCddICkgPyBnZXRfdGVybSggJHRlcm1bJ3Rlcm1faWQnXSwgJ2NhdGVnb3J5JyApIDogZmFsc2U7CgkJfSBlbHNlaWYgKCBpc3NldCggJGNhdGVnb3J5LT50ZXJtX2lkICkgKSB7CgkJCXJldHVybiBnZXRfdGVybSggJGNhdGVnb3J5LT50ZXJtX2lkLCAnY2F0ZWdvcnknICk7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiB0b3BvbG9naWNhbGx5X3NvcnRfdGVybXMoICR0ZXJtcyApIHsKCQkkc29ydGVkID0gW107CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5Db2RlQW5hbHlzaXMuQXNzaWdubWVudEluQ29uZGl0aW9uLkZvdW5kSW5XaGlsZUNvbmRpdGlvbiAtLSBhc3NpZ25tZW50IGlzIHVzZWQgYXMgYnJlYWsgY29uZGl0aW9uLgoJCXdoaWxlICggJHRlcm0gPSBhcnJheV9zaGlmdCggJHRlcm1zICkgKSB7CgkJCWlmICggMCA9PT0gKGludCkgJHRlcm0tPnBhcmVudCB8fCBpc3NldCggJHNvcnRlZFsgJHRlcm0tPnBhcmVudCBdICkgKSB7CgkJCQkkc29ydGVkWyAkdGVybS0+dGVybV9pZCBdID0gJHRlcm07CgkJCX0gZWxzZSB7CgkJCQkkdGVybXNbXSA9ICR0ZXJtOwoJCQl9CgkJfQoJCXJldHVybiAkc29ydGVkOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfZm9yX29ycGhhbmVkX3Rlcm1zKCAkdGVybXMgKSB7CgkJJHRlcm1faWRzICAgID0gW107CgkJJGhhdmVfcGFyZW50ID0gW107CgoJCWZvcmVhY2ggKCAkdGVybXMgYXMgJHRlcm0gKSB7CgkJCSR0ZXJtX2lkc1sgJHRlcm0tPnRlcm1faWQgXSA9IHRydWU7CgkJCWlmICggMCAhPT0gKGludCkgJHRlcm0tPnBhcmVudCApIHsKCQkJCSRoYXZlX3BhcmVudFtdID0gJHRlcm07CgkJCX0KCQl9CgoJCWZvcmVhY2ggKCAkaGF2ZV9wYXJlbnQgYXMgJGhhc19wYXJlbnQgKSB7CgkJCWlmICggISBpc3NldCggJHRlcm1faWRzWyAkaGFzX3BhcmVudC0+cGFyZW50IF0gKSApIHsKCQkJCSR0aGlzLT5taXNzaW5nX3BhcmVudHMgPSAkaGFzX3BhcmVudDsKCQkJCXRocm93IG5ldyBXUF9FeHBvcnRfVGVybV9FeGNlcHRpb24oICJUZXJtIGlzIG1pc3NpbmcgYSBwYXJlbnQ6IHskaGFzX3BhcmVudC0+c2x1Z30gKHskaGFzX3BhcmVudC0+dGVybV90YXhvbm9teV9pZH0pIiApOwoJCQl9CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF90ZXJtc19mb3JfcG9zdCggJHBvc3QgKSB7CgkJJHRheG9ub21pZXMgPSBnZXRfb2JqZWN0X3RheG9ub21pZXMoICRwb3N0LT5wb3N0X3R5cGUgKTsKCQlpZiAoIGVtcHR5KCAkdGF4b25vbWllcyApICkgewoJCQlyZXR1cm4gW107CgkJfQoJCXJldHVybiB3cF9nZXRfb2JqZWN0X3Rlcm1zKCAkcG9zdC0+SUQsICR0YXhvbm9taWVzICkgPzogW107Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X21ldGFfZm9yX3Bvc3QoICRwb3N0ICkgewoJCWdsb2JhbCAkd3BkYjsKCQkkbWV0YV9mb3JfZXhwb3J0ID0gW107CgkJJG1ldGFfZnJvbV9kYiAgICA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHdwZGItPnByZXBhcmUoICJTRUxFQ1QgKiBGUk9NICR3cGRiLT5wb3N0bWV0YSBXSEVSRSBwb3N0X2lkID0gJWQiLCAkcG9zdC0+SUQgKSApOwoJCWZvcmVhY2ggKCAkbWV0YV9mcm9tX2RiIGFzICRtZXRhICkgewoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQlpZiAoIGFwcGx5X2ZpbHRlcnMoICd3eHJfZXhwb3J0X3NraXBfcG9zdG1ldGEnLCBmYWxzZSwgJG1ldGEtPm1ldGFfa2V5LCAkbWV0YSApICkgewoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCBpbl9hcnJheSggJG1ldGEtPm1ldGFfa2V5LCBbICdfZWRpdF9sb2NrJywgJ193cF9hdHRhY2htZW50X21ldGFkYXRhJywgJ193cF9hdHRhY2hlZF9maWxlJyBdLCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkbWV0YV9mb3JfZXhwb3J0W10gPSAkbWV0YTsKCQl9CgkJcmV0dXJuICRtZXRhX2Zvcl9leHBvcnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tbWVudHNfZm9yX3Bvc3QoICRwb3N0ICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJaWYgKCBpc3NldCggJHRoaXMtPmZpbHRlcnNbJ3NraXBfY29tbWVudHMnXSApICkgewoJCQlyZXR1cm4gW107CgkJfQoKCQkkY29tbWVudHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUICogRlJPTSAkd3BkYi0+Y29tbWVudHMgV0hFUkUgY29tbWVudF9wb3N0X0lEID0gJWQgQU5EIGNvbW1lbnRfYXBwcm92ZWQgPD4gJ3NwYW0nIiwgJHBvc3QtPklEICkgKTsKCQlmb3JlYWNoICggJGNvbW1lbnRzIGFzICRjb21tZW50ICkgewoJCQkkY29tbWVudC0+bWV0YSA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHdwZGItPnByZXBhcmUoICJTRUxFQ1QgKiBGUk9NICR3cGRiLT5jb21tZW50bWV0YSBXSEVSRSBjb21tZW50X2lkID0gJWQiLCAkY29tbWVudC0+Y29tbWVudF9JRCApICkgPzogW107CgkJfQoJCXJldHVybiAkY29tbWVudHM7Cgl9Cn0KCjw/cGhwCgpjbGFzcyBXUF9FeHBvcnRfVGVybV9FeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKfQo8P3BocAoKY2xhc3MgV1BfTWFwX0l0ZXJhdG9yIGV4dGVuZHMgSXRlcmF0b3JJdGVyYXRvciB7CglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRpdGVyYXRvciwgJGNhbGxiYWNrICkgewoJCSR0aGlzLT5jYWxsYmFjayA9ICRjYWxsYmFjazsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCAkaXRlcmF0b3IgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpIHsKCQkkb3JpZ2luYWxfY3VycmVudCA9IHBhcmVudDo6Y3VycmVudCgpOwoJCXJldHVybiBjYWxsX3VzZXJfZnVuYyggJHRoaXMtPmNhbGxiYWNrLCAkb3JpZ2luYWxfY3VycmVudCApOwoJfQp9Cjw/cGhwCgpjbGFzcyBXUF9FeHBvcnRfUmV0dXJuZXIgZXh0ZW5kcyBXUF9FeHBvcnRfQmFzZV9Xcml0ZXIgewoJcHJpdmF0ZSAkcmVzdWx0ID0gJyc7CgoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydCgpIHsKCQkkdGhpcy0+cHJpdmF0ZSA9ICcnOwoJCXRyeSB7CgkJCXBhcmVudDo6ZXhwb3J0KCk7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9FeGNlcHRpb24gJGUgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gUG9zc2libHkgdXNlZCBieSB0aGlyZCBwYXJ0eSBleHRlbnNpb24uCgkJCSRtZXNzYWdlID0gYXBwbHlfZmlsdGVycyggJ2V4cG9ydF9lcnJvcl9tZXNzYWdlJywgJGUtPmdldE1lc3NhZ2UoKSApOwoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnd3AtZXhwb3J0LWVycm9yJywgJG1lc3NhZ2UgKTsKCgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9UZXJtX0V4Y2VwdGlvbiAkZSApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBQb3NzaWJseSB1c2VkIGJ5IHRoaXJkIHBhcnR5IGV4dGVuc2lvbnMuCgkJCWRvX2FjdGlvbiggJ2V4cG9ydF90ZXJtX29ycGhhbmVkJywgJHRoaXMtPmZvcm1hdHRlci0+ZXhwb3J0LT5taXNzaW5nX3BhcmVudHMgKTsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBQb3NzaWJseSB1c2VkIGJ5IHRoaXJkIHBhcnR5IGV4dGVuc2lvbi4KCQkJJG1lc3NhZ2UgPSBhcHBseV9maWx0ZXJzKCAnZXhwb3J0X3Rlcm1fZXJyb3JfbWVzc2FnZScsICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ3dwLWV4cG9ydC1lcnJvcicsICRtZXNzYWdlICk7CgkJfQoJCXJldHVybiAkdGhpcy0+cmVzdWx0OwoJfQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlKCAkeG1sICkgewoJCSR0aGlzLT5yZXN1bHQgLj0gJHhtbDsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKCi8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQgLS0gQ2hhbmdpbmcgYnJlYWtzIFBoYXIgY29tcGF0LgpkZWZpbmUoICdXUF9DTElfRVhQT1JUX0NPTU1BTkRfTk9fU1BMSVQnLCAnLTEnICk7CgovKioKICogRXhwb3J0cyBXb3JkUHJlc3MgY29udGVudCB0byBhIFdYUiBmaWxlLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBFeHBvcnQgcG9zdHMgcHVibGlzaGVkIGJ5IHRoZSB1c2VyIGJldHdlZW4gZ2l2ZW4gc3RhcnQgYW5kIGVuZCBkYXRlCiAqICAgICAkIHdwIGV4cG9ydCAtLWRpcj0vdG1wLyAtLXVzZXI9YWRtaW4gLS1wb3N0X3R5cGU9cG9zdCAtLXN0YXJ0X2RhdGU9MjAxMS0wMS0wMSAtLWVuZF9kYXRlPTIwMTEtMTItMzEKICogICAgIFN0YXJ0aW5nIGV4cG9ydCBwcm9jZXNzLi4uCiAqICAgICBXcml0aW5nIHRvIGZpbGUgL3RtcC9zdGFnaW5nLndvcmRwcmVzcy4yMDE2LTA1LTI0LjAwMC54bWwKICogICAgIFN1Y2Nlc3M6IEFsbCBkb25lIHdpdGggZXhwb3J0LgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIEV4cG9ydF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJKiBJbml0aWFsaXplIHRoZSBhcnJheSBvZiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGV2ZW50dWFsbHkgYmUgcGFzc2VkIHRvIGV4cG9ydF93cC4KCSoKCSogQHZhciBhcnJheQoJKi8KCXB1YmxpYyAkZXhwb3J0X2FyZ3MgPSBbXTsKCglwcml2YXRlICRzdGRvdXQ7Cglwcml2YXRlICRtYXhfZmlsZV9zaXplOwoJcHJpdmF0ZSAkd3hyX3BhdGg7CgoJLyoqCgkgKiBFeHBvcnRzIFdvcmRQcmVzcyBjb250ZW50IHRvIGEgV1hSIGZpbGUuCgkgKgoJICogR2VuZXJhdGVzIG9uZSBvciBtb3JlIFdYUiBmaWxlcyBjb250YWluaW5nIGF1dGhvcnMsIHRlcm1zLCBwb3N0cywKCSAqIGNvbW1lbnRzLCBhbmQgYXR0YWNobWVudHMuIFdYUiBmaWxlcyBkbyBub3QgaW5jbHVkZSBzaXRlIGNvbmZpZ3VyYXRpb24KCSAqIChvcHRpb25zKSBvciB0aGUgYXR0YWNobWVudCBmaWxlcyB0aGVtc2VsdmVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1kaXI9PGRpcm5hbWU+XQoJICogOiBGdWxsIHBhdGggdG8gZGlyZWN0b3J5IHdoZXJlIFdYUiBleHBvcnQgZmlsZXMgc2hvdWxkIGJlIHN0b3JlZC4gRGVmYXVsdHMKCSAqIHRvIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuCgkgKgoJICogWy0tc3Rkb3V0XQoJICogOiBPdXRwdXQgdGhlIHdob2xlIFhNTCB1c2luZyBzdGFuZGFyZCBvdXRwdXQgKGluY29tcGF0aWJsZSB3aXRoIC0tZGlyPSkKCSAqCgkgKiBbLS1za2lwX2NvbW1lbnRzXQoJICogOiBEb24ndCBpbmNsdWRlIGNvbW1lbnRzIGluIHRoZSBXWFIgZXhwb3J0IGZpbGUuCgkgKgoJICogWy0tbWF4X2ZpbGVfc2l6ZT08TUI+XQoJICogOiBBIHNpbmdsZSBleHBvcnQgZmlsZSBzaG91bGQgaGF2ZSB0aGlzIG1hbnkgbWVnYWJ5dGVzLiAtMSBmb3IgdW5saW1pdGVkLgoJICogLS0tCgkgKiBkZWZhdWx0OiAxNQoJICogLS0tCgkgKgoJICogIyMgRklMVEVSUwoJICoKCSAqIFstLXN0YXJ0X2RhdGU9PGRhdGU+XQoJICogOiBFeHBvcnQgb25seSBwb3N0cyBwdWJsaXNoZWQgYWZ0ZXIgdGhpcyBkYXRlLCBpbiBmb3JtYXQgWVlZWS1NTS1ERC4KCSAqCgkgKiBbLS1lbmRfZGF0ZT08ZGF0ZT5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIHB1Ymxpc2hlZCBiZWZvcmUgdGhpcyBkYXRlLCBpbiBmb3JtYXQgWVlZWS1NTS1ERC4KCSAqCgkgKiBbLS1wb3N0X3R5cGU9PHBvc3QtdHlwZT5dCgkgKiA6IEV4cG9ydCBvbmx5IHBvc3RzIHdpdGggdGhpcyBwb3N0X3R5cGUuIFNlcGFyYXRlIG11bHRpcGxlIHBvc3QgdHlwZXMgd2l0aCBhCgkgKiBjb21tYS4KCSAqIC0tLQoJICogZGVmYXVsdDogYW55CgkgKiAtLS0KCSAqCgkgKiBbLS1wb3N0X3R5cGVfX25vdF9pbj08cG9zdC10eXBlPl0KCSAqIDogRXhwb3J0IGFsbCBwb3N0IHR5cGVzIGV4Y2VwdCB0aG9zZSBpZGVudGlmaWVkLiBTZXBhcmF0ZSBtdWx0aXBsZSBwb3N0IHR5cGVzCgkgKiB3aXRoIGEgY29tbWEuIERlZmF1bHRzIHRvIG5vbmUuCgkgKgoJICogWy0tcG9zdF9faW49PHBpZD5dCgkgKiA6IEV4cG9ydCBhbGwgcG9zdHMgc3BlY2lmaWVkIGFzIGEgY29tbWEtIG9yIHNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIElEcy4KCSAqIFBvc3QncyBhdHRhY2htZW50cyB3b24ndCBiZSBleHBvcnRlZCB1bmxlc3MgLS13aXRoX2F0dGFjaG1lbnRzIGlzIHNwZWNpZmllZC4KCSAqCgkgKiBbLS13aXRoX2F0dGFjaG1lbnRzXQoJICogOiBGb3JjZSBpbmNsdWRpbmcgYXR0YWNobWVudHMgaW4gY2FzZSAtLXBvc3RfX2luIGhhcyBiZWVuIHNwZWNpZmllZC4KCSAqCgkgKiBbLS1zdGFydF9pZD08cGlkPl0KCSAqIDogRXhwb3J0IG9ubHkgcG9zdHMgd2l0aCBJRHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoaXMgcG9zdCBJRC4KCSAqCgkgKiBbLS1tYXhfbnVtX3Bvc3RzPTxudW0+XQoJICogOiBFeHBvcnQgbm8gbW9yZSB0aGFuIDxudW0+IHBvc3RzIChleGNsdWRpbmcgYXR0YWNobWVudHMpLgoJICoKCSAqIFstLWF1dGhvcj08YXV0aG9yPl0KCSAqIDogRXhwb3J0IG9ubHkgcG9zdHMgYnkgdGhpcyBhdXRob3IuIENhbiBiZSBlaXRoZXIgdXNlciBsb2dpbiBvciB1c2VyIElELgoJICoKCSAqIFstLWNhdGVnb3J5PTxuYW1lPl0KCSAqIDogRXhwb3J0IG9ubHkgcG9zdHMgaW4gdGhpcyBjYXRlZ29yeS4KCSAqCgkgKiBbLS1wb3N0X3N0YXR1cz08c3RhdHVzPl0KCSAqIDogRXhwb3J0IG9ubHkgcG9zdHMgd2l0aCB0aGlzIHN0YXR1cy4KCSAqCgkgKiBbLS1maWxlbmFtZV9mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFVzZSBhIGN1c3RvbSBmb3JtYXQgZm9yIGV4cG9ydCBmaWxlbmFtZXMuIERlZmF1bHRzIHRvICd7c2l0ZX0ud29yZHByZXNzLntkYXRlfS57bn0ueG1sJy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEV4cG9ydCBwb3N0cyBwdWJsaXNoZWQgYnkgdGhlIHVzZXIgYmV0d2VlbiBnaXZlbiBzdGFydCBhbmQgZW5kIGRhdGUKCSAqICAgICAkIHdwIGV4cG9ydCAtLWRpcj0vdG1wLyAtLXVzZXI9YWRtaW4gLS1wb3N0X3R5cGU9cG9zdCAtLXN0YXJ0X2RhdGU9MjAxMS0wMS0wMSAtLWVuZF9kYXRlPTIwMTEtMTItMzEKCSAqICAgICBTdGFydGluZyBleHBvcnQgcHJvY2Vzcy4uLgoJICogICAgIFdyaXRpbmcgdG8gZmlsZSAvdG1wL3N0YWdpbmcud29yZHByZXNzLjIwMTYtMDUtMjQuMDAwLnhtbAoJICogICAgIFN1Y2Nlc3M6IEFsbCBkb25lIHdpdGggZXhwb3J0LgoJICoKCSAqICAgICAjIEV4cG9ydCBwb3N0cyBieSBJRHMKCSAqICAgICAkIHdwIGV4cG9ydCAtLWRpcj0vdG1wLyAtLXBvc3RfX2luPTEyMywxMjQsMTI1CgkgKiAgICAgU3RhcnRpbmcgZXhwb3J0IHByb2Nlc3MuLi4KCSAqICAgICBXcml0aW5nIHRvIGZpbGUgL3RtcC9zdGFnaW5nLndvcmRwcmVzcy4yMDE2LTA1LTI0LjAwMC54bWwKCSAqICAgICBTdWNjZXNzOiBBbGwgZG9uZSB3aXRoIGV4cG9ydC4KCSAqCgkgKiAgICAgIyBFeHBvcnQgYSByYW5kb20gc3Vic2V0IG9mIGNvbnRlbnQKCSAqICAgICAkIHdwIGV4cG9ydCAtLXBvc3RfX2luPSIkKHdwIHBvc3QgbGlzdCAtLXBvc3RfdHlwZT1wb3N0IC0tb3JkZXJieT1yYW5kIC0tcG9zdHNfcGVyX3BhZ2U9OCAtLWZvcm1hdD1pZHMpIgoJICogICAgIFN0YXJ0aW5nIGV4cG9ydCBwcm9jZXNzLi4uCgkgKiAgICAgV3JpdGluZyB0byBmaWxlIC92YXIvd3d3L2V4YW1wbGUuY29tL3B1YmxpY19odG1sL3N0YWdpbmcud29yZHByZXNzLjIwMTYtMDUtMjQuMDAwLnhtbAoJICogICAgIFN1Y2Nlc3M6IEFsbCBkb25lIHdpdGggZXhwb3J0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkZGVmYXVsdHMgPSBbCgkJCSdkaXInICAgICAgICAgICAgICAgPT4gbnVsbCwKCQkJJ3N0ZG91dCcgICAgICAgICAgICA9PiBmYWxzZSwKCQkJJ3N0YXJ0X2RhdGUnICAgICAgICA9PiBudWxsLAoJCQknZW5kX2RhdGUnICAgICAgICAgID0+IG51bGwsCgkJCSdwb3N0X3R5cGUnICAgICAgICAgPT4gbnVsbCwKCQkJJ3Bvc3RfdHlwZV9fbm90X2luJyA9PiBudWxsLAoJCQknbWF4X251bV9wb3N0cycgICAgID0+IG51bGwsCgkJCSdhdXRob3InICAgICAgICAgICAgPT4gbnVsbCwKCQkJJ2NhdGVnb3J5JyAgICAgICAgICA9PiBudWxsLAoJCQkncG9zdF9zdGF0dXMnICAgICAgID0+IG51bGwsCgkJCSdwb3N0X19pbicgICAgICAgICAgPT4gbnVsbCwKCQkJJ3dpdGhfYXR0YWNobWVudHMnICA9PiB0cnVlLCAvLyBvciBGQUxTRSBpZiB1c2VyIHJlcXVlc3RlZCBzb21lIHBvc3RfX2luCgkJCSdzdGFydF9pZCcgICAgICAgICAgPT4gbnVsbCwKCQkJJ3NraXBfY29tbWVudHMnICAgICA9PiBudWxsLAoJCQknbWF4X2ZpbGVfc2l6ZScgICAgID0+IDE1LAoJCQknZmlsZW5hbWVfZm9ybWF0JyAgID0+ICd7c2l0ZX0ud29yZHByZXNzLntkYXRlfS57bn0ueG1sJywKCQldOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydzdGRvdXQnXSApICYmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2RpciddICkgfHwgISBlbXB0eSggJGFzc29jX2FyZ3NbJ2ZpbGVuYW1lX2Zvcm1hdCddICkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJy0tc3Rkb3V0IGFuZCAtLWRpciBjYW5ub3QgYmUgdXNlZCB0b2dldGhlci4nICk7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydwb3N0X19pbiddICkgJiYgZW1wdHkoICRhc3NvY19hcmdzWyd3aXRoX2F0dGFjaG1lbnRzJ10gKSApIHsKCQkJJGRlZmF1bHRzWyd3aXRoX2F0dGFjaG1lbnRzJ10gPSBmYWxzZTsKCQl9CgoJCSRhc3NvY19hcmdzID0gd3BfcGFyc2VfYXJncyggJGFzc29jX2FyZ3MsICRkZWZhdWx0cyApOwoKCQkkdGhpcy0+dmFsaWRhdGVfYXJncyggJGFzc29jX2FyZ3MgKTsKCgkJJHRoaXMtPmV4cG9ydF9hcmdzWyd3aXRoX2F0dGFjaG1lbnRzJ10gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSgKCQkJJGFzc29jX2FyZ3MsCgkJCSd3aXRoX2F0dGFjaG1lbnRzJywKCQkJJGRlZmF1bHRzWyd3aXRoX2F0dGFjaG1lbnRzJ10KCQkpOwoKCQlpZiAoICEgZnVuY3Rpb25fZXhpc3RzKCAnd3BfZXhwb3J0JyApICkgewoJCQlzZWxmOjpsb2FkX2V4cG9ydF9hcGkoKTsKCQl9CgoJCWlmICggISAkdGhpcy0+c3Rkb3V0ICkgewoJCQlXUF9DTEk6OmxvZyggJ1N0YXJ0aW5nIGV4cG9ydCBwcm9jZXNzLi4uJyApOwoJCX0KCgkJYWRkX2FjdGlvbigKCQkJJ3dwX2V4cG9ydF9uZXdfZmlsZScsCgkJCXN0YXRpYyBmdW5jdGlvbiAoICRmaWxlX3BhdGggKSB7CgkJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ1dyaXRpbmcgdG8gZmlsZSAlcycsICRmaWxlX3BhdGggKSApOwoJCQkJVXRpbHNcd3BfY2xlYXJfb2JqZWN0X2NhY2hlKCk7CgkJCX0KCQkpOwoKCQl0cnkgewoJCQlpZiAoICR0aGlzLT5zdGRvdXQgKSB7CgkJCQl3cF9leHBvcnQoCgkJCQkJWwoJCQkJCQknZmlsdGVycycgICAgID0+ICR0aGlzLT5leHBvcnRfYXJncywKCQkJCQkJJ3dyaXRlcicgICAgICA9PiAnV1BfRXhwb3J0X0ZpbGVfV3JpdGVyJywKCQkJCQkJJ3dyaXRlcl9hcmdzJyA9PiAncGhwOi8vb3V0cHV0JywKCQkJCQldCgkJCQkpOwoJCQl9IGVsc2UgewoJCQkJd3BfZXhwb3J0KAoJCQkJCVsKCQkJCQkJJ2ZpbHRlcnMnICAgICA9PiAkdGhpcy0+ZXhwb3J0X2FyZ3MsCgkJCQkJCSd3cml0ZXInICAgICAgPT4gJ1dQX0V4cG9ydF9TcGxpdF9GaWxlc19Xcml0ZXInLAoJCQkJCQknd3JpdGVyX2FyZ3MnID0+IFsKCQkJCQkJCSdtYXhfZmlsZV9zaXplJyAgICAgICAgID0+ICR0aGlzLT5tYXhfZmlsZV9zaXplLAoJCQkJCQkJJ2Rlc3RpbmF0aW9uX2RpcmVjdG9yeScgPT4gJHRoaXMtPnd4cl9wYXRoLAoJCQkJCQkJJ2ZpbGVuYW1lX3RlbXBsYXRlJyAgICAgPT4gc2VsZjo6Z2V0X2ZpbGVuYW1lX3RlbXBsYXRlKCAkYXNzb2NfYXJnc1snZmlsZW5hbWVfZm9ybWF0J10gKSwKCQkJCQkJXSwKCQkJCQldCgkJCQkpOwoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJaWYgKCAhICR0aGlzLT5zdGRvdXQgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ0FsbCBkb25lIHdpdGggZXhwb3J0LicgKTsKCQl9Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2ZpbGVuYW1lX3RlbXBsYXRlKCAkZmlsZW5hbWVfZm9ybWF0ICkgewoJCSRzaXRlbmFtZSA9IHNhbml0aXplX2tleSggZ2V0X2Jsb2dpbmZvKCAnbmFtZScgKSApOwoJCWlmICggZW1wdHkoICRzaXRlbmFtZSApICkgewoJCQkkc2l0ZW5hbWUgPSAnc2l0ZSc7CgkJfQoJCXJldHVybiBzdHJfcmVwbGFjZSggWyAne3NpdGV9JywgJ3tkYXRlfScsICd7bn0nIF0sIFsgJHNpdGVuYW1lLCBkYXRlKCAnWS1tLWQnICksICclMDNkJyBdLCAkZmlsZW5hbWVfZm9ybWF0ICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCX0KCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGxvYWRfZXhwb3J0X2FwaSgpIHsKCQlyZXF1aXJlIGRpcm5hbWUoIF9fRElSX18gKSAuICcvZnVuY3Rpb25zLnBocCc7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB2YWxpZGF0ZV9hcmdzKCAkYXJncyApIHsKCQkkaGFzX2Vycm9ycyA9IGZhbHNlOwoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCWlmICggaXNfY2FsbGFibGUoIFsgJHRoaXMsICdjaGVja18nIC4gJGtleSBdICkgKSB7CgkJCQkkcmVzdWx0ID0gY2FsbF91c2VyX2Z1bmMoIFsgJHRoaXMsICdjaGVja18nIC4gJGtleSBdLCAkdmFsdWUgKTsKCQkJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCQkJJGhhc19lcnJvcnMgPSB0cnVlOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICRhcmdzWydzdGRvdXQnXSApIHsKCQkJJHRoaXMtPnd4cl9wYXRoID0gbnVsbDsKCQkJJHRoaXMtPnN0ZG91dCAgID0gdHJ1ZTsKCQl9CgoJCWlmICggJGhhc19lcnJvcnMgKSB7CgkJCVdQX0NMSTo6aGFsdCggMSApOwoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2RpciggJHBhdGggKSB7CgkJaWYgKCBlbXB0eSggJHBhdGggKSApIHsKCQkJJHBhdGggPSBnZXRjd2QoKTsKCQl9IGVsc2VpZiAoICEgaXNfZGlyKCAkcGF0aCApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiVGhlIGRpcmVjdG9yeSAnJXMnIGRvZXMgbm90IGV4aXN0LiIsICRwYXRoICkgKTsKCQl9IGVsc2VpZiAoICEgaXNfd3JpdGFibGUoICRwYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJUaGUgZGlyZWN0b3J5ICclcycgaXMgbm90IHdyaXRhYmxlLiIsICRwYXRoICkgKTsKCQl9CgoJCSR0aGlzLT53eHJfcGF0aCA9IHRyYWlsaW5nc2xhc2hpdCggJHBhdGggKTsKCgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19zdGFydF9kYXRlKCAkZGF0ZSApIHsKCQlpZiAoIG51bGwgPT09ICRkYXRlICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSR0aW1lID0gc3RydG90aW1lKCAkZGF0ZSApOwoJCWlmICggISBlbXB0eSggJGRhdGUgKSAmJiAhICR0aW1lICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdUaGUgc3RhcnRfZGF0ZSAlcyBpcyBpbnZhbGlkLicsICRkYXRlICkgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ3N0YXJ0X2RhdGUnXSA9IGRhdGUoICdZLW0tZCcsICR0aW1lICk7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX2VuZF9kYXRlKCAkZGF0ZSApIHsKCQlpZiAoIG51bGwgPT09ICRkYXRlICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSR0aW1lID0gc3RydG90aW1lKCAkZGF0ZSApOwoJCWlmICggISBlbXB0eSggJGRhdGUgKSAmJiAhICR0aW1lICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdUaGUgZW5kX2RhdGUgJXMgaXMgaW52YWxpZC4nLCAkZGF0ZSApICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHRoaXMtPmV4cG9ydF9hcmdzWydlbmRfZGF0ZSddID0gZGF0ZSggJ1ktbS1kJywgJHRpbWUgKTsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EYXRlVGltZS5SZXN0cmljdGVkRnVuY3Rpb25zLmRhdGVfZGF0ZQoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfcG9zdF90eXBlKCAkcG9zdF90eXBlICkgewoJCWlmICggbnVsbCA9PT0gJHBvc3RfdHlwZSB8fCAnYW55JyA9PT0gJHBvc3RfdHlwZSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkkcG9zdF90eXBlICA9IGFycmF5X3VuaXF1ZSggYXJyYXlfZmlsdGVyKCBleHBsb2RlKCAnLCcsICRwb3N0X3R5cGUgKSApICk7CgkJJHBvc3RfdHlwZXMgPSBnZXRfcG9zdF90eXBlcygpOwoKCQlmb3JlYWNoICggJHBvc3RfdHlwZSBhcyAkdHlwZSApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkdHlwZSwgJHBvc3RfdHlwZXMsIHRydWUgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZygKCQkJCQlzcHJpbnRmKAoJCQkJCQknVGhlIHBvc3QgdHlwZSAlcyBkb2VzIG5vdCBleGlzdC4gQ2hvb3NlICJhbnkiIG9yIGFueSBvZiB0aGVzZSBleGlzdGluZyBwb3N0IHR5cGVzIGluc3RlYWQ6ICVzJywKCQkJCQkJJHR5cGUsCgkJCQkJCWltcGxvZGUoICcsICcsICRwb3N0X3R5cGVzICkKCQkJCQkpCgkJCQkpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJCSR0aGlzLT5leHBvcnRfYXJnc1sncG9zdF90eXBlJ10gPSAkcG9zdF90eXBlOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfcG9zdF90eXBlX19ub3RfaW4oICRwb3N0X3R5cGUgKSB7CgkJaWYgKCBudWxsID09PSAkcG9zdF90eXBlICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRwb3N0X3R5cGUgID0gYXJyYXlfdW5pcXVlKCBhcnJheV9maWx0ZXIoIGV4cGxvZGUoICcsJywgJHBvc3RfdHlwZSApICkgKTsKCQkkcG9zdF90eXBlcyA9IGdldF9wb3N0X3R5cGVzKCk7CgoJCWZvcmVhY2ggKCAkcG9zdF90eXBlIGFzICR0eXBlICkgewoJCQlpZiAoICEgaW5fYXJyYXkoICR0eXBlLCAkcG9zdF90eXBlcywgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCXNwcmludGYoCgkJCQkJCSdUaGUgcG9zdCB0eXBlICVzIGRvZXMgbm90IGV4aXN0LiBVc2UgYW55IG9mIHRoZXNlIGV4aXN0aW5nIHBvc3QgdHlwZXMgaW5zdGVhZDogJXMnLAoJCQkJCQkkdHlwZSwKCQkJCQkJaW1wbG9kZSggJywgJywgJHBvc3RfdHlwZXMgKQoJCQkJCSkKCQkJCSk7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgkJJHRoaXMtPmV4cG9ydF9hcmdzWydwb3N0X3R5cGUnXSA9IGFycmF5X2RpZmYoICRwb3N0X3R5cGVzLCAkcG9zdF90eXBlICk7CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19wb3N0X19pbiggJHBvc3RfX2luICkgewoJCWlmICggbnVsbCA9PT0gJHBvc3RfX2luICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRzZXBhcmF0b3IgPSBmYWxzZSAhPT0gc3RyaXBvcyggJHBvc3RfX2luLCAnICcgKSA/ICcgJyA6ICcsJzsKCQkkcG9zdF9faW4gID0gYXJyYXlfZmlsdGVyKCBhcnJheV91bmlxdWUoIGFycmF5X21hcCggJ2ludHZhbCcsIGV4cGxvZGUoICRzZXBhcmF0b3IsICRwb3N0X19pbiApICkgKSApOwoJCWlmICggZW1wdHkoICRwb3N0X19pbiApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdwb3N0X19pbiBzaG91bGQgYmUgY29tbWEtc2VwYXJhdGVkIHBvc3QgSURzLicgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBOZXcgZXhwb3J0ZXIgdXNlcyBhIGRpZmZlcmVudCBhcmd1bWVudC4KCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ3Bvc3RfaWRzJ10gPSAkcG9zdF9faW47CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19zdGFydF9pZCggJHN0YXJ0X2lkICkgewoJCWlmICggbnVsbCA9PT0gJHN0YXJ0X2lkICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRzdGFydF9pZCA9IChpbnQpICRzdGFydF9pZDsKCgkJLy8gUG9zdCBJRHMgbXVzdCBiZSBncmVhdGVyIHRoYW4gMC4KCQlpZiAoIDAgPj0gJHN0YXJ0X2lkICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJJbnZhbGlkIHN0YXJ0IElEOiB7JHN0YXJ0X2lkfSIgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJHRoaXMtPmV4cG9ydF9hcmdzWydzdGFydF9pZCddID0gJHN0YXJ0X2lkOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfYXV0aG9yKCAkYXV0aG9yICkgewoJCWlmICggbnVsbCA9PT0gJGF1dGhvciApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkRlcHJlY2F0ZWRGdW5jdGlvbnMuZ2V0X3VzZXJzX29mX2Jsb2dGb3VuZCAtLSBGYWxsYmFjay4KCQkkYXV0aG9ycyA9IGZ1bmN0aW9uX2V4aXN0cyggJ2dldF91c2VycycgKSA/IGdldF91c2VycygpIDogZ2V0X3VzZXJzX29mX2Jsb2coKTsKCQlpZiAoIGVtcHR5KCAkYXV0aG9ycyApIHx8IGlzX3dwX2Vycm9yKCAkYXV0aG9ycyApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdDb3VsZCBub3QgZmluZCBhbnkgYXV0aG9ycyBpbiB0aGlzIGJsb2cuJyApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSRoaXQgPSBmYWxzZTsKCQlmb3JlYWNoICggJGF1dGhvcnMgYXMgJHVzZXIgKSB7CgkJCWlmICggJGhpdCApIHsKCQkJCWJyZWFrOwoJCQl9CgkJCWlmICggKGludCkgJGF1dGhvciA9PT0gJHVzZXItPklEIHx8ICRhdXRob3IgPT09ICR1c2VyLT51c2VyX2xvZ2luICkgewoJCQkJJGhpdCA9ICR1c2VyLT5JRDsKCQkJfQoJCX0KCQlpZiAoIGZhbHNlID09PSAkaGl0ICkgewoJCQkkYXV0aG9yc19uaWNlID0gW107CgkJCWZvcmVhY2ggKCAkYXV0aG9ycyBhcyAkX2F1dGhvciApIHsKCQkJCSRhdXRob3JzX25pY2VbXSA9IHNwcmludGYoICclcyAoJXMpJywgJF9hdXRob3ItPnVzZXJfbG9naW4sICRfYXV0aG9yLT5kaXNwbGF5X25hbWUgKTsKCQkJfQoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdDb3VsZCBub3QgZmluZCBhIG1hdGNoaW5nIGF1dGhvciBmb3IgJXMuIFRoZSBmb2xsb3dpbmcgYXV0aG9ycyBleGlzdDogJXMnLCAkYXV0aG9yLCBpbXBsb2RlKCAnLCAnLCAkYXV0aG9yc19uaWNlICkgKSApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ2F1dGhvciddID0gJGhpdDsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNoZWNrX21heF9udW1fcG9zdHMoICRudW0gKSB7CgkJaWYgKCBudWxsICE9PSAkbnVtICYmICggISBpc19udW1lcmljKCAkbnVtICkgfHwgJG51bSA8PSAwICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ21heF9udW1fcG9zdHMgc2hvdWxkIGJlIGEgcG9zaXRpdmUgaW50ZWdlci4nICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCSR0aGlzLT5leHBvcnRfYXJnc1snbWF4X251bV9wb3N0cyddID0gKGludCkgJG51bTsKCgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19jYXRlZ29yeSggJGNhdGVnb3J5ICkgewoJCWlmICggbnVsbCA9PT0gJGNhdGVnb3J5ICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSR0ZXJtID0gY2F0ZWdvcnlfZXhpc3RzKCAkY2F0ZWdvcnkgKTsKCQlpZiAoIGVtcHR5KCAkdGVybSApIHx8IGlzX3dwX2Vycm9yKCAkdGVybSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICdDb3VsZCBub3QgZmluZCBhIGNhdGVnb3J5IG1hdGNoaW5nICVzLicsICRjYXRlZ29yeSApICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHRoaXMtPmV4cG9ydF9hcmdzWydjYXRlZ29yeSddID0gJGNhdGVnb3J5OwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfcG9zdF9zdGF0dXMoICRzdGF0dXMgKSB7CgkJaWYgKCBudWxsID09PSAkc3RhdHVzICkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCSRzdGF0aSA9IGdldF9wb3N0X3N0YXR1c2VzKCk7CgkJaWYgKCBlbXB0eSggJHN0YXRpICkgfHwgaXNfd3BfZXJyb3IoICRzdGF0aSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdDb3VsZCBub3QgZmluZCBhbnkgcG9zdCBzdGF0aS4nICk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCWlmICggISBpc3NldCggJHN0YXRpWyAkc3RhdHVzIF0gKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnQ291bGQgbm90IGZpbmQgYSBwb3N0X3N0YXR1cyBtYXRjaGluZyAlcy4gSGVyZSBpcyBhIGxpc3Qgb2YgYXZhaWxhYmxlIHN0YXRpOiAlcycsICRzdGF0dXMsIGltcGxvZGUoICcsICcsIGFycmF5X2tleXMoICRzdGF0aSApICkgKSApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCSR0aGlzLT5leHBvcnRfYXJnc1snc3RhdHVzJ10gPSAkc3RhdHVzOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfc2tpcF9jb21tZW50cyggJHNraXAgKSB7CgkJaWYgKCBudWxsID09PSAkc2tpcCApIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlpZiAoIDAgIT09IChpbnQpICRza2lwICYmIDEgIT09IChpbnQpICRza2lwICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdza2lwX2NvbW1lbnRzIG5lZWRzIHRvIGJlIDAgKG5vKSBvciAxICh5ZXMpLicgKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkdGhpcy0+ZXhwb3J0X2FyZ3NbJ3NraXBfY29tbWVudHMnXSA9ICRza2lwOwoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfbWF4X2ZpbGVfc2l6ZSggJHNpemUgKSB7CgkJaWYgKCAhIGlzX251bWVyaWMoICRzaXplICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ21heF9maWxlX3NpemUgc2hvdWxkIGJlIG51bWVyaWMuJyApOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkkdGhpcy0+bWF4X2ZpbGVfc2l6ZSA9ICRzaXplOwoKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAovKioKICogVmVyc2lvbiBudW1iZXIgZm9yIHRoZSBleHBvcnQgZm9ybWF0LgogKgogKiBCdW1wIHRoaXMgd2hlbiBzb21ldGhpbmcgY2hhbmdlcyB0aGF0IG1pZ2h0IGFmZmVjdCBjb21wYXRpYmlsaXR5LgogKgogKiBAc2luY2UgMi41LjAKICovCmRlZmluZSggJ1dYUl9WRVJTSU9OJywgJzEuMicgKTsgLy9waHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRDb25zdGFudEZvdW5kIC0tIFdvcmRQcmVzcyBjb25zdGFudC4KCi8qKgogKiBSZXNwb25zaWJsZSBmb3IgZm9ybWF0dGluZyB0aGUgZGF0YSBpbiBXUF9FeHBvcnRfUXVlcnkgdG8gV1hSCiAqLwpjbGFzcyBXUF9FeHBvcnRfV1hSX0Zvcm1hdHRlciB7CglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRleHBvcnQgKSB7CgkJJHRoaXMtPmV4cG9ydCAgICAgID0gJGV4cG9ydDsKCQkkdGhpcy0+d3hyX3ZlcnNpb24gPSBXWFJfVkVSU0lPTjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gYmVmb3JlX3Bvc3RzKCAkcmVxdWVzdGVkX3NlY3Rpb25zID0gW10gKSB7CgkJJGF2YWlsYWJsZV9zZWN0aW9ucyA9IFsKCQkJJ2hlYWRlcicsCgkJCSdzaXRlX21ldGFkYXRhJywKCQkJJ2F1dGhvcnMnLAoJCQknY2F0ZWdvcmllcycsCgkJCSd0YWdzJywKCQkJJ25hdl9tZW51X3Rlcm1zJywKCQkJJ2N1c3RvbV90YXhvbm9taWVzX3Rlcm1zJywKCQkJJ3JzczJfaGVhZF9hY3Rpb24nLAoJCV07CgoJCSRiZWZvcmVfcG9zdHNfeG1sID0gJyc7CgoJCWZvcmVhY2ggKCAkYXZhaWxhYmxlX3NlY3Rpb25zIGFzICRzZWN0aW9uICkgewoJCQlpZiAoICEgJHJlcXVlc3RlZF9zZWN0aW9ucyB8fCBpbl9hcnJheSggJHNlY3Rpb24sICRyZXF1ZXN0ZWRfc2VjdGlvbnMsIHRydWUgKSApIHsKCQkJCSRiZWZvcmVfcG9zdHNfeG1sIC49ICR0aGlzLT4kc2VjdGlvbigpOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGJlZm9yZV9wb3N0c194bWw7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHBvc3RzKCkgewoJCXJldHVybiBuZXcgV1BfTWFwX0l0ZXJhdG9yKCAkdGhpcy0+ZXhwb3J0LT5wb3N0cygpLCBbICR0aGlzLCAncG9zdCcgXSApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBhZnRlcl9wb3N0cygpIHsKCQlyZXR1cm4gJHRoaXMtPmZvb3RlcigpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBoZWFkZXIoKSB7CgkJJG94eW1lbCAgICAgICAgICAgPSBuZXcgT3h5bWVsKCk7CgkJJHdwX2dlbmVyYXRvcl90YWcgPSAkdGhpcy0+ZXhwb3J0LT53cF9nZW5lcmF0b3JfdGFnKCk7CgkJJGNvbW1lbnQgICAgICAgICAgPSA8PDxDT01NRU5UCgogVGhpcyBpcyBhIFdvcmRQcmVzcyBlWHRlbmRlZCBSU1MgZmlsZSBnZW5lcmF0ZWQgYnkgV29yZFByZXNzIGFzIGFuIGV4cG9ydCBvZiB5b3VyIHNpdGUuCiBJdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB5b3VyIHNpdGUncyBwb3N0cywgcGFnZXMsIGNvbW1lbnRzLCBjYXRlZ29yaWVzLCBhbmQgb3RoZXIgY29udGVudC4KIFlvdSBtYXkgdXNlIHRoaXMgZmlsZSB0byB0cmFuc2ZlciB0aGF0IGNvbnRlbnQgZnJvbSBvbmUgc2l0ZSB0byBhbm90aGVyLgogVGhpcyBmaWxlIGlzIG5vdCBpbnRlbmRlZCB0byBzZXJ2ZSBhcyBhIGNvbXBsZXRlIGJhY2t1cCBvZiB5b3VyIHNpdGUuCgogVG8gaW1wb3J0IHRoaXMgaW5mb3JtYXRpb24gaW50byBhIFdvcmRQcmVzcyBzaXRlIGZvbGxvdyB0aGVzZSBzdGVwczoKIDEuIExvZyBpbiB0byB0aGF0IHNpdGUgYXMgYW4gYWRtaW5pc3RyYXRvci4KIDIuIEdvIHRvIFRvb2xzOiBJbXBvcnQgaW4gdGhlIFdvcmRQcmVzcyBhZG1pbiBwYW5lbC4KIDMuIEluc3RhbGwgdGhlICJXb3JkUHJlc3MiIGltcG9ydGVyIGZyb20gdGhlIGxpc3QuCiA0LiBBY3RpdmF0ZSAmIFJ1biBJbXBvcnRlci4KIDUuIFVwbG9hZCB0aGlzIGZpbGUgdXNpbmcgdGhlIGZvcm0gcHJvdmlkZWQgb24gdGhhdCBwYWdlLgogNi4gWW91IHdpbGwgZmlyc3QgYmUgYXNrZWQgdG8gbWFwIHRoZSBhdXRob3JzIGluIHRoaXMgZXhwb3J0IGZpbGUgdG8gdXNlcnMKICAgIG9uIHRoZSBzaXRlLiBGb3IgZWFjaCBhdXRob3IsIHlvdSBtYXkgY2hvb3NlIHRvIG1hcCB0byBhbgogICAgZXhpc3RpbmcgdXNlciBvbiB0aGUgc2l0ZSBvciB0byBjcmVhdGUgYSBuZXcgdXNlci4KIDcuIFdvcmRQcmVzcyB3aWxsIHRoZW4gaW1wb3J0IGVhY2ggb2YgdGhlIHBvc3RzLCBwYWdlcywgY29tbWVudHMsIGNhdGVnb3JpZXMsIGV0Yy4KICAgIGNvbnRhaW5lZCBpbiB0aGlzIGZpbGUgaW50byB5b3VyIHNpdGUuCgpDT01NRU5UOwoJCXJldHVybiAkb3h5bWVsCgkJCS0+eG1sCgkJCS0+Y29tbWVudCggJGNvbW1lbnQgKQoJCQktPnJhdyggJHdwX2dlbmVyYXRvcl90YWcgKQoJCQktPm9wZW5fcnNzKAoJCQkJWwoJCQkJCSd2ZXJzaW9uJyAgICAgICA9PiAnMi4wJywKCQkJCQkneG1sbnM6ZXhjZXJwdCcgPT4gImh0dHA6Ly93b3JkcHJlc3Mub3JnL2V4cG9ydC97JHRoaXMtPnd4cl92ZXJzaW9ufS9leGNlcnB0LyIsCgkJCQkJJ3htbG5zOmNvbnRlbnQnID0+ICdodHRwOi8vcHVybC5vcmcvcnNzLzEuMC9tb2R1bGVzL2NvbnRlbnQvJywKCQkJCQkneG1sbnM6d2Z3JyAgICAgPT4gJ2h0dHA6Ly93ZWxsZm9ybWVkd2ViLm9yZy9Db21tZW50QVBJLycsCgkJCQkJJ3htbG5zOmRjJyAgICAgID0+ICdodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLycsCgkJCQkJJ3htbG5zOndwJyAgICAgID0+ICJodHRwOi8vd29yZHByZXNzLm9yZy9leHBvcnQveyR0aGlzLT53eHJfdmVyc2lvbn0vIiwKCQkJCV0KCQkJKQoJCQkJLT5vcGVuX2NoYW5uZWwKCQkJCS0+dG9fc3RyaW5nKCk7CgoJfQoKCXB1YmxpYyBmdW5jdGlvbiBzaXRlX21ldGFkYXRhKCkgewoJCSRveHltZWwgICA9IG5ldyBPeHltZWwoKTsKCQkkbWV0YWRhdGEgPSAkdGhpcy0+ZXhwb3J0LT5zaXRlX21ldGFkYXRhKCk7CgkJcmV0dXJuICRveHltZWwKCQkJLT50aXRsZSggJG1ldGFkYXRhWyduYW1lJ10gKQoJCQktPmxpbmsoICRtZXRhZGF0YVsndXJsJ10gKQoJCQktPmRlc2NyaXB0aW9uKCAkbWV0YWRhdGFbJ2Rlc2NyaXB0aW9uJ10gKQoJCQktPnB1YkRhdGUoICRtZXRhZGF0YVsncHViRGF0ZSddICkKCQkJLT5sYW5ndWFnZSggJG1ldGFkYXRhWydsYW5ndWFnZSddICkKCQkJLT50YWcoICd3cDp3eHJfdmVyc2lvbicsICR0aGlzLT53eHJfdmVyc2lvbiApCgkJCS0+dGFnKCAnd3A6YmFzZV9zaXRlX3VybCcsICRtZXRhZGF0YVsnc2l0ZV91cmwnXSApCgkJCS0+dGFnKCAnd3A6YmFzZV9ibG9nX3VybCcsICRtZXRhZGF0YVsnYmxvZ191cmwnXSApCgkJCS0+dG9fc3RyaW5nKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGF1dGhvcnMoKSB7CgkJJG94eW1lbCAgPSBuZXcgT3h5bWVsKCk7CgkJJGF1dGhvcnMgPSAkdGhpcy0+ZXhwb3J0LT5hdXRob3JzKCk7CgkJZm9yZWFjaCAoICRhdXRob3JzIGFzICRhdXRob3IgKSB7CgkJCSRveHltZWwKCQkJCS0+dGFnKCAnd3A6YXV0aG9yJyApLT5jb250YWlucwoJCQkJCS0+dGFnKCAnd3A6YXV0aG9yX2lkJywgJGF1dGhvci0+SUQgKQoJCQkJCS0+dGFnKCAnd3A6YXV0aG9yX2xvZ2luJywgJGF1dGhvci0+dXNlcl9sb2dpbiApCgkJCQkJLT50YWcoICd3cDphdXRob3JfZW1haWwnLCAkYXV0aG9yLT51c2VyX2VtYWlsICkKCQkJCQktPnRhZyggJ3dwOmF1dGhvcl9kaXNwbGF5X25hbWUnICktPmNvbnRhaW5zLT5jZGF0YSggJGF1dGhvci0+ZGlzcGxheV9uYW1lICktPmVuZAoJCQkJCS0+dGFnKCAnd3A6YXV0aG9yX2ZpcnN0X25hbWUnICktPmNvbnRhaW5zLT5jZGF0YSggJGF1dGhvci0+dXNlcl9maXJzdG5hbWUgKS0+ZW5kCgkJCQkJLT50YWcoICd3cDphdXRob3JfbGFzdF9uYW1lJyApLT5jb250YWlucy0+Y2RhdGEoICRhdXRob3ItPnVzZXJfbGFzdG5hbWUgKS0+ZW5kCgkJCQkJLT5lbmQ7CgkJfQoJCXJldHVybiAkb3h5bWVsLT50b19zdHJpbmcoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY2F0ZWdvcmllcygpIHsKCQkkb3h5bWVsICAgICA9IG5ldyBXUF9FeHBvcnRfT3h5bWVsKCk7CgkJJGNhdGVnb3JpZXMgPSAkdGhpcy0+ZXhwb3J0LT5jYXRlZ29yaWVzKCk7CgkJZm9yZWFjaCAoICRjYXRlZ29yaWVzIGFzICRjYXRlZ29yeSApIHsKCQkJJGNhdGVnb3J5LT5wYXJlbnRfc2x1ZyA9ICRjYXRlZ29yeS0+cGFyZW50ID8gJGNhdGVnb3JpZXNbICRjYXRlZ29yeS0+cGFyZW50IF0tPnNsdWcgOiAnJzsKCQkJJG94eW1lbC0+dGFnKCAnd3A6Y2F0ZWdvcnknICktPmNvbnRhaW5zCgkJCQktPnRhZyggJ3dwOnRlcm1faWQnLCAkY2F0ZWdvcnktPnRlcm1faWQgKQoJCQkJLT50YWcoICd3cDpjYXRlZ29yeV9uaWNlbmFtZScsICRjYXRlZ29yeS0+c2x1ZyApCgkJCQktPnRhZyggJ3dwOmNhdGVnb3J5X3BhcmVudCcsICRjYXRlZ29yeS0+cGFyZW50X3NsdWcgKQoJCQkJLT5vcHRpb25hbF9jZGF0YSggJ3dwOmNhdF9uYW1lJywgJGNhdGVnb3J5LT5uYW1lICkKCQkJCS0+b3B0aW9uYWxfY2RhdGEoICd3cDpjYXRlZ29yeV9kZXNjcmlwdGlvbicsICRjYXRlZ29yeS0+ZGVzY3JpcHRpb24gKQoJCQkJLT5lbmQ7CgkJfQoJCXJldHVybiAkb3h5bWVsLT50b19zdHJpbmcoKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdGFncygpIHsKCQkkb3h5bWVsID0gbmV3IFdQX0V4cG9ydF9PeHltZWwoKTsKCQkkdGFncyAgID0gJHRoaXMtPmV4cG9ydC0+dGFncygpOwoJCWZvcmVhY2ggKCAkdGFncyBhcyAkdGFnICkgewoJCQkkb3h5bWVsLT50YWcoICd3cDp0YWcnICktPmNvbnRhaW5zCgkJCQktPnRhZyggJ3dwOnRlcm1faWQnLCAkdGFnLT50ZXJtX2lkICkKCQkJCS0+dGFnKCAnd3A6dGFnX3NsdWcnLCAkdGFnLT5zbHVnICkKCQkJCS0+b3B0aW9uYWxfY2RhdGEoICd3cDp0YWdfbmFtZScsICR0YWctPm5hbWUgKQoJCQkJLT5vcHRpb25hbF9jZGF0YSggJ3dwOnRhZ19kZXNjcmlwdGlvbicsICR0YWctPmRlc2NyaXB0aW9uICkKCQkJCS0+ZW5kOwoJCX0KCQlyZXR1cm4gJG94eW1lbC0+dG9fc3RyaW5nKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG5hdl9tZW51X3Rlcm1zKCkgewoJCXJldHVybiAkdGhpcy0+dGVybXMoICR0aGlzLT5leHBvcnQtPm5hdl9tZW51X3Rlcm1zKCkgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY3VzdG9tX3RheG9ub21pZXNfdGVybXMoKSB7CgkJcmV0dXJuICR0aGlzLT50ZXJtcyggJHRoaXMtPmV4cG9ydC0+Y3VzdG9tX3RheG9ub21pZXNfdGVybXMoKSApOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByc3MyX2hlYWRfYWN0aW9uKCkgewoJCW9iX3N0YXJ0KCk7CgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBXb3JkUHJlc3MgbmF0aXZlIGhvb2suCgkJZG9fYWN0aW9uKCAncnNzMl9oZWFkJyApOwoJCXJldHVybiBvYl9nZXRfY2xlYW4oKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcG9zdCggJHBvc3QgKSB7CgkJJG94eW1lbCAgICAgICAgICAgICAgICAgICAgICAgICAgID0gbmV3IFdQX0V4cG9ydF9PeHltZWwoKTsKCQkkR0xPQkFMU1snd3BfcXVlcnknXS0+aW5fdGhlX2xvb3AgPSB0cnVlOwoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuV1AuR2xvYmFsVmFyaWFibGVzT3ZlcnJpZGUuUHJvaGliaXRlZCAtLSBJbnRlbnRpb25hbC4KCQkkR0xPQkFMU1sncG9zdCddID0gJHBvc3Q7CgkJc2V0dXBfcG9zdGRhdGEoICRwb3N0ICk7CgoJCSRveHltZWwtPml0ZW0tPmNvbnRhaW5zCgkJCS0+dGl0bGUoIGFwcGx5X2ZpbHRlcnMoICd0aGVfdGl0bGVfcnNzJywgJHBvc3QtPnBvc3RfdGl0bGUgKSApIC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gV29yZFByZXNzIG5hdGl2ZSBob29rLgoJCQktPmxpbmsoIGVzY191cmwoIGFwcGx5X2ZpbHRlcnMoICd0aGVfcGVybWFsaW5rX3JzcycsIGdldF9wZXJtYWxpbmsoKSApICkgKSAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFdvcmRQcmVzcyBuYXRpdmUgaG9vay4KCQkJLT5wdWJEYXRlKCBteXNxbDJkYXRlKCAnRCwgZCBNIFkgSDppOnMgKzAwMDAnLCBnZXRfcG9zdF90aW1lKCAnWS1tLWQgSDppOnMnLCB0cnVlICksIGZhbHNlICkgKQoJCQktPnRhZyggJ2RjOmNyZWF0b3InLCBnZXRfdGhlX2F1dGhvcl9tZXRhKCAnbG9naW4nICkgKQoJCQktPmd1aWQoIGVzY191cmwoIGdldF90aGVfZ3VpZCgpICksIFsgJ2lzUGVybWFMaW5rJyA9PiAnZmFsc2UnIF0gKQoJCQktPmRlc2NyaXB0aW9uKCAnJyApCgkJCS0+dGFnKCAnY29udGVudDplbmNvZGVkJyApLT5jb250YWlucy0+Y2RhdGEoICRwb3N0LT5wb3N0X2NvbnRlbnQgKS0+ZW5kCgkJCS0+dGFnKCAnZXhjZXJwdDplbmNvZGVkJyApLT5jb250YWlucy0+Y2RhdGEoICRwb3N0LT5wb3N0X2V4Y2VycHQgKS0+ZW5kCgkJCS0+dGFnKCAnd3A6cG9zdF9pZCcsICRwb3N0LT5JRCApCgkJCS0+dGFnKCAnd3A6cG9zdF9kYXRlJywgJHBvc3QtPnBvc3RfZGF0ZSApCgkJCS0+dGFnKCAnd3A6cG9zdF9kYXRlX2dtdCcsICRwb3N0LT5wb3N0X2RhdGVfZ210ICkKCQkJLT50YWcoICd3cDpwb3N0X21vZGlmaWVkJywgJHBvc3QtPnBvc3RfbW9kaWZpZWQgKQoJCQktPnRhZyggJ3dwOnBvc3RfbW9kaWZpZWRfZ210JywgJHBvc3QtPnBvc3RfbW9kaWZpZWRfZ210ICkKCQkJLT50YWcoICd3cDpjb21tZW50X3N0YXR1cycsICRwb3N0LT5jb21tZW50X3N0YXR1cyApCgkJCS0+dGFnKCAnd3A6cGluZ19zdGF0dXMnLCAkcG9zdC0+cGluZ19zdGF0dXMgKQoJCQktPnRhZyggJ3dwOnBvc3RfbmFtZScsICRwb3N0LT5wb3N0X25hbWUgKQoJCQktPnRhZyggJ3dwOnN0YXR1cycsICRwb3N0LT5wb3N0X3N0YXR1cyApCgkJCS0+dGFnKCAnd3A6cG9zdF9wYXJlbnQnLCAkcG9zdC0+cG9zdF9wYXJlbnQgKQoJCQktPnRhZyggJ3dwOm1lbnVfb3JkZXInLCAkcG9zdC0+bWVudV9vcmRlciApCgkJCS0+dGFnKCAnd3A6cG9zdF90eXBlJywgJHBvc3QtPnBvc3RfdHlwZSApCgkJCS0+dGFnKCAnd3A6cG9zdF9wYXNzd29yZCcsICRwb3N0LT5wb3N0X3Bhc3N3b3JkICkKCQkJLT50YWcoICd3cDppc19zdGlja3knLCAkcG9zdC0+aXNfc3RpY2t5ICkKCQkJLT5vcHRpb25hbCggJ3dwOmF0dGFjaG1lbnRfdXJsJywgd3BfZ2V0X2F0dGFjaG1lbnRfdXJsKCAkcG9zdC0+SUQgKSApOwoJCWZvcmVhY2ggKCAkcG9zdC0+dGVybXMgYXMgJHRlcm0gKSB7CgkJCSRveHltZWwKCQkJLT5jYXRlZ29yeSgKCQkJCVsKCQkJCQknZG9tYWluJyAgID0+ICR0ZXJtLT50YXhvbm9teSwKCQkJCQknbmljZW5hbWUnID0+ICR0ZXJtLT5zbHVnLAoJCQkJXQoJCQkpLT5jb250YWlucy0+Y2RhdGEoICR0ZXJtLT5uYW1lICktPmVuZDsKCQl9CgkJZm9yZWFjaCAoICRwb3N0LT5tZXRhIGFzICRtZXRhICkgewoJCQkkb3h5bWVsCgkJCS0+dGFnKCAnd3A6cG9zdG1ldGEnICktPmNvbnRhaW5zCgkJCQktPnRhZyggJ3dwOm1ldGFfa2V5JywgJG1ldGEtPm1ldGFfa2V5ICkKCQkJCS0+dGFnKCAnd3A6bWV0YV92YWx1ZScgKS0+Y29udGFpbnMtPmNkYXRhKCAkbWV0YS0+bWV0YV92YWx1ZSApLT5lbmQKCQkJCS0+ZW5kOwoJCX0KCQlmb3JlYWNoICggJHBvc3QtPmNvbW1lbnRzIGFzICRjb21tZW50ICkgewoJCQkkb3h5bWVsCgkJCS0+dGFnKCAnd3A6Y29tbWVudCcgKS0+Y29udGFpbnMKCQkJCS0+dGFnKCAnd3A6Y29tbWVudF9pZCcsICRjb21tZW50LT5jb21tZW50X0lEICkKCQkJCS0+dGFnKCAnd3A6Y29tbWVudF9hdXRob3InICktPmNvbnRhaW5zLT5jZGF0YSggJGNvbW1lbnQtPmNvbW1lbnRfYXV0aG9yICktPmVuZAoJCQkJLT50YWcoICd3cDpjb21tZW50X2F1dGhvcl9lbWFpbCcsICRjb21tZW50LT5jb21tZW50X2F1dGhvcl9lbWFpbCApCgkJCQktPnRhZyggJ3dwOmNvbW1lbnRfYXV0aG9yX3VybCcsIGVzY191cmwoICRjb21tZW50LT5jb21tZW50X2F1dGhvcl91cmwgKSApCgkJCQktPnRhZyggJ3dwOmNvbW1lbnRfYXV0aG9yX0lQJywgJGNvbW1lbnQtPmNvbW1lbnRfYXV0aG9yX0lQICkKCQkJCS0+dGFnKCAnd3A6Y29tbWVudF9kYXRlJywgJGNvbW1lbnQtPmNvbW1lbnRfZGF0ZSApCgkJCQktPnRhZyggJ3dwOmNvbW1lbnRfZGF0ZV9nbXQnLCAkY29tbWVudC0+Y29tbWVudF9kYXRlX2dtdCApCgkJCQktPnRhZyggJ3dwOmNvbW1lbnRfY29udGVudCcgKS0+Y29udGFpbnMtPmNkYXRhKCAkY29tbWVudC0+Y29tbWVudF9jb250ZW50ICktPmVuZAoJCQkJLT50YWcoICd3cDpjb21tZW50X2FwcHJvdmVkJywgJGNvbW1lbnQtPmNvbW1lbnRfYXBwcm92ZWQgKQoJCQkJLT50YWcoICd3cDpjb21tZW50X3R5cGUnLCAkY29tbWVudC0+Y29tbWVudF90eXBlICkKCQkJCS0+dGFnKCAnd3A6Y29tbWVudF9wYXJlbnQnLCAkY29tbWVudC0+Y29tbWVudF9wYXJlbnQgKQoJCQkJLT50YWcoICd3cDpjb21tZW50X3VzZXJfaWQnLCAkY29tbWVudC0+dXNlcl9pZCApCgkJCQktPm94eW1lbCggJHRoaXMtPmNvbW1lbnRfbWV0YSggJGNvbW1lbnQgKSApCgkJCQktPmVuZDsKCQl9CgkJJG94eW1lbAoJCQktPmVuZDsKCQlyZXR1cm4gJG94eW1lbC0+dG9fc3RyaW5nKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGZvb3RlcigpIHsKCQkkb3h5bWVsID0gbmV3IE94eW1lbCgpOwoJCXJldHVybiAkb3h5bWVsLT5jbG9zZV9jaGFubmVsLT5jbG9zZV9yc3MtPnRvX3N0cmluZygpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiB0ZXJtcyggJHRlcm1zICkgewoJCSRveHltZWwgPSBuZXcgV1BfRXhwb3J0X094eW1lbCgpOwoJCWZvcmVhY2ggKCAkdGVybXMgYXMgJHRlcm0gKSB7CgkJCSR0ZXJtLT5wYXJlbnRfc2x1ZyA9ICR0ZXJtLT5wYXJlbnQgPyAkdGVybXNbICR0ZXJtLT5wYXJlbnQgXS0+c2x1ZyA6ICcnOwoJCQkkb3h5bWVsLT50YWcoICd3cDp0ZXJtJyApLT5jb250YWlucwoJCQkJLT50YWcoICd3cDp0ZXJtX2lkJywgJHRlcm0tPnRlcm1faWQgKQoJCQkJLT50YWcoICd3cDp0ZXJtX3RheG9ub215JywgJHRlcm0tPnRheG9ub215ICkKCQkJCS0+dGFnKCAnd3A6dGVybV9zbHVnJywgJHRlcm0tPnNsdWcgKTsKCQkJaWYgKCAnbmF2X21lbnUnICE9PSAkdGVybS0+dGF4b25vbXkgKSB7CgkJCQkkb3h5bWVsCgkJCQktPnRhZyggJ3dwOnRlcm1fcGFyZW50JywgJHRlcm0tPnBhcmVudF9zbHVnICk7CgkJCX0KCQkJCSRveHltZWwKCQkJCS0+b3B0aW9uYWxfY2RhdGEoICd3cDp0ZXJtX25hbWUnLCAkdGVybS0+bmFtZSApCgkJCQktPm9wdGlvbmFsX2NkYXRhKCAnd3A6dGVybV9kZXNjcmlwdGlvbicsICR0ZXJtLT5kZXNjcmlwdGlvbiApCgkJCQktPmVuZDsKCQl9CgkJcmV0dXJuICRveHltZWwtPnRvX3N0cmluZygpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiBjb21tZW50X21ldGEoICRjb21tZW50ICkgewoJCWdsb2JhbCAkd3BkYjsKCQkkbWV0YXMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUICogRlJPTSAkd3BkYi0+Y29tbWVudG1ldGEgV0hFUkUgY29tbWVudF9pZCA9ICVkIiwgJGNvbW1lbnQtPmNvbW1lbnRfSUQgKSApOwoJCWlmICggISAkbWV0YXMgKSB7CgkJCXJldHVybiBuZXcgT3h5bWVsKCk7CgkJfQoJCSRveHltZWwgPSBuZXcgV1BfRXhwb3J0X094eW1lbCgpOwoJCWZvcmVhY2ggKCAkbWV0YXMgYXMgJG1ldGEgKSB7CgkJCSRveHltZWwtPnRhZyggJ3dwOmNvbW1lbnRtZXRhJyApLT5jb250YWlucwoJCQkJLT50YWcoICd3cDptZXRhX2tleScsICRtZXRhLT5tZXRhX2tleSApCgkJCQktPnRhZyggJ3dwOm1ldGFfdmFsdWUnICktPmNvbnRhaW5zLT5jZGF0YSggJG1ldGEtPm1ldGFfdmFsdWUgKS0+ZW5kCgkJCS0+ZW5kOwoJCX0KCQlyZXR1cm4gJG94eW1lbDsKCX0KfQo8P3BocAoKY2xhc3MgV1BfRXhwb3J0X094eW1lbCBleHRlbmRzIE94eW1lbCB7CglwdWJsaWMgZnVuY3Rpb24gb3B0aW9uYWwoICR0YWdfbmFtZSwgJGNvbnRlbnRzICkgewoJCWlmICggKCBwcm9wZXJ0eV9leGlzdHMoICR0aGlzLCAkdGFnX25hbWUgKSB8fCBtZXRob2RfZXhpc3RzKCAkdGhpcywgJHRhZ19uYW1lICkgKSAmJiAkY29udGVudHMgKSB7CgkJCSR0aGlzLT4kdGFnX25hbWUoICRjb250ZW50cyApOwoJCX0KCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG9wdGlvbmFsX2NkYXRhKCAkdGFnX25hbWUsICRjb250ZW50cyApIHsKCQlpZiAoIHByb3BlcnR5X2V4aXN0cyggJHRoaXMsICR0YWdfbmFtZSApICYmIGlzX29iamVjdCggJHRoaXMtPiR0YWdfbmFtZSApICYmICRjb250ZW50cyApIHsKCQkJJHRoaXMtPiR0YWdfbmFtZS0+Y29udGFpbnMtPmNkYXRhKCAkY29udGVudHMgKS0+ZW5kOwoJCX0KCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNkYXRhKCAkdGV4dCApIHsKCQlpZiAoIGlzX3N0cmluZyggJHRleHQgKSAmJiAhIHNlZW1zX3V0ZjgoICR0ZXh0ICkgKSB7CgkJCSR0ZXh0ID0gdXRmOF9lbmNvZGUoICR0ZXh0ICk7CgkJfQoJCXJldHVybiBwYXJlbnQ6OmNkYXRhKCAkdGV4dCApOwoJfQp9Cgo8P3BocAoKY2xhc3MgV1BfRXhwb3J0X1NwbGl0X0ZpbGVzX1dyaXRlciBleHRlbmRzIFdQX0V4cG9ydF9CYXNlX1dyaXRlciB7Cglwcml2YXRlICRtYXhfZmlsZV9zaXplOwoJcHJpdmF0ZSAkZGVzdGluYXRpb25fZGlyZWN0b3J5OwoJcHJpdmF0ZSAkZmlsZW5hbWVfdGVtcGxhdGU7Cglwcml2YXRlICRiZWZvcmVfcG9zdHNfeG1sOwoJcHJpdmF0ZSAkYWZ0ZXJfcG9zdHNfeG1sOwoKCXByaXZhdGUgJGY7Cglwcml2YXRlICRuZXh0X2ZpbGVfbnVtYmVyICA9IDA7Cglwcml2YXRlICRjdXJyZW50X2ZpbGVfc2l6ZSA9IDA7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZm9ybWF0dGVyLCAkd3JpdGVyX2FyZ3MgPSBbXSApIHsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCAkZm9ybWF0dGVyICk7CgoJCWlmICggISBkZWZpbmVkKCAnTUJfSU5fQllURVMnICkgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQgLS0gV29yZFByZXNzIG5hdGl2ZSBjb25zdGFudHMuCgkJCWRlZmluZSggJ01CX0lOX0JZVEVTJywgMTAyNCAqIDEwMjQgKTsKCQl9CgoJCS8vVE9ETzogY2hlY2sgaWYgYXJncyBhcmUgbm90IG1pc3NpbmcKCQlpZiAoIGlzX251bGwoICR3cml0ZXJfYXJnc1snbWF4X2ZpbGVfc2l6ZSddICkgKSB7CgkJCSR0aGlzLT5tYXhfZmlsZV9zaXplID0gMTUgKiBNQl9JTl9CWVRFUzsKCQl9IGVsc2VpZiAoIFdQX0NMSV9FWFBPUlRfQ09NTUFORF9OT19TUExJVCA9PT0gKHN0cmluZykgJHdyaXRlcl9hcmdzWydtYXhfZmlsZV9zaXplJ10gKSB7CgkJCSR0aGlzLT5tYXhfZmlsZV9zaXplID0gV1BfQ0xJX0VYUE9SVF9DT01NQU5EX05PX1NQTElUOwoJCX0gZWxzZSB7CgkJCSR0aGlzLT5tYXhfZmlsZV9zaXplID0gJHdyaXRlcl9hcmdzWydtYXhfZmlsZV9zaXplJ10gKiBNQl9JTl9CWVRFUzsKCQl9CgoJCSR0aGlzLT5kZXN0aW5hdGlvbl9kaXJlY3RvcnkgPSAkd3JpdGVyX2FyZ3NbJ2Rlc3RpbmF0aW9uX2RpcmVjdG9yeSddOwoJCSR0aGlzLT5maWxlbmFtZV90ZW1wbGF0ZSAgICAgPSAkd3JpdGVyX2FyZ3NbJ2ZpbGVuYW1lX3RlbXBsYXRlJ107CgkJJHRoaXMtPmJlZm9yZV9wb3N0c194bWwgICAgICA9ICR0aGlzLT5mb3JtYXR0ZXItPmJlZm9yZV9wb3N0cygpOwoJCSR0aGlzLT5hZnRlcl9wb3N0c194bWwgICAgICAgPSAkdGhpcy0+Zm9ybWF0dGVyLT5hZnRlcl9wb3N0cygpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBleHBvcnQoKSB7CgkJJHRoaXMtPnN0YXJ0X25ld19maWxlKCk7CgkJZm9yZWFjaCAoICR0aGlzLT5mb3JtYXR0ZXItPnBvc3RzKCkgYXMgJHBvc3RfeG1sICkgewoJCQlpZiAoIFdQX0NMSV9FWFBPUlRfQ09NTUFORF9OT19TUExJVCAhPT0gJHRoaXMtPm1heF9maWxlX3NpemUgJiYgJHRoaXMtPmN1cnJlbnRfZmlsZV9zaXplICsgc3RybGVuKCAkcG9zdF94bWwgKSA+ICR0aGlzLT5tYXhfZmlsZV9zaXplICkgewoJCQkJJHRoaXMtPnN0YXJ0X25ld19maWxlKCk7CgkJCX0KCQkJJHRoaXMtPndyaXRlKCAkcG9zdF94bWwgKTsKCQl9CgkJJHRoaXMtPmNsb3NlX2N1cnJlbnRfZmlsZSgpOwoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSggJHhtbCApIHsKCQkkcmVzID0gZndyaXRlKCAkdGhpcy0+ZiwgJHhtbCApOwoJCWlmICggZmFsc2UgPT09ICRyZXMgKSB7CgkJCXRocm93IG5ldyBXUF9FeHBvcnRfRXhjZXB0aW9uKCAnV1AgRXhwb3J0OiBlcnJvciB3cml0aW5nIHRvIGV4cG9ydCBmaWxlLicgKTsKCQl9CgkJJHRoaXMtPmN1cnJlbnRfZmlsZV9zaXplICs9IHN0cmxlbiggJHhtbCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc3RhcnRfbmV3X2ZpbGUoKSB7CgkJaWYgKCAkdGhpcy0+ZiApIHsKCQkJJHRoaXMtPmNsb3NlX2N1cnJlbnRfZmlsZSgpOwoJCX0KCQkkZmlsZV9wYXRoID0gJHRoaXMtPm5leHRfZmlsZV9wYXRoKCk7CgkJJHRoaXMtPmYgICA9IGZvcGVuKCAkZmlsZV9wYXRoLCAndycgKTsKCQlpZiAoICEgJHRoaXMtPmYgKSB7CgkJCXRocm93IG5ldyBXUF9FeHBvcnRfRXhjZXB0aW9uKCAiV1AgRXhwb3J0OiBlcnJvciBvcGVuaW5nIHskZmlsZV9wYXRofSBmb3Igd3JpdGluZy4iICk7CgkJfQoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gUG9zc2libHkgdXNlZCBieSB0aGlyZCBwYXJ0eSBleHRlbnNpb24uCgkJZG9fYWN0aW9uKCAnd3BfZXhwb3J0X25ld19maWxlJywgJGZpbGVfcGF0aCApOwoJCSR0aGlzLT5jdXJyZW50X2ZpbGVfc2l6ZSA9IDA7CgkJJHRoaXMtPndyaXRlKCAkdGhpcy0+YmVmb3JlX3Bvc3RzX3htbCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gY2xvc2VfY3VycmVudF9maWxlKCkgewoJCWlmICggISAkdGhpcy0+ZiApIHsKCQkJcmV0dXJuOwoJCX0KCQkkdGhpcy0+d3JpdGUoICR0aGlzLT5hZnRlcl9wb3N0c194bWwgKTsKCQlmY2xvc2UoICR0aGlzLT5mICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBuZXh0X2ZpbGVfbmFtZSgpIHsKCQkkbmV4dF9maWxlX25hbWUgPSBzcHJpbnRmKCAkdGhpcy0+ZmlsZW5hbWVfdGVtcGxhdGUsICR0aGlzLT5uZXh0X2ZpbGVfbnVtYmVyICk7CgkJJHRoaXMtPm5leHRfZmlsZV9udW1iZXIrKzsKCQlyZXR1cm4gJG5leHRfZmlsZV9uYW1lOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gbmV4dF9maWxlX3BhdGgoKSB7CgkJcmV0dXJuIHVudHJhaWxpbmdzbGFzaGl0KCAkdGhpcy0+ZGVzdGluYXRpb25fZGlyZWN0b3J5ICkgLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJHRoaXMtPm5leHRfZmlsZV9uYW1lKCk7Cgl9Cgp9Cjw/cGhwCgpjbGFzcyBXUF9JdGVyYXRvcl9FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewp9Cjw/cGhwCgoKY2xhc3MgV1BfRXhwb3J0X1hNTF9PdmVyX0hUVFAgZXh0ZW5kcyBXUF9FeHBvcnRfQmFzZV9Xcml0ZXIgewoJcHJpdmF0ZSAkZmlsZV9uYW1lOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggJGZvcm1hdHRlciwgJGZpbGVfbmFtZSApIHsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCAkZm9ybWF0dGVyICk7CgkJJHRoaXMtPmZpbGVfbmFtZSA9ICRmaWxlX25hbWU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGV4cG9ydCgpIHsKCQl0cnkgewoJCQkkZXhwb3J0ID0gJHRoaXMtPmdldF9leHBvcnQoKTsKCQkJJHRoaXMtPnNlbmRfaGVhZGVycygpOwoJCQllY2hvICRleHBvcnQ7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9FeGNlcHRpb24gJGUgKSB7CgkJCS8vIHBocGNzOmRpc2FibGUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIFBvc3NpYmx5IHVzZWQgYnkgdGhpcmQgcGFydHkgZXh0ZW5zaW9uLgoJCQkkbWVzc2FnZSA9IGFwcGx5X2ZpbHRlcnMoICdleHBvcnRfZXJyb3JfbWVzc2FnZScsICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJd3BfZGllKCAkbWVzc2FnZSwgX18oICdFeHBvcnQgRXJyb3InICksIFsgJ2JhY2tfbGluaycgPT4gdHJ1ZSBdICk7CgkJfSBjYXRjaCAoIFdQX0V4cG9ydF9UZXJtX0V4Y2VwdGlvbiAkZSApIHsKCQkJZG9fYWN0aW9uKCAnZXhwb3J0X3Rlcm1fb3JwaGFuZWQnLCAkdGhpcy0+Zm9ybWF0dGVyLT5leHBvcnQtPm1pc3NpbmdfcGFyZW50cyApOwoJCQkkbWVzc2FnZSA9IGFwcGx5X2ZpbHRlcnMoICdleHBvcnRfdGVybV9lcnJvcl9tZXNzYWdlJywgJGUtPmdldE1lc3NhZ2UoKSApOwoJCQkvLyBwaHBjczplbmFibGUKCQkJd3BfZGllKCAkbWVzc2FnZSwgX18oICdFeHBvcnQgRXJyb3InICksIFsgJ2JhY2tfbGluaycgPT4gdHJ1ZSBdICk7CgkJfQoJfQoKCXByb3RlY3RlZCBmdW5jdGlvbiB3cml0ZSggJHhtbCApIHsKCQkkdGhpcy0+cmVzdWx0IC49ICR4bWw7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9leHBvcnQoKSB7CgkJJHRoaXMtPnJlc3VsdCA9ICcnOwoJCXBhcmVudDo6ZXhwb3J0KCk7CgkJcmV0dXJuICR0aGlzLT5yZXN1bHQ7Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNlbmRfaGVhZGVycygpIHsKCQloZWFkZXIoICdDb250ZW50LURlc2NyaXB0aW9uOiBGaWxlIFRyYW5zZmVyJyApOwoJCWhlYWRlciggJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPScgLiAkdGhpcy0+ZmlsZV9uYW1lICk7CgkJaGVhZGVyKCAnQ29udGVudC1UeXBlOiB0ZXh0L3htbDsgY2hhcnNldD0nIC4gZ2V0X29wdGlvbiggJ2Jsb2dfY2hhcnNldCcgKSwgdHJ1ZSApOwoJfQp9Cjw/cGhwCgphYnN0cmFjdCBjbGFzcyBXUF9FeHBvcnRfQmFzZV9Xcml0ZXIgewoJcHJvdGVjdGVkICRmb3JtYXR0ZXI7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkZm9ybWF0dGVyICkgewoJCSR0aGlzLT5mb3JtYXR0ZXIgPSAkZm9ybWF0dGVyOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBleHBvcnQoKSB7CgkJJHRoaXMtPndyaXRlKCAkdGhpcy0+Zm9ybWF0dGVyLT5iZWZvcmVfcG9zdHMoKSApOwoJCWZvcmVhY2ggKCAkdGhpcy0+Zm9ybWF0dGVyLT5wb3N0cygpIGFzICRwb3N0X2luX3d4ciApIHsKCQkJJHRoaXMtPndyaXRlKCAkcG9zdF9pbl93eHIgKTsKCQl9CgkJJHRoaXMtPndyaXRlKCAkdGhpcy0+Zm9ybWF0dGVyLT5hZnRlcl9wb3N0cygpICk7Cgl9CgoJYWJzdHJhY3QgcHJvdGVjdGVkIGZ1bmN0aW9uIHdyaXRlKCAkeG1sICk7Cn0KPD9waHAKCmVycm9yX3JlcG9ydGluZygtMSk7CnJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCgokYXJncyA9IG5ldyBjbGlcQXJndW1lbnRzKGFycmF5KAoJJ2ZsYWdzJyA9PiBhcnJheSgKCQkndmVyYm9zZScgPT4gYXJyYXkoCgkJCSdkZXNjcmlwdGlvbicgPT4gJ1R1cm4gb24gdmVyYm9zZSBtb2RlJywKCQkJJ2FsaWFzZXMnICAgICA9PiBhcnJheSgndicpCgkJKSwKCQknYycgPT4gYXJyYXkoCgkJCSdkZXNjcmlwdGlvbicgPT4gJ0EgY291bnRlciB0byB0ZXN0IHN0YWNrYWJsZScsCgkJCSdzdGFja2FibGUnICAgPT4gdHJ1ZQoJCSkKCSksCgknb3B0aW9ucycgPT4gYXJyYXkoCgkJJ3VzZXInID0+IGFycmF5KAoJCQknZGVzY3JpcHRpb24nID0+ICdVc2VybmFtZSBmb3IgYXV0aGVudGljYXRpb24nLAoJCQknYWxpYXNlcycgICAgID0+IGFycmF5KCd1JykKCQkpCgkpLAoJJ3N0cmljdCcgPT4gdHJ1ZQopKTsKCnRyeSB7CiAgICAkYXJncy0+cGFyc2UoKTsKfSBjYXRjaCAoY2xpXEludmFsaWRBcmd1bWVudHMgJGUpIHsKICAgIGVjaG8gJGUtPmdldE1lc3NhZ2UoKSAuICJcblxuIjsKfQoKcHJpbnRfcigkYXJncy0+Z2V0QXJndW1lbnRzKCkpOwo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIFJ5YW4gU3VsbGl2YW4gPHJzdWxsaXZhbkBjb25uZWN0c3R1ZGlvcy5jb20+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXHRyZWU7CgovKioKICogVHJlZSByZW5kZXJlcnMgYXJlIHVzZWQgdG8gY2hhbmdlIGhvdyBhIHRyZWUgaXMgZGlzcGxheWVkLgogKi8KYWJzdHJhY3QgY2xhc3MgUmVuZGVyZXIgewoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICR0cmVlCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIGFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiByZW5kZXIoYXJyYXkgJHRyZWUpOwoKfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIFJ5YW4gU3VsbGl2YW4gPHJzdWxsaXZhbkBjb25uZWN0c3R1ZGlvcy5jb20+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXHRyZWU7CgovKioKICogVGhlIEFTQ0lJIHJlbmRlcmVyIHJlbmRlcnMgdHJlZXMgd2l0aCBBU0NJSSBsaW5lcy4KICovCmNsYXNzIE1hcmtkb3duIGV4dGVuZHMgUmVuZGVyZXIgewoKICAgIC8qKgogICAgICogSG93IG1hbnkgc3BhY2VzIHRvIGluZGVudCBieQogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRfcGFkZGluZyA9IDI7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICRwYWRkaW5nIE9wdGlvbmFsLiBEZWZhdWx0IDIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRwYWRkaW5nID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHBhZGRpbmcpCiAgICAgICAgewogICAgICAgICAgICAkdGhpcy0+X3BhZGRpbmcgPSAkcGFkZGluZzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW5kZXJzIHRoZSB0cmVlCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICR0cmVlCiAgICAgKiBAcGFyYW0gaW50ICRsZXZlbCBPcHRpb25hbAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcihhcnJheSAkdHJlZSwgJGxldmVsID0gMCkKICAgIHsKICAgICAgICAkb3V0cHV0ID0gJyc7CgogICAgICAgIGZvcmVhY2ggKCR0cmVlIGFzICRsYWJlbCA9PiAkbmV4dCkKICAgICAgICB7CgogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRuZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgJGxhYmVsID0gJG5leHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE91dHB1dCB0aGUgbGFiZWwKICAgICAgICAgICAgJG91dHB1dCAuPSBzcHJpbnRmKCIlcy0gJXNcbiIsIHN0cl9yZXBlYXQoJyAnLCAkbGV2ZWwgKiAkdGhpcy0+X3BhZGRpbmcpLCAkbGFiZWwpOwoKICAgICAgICAgICAgLy8gTmV4dCBsZXZlbAogICAgICAgICAgICBpZiAoaXNfYXJyYXkoJG5leHQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkb3V0cHV0IC49ICR0aGlzLT5yZW5kZXIoJG5leHQsICRsZXZlbCArIDEpOwogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9Cgp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgUnlhbiBTdWxsaXZhbiA8cnN1bGxpdmFuQGNvbm5lY3RzdHVkaW9zLmNvbT4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdHJlZTsKCi8qKgogKiBUaGUgQVNDSUkgcmVuZGVyZXIgcmVuZGVycyB0cmVlcyB3aXRoIEFTQ0lJIGxpbmVzLgogKi8KY2xhc3MgQXNjaWkgZXh0ZW5kcyBSZW5kZXJlciB7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHRyZWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZW5kZXIoYXJyYXkgJHRyZWUpCiAgICB7CiAgICAgICAgJG91dHB1dCA9ICcnOwoKICAgICAgICAkdHJlZUl0ZXJhdG9yID0gbmV3IFxSZWN1cnNpdmVUcmVlSXRlcmF0b3IoCiAgICAgICAgICAgIG5ldyBcUmVjdXJzaXZlQXJyYXlJdGVyYXRvcigkdHJlZSksCiAgICAgICAgICAgIFxSZWN1cnNpdmVUcmVlSXRlcmF0b3I6OlNFTEZfRklSU1QKICAgICAgICApOwoKICAgICAgICBmb3JlYWNoICgkdHJlZUl0ZXJhdG9yIGFzICR2YWwpCiAgICAgICAgewogICAgICAgICAgICAkb3V0cHV0IC49ICR2YWwgLiAiXG4iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRvdXRwdXQ7CiAgICB9Cgp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGk7Cgp1c2UgY2xpXFNoZWxsOwp1c2UgY2xpXFN0cmVhbXM7CnVzZSBjbGlcdGFibGVcQXNjaWk7CnVzZSBjbGlcdGFibGVcUmVuZGVyZXI7CnVzZSBjbGlcdGFibGVcVGFidWxhcjsKCi8qKgogKiBUaGUgYFRhYmxlYCBjbGFzcyBpcyB1c2VkIHRvIGRpc3BsYXkgZGF0YSBpbiBhIHRhYnVsYXIgZm9ybWF0LgogKi8KY2xhc3MgVGFibGUgewoJcHJvdGVjdGVkICRfcmVuZGVyZXI7Cglwcm90ZWN0ZWQgJF9oZWFkZXJzID0gYXJyYXkoKTsKCXByb3RlY3RlZCAkX2Zvb3RlcnMgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfd2lkdGggPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfcm93cyA9IGFycmF5KCk7CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGUgYFRhYmxlYCBjbGFzcy4KCSAqCgkgKiBUaGVyZSBhcmUgMyB3YXlzIHRvIGluc3RhbnRpYXRlIHRoaXMgY2xhc3M6CgkgKgoJICogIDEuIFBhc3MgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyIGZvciB0aGUgY29sdW1uIGhlYWRlcnMKCSAqICAgICBhbmQgYSAyLWRpbWVuc2lvbmFsIGFycmF5IGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyIGZvciB0aGUgZGF0YSByb3dzLgoJICogIDIuIFBhc3MgYW4gYXJyYXkgb2YgaGFzaCB0YWJsZXMgKHN0cmluZyBpbmRleGVzIGluc3RlYWQgb2YgbnVtZXJpY2FsKQoJICogICAgIHdoZXJlIGVhY2ggaGFzaCB0YWJsZSBpcyBhIHJvdyBhbmQgdGhlIGluZGV4ZXMgb2YgdGhlICpmaXJzdCogaGFzaAoJICogICAgIHRhYmxlIGFyZSB1c2VkIGFzIHRoZSBoZWFkZXIgdmFsdWVzLgoJICogIDMuIFBhc3Mgbm90aGluZyBhbmQgdXNlIGBzZXRIZWFkZXJzKClgIGFuZCBgYWRkUm93KClgIG9yIGBzZXRSb3dzKClgLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMgIEhlYWRlcnMgdXNlZCBpbiB0aGlzIHRhYmxlLiBPcHRpb25hbC4KCSAqIEBwYXJhbSBhcnJheSAgJHJvd3MgICAgIFRoZSByb3dzIG9mIGRhdGEgZm9yIHRoaXMgdGFibGUuIE9wdGlvbmFsLgoJICogQHBhcmFtIGFycmF5ICAkZm9vdGVycyAgRm9vdGVycyB1c2VkIGluIHRoaXMgdGFibGUuIE9wdGlvbmFsLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGhlYWRlcnMgPSBudWxsLCBhcnJheSAkcm93cyA9IG51bGwsIGFycmF5ICRmb290ZXJzID0gbnVsbCkgewoJCWlmICghZW1wdHkoJGhlYWRlcnMpKSB7CgkJCS8vIElmIGFsbCB0aGUgcm93cyBpcyBnaXZlbiBpbiAkaGVhZGVycyB3ZSB1c2UgdGhlIGtleXMgZnJvbSB0aGUKCQkJLy8gZmlyc3Qgcm93IGZvciB0aGUgaGVhZGVyIHZhbHVlcwoJCQlpZiAoJHJvd3MgPT09IG51bGwpIHsKCQkJCSRyb3dzID0gJGhlYWRlcnM7CgkJCQkka2V5cyA9IGFycmF5X2tleXMoYXJyYXlfc2hpZnQoJGhlYWRlcnMpKTsKCQkJCSRoZWFkZXJzID0gYXJyYXkoKTsKCgkJCQlmb3JlYWNoICgka2V5cyBhcyAkaGVhZGVyKSB7CgkJCQkJJGhlYWRlcnNbJGhlYWRlcl0gPSAkaGVhZGVyOwoJCQkJfQoJCQl9CgoJCQkkdGhpcy0+c2V0SGVhZGVycygkaGVhZGVycyk7CgkJCSR0aGlzLT5zZXRSb3dzKCRyb3dzKTsKCQl9CgoJCWlmICghZW1wdHkoJGZvb3RlcnMpKSB7CgkJCSR0aGlzLT5zZXRGb290ZXJzKCRmb290ZXJzKTsKCQl9CgoJCWlmIChTaGVsbDo6aXNQaXBlZCgpKSB7CgkJCSR0aGlzLT5zZXRSZW5kZXJlcihuZXcgVGFidWxhcigpKTsKCQl9IGVsc2UgewoJCQkkdGhpcy0+c2V0UmVuZGVyZXIobmV3IEFzY2lpKCkpOwoJCX0KCX0KCglwdWJsaWMgZnVuY3Rpb24gcmVzZXRUYWJsZSgpCgl7CgkJJHRoaXMtPl9oZWFkZXJzID0gYXJyYXkoKTsKCQkkdGhpcy0+X3dpZHRoID0gYXJyYXkoKTsKCQkkdGhpcy0+X3Jvd3MgPSBhcnJheSgpOwoJCSR0aGlzLT5fZm9vdGVycyA9IGFycmF5KCk7CgkJcmV0dXJuICR0aGlzOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgcmVuZGVyZXIgdXNlZCBieSB0aGlzIHRhYmxlLgoJICoKCSAqIEBwYXJhbSB0YWJsZVxSZW5kZXJlciAgJHJlbmRlcmVyICBUaGUgcmVuZGVyZXIgdG8gdXNlIGZvciBvdXRwdXQuCgkgKiBAc2VlICAgdGFibGVcUmVuZGVyZXIKCSAqIEBzZWUgICB0YWJsZVxBc2NpaQoJICogQHNlZSAgIHRhYmxlXFRhYnVsYXIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldFJlbmRlcmVyKFJlbmRlcmVyICRyZW5kZXJlcikgewoJCSR0aGlzLT5fcmVuZGVyZXIgPSAkcmVuZGVyZXI7Cgl9CgoJLyoqCgkgKiBMb29wcyB0aHJvdWdoIHRoZSByb3cgYW5kIHNldHMgdGhlIG1heGltdW0gd2lkdGggZm9yIGVhY2ggY29sdW1uLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHJvdyAgVGhlIHRhYmxlIHJvdy4KICAgICAqIEByZXR1cm4gYXJyYXkgJHJvdwoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tSb3coYXJyYXkgJHJvdykgewoJCWZvcmVhY2ggKCRyb3cgYXMgJGNvbHVtbiA9PiAkc3RyKSB7CgkJCSR3aWR0aCA9IENvbG9yczo6d2lkdGgoICRzdHIsICR0aGlzLT5pc0FzY2lpUHJlQ29sb3JpemVkKCAkY29sdW1uICkgKTsKCQkJaWYgKCFpc3NldCgkdGhpcy0+X3dpZHRoWyRjb2x1bW5dKSB8fCAkd2lkdGggPiAkdGhpcy0+X3dpZHRoWyRjb2x1bW5dKSB7CgkJCQkkdGhpcy0+X3dpZHRoWyRjb2x1bW5dID0gJHdpZHRoOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHJvdzsKCX0KCgkvKioKCSAqIE91dHB1dCB0aGUgdGFibGUgdG8gYFNURE9VVGAgdXNpbmcgYGNsaVxsaW5lKClgLgoJICoKCSAqIElmIFNURE9VVCBpcyBhIHBpcGUgb3IgcmVkaXJlY3RlZCB0byBhIGZpbGUsIHNob3VsZCBvdXRwdXQgc2ltcGxlCgkgKiB0YWItc2VwYXJhdGVkIHRleHQuIE90aGVyd2lzZSwgcmVuZGVycyB0YWJsZSB3aXRoIEFTQ0lJIHRhYmxlIGJvcmRlcnMKCSAqCgkgKiBAdXNlcyBjbGlcU2hlbGw6OmlzUGlwZWQoKSBEZXRlcm1pbmUgd2hhdCBmb3JtYXQgdG8gb3V0cHV0CgkgKgoJICogQHNlZSBjbGlcVGFibGU6OnJlbmRlclJvdygpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCkgewoJCWZvcmVhY2goICR0aGlzLT5nZXREaXNwbGF5TGluZXMoKSBhcyAkbGluZSApIHsKCQkJU3RyZWFtczo6bGluZSggJGxpbmUgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHRhYmxlIGxpbmVzIHRvIG91dHB1dC4KCSAqCgkgKiBAc2VlIGNsaVxUYWJsZTo6ZGlzcGxheSgpCgkgKiBAc2VlIGNsaVxUYWJsZTo6cmVuZGVyUm93KCkKCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXREaXNwbGF5TGluZXMoKSB7CgkJJHRoaXMtPl9yZW5kZXJlci0+c2V0V2lkdGhzKCR0aGlzLT5fd2lkdGgsICRmYWxsYmFjayA9IHRydWUpOwoJCSRib3JkZXIgPSAkdGhpcy0+X3JlbmRlcmVyLT5ib3JkZXIoKTsKCgkJJG91dCA9IGFycmF5KCk7CgkJaWYgKGlzc2V0KCRib3JkZXIpKSB7CgkJCSRvdXRbXSA9ICRib3JkZXI7CgkJfQoJCSRvdXRbXSA9ICR0aGlzLT5fcmVuZGVyZXItPnJvdygkdGhpcy0+X2hlYWRlcnMpOwoJCWlmIChpc3NldCgkYm9yZGVyKSkgewoJCQkkb3V0W10gPSAkYm9yZGVyOwoJCX0KCgkJZm9yZWFjaCAoJHRoaXMtPl9yb3dzIGFzICRyb3cpIHsKCQkJJHJvdyA9ICR0aGlzLT5fcmVuZGVyZXItPnJvdygkcm93KTsKCQkJJHJvdyA9IGV4cGxvZGUoIFBIUF9FT0wsICRyb3cgKTsKCQkJJG91dCA9IGFycmF5X21lcmdlKCAkb3V0LCAkcm93ICk7CgkJfQoKCQlpZiAoaXNzZXQoJGJvcmRlcikpIHsKCQkJJG91dFtdID0gJGJvcmRlcjsKCQl9CgoJCWlmICgkdGhpcy0+X2Zvb3RlcnMpIHsKCQkJJG91dFtdID0gJHRoaXMtPl9yZW5kZXJlci0+cm93KCR0aGlzLT5fZm9vdGVycyk7CgkJCWlmIChpc3NldCgkYm9yZGVyKSkgewoJCQkJJG91dFtdID0gJGJvcmRlcjsKCQkJfQoJCX0KCQlyZXR1cm4gJG91dDsKCX0KCgkvKioKCSAqIFNvcnQgdGhlIHRhYmxlIGJ5IGEgY29sdW1uLiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgYGNsaVxUYWJsZTo6ZGlzcGxheSgpYC4KCSAqCgkgKiBAcGFyYW0gaW50ICAkY29sdW1uICBUaGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byBzb3J0IGJ5LgoJICovCglwdWJsaWMgZnVuY3Rpb24gc29ydCgkY29sdW1uKSB7CgkJaWYgKCFpc3NldCgkdGhpcy0+X2hlYWRlcnNbJGNvbHVtbl0pKSB7CgkJCXRyaWdnZXJfZXJyb3IoJ05vIGNvbHVtbiB3aXRoIGluZGV4ICcgLiAkY29sdW1uLCBFX1VTRVJfTk9USUNFKTsKCQkJcmV0dXJuOwoJCX0KCgkJdXNvcnQoJHRoaXMtPl9yb3dzLCBmdW5jdGlvbigkYSwgJGIpIHVzZSAoJGNvbHVtbikgewoJCQlyZXR1cm4gc3RyY21wKCRhWyRjb2x1bW5dLCAkYlskY29sdW1uXSk7CgkJfSk7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGhlYWRlcnMgb2YgdGhlIHRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMgIEFuIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyBjb2x1bW4gaGVhZGVyIG5hbWVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0SGVhZGVycyhhcnJheSAkaGVhZGVycykgewoJCSR0aGlzLT5faGVhZGVycyA9ICR0aGlzLT5jaGVja1JvdygkaGVhZGVycyk7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGZvb3RlcnMgb2YgdGhlIHRhYmxlLgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGZvb3RlcnMgIEFuIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyBjb2x1bW4gZm9vdGVycyBuYW1lcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldEZvb3RlcnMoYXJyYXkgJGZvb3RlcnMpIHsKCQkkdGhpcy0+X2Zvb3RlcnMgPSAkdGhpcy0+Y2hlY2tSb3coJGZvb3RlcnMpOwoJfQoKCgkvKioKCSAqIEFkZCBhIHJvdyB0byB0aGUgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkcm93ICBUaGUgcm93IGRhdGEuCgkgKiBAc2VlIGNsaVxUYWJsZTo6Y2hlY2tSb3coKQoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkUm93KGFycmF5ICRyb3cpIHsKCQkkdGhpcy0+X3Jvd3NbXSA9ICR0aGlzLT5jaGVja1Jvdygkcm93KTsKCX0KCgkvKioKCSAqIENsZWFycyBhbGwgcHJldmlvdXMgcm93cyBhbmQgYWRkcyB0aGUgZ2l2ZW4gcm93cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRyb3dzICBBIDItZGltZW5zaW9uYWwgYXJyYXkgb2Ygcm93IGRhdGEuCgkgKiBAc2VlIGNsaVxUYWJsZTo6YWRkUm93KCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldFJvd3MoYXJyYXkgJHJvd3MpIHsKCQkkdGhpcy0+X3Jvd3MgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCRyb3dzIGFzICRyb3cpIHsKCQkJJHRoaXMtPmFkZFJvdygkcm93KTsKCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNvdW50Um93cygpIHsKCQlyZXR1cm4gY291bnQoJHRoaXMtPl9yb3dzKTsKCX0KCgkvKioKCSAqIFNldCB3aGV0aGVyIGl0ZW1zIGluIGFuIEFzY2lpIHRhYmxlIGFyZSBwcmUtY29sb3JpemVkLgoJICoKCSAqIEBwYXJhbSBib29sfGFycmF5ICRwcmVjb2xvcml6ZWQgQSBib29sZWFuIHRvIHNldCBhbGwgY29sdW1ucyBpbiB0aGUgdGFibGUgYXMgcHJlLWNvbG9yaXplZCwgb3IgYW4gYXJyYXkgb2YgYm9vbGVhbnMga2V5ZWQgYnkgY29sdW1uIGluZGV4IChudW1iZXIpIHRvIHNldCBpbmRpdmlkdWFsIGNvbHVtbnMgYXMgcHJlLWNvbG9yaXplZC4KCSAqIEBzZWUgY2xpXEFzY2lpOjpzZXRQcmVDb2xvcml6ZWQoKQoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0QXNjaWlQcmVDb2xvcml6ZWQoICRwcmVfY29sb3JpemVkICkgewoJCWlmICggJHRoaXMtPl9yZW5kZXJlciBpbnN0YW5jZW9mIEFzY2lpICkgewoJCQkkdGhpcy0+X3JlbmRlcmVyLT5zZXRQcmVDb2xvcml6ZWQoICRwcmVfY29sb3JpemVkICk7CgkJfQoJfQoKCS8qKgoJICogSXMgYSBjb2x1bW4gaW4gYW4gQXNjaWkgdGFibGUgcHJlLWNvbG9yaXplZD8KCSAqCgkgKiBAcGFyYW0gaW50ICRjb2x1bW4gQ29sdW1uIGluZGV4IHRvIGNoZWNrLgoJICogQHJldHVybiBib29sIFRydWUgaWYgd2hvbGUgQXNjaWkgdGFibGUgaXMgbWFya2VkIGFzIHByZS1jb2xvcml6ZWQsIG9yIGlmIHRoZSBpbmRpdmlkdWFsIGNvbHVtbiBpcyBwcmUtY29sb3JpemVkOyBlbHNlIGZhbHNlLgoJICogQHNlZSBjbGlcQXNjaWk6OmlzUHJlQ29sb3JpemVkKCkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpc0FzY2lpUHJlQ29sb3JpemVkKCAkY29sdW1uICkgewoJCWlmICggJHRoaXMtPl9yZW5kZXJlciBpbnN0YW5jZW9mIEFzY2lpICkgewoJCQlyZXR1cm4gJHRoaXMtPl9yZW5kZXJlci0+aXNQcmVDb2xvcml6ZWQoICRjb2x1bW4gKTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGk7CgovKioKICogQSBtb3JlIGNvbXBsZXggdHlwZSBvZiBOb3RpZmllciwgYFByb2dyZXNzYCBOb3RpZmllcnMgYWx3YXlzIGhhdmUgYSBtYXhpbQogKiB2YWx1ZSBhbmQgZ2VuZXJhbGx5IHNob3cgc29tZSBmb3JtIG9mIHBlcmNlbnQgY29tcGxldGUgb3IgZXN0aW1hdGVkIHRpbWUKICogdG8gY29tcGxldGlvbiBhbG9uZyB3aXRoIHRoZSBzdGFuZGFyZCBOb3RpZmllciBkaXNwbGF5cy4KICoKICogQHNlZSBjbGlcTm90aWZ5CiAqLwphYnN0cmFjdCBjbGFzcyBQcm9ncmVzcyBleHRlbmRzIFxjbGlcTm90aWZ5IHsKCXByb3RlY3RlZCAkX3RvdGFsID0gMDsKCgkvKioKCSAqIEluc3RhbnRpYXRlcyBhIFByb2dyZXNzIE5vdGlmaWVyLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRtc2cgICAgICAgVGhlIHRleHQgdG8gZGlzcGxheSBuZXh0IHRvIHRoZSBOb3RpZmllci4KCSAqIEBwYXJhbSBpbnQgICAgICR0b3RhbCAgICAgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrcyB3ZSB3aWxsIGJlIHBlcmZvcm1pbmcuCgkgKiBAcGFyYW0gaW50ICAgICAkaW50ZXJ2YWwgIFRoZSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiB1cGRhdGVzLgoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OnNldFRvdGFsKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtc2csICR0b3RhbCwgJGludGVydmFsID0gMTAwKSB7CgkJcGFyZW50OjpfX2NvbnN0cnVjdCgkbXNnLCAkaW50ZXJ2YWwpOwoJCSR0aGlzLT5zZXRUb3RhbCgkdG90YWwpOwoJfQoKCS8qKgoJICogU2V0IHRoZSBtYXggaW5jcmVtZW50cyBmb3IgdGhpcyBwcm9ncmVzcyBub3RpZmllci4KCSAqCgkgKiBAcGFyYW0gaW50ICAkdG90YWwgIFRoZSB0b3RhbCBudW1iZXIgb2YgdGltZXMgdGhpcyBpbmRpY2F0b3Igc2hvdWxkIGJlIGB0aWNrYGVkLgoJICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uICBUaHJvd24gaWYgdGhlIGAkdG90YWxgIGlzIGxlc3MgdGhhbiAwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0VG90YWwoJHRvdGFsKSB7CgkJJHRoaXMtPl90b3RhbCA9IChpbnQpJHRvdGFsOwoKCQlpZiAoJHRoaXMtPl90b3RhbCA8IDApIHsKCQkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ01heGltdW0gdmFsdWUgb3V0IG9mIHJhbmdlLCBtdXN0IGJlIHBvc2l0aXZlLicpOwoJCX0KCX0KCgkvKioKCSAqIFJlc2V0IHRoZSBwcm9ncmVzcyBzdGF0ZSBzbyB0aGUgc2FtZSBpbnN0YW5jZSBjYW4gYmUgdXNlZCBpbiBtdWx0aXBsZSBsb29wcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlc2V0KCR0b3RhbCA9IG51bGwpIHsKCQlwYXJlbnQ6OnJlc2V0KCk7CgoJCWlmICgkdG90YWwpIHsKCQkJJHRoaXMtPnNldFRvdGFsKCR0b3RhbCk7CgkJfQoJfQoKCS8qKgoJICogQmVoYXZlcyBpbiBhIHNpbWlsYXIgbWFubmVyIHRvIGBjbGlcTm90aWZ5OjpjdXJyZW50KClgLCBidXQgdGhlIG91dHB1dAoJICogaXMgcGFkZGVkIHRvIG1hdGNoIHRoZSBsZW5ndGggb2YgYGNsaVxQcm9ncmVzczo6dG90YWwoKWAuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgYW5kIHBhZGRlZCB0aWNrIGNvdW50LgoJICogQHNlZSBjbGlcUHJvZ3Jlc3M6OnRvdGFsKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJJHNpemUgPSBzdHJsZW4oJHRoaXMtPnRvdGFsKCkpOwoJCXJldHVybiBzdHJfcGFkKHBhcmVudDo6Y3VycmVudCgpLCAkc2l6ZSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgdG90YWwgZXhwZWN0ZWQgdGlja3MuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgdG90YWwgdGlja3MuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0b3RhbCgpIHsKCQlyZXR1cm4gbnVtYmVyX2Zvcm1hdCgkdGhpcy0+X3RvdGFsKTsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZXMgdGhlIGVzdGltYXRlZCB0b3RhbCB0aW1lIGZvciB0aGUgdGljayBjb3VudCB0byByZWFjaCB0aGUKCSAqIHRvdGFsIHRpY2tzIGdpdmVuLgoJICoKCSAqIEByZXR1cm4gaW50ICBUaGUgZXN0aW1hdGVkIHRvdGFsIG51bWJlciBvZiBzZWNvbmRzIGZvciBhbGwgdGlja3MgdG8gYmUKCSAqICAgICAgICAgICAgICBjb21wbGV0ZWQuIFRoaXMgaXMgbm90IHRoZSBlc3RpbWF0ZWQgdGltZSBsZWZ0LCBidXQgdG90YWwuCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnNwZWVkKCkKCSAqIEBzZWUgY2xpXE5vdGlmeTo6ZWxhcHNlZCgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBlc3RpbWF0ZWQoKSB7CgkJJHNwZWVkID0gJHRoaXMtPnNwZWVkKCk7CgkJaWYgKCEkc3BlZWQgfHwgISR0aGlzLT5lbGFwc2VkKCkpIHsKCQkJcmV0dXJuIDA7CgkJfQoKCQkkZXN0aW1hdGVkID0gcm91bmQoJHRoaXMtPl90b3RhbCAvICRzcGVlZCk7CgkJcmV0dXJuICRlc3RpbWF0ZWQ7Cgl9CgoJLyoqCgkgKiBGb3JjZXMgdGhlIGN1cnJlbnQgdGljayBjb3VudCB0byB0aGUgdG90YWwgdGlja3MgZ2l2ZW4gYXQgaW5zdGF0aWF0aW9uCgkgKiB0aW1lIGJlZm9yZSBwYXNzaW5nIG9uIHRvIGBjbGlcTm90aWZ5OjpmaW5pc2goKWAuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmaW5pc2goKSB7CgkJJHRoaXMtPl9jdXJyZW50ID0gJHRoaXMtPl90b3RhbDsKCQlwYXJlbnQ6OmZpbmlzaCgpOwoJfQoKCS8qKgoJICogSW5jcmVtZW50cyBhcmUgdGljayBjb3VudGVyIGJ5IHRoZSBnaXZlbiBhbW91bnQuIElmIG5vIGFtb3VudCBpcyBwcm92aWRlZCwKCSAqIHRoZSB0aWNrZXIgaXMgaW5jcmVtZW50ZWQgYnkgMS4KCSAqCgkgKiBAcGFyYW0gaW50ICAkaW5jcmVtZW50ICBUaGUgYW1vdW50IHRvIGluY3JlbWVudCBieS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluY3JlbWVudCgkaW5jcmVtZW50ID0gMSkgewoJCSR0aGlzLT5fY3VycmVudCA9IG1pbigkdGhpcy0+X3RvdGFsLCAkdGhpcy0+X2N1cnJlbnQgKyAkaW5jcmVtZW50KTsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBjb21wbGV0ZWQuCgkgKgoJICogQHJldHVybiBmbG9hdCAgVGhlIHBlcmNlbnQgY29tcGxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcGVyY2VudCgpIHsKCQlpZiAoJHRoaXMtPl90b3RhbCA9PSAwKSB7CgkJCXJldHVybiAxOwoJCX0KCgkJcmV0dXJuICgkdGhpcy0+X2N1cnJlbnQgLyAkdGhpcy0+X3RvdGFsKTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXHByb2dyZXNzOwoKdXNlIGNsaTsKdXNlIGNsaVxOb3RpZnk7CnVzZSBjbGlcUHJvZ3Jlc3M7CnVzZSBjbGlcU2hlbGw7CnVzZSBjbGlcU3RyZWFtczsKCi8qKgogKiBEaXNwbGF5cyBhIHByb2dyZXNzIGJhciBzcGFubmluZyB0aGUgZW50aXJlIHNoZWxsLgogKgogKiBCYXNpYyBmb3JtYXQ6CiAqCiAqICAgXk1TRyAgUEVSJSBbPT09PT09PT09PT09PT09PT09PT09PT0gICAgICAgICAgICBdICAwMDowMCAvIDAwOjAwJAogKi8KY2xhc3MgQmFyIGV4dGVuZHMgUHJvZ3Jlc3MgewoJcHJvdGVjdGVkICRfYmFycyA9ICc9Pic7Cglwcm90ZWN0ZWQgJF9mb3JtYXRNZXNzYWdlID0gJ3s6bXNnfSAgezpwZXJjZW50fSUgWyc7Cglwcm90ZWN0ZWQgJF9mb3JtYXRUaW1pbmcgPSAnXSB7OmVsYXBzZWR9IC8gezplc3RpbWF0ZWR9JzsKCXByb3RlY3RlZCAkX2Zvcm1hdCA9ICd7Om1zZ317OmJhcn17OnRpbWluZ30nOwoKCS8qKgoJICogUHJpbnRzIHRoZSBwcm9ncmVzcyBiYXIgdG8gdGhlIHNjcmVlbiB3aXRoIHBlcmNlbnQgY29tcGxldGUsIGVsYXBzZWQgdGltZQoJICogYW5kIGVzdGltYXRlZCB0b3RhbCB0aW1lLgoJICoKCSAqIEBwYXJhbSBib29sZWFuICAkZmluaXNoICBgdHJ1ZWAgaWYgdGhpcyB3YXMgY2FsbGVkIGZyb20KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY2xpXE5vdGlmeTo6ZmluaXNoKClgLCBgZmFsc2VgIG90aGVyd2lzZS4KCSAqIEBzZWUgY2xpXG91dCgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmZvcm1hdFRpbWUoKQoJICogQHNlZSBjbGlcTm90aWZ5OjplbGFwc2VkKCkKCSAqIEBzZWUgY2xpXFByb2dyZXNzOjplc3RpbWF0ZWQoKTsKCSAqIEBzZWUgY2xpXFByb2dyZXNzOjpwZXJjZW50KCkKCSAqIEBzZWUgY2xpXFNoZWxsOjpjb2x1bW5zKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRpc3BsYXkoJGZpbmlzaCA9IGZhbHNlKSB7CgkJJF9wZXJjZW50ID0gJHRoaXMtPnBlcmNlbnQoKTsKCgkJJHBlcmNlbnQgPSBzdHJfcGFkKGZsb29yKCRfcGVyY2VudCAqIDEwMCksIDMpOwoJCSRtc2cgPSAkdGhpcy0+X21lc3NhZ2U7CgkJJG1zZyA9IFN0cmVhbXM6OnJlbmRlcigkdGhpcy0+X2Zvcm1hdE1lc3NhZ2UsIGNvbXBhY3QoJ21zZycsICdwZXJjZW50JykpOwoKCQkkZXN0aW1hdGVkID0gJHRoaXMtPmZvcm1hdFRpbWUoJHRoaXMtPmVzdGltYXRlZCgpKTsKCQkkZWxhcHNlZCAgID0gc3RyX3BhZCgkdGhpcy0+Zm9ybWF0VGltZSgkdGhpcy0+ZWxhcHNlZCgpKSwgc3RybGVuKCRlc3RpbWF0ZWQpKTsKCQkkdGltaW5nICAgID0gU3RyZWFtczo6cmVuZGVyKCR0aGlzLT5fZm9ybWF0VGltaW5nLCBjb21wYWN0KCdlbGFwc2VkJywgJ2VzdGltYXRlZCcpKTsKCgkJJHNpemUgPSBTaGVsbDo6Y29sdW1ucygpOwoJCSRzaXplIC09IHN0cmxlbigkbXNnIC4gJHRpbWluZyk7CgkJaWYgKCAkc2l6ZSA8IDAgKSB7CgkJCSRzaXplID0gMDsKCQl9CgoJCSRiYXIgPSBzdHJfcmVwZWF0KCR0aGlzLT5fYmFyc1swXSwgZmxvb3IoJF9wZXJjZW50ICogJHNpemUpKSAuICR0aGlzLT5fYmFyc1sxXTsKCQkvLyBzdWJzdHIgaXMgbmVlZGVkIHRvIHRyaW0gb2ZmIHRoZSBiYXIgY2FwIGF0IDEwMCUKCQkkYmFyID0gc3Vic3RyKHN0cl9wYWQoJGJhciwgJHNpemUsICcgJyksIDAsICRzaXplKTsKCgkJU3RyZWFtczo6b3V0KCR0aGlzLT5fZm9ybWF0LCBjb21wYWN0KCdtc2cnLCAnYmFyJywgJ3RpbWluZycpKTsKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIGF1Z21lbnRzIHRoZSBiYXNlIGRlZmluaXRpb24gZnJvbSBjbGlcTm90aWZ5IHRvIG9wdGlvbmFsbHkKCSAqIGFsbG93IHBhc3NpbmcgYSBuZXcgbWVzc2FnZS4KCSAqCgkgKiBAcGFyYW0gaW50ICAgICRpbmNyZW1lbnQgVGhlIGFtb3VudCB0byBpbmNyZW1lbnQgYnkuCgkgKiBAcGFyYW0gc3RyaW5nICRtc2cgICAgICAgVGhlIHRleHQgdG8gZGlzcGxheSBuZXh0IHRvIHRoZSBOb3RpZmllci4gKG9wdGlvbmFsKQoJICogQHNlZSBjbGlcTm90aWZ5Ojp0aWNrKCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRpY2soJGluY3JlbWVudCA9IDEsICRtc2cgPSBudWxsKSB7CgkJaWYgKCRtc2cpIHsKCQkJJHRoaXMtPl9tZXNzYWdlID0gJG1zZzsKCQl9CgkJTm90aWZ5Ojp0aWNrKCRpbmNyZW1lbnQpOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcYXJndW1lbnRzOwoKdXNlIGNsaVxNZW1vaXplOwoKLyoqCiAqIFJlcHJlc2VudHMgYW4gQXJndW1lbnQgb3IgYSB2YWx1ZSBhbmQgcHJvdmlkZXMgc2V2ZXJhbCBoZWxwZXJzIHJlbGF0ZWQgdG8gcGFyc2luZyBhbiBhcmd1bWVudCBsaXN0LgogKi8KY2xhc3MgQXJndW1lbnQgZXh0ZW5kcyBNZW1vaXplIHsKCS8qKgoJICogVGhlIGNhbm9uaWNhbCBuYW1lIG9mIHRoaXMgYXJndW1lbnQsIHVzZWQgZm9yIGFsaWFzaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcKCSAqLwoJcHVibGljICRrZXk7CgoJcHJpdmF0ZSAkX2FyZ3VtZW50OwoJcHJpdmF0ZSAkX3JhdzsKCgkvKioKCSAqIEBwYXJhbSBzdHJpbmcgICRhcmd1bWVudCAgVGhlIHJhdyBhcmd1bWVudCwgbGVhZGluZyBkYXNoZXMgaW5jbHVkZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYXJndW1lbnQpIHsKCQkkdGhpcy0+X3JhdyA9ICRhcmd1bWVudDsKCQkkdGhpcy0+a2V5ID0mICR0aGlzLT5fYXJndW1lbnQ7CgoJCWlmICgkdGhpcy0+aXNMb25nKSB7CgkJCSR0aGlzLT5fYXJndW1lbnQgPSBzdWJzdHIoJHRoaXMtPl9yYXcsIDIpOwoJCX0gZWxzZSBpZiAoJHRoaXMtPmlzU2hvcnQpIHsKCQkJJHRoaXMtPl9hcmd1bWVudCA9IHN1YnN0cigkdGhpcy0+X3JhdywgMSk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPl9hcmd1bWVudCA9ICR0aGlzLT5fcmF3OwoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJhdyBpbnB1dCBhcyBhIHN0cmluZy4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpIHsKCQlyZXR1cm4gKHN0cmluZykkdGhpcy0+X3JhdzsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGZvcm1hdHRlZCBhcmd1bWVudCBzdHJpbmcuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHZhbHVlKCkgewoJCXJldHVybiAkdGhpcy0+X2FyZ3VtZW50OwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcmF3IGlucHV0LgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJhdygpIHsKCQlyZXR1cm4gJHRoaXMtPl9yYXc7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBsb25nIGFyZ3VtZW50cy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzTG9uZygpIHsKCQlyZXR1cm4gKDAgPT0gc3RybmNtcCgkdGhpcy0+X3JhdywgJy0tJywgMikpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdHJpbmcgbWF0Y2hlcyB0aGUgcGF0dGVybiBmb3Igc2hvcnQgYXJndW1lbnRzLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNTaG9ydCgpIHsKCQlyZXR1cm4gISR0aGlzLT5pc0xvbmcgJiYgKDAgPT0gc3RybmNtcCgkdGhpcy0+X3JhdywgJy0nLCAxKSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBhcmd1bWVudHMuCgkgKgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpc0FyZ3VtZW50KCkgewoJCXJldHVybiAkdGhpcy0+aXNTaG9ydCgpIHx8ICR0aGlzLT5pc0xvbmcoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3RyaW5nIG1hdGNoZXMgdGhlIHBhdHRlcm4gZm9yIHZhbHVlcy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzVmFsdWUoKSB7CgkJcmV0dXJuICEkdGhpcy0+aXNBcmd1bWVudDsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXJndW1lbnQgaXMgc2hvcnQgYnV0IGNvbnRhaW5zIHNldmVyYWwgY2hhcmFjdGVycy4gRWFjaAoJICogY2hhcmFjdGVyIGlzIGNvbnNpZGVyZWQgYSBzZXBhcmF0ZSBhcmd1bWVudC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGNhbkV4cGxvZGUoKSB7CgkJcmV0dXJuICR0aGlzLT5pc1Nob3J0ICYmIHN0cmxlbigkdGhpcy0+X2FyZ3VtZW50KSA+IDE7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFsbCBidXQgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgYXJndW1lbnQsIHJlbW92aW5nIHRoZW0gZnJvbSB0aGUKCSAqIG9iamVjdHMgcmVwcmVzZW50YXRpb24gYXQgdGhlIHNhbWUgdGltZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBleHBsb2RlZCgpIHsKCQkkZXhwbG9kZWQgPSBhcnJheSgpOwoKCQlmb3IgKCRpID0gc3RybGVuKCR0aGlzLT5fYXJndW1lbnQpOyAkaSA+IDA7ICRpLS0pIHsKCQkJYXJyYXlfcHVzaCgkZXhwbG9kZWQsICR0aGlzLT5fYXJndW1lbnRbJGkgLSAxXSk7CgkJfQoKCQkkdGhpcy0+X2FyZ3VtZW50ID0gYXJyYXlfcG9wKCRleHBsb2RlZCk7CgkJJHRoaXMtPl9yYXcgICAgICA9ICctJyAuICR0aGlzLT5fYXJndW1lbnQ7CgkJcmV0dXJuICRleHBsb2RlZDsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXGFyZ3VtZW50czsKCnVzZSBjbGlcQXJndW1lbnRzOwoKLyoqCiAqIEFyZ3VtZW50cyBoZWxwIHNjcmVlbiByZW5kZXJlcgogKi8KY2xhc3MgSGVscFNjcmVlbiB7Cglwcm90ZWN0ZWQgJF9mbGFncyA9IGFycmF5KCk7Cglwcm90ZWN0ZWQgJF9tYXhGbGFnID0gMDsKCXByb3RlY3RlZCAkX29wdGlvbnMgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfbWF4T3B0aW9uID0gMDsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQXJndW1lbnRzICRhcmd1bWVudHMpIHsKCQkkdGhpcy0+c2V0QXJndW1lbnRzKCRhcmd1bWVudHMpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBfX3RvU3RyaW5nKCkgewoJCXJldHVybiAkdGhpcy0+cmVuZGVyKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50cyhBcmd1bWVudHMgJGFyZ3VtZW50cykgewoJCSR0aGlzLT5jb25zdW1lQXJndW1lbnRGbGFncygkYXJndW1lbnRzKTsKCQkkdGhpcy0+Y29uc3VtZUFyZ3VtZW50T3B0aW9ucygkYXJndW1lbnRzKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY29uc3VtZUFyZ3VtZW50RmxhZ3MoQXJndW1lbnRzICRhcmd1bWVudHMpIHsKCQkkZGF0YSA9ICR0aGlzLT5fY29uc3VtZSgkYXJndW1lbnRzLT5nZXRGbGFncygpKTsKCgkJJHRoaXMtPl9mbGFncyA9ICRkYXRhWzBdOwoJCSR0aGlzLT5fZmxhZ01heCA9ICRkYXRhWzFdOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjb25zdW1lQXJndW1lbnRPcHRpb25zKEFyZ3VtZW50cyAkYXJndW1lbnRzKSB7CgkJJGRhdGEgPSAkdGhpcy0+X2NvbnN1bWUoJGFyZ3VtZW50cy0+Z2V0T3B0aW9ucygpKTsKCgkJJHRoaXMtPl9vcHRpb25zID0gJGRhdGFbMF07CgkJJHRoaXMtPl9vcHRpb25NYXggPSAkZGF0YVsxXTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKCkgewoJCSRoZWxwID0gYXJyYXkoKTsKCgkJYXJyYXlfcHVzaCgkaGVscCwgJHRoaXMtPl9yZW5kZXJGbGFncygpKTsKCQlhcnJheV9wdXNoKCRoZWxwLCAkdGhpcy0+X3JlbmRlck9wdGlvbnMoKSk7CgoJCXJldHVybiBqb2luKCJcblxuIiwgJGhlbHApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX3JlbmRlckZsYWdzKCkgewoJCWlmIChlbXB0eSgkdGhpcy0+X2ZsYWdzKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXJldHVybiAiRmxhZ3NcbiIgLiAkdGhpcy0+X3JlbmRlclNjcmVlbigkdGhpcy0+X2ZsYWdzLCAkdGhpcy0+X2ZsYWdNYXgpOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX3JlbmRlck9wdGlvbnMoKSB7CgkJaWYgKGVtcHR5KCR0aGlzLT5fb3B0aW9ucykpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlyZXR1cm4gIk9wdGlvbnNcbiIgLiAkdGhpcy0+X3JlbmRlclNjcmVlbigkdGhpcy0+X29wdGlvbnMsICR0aGlzLT5fb3B0aW9uTWF4KTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9yZW5kZXJTY3JlZW4oJG9wdGlvbnMsICRtYXgpIHsKCQkkaGVscCA9IGFycmF5KCk7CgkJZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG9wdGlvbiA9PiAkc2V0dGluZ3MpIHsKCQkJJGZvcm1hdHRlZCA9ICcgICcgLiBzdHJfcGFkKCRvcHRpb24sICRtYXgpOwoKCQkJJGRsZW4gPSA4MCAtIDQgLSAkbWF4OwoKCQkJJGRlc2NyaXB0aW9uID0gc3RyX3NwbGl0KCRzZXR0aW5nc1snZGVzY3JpcHRpb24nXSwgJGRsZW4pOwoJCQkkZm9ybWF0dGVkLj0gJyAgJyAuIGFycmF5X3NoaWZ0KCRkZXNjcmlwdGlvbik7CgoJCQlpZiAoJHNldHRpbmdzWydkZWZhdWx0J10pIHsKCQkJCSRmb3JtYXR0ZWQgLj0gJyBbZGVmYXVsdDogJyAuICRzZXR0aW5nc1snZGVmYXVsdCddIC4gJ10nOwoJCQl9CgoJCQkkcGFkID0gc3RyX3JlcGVhdCgnICcsICRtYXggKyAzKTsKCQkJd2hpbGUgKCRkZXNjID0gYXJyYXlfc2hpZnQoJGRlc2NyaXB0aW9uKSkgewoJCQkJJGZvcm1hdHRlZCAuPSAiXG4ke3BhZH0ke2Rlc2N9IjsKCQkJfQoKCQkJYXJyYXlfcHVzaCgkaGVscCwgJGZvcm1hdHRlZCk7CgkJfQoKCQlyZXR1cm4gam9pbigiXG4iLCAkaGVscCk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBfY29uc3VtZSgkb3B0aW9ucykgewoJCSRtYXggPSAwOwoJCSRvdXQgPSBhcnJheSgpOwoKCQlmb3JlYWNoICgkb3B0aW9ucyBhcyAkb3B0aW9uID0+ICRzZXR0aW5ncykgewoJCQkkbmFtZXMgPSBhcnJheSgnLS0nIC4gJG9wdGlvbik7CgoJCQlmb3JlYWNoICgkc2V0dGluZ3NbJ2FsaWFzZXMnXSBhcyAkYWxpYXMpIHsKCQkJCWFycmF5X3B1c2goJG5hbWVzLCAnLScgLiAkYWxpYXMpOwoJCQl9CgoJCQkkbmFtZXMgPSBqb2luKCcsICcsICRuYW1lcyk7CgkJCSRtYXggPSBtYXgoc3RybGVuKCRuYW1lcyksICRtYXgpOwoJCQkkb3V0WyRuYW1lc10gPSAkc2V0dGluZ3M7CgkJfQoKCQlyZXR1cm4gYXJyYXkoJG91dCwgJG1heCk7Cgl9Cn0KCjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcYXJndW1lbnRzOwoKdXNlIGNsaVxNZW1vaXplOwoKY2xhc3MgTGV4ZXIgZXh0ZW5kcyBNZW1vaXplIGltcGxlbWVudHMgXEl0ZXJhdG9yIHsKCXByaXZhdGUgJF9pdGVtcyA9IGFycmF5KCk7Cglwcml2YXRlICRfaW5kZXggPSAwOwoJcHJpdmF0ZSAkX2xlbmd0aCA9IDA7Cglwcml2YXRlICRfZmlyc3QgPSB0cnVlOwoKCS8qKgoJICogQHBhcmFtIGFycmF5ICAkaXRlbXMgIEEgbGlzdCBvZiBzdHJpbmdzIHRvIHByb2Nlc3MgYXMgdG9rZW5zLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGl0ZW1zKSB7CgkJJHRoaXMtPl9pdGVtcyA9ICRpdGVtczsKCQkkdGhpcy0+X2xlbmd0aCA9IGNvdW50KCRpdGVtcyk7Cgl9CgoJLyoqCgkgKiBUaGUgY3VycmVudCB0b2tlbi4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwdWJsaWMgZnVuY3Rpb24gY3VycmVudCgpIHsKCQlyZXR1cm4gJHRoaXMtPl9pdGVtOwoJfQoKCS8qKgoJICogUGVlayBhaGVhZCB0byB0aGUgbmV4dCB0b2tlbiB3aXRob3V0IG1vdmluZyB0aGUgY3Vyc29yLgoJICoKCSAqIEByZXR1cm4gQXJndW1lbnQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBlZWsoKSB7CgkJcmV0dXJuIG5ldyBBcmd1bWVudCgkdGhpcy0+X2l0ZW1zWzBdKTsKCX0KCgkvKioKCSAqIE1vdmUgdGhlIGN1cnNvciBmb3J3YXJkIDEgZWxlbWVudCBpZiBpdCBpcyB2YWxpZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG5leHQoKSB7CgkJaWYgKCR0aGlzLT52YWxpZCgpKSB7CgkJCSR0aGlzLT5fc2hpZnQoKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIGN1cnNvci4KCSAqCgkgKiBAcmV0dXJuIGludAoJICovCglwdWJsaWMgZnVuY3Rpb24ga2V5KCkgewoJCXJldHVybiAkdGhpcy0+X2luZGV4OwoJfQoKCS8qKgoJICogTW92ZSBmb3J3YXJkIDEgZWxlbWVudCBhbmQsIGlmIHRoZSBtZXRob2QgaGFzbid0IGJlZW4gY2FsbGVkIGJlZm9yZSwgcmVzZXQKCSAqIHRoZSBjdXJzb3IncyBwb3NpdGlvbiB0byAwLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmV3aW5kKCkgewoJCSR0aGlzLT5fc2hpZnQoKTsKCQlpZiAoJHRoaXMtPl9maXJzdCkgewoJCQkkdGhpcy0+X2luZGV4ID0gMDsKCQkJJHRoaXMtPl9maXJzdCA9IGZhbHNlOwoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3Vyc29yIGhhcyBub3QgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBsaXN0LgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gdmFsaWQoKSB7CgkJcmV0dXJuICgkdGhpcy0+X2luZGV4IDwgJHRoaXMtPl9sZW5ndGgpOwoJfQoKCS8qKgoJICogUHVzaCBhbiBlbGVtZW50IHRvIHRoZSBmcm9udCBvZiB0aGUgc3RhY2suCgkgKgoJICogQHBhcmFtIG1peGVkICAkaXRlbSAgVGhlIHZhbHVlIHRvIHNldAoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5zaGlmdCgkaXRlbSkgewoJCWFycmF5X3Vuc2hpZnQoJHRoaXMtPl9pdGVtcywgJGl0ZW0pOwoJCSR0aGlzLT5fbGVuZ3RoICs9IDE7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0LgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gZW5kKCkgewoJCXJldHVybiAoJHRoaXMtPl9pbmRleCArIDEpID09ICR0aGlzLT5fbGVuZ3RoOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gX3NoaWZ0KCkgewoJCSR0aGlzLT5faXRlbSA9IG5ldyBBcmd1bWVudChhcnJheV9zaGlmdCgkdGhpcy0+X2l0ZW1zKSk7CgkJJHRoaXMtPl9pbmRleCArPSAxOwoJCSR0aGlzLT5fZXhwbG9kZSgpOwoJCSR0aGlzLT5fdW5tZW1vKCdwZWVrJyk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBfZXhwbG9kZSgpIHsKCQlpZiAoISR0aGlzLT5faXRlbS0+Y2FuRXhwbG9kZSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlmb3JlYWNoICgkdGhpcy0+X2l0ZW0tPmV4cGxvZGVkIGFzICRwaWVjZSkgewoJCQkkdGhpcy0+dW5zaGlmdCgnLScgLiAkcGllY2UpOwoJCX0KCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXGFyZ3VtZW50czsKCi8qKgogKiBUaHJvd24gd2hlbiB1bmRlZmluZWQgYXJndW1lbnRzIGFyZSBkZXRlY3RlZCBpbiBzdHJpY3QgbW9kZS4KICovCmNsYXNzIEludmFsaWRBcmd1bWVudHMgZXh0ZW5kcyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIHsKCXByb3RlY3RlZCAkYXJndW1lbnRzOwoKCS8qKgoJICogQHBhcmFtIGFycmF5ICAkYXJndW1lbnRzICBBIGxpc3Qgb2YgYXJndW1lbnRzIHRoYXQgZG8gbm90IGZpdCB0aGUgcHJvZmlsZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRhcmd1bWVudHMpIHsKCQkkdGhpcy0+YXJndW1lbnRzID0gJGFyZ3VtZW50czsKCQkkdGhpcy0+bWVzc2FnZSA9ICR0aGlzLT5fZ2VuZXJhdGVNZXNzYWdlKCk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGFyZ3VtZW50cyB0aGF0IGNhdXNlZCB0aGUgZXhjZXB0aW9uLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50cygpIHsKCQlyZXR1cm4gJHRoaXMtPmFyZ3VtZW50czsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9nZW5lcmF0ZU1lc3NhZ2UoKSB7CgkJcmV0dXJuICd1bmtub3duIGFyZ3VtZW50JyAuCgkJCShjb3VudCgkdGhpcy0+YXJndW1lbnRzKSA+IDEgPyAncycgOiAnJykgLgoJCQknOiAnIC4gam9pbignLCAnLCAkdGhpcy0+YXJndW1lbnRzKTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIFJ5YW4gU3VsbGl2YW4gPHJzdWxsaXZhbkBjb25uZWN0c3R1ZGlvcy5jb20+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKLyoqCiAqIFRoZSBgVHJlZWAgY2xhc3MgaXMgdXNlZCB0byBkaXNwbGF5IGRhdGEgaW4gYSB0cmVlLWxpa2UgZm9ybWF0LgogKi8KY2xhc3MgVHJlZSB7CgogICAgcHJvdGVjdGVkICRfcmVuZGVyZXI7CiAgICBwcm90ZWN0ZWQgJF9kYXRhID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHJlbmRlcmVyIHVzZWQgYnkgdGhpcyB0cmVlLgogICAgICoKICAgICAqIEBwYXJhbSB0cmVlXFJlbmRlcmVyICAkcmVuZGVyZXIgIFRoZSByZW5kZXJlciB0byB1c2UgZm9yIG91dHB1dC4KICAgICAqIEBzZWUgICB0cmVlXFJlbmRlcmVyCiAgICAgKiBAc2VlICAgdHJlZVxBc2NpaQogICAgICogQHNlZSAgIHRyZWVcTWFya2Rvd24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJlbmRlcmVyKHRyZWVcUmVuZGVyZXIgJHJlbmRlcmVyKSB7CiAgICAgICAgJHRoaXMtPl9yZW5kZXJlciA9ICRyZW5kZXJlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgZGF0YS4KICAgICAqIEZvcm1hdDoKICAgICAqICAgICBbCiAgICAgKiAgICAgICAgICdMYWJlbCcgPT4gWwogICAgICogICAgICAgICAgICAgJ1RoaW5nJyA9PiBbJ1RoaW5nJ10sCiAgICAgKiAgICAgICAgIF0sCiAgICAgKiAgICAgICAgICdUaGluZycsCiAgICAgKiAgICAgXQogICAgICogQHBhcmFtIGFycmF5ICRkYXRhCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREYXRhKGFycmF5ICRkYXRhKQogICAgewogICAgICAgICR0aGlzLT5fZGF0YSA9ICRkYXRhOwogICAgfQoKICAgIC8qKgogICAgICogUmVuZGVyIHRoZSB0cmVlIGFuZCByZXR1cm4gaXQgYXMgYSBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVuZGVyKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPl9yZW5kZXJlci0+cmVuZGVyKCR0aGlzLT5fZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaXNwbGF5IHRoZSByZW5kZXJlZCB0cmVlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCkKICAgIHsKICAgICAgICBlY2hvICR0aGlzLT5yZW5kZXIoKTsKICAgIH0KCn0KPD9waHAKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaTsKCi8qKgogKiBDaGFuZ2UgdGhlIGNvbG9yIG9mIHRleHQuCiAqCiAqIFJlZmVyZW5jZTogaHR0cDovL2dyYXBoY29tcC5jb20vaW5mby9zcGVjcy9hbnNpX2NvbC5odG1sI2NvbG9ycwogKi8KY2xhc3MgQ29sb3JzIHsKCXN0YXRpYyBwcm90ZWN0ZWQgJF9jb2xvcnMgPSBhcnJheSgKCQknY29sb3InID0+IGFycmF5KAoJCQknYmxhY2snICAgPT4gMzAsCgkJCSdyZWQnCSA9PiAzMSwKCQkJJ2dyZWVuJyAgID0+IDMyLAoJCQkneWVsbG93JyAgPT4gMzMsCgkJCSdibHVlJwk9PiAzNCwKCQkJJ21hZ2VudGEnID0+IDM1LAoJCQknY3lhbicJPT4gMzYsCgkJCSd3aGl0ZScgICA9PiAzNwoJCSksCgkJJ3N0eWxlJyA9PiBhcnJheSgKCQkJJ2JyaWdodCcJID0+IDEsCgkJCSdkaW0nCQk9PiAyLAoJCQkndW5kZXJsaW5lJyA9PiA0LAoJCQknYmxpbmsnCSAgPT4gNSwKCQkJJ3JldmVyc2UnCT0+IDcsCgkJCSdoaWRkZW4nCSA9PiA4CgkJKSwKCQknYmFja2dyb3VuZCcgPT4gYXJyYXkoCgkJCSdibGFjaycgICA9PiA0MCwKCQkJJ3JlZCcJID0+IDQxLAoJCQknZ3JlZW4nICAgPT4gNDIsCgkJCSd5ZWxsb3cnICA9PiA0MywKCQkJJ2JsdWUnCT0+IDQ0LAoJCQknbWFnZW50YScgPT4gNDUsCgkJCSdjeWFuJwk9PiA0NiwKCQkJJ3doaXRlJyAgID0+IDQ3CgkJKQoJKTsKCXN0YXRpYyBwcm90ZWN0ZWQgJF9lbmFibGVkID0gbnVsbDsKCglzdGF0aWMgcHJvdGVjdGVkICRfc3RyaW5nX2NhY2hlID0gYXJyYXkoKTsKCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGVuYWJsZSgkZm9yY2UgPSB0cnVlKSB7CgkJc2VsZjo6JF9lbmFibGVkID0gJGZvcmNlID09PSB0cnVlID8gdHJ1ZSA6IG51bGw7Cgl9CgoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBkaXNhYmxlKCRmb3JjZSA9IHRydWUpIHsKCQlzZWxmOjokX2VuYWJsZWQgPSAkZm9yY2UgPT09IHRydWUgPyBmYWxzZSA6IG51bGw7Cgl9CgoJLyoqCgkgKiBDaGVjayBpZiB3ZSBzaG91bGQgY29sb3JpemUgb3V0cHV0IGJhc2VkIG9uIGxvY2FsIGZsYWdzIGFuZCBzaGVsbCB0eXBlLgoJICoKCSAqIE9ubHkgY2hlY2sgdGhlIHNoZWxsIHR5cGUgaWYgYENvbG9yczo6JF9lbmFibGVkYCBpcyBudWxsIGFuZCBgJGNvbG9yZWRgIGlzIG51bGwuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gc2hvdWxkQ29sb3JpemUoJGNvbG9yZWQgPSBudWxsKSB7CgkJcmV0dXJuIHNlbGY6OiRfZW5hYmxlZCA9PT0gdHJ1ZSB8fAoJCQkoc2VsZjo6JF9lbmFibGVkICE9PSBmYWxzZSAmJgoJCQkJKCRjb2xvcmVkID09PSB0cnVlIHx8CgkJCQkJKCRjb2xvcmVkICE9PSBmYWxzZSAmJiBTdHJlYW1zOjppc1R0eSgpKSkpOwoJfQoKCS8qKgoJICogU2V0IHRoZSBjb2xvci4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAkY29sb3IgIFRoZSBuYW1lIG9mIHRoZSBjb2xvciBvciBzdHlsZSB0byBzZXQuCiAgICAgKiBAcmV0dXJuIHN0cmluZwoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGNvbG9yKCRjb2xvcikgewoJCWlmICghaXNfYXJyYXkoJGNvbG9yKSkgewoJCQkkY29sb3IgPSBjb21wYWN0KCdjb2xvcicpOwoJCX0KCgkJJGNvbG9yICs9IGFycmF5KCdjb2xvcicgPT4gbnVsbCwgJ3N0eWxlJyA9PiBudWxsLCAnYmFja2dyb3VuZCcgPT4gbnVsbCk7CgoJCWlmICgkY29sb3JbJ2NvbG9yJ10gPT0gJ3Jlc2V0JykgewoJCQlyZXR1cm4gIlwwMzNbMG0iOwoJCX0KCgkJJGNvbG9ycyA9IGFycmF5KCk7CgkJZm9yZWFjaCAoYXJyYXkoJ2NvbG9yJywgJ3N0eWxlJywgJ2JhY2tncm91bmQnKSBhcyAkdHlwZSkgewoJCQkkY29kZSA9ICRjb2xvclskdHlwZV07CgkJCWlmIChpc3NldChzZWxmOjokX2NvbG9yc1skdHlwZV1bJGNvZGVdKSkgewoJCQkJJGNvbG9yc1tdID0gc2VsZjo6JF9jb2xvcnNbJHR5cGVdWyRjb2RlXTsKCQkJfQoJCX0KCgkJaWYgKGVtcHR5KCRjb2xvcnMpKSB7CgkJCSRjb2xvcnNbXSA9IDA7CgkJfQoKCQlyZXR1cm4gIlwwMzNbIiAuIGpvaW4oJzsnLCAkY29sb3JzKSAuICJtIjsKCX0KCgkvKioKCSAqIENvbG9yaXplIGEgc3RyaW5nIHVzaW5nIGhlbHBmdWwgc3RyaW5nIGZvcm1hdHRlcnMuIElmIHRoZSBgU3RyZWFtczo6JG91dGAgcG9pbnRzIHRvIGEgVFRZIGNvbG9yaW5nIHdpbGwgYmUgZW5hYmxlZCwKCSAqIG90aGVyd2lzZSBkaXNhYmxlZC4gWW91IGNhbiBjb250cm9sIHRoaXMgY2hlY2sgd2l0aCB0aGUgYCRjb2xvcmVkYCBwYXJhbWV0ZXIuCgkgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRzdHJpbmcKCSAqIEBwYXJhbSBib29sZWFuICAkY29sb3JlZCAgRm9yY2UgZW5hYmxlIG9yIGRpc2FibGUgdGhlIGNvbG9yaXplZCBvdXRwdXQuIElmIGxlZnQgYXMgYG51bGxgIHRoZSBUVFkgd2lsbCBjb250cm9sIGNvbG9yaW5nLgogICAgICogQHJldHVybiBzdHJpbmcKCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBjb2xvcml6ZSgkc3RyaW5nLCAkY29sb3JlZCA9IG51bGwpIHsKCQkkcGFzc2VkID0gJHN0cmluZzsKCgkJaWYgKCFzZWxmOjpzaG91bGRDb2xvcml6ZSgkY29sb3JlZCkpIHsKCQkJJHJldHVybiA9IHNlbGY6OmRlY29sb3JpemUoICRwYXNzZWQsIDIgLyprZWVwX2VuY29kaW5ncyovICk7CgkJCXNlbGY6OmNhY2hlU3RyaW5nKCRwYXNzZWQsICRyZXR1cm4pOwoJCQlyZXR1cm4gJHJldHVybjsKCQl9CgoJCSRtZDUgPSBtZDUoJHBhc3NlZCk7CgkJaWYgKGlzc2V0KHNlbGY6OiRfc3RyaW5nX2NhY2hlWyRtZDVdWydjb2xvcml6ZWQnXSkpIHsKCQkJcmV0dXJuIHNlbGY6OiRfc3RyaW5nX2NhY2hlWyRtZDVdWydjb2xvcml6ZWQnXTsKCQl9CgoJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnJSUnLCAnJcK+JywgJHN0cmluZyk7CgoJCWZvcmVhY2ggKHNlbGY6OmdldENvbG9ycygpIGFzICRrZXkgPT4gJHZhbHVlKSB7CgkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgka2V5LCBzZWxmOjpjb2xvcigkdmFsdWUpLCAkc3RyaW5nKTsKCQl9CgoJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnJcK+JywgJyUnLCAkc3RyaW5nKTsKCQlzZWxmOjpjYWNoZVN0cmluZygkcGFzc2VkLCAkc3RyaW5nKTsKCgkJcmV0dXJuICRzdHJpbmc7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgY29sb3IgaW5mb3JtYXRpb24gZnJvbSBhIHN0cmluZy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgQSBzdHJpbmcgd2l0aCBjb2xvciBpbmZvcm1hdGlvbi4KCSAqIEBwYXJhbSBpbnQgICAgJGtlZXAgICBPcHRpb25hbC4gSWYgdGhlIDEgYml0IGlzIHNldCwgY29sb3IgdG9rZW5zIChlZyAiJW4iKSB3b24ndCBiZSBzdHJpcHBlZC4gSWYgdGhlIDIgYml0IGlzIHNldCwgY29sb3IgZW5jb2RpbmdzIChBTlNJIGVzY2FwZXMpIHdvbid0IGJlIHN0cmlwcGVkLiBEZWZhdWx0IDAuCgkgKiBAcmV0dXJuIHN0cmluZyBBIHN0cmluZyB3aXRoIGNvbG9yIGluZm9ybWF0aW9uIHJlbW92ZWQuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gZGVjb2xvcml6ZSggJHN0cmluZywgJGtlZXAgPSAwICkgewoJCWlmICggISAoICRrZWVwICYgMSApICkgewoJCQkvLyBHZXQgcmlkIG9mIGNvbG9yIHRva2VucyBpZiB0aGV5IGV4aXN0CgkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnJSUnLCAnJcK+JywgJHN0cmluZyk7CgkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZShhcnJheV9rZXlzKHNlbGY6OmdldENvbG9ycygpKSwgJycsICRzdHJpbmcpOwoJCQkkc3RyaW5nID0gc3RyX3JlcGxhY2UoJyXCvicsICclJywgJHN0cmluZyk7CgkJfQoKCQlpZiAoICEgKCAka2VlcCAmIDIgKSApIHsKCQkJLy8gUmVtb3ZlIGNvbG9yIGVuY29kaW5nIGlmIGl0IGV4aXN0cwoJCQlmb3JlYWNoIChzZWxmOjpnZXRDb2xvcnMoKSBhcyAka2V5ID0+ICR2YWx1ZSkgewoJCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKHNlbGY6OmNvbG9yKCR2YWx1ZSksICcnLCAkc3RyaW5nKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRzdHJpbmc7Cgl9CgoJLyoqCgkgKiBDYWNoZSB0aGUgb3JpZ2luYWwsIGNvbG9yaXplZCwgYW5kIGRlY29sb3JpemVkIHZlcnNpb25zIG9mIGEgc3RyaW5nLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhc3NlZCBUaGUgb3JpZ2luYWwgc3RyaW5nIGJlZm9yZSBjb2xvcml6YXRpb24uCgkgKiBAcGFyYW0gc3RyaW5nICRjb2xvcml6ZWQgVGhlIHN0cmluZyBhZnRlciBydW5uaW5nIHRocm91Z2ggc2VsZjo6Y29sb3JpemUuCgkgKiBAcGFyYW0gc3RyaW5nICRkZXByZWNhdGVkIE9wdGlvbmFsLiBOb3QgdXNlZC4gRGVmYXVsdCBudWxsLgoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGNhY2hlU3RyaW5nKCAkcGFzc2VkLCAkY29sb3JpemVkLCAkZGVwcmVjYXRlZCA9IG51bGwgKSB7CgkJc2VsZjo6JF9zdHJpbmdfY2FjaGVbbWQ1KCRwYXNzZWQpXSA9IGFycmF5KAoJCQkncGFzc2VkJyAgICAgID0+ICRwYXNzZWQsCgkJCSdjb2xvcml6ZWQnICAgPT4gJGNvbG9yaXplZCwKCQkJJ2RlY29sb3JpemVkJyA9PiBzZWxmOjpkZWNvbG9yaXplKCRwYXNzZWQpLCAvLyBOb3QgdmVyeSB1c2VmdWwgYnV0IGtlZXAgZm9yIEJDLgoJCSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIHdpdGhvdXQgY29sb3IgY29kZXMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJHN0cmluZyAgdGhlIHN0cmluZyB0byBtZWFzdXJlCiAgICAgKiBAcmV0dXJuIGludAoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGxlbmd0aCgkc3RyaW5nKSB7CgkJcmV0dXJuIHNhZmVfc3RybGVuKCBzZWxmOjpkZWNvbG9yaXplKCAkc3RyaW5nICkgKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgd2lkdGggKGxlbmd0aCBpbiBjaGFyYWN0ZXJzKSBvZiB0aGUgc3RyaW5nIHdpdGhvdXQgY29sb3IgY29kZXMgaWYgZW5hYmxlZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgJHN0cmluZyAgICAgICAgVGhlIHN0cmluZyB0byBtZWFzdXJlLgoJICogQHBhcmFtIGJvb2wgICAgICAgICRwcmVfY29sb3JpemVkIE9wdGlvbmFsLiBTZXQgaWYgdGhlIHN0cmluZyBpcyBwcmUtY29sb3JpemVkLiBEZWZhdWx0IGZhbHNlLgoJICogQHBhcmFtIHN0cmluZ3xib29sICRlbmNvZGluZyAgICAgIE9wdGlvbmFsLiBUaGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmluZy4gRGVmYXVsdCBmYWxzZS4KICAgICAqIEByZXR1cm4gaW50CgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gd2lkdGgoICRzdHJpbmcsICRwcmVfY29sb3JpemVkID0gZmFsc2UsICRlbmNvZGluZyA9IGZhbHNlICkgewoJCXJldHVybiBzdHJ3aWR0aCggJHByZV9jb2xvcml6ZWQgfHwgc2VsZjo6c2hvdWxkQ29sb3JpemUoKSA/IHNlbGY6OmRlY29sb3JpemUoICRzdHJpbmcsICRwcmVfY29sb3JpemVkID8gMSAvKmtlZXBfdG9rZW5zKi8gOiAwICkgOiAkc3RyaW5nLCAkZW5jb2RpbmcgKTsKCX0KCgkvKioKCSAqIFBhZCB0aGUgc3RyaW5nIHRvIGEgY2VydGFpbiBkaXNwbGF5IGxlbmd0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgJHN0cmluZyAgICAgICAgVGhlIHN0cmluZyB0byBwYWQuCgkgKiBAcGFyYW0gaW50ICAgICAgICAgJGxlbmd0aCAgICAgICAgVGhlIGRpc3BsYXkgbGVuZ3RoLgoJICogQHBhcmFtIGJvb2wgICAgICAgICRwcmVfY29sb3JpemVkIE9wdGlvbmFsLiBTZXQgaWYgdGhlIHN0cmluZyBpcyBwcmUtY29sb3JpemVkLiBEZWZhdWx0IGZhbHNlLgoJICogQHBhcmFtIHN0cmluZ3xib29sICRlbmNvZGluZyAgICAgIE9wdGlvbmFsLiBUaGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmluZy4gRGVmYXVsdCBmYWxzZS4KCSAqIEBwYXJhbSBpbnQgICAgICAgICAkcGFkX3R5cGUgICAgICBPcHRpb25hbC4gQ2FuIGJlIFNUUl9QQURfUklHSFQsIFNUUl9QQURfTEVGVCwgb3IgU1RSX1BBRF9CT1RILiBJZiBwYWRfdHlwZSBpcyBub3Qgc3BlY2lmaWVkIGl0IGlzIGFzc3VtZWQgdG8gYmUgU1RSX1BBRF9SSUdIVC4KICAgICAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gcGFkKCAkc3RyaW5nLCAkbGVuZ3RoLCAkcHJlX2NvbG9yaXplZCA9IGZhbHNlLCAkZW5jb2RpbmcgPSBmYWxzZSwgJHBhZF90eXBlID0gU1RSX1BBRF9SSUdIVCApIHsKCQkkcmVhbF9sZW5ndGggPSBzZWxmOjp3aWR0aCggJHN0cmluZywgJHByZV9jb2xvcml6ZWQsICRlbmNvZGluZyApOwoJCSRkaWZmID0gc3RybGVuKCAkc3RyaW5nICkgLSAkcmVhbF9sZW5ndGg7CgkJJGxlbmd0aCArPSAkZGlmZjsKCgkJcmV0dXJuIHN0cl9wYWQoICRzdHJpbmcsICRsZW5ndGgsICcgJywgJHBhZF90eXBlICk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIGNvbG9yIG1hcHBpbmcgYXJyYXkuCgkgKgoJICogQHJldHVybiBhcnJheSBBcnJheSBvZiBjb2xvciB0b2tlbnMgbWFwcGVkIHRvIGNvbG9ycyBhbmQgc3R5bGVzLgoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGdldENvbG9ycygpIHsKCQlyZXR1cm4gYXJyYXkoCgkJCScleScgPT4gYXJyYXkoJ2NvbG9yJyA9PiAneWVsbG93JyksCgkJCSclZycgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnZ3JlZW4nKSwKCQkJJyViJyA9PiBhcnJheSgnY29sb3InID0+ICdibHVlJyksCgkJCSclcicgPT4gYXJyYXkoJ2NvbG9yJyA9PiAncmVkJyksCgkJCSclcCcgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnbWFnZW50YScpLAoJCQknJW0nID0+IGFycmF5KCdjb2xvcicgPT4gJ21hZ2VudGEnKSwKCQkJJyVjJyA9PiBhcnJheSgnY29sb3InID0+ICdjeWFuJyksCgkJCScldycgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnd2hpdGUnKSwKCQkJJyVrJyA9PiBhcnJheSgnY29sb3InID0+ICdibGFjaycpLAoJCQknJW4nID0+IGFycmF5KCdjb2xvcicgPT4gJ3Jlc2V0JyksCgkJCSclWScgPT4gYXJyYXkoJ2NvbG9yJyA9PiAneWVsbG93JywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclRycgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnZ3JlZW4nLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVCJyA9PiBhcnJheSgnY29sb3InID0+ICdibHVlJywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclUicgPT4gYXJyYXkoJ2NvbG9yJyA9PiAncmVkJywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclUCcgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnbWFnZW50YScsICdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJU0nID0+IGFycmF5KCdjb2xvcicgPT4gJ21hZ2VudGEnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVDJyA9PiBhcnJheSgnY29sb3InID0+ICdjeWFuJywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclVycgPT4gYXJyYXkoJ2NvbG9yJyA9PiAnd2hpdGUnLCAnc3R5bGUnID0+ICdicmlnaHQnKSwKCQkJJyVLJyA9PiBhcnJheSgnY29sb3InID0+ICdibGFjaycsICdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJU4nID0+IGFycmF5KCdjb2xvcicgPT4gJ3Jlc2V0JywgJ3N0eWxlJyA9PiAnYnJpZ2h0JyksCgkJCSclMycgPT4gYXJyYXkoJ2JhY2tncm91bmQnID0+ICd5ZWxsb3cnKSwKCQkJJyUyJyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ2dyZWVuJyksCgkJCSclNCcgPT4gYXJyYXkoJ2JhY2tncm91bmQnID0+ICdibHVlJyksCgkJCSclMScgPT4gYXJyYXkoJ2JhY2tncm91bmQnID0+ICdyZWQnKSwKCQkJJyU1JyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ21hZ2VudGEnKSwKCQkJJyU2JyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ2N5YW4nKSwKCQkJJyU3JyA9PiBhcnJheSgnYmFja2dyb3VuZCcgPT4gJ3doaXRlJyksCgkJCSclMCcgPT4gYXJyYXkoJ2JhY2tncm91bmQnID0+ICdibGFjaycpLAoJCQknJUYnID0+IGFycmF5KCdzdHlsZScgPT4gJ2JsaW5rJyksCgkJCSclVScgPT4gYXJyYXkoJ3N0eWxlJyA9PiAndW5kZXJsaW5lJyksCgkJCSclOCcgPT4gYXJyYXkoJ3N0eWxlJyA9PiAncmV2ZXJzZScpLAoJCQknJTknID0+IGFycmF5KCdzdHlsZScgPT4gJ2JyaWdodCcpLAoJCQknJV8nID0+IGFycmF5KCdzdHlsZScgPT4gJ2JyaWdodCcpCgkJKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgY2FjaGVkIHN0cmluZyB2YWx1ZXMuCgkgKgoJICogQHJldHVybiBhcnJheSBUaGUgY2FjaGVkIHN0cmluZyB2YWx1ZXMuCgkgKi8KCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gZ2V0U3RyaW5nQ2FjaGUoKSB7CgkJcmV0dXJuIHNlbGY6OiRfc3RyaW5nX2NhY2hlOwoJfQoKCS8qKgoJICogQ2xlYXIgdGhlIHN0cmluZyBjYWNoZS4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBjbGVhclN0cmluZ0NhY2hlKCkgewoJCXNlbGY6OiRfc3RyaW5nX2NhY2hlID0gYXJyYXkoKTsKCX0KfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKdXNlIGNsaVxTdHJlYW1zOwoKLyoqCiAqIFRoZSBgTm90aWZ5YCBjbGFzcyBpcyB0aGUgYmFzaXMgb2YgYWxsIGZlZWRiYWNrIGNsYXNzZXMsIHN1Y2ggYXMgSW5kaWNhdG9ycwogKiBhbmQgUHJvZ3Jlc3MgbWV0ZXJzLiBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gcmVmcmVzaCBvdXRwdXQgYWZ0ZXIgMTAwbXMKICogaGF2ZSBwYXNzZWQuIFRoaXMgaXMgZG9uZSB0byBwcmV2ZW50aW5nIHRoZSBzY3JlZW4gZnJvbSBmbGlja2VyaW5nIGFuZCBrZWVwCiAqIHNsb3dkb3ducyBmcm9tIG91dHB1dCB0byBhIG1pbmltdW0uCiAqCiAqIFRoZSBtb3N0IGJhc2ljIGZvcm0gb2YgTm90aWZpZXIgaGFzIG5vIG1heGltLCBhbmQgc2ltcGx5IGRpc3BsYXlzIGEgc2VyaWVzCiAqIG9mIGNoYXJhY3RlcnMgdG8gaW5kaWNhdGUgcHJvZ3Jlc3MgaXMgYmVpbmcgbWFkZS4KICovCmFic3RyYWN0IGNsYXNzIE5vdGlmeSB7Cglwcm90ZWN0ZWQgJF9jdXJyZW50ID0gMDsKCXByb3RlY3RlZCAkX2ZpcnN0ID0gdHJ1ZTsKCXByb3RlY3RlZCAkX2ludGVydmFsOwoJcHJvdGVjdGVkICRfbWVzc2FnZTsKCXByb3RlY3RlZCAkX3N0YXJ0OwoJcHJvdGVjdGVkICRfdGltZXI7CgoJLyoqCgkgKiBJbnN0YXRpYXRlcyBhIE5vdGlmaWNhdGlvbiBvYmplY3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJG1zZyAgICAgICBUaGUgdGV4dCB0byBkaXNwbGF5IG5leHQgdG8gdGhlIE5vdGlmaWVyLgoJICogQHBhcmFtIGludCAgICAgJGludGVydmFsICBUaGUgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gdXBkYXRlcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtc2csICRpbnRlcnZhbCA9IDEwMCkgewoJCSR0aGlzLT5fbWVzc2FnZSA9ICRtc2c7CgkJJHRoaXMtPl9pbnRlcnZhbCA9IChpbnQpJGludGVydmFsOwoJfQoKCS8qKgoJICogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgdG8gcHJpbnQgb3V0IHRoZSBOb3RpZmllci4gVGhpcyBtZXRob2QgaXMKCSAqIGNhbGxlZCBmcm9tIGBjbGlcTm90aWZ5Ojp0aWNrKClgIGFmdGVyIGBjbGlcTm90aWZ5OjokX2ludGVydmFsYCBoYXMgcGFzc2VkLgoJICoKCSAqIEBhYnN0cmFjdAoJICogQHBhcmFtIGJvb2xlYW4gICRmaW5pc2gKCSAqIEBzZWUgY2xpXE5vdGlmeTo6dGljaygpCgkgKi8KCWFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCRmaW5pc2ggPSBmYWxzZSk7CgoJLyoqCgkgKiBSZXNldCB0aGUgbm90aWZpZXIgc3RhdGUgc28gdGhlIHNhbWUgaW5zdGFuY2UgY2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgbG9vcHMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZXNldCgpIHsKCQkkdGhpcy0+X2N1cnJlbnQgPSAwOwoJCSR0aGlzLT5fZmlyc3QgPSB0cnVlOwoJCSR0aGlzLT5fc3RhcnQgPSBudWxsOwoJCSR0aGlzLT5fdGltZXIgPSBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgZm9ybWF0dGVkIHRpY2sgY291bnQuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgdGljayBjb3VudC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKSB7CgkJcmV0dXJuIG51bWJlcl9mb3JtYXQoJHRoaXMtPl9jdXJyZW50KTsKCX0KCgkvKioKCSAqIENhbGN1bGF0ZXMgdGhlIHRpbWUgZWxhcHNlZCBzaW5jZSB0aGUgTm90aWZpZXIgd2FzIGZpcnN0IHRpY2tlZC4KCSAqCgkgKiBAcmV0dXJuIGludCAgVGhlIGVsYXBzZWQgdGltZSBpbiBzZWNvbmRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZWxhcHNlZCgpIHsKCQlpZiAoISR0aGlzLT5fc3RhcnQpIHsKCQkJcmV0dXJuIDA7CgkJfQoKCQkkZWxhcHNlZCA9IHRpbWUoKSAtICR0aGlzLT5fc3RhcnQ7CgkJcmV0dXJuICRlbGFwc2VkOwoJfQoKCS8qKgoJICogQ2FsY3VsYXRlcyB0aGUgc3BlZWQgKG51bWJlciBvZiB0aWNrcyBwZXIgc2Vjb25kKSBhdCB3aGljaCB0aGUgTm90aWZpZXIKCSAqIGlzIGJlaW5nIHVwZGF0ZWQuCgkgKgoJICogQHJldHVybiBpbnQgIFRoZSBudW1iZXIgb2YgdGlja3MgcGVyZm9ybWVkIGluIDEgc2Vjb25kLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc3BlZWQoKSB7CgkJc3RhdGljICR0aWNrLCAkaXRlcmF0aW9uID0gMCwgJHNwZWVkID0gMDsKCgkJaWYgKCEkdGhpcy0+X3N0YXJ0KSB7CgkJCXJldHVybiAwOwoJCX0gZWxzZSBpZiAoISR0aWNrKSB7CgkJCSR0aWNrID0gJHRoaXMtPl9zdGFydDsKCQl9CgoJCSRub3cgPSBtaWNyb3RpbWUodHJ1ZSk7CgkJJHNwYW4gPSAkbm93IC0gJHRpY2s7CgkJaWYgKCRzcGFuID4gMSkgewoJCQkkaXRlcmF0aW9uKys7CgkJCSR0aWNrID0gJG5vdzsKCQkJJHNwZWVkID0gKCR0aGlzLT5fY3VycmVudCAvICRpdGVyYXRpb24pIC8gJHNwYW47CgkJfQoKCQlyZXR1cm4gJHNwZWVkOwoJfQoKCS8qKgoJICogVGFrZXMgYSB0aW1lIHNwYW4gZ2l2ZW4gaW4gc2Vjb25kcyBhbmQgZm9ybWF0cyBpdCBmb3IgZGlzcGxheS4gVGhlCgkgKiByZXR1cm5lZCBzdHJpbmcgd2lsbCBiZSBpbiBNTTpTUyBmb3JtLgoJICoKCSAqIEBwYXJhbSBpbnQgICR0aW1lIFRoZSB0aW1lIHNwYW4gaW4gc2Vjb25kcyB0byBmb3JtYXQuCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIGZvcm1hdHRlZCB0aW1lIHNwYW4uCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmb3JtYXRUaW1lKCR0aW1lKSB7CgkJcmV0dXJuIGZsb29yKCR0aW1lIC8gNjApIC4gJzonIC4gc3RyX3BhZCgkdGltZSAlIDYwLCAyLCAwLCBTVFJfUEFEX0xFRlQpOwoJfQoKCS8qKgoJICogRmluaXNoIG91ciBOb3RpZmljYXRpb24gZGlzcGxheS4gU2hvdWxkIGJlIGNhbGxlZCBhZnRlciB0aGUgTm90aWZpZXIgaXMKCSAqIG5vIGxvbmdlciBuZWVkZWQuCgkgKgoJICogQHNlZSBjbGlcTm90aWZ5OjpkaXNwbGF5KCkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGZpbmlzaCgpIHsKCQlTdHJlYW1zOjpvdXQoIlxyIik7CgkJJHRoaXMtPmRpc3BsYXkodHJ1ZSk7CgkJU3RyZWFtczo6bGluZSgpOwoJfQoKCS8qKgoJICogSW5jcmVtZW50cyBhcmUgdGljayBjb3VudGVyIGJ5IHRoZSBnaXZlbiBhbW91bnQuIElmIG5vIGFtb3VudCBpcyBwcm92aWRlZCwKCSAqIHRoZSB0aWNrZXIgaXMgaW5jcmVtZW50ZWQgYnkgMS4KCSAqCgkgKiBAcGFyYW0gaW50ICAkaW5jcmVtZW50ICBUaGUgYW1vdW50IHRvIGluY3JlbWVudCBieS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluY3JlbWVudCgkaW5jcmVtZW50ID0gMSkgewoJCSR0aGlzLT5fY3VycmVudCArPSAkaW5jcmVtZW50OwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkaXNwbGF5IHNob3VsZCBiZSB1cGRhdGVkIG9yIG5vdCBhY2NvcmRpbmcgdG8KCSAqIG91ciBpbnRlcnZhbCBzZXR0aW5nLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbiAgYHRydWVgIGlmIHRoZSBkaXNwbGF5IHNob3VsZCBiZSB1cGRhdGVkLCBgZmFsc2VgIG90aGVyd2lzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNob3VsZFVwZGF0ZSgpIHsKCQkkbm93ID0gbWljcm90aW1lKHRydWUpICogMTAwMDsKCgkJaWYgKGVtcHR5KCR0aGlzLT5fdGltZXIpKSB7CgkJCSR0aGlzLT5fc3RhcnQgPSAoaW50KSgoJHRoaXMtPl90aW1lciA9ICRub3cpIC8gMTAwMCk7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJaWYgKCgkbm93IC0gJHRoaXMtPl90aW1lcikgPiAkdGhpcy0+X2ludGVydmFsKSB7CgkJCSR0aGlzLT5fdGltZXIgPSAkbm93OwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogVGhpcyBtZXRob2QgaXMgdGhlIG1lYXQgb2YgYWxsIE5vdGlmaWVycy4gRmlyc3Qgd2UgaW5jcmVtZW50IHRoZSB0aWNrZXIKCSAqIGFuZCB0aGVuIHVwZGF0ZSB0aGUgZGlzcGxheSBpZiBlbm91Z2ggdGltZSBoYXMgcGFzc2VkIHNpbmNlIG91ciBsYXN0IHRpY2suCgkgKgoJICogQHBhcmFtIGludCAgJGluY3JlbWVudCAgVGhlIGFtb3VudCB0byBpbmNyZW1lbnQgYnkuCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmluY3JlbWVudCgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OnNob3VsZFVwZGF0ZSgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmRpc3BsYXkoKQoJICovCglwdWJsaWMgZnVuY3Rpb24gdGljaygkaW5jcmVtZW50ID0gMSkgewoJCSR0aGlzLT5pbmNyZW1lbnQoJGluY3JlbWVudCk7CgoJCWlmICgkdGhpcy0+c2hvdWxkVXBkYXRlKCkpIHsKCQkJU3RyZWFtczo6b3V0KCJcciIpOwoJCQkkdGhpcy0+ZGlzcGxheSgpOwoJCX0KCX0KfQo8P3BocAoKLyoqCiAqIFBIUCBDb21tYW5kIExpbmUgVG9vbHMKICoKICogVGhpcyBzb3VyY2UgZmlsZSBpcyBzdWJqZWN0IHRvIHRoZSBNSVQgbGljZW5zZSB0aGF0IGlzIGJ1bmRsZWQKICogd2l0aCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpbGUgTElDRU5TRS4KICoKICogQGF1dGhvciAgICBKYW1lcyBMb2dzZG9uIDxkd2FyZkBnaXJzYnJhaW4ub3JnPgogKiBAY29weXJpZ2h0IDIwMTAgSmFtZXMgTG9nc2RvbSAoaHR0cDovL2dpcnNicmFpbi5vcmcpCiAqIEBsaWNlbnNlICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAgVGhlIE1JVCBMaWNlbnNlCiAqLwoKbmFtZXNwYWNlIGNsaTsKCi8qKgogKiBIYW5kbGVzIHJlbmRlcmluZyBzdHJpbmdzLiBJZiBleHRyYSBzY2FsYXIgYXJndW1lbnRzIGFyZSBnaXZlbiBhZnRlciB0aGUgYCRtc2dgCiAqIHRoZSBzdHJpbmcgd2lsbCBiZSByZW5kZXJlZCB3aXRoIGBzcHJpbnRmYC4gSWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyBhbiBgYXJyYXlgCiAqIHRoZW4gZWFjaCBrZXkgaW4gdGhlIGFycmF5IHdpbGwgYmUgdGhlIHBsYWNlaG9sZGVyIG5hbWUuIFBsYWNlaG9sZGVycyBhcmUgb2YgdGhlCiAqIGZvcm1hdCB7OmtleX0uCiAqCiAqIEBwYXJhbSBzdHJpbmcgICAkbXNnICBUaGUgbWVzc2FnZSB0byByZW5kZXIuCiAqIEBwYXJhbSBtaXhlZCAgICAuLi4gICBFaXRoZXIgc2NhbGFyIGFyZ3VtZW50cyBvciBhIHNpbmdsZSBhcnJheSBhcmd1bWVudC4KICogQHJldHVybiBzdHJpbmcgIFRoZSByZW5kZXJlZCBzdHJpbmcuCiAqLwpmdW5jdGlvbiByZW5kZXIoICRtc2cgKSB7CglyZXR1cm4gU3RyZWFtczo6X2NhbGwoICdyZW5kZXInLCBmdW5jX2dldF9hcmdzKCkgKTsKfQoKLyoqCiAqIFNob3J0Y3V0IGZvciBwcmludGluZyB0byBgU1RET1VUYC4gVGhlIG1lc3NhZ2UgYW5kIHBhcmFtZXRlcnMgYXJlIHBhc3NlZAogKiB0aHJvdWdoIGBzcHJpbnRmYCBiZWZvcmUgb3V0cHV0LgogKgogKiBAcGFyYW0gc3RyaW5nICAkbXNnICBUaGUgbWVzc2FnZSB0byBvdXRwdXQgaW4gYHByaW50ZmAgZm9ybWF0LgogKiBAcGFyYW0gbWl4ZWQgICAuLi4gICBFaXRoZXIgc2NhbGFyIGFyZ3VtZW50cyBvciBhIHNpbmdsZSBhcnJheSBhcmd1bWVudC4KICogQHJldHVybiB2b2lkCiAqIEBzZWUgXGNsaVxyZW5kZXIoKQogKi8KZnVuY3Rpb24gb3V0KCAkbXNnICkgewoJU3RyZWFtczo6X2NhbGwoICdvdXQnLCBmdW5jX2dldF9hcmdzKCkgKTsKfQoKLyoqCiAqIFBhZHMgYCRtc2dgIHRvIHRoZSB3aWR0aCBvZiB0aGUgc2hlbGwgYmVmb3JlIHBhc3NpbmcgdG8gYGNsaVxvdXRgLgogKgogKiBAcGFyYW0gc3RyaW5nICAkbXNnICBUaGUgbWVzc2FnZSB0byBwYWQgYW5kIHBhc3Mgb24uCiAqIEBwYXJhbSBtaXhlZCAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgogKiBAcmV0dXJuIHZvaWQKICogQHNlZSBjbGlcb3V0KCkKICovCmZ1bmN0aW9uIG91dF9wYWRkZWQoICRtc2cgKSB7CglTdHJlYW1zOjpfY2FsbCggJ291dF9wYWRkZWQnLCBmdW5jX2dldF9hcmdzKCkgKTsKfQoKLyoqCiAqIFByaW50cyBhIG1lc3NhZ2UgdG8gYFNURE9VVGAgd2l0aCBhIG5ld2xpbmUgYXBwZW5kZWQuIFNlZSBgXGNsaVxvdXRgIGZvcgogKiBtb3JlIGRvY3VtZW50YXRpb24uCiAqCiAqIEBzZWUgY2xpXG91dCgpCiAqLwpmdW5jdGlvbiBsaW5lKCAkbXNnID0gJycgKSB7CglTdHJlYW1zOjpfY2FsbCggJ2xpbmUnLCBmdW5jX2dldF9hcmdzKCkgKTsKfQoKLyoqCiAqIFNob3J0Y3V0IGZvciBwcmludGluZyB0byBgU1RERVJSYC4gVGhlIG1lc3NhZ2UgYW5kIHBhcmFtZXRlcnMgYXJlIHBhc3NlZAogKiB0aHJvdWdoIGBzcHJpbnRmYCBiZWZvcmUgb3V0cHV0LgogKgogKiBAcGFyYW0gc3RyaW5nICAkbXNnICBUaGUgbWVzc2FnZSB0byBvdXRwdXQgaW4gYHByaW50ZmAgZm9ybWF0LiBXaXRoIG5vIHN0cmluZywKICogICAgICAgICAgICAgICAgICAgICAgYSBuZXdsaW5lIGlzIHByaW50ZWQuCiAqIEBwYXJhbSBtaXhlZCAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgogKiBAcmV0dXJuIHZvaWQKICovCmZ1bmN0aW9uIGVyciggJG1zZyA9ICcnICkgewoJU3RyZWFtczo6X2NhbGwoICdlcnInLCBmdW5jX2dldF9hcmdzKCkgKTsKfQoKLyoqCiAqIFRha2VzIGlucHV0IGZyb20gYFNURElOYCBpbiB0aGUgZ2l2ZW4gZm9ybWF0LiBJZiBhbiBlbmQgb2YgdHJhbnNtaXNzaW9uCiAqIGNoYXJhY3RlciBpcyBzZW50ICheRCksIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCiAqCiAqIEBwYXJhbSBzdHJpbmcgICRmb3JtYXQgIEEgdmFsaWQgaW5wdXQgZm9ybWF0LiBTZWUgYGZzY2FuZmAgZm9yIGRvY3VtZW50YXRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICAgIElmIG5vbmUgaXMgZ2l2ZW4sIGFsbCBpbnB1dCB1cCB0byB0aGUgZmlyc3QgbmV3bGluZQogKiAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhY2NlcHRlZC4KICogQHJldHVybiBzdHJpbmcgIFRoZSBpbnB1dCB3aXRoIHdoaXRlc3BhY2UgdHJpbW1lZC4KICogQHRocm93cyBcRXhjZXB0aW9uICBUaHJvd24gaWYgY3RybC1EIChFT1QpIGlzIHNlbnQgYXMgaW5wdXQuCiAqLwpmdW5jdGlvbiBpbnB1dCggJGZvcm1hdCA9IG51bGwgKSB7CglyZXR1cm4gU3RyZWFtczo6aW5wdXQoICRmb3JtYXQgKTsKfQoKLyoqCiAqIERpc3BsYXlzIGFuIGlucHV0IHByb21wdC4gSWYgbm8gZGVmYXVsdCB2YWx1ZSBpcyBwcm92aWRlZCB0aGUgcHJvbXB0IHdpbGwKICogY29udGludWUgZGlzcGxheWluZyB1bnRpbCBpbnB1dCBpcyByZWNlaXZlZC4KICoKICogQHBhcmFtIHN0cmluZyAgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXIuCiAqIEBwYXJhbSBzdHJpbmcgICRkZWZhdWx0ICBBIGRlZmF1bHQgdmFsdWUgaWYgdGhlIHVzZXIgcHJvdmlkZXMgbm8gaW5wdXQuCiAqIEBwYXJhbSBzdHJpbmcgICRtYXJrZXIgICBBIHN0cmluZyB0byBhcHBlbmQgdG8gdGhlIHF1ZXN0aW9uIGFuZCBkZWZhdWx0IHZhbHVlIG9uIGRpc3BsYXkuCiAqIEBwYXJhbSBib29sZWFuICRoaWRlICAgICBJZiB0aGUgdXNlciBpbnB1dCBzaG91bGQgYmUgaGlkZGVuCiAqIEByZXR1cm4gc3RyaW5nICBUaGUgdXNlcnMgaW5wdXQuCiAqIEBzZWUgY2xpXGlucHV0KCkKICovCmZ1bmN0aW9uIHByb21wdCggJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IGZhbHNlLCAkbWFya2VyID0gJzogJywgJGhpZGUgPSBmYWxzZSApIHsKCXJldHVybiBTdHJlYW1zOjpwcm9tcHQoICRxdWVzdGlvbiwgJGRlZmF1bHQsICRtYXJrZXIsICRoaWRlICk7Cn0KCi8qKgogKiBQcmVzZW50cyBhIHVzZXIgd2l0aCBhIG11bHRpcGxlIGNob2ljZSBxdWVzdGlvbiwgdXNlZnVsIGZvciAneWVzL25vJyB0eXBlCiAqIHF1ZXN0aW9ucyAod2hpY2ggdGhpcyBmdW5jdGlvbiBkZWZhdWx0cyB0b28pLgogKgogKiBAcGFyYW0gc3RyaW5nICAgICAgJHF1ZXN0aW9uICAgVGhlIHF1ZXN0aW9uIHRvIGFzayB0aGUgdXNlci4KICogQHBhcmFtIHN0cmluZyAgICAgICRjaG9pY2UKICogQHBhcmFtIHN0cmluZ3xudWxsICRkZWZhdWx0ICAgIFRoZSBkZWZhdWx0IGNob2ljZS4gTlVMTCBpZiBhIGRlZmF1bHQgaXMgbm90IGFsbG93ZWQuCiAqIEBpbnRlcm5hbCBwYXJhbSBzdHJpbmcgJHZhbGlkICBBIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGFsbG93ZWQgYXMgYSByZXNwb25zZS4gQ2FzZQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgaWdub3JlZC4KICogQHJldHVybiBzdHJpbmcgIFRoZSB1c2VycyBjaG9pY2UuCiAqIEBzZWUgICAgICBjbGlccHJvbXB0KCkKICovCmZ1bmN0aW9uIGNob29zZSggJHF1ZXN0aW9uLCAkY2hvaWNlID0gJ3luJywgJGRlZmF1bHQgPSAnbicgKSB7CglyZXR1cm4gU3RyZWFtczo6Y2hvb3NlKCAkcXVlc3Rpb24sICRjaG9pY2UsICRkZWZhdWx0ICk7Cn0KCi8qKgogKiBEb2VzIHRoZSBzYW1lIGFzIHtAc2VlIGNob29zZSgpfSwgYnV0IGFsd2F5cyBhc2tzIHllcy9ubyBhbmQgcmV0dXJucyBhIGJvb2xlYW4KICoKICogQHBhcmFtIHN0cmluZyAgICAkcXVlc3Rpb24gIFRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXIuCiAqIEBwYXJhbSBib29sfG51bGwgJGRlZmF1bHQgICBUaGUgZGVmYXVsdCBjaG9pY2UsIGluIGEgYm9vbGVhbiBmb3JtYXQuCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gY29uZmlybSggJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IGZhbHNlICkgewoJaWYgKCBpc19ib29sKCAkZGVmYXVsdCApICkgewoJCSRkZWZhdWx0ID0gJGRlZmF1bHQ/ICd5JyA6ICduJzsKCX0KCSRyZXN1bHQgID0gY2hvb3NlKCAkcXVlc3Rpb24sICd5bicsICRkZWZhdWx0ICk7CglyZXR1cm4gJHJlc3VsdCA9PSAneSc7Cn0KCi8qKgogKiBEaXNwbGF5cyBhbiBhcnJheSBvZiBzdHJpbmdzIGFzIGEgbWVudSB3aGVyZSBhIHVzZXIgY2FuIGVudGVyIGEgbnVtYmVyIHRvCiAqIGNob29zZSBhbiBvcHRpb24uIFRoZSBhcnJheSBtdXN0IGJlIGEgc2luZ2xlIGRpbWVuc2lvbiB3aXRoIGVpdGhlciBzdHJpbmdzCiAqIG9yIG9iamVjdHMgd2l0aCBhIGBfX3RvU3RyaW5nKClgIG1ldGhvZC4KICoKICogQHBhcmFtIGFycmF5ICAkaXRlbXMgICBUaGUgbGlzdCBvZiBpdGVtcyB0aGUgdXNlciBjYW4gY2hvb3NlIGZyb20uCiAqIEBwYXJhbSBzdHJpbmcgJGRlZmF1bHQgVGhlIGluZGV4IG9mIHRoZSBkZWZhdWx0IGl0ZW0uCiAqIEBwYXJhbSBzdHJpbmcgJHRpdGxlICAgVGhlIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyIHdoZW4gcHJvbXB0ZWQuCiAqIEByZXR1cm4gc3RyaW5nICBUaGUgaW5kZXggb2YgdGhlIGNob3NlbiBpdGVtLgogKiBAc2VlIGNsaVxsaW5lKCkKICogQHNlZSBjbGlcaW5wdXQoKQogKiBAc2VlIGNsaVxlcnIoKQogKi8KZnVuY3Rpb24gbWVudSggJGl0ZW1zLCAkZGVmYXVsdCA9IG51bGwsICR0aXRsZSA9ICdDaG9vc2UgYW4gaXRlbScgKSB7CglyZXR1cm4gU3RyZWFtczo6bWVudSggJGl0ZW1zLCAkZGVmYXVsdCwgJHRpdGxlICk7Cn0KCi8qKgogKiBBdHRlbXB0cyBhbiBlbmNvZGluZy1zYWZlIHdheSBvZiBnZXR0aW5nIHN0cmluZyBsZW5ndGguIElmIGludGwgZXh0ZW5zaW9uIG9yIFBDUkUgd2l0aCAnXFgnIG9yIG1iX3N0cmluZyBleHRlbnNpb24gYXJlbid0CiAqIGF2YWlsYWJsZSwgZmFsbHMgYmFjayB0byBiYXNpYyBzdHJsZW4uCiAqCiAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHN0ciAgICAgIFRoZSBzdHJpbmcgdG8gY2hlY2suCiAqIEBwYXJhbSAgc3RyaW5nfGJvb2wgJGVuY29kaW5nIE9wdGlvbmFsLiBUaGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmluZy4gRGVmYXVsdCBmYWxzZS4KICogQHJldHVybiBpbnQgIE51bWVyaWMgdmFsdWUgdGhhdCByZXByZXNlbnRzIHRoZSBzdHJpbmcncyBsZW5ndGgKICovCmZ1bmN0aW9uIHNhZmVfc3RybGVuKCAkc3RyLCAkZW5jb2RpbmcgPSBmYWxzZSApIHsKCS8vIEFsbG93IGZvciBzZWxlY3RpdmUgdGVzdGluZ3MgLSAiMSIgYml0IHNldCB0ZXN0cyBncmFwaGVtZV9zdHJsZW4oKSwgIjIiIHByZWdfbWF0Y2hfYWxsKCAnL1xYL3UnICksICI0IiBtYl9zdHJsZW4oKSwgIm90aGVyIiBzdHJsZW4oKS4KCSR0ZXN0X3NhZmVfc3RybGVuID0gZ2V0ZW52KCAnUEhQX0NMSV9UT09MU19URVNUX1NBRkVfU1RSTEVOJyApOwoKCS8vIEFzc3VtZSBVVEYtOCBpZiBubyBlbmNvZGluZyBnaXZlbiAtIGBncmFwaGVtZV9zdHJsZW4oKWAgd2lsbCByZXR1cm4gbnVsbCBpZiBnaXZlbiBub24tVVRGLTggc3RyaW5nLgoJaWYgKCAoICEgJGVuY29kaW5nIHx8ICdVVEYtOCcgPT09ICRlbmNvZGluZyApICYmIGNhbl91c2VfaWN1KCkgJiYgbnVsbCAhPT0gKCAkbGVuZ3RoID0gZ3JhcGhlbWVfc3RybGVuKCAkc3RyICkgKSApIHsKCQlpZiAoICEgJHRlc3Rfc2FmZV9zdHJsZW4gfHwgKCAkdGVzdF9zYWZlX3N0cmxlbiAmIDEgKSApIHsKCQkJcmV0dXJuICRsZW5ndGg7CgkJfQoJfQoJLy8gQXNzdW1lIFVURi04IGlmIG5vIGVuY29kaW5nIGdpdmVuIC0gYHByZWdfbWF0Y2hfYWxsKClgIHdpbGwgcmV0dXJuIGZhbHNlIGlmIGdpdmVuIG5vbi1VVEYtOCBzdHJpbmcuCglpZiAoICggISAkZW5jb2RpbmcgfHwgJ1VURi04JyA9PT0gJGVuY29kaW5nICkgJiYgY2FuX3VzZV9wY3JlX3goKSAmJiBmYWxzZSAhPT0gKCAkbGVuZ3RoID0gcHJlZ19tYXRjaF9hbGwoICcvXFgvdScsICRzdHIsICRkdW1teSAvKm5lZWRlZCBmb3IgUEhQIDUuMyovICkgKSApIHsKCQlpZiAoICEgJHRlc3Rfc2FmZV9zdHJsZW4gfHwgKCAkdGVzdF9zYWZlX3N0cmxlbiAmIDIgKSApIHsKCQkJcmV0dXJuICRsZW5ndGg7CgkJfQoJfQoJLy8gTGVnYWN5IGVuY29kaW5ncyBhbmQgb2xkIFBIUHMgd2lsbCByZWFjaCBoZXJlLgoJaWYgKCBmdW5jdGlvbl9leGlzdHMoICdtYl9zdHJsZW4nICkgJiYgKCAkZW5jb2RpbmcgfHwgZnVuY3Rpb25fZXhpc3RzKCAnbWJfZGV0ZWN0X2VuY29kaW5nJyApICkgKSB7CgkJaWYgKCAhICRlbmNvZGluZyApIHsKCQkJJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCAkc3RyLCBudWxsLCB0cnVlIC8qc3RyaWN0Ki8gKTsKCQl9CgkJJGxlbmd0aCA9ICRlbmNvZGluZyA/IG1iX3N0cmxlbiggJHN0ciwgJGVuY29kaW5nICkgOiBtYl9zdHJsZW4oICRzdHIgKTsgLy8gbWJzdHJpbmcgZnVuY3MgY2FuIGZhaWwgaWYgZ2l2ZW4gYCRlbmNvZGluZ2AgYXJnIHRoYXQgZXZhbHMgdG8gZmFsc2UuCgkJaWYgKCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSB7CgkJCS8vIFN1YnRyYWN0IGNvbWJpbmluZyBjaGFyYWN0ZXJzLgoJCQkkbGVuZ3RoIC09IHByZWdfbWF0Y2hfYWxsKCBnZXRfdW5pY29kZV9yZWdleHMoICdtJyApLCAkc3RyLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApOwoJCX0KCQlpZiAoICEgJHRlc3Rfc2FmZV9zdHJsZW4gfHwgKCAkdGVzdF9zYWZlX3N0cmxlbiAmIDQgKSApIHsKCQkJcmV0dXJuICRsZW5ndGg7CgkJfQoJfQoJcmV0dXJuIHN0cmxlbiggJHN0ciApOwp9CgovKioKICogQXR0ZW1wdHMgYW4gZW5jb2Rpbmctc2FmZSB3YXkgb2YgZ2V0dGluZyBhIHN1YnN0cmluZy4gSWYgaW50bCBleHRlbnNpb24gb3IgUENSRSB3aXRoICdcWCcgb3IgbWJfc3RyaW5nIGV4dGVuc2lvbiBhcmVuJ3QKICogYXZhaWxhYmxlLCBmYWxscyBiYWNrIHRvIHN1YnN0cigpLgogKiAJCQogKiBAcGFyYW0gIHN0cmluZyAgICAgICAgJHN0ciAgICAgIFRoZSBpbnB1dCBzdHJpbmcuCiAqIEBwYXJhbSAgaW50ICAgICAgICAgICAkc3RhcnQgICAgVGhlIHN0YXJ0aW5nIHBvc2l0aW9uIG9mIHRoZSBzdWJzdHJpbmcuCiAqIEBwYXJhbSAgaW50fGJvb2x8bnVsbCAkbGVuZ3RoICAgT3B0aW9uYWwsIHVubGVzcyAkaXNfd2lkdGggaXMgc2V0LiBNYXhpbXVtIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nLiBEZWZhdWx0IGZhbHNlLiBOZWdhdGl2ZSBub3Qgc3VwcG9ydGVkLgogKiBAcGFyYW0gIGludHxib29sICAgICAgJGlzX3dpZHRoIE9wdGlvbmFsLiBJZiBzZXQgYW5kIGVuY29kaW5nIGlzIFVURi04LCAkbGVuZ3RoICh3aGljaCBtdXN0IGJlIHNwZWNpZmllZCkgaXMgaW50ZXJwcmV0ZWQgYXMgc3BhY2luZyB3aWR0aC4gRGVmYXVsdCBmYWxzZS4KICogQHBhcmFtICBzdHJpbmd8Ym9vbCAgICRlbmNvZGluZyBPcHRpb25hbC4gVGhlIGVuY29kaW5nIG9mIHRoZSBzdHJpbmcuIERlZmF1bHQgZmFsc2UuCiAqIEByZXR1cm4gYm9vbHxzdHJpbmcgIEZhbHNlIGlmIGdpdmVuIHVuc3VwcG9ydGVkIGFyZ3MsIG90aGVyd2lzZSBzdWJzdHJpbmcgb2Ygc3RyaW5nIHNwZWNpZmllZCBieSBzdGFydCBhbmQgbGVuZ3RoIHBhcmFtZXRlcnMKICovCmZ1bmN0aW9uIHNhZmVfc3Vic3RyKCAkc3RyLCAkc3RhcnQsICRsZW5ndGggPSBmYWxzZSwgJGlzX3dpZHRoID0gZmFsc2UsICRlbmNvZGluZyA9IGZhbHNlICkgewoJLy8gTmVnYXRpdmUgJGxlbmd0aCBvciAkaXNfd2lkdGggYW5kICRsZW5ndGggbm90IHNwZWNpZmllZCBub3Qgc3VwcG9ydGVkLgoJaWYgKCAkbGVuZ3RoIDwgMCB8fCAoICRpc193aWR0aCAmJiAoIG51bGwgPT09ICRsZW5ndGggfHwgZmFsc2UgPT09ICRsZW5ndGggKSApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCS8vIE5lZWQgdGhpcyBmb3Igbm9ybWFsaXphdGlvbiBiZWxvdyBhbmQgb3RoZXIgdXNlcy4KCSRzYWZlX3N0cmxlbiA9IHNhZmVfc3RybGVuKCAkc3RyLCAkZW5jb2RpbmcgKTsKCgkvLyBOb3JtYWxpemUgYCRsZW5ndGhgIHdoZW4gbm90IHNwZWNpZmllZCAtIFBIUCA1LjMgc3Vic3RyIHRha2VzIGZhbHNlIGFzIGZ1bGwgbGVuZ3RoLCBQSFAgPiA1LjMgdGFrZXMgbnVsbC4KCWlmICggbnVsbCA9PT0gJGxlbmd0aCB8fCBmYWxzZSA9PT0gJGxlbmd0aCApIHsKCQkkbGVuZ3RoID0gJHNhZmVfc3RybGVuOwoJfQoJLy8gTm9ybWFsaXplIGAkc3RhcnRgIC0gdmFyaW91cyBtZXRob2RzIHRyZWF0IHRoaXMgZGlmZmVyZW50bHkuCglpZiAoICRzdGFydCA+ICRzYWZlX3N0cmxlbiApIHsKCQlyZXR1cm4gJyc7Cgl9CglpZiAoICRzdGFydCA8IDAgJiYgLSRzdGFydCA+ICRzYWZlX3N0cmxlbiApIHsKCQkkc3RhcnQgPSAwOwoJfQoKCS8vIEFsbG93IGZvciBzZWxlY3RpdmUgdGVzdGluZ3MgLSAiMSIgYml0IHNldCB0ZXN0cyBncmFwaGVtZV9zdWJzdHIoKSwgIjIiIHByZWdfc3BsaXQoICcvXFgvJyApLCAiNCIgbWJfc3Vic3RyKCksICI4IiBzdWJzdHIoKS4KCSR0ZXN0X3NhZmVfc3Vic3RyID0gZ2V0ZW52KCAnUEhQX0NMSV9UT09MU19URVNUX1NBRkVfU1VCU1RSJyApOwoKCS8vIEFzc3VtZSBVVEYtOCBpZiBubyBlbmNvZGluZyBnaXZlbiAtIGBncmFwaGVtZV9zdWJzdHIoKWAgd2lsbCByZXR1cm4gZmFsc2UgKG5vdCBudWxsIGxpa2UgYGdyYXBoZW1lX3N0cmxlbigpYCkgaWYgZ2l2ZW4gbm9uLVVURi04IHN0cmluZy4KCWlmICggKCAhICRlbmNvZGluZyB8fCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSAmJiBjYW5fdXNlX2ljdSgpICYmIGZhbHNlICE9PSAoICR0cnkgPSBncmFwaGVtZV9zdWJzdHIoICRzdHIsICRzdGFydCwgJGxlbmd0aCApICkgKSB7CgkJaWYgKCAhICR0ZXN0X3NhZmVfc3Vic3RyIHx8ICggJHRlc3Rfc2FmZV9zdWJzdHIgJiAxICkgKSB7CgkJCXJldHVybiAkaXNfd2lkdGggPyBfc2FmZV9zdWJzdHJfZWF3KCAkdHJ5LCAkbGVuZ3RoICkgOiAkdHJ5OwoJCX0KCX0KCS8vIEFzc3VtZSBVVEYtOCBpZiBubyBlbmNvZGluZyBnaXZlbiAtIGBwcmVnX3NwbGl0KClgIHJldHVybnMgYSBvbmUgZWxlbWVudCBhcnJheSBpZiBnaXZlbiBub24tVVRGLTggc3RyaW5nIChQSFAgYnVnKSBzbyBuZWVkIHRvIGNoZWNrIGBwcmVnX2xhc3RfZXJyb3IoKWAuCglpZiAoICggISAkZW5jb2RpbmcgfHwgJ1VURi04JyA9PT0gJGVuY29kaW5nICkgJiYgY2FuX3VzZV9wY3JlX3goKSApIHsKCQlpZiAoIGZhbHNlICE9PSAoICR0cnkgPSBwcmVnX3NwbGl0KCAnLyhcWCkvdScsICRzdHIsICRzYWZlX3N0cmxlbiArIDEsIFBSRUdfU1BMSVRfREVMSU1fQ0FQVFVSRSB8IFBSRUdfU1BMSVRfTk9fRU1QVFkgKSApICYmICEgcHJlZ19sYXN0X2Vycm9yKCkgKSB7CgkJCSR0cnkgPSBpbXBsb2RlKCAnJywgYXJyYXlfc2xpY2UoICR0cnksICRzdGFydCwgJGxlbmd0aCApICk7CgkJCWlmICggISAkdGVzdF9zYWZlX3N1YnN0ciB8fCAoICR0ZXN0X3NhZmVfc3Vic3RyICYgMiApICkgewoJCQkJcmV0dXJuICRpc193aWR0aCA/IF9zYWZlX3N1YnN0cl9lYXcoICR0cnksICRsZW5ndGggKSA6ICR0cnk7CgkJCX0KCQl9Cgl9CgkvLyBMZWdhY3kgZW5jb2RpbmdzIGFuZCBvbGQgUEhQcyB3aWxsIHJlYWNoIGhlcmUuCglpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ21iX3N1YnN0cicgKSAmJiAoICRlbmNvZGluZyB8fCBmdW5jdGlvbl9leGlzdHMoICdtYl9kZXRlY3RfZW5jb2RpbmcnICkgKSApIHsKCQlpZiAoICEgJGVuY29kaW5nICkgewoJCQkkZW5jb2RpbmcgPSBtYl9kZXRlY3RfZW5jb2RpbmcoICRzdHIsIG51bGwsIHRydWUgLypzdHJpY3QqLyApOwoJCX0KCQkvLyBCdWc6IG5vdCBhZGp1c3RpbmcgZm9yIGNvbWJpbmluZyBjaGFycy4KCQkkdHJ5ID0gJGVuY29kaW5nID8gbWJfc3Vic3RyKCAkc3RyLCAkc3RhcnQsICRsZW5ndGgsICRlbmNvZGluZyApIDogbWJfc3Vic3RyKCAkc3RyLCAkc3RhcnQsICRsZW5ndGggKTsgLy8gbWJzdHJpbmcgZnVuY3MgY2FuIGZhaWwgaWYgZ2l2ZW4gYCRlbmNvZGluZ2AgYXJnIHRoYXQgZXZhbHMgdG8gZmFsc2UuCgkJaWYgKCAnVVRGLTgnID09PSAkZW5jb2RpbmcgJiYgJGlzX3dpZHRoICkgewoJCQkkdHJ5ID0gX3NhZmVfc3Vic3RyX2VhdyggJHRyeSwgJGxlbmd0aCApOwoJCX0KCQlpZiAoICEgJHRlc3Rfc2FmZV9zdWJzdHIgfHwgKCAkdGVzdF9zYWZlX3N1YnN0ciAmIDQgKSApIHsKCQkJcmV0dXJuICR0cnk7CgkJfQoJfQoJcmV0dXJuIHN1YnN0ciggJHN0ciwgJHN0YXJ0LCAkbGVuZ3RoICk7Cn0KCi8qKgogKiBJbnRlcm5hbCBmdW5jdGlvbiB1c2VkIGJ5IGBzYWZlX3N1YnN0cigpYCB0byBhZGp1c3QgZm9yIEVhc3QgQXNpYW4gZG91YmxlLXdpZHRoIGNoYXJzLgogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gX3NhZmVfc3Vic3RyX2VhdyggJHN0ciwgJGxlbmd0aCApIHsKCS8vIFNldCB0aGUgRWFzdCBBc2lhbiBXaWR0aCByZWdleC4KCSRlYXdfcmVnZXggPSBnZXRfdW5pY29kZV9yZWdleHMoICdlYXcnICk7CgoJLy8gSWYgdGhlcmUncyBhbnkgRWFzdCBBc2lhbiBkb3VibGUtd2lkdGggY2hhcnMuLi4KCWlmICggcHJlZ19tYXRjaCggJGVhd19yZWdleCwgJHN0ciApICkgewoJCS8vIE5vdGUgdGhhdCBpZiB0aGUgbGVuZ3RoIGVuZHMgaW4gdGhlIG1pZGRsZSBvZiBhIGRvdWJsZS13aWR0aCBjaGFyLCB0aGUgY2hhciBpcyBleGNsdWRlZCwgbm90IGluY2x1ZGVkLgoKCQkvLyBTZWUgaWYgaXQncyBhbGwgRUFXLgoJCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnbWJfc3Vic3RyJyApICYmIHByZWdfbWF0Y2hfYWxsKCAkZWF3X3JlZ2V4LCAkc3RyLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApID09PSAkbGVuZ3RoICkgewoJCQkvLyBKdXN0IGhhbHZlIHRoZSBsZW5ndGggc28gKHJvdW5kZWQgZG93biB0byBhIG1pbmltdW0gb2YgMSkuCgkJCSRzdHIgPSBtYl9zdWJzdHIoICRzdHIsIDAsIG1heCggKGludCkgKCAkbGVuZ3RoIC8gMiApLCAxICksICdVVEYtOCcgKTsKCQl9IGVsc2UgewoJCQkvLyBFeHBsb2RlIHN0cmluZyBpbnRvIGFuIGFycmF5IG9mIFVURi04IGNoYXJzLiBCYXNlZCBvbiBjb3JlIGBfbWJfc3Vic3RyKClgIGluICJ3cC1pbmNsdWRlcy9jb21wYXQucGhwIi4KCQkJJGNoYXJzID0gcHJlZ19zcGxpdCggJy8oW1x4MDAtXHg3Zlx4YzItXHhmNF1bXlx4MDAtXHg3Zlx4YzItXHhmNF0qKS8nLCAkc3RyLCAkbGVuZ3RoICsgMSwgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFIHwgUFJFR19TUExJVF9OT19FTVBUWSApOwoJCQkkY250ID0gbWluKCBjb3VudCggJGNoYXJzICksICRsZW5ndGggKTsKCQkJJHdpZHRoID0gJGxlbmd0aDsKCgkJCWZvciAoICRsZW5ndGggPSAwOyAkbGVuZ3RoIDwgJGNudCAmJiAkd2lkdGggPiAwOyAkbGVuZ3RoKysgKSB7CgkJCQkkd2lkdGggLT0gcHJlZ19tYXRjaCggJGVhd19yZWdleCwgJGNoYXJzWyAkbGVuZ3RoIF0gKSA/IDIgOiAxOwoJCQl9CgkJCS8vIFJvdW5kIGRvd24gdG8gYSBtaW5pbXVtIG9mIDEuCgkJCWlmICggJHdpZHRoIDwgMCAmJiAkbGVuZ3RoID4gMSApIHsKCQkJCSRsZW5ndGgtLTsKCQkJfQoJCQlyZXR1cm4gam9pbiggJycsIGFycmF5X3NsaWNlKCAkY2hhcnMsIDAsICRsZW5ndGggKSApOwoJCX0KCX0KCXJldHVybiAkc3RyOwp9CgovKioKICogQW4gZW5jb2Rpbmctc2FmZSB3YXkgb2YgcGFkZGluZyBzdHJpbmcgbGVuZ3RoIGZvciBkaXNwbGF5CiAqCiAqIEBwYXJhbSAgc3RyaW5nICAgICAgJHN0cmluZyAgIFRoZSBzdHJpbmcgdG8gcGFkLgogKiBAcGFyYW0gIGludCAgICAgICAgICRsZW5ndGggICBUaGUgbGVuZ3RoIHRvIHBhZCBpdCB0by4KICogQHBhcmFtICBzdHJpbmd8Ym9vbCAkZW5jb2RpbmcgT3B0aW9uYWwuIFRoZSBlbmNvZGluZyBvZiB0aGUgc3RyaW5nLiBEZWZhdWx0IGZhbHNlLgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gc2FmZV9zdHJfcGFkKCAkc3RyaW5nLCAkbGVuZ3RoLCAkZW5jb2RpbmcgPSBmYWxzZSApIHsKCSRyZWFsX2xlbmd0aCA9IHN0cndpZHRoKCAkc3RyaW5nLCAkZW5jb2RpbmcgKTsKCSRkaWZmID0gc3RybGVuKCAkc3RyaW5nICkgLSAkcmVhbF9sZW5ndGg7CgkkbGVuZ3RoICs9ICRkaWZmOwoKCXJldHVybiBzdHJfcGFkKCAkc3RyaW5nLCAkbGVuZ3RoICk7Cn0KCi8qKgogKiBHZXQgd2lkdGggb2Ygc3RyaW5nLCBpZSBsZW5ndGggaW4gY2hhcmFjdGVycywgdGFraW5nIGludG8gYWNjb3VudCBtdWx0aS1ieXRlIGFuZCBtYXJrIGNoYXJhY3RlcnMgZm9yIFVURi04LCBhbmQgbXVsdGktYnl0ZSBmb3Igbm9uLVVURi04LgogKgogKiBAcGFyYW0gIHN0cmluZyAgICAgICRzdHJpbmcgICBUaGUgc3RyaW5nIHRvIGNoZWNrLgogKiBAcGFyYW0gIHN0cmluZ3xib29sICRlbmNvZGluZyBPcHRpb25hbC4gVGhlIGVuY29kaW5nIG9mIHRoZSBzdHJpbmcuIERlZmF1bHQgZmFsc2UuCiAqIEByZXR1cm4gaW50ICBUaGUgc3RyaW5nJ3Mgd2lkdGguCiAqLwpmdW5jdGlvbiBzdHJ3aWR0aCggJHN0cmluZywgJGVuY29kaW5nID0gZmFsc2UgKSB7CgkvLyBTZXQgdGhlIEVhc3QgQXNpYW4gV2lkdGggYW5kIE1hcmsgcmVnZXhzLgoJbGlzdCggJGVhd19yZWdleCwgJG1fcmVnZXggKSA9IGdldF91bmljb2RlX3JlZ2V4cygpOwoKCS8vIEFsbG93IGZvciBzZWxlY3RpdmUgdGVzdGluZ3MgLSAiMSIgYml0IHNldCB0ZXN0cyBncmFwaGVtZV9zdHJsZW4oKSwgIjIiIHByZWdfbWF0Y2hfYWxsKCAnL1xYL3UnICksICI0IiBtYl9zdHJ3aWR0aCgpLCAib3RoZXIiIHNhZmVfc3RybGVuKCkuCgkkdGVzdF9zdHJ3aWR0aCA9IGdldGVudiggJ1BIUF9DTElfVE9PTFNfVEVTVF9TVFJXSURUSCcgKTsKCgkvLyBBc3N1bWUgVVRGLTggaWYgbm8gZW5jb2RpbmcgZ2l2ZW4gLSBgZ3JhcGhlbWVfc3RybGVuKClgIHdpbGwgcmV0dXJuIG51bGwgaWYgZ2l2ZW4gbm9uLVVURi04IHN0cmluZy4KCWlmICggKCAhICRlbmNvZGluZyB8fCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSAmJiBjYW5fdXNlX2ljdSgpICYmIG51bGwgIT09ICggJHdpZHRoID0gZ3JhcGhlbWVfc3RybGVuKCAkc3RyaW5nICkgKSApIHsKCQlpZiAoICEgJHRlc3Rfc3Ryd2lkdGggfHwgKCAkdGVzdF9zdHJ3aWR0aCAmIDEgKSApIHsKCQkJcmV0dXJuICR3aWR0aCArIHByZWdfbWF0Y2hfYWxsKCAkZWF3X3JlZ2V4LCAkc3RyaW5nLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApOwoJCX0KCX0KCS8vIEFzc3VtZSBVVEYtOCBpZiBubyBlbmNvZGluZyBnaXZlbiAtIGBwcmVnX21hdGNoX2FsbCgpYCB3aWxsIHJldHVybiBmYWxzZSBpZiBnaXZlbiBub24tVVRGLTggc3RyaW5nLgoJaWYgKCAoICEgJGVuY29kaW5nIHx8ICdVVEYtOCcgPT09ICRlbmNvZGluZyApICYmIGNhbl91c2VfcGNyZV94KCkgJiYgZmFsc2UgIT09ICggJHdpZHRoID0gcHJlZ19tYXRjaF9hbGwoICcvXFgvdScsICRzdHJpbmcsICRkdW1teSAvKm5lZWRlZCBmb3IgUEhQIDUuMyovICkgKSApIHsKCQlpZiAoICEgJHRlc3Rfc3Ryd2lkdGggfHwgKCAkdGVzdF9zdHJ3aWR0aCAmIDIgKSApIHsKCQkJcmV0dXJuICR3aWR0aCArIHByZWdfbWF0Y2hfYWxsKCAkZWF3X3JlZ2V4LCAkc3RyaW5nLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApOwoJCX0KCX0KCS8vIExlZ2FjeSBlbmNvZGluZ3MgYW5kIG9sZCBQSFBzIHdpbGwgcmVhY2ggaGVyZS4KCWlmICggZnVuY3Rpb25fZXhpc3RzKCAnbWJfc3Ryd2lkdGgnICkgJiYgKCAkZW5jb2RpbmcgfHwgZnVuY3Rpb25fZXhpc3RzKCAnbWJfZGV0ZWN0X2VuY29kaW5nJyApICkgKSB7CgkJaWYgKCAhICRlbmNvZGluZyApIHsKCQkJJGVuY29kaW5nID0gbWJfZGV0ZWN0X2VuY29kaW5nKCAkc3RyaW5nLCBudWxsLCB0cnVlIC8qc3RyaWN0Ki8gKTsKCQl9CgkJJHdpZHRoID0gJGVuY29kaW5nID8gbWJfc3Ryd2lkdGgoICRzdHJpbmcsICRlbmNvZGluZyApIDogbWJfc3Ryd2lkdGgoICRzdHJpbmcgKTsgLy8gbWJzdHJpbmcgZnVuY3MgY2FuIGZhaWwgaWYgZ2l2ZW4gYCRlbmNvZGluZ2AgYXJnIHRoYXQgZXZhbHMgdG8gZmFsc2UuCgkJaWYgKCAnVVRGLTgnID09PSAkZW5jb2RpbmcgKSB7CgkJCS8vIFN1YnRyYWN0IGNvbWJpbmluZyBjaGFyYWN0ZXJzLgoJCQkkd2lkdGggLT0gcHJlZ19tYXRjaF9hbGwoICRtX3JlZ2V4LCAkc3RyaW5nLCAkZHVtbXkgLypuZWVkZWQgZm9yIFBIUCA1LjMqLyApOwoJCX0KCQlpZiAoICEgJHRlc3Rfc3Ryd2lkdGggfHwgKCAkdGVzdF9zdHJ3aWR0aCAmIDQgKSApIHsKCQkJcmV0dXJuICR3aWR0aDsKCQl9Cgl9CglyZXR1cm4gc2FmZV9zdHJsZW4oICRzdHJpbmcsICRlbmNvZGluZyApOwp9CgovKioKICogUmV0dXJucyB3aGV0aGVyIElDVSBpcyBtb2Rlcm4gZW5vdWdoIG5vdCB0byBmbGFrZSBvdXQuCiAqCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gY2FuX3VzZV9pY3UoKSB7CglzdGF0aWMgJGNhbl91c2VfaWN1ID0gbnVsbDsKCglpZiAoIG51bGwgPT09ICRjYW5fdXNlX2ljdSApIHsKCQkvLyBDaG9vc2luZyBJQ1UgNTQsIFVuaWNvZGUgNy4wLgoJCSRjYW5fdXNlX2ljdSA9IGRlZmluZWQoICdJTlRMX0lDVV9WRVJTSU9OJyApICYmIHZlcnNpb25fY29tcGFyZSggSU5UTF9JQ1VfVkVSU0lPTiwgJzU0LjEnLCAnPj0nICkgJiYgZnVuY3Rpb25fZXhpc3RzKCAnZ3JhcGhlbWVfc3RybGVuJyApICYmIGZ1bmN0aW9uX2V4aXN0cyggJ2dyYXBoZW1lX3N1YnN0cicgKTsKCX0KCglyZXR1cm4gJGNhbl91c2VfaWN1Owp9CgovKioKICogUmV0dXJucyB3aGV0aGVyIFBDUkUgVW5pY29kZSBleHRlbmRlZCBncmFwaGVtZSBjbHVzdGVyICdcWCcgaXMgYXZhaWxhYmxlIGZvciB1c2UuCiAqCiAqIEByZXR1cm4gYm9vbAogKi8KZnVuY3Rpb24gY2FuX3VzZV9wY3JlX3goKSB7CglzdGF0aWMgJGNhbl91c2VfcGNyZV94ID0gbnVsbDsKCglpZiAoIG51bGwgPT09ICRjYW5fdXNlX3BjcmVfeCApIHsKCQkvLyAnXFgnIGludHJvZHVjZWQgKGFzIFVuaWNkZSBleHRlbmRlZCBncmFwaGVtZSBjbHVzdGVyKSBpbiBQQ1JFIDguMzIgLSBzZWUgaHR0cHM6Ly92Y3MucGNyZS5vcmcvcGNyZS9jb2RlL3RhZ3MvcGNyZS04LjMyL0NoYW5nZUxvZz92aWV3PW1hcmt1cCBsaW5lIDUzLgoJCS8vIE9sZGVyIHZlcnNpb25zIG9mIFBDUkUgd2VyZSBidW5kbGVkIHdpdGggUEhQIDw9IDUuMy4yMyAmIDw9IDUuNC4xMy4KCQkkcGNyZV92ZXJzaW9uID0gc3Vic3RyKCBQQ1JFX1ZFUlNJT04sIDAsIHN0cnNwbiggUENSRV9WRVJTSU9OLCAnMDEyMzQ1Njc4OS4nICkgKTsgLy8gUmVtb3ZlIGFueSB0cmFpbGluZyBkYXRlIHN0dWZmLgoJCSRjYW5fdXNlX3BjcmVfeCA9IHZlcnNpb25fY29tcGFyZSggJHBjcmVfdmVyc2lvbiwgJzguMzInLCAnPj0nICkgJiYgZmFsc2UgIT09IEBwcmVnX21hdGNoKCAnL1xYL3UnLCAnJyApOwoJfQoKCXJldHVybiAkY2FuX3VzZV9wY3JlX3g7Cn0KCi8qKgogKiBHZXQgdGhlIHJlZ2V4cyBnZW5lcmF0ZWQgZnJvbSBVbmljb2RlIGRhdGEuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGlkeCBPcHRpb25hbC4gUmV0dXJuIGEgc3BlY2lmaWMgcmVnZXggb25seS4gRGVmYXVsdCBudWxsLgogKiBAcmV0dXJuIGFycmF5fHN0cmluZyAgUmV0dXJucyBrZXllZCBhcnJheSBpZiBub3QgZ2l2ZW4gJGlkeCBvciAkaWR4IGRvZXNuJ3QgZXhpc3QsIG90aGVyd2lzZSB0aGUgc3BlY2lmaWMgcmVnZXggc3RyaW5nLgogKi8KZnVuY3Rpb24gZ2V0X3VuaWNvZGVfcmVnZXhzKCAkaWR4ID0gbnVsbCApIHsKCXN0YXRpYyAkZWF3X3JlZ2V4OyAvLyBFYXN0IEFzaWFuIFdpZHRoIHJlZ2V4LiBDaGFyYWN0ZXJzIHRoYXQgY291bnQgYXMgMiBjaGFyYWN0ZXJzIGFzIHRoZXkncmUgIndpZGUiIG9yICJmdWxsd2lkdGgiLiBTZWUgaHR0cDovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRzL3RyMTEvdHIxMS0xOS5odG1sCglzdGF0aWMgJG1fcmVnZXg7IC8vIE1hcmsgY2hhcmFjdGVycyByZWdleCAoVW5pY29kZSBwcm9wZXJ0eSAiTSIpIC0gbWFyayBjb21iaW5pbmcgIk1jIiwgbWFyayBlbmNsb3NpbmcgIk1lIiBhbmQgbWFyayBub24tc3BhY2luZyAiTW4iIGNoYXJzIHRoYXQgc2hvdWxkIGJlIGlnbm9yZWQgZm9yIHNwYWNpbmcgcHVycG9zZXMuCglpZiAoIG51bGwgPT09ICRlYXdfcmVnZXggKSB7CgkJLy8gTG9hZCBib3RoIHJlZ2V4cyBnZW5lcmF0ZWQgZnJvbSBVbmljb2RlIGRhdGEuCgkJcmVxdWlyZSBfX0RJUl9fIC4gJy91bmljb2RlL3JlZ2V4LnBocCc7Cgl9CgoJaWYgKCBudWxsICE9PSAkaWR4ICkgewoJCWlmICggJ2VhdycgPT09ICRpZHggKSB7CgkJCXJldHVybiAkZWF3X3JlZ2V4OwoJCX0KCQlpZiAoICdtJyA9PT0gJGlkeCApIHsKCQkJcmV0dXJuICRtX3JlZ2V4OwoJCX0KCX0KCglyZXR1cm4gYXJyYXkoICRlYXdfcmVnZXgsICRtX3JlZ2V4LCApOwp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdGFibGU7CgovKioKICogVGhlIHRhYnVsYXIgcmVuZGVyZXIgaXMgdXNlZCBmb3IgZGlzcGxheWluZyBkYXRhIGluIGEgdGFidWxhciBmb3JtYXQuCiAqLwpjbGFzcyBUYWJ1bGFyIGV4dGVuZHMgUmVuZGVyZXIgewoJLyoqCgkgKiBSZW5kZXJzIGEgcm93IGZvciBvdXRwdXQuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkcm93ICBUaGUgdGFibGUgcm93LgoJICogQHJldHVybiBzdHJpbmcgIFRoZSBmb3JtYXR0ZWQgdGFibGUgcm93LgoJICovCglwdWJsaWMgZnVuY3Rpb24gcm93KGFycmF5ICRyb3cpIHsKCQlyZXR1cm4gaW1wbG9kZSgiXHQiLCBhcnJheV92YWx1ZXMoJHJvdykpOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcdGFibGU7CgovKioKICogVGFibGUgcmVuZGVyZXJzIGFyZSB1c2VkIHRvIGNoYW5nZSBob3cgYSB0YWJsZSBpcyBkaXNwbGF5ZWQuCiAqLwphYnN0cmFjdCBjbGFzcyBSZW5kZXJlciB7Cglwcm90ZWN0ZWQgJF93aWR0aHMgPSBhcnJheSgpOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkd2lkdGhzID0gYXJyYXkoKSkgewoJCSR0aGlzLT5zZXRXaWR0aHMoJHdpZHRocyk7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHdpZHRocyBvZiBlYWNoIGNvbHVtbiBpbiB0aGUgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkd2lkdGhzICAgIFRoZSB3aWR0aHMgb2YgdGhlIGNvbHVtbnMuCgkgKiBAcGFyYW0gYm9vbCAgICRmYWxsYmFjayAgV2hldGhlciB0byB1c2UgdGhlc2UgdmFsdWVzIGFzIGZhbGxiYWNrIG9ubHkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRXaWR0aHMoYXJyYXkgJHdpZHRocywgJGZhbGxiYWNrID0gZmFsc2UpIHsKCQlpZiAoJGZhbGxiYWNrKSB7CgkJCWZvcmVhY2ggKCAkdGhpcy0+X3dpZHRocyBhcyAkaW5kZXggPT4gJHZhbHVlICkgewoJCQkgICAgJHdpZHRoc1skaW5kZXhdID0gJHZhbHVlOwoJCQl9CgkJfQoJCSR0aGlzLT5fd2lkdGhzID0gJHdpZHRoczsKCX0KCgkvKioKCSAqIFJlbmRlciBhIGJvcmRlciBmb3IgdGhlIHRvcCBhbmQgYm90dG9tIGFuZCBzZXBhcmF0aW5nIHRoZSBoZWFkZXJzIGZyb20gdGhlCgkgKiB0YWJsZSByb3dzLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgdGFibGUgYm9yZGVyLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYm9yZGVyKCkgewoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmVuZGVycyBhIHJvdyBmb3Igb3V0cHV0LgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHJvdyAgVGhlIHRhYmxlIHJvdy4KCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgZm9ybWF0dGVkIHRhYmxlIHJvdy4KCSAqLwoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHJvdyhhcnJheSAkcm93KTsKfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpXHRhYmxlOwoKdXNlIGNsaVxDb2xvcnM7CnVzZSBjbGlcU2hlbGw7CgovKioKICogVGhlIEFTQ0lJIHJlbmRlcmVyIHJlbmRlcnMgdGFibGVzIHdpdGggQVNDSUkgYm9yZGVycy4KICovCmNsYXNzIEFzY2lpIGV4dGVuZHMgUmVuZGVyZXIgewoJcHJvdGVjdGVkICRfY2hhcmFjdGVycyA9IGFycmF5KAoJCSdjb3JuZXInICA9PiAnKycsCgkJJ2xpbmUnICAgID0+ICctJywKCQknYm9yZGVyJyAgPT4gJ3wnLAoJCSdwYWRkaW5nJyA9PiAnICcsCgkpOwoJcHJvdGVjdGVkICRfYm9yZGVyID0gbnVsbDsKCXByb3RlY3RlZCAkX2NvbnN0cmFpbnRXaWR0aCA9IG51bGw7Cglwcm90ZWN0ZWQgJF9wcmVfY29sb3JpemVkID0gZmFsc2U7CgoJLyoqCgkgKiBTZXQgdGhlIHdpZHRocyBvZiBlYWNoIGNvbHVtbiBpbiB0aGUgdGFibGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICAkd2lkdGhzICAgIFRoZSB3aWR0aHMgb2YgdGhlIGNvbHVtbnMuCgkgKiBAcGFyYW0gYm9vbCAgICRmYWxsYmFjayAgV2hldGhlciB0byB1c2UgdGhlc2UgdmFsdWVzIGFzIGZhbGxiYWNrIG9ubHkuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRXaWR0aHMoYXJyYXkgJHdpZHRocywgJGZhbGxiYWNrID0gZmFsc2UpIHsKCQlpZiAoJGZhbGxiYWNrKSB7CgkJCWZvcmVhY2ggKCAkdGhpcy0+X3dpZHRocyBhcyAkaW5kZXggPT4gJHZhbHVlICkgewoJCQkgICAgJHdpZHRoc1skaW5kZXhdID0gJHZhbHVlOwoJCQl9CgkJfQoJCSR0aGlzLT5fd2lkdGhzID0gJHdpZHRoczsKCgkJaWYgKCBpc19udWxsKCAkdGhpcy0+X2NvbnN0cmFpbnRXaWR0aCApICkgewoJCQkkdGhpcy0+X2NvbnN0cmFpbnRXaWR0aCA9IChpbnQpIFNoZWxsOjpjb2x1bW5zKCk7CgkJfQoJCSRjb2xfY291bnQgPSBjb3VudCggJHdpZHRocyApOwoJCSRjb2xfYm9yZGVyc19jb3VudCA9ICRjb2xfY291bnQgPyAoICggJGNvbF9jb3VudCAtIDEgKSAqIHN0cmxlbiggJHRoaXMtPl9jaGFyYWN0ZXJzWydib3JkZXInXSApICkgOiAwOwoJCSR0YWJsZV9ib3JkZXJzX2NvdW50ID0gc3RybGVuKCAkdGhpcy0+X2NoYXJhY3RlcnNbJ2JvcmRlciddICkgKiAyOwoJCSRjb2xfcGFkZGluZ19jb3VudCA9ICRjb2xfY291bnQgKiBzdHJsZW4oICR0aGlzLT5fY2hhcmFjdGVyc1sncGFkZGluZyddICkgKiAyOwoJCSRtYXhfd2lkdGggPSAkdGhpcy0+X2NvbnN0cmFpbnRXaWR0aCAtICRjb2xfYm9yZGVyc19jb3VudCAtICR0YWJsZV9ib3JkZXJzX2NvdW50IC0gJGNvbF9wYWRkaW5nX2NvdW50OwoKCQlpZiAoICR3aWR0aHMgJiYgJG1heF93aWR0aCAmJiBhcnJheV9zdW0oICR3aWR0aHMgKSA+ICRtYXhfd2lkdGggKSB7CgoJCQkkYXZnID0gZmxvb3IoICRtYXhfd2lkdGggLyBjb3VudCggJHdpZHRocyApICk7CgkJCSRyZXNpemVfd2lkdGhzID0gYXJyYXkoKTsKCQkJJGV4dHJhX3dpZHRoID0gMDsKCQkJZm9yZWFjaCggJHdpZHRocyBhcyAkd2lkdGggKSB7CgkJCQlpZiAoICR3aWR0aCA+ICRhdmcgKSB7CgkJCQkJJHJlc2l6ZV93aWR0aHNbXSA9ICR3aWR0aDsKCQkJCX0gZWxzZSB7CgkJCQkJJGV4dHJhX3dpZHRoID0gJGV4dHJhX3dpZHRoICsgKCAkYXZnIC0gJHdpZHRoICk7CgkJCQl9CgkJCX0KCgkJCWlmICggISBlbXB0eSggJHJlc2l6ZV93aWR0aHMgKSAmJiAkZXh0cmFfd2lkdGggKSB7CgkJCQkkYXZnX2V4dHJhX3dpZHRoID0gZmxvb3IoICRleHRyYV93aWR0aCAvIGNvdW50KCAkcmVzaXplX3dpZHRocyApICk7CgkJCQlmb3JlYWNoKCAkd2lkdGhzIGFzICYkd2lkdGggKSB7CgkJCQkJaWYgKCBpbl9hcnJheSggJHdpZHRoLCAkcmVzaXplX3dpZHRocyApICkgewoJCQkJCQkkd2lkdGggPSAkYXZnICsgJGF2Z19leHRyYV93aWR0aDsKCQkJCQkJYXJyYXlfc2hpZnQoICRyZXNpemVfd2lkdGhzICk7CgkJCQkJCS8vIExhc3QgaXRlbSBnZXRzIHRoZSBjYWtlCgkJCQkJCWlmICggZW1wdHkoICRyZXNpemVfd2lkdGhzICkgKSB7CgkJCQkJCQkkd2lkdGggPSAwOyAvLyBaZXJvIGl0IHNvIG5vdCBpbiBzdW0uCgkJCQkJCQkkd2lkdGggPSAkbWF4X3dpZHRoIC0gYXJyYXlfc3VtKCAkd2lkdGhzICk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJfQoKCQkkdGhpcy0+X3dpZHRocyA9ICR3aWR0aHM7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIGNvbnN0cmFpbnQgd2lkdGggZm9yIHRoZSB0YWJsZQoJICoKCSAqIEBwYXJhbSBpbnQgJGNvbnN0cmFpbnRXaWR0aAoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0Q29uc3RyYWludFdpZHRoKCAkY29uc3RyYWludFdpZHRoICkgewoJCSR0aGlzLT5fY29uc3RyYWludFdpZHRoID0gJGNvbnN0cmFpbnRXaWR0aDsKCX0KCgkvKioKCSAqIFNldCB0aGUgY2hhcmFjdGVycyB1c2VkIGZvciByZW5kZXJpbmcgdGhlIEFzY2lpIHRhYmxlLgoJICoKCSAqIFRoZSBrZXlzIGBjb3JuZXJgLCBgbGluZWAgYW5kIGBib3JkZXJgIGFyZSB1c2VkIGluIHJlbmRlcmluZy4KCSAqCgkgKiBAcGFyYW0gJGNoYXJhY3RlcnMgIGFycmF5ICBDaGFyYWN0ZXJzIHVzZWQgaW4gcmVuZGVyaW5nLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0Q2hhcmFjdGVycyhhcnJheSAkY2hhcmFjdGVycykgewoJCSR0aGlzLT5fY2hhcmFjdGVycyA9IGFycmF5X21lcmdlKCR0aGlzLT5fY2hhcmFjdGVycywgJGNoYXJhY3RlcnMpOwoJfQoKCS8qKgoJICogUmVuZGVyIGEgYm9yZGVyIGZvciB0aGUgdG9wIGFuZCBib3R0b20gYW5kIHNlcGFyYXRpbmcgdGhlIGhlYWRlcnMgZnJvbSB0aGUKCSAqIHRhYmxlIHJvd3MuCgkgKgoJICogQHJldHVybiBzdHJpbmcgIFRoZSB0YWJsZSBib3JkZXIuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBib3JkZXIoKSB7CgkJaWYgKCFpc3NldCgkdGhpcy0+X2JvcmRlcikpIHsKCQkJJHRoaXMtPl9ib3JkZXIgPSAkdGhpcy0+X2NoYXJhY3RlcnNbJ2Nvcm5lciddOwoJCQlmb3JlYWNoICgkdGhpcy0+X3dpZHRocyBhcyAkd2lkdGgpIHsKCQkJCSR0aGlzLT5fYm9yZGVyIC49IHN0cl9yZXBlYXQoJHRoaXMtPl9jaGFyYWN0ZXJzWydsaW5lJ10sICR3aWR0aCArIDIpOwoJCQkJJHRoaXMtPl9ib3JkZXIgLj0gJHRoaXMtPl9jaGFyYWN0ZXJzWydjb3JuZXInXTsKCQkJfQoJCX0KCgkJcmV0dXJuICR0aGlzLT5fYm9yZGVyOwoJfQoKCS8qKgoJICogUmVuZGVycyBhIHJvdyBmb3Igb3V0cHV0LgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJHJvdyAgVGhlIHRhYmxlIHJvdy4KCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgZm9ybWF0dGVkIHRhYmxlIHJvdy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJvdyggYXJyYXkgJHJvdyApIHsKCgkJJGV4dHJhX3Jvd19jb3VudCA9IDA7CgoJCWlmICggY291bnQoICRyb3cgKSA+IDAgKSB7CgkJCSRleHRyYV9yb3dzID0gYXJyYXlfZmlsbCggMCwgY291bnQoICRyb3cgKSwgYXJyYXkoKSApOwoKCQkJZm9yZWFjaCggJHJvdyBhcyAkY29sID0+ICR2YWx1ZSApIHsKCgkJCQkkdmFsdWUgPSBzdHJfcmVwbGFjZSggYXJyYXkoICJcclxuIiwgIlxuIiApLCAnICcsICR2YWx1ZSApOwoKCQkJCSRjb2xfd2lkdGggPSAkdGhpcy0+X3dpZHRoc1sgJGNvbCBdOwoJCQkJJGVuY29kaW5nID0gZnVuY3Rpb25fZXhpc3RzKCAnbWJfZGV0ZWN0X2VuY29kaW5nJyApID8gbWJfZGV0ZWN0X2VuY29kaW5nKCAkdmFsdWUsIG51bGwsIHRydWUgLypzdHJpY3QqLyApIDogZmFsc2U7CgkJCQkkb3JpZ2luYWxfdmFsX3dpZHRoID0gQ29sb3JzOjp3aWR0aCggJHZhbHVlLCBzZWxmOjppc1ByZUNvbG9yaXplZCggJGNvbCApLCAkZW5jb2RpbmcgKTsKCQkJCWlmICggJGNvbF93aWR0aCAmJiAkb3JpZ2luYWxfdmFsX3dpZHRoID4gJGNvbF93aWR0aCApIHsKCQkJCQkkcm93WyAkY29sIF0gPSBcY2xpXHNhZmVfc3Vic3RyKCAkdmFsdWUsIDAsICRjb2xfd2lkdGgsIHRydWUgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCQkkdmFsdWUgPSBcY2xpXHNhZmVfc3Vic3RyKCAkdmFsdWUsIFxjbGlcc2FmZV9zdHJsZW4oICRyb3dbICRjb2wgXSwgJGVuY29kaW5nICksIG51bGwgLypsZW5ndGgqLywgZmFsc2UgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCQkkaSA9IDA7CgkJCQkJZG8gewoJCQkJCQkkZXh0cmFfdmFsdWUgPSBcY2xpXHNhZmVfc3Vic3RyKCAkdmFsdWUsIDAsICRjb2xfd2lkdGgsIHRydWUgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCQkJJHZhbF93aWR0aCA9IENvbG9yczo6d2lkdGgoICRleHRyYV92YWx1ZSwgc2VsZjo6aXNQcmVDb2xvcml6ZWQoICRjb2wgKSwgJGVuY29kaW5nICk7CgkJCQkJCWlmICggJHZhbF93aWR0aCApIHsKCQkJCQkJCSRleHRyYV9yb3dzWyAkY29sIF1bXSA9ICRleHRyYV92YWx1ZTsKCQkJCQkJCSR2YWx1ZSA9IFxjbGlcc2FmZV9zdWJzdHIoICR2YWx1ZSwgXGNsaVxzYWZlX3N0cmxlbiggJGV4dHJhX3ZhbHVlLCAkZW5jb2RpbmcgKSwgbnVsbCAvKmxlbmd0aCovLCBmYWxzZSAvKmlzX3dpZHRoKi8sICRlbmNvZGluZyApOwoJCQkJCQkJJGkrKzsKCQkJCQkJCWlmICggJGkgPiAkZXh0cmFfcm93X2NvdW50ICkgewoJCQkJCQkJCSRleHRyYV9yb3dfY291bnQgPSAkaTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gd2hpbGUoICR2YWx1ZSApOwoJCQkJfQoKCQkJfQoJCX0KCgkJJHJvdyA9IGFycmF5X21hcChhcnJheSgkdGhpcywgJ3BhZENvbHVtbicpLCAkcm93LCBhcnJheV9rZXlzKCRyb3cpKTsKCQlhcnJheV91bnNoaWZ0KCRyb3csICcnKTsgLy8gRmlyc3QgYm9yZGVyCgkJYXJyYXlfcHVzaCgkcm93LCAnJyk7IC8vIExhc3QgYm9yZGVyCgoJCSRyZXQgPSBqb2luKCR0aGlzLT5fY2hhcmFjdGVyc1snYm9yZGVyJ10sICRyb3cpOwoJCWlmICggJGV4dHJhX3Jvd19jb3VudCApIHsKCQkJZm9yZWFjaCggJGV4dHJhX3Jvd3MgYXMgJGNvbCA9PiAkY29sX3ZhbHVlcyApIHsKCQkJCXdoaWxlKCBjb3VudCggJGNvbF92YWx1ZXMgKSA8ICRleHRyYV9yb3dfY291bnQgKSB7CgkJCQkJJGNvbF92YWx1ZXNbXSA9ICcnOwoJCQkJfQoJCQl9CgoJCQlkbyB7CgkJCQkkcm93X3ZhbHVlcyA9IGFycmF5KCk7CgkJCQkkaGFzX21vcmUgPSBmYWxzZTsKCQkJCWZvcmVhY2goICRleHRyYV9yb3dzIGFzICRjb2wgPT4gJiRjb2xfdmFsdWVzICkgewoJCQkJCSRyb3dfdmFsdWVzWyAkY29sIF0gPSBhcnJheV9zaGlmdCggJGNvbF92YWx1ZXMgKTsKCQkJCQlpZiAoIGNvdW50KCAkY29sX3ZhbHVlcyApICkgewoJCQkJCQkkaGFzX21vcmUgPSB0cnVlOwoJCQkJCX0KCQkJCX0KCgkJCQkkcm93X3ZhbHVlcyA9IGFycmF5X21hcChhcnJheSgkdGhpcywgJ3BhZENvbHVtbicpLCAkcm93X3ZhbHVlcywgYXJyYXlfa2V5cygkcm93X3ZhbHVlcykpOwoJCQkJYXJyYXlfdW5zaGlmdCgkcm93X3ZhbHVlcywgJycpOyAvLyBGaXJzdCBib3JkZXIKCQkJCWFycmF5X3B1c2goJHJvd192YWx1ZXMsICcnKTsgLy8gTGFzdCBib3JkZXIKCgkJCQkkcmV0IC49IFBIUF9FT0wgLiBqb2luKCR0aGlzLT5fY2hhcmFjdGVyc1snYm9yZGVyJ10sICRyb3dfdmFsdWVzKTsKCQkJfSB3aGlsZSggJGhhc19tb3JlICk7CgkJfQoJCXJldHVybiAkcmV0OwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gcGFkQ29sdW1uKCRjb250ZW50LCAkY29sdW1uKSB7CgkJcmV0dXJuICR0aGlzLT5fY2hhcmFjdGVyc1sncGFkZGluZyddIC4gQ29sb3JzOjpwYWQoICRjb250ZW50LCAkdGhpcy0+X3dpZHRoc1sgJGNvbHVtbiBdLCAkdGhpcy0+aXNQcmVDb2xvcml6ZWQoICRjb2x1bW4gKSApIC4gJHRoaXMtPl9jaGFyYWN0ZXJzWydwYWRkaW5nJ107Cgl9CgoJLyoqCgkgKiBTZXQgd2hldGhlciBpdGVtcyBhcmUgcHJlLWNvbG9yaXplZC4KCSAqCgkgKiBAcGFyYW0gYm9vbHxhcnJheSAkY29sb3JpemVkIEEgYm9vbGVhbiB0byBzZXQgYWxsIGNvbHVtbnMgaW4gdGhlIHRhYmxlIGFzIHByZS1jb2xvcml6ZWQsIG9yIGFuIGFycmF5IG9mIGJvb2xlYW5zIGtleWVkIGJ5IGNvbHVtbiBpbmRleCAobnVtYmVyKSB0byBzZXQgaW5kaXZpZHVhbCBjb2x1bW5zIGFzIHByZS1jb2xvcml6ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXRQcmVDb2xvcml6ZWQoICRwcmVfY29sb3JpemVkICkgewoJCSR0aGlzLT5fcHJlX2NvbG9yaXplZCA9ICRwcmVfY29sb3JpemVkOwoJfQoKCS8qKgoJICogSXMgYSBjb2x1bW4gcHJlLWNvbG9yaXplZD8KCSAqCgkgKiBAcGFyYW0gaW50ICRjb2x1bW4gQ29sdW1uIGluZGV4IHRvIGNoZWNrLgoJICogQHJldHVybiBib29sIFRydWUgaWYgd2hvbGUgdGFibGUgaXMgbWFya2VkIGFzIHByZS1jb2xvcml6ZWQsIG9yIGlmIHRoZSBpbmRpdmlkdWFsIGNvbHVtbiBpcyBwcmUtY29sb3JpemVkOyBlbHNlIGZhbHNlLgoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNQcmVDb2xvcml6ZWQoICRjb2x1bW4gKSB7CgkJaWYgKCBpc19ib29sKCAkdGhpcy0+X3ByZV9jb2xvcml6ZWQgKSApIHsKCQkJcmV0dXJuICR0aGlzLT5fcHJlX2NvbG9yaXplZDsKCQl9CgkJaWYgKCBpc19hcnJheSggJHRoaXMtPl9wcmVfY29sb3JpemVkICkgJiYgaXNzZXQoICR0aGlzLT5fcHJlX2NvbG9yaXplZFsgJGNvbHVtbiBdICkgKSB7CgkJCXJldHVybiAkdGhpcy0+X3ByZV9jb2xvcml6ZWRbICRjb2x1bW4gXTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcbm90aWZ5OwoKdXNlIGNsaVxOb3RpZnk7CnVzZSBjbGlcU3RyZWFtczsKCi8qKgogKiBUaGUgYFNwaW5uZXJgIE5vdGlmaWVyIGRpc3BsYXlzIGFuIEFTQ0lJIHNwaW5uZXIuCiAqLwpjbGFzcyBTcGlubmVyIGV4dGVuZHMgTm90aWZ5IHsKCXByb3RlY3RlZCAkX2NoYXJzID0gJy1cfC8nOwoJcHJvdGVjdGVkICRfZm9ybWF0ID0gJ3s6bXNnfSB7OmNoYXJ9ICAoezplbGFwc2VkfSwgezpzcGVlZH0vcyknOwoJcHJvdGVjdGVkICRfaXRlcmF0aW9uID0gMDsKCgkvKioKCSAqIFByaW50cyB0aGUgY3VycmVudCBzcGlubmVyIHBvc2l0aW9uIHRvIGBTVERPVVRgIHdpdGggdGhlIHRpbWUgZWxhcHNlZAoJICogYW5kIHRpY2sgc3BlZWQuCgkgKgoJICogQHBhcmFtIGJvb2xlYW4gICRmaW5pc2ggIGB0cnVlYCBpZiB0aGlzIHdhcyBjYWxsZWQgZnJvbQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIGBjbGlcTm90aWZ5OjpmaW5pc2goKWAsIGBmYWxzZWAgb3RoZXJ3aXNlLgoJICogQHNlZSBjbGlcb3V0X3BhZGRlZCgpCgkgKiBAc2VlIGNsaVxOb3RpZnk6OmZvcm1hdFRpbWUoKQoJICogQHNlZSBjbGlcTm90aWZ5OjpzcGVlZCgpCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkaXNwbGF5KCRmaW5pc2ggPSBmYWxzZSkgewoJCSRtc2cgPSAkdGhpcy0+X21lc3NhZ2U7CgkJJGlkeCA9ICR0aGlzLT5faXRlcmF0aW9uKysgJSBzdHJsZW4oJHRoaXMtPl9jaGFycyk7CgkJJGNoYXIgPSAkdGhpcy0+X2NoYXJzWyRpZHhdOwoJCSRzcGVlZCA9IG51bWJlcl9mb3JtYXQocm91bmQoJHRoaXMtPnNwZWVkKCkpKTsKCQkkZWxhcHNlZCA9ICR0aGlzLT5mb3JtYXRUaW1lKCR0aGlzLT5lbGFwc2VkKCkpOwoKCQlTdHJlYW1zOjpvdXRfcGFkZGVkKCR0aGlzLT5fZm9ybWF0LCBjb21wYWN0KCdtc2cnLCAnY2hhcicsICdlbGFwc2VkJywgJ3NwZWVkJykpOwoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGlcbm90aWZ5OwoKdXNlIGNsaVxOb3RpZnk7CnVzZSBjbGlcU3RyZWFtczsKCi8qKgogKiBBIE5vdGlmZXIgdGhhdCBkaXNwbGF5cyBhIHN0cmluZyBvZiBwZXJpb2RzLgogKi8KY2xhc3MgRG90cyBleHRlbmRzIE5vdGlmeSB7Cglwcm90ZWN0ZWQgJF9kb3RzOwoJcHJvdGVjdGVkICRfZm9ybWF0ID0gJ3s6bXNnfXs6ZG90c30gICh7OmVsYXBzZWR9LCB7OnNwZWVkfS9zKSc7Cglwcm90ZWN0ZWQgJF9pdGVyYXRpb247CgoJLyoqCgkgKiBJbnN0YXRpYXRlcyBhIE5vdGlmaWNhdGlvbiBvYmplY3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJG1zZyAgICAgICBUaGUgdGV4dCB0byBkaXNwbGF5IG5leHQgdG8gdGhlIE5vdGlmaWVyLgoJICogQHBhcmFtIGludCAgICAgJGRvdHMgICAgICBUaGUgbnVtYmVyIG9mIGRvdHMgdG8gaXRlcmF0ZSB0aHJvdWdoLgoJICogQHBhcmFtIGludCAgICAgJGludGVydmFsICBUaGUgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gdXBkYXRlcy4KCSAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1zZywgJGRvdHMgPSAzLCAkaW50ZXJ2YWwgPSAxMDApIHsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCRtc2csICRpbnRlcnZhbCk7CgkJJHRoaXMtPl9kb3RzID0gKGludCkkZG90czsKCgkJaWYgKCR0aGlzLT5fZG90cyA8PSAwKSB7CgkJCXRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdEb3QgY291bnQgb3V0IG9mIHJhbmdlLCBtdXN0IGJlIHBvc2l0aXZlLicpOwoJCX0KCX0KCgkvKioKCSAqIFByaW50cyB0aGUgY29ycmVjdCBudW1iZXIgb2YgZG90cyB0byBgU1RET1VUYCB3aXRoIHRoZSB0aW1lIGVsYXBzZWQgYW5kCgkgKiB0aWNrIHNwZWVkLgoJICoKCSAqIEBwYXJhbSBib29sZWFuICAkZmluaXNoICBgdHJ1ZWAgaWYgdGhpcyB3YXMgY2FsbGVkIGZyb20KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY2xpXE5vdGlmeTo6ZmluaXNoKClgLCBgZmFsc2VgIG90aGVyd2lzZS4KCSAqIEBzZWUgY2xpXG91dF9wYWRkZWQoKQoJICogQHNlZSBjbGlcTm90aWZ5Ojpmb3JtYXRUaW1lKCkKCSAqIEBzZWUgY2xpXE5vdGlmeTo6c3BlZWQoKQoJICovCglwdWJsaWMgZnVuY3Rpb24gZGlzcGxheSgkZmluaXNoID0gZmFsc2UpIHsKCQkkcmVwZWF0ID0gJHRoaXMtPl9kb3RzOwoJCWlmICghJGZpbmlzaCkgewoJCQkkcmVwZWF0ID0gJHRoaXMtPl9pdGVyYXRpb24rKyAlICRyZXBlYXQ7CgkJfQoKCQkkbXNnID0gJHRoaXMtPl9tZXNzYWdlOwoJCSRkb3RzID0gc3RyX3BhZChzdHJfcmVwZWF0KCcuJywgJHJlcGVhdCksICR0aGlzLT5fZG90cyk7CgkJJHNwZWVkID0gbnVtYmVyX2Zvcm1hdChyb3VuZCgkdGhpcy0+c3BlZWQoKSkpOwoJCSRlbGFwc2VkID0gJHRoaXMtPmZvcm1hdFRpbWUoJHRoaXMtPmVsYXBzZWQoKSk7CgoJCVN0cmVhbXM6Om91dF9wYWRkZWQoJHRoaXMtPl9mb3JtYXQsIGNvbXBhY3QoJ21zZycsICdkb3RzJywgJ3NwZWVkJywgJ2VsYXBzZWQnKSk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBjbGk7CgpjbGFzcyBTdHJlYW1zIHsKCglwcm90ZWN0ZWQgc3RhdGljICRvdXQgPSBTVERPVVQ7Cglwcm90ZWN0ZWQgc3RhdGljICRpbiA9IFNURElOOwoJcHJvdGVjdGVkIHN0YXRpYyAkZXJyID0gU1RERVJSOwoKCXN0YXRpYyBmdW5jdGlvbiBfY2FsbCggJGZ1bmMsICRhcmdzICkgewoJCSRtZXRob2QgPSBfX0NMQVNTX18gLiAnOjonIC4gJGZ1bmM7CgkJcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCAkbWV0aG9kLCAkYXJncyApOwoJfQoKCXN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gaXNUdHkoKSB7CgkJcmV0dXJuIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2lzYXR0eScpICYmIHBvc2l4X2lzYXR0eShzdGF0aWM6OiRvdXQpKTsKCX0KCgkvKioKCSAqIEhhbmRsZXMgcmVuZGVyaW5nIHN0cmluZ3MuIElmIGV4dHJhIHNjYWxhciBhcmd1bWVudHMgYXJlIGdpdmVuIGFmdGVyIHRoZSBgJG1zZ2AKCSAqIHRoZSBzdHJpbmcgd2lsbCBiZSByZW5kZXJlZCB3aXRoIGBzcHJpbnRmYC4gSWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyBhbiBgYXJyYXlgCgkgKiB0aGVuIGVhY2gga2V5IGluIHRoZSBhcnJheSB3aWxsIGJlIHRoZSBwbGFjZWhvbGRlciBuYW1lLiBQbGFjZWhvbGRlcnMgYXJlIG9mIHRoZQoJICogZm9ybWF0IHs6a2V5fS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gcmVuZGVyLgoJICogQHBhcmFtIG1peGVkICAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgoJICogQHJldHVybiBzdHJpbmcgIFRoZSByZW5kZXJlZCBzdHJpbmcuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVuZGVyKCAkbXNnICkgewoJCSRhcmdzID0gZnVuY19nZXRfYXJncygpOwoKCQkvLyBObyBzdHJpbmcgcmVwbGFjZW1lbnQgaXMgbmVlZGVkCgkJaWYoIGNvdW50KCAkYXJncyApID09IDEgfHwgKCBpc19zdHJpbmcoICRhcmdzWzFdICkgJiYgJycgPT09ICRhcmdzWzFdICkgKSB7CgkJCXJldHVybiBDb2xvcnM6OnNob3VsZENvbG9yaXplKCkgPyBDb2xvcnM6OmNvbG9yaXplKCAkbXNnICkgOiAkbXNnOwoJCX0KCgkJLy8gSWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIG5vdCBhbiBhcnJheSBqdXN0IHBhc3MgdG8gc3ByaW50ZgoJCWlmKCAhaXNfYXJyYXkoICRhcmdzWzFdICkgKSB7CgkJCS8vIENvbG9yaXplIHRoZSBtZXNzYWdlIGZpcnN0IHNvIHNwcmludGYgZG9lc24ndCBiaXRjaCBhdCB1cwoJCQlpZiAoIENvbG9yczo6c2hvdWxkQ29sb3JpemUoKSApIHsKCQkJCSRhcmdzWzBdID0gQ29sb3JzOjpjb2xvcml6ZSggJGFyZ3NbMF0gKTsKCQkJfQoKCQkJLy8gRXNjYXBlIHBlcmNlbnQgY2hhcmFjdGVycyBmb3Igc3ByaW50ZgoJCQkkYXJnc1swXSA9IHByZWdfcmVwbGFjZSgnLyglKFteXHddfCQpKS8nLCAiJSQxIiwgJGFyZ3NbMF0pOwoKCQkJcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCAnc3ByaW50ZicsICRhcmdzICk7CgkJfQoKCQkvLyBIZXJlIHdlIGRvIG5hbWVkIHJlcGxhY2VtZW50IHNvIGZvcm1hdHRpbmcgc3RyaW5ncyBhcmUgbW9yZSB1bmRlcnN0YW5kYWJsZQoJCWZvcmVhY2goICRhcmdzWzFdIGFzICRrZXkgPT4gJHZhbHVlICkgewoJCQkkbXNnID0gc3RyX3JlcGxhY2UoICd7OicgLiAka2V5IC4gJ30nLCAkdmFsdWUsICRtc2cgKTsKCQl9CgkJcmV0dXJuIENvbG9yczo6c2hvdWxkQ29sb3JpemUoKSA/IENvbG9yczo6Y29sb3JpemUoICRtc2cgKSA6ICRtc2c7Cgl9CgoJLyoqCgkgKiBTaG9ydGN1dCBmb3IgcHJpbnRpbmcgdG8gYFNURE9VVGAuIFRoZSBtZXNzYWdlIGFuZCBwYXJhbWV0ZXJzIGFyZSBwYXNzZWQKCSAqIHRocm91Z2ggYHNwcmludGZgIGJlZm9yZSBvdXRwdXQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gb3V0cHV0IGluIGBwcmludGZgIGZvcm1hdC4KCSAqIEBwYXJhbSBtaXhlZCAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgoJICogQHJldHVybiB2b2lkCgkgKiBAc2VlIFxjbGlccmVuZGVyKCkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBvdXQoICRtc2cgKSB7CgkJZndyaXRlKCBzdGF0aWM6OiRvdXQsIHNlbGY6Ol9jYWxsKCAncmVuZGVyJywgZnVuY19nZXRfYXJncygpICkgKTsKCX0KCgkvKioKCSAqIFBhZHMgYCRtc2dgIHRvIHRoZSB3aWR0aCBvZiB0aGUgc2hlbGwgYmVmb3JlIHBhc3NpbmcgdG8gYGNsaVxvdXRgLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRtc2cgIFRoZSBtZXNzYWdlIHRvIHBhZCBhbmQgcGFzcyBvbi4KCSAqIEBwYXJhbSBtaXhlZCAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgoJICogQHJldHVybiB2b2lkCgkgKiBAc2VlIGNsaVxvdXQoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG91dF9wYWRkZWQoICRtc2cgKSB7CgkJJG1zZyA9IHNlbGY6Ol9jYWxsKCAncmVuZGVyJywgZnVuY19nZXRfYXJncygpICk7CgkJc2VsZjo6b3V0KCBzdHJfcGFkKCAkbXNnLCBcY2xpXFNoZWxsOjpjb2x1bW5zKCkgKSApOwoJfQoKCS8qKgoJICogUHJpbnRzIGEgbWVzc2FnZSB0byBgU1RET1VUYCB3aXRoIGEgbmV3bGluZSBhcHBlbmRlZC4gU2VlIGBcY2xpXG91dGAgZm9yCgkgKiBtb3JlIGRvY3VtZW50YXRpb24uCgkgKgoJICogQHNlZSBjbGlcb3V0KCkKCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsaW5lKCAkbXNnID0gJycgKSB7CgkJLy8gZnVuY19nZXRfYXJncyBpcyBlbXB0eSBpZiBubyBhcmdzIGFyZSBwYXNzZWQgZXZlbiB3aXRoIHRoZSBkZWZhdWx0IGFib3ZlLgoJCSRhcmdzID0gYXJyYXlfbWVyZ2UoIGZ1bmNfZ2V0X2FyZ3MoKSwgYXJyYXkoICcnICkgKTsKCQkkYXJnc1swXSAuPSAiXG4iOwoKCQlzZWxmOjpfY2FsbCggJ291dCcsICRhcmdzICk7Cgl9CgoJLyoqCgkgKiBTaG9ydGN1dCBmb3IgcHJpbnRpbmcgdG8gYFNUREVSUmAuIFRoZSBtZXNzYWdlIGFuZCBwYXJhbWV0ZXJzIGFyZSBwYXNzZWQKCSAqIHRocm91Z2ggYHNwcmludGZgIGJlZm9yZSBvdXRwdXQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJG1zZyAgVGhlIG1lc3NhZ2UgdG8gb3V0cHV0IGluIGBwcmludGZgIGZvcm1hdC4gV2l0aCBubyBzdHJpbmcsCgkgKiAgICAgICAgICAgICAgICAgICAgICBhIG5ld2xpbmUgaXMgcHJpbnRlZC4KCSAqIEBwYXJhbSBtaXhlZCAgIC4uLiAgIEVpdGhlciBzY2FsYXIgYXJndW1lbnRzIG9yIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LgoJICogQHJldHVybiB2b2lkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXJyKCAkbXNnID0gJycgKSB7CgkJLy8gZnVuY19nZXRfYXJncyBpcyBlbXB0eSBpZiBubyBhcmdzIGFyZSBwYXNzZWQgZXZlbiB3aXRoIHRoZSBkZWZhdWx0IGFib3ZlLgoJCSRhcmdzID0gYXJyYXlfbWVyZ2UoIGZ1bmNfZ2V0X2FyZ3MoKSwgYXJyYXkoICcnICkgKTsKCQkkYXJnc1swXSAuPSAiXG4iOwoJCWZ3cml0ZSggc3RhdGljOjokZXJyLCBzZWxmOjpfY2FsbCggJ3JlbmRlcicsICRhcmdzICkgKTsKCX0KCgkvKioKCSAqIFRha2VzIGlucHV0IGZyb20gYFNURElOYCBpbiB0aGUgZ2l2ZW4gZm9ybWF0LiBJZiBhbiBlbmQgb2YgdHJhbnNtaXNzaW9uCgkgKiBjaGFyYWN0ZXIgaXMgc2VudCAoXkQpLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgICRmb3JtYXQgIEEgdmFsaWQgaW5wdXQgZm9ybWF0LiBTZWUgYGZzY2FuZmAgZm9yIGRvY3VtZW50YXRpb24uCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICBJZiBub25lIGlzIGdpdmVuLCBhbGwgaW5wdXQgdXAgdG8gdGhlIGZpcnN0IG5ld2xpbmUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGFjY2VwdGVkLgoJICogQHBhcmFtIGJvb2xlYW4gJGhpZGUgICAgSWYgdHJ1ZSB3aWxsIGhpZGUgd2hhdCB0aGUgdXNlciB0eXBlcyBpbi4KCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgaW5wdXQgd2l0aCB3aGl0ZXNwYWNlIHRyaW1tZWQuCgkgKiBAdGhyb3dzIFxFeGNlcHRpb24gIFRocm93biBpZiBjdHJsLUQgKEVPVCkgaXMgc2VudCBhcyBpbnB1dC4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpbnB1dCggJGZvcm1hdCA9IG51bGwsICRoaWRlID0gZmFsc2UgKSB7CgkJaWYgKCAkaGlkZSApCgkJCVNoZWxsOjpoaWRlKCk7CgoJCWlmKCAkZm9ybWF0ICkgewoJCQlmc2NhbmYoIHN0YXRpYzo6JGluLCAkZm9ybWF0IC4gIlxuIiwgJGxpbmUgKTsKCQl9IGVsc2UgewoJCQkkbGluZSA9IGZnZXRzKCBzdGF0aWM6OiRpbiApOwoJCX0KCgkJaWYgKCAkaGlkZSApIHsKCQkJU2hlbGw6OmhpZGUoIGZhbHNlICk7CgkJCWVjaG8gIlxuIjsKCQl9CgoJCWlmKCAkbGluZSA9PT0gZmFsc2UgKSB7CgkJCXRocm93IG5ldyBcRXhjZXB0aW9uKCAnQ2F1Z2h0IF5EIGR1cmluZyBpbnB1dCcgKTsKCQl9CgoJCXJldHVybiB0cmltKCAkbGluZSApOwoJfQoKCS8qKgoJICogRGlzcGxheXMgYW4gaW5wdXQgcHJvbXB0LiBJZiBubyBkZWZhdWx0IHZhbHVlIGlzIHByb3ZpZGVkIHRoZSBwcm9tcHQgd2lsbAoJICogY29udGludWUgZGlzcGxheWluZyB1bnRpbCBpbnB1dCBpcyByZWNlaXZlZC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgJHF1ZXN0aW9uIFRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXIuCgkgKiBAcGFyYW0gYm9vbHxzdHJpbmcgJGRlZmF1bHQgIEEgZGVmYXVsdCB2YWx1ZSBpZiB0aGUgdXNlciBwcm92aWRlcyBubyBpbnB1dC4KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAkbWFya2VyICAgQSBzdHJpbmcgdG8gYXBwZW5kIHRvIHRoZSBxdWVzdGlvbiBhbmQgZGVmYXVsdCB2YWx1ZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbiBkaXNwbGF5LgoJICogQHBhcmFtIGJvb2xlYW4gICAgICRoaWRlICAgICBPcHRpb25hbGx5IGhpZGVzIHdoYXQgdGhlIHVzZXIgdHlwZXMgaW4uCgkgKiBAcmV0dXJuIHN0cmluZyAgVGhlIHVzZXJzIGlucHV0LgoJICogQHNlZSBjbGlcaW5wdXQoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb21wdCggJHF1ZXN0aW9uLCAkZGVmYXVsdCA9IG51bGwsICRtYXJrZXIgPSAnOiAnLCAkaGlkZSA9IGZhbHNlICkgewoJCWlmKCAkZGVmYXVsdCAmJiBzdHJwb3MoICRxdWVzdGlvbiwgJ1snICkgPT09IGZhbHNlICkgewoJCQkkcXVlc3Rpb24gLj0gJyBbJyAuICRkZWZhdWx0IC4gJ10nOwoJCX0KCgkJd2hpbGUoIHRydWUgKSB7CgkJCXNlbGY6Om91dCggJHF1ZXN0aW9uIC4gJG1hcmtlciApOwoJCQkkbGluZSA9IHNlbGY6OmlucHV0KCBudWxsLCAkaGlkZSApOwoKCQkJaWYgKCB0cmltKCAkbGluZSApICE9PSAnJyApCgkJCQlyZXR1cm4gJGxpbmU7CgkJCWlmKCAkZGVmYXVsdCAhPT0gZmFsc2UgKQoJCQkJcmV0dXJuICRkZWZhdWx0OwoJCX0KCX0KCgkvKioKCSAqIFByZXNlbnRzIGEgdXNlciB3aXRoIGEgbXVsdGlwbGUgY2hvaWNlIHF1ZXN0aW9uLCB1c2VmdWwgZm9yICd5ZXMvbm8nIHR5cGUKCSAqIHF1ZXN0aW9ucyAod2hpY2ggdGhpcyBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGRlZmF1bHRzIHRvbykuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgJHF1ZXN0aW9uICBUaGUgcXVlc3Rpb24gdG8gYXNrIHRoZSB1c2VyLgoJICogQHBhcmFtIHN0cmluZyAgJGNob2ljZSAgICBBIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGFsbG93ZWQgYXMgYSByZXNwb25zZS4gQ2FzZSBpcyBpZ25vcmVkLgoJICogQHBhcmFtIHN0cmluZyAgJGRlZmF1bHQgICBUaGUgZGVmYXVsdCBjaG9pY2UuIE5VTEwgaWYgYSBkZWZhdWx0IGlzIG5vdCBhbGxvd2VkLgoJICogQHJldHVybiBzdHJpbmcgIFRoZSB1c2VycyBjaG9pY2UuCgkgKiBAc2VlIGNsaVxwcm9tcHQoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNob29zZSggJHF1ZXN0aW9uLCAkY2hvaWNlID0gJ3luJywgJGRlZmF1bHQgPSAnbicgKSB7CgkJaWYoICFpc19zdHJpbmcoICRjaG9pY2UgKSApIHsKCQkJJGNob2ljZSA9IGpvaW4oICcnLCAkY2hvaWNlICk7CgkJfQoKCQkvLyBNYWtlIGV2ZXJ5IGNob2ljZSBjaGFyYWN0ZXIgbG93ZXJjYXNlIGV4Y2VwdCB0aGUgZGVmYXVsdAoJCSRjaG9pY2UgPSBzdHJfaXJlcGxhY2UoICRkZWZhdWx0LCBzdHJ0b3VwcGVyKCAkZGVmYXVsdCApLCBzdHJ0b2xvd2VyKCAkY2hvaWNlICkgKTsKCQkvLyBTZXBlcmF0ZSBlYWNoIGNob2ljZSB3aXRoIGEgZm9yd2FyZC1zbGFzaAoJCSRjaG9pY2VzID0gdHJpbSggam9pbiggJy8nLCBwcmVnX3NwbGl0KCAnLy8nLCAkY2hvaWNlICkgKSwgJy8nICk7CgoJCXdoaWxlKCB0cnVlICkgewoJCQkkbGluZSA9IHNlbGY6OnByb21wdCggc3ByaW50ZiggJyVzPyBbJXNdJywgJHF1ZXN0aW9uLCAkY2hvaWNlcyApLCAkZGVmYXVsdCwgJycgKTsKCgkJCWlmKCBzdHJpcG9zKCAkY2hvaWNlLCAkbGluZSApICE9PSBmYWxzZSApIHsKCQkJCXJldHVybiBzdHJ0b2xvd2VyKCAkbGluZSApOwoJCQl9CgkJCWlmKCAhZW1wdHkoICRkZWZhdWx0ICkgKSB7CgkJCQlyZXR1cm4gc3RydG9sb3dlciggJGRlZmF1bHQgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIERpc3BsYXlzIGFuIGFycmF5IG9mIHN0cmluZ3MgYXMgYSBtZW51IHdoZXJlIGEgdXNlciBjYW4gZW50ZXIgYSBudW1iZXIgdG8KCSAqIGNob29zZSBhbiBvcHRpb24uIFRoZSBhcnJheSBtdXN0IGJlIGEgc2luZ2xlIGRpbWVuc2lvbiB3aXRoIGVpdGhlciBzdHJpbmdzCgkgKiBvciBvYmplY3RzIHdpdGggYSBgX190b1N0cmluZygpYCBtZXRob2QuCgkgKgoJICogQHBhcmFtIGFycmF5ICAgJGl0ZW1zICAgIFRoZSBsaXN0IG9mIGl0ZW1zIHRoZSB1c2VyIGNhbiBjaG9vc2UgZnJvbS4KCSAqIEBwYXJhbSBzdHJpbmcgICRkZWZhdWx0ICBUaGUgaW5kZXggb2YgdGhlIGRlZmF1bHQgaXRlbS4KCSAqIEBwYXJhbSBzdHJpbmcgICR0aXRsZSAgICBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIgd2hlbiBwcm9tcHRlZC4KCSAqIEByZXR1cm4gc3RyaW5nICBUaGUgaW5kZXggb2YgdGhlIGNob3NlbiBpdGVtLgoJICogQHNlZSBjbGlcbGluZSgpCgkgKiBAc2VlIGNsaVxpbnB1dCgpCgkgKiBAc2VlIGNsaVxlcnIoKQoJICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lbnUoICRpdGVtcywgJGRlZmF1bHQgPSBudWxsLCAkdGl0bGUgPSAnQ2hvb3NlIGFuIGl0ZW0nICkgewoJCSRtYXAgPSBhcnJheV92YWx1ZXMoICRpdGVtcyApOwoKCQlpZiggJGRlZmF1bHQgJiYgc3RycG9zKCAkdGl0bGUsICdbJyApID09PSBmYWxzZSAmJiBpc3NldCggJGl0ZW1zWyRkZWZhdWx0XSApICkgewoJCQkkdGl0bGUgLj0gJyBbJyAuICRpdGVtc1skZGVmYXVsdF0gLiAnXSc7CgkJfQoKCQlmb3JlYWNoKCAkbWFwIGFzICRpZHggPT4gJGl0ZW0gKSB7CgkJCXNlbGY6OmxpbmUoICcgICVkLiAlcycsICRpZHggKyAxLCAoc3RyaW5nKSRpdGVtICk7CgkJfQoJCXNlbGY6OmxpbmUoKTsKCgkJd2hpbGUoIHRydWUgKSB7CgkJCWZ3cml0ZSggc3RhdGljOjokb3V0LCBzcHJpbnRmKCAnJXM6ICcsICR0aXRsZSApICk7CgkJCSRsaW5lID0gc2VsZjo6aW5wdXQoKTsKCgkJCWlmKCBpc19udW1lcmljKCAkbGluZSApICkgewoJCQkJJGxpbmUtLTsKCQkJCWlmKCBpc3NldCggJG1hcFskbGluZV0gKSApIHsKCQkJCQlyZXR1cm4gYXJyYXlfc2VhcmNoKCAkbWFwWyRsaW5lXSwgJGl0ZW1zICk7CgkJCQl9CgoJCQkJaWYoICRsaW5lIDwgMCB8fCAkbGluZSA+PSBjb3VudCggJG1hcCApICkgewoJCQkJCXNlbGY6OmVyciggJ0ludmFsaWQgbWVudSBzZWxlY3Rpb246IG91dCBvZiByYW5nZScgKTsKCQkJCX0KCQkJfSBlbHNlIGlmKCBpc3NldCggJGRlZmF1bHQgKSApIHsKCQkJCXJldHVybiAkZGVmYXVsdDsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFNldHMgb25lIG9mIHRoZSBzdHJlYW1zIChpbnB1dCwgb3V0cHV0LCBvciBlcnJvcikgdG8gYSBgc3RyZWFtYCB0eXBlIHJlc291cmNlLgoJICoKCSAqIFZhbGlkICR3aGljaFN0cmVhbSB2YWx1ZXMgYXJlOgoJICogICAgLSAnaW4nICAgKGRlZmF1bHQ6IFNURElOKQoJICogICAgLSAnb3V0JyAgKGRlZmF1bHQ6IFNURE9VVCkKCSAqICAgIC0gJ2VycicgIChkZWZhdWx0OiBTVERFUlIpCgkgKgoJICogQW55IGN1c3RvbSBzdHJlYW1zIHdpbGwgYmUgY2xvc2VkIGZvciB5b3Ugb24gc2h1dGRvd24sIHNvIHBsZWFzZSBkb24ndCBjbG9zZSBzdHJlYW0KCSAqIHJlc291cmNlcyB1c2VkIHdpdGggdGhpcyBtZXRob2QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAgICAkd2hpY2hTdHJlYW0gIFRoZSBzdHJlYW0gcHJvcGVydHkgdG8gdXBkYXRlCgkgKiBAcGFyYW0gcmVzb3VyY2UgICRzdHJlYW0gICAgICAgVGhlIG5ldyBzdHJlYW0gcmVzb3VyY2UgdG8gdXNlCgkgKiBAcmV0dXJuIHZvaWQKCSAqIEB0aHJvd3MgXEV4Y2VwdGlvbiBUaHJvd24gaWYgJHN0cmVhbSBpcyBub3QgYSByZXNvdXJjZSBvZiB0aGUgJ3N0cmVhbScgdHlwZS4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRTdHJlYW0oICR3aGljaFN0cmVhbSwgJHN0cmVhbSApIHsKCQlpZiggIWlzX3Jlc291cmNlKCAkc3RyZWFtICkgfHwgZ2V0X3Jlc291cmNlX3R5cGUoICRzdHJlYW0gKSAhPT0gJ3N0cmVhbScgKSB7CgkJCXRocm93IG5ldyBcRXhjZXB0aW9uKCAnSW52YWxpZCByZXNvdXJjZSB0eXBlIScgKTsKCQl9CgkJaWYoIHByb3BlcnR5X2V4aXN0cyggX19DTEFTU19fLCAkd2hpY2hTdHJlYW0gKSApIHsKCQkJc3RhdGljOjokeyR3aGljaFN0cmVhbX0gPSAkc3RyZWFtOwoJCX0KCQlyZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbiggZnVuY3Rpb24oKSB1c2UgKCRzdHJlYW0pIHsKCQkJZmNsb3NlKCAkc3RyZWFtICk7CgkJfSApOwoJfQoKfQo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKLyoqCiAqIFRoZSBgU2hlbGxgIGNsYXNzIGlzIGEgdXRpbGl0eSBjbGFzcyBmb3Igc2hlbGwgcmVsYXRlZCB0YXNrcyBzdWNoIGFzCiAqIGluZm9ybWF0aW9uIG9uIHdpZHRoLgogKi8KY2xhc3MgU2hlbGwgewoKCS8qKgoJICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgdGhlIGN1cnJlbnQgc2hlbGwgaGFzIGZvciBkaXNwbGF5LgoJICoKCSAqIEByZXR1cm4gaW50ICBUaGUgbnVtYmVyIG9mIGNvbHVtbnMuCgkgKiBAdG9kbyBUZXN0IG9uIG1vcmUgc3lzdGVtcy4KCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBjb2x1bW5zKCkgewoJCXN0YXRpYyAkY29sdW1uczsKCgkJaWYgKCBnZXRlbnYoICdQSFBfQ0xJX1RPT0xTX1RFU1RfU0hFTExfQ09MVU1OU19SRVNFVCcgKSApIHsKCQkJJGNvbHVtbnMgPSBudWxsOwoJCX0KCQlpZiAoIG51bGwgPT09ICRjb2x1bW5zICkgewoJCQlpZiAoIGZ1bmN0aW9uX2V4aXN0cyggJ2V4ZWMnICkgKSB7CgkJCQlpZiAoIHNlbGY6OmlzX3dpbmRvd3MoKSApIHsKCQkJCQkvLyBDYXRlciBmb3Igc2hlbGxzIHN1Y2ggYXMgQ3lnd2luIGFuZCBHaXQgYmFzaCB3aGVyZSBgbW9kZSBDT05gIHJldHVybnMgYW4gaW5jb3JyZWN0IHZhbHVlIGZvciBjb2x1bW5zLgoJCQkJCWlmICggKCAkc2hlbGwgPSBnZXRlbnYoICdTSEVMTCcgKSApICYmIHByZWdfbWF0Y2goICcvKD86YmFzaHx6c2gpKD86XC5leGUpPyQvJywgJHNoZWxsICkgJiYgZ2V0ZW52KCAnVEVSTScgKSApIHsKCQkJCQkJJGNvbHVtbnMgPSAoaW50KSBleGVjKCAndHB1dCBjb2xzJyApOwoJCQkJCX0KCQkJCQlpZiAoICEgJGNvbHVtbnMgKSB7CgkJCQkJCSRyZXR1cm5fdmFyID0gLTE7CgkJCQkJCSRvdXRwdXQgPSBhcnJheSgpOwoJCQkJCQlleGVjKCAnbW9kZSBDT04nLCAkb3V0cHV0LCAkcmV0dXJuX3ZhciApOwoJCQkJCQlpZiAoIDAgPT09ICRyZXR1cm5fdmFyICYmICRvdXRwdXQgKSB7CgkJCQkJCQkvLyBMb29rIGZvciBzZWNvbmQgbGluZSBlbmRpbmcgaW4gIjogPG51bWJlcj4iIChzZWFyY2hpbmcgZm9yICJDb2x1bW5zOiIgd2lsbCBmYWlsIG9uIG5vbi1FbmdsaXNoIGxvY2FsZXMpLgoJCQkJCQkJaWYgKCBwcmVnX21hdGNoKCAnLzpccypbMC05XStcblteOl0rOlxzKihbMC05XSspXG4vJywgaW1wbG9kZSggIlxuIiwgJG91dHB1dCApLCAkbWF0Y2hlcyApICkgewoJCQkJCQkJCSRjb2x1bW5zID0gKGludCkgJG1hdGNoZXNbMV07CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCWlmICggISAoICRjb2x1bW5zID0gKGludCkgZ2V0ZW52KCAnQ09MVU1OUycgKSApICkgewoJCQkJCQkkc2l6ZSA9IGV4ZWMoICcvdXNyL2Jpbi9lbnYgc3R0eSBzaXplIDI+L2Rldi9udWxsJyApOwoJCQkJCQlpZiAoICcnICE9PSAkc2l6ZSAmJiBwcmVnX21hdGNoKCAnL1swLTldKyAoWzAtOV0rKS8nLCAkc2l6ZSwgJG1hdGNoZXMgKSApIHsKCQkJCQkJCSRjb2x1bW5zID0gKGludCkgJG1hdGNoZXNbMV07CgkJCQkJCX0KCQkJCQkJaWYgKCAhICRjb2x1bW5zICkgewoJCQkJCQkJaWYgKCBnZXRlbnYoICdURVJNJyApICkgewoJCQkJCQkJCSRjb2x1bW5zID0gKGludCkgZXhlYyggJy91c3IvYmluL2VudiB0cHV0IGNvbHMgMj4vZGV2L251bGwnICk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWlmICggISAkY29sdW1ucyApIHsKCQkJCSRjb2x1bW5zID0gODA7IC8vIGRlZmF1bHQgd2lkdGggb2YgY21kIHdpbmRvdyBvbiBXaW5kb3dzIE9TCgkJCX0KCQl9CgoJCXJldHVybiAkY29sdW1uczsKCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBvdXRwdXQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGlzIGEgVFRZIG9yIGEgcGlwZSAvIHJlZGlyZWN0CgkgKgoJICogUmV0dXJucyB0cnVlIGlmIFNURE9VVCBvdXRwdXQgaXMgYmVpbmcgcmVkaXJlY3RlZCB0byBhIHBpcGUgb3IgYSBmaWxlOyBmYWxzZSBpcwoJICogb3V0cHV0IGlzIGJlaW5nIHNlbnQgZGlyZWN0bHkgdG8gdGhlIHRlcm1pbmFsLgoJICoKCSAqIElmIGFuIGVudiB2YXJpYWJsZSBTSEVMTF9QSVBFIGV4aXN0cywgcmV0dXJuZWQgcmVzdWx0IGRlcGVuZHMgaXQncwoJICogdmFsdWUuIFN0cmluZ3MgbGlrZSAxLCAwLCB5ZXMsIG5vLCB0aGF0IHZhbGlkYXRlIHRvIGJvb2xlYW5zIGFyZSBhY2NlcHRlZC4KCSAqCgkgKiBUbyBlbmFibGUgQVNDSUkgZm9ybWF0dGluZyBldmVuIHdoZW4gc2hlbGwgaXMgcGlwZWQsIHVzZSB0aGUKCSAqIEVOViB2YXJpYWJsZSBTSEVMTF9QSVBFPTAKCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBpc1BpcGVkKCkgewoJCSRzaGVsbFBpcGUgPSBnZXRlbnYoJ1NIRUxMX1BJUEUnKTsKCgkJaWYgKCRzaGVsbFBpcGUgIT09IGZhbHNlKSB7CgkJCXJldHVybiBmaWx0ZXJfdmFyKCRzaGVsbFBpcGUsIEZJTFRFUl9WQUxJREFURV9CT09MRUFOKTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gKGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfaXNhdHR5JykgJiYgIXBvc2l4X2lzYXR0eShTVERPVVQpKTsKCQl9Cgl9CgoJLyoqCgkgKiBVc2VzIGBzdHR5YCB0byBoaWRlIGlucHV0L291dHB1dCBjb21wbGV0ZWx5LgoJICogQHBhcmFtIGJvb2xlYW4gJGhpZGRlbiBXaWxsIGhpZGUvc2hvdyB0aGUgbmV4dCBkYXRhLiBEZWZhdWx0cyB0byB0cnVlLgoJICovCglzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGhpZGUoJGhpZGRlbiA9IHRydWUpIHsKCQlzeXN0ZW0oICdzdHR5ICcgLiAoICRoaWRkZW4/ICctZWNobycgOiAnZWNobycgKSApOwoJfQoKCS8qKgoJICogSXMgdGhpcyBzaGVsbCBpbiBXaW5kb3dzPwoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglzdGF0aWMgcHJpdmF0ZSBmdW5jdGlvbiBpc193aW5kb3dzKCkgewoJCXJldHVybiBzdHJ0b3VwcGVyKHN1YnN0cihQSFBfT1MsIDAsIDMpKSA9PT0gJ1dJTic7Cgl9Cgp9Cgo/Pgo8P3BocAovKioKICogUEhQIENvbW1hbmQgTGluZSBUb29scwogKgogKiBUaGlzIHNvdXJjZSBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIE1JVCBsaWNlbnNlIHRoYXQgaXMgYnVuZGxlZAogKiB3aXRoIHRoaXMgcGFja2FnZSBpbiB0aGUgZmlsZSBMSUNFTlNFLgogKgogKiBAYXV0aG9yICAgIEphbWVzIExvZ3Nkb24gPGR3YXJmQGdpcnNicmFpbi5vcmc+CiAqIEBjb3B5cmlnaHQgMjAxMCBKYW1lcyBMb2dzZG9tIChodHRwOi8vZ2lyc2JyYWluLm9yZykKICogQGxpY2Vuc2UgICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocCBUaGUgTUlUIExpY2Vuc2UKICovCgpuYW1lc3BhY2UgY2xpOwoKYWJzdHJhY3QgY2xhc3MgTWVtb2l6ZSB7Cglwcm90ZWN0ZWQgJF9tZW1vQ2FjaGUgPSBhcnJheSgpOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkgewoJCWlmIChpc3NldCgkdGhpcy0+X21lbW9DYWNoZVskbmFtZV0pKSB7CgkJCXJldHVybiAkdGhpcy0+X21lbW9DYWNoZVskbmFtZV07CgkJfQoKCQkvLyBIaWRlIHByb2JhYmxlIHByaXZhdGUgbWV0aG9kcwoJCWlmICgwID09IHN0cm5jbXAoJG5hbWUsICdfJywgMSkpIHsKCQkJcmV0dXJuICgkdGhpcy0+X21lbW9DYWNoZVskbmFtZV0gPSBudWxsKTsKCQl9CgoJCWlmICghbWV0aG9kX2V4aXN0cygkdGhpcywgJG5hbWUpKSB7CgkJCXJldHVybiAoJHRoaXMtPl9tZW1vQ2FjaGVbJG5hbWVdID0gbnVsbCk7CgkJfQoKCQkkbWV0aG9kID0gYXJyYXkoJHRoaXMsICRuYW1lKTsKCQkoJHRoaXMtPl9tZW1vQ2FjaGVbJG5hbWVdID0gY2FsbF91c2VyX2Z1bmMoJG1ldGhvZCkpOwoJCXJldHVybiAkdGhpcy0+X21lbW9DYWNoZVskbmFtZV07Cgl9CgoJcHJvdGVjdGVkIGZ1bmN0aW9uIF91bm1lbW8oJG5hbWUpIHsKCQlpZiAoJG5hbWUgPT09IHRydWUpIHsKCQkJJHRoaXMtPl9tZW1vQ2FjaGUgPSBhcnJheSgpOwoJCX0gZWxzZSB7CgkJCXVuc2V0KCR0aGlzLT5fbWVtb0NhY2hlWyRuYW1lXSk7CgkJfQoJfQp9Cjw/cGhwCi8qKgogKiBQSFAgQ29tbWFuZCBMaW5lIFRvb2xzCiAqCiAqIFRoaXMgc291cmNlIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgTUlUIGxpY2Vuc2UgdGhhdCBpcyBidW5kbGVkCiAqIHdpdGggdGhpcyBwYWNrYWdlIGluIHRoZSBmaWxlIExJQ0VOU0UuCiAqCiAqIEBhdXRob3IgICAgSmFtZXMgTG9nc2RvbiA8ZHdhcmZAZ2lyc2JyYWluLm9yZz4KICogQGNvcHlyaWdodCAyMDEwIEphbWVzIExvZ3Nkb20gKGh0dHA6Ly9naXJzYnJhaW4ub3JnKQogKiBAbGljZW5zZSAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFRoZSBNSVQgTGljZW5zZQogKi8KCm5hbWVzcGFjZSBjbGk7Cgp1c2UgY2xpXGFyZ3VtZW50c1xBcmd1bWVudDsKdXNlIGNsaVxhcmd1bWVudHNcSGVscFNjcmVlbjsKdXNlIGNsaVxhcmd1bWVudHNcSW52YWxpZEFyZ3VtZW50czsKdXNlIGNsaVxhcmd1bWVudHNcTGV4ZXI7CgovKioKICogUGFyc2VzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMuCiAqLwpjbGFzcyBBcmd1bWVudHMgaW1wbGVtZW50cyBcQXJyYXlBY2Nlc3MgewoJcHJvdGVjdGVkICRfZmxhZ3MgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfb3B0aW9ucyA9IGFycmF5KCk7Cglwcm90ZWN0ZWQgJF9zdHJpY3QgPSBmYWxzZTsKCXByb3RlY3RlZCAkX2lucHV0ID0gYXJyYXkoKTsKCXByb3RlY3RlZCAkX2ludmFsaWQgPSBhcnJheSgpOwoJcHJvdGVjdGVkICRfcGFyc2VkOwoJcHJvdGVjdGVkICRfbGV4ZXI7CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGUgYXJndW1lbnQgcGFyc2VyLiBJZiB5b3Ugd2lzaCB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgYmVoYXZpb3VyCgkgKiB5b3UgbWF5IHBhc3MgYW4gYXJyYXkgb2Ygb3B0aW9ucyBhcyB0aGUgZmlyc3QgYXJndW1lbnQuIFZhbGlkIG9wdGlvbnMgYXJlCgkgKiBgJ2hlbHAnYCBhbmQgYCdzdHJpY3QnYCwgZWFjaCBhIGJvb2xlYW4uCgkgKgoJICogYCdoZWxwJ2AgaXMgYHRydWVgIGJ5IGRlZmF1bHQsIGAnc3RyaWN0J2AgaXMgZmFsc2UgYnkgZGVmYXVsdC4KCSAqCgkgKiBAcGFyYW0gIGFycmF5ICAkb3B0aW9ucyAgQW4gYXJyYXkgb2Ygb3B0aW9ucyBmb3IgdGhpcyBwYXJzZXIuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb3B0aW9ucyA9IGFycmF5KCkpIHsKCQkkb3B0aW9ucyArPSBhcnJheSgKCQkJJ3N0cmljdCcgPT4gZmFsc2UsCgkJCSdpbnB1dCcgID0+IGFycmF5X3NsaWNlKCRfU0VSVkVSWydhcmd2J10sIDEpCgkJKTsKCgkJJHRoaXMtPl9pbnB1dCA9ICRvcHRpb25zWydpbnB1dCddOwoJCSR0aGlzLT5zZXRTdHJpY3QoJG9wdGlvbnNbJ3N0cmljdCddKTsKCgkJaWYgKGlzc2V0KCRvcHRpb25zWydmbGFncyddKSkgewoJCQkkdGhpcy0+YWRkRmxhZ3MoJG9wdGlvbnNbJ2ZsYWdzJ10pOwoJCX0KCQlpZiAoaXNzZXQoJG9wdGlvbnNbJ29wdGlvbnMnXSkpIHsKCQkJJHRoaXMtPmFkZE9wdGlvbnMoJG9wdGlvbnNbJ29wdGlvbnMnXSk7CgkJfQoJfQoKCS8qKgoJICogR2V0IHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBmb3VuZCBieSB0aGUgZGVmaW5lZCBkZWZpbml0aW9ucy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudHMoKSB7CgkJaWYgKCFpc3NldCgkdGhpcy0+X3BhcnNlZCkpIHsKCQkJJHRoaXMtPnBhcnNlKCk7CgkJfQoJCXJldHVybiAkdGhpcy0+X3BhcnNlZDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0SGVscFNjcmVlbigpIHsKCQlyZXR1cm4gbmV3IEhlbHBTY3JlZW4oJHRoaXMpOwoJfQoKCS8qKgoJICogRW5jb2RlcyB0aGUgcGFyc2VkIGFyZ3VtZW50cyBhcyBKU09OLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhc0pTT04oKSB7CgkJcmV0dXJuIGpzb25fZW5jb2RlKCR0aGlzLT5fcGFyc2VkKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiBhIGdpdmVuIGFyZ3VtZW50IHdhcyBwYXJzZWQuCgkgKgoJICogQHBhcmFtIG1peGVkICAkb2Zmc2V0ICBBbiBBcmd1bWVudCBvYmplY3Qgb3IgdGhlIG5hbWUgb2YgdGhlIGFyZ3VtZW50LgoJICogQHJldHVybiBib29sCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBvZmZzZXRFeGlzdHMoJG9mZnNldCkgewoJCWlmICgkb2Zmc2V0IGluc3RhbmNlT2YgQXJndW1lbnQpIHsKCQkJJG9mZnNldCA9ICRvZmZzZXQtPmtleTsKCQl9CgoJCXJldHVybiBhcnJheV9rZXlfZXhpc3RzKCRvZmZzZXQsICR0aGlzLT5fcGFyc2VkKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgcGFyc2VkIGFyZ3VtZW50J3MgdmFsdWUuCgkgKgoJICogQHBhcmFtIG1peGVkICAkb2Zmc2V0ICBBbiBBcmd1bWVudCBvYmplY3Qgb3IgdGhlIG5hbWUgb2YgdGhlIGFyZ3VtZW50LgoJICogQHJldHVybiBtaXhlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0R2V0KCRvZmZzZXQpIHsKCQlpZiAoJG9mZnNldCBpbnN0YW5jZU9mIEFyZ3VtZW50KSB7CgkJCSRvZmZzZXQgPSAkb2Zmc2V0LT5rZXk7CgkJfQoKCQlpZiAoaXNzZXQoJHRoaXMtPl9wYXJzZWRbJG9mZnNldF0pKSB7CgkJCXJldHVybiAkdGhpcy0+X3BhcnNlZFskb2Zmc2V0XTsKCQl9Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHBhcnNlZCBhcmd1bWVudC4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgICRvZmZzZXQgIEFuIEFyZ3VtZW50IG9iamVjdCBvciB0aGUgbmFtZSBvZiB0aGUgYXJndW1lbnQuCgkgKiBAcGFyYW0gbWl4ZWQgICR2YWx1ZSAgIFRoZSB2YWx1ZSB0byBzZXQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgkb2Zmc2V0LCAkdmFsdWUpIHsKCQlpZiAoJG9mZnNldCBpbnN0YW5jZU9mIEFyZ3VtZW50KSB7CgkJCSRvZmZzZXQgPSAkb2Zmc2V0LT5rZXk7CgkJfQoKCQkkdGhpcy0+X3BhcnNlZFskb2Zmc2V0XSA9ICR2YWx1ZTsKCX0KCgkvKioKCSAqIFVuc2V0IGEgcGFyc2VkIGFyZ3VtZW50LgoJICoKCSAqIEBwYXJhbSBtaXhlZCAgJG9mZnNldCAgQW4gQXJndW1lbnQgb2JqZWN0IG9yIHRoZSBuYW1lIG9mIHRoZSBhcmd1bWVudC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIG9mZnNldFVuc2V0KCRvZmZzZXQpIHsKCQlpZiAoJG9mZnNldCBpbnN0YW5jZU9mIEFyZ3VtZW50KSB7CgkJCSRvZmZzZXQgPSAkb2Zmc2V0LT5rZXk7CgkJfQoKCQl1bnNldCgkdGhpcy0+X3BhcnNlZFskb2Zmc2V0XSk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgZmxhZyAoYm9vbGVhbiBhcmd1bWVudCkgdG8gdGhlIGFyZ3VtZW50IGxpc3QuCgkgKgoJICogQHBhcmFtIG1peGVkICAkZmxhZyAgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBmbGFnLCBvciBhbiBhcnJheSBvZiBzdHJpbmdzLgoJICogQHBhcmFtIGFycmF5ICAkc2V0dGluZ3MgIEFuIGFycmF5IG9mIHNldHRpbmdzIGZvciB0aGlzIGZsYWcuCgkgKiBAc2V0dGluZyBzdHJpbmcgIGRlc2NyaXB0aW9uICBBIGRlc2NyaXB0aW9uIHRvIGJlIHNob3duIGluIC0taGVscC4KCSAqIEBzZXR0aW5nIGJvb2wgICAgZGVmYXVsdCAgVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgZmxhZy4KCSAqIEBzZXR0aW5nIGJvb2wgICAgc3RhY2thYmxlICBXaGV0aGVyIHRoZSBmbGFnIGlzIHJlcGVhdGFibGUgdG8gaW5jcmVhc2UgdGhlIHZhbHVlLgoJICogQHNldHRpbmcgYXJyYXkgICBhbGlhc2VzICBPdGhlciB3YXlzIHRvIHRyaWdnZXIgdGhpcyBmbGFnLgoJICogQHJldHVybiAkdGhpcwoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkRmxhZygkZmxhZywgJHNldHRpbmdzID0gYXJyYXkoKSkgewoJCWlmIChpc19zdHJpbmcoJHNldHRpbmdzKSkgewoJCQkkc2V0dGluZ3MgPSBhcnJheSgnZGVzY3JpcHRpb24nID0+ICRzZXR0aW5ncyk7CgkJfQoJCWlmIChpc19hcnJheSgkZmxhZykpIHsKCQkJJHNldHRpbmdzWydhbGlhc2VzJ10gPSAkZmxhZzsKCQkJJGZsYWcgPSBhcnJheV9zaGlmdCgkc2V0dGluZ3NbJ2FsaWFzZXMnXSk7CgkJfQoJCWlmIChpc3NldCgkdGhpcy0+X2ZsYWdzWyRmbGFnXSkpIHsKCQkJJHRoaXMtPl93YXJuKCdmbGFnIGFscmVhZHkgZXhpc3RzOiAnIC4gJGZsYWcpOwoJCQlyZXR1cm4gJHRoaXM7CgkJfQoKCQkkc2V0dGluZ3MgKz0gYXJyYXkoCgkJCSdkZWZhdWx0JyAgICAgPT4gZmFsc2UsCgkJCSdzdGFja2FibGUnICAgPT4gZmFsc2UsCgkJCSdkZXNjcmlwdGlvbicgPT4gbnVsbCwKCQkJJ2FsaWFzZXMnICAgICA9PiBhcnJheSgpCgkJKTsKCgkJJHRoaXMtPl9mbGFnc1skZmxhZ10gPSAkc2V0dGluZ3M7CgkJcmV0dXJuICR0aGlzOwoJfQoKCS8qKgoJICogQWRkIG11bHRpcGxlIGZsYWdzIGF0IG9uY2UuIFRoZSBpbnB1dCBhcnJheSBzaG91bGQgYmUga2V5ZWQgd2l0aCB0aGUKCSAqIHByaW1hcnkgZmxhZyBjaGFyYWN0ZXIsIGFuZCB0aGUgdmFsdWVzIHNob3VsZCBiZSB0aGUgc2V0dGluZ3MgYXJyYXkKCSAqIHVzZWQgYnkge2FkZEZsYWd9LgoJICoKCSAqIEBwYXJhbSBhcnJheSAgJGZsYWdzICBBbiBhcnJheSBvZiBmbGFncyB0byBhZGQKCSAqIEByZXR1cm4gJHRoaXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZEZsYWdzKCRmbGFncykgewoJCWZvcmVhY2ggKCRmbGFncyBhcyAkZmxhZyA9PiAkc2V0dGluZ3MpIHsKCQkJaWYgKGlzX251bWVyaWMoJGZsYWcpKSB7CgkJCQkkdGhpcy0+X3dhcm4oJ05vIGZsYWcgY2hhcmFjdGVyIGdpdmVuJyk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHRoaXMtPmFkZEZsYWcoJGZsYWcsICRzZXR0aW5ncyk7CgkJfQoKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJLyoqCgkgKiBBZGRzIGFuIG9wdGlvbiAoc3RyaW5nIGFyZ3VtZW50KSB0byB0aGUgYXJndW1lbnQgbGlzdC4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgICRvcHRpb24gIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgb3B0aW9uLCBvciBhbiBhcnJheSBvZiBzdHJpbmdzLgoJICogQHBhcmFtIGFycmF5ICAkc2V0dGluZ3MgIEFuIGFycmF5IG9mIHNldHRpbmdzIGZvciB0aGlzIG9wdGlvbi4KCSAqIEBzZXR0aW5nIHN0cmluZyAgZGVzY3JpcHRpb24gIEEgZGVzY3JpcHRpb24gdG8gYmUgc2hvd24gaW4gLS1oZWxwLgoJICogQHNldHRpbmcgYm9vbCAgICBkZWZhdWx0ICBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBvcHRpb24uCgkgKiBAc2V0dGluZyBhcnJheSAgIGFsaWFzZXMgIE90aGVyIHdheXMgdG8gdHJpZ2dlciB0aGlzIG9wdGlvbi4KCSAqIEByZXR1cm4gJHRoaXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZE9wdGlvbigkb3B0aW9uLCAkc2V0dGluZ3MgPSBhcnJheSgpKSB7CgkJaWYgKGlzX3N0cmluZygkc2V0dGluZ3MpKSB7CgkJCSRzZXR0aW5ncyA9IGFycmF5KCdkZXNjcmlwdGlvbicgPT4gJHNldHRpbmdzKTsKCQl9CgkJaWYgKGlzX2FycmF5KCRvcHRpb24pKSB7CgkJCSRzZXR0aW5nc1snYWxpYXNlcyddID0gJG9wdGlvbjsKCQkJJG9wdGlvbiA9IGFycmF5X3NoaWZ0KCRzZXR0aW5nc1snYWxpYXNlcyddKTsKCQl9CgkJaWYgKGlzc2V0KCR0aGlzLT5fb3B0aW9uc1skb3B0aW9uXSkpIHsKCQkJJHRoaXMtPl93YXJuKCdvcHRpb24gYWxyZWFkeSBleGlzdHM6ICcgLiAkb3B0aW9uKTsKCQkJcmV0dXJuICR0aGlzOwoJCX0KCgkJJHNldHRpbmdzICs9IGFycmF5KAoJCQknZGVmYXVsdCcgICAgID0+IG51bGwsCgkJCSdkZXNjcmlwdGlvbicgPT4gbnVsbCwKCQkJJ2FsaWFzZXMnICAgICA9PiBhcnJheSgpCgkJKTsKCgkJJHRoaXMtPl9vcHRpb25zWyRvcHRpb25dID0gJHNldHRpbmdzOwoJCXJldHVybiAkdGhpczsKCX0KCgkvKioKCSAqIEFkZCBtdWx0aXBsZSBvcHRpb25zIGF0IG9uY2UuIFRoZSBpbnB1dCBhcnJheSBzaG91bGQgYmUga2V5ZWQgd2l0aCB0aGUKCSAqIHByaW1hcnkgb3B0aW9uIHN0cmluZywgYW5kIHRoZSB2YWx1ZXMgc2hvdWxkIGJlIHRoZSBzZXR0aW5ncyBhcnJheQoJICogdXNlZCBieSB7YWRkT3B0aW9ufS4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zICBBbiBhcnJheSBvZiBvcHRpb25zIHRvIGFkZAoJICogQHJldHVybiAkdGhpcwoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkT3B0aW9ucygkb3B0aW9ucykgewoJCWZvcmVhY2ggKCRvcHRpb25zIGFzICRvcHRpb24gPT4gJHNldHRpbmdzKSB7CgkJCWlmIChpc19udW1lcmljKCRvcHRpb24pKSB7CgkJCQkkdGhpcy0+X3dhcm4oJ05vIG9wdGlvbiBzdHJpbmcgZ2l2ZW4nKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkdGhpcy0+YWRkT3B0aW9uKCRvcHRpb24sICRzZXR0aW5ncyk7CgkJfQoKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJLyoqCgkgKiBFbmFibGUgb3IgZGlzYWJsZSBzdHJpY3QgbW9kZS4gSWYgc3RyaWN0IG1vZGUgaXMgYWN0aXZlIGFueSBpbnZhbGlkCgkgKiBhcmd1bWVudHMgZm91bmQgYnkgdGhlIHBhcnNlciB3aWxsIHRocm93IGBjbGlcYXJndW1lbnRzXEludmFsaWRBcmd1bWVudHNgLgoJICoKCSAqIEV2ZW4gaWYgc3RyaWN0IGlzIGRpc2FibGVkLCBpbnZhbGlkIGFyZ3VtZW50cyBhcmUgbG9nZ2VkIGFuZCBjYW4gYmUKCSAqIHJldHJpZXZlZCB3aXRoIGBjbGlcQXJndW1lbnRzOjpnZXRJbnZhbGlkQXJndW1lbnRzKClgLgoJICoKCSAqIEBwYXJhbSBib29sICAkc3RyaWN0ICBUcnVlIHRvIGVuYWJsZSwgZmFsc2UgdG8gZGlzYWJsZS4KCSAqIEByZXR1cm4gJHRoaXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHNldFN0cmljdCgkc3RyaWN0KSB7CgkJJHRoaXMtPl9zdHJpY3QgPSAoYm9vbCkkc3RyaWN0OwoJCXJldHVybiAkdGhpczsKCX0KCgkvKioKCSAqIEdldCB0aGUgbGlzdCBvZiBpbnZhbGlkIGFyZ3VtZW50cyB0aGUgcGFyc2VyIGZvdW5kLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldEludmFsaWRBcmd1bWVudHMoKSB7CgkJcmV0dXJuICR0aGlzLT5faW52YWxpZDsKCX0KCgkvKioKCSAqIEdldCBhIGZsYWcgYnkgcHJpbWFyeSBtYXRjaGVyIG9yIGFueSBkZWZpbmVkIGFsaWFzZXMuCgkgKgoJICogQHBhcmFtIG1peGVkICAkZmxhZyAgRWl0aGVyIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgZmxhZyBvciBhbgoJICogICAgICAgICAgICAgICAgICAgICAgY2xpXGFyZ3VtZW50c1xBcmd1bWVudCBvYmplY3QuCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXRGbGFnKCRmbGFnKSB7CgkJaWYgKCRmbGFnIGluc3RhbmNlT2YgQXJndW1lbnQpIHsKCQkJJG9iaiAgPSAkZmxhZzsKCQkJJGZsYWcgPSAkZmxhZy0+dmFsdWU7CgkJfQoKCQlpZiAoaXNzZXQoJHRoaXMtPl9mbGFnc1skZmxhZ10pKSB7CgkJCXJldHVybiAkdGhpcy0+X2ZsYWdzWyRmbGFnXTsKCQl9CgoJCWZvcmVhY2ggKCR0aGlzLT5fZmxhZ3MgYXMgJG1hc3RlciA9PiAkc2V0dGluZ3MpIHsKCQkJaWYgKGluX2FycmF5KCRmbGFnLCAoYXJyYXkpJHNldHRpbmdzWydhbGlhc2VzJ10pKSB7CgkJCQlpZiAoaXNzZXQoJG9iaikpIHsKCQkJCQkkb2JqLT5rZXkgPSAkbWFzdGVyOwoJCQkJfQoKCQkJCSRjYWNoZVskZmxhZ10gPSYgJHNldHRpbmdzOwoJCQkJcmV0dXJuICRzZXR0aW5nczsKCQkJfQoJCX0KCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0RmxhZ3MoKSB7CgkJcmV0dXJuICR0aGlzLT5fZmxhZ3M7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGhhc0ZsYWdzKCkgewoJCXJldHVybiAhZW1wdHkoJHRoaXMtPl9mbGFncyk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIGRlZmluZWQgYXMgYSBmbGFnLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAgJGFyZ3VtZW50ICBFaXRoZXIgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBmbGFnIG9yIGFuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpXGFyZ3VtZW50c1xBcmd1bWVudCBvYmplY3QuCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzRmxhZygkYXJndW1lbnQpIHsKCQlyZXR1cm4gKG51bGwgIT09ICR0aGlzLT5nZXRGbGFnKCRhcmd1bWVudCkpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBmbGFnIGlzIHN0YWNrYWJsZS4KCSAqCgkgKiBAcGFyYW0gbWl4ZWQgICRmbGFnICBFaXRoZXIgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBmbGFnIG9yIGFuCgkgKiAgICAgICAgICAgICAgICAgICAgICBjbGlcYXJndW1lbnRzXEFyZ3VtZW50IG9iamVjdC4KCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNTdGFja2FibGUoJGZsYWcpIHsKCQkkc2V0dGluZ3MgPSAkdGhpcy0+Z2V0RmxhZygkZmxhZyk7CgoJCXJldHVybiBpc3NldCgkc2V0dGluZ3MpICYmICh0cnVlID09PSAkc2V0dGluZ3NbJ3N0YWNrYWJsZSddKTsKCX0KCgkvKioKCSAqIEdldCBhbiBvcHRpb24gYnkgcHJpbWFyeSBtYXRjaGVyIG9yIGFueSBkZWZpbmVkIGFsaWFzZXMuCgkgKgoJICogQHBhcmFtIG1peGVkICAkb3B0aW9uIEVpdGhlciBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIG9wdGlvbiBvciBhbgoJICogICAgICAgICAgICAgICAgICAgICAgIGNsaVxhcmd1bWVudHNcQXJndW1lbnQgb2JqZWN0LgoJICogQHJldHVybiBhcnJheQoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRvcHRpb24pIHsKCQlpZiAoJG9wdGlvbiBpbnN0YW5jZU9mIEFyZ3VtZW50KSB7CgkJCSRvYmogPSAkb3B0aW9uOwoJCQkkb3B0aW9uID0gJG9wdGlvbi0+dmFsdWU7CgkJfQoKCQlpZiAoaXNzZXQoJHRoaXMtPl9vcHRpb25zWyRvcHRpb25dKSkgewoJCQlyZXR1cm4gJHRoaXMtPl9vcHRpb25zWyRvcHRpb25dOwoJCX0KCgkJZm9yZWFjaCAoJHRoaXMtPl9vcHRpb25zIGFzICRtYXN0ZXIgPT4gJHNldHRpbmdzKSB7CgkJCWlmIChpbl9hcnJheSgkb3B0aW9uLCAoYXJyYXkpJHNldHRpbmdzWydhbGlhc2VzJ10pKSB7CgkJCQlpZiAoaXNzZXQoJG9iaikpIHsKCQkJCQkkb2JqLT5rZXkgPSAkbWFzdGVyOwoJCQkJfQoKCQkJCXJldHVybiAkc2V0dGluZ3M7CgkJCX0KCQl9Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbnMoKSB7CgkJcmV0dXJuICR0aGlzLT5fb3B0aW9uczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gaGFzT3B0aW9ucygpIHsKCQlyZXR1cm4gIWVtcHR5KCR0aGlzLT5fb3B0aW9ucyk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIGRlZmluZWQgYXMgYW4gb3B0aW9uLgoJICoKCSAqIEBwYXJhbSBtaXhlZCAgJGFyZ3VtZW50ICBFaXRoZXIgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBvcHRpb24gb3IgYW4KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlcYXJndW1lbnRzXEFyZ3VtZW50IG9iamVjdC4KCSAqIEByZXR1cm4gYm9vbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNPcHRpb24oJGFyZ3VtZW50KSB7CgkJcmV0dXJuIChudWxsICE9ICR0aGlzLT5nZXRPcHRpb24oJGFyZ3VtZW50KSk7Cgl9CgoJLyoqCgkgKiBQYXJzZXMgdGhlIGFyZ3VtZW50IGxpc3Qgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy4gVGhlIHJldHVybmVkIGFyZ3VtZW50IGxpc3QKCSAqIHdpbGwgdXNlIGVpdGhlciB0aGUgZmlyc3QgbG9uZyBuYW1lIGdpdmVuIG9yIHRoZSBmaXJzdCBuYW1lIGluIHRoZSBsaXN0CgkgKiBpZiBhIGxvbmcgbmFtZSBpcyBub3QgZ2l2ZW4uCgkgKgoJICogQHJldHVybiBhcnJheQoJICogQHRocm93cyBhcmd1bWVudHNcSW52YWxpZEFyZ3VtZW50cwoJICovCglwdWJsaWMgZnVuY3Rpb24gcGFyc2UoKSB7CgkJJHRoaXMtPl9pbnZhbGlkID0gYXJyYXkoKTsKCQkkdGhpcy0+X3BhcnNlZCA9IGFycmF5KCk7CgkJJHRoaXMtPl9sZXhlciA9IG5ldyBMZXhlcigkdGhpcy0+X2lucHV0KTsKCgkJJHRoaXMtPl9hcHBseURlZmF1bHRzKCk7CgoJCWZvcmVhY2ggKCR0aGlzLT5fbGV4ZXIgYXMgJGFyZ3VtZW50KSB7CgkJCWlmICgkdGhpcy0+X3BhcnNlRmxhZygkYXJndW1lbnQpKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoJHRoaXMtPl9wYXJzZU9wdGlvbigkYXJndW1lbnQpKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJYXJyYXlfcHVzaCgkdGhpcy0+X2ludmFsaWQsICRhcmd1bWVudC0+cmF3KTsKCQl9CgoJCWlmICgkdGhpcy0+X3N0cmljdCAmJiAhZW1wdHkoJHRoaXMtPl9pbnZhbGlkKSkgewoJCQl0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50cygkdGhpcy0+X2ludmFsaWQpOwoJCX0KCX0KCgkvKioKCSAqIFRoaXMgYXBwbGllcyB0aGUgZGVmYXVsdCB2YWx1ZXMsIGlmIGFueSwgb2YgYWxsIG9mIHRoZQoJICogZmxhZ3MgYW5kIG9wdGlvbnMsIHNvIHRoYXQgaWYgdGhlcmUgaXMgYSBkZWZhdWx0IHZhbHVlCgkgKiBpdCB3aWxsIGJlIGF2YWlsYWJsZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBfYXBwbHlEZWZhdWx0cygpIHsKCQlmb3JlYWNoKCR0aGlzLT5fZmxhZ3MgYXMgJGZsYWcgPT4gJHNldHRpbmdzKSB7CgkJCSR0aGlzWyRmbGFnXSA9ICRzZXR0aW5nc1snZGVmYXVsdCddOwoJCX0KCgkJZm9yZWFjaCgkdGhpcy0+X29wdGlvbnMgYXMgJG9wdGlvbiA9PiAkc2V0dGluZ3MpIHsKCQkJLy8gSWYgdGhlIGRlZmF1bHQgaXMgMCB3ZSBzaG91bGQgc3RpbGwgbGV0IGl0IGJlIHNldC4KCQkJaWYgKCFlbXB0eSgkc2V0dGluZ3NbJ2RlZmF1bHQnXSkgfHwgJHNldHRpbmdzWydkZWZhdWx0J10gPT09IDApIHsKCQkJCSR0aGlzWyRvcHRpb25dID0gJHNldHRpbmdzWydkZWZhdWx0J107CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBfd2FybigkbWVzc2FnZSkgewoJCXRyaWdnZXJfZXJyb3IoJ1snIC4gX19DTEFTU19fIC4nXSAnIC4gJG1lc3NhZ2UsIEVfVVNFUl9XQVJOSU5HKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9wYXJzZUZsYWcoJGFyZ3VtZW50KSB7CgkJaWYgKCEkdGhpcy0+aXNGbGFnKCRhcmd1bWVudCkpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJaWYgKCR0aGlzLT5pc1N0YWNrYWJsZSgkYXJndW1lbnQpKSB7CgkJCWlmICghaXNzZXQoJHRoaXNbJGFyZ3VtZW50XSkpIHsKCQkJCSR0aGlzWyRhcmd1bWVudC0+a2V5XSA9IDA7CgkJCX0KCgkJCSR0aGlzWyRhcmd1bWVudC0+a2V5XSArPSAxOwoJCX0gZWxzZSB7CgkJCSR0aGlzWyRhcmd1bWVudC0+a2V5XSA9IHRydWU7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIF9wYXJzZU9wdGlvbigkb3B0aW9uKSB7CgkJaWYgKCEkdGhpcy0+aXNPcHRpb24oJG9wdGlvbikpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLy8gUGVhayBhaGVhZCB0byBtYWtlIHN1cmUgd2UgZ2V0IGEgdmFsdWUuCgkJaWYgKCR0aGlzLT5fbGV4ZXItPmVuZCgpIHx8ICEkdGhpcy0+X2xleGVyLT5wZWVrLT5pc1ZhbHVlKSB7CgkJCSRvcHRpb25TZXR0aW5ncyA9ICR0aGlzLT5nZXRPcHRpb24oJG9wdGlvbi0+a2V5KTsKCgkJCWlmIChlbXB0eSgkb3B0aW9uU2V0dGluZ3NbJ2RlZmF1bHQnXSkgJiYgJG9wdGlvblNldHRpbmdzICE9PSAwKSB7CgkJCQkvLyBPb3BzISBHb3Qgbm8gdmFsdWUgYW5kIG5vIGRlZmF1bHQgLCB0aHJvdyBhIHdhcm5pbmcgYW5kIGNvbnRpbnVlLgoJCQkJJHRoaXMtPl93YXJuKCdubyB2YWx1ZSBnaXZlbiBmb3IgJyAuICRvcHRpb24tPnJhdyk7CgkJCQkkdGhpc1skb3B0aW9uLT5rZXldID0gbnVsbDsKCQkJfSBlbHNlIHsKCQkJCS8vIE5vIHZhbHVlIGFuZCB3ZSBoYXZlIGEgZGVmYXVsdCwgc28gd2Ugc2V0IHRvIHRoZSBkZWZhdWx0CgkJCQkkdGhpc1skb3B0aW9uLT5rZXldID0gJG9wdGlvblNldHRpbmdzWydkZWZhdWx0J107CgkJCX0KCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyBTdG9yZSBhcyBhcnJheSBhbmQgam9pbiB0byBzdHJpbmcgYWZ0ZXIgbG9vcGluZyBmb3IgdmFsdWVzCgkJJHZhbHVlcyA9IGFycmF5KCk7CgoJCS8vIExvb3AgdW50aWwgd2UgZmluZCBhIGZsYWcgaW4gcGVhay1haGVhZAoJCWZvcmVhY2ggKCR0aGlzLT5fbGV4ZXIgYXMgJHZhbHVlKSB7CgkJCWFycmF5X3B1c2goJHZhbHVlcywgJHZhbHVlLT5yYXcpOwoKCQkJaWYgKCEkdGhpcy0+X2xleGVyLT5lbmQoKSAmJiAhJHRoaXMtPl9sZXhlci0+cGVlay0+aXNWYWx1ZSkgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCSR0aGlzWyRvcHRpb24tPmtleV0gPSBqb2luKCcgJywgJHZhbHVlcyk7CgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKLy8gR2VuZXJhdGVkIGJ5ICJnZW5fZWFzdF9hc2lhbl93aWR0aC5waHAiIGZyb20gImh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzEwLjAuMC91Y2QvRWFzdEFzaWFuV2lkdGgudHh0Ii4KJGVhd19yZWdleCA9ICcvXHhlMSg/Olx4ODRbXHg4MC1ceGJmXXxceDg1W1x4ODAtXHg5Zl0pfFx4ZTIoPzpceDhjW1x4OWFceDliXHhhOVx4YWFdfFx4OGZbXHhhOS1ceGFjXHhiMFx4YjNdfFx4OTdbXHhiZFx4YmVdfFx4OThbXHg5NFx4OTVdfFx4OTlbXHg4OC1ceDkzXHhiZl18XHg5YVtceDkzXHhhMVx4YWFceGFiXHhiZFx4YmVdfFx4OWJbXHg4NFx4ODVceDhlXHg5NFx4YWFceGIyXHhiM1x4YjVceGJhXHhiZF18XHg5Y1tceDg1XHg4YVx4OGJceGE4XXxceDlkW1x4OGNceDhlXHg5My1ceDk1XHg5N118XHg5ZVtceDk1LVx4OTdceGIwXHhiZl18XHhhY1tceDliXHg5Y118XHhhZFtceDkwXHg5NV18XHhiYVtceDgwLVx4OTlceDliLVx4YmZdfFx4YmJbXHg4MC1ceGIzXXxbXHhiYy1ceGJlXVtceDgwLVx4YmZdfFx4YmZbXHg4MC1ceDk1XHhiMC1ceGJiXSl8XHhlMyg/Olx4ODBbXHg4MC1ceGJlXXxceDgxW1x4ODEtXHhiZl18XHg4MltceDgwLVx4OTZceDk5LVx4YmZdfFx4ODNbXHg4MC1ceGJmXXxceDg0W1x4ODUtXHhhZVx4YjEtXHhiZl18XHg4NVtceDgwLVx4YmZdfFx4ODZbXHg4MC1ceDhlXHg5MC1ceGJhXXxceDg3W1x4ODAtXHhhM1x4YjAtXHhiZl18XHg4OFtceDgwLVx4OWVceGEwLVx4YmZdfFx4ODlbXHg4MC1ceDg3XHg5MC1ceGJmXXxceDhhW1x4ODAtXHhiZl18XHg4YltceDgwLVx4YmVdfFtceDhjLVx4YmZdW1x4ODAtXHhiZl0pfFx4ZTQoPzpbXHg4MC1ceGI2XVtceDgwLVx4YmZdfFtceGI4LVx4YmZdW1x4ODAtXHhiZl0pfFtceGU1LVx4ZTldW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGVhKD86W1x4ODAtXHg5MV1bXHg4MC1ceGJmXXxceDkyW1x4ODAtXHg4Y1x4OTAtXHhiZl18XHg5M1tceDgwLVx4ODZdfFx4YTVbXHhhMC1ceGJjXXxbXHhiMC1ceGJmXVtceDgwLVx4YmZdKXxbXHhlYlx4ZWNdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGVkKD86W1x4ODAtXHg5ZF1bXHg4MC1ceGJmXXxceDllW1x4ODAtXHhhM10pfFx4ZWYoPzpbXHhhNC1ceGFiXVtceDgwLVx4YmZdfFx4YjhbXHg5MC1ceDk5XHhiMC1ceGJmXXxceGI5W1x4ODAtXHg5Mlx4OTQtXHhhNlx4YTgtXHhhYl18XHhiY1tceDgxLVx4YmZdfFx4YmRbXHg4MC1ceGEwXXxceGJmW1x4YTAtXHhhNl0pfFx4ZjAoPzpceDk2XHhiZltceGEwXHhhMV18XHg5N1tceDgwLVx4YmZdW1x4ODAtXHhiZl18XHg5OCg/OltceDgwLVx4OWVdW1x4ODAtXHhiZl18XHg5ZltceDgwLVx4YWNdfFtceGEwLVx4YWFdW1x4ODAtXHhiZl18XHhhYltceDgwLVx4YjJdKXxceDliKD86W1x4ODAtXHg4M11bXHg4MC1ceGJmXXxceDg0W1x4ODAtXHg5ZV18XHg4NVtceGIwLVx4YmZdfFtceDg2LVx4OGFdW1x4ODAtXHhiZl18XHg4YltceDgwLVx4YmJdKXxceDlmKD86XHg4MFx4ODR8XHg4M1x4OGZ8XHg4NltceDhlXHg5MS1ceDlhXXxceDg4W1x4ODAtXHg4Mlx4OTAtXHhiYl18XHg4OVtceDgwLVx4ODhceDkwXHg5MVx4YTAtXHhhNV18XHg4Y1tceDgwLVx4YTBceGFkLVx4YjVceGI3LVx4YmZdfFx4OGRbXHg4MC1ceGJjXHhiZVx4YmZdfFx4OGVbXHg4MC1ceDkzXHhhMC1ceGJmXXxceDhmW1x4ODAtXHg4YVx4OGYtXHg5M1x4YTAtXHhiMFx4YjRceGI4LVx4YmZdfFx4OTBbXHg4MC1ceGJlXXxceDkxW1x4ODBceDgyLVx4YmZdfFx4OTJbXHg4MC1ceGJmXXxceDkzW1x4ODAtXHhiY1x4YmZdfFx4OTRbXHg4MC1ceGJkXXxceDk1W1x4OGItXHg4ZVx4OTAtXHhhN1x4YmFdfFx4OTZbXHg5NVx4OTZceGE0XXxceDk3W1x4YmItXHhiZl18XHg5OFtceDgwLVx4YmZdfFx4OTlbXHg4MC1ceDhmXXxceDlhW1x4ODAtXHhiZl18XHg5YltceDgwLVx4ODVceDhjXHg5MC1ceDkyXHhhYlx4YWNceGI0LVx4YjhdfFx4YTRbXHg5MC1ceGJlXXxceGE1W1x4ODAtXHg4Y1x4OTAtXHhhYl18XHhhNltceDgwLVx4OTddfFx4YTdbXHg4MFx4OTAtXHhhNl0pfFtceGEwLVx4YWVdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGFmKD86W1x4ODAtXHhiZV1bXHg4MC1ceGJmXXxceGJmW1x4ODAtXHhiZF0pfFtceGIwLVx4YmVdW1x4ODAtXHhiZl1bXHg4MC1ceGJmXXxceGJmKD86W1x4ODAtXHhiZV1bXHg4MC1ceGJmXXxceGJmW1x4ODAtXHhiZF0pKS8nOyAvLyAxODE3MzggY29kZSBwb2ludHMuCgovLyBHZW5lcmF0ZWQgYnkgImdlbl9jYXRfcmVnZXhfYWx0cy5waHAiIGZyb20gImh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzEwLjAuMC91Y2QvVW5pY29kZURhdGEudHh0Ii4KJG1fcmVnZXggPSAnL1x4Y2NbXHg4MC1ceGJmXXxceGNkW1x4ODAtXHhhZl18XHhkMltceDgzLVx4ODldfFx4ZDZbXHg5MS1ceGJkXHhiZl18XHhkN1tceDgxXHg4Mlx4ODRceDg1XHg4N118XHhkOFtceDkwLVx4OWFdfFx4ZDlbXHg4Yi1ceDlmXHhiMF18XHhkYltceDk2LVx4OWNceDlmLVx4YTRceGE3XHhhOFx4YWEtXHhhZF18XHhkY1tceDkxXHhiMC1ceGJmXXxceGRkW1x4ODAtXHg4YV18XHhkZVtceGE2LVx4YjBdfFx4ZGZbXHhhYi1ceGIzXXxceGUwKD86XHhhMFtceDk2LVx4OTlceDliLVx4YTNceGE1LVx4YTdceGE5LVx4YWRdfFx4YTFbXHg5OS1ceDliXXxceGEzW1x4OTQtXHhhMVx4YTMtXHhiZl18XHhhNFtceDgwLVx4ODNceGJhLVx4YmNceGJlXHhiZl18XHhhNVtceDgwLVx4OGZceDkxLVx4OTdceGEyXHhhM118XHhhNltceDgxLVx4ODNceGJjXHhiZVx4YmZdfFx4YTdbXHg4MC1ceDg0XHg4N1x4ODhceDhiLVx4OGRceDk3XHhhMlx4YTNdfFx4YThbXHg4MS1ceDgzXHhiY1x4YmVceGJmXXxceGE5W1x4ODAtXHg4Mlx4ODdceDg4XHg4Yi1ceDhkXHg5MVx4YjBceGIxXHhiNV18XHhhYVtceDgxLVx4ODNceGJjXHhiZVx4YmZdfFx4YWJbXHg4MC1ceDg1XHg4Ny1ceDg5XHg4Yi1ceDhkXHhhMlx4YTNceGJhLVx4YmZdfFx4YWNbXHg4MS1ceDgzXHhiY1x4YmVceGJmXXxceGFkW1x4ODAtXHg4NFx4ODdceDg4XHg4Yi1ceDhkXHg5Nlx4OTdceGEyXHhhM118XHhhZVtceDgyXHhiZVx4YmZdfFx4YWZbXHg4MC1ceDgyXHg4Ni1ceDg4XHg4YS1ceDhkXHg5N118XHhiMFtceDgwLVx4ODNceGJlXHhiZl18XHhiMVtceDgwLVx4ODRceDg2LVx4ODhceDhhLVx4OGRceDk1XHg5Nlx4YTJceGEzXXxceGIyW1x4ODEtXHg4M1x4YmNceGJlXHhiZl18XHhiM1tceDgwLVx4ODRceDg2LVx4ODhceDhhLVx4OGRceDk1XHg5Nlx4YTJceGEzXXxceGI0W1x4ODAtXHg4M1x4YmJceGJjXHhiZVx4YmZdfFx4YjVbXHg4MC1ceDg0XHg4Ni1ceDg4XHg4YS1ceDhkXHg5N1x4YTJceGEzXXxceGI2W1x4ODJceDgzXXxceGI3W1x4OGFceDhmLVx4OTRceDk2XHg5OC1ceDlmXHhiMlx4YjNdfFx4YjhbXHhiMVx4YjQtXHhiYV18XHhiOVtceDg3LVx4OGVdfFx4YmFbXHhiMVx4YjQtXHhiOVx4YmJceGJjXXxceGJiW1x4ODgtXHg4ZF18XHhiY1tceDk4XHg5OVx4YjVceGI3XHhiOVx4YmVceGJmXXxceGJkW1x4YjEtXHhiZl18XHhiZVtceDgwLVx4ODRceDg2XHg4N1x4OGQtXHg5N1x4OTktXHhiY118XHhiZlx4ODYpfFx4ZTEoPzpceDgwW1x4YWItXHhiZV18XHg4MVtceDk2LVx4OTlceDllLVx4YTBceGEyLVx4YTRceGE3LVx4YWRceGIxLVx4YjRdfFx4ODJbXHg4Mi1ceDhkXHg4Zlx4OWEtXHg5ZF18XHg4ZFtceDlkLVx4OWZdfFx4OWNbXHg5Mi1ceDk0XHhiMi1ceGI0XXxceDlkW1x4OTJceDkzXHhiMlx4YjNdfFx4OWVbXHhiNC1ceGJmXXxceDlmW1x4ODAtXHg5M1x4OWRdfFx4YTBbXHg4Yi1ceDhkXXxceGEyW1x4ODVceDg2XHhhOV18XHhhNFtceGEwLVx4YWJceGIwLVx4YmJdfFx4YThbXHg5Ny1ceDliXXxceGE5W1x4OTUtXHg5ZVx4YTAtXHhiY1x4YmZdfFx4YWFbXHhiMC1ceGJlXXxceGFjW1x4ODAtXHg4NFx4YjQtXHhiZl18XHhhZFtceDgwLVx4ODRceGFiLVx4YjNdfFx4YWVbXHg4MC1ceDgyXHhhMS1ceGFkXXxceGFmW1x4YTYtXHhiM118XHhiMFtceGE0LVx4YjddfFx4YjNbXHg5MC1ceDkyXHg5NC1ceGE4XHhhZFx4YjItXHhiNFx4YjctXHhiOV18XHhiN1tceDgwLVx4YjlceGJiLVx4YmZdKXxceGUyKD86XHg4M1tceDkwLVx4YjBdfFx4YjNbXHhhZi1ceGIxXXxceGI1XHhiZnxceGI3W1x4YTAtXHhiZl0pfFx4ZTMoPzpceDgwW1x4YWEtXHhhZl18XHg4MltceDk5XHg5YV0pfFx4ZWEoPzpceDk5W1x4YWYtXHhiMlx4YjQtXHhiZF18XHg5YVtceDllXHg5Zl18XHg5YltceGIwXHhiMV18XHhhMFtceDgyXHg4Nlx4OGJceGEzLVx4YTddfFx4YTJbXHg4MFx4ODFceGI0LVx4YmZdfFx4YTNbXHg4MC1ceDg1XHhhMC1ceGIxXXxceGE0W1x4YTYtXHhhZF18XHhhNVtceDg3LVx4OTNdfFx4YTZbXHg4MC1ceDgzXHhiMy1ceGJmXXxceGE3W1x4ODBceGE1XXxceGE4W1x4YTktXHhiNl18XHhhOVtceDgzXHg4Y1x4OGRceGJiLVx4YmRdfFx4YWFbXHhiMFx4YjItXHhiNFx4YjdceGI4XHhiZVx4YmZdfFx4YWJbXHg4MVx4YWItXHhhZlx4YjVceGI2XXxceGFmW1x4YTMtXHhhYVx4YWNceGFkXSl8XHhlZig/Olx4YWNceDllfFx4YjhbXHg4MC1ceDhmXHhhMC1ceGFmXSl8XHhmMCg/Olx4OTAoPzpceDg3XHhiZHxceDhiXHhhMHxceDhkW1x4YjYtXHhiYV18XHhhOFtceDgxLVx4ODNceDg1XHg4Nlx4OGMtXHg4Zlx4YjgtXHhiYVx4YmZdfFx4YWJbXHhhNVx4YTZdKXxceDkxKD86XHg4MFtceDgwLVx4ODJceGI4LVx4YmZdfFx4ODFbXHg4MC1ceDg2XHhiZl18XHg4MltceDgwLVx4ODJceGIwLVx4YmFdfFx4ODRbXHg4MC1ceDgyXHhhNy1ceGI0XXxceDg1XHhiM3xceDg2W1x4ODAtXHg4Mlx4YjMtXHhiZl18XHg4N1tceDgwXHg4YS1ceDhjXXxceDg4W1x4YWMtXHhiN1x4YmVdfFx4OGJbXHg5Zi1ceGFhXXxceDhjW1x4ODAtXHg4M1x4YmNceGJlXHhiZl18XHg4ZFtceDgwLVx4ODRceDg3XHg4OFx4OGItXHg4ZFx4OTdceGEyXHhhM1x4YTYtXHhhY1x4YjAtXHhiNF18XHg5MFtceGI1LVx4YmZdfFx4OTFbXHg4MC1ceDg2XXxceDkyW1x4YjAtXHhiZl18XHg5M1tceDgwLVx4ODNdfFx4OTZbXHhhZi1ceGI1XHhiOC1ceGJmXXxceDk3W1x4ODBceDljXHg5ZF18XHg5OFtceGIwLVx4YmZdfFx4OTlceDgwfFx4OWFbXHhhYi1ceGI3XXxceDljW1x4OWQtXHhhYl18XHhhOFtceDgxLVx4OGFceGIzLVx4YjlceGJiLVx4YmVdfFx4YTlbXHg4N1x4OTEtXHg5Yl18XHhhYVtceDhhLVx4OTldfFx4YjBbXHhhZi1ceGI2XHhiOC1ceGJmXXxceGIyW1x4OTItXHhhN1x4YTktXHhiNl18XHhiNFtceGIxLVx4YjZceGJhXHhiY1x4YmRceGJmXXxceGI1W1x4ODAtXHg4NVx4ODddKXxceDk2KD86XHhhYltceGIwLVx4YjRdfFx4YWNbXHhiMC1ceGI2XXxceGJkW1x4OTEtXHhiZV18XHhiZVtceDhmLVx4OTJdKXxceDliXHhiMltceDlkXHg5ZV18XHg5ZCg/Olx4ODVbXHhhNS1ceGE5XHhhZC1ceGIyXHhiYi1ceGJmXXxceDg2W1x4ODAtXHg4Mlx4ODUtXHg4Ylx4YWEtXHhhZF18XHg4OVtceDgyLVx4ODRdfFx4YThbXHg4MC1ceGI2XHhiYi1ceGJmXXxceGE5W1x4ODAtXHhhY1x4YjVdfFx4YWFbXHg4NFx4OWItXHg5Zlx4YTEtXHhhZl0pfFx4OWUoPzpceDgwW1x4ODAtXHg4Nlx4ODgtXHg5OFx4OWItXHhhMVx4YTNceGE0XHhhNi1ceGFhXXxceGEzW1x4OTAtXHg5Nl18XHhhNVtceDg0LVx4OGFdKSl8XHhmM1x4YTAoPzpbXHg4NC1ceDg2XVtceDgwLVx4YmZdfFx4ODdbXHg4MC1ceGFmXSkvJzsgLy8gMjE3NyBjb2RlIHBvaW50cy4KPD9waHAKLyoqCiAqIEFuIGV4YW1wbGUgYXBwbGljYXRpb24gdXNpbmcgcGhwLWNsaS10b29scyBhbmQgQnV6egogKi8KCnJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKCmRlZmluZSgnQlVaWl9QQVRIJywgcmVhbHBhdGgoJy4uL0J1enonKSk7CmRlZmluZSgnU0NSSVBUX05BTUUnLCBhcnJheV9zaGlmdCgkYXJndikpOwoKcmVxdWlyZV9vbmNlIEJVWlpfUEFUSCAuICcvbGliL0J1enovQ2xhc3NMb2FkZXIucGhwJzsKQnV6elxDbGFzc0xvYWRlcjo6cmVnaXN0ZXIoKTsKCmNsYXNzIEh0dHBDb25zb2xlIHsKICAgIHByb3RlY3RlZCAkX2hvc3Q7CiAgICBwcm90ZWN0ZWQgJF9wcm9tcHQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRob3N0KSB7CiAgICAgICAgJHRoaXMtPl9ob3N0ID0gJ2h0dHA6Ly8nIC4gJGhvc3Q7CiAgICAgICAgJHRoaXMtPl9wcm9tcHQgPSAnJUsnIC4gJHRoaXMtPl9ob3N0IC4gJyVuLyVLPiVuICc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3QoJHR5cGUsICRwYXRoKSB7CiAgICAgICAgJHJlcXVlc3QgPSBuZXcgQnV6elxNZXNzYWdlXFJlcXVlc3QoJHR5cGUsICRwYXRoLCAkdGhpcy0+X2hvc3QpOwogICAgICAgICRyZXNwb25zZSA9IG5ldyBCdXp6XE1lc3NhZ2VcUmVzcG9uc2U7CgogICAgICAgICRjbGllbnQgPSBuZXcgQnV6elxDbGllbnRcRmlsZUdldENvbnRlbnRzKCk7CiAgICAgICAgJGNsaWVudC0+c2VuZCgkcmVxdWVzdCwgJHJlc3BvbnNlKTsKCiAgICAgICAgLy8gRGlzcGxheSBoZWFkZXJzCiAgICAgICAgZm9yZWFjaCAoJHJlc3BvbnNlLT5nZXRIZWFkZXJzKCkgYXMgJGkgPT4gJGhlYWRlcikgewogICAgICAgICAgICBpZiAoJGkgPT0gMCkgewogICAgICAgICAgICAgICAgXGNsaVxsaW5lKCclR3s6aGVhZGVyfSVuJywgY29tcGFjdCgnaGVhZGVyJykpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGV4cGxvZGUoJzogJywgJGhlYWRlciwgMik7CiAgICAgICAgICAgIFxjbGlcbGluZSgnJVd7OmtleX0lbjogezp2YWx1ZX0nLCBjb21wYWN0KCdrZXknLCAndmFsdWUnKSk7CiAgICAgICAgfQogICAgICAgIFxjbGlcbGluZSgiXG4iKTsKICAgICAgICBwcmludCAkcmVzcG9uc2UtPmdldENvbnRlbnQoKSAuICJcbiI7CgogICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJ1bigpIHsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkY21kID0gXGNsaVxwcm9tcHQoJHRoaXMtPl9wcm9tcHQsIGZhbHNlLCBudWxsKTsKCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXihIRUFEfEdFVHxQT1NUfFBVVHxERUxFVEUpIChcUyspJC8nLCAkY21kLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5oYW5kbGVSZXF1ZXN0KCRtYXRjaGVzWzFdLCAkbWF0Y2hlc1syXSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRjbWQgPT0gJ1xxJykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnRyeSB7CiAgICAkY29uc29sZSA9IG5ldyBIdHRwQ29uc29sZShhcnJheV9zaGlmdCgkYXJndikgPzogJzEyNy4wLjAuMTo4MCcpOwogICAgJGNvbnNvbGUtPnJ1bigpOwp9IGNhdGNoIChcRXhjZXB0aW9uICRlKSB7CiAgICBcY2xpXGVycigiXG5cbiVSIiAuICRlLT5nZXRNZXNzYWdlKCkgLiAiJW5cbiIpOwp9Cgo/Pgo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2Nyb25fYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfY3Jvbl9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX2Nyb25fYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2Nyb24nLCAnQ3Jvbl9Db21tYW5kJyApOwpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY3JvbiBldmVudCcsICdDcm9uX0V2ZW50X0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdjcm9uIHNjaGVkdWxlJywgJ0Nyb25fU2NoZWR1bGVfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogU2NoZWR1bGVzLCBydW5zLCBhbmQgZGVsZXRlcyBXUC1Dcm9uIGV2ZW50cy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2NoZWR1bGUgYSBuZXcgY3JvbiBldmVudAogKiAgICAgJCB3cCBjcm9uIGV2ZW50IHNjaGVkdWxlIGNyb25fdGVzdAogKiAgICAgU3VjY2VzczogU2NoZWR1bGVkIGV2ZW50IHdpdGggaG9vayAnY3Jvbl90ZXN0JyBmb3IgMjAxNi0wNS0zMSAxMDoxOToxNiBHTVQuCiAqCiAqICAgICAjIFJ1biBhbGwgY3JvbiBldmVudHMgZHVlIHJpZ2h0IG5vdwogKiAgICAgJCB3cCBjcm9uIGV2ZW50IHJ1biAtLWR1ZS1ub3cKICogICAgIFN1Y2Nlc3M6IEV4ZWN1dGVkIGEgdG90YWwgb2YgMiBjcm9uIGV2ZW50cy4KICoKICogICAgICMgRGVsZXRlIGFsbCBzY2hlZHVsZWQgY3JvbiBldmVudHMgZm9yIHRoZSBnaXZlbiBob29rCiAqICAgICAkIHdwIGNyb24gZXZlbnQgZGVsZXRlIGNyb25fdGVzdAogKiAgICAgU3VjY2VzczogRGVsZXRlZCAyIGluc3RhbmNlcyBvZiB0aGUgY3JvbiBldmVudCAnY3Jvbl90ZXN0Jy4KICoKICogICAgICMgTGlzdCBzY2hlZHVsZWQgY3JvbiBldmVudHMgaW4gSlNPTgogKiAgICAgJCB3cCBjcm9uIGV2ZW50IGxpc3QgLS1maWVsZHM9aG9vayxuZXh0X3J1biAtLWZvcm1hdD1qc29uCiAqICAgICBbeyJob29rIjoid3BfdmVyc2lvbl9jaGVjayIsIm5leHRfcnVuIjoiMjAxNi0wNS0zMSAxMDoxNToxMyJ9LHsiaG9vayI6IndwX3VwZGF0ZV9wbHVnaW5zIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjEzIn0seyJob29rIjoid3BfdXBkYXRlX3RoZW1lcyIsIm5leHRfcnVuIjoiMjAxNi0wNS0zMSAxMDoxNToxNCJ9XQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENyb25fRXZlbnRfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRmaWVsZHMgPSBhcnJheSgKCQknaG9vaycsCgkJJ25leHRfcnVuX2dtdCcsCgkJJ25leHRfcnVuX3JlbGF0aXZlJywKCQkncmVjdXJyZW5jZScsCgkpOwoKCXByaXZhdGUgc3RhdGljICR0aW1lX2Zvcm1hdCA9ICdZLW0tZCBIOmk6cyc7CgoJLyoqCgkgKiBMaXN0cyBzY2hlZHVsZWQgY3JvbiBldmVudHMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmlsdGVyIGJ5IG9uZSBvciBtb3JlIGZpZWxkcy4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIGV2ZW50LgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGlkcwoJICogICAtIGpzb24KCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBjcm9uIGV2ZW50OgoJICogKiBob29rCgkgKiAqIG5leHRfcnVuX2dtdAoJICogKiBuZXh0X3J1bl9yZWxhdGl2ZQoJICogKiByZWN1cnJlbmNlCgkgKgoJICogVGhlc2UgZmllbGRzIGFyZSBvcHRpb25hbGx5IGF2YWlsYWJsZToKCSAqICogdGltZQoJICogKiBzaWcKCSAqICogYXJncwoJICogKiBzY2hlZHVsZQoJICogKiBpbnRlcnZhbAoJICogKiBuZXh0X3J1bgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBzY2hlZHVsZWQgY3JvbiBldmVudHMKCSAqICAgICAkIHdwIGNyb24gZXZlbnQgbGlzdAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICogICAgIHwgaG9vayAgICAgICAgICAgICAgfCBuZXh0X3J1bl9nbXQgICAgICAgIHwgbmV4dF9ydW5fcmVsYXRpdmUgICB8IHJlY3VycmVuY2UgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICogICAgIHwgd3BfdmVyc2lvbl9jaGVjayAgfCAyMDE2LTA1LTMxIDIyOjE1OjEzIHwgMTEgaG91cnMgNTcgbWludXRlcyB8IDEyIGhvdXJzICAgfAoJICogICAgIHwgd3BfdXBkYXRlX3BsdWdpbnMgfCAyMDE2LTA1LTMxIDIyOjE1OjEzIHwgMTEgaG91cnMgNTcgbWludXRlcyB8IDEyIGhvdXJzICAgfAoJICogICAgIHwgd3BfdXBkYXRlX3RoZW1lcyAgfCAyMDE2LTA1LTMxIDIyOjE1OjE0IHwgMTEgaG91cnMgNTcgbWludXRlcyB8IDEyIGhvdXJzICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICoKCSAqICAgICAjIExpc3Qgc2NoZWR1bGVkIGNyb24gZXZlbnRzIGluIEpTT04KCSAqICAgICAkIHdwIGNyb24gZXZlbnQgbGlzdCAtLWZpZWxkcz1ob29rLG5leHRfcnVuIC0tZm9ybWF0PWpzb24KCSAqICAgICBbeyJob29rIjoid3BfdmVyc2lvbl9jaGVjayIsIm5leHRfcnVuIjoiMjAxNi0wNS0zMSAxMDoxNToxMyJ9LHsiaG9vayI6IndwX3VwZGF0ZV9wbHVnaW5zIiwibmV4dF9ydW4iOiIyMDE2LTA1LTMxIDEwOjE1OjEzIn0seyJob29rIjoid3BfdXBkYXRlX3RoZW1lcyIsIm5leHRfcnVuIjoiMjAxNi0wNS0zMSAxMDoxNToxNCJ9XQoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoKCQkkZXZlbnRzID0gc2VsZjo6Z2V0X2Nyb25fZXZlbnRzKCk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRldmVudHMgKSApIHsKCQkJJGV2ZW50cyA9IGFycmF5KCk7CgkJfQoKCQlmb3JlYWNoICggJGV2ZW50cyBhcyAka2V5ID0+ICRldmVudCApIHsKCQkJZm9yZWFjaCAoICR0aGlzLT5maWVsZHMgYXMgJGZpZWxkICkgewoJCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gKSAmJiAkZXZlbnQtPnskZmllbGR9ICE9PSAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gKSB7CgkJCQkJdW5zZXQoICRldmVudHNbICRrZXkgXSApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiAoICdpZHMnID09PSAkZm9ybWF0dGVyLT5mb3JtYXQgKSB7CgkJCWVjaG8gaW1wbG9kZSggJyAnLCB3cF9saXN0X3BsdWNrKCAkZXZlbnRzLCAnaG9vaycgKSApOwoJCX0gZWxzZSB7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRldmVudHMgKTsKCQl9CgoJfQoKCS8qKgoJICogU2NoZWR1bGVzIGEgbmV3IGNyb24gZXZlbnQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxob29rPgoJICogOiBUaGUgaG9vayBuYW1lLgoJICoKCSAqIFs8bmV4dC1ydW4+XQoJICogOiBBIFVuaXggdGltZXN0YW1wIG9yIGFuIEVuZ2xpc2ggdGV4dHVhbCBkYXRldGltZSBkZXNjcmlwdGlvbiBjb21wYXRpYmxlIHdpdGggYHN0cnRvdGltZSgpYC4gRGVmYXVsdHMgdG8gbm93LgoJICoKCSAqIFs8cmVjdXJyZW5jZT5dCgkgKiA6IEhvdyBvZnRlbiB0aGUgZXZlbnQgc2hvdWxkIHJlY3VyLiBTZWUgYHdwIGNyb24gc2NoZWR1bGUgbGlzdGAgZm9yIGF2YWlsYWJsZSBzY2hlZHVsZSBuYW1lcy4gRGVmYXVsdHMgdG8gbm8gcmVjdXJyZW5jZS4KCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IEFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBob29rIGZvciB0aGUgZXZlbnQuIDxmaWVsZD4gc2hvdWxkIGJlIGEgbnVtZXJpYyBrZXksIG5vdCBhIHN0cmluZy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFNjaGVkdWxlIGEgbmV3IGNyb24gZXZlbnQKCSAqICAgICAkIHdwIGNyb24gZXZlbnQgc2NoZWR1bGUgY3Jvbl90ZXN0CgkgKiAgICAgU3VjY2VzczogU2NoZWR1bGVkIGV2ZW50IHdpdGggaG9vayAnY3Jvbl90ZXN0JyBmb3IgMjAxNi0wNS0zMSAxMDoxOToxNiBHTVQuCgkgKgoJICogICAgICMgU2NoZWR1bGUgbmV3IGNyb24gZXZlbnQgd2l0aCBob3VybHkgcmVjdXJyZW5jZQoJICogICAgICQgd3AgY3JvbiBldmVudCBzY2hlZHVsZSBjcm9uX3Rlc3Qgbm93IGhvdXJseQoJICogICAgIFN1Y2Nlc3M6IFNjaGVkdWxlZCBldmVudCB3aXRoIGhvb2sgJ2Nyb25fdGVzdCcgZm9yIDIwMTYtMDUtMzEgMTA6MjA6MzIgR01ULgoJICoKCSAqICAgICAjIFNjaGVkdWxlIG5ldyBjcm9uIGV2ZW50IGFuZCBwYXNzIGFyZ3VtZW50cwoJICogICAgICQgd3AgY3JvbiBldmVudCBzY2hlZHVsZSBjcm9uX3Rlc3QgJysxIGhvdXInIC0tMD1maXJzdC1hcmd1bWVudCAtLTE9c2Vjb25kLWFyZ3VtZW50CgkgKiAgICAgU3VjY2VzczogU2NoZWR1bGVkIGV2ZW50IHdpdGggaG9vayAnY3Jvbl90ZXN0JyBmb3IgMjAxNi0wNS0zMSAxMToyMTozNSBHTVQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzY2hlZHVsZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggY291bnQoICRhc3NvY19hcmdzICkgJiYgY291bnQoIGFycmF5X2ZpbHRlciggYXJyYXlfa2V5cyggJGFzc29jX2FyZ3MgKSwgJ2lzX3N0cmluZycgKSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdOdW1lcmljIGtleXMgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBob29rIGFyZ3VtZW50cy4nICk7CgkJfQoKCQkkaG9vayAgICAgICA9ICRhcmdzWzBdOwoJCSRuZXh0X3J1biAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAxLCAnbm93JyApOwoJCSRyZWN1cnJlbmNlID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAyLCBmYWxzZSApOwoKCQlpZiAoIGVtcHR5KCAkbmV4dF9ydW4gKSApIHsKCQkJJHRpbWVzdGFtcCA9IHRpbWUoKTsKCQl9IGVsc2VpZiAoIGlzX251bWVyaWMoICRuZXh0X3J1biApICkgewoJCQkkdGltZXN0YW1wID0gYWJzaW50KCAkbmV4dF9ydW4gKTsKCQl9IGVsc2UgewoJCQkkdGltZXN0YW1wID0gc3RydG90aW1lKCAkbmV4dF9ydW4gKTsKCQl9CgoJCWlmICggISAkdGltZXN0YW1wICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiJyVzJyBpcyBub3QgYSB2YWxpZCBkYXRldGltZS4iLCAkbmV4dF9ydW4gKSApOwoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkcmVjdXJyZW5jZSApICkgewoKCQkJJHNjaGVkdWxlcyA9IHdwX2dldF9zY2hlZHVsZXMoKTsKCgkJCWlmICggISBpc3NldCggJHNjaGVkdWxlc1sgJHJlY3VycmVuY2UgXSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIiclcycgaXMgbm90IGEgdmFsaWQgc2NoZWR1bGUgbmFtZSBmb3IgcmVjdXJyZW5jZS4iLCAkcmVjdXJyZW5jZSApICk7CgkJCX0KCgkJCSRldmVudCA9IHdwX3NjaGVkdWxlX2V2ZW50KCAkdGltZXN0YW1wLCAkcmVjdXJyZW5jZSwgJGhvb2ssICRhc3NvY19hcmdzICk7CgoJCX0gZWxzZSB7CgoJCQkkZXZlbnQgPSB3cF9zY2hlZHVsZV9zaW5nbGVfZXZlbnQoICR0aW1lc3RhbXAsICRob29rLCAkYXNzb2NfYXJncyApOwoKCQl9CgoJCWlmICggZmFsc2UgIT09ICRldmVudCApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAiU2NoZWR1bGVkIGV2ZW50IHdpdGggaG9vayAnJXMnIGZvciAlcyBHTVQuIiwgJGhvb2ssIGRhdGUoIHNlbGY6OiR0aW1lX2Zvcm1hdCwgJHRpbWVzdGFtcCApICkgKTsgLy9waHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJ0V2ZW50IG5vdCBzY2hlZHVsZWQuJyApOwoJCX0KCgl9CgoJLyoqCgkgKiBSdW5zIHRoZSBuZXh0IHNjaGVkdWxlZCBjcm9uIGV2ZW50IGZvciB0aGUgZ2l2ZW4gaG9vay4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxob29rPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgaG9va3MgdG8gcnVuLgoJICoKCSAqIFstLWR1ZS1ub3ddCgkgKiA6IFJ1biBhbGwgaG9va3MgZHVlIHJpZ2h0IG5vdy4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IFJ1biBhbGwgaG9va3MuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBSdW4gYWxsIGNyb24gZXZlbnRzIGR1ZSByaWdodCBub3cKCSAqICAgICAkIHdwIGNyb24gZXZlbnQgcnVuIC0tZHVlLW5vdwoJICogICAgIFN1Y2Nlc3M6IEV4ZWN1dGVkIGEgdG90YWwgb2YgMiBjcm9uIGV2ZW50cy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJ1biggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlpZiAoIGVtcHR5KCAkYXJncyApICYmICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHVlLW5vdycgKSAmJiAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IG9uZSBvciBtb3JlIGNyb24gZXZlbnRzLCBvciB1c2UgLS1kdWUtbm93Ly0tYWxsLicgKTsKCQl9CgoJCSRldmVudHMgPSBzZWxmOjpnZXRfY3Jvbl9ldmVudHMoKTsKCgkJaWYgKCBpc193cF9lcnJvciggJGV2ZW50cyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZXZlbnRzICk7CgkJfQoKCQkkaG9va3MgPSB3cF9saXN0X3BsdWNrKCAkZXZlbnRzLCAnaG9vaycgKTsKCQlmb3JlYWNoICggJGFyZ3MgYXMgJGhvb2sgKSB7CgkJCWlmICggISBpbl9hcnJheSggJGhvb2ssICRob29rcywgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkludmFsaWQgY3JvbiBldmVudCAnJXMnIiwgJGhvb2sgKSApOwoJCQl9CgkJfQoKCQlpZiAoIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2R1ZS1ub3cnICkgKSB7CgkJCSRkdWVfZXZlbnRzID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoICRldmVudHMgYXMgJGV2ZW50ICkgewoJCQkJaWYgKCAhIGVtcHR5KCAkYXJncyApICYmICEgaW5fYXJyYXkoICRldmVudC0+aG9vaywgJGFyZ3MsIHRydWUgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWlmICggdGltZSgpID49ICRldmVudC0+dGltZSApIHsKCQkJCQkkZHVlX2V2ZW50c1tdID0gJGV2ZW50OwoJCQkJfQoJCQl9CgkJCSRldmVudHMgPSAkZHVlX2V2ZW50czsKCQl9IGVsc2VpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJyApICkgewoJCQkkZHVlX2V2ZW50cyA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCAkZXZlbnRzIGFzICRldmVudCApIHsKCQkJCWlmICggaW5fYXJyYXkoICRldmVudC0+aG9vaywgJGFyZ3MsIHRydWUgKSApIHsKCQkJCQkkZHVlX2V2ZW50c1tdID0gJGV2ZW50OwoJCQkJfQoJCQl9CgkJCSRldmVudHMgPSAkZHVlX2V2ZW50czsKCQl9CgoJCSRleGVjdXRlZCA9IDA7CgkJZm9yZWFjaCAoICRldmVudHMgYXMgJGV2ZW50ICkgewoJCQkkc3RhcnQgID0gbWljcm90aW1lKCB0cnVlICk7CgkJCSRyZXN1bHQgPSBzZWxmOjpydW5fZXZlbnQoICRldmVudCApOwoJCQkkdG90YWwgID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gJHN0YXJ0LCAzICk7CgkJCSRleGVjdXRlZCsrOwoJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggIkV4ZWN1dGVkIHRoZSBjcm9uIGV2ZW50ICclcycgaW4gJXNzLiIsICRldmVudC0+aG9vaywgJHRvdGFsICkgKTsKCQl9CgoJCSRtZXNzYWdlID0gKCAxID09PSAkZXhlY3V0ZWQgKSA/ICdFeGVjdXRlZCBhIHRvdGFsIG9mICVkIGNyb24gZXZlbnQuJyA6ICdFeGVjdXRlZCBhIHRvdGFsIG9mICVkIGNyb24gZXZlbnRzLic7CgkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkbWVzc2FnZSwgJGV4ZWN1dGVkICkgKTsKCX0KCgkvKioKCSAqIFVuc2NoZWR1bGVzIGFsbCBjcm9uIGV2ZW50cyBmb3IgYSBnaXZlbiBob29rLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8aG9vaz4KCSAqIDogTmFtZSBvZiB0aGUgaG9vayBmb3Igd2hpY2ggYWxsIGV2ZW50cyBzaG91bGQgYmUgdW5zY2hlZHVsZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVbnNjaGVkdWxlIGEgY3JvbiBldmVudCBvbiBnaXZlbiBob29rLgoJICogICAgICQgd3AgY3JvbiBldmVudCB1bnNjaGVkdWxlIGNyb25fdGVzdAoJICogICAgIFN1Y2Nlc3M6IFVuc2NoZWR1bGVkIDIgZXZlbnRzIHdpdGggaG9vayAnY3Jvbl90ZXN0Jy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuc2NoZWR1bGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJbGlzdCggJGhvb2sgKSA9ICRhcmdzOwoKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuOS4wJywgJzwnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdVbnNjaGVkdWxpbmcgZXZlbnRzIGlzIG9ubHkgc3VwcG9ydGVkIGZyb20gV29yZFByZXNzIDQuOS4wIG9ud2FyZHMuJyApOwoJCX0KCgkJJHVuc2NoZWR1bGVkID0gd3BfdW5zY2hlZHVsZV9ob29rKCAkaG9vayApOwoKCQlpZiAoIGVtcHR5KCAkdW5zY2hlZHVsZWQgKSApIHsKCQkJJG1lc3NhZ2UgPSAnRmFpbGVkIHRvIHVuc2NoZWR1bGUgZXZlbnRzIGZvciBob29rIFwnJTFcJHMuJzsKCgkJCS8vIElmIDAgZXZlbnQgZm91bmQgb24gaG9vay4KCQkJaWYgKCAwID09PSAkdW5zY2hlZHVsZWQgKSB7CgkJCQkkbWVzc2FnZSA9ICJObyBldmVudHMgZm91bmQgZm9yIGhvb2sgJyUxXCRzJy4iOwoJCQl9CgoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAkbWVzc2FnZSwgJGhvb2sgKSApOwoKCQl9IGVsc2UgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoCgkJCQlzcHJpbnRmKAoJCQkJCSdVbnNjaGVkdWxlZCAlMSRkICUyJHMgZm9yIGhvb2sgXCclMyRzXCcuJywKCQkJCQkkdW5zY2hlZHVsZWQsCgkJCQkJVXRpbHNccGx1cmFsaXplKCAnZXZlbnQnLCAkdW5zY2hlZHVsZWQgKSwKCQkJCQkkaG9vawoJCQkJKQoJCQkpOwoJCX0KCgl9CgoJLyoqCgkgKiBFeGVjdXRlcyBhbiBldmVudCBpbW1lZGlhdGVseS4KCSAqCgkgKiBAcGFyYW0gc3RkQ2xhc3MgJGV2ZW50IFRoZSBldmVudAoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGV2ZW50IHdhcyBzdWNjZXNzZnVsbHkgZXhlY3V0ZWQgb3Igbm90LgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHJ1bl9ldmVudCggc3RkQ2xhc3MgJGV2ZW50ICkgewoKCQlpZiAoICEgZGVmaW5lZCggJ0RPSU5HX0NST04nICkgKSB7CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZENvbnN0YW50Rm91bmQgLS0gVXNpbmcgbmF0aXZlIFdvcmRQcmVzcyBjb25zdGFudC4KCQkJZGVmaW5lKCAnRE9JTkdfQ1JPTicsIHRydWUgKTsKCQl9CgoJCWlmICggZmFsc2UgIT09ICRldmVudC0+c2NoZWR1bGUgKSB7CgkJCSRuZXdfYXJncyA9IGFycmF5KCAkZXZlbnQtPnRpbWUsICRldmVudC0+c2NoZWR1bGUsICRldmVudC0+aG9vaywgJGV2ZW50LT5hcmdzICk7CgkJCWNhbGxfdXNlcl9mdW5jX2FycmF5KCAnd3BfcmVzY2hlZHVsZV9ldmVudCcsICRuZXdfYXJncyApOwoJCX0KCgkJd3BfdW5zY2hlZHVsZV9ldmVudCggJGV2ZW50LT50aW1lLCAkZXZlbnQtPmhvb2ssICRldmVudC0+YXJncyApOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuRHluYW1pY0hvb2tuYW1lRm91bmQgLS0gQ2FuJ3QgcHJlZml4IGR5bmFtaWMgaG9va3MgaGVyZSwgY2FsbGluZyByZWdpc3RlcmVkIGhvb2tzLgoJCWRvX2FjdGlvbl9yZWZfYXJyYXkoICRldmVudC0+aG9vaywgJGV2ZW50LT5hcmdzICk7CgoJCXJldHVybiB0cnVlOwoKCX0KCgkvKioKCSAqIERlbGV0ZXMgYWxsIHNjaGVkdWxlZCBjcm9uIGV2ZW50cyBmb3IgdGhlIGdpdmVuIGhvb2suCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxob29rPgoJICogOiBUaGUgaG9vayBuYW1lLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGFsbCBzY2hlZHVsZWQgY3JvbiBldmVudHMgZm9yIHRoZSBnaXZlbiBob29rCgkgKiAgICAgJCB3cCBjcm9uIGV2ZW50IGRlbGV0ZSBjcm9uX3Rlc3QKCSAqICAgICBTdWNjZXNzOiBEZWxldGVkIDIgaW5zdGFuY2VzIG9mIHRoZSBjcm9uIGV2ZW50ICdjcm9uX3Rlc3QnLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRob29rICAgPSAkYXJnc1swXTsKCQkkZXZlbnRzID0gc2VsZjo6Z2V0X2Nyb25fZXZlbnRzKCk7CgoJCWlmICggaXNfd3BfZXJyb3IoICRldmVudHMgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGV2ZW50cyApOwoJCX0KCgkJJGRlbGV0ZWQgPSAwOwoJCWZvcmVhY2ggKCAkZXZlbnRzIGFzICRldmVudCApIHsKCQkJaWYgKCAkZXZlbnQtPmhvb2sgPT09ICRob29rICkgewoJCQkJJHJlc3VsdCA9IHNlbGY6OmRlbGV0ZV9ldmVudCggJGV2ZW50ICk7CgkJCQlpZiAoICRyZXN1bHQgKSB7CgkJCQkJJGRlbGV0ZWQrKzsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiRmFpbGVkIHRvIHRoZSBkZWxldGUgdGhlIGNyb24gZXZlbnQgJyVzJy4iLCAkaG9vayApICk7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJGRlbGV0ZWQgKSB7CgkJCSRtZXNzYWdlID0gKCAxID09PSAkZGVsZXRlZCApID8gIkRlbGV0ZWQgdGhlIGNyb24gZXZlbnQgJyUyXCRzJy4iIDogIkRlbGV0ZWQgJTFcJGQgaW5zdGFuY2VzIG9mIHRoZSBjcm9uIGV2ZW50ICclMlwkcycuIjsKCQkJV1BfQ0xJOjpzdWNjZXNzKCBzcHJpbnRmKCAkbWVzc2FnZSwgJGRlbGV0ZWQsICRob29rICkgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBjcm9uIGV2ZW50ICclcycuIiwgJGhvb2sgKSApOwoJCX0KCgl9CgoJLyoqCgkgKiBEZWxldGVzIGEgY3JvbiBldmVudC4KCSAqCgkgKiBAcGFyYW0gc3RkQ2xhc3MgJGV2ZW50IFRoZSBldmVudAoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGV2ZW50IHdhcyBzdWNjZXNzZnVsbHkgZGVsZXRlZCBvciBub3QuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZGVsZXRlX2V2ZW50KCBzdGRDbGFzcyAkZXZlbnQgKSB7CgkJJGNyb25zID0gX2dldF9jcm9uX2FycmF5KCk7CgoJCWlmICggISBpc3NldCggJGNyb25zWyAkZXZlbnQtPnRpbWUgXVsgJGV2ZW50LT5ob29rIF1bICRldmVudC0+c2lnIF0gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJd3BfdW5zY2hlZHVsZV9ldmVudCggJGV2ZW50LT50aW1lLCAkZXZlbnQtPmhvb2ssICRldmVudC0+YXJncyApOwoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQ2FsbGJhY2sgZnVuY3Rpb24gdG8gZm9ybWF0IGEgY3JvbiBldmVudC4KCSAqCgkgKiBAcGFyYW0gc3RkQ2xhc3MgJGV2ZW50IFRoZSBldmVudC4KCSAqIEByZXR1cm4gc3RkQ2xhc3MgVGhlIGZvcm1hdHRlZCBldmVudCBvYmplY3QuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZm9ybWF0X2V2ZW50KCBzdGRDbGFzcyAkZXZlbnQgKSB7CgoJCSRldmVudC0+bmV4dF9ydW4gICAgICAgICAgPSBnZXRfZGF0ZV9mcm9tX2dtdCggZGF0ZSggJ1ktbS1kIEg6aTpzJywgJGV2ZW50LT50aW1lICksIHNlbGY6OiR0aW1lX2Zvcm1hdCApOyAvL3BocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy5kYXRlX2RhdGUKCQkkZXZlbnQtPm5leHRfcnVuX2dtdCAgICAgID0gZGF0ZSggc2VsZjo6JHRpbWVfZm9ybWF0LCAkZXZlbnQtPnRpbWUgKTsgLy9waHBjczppZ25vcmUgV29yZFByZXNzLkRhdGVUaW1lLlJlc3RyaWN0ZWRGdW5jdGlvbnMuZGF0ZV9kYXRlCgkJJGV2ZW50LT5uZXh0X3J1bl9yZWxhdGl2ZSA9IHNlbGY6OmludGVydmFsKCAkZXZlbnQtPnRpbWUgLSB0aW1lKCkgKTsKCQkkZXZlbnQtPnJlY3VycmVuY2UgICAgICAgID0gKCAkZXZlbnQtPnNjaGVkdWxlICkgPyBzZWxmOjppbnRlcnZhbCggJGV2ZW50LT5pbnRlcnZhbCApIDogJ05vbi1yZXBlYXRpbmcnOwoKCQlyZXR1cm4gJGV2ZW50OwoJfQoKCS8qKgoJICogRmV0Y2hlcyBhbiBhcnJheSBvZiBzY2hlZHVsZWQgY3JvbiBldmVudHMuCgkgKgoJICogQHJldHVybiBhcnJheXxXUF9FcnJvciBBbiBhcnJheSBvZiBldmVudCBvYmplY3RzLCBvciBhIFdQX0Vycm9yIG9iamVjdCBpZiB0aGVyZSBhcmUgbm8gZXZlbnRzIHNjaGVkdWxlZC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRfY3Jvbl9ldmVudHMoKSB7CgoJCSRjcm9ucyAgPSBfZ2V0X2Nyb25fYXJyYXkoKTsKCQkkZXZlbnRzID0gYXJyYXkoKTsKCgkJaWYgKCBlbXB0eSggJGNyb25zICkgKSB7CgkJCXJldHVybiBuZXcgV1BfRXJyb3IoCgkJCQknbm9fZXZlbnRzJywKCQkJCSdZb3UgY3VycmVudGx5IGhhdmUgbm8gc2NoZWR1bGVkIGNyb24gZXZlbnRzLicKCQkJKTsKCQl9CgoJCWZvcmVhY2ggKCAkY3JvbnMgYXMgJHRpbWUgPT4gJGhvb2tzICkgewoJCQlmb3JlYWNoICggJGhvb2tzIGFzICRob29rID0+ICRob29rX2V2ZW50cyApIHsKCQkJCWZvcmVhY2ggKCAkaG9va19ldmVudHMgYXMgJHNpZyA9PiAkZGF0YSApIHsKCgkJCQkJJGV2ZW50c1tdID0gKG9iamVjdCkgYXJyYXkoCgkJCQkJCSdob29rJyAgICAgPT4gJGhvb2ssCgkJCQkJCSd0aW1lJyAgICAgPT4gJHRpbWUsCgkJCQkJCSdzaWcnICAgICAgPT4gJHNpZywKCQkJCQkJJ2FyZ3MnICAgICA9PiAkZGF0YVsnYXJncyddLAoJCQkJCQknc2NoZWR1bGUnID0+ICRkYXRhWydzY2hlZHVsZSddLAoJCQkJCQknaW50ZXJ2YWwnID0+IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkZGF0YSwgJ2ludGVydmFsJyApLAoJCQkJCSk7CgoJCQkJfQoJCQl9CgkJfQoKCQkkZXZlbnRzID0gYXJyYXlfbWFwKCAnQ3Jvbl9FdmVudF9Db21tYW5kOjpmb3JtYXRfZXZlbnQnLCAkZXZlbnRzICk7CgoJCXJldHVybiAkZXZlbnRzOwoKCX0KCgkvKioKCSAqIENvbnZlcnRzIGEgdGltZSBpbnRlcnZhbCBpbnRvIGh1bWFuLXJlYWRhYmxlIGZvcm1hdC4KCSAqCgkgKiBTaW1pbGFyIHRvIFdvcmRQcmVzcycgYnVpbHQtaW4gYGh1bWFuX3RpbWVfZGlmZigpYCBidXQgcmV0dXJucyB0d28gdGltZSBwZXJpb2QgY2h1bmtzIGluc3RlYWQgb2YganVzdCBvbmUuCgkgKgoJICogQHBhcmFtIGludCAkc2luY2UgQW4gaW50ZXJ2YWwgb2YgdGltZSBpbiBzZWNvbmRzCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgaW50ZXJ2YWwgaW4gaHVtYW4gcmVhZGFibGUgZm9ybWF0CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGludGVydmFsKCAkc2luY2UgKSB7CgkJaWYgKCAkc2luY2UgPD0gMCApIHsKCQkJcmV0dXJuICdub3cnOwoJCX0KCgkJJHNpbmNlID0gYWJzaW50KCAkc2luY2UgKTsKCgkJLy8gQXJyYXkgb2YgdGltZSBwZXJpb2QgY2h1bmtzLgoJCSRjaHVua3MgPSBhcnJheSgKCQkJYXJyYXkoIDYwICogNjAgKiAyNCAqIDM2NSwgJ3llYXInICksCgkJCWFycmF5KCA2MCAqIDYwICogMjQgKiAzMCwgJ21vbnRoJyApLAoJCQlhcnJheSggNjAgKiA2MCAqIDI0ICogNywgJ3dlZWsnICksCgkJCWFycmF5KCA2MCAqIDYwICogMjQsICdkYXknICksCgkJCWFycmF5KCA2MCAqIDYwLCAnaG91cicgKSwKCQkJYXJyYXkoIDYwLCAnbWludXRlJyApLAoJCQlhcnJheSggMSwgJ3NlY29uZCcgKSwKCQkpOwoKCQkvLyB3ZSBvbmx5IHdhbnQgdG8gb3V0cHV0IHR3byBjaHVua3Mgb2YgdGltZSBoZXJlLCBlZzoKCQkvLyB4IHllYXJzLCB4eCBtb250aHMKCQkvLyB4IGRheXMsIHh4IGhvdXJzCgkJLy8gc28gdGhlcmUncyBvbmx5IHR3byBiaXRzIG9mIGNhbGN1bGF0aW9uIGJlbG93OgoKCQkvLyBzdGVwIG9uZTogdGhlIGZpcnN0IGNodW5rCgkJZm9yICggJGkgPSAwLCAkaiA9IGNvdW50KCAkY2h1bmtzICk7ICRpIDwgJGo7ICRpKysgKSB7CgkJCSRzZWNvbmRzID0gJGNodW5rc1sgJGkgXVswXTsKCQkJJG5hbWUgICAgPSAkY2h1bmtzWyAkaSBdWzFdOwoKCQkJLy8gRmluZGluZyB0aGUgYmlnZ2VzdCBjaHVuayAoaWYgdGhlIGNodW5rIGZpdHMsIGJyZWFrKS4KCQkJJGNvdW50ID0gZmxvb3IoICRzaW5jZSAvICRzZWNvbmRzICk7CgkJCWlmICggZmxvYXR2YWwoIDAgKSAhPT0gJGNvdW50ICkgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCS8vIFNldCBvdXRwdXQgdmFyLgoJCSRvdXRwdXQgPSBzcHJpbnRmKCAnJWQgJXMnLCAkY291bnQsIFV0aWxzXHBsdXJhbGl6ZSggJG5hbWUsIGFic2ludCggJGNvdW50ICkgKSApOwoKCQkvLyBTdGVwIHR3bzogdGhlIHNlY29uZCBjaHVuay4KCQlpZiAoICRpICsgMSA8ICRqICkgewoJCQkkc2Vjb25kczIgPSAkY2h1bmtzWyAkaSArIDEgXVswXTsKCQkJJG5hbWUyICAgID0gJGNodW5rc1sgJGkgKyAxIF1bMV07CgoJCQkkY291bnQyID0gZmxvb3IoICggJHNpbmNlIC0gKCAkc2Vjb25kcyAqICRjb3VudCApICkgLyAkc2Vjb25kczIgKTsKCQkJaWYgKCBmbG9hdHZhbCggMCApICE9PSAkY291bnQyICkgewoJCQkJLy8gQWRkIHRvIG91dHB1dCB2YXIuCgkJCQkkb3V0cHV0IC49ICcgJyAuIHNwcmludGYoICclZCAlcycsICRjb3VudDIsIFV0aWxzXHBsdXJhbGl6ZSggJG5hbWUyLCBhYnNpbnQoICRjb3VudDIgKSApICk7CgkJCX0KCQl9CgoJCXJldHVybiAkb3V0cHV0OwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2Zvcm1hdHRlciggJiRhc3NvY19hcmdzICkgewoJCXJldHVybiBuZXcgXFdQX0NMSVxGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzLCAnZXZlbnQnICk7Cgl9Cgp9Cjw/cGhwCgovKioKICogVGVzdHMsIHJ1bnMsIGFuZCBkZWxldGVzIFdQLUNyb24gZXZlbnRzOyBtYW5hZ2VzIFdQLUNyb24gc2NoZWR1bGVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBUZXN0IFdQIENyb24gc3Bhd25pbmcgc3lzdGVtCiAqICAgICAkIHdwIGNyb24gdGVzdAogKiAgICAgU3VjY2VzczogV1AtQ3JvbiBzcGF3bmluZyBpcyB3b3JraW5nIGFzIGV4cGVjdGVkLgogKi8KY2xhc3MgQ3Jvbl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogVGVzdHMgdGhlIFdQIENyb24gc3Bhd25pbmcgc3lzdGVtIGFuZCByZXBvcnRzIGJhY2sgaXRzIHN0YXR1cy4KCSAqCgkgKiBUaGlzIGNvbW1hbmQgdGVzdHMgdGhlIHNwYXduaW5nIHN5c3RlbSBieSBwZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgc3RlcHM6CgkgKgoJICogKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBgRElTQUJMRV9XUF9DUk9OYCBjb25zdGFudCBpcyBzZXQ7IGVycm9ycyBpZiB0cnVlCgkgKiBiZWNhdXNlIFdQLUNyb24gaXMgZGlzYWJsZWQuCgkgKiAqIENoZWNrcyB0byBzZWUgaWYgdGhlIGBBTFRFUk5BVEVfV1BfQ1JPTmAgY29uc3RhbnQgaXMgc2V0OyB3YXJucyBpZiB0cnVlLgoJICogKiBBdHRlbXB0cyB0byBzcGF3biBXUC1Dcm9uIG92ZXIgSFRUUDsgd2FybnMgaWYgbm9uIDIwMCByZXNwb25zZSBjb2RlIGlzCgkgKiByZXR1cm5lZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENyb24gdGVzdCBydW5zIHN1Y2Nlc3NmdWxseS4KCSAqICAgICAkIHdwIGNyb24gdGVzdAoJICogICAgIFN1Y2Nlc3M6IFdQLUNyb24gc3Bhd25pbmcgaXMgd29ya2luZyBhcyBleHBlY3RlZC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHRlc3QoKSB7CgoJCWlmICggZGVmaW5lZCggJ0RJU0FCTEVfV1BfQ1JPTicgKSAmJiBESVNBQkxFX1dQX0NST04gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgRElTQUJMRV9XUF9DUk9OIGNvbnN0YW50IGlzIHNldCB0byB0cnVlLiBXUC1Dcm9uIHNwYXduaW5nIGlzIGRpc2FibGVkLicgKTsKCQl9CgoJCWlmICggZGVmaW5lZCggJ0FMVEVSTkFURV9XUF9DUk9OJyApICYmIEFMVEVSTkFURV9XUF9DUk9OICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICdUaGUgQUxURVJOQVRFX1dQX0NST04gY29uc3RhbnQgaXMgc2V0IHRvIHRydWUuIFdQLUNyb24gc3Bhd25pbmcgaXMgbm90IGFzeW5jaHJvbm91cy4nICk7CgkJfQoKCQkkc3Bhd24gPSBzZWxmOjpnZXRfY3Jvbl9zcGF3bigpOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkc3Bhd24gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ1dQLUNyb24gc3Bhd24gZmFpbGVkIHdpdGggZXJyb3I6ICVzJywgJHNwYXduLT5nZXRfZXJyb3JfbWVzc2FnZSgpICkgKTsKCQl9CgoJCSRjb2RlICAgID0gd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX2NvZGUoICRzcGF3biApOwoJCSRtZXNzYWdlID0gd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX21lc3NhZ2UoICRzcGF3biApOwoKCQlpZiAoIDIwMCA9PT0gJGNvZGUgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1dQLUNyb24gc3Bhd25pbmcgaXMgd29ya2luZyBhcyBleHBlY3RlZC4nICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnV1AtQ3JvbiBzcGF3biBzdWNjZWVkZWQgYnV0IHJldHVybmVkIEhUVFAgc3RhdHVzIGNvZGU6ICUxJHMgJTIkcycsICRjb2RlLCAkbWVzc2FnZSApICk7CgkJfQoKCX0KCgkvKioKCSAqIFNwYXducyBhIHJlcXVlc3QgdG8gYHdwLWNyb24ucGhwYCBhbmQgcmV0dXJuIHRoZSByZXNwb25zZS4KCSAqCgkgKiBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIG1pbWljIHRoZSBmdW5jdGlvbmFsaXR5IGluIGBzcGF3bl9jcm9uKClgCgkgKiB3aXRoIHRoZSBhZGRpdGlvbiBvZiByZXR1cm5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgYHdwX3JlbW90ZV9wb3N0KClgCgkgKiByZXF1ZXN0LgoJICoKCSAqIEByZXR1cm4gV1BfRXJyb3J8YXJyYXkgVGhlIHJlc3BvbnNlIG9yIFdQX0Vycm9yIG9uIGZhaWx1cmUuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0X2Nyb25fc3Bhd24oKSB7CgoJCSRzc2x2ZXJpZnkgICAgID0gXFdQX0NMSVxVdGlsc1x3cF92ZXJzaW9uX2NvbXBhcmUoIDQuMCwgJzwnICk7CgkJJGRvaW5nX3dwX2Nyb24gPSBzcHJpbnRmKCAnJS4yMkYnLCBtaWNyb3RpbWUoIHRydWUgKSApOwoKCQkkY3Jvbl9yZXF1ZXN0X2FycmF5ID0gYXJyYXkoCgkJCSd1cmwnICA9PiBzaXRlX3VybCggJ3dwLWNyb24ucGhwP2RvaW5nX3dwX2Nyb249JyAuICRkb2luZ193cF9jcm9uICksCgkJCSdrZXknICA9PiAkZG9pbmdfd3BfY3JvbiwKCQkJJ2FyZ3MnID0+IGFycmF5KAoJCQkJJ3RpbWVvdXQnICAgPT4gMywKCQkJCSdibG9ja2luZycgID0+IHRydWUsCgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIENhbGxpbmcgbmF0aXZlIFdvcmRQcmVzcyBob29rLgoJCQkJJ3NzbHZlcmlmeScgPT4gYXBwbHlfZmlsdGVycyggJ2h0dHBzX2xvY2FsX3NzbF92ZXJpZnknLCAkc3NsdmVyaWZ5ICksCgkJCSksCgkJKTsKCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5QcmVmaXhBbGxHbG9iYWxzLk5vblByZWZpeGVkSG9va25hbWVGb3VuZCAtLSBDYWxsaW5nIG5hdGl2ZSBXb3JkUHJlc3MgaG9vay4KCQkkY3Jvbl9yZXF1ZXN0ID0gYXBwbHlfZmlsdGVycyggJ2Nyb25fcmVxdWVzdCcsICRjcm9uX3JlcXVlc3RfYXJyYXkgKTsKCgkJIyBFbmZvcmNlIGEgYmxvY2tpbmcgcmVxdWVzdCBpbiBjYXNlIHNvbWV0aGluZyB0aGF0J3MgaG9va2VkIG9udG8gdGhlICdjcm9uX3JlcXVlc3QnIGZpbHRlciBzZXRzIGl0IHRvIGZhbHNlCgkJJGNyb25fcmVxdWVzdFsnYXJncyddWydibG9ja2luZyddID0gdHJ1ZTsKCgkJJHJlc3VsdCA9IHdwX3JlbW90ZV9wb3N0KCAkY3Jvbl9yZXF1ZXN0Wyd1cmwnXSwgJGNyb25fcmVxdWVzdFsnYXJncyddICk7CgoJCXJldHVybiAkcmVzdWx0OwoKCX0KCn0KPD9waHAKCi8qKgogKiBHZXRzIFdQLUNyb24gc2NoZWR1bGVzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcwogKiAgICAgJCB3cCBjcm9uIHNjaGVkdWxlIGxpc3QKICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICAgIHwgZGlzcGxheSAgICAgfCBpbnRlcnZhbCB8CiAqICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKICogICAgIHwgaG91cmx5ICAgICB8IE9uY2UgSG91cmx5IHwgMzYwMCAgICAgfAogKiAgICAgfCB0d2ljZWRhaWx5IHwgVHdpY2UgRGFpbHkgfCA0MzIwMCAgICB8CiAqICAgICB8IGRhaWx5ICAgICAgfCBPbmNlIERhaWx5ICB8IDg2NDAwICAgIHwKICogICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwogKi8KY2xhc3MgQ3Jvbl9TY2hlZHVsZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IGFycmF5KAoJCSduYW1lJywKCQknZGlzcGxheScsCgkJJ2ludGVydmFsJywKCSk7CgoJLyoqCgkgKiBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIHNpbmdsZSBmaWVsZCBmb3IgZWFjaCBzY2hlZHVsZS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIGNyb24gc2NoZWR1bGU6CgkgKgoJICogKiBuYW1lCgkgKiAqIGRpc3BsYXkKCSAqICogaW50ZXJ2YWwKCSAqCgkgKiBUaGVyZSBhcmUgbm8gYWRkaXRpb25hbCBmaWVsZHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGF2YWlsYWJsZSBjcm9uIHNjaGVkdWxlcwoJICogICAgICQgd3AgY3JvbiBzY2hlZHVsZSBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBuYW1lICAgICAgIHwgZGlzcGxheSAgICAgfCBpbnRlcnZhbCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBob3VybHkgICAgIHwgT25jZSBIb3VybHkgfCAzNjAwICAgICB8CgkgKiAgICAgfCB0d2ljZWRhaWx5IHwgVHdpY2UgRGFpbHkgfCA0MzIwMCAgICB8CgkgKiAgICAgfCBkYWlseSAgICAgIHwgT25jZSBEYWlseSAgfCA4NjQwMCAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgTGlzdCBpZCBvZiBhdmFpbGFibGUgY3JvbiBzY2hlZHVsZQoJICogICAgICQgd3AgY3JvbiBzY2hlZHVsZSBsaXN0IC0tZmllbGRzPW5hbWUgLS1mb3JtYXQ9aWRzCgkgKiAgICAgaG91cmx5IHR3aWNlZGFpbHkgZGFpbHkKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRmb3JtYXR0ZXIgPSAkdGhpcy0+Z2V0X2Zvcm1hdHRlciggJGFzc29jX2FyZ3MgKTsKCgkJJHNjaGVkdWxlcyA9IHNlbGY6OmdldF9zY2hlZHVsZXMoKTsKCgkJaWYgKCAnaWRzJyA9PT0gJGZvcm1hdHRlci0+Zm9ybWF0ICkgewoJCQllY2hvIGltcGxvZGUoICcgJywgd3BfbGlzdF9wbHVjayggJHNjaGVkdWxlcywgJ25hbWUnICkgKTsKCQl9IGVsc2UgewoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkc2NoZWR1bGVzICk7CgkJfQoKCX0KCgkvKioKCSAqIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZvcm1hdCBhIGNyb24gc2NoZWR1bGUuCgkgKgoJICogQHBhcmFtIGFycmF5ICRzY2hlZHVsZSBUaGUgc2NoZWR1bGUuCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBzY2hlZHVsZSBuYW1lLgoJICogQHJldHVybiBhcnJheSBUaGUgZm9ybWF0dGVkIHNjaGVkdWxlLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZvcm1hdF9zY2hlZHVsZSggYXJyYXkgJHNjaGVkdWxlLCAkbmFtZSApIHsKCQkkc2NoZWR1bGVbJ25hbWUnXSA9ICRuYW1lOwoJCXJldHVybiAkc2NoZWR1bGU7Cgl9CgoJLyoqCgkqIFJldHVybiBhIGxpc3Qgb2YgdGhlIGNyb24gc2NoZWR1bGVzIHNvcnRlZCBhY2NvcmRpbmcgdG8gaW50ZXJ2YWwuCgkqCgkqIEByZXR1cm4gYXJyYXkgVGhlIGFycmF5IG9mIGNyb24gc2NoZWR1bGVzLiBFYWNoIHNjaGVkdWxlIGlzIGl0c2VsZiBhbiBhcnJheS4KCSovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldF9zY2hlZHVsZXMoKSB7CgkJJHNjaGVkdWxlcyA9IHdwX2dldF9zY2hlZHVsZXMoKTsKCQlpZiAoICEgZW1wdHkoICRzY2hlZHVsZXMgKSApIHsKCQkJdWFzb3J0KCAkc2NoZWR1bGVzLCAnQ3Jvbl9TY2hlZHVsZV9Db21tYW5kOjpzb3J0JyApOwoJCQkkc2NoZWR1bGVzID0gYXJyYXlfbWFwKCAnQ3Jvbl9TY2hlZHVsZV9Db21tYW5kOjpmb3JtYXRfc2NoZWR1bGUnLCAkc2NoZWR1bGVzLCBhcnJheV9rZXlzKCAkc2NoZWR1bGVzICkgKTsKCQl9CgkJcmV0dXJuICRzY2hlZHVsZXM7Cgl9CgoJLyoqCgkgKiBDYWxsYmFjayBmdW5jdGlvbiB0byBzb3J0IHRoZSBjcm9uIHNjaGVkdWxlIGFycmF5IGJ5IGludGVydmFsLgoJICoKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzb3J0KCBhcnJheSAkYSwgYXJyYXkgJGIgKSB7CgkJcmV0dXJuICRhWydpbnRlcnZhbCddIC0gJGJbJ2ludGVydmFsJ107Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZm9ybWF0dGVyKCAmJGFzc29jX2FyZ3MgKSB7CgkJcmV0dXJuIG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMsICdzY2hlZHVsZScgKTsKCX0KCn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9jb3JlX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX2NvcmVfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9jb3JlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb3JlJywgJ0NvcmVfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBDb21wb3NlclxTZW12ZXJcQ29tcGFyYXRvcjsKdXNlIFdQX0NMSVxFeHRyYWN0b3I7CnVzZSBXUF9DTElcSXRlcmF0b3JzXFRhYmxlIGFzIFRhYmxlSXRlcmF0b3I7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcRm9ybWF0dGVyOwp1c2UgV1BfQ0xJXFdwT3JnQXBpOwoKLyoqCiAqIERvd25sb2FkcywgaW5zdGFsbHMsIHVwZGF0ZXMsIGFuZCBtYW5hZ2VzIGEgV29yZFByZXNzIGluc3RhbGxhdGlvbi4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgRG93bmxvYWQgV29yZFByZXNzIGNvcmUKICogICAgICQgd3AgY29yZSBkb3dubG9hZCAtLWxvY2FsZT1ubF9OTAogKiAgICAgRG93bmxvYWRpbmcgV29yZFByZXNzIDQuNS4yIChubF9OTCkuLi4KICogICAgIG1kNSBoYXNoIHZlcmlmaWVkOiBjNTM2NmQwNWI1MjE4MzFkZDBiMjlkZmMzODZlNTZhNQogKiAgICAgU3VjY2VzczogV29yZFByZXNzIGRvd25sb2FkZWQuCiAqCiAqICAgICAjIEluc3RhbGwgV29yZFByZXNzCiAqICAgICAkIHdwIGNvcmUgaW5zdGFsbCAtLXVybD1leGFtcGxlLmNvbSAtLXRpdGxlPUV4YW1wbGUgLS1hZG1pbl91c2VyPXN1cGVydmlzb3IgLS1hZG1pbl9wYXNzd29yZD1zdHJvbmdwYXNzd29yZCAtLWFkbWluX2VtYWlsPWluZm9AZXhhbXBsZS5jb20KICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LgogKgogKiAgICAgIyBEaXNwbGF5IHRoZSBXb3JkUHJlc3MgdmVyc2lvbgogKiAgICAgJCB3cCBjb3JlIHZlcnNpb24KICogICAgIDQuNS4yCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ29yZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogQ2hlY2tzIGZvciBXb3JkUHJlc3MgdXBkYXRlcyB2aWEgVmVyc2lvbiBDaGVjayBBUEkuCgkgKgoJICogTGlzdHMgdGhlIG1vc3QgcmVjZW50IHZlcnNpb25zIHdoZW4gdGhlcmUgYXJlIHVwZGF0ZXMgYXZhaWxhYmxlLAoJICogb3Igc3VjY2VzcyBtZXNzYWdlIHdoZW4gdXAgdG8gZGF0ZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tbWlub3JdCgkgKiA6IENvbXBhcmUgb25seSB0aGUgZmlyc3QgdHdvIHBhcnRzIG9mIHRoZSB2ZXJzaW9uIG51bWJlci4KCSAqCgkgKiBbLS1tYWpvcl0KCSAqIDogQ29tcGFyZSBvbmx5IHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSB2ZXJzaW9uIG51bWJlci4KCSAqCgkgKiBbLS1maWVsZD08ZmllbGQ+XQoJICogOiBQcmludHMgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkIGZvciBlYWNoIHVwZGF0ZS4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4gRGVmYXVsdHMgdG8gdmVyc2lvbix1cGRhdGVfdHlwZSxwYWNrYWdlX3VybC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBjb3VudAoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGNvcmUgY2hlY2stdXBkYXRlCgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCB2ZXJzaW9uIHwgdXBkYXRlX3R5cGUgfCBwYWNrYWdlX3VybCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCA0LjUuMiAgIHwgbWFqb3IgICAgICAgfCBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3JlbGVhc2Uvd29yZHByZXNzLTQuNS4yLnppcCB8CgkgKiAgICAgKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgY2hlY2stdXBkYXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjaGVja191cGRhdGUoICRfLCAkYXNzb2NfYXJncyApIHsKCgkJJHVwZGF0ZXMgPSAkdGhpcy0+Z2V0X3VwZGF0ZXMoICRhc3NvY19hcmdzICk7CgkJaWYgKCAkdXBkYXRlcyApIHsKCQkJJHVwZGF0ZXMgICA9IGFycmF5X3JldmVyc2UoICR1cGRhdGVzICk7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQlbICd2ZXJzaW9uJywgJ3VwZGF0ZV90eXBlJywgJ3BhY2thZ2VfdXJsJyBdCgkJCSk7CgkJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICR1cGRhdGVzICk7CgkJfSBlbHNlaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgfHwgJ3RhYmxlJyA9PT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdXb3JkUHJlc3MgaXMgYXQgdGhlIGxhdGVzdCB2ZXJzaW9uLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBEb3dubG9hZHMgY29yZSBXb3JkUHJlc3MgZmlsZXMuCgkgKgoJICogRG93bmxvYWRzIGFuZCBleHRyYWN0cyBXb3JkUHJlc3MgY29yZSBmaWxlcyB0byB0aGUgc3BlY2lmaWVkIHBhdGguIFVzZXMKCSAqIGN1cnJlbnQgZGlyZWN0b3J5IHdoZW4gbm8gcGF0aCBpcyBzcGVjaWZpZWQuIERvd25sb2FkZWQgYnVpbGQgaXMgdmVyaWZpZWQKCSAqIHRvIGhhdmUgdGhlIGNvcnJlY3QgbWQ1IGFuZCB0aGVuIGNhY2hlZCB0byB0aGUgbG9jYWwgZmlsZXN5dGVtLgoJICogU3Vic2VxdWVudCB1c2VzIG9mIGNvbW1hbmQgd2lsbCB1c2UgdGhlIGxvY2FsIGNhY2hlIGlmIGl0IHN0aWxsIGV4aXN0cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxkb3dubG9hZC11cmw+XQoJICogOiBEb3dubG9hZCBkaXJlY3RseSBmcm9tIGEgcHJvdmlkZWQgVVJMIGluc3RlYWQgb2YgZmV0Y2hpbmcgdGhlIFVSTCBmcm9tIHRoZSB3b3JkcHJlc3Mub3JnIHNlcnZlcnMuCgkgKgoJICogWy0tcGF0aD08cGF0aD5dCgkgKiA6IFNwZWNpZnkgdGhlIHBhdGggaW4gd2hpY2ggdG8gaW5zdGFsbCBXb3JkUHJlc3MuIERlZmF1bHRzIHRvIGN1cnJlbnQKCSAqIGRpcmVjdG9yeS4KCSAqCgkgKiBbLS1sb2NhbGU9PGxvY2FsZT5dCgkgKiA6IFNlbGVjdCB3aGljaCBsYW5ndWFnZSB5b3Ugd2FudCB0byBkb3dubG9hZC4KCSAqCgkgKiBbLS12ZXJzaW9uPTx2ZXJzaW9uPl0KCSAqIDogU2VsZWN0IHdoaWNoIHZlcnNpb24geW91IHdhbnQgdG8gZG93bmxvYWQuIEFjY2VwdHMgYSB2ZXJzaW9uIG51bWJlciwgJ2xhdGVzdCcgb3IgJ25pZ2h0bHknLgoJICoKCSAqIFstLXNraXAtY29udGVudF0KCSAqIDogRG93bmxvYWQgV1Agd2l0aG91dCB0aGUgZGVmYXVsdCB0aGVtZXMgYW5kIHBsdWdpbnMuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZXMgZXhpc3RpbmcgZmlsZXMsIGlmIHByZXNlbnQuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IGRvd25sb2FkIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGNvcmUgZG93bmxvYWQgLS1sb2NhbGU9bmxfTkwKCSAqICAgICBEb3dubG9hZGluZyBXb3JkUHJlc3MgNC41LjIgKG5sX05MKS4uLgoJICogICAgIG1kNSBoYXNoIHZlcmlmaWVkOiBjNTM2NmQwNWI1MjE4MzFkZDBiMjlkZmMzODZlNTZhNQoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBkb3dubG9hZGVkLgoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQkkZG93bmxvYWRfZGlyID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ3BhdGgnXSApCgkJCT8gKCBydHJpbSggJGFzc29jX2FyZ3NbJ3BhdGgnXSwgJy9cXCcgKSAuICcvJyApCgkJCTogQUJTUEFUSDsKCgkJJHdvcmRwcmVzc19wcmVzZW50ID0gaXNfcmVhZGFibGUoICRkb3dubG9hZF9kaXIgLiAnd3AtbG9hZC5waHAnICk7CgoJCWlmICggJHdvcmRwcmVzc19wcmVzZW50ICYmICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdXb3JkUHJlc3MgZmlsZXMgc2VlbSB0byBhbHJlYWR5IGJlIHByZXNlbnQgaGVyZS4nICk7CgkJfQoKCQlpZiAoICEgaXNfZGlyKCAkZG93bmxvYWRfZGlyICkgKSB7CgkJCWlmICggISBpc193cml0YWJsZSggZGlybmFtZSggJGRvd25sb2FkX2RpciApICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiSW5zdWZmaWNpZW50IHBlcm1pc3Npb24gdG8gY3JlYXRlIGRpcmVjdG9yeSAneyRkb3dubG9hZF9kaXJ9Jy4iICk7CgkJCX0KCgkJCVdQX0NMSTo6bG9nKCAiQ3JlYXRpbmcgZGlyZWN0b3J5ICd7JGRvd25sb2FkX2Rpcn0nLiIgKTsKCQkJaWYgKCAhIEBta2RpciggJGRvd25sb2FkX2RpciwgMDc3NywgdHJ1ZSAvKnJlY3Vyc2l2ZSovICkgKSB7CgkJCQkkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQkJV1BfQ0xJOjplcnJvciggIkZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICd7JGRvd25sb2FkX2Rpcn0nOiB7JGVycm9yWydtZXNzYWdlJ119LiIgKTsKCQkJfQoJCX0KCgkJaWYgKCAhIGlzX3dyaXRhYmxlKCAkZG93bmxvYWRfZGlyICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICIneyRkb3dubG9hZF9kaXJ9JyBpcyBub3Qgd3JpdGFibGUgYnkgY3VycmVudCB1c2VyLiIgKTsKCQl9CgoJCSRsb2NhbGUgICAgICAgPSAoc3RyaW5nKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsb2NhbGUnLCAnZW5fVVMnICk7CgkJJHNraXBfY29udGVudCA9IChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLWNvbnRlbnQnLCBmYWxzZSApOwoJCSRpbnNlY3VyZSAgICAgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApOwoKCQkkZG93bmxvYWRfdXJsID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJGZyb21fdXJsICAgICA9ICEgZW1wdHkoICRkb3dubG9hZF91cmwgKTsKCgkJaWYgKCAkZnJvbV91cmwgKSB7CgkJCSR2ZXJzaW9uID0gbnVsbDsKCQkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1ZlcnNpb24gb3B0aW9uIGlzIG5vdCBhdmFpbGFibGUgZm9yIFVSTCBkb3dubG9hZHMuJyApOwoJCQl9CgkJCWlmICggJHNraXBfY29udGVudCB8fCAnZW5fVVMnICE9PSAkbG9jYWxlICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1NraXAgY29udGVudCBhbmQgbG9jYWxlIG9wdGlvbnMgYXJlIG5vdCBhdmFpbGFibGUgZm9yIFVSTCBkb3dubG9hZHMuJyApOwoJCQl9CgkJfSBlbHNlaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICYmICdsYXRlc3QnICE9PSAkYXNzb2NfYXJnc1sndmVyc2lvbiddICkgewoJCQkkdmVyc2lvbiA9ICRhc3NvY19hcmdzWyd2ZXJzaW9uJ107CgkJCWlmICggaW5fYXJyYXkoIHN0cnRvbG93ZXIoICR2ZXJzaW9uICksIFsgJ3RydW5rJywgJ25pZ2h0bHknIF0sIHRydWUgKSApIHsKCQkJCSR2ZXJzaW9uID0gJ25pZ2h0bHknOwoJCQl9CgoJCQkvLyBOaWdodGx5IGJ1aWxkcyBhbmQgc2tpcCBjb250ZW50IGFyZSBvbmx5IGF2YWlsYWJsZSBpbiAuemlwIGZvcm1hdC4KCQkJJGV4dGVuc2lvbiA9ICggKCAnbmlnaHRseScgPT09ICR2ZXJzaW9uICkgfHwgJHNraXBfY29udGVudCApCgkJCQk/ICd6aXAnCgkJCQk6ICd0YXIuZ3onOwoKCQkJJGRvd25sb2FkX3VybCA9ICR0aGlzLT5nZXRfZG93bmxvYWRfdXJsKCAkdmVyc2lvbiwgJGxvY2FsZSwgJGV4dGVuc2lvbiApOwoJCX0gZWxzZSB7CgkJCXRyeSB7CgkJCQkkb2ZmZXIgPSAoIG5ldyBXcE9yZ0FwaSggWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdICkgKQoJCQkJCS0+Z2V0X2NvcmVfZG93bmxvYWRfb2ZmZXIoICRsb2NhbGUgKTsKCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQkJV1BfQ0xJOjplcnJvciggJGV4Y2VwdGlvbiApOwoJCQl9CgkJCWlmICggISAkb2ZmZXIgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiVGhlIHJlcXVlc3RlZCBsb2NhbGUgKHskbG9jYWxlfSkgd2FzIG5vdCBmb3VuZC4iICk7CgkJCX0KCQkJJHZlcnNpb24gICAgICA9ICRvZmZlclsnY3VycmVudCddOwoJCQkkZG93bmxvYWRfdXJsID0gJG9mZmVyWydkb3dubG9hZCddOwoJCQlpZiAoICEgJHNraXBfY29udGVudCApIHsKCQkJCSRkb3dubG9hZF91cmwgPSBzdHJfcmVwbGFjZSggJy56aXAnLCAnLnRhci5neicsICRkb3dubG9hZF91cmwgKTsKCQkJfQoJCX0KCgkJaWYgKCAnbmlnaHRseScgPT09ICR2ZXJzaW9uICYmICdlbl9VUycgIT09ICRsb2NhbGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdOaWdodGx5IGJ1aWxkcyBhcmUgb25seSBhdmFpbGFibGUgZm9yIHRoZSBlbl9VUyBsb2NhbGUuJyApOwoJCX0KCgkJJGZyb21fdmVyc2lvbiA9ICcnOwoJCWlmICggZmlsZV9leGlzdHMoICRkb3dubG9hZF9kaXIgLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnICkgKSB7CgkJCSR3cF9kZXRhaWxzICAgPSBzZWxmOjpnZXRfd3BfZGV0YWlscyggJGRvd25sb2FkX2RpciApOwoJCQkkZnJvbV92ZXJzaW9uID0gJHdwX2RldGFpbHNbJ3dwX3ZlcnNpb24nXTsKCQl9CgoJCWlmICggJGZyb21fdXJsICkgewoJCQlXUF9DTEk6OmxvZyggIkRvd25sb2FkaW5nIGZyb20geyRkb3dubG9hZF91cmx9IC4uLiIgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmxvZyggIkRvd25sb2FkaW5nIFdvcmRQcmVzcyB7JHZlcnNpb259ICh7JGxvY2FsZX0pLi4uIiApOwoJCX0KCgkJJHBhdGhfcGFydHMgPSBwYXRoaW5mbyggJGRvd25sb2FkX3VybCApOwoJCSRleHRlbnNpb24gID0gJ3Rhci5neic7CgkJaWYgKCAnemlwJyA9PT0gJHBhdGhfcGFydHNbJ2V4dGVuc2lvbiddICkgewoJCQkkZXh0ZW5zaW9uID0gJ3ppcCc7CgkJCWlmICggISBjbGFzc19leGlzdHMoICdaaXBBcmNoaXZlJyApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ0V4dHJhY3RpbmcgYSB6aXAgZmlsZSByZXF1aXJlcyBaaXBBcmNoaXZlLicgKTsKCQkJfQoJCX0KCgkJaWYgKCAkc2tpcF9jb250ZW50ICYmICd6aXAnICE9PSAkZXh0ZW5zaW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAnU2tpcCBjb250ZW50IGlzIG9ubHkgYXZhaWxhYmxlIGZvciBaSVAgZmlsZXMuJyApOwoJCX0KCgkJJGNhY2hlID0gV1BfQ0xJOjpnZXRfY2FjaGUoKTsKCQlpZiAoICRmcm9tX3VybCApIHsKCQkJJGNhY2hlX2ZpbGUgPSBudWxsOwoJCX0gZWxzZSB7CgkJCSRjYWNoZV9rZXkgID0gImNvcmUvd29yZHByZXNzLXskdmVyc2lvbn0teyRsb2NhbGV9LnskZXh0ZW5zaW9ufSI7CgkJCSRjYWNoZV9maWxlID0gJGNhY2hlLT5oYXMoICRjYWNoZV9rZXkgKTsKCQl9CgoJCSRiYWRfY2FjaGUgPSBmYWxzZTsKCQlpZiAoICRjYWNoZV9maWxlICkgewoJCQlXUF9DTEk6OmxvZyggIlVzaW5nIGNhY2hlZCBmaWxlICd7JGNhY2hlX2ZpbGV9Jy4uLiIgKTsKCQkJJHNraXBfY29udGVudF9jYWNoZV9maWxlID0gJHNraXBfY29udGVudCA/IHNlbGY6OnN0cmlwX2NvbnRlbnRfZGlyKCAkY2FjaGVfZmlsZSApIDogbnVsbDsKCQkJdHJ5IHsKCQkJCUV4dHJhY3Rvcjo6ZXh0cmFjdCggJHNraXBfY29udGVudF9jYWNoZV9maWxlID86ICRjYWNoZV9maWxlLCAkZG93bmxvYWRfZGlyICk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ0V4dHJhY3Rpb24gZmFpbGVkLCBkb3dubG9hZGluZyBhIG5ldyBjb3B5Li4uJyApOwoJCQkJJGJhZF9jYWNoZSA9IHRydWU7CgkJCX0KCQl9CgoJCWlmICggISAkY2FjaGVfZmlsZSB8fCAkYmFkX2NhY2hlICkgewoJCQkvLyBXZSBuZWVkIHRvIHVzZSBhIHRlbXBvcmFyeSBmaWxlIGJlY2F1c2UgcGlwaW5nIGZyb20gY1VSTCB0byB0YXIgaXMgZmxha3kKCQkJLy8gb24gTWluR1cgKGFuZCBwcm9iYWJseSBpbiBvdGhlciBlbnZpcm9ubWVudHMgdG9vKS4KCQkJJHRlbXAgPSBVdGlsc1xnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwXycgKSAuICIueyRleHRlbnNpb259IjsKCQkJcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oCgkJCQlmdW5jdGlvbiAoKSB1c2UgKCAkdGVtcCApIHsKCQkJCQlpZiAoIGZpbGVfZXhpc3RzKCAkdGVtcCApICkgewoJCQkJCQl1bmxpbmsoICR0ZW1wICk7CgkJCQkJfQoJCQkJfQoJCQkpOwoKCQkJJGhlYWRlcnMgPSBbICdBY2NlcHQnID0+ICdhcHBsaWNhdGlvbi9qc29uJyBdOwoJCQkkb3B0aW9ucyA9IFsKCQkJCSd0aW1lb3V0JyAgPT4gNjAwLCAgLy8gMTAgbWludXRlcyBvdWdodCB0byBiZSBlbm91Z2ggZm9yIGV2ZXJ5Ym9keQoJCQkJJ2ZpbGVuYW1lJyA9PiAkdGVtcCwKCQkJCSdpbnNlY3VyZScgPT4gJGluc2VjdXJlLAoJCQldOwoKCQkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJGRvd25sb2FkX3VybCwgbnVsbCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgoJCQlpZiAoIDQwNCA9PT0gKGludCkgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdSZWxlYXNlIG5vdCBmb3VuZC4gRG91YmxlLWNoZWNrIGxvY2FsZSBvciB2ZXJzaW9uLicgKTsKCQkJfSBlbHNlaWYgKCAyMCAhPT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgYWNjZXNzIGRvd25sb2FkIFVSTCAoSFRUUCBjb2RlIHskcmVzcG9uc2UtPnN0YXR1c19jb2RlfSkuIiApOwoJCQl9CgoJCQlpZiAoICduaWdodGx5JyAhPT0gJHZlcnNpb24gKSB7CgkJCQl1bnNldCggJG9wdGlvbnNbJ2ZpbGVuYW1lJ10gKTsKCQkJCSRtZDVfcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkZG93bmxvYWRfdXJsIC4gJy5tZDUnLCBudWxsLCBbXSwgJG9wdGlvbnMgKTsKCQkJCWlmICggJG1kNV9yZXNwb25zZS0+c3RhdHVzX2NvZGUgPj0gMjAwICYmICRtZDVfcmVzcG9uc2UtPnN0YXR1c19jb2RlIDwgMzAwICkgewoJCQkJCSRtZDVfZmlsZSA9IG1kNV9maWxlKCAkdGVtcCApOwoKCQkJCQlpZiAoICRtZDVfZmlsZSA9PT0gJG1kNV9yZXNwb25zZS0+Ym9keSApIHsKCQkJCQkJV1BfQ0xJOjpsb2coICdtZDUgaGFzaCB2ZXJpZmllZDogJyAuICRtZDVfZmlsZSApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICJtZDUgaGFzaCBmb3IgZG93bmxvYWQgKHskbWQ1X2ZpbGV9KSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUgcmVsZWFzZSBoYXNoICh7JG1kNV9yZXNwb25zZS0+Ym9keX0pLiIgKTsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkbid0IGFjY2VzcyBtZDUgaGFzaCBmb3IgcmVsZWFzZSAoeyRkb3dubG9hZF91cmx9Lm1kNSwgSFRUUCBjb2RlIHskbWQ1X3Jlc3BvbnNlLT5zdGF0dXNfY29kZX0pLiIgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ21kNSBoYXNoIGNoZWNrcyBhcmUgbm90IGF2YWlsYWJsZSBmb3IgbmlnaHRseSBkb3dubG9hZHMuJyApOwoJCQl9CgoJCQkkc2tpcF9jb250ZW50X3RlbXAgPSAkc2tpcF9jb250ZW50ID8gc2VsZjo6c3RyaXBfY29udGVudF9kaXIoICR0ZW1wICkgOiBudWxsOwoKCQkJdHJ5IHsKCQkJCUV4dHJhY3Rvcjo6ZXh0cmFjdCggJHNraXBfY29udGVudF90ZW1wID86ICR0ZW1wLCAkZG93bmxvYWRfZGlyICk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBleHRyYWN0IFdvcmRQcmVzcyBhcmNoaXZlLiB7JGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpfSIgKTsKCQkJfQoKCQkJLy8gRG8gbm90IHVzZSB0aGUgY2FjaGUgZm9yIG5pZ2h0bHkgYnVpbGRzIG9yIGZvciBkb3dubG9hZGVkIFVSTHMKCQkJLy8gKHRoZSBVUkwgY291bGQgYmUgc29tZXRoaW5nIGxpa2UgImxhdGVzdC56aXAiIG9yICJuaWdodGx5LnppcCIpLgoJCQlpZiAoICEgJGZyb21fdXJsICYmICduaWdodGx5JyAhPT0gJHZlcnNpb24gKSB7CgkJCQkkY2FjaGUtPmltcG9ydCggJGNhY2hlX2tleSwgJHRlbXAgKTsKCQkJfQoJCX0KCgkJaWYgKCAkd29yZHByZXNzX3ByZXNlbnQgKSB7CgkJCSR0aGlzLT5jbGVhbnVwX2V4dHJhX2ZpbGVzKCAkZnJvbV92ZXJzaW9uLCAkdmVyc2lvbiwgJGxvY2FsZSwgJGluc2VjdXJlICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdXb3JkUHJlc3MgZG93bmxvYWRlZC4nICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgaWYgV29yZFByZXNzIGlzIGluc3RhbGxlZC4KCSAqCgkgKiBEZXRlcm1pbmVzIHdoZXRoZXIgV29yZFByZXNzIGlzIGluc3RhbGxlZCBieSBjaGVja2luZyBpZiB0aGUgc3RhbmRhcmQKCSAqIGRhdGFiYXNlIHRhYmxlcyBhcmUgaW5zdGFsbGVkLiBEb2Vzbid0IHByb2R1Y2Ugb3V0cHV0OyB1c2VzIGV4aXQgY29kZXMKCSAqIHRvIGNvbW11bmljYXRlIHdoZXRoZXIgV29yZFByZXNzIGlzIGluc3RhbGxlZC4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBDaGVjayBpZiB0aGlzIGlzIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgV29yZFByZXNzIGlzIGluc3RhbGxlZDsgZXhpdCBzdGF0dXMgMCBpZiBpbnN0YWxsZWQsIG90aGVyd2lzZSAxCgkgKiAgICAgJCB3cCBjb3JlIGlzLWluc3RhbGxlZAoJICogICAgICQgZWNobyAkPwoJICogICAgIDEKCSAqCgkgKiAgICAgIyBCYXNoIHNjcmlwdCBmb3IgY2hlY2tpbmcgd2hldGhlciBXb3JkUHJlc3MgaXMgaW5zdGFsbGVkIG9yIG5vdAoJICogICAgIGlmICEgd3AgY29yZSBpcy1pbnN0YWxsZWQ7IHRoZW4KCSAqICAgICAgICAgd3AgY29yZSBpbnN0YWxsCgkgKiAgICAgZmkKCSAqCgkgKiBAc3ViY29tbWFuZCBpcy1pbnN0YWxsZWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGlzX2luc3RhbGxlZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWlmICggaXNfYmxvZ19pbnN0YWxsZWQoKQoJCQkmJiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKQoJCQkJfHwgaXNfbXVsdGlzaXRlKCkgKSApIHsKCQkJV1BfQ0xJOjpoYWx0KCAwICk7CgkJfQoKCQlXUF9DTEk6OmhhbHQoIDEgKTsKCX0KCgkvKioKCSAqIFJ1bnMgdGhlIHN0YW5kYXJkIFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gcHJvY2Vzcy4KCSAqCgkgKiBDcmVhdGVzIHRoZSBXb3JkUHJlc3MgdGFibGVzIGluIHRoZSBkYXRhYmFzZSB1c2luZyB0aGUgVVJMLCB0aXRsZSwgYW5kCgkgKiBkZWZhdWx0IGFkbWluIHVzZXIgZGV0YWlscyBwcm92aWRlZC4gUGVyZm9ybXMgdGhlIGZhbW91cyA1IG1pbnV0ZSBpbnN0YWxsCgkgKiBpbiBzZWNvbmRzIG9yIGxlc3MuCgkgKgoJICogTm90ZTogaWYgeW91J3ZlIGluc3RhbGxlZCBXb3JkUHJlc3MgaW4gYSBzdWJkaXJlY3RvcnksIHRoZW4geW91J2xsIG5lZWQKCSAqIHRvIGB3cCBvcHRpb24gdXBkYXRlIHNpdGV1cmxgIGFmdGVyIGB3cCBjb3JlIGluc3RhbGxgLiBGb3IgaW5zdGFuY2UsIGlmCgkgKiBXb3JkUHJlc3MgaXMgaW5zdGFsbGVkIGluIHRoZSBgL3dwYCBkaXJlY3RvcnkgYW5kIHlvdXIgZG9tYWluIGlzIGV4YW1wbGUuY29tLAoJICogdGhlbiB5b3UnbGwgbmVlZCB0byBydW4gYHdwIG9wdGlvbiB1cGRhdGUgc2l0ZXVybCBodHRwOi8vZXhhbXBsZS5jb20vd3BgIGZvcgoJICogeW91ciBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uIHRvIGZ1bmN0aW9uIHByb3Blcmx5LgoJICoKCSAqIE5vdGU6IFdoZW4gdXNpbmcgY3VzdG9tIHVzZXIgdGFibGVzIChlLmcuIGBDVVNUT01fVVNFUl9UQUJMRWApLCB0aGUgYWRtaW4KCSAqIGVtYWlsIGFuZCBwYXNzd29yZCBhcmUgaWdub3JlZCBpZiB0aGUgdXNlcl9sb2dpbiBhbHJlYWR5IGV4aXN0cy4gSWYgdGhlCgkgKiB1c2VyX2xvZ2luIGRvZXNuJ3QgZXhpc3QsIGEgbmV3IHVzZXIgd2lsbCBiZSBjcmVhdGVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiAtLXVybD08dXJsPgoJICogOiBUaGUgYWRkcmVzcyBvZiB0aGUgbmV3IHNpdGUuCgkgKgoJICogLS10aXRsZT08c2l0ZS10aXRsZT4KCSAqIDogVGhlIHRpdGxlIG9mIHRoZSBuZXcgc2l0ZS4KCSAqCgkgKiAtLWFkbWluX3VzZXI9PHVzZXJuYW1lPgoJICogOiBUaGUgbmFtZSBvZiB0aGUgYWRtaW4gdXNlci4KCSAqCgkgKiBbLS1hZG1pbl9wYXNzd29yZD08cGFzc3dvcmQ+XQoJICogOiBUaGUgcGFzc3dvcmQgZm9yIHRoZSBhZG1pbiB1c2VyLiBEZWZhdWx0cyB0byByYW5kb21seSBnZW5lcmF0ZWQgc3RyaW5nLgoJICoKCSAqIC0tYWRtaW5fZW1haWw9PGVtYWlsPgoJICogOiBUaGUgZW1haWwgYWRkcmVzcyBmb3IgdGhlIGFkbWluIHVzZXIuCgkgKgoJICogWy0tc2tpcC1lbWFpbF0KCSAqIDogRG9uJ3Qgc2VuZCBhbiBlbWFpbCBub3RpZmljYXRpb24gdG8gdGhlIG5ldyBhZG1pbiB1c2VyLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgSW5zdGFsbCBXb3JkUHJlc3MgaW4gNSBzZWNvbmRzCgkgKiAgICAgJCB3cCBjb3JlIGluc3RhbGwgLS11cmw9ZXhhbXBsZS5jb20gLS10aXRsZT1FeGFtcGxlIC0tYWRtaW5fdXNlcj1zdXBlcnZpc29yIC0tYWRtaW5fcGFzc3dvcmQ9c3Ryb25ncGFzc3dvcmQgLS1hZG1pbl9lbWFpbD1pbmZvQGV4YW1wbGUuY29tCgkgKiAgICAgU3VjY2VzczogV29yZFByZXNzIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuCgkgKgoJICogICAgICMgSW5zdGFsbCBXb3JkUHJlc3Mgd2l0aG91dCBkaXNjbG9zaW5nIGFkbWluX3Bhc3N3b3JkIHRvIGJhc2ggaGlzdG9yeQoJICogICAgICQgd3AgY29yZSBpbnN0YWxsIC0tdXJsPWV4YW1wbGUuY29tIC0tdGl0bGU9RXhhbXBsZSAtLWFkbWluX3VzZXI9c3VwZXJ2aXNvciAtLWFkbWluX2VtYWlsPWluZm9AZXhhbXBsZS5jb20gLS1wcm9tcHQ9YWRtaW5fcGFzc3dvcmQgPCBhZG1pbl9wYXNzd29yZC50eHQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICR0aGlzLT5kb19pbnN0YWxsKCAkYXNzb2NfYXJncyApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdXb3JkUHJlc3MgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4nICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpsb2coICdXb3JkUHJlc3MgaXMgYWxyZWFkeSBpbnN0YWxsZWQuJyApOwoJCX0KCX0KCgkvKioKCSAqIFRyYW5zZm9ybXMgYW4gZXhpc3Rpbmcgc2luZ2xlLXNpdGUgaW5zdGFsbGF0aW9uIGludG8gYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLgoJICoKCSAqIENyZWF0ZXMgdGhlIG11bHRpc2l0ZSBkYXRhYmFzZSB0YWJsZXMsIGFuZCBhZGRzIHRoZSBtdWx0aXNpdGUgY29uc3RhbnRzCgkgKiB0byB3cC1jb25maWcucGhwLgoJICoKCSAqIEZvciB0aG9zZSB1c2luZyBXb3JkUHJlc3Mgd2l0aCBBcGFjaGUsIHJlbWVtYmVyIHRvIHVwZGF0ZSB0aGUgYC5odGFjY2Vzc2AKCSAqIGZpbGUgd2l0aCB0aGUgYXBwcm9wcmlhdGUgbXVsdGlzaXRlIHJld3JpdGUgcnVsZXMuCgkgKgoJICogW1JldmlldyB0aGUgbXVsdGlzaXRlIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DcmVhdGVfQV9OZXR3b3JrKQoJICogZm9yIG1vcmUgZGV0YWlscyBhYm91dCBob3cgbXVsdGlzaXRlIHdvcmtzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS10aXRsZT08bmV0d29yay10aXRsZT5dCgkgKiA6IFRoZSB0aXRsZSBvZiB0aGUgbmV3IG5ldHdvcmsuCgkgKgoJICogWy0tYmFzZT08dXJsLXBhdGg+XQoJICogOiBCYXNlIHBhdGggYWZ0ZXIgdGhlIGRvbWFpbiBuYW1lIHRoYXQgZWFjaCBzaXRlIHVybCB3aWxsIHN0YXJ0IHdpdGguCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IC8KCSAqIC0tLQoJICoKCSAqIFstLXN1YmRvbWFpbnNdCgkgKiA6IElmIHBhc3NlZCwgdGhlIG5ldHdvcmsgd2lsbCB1c2Ugc3ViZG9tYWlucywgaW5zdGVhZCBvZiBzdWJkaXJlY3Rvcmllcy4gRG9lc24ndCB3b3JrIHdpdGggJ2xvY2FsaG9zdCcuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBjb3JlIG11bHRpc2l0ZS1jb252ZXJ0CgkgKiAgICAgU2V0IHVwIG11bHRpc2l0ZSBkYXRhYmFzZSB0YWJsZXMuCgkgKiAgICAgQWRkZWQgbXVsdGlzaXRlIGNvbnN0YW50cyB0byB3cC1jb25maWcucGhwLgoJICogICAgIFN1Y2Nlc3M6IE5ldHdvcmsgaW5zdGFsbGVkLiBEb24ndCBmb3JnZXQgdG8gc2V0IHVwIHJld3JpdGUgcnVsZXMuCgkgKgoJICogQHN1YmNvbW1hbmQgbXVsdGlzaXRlLWNvbnZlcnQKCSAqIEBhbGlhcyBpbnN0YWxsLW5ldHdvcmsKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG11bHRpc2l0ZV9jb252ZXJ0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1RoaXMgYWxyZWFkeSBpcyBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uJyApOwoJCX0KCgkJJGFzc29jX2FyZ3MgPSBzZWxmOjpzZXRfbXVsdGlzaXRlX2RlZmF1bHRzKCAkYXNzb2NfYXJncyApOwoJCWlmICggISBpc3NldCggJGFzc29jX2FyZ3NbJ3RpdGxlJ10gKSApIHsKCQkJLy8gdHJhbnNsYXRvcnM6IHBsYWNlaG9sZGVyIGlzIGJsb2cgbmFtZQoJCQkkYXNzb2NfYXJnc1sndGl0bGUnXSA9IHNwcmludGYoIF94KCAnJXMgU2l0ZXMnLCAnRGVmYXVsdCBuZXR3b3JrIG5hbWUnICksIGdldF9vcHRpb24oICdibG9nbmFtZScgKSApOwoJCX0KCgkJaWYgKCAkdGhpcy0+bXVsdGlzaXRlX2NvbnZlcnRfKCAkYXNzb2NfYXJncyApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJOZXR3b3JrIGluc3RhbGxlZC4gRG9uJ3QgZm9yZ2V0IHRvIHNldCB1cCByZXdyaXRlIHJ1bGVzIChhbmQgYSAuaHRhY2Nlc3MgZmlsZSwgaWYgdXNpbmcgQXBhY2hlKS4iICk7CgkJfQoJfQoKCS8qKgoJICogSW5zdGFsbHMgV29yZFByZXNzIG11bHRpc2l0ZSBmcm9tIHNjcmF0Y2guCgkgKgoJICogQ3JlYXRlcyB0aGUgV29yZFByZXNzIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UgdXNpbmcgdGhlIFVSTCwgdGl0bGUsIGFuZAoJICogZGVmYXVsdCBhZG1pbiB1c2VyIGRldGFpbHMgcHJvdmlkZWQuIFRoZW4sIGNyZWF0ZXMgdGhlIG11bHRpc2l0ZSB0YWJsZXMKCSAqIGluIHRoZSBkYXRhYmFzZSBhbmQgYWRkcyBtdWx0aXNpdGUgY29uc3RhbnRzIHRvIHRoZSB3cC1jb25maWcucGhwLgoJICoKCSAqIEZvciB0aG9zZSB1c2luZyBXb3JkUHJlc3Mgd2l0aCBBcGFjaGUsIHJlbWVtYmVyIHRvIHVwZGF0ZSB0aGUgYC5odGFjY2Vzc2AKCSAqIGZpbGUgd2l0aCB0aGUgYXBwcm9wcmlhdGUgbXVsdGlzaXRlIHJld3JpdGUgcnVsZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLXVybD08dXJsPl0KCSAqIDogVGhlIGFkZHJlc3Mgb2YgdGhlIG5ldyBzaXRlLgoJICoKCSAqIFstLWJhc2U9PHVybC1wYXRoPl0KCSAqIDogQmFzZSBwYXRoIGFmdGVyIHRoZSBkb21haW4gbmFtZSB0aGF0IGVhY2ggc2l0ZSB1cmwgaW4gdGhlIG5ldHdvcmsgd2lsbCBzdGFydCB3aXRoLgoJICogLS0tCgkgKiBkZWZhdWx0OiAvCgkgKiAtLS0KCSAqCgkgKiBbLS1zdWJkb21haW5zXQoJICogOiBJZiBwYXNzZWQsIHRoZSBuZXR3b3JrIHdpbGwgdXNlIHN1YmRvbWFpbnMsIGluc3RlYWQgb2Ygc3ViZGlyZWN0b3JpZXMuIERvZXNuJ3Qgd29yayB3aXRoICdsb2NhbGhvc3QnLgoJICoKCSAqIC0tdGl0bGU9PHNpdGUtdGl0bGU+CgkgKiA6IFRoZSB0aXRsZSBvZiB0aGUgbmV3IHNpdGUuCgkgKgoJICogLS1hZG1pbl91c2VyPTx1c2VybmFtZT4KCSAqIDogVGhlIG5hbWUgb2YgdGhlIGFkbWluIHVzZXIuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGFkbWluCgkgKiAtLS0KCSAqCgkgKiBbLS1hZG1pbl9wYXNzd29yZD08cGFzc3dvcmQ+XQoJICogOiBUaGUgcGFzc3dvcmQgZm9yIHRoZSBhZG1pbiB1c2VyLiBEZWZhdWx0cyB0byByYW5kb21seSBnZW5lcmF0ZWQgc3RyaW5nLgoJICoKCSAqIC0tYWRtaW5fZW1haWw9PGVtYWlsPgoJICogOiBUaGUgZW1haWwgYWRkcmVzcyBmb3IgdGhlIGFkbWluIHVzZXIuCgkgKgoJICogWy0tc2tpcC1lbWFpbF0KCSAqIDogRG9uJ3Qgc2VuZCBhbiBlbWFpbCBub3RpZmljYXRpb24gdG8gdGhlIG5ldyBhZG1pbiB1c2VyLgoJICoKCSAqIFstLXNraXAtY29uZmlnXQoJICogOiBEb24ndCBhZGQgbXVsdGlzaXRlIGNvbnN0YW50cyB0byB3cC1jb25maWcucGhwLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgY29yZSBtdWx0aXNpdGUtaW5zdGFsbCAtLXRpdGxlPSJXZWxjb21lIHRvIHRoZSBXb3JkUHJlc3MiIFwKCSAqICAgICA+IC0tYWRtaW5fdXNlcj0iYWRtaW4iIC0tYWRtaW5fcGFzc3dvcmQ9InBhc3N3b3JkIiBcCgkgKiAgICAgPiAtLWFkbWluX2VtYWlsPSJ1c2VyQGV4YW1wbGUuY29tIgoJICogICAgIFNpbmdsZSBzaXRlIGRhdGFiYXNlIHRhYmxlcyBhbHJlYWR5IHByZXNlbnQuCgkgKiAgICAgU2V0IHVwIG11bHRpc2l0ZSBkYXRhYmFzZSB0YWJsZXMuCgkgKiAgICAgQWRkZWQgbXVsdGlzaXRlIGNvbnN0YW50cyB0byB3cC1jb25maWcucGhwLgoJICogICAgIFN1Y2Nlc3M6IE5ldHdvcmsgaW5zdGFsbGVkLiBEb24ndCBmb3JnZXQgdG8gc2V0IHVwIHJld3JpdGUgcnVsZXMuCgkgKgoJICogQHN1YmNvbW1hbmQgbXVsdGlzaXRlLWluc3RhbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIG11bHRpc2l0ZV9pbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCAkdGhpcy0+ZG9faW5zdGFsbCggJGFzc29jX2FyZ3MgKSApIHsKCQkJV1BfQ0xJOjpsb2coICdDcmVhdGVkIHNpbmdsZSBzaXRlIGRhdGFiYXNlIHRhYmxlcy4nICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpsb2coICdTaW5nbGUgc2l0ZSBkYXRhYmFzZSB0YWJsZXMgYWxyZWFkeSBwcmVzZW50LicgKTsKCQl9CgoJCSRhc3NvY19hcmdzID0gc2VsZjo6c2V0X211bHRpc2l0ZV9kZWZhdWx0cyggJGFzc29jX2FyZ3MgKTsKCQkvLyB0cmFuc2xhdG9yczogcGxhY2Vob2xkZXIgaXMgdXNlciBzdXBwbGllZCB0aXRsZQoJCSRhc3NvY19hcmdzWyd0aXRsZSddID0gc3ByaW50ZiggX3goICclcyBTaXRlcycsICdEZWZhdWx0IG5ldHdvcmsgbmFtZScgKSwgJGFzc29jX2FyZ3NbJ3RpdGxlJ10gKTsKCgkJLy8gT3ZlcndyaXRlIHJ1bnRpbWUgYXJncywgdG8gYXZvaWQgbWlzbWF0Y2hlcy4KCQkkY29uc3RzX3RvX2FyZ3MgPSBbCgkJCSdTVUJET01BSU5fSU5TVEFMTCcgICAgPT4gJ3N1YmRvbWFpbnMnLAoJCQknUEFUSF9DVVJSRU5UX1NJVEUnICAgID0+ICdiYXNlJywKCQkJJ1NJVEVfSURfQ1VSUkVOVF9TSVRFJyA9PiAnc2l0ZV9pZCcsCgkJCSdCTE9HX0lEX0NVUlJFTlRfU0lURScgPT4gJ2Jsb2dfaWQnLAoJCV07CgoJCWZvcmVhY2ggKCAkY29uc3RzX3RvX2FyZ3MgYXMgJGNvbnN0ID0+ICRhcmcgKSB7CgkJCWlmICggZGVmaW5lZCggJGNvbnN0ICkgKSB7CgkJCQkkYXNzb2NfYXJnc1sgJGFyZyBdID0gY29uc3RhbnQoICRjb25zdCApOwoJCQl9CgkJfQoKCQlpZiAoICEgJHRoaXMtPm11bHRpc2l0ZV9jb252ZXJ0XyggJGFzc29jX2FyZ3MgKSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gRG8gdGhlIHN0ZXBzIHRoYXQgd2VyZSBza2lwcGVkIGJ5IHBvcHVsYXRlX25ldHdvcmsoKSwKCQkvLyB3aGljaCBjaGVja3MgaXNfbXVsdGlzaXRlKCkuCgkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJJHNpdGVfdXNlciA9IGdldF91c2VyX2J5KCAnZW1haWwnLCAkYXNzb2NfYXJnc1snYWRtaW5fZW1haWwnXSApOwoJCQlzZWxmOjphZGRfc2l0ZV9hZG1pbnMoICRzaXRlX3VzZXIgKTsKCQkJJGRvbWFpbiA9IHNlbGY6OmdldF9jbGVhbl9iYXNlZG9tYWluKCk7CgkJCXNlbGY6OmNyZWF0ZV9pbml0aWFsX2Jsb2coCgkJCQkkYXNzb2NfYXJnc1snc2l0ZV9pZCddLAoJCQkJJGFzc29jX2FyZ3NbJ2Jsb2dfaWQnXSwKCQkJCSRkb21haW4sCgkJCQkkYXNzb2NfYXJnc1snYmFzZSddLAoJCQkJJGFzc29jX2FyZ3NbJ3N1YmRvbWFpbnMnXSwKCQkJCSRzaXRlX3VzZXIKCQkJKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIk5ldHdvcmsgaW5zdGFsbGVkLiBEb24ndCBmb3JnZXQgdG8gc2V0IHVwIHJld3JpdGUgcnVsZXMgKGFuZCBhIC5odGFjY2VzcyBmaWxlLCBpZiB1c2luZyBBcGFjaGUpLiIgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzZXRfbXVsdGlzaXRlX2RlZmF1bHRzKCAkYXNzb2NfYXJncyApIHsKCQkkZGVmYXVsdHMgPSBbCgkJCSdzdWJkb21haW5zJyA9PiBmYWxzZSwKCQkJJ2Jhc2UnICAgICAgID0+ICcvJywKCQkJJ3NpdGVfaWQnICAgID0+IDEsCgkJCSdibG9nX2lkJyAgICA9PiAxLAoJCV07CgoJCXJldHVybiBhcnJheV9tZXJnZSggJGRlZmF1bHRzLCAkYXNzb2NfYXJncyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gZG9faW5zdGFsbCggJGFzc29jX2FyZ3MgKSB7CgkJaWYgKCBpc19ibG9nX2luc3RhbGxlZCgpICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoIHRydWUgPT09IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtZW1haWwnICkgKSB7CgkJCWlmICggISBmdW5jdGlvbl9leGlzdHMoICd3cF9uZXdfYmxvZ19ub3RpZmljYXRpb24nICkgKSB7CgkJCQlmdW5jdGlvbiB3cF9uZXdfYmxvZ19ub3RpZmljYXRpb24oKSB7CgkJCQkJLy8gU2lsZW5jZSBpcyBnb2xkZW4KCQkJCX0KCQkJfQoJCQkvLyBXUCA0LjkuMCAtIHNraXAgIk5vdGljZSBvZiBBZG1pbiBFbWFpbCBDaGFuZ2UiIGVtYWlsIGFzIHdlbGwgKGh0dHBzOi8vY29yZS50cmFjLndvcmRwcmVzcy5vcmcvdGlja2V0LzM5MTE3KS4KCQkJYWRkX2ZpbHRlciggJ3NlbmRfc2l0ZV9hZG1pbl9lbWFpbF9jaGFuZ2VfZW1haWwnLCAnX19yZXR1cm5fZmFsc2UnICk7CgkJfQoKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy91cGdyYWRlLnBocCc7CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ3RpdGxlJyAgICAgICAgICA9PiAnJywKCQkJJ2FkbWluX3VzZXInICAgICA9PiAnJywKCQkJJ2FkbWluX2VtYWlsJyAgICA9PiAnJywKCQkJJ2FkbWluX3Bhc3N3b3JkJyA9PiAnJywKCQldOwoKCQkkYXJncyA9IHdwX3BhcnNlX2FyZ3MoICRhc3NvY19hcmdzLCAkZGVmYXVsdHMgKTsKCgkJLy8gU3VwcG9ydCBwcm9tcHRpbmcgZm9yIHRoZSBgLS11cmw9PHVybD5gLAoJCS8vIHdoaWNoIGlzIG5vcm1hbGx5IGEgcnVudGltZSBhcmd1bWVudAoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyd1cmwnXSApICkgewoJCQlXUF9DTEk6OnNldF91cmwoICRhc3NvY19hcmdzWyd1cmwnXSApOwoJCX0KCgkJJHB1YmxpYyAgID0gdHJ1ZTsKCQkkcGFzc3dvcmQgPSBlbXB0eSggJGFyZ3NbJ2FkbWluX3Bhc3N3b3JkJ10gKQoJCQk/IHdwX2dlbmVyYXRlX3Bhc3N3b3JkKCAxOCApCgkJCTogJGFyZ3NbJ2FkbWluX3Bhc3N3b3JkJ107CgoJCWlmICggISBpc19lbWFpbCggJGFyZ3NbJ2FkbWluX2VtYWlsJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRoZSAneyRhcmdzWydhZG1pbl9lbWFpbCddfScgZW1haWwgYWRkcmVzcyBpcyBpbnZhbGlkLiIgKTsKCQl9CgoJCSRyZXN1bHQgPSB3cF9pbnN0YWxsKAoJCQkkYXJnc1sndGl0bGUnXSwKCQkJJGFyZ3NbJ2FkbWluX3VzZXInXSwKCQkJJGFyZ3NbJ2FkbWluX2VtYWlsJ10sCgkJCSRwdWJsaWMsCgkJCScnLAoJCQkkcGFzc3dvcmQKCQkpOwoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkcmVzdWx0ICkgKSB7CgkJCSRyZWFzb24gPSBXUF9DTEk6OmVycm9yX3RvX3N0cmluZyggJHJlc3VsdCApOwoJCQlXUF9DTEk6OmVycm9yKCAiSW5zdGFsbGF0aW9uIGZhaWxlZCAoeyRyZWFzb259KS4iICk7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRHTE9CQUxTWyd3cGRiJ10tPmxhc3RfZXJyb3IgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0luc3RhbGxhdGlvbiBwcm9kdWNlZCBkYXRhYmFzZSBlcnJvcnMsIGFuZCBtYXkgaGF2ZSBwYXJ0aWFsbHkgb3IgY29tcGxldGVseSBmYWlsZWQuJyApOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFyZ3NbJ2FkbWluX3Bhc3N3b3JkJ10gKSApIHsKCQkJV1BfQ0xJOjpsb2coICJBZG1pbiBwYXNzd29yZDogeyRyZXN1bHRbJ3Bhc3N3b3JkJ119IiApOwoJCX0KCgkJLy8gQ29uZmlybSB0aGUgdXBsb2FkcyBkaXJlY3RvcnkgZXhpc3RzCgkJJHVwbG9hZF9kaXIgPSB3cF91cGxvYWRfZGlyKCk7CgkJaWYgKCAhIGVtcHR5KCAkdXBsb2FkX2RpclsnZXJyb3InXSApICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICR1cGxvYWRfZGlyWydlcnJvciddICk7CgkJfQoKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG11bHRpc2l0ZV9jb252ZXJ0XyggJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICd3cC1hZG1pbi9pbmNsdWRlcy91cGdyYWRlLnBocCc7CgoJCSRkb21haW4gPSBzZWxmOjpnZXRfY2xlYW5fYmFzZWRvbWFpbigpOwoJCWlmICggJ2xvY2FsaG9zdCcgPT09ICRkb21haW4gJiYgISBlbXB0eSggJGFzc29jX2FyZ3NbJ3N1YmRvbWFpbnMnXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiTXVsdGlzaXRlIHdpdGggc3ViZG9tYWlucyBjYW5ub3QgYmUgY29uZmlndXJlZCB3aGVuIGRvbWFpbiBpcyAnbG9jYWxob3N0Jy4iICk7CgkJfQoKCQkvLyBuZWVkIHRvIHJlZ2lzdGVyIHRoZSBtdWx0aXNpdGUgdGFibGVzIG1hbnVhbGx5IGZvciBzb21lIHJlYXNvbgoJCWZvcmVhY2ggKCAkd3BkYi0+dGFibGVzKCAnbXNfZ2xvYmFsJyApIGFzICR0YWJsZSA9PiAkcHJlZml4ZWRfdGFibGUgKSB7CgkJCSR3cGRiLT4kdGFibGUgPSAkcHJlZml4ZWRfdGFibGU7CgkJfQoKCQlpbnN0YWxsX25ldHdvcmsoKTsKCgkJJHJlc3VsdCA9IHBvcHVsYXRlX25ldHdvcmsoCgkJCSRhc3NvY19hcmdzWydzaXRlX2lkJ10sCgkJCSRkb21haW4sCgkJCWdldF9vcHRpb24oICdhZG1pbl9lbWFpbCcgKSwKCQkJJGFzc29jX2FyZ3NbJ3RpdGxlJ10sCgkJCSRhc3NvY19hcmdzWydiYXNlJ10sCgkJCSRhc3NvY19hcmdzWydzdWJkb21haW5zJ10KCQkpOwoKCQkkc2l0ZV9pZCA9ICR3cGRiLT5nZXRfdmFyKCAiU0VMRUNUIGlkIEZST00gJHdwZGItPnNpdGUiICk7CgkJJHNpdGVfaWQgPSAoIG51bGwgPT09ICRzaXRlX2lkICkgPyAxIDogKGludCkgJHNpdGVfaWQ7CgoJCWlmICggdHJ1ZSA9PT0gJHJlc3VsdCApIHsKCQkJV1BfQ0xJOjpsb2coICdTZXQgdXAgbXVsdGlzaXRlIGRhdGFiYXNlIHRhYmxlcy4nICk7CgkJfSBlbHNlaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlzd2l0Y2ggKCAkcmVzdWx0LT5nZXRfZXJyb3JfY29kZSgpICkgewoKCQkJCWNhc2UgJ3NpdGVpZF9leGlzdHMnOgoJCQkJCVdQX0NMSTo6bG9nKCAkcmVzdWx0LT5nZXRfZXJyb3JfbWVzc2FnZSgpICk7CgkJCQkJcmV0dXJuIGZhbHNlOwoKCQkJCWNhc2UgJ25vX3dpbGRjYXJkX2Rucyc6CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBfXyggJ1dpbGRjYXJkIEROUyBtYXkgbm90IGJlIGNvbmZpZ3VyZWQgY29ycmVjdGx5LicgKSApOwoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJV1BfQ0xJOjplcnJvciggJHJlc3VsdCApOwoJCQl9CgkJfQoKCQkvLyBkZWxldGVfc2l0ZV9vcHRpb24oKSBjbGVhbnMgdGhlIGFsbG9wdGlvbnMgY2FjaGUgdG8gcHJldmVudCBkdXBlIG9wdGlvbgoJCWRlbGV0ZV9zaXRlX29wdGlvbiggJ3VwbG9hZF9zcGFjZV9jaGVja19kaXNhYmxlZCcgKTsKCQl1cGRhdGVfc2l0ZV9vcHRpb24oICd1cGxvYWRfc3BhY2VfY2hlY2tfZGlzYWJsZWQnLCAxICk7CgoJCWlmICggISBpc19tdWx0aXNpdGUoKSApIHsKCQkJJHN1YmRvbWFpbl9leHBvcnQgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdzdWJkb21haW5zJyApID8gJ3RydWUnIDogJ2ZhbHNlJzsKCQkJJG1zX2NvbmZpZyAgICAgICAgPSA8PDxFT1QKZGVmaW5lKCAnV1BfQUxMT1dfTVVMVElTSVRFJywgdHJ1ZSApOwpkZWZpbmUoICdNVUxUSVNJVEUnLCB0cnVlICk7CmRlZmluZSggJ1NVQkRPTUFJTl9JTlNUQUxMJywgeyRzdWJkb21haW5fZXhwb3J0fSApOwpcJGJhc2UgPSAneyRhc3NvY19hcmdzWydiYXNlJ119JzsKZGVmaW5lKCAnRE9NQUlOX0NVUlJFTlRfU0lURScsICd7JGRvbWFpbn0nICk7CmRlZmluZSggJ1BBVEhfQ1VSUkVOVF9TSVRFJywgJ3skYXNzb2NfYXJnc1snYmFzZSddfScgKTsKZGVmaW5lKCAnU0lURV9JRF9DVVJSRU5UX1NJVEUnLCB7JHNpdGVfaWR9ICk7CmRlZmluZSggJ0JMT0dfSURfQ1VSUkVOVF9TSVRFJywgMSApOwpFT1Q7CgoJCQkkd3BfY29uZmlnX3BhdGggPSBVdGlsc1xsb2NhdGVfd3BfY29uZmlnKCk7CgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jb25maWcnICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIkFkZGl0aW9uIG9mIG11bHRpc2l0ZSBjb25zdGFudHMgdG8gJ3dwLWNvbmZpZy5waHAnIHNraXBwZWQuIFlvdSBuZWVkIHRvIGFkZCB0aGVtIG1hbnVhbGx5OlxueyRtc19jb25maWd9IiApOwoJCQl9IGVsc2VpZiAoIGlzX3dyaXRhYmxlKCAkd3BfY29uZmlnX3BhdGggKSAmJiBzZWxmOjptb2RpZnlfd3BfY29uZmlnKCAkbXNfY29uZmlnICkgKSB7CgkJCQlXUF9DTEk6OmxvZyggIkFkZGVkIG11bHRpc2l0ZSBjb25zdGFudHMgdG8gJ3dwLWNvbmZpZy5waHAnLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIk11bHRpc2l0ZSBjb25zdGFudHMgY291bGQgbm90IGJlIHdyaXR0ZW4gdG8gJ3dwLWNvbmZpZy5waHAnLiBZb3UgbWF5IG5lZWQgdG8gYWRkIHRoZW0gbWFudWFsbHk6XG57JG1zX2NvbmZpZ30iICk7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiBNdWx0aXNpdGUgY29uc3RhbnRzIGFyZSBkZWZpbmVkLCB0aGVyZWZvcmUgd2UgYWxyZWFkeSBoYXZlIGFuIGVtcHR5IHNpdGVfYWRtaW5zIHNpdGUgbWV0YS4KCQkJICoKCQkJICogQ29kZSBiYXNlZCBvbiBwYXJ0cyBvZiBkZWxldGVfbmV0d29ya19vcHRpb24uICovCgkJCSRyb3dzID0gJHdwZGItPmdldF9yZXN1bHRzKCAiU0VMRUNUIG1ldGFfaWQsIHNpdGVfaWQgRlJPTSB7JHdwZGItPnNpdGVtZXRhfSBXSEVSRSBtZXRhX2tleSA9ICdzaXRlX2FkbWlucycgQU5EIG1ldGFfdmFsdWUgPSAnJyIgKTsKCgkJCWZvcmVhY2ggKCAkcm93cyBhcyAkcm93ICkgewoJCQkJd3BfY2FjaGVfZGVsZXRlKCAieyRyb3ctPnNpdGVfaWR9OnNpdGVfYWRtaW5zIiwgJ3NpdGUtb3B0aW9ucycgKTsKCgkJCQkkd3BkYi0+ZGVsZXRlKAoJCQkJCSR3cGRiLT5zaXRlbWV0YSwKCQkJCQlbICdtZXRhX2lkJyA9PiAkcm93LT5tZXRhX2lkIF0KCQkJCSk7CgkJCX0KCQl9CgoJCXJldHVybiB0cnVlOwoJfQoKCS8vIGNvcGllZCBmcm9tIHBvcHVsYXRlX25ldHdvcmsoKQoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlX2luaXRpYWxfYmxvZyggJG5ldHdvcmtfaWQsICRibG9nX2lkLCAkZG9tYWluLCAkcGF0aCwKCQkkc3ViZG9tYWluX2luc3RhbGwsICRzaXRlX3VzZXIgKSB7CgkJZ2xvYmFsICR3cGRiLCAkY3VycmVudF9zaXRlLCAkd3BfcmV3cml0ZTsKCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5HbG9iYWxWYXJpYWJsZXNPdmVycmlkZS5Qcm9oaWJpdGVkIC0tIFRoaXMgaXMgbWVhbnQgdG8gcmVwbGFjZSBDb3JlIGZ1bmN0aW9uYWxpdHkuCgkJJGN1cnJlbnRfc2l0ZSAgICAgICAgICAgID0gbmV3IHN0ZENsYXNzKCk7CgkJJGN1cnJlbnRfc2l0ZS0+ZG9tYWluICAgID0gJGRvbWFpbjsKCQkkY3VycmVudF9zaXRlLT5wYXRoICAgICAgPSAkcGF0aDsKCQkkY3VycmVudF9zaXRlLT5zaXRlX25hbWUgPSB1Y2ZpcnN0KCAkZG9tYWluICk7CgkJJGJsb2dfZGF0YSAgICAgICAgICAgICAgID0gWwoJCQknc2l0ZV9pZCcgICAgPT4gJG5ldHdvcmtfaWQsCgkJCSdkb21haW4nICAgICA9PiAkZG9tYWluLAoJCQkncGF0aCcgICAgICAgPT4gJHBhdGgsCgkJCSdyZWdpc3RlcmVkJyA9PiBjdXJyZW50X3RpbWUoICdteXNxbCcgKSwKCQldOwoJCSR3cGRiLT5pbnNlcnQoICR3cGRiLT5ibG9ncywgJGJsb2dfZGF0YSApOwoJCSRjdXJyZW50X3NpdGUtPmJsb2dfaWQgPSAkd3BkYi0+aW5zZXJ0X2lkOwoJCSRibG9nX2lkICAgICAgICAgICAgICAgPSAkd3BkYi0+aW5zZXJ0X2lkOwoJCXVwZGF0ZV91c2VyX21ldGEoICRzaXRlX3VzZXItPklELCAnc291cmNlX2RvbWFpbicsICRkb21haW4gKTsKCQl1cGRhdGVfdXNlcl9tZXRhKCAkc2l0ZV91c2VyLT5JRCwgJ3ByaW1hcnlfYmxvZycsICRibG9nX2lkICk7CgoJCWlmICggJHN1YmRvbWFpbl9pbnN0YWxsICkgewoJCQkkd3BfcmV3cml0ZS0+c2V0X3Blcm1hbGlua19zdHJ1Y3R1cmUoICcvJXllYXIlLyVtb250aG51bSUvJWRheSUvJXBvc3RuYW1lJS8nICk7CgkJfSBlbHNlIHsKCQkJJHdwX3Jld3JpdGUtPnNldF9wZXJtYWxpbmtfc3RydWN0dXJlKCAnL2Jsb2cvJXllYXIlLyVtb250aG51bSUvJWRheSUvJXBvc3RuYW1lJS8nICk7CgkJfQoKCQlmbHVzaF9yZXdyaXRlX3J1bGVzKCk7Cgl9CgoJLy8gY29waWVkIGZyb20gcG9wdWxhdGVfbmV0d29yaygpCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBhZGRfc2l0ZV9hZG1pbnMoICRzaXRlX3VzZXIgKSB7CgkJJHNpdGVfYWRtaW5zID0gWyAkc2l0ZV91c2VyLT51c2VyX2xvZ2luIF07CgkJJHVzZXJzICAgICAgID0gZ2V0X3VzZXJzKCBbICdmaWVsZHMnID0+IFsgJ0lEJywgJ3VzZXJfbG9naW4nIF0gXSApOwoJCWlmICggJHVzZXJzICkgewoJCQlmb3JlYWNoICggJHVzZXJzIGFzICR1c2VyICkgewoJCQkJaWYgKCBpc19zdXBlcl9hZG1pbiggJHVzZXItPklEICkKCQkJCQkmJiAhIGluX2FycmF5KCAkdXNlci0+dXNlcl9sb2dpbiwgJHNpdGVfYWRtaW5zLCB0cnVlICkgKSB7CgkJCQkJJHNpdGVfYWRtaW5zW10gPSAkdXNlci0+dXNlcl9sb2dpbjsKCQkJCX0KCQkJfQoJCX0KCgkJdXBkYXRlX3NpdGVfb3B0aW9uKCAnc2l0ZV9hZG1pbnMnLCAkc2l0ZV9hZG1pbnMgKTsKCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBtb2RpZnlfd3BfY29uZmlnKCAkY29udGVudCApIHsKCQkkd3BfY29uZmlnX3BhdGggPSBVdGlsc1xsb2NhdGVfd3BfY29uZmlnKCk7CgoJCSR0b2tlbiAgICAgICAgICAgPSAiLyogVGhhdCdzIGFsbCwgc3RvcCBlZGl0aW5nISI7CgkJJGNvbmZpZ19jb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkd3BfY29uZmlnX3BhdGggKTsKCQlpZiAoIGZhbHNlID09PSBzdHJwb3MoICRjb25maWdfY29udGVudHMsICR0b2tlbiApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlsaXN0KCAkYmVmb3JlLCAkYWZ0ZXIgKSA9IGV4cGxvZGUoICR0b2tlbiwgJGNvbmZpZ19jb250ZW50cyApOwoKCQkkY29udGVudCA9IHRyaW0oICRjb250ZW50ICk7CgoJCWZpbGVfcHV0X2NvbnRlbnRzKAoJCQkkd3BfY29uZmlnX3BhdGgsCgkJCSJ7JGJlZm9yZX1cblxueyRjb250ZW50fVxuXG57JHRva2VufXskYWZ0ZXJ9IgoJCSk7CgoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9jbGVhbl9iYXNlZG9tYWluKCkgewoJCSRkb21haW4gPSBwcmVnX3JlcGxhY2UoICd8aHR0cHM/Oi8vfCcsICcnLCBnZXRfb3B0aW9uKCAnc2l0ZXVybCcgKSApOwoJCSRzbGFzaCAgPSBzdHJwb3MoICRkb21haW4sICcvJyApOwoJCWlmICggZmFsc2UgIT09ICRzbGFzaCApIHsKCQkJJGRvbWFpbiA9IHN1YnN0ciggJGRvbWFpbiwgMCwgJHNsYXNoICk7CgkJfQoJCXJldHVybiAkZG9tYWluOwoJfQoKCS8qKgoJICogRGlzcGxheXMgdGhlIFdvcmRQcmVzcyB2ZXJzaW9uLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1leHRyYV0KCSAqIDogU2hvdyBleHRlbmRlZCB2ZXJzaW9uIGluZm9ybWF0aW9uLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzcGxheSB0aGUgV29yZFByZXNzIHZlcnNpb24KCSAqICAgICAkIHdwIGNvcmUgdmVyc2lvbgoJICogICAgIDQuNS4yCgkgKgoJICogICAgICMgRGlzcGxheSBXb3JkUHJlc3MgdmVyc2lvbiBhbG9uZyB3aXRoIG90aGVyIGluZm9ybWF0aW9uCgkgKiAgICAgJCB3cCBjb3JlIHZlcnNpb24gLS1leHRyYQoJICogICAgIFdvcmRQcmVzcyB2ZXJzaW9uOiA0LjUuMgoJICogICAgIERhdGFiYXNlIHJldmlzaW9uOiAzNjY4NgoJICogICAgIFRpbnlNQ0UgdmVyc2lvbjogICA0LjMxMCAoNDMxMC0yMDE2MDQxOCkKCSAqICAgICBQYWNrYWdlIGxhbmd1YWdlOiAgZW5fVVMKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gdmVyc2lvbiggJGFyZ3MgPSBbXSwgJGFzc29jX2FyZ3MgPSBbXSApIHsKCQkkZGV0YWlscyA9IHNlbGY6OmdldF93cF9kZXRhaWxzKCk7CgoJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleHRyYScgKSApIHsKCQkJV1BfQ0xJOjpsaW5lKCAkZGV0YWlsc1snd3BfdmVyc2lvbiddICk7CgkJCXJldHVybjsKCQl9CgoJCSRtYXRjaCAgICAgICAgICAgICAgICAgICA9IFtdOwoJCSRmb3VuZF92ZXJzaW9uICAgICAgICAgICA9IHByZWdfbWF0Y2goICcvKFxkKShcZCspLS8nLCAkZGV0YWlsc1sndGlueW1jZV92ZXJzaW9uJ10sICRtYXRjaCApOwoJCSRodW1hbl9yZWFkYWJsZV90aW55X21jZSA9ICRmb3VuZF92ZXJzaW9uID8gInskbWF0Y2hbMV19LnskbWF0Y2hbMl19IiA6ICcnOwoKCQllY2hvIFV0aWxzXG11c3RhY2hlX3JlbmRlcigKCQkJc2VsZjo6Z2V0X3RlbXBsYXRlX3BhdGgoICd2ZXJzaW9ucy5tdXN0YWNoZScgKSwKCQkJWwoJCQkJJ3dwLXZlcnNpb24nICAgID0+ICRkZXRhaWxzWyd3cF92ZXJzaW9uJ10sCgkJCQknZGItdmVyc2lvbicgICAgPT4gJGRldGFpbHNbJ3dwX2RiX3ZlcnNpb24nXSwKCQkJCSdsb2NhbC1wYWNrYWdlJyA9PiBlbXB0eSggJGRldGFpbHNbJ3dwX2xvY2FsX3BhY2thZ2UnXSApCgkJCQkJPyAnZW5fVVMnCgkJCQkJOiAkZGV0YWlsc1snd3BfbG9jYWxfcGFja2FnZSddLAoJCQkJJ21jZS12ZXJzaW9uJyAgID0+ICRodW1hbl9yZWFkYWJsZV90aW55X21jZQoJCQkJCT8gInskaHVtYW5fcmVhZGFibGVfdGlueV9tY2V9ICh7JGRldGFpbHNbJ3RpbnltY2VfdmVyc2lvbiddfSkiCgkJCQkJOiAkZGV0YWlsc1sndGlueW1jZV92ZXJzaW9uJ10sCgkJCV0KCQkpOwoJfQoKCS8qKgoJICogR2V0cyB2ZXJzaW9uIGluZm9ybWF0aW9uIGZyb20gYHdwLWluY2x1ZGVzL3ZlcnNpb24ucGhwYC4KCSAqCgkgKiBAcmV0dXJuIGFycmF5IHsKCSAqICAgICBAdHlwZSBzdHJpbmcgJHdwX3ZlcnNpb24gVGhlIFdvcmRQcmVzcyB2ZXJzaW9uLgoJICogICAgIEB0eXBlIGludCAkd3BfZGJfdmVyc2lvbiBUaGUgV29yZFByZXNzIERCIHJldmlzaW9uLgoJICogICAgIEB0eXBlIHN0cmluZyAkdGlueW1jZV92ZXJzaW9uIFRoZSBUaW55TUNFIHZlcnNpb24uCgkgKiAgICAgQHR5cGUgc3RyaW5nICR3cF9sb2NhbF9wYWNrYWdlIFRoZSBUaW55TUNFIHZlcnNpb24uCgkgKiB9CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF93cF9kZXRhaWxzKCAkYWJzcGF0aCA9IEFCU1BBVEggKSB7CgkJJHZlcnNpb25zX3BhdGggPSAkYWJzcGF0aCAuICd3cC1pbmNsdWRlcy92ZXJzaW9uLnBocCc7CgoJCWlmICggISBpc19yZWFkYWJsZSggJHZlcnNpb25zX3BhdGggKSApIHsKCQkJV1BfQ0xJOjplcnJvcigKCQkJCSJUaGlzIGRvZXMgbm90IHNlZW0gdG8gYmUgYSBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uLlxuIiAuCgkJCQknUGFzcyAtLXBhdGg9YHBhdGgvdG8vd29yZHByZXNzYCBvciBydW4gYHdwIGNvcmUgZG93bmxvYWRgLicKCQkJKTsKCQl9CgoJCSR2ZXJzaW9uX2NvbnRlbnQgPSBmaWxlX2dldF9jb250ZW50cyggJHZlcnNpb25zX3BhdGgsIG51bGwsIG51bGwsIDYsIDIwNDggKTsKCgkJJHZhcnMgICA9IFsgJ3dwX3ZlcnNpb24nLCAnd3BfZGJfdmVyc2lvbicsICd0aW55bWNlX3ZlcnNpb24nLCAnd3BfbG9jYWxfcGFja2FnZScgXTsKCQkkcmVzdWx0ID0gW107CgoJCWZvcmVhY2ggKCAkdmFycyBhcyAkdmFyX25hbWUgKSB7CgkJCSRyZXN1bHRbICR2YXJfbmFtZSBdID0gc2VsZjo6ZmluZF92YXIoICR2YXJfbmFtZSwgJHZlcnNpb25fY29udGVudCApOwoJCX0KCgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB0ZW1wbGF0ZSBwYXRoIGJhc2VkIG9uIGluc3RhbGxhdGlvbiB0eXBlLgoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfdGVtcGxhdGVfcGF0aCggJHRlbXBsYXRlICkgewoJCSRjb21tYW5kX3Jvb3QgID0gVXRpbHNccGhhcl9zYWZlX3BhdGgoIGRpcm5hbWUoIF9fRElSX18gKSApOwoJCSR0ZW1wbGF0ZV9wYXRoID0gInskY29tbWFuZF9yb290fS90ZW1wbGF0ZXMveyR0ZW1wbGF0ZX0iOwoKCQlpZiAoICEgZmlsZV9leGlzdHMoICR0ZW1wbGF0ZV9wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBmaW5kIHskdGVtcGxhdGV9IiApOwoJCX0KCgkJcmV0dXJuICR0ZW1wbGF0ZV9wYXRoOwoJfQoKCS8qKgoJICogU2VhcmNoZXMgZm9yIHRoZSB2YWx1ZSBhc3NpZ25lZCB0byB2YXJpYWJsZSBgJHZhcl9uYW1lYCBpbiBQSFAgY29kZSBgJGNvZGVgLgoJICoKCSAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byBtYXRjaGluZyB0aGUgYFwkVkFSX05BTUUgPSAoW147XSspYCByZWd1bGFyIGV4cHJlc3Npb24gYW5kIHJldHVybmluZwoJICogdGhlIGZpcnN0IG1hdGNoIGVpdGhlciBhcyBhIGBzdHJpbmdgIG9yIGFzIGFuIGBpbnRlZ2VyYCAoZGVwZW5kaW5nIGlmIGl0J3Mgc3Vycm91bmRlZCBieQoJICogcXVvdGVzIG9yIG5vdCkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdmFyX25hbWUgVmFyaWFibGUgbmFtZSB0byBzZWFyY2ggZm9yLgoJICogQHBhcmFtIHN0cmluZyAkY29kZSBQSFAgY29kZSB0byBzZWFyY2ggaW4uCgkgKgoJICogQHJldHVybiBpbnR8c3RyaW5nfG51bGwKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZmluZF92YXIoICR2YXJfbmFtZSwgJGNvZGUgKSB7CgkJJHN0YXJ0ID0gc3RycG9zKCAkY29kZSwgJyQnIC4gJHZhcl9uYW1lIC4gJyA9ICcgKTsKCgkJaWYgKCAhICRzdGFydCApIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQkkc3RhcnQgPSAkc3RhcnQgKyBzdHJsZW4oICR2YXJfbmFtZSApICsgMzsKCQkkZW5kICAgPSBzdHJwb3MoICRjb2RlLCAnOycsICRzdGFydCApOwoKCQkkdmFsdWUgPSBzdWJzdHIoICRjb2RlLCAkc3RhcnQsICRlbmQgLSAkc3RhcnQgKTsKCgkJcmV0dXJuIHRyaW0oICR2YWx1ZSwgIiAnIiApOwoJfQoKCS8qKgoJICogU2VjdXJpdHkgY29weSBvZiB0aGUgY29yZSBmdW5jdGlvbiB3aXRoIFJlcXVlc3RzIC0gR2V0cyB0aGUgY2hlY2tzdW1zIGZvciB0aGUgZ2l2ZW4gdmVyc2lvbiBvZiBXb3JkUHJlc3MuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgVmVyc2lvbiBzdHJpbmcgdG8gcXVlcnkuCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUgICBMb2NhbGUgdG8gcXVlcnkuCgkgKiBAcGFyYW0gYm9vbCAgICRpbnNlY3VyZSBXaGV0aGVyIHRvIHJldHJ5IHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBvbiBUTFMgaGFuZHNoYWtlIGZhaWx1cmUuCgkgKiBAcmV0dXJuIHN0cmluZ3xhcnJheSBTdHJpbmcgbWVzc2FnZSBvbiBmYWlsdXJlLiBBbiBhcnJheSBvZiBjaGVja3N1bXMgb24gc3VjY2Vzcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X2NvcmVfY2hlY2tzdW1zKCAkdmVyc2lvbiwgJGxvY2FsZSwgJGluc2VjdXJlICkgewoJCSRxdWVyeSA9IGh0dHBfYnVpbGRfcXVlcnkoIGNvbXBhY3QoICd2ZXJzaW9uJywgJ2xvY2FsZScgKSwgbnVsbCwgJyYnICk7CgkJJHVybCAgID0gImh0dHBzOi8vYXBpLndvcmRwcmVzcy5vcmcvY29yZS9jaGVja3N1bXMvMS4wLz97JHF1ZXJ5fSI7CgoJCSRoZWFkZXJzID0gWyAnQWNjZXB0JyA9PiAnYXBwbGljYXRpb24vanNvbicgXTsKCQkkb3B0aW9ucyA9IFsKCQkJJ3RpbWVvdXQnICA9PiAzMCwKCQkJJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUsCgkJXTsKCgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHVybCwgbnVsbCwgJGhlYWRlcnMsICRvcHRpb25zICk7CgoJCWlmICggISAkcmVzcG9uc2UtPnN1Y2Nlc3MgfHwgMjAwICE9PSAoaW50KSAkcmVzcG9uc2UtPnN0YXR1c19jb2RlICkgewoJCQlyZXR1cm4gIkNoZWNrc3VtIHJlcXVlc3QgJ3skdXJsfScgZmFpbGVkIChIVFRQIHskcmVzcG9uc2UtPnN0YXR1c19jb2RlfSkuIjsKCQl9CgoJCSRib2R5ID0gdHJpbSggJHJlc3BvbnNlLT5ib2R5ICk7CgkJJGJvZHkgPSBqc29uX2RlY29kZSggJGJvZHksIHRydWUgKTsKCgkJaWYgKCAhIGlzX2FycmF5KCAkYm9keSApCgkJCXx8ICEgaXNzZXQoICRib2R5WydjaGVja3N1bXMnXSApCgkJCXx8ICEgaXNfYXJyYXkoICRib2R5WydjaGVja3N1bXMnXSApICkgewoJCQlyZXR1cm4gIkNoZWNrc3VtcyBub3QgYXZhaWxhYmxlIGZvciBXb3JkUHJlc3MgeyR2ZXJzaW9ufS97JGxvY2FsZX0uIjsKCQl9CgoJCXJldHVybiAkYm9keVsnY2hlY2tzdW1zJ107Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIFdvcmRQcmVzcyB0byBhIG5ld2VyIHZlcnNpb24uCgkgKgoJICogRGVmYXVsdHMgdG8gdXBkYXRpbmcgV29yZFByZXNzIHRvIHRoZSBsYXRlc3QgdmVyc2lvbi4KCSAqCgkgKiBJZiB5b3Ugc2VlICJFcnJvcjogQW5vdGhlciB1cGRhdGUgaXMgY3VycmVudGx5IGluIHByb2dyZXNzLiIsIHlvdSBtYXkKCSAqIG5lZWQgdG8gcnVuIGB3cCBvcHRpb24gZGVsZXRlIGNvcmVfdXBkYXRlci5sb2NrYCBhZnRlciB2ZXJpZnlpbmcgYW5vdGhlcgoJICogdXBkYXRlIGlzbid0IGFjdHVhbGx5IHJ1bm5pbmcuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8emlwPl0KCSAqIDogUGF0aCB0byB6aXAgZmlsZSB0byB1c2UsIGluc3RlYWQgb2YgZG93bmxvYWRpbmcgZnJvbSB3b3JkcHJlc3Mub3JnLgoJICoKCSAqIFstLW1pbm9yXQoJICogOiBPbmx5IHBlcmZvcm0gdXBkYXRlcyBmb3IgbWlub3IgcmVsZWFzZXMgKGUuZy4gdXBkYXRlIGZyb20gV1AgNC4zIHRvIDQuMy4zIGluc3RlYWQgb2YgNC40LjIpLgoJICoKCSAqIFstLXZlcnNpb249PHZlcnNpb24+XQoJICogOiBVcGRhdGUgdG8gYSBzcGVjaWZpYyB2ZXJzaW9uLCBpbnN0ZWFkIG9mIHRvIHRoZSBsYXRlc3QgdmVyc2lvbi4gQWx0ZXJuYXRpdmVseSBhY2NlcHRzICduaWdodGx5Jy4KCSAqCgkgKiBbLS1mb3JjZV0KCSAqIDogVXBkYXRlIGV2ZW4gd2hlbiBpbnN0YWxsZWQgV1AgdmVyc2lvbiBpcyBncmVhdGVyIHRoYW4gdGhlIHJlcXVlc3RlZCB2ZXJzaW9uLgoJICoKCSAqIFstLWxvY2FsZT08bG9jYWxlPl0KCSAqIDogU2VsZWN0IHdoaWNoIGxhbmd1YWdlIHlvdSB3YW50IHRvIGRvd25sb2FkLgoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBkb3dubG9hZCB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBVcGRhdGUgV29yZFByZXNzCgkgKiAgICAgJCB3cCBjb3JlIHVwZGF0ZQoJICogICAgIFVwZGF0aW5nIHRvIHZlcnNpb24gNC41LjIgKGVuX1VTKS4uLgoJICogICAgIERvd25sb2FkaW5nIHVwZGF0ZSBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvcmVsZWFzZS93b3JkcHJlc3MtNC41LjItbm8tY29udGVudC56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIENsZWFuaW5nIHVwIGZpbGVzLi4uCgkgKiAgICAgTm8gZmlsZXMgZm91bmQgdGhhdCBuZWVkIGNsZWFuaW5nIHVwCgkgKiAgICAgU3VjY2VzczogV29yZFByZXNzIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICoKCSAqICAgICAjIFVwZGF0ZSBXb3JkUHJlc3MgdG8gbGF0ZXN0IHZlcnNpb24gb2YgMy44IHJlbGVhc2UKCSAqICAgICAkIHdwIGNvcmUgdXBkYXRlIC0tdmVyc2lvbj0zLjggLi4vbGF0ZXN0LnppcAoJICogICAgIFVwZGF0aW5nIHRvIHZlcnNpb24gMy44ICgpLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBDbGVhbmluZyB1cCBmaWxlcy4uLgoJICogICAgIEZpbGUgcmVtb3ZlZDogd3AtYWRtaW4vanMvdGFncy1ib3guanMKCSAqICAgICAuLi4KCSAqICAgICBGaWxlIHJlbW92ZWQ6IHdwLWFkbWluL2pzL3VwZGF0ZXMubWluLgoJICogICAgIDM3NyBmaWxlcyBjbGVhbmVkIHVwCgkgKiAgICAgU3VjY2VzczogV29yZFByZXNzIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICoKCSAqICAgICAjIFVwZGF0ZSBXb3JkUHJlc3MgdG8gMy4xIGZvcmNlZnVsbHkKCSAqICAgICAkIHdwIGNvcmUgdXBkYXRlIC0tdmVyc2lvbj0zLjEgLS1mb3JjZQoJICogICAgIFVwZGF0aW5nIHRvIHZlcnNpb24gMy4xIChlbl9VUykuLi4KCSAqICAgICBEb3dubG9hZGluZyB1cGRhdGUgZnJvbSBodHRwczovL3dvcmRwcmVzcy5vcmcvd29yZHByZXNzLTMuMS56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIFdhcm5pbmc6IENoZWNrc3VtcyBub3QgYXZhaWxhYmxlIGZvciBXb3JkUHJlc3MgMy4xL2VuX1VTLiBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4KCSAqICAgICBTdWNjZXNzOiBXb3JkUHJlc3MgdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKgoJICogQGFsaWFzIHVwZ3JhZGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWdsb2JhbCAkd3BfdmVyc2lvbjsKCgkJJHVwZGF0ZSAgID0gbnVsbDsKCQkkdXBncmFkZXIgPSAnV1BfQ0xJXFxDb3JlXFxDb3JlVXBncmFkZXInOwoKCQlpZiAoICd0cnVuaycgPT09IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3ZlcnNpb24nICkgKSB7CgkJCSRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gPSAnbmlnaHRseSc7CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhcmdzWzBdICkgKSB7CgoJCQkvLyBaSVAgcGF0aCBvciBVUkwgaXMgZ2l2ZW4KCQkJJHVwZ3JhZGVyID0gJ1dQX0NMSVxcQ29yZVxcTm9uRGVzdHJ1Y3RpdmVDb3JlVXBncmFkZXInOwoJCQkkdmVyc2lvbiAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2ZXJzaW9uJyApOwoKCQkJJHVwZGF0ZSA9IChvYmplY3QpIFsKCQkJCSdyZXNwb25zZScgPT4gJ3VwZ3JhZGUnLAoJCQkJJ2N1cnJlbnQnICA9PiAkdmVyc2lvbiwKCQkJCSdkb3dubG9hZCcgPT4gJGFyZ3NbMF0sCgkJCQkncGFja2FnZXMnID0+IChvYmplY3QpIFsKCQkJCQkncGFydGlhbCcgICAgID0+IG51bGwsCgkJCQkJJ25ld19idW5kbGVkJyA9PiBudWxsLAoJCQkJCSdub19jb250ZW50JyAgPT4gbnVsbCwKCQkJCQknZnVsbCcgICAgICAgID0+ICRhcmdzWzBdLAoJCQkJXSwKCQkJCSd2ZXJzaW9uJyAgPT4gJHZlcnNpb24sCgkJCQknbG9jYWxlJyAgID0+IG51bGwsCgkJCV07CgoJCX0gZWxzZWlmICggZW1wdHkoICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10gKSApIHsKCgkJCS8vIFVwZGF0ZSB0byBuZXh0IHJlbGVhc2UKCQkJd3BfdmVyc2lvbl9jaGVjaygpOwoJCQkkZnJvbV9hcGkgPSBnZXRfc2l0ZV90cmFuc2llbnQoICd1cGRhdGVfY29yZScgKTsKCgkJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbWlub3InICkgKSB7CgkJCQlmb3JlYWNoICggJGZyb21fYXBpLT51cGRhdGVzIGFzICRvZmZlciApIHsKCQkJCQkkc2VtX3ZlciA9IFV0aWxzXGdldF9uYW1lZF9zZW1fdmVyKCAkb2ZmZXItPnZlcnNpb24sICR3cF92ZXJzaW9uICk7CgkJCQkJaWYgKCAhICRzZW1fdmVyIHx8ICdwYXRjaCcgIT09ICRzZW1fdmVyICkgewoJCQkJCQljb250aW51ZTsKCQkJCQl9CgkJCQkJJHVwZGF0ZSA9ICRvZmZlcjsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWlmICggZW1wdHkoICR1cGRhdGUgKSApIHsKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdXb3JkUHJlc3MgaXMgYXQgdGhlIGxhdGVzdCBtaW5vciByZWxlYXNlLicgKTsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlpZiAoICEgZW1wdHkoICRmcm9tX2FwaS0+dXBkYXRlcyApICkgewoJCQkJCWxpc3QoICR1cGRhdGUgKSA9ICRmcm9tX2FwaS0+dXBkYXRlczsKCQkJCX0KCQkJfQoJCX0gZWxzZWlmICggVXRpbHNcd3BfdmVyc2lvbl9jb21wYXJlKCAkYXNzb2NfYXJnc1sndmVyc2lvbiddLCAnPCcgKQoJCQl8fCAnbmlnaHRseScgPT09ICRhc3NvY19hcmdzWyd2ZXJzaW9uJ10KCQkJfHwgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICkgKSB7CgoJCQkvLyBTcGVjaWZpYyB2ZXJzaW9uIGlzIGdpdmVuCgkJCSR2ZXJzaW9uID0gJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXTsKCQkJJGxvY2FsZSAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsb2NhbGUnLCBnZXRfbG9jYWxlKCkgKTsKCgkJCSRuZXdfcGFja2FnZSA9ICR0aGlzLT5nZXRfZG93bmxvYWRfdXJsKCAkdmVyc2lvbiwgJGxvY2FsZSApOwoKCQkJJHVwZGF0ZSA9IChvYmplY3QpIFsKCQkJCSdyZXNwb25zZScgPT4gJ3VwZ3JhZGUnLAoJCQkJJ2N1cnJlbnQnICA9PiAkYXNzb2NfYXJnc1sndmVyc2lvbiddLAoJCQkJJ2Rvd25sb2FkJyA9PiAkbmV3X3BhY2thZ2UsCgkJCQkncGFja2FnZXMnID0+IChvYmplY3QpIFsKCQkJCQkncGFydGlhbCcgICAgID0+IG51bGwsCgkJCQkJJ25ld19idW5kbGVkJyA9PiBudWxsLAoJCQkJCSdub19jb250ZW50JyAgPT4gbnVsbCwKCQkJCQknZnVsbCcgICAgICAgID0+ICRuZXdfcGFja2FnZSwKCQkJCV0sCgkJCQkndmVyc2lvbicgID0+ICR2ZXJzaW9uLAoJCQkJJ2xvY2FsZScgICA9PiAkbG9jYWxlLAoJCQldOwoKCQl9CgoJCWlmICggISBlbXB0eSggJHVwZGF0ZSApCgkJCSYmICggJHVwZGF0ZS0+dmVyc2lvbiAhPT0gJHdwX3ZlcnNpb24KCQkJfHwgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICkgKSApIHsKCgkJCXJlcXVpcmVfb25jZSBBQlNQQVRIIC4gJ3dwLWFkbWluL2luY2x1ZGVzL3VwZ3JhZGUucGhwJzsKCgkJCWlmICggJHVwZGF0ZS0+dmVyc2lvbiApIHsKCQkJCVdQX0NMSTo6bG9nKCAiVXBkYXRpbmcgdG8gdmVyc2lvbiB7JHVwZGF0ZS0+dmVyc2lvbn0gKHskdXBkYXRlLT5sb2NhbGV9KS4uLiIgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAnU3RhcnRpbmcgdXBkYXRlLi4uJyApOwoJCQl9CgoJCQkkZnJvbV92ZXJzaW9uID0gJHdwX3ZlcnNpb247CgkJCSRpbnNlY3VyZSAgICAgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApOwoKCQkJJEdMT0JBTFNbJ3dwY2xpX2NvcmVfdXBkYXRlX29iaiddID0gJHVwZGF0ZTsKCQkJJHJlc3VsdCAgICAgICAgICAgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X3VwZ3JhZGVyKCAkdXBncmFkZXIsICRpbnNlY3VyZSApLT51cGdyYWRlKCAkdXBkYXRlICk7CgkJCXVuc2V0KCAkR0xPQkFMU1snd3BjbGlfY29yZV91cGRhdGVfb2JqJ10gKTsKCgkJCWlmICggaXNfd3BfZXJyb3IoICRyZXN1bHQgKSApIHsKCQkJCSRtZXNzYWdlID0gV1BfQ0xJOjplcnJvcl90b19zdHJpbmcoICRyZXN1bHQgKTsKCQkJCWlmICggJ3VwX3RvX2RhdGUnICE9PSAkcmVzdWx0LT5nZXRfZXJyb3JfY29kZSgpICkgewoJCQkJCVdQX0NMSTo6ZXJyb3IoICRtZXNzYWdlICk7CgkJCQl9IGVsc2UgewoJCQkJCVdQX0NMSTo6c3VjY2VzcyggJG1lc3NhZ2UgKTsKCQkJCX0KCQkJfSBlbHNlIHsKCgkJCQkkdG9fdmVyc2lvbiA9ICcnOwoJCQkJaWYgKCBmaWxlX2V4aXN0cyggQUJTUEFUSCAuICd3cC1pbmNsdWRlcy92ZXJzaW9uLnBocCcgKSApIHsKCQkJCQkkd3BfZGV0YWlscyA9IHNlbGY6OmdldF93cF9kZXRhaWxzKCk7CgkJCQkJJHRvX3ZlcnNpb24gPSAkd3BfZGV0YWlsc1snd3BfdmVyc2lvbiddOwoJCQkJfQoKCQkJCSRsb2NhbGUgPSAoc3RyaW5nKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdsb2NhbGUnLCBnZXRfbG9jYWxlKCkgKTsKCQkJCSR0aGlzLT5jbGVhbnVwX2V4dHJhX2ZpbGVzKCAkZnJvbV92ZXJzaW9uLCAkdG9fdmVyc2lvbiwgJGxvY2FsZSwgJGluc2VjdXJlICk7CgoJCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LicgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1dvcmRQcmVzcyBpcyB1cCB0byBkYXRlLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBSdW5zIHRoZSBXb3JkUHJlc3MgZGF0YWJhc2UgdXBkYXRlIHByb2NlZHVyZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBVcGRhdGUgZGF0YWJhc2VzIGZvciBhbGwgc2l0ZXMgb24gYSBuZXR3b3JrCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogQ29tcGFyZSBkYXRhYmFzZSB2ZXJzaW9ucyB3aXRob3V0IHBlcmZvcm1pbmcgdGhlIHVwZGF0ZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFVwZGF0ZSB0aGUgV29yZFByZXNzIGRhdGFiYXNlCgkgKiAgICAgJCB3cCBjb3JlIHVwZGF0ZS1kYgoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBkYXRhYmFzZSB1cGdyYWRlZCBzdWNjZXNzZnVsbHkgZnJvbSBkYiB2ZXJzaW9uIDM2Njg2IHRvIDM1NzAwLgoJICoKCSAqICAgICAjIFVwZGF0ZSBkYXRhYmFzZXMgZm9yIGFsbCBzaXRlcyBvbiBhIG5ldHdvcmsKCSAqICAgICAkIHdwIGNvcmUgdXBkYXRlLWRiIC0tbmV0d29yawoJICogICAgIFdvcmRQcmVzcyBkYXRhYmFzZSB1cGdyYWRlZCBzdWNjZXNzZnVsbHkgZnJvbSBkYiB2ZXJzaW9uIDM1NzAwIHRvIDI5NjMwIG9uIGV4YW1wbGUuY29tLwoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBkYXRhYmFzZSB1cGdyYWRlZCBvbiAxMjMvMTIzIHNpdGVzCgkgKgoJICogQHN1YmNvbW1hbmQgdXBkYXRlLWRiCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGVfZGIoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGIsICR3cF9kYl92ZXJzaW9uLCAkd3BfY3VycmVudF9kYl92ZXJzaW9uOwoKCQkkbmV0d29yayA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICk7CgkJaWYgKCAkbmV0d29yayAmJiAhIGlzX211bHRpc2l0ZSgpICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQl9CgoJCSRkcnlfcnVuID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKTsKCQlpZiAoICRkcnlfcnVuICkgewoJCQlXUF9DTEk6OmxvZyggJ1BlcmZvcm1pbmcgYSBkcnkgcnVuLCB3aXRoIG5vIGRhdGFiYXNlIG1vZGlmaWNhdGlvbi4nICk7CgkJfQoKCQlpZiAoICRuZXR3b3JrICkgewoJCQkkaXRlcmF0b3JfYXJncyA9IFsKCQkJCSd0YWJsZScgPT4gJHdwZGItPmJsb2dzLAoJCQkJJ3doZXJlJyA9PiBbCgkJCQkJJ3NwYW0nICAgICA9PiAwLAoJCQkJCSdkZWxldGVkJyAgPT4gMCwKCQkJCQknYXJjaGl2ZWQnID0+IDAsCgkJCQldLAoJCQldOwoJCQkkaXQgICAgICAgICAgICA9IG5ldyBUYWJsZUl0ZXJhdG9yKCAkaXRlcmF0b3JfYXJncyApOwoJCQkkc3VjY2VzcyAgICAgICA9IDA7CgkJCSR0b3RhbCAgICAgICAgID0gMDsKCQkJJHNpdGVfaWRzICAgICAgPSBbXTsKCQkJZm9yZWFjaCAoICRpdCBhcyAkYmxvZyApIHsKCQkJCSR0b3RhbCsrOwoJCQkJJHNpdGVfaWRzW10gPSAkYmxvZy0+c2l0ZV9pZDsKCQkJCSR1cmwgICAgICAgID0gJGJsb2ctPmRvbWFpbiAuICRibG9nLT5wYXRoOwoJCQkJJGNtZCAgICAgICAgPSAiLS11cmw9eyR1cmx9IGNvcmUgdXBkYXRlLWRiIjsKCQkJCWlmICggJGRyeV9ydW4gKSB7CgkJCQkJJGNtZCAuPSAnIC0tZHJ5LXJ1bic7CgkJCQl9CgkJCQkkcHJvY2VzcyA9IFdQX0NMSTo6cnVuY29tbWFuZCggJGNtZCwgWyAncmV0dXJuJyA9PiAnYWxsJyBdICk7CgkJCQlpZiAoIDAgPT09IChpbnQpICRwcm9jZXNzLT5yZXR1cm5fY29kZSApIHsKCQkJCQkvLyBTZWUgaWYgd2UgY2FuIHBhcnNlIHRoZSBzdGRvdXQKCQkJCQlpZiAoIHByZWdfbWF0Y2goICcjU3VjY2VzczogKC4rKSMnLCAkcHJvY2Vzcy0+c3Rkb3V0LCAkbWF0Y2hlcyApICkgewoJCQkJCQkkbWVzc2FnZSA9IHJ0cmltKCAkbWF0Y2hlc1sxXSwgJy4nICk7CgkJCQkJCSRtZXNzYWdlID0gInskbWVzc2FnZX0gb24geyR1cmx9IjsKCQkJCQl9IGVsc2UgewoJCQkJCQkkbWVzc2FnZSA9ICJEYXRhYmFzZSB1cGdyYWRlZCBzdWNjZXNzZnVsbHkgb24geyR1cmx9IjsKCQkJCQl9CgkJCQkJV1BfQ0xJOjpsb2coICRtZXNzYWdlICk7CgkJCQkJJHN1Y2Nlc3MrKzsKCQkJCX0gZWxzZSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiRGF0YWJhc2UgZmFpbGVkIHRvIHVwZ3JhZGUgb24geyR1cmx9IiApOwoJCQkJfQoJCQl9CgkJCWlmICggISAkZHJ5X3J1biAmJiAkdG90YWwgJiYgJHN1Y2Nlc3MgPT09ICR0b3RhbCApIHsKCQkJCWZvcmVhY2ggKCBhcnJheV91bmlxdWUoICRzaXRlX2lkcyApIGFzICRzaXRlX2lkICkgewoJCQkJCXVwZGF0ZV9tZXRhZGF0YSggJ3NpdGUnLCAkc2l0ZV9pZCwgJ3dwbXVfdXBncmFkZV9zaXRlJywgJHdwX2RiX3ZlcnNpb24gKTsKCQkJCX0KCQkJfQoJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgb24geyRzdWNjZXNzfS97JHRvdGFsfSBzaXRlcy4iICk7CgkJfSBlbHNlIHsKCQkJcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3AtYWRtaW4vaW5jbHVkZXMvdXBncmFkZS5waHAnOwoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLldQLkdsb2JhbFZhcmlhYmxlc092ZXJyaWRlLlByb2hpYml0ZWQgLS0gUmVwbGFjaW5nIFdQIENvcmUgYmVoYXZpb3IgaXMgdGhlIGdvYWwgaGVyZS4KCQkJJHdwX2N1cnJlbnRfZGJfdmVyc2lvbiA9IChpbnQpIF9fZ2V0X29wdGlvbiggJ2RiX3ZlcnNpb24nICk7CgkJCWlmICggJHdwX2RiX3ZlcnNpb24gIT09ICR3cF9jdXJyZW50X2RiX3ZlcnNpb24gKSB7CgkJCQlpZiAoICRkcnlfcnVuICkgewoJCQkJCVdQX0NMSTo6c3VjY2VzcyggIldvcmRQcmVzcyBkYXRhYmFzZSB3aWxsIGJlIHVwZ3JhZGVkIGZyb20gZGIgdmVyc2lvbiB7JHdwX2N1cnJlbnRfZGJfdmVyc2lvbn0gdG8geyR3cF9kYl92ZXJzaW9ufS4iICk7CgkJCQl9IGVsc2UgewoJCQkJCS8vIFdQIHVwZ3JhZGUgaXNuJ3QgdG9vIGZ1c3N5IGFib3V0IGdlbmVyYXRpbmcgTXlTUUwgd2FybmluZ3Mgc3VjaCBhcyAiRHVwbGljYXRlIGtleSBuYW1lIiBkdXJpbmcgYW4gdXBncmFkZSBzbyBzdXBwcmVzcy4KCQkJCQkkd3BkYi0+c3VwcHJlc3NfZXJyb3JzKCk7CgoJCQkJCS8vIFdQIHVwZ3JhZGUgZXhwZWN0cyBgJF9TRVJWRVJbJ0hUVFBfSE9TVCddYCB0byBiZSBzZXQgaW4gYHdwX2d1ZXNzX3VybCgpYCwgb3RoZXJ3aXNlIGdldCBQSFAgbm90aWNlLgoJCQkJCWlmICggISBpc3NldCggJF9TRVJWRVJbJ0hUVFBfSE9TVCddICkgKSB7CgkJCQkJCSRfU0VSVkVSWydIVFRQX0hPU1QnXSA9ICdodHRwOi8vZXhhbXBsZS5jb20nOwoJCQkJCX0KCgkJCQkJd3BfdXBncmFkZSgpOwoKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgdXBncmFkZWQgc3VjY2Vzc2Z1bGx5IGZyb20gZGIgdmVyc2lvbiB7JHdwX2N1cnJlbnRfZGJfdmVyc2lvbn0gdG8geyR3cF9kYl92ZXJzaW9ufS4iICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJXb3JkUHJlc3MgZGF0YWJhc2UgYWxyZWFkeSBhdCBsYXRlc3QgZGIgdmVyc2lvbiB7JHdwX2RiX3ZlcnNpb259LiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEdldHMgZG93bmxvYWQgdXJsIGJhc2VkIG9uIHZlcnNpb24sIGxvY2FsZSBhbmQgZGVzaXJlZCBmaWxlIHR5cGUuCgkgKgoJICogQHBhcmFtICR2ZXJzaW9uCgkgKiBAcGFyYW0gc3RyaW5nICRsb2NhbGUKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVfdHlwZQoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfZG93bmxvYWRfdXJsKCAkdmVyc2lvbiwgJGxvY2FsZSA9ICdlbl9VUycsICRmaWxlX3R5cGUgPSAnemlwJyApIHsKCgkJaWYgKCAnbmlnaHRseScgPT09ICR2ZXJzaW9uICkgewoJCQlpZiAoICd6aXAnID09PSAkZmlsZV90eXBlICkgewoJCQkJcmV0dXJuICdodHRwczovL3dvcmRwcmVzcy5vcmcvbmlnaHRseS1idWlsZHMvd29yZHByZXNzLWxhdGVzdC56aXAnOwoJCQl9IGVsc2UgewoJCQkJV1BfQ0xJOjplcnJvciggJ05pZ2h0bHkgYnVpbGRzIGFyZSBvbmx5IGF2YWlsYWJsZSBpbiAuemlwIGZvcm1hdC4nICk7CgkJCX0KCQl9CgoJCSRsb2NhbGVfc3ViZG9tYWluID0gJ2VuX1VTJyA9PT0gJGxvY2FsZSA/ICcnIDogc3Vic3RyKCAkbG9jYWxlLCAwLCAyICkgLiAnLic7CgkJJGxvY2FsZV9zdWZmaXggICAgPSAnZW5fVVMnID09PSAkbG9jYWxlID8gJycgOiAiLXskbG9jYWxlfSI7CgoJCXJldHVybiAiaHR0cHM6Ly97JGxvY2FsZV9zdWJkb21haW59d29yZHByZXNzLm9yZy93b3JkcHJlc3MteyR2ZXJzaW9ufXskbG9jYWxlX3N1ZmZpeH0ueyRmaWxlX3R5cGV9IjsKCX0KCgkvKioKCSAqIFJldHVybnMgdXBkYXRlIGluZm9ybWF0aW9uLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF91cGRhdGVzKCAkYXNzb2NfYXJncyApIHsKCQl3cF92ZXJzaW9uX2NoZWNrKCk7CgkJJGZyb21fYXBpID0gZ2V0X3NpdGVfdHJhbnNpZW50KCAndXBkYXRlX2NvcmUnICk7CgkJaWYgKCAhICRmcm9tX2FwaSApIHsKCQkJcmV0dXJuIFtdOwoJCX0KCgkJJGNvbXBhcmVfdmVyc2lvbiA9IHN0cl9yZXBsYWNlKCAnLXNyYycsICcnLCAkR0xPQkFMU1snd3BfdmVyc2lvbiddICk7CgoJCSR1cGRhdGVzID0gWwoJCQknbWFqb3InID0+IGZhbHNlLAoJCQknbWlub3InID0+IGZhbHNlLAoJCV07CgkJZm9yZWFjaCAoICRmcm9tX2FwaS0+dXBkYXRlcyBhcyAkb2ZmZXIgKSB7CgoJCQkkdXBkYXRlX3R5cGUgPSBVdGlsc1xnZXRfbmFtZWRfc2VtX3ZlciggJG9mZmVyLT52ZXJzaW9uLCAkY29tcGFyZV92ZXJzaW9uICk7CgkJCWlmICggISAkdXBkYXRlX3R5cGUgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gV29yZFByZXNzIGZvbGxvdyBpdHMgb3duIHZlcnNpb25pbmcgd2hpY2ggaXMgcm91Z2hseSBlcXVpdmFsZW50IHRvIHNlbXZlcgoJCQlpZiAoICdtaW5vcicgPT09ICR1cGRhdGVfdHlwZSApIHsKCQkJCSR1cGRhdGVfdHlwZSA9ICdtYWpvcic7CgkJCX0gZWxzZWlmICggJ3BhdGNoJyA9PT0gJHVwZGF0ZV90eXBlICkgewoJCQkJJHVwZGF0ZV90eXBlID0gJ21pbm9yJzsKCQkJfQoKCQkJaWYgKCAhIGVtcHR5KCAkdXBkYXRlc1sgJHVwZGF0ZV90eXBlIF0gKSAmJiAhIENvbXBhcmF0b3I6OmdyZWF0ZXJUaGFuKCAkb2ZmZXItPnZlcnNpb24sICR1cGRhdGVzWyAkdXBkYXRlX3R5cGUgXVsndmVyc2lvbiddICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHVwZGF0ZXNbICR1cGRhdGVfdHlwZSBdID0gWwoJCQkJJ3ZlcnNpb24nICAgICA9PiAkb2ZmZXItPnZlcnNpb24sCgkJCQkndXBkYXRlX3R5cGUnID0+ICR1cGRhdGVfdHlwZSwKCQkJCSdwYWNrYWdlX3VybCcgPT4gISBlbXB0eSggJG9mZmVyLT5wYWNrYWdlcy0+cGFydGlhbCApID8gJG9mZmVyLT5wYWNrYWdlcy0+cGFydGlhbCA6ICRvZmZlci0+cGFja2FnZXMtPmZ1bGwsCgkJCV07CgkJfQoKCQlmb3JlYWNoICggJHVwZGF0ZXMgYXMgJHR5cGUgPT4gJHZhbHVlICkgewoJCQlpZiAoIGVtcHR5KCAkdmFsdWUgKSApIHsKCQkJCXVuc2V0KCAkdXBkYXRlc1sgJHR5cGUgXSApOwoJCQl9CgkJfQoKCQlmb3JlYWNoICggWyAnbWFqb3InLCAnbWlub3InIF0gYXMgJHR5cGUgKSB7CgkJCWlmICggdHJ1ZSA9PT0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAkdHlwZSApICkgewoJCQkJcmV0dXJuICEgZW1wdHkoICR1cGRhdGVzWyAkdHlwZSBdICkKCQkJCQk/IFsgJHVwZGF0ZXNbICR0eXBlIF0gXQoJCQkJCTogZmFsc2U7CgkJCX0KCQl9CgkJcmV0dXJuIGFycmF5X3ZhbHVlcyggJHVwZGF0ZXMgKTsKCX0KCgkvKioKCSAqIENsZWFuIHVwIGV4dHJhIGZpbGVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb25fZnJvbSBTdGFydGluZyB2ZXJzaW9uIHRoYXQgdGhlIGluc3RhbGxhdGlvbiB3YXMgdXBkYXRlZCBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbl90byAgIFRhcmdldCB2ZXJzaW9uIHRoYXQgdGhlIGluc3RhbGxhdGlvbiBpcyB1cGRhdGVkIHRvLgoJICogQHBhcmFtIHN0cmluZyAkbG9jYWxlICAgICAgIExvY2FsZSBvZiB0aGUgaW5zdGFsbGF0aW9uLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgICAgIFdoZXRoZXIgdG8gcmV0cnkgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIG9uIFRMUyBoYW5kc2hha2UgZmFpbHVyZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjbGVhbnVwX2V4dHJhX2ZpbGVzKCAkdmVyc2lvbl9mcm9tLCAkdmVyc2lvbl90bywgJGxvY2FsZSwgJGluc2VjdXJlICkgewoJCWlmICggISAkdmVyc2lvbl9mcm9tIHx8ICEgJHZlcnNpb25fdG8gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ0ZhaWxlZCB0byBmaW5kIFdvcmRQcmVzcyB2ZXJzaW9uLiBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4nICk7CgkJCXJldHVybjsKCQl9CgoJCSRvbGRfY2hlY2tzdW1zID0gc2VsZjo6Z2V0X2NvcmVfY2hlY2tzdW1zKCAkdmVyc2lvbl9mcm9tLCAkbG9jYWxlID86ICdlbl9VUycsICRpbnNlY3VyZSApOwoJCWlmICggISBpc19hcnJheSggJG9sZF9jaGVja3N1bXMgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRvbGRfY2hlY2tzdW1zfSBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4iICk7CgkJCXJldHVybjsKCQl9CgkJJG5ld19jaGVja3N1bXMgPSBzZWxmOjpnZXRfY29yZV9jaGVja3N1bXMoICR2ZXJzaW9uX3RvLCAkbG9jYWxlID86ICdlbl9VUycsICRpbnNlY3VyZSApOwoJCWlmICggISBpc19hcnJheSggJG5ld19jaGVja3N1bXMgKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAieyRuZXdfY2hlY2tzdW1zfSBQbGVhc2UgY2xlYW51cCBmaWxlcyBtYW51YWxseS4iICk7CgkJCXJldHVybjsKCQl9CgoJCSRmaWxlc190b19yZW1vdmUgPSBhcnJheV9kaWZmKCBhcnJheV9rZXlzKCAkb2xkX2NoZWNrc3VtcyApLCBhcnJheV9rZXlzKCAkbmV3X2NoZWNrc3VtcyApICk7CgoJCWlmICggISBlbXB0eSggJGZpbGVzX3RvX3JlbW92ZSApICkgewoJCQlXUF9DTEk6OmxvZyggJ0NsZWFuaW5nIHVwIGZpbGVzLi4uJyApOwoKCQkJJGNvdW50ID0gMDsKCQkJZm9yZWFjaCAoICRmaWxlc190b19yZW1vdmUgYXMgJGZpbGUgKSB7CgoJCQkJLy8gd3AtY29udGVudCBzaG91bGQgYmUgY29uc2lkZXJlZCB1c2VyIGRhdGEKCQkJCWlmICggMCA9PT0gc3RyaXBvcyggJGZpbGUsICd3cC1jb250ZW50JyApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggZmlsZV9leGlzdHMoIEFCU1BBVEggLiAkZmlsZSApICkgewoJCQkJCXVubGluayggQUJTUEFUSCAuICRmaWxlICk7CgkJCQkJV1BfQ0xJOjpsb2coICJGaWxlIHJlbW92ZWQ6IHskZmlsZX0iICk7CgkJCQkJJGNvdW50Kys7CgkJCQl9CgkJCX0KCgkJCWlmICggJGNvdW50ICkgewoJCQkJV1BfQ0xJOjpsb2coIG51bWJlcl9mb3JtYXQoICRjb3VudCApIC4gJyBmaWxlcyBjbGVhbmVkIHVwLicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6bG9nKCAnTm8gZmlsZXMgZm91bmQgdGhhdCBuZWVkIGNsZWFuaW5nIHVwLicgKTsKCQkJfQoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBzdHJpcF9jb250ZW50X2RpciggJHppcF9maWxlICkgewoJCSRuZXdfemlwX2ZpbGUgPSBVdGlsc1xnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwXycgKSAuICcuemlwJzsKCQlyZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbigKCQkJZnVuY3Rpb24gKCkgdXNlICggJG5ld196aXBfZmlsZSApIHsKCQkJCWlmICggZmlsZV9leGlzdHMoICRuZXdfemlwX2ZpbGUgKSApIHsKCQkJCQl1bmxpbmsoICRuZXdfemlwX2ZpbGUgKTsKCQkJCX0KCQkJfQoJCSk7CgkJLy8gRHVwbGljYXRlIGZpbGUgdG8gYXZvaWQgbW9kaWZ5aW5nIHRoZSBvcmlnaW5hbCwgd2hpY2ggY291bGQgYmUgY2FjaGUuCgkJaWYgKCAhIGNvcHkoICR6aXBfZmlsZSwgJG5ld196aXBfZmlsZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnRmFpbGVkIHRvIGNvcHkgWklQIGZpbGUuJyApOwoJCX0KCQkkemlwID0gbmV3IFppcEFyY2hpdmUoKTsKCQkkcmVzID0gJHppcC0+b3BlbiggJG5ld196aXBfZmlsZSApOwoJCWlmICggdHJ1ZSA9PT0gJHJlcyApIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5OYW1pbmdDb252ZW50aW9ucy5WYWxpZFZhcmlhYmxlTmFtZS5Vc2VkUHJvcGVydHlOb3RTbmFrZUNhc2UKCQkJZm9yICggJGkgPSAwOyAkaSA8ICR6aXAtPm51bUZpbGVzOyAkaSsrICkgewoJCQkJJGluZm8gPSAkemlwLT5zdGF0SW5kZXgoICRpICk7CgkJCQlpZiAoIGZhbHNlICE9PSBzdHJpcG9zKCAkaW5mb1snbmFtZSddLCAnd3AtY29udGVudC8nICkgKSB7CgkJCQkJJHppcC0+ZGVsZXRlSW5kZXgoICRpICk7CgkJCQl9CgkJCX0KCQkJJHppcC0+Y2xvc2UoKTsKCQkJcmV0dXJuICRuZXdfemlwX2ZpbGU7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggJ1ppcEFyY2hpdmUgZmFpbGVkIHRvIG9wZW4gWklQIGZpbGUuJyApOwoJCX0KCX0KCn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29yZTsKCnVzZSBFeGNlcHRpb247CnVzZSBSZXF1ZXN0c19SZXNwb25zZTsKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0Vycm9yOwp1c2UgQ29yZV9VcGdyYWRlciBhcyBEZWZhdWx0Q29yZVVwZ3JhZGVyOwp1c2UgV1BfRmlsZXN5c3RlbV9CYXNlOwoKLyoqCiAqIEEgQ29yZSBVcGdyYWRlciBjbGFzcyB0aGF0IGNhY2hlcyB0aGUgZG93bmxvYWQsIGFuZCB1c2VzIGNhY2hlZCBpZiBhdmFpbGFibGUuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ29yZVVwZ3JhZGVyIGV4dGVuZHMgRGVmYXVsdENvcmVVcGdyYWRlciB7CgoJLyoqCgkgKiBXaGV0aGVyIHRvIHJldHJ5IHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBvbiBUTFMgaGFuZHNoYWtlIGZhaWx1cmUuCgkgKgoJICogQHZhciBib29sCgkgKi8KCXByaXZhdGUgJGluc2VjdXJlOwoKCS8qKgoJICogQ29yZVVwZ3JhZGVyIGNvbnN0cnVjdG9yLgoJICoKCSAqIEBwYXJhbSBXUF9VcGdyYWRlcl9Ta2lufG51bGwgJHNraW4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkc2tpbiA9IG51bGwsICRpbnNlY3VyZSA9IGZhbHNlICkgewoJCSR0aGlzLT5pbnNlY3VyZSA9ICRpbnNlY3VyZTsKCQlwYXJlbnQ6Ol9fY29uc3RydWN0KCAkc2tpbiApOwoJfQoKCS8qKgoJICogQ2FjaGVzIHRoZSBkb3dubG9hZCwgYW5kIHVzZXMgY2FjaGVkIGlmIGF2YWlsYWJsZS4KCSAqCgkgKiBAYWNjZXNzIHB1YmxpYwoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2UgICAgICAgICAgVGhlIFVSSSBvZiB0aGUgcGFja2FnZS4gSWYgdGhpcyBpcyB0aGUgZnVsbCBwYXRoIHRvIGFuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nIGxvY2FsIGZpbGUsIGl0IHdpbGwgYmUgcmV0dXJuZWQgdW50b3VjaGVkLgoJICogQHBhcmFtIGJvb2wgICAkY2hlY2tfc2lnbmF0dXJlcyBXaGV0aGVyIHRvIHZhbGlkYXRlIGZpbGUgc2lnbmF0dXJlcy4gRGVmYXVsdCB0cnVlLgoJICogQHBhcmFtIGFycmF5ICAkaG9va19leHRyYSAgICAgICBFeHRyYSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmlsdGVyIGhvb2tzLiBEZWZhdWx0IGVtcHR5IGFycmF5LgoJICogQHJldHVybiBzdHJpbmd8V1BfRXJyb3IgVGhlIGZ1bGwgcGF0aCB0byB0aGUgZG93bmxvYWRlZCBwYWNrYWdlIGZpbGUsIG9yIGEgV1BfRXJyb3Igb2JqZWN0LgoJICovCglwdWJsaWMgZnVuY3Rpb24gZG93bmxvYWRfcGFja2FnZSggJHBhY2thZ2UsICRjaGVja19zaWduYXR1cmVzID0gdHJ1ZSwgJGhvb2tfZXh0cmEgPSBbXSApIHsKCgkJLyoqCgkJICogRmlsdGVyIHdoZXRoZXIgdG8gcmV0dXJuIHRoZSBwYWNrYWdlLgoJCSAqCgkJICogQHNpbmNlIDMuNy4wCgkJICoKCQkgKiBAcGFyYW0gYm9vbCAgICAkcmVwbHkgICBXaGV0aGVyIHRvIGJhaWwgd2l0aG91dCByZXR1cm5pbmcgdGhlIHBhY2thZ2UuIERlZmF1bHQgaXMgZmFsc2UuCgkJICogQHBhcmFtIHN0cmluZyAgJHBhY2thZ2UgVGhlIHBhY2thZ2UgZmlsZSBuYW1lLgoJCSAqIEBwYXJhbSBvYmplY3QgICR0aGlzICAgIFRoZSBXUF9VcGdyYWRlciBpbnN0YW5jZS4KCQkgKi8KCQkkcmVwbHkgPSBhcHBseV9maWx0ZXJzKAoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLk5hbWluZ0NvbnZlbnRpb25zLlByZWZpeEFsbEdsb2JhbHMuTm9uUHJlZml4ZWRIb29rbmFtZUZvdW5kIC0tIE92ZXJyaWRlIGV4aXN0aW5nIGhvb2sgZnJvbSBDb3JlLgoJCQkndXBncmFkZXJfcHJlX2Rvd25sb2FkJywKCQkJZmFsc2UsCgkJCSRwYWNrYWdlLAoJCQkkdGhpcywKCQkJJGhvb2tfZXh0cmEKCQkpOwoJCWlmICggZmFsc2UgIT09ICRyZXBseSApIHsKCQkJcmV0dXJuICRyZXBseTsKCQl9CgoJCS8vIENoZWNrIGlmIHBhY2thZ2UgaXMgYSBsb2NhbCBvciByZW1vdGUgZmlsZS4gQmFpbCBpZiBpdCdzIGxvY2FsLgoJCWlmICggISBwcmVnX21hdGNoKCAnIV4oaHR0cHxodHRwc3xmdHApOi8vIWknLCAkcGFja2FnZSApICYmIGZpbGVfZXhpc3RzKCAkcGFja2FnZSApICkgewoJCQlyZXR1cm4gJHBhY2thZ2U7CgkJfQoKCQlpZiAoIGVtcHR5KCAkcGFja2FnZSApICkgewoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnbm9fcGFja2FnZScsICR0aGlzLT5zdHJpbmdzWydub19wYWNrYWdlJ10gKTsKCQl9CgoJCSRmaWxlbmFtZSAgPSBwYXRoaW5mbyggJHBhY2thZ2UsIFBBVEhJTkZPX0ZJTEVOQU1FICk7CgkJJGV4dGVuc2lvbiA9IHBhdGhpbmZvKCAkcGFja2FnZSwgUEFUSElORk9fRVhURU5TSU9OICk7CgoJCSR0ZW1wID0gVXRpbHNcZ2V0X3RlbXBfZGlyKCkgLiB1bmlxaWQoICd3cF8nICkgLiAiLnskZXh0ZW5zaW9ufSI7CgkJcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oCgkJCWZ1bmN0aW9uICgpIHVzZSAoICR0ZW1wICkgewoJCQkJaWYgKCBmaWxlX2V4aXN0cyggJHRlbXAgKSApIHsKCQkJCQl1bmxpbmsoICR0ZW1wICk7CgkJCQl9CgkJCX0KCQkpOwoKCQkkY2FjaGUgICAgICA9IFdQX0NMSTo6Z2V0X2NhY2hlKCk7CgkJJHVwZGF0ZSAgICAgPSAkR0xPQkFMU1snd3BjbGlfY29yZV91cGRhdGVfb2JqJ107CgkJJGNhY2hlX2tleSAgPSAiY29yZS97JGZpbGVuYW1lfS17JHVwZGF0ZS0+bG9jYWxlfS57JGV4dGVuc2lvbn0iOwoJCSRjYWNoZV9maWxlID0gJGNhY2hlLT5oYXMoICRjYWNoZV9rZXkgKTsKCgkJaWYgKCAkY2FjaGVfZmlsZSAmJiBmYWxzZSA9PT0gc3RyaXBvcyggJHBhY2thZ2UsICdodHRwczovL3dvcmRwcmVzcy5vcmcvbmlnaHRseS1idWlsZHMvJyApCgkJCSYmIGZhbHNlID09PSBzdHJpcG9zKCAkcGFja2FnZSwgJ2h0dHA6Ly93b3JkcHJlc3Mub3JnL25pZ2h0bHktYnVpbGRzLycgKSApIHsKCQkJV1BfQ0xJOjpsb2coICJVc2luZyBjYWNoZWQgZmlsZSAneyRjYWNoZV9maWxlfScuLi4iICk7CgkJCWNvcHkoICRjYWNoZV9maWxlLCAkdGVtcCApOwoJCQlyZXR1cm4gJHRlbXA7CgkJfQoKCQkvKgoJCSAqIERvd25sb2FkIHRvIGEgdGVtcG9yYXJ5IGZpbGUgYmVjYXVzZSBwaXBpbmcgZnJvbSBjVVJMIHRvIHRhciBpcyBmbGFreQoJCSAqIG9uIE1pbkdXIChhbmQgcHJvYmFibHkgaW4gb3RoZXIgZW52aXJvbm1lbnRzIHRvbykuCgkJICovCgkJJGhlYWRlcnMgPSBbICdBY2NlcHQnID0+ICdhcHBsaWNhdGlvbi9qc29uJyBdOwoJCSRvcHRpb25zID0gWwoJCQkndGltZW91dCcgICAgICAgPT4gNjAwLCAgLy8gMTAgbWludXRlcyBvdWdodCB0byBiZSBlbm91Z2ggZm9yIGV2ZXJ5Ym9keS4KCQkJJ2ZpbGVuYW1lJyAgICAgID0+ICR0ZW1wLAoJCQknaGFsdF9vbl9lcnJvcicgPT4gZmFsc2UsCgkJCSdpbnNlY3VyZScgICAgICA9PiAkdGhpcy0+aW5zZWN1cmUsCgkJXTsKCgkJJHRoaXMtPnNraW4tPmZlZWRiYWNrKCAnZG93bmxvYWRpbmdfcGFja2FnZScsICRwYWNrYWdlICk7CgoJCS8qKiBAdmFyIFJlcXVlc3RzX1Jlc3BvbnNlfG51bGwgJHJlcSAqLwoJCXRyeSB7CgkJCSRyZXNwb25zZSA9IFV0aWxzXGh0dHBfcmVxdWVzdCggJ0dFVCcsICRwYWNrYWdlLCBudWxsLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlyZXR1cm4gbmV3IFdQX0Vycm9yKCAnZG93bmxvYWRfZmFpbGVkJywgJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJaWYgKCAhIGlzX251bGwoICRyZXNwb25zZSApICYmIDIwMCAhPT0gKGludCkgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJcmV0dXJuIG5ldyBXUF9FcnJvciggJ2Rvd25sb2FkX2ZhaWxlZCcsICR0aGlzLT5zdHJpbmdzWydkb3dubG9hZF9mYWlsZWQnXSApOwoJCX0KCgkJaWYgKCBmYWxzZSA9PT0gc3RyaXBvcyggJHBhY2thZ2UsICdodHRwczovL3dvcmRwcmVzcy5vcmcvbmlnaHRseS1idWlsZHMvJyApICkgewoJCQkkY2FjaGUtPmltcG9ydCggJGNhY2hlX2tleSwgJHRlbXAgKTsKCQl9CgoJCXJldHVybiAkdGVtcDsKCX0KCgkvKioKCSAqIFVwZ3JhZGUgV29yZFByZXNzIGNvcmUuCgkgKgoJICogQGFjY2VzcyBwdWJsaWMKCSAqCgkgKiBAZ2xvYmFsIFdQX0ZpbGVzeXN0ZW1fQmFzZSAkd3BfZmlsZXN5c3RlbSBTdWJjbGFzcwoJICogQGdsb2JhbCBjYWxsYWJsZSAgICAgICAgICAgJF93cF9maWxlc3lzdGVtX2RpcmVjdF9tZXRob2QKCSAqCgkgKiBAcGFyYW0gb2JqZWN0ICRjdXJyZW50IFJlc3BvbnNlIG9iamVjdCBmb3Igd2hldGhlciBXb3JkUHJlc3MgaXMgY3VycmVudC4KCSAqIEBwYXJhbSBhcnJheSAgJGFyZ3MgewoJICogICAgICAgIE9wdGlvbmFsLiBBcmd1bWVudHMgZm9yIHVwZ3JhZGluZyBXb3JkUHJlc3MgY29yZS4gRGVmYXVsdCBlbXB0eSBhcnJheS4KCSAqCgkgKiAgICAgICAgQHR5cGUgYm9vbCAkcHJlX2NoZWNrX21kNSAgICBXaGV0aGVyIHRvIGNoZWNrIHRoZSBmaWxlIGNoZWNrc3VtcyBiZWZvcmUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGVtcHRpbmcgdGhlIHVwZ3JhZGUuIERlZmF1bHQgdHJ1ZS4KCSAqICAgICAgICBAdHlwZSBib29sICRhdHRlbXB0X3JvbGxiYWNrIFdoZXRoZXIgdG8gYXR0ZW1wdCB0byByb2xsYmFjayB0aGUgY2hhbmNlcyBpZgoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlcmUgaXMgYSBwcm9ibGVtLiBEZWZhdWx0IGZhbHNlLgoJICogICAgICAgIEB0eXBlIGJvb2wgJGRvX3JvbGxiYWNrICAgICAgV2hldGhlciB0byBwZXJmb3JtIHRoaXMgInVwZ3JhZGUiIGFzIGEgcm9sbGJhY2suCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IGZhbHNlLgoJICogfQoJICogQHJldHVybiBudWxsfGZhbHNlfFdQX0Vycm9yIEZhbHNlIG9yIFdQX0Vycm9yIG9uIGZhaWx1cmUsIG51bGwgb24gc3VjY2Vzcy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZ3JhZGUoICRjdXJyZW50LCAkYXJncyA9IFtdICkgewoJCXNldF9lcnJvcl9oYW5kbGVyKCBbIF9fQ0xBU1NfXywgJ2Vycm9yX2hhbmRsZXInIF0sIEVfVVNFUl9XQVJOSU5HIHwgRV9VU0VSX05PVElDRSApOwoKCQkkcmVzdWx0ID0gcGFyZW50Ojp1cGdyYWRlKCAkY3VycmVudCwgJGFyZ3MgKTsKCgkJcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogRXJyb3IgaGFuZGxlciB0byBpZ25vcmUgZmFpbHVyZXMgb24gYWNjZXNzaW5nIFNTTCAiaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy9jb3JlL2NoZWNrc3Vtcy8xLjAvIiBpbiBgZ2V0X2NvcmVfY2hlY2tzdW1zKClgIHdoaWNoIHNlZW0gdG8gb2NjdXIgaW50ZXJtaXR0ZW50bHkuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXJyb3JfaGFuZGxlciggJGVycm5vLCAkZXJyc3RyLCAkZXJyZmlsZSwgJGVycmxpbmUsICRlcnJjb250ZXh0ID0gbnVsbCApIHsKCQkvLyBJZiBpZ25vcmluZyBFX1VTRVJfV0FSTklORyB8IEVfVVNFUl9OT1RJQ0UsIGRlZmF1bHQuCgkJaWYgKCAhICggZXJyb3JfcmVwb3J0aW5nKCkgJiAkZXJybm8gKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkvLyBJZiBub3QgaW4gIndwLWFkbWluL2luY2x1ZGVzL3VwZGF0ZS5waHAiLCBkZWZhdWx0LgoJCSR1cGRhdGVfcGhwID0gJ3dwLWFkbWluL2luY2x1ZGVzL3VwZGF0ZS5waHAnOwoJCWlmICggMCAhPT0gc3Vic3RyX2NvbXBhcmUoICRlcnJmaWxlLCAkdXBkYXRlX3BocCwgLXN0cmxlbiggJHVwZGF0ZV9waHAgKSApICkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCS8vIEVsc2UgYXNzdW1lIGl0J3MgaW4gYGdldF9jb3JlX2NoZWNrc3VtcygpYCBhbmQganVzdCBpZ25vcmUgaXQuCgkJcmV0dXJuIHRydWU7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcQ29yZTsKCi8qKgogKiBBIENvcmUgVXBncmFkZXIgY2xhc3MgdGhhdCBsZWF2ZXMgcGFja2FnZXMgaW50YWN0IGJ5IGRlZmF1bHQuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgTm9uRGVzdHJ1Y3RpdmVDb3JlVXBncmFkZXIgZXh0ZW5kcyBDb3JlVXBncmFkZXIgewoJLy8gcGhwY3M6aWdub3JlIEdlbmVyaWMuQ29kZUFuYWx5c2lzLlVzZWxlc3NPdmVycmlkaW5nTWV0aG9kLkZvdW5kIC0tIFByb3ZpZGUgZGVmYXVsdCB2YWx1ZS4KCXB1YmxpYyBmdW5jdGlvbiB1bnBhY2tfcGFja2FnZSggJHBhY2thZ2UsICRkZWxldGVfcGFja2FnZSA9IGZhbHNlICkgewoJCXJldHVybiBwYXJlbnQ6OnVucGFja19wYWNrYWdlKCAkcGFja2FnZSwgJGRlbGV0ZV9wYWNrYWdlICk7Cgl9Cn0KCjw/cGhwCi8qKgogKiBMaXN0IGFsbCBjb250cmlidXRvcnMgdG8gdGhpcyByZWxlYXNlLgogKgogKiBVc2FnZTogd3AgLS1yZXF1aXJlPXV0aWxzL2NvbnRyaWItbGlzdC5waHAgY29udHJpYi1saXN0CiAqCiAqIElmIHlvdSBydW4gaW50byBHaXRIdWIgQVBJIHJhdGUgbGltaXQgaXNzdWVzLCBzZXQgYSBHSVRIVUJfVE9LRU4KICogZW52aXJvbm1lbnQgdmFyaWFibGUuCiAqLwoKdXNlIFdQX0NMSVxVdGlsczsKCmNsYXNzIENvbnRyaWJfTGlzdF9Db21tYW5kIHsKCgkvKioKCSAqIExpc3QgYWxsIGNvbnRyaWJ1dG9ycyB0byB0aGlzIHJlbGVhc2UuCgkgKgoJICogUnVuIHdpdGhpbiB0aGUgbWFpbiBXUC1DTEkgcHJvamVjdCByZXBvc2l0b3J5LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBzcGVjaWZpYyBmb3JtYXQuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IG1hcmtkb3duCgkgKiBvcHRpb25zOgoJICogICAtIG1hcmtkb3duCgkgKiAgIC0gaHRtbAoJICogLS0tCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgoJCSRjb250cmlidXRvcnMgICAgICAgPSBhcnJheSgpOwoJCSRjb250cmlidXRvcl9jb3VudCAgPSAwOwoJCSRwdWxsX3JlcXVlc3RfY291bnQgPSAwOwoKCQkvLyBHZXQgdGhlIGNvbnRyaWJ1dG9ycyB0byB0aGUgY3VycmVudCBvcGVuIGxhcmdlIHByb2plY3QgbWlsZXN0b25lcwoJCWZvcmVhY2ggKCBhcnJheSggJ3dwLWNsaS93cC1jbGknLCAnd3AtY2xpL2hhbmRib29rJywgJ3dwLWNsaS93cC1jbGkuZ2l0aHViLmNvbScgKSBhcyAkcmVwbyApIHsKCQkJJG1pbGVzdG9uZXMgPSBzZWxmOjpnZXRfcHJvamVjdF9taWxlc3RvbmVzKCAkcmVwbyApOwoJCQkvLyBDaGVhcCB3YXkgdG8gZ2V0IHRoZSBsYXRlc3QgbWlsZXN0b25lCgkJCSRtaWxlc3RvbmUgPSBhcnJheV9zaGlmdCggJG1pbGVzdG9uZXMgKTsKCQkJV1BfQ0xJOjpsb2coICdDdXJyZW50IG9wZW4gJyAuICRyZXBvIC4gJyBtaWxlc3RvbmU6ICcgLiAkbWlsZXN0b25lLT50aXRsZSApOwoJCQkkcHVsbF9yZXF1ZXN0cyAgICAgPSBzZWxmOjpnZXRfcHJvamVjdF9taWxlc3RvbmVfcHVsbF9yZXF1ZXN0cyggJHJlcG8sICRtaWxlc3RvbmUtPm51bWJlciApOwoJCQkkcmVwb19jb250cmlidXRvcnMgPSBzZWxmOjpwYXJzZV9jb250cmlidXRvcnNfZnJvbV9wdWxsX3JlcXVlc3RzKCAkcHVsbF9yZXF1ZXN0cyApOwoJCQlXUF9DTEk6OmxvZyggJyAtIENvbnRyaWJ1dG9yczogJyAuIGNvdW50KCAkcmVwb19jb250cmlidXRvcnMgKSApOwoJCQlXUF9DTEk6OmxvZyggJyAtIFB1bGwgcmVxdWVzdHM6ICcgLiBjb3VudCggJHB1bGxfcmVxdWVzdHMgKSApOwoJCQkkcHVsbF9yZXF1ZXN0X2NvdW50ICs9IGNvdW50KCAkcHVsbF9yZXF1ZXN0cyApOwoJCQkkY29udHJpYnV0b3JzICAgICAgICA9IGFycmF5X21lcmdlKCAkY29udHJpYnV0b3JzLCAkcmVwb19jb250cmlidXRvcnMgKTsKCQl9CgoJCS8vIElkZW50aWZ5IGFsbCBjb21tYW5kIGRlcGVuZGVuY2llcyBhbmQgdGhlaXIgY29udHJpYnV0b3JzCgkJJG1pbGVzdG9uZXMgPSBzZWxmOjpnZXRfcHJvamVjdF9taWxlc3RvbmVzKCAnd3AtY2xpL3dwLWNsaScsIGFycmF5KCAnc3RhdGUnID0+ICdjbG9zZWQnICkgKTsKCQkvLyBDaGVhcCB3YXkgdG8gZ2V0IHRoZSBsYXRlc3QgY2xvc2VkIG1pbGVzdG9uZQoJCSRtaWxlc3RvbmUgICAgICAgICA9IGFycmF5X3NoaWZ0KCAkbWlsZXN0b25lcyApOwoJCSRjb21wb3Nlcl9sb2NrX3VybCA9IHNwcmludGYoICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd3AtY2xpL3dwLWNsaS92JXMvY29tcG9zZXIubG9jaycsICRtaWxlc3RvbmUtPnRpdGxlICk7CgkJV1BfQ0xJOjpsb2coICdGZXRjaGluZyAnIC4gJGNvbXBvc2VyX2xvY2tfdXJsICk7CgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJGNvbXBvc2VyX2xvY2tfdXJsICk7CgkJaWYgKCAyMDAgIT09ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdDb3VsZCBub3QgZmV0Y2ggY29tcG9zZXIuanNvbiAoSFRUUCBjb2RlICVkKScsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSApOwoJCX0KCQkkY29tcG9zZXJfanNvbiA9IGpzb25fZGVjb2RlKCAkcmVzcG9uc2UtPmJvZHksIHRydWUgKTsKCQlmb3JlYWNoICggJGNvbXBvc2VyX2pzb25bJ3BhY2thZ2VzJ10gYXMgJHBhY2thZ2UgKSB7CgkJCSRwYWNrYWdlX25hbWUgICAgICAgPSAkcGFja2FnZVsnbmFtZSddOwoJCQkkdmVyc2lvbl9jb25zdHJhaW50ID0gc3RyX3JlcGxhY2UoICd2JywgJycsICRwYWNrYWdlWyd2ZXJzaW9uJ10gKTsKCQkJaWYgKCAhIHByZWdfbWF0Y2goICcjXndwLWNsaS8uKy1jb21tYW5kJCMnLCAkcGFja2FnZV9uYW1lICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkvLyBDbG9zZWQgbWlsZXN0b25lcyBkZW5vdGUgYSB0YWdnZWQgcmVsZWFzZQoJCQkkbWlsZXN0b25lcyAgICAgICA9IHNlbGY6OmdldF9wcm9qZWN0X21pbGVzdG9uZXMoICRwYWNrYWdlX25hbWUsIGFycmF5KCAnc3RhdGUnID0+ICdjbG9zZWQnICkgKTsKCQkJJG1pbGVzdG9uZV9pZHMgICAgPSBhcnJheSgpOwoJCQkkbWlsZXN0b25lX3RpdGxlcyA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCAkbWlsZXN0b25lcyBhcyAkbWlsZXN0b25lICkgewoJCQkJaWYgKCAhIHZlcnNpb25fY29tcGFyZSggJG1pbGVzdG9uZS0+dGl0bGUsICR2ZXJzaW9uX2NvbnN0cmFpbnQsICc+JyApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJJG1pbGVzdG9uZV9pZHNbXSAgICA9ICRtaWxlc3RvbmUtPm51bWJlcjsKCQkJCSRtaWxlc3RvbmVfdGl0bGVzW10gPSAkbWlsZXN0b25lLT50aXRsZTsKCQkJfQoJCQkvLyBObyBzaGlwcGVkIHJlbGVhc2VzIGZvciB0aGlzIG1pbGVzdG9uZS4KCQkJaWYgKCBlbXB0eSggJG1pbGVzdG9uZV9pZHMgKSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCVdQX0NMSTo6bG9nKCAnQ2xvc2VkICcgLiAkcGFja2FnZV9uYW1lIC4gJyBtaWxlc3RvbmUocyk6ICcgLiBpbXBsb2RlKCAnLCAnLCAkbWlsZXN0b25lX3RpdGxlcyApICk7CgkJCWZvcmVhY2ggKCAkbWlsZXN0b25lX2lkcyBhcyAkbWlsZXN0b25lX2lkICkgewoJCQkJJHB1bGxfcmVxdWVzdHMgICAgID0gc2VsZjo6Z2V0X3Byb2plY3RfbWlsZXN0b25lX3B1bGxfcmVxdWVzdHMoICRwYWNrYWdlX25hbWUsICRtaWxlc3RvbmVfaWQgKTsKCQkJCSRyZXBvX2NvbnRyaWJ1dG9ycyA9IHNlbGY6OnBhcnNlX2NvbnRyaWJ1dG9yc19mcm9tX3B1bGxfcmVxdWVzdHMoICRwdWxsX3JlcXVlc3RzICk7CgkJCQlXUF9DTEk6OmxvZyggJyAtIENvbnRyaWJ1dG9yczogJyAuIGNvdW50KCAkcmVwb19jb250cmlidXRvcnMgKSApOwoJCQkJV1BfQ0xJOjpsb2coICcgLSBQdWxsIHJlcXVlc3RzOiAnIC4gY291bnQoICRwdWxsX3JlcXVlc3RzICkgKTsKCQkJCSRwdWxsX3JlcXVlc3RfY291bnQgKz0gY291bnQoICRwdWxsX3JlcXVlc3RzICk7CgkJCQkkY29udHJpYnV0b3JzICAgICAgICA9IGFycmF5X21lcmdlKCAkY29udHJpYnV0b3JzLCAkcmVwb19jb250cmlidXRvcnMgKTsKCQkJfQoJCX0KCgkJV1BfQ0xJOjpsb2coICdUb3RhbCBjb250cmlidXRvcnM6ICcgLiBjb3VudCggJGNvbnRyaWJ1dG9ycyApICk7CgkJV1BfQ0xJOjpsb2coICdUb3RhbCBwdWxsIHJlcXVlc3RzOiAnIC4gJHB1bGxfcmVxdWVzdF9jb3VudCApOwoKCQkvLyBTb3J0IGFuZCByZW5kZXIgdGhlIGNvbnRyaWJ1dG9yIGxpc3QKCQlhc29ydCggJGNvbnRyaWJ1dG9ycywgU09SVF9OQVRVUkFMIHwgU09SVF9GTEFHX0NBU0UgKTsKCQlpZiAoIGluX2FycmF5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10sIGFycmF5KCAnbWFya2Rvd24nLCAnaHRtbCcgKSwgdHJ1ZSApICkgewoJCQkkY29udHJpYl9saXN0ID0gJyc7CgkJCWZvcmVhY2ggKCAkY29udHJpYnV0b3JzIGFzICR1cmwgPT4gJGxvZ2luICkgewoJCQkJaWYgKCAnbWFya2Rvd24nID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCQkJJGNvbnRyaWJfbGlzdCAuPSAnWycgLiAkbG9naW4gLiAnXSgnIC4gJHVybCAuICcpLCAnOwoJCQkJfSBlbHNlaWYgKCAnaHRtbCcgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJCQkkY29udHJpYl9saXN0IC49ICc8YSBocmVmPSInIC4gJHVybCAuICciPicgLiAkbG9naW4gLiAnPC9hPiwgJzsKCQkJCX0KCQkJfQoJCQkkY29udHJpYl9saXN0ID0gcnRyaW0oICRjb250cmliX2xpc3QsICcsICcgKTsKCQkJV1BfQ0xJOjpsb2coICRjb250cmliX2xpc3QgKTsKCQl9Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIG1pbGVzdG9uZXMgZm9yIGEgZ2l2ZW4gcHJvamVjdAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHByb2plY3QKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3Byb2plY3RfbWlsZXN0b25lcyggJHByb2plY3QsICRhcmdzID0gYXJyYXkoKSApIHsKCQkkcmVxdWVzdF91cmwgICAgICAgICAgICA9IHNwcmludGYoICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zLyVzL21pbGVzdG9uZXMnLCAkcHJvamVjdCApOwoJCWxpc3QoICRib2R5LCAkaGVhZGVycyApID0gc2VsZjo6bWFrZV9naXRodWJfYXBpX3JlcXVlc3QoICRyZXF1ZXN0X3VybCwgJGFyZ3MgKTsKCQlyZXR1cm4gJGJvZHk7Cgl9CgoJLyoqCgkgKiBHZXQgdGhlIHB1bGwgcmVxdWVzdHMgYXNzaWduZWQgdG8gYSBtaWxlc3RvbmUgb2YgYSBnaXZlbiBwcm9qZWN0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkcHJvamVjdAoJICogQHBhcmFtIGludGVnZXIgJG1pbGVzdG9uZV9pZAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfcHJvamVjdF9taWxlc3RvbmVfcHVsbF9yZXF1ZXN0cyggJHByb2plY3QsICRtaWxlc3RvbmVfaWQgKSB7CgkJJHJlcXVlc3RfdXJsICAgPSBzcHJpbnRmKCAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8lcy9pc3N1ZXMnLCAkcHJvamVjdCApOwoJCSRhcmdzICAgICAgICAgID0gYXJyYXkoCgkJCSdtaWxlc3RvbmUnID0+ICRtaWxlc3RvbmVfaWQsCgkJCSdzdGF0ZScgICAgID0+ICdhbGwnLAoJCSk7CgkJJHB1bGxfcmVxdWVzdHMgPSBhcnJheSgpOwoJCWRvIHsKCQkJbGlzdCggJGJvZHksICRoZWFkZXJzICkgPSBzZWxmOjptYWtlX2dpdGh1Yl9hcGlfcmVxdWVzdCggJHJlcXVlc3RfdXJsLCAkYXJncyApOwoJCQlmb3JlYWNoICggJGJvZHkgYXMgJGlzc3VlICkgewoJCQkJaWYgKCAhIGVtcHR5KCAkaXNzdWUtPnB1bGxfcmVxdWVzdCApICkgewoJCQkJCSRwdWxsX3JlcXVlc3RzW10gPSAkaXNzdWU7CgkJCQl9CgkJCX0KCQkJJGFyZ3MgICAgICAgID0gYXJyYXkoKTsKCQkJJHJlcXVlc3RfdXJsID0gZmFsc2U7CgkJCS8vIFNldCAkcmVxdWVzdF91cmwgdG8gJ3JlbD0ibmV4dCIgaWYgcHJlc2VudCcKCQkJaWYgKCAhIGVtcHR5KCAkaGVhZGVyc1snTGluayddICkgKSB7CgkJCQkkYml0cyA9IHRyaW0oIGV4cGxvZGUoICcsJywgJGhlYWRlcnNbJ0xpbmsnXSApICk7CgkJCQlmb3JlYWNoICggJGJpdHMgYXMgJGJpdCApIHsKCQkJCQlpZiAoIGZhbHNlICE9PSBzdHJpcG9zKCAkYml0LCAncmVsPSJuZXh0IicgKSApIHsKCQkJCQkJJGhyZWZhbmRyZWwgID0gZXhwbG9kZSggJzsgJywgJGJpdCApOwoJCQkJCQkkcmVxdWVzdF91cmwgPSB0cmltKCAkaHJlZmFuZHJlbFswXSwgJzw+JyApOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9IHdoaWxlICggJHJlcXVlc3RfdXJsICk7CgkJcmV0dXJuICRwdWxsX3JlcXVlc3RzOwoJfQoKCS8qKgoJICogUGFyc2UgdGhlIGNvbnRyaWJ1dG9ycyBmcm9tIHB1bGwgcmVxdWVzdCBvYmplY3RzCgkgKgoJICogQHBhcmFtIGFycmF5ICRwdWxsX3JlcXVlc3RzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHBhcnNlX2NvbnRyaWJ1dG9yc19mcm9tX3B1bGxfcmVxdWVzdHMoICRwdWxsX3JlcXVlc3RzICkgewoJCSRjb250cmlidXRvcnMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkcHVsbF9yZXF1ZXN0cyBhcyAkcHVsbF9yZXF1ZXN0ICkgewoJCQlpZiAoICEgZW1wdHkoICRwdWxsX3JlcXVlc3QtPnVzZXIgKSApIHsKCQkJCSRjb250cmlidXRvcnNbICRwdWxsX3JlcXVlc3QtPnVzZXItPmh0bWxfdXJsIF0gPSAkcHVsbF9yZXF1ZXN0LT51c2VyLT5sb2dpbjsKCQkJfQoJCX0KCQlyZXR1cm4gJGNvbnRyaWJ1dG9yczsKCX0KCgkvKioKCSAqIE1ha2UgYSByZXF1ZXN0IHRvIHRoZSBHaXRIdWIgQVBJCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdXJsCgkgKiBAcGFyYW0gc3RyaW5nICRhcmdzCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIG1ha2VfZ2l0aHViX2FwaV9yZXF1ZXN0KCAkdXJsLCAkYXJncyA9IGFycmF5KCkgKSB7CgkJJGhlYWRlcnMgPSBhcnJheSgKCQkJJ0FjY2VwdCcgICAgID0+ICdhcHBsaWNhdGlvbi92bmQuZ2l0aHViLnYzK2pzb24nLAoJCQknVXNlci1BZ2VudCcgPT4gJ1dQLUNMSScsCgkJKTsKCQkkdG9rZW4gICA9IGdldGVudiggJ0dJVEhVQl9UT0tFTicgKTsKCQlpZiAoIGZhbHNlICE9PSAkdG9rZW4gKSB7CgkJCSRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAndG9rZW4gJyAuICR0b2tlbjsKCQl9CgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHVybCwgJGFyZ3MsICRoZWFkZXJzICk7CgkJaWYgKCAyMDAgIT09ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICdHaXRIdWIgQVBJIHJldHVybmVkOiAlcyAoSFRUUCBjb2RlICVkKScsICRyZXNwb25zZS0+Ym9keSwgJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApICk7CgkJfQoJCXJldHVybiBhcnJheSgganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSApLCAkcmVzcG9uc2UtPmhlYWRlcnMgKTsKCX0KCn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdjb250cmliLWxpc3QnLCAnQ29udHJpYl9MaXN0X0NvbW1hbmQnICk7CiMhL3Vzci9iaW4vZW52IHNoCgojIFNwZWNpYWwgY2FzZSBmb3IgKkFNUCBpbnN0YWxsZXJzLCBzaW5jZSB0aGV5IG5vcm1hbGx5IGRvbid0IHNldCB0aGVtc2VsdmVzCiMgYXMgdGhlIGRlZmF1bHQgY2xpIHBocCBvdXQgb2YgdGhlIGJveC4KZm9yIGFtcF9waHAgaW4gJChjYXQgJChkaXJuYW1lICQwKS9hbXAtcGF0aHMudHh0KTsgZG8KCWlmIFsgLXggJGFtcF9waHAgXTsgdGhlbgoJCWVjaG8gJGFtcF9waHAKCQlleGl0CglmaQpkb25lCgp3aGljaCBwaHAgfHwgd2hpY2ggcGhwLWNsaQoKaWYgWyAkPyAtZXEgMCBdOyB0aGVuCglleGl0CmZpCgplY2hvICJubyBQSFAgYmluYXJ5IGZvdW5kIiA+JjIKZXhpdCAxCjw/cGhwCgokZmlsZSA9ICRhcmd2WzFdOwppZiAoICEgZmlsZV9leGlzdHMoICRmaWxlICkgKSB7CgllY2hvICdGaWxlIGRvZXMgbm90IGV4aXN0Lic7CglleGl0KCAxICk7Cn0KCiRjb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkZmlsZSApOwokY29tcG9zZXIgPSBqc29uX2RlY29kZSggJGNvbnRlbnRzICk7CgppZiAoIGVtcHR5KCAkY29tcG9zZXIgKSB8fCAhIGlzX29iamVjdCggJGNvbXBvc2VyICkgKSB7CgllY2hvICdJbnZhbGlkIGNvbXBvc2VyLmpzb24gZm9yIHBhY2thZ2UuJzsKCWV4aXQoIDEgKTsKfQoKaWYgKCBlbXB0eSggJGNvbXBvc2VyLT5hdXRvbG9hZC0+ZmlsZXMgKSApIHsKCWVjaG8gJ2NvbXBvc2VyLmpzb24gbXVzdCBzcGVjaWZ5IHZhbGlkICJhdXRvbG9hZCIgPT4gImZpbGVzIic7CglleGl0KCAxICk7Cn0KCmVjaG8gaW1wbG9kZSggUEhQX0VPTCwgJGNvbXBvc2VyLT5hdXRvbG9hZC0+ZmlsZXMgKTsKZXhpdCggMCApOwo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX3N1cGVyX2FkbWluX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX3N1cGVyX2FkbWluX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfc3VwZXJfYWRtaW5fYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdzdXBlci1hZG1pbicsCgknU3VwZXJfQWRtaW5fQ29tbWFuZCcsCglhcnJheSgKCQknYmVmb3JlX2ludm9rZScgPT4gZnVuY3Rpb24gKCkgewoJCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnVGhpcyBpcyBub3QgYSBtdWx0aXNpdGUgaW5zdGFsbGF0aW9uLicgKTsKCQkJfQoJCX0sCgkpCik7Cjw/cGhwCnVzZSBXUF9DTElcRmV0Y2hlcnNcVXNlciBhcyBVc2VyRmV0Y2hlcjsKCi8qKgogKiBMaXN0cywgYWRkcywgb3IgcmVtb3ZlcyBzdXBlciBhZG1pbiB1c2VycyBvbiBhIG11bHRpc2l0ZSBpbnN0YWxsYXRpb24uCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgdXNlciB3aXRoIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcwogKiAgICAgJCB3cCBzdXBlci1hZG1pbiBsaXN0CiAqICAgICBzdXBlcnZpc29yCiAqICAgICBhZG1pbmlzdHJhdG9yCiAqCiAqICAgICAjIEdyYW50IHN1cGVyLWFkbWluIHByaXZpbGVnZXMgdG8gdGhlIHVzZXIuCiAqICAgICAkIHdwIHN1cGVyLWFkbWluIGFkZCBzdXBlcmFkbWluMgogKiAgICAgU3VjY2VzczogR3JhbnRlZCBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMuCiAqCiAqICAgICAjIFJldm9rZSBzdXBlci1hZG1pbiBwcml2aWxlZ2VzIHRvIHRoZSB1c2VyLgogKiAgICAgJCB3cCBzdXBlci1hZG1pbiByZW1vdmUgc3VwZXJhZG1pbjIKICogICAgIFN1Y2Nlc3M6IFJldm9rZWQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIFN1cGVyX0FkbWluX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJcHJpdmF0ZSAkZmllbGRzID0gYXJyYXkoCgkJJ3VzZXJfbG9naW4nLAoJKTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPmZldGNoZXIgPSBuZXcgVXNlckZldGNoZXIoKTsKCX0KCgkvKioKCSAqIExpc3RzIHVzZXJzIHdpdGggc3VwZXIgYWRtaW4gY2FwYWJpbGl0aWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogbGlzdAoJICogb3B0aW9uczoKCSAqICAgLSBsaXN0CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExpc3QgdXNlciB3aXRoIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcwoJICogICAgICQgd3Agc3VwZXItYWRtaW4gbGlzdAoJICogICAgIHN1cGVydmlzb3IKCSAqICAgICBhZG1pbmlzdHJhdG9yCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF9zdWJjb21tYW5kKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJHN1cGVyX2FkbWlucyA9IHNlbGY6OmdldF9hZG1pbnMoKTsKCgkJaWYgKCAnbGlzdCcgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJZm9yZWFjaCAoICRzdXBlcl9hZG1pbnMgYXMgJHVzZXJfbG9naW4gKSB7CgkJCQlXUF9DTEk6OmxpbmUoICR1c2VyX2xvZ2luICk7CgkJCX0KCQl9IGVsc2UgewoJCQkkb3V0cHV0X3VzZXJzID0gYXJyYXkoKTsKCQkJZm9yZWFjaCAoICRzdXBlcl9hZG1pbnMgYXMgJHVzZXJfbG9naW4gKSB7CgkJCQkkb3V0cHV0X3VzZXIgPSBuZXcgc3RkQ2xhc3MoKTsKCgkJCQkkb3V0cHV0X3VzZXItPnVzZXJfbG9naW4gPSAkdXNlcl9sb2dpbjsKCgkJCQkkb3V0cHV0X3VzZXJzW10gPSAkb3V0cHV0X3VzZXI7CgkJCX0KCQkJJGZvcm1hdHRlciA9IG5ldyBcV1BfQ0xJXEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5maWVsZHMgKTsKCQkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJG91dHB1dF91c2VycyApOwoJCX0KCX0KCgkvKioKCSAqIEdyYW50cyBzdXBlciBhZG1pbiBwcml2aWxlZ2VzIHRvIG9uZSBvciBtb3JlIHVzZXJzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dXNlcj4uLi4KCSAqIDogT25lIG9yIG1vcmUgdXNlciBJRHMsIHVzZXIgZW1haWxzLCBvciB1c2VyIGxvZ2lucy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHN1cGVyLWFkbWluIGFkZCBzdXBlcmFkbWluMgoJICogICAgIFN1Y2Nlc3M6IEdyYW50ZWQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWRkKCAkYXJncywgJF8gKSB7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSR1c2VycyAgICAgPSAkdGhpcy0+ZmV0Y2hlci0+Z2V0X21hbnkoICRhcmdzICk7CgkJaWYgKCBjb3VudCggJHVzZXJzICkgIT09IGNvdW50KCAkYXJncyApICkgewoJCQkkZXJyb3JzID0gY291bnQoICRhcmdzICkgLSBjb3VudCggJHVzZXJzICk7CgkJfQoJCSR1c2VyX2xvZ2lucyAgICAgID0gd3BfbGlzdF9wbHVjayggJHVzZXJzLCAndXNlcl9sb2dpbicgKTsKCQkkc3VwZXJfYWRtaW5zICAgICA9IHNlbGY6OmdldF9hZG1pbnMoKTsKCQkkbnVtX3N1cGVyX2FkbWlucyA9IGNvdW50KCAkc3VwZXJfYWRtaW5zICk7CgoJCWZvcmVhY2ggKCAkdXNlcl9sb2dpbnMgYXMgJHVzZXJfbG9naW4gKSB7CgkJCWlmICggaW5fYXJyYXkoICR1c2VyX2xvZ2luLCAkc3VwZXJfYWRtaW5zLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJVc2VyICd7JHVzZXJfbG9naW59JyBhbHJlYWR5IGhhcyBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMuIiApOwoJCQkJY29udGludWU7CgkJCX0KCgkJCSRzdXBlcl9hZG1pbnNbXSA9ICR1c2VyX2xvZ2luOwoJCQkkc3VjY2Vzc2VzKys7CgkJfQoKCQlpZiAoIGNvdW50KCAkc3VwZXJfYWRtaW5zICkgPT09ICRudW1fc3VwZXJfYWRtaW5zICkgewoJCQlpZiAoICRlcnJvcnMgKSB7CgkJCQkkdXNlcl9jb3VudCA9IGNvdW50KCAkYXJncyApOwoJCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGdyYW50IHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcyB0byB7JGVycm9yc30gb2YgeyR1c2VyX2NvdW50fSB1c2Vycy4iICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdTdXBlciBhZG1pbnMgcmVtYWluIHVuY2hhbmdlZC4nICk7CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAoIHVwZGF0ZV9zaXRlX29wdGlvbiggJ3NpdGVfYWRtaW5zJywgJHN1cGVyX2FkbWlucyApICkgewoJCQkJaWYgKCAkZXJyb3JzICkgewoJCQkJCSR1c2VyX2NvdW50ID0gY291bnQoICRhcmdzICk7CgkJCQkJV1BfQ0xJOjplcnJvciggIk9ubHkgZ3JhbnRlZCBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMgdG8geyRzdWNjZXNzZXN9IG9mIHskdXNlcl9jb3VudH0gdXNlcnMuIiApOwoJCQkJfSBlbHNlIHsKCQkJCQkkbWVzc2FnZSA9ICRzdWNjZXNzZXMgPiAxID8gJ3VzZXJzJyA6ICd1c2VyJzsKCQkJCQlXUF9DTEk6OnN1Y2Nlc3MoICJHcmFudGVkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcyB0byB7JHN1Y2Nlc3Nlc30geyRtZXNzYWdlfS4iICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnU2l0ZSBvcHRpb25zIHVwZGF0ZSBmYWlsZWQuJyApOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogUmVtb3ZlcyBzdXBlciBhZG1pbiBwcml2aWxlZ2VzIGZyb20gb25lIG9yIG1vcmUgdXNlcnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx1c2VyPi4uLgoJICogOiBPbmUgb3IgbW9yZSB1c2VyIElEcywgdXNlciBlbWFpbHMsIG9yIHVzZXIgbG9naW5zLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc3VwZXItYWRtaW4gcmVtb3ZlIHN1cGVyYWRtaW4yCgkgKiAgICAgU3VjY2VzczogUmV2b2tlZCBzdXBlci1hZG1pbiBjYXBhYmlsaXRpZXMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiByZW1vdmUoICRhcmdzLCAkXyApIHsKCQkkc3VwZXJfYWRtaW5zID0gc2VsZjo6Z2V0X2FkbWlucygpOwoJCWlmICggISAkc3VwZXJfYWRtaW5zICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gc3VwZXIgYWRtaW5zIHRvIHJldm9rZSBzdXBlci1hZG1pbiBwcml2aWxlZ2VzIGZyb20uJyApOwoJCX0KCgkJJHVzZXJzICAgICAgICAgICAgID0gJHRoaXMtPmZldGNoZXItPmdldF9tYW55KCAkYXJncyApOwoJCSR1c2VyX2xvZ2lucyAgICAgICA9ICR1c2VycyA/IGFycmF5X3ZhbHVlcyggYXJyYXlfdW5pcXVlKCB3cF9saXN0X3BsdWNrKCAkdXNlcnMsICd1c2VyX2xvZ2luJyApICkgKSA6IGFycmF5KCk7CgkJJHVzZXJfbG9naW5zX2NvdW50ID0gY291bnQoICR1c2VyX2xvZ2lucyApOwoKCQlpZiAoICR1c2VyX2xvZ2luc19jb3VudCA8IGNvdW50KCAkYXJncyApICkgewoJCQkkZmxpcHBlZF91c2VyX2xvZ2lucyA9IGFycmF5X2ZsaXAoICR1c2VyX2xvZ2lucyApOwoJCQkvLyBGZXRjaGVyIGhhcyBhbHJlYWR5IHdhcm5lZCBzbyBkb24ndCBib3RoZXIgaGVyZSwgYnV0IGNvbnRpbnVlIHdpdGggYW55IGFyZ3MgdGhhdCBhcmUgcG9zc2libGUgbG9naW4gbmFtZXMgdG8gY2F0ZXIgZm9yIGludmFsaWQgdXNlcnMgaW4gdGhlIHNpdGUgb3B0aW9ucyBtZXRhLgoKCQkJJHVzZXJfbG9naW5zICAgICAgID0gYXJyYXlfbWVyZ2UoCgkJCQkkdXNlcl9sb2dpbnMsCgkJCQlhcnJheV91bmlxdWUoCgkJCQkJYXJyYXlfZmlsdGVyKAoJCQkJCQkkYXJncywKCQkJCQkJZnVuY3Rpb24gKCAkdiApIHVzZSAoICRmbGlwcGVkX3VzZXJfbG9naW5zICkgewoJCQkJCQkJLy8gRXhjbHVkZSBudW1lcmljIGFuZCBlbWFpbC1saWtlIGxvZ2lucyAobG9naW4gbmFtZXMgY2FuIGJlIGVtYWlsLWxpa2UgYnV0IGlnbm9yZSB0aGlzIGdpdmVuIHRoZSBjaXJjdW1zdGFuY2VzKS4KCQkJCQkJCXJldHVybiAhIGlzc2V0KCAkZmxpcHBlZF91c2VyX2xvZ2luc1sgJHYgXSApICYmICEgaXNfbnVtZXJpYyggJHYgKSAmJiAhIGlzX2VtYWlsKCAkdiApOwoJCQkJCQl9CgkJCQkJKQoJCQkJKQoJCQkpOwoJCQkkdXNlcl9sb2dpbnNfY291bnQgPSBjb3VudCggJHVzZXJfbG9naW5zICk7CgkJfQoJCWlmICggISAkdXNlcl9sb2dpbnMgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdObyB2YWxpZCB1c2VyIGxvZ2lucyBnaXZlbiB0byByZXZva2Ugc3VwZXItYWRtaW4gcHJpdmlsZWdlcyBmcm9tLicgKTsKCQl9CgoJCSR1cGRhdGVfc3VwZXJfYWRtaW5zID0gYXJyYXlfZGlmZiggJHN1cGVyX2FkbWlucywgJHVzZXJfbG9naW5zICk7CgkJaWYgKCAkdXBkYXRlX3N1cGVyX2FkbWlucyA9PT0gJHN1cGVyX2FkbWlucyApIHsKCQkJV1BfQ0xJOjplcnJvciggJHVzZXJfbG9naW5zX2NvdW50ID4gMSA/ICdOb25lIG9mIHRoZSBnaXZlbiB1c2VycyBpcyBhIHN1cGVyIGFkbWluLicgOiAnVGhlIGdpdmVuIHVzZXIgaXMgbm90IGEgc3VwZXIgYWRtaW4uJyApOwoJCX0KCgkJdXBkYXRlX3NpdGVfb3B0aW9uKCAnc2l0ZV9hZG1pbnMnLCAkdXBkYXRlX3N1cGVyX2FkbWlucyApOwoKCQkkc3VjY2Vzc2VzID0gY291bnQoICRzdXBlcl9hZG1pbnMgKSAtIGNvdW50KCAkdXBkYXRlX3N1cGVyX2FkbWlucyApOwoJCWlmICggJHN1Y2Nlc3NlcyA9PT0gJHVzZXJfbG9naW5zX2NvdW50ICkgewoJCQkkbWVzc2FnZSA9ICR1c2VyX2xvZ2luc19jb3VudCA+IDEgPyAndXNlcnMnIDogJ3VzZXInOwoJCQkkbXNnICAgICA9ICJSZXZva2VkIHN1cGVyLWFkbWluIGNhcGFiaWxpdGllcyBmcm9tIHskdXNlcl9sb2dpbnNfY291bnR9IHskbWVzc2FnZX0uIjsKCQl9IGVsc2UgewoJCQkkbXNnID0gIlJldm9rZWQgc3VwZXItYWRtaW4gY2FwYWJpbGl0aWVzIGZyb20geyRzdWNjZXNzZXN9IG9mIHskdXNlcl9sb2dpbnNfY291bnR9IHVzZXJzLiI7CgkJfQoJCWlmICggISAkdXBkYXRlX3N1cGVyX2FkbWlucyApIHsKCQkJJG1zZyAuPSAnIFRoZXJlIGFyZSBubyByZW1haW5pbmcgc3VwZXIgYWRtaW5zLic7CgkJfQoJCVdQX0NMSTo6c3VjY2VzcyggJG1zZyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9hZG1pbnMoKSB7CgkJLy8gV2UgZG9uJ3QgdXNlIGdldF9zdXBlcl9hZG1pbnMoKSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gbWVzcyB3aXRoIHRoZSBnbG9iYWwKCQlyZXR1cm4gKGFycmF5KSBnZXRfc2l0ZV9vcHRpb24oICdzaXRlX2FkbWlucycsIGFycmF5KCAnYWRtaW4nICkgKTsKCX0KfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX3BhY2thZ2VfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfcGFja2FnZV9hdXRvbG9hZGVyICkgJiYgISBjbGFzc19leGlzdHMoICdQYWNrYWdlX0NvbW1hbmQnICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3BhY2thZ2VfYXV0b2xvYWRlcjsKfQpXUF9DTEk6OmFkZF9jb21tYW5kKCAncGFja2FnZScsICdQYWNrYWdlX0NvbW1hbmQnICk7Cjw/cGhwCgovKgogKiBXUF9DTEk6IENvcGllZCBhbmQgYWRhcHRlZCBmcm9tIHZlbmRvci9jb21wb3Nlci9jb21wb3Nlci9zcmMvQ29tcG9zZXIvSnNvbi9Kc29uTWFuaXB1bGF0b3IucGhwLiBDaGFuZ2VzIG1hcmtlZCBgV1BfQ0xJYC4KICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgQ29tcG9zZXIuCiAqCiAqIChjKSBOaWxzIEFkZXJtYW5uIDxuYWRlcm1hbkBuYWRlcm1hbi5kZT4KICogICAgIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBXUF9DTEk7IC8vIFdQX0NMSQoKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7IC8vIFdQX0NMSQp1c2UgQ29tcG9zZXJcUmVwb3NpdG9yeVxQbGF0Zm9ybVJlcG9zaXRvcnk7CgovKioKICogQGF1dGhvciBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKi8KY2xhc3MgSnNvbk1hbmlwdWxhdG9yCnsKICAgIHByaXZhdGUgc3RhdGljICRERUZJTkVTID0gJyg/KERFRklORSkKICAgICAgICg/PG51bWJlcj4gICAtPyAoPz0gWzEtOV18MCg/IVxkKSApIFxkKyAoXC5cZCspPyAoW2VFXSBbKy1dPyBcZCspPyApCiAgICAgICAoPzxib29sZWFuPiAgIHRydWUgfCBmYWxzZSB8IG51bGwgKQogICAgICAgKD88c3RyaW5nPiAgICAiIChbXiJcXFxcXSogfCBcXFxcIFsiXFxcXGJmbnJ0XC9dIHwgXFxcXCB1IFswLTlhLWZdezR9ICkqICIgKQogICAgICAgKD88YXJyYXk+ICAgICBcWyAgKD86ICAoPyZqc29uKSBccyogKD86ICwgKD8manNvbikgXHMqICkqICApPyAgXHMqIFxdICkKICAgICAgICg/PHBhaXI+ICAgICAgXHMqICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICkKICAgICAgICg/PG9iamVjdD4gICAgXHsgICg/OiAgKD8mcGFpcikgICg/OiAsICg/JnBhaXIpICApKiAgKT8gIFxzKiBcfSApCiAgICAgICAoPzxqc29uPiAgIFxzKiAoPzogKD8mbnVtYmVyKSB8ICg/JmJvb2xlYW4pIHwgKD8mc3RyaW5nKSB8ICg/JmFycmF5KSB8ICg/Jm9iamVjdCkgKSApCiAgICApJzsKCiAgICBwcml2YXRlICRjb250ZW50czsKICAgIHByaXZhdGUgJG5ld2xpbmU7CiAgICBwcml2YXRlICRpbmRlbnQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb250ZW50cykKICAgIHsKICAgICAgICAkY29udGVudHMgPSB0cmltKCRjb250ZW50cyk7CiAgICAgICAgaWYgKCRjb250ZW50cyA9PT0gJycpIHsKICAgICAgICAgICAgJGNvbnRlbnRzID0gJ3t9JzsKICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+cHJlZ01hdGNoKCcjXlx7KC4qKVx9JCNzJywgJGNvbnRlbnRzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIGpzb24gZmlsZSBtdXN0IGJlIGFuIG9iamVjdCAoe30pJyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5uZXdsaW5lID0gZmFsc2UgIT09IHN0cnBvcygkY29udGVudHMsICJcclxuIikgPyAiXHJcbiIgOiAiXG4iOwogICAgICAgICR0aGlzLT5jb250ZW50cyA9ICRjb250ZW50cyA9PT0gJ3t9JyA/ICd7JyAuICR0aGlzLT5uZXdsaW5lIC4gJ30nIDogJGNvbnRlbnRzOwogICAgICAgICR0aGlzLT5kZXRlY3RJbmRlbnRpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29udGVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29udGVudHMgLiAkdGhpcy0+bmV3bGluZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTGluaygkdHlwZSwgJHBhY2thZ2UsICRjb25zdHJhaW50LCAkc29ydFBhY2thZ2VzID0gZmFsc2UsICRjYXNlSW5zZW5zaXRpdmUgPSBmYWxzZSkgLy8gV1BfQ0xJOiBjYXNlSW5zZW5zaXRpdmUuCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CgogICAgICAgIC8vIG5vIGxpbmsgb2YgdGhhdCB0eXBlIHlldAogICAgICAgIGlmICghaXNzZXQoJGRlY29kZWRbJHR5cGVdKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE1haW5LZXkoJHR5cGUsIGFycmF5KCRwYWNrYWdlID0+ICRjb25zdHJhaW50KSk7CiAgICAgICAgfQoKICAgICAgICAkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+XHMqXHtccyooPzooPyZzdHJpbmcpXHMqOlxzKig/Jmpzb24pXHMqLFxzKikqPyknLgogICAgICAgICAgICAnKD9QPHByb3BlcnR5PicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCR0eXBlKSkuJ1xzKjpccyopKD9QPHZhbHVlPig/Jmpzb24pKSg/UDxlbmQ+LiopfXN4JzsKICAgICAgICBpZiAoISR0aGlzLT5wcmVnTWF0Y2goJHJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKCQkvLyBXUF9DTEk6IGJlZ2luIGNhc2VJbnNlbnNpdGl2ZS4KCQlpZiAoJGNhc2VJbnNlbnNpdGl2ZSkgewoJCQkvLyBKdXN0IHphcCBhbnkgZXhpc3RpbmcgcGFja2FnZXMgZmlyc3QgaW4gYSBjYXNlIGluc2Vuc2l0aXZlIG1hbm5lci4KCQkJJHRoaXMtPnJlbW92ZVN1Yk5vZGUoJHR5cGUsICRwYWNrYWdlLCAkY2FzZUluc2Vuc2l0aXZlKTsKCQkJcmV0dXJuICR0aGlzLT5hZGRMaW5rKCR0eXBlLCAkcGFja2FnZSwgJGNvbnN0cmFpbnQsICRzb3J0UGFja2FnZXMpOwoJCX0KCQkvLyBXUF9DTEk6IGVuZCBjYXNlSW5zZW5zaXRpdmUuCgogICAgICAgICRsaW5rcyA9ICRtYXRjaGVzWyd2YWx1ZSddOwoKICAgICAgICAvLyB0cnkgdG8gZmluZCBleGlzdGluZyBsaW5rCiAgICAgICAgJHBhY2thZ2VSZWdleCA9IHN0cl9yZXBsYWNlKCcvJywgJ1xcXFw/LycsIHByZWdfcXVvdGUoJHBhY2thZ2UpKTsKICAgICAgICAkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJyIoP1A8cGFja2FnZT4nLiRwYWNrYWdlUmVnZXguJykiKFxzKjpccyopKD8mc3RyaW5nKX1peCc7CiAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJHJlZ2V4LCAkbGlua3MsICRwYWNrYWdlTWF0Y2hlcykpIHsKICAgICAgICAgICAgLy8gdXBkYXRlIGV4aXN0aW5nIGxpbmsKICAgICAgICAgICAgJGV4aXN0aW5nUGFja2FnZSA9ICRwYWNrYWdlTWF0Y2hlc1sncGFja2FnZSddOwogICAgICAgICAgICAkcGFja2FnZVJlZ2V4ID0gc3RyX3JlcGxhY2UoJy8nLCAnXFxcXD8vJywgcHJlZ19xdW90ZSgkZXhpc3RpbmdQYWNrYWdlKSk7CiAgICAgICAgICAgICRsaW5rcyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygneycuc2VsZjo6JERFRklORVMuJyInLiRwYWNrYWdlUmVnZXguJyIoP1A8c2VwYXJhdG9yPlxzKjpccyopKD8mc3RyaW5nKX1peCcsIGZ1bmN0aW9uICgkbSkgdXNlICgkZXhpc3RpbmdQYWNrYWdlLCAkY29uc3RyYWludCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEpzb25GaWxlOjplbmNvZGUoc3RyX3JlcGxhY2UoJ1xcLycsICcvJywgJGV4aXN0aW5nUGFja2FnZSkpIC4gJG1bJ3NlcGFyYXRvciddIC4gJyInIC4gJGNvbnN0cmFpbnQgLiAnIic7CiAgICAgICAgICAgIH0sICRsaW5rcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJyNeXHMqXHtccypcUysuKj8oXHMqXH1ccyopJCNzJywgJGxpbmtzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAvLyBsaW5rIG1pc3NpbmcgYnV0IG5vbiBlbXB0eSBsaW5rcwogICAgICAgICAgICAgICAgJGxpbmtzID0gcHJlZ19yZXBsYWNlKAogICAgICAgICAgICAgICAgICAgICd7Jy5wcmVnX3F1b3RlKCRtYXRjaFsxXSkuJyR9JywKICAgICAgICAgICAgICAgICAgICAvLyBhZGRjc2xhc2hlcyBpcyB1c2VkIHRvIGRvdWJsZSB1cCBiYWNrc2xhc2hlcy8kIHNpbmNlIHByZWdfcmVwbGFjZSByZXNvbHZlcyB0aGVtIGFzIGJhY2sgcmVmZXJlbmNlcyBvdGhlcndpc2UsIHNlZSAjMTU4OAogICAgICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCcsJyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuICR0aGlzLT5pbmRlbnQgLiBKc29uRmlsZTo6ZW5jb2RlKCRwYWNrYWdlKS4nOiAnLkpzb25GaWxlOjplbmNvZGUoJGNvbnN0cmFpbnQpIC4gJG1hdGNoWzFdLCAnXFwkJyksCiAgICAgICAgICAgICAgICAgICAgJGxpbmtzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gbGlua3MgZW1wdHkKICAgICAgICAgICAgICAgICRsaW5rcyA9ICd7JyAuICR0aGlzLT5uZXdsaW5lIC4KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJHBhY2thZ2UpLic6ICcuSnNvbkZpbGU6OmVuY29kZSgkY29uc3RyYWludCkgLiAkdGhpcy0+bmV3bGluZSAuCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGVudCAuICd9JzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHRydWUgPT09ICRzb3J0UGFja2FnZXMpIHsKICAgICAgICAgICAgJHJlcXVpcmVtZW50cyA9IGpzb25fZGVjb2RlKCRsaW5rcywgdHJ1ZSk7CiAgICAgICAgICAgICR0aGlzLT5zb3J0UGFja2FnZXMoJHJlcXVpcmVtZW50cyk7CiAgICAgICAgICAgICRsaW5rcyA9ICR0aGlzLT5mb3JtYXQoJHJlcXVpcmVtZW50cyk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkbWF0Y2hlc1snc3RhcnQnXSAuICRtYXRjaGVzWydwcm9wZXJ0eSddIC4gJGxpbmtzIC4gJG1hdGNoZXNbJ2VuZCddOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNvcnRzIHBhY2thZ2VzIGJ5IGltcG9ydGFuY2UgKHBsYXRmb3JtIHBhY2thZ2VzIGZpcnN0LCB0aGVuIFBIUCBkZXBlbmRlbmNpZXMpIGFuZCBhbHBoYWJldGljYWxseS4KICAgICAqCiAgICAgKiBAbGluayBodHRwczovL2dldGNvbXBvc2VyLm9yZy9kb2MvMDItbGlicmFyaWVzLm1kI3BsYXRmb3JtLXBhY2thZ2VzCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRwYWNrYWdlcwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNvcnRQYWNrYWdlcyhhcnJheSAmJHBhY2thZ2VzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcHJlZml4ID0gZnVuY3Rpb24gKCRyZXF1aXJlbWVudCkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaChQbGF0Zm9ybVJlcG9zaXRvcnk6OlBMQVRGT1JNX1BBQ0tBR0VfUkVHRVgsICRyZXF1aXJlbWVudCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICcvXnBocC8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15oaHZtLycsCiAgICAgICAgICAgICAgICAgICAgICAgICcvXmV4dC8nLAogICAgICAgICAgICAgICAgICAgICAgICAnL15saWIvJywKICAgICAgICAgICAgICAgICAgICAgICAgJy9eXEQvJywKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnMC0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcxLSQwJywKICAgICAgICAgICAgICAgICAgICAgICAgJzItJDAnLAogICAgICAgICAgICAgICAgICAgICAgICAnMy0kMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICc0LSQwJywKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICRyZXF1aXJlbWVudAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICc1LScuJHJlcXVpcmVtZW50OwogICAgICAgIH07CgogICAgICAgIHVrc29ydCgkcGFja2FnZXMsIGZ1bmN0aW9uICgkYSwgJGIpIHVzZSAoJHByZWZpeCkgewogICAgICAgICAgICByZXR1cm4gc3RybmF0Y21wKCRwcmVmaXgoJGEpLCAkcHJlZml4KCRiKSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZFJlcG9zaXRvcnkoJG5hbWUsICRjb25maWcpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hZGRTdWJOb2RlKCdyZXBvc2l0b3JpZXMnLCAkbmFtZSwgJGNvbmZpZyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlbW92ZVJlcG9zaXRvcnkoJG5hbWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW1vdmVTdWJOb2RlKCdyZXBvc2l0b3JpZXMnLCAkbmFtZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZENvbmZpZ1NldHRpbmcoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZFN1Yk5vZGUoJ2NvbmZpZycsICRuYW1lLCAkdmFsdWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVDb25maWdTZXR0aW5nKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgnY29uZmlnJywgJG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRQcm9wZXJ0eSgkbmFtZSwgJHZhbHVlKQogICAgewogICAgICAgIGlmIChzdWJzdHIoJG5hbWUsIDAsIDYpID09PSAnZXh0cmEuJykgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmFkZFN1Yk5vZGUoJ2V4dHJhJywgc3Vic3RyKCRuYW1lLCA2KSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+YWRkTWFpbktleSgkbmFtZSwgJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHkoJG5hbWUpCiAgICB7CiAgICAgICAgaWYgKHN1YnN0cigkbmFtZSwgMCwgNikgPT09ICdleHRyYS4nKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlU3ViTm9kZSgnZXh0cmEnLCBzdWJzdHIoJG5hbWUsIDYpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+cmVtb3ZlTWFpbktleSgkbmFtZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFkZFN1Yk5vZGUoJG1haW5Ob2RlLCAkbmFtZSwgJHZhbHVlLCAkY2FzZUluc2Vuc2l0aXZlID0gZmFsc2UpIC8vIFdQX0NMSTogY2FzZUluc2Vuc2l0aXZlLgogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAkc3ViTmFtZSA9IG51bGw7CiAgICAgICAgaWYgKGluX2FycmF5KCRtYWluTm9kZSwgYXJyYXkoJ2NvbmZpZycsICdleHRyYScpKSAmJiBmYWxzZSAhPT0gc3RycG9zKCRuYW1lLCAnLicpKSB7CiAgICAgICAgICAgIGxpc3QoJG5hbWUsICRzdWJOYW1lKSA9IGV4cGxvZGUoJy4nLCAkbmFtZSwgMik7CiAgICAgICAgfQoKICAgICAgICAvLyBubyBtYWluIG5vZGUgeWV0CiAgICAgICAgaWYgKCFpc3NldCgkZGVjb2RlZFskbWFpbk5vZGVdKSkgewogICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRNYWluS2V5KCRtYWluTm9kZSwgYXJyYXkoJG5hbWUgPT4gYXJyYXkoJHN1Yk5hbWUgPT4gJHZhbHVlKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZE1haW5LZXkoJG1haW5Ob2RlLCBhcnJheSgkbmFtZSA9PiAkdmFsdWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBtYWluIG5vZGUgY29udGVudCBub3QgbWF0Y2gtYWJsZQogICAgICAgICRub2RlUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+IFxzKiBceyBccyogKD86ICg/JnN0cmluZykgXHMqIDogKD8manNvbikgXHMqICwgXHMqICkqPycuCiAgICAgICAgICAgIHByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgkbWFpbk5vZGUpKS4nXHMqOlxzKikoP1A8Y29udGVudD4oPyZvYmplY3QpKSg/UDxlbmQ+LiopfXN4JzsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+cHJlZ01hdGNoKCRub2RlUmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoXFJ1bnRpbWVFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCRlLT5nZXRDb2RlKCkgPT09IFBSRUdfQkFDS1RSQUNLX0xJTUlUX0VSUk9SKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQoKCQkvLyBXUF9DTEk6IGJlZ2luIGNhc2VJbnNlbnNpdGl2ZS4KCQlpZiAoJGNhc2VJbnNlbnNpdGl2ZSkgewoJCQkvLyBKdXN0IHphcCBhbnkgZXhpc3RpbmcgbmFtZXMgZmlyc3QgaW4gYSBjYXNlIGluc2Vuc2l0aXZlIG1hbm5lci4KCQkJJHRoaXMtPnJlbW92ZVN1Yk5vZGUoJG1haW5Ob2RlLCAkbmFtZSwgJGNhc2VJbnNlbnNpdGl2ZSk7CgkJCXJldHVybiAkdGhpcy0+YWRkU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lLCAkdmFsdWUpOwoJCX0KCQkvLyBXUF9DTEk6IGVuZCBjYXNlSW5zZW5zaXRpdmUuCgogICAgICAgICRjaGlsZHJlbiA9ICRtYXRjaFsnY29udGVudCddOwogICAgICAgIC8vIGludmFsaWQgbWF0Y2ggZHVlIHRvIHVuLXJlZ2V4YWJsZSBjb250ZW50LCBhYm9ydAogICAgICAgIGlmICghQGpzb25fZGVjb2RlKCRjaGlsZHJlbikpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHRoYXQgPSAkdGhpczsKCiAgICAgICAgLy8gY2hpbGQgZXhpc3RzCiAgICAgICAgJGNoaWxkUmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJyg/UDxzdGFydD4iJy5wcmVnX3F1b3RlKCRuYW1lKS4nIlxzKjpccyopKD9QPGNvbnRlbnQ+KD8manNvbikpKD9QPGVuZD4sPyl9eCc7CiAgICAgICAgaWYgKCR0aGlzLT5wcmVnTWF0Y2goJGNoaWxkUmVnZXgsICRjaGlsZHJlbiwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICRjaGlsZHJlbiA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygkY2hpbGRSZWdleCwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCRuYW1lLCAkc3ViTmFtZSwgJHZhbHVlLCAkdGhhdCkgewogICAgICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJGN1clZhbCA9IGpzb25fZGVjb2RlKCRtYXRjaGVzWydjb250ZW50J10sIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJGN1clZhbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGN1clZhbCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRjdXJWYWxbJHN1Yk5hbWVdID0gJHZhbHVlOwogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9ICRjdXJWYWw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRtYXRjaGVzWydzdGFydCddIC4gJHRoYXQtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJG1hdGNoZXNbJ2VuZCddOwogICAgICAgICAgICB9LCAkY2hpbGRyZW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5wcmVnTWF0Y2goJyNeeyBccyo/ICg/UDxjb250ZW50PlxTKy4qPyk/ICg/UDx0cmFpbGluZ3NwYWNlPlxzKikgfSQjc3gnLCAkY2hpbGRyZW4sICRtYXRjaCk7CgogICAgICAgICAgICAkd2hpdGVzcGFjZSA9ICcnOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRtYXRjaFsndHJhaWxpbmdzcGFjZSddKSkgewogICAgICAgICAgICAgICAgJHdoaXRlc3BhY2UgPSAkbWF0Y2hbJ3RyYWlsaW5nc3BhY2UnXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkbWF0Y2hbJ2NvbnRlbnQnXSkpIHsKICAgICAgICAgICAgICAgIGlmICgkc3ViTmFtZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9IGFycmF5KCRzdWJOYW1lID0+ICR2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gY2hpbGQgbWlzc2luZyBidXQgbm9uIGVtcHR5IGNoaWxkcmVuCiAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgJyMnLiR3aGl0ZXNwYWNlLid9JCMnLAogICAgICAgICAgICAgICAgICAgIGFkZGNzbGFzaGVzKCcsJyAuICR0aGlzLT5uZXdsaW5lIC4gJHRoaXMtPmluZGVudCAuICR0aGlzLT5pbmRlbnQgLiBKc29uRmlsZTo6ZW5jb2RlKCRuYW1lKS4nOiAnLiR0aGlzLT5mb3JtYXQoJHZhbHVlLCAxKSAuICR3aGl0ZXNwYWNlIC4gJ30nLCAnXFwkJyksCiAgICAgICAgICAgICAgICAgICAgJGNoaWxkcmVuCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlID0gYXJyYXkoJHN1Yk5hbWUgPT4gJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBjaGlsZHJlbiBwcmVzZW50IGJ1dCBlbXB0eQogICAgICAgICAgICAgICAgJGNoaWxkcmVuID0gJ3snIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gJHRoaXMtPmluZGVudCAuIEpzb25GaWxlOjplbmNvZGUoJG5hbWUpLic6ICcuJHRoaXMtPmZvcm1hdCgkdmFsdWUsIDEpIC4gJHdoaXRlc3BhY2UgLiAnfSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygkbm9kZVJlZ2V4LCBmdW5jdGlvbiAoJG0pIHVzZSAoJGNoaWxkcmVuKSB7CiAgICAgICAgICAgIHJldHVybiAkbVsnc3RhcnQnXSAuICRjaGlsZHJlbiAuICRtWydlbmQnXTsKICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlU3ViTm9kZSgkbWFpbk5vZGUsICRuYW1lLCAkY2FzZUluc2Vuc2l0aXZlID0gZmFsc2UpIC8vIFdQX0NMSTogY2FzZUluc2Vuc2l0aXZlLgogICAgewogICAgICAgICRkZWNvZGVkID0gSnNvbkZpbGU6OnBhcnNlSnNvbigkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICAvLyBubyBub2RlIG9yIGVtcHR5IG5vZGUKICAgICAgICBpZiAoZW1wdHkoJGRlY29kZWRbJG1haW5Ob2RlXSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKCQkvLyBXUF9DTEk6IGJlZ2luIGNhc2VJbnNlbnNpdGl2ZS4KCQlpZiAoICRjYXNlSW5zZW5zaXRpdmUgKSB7CgkJCS8vIFRoaXMgaXMgbW9yZSBvciBsZXNzIGEgY29weSBvZiB0aGUgY29kZSBhdCB0aGUgc3RhcnQgb2YgYGFkZExpbmsoKWAgYWJvdmUuCgkJCSRyZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nXig/UDxzdGFydD5ccypce1xzKig/Oig/JnN0cmluZylccyo6XHMqKD8manNvbilccyosXHMqKSo/KScuCgkJCQknKD9QPHByb3BlcnR5PicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCRtYWluTm9kZSkpLidccyo6XHMqKSg/UDx2YWx1ZT4oPyZqc29uKSkoP1A8ZW5kPi4qKX1zeCc7CgkJCWlmICghJHRoaXMtPnByZWdNYXRjaCgkcmVnZXgsICR0aGlzLT5jb250ZW50cywgJG1hdGNoZXMpKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJJHZhbHVlID0gJG1hdGNoZXNbJ3ZhbHVlJ107IC8vIFJlbmFtZWQgZnJvbSBgJGxpbmtzYCBpbiBgYWRkTGluaygpYCBjYXNlIGFib3ZlLgoKCQkJLy8gdHJ5IHRvIGZpbmQgZXhpc3RpbmcgdmFsdWVzCgkJCSRuYW1lUmVnZXggPSBzdHJfcmVwbGFjZSgnLycsICdcXFxcPy8nLCBwcmVnX3F1b3RlKCRuYW1lKSk7IC8vIFJlbmFtZWQgZnJvbSBgJHBhY2thZ2VSZWdleGAgaW4gYGFkZExpbmsoKWAgY2FzZSBhYm92ZS4KCQkJJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLiciKD9QPG5hbWU+Jy4kbmFtZVJlZ2V4LicpIihccyo6XHMqKSg/Jmpzb24pfWl4JzsgLy8gTmVlZCBgKD8manNvbilgIFBDUkUgc3Vicm91dGluZSBoZXJlLCBhcyBvcHBvc2VkIHRvIGAoPyZzdHJpbmcpYCBpbiBgYWRkTGluaygpYCBjYXNlLgoJCQlpZiAocHJlZ19tYXRjaF9hbGwoJHJlZ2V4LCAkdmFsdWUsICRuYW1lTWF0Y2hlcykpIHsKCQkJCS8vIEp1c3QgemFwIHRoZW0gYWxsIGluZGl2aWR1YWxseSBpbiBhIGNhc2Ugc2Vuc2l0aXZlIG1hbm5lci4KCQkJCWZvcmVhY2ggKCAkbmFtZU1hdGNoZXNbJ25hbWUnXSBhcyAkbmFtZU1hdGNoICkgewoJCQkJCSR0aGlzLT5yZW1vdmVTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWVNYXRjaCk7CgkJCQl9CgkJCX0KCgkJCXJldHVybiB0cnVlOwoJCX0KCQkvLyBXUF9DTEk6IGVuZCBjYXNlSW5zZW5zaXRpdmUuCgogICAgICAgIC8vIG5vIG5vZGUgY29udGVudCBtYXRjaC1hYmxlCiAgICAgICAgJG5vZGVSZWdleCA9ICd7Jy5zZWxmOjokREVGSU5FUy4nXig/UDxzdGFydD4gXHMqIFx7IFxzKiAoPzogKD8mc3RyaW5nKSBccyogOiAoPyZqc29uKSBccyogLCBccyogKSo/Jy4KICAgICAgICAgICAgcHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCRtYWluTm9kZSkpLidccyo6XHMqKSg/UDxjb250ZW50Pig/Jm9iamVjdCkpKD9QPGVuZD4uKil9c3gnOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghJHRoaXMtPnByZWdNYXRjaCgkbm9kZVJlZ2V4LCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFxSdW50aW1lRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgkZS0+Z2V0Q29kZSgpID09PSBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KCiAgICAgICAgJGNoaWxkcmVuID0gJG1hdGNoWydjb250ZW50J107CgogICAgICAgIC8vIGludmFsaWQgbWF0Y2ggZHVlIHRvIHVuLXJlZ2V4YWJsZSBjb250ZW50LCBhYm9ydAogICAgICAgIGlmICghQGpzb25fZGVjb2RlKCRjaGlsZHJlbiwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgJHN1Yk5hbWUgPSBudWxsOwogICAgICAgIGlmIChpbl9hcnJheSgkbWFpbk5vZGUsIGFycmF5KCdjb25maWcnLCAnZXh0cmEnKSkgJiYgZmFsc2UgIT09IHN0cnBvcygkbmFtZSwgJy4nKSkgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkc3ViTmFtZSkgPSBleHBsb2RlKCcuJywgJG5hbWUsIDIpOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbm9kZSB0byByZW1vdmUKICAgICAgICBpZiAoIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdKSB8fCAoJHN1Yk5hbWUgJiYgIWlzc2V0KCRkZWNvZGVkWyRtYWluTm9kZV1bJG5hbWVdWyRzdWJOYW1lXSkpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gdHJ5IGFuZCBmaW5kIGEgbWF0Y2ggZm9yIHRoZSBzdWJrZXkKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgneyInLnByZWdfcXVvdGUoJG5hbWUpLiciXHMqOn1pJywgJGNoaWxkcmVuKSkgewogICAgICAgICAgICAvLyBmaW5kIGJlc3QgbWF0Y2ggZm9yIHRoZSB2YWx1ZSBvZiAibmFtZSIKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2hfYWxsKCd7Jy5zZWxmOjokREVGSU5FUy4nIicucHJlZ19xdW90ZSgkbmFtZSkuJyJccyo6XHMqKD86KD8manNvbikpfXgnLCAkY2hpbGRyZW4sICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgJGJlc3RNYXRjaCA9ICcnOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXNbMF0gYXMgJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkYmVzdE1hdGNoKSA8IHN0cmxlbigkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRiZXN0TWF0Y2ggPSAkbWF0Y2g7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNoaWxkcmVuQ2xlYW4gPSBwcmVnX3JlcGxhY2UoJ3ssXHMqJy5wcmVnX3F1b3RlKCRiZXN0TWF0Y2gpLid9JywgJycsICRjaGlsZHJlbiwgLTEsICRjb3VudCk7IC8vIFdQX0NMSTogQXMgdGhlIHByZWdfbWF0Y2hfYWxsKCkgYWJvdmUgaXMgY2FzZS1zZW5zaXRpdmUsIHNvIHNob3VsZCB0aGlzIGJlLgogICAgICAgICAgICAgICAgaWYgKDEgIT09ICRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gcHJlZ19yZXBsYWNlKCd7Jy5wcmVnX3F1b3RlKCRiZXN0TWF0Y2gpLidccyosP1xzKn0nLCAnJywgJGNoaWxkcmVuQ2xlYW4sIC0xLCAkY291bnQpOyAvLyBXUF9DTEk6IGRpdHRvLgogICAgICAgICAgICAgICAgICAgIGlmICgxICE9PSAkY291bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjaGlsZHJlbkNsZWFuID0gJGNoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gY2hpbGQgZGF0YSBsZWZ0LCAkbmFtZSB3YXMgdGhlIG9ubHkga2V5IGluCiAgICAgICAgJHRoaXMtPnByZWdNYXRjaCgnI157IFxzKj8gKD9QPGNvbnRlbnQ+XFMrLio/KT8gKD9QPHRyYWlsaW5nc3BhY2U+XHMqKSB9JCNzeCcsICRjaGlsZHJlbkNsZWFuLCAkbWF0Y2gpOwogICAgICAgIGlmIChlbXB0eSgkbWF0Y2hbJ2NvbnRlbnQnXSkpIHsKICAgICAgICAgICAgJG5ld2xpbmUgPSAkdGhpcy0+bmV3bGluZTsKICAgICAgICAgICAgJGluZGVudCA9ICR0aGlzLT5pbmRlbnQ7CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJG5vZGVSZWdleCwgZnVuY3Rpb24gKCRtYXRjaGVzKSB1c2UgKCRpbmRlbnQsICRuZXdsaW5lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3N0YXJ0J10gLiAneycgLiAkbmV3bGluZSAuICRpbmRlbnQgLiAnfScgLiAkbWF0Y2hlc1snZW5kJ107CiAgICAgICAgICAgIH0sICR0aGlzLT5jb250ZW50cyk7CgogICAgICAgICAgICAvLyB3ZSBoYXZlIGEgc3VibmFtZSwgc28gd2UgcmVzdG9yZSB0aGUgcmVzdCBvZiAkbmFtZQogICAgICAgICAgICBpZiAoJHN1Yk5hbWUgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICRjdXJWYWwgPSBqc29uX2RlY29kZSgkY2hpbGRyZW4sIHRydWUpOwogICAgICAgICAgICAgICAgdW5zZXQoJGN1clZhbFskbmFtZV1bJHN1Yk5hbWVdKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRTdWJOb2RlKCRtYWluTm9kZSwgJG5hbWUsICRjdXJWYWxbJG5hbWVdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAkdGhhdCA9ICR0aGlzOwogICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygkbm9kZVJlZ2V4LCBmdW5jdGlvbiAoJG1hdGNoZXMpIHVzZSAoJHRoYXQsICRuYW1lLCAkc3ViTmFtZSwgJGNoaWxkcmVuQ2xlYW4pIHsKICAgICAgICAgICAgaWYgKCRzdWJOYW1lICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkY3VyVmFsID0ganNvbl9kZWNvZGUoJG1hdGNoZXNbJ2NvbnRlbnQnXSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB1bnNldCgkY3VyVmFsWyRuYW1lXVskc3ViTmFtZV0pOwogICAgICAgICAgICAgICAgJGNoaWxkcmVuQ2xlYW4gPSAkdGhhdC0+Zm9ybWF0KCRjdXJWYWwsIDApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbJ3N0YXJ0J10gLiAkY2hpbGRyZW5DbGVhbiAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICB9LCAkdGhpcy0+Y29udGVudHMpOwoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkTWFpbktleSgka2V5LCAkY29udGVudCkKICAgIHsKICAgICAgICAkZGVjb2RlZCA9IEpzb25GaWxlOjpwYXJzZUpzb24oJHRoaXMtPmNvbnRlbnRzKTsKICAgICAgICAkY29udGVudCA9ICR0aGlzLT5mb3JtYXQoJGNvbnRlbnQpOwoKICAgICAgICAvLyBrZXkgZXhpc3RzIGFscmVhZHkKICAgICAgICAkcmVnZXggPSAneycuc2VsZjo6JERFRklORVMuJ14oP1A8c3RhcnQ+XHMqXHtccyooPzooPyZzdHJpbmcpXHMqOlxzKig/Jmpzb24pXHMqLFxzKikqPyknLgogICAgICAgICAgICAnKD9QPGtleT4nLnByZWdfcXVvdGUoSnNvbkZpbGU6OmVuY29kZSgka2V5KSkuJ1xzKjpccyooPyZqc29uKSkoP1A8ZW5kPi4qKX1zeCc7CiAgICAgICAgaWYgKGlzc2V0KCRkZWNvZGVkWyRrZXldKSAmJiAkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgLy8gaW52YWxpZCBtYXRjaCBkdWUgdG8gdW4tcmVnZXhhYmxlIGNvbnRlbnQsIGFib3J0CiAgICAgICAgICAgIGlmICghQGpzb25fZGVjb2RlKCd7Jy4kbWF0Y2hlc1sna2V5J10uJ30nKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkbWF0Y2hlc1snc3RhcnQnXSAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuJzogJy4kY29udGVudCAuICRtYXRjaGVzWydlbmQnXTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gYXBwZW5kIGF0IHRoZSBlbmQgb2YgdGhlIGZpbGUgYW5kIGtlZXAgd2hpdGVzcGFjZQogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCcjW157XHNdKFxzKilcfSQjJywgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5jb250ZW50cyA9IHByZWdfcmVwbGFjZSgKICAgICAgICAgICAgICAgICcjJy4kbWF0Y2hbMV0uJ1x9JCMnLAogICAgICAgICAgICAgICAgYWRkY3NsYXNoZXMoJywnIC4gJHRoaXMtPm5ld2xpbmUgLiAkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4gJzogJy4gJGNvbnRlbnQgLiAkdGhpcy0+bmV3bGluZSAuICd9JywgJ1xcJCcpLAogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzCiAgICAgICAgICAgICk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGVuZCBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlCiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gcHJlZ19yZXBsYWNlKAogICAgICAgICAgICAnI1x9JCMnLAogICAgICAgICAgICBhZGRjc2xhc2hlcygkdGhpcy0+aW5kZW50IC4gSnNvbkZpbGU6OmVuY29kZSgka2V5KS4gJzogJy4kY29udGVudCAuICR0aGlzLT5uZXdsaW5lIC4gJ30nLCAnXFwkJyksCiAgICAgICAgICAgICR0aGlzLT5jb250ZW50cwogICAgICAgICk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVNYWluS2V5KCRrZXkpCiAgICB7CiAgICAgICAgJGRlY29kZWQgPSBKc29uRmlsZTo6cGFyc2VKc29uKCR0aGlzLT5jb250ZW50cyk7CgogICAgICAgIGlmICghaXNzZXQoJGRlY29kZWRbJGtleV0pKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8ga2V5IGV4aXN0cyBhbHJlYWR5CiAgICAgICAgJHJlZ2V4ID0gJ3snLnNlbGY6OiRERUZJTkVTLideKD9QPHN0YXJ0PlxzKlx7XHMqKD86KD8mc3RyaW5nKVxzKjpccyooPyZqc29uKVxzKixccyopKj8pJy4KICAgICAgICAgICAgJyg/UDxyZW1vdmFsPicucHJlZ19xdW90ZShKc29uRmlsZTo6ZW5jb2RlKCRrZXkpKS4nXHMqOlxzKig/Jmpzb24pKVxzKiw/XHMqKD9QPGVuZD4uKil9c3gnOwogICAgICAgIGlmICgkdGhpcy0+cHJlZ01hdGNoKCRyZWdleCwgJHRoaXMtPmNvbnRlbnRzLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgLy8gaW52YWxpZCBtYXRjaCBkdWUgdG8gdW4tcmVnZXhhYmxlIGNvbnRlbnQsIGFib3J0CiAgICAgICAgICAgIGlmICghQGpzb25fZGVjb2RlKCd7Jy4kbWF0Y2hlc1sncmVtb3ZhbCddLid9JykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB3ZSBhcmUgbm90IGxlYXZpbmcgYSBkYW5nbGluZyBjb21tYSBvbiB0aGUgcHJldmlvdXMgbGluZSBpZiB0aGUgbGFzdCBsaW5lIHdhcyByZW1vdmVkCiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcjLFxzKiQjJywgJG1hdGNoZXNbJ3N0YXJ0J10pICYmIHByZWdfbWF0Y2goJyNeXH0kIycsICRtYXRjaGVzWydlbmQnXSkpIHsKICAgICAgICAgICAgICAgICRtYXRjaGVzWydzdGFydCddID0gcnRyaW0ocHJlZ19yZXBsYWNlKCcjLChccyopJCMnLCAnJDEnLCAkbWF0Y2hlc1snc3RhcnQnXSksICR0aGlzLT5pbmRlbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSAkbWF0Y2hlc1snc3RhcnQnXSAuICRtYXRjaGVzWydlbmQnXTsKICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJyNeXHtccypcfVxzKiQjJywgJHRoaXMtPmNvbnRlbnRzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gIntcbn0iOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZm9ybWF0KCRkYXRhLCAkZGVwdGggPSAwKQogICAgewogICAgICAgIGlmIChpc19hcnJheSgkZGF0YSkpIHsKICAgICAgICAgICAgcmVzZXQoJGRhdGEpOwoKICAgICAgICAgICAgaWYgKGlzX251bWVyaWMoa2V5KCRkYXRhKSkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRkYXRhIGFzICRrZXkgPT4gJHZhbCkgewogICAgICAgICAgICAgICAgICAgICRkYXRhWyRrZXldID0gJHRoaXMtPmZvcm1hdCgkdmFsLCAkZGVwdGggKyAxKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJ1snLmltcGxvZGUoJywgJywgJGRhdGEpLiddJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG91dCA9ICd7JyAuICR0aGlzLT5uZXdsaW5lOwogICAgICAgICAgICAkZWxlbXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkZGF0YSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICAgICAgICAgICRlbGVtc1tdID0gc3RyX3JlcGVhdCgkdGhpcy0+aW5kZW50LCAkZGVwdGggKyAyKSAuIEpzb25GaWxlOjplbmNvZGUoJGtleSkuICc6ICcuJHRoaXMtPmZvcm1hdCgkdmFsLCAkZGVwdGggKyAxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICRvdXQgLiBpbXBsb2RlKCcsJy4kdGhpcy0+bmV3bGluZSwgJGVsZW1zKSAuICR0aGlzLT5uZXdsaW5lIC4gc3RyX3JlcGVhdCgkdGhpcy0+aW5kZW50LCAkZGVwdGggKyAxKSAuICd9JzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBKc29uRmlsZTo6ZW5jb2RlKCRkYXRhKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGV0ZWN0SW5kZW50aW5nKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnByZWdNYXRjaCgne14oWyBcdF0rKSJ9bScsICR0aGlzLT5jb250ZW50cywgJG1hdGNoKSkgewogICAgICAgICAgICAkdGhpcy0+aW5kZW50ID0gJG1hdGNoWzFdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRlbnQgPSAnICAgICc7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwcmVnTWF0Y2goJHJlLCAkc3RyLCAmJG1hdGNoZXMgPSBhcnJheSgpKQogICAgewogICAgICAgICRjb3VudCA9IHByZWdfbWF0Y2goJHJlLCAkc3RyLCAkbWF0Y2hlcyk7CgogICAgICAgIGlmICgkY291bnQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHN3aXRjaCAocHJlZ19sYXN0X2Vycm9yKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19OT19FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX05PX0VSUk9SJywgUFJFR19OT19FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfSU5URVJOQUxfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19JTlRFUk5BTF9FUlJPUicsIFBSRUdfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX0JBQ0tUUkFDS19MSU1JVF9FUlJPUicsIFBSRUdfQkFDS1RSQUNLX0xJTUlUX0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgUFJFR19SRUNVUlNJT05fTElNSVRfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19SRUNVUlNJT05fTElNSVRfRVJST1InLCBQUkVHX1JFQ1VSU0lPTl9MSU1JVF9FUlJPUik7CiAgICAgICAgICAgICAgICBjYXNlIFBSRUdfQkFEX1VURjhfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdGYWlsZWQgdG8gZXhlY3V0ZSByZWdleDogUFJFR19CQURfVVRGOF9FUlJPUicsIFBSRUdfQkFEX1VURjhfRVJST1IpOwogICAgICAgICAgICAgICAgY2FzZSBQUkVHX0JBRF9VVEY4X09GRlNFVF9FUlJPUjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0ZhaWxlZCB0byBleGVjdXRlIHJlZ2V4OiBQUkVHX0JBRF9VVEY4X09GRlNFVF9FUlJPUicsIFBSRUdfQkFEX1VURjhfT0ZGU0VUX0VSUk9SKTsKICAgICAgICAgICAgICAgIGNhc2UgNjogLy8gUFJFR19KSVRfU1RBQ0tMSU1JVF9FUlJPUgogICAgICAgICAgICAgICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+IDcwMDAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFBSRUdfSklUX1NUQUNLTElNSVRfRVJST1InLCA2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gZmFsbHRocm91Z2gKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignRmFpbGVkIHRvIGV4ZWN1dGUgcmVnZXg6IFVua25vd24gZXJyb3InKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRjb3VudDsKICAgIH0KfQo8P3BocAoKdXNlIENvbXBvc2VyXENvbXBvc2VyOwp1c2UgQ29tcG9zZXJcQ29uZmlnOwp1c2UgQ29tcG9zZXJcQ29uZmlnXEpzb25Db25maWdTb3VyY2U7CnVzZSBDb21wb3NlclxEZXBlbmRlbmN5UmVzb2x2ZXJcUG9vbDsKdXNlIENvbXBvc2VyXERlcGVuZGVuY3lSZXNvbHZlclxSZXF1ZXN0Owp1c2UgQ29tcG9zZXJcRXZlbnREaXNwYXRjaGVyXEV2ZW50Owp1c2UgQ29tcG9zZXJcRmFjdG9yeTsKdXNlIENvbXBvc2VyXElPXE51bGxJTzsKdXNlIENvbXBvc2VyXEluc3RhbGxlcjsKdXNlIENvbXBvc2VyXEpzb25cSnNvbkZpbGU7CnVzZSBDb21wb3NlclxQYWNrYWdlOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxCYXNlUGFja2FnZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcUGFja2FnZUludGVyZmFjZTsKdXNlIENvbXBvc2VyXFBhY2thZ2VcVmVyc2lvblxWZXJzaW9uUGFyc2VyOwp1c2UgQ29tcG9zZXJcUGFja2FnZVxWZXJzaW9uXFZlcnNpb25TZWxlY3RvcjsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XENvbXBvc2l0ZVJlcG9zaXRvcnk7CnVzZSBDb21wb3NlclxSZXBvc2l0b3J5XENvbXBvc2VyUmVwb3NpdG9yeTsKdXNlIENvbXBvc2VyXFJlcG9zaXRvcnlcUmVwb3NpdG9yeU1hbmFnZXI7CnVzZSBDb21wb3NlclxVdGlsXEZpbGVzeXN0ZW07CnVzZSBDb21wb3NlclxVdGlsXEh0dHBEb3dubG9hZGVyOwp1c2UgV1BfQ0xJXENvbXBvc2VySU87CnVzZSBXUF9DTElcRXh0cmFjdG9yOwp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXEpzb25NYW5pcHVsYXRvcjsKdXNlIFdQX0NMSVxQYWNrYWdlTWFuYWdlckV2ZW50U3Vic2NyaWJlcjsKCi8qKgogKiBMaXN0cywgaW5zdGFsbHMsIGFuZCByZW1vdmVzIFdQLUNMSSBwYWNrYWdlcy4KICoKICogV1AtQ0xJIHBhY2thZ2VzIGFyZSBjb21tdW5pdHktbWFpbnRhaW5lZCBwcm9qZWN0cyBidWlsdCBvbiBXUC1DTEkuIFRoZXkgY2FuCiAqIGNvbnRhaW4gV1AtQ0xJIGNvbW1hbmRzLCBidXQgdGhleSBjYW4gYWxzbyBqdXN0IGV4dGVuZCBXUC1DTEkgaW4gc29tZSB3YXkuCiAqCiAqIExlYXJuIGhvdyB0byBjcmVhdGUgeW91ciBvd24gY29tbWFuZCBmcm9tIHRoZQogKiBbQ29tbWFuZHMgQ29va2Jvb2tdKGh0dHBzOi8vbWFrZS53b3JkcHJlc3Mub3JnL2NsaS9oYW5kYm9vay9jb21tYW5kcy1jb29rYm9vay8pCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIExpc3QgaW5zdGFsbGVkIHBhY2thZ2VzCiAqICAgICAkIHdwIHBhY2thZ2UgbGlzdAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwogKiAgICAgfCBuYW1lICAgICAgICAgICAgICAgICAgfCBkZXNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYXV0aG9ycyB8IHZlcnNpb24gICAgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwogKiAgICAgfCB3cC1jbGkvc2VydmVyLWNvbW1hbmQgfCBTdGFydCBhIGRldmVsb3BtZW50IHNlcnZlciBmb3IgV29yZFByZXNzIHwgICAgICAgICB8IGRldi1tYXN0ZXIgfAogKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBsYXRlc3QgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiB0aGUgcGFja2FnZQogKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgd3AtY2xpL3NlcnZlci1jb21tYW5kCiAqICAgICBJbnN0YWxsaW5nIHBhY2thZ2Ugd3AtY2xpL3NlcnZlci1jb21tYW5kIChkZXYtbWFzdGVyKQogKiAgICAgVXBkYXRpbmcgL2hvbWUvcGVyc29uLy53cC1jbGkvcGFja2FnZXMvY29tcG9zZXIuanNvbiB0byByZXF1aXJlIHRoZSBwYWNrYWdlLi4uCiAqICAgICBVc2luZyBDb21wb3NlciB0byBpbnN0YWxsIHRoZSBwYWNrYWdlLi4uCiAqICAgICAtLS0KICogICAgIExvYWRpbmcgY29tcG9zZXIgcmVwb3NpdG9yaWVzIHdpdGggcGFja2FnZSBpbmZvcm1hdGlvbgogKiAgICAgVXBkYXRpbmcgZGVwZW5kZW5jaWVzCiAqICAgICBSZXNvbHZpbmcgZGVwZW5kZW5jaWVzIHRocm91Z2ggU0FUCiAqICAgICBEZXBlbmRlbmN5IHJlc29sdXRpb24gY29tcGxldGVkIGluIDAuMDA1IHNlY29uZHMKICogICAgIEFuYWx5emVkIDczMiBwYWNrYWdlcyB0byByZXNvbHZlIGRlcGVuZGVuY2llcwogKiAgICAgQW5hbHl6ZWQgMTAzNCBydWxlcyB0byByZXNvbHZlIGRlcGVuZGVuY2llcwogKiAgICAgIC0gSW5zdGFsbGluZyBwYWNrYWdlCiAqICAgICBXcml0aW5nIGxvY2sgZmlsZQogKiAgICAgR2VuZXJhdGluZyBhdXRvbG9hZCBmaWxlcwogKiAgICAgLS0tCiAqICAgICBTdWNjZXNzOiBQYWNrYWdlIGluc3RhbGxlZC4KICoKICogICAgICMgVW5pbnN0YWxsIHBhY2thZ2UKICogICAgICQgd3AgcGFja2FnZSB1bmluc3RhbGwgd3AtY2xpL3NlcnZlci1jb21tYW5kCiAqICAgICBSZW1vdmluZyByZXF1aXJlIHN0YXRlbWVudCBmcm9tIC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzL2NvbXBvc2VyLmpzb24KICogICAgIERlbGV0aW5nIHBhY2thZ2UgZGlyZWN0b3J5IC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzL3ZlbmRvci93cC1jbGkvc2VydmVyLWNvbW1hbmQKICogICAgIFJlZ2VuZXJhdGluZyBDb21wb3NlciBhdXRvbG9hZC4KICogICAgIFN1Y2Nlc3M6IFVuaW5zdGFsbGVkIHBhY2thZ2UuCiAqCiAqIEBwYWNrYWdlIFdQLUNMSQogKgogKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAogKi8KY2xhc3MgUGFja2FnZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCWNvbnN0IFBBQ0tBR0VfSU5ERVhfVVJMID0gJ2h0dHBzOi8vd3AtY2xpLm9yZy9wYWNrYWdlLWluZGV4Lyc7Cgljb25zdCBTU0xfQ0VSVElGSUNBVEUgICA9ICcvcm1jY3VlL3JlcXVlc3RzL2xpYnJhcnkvUmVxdWVzdHMvVHJhbnNwb3J0L2NhY2VydC5wZW0nOwoKCXByaXZhdGUgJHZlcnNpb25fc2VsZWN0b3IgPSBmYWxzZTsKCgkvKioKCSAqIERlZmF1bHQgYXV0aG9yIGRhdGEgdXNlZCB3aGlsZSBjcmVhdGluZyBkZWZhdWx0IFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkYXV0aG9yX2RhdGEgPSBbCgkJJ25hbWUnICA9PiAnV1AtQ0xJJywKCQknZW1haWwnID0+ICdub3JlcGx5QHdwY2xpLm9yZycsCgldOwoKCS8qKgoJICogRGVmYXVsdCByZXBvc2l0b3J5IGRhdGEgdXNlZCB3aGlsZSBjcmVhdGluZyBkZWZhdWx0IFdQLUNMSSBwYWNrYWdlcyBjb21wb3Nlci5qc29uLgoJICogQHZhciBhcnJheQoJICovCglwcml2YXRlICRjb21wb3Nlcl90eXBlX3BhY2thZ2UgPSBbCgkJJ3R5cGUnID0+ICdjb21wb3NlcicsCgkJJ3VybCcgID0+IHNlbGY6OlBBQ0tBR0VfSU5ERVhfVVJMLAoJXTsKCgkvKioKCSAqIEJyb3dzZXMgV1AtQ0xJIHBhY2thZ2VzIGF2YWlsYWJsZSBmb3IgaW5zdGFsbGF0aW9uLgoJICoKCSAqIExpc3RzIHBhY2thZ2VzIGF2YWlsYWJsZSBmb3IgaW5zdGFsbGF0aW9uIGZyb20gdGhlIFtQYWNrYWdlIEluZGV4XShodHRwOi8vd3AtY2xpLm9yZy9wYWNrYWdlLWluZGV4LykuCgkgKiBBbHRob3VnaCB0aGUgcGFja2FnZSBpbmRleCB3aWxsIHJlbWFpbiBpbiBwbGFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZWFzb25zLCBpdCBoYXMgYmVlbgoJICogZGVwcmVjYXRlZCBhbmQgd2lsbCBub3QgYmUgdXBkYXRlZCBmdXJ0aGVyLiBQbGVhc2UgcmVmZXIgdG8gaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS9pZGVhcy9pc3N1ZXMvNTEKCSAqIHRvIHJlYWQgYWJvdXQgaXRzIHBvdGVudGlhbCByZXBsYWNlbWVudC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHBhY2thZ2U6CgkgKgoJICogKiBuYW1lCgkgKiAqIGRlc2NyaXB0aW9uCgkgKiAqIGF1dGhvcnMKCSAqICogdmVyc2lvbgoJICoKCSAqIFRoZXJlIGFyZSBubyBvcHRpb25hbGx5IGF2YWlsYWJsZSBmaWVsZHMuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwYWNrYWdlIGJyb3dzZSAtLWZvcm1hdD15YW1sCgkgKiAgICAgLS0tCgkgKiAgICAgMTB1cC9tdS1taWdyYXRpb246CgkgKiAgICAgICBuYW1lOiAxMHVwL211LW1pZ3JhdGlvbgoJICogICAgICAgZGVzY3JpcHRpb246IEEgc2V0IG9mIFdQLUNMSSBjb21tYW5kcyB0byBzdXBwb3J0IHRoZSBtaWdyYXRpb24gb2Ygc2luZ2xlIFdvcmRQcmVzcyBpbnN0YW5jZXMgdG8gbXVsdGlzaXRlCgkgKiAgICAgICBhdXRob3JzOiBOw61jaG9sYXMgQW5kcsOpCgkgKiAgICAgICB2ZXJzaW9uOiBkZXYtbWFzdGVyLCBkZXYtZGV2ZWxvcAoJICogICAgIGFhZW1ubm9zdHR2L3dwLWNsaS1kb3RlbnYtY29tbWFuZDoKCSAqICAgICAgIG5hbWU6IGFhZW1ubm9zdHR2L3dwLWNsaS1kb3RlbnYtY29tbWFuZAoJICogICAgICAgZGVzY3JpcHRpb246IERvdGVudiBjb21tYW5kcyBmb3IgV1AtQ0xJCgkgKiAgICAgICBhdXRob3JzOiBFdmFuIE1hdHRzb24KCSAqICAgICAgIHZlcnNpb246IHYwLjEsIHYwLjEtYmV0YS4xLCB2MC4yLCBkZXYtbWFzdGVyLCBkZXYtZGV2LCBkZXYtZGV2ZWxvcCwgZGV2LXRlc3RzL2JlaGF0CgkgKiAgICAgYWFlbW5ub3N0dHYvd3AtY2xpLWh0dHAtY29tbWFuZDoKCSAqICAgICAgIG5hbWU6IGFhZW1ubm9zdHR2L3dwLWNsaS1odHRwLWNvbW1hbmQKCSAqICAgICAgIGRlc2NyaXB0aW9uOiBXUC1DTEkgY29tbWFuZCBmb3IgdXNpbmcgdGhlIFdvcmRQcmVzcyBIVFRQIEFQSQoJICogICAgICAgYXV0aG9yczogRXZhbiBNYXR0c29uCgkgKiAgICAgICB2ZXJzaW9uOiBkZXYtbWFzdGVyCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBicm93c2UoICRfLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpOwoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHx8ICd0YWJsZScgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJV1BfQ0xJOjpsaW5lKCBXUF9DTEk6OmNvbG9yaXplKCAnJUNBbHRob3VnaCB0aGUgcGFja2FnZSBpbmRleCB3aWxsIHJlbWFpbiBpbiBwbGFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZWFzb25zLCBpdCBoYXMgYmVlbiBkZXByZWNhdGVkIGFuZCB3aWxsIG5vdCBiZSB1cGRhdGVkIGZ1cnRoZXIuIFBsZWFzZSByZWZlciB0byBodHRwczovL2dpdGh1Yi5jb20vd3AtY2xpL2lkZWFzL2lzc3Vlcy81MSB0byByZWFkIGFib3V0IGl0cyBwb3RlbnRpYWwgcmVwbGFjZW1lbnQuJW4nICkgKTsKCQl9CgkJJHRoaXMtPnNob3dfcGFja2FnZXMoICdicm93c2UnLCAkdGhpcy0+Z2V0X2NvbW11bml0eV9wYWNrYWdlcygpLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogSW5zdGFsbHMgYSBXUC1DTEkgcGFja2FnZS4KCSAqCgkgKiBQYWNrYWdlcyBhcmUgcmVxdWlyZWQgdG8gYmUgYSB2YWxpZCBDb21wb3NlciBwYWNrYWdlLCBhbmQgY2FuIGJlCgkgKiBzcGVjaWZpZWQgYXM6CgkgKgoJICogKiBQYWNrYWdlIG5hbWUgZnJvbSBXUC1DTEkncyBwYWNrYWdlIGluZGV4LgoJICogKiBHaXQgVVJMIGFjY2Vzc2libGUgYnkgdGhlIGN1cnJlbnQgc2hlbGwgdXNlci4KCSAqICogUGF0aCB0byBhIGRpcmVjdG9yeSBvbiB0aGUgbG9jYWwgbWFjaGluZS4KCSAqICogTG9jYWwgb3IgcmVtb3RlIC56aXAgZmlsZS4KCSAqCgkgKiBQYWNrYWdlcyBhcmUgaW5zdGFsbGVkIHRvIGB+Ly53cC1jbGkvcGFja2FnZXMvYCBieSBkZWZhdWx0LiBVc2UgdGhlCgkgKiBgV1BfQ0xJX1BBQ0tBR0VTX0RJUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gcHJvdmlkZSBhIGN1c3RvbSBwYXRoLgoJICoKCSAqIFdoZW4gaW5zdGFsbGluZyBhIGxvY2FsIGRpcmVjdG9yeSwgV1AtQ0xJIHNpbXBseSByZWdpc3RlcnMgYQoJICogcmVmZXJlbmNlIHRvIHRoZSBkaXJlY3RvcnkuIElmIHlvdSBtb3ZlIG9yIGRlbGV0ZSB0aGUgZGlyZWN0b3J5LCBXUC1DTEkncwoJICogcmVmZXJlbmNlIGJyZWFrcy4KCSAqCgkgKiBXaGVuIGluc3RhbGxpbmcgYSAuemlwIGZpbGUsIFdQLUNMSSBleHRyYWN0cyB0aGUgcGFja2FnZSB0bwoJICogYH4vLndwLWNsaS9wYWNrYWdlcy9sb2NhbC88cGFja2FnZS1uYW1lPmAuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxuYW1lfGdpdHxwYXRofHppcD4KCSAqIDogTmFtZSwgZ2l0IFVSTCwgZGlyZWN0b3J5IHBhdGgsIG9yIC56aXAgZmlsZSBmb3IgdGhlIHBhY2thZ2UgdG8gaW5zdGFsbC4KCSAqIE5hbWVzIGNhbiBvcHRpb25hbGx5IGluY2x1ZGUgYSB2ZXJzaW9uIGNvbnN0cmFpbnQKCSAqIChlLmcuIHdwLWNsaS9zZXJ2ZXItY29tbWFuZDpAc3RhYmxlKS4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluc3RhbGwgYSBwYWNrYWdlIGhvc3RlZCBhdCBhIGdpdCBVUkwuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgcnVuY29tbWFuZC9ob29rCgkgKgoJICogICAgICMgSW5zdGFsbCB0aGUgbGF0ZXN0IHN0YWJsZSB2ZXJzaW9uLgoJICogICAgICQgd3AgcGFja2FnZSBpbnN0YWxsIHdwLWNsaS9zZXJ2ZXItY29tbWFuZDpAc3RhYmxlCgkgKgoJICogICAgICMgSW5zdGFsbCBhIHBhY2thZ2UgaG9zdGVkIGF0IGEgR2l0TGFiLmNvbSBVUkwuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgaHR0cHM6Ly9naXRsYWIuY29tL2Zvby93cC1jbGktYmFyLWNvbW1hbmQuZ2l0CgkgKgoJICogICAgICMgSW5zdGFsbCBhIHBhY2thZ2UgaW4gYSAuemlwIGZpbGUuCgkgKiAgICAgJCB3cCBwYWNrYWdlIGluc3RhbGwgZ29vZ2xlLXNpdGVtYXAtZ2VuZXJhdG9yLWNsaS56aXAKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkcGFja2FnZV9uYW1lICkgPSAkYXJnczsKCgkJJGluc2VjdXJlID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCgkJJHRoaXMtPnNldF9jb21wb3Nlcl9hdXRoX2Vudl92YXIoKTsKCQkkZ2l0X3BhY2thZ2UgPSBmYWxzZTsKCQkkZGlyX3BhY2thZ2UgPSBmYWxzZTsKCQkkdmVyc2lvbiAgICAgPSAnZGV2LW1hc3Rlcic7CgkJaWYgKCAkdGhpcy0+aXNfZ2l0X3JlcG9zaXRvcnkoICRwYWNrYWdlX25hbWUgKSApIHsKCQkJJGdpdF9wYWNrYWdlID0gJHBhY2thZ2VfbmFtZTsKCQkJcHJlZ19tYXRjaCggJyMoW146XC9dK1wvW15cL10rKVwuZ2l0IycsICRwYWNrYWdlX25hbWUsICRtYXRjaGVzICk7CgkJCWlmICggISBlbXB0eSggJG1hdGNoZXNbMV0gKSApIHsKCQkJCSRwYWNrYWdlX25hbWUgPSAkdGhpcy0+Y2hlY2tfZ2l0X3BhY2thZ2VfbmFtZSggJG1hdGNoZXNbMV0sICRwYWNrYWdlX25hbWUsICcnLCAkaW5zZWN1cmUgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZG4ndCBwYXJzZSBwYWNrYWdlIG5hbWUgZnJvbSBleHBlY3RlZCBwYXRoICc8bmFtZT4vPHBhY2thZ2U+Jy4iICk7CgkJCX0KCQl9IGVsc2VpZiAoICggZmFsc2UgIT09IHN0cnBvcyggJHBhY2thZ2VfbmFtZSwgJzovLycgKSAmJiBmYWxzZSAhPT0gc3RyaXBvcyggJHBhY2thZ2VfbmFtZSwgJy56aXAnICkgKQoJCQl8fCAoIHBhdGhpbmZvKCAkcGFja2FnZV9uYW1lLCBQQVRISU5GT19FWFRFTlNJT04gKSA9PT0gJ3ppcCcgJiYgaXNfZmlsZSggJHBhY2thZ2VfbmFtZSApICkgKSB7CgkJCS8vIERvd25sb2FkIHRoZSByZW1vdGUgWklQIGZpbGUgdG8gYSB0ZW1wIGRpcmVjdG9yeQoJCQkkdGVtcCA9IGZhbHNlOwoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICRwYWNrYWdlX25hbWUsICc6Ly8nICkgKSB7CgkJCQkkdGVtcCAgICAgPSBVdGlsc1xnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwLWNsaS1wYWNrYWdlXycsIHRydWUgLyptb3JlX2VudHJvcHkqLyApIC4gJy56aXAnOwoJCQkJJG9wdGlvbnMgID0gWwoJCQkJCSd0aW1lb3V0JyAgPT4gNjAwLAoJCQkJCSdmaWxlbmFtZScgPT4gJHRlbXAsCgkJCQkJJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUsCgkJCQldOwoJCQkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHBhY2thZ2VfbmFtZSwgbnVsbCwgW10sICRvcHRpb25zICk7CgkJCQlpZiAoIDIwICE9PSAoaW50KSBzdWJzdHIoICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsIDAsIDIgKSApIHsKCQkJCQlAdW5saW5rKCAkdGVtcCApOyAvLyBAY29kaW5nU3RhbmRhcmRzSWdub3JlTGluZQoJCQkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJDb3VsZG4ndCBkb3dubG9hZCBwYWNrYWdlIGZyb20gJyVzJyAoSFRUUCBjb2RlICVkKS4iLCAkcGFja2FnZV9uYW1lLCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlICkgKTsKCQkJCX0KCQkJCSRwYWNrYWdlX25hbWUgPSAkdGVtcDsKCQkJfQoJCQkkZGlyX3BhY2thZ2UgPSBVdGlsc1xnZXRfdGVtcF9kaXIoKSAuIHVuaXFpZCggJ3dwLWNsaS1wYWNrYWdlXycsIHRydWUgLyptb3JlX2VudHJvcHkqLyApOwoJCQl0cnkgewoJCQkJLy8gRXh0cmFjdCB0aGUgcGFja2FnZSB0byBnZXQgdGhlIHBhY2thZ2UgbmFtZQoJCQkJRXh0cmFjdG9yOjpleHRyYWN0KCAkcGFja2FnZV9uYW1lLCAkZGlyX3BhY2thZ2UgKTsKCQkJCWlmICggJHRlbXAgKSB7CgkJCQkJdW5saW5rKCAkdGVtcCApOwoJCQkJCSR0ZW1wID0gZmFsc2U7CgkJCQl9CgkJCQlsaXN0KCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiApID0gc2VsZjo6Z2V0X3BhY2thZ2VfbmFtZV9hbmRfdmVyc2lvbl9mcm9tX2Rpcl9wYWNrYWdlKCAkZGlyX3BhY2thZ2UgKTsKCQkJCS8vIE1vdmUgdG8gYSBsb2NhdGlvbiBiYXNlZCBvbiB0aGUgcGFja2FnZSBuYW1lCgkJCQkkbG9jYWxfZGlyICAgICAgICAgID0gcnRyaW0oIFdQX0NMSTo6Z2V0X3J1bm5lcigpLT5nZXRfcGFja2FnZXNfZGlyX3BhdGgoKSwgJy8nICkgLiAnL2xvY2FsLyc7CgkJCQkkYWN0dWFsX2Rpcl9wYWNrYWdlID0gJGxvY2FsX2RpciAuIHN0cl9yZXBsYWNlKCAnLycsICctJywgJHBhY2thZ2VfbmFtZSApOwoJCQkJRXh0cmFjdG9yOjpjb3B5X292ZXJ3cml0ZV9maWxlcyggJGRpcl9wYWNrYWdlLCAkYWN0dWFsX2Rpcl9wYWNrYWdlICk7CgkJCQlFeHRyYWN0b3I6OnJtZGlyKCAkZGlyX3BhY2thZ2UgKTsKCQkJCS8vIEJlaG9sZCwgdGhlIGV4dHJhY3RlZCBwYWNrYWdlCgkJCQkkZGlyX3BhY2thZ2UgPSAkYWN0dWFsX2Rpcl9wYWNrYWdlOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJaWYgKCAkdGVtcCApIHsKCQkJCQl1bmxpbmsoICR0ZW1wICk7CgkJCQl9CgkJCQlpZiAoIGZpbGVfZXhpc3RzKCAkZGlyX3BhY2thZ2UgKSApIHsKCQkJCQl0cnkgewoJCQkJCQlFeHRyYWN0b3I6OnJtZGlyKCAkZGlyX3BhY2thZ2UgKTsKCQkJCQl9IGNhdGNoICggRXhjZXB0aW9uICRybWRpcl9lICkgewoJCQkJCQlXUF9DTEk6Ondhcm5pbmcoICRybWRpcl9lLT5nZXRNZXNzYWdlKCkgKTsKCQkJCQl9CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJCX0KCQl9IGVsc2VpZiAoIGlzX2RpciggJHBhY2thZ2VfbmFtZSApICYmIGZpbGVfZXhpc3RzKCAkcGFja2FnZV9uYW1lIC4gJy9jb21wb3Nlci5qc29uJyApICkgewoJCQkkZGlyX3BhY2thZ2UgPSAkcGFja2FnZV9uYW1lOwoJCQlpZiAoICEgVXRpbHNcaXNfcGF0aF9hYnNvbHV0ZSggJGRpcl9wYWNrYWdlICkgKSB7CgkJCQkkZGlyX3BhY2thZ2UgPSBnZXRjd2QoKSAuIERJUkVDVE9SWV9TRVBBUkFUT1IgLiAkZGlyX3BhY2thZ2U7CgkJCX0KCQkJbGlzdCggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24gKSA9IHNlbGY6OmdldF9wYWNrYWdlX25hbWVfYW5kX3ZlcnNpb25fZnJvbV9kaXJfcGFja2FnZSggJGRpcl9wYWNrYWdlICk7CgkJfSBlbHNlIHsKCQkJaWYgKCBmYWxzZSAhPT0gc3RycG9zKCAkcGFja2FnZV9uYW1lLCAnOicgKSApIHsKCQkJCWxpc3QoICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uICkgPSBleHBsb2RlKCAnOicsICRwYWNrYWdlX25hbWUgKTsKCQkJfQoJCQkkcGFja2FnZSA9ICR0aGlzLT5nZXRfcGFja2FnZV9ieV9zaG9ydGVuZWRfaWRlbnRpZmllciggJHBhY2thZ2VfbmFtZSApOwoJCQlpZiAoICEgJHBhY2thZ2UgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBwYWNrYWdlOiBzaG9ydGVuZWQgaWRlbnRpZmllciAnJXMnIG5vdCBmb3VuZC4iLCAkcGFja2FnZV9uYW1lICkgKTsKCQkJfQoJCQlpZiAoIGlzX3N0cmluZyggJHBhY2thZ2UgKSApIHsKCQkJCWlmICggJHRoaXMtPmlzX2dpdF9yZXBvc2l0b3J5KCAkcGFja2FnZSApICkgewoJCQkJCSRnaXRfcGFja2FnZSA9ICRwYWNrYWdlOwoJCQkJCWlmICggJ0BzdGFibGUnID09PSAkdmVyc2lvbiApIHsKCQkJCQkJJHRhZyAgICAgPSAkdGhpcy0+Z2V0X2dpdGh1Yl9sYXRlc3RfcmVsZWFzZV90YWcoICRwYWNrYWdlX25hbWUsICRpbnNlY3VyZSApOwoJCQkJCQkkdmVyc2lvbiA9ICR0aGlzLT5ndWVzc192ZXJzaW9uX2NvbnN0cmFpbnRfZnJvbV90YWcoICR0YWcgKTsKCQkJCQl9CgkJCQkJJHBhY2thZ2VfbmFtZSA9ICR0aGlzLT5jaGVja19naXRodWJfcGFja2FnZV9uYW1lKCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiwgJGluc2VjdXJlICk7CgkJCQl9CgkJCX0gZWxzZWlmICggJHBhY2thZ2VfbmFtZSAhPT0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSApIHsKCQkJCS8vIEJDIHN1cHBvcnQgZm9yIHNwZWNpZnlpbmcgbG93ZXJjYXNlIG5hbWVzIGZvciBtaXhlZC1jYXNlIHBhY2thZ2UgaW5kZXggcGFja2FnZXMgLSBkb24ndCBib3RoZXIgd2FybmluZy4KCQkJCSRwYWNrYWdlX25hbWUgPSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpOwoJCQl9CgkJfQoKCQlpZiAoICR0aGlzLT5pc19jb21wb3Nlcl92MigpICkgewoJCQkkcGFja2FnZV9uYW1lID0gZnVuY3Rpb25fZXhpc3RzKCAnbWJfc3RydG9sb3dlcicgKQoJCQkJPyBtYl9zdHJ0b2xvd2VyKCAkcGFja2FnZV9uYW1lICkKCQkJCTogc3RydG9sb3dlciggJHBhY2thZ2VfbmFtZSApOwoJCX0KCgkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdJbnN0YWxsaW5nIHBhY2thZ2UgJXMgKCVzKScsICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uICkgKTsKCgkJLy8gUmVhZCB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24gYW5kIGRvIHNvbWUgaW5pdGlhbCBlcnJvciBjaGVja2luZy4KCQlsaXN0KCAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwLCAkY29tcG9zZXJfYmFja3VwX2RlY29kZWQgKSA9ICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbl9wYXRoX2JhY2t1cF9kZWNvZGVkKCk7CgoJCS8vIFJldmVydCBvbiBzaHV0ZG93biBpZiBgJHJldmVydGAgaXMgdHJ1ZSAoc2V0IHRvIGZhbHNlIG9uIHN1Y2Nlc3MpLgoJCSRyZXZlcnQgPSB0cnVlOwoJCSR0aGlzLT5yZWdpc3Rlcl9yZXZlcnRfc2h1dGRvd25fZnVuY3Rpb24oICRqc29uX3BhdGgsICRjb21wb3Nlcl9iYWNrdXAsICRyZXZlcnQgKTsKCgkJLy8gQWRkIHRoZSAncmVxdWlyZScgdG8gY29tcG9zZXIuanNvbgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnVXBkYXRpbmcgJXMgdG8gcmVxdWlyZSB0aGUgcGFja2FnZS4uLicsICRqc29uX3BhdGggKSApOwoJCSRqc29uX21hbmlwdWxhdG9yID0gbmV3IEpzb25NYW5pcHVsYXRvciggJGNvbXBvc2VyX2JhY2t1cCApOwoJCSRqc29uX21hbmlwdWxhdG9yLT5hZGRNYWluS2V5KCAnbmFtZScsICd3cC1jbGkvd3AtY2xpJyApOwoJCSRqc29uX21hbmlwdWxhdG9yLT5hZGRNYWluS2V5KCAndmVyc2lvbicsIHNlbGY6OmdldF93cF9jbGlfdmVyc2lvbl9jb21wb3NlcigpICk7CgkJJGpzb25fbWFuaXB1bGF0b3ItPmFkZExpbmsoICdyZXF1aXJlJywgJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24sIGZhbHNlIC8qc29ydFBhY2thZ2VzKi8sIHRydWUgLypjYXNlSW5zZW5zaXRpdmUqLyApOwoJCSRqc29uX21hbmlwdWxhdG9yLT5hZGRDb25maWdTZXR0aW5nKCAnc2VjdXJlLWh0dHAnLCB0cnVlICk7CgoJCSRwYWNrYWdlX2FyZ3MgPSBbXTsKCQlpZiAoICRnaXRfcGFja2FnZSApIHsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdSZWdpc3RlcmluZyAlcyBhcyBhIFZDUyByZXBvc2l0b3J5Li4uJywgJGdpdF9wYWNrYWdlICkgKTsKCQkJJHBhY2thZ2VfYXJncyA9IFsKCQkJCSd0eXBlJyA9PiAndmNzJywKCQkJCSd1cmwnICA9PiAkZ2l0X3BhY2thZ2UsCgkJCV07CgkJCSRqc29uX21hbmlwdWxhdG9yLT5hZGRTdWJOb2RlKAoJCQkJJ3JlcG9zaXRvcmllcycsCgkJCQkkcGFja2FnZV9uYW1lLAoJCQkJJHBhY2thZ2VfYXJncywKCQkJCXRydWUgLypjYXNlSW5zZW5zaXRpdmUqLwoJCQkpOwoJCX0gZWxzZWlmICggJGRpcl9wYWNrYWdlICkgewoJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJ1JlZ2lzdGVyaW5nICVzIGFzIGEgcGF0aCByZXBvc2l0b3J5Li4uJywgJGRpcl9wYWNrYWdlICkgKTsKCQkJJHBhY2thZ2VfYXJncyA9IFsKCQkJCSd0eXBlJyA9PiAncGF0aCcsCgkJCQkndXJsJyAgPT4gJGRpcl9wYWNrYWdlLAoJCQldOwoJCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkU3ViTm9kZSgKCQkJCSdyZXBvc2l0b3JpZXMnLAoJCQkJJHBhY2thZ2VfbmFtZSwKCQkJCSRwYWNrYWdlX2FyZ3MsCgkJCQl0cnVlIC8qY2FzZUluc2Vuc2l0aXZlKi8KCQkJKTsKCQl9CgkJLy8gSWYgdGhlIGNvbXBvc2VyIGZpbGUgZG9lcyBub3QgY29udGFpbiB0aGUgY3VycmVudCBwYWNrYWdlIGluZGV4IHJlcG9zaXRvcnksIHJlZnJlc2ggdGhlIHJlcG9zaXRvcnkgZGVmaW5pdGlvbi4KCQlpZiAoIGVtcHR5KCAkY29tcG9zZXJfYmFja3VwX2RlY29kZWRbJ3JlcG9zaXRvcmllcyddWyd3cC1jbGknXVsndXJsJ10gKSB8fCBzZWxmOjpQQUNLQUdFX0lOREVYX1VSTCAhPT0gJGNvbXBvc2VyX2JhY2t1cF9kZWNvZGVkWydyZXBvc2l0b3JpZXMnXVsnd3AtY2xpJ11bJ3VybCddICkgewoJCQlXUF9DTEk6OmxvZyggJ1VwZGF0aW5nIHBhY2thZ2UgaW5kZXggcmVwb3NpdG9yeSB1cmwuLi4nICk7CgkJCSRwYWNrYWdlX2FyZ3MgPSAkdGhpcy0+Y29tcG9zZXJfdHlwZV9wYWNrYWdlOwoJCQkkanNvbl9tYW5pcHVsYXRvci0+YWRkUmVwb3NpdG9yeSgKCQkJCSd3cC1jbGknLAoJCQkJJHBhY2thZ2VfYXJncwoJCQkpOwoJCX0KCgkJZmlsZV9wdXRfY29udGVudHMoICRqc29uX3BhdGgsICRqc29uX21hbmlwdWxhdG9yLT5nZXRDb250ZW50cygpICk7CgkJJGNvbXBvc2VyID0gJHRoaXMtPmdldF9jb21wb3NlcigpOwoKCQkvLyBTZXQgdXAgdGhlIEV2ZW50U3Vic2NyaWJlcgoJCSRldmVudF9zdWJzY3JpYmVyID0gbmV3IFBhY2thZ2VNYW5hZ2VyRXZlbnRTdWJzY3JpYmVyKCk7CgkJJGNvbXBvc2VyLT5nZXRFdmVudERpc3BhdGNoZXIoKS0+YWRkU3Vic2NyaWJlciggJGV2ZW50X3N1YnNjcmliZXIgKTsKCQkvLyBTZXQgdXAgdGhlIGluc3RhbGxlcgoJCSRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoIG5ldyBDb21wb3NlcklPKCksICRjb21wb3NlciApOwoJCSRpbnN0YWxsLT5zZXRVcGRhdGUoIHRydWUgKTsgLy8gSW5zdGFsbGVyIGNsYXNzIHdpbGwgb25seSBvdmVycmlkZSBjb21wb3Nlci5sb2NrIHdpdGggdGhpcyBmbGFnCgkJJGluc3RhbGwtPnNldFByZWZlclNvdXJjZSggdHJ1ZSApOyAvLyBVc2UgVkNTIHdoZW4gVkNTIGZvciBlYXNpZXIgY29udHJpYnV0aW9ucy4KCgkJLy8gVHJ5IHJ1bm5pbmcgdGhlIGluc3RhbGxlciwgYnV0IHJldmVydCBjb21wb3Nlci5qc29uIGlmIGZhaWxlZAoJCVdQX0NMSTo6bG9nKCAnVXNpbmcgQ29tcG9zZXIgdG8gaW5zdGFsbCB0aGUgcGFja2FnZS4uLicgKTsKCQlXUF9DTEk6OmxvZyggJy0tLScgKTsKCQkkcmVzID0gZmFsc2U7CgkJdHJ5IHsKCQkJJHJlcyA9ICRpbnN0YWxsLT5ydW4oKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgoJCS8vIFRPRE86IFRoZSAtLWluc2VjdXJlIGZsYWcgc2hvdWxkIGNhdXNlIGFub3RoZXIgQ29tcG9zZXIgcnVuIHdpdGggdmVyaWZ5IGRpc2FibGVkLgoKCQlXUF9DTEk6OmxvZyggJy0tLScgKTsKCgkJaWYgKCAwID09PSAkcmVzICkgewoJCQkkcmV2ZXJ0ID0gZmFsc2U7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1BhY2thZ2UgaW5zdGFsbGVkLicgKTsKCQl9IGVsc2UgewoJCQkkcmVzX21zZyA9ICRyZXMgPyAiIChDb21wb3NlciByZXR1cm4gY29kZSB7JHJlc30pIiA6ICcnOyAvLyAkcmVzIG1heSBiZSBudWxsIGFwcGFyZW50bHkuCgkJCVdQX0NMSTo6ZGVidWcoICJjb21wb3Nlci5qc29uIGNvbnRlbnQ6XG4iIC4gZmlsZV9nZXRfY29udGVudHMoICRqc29uX3BhdGggKSwgJ3BhY2thZ2VzJyApOwoJCQlXUF9DTEk6OmVycm9yKCAiUGFja2FnZSBpbnN0YWxsYXRpb24gZmFpbGVkeyRyZXNfbXNnfS4iICk7CgkJfQoJfQoKCS8qKgoJICogTGlzdHMgaW5zdGFsbGVkIFdQLUNMSSBwYWNrYWdlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogIyMgQVZBSUxBQkxFIEZJRUxEUwoJICoKCSAqIFRoZXNlIGZpZWxkcyB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIHBhY2thZ2U6CgkgKgoJICogKiBuYW1lCgkgKiAqIGF1dGhvcnMKCSAqICogdmVyc2lvbgoJICogKiB1cGRhdGUKCSAqICogdXBkYXRlX3ZlcnNpb24KCSAqCgkgKiBUaGVzZSBmaWVsZHMgYXJlIG9wdGlvbmFsbHkgYXZhaWxhYmxlOgoJICoKCSAqICogZGVzY3JpcHRpb24KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBhY2thZ2UgbGlzdAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSsKCSAqICAgICB8IG5hbWUgICAgICAgICAgICAgICAgICB8IGRlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhdXRob3JzIHwgdmVyc2lvbiAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tKwoJICogICAgIHwgd3AtY2xpL3NlcnZlci1jb21tYW5kIHwgU3RhcnQgYSBkZXZlbG9wbWVudCBzZXJ2ZXIgZm9yIFdvcmRQcmVzcyB8ICAgICAgICAgfCBkZXYtbWFzdGVyIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLSstLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdGhpcy0+c2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpOwoJCSR0aGlzLT5zaG93X3BhY2thZ2VzKCAnbGlzdCcsICR0aGlzLT5nZXRfaW5zdGFsbGVkX3BhY2thZ2VzKCksICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBwYXRoIHRvIGFuIGluc3RhbGxlZCBXUC1DTEkgcGFja2FnZSwgb3IgdGhlIHBhY2thZ2UgZGlyZWN0b3J5LgoJICoKCSAqIElmIHlvdSB3YW50IHRvIGNvbnRyaWJ1dGUgdG8gYSBwYWNrYWdlLCB0aGlzIGlzIGEgZ3JlYXQgd2F5IHRvIGp1bXAgdG8gaXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8bmFtZT5dCgkgKiA6IE5hbWUgb2YgdGhlIHBhY2thZ2UgdG8gZ2V0IHRoZSBkaXJlY3RvcnkgZm9yLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHBhY2thZ2UgcGF0aAoJICogICAgICQgd3AgcGFja2FnZSBwYXRoCgkgKiAgICAgL2hvbWUvcGVyc29uLy53cC1jbGkvcGFja2FnZXMvCgkgKgoJICogICAgICMgQ2hhbmdlIGRpcmVjdG9yeSB0byBwYWNrYWdlIHBhdGgKCSAqICAgICAkIGNkICQod3AgcGFja2FnZSBwYXRoKSAmJiBwd2QKCSAqICAgICAvaG9tZS92YWdyYW50Ly53cC1jbGkvcGFja2FnZXMKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGgoICRhcmdzICkgewoJCSRwYWNrYWdlc19kaXIgPSBXUF9DTEk6OmdldF9ydW5uZXIoKS0+Z2V0X3BhY2thZ2VzX2Rpcl9wYXRoKCk7CgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICkgewoJCQkkcGFja2FnZXNfZGlyIC49ICd2ZW5kb3IvJyAuICRhcmdzWzBdOwoJCQlpZiAoICEgaXNfZGlyKCAkcGFja2FnZXNfZGlyICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBwYWNrYWdlIG5hbWUuJyApOwoJCQl9CgkJfQoJCVdQX0NMSTo6bGluZSggJHBhY2thZ2VzX2RpciApOwoJfQoKCS8qKgoJICogVXBkYXRlcyBhbGwgaW5zdGFsbGVkIFdQLUNMSSBwYWNrYWdlcyB0byB0aGVpciBsYXRlc3QgdmVyc2lvbi4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHBhY2thZ2UgdXBkYXRlCgkgKiAgICAgVXNpbmcgQ29tcG9zZXIgdG8gdXBkYXRlIHBhY2thZ2VzLi4uCgkgKiAgICAgLS0tCgkgKiAgICAgTG9hZGluZyBjb21wb3NlciByZXBvc2l0b3JpZXMgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uCgkgKiAgICAgVXBkYXRpbmcgZGVwZW5kZW5jaWVzCgkgKiAgICAgUmVzb2x2aW5nIGRlcGVuZGVuY2llcyB0aHJvdWdoIFNBVAoJICogICAgIERlcGVuZGVuY3kgcmVzb2x1dGlvbiBjb21wbGV0ZWQgaW4gMC4wNzQgc2Vjb25kcwoJICogICAgIEFuYWx5emVkIDEwNjIgcGFja2FnZXMgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMKCSAqICAgICBBbmFseXplZCAyMjM4MyBydWxlcyB0byByZXNvbHZlIGRlcGVuZGVuY2llcwoJICogICAgIFdyaXRpbmcgbG9jayBmaWxlCgkgKiAgICAgR2VuZXJhdGluZyBhdXRvbG9hZCBmaWxlcwoJICogICAgIC0tLQoJICogICAgIFN1Y2Nlc3M6IFBhY2thZ2VzIHVwZGF0ZWQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoKSB7CgkJJHRoaXMtPnNldF9jb21wb3Nlcl9hdXRoX2Vudl92YXIoKTsKCQkkY29tcG9zZXIgPSAkdGhpcy0+Z2V0X2NvbXBvc2VyKCk7CgoJCS8vIFNldCB1cCB0aGUgRXZlbnRTdWJzY3JpYmVyCgkJJGV2ZW50X3N1YnNjcmliZXIgPSBuZXcgUGFja2FnZU1hbmFnZXJFdmVudFN1YnNjcmliZXIoKTsKCQkkY29tcG9zZXItPmdldEV2ZW50RGlzcGF0Y2hlcigpLT5hZGRTdWJzY3JpYmVyKCAkZXZlbnRfc3Vic2NyaWJlciApOwoKCQkvLyBTZXQgdXAgdGhlIGluc3RhbGxlcgoJCSRpbnN0YWxsID0gSW5zdGFsbGVyOjpjcmVhdGUoIG5ldyBDb21wb3NlcklPKCksICRjb21wb3NlciApOwoJCSRpbnN0YWxsLT5zZXRVcGRhdGUoIHRydWUgKTsgLy8gSW5zdGFsbGVyIGNsYXNzIHdpbGwgb25seSBvdmVycmlkZSBjb21wb3Nlci5sb2NrIHdpdGggdGhpcyBmbGFnCgkJJGluc3RhbGwtPnNldFByZWZlclNvdXJjZSggdHJ1ZSApOyAvLyBVc2UgVkNTIHdoZW4gVkNTIGZvciBlYXNpZXIgY29udHJpYnV0aW9ucy4KCQlXUF9DTEk6OmxvZyggJ1VzaW5nIENvbXBvc2VyIHRvIHVwZGF0ZSBwYWNrYWdlcy4uLicgKTsKCQlXUF9DTEk6OmxvZyggJy0tLScgKTsKCQkkcmVzID0gZmFsc2U7CgkJdHJ5IHsKCQkJJHJlcyA9ICRpbnN0YWxsLT5ydW4oKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQl9CgkJV1BfQ0xJOjpsb2coICctLS0nICk7CgoJCS8vIFRPRE86IFRoZSAtLWluc2VjdXJlICh0byBiZSBhZGRlZCBoZXJlKSBmbGFnIHNob3VsZCBjYXVzZSBhbm90aGVyIENvbXBvc2VyIHJ1biB3aXRoIHZlcmlmeSBkaXNhYmxlZC4KCgkJaWYgKCAwID09PSAkcmVzICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdQYWNrYWdlcyB1cGRhdGVkLicgKTsKCQl9IGVsc2UgewoJCQkkcmVzX21zZyA9ICRyZXMgPyAiIChDb21wb3NlciByZXR1cm4gY29kZSB7JHJlc30pIiA6ICcnOyAvLyAkcmVzIG1heSBiZSBudWxsIGFwcGFyZW50bHkuCgkJCVdQX0NMSTo6ZXJyb3IoICJGYWlsZWQgdG8gdXBkYXRlIHBhY2thZ2VzeyRyZXNfbXNnfS4iICk7CgkJfQoJfQoKCS8qKgoJICogVW5pbnN0YWxscyBhIFdQLUNMSSBwYWNrYWdlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bmFtZT4KCSAqIDogTmFtZSBvZiB0aGUgcGFja2FnZSB0byB1bmluc3RhbGwuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBwYWNrYWdlIHVuaW5zdGFsbCB3cC1jbGkvc2VydmVyLWNvbW1hbmQKCSAqICAgICBSZW1vdmluZyByZXF1aXJlIHN0YXRlbWVudCBmcm9tIC9ob21lL3BlcnNvbi8ud3AtY2xpL3BhY2thZ2VzL2NvbXBvc2VyLmpzb24KCSAqICAgICBEZWxldGluZyBwYWNrYWdlIGRpcmVjdG9yeSAvaG9tZS9wZXJzb24vLndwLWNsaS9wYWNrYWdlcy92ZW5kb3Ivd3AtY2xpL3NlcnZlci1jb21tYW5kCgkgKiAgICAgUmVnZW5lcmF0aW5nIENvbXBvc2VyIGF1dG9sb2FkLgoJICogICAgIFN1Y2Nlc3M6IFVuaW5zdGFsbGVkIHBhY2thZ2UuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1bmluc3RhbGwoICRhcmdzICkgewoJCWxpc3QoICRwYWNrYWdlX25hbWUgKSA9ICRhcmdzOwoKCQkkdGhpcy0+c2V0X2NvbXBvc2VyX2F1dGhfZW52X3ZhcigpOwoJCSRwYWNrYWdlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfcGFja2FnZV9ieV9uYW1lKCAkcGFja2FnZV9uYW1lICk7CgkJaWYgKCBmYWxzZSA9PT0gJHBhY2thZ2UgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQYWNrYWdlIG5vdCBpbnN0YWxsZWQuJyApOwoJCX0KCQkkcGFja2FnZV9uYW1lID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsgLy8gTWFrZSBzdXJlIHBhY2thZ2UgbmFtZSBpcyB3aGF0J3MgaW4gY29tcG9zZXIuanNvbi4KCgkJLy8gUmVhZCB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24gYW5kIGRvIHNvbWUgaW5pdGlhbCBlcnJvciBjaGVja2luZy4KCQlsaXN0KCAkanNvbl9wYXRoLCAkY29tcG9zZXJfYmFja3VwLCAkY29tcG9zZXJfYmFja3VwX2RlY29kZWQgKSA9ICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbl9wYXRoX2JhY2t1cF9kZWNvZGVkKCk7CgoJCS8vIFJldmVydCBvbiBzaHV0ZG93biBpZiBgJHJldmVydGAgaXMgdHJ1ZSAoc2V0IHRvIGZhbHNlIG9uIHN1Y2Nlc3MpLgoJCSRyZXZlcnQgPSB0cnVlOwoJCSR0aGlzLT5yZWdpc3Rlcl9yZXZlcnRfc2h1dGRvd25fZnVuY3Rpb24oICRqc29uX3BhdGgsICRjb21wb3Nlcl9iYWNrdXAsICRyZXZlcnQgKTsKCgkJLy8gUmVtb3ZlIHRoZSAncmVxdWlyZScgZnJvbSBjb21wb3Nlci5qc29uLgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnUmVtb3ZpbmcgcmVxdWlyZSBzdGF0ZW1lbnQgZnJvbSAlcycsICRqc29uX3BhdGggKSApOwoJCSRtYW5pcHVsYXRvciA9IG5ldyBKc29uTWFuaXB1bGF0b3IoICRjb21wb3Nlcl9iYWNrdXAgKTsKCQkkbWFuaXB1bGF0b3ItPnJlbW92ZVN1Yk5vZGUoICdyZXF1aXJlJywgJHBhY2thZ2VfbmFtZSwgdHJ1ZSAvKmNhc2VJbnNlbnNpdGl2ZSovICk7CgoJCS8vIFJlbW92ZSB0aGUgJ3JlcG9zaXRvcnknIGRldGFpbHMgZnJvbSBjb21wb3Nlci5qc29uLgoJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnUmVtb3ZpbmcgcmVwb3NpdG9yeSBkZXRhaWxzIGZyb20gJXMnLCAkanNvbl9wYXRoICkgKTsKCQkkbWFuaXB1bGF0b3ItPnJlbW92ZVN1Yk5vZGUoICdyZXBvc2l0b3JpZXMnLCAkcGFja2FnZV9uYW1lLCB0cnVlIC8qY2FzZUluc2Vuc2l0aXZlKi8gKTsKCgkJZmlsZV9wdXRfY29udGVudHMoICRqc29uX3BhdGgsICRtYW5pcHVsYXRvci0+Z2V0Q29udGVudHMoKSApOwoJCSRjb21wb3NlciA9ICR0aGlzLT5nZXRfY29tcG9zZXIoKTsKCgkJLy8gU2V0IHVwIHRoZSBpbnN0YWxsZXIuCgkJJGluc3RhbGwgPSBJbnN0YWxsZXI6OmNyZWF0ZSggbmV3IE51bGxJTygpLCAkY29tcG9zZXIgKTsKCQkkaW5zdGFsbC0+c2V0VXBkYXRlKCB0cnVlICk7IC8vIEluc3RhbGxlciBjbGFzcyB3aWxsIG9ubHkgb3ZlcnJpZGUgY29tcG9zZXIubG9jayB3aXRoIHRoaXMgZmxhZwoJCSRpbnN0YWxsLT5zZXRQcmVmZXJTb3VyY2UoIHRydWUgKTsgLy8gVXNlIFZDUyB3aGVuIFZDUyBmb3IgZWFzaWVyIGNvbnRyaWJ1dGlvbnMuCgoJCVdQX0NMSTo6bG9nKCAnUmVtb3ZpbmcgcGFja2FnZSBkaXJlY3RvcmllcyBhbmQgcmVnZW5lcmF0aW5nIGF1dG9sb2FkZXIuLi4nICk7CgkJJHJlcyA9IGZhbHNlOwoJCXRyeSB7CgkJCSRyZXMgPSAkaW5zdGFsbC0+cnVuKCk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQlpZiAoIDAgPT09ICRyZXMgKSB7CgkJCSRyZXZlcnQgPSBmYWxzZTsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnVW5pbnN0YWxsZWQgcGFja2FnZS4nICk7CgkJfSBlbHNlIHsKCQkJJHJlc19tc2cgPSAkcmVzID8gIiAoQ29tcG9zZXIgcmV0dXJuIGNvZGUgeyRyZXN9KSIgOiAnJzsgLy8gJHJlcyBtYXkgYmUgbnVsbCBhcHBhcmVudGx5LgoJCQlXUF9DTEk6OmVycm9yKCAiUGFja2FnZSByZW1vdmFsIGZhaWxlZHskcmVzX21zZ30uIiApOwoJCX0KCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIGEgcGFja2FnZSBpcyBhIFdQLUNMSSBjb21tdW5pdHkgcGFja2FnZSBiYXNlZAoJICogb24gbWVtYmVyc2hpcCBpbiBvdXIgcGFja2FnZSBpbmRleC4KCSAqCgkgKiBAcGFyYW0gb2JqZWN0ICAgICAgJHBhY2thZ2UgICAgIEEgcGFja2FnZSBvYmplY3QKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX2NvbW11bml0eV9wYWNrYWdlKCAkcGFja2FnZSApIHsKCQlyZXR1cm4gJHRoaXMtPnBhY2thZ2VfaW5kZXgoKS0+aGFzUGFja2FnZSggJHBhY2thZ2UgKTsKCX0KCgkvKioKCSAqIEdldHMgYSBDb21wb3NlciBpbnN0YW5jZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tcG9zZXIoKSB7CgkJJHRoaXMtPmF2b2lkX2NvbXBvc2VyX2NhX2J1bmRsZSgpOwoJCXRyeSB7CgkJCSRjb21wb3Nlcl9wYXRoID0gJHRoaXMtPmdldF9jb21wb3Nlcl9qc29uX3BhdGgoKTsKCgkJCS8vIENvbXBvc2VyJ3MgYXV0by1sb2FkIGdlbmVyYXRpbmcgY29kZSBtYWtlcyBzb21lIGFzc3VtcHRpb25zIGFib3V0IHdoZXJlCgkJCS8vIHRoZSAndmVuZG9yLWRpcicgaXMsIGFuZCB3aGVyZSBDb21wb3NlciBpcyBydW5uaW5nIGZyb20uCgkJCS8vIEJlc3QgdG8ganVzdCBwcmV0ZW5kIHdlJ3JlIGluc3RhbGxpbmcgYSBwYWNrYWdlIGZyb20gfi8ud3AtY2xpIG9yIHNpbWlsYXIKCQkJY2hkaXIoIHBhdGhpbmZvKCAkY29tcG9zZXJfcGF0aCwgUEFUSElORk9fRElSTkFNRSApICk7CgoJCQkvLyBQcmV2ZW50IERhdGVUaW1lIGVycm9yL3dhcm5pbmcgd2hlbiBubyB0aW1lem9uZSBzZXQuCgkJCS8vIE5vdGU6IFRoZSBwYWNrYWdlIGlzIGxvYWRlZCBiZWZvcmUgV29yZFByZXNzIGxvYWQsIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkb24ndCBoYXZlIHNldCB0aW1lIGluIHBocC5pbmkuCgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuRGF0ZVRpbWUuUmVzdHJpY3RlZEZ1bmN0aW9ucy50aW1lem9uZV9jaGFuZ2VfZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCxXb3JkUHJlc3MuUEhQLk5vU2lsZW5jZWRFcnJvcnMuRGlzY291cmFnZWQKCQkJZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCggQGRhdGVfZGVmYXVsdF90aW1lem9uZV9nZXQoKSApOwoKCQkJJGNvbXBvc2VyID0gRmFjdG9yeTo6Y3JlYXRlKCBuZXcgTnVsbElPKCksICRjb21wb3Nlcl9wYXRoICk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggJ0ZhaWxlZCB0byBnZXQgY29tcG9zZXIgaW5zdGFuY2U6ICVzJywgJGUtPmdldE1lc3NhZ2UoKSApICk7CgkJfQoJCXJldHVybiAkY29tcG9zZXI7Cgl9CgoJLyoqCgkgKiBHZXRzIGFsbCBvZiB0aGUgY29tbXVuaXR5IHBhY2thZ2VzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tbXVuaXR5X3BhY2thZ2VzKCkgewoJCXN0YXRpYyAkY29tbXVuaXR5X3BhY2thZ2VzOwoKCQlpZiAoIG51bGwgPT09ICRjb21tdW5pdHlfcGFja2FnZXMgKSB7CgkJCSR0aGlzLT5hdm9pZF9jb21wb3Nlcl9jYV9idW5kbGUoKTsKCQkJdHJ5IHsKCQkJCSRjb21tdW5pdHlfcGFja2FnZXMgPSAkdGhpcy0+cGFja2FnZV9pbmRleCgpLT5nZXRQYWNrYWdlcygpOwoJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJGNvbW11bml0eV9wYWNrYWdlczsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHBhY2thZ2UgaW5kZXggaW5zdGFuY2UKCSAqCgkgKiBXZSBuZWVkIHRvIGNvbnN0cnVjdCB0aGUgaW5zdGFuY2UgbWFudWFsbHksIGJlY2F1c2UgdGhlcmUncyBubyB3YXkgdG8gc2VsZWN0CgkgKiBhIHBhcnRpY3VsYXIgaW5zdGFuY2UgdXNpbmcgJGNvbXBvc2VyLT5nZXRSZXBvc2l0b3J5TWFuYWdlcigpCgkgKgoJICogQHJldHVybiBDb21wb3NlclJlcG9zaXRvcnkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBwYWNrYWdlX2luZGV4KCkgewoJCXN0YXRpYyAkcGFja2FnZV9pbmRleDsKCgkJaWYgKCAhICRwYWNrYWdlX2luZGV4ICkgewoJCQkkY29uZmlnX2FyZ3MgPSBbCgkJCQknY29uZmlnJyA9PiBbCgkJCQkJJ3NlY3VyZS1odHRwJyA9PiB0cnVlLAoJCQkJCSdob21lJyAgICAgICAgPT4gZGlybmFtZSggJHRoaXMtPmdldF9jb21wb3Nlcl9qc29uX3BhdGgoKSApLAoJCQkJXSwKCQkJXTsKCQkJJGNvbmZpZyAgICAgID0gbmV3IENvbmZpZygpOwoJCQkkY29uZmlnLT5tZXJnZSggJGNvbmZpZ19hcmdzICk7CgkJCSRjb25maWctPnNldENvbmZpZ1NvdXJjZSggbmV3IEpzb25Db25maWdTb3VyY2UoICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbigpICkgKTsKCgkJCSRpbyA9IG5ldyBOdWxsSU8oKTsKCQkJdHJ5IHsKCQkJCWlmICggJHRoaXMtPmlzX2NvbXBvc2VyX3YyKCkgKSB7CgkJCQkJJGh0dHBfZG93bmxvYWRlciA9IG5ldyBIdHRwRG93bmxvYWRlciggJGlvLCAkY29uZmlnICk7CgkJCQkJJHBhY2thZ2VfaW5kZXggICA9IG5ldyBDb21wb3NlclJlcG9zaXRvcnkoIFsgJ3VybCcgPT4gc2VsZjo6UEFDS0FHRV9JTkRFWF9VUkwgXSwgJGlvLCAkY29uZmlnLCAkaHR0cF9kb3dubG9hZGVyICk7CgkJCQl9IGVsc2UgewoJCQkJCSRwYWNrYWdlX2luZGV4ID0gbmV3IENvbXBvc2VyUmVwb3NpdG9yeSggWyAndXJsJyA9PiBzZWxmOjpQQUNLQUdFX0lOREVYX1VSTCBdLCAkaW8sICRjb25maWcgKTsKCQkJCX0KCQkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRwYWNrYWdlX2luZGV4OwoJfQoKCS8qKgoJICogRGlzcGxheXMgYSBzZXQgb2YgcGFja2FnZXMKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CgkgKiBAcGFyYW0gYXJyYXkKCSAqIEBwYXJhbSBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIHNob3dfcGFja2FnZXMoICRjb250ZXh0LCAkcGFja2FnZXMsICRhc3NvY19hcmdzICkgewoJCWlmICggJ2xpc3QnID09PSAkY29udGV4dCApIHsKCQkJJGRlZmF1bHRfZmllbGRzID0gWwoJCQkJJ25hbWUnLAoJCQkJJ2F1dGhvcnMnLAoJCQkJJ3ZlcnNpb24nLAoJCQkJJ3VwZGF0ZScsCgkJCQkndXBkYXRlX3ZlcnNpb24nLAoJCQldOwoJCX0gZWxzZWlmICggJ2Jyb3dzZScgPT09ICRjb250ZXh0ICkgewoJCQkkZGVmYXVsdF9maWVsZHMgPSBbCgkJCQknbmFtZScsCgkJCQknZGVzY3JpcHRpb24nLAoJCQkJJ2F1dGhvcnMnLAoJCQkJJ3ZlcnNpb24nLAoJCQldOwoJCX0KCQkkZGVmYXVsdHMgICA9IFsKCQkJJ2ZpZWxkcycgPT4gaW1wbG9kZSggJywnLCAkZGVmYXVsdF9maWVsZHMgKSwKCQkJJ2Zvcm1hdCcgPT4gJ3RhYmxlJywKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJJGNvbXBvc2VyID0gJHRoaXMtPmdldF9jb21wb3NlcigpOwoJCSRsaXN0ICAgICA9IFtdOwoJCWZvcmVhY2ggKCAkcGFja2FnZXMgYXMgJHBhY2thZ2UgKSB7CgkJCSRuYW1lID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsKCQkJaWYgKCBpc3NldCggJGxpc3RbICRuYW1lIF0gKSApIHsKCQkJCSRsaXN0WyAkbmFtZSBdWyd2ZXJzaW9uJ11bXSA9ICRwYWNrYWdlLT5nZXRQcmV0dHlWZXJzaW9uKCk7CgkJCX0gZWxzZSB7CgkJCQkkcGFja2FnZV9vdXRwdXQgICAgICAgICAgICAgICAgPSBbXTsKCQkJCSRwYWNrYWdlX291dHB1dFsnbmFtZSddICAgICAgICA9ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCk7CgkJCQkkcGFja2FnZV9vdXRwdXRbJ2Rlc2NyaXB0aW9uJ10gPSAkcGFja2FnZS0+Z2V0RGVzY3JpcHRpb24oKTsKCQkJCSRwYWNrYWdlX291dHB1dFsnYXV0aG9ycyddICAgICA9IGltcGxvZGUoICcsICcsIGFycmF5X2NvbHVtbiggKGFycmF5KSAkcGFja2FnZS0+Z2V0QXV0aG9ycygpLCAnbmFtZScgKSApOwoJCQkJJHBhY2thZ2Vfb3V0cHV0Wyd2ZXJzaW9uJ10gICAgID0gWyAkcGFja2FnZS0+Z2V0UHJldHR5VmVyc2lvbigpIF07CgkJCQkkdXBkYXRlICAgICAgICAgICAgICAgICAgICAgICAgPSAnbm9uZSc7CgkJCQkkdXBkYXRlX3ZlcnNpb24gICAgICAgICAgICAgICAgPSAnJzsKCQkJCWlmICggJ2xpc3QnID09PSAkY29udGV4dCApIHsKCQkJCQl0cnkgewoJCQkJCQkkbGF0ZXN0ID0gJHRoaXMtPmZpbmRfbGF0ZXN0X3BhY2thZ2UoICRwYWNrYWdlLCAkY29tcG9zZXIsIG51bGwgKTsKCQkJCQkJaWYgKCAkbGF0ZXN0ICYmICRsYXRlc3QtPmdldEZ1bGxQcmV0dHlWZXJzaW9uKCkgIT09ICRwYWNrYWdlLT5nZXRGdWxsUHJldHR5VmVyc2lvbigpICkgewoJCQkJCQkJJHVwZGF0ZSAgICAgICAgID0gJ2F2YWlsYWJsZSc7CgkJCQkJCQkkdXBkYXRlX3ZlcnNpb24gPSAkbGF0ZXN0LT5nZXRQcmV0dHlWZXJzaW9uKCk7CgkJCQkJCX0KCQkJCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQkJCQlXUF9DTEk6Ondhcm5pbmcoICRlLT5nZXRNZXNzYWdlKCkgKTsKCQkJCQkJJHVwZGF0ZSAgICAgICAgID0gJ2Vycm9yJzsKCQkJCQkJJHVwZGF0ZV92ZXJzaW9uID0gJHVwZGF0ZTsKCQkJCQl9CgkJCQl9CgkJCQkkcGFja2FnZV9vdXRwdXRbJ3VwZGF0ZSddICAgICAgICAgPSAkdXBkYXRlOwoJCQkJJHBhY2thZ2Vfb3V0cHV0Wyd1cGRhdGVfdmVyc2lvbiddID0gJHVwZGF0ZV92ZXJzaW9uOwoJCQkJJHBhY2thZ2Vfb3V0cHV0WydwcmV0dHlfbmFtZSddICAgID0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKTsgLy8gRGVwcmVjYXRlZCBidXQga2VwdCBmb3IgQkMgd2l0aCBwYWNrYWdlLWNvbW1hbmQgMS4wLjguCgkJCQkkbGlzdFsgJHBhY2thZ2Vfb3V0cHV0WyduYW1lJ10gXSAgPSAkcGFja2FnZV9vdXRwdXQ7CgkJCX0KCQl9CgoJCSRsaXN0ID0gYXJyYXlfbWFwKAoJCQlmdW5jdGlvbiggJHBhY2thZ2UgKSB7CgkJCQkkcGFja2FnZVsndmVyc2lvbiddID0gaW1wbG9kZSggJywgJywgJHBhY2thZ2VbJ3ZlcnNpb24nXSApOwoJCQkJcmV0dXJuICRwYWNrYWdlOwoJCQl9LAoJCQkkbGlzdAoJCSk7CgoJCWtzb3J0KCAkbGlzdCApOwoJCWlmICggJ2lkcycgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJJGxpc3QgPSBhcnJheV9rZXlzKCAkbGlzdCApOwoJCX0KCQlVdGlsc1xmb3JtYXRfaXRlbXMoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgJGxpc3QsICRhc3NvY19hcmdzWydmaWVsZHMnXSApOwoJfQoKCS8qKgoJICogR2V0cyBhIHBhY2thZ2UgYnkgaXRzIHNob3J0ZW5lZCBpZGVudGlmaWVyLgoJICoKCSAqIEEgc2hvcnRlbmVkIGlkZW50aWZpZXIgaGFzIHRoZSBmb3JtIGA8dmVuZG9yPi88cGFja2FnZT5gLgoJICoKCSAqIFRoaXMgbWV0aG9kIGZpcnN0IGNoZWNrcyB0aGUgZGVwcmVjYXRlZCBwYWNrYWdlIGluZGV4LCBmb3IgQkMgcmVhc29ucywKCSAqIGFuZCB0aGVuIGZhbGxzIGJhY2sgdG8gdGhlIGNvcnJlc3BvbmRpbmcgR2l0SHViIFVSTC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlX25hbWUgTmFtZSBvZiB0aGUgcGFja2FnZSB0byBnZXQuCgkgKiBAcGFyYW0gYm9vbCAgICRpbnNlY3VyZSBXaGV0aGVyIHRvIGluc2VjdXJlbHkgcmV0cnkgZG93bmxvYWRzIHRoYXQgZmFpbGVkIFRMUyBoYW5kc2hha2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3BhY2thZ2VfYnlfc2hvcnRlbmVkX2lkZW50aWZpZXIoICRwYWNrYWdlX25hbWUsICRpbnNlY3VyZSA9IGZhbHNlICkgewoJCS8vIENoZWNrIHRoZSBwYWNrYWdlIGluZGV4IGZpcnN0LCBzbyB3ZSBkb24ndCBicmVhayBleGlzdGluZyBiZWhhdmlvci4KCQkkbGNfcGFja2FnZV9uYW1lID0gc3RydG9sb3dlciggJHBhY2thZ2VfbmFtZSApOyAvLyBGb3IgQkMgY2hlY2suCgkJZm9yZWFjaCAoICR0aGlzLT5nZXRfY29tbXVuaXR5X3BhY2thZ2VzKCkgYXMgJHBhY2thZ2UgKSB7CgkJCWlmICggJHBhY2thZ2VfbmFtZSA9PT0gJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSApIHsKCQkJCXJldHVybiAkcGFja2FnZTsKCQkJfQoJCQkvLyBGb3IgQkMgYWxsb3cgZ2V0dGluZyBieSBsb3dlcmNhc2UgbmFtZS4KCQkJaWYgKCAkbGNfcGFja2FnZV9uYW1lID09PSAkcGFja2FnZS0+Z2V0TmFtZSgpICkgewoJCQkJcmV0dXJuICRwYWNrYWdlOwoJCQl9CgkJfQoKCQkkb3B0aW9ucyA9IFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXTsKCgkJLy8gQ2hlY2sgaWYgdGhlIHBhY2thZ2UgZXhpc3RzIG9uIFBhY2thZ2lzdC4KCQkkdXJsICAgICAgPSAiaHR0cHM6Ly9yZXBvLnBhY2thZ2lzdC5vcmcvcC97JHBhY2thZ2VfbmFtZX0uanNvbiI7CgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHVybCwgbnVsbCwgW10sICRvcHRpb25zICk7CgkJaWYgKCAyMCA9PT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCXJldHVybiAkcGFja2FnZV9uYW1lOwoJCX0KCgkJLy8gRmFsbCBiYWNrIHRvIEdpdEh1YiBVUkwgaWYgd2UgaGFkIG5vIG1hdGNoIHlldC4KCQkkdXJsICAgICAgICAgID0gImh0dHBzOi8vZ2l0aHViLmNvbS97JHBhY2thZ2VfbmFtZX0uZ2l0IjsKCQkkZ2l0aHViX3Rva2VuID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOyAvLyBVc2UgR0lUSFVCX1RPS0VOIGlmIGF2YWlsYWJsZSB0byBhdm9pZCBhdXRob3JpemF0aW9uIGZhaWx1cmVzIG9yIHJhdGUtbGltaXRpbmcuCgkJJGhlYWRlcnMgICAgICA9ICRnaXRodWJfdG9rZW4gPyBbICdBdXRob3JpemF0aW9uJyA9PiAndG9rZW4gJyAuICRnaXRodWJfdG9rZW4gXSA6IFtdOwoJCSRyZXNwb25zZSAgICAgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkdXJsLCBudWxsIC8qZGF0YSovLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCQlpZiAoIDIwID09PSAoaW50KSBzdWJzdHIoICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsIDAsIDIgKSApIHsKCQkJcmV0dXJuICR1cmw7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBpbnN0YWxsZWQgY29tbXVuaXR5IHBhY2thZ2VzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9pbnN0YWxsZWRfcGFja2FnZXMoKSB7CgkJJGNvbXBvc2VyID0gJHRoaXMtPmdldF9jb21wb3NlcigpOwoKCQkkcmVwbyAgICAgICAgICAgICAgICAgICA9ICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0TG9jYWxSZXBvc2l0b3J5KCk7CgkJJGV4aXN0aW5nICAgICAgICAgICAgICAgPSBqc29uX2RlY29kZSggZmlsZV9nZXRfY29udGVudHMoICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbl9wYXRoKCkgKSwgdHJ1ZSApOwoJCSRpbnN0YWxsZWRfcGFja2FnZV9rZXlzID0gISBlbXB0eSggJGV4aXN0aW5nWydyZXF1aXJlJ10gKSA/IGFycmF5X2tleXMoICRleGlzdGluZ1sncmVxdWlyZSddICkgOiBbXTsKCQlpZiAoIGVtcHR5KCAkaW5zdGFsbGVkX3BhY2thZ2Vfa2V5cyApICkgewoJCQlyZXR1cm4gW107CgkJfQoJCS8vIEZvciB1c2UgYnkgbGVnYWN5IGluY29ycmVjdCBuYW1lIGNoZWNrLgoJCSRsY19pbnN0YWxsZWRfcGFja2FnZV9rZXlzID0gYXJyYXlfbWFwKCAnc3RydG9sb3dlcicsICRpbnN0YWxsZWRfcGFja2FnZV9rZXlzICk7CgkJJGluc3RhbGxlZF9wYWNrYWdlcyAgICAgICAgPSBbXTsKCQlmb3JlYWNoICggJHJlcG8tPmdldENhbm9uaWNhbFBhY2thZ2VzKCkgYXMgJHBhY2thZ2UgKSB7CgkJCSRpZHggPSBhcnJheV9zZWFyY2goICRwYWNrYWdlLT5nZXROYW1lKCksICRsY19pbnN0YWxsZWRfcGFja2FnZV9rZXlzLCB0cnVlICk7CgkJCS8vIFVzZSBwcmV0dHkgbmFtZSBhcyBpdCdzIGNhc2Ugc2Vuc2l0aXZlIGFuZCB3aGF0J3MgaW4gY29tcG9zZXIuanNvbiAob3IgYXQgbGVhc3Qgc2hvdWxkIGJlKS4KCQkJaWYgKCBpbl9hcnJheSggJHBhY2thZ2UtPmdldFByZXR0eU5hbWUoKSwgJGluc3RhbGxlZF9wYWNrYWdlX2tleXMsIHRydWUgKSApIHsKCQkJCSRpbnN0YWxsZWRfcGFja2FnZXNbXSA9ICRwYWNrYWdlOwoJCQl9IGVsc2VpZiAoIGZhbHNlICE9PSAkaWR4ICkgeyAvLyBMZWdhY3kgaW5jb3JyZWN0IG5hbWUgY2hlY2suCgkJCQlpZiAoICEgJHRoaXMtPmlzX2NvbXBvc2VyX3YyKCkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiRm91bmQgcGFja2FnZSAnJXMnIG1pc25hbWVkICclcycgaW4gJyVzJy4iLCAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpLCAkaW5zdGFsbGVkX3BhY2thZ2Vfa2V5c1sgJGlkeCBdLCAkdGhpcy0+Z2V0X2NvbXBvc2VyX2pzb25fcGF0aCgpICkgKTsKCQkJCX0KCQkJCSRpbnN0YWxsZWRfcGFja2FnZXNbXSA9ICRwYWNrYWdlOwoJCQl9CgkJfQoJCXJldHVybiAkaW5zdGFsbGVkX3BhY2thZ2VzOwoJfQoKCS8qKgoJICogR2V0cyBhbiBpbnN0YWxsZWQgcGFja2FnZSBieSBpdHMgbmFtZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfaW5zdGFsbGVkX3BhY2thZ2VfYnlfbmFtZSggJHBhY2thZ2VfbmFtZSApIHsKCQlmb3JlYWNoICggJHRoaXMtPmdldF9pbnN0YWxsZWRfcGFja2FnZXMoKSBhcyAkcGFja2FnZSApIHsKCQkJaWYgKCAkcGFja2FnZV9uYW1lID09PSAkcGFja2FnZS0+Z2V0UHJldHR5TmFtZSgpICkgewoJCQkJcmV0dXJuICRwYWNrYWdlOwoJCQl9CgkJCS8vIEFsc28gY2hlY2sgbm9uLXByZXR0eSAobG93ZXJjYXNlKSBuYW1lIGluIGNhc2Ugb2YgbGVnYWN5IGluY29ycmVjdCBuYW1lLgoJCQlpZiAoICRwYWNrYWdlX25hbWUgPT09ICRwYWNrYWdlLT5nZXROYW1lKCkgKSB7CgkJCQlyZXR1cm4gJHBhY2thZ2U7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIHRoZSBwYWNrYWdlIG5hbWUgcHJvdmlkZWQgaXMgYWxyZWFkeSBpbnN0YWxsZWQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaXNfcGFja2FnZV9pbnN0YWxsZWQoICRwYWNrYWdlX25hbWUgKSB7CgkJaWYgKCAkdGhpcy0+Z2V0X2luc3RhbGxlZF9wYWNrYWdlX2J5X25hbWUoICRwYWNrYWdlX25hbWUgKSApIHsKCQkJcmV0dXJuIHRydWU7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCgkvKioKCSAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIHBhY2thZ2UgZnJvbSB0aGUgY29tcG9zZXIuanNvbiBpbiBhIGRpcmVjdG9yeSBwYXRoCgkgKgoJICogQHBhcmFtIHN0cmluZyAkZGlyX3BhY2thZ2UKCSAqIEByZXR1cm4gYXJyYXkgVHdvLWVsZW1lbnQgYXJyYXkgY29udGFpbmluZyBwYWNrYWdlIG5hbWUgYW5kIHZlcnNpb24uCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9wYWNrYWdlX25hbWVfYW5kX3ZlcnNpb25fZnJvbV9kaXJfcGFja2FnZSggJGRpcl9wYWNrYWdlICkgewoJCSRjb21wb3Nlcl9maWxlID0gJGRpcl9wYWNrYWdlIC4gJy9jb21wb3Nlci5qc29uJzsKCQlpZiAoICEgZmlsZV9leGlzdHMoICRjb21wb3Nlcl9maWxlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJJbnZhbGlkIHBhY2thZ2U6IGNvbXBvc2VyLmpzb24gZmlsZSAnJXMnIG5vdCBmb3VuZC4iLCAkY29tcG9zZXJfZmlsZSApICk7CgkJfQoJCSRjb21wb3Nlcl9kYXRhID0ganNvbl9kZWNvZGUoIGZpbGVfZ2V0X2NvbnRlbnRzKCAkY29tcG9zZXJfZmlsZSApLCB0cnVlICk7CgkJaWYgKCBudWxsID09PSAkY29tcG9zZXJfZGF0YSApIHsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkludmFsaWQgcGFja2FnZTogZmFpbGVkIHRvIHBhcnNlIGNvbXBvc2VyLmpzb24gZmlsZSAnJXMnIGFzIGpzb24uIiwgJGNvbXBvc2VyX2ZpbGUgKSApOwoJCX0KCQlpZiAoIGVtcHR5KCAkY29tcG9zZXJfZGF0YVsnbmFtZSddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJJbnZhbGlkIHBhY2thZ2U6IG5vIG5hbWUgaW4gY29tcG9zZXIuanNvbiBmaWxlICclcycuIiwgJGNvbXBvc2VyX2ZpbGUgKSApOwoJCX0KCQkkcGFja2FnZV9uYW1lID0gJGNvbXBvc2VyX2RhdGFbJ25hbWUnXTsKCQkkdmVyc2lvbiAgICAgID0gJ2Rldi1tYXN0ZXInOwoJCWlmICggISBlbXB0eSggJGNvbXBvc2VyX2RhdGFbJ3ZlcnNpb24nXSApICkgewoJCQkkdmVyc2lvbiA9ICRjb21wb3Nlcl9kYXRhWyd2ZXJzaW9uJ107CgkJfQoJCXJldHVybiBbICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uIF07Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBXUC1DTEkgcGFja2FnZXMgY29tcG9zZXIuanNvbiBvYmplY3QuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbXBvc2VyX2pzb24oKSB7CgkJcmV0dXJuIG5ldyBKc29uRmlsZSggJHRoaXMtPmdldF9jb21wb3Nlcl9qc29uX3BhdGgoKSApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbXBvc2VyX2pzb25fcGF0aCgpIHsKCQlzdGF0aWMgJGNvbXBvc2VyX3BhdGg7CgoJCWlmICggbnVsbCA9PT0gJGNvbXBvc2VyX3BhdGggfHwgZ2V0ZW52KCAnV1BfQ0xJX1RFU1RfUEFDS0FHRV9HRVRfQ09NUE9TRVJfSlNPTl9QQVRIJyApICkgewoKCQkJaWYgKCBnZXRlbnYoICdXUF9DTElfUEFDS0FHRVNfRElSJyApICkgewoJCQkJJGNvbXBvc2VyX3BhdGggPSBVdGlsc1x0cmFpbGluZ3NsYXNoaXQoIGdldGVudiggJ1dQX0NMSV9QQUNLQUdFU19ESVInICkgKSAuICdjb21wb3Nlci5qc29uJzsKCQkJfSBlbHNlIHsKCQkJCSRjb21wb3Nlcl9wYXRoID0gVXRpbHNcdHJhaWxpbmdzbGFzaGl0KCBVdGlsc1xnZXRfaG9tZV9kaXIoKSApIC4gJy53cC1jbGkvcGFja2FnZXMvY29tcG9zZXIuanNvbic7CgkJCX0KCgkJCS8vIGBjb21wb3Nlci5qc29uYCBhbmQgaXRzIGRpcmVjdG9yeSBtaWdodCBuZWVkIHRvIGJlIGNyZWF0ZWQKCQkJaWYgKCAhIGZpbGVfZXhpc3RzKCAkY29tcG9zZXJfcGF0aCApICkgewoJCQkJJGNvbXBvc2VyX3BhdGggPSAkdGhpcy0+Y3JlYXRlX2RlZmF1bHRfY29tcG9zZXJfanNvbiggJGNvbXBvc2VyX3BhdGggKTsKCQkJfSBlbHNlIHsKCQkJCSRjb21wb3Nlcl9wYXRoID0gcmVhbHBhdGgoICRjb21wb3Nlcl9wYXRoICk7CgkJCQlpZiAoIGZhbHNlID09PSAkY29tcG9zZXJfcGF0aCApIHsKCQkJCQkkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJDb21wb3NlciBwYXRoICclcycgZm9yIHBhY2thZ2VzL2NvbXBvc2VyLmpzb24gbm90IGZvdW5kOiAlcyIsICRjb21wb3Nlcl9wYXRoLCAkZXJyb3JbJ21lc3NhZ2UnXSApICk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiAkY29tcG9zZXJfcGF0aDsKCX0KCgkvKioKCSAqIEdldHMgdGhlIFdQLUNMSSB2ZXJzaW9uIGZvciBjb21wb3Nlci5qc29uCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF93cF9jbGlfdmVyc2lvbl9jb21wb3NlcigpIHsKCQlwcmVnX21hdGNoKCAnI15bMC05XC5dKygtKGFscGhhfGJldGEpW14tXXswLH0pPyMnLCBXUF9DTElfVkVSU0lPTiwgJG1hdGNoZXMgKTsKCQkkdmVyc2lvbiA9IGlzc2V0KCAkbWF0Y2hlc1swXSApID8gJG1hdGNoZXNbMF0gOiAnJzsKCQlyZXR1cm4gJHZlcnNpb247Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGEgZGVmYXVsdCBXUC1DTEkgcGFja2FnZXMgY29tcG9zZXIuanNvbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb21wb3Nlcl9wYXRoIFdoZXJlIHRoZSBjb21wb3Nlci5qc29uIHNob3VsZCBiZSBjcmVhdGVkCgkgKiBAcmV0dXJuIHN0cmluZyBSZXR1cm5zIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBuZXdseSBjcmVhdGVkIGRlZmF1bHQgV1AtQ0xJIHBhY2thZ2VzIGNvbXBvc2VyLmpzb24uCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gY3JlYXRlX2RlZmF1bHRfY29tcG9zZXJfanNvbiggJGNvbXBvc2VyX3BhdGggKSB7CgoJCSRjb21wb3Nlcl9kaXIgPSBwYXRoaW5mbyggJGNvbXBvc2VyX3BhdGgsIFBBVEhJTkZPX0RJUk5BTUUgKTsKCQlpZiAoICEgaXNfZGlyKCAkY29tcG9zZXJfZGlyICkgKSB7CgkJCWlmICggISBAbWtkaXIoICRjb21wb3Nlcl9kaXIsIDA3NzcsIHRydWUgKSApIHsgLy8gQGNvZGluZ1N0YW5kYXJkc0lnbm9yZUxpbmUKCQkJCSRlcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ29tcG9zZXIgZGlyZWN0b3J5ICclcycgZm9yIHBhY2thZ2VzIGNvdWxkbid0IGJlIGNyZWF0ZWQ6ICVzIiwgJGNvbXBvc2VyX2RpciwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCQl9CgkJfQoKCQkkY29tcG9zZXJfZGlyID0gcmVhbHBhdGgoICRjb21wb3Nlcl9kaXIgKTsKCQlpZiAoIGZhbHNlID09PSAkY29tcG9zZXJfZGlyICkgewoJCQkkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiQ29tcG9zZXIgZGlyZWN0b3J5ICclcycgZm9yIHBhY2thZ2VzIG5vdCBmb3VuZDogJXMiLCAkY29tcG9zZXJfZGlyLCAkZXJyb3JbJ21lc3NhZ2UnXSApICk7CgkJfQoKCQkkY29tcG9zZXJfcGF0aCA9IFV0aWxzXHRyYWlsaW5nc2xhc2hpdCggJGNvbXBvc2VyX2RpciApIC4gVXRpbHNcYmFzZW5hbWUoICRjb21wb3Nlcl9wYXRoICk7CgoJCSRqc29uX2ZpbGUgPSBuZXcgSnNvbkZpbGUoICRjb21wb3Nlcl9wYXRoICk7CgoJCSRyZXBvc2l0b3JpZXMgPSAob2JqZWN0KSBbCgkJCSd3cC1jbGknID0+IChvYmplY3QpICR0aGlzLT5jb21wb3Nlcl90eXBlX3BhY2thZ2UsCgkJXTsKCgkJJG9wdGlvbnMgPSBbCgkJCSduYW1lJyAgICAgICAgICAgICAgPT4gJ3dwLWNsaS93cC1jbGknLAoJCQknZGVzY3JpcHRpb24nICAgICAgID0+ICdJbnN0YWxsZWQgY29tbXVuaXR5IHBhY2thZ2VzIHVzZWQgYnkgV1AtQ0xJJywKCQkJJ3ZlcnNpb24nICAgICAgICAgICA9PiBzZWxmOjpnZXRfd3BfY2xpX3ZlcnNpb25fY29tcG9zZXIoKSwKCQkJJ2F1dGhvcnMnICAgICAgICAgICA9PiBbIChvYmplY3QpICR0aGlzLT5hdXRob3JfZGF0YSBdLAoJCQknaG9tZXBhZ2UnICAgICAgICAgID0+IHNlbGY6OlBBQ0tBR0VfSU5ERVhfVVJMLAoJCQkncmVxdWlyZScgICAgICAgICAgID0+IG5ldyBzdGRDbGFzcygpLAoJCQkncmVxdWlyZS1kZXYnICAgICAgID0+IG5ldyBzdGRDbGFzcygpLAoJCQknbWluaW11bS1zdGFiaWxpdHknID0+ICdkZXYnLAoJCQkncHJlZmVyLXN0YWJsZScgICAgID0+IHRydWUsCgkJCSdsaWNlbnNlJyAgICAgICAgICAgPT4gJ01JVCcsCgkJCSdyZXBvc2l0b3JpZXMnICAgICAgPT4gJHJlcG9zaXRvcmllcywKCQldOwoKCQl0cnkgewoJCQkkanNvbl9maWxlLT53cml0ZSggJG9wdGlvbnMgKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZS0+Z2V0TWVzc2FnZSgpICk7CgkJfQoKCQlyZXR1cm4gJGNvbXBvc2VyX3BhdGg7Cgl9CgoJLyoqCgkgKiBHaXZlbiBhIHBhY2thZ2UsIHRoaXMgZmluZHMgdGhlIGxhdGVzdCBwYWNrYWdlIG1hdGNoaW5nIGl0CgkgKgoJICogQHBhcmFtICBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlCgkgKiBAcGFyYW0gIENvbXBvc2VyICAgICAgICAgJGNvbXBvc2VyCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgJHBocFZlcnNpb24KCSAqIEBwYXJhbSAgYm9vbCAgICAgICAgICAgICAkbWlub3JPbmx5CgkgKgoJICogQHJldHVybiBQYWNrYWdlSW50ZXJmYWNlfG51bGwKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBmaW5kX2xhdGVzdF9wYWNrYWdlKCBQYWNrYWdlSW50ZXJmYWNlICRwYWNrYWdlLCBDb21wb3NlciAkY29tcG9zZXIsICRwaHBfdmVyc2lvbiwgJG1pbm9yX29ubHkgPSBmYWxzZSApIHsKCQkvLyBGaW5kIHRoZSBsYXRlc3QgdmVyc2lvbiBhbGxvd2VkIGluIHRoaXMgcG9vbC9yZXBvc2l0b3J5IHNldC4KCQkkbmFtZSAgICAgICAgICAgICA9ICRwYWNrYWdlLT5nZXRQcmV0dHlOYW1lKCk7CgkJJHZlcnNpb25fc2VsZWN0b3IgPSAkdGhpcy0+Z2V0X3ZlcnNpb25fc2VsZWN0b3IoICRjb21wb3NlciApOwoJCSRzdGFiaWxpdHkgICAgICAgID0gJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldE1pbmltdW1TdGFiaWxpdHkoKTsKCQkkZmxhZ3MgICAgICAgICAgICA9ICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRTdGFiaWxpdHlGbGFncygpOwoJCWlmICggaXNzZXQoICRmbGFnc1sgJG5hbWUgXSApICkgewoJCQkkc3RhYmlsaXR5ID0gYXJyYXlfc2VhcmNoKCAkZmxhZ3NbICRuYW1lIF0sIEJhc2VQYWNrYWdlOjokc3RhYmlsaXRpZXMsIHRydWUgKTsKCQl9CgkJJGJlc3Rfc3RhYmlsaXR5ID0gJHN0YWJpbGl0eTsKCQlpZiAoICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRQcmVmZXJTdGFibGUoKSApIHsKCQkJJGJlc3Rfc3RhYmlsaXR5ID0gJHBhY2thZ2UtPmdldFN0YWJpbGl0eSgpOwoJCX0KCQkkdGFyZ2V0X3ZlcnNpb24gPSBudWxsOwoJCWlmICggMCA9PT0gc3RycG9zKCAkcGFja2FnZS0+Z2V0VmVyc2lvbigpLCAnZGV2LScgKSApIHsKCQkJJHRhcmdldF92ZXJzaW9uID0gJHBhY2thZ2UtPmdldFZlcnNpb24oKTsKCQl9CgkJaWYgKCBudWxsID09PSAkdGFyZ2V0X3ZlcnNpb24gJiYgJG1pbm9yX29ubHkgKSB7CgkJCSR0YXJnZXRfdmVyc2lvbiA9ICdeJyAuICRwYWNrYWdlLT5nZXRWZXJzaW9uKCk7CgkJfQoKCQlpZiAoICR0aGlzLT5pc19jb21wb3Nlcl92MigpICkgewoJCQlyZXR1cm4gJHZlcnNpb25fc2VsZWN0b3ItPmZpbmRCZXN0Q2FuZGlkYXRlKCAkbmFtZSwgJHRhcmdldF92ZXJzaW9uLCAkYmVzdF9zdGFiaWxpdHkgKTsKCQl9CgoJCXJldHVybiAkdmVyc2lvbl9zZWxlY3Rvci0+ZmluZEJlc3RDYW5kaWRhdGUoICRuYW1lLCAkdGFyZ2V0X3ZlcnNpb24sICRwaHBfdmVyc2lvbiwgJGJlc3Rfc3RhYmlsaXR5ICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfdmVyc2lvbl9zZWxlY3RvciggQ29tcG9zZXIgJGNvbXBvc2VyICkgewoJCWlmICggISAkdGhpcy0+dmVyc2lvbl9zZWxlY3RvciApIHsKCQkJaWYgKCAkdGhpcy0+aXNfY29tcG9zZXJfdjIoKSApIHsKCQkJCSRyZXBvc2l0b3J5X3NldCA9IG5ldyBSZXBvc2l0b3J5XFJlcG9zaXRvcnlTZXQoCgkJCQkJJGNvbXBvc2VyLT5nZXRQYWNrYWdlKCktPmdldE1pbmltdW1TdGFiaWxpdHkoKSwKCQkJCQkkY29tcG9zZXItPmdldFBhY2thZ2UoKS0+Z2V0U3RhYmlsaXR5RmxhZ3MoKQoJCQkJKTsKCQkJCSRyZXBvc2l0b3J5X3NldC0+YWRkUmVwb3NpdG9yeSggbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0UmVwb3NpdG9yaWVzKCkgKSApOwoJCQkJJHRoaXMtPnZlcnNpb25fc2VsZWN0b3IgPSBuZXcgVmVyc2lvblNlbGVjdG9yKCAkcmVwb3NpdG9yeV9zZXQgKTsKCQkJfSBlbHNlIHsKCQkJCSRwb29sID0gbmV3IFBvb2woICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRNaW5pbXVtU3RhYmlsaXR5KCksICRjb21wb3Nlci0+Z2V0UGFja2FnZSgpLT5nZXRTdGFiaWxpdHlGbGFncygpICk7CgkJCQkkcG9vbC0+YWRkUmVwb3NpdG9yeSggbmV3IENvbXBvc2l0ZVJlcG9zaXRvcnkoICRjb21wb3Nlci0+Z2V0UmVwb3NpdG9yeU1hbmFnZXIoKS0+Z2V0UmVwb3NpdG9yaWVzKCkgKSApOwoJCQkJJHRoaXMtPnZlcnNpb25fc2VsZWN0b3IgPSBuZXcgVmVyc2lvblNlbGVjdG9yKCAkcG9vbCApOwoJCQl9CgkJfQoKCQlyZXR1cm4gJHRoaXMtPnZlcnNpb25fc2VsZWN0b3I7Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciBhIGdpdmVuIHBhY2thZ2UgaXMgYSBnaXQgcmVwb3NpdG9yeS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlIFBhY2thZ2UgbmFtZSB0byBjaGVjay4KCSAqCgkgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgcGFja2FnZSBpcyBhIGdpdCByZXBvc2l0b3J5LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX2dpdF9yZXBvc2l0b3J5KCAkcGFja2FnZSApIHsKCQlyZXR1cm4gJy5naXQnID09PSBzdHJ0b2xvd2VyKCBzdWJzdHIoICRwYWNrYWdlLCAtNCwgNCApICk7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhhdCBgJHBhY2thZ2VfbmFtZWAgbWF0Y2hlcyB0aGUgbmFtZSBpbiBjb21wb3Nlci5qc29uIGF0IEdpdGh1Yi5jb20sIGFuZCByZXR1cm4gY29ycmVjdGVkIHZhbHVlIGlmIG5vdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlX25hbWUgUGFja2FnZSBuYW1lIHRvIGNoZWNrLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgICAgIE9wdGlvbmFsLiBQYWNrYWdlIHZlcnNpb24uIERlZmF1bHQgJ21hc3RlcicuCgkgKiBAcGFyYW0gYm9vbCAgICRpbnNlY3VyZSAgICAgT3B0aW9uYWwuIFdoZXRoZXIgdG8gaW5zZWN1cmVseSByZXRyeSBkb3dubG9hZHMgdGhhdCBmYWlsZWQgVExTIGhhbmRzaGFrZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19naXRodWJfcGFja2FnZV9uYW1lKCAkcGFja2FnZV9uYW1lLCAkdmVyc2lvbiA9ICcnLCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCQkvLyBHZW5lcmF0ZSByYXcgZ2l0IFVSTCBvZiBjb21wb3Nlci5qc29uIGZpbGUuCgkJJHJhd19jb250ZW50X3VybCA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vJyAuICRwYWNrYWdlX25hbWUgLiAnLycgLiAkdGhpcy0+Z2V0X3Jhd19naXRfdmVyc2lvbiggJHZlcnNpb24gKSAuICcvY29tcG9zZXIuanNvbic7CgkJJGdpdGh1Yl90b2tlbiAgICA9IGdldGVudiggJ0dJVEhVQl9UT0tFTicgKTsgLy8gVXNlIEdJVEhVQl9UT0tFTiBpZiBhdmFpbGFibGUgdG8gYXZvaWQgYXV0aG9yaXphdGlvbiBmYWlsdXJlcyBvciByYXRlLWxpbWl0aW5nLgoJCSRoZWFkZXJzICAgICAgICAgPSAkZ2l0aHViX3Rva2VuID8gWyAnQXV0aG9yaXphdGlvbicgPT4gJ3Rva2VuICcgLiAkZ2l0aHViX3Rva2VuIF0gOiBbXTsKCQkkb3B0aW9ucyAgICAgICAgID0gWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdOwoKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkcmF3X2NvbnRlbnRfdXJsLCBudWxsIC8qZGF0YSovLCAkaGVhZGVycywgJG9wdGlvbnMgKTsKCQlpZiAoIDIwICE9PSAoaW50KSBzdWJzdHIoICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsIDAsIDIgKSApIHsKCQkJLy8gQ291bGQgbm90IGdldCBjb21wb3Nlci5qc29uLiBQb3NzaWJseSBwcml2YXRlIHNvIHdhcm4gYW5kIHJldHVybiBiZXN0IGd1ZXNzIGZyb20gaW5wdXQgKGFsd2F5cyB4eHgveHh4KS4KCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiQ291bGRuJ3QgZG93bmxvYWQgY29tcG9zZXIuanNvbiBmaWxlIGZyb20gJyVzJyAoSFRUUCBjb2RlICVkKS4gUHJlc3VtaW5nIHBhY2thZ2UgbmFtZSBpcyAnJXMnLiIsICRyYXdfY29udGVudF91cmwsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsICRwYWNrYWdlX25hbWUgKSApOwoJCQlyZXR1cm4gJHBhY2thZ2VfbmFtZTsKCQl9CgoJCS8vIENvbnZlcnQgY29tcG9zZXIuanNvbiBKU09OIHRvIEFycmF5LgoJCSRjb21wb3Nlcl9jb250ZW50X2FzX2FycmF5ID0ganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSwgdHJ1ZSApOwoJCWlmICggbnVsbCA9PT0gJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJGYWlsZWQgdG8gcGFyc2UgJyVzJyBhcyBqc29uLiIsICRyYXdfY29udGVudF91cmwgKSApOwoJCX0KCQlpZiAoIGVtcHR5KCAkY29tcG9zZXJfY29udGVudF9hc19hcnJheVsnbmFtZSddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJJbnZhbGlkIHBhY2thZ2U6IG5vIG5hbWUgaW4gY29tcG9zZXIuanNvbiBmaWxlICclcycuIiwgJHJhd19jb250ZW50X3VybCApICk7CgkJfQoKCQkvLyBQYWNrYWdlIG5hbWUgaW4gY29tcG9zZXIuanNvbiB0aGF0IGlzIGhvc3RlZCBvbiBHaXRIdWIuCgkJJHBhY2thZ2VfbmFtZV9vbl9yZXBvID0gJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXlbJ25hbWUnXTsKCgkJLy8gSWYgcGFja2FnZSBuYW1lIGFuZCByZXBvc2l0b3J5IG5hbWUgYXJlIG5vdCBpZGVudGljYWwsIHRoZW4gZml4IGl0LgoJCWlmICggJHBhY2thZ2VfbmFtZSAhPT0gJHBhY2thZ2VfbmFtZV9vbl9yZXBvICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJQYWNrYWdlIG5hbWUgbWlzbWF0Y2guLi5VcGRhdGluZyBmcm9tIGdpdCBuYW1lICclcycgdG8gY29tcG9zZXIuanNvbiBuYW1lICclcycuIiwgJHBhY2thZ2VfbmFtZSwgJHBhY2thZ2VfbmFtZV9vbl9yZXBvICkgKTsKCQkJJHBhY2thZ2VfbmFtZSA9ICRwYWNrYWdlX25hbWVfb25fcmVwbzsKCQl9CgkJcmV0dXJuICRwYWNrYWdlX25hbWU7Cgl9CgoJLyoqCgkgKiBDaGVja3MgdGhhdCBgJHBhY2thZ2VfbmFtZWAgbWF0Y2hlcyB0aGUgbmFtZSBpbiBjb21wb3Nlci5qc29uIGF0IHRoZSBjb3JyZXNwb25kaW5nIHVwc3RyZWFtIHJlcG9zaXRvcnksIGFuZCByZXR1cm4gY29ycmVjdGVkIHZhbHVlIGlmIG5vdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYWNrYWdlX25hbWUgUGFja2FnZSBuYW1lIHRvIGNoZWNrLgoJICogQHBhcmFtIHN0cmluZyAkdXJybCAgICAgICAgIFVSTCB0byBmZXRjaCB0aGUgcGFja2FnZSBmcm9tLgoJICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiAgICAgIE9wdGlvbmFsLiBQYWNrYWdlIHZlcnNpb24uIERlZmF1bHQgJ21hc3RlcicuCgkgKiBAcGFyYW0gYm9vbCAgICRpbnNlY3VyZSAgICAgT3B0aW9uYWwuIFdoZXRoZXIgdG8gaW5zZWN1cmVseSByZXRyeSBkb3dubG9hZHMgdGhhdCBmYWlsZWQgVExTIGhhbmRzaGFrZS4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19naXRfcGFja2FnZV9uYW1lKCAkcGFja2FnZV9uYW1lLCAkdXJsID0gJycsICR2ZXJzaW9uID0gJycsICRpbnNlY3VyZSA9IGZhbHNlICkgewoJCWlmICggJHVybCAmJiAoIHN0cnBvcyggJHVybCwgJzovL2dpdGxhYi5jb20vJyApICE9PSBmYWxzZSApIHx8ICggc3RycG9zKCAkdXJsLCAnZ2l0QGdpdGxhYi5jb206JyApICE9PSBmYWxzZSApICkgewoJCQlyZXR1cm4gJHRoaXMtPmNoZWNrX2dpdGxhYl9wYWNrYWdlX25hbWUoICRwYWNrYWdlX25hbWUsICR2ZXJzaW9uLCAkaW5zZWN1cmUgKTsKCQl9CgoJCXJldHVybiAkdGhpcy0+Y2hlY2tfZ2l0aHViX3BhY2thZ2VfbmFtZSggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24sICRpbnNlY3VyZSApOwoJfQoKCS8qKgoJICogQ2hlY2tzIHRoYXQgYCRwYWNrYWdlX25hbWVgIG1hdGNoZXMgdGhlIG5hbWUgaW4gY29tcG9zZXIuanNvbiBhdCBHaXRMYWIuY29tLCBhbmQgcmV0dXJuIGNvcnJlY3RlZCB2YWx1ZSBpZiBub3QuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFja2FnZV9uYW1lIFBhY2thZ2UgbmFtZSB0byBjaGVjay4KCSAqIEBwYXJhbSBzdHJpbmcgJHZlcnNpb24gICAgICBPcHRpb25hbC4gUGFja2FnZSB2ZXJzaW9uLiBEZWZhdWx0ICdtYXN0ZXInLgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgICAgIE9wdGlvbmFsLiBXaGV0aGVyIHRvIGluc2VjdXJlbHkgcmV0cnkgZG93bmxvYWRzIHRoYXQgZmFpbGVkIFRMUyBoYW5kc2hha2UuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gY2hlY2tfZ2l0bGFiX3BhY2thZ2VfbmFtZSggJHBhY2thZ2VfbmFtZSwgJHZlcnNpb24gPSAnJywgJGluc2VjdXJlID0gZmFsc2UgKSB7CgkJLy8gR2VuZXJhdGUgcmF3IGdpdCBVUkwgb2YgY29tcG9zZXIuanNvbiBmaWxlLgoJCSRyYXdfY29udGVudF9wdWJsaWNfdXJsICA9ICdodHRwczovL2dpdGxhYi5jb20vJyAuICRwYWNrYWdlX25hbWUgLiAnLy0vcmF3LycgLiAkdGhpcy0+Z2V0X3Jhd19naXRfdmVyc2lvbiggJHZlcnNpb24gKSAuICcvY29tcG9zZXIuanNvbic7CgkJJHJhd19jb250ZW50X3ByaXZhdGVfdXJsID0gJ2h0dHBzOi8vZ2l0bGFiLmNvbS9hcGkvdjQvcHJvamVjdHMvJyAuIHJhd3VybGVuY29kZSggJHBhY2thZ2VfbmFtZSApIC4gJy9yZXBvc2l0b3J5L2ZpbGVzL2NvbXBvc2VyLmpzb24vcmF3P3JlZj0nIC4gJHRoaXMtPmdldF9yYXdfZ2l0X3ZlcnNpb24oICR2ZXJzaW9uICk7CgoJCSRvcHRpb25zID0gWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdOwoKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkcmF3X2NvbnRlbnRfcHVibGljX3VybCwgbnVsbCAvKmRhdGEqLywgW10sICRvcHRpb25zICk7CgkJaWYgKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlIDwgMjAwIHx8ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgPj0gMzAwICkgewoJCQkvLyBDb3VsZCBub3QgZ2V0IGNvbXBvc2VyLmpzb24uIFBvc3NpYmx5IHByaXZhdGUgc28gd2FybiBhbmQgcmV0dXJuIGJlc3QgZ3Vlc3MgZnJvbSBpbnB1dCAoYWx3YXlzIHh4eC94eHgpLgoJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICJDb3VsZG4ndCBkb3dubG9hZCBjb21wb3Nlci5qc29uIGZpbGUgZnJvbSAnJXMnIChIVFRQIGNvZGUgJWQpLiBQcmVzdW1pbmcgcGFja2FnZSBuYW1lIGlzICclcycuIiwgJHJhd19jb250ZW50X3B1YmxpY191cmwsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsICRwYWNrYWdlX25hbWUgKSApOwoJCQlyZXR1cm4gJHBhY2thZ2VfbmFtZTsKCQl9CgoJCWlmICggc3RycG9zKCAkcmVzcG9uc2UtPmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLCAndGV4dC9odG1sJyApID09PSAwICkgewoJCQkkZ2l0bGFiX3Rva2VuID0gZ2V0ZW52KCAnR0lUTEFCX1RPS0VOJyApOyAvLyBVc2UgR0lUTEFCX1RPS0VOIGlmIGF2YWlsYWJsZSB0byBhdm9pZCBhdXRob3JpemF0aW9uIGZhaWx1cmVzIG9yIHJhdGUtbGltaXRpbmcuCgkJCSRoZWFkZXJzICAgICAgPSAkZ2l0bGFiX3Rva2VuID8gWyAnUFJJVkFURS1UT0tFTicgPT4gJGdpdGxhYl90b2tlbiBdIDogW107CgkJCSRyZXNwb25zZSAgICAgPSBVdGlsc1xodHRwX3JlcXVlc3QoICdHRVQnLCAkcmF3X2NvbnRlbnRfcHJpdmF0ZV91cmwsIG51bGwgLypkYXRhKi8sICRoZWFkZXJzLCAkb3B0aW9ucyApOwoKCQkJaWYgKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlIDwgMjAwIHx8ICRyZXNwb25zZS0+c3RhdHVzX2NvZGUgPj0gMzAwICkgewoJCQkJLy8gQ291bGQgbm90IGdldCBjb21wb3Nlci5qc29uLiBQb3NzaWJseSBwcml2YXRlIHNvIHdhcm4gYW5kIHJldHVybiBiZXN0IGd1ZXNzIGZyb20gaW5wdXQgKGFsd2F5cyB4eHgveHh4KS4KCQkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIkNvdWxkbid0IGRvd25sb2FkIGNvbXBvc2VyLmpzb24gZmlsZSBmcm9tICclcycgKEhUVFAgY29kZSAlZCkuIFByZXN1bWluZyBwYWNrYWdlIG5hbWUgaXMgJyVzJy4iLCAkcmF3X2NvbnRlbnRfcHJpdmF0ZV91cmwsICRyZXNwb25zZS0+c3RhdHVzX2NvZGUsICRwYWNrYWdlX25hbWUgKSApOwoJCQkJcmV0dXJuICRwYWNrYWdlX25hbWU7CgkJCX0KCQl9CgoJCS8vIENvbnZlcnQgY29tcG9zZXIuanNvbiBKU09OIHRvIEFycmF5LgoJCSRjb21wb3Nlcl9jb250ZW50X2FzX2FycmF5ID0ganNvbl9kZWNvZGUoICRyZXNwb25zZS0+Ym9keSwgdHJ1ZSApOwoJCWlmICggbnVsbCA9PT0gJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoIHNwcmludGYoICJGYWlsZWQgdG8gcGFyc2UgJyVzJyBhcyBqc29uLiIsICRyZXNwb25zZS0+dXJsICkgKTsKCQl9CgkJaWYgKCBlbXB0eSggJGNvbXBvc2VyX2NvbnRlbnRfYXNfYXJyYXlbJ25hbWUnXSApICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiSW52YWxpZCBwYWNrYWdlOiBubyBuYW1lIGluIGNvbXBvc2VyLmpzb24gZmlsZSAnJXMnLiIsICRyZXNwb25zZS0+dXJsICkgKTsKCQl9CgoJCS8vIFBhY2thZ2UgbmFtZSBpbiBjb21wb3Nlci5qc29uIHRoYXQgaXMgaG9zdGVkIG9uIEdpdGxhYi4KCQkkcGFja2FnZV9uYW1lX29uX3JlcG8gPSAkY29tcG9zZXJfY29udGVudF9hc19hcnJheVsnbmFtZSddOwoKCQkvLyBJZiBwYWNrYWdlIG5hbWUgYW5kIHJlcG9zaXRvcnkgbmFtZSBhcmUgbm90IGlkZW50aWNhbCwgdGhlbiBmaXggaXQuCgkJaWYgKCAkcGFja2FnZV9uYW1lICE9PSAkcGFja2FnZV9uYW1lX29uX3JlcG8gKSB7CgkJCVdQX0NMSTo6d2FybmluZyggc3ByaW50ZiggIlBhY2thZ2UgbmFtZSBtaXNtYXRjaC4uLlVwZGF0aW5nIGZyb20gZ2l0IG5hbWUgJyVzJyB0byBjb21wb3Nlci5qc29uIG5hbWUgJyVzJy4iLCAkcGFja2FnZV9uYW1lLCAkcGFja2FnZV9uYW1lX29uX3JlcG8gKSApOwoJCQkkcGFja2FnZV9uYW1lID0gJHBhY2thZ2VfbmFtZV9vbl9yZXBvOwoJCX0KCQlyZXR1cm4gJHBhY2thZ2VfbmFtZTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmVyc2lvbiB0byB1c2UgZm9yIHJhdyBnaXRodWIgcmVxdWVzdC4gVmVyeSBiYXNpYy4KCSAqCgkgKiBAc3RyaW5nICR2ZXJzaW9uIFBhY2thZ2UgdmVyc2lvbi4KCSAqIEBzdHJpbmcgVmVyc2lvbiB0byB1c2UgZm9yIGdpdGh1YiByZXF1ZXN0LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9yYXdfZ2l0X3ZlcnNpb24oICR2ZXJzaW9uICkgewoJCWlmICggJycgPT09ICR2ZXJzaW9uICkgewoJCQlyZXR1cm4gJ21hc3Rlcic7CgkJfQoKCQkvLyBJZiBDb21wb3NlciBoYXNoIGdpdmVuIHRoZW4ganVzdCB1c2Ugd2hhdGV2ZXIncyBhZnRlciBpdC4KCQkkaGFzaF9wb3MgPSBzdHJwb3MoICR2ZXJzaW9uLCAnIycgKTsKCQlpZiAoIGZhbHNlICE9PSAkaGFzaF9wb3MgKSB7CgkJCXJldHVybiBzdWJzdHIoICR2ZXJzaW9uLCAkaGFzaF9wb3MgKyAxICk7CgkJfQoKCQkvLyBTdHJpcCBhbnkgQ29tcG9zZXIgJ2Rldi0nIHByZWZpeC4KCQlpZiAoIDAgPT09IHN0cm5jbXAoICR2ZXJzaW9uLCAnZGV2LScsIDQgKSApIHsKCQkJJHZlcnNpb24gPSBzdWJzdHIoICR2ZXJzaW9uLCA0ICk7CgkJfQoKCQkvLyBJZ25vcmUvc3RyaXAgYW55IHJlbGF0aXZlIHN1ZmZpeGVzLgoJCXJldHVybiBzdHJfcmVwbGFjZSggWyAnXicsICd+JyBdLCAnJywgJHZlcnNpb24gKTsKCX0KCgkvKioKCSAqIEdldHMgdGhlIHJlbGVhc2UgdGFnIGZvciB0aGUgbGF0ZXN0IHN0YWJsZSByZWxlYXNlIG9mIGEgR2l0SHViIHJlcG9zaXRvcnkuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGFja2FnZV9uYW1lIE5hbWUgb2YgdGhlIHJlcG9zaXRvcnkuCgkgKgoJICogQHJldHVybiBzdHJpbmcgUmVsZWFzZSB0YWcuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2dpdGh1Yl9sYXRlc3RfcmVsZWFzZV90YWcoICRwYWNrYWdlX25hbWUsICRpbnNlY3VyZSApIHsKCQkkdXJsICAgICAgPSAiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy97JHBhY2thZ2VfbmFtZX0vcmVsZWFzZXMvbGF0ZXN0IjsKCQkkb3B0aW9ucyAgPSBbICdpbnNlY3VyZScgPT4gJGluc2VjdXJlIF07CgkJJHJlc3BvbnNlID0gVXRpbHNcaHR0cF9yZXF1ZXN0KCAnR0VUJywgJHVybCwgbnVsbCwgW10sICRvcHRpb25zICk7CgkJaWYgKCAyMCAhPT0gKGludCkgc3Vic3RyKCAkcmVzcG9uc2UtPnN0YXR1c19jb2RlLCAwLCAyICkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ0NvdWxkIG5vdCBndWVzcyBzdGFibGUgdmVyc2lvbiBmcm9tIEdpdEh1YiByZXBvc2l0b3J5LCBmYWxsaW5nIGJhY2sgdG8gbWFzdGVyIGJyYW5jaCcgKTsKCQkJcmV0dXJuICdtYXN0ZXInOwoJCX0KCgkJJHBhY2thZ2VfZGF0YSA9IGpzb25fZGVjb2RlKCAkcmVzcG9uc2UtPmJvZHkgKTsKCQlpZiAoIEpTT05fRVJST1JfTk9ORSAhPT0ganNvbl9sYXN0X2Vycm9yKCkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ0NvdWxkIG5vdCBndWVzcyBzdGFibGUgdmVyc2lvbiBmcm9tIEdpdEh1YiByZXBvc2l0b3J5LCBmYWxsaW5nIGJhY2sgdG8gbWFzdGVyIGJyYW5jaCcgKTsKCQkJcmV0dXJuICdtYXN0ZXInOwoJCX0KCgkJJHRhZyA9ICRwYWNrYWdlX2RhdGEtPnRhZ19uYW1lOwoJCVdQX0NMSTo6ZGVidWcoICJFeHRyYWN0ZWQgbGF0ZXN0IHN0YWJsZSByZWxlYXNlIHRhZzogeyR0YWd9IiwgJ3BhY2thZ2VzJyApOwoKCQlyZXR1cm4gJHRhZzsKCX0KCgkvKioKCSAqIEd1ZXNzZXMgdGhlIHZlcnNpb24gY29uc3RyYWludCBmcm9tIGEgcmVsZWFzZSB0YWcuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkdGFnIFJlbGVhc2UgdGFnIHRvIGd1ZXNzIHRoZSB2ZXJzaW9uIGNvbnN0cmFpbnQgZnJvbS4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBWZXJzaW9uIGNvbnN0cmFpbnQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ3Vlc3NfdmVyc2lvbl9jb25zdHJhaW50X2Zyb21fdGFnKCAkdGFnICkgewoJCSRtYXRjaGVzID0gW107CgkJaWYgKCAxICE9PSBwcmVnX21hdGNoKCAnLyg/OnZlcnNpb258dilccyooKD86WzAtOV0rXC4/KSspKD86LS4qKS9pJywgJHRhZywgJG1hdGNoZXMgKSApIHsKCQkJcmV0dXJuICR0YWc7CgkJfQoKCQkkY29uc3RyYWludCA9ICJeeyRtYXRjaGVzWzFdfSI7CgkJV1BfQ0xJOjpkZWJ1ZyggIkd1ZXNzaW5nIHZlcnNpb24gY29uc3RyYWludCB0byB1c2U6IHskY29uc3RyYWludH0iLCAncGFja2FnZXMnICk7CgoJCXJldHVybiAkY29uc3RyYWludDsKCX0KCgkvKioKCSAqIFNldHMgYENPTVBPU0VSX0FVVEhgIGVudmlyb25tZW50IHZhcmlhYmxlICh3aGljaCBDb21wb3NlciBtZXJnZXMgaW50byB0aGUgY29uZmlnIHNldHVwIGluIGBDb21wb3NlclxGYWN0b3J5OjpjcmVhdGVDb25maWcoKWApIGRlcGVuZGluZyBvbiBhdmFpbGFibGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLgoJICogQXZvaWRzIGF1dGhvcml6YXRpb24gZmFpbHVyZXMgd2hlbiBhY2Nlc3NpbmcgdmFyaW91cyBzaXRlcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzZXRfY29tcG9zZXJfYXV0aF9lbnZfdmFyKCkgewoJCSRjaGFuZ2VkICAgICAgID0gZmFsc2U7CgkJJGNvbXBvc2VyX2F1dGggPSBnZXRlbnYoICdDT01QT1NFUl9BVVRIJyApOwoJCWlmICggZmFsc2UgIT09ICRjb21wb3Nlcl9hdXRoICkgewoJCQkkY29tcG9zZXJfYXV0aCA9IGpzb25fZGVjb2RlKCAkY29tcG9zZXJfYXV0aCwgdHJ1ZSAvKmFzc29jKi8gKTsKCQl9CgkJaWYgKCBlbXB0eSggJGNvbXBvc2VyX2F1dGggKSB8fCAhIGlzX2FycmF5KCAkY29tcG9zZXJfYXV0aCApICkgewoJCQkkY29tcG9zZXJfYXV0aCA9IFtdOwoJCX0KCQkkZ2l0aHViX3Rva2VuID0gZ2V0ZW52KCAnR0lUSFVCX1RPS0VOJyApOwoJCWlmICggISBpc3NldCggJGNvbXBvc2VyX2F1dGhbJ2dpdGh1Yi1vYXV0aCddICkgJiYgaXNfc3RyaW5nKCAkZ2l0aHViX3Rva2VuICkgKSB7CgkJCSRjb21wb3Nlcl9hdXRoWydnaXRodWItb2F1dGgnXSA9IFsgJ2dpdGh1Yi5jb20nID0+ICRnaXRodWJfdG9rZW4gXTsKCQkJJGNoYW5nZWQgICAgICAgICAgICAgICAgICAgICAgID0gdHJ1ZTsKCQl9CgkJaWYgKCAkY2hhbmdlZCApIHsKCQkJcHV0ZW52KCAnQ09NUE9TRVJfQVVUSD0nIC4ganNvbl9lbmNvZGUoICRjb21wb3Nlcl9hdXRoICkgKTsKCQl9Cgl9CgoJLyoqCgkgKiBBdm9pZCB1c2luZyBkZWZhdWx0IENvbXBvc2VyIENBIGJ1bmRsZSBpZiBpbiBwaGFyIGFzIHdlIGRvbid0IGluY2x1ZGUgaXQuCgkgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvc2VyL2NhLWJ1bmRsZS9ibG9iLzEuMS4wL3NyYy9DYUJ1bmRsZS5waHAjTDY0CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYXZvaWRfY29tcG9zZXJfY2FfYnVuZGxlKCkgewoJCWlmICggVXRpbHNcaW5zaWRlX3BoYXIoKSAmJiAhIGdldGVudiggJ1NTTF9DRVJUX0ZJTEUnICkgJiYgISBnZXRlbnYoICdTU0xfQ0VSVF9ESVInICkgJiYgISBpbmlfZ2V0KCAnb3BlbnNzbC5jYWZpbGUnICkgJiYgISBpbmlfZ2V0KCAnb3BlbnNzbC5jYXBhdGgnICkgKSB7CgkJCSRjZXJ0aWZpY2F0ZSA9IFV0aWxzXGV4dHJhY3RfZnJvbV9waGFyKCBXUF9DTElfVkVORE9SX0RJUiAuIHNlbGY6OlNTTF9DRVJUSUZJQ0FURSApOwoJCQlwdXRlbnYoICJTU0xfQ0VSVF9GSUxFPXskY2VydGlmaWNhdGV9IiApOwoJCX0KCX0KCgkvKioKCSAqIFJlYWRzIHRoZSBXUC1DTEkgcGFja2FnZXMgY29tcG9zZXIuanNvbiwgY2hlY2tpbmcgdmFsaWRpdHkgYW5kIHJldHVybmluZyBhcnJheSBjb250YWluaW5nIGl0cyBwYXRoLCBjb250ZW50cywgYW5kIGRlY29kZWQgY29udGVudHMuCgkgKgoJICogQHJldHVybiBhcnJheSBJbmRleGVkIGFycmF5IGNvbnRhaW5pbmcgdGhlIHBhdGgsIHRoZSBjb250ZW50cywgYW5kIHRoZSBkZWNvZGVkIGNvbnRlbnRzIG9mIHRoZSBXUC1DTEkgcGFja2FnZXMgY29tcG9zZXIuanNvbi4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29tcG9zZXJfanNvbl9wYXRoX2JhY2t1cF9kZWNvZGVkKCkgewoJCSRjb21wb3Nlcl9qc29uX29iaiA9ICR0aGlzLT5nZXRfY29tcG9zZXJfanNvbigpOwoJCSRqc29uX3BhdGggICAgICAgICA9ICRjb21wb3Nlcl9qc29uX29iai0+Z2V0UGF0aCgpOwoJCSRjb21wb3Nlcl9iYWNrdXAgICA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkanNvbl9wYXRoICk7CgkJaWYgKCBmYWxzZSA9PT0gJGNvbXBvc2VyX2JhY2t1cCApIHsKCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJV1BfQ0xJOjplcnJvciggc3ByaW50ZiggIkZhaWxlZCB0byByZWFkICclcyc6ICVzIiwgJGpzb25fcGF0aCwgJGVycm9yWydtZXNzYWdlJ10gKSApOwoJCX0KCQl0cnkgewoJCQkkY29tcG9zZXJfYmFja3VwX2RlY29kZWQgPSAkY29tcG9zZXJfanNvbl9vYmotPnJlYWQoKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRlICkgewoJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAiRmFpbGVkIHRvIHBhcnNlICclcycgYXMganNvbjogJXMiLCAkanNvbl9wYXRoLCAkZS0+Z2V0TWVzc2FnZSgpICkgKTsKCQl9CgoJCXJldHVybiBbICRqc29uX3BhdGgsICRjb21wb3Nlcl9iYWNrdXAsICRjb21wb3Nlcl9iYWNrdXBfZGVjb2RlZCBdOwoJfQoKCS8qKgoJICogUmVnaXN0ZXJzIGEgUEhQIHNodXRkb3duIGZ1bmN0aW9uIHRvIHJldmVydCBjb21wb3Nlci5qc29uIHVubGVzcwoJICogcmVmZXJlbmNlZCBgJHJldmVydGAgZmxhZyBpcyBmYWxzZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRqc29uX3BhdGggICAgICAgUGF0aCB0byBjb21wb3Nlci5qc29uLgoJICogQHBhcmFtIHN0cmluZyAkY29tcG9zZXJfYmFja3VwIE9yaWdpbmFsIGNvbnRlbnRzIG9mIGNvbXBvc2VyLmpzb24uCgkgKiBAcGFyYW0gYm9vbCAgICYkcmV2ZXJ0ICAgICAgICAgRmxhZ3Mgd2hldGhlciB0byByZXZlcnQgb3Igbm90LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJlZ2lzdGVyX3JldmVydF9zaHV0ZG93bl9mdW5jdGlvbiggJGpzb25fcGF0aCwgJGNvbXBvc2VyX2JhY2t1cCwgJiRyZXZlcnQgKSB7CgkJLy8gQWxsb2NhdGUgYWxsIG5lZWRlZCBtZW1vcnkgYmVmb3JlaGFuZCBhcyBtdWNoIGFzIHBvc3NpYmxlLgoJCSRyZXZlcnRfbXNnICAgICAgPSAiUmV2ZXJ0ZWQgY29tcG9zZXIuanNvbi5cbiI7CgkJJHJldmVydF9mYWlsX21zZyA9ICJGYWlsZWQgdG8gcmV2ZXJ0IGNvbXBvc2VyLmpzb24uXG4iOwoJCSRtZW1vcnlfbXNnICAgICAgPSAiV1AtQ0xJIHJhbiBvdXQgb2YgbWVtb3J5LiBQbGVhc2Ugc2VlIGh0dHBzOi8vYml0Lmx5L3dwY2xpbWVtIGZvciBmdXJ0aGVyIGhlbHAuXG4iOwoJCSRtZW1vcnlfc3RyaW5nICAgPSAnQWxsb3dlZCBtZW1vcnkgc2l6ZSBvZic7CgkJJGVycm9yX2FycmF5ICAgICA9IFsKCQkJJ3R5cGUnICAgID0+IDQyLAoJCQknbWVzc2FnZScgPT4gJ1NvbWUgcmFuZG9tIGR1bW15IHN0cmluZyB0byB0YWtlIHVwIG1lbW9yeScsCgkJCSdmaWxlJyAgICA9PiAnQW5vdGhlciByYW5kb20gc3RyaW5nLCB3aGljaCB3b3VsZCBiZSBhIGZpbGVuYW1lIHRoaXMgdGltZScsCgkJCSdsaW5lJyAgICA9PiAzMTQsCgkJXTsKCgkJcmVnaXN0ZXJfc2h1dGRvd25fZnVuY3Rpb24oCgkJCXN0YXRpYyBmdW5jdGlvbiAoKSB1c2UgKAoJCQkJJGpzb25fcGF0aCwKCQkJCSRjb21wb3Nlcl9iYWNrdXAsCgkJCQkmJHJldmVydCwKCQkJCSRyZXZlcnRfbXNnLAoJCQkJJHJldmVydF9mYWlsX21zZywKCQkJCSRtZW1vcnlfbXNnLAoJCQkJJG1lbW9yeV9zdHJpbmcsCgkJCQkkZXJyb3JfYXJyYXkKCQkJKSB7CgkJCQlpZiAoICRyZXZlcnQgKSB7CgkJCQkJaWYgKCBmYWxzZSAhPT0gZmlsZV9wdXRfY29udGVudHMoICRqc29uX3BhdGgsICRjb21wb3Nlcl9iYWNrdXAgKSApIHsKCQkJCQkJZndyaXRlKCBTVERFUlIsICRyZXZlcnRfbXNnICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJZndyaXRlKCBTVERFUlIsICRyZXZlcnRfZmFpbF9tc2cgKTsKCQkJCQl9CgkJCQl9CgoJCQkJJGVycm9yX2FycmF5ID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJCWlmICggaXNfYXJyYXkoICRlcnJvcl9hcnJheSApICYmIGZhbHNlICE9PSBzdHJwb3MoICRlcnJvcl9hcnJheVsnbWVzc2FnZSddLCAkbWVtb3J5X3N0cmluZyApICkgewoJCQkJCWZ3cml0ZSggU1RERVJSLCAkbWVtb3J5X21zZyApOwoJCQkJfQoJCQl9CgkJKTsKCX0KCgkvKioKCSAqIENoZWNrIHdoZXRoZXIgd2UgYXJlIGRlYWxpbmcgd2l0aCBDb21wb3NlciB2ZXJzaW9uIDIuMC4wKy4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpc19jb21wb3Nlcl92MigpIHsKCQlyZXR1cm4gdmVyc2lvbl9jb21wYXJlKCBDb21wb3Nlcjo6Z2V0VmVyc2lvbigpLCAnMi4wLjAnLCAnPj0nICk7Cgl9Cn0KPD9waHAKCmlmICggISBjbGFzc19leGlzdHMoICdXUF9DTEknICkgKSB7CglyZXR1cm47Cn0KCiR3cGNsaV9zZWFyY2hfcmVwbGFjZV9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9zZWFyY2hfcmVwbGFjZV9hdXRvbG9hZGVyICkgKSB7CglyZXF1aXJlX29uY2UgJHdwY2xpX3NlYXJjaF9yZXBsYWNlX2F1dG9sb2FkZXI7Cn0KCldQX0NMSTo6YWRkX2NvbW1hbmQoICdzZWFyY2gtcmVwbGFjZScsICdTZWFyY2hfUmVwbGFjZV9Db21tYW5kJyApOwo8P3BocAoKY2xhc3MgU2VhcmNoX1JlcGxhY2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCglwcml2YXRlICRkcnlfcnVuOwoJcHJpdmF0ZSAkZXhwb3J0X2hhbmRsZSA9IGZhbHNlOwoJcHJpdmF0ZSAkZXhwb3J0X2luc2VydF9zaXplOwoJcHJpdmF0ZSAkcmVjdXJzZV9vYmplY3RzOwoJcHJpdmF0ZSAkcmVnZXg7Cglwcml2YXRlICRyZWdleF9mbGFnczsKCXByaXZhdGUgJHJlZ2V4X2RlbGltaXRlcjsKCXByaXZhdGUgJHJlZ2V4X2xpbWl0ID0gLTE7Cglwcml2YXRlICRza2lwX3RhYmxlczsKCXByaXZhdGUgJHNraXBfY29sdW1uczsKCXByaXZhdGUgJGluY2x1ZGVfY29sdW1uczsKCXByaXZhdGUgJGZvcm1hdDsKCXByaXZhdGUgJHJlcG9ydDsKCXByaXZhdGUgJHJlcG9ydF9jaGFuZ2VkX29ubHk7CgoJcHJpdmF0ZSAkbG9nX2hhbmRsZSAgICAgICAgID0gbnVsbDsKCXByaXZhdGUgJGxvZ19iZWZvcmVfY29udGV4dCA9IDQwOwoJcHJpdmF0ZSAkbG9nX2FmdGVyX2NvbnRleHQgID0gNDA7Cglwcml2YXRlICRsb2dfcHJlZml4ZXMgICAgICAgPSBhcnJheSggJzwgJywgJz4gJyApOwoJcHJpdmF0ZSAkbG9nX2NvbG9yczsKCXByaXZhdGUgJGxvZ19lbmNvZGluZzsKCgkvKioKCSAqIFNlYXJjaGVzL3JlcGxhY2VzIHN0cmluZ3MgaW4gdGhlIGRhdGFiYXNlLgoJICoKCSAqIFNlYXJjaGVzIHRocm91Z2ggYWxsIHJvd3MgaW4gYSBzZWxlY3Rpb24gb2YgdGFibGVzIGFuZCByZXBsYWNlcwoJICogYXBwZWFyYW5jZXMgb2YgdGhlIGZpcnN0IHN0cmluZyB3aXRoIHRoZSBzZWNvbmQgc3RyaW5nLgoJICoKCSAqIEJ5IGRlZmF1bHQsIHRoZSBjb21tYW5kIHVzZXMgdGFibGVzIHJlZ2lzdGVyZWQgdG8gdGhlIGAkd3BkYmAgb2JqZWN0LiBPbgoJICogbXVsdGlzaXRlLCB0aGlzIHdpbGwganVzdCBiZSB0aGUgdGFibGVzIGZvciB0aGUgY3VycmVudCBzaXRlIHVubGVzcwoJICogYC0tbmV0d29ya2AgaXMgc3BlY2lmaWVkLgoJICoKCSAqIFNlYXJjaC9yZXBsYWNlIGludGVsbGlnZW50bHkgaGFuZGxlcyBQSFAgc2VyaWFsaXplZCBkYXRhLCBhbmQgZG9lcyBub3QKCSAqIGNoYW5nZSBwcmltYXJ5IGtleSB2YWx1ZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxvbGQ+CgkgKiA6IEEgc3RyaW5nIHRvIHNlYXJjaCBmb3Igd2l0aGluIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiA8bmV3PgoJICogOiBSZXBsYWNlIGluc3RhbmNlcyBvZiB0aGUgZmlyc3Qgc3RyaW5nIHdpdGggdGhpcyBuZXcgc3RyaW5nLgoJICoKCSAqIFs8dGFibGU+Li4uXQoJICogOiBMaXN0IG9mIGRhdGFiYXNlIHRhYmxlcyB0byByZXN0cmljdCB0aGUgcmVwbGFjZW1lbnQgdG8uIFdpbGRjYXJkcyBhcmUKCSAqIHN1cHBvcnRlZCwgZS5nLiBgJ3dwXypvcHRpb25zJ2Agb3IgYCd3cF9wb3N0KidgLgoJICoKCSAqIFstLWRyeS1ydW5dCgkgKiA6IFJ1biB0aGUgZW50aXJlIHNlYXJjaC9yZXBsYWNlIG9wZXJhdGlvbiBhbmQgc2hvdyByZXBvcnQsIGJ1dCBkb24ndCBzYXZlCgkgKiBjaGFuZ2VzIHRvIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBTZWFyY2gvcmVwbGFjZSB0aHJvdWdoIGFsbCB0aGUgdGFibGVzIHJlZ2lzdGVyZWQgdG8gJHdwZGIgaW4gYQoJICogbXVsdGlzaXRlIGluc3RhbGwuCgkgKgoJICogWy0tYWxsLXRhYmxlcy13aXRoLXByZWZpeF0KCSAqIDogRW5hYmxlIHJlcGxhY2VtZW50IG9uIGFueSB0YWJsZXMgdGhhdCBtYXRjaCB0aGUgdGFibGUgcHJlZml4IGV2ZW4gaWYKCSAqIG5vdCByZWdpc3RlcmVkIG9uICR3cGRiLgoJICoKCSAqIFstLWFsbC10YWJsZXNdCgkgKiA6IEVuYWJsZSByZXBsYWNlbWVudCBvbiBBTEwgdGFibGVzIGluIHRoZSBkYXRhYmFzZSwgcmVnYXJkbGVzcyBvZiB0aGUKCSAqIHByZWZpeCwgYW5kIGV2ZW4gaWYgbm90IHJlZ2lzdGVyZWQgb24gJHdwZGIuIE92ZXJyaWRlcyAtLW5ldHdvcmsKCSAqIGFuZCAtLWFsbC10YWJsZXMtd2l0aC1wcmVmaXguCgkgKgoJICogWy0tZXhwb3J0Wz08ZmlsZT5dXQoJICogOiBXcml0ZSB0cmFuc2Zvcm1lZCBkYXRhIGFzIFNRTCBmaWxlIGluc3RlYWQgb2Ygc2F2aW5nIHJlcGxhY2VtZW50cyB0bwoJICogdGhlIGRhdGFiYXNlLiBJZiA8ZmlsZT4gaXMgbm90IHN1cHBsaWVkLCB3aWxsIG91dHB1dCB0byBTVERPVVQuCgkgKgoJICogWy0tZXhwb3J0X2luc2VydF9zaXplPTxyb3dzPl0KCSAqIDogRGVmaW5lIG51bWJlciBvZiByb3dzIGluIHNpbmdsZSBJTlNFUlQgc3RhdGVtZW50IHdoZW4gZG9pbmcgU1FMIGV4cG9ydC4KCSAqIFlvdSBtaWdodCB3YW50IHRvIGNoYW5nZSB0aGlzIGRlcGVuZGluZyBvbiB5b3VyIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24KCSAqIChlLmcuIGlmIHlvdSBuZWVkIHRvIGRvIGZld2VyIHF1ZXJpZXMpLiBEZWZhdWx0OiA1MAoJICoKCSAqIFstLXNraXAtdGFibGVzPTx0YWJsZXM+XQoJICogOiBEbyBub3QgcGVyZm9ybSB0aGUgcmVwbGFjZW1lbnQgb24gc3BlY2lmaWMgdGFibGVzLiBVc2UgY29tbWFzIHRvCgkgKiBzcGVjaWZ5IG11bHRpcGxlIHRhYmxlcy4gV2lsZGNhcmRzIGFyZSBzdXBwb3J0ZWQsIGUuZy4gYCd3cF8qb3B0aW9ucydgIG9yIGAnd3BfcG9zdConYC4KCSAqCgkgKiBbLS1za2lwLWNvbHVtbnM9PGNvbHVtbnM+XQoJICogOiBEbyBub3QgcGVyZm9ybSB0aGUgcmVwbGFjZW1lbnQgb24gc3BlY2lmaWMgY29sdW1ucy4gVXNlIGNvbW1hcyB0bwoJICogc3BlY2lmeSBtdWx0aXBsZSBjb2x1bW5zLgoJICoKCSAqIFstLWluY2x1ZGUtY29sdW1ucz08Y29sdW1ucz5dCgkgKiA6IFBlcmZvcm0gdGhlIHJlcGxhY2VtZW50IG9uIHNwZWNpZmljIGNvbHVtbnMuIFVzZSBjb21tYXMgdG8KCSAqIHNwZWNpZnkgbXVsdGlwbGUgY29sdW1ucy4KCSAqCgkgKiBbLS1wcmVjaXNlXQoJICogOiBGb3JjZSB0aGUgdXNlIG9mIFBIUCAoaW5zdGVhZCBvZiBTUUwpIHdoaWNoIGlzIG1vcmUgdGhvcm91Z2gsCgkgKiBidXQgc2xvd2VyLgoJICoKCSAqIFstLXJlY3Vyc2Utb2JqZWN0c10KCSAqIDogRW5hYmxlIHJlY3Vyc2luZyBpbnRvIG9iamVjdHMgdG8gcmVwbGFjZSBzdHJpbmdzLiBEZWZhdWx0cyB0byB0cnVlOwoJICogcGFzcyAtLW5vLXJlY3Vyc2Utb2JqZWN0cyB0byBkaXNhYmxlLgoJICoKCSAqIFstLXZlcmJvc2VdCgkgKiA6IFByaW50cyByb3dzIHRvIHRoZSBjb25zb2xlIGFzIHRoZXkncmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1yZWdleF0KCSAqIDogUnVucyB0aGUgc2VhcmNoIHVzaW5nIGEgcmVndWxhciBleHByZXNzaW9uICh3aXRob3V0IGRlbGltaXRlcnMpLgoJICogV2FybmluZzogc2VhcmNoLXJlcGxhY2Ugd2lsbCB0YWtlIGFib3V0IDE1LTIweCBsb25nZXIgd2hlbiB1c2luZyAtLXJlZ2V4LgoJICoKCSAqIFstLXJlZ2V4LWZsYWdzPTxyZWdleC1mbGFncz5dCgkgKiA6IFBhc3MgUENSRSBtb2RpZmllcnMgdG8gcmVnZXggc2VhcmNoLXJlcGxhY2UgKGUuZy4gJ2knIGZvciBjYXNlLWluc2Vuc2l0aXZpdHkpLgoJICoKCSAqIFstLXJlZ2V4LWRlbGltaXRlcj08cmVnZXgtZGVsaW1pdGVyPl0KCSAqIDogVGhlIGRlbGltaXRlciB0byB1c2UgZm9yIHRoZSByZWdleC4gSXQgbXVzdCBiZSBlc2NhcGVkIGlmIGl0IGFwcGVhcnMgaW4gdGhlIHNlYXJjaCBzdHJpbmcuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSByZXN1bHQgb2YgYGNocigxKWAuCgkgKgoJICogWy0tcmVnZXgtbGltaXQ9PHJlZ2V4LWxpbWl0Pl0KCSAqIDogVGhlIG1heGltdW0gcG9zc2libGUgcmVwbGFjZW1lbnRzIGZvciB0aGUgcmVnZXggcGVyIHJvdyAob3IgcGVyIHVuc2VyaWFsaXplZCBkYXRhIGJpdCBwZXIgcm93KS4gRGVmYXVsdHMgdG8gLTEgKG5vIGxpbWl0KS4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjb3VudAoJICogLS0tCgkgKgoJICogWy0tcmVwb3J0XQoJICogOiBQcm9kdWNlIHJlcG9ydC4gRGVmYXVsdHMgdG8gdHJ1ZS4KCSAqCgkgKiBbLS1yZXBvcnQtY2hhbmdlZC1vbmx5XQoJICogOiBSZXBvcnQgY2hhbmdlZCBmaWVsZHMgb25seS4gRGVmYXVsdHMgdG8gZmFsc2UsIHVubGVzcyBsb2dnaW5nLCB3aGVuIGl0IGRlZmF1bHRzIHRvIHRydWUuCgkgKgoJICogWy0tbG9nWz08ZmlsZT5dXQoJICogOiBMb2cgdGhlIGl0ZW1zIGNoYW5nZWQuIElmIDxmaWxlPiBpcyBub3Qgc3VwcGxpZWQgb3IgaXMgIi0iLCB3aWxsIG91dHB1dCB0byBTVERPVVQuCgkgKiBXYXJuaW5nOiBjYXVzZXMgYSBzaWduaWZpY2FudCBzbG93IGRvd24sIHNpbWlsYXIgb3Igd29yc2UgdG8gZW5hYmxpbmcgLS1wcmVjaXNlIG9yIC0tcmVnZXguCgkgKgoJICogWy0tYmVmb3JlX2NvbnRleHQ9PG51bT5dCgkgKiA6IEZvciBsb2dnaW5nLCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGJlZm9yZSB0aGUgb2xkIG1hdGNoIGFuZCB0aGUgbmV3IHJlcGxhY2VtZW50LiBEZWZhdWx0IDQwLiBJZ25vcmVkIGlmIG5vdCBsb2dnaW5nLgoJICoKCSAqIFstLWFmdGVyX2NvbnRleHQ9PG51bT5dCgkgKiA6IEZvciBsb2dnaW5nLCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBkaXNwbGF5IGFmdGVyIHRoZSBvbGQgbWF0Y2ggYW5kIHRoZSBuZXcgcmVwbGFjZW1lbnQuIERlZmF1bHQgNDAuIElnbm9yZWQgaWYgbm90IGxvZ2dpbmcuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTZWFyY2ggYW5kIHJlcGxhY2UgYnV0IHNraXAgb25lIGNvbHVtbgoJICogICAgICQgd3Agc2VhcmNoLXJlcGxhY2UgJ2h0dHA6Ly9leGFtcGxlLnRlc3QnICdodHRwOi8vZXhhbXBsZS5jb20nIC0tc2tpcC1jb2x1bW5zPWd1aWQKCSAqCgkgKiAgICAgIyBSdW4gc2VhcmNoL3JlcGxhY2Ugb3BlcmF0aW9uIGJ1dCBkb250IHNhdmUgaW4gZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlICdmb28nICdiYXInIHdwX3Bvc3RzIHdwX3Bvc3RtZXRhIHdwX3Rlcm1zIC0tZHJ5LXJ1bgoJICoKCSAqICAgICAjIFJ1biBjYXNlLWluc2Vuc2l0aXZlIHJlZ2V4IHNlYXJjaC9yZXBsYWNlIG9wZXJhdGlvbiAoc2xvdykKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlICdcW2ZvbyBpZD0iKFswLTldKykiJyAnW2JhciBpZD0iXDEiJyAtLXJlZ2V4IC0tcmVnZXgtZmxhZ3M9J2knCgkgKgoJICogICAgICMgVHVybiB5b3VyIHByb2R1Y3Rpb24gbXVsdGlzaXRlIGRhdGFiYXNlIGludG8gYSBsb2NhbCBkZXYgZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlIC0tdXJsPWV4YW1wbGUuY29tIGV4YW1wbGUuY29tIGV4YW1wbGUudGVzdCAnd3BfKm9wdGlvbnMnIHdwX2Jsb2dzCgkgKgoJICogICAgICMgU2VhcmNoL3JlcGxhY2UgdG8gYSBTUUwgZmlsZSB3aXRob3V0IHRyYW5zZm9ybWluZyB0aGUgZGF0YWJhc2UKCSAqICAgICAkIHdwIHNlYXJjaC1yZXBsYWNlIGZvbyBiYXIgLS1leHBvcnQ9ZGF0YWJhc2Uuc3FsCgkgKgoJICogICAgICMgQmFzaCBzY3JpcHQ6IFNlYXJjaC9yZXBsYWNlIHByb2R1Y3Rpb24gdG8gZGV2ZWxvcG1lbnQgdXJsIChtdWx0aXNpdGUgY29tcGF0aWJsZSkKCSAqICAgICAjIS9iaW4vYmFzaAoJICogICAgIGlmICQod3AgLS11cmw9aHR0cDovL2V4YW1wbGUuY29tIGNvcmUgaXMtaW5zdGFsbGVkIC0tbmV0d29yayk7IHRoZW4KCSAqICAgICAgICAgd3Agc2VhcmNoLXJlcGxhY2UgLS11cmw9aHR0cDovL2V4YW1wbGUuY29tICdodHRwOi8vZXhhbXBsZS5jb20nICdodHRwOi8vZXhhbXBsZS50ZXN0JyAtLXJlY3Vyc2Utb2JqZWN0cyAtLW5ldHdvcmsgLS1za2lwLWNvbHVtbnM9Z3VpZCAtLXNraXAtdGFibGVzPXdwX3VzZXJzCgkgKiAgICAgZWxzZQoJICogICAgICAgICB3cCBzZWFyY2gtcmVwbGFjZSAnaHR0cDovL2V4YW1wbGUuY29tJyAnaHR0cDovL2V4YW1wbGUudGVzdCcgLS1yZWN1cnNlLW9iamVjdHMgLS1za2lwLWNvbHVtbnM9Z3VpZCAtLXNraXAtdGFibGVzPXdwX3VzZXJzCgkgKiAgICAgZmkKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cGRiOwoJCSRvbGQgICAgICAgICAgICAgICAgICAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkbmV3ICAgICAgICAgICAgICAgICAgID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJHRvdGFsICAgICAgICAgICAgICAgICA9IDA7CgkJJHJlcG9ydCAgICAgICAgICAgICAgICA9IGFycmF5KCk7CgkJJHRoaXMtPmRyeV9ydW4gICAgICAgICA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZHJ5LXJ1bicgKTsKCQkkcGhwX29ubHkgICAgICAgICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdwcmVjaXNlJyApOwoJCSR0aGlzLT5yZWN1cnNlX29iamVjdHMgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3JlY3Vyc2Utb2JqZWN0cycsIHRydWUgKTsKCQkkdGhpcy0+dmVyYm9zZSAgICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd2ZXJib3NlJyApOwoJCSR0aGlzLT5mb3JtYXQgICAgICAgICAgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2Zvcm1hdCcgKTsKCQkkdGhpcy0+cmVnZXggICAgICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleCcsIGZhbHNlICk7CgoJCWlmICggbnVsbCAhPT0gJHRoaXMtPnJlZ2V4ICkgewoJCQkkZGVmYXVsdF9yZWdleF9kZWxpbWl0ZXIgPSBmYWxzZTsKCQkJJHRoaXMtPnJlZ2V4X2ZsYWdzICAgICAgID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleC1mbGFncycsIGZhbHNlICk7CgkJCSR0aGlzLT5yZWdleF9kZWxpbWl0ZXIgICA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAncmVnZXgtZGVsaW1pdGVyJywgJycgKTsKCQkJaWYgKCAnJyA9PT0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlciApIHsKCQkJCSR0aGlzLT5yZWdleF9kZWxpbWl0ZXIgICA9IGNociggMSApOwoJCQkJJGRlZmF1bHRfcmVnZXhfZGVsaW1pdGVyID0gdHJ1ZTsKCQkJfQoJCX0KCgkJJHJlZ2V4X2xpbWl0ID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZWdleC1saW1pdCcgKTsKCQlpZiAoIG51bGwgIT09ICRyZWdleF9saW1pdCApIHsKCQkJaWYgKCAhIHByZWdfbWF0Y2goICcvXig/OlswLTldK3wtMSkkLycsICRyZWdleF9saW1pdCApIHx8IDAgPT09IChpbnQpICRyZWdleF9saW1pdCApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdgLS1yZWdleC1saW1pdGAgZXhwZWN0cyBhIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXIgb3IgLTEuJyApOwoJCQl9CgkJCSR0aGlzLT5yZWdleF9saW1pdCA9IChpbnQpICRyZWdleF9saW1pdDsKCQl9CgoJCWlmICggISBlbXB0eSggJHRoaXMtPnJlZ2V4ICkgKSB7CgkJCWlmICggJycgPT09ICR0aGlzLT5yZWdleF9kZWxpbWl0ZXIgKSB7CgkJCQkkdGhpcy0+cmVnZXhfZGVsaW1pdGVyID0gY2hyKCAxICk7CgkJCX0KCQkJJHNlYXJjaF9yZWdleCAgPSAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyOwoJCQkkc2VhcmNoX3JlZ2V4IC49ICRvbGQ7CgkJCSRzZWFyY2hfcmVnZXggLj0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJJHNlYXJjaF9yZWdleCAuPSAkdGhpcy0+cmVnZXhfZmxhZ3M7CgoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5Ob1NpbGVuY2VkRXJyb3JzLkRpc2NvdXJhZ2VkIC0tIFByZXZlbnRpbmcgYSB3YXJuaW5nIHdoZW4gdGVzdGluZyB0aGUgcmVnZXguCgkJCWlmICggZmFsc2UgPT09IEBwcmVnX21hdGNoKCAkc2VhcmNoX3JlZ2V4LCAnJyApICkgewoJCQkJJGVycm9yICAgICAgICAgICAgICA9IGVycm9yX2dldF9sYXN0KCk7CgkJCQkkcHJlZ19lcnJvcl9tZXNzYWdlID0gKCAhIGVtcHR5KCAkZXJyb3IgKSAmJiBhcnJheV9rZXlfZXhpc3RzKCAnbWVzc2FnZScsICRlcnJvciApICkgPyAiXG57JGVycm9yWydtZXNzYWdlJ119LiIgOiAnJzsKCQkJCWlmICggJGRlZmF1bHRfcmVnZXhfZGVsaW1pdGVyICkgewoJCQkJCSRmbGFnc19tc2cgPSAkdGhpcy0+cmVnZXhfZmxhZ3MgPyAiZmxhZ3MgJyR0aGlzLT5yZWdleF9mbGFncyciIDogJ25vIGZsYWdzJzsKCQkJCQkkbXNnICAgICAgID0gIlRoZSByZWdleCBwYXR0ZXJuICckb2xkJyB3aXRoIGRlZmF1bHQgZGVsaW1pdGVyICdjaHIoMSknIGFuZCB7JGZsYWdzX21zZ30gZmFpbHMuIjsKCQkJCX0gZWxzZSB7CgkJCQkJJG1zZyA9ICJUaGUgcmVnZXggJyRzZWFyY2hfcmVnZXgnIGZhaWxzLiI7CgkJCQl9CgkJCQlXUF9DTEk6OmVycm9yKCAkbXNnIC4gJHByZWdfZXJyb3JfbWVzc2FnZSApOwoJCQl9CgkJfQoKCQkkdGhpcy0+c2tpcF9jb2x1bW5zICAgID0gZXhwbG9kZSggJywnLCBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtY29sdW1ucycgKSApOwoJCSR0aGlzLT5za2lwX3RhYmxlcyAgICAgPSBleHBsb2RlKCAnLCcsIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC10YWJsZXMnICkgKTsKCQkkdGhpcy0+aW5jbHVkZV9jb2x1bW5zID0gYXJyYXlfZmlsdGVyKCBleHBsb2RlKCAnLCcsIFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5jbHVkZS1jb2x1bW5zJyApICkgKTsKCgkJaWYgKCAkb2xkID09PSAkbmV3ICYmICEgJHRoaXMtPnJlZ2V4ICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJSZXBsYWNlbWVudCB2YWx1ZSAneyRvbGR9JyBpcyBpZGVudGljYWwgdG8gc2VhcmNoIHZhbHVlICd7JG5ld30nLiBTa2lwcGluZyBvcGVyYXRpb24uIiApOwoJCQlleGl0OwoJCX0KCgkJJGV4cG9ydCA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZXhwb3J0JyApOwoJCWlmICggbnVsbCAhPT0gJGV4cG9ydCApIHsKCQkJaWYgKCAkdGhpcy0+ZHJ5X3J1biApIHsKCQkJCVdQX0NMSTo6ZXJyb3IoICdZb3UgY2Fubm90IHN1cHBseSAtLWRyeS1ydW4gYW5kIC0tZXhwb3J0IGF0IHRoZSBzYW1lIHRpbWUuJyApOwoJCQl9CgkJCWlmICggdHJ1ZSA9PT0gJGV4cG9ydCApIHsKCQkJCSR0aGlzLT5leHBvcnRfaGFuZGxlID0gU1RET1VUOwoJCQkJJHRoaXMtPnZlcmJvc2UgICAgICAgPSBmYWxzZTsKCQkJfSBlbHNlIHsKCQkJCSR0aGlzLT5leHBvcnRfaGFuZGxlID0gQGZvcGVuKCAkYXNzb2NfYXJnc1snZXhwb3J0J10sICd3JyApOwoJCQkJaWYgKCBmYWxzZSA9PT0gJHRoaXMtPmV4cG9ydF9oYW5kbGUgKSB7CgkJCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnVW5hYmxlIHRvIG9wZW4gZXhwb3J0IGZpbGUgIiVzIiBmb3Igd3JpdGluZzogJXMuJywgJGFzc29jX2FyZ3NbJ2V4cG9ydCddLCAkZXJyb3JbJ21lc3NhZ2UnXSApICk7CgkJCQl9CgkJCX0KCQkJJGV4cG9ydF9pbnNlcnRfc2l6ZSA9IFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdleHBvcnRfaW5zZXJ0X3NpemUnLCA1MCApOwoJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5TdHJpY3RDb21wYXJpc29ucy5Mb29zZUNvbXBhcmlzb24gLS0gU2VlIHRoZSBjb2RlLCB0aGlzIGlzIGRlbGliZXJhdGUuCgkJCWlmICggKGludCkgJGV4cG9ydF9pbnNlcnRfc2l6ZSA9PSAkZXhwb3J0X2luc2VydF9zaXplICYmICRleHBvcnRfaW5zZXJ0X3NpemUgPiAwICkgewoJCQkJJHRoaXMtPmV4cG9ydF9pbnNlcnRfc2l6ZSA9ICRleHBvcnRfaW5zZXJ0X3NpemU7CgkJCX0KCQkJJHBocF9vbmx5ID0gdHJ1ZTsKCQl9CgoJCSRsb2cgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2xvZycgKTsKCQlpZiAoIG51bGwgIT09ICRsb2cgKSB7CgkJCWlmICggdHJ1ZSA9PT0gJGxvZyB8fCAnLScgPT09ICRsb2cgKSB7CgkJCQkkdGhpcy0+bG9nX2hhbmRsZSA9IFNURE9VVDsKCQkJfSBlbHNlIHsKCQkJCSR0aGlzLT5sb2dfaGFuZGxlID0gQGZvcGVuKCAkYXNzb2NfYXJnc1snbG9nJ10sICd3JyApOwoJCQkJaWYgKCBmYWxzZSA9PT0gJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkJJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKCQkJCQlXUF9DTEk6OmVycm9yKCBzcHJpbnRmKCAnVW5hYmxlIHRvIG9wZW4gbG9nIGZpbGUgIiVzIiBmb3Igd3JpdGluZzogJXMuJywgJGFzc29jX2FyZ3NbJ2xvZyddLCAkZXJyb3JbJ21lc3NhZ2UnXSApICk7CgkJCQl9CgkJCX0KCQkJaWYgKCAkdGhpcy0+bG9nX2hhbmRsZSApIHsKCQkJCSRiZWZvcmVfY29udGV4dCA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYmVmb3JlX2NvbnRleHQnICk7CgkJCQlpZiAoIG51bGwgIT09ICRiZWZvcmVfY29udGV4dCAmJiBwcmVnX21hdGNoKCAnL15bMC05XSskLycsICRiZWZvcmVfY29udGV4dCApICkgewoJCQkJCSR0aGlzLT5sb2dfYmVmb3JlX2NvbnRleHQgPSAoaW50KSAkYmVmb3JlX2NvbnRleHQ7CgkJCQl9CgoJCQkJJGFmdGVyX2NvbnRleHQgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FmdGVyX2NvbnRleHQnICk7CgkJCQlpZiAoIG51bGwgIT09ICRhZnRlcl9jb250ZXh0ICYmIHByZWdfbWF0Y2goICcvXlswLTldKyQvJywgJGFmdGVyX2NvbnRleHQgKSApIHsKCQkJCQkkdGhpcy0+bG9nX2FmdGVyX2NvbnRleHQgPSAoaW50KSAkYWZ0ZXJfY29udGV4dDsKCQkJCX0KCgkJCQkkbG9nX3ByZWZpeGVzID0gZ2V0ZW52KCAnV1BfQ0xJX1NFQVJDSF9SRVBMQUNFX0xPR19QUkVGSVhFUycgKTsKCQkJCWlmICggZmFsc2UgIT09ICRsb2dfcHJlZml4ZXMgJiYgcHJlZ19tYXRjaCggJy9eKFteLF0qKSwoW14sXSopJC8nLCAkbG9nX3ByZWZpeGVzLCAkbWF0Y2hlcyApICkgewoJCQkJCSR0aGlzLT5sb2dfcHJlZml4ZXMgPSBhcnJheSggJG1hdGNoZXNbMV0sICRtYXRjaGVzWzJdICk7CgkJCQl9CgoJCQkJaWYgKCBTVERPVVQgPT09ICR0aGlzLT5sb2dfaGFuZGxlICkgewoJCQkJCSRkZWZhdWx0X2xvZ19jb2xvcnMgPSBhcnJheSgKCQkJCQkJJ2xvZ190YWJsZV9jb2x1bW5faWQnID0+ICclQicsCgkJCQkJCSdsb2dfb2xkJyAgICAgICAgICAgICA9PiAnJVInLAoJCQkJCQknbG9nX25ldycgICAgICAgICAgICAgPT4gJyVHJywKCQkJCQkpOwoJCQkJfSBlbHNlIHsKCQkJCQkkZGVmYXVsdF9sb2dfY29sb3JzID0gYXJyYXkoCgkJCQkJCSdsb2dfdGFibGVfY29sdW1uX2lkJyA9PiAnJywKCQkJCQkJJ2xvZ19vbGQnICAgICAgICAgICAgID0+ICcnLAoJCQkJCQknbG9nX25ldycgICAgICAgICAgICAgPT4gJycsCgkJCQkJKTsKCQkJCX0KCgkJCQkkbG9nX2NvbG9ycyA9IGdldGVudiggJ1dQX0NMSV9TRUFSQ0hfUkVQTEFDRV9MT0dfQ09MT1JTJyApOwoJCQkJaWYgKCBmYWxzZSAhPT0gJGxvZ19jb2xvcnMgJiYgcHJlZ19tYXRjaCggJy9eKFteLF0qKSwoW14sXSopLChbXixdKikkLycsICRsb2dfY29sb3JzLCAkbWF0Y2hlcyApICkgewoJCQkJCSRkZWZhdWx0X2xvZ19jb2xvcnMgPSBhcnJheSgKCQkJCQkJJ2xvZ190YWJsZV9jb2x1bW5faWQnID0+ICRtYXRjaGVzWzFdLAoJCQkJCQknbG9nX29sZCcgICAgICAgICAgICAgPT4gJG1hdGNoZXNbMl0sCgkJCQkJCSdsb2dfbmV3JyAgICAgICAgICAgICA9PiAkbWF0Y2hlc1szXSwKCQkJCQkpOwoJCQkJfQoKCQkJCSR0aGlzLT5sb2dfY29sb3JzICAgPSBzZWxmOjpnZXRfY29sb3JzKCAkYXNzb2NfYXJncywgJGRlZmF1bHRfbG9nX2NvbG9ycyApOwoJCQkJJHRoaXMtPmxvZ19lbmNvZGluZyA9IDAgPT09IHN0cnBvcyggJHdwZGItPmNoYXJzZXQsICd1dGY4JyApID8gJ1VURi04JyA6IGZhbHNlOwoJCQl9CgkJfQoKCQkkdGhpcy0+cmVwb3J0ID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZXBvcnQnLCB0cnVlICk7CgkJLy8gRGVmYXVsdHMgdG8gdHJ1ZSBpZiBsb2dnaW5nLCBlbHNlIGRlZmF1bHRzIHRvIGZhbHNlLgoJCSR0aGlzLT5yZXBvcnRfY2hhbmdlZF9vbmx5ID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdyZXBvcnQtY2hhbmdlZC1vbmx5JywgbnVsbCAhPT0gJHRoaXMtPmxvZ19oYW5kbGUgKTsKCgkJaWYgKCAkdGhpcy0+cmVnZXhfZmxhZ3MgKSB7CgkJCSRwaHBfb25seSA9IHRydWU7CgkJfQoKCQkvLyBuZXZlciBtZXNzIHdpdGggaGFzaGVkIHBhc3N3b3JkcwoJCSR0aGlzLT5za2lwX2NvbHVtbnNbXSA9ICd1c2VyX3Bhc3MnOwoKCQkvLyBHZXQgdGFibGUgbmFtZXMgYmFzZWQgb24gbGVmdG92ZXIgJGFyZ3Mgb3Igc3VwcGxpZWQgJGFzc29jX2FyZ3MKCQkkdGFibGVzID0gXFdQX0NMSVxVdGlsc1x3cF9nZXRfdGFibGVfbmFtZXMoICRhcmdzLCAkYXNzb2NfYXJncyApOwoKCQlmb3JlYWNoICggJHRhYmxlcyBhcyAkdGFibGUgKSB7CgoJCQlmb3JlYWNoICggJHRoaXMtPnNraXBfdGFibGVzIGFzICRza2lwX3RhYmxlICkgewoJCQkJaWYgKCBmbm1hdGNoKCAkc2tpcF90YWJsZSwgJHRhYmxlICkgKSB7CgkJCQkJY29udGludWUgMjsKCQkJCX0KCQkJfQoKCQkJJHRhYmxlX3NxbCA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICR0YWJsZSApOwoKCQkJaWYgKCAkdGhpcy0+ZXhwb3J0X2hhbmRsZSApIHsKCQkJCWZ3cml0ZSggJHRoaXMtPmV4cG9ydF9oYW5kbGUsICJcbkRST1AgVEFCTEUgSUYgRVhJU1RTICR0YWJsZV9zcWw7XG4iICk7CgoJCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5JbnRlcnBvbGF0ZWROb3RQcmVwYXJlZCAtLSBlc2NhcGVkIHRocm91Z2ggc2VsZjo6ZXNjX3NxbF9pZGVudAoJCQkJJHJvdyA9ICR3cGRiLT5nZXRfcm93KCAiU0hPVyBDUkVBVEUgVEFCTEUgJHRhYmxlX3NxbCIsIEFSUkFZX04gKTsKCgkJCQlmd3JpdGUoICR0aGlzLT5leHBvcnRfaGFuZGxlLCAkcm93WzFdIC4gIjtcbiIgKTsKCQkJCWxpc3QoICR0YWJsZV9yZXBvcnQsICR0b3RhbF9yb3dzICkgPSAkdGhpcy0+cGhwX2V4cG9ydF90YWJsZSggJHRhYmxlLCAkb2xkLCAkbmV3ICk7CgkJCQlpZiAoICR0aGlzLT5yZXBvcnQgKSB7CgkJCQkJJHJlcG9ydCA9IGFycmF5X21lcmdlKCAkcmVwb3J0LCAkdGFibGVfcmVwb3J0ICk7CgkJCQl9CgkJCQkkdG90YWwgKz0gJHRvdGFsX3Jvd3M7CgkJCQkvLyBEb24ndCBwZXJmb3JtIHJlcGxhY2VtZW50cyBvbiB0aGUgYWN0dWFsIGRhdGFiYXNlCgkJCQljb250aW51ZTsKCQkJfQoKCQkJbGlzdCggJHByaW1hcnlfa2V5cywgJGNvbHVtbnMsICRhbGxfY29sdW1ucyApID0gc2VsZjo6Z2V0X2NvbHVtbnMoICR0YWJsZSApOwoKCQkJLy8gc2luY2Ugd2UnbGwgYmUgdXBkYXRpbmcgb25lIHJvdyBhdCBhIHRpbWUsCgkJCS8vIHdlIG5lZWQgYSBwcmltYXJ5IGtleSB0byBpZGVudGlmeSB0aGUgcm93CgkJCWlmICggZW1wdHkoICRwcmltYXJ5X2tleXMgKSApIHsKCgkJCQkvLyB3YXNuJ3QgdXBkYXRlZCwgc28gc2tpcCB0byB0aGUgbmV4dCB0YWJsZQoJCQkJaWYgKCAkdGhpcy0+cmVwb3J0X2NoYW5nZWRfb25seSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWlmICggJHRoaXMtPnJlcG9ydCApIHsKCQkJCQkkcmVwb3J0W10gPSBhcnJheSggJHRhYmxlLCAnJywgJ3NraXBwZWQnLCAnJyApOwoJCQkJfSBlbHNlIHsKCQkJCQlXUF9DTEk6Ondhcm5pbmcoICRhbGxfY29sdW1ucyA/ICJObyBwcmltYXJ5IGtleXMgZm9yIHRhYmxlICckdGFibGUnLiIgOiAiTm8gc3VjaCB0YWJsZSAnJHRhYmxlJy4iICk7CgkJCQl9CgkJCQljb250aW51ZTsKCQkJfQoKCQkJZm9yZWFjaCAoICRjb2x1bW5zIGFzICRjb2wgKSB7CgkJCQlpZiAoICEgZW1wdHkoICR0aGlzLT5pbmNsdWRlX2NvbHVtbnMgKSAmJiAhIGluX2FycmF5KCAkY29sLCAkdGhpcy0+aW5jbHVkZV9jb2x1bW5zLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCBpbl9hcnJheSggJGNvbCwgJHRoaXMtPnNraXBfY29sdW1ucywgdHJ1ZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggJHRoaXMtPnZlcmJvc2UgJiYgJ2NvdW50JyAhPT0gJHRoaXMtPmZvcm1hdCApIHsKCQkJCQkkdGhpcy0+c3RhcnRfdGltZSA9IG1pY3JvdGltZSggdHJ1ZSApOwoJCQkJCVdQX0NMSTo6bG9nKCBzcHJpbnRmKCAnQ2hlY2tpbmc6ICVzLiVzJywgJHRhYmxlLCAkY29sICkgKTsKCQkJCX0KCgkJCQlpZiAoICEgJHBocF9vbmx5ICYmICEgJHRoaXMtPnJlZ2V4ICkgewoJCQkJCSRjb2xfc3FsICAgICAgICAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbCApOwoJCQkJCSR3cGRiLT5sYXN0X2Vycm9yID0gJyc7CgoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJCQkkc2VyaWFsX3JvdyA9ICR3cGRiLT5nZXRfcm93KCAiU0VMRUNUICogRlJPTSAkdGFibGVfc3FsIFdIRVJFICRjb2xfc3FsIFJFR0VYUCAnXlthaU9dOlsxLTldJyBMSU1JVCAxIiApOwoKCQkJCQkvLyBXaGVuIHRoZSByZWdleCB0cmlnZ2VycyBhbiBlcnJvciwgd2Ugc2hvdWxkIGZhbGwgYmFjayB0byBQSFAKCQkJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICR3cGRiLT5sYXN0X2Vycm9yLCAnRVJST1IgMTEzOScgKSApIHsKCQkJCQkJJHNlcmlhbF9yb3cgPSB0cnVlOwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoICRwaHBfb25seSB8fCAkdGhpcy0+cmVnZXggfHwgbnVsbCAhPT0gJHNlcmlhbF9yb3cgKSB7CgkJCQkJJHR5cGUgID0gJ1BIUCc7CgkJCQkJJGNvdW50ID0gJHRoaXMtPnBocF9oYW5kbGVfY29sKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJHR5cGUgID0gJ1NRTCc7CgkJCQkJJGNvdW50ID0gJHRoaXMtPnNxbF9oYW5kbGVfY29sKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKTsKCQkJCX0KCgkJCQlpZiAoICR0aGlzLT5yZXBvcnQgJiYgKCAkY291bnQgfHwgISAkdGhpcy0+cmVwb3J0X2NoYW5nZWRfb25seSApICkgewoJCQkJCSRyZXBvcnRbXSA9IGFycmF5KCAkdGFibGUsICRjb2wsICRjb3VudCwgJHR5cGUgKTsKCQkJCX0KCgkJCQkkdG90YWwgKz0gJGNvdW50OwoJCQl9CgkJfQoKCQlpZiAoICR0aGlzLT5leHBvcnRfaGFuZGxlICYmIFNURE9VVCAhPT0gJHRoaXMtPmV4cG9ydF9oYW5kbGUgKSB7CgkJCWZjbG9zZSggJHRoaXMtPmV4cG9ydF9oYW5kbGUgKTsKCQl9CgoJCS8vIE9ubHkgaW5mb3JtYXRpb25hbCBvdXRwdXQgYWZ0ZXIgdGhpcyBwb2ludAoJCWlmICggV1BfQ0xJOjpnZXRfY29uZmlnKCAncXVpZXQnICkgfHwgU1RET1VUID09PSAkdGhpcy0+ZXhwb3J0X2hhbmRsZSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCAnY291bnQnID09PSAkdGhpcy0+Zm9ybWF0ICkgewoJCQlXUF9DTEk6OmxpbmUoICR0b3RhbCApOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoICR0aGlzLT5yZXBvcnQgJiYgISBlbXB0eSggJHJlcG9ydCApICkgewoJCQkkdGFibGUgPSBuZXcgXGNsaVxUYWJsZSgpOwoJCQkkdGFibGUtPnNldEhlYWRlcnMoIGFycmF5KCAnVGFibGUnLCAnQ29sdW1uJywgJ1JlcGxhY2VtZW50cycsICdUeXBlJyApICk7CgkJCSR0YWJsZS0+c2V0Um93cyggJHJlcG9ydCApOwoJCQkkdGFibGUtPmRpc3BsYXkoKTsKCQl9CgoJCWlmICggISAkdGhpcy0+ZHJ5X3J1biApIHsKCQkJaWYgKCAhIGVtcHR5KCAkYXNzb2NfYXJnc1snZXhwb3J0J10gKSApIHsKCQkJCSRzdWNjZXNzX21lc3NhZ2UgPSAxID09PSAkdG90YWwgPyAiTWFkZSAxIHJlcGxhY2VtZW50IGFuZCBleHBvcnRlZCB0byB7JGFzc29jX2FyZ3NbJ2V4cG9ydCddfS4iIDogIk1hZGUgeyR0b3RhbH0gcmVwbGFjZW1lbnRzIGFuZCBleHBvcnRlZCB0byB7JGFzc29jX2FyZ3NbJ2V4cG9ydCddfS4iOwoJCQl9IGVsc2UgewoJCQkJJHN1Y2Nlc3NfbWVzc2FnZSA9IDEgPT09ICR0b3RhbCA/ICdNYWRlIDEgcmVwbGFjZW1lbnQuJyA6ICJNYWRlICR0b3RhbCByZXBsYWNlbWVudHMuIjsKCQkJCWlmICggJHRvdGFsICYmICdEZWZhdWx0JyAhPT0gV1BfQ0xJXFV0aWxzXHdwX2dldF9jYWNoZV90eXBlKCkgKSB7CgkJCQkJJHN1Y2Nlc3NfbWVzc2FnZSAuPSAnIFBsZWFzZSByZW1lbWJlciB0byBmbHVzaCB5b3VyIHBlcnNpc3RlbnQgb2JqZWN0IGNhY2hlIHdpdGggYHdwIGNhY2hlIGZsdXNoYC4nOwoJCQkJfQoJCQl9CgkJCVdQX0NMSTo6c3VjY2VzcyggJHN1Y2Nlc3NfbWVzc2FnZSApOwoJCX0gZWxzZSB7CgkJCSRzdWNjZXNzX21lc3NhZ2UgPSAoIDEgPT09ICR0b3RhbCApID8gJyVkIHJlcGxhY2VtZW50IHRvIGJlIG1hZGUuJyA6ICclZCByZXBsYWNlbWVudHMgdG8gYmUgbWFkZS4nOwoJCQlXUF9DTEk6OnN1Y2Nlc3MoIHNwcmludGYoICRzdWNjZXNzX21lc3NhZ2UsICR0b3RhbCApICk7CgkJfQoJfQoKCXByaXZhdGUgZnVuY3Rpb24gcGhwX2V4cG9ydF90YWJsZSggJHRhYmxlLCAkb2xkLCAkbmV3ICkgewoJCWxpc3QoICRwcmltYXJ5X2tleXMsICRjb2x1bW5zLCAkYWxsX2NvbHVtbnMgKSA9IHNlbGY6OmdldF9jb2x1bW5zKCAkdGFibGUgKTsKCgkJJGNodW5rX3NpemUgPSBnZXRlbnYoICdCRUhBVF9SVU4nICkgPyAxMCA6IDEwMDA7CgkJJGFyZ3MgICAgICAgPSBhcnJheSgKCQkJJ3RhYmxlJyAgICAgID0+ICR0YWJsZSwKCQkJJ2ZpZWxkcycgICAgID0+ICRhbGxfY29sdW1ucywKCQkJJ2NodW5rX3NpemUnID0+ICRjaHVua19zaXplLAoJCSk7CgoJCSRyZXBsYWNlciAgID0gbmV3IFxXUF9DTElcU2VhcmNoUmVwbGFjZXIoICRvbGQsICRuZXcsICR0aGlzLT5yZWN1cnNlX29iamVjdHMsICR0aGlzLT5yZWdleCwgJHRoaXMtPnJlZ2V4X2ZsYWdzLCAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyLCBmYWxzZSwgJHRoaXMtPnJlZ2V4X2xpbWl0ICk7CgkJJGNvbF9jb3VudHMgPSBhcnJheV9maWxsX2tleXMoICRhbGxfY29sdW1ucywgMCApOwoJCWlmICggJHRoaXMtPnZlcmJvc2UgJiYgJ3RhYmxlJyA9PT0gJHRoaXMtPmZvcm1hdCApIHsKCQkJJHRoaXMtPnN0YXJ0X3RpbWUgPSBtaWNyb3RpbWUoIHRydWUgKTsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICdDaGVja2luZzogJXMnLCAkdGFibGUgKSApOwoJCX0KCgkJJHJvd3MgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCBuZXcgXFdQX0NMSVxJdGVyYXRvcnNcVGFibGUoICRhcmdzICkgYXMgJGkgPT4gJHJvdyApIHsKCQkJJHJvd19maWVsZHMgPSBhcnJheSgpOwoJCQlmb3JlYWNoICggJGFsbF9jb2x1bW5zIGFzICRjb2wgKSB7CgkJCQkkdmFsdWUgPSAkcm93LT4kY29sOwoJCQkJaWYgKCAkdmFsdWUgJiYgISBpbl9hcnJheSggJGNvbCwgJHByaW1hcnlfa2V5cywgdHJ1ZSApICYmICEgaW5fYXJyYXkoICRjb2wsICR0aGlzLT5za2lwX2NvbHVtbnMsIHRydWUgKSApIHsKCQkJCQkkbmV3X3ZhbHVlID0gJHJlcGxhY2VyLT5ydW4oICR2YWx1ZSApOwoJCQkJCWlmICggJG5ld192YWx1ZSAhPT0gJHZhbHVlICkgewoJCQkJCQkkY29sX2NvdW50c1sgJGNvbCBdKys7CgkJCQkJCSR2YWx1ZSA9ICRuZXdfdmFsdWU7CgkJCQkJfQoJCQkJfQoJCQkJJHJvd19maWVsZHNbICRjb2wgXSA9ICR2YWx1ZTsKCQkJfQoJCQkkcm93c1tdID0gJHJvd19maWVsZHM7CgkJfQoJCSR0aGlzLT53cml0ZV9zcWxfcm93X2ZpZWxkcyggJHRhYmxlLCAkcm93cyApOwoKCQkkdGFibGVfcmVwb3J0ID0gYXJyYXkoKTsKCQkkdG90YWxfcm93cyAgID0gMDsKCQkkdG90YWxfY29scyAgID0gMDsKCQlmb3JlYWNoICggJGNvbF9jb3VudHMgYXMgJGNvbCA9PiAkY29sX2NvdW50ICkgewoJCQlpZiAoICR0aGlzLT5yZXBvcnQgJiYgKCAkY29sX2NvdW50IHx8ICEgJHRoaXMtPnJlcG9ydF9jaGFuZ2VkX29ubHkgKSApIHsKCQkJCSR0YWJsZV9yZXBvcnRbXSA9IGFycmF5KCAkdGFibGUsICRjb2wsICRjb2xfY291bnQsICdQSFAnICk7CgkJCX0KCQkJaWYgKCAkY29sX2NvdW50ICkgewoJCQkJJHRvdGFsX2NvbHMrKzsKCQkJCSR0b3RhbF9yb3dzICs9ICRjb2xfY291bnQ7CgkJCX0KCQl9CgoJCWlmICggJHRoaXMtPnZlcmJvc2UgJiYgJ3RhYmxlJyA9PT0gJHRoaXMtPmZvcm1hdCApIHsKCQkJJHRpbWUgPSByb3VuZCggbWljcm90aW1lKCB0cnVlICkgLSAkdGhpcy0+c3RhcnRfdGltZSwgMyApOwoJCQlXUF9DTEk6OmxvZyggc3ByaW50ZiggJyVkIGNvbHVtbnMgYW5kICVkIHRvdGFsIHJvd3MgYWZmZWN0ZWQgdXNpbmcgUEhQIChpbiAlc3MpLicsICR0b3RhbF9jb2xzLCAkdG90YWxfcm93cywgJHRpbWUgKSApOwoJCX0KCgkJcmV0dXJuIGFycmF5KCAkdGFibGVfcmVwb3J0LCAkdG90YWxfcm93cyApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc3FsX2hhbmRsZV9jb2woICRjb2wsICRwcmltYXJ5X2tleXMsICR0YWJsZSwgJG9sZCwgJG5ldyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCQkkY29sX3NxbCAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbCApOwoJCWlmICggJHRoaXMtPmRyeV9ydW4gKSB7CgkJCWlmICggJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkkY291bnQgPSAkdGhpcy0+bG9nX3NxbF9kaWZmKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKTsKCQkJfSBlbHNlIHsKCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJCSRjb3VudCA9ICR3cGRiLT5nZXRfdmFyKCAkd3BkYi0+cHJlcGFyZSggIlNFTEVDVCBDT1VOVCgkY29sX3NxbCkgRlJPTSAkdGFibGVfc3FsIFdIRVJFICRjb2xfc3FsIExJS0UgQklOQVJZICVzOyIsICclJyAuIHNlbGY6OmVzY19saWtlKCAkb2xkICkgLiAnJScgKSApOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKCAkdGhpcy0+bG9nX2hhbmRsZSApIHsKCQkJCSR0aGlzLT5sb2dfc3FsX2RpZmYoICRjb2wsICRwcmltYXJ5X2tleXMsICR0YWJsZSwgJG9sZCwgJG5ldyApOwoJCQl9CgkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkJJGNvdW50ID0gJHdwZGItPnF1ZXJ5KCAkd3BkYi0+cHJlcGFyZSggIlVQREFURSAkdGFibGVfc3FsIFNFVCAkY29sX3NxbCA9IFJFUExBQ0UoJGNvbF9zcWwsICVzLCAlcyk7IiwgJG9sZCwgJG5ldyApICk7CgkJfQoKCQlpZiAoICR0aGlzLT52ZXJib3NlICYmICd0YWJsZScgPT09ICR0aGlzLT5mb3JtYXQgKSB7CgkJCSR0aW1lID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gJHRoaXMtPnN0YXJ0X3RpbWUsIDMgKTsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICclZCByb3dzIGFmZmVjdGVkIHVzaW5nIFNRTCAoaW4gJXNzKS4nLCAkY291bnQsICR0aW1lICkgKTsKCQl9CgkJcmV0dXJuICRjb3VudDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIHBocF9oYW5kbGVfY29sKCAkY29sLCAkcHJpbWFyeV9rZXlzLCAkdGFibGUsICRvbGQsICRuZXcgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkkY291bnQgICAgPSAwOwoJCSRyZXBsYWNlciA9IG5ldyBcV1BfQ0xJXFNlYXJjaFJlcGxhY2VyKCAkb2xkLCAkbmV3LCAkdGhpcy0+cmVjdXJzZV9vYmplY3RzLCAkdGhpcy0+cmVnZXgsICR0aGlzLT5yZWdleF9mbGFncywgJHRoaXMtPnJlZ2V4X2RlbGltaXRlciwgbnVsbCAhPT0gJHRoaXMtPmxvZ19oYW5kbGUsICR0aGlzLT5yZWdleF9saW1pdCApOwoKCQkkdGFibGVfc3FsICAgICAgICAgICAgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCQkkY29sX3NxbCAgICAgICAgICAgICAgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkY29sICk7CgkJJHdoZXJlICAgICAgICAgICAgICAgID0gJHRoaXMtPnJlZ2V4ID8gJycgOiAiIFdIRVJFICRjb2xfc3FsIiAuICR3cGRiLT5wcmVwYXJlKCAnIExJS0UgQklOQVJZICVzJywgJyUnIC4gc2VsZjo6ZXNjX2xpa2UoICRvbGQgKSAuICclJyApOwoJCSRlc2NhcGVkX3ByaW1hcnlfa2V5cyA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICRwcmltYXJ5X2tleXMgKTsKCQkkcHJpbWFyeV9rZXlzX3NxbCAgICAgPSBpbXBsb2RlKCAnLCcsICRlc2NhcGVkX3ByaW1hcnlfa2V5cyApOwoJCSRvcmRlcl9ieV9rZXlzICAgICAgICA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICRrZXkgKSB7CgkJCQlyZXR1cm4gInska2V5fSBBU0MiOwoJCQl9LAoJCQkkZXNjYXBlZF9wcmltYXJ5X2tleXMKCQkpOwoJCSRvcmRlcl9ieV9zcWwgICAgICAgICA9ICdPUkRFUiBCWSAnIC4gaW1wbG9kZSggJywnLCAkb3JkZXJfYnlfa2V5cyApOwoJCSRsaW1pdCAgICAgICAgICAgICAgICA9IDEwMDA7CgkJJG9mZnNldCAgICAgICAgICAgICAgID0gMDsKCgkJLy8gMiBlcnJvcnM6CgkJLy8gLSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkvLyAtIFdvcmRQcmVzcy5Db2RlQW5hbHlzaXMuQXNzaWdubWVudEluQ29uZGl0aW9uIC0tIG5vIHJlYXNvbiB0byBkbyBjb3B5LXBhc3RlIGZvciBhIHNpbmdsZSB2YWxpZCBhc3NpZ25tZW50IGluIHdoaWxlCgkJLy8gcGhwY3M6aWdub3JlCgkJd2hpbGUgKCAkcm93cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIlNFTEVDVCB7JHByaW1hcnlfa2V5c19zcWx9IEZST00geyR0YWJsZV9zcWx9IHskd2hlcmV9IHskb3JkZXJfYnlfc3FsfSBMSU1JVCB7JGxpbWl0fSBPRkZTRVQgeyRvZmZzZXR9IiApICkgewoJCQlmb3JlYWNoICggJHJvd3MgYXMgJGtleXMgKSB7CgkJCQkkd2hlcmVfc3FsID0gJyc7CgkJCQlmb3JlYWNoICggKGFycmF5KSAka2V5cyBhcyAkayA9PiAkdiApIHsKCQkJCQlpZiAoIHN0cmxlbiggJHdoZXJlX3NxbCApICkgewoJCQkJCQkkd2hlcmVfc3FsIC49ICcgQU5EICc7CgkJCQkJfQoJCQkJCSR3aGVyZV9zcWwgLj0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGsgKSAuICcgPSAnIC4gc2VsZjo6ZXNjX3NxbF92YWx1ZSggJHYgKTsKCQkJCX0KCgkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIGVzY2FwZWQgdGhyb3VnaCBzZWxmOjplc2Nfc3FsX2lkZW50CgkJCQkkY29sX3ZhbHVlID0gJHdwZGItPmdldF92YXIoICJTRUxFQ1QgeyRjb2xfc3FsfSBGUk9NIHskdGFibGVfc3FsfSBXSEVSRSB7JHdoZXJlX3NxbH0iICk7CgoJCQkJaWYgKCAnJyA9PT0gJGNvbF92YWx1ZSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkdmFsdWUgPSAkcmVwbGFjZXItPnJ1biggJGNvbF92YWx1ZSApOwoKCQkJCWlmICggJHZhbHVlID09PSAkY29sX3ZhbHVlICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCWlmICggJHRoaXMtPmxvZ19oYW5kbGUgKSB7CgkJCQkJJHRoaXMtPmxvZ19waHBfZGlmZiggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZCwgJG5ldywgJHJlcGxhY2VyLT5nZXRfbG9nX2RhdGEoKSApOwoJCQkJCSRyZXBsYWNlci0+Y2xlYXJfbG9nX2RhdGEoKTsKCQkJCX0KCgkJCQlpZiAoICR0aGlzLT5kcnlfcnVuICkgewoJCQkJCSRjb3VudCsrOwoJCQkJfSBlbHNlIHsKCQkJCQkkdXBkYXRlX3doZXJlID0gYXJyYXkoKTsKCQkJCQlmb3JlYWNoICggKGFycmF5KSAka2V5cyBhcyAkayA9PiAkdiApIHsKCQkJCQkJJHVwZGF0ZV93aGVyZVsgJGsgXSA9ICR2OwoJCQkJCX0KCgkJCQkJJGNvdW50ICs9ICR3cGRiLT51cGRhdGUoICR0YWJsZSwgYXJyYXkoICRjb2wgPT4gJHZhbHVlICksICR1cGRhdGVfd2hlcmUgKTsKCQkJCX0KCQkJfQoKCQkJJG9mZnNldCArPSAkbGltaXQ7CgkJfQoKCQlpZiAoICR0aGlzLT52ZXJib3NlICYmICd0YWJsZScgPT09ICR0aGlzLT5mb3JtYXQgKSB7CgkJCSR0aW1lID0gcm91bmQoIG1pY3JvdGltZSggdHJ1ZSApIC0gJHRoaXMtPnN0YXJ0X3RpbWUsIDMgKTsKCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICclZCByb3dzIGFmZmVjdGVkIHVzaW5nIFBIUCAoaW4gJXNzKS4nLCAkY291bnQsICR0aW1lICkgKTsKCQl9CgoJCXJldHVybiAkY291bnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZV9zcWxfcm93X2ZpZWxkcyggJHRhYmxlLCAkcm93cyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCWlmICggZW1wdHkoICRyb3dzICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCgkJJGluc2VydCAgPSAiSU5TRVJUIElOVE8gJHRhYmxlX3NxbCAoIjsKCQkkaW5zZXJ0IC49IGpvaW4oICcsICcsIHNlbGY6OmVzY19zcWxfaWRlbnQoIGFycmF5X2tleXMoICRyb3dzWzBdICkgKSApOwoJCSRpbnNlcnQgLj0gJykgVkFMVUVTICc7CgkJJGluc2VydCAuPSAiXG4iOwoKCQkkc3FsICAgID0gJGluc2VydDsKCQkkdmFsdWVzID0gYXJyYXkoKTsKCgkJJGluZGV4ICAgICAgICAgICAgICA9IDE7CgkJJGNvdW50ICAgICAgICAgICAgICA9IGNvdW50KCAkcm93cyApOwoJCSRleHBvcnRfaW5zZXJ0X3NpemUgPSAkdGhpcy0+ZXhwb3J0X2luc2VydF9zaXplOwoKCQlmb3JlYWNoICggJHJvd3MgYXMgJHJvd19maWVsZHMgKSB7CgkJCSRzdWJzID0gYXJyYXkoKTsKCgkJCWZvcmVhY2ggKCAkcm93X2ZpZWxkcyBhcyAkZmllbGRfdmFsdWUgKSB7CgkJCQlpZiAoIG51bGwgPT09ICRmaWVsZF92YWx1ZSApIHsKCQkJCQkkc3Vic1tdID0gJ05VTEwnOwoJCQkJfSBlbHNlIHsKCQkJCQkkc3Vic1tdICAgPSAnJXMnOwoJCQkJCSR2YWx1ZXNbXSA9ICRmaWVsZF92YWx1ZTsKCQkJCX0KCQkJfQoKCQkJJHNxbCAuPSAnKCcgLiBqb2luKCAnLCAnLCAkc3VicyApIC4gJyknOwoKCQkJLy8gQWRkIG5ldyBpbnNlcnQgc3RhdGVtZW50IGlmIG5lZWRlZC4gQmVmb3JlIHRoaXMgd2UgY2xvc2UgdGhlIHByZXZpb3VzIHdpdGggc2VtaWNvbG9uIGFuZCB3cml0ZSBzdGF0ZW1lbnQgdG8gc3FsLWZpbGUuCgkJCS8vICJTdGF0ZW1lbnQgYnJlYWsiIGlzIG5lZWRlZDoKCQkJLy8JCTEuIFdoZW4gdGhlIGxvb3AgaXMgcnVubmluZyBldmVyeSBudGggdGltZSAod2hlcmUgbiBpcyBpbnNlcnQgc3RhdGVtZW50IHNpemUsICRleHBvcnRfaW5kZXhfc2l6ZSkuIFJlbWFpbmRlciBpcyB6ZXJvIGFsc28gb24gZmlyc3Qgcm91bmQsIHNvIGl0IGhhdmUgdG8gYmUgZXhjbHVkZWQuCgkJCS8vCQkJJGluZGV4ICUgJGV4cG9ydF9pbnNlcnRfc2l6ZSA9PSAwICYmICRpbmRleCA+IDAKCQkJLy8JCTIuIE9yIHdoZW4gdGhlIGxvb3AgaXMgcnVubmluZyBsYXN0IHRpbWUKCQkJLy8JCQkkaW5kZXggPT0gJGNvdW50CgkJCWlmICggKCAwID09PSAkaW5kZXggJSAkZXhwb3J0X2luc2VydF9zaXplICYmICRpbmRleCA+IDAgKSB8fCAkaW5kZXggPT09ICRjb3VudCApIHsKCQkJCSRzcWwgLj0gIjtcbiI7CgoJCQkJaWYgKCBtZXRob2RfZXhpc3RzKCAkd3BkYiwgJ3JlbW92ZV9wbGFjZWhvbGRlcl9lc2NhcGUnICkgKSB7CgkJCQkJLy8gc2luY2UgNC44LjMKCQkJCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLk5vdFByZXBhcmVkIC0tIHZlcmlmaWVkIGlucHV0cyBhYm92ZQoJCQkJCSRzcWwgPSAkd3BkYi0+cmVtb3ZlX3BsYWNlaG9sZGVyX2VzY2FwZSggJHdwZGItPnByZXBhcmUoICRzcWwsIGFycmF5X3ZhbHVlcyggJHZhbHVlcyApICkgKTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gNC44LjIgb3IgbGVzcwoJCQkJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuTm90UHJlcGFyZWQgLS0gdmVyaWZpZWQgaW5wdXRzIGFib3ZlCgkJCQkJJHNxbCA9ICR3cGRiLT5wcmVwYXJlKCAkc3FsLCBhcnJheV92YWx1ZXMoICR2YWx1ZXMgKSApOwoJCQkJfQoKCQkJCWZ3cml0ZSggJHRoaXMtPmV4cG9ydF9oYW5kbGUsICRzcWwgKTsKCgkJCQkvLyBJZiB0aGVyZSBpcyBzdGlsbCByb3dzIHRvIGxvb3AsIHJlc2V0ICRzcWwgYW5kICR2YWx1ZXMgdmFyaWFibGVzLgoJCQkJaWYgKCAkY291bnQgPiAkaW5kZXggKSB7CgkJCQkJJHNxbCAgICA9ICRpbnNlcnQ7CgkJCQkJJHZhbHVlcyA9IGFycmF5KCk7CgkJCQl9CgkJCX0gZWxzZSB7IC8vIE90aGVyd2lzZSBqdXN0IGFkZCBjb21tYSBhbmQgbmV3IGxpbmUKCQkJCSRzcWwgLj0gIixcbiI7CgkJCX0KCgkJCSRpbmRleCsrOwoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfY29sdW1ucyggJHRhYmxlICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJHRhYmxlX3NxbCAgICAgICA9IHNlbGY6OmVzY19zcWxfaWRlbnQoICR0YWJsZSApOwoJCSRwcmltYXJ5X2tleXMgICAgPSBhcnJheSgpOwoJCSR0ZXh0X2NvbHVtbnMgICAgPSBhcnJheSgpOwoJCSRhbGxfY29sdW1ucyAgICAgPSBhcnJheSgpOwoJCSRzdXBwcmVzc19lcnJvcnMgPSAkd3BkYi0+c3VwcHJlc3NfZXJyb3JzKCk7CgoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuREIuUHJlcGFyZWRTUUwuSW50ZXJwb2xhdGVkTm90UHJlcGFyZWQgLS0gZXNjYXBlZCB0aHJvdWdoIHNlbGY6OmVzY19zcWxfaWRlbnQKCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggIkRFU0NSSUJFICR0YWJsZV9zcWwiICk7CgoJCWlmICggISBlbXB0eSggJHJlc3VsdHMgKSApIHsKCQkJZm9yZWFjaCAoICRyZXN1bHRzIGFzICRjb2wgKSB7CgkJCQlpZiAoICdQUkknID09PSAkY29sLT5LZXkgKSB7CgkJCQkJJHByaW1hcnlfa2V5c1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQlpZiAoIHNlbGY6OmlzX3RleHRfY29sKCAkY29sLT5UeXBlICkgKSB7CgkJCQkJJHRleHRfY29sdW1uc1tdID0gJGNvbC0+RmllbGQ7CgkJCQl9CgkJCQkkYWxsX2NvbHVtbnNbXSA9ICRjb2wtPkZpZWxkOwoJCQl9CgkJfQoJCSR3cGRiLT5zdXBwcmVzc19lcnJvcnMoICRzdXBwcmVzc19lcnJvcnMgKTsKCQlyZXR1cm4gYXJyYXkoICRwcmltYXJ5X2tleXMsICR0ZXh0X2NvbHVtbnMsICRhbGxfY29sdW1ucyApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGlzX3RleHRfY29sKCAkdHlwZSApIHsKCQlmb3JlYWNoICggYXJyYXkoICd0ZXh0JywgJ3ZhcmNoYXInICkgYXMgJHRva2VuICkgewoJCQlpZiAoIGZhbHNlICE9PSBzdHJwb3MoICR0eXBlLCAkdG9rZW4gKSApIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX2xpa2UoICRvbGQgKSB7CgkJZ2xvYmFsICR3cGRiOwoKCQkvLyBSZW1vdmUgbm90aWNlcyBpbiA0LjAgYW5kIHN1cHBvcnQgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkKCQlpZiAoIG1ldGhvZF9leGlzdHMoICR3cGRiLCAnZXNjX2xpa2UnICkgKSB7CgkJCS8vIDQuMAoJCQkkb2xkID0gJHdwZGItPmVzY19saWtlKCAkb2xkICk7CgkJfSBlbHNlIHsKCQkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5XUC5EZXByZWNhdGVkRnVuY3Rpb25zLmxpa2VfZXNjYXBlRm91bmQgLS0gQkMtbGF5ZXIgZm9yIFdQIDMuOSBvciBsZXNzLgoJCQkkb2xkID0gbGlrZV9lc2NhcGUoIGVzY19zcWwoICRvbGQgKSApOyAvLyBOb3RlOiB0aGlzIGRvdWJsZSBlc2NhcGluZyBpcyBhY3R1YWxseSBuZWNlc3NhcnksIGV2ZW4gdGhvdWdoIGBlc2NfbGlrZSgpYCB3aWxsIGJlIHVzZWQgaW4gYSBgcHJlcGFyZSgpYC4KCQl9CgoJCXJldHVybiAkb2xkOwoJfQoKCS8qKgoJICogRXNjYXBlcyAoYmFja3RpY2tzKSBNeVNRTCBpZGVudGlmaWVycyAoYWthIHNjaGVtYSBvYmplY3QgbmFtZXMpIC0gaS5lLiBjb2x1bW4gbmFtZXMsIHRhYmxlIG5hbWVzLCBhbmQgZGF0YWJhc2UvaW5kZXgvYWxpYXMvdmlldyBldGMgbmFtZXMuCgkgKiBTZWUgaHR0cHM6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNS41L2VuL2lkZW50aWZpZXJzLmh0bWwKCSAqCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRpZGVudHMgQSBzaW5nbGUgaWRlbnRpZmllciBvciBhbiBhcnJheSBvZiBpZGVudGlmaWVycy4KCSAqIEByZXR1cm4gc3RyaW5nfGFycmF5IEFuIGVzY2FwZWQgc3RyaW5nIGlmIGdpdmVuIGEgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBlc2NhcGVkIHN0cmluZ3MgaWYgZ2l2ZW4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZXNjX3NxbF9pZGVudCggJGlkZW50cyApIHsKCQkkYmFja3RpY2sgPSBmdW5jdGlvbiAoICR2ICkgewoJCQkvLyBFc2NhcGUgYW55IGJhY2t0aWNrcyBpbiB0aGUgaWRlbnRpZmllciBieSBkb3VibGluZy4KCQkJcmV0dXJuICdgJyAuIHN0cl9yZXBsYWNlKCAnYCcsICdgYCcsICR2ICkgLiAnYCc7CgkJfTsKCQlpZiAoIGlzX3N0cmluZyggJGlkZW50cyApICkgewoJCQlyZXR1cm4gJGJhY2t0aWNrKCAkaWRlbnRzICk7CgkJfQoJCXJldHVybiBhcnJheV9tYXAoICRiYWNrdGljaywgJGlkZW50cyApOwoJfQoKCS8qKgoJICogUHV0cyBNeVNRTCBzdHJpbmcgdmFsdWVzIGluIHNpbmdsZSBxdW90ZXMsIHRvIGF2b2lkIHRoZW0gYmVpbmcgaW50ZXJwcmV0ZWQgYXMgY29sdW1uIG5hbWVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJHZhbHVlcyBBIHNpbmdsZSB2YWx1ZSBvciBhbiBhcnJheSBvZiB2YWx1ZXMuCgkgKiBAcmV0dXJuIHN0cmluZ3xhcnJheSBBIHF1b3RlZCBzdHJpbmcgaWYgZ2l2ZW4gYSBzdHJpbmcsIG9yIGFuIGFycmF5IG9mIHF1b3RlZCBzdHJpbmdzIGlmIGdpdmVuIGFuIGFycmF5IG9mIHN0cmluZ3MuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGVzY19zcWxfdmFsdWUoICR2YWx1ZXMgKSB7CgkJJHF1b3RlID0gZnVuY3Rpb24gKCAkdiApIHsKCQkJLy8gRG9uJ3QgcXVvdGUgaW50ZWdlciB2YWx1ZXMgdG8gYXZvaWQgTXlTUUwncyBpbXBsaWNpdCB0eXBlIGNvbnZlcnNpb24uCgkJCWlmICggcHJlZ19tYXRjaCggJy9eWystXT9bMC05XXsxLDIwfSQvJywgJHYgKSApIHsgLy8gTXlTUUwgQklHSU5UIFVOU0lHTkVEIG1heCAxODQ0Njc0NDA3MzcwOTU1MTYxNSAoMjAgZGlnaXRzKS4KCQkJCXJldHVybiBlc2Nfc3FsKCAkdiApOwoJCQl9CgoJCQkvLyBQdXQgYW55IHN0cmluZyB2YWx1ZXMgYmV0d2VlbiBzaW5nbGUgcXVvdGVzLgoJCQlyZXR1cm4gIiciIC4gZXNjX3NxbCggJHYgKSAuICInIjsKCQl9OwoKCQlpZiAoIGlzX2FycmF5KCAkdmFsdWVzICkgKSB7CgkJCXJldHVybiBhcnJheV9tYXAoICRxdW90ZSwgJHZhbHVlcyApOwoJCX0KCgkJcmV0dXJuICRxdW90ZSggJHZhbHVlcyApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgY29sb3IgY29kZXMgZnJvbSB0aGUgb3B0aW9ucyBpZiBhbnksIGFuZCByZXR1cm5zIHRoZSBwYXNzZWQgaW4gYXJyYXkgY29sb3JpemVkIHdpdGggMiBlbGVtZW50cyBwZXIgZW50cnksIGEgY29sb3IgY29kZSAob3IgJycpIGFuZCBhIHJlc2V0IChvciAnJykuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFRoZSBhc3NvY2lhdGl2ZSBhcmd1bWVudCBhcnJheSBwYXNzZWQgdG8gdGhlIGNvbW1hbmQuCgkgKiBAcGFyYW0gYXJyYXkgJGNvbG9ycyBBcnJheSBvZiBkZWZhdWx0IHBlcmNlbnQgY29sb3IgY29kZSBzdHJpbmdzIGtleWVkIGJ5IHRoZSBjb2xvciBjb250ZXh0cy4KCSAqIEByZXR1cm4gYXJyYXkgQXJyYXkgY29udGFpbmluZyAyLWVsZW1lbnQgYXJyYXlzIGtleWVkIHRvIHRoZSBpbnB1dCAkY29sb3JzIGFycmF5LgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9jb2xvcnMoICRhc3NvY19hcmdzLCAkY29sb3JzICkgewoJCSRjb2xvcl9yZXNldCA9IFdQX0NMSTo6Y29sb3JpemUoICclbicgKTsKCgkJJGNvbG9yX2NvZGVfY2FsbGJhY2sgPSBmdW5jdGlvbiAoICR2ICkgewoJCQlyZXR1cm4gc3Vic3RyKCAkdiwgMSApOwoJCX07CgoJCSRjb2xvcl9jb2RlcyA9IGFycmF5X2tleXMoIFxjbGlcQ29sb3JzOjpnZXRDb2xvcnMoKSApOwoJCSRjb2xvcl9jb2RlcyA9IGFycmF5X21hcCggJGNvbG9yX2NvZGVfY2FsbGJhY2ssICRjb2xvcl9jb2RlcyApOwoJCSRjb2xvcl9jb2RlcyA9IGltcGxvZGUoICcnLCAkY29sb3JfY29kZXMgKTsKCgkJJGNvbG9yX2NvZGVzX3JlZ2V4ID0gJy9eKD86JVsnIC4gJGNvbG9yX2NvZGVzIC4gJ10pKiQvJzsKCgkJZm9yZWFjaCAoIGFycmF5X2tleXMoICRjb2xvcnMgKSBhcyAkY29sb3JfY29sICkgewoJCQkkY29sX2NvbG9yX2ZsYWcgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJGNvbG9yX2NvbCAuICdfY29sb3InICk7CgkJCWlmICggbnVsbCAhPT0gJGNvbF9jb2xvcl9mbGFnICkgewoJCQkJaWYgKCAhIHByZWdfbWF0Y2goICRjb2xvcl9jb2Rlc19yZWdleCwgJGNvbF9jb2xvcl9mbGFnLCAkbWF0Y2hlcyApICkgewoJCQkJCVdQX0NMSTo6d2FybmluZyggIlVucmVjb2duaXplZCBwZXJjZW50IGNvbG9yIGNvZGUgJyRjb2xfY29sb3JfZmxhZycgZm9yICd7JGNvbG9yX2NvbH1fY29sb3InLiIgKTsKCQkJCX0gZWxzZSB7CgkJCQkJJGNvbG9yc1sgJGNvbG9yX2NvbCBdID0gJG1hdGNoZXNbMF07CgkJCQl9CgkJCX0KCQkJJGNvbG9yc1sgJGNvbG9yX2NvbCBdID0gJGNvbG9yc1sgJGNvbG9yX2NvbCBdID8gYXJyYXkoIFdQX0NMSTo6Y29sb3JpemUoICRjb2xvcnNbICRjb2xvcl9jb2wgXSApLCAkY29sb3JfcmVzZXQgKSA6IGFycmF5KCAnJywgJycgKTsKCQl9CgoJCXJldHVybiAkY29sb3JzOwoJfQoKCS8qCgkgKiBMb2dzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gb2xkIG1hdGNoIGFuZCBuZXcgcmVwbGFjZW1lbnQgZm9yIFNRTCByZXBsYWNlbWVudC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRjb2wgQ29sdW1uIGJlaW5nIHByb2Nlc3NlZC4KCSAqIEBwYXJhbSBhcnJheSAkcHJpbWFyeV9rZXlzIFByaW1hcnkga2V5cyBmb3IgdGFibGUuCgkgKiBAcGFyYW0gc3RyaW5nICR0YWJsZSBUYWJsZSBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gc3RyaW5nICRvbGQgT2xkIHZhbHVlIHRvIG1hdGNoLgoJICogQHBhcmFtIHN0cmluZyAkbmV3IE5ldyB2YWx1ZSB0byByZXBsYWNlIHRoZSBvbGQgdmFsdWUgd2l0aC4KCSAqIEByZXR1cm4gaW50IENvdW50IG9mIGNoYW5nZWQgcm93cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBsb2dfc3FsX2RpZmYoICRjb2wsICRwcmltYXJ5X2tleXMsICR0YWJsZSwgJG9sZCwgJG5ldyApIHsKCQlnbG9iYWwgJHdwZGI7CgkJaWYgKCAkcHJpbWFyeV9rZXlzICkgewoJCQkkZXNjX3ByaW1hcnlfa2V5cyA9IGltcGxvZGUoICcsICcsIHNlbGY6OmVzY19zcWxfaWRlbnQoICRwcmltYXJ5X2tleXMgKSApOwoJCQkkcHJpbWFyeV9rZXlzX3NxbCA9IGNvdW50KCAkcHJpbWFyeV9rZXlzICkgPiAxID8gIkNPTkNBVF9XUygnLCcsIHskZXNjX3ByaW1hcnlfa2V5c30pLCAiIDogInskZXNjX3ByaW1hcnlfa2V5c30sICI7CgkJfSBlbHNlIHsKCQkJJHByaW1hcnlfa2V5c19zcWwgPSAnJzsKCQl9CgoJCSR0YWJsZV9zcWwgPSBzZWxmOjplc2Nfc3FsX2lkZW50KCAkdGFibGUgKTsKCQkkY29sX3NxbCAgID0gc2VsZjo6ZXNjX3NxbF9pZGVudCggJGNvbCApOwoKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLkRCLlByZXBhcmVkU1FMLkludGVycG9sYXRlZE5vdFByZXBhcmVkIC0tIGVzY2FwZWQgdGhyb3VnaCBzZWxmOjplc2Nfc3FsX2lkZW50CgkJJHJlc3VsdHMgPSAkd3BkYi0+Z2V0X3Jlc3VsdHMoICR3cGRiLT5wcmVwYXJlKCAiU0VMRUNUIHskcHJpbWFyeV9rZXlzX3NxbH17JGNvbF9zcWx9IEZST00geyR0YWJsZV9zcWx9IFdIRVJFIHskY29sX3NxbH0gTElLRSBCSU5BUlkgJXMiLCAnJScgLiBzZWxmOjplc2NfbGlrZSggJG9sZCApIC4gJyUnICksIEFSUkFZX04gKTsKCgkJaWYgKCBlbXB0eSggJHJlc3VsdHMgKSApIHsKCQkJcmV0dXJuIDA7CgkJfQoKCQkkc2VhcmNoX3JlZ2V4ID0gJy8nIC4gcHJlZ19xdW90ZSggJG9sZCwgJy8nICkgLiAnLyc7CgoJCWZvcmVhY2ggKCAkcmVzdWx0cyBhcyAkcmVzdWx0ICkgewoJCQlsaXN0KCAka2V5cywgJGRhdGEgKSA9ICRwcmltYXJ5X2tleXMgPyBhcnJheSggJHJlc3VsdFswXSwgJHJlc3VsdFsxXSApIDogYXJyYXkoIG51bGwsICRyZXN1bHRbMF0gKTsKCQkJaWYgKCBwcmVnX21hdGNoX2FsbCggJHNlYXJjaF9yZWdleCwgJGRhdGEsICRtYXRjaGVzLCBQUkVHX09GRlNFVF9DQVBUVVJFICkgKSB7CgkJCQlsaXN0KCAkb2xkX2JpdHMsICRuZXdfYml0cyApID0gJHRoaXMtPmxvZ19iaXRzKCAkc2VhcmNoX3JlZ2V4LCAkZGF0YSwgJG1hdGNoZXMsICRuZXcgKTsKCQkJCSR0aGlzLT5sb2dfd3JpdGUoICRjb2wsICRrZXlzLCAkdGFibGUsICRvbGRfYml0cywgJG5ld19iaXRzICk7CgkJCX0KCQl9CgkJcmV0dXJuIGNvdW50KCAkcmVzdWx0cyApOwoJfQoKCS8qCgkgKiBMb2dzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gb2xkIG1hdGNoZXMgYW5kIG5ldyByZXBsYWNlbWVudHMgYXQgdGhlIGVuZCBvZiBhIFBIUCAocmVnZXgpIHJlcGxhY2VtZW50IG9mIGEgZGF0YWJhc2Ugcm93LgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGNvbCBDb2x1bW4gYmVpbmcgcHJvY2Vzc2VkLgoJICogQHBhcmFtIGFycmF5ICRrZXlzIEFzc29jaWF0aXZlIGFycmF5IChvciBvYmplY3QpIG9mIHByaW1hcnkga2V5IG5hbWVzIGFuZCB0aGVpciB2YWx1ZXMgZm9yIHRoZSByb3cgYmVpbmcgcHJvY2Vzc2VkLgoJICogQHBhcmFtIHN0cmluZyAkdGFibGUgVGFibGUgYmVpbmcgcHJvY2Vzc2VkLgoJICogQHBhcmFtIHN0cmluZyAkb2xkIE9sZCB2YWx1ZSB0byBtYXRjaC4KCSAqIEBwYXJhbSBzdHJpbmcgJG5ldyBOZXcgdmFsdWUgdG8gcmVwbGFjZSB0aGUgb2xkIHZhbHVlIHdpdGguCgkgKiBAcGFyYW0gYXJyYXkgJGxvZ19kYXRhIEFycmF5IG9mIGRhdGEgc3RyaW5ncyBiZWZvcmUgcmVwbGFjZW1lbnRzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGxvZ19waHBfZGlmZiggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZCwgJG5ldywgJGxvZ19kYXRhICkgewoJCWlmICggJHRoaXMtPnJlZ2V4ICkgewoJCQkkc2VhcmNoX3JlZ2V4ID0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlciAuICRvbGQgLiAkdGhpcy0+cmVnZXhfZGVsaW1pdGVyIC4gJHRoaXMtPnJlZ2V4X2ZsYWdzOwoJCX0gZWxzZSB7CgkJCSRzZWFyY2hfcmVnZXggPSAnLycgLiBwcmVnX3F1b3RlKCAkb2xkLCAnLycgKSAuICcvJzsKCQl9CgoJCSRvbGRfYml0cyA9IGFycmF5KCk7CgkJJG5ld19iaXRzID0gYXJyYXkoKTsKCQlmb3JlYWNoICggJGxvZ19kYXRhIGFzICRkYXRhICkgewoJCQlpZiAoIHByZWdfbWF0Y2hfYWxsKCAkc2VhcmNoX3JlZ2V4LCAkZGF0YSwgJG1hdGNoZXMsIFBSRUdfT0ZGU0VUX0NBUFRVUkUgKSApIHsKCQkJCSRiaXRzICAgICA9ICR0aGlzLT5sb2dfYml0cyggJHNlYXJjaF9yZWdleCwgJGRhdGEsICRtYXRjaGVzLCAkbmV3ICk7CgkJCQkkb2xkX2JpdHMgPSBhcnJheV9tZXJnZSggJG9sZF9iaXRzLCAkYml0c1swXSApOwoJCQkJJG5ld19iaXRzID0gYXJyYXlfbWVyZ2UoICRuZXdfYml0cywgJGJpdHNbMV0gKTsKCQkJfQoJCX0KCQlpZiAoICRvbGRfYml0cyApIHsKCQkJJHRoaXMtPmxvZ193cml0ZSggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZF9iaXRzLCAkbmV3X2JpdHMgKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBhcnJheXMgb2Ygb2xkIG1hdGNoZXMgYW5kIG5ldyByZXBsYWNlbWVudHMgYmFzZWQgb24gdGhlIHBhc3NlZC1pbiBtYXRjaGVzLCB3aXRoIGNvbnRleHQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2VhcmNoX3JlZ2V4IFRoZSBzZWFyY2ggcmVndWxhciBleHByZXNzaW9uLgoJICogQHBhcmFtIHN0cmluZyAkb2xkX2RhdGEgRXhpc3RpbmcgZGF0YSBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJG9sZF9tYXRjaGVzIE9sZCBtYXRjaGVzIGFycmF5IHJldHVybmVkIGJ5IGBwcmVnX21hdGNoX2FsbCgpYC4KCSAqIEBwYXJhbSBzdHJpbmcgJG5ldyBOZXcgdmFsdWUgdG8gcmVwbGFjZSB0aGUgb2xkIHZhbHVlIHdpdGguCgkgKiBAcmV0dXJuIGFycmF5IFR3byBlbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIGFycmF5IG9mIG9sZCBtYXRjaCBsb2cgc3RyaW5ncyBhbmQgdGhlIGFycmF5IG9mIG5ldyByZXBsYWNlbWVudCBsb2cgc3RyaW5ncyB3aXRoIGJlZm9yZS9hZnRlciBjb250ZXh0cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBsb2dfYml0cyggJHNlYXJjaF9yZWdleCwgJG9sZF9kYXRhLCAkb2xkX21hdGNoZXMsICRuZXcgKSB7CgkJJGVuY29kaW5nID0gJHRoaXMtPmxvZ19lbmNvZGluZzsKCQlpZiAoICEgJGVuY29kaW5nICYmICggJHRoaXMtPmxvZ19iZWZvcmVfY29udGV4dCB8fCAkdGhpcy0+bG9nX2FmdGVyX2NvbnRleHQgKSAmJiBmdW5jdGlvbl9leGlzdHMoICdtYl9kZXRlY3RfZW5jb2RpbmcnICkgKSB7CgkJCSRlbmNvZGluZyA9IG1iX2RldGVjdF9lbmNvZGluZyggJG9sZF9kYXRhLCBudWxsLCB0cnVlIC8qc3RyaWN0Ki8gKTsKCQl9CgoJCS8vIEdlbmVyYXRlIGEgbmV3IGRhdGEgbWF0Y2hlcyBhbmFsb2cgb2YgdGhlIG9sZCBkYXRhIG1hdGNoZXMgYnkgc2ltdWxhdGluZyBhIGBwcmVnX3JlcGxhY2UoKWAuCgkJJGlzX3JlZ2V4ICAgID0gJHRoaXMtPnJlZ2V4OwoJCSRpICAgICAgICAgICA9IDA7CgkJJGRpZmYgICAgICAgID0gMDsKCQkkbmV3X21hdGNoZXMgPSBhcnJheSgpOwoJCSRuZXdfZGF0YSAgICA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygKCQkJJHNlYXJjaF9yZWdleCwKCQkJZnVuY3Rpb24gKCAkbWF0Y2hlcyApIHVzZSAoICRvbGRfbWF0Y2hlcywgJG5ldywgJGlzX3JlZ2V4LCAmJG5ld19tYXRjaGVzLCAmJGksICYkZGlmZiApIHsKCQkJCWlmICggJGlzX3JlZ2V4ICkgewoJCQkJCS8vIFN1YiBpbiBhbnkgYmFjayByZWZlcmVuY2VzLCAiJDEiLCAiXDIiIGV0YywgaW4gdGhlIHJlcGxhY2VtZW50IHN0cmluZy4KCQkJCQkkbmV3ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAoJCQkJCQknLyg/PCFcXFxcKSg/OlxcXFxcXFxcKSooKD86XFxcXHxcXCQpWzAtOV17MSwyfXxcXCR7WzAtOV17MSwyfVxcfSkvJywKCQkJCQkJZnVuY3Rpb24gKCAkbSApIHVzZSAoICRtYXRjaGVzICkgewoJCQkJCQkJJGlkeCA9IChpbnQpIHN0cl9yZXBsYWNlKCBhcnJheSggJ1xcJywgJyQnLCAneycsICd9JyApLCAnJywgJG1bMF0gKTsKCQkJCQkJCXJldHVybiBpc3NldCggJG1hdGNoZXNbICRpZHggXSApID8gJG1hdGNoZXNbICRpZHggXSA6ICcnOwoJCQkJCQl9LAoJCQkJCQkkbmV3CgkJCQkJKTsKCQkJCQkkbmV3ID0gc3RyX3JlcGxhY2UoICdcXFxcJywgJ1xcJywgJG5ldyApOyAvLyBVbmVzY2FwZSBhbnkgYmFja3NsYXNoZWQgYmFja3NsYXNoZXMuCgkJCQl9CgoJCQkJJG5ld19tYXRjaGVzWzBdWyAkaSBdWzBdID0gJG5ldzsKCQkJCSRuZXdfbWF0Y2hlc1swXVsgJGkgXVsxXSA9ICRvbGRfbWF0Y2hlc1swXVsgJGkgXVsxXSArICRkaWZmOwoKCQkJCSRkaWZmICs9IHN0cmxlbiggJG5ldyApIC0gc3RybGVuKCAkb2xkX21hdGNoZXNbMF1bICRpIF1bMF0gKTsKCQkJCSRpKys7CgkJCQlyZXR1cm4gJG5ldzsKCQkJfSwKCQkJJG9sZF9kYXRhLAoJCQkkdGhpcy0+cmVnZXhfbGltaXQsCgkJCSRtYXRjaF9jbnQKCQkpOwoKCQkkb2xkX2JpdHMgICAgICAgID0gYXJyYXkoKTsKCQkkbmV3X2JpdHMgICAgICAgID0gYXJyYXkoKTsKCQkkYXBwZW5kX25leHQgICAgID0gZmFsc2U7CgkJJGxhc3Rfb2xkX29mZnNldCA9IDA7CgkJJGxhc3RfbmV3X29mZnNldCA9IDA7CgkJZm9yICggJGkgPSAwOyAkaSA8ICRtYXRjaF9jbnQ7ICRpKysgKSB7CgkJCSRvbGRfbWF0Y2ggID0gJG9sZF9tYXRjaGVzWzBdWyAkaSBdWzBdOwoJCQkkb2xkX29mZnNldCA9ICRvbGRfbWF0Y2hlc1swXVsgJGkgXVsxXTsKCQkJJG5ld19tYXRjaCAgPSAkbmV3X21hdGNoZXNbMF1bICRpIF1bMF07CgkJCSRuZXdfb2Zmc2V0ID0gJG5ld19tYXRjaGVzWzBdWyAkaSBdWzFdOwoKCQkJJG9sZF9sb2cgPSAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX29sZCddWzBdIC4gJG9sZF9tYXRjaCAuICR0aGlzLT5sb2dfY29sb3JzWydsb2dfb2xkJ11bMV07CgkJCSRuZXdfbG9nID0gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ19uZXcnXVswXSAuICRuZXdfbWF0Y2ggLiAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX25ldyddWzFdOwoKCQkJJG9sZF9iZWZvcmUgICAgICA9ICcnOwoJCQkkb2xkX2FmdGVyICAgICAgID0gJyc7CgkJCSRuZXdfYmVmb3JlICAgICAgPSAnJzsKCQkJJG5ld19hZnRlciAgICAgICA9ICcnOwoJCQkkYWZ0ZXJfc2hvcnRlbmVkID0gZmFsc2U7CgoJCQkvLyBPZmZzZXRzIGFyZSBpbiBieXRlcywgc28gbmVlZCB0byB1c2UgYHN0cmxlbigpYCBhbmQgYHN1YnN0cigpYCBiZWZvcmUgdXNpbmcgYHNhZmVfc3Vic3RyKClgLgoJCQlpZiAoICR0aGlzLT5sb2dfYmVmb3JlX2NvbnRleHQgJiYgJG9sZF9vZmZzZXQgJiYgISAkYXBwZW5kX25leHQgKSB7CgkJCQkkb2xkX2JlZm9yZSA9IFxjbGlcc2FmZV9zdWJzdHIoIHN1YnN0ciggJG9sZF9kYXRhLCAkbGFzdF9vbGRfb2Zmc2V0LCAkb2xkX29mZnNldCAtICRsYXN0X29sZF9vZmZzZXQgKSwgLSR0aGlzLT5sb2dfYmVmb3JlX2NvbnRleHQsIG51bGwgLypsZW5ndGgqLywgZmFsc2UgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCSRuZXdfYmVmb3JlID0gXGNsaVxzYWZlX3N1YnN0ciggc3Vic3RyKCAkbmV3X2RhdGEsICRsYXN0X25ld19vZmZzZXQsICRuZXdfb2Zmc2V0IC0gJGxhc3RfbmV3X29mZnNldCApLCAtJHRoaXMtPmxvZ19iZWZvcmVfY29udGV4dCwgbnVsbCAvKmxlbmd0aCovLCBmYWxzZSAvKmlzX3dpZHRoKi8sICRlbmNvZGluZyApOwoJCQl9CgkJCWlmICggJHRoaXMtPmxvZ19hZnRlcl9jb250ZXh0ICkgewoJCQkJJG9sZF9lbmRfb2Zmc2V0ID0gJG9sZF9vZmZzZXQgKyBzdHJsZW4oICRvbGRfbWF0Y2ggKTsKCQkJCSRuZXdfZW5kX29mZnNldCA9ICRuZXdfb2Zmc2V0ICsgc3RybGVuKCAkbmV3X21hdGNoICk7CgkJCQkkb2xkX2FmdGVyICAgICAgPSBcY2xpXHNhZmVfc3Vic3RyKCBzdWJzdHIoICRvbGRfZGF0YSwgJG9sZF9lbmRfb2Zmc2V0ICksIDAsICR0aGlzLT5sb2dfYWZ0ZXJfY29udGV4dCwgZmFsc2UgLyppc193aWR0aCovLCAkZW5jb2RpbmcgKTsKCQkJCSRuZXdfYWZ0ZXIgICAgICA9IFxjbGlcc2FmZV9zdWJzdHIoIHN1YnN0ciggJG5ld19kYXRhLCAkbmV3X2VuZF9vZmZzZXQgKSwgMCwgJHRoaXMtPmxvZ19hZnRlcl9jb250ZXh0LCBmYWxzZSAvKmlzX3dpZHRoKi8sICRlbmNvZGluZyApOwoJCQkJLy8gVG8gbGVzc2VuIGNvbnRleHQgZHVwbGljYXRpb24gaW4gb3V0cHV0LCBzaG9ydGVuIHRoZSBhZnRlciBjb250ZXh0IGlmIGl0IG92ZXJsYXBzIHdpdGggdGhlIG5leHQgbWF0Y2guCgkJCQlpZiAoICRpICsgMSA8ICRtYXRjaF9jbnQgJiYgJG9sZF9lbmRfb2Zmc2V0ICsgc3RybGVuKCAkb2xkX2FmdGVyICkgPiAkb2xkX21hdGNoZXNbMF1bICRpICsgMSBdWzFdICkgewoJCQkJCSRvbGRfYWZ0ZXIgICAgICAgPSBzdWJzdHIoICRvbGRfYWZ0ZXIsIDAsICRvbGRfbWF0Y2hlc1swXVsgJGkgKyAxIF1bMV0gLSAkb2xkX2VuZF9vZmZzZXQgKTsKCQkJCQkkbmV3X2FmdGVyICAgICAgID0gc3Vic3RyKCAkbmV3X2FmdGVyLCAwLCAkbmV3X21hdGNoZXNbMF1bICRpICsgMSBdWzFdIC0gJG5ld19lbmRfb2Zmc2V0ICk7CgkJCQkJJGFmdGVyX3Nob3J0ZW5lZCA9IHRydWU7CgkJCQkJLy8gT24gdGhlIG5leHQgaXRlcmF0aW9uLCB3aWxsIGFwcGVuZCB3aXRoIG5vIGJlZm9yZSBjb250ZXh0LgoJCQkJfQoJCQl9CgoJCQlpZiAoICRhcHBlbmRfbmV4dCApIHsKCQkJCSRjbnQgICAgICAgICAgICAgICAgICAgPSBjb3VudCggJG9sZF9iaXRzICk7CgkJCQkkb2xkX2JpdHNbICRjbnQgLSAxIF0gLj0gJG9sZF9sb2cgLiAkb2xkX2FmdGVyOwoJCQkJJG5ld19iaXRzWyAkY250IC0gMSBdIC49ICRuZXdfbG9nIC4gJG5ld19hZnRlcjsKCQkJfSBlbHNlIHsKCQkJCSRvbGRfYml0c1tdID0gJG9sZF9iZWZvcmUgLiAkb2xkX2xvZyAuICRvbGRfYWZ0ZXI7CgkJCQkkbmV3X2JpdHNbXSA9ICRuZXdfYmVmb3JlIC4gJG5ld19sb2cgLiAkbmV3X2FmdGVyOwoJCQl9CgkJCSRhcHBlbmRfbmV4dCAgICAgPSAkYWZ0ZXJfc2hvcnRlbmVkOwoJCQkkbGFzdF9vbGRfb2Zmc2V0ID0gJG9sZF9vZmZzZXQ7CgkJCSRsYXN0X25ld19vZmZzZXQgPSAkbmV3X29mZnNldDsKCQl9CgoJCXJldHVybiBhcnJheSggJG9sZF9iaXRzLCAkbmV3X2JpdHMgKTsKCX0KCgkvKgoJICogT3V0cHV0cyB0aGUgbG9nIHN0cmluZ3MuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkY29sIENvbHVtbiBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJGtleXMgQXNzb2NpYXRpdmUgYXJyYXkgKG9yIG9iamVjdCkgb2YgcHJpbWFyeSBrZXkgbmFtZXMgYW5kIHRoZWlyIHZhbHVlcyBmb3IgdGhlIHJvdyBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gc3RyaW5nICR0YWJsZSBUYWJsZSBiZWluZyBwcm9jZXNzZWQuCgkgKiBAcGFyYW0gYXJyYXkgJG9sZF9iaXRzIEFycmF5IG9mIG9sZCBtYXRjaCBsb2cgc3RyaW5ncy4KCSAqIEBwYXJhbSBhcnJheSAkbmV3X2JpdHMgQXJyYXkgb2YgbmV3IHJlcGxhY2VtZW50IGxvZyBzdHJpbmdzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGxvZ193cml0ZSggJGNvbCwgJGtleXMsICR0YWJsZSwgJG9sZF9iaXRzLCAkbmV3X2JpdHMgKSB7CgkJJGlkX2xvZyAgICAgICAgICAgICAgPSAka2V5cyA/ICggJzonIC4gaW1wbG9kZSggJywnLCAoYXJyYXkpICRrZXlzICkgKSA6ICcnOwoJCSR0YWJsZV9jb2x1bW5faWRfbG9nID0gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ190YWJsZV9jb2x1bW5faWQnXVswXSAuICR0YWJsZSAuICcuJyAuICRjb2wgLiAkaWRfbG9nIC4gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ190YWJsZV9jb2x1bW5faWQnXVsxXTsKCgkJJG9sZF9sb2cgPSBzdHJfcmVwbGFjZSggYXJyYXkoICJcclxuIiwgIlxuIiApLCAnICcsIGltcGxvZGUoICcgWy4uLl0gJywgJG9sZF9iaXRzICkgKTsKCQkkbmV3X2xvZyA9IHN0cl9yZXBsYWNlKCBhcnJheSggIlxyXG4iLCAiXG4iICksICcgJywgaW1wbG9kZSggJyBbLi4uXSAnLCAkbmV3X2JpdHMgKSApOwoKCQlpZiAoICR0aGlzLT5sb2dfcHJlZml4ZXNbMF0gKSB7CgkJCSRvbGRfbG9nID0gJHRoaXMtPmxvZ19jb2xvcnNbJ2xvZ19vbGQnXVswXSAuICR0aGlzLT5sb2dfcHJlZml4ZXNbMF0gLiAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX29sZCddWzFdIC4gJG9sZF9sb2c7CgkJfQoJCWlmICggJHRoaXMtPmxvZ19wcmVmaXhlc1sxXSApIHsKCQkJJG5ld19sb2cgPSAkdGhpcy0+bG9nX2NvbG9yc1snbG9nX25ldyddWzBdIC4gJHRoaXMtPmxvZ19wcmVmaXhlc1sxXSAuICR0aGlzLT5sb2dfY29sb3JzWydsb2dfbmV3J11bMV0gLiAkbmV3X2xvZzsKCQl9CgoJCWZ3cml0ZSggJHRoaXMtPmxvZ19oYW5kbGUsICJ7JHRhYmxlX2NvbHVtbl9pZF9sb2d9XG57JG9sZF9sb2d9XG57JG5ld19sb2d9XG4iICk7Cgl9Cgp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIEFycmF5T2JqZWN0Owp1c2UgRXhjZXB0aW9uOwoKY2xhc3MgU2VhcmNoUmVwbGFjZXIgewoKCXByaXZhdGUgJGZyb207Cglwcml2YXRlICR0bzsKCXByaXZhdGUgJHJlY3Vyc2Vfb2JqZWN0czsKCXByaXZhdGUgJHJlZ2V4OwoJcHJpdmF0ZSAkcmVnZXhfZmxhZ3M7Cglwcml2YXRlICRyZWdleF9kZWxpbWl0ZXI7Cglwcml2YXRlICRyZWdleF9saW1pdDsKCXByaXZhdGUgJGxvZ2dpbmc7Cglwcml2YXRlICRsb2dfZGF0YTsKCXByaXZhdGUgJG1heF9yZWN1cnNpb247CgoJLyoqCgkgKiBAcGFyYW0gc3RyaW5nICAkZnJvbSAgICAgICAgICAgIFN0cmluZyB3ZSdyZSBsb29raW5nIHRvIHJlcGxhY2UuCgkgKiBAcGFyYW0gc3RyaW5nICAkdG8gICAgICAgICAgICAgIFdoYXQgd2Ugd2FudCBpdCB0byBiZSByZXBsYWNlZCB3aXRoLgoJICogQHBhcmFtIGJvb2wgICAgJHJlY3Vyc2Vfb2JqZWN0cyBTaG91bGQgb2JqZWN0cyBiZSByZWN1cnNpdmVseSByZXBsYWNlZD8KCSAqIEBwYXJhbSBib29sICAgICRyZWdleCAgICAgICAgICAgV2hldGhlciBgJGZyb21gIGlzIGEgcmVndWxhciBleHByZXNzaW9uLgoJICogQHBhcmFtIHN0cmluZyAgJHJlZ2V4X2ZsYWdzICAgICBGbGFncyBmb3IgcmVndWxhciBleHByZXNzaW9uLgoJICogQHBhcmFtIHN0cmluZyAgJHJlZ2V4X2RlbGltaXRlciBEZWxpbWl0ZXIgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbi4KCSAqIEBwYXJhbSBib29sICAgICRsb2dnaW5nICAgICAgICAgV2hldGhlciBsb2dnaW5nLgoJICogQHBhcmFtIGludGVnZXIgJHJlZ2V4X2xpbWl0ICAgICBUaGUgbWF4aW11bSBwb3NzaWJsZSByZXBsYWNlbWVudHMgZm9yIGVhY2ggcGF0dGVybiBpbiBlYWNoIHN1YmplY3Qgc3RyaW5nLgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRmcm9tLCAkdG8sICRyZWN1cnNlX29iamVjdHMgPSBmYWxzZSwgJHJlZ2V4ID0gZmFsc2UsICRyZWdleF9mbGFncyA9ICcnLCAkcmVnZXhfZGVsaW1pdGVyID0gJy8nLCAkbG9nZ2luZyA9IGZhbHNlLCAkcmVnZXhfbGltaXQgPSAtMSApIHsKCQkkdGhpcy0+ZnJvbSAgICAgICAgICAgID0gJGZyb207CgkJJHRoaXMtPnRvICAgICAgICAgICAgICA9ICR0bzsKCQkkdGhpcy0+cmVjdXJzZV9vYmplY3RzID0gJHJlY3Vyc2Vfb2JqZWN0czsKCQkkdGhpcy0+cmVnZXggICAgICAgICAgID0gJHJlZ2V4OwoJCSR0aGlzLT5yZWdleF9mbGFncyAgICAgPSAkcmVnZXhfZmxhZ3M7CgkJJHRoaXMtPnJlZ2V4X2RlbGltaXRlciA9ICRyZWdleF9kZWxpbWl0ZXI7CgkJJHRoaXMtPnJlZ2V4X2xpbWl0ICAgICA9ICRyZWdleF9saW1pdDsKCQkkdGhpcy0+bG9nZ2luZyAgICAgICAgID0gJGxvZ2dpbmc7CgkJJHRoaXMtPmNsZWFyX2xvZ19kYXRhKCk7CgoJCS8vIEdldCB0aGUgWERlYnVnIG5lc3RpbmcgbGV2ZWwuIFdpbGwgYmUgemVybyAobm8gbGltaXQpIGlmIG5vIHZhbHVlIGlzIHNldAoJCSR0aGlzLT5tYXhfcmVjdXJzaW9uID0gaW50dmFsKCBpbmlfZ2V0KCAneGRlYnVnLm1heF9uZXN0aW5nX2xldmVsJyApICk7Cgl9CgoJLyoqCgkgKiBUYWtlIGEgc2VyaWFsaXNlZCBhcnJheSBhbmQgdW5zZXJpYWxpc2UgaXQgcmVwbGFjaW5nIGVsZW1lbnRzIGFzIG5lZWRlZCBhbmQKCSAqIHVuc2VyaWFsaXNpbmcgYW55IHN1Ym9yZGluYXRlIGFycmF5cyBhbmQgcGVyZm9ybWluZyB0aGUgcmVwbGFjZSBvbiB0aG9zZSB0b28uCgkgKiBJZ25vcmVzIGFueSBzZXJpYWxpemVkIG9iamVjdHMgdW5sZXNzICRyZWN1cnNlX29iamVjdHMgaXMgc2V0IHRvIHRydWUuCgkgKgoJICogQHBhcmFtIGFycmF5fHN0cmluZyAkZGF0YSAgICAgICAgICAgIFRoZSBkYXRhIHRvIG9wZXJhdGUgb24uCgkgKiBAcGFyYW0gYm9vbCAgICAgICAgICRzZXJpYWxpc2VkICAgICAgRG9lcyB0aGUgdmFsdWUgb2YgJGRhdGEgbmVlZCB0byBiZSB1bnNlcmlhbGl6ZWQ/CgkgKgoJICogQHJldHVybiBhcnJheSAgICAgICBUaGUgb3JpZ2luYWwgYXJyYXkgd2l0aCBhbGwgZWxlbWVudHMgcmVwbGFjZWQgYXMgbmVlZGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcnVuKCAkZGF0YSwgJHNlcmlhbGlzZWQgPSBmYWxzZSApIHsKCQlyZXR1cm4gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJGRhdGEsICRzZXJpYWxpc2VkICk7Cgl9CgoJLyoqCgkgKiBAcGFyYW0gaW50ICAgICAgICAgICRyZWN1cnNpb25fbGV2ZWwgQ3VycmVudCByZWN1cnNpb24gZGVwdGggd2l0aGluIHRoZSBvcmlnaW5hbCBkYXRhLgoJICogQHBhcmFtIGFycmF5ICAgICAgICAkdmlzaXRlZF9kYXRhICAgIERhdGEgdGhhdCBoYXMgYmVlbiBzZWVuIGluIHByZXZpb3VzIHJlY3Vyc2lvbiBpdGVyYXRpb25zLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHJ1bl9yZWN1cnNpdmVseSggJGRhdGEsICRzZXJpYWxpc2VkLCAkcmVjdXJzaW9uX2xldmVsID0gMCwgJHZpc2l0ZWRfZGF0YSA9IGFycmF5KCkgKSB7CgoJCS8vIHNvbWUgdW5zZXJpbGlhc2VkIGRhdGEgY2Fubm90IGJlIHJlLXNlcmlhbGlzZWQgZWcuIFNpbXBsZVhNTEVsZW1lbnRzCgkJdHJ5IHsKCgkJCWlmICggJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cyApIHsKCgkJCQkvLyBJZiB3ZSd2ZSByZWFjaGVkIHRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBsZXZlbCwgc2hvcnQgY2lyY3VpdAoJCQkJaWYgKCAwICE9PSAkdGhpcy0+bWF4X3JlY3Vyc2lvbiAmJiAkcmVjdXJzaW9uX2xldmVsID49ICR0aGlzLT5tYXhfcmVjdXJzaW9uICkgewoJCQkJCXJldHVybiAkZGF0YTsKCQkJCX0KCgkJCQlpZiAoIGlzX2FycmF5KCAkZGF0YSApIHx8IGlzX29iamVjdCggJGRhdGEgKSApIHsKCQkJCQkvLyBJZiB3ZSd2ZSBzZWVuIHRoaXMgZXhhY3Qgb2JqZWN0IG9yIGFycmF5IGJlZm9yZSwgc2hvcnQgY2lyY3VpdAoJCQkJCWlmICggaW5fYXJyYXkoICRkYXRhLCAkdmlzaXRlZF9kYXRhLCB0cnVlICkgKSB7CgkJCQkJCXJldHVybiAkZGF0YTsgLy8gQXZvaWQgaW5maW5pdGUgbG9vcHMgd2hlbiB0aGVyZSdzIGEgY3ljbGUKCQkJCQl9CgkJCQkJLy8gQWRkIHRoaXMgZGF0YSB0byB0aGUgbGlzdCBvZgoJCQkJCSR2aXNpdGVkX2RhdGFbXSA9ICRkYXRhOwoJCQkJfQoJCQl9CgoJCQkkdW5zZXJpYWxpemVkID0gaXNfc3RyaW5nKCAkZGF0YSApID8gQHVuc2VyaWFsaXplKCAkZGF0YSApIDogZmFsc2U7CgkJCWlmICggZmFsc2UgIT09ICR1bnNlcmlhbGl6ZWQgKSB7CgkJCQkkZGF0YSA9ICR0aGlzLT5ydW5fcmVjdXJzaXZlbHkoICR1bnNlcmlhbGl6ZWQsIHRydWUsICRyZWN1cnNpb25fbGV2ZWwgKyAxICk7CgkJCX0gZWxzZWlmICggaXNfYXJyYXkoICRkYXRhICkgKSB7CgkJCQkka2V5cyA9IGFycmF5X2tleXMoICRkYXRhICk7CgkJCQlmb3JlYWNoICggJGtleXMgYXMgJGtleSApIHsKCQkJCQkkZGF0YVsgJGtleSBdID0gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJGRhdGFbICRrZXkgXSwgZmFsc2UsICRyZWN1cnNpb25fbGV2ZWwgKyAxLCAkdmlzaXRlZF9kYXRhICk7CgkJCQl9CgkJCX0gZWxzZWlmICggJHRoaXMtPnJlY3Vyc2Vfb2JqZWN0cyAmJiAoIGlzX29iamVjdCggJGRhdGEgKSB8fCAkZGF0YSBpbnN0YW5jZW9mIFxfX1BIUF9JbmNvbXBsZXRlX0NsYXNzICkgKSB7CgkJCQlpZiAoICRkYXRhIGluc3RhbmNlb2YgXF9fUEhQX0luY29tcGxldGVfQ2xhc3MgKSB7CgkJCQkJJGFycmF5ID0gbmV3IEFycmF5T2JqZWN0KCAkZGF0YSApOwoJCQkJCVxXUF9DTEk6Ondhcm5pbmcoCgkJCQkJCXNwcmludGYoCgkJCQkJCQknU2tpcHBpbmcgYW4gdW5pbml0aWFsaXplZCBjbGFzcyAiJXMiLCByZXBsYWNlbWVudHMgbWlnaHQgbm90IGJlIGNvbXBsZXRlLicsCgkJCQkJCQkkYXJyYXlbJ19fUEhQX0luY29tcGxldGVfQ2xhc3NfTmFtZSddCgkJCQkJCSkKCQkJCQkpOwoJCQkJfSBlbHNlIHsKCQkJCQlmb3JlYWNoICggJGRhdGEgYXMgJGtleSA9PiAkdmFsdWUgKSB7CgkJCQkJCSRkYXRhLT4ka2V5ID0gJHRoaXMtPnJ1bl9yZWN1cnNpdmVseSggJHZhbHVlLCBmYWxzZSwgJHJlY3Vyc2lvbl9sZXZlbCArIDEsICR2aXNpdGVkX2RhdGEgKTsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZWlmICggaXNfc3RyaW5nKCAkZGF0YSApICkgewoJCQkJaWYgKCAkdGhpcy0+bG9nZ2luZyApIHsKCQkJCQkkb2xkX2RhdGEgPSAkZGF0YTsKCQkJCX0KCQkJCWlmICggJHRoaXMtPnJlZ2V4ICkgewoJCQkJCSRzZWFyY2hfcmVnZXggID0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJCQkkc2VhcmNoX3JlZ2V4IC49ICR0aGlzLT5mcm9tOwoJCQkJCSRzZWFyY2hfcmVnZXggLj0gJHRoaXMtPnJlZ2V4X2RlbGltaXRlcjsKCQkJCQkkc2VhcmNoX3JlZ2V4IC49ICR0aGlzLT5yZWdleF9mbGFnczsKCgkJCQkJJHJlc3VsdCA9IHByZWdfcmVwbGFjZSggJHNlYXJjaF9yZWdleCwgJHRoaXMtPnRvLCAkZGF0YSwgJHRoaXMtPnJlZ2V4X2xpbWl0ICk7CgkJCQkJaWYgKCBudWxsID09PSAkcmVzdWx0IHx8IFBSRUdfTk9fRVJST1IgIT09IHByZWdfbGFzdF9lcnJvcigpICkgewoJCQkJCQlcV1BfQ0xJOjp3YXJuaW5nKAoJCQkJCQkJc3ByaW50ZigKCQkJCQkJCQknVGhlIHByb3ZpZGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aHJldyBhIFBDUkUgZXJyb3IgLSAlcycsCgkJCQkJCQkJJHRoaXMtPnByZWdfZXJyb3JfbWVzc2FnZSggJHJlc3VsdCApCgkJCQkJCQkpCgkJCQkJCSk7CgkJCQkJfQoJCQkJCSRkYXRhID0gJHJlc3VsdDsKCQkJCX0gZWxzZSB7CgkJCQkJJGRhdGEgPSBzdHJfcmVwbGFjZSggJHRoaXMtPmZyb20sICR0aGlzLT50bywgJGRhdGEgKTsKCQkJCX0KCQkJCWlmICggJHRoaXMtPmxvZ2dpbmcgJiYgJG9sZF9kYXRhICE9PSAkZGF0YSApIHsKCQkJCQkkdGhpcy0+bG9nX2RhdGFbXSA9ICRvbGRfZGF0YTsKCQkJCX0KCQkJfQoKCQkJaWYgKCAkc2VyaWFsaXNlZCApIHsKCQkJCXJldHVybiBzZXJpYWxpemUoICRkYXRhICk7CgkJCX0KCQl9IGNhdGNoICggRXhjZXB0aW9uICRlcnJvciApIHsgLy8gcGhwY3M6aWdub3JlIEdlbmVyaWMuQ29kZUFuYWx5c2lzLkVtcHR5U3RhdGVtZW50LkRldGVjdGVkQ2F0Y2ggLS0gRGVsaWJlcmFsbHkgZW1wdHkuCgoJCX0KCgkJcmV0dXJuICRkYXRhOwoJfQoKCS8qKgoJICogR2V0cyBleGlzdGluZyBkYXRhIHNhdmVkIGZvciB0aGlzIHJ1biB3aGVuIGxvZ2dpbmcuCgkgKiBAcmV0dXJuIGFycmF5IEFycmF5IG9mIGRhdGEgc3RyaW5ncywgcHJpb3IgdG8gcmVwbGFjZW1lbnRzLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZ2V0X2xvZ19kYXRhKCkgewoJCXJldHVybiAkdGhpcy0+bG9nX2RhdGE7Cgl9CgoJLyoqCgkgKiBDbGVhcnMgZGF0YSBzdG9yZWQgZm9yIGxvZ2dpbmcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjbGVhcl9sb2dfZGF0YSgpIHsKCQkkdGhpcy0+bG9nX2RhdGEgPSBhcnJheSgpOwoJfQoKCS8qKgoJICogR2V0IHRoZSBQQ1JFIGVycm9yIGNvbnN0YW50IG5hbWUgZnJvbSBhbiBlcnJvciB2YWx1ZS4KCSAqCgkgKiBAcGFyYW0gIGludGVnZXIgJGVycm9yIEVycm9yIGNvZGUuCgkgKiBAcmV0dXJuIHN0cmluZyAgICAgICAgIEVycm9yIGNvbnN0YW50IG5hbWUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcHJlZ19lcnJvcl9tZXNzYWdlKCAkZXJyb3IgKSB7CgkJc3RhdGljICRlcnJvcl9uYW1lcyA9IG51bGw7CgoJCWlmICggbnVsbCA9PT0gJGVycm9yX25hbWVzICkgewoJCQkkZGVmaW5pdGlvbnMgICAgPSBnZXRfZGVmaW5lZF9jb25zdGFudHMoIHRydWUgKTsKCQkJJHBjcmVfY29uc3RhbnRzID0gYXJyYXlfa2V5X2V4aXN0cyggJ3BjcmUnLCAkZGVmaW5pdGlvbnMgKQoJCQkJPyAkZGVmaW5pdGlvbnNbJ3BjcmUnXQoJCQkJOiBhcnJheSgpOwoJCQkkZXJyb3JfbmFtZXMgICAgPSBhcnJheV9mbGlwKCAkcGNyZV9jb25zdGFudHMgKTsKCQl9CgoJCXJldHVybiBpc3NldCggJGVycm9yX25hbWVzWyAkZXJyb3IgXSApCgkJCT8gJGVycm9yX25hbWVzWyAkZXJyb3IgXQoJCQk6ICc8dW5rbm93biBlcnJvcj4nOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfY2FjaGVfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfY2FjaGVfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9jYWNoZV9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnY2FjaGUnLCAnQ2FjaGVfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3RyYW5zaWVudCcsICdUcmFuc2llbnRfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQWRkcywgZ2V0cywgYW5kIGRlbGV0ZXMgZW50cmllcyBpbiB0aGUgV29yZFByZXNzIFRyYW5zaWVudCBDYWNoZS4KICoKICogQnkgZGVmYXVsdCwgdGhlIHRyYW5zaWVudCBjYWNoZSB1c2VzIHRoZSBXb3JkUHJlc3MgZGF0YWJhc2UgdG8gcGVyc2lzdCB2YWx1ZXMKICogYmV0d2VlbiByZXF1ZXN0cy4gT24gYSBzaW5nbGUgc2l0ZSBpbnN0YWxsYXRpb24sIHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoZQogKiBgd3Bfb3B0aW9uc2AgdGFibGUuIE9uIGEgbXVsdGlzaXRlIGluc3RhbGxhdGlvbiwgdmFsdWVzIGFyZSBzdG9yZWQgaW4gdGhlCiAqIGB3cF9vcHRpb25zYCBvciB0aGUgYHdwX3NpdGVtZXRhYCB0YWJsZSwgZGVwZW5kaW5nIG9uIHVzZSBvZiB0aGUgYC0tbmV0d29ya2AKICogZmxhZy4KICoKICogV2hlbiBhIHBlcnNpc3RlbnQgb2JqZWN0IGNhY2hlIGRyb3AtaW4gaXMgaW5zdGFsbGVkIChlLmcuIFJlZGlzIG9yIE1lbWNhY2hlZCksCiAqIHRoZSB0cmFuc2llbnQgY2FjaGUgc2tpcHMgdGhlIGRhdGFiYXNlIGFuZCBzaW1wbHkgd3JhcHMgdGhlIFdQIE9iamVjdCBDYWNoZS4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgU2V0IHRyYW5zaWVudC4KICogICAgICQgd3AgdHJhbnNpZW50IHNldCBzYW1wbGVfa2V5ICJ0ZXN0IGRhdGEiIDM2MDAKICogICAgIFN1Y2Nlc3M6IFRyYW5zaWVudCBhZGRlZC4KICoKICogICAgICMgR2V0IHRyYW5zaWVudC4KICogICAgICQgd3AgdHJhbnNpZW50IGdldCBzYW1wbGVfa2V5CiAqICAgICB0ZXN0IGRhdGEKICoKICogICAgICMgRGVsZXRlIHRyYW5zaWVudC4KICogICAgICQgd3AgdHJhbnNpZW50IGRlbGV0ZSBzYW1wbGVfa2V5CiAqICAgICBTdWNjZXNzOiBUcmFuc2llbnQgZGVsZXRlZC4KICoKICogICAgICMgRGVsZXRlIGV4cGlyZWQgdHJhbnNpZW50cy4KICogICAgICQgd3AgdHJhbnNpZW50IGRlbGV0ZSAtLWV4cGlyZWQKICogICAgIFN1Y2Nlc3M6IDEyIGV4cGlyZWQgdHJhbnNpZW50cyBkZWxldGVkIGZyb20gdGhlIGRhdGFiYXNlLgogKgogKiAgICAgIyBEZWxldGUgYWxsIHRyYW5zaWVudHMuCiAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgLS1hbGwKICogICAgIFN1Y2Nlc3M6IDE0IHRyYW5zaWVudHMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KICovCmNsYXNzIFRyYW5zaWVudF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogR2V0cyBhIHRyYW5zaWVudCB2YWx1ZS4KCSAqCgkgKiBGb3IgYSBtb3JlIGNvbXBsZXRlIGV4cGxhbmF0aW9uIG9mIHRoZSB0cmFuc2llbnQgY2FjaGUsIGluY2x1ZGluZyB0aGUKCSAqIG5ldHdvcmt8c2l0ZSBjYWNoZSwgcGxlYXNlIHNlZSBkb2NzIGZvciBgd3AgdHJhbnNpZW50YC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogS2V5IGZvciB0aGUgdHJhbnNpZW50LgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiBbLS1uZXR3b3JrXQoJICogOiBHZXQgdGhlIHZhbHVlIG9mIGEgbmV0d29ya3xzaXRlIHRyYW5zaWVudC4gT24gc2luZ2xlIHNpdGUsIHRoaXMgaXMKCSAqIGlzIGEgc3BlY2lhbGx5LW5hbWVkIGNhY2hlIGtleS4gT24gbXVsdGlzaXRlLCB0aGlzIGlzIGEgZ2xvYmFsIGNhY2hlCgkgKiAoaW5zdGVhZCBvZiBsb2NhbCB0byB0aGUgc2l0ZSkuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZ2V0IHNhbXBsZV9rZXkKCSAqICAgICB0ZXN0IGRhdGEKCSAqCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZ2V0IHJhbmRvbV9rZXkKCSAqICAgICBXYXJuaW5nOiBUcmFuc2llbnQgd2l0aCBrZXkgInJhbmRvbV9rZXkiIGlzIG5vdCBzZXQuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5ICkgPSAkYXJnczsKCgkJJGZ1bmMgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnbmV0d29yaycgKSA/ICdnZXRfc2l0ZV90cmFuc2llbnQnIDogJ2dldF90cmFuc2llbnQnOwoJCSR2YWx1ZSA9ICRmdW5jKCAka2V5ICk7CgoJCWlmICggZmFsc2UgPT09ICR2YWx1ZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnVHJhbnNpZW50IHdpdGgga2V5ICInIC4gJGtleSAuICciIGlzIG5vdCBzZXQuJyApOwoJCQlleGl0OwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogU2V0cyBhIHRyYW5zaWVudCB2YWx1ZS4KCSAqCgkgKiBgPGV4cGlyYXRpb24+YCBpcyB0aGUgdGltZSB1bnRpbCBleHBpcmF0aW9uLCBpbiBzZWNvbmRzLgoJICoKCSAqIEZvciBhIG1vcmUgY29tcGxldGUgZXhwbGFuYXRpb24gb2YgdGhlIHRyYW5zaWVudCBjYWNoZSwgaW5jbHVkaW5nIHRoZQoJICogbmV0d29ya3xzaXRlIGNhY2hlLCBwbGVhc2Ugc2VlIGRvY3MgZm9yIGB3cCB0cmFuc2llbnRgLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBLZXkgZm9yIHRoZSB0cmFuc2llbnQuCgkgKgoJICogPHZhbHVlPgoJICogOiBWYWx1ZSB0byBiZSBzZXQgZm9yIHRoZSB0cmFuc2llbnQuCgkgKgoJICogWzxleHBpcmF0aW9uPl0KCSAqIDogVGltZSB1bnRpbCBleHBpcmF0aW9uLCBpbiBzZWNvbmRzLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IFNldCB0aGUgdmFsdWUgb2YgYSBuZXR3b3JrfHNpdGUgdHJhbnNpZW50LiBPbiBzaW5nbGUgc2l0ZSwgdGhpcyBpcwoJICogaXMgYSBzcGVjaWFsbHktbmFtZWQgY2FjaGUga2V5LiBPbiBtdWx0aXNpdGUsIHRoaXMgaXMgYSBnbG9iYWwgY2FjaGUKCSAqIChpbnN0ZWFkIG9mIGxvY2FsIHRvIHRoZSBzaXRlKS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHRyYW5zaWVudCBzZXQgc2FtcGxlX2tleSAidGVzdCBkYXRhIiAzNjAwCgkgKiAgICAgU3VjY2VzczogVHJhbnNpZW50IGFkZGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJHZhbHVlICkgPSAkYXJnczsKCgkJJGV4cGlyYXRpb24gPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFyZ3MsIDIsIDAgKTsKCgkJJGZ1bmMgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJyApID8gJ3NldF9zaXRlX3RyYW5zaWVudCcgOiAnc2V0X3RyYW5zaWVudCc7CgkJaWYgKCAkZnVuYyggJGtleSwgJHZhbHVlLCAkZXhwaXJhdGlvbiApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUcmFuc2llbnQgYWRkZWQuJyApOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUcmFuc2llbnQgY291bGQgbm90IGJlIHNldC4nICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhIHRyYW5zaWVudCB2YWx1ZS4KCSAqCgkgKiBGb3IgYSBtb3JlIGNvbXBsZXRlIGV4cGxhbmF0aW9uIG9mIHRoZSB0cmFuc2llbnQgY2FjaGUsIGluY2x1ZGluZyB0aGUKCSAqIG5ldHdvcmt8c2l0ZSBjYWNoZSwgcGxlYXNlIHNlZSBkb2NzIGZvciBgd3AgdHJhbnNpZW50YC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxrZXk+XQoJICogOiBLZXkgZm9yIHRoZSB0cmFuc2llbnQuCgkgKgoJICogWy0tbmV0d29ya10KCSAqIDogRGVsZXRlIHRoZSB2YWx1ZSBvZiBhIG5ldHdvcmt8c2l0ZSB0cmFuc2llbnQuIE9uIHNpbmdsZSBzaXRlLCB0aGlzIGlzCgkgKiBpcyBhIHNwZWNpYWxseS1uYW1lZCBjYWNoZSBrZXkuIE9uIG11bHRpc2l0ZSwgdGhpcyBpcyBhIGdsb2JhbCBjYWNoZQoJICogKGluc3RlYWQgb2YgbG9jYWwgdG8gdGhlIHNpdGUpLgoJICoKCSAqIFstLWFsbF0KCSAqIDogRGVsZXRlIGFsbCB0cmFuc2llbnRzLgoJICoKCSAqIFstLWV4cGlyZWRdCgkgKiA6IERlbGV0ZSBhbGwgZXhwaXJlZCB0cmFuc2llbnRzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHRyYW5zaWVudC4KCSAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgc2FtcGxlX2tleQoJICogICAgIFN1Y2Nlc3M6IFRyYW5zaWVudCBkZWxldGVkLgoJICoKCSAqICAgICAjIERlbGV0ZSBleHBpcmVkIHRyYW5zaWVudHMuCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIC0tZXhwaXJlZAoJICogICAgIFN1Y2Nlc3M6IDEyIGV4cGlyZWQgdHJhbnNpZW50cyBkZWxldGVkIGZyb20gdGhlIGRhdGFiYXNlLgoJICoKCSAqICAgICAjIERlbGV0ZSBleHBpcmVkIHNpdGUgdHJhbnNpZW50cy4KCSAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgLS1leHBpcmVkIC0tbmV0d29yawoJICogICAgIFN1Y2Nlc3M6IDEgZXhwaXJlZCB0cmFuc2llbnQgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHRyYW5zaWVudHMuCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgZGVsZXRlIC0tYWxsCgkgKiAgICAgU3VjY2VzczogMTQgdHJhbnNpZW50cyBkZWxldGVkIGZyb20gdGhlIGRhdGFiYXNlLgoJICoKCSAqICAgICAjIERlbGV0ZSBhbGwgc2l0ZSB0cmFuc2llbnRzLgoJICogICAgICQgd3AgdHJhbnNpZW50IGRlbGV0ZSAtLWFsbCAtLW5ldHdvcmsKCSAqICAgICBTdWNjZXNzOiAyIHRyYW5zaWVudHMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4KCSAqCgkgKiAgICAgIyBEZWxldGUgYWxsIHRyYW5zaWVudHMgaW4gYSBtdWx0c2l0ZS4KCSAqICAgICAkIHdwIHRyYW5zaWVudCBkZWxldGUgLS1hbGwgLS1uZXR3b3JrICYmIHdwIHNpdGUgbGlzdCAtLWZpZWxkPXVybCB8IHhhcmdzIC1uMSAtSSAlIHdwIC0tdXJsPSUgdHJhbnNpZW50IGRlbGV0ZSAtLWFsbAoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGtleSA9ICggISBlbXB0eSggJGFyZ3MgKSApID8gJGFyZ3NbMF0gOiBudWxsOwoKCQkkYWxsICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcgKTsKCQkkZXhwaXJlZCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2V4cGlyZWQnICk7CgkJJG5ldHdvcmsgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICduZXR3b3JrJyApOwoKCQlpZiAoIHRydWUgPT09ICRhbGwgKSB7CgkJCSR0aGlzLT5kZWxldGVfYWxsKCAkbmV0d29yayApOwoJCQlyZXR1cm47CgkJfSBlbHNlaWYgKCB0cnVlID09PSAkZXhwaXJlZCApIHsKCQkJJHRoaXMtPmRlbGV0ZV9leHBpcmVkKCAkbmV0d29yayApOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoICEgJGtleSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IHRyYW5zaWVudCBrZXksIG9yIHVzZSAtLWFsbCBvciAtLWV4cGlyZWQuJyApOwoJCX0KCgkJJGZ1bmMgPSAkbmV0d29yayA/ICdkZWxldGVfc2l0ZV90cmFuc2llbnQnIDogJ2RlbGV0ZV90cmFuc2llbnQnOwoKCQlpZiAoICRmdW5jKCAka2V5ICkgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ1RyYW5zaWVudCBkZWxldGVkLicgKTsKCQl9IGVsc2UgewoJCQkkZnVuYyA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnICkgPyAnZ2V0X3NpdGVfdHJhbnNpZW50JyA6ICdnZXRfdHJhbnNpZW50JzsKCQkJaWYgKCAkZnVuYyggJGtleSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ1RyYW5zaWVudCB3YXMgbm90IGRlbGV0ZWQgZXZlbiB0aG91Z2ggdGhlIHRyYW5zaWVudCBhcHBlYXJzIHRvIGV4aXN0LicgKTsKCQkJfSBlbHNlIHsKCQkJCVdQX0NMSTo6d2FybmluZyggJ1RyYW5zaWVudCB3YXMgbm90IGRlbGV0ZWQ7IGhvd2V2ZXIsIHRoZSB0cmFuc2llbnQgZG9lcyBub3QgYXBwZWFyIHRvIGV4aXN0LicgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIERldGVybWluZXMgdGhlIHR5cGUgb2YgdHJhbnNpZW50cyBpbXBsZW1lbnRhdGlvbi4KCSAqCgkgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgdHJhbnNpZW50cyBBUEkgaXMgdXNpbmcgYW4gb2JqZWN0IGNhY2hlIG9yIHRoZQoJICogZGF0YWJhc2UuCgkgKgoJICogRm9yIGEgbW9yZSBjb21wbGV0ZSBleHBsYW5hdGlvbiBvZiB0aGUgdHJhbnNpZW50IGNhY2hlLCBpbmNsdWRpbmcgdGhlCgkgKiBuZXR3b3JrfHNpdGUgY2FjaGUsIHBsZWFzZSBzZWUgZG9jcyBmb3IgYHdwIHRyYW5zaWVudGAuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCB0cmFuc2llbnQgdHlwZQoJICogICAgIFRyYW5zaWVudHMgYXJlIHNhdmVkIHRvIHRoZSBkYXRhYmFzZS4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHR5cGUoKSB7CgkJaWYgKCB3cF91c2luZ19leHRfb2JqZWN0X2NhY2hlKCkgKSB7CgkJCSRtZXNzYWdlID0gJ1RyYW5zaWVudHMgYXJlIHNhdmVkIHRvIHRoZSBvYmplY3QgY2FjaGUuJzsKCQl9IGVsc2UgewoJCQkkbWVzc2FnZSA9ICdUcmFuc2llbnRzIGFyZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UuJzsKCQl9CgoJCVdQX0NMSTo6bGluZSggJG1lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIExpc3RzIHRyYW5zaWVudHMgYW5kIHRoZWlyIHZhbHVlcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tc2VhcmNoPTxwYXR0ZXJuPl0KCSAqIDogVXNlIHdpbGRjYXJkcyAoICogYW5kID8gKSB0byBtYXRjaCB0cmFuc2llbnQgbmFtZS4KCSAqCgkgKiBbLS1leGNsdWRlPTxwYXR0ZXJuPl0KCSAqIDogUGF0dGVybiB0byBleGNsdWRlLiBVc2Ugd2lsZGNhcmRzICggKiBhbmQgPyApIHRvIG1hdGNoIHRyYW5zaWVudCBuYW1lLgoJICoKCSAqIFstLW5ldHdvcmtdCgkgKiA6IEdldCB0aGUgdmFsdWVzIG9mIG5ldHdvcmt8c2l0ZSB0cmFuc2llbnRzLiBPbiBzaW5nbGUgc2l0ZSwgdGhpcyBpcwoJICogYSBzcGVjaWFsbHktbmFtZWQgY2FjaGUga2V5LiBPbiBtdWx0aXNpdGUsIHRoaXMgaXMgYSBnbG9iYWwgY2FjaGUKCSAqIChpbnN0ZWFkIG9mIGxvY2FsIHRvIHRoZSBzaXRlKS4KCSAqCgkgKiBbLS11bnNlcmlhbGl6ZV0KCSAqIDogVW5zZXJpYWxpemUgdHJhbnNpZW50IHZhbHVlcyBpbiBvdXRwdXQuCgkgKgoJICogWy0taHVtYW4tcmVhZGFibGVdCgkgKiA6IEh1bWFuLXJlYWRhYmxlIG91dHB1dCBmb3IgZXhwaXJhdGlvbnMuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIG9iamVjdCBmaWVsZHMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBUaGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgZm9yIHRoZSB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBqc29uCgkgKiAgIC0gY3N2CgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhpcyBmaWVsZCB3aWxsIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0IGZvciBlYWNoIG1hdGNoaW5nIG9wdGlvbjoKCSAqCgkgKiAqIG5hbWUKCSAqICogdmFsdWUKCSAqICogZXhwaXJhdGlvbgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBhbGwgdHJhbnNpZW50cwoJICogICAgICQgd3AgdHJhbnNpZW50IGxpc3QKCSogICAgICArLS0tLS0tKy0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKwoJKiAgICAgIHwgbmFtZSB8IHZhbHVlIHwgZXhwaXJhdGlvbiAgICB8CgkqICAgICAgKy0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0tLS0tLSsKCSogICAgICB8IGZvbyAgfCBiYXIgICB8IDM5IG1pbnMgICAgICAgfAoJKiAgICAgIHwgZm9vMiB8IGJhcjIgIHwgbm8gZXhwaXJhdGlvbiB8CgkqICAgICAgfCBmb28zIHwgYmFyMiAgfCBleHBpcmVkICAgICAgIHwKCSogICAgICB8IGZvbzQgfCBiYXI0ICB8IDQgaG91cnMgICAgICAgfAoJKiAgICAgICstLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0rCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCSRuZXR3b3JrICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ25ldHdvcmsnLCBmYWxzZSApOwoJCSR1bnNlcmlhbGl6ZSAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3Vuc2VyaWFsaXplJywgZmFsc2UgKTsKCQkkaHVtYW5fcmVhZGFibGUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdodW1hbi1yZWFkYWJsZScsIGZhbHNlICk7CgoJCSRmaWVsZHMgPSBhcnJheSggJ25hbWUnLCAndmFsdWUnLCAnZXhwaXJhdGlvbicgKTsKCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1snZmllbGRzJ10gKSApIHsKCQkJJGZpZWxkcyA9IGV4cGxvZGUoICcsJywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7CgkJfQoKCQkkcGF0dGVybiA9ICclJzsKCQkkZXhjbHVkZSA9ICcnOwoJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWydzZWFyY2gnXSApICkgewoJCQkkcGF0dGVybiA9IFV0aWxzXGVzY19saWtlKCAkYXNzb2NfYXJnc1snc2VhcmNoJ10gKTsKCQkJLy8gU3Vic3RpdHV0ZSB3aWxkY2FyZHMuCgkJCSRwYXR0ZXJuID0gc3RyX3JlcGxhY2UoCgkJCQlhcnJheSggJyonLCAnPycgKSwKCQkJCWFycmF5KCAnJScsICdfJyApLAoJCQkJJHBhdHRlcm4KCQkJKTsKCQl9CgkJaWYgKCBpc3NldCggJGFzc29jX2FyZ3NbJ2V4Y2x1ZGUnXSApICkgewoJCQkkZXhjbHVkZSA9IFV0aWxzXGVzY19saWtlKCAkYXNzb2NfYXJnc1snZXhjbHVkZSddICk7CgkJCS8vIFN1YnN0aXR1dGUgd2lsZGNhcmRzLgoJCQkkZXhjbHVkZSA9IHN0cl9yZXBsYWNlKAoJCQkJYXJyYXkoICcqJywgJz8nICksCgkJCQlhcnJheSggJyUnLCAnXycgKSwKCQkJCSRleGNsdWRlCgkJCSk7CgkJfQoKCQlpZiAoICRuZXR3b3JrICkgewoJCQlpZiAoIGlzX211bHRpc2l0ZSgpICkgewoJCQkJJHdoZXJlICA9ICR3cGRiLT5wcmVwYXJlKAoJCQkJCSdXSEVSRSBgbWV0YV9rZXlgIExJS0UgJXMnLAoJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICRwYXR0ZXJuCgkJCQkpOwoJCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKAoJCQkJCScgQU5EIG1ldGFfa2V5IE5PVCBMSUtFICVzJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJwoJCQkJKTsKCQkJCWlmICggJGV4Y2x1ZGUgKSB7CgkJCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKAoJCQkJCQknIEFORCBtZXRhX2tleSBOT1QgTElLRSAlcycsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICRleGNsdWRlCgkJCQkJKTsKCQkJCX0KCgkJCQkkcXVlcnkgPSAiU0VMRUNUIGBtZXRhX2tleWAgYXMgYG5hbWVgLCBgbWV0YV92YWx1ZWAgYXMgYHZhbHVlYCBGUk9NIHskd3BkYi0+c2l0ZW1ldGF9IHskd2hlcmV9IjsKCQkJfSBlbHNlIHsKCQkJCSR3aGVyZSAgPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQknV0hFUkUgYG9wdGlvbl9uYW1lYCBMSUtFICVzJywKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAkcGF0dGVybgoJCQkJKTsKCQkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQknIEFORCBvcHRpb25fbmFtZSBOT1QgTElLRSAlcycsCgkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nICkgLiAnJScKCQkJCSk7CgkJCQlpZiAoICRleGNsdWRlICkgewoJCQkJCSR3aGVyZSAuPSAkd3BkYi0+cHJlcGFyZSgKCQkJCQkJJyBBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJXMnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAkZXhjbHVkZQoJCQkJCSk7CgkJCQl9CgoJCQkJJHF1ZXJ5ID0gIlNFTEVDVCBgb3B0aW9uX25hbWVgIGFzIGBuYW1lYCwgYG9wdGlvbl92YWx1ZWAgYXMgYHZhbHVlYCBGUk9NIHskd3BkYi0+b3B0aW9uc30geyR3aGVyZX0iOwoJCQl9CgkJfSBlbHNlIHsKCQkJJHdoZXJlICA9ICR3cGRiLT5wcmVwYXJlKAoJCQkJJ1dIRVJFIGBvcHRpb25fbmFtZWAgTElLRSAlcycsCgkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfJyApIC4gJHBhdHRlcm4KCQkJKTsKCQkJJHdoZXJlIC49ICR3cGRiLT5wcmVwYXJlKAoJCQkJJyBBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJXMnLAoJCQkJVXRpbHNcZXNjX2xpa2UoICdfdHJhbnNpZW50X3RpbWVvdXRfJyApIC4gJyUnCgkJCSk7CgkJCWlmICggJGV4Y2x1ZGUgKSB7CgkJCQkkd2hlcmUgLj0gJHdwZGItPnByZXBhcmUoCgkJCQkJJyBBTkQgb3B0aW9uX25hbWUgTk9UIExJS0UgJXMnLAoJCQkJCVV0aWxzXGVzY19saWtlKCAnX3RyYW5zaWVudF8nICkgLiAkZXhjbHVkZQoJCQkJKTsKCQkJfQoKCQkJJHF1ZXJ5ID0gIlNFTEVDVCBgb3B0aW9uX25hbWVgIGFzIGBuYW1lYCwgYG9wdGlvbl92YWx1ZWAgYXMgYHZhbHVlYCBGUk9NIHskd3BkYi0+b3B0aW9uc30geyR3aGVyZX0iOwoJCX0KCgkJLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5EQi5QcmVwYXJlZFNRTC5Ob3RQcmVwYXJlZCAtLSBQcmVwYXJlZCBwcm9wZXJseSBhYm92ZS4KCQkkcmVzdWx0cyA9ICR3cGRiLT5nZXRfcmVzdWx0cyggJHF1ZXJ5ICk7CgoJCWZvcmVhY2ggKCAkcmVzdWx0cyBhcyAkcmVzdWx0ICkgewoJCQkkcmVzdWx0LT5uYW1lICAgICAgID0gc3RyX3JlcGxhY2UoIGFycmF5KCAnX3NpdGVfdHJhbnNpZW50XycsICdfdHJhbnNpZW50XycgKSwgJycsICRyZXN1bHQtPm5hbWUgKTsKCQkJJHJlc3VsdC0+ZXhwaXJhdGlvbiA9ICR0aGlzLT5nZXRfdHJhbnNpZW50X2V4cGlyYXRpb24oICRyZXN1bHQtPm5hbWUsICRuZXR3b3JrLCAkaHVtYW5fcmVhZGFibGUgKTsKCgkJCWlmICggJHVuc2VyaWFsaXplICkgewoJCQkJJHJlc3VsdC0+dmFsdWUgPSBtYXliZV91bnNlcmlhbGl6ZSggJHJlc3VsdC0+dmFsdWUgKTsKCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBcV1BfQ0xJXEZvcm1hdHRlcigKCQkJJGFzc29jX2FyZ3MsCgkJCSRmaWVsZHMKCQkpOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRyZXN1bHRzICk7Cgl9CgoJLyoqCgkgKiBSZXRyaWV2ZXMgdGhlIGV4cGlyYXRpb24gdGltZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lICAgICAgICAgICAgICBUcmFuc2llbnQgbmFtZS4KCSAqIEBwYXJhbSBib29sICAgJGlzX3NpdGVfdHJhbnNpZW50IE9wdGlvbmFsLiBXaGV0aGVyIHRoaXMgaXMgYSBzaXRlIHRyYW5zaWVudC4gRGVmYXVsdCBmYWxzZS4KCSAqIEBwYXJhbSBib29sICAgJGh1bWFuX3JlYWRhYmxlICAgIE9wdGlvbmFsLiBXaGV0aGVyIHRvIHJldHVybiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG5vdyBhbmQgdGhlCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmF0aW9uIHRpbWUgaW4gYSBodW1hbi1yZWFkYWJsZSBmb3JtYXQuIERlZmF1bHQgZmFsc2UuCgkgKiBAcmV0dXJuIHN0cmluZyBFeHBpcmF0aW9uIHRpbWUgc3RyaW5nLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF90cmFuc2llbnRfZXhwaXJhdGlvbiggJG5hbWUsICRpc19zaXRlX3RyYW5zaWVudCA9IGZhbHNlLCAkaHVtYW5fcmVhZGFibGUgPSBmYWxzZSApIHsKCQlpZiAoICRpc19zaXRlX3RyYW5zaWVudCApIHsKCQkJaWYgKCBpc19tdWx0aXNpdGUoKSApIHsKCQkJCSRleHBpcmF0aW9uID0gKGludCkgZ2V0X3NpdGVfb3B0aW9uKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJyAuICRuYW1lICk7CgkJCX0gZWxzZSB7CgkJCQkkZXhwaXJhdGlvbiA9IChpbnQpIGdldF9vcHRpb24oICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nIC4gJG5hbWUgKTsKCQkJfQoJCX0gZWxzZSB7CgkJCSRleHBpcmF0aW9uID0gKGludCkgZ2V0X29wdGlvbiggJ190cmFuc2llbnRfdGltZW91dF8nIC4gJG5hbWUgKTsKCQl9CgoJCWlmICggMCA9PT0gJGV4cGlyYXRpb24gKSB7CgkJCXJldHVybiAkaHVtYW5fcmVhZGFibGUgPyAnbmV2ZXIgZXhwaXJlcycgOiAnZmFsc2UnOwoJCX0KCgkJaWYgKCAhICRodW1hbl9yZWFkYWJsZSApIHsKCQkJcmV0dXJuICRleHBpcmF0aW9uOwoJCX0KCgkJJG5vdyA9IHRpbWUoKTsKCgkJaWYgKCAkbm93ID4gJGV4cGlyYXRpb24gKSB7CgkJCXJldHVybiAnZXhwaXJlZCc7CgkJfQoKCQlyZXR1cm4gaHVtYW5fdGltZV9kaWZmKCAkbm93LCAkZXhwaXJhdGlvbiApOwoJfQoKCS8qKgoJICogRGVsZXRlcyBhbGwgZXhwaXJlZCB0cmFuc2llbnRzLgoJICoKCSAqIE9ubHkgZGVsZXRlcyB0aGUgZXhwaXJlZCB0cmFuc2llbnRzIGZyb20gdGhlIGRhdGFiYXNlLgoJICoKCSAqIEBwYXJhbSBib29sICRuZXR3b3JrIFdoZXRoZXIgdG8gZGVsZXRlIHRyYW5zaWVudHMgb3IgbmV0d29ya3xzaXRlIHRyYW5zaWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZGVsZXRlX2V4cGlyZWQoICRuZXR3b3JrICkgewoJCWdsb2JhbCAkd3BkYjsKCgkJJGNvdW50ID0gMDsKCgkJaWYgKCAhICRuZXR3b3JrICkgewoJCQkkY291bnQgKz0gJHdwZGItPnF1ZXJ5KAoJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJIkRFTEVURSBhLCBiIEZST00geyR3cGRiLT5vcHRpb25zfSBhLCB7JHdwZGItPm9wdGlvbnN9IGIKCQkJCQkJV0hFUkUgYS5vcHRpb25fbmFtZSBMSUtFICVzCgkJCQkJCUFORCBhLm9wdGlvbl9uYW1lIE5PVCBMSUtFICVzCgkJCQkJCUFORCBiLm9wdGlvbl9uYW1lID0gQ09OQ0FUKCAnX3RyYW5zaWVudF90aW1lb3V0XycsIFNVQlNUUklORyggYS5vcHRpb25fbmFtZSwgMTIgKSApCgkJCQkJCUFORCBiLm9wdGlvbl92YWx1ZSA8ICVkIiwKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCVV0aWxzXGVzY19saWtlKCAnX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJywKCQkJCQl0aW1lKCkKCQkJCSkKCQkJKTsKCQl9IGVsc2UgewoJCQlpZiAoICEgaXNfbXVsdGlzaXRlKCkgKSB7CgkJCQkvLyBOb24tTXVsdGlzaXRlIHN0b3JlcyBzaXRlIHRyYW5zaWVudHMgaW4gdGhlIG9wdGlvbnMgdGFibGUuCgkJCQkkY291bnQgKz0gJHdwZGItPnF1ZXJ5KAoJCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCQkiREVMRVRFIGEsIGIgRlJPTSB7JHdwZGItPm9wdGlvbnN9IGEsIHskd3BkYi0+b3B0aW9uc30gYgoJCQkJCQkJV0hFUkUgYS5vcHRpb25fbmFtZSBMSUtFICVzCgkJCQkJCQlBTkQgYS5vcHRpb25fbmFtZSBOT1QgTElLRSAlcwoJCQkJCQkJQU5EIGIub3B0aW9uX25hbWUgPSBDT05DQVQoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEub3B0aW9uX25hbWUsIDE3ICkgKQoJCQkJCQkJQU5EIGIub3B0aW9uX3ZhbHVlIDwgJWQiLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF8nICkgLiAnJScsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50X3RpbWVvdXRfJyApIC4gJyUnLAoJCQkJCQl0aW1lKCkKCQkJCQkpCgkJCQkpOwoJCQl9IGVsc2UgewoJCQkJLy8gTXVsdGlzaXRlIHN0b3JlcyBzaXRlIHRyYW5zaWVudHMgaW4gdGhlIHNpdGVtZXRhIHRhYmxlLgoJCQkJJGNvdW50ICs9ICR3cGRiLT5xdWVyeSgKCQkJCQkkd3BkYi0+cHJlcGFyZSgKCQkJCQkJIkRFTEVURSBhLCBiIEZST00geyR3cGRiLT5zaXRlbWV0YX0gYSwgeyR3cGRiLT5zaXRlbWV0YX0gYgoJCQkJCQkJV0hFUkUgYS5tZXRhX2tleSBMSUtFICVzCgkJCQkJCQlBTkQgYS5tZXRhX2tleSBOT1QgTElLRSAlcwoJCQkJCQkJQU5EIGIubWV0YV9rZXkgPSBDT05DQVQoICdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nLCBTVUJTVFJJTkcoIGEubWV0YV9rZXksIDE3ICkgKQoJCQkJCQkJQU5EIGIubWV0YV92YWx1ZSA8ICVkIiwKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJywKCQkJCQkJdGltZSgpCgkJCQkJKQoJCQkJKTsKCQkJfQoJCX0KCgkJLy8gVGhlIGFib3ZlIHF1ZXJpZXMgZGVsZXRlIHRoZSB0cmFuc2llbnQgYW5kIHRoZSB0cmFuc2llbnQgdGltZW91dAoJCS8vIHRodXMgZWFjaCB0cmFuc2llbnQgaXMgY291bnRlZCB0d2ljZS4KCQkkY291bnQgPSAkY291bnQgLyAyOwoKCQlpZiAoICRjb3VudCA+IDAgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcygKCQkJCXNwcmludGYoCgkJCQkJJyVkIGV4cGlyZWQgJXMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4nLAoJCQkJCSRjb3VudCwKCQkJCQlVdGlsc1xwbHVyYWxpemUoICd0cmFuc2llbnQnLCAkY291bnQgKQoJCQkJKQoJCQkpOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ05vIGV4cGlyZWQgdHJhbnNpZW50cyBmb3VuZC4nICk7CgkJfQoKCQlpZiAoIHdwX3VzaW5nX2V4dF9vYmplY3RfY2FjaGUoKSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAnVHJhbnNpZW50cyBhcmUgc3RvcmVkIGluIGFuIGV4dGVybmFsIG9iamVjdCBjYWNoZSwgYW5kIHRoaXMgY29tbWFuZCBvbmx5IGRlbGV0ZXMgdGhvc2Ugc3RvcmVkIGluIHRoZSBkYXRhYmFzZS4gWW91IG11c3QgZmx1c2ggdGhlIGNhY2hlIHRvIGRlbGV0ZSBhbGwgdHJhbnNpZW50cy4nICk7CgkJfQoJfQoKCS8qKgoJICogRGVsZXRlcyBhbGwgdHJhbnNpZW50cy4KCSAqCgkgKiBPbmx5IGRlbGV0ZXMgdGhlIHRyYW5zaWVudHMgZnJvbSB0aGUgZGF0YWJhc2UuCgkgKgoJICogQHBhcmFtIGJvb2wgJG5ldHdvcmsgV2hldGhlciB0byBkZWxldGUgdHJhbnNpZW50cyBvciBuZXR3b3JrfHNpdGUgdHJhbnNpZW50cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBkZWxldGVfYWxsKCAkbmV0d29yayApIHsKCQlnbG9iYWwgJHdwZGI7CgoJCS8vIFRvIGVuc3VyZSBwcm9wZXIgY291bnQgdmFsdWVzIHdlIGZpcnN0IGRlbGV0ZSBhbGwgdHJhbnNpZW50cyB3aXRoIGEgdGltZW91dAoJCS8vIGFuZCB0aGVuIHRoZSByZW1haW5pbmcgdHJhbnNpZW50cyB3aXRob3V0IGEgdGltZW91dC4KCQkkY291bnQgPSAwOwoKCQlpZiAoICEgJG5ldHdvcmsgKSB7CgkJCSRkZWxldGVkID0gJHdwZGItPnF1ZXJ5KAoJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJIkRFTEVURSBhLCBiIEZST00geyR3cGRiLT5vcHRpb25zfSBhLCB7JHdwZGItPm9wdGlvbnN9IGIKCQkJCQkJV0hFUkUgYS5vcHRpb25fbmFtZSBMSUtFICVzCgkJCQkJCUFORCBhLm9wdGlvbl9uYW1lIE5PVCBMSUtFICVzCgkJCQkJCUFORCBiLm9wdGlvbl9uYW1lID0gQ09OQ0FUKCAnX3RyYW5zaWVudF90aW1lb3V0XycsIFNVQlNUUklORyggYS5vcHRpb25fbmFtZSwgMTIgKSApIiwKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCVV0aWxzXGVzY19saWtlKCAnX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJwoJCQkJKQoJCQkpOwoKCQkJJGNvdW50ICs9ICRkZWxldGVkIC8gMjsgLy8gSWdub3JlIGFmZmVjdGVkIHJvd3MgZm9yIHRpbWVvdXRzLgoKCQkJJGNvdW50ICs9ICR3cGRiLT5xdWVyeSgKCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCSJERUxFVEUgRlJPTSAkd3BkYi0+b3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZSBMSUtFICVzIiwKCQkJCQlVdGlsc1xlc2NfbGlrZSggJ190cmFuc2llbnRfJyApIC4gJyUnCgkJCQkpCgkJCSk7CgkJfSBlbHNlIHsKCQkJaWYgKCAhIGlzX211bHRpc2l0ZSgpICkgewoJCQkJLy8gTm9uLU11bHRpc2l0ZSBzdG9yZXMgc2l0ZSB0cmFuc2llbnRzIGluIHRoZSBvcHRpb25zIHRhYmxlLgoJCQkJJGRlbGV0ZWQgPSAkd3BkYi0+cXVlcnkoCgkJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJCSJERUxFVEUgYSwgYiBGUk9NIHskd3BkYi0+b3B0aW9uc30gYSwgeyR3cGRiLT5vcHRpb25zfSBiCgkJCQkJCQlXSEVSRSBhLm9wdGlvbl9uYW1lIExJS0UgJXMKCQkJCQkJCUFORCBhLm9wdGlvbl9uYW1lIE5PVCBMSUtFICVzCgkJCQkJCQlBTkQgYi5vcHRpb25fbmFtZSA9IENPTkNBVCggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycsIFNVQlNUUklORyggYS5vcHRpb25fbmFtZSwgMTcgKSApIiwKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJwoJCQkJCSkKCQkJCSk7CgoJCQkJJGNvdW50ICs9ICRkZWxldGVkIC8gMjsgLy8gSWdub3JlIGFmZmVjdGVkIHJvd3MgZm9yIHRpbWVvdXRzLgoKCQkJCSRjb3VudCArPSAkd3BkYi0+cXVlcnkoCgkJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJCSJERUxFVEUgRlJPTSAkd3BkYi0+b3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZSBMSUtFICVzIiwKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJyUnCgkJCQkJKQoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCS8vIE11bHRpc2l0ZSBzdG9yZXMgc2l0ZSB0cmFuc2llbnRzIGluIHRoZSBzaXRlbWV0YSB0YWJsZS4KCQkJCSRkZWxldGVkID0gJHdwZGItPnF1ZXJ5KAoJCQkJCSR3cGRiLT5wcmVwYXJlKAoJCQkJCQkiREVMRVRFIGEsIGIgRlJPTSB7JHdwZGItPnNpdGVtZXRhfSBhLCB7JHdwZGItPnNpdGVtZXRhfSBiCgkJCQkJCQlXSEVSRSBhLm1ldGFfa2V5IExJS0UgJXMKCQkJCQkJCUFORCBhLm1ldGFfa2V5IE5PVCBMSUtFICVzCgkJCQkJCQlBTkQgYi5tZXRhX2tleSA9IENPTkNBVCggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycsIFNVQlNUUklORyggYS5tZXRhX2tleSwgMTcgKSApIiwKCQkJCQkJVXRpbHNcZXNjX2xpa2UoICdfc2l0ZV90cmFuc2llbnRfJyApIC4gJyUnLAoJCQkJCQlVdGlsc1xlc2NfbGlrZSggJ19zaXRlX3RyYW5zaWVudF90aW1lb3V0XycgKSAuICclJwoJCQkJCSkKCQkJCSk7CgoJCQkJJGNvdW50ICs9ICRkZWxldGVkIC8gMjsgLy8gSWdub3JlIGFmZmVjdGVkIHJvd3MgZm9yIHRpbWVvdXRzLgoKCQkJCSRjb3VudCArPSAkd3BkYi0+cXVlcnkoCgkJCQkJJHdwZGItPnByZXBhcmUoCgkJCQkJCSJERUxFVEUgRlJPTSAkd3BkYi0+c2l0ZW1ldGEgV0hFUkUgbWV0YV9rZXkgTElLRSAlcyIsCgkJCQkJCVV0aWxzXGVzY19saWtlKCAnX3NpdGVfdHJhbnNpZW50XycgKSAuICclJwoJCQkJCSkKCQkJCSk7CgkJCX0KCQl9CgoJCWlmICggJGNvdW50ID4gMCApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKAoJCQkJc3ByaW50ZigKCQkJCQknJWQgJXMgZGVsZXRlZCBmcm9tIHRoZSBkYXRhYmFzZS4nLAoJCQkJCSRjb3VudCwKCQkJCQlVdGlsc1xwbHVyYWxpemUoICd0cmFuc2llbnQnLCAkY291bnQgKQoJCQkJKQoJCQkpOwoJCX0gZWxzZSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJ05vIHRyYW5zaWVudHMgZm91bmQuJyApOwoJCX0KCgkJaWYgKCB3cF91c2luZ19leHRfb2JqZWN0X2NhY2hlKCkgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ1RyYW5zaWVudHMgYXJlIHN0b3JlZCBpbiBhbiBleHRlcm5hbCBvYmplY3QgY2FjaGUsIGFuZCB0aGlzIGNvbW1hbmQgb25seSBkZWxldGVzIHRob3NlIHN0b3JlZCBpbiB0aGUgZGF0YWJhc2UuIFlvdSBtdXN0IGZsdXNoIHRoZSBjYWNoZSB0byBkZWxldGUgYWxsIHRyYW5zaWVudHMuJyApOwoJCX0KCX0KfQo8P3BocAoKLyoqCiAqIEFkZHMsIHJlbW92ZXMsIGZldGNoZXMsIGFuZCBmbHVzaGVzIHRoZSBXUCBPYmplY3QgQ2FjaGUgb2JqZWN0LgogKgogKiBCeSBkZWZhdWx0LCB0aGUgV1AgT2JqZWN0IENhY2hlIGV4aXN0cyBpbiBQSFAgbWVtb3J5IGZvciB0aGUgbGVuZ3RoIG9mIHRoZQogKiByZXF1ZXN0IChhbmQgaXMgZW1wdGllZCBhdCB0aGUgZW5kKS4gVXNlIGEgcGVyc2lzdGVudCBvYmplY3QgY2FjaGUgZHJvcC1pbgogKiB0byBwZXJzaXN0IHRoZSBvYmplY3QgY2FjaGUgYmV0d2VlbiByZXF1ZXN0cy4KICoKICogW1JlYWQgdGhlIGNvZGV4IGFydGljbGVdKGh0dHBzOi8vY29kZXgud29yZHByZXNzLm9yZy9DbGFzc19SZWZlcmVuY2UvV1BfT2JqZWN0X0NhY2hlKQogKiBmb3IgbW9yZSBkZXRhaWwuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIFNldCBjYWNoZS4KICogICAgICQgd3AgY2FjaGUgc2V0IG15X2tleSBteV92YWx1ZSBteV9ncm91cCAzMDAKICogICAgIFN1Y2Nlc3M6IFNldCBvYmplY3QgJ215X2tleScgaW4gZ3JvdXAgJ215X2dyb3VwJy4KICoKICogICAgICMgR2V0IGNhY2hlLgogKiAgICAgJCB3cCBjYWNoZSBnZXQgbXlfa2V5IG15X2dyb3VwCiAqICAgICBteV92YWx1ZQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENhY2hlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBBZGRzIGEgdmFsdWUgdG8gdGhlIG9iamVjdCBjYWNoZS4KCSAqCgkgKiBFcnJvcnMgaWYgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyBmb3IgdGhlIGtleSwgd2hpY2ggbWVhbnMgdGhlIHZhbHVlIGNhbid0CgkgKiBiZSBhZGRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gYWRkIHRvIHRoZSBrZXkuCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiBbPGV4cGlyYXRpb24+XQoJICogOiBEZWZpbmUgaG93IGxvbmcgdG8ga2VlcCB0aGUgdmFsdWUsIGluIHNlY29uZHMuIGAwYCBtZWFucyBhcyBsb25nIGFzIHBvc3NpYmxlLgoJICogLS0tCgkgKiBkZWZhdWx0OiAwCgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIGFkZCBteV9rZXkgbXlfZ3JvdXAgbXlfdmFsdWUgMzAwCgkgKiAgICAgU3VjY2VzczogQWRkZWQgb2JqZWN0ICdteV9rZXknIGluIGdyb3VwICdteV92YWx1ZScuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBhZGQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSA9ICRhcmdzOwoKCQlpZiAoICEgd3BfY2FjaGVfYWRkKCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBhZGQgb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4gRG9lcyBpdCBhbHJlYWR5IGV4aXN0PyIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIkFkZGVkIG9iamVjdCAnJGtleScgaW4gZ3JvdXAgJyRncm91cCcuIiApOwoJfQoKCS8qKgoJICogRGVjcmVtZW50cyBhIHZhbHVlIGluIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSBkZWNyZW1lbnRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8b2Zmc2V0Pl0KCSAqIDogVGhlIGFtb3VudCBieSB3aGljaCB0byBkZWNyZW1lbnQgdGhlIGl0ZW0ncyB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIERlY3JlYXNlIGNhY2hlIHZhbHVlLgoJICogICAgICQgd3AgY2FjaGUgZGVjciBteV9rZXkgMiBteV9ncm91cAoJICogICAgIDQ4CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWNyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJG9mZnNldCwgJGdyb3VwICkgPSAkYXJnczsKCQkkdmFsdWUgPSB3cF9jYWNoZV9kZWNyKCAka2V5LCAkb2Zmc2V0LCAkZ3JvdXAgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIHZhbHVlIHdhcyBub3QgZGVjcmVtZW50ZWQuJyApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIHZhbHVlIGZyb20gdGhlIG9iamVjdCBjYWNoZS4KCSAqCgkgKiBFcnJvcnMgaWYgdGhlIHZhbHVlIGNhbid0IGJlIGRlbGV0ZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxrZXk+CgkgKiA6IENhY2hlIGtleS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIGNhY2hlLgoJICogICAgICQgd3AgY2FjaGUgZGVsZXRlIG15X2tleSBteV9ncm91cAoJICogICAgIFN1Y2Nlc3M6IE9iamVjdCBkZWxldGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZGVsZXRlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJGdyb3VwICkgPSAkYXJnczsKCQkkcmVzdWx0ICAgICAgICAgICAgICA9IHdwX2NhY2hlX2RlbGV0ZSggJGtleSwgJGdyb3VwICk7CgoJCWlmICggZmFsc2UgPT09ICRyZXN1bHQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgb2JqZWN0IHdhcyBub3QgZGVsZXRlZC4nICk7CgkJfQoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdPYmplY3QgZGVsZXRlZC4nICk7Cgl9CgoJLyoqCgkgKiBGbHVzaGVzIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRm9yIFdvcmRQcmVzcyBtdWx0aXNpdGUgaW5zdGFuY2VzIHVzaW5nIGEgcGVyc2lzdGVudCBvYmplY3QgY2FjaGUsCgkgKiBmbHVzaGluZyB0aGUgb2JqZWN0IGNhY2hlIHdpbGwgdHlwaWNhbGx5IGZsdXNoIHRoZSBjYWNoZSBmb3IgYWxsIHNpdGVzLgoJICogQmV3YXJlIG9mIHRoZSBwZXJmb3JtYW5jZSBpbXBhY3Qgd2hlbiBmbHVzaGluZyB0aGUgb2JqZWN0IGNhY2hlIGluCgkgKiBwcm9kdWN0aW9uLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgb2JqZWN0IGNhY2hlIGNhbid0IGJlIGZsdXNoZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBGbHVzaCBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIGZsdXNoCgkgKiAgICAgU3VjY2VzczogVGhlIGNhY2hlIHdhcyBmbHVzaGVkLgoJICovCglwdWJsaWMgZnVuY3Rpb24gZmx1c2goICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdmFsdWUgPSB3cF9jYWNoZV9mbHVzaCgpOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgb2JqZWN0IGNhY2hlIGNvdWxkIG5vdCBiZSBmbHVzaGVkLicgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1RoZSBjYWNoZSB3YXMgZmx1c2hlZC4nICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgb2JqZWN0IGNhY2hlLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgdmFsdWUgZG9lc24ndCBleGlzdC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8Z3JvdXA+XQoJICogOiBNZXRob2QgZm9yIGdyb3VwaW5nIGRhdGEgd2l0aGluIHRoZSBjYWNoZSB3aGljaCBhbGxvd3MgdGhlIHNhbWUga2V5IHRvIGJlIHVzZWQgYWNyb3NzIGdyb3Vwcy4KCSAqIC0tLQoJICogZGVmYXVsdDogZGVmYXVsdAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBHZXQgY2FjaGUuCgkgKiAgICAgJCB3cCBjYWNoZSBnZXQgbXlfa2V5IG15X2dyb3VwCgkgKiAgICAgbXlfdmFsdWUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdldCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXksICRncm91cCApID0gJGFyZ3M7CgkJJHZhbHVlICAgICAgICAgICAgICAgPSB3cF9jYWNoZV9nZXQoICRrZXksICRncm91cCApOwoKCQlpZiAoIGZhbHNlID09PSAkdmFsdWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJPYmplY3Qgd2l0aCBrZXkgJyRrZXknIGFuZCBncm91cCAnJGdyb3VwJyBub3QgZm91bmQuIiApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogSW5jcmVtZW50cyBhIHZhbHVlIGluIHRoZSBvYmplY3QgY2FjaGUuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSBpbmNyZW1lbnRlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIFs8b2Zmc2V0Pl0KCSAqIDogVGhlIGFtb3VudCBieSB3aGljaCB0byBpbmNyZW1lbnQgdGhlIGl0ZW0ncyB2YWx1ZS4KCSAqIC0tLQoJICogZGVmYXVsdDogMQoJICogLS0tCgkgKgoJICogWzxncm91cD5dCgkgKiA6IE1ldGhvZCBmb3IgZ3JvdXBpbmcgZGF0YSB3aXRoaW4gdGhlIGNhY2hlIHdoaWNoIGFsbG93cyB0aGUgc2FtZSBrZXkgdG8gYmUgdXNlZCBhY3Jvc3MgZ3JvdXBzLgoJICogLS0tCgkgKiBkZWZhdWx0OiBkZWZhdWx0CgkgKiAtLS0KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEluY3JlYXNlIGNhY2hlIHZhbHVlLgoJICogICAgICQgd3AgY2FjaGUgaW5jciBteV9rZXkgMiBteV9ncm91cAoJICogICAgIDUwCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBpbmNyKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJbGlzdCggJGtleSwgJG9mZnNldCwgJGdyb3VwICkgPSAkYXJnczsKCQkkdmFsdWUgPSB3cF9jYWNoZV9pbmNyKCAka2V5LCAkb2Zmc2V0LCAkZ3JvdXAgKTsKCgkJaWYgKCBmYWxzZSA9PT0gJHZhbHVlICkgewoJCQlXUF9DTEk6OmVycm9yKCAnVGhlIHZhbHVlIHdhcyBub3QgaW5jcmVtZW50ZWQuJyApOwoJCX0KCgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogUmVwbGFjZXMgYSB2YWx1ZSBpbiB0aGUgb2JqZWN0IGNhY2hlLCBpZiB0aGUgdmFsdWUgYWxyZWFkeSBleGlzdHMuCgkgKgoJICogRXJyb3JzIGlmIHRoZSB2YWx1ZSBjYW4ndCBiZSByZXBsYWNlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGtleT4KCSAqIDogQ2FjaGUga2V5LgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gcmVwbGFjZS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqIFs8ZXhwaXJhdGlvbj5dCgkgKiA6IERlZmluZSBob3cgbG9uZyB0byBrZWVwIHRoZSB2YWx1ZSwgaW4gc2Vjb25kcy4gYDBgIG1lYW5zIGFzIGxvbmcgYXMgcG9zc2libGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDAKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVwbGFjZSBjYWNoZS4KCSAqICAgICAkIHdwIGNhY2hlIHJlcGxhY2UgbXlfa2V5IG5ld192YWx1ZSBteV9ncm91cAoJICogICAgIFN1Y2Nlc3M6IFJlcGxhY2VkIG9iamVjdCAnbXlfa2V5JyBpbiBncm91cCAnbXlfZ3JvdXAnLgoJICovCglwdWJsaWMgZnVuY3Rpb24gcmVwbGFjZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCWxpc3QoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApID0gJGFyZ3M7CgkJJHJlc3VsdCA9IHdwX2NhY2hlX3JlcGxhY2UoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApOwoKCQlpZiAoIGZhbHNlID09PSAkcmVzdWx0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHJlcGxhY2Ugb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4gRG9lcyBpdCBub3QgZXhpc3Q/IiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiUmVwbGFjZWQgb2JqZWN0ICcka2V5JyBpbiBncm91cCAnJGdyb3VwJy4iICk7Cgl9CgoJLyoqCgkgKiBTZXRzIGEgdmFsdWUgdG8gdGhlIG9iamVjdCBjYWNoZSwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIGl0IGFscmVhZHkgZXhpc3RzLgoJICoKCSAqIEVycm9ycyBpZiB0aGUgdmFsdWUgY2FuJ3QgYmUgc2V0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8a2V5PgoJICogOiBDYWNoZSBrZXkuCgkgKgoJICogPHZhbHVlPgoJICogOiBWYWx1ZSB0byBzZXQgb24gdGhlIGtleS4KCSAqCgkgKiBbPGdyb3VwPl0KCSAqIDogTWV0aG9kIGZvciBncm91cGluZyBkYXRhIHdpdGhpbiB0aGUgY2FjaGUgd2hpY2ggYWxsb3dzIHRoZSBzYW1lIGtleSB0byBiZSB1c2VkIGFjcm9zcyBncm91cHMuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IGRlZmF1bHQKCSAqIC0tLQoJICoKCSAqIFs8ZXhwaXJhdGlvbj5dCgkgKiA6IERlZmluZSBob3cgbG9uZyB0byBrZWVwIHRoZSB2YWx1ZSwgaW4gc2Vjb25kcy4gYDBgIG1lYW5zIGFzIGxvbmcgYXMgcG9zc2libGUuCgkgKiAtLS0KCSAqIGRlZmF1bHQ6IDAKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgU2V0IGNhY2hlLgoJICogICAgICQgd3AgY2FjaGUgc2V0IG15X2tleSBteV92YWx1ZSBteV9ncm91cCAzMDAKCSAqICAgICBTdWNjZXNzOiBTZXQgb2JqZWN0ICdteV9rZXknIGluIGdyb3VwICdteV9ncm91cCcuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAka2V5LCAkdmFsdWUsICRncm91cCwgJGV4cGlyYXRpb24gKSA9ICRhcmdzOwoJCSRyZXN1bHQgPSB3cF9jYWNoZV9zZXQoICRrZXksICR2YWx1ZSwgJGdyb3VwLCAkZXhwaXJhdGlvbiApOwoKCQlpZiAoIGZhbHNlID09PSAkcmVzdWx0ICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IGFkZCBvYmplY3QgJyRrZXknIGluIGdyb3VwICckZ3JvdXAnLiIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggIlNldCBvYmplY3QgJyRrZXknIGluIGdyb3VwICckZ3JvdXAnLiIgKTsKCX0KCgkvKioKCSAqIEF0dGVtcHRzIHRvIGRldGVybWluZSB3aGljaCBvYmplY3QgY2FjaGUgaXMgYmVpbmcgdXNlZC4KCSAqCgkgKiBOb3RlIHRoYXQgdGhlIGd1ZXNzZXMgbWFkZSBieSB0aGlzIGZ1bmN0aW9uIGFyZSBiYXNlZCBvbiB0aGUKCSAqIFdQX09iamVjdF9DYWNoZSBjbGFzc2VzIHRoYXQgZGVmaW5lIHRoZSAzcmQgcGFydHkgb2JqZWN0IGNhY2hlIGV4dGVuc2lvbi4KCSAqIENoYW5nZXMgdG8gdGhvc2UgY2xhc3NlcyBjb3VsZCByZW5kZXIgcHJvYmxlbXMgd2l0aCB0aGlzIGZ1bmN0aW9uJ3MKCSAqIGFiaWxpdHkgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdCBjYWNoZSBpcyBiZWluZyB1c2VkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgY2FjaGUgdHlwZS4KCSAqICAgICAkIHdwIGNhY2hlIHR5cGUKCSAqICAgICBEZWZhdWx0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0eXBlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJG1lc3NhZ2UgPSBXUF9DTElcVXRpbHNcd3BfZ2V0X2NhY2hlX3R5cGUoKTsKCQlXUF9DTEk6OmxpbmUoICRtZXNzYWdlICk7Cgl9Cgp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfc2hlbGxfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwppZiAoIGZpbGVfZXhpc3RzKCAkd3BjbGlfc2hlbGxfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9zaGVsbF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2hlbGwnLCAnU2hlbGxfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgpjbGFzcyBTaGVsbF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogT3BlbnMgYW4gaW50ZXJhY3RpdmUgUEhQIGNvbnNvbGUgZm9yIHJ1bm5pbmcgYW5kIHRlc3RpbmcgUEhQIGNvZGUuCgkgKgoJICogYHdwIHNoZWxsYCBhbGxvd3MgeW91IHRvIGV2YWx1YXRlIFBIUCBzdGF0ZW1lbnRzIGFuZCBleHByZXNzaW9ucwoJICogaW50ZXJhY3RpdmVseSwgZnJvbSB3aXRoaW4gYSBXb3JkUHJlc3MgZW52aXJvbm1lbnQuIFR5cGUgYSBiaXQgb2YgY29kZSwKCSAqIGhpdCBlbnRlciwgYW5kIHNlZSB0aGUgY29kZSBleGVjdXRlIHJpZ2h0IGJlZm9yZSB5b3UuIEJlY2F1c2UgV29yZFByZXNzCgkgKiBpcyBsb2FkZWQsIHlvdSBoYXZlIGFjY2VzcyB0byBhbGwgdGhlIGZ1bmN0aW9ucywgY2xhc3NlcyBhbmQgZ2xvYmFscwoJICogdGhhdCB5b3UgY2FuIHVzZSB3aXRoaW4gYSBXb3JkUHJlc3MgcGx1Z2luLCBmb3IgZXhhbXBsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tYmFzaWNdCgkgKiA6IEZvcmNlIHRoZSB1c2Ugb2YgV1AtQ0xJJ3MgYnVpbHQtaW4gUEhQIFJFUEwsIGV2ZW4gaWYgdGhlIEJvcmlzIG9yCgkgKiBQc3lTSCBQSFAgUkVQTHMgYXJlIGF2YWlsYWJsZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENhbGwgZ2V0X2Jsb2dpbmZvKCkgdG8gZ2V0IHRoZSBuYW1lIG9mIHRoZSBzaXRlLgoJICogICAgICQgd3Agc2hlbGwKCSAqICAgICB3cD4gZ2V0X2Jsb2dpbmZvKCAnbmFtZScgKTsKCSAqICAgICA9PiBzdHJpbmcoNikgIldQLUNMSSIKCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkXywgJGFzc29jX2FyZ3MgKSB7CgkJJGltcGxlbWVudGF0aW9ucyA9IGFycmF5KAoJCQknUHN5XFxTaGVsbCcsCgkJCSdCb3Jpc1xcQm9yaXMnLAoJCQknV1BfQ0xJXFxTaGVsbFxcUkVQTCcsCgkJKTsKCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdiYXNpYycgKSApIHsKCQkJJGNsYXNzID0gJ1dQX0NMSVxcU2hlbGxcXFJFUEwnOwoJCX0gZWxzZSB7CgkJCWZvcmVhY2ggKCAkaW1wbGVtZW50YXRpb25zIGFzICRjYW5kaWRhdGUgKSB7CgkJCQlpZiAoIGNsYXNzX2V4aXN0cyggJGNhbmRpZGF0ZSApICkgewoJCQkJCSRjbGFzcyA9ICRjYW5kaWRhdGU7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggJ1BzeVxcU2hlbGwnID09PSAkY2xhc3MgKSB7CgkJCSRzaGVsbCA9IG5ldyBQc3lcU2hlbGwoKTsKCQkJJHNoZWxsLT5ydW4oKTsKCQl9IGVsc2UgewoJCQkkcmVwbCA9IG5ldyAkY2xhc3MoICd3cD4gJyApOwoJCQkkcmVwbC0+c3RhcnQoKTsKCQl9Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcU2hlbGw7Cgp1c2UgV1BfQ0xJOwoKY2xhc3MgUkVQTCB7CgoJcHJpdmF0ZSAkcHJvbXB0OwoKCXByaXZhdGUgJGhpc3RvcnlfZmlsZTsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoICRwcm9tcHQgKSB7CgkJJHRoaXMtPnByb21wdCA9ICRwcm9tcHQ7CgoJCSR0aGlzLT5zZXRfaGlzdG9yeV9maWxlKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIHN0YXJ0KCkgewoJCXdoaWxlICggdHJ1ZSApIHsKCQkJJGxpbmUgPSAkdGhpcy0+cHJvbXB0KCk7CgoJCQlpZiAoICcnID09PSAkbGluZSApIHsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbGluZSA9IHJ0cmltKCAkbGluZSwgJzsnICkgLiAnOyc7CgoJCQlpZiAoIHNlbGY6OnN0YXJ0c193aXRoKCBzZWxmOjpub25fZXhwcmVzc2lvbnMoKSwgJGxpbmUgKSApIHsKCQkJCW9iX3N0YXJ0KCk7CgkJCQkvLyBwaHBjczppZ25vcmUgU3F1aXouUEhQLkV2YWwuRGlzY291cmFnZWQgLS0gVGhpcyBpcyBtZWFudCB0byBiZSBhIFJFUEwsIG5vIHdheSB0byBhdm9pZCBldmFsLgoJCQkJZXZhbCggJGxpbmUgKTsKCQkJCSRvdXQgPSBvYl9nZXRfY2xlYW4oKTsKCQkJCWlmICggMCA8IHN0cmxlbiggJG91dCApICkgewoJCQkJCSRvdXQgPSBydHJpbSggJG91dCwgIlxuIiApIC4gIlxuIjsKCQkJCX0KCQkJCWZ3cml0ZSggU1RET1VULCAkb3V0ICk7CgkJCX0gZWxzZSB7CgkJCQlpZiAoICEgc2VsZjo6c3RhcnRzX3dpdGgoICdyZXR1cm4nLCAkbGluZSApICkgewoJCQkJCSRsaW5lID0gJ3JldHVybiAnIC4gJGxpbmU7CgkJCQl9CgoJCQkJLy8gV3JpdGUgZGlyZWN0bHkgdG8gU1RET1VULCB0byBzaWRlc3RlcCBhbnkgb3V0cHV0IGJ1ZmZlcnMgY3JlYXRlZCBieSBwbHVnaW5zCgkJCQlvYl9zdGFydCgpOwoJCQkJLy8gcGhwY3M6aWdub3JlIFNxdWl6LlBIUC5FdmFsLkRpc2NvdXJhZ2VkIC0tIFRoaXMgaXMgbWVhbnQgdG8gYmUgYSBSRVBMLCBubyB3YXkgdG8gYXZvaWQgZXZhbC4KCQkJCSRldmwgPSBldmFsKCAkbGluZSApOwoJCQkJJG91dCA9IG9iX2dldF9jbGVhbigpOwoJCQkJaWYgKCAwIDwgc3RybGVuKCAkb3V0ICkgKSB7CgkJCQkJZWNobyBydHJpbSggJG91dCwgIlxuIiApIC4gIlxuIjsKCQkJCX0KCQkJCWVjaG8gJz0+ICc7CgkJCQl2YXJfZHVtcCggJGV2bCApOwoJCQkJZndyaXRlKCBTVERPVVQsIG9iX2dldF9jbGVhbigpICk7CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gbm9uX2V4cHJlc3Npb25zKCkgewoJCXJldHVybiBpbXBsb2RlKAoJCQknfCcsCgkJCWFycmF5KAoJCQkJJ2VjaG8nLAoJCQkJJ2dsb2JhbCcsCgkJCQkndW5zZXQnLAoJCQkJJ2Z1bmN0aW9uJywKCQkJCSd3aGlsZScsCgkJCQknZm9yJywKCQkJCSdmb3JlYWNoJywKCQkJCSdpZicsCgkJCQknc3dpdGNoJywKCQkJCSdpbmNsdWRlJywKCQkJCSdpbmNsdWRlXF9vbmNlJywKCQkJCSdyZXF1aXJlJywKCQkJCSdyZXF1aXJlXF9vbmNlJywKCQkJKQoJCSk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBwcm9tcHQoKSB7CgkJJGZ1bGxfbGluZSA9IGZhbHNlOwoKCQkkZG9uZSA9IGZhbHNlOwoJCWRvIHsKCQkJJHByb21wdCA9ICggISAkZG9uZSAmJiBmYWxzZSAhPT0gJGZ1bGxfbGluZSApID8gJy0tPiAnIDogJHRoaXMtPnByb21wdDsKCgkJCSRmcCA9IHBvcGVuKCBzZWxmOjpjcmVhdGVfcHJvbXB0X2NtZCggJHByb21wdCwgJHRoaXMtPmhpc3RvcnlfZmlsZSApLCAncicgKTsKCgkJCSRsaW5lID0gZmdldHMoICRmcCApOwoKCQkJcGNsb3NlKCAkZnAgKTsKCgkJCWlmICggISAkbGluZSApIHsKCQkJCWJyZWFrOwoJCQl9CgoJCQkkbGluZSA9IHJ0cmltKCAkbGluZSwgIlxuIiApOwoKCQkJaWYgKCAkbGluZSAmJiAnXFwnID09PSAkbGluZVsgc3RybGVuKCAkbGluZSApIC0gMSBdICkgewoJCQkJJGxpbmUgPSBzdWJzdHIoICRsaW5lLCAwLCAtMSApOwoJCQl9IGVsc2UgewoJCQkJJGRvbmUgPSB0cnVlOwoJCQl9CgoJCQkkZnVsbF9saW5lIC49ICRsaW5lOwoKCQl9IHdoaWxlICggISAkZG9uZSApOwoKCQlpZiAoIGZhbHNlID09PSAkZnVsbF9saW5lICkgewoJCQlyZXR1cm4gJ2V4aXQnOwoJCX0KCgkJcmV0dXJuICRmdWxsX2xpbmU7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlX3Byb21wdF9jbWQoICRwcm9tcHQsICRoaXN0b3J5X3BhdGggKSB7CgkJJHByb21wdCAgICAgICA9IGVzY2FwZXNoZWxsYXJnKCAkcHJvbXB0ICk7CgkJJGhpc3RvcnlfcGF0aCA9IGVzY2FwZXNoZWxsYXJnKCAkaGlzdG9yeV9wYXRoICk7CgkJaWYgKCBnZXRlbnYoICdXUF9DTElfQ1VTVE9NX1NIRUxMJyApICkgewoJCQkkc2hlbGxfYmluYXJ5ID0gZ2V0ZW52KCAnV1BfQ0xJX0NVU1RPTV9TSEVMTCcgKTsKCQl9IGVsc2UgewoJCQkkc2hlbGxfYmluYXJ5ID0gJy9iaW4vYmFzaCc7CgkJfQoKCQlpZiAoICEgaXNfZmlsZSggJHNoZWxsX2JpbmFyeSApIHx8ICEgaXNfcmVhZGFibGUoICRzaGVsbF9iaW5hcnkgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIlRoZSBzaGVsbCBiaW5hcnkgJ3skc2hlbGxfYmluYXJ5fScgaXMgbm90IHZhbGlkLiBZb3UgY2FuIG92ZXJyaWRlIHRoZSBzaGVsbCB0byBiZSB1c2VkIHRocm91Z2ggdGhlIFdQX0NMSV9DVVNUT01fU0hFTEwgZW52aXJvbm1lbnQgdmFyaWFibGUuIiApOwoJCX0KCgkJJHNoZWxsX2JpbmFyeSA9IGVzY2FwZXNoZWxsYXJnKCAkc2hlbGxfYmluYXJ5ICk7CgoJCSRjbWQgPSAnc2V0IC1mOyAnCgkJCS4gImhpc3RvcnkgLXIgeyRoaXN0b3J5X3BhdGh9OyAiCgkJCS4gJ0xJTkU9IiI7ICcKCQkJLiAicmVhZCAtcmUgLXAgeyRwcm9tcHR9IExJTkU7ICIKCQkJLiAnWyAkPyAtZXEgMCBdIHx8IGV4aXQ7ICcKCQkJLiAnaGlzdG9yeSAtcyAiJExJTkUiOyAnCgkJCS4gImhpc3RvcnkgLXcgeyRoaXN0b3J5X3BhdGh9OyAiCgkJCS4gJ2VjaG8gJExJTkU7ICc7CgoJCXJldHVybiAieyRzaGVsbF9iaW5hcnl9IC1jICIgLiBlc2NhcGVzaGVsbGFyZyggJGNtZCApOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gc2V0X2hpc3RvcnlfZmlsZSgpIHsKCQkkZGF0YSA9IGdldGN3ZCgpIC4gZ2V0X2N1cnJlbnRfdXNlcigpOwoKCQkkdGhpcy0+aGlzdG9yeV9maWxlID0gXFdQX0NMSVxVdGlsc1xnZXRfdGVtcF9kaXIoKSAuICd3cC1jbGktaGlzdG9yeS0nIC4gbWQ1KCAkZGF0YSApOwoJfQoKCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHN0YXJ0c193aXRoKCAkdG9rZW5zLCAkbGluZSApIHsKCQlyZXR1cm4gcHJlZ19tYXRjaCggIi9eKCR0b2tlbnMpW1woXHNdKy8iLCAkbGluZSApOwoJfQp9Cgo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2NoZWNrc3VtX2F1dG9sb2FkZXIgPSBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX2NoZWNrc3VtX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfY2hlY2tzdW1fYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvcmUnLCAnQ29yZV9Db21tYW5kX05hbWVzcGFjZScgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvcmUgdmVyaWZ5LWNoZWNrc3VtcycsICdDaGVja3N1bV9Db3JlX0NvbW1hbmQnICk7CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAncGx1Z2luJywgJ1BsdWdpbl9Db21tYW5kX05hbWVzcGFjZScgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3BsdWdpbiB2ZXJpZnktY2hlY2tzdW1zJywgJ0NoZWNrc3VtX1BsdWdpbl9Db21tYW5kJyApOwoKPD9waHAKCnVzZSBXUF9DTElcRGlzcGF0Y2hlclxDb21tYW5kTmFtZXNwYWNlOwoKLyoqCiAqIE1hbmFnZXMgcGx1Z2lucywgaW5jbHVkaW5nIGluc3RhbGxzLCBhY3RpdmF0aW9ucywgYW5kIHVwZGF0ZXMuCiAqLwpmaW5hbCBjbGFzcyBQbHVnaW5fQ29tbWFuZF9OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgovKioKICogQmFzZSBjb21tYW5kIHRoYXQgYWxsIGNoZWNrc3VtIGNvbW1hbmRzIHJlbHkgb24uCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ2hlY2tzdW1fQmFzZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogTm9ybWFsaXplcyBkaXJlY3Rvcnkgc2VwYXJhdG9ycyB0byBzbGFzaGVzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byBjb252ZXJ0LgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIFBhdGggd2l0aCBhbGwgYmFja3NsYXNoZXMgcmVwbGFjZWQgYnkgc2xhc2hlcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBub3JtYWxpemVfZGlyZWN0b3J5X3NlcGFyYXRvcnMoICRwYXRoICkgewoJCXJldHVybiBzdHJfcmVwbGFjZSggJ1xcJywgJy8nLCAkcGF0aCApOwoJfQoKCS8qKgoJICogUmVhZCBhIHJlbW90ZSBmaWxlIGFuZCByZXR1cm4gaXRzIGNvbnRlbnRzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHVybCBVUkwgb2YgdGhlIHJlbW90ZSBmaWxlIHRvIHJlYWQuCgkgKgoJICogQHJldHVybiBtaXhlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIF9yZWFkKCAkdXJsICkgeyAvLyBwaHBjczppZ25vcmUgUFNSMi5NZXRob2RzLk1ldGhvZERlY2xhcmF0aW9uLlVuZGVyc2NvcmUgLS0gQ291bGQgYmUgdXNlZCBpbiBjbGFzc2VzIGV4dGVuZGluZyB0aGlzIGNsYXNzLgoJCSRoZWFkZXJzICA9IGFycmF5KCAnQWNjZXB0JyA9PiAnYXBwbGljYXRpb24vanNvbicgKTsKCQkkcmVzcG9uc2UgPSBVdGlsc1xodHRwX3JlcXVlc3QoCgkJCSdHRVQnLAoJCQkkdXJsLAoJCQludWxsLAoJCQkkaGVhZGVycywKCQkJYXJyYXkoICd0aW1lb3V0JyA9PiAzMCApCgkJKTsKCQlpZiAoIDIwMCA9PT0gJHJlc3BvbnNlLT5zdGF0dXNfY29kZSApIHsKCQkJcmV0dXJuICRyZXNwb25zZS0+Ym9keTsKCQl9CgkJV1BfQ0xJOjplcnJvciggIkNvdWxkbid0IGZldGNoIHJlc3BvbnNlIGZyb20geyR1cmx9IChIVFRQIGNvZGUgeyRyZXNwb25zZS0+c3RhdHVzX2NvZGV9KS4iICk7Cgl9CgoJLyoqCgkgKiBSZWN1cnNpdmVseSBnZXQgdGhlIGxpc3Qgb2YgZmlsZXMgZm9yIGEgZ2l2ZW4gcGF0aC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJvb3QgcGF0aCB0byBzdGFydCB0aGUgcmVjdXJzaXZlIHRyYXZlcnNhbCBpbi4KCSAqCgkgKiBAcmV0dXJuIGFycmF5PHN0cmluZz4KCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9maWxlcyggJHBhdGggKSB7CgkJJGZpbHRlcmVkX2ZpbGVzID0gYXJyYXkoKTsKCQl0cnkgewoJCQkkZmlsZXMgPSBuZXcgUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcigKCQkJCW5ldyBSZWN1cnNpdmVDYWxsYmFja0ZpbHRlckl0ZXJhdG9yKAoJCQkJCW5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigKCQkJCQkJJHBhdGgsCgkJCQkJCVJlY3Vyc2l2ZURpcmVjdG9yeUl0ZXJhdG9yOjpTS0lQX0RPVFMKCQkJCQkpLAoJCQkJCWZ1bmN0aW9uICggJGN1cnJlbnQsICRrZXksICRpdGVyYXRvciApIHVzZSAoICRwYXRoICkgewoJCQkJCQlyZXR1cm4gJHRoaXMtPmZpbHRlcl9maWxlKCBzZWxmOjpub3JtYWxpemVfZGlyZWN0b3J5X3NlcGFyYXRvcnMoIHN1YnN0ciggJGN1cnJlbnQtPmdldFBhdGhuYW1lKCksIHN0cmxlbiggJHBhdGggKSApICkgKTsKCQkJCQl9CgkJCQkpLAoJCQkJUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcjo6Q0hJTERfRklSU1QKCQkJKTsKCQkJZm9yZWFjaCAoICRmaWxlcyBhcyAkZmlsZV9pbmZvICkgewoJCQkJaWYgKCAkZmlsZV9pbmZvLT5pc0ZpbGUoKSApIHsKCQkJCQkkZmlsdGVyZWRfZmlsZXNbXSA9IHNlbGY6Om5vcm1hbGl6ZV9kaXJlY3Rvcnlfc2VwYXJhdG9ycyggc3Vic3RyKCAkZmlsZV9pbmZvLT5nZXRQYXRobmFtZSgpLCBzdHJsZW4oICRwYXRoICkgKSApOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZSApIHsKCQkJV1BfQ0xJOjplcnJvciggJGUtPmdldE1lc3NhZ2UoKSApOwoJCX0KCgkJcmV0dXJuICRmaWx0ZXJlZF9maWxlczsKCX0KCgkvKioKCSAqIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgZmlsZSBpbiB0aGUgdmVyaWZpY2F0aW9uIG9yIG5vdC4KCSAqCgkgKiBDYW4gYmUgb3ZlcnJpZGRlbiBpbiBzdWJjbGFzc2VzLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVwYXRoIFBhdGggdG8gYSBmaWxlLgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZmlsdGVyX2ZpbGUoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KfQo8P3BocAoKdXNlIFdQX0NMSVxEaXNwYXRjaGVyXENvbW1hbmROYW1lc3BhY2U7CgovKioKICogRG93bmxvYWRzLCBpbnN0YWxscywgdXBkYXRlcywgYW5kIG1hbmFnZXMgYSBXb3JkUHJlc3MgaW5zdGFsbGF0aW9uLgogKi8KZmluYWwgY2xhc3MgQ29yZV9Db21tYW5kX05hbWVzcGFjZSBleHRlbmRzIENvbW1hbmROYW1lc3BhY2UgewoKfQo8P3BocAoKdXNlIFdQX0NMSVxGZXRjaGVyczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CnVzZSBXUF9DTElcVXRpbHM7CnVzZSBXUF9DTElcV3BPcmdBcGk7CgovKioKICogVmVyaWZpZXMgcGx1Z2luIGZpbGUgaW50ZWdyaXR5IGJ5IGNvbXBhcmluZyB0byBwdWJsaXNoZWQgY2hlY2tzdW1zLgogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIENoZWNrc3VtX1BsdWdpbl9Db21tYW5kIGV4dGVuZHMgQ2hlY2tzdW1fQmFzZV9Db21tYW5kIHsKCgkvKioKCSAqIFVSTCB0ZW1wbGF0ZSB0aGF0IHBvaW50cyB0byB0aGUgQVBJIGVuZHBvaW50IHRvIHVzZS4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCglwcml2YXRlICR1cmxfdGVtcGxhdGUgPSAnaHR0cHM6Ly9kb3dubG9hZHMud29yZHByZXNzLm9yZy9wbHVnaW4tY2hlY2tzdW1zL3tzbHVnfS97dmVyc2lvbn0uanNvbic7CgoJLyoqCgkgKiBDYWNoZWQgcGx1Z2luIGRhdGEgZm9yIGFsbCBpbnN0YWxsZWQgcGx1Z2lucy4KCSAqCgkgKiBAdmFyIGFycmF5fG51bGwKCSAqLwoJcHJpdmF0ZSAkcGx1Z2luc19kYXRhOwoKCS8qKgoJICogQXJyYXkgb2YgZGV0ZWN0ZWQgZXJyb3JzLgoJICoKCSAqIEB2YXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSAkZXJyb3JzID0gYXJyYXkoKTsKCgkvKioKCSAqIFZlcmlmaWVzIHBsdWdpbiBmaWxlcyBhZ2FpbnN0IFdvcmRQcmVzcy5vcmcncyBjaGVja3N1bXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8cGx1Z2luPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgcGx1Z2lucyB0byB2ZXJpZnkuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBwbHVnaW5zIHdpbGwgYmUgdmVyaWZpZWQuCgkgKgoJICogWy0tc3RyaWN0XQoJICogOiBJZiBzZXQsIGV2ZW4gInNvZnQgY2hhbmdlcyIgbGlrZSByZWFkbWUudHh0IGNoYW5nZXMgd2lsbCB0cmlnZ2VyCgkgKiBjaGVja3N1bSBlcnJvcnMuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgc3BlY2lmaWMgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGpzb24KCSAqICAgLSBjc3YKCSAqICAgLSB5YW1sCgkgKiAgIC0gY291bnQKCSAqIC0tLQoJICoKCSAqIFstLWluc2VjdXJlXQoJICogOiBSZXRyeSBkb3dubG9hZHMgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGlmIFRMUyBoYW5kc2hha2UgZmFpbHMuIE5vdGU6IFRoaXMgbWFrZXMgdGhlIHJlcXVlc3QgdnVsbmVyYWJsZSB0byBhIE1JVE0gYXR0YWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgVmVyaWZ5IHRoZSBjaGVja3N1bXMgb2YgYWxsIGluc3RhbGxlZCBwbHVnaW5zCgkgKiAgICAgJCB3cCBwbHVnaW4gdmVyaWZ5LWNoZWNrc3VtcyAtLWFsbAoJICogICAgIFN1Y2Nlc3M6IFZlcmlmaWVkIDggb2YgOCBwbHVnaW5zLgoJICoKCSAqICAgICAjIFZlcmlmeSB0aGUgY2hlY2tzdW1zIG9mIGEgc2luZ2xlIHBsdWdpbiwgQWtpc21ldCBpbiB0aGlzIGNhc2UKCSAqICAgICAkIHdwIHBsdWdpbiB2ZXJpZnktY2hlY2tzdW1zIGFraXNtZXQKCSAqICAgICBTdWNjZXNzOiBWZXJpZmllZCAxIG9mIDEgcGx1Z2lucy4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIF9faW52b2tlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRmZXRjaGVyICA9IG5ldyBGZXRjaGVyc1xVbmZpbHRlcmVkUGx1Z2luKCk7CgkJJGFsbCAgICAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgkJJHN0cmljdCAgID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0cmljdCcsIGZhbHNlICk7CgkJJGluc2VjdXJlID0gKGJvb2wpIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2luc2VjdXJlJywgZmFsc2UgKTsKCQkkcGx1Z2lucyAgPSAkZmV0Y2hlci0+Z2V0X21hbnkoICRhbGwgPyAkdGhpcy0+Z2V0X2FsbF9wbHVnaW5fbmFtZXMoKSA6ICRhcmdzICk7CgoJCWlmICggZW1wdHkoICRwbHVnaW5zICkgJiYgISAkYWxsICkgewoJCQlXUF9DTEk6OmVycm9yKCAnWW91IG5lZWQgdG8gc3BlY2lmeSBlaXRoZXIgb25lIG9yIG1vcmUgcGx1Z2luIHNsdWdzIHRvIGNoZWNrIG9yIHVzZSB0aGUgLS1hbGwgZmxhZyB0byBjaGVjayBhbGwgcGx1Z2lucy4nICk7CgkJfQoKCQkkc2tpcHMgPSAwOwoKCQlmb3JlYWNoICggJHBsdWdpbnMgYXMgJHBsdWdpbiApIHsKCQkJJHZlcnNpb24gPSAkdGhpcy0+Z2V0X3BsdWdpbl92ZXJzaW9uKCAkcGx1Z2luLT5maWxlICk7CgoJCQlpZiAoIGZhbHNlID09PSAkdmVyc2lvbiApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkIG5vdCByZXRyaWV2ZSB0aGUgdmVyc2lvbiBmb3IgcGx1Z2luIHskcGx1Z2luLT5uYW1lfSwgc2tpcHBpbmcuIiApOwoJCQkJJHNraXBzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHdwX29yZ19hcGkgPSBuZXcgV3BPcmdBcGkoIFsgJ2luc2VjdXJlJyA9PiAkaW5zZWN1cmUgXSApOwoKCQkJdHJ5IHsKCQkJCSRjaGVja3N1bXMgPSAkd3Bfb3JnX2FwaS0+Z2V0X3BsdWdpbl9jaGVja3N1bXMoICRwbHVnaW4tPm5hbWUsICR2ZXJzaW9uICk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJCSRjaGVja3N1bXMgPSBmYWxzZTsKCQkJfQoKCQkJaWYgKCBmYWxzZSA9PT0gJGNoZWNrc3VtcyApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkNvdWxkIG5vdCByZXRyaWV2ZSB0aGUgY2hlY2tzdW1zIGZvciB2ZXJzaW9uIHskdmVyc2lvbn0gb2YgcGx1Z2luIHskcGx1Z2luLT5uYW1lfSwgc2tpcHBpbmcuIiApOwoJCQkJJHNraXBzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJGZpbGVzID0gJHRoaXMtPmdldF9wbHVnaW5fZmlsZXMoICRwbHVnaW4tPmZpbGUgKTsKCgkJCWZvcmVhY2ggKCAkY2hlY2tzdW1zIGFzICRmaWxlID0+ICRjaGVja3N1bV9hcnJheSApIHsKCQkJCWlmICggISBpbl9hcnJheSggJGZpbGUsICRmaWxlcywgdHJ1ZSApICkgewoJCQkJCSR0aGlzLT5hZGRfZXJyb3IoICRwbHVnaW4tPm5hbWUsICRmaWxlLCAnRmlsZSBpcyBtaXNzaW5nJyApOwoJCQkJfQoJCQl9CgoJCQlmb3JlYWNoICggJGZpbGVzIGFzICRmaWxlICkgewoJCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRmaWxlLCAkY2hlY2tzdW1zICkgKSB7CgkJCQkJJHRoaXMtPmFkZF9lcnJvciggJHBsdWdpbi0+bmFtZSwgJGZpbGUsICdGaWxlIHdhcyBhZGRlZCcgKTsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlpZiAoICEgJHN0cmljdCAmJiAkdGhpcy0+aXNfc29mdF9jaGFuZ2VfZmlsZSggJGZpbGUgKSApIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQkkcmVzdWx0ID0gJHRoaXMtPmNoZWNrX2ZpbGVfY2hlY2tzdW0oIGRpcm5hbWUoICRwbHVnaW4tPmZpbGUgKSAuICcvJyAuICRmaWxlLCAkY2hlY2tzdW1zWyAkZmlsZSBdICk7CgkJCQlpZiAoIHRydWUgIT09ICRyZXN1bHQgKSB7CgkJCQkJJHRoaXMtPmFkZF9lcnJvciggJHBsdWdpbi0+bmFtZSwgJGZpbGUsIGlzX3N0cmluZyggJHJlc3VsdCApID8gJHJlc3VsdCA6ICdDaGVja3N1bSBkb2VzIG5vdCBtYXRjaCcgKTsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCAhIGVtcHR5KCAkdGhpcy0+ZXJyb3JzICkgKSB7CgkJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKAoJCQkJJGFzc29jX2FyZ3MsCgkJCQlhcnJheSggJ3BsdWdpbl9uYW1lJywgJ2ZpbGUnLCAnbWVzc2FnZScgKQoJCQkpOwoJCQkkZm9ybWF0dGVyLT5kaXNwbGF5X2l0ZW1zKCAkdGhpcy0+ZXJyb3JzICk7CgkJfQoKCQkkdG90YWwgICAgID0gY291bnQoICRwbHVnaW5zICk7CgkJJGZhaWx1cmVzICA9IGNvdW50KCBhcnJheV91bmlxdWUoIGFycmF5X2NvbHVtbiggJHRoaXMtPmVycm9ycywgJ3BsdWdpbl9uYW1lJyApICkgKTsKCQkkc3VjY2Vzc2VzID0gJHRvdGFsIC0gJGZhaWx1cmVzIC0gJHNraXBzOwoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoCgkJCSdwbHVnaW4nLAoJCQkndmVyaWZ5JywKCQkJJHRvdGFsLAoJCQkkc3VjY2Vzc2VzLAoJCQkkZmFpbHVyZXMsCgkJCSRza2lwcwoJCSk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbmV3IGVycm9yIHRvIHRoZSBhcnJheSBvZiBkZXRlY3RlZCBlcnJvcnMuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGx1Z2luX25hbWUgTmFtZSBvZiB0aGUgcGx1Z2luIHRoYXQgaGFkIHRoZSBlcnJvci4KCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgUmVsYXRpdmUgcGF0aCB0byB0aGUgZmlsZSB0aGF0IGhhZCB0aGUgZXJyb3IuCgkgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIE1lc3NhZ2UgZXhwbGFpbmluZyB0aGUgZXJyb3IuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gYWRkX2Vycm9yKCAkcGx1Z2luX25hbWUsICRmaWxlLCAkbWVzc2FnZSApIHsKCQkkZXJyb3JbJ3BsdWdpbl9uYW1lJ10gPSAkcGx1Z2luX25hbWU7CgkJJGVycm9yWydmaWxlJ10gICAgICAgID0gJGZpbGU7CgkJJGVycm9yWydtZXNzYWdlJ10gICAgID0gJG1lc3NhZ2U7CgkJJHRoaXMtPmVycm9yc1tdICAgICAgID0gJGVycm9yOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgY3VycmVudGx5IGluc3RhbGxlZCB2ZXJzaW9uIGZvciBhIGdpdmVuIHBsdWdpbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJlbGF0aXZlIHBhdGggdG8gcGx1Z2luIGZpbGUgdG8gZ2V0IHRoZSB2ZXJzaW9uIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZ3xmYWxzZSBJbnN0YWxsZWQgdmVyc2lvbiBvZiB0aGUgcGx1Z2luLCBvciBmYWxzZSBpZiBub3QKCSAqICAgICAgICAgICAgICAgICAgICAgIGZvdW5kLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9wbHVnaW5fdmVyc2lvbiggJHBhdGggKSB7CgkJaWYgKCAhIGlzc2V0KCAkdGhpcy0+cGx1Z2luc19kYXRhICkgKSB7CgkJCSR0aGlzLT5wbHVnaW5zX2RhdGEgPSBnZXRfcGx1Z2lucygpOwoJCX0KCgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRwYXRoLCAkdGhpcy0+cGx1Z2luc19kYXRhICkgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiAkdGhpcy0+cGx1Z2luc19kYXRhWyAkcGF0aCBdWydWZXJzaW9uJ107Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBuYW1lcyBvZiBhbGwgaW5zdGFsbGVkIHBsdWdpbnMuCgkgKgoJICogQHJldHVybiBhcnJheTxzdHJpbmc+IE5hbWVzIG9mIGFsbCBpbnN0YWxsZWQgcGx1Z2lucy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWxsX3BsdWdpbl9uYW1lcygpIHsKCQkkbmFtZXMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCBnZXRfcGx1Z2lucygpIGFzICRmaWxlID0+ICRkZXRhaWxzICkgewoJCQkkbmFtZXNbXSA9IFV0aWxzXGdldF9wbHVnaW5fbmFtZSggJGZpbGUgKTsKCQl9CgoJCXJldHVybiAkbmFtZXM7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBsaXN0IG9mIGZpbGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGdpdmVuIHBsdWdpbi4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFJlbGF0aXZlIHBhdGggdG8gdGhlIG1haW4gcGx1Z2luIGZpbGUuCgkgKgoJICogQHJldHVybiBhcnJheTxzdHJpbmc+IEFycmF5IG9mIGZpbGVzIHdpdGggdGhlaXIgcmVsYXRpdmUgcGF0aHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3BsdWdpbl9maWxlcyggJHBhdGggKSB7CgkJJGZvbGRlciA9IGRpcm5hbWUoICR0aGlzLT5nZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSApOwoKCQkvLyBSZXR1cm4gc2luZ2xlIGZpbGUgcGx1Z2lucyBpbW1lZGlhdGVseSwgdG8gYXZvaWQgaXRlcmF0aW5nIG92ZXIgdGhlCgkJLy8gZW50aXJlIHBsdWdpbnMgZm9sZGVyLgoJCWlmICggV1BfUExVR0lOX0RJUiA9PT0gJGZvbGRlciApIHsKCQkJcmV0dXJuIChhcnJheSkgJHBhdGg7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmdldF9maWxlcyggdHJhaWxpbmdzbGFzaGl0KCAkZm9sZGVyICkgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB0aGUgaW50ZWdyaXR5IG9mIGEgc2luZ2xlIHBsdWdpbiBmaWxlIGJ5IGNvbXBhcmluZyBpdCB0byB0aGUKCSAqIG9mZmljaWFsbHkgcHJvdmlkZWQgY2hlY2tzdW0uCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCAgICAgIFJlbGF0aXZlIHBhdGggdG8gdGhlIHBsdWdpbiBmaWxlIHRvIGNoZWNrIHRoZQoJICogICAgICAgICAgICAgICAgICAgICAgICAgIGludGVncml0eSBvZi4KCSAqIEBwYXJhbSBhcnJheSAgJGNoZWNrc3VtcyBBcnJheSBvZiBwcm92aWRlZCBjaGVja3N1bXMgdG8gY29tcGFyZSBhZ2FpbnN0LgoJICoKCSAqIEByZXR1cm4gdHJ1ZXxzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBjaGVja19maWxlX2NoZWNrc3VtKCAkcGF0aCwgJGNoZWNrc3VtcyApIHsKCQlpZiAoICR0aGlzLT5zdXBwb3J0c19zaGEyNTYoKQoJCQkmJiBhcnJheV9rZXlfZXhpc3RzKCAnc2hhMjU2JywgJGNoZWNrc3VtcyApCgkJKSB7CgkJCSRzaGEyNTYgPSAkdGhpcy0+Z2V0X3NoYTI1NiggJHRoaXMtPmdldF9hYnNvbHV0ZV9wYXRoKCAkcGF0aCApICk7CgoJCQlyZXR1cm4gaW5fYXJyYXkoICRzaGEyNTYsIChhcnJheSkgJGNoZWNrc3Vtc1snc2hhMjU2J10sIHRydWUgKTsKCQl9CgoJCWlmICggISBhcnJheV9rZXlfZXhpc3RzKCAnbWQ1JywgJGNoZWNrc3VtcyApICkgewoJCQlyZXR1cm4gJ05vIG1hdGNoaW5nIGNoZWNrc3VtIGFsZ29yaXRobSBmb3VuZCc7CgkJfQoKCQkkbWQ1ID0gJHRoaXMtPmdldF9tZDUoICR0aGlzLT5nZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSApOwoKCQlyZXR1cm4gaW5fYXJyYXkoICRtZDUsIChhcnJheSkgJGNoZWNrc3Vtc1snbWQ1J10sIHRydWUgKTsKCX0KCgkvKioKCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IGVudmlyb25tZW50IHN1cHBvcnRzIDI1Ni1iaXQgU0hBLTIuCgkgKgoJICogU2hvdWxkIGJlIHN1cHBvcnRlZCBmb3IgUEhQIDUrLCBidXQgd2UgbWlnaHQgZmluZCBlZGdlIGNhc2VzIGRlcGVuZGluZyBvbgoJICogaG9zdC4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBzdXBwb3J0c19zaGEyNTYoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSAyNTYtYml0IFNIQS0yIG9mIGEgZ2l2ZW4gZmlsZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRmaWxlcGF0aCBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBmaWxlIHRvIGNhbGN1bGF0ZSB0aGUgU0hBLTIKCSAqICAgICAgICAgICAgICAgICAgICAgICAgIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9zaGEyNTYoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gaGFzaF9maWxlKCAnc2hhMjU2JywgJGZpbGVwYXRoICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBNRDUgb2YgYSBnaXZlbiBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGVwYXRoIEFic29sdXRlIHBhdGggdG8gdGhlIGZpbGUgdG8gY2FsY3VsYXRlIHRoZSBNRDUKCSAqICAgICAgICAgICAgICAgICAgICAgICAgIGZvci4KCSAqCgkgKiBAcmV0dXJuIHN0cmluZwoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9tZDUoICRmaWxlcGF0aCApIHsKCQlyZXR1cm4gaGFzaF9maWxlKCAnbWQ1JywgJGZpbGVwYXRoICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBhYnNvbHV0ZSBwYXRoIHRvIGEgcmVsYXRpdmUgcGx1Z2luIGZpbGUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkcGF0aCBSZWxhdGl2ZSBwYXRoIHRvIGdldCB0aGUgYWJzb2x1dGUgcGF0aCBmb3IuCgkgKgoJICogQHJldHVybiBzdHJpbmcKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfYWJzb2x1dGVfcGF0aCggJHBhdGggKSB7CgkJcmV0dXJuIFdQX1BMVUdJTl9ESVIgLiAnLycgLiAkcGF0aDsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBsaXN0IG9mIGZpbGVzIHRoYXQgb25seSB0cmlnZ2VyIGNoZWNrc3VtIGVycm9ycyBpbiBzdHJpY3QgbW9kZS4KCSAqCgkgKiBAcmV0dXJuIGFycmF5PHN0cmluZz4gQXJyYXkgb2YgZmlsZSBuYW1lcy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfc29mdF9jaGFuZ2VfZmlsZXMoKSB7CgkJc3RhdGljICRmaWxlcyA9IGFycmF5KAoJCQkncmVhZG1lLnR4dCcsCgkJCSdyZWFkbWUubWQnLAoJCSk7CgoJCXJldHVybiAkZmlsZXM7Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciBhIGdpdmVuIGZpbGUgd2lsbCBvbmx5IHRyaWdnZXIgY2hlY2tzdW0gZXJyb3JzIGluIHN0cmljdAoJICogbW9kZS4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRmaWxlIEZpbGUgdG8gY2hlY2suCgkgKgoJICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGZpbGUgb25seSB0cmlnZ2VycyBjaGVja3N1bSBlcnJvcnMgaW4gc3RyaWN0CgkgKiBtb2RlLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX3NvZnRfY2hhbmdlX2ZpbGUoICRmaWxlICkgewoJCXJldHVybiBpbl9hcnJheSggc3RydG9sb3dlciggJGZpbGUgKSwgJHRoaXMtPmdldF9zb2Z0X2NoYW5nZV9maWxlcygpLCB0cnVlICk7Cgl9Cn0KPD9waHAKCm5hbWVzcGFjZSBXUF9DTElcRmV0Y2hlcnM7CgovKioKICogRmV0Y2ggYSBXb3JkUHJlc3MgcGx1Z2luIGJhc2VkIG9uIG9uZSBvZiBpdHMgYXR0cmlidXRlcy4KICoKICogVGhpcyBpcyBhIHNwZWNpYWwgdmVyc2lvbiBvZiB0aGUgcGx1Z2luIGZldGNoZXIuIEl0IGRvZXNuJ3QgdXNlIHRoZQogKiBgYWxsX3BsdWdpbnNgIGZpbHRlciwgc28gdGhhdCBwbHVnaW5zIGNhbm5vdCBoaWRlIHRoZW1zZWx2ZXMgZnJvbSB0aGUKICogY2hlY2tzLgogKgogKi8KY2xhc3MgVW5maWx0ZXJlZFBsdWdpbiBleHRlbmRzIEJhc2UgewoKCS8qKgoJICogQHZhciBzdHJpbmcgJG1zZyBFcnJvciBtZXNzYWdlIHRvIHVzZSB3aGVuIGludmFsaWQgZGF0YSBpcyBwcm92aWRlZAoJICovCglwcm90ZWN0ZWQgJG1zZyA9ICJUaGUgJyVzJyBwbHVnaW4gY291bGQgbm90IGJlIGZvdW5kLiI7CgoJLyoqCgkgKiBHZXQgYSBwbHVnaW4gb2JqZWN0IGJ5IG5hbWUuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICoKCSAqIEByZXR1cm4gb2JqZWN0fGZhbHNlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRuYW1lICkgewoJCWZvcmVhY2ggKCBnZXRfcGx1Z2lucygpIGFzICRmaWxlID0+ICRfICkgewoJCQlpZiAoICJ7JG5hbWV9LnBocCIgPT09ICRmaWxlIHx8CgkJCQkoICRuYW1lICYmICRmaWxlID09PSAkbmFtZSApIHx8CgkJCQkoIGRpcm5hbWUoICRmaWxlICkgPT09ICRuYW1lICYmICcuJyAhPT0gJG5hbWUgKSApIHsKCQkJCXJldHVybiAob2JqZWN0KSBjb21wYWN0KCAnbmFtZScsICdmaWxlJyApOwoJCQl9CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9Cn0KCjw/cGhwCgp1c2UgV1BfQ0xJXFV0aWxzOwp1c2UgV1BfQ0xJXFdwT3JnQXBpOwoKLyoqCiAqIFZlcmlmaWVzIGNvcmUgZmlsZSBpbnRlZ3JpdHkgYnkgY29tcGFyaW5nIHRvIHB1Ymxpc2hlZCBjaGVja3N1bXMuCiAqCiAqIEBwYWNrYWdlIHdwLWNsaQogKi8KY2xhc3MgQ2hlY2tzdW1fQ29yZV9Db21tYW5kIGV4dGVuZHMgQ2hlY2tzdW1fQmFzZV9Db21tYW5kIHsKCgkvKioKCSAqIFZlcmlmaWVzIFdvcmRQcmVzcyBmaWxlcyBhZ2FpbnN0IFdvcmRQcmVzcy5vcmcncyBjaGVja3N1bXMuCgkgKgoJICogRG93bmxvYWRzIG1kNSBjaGVja3N1bXMgZm9yIHRoZSBjdXJyZW50IHZlcnNpb24gZnJvbSBXb3JkUHJlc3Mub3JnLCBhbmQKCSAqIGNvbXBhcmVzIHRob3NlIGNoZWNrc3VtcyBhZ2FpbnN0IHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIGZpbGVzLgoJICoKCSAqIEZvciBzZWN1cml0eSwgYXZvaWRzIGxvYWRpbmcgV29yZFByZXNzIHdoZW4gdmVyaWZ5aW5nIGNoZWNrc3Vtcy4KCSAqCgkgKiBJZiB5b3UgZXhwZXJpZW5jZSBpc3N1ZXMgdmVyaWZ5aW5nIGZyb20gdGhpcyBjb21tYW5kLCBlbnN1cmUgeW91IGFyZQoJICogcGFzc2luZyB0aGUgcmVsZXZhbnQgYC0tbG9jYWxlYCBhbmQgYC0tdmVyc2lvbmAgYXJndW1lbnRzIGFjY29yZGluZyB0bwoJICogdGhlIHZhbHVlcyBmcm9tIHRoZSBgRGFzaGJvYXJkLT5VcGRhdGVzYCBtZW51IGluIHRoZSBhZG1pbiBhcmVhIG9mIHRoZQoJICogc2l0ZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tdmVyc2lvbj08dmVyc2lvbj5dCgkgKiA6IFZlcmlmeSBjaGVja3N1bXMgYWdhaW5zdCBhIHNwZWNpZmljIHZlcnNpb24gb2YgV29yZFByZXNzLgoJICoKCSAqIFstLWxvY2FsZT08bG9jYWxlPl0KCSAqIDogVmVyaWZ5IGNoZWNrc3VtcyBhZ2FpbnN0IGEgc3BlY2lmaWMgbG9jYWxlIG9mIFdvcmRQcmVzcy4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgZG93bmxvYWRzIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIFZlcmlmeSBjaGVja3N1bXMKCSAqICAgICAkIHdwIGNvcmUgdmVyaWZ5LWNoZWNrc3VtcwoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gdmVyaWZpZXMgYWdhaW5zdCBjaGVja3N1bXMuCgkgKgoJICogICAgICMgVmVyaWZ5IGNoZWNrc3VtcyBmb3IgZ2l2ZW4gV29yZFByZXNzIHZlcnNpb24KCSAqICAgICAkIHdwIGNvcmUgdmVyaWZ5LWNoZWNrc3VtcyAtLXZlcnNpb249NC4wCgkgKiAgICAgU3VjY2VzczogV29yZFByZXNzIGluc3RhbGxhdGlvbiB2ZXJpZmllcyBhZ2FpbnN0IGNoZWNrc3Vtcy4KCSAqCgkgKiAgICAgIyBWZXJpZnkgY2hlY2tzdW1zIGZvciBnaXZlbiBsb2NhbGUKCSAqICAgICAkIHdwIGNvcmUgdmVyaWZ5LWNoZWNrc3VtcyAtLWxvY2FsZT1lbl9VUwoJICogICAgIFN1Y2Nlc3M6IFdvcmRQcmVzcyBpbnN0YWxsYXRpb24gdmVyaWZpZXMgYWdhaW5zdCBjaGVja3N1bXMuCgkgKgoJICogICAgICMgVmVyaWZ5IGNoZWNrc3VtcyBmb3IgZ2l2ZW4gbG9jYWxlCgkgKiAgICAgJCB3cCBjb3JlIHZlcmlmeS1jaGVja3N1bXMgLS1sb2NhbGU9amEKCSAqICAgICBXYXJuaW5nOiBGaWxlIGRvZXNuJ3QgdmVyaWZ5IGFnYWluc3QgY2hlY2tzdW06IHdwLWluY2x1ZGVzL3ZlcnNpb24ucGhwCgkgKiAgICAgV2FybmluZzogRmlsZSBkb2Vzbid0IHZlcmlmeSBhZ2FpbnN0IGNoZWNrc3VtOiByZWFkbWUuaHRtbAoJICogICAgIFdhcm5pbmc6IEZpbGUgZG9lc24ndCB2ZXJpZnkgYWdhaW5zdCBjaGVja3N1bTogd3AtY29uZmlnLXNhbXBsZS5waHAKCSAqICAgICBFcnJvcjogV29yZFByZXNzIGluc3RhbGxhdGlvbiBkb2Vzbid0IHZlcmlmeSBhZ2FpbnN0IGNoZWNrc3Vtcy4KCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkd3BfdmVyc2lvbiA9ICcnOwoJCSRsb2NhbGUgICAgID0gJyc7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ3ZlcnNpb24nXSApICkgewoJCQkkd3BfdmVyc2lvbiA9ICRhc3NvY19hcmdzWyd2ZXJzaW9uJ107CgkJfQoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydsb2NhbGUnXSApICkgewoJCQkkbG9jYWxlID0gJGFzc29jX2FyZ3NbJ2xvY2FsZSddOwoJCX0KCgkJaWYgKCBlbXB0eSggJHdwX3ZlcnNpb24gKSApIHsKCQkJJGRldGFpbHMgICAgPSBzZWxmOjpnZXRfd3BfZGV0YWlscygpOwoJCQkkd3BfdmVyc2lvbiA9ICRkZXRhaWxzWyd3cF92ZXJzaW9uJ107CgoJCQlpZiAoIGVtcHR5KCAkbG9jYWxlICkgKSB7CgkJCQkkbG9jYWxlID0gJGRldGFpbHNbJ3dwX2xvY2FsX3BhY2thZ2UnXTsKCQkJfQoJCX0KCgkJJGluc2VjdXJlICAgPSAoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApOwoJCSR3cF9vcmdfYXBpID0gbmV3IFdwT3JnQXBpKCBbICdpbnNlY3VyZScgPT4gJGluc2VjdXJlIF0gKTsKCgkJdHJ5IHsKCQkJJGNoZWNrc3VtcyA9ICR3cF9vcmdfYXBpLT5nZXRfY29yZV9jaGVja3N1bXMoICR3cF92ZXJzaW9uLCBlbXB0eSggJGxvY2FsZSApID8gJ2VuX1VTJyA6ICRsb2NhbGUgKTsKCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRleGNlcHRpb24gKTsKCQl9CgoJCWlmICggISBpc19hcnJheSggJGNoZWNrc3VtcyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgZ2V0IGNoZWNrc3VtcyBmcm9tIFdvcmRQcmVzcy5vcmcuIiApOwoJCX0KCgkJJGhhc19lcnJvcnMgPSBmYWxzZTsKCQlmb3JlYWNoICggJGNoZWNrc3VtcyBhcyAkZmlsZSA9PiAkY2hlY2tzdW0gKSB7CgkJCS8vIFNraXAgZmlsZXMgd2hpY2ggZ2V0IHVwZGF0ZWQKCQkJaWYgKCAnd3AtY29udGVudCcgPT09IHN1YnN0ciggJGZpbGUsIDAsIDEwICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJaWYgKCAhIGZpbGVfZXhpc3RzKCBBQlNQQVRIIC4gJGZpbGUgKSApIHsKCQkJCVdQX0NMSTo6d2FybmluZyggIkZpbGUgZG9lc24ndCBleGlzdDogeyRmaWxlfSIgKTsKCQkJCSRoYXNfZXJyb3JzID0gdHJ1ZTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkbWQ1X2ZpbGUgPSBtZDVfZmlsZSggQUJTUEFUSCAuICRmaWxlICk7CgkJCWlmICggJG1kNV9maWxlICE9PSAkY2hlY2tzdW0gKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJGaWxlIGRvZXNuJ3QgdmVyaWZ5IGFnYWluc3QgY2hlY2tzdW06IHskZmlsZX0iICk7CgkJCQkkaGFzX2Vycm9ycyA9IHRydWU7CgkJCX0KCQl9CgoJCSRjb3JlX2NoZWNrc3Vtc19maWxlcyA9IGFycmF5X2ZpbHRlciggYXJyYXlfa2V5cyggJGNoZWNrc3VtcyApLCBbICR0aGlzLCAnZmlsdGVyX2ZpbGUnIF0gKTsKCQkkY29yZV9maWxlcyAgICAgICAgICAgPSAkdGhpcy0+Z2V0X2ZpbGVzKCBBQlNQQVRIICk7CgkJJGFkZGl0aW9uYWxfZmlsZXMgICAgID0gYXJyYXlfZGlmZiggJGNvcmVfZmlsZXMsICRjb3JlX2NoZWNrc3Vtc19maWxlcyApOwoKCQlpZiAoICEgZW1wdHkoICRhZGRpdGlvbmFsX2ZpbGVzICkgKSB7CgkJCWZvcmVhY2ggKCAkYWRkaXRpb25hbF9maWxlcyBhcyAkYWRkaXRpb25hbF9maWxlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiRmlsZSBzaG91bGQgbm90IGV4aXN0OiB7JGFkZGl0aW9uYWxfZmlsZX0iICk7CgkJCX0KCQl9CgoJCWlmICggISAkaGFzX2Vycm9ycyApIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAnV29yZFByZXNzIGluc3RhbGxhdGlvbiB2ZXJpZmllcyBhZ2FpbnN0IGNoZWNrc3Vtcy4nICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjplcnJvciggIldvcmRQcmVzcyBpbnN0YWxsYXRpb24gZG9lc24ndCB2ZXJpZnkgYWdhaW5zdCBjaGVja3N1bXMuIiApOwoJCX0KCX0KCgkvKioKCSAqIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgZmlsZSBpbiB0aGUgdmVyaWZpY2F0aW9uIG9yIG5vdC4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRmaWxlcGF0aCBQYXRoIHRvIGEgZmlsZS4KCSAqCgkgKiBAcmV0dXJuIGJvb2wKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGZpbHRlcl9maWxlKCAkZmlsZXBhdGggKSB7CgkJcmV0dXJuICggMCA9PT0gc3RycG9zKCAkZmlsZXBhdGgsICd3cC1hZG1pbi8nICkKCQkJfHwgMCA9PT0gc3RycG9zKCAkZmlsZXBhdGgsICd3cC1pbmNsdWRlcy8nICkKCQkJfHwgMSA9PT0gcHJlZ19tYXRjaCggJy9ed3AtKD8hY29uZmlnXC5waHApKFteXC9dKikkLycsICRmaWxlcGF0aCApCgkJKTsKCX0KCgkvKioKCSAqIEdldHMgdmVyc2lvbiBpbmZvcm1hdGlvbiBmcm9tIGB3cC1pbmNsdWRlcy92ZXJzaW9uLnBocGAuCgkgKgoJICogQHJldHVybiBhcnJheSB7CgkgKiAgICAgQHR5cGUgc3RyaW5nICR3cF92ZXJzaW9uIFRoZSBXb3JkUHJlc3MgdmVyc2lvbi4KCSAqICAgICBAdHlwZSBpbnQgJHdwX2RiX3ZlcnNpb24gVGhlIFdvcmRQcmVzcyBEQiByZXZpc2lvbi4KCSAqICAgICBAdHlwZSBzdHJpbmcgJHRpbnltY2VfdmVyc2lvbiBUaGUgVGlueU1DRSB2ZXJzaW9uLgoJICogICAgIEB0eXBlIHN0cmluZyAkd3BfbG9jYWxfcGFja2FnZSBUaGUgVGlueU1DRSB2ZXJzaW9uLgoJICogfQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfd3BfZGV0YWlscygpIHsKCQkkdmVyc2lvbnNfcGF0aCA9IEFCU1BBVEggLiAnd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnOwoKCQlpZiAoICEgaXNfcmVhZGFibGUoICR2ZXJzaW9uc19wYXRoICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoCgkJCQkiVGhpcyBkb2VzIG5vdCBzZWVtIHRvIGJlIGEgV29yZFByZXNzIGluc3RhbGwuXG4iIC4KCQkJCSdQYXNzIC0tcGF0aD1gcGF0aC90by93b3JkcHJlc3NgIG9yIHJ1biBgd3AgY29yZSBkb3dubG9hZGAuJwoJCQkpOwoJCX0KCgkJJHZlcnNpb25fY29udGVudCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkdmVyc2lvbnNfcGF0aCwgbnVsbCwgbnVsbCwgNiwgMjA0OCApOwoKCQkkdmFycyAgID0gWyAnd3BfdmVyc2lvbicsICd3cF9kYl92ZXJzaW9uJywgJ3RpbnltY2VfdmVyc2lvbicsICd3cF9sb2NhbF9wYWNrYWdlJyBdOwoJCSRyZXN1bHQgPSBbXTsKCgkJZm9yZWFjaCAoICR2YXJzIGFzICR2YXJfbmFtZSApIHsKCQkJJHJlc3VsdFsgJHZhcl9uYW1lIF0gPSBzZWxmOjpmaW5kX3ZhciggJHZhcl9uYW1lLCAkdmVyc2lvbl9jb250ZW50ICk7CgkJfQoKCQlyZXR1cm4gJHJlc3VsdDsKCX0KCgkvKioKCSAqIFNlYXJjaGVzIGZvciB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdmFyaWFibGUgYCR2YXJfbmFtZWAgaW4gUEhQIGNvZGUgYCRjb2RlYC4KCSAqCgkgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gbWF0Y2hpbmcgdGhlIGBcJFZBUl9OQU1FID0gKFteO10rKWAgcmVndWxhciBleHByZXNzaW9uIGFuZCByZXR1cm5pbmcKCSAqIHRoZSBmaXJzdCBtYXRjaCBlaXRoZXIgYXMgYSBgc3RyaW5nYCBvciBhcyBhbiBgaW50ZWdlcmAgKGRlcGVuZGluZyBpZiBpdCdzIHN1cnJvdW5kZWQgYnkKCSAqIHF1b3RlcyBvciBub3QpLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHZhcl9uYW1lIFZhcmlhYmxlIG5hbWUgdG8gc2VhcmNoIGZvci4KCSAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgUEhQIGNvZGUgdG8gc2VhcmNoIGluLgoJICoKCSAqIEByZXR1cm4gaW50fHN0cmluZ3xudWxsCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGZpbmRfdmFyKCAkdmFyX25hbWUsICRjb2RlICkgewoJCSRzdGFydCA9IHN0cnBvcyggJGNvZGUsICckJyAuICR2YXJfbmFtZSAuICcgPSAnICk7CgoJCWlmICggISAkc3RhcnQgKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJJHN0YXJ0ID0gJHN0YXJ0ICsgc3RybGVuKCAkdmFyX25hbWUgKSArIDM7CgkJJGVuZCAgID0gc3RycG9zKCAkY29kZSwgJzsnLCAkc3RhcnQgKTsKCgkJJHZhbHVlID0gc3Vic3RyKCAkY29kZSwgJHN0YXJ0LCAkZW5kIC0gJHN0YXJ0ICk7CgoJCXJldHVybiB0cmltKCAkdmFsdWUsICInIiApOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfbGFuZ3VhZ2VfYXV0b2xvYWRlciA9IGRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3ZlbmRvci9hdXRvbG9hZC5waHAnOwoKaWYgKCBmaWxlX2V4aXN0cyggJHdwY2xpX2xhbmd1YWdlX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfbGFuZ3VhZ2VfYXV0b2xvYWRlcjsKfQoKJHdwY2xpX2xhbmd1YWdlX2NoZWNrX3JlcXVpcmVtZW50cyA9IGZ1bmN0aW9uKCkgewoJaWYgKCBcV1BfQ0xJXFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuMCcsICc8JyApICkgewoJCVdQX0NMSTo6ZXJyb3IoICdSZXF1aXJlcyBXb3JkUHJlc3MgNC4wIG9yIGdyZWF0ZXIuJyApOwoJfQp9OwoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdsYW5ndWFnZSBjb3JlJywKCSdDb3JlX0xhbmd1YWdlX0NvbW1hbmQnLAoJYXJyYXkoICdiZWZvcmVfaW52b2tlJyA9PiAkd3BjbGlfbGFuZ3VhZ2VfY2hlY2tfcmVxdWlyZW1lbnRzICkKKTsKCldQX0NMSTo6YWRkX2NvbW1hbmQoCgknbGFuZ3VhZ2UgcGx1Z2luJywKCSdQbHVnaW5fTGFuZ3VhZ2VfQ29tbWFuZCcsCglhcnJheSggJ2JlZm9yZV9pbnZva2UnID0+ICR3cGNsaV9sYW5ndWFnZV9jaGVja19yZXF1aXJlbWVudHMgKQopOwoKV1BfQ0xJOjphZGRfY29tbWFuZCgKCSdsYW5ndWFnZSB0aGVtZScsCgknVGhlbWVfTGFuZ3VhZ2VfQ29tbWFuZCcsCglhcnJheSggJ2JlZm9yZV9pbnZva2UnID0+ICR3cGNsaV9sYW5ndWFnZV9jaGVja19yZXF1aXJlbWVudHMgKQopOwoKV1BfQ0xJOjphZGRfaG9vaygKCSdhZnRlcl9hZGRfY29tbWFuZDpzaXRlJywKCWZ1bmN0aW9uICgpIHsKCQlXUF9DTEk6OmFkZF9jb21tYW5kKCAnc2l0ZSBzd2l0Y2gtbGFuZ3VhZ2UnLCAnU2l0ZV9Td2l0Y2hfTGFuZ3VhZ2VfQ29tbWFuZCcgKTsKCX0KKTsKCmlmICggY2xhc3NfZXhpc3RzKCAnV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZScgKSApIHsKCVdQX0NMSTo6YWRkX2NvbW1hbmQoICdsYW5ndWFnZScsICdMYW5ndWFnZV9OYW1lc3BhY2UnICk7Cn0KPD9waHAKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyBwbHVnaW4gbGFuZ3VhZ2UgcGFja3MuCiAqCiAqICMjIEVYQU1QTEVTCiAqCiAqICAgICAjIEluc3RhbGwgdGhlIER1dGNoIHBsdWdpbiBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gaW5zdGFsbCBoZWxsby1kb2xseSBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgaW5zdGFsbGVkLgogKgogKiAgICAgIyBVbmluc3RhbGwgdGhlIER1dGNoIHBsdWdpbiBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gdW5pbnN0YWxsIGhlbGxvLWRvbGx5IG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSB1bmluc3RhbGxlZC4KICoKICogICAgICMgTGlzdCBpbnN0YWxsZWQgcGx1Z2luIGxhbmd1YWdlIHBhY2thZ2VzLgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gbGlzdCAtLXN0YXR1cz1pbnN0YWxsZWQKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBsYW5ndWFnZSB8IGVuZ2xpc2hfbmFtZSB8IG5hdGl2ZV9uYW1lIHwgc3RhdHVzICAgIHwgdXBkYXRlICAgIHwgdXBkYXRlZCAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmxfTkwgICAgfCBEdXRjaCAgICAgICAgfCBOZWRlcmxhbmRzICB8IGluc3RhbGxlZCB8IGF2YWlsYWJsZSB8IDIwMTYtMDUtMTMgMDg6MTI6NTAgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqLwpjbGFzcyBQbHVnaW5fTGFuZ3VhZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSVxDb21tYW5kV2l0aFRyYW5zbGF0aW9uIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAncGx1Z2lucyc7CgoJcHJvdGVjdGVkICRvYmpfZmllbGRzID0gYXJyYXkoCgkJJ3BsdWdpbicsCgkJJ2xhbmd1YWdlJywKCQknZW5nbGlzaF9uYW1lJywKCQknbmF0aXZlX25hbWUnLAoJCSdzdGF0dXMnLAoJCSd1cGRhdGUnLAoJCSd1cGRhdGVkJywKCSk7CgoJLyoqCgkgKiBMaXN0cyBhbGwgYXZhaWxhYmxlIGxhbmd1YWdlcyBmb3Igb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIGxpc3QgbGFuZ3VhZ2VzIGZvci4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgYXZhaWxhYmxlIGxhbmd1YWdlcyBmb3IgYWxsIHBsdWdpbnMgd2lsbCBiZSBsaXN0ZWQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogRGlzcGxheSB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgcmVzdWx0cyBieSBrZXk9dmFsdWUgcGFpcnMuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggdHJhbnNsYXRpb246CgkgKgoJICogKiBwbHVnaW4KCSAqICogbGFuZ3VhZ2UKCSAqICogZW5nbGlzaF9uYW1lCgkgKiAqIG5hdGl2ZV9uYW1lCgkgKiAqIHN0YXR1cwoJICogKiB1cGRhdGUKCSAqICogdXBkYXRlZAoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBsYW5ndWFnZSxlbmdsaXNoX25hbWUsc3RhdHVzIGZpZWxkcyBvZiBhdmFpbGFibGUgbGFuZ3VhZ2VzLgoJICogICAgICQgd3AgbGFuZ3VhZ2UgcGx1Z2luIGxpc3QgLS1maWVsZHM9bGFuZ3VhZ2UsZW5nbGlzaF9uYW1lLHN0YXR1cwoJICogICAgICstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGxhbmd1YWdlICAgICAgIHwgZW5nbGlzaF9uYW1lICAgICAgICAgICAgfCBzdGF0dXMgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgYXIgICAgICAgICAgICAgfCBBcmFiaWMgICAgICAgICAgICAgICAgICB8IHVuaW5zdGFsbGVkIHwKCSAqICAgICB8IGFyeSAgICAgICAgICAgIHwgTW9yb2NjYW4gQXJhYmljICAgICAgICAgfCB1bmluc3RhbGxlZCB8CgkgKiAgICAgfCBheiAgICAgICAgICAgICB8IEF6ZXJiYWlqYW5pICAgICAgICAgICAgIHwgdW5pbnN0YWxsZWQgfAoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGFsbCA9IFxXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWxsJywgZmFsc2UgKTsKCgkJaWYgKCAhICRhbGwgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdQbGVhc2Ugc3BlY2lmeSBvbmUgb3IgbW9yZSBwbHVnaW5zLCBvciB1c2UgLS1hbGwuJyApOwoJCX0KCgkJaWYgKCAkYWxsICkgewoJCQkkYXJncyA9IGFycmF5X21hcCggJ1xXUF9DTElcVXRpbHNcZ2V0X3BsdWdpbl9uYW1lJywgYXJyYXlfa2V5cyggJHRoaXMtPmdldF9hbGxfcGx1Z2lucygpICkgKTsKCgkJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdObyBwbHVnaW5zIGluc3RhbGxlZC4nICk7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgoJCSR1cGRhdGVzICAgICAgICA9ICR0aGlzLT5nZXRfdHJhbnNsYXRpb25fdXBkYXRlcygpOwoJCSRjdXJyZW50X2xvY2FsZSA9IGdldF9sb2NhbGUoKTsKCgkJJHRyYW5zbGF0aW9ucyA9IGFycmF5KCk7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkcGx1Z2luICkgewoJCQkkaW5zdGFsbGVkX3RyYW5zbGF0aW9ucyA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcyggJHBsdWdpbiApOwoJCQkkYXZhaWxhYmxlX3RyYW5zbGF0aW9ucyA9ICR0aGlzLT5nZXRfYWxsX2xhbmd1YWdlcyggJHBsdWdpbiApOwoKCQkJZm9yZWFjaCAoICRhdmFpbGFibGVfdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbiApIHsKCQkJCSR0cmFuc2xhdGlvblsncGx1Z2luJ10gPSAkcGx1Z2luOwoJCQkJJHRyYW5zbGF0aW9uWydzdGF0dXMnXSA9IGluX2FycmF5KCAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10sICRpbnN0YWxsZWRfdHJhbnNsYXRpb25zLCB0cnVlICkgPyAnaW5zdGFsbGVkJyA6ICd1bmluc3RhbGxlZCc7CgoJCQkJaWYgKCAkY3VycmVudF9sb2NhbGUgPT09ICR0cmFuc2xhdGlvblsnbGFuZ3VhZ2UnXSApIHsKCQkJCQkkdHJhbnNsYXRpb25bJ3N0YXR1cyddID0gJ2FjdGl2ZSc7CgkJCQl9CgoJCQkJJGZpbHRlcl9hcmdzID0gYXJyYXkoCgkJCQkJJ2xhbmd1YWdlJyA9PiAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10sCgkJCQkJJ3R5cGUnICAgICA9PiAncGx1Z2luJywKCQkJCQknc2x1ZycgICAgID0+ICRwbHVnaW4sCgkJCQkpOwoJCQkJJHVwZGF0ZSAgICAgID0gd3BfbGlzdF9maWx0ZXIoICR1cGRhdGVzLCAkZmlsdGVyX2FyZ3MgKTsKCgkJCQkkdHJhbnNsYXRpb25bJ3VwZGF0ZSddID0gJHVwZGF0ZSA/ICdhdmFpbGFibGUnIDogJ25vbmUnOwoKCQkJCS8vIFN1cHBvcnQgZmVhdHVyZXMgbGlrZSAtLXN0YXR1cz1hY3RpdmUuCgkJCQlmb3JlYWNoICggYXJyYXlfa2V5cyggJHRyYW5zbGF0aW9uICkgYXMgJGZpZWxkICkgewoJCQkJCWlmICggaXNzZXQoICRhc3NvY19hcmdzWyAkZmllbGQgXSApICYmICRhc3NvY19hcmdzWyAkZmllbGQgXSAhPT0gJHRyYW5zbGF0aW9uWyAkZmllbGQgXSApIHsKCQkJCQkJY29udGludWUgMjsKCQkJCQl9CgkJCQl9CgoJCQkJJHRyYW5zbGF0aW9uc1tdID0gJHRyYW5zbGF0aW9uOwoJCQl9CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHRyYW5zbGF0aW9ucyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgZ2l2ZW4gbGFuZ3VhZ2UgaXMgaW5zdGFsbGVkLgoJICoKCSAqIFJldHVybnMgZXhpdCBjb2RlIDAgd2hlbiBpbnN0YWxsZWQsIDEgd2hlbiB1bmluc3RhbGxlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHBsdWdpbj4KCSAqIDogUGx1Z2luIHRvIGNoZWNrIGZvci4KCSAqCgkgKiA8bGFuZ3VhZ2U+Li4uCgkgKiA6IFRoZSBsYW5ndWFnZSBjb2RlIHRvIGNoZWNrLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgQ2hlY2sgd2hldGhlciB0aGUgR2VybWFuIGxhbmd1YWdlIGlzIGluc3RhbGxlZCBmb3IgQWtpc21ldDsgZXhpdCBzdGF0dXMgMCBpZiBpbnN0YWxsZWQsIG90aGVyd2lzZSAxLgoJICogICAgICQgd3AgbGFuZ3VhZ2UgcGx1Z2luIGlzLWluc3RhbGxlZCBha2lzbWV0IGRlX0RFCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWluc3RhbGxlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfaW5zdGFsbGVkKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSRwbHVnaW4gICAgICAgICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSRsYW5ndWFnZV9jb2RlcyA9IChhcnJheSkgJGFyZ3M7CgoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoICRwbHVnaW4gKTsKCgkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJXFdQX0NMSTo6aGFsdCggMSApOwoJCQl9CgkJfQoKCQlcV1BfQ0xJOjpoYWx0KCAwICk7Cgl9CgoJLyoqCgkgKiBJbnN0YWxscyBhIGdpdmVuIGxhbmd1YWdlIGZvciBhIHBsdWdpbi4KCSAqCgkgKiBEb3dubG9hZHMgdGhlIGxhbmd1YWdlIHBhY2sgZnJvbSBXb3JkUHJlc3Mub3JnLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHBsdWdpbj5dCgkgKiA6IFBsdWdpbiB0byBpbnN0YWxsIGxhbmd1YWdlIGZvci4KCSAqCgkgKiBbLS1hbGxdCgkgKiA6IElmIHNldCwgbGFuZ3VhZ2VzIGZvciBhbGwgcGx1Z2lucyB3aWxsIGJlIGluc3RhbGxlZC4KCSAqCgkgKiA8bGFuZ3VhZ2U+Li4uCgkgKiA6IExhbmd1YWdlIGNvZGUgdG8gaW5zdGFsbC4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4gVXNlZCB3aGVuIGluc3RhbGxpbmcgbGFuZ3VhZ2VzIGZvciBhbGwgcGx1Z2lucy4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gc3VtbWFyeQoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbnN0YWxsIHRoZSBKYXBhbmVzZSBsYW5ndWFnZSBmb3IgQWtpc21ldC4KCSAqICAgICAkIHdwIGxhbmd1YWdlIHBsdWdpbiBpbnN0YWxsIGFraXNtZXQgamEKCSAqICAgICBEb3dubG9hZGluZyB0cmFuc2xhdGlvbiBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdHJhbnNsYXRpb24vcGx1Z2luL2FraXNtZXQvNC4wLjMvamEuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFRyYW5zbGF0aW9uIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIExhbmd1YWdlICdqYScgaW5zdGFsbGVkLgoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgbGFuZ3VhZ2VzLgoJICoKCSAqIEBzdWJjb21tYW5kIGluc3RhbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQlpZiAoICEgJGFsbCAmJiBjb3VudCggJGFyZ3MgKSA8IDIgKSB7CgkJCVxXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgYSBwbHVnaW4sIG9yIHVzZSAtLWFsbC4nICk7CgkJfQoKCQlpZiAoICRhbGwgKSB7CgkJCSR0aGlzLT5pbnN0YWxsX21hbnkoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJCX0gZWxzZSB7CgkJCSR0aGlzLT5pbnN0YWxsX29uZSggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJfQoJfQoKCS8qKgoJICogSW5zdGFsbHMgdHJhbnNsYXRpb25zIGZvciBhIHBsdWdpbi4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgUnVudGltZSBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUnVudGltZSBhcmd1bWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaW5zdGFsbF9vbmUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGx1Z2luICAgICAgICAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkbGFuZ3VhZ2VfY29kZXMgPSAoYXJyYXkpICRhcmdzOwoJCSRjb3VudCAgICAgICAgICA9IGNvdW50KCAkbGFuZ3VhZ2VfY29kZXMgKTsKCgkJJGF2YWlsYWJsZSA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcyggJHBsdWdpbiApOwoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkc2tpcHMgICAgID0gMDsKCQlmb3JlYWNoICggJGxhbmd1YWdlX2NvZGVzIGFzICRsYW5ndWFnZV9jb2RlICkgewoKCQkJaWYgKCBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBhbHJlYWR5IGluc3RhbGxlZC4iICk7CgkJCQkkc2tpcHMrKzsKCQkJfSBlbHNlIHsKCQkJCSRyZXNwb25zZSA9ICR0aGlzLT5kb3dubG9hZF9sYW5ndWFnZV9wYWNrKCAkbGFuZ3VhZ2VfY29kZSwgJHBsdWdpbiApOwoKCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQkJCVxXUF9DTEk6Ondhcm5pbmcoICRyZXNwb25zZSApOwoJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBub3QgaW5zdGFsbGVkLiIgKTsKCgkJCQkJLy8gU2tpcCBpZiB0cmFuc2xhdGlvbiBpcyBub3QgeWV0IGF2YWlsYWJsZS4KCQkJCQlpZiAoICdub3RfZm91bmQnID09PSAkcmVzcG9uc2UtPmdldF9lcnJvcl9jb2RlKCkgKSB7CgkJCQkJCSRza2lwcysrOwoJCQkJCX0gZWxzZSB7CgkJCQkJCSRlcnJvcnMrKzsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBpbnN0YWxsZWQuIiApOwoJCQkJCSRzdWNjZXNzZXMrKzsKCQkJCX0KCQkJfQoJCX0KCgkJXFdQX0NMSVxVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICdsYW5ndWFnZScsICdpbnN0YWxsJywgJGNvdW50LCAkc3VjY2Vzc2VzLCAkZXJyb3JzLCAkc2tpcHMgKTsKCX0KCgkvKioKCSAqIEluc3RhbGxzIHRyYW5zbGF0aW9ucyBmb3IgYWxsIGluc3RhbGxlZCBwbHVnaW5zLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkYXJncyAgICAgICBSdW50aW1lIGFyZ3VtZW50cy4KCSAqIEBwYXJhbSBhcnJheSAkYXNzb2NfYXJncyBSdW50aW1lIGFyZ3VtZW50cy4KCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBpbnN0YWxsX21hbnkoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkbGFuZ3VhZ2VfY29kZXMgPSAoYXJyYXkpICRhcmdzOwoJCSRwbHVnaW5zICAgICAgICA9ICR0aGlzLT5nZXRfYWxsX3BsdWdpbnMoKTsKCgkJaWYgKCBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgKSB7CgkJCSRhc3NvY19hcmdzWydmb3JtYXQnXSA9ICd0YWJsZSc7CgkJfQoKCQlpZiAoIGluX2FycmF5KCAkYXNzb2NfYXJnc1snZm9ybWF0J10sIGFycmF5KCAnanNvbicsICdjc3YnICksIHRydWUgKSApIHsKCQkJJGxvZ2dlciA9IG5ldyBcV1BfQ0xJXExvZ2dlcnNcUXVpZXQoKTsKCQkJXFdQX0NMSTo6c2V0X2xvZ2dlciggJGxvZ2dlciApOwoJCX0KCgkJaWYgKCBlbXB0eSggJHBsdWdpbnMgKSApIHsKCQkJXFdQX0NMSTo6c3VjY2VzcyggJ05vIHBsdWdpbnMgaW5zdGFsbGVkLicgKTsKCQkJcmV0dXJuOwoJCX0KCgkJJGNvdW50ID0gY291bnQoICRwbHVnaW5zICkgKiBjb3VudCggJGxhbmd1YWdlX2NvZGVzICk7CgoJCSRyZXN1bHRzID0gYXJyYXkoKTsKCgkJJHN1Y2Nlc3NlcyA9IDA7CgkJJGVycm9ycyAgICA9IDA7CgkJJHNraXBzICAgICA9IDA7CgkJZm9yZWFjaCAoICRwbHVnaW5zIGFzICRwbHVnaW5fcGF0aCA9PiAkcGx1Z2luX2RldGFpbHMgKSB7CgkJCSRwbHVnaW5fbmFtZSA9IFxXUF9DTElcVXRpbHNcZ2V0X3BsdWdpbl9uYW1lKCAkcGx1Z2luX3BhdGggKTsKCgkJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoICRwbHVnaW5fbmFtZSApOwoKCQkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJCSRyZXN1bHQgPSBbCgkJCQkJJ25hbWUnICAgPT4gJHBsdWdpbl9uYW1lLAoJCQkJCSdsb2NhbGUnID0+ICRsYW5ndWFnZV9jb2RlLAoJCQkJXTsKCgkJCQlpZiAoIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBmb3IgJ3skcGx1Z2luX2RldGFpbHNbJ05hbWUnXX0nIGFscmVhZHkgaW5zdGFsbGVkLiIgKTsKCQkJCQkkcmVzdWx0WydzdGF0dXMnXSA9ICdhbHJlYWR5IGluc3RhbGxlZCc7CgkJCQkJJHNraXBzKys7CgkJCQl9IGVsc2UgewoJCQkJCSRyZXNwb25zZSA9ICR0aGlzLT5kb3dubG9hZF9sYW5ndWFnZV9wYWNrKCAkbGFuZ3VhZ2VfY29kZSwgJHBsdWdpbl9uYW1lICk7CgoJCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQkJCQlcV1BfQ0xJOjp3YXJuaW5nKCAkcmVzcG9uc2UgKTsKCQkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGZvciAneyRwbHVnaW5fZGV0YWlsc1snTmFtZSddfScgbm90IGluc3RhbGxlZC4iICk7CgoJCQkJCQlpZiAoICdub3RfZm91bmQnID09PSAkcmVzcG9uc2UtPmdldF9lcnJvcl9jb2RlKCkgKSB7CgkJCQkJCQkkcmVzdWx0WydzdGF0dXMnXSA9ICdub3QgYXZhaWxhYmxlJzsKCQkJCQkJCSRza2lwcysrOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnbm90IGluc3RhbGxlZCc7CgkJCQkJCQkkZXJyb3JzKys7CgkJCQkJCX0KCQkJCQl9IGVsc2UgewoJCQkJCQlcV1BfQ0xJOjpsb2coICJMYW5ndWFnZSAneyRsYW5ndWFnZV9jb2RlfScgZm9yICd7JHBsdWdpbl9kZXRhaWxzWydOYW1lJ119JyBpbnN0YWxsZWQuIiApOwoJCQkJCQkkcmVzdWx0WydzdGF0dXMnXSA9ICdpbnN0YWxsZWQnOwoJCQkJCQkkc3VjY2Vzc2VzKys7CgkJCQkJfQoJCQkJfQoKCQkJCSRyZXN1bHRzW10gPSAob2JqZWN0KSAkcmVzdWx0OwoJCQl9CgkJfQoKCQlpZiAoICdzdW1tYXJ5JyAhPT0gJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgewoJCQlcV1BfQ0xJXFV0aWxzXGZvcm1hdF9pdGVtcyggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCAkcmVzdWx0cywgYXJyYXkoICduYW1lJywgJ2xvY2FsZScsICdzdGF0dXMnICkgKTsKCQl9CgoJCVxXUF9DTElcVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnbGFuZ3VhZ2UnLCAnaW5zdGFsbCcsICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJHNraXBzICk7Cgl9CgoJLyoqCgkgKiBVbmluc3RhbGxzIGEgZ2l2ZW4gbGFuZ3VhZ2UgZm9yIGEgcGx1Z2luLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8cGx1Z2luPgoJICogOiBQbHVnaW4gdG8gdW5pbnN0YWxsIGxhbmd1YWdlIGZvci4KCSAqCgkgKiA8bGFuZ3VhZ2U+Li4uCgkgKiA6IExhbmd1YWdlIGNvZGUgdG8gdW5pbnN0YWxsLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbGFuZ3VhZ2UgcGx1Z2luIHVuaW5zdGFsbCBoZWxsby1kb2xseSBqYQoJICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIHVuaW5zdGFsbGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIHVuaW5zdGFsbAoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJLyoqIEB2YXIgV1BfRmlsZXN5c3RlbV9CYXNlICR3cF9maWxlc3lzdGVtICovCgkJZ2xvYmFsICR3cF9maWxlc3lzdGVtOwoKCQkkcGx1Z2luICAgICAgICAgPSBhcnJheV9zaGlmdCggJGFyZ3MgKTsKCQkkbGFuZ3VhZ2VfY29kZXMgPSAoYXJyYXkpICRhcmdzOwoJCSRjdXJyZW50X2xvY2FsZSA9IGdldF9sb2NhbGUoKTsKCgkJJGRpciAgID0gV1BfTEFOR19ESVIgLiAiLyR0aGlzLT5vYmpfdHlwZSI7CgkJJGZpbGVzID0gc2NhbmRpciggJGRpciApOwoKCQlpZiAoICEgJGZpbGVzICkgewoJCQlcV1BfQ0xJOjplcnJvciggJ05vIGZpbGVzIGZvdW5kIGluIGxhbmd1YWdlIGRpcmVjdG9yeS4nICk7CgkJfQoKCQkvLyBBcyBvZiBXUCA0LjAsIG5vIEFQSSBmb3IgZGVsZXRpbmcgYSBsYW5ndWFnZSBwYWNrCgkJV1BfRmlsZXN5c3RlbSgpOwoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoICRwbHVnaW4gKTsKCgkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJXFdQX0NMSTo6ZXJyb3IoICdMYW5ndWFnZSBub3QgaW5zdGFsbGVkLicgKTsKCQkJfQoKCQkJaWYgKCAkbGFuZ3VhZ2VfY29kZSA9PT0gJGN1cnJlbnRfbG9jYWxlICkgewoJCQkJXFdQX0NMSTo6d2FybmluZyggIlRoZSAneyRsYW5ndWFnZV9jb2RlfScgbGFuZ3VhZ2UgaXMgYWN0aXZlLiIgKTsKCQkJCWV4aXQ7CgkJCX0KCgkJCWlmICggJHdwX2ZpbGVzeXN0ZW0tPmRlbGV0ZSggInskZGlyfS97JHBsdWdpbn0teyRsYW5ndWFnZV9jb2RlfS5wbyIgKSAmJiAkd3BfZmlsZXN5c3RlbS0+ZGVsZXRlKCAieyRkaXJ9L3skcGx1Z2lufS17JGxhbmd1YWdlX2NvZGV9Lm1vIiApICkgewoJCQkJXFdQX0NMSTo6c3VjY2VzcyggJ0xhbmd1YWdlIHVuaW5zdGFsbGVkLicgKTsKCQkJfSBlbHNlIHsKCQkJCVxXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgdW5pbnN0YWxsIGxhbmd1YWdlLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgaW5zdGFsbGVkIGxhbmd1YWdlcyBmb3Igb25lIG9yIG1vcmUgcGx1Z2lucy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxwbHVnaW4+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBwbHVnaW5zIHRvIHVwZGF0ZSBsYW5ndWFnZXMgZm9yLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBsYW5ndWFnZXMgZm9yIGFsbCBwbHVnaW5zIHdpbGwgYmUgdXBkYXRlZC4KCSAqCgkgKiBbLS1kcnktcnVuXQoJICogOiBQcmV2aWV3IHdoaWNoIHRyYW5zbGF0aW9ucyB3b3VsZCBiZSB1cGRhdGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbGFuZ3VhZ2UgcGx1Z2luIHVwZGF0ZSAtLWFsbAoJICogICAgIFVwZGF0aW5nICdKYXBhbmVzZScgdHJhbnNsYXRpb24gZm9yIEFraXNtZXQgMy4xLjExLi4uCgkgKiAgICAgRG93bmxvYWRpbmcgdHJhbnNsYXRpb24gZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RyYW5zbGF0aW9uL3BsdWdpbi9ha2lzbWV0LzMuMS4xMS9qYS56aXAuLi4KCSAqICAgICBUcmFuc2xhdGlvbiB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4KCSAqICAgICBTdWNjZXNzOiBVcGRhdGVkIDEvMSB0cmFuc2xhdGlvbi4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCWlmICggISAkYWxsICYmIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgb25lIG9yIG1vcmUgcGx1Z2lucywgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCWlmICggJGFsbCApIHsKCQkJJGFyZ3MgPSBhcnJheV9tYXAoICdcV1BfQ0xJXFV0aWxzXGdldF9wbHVnaW5fbmFtZScsIGFycmF5X2tleXMoICR0aGlzLT5nZXRfYWxsX3BsdWdpbnMoKSApICk7CgkJCWlmICggZW1wdHkoICRhcmdzICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdObyBwbHVnaW5zIGluc3RhbGxlZC4nICk7CgoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQlwYXJlbnQ6OnVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBHZXRzIGFsbCBhdmFpbGFibGUgcGx1Z2lucy4KCSAqCgkgKiBVc2VzIHRoZSBzYW1lIGZpbHRlciBjb3JlIHVzZXMgaW4gcGx1Z2lucy5waHAgdG8gZGV0ZXJtaW5lIHdoaWNoIHBsdWdpbnMKCSAqIHNob3VsZCBiZSBhdmFpbGFibGUgdG8gbWFuYWdlIHRocm91Z2ggdGhlIFdQX1BsdWdpbnNfTGlzdF9UYWJsZSBjbGFzcy4KCSAqCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2FsbF9wbHVnaW5zKCkgewoJCS8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gVXNpbmcgV1AgbmF0aXZlIGhvb2suCgkJcmV0dXJuIGFwcGx5X2ZpbHRlcnMoICdhbGxfcGx1Z2lucycsIGdldF9wbHVnaW5zKCkgKTsKCX0KfQo8P3BocAoKY2xhc3MgU2l0ZV9Td2l0Y2hfTGFuZ3VhZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSVxDb21tYW5kV2l0aFRyYW5zbGF0aW9uIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAnY29yZSc7CgoJLyoqCgkgKiBBY3RpdmF0ZXMgYSBnaXZlbiBsYW5ndWFnZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGxhbmd1YWdlPgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIGFjdGl2YXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3Agc2l0ZSBzd2l0Y2gtbGFuZ3VhZ2UgamEKCSAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSBhY3RpdmF0ZWQuCgkgKgoJICogQHRocm93cyBXUF9DTElcRXhpdEV4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlsaXN0KCAkbGFuZ3VhZ2VfY29kZSApID0gJGFyZ3M7CgoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCgkJaWYgKCAhIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTGFuZ3VhZ2Ugbm90IGluc3RhbGxlZC4nICk7CgkJfQoKCQlpZiAoICdlbl9VUycgPT09ICRsYW5ndWFnZV9jb2RlICkgewoJCQkkbGFuZ3VhZ2VfY29kZSA9ICcnOwoJCX0KCgkJaWYgKCBnZXRfbG9jYWxlKCkgPT09ICRsYW5ndWFnZV9jb2RlICkgewoJCQlXUF9DTEk6Ondhcm5pbmcoICJMYW5ndWFnZSAneyRsYW5ndWFnZV9jb2RlfScgYWxyZWFkeSBhY3RpdmUuIiApOwoKCQkJcmV0dXJuOwoJCX0KCgkJdXBkYXRlX29wdGlvbiggJ1dQTEFORycsICRsYW5ndWFnZV9jb2RlICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ0xhbmd1YWdlIGFjdGl2YXRlZC4nICk7Cgl9Cn0KPD9waHAKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyB0aGVtZSBsYW5ndWFnZSBwYWNrcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgSW5zdGFsbCB0aGUgRHV0Y2ggdGhlbWUgbGFuZ3VhZ2UgcGFjay4KICogICAgICQgd3AgbGFuZ3VhZ2UgdGhlbWUgaW5zdGFsbCB0d2VudHl0ZW4gbmxfTkwKICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIGluc3RhbGxlZC4KICoKICogICAgICMgVW5pbnN0YWxsIHRoZSBEdXRjaCB0aGVtZSBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSB1bmluc3RhbGwgdHdlbnR5dGVuIG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSB1bmluc3RhbGxlZC4KICoKICogICAgICMgTGlzdCBpbnN0YWxsZWQgdGhlbWUgbGFuZ3VhZ2UgcGFja2FnZXMuCiAqICAgICAkIHdwIGxhbmd1YWdlIHRoZW1lIGxpc3QgLS1zdGF0dXM9aW5zdGFsbGVkCiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbGFuZ3VhZ2UgfCBlbmdsaXNoX25hbWUgfCBuYXRpdmVfbmFtZSB8IHN0YXR1cyAgICB8IHVwZGF0ZSAgICB8IHVwZGF0ZWQgICAgICAgICAgICAgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICB8IG5sX05MICAgIHwgRHV0Y2ggICAgICAgIHwgTmVkZXJsYW5kcyAgfCBpbnN0YWxsZWQgfCBhdmFpbGFibGUgfCAyMDE2LTA1LTEzIDA4OjEyOjUwIHwKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKi8KY2xhc3MgVGhlbWVfTGFuZ3VhZ2VfQ29tbWFuZCBleHRlbmRzIFdQX0NMSVxDb21tYW5kV2l0aFRyYW5zbGF0aW9uIHsKCXByb3RlY3RlZCAkb2JqX3R5cGUgPSAndGhlbWVzJzsKCglwcm90ZWN0ZWQgJG9ial9maWVsZHMgPSBhcnJheSgKCQkndGhlbWUnLAoJCSdsYW5ndWFnZScsCgkJJ2VuZ2xpc2hfbmFtZScsCgkJJ25hdGl2ZV9uYW1lJywKCQknc3RhdHVzJywKCQkndXBkYXRlJywKCQkndXBkYXRlZCcsCgkpOwoKCS8qKgoJICogTGlzdHMgYWxsIGF2YWlsYWJsZSBsYW5ndWFnZXMgZm9yIG9uZSBvciBtb3JlIHRoZW1lcy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT4uLi5dCgkgKiA6IE9uZSBvciBtb3JlIHRoZW1lcyB0byBsaXN0IGxhbmd1YWdlcyBmb3IuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGF2YWlsYWJsZSBsYW5ndWFnZXMgZm9yIGFsbCB0aGVtZXMgd2lsbCBiZSBsaXN0ZWQuCgkgKgoJICogWy0tZmllbGQ9PGZpZWxkPl0KCSAqIDogRGlzcGxheSB0aGUgdmFsdWUgb2YgYSBzaW5nbGUgZmllbGQuCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgcmVzdWx0cyBieSBrZXk9dmFsdWUgcGFpcnMuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggdHJhbnNsYXRpb246CgkgKgoJICogKiB0aGVtZQoJICogKiBsYW5ndWFnZQoJICogKiBlbmdsaXNoX25hbWUKCSAqICogbmF0aXZlX25hbWUKCSAqICogc3RhdHVzCgkgKiAqIHVwZGF0ZQoJICogKiB1cGRhdGVkCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGxhbmd1YWdlLGVuZ2xpc2hfbmFtZSxzdGF0dXMgZmllbGRzIG9mIGF2YWlsYWJsZSBsYW5ndWFnZXMuCgkgKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSBsaXN0IC0tZmllbGRzPWxhbmd1YWdlLGVuZ2xpc2hfbmFtZSxzdGF0dXMKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rCgkgKiAgICAgfCBsYW5ndWFnZSAgICAgICB8IGVuZ2xpc2hfbmFtZSAgICAgICAgICAgIHwgc3RhdHVzICAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGFyICAgICAgICAgICAgIHwgQXJhYmljICAgICAgICAgICAgICAgICAgfCB1bmluc3RhbGxlZCB8CgkgKiAgICAgfCBhcnkgICAgICAgICAgICB8IE1vcm9jY2FuIEFyYWJpYyAgICAgICAgIHwgdW5pbnN0YWxsZWQgfAoJICogICAgIHwgYXogICAgICAgICAgICAgfCBBemVyYmFpamFuaSAgICAgICAgICAgICB8IHVuaW5zdGFsbGVkIHwKCSAqCgkgKiBAc3ViY29tbWFuZCBsaXN0CgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBsaXN0XyggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRhbGwgPSBcV1BfQ0xJXFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCWlmICggISAkYWxsICYmIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgb25lIG9yIG1vcmUgdGhlbWVzLCBvciB1c2UgLS1hbGwuJyApOwoJCX0KCgkJaWYgKCAkYWxsICkgewoJCQkkYXJncyA9IGFycmF5X21hcCgKCQkJCWZ1bmN0aW9uKCAkZmlsZSApIHsKCQkJCQlyZXR1cm4gXFdQX0NMSVxVdGlsc1xnZXRfdGhlbWVfbmFtZSggJGZpbGUgKTsKCQkJCX0sCgkJCQlhcnJheV9rZXlzKCB3cF9nZXRfdGhlbWVzKCkgKQoJCQkpOwoKCQkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ05vIHRoZW1lcyBpbnN0YWxsZWQuJyApOwoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQkkdXBkYXRlcyAgICAgICAgPSAkdGhpcy0+Z2V0X3RyYW5zbGF0aW9uX3VwZGF0ZXMoKTsKCQkkY3VycmVudF9sb2NhbGUgPSBnZXRfbG9jYWxlKCk7CgoJCSR0cmFuc2xhdGlvbnMgPSBhcnJheSgpOwoKCQlmb3JlYWNoICggJGFyZ3MgYXMgJHRoZW1lICkgewoJCQkkaW5zdGFsbGVkX3RyYW5zbGF0aW9ucyA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcyggJHRoZW1lICk7CgkJCSRhdmFpbGFibGVfdHJhbnNsYXRpb25zID0gJHRoaXMtPmdldF9hbGxfbGFuZ3VhZ2VzKCAkdGhlbWUgKTsKCgkJCWZvcmVhY2ggKCAkYXZhaWxhYmxlX3RyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCQkkdHJhbnNsYXRpb25bJ3RoZW1lJ10gID0gJHRoZW1lOwoJCQkJJHRyYW5zbGF0aW9uWydzdGF0dXMnXSA9IGluX2FycmF5KCAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10sICRpbnN0YWxsZWRfdHJhbnNsYXRpb25zLCB0cnVlICkgPyAnaW5zdGFsbGVkJyA6ICd1bmluc3RhbGxlZCc7CgoJCQkJaWYgKCAkY3VycmVudF9sb2NhbGUgPT09ICR0cmFuc2xhdGlvblsnbGFuZ3VhZ2UnXSApIHsKCQkJCQkkdHJhbnNsYXRpb25bJ3N0YXR1cyddID0gJ2FjdGl2ZSc7CgkJCQl9CgoJCQkJJGZpbHRlcl9hcmdzID0gYXJyYXkoCgkJCQkJJ2xhbmd1YWdlJyA9PiAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10sCgkJCQkJJ3R5cGUnICAgICA9PiAndGhlbWUnLAoJCQkJCSdzbHVnJyAgICAgPT4gJHRoZW1lLAoJCQkJKTsKCQkJCSR1cGRhdGUgICAgICA9IHdwX2xpc3RfZmlsdGVyKCAkdXBkYXRlcywgJGZpbHRlcl9hcmdzICk7CgoJCQkJJHRyYW5zbGF0aW9uWyd1cGRhdGUnXSA9ICR1cGRhdGUgPyAnYXZhaWxhYmxlJyA6ICdub25lJzsKCgkJCQkvLyBTdXBwb3J0IGZlYXR1cmVzIGxpa2UgLS1zdGF0dXM9YWN0aXZlLgoJCQkJZm9yZWFjaCAoIGFycmF5X2tleXMoICR0cmFuc2xhdGlvbiApIGFzICRmaWVsZCApIHsKCQkJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gKSAmJiAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gIT09ICR0cmFuc2xhdGlvblsgJGZpZWxkIF0gKSB7CgkJCQkJCWNvbnRpbnVlIDI7CgkJCQkJfQoJCQkJfQoKCQkJCSR0cmFuc2xhdGlvbnNbXSA9ICR0cmFuc2xhdGlvbjsKCQkJfQoJCX0KCgkJJGZvcm1hdHRlciA9ICR0aGlzLT5nZXRfZm9ybWF0dGVyKCAkYXNzb2NfYXJncyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICR0cmFuc2xhdGlvbnMgKTsKCX0KCgkvKioKCSAqIENoZWNrcyBpZiBhIGdpdmVuIGxhbmd1YWdlIGlzIGluc3RhbGxlZC4KCSAqCgkgKiBSZXR1cm5zIGV4aXQgY29kZSAwIHdoZW4gaW5zdGFsbGVkLCAxIHdoZW4gdW5pbnN0YWxsZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx0aGVtZT4KCSAqIDogVGhlbWUgdG8gY2hlY2sgZm9yLgoJICoKCSAqIDxsYW5ndWFnZT4uLi4KCSAqIDogVGhlIGxhbmd1YWdlIGNvZGUgdG8gY2hlY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIHRoZSBHZXJtYW4gbGFuZ3VhZ2UgaXMgaW5zdGFsbGVkIGZvciBUd2VudHkgU2V2ZW50ZWVuOyBleGl0IHN0YXR1cyAwIGlmIGluc3RhbGxlZCwgb3RoZXJ3aXNlIDEuCgkgKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSBpcy1pbnN0YWxsZWQgdHdlbnR5c2V2ZW50ZWVuIGRlX0RFCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWluc3RhbGxlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfaW5zdGFsbGVkKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCSR0aGVtZSAgICAgICAgICA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoJCSRsYW5ndWFnZV9jb2RlcyA9IChhcnJheSkgJGFyZ3M7CgoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoICR0aGVtZSApOwoKCQlmb3JlYWNoICggJGxhbmd1YWdlX2NvZGVzIGFzICRsYW5ndWFnZV9jb2RlICkgewoJCQlpZiAoICEgaW5fYXJyYXkoICRsYW5ndWFnZV9jb2RlLCAkYXZhaWxhYmxlLCB0cnVlICkgKSB7CgkJCQlcV1BfQ0xJOjpoYWx0KCAxICk7CgkJCX0KCQl9CgoJCVxXUF9DTEk6OmhhbHQoIDAgKTsKCX0KCgkvKioKCSAqIEluc3RhbGxzIGEgZ2l2ZW4gbGFuZ3VhZ2UgZm9yIGEgdGhlbWUuCgkgKgoJICogRG93bmxvYWRzIHRoZSBsYW5ndWFnZSBwYWNrIGZyb20gV29yZFByZXNzLm9yZy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzx0aGVtZT5dCgkgKiA6IFRoZW1lIHRvIGluc3RhbGwgbGFuZ3VhZ2UgZm9yLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBsYW5ndWFnZXMgZm9yIGFsbCB0aGVtZXMgd2lsbCBiZSBpbnN0YWxsZWQuCgkgKgoJICogPGxhbmd1YWdlPi4uLgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIGluc3RhbGwuCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBSZW5kZXIgb3V0cHV0IGluIGEgcGFydGljdWxhciBmb3JtYXQuIFVzZWQgd2hlbiBpbnN0YWxsaW5nIGxhbmd1YWdlcyBmb3IgYWxsIHRoZW1lcy4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0gc3VtbWFyeQoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBJbnN0YWxsIHRoZSBKYXBhbmVzZSBsYW5ndWFnZSBmb3IgVHdlbnR5IFNldmVudGVlbi4KCSAqICAgICAkIHdwIGxhbmd1YWdlIHRoZW1lIGluc3RhbGwgdHdlbnR5c2V2ZW50ZWVuIGphCgkgKiAgICAgRG93bmxvYWRpbmcgdHJhbnNsYXRpb24gZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RyYW5zbGF0aW9uL3RoZW1lL3R3ZW50eXNldmVudGVlbi8xLjMvamEuemlwLi4uCgkgKiAgICAgVW5wYWNraW5nIHRoZSB1cGRhdGUuLi4KCSAqICAgICBJbnN0YWxsaW5nIHRoZSBsYXRlc3QgdmVyc2lvbi4uLgoJICogICAgIFRyYW5zbGF0aW9uIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LgoJICogICAgIExhbmd1YWdlICdqYScgaW5zdGFsbGVkLgoJICogICAgIFN1Y2Nlc3M6IEluc3RhbGxlZCAxIG9mIDEgbGFuZ3VhZ2VzLgoJICoKCSAqIEBzdWJjb21tYW5kIGluc3RhbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGluc3RhbGwoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQlpZiAoICEgJGFsbCAmJiBjb3VudCggJGFyZ3MgKSA8IDIgKSB7CgkJCVxXUF9DTEk6OmVycm9yKCAnUGxlYXNlIHNwZWNpZnkgYSB0aGVtZSwgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCWlmICggJGFsbCApIHsKCQkJJHRoaXMtPmluc3RhbGxfbWFueSggJGFyZ3MsICRhc3NvY19hcmdzICk7CgkJfSBlbHNlIHsKCQkJJHRoaXMtPmluc3RhbGxfb25lKCAkYXJncywgJGFzc29jX2FyZ3MgKTsKCQl9Cgl9CgoJLyoqCgkgKiBJbnN0YWxscyB0cmFuc2xhdGlvbnMgZm9yIGEgdGhlbWUuCgkgKgoJICogQHBhcmFtIGFycmF5ICRhcmdzICAgICAgIFJ1bnRpbWUgYXJndW1lbnRzLgoJICogQHBhcmFtIGFycmF5ICRhc3NvY19hcmdzIFJ1bnRpbWUgYXJndW1lbnRzLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIGluc3RhbGxfb25lKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRoZW1lICAgICAgICAgID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJGxhbmd1YWdlX2NvZGVzID0gKGFycmF5KSAkYXJnczsKCQkkY291bnQgICAgICAgICAgPSBjb3VudCggJGxhbmd1YWdlX2NvZGVzICk7CgoJCSRhdmFpbGFibGUgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoICR0aGVtZSApOwoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkc2tpcHMgICAgID0gMDsKCQlmb3JlYWNoICggJGxhbmd1YWdlX2NvZGVzIGFzICRsYW5ndWFnZV9jb2RlICkgewoKCQkJaWYgKCBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBhbHJlYWR5IGluc3RhbGxlZC4iICk7CgkJCQkkc2tpcHMrKzsKCQkJfSBlbHNlIHsKCQkJCSRyZXNwb25zZSA9ICR0aGlzLT5kb3dubG9hZF9sYW5ndWFnZV9wYWNrKCAkbGFuZ3VhZ2VfY29kZSwgJHRoZW1lICk7CgoJCQkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgKSB7CgkJCQkJXFdQX0NMSTo6d2FybmluZyggJHJlc3BvbnNlICk7CgkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIG5vdCBpbnN0YWxsZWQuIiApOwoKCQkJCQkvLyBTa2lwIGlmIHRyYW5zbGF0aW9uIGlzIG5vdCB5ZXQgYXZhaWxhYmxlLgoJCQkJCWlmICggJ25vdF9mb3VuZCcgPT09ICRyZXNwb25zZS0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCQkJCQkJJHNraXBzKys7CgkJCQkJfSBlbHNlIHsKCQkJCQkJJGVycm9ycysrOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGluc3RhbGxlZC4iICk7CgkJCQkJJHN1Y2Nlc3NlcysrOwoJCQkJfQoJCQl9CgkJfQoKCQlcV1BfQ0xJXFV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ2xhbmd1YWdlJywgJ2luc3RhbGwnLCAkY291bnQsICRzdWNjZXNzZXMsICRlcnJvcnMsICRza2lwcyApOwoJfQoKCS8qKgoJICogSW5zdGFsbHMgdHJhbnNsYXRpb25zIGZvciBhbGwgaW5zdGFsbGVkIHRoZW1lcy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFyZ3MgICAgICAgUnVudGltZSBhcmd1bWVudHMuCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUnVudGltZSBhcmd1bWVudHMuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gaW5zdGFsbF9tYW55KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJGxhbmd1YWdlX2NvZGVzID0gKGFycmF5KSAkYXJnczsKCQkkdGhlbWVzICAgICAgICAgPSB3cF9nZXRfdGhlbWVzKCk7CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICkgewoJCQkkYXNzb2NfYXJnc1snZm9ybWF0J10gPSAndGFibGUnOwoJCX0KCgkJaWYgKCBpbl9hcnJheSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddLCBhcnJheSggJ2pzb24nLCAnY3N2JyApLCB0cnVlICkgKSB7CgkJCSRsb2dnZXIgPSBuZXcgXFdQX0NMSVxMb2dnZXJzXFF1aWV0KCk7CgkJCVxXUF9DTEk6OnNldF9sb2dnZXIoICRsb2dnZXIgKTsKCQl9CgoJCWlmICggZW1wdHkoICR0aGVtZXMgKSApIHsKCQkJXFdQX0NMSTo6c3VjY2VzcyggJ05vIHRoZW1lcyBpbnN0YWxsZWQuJyApOwoJCQlyZXR1cm47CgkJfQoKCQkkY291bnQgPSBjb3VudCggJHRoZW1lcyApICogY291bnQoICRsYW5ndWFnZV9jb2RlcyApOwoKCQkkcmVzdWx0cyA9IGFycmF5KCk7CgoJCSRzdWNjZXNzZXMgPSAwOwoJCSRlcnJvcnMgICAgPSAwOwoJCSRza2lwcyAgICAgPSAwOwoJCWZvcmVhY2ggKCAkdGhlbWVzIGFzICR0aGVtZV9wYXRoID0+ICR0aGVtZV9kZXRhaWxzICkgewoJCQkkdGhlbWVfbmFtZSA9IFxXUF9DTElcVXRpbHNcZ2V0X3RoZW1lX25hbWUoICR0aGVtZV9wYXRoICk7CgoJCQkkYXZhaWxhYmxlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCAkdGhlbWVfbmFtZSApOwoKCQkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJCSRyZXN1bHQgPSBbCgkJCQkJJ25hbWUnICAgPT4gJHRoZW1lX25hbWUsCgkJCQkJJ2xvY2FsZScgPT4gJGxhbmd1YWdlX2NvZGUsCgkJCQldOwoKCQkJCWlmICggaW5fYXJyYXkoICRsYW5ndWFnZV9jb2RlLCAkYXZhaWxhYmxlLCB0cnVlICkgKSB7CgkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGZvciAneyR0aGVtZV9kZXRhaWxzWydOYW1lJ119JyBhbHJlYWR5IGluc3RhbGxlZC4iICk7CgkJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnYWxyZWFkeSBpbnN0YWxsZWQnOwoJCQkJCSRza2lwcysrOwoJCQkJfSBlbHNlIHsKCQkJCQkkcmVzcG9uc2UgPSAkdGhpcy0+ZG93bmxvYWRfbGFuZ3VhZ2VfcGFjayggJGxhbmd1YWdlX2NvZGUsICR0aGVtZV9uYW1lICk7CgoJCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQkJCQlcV1BfQ0xJOjp3YXJuaW5nKCAkcmVzcG9uc2UgKTsKCQkJCQkJXFdQX0NMSTo6bG9nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGZvciAneyR0aGVtZV9kZXRhaWxzWydOYW1lJ119JyBub3QgaW5zdGFsbGVkLiIgKTsKCgkJCQkJCWlmICggJ25vdF9mb3VuZCcgPT09ICRyZXNwb25zZS0+Z2V0X2Vycm9yX2NvZGUoKSApIHsKCQkJCQkJCSRyZXN1bHRbJ3N0YXR1cyddID0gJ25vdCBhdmFpbGFibGUnOwoJCQkJCQkJJHNraXBzKys7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQkkcmVzdWx0WydzdGF0dXMnXSA9ICdub3QgaW5zdGFsbGVkJzsKCQkJCQkJCSRlcnJvcnMrKzsKCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBmb3IgJ3skdGhlbWVfZGV0YWlsc1snTmFtZSddfScgaW5zdGFsbGVkLiIgKTsKCQkJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnaW5zdGFsbGVkJzsKCQkJCQkJJHN1Y2Nlc3NlcysrOwoJCQkJCX0KCQkJCX0KCgkJCQkkcmVzdWx0c1tdID0gKG9iamVjdCkgJHJlc3VsdDsKCQkJfQoJCX0KCgkJaWYgKCAnc3VtbWFyeScgIT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJXFdQX0NMSVxVdGlsc1xmb3JtYXRfaXRlbXMoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgJHJlc3VsdHMsIGFycmF5KCAnbmFtZScsICdsb2NhbGUnLCAnc3RhdHVzJyApICk7CgkJfQoKCQlcV1BfQ0xJXFV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ2xhbmd1YWdlJywgJ2luc3RhbGwnLCAkY291bnQsICRzdWNjZXNzZXMsICRlcnJvcnMsICRza2lwcyApOwoJfQoKCS8qKgoJICogVW5pbnN0YWxscyBhIGdpdmVuIGxhbmd1YWdlIGZvciBhIHRoZW1lLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8dGhlbWU+CgkgKiA6IFRoZW1lIHRvIHVuaW5zdGFsbCBsYW5ndWFnZSBmb3IuCgkgKgoJICogPGxhbmd1YWdlPi4uLgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIHVuaW5zdGFsbC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGxhbmd1YWdlIHRoZW1lIHVuaW5zdGFsbCB0d2VudHl0ZW4gamEKCSAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSB1bmluc3RhbGxlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCB1bmluc3RhbGwKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVuaW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCS8qKiBAdmFyIFdQX0ZpbGVzeXN0ZW1fQmFzZSAkd3BfZmlsZXN5c3RlbSAqLwoJCWdsb2JhbCAkd3BfZmlsZXN5c3RlbTsKCgkJJHRoZW1lICAgICAgICAgID0gYXJyYXlfc2hpZnQoICRhcmdzICk7CgkJJGxhbmd1YWdlX2NvZGVzID0gKGFycmF5KSAkYXJnczsKCQkkY3VycmVudF9sb2NhbGUgPSBnZXRfbG9jYWxlKCk7CgoJCSRkaXIgICA9IFdQX0xBTkdfRElSIC4gIi8kdGhpcy0+b2JqX3R5cGUiOwoJCSRmaWxlcyA9IHNjYW5kaXIoICRkaXIgKTsKCgkJaWYgKCAhICRmaWxlcyApIHsKCQkJXFdQX0NMSTo6ZXJyb3IoICdObyBmaWxlcyBmb3VuZCBpbiBsYW5ndWFnZSBkaXJlY3RvcnkuJyApOwoJCX0KCgkJLy8gQXMgb2YgV1AgNC4wLCBubyBBUEkgZm9yIGRlbGV0aW5nIGEgbGFuZ3VhZ2UgcGFjawoJCVdQX0ZpbGVzeXN0ZW0oKTsKCQkkYXZhaWxhYmxlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCAkdGhlbWUgKTsKCgkJZm9yZWFjaCAoICRsYW5ndWFnZV9jb2RlcyBhcyAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJaWYgKCAhIGluX2FycmF5KCAkbGFuZ3VhZ2VfY29kZSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ0xhbmd1YWdlIG5vdCBpbnN0YWxsZWQuJyApOwoJCQl9CgoJCQlpZiAoICRsYW5ndWFnZV9jb2RlID09PSAkY3VycmVudF9sb2NhbGUgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJUaGUgJ3skbGFuZ3VhZ2VfY29kZX0nIGxhbmd1YWdlIGlzIGFjdGl2ZS4iICk7CgkJCQlleGl0OwoJCQl9CgoJCQlpZiAoICR3cF9maWxlc3lzdGVtLT5kZWxldGUoICJ7JGRpcn0veyR0aGVtZX0teyRsYW5ndWFnZV9jb2RlfS5wbyIgKSAmJiAkd3BfZmlsZXN5c3RlbS0+ZGVsZXRlKCAieyRkaXJ9L3skdGhlbWV9LXskbGFuZ3VhZ2VfY29kZX0ubW8iICkgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdMYW5ndWFnZSB1bmluc3RhbGxlZC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgdW5pbnN0YWxsIGxhbmd1YWdlLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgaW5zdGFsbGVkIGxhbmd1YWdlcyBmb3Igb25lIG9yIG1vcmUgdGhlbWVzLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiBbPHRoZW1lPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgdGhlbWVzIHRvIHVwZGF0ZSBsYW5ndWFnZXMgZm9yLgoJICoKCSAqIFstLWFsbF0KCSAqIDogSWYgc2V0LCBsYW5ndWFnZXMgZm9yIGFsbCB0aGVtZXMgd2lsbCBiZSB1cGRhdGVkLgoJICoKCSAqIFstLWRyeS1ydW5dCgkgKiA6IFByZXZpZXcgd2hpY2ggdHJhbnNsYXRpb25zIHdvdWxkIGJlIHVwZGF0ZWQuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSB1cGRhdGUgLS1hbGwKCSAqICAgICBVcGRhdGluZyAnSmFwYW5lc2UnIHRyYW5zbGF0aW9uIGZvciBUd2VudHkgRmlmdGVlbiAxLjUuLi4KCSAqICAgICBEb3dubG9hZGluZyB0cmFuc2xhdGlvbiBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdHJhbnNsYXRpb24vdGhlbWUvdHdlbnR5ZmlmdGVlbi8xLjUvamEuemlwLi4uCgkgKiAgICAgVHJhbnNsYXRpb24gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAxLzEgdHJhbnNsYXRpb24uCgkgKgoJICogQHN1YmNvbW1hbmQgdXBkYXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkYWxsID0gXFdQX0NMSVxVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdhbGwnLCBmYWxzZSApOwoKCQlpZiAoICEgJGFsbCAmJiBlbXB0eSggJGFyZ3MgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IG9uZSBvciBtb3JlIHRoZW1lcywgb3IgdXNlIC0tYWxsLicgKTsKCQl9CgoJCWlmICggJGFsbCApIHsKCQkJJGFyZ3MgPSBhcnJheV9tYXAoICdcV1BfQ0xJXFV0aWxzXGdldF90aGVtZV9uYW1lJywgYXJyYXlfa2V5cyggd3BfZ2V0X3RoZW1lcygpICkgKTsKCQkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJCVdQX0NMSTo6c3VjY2VzcyggJ05vIHRoZW1lcyBpbnN0YWxsZWQuJyApOwoKCQkJCXJldHVybjsKCQkJfQoJCX0KCgkJcGFyZW50Ojp1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApOwoJfQp9Cjw/cGhwCgp1c2UgV1BfQ0xJXERpc3BhdGNoZXJcQ29tbWFuZE5hbWVzcGFjZTsKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyBsYW5ndWFnZSBwYWNrcy4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgSW5zdGFsbCB0aGUgRHV0Y2ggY29yZSBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGluc3RhbGwgbmxfTkwKICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIGluc3RhbGxlZC4KICoKICogICAgICMgQWN0aXZhdGUgdGhlIER1dGNoIGNvcmUgbGFuZ3VhZ2UgcGFjay4KICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBhY3RpdmF0ZSBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgYWN0aXZhdGVkLgogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBEdXRjaCBsYW5ndWFnZSBwYWNrIGZvciBUd2VudHkgU2V2ZW50ZWVuLgogKiAgICAgJCB3cCBsYW5ndWFnZSB0aGVtZSBpbnN0YWxsIHR3ZW50eXNldmVudGVlbiBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgaW5zdGFsbGVkLgogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBEdXRjaCBsYW5ndWFnZSBwYWNrIGZvciBBa2lzbWV0LgogKiAgICAgJCB3cCBsYW5ndWFnZSBwbHVnaW4gaW5zdGFsbCBha2lzbWV0IG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSBpbnN0YWxsZWQuCiAqLwpjbGFzcyBMYW5ndWFnZV9OYW1lc3BhY2UgZXh0ZW5kcyBDb21tYW5kTmFtZXNwYWNlIHsKCn0KPD9waHAKCi8qKgogKiBJbnN0YWxscywgYWN0aXZhdGVzLCBhbmQgbWFuYWdlcyBjb3JlIGxhbmd1YWdlIHBhY2tzLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBJbnN0YWxsIHRoZSBEdXRjaCBjb3JlIGxhbmd1YWdlIHBhY2suCiAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgaW5zdGFsbCBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgaW5zdGFsbGVkLgogKgogKiAgICAgIyBBY3RpdmF0ZSB0aGUgRHV0Y2ggY29yZSBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGFjdGl2YXRlIG5sX05MCiAqICAgICBTdWNjZXNzOiBMYW5ndWFnZSBhY3RpdmF0ZWQuCiAqCiAqICAgICAjIFVuaW5zdGFsbCB0aGUgRHV0Y2ggY29yZSBsYW5ndWFnZSBwYWNrLgogKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIHVuaW5zdGFsbCBubF9OTAogKiAgICAgU3VjY2VzczogTGFuZ3VhZ2UgdW5pbnN0YWxsZWQuCiAqCiAqICAgICAjIExpc3QgaW5zdGFsbGVkIGNvcmUgbGFuZ3VhZ2UgcGFja2FnZXMuCiAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgbGlzdCAtLXN0YXR1cz1pbnN0YWxsZWQKICogICAgICstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBsYW5ndWFnZSB8IGVuZ2xpc2hfbmFtZSB8IG5hdGl2ZV9uYW1lIHwgc3RhdHVzICAgIHwgdXBkYXRlICAgIHwgdXBkYXRlZCAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmxfTkwgICAgfCBEdXRjaCAgICAgICAgfCBOZWRlcmxhbmRzICB8IGluc3RhbGxlZCB8IGF2YWlsYWJsZSB8IDIwMTYtMDUtMTMgMDg6MTI6NTAgfAogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqLwpjbGFzcyBDb3JlX0xhbmd1YWdlX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElcQ29tbWFuZFdpdGhUcmFuc2xhdGlvbiB7Cglwcm90ZWN0ZWQgJG9ial90eXBlID0gJ2NvcmUnOwoKCXByb3RlY3RlZCAkb2JqX2ZpZWxkcyA9IGFycmF5KAoJCSdsYW5ndWFnZScsCgkJJ2VuZ2xpc2hfbmFtZScsCgkJJ25hdGl2ZV9uYW1lJywKCQknc3RhdHVzJywKCQkndXBkYXRlJywKCQkndXBkYXRlZCcsCgkpOwoKCS8qKgoJICogTGlzdHMgYWxsIGF2YWlsYWJsZSBsYW5ndWFnZXMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkPTxmaWVsZD5dCgkgKiA6IERpc3BsYXkgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGZpZWxkCgkgKgoJICogWy0tPGZpZWxkPj08dmFsdWU+XQoJICogOiBGaWx0ZXIgcmVzdWx0cyBieSBrZXk9dmFsdWUgcGFpcnMuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggdHJhbnNsYXRpb246CgkgKgoJICogKiBsYW5ndWFnZQoJICogKiBlbmdsaXNoX25hbWUKCSAqICogbmF0aXZlX25hbWUKCSAqICogc3RhdHVzCgkgKiAqIHVwZGF0ZQoJICogKiB1cGRhdGVkCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBMaXN0IGxhbmd1YWdlLGVuZ2xpc2hfbmFtZSxzdGF0dXMgZmllbGRzIG9mIGF2YWlsYWJsZSBsYW5ndWFnZXMuCgkgKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGxpc3QgLS1maWVsZHM9bGFuZ3VhZ2UsZW5nbGlzaF9uYW1lLHN0YXR1cwoJICogICAgICstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSsKCSAqICAgICB8IGxhbmd1YWdlICAgICAgIHwgZW5nbGlzaF9uYW1lICAgICAgICAgICAgfCBzdGF0dXMgICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tKwoJICogICAgIHwgYXIgICAgICAgICAgICAgfCBBcmFiaWMgICAgICAgICAgICAgICAgICB8IHVuaW5zdGFsbGVkIHwKCSAqICAgICB8IGFyeSAgICAgICAgICAgIHwgTW9yb2NjYW4gQXJhYmljICAgICAgICAgfCB1bmluc3RhbGxlZCB8CgkgKiAgICAgfCBheiAgICAgICAgICAgICB8IEF6ZXJiYWlqYW5pICAgICAgICAgICAgIHwgdW5pbnN0YWxsZWQgfAoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHRyYW5zbGF0aW9ucyA9ICR0aGlzLT5nZXRfYWxsX2xhbmd1YWdlcygpOwoJCSRhdmFpbGFibGUgICAgPSAkdGhpcy0+Z2V0X2luc3RhbGxlZF9sYW5ndWFnZXMoKTsKCQkkdXBkYXRlcyAgICAgID0gJHRoaXMtPmdldF90cmFuc2xhdGlvbl91cGRhdGVzKCk7CgoJCSRjdXJyZW50X2xvY2FsZSA9IGdldF9sb2NhbGUoKTsKCgkJJHRyYW5zbGF0aW9ucyA9IGFycmF5X21hcCgKCQkJZnVuY3Rpb24oICR0cmFuc2xhdGlvbiApIHVzZSAoICRhdmFpbGFibGUsICRjdXJyZW50X2xvY2FsZSwgJHVwZGF0ZXMgKSB7CgkJCQkkdHJhbnNsYXRpb25bJ3N0YXR1cyddID0gJ3VuaW5zdGFsbGVkJzsKCQkJCWlmICggaW5fYXJyYXkoICR0cmFuc2xhdGlvblsnbGFuZ3VhZ2UnXSwgJGF2YWlsYWJsZSwgdHJ1ZSApICkgewoJCQkJCSR0cmFuc2xhdGlvblsnc3RhdHVzJ10gPSAnaW5zdGFsbGVkJzsKCQkJCX0KCgkJCQlpZiAoICRjdXJyZW50X2xvY2FsZSA9PT0gJHRyYW5zbGF0aW9uWydsYW5ndWFnZSddICkgewoJCQkJCSR0cmFuc2xhdGlvblsnc3RhdHVzJ10gPSAnYWN0aXZlJzsKCQkJCX0KCgkJCQkkdXBkYXRlID0gd3BfbGlzdF9maWx0ZXIoICR1cGRhdGVzLCBhcnJheSggJ2xhbmd1YWdlJyA9PiAkdHJhbnNsYXRpb25bJ2xhbmd1YWdlJ10gKSApOwoJCQkJaWYgKCAkdXBkYXRlICkgewoJCQkJCSR0cmFuc2xhdGlvblsndXBkYXRlJ10gPSAnYXZhaWxhYmxlJzsKCQkJCX0gZWxzZSB7CgkJCQkJJHRyYW5zbGF0aW9uWyd1cGRhdGUnXSA9ICdub25lJzsKCQkJCX0KCgkJCQlyZXR1cm4gJHRyYW5zbGF0aW9uOwoJCQl9LAoJCQkkdHJhbnNsYXRpb25zCgkJKTsKCgkJZm9yZWFjaCAoICR0cmFuc2xhdGlvbnMgYXMgJGtleSA9PiAkdHJhbnNsYXRpb24gKSB7CgkJCWZvcmVhY2ggKCBhcnJheV9rZXlzKCAkdHJhbnNsYXRpb24gKSBhcyAkZmllbGQgKSB7CgkJCQlpZiAoIGlzc2V0KCAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gKSAmJiAkYXNzb2NfYXJnc1sgJGZpZWxkIF0gIT09ICR0cmFuc2xhdGlvblsgJGZpZWxkIF0gKSB7CgkJCQkJdW5zZXQoICR0cmFuc2xhdGlvbnNbICRrZXkgXSApOwoJCQkJfQoJCQl9CgkJfQoKCQkkZm9ybWF0dGVyID0gJHRoaXMtPmdldF9mb3JtYXR0ZXIoICRhc3NvY19hcmdzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJHRyYW5zbGF0aW9ucyApOwoJfQoKCS8qKgoJICogQ2hlY2tzIGlmIGEgZ2l2ZW4gbGFuZ3VhZ2UgaXMgaW5zdGFsbGVkLgoJICoKCSAqIFJldHVybnMgZXhpdCBjb2RlIDAgd2hlbiBpbnN0YWxsZWQsIDEgd2hlbiB1bmluc3RhbGxlZC4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGxhbmd1YWdlPgoJICogOiBUaGUgbGFuZ3VhZ2UgY29kZSB0byBjaGVjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoZWNrIHdoZXRoZXIgdGhlIEdlcm1hbiBsYW5ndWFnZSBpcyBpbnN0YWxsZWQ7IGV4aXQgc3RhdHVzIDAgaWYgaW5zdGFsbGVkLCBvdGhlcndpc2UgMS4KCSAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgaXMtaW5zdGFsbGVkIGRlX0RFCgkgKiAgICAgJCBlY2hvICQ/CgkgKiAgICAgMQoJICoKCSAqIEBzdWJjb21tYW5kIGlzLWluc3RhbGxlZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaXNfaW5zdGFsbGVkKCAkYXJncywgJGFzc29jX2FyZ3MgPSBhcnJheSgpICkgewoJCWxpc3QoICRsYW5ndWFnZV9jb2RlICkgPSAkYXJnczsKCQkkYXZhaWxhYmxlICAgICAgICAgICAgID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCk7CgkJaWYgKCBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJXFdQX0NMSTo6aGFsdCggMCApOwoJCX0gZWxzZSB7CgkJCVxXUF9DTEk6OmhhbHQoIDEgKTsKCQl9Cgl9CgoJLyoqCgkgKiBJbnN0YWxscyBhIGdpdmVuIGxhbmd1YWdlLgoJICoKCSAqIERvd25sb2FkcyB0aGUgbGFuZ3VhZ2UgcGFjayBmcm9tIFdvcmRQcmVzcy5vcmcuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxsYW5ndWFnZT4uLi4KCSAqIDogTGFuZ3VhZ2UgY29kZSB0byBpbnN0YWxsLgoJICoKCSAqIFstLWFjdGl2YXRlXQoJICogOiBJZiBzZXQsIHRoZSBsYW5ndWFnZSB3aWxsIGJlIGFjdGl2YXRlZCBpbW1lZGlhdGVseSBhZnRlciBpbnN0YWxsLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgSW5zdGFsbCB0aGUgSmFwYW5lc2UgbGFuZ3VhZ2UuCgkgKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIGluc3RhbGwgamEKCSAqICAgICBEb3dubG9hZGluZyB0cmFuc2xhdGlvbiBmcm9tIGh0dHBzOi8vZG93bmxvYWRzLndvcmRwcmVzcy5vcmcvdHJhbnNsYXRpb24vY29yZS80LjkuOC9qYS56aXAuLi4KCSAqICAgICBVbnBhY2tpbmcgdGhlIHVwZGF0ZS4uLgoJICogICAgIEluc3RhbGxpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uLi4uCgkgKiAgICAgVHJhbnNsYXRpb24gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgTGFuZ3VhZ2UgJ2phJyBpbnN0YWxsZWQuCgkgKiAgICAgU3VjY2VzczogSW5zdGFsbGVkIDEgb2YgMSBsYW5ndWFnZXMuCgkgKgoJICogQHN1YmNvbW1hbmQgaW5zdGFsbAoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5zdGFsbCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoJCSRsYW5ndWFnZV9jb2RlcyA9IChhcnJheSkgJGFyZ3M7CgkJJGNvdW50ICAgICAgICAgID0gY291bnQoICRsYW5ndWFnZV9jb2RlcyApOwoKCQlpZiAoICRjb3VudCA+IDEgJiYgaW5fYXJyYXkoIHRydWUsICRhc3NvY19hcmdzLCB0cnVlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdPbmx5IGEgc2luZ2xlIGxhbmd1YWdlIGNhbiBiZSBhY3RpdmUuJyApOwoJCX0KCgkJJGF2YWlsYWJsZSA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcygpOwoKCQkkc3VjY2Vzc2VzID0gMDsKCQkkZXJyb3JzICAgID0gMDsKCQkkc2tpcHMgICAgID0gMDsKCQlmb3JlYWNoICggJGxhbmd1YWdlX2NvZGVzIGFzICRsYW5ndWFnZV9jb2RlICkgewoKCQkJaWYgKCBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBhbHJlYWR5IGluc3RhbGxlZC4iICk7CgkJCQkkc2tpcHMrKzsKCQkJfSBlbHNlIHsKCQkJCSRyZXNwb25zZSA9ICR0aGlzLT5kb3dubG9hZF9sYW5ndWFnZV9wYWNrKCAkbGFuZ3VhZ2VfY29kZSApOwoKCQkJCWlmICggaXNfd3BfZXJyb3IoICRyZXNwb25zZSApICkgewoJCQkJCVxXUF9DTEk6Ondhcm5pbmcoICRyZXNwb25zZSApOwoJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBub3QgaW5zdGFsbGVkLiIgKTsKCgkJCQkJLy8gU2tpcCBpZiB0cmFuc2xhdGlvbiBpcyBub3QgeWV0IGF2YWlsYWJsZS4KCQkJCQlpZiAoICdub3RfZm91bmQnID09PSAkcmVzcG9uc2UtPmdldF9lcnJvcl9jb2RlKCkgKSB7CgkJCQkJCSRza2lwcysrOwoJCQkJCX0gZWxzZSB7CgkJCQkJCSRlcnJvcnMrKzsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCVxXUF9DTEk6OmxvZyggIkxhbmd1YWdlICd7JGxhbmd1YWdlX2NvZGV9JyBpbnN0YWxsZWQuIiApOwoJCQkJCSRzdWNjZXNzZXMrKzsKCQkJCX0KCQkJfQoKCQkJaWYgKCBXUF9DTElcVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnYWN0aXZhdGUnICkgKSB7CgkJCQkkdGhpcy0+YWN0aXZhdGVfbGFuZ3VhZ2UoICRsYW5ndWFnZV9jb2RlICk7CgkJCX0KCQl9CgoJCVxXUF9DTElcVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnbGFuZ3VhZ2UnLCAnaW5zdGFsbCcsICRjb3VudCwgJHN1Y2Nlc3NlcywgJGVycm9ycywgJHNraXBzICk7Cgl9CgoJLyoqCgkgKiBVbmluc3RhbGxzIGEgZ2l2ZW4gbGFuZ3VhZ2UuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxsYW5ndWFnZT4uLi4KCSAqIDogTGFuZ3VhZ2UgY29kZSB0byB1bmluc3RhbGwuCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgJCB3cCBsYW5ndWFnZSBjb3JlIHVuaW5zdGFsbCBqYQoJICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIHVuaW5zdGFsbGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIHVuaW5zdGFsbAoJICogQHRocm93cyBXUF9DTElcRXhpdEV4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gdW5pbnN0YWxsKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJZ2xvYmFsICR3cF9maWxlc3lzdGVtOwoKCQkkbGFuZ3VhZ2VfY29kZXMgPSAoYXJyYXkpICRhcmdzOwoKCQkkYXZhaWxhYmxlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCk7CgoJCWZvcmVhY2ggKCAkbGFuZ3VhZ2VfY29kZXMgYXMgJGxhbmd1YWdlX2NvZGUgKSB7CgoJCQlpZiAoICEgaW5fYXJyYXkoICRsYW5ndWFnZV9jb2RlLCAkYXZhaWxhYmxlLCB0cnVlICkgKSB7CgkJCQlXUF9DTEk6OmVycm9yKCAnTGFuZ3VhZ2Ugbm90IGluc3RhbGxlZC4nICk7CgkJCX0KCgkJCSRkaXIgICA9ICdjb3JlJyA9PT0gJHRoaXMtPm9ial90eXBlID8gJycgOiAiLyR0aGlzLT5vYmpfdHlwZSI7CgkJCSRmaWxlcyA9IHNjYW5kaXIoIFdQX0xBTkdfRElSIC4gJGRpciApOwoJCQlpZiAoICEgJGZpbGVzICkgewoJCQkJV1BfQ0xJOjplcnJvciggJ05vIGZpbGVzIGZvdW5kIGluIGxhbmd1YWdlIGRpcmVjdG9yeS4nICk7CgkJCX0KCgkJCSRjdXJyZW50X2xvY2FsZSA9IGdldF9sb2NhbGUoKTsKCQkJaWYgKCAkbGFuZ3VhZ2VfY29kZSA9PT0gJGN1cnJlbnRfbG9jYWxlICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiVGhlICd7JGxhbmd1YWdlX2NvZGV9JyBsYW5ndWFnZSBpcyBhY3RpdmUuIiApOwoJCQkJZXhpdDsKCQkJfQoKCQkJLy8gQXMgb2YgV1AgNC4wLCBubyBBUEkgZm9yIGRlbGV0aW5nIGEgbGFuZ3VhZ2UgcGFjawoJCQlXUF9GaWxlc3lzdGVtKCk7CgkJCSRkZWxldGVkID0gZmFsc2U7CgkJCWZvcmVhY2ggKCAkZmlsZXMgYXMgJGZpbGUgKSB7CgkJCQlpZiAoICcuJyA9PT0gJGZpbGVbMF0gfHwgaXNfZGlyKCAkZmlsZSApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJJGV4dGVuc2lvbl9sZW5ndGggPSBzdHJsZW4oICRsYW5ndWFnZV9jb2RlICkgKyA0OwoJCQkJJGVuZGluZyAgICAgICAgICAgPSBzdWJzdHIoICRmaWxlLCAtJGV4dGVuc2lvbl9sZW5ndGggKTsKCQkJCWlmICggISBpbl9hcnJheSggJGZpbGUsIGFycmF5KCAkbGFuZ3VhZ2VfY29kZSAuICcucG8nLCAkbGFuZ3VhZ2VfY29kZSAuICcubW8nICksIHRydWUgKSAmJiAhIGluX2FycmF5KCAkZW5kaW5nLCBhcnJheSggJy0nIC4gJGxhbmd1YWdlX2NvZGUgLiAnLnBvJywgJy0nIC4gJGxhbmd1YWdlX2NvZGUgLiAnLm1vJyApLCB0cnVlICkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJLyoqIEB2YXIgV1BfRmlsZXN5c3RlbV9CYXNlICR3cF9maWxlc3lzdGVtICovCgkJCQkkZGVsZXRlZCA9ICR3cF9maWxlc3lzdGVtLT5kZWxldGUoIFdQX0xBTkdfRElSIC4gJGRpciAuICcvJyAuICRmaWxlICk7CgkJCX0KCgkJCWlmICggJGRlbGV0ZWQgKSB7CgkJCQlXUF9DTEk6OnN1Y2Nlc3MoICdMYW5ndWFnZSB1bmluc3RhbGxlZC4nICk7CgkJCX0gZWxzZSB7CgkJCQlXUF9DTEk6OmVycm9yKCAiQ291bGRuJ3QgdW5pbnN0YWxsIGxhbmd1YWdlLiIgKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFVwZGF0ZXMgaW5zdGFsbGVkIGxhbmd1YWdlcyBmb3IgY29yZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWy0tZHJ5LXJ1bl0KCSAqIDogUHJldmlldyB3aGljaCB0cmFuc2xhdGlvbnMgd291bGQgYmUgdXBkYXRlZC4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIGxhbmd1YWdlIGNvcmUgdXBkYXRlCgkgKiAgICAgVXBkYXRpbmcgJ0phcGFuZXNlJyB0cmFuc2xhdGlvbiBmb3IgV29yZFByZXNzIDQuOS4yLi4uCgkgKiAgICAgRG93bmxvYWRpbmcgdHJhbnNsYXRpb24gZnJvbSBodHRwczovL2Rvd25sb2Fkcy53b3JkcHJlc3Mub3JnL3RyYW5zbGF0aW9uL2NvcmUvNC45LjIvamEuemlwLi4uCgkgKiAgICAgVHJhbnNsYXRpb24gdXBkYXRlZCBzdWNjZXNzZnVsbHkuCgkgKiAgICAgU3VjY2VzczogVXBkYXRlZCAxLzEgdHJhbnNsYXRpb24uCgkgKgoJICogQHN1YmNvbW1hbmQgdXBkYXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsgLy8gcGhwY3M6aWdub3JlIEdlbmVyaWMuQ29kZUFuYWx5c2lzLlVzZWxlc3NPdmVycmlkaW5nTWV0aG9kLkZvdW5kIC0tIE92ZXJydWxpbmcgdGhlIGRvY3VtZW50YXRpb24sIHNvIG5vdCB1c2VsZXNzIDstKS4KCQlwYXJlbnQ6OnVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICk7Cgl9CgoJLyoqCgkgKiBBY3RpdmF0ZXMgYSBnaXZlbiBsYW5ndWFnZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPGxhbmd1YWdlPgoJICogOiBMYW5ndWFnZSBjb2RlIHRvIGFjdGl2YXRlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICQgd3AgbGFuZ3VhZ2UgY29yZSBhY3RpdmF0ZSBqYQoJICogICAgIFN1Y2Nlc3M6IExhbmd1YWdlIGFjdGl2YXRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBhY3RpdmF0ZQoJICogQHRocm93cyBXUF9DTElcRXhpdEV4Y2VwdGlvbgoJICovCglwdWJsaWMgZnVuY3Rpb24gYWN0aXZhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlcV1BfQ0xJOjp3YXJuaW5nKCAnVGhpcyBjb21tYW5kIGlzIGRlcHJlY2F0ZWQuIHVzZSB3cCBzaXRlIHN3aXRjaC1sYW5ndWFnZSBpbnN0ZWFkJyApOwoKCQlsaXN0KCAkbGFuZ3VhZ2VfY29kZSApID0gJGFyZ3M7CgoJCSR0aGlzLT5hY3RpdmF0ZV9sYW5ndWFnZSggJGxhbmd1YWdlX2NvZGUgKTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGFjdGl2YXRlX2xhbmd1YWdlKCAkbGFuZ3VhZ2VfY29kZSApIHsKCQkkYXZhaWxhYmxlID0gJHRoaXMtPmdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCk7CgoJCWlmICggISBpbl9hcnJheSggJGxhbmd1YWdlX2NvZGUsICRhdmFpbGFibGUsIHRydWUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0xhbmd1YWdlIG5vdCBpbnN0YWxsZWQuJyApOwoJCX0KCgkJaWYgKCAnZW5fVVMnID09PSAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJJGxhbmd1YWdlX2NvZGUgPSAnJzsKCQl9CgoJCWlmICggZ2V0X2xvY2FsZSgpID09PSAkbGFuZ3VhZ2VfY29kZSApIHsKCQkJV1BfQ0xJOjp3YXJuaW5nKCAiTGFuZ3VhZ2UgJ3skbGFuZ3VhZ2VfY29kZX0nIGFscmVhZHkgYWN0aXZlLiIgKTsKCgkJCXJldHVybjsKCQl9CgoJCXVwZGF0ZV9vcHRpb24oICdXUExBTkcnLCAkbGFuZ3VhZ2VfY29kZSApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdMYW5ndWFnZSBhY3RpdmF0ZWQuJyApOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgV1BfQ0xJOwoKdXNlIFdQX0NMSTsKdXNlIFdQX0NMSV9Db21tYW5kOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIFdQLUNMSSBjb21tYW5kcyB0aGF0IGRlYWwgd2l0aCB0cmFuc2xhdGlvbnMKICoKICogQHBhY2thZ2Ugd3AtY2xpCiAqLwphYnN0cmFjdCBjbGFzcyBDb21tYW5kV2l0aFRyYW5zbGF0aW9uIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoJcHJvdGVjdGVkICRvYmpfdHlwZTsKCglwcm90ZWN0ZWQgJG9ial9maWVsZHM7CgoJLyoqCgkgKiBDYWxsYmFjayB0byBzb3J0IGFycmF5IGJ5IGEgJ2xhbmd1YWdlJyBrZXkuCgkgKi8KCXByb3RlY3RlZCBmdW5jdGlvbiBzb3J0X3RyYW5zbGF0aW9uc19jYWxsYmFjayggJGEsICRiICkgewoJCXJldHVybiBzdHJuYXRjYXNlY21wKCAkYVsnbGFuZ3VhZ2UnXSwgJGJbJ2xhbmd1YWdlJ10gKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgaW5zdGFsbGVkIGxhbmd1YWdlcyBmb3IgdGhlIGN1cnJlbnQgb2JqZWN0IHR5cGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB1cGRhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkdXBkYXRlcyA9ICR0aGlzLT5nZXRfdHJhbnNsYXRpb25fdXBkYXRlcygpOwoKCQlpZiAoIGVtcHR5KCAkdXBkYXRlcyApICkgewoJCQlXUF9DTEk6OnN1Y2Nlc3MoICdUcmFuc2xhdGlvbnMgYXJlIHVwIHRvIGRhdGUuJyApOwoKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCBlbXB0eSggJGFyZ3MgKSApIHsKCQkJJGFyZ3MgPSBhcnJheSggbnVsbCApOyAvLyBVc2VkIGZvciBjb3JlLgoJCX0KCgkJJHVwZ3JhZGVyICAgICAgPSAnV1BfQ0xJXFxMYW5ndWFnZVBhY2tVcGdyYWRlcic7CgkJJHJlc3VsdHMgICAgICAgPSBhcnJheSgpOwoJCSRudW1fdG9fdXBkYXRlID0gMDsKCgkJZm9yZWFjaCAoICRhcmdzIGFzICRzbHVnICkgewoJCQkvLyBHZXRzIGEgbGlzdCBvZiBhbGwgbGFuZ3VhZ2VzLgoJCQkkYWxsX2xhbmd1YWdlcyA9ICR0aGlzLT5nZXRfYWxsX2xhbmd1YWdlcyggJHNsdWcgKTsKCgkJCSR1cGRhdGVzX3Blcl90eXBlID0gYXJyYXkoKTsKCgkJCS8vIEZvcm1hdHMgdGhlIHVwZGF0ZXMgbGlzdC4KCQkJZm9yZWFjaCAoICR1cGRhdGVzIGFzICR1cGRhdGUgKSB7CgkJCQlpZiAoIG51bGwgIT09ICRzbHVnICYmICR1cGRhdGUtPnNsdWcgIT09ICRzbHVnICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCSRuYW1lID0gJ1dvcmRQcmVzcyc7IC8vIENvcmUuCgoJCQkJaWYgKCAncGx1Z2luJyA9PT0gJHVwZGF0ZS0+dHlwZSApIHsKCQkJCQkkcGx1Z2lucyAgICAgPSBnZXRfcGx1Z2lucyggJy8nIC4gJHVwZGF0ZS0+c2x1ZyApOwoJCQkJCSRwbHVnaW5fZGF0YSA9IGFycmF5X3NoaWZ0KCAkcGx1Z2lucyApOwoJCQkJCSRuYW1lICAgICAgICA9ICRwbHVnaW5fZGF0YVsnTmFtZSddOwoJCQkJfSBlbHNlaWYgKCAndGhlbWUnID09PSAkdXBkYXRlLT50eXBlICkgewoJCQkJCSR0aGVtZV9kYXRhID0gd3BfZ2V0X3RoZW1lKCAkdXBkYXRlLT5zbHVnICk7CgkJCQkJJG5hbWUgICAgICAgPSAkdGhlbWVfZGF0YVsnTmFtZSddOwoJCQkJfQoKCQkJCS8vIEdldHMgdGhlIHRyYW5zbGF0aW9uIGRhdGEuCgkJCQkkdHJhbnNsYXRpb24gPSB3cF9saXN0X2ZpbHRlciggJGFsbF9sYW5ndWFnZXMsIGFycmF5KCAnbGFuZ3VhZ2UnID0+ICR1cGRhdGUtPmxhbmd1YWdlICkgKTsKCQkJCSR0cmFuc2xhdGlvbiA9IChvYmplY3QpIHJlc2V0KCAkdHJhbnNsYXRpb24gKTsKCgkJCQkkdXBkYXRlLT5UeXBlICAgID0gdWNmaXJzdCggJHVwZGF0ZS0+dHlwZSApOwoJCQkJJHVwZGF0ZS0+TmFtZSAgICA9ICRuYW1lOwoJCQkJJHVwZGF0ZS0+VmVyc2lvbiA9ICR1cGRhdGUtPnZlcnNpb247CgoJCQkJaWYgKCBpc3NldCggJHRyYW5zbGF0aW9uLT5lbmdsaXNoX25hbWUgKSApIHsKCQkJCQkkdXBkYXRlLT5MYW5ndWFnZSA9ICR0cmFuc2xhdGlvbi0+ZW5nbGlzaF9uYW1lOwoJCQkJfQoKCQkJCWlmICggISBpc3NldCggJHVwZGF0ZXNfcGVyX3R5cGVbICR1cGRhdGUtPnR5cGUgXSApICkgewoJCQkJCSR1cGRhdGVzX3Blcl90eXBlWyAkdXBkYXRlLT50eXBlIF0gPSBhcnJheSgpOwoJCQkJfQoJCQkJJHVwZGF0ZXNfcGVyX3R5cGVbICR1cGRhdGUtPnR5cGUgXVtdID0gJHVwZGF0ZTsKCQkJfQoKCQkJJG9ial90eXBlICAgICAgICAgID0gcnRyaW0oICR0aGlzLT5vYmpfdHlwZSwgJ3MnICk7CgkJCSRhdmFpbGFibGVfdXBkYXRlcyA9IGlzc2V0KCAkdXBkYXRlc19wZXJfdHlwZVsgJG9ial90eXBlIF0gKSA/ICR1cGRhdGVzX3Blcl90eXBlWyAkb2JqX3R5cGUgXSA6IG51bGw7CgoJCQlpZiAoICEgaXNfYXJyYXkoICRhdmFpbGFibGVfdXBkYXRlcyApICkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCSRudW1fdG9fdXBkYXRlICs9IGNvdW50KCAkYXZhaWxhYmxlX3VwZGF0ZXMgKTsKCgkJCWlmICggISBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkcnktcnVuJyApICkgewoJCQkJLy8gVXBkYXRlIHRyYW5zbGF0aW9ucy4KCQkJCWZvcmVhY2ggKCAkYXZhaWxhYmxlX3VwZGF0ZXMgYXMgJHVwZGF0ZSApIHsKCQkJCQlXUF9DTEk6OmxpbmUoICJVcGRhdGluZyAneyR1cGRhdGUtPkxhbmd1YWdlfScgdHJhbnNsYXRpb24gZm9yIHskdXBkYXRlLT5OYW1lfSB7JHVwZGF0ZS0+VmVyc2lvbn0uLi4iICk7CgoJCQkJCSRyZXN1bHQgPSBVdGlsc1xnZXRfdXBncmFkZXIoICR1cGdyYWRlciApLT51cGdyYWRlKCAkdXBkYXRlICk7CgoJCQkJCSRyZXN1bHRzW10gPSAkcmVzdWx0OwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBPbmx5IHByZXZpZXcgd2hpY2ggdHJhbnNsYXRpb25zIHdvdWxkIGJlIHVwZGF0ZWQuCgkJaWYgKCBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdkcnktcnVuJyApICkgewoJCQkkdXBkYXRlX2NvdW50ID0gY291bnQoICR1cGRhdGVzICk7CgoJCQlXUF9DTEk6OmxpbmUoCgkJCQlzcHJpbnRmKAoJCQkJCSdGb3VuZCAlZCB0cmFuc2xhdGlvbiAlcyB0aGF0IHdvdWxkIGJlIHByb2Nlc3NlZDonLAoJCQkJCSR1cGRhdGVfY291bnQsCgkJCQkJV1BfQ0xJXFV0aWxzXHBsdXJhbGl6ZSggJ3VwZGF0ZScsICR1cGRhdGVfY291bnQgKQoJCQkJKQoJCQkpOwoKCQkJVXRpbHNcZm9ybWF0X2l0ZW1zKCAndGFibGUnLCAkdXBkYXRlcywgYXJyYXkoICdUeXBlJywgJ05hbWUnLCAnVmVyc2lvbicsICdMYW5ndWFnZScgKSApOwoKCQkJcmV0dXJuOwoJCX0KCgkJJG51bV91cGRhdGVkID0gY291bnQoIGFycmF5X2ZpbHRlciggJHJlc3VsdHMgKSApOwoKCQkkbGluZSA9IHNwcmludGYoICJVcGRhdGVkICRudW1fdXBkYXRlZC8kbnVtX3RvX3VwZGF0ZSAlcy4iLCBXUF9DTElcVXRpbHNccGx1cmFsaXplKCAndHJhbnNsYXRpb24nLCAkbnVtX3VwZGF0ZWQgKSApOwoKCQlpZiAoICRudW1fdG9fdXBkYXRlID09PSAkbnVtX3VwZGF0ZWQgKSB7CgkJCVdQX0NMSTo6c3VjY2VzcyggJGxpbmUgKTsKCQl9IGVsc2VpZiAoICRudW1fdXBkYXRlZCA+IDAgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJGxpbmUgKTsKCQl9IGVsc2UgewoJCQlXUF9DTEk6OmVycm9yKCAkbGluZSApOwoJCX0KCX0KCgkvKioKCSAqIEdldCBhbGwgdXBkYXRlcyBhdmFpbGFibGUgZm9yIGFsbCB0cmFuc2xhdGlvbnMuCgkgKgoJICogQHNlZSB3cF9nZXRfdHJhbnNsYXRpb25fdXBkYXRlcygpCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X3RyYW5zbGF0aW9uX3VwZGF0ZXMoKSB7CgkJJGF2YWlsYWJsZSA9ICR0aGlzLT5nZXRfaW5zdGFsbGVkX2xhbmd1YWdlcygpOwoKCQkkZnVuYyA9IGZ1bmN0aW9uKCkgdXNlICggJGF2YWlsYWJsZSApIHsKCQkJcmV0dXJuICRhdmFpbGFibGU7CgkJfTsKCgkJc3dpdGNoICggJHRoaXMtPm9ial90eXBlICkgewoJCQljYXNlICdwbHVnaW5zJzoKCQkJCWFkZF9maWx0ZXIoICdwbHVnaW5zX3VwZGF0ZV9jaGVja19sb2NhbGVzJywgJGZ1bmMgKTsKCgkJCQl3cF9jbGVhbl9wbHVnaW5zX2NhY2hlKCk7CgkJCQkvLyBDaGVjayBmb3IgUGx1Z2luIHRyYW5zbGF0aW9uIHVwZGF0ZXMuCgkJCQl3cF91cGRhdGVfcGx1Z2lucygpOwoKCQkJCXJlbW92ZV9maWx0ZXIoICdwbHVnaW5zX3VwZGF0ZV9jaGVja19sb2NhbGVzJywgJGZ1bmMgKTsKCgkJCQkkdHJhbnNpZW50ID0gJ3VwZGF0ZV9wbHVnaW5zJzsKCQkJCWJyZWFrOwoJCQljYXNlICd0aGVtZXMnOgoJCQkJYWRkX2ZpbHRlciggJ3RoZW1lc191cGRhdGVfY2hlY2tfbG9jYWxlcycsICRmdW5jICk7CgoJCQkJd3BfY2xlYW5fdGhlbWVzX2NhY2hlKCk7CgkJCQkvLyBDaGVjayBmb3IgVGhlbWUgdHJhbnNsYXRpb24gdXBkYXRlcy4KCQkJCXdwX3VwZGF0ZV90aGVtZXMoKTsKCgkJCQlyZW1vdmVfZmlsdGVyKCAndGhlbWVzX3VwZGF0ZV9jaGVja19sb2NhbGVzJywgJGZ1bmMgKTsKCgkJCQkkdHJhbnNpZW50ID0gJ3VwZGF0ZV90aGVtZXMnOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlkZWxldGVfc2l0ZV90cmFuc2llbnQoICd1cGRhdGVfY29yZScgKTsKCgkJCQkvLyBDaGVjayBmb3IgQ29yZSB0cmFuc2xhdGlvbiB1cGRhdGVzLgoJCQkJd3BfdmVyc2lvbl9jaGVjaygpOwoKCQkJCSR0cmFuc2llbnQgPSAndXBkYXRlX2NvcmUnOwoJCQkJYnJlYWs7CgkJfQoKCQkkdXBkYXRlcyAgID0gYXJyYXkoKTsKCQkkdHJhbnNpZW50ID0gZ2V0X3NpdGVfdHJhbnNpZW50KCAkdHJhbnNpZW50ICk7CgoJCWlmICggZW1wdHkoICR0cmFuc2llbnQtPnRyYW5zbGF0aW9ucyApICkgewoJCQlyZXR1cm4gJHVwZGF0ZXM7CgkJfQoKCQlmb3JlYWNoICggJHRyYW5zaWVudC0+dHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbiApIHsKCQkJJHVwZGF0ZXNbXSA9IChvYmplY3QpICR0cmFuc2xhdGlvbjsKCQl9CgoJCXJldHVybiAkdXBkYXRlczsKCX0KCgkvKioKCSAqIERvd25sb2FkIGEgbGFuZ3VhZ2UgcGFjay4KCSAqCgkgKiBAc2VlIHdwX2Rvd25sb2FkX2xhbmd1YWdlX3BhY2soKQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGRvd25sb2FkIExhbmd1YWdlIGNvZGUgdG8gZG93bmxvYWQuCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnIFBsdWdpbiBvciB0aGVtZSBzbHVnLiBOb3QgdXNlZCBmb3IgY29yZS4KCSAqIEByZXR1cm4gc3RyaW5nfFxXUF9FcnJvciBSZXR1cm5zIHRoZSBsYW5ndWFnZSBjb2RlIGlmIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkLCBvciBhIFdQX0Vycm9yIG9iamVjdCBvbiBmYWlsdXJlLgoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZG93bmxvYWRfbGFuZ3VhZ2VfcGFjayggJGRvd25sb2FkLCAkc2x1ZyA9IG51bGwgKSB7CgkJJHRyYW5zbGF0aW9ucyAgICAgICAgPSAkdGhpcy0+Z2V0X2FsbF9sYW5ndWFnZXMoICRzbHVnICk7CgkJJHRyYW5zbGF0aW9uX3RvX2xvYWQgPSBudWxsOwoKCQlmb3JlYWNoICggJHRyYW5zbGF0aW9ucyBhcyAkdHJhbnNsYXRpb24gKSB7CgkJCWlmICggJHRyYW5zbGF0aW9uWydsYW5ndWFnZSddID09PSAkZG93bmxvYWQgKSB7CgkJCQkkdHJhbnNsYXRpb25fdG9fbG9hZCA9ICR0cmFuc2xhdGlvbjsKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQlpZiAoICEgJHRyYW5zbGF0aW9uX3RvX2xvYWQgKSB7CgkJCXJldHVybiBuZXcgXFdQX0Vycm9yKCAnbm90X2ZvdW5kJywgIkxhbmd1YWdlICd7JGRvd25sb2FkfScgbm90IGF2YWlsYWJsZS4iICk7CgkJfQoJCSR0cmFuc2xhdGlvbiA9IChvYmplY3QpICR0cmFuc2xhdGlvbjsKCgkJJHRyYW5zbGF0aW9uLT50eXBlID0gcnRyaW0oICR0aGlzLT5vYmpfdHlwZSwgJ3MnICk7CgoJCS8vIE1ha2Ugc3VyZSBjYWNoaW5nIGluIExhbmd1YWdlUGFja1VwZ3JhZGVyIHdvcmtzLgoJCWlmICggISBpc3NldCggJHRyYW5zbGF0aW9uLT5zbHVnICkgKSB7CgkJCSR0cmFuc2xhdGlvbi0+c2x1ZyA9ICRzbHVnOwoJCX0KCgkJJHVwZ3JhZGVyID0gJ1dQX0NMSVxcTGFuZ3VhZ2VQYWNrVXBncmFkZXInOwoJCSRyZXN1bHQgICA9IFV0aWxzXGdldF91cGdyYWRlciggJHVwZ3JhZGVyICktPnVwZ3JhZGUoICR0cmFuc2xhdGlvbiwgYXJyYXkoICdjbGVhcl91cGRhdGVfY2FjaGUnID0+IGZhbHNlICkgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3VsdCApICkgewoJCQlyZXR1cm4gJHJlc3VsdDsKCQl9CgoJCWlmICggISAkcmVzdWx0ICkgewoJCQlyZXR1cm4gbmV3IFxXUF9FcnJvciggJ25vdF9pbnN0YWxsZWQnLCAiQ291bGQgbm90IGluc3RhbGwgbGFuZ3VhZ2UgJ3skZG93bmxvYWR9Jy4iICk7CgkJfQoKCQlyZXR1cm4gJHRyYW5zbGF0aW9uLT5sYW5ndWFnZTsKCX0KCgkvKioKCSAqIFJldHVybiBhIGxpc3Qgb2YgaW5zdGFsbGVkIGxhbmd1YWdlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnIE9wdGlvbmFsLiBQbHVnaW4gb3IgdGhlbWUgc2x1Zy4gRGVmYXVsdHMgdG8gJ2RlZmF1bHQnIGZvciBjb3JlLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9pbnN0YWxsZWRfbGFuZ3VhZ2VzKCAkc2x1ZyA9ICdkZWZhdWx0JyApIHsKCQkkYXZhaWxhYmxlICAgPSB3cF9nZXRfaW5zdGFsbGVkX3RyYW5zbGF0aW9ucyggJHRoaXMtPm9ial90eXBlICk7CgkJJGF2YWlsYWJsZSAgID0gISBlbXB0eSggJGF2YWlsYWJsZVsgJHNsdWcgXSApID8gYXJyYXlfa2V5cyggJGF2YWlsYWJsZVsgJHNsdWcgXSApIDogYXJyYXkoKTsKCQkkYXZhaWxhYmxlW10gPSAnZW5fVVMnOwoKCQlyZXR1cm4gJGF2YWlsYWJsZTsKCX0KCgkvKioKCSAqIFJldHVybiBhIGxpc3Qgb2YgYWxsIGxhbmd1YWdlcy4KCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzbHVnIE9wdGlvbmFsLiBQbHVnaW4gb3IgdGhlbWUgc2x1Zy4gTm90IHVzZWQgZm9yIGNvcmUuCgkgKgoJICogQHJldHVybiBhcnJheQoJICovCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0X2FsbF9sYW5ndWFnZXMoICRzbHVnID0gbnVsbCApIHsKCQlyZXF1aXJlX29uY2UgQUJTUEFUSCAuICcvd3AtYWRtaW4vaW5jbHVkZXMvdHJhbnNsYXRpb24taW5zdGFsbC5waHAnOwoJCXJlcXVpcmUgQUJTUEFUSCAuIFdQSU5DIC4gJy92ZXJzaW9uLnBocCc7IC8vIEluY2x1ZGUgYW4gdW5tb2RpZmllZCAkd3BfdmVyc2lvbgoKCQkkYXJncyA9IGFycmF5KAoJCQkndmVyc2lvbicgPT4gJHdwX3ZlcnNpb24sCgkJKTsKCgkJaWYgKCAkc2x1ZyApIHsKCQkJJGFyZ3NbJ3NsdWcnXSA9ICRzbHVnOwoKCQkJaWYgKCAncGx1Z2lucycgPT09ICR0aGlzLT5vYmpfdHlwZSApIHsKCQkJCSRwbHVnaW5zICAgICA9IGdldF9wbHVnaW5zKCAnLycgLiAkc2x1ZyApOwoJCQkJJHBsdWdpbl9kYXRhID0gYXJyYXlfc2hpZnQoICRwbHVnaW5zICk7CgkJCQlpZiAoIGlzc2V0KCAkcGx1Z2luX2RhdGFbJ1ZlcnNpb24nXSApICkgewoJCQkJCSRhcmdzWyd2ZXJzaW9uJ10gPSAkcGx1Z2luX2RhdGFbJ1ZlcnNpb24nXTsKCQkJCX0KCQkJfSBlbHNlaWYgKCAndGhlbWVzJyA9PT0gJHRoaXMtPm9ial90eXBlICkgewoJCQkJJHRoZW1lX2RhdGEgPSB3cF9nZXRfdGhlbWUoICRzbHVnICk7CgkJCQlpZiAoIGlzc2V0KCAkdGhlbWVfZGF0YVsnVmVyc2lvbiddICkgKSB7CgkJCQkJJGFyZ3NbJ3ZlcnNpb24nXSA9ICR0aGVtZV9kYXRhWydWZXJzaW9uJ107CgkJCQl9CgkJCX0KCQl9CgoJCSRyZXNwb25zZSA9IHRyYW5zbGF0aW9uc19hcGkoICR0aGlzLT5vYmpfdHlwZSwgJGFyZ3MgKTsKCgkJaWYgKCBpc193cF9lcnJvciggJHJlc3BvbnNlICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICRyZXNwb25zZSApOwoJCX0KCgkJJHRyYW5zbGF0aW9ucyA9ICEgZW1wdHkoICRyZXNwb25zZVsndHJhbnNsYXRpb25zJ10gKSA/ICRyZXNwb25zZVsndHJhbnNsYXRpb25zJ10gOiBhcnJheSgpOwoKCQkkZW5fdXMgPSBhcnJheSgKCQkJJ2xhbmd1YWdlJyAgICAgPT4gJ2VuX1VTJywKCQkJJ2VuZ2xpc2hfbmFtZScgPT4gJ0VuZ2xpc2ggKFVuaXRlZCBTdGF0ZXMpJywKCQkJJ25hdGl2ZV9uYW1lJyAgPT4gJ0VuZ2xpc2ggKFVuaXRlZCBTdGF0ZXMpJywKCQkJJ3VwZGF0ZWQnICAgICAgPT4gJycsCgkJKTsKCgkJJHRyYW5zbGF0aW9uc1tdID0gJGVuX3VzOwoKCQl1YXNvcnQoICR0cmFuc2xhdGlvbnMsIGFycmF5KCAkdGhpcywgJ3NvcnRfdHJhbnNsYXRpb25zX2NhbGxiYWNrJyApICk7CgoJCXJldHVybiAkdHJhbnNsYXRpb25zOwoJfQoKCS8qKgoJICogR2V0IEZvcm1hdHRlciBvYmplY3QgYmFzZWQgb24gc3VwcGxpZWQgcGFyYW1ldGVycy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFzc29jX2FyZ3MgUGFyYW1ldGVycyBwYXNzZWQgdG8gY29tbWFuZC4gRGV0ZXJtaW5lcyBmb3JtYXR0aW5nLgoJICogQHJldHVybiBGb3JtYXR0ZXIKCSAqLwoJcHJvdGVjdGVkIGZ1bmN0aW9uIGdldF9mb3JtYXR0ZXIoICYkYXNzb2NfYXJncyApIHsKCQlyZXR1cm4gbmV3IEZvcm1hdHRlciggJGFzc29jX2FyZ3MsICR0aGlzLT5vYmpfZmllbGRzLCAkdGhpcy0+b2JqX3R5cGUgKTsKCX0KfQo8P3BocAoKbmFtZXNwYWNlIFdQX0NMSTsKCnVzZSBXUF9DTEk7CgovKioKICogQSBMYW5ndWFnZSBQYWNrIFVwZ3JhZGVyIGNsYXNzIHRoYXQgY2FjaGVzIHRoZSBkb3dubG9hZCwgYW5kIHVzZXMgY2FjaGVkIGlmIGF2YWlsYWJsZQogKgogKiBAcGFja2FnZSB3cC1jbGkKICovCmNsYXNzIExhbmd1YWdlUGFja1VwZ3JhZGVyIGV4dGVuZHMgXExhbmd1YWdlX1BhY2tfVXBncmFkZXIgewoJLyoqCgkgKiBJbml0aWFsaXplIHRoZSB1cGdyYWRlIHN0cmluZ3MuCgkgKgoJICogTWFrZXMgc3VyZSB0aGF0IHRoZSBzdHJpbmdzIGFyZSBhbHdheXMgaW4gRW5nbGlzaC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZ3JhZGVfc3RyaW5ncygpIHsKCQkkc3dpdGNoZWRfbG9jYWxlID0gZnVuY3Rpb25fZXhpc3RzKCAnc3dpdGNoX3RvX2xvY2FsZScgKSAmJiBzd2l0Y2hfdG9fbG9jYWxlKCAnZW5fVVMnICk7CgoJCXBhcmVudDo6dXBncmFkZV9zdHJpbmdzKCk7CgoJCWlmICggJHN3aXRjaGVkX2xvY2FsZSApIHsKCQkJcmVzdG9yZV9wcmV2aW91c19sb2NhbGUoKTsKCQl9Cgl9CgoJLyoqCgkgKiBJbml0aWFsaXplIHRoZSBnZW5lcmljIHN0cmluZ3MuCgkgKgoJICogTWFrZXMgc3VyZSB0aGF0IHRoZSBzdHJpbmdzIGFyZSBhbHdheXMgaW4gRW5nbGlzaC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIGdlbmVyaWNfc3RyaW5ncygpIHsKCQkkc3dpdGNoZWRfbG9jYWxlID0gZnVuY3Rpb25fZXhpc3RzKCAnc3dpdGNoX3RvX2xvY2FsZScgKSAmJiBzd2l0Y2hfdG9fbG9jYWxlKCAnZW5fVVMnICk7CgoJCXBhcmVudDo6Z2VuZXJpY19zdHJpbmdzKCk7CgoJCWlmICggJHN3aXRjaGVkX2xvY2FsZSApIHsKCQkJcmVzdG9yZV9wcmV2aW91c19sb2NhbGUoKTsKCQl9Cgl9CgoJLyoqCgkgKiBDYWNoZXMgdGhlIGRvd25sb2FkLCBhbmQgdXNlcyBjYWNoZWQgaWYgYXZhaWxhYmxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHBhY2thZ2UgICAgICAgICAgVGhlIFVSSSBvZiB0aGUgcGFja2FnZS4gSWYgdGhpcyBpcyB0aGUgZnVsbCBwYXRoIHRvIGFuCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nIGxvY2FsIGZpbGUsIGl0IHdpbGwgYmUgcmV0dXJuZWQgdW50b3VjaGVkLgoJICogQHBhcmFtIGJvb2wgICAkY2hlY2tfc2lnbmF0dXJlcyBXaGV0aGVyIHRvIHZhbGlkYXRlIGZpbGUgc2lnbmF0dXJlcy4gRGVmYXVsdCBmYWxzZS4KCSAqIEBwYXJhbSBhcnJheSAgJGhvb2tfZXh0cmEgICAgICAgRXh0cmEgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZpbHRlciBob29rcy4gRGVmYXVsdCBlbXB0eSBhcnJheS4KCSAqIEByZXR1cm4gc3RyaW5nfFxXUF9FcnJvciBUaGUgZnVsbCBwYXRoIHRvIHRoZSBkb3dubG9hZGVkIHBhY2thZ2UgZmlsZSwgb3IgYSBXUF9FcnJvciBvYmplY3QuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkb3dubG9hZF9wYWNrYWdlKCAkcGFja2FnZSwgJGNoZWNrX3NpZ25hdHVyZXMgPSBmYWxzZSwgJGhvb2tfZXh0cmEgPSBbXSApIHsKCgkJLyoqCgkJICogRmlsdGVyIHdoZXRoZXIgdG8gcmV0dXJuIHRoZSBwYWNrYWdlLgoJCSAqCgkJICogQHNpbmNlIDMuNy4wCgkJICogQHNpbmNlIDUuNS4wIEFkZGVkIHRoZSBgJGhvb2tfZXh0cmFgIHBhcmFtZXRlci4KCQkgKgoJCSAqIEBwYXJhbSBib29sICAgICAgICAgICRyZXBseSAgICAgIFdoZXRoZXIgdG8gYmFpbCB3aXRob3V0IHJldHVybmluZyB0aGUgcGFja2FnZS4gRGVmYXVsdCBpcyBmYWxzZS4KCQkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAkcGFja2FnZSAgICBUaGUgcGFja2FnZSBmaWxlIG5hbWUuCgkJICogQHBhcmFtIFxXUF9VcGdyYWRlciAgJHRoaXMgICAgICAgVGhlIFdQX1VwZ3JhZGVyIGluc3RhbmNlLgoJCSAqIEBwYXJhbSBhcnJheSAgICAgICAgICRob29rX2V4dHJhIEV4dHJhIGFyZ3VtZW50cyBwYXNzZWQgdG8gaG9va2VkIGZpbHRlcnMuCgkJICoKCQkgKiBAcGhwY3M6ZGlzYWJsZSBXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscy5Ob25QcmVmaXhlZEhvb2tuYW1lRm91bmQgLS0gVXNpbmcgV1AgbmF0aXZlIGhvb2suCgkJICovCgkJJHJlcGx5ID0gYXBwbHlfZmlsdGVycyggJ3VwZ3JhZGVyX3ByZV9kb3dubG9hZCcsIGZhbHNlLCAkcGFja2FnZSwgJHRoaXMsICRob29rX2V4dHJhICk7CgkJLy8gcGhwY3M6ZW5hYmxlCgoJCWlmICggZmFsc2UgIT09ICRyZXBseSApIHsKCQkJcmV0dXJuICRyZXBseTsKCQl9CgoJCS8vIENoZWNrIGlmIHBhY2thZ2UgaXMgYSBsb2NhbCBvciByZW1vdGUgZmlsZS4gQmFpbCBpZiBpdCdzIGxvY2FsLgoJCWlmICggISBwcmVnX21hdGNoKCAnIV4oaHR0cHxodHRwc3xmdHApOi8vIWknLCAkcGFja2FnZSApICYmIGZpbGVfZXhpc3RzKCAkcGFja2FnZSApICkgewoJCQlyZXR1cm4gJHBhY2thZ2U7CgkJfQoKCQlpZiAoIGVtcHR5KCAkcGFja2FnZSApICkgewoJCQlyZXR1cm4gbmV3IFxXUF9FcnJvciggJ25vX3BhY2thZ2UnLCAkdGhpcy0+c3RyaW5nc1snbm9fcGFja2FnZSddICk7CgkJfQoKCQkkbGFuZ3VhZ2VfdXBkYXRlID0gJHRoaXMtPnNraW4tPmxhbmd1YWdlX3VwZGF0ZTsKCQkkdHlwZSAgICAgICAgICAgID0gJGxhbmd1YWdlX3VwZGF0ZS0+dHlwZTsKCQkkc2x1ZyAgICAgICAgICAgID0gZW1wdHkoICRsYW5ndWFnZV91cGRhdGUtPnNsdWcgKSA/ICdkZWZhdWx0JyA6ICRsYW5ndWFnZV91cGRhdGUtPnNsdWc7CgkJJHVwZGF0ZWQgICAgICAgICA9IHN0cnRvdGltZSggJGxhbmd1YWdlX3VwZGF0ZS0+dXBkYXRlZCApOwoJCSR2ZXJzaW9uICAgICAgICAgPSAkbGFuZ3VhZ2VfdXBkYXRlLT52ZXJzaW9uOwoJCSRsYW5ndWFnZSAgICAgICAgPSAkbGFuZ3VhZ2VfdXBkYXRlLT5sYW5ndWFnZTsKCQkkZXh0ICAgICAgICAgICAgID0gcGF0aGluZm8oICRwYWNrYWdlLCBQQVRISU5GT19FWFRFTlNJT04gKTsKCgkJJHRlbXAgPSBcV1BfQ0xJXFV0aWxzXGdldF90ZW1wX2RpcigpIC4gdW5pcWlkKCAnd3BfJyApIC4gJy4nIC4gJGV4dDsKCgkJJGNhY2hlICAgICAgPSBXUF9DTEk6OmdldF9jYWNoZSgpOwoJCSRjYWNoZV9rZXkgID0gInRyYW5zbGF0aW9uL3skdHlwZX0teyRzbHVnfS17JHZlcnNpb259LXskbGFuZ3VhZ2V9LXskdXBkYXRlZH0ueyRleHR9IjsKCQkkY2FjaGVfZmlsZSA9ICRjYWNoZS0+aGFzKCAkY2FjaGVfa2V5ICk7CgoJCWlmICggJGNhY2hlX2ZpbGUgKSB7CgkJCVdQX0NMSTo6bG9nKCAiVXNpbmcgY2FjaGVkIGZpbGUgJyRjYWNoZV9maWxlJy4uLiIgKTsKCQkJY29weSggJGNhY2hlX2ZpbGUsICR0ZW1wICk7CgkJCXJldHVybiAkdGVtcDsKCQl9CgoJCSR0aGlzLT5za2luLT5mZWVkYmFjayggJ2Rvd25sb2FkaW5nX3BhY2thZ2UnLCAkcGFja2FnZSApOwoKCQkkdGVtcCA9IGRvd25sb2FkX3VybCggJHBhY2thZ2UsIDYwMCApOyAvLyAxMCBtaW51dGVzIG91Z2h0IHRvIGJlIGVub3VnaCBmb3IgZXZlcnlib2R5LgoKCQlpZiAoIGlzX3dwX2Vycm9yKCAkdGVtcCApICkgewoJCQlyZXR1cm4gJHRlbXA7CgkJfQoKCQkkY2FjaGUtPmltcG9ydCggJGNhY2hlX2tleSwgJHRlbXAgKTsKCgkJcmV0dXJuICR0ZW1wOwoJfQp9Cjw/cGhwCgppZiAoICEgY2xhc3NfZXhpc3RzKCAnV1BfQ0xJJyApICkgewoJcmV0dXJuOwp9Cgokd3BjbGlfZXZhbF9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9ldmFsX2F1dG9sb2FkZXIgKSApIHsKCXJlcXVpcmVfb25jZSAkd3BjbGlfZXZhbF9hdXRvbG9hZGVyOwp9CgpXUF9DTEk6OmFkZF9jb21tYW5kKCAnZXZhbCcsICdFdmFsX0NvbW1hbmQnICk7CldQX0NMSTo6YWRkX2NvbW1hbmQoICdldmFsLWZpbGUnLCAnRXZhbEZpbGVfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgpjbGFzcyBFdmFsX0NvbW1hbmQgZXh0ZW5kcyBXUF9DTElfQ29tbWFuZCB7CgoJLyoqCgkgKiBFeGVjdXRlcyBhcmJpdHJhcnkgUEhQIGNvZGUuCgkgKgoJICogTm90ZTogYmVjYXVzZSBjb2RlIGlzIGV4ZWN1dGVkIHdpdGhpbiBhIG1ldGhvZCwgZ2xvYmFsIHZhcmlhYmxlcyBuZWVkCgkgKiB0byBiZSBleHBsaWNpdGx5IGdsb2JhbGl6ZWQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxwaHAtY29kZT4KCSAqIDogVGhlIGNvZGUgdG8gZXhlY3V0ZSwgYXMgYSBzdHJpbmcuCgkgKgoJICogWy0tc2tpcC13b3JkcHJlc3NdCgkgKiA6IEV4ZWN1dGUgY29kZSB3aXRob3V0IGxvYWRpbmcgV29yZFByZXNzLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGlzcGxheSBXb3JkUHJlc3MgY29udGVudCBkaXJlY3RvcnkuCgkgKiAgICAgJCB3cCBldmFsICdlY2hvIFdQX0NPTlRFTlRfRElSOycKCSAqICAgICAvdmFyL3d3dy93b3JkcHJlc3Mvd3AtY29udGVudAoJICoKCSAqICAgICAjIEdlbmVyYXRlIGEgcmFuZG9tIG51bWJlci4KCSAqICAgICAkIHdwIGV2YWwgJ2VjaG8gcmFuZCgpOycgLS1za2lwLXdvcmRwcmVzcwoJICogICAgIDQ3OTYyMDQyMwoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBfX2ludm9rZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlpZiAoIG51bGwgPT09IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtd29yZHByZXNzJyApICkgewoJCQlXUF9DTEk6OmdldF9ydW5uZXIoKS0+bG9hZF93b3JkcHJlc3MoKTsKCQl9CgoJCWV2YWwoICRhcmdzWzBdICk7Cgl9Cn0KPD9waHAKCnVzZSBXUF9DTElcVXRpbHM7CgpjbGFzcyBFdmFsRmlsZV9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCS8qKgoJICogUmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gdG8gbWF0Y2ggdGhlIHNoZWxsIHNoZWJhbmcuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgU0hFQkFOR19QQVRURVJOID0gJy9eKCMhLiopJC9tJzsKCgkvKioKCSAqIExvYWRzIGFuZCBleGVjdXRlcyBhIFBIUCBmaWxlLgoJICoKCSAqIE5vdGU6IGJlY2F1c2UgY29kZSBpcyBleGVjdXRlZCB3aXRoaW4gYSBtZXRob2QsIGdsb2JhbCB2YXJpYWJsZXMgbmVlZAoJICogdG8gYmUgZXhwbGljaXRseSBnbG9iYWxpemVkLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8ZmlsZT4KCSAqIDogVGhlIHBhdGggdG8gdGhlIFBIUCBmaWxlIHRvIGV4ZWN1dGUuICBVc2UgJy0nIHRvIHJ1biBjb2RlIGZyb20gU1RESU4uCgkgKgoJICogWzxhcmc+Li4uXQoJICogOiBPbmUgb3IgbW9yZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmlsZS4gVGhleSBhcmUgcGxhY2VkIGluIHRoZSAkYXJncyB2YXJpYWJsZS4KCSAqCgkgKiBbLS1za2lwLXdvcmRwcmVzc10KCSAqIDogTG9hZCBhbmQgZXhlY3V0ZSBmaWxlIHdpdGhvdXQgbG9hZGluZyBXb3JkUHJlc3MuCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICB3cCBldmFsLWZpbGUgbXktY29kZS5waHAgdmFsdWUxIHZhbHVlMgoJICovCglwdWJsaWMgZnVuY3Rpb24gX19pbnZva2UoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkZmlsZSA9IGFycmF5X3NoaWZ0KCAkYXJncyApOwoKCQlpZiAoICctJyAhPT0gJGZpbGUgJiYgISBmaWxlX2V4aXN0cyggJGZpbGUgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIickZmlsZScgZG9lcyBub3QgZXhpc3QuIiApOwoJCX0KCgkJaWYgKCBudWxsID09PSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdza2lwLXdvcmRwcmVzcycgKSApIHsKCQkJV1BfQ0xJOjpnZXRfcnVubmVyKCktPmxvYWRfd29yZHByZXNzKCk7CgkJfQoKCQlzZWxmOjpleGVjdXRlX2V2YWwoICRmaWxlLCAkYXJncyApOwoJfQoKCS8qKgoJICogRXZhbHVhdGUgYSBwcm92aWRlZCBmaWxlLgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGZpbGUgRmlsZXBhdGggdG8gZXhlY3V0ZSwgb3IgLSBmb3IgU1RESU4uCgkgKiBAcGFyYW0gbWl4ZWQgICRhcmdzIEFycmF5IG9mIHBvc2l0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZpbGUuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4ZWN1dGVfZXZhbCggJGZpbGUsICRhcmdzICkgewoJCWlmICggJy0nID09PSAkZmlsZSApIHsKCQkJZXZhbCggJz8+JyAuIGZpbGVfZ2V0X2NvbnRlbnRzKCAncGhwOi8vc3RkaW4nICkgKTsKCQl9IGVsc2UgewoJCQkkZmlsZV9jb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkZmlsZSApOwoKCQkJLy8gQWRqdXN0IGZvciBfX0ZJTEVfXyBhbmQgX19ESVJfXyBtYWdpYyBjb25zdGFudHMuCgkJCSRmaWxlX2NvbnRlbnRzID0gVXRpbHNccmVwbGFjZV9wYXRoX2NvbnN0cyggJGZpbGVfY29udGVudHMsICRmaWxlICk7CgoJCQkvLyBDaGVjayBmb3IgYW5kIHJlbW92ZSBzaGUtYmFuZy4KCQkJaWYgKCAwID09PSBzdHJuY21wKCAkZmlsZV9jb250ZW50cywgJyMhJywgMiApICkgewoJCQkJJGZpbGVfY29udGVudHMgPSBwcmVnX3JlcGxhY2UoIHN0YXRpYzo6U0hFQkFOR19QQVRURVJOLCAnJywgJGZpbGVfY29udGVudHMgKTsKCQkJfQoKCQkJZXZhbCggJz8+JyAuICRmaWxlX2NvbnRlbnRzICk7CgkJfQoJfQp9Cgo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX3dpZGdldF9hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV93aWRnZXRfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV93aWRnZXRfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3dpZGdldCcsICdXaWRnZXRfQ29tbWFuZCcgKTsKV1BfQ0xJOjphZGRfY29tbWFuZCggJ3NpZGViYXInLCAnU2lkZWJhcl9Db21tYW5kJyApOwo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CgovKioKICogTWFuYWdlcyB3aWRnZXRzLCBpbmNsdWRpbmcgYWRkaW5nIGFuZCBtb3ZpbmcgdGhlbSB3aXRoaW4gc2lkZWJhcnMuCiAqCiAqIEEgW3dpZGdldF0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy90aGVtZXMvZnVuY3Rpb25hbGl0eS93aWRnZXRzLykgYWRkcyBjb250ZW50IGFuZCBmZWF0dXJlcyB0byBhIHdpZGdldCBhcmVhIChhbHNvIGNhbGxlZCBhIFtzaWRlYmFyXShodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3RoZW1lcy9mdW5jdGlvbmFsaXR5L3NpZGViYXJzLykpLgogKgogKiAjIyBFWEFNUExFUwogKgogKiAgICAgIyBMaXN0IHdpZGdldHMgb24gYSBnaXZlbiBzaWRlYmFyCiAqICAgICAkIHdwIHdpZGdldCBsaXN0IHNpZGViYXItMQogKiAgICAgKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICogICAgIHwgbmFtZSAgICAgfCBpZCAgICAgICAgIHwgcG9zaXRpb24gfCBvcHRpb25zICAgICAgICAgICAgICB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgICAgfCBtZXRhICAgICB8IG1ldGEtNiAgICAgfCAxICAgICAgICB8IHsidGl0bGUiOiJNZXRhIn0gICAgIHwKICogICAgIHwgY2FsZW5kYXIgfCBjYWxlbmRhci0yIHwgMiAgICAgICAgfCB7InRpdGxlIjoiQ2FsZW5kYXIifSB8CiAqICAgICArLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogKgogKiAgICAgIyBBZGQgYSBjYWxlbmRhciB3aWRnZXQgdG8gdGhlIHNlY29uZCBwb3NpdGlvbiBvbiB0aGUgc2lkZWJhcgogKiAgICAgJCB3cCB3aWRnZXQgYWRkIGNhbGVuZGFyIHNpZGViYXItMSAyCiAqICAgICBTdWNjZXNzOiBBZGRlZCB3aWRnZXQgdG8gc2lkZWJhci4KICoKICogICAgICMgVXBkYXRlIG9wdGlvbihzKSBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiB3aWRnZXQKICogICAgICQgd3Agd2lkZ2V0IHVwZGF0ZSBjYWxlbmRhci0xIC0tdGl0bGU9IkNhbGVuZGFyIgogKiAgICAgU3VjY2VzczogV2lkZ2V0IHVwZGF0ZWQuCiAqCiAqICAgICAjIERlbGV0ZSBvbmUgb3IgbW9yZSB3aWRnZXRzIGVudGlyZWx5CiAqICAgICAkIHdwIHdpZGdldCBkZWxldGUgY2FsZW5kYXItMiBhcmNoaXZlLTEKICogICAgIFN1Y2Nlc3M6IDIgd2lkZ2V0cyByZW1vdmVkIGZyb20gc2lkZWJhci4KICovCmNsYXNzIFdpZGdldF9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IFsKCQknbmFtZScsCgkJJ2lkJywKCQkncG9zaXRpb24nLAoJCSdvcHRpb25zJywKCV07CgoJLyoqCgkgKiBMaXN0cyB3aWRnZXRzIGFzc29jaWF0ZWQgd2l0aCBhIHNpZGViYXIuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxzaWRlYmFyLWlkPgoJICogOiBJRCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgc2lkZWJhci4KCSAqCgkgKiBbLS1maWVsZHM9PGZpZWxkcz5dCgkgKiA6IExpbWl0IHRoZSBvdXRwdXQgdG8gc3BlY2lmaWMgb2JqZWN0IGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBpZHMKCSAqICAgLSBqc29uCgkgKiAgIC0gY291bnQKCSAqICAgLSB5YW1sCgkgKiAtLS0KCSAqCgkgKiAjIyBBVkFJTEFCTEUgRklFTERTCgkgKgoJICogVGhlc2UgZmllbGRzIHdpbGwgYmUgZGlzcGxheWVkIGJ5IGRlZmF1bHQgZm9yIGVhY2ggd2lkZ2V0OgoJICoKCSAqICogbmFtZQoJICogKiBpZAoJICogKiBwb3NpdGlvbgoJICogKiBvcHRpb25zCgkgKgoJICogVGhlcmUgYXJlIG5vIG9wdGlvbmFsbHkgYXZhaWxhYmxlIGZpZWxkcy4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHdpZGdldCBsaXN0IHNpZGViYXItMSAtLWZpZWxkcz1uYW1lLGlkIC0tZm9ybWF0PWNzdgoJICogICAgIG5hbWUsaWQKCSAqICAgICBtZXRhLG1ldGEtNQoJICogICAgIHNlYXJjaCxzZWFyY2gtMwoJICoKCSAqIEBzdWJjb21tYW5kIGxpc3QKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGxpc3RfKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWxpc3QoICRzaWRlYmFyX2lkICkgPSAkYXJnczsKCgkJJHRoaXMtPnZhbGlkYXRlX3NpZGViYXIoICRzaWRlYmFyX2lkICk7CgoJCSRvdXRwdXRfd2lkZ2V0cyA9ICR0aGlzLT5nZXRfc2lkZWJhcl93aWRnZXRzKCAkc2lkZWJhcl9pZCApOwoKCQlpZiAoICEgZW1wdHkoICRhc3NvY19hcmdzWydmb3JtYXQnXSApICYmICdpZHMnID09PSAkYXNzb2NfYXJnc1snZm9ybWF0J10gKSB7CgkJCSRvdXRwdXRfd2lkZ2V0cyA9IHdwX2xpc3RfcGx1Y2soICRvdXRwdXRfd2lkZ2V0cywgJ2lkJyApOwoJCX0KCgkJJGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoICRhc3NvY19hcmdzLCAkdGhpcy0+ZmllbGRzICk7CgkJJGZvcm1hdHRlci0+ZGlzcGxheV9pdGVtcyggJG91dHB1dF93aWRnZXRzICk7CgoJfQoKCS8qKgoJICogQWRkcyBhIHdpZGdldCB0byBhIHNpZGViYXIuCgkgKgoJICogQ3JlYXRlcyBhIG5ldyB3aWRnZXQgZW50cnkgaW4gdGhlIGRhdGFiYXNlLCBhbmQgYXNzb2NpYXRlcyBpdCB3aXRoIHRoZQoJICogc2lkZWJhci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG5hbWU+CgkgKiA6IFdpZGdldCBuYW1lLgoJICoKCSAqIDxzaWRlYmFyLWlkPgoJICogOiBJRCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgc2lkZWJhci4KCSAqCgkgKiBbPHBvc2l0aW9uPl0KCSAqIDogV2lkZ2V0J3MgY3VycmVudCBwb3NpdGlvbiB3aXRoaW4gdGhlIHNpZGViYXIuIERlZmF1bHRzIHRvIGxhc3QKCSAqCgkgKiBbLS08ZmllbGQ+PTx2YWx1ZT5dCgkgKiA6IFdpZGdldCBvcHRpb24gdG8gYWRkLCB3aXRoIGl0cyBuZXcgdmFsdWUKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEFkZCBhIG5ldyBjYWxlbmRhciB3aWRnZXQgdG8gc2lkZWJhci0xIHdpdGggdGl0bGUgIkNhbGVuZGFyIgoJICogICAgICQgd3Agd2lkZ2V0IGFkZCBjYWxlbmRhciBzaWRlYmFyLTEgMiAtLXRpdGxlPSJDYWxlbmRhciIKCSAqICAgICBTdWNjZXNzOiBBZGRlZCB3aWRnZXQgdG8gc2lkZWJhci4KCSAqCgkgKiBAc3ViY29tbWFuZCBhZGQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGFkZCggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkbmFtZSwgJHNpZGViYXJfaWQgKSA9ICRhcmdzOwoJCSRwb3NpdGlvbiAgICAgICAgICAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhcmdzLCAyLCAxICkgLSAxOwoJCSR0aGlzLT52YWxpZGF0ZV9zaWRlYmFyKCAkc2lkZWJhcl9pZCApOwoKCQkkd2lkZ2V0ID0gJHRoaXMtPmdldF93aWRnZXRfb2JqKCAkbmFtZSApOwoJCWlmICggZmFsc2UgPT09ICR3aWRnZXQgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdJbnZhbGlkIHdpZGdldCB0eXBlLicgKTsKCQl9CgoJCS8qCgkJICogQWRkaW5nIGEgd2lkZ2V0IGlzIGFzIGVhc3kgYXM6CgkJICogMS4gQ3JlYXRpbmcgYSBuZXcgd2lkZ2V0IG9wdGlvbgoJCSAqIDIuIEFkZGluZyB0aGUgd2lkZ2V0IHRvIHRoZSBzaWRlYmFyCgkJICogMy4gUG9zaXRpb25pbmcgYXBwcm9wcmlhdGVseQoJCSAqLwoJCSR3aWRnZXRfb3B0aW9ucyA9ICR0aGlzLT5nZXRfd2lkZ2V0X29wdGlvbnMoICRuYW1lICk7CgkJJG9wdGlvbl9rZXlzICAgID0gJHdpZGdldF9vcHRpb25zOwoJCWlmICggISBpc3NldCggJHdpZGdldF9vcHRpb25zWydfbXVsdGl3aWRnZXQnXSApICkgewoJCQkkd2lkZ2V0X29wdGlvbnNbJ19tdWx0aXdpZGdldCddID0gMTsKCQl9CgkJdW5zZXQoICRvcHRpb25fa2V5c1snX211bHRpd2lkZ2V0J10gKTsKCQkkb3B0aW9uX2tleXMgICAgICAgICAgICAgICAgICAgICA9IGFycmF5X2tleXMoICRvcHRpb25fa2V5cyApOwoJCSRsYXN0X2tleSAgICAgICAgICAgICAgICAgICAgICAgID0gYXJyYXlfcG9wKCAkb3B0aW9uX2tleXMgKTsKCQkkb3B0aW9uX2luZGV4ICAgICAgICAgICAgICAgICAgICA9ICRsYXN0X2tleSArIDE7CgkJJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF0gPSAkdGhpcy0+c2FuaXRpemVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkYXNzb2NfYXJncywgYXJyYXkoKSApOwoJCSR0aGlzLT51cGRhdGVfd2lkZ2V0X29wdGlvbnMoICRuYW1lLCAkd2lkZ2V0X29wdGlvbnMgKTsKCgkJJHdpZGdldF9pZCA9ICRuYW1lIC4gJy0nIC4gJG9wdGlvbl9pbmRleDsKCQkkdGhpcy0+bW92ZV9zaWRlYmFyX3dpZGdldCggJHdpZGdldF9pZCwgbnVsbCwgJHNpZGViYXJfaWQsIG51bGwsICRwb3NpdGlvbiApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdBZGRlZCB3aWRnZXQgdG8gc2lkZWJhci4nICk7CgoJfQoKCS8qKgoJICogVXBkYXRlcyBvcHRpb25zIGZvciBhbiBleGlzdGluZyB3aWRnZXQuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDx3aWRnZXQtaWQ+CgkgKiA6IFVuaXF1ZSBJRCBmb3IgdGhlIHdpZGdldAoJICoKCSAqIFstLTxmaWVsZD49PHZhbHVlPl0KCSAqIDogRmllbGQgdG8gdXBkYXRlLCB3aXRoIGl0cyBuZXcgdmFsdWUKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoYW5nZSBjYWxlbmRhci0xIHdpZGdldCB0aXRsZSB0byAiT3VyIENhbGVuZGFyIgoJICogICAgICQgd3Agd2lkZ2V0IHVwZGF0ZSBjYWxlbmRhci0xIC0tdGl0bGU9Ik91ciBDYWxlbmRhciIKCSAqICAgICBTdWNjZXNzOiBXaWRnZXQgdXBkYXRlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCB1cGRhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHVwZGF0ZSggJGFyZ3MsICRhc3NvY19hcmdzICkgewoKCQlsaXN0KCAkd2lkZ2V0X2lkICkgPSAkYXJnczsKCQlpZiAoICEgJHRoaXMtPnZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJXaWRnZXQgZG9lc24ndCBleGlzdC4iICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkYXNzb2NfYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gb3B0aW9ucyBzcGVjaWZpZWQgdG8gdXBkYXRlLicgKTsKCQl9CgoJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4ICkgPSAkdGhpcy0+Z2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICk7CgoJCSR3aWRnZXRfb3B0aW9ucyAgICAgICAgICAgICAgICAgID0gJHRoaXMtPmdldF93aWRnZXRfb3B0aW9ucyggJG5hbWUgKTsKCQkkY2xlYW5fb3B0aW9ucyAgICAgICAgICAgICAgICAgICA9ICR0aGlzLT5zYW5pdGl6ZV93aWRnZXRfb3B0aW9ucyggJG5hbWUsICRhc3NvY19hcmdzLCAkd2lkZ2V0X29wdGlvbnNbICRvcHRpb25faW5kZXggXSApOwoJCSR3aWRnZXRfb3B0aW9uc1sgJG9wdGlvbl9pbmRleCBdID0gYXJyYXlfbWVyZ2UoIChhcnJheSkgJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF0sICRjbGVhbl9vcHRpb25zICk7CgkJJHRoaXMtPnVwZGF0ZV93aWRnZXRfb3B0aW9ucyggJG5hbWUsICR3aWRnZXRfb3B0aW9ucyApOwoKCQlXUF9DTEk6OnN1Y2Nlc3MoICdXaWRnZXQgdXBkYXRlZC4nICk7CgoJfQoKCS8qKgoJICogTW92ZXMgdGhlIHBvc2l0aW9uIG9mIGEgd2lkZ2V0LgoJICoKCSAqIENoYW5nZXMgdGhlIG9yZGVyIG9mIGEgd2lkZ2V0IGluIGl0cyBleGlzdGluZyBzaWRlYmFyLCBvciBtb3ZlcyBpdCB0byBhCgkgKiBuZXcgc2lkZWJhci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHdpZGdldC1pZD4KCSAqIDogVW5pcXVlIElEIGZvciB0aGUgd2lkZ2V0CgkgKgoJICogWy0tcG9zaXRpb249PHBvc2l0aW9uPl0KCSAqIDogQXNzaWduIHRoZSB3aWRnZXQgdG8gYSBuZXcgcG9zaXRpb24uCgkgKgoJICogWy0tc2lkZWJhci1pZD08c2lkZWJhci1pZD5dCgkgKiA6IEFzc2lnbiB0aGUgd2lkZ2V0IHRvIGEgbmV3IHNpZGViYXIKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIENoYW5nZSBwb3NpdGlvbiBvZiB3aWRnZXQKCSAqICAgICAkIHdwIHdpZGdldCBtb3ZlIHJlY2VudC1jb21tZW50cy0yIC0tcG9zaXRpb249MgoJICogICAgIFN1Y2Nlc3M6IFdpZGdldCBtb3ZlZC4KCSAqCgkgKiAgICAgIyBNb3ZlIHdpZGdldCB0byBJbmFjdGl2ZSBXaWRnZXRzCgkgKiAgICAgJCB3cCB3aWRnZXQgbW92ZSByZWNlbnQtY29tbWVudHMtMiAtLXNpZGViYXItaWQ9d3BfaW5hY3RpdmVfd2lkZ2V0cwoJICogICAgIFN1Y2Nlc3M6IFdpZGdldCBtb3ZlZC4KCSAqCgkgKiBAc3ViY29tbWFuZCBtb3ZlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBtb3ZlKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWxpc3QoICR3aWRnZXRfaWQgKSA9ICRhcmdzOwoJCWlmICggISAkdGhpcy0+dmFsaWRhdGVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggIldpZGdldCBkb2Vzbid0IGV4aXN0LiIgKTsKCQl9CgoJCWlmICggZW1wdHkoICRhc3NvY19hcmdzWydwb3NpdGlvbiddICkgJiYgZW1wdHkoICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ0EgbmV3IHBvc2l0aW9uIG9yIG5ldyBzaWRlYmFyIG11c3QgYmUgc3BlY2lmaWVkLicgKTsKCQl9CgoJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4LCAkY3VycmVudF9zaWRlYmFyX2lkLCAkY3VycmVudF9zaWRlYmFyX2luZGV4ICkgPSAkdGhpcy0+Z2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICk7CgoJCSRuZXdfc2lkZWJhcl9pZCA9ICEgZW1wdHkoICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gKSA/ICRhc3NvY19hcmdzWydzaWRlYmFyLWlkJ10gOiAkY3VycmVudF9zaWRlYmFyX2lkOwoJCSR0aGlzLT52YWxpZGF0ZV9zaWRlYmFyKCAkbmV3X3NpZGViYXJfaWQgKTsKCgkJJG5ld19zaWRlYmFyX2luZGV4ID0gISBlbXB0eSggJGFzc29jX2FyZ3NbJ3Bvc2l0aW9uJ10gKSA/ICRhc3NvY19hcmdzWydwb3NpdGlvbiddIC0gMSA6ICRjdXJyZW50X3NpZGViYXJfaW5kZXg7CgkJLy8gTW92aW5nIGJldHdlZW4gc2lkZWJhcnMgYWRkcyB0byB0aGUgdG9wLgoJCWlmICggJG5ld19zaWRlYmFyX2lkICE9PSAkY3VycmVudF9zaWRlYmFyX2lkICYmICRuZXdfc2lkZWJhcl9pbmRleCA9PT0gJGN1cnJlbnRfc2lkZWJhcl9pbmRleCApIHsKCQkJLy8gSHVtYW4tcmVhZGFibGUgcG9zaXRpb25zIGFyZSBkaWZmZXJlbnQgdGhhbiBudW1lcmljYWxseSBpbmRleGVkIGFycmF5LgoJCQkkbmV3X3NpZGViYXJfaW5kZXggPSAwOwoJCX0KCgkJJHRoaXMtPm1vdmVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQsICRjdXJyZW50X3NpZGViYXJfaWQsICRuZXdfc2lkZWJhcl9pZCwgJGN1cnJlbnRfc2lkZWJhcl9pbmRleCwgJG5ld19zaWRlYmFyX2luZGV4ICk7CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1dpZGdldCBtb3ZlZC4nICk7CgoJfQoKCS8qKgoJICogRGVhY3RpdmF0ZXMgb25lIG9yIG1vcmUgd2lkZ2V0cyBmcm9tIGFuIGFjdGl2ZSBzaWRlYmFyLgoJICoKCSAqIE1vdmVzIHdpZGdldHMgdG8gSW5hY3RpdmUgV2lkZ2V0cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHdpZGdldC1pZD4uLi4KCSAqIDogVW5pcXVlIElEIGZvciB0aGUgd2lkZ2V0KHMpCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWFjdGl2YXRlIHRoZSByZWNlbnQtY29tbWVudHMtMiB3aWRnZXQuCgkgKiAgICAgJCB3cCB3aWRnZXQgZGVhY3RpdmF0ZSByZWNlbnQtY29tbWVudHMtMgoJICogICAgIFN1Y2Nlc3M6IDEgd2lkZ2V0IGRlYWN0aXZhdGVkLgoJICoKCSAqIEBzdWJjb21tYW5kIGRlYWN0aXZhdGUKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGRlYWN0aXZhdGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvdW50ICA9IDA7CgkJJGVycm9ycyA9IDA7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkd2lkZ2V0X2lkICkgewoJCQlpZiAoICEgJHRoaXMtPnZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJXaWRnZXQgJ3skd2lkZ2V0X2lkfScgZG9lc24ndCBleGlzdC4iICk7CgkJCQkkZXJyb3JzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJbGlzdCggJG5hbWUsICRvcHRpb25faW5kZXgsICRzaWRlYmFyX2lkLCAkc2lkZWJhcl9pbmRleCApID0gJHRoaXMtPmdldF93aWRnZXRfZGF0YSggJHdpZGdldF9pZCApOwoJCQlpZiAoICd3cF9pbmFjdGl2ZV93aWRnZXRzJyA9PT0gJHNpZGViYXJfaWQgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoIHNwcmludGYoICInJXMnIGlzIGFscmVhZHkgZGVhY3RpdmF0ZWQuIiwgJHdpZGdldF9pZCApICk7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJJHRoaXMtPm1vdmVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQsICRzaWRlYmFyX2lkLCAnd3BfaW5hY3RpdmVfd2lkZ2V0cycsICRzaWRlYmFyX2luZGV4LCAwICk7CgoJCQkkY291bnQrKzsKCgkJfQoKCQlVdGlsc1xyZXBvcnRfYmF0Y2hfb3BlcmF0aW9uX3Jlc3VsdHMoICd3aWRnZXQnLCAnZGVhY3RpdmF0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgb25lIG9yIG1vcmUgd2lkZ2V0cyBmcm9tIGEgc2lkZWJhci4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPHdpZGdldC1pZD4uLi4KCSAqIDogVW5pcXVlIElEIGZvciB0aGUgd2lkZ2V0KHMpCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBEZWxldGUgdGhlIHJlY2VudC1jb21tZW50cy0yIHdpZGdldCBmcm9tIGl0cyBzaWRlYmFyLgoJICogICAgICQgd3Agd2lkZ2V0IGRlbGV0ZSByZWNlbnQtY29tbWVudHMtMgoJICogICAgIFN1Y2Nlc3M6IERlbGV0ZWQgMSBvZiAxIHdpZGdldHMuCgkgKgoJICogQHN1YmNvbW1hbmQgZGVsZXRlCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCgkJJGNvdW50ICA9IDA7CgkJJGVycm9ycyA9IDA7CgoJCWZvcmVhY2ggKCAkYXJncyBhcyAkd2lkZ2V0X2lkICkgewoJCQlpZiAoICEgJHRoaXMtPnZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgKSB7CgkJCQlXUF9DTEk6Ondhcm5pbmcoICJXaWRnZXQgJ3skd2lkZ2V0X2lkfScgZG9lc24ndCBleGlzdC4iICk7CgkJCQkkZXJyb3JzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gUmVtb3ZlIHRoZSB3aWRnZXQncyBzZXR0aW5ncy4KCQkJbGlzdCggJG5hbWUsICRvcHRpb25faW5kZXgsICRzaWRlYmFyX2lkLCAkc2lkZWJhcl9pbmRleCApID0gJHRoaXMtPmdldF93aWRnZXRfZGF0YSggJHdpZGdldF9pZCApOwoJCQkkd2lkZ2V0X29wdGlvbnMgPSAkdGhpcy0+Z2V0X3dpZGdldF9vcHRpb25zKCAkbmFtZSApOwoJCQl1bnNldCggJHdpZGdldF9vcHRpb25zWyAkb3B0aW9uX2luZGV4IF0gKTsKCQkJJHRoaXMtPnVwZGF0ZV93aWRnZXRfb3B0aW9ucyggJG5hbWUsICR3aWRnZXRfb3B0aW9ucyApOwoKCQkJLy8gUmVtb3ZlIHRoZSB3aWRnZXQgZnJvbSB0aGUgc2lkZWJhci4KCQkJJGFsbF93aWRnZXRzID0gJHRoaXMtPndwX2dldF9zaWRlYmFyc193aWRnZXRzKCk7CgkJCXVuc2V0KCAkYWxsX3dpZGdldHNbICRzaWRlYmFyX2lkIF1bICRzaWRlYmFyX2luZGV4IF0gKTsKCQkJJGFsbF93aWRnZXRzWyAkc2lkZWJhcl9pZCBdID0gYXJyYXlfdmFsdWVzKCAkYWxsX3dpZGdldHNbICRzaWRlYmFyX2lkIF0gKTsKCQkJdXBkYXRlX29wdGlvbiggJ3NpZGViYXJzX3dpZGdldHMnLCAkYWxsX3dpZGdldHMgKTsKCgkJCSRjb3VudCsrOwoJCX0KCgkJVXRpbHNccmVwb3J0X2JhdGNoX29wZXJhdGlvbl9yZXN1bHRzKCAnd2lkZ2V0JywgJ2RlbGV0ZScsIGNvdW50KCAkYXJncyApLCAkY291bnQsICRlcnJvcnMgKTsKCX0KCgkvKioKCSAqIFJlc2V0cyBzaWRlYmFyLgoJICoKCSAqIFJlbW92ZXMgYWxsIHdpZGdldHMgZnJvbSB0aGUgc2lkZWJhciBhbmQgcGxhY2VzIHRoZW0gaW4gSW5hY3RpdmUgV2lkZ2V0cy4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxzaWRlYmFyLWlkPi4uLl0KCSAqIDogT25lIG9yIG1vcmUgc2lkZWJhcnMgdG8gcmVzZXQuCgkgKgoJICogWy0tYWxsXQoJICogOiBJZiBzZXQsIGFsbCBzaWRlYmFycyB3aWxsIGJlIHJlc2V0LgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgUmVzZXQgYSBzaWRlYmFyCgkgKiAgICAgJCB3cCB3aWRnZXQgcmVzZXQgc2lkZWJhci0xCgkgKiAgICAgU3VjY2VzczogU2lkZWJhciAnc2lkZWJhci0xJyByZXNldC4KCSAqCgkgKiAgICAgIyBSZXNldCBtdWx0aXBsZSBzaWRlYmFycwoJICogICAgICQgd3Agd2lkZ2V0IHJlc2V0IHNpZGViYXItMSBzaWRlYmFyLTIKCSAqICAgICBTdWNjZXNzOiBTaWRlYmFyICdzaWRlYmFyLTEnIHJlc2V0LgoJICogICAgIFN1Y2Nlc3M6IFNpZGViYXIgJ3NpZGViYXItMicgcmVzZXQuCgkgKgoJICogICAgICMgUmVzZXQgYWxsIHNpZGViYXJzCgkgKiAgICAgJCB3cCB3aWRnZXQgcmVzZXQgLS1hbGwKCSAqICAgICBTdWNjZXNzOiBTaWRlYmFyICdzaWRlYmFyLTEnIHJlc2V0LgoJICogICAgIFN1Y2Nlc3M6IFNpZGViYXIgJ3NpZGViYXItMicgcmVzZXQuCgkgKiAgICAgU3VjY2VzczogU2lkZWJhciAnc2lkZWJhci0zJyByZXNldC4KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHJlc2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCWdsb2JhbCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFyczsKCgkJJGFsbCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2FsbCcsIGZhbHNlICk7CgoJCS8vIEJhaWwgaWYgbm8gYXJndW1lbnRzIGFuZCBubyBhbGwgZmxhZy4KCQlpZiAoICEgJGFsbCAmJiBlbXB0eSggJGFyZ3MgKSApIHsKCQkJV1BfQ0xJOjplcnJvciggJ1BsZWFzZSBzcGVjaWZ5IG9uZSBvciBtb3JlIHNpZGViYXJzLCBvciB1c2UgLS1hbGwuJyApOwoJCX0KCgkJLy8gRmV0Y2ggYWxsIHNpZGViYXJzIGlmIGFsbCBmbGFnIGlzIHNldC4KCQlpZiAoICRhbGwgKSB7CgkJCSRhcmdzID0gYXJyYXlfa2V5cyggJHdwX3JlZ2lzdGVyZWRfc2lkZWJhcnMgKTsKCQl9CgoJCS8vIFNpZGViYXIgSUQgd3BfaW5hY3RpdmVfd2lkZ2V0cyBpcyByZXNlcnZlZCBieSBXUCBjb3JlIGZvciBpbmFjdGl2ZSB3aWRnZXRzLgoJCWlmICggaXNzZXQoICRhcmdzWyd3cF9pbmFjdGl2ZV93aWRnZXRzJ10gKSApIHsKCQkJdW5zZXQoICRhcmdzWyd3cF9pbmFjdGl2ZV93aWRnZXRzJ10gKTsKCQl9CgoJCS8vIENoZWNrIGlmIG5vIHJlZ2lzdGVyZWQgc2lkZWJhci4KCQlpZiAoIGVtcHR5KCAkYXJncyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnTm8gc2lkZWJhciByZWdpc3RlcmVkLicgKTsKCQl9CgoJCSRjb3VudCAgPSAwOwoJCSRlcnJvcnMgPSAwOwoJCWZvcmVhY2ggKCAkYXJncyBhcyAkc2lkZWJhcl9pZCApIHsKCQkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRzaWRlYmFyX2lkLCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFycyApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAnSW52YWxpZCBzaWRlYmFyOiAlcycsICRzaWRlYmFyX2lkICkgKTsKCQkJCSRlcnJvcnMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkkd2lkZ2V0cyA9ICR0aGlzLT5nZXRfc2lkZWJhcl93aWRnZXRzKCAkc2lkZWJhcl9pZCApOwoJCQlpZiAoIGVtcHR5KCAkd2lkZ2V0cyApICkgewoJCQkJV1BfQ0xJOjp3YXJuaW5nKCBzcHJpbnRmKCAiU2lkZWJhciAnJXMnIGlzIGFscmVhZHkgZW1wdHkuIiwgJHNpZGViYXJfaWQgKSApOwoJCQl9IGVsc2UgewoJCQkJZm9yZWFjaCAoICR3aWRnZXRzIGFzICR3aWRnZXQgKSB7CgkJCQkJJHdpZGdldF9pZCA9ICR3aWRnZXQtPmlkOwoJCQkJCWxpc3QoICRuYW1lLCAkb3B0aW9uX2luZGV4LCAkbmV3X3NpZGViYXJfaWQsICRzaWRlYmFyX2luZGV4ICkgPSAkdGhpcy0+Z2V0X3dpZGdldF9kYXRhKCAkd2lkZ2V0X2lkICk7CgkJCQkJJHRoaXMtPm1vdmVfc2lkZWJhcl93aWRnZXQoICR3aWRnZXRfaWQsICRuZXdfc2lkZWJhcl9pZCwgJ3dwX2luYWN0aXZlX3dpZGdldHMnLCAkc2lkZWJhcl9pbmRleCwgMCApOwoJCQkJfQoJCQkJV1BfQ0xJOjpsb2coIHNwcmludGYoICJTaWRlYmFyICclcycgcmVzZXQuIiwgJHNpZGViYXJfaWQgKSApOwoJCQkJJGNvdW50Kys7CgkJCX0KCQl9CgoJCVV0aWxzXHJlcG9ydF9iYXRjaF9vcGVyYXRpb25fcmVzdWx0cyggJ3NpZGViYXInLCAncmVzZXQnLCBjb3VudCggJGFyZ3MgKSwgJGNvdW50LCAkZXJyb3JzICk7Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciBhIHNpZGViYXIgaXMgYSB2YWxpZCBzaWRlYmFyCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2lkZWJhcl9pZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlX3NpZGViYXIoICRzaWRlYmFyX2lkICkgewoJCWdsb2JhbCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFyczsKCgkJVXRpbHNcd3BfcmVnaXN0ZXJfdW51c2VkX3NpZGViYXIoKTsKCgkJaWYgKCAhIGFycmF5X2tleV9leGlzdHMoICRzaWRlYmFyX2lkLCAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFycyApICkgewoJCQlXUF9DTEk6OmVycm9yKCAnSW52YWxpZCBzaWRlYmFyLicgKTsKCQl9Cgl9CgoJLyoqCgkgKiBDaGVja3Mgd2hldGhlciB0aGUgc3BlY2lmaWVkIHdpZGdldCBpcyBvbiB0aGUgc2lkZWJhcgoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdpZGdldF9pZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHZhbGlkYXRlX3NpZGViYXJfd2lkZ2V0KCAkd2lkZ2V0X2lkICkgewoKCQkkc2lkZWJhcnNfd2lkZ2V0cyA9ICR0aGlzLT53cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpOwoKCQkkd2lkZ2V0X2V4aXN0cyA9IGZhbHNlOwoJCWZvcmVhY2ggKCAkc2lkZWJhcnNfd2lkZ2V0cyBhcyAkc2lkZWJhcl9pZCA9PiAkd2lkZ2V0cyApIHsKCgkJCWlmICggaW5fYXJyYXkoICR3aWRnZXRfaWQsICR3aWRnZXRzLCB0cnVlICkgKSB7CgkJCQkkd2lkZ2V0X2V4aXN0cyA9IHRydWU7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyZXR1cm4gJHdpZGdldF9leGlzdHM7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB3aWRnZXRzIChhbmQgdGhlaXIgYXNzb2NpYXRlZCBkYXRhKSBmb3IgYSBnaXZlbiBzaWRlYmFyCgkgKgoJICogQHBhcmFtIHN0cmluZyAkc2lkZWJhcl9pZAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF9zaWRlYmFyX3dpZGdldHMoICRzaWRlYmFyX2lkICkgewoKCQkkYWxsX3dpZGdldHMgPSAkdGhpcy0+d3BfZ2V0X3NpZGViYXJzX3dpZGdldHMoKTsKCgkJaWYgKCBlbXB0eSggJGFsbF93aWRnZXRzWyAkc2lkZWJhcl9pZCBdICkgKSB7CgkJCXJldHVybiBhcnJheSgpOwoJCX0KCgkJJHByZXBhcmVkX3dpZGdldHMgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCAkYWxsX3dpZGdldHNbICRzaWRlYmFyX2lkIF0gYXMgJGtleSA9PiAkd2lkZ2V0X2lkICkgewoKCQkJJHByZXBhcmVkX3dpZGdldCA9IG5ldyBzdGRDbGFzcygpOwoKCQkJJHBhcnRzICAgICAgICA9IGV4cGxvZGUoICctJywgJHdpZGdldF9pZCApOwoJCQkkb3B0aW9uX2luZGV4ID0gYXJyYXlfcG9wKCAkcGFydHMgKTsKCQkJJHdpZGdldF9uYW1lICA9IGltcGxvZGUoICctJywgJHBhcnRzICk7CgoJCQkkcHJlcGFyZWRfd2lkZ2V0LT5uYW1lICAgICA9ICR3aWRnZXRfbmFtZTsKCQkJJHByZXBhcmVkX3dpZGdldC0+aWQgICAgICAgPSAkd2lkZ2V0X2lkOwoJCQkkcHJlcGFyZWRfd2lkZ2V0LT5wb3NpdGlvbiA9ICRrZXkgKyAxOwoJCQkkd2lkZ2V0X29wdGlvbnMgICAgICAgICAgICA9IGdldF9vcHRpb24oICd3aWRnZXRfJyAuICR3aWRnZXRfbmFtZSApOwoJCQkkcHJlcGFyZWRfd2lkZ2V0LT5vcHRpb25zICA9ICR3aWRnZXRfb3B0aW9uc1sgJG9wdGlvbl9pbmRleCBdOwoKCQkJJHByZXBhcmVkX3dpZGdldHNbXSA9ICRwcmVwYXJlZF93aWRnZXQ7CgkJfQoKCQlyZXR1cm4gJHByZXBhcmVkX3dpZGdldHM7Cgl9CgoJLyoqCgkgKiBSZS1pbXBsZW1lbnRhdGlvbiBvZiB3cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpCgkgKiBiZWNhdXNlIHRoZSBvcmlnaW5hbCBoYXMgYSBuYXN0eSBnbG9iYWwgY29tcG9uZW50CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gd3BfZ2V0X3NpZGViYXJzX3dpZGdldHMoKSB7CgkJJHNpZGViYXJzX3dpZGdldHMgPSBnZXRfb3B0aW9uKCAnc2lkZWJhcnNfd2lkZ2V0cycsIGFycmF5KCkgKTsKCgkJaWYgKCBpc19hcnJheSggJHNpZGViYXJzX3dpZGdldHMgKSAmJiBpc3NldCggJHNpZGViYXJzX3dpZGdldHNbJ2FycmF5X3ZlcnNpb24nXSApICkgewoJCQl1bnNldCggJHNpZGViYXJzX3dpZGdldHNbJ2FycmF5X3ZlcnNpb24nXSApOwoJCX0KCgkJcmV0dXJuICRzaWRlYmFyc193aWRnZXRzOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgd2lkZ2V0J3MgbmFtZSwgb3B0aW9uIGluZGV4LCBzaWRlYmFyLCBhbmQgc2lkZWJhciBpbmRleCBmcm9tIGl0cyBJRAoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJHdpZGdldF9pZAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF93aWRnZXRfZGF0YSggJHdpZGdldF9pZCApIHsKCgkJJHBhcnRzICAgICAgICA9IGV4cGxvZGUoICctJywgJHdpZGdldF9pZCApOwoJCSRvcHRpb25faW5kZXggPSBhcnJheV9wb3AoICRwYXJ0cyApOwoJCSRuYW1lICAgICAgICAgPSBpbXBsb2RlKCAnLScsICRwYXJ0cyApOwoKCQkkc2lkZWJhcl9pZCAgICA9IGZhbHNlOwoJCSRzaWRlYmFyX2luZGV4ID0gZmFsc2U7CgkJJGFsbF93aWRnZXRzICAgPSAkdGhpcy0+d3BfZ2V0X3NpZGViYXJzX3dpZGdldHMoKTsKCQlmb3JlYWNoICggJGFsbF93aWRnZXRzIGFzICRzX2lkID0+ICYkd2lkZ2V0cyApIHsKCgkJCSRrZXkgPSBhcnJheV9zZWFyY2goICR3aWRnZXRfaWQsICR3aWRnZXRzLCB0cnVlICk7CgkJCWlmICggZmFsc2UgIT09ICRrZXkgKSB7CgkJCQkkc2lkZWJhcl9pZCAgICA9ICRzX2lkOwoJCQkJJHNpZGViYXJfaW5kZXggPSAka2V5OwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXJldHVybiBhcnJheSggJG5hbWUsICRvcHRpb25faW5kZXgsICRzaWRlYmFyX2lkLCAkc2lkZWJhcl9pbmRleCApOwoJfQoKCS8qKgoJICogR2V0cyB0aGUgb3B0aW9ucyBmb3IgYSBnaXZlbiB3aWRnZXQKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRuYW1lCgkgKiBAcmV0dXJuIGFycmF5CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X3dpZGdldF9vcHRpb25zKCAkbmFtZSApIHsKCQlyZXR1cm4gZ2V0X29wdGlvbiggJ3dpZGdldF8nIC4gJG5hbWUsIGFycmF5KCkgKTsKCX0KCgkvKioKCSAqIFVwZGF0ZXMgdGhlIG9wdGlvbnMgZm9yIGEgZ2l2ZW4gd2lkZ2V0CgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICogQHBhcmFtIG1peGVkCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gdXBkYXRlX3dpZGdldF9vcHRpb25zKCAkbmFtZSwgJHZhbHVlICkgewoJCXVwZGF0ZV9vcHRpb24oICd3aWRnZXRfJyAuICRuYW1lLCAkdmFsdWUgKTsKCX0KCgkvKioKCSAqIFJlcG9zaXRpb25zIGEgd2lkZ2V0IHdpdGhpbiBhIHNpZGViYXIgb3IgbW92ZSB0byBhbm90aGVyIHNpZGViYXIuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkd2lkZ2V0X2lkCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGN1cnJlbnRfc2lkZWJhcl9pZAoJICogQHBhcmFtIHN0cmluZyAkbmV3X3NpZGViYXJfaWQKCSAqIEBwYXJhbSBpbnR8bnVsbCAkY3VycmVudF9pbmRleAoJICogQHBhcmFtIGludCAkbmV3X2luZGV4CgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gbW92ZV9zaWRlYmFyX3dpZGdldCggJHdpZGdldF9pZCwgJGN1cnJlbnRfc2lkZWJhcl9pZCwgJG5ld19zaWRlYmFyX2lkLCAkY3VycmVudF9pbmRleCwgJG5ld19pbmRleCApIHsKCgkJJGFsbF93aWRnZXRzICAgICA9ICR0aGlzLT53cF9nZXRfc2lkZWJhcnNfd2lkZ2V0cygpOwoJCSRuZWVkc19wbGFjZW1lbnQgPSB0cnVlOwoJCS8vIEV4aXN0aW5nIHdpZGdldAoJCWlmICggJGN1cnJlbnRfc2lkZWJhcl9pZCAmJiAhIGlzX251bGwoICRjdXJyZW50X2luZGV4ICkgKSB7CgoJCQkkd2lkZ2V0cyA9ICRhbGxfd2lkZ2V0c1sgJGN1cnJlbnRfc2lkZWJhcl9pZCBdOwoJCQlpZiAoICRjdXJyZW50X3NpZGViYXJfaWQgIT09ICRuZXdfc2lkZWJhcl9pZCApIHsKCgkJCQl1bnNldCggJHdpZGdldHNbICRjdXJyZW50X2luZGV4IF0gKTsKCgkJCX0gZWxzZSB7CgoJCQkJJHBhcnQgPSBhcnJheV9zcGxpY2UoICR3aWRnZXRzLCAkY3VycmVudF9pbmRleCwgMSApOwoJCQkJYXJyYXlfc3BsaWNlKCAkd2lkZ2V0cywgJG5ld19pbmRleCwgMCwgJHBhcnQgKTsKCgkJCQkkbmVlZHNfcGxhY2VtZW50ID0gZmFsc2U7CgoJCQl9CgoJCQkkYWxsX3dpZGdldHNbICRjdXJyZW50X3NpZGViYXJfaWQgXSA9IGFycmF5X3ZhbHVlcyggJHdpZGdldHMgKTsKCgkJfQoKCQlpZiAoICRuZWVkc19wbGFjZW1lbnQgKSB7CgkJCSR3aWRnZXRzICAgICAgICAgICAgICAgICAgICAgICAgPSAhIGVtcHR5KCAkYWxsX3dpZGdldHNbICRuZXdfc2lkZWJhcl9pZCBdICkgPyAkYWxsX3dpZGdldHNbICRuZXdfc2lkZWJhcl9pZCBdIDogYXJyYXkoKTsKCQkJJGJlZm9yZSAgICAgICAgICAgICAgICAgICAgICAgICA9IGFycmF5X3NsaWNlKCAkd2lkZ2V0cywgMCwgJG5ld19pbmRleCwgdHJ1ZSApOwoJCQkkYWZ0ZXIgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXJyYXlfc2xpY2UoICR3aWRnZXRzLCAkbmV3X2luZGV4LCBjb3VudCggJHdpZGdldHMgKSwgdHJ1ZSApOwoJCQkkd2lkZ2V0cyAgICAgICAgICAgICAgICAgICAgICAgID0gYXJyYXlfbWVyZ2UoICRiZWZvcmUsIGFycmF5KCAkd2lkZ2V0X2lkICksICRhZnRlciApOwoJCQkkYWxsX3dpZGdldHNbICRuZXdfc2lkZWJhcl9pZCBdID0gYXJyYXlfdmFsdWVzKCAkd2lkZ2V0cyApOwoJCX0KCgkJdXBkYXRlX29wdGlvbiggJ3NpZGViYXJzX3dpZGdldHMnLCAkYWxsX3dpZGdldHMgKTsKCgl9CgoJLyoqCgkgKiBHZXRzIGEgd2lkZ2V0J3MgaW5zdGFudGlhdGVkIG9iamVjdCBiYXNlZCBvbiBpdHMgbmFtZQoJICoKCSAqIEBwYXJhbSBzdHJpbmcgJGlkX2Jhc2UgTmFtZSBvZiB0aGUgd2lkZ2V0CgkgKiBAcmV0dXJuIFdQX1dpZGdldHxmYWxzZQoJICovCglwcml2YXRlIGZ1bmN0aW9uIGdldF93aWRnZXRfb2JqKCAkaWRfYmFzZSApIHsKCQlnbG9iYWwgJHdwX3dpZGdldF9mYWN0b3J5OwoKCQkkd2lkZ2V0ID0gd3BfZmlsdGVyX29iamVjdF9saXN0KCAkd3Bfd2lkZ2V0X2ZhY3RvcnktPndpZGdldHMsIGFycmF5KCAnaWRfYmFzZScgPT4gJGlkX2Jhc2UgKSApOwoJCWlmICggZW1wdHkoICR3aWRnZXQgKSApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcmV0dXJuIGFycmF5X3BvcCggJHdpZGdldCApOwoJfQoKCS8qKgoJICogQ2xlYW5zIHVwIGEgd2lkZ2V0J3Mgb3B0aW9ucyBiYXNlZCBvbiBpdHMgdXBkYXRlIGNhbGxiYWNrCgkgKgoJICogQHBhcmFtIHN0cmluZyAkaWRfYmFzZSBOYW1lIG9mIHRoZSB3aWRnZXQKCSAqIEBwYXJhbSBtaXhlZCAkZGlydHlfb3B0aW9ucwoJICogQHBhcmFtIG1peGVkICRvbGRfb3B0aW9ucwoJICogQHJldHVybiBtaXhlZAoJICovCglwcml2YXRlIGZ1bmN0aW9uIHNhbml0aXplX3dpZGdldF9vcHRpb25zKCAkaWRfYmFzZSwgJGRpcnR5X29wdGlvbnMsICRvbGRfb3B0aW9ucyApIHsKCgkJJHdpZGdldCA9ICR0aGlzLT5nZXRfd2lkZ2V0X29iaiggJGlkX2Jhc2UgKTsKCQlpZiAoIGVtcHR5KCAkd2lkZ2V0ICkgKSB7CgkJCXJldHVybiBhcnJheSgpOwoJCX0KCgkJLy8gTm8gZWFzeSB3YXkgdG8gZGV0ZXJtaW5lIGV4cGVjdGVkIGFycmF5IGtleXMgZm9yICRkaXJ0eV9vcHRpb25zCgkJLy8gYmVjYXVzZSBXaWRnZXQgQVBJIGRlcGVuZGVudCBvbiB0aGUgZm9ybSBmaWVsZHMKCQkvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlBIUC5Ob1NpbGVuY2VkRXJyb3JzLkRpc2NvdXJhZ2VkIC0tIFdoaXRlbGlzdGluZyBkdWUgdG8gYWJvdmUgcmVhc29uLgoJCXJldHVybiBAJHdpZGdldC0+dXBkYXRlKCAkZGlydHlfb3B0aW9ucywgJG9sZF9vcHRpb25zICk7CgoJfQoKfQo8P3BocAoKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxGb3JtYXR0ZXI7CgovKioKICogTGlzdHMgcmVnaXN0ZXJlZCBzaWRlYmFycy4KICoKICogQSBbc2lkZWJhcl0oaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy90aGVtZXMvZnVuY3Rpb25hbGl0eS9zaWRlYmFycy8pIGlzIGFueSB3aWRnZXRpemVkIGFyZWEgb2YgeW91ciB0aGVtZS4KICoKICogIyMgRVhBTVBMRVMKICoKICogICAgICMgTGlzdCBzaWRlYmFycwogKiAgICAgJCB3cCBzaWRlYmFyIGxpc3QgLS1maWVsZHM9bmFtZSxpZCAtLWZvcm1hdD1jc3YKICogICAgIG5hbWUsaWQKICogICAgICJXaWRnZXQgQXJlYSIsc2lkZWJhci0xCiAqICAgICAiSW5hY3RpdmUgV2lkZ2V0cyIsd3BfaW5hY3RpdmVfd2lkZ2V0cwogKi8KY2xhc3MgU2lkZWJhcl9Db21tYW5kIGV4dGVuZHMgV1BfQ0xJX0NvbW1hbmQgewoKCXByaXZhdGUgJGZpZWxkcyA9IFsKCQknbmFtZScsCgkJJ2lkJywKCQknZGVzY3JpcHRpb24nLAoJXTsKCgkvKioKCSAqIExpc3RzIHJlZ2lzdGVyZWQgc2lkZWJhcnMuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFstLWZpZWxkcz08ZmllbGRzPl0KCSAqIDogTGltaXQgdGhlIG91dHB1dCB0byBzcGVjaWZpYyBvYmplY3QgZmllbGRzLgoJICoKCSAqIFstLWZvcm1hdD08Zm9ybWF0Pl0KCSAqIDogUmVuZGVyIG91dHB1dCBpbiBhIHBhcnRpY3VsYXIgZm9ybWF0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB0YWJsZQoJICogb3B0aW9uczoKCSAqICAgLSB0YWJsZQoJICogICAtIGNzdgoJICogICAtIGpzb24KCSAqICAgLSBpZHMKCSAqICAgLSBjb3VudAoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEFWQUlMQUJMRSBGSUVMRFMKCSAqCgkgKiBUaGVzZSBmaWVsZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCBzaWRlYmFyOgoJICoKCSAqICogbmFtZQoJICogKiBpZAoJICogKiBkZXNjcmlwdGlvbgoJICoKCSAqIFRoZXNlIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBhdmFpbGFibGU6CgkgKgoJICogKiBjbGFzcwoJICogKiBiZWZvcmVfd2lkZ2V0CgkgKiAqIGFmdGVyX3dpZGdldAoJICogKiBiZWZvcmVfdGl0bGUKCSAqICogYWZ0ZXJfdGl0bGUKCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAkIHdwIHNpZGViYXIgbGlzdCAtLWZpZWxkcz1uYW1lLGlkIC0tZm9ybWF0PWNzdgoJICogICAgIG5hbWUsaWQKCSAqICAgICAiV2lkZ2V0IEFyZWEiLHNpZGViYXItMQoJICogICAgICJJbmFjdGl2ZSBXaWRnZXRzIix3cF9pbmFjdGl2ZV93aWRnZXRzCgkgKgoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQlnbG9iYWwgJHdwX3JlZ2lzdGVyZWRfc2lkZWJhcnM7CgoJCVV0aWxzXHdwX3JlZ2lzdGVyX3VudXNlZF9zaWRlYmFyKCk7CgoJCWlmICggISBlbXB0eSggJGFzc29jX2FyZ3NbJ2Zvcm1hdCddICkgJiYgJ2lkcycgPT09ICRhc3NvY19hcmdzWydmb3JtYXQnXSApIHsKCQkJJHNpZGViYXJzID0gd3BfbGlzdF9wbHVjayggJHdwX3JlZ2lzdGVyZWRfc2lkZWJhcnMsICdpZCcgKTsKCQl9IGVsc2UgewoJCQkkc2lkZWJhcnMgPSAkd3BfcmVnaXN0ZXJlZF9zaWRlYmFyczsKCQl9CgoJCSRmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKCAkYXNzb2NfYXJncywgJHRoaXMtPmZpZWxkcyApOwoJCSRmb3JtYXR0ZXItPmRpc3BsYXlfaXRlbXMoICRzaWRlYmFycyApOwoJfQoKfQo8P3BocAoKaWYgKCAhIGNsYXNzX2V4aXN0cyggJ1dQX0NMSScgKSApIHsKCXJldHVybjsKfQoKJHdwY2xpX2NvbmZpZ19hdXRvbG9hZGVyID0gZGlybmFtZSggX19GSUxFX18gKSAuICcvdmVuZG9yL2F1dG9sb2FkLnBocCc7CmlmICggZmlsZV9leGlzdHMoICR3cGNsaV9jb25maWdfYXV0b2xvYWRlciApICkgewoJcmVxdWlyZV9vbmNlICR3cGNsaV9jb25maWdfYXV0b2xvYWRlcjsKfQoKV1BfQ0xJOjphZGRfY29tbWFuZCggJ2NvbmZpZycsICdDb25maWdfQ29tbWFuZCcgKTsKPD9waHAKCnVzZSBXUF9DTElcRXhpdEV4Y2VwdGlvbjsKdXNlIFdQX0NMSVxVdGlsczsKdXNlIFdQX0NMSVxXcE9yZ0FwaTsKCi8qKgogKiBHZW5lcmF0ZXMgYW5kIHJlYWRzIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCiAqLwpjbGFzcyBDb25maWdfQ29tbWFuZCBleHRlbmRzIFdQX0NMSV9Db21tYW5kIHsKCgkvKioKCSAqIExpc3Qgb2YgY2hhcmFjdGVycyB0aGF0IGFyZSB2YWxpZCBmb3IgYSBrZXkgbmFtZS4KCSAqCgkgKiBAdmFyIHN0cmluZwoJICovCgljb25zdCBWQUxJRF9LRVlfQ0hBUkFDVEVSUyA9ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OSFAIyQlXiYqKCktXyBbXXt9PD5+YCs9LC47Oi8/fCc7CgoJLyoqCgkgKiBMaXN0IG9mIGRlZmF1bHQgY29uc3RhbnRzIHRoYXQgYXJlIGdlbmVyYXRlZCBieSBXb3JkUHJlc3MgQ29yZS4KCSAqCgkgKiBAc3RyaW5nCgkgKi8KCWNvbnN0IERFRkFVTFRfU0FMVF9DT05TVEFOVFMgPSBbCgkJJ0FVVEhfS0VZJywKCQknU0VDVVJFX0FVVEhfS0VZJywKCQknTE9HR0VEX0lOX0tFWScsCgkJJ05PTkNFX0tFWScsCgkJJ0FVVEhfU0FMVCcsCgkJJ1NFQ1VSRV9BVVRIX1NBTFQnLAoJCSdMT0dHRURfSU5fU0FMVCcsCgkJJ05PTkNFX1NBTFQnLAoJXTsKCgkvKioKCSAqIFJldHJpZXZlIHRoZSBpbml0aWFsIGxvY2FsZSBmcm9tIHRoZSBXb3JkUHJlc3MgdmVyc2lvbiBmaWxlLgoJICoKCSAqIEByZXR1cm4gc3RyaW5nIEluaXRpYWwgbG9jYWxlIGlmIHByZXNlbnQsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub3QuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldF9pbml0aWFsX2xvY2FsZSgpIHsKCQlnbG9iYWwgJHdwX2xvY2FsX3BhY2thZ2U7CgoJCWluY2x1ZGUgQUJTUEFUSCAuICcvd3AtaW5jbHVkZXMvdmVyc2lvbi5waHAnOwoKCQlpZiAoICEgZW1wdHkoICR3cF9sb2NhbF9wYWNrYWdlICkgKSB7CgkJCXJldHVybiAkd3BfbG9jYWxfcGFja2FnZTsKCQl9CgoJCXJldHVybiAnJzsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBhIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBDcmVhdGVzIGEgbmV3IHdwLWNvbmZpZy5waHAgd2l0aCBkYXRhYmFzZSBjb25zdGFudHMsIGFuZCB2ZXJpZmllcyB0aGF0CgkgKiB0aGUgZGF0YWJhc2UgY29uc3RhbnRzIGFyZSBjb3JyZWN0LgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiAtLWRibmFtZT08ZGJuYW1lPgoJICogOiBTZXQgdGhlIGRhdGFiYXNlIG5hbWUuCgkgKgoJICogLS1kYnVzZXI9PGRidXNlcj4KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSB1c2VyLgoJICoKCSAqIFstLWRicGFzcz08ZGJwYXNzPl0KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSB1c2VyIHBhc3N3b3JkLgoJICoKCSAqIFstLWRiaG9zdD08ZGJob3N0Pl0KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSBob3N0LgoJICogLS0tCgkgKiBkZWZhdWx0OiBsb2NhbGhvc3QKCSAqIC0tLQoJICoKCSAqIFstLWRicHJlZml4PTxkYnByZWZpeD5dCgkgKiA6IFNldCB0aGUgZGF0YWJhc2UgdGFibGUgcHJlZml4LgoJICogLS0tCgkgKiBkZWZhdWx0OiB3cF8KCSAqIC0tLQoJICoKCSAqIFstLWRiY2hhcnNldD08ZGJjaGFyc2V0Pl0KCSAqIDogU2V0IHRoZSBkYXRhYmFzZSBjaGFyc2V0LgoJICogLS0tCgkgKiBkZWZhdWx0OiB1dGY4CgkgKiAtLS0KCSAqCgkgKiBbLS1kYmNvbGxhdGU9PGRiY29sbGF0ZT5dCgkgKiA6IFNldCB0aGUgZGF0YWJhc2UgY29sbGF0aW9uLgoJICogLS0tCgkgKiBkZWZhdWx0OgoJICogLS0tCgkgKgoJICogWy0tbG9jYWxlPTxsb2NhbGU+XQoJICogOiBTZXQgdGhlIFdQTEFORyBjb25zdGFudC4gRGVmYXVsdHMgdG8gJHdwX2xvY2FsX3BhY2thZ2UgdmFyaWFibGUuCgkgKgoJICogWy0tZXh0cmEtcGhwXQoJICogOiBJZiBzZXQsIHRoZSBjb21tYW5kIGNvcGllcyBhZGRpdGlvbmFsIFBIUCBjb2RlIGludG8gd3AtY29uZmlnLnBocCBmcm9tIFNURElOLgoJICoKCSAqIFstLXNraXAtc2FsdHNdCgkgKiA6IElmIHNldCwga2V5cyBhbmQgc2FsdHMgd29uJ3QgYmUgZ2VuZXJhdGVkLCBidXQgc2hvdWxkIGluc3RlYWQgYmUgcGFzc2VkIHZpYSBgLS1leHRyYS1waHBgLgoJICoKCSAqIFstLXNraXAtY2hlY2tdCgkgKiA6IElmIHNldCwgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gaXMgbm90IGNoZWNrZWQuCgkgKgoJICogWy0tZm9yY2VdCgkgKiA6IE92ZXJ3cml0ZXMgZXhpc3RpbmcgZmlsZXMsIGlmIHByZXNlbnQuCgkgKgoJICogWy0taW5zZWN1cmVdCgkgKiA6IFJldHJ5IEFQSSBkb3dubG9hZCB3aXRob3V0IGNlcnRpZmljYXRlIHZhbGlkYXRpb24gaWYgVExTIGhhbmRzaGFrZSBmYWlscy4gTm90ZTogVGhpcyBtYWtlcyB0aGUgcmVxdWVzdCB2dWxuZXJhYmxlIHRvIGEgTUlUTSBhdHRhY2suCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTdGFuZGFyZCB3cC1jb25maWcucGhwIGZpbGUKCSAqICAgICAkIHdwIGNvbmZpZyBjcmVhdGUgLS1kYm5hbWU9dGVzdGluZyAtLWRidXNlcj13cCAtLWRicGFzcz1zZWN1cmVwc3dkIC0tbG9jYWxlPXJvX1JPCgkgKiAgICAgU3VjY2VzczogR2VuZXJhdGVkICd3cC1jb25maWcucGhwJyBmaWxlLgoJICoKCSAqICAgICAjIEVuYWJsZSBXUF9ERUJVRyBhbmQgV1BfREVCVUdfTE9HCgkgKiAgICAgJCB3cCBjb25maWcgY3JlYXRlIC0tZGJuYW1lPXRlc3RpbmcgLS1kYnVzZXI9d3AgLS1kYnBhc3M9c2VjdXJlcHN3ZCAtLWV4dHJhLXBocCA8PFBIUAoJICogICAgIGRlZmluZSggJ1dQX0RFQlVHJywgdHJ1ZSApOwoJICogICAgIGRlZmluZSggJ1dQX0RFQlVHX0xPRycsIHRydWUgKTsKCSAqICAgICBQSFAKCSAqICAgICBTdWNjZXNzOiBHZW5lcmF0ZWQgJ3dwLWNvbmZpZy5waHAnIGZpbGUuCgkgKgoJICogICAgICMgQXZvaWQgZGlzY2xvc2luZyBwYXNzd29yZCB0byBiYXNoIGhpc3RvcnkgYnkgcmVhZGluZyBmcm9tIHBhc3N3b3JkLnR4dAoJICogICAgICMgVXNpbmcgLS1wcm9tcHQ9ZGJwYXNzIHdpbGwgcHJvbXB0IGZvciB0aGUgJ2RicGFzcycgYXJndW1lbnQKCSAqICAgICAkIHdwIGNvbmZpZyBjcmVhdGUgLS1kYm5hbWU9dGVzdGluZyAtLWRidXNlcj13cCAtLXByb21wdD1kYnBhc3MgPCBwYXNzd29yZC50eHQKCSAqICAgICBTdWNjZXNzOiBHZW5lcmF0ZWQgJ3dwLWNvbmZpZy5waHAnIGZpbGUuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBjcmVhdGUoICRfLCAkYXNzb2NfYXJncyApIHsKCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZm9yY2UnICkgJiYgVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpICkgewoJCQlXUF9DTEk6OmVycm9yKCAiVGhlICd3cC1jb25maWcucGhwJyBmaWxlIGFscmVhZHkgZXhpc3RzLiIgKTsKCQl9CgoJCSRkZWZhdWx0cyAgID0gWwoJCQknZGJob3N0JyAgICA9PiAnbG9jYWxob3N0JywKCQkJJ2RicGFzcycgICAgPT4gJycsCgkJCSdkYnByZWZpeCcgID0+ICd3cF8nLAoJCQknZGJjaGFyc2V0JyA9PiAndXRmOCcsCgkJCSdkYmNvbGxhdGUnID0+ICcnLAoJCQknbG9jYWxlJyAgICA9PiBzZWxmOjpnZXRfaW5pdGlhbF9sb2NhbGUoKSwKCQldOwoJCSRhc3NvY19hcmdzID0gYXJyYXlfbWVyZ2UoICRkZWZhdWx0cywgJGFzc29jX2FyZ3MgKTsKCgkJaWYgKCBwcmVnX21hdGNoKCAnfFteYS16MC05X118aScsICRhc3NvY19hcmdzWydkYnByZWZpeCddICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICctLWRicHJlZml4IGNhbiBvbmx5IGNvbnRhaW4gbnVtYmVycywgbGV0dGVycywgYW5kIHVuZGVyc2NvcmVzLicgKTsKCQl9CgoJCSRteXNxbF9kYl9jb25uZWN0aW9uX2FyZ3MgPSBbCgkJCSdleGVjdXRlJyA9PiAnOycsCgkJCSdob3N0JyAgICA9PiAkYXNzb2NfYXJnc1snZGJob3N0J10sCgkJCSd1c2VyJyAgICA9PiAkYXNzb2NfYXJnc1snZGJ1c2VyJ10sCgkJCSdwYXNzJyAgICA9PiAkYXNzb2NfYXJnc1snZGJwYXNzJ10sCgkJXTsKCgkJLy8gQ2hlY2sgREIgY29ubmVjdGlvbi4KCQlpZiAoICEgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnc2tpcC1jaGVjaycgKSApIHsKCQkJVXRpbHNccnVuX215c3FsX2NvbW1hbmQoICcvdXNyL2Jpbi9lbnYgbXlzcWwgLS1uby1kZWZhdWx0cycsICRteXNxbF9kYl9jb25uZWN0aW9uX2FyZ3MgKTsKCQl9CgoJCWlmICggVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnZXh0cmEtcGhwJyApID09PSB0cnVlICkgewoJCQkkYXNzb2NfYXJnc1snZXh0cmEtcGhwJ10gPSBmaWxlX2dldF9jb250ZW50cyggJ3BocDovL3N0ZGluJyApOwoJCX0KCgkJaWYgKCAhIFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3NraXAtc2FsdHMnICkgKSB7CgkJCXRyeSB7CgkJCQkkYXNzb2NfYXJnc1sna2V5cy1hbmQtc2FsdHMnXSAgICA9IHRydWU7CgkJCQkkYXNzb2NfYXJnc1snYXV0aC1rZXknXSAgICAgICAgICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWydzZWN1cmUtYXV0aC1rZXknXSAgID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQkJJGFzc29jX2FyZ3NbJ2xvZ2dlZC1pbi1rZXknXSAgICAgPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCQkkYXNzb2NfYXJnc1snbm9uY2Uta2V5J10gICAgICAgICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWydhdXRoLXNhbHQnXSAgICAgICAgID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQkJJGFzc29jX2FyZ3NbJ3NlY3VyZS1hdXRoLXNhbHQnXSAgPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCQkkYXNzb2NfYXJnc1snbG9nZ2VkLWluLXNhbHQnXSAgICA9IHNlbGY6OnVuaXF1ZV9rZXkoKTsKCQkJCSRhc3NvY19hcmdzWydub25jZS1zYWx0J10gICAgICAgID0gc2VsZjo6dW5pcXVlX2tleSgpOwoJCQkJJGFzc29jX2FyZ3NbJ3dwLWNhY2hlLWtleS1zYWx0J10gPSBzZWxmOjp1bmlxdWVfa2V5KCk7CgkJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGUgKSB7CgkJCQkkYXNzb2NfYXJnc1sna2V5cy1hbmQtc2FsdHMnXSAgICAgPSBmYWxzZTsKCQkJCSRhc3NvY19hcmdzWydrZXlzLWFuZC1zYWx0cy1hbHQnXSA9IHNlbGY6OmZldGNoX3JlbW90ZV9zYWx0cygKCQkJCQkoYm9vbCkgVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAnaW5zZWN1cmUnLCBmYWxzZSApCgkJCQkpOwoJCQl9CgkJfQoKCQlpZiAoIFV0aWxzXHdwX3ZlcnNpb25fY29tcGFyZSggJzQuMCcsICc8JyApICkgewoJCQkkYXNzb2NfYXJnc1snYWRkLXdwbGFuZyddID0gdHJ1ZTsKCQl9IGVsc2UgewoJCQkkYXNzb2NfYXJnc1snYWRkLXdwbGFuZyddID0gZmFsc2U7CgkJfQoKCQkkY29tbWFuZF9yb290ID0gVXRpbHNccGhhcl9zYWZlX3BhdGgoIGRpcm5hbWUoIF9fRElSX18gKSApOwoJCSRvdXQgICAgICAgICAgPSBVdGlsc1xtdXN0YWNoZV9yZW5kZXIoICJ7JGNvbW1hbmRfcm9vdH0vdGVtcGxhdGVzL3dwLWNvbmZpZy5tdXN0YWNoZSIsICRhc3NvY19hcmdzICk7CgoJCSRieXRlc193cml0dGVuID0gZmlsZV9wdXRfY29udGVudHMoIEFCU1BBVEggLiAnd3AtY29uZmlnLnBocCcsICRvdXQgKTsKCQlpZiAoICEgJGJ5dGVzX3dyaXR0ZW4gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgY3JlYXRlIG5ldyAnd3AtY29uZmlnLnBocCcgZmlsZS4iICk7CgkJfSBlbHNlIHsKCQkJV1BfQ0xJOjpzdWNjZXNzKCAiR2VuZXJhdGVkICd3cC1jb25maWcucGhwJyBmaWxlLiIgKTsKCQl9Cgl9CgoJLyoqCgkgKiBMYXVuY2hlcyBzeXN0ZW0gZWRpdG9yIHRvIGVkaXQgdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIExhdW5jaCBzeXN0ZW0gZWRpdG9yIHRvIGVkaXQgd3AtY29uZmlnLnBocCBmaWxlCgkgKiAgICAgJCB3cCBjb25maWcgZWRpdAoJICoKCSAqICAgICAjIEVkaXQgd3AtY29uZmlnLnBocCBmaWxlIGluIGEgc3BlY2lmaWMgZWRpdG9yCgkgKiAgICAgJCBFRElUT1I9dmltIHdwIGNvbmZpZyBlZGl0CgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIGVkaXQoKSB7CgkJJGNvbmZpZ19wYXRoID0gJHRoaXMtPmdldF9jb25maWdfcGF0aCgpOwoJCSRjb250ZW50cyAgICA9IGZpbGVfZ2V0X2NvbnRlbnRzKCAkY29uZmlnX3BhdGggKTsKCQkkciAgICAgICAgICAgPSBVdGlsc1xsYXVuY2hfZWRpdG9yX2Zvcl9pbnB1dCggJGNvbnRlbnRzLCAnd3AtY29uZmlnLnBocCcsICdwaHAnICk7CgkJaWYgKCBmYWxzZSA9PT0gJHIgKSB7CgkJCVdQX0NMSTo6d2FybmluZyggJ05vIGNoYW5nZXMgbWFkZSB0byB3cC1jb25maWcucGhwLCBhYm9ydGVkLicgKTsKCQl9IGVsc2UgewoJCQlmaWxlX3B1dF9jb250ZW50cyggJGNvbmZpZ19wYXRoLCAkciApOwoJCX0KCX0KCgkvKioKCSAqIEdldHMgdGhlIHBhdGggdG8gd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHdwLWNvbmZpZy5waHAgZmlsZSBwYXRoCgkgKiAgICAgJCB3cCBjb25maWcgcGF0aAoJICogICAgIC9ob21lL3BlcnNvbi9odGRvY3MvcHJvamVjdC93cC1jb25maWcucGhwCgkgKgoJICogQHdoZW4gYmVmb3JlX3dwX2xvYWQKCSAqLwoJcHVibGljIGZ1bmN0aW9uIHBhdGgoKSB7CgkJV1BfQ0xJOjpsaW5lKCAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCkgKTsKCX0KCgkvKioKCSAqIExpc3RzIHZhcmlhYmxlcywgY29uc3RhbnRzLCBhbmQgZmlsZSBpbmNsdWRlcyBkZWZpbmVkIGluIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogWzxmaWx0ZXI+Li4uXQoJICogOiBOYW1lIG9yIHBhcnRpYWwgbmFtZSB0byBmaWx0ZXIgdGhlIGxpc3QgYnkuCgkgKgoJICogWy0tZmllbGRzPTxmaWVsZHM+XQoJICogOiBMaW1pdCB0aGUgb3V0cHV0IHRvIHNwZWNpZmljIGZpZWxkcy4gRGVmYXVsdHMgdG8gYWxsIGZpZWxkcy4KCSAqCgkgKiBbLS1mb3JtYXQ9PGZvcm1hdD5dCgkgKiA6IFJlbmRlciBvdXRwdXQgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdGFibGUKCSAqIG9wdGlvbnM6CgkgKiAgIC0gdGFibGUKCSAqICAgLSBjc3YKCSAqICAgLSBqc29uCgkgKiAgIC0geWFtbAoJICogLS0tCgkgKgoJICogWy0tc3RyaWN0XQoJICogOiBFbmZvcmNlIHN0cmljdCBtYXRjaGluZyB3aGVuIGEgZmlsdGVyIGlzIHByb3ZpZGVkLgoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgTGlzdCBjb25zdGFudHMgYW5kIHZhcmlhYmxlcyBkZWZpbmVkIGluIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqICAgICAkIHdwIGNvbmZpZyBsaXN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqICAgICB8IGtleSAgICAgICAgICAgICAgfCB2YWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgdHlwZSAgICAgfAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCB0YWJsZV9wcmVmaXggICAgIHwgd3BfICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHZhcmlhYmxlIHwKCSAqICAgICB8IERCX05BTUUgICAgICAgICAgfCB3cF9jbGlfdGVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgY29uc3RhbnQgfAoJICogICAgIHwgREJfVVNFUiAgICAgICAgICB8IHJvb3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBjb25zdGFudCB8CgkgKiAgICAgfCBEQl9QQVNTV09SRCAgICAgIHwgcm9vdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGNvbnN0YW50IHwKCSAqICAgICB8IEFVVEhfS0VZICAgICAgICAgfCByNitAc2hQMXlPJiQpMWdkdS5obFsvajs3WnJ2bXR+bzsjV3hTc2EwbWxRT2kyNGoyY1IsN2krUU0vIzdTOm9eIHwgY29uc3RhbnQgfAoJICogICAgIHwgU0VDVVJFX0FVVEhfS0VZICB8IGlPLXohX20tLVlIJFR4MnRmLyZWLFlXKjEzWl9IaVJMcWkpZD8kby10TWRZKzgycEskYFQuTllXfmlUTFc7eHAgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiAgICAgIyBMaXN0IG9ubHkgZGF0YWJhc2UgdXNlciBhbmQgcGFzc3dvcmQgZnJvbSB3cC1jb25maWcucGhwIGZpbGUuCgkgKiAgICAgJCB3cCBjb25maWcgbGlzdCBEQl9VU0VSIERCX1BBU1NXT1JEIC0tc3RyaWN0CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBrZXkgICAgICAgICAgICAgIHwgdmFsdWUgfCB0eXBlICAgICB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBEQl9VU0VSICAgICAgICAgIHwgcm9vdCAgfCBjb25zdGFudCB8CgkgKiAgICAgfCBEQl9QQVNTV09SRCAgICAgIHwgcm9vdCAgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0rCgkgKgoJICogICAgICMgTGlzdCBhbGwgc2FsdHMgZnJvbSB3cC1jb25maWcucGhwIGZpbGUuCgkgKiAgICAgJCB3cCBjb25maWcgbGlzdCBfU0FMVAoJICogICAgICstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rCgkgKiAgICAgfCBrZXkgICAgICAgICAgICAgIHwgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHR5cGUgICAgIHwKCSAqICAgICArLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKwoJICogICAgIHwgQVVUSF9TQUxUICAgICAgICB8IG46XVhkaXRrK183PlFpPT5CbXRaSGlILTYvRWNydmwoVjVjZWVHUDp7Pj87QlRePVtCMy0wPix+RjV6JCgrUSQgfCBjb25zdGFudCB8CgkgKiAgICAgfCBTRUNVUkVfQVVUSF9TQUxUIHwgP1ovcHxYaER3M3d9P2MueiV8K0JBcnwoSXYqSCUlVStEdSZrS1IgeT9jSk9ZeVJWUkJlQlsyekYtYCg+K0xDQyB8IGNvbnN0YW50IHwKCSAqICAgICB8IExPR0dFRF9JTl9TQUxUICAgfCArJEAoMXtiflp+c31Dcz44WV02W202flRub0NEcEU+TyVlNzV1fSY2a1VIIT5xOjd1TTRseGJCNlsxcGFfWCxxIHwgY29uc3RhbnQgfAoJICogICAgIHwgTk9OQ0VfU0FMVCAgICAgICB8IF94K0YgbGl8UUw/ME9TUW5zMV9KWnt8SXgzSmxlb3gtNzFrbS9naWZueXo4a21vPXctO0BBRThXLChmUDxOfTIgfCBjb25zdGFudCB8CgkgKiAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLSsKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICogQHN1YmNvbW1hbmQgbGlzdAoJICovCglwdWJsaWMgZnVuY3Rpb24gbGlzdF8oICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoKTsKCgkJJHN0cmljdCA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3N0cmljdCcgKTsKCQlpZiAoICRzdHJpY3QgJiYgZW1wdHkoICRhcmdzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICdUaGUgLS1zdHJpY3Qgb3B0aW9uIGNhbiBvbmx5IGJlIHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBhIGZpbHRlci4nICk7CgkJfQoKCQkkZGVmYXVsdF9maWVsZHMgPSBbCgkJCSduYW1lJywKCQkJJ3ZhbHVlJywKCQkJJ3R5cGUnLAoJCV07CgoJCSRkZWZhdWx0cyA9IFsKCQkJJ2ZpZWxkcycgPT4gaW1wbG9kZSggJywnLCAkZGVmYXVsdF9maWVsZHMgKSwKCQkJJ2Zvcm1hdCcgPT4gJ3RhYmxlJywKCQldOwoKCQkkYXNzb2NfYXJncyA9IGFycmF5X21lcmdlKCAkZGVmYXVsdHMsICRhc3NvY19hcmdzICk7CgoJCSR2YWx1ZXMgPSBzZWxmOjpnZXRfd3BfY29uZmlnX3ZhcnMoKTsKCgkJaWYgKCAhIGVtcHR5KCAkYXJncyApICkgewoJCQkkdmFsdWVzID0gJHRoaXMtPmZpbHRlcl92YWx1ZXMoICR2YWx1ZXMsICRhcmdzLCAkc3RyaWN0ICk7CgkJfQoKCQlpZiAoIGVtcHR5KCAkdmFsdWVzICkgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJObyBtYXRjaGluZyBlbnRyaWVzIGZvdW5kIGluICd3cC1jb25maWcucGhwJy4iICk7CgkJfQoKCQlVdGlsc1xmb3JtYXRfaXRlbXMoICRhc3NvY19hcmdzWydmb3JtYXQnXSwgJHZhbHVlcywgJGFzc29jX2FyZ3NbJ2ZpZWxkcyddICk7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmljIGNvbnN0YW50IG9yIHZhcmlhYmxlIGRlZmluZWQgaW4gd3AtY29uZmlnLnBocCBmaWxlLgoJICoKCSAqICMjIE9QVElPTlMKCSAqCgkgKiA8bmFtZT4KCSAqIDogTmFtZSBvZiB0aGUgd3AtY29uZmlnLnBocCBjb25zdGFudCBvciB2YXJpYWJsZS4KCSAqCgkgKiBbLS10eXBlPTx0eXBlPl0KCSAqIDogVHlwZSBvZiBjb25maWcgdmFsdWUgdG8gcmV0cmlldmUuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogWy0tZm9ybWF0PTxmb3JtYXQ+XQoJICogOiBHZXQgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGZvcm1hdC4KCSAqIC0tLQoJICogZGVmYXVsdDogdmFyX2V4cG9ydAoJICogb3B0aW9uczoKCSAqICAgLSB2YXJfZXhwb3J0CgkgKiAgIC0ganNvbgoJICogICAtIHlhbWwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgR2V0IHRoZSB0YWJsZV9wcmVmaXggYXMgZGVmaW5lZCBpbiB3cC1jb25maWcucGhwIGZpbGUuCgkgKiAgICAgJCB3cCBjb25maWcgZ2V0IHRhYmxlX3ByZWZpeAoJICogICAgIHdwXwoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBnZXQoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoKTsKCgkJbGlzdCggJG5hbWUgKSA9ICRhcmdzOwoJCSR0eXBlICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd0eXBlJyApOwoKCQkkdmFsdWUgPSAkdGhpcy0+cmV0dXJuX3ZhbHVlKCAkbmFtZSwgJHR5cGUsIHNlbGY6OmdldF93cF9jb25maWdfdmFycygpICk7CgkJV1BfQ0xJOjpwcmludF92YWx1ZSggJHZhbHVlLCAkYXNzb2NfYXJncyApOwoJfQoKCS8qKgoJICogR2V0IHRoZSBhcnJheSBvZiB3cC1jb25maWcucGhwIGNvbnN0YW50cyBhbmQgdmFyaWFibGVzLgoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0X3dwX2NvbmZpZ192YXJzKCkgewoJCSR3cF9jbGlfb3JpZ2luYWxfZGVmaW5lZF9jb25zdGFudHMgPSBnZXRfZGVmaW5lZF9jb25zdGFudHMoKTsKCQkkd3BfY2xpX29yaWdpbmFsX2RlZmluZWRfdmFycyAgICAgID0gZ2V0X2RlZmluZWRfdmFycygpOwoJCSR3cF9jbGlfb3JpZ2luYWxfaW5jbHVkZXMgICAgICAgICAgPSBnZXRfaW5jbHVkZWRfZmlsZXMoKTsKCgkJLy8gcGhwY3M6aWdub3JlIFNxdWl6LlBIUC5FdmFsLkRpc2NvdXJhZ2VkIC0tIERvbid0IGhhdmUgYW5vdGhlciB3YXkuCgkJZXZhbCggV1BfQ0xJOjpnZXRfcnVubmVyKCktPmdldF93cF9jb25maWdfY29kZSgpICk7CgoJCSR3cF9jb25maWdfdmFycyAgICAgID0gc2VsZjo6Z2V0X3dwX2NvbmZpZ19kaWZmKCBnZXRfZGVmaW5lZF92YXJzKCksICR3cF9jbGlfb3JpZ2luYWxfZGVmaW5lZF92YXJzLCAndmFyaWFibGUnLCBbICd3cF9jbGlfb3JpZ2luYWxfZGVmaW5lZF92YXJzJyBdICk7CgkJJHdwX2NvbmZpZ19jb25zdGFudHMgPSBzZWxmOjpnZXRfd3BfY29uZmlnX2RpZmYoIGdldF9kZWZpbmVkX2NvbnN0YW50cygpLCAkd3BfY2xpX29yaWdpbmFsX2RlZmluZWRfY29uc3RhbnRzLCAnY29uc3RhbnQnICk7CgoJCWZvcmVhY2ggKCAkd3BfY29uZmlnX3ZhcnMgYXMgJG5hbWUgPT4gJHZhbHVlICkgewoJCQlpZiAoICd3cF9jbGlfb3JpZ2luYWxfaW5jbHVkZXMnID09PSAkdmFsdWVbJ25hbWUnXSApIHsKCQkJCSRuYW1lX2JhY2t1cCA9ICRuYW1lOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXVuc2V0KCAkd3BfY29uZmlnX3ZhcnNbICRuYW1lX2JhY2t1cCBdICk7CgkJJHdwX2NvbmZpZ192YXJzICAgICAgICAgICA9IGFycmF5X3ZhbHVlcyggJHdwX2NvbmZpZ192YXJzICk7CgkJJHdwX2NvbmZpZ19pbmNsdWRlcyAgICAgICA9IGFycmF5X2RpZmYoIGdldF9pbmNsdWRlZF9maWxlcygpLCAkd3BfY2xpX29yaWdpbmFsX2luY2x1ZGVzICk7CgkJJHdwX2NvbmZpZ19pbmNsdWRlc19hcnJheSA9IFtdOwoKCQlmb3JlYWNoICggJHdwX2NvbmZpZ19pbmNsdWRlcyBhcyAkbmFtZSA9PiAkdmFsdWUgKSB7CgkJCSR3cF9jb25maWdfaW5jbHVkZXNfYXJyYXlbXSA9IFsKCQkJCSduYW1lJyAgPT4gYmFzZW5hbWUoICR2YWx1ZSApLAoJCQkJJ3ZhbHVlJyA9PiAkdmFsdWUsCgkJCQkndHlwZScgID0+ICdpbmNsdWRlcycsCgkJCV07CgkJfQoKCQlyZXR1cm4gYXJyYXlfbWVyZ2UoICR3cF9jb25maWdfdmFycywgJHdwX2NvbmZpZ19jb25zdGFudHMsICR3cF9jb25maWdfaW5jbHVkZXNfYXJyYXkgKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWMgY29uc3RhbnQgb3IgdmFyaWFibGUgZGVmaW5lZCBpbiB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxuYW1lPgoJICogOiBOYW1lIG9mIHRoZSB3cC1jb25maWcucGhwIGNvbnN0YW50IG9yIHZhcmlhYmxlLgoJICoKCSAqIDx2YWx1ZT4KCSAqIDogVmFsdWUgdG8gc2V0IHRoZSB3cC1jb25maWcucGhwIGNvbnN0YW50IG9yIHZhcmlhYmxlIHRvLgoJICoKCSAqIFstLWFkZF0KCSAqIDogQWRkIHRoZSB2YWx1ZSBpZiBpdCBkb2Vzbid0IGV4aXN0IHlldC4KCSAqIFRoaXMgaXMgdGhlIGRlZmF1bHQgYmVoYXZpb3IsIG92ZXJyaWRlIHdpdGggLS1uby1hZGQuCgkgKgoJICogWy0tcmF3XQoJICogOiBQbGFjZSB0aGUgdmFsdWUgaW50byB0aGUgd3AtY29uZmlnLnBocCBmaWxlIGFzIGlzLCBpbnN0ZWFkIG9mIGFzIGEgcXVvdGVkIHN0cmluZy4KCSAqCgkgKiBbLS1hbmNob3I9PGFuY2hvcj5dCgkgKiA6IEFuY2hvciBzdHJpbmcgd2hlcmUgYWRkaXRpb25zIG9mIG5ldyB2YWx1ZXMgYXJlIGFuY2hvcmVkIGFyb3VuZC4KCSAqIERlZmF1bHRzIHRvICIvKiBUaGF0J3MgYWxsLCBzdG9wIGVkaXRpbmchIi4KCSAqCgkgKiBbLS1wbGFjZW1lbnQ9PHBsYWNlbWVudD5dCgkgKiA6IFdoZXJlIHRvIHBsYWNlIHRoZSBuZXcgdmFsdWVzIGluIHJlbGF0aW9uIHRvIHRoZSBhbmNob3Igc3RyaW5nLgoJICogLS0tCgkgKiBkZWZhdWx0OiAnYmVmb3JlJwoJICogb3B0aW9uczoKCSAqICAgLSBiZWZvcmUKCSAqICAgLSBhZnRlcgoJICogLS0tCgkgKgoJICogWy0tc2VwYXJhdG9yPTxzZXBhcmF0b3I+XQoJICogOiBTZXBhcmF0b3Igc3RyaW5nIHRvIHB1dCBiZXR3ZWVuIGFuIGFkZGVkIHZhbHVlIGFuZCBpdHMgYW5jaG9yIHN0cmluZy4KCSAqIFRoZSBmb2xsb3dpbmcgZXNjYXBlIHNlcXVlbmNlcyB3aWxsIGJlIHJlY29nbml6ZWQgYW5kIHByb3Blcmx5IGludGVycHJldGVkOiAnXG4nID0+IG5ld2xpbmUsICdccicgPT4gY2FycmlhZ2UgcmV0dXJuLCAnXHQnID0+IHRhYi4KCSAqIERlZmF1bHRzIHRvIGEgc2luZ2xlIEVPTCAoIlxuIiBvbiAqbml4IGFuZCAiXHJcbiIgb24gV2luZG93cykuCgkgKgoJICogWy0tdHlwZT08dHlwZT5dCgkgKiA6IFR5cGUgb2YgdGhlIGNvbmZpZyB2YWx1ZSB0byBzZXQuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBTZXQgdGhlIFdQX0RFQlVHIGNvbnN0YW50IHRvIHRydWUuCgkgKiAgICAgJCB3cCBjb25maWcgc2V0IFdQX0RFQlVHIHRydWUgLS1yYXcKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gc2V0KCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBhdGggPSAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCk7CgoJCWxpc3QoICRuYW1lLCAkdmFsdWUgKSA9ICRhcmdzOwoJCSR0eXBlICAgICAgICAgICAgICAgICA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ3R5cGUnICk7CgoJCSRvcHRpb25zID0gW107CgoJCSRvcHRpb25fZmxhZ3MgPSBbCgkJCSdyYXcnICAgICAgID0+IGZhbHNlLAoJCQknYWRkJyAgICAgICA9PiB0cnVlLAoJCQknYW5jaG9yJyAgICA9PiBudWxsLAoJCQkncGxhY2VtZW50JyA9PiBudWxsLAoJCQknc2VwYXJhdG9yJyA9PiBudWxsLAoJCV07CgoJCWZvcmVhY2ggKCAkb3B0aW9uX2ZsYWdzIGFzICRvcHRpb24gPT4gJGRlZmF1bHQgKSB7CgkJCSRvcHRpb25fdmFsdWUgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICRvcHRpb24sICRkZWZhdWx0ICk7CgkJCWlmICggbnVsbCAhPT0gJG9wdGlvbl92YWx1ZSApIHsKCQkJCSRvcHRpb25zWyAkb3B0aW9uIF0gPSAkb3B0aW9uX3ZhbHVlOwoJCQkJaWYgKCAnc2VwYXJhdG9yJyA9PT0gJG9wdGlvbiApIHsKCQkJCQkkb3B0aW9uc1snc2VwYXJhdG9yJ10gPSAkdGhpcy0+cGFyc2Vfc2VwYXJhdG9yKCAkb3B0aW9uc1snc2VwYXJhdG9yJ10gKTsKCQkJCX0KCQkJfQoJCX0KCgkJJGFkZGluZyA9IGZhbHNlOwoJCXRyeSB7CgkJCSRjb25maWdfdHJhbnNmb3JtZXIgPSBuZXcgV1BDb25maWdUcmFuc2Zvcm1lciggJHBhdGggKTsKCgkJCXN3aXRjaCAoICR0eXBlICkgewoJCQkJY2FzZSAnYWxsJzoKCQkJCQkkaGFzX2NvbnN0YW50ID0gJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAnY29uc3RhbnQnLCAkbmFtZSApOwoJCQkJCSRoYXNfdmFyaWFibGUgPSAkY29uZmlnX3RyYW5zZm9ybWVyLT5leGlzdHMoICd2YXJpYWJsZScsICRuYW1lICk7CgkJCQkJaWYgKCAkaGFzX2NvbnN0YW50ICYmICRoYXNfdmFyaWFibGUgKSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICJGb3VuZCBib3RoIGEgY29uc3RhbnQgYW5kIGEgdmFyaWFibGUgJ3skbmFtZX0nIGluIHRoZSAnd3AtY29uZmlnLnBocCcgZmlsZS4gVXNlIC0tdHlwZT08dHlwZT4gdG8gZGlzYW1iaWd1YXRlLiIgKTsKCQkJCQl9CgkJCQkJaWYgKCAhICRoYXNfY29uc3RhbnQgJiYgISAkaGFzX3ZhcmlhYmxlICkgewoJCQkJCQlpZiAoICEgJG9wdGlvbnNbJ2FkZCddICkgewoJCQkJCQkJJG1lc3NhZ2UgPSAiVGhlIGNvbnN0YW50IG9yIHZhcmlhYmxlICd7JG5hbWV9JyBpcyBub3QgZGVmaW5lZCBpbiB0aGUgJ3dwLWNvbmZpZy5waHAnIGZpbGUuIjsKCQkJCQkJCVdQX0NMSTo6ZXJyb3IoICRtZXNzYWdlICk7CgkJCQkJCX0KCQkJCQkJJHR5cGUgICA9ICdjb25zdGFudCc7CgkJCQkJCSRhZGRpbmcgPSB0cnVlOwoJCQkJCX0gZWxzZSB7CgkJCQkJCSR0eXBlID0gJGhhc19jb25zdGFudCA/ICdjb25zdGFudCcgOiAndmFyaWFibGUnOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgJ2NvbnN0YW50JzoKCQkJCWNhc2UgJ3ZhcmlhYmxlJzoKCQkJCQlpZiAoICEgJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAkdHlwZSwgJG5hbWUgKSApIHsKCQkJCQkJaWYgKCAhICRvcHRpb25zWydhZGQnXSApIHsKCQkJCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgeyR0eXBlfSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLiIgKTsKCQkJCQkJfQoJCQkJCQkkYWRkaW5nID0gdHJ1ZTsKCQkJCQl9CgkJCX0KCgkJCSRjb25maWdfdHJhbnNmb3JtZXItPnVwZGF0ZSggJHR5cGUsICRuYW1lLCAkdmFsdWUsICRvcHRpb25zICk7CgoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBwcm9jZXNzIHRoZSAnd3AtY29uZmlnLnBocCcgdHJhbnNmb3JtYXRpb24uXG5SZWFzb246IHskZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCl9IiApOwoJCX0KCgkJJHJhdyA9ICRvcHRpb25zWydyYXcnXSA/ICdyYXcgJyA6ICcnOwoJCWlmICggJGFkZGluZyApIHsKCQkJJG1lc3NhZ2UgPSAiQWRkZWQgdGhlIHskdHlwZX0gJ3skbmFtZX0nIHRvIHRoZSAnd3AtY29uZmlnLnBocCcgZmlsZSB3aXRoIHRoZSB7JHJhd312YWx1ZSAneyR2YWx1ZX0nLiI7CgkJfSBlbHNlIHsKCQkJJG1lc3NhZ2UgPSAiVXBkYXRlZCB0aGUgeyR0eXBlfSAneyRuYW1lfScgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlIHdpdGggdGhlIHskcmF3fXZhbHVlICd7JHZhbHVlfScuIjsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggJG1lc3NhZ2UgKTsKCX0KCgkvKioKCSAqIERlbGV0ZXMgYSBzcGVjaWZpYyBjb25zdGFudCBvciB2YXJpYWJsZSBmcm9tIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIDxuYW1lPgoJICogOiBOYW1lIG9mIHRoZSB3cC1jb25maWcucGhwIGNvbnN0YW50IG9yIHZhcmlhYmxlLgoJICoKCSAqIFstLXR5cGU9PHR5cGU+XQoJICogOiBUeXBlIG9mIHRoZSBjb25maWcgdmFsdWUgdG8gZGVsZXRlLiBEZWZhdWx0cyB0byAnYWxsJy4KCSAqIC0tLQoJICogZGVmYXVsdDogYWxsCgkgKiBvcHRpb25zOgoJICogICAtIGNvbnN0YW50CgkgKiAgIC0gdmFyaWFibGUKCSAqICAgLSBhbGwKCSAqIC0tLQoJICoKCSAqICMjIEVYQU1QTEVTCgkgKgoJICogICAgICMgRGVsZXRlIHRoZSBDT09LSUVfRE9NQUlOIGNvbnN0YW50IGZyb20gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqICAgICAkIHdwIGNvbmZpZyBkZWxldGUgQ09PS0lFX0RPTUFJTgoJICoKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBkZWxldGUoICRhcmdzLCAkYXNzb2NfYXJncyApIHsKCQkkcGF0aCA9ICR0aGlzLT5nZXRfY29uZmlnX3BhdGgoKTsKCgkJbGlzdCggJG5hbWUgKSA9ICRhcmdzOwoJCSR0eXBlICAgICAgICAgPSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICd0eXBlJyApOwoKCQl0cnkgewoJCQkkY29uZmlnX3RyYW5zZm9ybWVyID0gbmV3IFdQQ29uZmlnVHJhbnNmb3JtZXIoICRwYXRoICk7CgoJCQlzd2l0Y2ggKCAkdHlwZSApIHsKCQkJCWNhc2UgJ2FsbCc6CgkJCQkJJGhhc19jb25zdGFudCA9ICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJ2NvbnN0YW50JywgJG5hbWUgKTsKCQkJCQkkaGFzX3ZhcmlhYmxlID0gJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAndmFyaWFibGUnLCAkbmFtZSApOwoJCQkJCWlmICggJGhhc19jb25zdGFudCAmJiAkaGFzX3ZhcmlhYmxlICkgewoJCQkJCQlXUF9DTEk6OmVycm9yKCAiRm91bmQgYm90aCBhIGNvbnN0YW50IGFuZCBhIHZhcmlhYmxlICd7JG5hbWV9JyBpbiB0aGUgJ3dwLWNvbmZpZy5waHAnIGZpbGUuIFVzZSAtLXR5cGU9PHR5cGU+IHRvIGRpc2FtYmlndWF0ZS4iICk7CgkJCQkJfQoJCQkJCWlmICggISAkaGFzX2NvbnN0YW50ICYmICEgJGhhc192YXJpYWJsZSApIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggIlRoZSBjb25zdGFudCBvciB2YXJpYWJsZSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLiIgKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkkdHlwZSA9ICRoYXNfY29uc3RhbnQgPyAnY29uc3RhbnQnIDogJ3ZhcmlhYmxlJzsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICdjb25zdGFudCc6CgkJCQljYXNlICd2YXJpYWJsZSc6CgkJCQkJaWYgKCAhICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJHR5cGUsICRuYW1lICkgKSB7CgkJCQkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgeyR0eXBlfSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLiIgKTsKCQkJCQl9CgkJCX0KCgkJCSRjb25maWdfdHJhbnNmb3JtZXItPnJlbW92ZSggJHR5cGUsICRuYW1lICk7CgoJCX0gY2F0Y2ggKCBFeGNlcHRpb24gJGV4Y2VwdGlvbiApIHsKCQkJV1BfQ0xJOjplcnJvciggIkNvdWxkIG5vdCBwcm9jZXNzIHRoZSAnd3AtY29uZmlnLnBocCcgdHJhbnNmb3JtYXRpb24uXG5SZWFzb246IHskZXhjZXB0aW9uLT5nZXRNZXNzYWdlKCl9IiApOwoJCX0KCgkJV1BfQ0xJOjpzdWNjZXNzKCAiRGVsZXRlZCB0aGUgeyR0eXBlfSAneyRuYW1lfScgZnJvbSB0aGUgJ3dwLWNvbmZpZy5waHAnIGZpbGUuIiApOwoJfQoKCS8qKgoJICogQ2hlY2tzIHdoZXRoZXIgYSBzcGVjaWZpYyBjb25zdGFudCBvciB2YXJpYWJsZSBleGlzdHMgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiAjIyBPUFRJT05TCgkgKgoJICogPG5hbWU+CgkgKiA6IE5hbWUgb2YgdGhlIHdwLWNvbmZpZy5waHAgY29uc3RhbnQgb3IgdmFyaWFibGUuCgkgKgoJICogWy0tdHlwZT08dHlwZT5dCgkgKiA6IFR5cGUgb2YgdGhlIGNvbmZpZyB2YWx1ZSB0byBzZXQuIERlZmF1bHRzIHRvICdhbGwnLgoJICogLS0tCgkgKiBkZWZhdWx0OiBhbGwKCSAqIG9wdGlvbnM6CgkgKiAgIC0gY29uc3RhbnQKCSAqICAgLSB2YXJpYWJsZQoJICogICAtIGFsbAoJICogLS0tCgkgKgoJICogIyMgRVhBTVBMRVMKCSAqCgkgKiAgICAgIyBDaGVjayB3aGV0aGVyIHRoZSBEQl9QQVNTV09SRCBjb25zdGFudCBleGlzdHMgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqICAgICAkIHdwIGNvbmZpZyBoYXMgREJfUEFTU1dPUkQKCSAqCgkgKiBAd2hlbiBiZWZvcmVfd3BfbG9hZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaGFzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgkJJHBhdGggPSAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCk7CgoJCWxpc3QoICRuYW1lICkgPSAkYXJnczsKCQkkdHlwZSAgICAgICAgID0gVXRpbHNcZ2V0X2ZsYWdfdmFsdWUoICRhc3NvY19hcmdzLCAndHlwZScgKTsKCgkJdHJ5IHsKCQkJJGNvbmZpZ190cmFuc2Zvcm1lciA9IG5ldyBXUENvbmZpZ1RyYW5zZm9ybWVyKCAkcGF0aCApOwoKCQkJc3dpdGNoICggJHR5cGUgKSB7CgkJCQljYXNlICdhbGwnOgoJCQkJCSRoYXNfY29uc3RhbnQgPSAkY29uZmlnX3RyYW5zZm9ybWVyLT5leGlzdHMoICdjb25zdGFudCcsICRuYW1lICk7CgkJCQkJJGhhc192YXJpYWJsZSA9ICRjb25maWdfdHJhbnNmb3JtZXItPmV4aXN0cyggJ3ZhcmlhYmxlJywgJG5hbWUgKTsKCQkJCQlpZiAoICRoYXNfY29uc3RhbnQgJiYgJGhhc192YXJpYWJsZSApIHsKCQkJCQkJV1BfQ0xJOjplcnJvciggIkZvdW5kIGJvdGggYSBjb25zdGFudCBhbmQgYSB2YXJpYWJsZSAneyRuYW1lfScgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLiBVc2UgLS10eXBlPTx0eXBlPiB0byBkaXNhbWJpZ3VhdGUuIiApOwoJCQkJCX0KCQkJCQlpZiAoICEgJGhhc19jb25zdGFudCAmJiAhICRoYXNfdmFyaWFibGUgKSB7CgkJCQkJCVdQX0NMSTo6aGFsdCggMSApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCVdQX0NMSTo6aGFsdCggMCApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgJ2NvbnN0YW50JzoKCQkJCWNhc2UgJ3ZhcmlhYmxlJzoKCQkJCQlpZiAoICEgJGNvbmZpZ190cmFuc2Zvcm1lci0+ZXhpc3RzKCAkdHlwZSwgJG5hbWUgKSApIHsKCQkJCQkJV1BfQ0xJOjpoYWx0KCAxICk7CgkJCQkJfQoJCQkJCVdQX0NMSTo6aGFsdCggMCApOwoJCQl9CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAiQ291bGQgbm90IHByb2Nlc3MgdGhlICd3cC1jb25maWcucGhwJyB0cmFuc2Zvcm1hdGlvbi5cblJlYXNvbjogeyRleGNlcHRpb24tPmdldE1lc3NhZ2UoKX0iICk7CgkJfQoJfQoKCS8qKgoJICogUmVmcmVzaGVzIHRoZSBzYWx0cyBkZWZpbmVkIGluIHRoZSB3cC1jb25maWcucGhwIGZpbGUuCgkgKgoJICogIyMgT1BUSU9OUwoJICoKCSAqIFs8a2V5cz4uLi5dCgkgKiA6IE9uZSBvcmUgbW9yZSBrZXlzIHRvIHNodWZmbGUuIElmIG5vbmUgYXJlIHByb3ZpZGVkLCB0aGlzIGZhbGxzIGJhY2sgdG8gdGhlIGRlZmF1bHQgV29yZFByZXNzIENvcmUgc2FsdCBrZXlzLgoJICoKCSAqIFstLWZvcmNlXQoJICogOiBJZiBhbiB1bmtub3duIGtleSBpcyByZXF1ZXN0ZWQgdG8gYmUgc2h1ZmZsZWQsIGFkZCBpdCBpbnN0ZWFkIG9mIHRocm93aW5nIGEgd2FybmluZy4KCSAqCgkgKiBbLS1pbnNlY3VyZV0KCSAqIDogUmV0cnkgQVBJIGRvd25sb2FkIHdpdGhvdXQgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpZiBUTFMgaGFuZHNoYWtlIGZhaWxzLiBOb3RlOiBUaGlzIG1ha2VzIHRoZSByZXF1ZXN0IHZ1bG5lcmFibGUgdG8gYSBNSVRNIGF0dGFjay4KCSAqCgkgKiAjIyBFWEFNUExFUwoJICoKCSAqICAgICAjIEdldCBuZXcgc2FsdHMgZm9yIHlvdXIgd3AtY29uZmlnLnBocCBmaWxlCgkgKiAgICAgJCB3cCBjb25maWcgc2h1ZmZsZS1zYWx0cwoJICogICAgIFN1Y2Nlc3M6IFNodWZmbGVkIHRoZSBzYWx0IGtleXMuCgkgKgoJICogICAgICMgQWRkIGEgY2FjaGUga2V5IHNhbHQgdG8gdGhlIHdwLWNvbmZpZy5waHAgZmlsZQoJICogICAgICQgd3AgY29uZmlnIHNodWZmbGUtc2FsdHMgV1BfQ0FDSEVfS0VZX1NBTFQgLS1mb3JjZQoJICoKCSAqIEBzdWJjb21tYW5kIHNodWZmbGUtc2FsdHMKCSAqIEB3aGVuIGJlZm9yZV93cF9sb2FkCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBzaHVmZmxlX3NhbHRzKCAkYXJncywgJGFzc29jX2FyZ3MgKSB7CgoJCSRrZXlzICA9ICRhcmdzOwoJCSRmb3JjZSA9IFV0aWxzXGdldF9mbGFnX3ZhbHVlKCAkYXNzb2NfYXJncywgJ2ZvcmNlJywgZmFsc2UgKTsKCgkJaWYgKCBlbXB0eSggJGtleXMgKSApIHsKCQkJJGtleXMgPSBzZWxmOjpERUZBVUxUX1NBTFRfQ09OU1RBTlRTOwoJCX0KCgkJJHNlY3JldF9rZXlzID0gW107CgoJCXRyeSB7CgkJCWZvcmVhY2ggKCAka2V5cyBhcyAka2V5ICkgewoJCQkJaWYgKCAhICRmb3JjZSAmJiAhIGluX2FycmF5KCAka2V5LCBzZWxmOjpERUZBVUxUX1NBTFRfQ09OU1RBTlRTLCB0cnVlICkgKSB7CgkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IHNodWZmbGUgdGhlIHVua25vd24ga2V5ICd7JGtleX0nLiIgKTsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCSRzZWNyZXRfa2V5c1sgJGtleSBdID0gdHJpbSggc2VsZjo6dW5pcXVlX2tleSgpICk7CgkJCX0KCQl9IGNhdGNoICggRXhjZXB0aW9uICRleCApIHsKCQkJZm9yZWFjaCAoICRrZXlzIGFzICRrZXkgKSB7CgkJCQlpZiAoICEgaW5fYXJyYXkoICRrZXksIHNlbGY6OkRFRkFVTFRfU0FMVF9DT05TVEFOVFMsIHRydWUgKSApIHsKCQkJCQlpZiAoICRmb3JjZSApIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IGFkZCB0aGUga2V5ICd7JGtleX0nIGJlY2F1c2UgJ3JhbmRvbV9pbnQoKScgaXMgbm90IHN1cHBvcnRlZC4iICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJV1BfQ0xJOjp3YXJuaW5nKCAiQ291bGQgbm90IHNodWZmbGUgdGhlIHVua25vd24ga2V5ICd7JGtleX0nLiIgKTsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCSRyZW1vdGVfc2FsdHMgPSBzZWxmOjpmZXRjaF9yZW1vdGVfc2FsdHMoIChib29sKSBVdGlsc1xnZXRfZmxhZ192YWx1ZSggJGFzc29jX2FyZ3MsICdpbnNlY3VyZScsIGZhbHNlICkgKTsKCQkJJHJlbW90ZV9zYWx0cyA9IGV4cGxvZGUoICJcbiIsICRyZW1vdGVfc2FsdHMgKTsKCQkJZm9yZWFjaCAoICRyZW1vdGVfc2FsdHMgYXMgJGsgPT4gJHNhbHQgKSB7CgkJCQlpZiAoICEgZW1wdHkoICRzYWx0ICkgKSB7CgkJCQkJJGtleSA9IHNlbGY6OkRFRkFVTFRfU0FMVF9DT05TVEFOVFNbICRrIF07CgkJCQkJaWYgKCBpbl9hcnJheSggJGtleSwgJGtleXMsIHRydWUgKSApIHsKCQkJCQkJJHNlY3JldF9rZXlzWyAka2V5IF0gPSB0cmltKCBzdWJzdHIoICRzYWx0LCAyOCwgNjQgKSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJJHBhdGggPSAkdGhpcy0+Z2V0X2NvbmZpZ19wYXRoKCk7CgoJCXRyeSB7CgkJCSRjb25maWdfdHJhbnNmb3JtZXIgPSBuZXcgV1BDb25maWdUcmFuc2Zvcm1lciggJHBhdGggKTsKCQkJZm9yZWFjaCAoICRzZWNyZXRfa2V5cyBhcyAka2V5ID0+ICR2YWx1ZSApIHsKCQkJCSRjb25maWdfdHJhbnNmb3JtZXItPnVwZGF0ZSggJ2NvbnN0YW50JywgJGtleSwgKHN0cmluZykgJHZhbHVlICk7CgkJCX0KCQl9IGNhdGNoICggRXhjZXB0aW9uICRleGNlcHRpb24gKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJDb3VsZCBub3QgcHJvY2VzcyB0aGUgJ3dwLWNvbmZpZy5waHAnIHRyYW5zZm9ybWF0aW9uLlxuUmVhc29uOiB7JGV4Y2VwdGlvbi0+Z2V0TWVzc2FnZSgpfSIgKTsKCQl9CgoJCVdQX0NMSTo6c3VjY2VzcyggJ1NodWZmbGVkIHRoZSBzYWx0IGtleXMuJyApOwoKCX0KCgkvKioKCSAqIEZpbHRlcnMgd3AtY29uZmlnLnBocCBmaWxlIGNvbmZpZ3VyYXRpb25zLgoJICoKCSAqIEBwYXJhbSBhcnJheSAkbGlzdAoJICogQHBhcmFtIGFycmF5ICRwcmV2aW91c19saXN0CgkgKiBAcGFyYW0gc3RyaW5nICR0eXBlCgkgKiBAcGFyYW0gYXJyYXkgJGV4Y2x1ZGVfbGlzdAoJICogQHJldHVybiBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRfd3BfY29uZmlnX2RpZmYoICRsaXN0LCAkcHJldmlvdXNfbGlzdCwgJHR5cGUsICRleGNsdWRlX2xpc3QgPSBbXSApIHsKCQkkcmVzdWx0ID0gW107CgkJZm9yZWFjaCAoICRsaXN0IGFzICRuYW1lID0+ICR2YWwgKSB7CgkJCWlmICggYXJyYXlfa2V5X2V4aXN0cyggJG5hbWUsICRwcmV2aW91c19saXN0ICkgfHwgaW5fYXJyYXkoICRuYW1lLCAkZXhjbHVkZV9saXN0LCB0cnVlICkgKSB7CgkJCQljb250aW51ZTsKCQkJfQoJCQkkb3V0ICAgICAgICAgID0gW107CgkJCSRvdXRbJ25hbWUnXSAgPSAkbmFtZTsKCQkJJG91dFsndmFsdWUnXSA9ICR2YWw7CgkJCSRvdXRbJ3R5cGUnXSAgPSAkdHlwZTsKCQkJJHJlc3VsdFtdICAgICA9ICRvdXQ7CgkJfQoJCXJldHVybiAkcmVzdWx0OwoJfQoKCS8qKgoJICogUmVhZCB0aGUgc2FsdHMgZnJvbSB0aGUgV29yZFByZXNzLm9yZyBBUEkuCgkgKgoJICogQHBhcmFtIGJvb2wgICAkaW5zZWN1cmUgT3B0aW9uYWwuIFdoZXRoZXIgdG8gcmV0cnkgd2l0aG91dCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIG9uIFRMUyBoYW5kc2hha2UgZmFpbHVyZS4KCSAqIEByZXR1cm4gc3RyaW5nIFN0cmluZyB3aXRoIGEgc2V0IG9mIFBIUCBkZWZpbmUoKSBzdGF0ZW1lbnRzIHRvIGRlZmluZSB0aGUgc2FsdHMuCgkgKiBAdGhyb3dzIEV4aXRFeGNlcHRpb24gSWYgdGhlIHJlbW90ZSByZXF1ZXN0IGZhaWxlZC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZmV0Y2hfcmVtb3RlX3NhbHRzKCAkaW5zZWN1cmUgPSBmYWxzZSApIHsKCQl0cnkgewoJCQkkc2FsdHMgPSAoc3RyaW5nKSAoIG5ldyBXcE9yZ0FwaSggWyAnaW5zZWN1cmUnID0+ICRpbnNlY3VyZSBdICkgKS0+Z2V0X3NhbHRzKCk7CgkJfSBjYXRjaCAoIEV4Y2VwdGlvbiAkZXhjZXB0aW9uICkgewoJCQlXUF9DTEk6OmVycm9yKCAkZXhjZXB0aW9uICk7CgkJfQoKCQlyZXR1cm4gJHNhbHRzOwoJfQoKCS8qKgoJICogUHJpbnRzIHRoZSB2YWx1ZSBvZiBhIGNvbnN0YW50IG9yIHZhcmlhYmxlIGRlZmluZWQgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBJZiB0aGUgY29uc3RhbnQgb3IgdmFyaWFibGUgaXMgbm90IGRlZmluZWQgaW4gdGhlIHdwLWNvbmZpZy5waHAgZmlsZSB0aGVuIGFuIGVycm9yIHdpbGwgYmUgcmV0dXJuZWQuCgkgKgoJICogQHBhcmFtIHN0cmluZyAkbmFtZQoJICogQHBhcmFtIHN0cmluZyAkdHlwZQoJICogQHBhcmFtIGFycmF5ICR2YWx1ZXMKCSAqCgkgKiBAcmV0dXJuIHN0cmluZyBUaGUgdmFsdWUgb2YgdGhlIHJlcXVlc3RlZCBjb25zdGFudCBvciB2YXJpYWJsZSBhcyBkZWZpbmVkIGluIHRoZSB3cC1jb25maWcucGhwIGZpbGU7IGlmIHRoZQoJICogICAgICAgICAgICAgICAgcmVxdWVzdGVkIGNvbnN0YW50IG9yIHZhcmlhYmxlIGlzIG5vdCBkZWZpbmVkIHRoZW4gdGhlIGZ1bmN0aW9uIHdpbGwgcHJpbnQgYW4gZXJyb3IgYW5kIGV4aXQuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gcmV0dXJuX3ZhbHVlKCAkbmFtZSwgJHR5cGUsICR2YWx1ZXMgKSB7CgkJJHJlc3VsdHMgPSBbXTsKCQlmb3JlYWNoICggJHZhbHVlcyBhcyAkdmFsdWUgKSB7CgkJCWlmICggJG5hbWUgPT09ICR2YWx1ZVsnbmFtZSddICYmICggJ2FsbCcgPT09ICR0eXBlIHx8ICR0eXBlID09PSAkdmFsdWVbJ3R5cGUnXSApICkgewoJCQkJJHJlc3VsdHNbXSA9ICR2YWx1ZTsKCQkJfQoJCX0KCgkJaWYgKCBjb3VudCggJHJlc3VsdHMgKSA+IDEgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJGb3VuZCBib3RoIGEgY29uc3RhbnQgYW5kIGEgdmFyaWFibGUgJ3skbmFtZX0nIGluIHRoZSAnd3AtY29uZmlnLnBocCcgZmlsZS4gVXNlIC0tdHlwZT08dHlwZT4gdG8gZGlzYW1iaWd1YXRlLiIgKTsKCQl9CgoJCWlmICggISBlbXB0eSggJHJlc3VsdHMgKSApIHsKCQkJcmV0dXJuICRyZXN1bHRzWzBdWyd2YWx1ZSddOwoJCX0KCgkJJHR5cGUgICAgICA9ICdhbGwnID09PSAkdHlwZSA/ICdjb25zdGFudCBvciB2YXJpYWJsZScgOiAkdHlwZTsKCQkkbmFtZXMgICAgID0gYXJyYXlfY29sdW1uKCAkdmFsdWVzLCAnbmFtZScgKTsKCQkkY2FuZGlkYXRlID0gVXRpbHNcZ2V0X3N1Z2dlc3Rpb24oICRuYW1lLCAkbmFtZXMgKTsKCgkJaWYgKCAhIGVtcHR5KCAkY2FuZGlkYXRlICkgJiYgJGNhbmRpZGF0ZSAhPT0gJG5hbWUgKSB7CgkJCVdQX0NMSTo6ZXJyb3IoICJUaGUgeyR0eXBlfSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLlxuRGlkIHlvdSBtZWFuICd7JGNhbmRpZGF0ZX0nPyIgKTsKCQl9CgoJCVdQX0NMSTo6ZXJyb3IoICJUaGUgeyR0eXBlfSAneyRuYW1lfScgaXMgbm90IGRlZmluZWQgaW4gdGhlICd3cC1jb25maWcucGhwJyBmaWxlLiIgKTsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBrZXkvc2FsdCBmb3IgdGhlIHdwLWNvbmZpZy5waHAgZmlsZS4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbgoJICoKCSAqIEByZXR1cm4gc3RyaW5nCgkgKi8KCXByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHVuaXF1ZV9rZXkoKSB7CgkJaWYgKCAhIGZ1bmN0aW9uX2V4aXN0cyggJ3JhbmRvbV9pbnQnICkgKSB7CgkJCXRocm93IG5ldyBFeGNlcHRpb24oICIncmFuZG9tX2ludCcgZG9lcyBub3QgZXhpc3QiICk7CgkJfQoKCQkkY2hhcnMgPSBzZWxmOjpWQUxJRF9LRVlfQ0hBUkFDVEVSUzsKCQkka2V5ICAgPSAnJzsKCgkJZm9yICggJGkgPSAwOyAkaSA8IDY0OyAkaSsrICkgewoJCQkvLyBwaHBjczppZ25vcmUgUEhQQ29tcGF0aWJpbGl0eS5GdW5jdGlvblVzZS5OZXdGdW5jdGlvbnMucmFuZG9tX2ludEZvdW5kIC0tIFdpbGwgYmUgY2FsbGVkIG9ubHkgaWYgZnVuY3Rpb24gZXhpc3RzLgoJCQkka2V5IC49IHN1YnN0ciggJGNoYXJzLCByYW5kb21faW50KCAwLCBzdHJsZW4oICRjaGFycyApIC0gMSApLCAxICk7CgkJfQoKCQlyZXR1cm4gJGtleTsKCX0KCgkvKioKCSAqIEZpbHRlcnMgdGhlIHZhbHVlcyBiYXNlZCBvbiBhIHByb3ZpZGVyIGZpbHRlciBrZXkuCgkgKgoJICogQHBhcmFtIGFycmF5ICR2YWx1ZXMKCSAqIEBwYXJhbSBhcnJheSAkZmlsdGVycwoJICogQHBhcmFtIGJvb2wgJHN0cmljdAoJICoKCSAqIEByZXR1cm4gYXJyYXkKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBmaWx0ZXJfdmFsdWVzKCAkdmFsdWVzLCAkZmlsdGVycywgJHN0cmljdCApIHsKCQkkcmVzdWx0ID0gW107CgoJCWZvcmVhY2ggKCAkdmFsdWVzIGFzICR2YWx1ZSApIHsKCQkJZm9yZWFjaCAoICRmaWx0ZXJzIGFzICRmaWx0ZXIgKSB7CgkJCQlpZiAoICRzdHJpY3QgJiYgJGZpbHRlciAhPT0gJHZhbHVlWyduYW1lJ10gKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJaWYgKCBmYWxzZSA9PT0gc3RycG9zKCAkdmFsdWVbJ25hbWUnXSwgJGZpbHRlciApICkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoKCQkJCSRyZXN1bHRbXSA9ICR2YWx1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJLyoqCgkgKiBHZXRzIHRoZSBwYXRoIHRvIHRoZSB3cC1jb25maWcucGhwIGZpbGUgb3IgZ2l2ZXMgYSBoZWxwZnVsIGVycm9yIGlmIG5vbmUgZm91bmQuCgkgKgoJICogQHJldHVybiBzdHJpbmcgUGF0aCB0byB3cC1jb25maWcucGhwIGZpbGUuCgkgKi8KCXByaXZhdGUgZnVuY3Rpb24gZ2V0X2NvbmZpZ19wYXRoKCkgewoJCSRwYXRoID0gVXRpbHNcbG9jYXRlX3dwX2NvbmZpZygpOwoJCWlmICggISAkcGF0aCApIHsKCQkJV1BfQ0xJOjplcnJvciggIid3cC1jb25maWcucGhwJyBub3QgZm91bmQuXG5FaXRoZXIgY3JlYXRlIG9uZSBtYW51YWxseSBvciB1c2UgYHdwIGNvbmZpZyBjcmVhdGVgLiIgKTsKCQl9CgkJcmV0dXJuICRwYXRoOwoJfQoKCS8qKgoJICogUGFyc2VzIHRoZSBzZXBhcmF0b3IgYXJndW1lbnQsIHRvIGFsbG93IGZvciBzcGVjaWFsIGNoYXJhY3RlciBoYW5kbGluZy4KCSAqCgkgKiBEb2VzIHRoZSBmb2xsb3dpbmcgdHJhbnNmb3JtYXRpb25zOgoJICogLSAnXG4nID0+ICJcbiIgKG5ld2xpbmUpCgkgKiAtICdccicgPT4gIlxyIiAoY2FycmlhZ2UgcmV0dXJuKQoJICogLSAnXHQnID0+ICJcdCIgKHRhYikKCSAqCgkgKiBAcGFyYW0gc3RyaW5nICRzZXBhcmF0b3IgU2VwYXJhdG9yIHN0cmluZyB0byBwYXJzZS4KCSAqCgkgKiBAcmV0dXJuIG1peGVkIFBhcnNlZCBzZXBhcmF0b3Igc3RyaW5nLgoJICovCglwcml2YXRlIGZ1bmN0aW9uIHBhcnNlX3NlcGFyYXRvciggJHNlcGFyYXRvciApIHsKCQkkc2VwYXJhdG9yID0gc3RyX3JlcGxhY2UoCgkJCVsgJ1xuJywgJ1xyJywgJ1x0JyBdLAoJCQlbICJcbiIsICJcciIsICJcdCIgXSwKCQkJJHNlcGFyYXRvcgoJCSk7CgoJCXJldHVybiAkc2VwYXJhdG9yOwoJfQp9Cjw/cGhwCmNsYXNzIE94eW1lbCB7Cglwcml2YXRlICR4bWw7Cglwcml2YXRlICRkb207Cglwcml2YXRlICRjdXJyZW50X2VsZW1lbnQ7Cglwcml2YXRlICRsYXN0X2luc2VydGVkOwoJcHJpdmF0ZSAkZ29fZGVlcF9vbl9uZXh0X2VsZW1lbnQgPSAwOwoJcHJpdmF0ZSAkZ29fdXBfb25fbmV4dF9lbGVtZW50ID0gMDsKCXByaXZhdGUgJG5lc3RpbmdfbGV2ZWwgPSAwOwoJcHJpdmF0ZSAkY29udGFpbnNfbmVzdGluZ19sZXZlbCA9IDA7Cglwcml2YXRlICRpbmRlbnRhdGlvbj0gJyAgJzsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPnhtbCA9ICcnOwoJCSR0aGlzLT5pbml0X25ld19kb20oKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdG9fc3RyaW5nKCkgewoJCXJldHVybiAkdGhpcy0+eG1sIC49ICR0aGlzLT5pbmRlbnQoICR0aGlzLT54bWxfZnJvbV9kb20oKSwgJHRoaXMtPm5lc3RpbmdfbGV2ZWwgKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gX19jYWxsKCAkbmFtZSwgJGFyZ3MgKSB7CgkJYXJyYXlfdW5zaGlmdCggJGFyZ3MsICRuYW1lICk7CgkJcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KCBhcnJheSggJHRoaXMsICd0YWcnICksICRhcmdzICk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIF9fZ2V0KCAkbmFtZSApIHsKCQlyZXR1cm4gJHRoaXMtPiRuYW1lKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGNvbnRhaW5zKCkgewoJCSR0aGlzLT5jb250YWluc19uZXN0aW5nX2xldmVsKys7CgkJJHRoaXMtPm5lc3RpbmdfbGV2ZWwrKzsKCQlpZiAoICR0aGlzLT5nb19kZWVwX29uX25leHRfZWxlbWVudCApIHsKCQkJdGhyb3cgbmV3IE94eW1lbEV4Y2VwdGlvbiggJ2NvbnRhaW5zIGNhbm5vdCBiZSB1c2VkIGNvbnNlY3V0aXZlbHkgbW9yZSB0aGFuIG9uY2UnICk7CgkJfQoJCSR0aGlzLT5nb19kZWVwX29uX25leHRfZWxlbWVudCsrOwoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZW5kKCkgewoJCSR0aGlzLT5jb250YWluc19uZXN0aW5nX2xldmVsLS07CgkJJHRoaXMtPm5lc3RpbmdfbGV2ZWwtLTsKCQlpZiAoICR0aGlzLT5jb250YWluc19uZXN0aW5nX2xldmVsIDwgMCApIHsKCQkJdGhyb3cgbmV3IE94eW1lbEV4Y2VwdGlvbiggJ2VuZCBpcyB1c2VkIHdpdGhvdXQgYSBtYXRjaGluZyBjb250YWlucycgKTsKCQl9CgkJJHRoaXMtPmdvX3VwX29uX25leHRfZWxlbWVudCsrOwoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gdGFnKCAkbmFtZSwgJGNvbnRlbnRfb3JfYXR0cmlidXRlcyA9IG51bGwsICRhdHRyaWJ1dGVzID0gYXJyYXkoKSApIHsKCQlsaXN0KCAkY29udGVudCwgJGF0dHJpYnV0ZXMgKSA9ICR0aGlzLT5nZXRfY29udGVudF9hbmRfYXR0cmlidXRlc19mcm9tX3RhZ19hcmdzKCAkY29udGVudF9vcl9hdHRyaWJ1dGVzLCAkYXR0cmlidXRlcyApOwoJCSRpc19vcGVuaW5nID0gIDAgPT09IHN0cnBvcyggJG5hbWUsICdvcGVuXycgKTsKCQkkaXNfY2xvc2luZyA9ICAwID09PSBzdHJwb3MoICRuYW1lLCAnY2xvc2VfJyApOwoJCSRuYW1lID0gcHJlZ19yZXBsYWNlKCIvXihvcGVufGNsb3NlKV8vIiwgJycsICRuYW1lICk7CgoJCSRlbGVtZW50ID0gJHRoaXMtPmNyZWF0ZV9lbGVtZW50KCAkbmFtZSwgJGNvbnRlbnQsICRhdHRyaWJ1dGVzICk7CgoJCWlmICggISRpc19vcGVuaW5nICYmICEkaXNfY2xvc2luZyApCgkJCSR0aGlzLT5hZGRfZWxlbWVudF90b19kb20oICRlbGVtZW50ICk7CgkJZWxzZWlmICggJGlzX29wZW5pbmcgKQoJCQkkdGhpcy0+YWRkX29wZW5pbmdfdGFnX2Zyb21fZWxlbWVudCggJGVsZW1lbnQgKTsKCQllbHNlaWYgKCAkaXNfY2xvc2luZyApCgkJCSR0aGlzLT5hZGRfY2xvc2luZ190YWdfZnJvbV90YWdfbmFtZSggJG5hbWUgKTsKCgkJcmV0dXJuICR0aGlzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjZGF0YSggJHRleHQgKSB7CgkJJHRoaXMtPmFkZF9lbGVtZW50X3RvX2RvbSggJHRoaXMtPmRvbS0+Y3JlYXRlQ0RBVEFTZWN0aW9uKCAkdGV4dCApICk7CgkJcmV0dXJuICR0aGlzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiB0ZXh0KCAkdGV4dCApIHsKCQkkdGhpcy0+YWRkX2VsZW1lbnRfdG9fZG9tKCAkdGhpcy0+ZG9tLT5jcmVhdGVUZXh0Tm9kZSggJHRleHQgKSApOwoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY29tbWVudCggJHRleHQgKSB7CgkJJHRoaXMtPmFkZF9lbGVtZW50X3RvX2RvbSggJHRoaXMtPmRvbS0+Y3JlYXRlQ29tbWVudCggJHRleHQgKSApOwoJCXJldHVybiAkdGhpczsKCX0KCglwdWJsaWMgZnVuY3Rpb24geG1sKCkgewoJCSR0aGlzLT5hZGRfZWxlbWVudF90b19kb20oICR0aGlzLT5kb20tPmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbiggJ3htbCcsICd2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCInICkgKTsKCQlyZXR1cm4gJHRoaXM7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIG94eW1lbCggT3h5bWVsICRvdGhlciApIHsKCQlmb3JlYWNoKCAkb3RoZXItPmRvbS0+Y2hpbGROb2RlcyBhcyAkY2hpbGQgKSB7CgkJCSRjaGlsZCA9ICR0aGlzLT5kb20tPmltcG9ydE5vZGUoICRjaGlsZCwgdHJ1ZSApOwoJCQkkdGhpcy0+YWRkX2VsZW1lbnRfdG9fZG9tKCAkY2hpbGQgKTsKCQl9CgkJcmV0dXJuICR0aGlzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiByYXcoICAkcmF3X3htbCApIHsKCQlpZiAoICEkcmF3X3htbCApIHsKCQkJcmV0dXJuICR0aGlzOwoJCX0KCQkkZnJhZ21lbnQgPSAkdGhpcy0+ZG9tLT5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CgkJJGZyYWdtZW50LT5hcHBlbmRYTUwoJHJhd194bWwpOwoJCSR0aGlzLT5hZGRfZWxlbWVudF90b19kb20oICRmcmFnbWVudCApOwoJCXJldHVybiAkdGhpczsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGFkZF9lbGVtZW50X3RvX2RvbSggJGVsZW1lbnQgKSB7CgkJJHRoaXMtPm1vdmVfY3VycmVudF9lbGVtZW50X2RlZXAoKTsKCQkkdGhpcy0+bW92ZV9jdXJyZW50X2VsZW1lbnRfdXAoKTsKCQkkdGhpcy0+bGFzdF9pbnNlcnRlZCA9ICR0aGlzLT5jdXJyZW50X2VsZW1lbnQtPmFwcGVuZENoaWxkKCRlbGVtZW50KTsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIG1vdmVfY3VycmVudF9lbGVtZW50X2RlZXAoKSB7CgkJaWYgKCAkdGhpcy0+Z29fZGVlcF9vbl9uZXh0X2VsZW1lbnQgKSB7CgkJCWlmICggISR0aGlzLT5sYXN0X2luc2VydGVkICkgewoJCQkJdGhyb3cgbmV3IE94eW1lbEV4Y2VwdGlvbiggJ2NvbnRhaW5zIGhhcyBiZWVuIHVzZWQgYmVmb3JlIGFkZGluZyBhbnkgdGFncycgKTsKCQkJfQoJCQkkdGhpcy0+Y3VycmVudF9lbGVtZW50ID0gJHRoaXMtPmxhc3RfaW5zZXJ0ZWQ7CgkJCSR0aGlzLT5nb19kZWVwX29uX25leHRfZWxlbWVudC0tOwoJCX0KCX0KCglwcml2YXRlIGZ1bmN0aW9uIG1vdmVfY3VycmVudF9lbGVtZW50X3VwKCkgewoJCWlmICggJHRoaXMtPmdvX3VwX29uX25leHRfZWxlbWVudCApIHsKCQkJd2hpbGUgKCAkdGhpcy0+Z29fdXBfb25fbmV4dF9lbGVtZW50ICkgewoJCQkJJHRoaXMtPmN1cnJlbnRfZWxlbWVudCA9ICR0aGlzLT5jdXJyZW50X2VsZW1lbnQtPnBhcmVudE5vZGU7CgkJCQkkdGhpcy0+Z29fdXBfb25fbmV4dF9lbGVtZW50LS07CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfY29udGVudF9hbmRfYXR0cmlidXRlc19mcm9tX3RhZ19hcmdzKCAkY29udGVudF9vcl9hdHRyaWJ1dGVzLCBhcnJheSAkYXR0cmlidXRlcyApIHsKCQkkY29udGVudCA9IG51bGw7CgkJaWYgKCAhJGF0dHJpYnV0ZXMgKSB7CgkJCWlmICggaXNfYXJyYXkoICRjb250ZW50X29yX2F0dHJpYnV0ZXMgKSApCgkJCQkkYXR0cmlidXRlcyA9ICRjb250ZW50X29yX2F0dHJpYnV0ZXM7CgkJCWVsc2UKCQkJCSRjb250ZW50ID0gJGNvbnRlbnRfb3JfYXR0cmlidXRlczsKCQl9IGVsc2UgewoJCQkkY29udGVudCA9ICRjb250ZW50X29yX2F0dHJpYnV0ZXM7CgkJfQoJCXJldHVybiBhcnJheSggJGNvbnRlbnQsICRhdHRyaWJ1dGVzICk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBpbml0X25ld19kb20oKSB7CgkJdW5zZXQoICR0aGlzLT5kb20sICR0aGlzLT5jdXJyZW50X2VsZW1lbnQgKTsKCQkkdGhpcy0+ZG9tID0gbmV3IERPTURvY3VtZW50KCk7CgkJJHRoaXMtPmRvbS0+Zm9ybWF0T3V0cHV0ID0gdHJ1ZTsKCQkkdGhpcy0+Y3VycmVudF9lbGVtZW50ID0gJHRoaXMtPmRvbTsKCQkkdGhpcy0+bGFzdF9pbnNlcnRlZCA9IG51bGw7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiB4bWxfZnJvbV9kb20oKSB7CgkJaWYgKCAwICE9PSAkdGhpcy0+Y29udGFpbnNfbmVzdGluZ19sZXZlbCApIHsKCQkJdGhyb3cgbmV3IE94eW1lbEV4Y2VwdGlvbiggJ2NvbnRhaW5zIGFuZCBlbmQgY2FsbHMgZG8gbm90IG1hdGNoJyApOwoJCX0KCQkkeG1sID0gJyc7CgkJZm9yZWFjaCggJHRoaXMtPmRvbS0+Y2hpbGROb2RlcyBhcyAkY2hpbGQgKSB7CgkJCSR4bWwgLj0gJHRoaXMtPmRvbS0+c2F2ZVhNTCggJGNoaWxkICkgLiAiXG4iOwoJCX0KCQlyZXR1cm4gJHhtbDsKCX0KCglwcml2YXRlIGZ1bmN0aW9uIGNyZWF0ZV9lbGVtZW50KCAkbmFtZSwgJGNvbnRlbnQsICRhdHRyaWJ1dGVzICkgewoJCWlmICggIWlzX251bGwoICRjb250ZW50ICkgKQoJCQkkZWxlbWVudCA9ICR0aGlzLT5kb20tPmNyZWF0ZUVsZW1lbnQoICRuYW1lLCAkY29udGVudCApOwoJCWVsc2UKCQkJJGVsZW1lbnQgPSAkdGhpcy0+ZG9tLT5jcmVhdGVFbGVtZW50KCAkbmFtZSApOwoKCQlmb3JlYWNoKCAkYXR0cmlidXRlcyBhcyAkYXR0cmlidXRlX25hbWUgPT4gJGF0dHJpYnV0ZV92YWx1ZSApIHsKCQkJJGVsZW1lbnQtPnNldEF0dHJpYnV0ZSggJGF0dHJpYnV0ZV9uYW1lLCAkYXR0cmlidXRlX3ZhbHVlICk7CgkJfQoKCQlyZXR1cm4gJGVsZW1lbnQ7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhZGRfb3BlbmluZ190YWdfZnJvbV9lbGVtZW50KCAkZWxlbWVudCApIHsKCQkkdGhpcy0+eG1sIC49ICR0aGlzLT5pbmRlbnQoICR0aGlzLT54bWxfZnJvbV9kb20oKSwgJHRoaXMtPm5lc3RpbmdfbGV2ZWwgKTsKCQkkdGFnID0gJHRoaXMtPmRvbS0+c2F2ZVhNTCgkZWxlbWVudCk7CgkJJHRoaXMtPnhtbCAuPSAkdGhpcy0+aW5kZW50KCBzdHJfcmVwbGFjZSggJy8+JywgJz4nLCAkdGFnICkgLiAiXG4iLCAkdGhpcy0+bmVzdGluZ19sZXZlbCApOwoJCSR0aGlzLT5uZXN0aW5nX2xldmVsKys7CgkJJHRoaXMtPmluaXRfbmV3X2RvbSgpOwoJfQoKCXByaXZhdGUgZnVuY3Rpb24gYWRkX2Nsb3NpbmdfdGFnX2Zyb21fdGFnX25hbWUoICRuYW1lICkgewoJCSR0aGlzLT54bWwgLj0gJHRoaXMtPnhtbF9mcm9tX2RvbSgpOwoJCSR0aGlzLT5uZXN0aW5nX2xldmVsLS07CgkJaWYgKCAkdGhpcy0+bmVzdGluZ19sZXZlbCA8IDAgKSB7CgkJCSR0aGlzLT54bWwgPSAkdGhpcy0+aW5kZW50KCAkdGhpcy0+eG1sLCAtJHRoaXMtPm5lc3RpbmdfbGV2ZWwgKTsKCQkJJHRoaXMtPm5lc3RpbmdfbGV2ZWwgPSAwOwoJCX0KCQkkdGhpcy0+eG1sIC49ICR0aGlzLT5pbmRlbnQoICI8LyRuYW1lPlxuIiwgJHRoaXMtPm5lc3RpbmdfbGV2ZWwgKTsKCQkkdGhpcy0+aW5pdF9uZXdfZG9tKCk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBpbmRlbnQoICRzdHJpbmcsICRsZXZlbCApIHsKCQlpZiAoICEkbGV2ZWwgKSB7CgkJCXJldHVybiAkc3RyaW5nOwoJCX0KCQkkbGluZXMgPSBleHBsb2RlKCAiXG4iLCAkc3RyaW5nICk7CgkJZm9yZWFjaCggJGxpbmVzIGFzICYkbGluZSApIHsKCQkJaWYgKCAhdHJpbSggJGxpbmUgKSApCgkJCQljb250aW51ZTsKCQkJJGxpbmUgPSBzdHJfcmVwZWF0KCAkdGhpcy0+aW5kZW50YXRpb24sICRsZXZlbCApIC4gJGxpbmU7CgkJfQoJCXJldHVybiBpbXBsb2RlKCAiXG4iLCAkbGluZXMgKTsKCX0KfQoKY2xhc3MgT3h5bWVsRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKfQo8P3BocApyZXF1aXJlX29uY2UgZGlybmFtZSggX19GSUxFX18gKSAuICcvT3h5bWVsLnBocCc7CgpjbGFzcyBPeHltZWxUZXN0IGV4dGVuZHMgUEhQVW5pdF9GcmFtZXdvcmtfVGVzdENhc2UgewoJZnVuY3Rpb24gX19jb25zdHJ1Y3QoKSB7CgkJJHRoaXMtPnggPSBuZXcgT3h5bWVsOwoJfQoKCWZ1bmN0aW9uIHRlc3RfeG1sX2FkZHNfcHJvY2VzaW5nX2luc3RydXRpb25fd2l0aF92ZXJzaW9uX2FuZF9lbmNvZGluZygpIHsKCQkkdGhpcy0+YSggJzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+JywgJHRoaXMtPngtPnhtbCApOwoJfQoKCWZ1bmN0aW9uIHRlc3Rfc2VsZl9jbG9zaW5nKCkgewoJCSR0aGlzLT5hKCc8YmFiYS8+JywgJHRoaXMtPngtPmJhYmEpOwoJfQoJZnVuY3Rpb24gdGVzdF9zZWxmX2Nsb3NpbmdfbWV0aG9kKCkgewoJCSR0aGlzLT5hKCc8YmFiYS8+JywgJHRoaXMtPngtPmJhYmEoKSk7Cgl9CglmdW5jdGlvbiB0ZXN0X2F0dHJpYnV0ZV9ub19jb250ZW50KCkgewoJCSR0aGlzLT5hKCc8YmFiYSBhPSJiIiBjPSJkIi8+JywgJHRoaXMtPngtPmJhYmEoIGFycmF5KCAnYScgPT4gJ2InLCAnYycgPT4gJ2QnICkgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfY29udGVudF9ub19hdHRyaWJ1dGUoKSB7CgkJJHRoaXMtPmEoJzxiYWJhPmNvbnRlbnQ8L2JhYmE+JywgJHRoaXMtPngtPmJhYmEoICdjb250ZW50JyApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9lc2NhcGlpbmdfb2ZfY29udGVudCgpIHsKCQkkdGhpcy0+YSgnPGJhYmE+Jmx0OzwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYSggJzwnICkgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2VzY2FwaW5nX29mX2F0dHJpYnV0ZXMoKSB7CgkJJHRoaXMtPmEoJzxiYWJhIGE9IiZsdDsiLz4nLCAkdGhpcy0+eC0+YmFiYSggYXJyYXkoICdhJyA9PiAnPCcgKSApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9jb250ZW50X2FuZF9hdHRyaWJ1dGVzKCkgewoJCSR0aGlzLT5hKCc8YmFiYSBhPSJiIiBjPSJkIj5jb250ZW50PC9iYWJhPicsICR0aGlzLT54LT5iYWJhKCAnY29udGVudCcsIGFycmF5KCAnYScgPT4gJ2InLCAnYycgPT4gJ2QnICkgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfY29udGVudF9hbmRfYXR0cmlidXRlc19lcnJvcigpIHsKCQkkdGhpcy0+c2V0RXhwZWN0ZWRFeGNlcHRpb24oICdQSFBVbml0X0ZyYW1ld29ya19FcnJvcicgKTsKCQkkdGhpcy0+YSgnPGJhYmEgYT0iYiIgYz0iZCI+Y29udGVudDwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYSggYXJyYXkoICdhJyA9PiAnYicsICdjJyA9PiAnZCcgKSwgJ2NvbnRlbnQnICkgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2dvX2Rvd24oKSB7CgkJJHRoaXMtPmEoJzxiYWJhPgogIDxkeWFkby8+CjwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYS0+Y29udGFpbnMtPmR5YWRvLT5lbmQgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2dvX2Rvd25fYW5kX3VwKCkgewoJCSR0aGlzLT5hKCI8bGV2ZWwwPgogIDxsZXZlbDEvPgo8L2xldmVsMD4KPGxldmVsMC8+IiwgJHRoaXMtPngtPmxldmVsMC0+Y29udGFpbnMtPmxldmVsMS0+ZW5kLT5sZXZlbDAgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NkYXRhKCkgewoJCSR0aGlzLT5hKCc8YmFiYT48IVtDREFUQVtjb250ZW50XV0+PC9iYWJhPicsICR0aGlzLT54LT5iYWJhLT5jb250YWlucy0+Y2RhdGEoJ2NvbnRlbnQnKS0+ZW5kKTsKCX0KCglmdW5jdGlvbiB0ZXN0X25lc3RlZF9jZGF0YSgpIHsKCQkkdGhpcy0+YSggJzwhW0NEQVRBW3hdXV1dPjwhW0NEQVRBWz5dXT4nLCAkdGhpcy0+eC0+Y2RhdGEoICd4XV0+JyApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9yYXcoKSB7CgkJJHRoaXMtPmEoJzxiYWJhPgogIDxkeWFkby8+CjwvYmFiYT4nLCAkdGhpcy0+eC0+YmFiYS0+Y29udGFpbnMtPnJhdygnPGR5YWRvPjwvZHlhZG8+JyktPmVuZCk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9yYXdfZG9lc250X2RvX2FueXRoaW5nX3dpdGhfZW1wdHlfYXJnKCkgewoJCSR0aGlzLT5hKCc8YmFiYS8+JywgJHRoaXMtPngtPmJhYmEtPnJhdyggJycgKSApOwoJfQoKCWZ1bmN0aW9uIHRlc3Rfb3h5bWVsX25zKCkgewoJCSRveHltZWwgPSBuZXcgT3h5bWVsOwoJCSRveHltZWwtPnRhZyggJ3dwOmJhYmEnICk7CgkJJHRoaXMtPmEoICc8d3A6YmFiYS8+JywgJHRoaXMtPngtPm94eW1lbCggJG94eW1lbCApICk7Cgl9CgoJZnVuY3Rpb24geF90ZXN0X29ubHlfdXBfZXJyb3IoKSB7CgkJJHRoaXMtPmEoJycsICR0aGlzLT54LT5lbmQgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X29wZW5faW5fdGhlX2VuZCgpIHsKCQkkdGhpcy0+YSgiPGJhYmEvPgo8bmV3dGFnPiIsICR0aGlzLT54LT5iYWJhLT5vcGVuX25ld3RhZyApOwoJfQoKCWZ1bmN0aW9uIHRlc3Rfb3Blbl93aXRoX2F0dHJpYnV0ZXMoKSB7CgkJJHRoaXMtPmEoIjxiYWJhLz4KPG5ld3RhZyBhPVwiYlwiPiIsICR0aGlzLT54LT5iYWJhLT5vcGVuX25ld3RhZyggYXJyYXkoICdhJyA9PiAnYicgKSApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9kb21fb3Blbl9kb20oKSB7CgkJJHRoaXMtPmEoIjxiYWJhLz4KPG5ld3RhZz4KICA8YmFiYS8+IiwgJHRoaXMtPngtPmJhYmEtPm9wZW5fbmV3dGFnLT5iYWJhICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9jbG9zZV9pbl90aGVfYmVnaW5uaW5nKCkgewoJCSR0aGlzLT5hKCI8L29sZHRhZz4KPGJhYmEvPiIsICR0aGlzLT54LT5jbG9zZV9vbGR0YWctPmJhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2RvbV9jbG9zZV9kb20oKSB7CgkJJHRoaXMtPmEoIiAgPGJhYmEvPgo8L29sZHRhZz4KPGJhYmEvPiIsICR0aGlzLT54LT5iYWJhLT5jbG9zZV9vbGR0YWctPmJhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2JhYmEoKSB7CgkJJHRoaXMtPmEoIjxhPmJhYmE8eC8+PC9hPiIsICR0aGlzLT54LT5hKCdiYWJhJyktPmNvbnRhaW5zLT54LT5lbmQgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NvbW1lbnQoKSB7CgkJJHRoaXMtPmEoJzwhLS1iYWJhLS0+JywgJHRoaXMtPngtPmNvbW1lbnQoJ2JhYmEnKSk7Cgl9CgoJZnVuY3Rpb24gdGVzdF90d29faW52b2NhdGlvbnMoKSB7CgkJJHRoaXMtPngtPmJhYmEoKTsKCQkkdGhpcy0+eC0+ZHlhZG8oKTsKCQkkdGhpcy0+YSggIjxiYWJhLz4KPGR5YWRvLz4iLCAkdGhpcy0+eCApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfZG91YmxlX2VuZCgpIHsKCQkkdGhpcy0+YSggIjxvdXQ+CiAgPG1pZD4KICAgIDxpbi8+CiAgPC9taWQ+Cjwvb3V0Pgo8bmV4dG91dC8+IiwgJHRoaXMtPngtPm91dC0+Y29udGFpbnMtPm1pZC0+Y29udGFpbnMtPmluLT5lbmQtPmVuZC0+bmV4dG91dCApOwoJfQoKCWZ1bmN0aW9uIHRlc3RfZW5kX3dpdGhvdXRfY29udGFpbnMoKSB7CgkJJHRoaXMtPnNldEV4cGVjdGVkRXhjZXB0aW9uKCAnT3h5bWVsRXhjZXB0aW9uJyApOwoJCSR0aGlzLT54LT5lbmQtPmJhYmE7Cgl9CgoJZnVuY3Rpb24gdGVzdF9sZWFkaW5nX2NvbnRhaW5zKCkgewoJCSR0aGlzLT5zZXRFeHBlY3RlZEV4Y2VwdGlvbiggJ094eW1lbEV4Y2VwdGlvbicgKTsKCQkkdGhpcy0+YSggJzxiYWJhLz4nLCAkdGhpcy0+eC0+Y29udGFpbnMtPmJhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X2NvbnNlY3V0aXZlX2NvbnRhaW5zX3Nob3VsZF9lcnJvcigpIHsKCQkkdGhpcy0+c2V0RXhwZWN0ZWRFeGNlcHRpb24oICdPeHltZWxFeGNlcHRpb24nICk7CgkJJHRoaXMtPngtPmJhYmEtPmNvbnRhaW5zLT5jb250YWlucy0+ZHlhZG8tPmVuZC0+d2luazsKCX0KCglmdW5jdGlvbiB0ZXN0X2VuZF93aXRob3V0X21hdGhjaW5nX2NvbnRhaW5zX2J1dF93aXRoX2Vub3VnaF9wYXJlbnRzKCkgewoJCSR0aGlzLT5zZXRFeHBlY3RlZEV4Y2VwdGlvbiggJ094eW1lbEV4Y2VwdGlvbicgKTsKCQkkdGhpcy0+eC0+Y29udGFpbnMtPmJhYmEtPmVuZC0+ZW5kLT5iYWJhOwoJfQoKCWZ1bmN0aW9uIHRlc3RfY29udGFpbnNfYWZ0ZXJfbmV3bHlfaW5pdGlhbGl6ZWRfZG9tX3Nob3VsZF9lcnJvcigpIHsKCQkkdGhpcy0+c2V0RXhwZWN0ZWRFeGNlcHRpb24oICdPeHltZWxFeGNlcHRpb24nICk7CgkJJHRoaXMtPngtPmJhYmEtPm9wZW5fcnNzLT5jb250YWlucy0+YmFiYS0+ZW5kOwoJfQoKCWZ1bmN0aW9uIHRlc3RfbmVzdGVkX29wZW5fdGFnc19zaG91bGRfYmVfaW5kZW50ZWQoKSB7CgkJJHRoaXMtPmEoICI8YmFiYT4KICA8YmFiYT4iLCAkdGhpcy0+eC0+b3Blbl9iYWJhLT5vcGVuX2JhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X25vcm1hbF94bWxfYmV0d2Vlbl90d29fb3BlbmluZ190YWdzX3Nob3VsZF9iZV9pbmRlbnRlZCgpIHsKCQkkdGhpcy0+YSggIjxiYWJhPgogIDxiYWJhLz4KICA8YmFiYT4iLCAkdGhpcy0+eC0+b3Blbl9iYWJhLT5iYWJhLT5vcGVuX2JhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X25vcm1hbF94bWxfYWZ0ZXJfb3BlbmluZ190YWdfc2hvdWxkX2JlX2luZGVudGVkKCkgewoJCSR0aGlzLT5hKCAiPGJhYmE+CiAgPGJhYmEvPiIsICR0aGlzLT54LT5vcGVuX2JhYmEtPmJhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X25vcm1hbF94bWxfYmVmb3JlX2Nsb3NpbmdfdGFnX3Nob3VsZF9iZV9pbmRlbnRlZCgpIHsKCQkkdGhpcy0+YSggIiAgPGJhYmEvPgo8L2JhYmE+IiwgJHRoaXMtPngtPmJhYmEtPmNsb3NlX2JhYmEgKTsKCX0KCglmdW5jdGlvbiB0ZXN0X3RleHRfc2hvdWxkX2VzY2FwZV90aGVfY29udGVudF9pbnNpZGUoKSB7CgkJJHRoaXMtPmEoICdhICZhbXA7IGInLCAkdGhpcy0+eC0+dGV4dCggJ2EgJiBiJyApICk7Cgl9CgoJZnVuY3Rpb24gdGVzdF9kYW5nbGluZ19jb250YWluc19zaG91bGRfYmVfY2F1Z2h0X2luX3RoZV9lbmQoKSB7CgkJJHRoaXMtPnNldEV4cGVjdGVkRXhjZXB0aW9uKCAnT3h5bWVsRXhjZXB0aW9uJyApOwoJCSR0aGlzLT54LT5jb250YWlucy0+dG9fc3RyaW5nKCk7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBhKCR2YWx1ZSwgJHgpIHsKCQkkdGhpcy0+YXNzZXJ0RXF1YWxzKCAkdmFsdWUgLiAiXG4iLCAkeC0+dG9fc3RyaW5nKCkpOwoJfQp9Cjw/cGhwCgpuYW1lc3BhY2UgUHNyXExvZzsKCi8qKgogKiBUaGlzIGlzIGEgc2ltcGxlIExvZ2dlciBpbXBsZW1lbnRhdGlvbiB0aGF0IG90aGVyIExvZ2dlcnMgY2FuIGluaGVyaXQgZnJvbS4KICoKICogSXQgc2ltcGx5IGRlbGVnYXRlcyBhbGwgbG9nLWxldmVsLXNwZWNpZmljIG1ldGhvZHMgdG8gdGhlIGBsb2dgIG1ldGhvZCB0bwogKiByZWR1Y2UgYm9pbGVycGxhdGUgY29kZSB0aGF0IGEgc2ltcGxlIExvZ2dlciB0aGF0IGRvZXMgdGhlIHNhbWUgdGhpbmcgd2l0aAogKiBtZXNzYWdlcyByZWdhcmRsZXNzIG9mIHRoZSBlcnJvciBsZXZlbCBoYXMgdG8gaW1wbGVtZW50LgogKi8KYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RMb2dnZXIgaW1wbGVtZW50cyBMb2dnZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTeXN0ZW0gaXMgdW51c2FibGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbWVyZ2VuY3koJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpFTUVSR0VOQ1ksICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBY3Rpb24gbXVzdCBiZSB0YWtlbiBpbW1lZGlhdGVseS4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBFbnRpcmUgd2Vic2l0ZSBkb3duLCBkYXRhYmFzZSB1bmF2YWlsYWJsZSwgZXRjLiBUaGlzIHNob3VsZAogICAgICogdHJpZ2dlciB0aGUgU01TIGFsZXJ0cyBhbmQgd2FrZSB5b3UgdXAuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGVydCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkFMRVJULCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JpdGljYWwgY29uZGl0aW9ucy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBBcHBsaWNhdGlvbiBjb21wb25lbnQgdW5hdmFpbGFibGUsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JpdGljYWwoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpDUklUSUNBTCwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1bnRpbWUgZXJyb3JzIHRoYXQgZG8gbm90IHJlcXVpcmUgaW1tZWRpYXRlIGFjdGlvbiBidXQgc2hvdWxkIHR5cGljYWxseQogICAgICogYmUgbG9nZ2VkIGFuZCBtb25pdG9yZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkVSUk9SLCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogRXhjZXB0aW9uYWwgb2NjdXJyZW5jZXMgdGhhdCBhcmUgbm90IGVycm9ycy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2Ugb2YgZGVwcmVjYXRlZCBBUElzLCBwb29yIHVzZSBvZiBhbiBBUEksIHVuZGVzaXJhYmxlIHRoaW5ncwogICAgICogdGhhdCBhcmUgbm90IG5lY2Vzc2FyaWx5IHdyb25nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OldBUk5JTkcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGljZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6Ok5PVElDRSwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEludGVyZXN0aW5nIGV2ZW50cy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2VyIGxvZ3MgaW4sIFNRTCBsb2dzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OklORk8sICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXRhaWxlZCBkZWJ1ZyBpbmZvcm1hdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlYnVnKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6REVCVUcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIERlc2NyaWJlcyBhIGxvZ2dlci1hd2FyZSBpbnN0YW5jZS4KICovCmludGVyZmFjZSBMb2dnZXJBd2FyZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFNldHMgYSBsb2dnZXIgaW5zdGFuY2Ugb24gdGhlIG9iamVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExvZ2dlcihMb2dnZXJJbnRlcmZhY2UgJGxvZ2dlcik7Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIERlc2NyaWJlcyBsb2cgbGV2ZWxzLgogKi8KY2xhc3MgTG9nTGV2ZWwKewogICAgY29uc3QgRU1FUkdFTkNZID0gJ2VtZXJnZW5jeSc7CiAgICBjb25zdCBBTEVSVCAgICAgPSAnYWxlcnQnOwogICAgY29uc3QgQ1JJVElDQUwgID0gJ2NyaXRpY2FsJzsKICAgIGNvbnN0IEVSUk9SICAgICA9ICdlcnJvcic7CiAgICBjb25zdCBXQVJOSU5HICAgPSAnd2FybmluZyc7CiAgICBjb25zdCBOT1RJQ0UgICAgPSAnbm90aWNlJzsKICAgIGNvbnN0IElORk8gICAgICA9ICdpbmZvJzsKICAgIGNvbnN0IERFQlVHICAgICA9ICdkZWJ1Zyc7Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIEJhc2ljIEltcGxlbWVudGF0aW9uIG9mIExvZ2dlckF3YXJlSW50ZXJmYWNlLgogKi8KdHJhaXQgTG9nZ2VyQXdhcmVUcmFpdAp7CiAgICAvKioKICAgICAqIFRoZSBsb2dnZXIgaW5zdGFuY2UuCiAgICAgKgogICAgICogQHZhciBMb2dnZXJJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxvZ2dlcjsKCiAgICAvKioKICAgICAqIFNldHMgYSBsb2dnZXIuCiAgICAgKgogICAgICogQHBhcmFtIExvZ2dlckludGVyZmFjZSAkbG9nZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2dnZXIoTG9nZ2VySW50ZXJmYWNlICRsb2dnZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZ2dlciA9ICRsb2dnZXI7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKY2xhc3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGV4dGVuZHMgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgp7Cn0KPD9waHAKCm5hbWVzcGFjZSBQc3JcTG9nOwoKLyoqCiAqIFRoaXMgaXMgYSBzaW1wbGUgTG9nZ2VyIHRyYWl0IHRoYXQgY2xhc3NlcyB1bmFibGUgdG8gZXh0ZW5kIEFic3RyYWN0TG9nZ2VyCiAqIChiZWNhdXNlIHRoZXkgZXh0ZW5kIGFub3RoZXIgY2xhc3MsIGV0YykgY2FuIGluY2x1ZGUuCiAqCiAqIEl0IHNpbXBseSBkZWxlZ2F0ZXMgYWxsIGxvZy1sZXZlbC1zcGVjaWZpYyBtZXRob2RzIHRvIHRoZSBgbG9nYCBtZXRob2QgdG8KICogcmVkdWNlIGJvaWxlcnBsYXRlIGNvZGUgdGhhdCBhIHNpbXBsZSBMb2dnZXIgdGhhdCBkb2VzIHRoZSBzYW1lIHRoaW5nIHdpdGgKICogbWVzc2FnZXMgcmVnYXJkbGVzcyBvZiB0aGUgZXJyb3IgbGV2ZWwgaGFzIHRvIGltcGxlbWVudC4KICovCnRyYWl0IExvZ2dlclRyYWl0CnsKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVtZXJnZW5jeSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkVNRVJHRU5DWSwgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEFjdGlvbiBtdXN0IGJlIHRha2VuIGltbWVkaWF0ZWx5LgogICAgICoKICAgICAqIEV4YW1wbGU6IEVudGlyZSB3ZWJzaXRlIGRvd24sIGRhdGFiYXNlIHVuYXZhaWxhYmxlLCBldGMuIFRoaXMgc2hvdWxkCiAgICAgKiB0cmlnZ2VyIHRoZSBTTVMgYWxlcnRzIGFuZCB3YWtlIHlvdSB1cC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbGVydCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OkFMRVJULCAkbWVzc2FnZSwgJGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JpdGljYWwgY29uZGl0aW9ucy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBBcHBsaWNhdGlvbiBjb21wb25lbnQgdW5hdmFpbGFibGUsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyaXRpY2FsKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6Q1JJVElDQUwsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSdW50aW1lIGVycm9ycyB0aGF0IGRvIG5vdCByZXF1aXJlIGltbWVkaWF0ZSBhY3Rpb24gYnV0IHNob3VsZCB0eXBpY2FsbHkKICAgICAqIGJlIGxvZ2dlZCBhbmQgbW9uaXRvcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6RVJST1IsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGNlcHRpb25hbCBvY2N1cnJlbmNlcyB0aGF0IGFyZSBub3QgZXJyb3JzLgogICAgICoKICAgICAqIEV4YW1wbGU6IFVzZSBvZiBkZXByZWNhdGVkIEFQSXMsIHBvb3IgdXNlIG9mIGFuIEFQSSwgdW5kZXNpcmFibGUgdGhpbmdzCiAgICAgKiB0aGF0IGFyZSBub3QgbmVjZXNzYXJpbHkgd3JvbmcuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICogQHBhcmFtIGFycmF5ICAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2FybmluZygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKQogICAgewogICAgICAgICR0aGlzLT5sb2coTG9nTGV2ZWw6OldBUk5JTkcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub3RpY2UoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bG9nKExvZ0xldmVsOjpOT1RJQ0UsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcmVzdGluZyBldmVudHMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlciBsb2dzIGluLCBTUUwgbG9ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmZvKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6SU5GTywgJG1lc3NhZ2UsICRjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIERldGFpbGVkIGRlYnVnIGluZm9ybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlYnVnKCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPmxvZyhMb2dMZXZlbDo6REVCVUcsICRtZXNzYWdlLCAkY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgJGxldmVsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gYXJyYXkgICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcUHNyXExvZ1xJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUHNyXExvZzsKCi8qKgogKiBEZXNjcmliZXMgYSBsb2dnZXIgaW5zdGFuY2UuCiAqCiAqIFRoZSBtZXNzYWdlIE1VU1QgYmUgYSBzdHJpbmcgb3Igb2JqZWN0IGltcGxlbWVudGluZyBfX3RvU3RyaW5nKCkuCiAqCiAqIFRoZSBtZXNzYWdlIE1BWSBjb250YWluIHBsYWNlaG9sZGVycyBpbiB0aGUgZm9ybToge2Zvb30gd2hlcmUgZm9vCiAqIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGNvbnRleHQgZGF0YSBpbiBrZXkgImZvbyIuCiAqCiAqIFRoZSBjb250ZXh0IGFycmF5IGNhbiBjb250YWluIGFyYml0cmFyeSBkYXRhLiBUaGUgb25seSBhc3N1bXB0aW9uIHRoYXQKICogY2FuIGJlIG1hZGUgYnkgaW1wbGVtZW50b3JzIGlzIHRoYXQgaWYgYW4gRXhjZXB0aW9uIGluc3RhbmNlIGlzIGdpdmVuCiAqIHRvIHByb2R1Y2UgYSBzdGFjayB0cmFjZSwgaXQgTVVTVCBiZSBpbiBhIGtleSBuYW1lZCAiZXhjZXB0aW9uIi4KICoKICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9waHAtZmlnL2ZpZy1zdGFuZGFyZHMvYmxvYi9tYXN0ZXIvYWNjZXB0ZWQvUFNSLTMtbG9nZ2VyLWludGVyZmFjZS5tZAogKiBmb3IgdGhlIGZ1bGwgaW50ZXJmYWNlIHNwZWNpZmljYXRpb24uCiAqLwppbnRlcmZhY2UgTG9nZ2VySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogU3lzdGVtIGlzIHVudXNhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW1lcmdlbmN5KCRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwoKICAgIC8qKgogICAgICogQWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkuCiAgICAgKgogICAgICogRXhhbXBsZTogRW50aXJlIHdlYnNpdGUgZG93biwgZGF0YWJhc2UgdW5hdmFpbGFibGUsIGV0Yy4gVGhpcyBzaG91bGQKICAgICAqIHRyaWdnZXIgdGhlIFNNUyBhbGVydHMgYW5kIHdha2UgeW91IHVwLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWxlcnQoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBDcml0aWNhbCBjb25kaXRpb25zLgogICAgICoKICAgICAqIEV4YW1wbGU6IEFwcGxpY2F0aW9uIGNvbXBvbmVudCB1bmF2YWlsYWJsZSwgdW5leHBlY3RlZCBleGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcml0aWNhbCgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIFJ1bnRpbWUgZXJyb3JzIHRoYXQgZG8gbm90IHJlcXVpcmUgaW1tZWRpYXRlIGFjdGlvbiBidXQgc2hvdWxkIHR5cGljYWxseQogICAgICogYmUgbG9nZ2VkIGFuZCBtb25pdG9yZWQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbmFsIG9jY3VycmVuY2VzIHRoYXQgYXJlIG5vdCBlcnJvcnMuCiAgICAgKgogICAgICogRXhhbXBsZTogVXNlIG9mIGRlcHJlY2F0ZWQgQVBJcywgcG9vciB1c2Ugb2YgYW4gQVBJLCB1bmRlc2lyYWJsZSB0aGluZ3MKICAgICAqIHRoYXQgYXJlIG5vdCBuZWNlc3NhcmlseSB3cm9uZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdhcm5pbmcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBOb3JtYWwgYnV0IHNpZ25pZmljYW50IGV2ZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkbWVzc2FnZQogICAgICogQHBhcmFtIG1peGVkW10gJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vdGljZSgkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIEludGVyZXN0aW5nIGV2ZW50cy4KICAgICAqCiAgICAgKiBFeGFtcGxlOiBVc2VyIGxvZ3MgaW4sIFNRTCBsb2dzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaW5mbygkbWVzc2FnZSwgYXJyYXkgJGNvbnRleHQgPSBhcnJheSgpKTsKCiAgICAvKioKICAgICAqIERldGFpbGVkIGRlYnVnIGluZm9ybWF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICRtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWl4ZWRbXSAkY29udGV4dAogICAgICoKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVidWcoJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSk7CgogICAgLyoqCiAgICAgKiBMb2dzIHdpdGggYW4gYXJiaXRyYXJ5IGxldmVsLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICRsZXZlbAogICAgICogQHBhcmFtIHN0cmluZyAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtaXhlZFtdICRjb250ZXh0CiAgICAgKgogICAgICogQHJldHVybiB2b2lkCiAgICAgKgogICAgICogQHRocm93cyBcUHNyXExvZ1xJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGxvZygkbGV2ZWwsICRtZXNzYWdlLCBhcnJheSAkY29udGV4dCA9IGFycmF5KCkpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgUHNyXExvZzsKCi8qKgogKiBUaGlzIExvZ2dlciBjYW4gYmUgdXNlZCB0byBhdm9pZCBjb25kaXRpb25hbCBsb2cgY2FsbHMuCiAqCiAqIExvZ2dpbmcgc2hvdWxkIGFsd2F5cyBiZSBvcHRpb25hbCwgYW5kIGlmIG5vIGxvZ2dlciBpcyBwcm92aWRlZCB0byB5b3VyCiAqIGxpYnJhcnkgY3JlYXRpbmcgYSBOdWxsTG9nZ2VyIGluc3RhbmNlIHRvIGhhdmUgc29tZXRoaW5nIHRvIHRocm93IGxvZ3MgYXQKICogaXMgYSBnb29kIHdheSB0byBhdm9pZCBsaXR0ZXJpbmcgeW91ciBjb2RlIHdpdGggYGlmICgkdGhpcy0+bG9nZ2VyKSB7IH1gCiAqIGJsb2Nrcy4KICovCmNsYXNzIE51bGxMb2dnZXIgZXh0ZW5kcyBBYnN0cmFjdExvZ2dlcgp7CiAgICAvKioKICAgICAqIExvZ3Mgd2l0aCBhbiBhcmJpdHJhcnkgbGV2ZWwuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkbGV2ZWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcnJheSAgJGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxQc3JcTG9nXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbG9nKCRsZXZlbCwgJG1lc3NhZ2UsIGFycmF5ICRjb250ZXh0ID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAvLyBub29wCiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKU09OIExpbnQgcGFja2FnZS4KICoKICogKGMpIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTZWxkXEpzb25MaW50OwoKY2xhc3MgRHVwbGljYXRlS2V5RXhjZXB0aW9uIGV4dGVuZHMgUGFyc2luZ0V4Y2VwdGlvbgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHBocHN0YW4tcGFyYW0gYXJyYXl7dGV4dD86IHN0cmluZywgdG9rZW4/OiBzdHJpbmcsIGxpbmU/OiBpbnQsIGxvYz86IGFycmF5e2ZpcnN0X2xpbmU6IGludCwgZmlyc3RfY29sdW1uOiBpbnQsIGxhc3RfbGluZTogaW50LCBsYXN0X2NvbHVtbjogaW50fSwgZXhwZWN0ZWQ/OiBzdHJpbmdbXX0gJGRldGFpbHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtZXNzYWdlLCAka2V5LCBhcnJheSAkZGV0YWlscyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJGRldGFpbHNbJ2tleSddID0gJGtleTsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkZGV0YWlscyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZXRhaWxzWydrZXknXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXJldHVybiBhcnJheXt0ZXh0Pzogc3RyaW5nLCB0b2tlbj86IHN0cmluZywgbGluZT86IGludCwgbG9jPzogYXJyYXl7Zmlyc3RfbGluZTogaW50LCBmaXJzdF9jb2x1bW46IGludCwgbGFzdF9saW5lOiBpbnQsIGxhc3RfY29sdW1uOiBpbnR9LCBleHBlY3RlZD86IHN0cmluZ1tdLCBrZXk6IHN0cmluZ30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERldGFpbHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGV0YWlsczsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpTT04gTGludCBwYWNrYWdlLgogKgogKiAoYykgSm9yZGkgQm9nZ2lhbm8gPGouYm9nZ2lhbm9Ac2VsZC5iZT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIFNlbGRcSnNvbkxpbnQ7CgpjbGFzcyBQYXJzaW5nRXhjZXB0aW9uIGV4dGVuZHMgXEV4Y2VwdGlvbgp7CiAgICBwcm90ZWN0ZWQgJGRldGFpbHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlCiAgICAgKiBAcGhwc3Rhbi1wYXJhbSBhcnJheXt0ZXh0Pzogc3RyaW5nLCB0b2tlbj86IHN0cmluZywgbGluZT86IGludCwgbG9jPzogYXJyYXl7Zmlyc3RfbGluZTogaW50LCBmaXJzdF9jb2x1bW46IGludCwgbGFzdF9saW5lOiBpbnQsIGxhc3RfY29sdW1uOiBpbnR9LCBleHBlY3RlZD86IHN0cmluZ1tdfSAkZGV0YWlscwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsICRkZXRhaWxzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGV0YWlscyA9ICRkZXRhaWxzOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHBocHN0YW4tcmV0dXJuIGFycmF5e3RleHQ/OiBzdHJpbmcsIHRva2VuPzogc3RyaW5nLCBsaW5lPzogaW50LCBsb2M/OiBhcnJheXtmaXJzdF9saW5lOiBpbnQsIGZpcnN0X2NvbHVtbjogaW50LCBsYXN0X2xpbmU6IGludCwgbGFzdF9jb2x1bW46IGludH0sIGV4cGVjdGVkPzogc3RyaW5nW119CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZXRhaWxzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRldGFpbHM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKU09OIExpbnQgcGFja2FnZS4KICoKICogKGMpIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTZWxkXEpzb25MaW50Owp1c2Ugc3RkQ2xhc3M7CgovKioKICogUGFyc2VyIGNsYXNzCiAqCiAqIEV4YW1wbGU6CiAqCiAqICRwYXJzZXIgPSBuZXcgSnNvblBhcnNlcigpOwogKiAvLyByZXR1cm5zIG51bGwgaWYgaXQncyB2YWxpZCBqc29uLCBvciBhbiBlcnJvciBvYmplY3QKICogJHBhcnNlci0+bGludCgkanNvbik7CiAqIC8vIHJldHVybnMgcGFyc2VkIGpzb24sIGxpa2UganNvbl9kZWNvZGUgZG9lcywgYnV0IHNsb3dlciwgdGhyb3dzIGV4Y2VwdGlvbnMgb24gZmFpbHVyZS4KICogJHBhcnNlci0+cGFyc2UoJGpzb24pOwogKgogKiBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vemFhY2gvanNvbmxpbnQKICovCmNsYXNzIEpzb25QYXJzZXIKewogICAgY29uc3QgREVURUNUX0tFWV9DT05GTElDVFMgPSAxOwogICAgY29uc3QgQUxMT1dfRFVQTElDQVRFX0tFWVMgPSAyOwogICAgY29uc3QgUEFSU0VfVE9fQVNTT0MgPSA0OwoKICAgIHByaXZhdGUgJGxleGVyOwoKICAgIHByaXZhdGUgJGZsYWdzOwogICAgcHJpdmF0ZSAkc3RhY2s7CiAgICBwcml2YXRlICR2c3RhY2s7IC8vIHNlbWFudGljIHZhbHVlIHN0YWNrCiAgICBwcml2YXRlICRsc3RhY2s7IC8vIGxvY2F0aW9uIHN0YWNrCgogICAgLyoqCiAgICAgKiBAcGhwc3Rhbi12YXIgYXJyYXk8c3RyaW5nLCBpbnQ+CiAgICAgKi8KICAgIHByaXZhdGUgJHN5bWJvbHMgPSBhcnJheSgKICAgICAgICAnZXJyb3InICAgICAgICAgICAgICAgICA9PiAyLAogICAgICAgICdKU09OU3RyaW5nJyAgICAgICAgICAgID0+IDMsCiAgICAgICAgJ1NUUklORycgICAgICAgICAgICAgICAgPT4gNCwKICAgICAgICAnSlNPTk51bWJlcicgICAgICAgICAgICA9PiA1LAogICAgICAgICdOVU1CRVInICAgICAgICAgICAgICAgID0+IDYsCiAgICAgICAgJ0pTT05OdWxsTGl0ZXJhbCcgICAgICAgPT4gNywKICAgICAgICAnTlVMTCcgICAgICAgICAgICAgICAgICA9PiA4LAogICAgICAgICdKU09OQm9vbGVhbkxpdGVyYWwnICAgID0+IDksCiAgICAgICAgJ1RSVUUnICAgICAgICAgICAgICAgICAgPT4gMTAsCiAgICAgICAgJ0ZBTFNFJyAgICAgICAgICAgICAgICAgPT4gMTEsCiAgICAgICAgJ0pTT05UZXh0JyAgICAgICAgICAgICAgPT4gMTIsCiAgICAgICAgJ0pTT05WYWx1ZScgICAgICAgICAgICAgPT4gMTMsCiAgICAgICAgJ0VPRicgICAgICAgICAgICAgICAgICAgPT4gMTQsCiAgICAgICAgJ0pTT05PYmplY3QnICAgICAgICAgICAgPT4gMTUsCiAgICAgICAgJ0pTT05BcnJheScgICAgICAgICAgICAgPT4gMTYsCiAgICAgICAgJ3snICAgICAgICAgICAgICAgICAgICAgPT4gMTcsCiAgICAgICAgJ30nICAgICAgICAgICAgICAgICAgICAgPT4gMTgsCiAgICAgICAgJ0pTT05NZW1iZXJMaXN0JyAgICAgICAgPT4gMTksCiAgICAgICAgJ0pTT05NZW1iZXInICAgICAgICAgICAgPT4gMjAsCiAgICAgICAgJzonICAgICAgICAgICAgICAgICAgICAgPT4gMjEsCiAgICAgICAgJywnICAgICAgICAgICAgICAgICAgICAgPT4gMjIsCiAgICAgICAgJ1snICAgICAgICAgICAgICAgICAgICAgPT4gMjMsCiAgICAgICAgJ10nICAgICAgICAgICAgICAgICAgICAgPT4gMjQsCiAgICAgICAgJ0pTT05FbGVtZW50TGlzdCcgICAgICAgPT4gMjUsCiAgICAgICAgJyRhY2NlcHQnICAgICAgICAgICAgICAgPT4gMCwKICAgICAgICAnJGVuZCcgICAgICAgICAgICAgICAgICA9PiAxLAogICAgKTsKCiAgICAvKioKICAgICAqIEBwaHBzdGFuLXZhciBhcnJheTxpbnQsIHN0cmluZz4KICAgICAqLwogICAgcHJpdmF0ZSAkdGVybWluYWxzXyA9IGFycmF5KAogICAgICAgIDIgICA9PiAiZXJyb3IiLAogICAgICAgIDQgICA9PiAiU1RSSU5HIiwKICAgICAgICA2ICAgPT4gIk5VTUJFUiIsCiAgICAgICAgOCAgID0+ICJOVUxMIiwKICAgICAgICAxMCAgPT4gIlRSVUUiLAogICAgICAgIDExICA9PiAiRkFMU0UiLAogICAgICAgIDE0ICA9PiAiRU9GIiwKICAgICAgICAxNyAgPT4gInsiLAogICAgICAgIDE4ICA9PiAifSIsCiAgICAgICAgMjEgID0+ICI6IiwKICAgICAgICAyMiAgPT4gIiwiLAogICAgICAgIDIzICA9PiAiWyIsCiAgICAgICAgMjQgID0+ICJdIiwKICAgICk7CgogICAgcHJpdmF0ZSAkcHJvZHVjdGlvbnNfID0gYXJyYXkoCiAgICAgICAgMCwKICAgICAgICBhcnJheSgzLCAxKSwKICAgICAgICBhcnJheSg1LCAxKSwKICAgICAgICBhcnJheSg3LCAxKSwKICAgICAgICBhcnJheSg5LCAxKSwKICAgICAgICBhcnJheSg5LCAxKSwKICAgICAgICBhcnJheSgxMiwgMiksCiAgICAgICAgYXJyYXkoMTMsIDEpLAogICAgICAgIGFycmF5KDEzLCAxKSwKICAgICAgICBhcnJheSgxMywgMSksCiAgICAgICAgYXJyYXkoMTMsIDEpLAogICAgICAgIGFycmF5KDEzLCAxKSwKICAgICAgICBhcnJheSgxMywgMSksCiAgICAgICAgYXJyYXkoMTUsIDIpLAogICAgICAgIGFycmF5KDE1LCAzKSwKICAgICAgICBhcnJheSgyMCwgMyksCiAgICAgICAgYXJyYXkoMTksIDEpLAogICAgICAgIGFycmF5KDE5LCAzKSwKICAgICAgICBhcnJheSgxNiwgMiksCiAgICAgICAgYXJyYXkoMTYsIDMpLAogICAgICAgIGFycmF5KDI1LCAxKSwKICAgICAgICBhcnJheSgyNSwgMykKICAgICk7CgogICAgcHJpdmF0ZSAkdGFibGUgPSBhcnJheShhcnJheSgzID0+IDUsIDQgPT4gYXJyYXkoMSwxMiksIDUgPT4gNiwgNiA9PiBhcnJheSgxLDEzKSwgNyA9PiAzLCA4ID0+IGFycmF5KDEsOSksIDkgPT4gNCwgMTAgPT4gYXJyYXkoMSwxMCksIDExID0+IGFycmF5KDEsMTEpLCAxMiA9PiAxLCAxMyA9PiAyLCAxNSA9PiA3LCAxNiA9PiA4LCAxNyA9PiBhcnJheSgxLDE0KSwgMjMgPT4gYXJyYXkoMSwxNSkpLCBhcnJheSggMSA9PiBhcnJheSgzKSksIGFycmF5KCAxNCA9PiBhcnJheSgxLDE2KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDcpLCAxOCA9PiBhcnJheSgyLDcpLCAyMiA9PiBhcnJheSgyLDcpLCAyNCA9PiBhcnJheSgyLDcpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsOCksIDE4ID0+IGFycmF5KDIsOCksIDIyID0+IGFycmF5KDIsOCksIDI0ID0+IGFycmF5KDIsOCkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiw5KSwgMTggPT4gYXJyYXkoMiw5KSwgMjIgPT4gYXJyYXkoMiw5KSwgMjQgPT4gYXJyYXkoMiw5KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDEwKSwgMTggPT4gYXJyYXkoMiwxMCksIDIyID0+IGFycmF5KDIsMTApLCAyNCA9PiBhcnJheSgyLDEwKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDExKSwgMTggPT4gYXJyYXkoMiwxMSksIDIyID0+IGFycmF5KDIsMTEpLCAyNCA9PiBhcnJheSgyLDExKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDEyKSwgMTggPT4gYXJyYXkoMiwxMiksIDIyID0+IGFycmF5KDIsMTIpLCAyNCA9PiBhcnJheSgyLDEyKSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDMpLCAxOCA9PiBhcnJheSgyLDMpLCAyMiA9PiBhcnJheSgyLDMpLCAyNCA9PiBhcnJheSgyLDMpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsNCksIDE4ID0+IGFycmF5KDIsNCksIDIyID0+IGFycmF5KDIsNCksIDI0ID0+IGFycmF5KDIsNCkpLCBhcnJheSggMTQgPT4gYXJyYXkoMiw1KSwgMTggPT4gYXJyYXkoMiw1KSwgMjIgPT4gYXJyYXkoMiw1KSwgMjQgPT4gYXJyYXkoMiw1KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDEpLCAxOCA9PiBhcnJheSgyLDEpLCAyMSA9PiBhcnJheSgyLDEpLCAyMiA9PiBhcnJheSgyLDEpLCAyNCA9PiBhcnJheSgyLDEpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsMiksIDE4ID0+IGFycmF5KDIsMiksIDIyID0+IGFycmF5KDIsMiksIDI0ID0+IGFycmF5KDIsMikpLCBhcnJheSggMyA9PiAyMCwgNCA9PiBhcnJheSgxLDEyKSwgMTggPT4gYXJyYXkoMSwxNyksIDE5ID0+IDE4LCAyMCA9PiAxOSApLCBhcnJheSggMyA9PiA1LCA0ID0+IGFycmF5KDEsMTIpLCA1ID0+IDYsIDYgPT4gYXJyYXkoMSwxMyksIDcgPT4gMywgOCA9PiBhcnJheSgxLDkpLCA5ID0+IDQsIDEwID0+IGFycmF5KDEsMTApLCAxMSA9PiBhcnJheSgxLDExKSwgMTMgPT4gMjMsIDE1ID0+IDcsIDE2ID0+IDgsIDE3ID0+IGFycmF5KDEsMTQpLCAyMyA9PiBhcnJheSgxLDE1KSwgMjQgPT4gYXJyYXkoMSwyMSksIDI1ID0+IDIyICksIGFycmF5KCAxID0+IGFycmF5KDIsNikpLCBhcnJheSggMTQgPT4gYXJyYXkoMiwxMyksIDE4ID0+IGFycmF5KDIsMTMpLCAyMiA9PiBhcnJheSgyLDEzKSwgMjQgPT4gYXJyYXkoMiwxMykpLCBhcnJheSggMTggPT4gYXJyYXkoMSwyNCksIDIyID0+IGFycmF5KDEsMjUpKSwgYXJyYXkoIDE4ID0+IGFycmF5KDIsMTYpLCAyMiA9PiBhcnJheSgyLDE2KSksIGFycmF5KCAyMSA9PiBhcnJheSgxLDI2KSksIGFycmF5KCAxNCA9PiBhcnJheSgyLDE4KSwgMTggPT4gYXJyYXkoMiwxOCksIDIyID0+IGFycmF5KDIsMTgpLCAyNCA9PiBhcnJheSgyLDE4KSksIGFycmF5KCAyMiA9PiBhcnJheSgxLDI4KSwgMjQgPT4gYXJyYXkoMSwyNykpLCBhcnJheSggMjIgPT4gYXJyYXkoMiwyMCksIDI0ID0+IGFycmF5KDIsMjApKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsMTQpLCAxOCA9PiBhcnJheSgyLDE0KSwgMjIgPT4gYXJyYXkoMiwxNCksIDI0ID0+IGFycmF5KDIsMTQpKSwgYXJyYXkoIDMgPT4gMjAsIDQgPT4gYXJyYXkoMSwxMiksIDIwID0+IDI5ICksIGFycmF5KCAzID0+IDUsIDQgPT4gYXJyYXkoMSwxMiksIDUgPT4gNiwgNiA9PiBhcnJheSgxLDEzKSwgNyA9PiAzLCA4ID0+IGFycmF5KDEsOSksIDkgPT4gNCwgMTAgPT4gYXJyYXkoMSwxMCksIDExID0+IGFycmF5KDEsMTEpLCAxMyA9PiAzMCwgMTUgPT4gNywgMTYgPT4gOCwgMTcgPT4gYXJyYXkoMSwxNCksIDIzID0+IGFycmF5KDEsMTUpKSwgYXJyYXkoIDE0ID0+IGFycmF5KDIsMTkpLCAxOCA9PiBhcnJheSgyLDE5KSwgMjIgPT4gYXJyYXkoMiwxOSksIDI0ID0+IGFycmF5KDIsMTkpKSwgYXJyYXkoIDMgPT4gNSwgNCA9PiBhcnJheSgxLDEyKSwgNSA9PiA2LCA2ID0+IGFycmF5KDEsMTMpLCA3ID0+IDMsIDggPT4gYXJyYXkoMSw5KSwgOSA9PiA0LCAxMCA9PiBhcnJheSgxLDEwKSwgMTEgPT4gYXJyYXkoMSwxMSksIDEzID0+IDMxLCAxNSA9PiA3LCAxNiA9PiA4LCAxNyA9PiBhcnJheSgxLDE0KSwgMjMgPT4gYXJyYXkoMSwxNSkpLCBhcnJheSggMTggPT4gYXJyYXkoMiwxNyksIDIyID0+IGFycmF5KDIsMTcpKSwgYXJyYXkoIDE4ID0+IGFycmF5KDIsMTUpLCAyMiA9PiBhcnJheSgyLDE1KSksIGFycmF5KCAyMiA9PiBhcnJheSgyLDIxKSwgMjQgPT4gYXJyYXkoMiwyMSkpLAogICAgKTsKCiAgICBwcml2YXRlICRkZWZhdWx0QWN0aW9ucyA9IGFycmF5KAogICAgICAgIDE2ID0+IGFycmF5KDIsIDYpCiAgICApOwoKICAgIC8qKgogICAgICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgICAgICAgJGlucHV0IEpTT04gc3RyaW5nCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgICAgICAkZmxhZ3MgQml0bWFzayBvZiBwYXJzZS9saW50IG9wdGlvbnMgKHNlZSBjb25zdGFudHMgb2YgdGhpcyBjbGFzcykKICAgICAqIEByZXR1cm4gbnVsbHxQYXJzaW5nRXhjZXB0aW9uIG51bGwgaWYgbm8gZXJyb3IgaXMgZm91bmQsIGEgUGFyc2luZ0V4Y2VwdGlvbiBjb250YWluaW5nIGFsbCBkZXRhaWxzIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbGludCgkaW5wdXQsICRmbGFncyA9IDApCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHRoaXMtPnBhcnNlKCRpbnB1dCwgJGZsYWdzKTsKICAgICAgICB9IGNhdGNoIChQYXJzaW5nRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHJldHVybiAkZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAgJGlucHV0IEpTT04gc3RyaW5nCiAgICAgKiBAcGFyYW0gIGludCAgICAgICAgICAgICAgJGZsYWdzIEJpdG1hc2sgb2YgcGFyc2UvbGludCBvcHRpb25zIChzZWUgY29uc3RhbnRzIG9mIHRoaXMgY2xhc3MpCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKiBAdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlKCRpbnB1dCwgJGZsYWdzID0gMCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmFpbE9uQk9NKCRpbnB1dCk7CgogICAgICAgICR0aGlzLT5mbGFncyA9ICRmbGFnczsKCiAgICAgICAgJHRoaXMtPnN0YWNrID0gYXJyYXkoMCk7CiAgICAgICAgJHRoaXMtPnZzdGFjayA9IGFycmF5KG51bGwpOwogICAgICAgICR0aGlzLT5sc3RhY2sgPSBhcnJheSgpOwoKICAgICAgICAkeXl0ZXh0ID0gJyc7CiAgICAgICAgJHl5bGluZW5vID0gMDsKICAgICAgICAkeXlsZW5nID0gMDsKICAgICAgICAkcmVjb3ZlcmluZyA9IDA7CiAgICAgICAgJFRFUlJPUiA9IDI7CiAgICAgICAgJEVPRiA9IDE7CgogICAgICAgICR0aGlzLT5sZXhlciA9IG5ldyBMZXhlcigpOwogICAgICAgICR0aGlzLT5sZXhlci0+c2V0SW5wdXQoJGlucHV0KTsKCiAgICAgICAgJHl5bG9jID0gJHRoaXMtPmxleGVyLT55eWxsb2M7CiAgICAgICAgJHRoaXMtPmxzdGFja1tdID0gJHl5bG9jOwoKICAgICAgICAkc3ltYm9sID0gbnVsbDsKICAgICAgICAkcHJlRXJyb3JTeW1ib2wgPSBudWxsOwogICAgICAgICRzdGF0ZSA9IG51bGw7CiAgICAgICAgJGFjdGlvbiA9IG51bGw7CiAgICAgICAgJGEgPSBudWxsOwogICAgICAgICRyID0gbnVsbDsKICAgICAgICAkeXl2YWwgPSBuZXcgc3RkQ2xhc3M7CiAgICAgICAgJHAgPSBudWxsOwogICAgICAgICRsZW4gPSBudWxsOwogICAgICAgICRuZXdTdGF0ZSA9IG51bGw7CiAgICAgICAgJGV4cGVjdGVkID0gbnVsbDsKICAgICAgICAkZXJyU3RyID0gbnVsbDsKCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgLy8gcmV0cmlldmUgc3RhdGUgbnVtYmVyIGZyb20gdG9wIG9mIHN0YWNrCiAgICAgICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zdGFja1tcY291bnQoJHRoaXMtPnN0YWNrKS0xXTsKCiAgICAgICAgICAgIC8vIHVzZSBkZWZhdWx0IGFjdGlvbnMgaWYgYXZhaWxhYmxlCiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+ZGVmYXVsdEFjdGlvbnNbJHN0YXRlXSkpIHsKICAgICAgICAgICAgICAgICRhY3Rpb24gPSAkdGhpcy0+ZGVmYXVsdEFjdGlvbnNbJHN0YXRlXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgkc3ltYm9sID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAkc3ltYm9sID0gJHRoaXMtPmxleCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVhZCBhY3Rpb24gZm9yIGN1cnJlbnQgc3RhdGUgYW5kIGZpcnN0IGlucHV0CiAgICAgICAgICAgICAgICAkYWN0aW9uID0gaXNzZXQoJHRoaXMtPnRhYmxlWyRzdGF0ZV1bJHN5bWJvbF0pID8gJHRoaXMtPnRhYmxlWyRzdGF0ZV1bJHN5bWJvbF0gOiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaGFuZGxlIHBhcnNlIGVycm9yCiAgICAgICAgICAgIGlmICghJGFjdGlvbiB8fCAhJGFjdGlvblswXSkgewogICAgICAgICAgICAgICAgaWYgKCEkcmVjb3ZlcmluZykgewogICAgICAgICAgICAgICAgICAgIC8vIFJlcG9ydCBlcnJvcgogICAgICAgICAgICAgICAgICAgICRleHBlY3RlZCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRhYmxlWyRzdGF0ZV0gYXMgJHAgPT4gJGlnbm9yZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnRlcm1pbmFsc19bJHBdKSAmJiAkcCA+IDIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRleHBlY3RlZFtdID0gIiciIC4gJHRoaXMtPnRlcm1pbmFsc19bJHBdIC4gIiciOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKFxpbl9hcnJheSgiJ1NUUklORyciLCAkZXhwZWN0ZWQpICYmIFxpbl9hcnJheShzdWJzdHIoJHRoaXMtPmxleGVyLT5tYXRjaCwgMCwgMSksIGFycmF5KCciJywgIiciKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAiSW52YWxpZCBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIiciID09PSBzdWJzdHIoJHRoaXMtPmxleGVyLT5tYXRjaCwgMCwgMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICIsIGl0IGFwcGVhcnMgeW91IHVzZWQgc2luZ2xlIHF1b3RlcyBpbnN0ZWFkIG9mIGRvdWJsZSBxdW90ZXMiOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgneyIuKz8oXFxcXFteImJmbnJ0L1xcXFx1XSguLi4pPyl9JywgJHRoaXMtPmxleGVyLT5nZXRGdWxsVXBjb21pbmdJbnB1dCgpLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAiLCBpdCBhcHBlYXJzIHlvdSBoYXZlIGFuIHVuZXNjYXBlZCBiYWNrc2xhc2ggYXQ6ICIuJG1hdGNoWzFdOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgneyIoPzpbXiJdK3xcXFxcIikqJH1tJywgJHRoaXMtPmxleGVyLT5nZXRGdWxsVXBjb21pbmdJbnB1dCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gIiwgaXQgYXBwZWFycyB5b3UgZm9yZ290IHRvIHRlcm1pbmF0ZSBhIHN0cmluZywgb3IgYXR0ZW1wdGVkIHRvIHdyaXRlIGEgbXVsdGlsaW5lIHN0cmluZyB3aGljaCBpcyBpbnZhbGlkIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciA9ICdQYXJzZSBlcnJvciBvbiBsaW5lICcgLiAoJHl5bGluZW5vKzEpIC4gIjpcbiI7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAkdGhpcy0+bGV4ZXItPnNob3dQb3NpdGlvbigpIC4gIlxuIjsKICAgICAgICAgICAgICAgICAgICBpZiAoJG1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAkbWVzc2FnZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkZXJyU3RyIC49IChcY291bnQoJGV4cGVjdGVkKSA+IDEpID8gIkV4cGVjdGVkIG9uZSBvZjogIiA6ICJFeHBlY3RlZDogIjsKICAgICAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSBpbXBsb2RlKCcsICcsICRleHBlY3RlZCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoJywnID09PSBzdWJzdHIodHJpbSgkdGhpcy0+bGV4ZXItPmdldFBhc3RJbnB1dCgpKSwgLTEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gIiAtIEl0IGFwcGVhcnMgeW91IGhhdmUgYW4gZXh0cmEgdHJhaWxpbmcgY29tbWEiOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlRXJyb3IoJGVyclN0ciwgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0JyA9PiAkdGhpcy0+bGV4ZXItPm1hdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAndG9rZW4nID0+ICFlbXB0eSgkdGhpcy0+dGVybWluYWxzX1skc3ltYm9sXSkgPyAkdGhpcy0+dGVybWluYWxzX1skc3ltYm9sXSA6ICRzeW1ib2wsCiAgICAgICAgICAgICAgICAgICAgICAgICdsaW5lJyA9PiAkdGhpcy0+bGV4ZXItPnl5bGluZW5vLAogICAgICAgICAgICAgICAgICAgICAgICAnbG9jJyA9PiAkeXlsb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICdleHBlY3RlZCcgPT4gJGV4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGp1c3QgcmVjb3ZlcmVkIGZyb20gYW5vdGhlciBlcnJvcgogICAgICAgICAgICAgICAgaWYgKCRyZWNvdmVyaW5nID09IDMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHN5bWJvbCA9PSAkRU9GKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCRlcnJTdHIgPzogJ1BhcnNpbmcgaGFsdGVkLicpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gZGlzY2FyZCBjdXJyZW50IGxvb2thaGVhZCBhbmQgZ3JhYiBhbm90aGVyCiAgICAgICAgICAgICAgICAgICAgJHl5bGVuZyA9ICR0aGlzLT5sZXhlci0+eXlsZW5nOwogICAgICAgICAgICAgICAgICAgICR5eXRleHQgPSAkdGhpcy0+bGV4ZXItPnl5dGV4dDsKICAgICAgICAgICAgICAgICAgICAkeXlsaW5lbm8gPSAkdGhpcy0+bGV4ZXItPnl5bGluZW5vOwogICAgICAgICAgICAgICAgICAgICR5eWxvYyA9ICR0aGlzLT5sZXhlci0+eXlsbG9jOwogICAgICAgICAgICAgICAgICAgICRzeW1ib2wgPSAkdGhpcy0+bGV4KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gdHJ5IHRvIHJlY292ZXIgZnJvbSBlcnJvcgogICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgZXJyb3IgcmVjb3ZlcnkgcnVsZSBpbiB0aGlzIHN0YXRlCiAgICAgICAgICAgICAgICAgICAgaWYgKFxhcnJheV9rZXlfZXhpc3RzKCRURVJST1IsICR0aGlzLT50YWJsZVskc3RhdGVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdGF0ZSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCRlcnJTdHIgPzogJ1BhcnNpbmcgaGFsdGVkLicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cG9wU3RhY2soMSk7CiAgICAgICAgICAgICAgICAgICAgJHN0YXRlID0gJHRoaXMtPnN0YWNrW1xjb3VudCgkdGhpcy0+c3RhY2spLTFdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRwcmVFcnJvclN5bWJvbCA9ICRzeW1ib2w7IC8vIHNhdmUgdGhlIGxvb2thaGVhZCB0b2tlbgogICAgICAgICAgICAgICAgJHN5bWJvbCA9ICRURVJST1I7ICAgICAgICAgLy8gaW5zZXJ0IGdlbmVyaWMgZXJyb3Igc3ltYm9sIGFzIG5ldyBsb29rYWhlYWQKICAgICAgICAgICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zdGFja1tcY291bnQoJHRoaXMtPnN0YWNrKS0xXTsKICAgICAgICAgICAgICAgICRhY3Rpb24gPSBpc3NldCgkdGhpcy0+dGFibGVbJHN0YXRlXVskVEVSUk9SXSkgPyAkdGhpcy0+dGFibGVbJHN0YXRlXVskVEVSUk9SXSA6IGZhbHNlOwogICAgICAgICAgICAgICAgJHJlY292ZXJpbmcgPSAzOyAvLyBhbGxvdyAzIHJlYWwgc3ltYm9scyB0byBiZSBzaGlmdGVkIGJlZm9yZSByZXBvcnRpbmcgYSBuZXcgZXJyb3IKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gdGhpcyBzaG91bGRuJ3QgaGFwcGVuLCB1bmxlc3MgcmVzb2x2ZSBkZWZhdWx0cyBhcmUgb2ZmCiAgICAgICAgICAgIGlmIChcaXNfYXJyYXkoJGFjdGlvblswXSkgJiYgXGNvdW50KCRhY3Rpb24pID4gMSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oJ1BhcnNlIEVycm9yOiBtdWx0aXBsZSBhY3Rpb25zIHBvc3NpYmxlIGF0IHN0YXRlOiAnIC4gJHN0YXRlIC4gJywgdG9rZW46ICcgLiAkc3ltYm9sKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICgkYWN0aW9uWzBdKSB7CiAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIHNoaWZ0CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnN0YWNrW10gPSAkc3ltYm9sOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT52c3RhY2tbXSA9ICR0aGlzLT5sZXhlci0+eXl0ZXh0OwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5sc3RhY2tbXSA9ICR0aGlzLT5sZXhlci0+eXlsbG9jOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFja1tdID0gJGFjdGlvblsxXTsgLy8gcHVzaCBzdGF0ZQogICAgICAgICAgICAgICAgICAgICRzeW1ib2wgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlmICghJHByZUVycm9yU3ltYm9sKSB7IC8vIG5vcm1hbCBleGVjdXRpb24vbm8gZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgJHl5bGVuZyA9ICR0aGlzLT5sZXhlci0+eXlsZW5nOwogICAgICAgICAgICAgICAgICAgICAgICAkeXl0ZXh0ID0gJHRoaXMtPmxleGVyLT55eXRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICR5eWxpbmVubyA9ICR0aGlzLT5sZXhlci0+eXlsaW5lbm87CiAgICAgICAgICAgICAgICAgICAgICAgICR5eWxvYyA9ICR0aGlzLT5sZXhlci0+eXlsbG9jOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHJlY292ZXJpbmcgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcmVjb3ZlcmluZy0tOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gZXJyb3IganVzdCBvY2N1cnJlZCwgcmVzdW1lIG9sZCBsb29rYWhlYWQgZi8gYmVmb3JlIGVycm9yCiAgICAgICAgICAgICAgICAgICAgICAgICRzeW1ib2wgPSAkcHJlRXJyb3JTeW1ib2w7CiAgICAgICAgICAgICAgICAgICAgICAgICRwcmVFcnJvclN5bWJvbCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gcmVkdWNlCiAgICAgICAgICAgICAgICAgICAgJGxlbiA9ICR0aGlzLT5wcm9kdWN0aW9uc19bJGFjdGlvblsxXV1bMV07CgogICAgICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gc2VtYW50aWMgYWN0aW9uCiAgICAgICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9ICR0aGlzLT52c3RhY2tbXGNvdW50KCR0aGlzLT52c3RhY2spIC0gJGxlbl07IC8vIGRlZmF1bHQgdG8gJCQgPSAkMQogICAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgbG9jYXRpb24sIHVzZXMgZmlyc3QgdG9rZW4gZm9yIGZpcnN0cywgbGFzdCBmb3IgbGFzdHMKICAgICAgICAgICAgICAgICAgICAkeXl2YWwtPnN0b3JlID0gYXJyYXkoIC8vIF8kID0gc3RvcmUKICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpcnN0X2xpbmUnID0+ICR0aGlzLT5sc3RhY2tbXGNvdW50KCR0aGlzLT5sc3RhY2spIC0gKCRsZW4gPzogMSldWydmaXJzdF9saW5lJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICdsYXN0X2xpbmUnID0+ICR0aGlzLT5sc3RhY2tbXGNvdW50KCR0aGlzLT5sc3RhY2spIC0gMV1bJ2xhc3RfbGluZSddLAogICAgICAgICAgICAgICAgICAgICAgICAnZmlyc3RfY29sdW1uJyA9PiAkdGhpcy0+bHN0YWNrW1xjb3VudCgkdGhpcy0+bHN0YWNrKSAtICgkbGVuID86IDEpXVsnZmlyc3RfY29sdW1uJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICdsYXN0X2NvbHVtbicgPT4gJHRoaXMtPmxzdGFja1tcY291bnQoJHRoaXMtPmxzdGFjaykgLSAxXVsnbGFzdF9jb2x1bW4nXSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRyID0gJHRoaXMtPnBlcmZvcm1BY3Rpb24oJHl5dmFsLCAkeXl0ZXh0LCAkeXlsZW5nLCAkeXlsaW5lbm8sICRhY3Rpb25bMV0sICR0aGlzLT52c3RhY2spOwoKICAgICAgICAgICAgICAgICAgICBpZiAoISRyIGluc3RhbmNlb2YgVW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkcjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgkbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5wb3BTdGFjaygkbGVuKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFja1tdID0gJHRoaXMtPnByb2R1Y3Rpb25zX1skYWN0aW9uWzFdXVswXTsgICAgLy8gcHVzaCBub250ZXJtaW5hbCAocmVkdWNlKQogICAgICAgICAgICAgICAgICAgICR0aGlzLT52c3RhY2tbXSA9ICR5eXZhbC0+dG9rZW47CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmxzdGFja1tdID0gJHl5dmFsLT5zdG9yZTsKICAgICAgICAgICAgICAgICAgICAkbmV3U3RhdGUgPSAkdGhpcy0+dGFibGVbJHRoaXMtPnN0YWNrW1xjb3VudCgkdGhpcy0+c3RhY2spLTJdXVskdGhpcy0+c3RhY2tbXGNvdW50KCR0aGlzLT5zdGFjayktMV1dOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zdGFja1tdID0gJG5ld1N0YXRlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgMzogLy8gYWNjZXB0CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUVycm9yKCRzdHIsICRoYXNoKQogICAgewogICAgICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCRzdHIsICRoYXNoKTsKICAgIH0KCiAgICAvLyAkJCA9ICR0b2tlbnMgLy8gbmVlZHMgdG8gYmUgcGFzc2VkIGJ5IHJlZj8KICAgIC8vICQgPSAkdG9rZW4KICAgIC8vIF8kIHJlbW92ZWQsIHVzZWxlc3M/CiAgICBwcml2YXRlIGZ1bmN0aW9uIHBlcmZvcm1BY3Rpb24oc3RkQ2xhc3MgJHl5dmFsLCAkeXl0ZXh0LCAkeXlsZW5nLCAkeXlsaW5lbm8sICR5eXN0YXRlLCAmJHRva2VucykKICAgIHsKICAgICAgICAvLyAkMCA9ICRsZW4KICAgICAgICAkbGVuID0gXGNvdW50KCR0b2tlbnMpIC0gMTsKICAgICAgICBzd2l0Y2ggKCR5eXN0YXRlKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAkeXl0ZXh0ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCd7KD86XFxcXFsiYmZucnQvXFxcXF18XFxcXHVbYS1mQS1GMC05XXs0fSl9JywgYXJyYXkoJHRoaXMsICdzdHJpbmdJbnRlcnBvbGF0aW9uJyksICR5eXRleHQpOwogICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gJHl5dGV4dDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICBpZiAoc3RycG9zKCR5eXRleHQsICdlJykgIT09IGZhbHNlIHx8IHN0cnBvcygkeXl0ZXh0LCAnRScpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IFxmbG9hdHZhbCgkeXl0ZXh0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBzdHJwb3MoJHl5dGV4dCwgJy4nKSA9PT0gZmFsc2UgPyBcaW50dmFsKCR5eXRleHQpIDogXGZsb2F0dmFsKCR5eXRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IG51bGw7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IHRydWU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNToKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IGZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiAkeXl2YWwtPnRva2VuID0gJHRva2Vuc1skbGVuLTFdOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmxhZ3MgJiBzZWxmOjpQQVJTRV9UT19BU1NPQykgewogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IGFycmF5KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gbmV3IHN0ZENsYXNzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSAkdG9rZW5zWyRsZW4tMV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBhcnJheSgkdG9rZW5zWyRsZW4tMl0sICR0b2tlbnNbJGxlbl0pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA3MDEwMCkgewogICAgICAgICAgICAgICAgJHByb3BlcnR5ID0gJHRva2Vuc1skbGVuXVswXSA9PT0gJycgPyAnX2VtcHR5XycgOiAkdG9rZW5zWyRsZW5dWzBdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHByb3BlcnR5ID0gJHRva2Vuc1skbGVuXVswXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHRoaXMtPmZsYWdzICYgc2VsZjo6UEFSU0VfVE9fQVNTT0MpIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBhcnJheSgpOwogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlblskcHJvcGVydHldID0gJHRva2Vuc1skbGVuXVsxXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSBuZXcgc3RkQ2xhc3M7CiAgICAgICAgICAgICAgICAkeXl2YWwtPnRva2VuLT4kcHJvcGVydHkgPSAkdG9rZW5zWyRsZW5dWzFdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmxhZ3MgJiBzZWxmOjpQQVJTRV9UT19BU1NPQykgewogICAgICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9JiAkdG9rZW5zWyRsZW4tMl07CiAgICAgICAgICAgICAgICAka2V5ID0gJHRva2Vuc1skbGVuXVswXTsKICAgICAgICAgICAgICAgIGlmICgoJHRoaXMtPmZsYWdzICYgc2VsZjo6REVURUNUX0tFWV9DT05GTElDVFMpICYmIGlzc2V0KCR0b2tlbnNbJGxlbi0yXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICAgICAkZXJyU3RyID0gJ1BhcnNlIGVycm9yIG9uIGxpbmUgJyAuICgkeXlsaW5lbm8rMSkgLiAiOlxuIjsKICAgICAgICAgICAgICAgICAgICAkZXJyU3RyIC49ICR0aGlzLT5sZXhlci0+c2hvd1Bvc2l0aW9uKCkgLiAiXG4iOwogICAgICAgICAgICAgICAgICAgICRlcnJTdHIgLj0gIkR1cGxpY2F0ZSBrZXk6ICIuJHRva2Vuc1skbGVuXVswXTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRHVwbGljYXRlS2V5RXhjZXB0aW9uKCRlcnJTdHIsICR0b2tlbnNbJGxlbl1bMF0sIGFycmF5KCdsaW5lJyA9PiAkeXlsaW5lbm8rMSkpOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCgkdGhpcy0+ZmxhZ3MgJiBzZWxmOjpBTExPV19EVVBMSUNBVEVfS0VZUykgJiYgaXNzZXQoJHRva2Vuc1skbGVuLTJdWyRrZXldKSkgewogICAgICAgICAgICAgICAgICAgICRkdXBsaWNhdGVDb3VudCA9IDE7CiAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAkZHVwbGljYXRlS2V5ID0gJGtleSAuICcuJyAuICRkdXBsaWNhdGVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGlzc2V0KCR0b2tlbnNbJGxlbi0yXVskZHVwbGljYXRlS2V5XSkpOwogICAgICAgICAgICAgICAgICAgICRrZXkgPSAkZHVwbGljYXRlS2V5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRva2Vuc1skbGVuLTJdWyRrZXldID0gJHRva2Vuc1skbGVuXVsxXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSAkdG9rZW5zWyRsZW4tMl07CiAgICAgICAgICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPCA3MDEwMCkgewogICAgICAgICAgICAgICAgICAgICRrZXkgPSAkdG9rZW5zWyRsZW5dWzBdID09PSAnJyA/ICdfZW1wdHlfJyA6ICR0b2tlbnNbJGxlbl1bMF07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRrZXkgPSAkdG9rZW5zWyRsZW5dWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCgkdGhpcy0+ZmxhZ3MgJiBzZWxmOjpERVRFQ1RfS0VZX0NPTkZMSUNUUykgJiYgaXNzZXQoJHRva2Vuc1skbGVuLTJdLT57JGtleX0pKSB7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciA9ICdQYXJzZSBlcnJvciBvbiBsaW5lICcgLiAoJHl5bGluZW5vKzEpIC4gIjpcbiI7CiAgICAgICAgICAgICAgICAgICAgJGVyclN0ciAuPSAkdGhpcy0+bGV4ZXItPnNob3dQb3NpdGlvbigpIC4gIlxuIjsKICAgICAgICAgICAgICAgICAgICAkZXJyU3RyIC49ICJEdXBsaWNhdGUga2V5OiAiLiR0b2tlbnNbJGxlbl1bMF07CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IER1cGxpY2F0ZUtleUV4Y2VwdGlvbigkZXJyU3RyLCAkdG9rZW5zWyRsZW5dWzBdLCBhcnJheSgnbGluZScgPT4gJHl5bGluZW5vKzEpKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoJHRoaXMtPmZsYWdzICYgc2VsZjo6QUxMT1dfRFVQTElDQVRFX0tFWVMpICYmIGlzc2V0KCR0b2tlbnNbJGxlbi0yXS0+eyRrZXl9KSkgewogICAgICAgICAgICAgICAgICAgICRkdXBsaWNhdGVDb3VudCA9IDE7CiAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAkZHVwbGljYXRlS2V5ID0gJGtleSAuICcuJyAuICRkdXBsaWNhdGVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGlzc2V0KCR0b2tlbnNbJGxlbi0yXS0+JGR1cGxpY2F0ZUtleSkpOwogICAgICAgICAgICAgICAgICAgICRrZXkgPSAkZHVwbGljYXRlS2V5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRva2Vuc1skbGVuLTJdLT4ka2V5ID0gJHRva2Vuc1skbGVuXVsxXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE4OgogICAgICAgICAgICAkeXl2YWwtPnRva2VuID0gYXJyYXkoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxOToKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9ICR0b2tlbnNbJGxlbi0xXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyMDoKICAgICAgICAgICAgJHl5dmFsLT50b2tlbiA9IGFycmF5KCR0b2tlbnNbJGxlbl0pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDIxOgogICAgICAgICAgICAkdG9rZW5zWyRsZW4tMl1bXSA9ICR0b2tlbnNbJGxlbl07CiAgICAgICAgICAgICR5eXZhbC0+dG9rZW4gPSAkdG9rZW5zWyRsZW4tMl07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBVbmRlZmluZWQoKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0cmluZ0ludGVycG9sYXRpb24oJG1hdGNoKQogICAgewogICAgICAgIHN3aXRjaCAoJG1hdGNoWzBdKSB7CiAgICAgICAgY2FzZSAnXFxcXCc6CiAgICAgICAgICAgIHJldHVybiAnXFwnOwogICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgcmV0dXJuICciJzsKICAgICAgICBjYXNlICdcYic6CiAgICAgICAgICAgIHJldHVybiBcY2hyKDgpOwogICAgICAgIGNhc2UgJ1xmJzoKICAgICAgICAgICAgcmV0dXJuIFxjaHIoMTIpOwogICAgICAgIGNhc2UgJ1xuJzoKICAgICAgICAgICAgcmV0dXJuICJcbiI7CiAgICAgICAgY2FzZSAnXHInOgogICAgICAgICAgICByZXR1cm4gIlxyIjsKICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgICAgIHJldHVybiAiXHQiOwogICAgICAgIGNhc2UgJ1wvJzoKICAgICAgICAgICAgcmV0dXJuICIvIjsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gaHRtbF9lbnRpdHlfZGVjb2RlKCcmI3gnLmx0cmltKHN1YnN0cigkbWF0Y2hbMF0sIDIpLCAnMCcpLic7JywgRU5UX1FVT1RFUywgJ1VURi04Jyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcG9wU3RhY2soJG4pCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YWNrID0gXGFycmF5X3NsaWNlKCR0aGlzLT5zdGFjaywgMCwgLSAoMiAqICRuKSk7CiAgICAgICAgJHRoaXMtPnZzdGFjayA9IFxhcnJheV9zbGljZSgkdGhpcy0+dnN0YWNrLCAwLCAtICRuKTsKICAgICAgICAkdGhpcy0+bHN0YWNrID0gXGFycmF5X3NsaWNlKCR0aGlzLT5sc3RhY2ssIDAsIC0gJG4pOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gbGV4KCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+bGV4ZXItPmxleCgpID86IDE7IC8vICRlbmQgPSAxCiAgICAgICAgLy8gaWYgdG9rZW4gaXNuJ3QgaXRzIG51bWVyaWMgdmFsdWUsIGNvbnZlcnQKICAgICAgICBpZiAoIWlzX251bWVyaWMoJHRva2VuKSkgewogICAgICAgICAgICAkdG9rZW4gPSBpc3NldCgkdGhpcy0+c3ltYm9sc1skdG9rZW5dKSA/ICR0aGlzLT5zeW1ib2xzWyR0b2tlbl0gOiAkdG9rZW47CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRva2VuOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZmFpbE9uQk9NKCRpbnB1dCkKICAgIHsKICAgICAgICAvLyBVVEYtOCBCeXRlT3JkZXJNYXJrIHNlcXVlbmNlCiAgICAgICAgJGJvbSA9ICJceEVGXHhCQlx4QkYiOwoKICAgICAgICBpZiAoc3Vic3RyKCRpbnB1dCwgMCwgMykgPT09ICRib20pIHsKICAgICAgICAgICAgJHRoaXMtPnBhcnNlRXJyb3IoIkJPTSBkZXRlY3RlZCwgbWFrZSBzdXJlIHlvdXIgaW5wdXQgZG9lcyBub3QgaW5jbHVkZSBhIFVuaWNvZGUgQnl0ZS1PcmRlci1NYXJrIiwgYXJyYXkoKSk7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSlNPTiBMaW50IHBhY2thZ2UuCiAqCiAqIChjKSBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU2VsZFxKc29uTGludDsKCmNsYXNzIFVuZGVmaW5lZAp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKU09OIExpbnQgcGFja2FnZS4KICoKICogKGMpIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTZWxkXEpzb25MaW50OwoKLyoqCiAqIExleGVyIGNsYXNzCiAqCiAqIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS96YWFjaC9qc29ubGludAogKi8KY2xhc3MgTGV4ZXIKewogICAgcHJpdmF0ZSAkRU9GID0gMTsKICAgIC8qKgogICAgICogQHBocHN0YW4tdmFyIGFycmF5PGludCwgc3RyaW5nPgogICAgICovCiAgICBwcml2YXRlICRydWxlcyA9IGFycmF5KAogICAgICAgIDAgPT4gJy9cR1xzKy8nLAogICAgICAgIDEgPT4gJy9cRy0/KFswLTldfFsxLTldWzAtOV0rKShcLlswLTldKyk/KFtlRV1bKy1dP1swLTldKyk/XGIvJywKICAgICAgICAyID0+ICd7XEciKD8+XFxcXFsiYmZucnQvXFxcXF18XFxcXHVbYS1mQS1GMC05XXs0fXxbXlwwLVx4MWZcXFxcIl0rKykqKyJ9JywKICAgICAgICAzID0+ICcvXEdcey8nLAogICAgICAgIDQgPT4gJy9cR1x9LycsCiAgICAgICAgNSA9PiAnL1xHXFsvJywKICAgICAgICA2ID0+ICcvXEdcXS8nLAogICAgICAgIDcgPT4gJy9cRywvJywKICAgICAgICA4ID0+ICcvXEc6LycsCiAgICAgICAgOSA9PiAnL1xHdHJ1ZVxiLycsCiAgICAgICAgMTAgPT4gJy9cR2ZhbHNlXGIvJywKICAgICAgICAxMSA9PiAnL1xHbnVsbFxiLycsCiAgICAgICAgMTIgPT4gJy9cRyQvJywKICAgICAgICAxMyA9PiAnL1xHLi8nLAogICAgKTsKCiAgICBwcml2YXRlICRjb25kaXRpb25zID0gYXJyYXkoCiAgICAgICAgIklOSVRJQUwiID0+IGFycmF5KAogICAgICAgICAgICAicnVsZXMiID0+IGFycmF5KDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMpLAogICAgICAgICAgICAiaW5jbHVzaXZlIiA9PiB0cnVlLAogICAgICAgICksCiAgICApOwoKICAgIHByaXZhdGUgJGNvbmRpdGlvblN0YWNrOwogICAgcHJpdmF0ZSAkaW5wdXQ7CiAgICBwcml2YXRlICRtb3JlOwogICAgcHJpdmF0ZSAkZG9uZTsKICAgIHByaXZhdGUgJG9mZnNldDsKCiAgICBwdWJsaWMgJG1hdGNoOwogICAgcHVibGljICR5eWxpbmVubzsKICAgIHB1YmxpYyAkeXlsZW5nOwogICAgcHVibGljICR5eXRleHQ7CiAgICBwdWJsaWMgJHl5bGxvYzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gbGV4KCkKICAgIHsKICAgICAgICAkciA9ICR0aGlzLT5uZXh0KCk7CiAgICAgICAgaWYgKCEkciBpbnN0YW5jZW9mIFVuZGVmaW5lZCkgewogICAgICAgICAgICByZXR1cm4gJHI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPmxleCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbnB1dCgkaW5wdXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlucHV0ID0gJGlucHV0OwogICAgICAgICR0aGlzLT5tb3JlID0gZmFsc2U7CiAgICAgICAgJHRoaXMtPmRvbmUgPSBmYWxzZTsKICAgICAgICAkdGhpcy0+b2Zmc2V0ID0gMDsKICAgICAgICAkdGhpcy0+eXlsaW5lbm8gPSAkdGhpcy0+eXlsZW5nID0gMDsKICAgICAgICAkdGhpcy0+eXl0ZXh0ID0gJHRoaXMtPm1hdGNoID0gJyc7CiAgICAgICAgJHRoaXMtPmNvbmRpdGlvblN0YWNrID0gYXJyYXkoJ0lOSVRJQUwnKTsKICAgICAgICAkdGhpcy0+eXlsbG9jID0gYXJyYXkoJ2ZpcnN0X2xpbmUnID0+IDEsICdmaXJzdF9jb2x1bW4nID0+IDAsICdsYXN0X2xpbmUnID0+IDEsICdsYXN0X2NvbHVtbicgPT4gMCk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2hvd1Bvc2l0aW9uKCkKICAgIHsKICAgICAgICAkcHJlID0gc3RyX3JlcGxhY2UoIlxuIiwgJycsICR0aGlzLT5nZXRQYXN0SW5wdXQoKSk7CiAgICAgICAgJGMgPSBzdHJfcmVwZWF0KCctJywgbWF4KDAsIFxzdHJsZW4oJHByZSkgLSAxKSk7IC8vIG5ldyBBcnJheShwcmUubGVuZ3RoICsgMSkuam9pbigiLSIpOwoKICAgICAgICByZXR1cm4gJHByZSAuIHN0cl9yZXBsYWNlKCJcbiIsICcnLCAkdGhpcy0+Z2V0VXBjb21pbmdJbnB1dCgpKSAuICJcbiIgLiAkYyAuICJeIjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFzdElucHV0KCkKICAgIHsKICAgICAgICAkcGFzdExlbmd0aCA9ICR0aGlzLT5vZmZzZXQgLSBcc3RybGVuKCR0aGlzLT5tYXRjaCk7CgogICAgICAgIHJldHVybiAoJHBhc3RMZW5ndGggPiAyMCA/ICcuLi4nIDogJycpIC4gc3Vic3RyKCR0aGlzLT5pbnB1dCwgbWF4KDAsICRwYXN0TGVuZ3RoIC0gMjApLCBtaW4oMjAsICRwYXN0TGVuZ3RoKSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFVwY29taW5nSW5wdXQoKQogICAgewogICAgICAgICRuZXh0ID0gJHRoaXMtPm1hdGNoOwogICAgICAgIGlmIChcc3RybGVuKCRuZXh0KSA8IDIwKSB7CiAgICAgICAgICAgICRuZXh0IC49IHN1YnN0cigkdGhpcy0+aW5wdXQsICR0aGlzLT5vZmZzZXQsIDIwIC0gXHN0cmxlbigkbmV4dCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN1YnN0cigkbmV4dCwgMCwgMjApIC4gKFxzdHJsZW4oJG5leHQpID4gMjAgPyAnLi4uJyA6ICcnKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVsbFVwY29taW5nSW5wdXQoKQogICAgewogICAgICAgICRuZXh0ID0gJHRoaXMtPm1hdGNoOwogICAgICAgIGlmIChzdWJzdHIoJG5leHQsIDAsIDEpID09PSAnIicgJiYgc3Vic3RyX2NvdW50KCRuZXh0LCAnIicpID09PSAxKSB7CiAgICAgICAgICAgICRsZW4gPSBcc3RybGVuKCR0aGlzLT5pbnB1dCk7CiAgICAgICAgICAgICRzdHJFbmQgPSBtaW4oc3RycG9zKCR0aGlzLT5pbnB1dCwgJyInLCAkdGhpcy0+b2Zmc2V0ICsgMSkgPzogJGxlbiwgc3RycG9zKCR0aGlzLT5pbnB1dCwgIlxuIiwgJHRoaXMtPm9mZnNldCArIDEpID86ICRsZW4pOwogICAgICAgICAgICAkbmV4dCAuPSBzdWJzdHIoJHRoaXMtPmlucHV0LCAkdGhpcy0+b2Zmc2V0LCAkc3RyRW5kIC0gJHRoaXMtPm9mZnNldCk7CiAgICAgICAgfSBlbHNlaWYgKFxzdHJsZW4oJG5leHQpIDwgMjApIHsKICAgICAgICAgICAgJG5leHQgLj0gc3Vic3RyKCR0aGlzLT5pbnB1dCwgJHRoaXMtPm9mZnNldCwgMjAgLSBcc3RybGVuKCRuZXh0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5leHQ7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRXJyb3IoJHN0ciwgJGhhc2gpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oJHN0cik7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBuZXh0KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmRvbmUpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5FT0Y7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+b2Zmc2V0ID09PSBcc3RybGVuKCR0aGlzLT5pbnB1dCkpIHsKICAgICAgICAgICAgJHRoaXMtPmRvbmUgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRva2VuID0gbnVsbDsKICAgICAgICAkbWF0Y2ggPSBudWxsOwogICAgICAgICRjb2wgPSBudWxsOwogICAgICAgICRsaW5lcyA9IG51bGw7CgogICAgICAgIGlmICghJHRoaXMtPm1vcmUpIHsKICAgICAgICAgICAgJHRoaXMtPnl5dGV4dCA9ICcnOwogICAgICAgICAgICAkdGhpcy0+bWF0Y2ggPSAnJzsKICAgICAgICB9CgogICAgICAgICRydWxlcyA9ICR0aGlzLT5nZXRDdXJyZW50UnVsZXMoKTsKICAgICAgICAkcnVsZXNMZW4gPSBcY291bnQoJHJ1bGVzKTsKCiAgICAgICAgZm9yICgkaT0wOyAkaSA8ICRydWxlc0xlbjsgJGkrKykgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkdGhpcy0+cnVsZXNbJHJ1bGVzWyRpXV0sICR0aGlzLT5pbnB1dCwgJG1hdGNoLCAwLCAkdGhpcy0+b2Zmc2V0KSkgewogICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJy9cbi4qLycsICRtYXRjaFswXSwgJGxpbmVzKTsKICAgICAgICAgICAgICAgICRsaW5lcyA9ICRsaW5lc1swXTsKICAgICAgICAgICAgICAgIGlmICgkbGluZXMpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+eXlsaW5lbm8gKz0gXGNvdW50KCRsaW5lcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRoaXMtPnl5bGxvYyA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICdmaXJzdF9saW5lJyA9PiAkdGhpcy0+eXlsbG9jWydsYXN0X2xpbmUnXSwKICAgICAgICAgICAgICAgICAgICAnbGFzdF9saW5lJyA9PiAkdGhpcy0+eXlsaW5lbm8rMSwKICAgICAgICAgICAgICAgICAgICAnZmlyc3RfY29sdW1uJyA9PiAkdGhpcy0+eXlsbG9jWydsYXN0X2NvbHVtbiddLAogICAgICAgICAgICAgICAgICAgICdsYXN0X2NvbHVtbicgPT4gJGxpbmVzID8gXHN0cmxlbigkbGluZXNbXGNvdW50KCRsaW5lcykgLSAxXSkgLSAxIDogJHRoaXMtPnl5bGxvY1snbGFzdF9jb2x1bW4nXSArIFxzdHJsZW4oJG1hdGNoWzBdKSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkdGhpcy0+eXl0ZXh0IC49ICRtYXRjaFswXTsKICAgICAgICAgICAgICAgICR0aGlzLT5tYXRjaCAuPSAkbWF0Y2hbMF07CiAgICAgICAgICAgICAgICAkdGhpcy0+eXlsZW5nID0gXHN0cmxlbigkdGhpcy0+eXl0ZXh0KTsKICAgICAgICAgICAgICAgICR0aGlzLT5tb3JlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAkdGhpcy0+b2Zmc2V0ICs9IFxzdHJsZW4oJG1hdGNoWzBdKTsKICAgICAgICAgICAgICAgICR0b2tlbiA9ICR0aGlzLT5wZXJmb3JtQWN0aW9uKCRydWxlc1skaV0sICR0aGlzLT5jb25kaXRpb25TdGFja1tcY291bnQoJHRoaXMtPmNvbmRpdGlvblN0YWNrKS0xXSk7CiAgICAgICAgICAgICAgICBpZiAoJHRva2VuKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0b2tlbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVuZGVmaW5lZCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPm9mZnNldCA9PT0gXHN0cmxlbigkdGhpcy0+aW5wdXQpKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+RU9GOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnBhcnNlRXJyb3IoCiAgICAgICAgICAgICdMZXhpY2FsIGVycm9yIG9uIGxpbmUgJyAuICgkdGhpcy0+eXlsaW5lbm8rMSkgLiAiLiBVbnJlY29nbml6ZWQgdGV4dC5cbiIgLiAkdGhpcy0+c2hvd1Bvc2l0aW9uKCksCiAgICAgICAgICAgIGFycmF5KAogICAgICAgICAgICAgICAgJ3RleHQnID0+ICIiLAogICAgICAgICAgICAgICAgJ3Rva2VuJyA9PiBudWxsLAogICAgICAgICAgICAgICAgJ2xpbmUnID0+ICR0aGlzLT55eWxpbmVubywKICAgICAgICAgICAgKQogICAgICAgICk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRDdXJyZW50UnVsZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uZGl0aW9uc1skdGhpcy0+Y29uZGl0aW9uU3RhY2tbXGNvdW50KCR0aGlzLT5jb25kaXRpb25TdGFjayktMV1dWydydWxlcyddOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcGVyZm9ybUFjdGlvbigkYXZvaWRpbmdfbmFtZV9jb2xsaXNpb25zLCAkWVlfU1RBUlQpCiAgICB7CiAgICAgICAgc3dpdGNoICgkYXZvaWRpbmdfbmFtZV9jb2xsaXNpb25zKSB7CiAgICAgICAgY2FzZSAwOi8qIHNraXAgd2hpdGVzcGFjZSAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiA2OwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgJHRoaXMtPnl5dGV4dCA9IHN1YnN0cigkdGhpcy0+eXl0ZXh0LCAxLCAkdGhpcy0+eXlsZW5nLTIpOwoKICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gMTc7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gMTg7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gMjM7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gMjQ7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gMjI7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gMjE7CiAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gMTA7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIDExOwogICAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgIHJldHVybiA4OwogICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiAxNDsKICAgICAgICBjYXNlIDEzOgogICAgICAgICAgICByZXR1cm4gJ0lOVkFMSUQnOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUEhBUiBVdGlscy4KICoKICogKGMpIEpvcmRpIEJvZ2dpYW5vIDxqLmJvZ2dpYW5vQHNlbGQuYmU+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBTZWxkXFBoYXJVdGlsczsKCmNsYXNzIFRpbWVzdGFtcHMKewogICAgcHJpdmF0ZSAkY29udGVudHM7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlIHBhdGggdG8gdGhlIHBoYXIgZmlsZSB0byB1c2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRmaWxlKQogICAgewogICAgICAgICR0aGlzLT5jb250ZW50cyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCRmaWxlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZXMgZWFjaCBmaWxlJ3MgdW5peCB0aW1lc3RhbXBzIGluIHRoZSBQSEFSCiAgICAgKgogICAgICogVGhlIFBIQVIgc2lnbmF0dXJlIGNhbiB0aGVuIGJlIHByb2R1Y2VkIGluIGEgcmVwcm9kdWNpYmxlIG1hbm5lci4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50fERhdGVUaW1lfHN0cmluZyAkdGltZXN0YW1wIERhdGUgc3RyaW5nIG9yIERhdGVUaW1lIG9yIHVuaXggdGltZXN0YW1wIHRvIHVzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBkYXRlVGltZXN0YW1wcygkdGltZXN0YW1wID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHRpbWVzdGFtcCBpbnN0YW5jZW9mIFxEYXRlVGltZSkgewogICAgICAgICAgICAkdGltZXN0YW1wID0gJHRpbWVzdGFtcC0+Z2V0VGltZXN0YW1wKCk7CiAgICAgICAgfSBlbHNlaWYgKGlzX3N0cmluZygkdGltZXN0YW1wKSkgewogICAgICAgICAgICAkdGltZXN0YW1wID0gc3RydG90aW1lKCR0aW1lc3RhbXApOwogICAgICAgIH0gZWxzZWlmICghaXNfaW50KCR0aW1lc3RhbXApKSB7CiAgICAgICAgICAgICR0aW1lc3RhbXAgPSBzdHJ0b3RpbWUoJzE5ODQtMTItMjRUMDA6MDA6MDBaJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBkZXRlY3QgbWFuaWZlc3Qgb2Zmc2V0IC8gZW5kIG9mIHN0dWIKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJ3tfX0hBTFRfQ09NUElMRVJcKFwpOyg/OiArXD8+KT9ccj9cbn0nLCAkdGhpcy0+Y29udGVudHMsICRtYXRjaCwgUFJFR19PRkZTRVRfQ0FQVFVSRSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3QgZGV0ZWN0IHRoZSBzdHViXCdzIGVuZCBpbiB0aGUgcGhhcicpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2V0IHN0YXJ0aW5nIHBvc2l0aW9uIGFuZCBza2lwIHBhc3QgbWFuaWZlc3QgbGVuZ3RoCiAgICAgICAgJHBvcyA9ICRtYXRjaFswXVsxXSArIHN0cmxlbigkbWF0Y2hbMF1bMF0pOwogICAgICAgICRzdHViRW5kID0gJHBvcyArICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgICRudW1GaWxlcyA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgIC8vIHNraXAgQVBJIHZlcnNpb24gKFlPTE8pCiAgICAgICAgJHBvcyArPSAyOwoKICAgICAgICAvLyBza2lwIFBIQVIgZmxhZ3MKICAgICAgICAkcG9zICs9IDQ7CgogICAgICAgICRhbGlhc0xlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQgKyAkYWxpYXNMZW5ndGg7CgogICAgICAgICRtZXRhZGF0YUxlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAkcG9zICs9IDQgKyAkbWV0YWRhdGFMZW5ndGg7CgogICAgICAgIHdoaWxlICgkcG9zIDwgJHN0dWJFbmQpIHsKICAgICAgICAgICAgJGZpbGVuYW1lTGVuZ3RoID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICAgICAkcG9zICs9IDQgKyAkZmlsZW5hbWVMZW5ndGg7CgogICAgICAgICAgICAvLyBza2lwIGZpbGVzaXplCiAgICAgICAgICAgICRwb3MgKz0gNDsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSB0aW1lc3RhbXAgdG8gYSBmaXhlZCB2YWx1ZQogICAgICAgICAgICAkdGhpcy0+Y29udGVudHMgPSBzdWJzdHJfcmVwbGFjZSgkdGhpcy0+Y29udGVudHMsIHBhY2soJ0wnLCAkdGltZXN0YW1wKSwgJHBvcywgNCk7CgogICAgICAgICAgICAvLyBza2lwIHRpbWVzdGFtcCwgY29tcHJlc3NlZCBmaWxlIHNpemUsIGNyYzMyIGNoZWNrc3VtIGFuZCBmaWxlIGZsYWdzCiAgICAgICAgICAgICRwb3MgKz0gNCo0OwoKICAgICAgICAgICAgJG1ldGFkYXRhTGVuZ3RoID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICAgICAkcG9zICs9IDQgKyAkbWV0YWRhdGFMZW5ndGg7CgogICAgICAgICAgICAkbnVtRmlsZXMtLTsKICAgICAgICB9CgogICAgICAgIGlmICgkbnVtRmlsZXMgIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxMb2dpY0V4Y2VwdGlvbignQWxsIGZpbGVzIHdlcmUgbm90IHByb2Nlc3NlZCwgc29tZXRoaW5nIG11c3QgaGF2ZSBnb25lIHdyb25nJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2F2ZXMgdGhlIHVwZGF0ZWQgcGhhciBmaWxlLCBvcHRpb25hbGx5IHdpdGggYW4gdXBkYXRlZCBzaWduYXR1cmUuCiAgICAgKgogICAgICogQHBhcmFtICBzdHJpbmcgJHBhdGgKICAgICAqIEBwYXJhbSAgaW50ICRzaWduYXR1cmVBbGdvIE9uZSBvZiBQaGFyOjpNRDUsIFBoYXI6OlNIQTEsIFBoYXI6OlNIQTI1NiBvciBQaGFyOjpTSEE1MTIKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2F2ZSgkcGF0aCwgJHNpZ25hdHVyZUFsZ28pCiAgICB7CiAgICAgICAgJHBvcyA9ICR0aGlzLT5kZXRlcm1pbmVTaWduYXR1cmVCZWdpbigpOwoKICAgICAgICAkYWxnb3MgPSBhcnJheSgKICAgICAgICAgICAgXFBoYXI6Ok1ENSA9PiAnbWQ1JywKICAgICAgICAgICAgXFBoYXI6OlNIQTEgPT4gJ3NoYTEnLAogICAgICAgICAgICBcUGhhcjo6U0hBMjU2ID0+ICdzaGEyNTYnLAogICAgICAgICAgICBcUGhhcjo6U0hBNTEyID0+ICdzaGE1MTInLAogICAgICAgICk7CgogICAgICAgIGlmICghaXNzZXQoJGFsZ29zWyRzaWduYXR1cmVBbGdvXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxVbmV4cGVjdGVkVmFsdWVFeGNlcHRpb24oJ0ludmFsaWQgaGFzaCBhbGdvcml0aG0gZ2l2ZW46ICcuJHNpZ25hdHVyZUFsZ28uJyBleHBlY3RlZCBvbmUgb2YgUGhhcjo6TUQ1LCBQaGFyOjpTSEExLCBQaGFyOjpTSEEyNTYgb3IgUGhhcjo6U0hBNTEyJyk7CiAgICAgICAgfQogICAgICAgICRhbGdvID0gJGFsZ29zWyRzaWduYXR1cmVBbGdvXTsKCiAgICAgICAgLy8gcmUtc2lnbiBwaGFyCiAgICAgICAgLy8gICAgICAgICAgIHNpZ25hdHVyZQogICAgICAgICRzaWduYXR1cmUgPSBoYXNoKCRhbGdvLCBzdWJzdHIoJHRoaXMtPmNvbnRlbnRzLCAwLCAkcG9zKSwgdHJ1ZSkKICAgICAgICAgICAgLy8gc2lnIHR5cGUKICAgICAgICAgICAgLiBwYWNrKCdMJywgJHNpZ25hdHVyZUFsZ28pCiAgICAgICAgICAgIC8vIG9oYWkgR3JlZyAmIE1hcmN1cwogICAgICAgICAgICAuICdHQk1CJzsKCiAgICAgICAgJHRoaXMtPmNvbnRlbnRzID0gc3Vic3RyKCR0aGlzLT5jb250ZW50cywgMCwgJHBvcykgLiAkc2lnbmF0dXJlOwoKICAgICAgICByZXR1cm4gZmlsZV9wdXRfY29udGVudHMoJHBhdGgsICR0aGlzLT5jb250ZW50cyk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiByZWFkVWludCgkcG9zLCAkYnl0ZXMpCiAgICB7CiAgICAgICAgJHJlcyA9IHVucGFjaygnVicsIHN1YnN0cigkdGhpcy0+Y29udGVudHMsICRwb3MsICRieXRlcykpOwoKICAgICAgICByZXR1cm4gJHJlc1sxXTsKICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzaWduYXR1cmUuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkZXRlcm1pbmVTaWduYXR1cmVCZWdpbigpCiAgICB7CiAgICAgICAgLy8gZGV0ZWN0IHNpZ25hdHVyZSBwb3NpdGlvbgogICAgICAgIGlmICghcHJlZ19tYXRjaCgne19fSEFMVF9DT01QSUxFUlwoXCk7KD86ICtcPz4pP1xyP1xufScsICR0aGlzLT5jb250ZW50cywgJG1hdGNoLCBQUkVHX09GRlNFVF9DQVBUVVJFKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ0NvdWxkIG5vdCBkZXRlY3QgdGhlIHN0dWJcJ3MgZW5kIGluIHRoZSBwaGFyJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBzZXQgc3RhcnRpbmcgcG9zaXRpb24gYW5kIHNraXAgcGFzdCBtYW5pZmVzdCBsZW5ndGgKICAgICAgICAkcG9zID0gJG1hdGNoWzBdWzFdICsgc3RybGVuKCRtYXRjaFswXVswXSk7CiAgICAgICAgJG1hbmlmZXN0RW5kID0gJHBvcyArIDQgKyAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CgogICAgICAgICRwb3MgKz0gNDsKICAgICAgICAkbnVtRmlsZXMgPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CgogICAgICAgICRwb3MgKz0gNDsKCiAgICAgICAgLy8gc2tpcCBBUEkgdmVyc2lvbiAoWU9MTykKICAgICAgICAkcG9zICs9IDI7CgogICAgICAgIC8vIHNraXAgUEhBUiBmbGFncwogICAgICAgICRwb3MgKz0gNDsKCiAgICAgICAgJGFsaWFzTGVuZ3RoID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICRwb3MgKz0gNCArICRhbGlhc0xlbmd0aDsKCiAgICAgICAgJG1ldGFkYXRhTGVuZ3RoID0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICRwb3MgKz0gNCArICRtZXRhZGF0YUxlbmd0aDsKCiAgICAgICAgJGNvbXByZXNzZWRTaXplcyA9IDA7CiAgICAgICAgd2hpbGUgKCgkbnVtRmlsZXMgPiAwKSAmJiAoJHBvcyA8ICRtYW5pZmVzdEVuZCAtIDI0KSkgewogICAgICAgICAgICAkZmlsZW5hbWVMZW5ndGggPSAkdGhpcy0+cmVhZFVpbnQoJHBvcywgNCk7CiAgICAgICAgICAgICRwb3MgKz0gNCArICRmaWxlbmFtZUxlbmd0aDsKCiAgICAgICAgICAgIC8vIHNraXAgZmlsZXNpemUgYW5kIHRpbWVzdGFtcAogICAgICAgICAgICAkcG9zICs9IDIqNDsKCiAgICAgICAgICAgICRjb21wcmVzc2VkU2l6ZXMgKz0gJHRoaXMtPnJlYWRVaW50KCRwb3MsIDQpOwogICAgICAgICAgICAvLyBza2lwIGNvbXByZXNzZWQgZmlsZSBzaXplLCBjcmMzMiBjaGVja3N1bSBhbmQgZmlsZSBmbGFncwogICAgICAgICAgICAkcG9zICs9IDMqNDsKCiAgICAgICAgICAgICRtZXRhZGF0YUxlbmd0aCA9ICR0aGlzLT5yZWFkVWludCgkcG9zLCA0KTsKICAgICAgICAgICAgJHBvcyArPSA0ICsgJG1ldGFkYXRhTGVuZ3RoOwoKICAgICAgICAgICAgJG51bUZpbGVzLS07CiAgICAgICAgfQoKICAgICAgICBpZiAoJG51bUZpbGVzICE9PSAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcTG9naWNFeGNlcHRpb24oJ0FsbCBmaWxlcyB3ZXJlIG5vdCBwcm9jZXNzZWQsIHNvbWV0aGluZyBtdXN0IGhhdmUgZ29uZSB3cm9uZycpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtYW5pZmVzdEVuZCArICRjb21wcmVzc2VkU2l6ZXM7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFBIQVIgVXRpbHMuCiAqCiAqIChjKSBKb3JkaSBCb2dnaWFubyA8ai5ib2dnaWFub0BzZWxkLmJlPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgU2VsZFxQaGFyVXRpbHM7CgpjbGFzcyBMaW50ZXIKewogICAgLyoqCiAgICAgKiBMaW50cyBhbGwgcGhwIGZpbGVzIGluc2lkZSBhIGdpdmVuIHBoYXIgd2l0aCB0aGUgY3VycmVudCBQSFAgdmVyc2lvbgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGhhciBmaWxlIHBhdGgKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBsaW50KCRwYXRoKQogICAgewogICAgICAgICRwaHAgPSBkZWZpbmVkKCdQSFBfQklOQVJZJykgPyBQSFBfQklOQVJZIDogJ3BocCc7CgogICAgICAgIGlmICgkaXNXaW5kb3dzID0gZGVmaW5lZCgnUEhQX1dJTkRPV1NfVkVSU0lPTl9CVUlMRCcpKSB7CiAgICAgICAgICAgICR0bXBGaWxlID0gQHRlbXBuYW0oc3lzX2dldF90ZW1wX2RpcigpLCAnJyk7CgogICAgICAgICAgICBpZiAoISR0bXBGaWxlIHx8ICFpc193cml0YWJsZSgkdG1wRmlsZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcUnVudGltZUV4Y2VwdGlvbignVW5hYmxlIHRvIGNyZWF0ZSB0ZW1wIGZpbGUnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHBocCA9IHNlbGY6OmVzY2FwZVdpbmRvd3NQYXRoKCRwaHApOwogICAgICAgICAgICAkdG1wRmlsZSA9IHNlbGY6OmVzY2FwZVdpbmRvd3NQYXRoKCR0bXBGaWxlKTsKCiAgICAgICAgICAgIC8vIFBIUCA4IGVuY2xvc2VzIHRoZSBjb21tYW5kIGluIGRvdWJsZS1xdW90ZXMKICAgICAgICAgICAgaWYgKFBIUF9WRVJTSU9OX0lEID49IDgwMDAwKSB7CiAgICAgICAgICAgICAgICAkZm9ybWF0ID0gJyVzIC1sICVzJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRmb3JtYXQgPSAnIiVzIC1sICVzIic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjb21tYW5kID0gc3ByaW50ZigkZm9ybWF0LCAkcGhwLCAkdG1wRmlsZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNvbW1hbmQgPSAiJyIuJHBocC4iJyAtbCI7CiAgICAgICAgfQoKICAgICAgICAkZGVzY3JpcHRvcnNwZWMgPSBhcnJheSgKICAgICAgICAgICAgMCA9PiBhcnJheSgncGlwZScsICdyJyksCiAgICAgICAgICAgIDEgPT4gYXJyYXkoJ3BpcGUnLCAndycpLAogICAgICAgICAgICAyID0+IGFycmF5KCdwaXBlJywgJ3cnKQogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggKG5ldyBcUmVjdXJzaXZlSXRlcmF0b3JJdGVyYXRvcihuZXcgXFBoYXIoJHBhdGgpKSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoJGZpbGUtPmlzRGlyKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdWJzdHIoJGZpbGUsIC00KSA9PT0gJy5waHAnKSB7CiAgICAgICAgICAgICAgICAkZmlsZW5hbWUgPSAoc3RyaW5nKSAkZmlsZTsKCiAgICAgICAgICAgICAgICBpZiAoJGlzV2luZG93cykgewogICAgICAgICAgICAgICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCR0bXBGaWxlLCBmaWxlX2dldF9jb250ZW50cygkZmlsZW5hbWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcHJvY2VzcyA9IHByb2Nfb3BlbigkY29tbWFuZCwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMpOwogICAgICAgICAgICAgICAgaWYgKGlzX3Jlc291cmNlKCRwcm9jZXNzKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghJGlzV2luZG93cykgewogICAgICAgICAgICAgICAgICAgICAgICBmd3JpdGUoJHBpcGVzWzBdLCBmaWxlX2dldF9jb250ZW50cygkZmlsZW5hbWUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZmNsb3NlKCRwaXBlc1swXSk7CgogICAgICAgICAgICAgICAgICAgICRzdGRvdXQgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRwaXBlc1sxXSk7CiAgICAgICAgICAgICAgICAgICAgZmNsb3NlKCRwaXBlc1sxXSk7CiAgICAgICAgICAgICAgICAgICAgJHN0ZGVyciA9IHN0cmVhbV9nZXRfY29udGVudHMoJHBpcGVzWzJdKTsKICAgICAgICAgICAgICAgICAgICBmY2xvc2UoJHBpcGVzWzJdKTsKCiAgICAgICAgICAgICAgICAgICAgJGV4aXRDb2RlID0gcHJvY19jbG9zZSgkcHJvY2Vzcyk7CgogICAgICAgICAgICAgICAgICAgIGlmICgkZXhpdENvZGUgIT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdGRlcnIgPSBzdHJfcmVwbGFjZSgkdG1wRmlsZSwgJGZpbGVuYW1lLCAkc3RkZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbignRmFpbGVkIGxpbnRpbmcgJy4kZmlsZS4nOiAnLiRzdGRlcnIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFxSdW50aW1lRXhjZXB0aW9uKCdDb3VsZCBub3Qgc3RhcnQgbGludGVyIHByb2Nlc3MnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCRpc1dpbmRvd3MpIHsKICAgICAgICAgICAgQHVubGluaygkdG1wRmlsZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIFdpbmRvd3MgZmlsZSBwYXRoCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGVzY2FwZWQgcGF0aAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBlc2NhcGVXaW5kb3dzUGF0aCgkcGF0aCkKICAgIHsKICAgICAgICAvLyBRdW90ZSBpZiBwYXRoIGNvbnRhaW5zIHNwYWNlcyBvciBicmFja2V0cwogICAgICAgIGlmIChzdHJwYnJrKCRwYXRoLCAiICgpIikgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRwYXRoID0gJyInLiRwYXRoLiciJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcGF0aDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRW50aXR5OwoKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKCi8qKgogKiBAcGFja2FnZSBKc29uU2NoZW1hXEVudGl0eQogKgogKiBAYXV0aG9yIEpvb3N0IE5pamh1aXMgPGpuaWpodWlzODFAZ21haWwuY29tPgogKi8KY2xhc3MgSnNvblBvaW50ZXIKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRmaWxlbmFtZTsKCiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJpdmF0ZSAkcHJvcGVydHlQYXRocyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGJvb2wgV2hldGhlciB0aGUgdmFsdWUgYXQgdGhpcyBwYXRoIHdhcyBzZXQgZnJvbSBhIHNjaGVtYSBkZWZhdWx0CiAgICAgKi8KICAgIHByaXZhdGUgJGZyb21EZWZhdWx0ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gJHZhbHVlIGlzIG5vdCBhIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHZhbHVlKQogICAgewogICAgICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignUmVmIHZhbHVlIG11c3QgYmUgYSBzdHJpbmcnKTsKICAgICAgICB9CgogICAgICAgICRzcGxpdFJlZiA9IGV4cGxvZGUoJyMnLCAkdmFsdWUsIDIpOwogICAgICAgICR0aGlzLT5maWxlbmFtZSA9ICRzcGxpdFJlZlswXTsKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygxLCAkc3BsaXRSZWYpKSB7CiAgICAgICAgICAgICR0aGlzLT5wcm9wZXJ0eVBhdGhzID0gJHRoaXMtPmRlY29kZVByb3BlcnR5UGF0aHMoJHNwbGl0UmVmWzFdKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwcm9wZXJ0eVBhdGhTdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZGVjb2RlUHJvcGVydHlQYXRocygkcHJvcGVydHlQYXRoU3RyaW5nKQogICAgewogICAgICAgICRwYXRocyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnLycsIHRyaW0oJHByb3BlcnR5UGF0aFN0cmluZywgJy8nKSkgYXMgJHBhdGgpIHsKICAgICAgICAgICAgJHBhdGggPSAkdGhpcy0+ZGVjb2RlUGF0aCgkcGF0aCk7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHBhdGgpICYmICcnICE9PSAkcGF0aCkgewogICAgICAgICAgICAgICAgJHBhdGhzW10gPSAkcGF0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRwYXRoczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBlbmNvZGVQcm9wZXJ0eVBhdGhzKCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfbWFwKAogICAgICAgICAgICBhcnJheSgkdGhpcywgJ2VuY29kZVBhdGgnKSwKICAgICAgICAgICAgJHRoaXMtPmdldFByb3BlcnR5UGF0aHMoKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBkZWNvZGVQYXRoKCRwYXRoKQogICAgewogICAgICAgIHJldHVybiBzdHJ0cigkcGF0aCwgYXJyYXkoJ34xJyA9PiAnLycsICd+MCcgPT4gJ34nLCAnJTI1JyA9PiAnJScpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGVuY29kZVBhdGgoJHBhdGgpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0cnRyKCRwYXRoLCBhcnJheSgnLycgPT4gJ34xJywgJ34nID0+ICd+MCcsICclJyA9PiAnJTI1JykpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpbGVuYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGVuYW1lOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydHlQYXRocygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9wZXJ0eVBhdGhzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRwcm9wZXJ0eVBhdGhzCiAgICAgKgogICAgICogQHJldHVybiBKc29uUG9pbnRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gd2l0aFByb3BlcnR5UGF0aHMoYXJyYXkgJHByb3BlcnR5UGF0aHMpCiAgICB7CiAgICAgICAgJG5ldyA9IGNsb25lICR0aGlzOwogICAgICAgICRuZXctPnByb3BlcnR5UGF0aHMgPSAkcHJvcGVydHlQYXRoczsKCiAgICAgICAgcmV0dXJuICRuZXc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydHlQYXRoQXNTdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiBydHJpbSgnIy8nIC4gaW1wbG9kZSgnLycsICR0aGlzLT5lbmNvZGVQcm9wZXJ0eVBhdGhzKCkpLCAnLycpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0RmlsZW5hbWUoKSAuICR0aGlzLT5nZXRQcm9wZXJ0eVBhdGhBc1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogTWFyayB0aGUgdmFsdWUgYXQgdGhpcyBwYXRoIGFzIGJlaW5nIHNldCBmcm9tIGEgc2NoZW1hIGRlZmF1bHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZyb21EZWZhdWx0KCkKICAgIHsKICAgICAgICAkdGhpcy0+ZnJvbURlZmF1bHQgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciB0aGUgdmFsdWUgYXQgdGhpcyBwYXRoIHdhcyBzZXQgZnJvbSBhIHNjaGVtYSBkZWZhdWx0CiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmcm9tRGVmYXVsdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5mcm9tRGVmYXVsdDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWE7Cgp1c2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xCYXNlQ29uc3RyYWludDsKdXNlIEpzb25TY2hlbWFcQ29uc3RyYWludHNcQ29uc3RyYWludDsKCi8qKgogKiBBIEpzb25TY2hlbWEgQ29uc3RyYWludAogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBCcnVubyBQcmlldG8gUmVpcyA8YnJ1bm8ucC5yZWlzQGdtYWlsLmNvbT4KICoKICogQHNlZSAgICBSRUFETUUubWQKICovCmNsYXNzIFZhbGlkYXRvciBleHRlbmRzIEJhc2VDb25zdHJhaW50CnsKICAgIGNvbnN0IFNDSEVNQV9NRURJQV9UWVBFID0gJ2FwcGxpY2F0aW9uL3NjaGVtYStqc29uJzsKCiAgICBjb25zdCBFUlJPUl9OT05FICAgICAgICAgICAgICAgICAgICA9IDB4MDAwMDAwMDA7CiAgICBjb25zdCBFUlJPUl9BTEwgICAgICAgICAgICAgICAgICAgICA9IDB4RkZGRkZGRkY7CiAgICBjb25zdCBFUlJPUl9ET0NVTUVOVF9WQUxJREFUSU9OICAgICA9IDB4MDAwMDAwMDE7CiAgICBjb25zdCBFUlJPUl9TQ0hFTUFfVkFMSURBVElPTiAgICAgICA9IDB4MDAwMDAwMDI7CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGdpdmVuIGRhdGEgYWdhaW5zdCB0aGUgc2NoZW1hIGFuZCByZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSByZXN1bHRzCiAgICAgKiBCb3RoIHRoZSBwaHAgb2JqZWN0IGFuZCB0aGUgc2NoZW1hIGFyZSBzdXBwb3NlZCB0byBiZSBhIHJlc3VsdCBvZiBhIGpzb25fZGVjb2RlIGNhbGwuCiAgICAgKiBUaGUgdmFsaWRhdGlvbiB3b3JrcyBhcyBkZWZpbmVkIGJ5IHRoZSBzY2hlbWEgcHJvcG9zYWwgaW4gaHR0cDovL2pzb24tc2NoZW1hLm9yZy4KICAgICAqCiAgICAgKiBOb3RlIHRoYXQgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIHBhc3NlZCBieSByZWZlcmVuY2UsIHNvIHlvdSBtdXN0IHBhc3MgaW4gYSB2YXJpYWJsZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkYXRlKCYkdmFsdWUsICRzY2hlbWEgPSBudWxsLCAkY2hlY2tNb2RlID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBtYWtlIHN1cmUgJHNjaGVtYSBpcyBhbiBvYmplY3QKICAgICAgICBpZiAoaXNfYXJyYXkoJHNjaGVtYSkpIHsKICAgICAgICAgICAgJHNjaGVtYSA9IHNlbGY6OmFycmF5VG9PYmplY3RSZWN1cnNpdmUoJHNjaGVtYSk7CiAgICAgICAgfQoKICAgICAgICAvLyBzZXQgY2hlY2tNb2RlCiAgICAgICAgJGluaXRpYWxDaGVja01vZGUgPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKCk7CiAgICAgICAgaWYgKCRjaGVja01vZGUgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPnNldENvbmZpZygkY2hlY2tNb2RlKTsKICAgICAgICB9CgogICAgICAgIC8vIGFkZCBwcm92aWRlZCBzY2hlbWEgdG8gU2NoZW1hU3RvcmFnZSB3aXRoIGludGVybmFsIFVSSSB0byBhbGxvdyBpbnRlcm5hbCAkcmVmIHJlc29sdXRpb24KICAgICAgICBpZiAoaXNfb2JqZWN0KCRzY2hlbWEpICYmIHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSkgewogICAgICAgICAgICAkc2NoZW1hVVJJID0gJHNjaGVtYS0+aWQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHNjaGVtYVVSSSA9IFNjaGVtYVN0b3JhZ2U6OklOVEVSTkFMX1BST1ZJREVEX1NDSEVNQV9VUkk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCktPmFkZFNjaGVtYSgkc2NoZW1hVVJJLCAkc2NoZW1hKTsKCiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignc2NoZW1hJyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soCiAgICAgICAgICAgICR2YWx1ZSwKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPmdldFNjaGVtYVN0b3JhZ2UoKS0+Z2V0U2NoZW1hKCRzY2hlbWFVUkkpCiAgICAgICAgKTsKCiAgICAgICAgJHRoaXMtPmZhY3RvcnktPnNldENvbmZpZygkaW5pdGlhbENoZWNrTW9kZSk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoYXJyYXlfdW5pcXVlKCR2YWxpZGF0b3ItPmdldEVycm9ycygpLCBTT1JUX1JFR1VMQVIpKTsKCiAgICAgICAgcmV0dXJuICR2YWxpZGF0b3ItPmdldEVycm9yTWFzaygpOwogICAgfQoKICAgIC8qKgogICAgICogQWxpYXMgdG8gdmFsaWRhdGUoKSwgdG8gbWFpbnRhaW4gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgcHJldmlvdXMgQVBJCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygkdmFsdWUsICRzY2hlbWEpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWxpZGF0ZSgkdmFsdWUsICRzY2hlbWEpOwogICAgfQoKICAgIC8qKgogICAgICogQWxpYXMgdG8gdmFsaWRhdGUoKSwgdG8gbWFpbnRhaW4gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgcHJldmlvdXMgQVBJCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb2VyY2UoJiR2YWx1ZSwgJHNjaGVtYSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnZhbGlkYXRlKCR2YWx1ZSwgJHNjaGVtYSwgQ29uc3RyYWludDo6Q0hFQ0tfTU9ERV9DT0VSQ0VfVFlQRVMpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgSnNvblNjaGVtYTsKCmNsYXNzIFJmYzMzMzkKewogICAgY29uc3QgUkVHRVggPSAnL14oXGR7NH0tXGR7Mn0tXGR7Mn1bVCBdezF9XGR7Mn06XGR7Mn06XGR7Mn0pKFwuXGQrKT8oWnwoWystXVxkezJ9KTo/KFxkezJ9KSkkLyc7CgogICAgLyoqCiAgICAgKiBUcnkgY3JlYXRpbmcgYSBEYXRlVGltZSBpbnN0YW5jZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cmluZwogICAgICoKICAgICAqIEByZXR1cm4gXERhdGVUaW1lfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVGcm9tU3RyaW5nKCRzdHJpbmcpCiAgICB7CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKHNlbGY6OlJFR0VYLCBzdHJ0b3VwcGVyKCRzdHJpbmcpLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAkZGF0ZUFuZFRpbWUgPSAkbWF0Y2hlc1sxXTsKICAgICAgICAkbWljcm9zZWNvbmRzID0gJG1hdGNoZXNbMl0gPzogJy4wMDAwMDAnOwogICAgICAgICR0aW1lWm9uZSA9ICdaJyAhPT0gJG1hdGNoZXNbM10gPyAkbWF0Y2hlc1s0XSAuICc6JyAuICRtYXRjaGVzWzVdIDogJyswMDowMCc7CiAgICAgICAgJGRhdGVGb3JtYXQgPSBzdHJwb3MoJGRhdGVBbmRUaW1lLCAnVCcpID09PSBmYWxzZSA/ICdZLW0tZCBIOmk6cy51UCcgOiAnWS1tLWRcVEg6aTpzLnVQJzsKICAgICAgICAkZGF0ZVRpbWUgPSBcRGF0ZVRpbWU6OmNyZWF0ZUZyb21Gb3JtYXQoJGRhdGVGb3JtYXQsICRkYXRlQW5kVGltZSAuICRtaWNyb3NlY29uZHMgLiAkdGltZVpvbmUsIG5ldyBcRGF0ZVRpbWVab25lKCdVVEMnKSk7CgogICAgICAgIHJldHVybiAkZGF0ZVRpbWUgPzogbnVsbDsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWE7CgppbnRlcmZhY2UgU2NoZW1hU3RvcmFnZUludGVyZmFjZQp7CiAgICAvKioKICAgICAqIEFkZHMgc2NoZW1hIHdpdGggZ2l2ZW4gaWRlbnRpZmllcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkCiAgICAgKiBAcGFyYW0gb2JqZWN0ICRzY2hlbWEKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFNjaGVtYSgkaWQsICRzY2hlbWEgPSBudWxsKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgc2NoZW1hIGZvciBnaXZlbiBpZGVudGlmaWVyLCBvciBudWxsIGlmIGl0IGRvZXMgbm90IGV4aXN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQKICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2NoZW1hKCRpZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHNjaGVtYSBmb3IgZ2l2ZW4gcmVmZXJlbmNlIHdpdGggYWxsIHN1Yi1yZWZlcmVuY2VzIHJlc29sdmVkCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVmCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWYoJHJlZik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHNjaGVtYSByZWZlcmVuY2VkIGJ5ICckcmVmJyBwcm9wZXJ0eQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkcmVmU2NoZW1hCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWZTY2hlbWEoJHJlZlNjaGVtYSk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcU2NoZW1hU3RvcmFnZTsKdXNlIEpzb25TY2hlbWFcU2NoZW1hU3RvcmFnZUludGVyZmFjZTsKdXNlIEpzb25TY2hlbWFcVXJpXFVyaVJldHJpZXZlcjsKdXNlIEpzb25TY2hlbWFcVXJpUmV0cmlldmVySW50ZXJmYWNlOwp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogRmFjdG9yeSBmb3IgY2VudHJhbGl6ZSBjb25zdHJhaW50IGluaXRpYWxpemF0aW9uLgogKi8KY2xhc3MgRmFjdG9yeQp7CiAgICAvKioKICAgICAqIEB2YXIgU2NoZW1hU3RvcmFnZQogICAgICovCiAgICBwcm90ZWN0ZWQgJHNjaGVtYVN0b3JhZ2U7CgogICAgLyoqCiAgICAgKiBAdmFyIFVyaVJldHJpZXZlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJHVyaVJldHJpZXZlcjsKCiAgICAvKioKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByaXZhdGUgJGNoZWNrTW9kZSA9IENvbnN0cmFpbnQ6OkNIRUNLX01PREVfTk9STUFMOwoKICAgIC8qKgogICAgICogQHZhciBUeXBlQ2hlY2tcVHlwZUNoZWNrSW50ZXJmYWNlW10KICAgICAqLwogICAgcHJpdmF0ZSAkdHlwZUNoZWNrID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgaW50IFZhbGlkYXRpb24gY29udGV4dAogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9yQ29udGV4dCA9IFZhbGlkYXRvcjo6RVJST1JfRE9DVU1FTlRfVkFMSURBVElPTjsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRjb25zdHJhaW50TWFwID0gYXJyYXkoCiAgICAgICAgJ2FycmF5JyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xDb2xsZWN0aW9uQ29uc3RyYWludCcsCiAgICAgICAgJ2NvbGxlY3Rpb24nID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXENvbGxlY3Rpb25Db25zdHJhaW50JywKICAgICAgICAnb2JqZWN0JyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xPYmplY3RDb25zdHJhaW50JywKICAgICAgICAndHlwZScgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcVHlwZUNvbnN0cmFpbnQnLAogICAgICAgICd1bmRlZmluZWQnID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXFVuZGVmaW5lZENvbnN0cmFpbnQnLAogICAgICAgICdzdHJpbmcnID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXFN0cmluZ0NvbnN0cmFpbnQnLAogICAgICAgICdudW1iZXInID0+ICdKc29uU2NoZW1hXENvbnN0cmFpbnRzXE51bWJlckNvbnN0cmFpbnQnLAogICAgICAgICdlbnVtJyA9PiAnSnNvblNjaGVtYVxDb25zdHJhaW50c1xFbnVtQ29uc3RyYWludCcsCiAgICAgICAgJ2Zvcm1hdCcgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcRm9ybWF0Q29uc3RyYWludCcsCiAgICAgICAgJ3NjaGVtYScgPT4gJ0pzb25TY2hlbWFcQ29uc3RyYWludHNcU2NoZW1hQ29uc3RyYWludCcsCiAgICAgICAgJ3ZhbGlkYXRvcicgPT4gJ0pzb25TY2hlbWFcVmFsaWRhdG9yJwogICAgKTsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXk8Q29uc3RyYWludEludGVyZmFjZT4KICAgICAqLwogICAgcHJpdmF0ZSAkaW5zdGFuY2VDYWNoZSA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gU2NoZW1hU3RvcmFnZSAgICAgICAgICRzY2hlbWFTdG9yYWdlCiAgICAgKiBAcGFyYW0gVXJpUmV0cmlldmVySW50ZXJmYWNlICR1cmlSZXRyaWV2ZXIKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgICAgJGNoZWNrTW9kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoCiAgICAgICAgU2NoZW1hU3RvcmFnZUludGVyZmFjZSAkc2NoZW1hU3RvcmFnZSA9IG51bGwsCiAgICAgICAgVXJpUmV0cmlldmVySW50ZXJmYWNlICR1cmlSZXRyaWV2ZXIgPSBudWxsLAogICAgICAgICRjaGVja01vZGUgPSBDb25zdHJhaW50OjpDSEVDS19NT0RFX05PUk1BTAogICAgKSB7CiAgICAgICAgLy8gc2V0IHByb3ZpZGVkIGNvbmZpZyBvcHRpb25zCiAgICAgICAgJHRoaXMtPnNldENvbmZpZygkY2hlY2tNb2RlKTsKCiAgICAgICAgJHRoaXMtPnVyaVJldHJpZXZlciA9ICR1cmlSZXRyaWV2ZXIgPzogbmV3IFVyaVJldHJpZXZlcigpOwogICAgICAgICR0aGlzLT5zY2hlbWFTdG9yYWdlID0gJHNjaGVtYVN0b3JhZ2UgPzogbmV3IFNjaGVtYVN0b3JhZ2UoJHRoaXMtPnVyaVJldHJpZXZlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgY29uZmlnIHZhbHVlcwogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGNoZWNrTW9kZSBTZXQgY2hlY2tNb2RlIG9wdGlvbnMgLSBkb2VzIG5vdCBwcmVzZXJ2ZSBleGlzdGluZyBmbGFncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uZmlnKCRjaGVja01vZGUgPSBDb25zdHJhaW50OjpDSEVDS19NT0RFX05PUk1BTCkKICAgIHsKICAgICAgICAkdGhpcy0+Y2hlY2tNb2RlID0gJGNoZWNrTW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuYWJsZSBjaGVja01vZGUgZmxhZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb25maWcoJG9wdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNoZWNrTW9kZSB8PSAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIERpc2FibGUgY2hlY2tNb2RlIGZsYWdzCiAgICAgKgogICAgICogQHBhcmFtIGludCAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlQ29uZmlnKCRvcHRpb25zKQogICAgewogICAgICAgICR0aGlzLT5jaGVja01vZGUgJj0gfiRvcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGNoZWNrTW9kZSBvcHRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRvcHRpb25zIE9wdGlvbnMgdG8gZ2V0LCBpZiBudWxsIHRoZW4gcmV0dXJuIGVudGlyZSBiaXRtYXNrCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZpZygkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y2hlY2tNb2RlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5jaGVja01vZGUgJiAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVXJpUmV0cmlldmVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmlSZXRyaWV2ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmV0cmlldmVyOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY2hlbWFTdG9yYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYVN0b3JhZ2U7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGVDaGVjaygpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dHlwZUNoZWNrWyR0aGlzLT5jaGVja01vZGVdKSkgewogICAgICAgICAgICAkdGhpcy0+dHlwZUNoZWNrWyR0aGlzLT5jaGVja01vZGVdID0gKCR0aGlzLT5jaGVja01vZGUgJiBDb25zdHJhaW50OjpDSEVDS19NT0RFX1RZUEVfQ0FTVCkKICAgICAgICAgICAgICAgID8gbmV3IFR5cGVDaGVja1xMb29zZVR5cGVDaGVjaygpCiAgICAgICAgICAgICAgICA6IG5ldyBUeXBlQ2hlY2tcU3RyaWN0VHlwZUNoZWNrKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnR5cGVDaGVja1skdGhpcy0+Y2hlY2tNb2RlXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsYXNzCiAgICAgKgogICAgICogQHJldHVybiBGYWN0b3J5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDb25zdHJhaW50Q2xhc3MoJG5hbWUsICRjbGFzcykKICAgIHsKICAgICAgICAvLyBFbnN1cmUgY2xhc3MgZXhpc3RzCiAgICAgICAgaWYgKCFjbGFzc19leGlzdHMoJGNsYXNzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdVbmtub3duIGNvbnN0cmFpbnQgJyAuICRuYW1lKTsKICAgICAgICB9CiAgICAgICAgLy8gRW5zdXJlIGNsYXNzIGlzIGFwcHJvcHJpYXRlCiAgICAgICAgaWYgKCFpbl9hcnJheSgnSnNvblNjaGVtYVxDb25zdHJhaW50c1xDb25zdHJhaW50SW50ZXJmYWNlJywgY2xhc3NfaW1wbGVtZW50cygkY2xhc3MpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIGNsYXNzICcgLiAkbmFtZSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jb25zdHJhaW50TWFwWyRuYW1lXSA9ICRjbGFzczsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgY29uc3RyYWludCBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIGNvbnN0cmFpbnQgbmFtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25zdHJhaW50TmFtZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIGlzIG5vdCBwb3NzaWJsZSBjcmVhdGUgdGhlIGNvbnN0cmFpbnQgaW5zdGFuY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbnN0cmFpbnRJbnRlcmZhY2V8T2JqZWN0Q29uc3RyYWludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2VGb3IoJGNvbnN0cmFpbnROYW1lKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmNvbnN0cmFpbnRNYXBbJGNvbnN0cmFpbnROYW1lXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVW5rbm93biBjb25zdHJhaW50ICcgLiAkY29uc3RyYWludE5hbWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+aW5zdGFuY2VDYWNoZVskY29uc3RyYWludE5hbWVdKSkgewogICAgICAgICAgICAkdGhpcy0+aW5zdGFuY2VDYWNoZVskY29uc3RyYWludE5hbWVdID0gbmV3ICR0aGlzLT5jb25zdHJhaW50TWFwWyRjb25zdHJhaW50TmFtZV0oJHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNsb25lICR0aGlzLT5pbnN0YW5jZUNhY2hlWyRjb25zdHJhaW50TmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGVycm9yIGNvbnRleHQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JDb250ZXh0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yQ29udGV4dDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgZXJyb3IgY29udGV4dAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbGlkYXRpb25Db250ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFcnJvckNvbnRleHQoJGVycm9yQ29udGV4dCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JDb250ZXh0ID0gJGVycm9yQ29udGV4dDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CgovKioKICogVGhlIENvbGxlY3Rpb25Db25zdHJhaW50IENvbnN0cmFpbnRzLCB2YWxpZGF0ZXMgYW4gYXJyYXkgYWdhaW5zdCBhIGdpdmVuIHNjaGVtYQogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBCcnVubyBQcmlldG8gUmVpcyA8YnJ1bm8ucC5yZWlzQGdtYWlsLmNvbT4KICovCmNsYXNzIENvbGxlY3Rpb25Db25zdHJhaW50IGV4dGVuZHMgQ29uc3RyYWludAp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCYkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBWZXJpZnkgbWluSXRlbXMKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bWluSXRlbXMpICYmIGNvdW50KCR2YWx1ZSkgPCAkc2NoZW1hLT5taW5JdGVtcykgewogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdUaGVyZSBtdXN0IGJlIGEgbWluaW11bSBvZiAnIC4gJHNjaGVtYS0+bWluSXRlbXMgLiAnIGl0ZW1zIGluIHRoZSBhcnJheScsICdtaW5JdGVtcycsIGFycmF5KCdtaW5JdGVtcycgPT4gJHNjaGVtYS0+bWluSXRlbXMpKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSBtYXhJdGVtcwogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5tYXhJdGVtcykgJiYgY291bnQoJHZhbHVlKSA+ICRzY2hlbWEtPm1heEl0ZW1zKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1RoZXJlIG11c3QgYmUgYSBtYXhpbXVtIG9mICcgLiAkc2NoZW1hLT5tYXhJdGVtcyAuICcgaXRlbXMgaW4gdGhlIGFycmF5JywgJ21heEl0ZW1zJywgYXJyYXkoJ21heEl0ZW1zJyA9PiAkc2NoZW1hLT5tYXhJdGVtcykpOwogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IHVuaXF1ZUl0ZW1zCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPnVuaXF1ZUl0ZW1zKSAmJiAkc2NoZW1hLT51bmlxdWVJdGVtcykgewogICAgICAgICAgICAkdW5pcXVlID0gJHZhbHVlOwogICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHZhbHVlKSAmJiBjb3VudCgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAkdW5pcXVlID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2YXJfZXhwb3J0KCRlLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0sICR2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50KGFycmF5X3VuaXF1ZSgkdW5pcXVlKSkgIT0gY291bnQoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnVGhlcmUgYXJlIG5vIGR1cGxpY2F0ZXMgYWxsb3dlZCBpbiB0aGUgYXJyYXknLCAndW5pcXVlSXRlbXMnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IGl0ZW1zCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPml0ZW1zKSkgewogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVJdGVtcygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBpdGVtcwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIFxzdGRDbGFzcyAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZUl0ZW1zKCYkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoaXNfb2JqZWN0KCRzY2hlbWEtPml0ZW1zKSkgewogICAgICAgICAgICAvLyBqdXN0IG9uZSB0eXBlIGRlZmluaXRpb24gZm9yIHRoZSB3aG9sZSBhcnJheQogICAgICAgICAgICBmb3JlYWNoICgkdmFsdWUgYXMgJGsgPT4gJiR2KSB7CiAgICAgICAgICAgICAgICAkaW5pdEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKCiAgICAgICAgICAgICAgICAvLyBGaXJzdCBjaGVjayBpZiBpdHMgZGVmaW5lZCBpbiAiaXRlbXMiCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHYsICRzY2hlbWEtPml0ZW1zLCAkcGF0aCwgJGspOwoKICAgICAgICAgICAgICAgIC8vIFJlY2hlY2sgd2l0aCAiYWRkaXRpb25hbEl0ZW1zIiBpZiB0aGUgZmlyc3QgdGVzdCBmYWlscwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRpbml0RXJyb3JzKSA8IGNvdW50KCR0aGlzLT5nZXRFcnJvcnMoKSkgJiYgKGlzc2V0KCRzY2hlbWEtPmFkZGl0aW9uYWxJdGVtcykgJiYgJHNjaGVtYS0+YWRkaXRpb25hbEl0ZW1zICE9PSBmYWxzZSkpIHsKICAgICAgICAgICAgICAgICAgICAkc2Vjb25kRXJyb3JzID0gJHRoaXMtPmdldEVycm9ycygpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdiwgJHNjaGVtYS0+YWRkaXRpb25hbEl0ZW1zLCAkcGF0aCwgJGspOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlc2V0IGVycm9ycyBpZiBuZWVkZWQKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkc2Vjb25kRXJyb3JzKSAmJiBjb3VudCgkc2Vjb25kRXJyb3JzKSA8IGNvdW50KCR0aGlzLT5nZXRFcnJvcnMoKSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJHNlY29uZEVycm9yczsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkc2Vjb25kRXJyb3JzKSAmJiBjb3VudCgkc2Vjb25kRXJyb3JzKSA9PT0gY291bnQoJHRoaXMtPmdldEVycm9ycygpKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lcnJvcnMgPSAkaW5pdEVycm9yczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB1bnNldCgkdik7IC8qIHJlbW92ZSBkYW5nbGluZyByZWZlcmVuY2UgdG8gcHJldmVudCBhbnkgZnV0dXJlIGJ1Z3MKICAgICAgICAgICAgICAgICAgICAgICAgKiBjYXVzZWQgYnkgYWNjaWRlbnRhbGx5IHVzaW5nICR2IGVsc2V3aGVyZSAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIERlZmluZWQgaXRlbSB0eXBlIGRlZmluaXRpb25zCiAgICAgICAgICAgIGZvcmVhY2ggKCR2YWx1ZSBhcyAkayA9PiAmJHYpIHsKICAgICAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRrLCAkc2NoZW1hLT5pdGVtcykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHYsICRzY2hlbWEtPml0ZW1zWyRrXSwgJHBhdGgsICRrKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBpdGVtcwogICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eV9leGlzdHMoJHNjaGVtYSwgJ2FkZGl0aW9uYWxJdGVtcycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc2NoZW1hLT5hZGRpdGlvbmFsSXRlbXMgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHYsICRzY2hlbWEtPmFkZGl0aW9uYWxJdGVtcywgJHBhdGgsICRrKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCwgJ1RoZSBpdGVtICcgLiAkaSAuICdbJyAuICRrIC4gJ10gaXMgbm90IGRlZmluZWQgYW5kIHRoZSBkZWZpbml0aW9uIGRvZXMgbm90IGFsbG93IGFkZGl0aW9uYWwgaXRlbXMnLCAnYWRkaXRpb25hbEl0ZW1zJywgYXJyYXkoJ2FkZGl0aW9uYWxJdGVtcycgPT4gJHNjaGVtYS0+YWRkaXRpb25hbEl0ZW1zKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgYmUgdmFsaWQgYWdhaW5zdCBhbiBlbXB0eSBzY2hlbWEKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2LCBuZXcgXHN0ZENsYXNzKCksICRwYXRoLCAkayk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuc2V0KCR2KTsgLyogcmVtb3ZlIGRhbmdsaW5nIHJlZmVyZW5jZSB0byBwcmV2ZW50IGFueSBmdXR1cmUgYnVncwogICAgICAgICAgICAgICAgICAgICAgICAqIGNhdXNlZCBieSBhY2NpZGVudGFsbHkgdXNpbmcgJHYgZWxzZXdoZXJlICovCgogICAgICAgICAgICAvLyBUcmVhdCB3aGVuIHdlIGhhdmUgbW9yZSBzY2hlbWEgZGVmaW5pdGlvbnMgdGhhbiB2YWx1ZXMsIG5vdCBmb3IgZW1wdHkgYXJyYXlzCiAgICAgICAgICAgIGlmIChjb3VudCgkdmFsdWUpID4gMCkgewogICAgICAgICAgICAgICAgZm9yICgkayA9IGNvdW50KCR2YWx1ZSk7ICRrIDwgY291bnQoJHNjaGVtYS0+aXRlbXMpOyAkaysrKSB7CiAgICAgICAgICAgICAgICAgICAgJHVuZGVmaW5lZEluc3RhbmNlID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd1bmRlZmluZWQnKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHVuZGVmaW5lZEluc3RhbmNlLCAkc2NoZW1hLT5pdGVtc1ska10sICRwYXRoLCAkayk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBPYmplY3RDb25zdHJhaW50IENvbnN0cmFpbnRzLCB2YWxpZGF0ZXMgYW4gb2JqZWN0IGFnYWluc3QgYSBnaXZlbiBzY2hlbWEKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgQnJ1bm8gUHJpZXRvIFJlaXMgPGJydW5vLnAucmVpc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBPYmplY3RDb25zdHJhaW50IGV4dGVuZHMgQ29uc3RyYWludAp7CiAgICAvKioKICAgICAqIEB2YXIgYXJyYXkgTGlzdCBvZiBwcm9wZXJ0aWVzIHRvIHdoaWNoIGEgZGVmYXVsdCB2YWx1ZSBoYXMgYmVlbiBhcHBsaWVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXBwbGllZERlZmF1bHRzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCYkZWxlbWVudCwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJHByb3BlcnRpZXMgPSBudWxsLAogICAgICAgICRhZGRpdGlvbmFsUHJvcCA9IG51bGwsICRwYXR0ZXJuUHJvcGVydGllcyA9IG51bGwsICRhcHBsaWVkRGVmYXVsdHMgPSBhcnJheSgpKQogICAgewogICAgICAgIGlmICgkZWxlbWVudCBpbnN0YW5jZW9mIFVuZGVmaW5lZENvbnN0cmFpbnQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFwcGxpZWREZWZhdWx0cyA9ICRhcHBsaWVkRGVmYXVsdHM7CgogICAgICAgICRtYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBpZiAoJHBhdHRlcm5Qcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRoZSBlbGVtZW50IHBhdHRlcm4gcHJvcGVydGllcwogICAgICAgICAgICAkbWF0Y2hlcyA9ICR0aGlzLT52YWxpZGF0ZVBhdHRlcm5Qcm9wZXJ0aWVzKCRlbGVtZW50LCAkcGF0aCwgJHBhdHRlcm5Qcm9wZXJ0aWVzKTsKICAgICAgICB9CgogICAgICAgIGlmICgkcHJvcGVydGllcykgewogICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgZWxlbWVudCBwcm9wZXJ0aWVzCiAgICAgICAgICAgICR0aGlzLT52YWxpZGF0ZVByb3BlcnRpZXMoJGVsZW1lbnQsICRwcm9wZXJ0aWVzLCAkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICAvLyB2YWxpZGF0ZSBhZGRpdGlvbmFsIGVsZW1lbnQgcHJvcGVydGllcyAmIGNvbnN0cmFpbnRzCiAgICAgICAgJHRoaXMtPnZhbGlkYXRlRWxlbWVudCgkZWxlbWVudCwgJG1hdGNoZXMsICRzY2hlbWEsICRwYXRoLCAkcHJvcGVydGllcywgJGFkZGl0aW9uYWxQcm9wKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGVQYXR0ZXJuUHJvcGVydGllcygkZWxlbWVudCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkcGF0dGVyblByb3BlcnRpZXMpCiAgICB7CiAgICAgICAgJHRyeSA9IGFycmF5KCcvJywgJyMnLCAnKycsICd+JywgJyUnKTsKICAgICAgICAkbWF0Y2hlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBhdHRlcm5Qcm9wZXJ0aWVzIGFzICRwcmVnZXggPT4gJHNjaGVtYSkgewogICAgICAgICAgICAkZGVsaW1pdGVyID0gJy8nOwogICAgICAgICAgICAvLyBDaG9vc2UgZGVsaW1pdGVyLiBOZWNlc3NhcnkgZm9yIHBhdHRlcm5zIGxpa2UgXi8gLCBvdGhlcndpc2UgeW91IGdldCBlcnJvcgogICAgICAgICAgICBmb3JlYWNoICgkdHJ5IGFzICRkZWxpbWl0ZXIpIHsKICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJHByZWdleCwgJGRlbGltaXRlcikgPT09IGZhbHNlKSB7IC8vIHNhZmUgdG8gdXNlCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFZhbGlkYXRlIHRoZSBwYXR0ZXJuIGJlZm9yZSB1c2luZyBpdCB0byB0ZXN0IGZvciBtYXRjaGVzCiAgICAgICAgICAgIGlmIChAcHJlZ19tYXRjaCgkZGVsaW1pdGVyIC4gJHByZWdleCAuICRkZWxpbWl0ZXIgLiAndScsICcnKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1RoZSBwYXR0ZXJuICInIC4gJHByZWdleCAuICciIGlzIGludmFsaWQnLCAncHJlZ2V4JywgYXJyYXkoJ3ByZWdleCcgPT4gJHByZWdleCkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAoJGVsZW1lbnQgYXMgJGkgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgkZGVsaW1pdGVyIC4gJHByZWdleCAuICRkZWxpbWl0ZXIgLiAndScsICRpKSkgewogICAgICAgICAgICAgICAgICAgICRtYXRjaGVzW10gPSAkaTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkc2NoZW1hID86IG5ldyBcc3RkQ2xhc3MoKSwgJHBhdGgsICRpLCBpbl9hcnJheSgkaSwgJHRoaXMtPmFwcGxpZWREZWZhdWx0cykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG1hdGNoZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGVsZW1lbnQgcHJvcGVydGllcwogICAgICoKICAgICAqIEBwYXJhbSBcU3RkQ2xhc3MgICAgICAgICRlbGVtZW50ICAgICAgICBFbGVtZW50IHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAkbWF0Y2hlcyAgICAgICAgTWF0Y2hlcyBmcm9tIHBhdHRlcm5Qcm9wZXJ0aWVzIChpZiBhbnkpCiAgICAgKiBAcGFyYW0gXFN0ZENsYXNzICAgICAgICAkc2NoZW1hICAgICAgICAgT2JqZWN0Q29uc3RyYWludCBkZWZpbml0aW9uCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aCAgICAgICAgICAgQ3VycmVudCB0ZXN0IHBhdGgKICAgICAqIEBwYXJhbSBcU3RkQ2xhc3MgICAgICAgICRwcm9wZXJ0aWVzICAgICBQcm9wZXJ0aWVzCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkYWRkaXRpb25hbFByb3AgQWRkaXRpb25hbCBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZUVsZW1lbnQoJGVsZW1lbnQsICRtYXRjaGVzLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLAogICAgICAgICRwcm9wZXJ0aWVzID0gbnVsbCwgJGFkZGl0aW9uYWxQcm9wID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+dmFsaWRhdGVNaW5NYXhDb25zdHJhaW50KCRlbGVtZW50LCAkc2NoZW1hLCAkcGF0aCk7CgogICAgICAgIGZvcmVhY2ggKCRlbGVtZW50IGFzICRpID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkZGVmaW5pdGlvbiA9ICR0aGlzLT5nZXRQcm9wZXJ0eSgkcHJvcGVydGllcywgJGkpOwoKICAgICAgICAgICAgLy8gbm8gYWRkaXRpb25hbCBwcm9wZXJ0aWVzIGFsbG93ZWQKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkaSwgJG1hdGNoZXMpICYmICRhZGRpdGlvbmFsUHJvcCA9PT0gZmFsc2UgJiYgJHRoaXMtPmlubGluZVNjaGVtYVByb3BlcnR5ICE9PSAkaSAmJiAhJGRlZmluaXRpb24pIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1RoZSBwcm9wZXJ0eSAnIC4gJGkgLiAnIGlzIG5vdCBkZWZpbmVkIGFuZCB0aGUgZGVmaW5pdGlvbiBkb2VzIG5vdCBhbGxvdyBhZGRpdGlvbmFsIHByb3BlcnRpZXMnLCAnYWRkaXRpb25hbFByb3AnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gYWRkaXRpb25hbCBwcm9wZXJ0aWVzIGRlZmluZWQKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkaSwgJG1hdGNoZXMpICYmICRhZGRpdGlvbmFsUHJvcCAmJiAhJGRlZmluaXRpb24pIHsKICAgICAgICAgICAgICAgIGlmICgkYWRkaXRpb25hbFByb3AgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCBudWxsLCAkcGF0aCwgJGksIGluX2FycmF5KCRpLCAkdGhpcy0+YXBwbGllZERlZmF1bHRzKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdmFsdWUsICRhZGRpdGlvbmFsUHJvcCwgJHBhdGgsICRpLCBpbl9hcnJheSgkaSwgJHRoaXMtPmFwcGxpZWREZWZhdWx0cykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBwcm9wZXJ0eSByZXF1aXJlcyBwcmVzZW5jZSBvZiBhbm90aGVyCiAgICAgICAgICAgICRyZXF1aXJlID0gJHRoaXMtPmdldFByb3BlcnR5KCRkZWZpbml0aW9uLCAncmVxdWlyZXMnKTsKICAgICAgICAgICAgaWYgKCRyZXF1aXJlICYmICEkdGhpcy0+Z2V0UHJvcGVydHkoJGVsZW1lbnQsICRyZXF1aXJlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnVGhlIHByZXNlbmNlIG9mIHRoZSBwcm9wZXJ0eSAnIC4gJGkgLiAnIHJlcXVpcmVzIHRoYXQgJyAuICRyZXF1aXJlIC4gJyBhbHNvIGJlIHByZXNlbnQnLCAncmVxdWlyZXMnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHByb3BlcnR5ID0gJHRoaXMtPmdldFByb3BlcnR5KCRlbGVtZW50LCAkaSwgJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd1bmRlZmluZWQnKSk7CiAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlTWluTWF4Q29uc3RyYWludCghKCRwcm9wZXJ0eSBpbnN0YW5jZW9mIFVuZGVmaW5lZENvbnN0cmFpbnQpID8gJHByb3BlcnR5IDogJGVsZW1lbnQsICRkZWZpbml0aW9uLCAkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgdGhlIGRlZmluaXRpb24gcHJvcGVydGllcwogICAgICoKICAgICAqIEBwYXJhbSBcc3RkQ2xhc3MgICAgICAgICRlbGVtZW50ICAgIEVsZW1lbnQgdG8gdmFsaWRhdGUKICAgICAqIEBwYXJhbSBcc3RkQ2xhc3MgICAgICAgICRwcm9wZXJ0aWVzIFByb3BlcnR5IGRlZmluaXRpb25zCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aCAgICAgICBQYXRoPwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0aWVzKCYkZWxlbWVudCwgJHByb3BlcnRpZXMgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwpCiAgICB7CiAgICAgICAgJHVuZGVmaW5lZENvbnN0cmFpbnQgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3VuZGVmaW5lZCcpOwoKICAgICAgICBmb3JlYWNoICgkcHJvcGVydGllcyBhcyAkaSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJHByb3BlcnR5ID0gJiR0aGlzLT5nZXRQcm9wZXJ0eSgkZWxlbWVudCwgJGksICR1bmRlZmluZWRDb25zdHJhaW50KTsKICAgICAgICAgICAgJGRlZmluaXRpb24gPSAkdGhpcy0+Z2V0UHJvcGVydHkoJHByb3BlcnRpZXMsICRpKTsKCiAgICAgICAgICAgIGlmIChpc19vYmplY3QoJGRlZmluaXRpb24pKSB7CiAgICAgICAgICAgICAgICAvLyBVbmRlZmluZWQgY29uc3RyYWludCB3aWxsIGNoZWNrIGZvciBpc19vYmplY3QoKSBhbmQgcXVpdCBpZiBpcyBub3QgLSBzbyB3aHkgcGFzcyBpdD8KICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkcHJvcGVydHksICRkZWZpbml0aW9uLCAkcGF0aCwgJGksIGluX2FycmF5KCRpLCAkdGhpcy0+YXBwbGllZERlZmF1bHRzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiByZXRyaWV2ZXMgYSBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdCBvciBhcnJheQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgJGVsZW1lbnQgIEVsZW1lbnQgdG8gdmFsaWRhdGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHByb3BlcnR5IFByb3BlcnR5IHRvIHJldHJpZXZlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICRmYWxsYmFjayBEZWZhdWx0IHZhbHVlIGlmIHByb3BlcnR5IGlzIG5vdCBmb3VuZAogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uICZnZXRQcm9wZXJ0eSgmJGVsZW1lbnQsICRwcm9wZXJ0eSwgJGZhbGxiYWNrID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJGVsZW1lbnQpICYmIChpc3NldCgkZWxlbWVudFskcHJvcGVydHldKSB8fCBhcnJheV9rZXlfZXhpc3RzKCRwcm9wZXJ0eSwgJGVsZW1lbnQpKSAvKiR0aGlzLT5jaGVja01vZGUgPT0gc2VsZjo6Q0hFQ0tfTU9ERV9UWVBFX0NBU1QqLykgewogICAgICAgICAgICByZXR1cm4gJGVsZW1lbnRbJHByb3BlcnR5XTsKICAgICAgICB9IGVsc2VpZiAoaXNfb2JqZWN0KCRlbGVtZW50KSAmJiBwcm9wZXJ0eV9leGlzdHMoJGVsZW1lbnQsICRwcm9wZXJ0eSkpIHsKICAgICAgICAgICAgcmV0dXJuICRlbGVtZW50LT4kcHJvcGVydHk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZhbGxiYWNrOwogICAgfQoKICAgIC8qKgogICAgICogdmFsaWRhdGluZyBtaW5pbXVtIGFuZCBtYXhpbXVtIHByb3BlcnR5IGNvbnN0cmFpbnRzIChpZiBwcmVzZW50KSBhZ2FpbnN0IGFuIGVsZW1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gXHN0ZENsYXNzICAgICAgICAkZWxlbWVudCAgICAgICAgICBFbGVtZW50IHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gXHN0ZENsYXNzICAgICAgICAkb2JqZWN0RGVmaW5pdGlvbiBPYmplY3RDb25zdHJhaW50IGRlZmluaXRpb24KICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoICAgICAgICAgICAgIFBhdGggdG8gdGVzdD8KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlTWluTWF4Q29uc3RyYWludCgkZWxlbWVudCwgJG9iamVjdERlZmluaXRpb24sIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBWZXJpZnkgbWluaW11bSBudW1iZXIgb2YgcHJvcGVydGllcwogICAgICAgIGlmIChpc3NldCgkb2JqZWN0RGVmaW5pdGlvbi0+bWluUHJvcGVydGllcykgJiYgIWlzX29iamVjdCgkb2JqZWN0RGVmaW5pdGlvbi0+bWluUHJvcGVydGllcykpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlDb3VudCgkZWxlbWVudCkgPCAkb2JqZWN0RGVmaW5pdGlvbi0+bWluUHJvcGVydGllcykgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBjb250YWluIGEgbWluaW11bSBvZiAnIC4gJG9iamVjdERlZmluaXRpb24tPm1pblByb3BlcnRpZXMgLiAnIHByb3BlcnRpZXMnLCAnbWluUHJvcGVydGllcycsIGFycmF5KCdtaW5Qcm9wZXJ0aWVzJyA9PiAkb2JqZWN0RGVmaW5pdGlvbi0+bWluUHJvcGVydGllcykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIFZlcmlmeSBtYXhpbXVtIG51bWJlciBvZiBwcm9wZXJ0aWVzCiAgICAgICAgaWYgKGlzc2V0KCRvYmplY3REZWZpbml0aW9uLT5tYXhQcm9wZXJ0aWVzKSAmJiAhaXNfb2JqZWN0KCRvYmplY3REZWZpbml0aW9uLT5tYXhQcm9wZXJ0aWVzKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUNvdW50KCRlbGVtZW50KSA+ICRvYmplY3REZWZpbml0aW9uLT5tYXhQcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGNvbnRhaW4gbm8gbW9yZSB0aGFuICcgLiAkb2JqZWN0RGVmaW5pdGlvbi0+bWF4UHJvcGVydGllcyAuICcgcHJvcGVydGllcycsICdtYXhQcm9wZXJ0aWVzJywgYXJyYXkoJ21heFByb3BlcnRpZXMnID0+ICRvYmplY3REZWZpbml0aW9uLT5tYXhQcm9wZXJ0aWVzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwp1c2UgSnNvblNjaGVtYVxSZmMzMzM5OwoKLyoqCiAqIFZhbGlkYXRlcyBhZ2FpbnN0IHRoZSAiZm9ybWF0IiBwcm9wZXJ0eQogKgogKiBAYXV0aG9yIEp1c3RpbiBSYWluYm93IDxqdXN0aW4ucmFpbmJvd0BnbWFpbC5jb20+CiAqCiAqIEBzZWUgICBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9kcmFmdC16eXAtanNvbi1zY2hlbWEtMDMjc2VjdGlvbi01LjIzCiAqLwpjbGFzcyBGb3JtYXRDb25zdHJhaW50IGV4dGVuZHMgQ29uc3RyYWludAp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCYkZWxlbWVudCwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHNjaGVtYS0+Zm9ybWF0KSB8fCAkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfRElTQUJMRV9GT1JNQVQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoJHNjaGVtYS0+Zm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgJ2RhdGUnOgogICAgICAgICAgICAgICAgaWYgKCEkZGF0ZSA9ICR0aGlzLT52YWxpZGF0ZURhdGVUaW1lKCRlbGVtZW50LCAnWS1tLWQnKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgc3ByaW50ZignSW52YWxpZCBkYXRlICVzLCBleHBlY3RlZCBmb3JtYXQgWVlZWS1NTS1ERCcsIGpzb25fZW5jb2RlKCRlbGVtZW50KSksICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAndGltZSc6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZURhdGVUaW1lKCRlbGVtZW50LCAnSDppOnMnKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgc3ByaW50ZignSW52YWxpZCB0aW1lICVzLCBleHBlY3RlZCBmb3JtYXQgaGg6bW06c3MnLCBqc29uX2VuY29kZSgkZWxlbWVudCkpLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2RhdGUtdGltZSc6CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gUmZjMzMzOTo6Y3JlYXRlRnJvbVN0cmluZygkZWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsIHNwcmludGYoJ0ludmFsaWQgZGF0ZS10aW1lICVzLCBleHBlY3RlZCBmb3JtYXQgWVlZWS1NTS1ERFRoaDptbTpzc1ogb3IgWVlZWS1NTS1ERFRoaDptbTpzcytoaDptbScsIGpzb25fZW5jb2RlKCRlbGVtZW50KSksICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAndXRjLW1pbGxpc2VjJzoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlRGF0ZVRpbWUoJGVsZW1lbnQsICdVJykpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsIHNwcmludGYoJ0ludmFsaWQgdGltZSAlcywgZXhwZWN0ZWQgaW50ZWdlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgRXBvY2gnLCBqc29uX2VuY29kZSgkZWxlbWVudCkpLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ3JlZ2V4JzoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlUmVnZXgoJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCByZWdleCBmb3JtYXQgJyAuICRlbGVtZW50LCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2NvbG9yJzoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlQ29sb3IoJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBjb2xvcicsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAnc3R5bGUnOgogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+dmFsaWRhdGVTdHlsZSgkZWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdJbnZhbGlkIHN0eWxlJywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICdwaG9uZSc6CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZVBob25lKCRlbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgcGhvbmUgbnVtYmVyJywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICd1cmknOgogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IGZpbHRlcl92YXIoJGVsZW1lbnQsIEZJTFRFUl9WQUxJREFURV9VUkwsIEZJTFRFUl9OVUxMX09OX0ZBSUxVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBVUkwgZm9ybWF0JywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICd1cmlyZWYnOgogICAgICAgICAgICBjYXNlICd1cmktcmVmZXJlbmNlJzoKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBmaWx0ZXJfdmFyKCRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfVVJMLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEZJTFRFUl9WQUxJREFURV9VUkwgZG9lcyBub3QgY29uZm9ybSB0byBSRkMtMzk4NiwgYW5kIGNhbm5vdCBoYW5kbGUgcmVsYXRpdmUgVVJMcywgYnV0CiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGpzb24tc2NoZW1hIHNwZWMgdXNlcyBSRkMtMzk4Niwgc28gbmVlZCBhIGJpdCBvZiBoYWNrZXJ5IHRvIHByb3Blcmx5IHZhbGlkYXRlIHRoZW0uCiAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tNC4yIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLgogICAgICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJGVsZW1lbnQsIDAsIDIpID09PSAnLy8nKSB7IC8vIG5ldHdvcmstcGF0aCByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbGlkVVJMID0gZmlsdGVyX3Zhcignc2NoZW1lOicgLiAkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX1VSTCwgRklMVEVSX05VTExfT05fRkFJTFVSRSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHN1YnN0cigkZWxlbWVudCwgMCwgMSkgPT09ICcvJykgeyAvLyBhYnNvbHV0ZS1wYXRoIHJlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRVUkwgPSBmaWx0ZXJfdmFyKCdzY2hlbWU6Ly9ob3N0JyAuICRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfVVJMLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoc3RybGVuKCRlbGVtZW50KSkgeyAvLyByZWxhdGl2ZS1wYXRoIHJlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAkcGF0aFBhcnRzID0gZXhwbG9kZSgnLycsICRlbGVtZW50LCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkcGF0aFBhcnRzWzBdLCAnOicpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZhbGlkVVJMID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWxpZFVSTCA9IGZpbHRlcl92YXIoJ3NjaGVtZTovL2hvc3QvJyAuICRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfVVJMLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR2YWxpZFVSTCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkdmFsaWRVUkwgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBVUkwgZm9ybWF0JywgJ2Zvcm1hdCcsIGFycmF5KCdmb3JtYXQnID0+ICRzY2hlbWEtPmZvcm1hdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAnZW1haWwnOgogICAgICAgICAgICAgICAgJGZpbHRlckZsYWdzID0gRklMVEVSX05VTExfT05fRkFJTFVSRTsKICAgICAgICAgICAgICAgIGlmIChkZWZpbmVkKCdGSUxURVJfRkxBR19FTUFJTF9VTklDT0RFJykpIHsKICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGF2YWlsYWJsZSBmcm9tIFBIUCA+PSA3LjEuMCwgc28gaWdub3JlIGl0IGZvciBjb3ZlcmFnZSBjaGVja3MKICAgICAgICAgICAgICAgICAgICAkZmlsdGVyRmxhZ3MgfD0gY29uc3RhbnQoJ0ZJTFRFUl9GTEFHX0VNQUlMX1VOSUNPREUnKTsgLy8gQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IGZpbHRlcl92YXIoJGVsZW1lbnQsIEZJTFRFUl9WQUxJREFURV9FTUFJTCwgJGZpbHRlckZsYWdzKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgZW1haWwnLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2lwLWFkZHJlc3MnOgogICAgICAgICAgICBjYXNlICdpcHY0JzoKICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBmaWx0ZXJfdmFyKCRlbGVtZW50LCBGSUxURVJfVkFMSURBVEVfSVAsIEZJTFRFUl9OVUxMX09OX0ZBSUxVUkUgfCBGSUxURVJfRkxBR19JUFY0KSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ludmFsaWQgSVAgYWRkcmVzcycsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAnaXB2Nic6CiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gZmlsdGVyX3ZhcigkZWxlbWVudCwgRklMVEVSX1ZBTElEQVRFX0lQLCBGSUxURVJfTlVMTF9PTl9GQUlMVVJFIHwgRklMVEVSX0ZMQUdfSVBWNikpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdJbnZhbGlkIElQIGFkZHJlc3MnLCAnZm9ybWF0JywgYXJyYXkoJ2Zvcm1hdCcgPT4gJHNjaGVtYS0+Zm9ybWF0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ2hvc3QtbmFtZSc6CiAgICAgICAgICAgIGNhc2UgJ2hvc3RuYW1lJzoKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlSG9zdG5hbWUoJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSW52YWxpZCBob3N0bmFtZScsICdmb3JtYXQnLCBhcnJheSgnZm9ybWF0JyA9PiAkc2NoZW1hLT5mb3JtYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIEVtcHR5IGFzIGl0IHNob3VsZCBiZToKICAgICAgICAgICAgICAgIC8vIFRoZSB2YWx1ZSBvZiB0aGlzIGtleXdvcmQgaXMgY2FsbGVkIGEgZm9ybWF0IGF0dHJpYnV0ZS4gSXQgTVVTVCBiZSBhIHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIEEgZm9ybWF0IGF0dHJpYnV0ZSBjYW4gZ2VuZXJhbGx5IG9ubHkgdmFsaWRhdGUgYSBnaXZlbiBzZXQgb2YgaW5zdGFuY2UgdHlwZXMuCiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdHlwZSBvZiB0aGUgaW5zdGFuY2UgdG8gdmFsaWRhdGUgaXMgbm90IGluIHRoaXMgc2V0LCB2YWxpZGF0aW9uIGZvcgogICAgICAgICAgICAgICAgLy8gdGhpcyBmb3JtYXQgYXR0cmlidXRlIGFuZCBpbnN0YW5jZSBTSE9VTEQgc3VjY2VlZC4KICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvbGF0ZXN0L2pzb24tc2NoZW1hLXZhbGlkYXRpb24uaHRtbCNhbmNob3IxMDUKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVEYXRlVGltZSgkZGF0ZXRpbWUsICRmb3JtYXQpCiAgICB7CiAgICAgICAgJGR0ID0gXERhdGVUaW1lOjpjcmVhdGVGcm9tRm9ybWF0KCRmb3JtYXQsICRkYXRldGltZSk7CgogICAgICAgIGlmICghJGR0KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICgkZGF0ZXRpbWUgPT09ICRkdC0+Zm9ybWF0KCRmb3JtYXQpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gaGFuZGxlcyB0aGUgY2FzZSB3aGVyZSBhIG5vbi02IGRpZ2l0IG1pY3Jvc2Vjb25kIGRhdGV0aW1lIGlzIHBhc3NlZAogICAgICAgIC8vIHdoaWNoIHdpbGwgZmFpbCB0aGUgYWJvdmUgc3RyaW5nIGNvbXBhcmlzb24gYmVjYXVzZSB0aGUgcGFzc2VkCiAgICAgICAgLy8gJGRhdGV0aW1lIG1heSBiZSAnMjAwMC0wNS0wMVQxMjoxMjoxMi4xMjNaJyBidXQgZm9ybWF0KCkgd2lsbCByZXR1cm4KICAgICAgICAvLyAnMjAwMC0wNS0wMVQxMjoxMjoxMi4xMjMwMDBaJwogICAgICAgIGlmICgoc3RycG9zKCd1JywgJGZvcm1hdCkgIT09IC0xKSAmJiAocHJlZ19tYXRjaCgnL1wuXGQrWiQvJywgJGRhdGV0aW1lKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlUmVnZXgoJHJlZ2V4KQogICAgewogICAgICAgIHJldHVybiBmYWxzZSAhPT0gQHByZWdfbWF0Y2goJy8nIC4gJHJlZ2V4IC4gJy91JywgJycpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZUNvbG9yKCRjb2xvcikKICAgIHsKICAgICAgICBpZiAoaW5fYXJyYXkoc3RydG9sb3dlcigkY29sb3IpLCBhcnJheSgnYXF1YScsICdibGFjaycsICdibHVlJywgJ2Z1Y2hzaWEnLAogICAgICAgICAgICAnZ3JheScsICdncmVlbicsICdsaW1lJywgJ21hcm9vbicsICduYXZ5JywgJ29saXZlJywgJ29yYW5nZScsICdwdXJwbGUnLAogICAgICAgICAgICAncmVkJywgJ3NpbHZlcicsICd0ZWFsJywgJ3doaXRlJywgJ3llbGxvdycpKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwcmVnX21hdGNoKCcvXiMoW2EtZjAtOV17M318W2EtZjAtOV17Nn0pJC9pJywgJGNvbG9yKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVTdHlsZSgkc3R5bGUpCiAgICB7CiAgICAgICAgJHByb3BlcnRpZXMgICAgID0gZXhwbG9kZSgnOycsIHJ0cmltKCRzdHlsZSwgJzsnKSk7CiAgICAgICAgJGludmFsaWRFbnRyaWVzID0gcHJlZ19ncmVwKCcvXlxzKlstYS16XStccyo6XHMqLiskL2knLCAkcHJvcGVydGllcywgUFJFR19HUkVQX0lOVkVSVCk7CgogICAgICAgIHJldHVybiBlbXB0eSgkaW52YWxpZEVudHJpZXMpOwogICAgfQoKICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZVBob25lKCRwaG9uZSkKICAgIHsKICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgnL15cKz8oXChcZHszfVwpfFxkezN9KSBcZHszfSBcZHs0fSQvJywgJHBob25lKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVIb3N0bmFtZSgkaG9zdCkKICAgIHsKICAgICAgICAkaG9zdG5hbWVSZWdleCA9ICcvXigoW2EtekEtWjAtOV18W2EtekEtWjAtOV1bYS16QS1aMC05XC1dKlthLXpBLVowLTldKVwuKSooW0EtWmEtejAtOV18W0EtWmEtejAtOV1bQS1aYS16MC05XC1dKltBLVphLXowLTldKSQvaSc7CgogICAgICAgIHJldHVybiBwcmVnX21hdGNoKCRob3N0bmFtZVJlZ2V4LCAkaG9zdCk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBOdW1iZXJDb25zdHJhaW50IENvbnN0cmFpbnRzLCB2YWxpZGF0ZXMgYW4gbnVtYmVyIGFnYWluc3QgYSBnaXZlbiBzY2hlbWEKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqIEBhdXRob3IgQnJ1bm8gUHJpZXRvIFJlaXMgPGJydW5vLnAucmVpc0BnbWFpbC5jb20+CiAqLwpjbGFzcyBOdW1iZXJDb25zdHJhaW50IGV4dGVuZHMgQ29uc3RyYWludAp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKCYkZWxlbWVudCwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgIC8vIFZlcmlmeSBtaW5pbXVtCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmV4Y2x1c2l2ZU1pbmltdW0pKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5taW5pbXVtKSkgewogICAgICAgICAgICAgICAgaWYgKCRzY2hlbWEtPmV4Y2x1c2l2ZU1pbmltdW0gJiYgJGVsZW1lbnQgPD0gJHNjaGVtYS0+bWluaW11bSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgaGF2ZSBhIG1pbmltdW0gdmFsdWUgb2YgJyAuICRzY2hlbWEtPm1pbmltdW0sICdleGNsdXNpdmVNaW5pbXVtJywgYXJyYXkoJ21pbmltdW0nID0+ICRzY2hlbWEtPm1pbmltdW0pKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkZWxlbWVudCA8ICRzY2hlbWEtPm1pbmltdW0pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtaW5pbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5taW5pbXVtLCAnbWluaW11bScsIGFycmF5KCdtaW5pbXVtJyA9PiAkc2NoZW1hLT5taW5pbXVtKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdVc2Ugb2YgZXhjbHVzaXZlTWluaW11bSByZXF1aXJlcyBwcmVzZW5jZSBvZiBtaW5pbXVtJywgJ21pc3NpbmdNaW5pbXVtJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJHNjaGVtYS0+bWluaW11bSkgJiYgJGVsZW1lbnQgPCAkc2NoZW1hLT5taW5pbXVtKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgaGF2ZSBhIG1pbmltdW0gdmFsdWUgb2YgJyAuICRzY2hlbWEtPm1pbmltdW0sICdtaW5pbXVtJywgYXJyYXkoJ21pbmltdW0nID0+ICRzY2hlbWEtPm1pbmltdW0pKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSBtYXhpbXVtCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmV4Y2x1c2l2ZU1heGltdW0pKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5tYXhpbXVtKSkgewogICAgICAgICAgICAgICAgaWYgKCRzY2hlbWEtPmV4Y2x1c2l2ZU1heGltdW0gJiYgJGVsZW1lbnQgPj0gJHNjaGVtYS0+bWF4aW11bSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgaGF2ZSBhIG1heGltdW0gdmFsdWUgb2YgJyAuICRzY2hlbWEtPm1heGltdW0sICdleGNsdXNpdmVNYXhpbXVtJywgYXJyYXkoJ21heGltdW0nID0+ICRzY2hlbWEtPm1heGltdW0pKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkZWxlbWVudCA+ICRzY2hlbWEtPm1heGltdW0pIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGhhdmUgYSBtYXhpbXVtIHZhbHVlIG9mICcgLiAkc2NoZW1hLT5tYXhpbXVtLCAnbWF4aW11bScsIGFycmF5KCdtYXhpbXVtJyA9PiAkc2NoZW1hLT5tYXhpbXVtKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdVc2Ugb2YgZXhjbHVzaXZlTWF4aW11bSByZXF1aXJlcyBwcmVzZW5jZSBvZiBtYXhpbXVtJywgJ21pc3NpbmdNYXhpbXVtJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJHNjaGVtYS0+bWF4aW11bSkgJiYgJGVsZW1lbnQgPiAkc2NoZW1hLT5tYXhpbXVtKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ011c3QgaGF2ZSBhIG1heGltdW0gdmFsdWUgb2YgJyAuICRzY2hlbWEtPm1heGltdW0sICdtYXhpbXVtJywgYXJyYXkoJ21heGltdW0nID0+ICRzY2hlbWEtPm1heGltdW0pKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSBkaXZpc2libGVCeSAtIERyYWZ0IHYzCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPmRpdmlzaWJsZUJ5KSAmJiAkdGhpcy0+Zm1vZCgkZWxlbWVudCwgJHNjaGVtYS0+ZGl2aXNpYmxlQnkpICE9IDApIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnSXMgbm90IGRpdmlzaWJsZSBieSAnIC4gJHNjaGVtYS0+ZGl2aXNpYmxlQnksICdkaXZpc2libGVCeScsIGFycmF5KCdkaXZpc2libGVCeScgPT4gJHNjaGVtYS0+ZGl2aXNpYmxlQnkpKTsKICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSBtdWx0aXBsZU9mIC0gRHJhZnQgdjQKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bXVsdGlwbGVPZikgJiYgJHRoaXMtPmZtb2QoJGVsZW1lbnQsICRzY2hlbWEtPm11bHRpcGxlT2YpICE9IDApIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBiZSBhIG11bHRpcGxlIG9mICcgLiAkc2NoZW1hLT5tdWx0aXBsZU9mLCAnbXVsdGlwbGVPZicsIGFycmF5KCdtdWx0aXBsZU9mJyA9PiAkc2NoZW1hLT5tdWx0aXBsZU9mKSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+Y2hlY2tGb3JtYXQoJGVsZW1lbnQsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBmbW9kKCRudW1iZXIxLCAkbnVtYmVyMikKICAgIHsKICAgICAgICAkbW9kdWx1cyA9ICgkbnVtYmVyMSAtIHJvdW5kKCRudW1iZXIxIC8gJG51bWJlcjIpICogJG51bWJlcjIpOwogICAgICAgICRwcmVjaXNpb24gPSAwLjAwMDAwMDAwMDE7CgogICAgICAgIGlmICgtJHByZWNpc2lvbiA8ICRtb2R1bHVzICYmICRtb2R1bHVzIDwgJHByZWNpc2lvbikgewogICAgICAgICAgICByZXR1cm4gMC4wOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtb2R1bHVzOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgU3RyaW5nQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIHN0cmluZyBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgU3RyaW5nQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJGVsZW1lbnQsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAvLyBWZXJpZnkgbWF4TGVuZ3RoCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPm1heExlbmd0aCkgJiYgJHRoaXMtPnN0cmxlbigkZWxlbWVudCkgPiAkc2NoZW1hLT5tYXhMZW5ndGgpIHsKICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTXVzdCBiZSBhdCBtb3N0ICcgLiAkc2NoZW1hLT5tYXhMZW5ndGggLiAnIGNoYXJhY3RlcnMgbG9uZycsICdtYXhMZW5ndGgnLCBhcnJheSgKICAgICAgICAgICAgICAgICdtYXhMZW5ndGgnID0+ICRzY2hlbWEtPm1heExlbmd0aCwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAvL3ZlcmlmeSBtaW5MZW5ndGgKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bWluTGVuZ3RoKSAmJiAkdGhpcy0+c3RybGVuKCRlbGVtZW50KSA8ICRzY2hlbWEtPm1pbkxlbmd0aCkgewogICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdNdXN0IGJlIGF0IGxlYXN0ICcgLiAkc2NoZW1hLT5taW5MZW5ndGggLiAnIGNoYXJhY3RlcnMgbG9uZycsICdtaW5MZW5ndGgnLCBhcnJheSgKICAgICAgICAgICAgICAgICdtaW5MZW5ndGgnID0+ICRzY2hlbWEtPm1pbkxlbmd0aCwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgYSByZWdleCBwYXR0ZXJuCiAgICAgICAgaWYgKGlzc2V0KCRzY2hlbWEtPnBhdHRlcm4pICYmICFwcmVnX21hdGNoKCcjJyAuIHN0cl9yZXBsYWNlKCcjJywgJ1xcIycsICRzY2hlbWEtPnBhdHRlcm4pIC4gJyN1JywgJGVsZW1lbnQpKSB7CiAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0RvZXMgbm90IG1hdGNoIHRoZSByZWdleCBwYXR0ZXJuICcgLiAkc2NoZW1hLT5wYXR0ZXJuLCAncGF0dGVybicsIGFycmF5KAogICAgICAgICAgICAgICAgJ3BhdHRlcm4nID0+ICRzY2hlbWEtPnBhdHRlcm4sCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNoZWNrRm9ybWF0KCRlbGVtZW50LCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gc3RybGVuKCRzdHJpbmcpCiAgICB7CiAgICAgICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ21ic3RyaW5nJykpIHsKICAgICAgICAgICAgcmV0dXJuIG1iX3N0cmxlbigkc3RyaW5nLCBtYl9kZXRlY3RfZW5jb2RpbmcoJHN0cmluZykpOwogICAgICAgIH0KCiAgICAgICAgLy8gbWJzdHJpbmcgaXMgcHJlc2VudCBvbiBhbGwgdGVzdCBwbGF0Zm9ybXMsIHNvIHN0cmxlbigpIGNhbiBiZSBpZ25vcmVkIGZvciBjb3ZlcmFnZQogICAgICAgIHJldHVybiBzdHJsZW4oJHN0cmluZyk7IC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxWYWxpZGF0aW9uRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogQSBtb3JlIGJhc2ljIGNvbnN0cmFpbnQgZGVmaW5pdGlvbiAtIHVzZWQgZm9yIHRoZSBwdWJsaWMKICogaW50ZXJmYWNlIHRvIGF2b2lkIGV4cG9zaW5nIGxpYnJhcnkgaW50ZXJuYWxzLgogKi8KY2xhc3MgQmFzZUNvbnN0cmFpbnQKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IEVycm9ycwogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9ycyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIGludCBBbGwgZXJyb3IgdHlwZXMgd2hpY2ggaGF2ZSBvY2N1cnJlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9yTWFzayA9IFZhbGlkYXRvcjo6RVJST1JfTk9ORTsKCiAgICAvKioKICAgICAqIEB2YXIgRmFjdG9yeQogICAgICovCiAgICBwcm90ZWN0ZWQgJGZhY3Rvcnk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gRmFjdG9yeSAkZmFjdG9yeQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoRmFjdG9yeSAkZmFjdG9yeSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmZhY3RvcnkgPSAkZmFjdG9yeSA/OiBuZXcgRmFjdG9yeSgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFcnJvcihKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRtZXNzYWdlLCAkY29uc3RyYWludCA9ICcnLCBhcnJheSAkbW9yZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGVycm9yID0gYXJyYXkoCiAgICAgICAgICAgICdwcm9wZXJ0eScgPT4gJHRoaXMtPmNvbnZlcnRKc29uUG9pbnRlckludG9Qcm9wZXJ0eVBhdGgoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSksCiAgICAgICAgICAgICdwb2ludGVyJyA9PiBsdHJpbShzdHJ2YWwoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSksICcjJyksCiAgICAgICAgICAgICdtZXNzYWdlJyA9PiAkbWVzc2FnZSwKICAgICAgICAgICAgJ2NvbnN0cmFpbnQnID0+ICRjb25zdHJhaW50LAogICAgICAgICAgICAnY29udGV4dCcgPT4gJHRoaXMtPmZhY3RvcnktPmdldEVycm9yQ29udGV4dCgpLAogICAgICAgICk7CgogICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKENvbnN0cmFpbnQ6OkNIRUNLX01PREVfRVhDRVBUSU9OUykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FeGNlcHRpb24oc3ByaW50ZignRXJyb3IgdmFsaWRhdGluZyAlczogJXMnLCAkZXJyb3JbJ3BvaW50ZXInXSwgJGVycm9yWydtZXNzYWdlJ10pKTsKICAgICAgICB9CgogICAgICAgIGlmIChpc19hcnJheSgkbW9yZSkgJiYgY291bnQoJG1vcmUpID4gMCkgewogICAgICAgICAgICAkZXJyb3IgKz0gJG1vcmU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+ZXJyb3JzW10gPSAkZXJyb3I7CiAgICAgICAgJHRoaXMtPmVycm9yTWFzayB8PSAkZXJyb3JbJ2NvbnRleHQnXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRXJyb3JzKGFycmF5ICRlcnJvcnMpCiAgICB7CiAgICAgICAgaWYgKCRlcnJvcnMpIHsKICAgICAgICAgICAgJHRoaXMtPmVycm9ycyA9IGFycmF5X21lcmdlKCR0aGlzLT5lcnJvcnMsICRlcnJvcnMpOwogICAgICAgICAgICAkZXJyb3JNYXNrID0gJiR0aGlzLT5lcnJvck1hc2s7CiAgICAgICAgICAgIGFycmF5X3dhbGsoJGVycm9ycywgZnVuY3Rpb24gKCRlcnJvcikgdXNlICgmJGVycm9yTWFzaykgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRlcnJvclsnY29udGV4dCddKSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvck1hc2sgfD0gJGVycm9yWydjb250ZXh0J107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXJyb3JzKCRlcnJvckNvbnRleHQgPSBWYWxpZGF0b3I6OkVSUk9SX0FMTCkKICAgIHsKICAgICAgICBpZiAoJGVycm9yQ29udGV4dCA9PT0gVmFsaWRhdG9yOjpFUlJPUl9BTEwpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcnM7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXJyYXlfZmlsdGVyKCR0aGlzLT5lcnJvcnMsIGZ1bmN0aW9uICgkZXJyb3IpIHVzZSAoJGVycm9yQ29udGV4dCkgewogICAgICAgICAgICBpZiAoJGVycm9yQ29udGV4dCAmICRlcnJvclsnY29udGV4dCddKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBudW1FcnJvcnMoJGVycm9yQ29udGV4dCA9IFZhbGlkYXRvcjo6RVJST1JfQUxMKQogICAgewogICAgICAgIGlmICgkZXJyb3JDb250ZXh0ID09PSBWYWxpZGF0b3I6OkVSUk9SX0FMTCkgewogICAgICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmVycm9ycyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmdldEVycm9ycygkZXJyb3JDb250ZXh0KSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGlzVmFsaWQoKQogICAgewogICAgICAgIHJldHVybiAhJHRoaXMtPmdldEVycm9ycygpOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXJzIGFueSByZXBvcnRlZCBlcnJvcnMuICBTaG91bGQgYmUgdXNlZCBiZXR3ZWVuCiAgICAgKiBtdWx0aXBsZSB2YWxpZGF0aW9uIGNoZWNrcy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc2V0KCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+ZXJyb3JNYXNrID0gVmFsaWRhdG9yOjpFUlJPUl9OT05FOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBlcnJvciBtYXNrCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yTWFzaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvck1hc2s7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSBjYXN0IGFuIGFzc29jaWF0aXZlIGFycmF5IHRvIGFuIG9iamVjdAogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFycmF5VG9PYmplY3RSZWN1cnNpdmUoJGFycmF5KQogICAgewogICAgICAgICRqc29uID0ganNvbl9lbmNvZGUoJGFycmF5KTsKICAgICAgICBpZiAoanNvbl9sYXN0X2Vycm9yKCkgIT09IFxKU09OX0VSUk9SX05PTkUpIHsKICAgICAgICAgICAgJG1lc3NhZ2UgPSAnVW5hYmxlIHRvIGVuY29kZSBzY2hlbWEgYXJyYXkgYXMgSlNPTic7CiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2pzb25fbGFzdF9lcnJvcl9tc2cnKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJzogJyAuIGpzb25fbGFzdF9lcnJvcl9tc2coKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCRtZXNzYWdlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAob2JqZWN0KSBqc29uX2RlY29kZSgkanNvbik7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBDb25zdHJhaW50cyBJbnRlcmZhY2UKICoKICogQGF1dGhvciBSb2JlcnQgU2Now7ZudGhhbCA8c2Vyb3NjaG9AZ29vZ2xlbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgQ29uc3RyYWludEludGVyZmFjZQp7CiAgICAvKioKICAgICAqIHJldHVybnMgYWxsIGNvbGxlY3RlZCBlcnJvcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFcnJvcnMoKTsKCiAgICAvKioKICAgICAqIGFkZHMgZXJyb3JzIHRvIHRoaXMgdmFsaWRhdG9yCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRlcnJvcnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEVycm9ycyhhcnJheSAkZXJyb3JzKTsKCiAgICAvKioKICAgICAqIGFkZHMgYW4gZXJyb3IKICAgICAqCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJG1lc3NhZ2UKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRjb25zdHJhaW50IHRoZSBjb25zdHJhaW50L3J1bGUgdGhhdCBpcyBicm9rZW4sIGUuZy46ICdtaW5MZW5ndGgnCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAgICAkbW9yZSAgICAgICBtb3JlIGFycmF5IGVsZW1lbnRzIHRvIGFkZCB0byB0aGUgZXJyb3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEVycm9yKEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJG1lc3NhZ2UsICRjb25zdHJhaW50PScnLCBhcnJheSAkbW9yZSA9IG51bGwpOwoKICAgIC8qKgogICAgICogY2hlY2tzIGlmIHRoZSB2YWxpZGF0b3IgaGFzIG5vdCByYWlzZWQgZXJyb3JzCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1ZhbGlkKCk7CgogICAgLyoqCiAgICAgKiBpbnZva2VzIHRoZSB2YWxpZGF0aW9uIG9mIGFuIGVsZW1lbnQKICAgICAqCiAgICAgKiBAYWJzdHJhY3QKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICoKICAgICAqIEB0aHJvd3MgXEpzb25TY2hlbWFcRXhjZXB0aW9uXEV4Y2VwdGlvbkludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKTsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xUeXBlQ2hlY2tcTG9vc2VUeXBlQ2hlY2s7CnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXFZhbGlkYXRpb25FeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXFVyaVxVcmlSZXNvbHZlcjsKCi8qKgogKiBUaGUgVW5kZWZpbmVkQ29uc3RyYWludCBDb25zdHJhaW50cwogKgogKiBAYXV0aG9yIFJvYmVydCBTY2jDtm50aGFsIDxzZXJvc2Nob0Bnb29nbGVtYWlsLmNvbT4KICogQGF1dGhvciBCcnVubyBQcmlldG8gUmVpcyA8YnJ1bm8ucC5yZWlzQGdtYWlsLmNvbT4KICovCmNsYXNzIFVuZGVmaW5lZENvbnN0cmFpbnQgZXh0ZW5kcyBDb25zdHJhaW50CnsKICAgIC8qKgogICAgICogQHZhciBhcnJheSBMaXN0IG9mIHByb3BlcnRpZXMgdG8gd2hpY2ggYSBkZWZhdWx0IHZhbHVlIGhhcyBiZWVuIGFwcGxpZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRhcHBsaWVkRGVmYXVsdHMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsLCAkZnJvbURlZmF1bHQgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoaXNfbnVsbCgkc2NoZW1hKSB8fCAhaXNfb2JqZWN0KCRzY2hlbWEpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRwYXRoID0gJHRoaXMtPmluY3JlbWVudFBhdGgoJHBhdGggPzogbmV3IEpzb25Qb2ludGVyKCcnKSwgJGkpOwogICAgICAgIGlmICgkZnJvbURlZmF1bHQpIHsKICAgICAgICAgICAgJHBhdGgtPnNldEZyb21EZWZhdWx0KCk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBzcGVjaWFsIHByb3BlcnRpZXMKICAgICAgICAkdGhpcy0+dmFsaWRhdGVDb21tb25Qcm9wZXJ0aWVzKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKCiAgICAgICAgLy8gY2hlY2sgYWxsT2YsIGFueU9mLCBhbmQgb25lT2YgcHJvcGVydGllcwogICAgICAgICR0aGlzLT52YWxpZGF0ZU9mUHJvcGVydGllcygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAnJyk7CgogICAgICAgIC8vIGNoZWNrIGtub3duIHR5cGVzCiAgICAgICAgJHRoaXMtPnZhbGlkYXRlVHlwZXMoJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBhZ2FpbnN0IHRoZSB0eXBlcwogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXIgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkaQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmFsaWRhdGVUeXBlcygmJHZhbHVlLCAkc2NoZW1hLCBKc29uUG9pbnRlciAkcGF0aCwgJGkgPSBudWxsKQogICAgewogICAgICAgIC8vIGNoZWNrIGFycmF5CiAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNBcnJheSgkdmFsdWUpKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0FycmF5KCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIG9iamVjdAogICAgICAgIGlmIChMb29zZVR5cGVDaGVjazo6aXNPYmplY3QoJHZhbHVlKSkgeyAvLyBvYmplY3QgcHJvY2Vzc2luZyBzaG91bGQgYWx3YXlzIGJlIHJ1biBvbiBhc3NvYyBhcnJheXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvIHVzZSBMb29zZVR5cGVDaGVjayBoZXJlIGV2ZW4gaWYgQ0hFQ0tfTU9ERV9UWVBFX0NBU1QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgbm90IHNldCAoaS5lLiBkb24ndCB1c2UgJHRoaXMtPmdldFR5cGVDaGVjaygpIGhlcmUpLgogICAgICAgICAgICAkdGhpcy0+Y2hlY2tPYmplY3QoCiAgICAgICAgICAgICAgICAkdmFsdWUsCiAgICAgICAgICAgICAgICAkc2NoZW1hLAogICAgICAgICAgICAgICAgJHBhdGgsCiAgICAgICAgICAgICAgICBpc3NldCgkc2NoZW1hLT5wcm9wZXJ0aWVzKSA/ICRzY2hlbWEtPnByb3BlcnRpZXMgOiBudWxsLAogICAgICAgICAgICAgICAgaXNzZXQoJHNjaGVtYS0+YWRkaXRpb25hbFByb3BlcnRpZXMpID8gJHNjaGVtYS0+YWRkaXRpb25hbFByb3BlcnRpZXMgOiBudWxsLAogICAgICAgICAgICAgICAgaXNzZXQoJHNjaGVtYS0+cGF0dGVyblByb3BlcnRpZXMpID8gJHNjaGVtYS0+cGF0dGVyblByb3BlcnRpZXMgOiBudWxsLAogICAgICAgICAgICAgICAgJHRoaXMtPmFwcGxpZWREZWZhdWx0cwogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgc3RyaW5nCiAgICAgICAgaWYgKGlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja1N0cmluZygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBudW1lcmljCiAgICAgICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tOdW1iZXIoJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2hlY2sgZW51bQogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5lbnVtKSkgewogICAgICAgICAgICAkdGhpcy0+Y2hlY2tFbnVtKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZXMgY29tbW9uIHByb3BlcnRpZXMKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyICRwYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlQ29tbW9uUHJvcGVydGllcygmJHZhbHVlLCAkc2NoZW1hLCBKc29uUG9pbnRlciAkcGF0aCwgJGkgPSAnJykKICAgIHsKICAgICAgICAvLyBpZiBpdCBleHRlbmRzIGFub3RoZXIgc2NoZW1hLCBpdCBtdXN0IHBhc3MgdGhhdCBzY2hlbWEgYXMgd2VsbAogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5leHRlbmRzKSkgewogICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRzY2hlbWEtPmV4dGVuZHMpKSB7CiAgICAgICAgICAgICAgICAkc2NoZW1hLT5leHRlbmRzID0gJHRoaXMtPnZhbGlkYXRlVXJpKCRzY2hlbWEsICRzY2hlbWEtPmV4dGVuZHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkc2NoZW1hLT5leHRlbmRzKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+ZXh0ZW5kcyBhcyAkZXh0ZW5kcykgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdmFsdWUsICRleHRlbmRzLCAkcGF0aCwgJGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJHNjaGVtYS0+ZXh0ZW5kcywgJHBhdGgsICRpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQXBwbHkgZGVmYXVsdCB2YWx1ZXMgZnJvbSBzY2hlbWEKICAgICAgICBpZiAoISRwYXRoLT5mcm9tRGVmYXVsdCgpKSB7CiAgICAgICAgICAgICR0aGlzLT5hcHBseURlZmF1bHRWYWx1ZXMoJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgcmVxdWlyZWQgdmFsdWVzCiAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNPYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICBpZiAoISgkdmFsdWUgaW5zdGFuY2VvZiBzZWxmKSAmJiBpc3NldCgkc2NoZW1hLT5yZXF1aXJlZCkgJiYgaXNfYXJyYXkoJHNjaGVtYS0+cmVxdWlyZWQpKSB7CiAgICAgICAgICAgICAgICAvLyBEcmFmdCA0IC0gUmVxdWlyZWQgaXMgYW4gYXJyYXkgb2Ygc3RyaW5ncyAtIGUuZy4gInJlcXVpcmVkIjogWyJmb28iLCAuLi5dCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkc2NoZW1hLT5yZXF1aXJlZCBhcyAkcmVxdWlyZWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJHZhbHVlLCAkcmVxdWlyZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmNyZW1lbnRQYXRoKCRwYXRoID86IG5ldyBKc29uUG9pbnRlcignJyksICRyZXF1aXJlZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHByb3BlcnR5ICcgLiAkcmVxdWlyZWQgLiAnIGlzIHJlcXVpcmVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZXF1aXJlZCcKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkc2NoZW1hLT5yZXF1aXJlZCkgJiYgIWlzX2FycmF5KCRzY2hlbWEtPnJlcXVpcmVkKSkgewogICAgICAgICAgICAgICAgLy8gRHJhZnQgMyAtIFJlcXVpcmVkIGF0dHJpYnV0ZSAtIGUuZy4gImZvbyI6IHsidHlwZSI6ICJzdHJpbmciLCAicmVxdWlyZWQiOiB0cnVlfQogICAgICAgICAgICAgICAgaWYgKCRzY2hlbWEtPnJlcXVpcmVkICYmICR2YWx1ZSBpbnN0YW5jZW9mIHNlbGYpIHsKICAgICAgICAgICAgICAgICAgICAkcHJvcGVydHlQYXRocyA9ICRwYXRoLT5nZXRQcm9wZXJ0eVBhdGhzKCk7CiAgICAgICAgICAgICAgICAgICAgJHByb3BlcnR5TmFtZSA9IGVuZCgkcHJvcGVydHlQYXRocyk7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAkcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgJ1RoZSBwcm9wZXJ0eSAnIC4gJHByb3BlcnR5TmFtZSAuICcgaXMgcmVxdWlyZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAncmVxdWlyZWQnCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB2YWx1ZSBpcyBib3RoIHVuZGVmaW5lZCBhbmQgbm90IHJlcXVpcmVkLCBza2lwIHJlbWFpbmluZyBjaGVja3MKICAgICAgICAgICAgICAgIC8vIGluIHRoaXMgbWV0aG9kIHdoaWNoIGFzc3VtZSBhbiBhY3R1YWwsIGRlZmluZWQgaW5zdGFuY2Ugd2hlbiB2YWxpZGF0aW5nLgogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZSBpbnN0YW5jZW9mIHNlbGYpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSB0eXBlCiAgICAgICAgaWYgKCEoJHZhbHVlIGluc3RhbmNlb2Ygc2VsZikpIHsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVHlwZSgkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgZGlzYWxsb3dlZCBpdGVtcwogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5kaXNhbGxvdykpIHsKICAgICAgICAgICAgJGluaXRFcnJvcnMgPSAkdGhpcy0+Z2V0RXJyb3JzKCk7CgogICAgICAgICAgICAkdHlwZVNjaGVtYSA9IG5ldyBcc3RkQ2xhc3MoKTsKICAgICAgICAgICAgJHR5cGVTY2hlbWEtPnR5cGUgPSAkc2NoZW1hLT5kaXNhbGxvdzsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVHlwZSgkdmFsdWUsICR0eXBlU2NoZW1hLCAkcGF0aCk7CgogICAgICAgICAgICAvLyBpZiBubyBuZXcgZXJyb3JzIHdlcmUgcmFpc2VkIGl0IG11c3QgYmUgYSBkaXNhbGxvd2VkIHZhbHVlCiAgICAgICAgICAgIGlmIChjb3VudCgkdGhpcy0+Z2V0RXJyb3JzKCkpID09IGNvdW50KCRpbml0RXJyb3JzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnRGlzYWxsb3dlZCB2YWx1ZSB3YXMgbWF0Y2hlZCcsICdkaXNhbGxvdycpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9ycyA9ICRpbml0RXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+bm90KSkgewogICAgICAgICAgICAkaW5pdEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJHNjaGVtYS0+bm90LCAkcGF0aCwgJGkpOwoKICAgICAgICAgICAgLy8gaWYgbm8gbmV3IGVycm9ycyB3ZXJlIHJhaXNlZCB0aGVuIHRoZSBpbnN0YW5jZSB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgIm5vdCIgc2NoZW1hCiAgICAgICAgICAgIGlmIChjb3VudCgkdGhpcy0+Z2V0RXJyb3JzKCkpID09IGNvdW50KCRpbml0RXJyb3JzKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnTWF0Y2hlZCBhIHNjaGVtYSB3aGljaCBpdCBzaG91bGQgbm90JywgJ25vdCcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmVycm9ycyA9ICRpbml0RXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdGhhdCBkZXBlbmRlbmNpZXMgYXJlIG1ldAogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5kZXBlbmRlbmNpZXMpICYmICR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNPYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVEZXBlbmRlbmNpZXMoJHZhbHVlLCAkc2NoZW1hLT5kZXBlbmRlbmNpZXMsICRwYXRoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIGEgZGVmYXVsdCBzaG91bGQgYmUgYXBwbGllZCBmb3IgdGhpcyB2YWx1ZQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkc2NoZW1hCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHBhcmVudFNjaGVtYQogICAgICogQHBhcmFtIGJvb2wgICRyZXF1aXJlZE9ubHkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBzaG91bGRBcHBseURlZmF1bHRWYWx1ZSgkcmVxdWlyZWRPbmx5LCAkc2NoZW1hLCAkbmFtZSA9IG51bGwsICRwYXJlbnRTY2hlbWEgPSBudWxsKQogICAgewogICAgICAgIC8vIHJlcXVpcmVkLW9ubHkgbW9kZSBpcyBvZmYKICAgICAgICBpZiAoISRyZXF1aXJlZE9ubHkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIC8vIGRyYWZ0LTA0IHJlcXVpcmVkIGlzIHNldAogICAgICAgIGlmICgKICAgICAgICAgICAgJG5hbWUgIT09IG51bGwKICAgICAgICAgICAgJiYgaXNzZXQoJHBhcmVudFNjaGVtYS0+cmVxdWlyZWQpCiAgICAgICAgICAgICYmIGlzX2FycmF5KCRwYXJlbnRTY2hlbWEtPnJlcXVpcmVkKQogICAgICAgICAgICAmJiBpbl9hcnJheSgkbmFtZSwgJHBhcmVudFNjaGVtYS0+cmVxdWlyZWQpCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICAvLyBkcmFmdC0wMyByZXF1aXJlZCBpcyBzZXQKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+cmVxdWlyZWQpICYmICFpc19hcnJheSgkc2NoZW1hLT5yZXF1aXJlZCkgJiYgJHNjaGVtYS0+cmVxdWlyZWQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIC8vIGRlZmF1bHQgY2FzZQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGx5IGRlZmF1bHQgdmFsdWVzCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcGF0aAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXBwbHlEZWZhdWx0VmFsdWVzKCYkdmFsdWUsICRzY2hlbWEsICRwYXRoKQogICAgewogICAgICAgIC8vIG9ubHkgYXBwbHkgZGVmYXVsdHMgaWYgZmVhdHVyZSBpcyBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfQVBQTFlfREVGQVVMVFMpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGx5IGRlZmF1bHRzIGlmIGFwcHJvcHJpYXRlCiAgICAgICAgJHJlcXVpcmVkT25seSA9ICR0aGlzLT5mYWN0b3J5LT5nZXRDb25maWcoc2VsZjo6Q0hFQ0tfTU9ERV9PTkxZX1JFUVVJUkVEX0RFRkFVTFRTKTsKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+cHJvcGVydGllcykgJiYgTG9vc2VUeXBlQ2hlY2s6OmlzT2JqZWN0KCR2YWx1ZSkpIHsKICAgICAgICAgICAgLy8gJHZhbHVlIGlzIGFuIG9iamVjdCBvciBhc3NvYyBhcnJheSwgYW5kIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgLSB0cmVhdCBhcyBhbiBvYmplY3QKICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+cHJvcGVydGllcyBhcyAkY3VycmVudFByb3BlcnR5ID0+ICRwcm9wZXJ0eURlZmluaXRpb24pIHsKICAgICAgICAgICAgICAgICRwcm9wZXJ0eURlZmluaXRpb24gPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0U2NoZW1hU3RvcmFnZSgpLT5yZXNvbHZlUmVmU2NoZW1hKCRwcm9wZXJ0eURlZmluaXRpb24pOwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICFMb29zZVR5cGVDaGVjazo6cHJvcGVydHlFeGlzdHMoJHZhbHVlLCAkY3VycmVudFByb3BlcnR5KQogICAgICAgICAgICAgICAgICAgICYmIHByb3BlcnR5X2V4aXN0cygkcHJvcGVydHlEZWZpbml0aW9uLCAnZGVmYXVsdCcpCiAgICAgICAgICAgICAgICAgICAgJiYgJHRoaXMtPnNob3VsZEFwcGx5RGVmYXVsdFZhbHVlKCRyZXF1aXJlZE9ubHksICRwcm9wZXJ0eURlZmluaXRpb24sICRjdXJyZW50UHJvcGVydHksICRzY2hlbWEpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAvLyBhc3NpZ24gZGVmYXVsdCB2YWx1ZQogICAgICAgICAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHByb3BlcnR5RGVmaW5pdGlvbi0+ZGVmYXVsdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTG9vc2VUeXBlQ2hlY2s6OnByb3BlcnR5U2V0KCR2YWx1ZSwgJGN1cnJlbnRQcm9wZXJ0eSwgY2xvbmUgJHByb3BlcnR5RGVmaW5pdGlvbi0+ZGVmYXVsdCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgTG9vc2VUeXBlQ2hlY2s6OnByb3BlcnR5U2V0KCR2YWx1ZSwgJGN1cnJlbnRQcm9wZXJ0eSwgJHByb3BlcnR5RGVmaW5pdGlvbi0+ZGVmYXVsdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hcHBsaWVkRGVmYXVsdHNbXSA9ICRjdXJyZW50UHJvcGVydHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoaXNzZXQoJHNjaGVtYS0+aXRlbXMpICYmIExvb3NlVHlwZUNoZWNrOjppc0FycmF5KCR2YWx1ZSkpIHsKICAgICAgICAgICAgJGl0ZW1zID0gYXJyYXkoKTsKICAgICAgICAgICAgaWYgKExvb3NlVHlwZUNoZWNrOjppc0FycmF5KCRzY2hlbWEtPml0ZW1zKSkgewogICAgICAgICAgICAgICAgJGl0ZW1zID0gJHNjaGVtYS0+aXRlbXM7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc3NldCgkc2NoZW1hLT5taW5JdGVtcykgJiYgY291bnQoJHZhbHVlKSA8ICRzY2hlbWEtPm1pbkl0ZW1zKSB7CiAgICAgICAgICAgICAgICAkaXRlbXMgPSBhcnJheV9maWxsKGNvdW50KCR2YWx1ZSksICRzY2hlbWEtPm1pbkl0ZW1zIC0gY291bnQoJHZhbHVlKSwgJHNjaGVtYS0+aXRlbXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vICR2YWx1ZSBpcyBhbiBhcnJheSwgYW5kIGl0ZW1zIGFyZSBkZWZpbmVkIC0gdHJlYXQgYXMgcGxhaW4gYXJyYXkKICAgICAgICAgICAgZm9yZWFjaCAoJGl0ZW1zIGFzICRjdXJyZW50SXRlbSA9PiAkaXRlbURlZmluaXRpb24pIHsKICAgICAgICAgICAgICAgICRpdGVtRGVmaW5pdGlvbiA9ICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCktPnJlc29sdmVSZWZTY2hlbWEoJGl0ZW1EZWZpbml0aW9uKTsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAhYXJyYXlfa2V5X2V4aXN0cygkY3VycmVudEl0ZW0sICR2YWx1ZSkKICAgICAgICAgICAgICAgICAgICAmJiBwcm9wZXJ0eV9leGlzdHMoJGl0ZW1EZWZpbml0aW9uLCAnZGVmYXVsdCcpCiAgICAgICAgICAgICAgICAgICAgJiYgJHRoaXMtPnNob3VsZEFwcGx5RGVmYXVsdFZhbHVlKCRyZXF1aXJlZE9ubHksICRpdGVtRGVmaW5pdGlvbikpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRpdGVtRGVmaW5pdGlvbi0+ZGVmYXVsdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlWyRjdXJyZW50SXRlbV0gPSBjbG9uZSAkaXRlbURlZmluaXRpb24tPmRlZmF1bHQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhbHVlWyRjdXJyZW50SXRlbV0gPSAkaXRlbURlZmluaXRpb24tPmRlZmF1bHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhdGgtPnNldEZyb21EZWZhdWx0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICR2YWx1ZSBpbnN0YW5jZW9mIHNlbGYKICAgICAgICAgICAgJiYgcHJvcGVydHlfZXhpc3RzKCRzY2hlbWEsICdkZWZhdWx0JykKICAgICAgICAgICAgJiYgJHRoaXMtPnNob3VsZEFwcGx5RGVmYXVsdFZhbHVlKCRyZXF1aXJlZE9ubHksICRzY2hlbWEpKSB7CiAgICAgICAgICAgIC8vICR2YWx1ZSBpcyBhIGxlYWYsIG5vdCBhIGNvbnRhaW5lciAtIGFwcGx5IHRoZSBkZWZhdWx0IGRpcmVjdGx5CiAgICAgICAgICAgICR2YWx1ZSA9IGlzX29iamVjdCgkc2NoZW1hLT5kZWZhdWx0KSA/IGNsb25lICRzY2hlbWEtPmRlZmF1bHQgOiAkc2NoZW1hLT5kZWZhdWx0OwogICAgICAgICAgICAkcGF0aC0+c2V0RnJvbURlZmF1bHQoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWYWxpZGF0ZSBhbGxPZiwgYW55T2YsIGFuZCBvbmVPZiBwcm9wZXJ0aWVzCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZU9mUHJvcGVydGllcygmJHZhbHVlLCAkc2NoZW1hLCBKc29uUG9pbnRlciAkcGF0aCwgJGkgPSAnJykKICAgIHsKICAgICAgICAvLyBWZXJpZnkgdHlwZQogICAgICAgIGlmICgkdmFsdWUgaW5zdGFuY2VvZiBzZWxmKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkc2NoZW1hLT5hbGxPZikpIHsKICAgICAgICAgICAgJGlzVmFsaWQgPSB0cnVlOwogICAgICAgICAgICBmb3JlYWNoICgkc2NoZW1hLT5hbGxPZiBhcyAkYWxsT2YpIHsKICAgICAgICAgICAgICAgICRpbml0RXJyb3JzID0gJHRoaXMtPmdldEVycm9ycygpOwogICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJGFsbE9mLCAkcGF0aCwgJGkpOwogICAgICAgICAgICAgICAgJGlzVmFsaWQgPSAkaXNWYWxpZCAmJiAoY291bnQoJHRoaXMtPmdldEVycm9ycygpKSA9PSBjb3VudCgkaW5pdEVycm9ycykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGlzVmFsaWQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ZhaWxlZCB0byBtYXRjaCBhbGwgc2NoZW1hcycsICdhbGxPZicpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+YW55T2YpKSB7CiAgICAgICAgICAgICRpc1ZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICRzdGFydEVycm9ycyA9ICR0aGlzLT5nZXRFcnJvcnMoKTsKICAgICAgICAgICAgJGNhdWdodEV4Y2VwdGlvbiA9IG51bGw7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzY2hlbWEtPmFueU9mIGFzICRhbnlPZikgewogICAgICAgICAgICAgICAgJGluaXRFcnJvcnMgPSAkdGhpcy0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdmFsdWUsICRhbnlPZiwgJHBhdGgsICRpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGlzVmFsaWQgPSAoY291bnQoJHRoaXMtPmdldEVycm9ycygpKSA9PSBjb3VudCgkaW5pdEVycm9ycykpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAkaXNWYWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGlzVmFsaWQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ0ZhaWxlZCB0byBtYXRjaCBhdCBsZWFzdCBvbmUgc2NoZW1hJywgJ2FueU9mJyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJHN0YXJ0RXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHNjaGVtYS0+b25lT2YpKSB7CiAgICAgICAgICAgICRhbGxFcnJvcnMgPSBhcnJheSgpOwogICAgICAgICAgICAkbWF0Y2hlZFNjaGVtYXMgPSAwOwogICAgICAgICAgICAkc3RhcnRFcnJvcnMgPSAkdGhpcy0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRzY2hlbWEtPm9uZU9mIGFzICRvbmVPZikgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJHZhbHVlLCAkb25lT2YsICRwYXRoLCAkaSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50KCR0aGlzLT5nZXRFcnJvcnMoKSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF0Y2hlZFNjaGVtYXMrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGFsbEVycm9ycyA9IGFycmF5X21lcmdlKCRhbGxFcnJvcnMsIGFycmF5X3ZhbHVlcygkdGhpcy0+Z2V0RXJyb3JzKCkpKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFZhbGlkYXRpb25FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBkZWxpYmVyYXRlbHkgZG8gbm90aGluZyBoZXJlIC0gdmFsaWRhdGlvbiBmYWlsZWQsIGJ1dCB3ZSB3YW50IHRvIGNoZWNrCiAgICAgICAgICAgICAgICAgICAgLy8gb3RoZXIgc2NoZW1hIG9wdGlvbnMgaW4gdGhlIE9uZU9mIGZpZWxkLgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkbWF0Y2hlZFNjaGVtYXMgIT09IDEpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcnMoYXJyYXlfbWVyZ2UoJGFsbEVycm9ycywgJHN0YXJ0RXJyb3JzKSk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICdGYWlsZWQgdG8gbWF0Y2ggZXhhY3RseSBvbmUgc2NoZW1hJywgJ29uZU9mJyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZXJyb3JzID0gJHN0YXJ0RXJyb3JzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGUgZGVwZW5kZW5jaWVzCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICRkZXBlbmRlbmNpZXMKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlciAkcGF0aAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB2YWxpZGF0ZURlcGVuZGVuY2llcygkdmFsdWUsICRkZXBlbmRlbmNpZXMsIEpzb25Qb2ludGVyICRwYXRoLCAkaSA9ICcnKQogICAgewogICAgICAgIGZvcmVhY2ggKCRkZXBlbmRlbmNpZXMgYXMgJGtleSA9PiAkZGVwZW5kZW5jeSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRrZXkpKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNfc3RyaW5nKCRkZXBlbmRlbmN5KSkgewogICAgICAgICAgICAgICAgICAgIC8vIERyYWZ0IDMgc3RyaW5nIGlzIGFsbG93ZWQgLSBlLmcuICJkZXBlbmRlbmNpZXMiOiB7ImJhciI6ICJmb28ifQogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUV4aXN0cygkdmFsdWUsICRkZXBlbmRlbmN5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRkRXJyb3IoJHBhdGgsICIka2V5IGRlcGVuZHMgb24gJGRlcGVuZGVuY3kgYW5kICRkZXBlbmRlbmN5IGlzIG1pc3NpbmciLCAnZGVwZW5kZW5jaWVzJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2FycmF5KCRkZXBlbmRlbmN5KSkgewogICAgICAgICAgICAgICAgICAgIC8vIERyYWZ0IDQgbXVzdCBiZSBhbiBhcnJheSAtIGUuZy4gImRlcGVuZGVuY2llcyI6IHsiYmFyIjogWyJmb28iXX0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZGVwZW5kZW5jeSBhcyAkZCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJHZhbHVlLCAkZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgIiRrZXkgZGVwZW5kcyBvbiAkZCBhbmQgJGQgaXMgbWlzc2luZyIsICdkZXBlbmRlbmNpZXMnKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19vYmplY3QoJGRlcGVuZGVuY3kpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU2NoZW1hIC0gZS5nLiAiZGVwZW5kZW5jaWVzIjogeyJiYXIiOiB7InByb3BlcnRpZXMiOiB7ImZvbyI6IHsuLi59fX19CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrVW5kZWZpbmVkKCR2YWx1ZSwgJGRlcGVuZGVuY3ksICRwYXRoLCAkaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlVXJpKCRzY2hlbWEsICRzY2hlbWFVcmkgPSBudWxsKQogICAgewogICAgICAgICRyZXNvbHZlciA9IG5ldyBVcmlSZXNvbHZlcigpOwogICAgICAgICRyZXRyaWV2ZXIgPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0VXJpUmV0cmlldmVyKCk7CgogICAgICAgICRqc29uU2NoZW1hID0gbnVsbDsKICAgICAgICBpZiAoJHJlc29sdmVyLT5pc1ZhbGlkKCRzY2hlbWFVcmkpKSB7CiAgICAgICAgICAgICRzY2hlbWFJZCA9IHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSA/ICRzY2hlbWEtPmlkIDogbnVsbDsKICAgICAgICAgICAgJGpzb25TY2hlbWEgPSAkcmV0cmlldmVyLT5yZXRyaWV2ZSgkc2NoZW1hSWQsICRzY2hlbWFVcmkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uU2NoZW1hOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbiBhcyBTdGFuZGFyZFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbjsKCi8qKgogKiBUaGUgVHlwZUNvbnN0cmFpbnQgQ29uc3RyYWludHMsIHZhbGlkYXRlcyBhbiBlbGVtZW50IGFnYWluc3QgYSBnaXZlbiB0eXBlCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgVHlwZUNvbnN0cmFpbnQgZXh0ZW5kcyBDb25zdHJhaW50CnsKICAgIC8qKgogICAgICogQHZhciBhcnJheXxzdHJpbmdbXSB0eXBlIHdvcmRpbmdzIGZvciB2YWxpZGF0aW9uIGVycm9yIG1lc3NhZ2VzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgJHdvcmRpbmcgPSBhcnJheSgKICAgICAgICAnaW50ZWdlcicgPT4gJ2FuIGludGVnZXInLAogICAgICAgICdudW1iZXInICA9PiAnYSBudW1iZXInLAogICAgICAgICdib29sZWFuJyA9PiAnYSBib29sZWFuJywKICAgICAgICAnb2JqZWN0JyAgPT4gJ2FuIG9iamVjdCcsCiAgICAgICAgJ2FycmF5JyAgID0+ICdhbiBhcnJheScsCiAgICAgICAgJ3N0cmluZycgID0+ICdhIHN0cmluZycsCiAgICAgICAgJ251bGwnICAgID0+ICdhIG51bGwnLAogICAgICAgICdhbnknICAgICA9PiBudWxsLCAvLyB2YWxpZGF0aW9uIG9mICdhbnknIGlzIGFsd2F5cyB0cnVlIHNvIGlzIG5vdCBuZWVkZWQgaW4gbWVzc2FnZSB3b3JkaW5nCiAgICAgICAgMCAgICAgICAgID0+IG51bGwsIC8vIHZhbGlkYXRpb24gb2YgYSBmYWxzZS15IHZhbHVlIGlzIGFsd2F5cyB0cnVlLCBzbyBub3QgbmVlZGVkIGFzIHdlbGwKICAgICk7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjaygmJHZhbHVlID0gbnVsbCwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgICR0eXBlID0gaXNzZXQoJHNjaGVtYS0+dHlwZSkgPyAkc2NoZW1hLT50eXBlIDogbnVsbDsKICAgICAgICAkaXNWYWxpZCA9IGZhbHNlOwogICAgICAgICR3b3JkaW5nID0gYXJyYXkoKTsKCiAgICAgICAgaWYgKGlzX2FycmF5KCR0eXBlKSkgewogICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVUeXBlc0FycmF5KCR2YWx1ZSwgJHR5cGUsICR3b3JkaW5nLCAkaXNWYWxpZCwgJHBhdGgpOwogICAgICAgIH0gZWxzZWlmIChpc19vYmplY3QoJHR5cGUpKSB7CiAgICAgICAgICAgICR0aGlzLT5jaGVja1VuZGVmaW5lZCgkdmFsdWUsICR0eXBlLCAkcGF0aCk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlzVmFsaWQgPSAkdGhpcy0+dmFsaWRhdGVUeXBlKCR2YWx1ZSwgJHR5cGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRpc1ZhbGlkID09PSBmYWxzZSkgewogICAgICAgICAgICBpZiAoIWlzX2FycmF5KCR0eXBlKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlVHlwZU5hbWVXb3JkaW5nKCR0eXBlKTsKICAgICAgICAgICAgICAgICR3b3JkaW5nW10gPSBzZWxmOjokd29yZGluZ1skdHlwZV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCB1Y3dvcmRzKGdldHR5cGUoJHZhbHVlKSkgLiAnIHZhbHVlIGZvdW5kLCBidXQgJyAuCiAgICAgICAgICAgICAgICAkdGhpcy0+aW1wbG9kZVdpdGgoJHdvcmRpbmcsICcsICcsICdvcicpIC4gJyBpcyByZXF1aXJlZCcsICd0eXBlJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBnaXZlbiAkdmFsdWUgYWdhaW5zdCB0aGUgYXJyYXkgb2YgdHlwZXMgaW4gJHR5cGUuIFNldHMgdGhlIHZhbHVlCiAgICAgKiBvZiAkaXNWYWxpZCB0byB0cnVlLCBpZiBhdCBsZWFzdCBvbmUgJHR5cGUgbWF0ZWNoZXMgdGhlIHR5cGUgb2YgJHZhbHVlIG9yIHRoZSB2YWx1ZQogICAgICogcGFzc2VkIGFzICRpc1ZhbGlkIGlzIGFscmVhZHkgdHJ1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlICAgICAgICAgICAgIFZhbHVlIHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gYXJyYXkgJHR5cGUgICAgICAgICAgICAgIFR5cGVDb25zdHJhaW50cyB0byBjaGVjayBhZ2FpbnMKICAgICAqIEBwYXJhbSBhcnJheSAkdmFsaWRUeXBlc1dvcmRpbmcgQW4gYXJyYXkgb2Ygd29yZGluZ3Mgb2YgdGhlIHZhbGlkIHR5cGVzIG9mIHRoZSBhcnJheSAkdHlwZQogICAgICogQHBhcmFtIGJvb2wgICRpc1ZhbGlkICAgICAgICAgICBUaGUgY3VycmVudCB2YWxpZGF0aW9uIHZhbHVlCiAgICAgKiBAcGFyYW0gJHBhdGgKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlVHlwZXNBcnJheSgmJHZhbHVlLCBhcnJheSAkdHlwZSwgJiR2YWxpZFR5cGVzV29yZGluZywgJiRpc1ZhbGlkLCAkcGF0aCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdHlwZSBhcyAkdHApIHsKICAgICAgICAgICAgLy8gJHRwIGNhbiBiZSBhbiBvYmplY3QsIGlmIGl0J3MgYSBzY2hlbWEgaW5zdGVhZCBvZiBhIHNpbXBsZSB0eXBlLCB2YWxpZGF0ZSBpdAogICAgICAgICAgICAvLyB3aXRoIGEgbmV3IHR5cGUgY29uc3RyYWludAogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCR0cCkpIHsKICAgICAgICAgICAgICAgIGlmICghJGlzVmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd0eXBlJyk7CiAgICAgICAgICAgICAgICAgICAgJHN1YlNjaGVtYSA9IG5ldyBcc3RkQ2xhc3MoKTsKICAgICAgICAgICAgICAgICAgICAkc3ViU2NoZW1hLT50eXBlID0gJHRwOwogICAgICAgICAgICAgICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHN1YlNjaGVtYSwgJHBhdGgsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICRlcnJvciA9ICR2YWxpZGF0b3ItPmdldEVycm9ycygpOwogICAgICAgICAgICAgICAgICAgICRpc1ZhbGlkID0gIShib29sKSAkZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkVHlwZXNXb3JkaW5nW10gPSBzZWxmOjokd29yZGluZ1snb2JqZWN0J107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dmFsaWRhdGVUeXBlTmFtZVdvcmRpbmcoJHRwKTsKICAgICAgICAgICAgICAgICR2YWxpZFR5cGVzV29yZGluZ1tdID0gc2VsZjo6JHdvcmRpbmdbJHRwXTsKICAgICAgICAgICAgICAgIGlmICghJGlzVmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAkaXNWYWxpZCA9ICR0aGlzLT52YWxpZGF0ZVR5cGUoJHZhbHVlLCAkdHApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW1wbG9kZXMgdGhlIGdpdmVuIGFycmF5IGxpa2UgaW1wbG9kZSgpIHdpdGggdHVybmVkIGFyb3VuZCBwYXJhbWV0ZXJzIGFuZCB3aXRoIHRoZQogICAgICogZGlmZmVyZW5jZSwgdGhhdCwgaWYgJGxpc3RFbmQgaXNuJ3QgZmFsc2UsIHRoZSBsYXN0IGVsZW1lbnQgZGVsaW1pdGVyIGlzICRsaXN0RW5kIGluc3RlYWQgb2YKICAgICAqICRkZWxpbWl0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkZWxlbWVudHMgIFRoZSBlbGVtZW50cyB0byBpbXBsb2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkZWxpbWl0ZXIgVGhlIGRlbGltaXRlciB0byB1c2UKICAgICAqIEBwYXJhbSBib29sICAgJGxpc3RFbmQgICBUaGUgbGFzdCBkZWxpbWl0ZXIgdG8gdXNlIChkZWZhdWx0cyB0byAkZGVsaW1pdGVyKQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBpbXBsb2RlV2l0aChhcnJheSAkZWxlbWVudHMsICRkZWxpbWl0ZXIgPSAnLCAnLCAkbGlzdEVuZCA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkbGlzdEVuZCA9PT0gZmFsc2UgfHwgIWlzc2V0KCRlbGVtZW50c1sxXSkpIHsKICAgICAgICAgICAgcmV0dXJuIGltcGxvZGUoJGRlbGltaXRlciwgJGVsZW1lbnRzKTsKICAgICAgICB9CiAgICAgICAgJGxhc3RFbGVtZW50ICA9IGFycmF5X3NsaWNlKCRlbGVtZW50cywgLTEpOwogICAgICAgICRmaXJzRWxlbWVudHMgPSBqb2luKCRkZWxpbWl0ZXIsIGFycmF5X3NsaWNlKCRlbGVtZW50cywgMCwgLTEpKTsKICAgICAgICAkaW1wbG9kZWRFbGVtZW50cyA9IGFycmF5X21lcmdlKGFycmF5KCRmaXJzRWxlbWVudHMpLCAkbGFzdEVsZW1lbnQpOwoKICAgICAgICByZXR1cm4gam9pbigiICRsaXN0RW5kICIsICRpbXBsb2RlZEVsZW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlcyB0aGUgZ2l2ZW4gJHR5cGUsIGlmIHRoZXJlJ3MgYW4gYXNzb2NpYXRlZCBzZWxmOjokd29yZGluZy4gSWYgbm90LCB0aHJvd3MgYW4KICAgICAqIGV4Y2VwdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIFRoZSB0eXBlIHRvIHZhbGlkYXRlCiAgICAgKgogICAgICogQHRocm93cyBTdGFuZGFyZFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdmFsaWRhdGVUeXBlTmFtZVdvcmRpbmcoJHR5cGUpCiAgICB7CiAgICAgICAgaWYgKCFpc3NldChzZWxmOjokd29yZGluZ1skdHlwZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdGFuZGFyZFVuZXhwZWN0ZWRWYWx1ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgIHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ05vIHdvcmRpbmcgZm9yICVzIGF2YWlsYWJsZSwgZXhwZWN0ZWQgd29yZGluZ3MgYXJlOiBbJXNdJywKICAgICAgICAgICAgICAgICAgICB2YXJfZXhwb3J0KCR0eXBlLCB0cnVlKSwKICAgICAgICAgICAgICAgICAgICBpbXBsb2RlKCcsICcsIGFycmF5X2ZpbHRlcihzZWxmOjokd29yZGluZykpKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZlcmlmaWVzIHRoYXQgYSBnaXZlbiB2YWx1ZSBpcyBvZiBhIGNlcnRhaW4gdHlwZQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgJHZhbHVlIFZhbHVlIHRvIHZhbGlkYXRlCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlICBUeXBlQ29uc3RyYWludCB0byBjaGVjayBhZ2FpbnN0CiAgICAgKgogICAgICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHZhbGlkYXRlVHlwZSgmJHZhbHVlLCAkdHlwZSkKICAgIHsKICAgICAgICAvL21vc3RseSB0aGUgY2FzZSBmb3IgaW5saW5lIHNjaGVtYQogICAgICAgIGlmICghJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoJ2FueScgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdvYmplY3QnID09PSAkdHlwZSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc09iamVjdCgkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdhcnJheScgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Z2V0VHlwZUNoZWNrKCktPmlzQXJyYXkoJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgICRjb2VyY2UgPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKENvbnN0cmFpbnQ6OkNIRUNLX01PREVfQ09FUkNFX1RZUEVTKTsKCiAgICAgICAgaWYgKCdpbnRlZ2VyJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgaWYgKCRjb2VyY2UpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT50b0ludGVnZXIoJHZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzX2ludCgkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdudW1iZXInID09PSAkdHlwZSkgewogICAgICAgICAgICBpZiAoJGNvZXJjZSkgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPnRvTnVtYmVyKCR2YWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBpc19udW1lcmljKCR2YWx1ZSkgJiYgIWlzX3N0cmluZygkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdib29sZWFuJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgaWYgKCRjb2VyY2UpIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT50b0Jvb2xlYW4oJHZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzX2Jvb2woJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIGlmICgnc3RyaW5nJyA9PT0gJHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIGlzX3N0cmluZygkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCdlbWFpbCcgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIHJldHVybiBpc19zdHJpbmcoJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIGlmICgnbnVsbCcgPT09ICR0eXBlKSB7CiAgICAgICAgICAgIHJldHVybiBpc19udWxsKCR2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKChpc19vYmplY3QoJHZhbHVlKSA/ICdvYmplY3QnIDogJHZhbHVlKSAuICcgaXMgYW4gaW52YWxpZCB0eXBlIGZvciAnIC4gJHR5cGUpOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgYSB2YWx1ZSB0byBib29sZWFuLiBGb3IgZXhhbXBsZSwgInRydWUiIGJlY29tZXMgdHJ1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gJHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGJvb2xlYW4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8bWl4ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHRvQm9vbGVhbigkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJ3RydWUnKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR2YWx1ZSA9PT0gJ2ZhbHNlJykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgYSBudW1lcmljIHN0cmluZyB0byBhIG51bWJlci4gRm9yIGV4YW1wbGUsICI0IiBiZWNvbWVzIDQuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSB0aGUgdmFsdWUgdG8gY29udmVydCB0byBhIG51bWJlcgogICAgICoKICAgICAqIEByZXR1cm4gaW50fGZsb2F0fG1peGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiB0b051bWJlcigkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSkgewogICAgICAgICAgICByZXR1cm4gJHZhbHVlICsgMDsgLy8gY2FzdCB0byBudW1iZXIKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWU7CiAgICB9CgogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHRvSW50ZWdlcigkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKGlzX251bWVyaWMoJHZhbHVlKSAmJiAoaW50KSAkdmFsdWUgPT0gJHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiAoaW50KSAkdmFsdWU7IC8vIGNhc3QgdG8gbnVtYmVyCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xUeXBlQ2hlY2s7CgppbnRlcmZhY2UgVHlwZUNoZWNrSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNPYmplY3QoJHZhbHVlKTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzQXJyYXkoJHZhbHVlKTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5R2V0KCR2YWx1ZSwgJHByb3BlcnR5KTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5U2V0KCYkdmFsdWUsICRwcm9wZXJ0eSwgJGRhdGEpOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvcGVydHlFeGlzdHMoJHZhbHVlLCAkcHJvcGVydHkpOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvcGVydHlDb3VudCgkdmFsdWUpOwp9Cjw/cGhwCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xUeXBlQ2hlY2s7CgpjbGFzcyBTdHJpY3RUeXBlQ2hlY2sgaW1wbGVtZW50cyBUeXBlQ2hlY2tJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc09iamVjdCgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzX29iamVjdCgkdmFsdWUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXNBcnJheSgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzX2FycmF5KCR2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUdldCgkdmFsdWUsICRwcm9wZXJ0eSkKICAgIHsKICAgICAgICByZXR1cm4gJHZhbHVlLT57JHByb3BlcnR5fTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5U2V0KCYkdmFsdWUsICRwcm9wZXJ0eSwgJGRhdGEpCiAgICB7CiAgICAgICAgJHZhbHVlLT57JHByb3BlcnR5fSA9ICRkYXRhOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcHJvcGVydHlFeGlzdHMoJHZhbHVlLCAkcHJvcGVydHkpCiAgICB7CiAgICAgICAgcmV0dXJuIHByb3BlcnR5X2V4aXN0cygkdmFsdWUsICRwcm9wZXJ0eSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBwcm9wZXJ0eUNvdW50KCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoIWlzX29iamVjdCgkdmFsdWUpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNvdW50KGdldF9vYmplY3RfdmFycygkdmFsdWUpKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHNcVHlwZUNoZWNrOwoKY2xhc3MgTG9vc2VUeXBlQ2hlY2sgaW1wbGVtZW50cyBUeXBlQ2hlY2tJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc09iamVjdCgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlzX29iamVjdCgkdmFsdWUpIHx8CiAgICAgICAgICAgIChpc19hcnJheSgkdmFsdWUpICYmIChjb3VudCgkdmFsdWUpID09IDAgfHwgc2VsZjo6aXNBc3NvY2lhdGl2ZUFycmF5KCR2YWx1ZSkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzQXJyYXkoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybgogICAgICAgICAgICBpc19hcnJheSgkdmFsdWUpICYmCiAgICAgICAgICAgIChjb3VudCgkdmFsdWUpID09IDAgfHwgIXNlbGY6OmlzQXNzb2NpYXRpdmVBcnJheSgkdmFsdWUpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5R2V0KCR2YWx1ZSwgJHByb3BlcnR5KQogICAgewogICAgICAgIGlmIChpc19vYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICByZXR1cm4gJHZhbHVlLT57JHByb3BlcnR5fTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdmFsdWVbJHByb3BlcnR5XTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5U2V0KCYkdmFsdWUsICRwcm9wZXJ0eSwgJGRhdGEpCiAgICB7CiAgICAgICAgaWYgKGlzX29iamVjdCgkdmFsdWUpKSB7CiAgICAgICAgICAgICR2YWx1ZS0+eyRwcm9wZXJ0eX0gPSAkZGF0YTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdmFsdWVbJHByb3BlcnR5XSA9ICRkYXRhOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5RXhpc3RzKCR2YWx1ZSwgJHByb3BlcnR5KQogICAgewogICAgICAgIGlmIChpc19vYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICByZXR1cm4gcHJvcGVydHlfZXhpc3RzKCR2YWx1ZSwgJHByb3BlcnR5KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheV9rZXlfZXhpc3RzKCRwcm9wZXJ0eSwgJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHByb3BlcnR5Q291bnQoJHZhbHVlKQogICAgewogICAgICAgIGlmIChpc19vYmplY3QoJHZhbHVlKSkgewogICAgICAgICAgICByZXR1cm4gY291bnQoZ2V0X29iamVjdF92YXJzKCR2YWx1ZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNvdW50KCR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgcHJvdmlkZWQgYXJyYXkgaXMgYXNzb2NpYXRpdmUgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhcnIKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gaXNBc3NvY2lhdGl2ZUFycmF5KCRhcnIpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleXMoJGFycikgIT09IHJhbmdlKDAsIGNvdW50KCRhcnIpIC0gMSk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXENvbnN0cmFpbnRzOwoKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwoKLyoqCiAqIFRoZSBFbnVtQ29uc3RyYWludCBDb25zdHJhaW50cywgdmFsaWRhdGVzIGFuIGVsZW1lbnQgYWdhaW5zdCBhIGdpdmVuIHNldCBvZiBwb3NzaWJpbGl0aWVzCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgRW51bUNvbnN0cmFpbnQgZXh0ZW5kcyBDb25zdHJhaW50CnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiRlbGVtZW50LCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgLy8gT25seSB2YWxpZGF0ZSBlbnVtIGlmIHRoZSBhdHRyaWJ1dGUgZXhpc3RzCiAgICAgICAgaWYgKCRlbGVtZW50IGluc3RhbmNlb2YgVW5kZWZpbmVkQ29uc3RyYWludCAmJiAoIWlzc2V0KCRzY2hlbWEtPnJlcXVpcmVkKSB8fCAhJHNjaGVtYS0+cmVxdWlyZWQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHR5cGUgPSBnZXR0eXBlKCRlbGVtZW50KTsKCiAgICAgICAgZm9yZWFjaCAoJHNjaGVtYS0+ZW51bSBhcyAkZW51bSkgewogICAgICAgICAgICAkZW51bVR5cGUgPSBnZXR0eXBlKCRlbnVtKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5mYWN0b3J5LT5nZXRDb25maWcoc2VsZjo6Q0hFQ0tfTU9ERV9UWVBFX0NBU1QpICYmICR0eXBlID09ICdhcnJheScgJiYgJGVudW1UeXBlID09ICdvYmplY3QnKSB7CiAgICAgICAgICAgICAgICBpZiAoKG9iamVjdCkgJGVsZW1lbnQgPT0gJGVudW0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gZ2V0dHlwZSgkZW51bSkpIHsKICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PSAnb2JqZWN0JykgewogICAgICAgICAgICAgICAgICAgIGlmICgkZWxlbWVudCA9PSAkZW51bSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRlbGVtZW50ID09PSAkZW51bSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmFkZEVycm9yKCRwYXRoLCAnRG9lcyBub3QgaGF2ZSBhIHZhbHVlIGluIHRoZSBlbnVtZXJhdGlvbiAnIC4ganNvbl9lbmNvZGUoJHNjaGVtYS0+ZW51bSksICdlbnVtJywgYXJyYXkoJ2VudW0nID0+ICRzY2hlbWEtPmVudW0pKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcQ29uc3RyYWludHM7Cgp1c2UgSnNvblNjaGVtYVxFbnRpdHlcSnNvblBvaW50ZXI7CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxJbnZhbGlkU2NoZW1hRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVmFsaWRhdG9yOwoKLyoqCiAqIFRoZSBTY2hlbWFDb25zdHJhaW50IENvbnN0cmFpbnRzLCB2YWxpZGF0ZXMgYW4gZWxlbWVudCBhZ2FpbnN0IGEgZ2l2ZW4gc2NoZW1hCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KY2xhc3MgU2NoZW1hQ29uc3RyYWludCBleHRlbmRzIENvbnN0cmFpbnQKewogICAgY29uc3QgREVGQVVMVF9TQ0hFTUFfU1BFQyA9ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMnOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJiRlbGVtZW50LCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRzY2hlbWEgIT09IG51bGwpIHsKICAgICAgICAgICAgLy8gcGFzc2VkIHNjaGVtYQogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9ICRzY2hlbWE7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJGVsZW1lbnQsICR0aGlzLT5pbmxpbmVTY2hlbWFQcm9wZXJ0eSkpIHsKICAgICAgICAgICAgLy8gaW5saW5lIHNjaGVtYQogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9ICR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlHZXQoJGVsZW1lbnQsICR0aGlzLT5pbmxpbmVTY2hlbWFQcm9wZXJ0eSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignbm8gc2NoZW1hIGZvdW5kIHRvIHZlcmlmeSBhZ2FpbnN0Jyk7CiAgICAgICAgfQoKICAgICAgICAvLyBjYXN0IGFycmF5IHNjaGVtYXMgdG8gb2JqZWN0CiAgICAgICAgaWYgKGlzX2FycmF5KCR2YWxpZGF0aW9uU2NoZW1hKSkgewogICAgICAgICAgICAkdmFsaWRhdGlvblNjaGVtYSA9IEJhc2VDb25zdHJhaW50OjphcnJheVRvT2JqZWN0UmVjdXJzaXZlKCR2YWxpZGF0aW9uU2NoZW1hKTsKICAgICAgICB9CgogICAgICAgIC8vIHZhbGlkYXRlIHNjaGVtYSBhZ2FpbnN0IHdoYXRldmVyIGlzIGRlZmluZWQgaW4gJHZhbGlkYXRpb25TY2hlbWEtPiRzY2hlbWEuIElmIG5vCiAgICAgICAgLy8gc2NoZW1hIGlzIGRlZmluZWQsIGFzc3VtZSBzZWxmOjpERUZBVUxUX1NDSEVNQV9TUEVDIChjdXJyZW50bHkgZHJhZnQtMDQpLgogICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfVkFMSURBVEVfU0NIRU1BKSkgewogICAgICAgICAgICBpZiAoISR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+aXNPYmplY3QoJHZhbGlkYXRpb25TY2hlbWEpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbignQ2Fubm90IHZhbGlkYXRlIHRoZSBzY2hlbWEgb2YgYSBub24tb2JqZWN0Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5nZXRUeXBlQ2hlY2soKS0+cHJvcGVydHlFeGlzdHMoJHZhbGlkYXRpb25TY2hlbWEsICckc2NoZW1hJykpIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gJHRoaXMtPmdldFR5cGVDaGVjaygpLT5wcm9wZXJ0eUdldCgkdmFsaWRhdGlvblNjaGVtYSwgJyRzY2hlbWEnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gc2VsZjo6REVGQVVMVF9TQ0hFTUFfU1BFQzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZ2V0IHRoZSBzcGVjIHNjaGVtYQogICAgICAgICAgICAkc2NoZW1hU3RvcmFnZSA9ICR0aGlzLT5mYWN0b3J5LT5nZXRTY2hlbWFTdG9yYWdlKCk7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmdldFR5cGVDaGVjaygpLT5pc09iamVjdCgkc2NoZW1hU3BlYykpIHsKICAgICAgICAgICAgICAgICRzY2hlbWFTcGVjID0gJHNjaGVtYVN0b3JhZ2UtPmdldFNjaGVtYSgkc2NoZW1hU3BlYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNhdmUgZXJyb3IgY291bnQsIGNvbmZpZyAmIHN1YnRyYWN0IENIRUNLX01PREVfVkFMSURBVEVfU0NIRU1BCiAgICAgICAgICAgICRpbml0aWFsRXJyb3JDb3VudCA9ICR0aGlzLT5udW1FcnJvcnMoKTsKICAgICAgICAgICAgJGluaXRpYWxDb25maWcgPSAkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKCk7CiAgICAgICAgICAgICRpbml0aWFsQ29udGV4dCA9ICR0aGlzLT5mYWN0b3J5LT5nZXRFcnJvckNvbnRleHQoKTsKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPnJlbW92ZUNvbmZpZyhzZWxmOjpDSEVDS19NT0RFX1ZBTElEQVRFX1NDSEVNQSB8IHNlbGY6OkNIRUNLX01PREVfQVBQTFlfREVGQVVMVFMpOwogICAgICAgICAgICAkdGhpcy0+ZmFjdG9yeS0+YWRkQ29uZmlnKHNlbGY6OkNIRUNLX01PREVfVFlQRV9DQVNUKTsKICAgICAgICAgICAgJHRoaXMtPmZhY3RvcnktPnNldEVycm9yQ29udGV4dChWYWxpZGF0b3I6OkVSUk9SX1NDSEVNQV9WQUxJREFUSU9OKTsKCiAgICAgICAgICAgIC8vIHZhbGlkYXRlIHNjaGVtYQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRoaXMtPmNoZWNrKCR2YWxpZGF0aW9uU2NoZW1hLCAkc2NoZW1hU3BlYyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFxFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZmFjdG9yeS0+Z2V0Q29uZmlnKHNlbGY6OkNIRUNLX01PREVfRVhDRVBUSU9OUykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFNjaGVtYUV4Y2VwdGlvbignU2NoZW1hIGRpZCBub3QgcGFzcyB2YWxpZGF0aW9uJywgMCwgJGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+bnVtRXJyb3JzKCkgPiAkaW5pdGlhbEVycm9yQ291bnQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZGRFcnJvcigkcGF0aCwgJ1NjaGVtYSBpcyBub3QgdmFsaWQnLCAnc2NoZW1hJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlc3RvcmUgdGhlIGluaXRpYWwgY29uZmlnCiAgICAgICAgICAgICR0aGlzLT5mYWN0b3J5LT5zZXRDb25maWcoJGluaXRpYWxDb25maWcpOwogICAgICAgICAgICAkdGhpcy0+ZmFjdG9yeS0+c2V0RXJyb3JDb250ZXh0KCRpbml0aWFsQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICAvLyB2YWxpZGF0ZSBlbGVtZW50IGFnYWluc3QgJHZhbGlkYXRpb25TY2hlbWEKICAgICAgICAkdGhpcy0+Y2hlY2tVbmRlZmluZWQoJGVsZW1lbnQsICR2YWxpZGF0aW9uU2NoZW1hLCAkcGF0aCwgJGkpOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxDb25zdHJhaW50czsKCnVzZSBKc29uU2NoZW1hXEVudGl0eVxKc29uUG9pbnRlcjsKCi8qKgogKiBUaGUgQmFzZSBDb25zdHJhaW50cywgYWxsIFZhbGlkYXRvcnMgc2hvdWxkIGV4dGVuZCB0aGlzIGNsYXNzCiAqCiAqIEBhdXRob3IgUm9iZXJ0IFNjaMO2bnRoYWwgPHNlcm9zY2hvQGdvb2dsZW1haWwuY29tPgogKiBAYXV0aG9yIEJydW5vIFByaWV0byBSZWlzIDxicnVuby5wLnJlaXNAZ21haWwuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgQ29uc3RyYWludCBleHRlbmRzIEJhc2VDb25zdHJhaW50IGltcGxlbWVudHMgQ29uc3RyYWludEludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGlubGluZVNjaGVtYVByb3BlcnR5ID0gJyRzY2hlbWEnOwoKICAgIGNvbnN0IENIRUNLX01PREVfTk9ORSA9ICAgICAgICAgICAgIDB4MDAwMDAwMDA7CiAgICBjb25zdCBDSEVDS19NT0RFX05PUk1BTCA9ICAgICAgICAgICAweDAwMDAwMDAxOwogICAgY29uc3QgQ0hFQ0tfTU9ERV9UWVBFX0NBU1QgPSAgICAgICAgMHgwMDAwMDAwMjsKICAgIGNvbnN0IENIRUNLX01PREVfQ09FUkNFX1RZUEVTID0gICAgIDB4MDAwMDAwMDQ7CiAgICBjb25zdCBDSEVDS19NT0RFX0FQUExZX0RFRkFVTFRTID0gICAweDAwMDAwMDA4OwogICAgY29uc3QgQ0hFQ0tfTU9ERV9FWENFUFRJT05TID0gICAgICAgMHgwMDAwMDAxMDsKICAgIGNvbnN0IENIRUNLX01PREVfRElTQUJMRV9GT1JNQVQgPSAgIDB4MDAwMDAwMjA7CiAgICBjb25zdCBDSEVDS19NT0RFX09OTFlfUkVRVUlSRURfREVGQVVMVFMgICA9IDB4MDAwMDAwODA7CiAgICBjb25zdCBDSEVDS19NT0RFX1ZBTElEQVRFX1NDSEVNQSA9ICAweDAwMDAwMTAwOwoKICAgIC8qKgogICAgICogQnViYmxlIGRvd24gdGhlIHBhdGgKICAgICAqCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aCBDdXJyZW50IHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRpICAgIFdoYXQgdG8gYXBwZW5kIHRvIHRoZSBwYXRoCiAgICAgKgogICAgICogQHJldHVybiBKc29uUG9pbnRlcjsKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGluY3JlbWVudFBhdGgoSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSkKICAgIHsKICAgICAgICAkcGF0aCA9ICRwYXRoID86IG5ldyBKc29uUG9pbnRlcignJyk7CiAgICAgICAgJHBhdGggPSAkcGF0aC0+d2l0aFByb3BlcnR5UGF0aHMoCiAgICAgICAgICAgIGFycmF5X21lcmdlKAogICAgICAgICAgICAgICAgJHBhdGgtPmdldFByb3BlcnR5UGF0aHMoKSwKICAgICAgICAgICAgICAgIGFycmF5X2ZpbHRlcihhcnJheSgkaSksICdzdHJsZW4nKQogICAgICAgICAgICApCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuICRwYXRoOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIGFuIGFycmF5CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrQXJyYXkoJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ2NvbGxlY3Rpb24nKTsKICAgICAgICAkdmFsaWRhdG9yLT5jaGVjaygkdmFsdWUsICRzY2hlbWEsICRwYXRoLCAkaSk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIGFuIG9iamVjdAogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRwcm9wZXJ0aWVzCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkYWRkaXRpb25hbFByb3BlcnRpZXMKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRwYXR0ZXJuUHJvcGVydGllcwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tPYmplY3QoJiR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJHByb3BlcnRpZXMgPSBudWxsLAogICAgICAgICRhZGRpdGlvbmFsUHJvcGVydGllcyA9IG51bGwsICRwYXR0ZXJuUHJvcGVydGllcyA9IG51bGwsICRhcHBsaWVkRGVmYXVsdHMgPSBhcnJheSgpKQogICAgewogICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ29iamVjdCcpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRwcm9wZXJ0aWVzLCAkYWRkaXRpb25hbFByb3BlcnRpZXMsICRwYXR0ZXJuUHJvcGVydGllcywgJGFwcGxpZWREZWZhdWx0cyk7CgogICAgICAgICR0aGlzLT5hZGRFcnJvcnMoJHZhbGlkYXRvci0+Z2V0RXJyb3JzKCkpOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSB0eXBlIG9mIGEgcHJvcGVydHkKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tUeXBlKCYkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCkKICAgIHsKICAgICAgICAkdmFsaWRhdG9yID0gJHRoaXMtPmZhY3RvcnktPmNyZWF0ZUluc3RhbmNlRm9yKCd0eXBlJyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhIHVuZGVmaW5lZCBlbGVtZW50CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrVW5kZWZpbmVkKCYkdmFsdWUsICRzY2hlbWEgPSBudWxsLCBKc29uUG9pbnRlciAkcGF0aCA9IG51bGwsICRpID0gbnVsbCwgJGZyb21EZWZhdWx0ID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcigndW5kZWZpbmVkJyk7CgogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHRoaXMtPmZhY3RvcnktPmdldFNjaGVtYVN0b3JhZ2UoKS0+cmVzb2x2ZVJlZlNjaGVtYSgkc2NoZW1hKSwgJHBhdGgsICRpLCAkZnJvbURlZmF1bHQpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhIHN0cmluZyBlbGVtZW50CiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHZhbHVlCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXJ8bnVsbCAkcGF0aAogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJGkKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrU3RyaW5nKCR2YWx1ZSwgJHNjaGVtYSA9IG51bGwsIEpzb25Qb2ludGVyICRwYXRoID0gbnVsbCwgJGkgPSBudWxsKQogICAgewogICAgICAgICR2YWxpZGF0b3IgPSAkdGhpcy0+ZmFjdG9yeS0+Y3JlYXRlSW5zdGFuY2VGb3IoJ3N0cmluZycpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKCiAgICAgICAgJHRoaXMtPmFkZEVycm9ycygkdmFsaWRhdG9yLT5nZXRFcnJvcnMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgYSBudW1iZXIgZWxlbWVudAogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXIgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tOdW1iZXIoJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignbnVtYmVyJyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhIGVudW0gZWxlbWVudAogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICR2YWx1ZQogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICAgJHNjaGVtYQogICAgICogQHBhcmFtIEpzb25Qb2ludGVyfG51bGwgJHBhdGgKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRpCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0VudW0oJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignZW51bScpOwogICAgICAgICR2YWxpZGF0b3ItPmNoZWNrKCR2YWx1ZSwgJHNjaGVtYSwgJHBhdGgsICRpKTsKCiAgICAgICAgJHRoaXMtPmFkZEVycm9ycygkdmFsaWRhdG9yLT5nZXRFcnJvcnMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgZm9ybWF0IG9mIGFuIGVsZW1lbnQKICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkdmFsdWUKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgICAgICRzY2hlbWEKICAgICAqIEBwYXJhbSBKc29uUG9pbnRlcnxudWxsICRwYXRoCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICAgICAkaQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hlY2tGb3JtYXQoJHZhbHVlLCAkc2NoZW1hID0gbnVsbCwgSnNvblBvaW50ZXIgJHBhdGggPSBudWxsLCAkaSA9IG51bGwpCiAgICB7CiAgICAgICAgJHZhbGlkYXRvciA9ICR0aGlzLT5mYWN0b3J5LT5jcmVhdGVJbnN0YW5jZUZvcignZm9ybWF0Jyk7CiAgICAgICAgJHZhbGlkYXRvci0+Y2hlY2soJHZhbHVlLCAkc2NoZW1hLCAkcGF0aCwgJGkpOwoKICAgICAgICAkdGhpcy0+YWRkRXJyb3JzKCR2YWxpZGF0b3ItPmdldEVycm9ycygpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgdHlwZSBjaGVjayBiYXNlZCBvbiB0aGUgc2V0IGNoZWNrIG1vZGUuCiAgICAgKgogICAgICogQHJldHVybiBUeXBlQ2hlY2tcVHlwZUNoZWNrSW50ZXJmYWNlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRUeXBlQ2hlY2soKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmFjdG9yeS0+Z2V0VHlwZUNoZWNrKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gSnNvblBvaW50ZXIgJHBvaW50ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBwcm9wZXJ0eSBwYXRoCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb252ZXJ0SnNvblBvaW50ZXJJbnRvUHJvcGVydHlQYXRoKEpzb25Qb2ludGVyICRwb2ludGVyKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheV9tYXAoCiAgICAgICAgICAgIGZ1bmN0aW9uICgkcGF0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoaXNfbnVtZXJpYygkcGF0aCkgPyAnWyVkXScgOiAnLiVzJywgJHBhdGgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAkcG9pbnRlci0+Z2V0UHJvcGVydHlQYXRocygpCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuIHRyaW0oaW1wbG9kZSgnJywgJHJlc3VsdCksICcuJyk7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBAcGFja2FnZSBKc29uU2NoZW1hXEV4Y2VwdGlvbgogKgogKiBAYXV0aG9yIEpvb3N0IE5pamh1aXMgPGpuaWpodWlzODFAZ21haWwuY29tPgogKi8KY2xhc3MgVW5yZXNvbHZhYmxlSnNvblBvaW50ZXJFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIEpzb25EZWNvZGluZ0V4Y2VwdGlvbgogKi8KY2xhc3MgSnNvbkRlY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7CiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGNvZGUgPSBKU09OX0VSUk9SX05PTkUsIFxFeGNlcHRpb24gJHByZXZpb3VzID0gbnVsbCkKICAgIHsKICAgICAgICBzd2l0Y2ggKCRjb2RlKSB7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9ERVBUSDoKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gJ1RoZSBtYXhpbXVtIHN0YWNrIGRlcHRoIGhhcyBiZWVuIGV4Y2VlZGVkJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfU1RBVEVfTUlTTUFUQ0g6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdJbnZhbGlkIG9yIG1hbGZvcm1lZCBKU09OJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfQ1RSTF9DSEFSOgogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnQ29udHJvbCBjaGFyYWN0ZXIgZXJyb3IsIHBvc3NpYmx5IGluY29ycmVjdGx5IGVuY29kZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9VVEY4OgogICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSAnTWFsZm9ybWVkIFVURi04IGNoYXJhY3RlcnMsIHBvc3NpYmx5IGluY29ycmVjdGx5IGVuY29kZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9TWU5UQVg6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdKU09OIHN5bnRheCBpcyBtYWxmb3JtZWQnOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICdTeW50YXggZXJyb3InOwogICAgICAgIH0KICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlLCAkY29kZSwgJHByZXZpb3VzKTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKY2xhc3MgVmFsaWRhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIFVyaVJlc29sdmVyRXhjZXB0aW9uCiAqLwpjbGFzcyBVcmlSZXNvbHZlckV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogKi8KY2xhc3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGV4dGVuZHMgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbgogKi8KY2xhc3MgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24KICovCmNsYXNzIEludmFsaWRDb25maWdFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uCnsKfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKLyoqCiAqIFdyYXBwZXIgZm9yIHRoZSBJbnZhbGlkU2NoZW1hTWVkaWFUeXBlCiAqLwpjbGFzcyBJbnZhbGlkU2NoZW1hRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgUnVudGltZUV4Y2VwdGlvbgogKi8KY2xhc3MgUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIFxSdW50aW1lRXhjZXB0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uSW50ZXJmYWNlCnsKfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcRXhjZXB0aW9uOwoKaW50ZXJmYWNlIEV4Y2VwdGlvbkludGVyZmFjZQp7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXEV4Y2VwdGlvbjsKCi8qKgogKiBXcmFwcGVyIGZvciB0aGUgSW52YWxpZFNjaGVtYU1lZGlhVHlwZQogKi8KY2xhc3MgSW52YWxpZFNjaGVtYU1lZGlhVHlwZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxFeGNlcHRpb247CgovKioKICogV3JhcHBlciBmb3IgdGhlIEludmFsaWRTb3VyY2VVcmlFeGNlcHRpb24KICovCmNsYXNzIEludmFsaWRTb3VyY2VVcmlFeGNlcHRpb24gZXh0ZW5kcyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24Kewp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxJdGVyYXRvcjsKCi8qKgogKiBAcGFja2FnZSBKc29uU2NoZW1hXEl0ZXJhdG9yCiAqCiAqIEBhdXRob3IgSm9vc3QgTmlqaHVpcyA8am5pamh1aXM4MUBnbWFpbC5jb20+CiAqLwpjbGFzcyBPYmplY3RJdGVyYXRvciBpbXBsZW1lbnRzIFxJdGVyYXRvciwgXENvdW50YWJsZQp7CiAgICAvKiogQHZhciBvYmplY3QgKi8KICAgIHByaXZhdGUgJG9iamVjdDsKCiAgICAvKiogQHZhciBpbnQgKi8KICAgIHByaXZhdGUgJHBvc2l0aW9uID0gMDsKCiAgICAvKiogQHZhciBhcnJheSAqLwogICAgcHJpdmF0ZSAkZGF0YSA9IGFycmF5KCk7CgogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHJpdmF0ZSAkaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBvYmplY3QgJG9iamVjdAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG9iamVjdCkKICAgIHsKICAgICAgICAkdGhpcy0+b2JqZWN0ID0gJG9iamVjdDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGN1cnJlbnQoKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+ZGF0YVskdGhpcy0+cG9zaXRpb25dOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dCgpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoKTsKICAgICAgICAkdGhpcy0+cG9zaXRpb24rKzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGtleSgpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXRpYWxpemUoKTsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5wb3NpdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHZhbGlkKCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwoKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmRhdGFbJHRoaXMtPnBvc2l0aW9uXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXdpbmQoKQogICAgewogICAgICAgICR0aGlzLT5pbml0aWFsaXplKCk7CiAgICAgICAgJHRoaXMtPnBvc2l0aW9uID0gMDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZSgpOwoKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXIKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0aWFsaXplKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5pbml0aWFsaXplZCkgewogICAgICAgICAgICAkdGhpcy0+ZGF0YSA9ICR0aGlzLT5idWlsZERhdGFGcm9tT2JqZWN0KCR0aGlzLT5vYmplY3QpOwogICAgICAgICAgICAkdGhpcy0+aW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBvYmplY3QgJG9iamVjdAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBidWlsZERhdGFGcm9tT2JqZWN0KCRvYmplY3QpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CgogICAgICAgICRzdGFjayA9IG5ldyBcU3BsU3RhY2soKTsKICAgICAgICAkc3RhY2stPnB1c2goJG9iamVjdCk7CgogICAgICAgIHdoaWxlICghJHN0YWNrLT5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgJGN1cnJlbnQgPSAkc3RhY2stPnBvcCgpOwogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRjdXJyZW50KSkgewogICAgICAgICAgICAgICAgYXJyYXlfcHVzaCgkcmVzdWx0LCAkY3VycmVudCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5nZXREYXRhRnJvbUl0ZW0oJGN1cnJlbnQpIGFzICRwcm9wZXJ0eU5hbWUgPT4gJHByb3BlcnR5VmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmIChpc19vYmplY3QoJHByb3BlcnR5VmFsdWUpIHx8IGlzX2FycmF5KCRwcm9wZXJ0eVZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICRzdGFjay0+cHVzaCgkcHJvcGVydHlWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG9iamVjdHxhcnJheSAkaXRlbQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXREYXRhRnJvbUl0ZW0oJGl0ZW0pCiAgICB7CiAgICAgICAgaWYgKCFpc19vYmplY3QoJGl0ZW0pICYmICFpc19hcnJheSgkaXRlbSkpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNfb2JqZWN0KCRpdGVtKSA/IGdldF9vYmplY3RfdmFycygkaXRlbSkgOiAkaXRlbTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWE7CgovKioKICogQHBhY2thZ2UgSnNvblNjaGVtYQogKi8KaW50ZXJmYWNlIFVyaVJldHJpZXZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJldHJpZXZlIGEgVVJJCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICR1cmkgICAgIEpTT04gU2NoZW1hIFVSSQogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRiYXNlVXJpCiAgICAgKgogICAgICogQHJldHVybiBvYmplY3QgSlNPTiBTY2hlbWEgY29udGVudHMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJldHJpZXZlKCR1cmksICRiYXNlVXJpID0gbnVsbCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hOwoKLyoqCiAqIEBwYWNrYWdlIEpzb25TY2hlbWEKICovCmludGVyZmFjZSBVcmlSZXNvbHZlckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIFJlc29sdmVzIGEgVVJJCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICR1cmkgICAgIEFic29sdXRlIG9yIHJlbGF0aXZlCiAgICAgKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGJhc2VVcmkgT3B0aW9uYWwgYmFzZSBVUkkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBYnNvbHV0ZSBVUkkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmUoJHVyaSwgJGJhc2VVcmkgPSBudWxsKTsKfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWE7Cgp1c2UgSnNvblNjaGVtYVxDb25zdHJhaW50c1xCYXNlQ29uc3RyYWludDsKdXNlIEpzb25TY2hlbWFcRW50aXR5XEpzb25Qb2ludGVyOwp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cVW5yZXNvbHZhYmxlSnNvblBvaW50ZXJFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXFVyaVxVcmlSZXNvbHZlcjsKdXNlIEpzb25TY2hlbWFcVXJpXFVyaVJldHJpZXZlcjsKCmNsYXNzIFNjaGVtYVN0b3JhZ2UgaW1wbGVtZW50cyBTY2hlbWFTdG9yYWdlSW50ZXJmYWNlCnsKICAgIGNvbnN0IElOVEVSTkFMX1BST1ZJREVEX1NDSEVNQV9VUkkgPSAnaW50ZXJuYWw6Ly9wcm92aWRlZC1zY2hlbWEvJzsKCiAgICBwcm90ZWN0ZWQgJHVyaVJldHJpZXZlcjsKICAgIHByb3RlY3RlZCAkdXJpUmVzb2x2ZXI7CiAgICBwcm90ZWN0ZWQgJHNjaGVtYXMgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgKICAgICAgICBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UgJHVyaVJldHJpZXZlciA9IG51bGwsCiAgICAgICAgVXJpUmVzb2x2ZXJJbnRlcmZhY2UgJHVyaVJlc29sdmVyID0gbnVsbAogICAgKSB7CiAgICAgICAgJHRoaXMtPnVyaVJldHJpZXZlciA9ICR1cmlSZXRyaWV2ZXIgPzogbmV3IFVyaVJldHJpZXZlcigpOwogICAgICAgICR0aGlzLT51cmlSZXNvbHZlciA9ICR1cmlSZXNvbHZlciA/OiBuZXcgVXJpUmVzb2x2ZXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVXJpUmV0cmlldmVySW50ZXJmYWNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcmlSZXRyaWV2ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmV0cmlldmVyOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBVcmlSZXNvbHZlckludGVyZmFjZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VXJpUmVzb2x2ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXJpUmVzb2x2ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTY2hlbWEoJGlkLCAkc2NoZW1hID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoaXNfbnVsbCgkc2NoZW1hKSAmJiAkaWQgIT09IHNlbGY6OklOVEVSTkFMX1BST1ZJREVEX1NDSEVNQV9VUkkpIHsKICAgICAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSB3YXMgdXNlci1wcm92aWRlZCB0byBWYWxpZGF0b3IgYW5kIGlzIHN0aWxsIG51bGwsIHRoZW4gYXNzdW1lIHRoaXMgaXMKICAgICAgICAgICAgLy8gd2hhdCB0aGUgdXNlciBpbnRlbmRlZCwgYXMgdGhlcmUncyBubyB3YXkgZm9yIHVzIHRvIHJldHJpZXZlIGFueXRoaW5nIGVsc2UuIFVzZXItc3VwcGxpZWQKICAgICAgICAgICAgLy8gc2NoZW1hcyBkbyBub3QgaGF2ZSBhbiBhc3NvY2lhdGVkIFVSSSB3aGVuIHBhc3NlZCB2aWEgVmFsaWRhdG9yOjp2YWxpZGF0ZSgpLgogICAgICAgICAgICAkc2NoZW1hID0gJHRoaXMtPnVyaVJldHJpZXZlci0+cmV0cmlldmUoJGlkKTsKICAgICAgICB9CgogICAgICAgIC8vIGNhc3QgYXJyYXkgc2NoZW1hcyB0byBvYmplY3QKICAgICAgICBpZiAoaXNfYXJyYXkoJHNjaGVtYSkpIHsKICAgICAgICAgICAgJHNjaGVtYSA9IEJhc2VDb25zdHJhaW50OjphcnJheVRvT2JqZWN0UmVjdXJzaXZlKCRzY2hlbWEpOwogICAgICAgIH0KCiAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgYnVnIGluIGRyYWZ0LTAzICYgZHJhZnQtMDQgbWV0YS1zY2hlbWFzIChpZCAmICRyZWYgZGVmaW5lZCB3aXRoIGluY29ycmVjdCBmb3JtYXQpCiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qc29uLXNjaGVtYS1vcmcvSlNPTi1TY2hlbWEtVGVzdC1TdWl0ZS9pc3N1ZXMvMTc3I2lzc3VlY29tbWVudC0yOTMwNTEzNjcKICAgICAgICBpZiAoaXNfb2JqZWN0KCRzY2hlbWEpICYmIHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSkgewogICAgICAgICAgICBpZiAoJHNjaGVtYS0+aWQgPT0gJ2h0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIycpIHsKICAgICAgICAgICAgICAgICRzY2hlbWEtPnByb3BlcnRpZXMtPmlkLT5mb3JtYXQgPSAndXJpLXJlZmVyZW5jZSc7CiAgICAgICAgICAgIH0gZWxzZWlmICgkc2NoZW1hLT5pZCA9PSAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wMy9zY2hlbWEjJykgewogICAgICAgICAgICAgICAgJHNjaGVtYS0+cHJvcGVydGllcy0+aWQtPmZvcm1hdCA9ICd1cmktcmVmZXJlbmNlJzsKICAgICAgICAgICAgICAgICRzY2hlbWEtPnByb3BlcnRpZXMtPnsnJHJlZid9LT5mb3JtYXQgPSAndXJpLXJlZmVyZW5jZSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHJlc29sdmUgcmVmZXJlbmNlcwogICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRzY2hlbWEsICRpZCk7CgogICAgICAgICR0aGlzLT5zY2hlbWFzWyRpZF0gPSAkc2NoZW1hOwogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgcmVzb2x2ZSBhbGwgcmVmZXJlbmNlcyBhZ2FpbnN0IHRoZSBwcm92aWRlZCBiYXNlCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAkc2NoZW1hCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZXhwYW5kUmVmcygmJHNjaGVtYSwgJGJhc2UgPSBudWxsKQogICAgewogICAgICAgIGlmICghaXNfb2JqZWN0KCRzY2hlbWEpKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkc2NoZW1hKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHNjaGVtYSBhcyAmJG1lbWJlcikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRtZW1iZXIsICRiYXNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHByb3BlcnR5X2V4aXN0cygkc2NoZW1hLCAnaWQnKSAmJiBpc19zdHJpbmcoJHNjaGVtYS0+aWQpICYmICRiYXNlICE9ICRzY2hlbWEtPmlkKSB7CiAgICAgICAgICAgICRiYXNlID0gJHRoaXMtPnVyaVJlc29sdmVyLT5yZXNvbHZlKCRzY2hlbWEtPmlkLCAkYmFzZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJvcGVydHlfZXhpc3RzKCRzY2hlbWEsICckcmVmJykgJiYgaXNfc3RyaW5nKCRzY2hlbWEtPnsnJHJlZid9KSkgewogICAgICAgICAgICAkcmVmUG9pbnRlciA9IG5ldyBKc29uUG9pbnRlcigkdGhpcy0+dXJpUmVzb2x2ZXItPnJlc29sdmUoJHNjaGVtYS0+eyckcmVmJ30sICRiYXNlKSk7CiAgICAgICAgICAgICRzY2hlbWEtPnsnJHJlZid9ID0gKHN0cmluZykgJHJlZlBvaW50ZXI7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkc2NoZW1hIGFzICYkbWVtYmVyKSB7CiAgICAgICAgICAgICR0aGlzLT5leHBhbmRSZWZzKCRtZW1iZXIsICRiYXNlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTY2hlbWEoJGlkKQogICAgewogICAgICAgIGlmICghYXJyYXlfa2V5X2V4aXN0cygkaWQsICR0aGlzLT5zY2hlbWFzKSkgewogICAgICAgICAgICAkdGhpcy0+YWRkU2NoZW1hKCRpZCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYXNbJGlkXTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlc29sdmVSZWYoJHJlZikKICAgIHsKICAgICAgICAkanNvblBvaW50ZXIgPSBuZXcgSnNvblBvaW50ZXIoJHJlZik7CgogICAgICAgIC8vIHJlc29sdmUgZmlsZW5hbWUgZm9yIHBvaW50ZXIKICAgICAgICAkZmlsZU5hbWUgPSAkanNvblBvaW50ZXItPmdldEZpbGVuYW1lKCk7CiAgICAgICAgaWYgKCFzdHJsZW4oJGZpbGVOYW1lKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5yZXNvbHZhYmxlSnNvblBvaW50ZXJFeGNlcHRpb24oc3ByaW50ZigKICAgICAgICAgICAgICAgICJDb3VsZCBub3QgcmVzb2x2ZSBmcmFnbWVudCAnJXMnOiBubyBmaWxlIGlzIGRlZmluZWQiLAogICAgICAgICAgICAgICAgJGpzb25Qb2ludGVyLT5nZXRQcm9wZXJ0eVBhdGhBc1N0cmluZygpCiAgICAgICAgICAgICkpOwogICAgICAgIH0KCiAgICAgICAgLy8gZ2V0ICYgcHJvY2VzcyB0aGUgc2NoZW1hCiAgICAgICAgJHJlZlNjaGVtYSA9ICR0aGlzLT5nZXRTY2hlbWEoJGZpbGVOYW1lKTsKICAgICAgICBmb3JlYWNoICgkanNvblBvaW50ZXItPmdldFByb3BlcnR5UGF0aHMoKSBhcyAkcGF0aCkgewogICAgICAgICAgICBpZiAoaXNfb2JqZWN0KCRyZWZTY2hlbWEpICYmIHByb3BlcnR5X2V4aXN0cygkcmVmU2NoZW1hLCAkcGF0aCkpIHsKICAgICAgICAgICAgICAgICRyZWZTY2hlbWEgPSAkdGhpcy0+cmVzb2x2ZVJlZlNjaGVtYSgkcmVmU2NoZW1hLT57JHBhdGh9KTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzX2FycmF5KCRyZWZTY2hlbWEpICYmIGFycmF5X2tleV9leGlzdHMoJHBhdGgsICRyZWZTY2hlbWEpKSB7CiAgICAgICAgICAgICAgICAkcmVmU2NoZW1hID0gJHRoaXMtPnJlc29sdmVSZWZTY2hlbWEoJHJlZlNjaGVtYVskcGF0aF0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVzb2x2YWJsZUpzb25Qb2ludGVyRXhjZXB0aW9uKHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgJ0ZpbGU6ICVzIGlzIGZvdW5kLCBidXQgY291bGQgbm90IHJlc29sdmUgZnJhZ21lbnQ6ICVzJywKICAgICAgICAgICAgICAgICAgICAkanNvblBvaW50ZXItPmdldEZpbGVuYW1lKCksCiAgICAgICAgICAgICAgICAgICAgJGpzb25Qb2ludGVyLT5nZXRQcm9wZXJ0eVBhdGhBc1N0cmluZygpCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWZTY2hlbWE7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNvbHZlUmVmU2NoZW1hKCRyZWZTY2hlbWEpCiAgICB7CiAgICAgICAgaWYgKGlzX29iamVjdCgkcmVmU2NoZW1hKSAmJiBwcm9wZXJ0eV9leGlzdHMoJHJlZlNjaGVtYSwgJyRyZWYnKSAmJiBpc19zdHJpbmcoJHJlZlNjaGVtYS0+eyckcmVmJ30pKSB7CiAgICAgICAgICAgICRuZXdTY2hlbWEgPSAkdGhpcy0+cmVzb2x2ZVJlZigkcmVmU2NoZW1hLT57JyRyZWYnfSk7CiAgICAgICAgICAgICRyZWZTY2hlbWEgPSAob2JqZWN0KSAoZ2V0X29iamVjdF92YXJzKCRyZWZTY2hlbWEpICsgZ2V0X29iamVjdF92YXJzKCRuZXdTY2hlbWEpKTsKICAgICAgICAgICAgdW5zZXQoJHJlZlNjaGVtYS0+eyckcmVmJ30pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZWZTY2hlbWE7CiAgICB9Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXFVyaTsKCnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxVcmlSZXNvbHZlckV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVXJpUmVzb2x2ZXJJbnRlcmZhY2U7CgovKioKICogUmVzb2x2ZXMgSlNPTiBTY2hlbWEgVVJJcwogKgogKiBAYXV0aG9yIFNhbmRlciBDb29sZW4gPHNhbmRlckBqaWJiZXIubmw+CiAqLwpjbGFzcyBVcmlSZXNvbHZlciBpbXBsZW1lbnRzIFVyaVJlc29sdmVySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUGFyc2VzIGEgVVJJIGludG8gZml2ZSBtYWluIGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmkKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZSgkdXJpKQogICAgewogICAgICAgIHByZWdfbWF0Y2goJ3xeKChbXjovPyNdKyk6KT8oLy8oW14vPyNdKikpPyhbXj8jXSopKFw/KFteI10qKSk/KCMoLiopKT98JywgJHVyaSwgJG1hdGNoKTsKCiAgICAgICAgJGNvbXBvbmVudHMgPSBhcnJheSgpOwogICAgICAgIGlmICg1IDwgY291bnQoJG1hdGNoKSkgewogICAgICAgICAgICAkY29tcG9uZW50cyA9ICBhcnJheSgKICAgICAgICAgICAgICAgICdzY2hlbWUnICAgID0+ICRtYXRjaFsyXSwKICAgICAgICAgICAgICAgICdhdXRob3JpdHknID0+ICRtYXRjaFs0XSwKICAgICAgICAgICAgICAgICdwYXRoJyAgICAgID0+ICRtYXRjaFs1XQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAoNyA8IGNvdW50KCRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHNbJ3F1ZXJ5J10gPSAkbWF0Y2hbN107CiAgICAgICAgfQogICAgICAgIGlmICg5IDwgY291bnQoJG1hdGNoKSkgewogICAgICAgICAgICAkY29tcG9uZW50c1snZnJhZ21lbnQnXSA9ICRtYXRjaFs5XTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY29tcG9uZW50czsKICAgIH0KCiAgICAvKioKICAgICAqIEJ1aWxkcyBhIFVSSSBiYXNlZCBvbiBuIGFycmF5IHdpdGggdGhlIG1haW4gY29tcG9uZW50cwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkY29tcG9uZW50cwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZW5lcmF0ZShhcnJheSAkY29tcG9uZW50cykKICAgIHsKICAgICAgICAkdXJpID0gJGNvbXBvbmVudHNbJ3NjaGVtZSddIC4gJzovLycKICAgICAgICAgICAgIC4gJGNvbXBvbmVudHNbJ2F1dGhvcml0eSddCiAgICAgICAgICAgICAuICRjb21wb25lbnRzWydwYXRoJ107CgogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdxdWVyeScsICRjb21wb25lbnRzKSAmJiBzdHJsZW4oJGNvbXBvbmVudHNbJ3F1ZXJ5J10pKSB7CiAgICAgICAgICAgICR1cmkgLj0gJz8nIC4gJGNvbXBvbmVudHNbJ3F1ZXJ5J107CiAgICAgICAgfQogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdmcmFnbWVudCcsICRjb21wb25lbnRzKSkgewogICAgICAgICAgICAkdXJpIC49ICcjJyAuICRjb21wb25lbnRzWydmcmFnbWVudCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR1cmk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXNvbHZlKCR1cmksICRiYXNlVXJpID0gbnVsbCkKICAgIHsKICAgICAgICAvLyB0cmVhdCBub24tdXJpIGJhc2UgYXMgbG9jYWwgZmlsZSBwYXRoCiAgICAgICAgaWYgKAogICAgICAgICAgICAhaXNfbnVsbCgkYmFzZVVyaSkgJiYKICAgICAgICAgICAgIWZpbHRlcl92YXIoJGJhc2VVcmksIFxGSUxURVJfVkFMSURBVEVfVVJMKSAmJgogICAgICAgICAgICAhcHJlZ19tYXRjaCgnfF5bXi9dKzovL3x1JywgJGJhc2VVcmkpCiAgICAgICAgKSB7CiAgICAgICAgICAgIGlmIChpc19maWxlKCRiYXNlVXJpKSkgewogICAgICAgICAgICAgICAgJGJhc2VVcmkgPSAnZmlsZTovLycgLiByZWFscGF0aCgkYmFzZVVyaSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpc19kaXIoJGJhc2VVcmkpKSB7CiAgICAgICAgICAgICAgICAkYmFzZVVyaSA9ICdmaWxlOi8vJyAuIHJlYWxwYXRoKCRiYXNlVXJpKSAuICcvJzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRiYXNlVXJpID0gJ2ZpbGU6Ly8nIC4gZ2V0Y3dkKCkgLiAnLycgLiAkYmFzZVVyaTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR1cmkgPT0gJycpIHsKICAgICAgICAgICAgcmV0dXJuICRiYXNlVXJpOwogICAgICAgIH0KCiAgICAgICAgJGNvbXBvbmVudHMgPSAkdGhpcy0+cGFyc2UoJHVyaSk7CiAgICAgICAgJHBhdGggPSAkY29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICBpZiAoIWVtcHR5KCRjb21wb25lbnRzWydzY2hlbWUnXSkpIHsKICAgICAgICAgICAgcmV0dXJuICR1cmk7CiAgICAgICAgfQogICAgICAgICRiYXNlQ29tcG9uZW50cyA9ICR0aGlzLT5wYXJzZSgkYmFzZVVyaSk7CiAgICAgICAgJGJhc2VQYXRoID0gJGJhc2VDb21wb25lbnRzWydwYXRoJ107CgogICAgICAgICRiYXNlQ29tcG9uZW50c1sncGF0aCddID0gc2VsZjo6Y29tYmluZVJlbGF0aXZlUGF0aFdpdGhCYXNlUGF0aCgkcGF0aCwgJGJhc2VQYXRoKTsKICAgICAgICBpZiAoaXNzZXQoJGNvbXBvbmVudHNbJ2ZyYWdtZW50J10pKSB7CiAgICAgICAgICAgICRiYXNlQ29tcG9uZW50c1snZnJhZ21lbnQnXSA9ICRjb21wb25lbnRzWydmcmFnbWVudCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5nZW5lcmF0ZSgkYmFzZUNvbXBvbmVudHMpOwogICAgfQoKICAgIC8qKgogICAgICogVHJpZXMgdG8gZ2x1ZSBhIHJlbGF0aXZlIHBhdGggb250byBhbiBhYnNvbHV0ZSBvbmUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWxhdGl2ZVBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VQYXRoCiAgICAgKgogICAgICogQHRocm93cyBVcmlSZXNvbHZlckV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nIE1lcmdlZCBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY29tYmluZVJlbGF0aXZlUGF0aFdpdGhCYXNlUGF0aCgkcmVsYXRpdmVQYXRoLCAkYmFzZVBhdGgpCiAgICB7CiAgICAgICAgJHJlbGF0aXZlUGF0aCA9IHNlbGY6Om5vcm1hbGl6ZVBhdGgoJHJlbGF0aXZlUGF0aCk7CiAgICAgICAgaWYgKCRyZWxhdGl2ZVBhdGggPT0gJycpIHsKICAgICAgICAgICAgcmV0dXJuICRiYXNlUGF0aDsKICAgICAgICB9CiAgICAgICAgaWYgKCRyZWxhdGl2ZVBhdGhbMF0gPT0gJy8nKSB7CiAgICAgICAgICAgIHJldHVybiAkcmVsYXRpdmVQYXRoOwogICAgICAgIH0KCiAgICAgICAgJGJhc2VQYXRoU2VnbWVudHMgPSBleHBsb2RlKCcvJywgJGJhc2VQYXRoKTsKCiAgICAgICAgcHJlZ19tYXRjaCgnfF4vPyhcLlwuLyg/OlwuLykqKSp8JywgJHJlbGF0aXZlUGF0aCwgJG1hdGNoKTsKICAgICAgICAkbnVtTGV2ZWxVcCA9IHN0cmxlbigkbWF0Y2hbMF0pIC8zICsgMTsKICAgICAgICBpZiAoJG51bUxldmVsVXAgPj0gY291bnQoJGJhc2VQYXRoU2VnbWVudHMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVcmlSZXNvbHZlckV4Y2VwdGlvbihzcHJpbnRmKCJVbmFibGUgdG8gcmVzb2x2ZSBVUkkgJyVzJyBmcm9tIGJhc2UgJyVzJyIsICRyZWxhdGl2ZVBhdGgsICRiYXNlUGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgJGJhc2VQYXRoU2VnbWVudHMgPSBhcnJheV9zbGljZSgkYmFzZVBhdGhTZWdtZW50cywgMCwgLSRudW1MZXZlbFVwKTsKICAgICAgICAkcGF0aCA9IHByZWdfcmVwbGFjZSgnfF4vPyhcLlwuLyhcLi8pKikqfCcsICcnLCAkcmVsYXRpdmVQYXRoKTsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoJy8nLCAkYmFzZVBhdGhTZWdtZW50cykgLiAnLycgLiAkcGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZXMgYSBVUkkgcGF0aCBjb21wb25lbnQgYnkgcmVtb3ZpbmcgZG90LXNsYXNoIGFuZCBkb3VibGUgc2xhc2hlcwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBub3JtYWxpemVQYXRoKCRwYXRoKQogICAgewogICAgICAgICRwYXRoID0gcHJlZ19yZXBsYWNlKCd8KCg/PCFcLilcLi8pKnwnLCAnJywgJHBhdGgpOwogICAgICAgICRwYXRoID0gcHJlZ19yZXBsYWNlKCd8Ly98JywgJy8nLCAkcGF0aCk7CgogICAgICAgIHJldHVybiAkcGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVyaQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWxpZCgkdXJpKQogICAgewogICAgICAgICRjb21wb25lbnRzID0gJHRoaXMtPnBhcnNlKCR1cmkpOwoKICAgICAgICByZXR1cm4gIWVtcHR5KCRjb21wb25lbnRzKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnM7Cgp1c2UgSnNvblNjaGVtYVxWYWxpZGF0b3I7CgovKioKICogVVJJIHJldHJpZXZlZCBiYXNlZCBvbiBhIHByZWRlZmluZWQgYXJyYXkgb2Ygc2NoZW1hcwogKgogKiBAZXhhbXBsZQogKgogKiAgICAgICRyZXRyaWV2ZXIgPSBuZXcgUHJlZGVmaW5lZEFycmF5KGFycmF5KAogKiAgICAgICAgICAnaHR0cDovL2FjbWUuY29tL3NjaGVtYXMvcGVyc29uIycgID0+ICd7IC4uLiB9JywKICogICAgICAgICAgJ2h0dHA6Ly9hY21lLmNvbS9zY2hlbWFzL2FkZHJlc3MjJyA9PiAneyAuLi4gfScsCiAqICAgICAgKSkKICoKICogICAgICAkc2NoZW1hID0gJHJldHJpZXZlci0+cmV0cmlldmUoJ2h0dHA6Ly9hY21lLmNvbS9zY2hlbWFzL3BlcnNvbiMnKTsKICovCmNsYXNzIFByZWRlZmluZWRBcnJheSBleHRlbmRzIEFic3RyYWN0UmV0cmlldmVyCnsKICAgIC8qKgogICAgICogQ29udGFpbnMgc2NoZW1hcyBhcyBVUkkgPT4gSlNPTgogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJpdmF0ZSAkc2NoZW1hczsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAkc2NoZW1hcwogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudFR5cGUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGFycmF5ICRzY2hlbWFzLCAkY29udGVudFR5cGUgPSBWYWxpZGF0b3I6OlNDSEVNQV9NRURJQV9UWVBFKQogICAgewogICAgICAgICR0aGlzLT5zY2hlbWFzICAgICA9ICRzY2hlbWFzOwogICAgICAgICR0aGlzLT5jb250ZW50VHlwZSA9ICRjb250ZW50VHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzXFVyaVJldHJpZXZlckludGVyZmFjZTo6cmV0cmlldmUoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmV0cmlldmUoJHVyaSkKICAgIHsKICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJHVyaSwgJHRoaXMtPnNjaGVtYXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSnNvblNjaGVtYVxFeGNlcHRpb25cUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgJ1RoZSBKU09OIHNjaGVtYSAiJXMiIHdhcyBub3QgZm91bmQuJywKICAgICAgICAgICAgICAgICR1cmkKICAgICAgICAgICAgKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYXNbJHVyaV07CiAgICB9Cn0KPD9waHAKLyoqCiAqIEpzb25TY2hlbWEKICoKICogQGZpbGVzb3VyY2UKICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxVcmlcUmV0cmlldmVyczsKCi8qKgogKiBBYnN0cmFjdFJldHJpZXZlciBpbXBsZW1lbnRzIHRoZSBkZWZhdWx0IHNoYXJlZCBiZWhhdmlvcgogKiB0aGF0IGFsbCBkZXNjZW5kYW50IFJldHJpZXZlcnMgc2hvdWxkIGluaGVyaXQKICoKICogQGF1dGhvciBTdGV2ZW4gR2FyY2lhIDx3ZWJ3aGFtbXlAZ21haWwuY29tPgogKi8KYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RSZXRyaWV2ZXIgaW1wbGVtZW50cyBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBNZWRpYSBjb250ZW50IHR5cGUKICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnRlbnRUeXBlOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcVXJpUmV0cmlldmVySW50ZXJmYWNlOjpnZXRDb250ZW50VHlwZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZW50VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb250ZW50VHlwZTsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnM7Cgp1c2UgSnNvblNjaGVtYVxFeGNlcHRpb25cUnVudGltZUV4Y2VwdGlvbjsKdXNlIEpzb25TY2hlbWFcVmFsaWRhdG9yOwoKLyoqCiAqIFRyaWVzIHRvIHJldHJpZXZlIEpTT04gc2NoZW1hcyBmcm9tIGEgVVJJIHVzaW5nIGNVUkwgbGlicmFyeQogKgogKiBAYXV0aG9yIFNhbmRlciBDb29sZW4gPHNhbmRlckBqaWJiZXIubmw+CiAqLwpjbGFzcyBDdXJsIGV4dGVuZHMgQWJzdHJhY3RSZXRyaWV2ZXIKewogICAgcHJvdGVjdGVkICRtZXNzYWdlQm9keTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgIGlmICghZnVuY3Rpb25fZXhpc3RzKCdjdXJsX2luaXQnKSkgewogICAgICAgICAgICAvLyBDYW5ub3QgdGVzdCB0aGlzLCBiZWNhdXNlIGN1cmxfaW5pdCBpcyBwcmVzZW50IG9uIGFsbCB0ZXN0IHBsYXRmb3JtcyBwbHVzIG1vY2sKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oJ2NVUkwgbm90IGluc3RhbGxlZCcpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcVXJpUmV0cmlldmVySW50ZXJmYWNlOjpyZXRyaWV2ZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpKQogICAgewogICAgICAgICRjaCA9IGN1cmxfaW5pdCgpOwoKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfVVJMLCAkdXJpKTsKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfSEVBREVSLCB0cnVlKTsKICAgICAgICBjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIHRydWUpOwogICAgICAgIGN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9IVFRQSEVBREVSLCBhcnJheSgnQWNjZXB0OiAnIC4gVmFsaWRhdG9yOjpTQ0hFTUFfTUVESUFfVFlQRSkpOwoKICAgICAgICAkcmVzcG9uc2UgPSBjdXJsX2V4ZWMoJGNoKTsKICAgICAgICBpZiAoZmFsc2UgPT09ICRyZXNwb25zZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXEpzb25TY2hlbWFcRXhjZXB0aW9uXFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCcpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmZldGNoTWVzc2FnZUJvZHkoJHJlc3BvbnNlKTsKICAgICAgICAkdGhpcy0+ZmV0Y2hDb250ZW50VHlwZSgkcmVzcG9uc2UpOwoKICAgICAgICBjdXJsX2Nsb3NlKCRjaCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+bWVzc2FnZUJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXNwb25zZSBjVVJMIEhUVFAgcmVzcG9uc2UKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBmZXRjaE1lc3NhZ2VCb2R5KCRyZXNwb25zZSkKICAgIHsKICAgICAgICBwcmVnX21hdGNoKCIvKD86XHJcbil7Mn0oLiopJC9tcyIsICRyZXNwb25zZSwgJG1hdGNoKTsKICAgICAgICAkdGhpcy0+bWVzc2FnZUJvZHkgPSAkbWF0Y2hbMV07CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZXNwb25zZSBjVVJMIEhUVFAgcmVzcG9uc2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgV2hldGhlciB0aGUgQ29udGVudC1UeXBlIGhlYWRlciB3YXMgZm91bmQgb3Igbm90CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaENvbnRlbnRUeXBlKCRyZXNwb25zZSkKICAgIHsKICAgICAgICBpZiAoMCA8IHByZWdfbWF0Y2goIi9Db250ZW50LVR5cGU6KFxWKikvaW1zIiwgJHJlc3BvbnNlLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgICR0aGlzLT5jb250ZW50VHlwZSA9IHRyaW0oJG1hdGNoWzFdKTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgovKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgSnNvblNjaGVtYSBwYWNrYWdlLgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRQogKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS4KICovCgpuYW1lc3BhY2UgSnNvblNjaGVtYVxVcmlcUmV0cmlldmVyczsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIFVSSSByZXRyaWV2ZXJzCiAqCiAqIEBhdXRob3IgU2FuZGVyIENvb2xlbiA8c2FuZGVyQGppYmJlci5ubD4KICovCmludGVyZmFjZSBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSBhIHNjaGVtYSBmcm9tIHRoZSBzcGVjaWZpZWQgVVJJCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJpIFVSSSB0aGF0IHJlc29sdmVzIHRvIGEgSlNPTiBzY2hlbWEKICAgICAqCiAgICAgKiBAdGhyb3dzIFxKc29uU2NoZW1hXEV4Y2VwdGlvblxSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uCiAgICAgKgogICAgICogQHJldHVybiBtaXhlZCBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmV0cmlldmUoJHVyaSk7CgogICAgLyoqCiAgICAgKiBHZXQgbWVkaWEgY29udGVudCB0eXBlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnRlbnRUeXBlKCk7Cn0KPD9waHAKCi8qCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBKc29uU2NoZW1hIHBhY2thZ2UuCiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFCiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLgogKi8KCm5hbWVzcGFjZSBKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzOwoKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXFJlc291cmNlTm90Rm91bmRFeGNlcHRpb247CgovKioKICogVHJpZXMgdG8gcmV0cmlldmUgSlNPTiBzY2hlbWFzIGZyb20gYSBVUkkgdXNpbmcgZmlsZV9nZXRfY29udGVudHMoKQogKgogKiBAYXV0aG9yIFNhbmRlciBDb29sZW4gPHNhbmRlckBqaWJiZXIubmw+CiAqLwpjbGFzcyBGaWxlR2V0Q29udGVudHMgZXh0ZW5kcyBBYnN0cmFjdFJldHJpZXZlcgp7CiAgICBwcm90ZWN0ZWQgJG1lc3NhZ2VCb2R5OwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEpzb25TY2hlbWFcVXJpXFJldHJpZXZlcnNcVXJpUmV0cmlldmVySW50ZXJmYWNlOjpyZXRyaWV2ZSgpCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXRyaWV2ZSgkdXJpKQogICAgewogICAgICAgICRlcnJvck1lc3NhZ2UgPSBudWxsOwogICAgICAgIHNldF9lcnJvcl9oYW5kbGVyKGZ1bmN0aW9uICgkZXJybm8sICRlcnJzdHIpIHVzZSAoJiRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICRlcnJzdHI7CiAgICAgICAgfSk7CiAgICAgICAgJHJlc3BvbnNlID0gZmlsZV9nZXRfY29udGVudHMoJHVyaSk7CiAgICAgICAgcmVzdG9yZV9lcnJvcl9oYW5kbGVyKCk7CgogICAgICAgIGlmICgkZXJyb3JNZXNzYWdlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKCRlcnJvck1lc3NhZ2UpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZhbHNlID09PSAkcmVzcG9uc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCBhdCAnIC4gJHVyaSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHJlc3BvbnNlID09ICcnCiAgICAgICAgICAgICYmIHN1YnN0cigkdXJpLCAwLCA3KSA9PSAnZmlsZTovLycgJiYgc3Vic3RyKCR1cmksIC0xKSA9PSAnLycKICAgICAgICApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oJ0pTT04gc2NoZW1hIG5vdCBmb3VuZCBhdCAnIC4gJHVyaSk7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+bWVzc2FnZUJvZHkgPSAkcmVzcG9uc2U7CiAgICAgICAgaWYgKCFlbXB0eSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpKSB7CiAgICAgICAgICAgIC8vICRodHRwX3Jlc3BvbnNlX2hlYWRlciBjYW5ub3QgYmUgdGVzdGVkLCBiZWNhdXNlIGl0J3MgZGVmaW5lZCBpbiB0aGUgbWV0aG9kJ3MgbG9jYWwgc2NvcGUKICAgICAgICAgICAgLy8gU2VlIGh0dHA6Ly9waHAubmV0L21hbnVhbC9lbi9yZXNlcnZlZC52YXJpYWJsZXMuaHR0cHJlc3BvbnNlaGVhZGVyLnBocCBmb3IgbW9yZSBpbmZvLgogICAgICAgICAgICAkdGhpcy0+ZmV0Y2hDb250ZW50VHlwZSgkaHR0cF9yZXNwb25zZV9oZWFkZXIpOyAvLyBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAgICAgICAgLy8gQ291bGQgYmUgYSAiZmlsZTovLyIgdXJsIG9yIHNvbWV0aGluZyBlbHNlIC0gZmFrZSB1cCB0aGUgcmVzcG9uc2UKICAgICAgICAgICAgJHRoaXMtPmNvbnRlbnRUeXBlID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+bWVzc2FnZUJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGhlYWRlcnMgSFRUUCBSZXNwb25zZSBIZWFkZXJzCiAgICAgKgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgd2FzIGZvdW5kIG9yIG5vdAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZldGNoQ29udGVudFR5cGUoYXJyYXkgJGhlYWRlcnMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGhlYWRlcnMgYXMgJGhlYWRlcikgewogICAgICAgICAgICBpZiAoJHRoaXMtPmNvbnRlbnRUeXBlID0gc2VsZjo6Z2V0Q29udGVudFR5cGVNYXRjaEluSGVhZGVyKCRoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkaGVhZGVyCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldENvbnRlbnRUeXBlTWF0Y2hJbkhlYWRlcigkaGVhZGVyKQogICAgewogICAgICAgIGlmICgwIDwgcHJlZ19tYXRjaCgiL0NvbnRlbnQtVHlwZTooXFYqKS9pbXMiLCAkaGVhZGVyLCAkbWF0Y2gpKSB7CiAgICAgICAgICAgIHJldHVybiB0cmltKCRtYXRjaFsxXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQo8P3BocAoKLyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpzb25TY2hlbWEgcGFja2FnZS4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0UKICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuCiAqLwoKbmFtZXNwYWNlIEpzb25TY2hlbWFcVXJpOwoKdXNlIEpzb25TY2hlbWFcRXhjZXB0aW9uXEludmFsaWRTY2hlbWFNZWRpYVR5cGVFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxKc29uRGVjb2RpbmdFeGNlcHRpb247CnVzZSBKc29uU2NoZW1hXEV4Y2VwdGlvblxSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uOwp1c2UgSnNvblNjaGVtYVxVcmlcUmV0cmlldmVyc1xGaWxlR2V0Q29udGVudHM7CnVzZSBKc29uU2NoZW1hXFVyaVxSZXRyaWV2ZXJzXFVyaVJldHJpZXZlckludGVyZmFjZTsKdXNlIEpzb25TY2hlbWFcVXJpUmV0cmlldmVySW50ZXJmYWNlIGFzIEJhc2VVcmlSZXRyaWV2ZXJJbnRlcmZhY2U7CnVzZSBKc29uU2NoZW1hXFZhbGlkYXRvcjsKCi8qKgogKiBSZXRyaWV2ZXMgSlNPTiBTY2hlbWEgVVJJcwogKgogKiBAYXV0aG9yIFR5bGVyIEFraW5zIDxmaWRpYW5AcnVta2luLmNvbT4KICovCmNsYXNzIFVyaVJldHJpZXZlciBpbXBsZW1lbnRzIEJhc2VVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IE1hcCBvZiBVUkwgdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdHJhbnNsYXRpb25NYXAgPSBhcnJheSgKICAgICAgICAvLyB1c2UgbG9jYWwgY29waWVzIG9mIHRoZSBzcGVjIHNjaGVtYXMKICAgICAgICAnfF5odHRwcz86Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtKDBbMzRdKS9zY2hlbWEjP3wnID0+ICdwYWNrYWdlOi8vZGlzdC9zY2hlbWEvanNvbi1zY2hlbWEtZHJhZnQtJDEuanNvbicKICAgICk7CgogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5IEEgbGlzdCBvZiBlbmRwb2ludHMgZm9yIG1lZGlhIHR5cGUgY2hlY2sgZXhjbHVzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYWxsb3dlZEludmFsaWRDb250ZW50VHlwZUVuZHBvaW50cyA9IGFycmF5KAogICAgICAgICdodHRwOi8vanNvbi1zY2hlbWEub3JnLycsCiAgICAgICAgJ2h0dHBzOi8vanNvbi1zY2hlbWEub3JnLycKICAgICk7CgogICAgLyoqCiAgICAgKiBAdmFyIG51bGx8VXJpUmV0cmlldmVySW50ZXJmYWNlCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdXJpUmV0cmlldmVyID0gbnVsbDsKCiAgICAvKioKICAgICAqIEB2YXIgYXJyYXl8b2JqZWN0W10KICAgICAqCiAgICAgKiBAc2VlIGxvYWRTY2hlbWEKICAgICAqLwogICAgcHJpdmF0ZSAkc2NoZW1hQ2FjaGUgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQWRkcyBhbiBlbmRwb2ludCB0byB0aGUgbWVkaWEgdHlwZSB2YWxpZGF0aW9uIGV4Y2x1c2lvbiBsaXN0CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZW5kcG9pbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEludmFsaWRDb250ZW50VHlwZUVuZHBvaW50KCRlbmRwb2ludCkKICAgIHsKICAgICAgICAkdGhpcy0+YWxsb3dlZEludmFsaWRDb250ZW50VHlwZUVuZHBvaW50c1tdID0gJGVuZHBvaW50OwogICAgfQoKICAgIC8qKgogICAgICogR3VhcmFudGVlIHRoZSBjb3JyZWN0IG1lZGlhIHR5cGUgd2FzIGVuY291bnRlcmVkCiAgICAgKgogICAgICogQHBhcmFtIFVyaVJldHJpZXZlckludGVyZmFjZSAkdXJpUmV0cmlldmVyCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICAgICR1cmkKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8dm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29uZmlybU1lZGlhVHlwZSgkdXJpUmV0cmlldmVyLCAkdXJpKQogICAgewogICAgICAgICRjb250ZW50VHlwZSA9ICR1cmlSZXRyaWV2ZXItPmdldENvbnRlbnRUeXBlKCk7CgogICAgICAgIGlmIChpc19udWxsKCRjb250ZW50VHlwZSkpIHsKICAgICAgICAgICAgLy8gV2VsbCwgd2UgZGlkbid0IGdldCBhbiBpbnZhbGlkIG9uZQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoaW5fYXJyYXkoJGNvbnRlbnRUeXBlLCBhcnJheShWYWxpZGF0b3I6OlNDSEVNQV9NRURJQV9UWVBFLCAnYXBwbGljYXRpb24vanNvbicpKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YWxsb3dlZEludmFsaWRDb250ZW50VHlwZUVuZHBvaW50cyBhcyAkZW5kcG9pbnQpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkdXJpLCAkZW5kcG9pbnQpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRTY2hlbWFNZWRpYVR5cGVFeGNlcHRpb24oc3ByaW50ZignTWVkaWEgdHlwZSAlcyBleHBlY3RlZCcsIFZhbGlkYXRvcjo6U0NIRU1BX01FRElBX1RZUEUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIFVSSSBSZXRyaWV2ZXIKICAgICAqCiAgICAgKiBJZiBub25lIGlzIHNwZWNpZmllZCwgc2V0cyBhIGRlZmF1bHQgRmlsZUdldENvbnRlbnRzIHJldHJpZXZlciBhbmQKICAgICAqIHJldHVybnMgdGhhdCBvYmplY3QuCiAgICAgKgogICAgICogQHJldHVybiBVcmlSZXRyaWV2ZXJJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVyaVJldHJpZXZlcigpCiAgICB7CiAgICAgICAgaWYgKGlzX251bGwoJHRoaXMtPnVyaVJldHJpZXZlcikpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFVyaVJldHJpZXZlcihuZXcgRmlsZUdldENvbnRlbnRzKCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT51cmlSZXRyaWV2ZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNvbHZlIGEgc2NoZW1hIGJhc2VkIG9uIHBvaW50ZXIKICAgICAqCiAgICAgKiBVUklzIGNhbiBoYXZlIGEgZnJhZ21lbnQgYXQgdGhlIGVuZCBpbiB0aGUgZm9ybWF0IG9mCiAgICAgKiAjL3BhdGgvdG8vb2JqZWN0IGFuZCB3ZSBhcmUgdG8gbG9vayB1cCB0aGUgJ3BhdGgnIHByb3BlcnR5IG9mCiAgICAgKiB0aGUgZmlyc3Qgb2JqZWN0IHRoZW4gdGhlICd0bycgYW5kICdvYmplY3QnIHByb3BlcnRpZXMuCiAgICAgKgogICAgICogQHBhcmFtIG9iamVjdCAkanNvblNjaGVtYSBKU09OIFNjaGVtYSBjb250ZW50cwogICAgICogQHBhcmFtIHN0cmluZyAkdXJpICAgICAgICBKU09OIFNjaGVtYSBVUkkKICAgICAqCiAgICAgKiBAdGhyb3dzIFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdCBKU09OIFNjaGVtYSBhZnRlciB3YWxraW5nIGRvd24gdGhlIGZyYWdtZW50IHBpZWNlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzb2x2ZVBvaW50ZXIoJGpzb25TY2hlbWEsICR1cmkpCiAgICB7CiAgICAgICAgJHJlc29sdmVyID0gbmV3IFVyaVJlc29sdmVyKCk7CiAgICAgICAgJHBhcnNlZCA9ICRyZXNvbHZlci0+cGFyc2UoJHVyaSk7CiAgICAgICAgaWYgKGVtcHR5KCRwYXJzZWRbJ2ZyYWdtZW50J10pKSB7CiAgICAgICAgICAgIHJldHVybiAkanNvblNjaGVtYTsKICAgICAgICB9CgogICAgICAgICRwYXRoID0gZXhwbG9kZSgnLycsICRwYXJzZWRbJ2ZyYWdtZW50J10pOwogICAgICAgIHdoaWxlICgkcGF0aCkgewogICAgICAgICAgICAkcGF0aEVsZW1lbnQgPSBhcnJheV9zaGlmdCgkcGF0aCk7CiAgICAgICAgICAgIGlmICghZW1wdHkoJHBhdGhFbGVtZW50KSkgewogICAgICAgICAgICAgICAgJHBhdGhFbGVtZW50ID0gc3RyX3JlcGxhY2UoJ34xJywgJy8nLCAkcGF0aEVsZW1lbnQpOwogICAgICAgICAgICAgICAgJHBhdGhFbGVtZW50ID0gc3RyX3JlcGxhY2UoJ34wJywgJ34nLCAkcGF0aEVsZW1lbnQpOwogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkanNvblNjaGVtYS0+JHBhdGhFbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICRqc29uU2NoZW1hID0gJGpzb25TY2hlbWEtPiRwYXRoRWxlbWVudDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdGcmFnbWVudCAiJyAuICRwYXJzZWRbJ2ZyYWdtZW50J10gLiAnIiBub3QgZm91bmQnCiAgICAgICAgICAgICAgICAgICAgICAgIC4gJyBpbiAnIC4gJHVyaQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFpc19vYmplY3QoJGpzb25TY2hlbWEpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICdGcmFnbWVudCBwYXJ0ICInIC4gJHBhdGhFbGVtZW50IC4gJyIgaXMgbm8gb2JqZWN0ICcKICAgICAgICAgICAgICAgICAgICAgICAgLiAnIGluICcgLiAkdXJpCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uU2NoZW1hOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmV0cmlldmUoJHVyaSwgJGJhc2VVcmkgPSBudWxsLCAkdHJhbnNsYXRlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkcmVzb2x2ZXIgPSBuZXcgVXJpUmVzb2x2ZXIoKTsKICAgICAgICAkcmVzb2x2ZWRVcmkgPSAkZmV0Y2hVcmkgPSAkcmVzb2x2ZXItPnJlc29sdmUoJHVyaSwgJGJhc2VVcmkpOwoKICAgICAgICAvL2ZldGNoIFVSTCB3aXRob3V0ICNmcmFnbWVudAogICAgICAgICRhclBhcnRzID0gJHJlc29sdmVyLT5wYXJzZSgkcmVzb2x2ZWRVcmkpOwogICAgICAgIGlmIChpc3NldCgkYXJQYXJ0c1snZnJhZ21lbnQnXSkpIHsKICAgICAgICAgICAgdW5zZXQoJGFyUGFydHNbJ2ZyYWdtZW50J10pOwogICAgICAgICAgICAkZmV0Y2hVcmkgPSAkcmVzb2x2ZXItPmdlbmVyYXRlKCRhclBhcnRzKTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGx5IFVSSSB0cmFuc2xhdGlvbnMKICAgICAgICBpZiAoJHRyYW5zbGF0ZSkgewogICAgICAgICAgICAkZmV0Y2hVcmkgPSAkdGhpcy0+dHJhbnNsYXRlKCRmZXRjaFVyaSk7CiAgICAgICAgfQoKICAgICAgICAkanNvblNjaGVtYSA9ICR0aGlzLT5sb2FkU2NoZW1hKCRmZXRjaFVyaSk7CgogICAgICAgIC8vIFVzZSB0aGUgSlNPTiBwb2ludGVyIGlmIHNwZWNpZmllZAogICAgICAgICRqc29uU2NoZW1hID0gJHRoaXMtPnJlc29sdmVQb2ludGVyKCRqc29uU2NoZW1hLCAkcmVzb2x2ZWRVcmkpOwoKICAgICAgICBpZiAoJGpzb25TY2hlbWEgaW5zdGFuY2VvZiBcc3RkQ2xhc3MpIHsKICAgICAgICAgICAgJGpzb25TY2hlbWEtPmlkID0gJHJlc29sdmVkVXJpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRqc29uU2NoZW1hOwogICAgfQoKICAgIC8qKgogICAgICogRmV0Y2ggYSBzY2hlbWEgZnJvbSB0aGUgZ2l2ZW4gVVJJLCBqc29uLWRlY29kZSBpdCBhbmQgcmV0dXJuIGl0LgogICAgICogQ2FjaGVzIHNjaGVtYSBvYmplY3RzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZldGNoVXJpIEFic29sdXRlIFVSSQogICAgICoKICAgICAqIEByZXR1cm4gb2JqZWN0IEpTT04gc2NoZW1hIG9iamVjdAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gbG9hZFNjaGVtYSgkZmV0Y2hVcmkpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5zY2hlbWFDYWNoZVskZmV0Y2hVcmldKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnNjaGVtYUNhY2hlWyRmZXRjaFVyaV07CiAgICAgICAgfQoKICAgICAgICAkdXJpUmV0cmlldmVyID0gJHRoaXMtPmdldFVyaVJldHJpZXZlcigpOwogICAgICAgICRjb250ZW50cyA9ICR0aGlzLT51cmlSZXRyaWV2ZXItPnJldHJpZXZlKCRmZXRjaFVyaSk7CiAgICAgICAgJHRoaXMtPmNvbmZpcm1NZWRpYVR5cGUoJHVyaVJldHJpZXZlciwgJGZldGNoVXJpKTsKICAgICAgICAkanNvblNjaGVtYSA9IGpzb25fZGVjb2RlKCRjb250ZW50cyk7CgogICAgICAgIGlmIChKU09OX0VSUk9SX05PTkUgPCAkZXJyb3IgPSBqc29uX2xhc3RfZXJyb3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSnNvbkRlY29kaW5nRXhjZXB0aW9uKCRlcnJvcik7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2NoZW1hQ2FjaGVbJGZldGNoVXJpXSA9ICRqc29uU2NoZW1hOwoKICAgICAgICByZXR1cm4gJGpzb25TY2hlbWE7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIFVSSSBSZXRyaWV2ZXIKICAgICAqCiAgICAgKiBAcGFyYW0gVXJpUmV0cmlldmVySW50ZXJmYWNlICR1cmlSZXRyaWV2ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzIGZvciBjaGFpbmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXJpUmV0cmlldmVyKFVyaVJldHJpZXZlckludGVyZmFjZSAkdXJpUmV0cmlldmVyKQogICAgewogICAgICAgICR0aGlzLT51cmlSZXRyaWV2ZXIgPSAkdXJpUmV0cmlldmVyOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBVUkkgaW50byBmaXZlIG1haW4gY29tcG9uZW50cwogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVyaQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHBhcnNlKCR1cmkpCiAgICB7CiAgICAgICAgcHJlZ19tYXRjaCgnfF4oKFteOi8/I10rKTopPygvLyhbXi8/I10qKSk/KFtePyNdKikoXD8oW14jXSopKT8oIyguKikpP3wnLCAkdXJpLCAkbWF0Y2gpOwoKICAgICAgICAkY29tcG9uZW50cyA9IGFycmF5KCk7CiAgICAgICAgaWYgKDUgPCBjb3VudCgkbWF0Y2gpKSB7CiAgICAgICAgICAgICRjb21wb25lbnRzID0gIGFycmF5KAogICAgICAgICAgICAgICAgJ3NjaGVtZScgICAgPT4gJG1hdGNoWzJdLAogICAgICAgICAgICAgICAgJ2F1dGhvcml0eScgPT4gJG1hdGNoWzRdLAogICAgICAgICAgICAgICAgJ3BhdGgnICAgICAgPT4gJG1hdGNoWzVdCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoNyA8IGNvdW50KCRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHNbJ3F1ZXJ5J10gPSAkbWF0Y2hbN107CiAgICAgICAgfQoKICAgICAgICBpZiAoOSA8IGNvdW50KCRtYXRjaCkpIHsKICAgICAgICAgICAgJGNvbXBvbmVudHNbJ2ZyYWdtZW50J10gPSAkbWF0Y2hbOV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGNvbXBvbmVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZHMgYSBVUkkgYmFzZWQgb24gbiBhcnJheSB3aXRoIHRoZSBtYWluIGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGNvbXBvbmVudHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2VuZXJhdGUoYXJyYXkgJGNvbXBvbmVudHMpCiAgICB7CiAgICAgICAgJHVyaSA9ICRjb21wb25lbnRzWydzY2hlbWUnXSAuICc6Ly8nCiAgICAgICAgICAgICAuICRjb21wb25lbnRzWydhdXRob3JpdHknXQogICAgICAgICAgICAgLiAkY29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygncXVlcnknLCAkY29tcG9uZW50cykpIHsKICAgICAgICAgICAgJHVyaSAuPSAkY29tcG9uZW50c1sncXVlcnknXTsKICAgICAgICB9CgogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdmcmFnbWVudCcsICRjb21wb25lbnRzKSkgewogICAgICAgICAgICAkdXJpIC49ICRjb21wb25lbnRzWydmcmFnbWVudCddOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR1cmk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXNvbHZlcyBhIFVSSQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVyaSAgICAgQWJzb2x1dGUgb3IgcmVsYXRpdmUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJhc2VVcmkgT3B0aW9uYWwgYmFzZSBVUkkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzb2x2ZSgkdXJpLCAkYmFzZVVyaSA9IG51bGwpCiAgICB7CiAgICAgICAgJGNvbXBvbmVudHMgPSAkdGhpcy0+cGFyc2UoJHVyaSk7CiAgICAgICAgJHBhdGggPSAkY29tcG9uZW50c1sncGF0aCddOwoKICAgICAgICBpZiAoKGFycmF5X2tleV9leGlzdHMoJ3NjaGVtZScsICRjb21wb25lbnRzKSkgJiYgKCdodHRwJyA9PT0gJGNvbXBvbmVudHNbJ3NjaGVtZSddKSkgewogICAgICAgICAgICByZXR1cm4gJHVyaTsKICAgICAgICB9CgogICAgICAgICRiYXNlQ29tcG9uZW50cyA9ICR0aGlzLT5wYXJzZSgkYmFzZVVyaSk7CiAgICAgICAgJGJhc2VQYXRoID0gJGJhc2VDb21wb25lbnRzWydwYXRoJ107CgogICAgICAgICRiYXNlQ29tcG9uZW50c1sncGF0aCddID0gVXJpUmVzb2x2ZXI6OmNvbWJpbmVSZWxhdGl2ZVBhdGhXaXRoQmFzZVBhdGgoJHBhdGgsICRiYXNlUGF0aCk7CgogICAgICAgIHJldHVybiAkdGhpcy0+Z2VuZXJhdGUoJGJhc2VDb21wb25lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVyaQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNWYWxpZCgkdXJpKQogICAgewogICAgICAgICRjb21wb25lbnRzID0gJHRoaXMtPnBhcnNlKCR1cmkpOwoKICAgICAgICByZXR1cm4gIWVtcHR5KCRjb21wb25lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIFVSTCB0cmFuc2xhdGlvbiBydWxlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFuc2xhdGlvbigkZnJvbSwgJHRvKQogICAgewogICAgICAgICR0aGlzLT50cmFuc2xhdGlvbk1hcFskZnJvbV0gPSAkdG87CiAgICB9CgogICAgLyoqCiAgICAgKiBBcHBseSBVUkkgdHJhbnNsYXRpb24gcnVsZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHRyYW5zbGF0ZSgkdXJpKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0aGlzLT50cmFuc2xhdGlvbk1hcCBhcyAkZnJvbSA9PiAkdG8pIHsKICAgICAgICAgICAgJHVyaSA9IHByZWdfcmVwbGFjZSgkZnJvbSwgJHRvLCAkdXJpKTsKICAgICAgICB9CgogICAgICAgIC8vIHRyYW5zbGF0ZSByZWZlcmVuY2VzIHRvIGxvY2FsIGZpbGVzIHdpdGhpbiB0aGUganNvbi1zY2hlbWEgcGFja2FnZQogICAgICAgICR1cmkgPSBwcmVnX3JlcGxhY2UoJ3xecGFja2FnZTovL3wnLCBzcHJpbnRmKCdmaWxlOi8vJXMvJywgcmVhbHBhdGgoX19ESVJfXyAuICcvLi4vLi4vLi4nKSksICR1cmkpOwoKICAgICAgICByZXR1cm4gJHVyaTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzOwoKdXNlIEV4Y2VwdGlvbjsKCi8qKgogKiBNYWluIGNsYXNzIHRvIGNvbnZlcnQgdGhlIHBsdXJhbCBydWxlcyBvZiBhIGxhbmd1YWdlIGZyb20gQ0xEUiB0byBnZXR0ZXh0LgogKi8KY2xhc3MgTGFuZ3VhZ2UKewogICAgLyoqCiAgICAgKiBUaGUgbGFuZ3VhZ2UgSUQuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRpZDsKCiAgICAvKioKICAgICAqIFRoZSBsYW5ndWFnZSBuYW1lLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkbmFtZTsKCiAgICAvKioKICAgICAqIElmIHRoaXMgbGFuZ3VhZ2UgaXMgZGVwcmVjYXRlZDogdGhlIGdldHRleHQgY29kZSBvZiB0aGUgbmV3IGxhbmd1YWdlLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljICRzdXBlcnNlZGVkQnk7CgogICAgLyoqCiAgICAgKiBUaGUgc2NyaXB0IG5hbWUuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgJHNjcmlwdDsKCiAgICAvKioKICAgICAqIFRoZSB0ZXJyaXRvcnkgbmFtZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyAkdGVycml0b3J5OwoKICAgIC8qKgogICAgICogVGhlIG5hbWUgb2YgdGhlIGJhc2UgbGFuZ3VhZ2UuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgJGJhc2VMYW5ndWFnZTsKCiAgICAvKioKICAgICAqIFRoZSBsaXN0IG9mIGNhdGVnb3JpZXMuCiAgICAgKgogICAgICogQHZhciBcR2V0dGV4dFxMYW5ndWFnZXNcQ2F0ZWdvcnlbXQogICAgICovCiAgICBwdWJsaWMgJGNhdGVnb3JpZXM7CgogICAgLyoqCiAgICAgKiBUaGUgZ2V0dGV4dCBmb3JtdWxhIHRvIGRlY2lkZSB3aGljaCBjYXRlZ29yeSBzaG91bGQgYmUgYXBwbGllZC4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJGZvcm11bGE7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIHRoZSBpbnN0YW5jZSBhbmQgcGFyc2UgdGhlIGxhbmd1YWdlIGNvZGUuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRpbmZvIFRoZSByZXN1bHQgb2YgQ2xkckRhdGE6OmdldExhbmd1YWdlSW5mbygpCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIHRocm93cyBhbiBFeGNlcHRpb24gaWYgJGZ1bGxJZCBpcyBub3QgdmFsaWQKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaW5mbykKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaW5mb1snaWQnXTsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRpbmZvWyduYW1lJ107CiAgICAgICAgJHRoaXMtPnN1cGVyc2VkZWRCeSA9IGlzc2V0KCRpbmZvWydzdXBlcnNlZGVkQnknXSkgPyAkaW5mb1snc3VwZXJzZWRlZEJ5J10gOiBudWxsOwogICAgICAgICR0aGlzLT5zY3JpcHQgPSBpc3NldCgkaW5mb1snc2NyaXB0J10pID8gJGluZm9bJ3NjcmlwdCddIDogbnVsbDsKICAgICAgICAkdGhpcy0+dGVycml0b3J5ID0gaXNzZXQoJGluZm9bJ3RlcnJpdG9yeSddKSA/ICRpbmZvWyd0ZXJyaXRvcnknXSA6IG51bGw7CiAgICAgICAgJHRoaXMtPmJhc2VMYW5ndWFnZSA9IGlzc2V0KCRpbmZvWydiYXNlTGFuZ3VhZ2UnXSkgPyAkaW5mb1snYmFzZUxhbmd1YWdlJ10gOiBudWxsOwogICAgICAgIC8vIExldCdzIGJ1aWxkIHRoZSBjYXRlZ29yeSBsaXN0CiAgICAgICAgJHRoaXMtPmNhdGVnb3JpZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRpbmZvWydjYXRlZ29yaWVzJ10gYXMgJGNsZHJDYXRlZ29yeUlkID0+ICRjbGRyRm9ybXVsYUFuZEV4YW1wbGVzKSB7CiAgICAgICAgICAgICRjYXRlZ29yeSA9IG5ldyBDYXRlZ29yeSgkY2xkckNhdGVnb3J5SWQsICRjbGRyRm9ybXVsYUFuZEV4YW1wbGVzKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGMpIHsKICAgICAgICAgICAgICAgIGlmICgkY2F0ZWdvcnktPmlkID09PSAkYy0+aWQpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgY2F0ZWdvcnkgJ3skY2F0ZWdvcnktPmlkfScgaXMgc3BlY2lmaWVkIG1vcmUgdGhhbiBvbmNlIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmNhdGVnb3JpZXNbXSA9ICRjYXRlZ29yeTsKICAgICAgICB9CiAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5jYXRlZ29yaWVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgbGFuZ3VhZ2UgJ3skaW5mb1snaWQnXX0nIGRvZXMgbm90IGhhdmUgYW55IHBsdXJhbCBjYXRlZ29yeSIpOwogICAgICAgIH0KICAgICAgICAvLyBMZXQncyBzb3J0IHRoZSBjYXRlZ29yaWVzIGZyb20gJ3plcm8nIHRvICdvdGhlcicKICAgICAgICB1c29ydCgkdGhpcy0+Y2F0ZWdvcmllcywgZnVuY3Rpb24gKENhdGVnb3J5ICRjYXRlZ29yeTEsIENhdGVnb3J5ICRjYXRlZ29yeTIpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5X3NlYXJjaCgkY2F0ZWdvcnkxLT5pZCwgQ2xkckRhdGE6OiRjYXRlZ29yaWVzKSAtIGFycmF5X3NlYXJjaCgkY2F0ZWdvcnkyLT5pZCwgQ2xkckRhdGE6OiRjYXRlZ29yaWVzKTsKICAgICAgICB9KTsKICAgICAgICAvLyBUaGUgJ290aGVyJyBjYXRlZ29yeSBzaG91bGQgYWx3YXlzIGJlIHRoZXJlCiAgICAgICAgaWYgKCR0aGlzLT5jYXRlZ29yaWVzW2NvdW50KCR0aGlzLT5jYXRlZ29yaWVzKSAtIDFdLT5pZCAhPT0gQ2xkckRhdGE6Ok9USEVSX0NBVEVHT1JZKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBsYW5ndWFnZSAneyRpbmZvWydpZCddfScgZG9lcyBub3QgaGF2ZSB0aGUgJyIgLiBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlkgLiAiJyBwbHVyYWwgY2F0ZWdvcnkiKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNoZWNrQWx3YXlzVHJ1ZUNhdGVnb3JpZXMoKTsKICAgICAgICAkdGhpcy0+Y2hlY2tBbHdheXNGYWxzZUNhdGVnb3JpZXMoKTsKICAgICAgICAkdGhpcy0+Y2hlY2tBbGxDYXRlZ29yaWVzV2l0aEV4YW1wbGVzKCk7CiAgICAgICAgJHRoaXMtPmZvcm11bGEgPSAkdGhpcy0+YnVpbGRGb3JtdWxhKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBsYW5ndWFnZXMgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gXEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRBbGwoKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKGFycmF5X2tleXMoQ2xkckRhdGE6OmdldExhbmd1YWdlTmFtZXMoKSkgYXMgJGNsZHJMYW5ndWFnZUlkKSB7CiAgICAgICAgICAgICRyZXN1bHRbXSA9IG5ldyBzZWxmKENsZHJEYXRhOjpnZXRMYW5ndWFnZUluZm8oJGNsZHJMYW5ndWFnZUlkKSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIExhbmd1YWdlIGluc3RhbmNlIGdpdmVuIHRoZSBsYW5ndWFnZSBpZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRpZAogICAgICoKICAgICAqIEByZXR1cm4gXEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRCeUlkKCRpZCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gbnVsbDsKICAgICAgICAkaW5mbyA9IENsZHJEYXRhOjpnZXRMYW5ndWFnZUluZm8oJGlkKTsKICAgICAgICBpZiAoaXNzZXQoJGluZm8pKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBuZXcgc2VsZigkaW5mbyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjbG9uZSBvZiB0aGlzIGluc3RhbmNlIHdpdGggYWxsIHRoZSBzdHJpbmdzIHRvIFVTLUFTQ0lJLgogICAgICoKICAgICAqIEByZXR1cm4gXEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVU0FzY2lpQ2xvbmUoKQogICAgewogICAgICAgICRjbG9uZSA9IGNsb25lICR0aGlzOwogICAgICAgIHNlbGY6OmFzY2lpZmllcigkY2xvbmUtPm5hbWUpOwogICAgICAgIHNlbGY6OmFzY2lpZmllcigkY2xvbmUtPmZvcm11bGEpOwogICAgICAgICRjbG9uZS0+Y2F0ZWdvcmllcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgICRjYXRlZ29yeUNsb25lID0gY2xvbmUgJGNhdGVnb3J5OwogICAgICAgICAgICBzZWxmOjphc2NpaWZpZXIoJGNhdGVnb3J5Q2xvbmUtPmV4YW1wbGVzKTsKICAgICAgICAgICAgJGNsb25lLT5jYXRlZ29yaWVzW10gPSAkY2F0ZWdvcnlDbG9uZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY2xvbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBCdWlsZCB0aGUgZm9ybXVsYSBzdGFydGluZyBmcm9tIHRoZSBjdXJyZW50bHkgZGVmaW5lZCBjYXRlZ29yaWVzLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICR3aXRob3V0UGFyZW50aGVzaXMgVFJVRSB0byBidWlsZCBhIGZvcm11bGEgaW4gc3RhbmRhcmQgZ2V0dGV4dCBmb3JtYXQsIEZBTFNFIChkZWZhdWx0KSB0byBidWlsZCBhIFBIUC1jb21wYXRpYmxlIGZvcm11bGEKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYnVpbGRGb3JtdWxhKCR3aXRob3V0UGFyZW50aGVzaXMgPSBmYWxzZSkKICAgIHsKICAgICAgICAkbnVtQ2F0ZWdvcmllcyA9IGNvdW50KCR0aGlzLT5jYXRlZ29yaWVzKTsKICAgICAgICBzd2l0Y2ggKCRudW1DYXRlZ29yaWVzKSB7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgIC8vIEp1c3Qgb25lIGNhdGVnb3J5CiAgICAgICAgICAgICAgICByZXR1cm4gJzAnOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZjo6cmVkdWNlRm9ybXVsYShzZWxmOjpyZXZlcnNlRm9ybXVsYSgkdGhpcy0+Y2F0ZWdvcmllc1swXS0+Zm9ybXVsYSkpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJGZvcm11bGEgPSAoc3RyaW5nKSAoJG51bUNhdGVnb3JpZXMgLSAxKTsKICAgICAgICAgICAgICAgIGZvciAoJGkgPSAkbnVtQ2F0ZWdvcmllcyAtIDI7ICRpID49IDA7ICRpLS0pIHsKICAgICAgICAgICAgICAgICAgICAkZiA9IHNlbGY6OnJlZHVjZUZvcm11bGEoJHRoaXMtPmNhdGVnb3JpZXNbJGldLT5mb3JtdWxhKTsKICAgICAgICAgICAgICAgICAgICBpZiAoISR3aXRob3V0UGFyZW50aGVzaXMgJiYgIXByZWdfbWF0Y2goJy9eXChbXigpXStcKSQvJywgJGYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmID0gIigke2Z9KSI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRmb3JtdWxhID0gIiR7Zn0gPyAke2l9IDogJHtmb3JtdWxhfSI7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkd2l0aG91dFBhcmVudGhlc2lzICYmICRpID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkZm9ybXVsYSA9ICIoJHtmb3JtdWxhfSkiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJGZvcm11bGE7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTGV0J3MgbG9vayBmb3IgY2F0ZWdvcmllcyB0aGF0IHdpbGwgYWx3YXlzIG9jY3VyLgogICAgICogVGhpcyBiZWNhdXNlIHdpdGggZGVjaW1hbHMgKENMRFIpIHdlIG1heSBoYXZlIG1vcmUgY2FzZXMsIHdpdGggaW50ZWdlcnMgKGdldHRleHQpIHdlIGhhdmUganVzdCBvbmUgY2FzZS4KICAgICAqIElmIHdlIGZvdW5kIHRoYXQgKHNpbmdsZSkgY2F0ZWdvcnkgd2UgcmVkdWNlIHRoZSBjYXRlZ29yaWVzIHRvIHRoYXQgb25lIG9ubHkuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tBbHdheXNUcnVlQ2F0ZWdvcmllcygpCiAgICB7CiAgICAgICAgJGFsd2F5c1RydWVDYXRlZ29yeSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgIGlmICgkY2F0ZWdvcnktPmZvcm11bGEgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGNhdGVnb3J5LT5leGFtcGxlcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgY2F0ZWdvcnkgJ3skY2F0ZWdvcnktPmlkfScgc2hvdWxkIGFsd2F5cyBvY2N1ciwgYnV0IGl0IGRvZXMgbm90IGhhdmUgZXhhbXBsZXMgKHNvIGZvciBDTERSIGl0IHdpbGwgbmV2ZXIgb2NjdXIgZm9yIGludGVnZXJzISkiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRhbHdheXNUcnVlQ2F0ZWdvcnkgPSAkY2F0ZWdvcnk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGFsd2F5c1RydWVDYXRlZ29yeSkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgICAgICBpZiAoKCRjYXRlZ29yeSAhPT0gJGFsd2F5c1RydWVDYXRlZ29yeSkgJiYgaXNzZXQoJGNhdGVnb3J5LT5leGFtcGxlcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgY2F0ZWdvcnkgJ3skY2F0ZWdvcnktPmlkfScgc2hvdWxkIG5ldmVyIG9jY3VyLCBidXQgaXQgaGFzIHNvbWUgZXhhbXBsZXMgKHNvIGZvciBDTERSIGl0IHdpbGwgb2NjdXIhKSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRhbHdheXNUcnVlQ2F0ZWdvcnktPmlkID0gQ2xkckRhdGE6Ok9USEVSX0NBVEVHT1JZOwogICAgICAgICAgICAkYWx3YXlzVHJ1ZUNhdGVnb3J5LT5mb3JtdWxhID0gbnVsbDsKICAgICAgICAgICAgJHRoaXMtPmNhdGVnb3JpZXMgPSBhcnJheSgkYWx3YXlzVHJ1ZUNhdGVnb3J5KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBMZXQncyBsb29rIGZvciBjYXRlZ29yaWVzIHRoYXQgd2lsbCBuZXZlciBvY2N1ci4KICAgICAqIFRoaXMgYmVjYXVzZSB3aXRoIGRlY2ltYWxzIChDTERSKSB3ZSBtYXkgaGF2ZSBtb3JlIGNhc2VzLCB3aXRoIGludGVnZXJzIChnZXR0ZXh0KSB3ZSBoYXZlIHNvbWUgbGVzcyBjYXNlcy4KICAgICAqIElmIHdlIGZvdW5kIHRob3NlIGNhdGVnb3JpZXMgd2Ugc3RyaXAgdGhlbSBvdXQuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tBbHdheXNGYWxzZUNhdGVnb3JpZXMoKQogICAgewogICAgICAgICRmaWx0ZXJlZCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgIGlmICgkY2F0ZWdvcnktPmZvcm11bGEgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGNhdGVnb3J5LT5leGFtcGxlcykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgY2F0ZWdvcnkgJ3skY2F0ZWdvcnktPmlkfScgc2hvdWxkIG5ldmVyIG9jY3VyLCBidXQgaXQgaGFzIGV4YW1wbGVzIChzbyBmb3IgQ0xEUiBpdCBtYXkgb2NjdXIhKSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGZpbHRlcmVkW10gPSAkY2F0ZWdvcnk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNhdGVnb3JpZXMgPSAkZmlsdGVyZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBMZXQncyBsb29rIGZvciBjYXRlZ29yaWVzIHRoYXQgZG9uJ3QgaGF2ZSBleGFtcGxlcy4KICAgICAqIFRoaXMgYmVjYXVzZSB3aXRoIGRlY2ltYWxzIChDTERSKSB3ZSBtYXkgaGF2ZSBtb3JlIGNhc2VzLCB3aXRoIGludGVnZXJzIChnZXR0ZXh0KSB3ZSBoYXZlIHNvbWUgbGVzcyBjYXNlcy4KICAgICAqIElmIHdlIGZvdW5kIHRob3NlIGNhdGVnb3JpZXMsIHdlIGNoZWNrIHRoYXQgdGhleSBuZXZlciBvY2N1ciBhbmQgd2Ugc3RyaXAgdGhlbSBvdXQuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2hlY2tBbGxDYXRlZ29yaWVzV2l0aEV4YW1wbGVzKCkKICAgIHsKICAgICAgICAkYWxsQ2F0ZWdvcmllc0lkcyA9IGFycmF5KCk7CiAgICAgICAgJGdvb2RDYXRlZ29yaWVzID0gYXJyYXkoKTsKICAgICAgICAkYmFkQ2F0ZWdvcmllcyA9IGFycmF5KCk7CiAgICAgICAgJGJhZENhdGVnb3JpZXNJZHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5jYXRlZ29yaWVzIGFzICRjYXRlZ29yeSkgewogICAgICAgICAgICAkYWxsQ2F0ZWdvcmllc0lkc1tdID0gJGNhdGVnb3J5LT5pZDsKICAgICAgICAgICAgaWYgKGlzc2V0KCRjYXRlZ29yeS0+ZXhhbXBsZXMpKSB7CiAgICAgICAgICAgICAgICAkZ29vZENhdGVnb3JpZXNbXSA9ICRjYXRlZ29yeTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRiYWRDYXRlZ29yaWVzW10gPSAkY2F0ZWdvcnk7CiAgICAgICAgICAgICAgICAkYmFkQ2F0ZWdvcmllc0lkc1tdID0gJGNhdGVnb3J5LT5pZDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJGJhZENhdGVnb3JpZXMpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHJlbW92ZUNhdGVnb3JpZXNXaXRob3V0RXhhbXBsZXMgPSBmYWxzZTsKICAgICAgICBzd2l0Y2ggKGltcGxvZGUoJywnLCAkYmFkQ2F0ZWdvcmllc0lkcykgLiAnQCcgLiBpbXBsb2RlKCcsJywgJGFsbENhdGVnb3JpZXNJZHMpKSB7CiAgICAgICAgICAgIGNhc2UgQ2xkckRhdGE6Ok9USEVSX0NBVEVHT1JZIC4gJ0BvbmUsZmV3LG1hbnksJyAuIENsZHJEYXRhOjpPVEhFUl9DQVRFR09SWToKICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPmJ1aWxkRm9ybXVsYSgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnKG4gJSAxMCA9PSAxICYmIG4gJSAxMDAgIT0gMTEpID8gMCA6ICgobiAlIDEwID49IDIgJiYgbiAlIDEwIDw9IDQgJiYgKG4gJSAxMDAgPCAxMiB8fCBuICUgMTAwID4gMTQpKSA/IDEgOiAoKG4gJSAxMCA9PSAwIHx8IG4gJSAxMCA+PSA1ICYmIG4gJSAxMCA8PSA5IHx8IG4gJSAxMDAgPj0gMTEgJiYgbiAlIDEwMCA8PSAxNCkgPyAyIDogMykpJzoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAwICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxIGJ1dCBub3Qgd2l0aCAxMSA9PiBjYXNlIDAgKCdvbmUnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDExICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDIgYnV0IG5vdCB3aXRoIDEyID0+IGNhc2UgMSAoJ2ZldycpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMTIgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMyBidXQgbm90IHdpdGggMTMgPT4gY2FzZSAxICgnZmV3JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxMyAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCA0IGJ1dCBub3Qgd2l0aCAxNCA9PiBjYXNlIDEgKCdmZXcnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDE0ICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDUgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDYgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDcgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDggICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDkgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyA9PiB0aGUgJ290aGVyJyBjYXNlIG5ldmVyIG9jY3VyczogdXNlICdvdGhlcicgZm9yICdtYW55JwogICAgICAgICAgICAgICAgICAgICAgICAkcmVtb3ZlQ2F0ZWdvcmllc1dpdGhvdXRFeGFtcGxlcyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJyhuID09IDEpID8gMCA6ICgobiAlIDEwID49IDIgJiYgbiAlIDEwIDw9IDQgJiYgKG4gJSAxMDAgPCAxMiB8fCBuICUgMTAwID4gMTQpKSA/IDEgOiAoKG4gIT0gMSAmJiAobiAlIDEwID09IDAgfHwgbiAlIDEwID09IDEpIHx8IG4gJSAxMCA+PSA1ICYmIG4gJSAxMCA8PSA5IHx8IG4gJSAxMDAgPj0gMTIgJiYgbiAlIDEwMCA8PSAxNCkgPyAyIDogMykpJzoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAwICAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMSBidXQgbm90IG51bWJlciAxID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXIgMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiBjYXNlIDAgKCdvbmUnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDIgYnV0IG5vdCB3aXRoIDEyICA9PiBjYXNlIDEgKCdmZXcnKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDEyICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAzIGJ1dCBub3Qgd2l0aCAxMyAgPT4gY2FzZSAxICgnZmV3JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCAxMyAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNCBidXQgbm90IHdpdGggMTQgID0+IGNhc2UgMSAoJ2ZldycpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggMTQgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDUgICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCA2ICAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlcnMgZW5kaW5nIHdpdGggNyAgICAgICAgICAgICAgICAgID0+IGNhc2UgMiAoJ21hbnknKQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOdW1iZXJzIGVuZGluZyB3aXRoIDggICAgICAgICAgICAgICAgICA9PiBjYXNlIDIgKCdtYW55JykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyBlbmRpbmcgd2l0aCA5ICAgICAgICAgICAgICAgICAgPT4gY2FzZSAyICgnbWFueScpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vID0+IHRoZSAnb3RoZXInIGNhc2UgbmV2ZXIgb2NjdXJzOiB1c2UgJ290aGVyJyBmb3IgJ21hbnknCiAgICAgICAgICAgICAgICAgICAgICAgICRyZW1vdmVDYXRlZ29yaWVzV2l0aG91dEV4YW1wbGVzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghJHJlbW92ZUNhdGVnb3JpZXNXaXRob3V0RXhhbXBsZXMpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5oYW5kbGVkIGNhc2Ugb2YgcGx1cmFsIGNhdGVnb3JpZXMgd2l0aG91dCBleGFtcGxlcyAnIiAuIGltcGxvZGUoJywgJywgJGJhZENhdGVnb3JpZXNJZHMpIC4gIicgb3V0IG9mICciIC4gaW1wbG9kZSgnLCAnLCAkYWxsQ2F0ZWdvcmllc0lkcykgLiAiJyIpOwogICAgICAgIH0KICAgICAgICBpZiAoJGJhZENhdGVnb3JpZXNbY291bnQoJGJhZENhdGVnb3JpZXMpIC0gMV0tPmlkID09PSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlkpIHsKICAgICAgICAgICAgLy8gV2UncmUgcmVtb3ZpbmcgdGhlICdvdGhlcicgY2Fnb3J5OiBsZXQncyBjaGFuZ2UgdGhlIGxhc3QgZ29vZCBjYXRlZ29yeSB0byAnb3RoZXInCiAgICAgICAgICAgICRsYXN0R29vZCA9ICRnb29kQ2F0ZWdvcmllc1tjb3VudCgkZ29vZENhdGVnb3JpZXMpIC0gMV07CiAgICAgICAgICAgICRsYXN0R29vZC0+aWQgPSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlk7CiAgICAgICAgICAgICRsYXN0R29vZC0+Zm9ybXVsYSA9IG51bGw7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jYXRlZ29yaWVzID0gJGdvb2RDYXRlZ29yaWVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV2ZXJzZSBhIGZvcm11bGEuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybXVsYQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIHJldmVyc2VGb3JtdWxhKCRmb3JtdWxhKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXm4oICUgXGQrKT8gPT0gXGQrKFwuXC5cZCt8LFxkKykqPyQvJywgJGZvcm11bGEpKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnID09ICcsICcgIT0gJywgJGZvcm11bGEpOwogICAgICAgIH0KICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15uKCAlIFxkKyk/ICE9IFxkKyhcLlwuXGQrfCxcZCspKj8kLycsICRmb3JtdWxhKSkgewogICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UoJyAhPSAnLCAnID09ICcsICRmb3JtdWxhKTsKICAgICAgICB9CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eXCg/biA9PSBcZCsgXHxcfCBuID09IFxkK1wpPyQvJywgJGZvcm11bGEpKSB7CiAgICAgICAgICAgIHJldHVybiB0cmltKHN0cl9yZXBsYWNlKGFycmF5KCcgPT0gJywgJyB8fCAnKSwgYXJyYXkoJyAhPSAnLCAnICYmICcpLCAkZm9ybXVsYSksICcoKScpOwogICAgICAgIH0KICAgICAgICAkbSA9IG51bGw7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKG4oPzogJSBcZCspPykgPT0gKFxkKykgJiYgKG4oPzogJSBcZCspPykgIT0gKFxkKykkLycsICRmb3JtdWxhLCAkbSkpIHsKICAgICAgICAgICAgcmV0dXJuICJ7JG1bMV19ICE9IHskbVsyXX0gfHwgeyRtWzNdfSA9PSB7JG1bNF19IjsKICAgICAgICB9CiAgICAgICAgc3dpdGNoICgkZm9ybXVsYSkgewogICAgICAgICAgICBjYXNlICcobiA9PSAxIHx8IG4gPT0gMiB8fCBuID09IDMpIHx8IG4gJSAxMCAhPSA0ICYmIG4gJSAxMCAhPSA2ICYmIG4gJSAxMCAhPSA5JzoKICAgICAgICAgICAgICAgIHJldHVybiAnbiAhPSAxICYmIG4gIT0gMiAmJiBuICE9IDMgJiYgKG4gJSAxMCA9PSA0IHx8IG4gJSAxMCA9PSA2IHx8IG4gJSAxMCA9PSA5KSc7CiAgICAgICAgICAgIGNhc2UgJyhuID09IDAgfHwgbiA9PSAxKSB8fCBuID49IDExICYmIG4gPD0gOTknOgogICAgICAgICAgICAgICAgcmV0dXJuICduID49IDIgJiYgKG4gPCAxMSB8fCBuID4gOTkpJzsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5hYmxlIHRvIHJldmVyc2UgdGhlIGZvcm11bGEgJyR7Zm9ybXVsYX0nIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWR1Y2Ugc29tZSBleGNlc3NpdmVseSBjb21wbGV4IGZvcm11bGFzLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZvcm11bGEKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiByZWR1Y2VGb3JtdWxhKCRmb3JtdWxhKQogICAgewogICAgICAgICRtYXAgPSBhcnJheSgKICAgICAgICAgICAgJ24gIT0gMCAmJiBuICE9IDEnID0+ICduID4gMScsCiAgICAgICAgICAgICcobiA9PSAwIHx8IG4gPT0gMSkgJiYgbiAhPSAwJyA9PiAnbiA9PSAxJywKICAgICAgICApOwoKICAgICAgICByZXR1cm4gaXNzZXQoJG1hcFskZm9ybXVsYV0pID8gJG1hcFskZm9ybXVsYV0gOiAkZm9ybXVsYTsKICAgIH0KCiAgICAvKioKICAgICAqIFRha2Ugb25lIHZhcmlhYmxlIGFuZCwgaWYgaXQncyBhIHN0cmluZywgd2UgdHJhbnNsaXRlcmF0ZSBpdCB0byBVUy1BU0NJSS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIHRoZSB2YXJpYWJsZSB0byB3b3JrIG9uCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGFzY2lpZmllcigmJHZhbHVlKQogICAgewogICAgICAgIGlmIChpc19zdHJpbmcoJHZhbHVlKSAmJiAkdmFsdWUgIT09ICcnKSB7CiAgICAgICAgICAgIC8vIEF2b2lkIGNvbnZlcnRpbmcgZnJvbSAnxbgnIHRvICciWScsIGxldCdzIHByZWZlciAnWScKICAgICAgICAgICAgJHRyYW5zbGl0ZXJhdGVkID0gc3RydHIoJHZhbHVlLCBhcnJheSgKICAgICAgICAgICAgICAgICfDgCcgPT4gJ0EnLCAnw4EnID0+ICdBJywgJ8OCJyA9PiAnQScsICfDgycgPT4gJ0EnLCAnw4QnID0+ICdBJywKICAgICAgICAgICAgICAgICfDiCcgPT4gJ0UnLCAnw4knID0+ICdFJywgJ8OKJyA9PiAnRScsICfDiycgPT4gJ0UnLAogICAgICAgICAgICAgICAgJ8OMJyA9PiAnSScsICfDjScgPT4gJ0knLCAnw44nID0+ICdJJywgJ8OPJyA9PiAnSScsCiAgICAgICAgICAgICAgICAnw5EnID0+ICdOJywKICAgICAgICAgICAgICAgICfDkicgPT4gJ08nLCAnw5MnID0+ICdPJywgJ8OUJyA9PiAnTycsICfDlScgPT4gJ08nLCAnw5YnID0+ICdPJywKICAgICAgICAgICAgICAgICfDmScgPT4gJ1UnLCAnw5onID0+ICdVJywgJ8ObJyA9PiAnVScsICfDnCcgPT4gJ1UnLAogICAgICAgICAgICAgICAgJ8W4JyA9PiAnWScsICfDnScgPT4gJ1knLAogICAgICAgICAgICAgICAgJ8OgJyA9PiAnYScsICfDoScgPT4gJ2EnLCAnw6InID0+ICdhJywgJ8OjJyA9PiAnYScsICfDpCcgPT4gJ2EnLAogICAgICAgICAgICAgICAgJ8OoJyA9PiAnZScsICfDqScgPT4gJ2UnLCAnw6onID0+ICdlJywgJ8OrJyA9PiAnZScsCiAgICAgICAgICAgICAgICAnw6wnID0+ICdpJywgJ8OtJyA9PiAnaScsICfDricgPT4gJ2knLCAnw68nID0+ICdpJywKICAgICAgICAgICAgICAgICfDsScgPT4gJ24nLCAnw7InID0+ICdvJywgJ8OzJyA9PiAnbycsICfDtCcgPT4gJ28nLCAnw7UnID0+ICdvJywgJ8O2JyA9PiAnbycsCiAgICAgICAgICAgICAgICAnw7knID0+ICd1JywgJ8O6JyA9PiAndScsICfDuycgPT4gJ3UnLCAnw7wnID0+ICd1JywKICAgICAgICAgICAgICAgICfDvScgPT4gJ3knLCAnw78nID0+ICd5JywKICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICR0cmFuc2xpdGVyYXRlZCA9IEBpY29udignVVRGLTgnLCAnVVMtQVNDSUkvL0lHTk9SRS8vVFJBTlNMSVQnLCAkdHJhbnNsaXRlcmF0ZWQpOwogICAgICAgICAgICBpZiAoJHRyYW5zbGl0ZXJhdGVkID09PSBmYWxzZSB8fCAkdHJhbnNsaXRlcmF0ZWQgPT09ICcnKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmFibGUgdG8gdHJhbnNsaXRlcmF0ZSAnJHt2YWx1ZX0nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHZhbHVlID0gJHRyYW5zbGl0ZXJhdGVkOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzOwoKdXNlIEV4Y2VwdGlvbjsKCi8qKgogKiBIb2xkcyB0aGUgQ0xEUiBkYXRhLgogKi8KY2xhc3MgQ2xkckRhdGEKewogICAgLyoqCiAgICAgKiBTdXBlci1zcGVjaWFsIHBsdXJhbCBjYXRlZ29yeTogdGhpcyBzaG91bGQgYWx3YXlzIGJlIHByZXNlbnQgZm9yIGFueSBsYW5ndWFnZS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBjb25zdCBPVEhFUl9DQVRFR09SWSA9ICdvdGhlcic7CgogICAgLyoqCiAgICAgKiBUaGUgbGlzdCBvZiB0aGUgcGx1cmFsIGNhdGVnb3JpZXMsIHNvcnRlZCBmcm9tICd6ZXJvJyB0byAnb3RoZXInLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkY2F0ZWdvcmllcyA9IGFycmF5KCd6ZXJvJywgJ29uZScsICd0d28nLCAnZmV3JywgJ21hbnknLCBzZWxmOjpPVEhFUl9DQVRFR09SWSk7CgogICAgLyoqCiAgICAgKiBUaGUgbG9hZGVkIENMRFIgZGF0YS4KICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRkYXRhOwoKICAgIC8qKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyAkcGx1cmFsczsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBkaWN0aW9uYXJ5IGNvbnRhaW5pbmcgdGhlIGxhbmd1YWdlIG5hbWVzLgogICAgICogVGhlIGtleXMgYXJlIHRoZSBsYW5ndWFnZSBpZGVudGlmaWVycy4KICAgICAqIFRoZSB2YWx1ZXMgYXJlIHRoZSBsYW5ndWFnZSBuYW1lcyBpbiBVUyBFbmdsaXNoLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRMYW5ndWFnZU5hbWVzKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0RGF0YSgnbGFuZ3VhZ2VzJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBkaWN0aW9uYXJ5IGNvbnRhaW5pbmcgdGhlIHRlcnJpdG9yeSBuYW1lcyAoaW4gVVMgRW5nbGlzaCkuCiAgICAgKiBUaGUga2V5cyBhcmUgdGhlIHRlcnJpdG9yeSBpZGVudGlmaWVycy4KICAgICAqIFRoZSB2YWx1ZXMgYXJlIHRoZSB0ZXJyaXRvcnkgbmFtZXMgaW4gVVMgRW5nbGlzaC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ1tdCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VGVycml0b3J5TmFtZXMoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpnZXREYXRhKCd0ZXJyaXRvcmllcycpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGEgZGljdGlvbmFyeSBjb250YWluaW5nIHRoZSBzY3JpcHQgbmFtZXMgKGluIFVTIEVuZ2xpc2gpLgogICAgICogVGhlIGtleXMgYXJlIHRoZSBzY3JpcHQgaWRlbnRpZmllcnMuCiAgICAgKiBUaGUgdmFsdWVzIGFyZSB0aGUgc2NyaXB0IG5hbWVzIGluIFVTIEVuZ2xpc2guCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJHN0YW5kQWxvbmUgc2V0IHRvIHRydWUgdG8gcmV0cmlldmUgdGhlIHN0YW5kLWFsb25lIHNjcmlwdCBuYW1lcywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmdbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFNjcmlwdE5hbWVzKCRzdGFuZEFsb25lKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpnZXREYXRhKCRzdGFuZEFsb25lID8gJ3N0YW5kQWxvbmVTY3JpcHRzJyA6ICdzY3JpcHRzJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGRpY3Rpb25hcnkgY29udGFpbmluZyB0aGUgcGx1cmFsIHJ1bGVzLgogICAgICogVGhlIGtleXMgYXJlIHRoZSBsYW5ndWFnZSBpZGVudGlmaWVycy4KICAgICAqIFRoZSB2YWx1ZXMgYXJlIGFycmF5cyB3aG9zZSBrZXlzIGFyZSB0aGUgQ0xEUiBjYXRlZ29yeSBuYW1lcyBhbmQgdGhlIHZhbHVlcyBhcmUgdGhlIENMRFIgY2F0ZWdvcnkgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBAZXhhbXBsZSBUaGUgRW5nbGlzaCBrZXktdmFsdWUgcGFpciBpcyBzb21ldGhpbmsgbGlrZSB0aGlzOgogICAgICogPGNvZGU+PHByZT4KICAgICAqICJlbiI6IHsKICAgICAqICAgICAicGx1cmFsUnVsZS1jb3VudC1vbmUiOiAiaSA9IDEgYW5kIHYgPSAwIEBpbnRlZ2VyIDEiLAogICAgICogICAgICJwbHVyYWxSdWxlLWNvdW50LW90aGVyIjogIiBAaW50ZWdlciAwLCAyfjE2LCAxMDAsIDEwMDAsIDEwMDAwLCAxMDAwMDAsIDEwMDAwMDAsIOKApiBAZGVjaW1hbCAwLjB+MS41LCAxMC4wLCAxMDAuMCwgMTAwMC4wLCAxMDAwMC4wLCAxMDAwMDAuMCwgMTAwMDAwMC4wLCDigKYiCiAgICAgKiB9CiAgICAgKiA8L3ByZT48L2NvZGU+CiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBsdXJhbHMoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpnZXREYXRhKCdwbHVyYWxzJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBsaXN0IG9mIHN1cGVyc2VkZWQgbGFuZ3VhZ2UgY29kZXMuCiAgICAgKgogICAgICogQHJldHVybiBhcnJheSBrZXlzIGFyZSB0aGUgZm9ybWVyIGxhbmd1YWdlIGNvZGVzLCB2YWx1ZXMgYXJlIHRoZSBuZXcgbGFuZ3VhZ2UvbG9jYWxlIGNvZGVzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0U3VwZXJzZWRlZExhbmd1YWdlcygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlbGY6OmdldERhdGEoJ3N1cGVyc2VkZWRMYW5ndWFnZXMnKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIHRoZSBuYW1lIG9mIGEgbGFuZ3VhZ2UsIGFzIHdlbGwgYXMgaWYgYSBsYW5ndWFnZSBjb2RlIGlzIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgYW5vdGhlciBsYW5ndWFnZSBjb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGlkIHRoZSBsYW5ndWFnZSBpZGVudGlmaWVyCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsIFJldHVybnMgYW4gYXJyYXkgd2l0aCB0aGUga2V5cyAnaWQnIChub3JtYWxpemVkKSwgJ25hbWUnLCAnc3VwZXJzZWRlZEJ5JyAob3B0aW9uYWwpLCAndGVycml0b3J5JyAob3B0aW9uYWwpLCAnc2NyaXB0JyAob3B0aW9uYWwpLCAnYmFzZUxhbmd1YWdlJyAob3B0aW9uYWwpLCAnY2F0ZWdvcmllcycuIElmICRpZCBpcyBub3QgdmFsaWQgcmV0dXJucyBudWxsLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldExhbmd1YWdlSW5mbygkaWQpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9IG51bGw7CiAgICAgICAgJG1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXihbYS16XXsyLDN9KSg/OltfXC1dKFthLXpdezR9KSk/KD86W19cLV0oW2Etel17Mn18WzAtOV17M30pKT8oPzokfC0pL2knLCAkaWQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAkbGFuZ3VhZ2VJZCA9IHN0cnRvbG93ZXIoJG1hdGNoZXNbMV0pOwogICAgICAgICAgICAkc2NyaXB0SWQgPSAoaXNzZXQoJG1hdGNoZXNbMl0pICYmICgkbWF0Y2hlc1syXSAhPT0gJycpKSA/IHVjZmlyc3Qoc3RydG9sb3dlcigkbWF0Y2hlc1syXSkpIDogbnVsbDsKICAgICAgICAgICAgJHRlcnJpdG9yeUlkID0gKGlzc2V0KCRtYXRjaGVzWzNdKSAmJiAoJG1hdGNoZXNbM10gIT09ICcnKSkgPyBzdHJ0b3VwcGVyKCRtYXRjaGVzWzNdKSA6IG51bGw7CiAgICAgICAgICAgICRub3JtYWxpemVkSWQgPSAkbGFuZ3VhZ2VJZDsKICAgICAgICAgICAgaWYgKGlzc2V0KCRzY3JpcHRJZCkpIHsKICAgICAgICAgICAgICAgICRub3JtYWxpemVkSWQgLj0gJ18nIC4gJHNjcmlwdElkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkdGVycml0b3J5SWQpKSB7CiAgICAgICAgICAgICAgICAkbm9ybWFsaXplZElkIC49ICdfJyAuICR0ZXJyaXRvcnlJZDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBTdHJ1Y3R1cmUgcHJlY2VkZW5jZTogc2VlIExpa2VseSBTdWJ0YWdzIC0gaHR0cDovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRzL3RyMzUvdHIzNS0zMS90cjM1Lmh0bWwjTGlrZWx5X1N1YnRhZ3MKICAgICAgICAgICAgJHZhcmlhbnRzID0gYXJyYXkoKTsKICAgICAgICAgICAgJHZhcmlhbnRzV2l0aFNjcmlwdCA9IGFycmF5KCk7CiAgICAgICAgICAgICR2YXJpYW50c1dpdGhUZXJyaXRvcnkgPSBhcnJheSgpOwogICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdElkKSAmJiBpc3NldCgkdGVycml0b3J5SWQpKSB7CiAgICAgICAgICAgICAgICAkdmFyaWFudHNXaXRoVGVycml0b3J5W10gPSAkdmFyaWFudHNXaXRoU2NyaXB0W10gPSAkdmFyaWFudHNbXSA9ICJ7JGxhbmd1YWdlSWR9X3skc2NyaXB0SWR9X3skdGVycml0b3J5SWR9IjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdElkKSkgewogICAgICAgICAgICAgICAgJHZhcmlhbnRzV2l0aFNjcmlwdFtdID0gJHZhcmlhbnRzW10gPSAieyRsYW5ndWFnZUlkfV97JHNjcmlwdElkfSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlJZCkpIHsKICAgICAgICAgICAgICAgICR2YXJpYW50c1dpdGhUZXJyaXRvcnlbXSA9ICR2YXJpYW50c1tdID0gInskbGFuZ3VhZ2VJZH1feyR0ZXJyaXRvcnlJZH0iOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR2YXJpYW50c1tdID0gJGxhbmd1YWdlSWQ7CiAgICAgICAgICAgICRhbGxHb29kID0gdHJ1ZTsKICAgICAgICAgICAgJHNjcmlwdE5hbWUgPSBudWxsOwogICAgICAgICAgICAkc2NyaXB0U3RhbmRBbG9uZU5hbWUgPSBudWxsOwogICAgICAgICAgICBpZiAoaXNzZXQoJHNjcmlwdElkKSkgewogICAgICAgICAgICAgICAgJHNjcmlwdE5hbWVzID0gc2VsZjo6Z2V0U2NyaXB0TmFtZXMoZmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzY3JpcHROYW1lc1skc2NyaXB0SWRdKSkgewogICAgICAgICAgICAgICAgICAgICRzY3JpcHROYW1lID0gJHNjcmlwdE5hbWVzWyRzY3JpcHRJZF07CiAgICAgICAgICAgICAgICAgICAgJHNjcmlwdFN0YW5kQWxvbmVOYW1lcyA9IHNlbGY6OmdldFNjcmlwdE5hbWVzKHRydWUpOwogICAgICAgICAgICAgICAgICAgICRzY3JpcHRTdGFuZEFsb25lTmFtZSA9ICRzY3JpcHRTdGFuZEFsb25lTmFtZXNbJHNjcmlwdElkXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGFsbEdvb2QgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkdGVycml0b3J5TmFtZSA9IG51bGw7CiAgICAgICAgICAgIGlmIChpc3NldCgkdGVycml0b3J5SWQpKSB7CiAgICAgICAgICAgICAgICAkdGVycml0b3J5TmFtZXMgPSBzZWxmOjpnZXRUZXJyaXRvcnlOYW1lcygpOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlOYW1lc1skdGVycml0b3J5SWRdKSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGVycml0b3J5SWQgIT09ICcwMDEnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0ZXJyaXRvcnlOYW1lID0gJHRlcnJpdG9yeU5hbWVzWyR0ZXJyaXRvcnlJZF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkYWxsR29vZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRsYW5ndWFnZU5hbWUgPSBudWxsOwogICAgICAgICAgICAkbGFuZ3VhZ2VOYW1lcyA9IHNlbGY6OmdldExhbmd1YWdlTmFtZXMoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJHZhcmlhbnRzIGFzICR2YXJpYW50KSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlTmFtZXNbJHZhcmlhbnRdKSkgewogICAgICAgICAgICAgICAgICAgICRsYW5ndWFnZU5hbWUgPSAkbGFuZ3VhZ2VOYW1lc1skdmFyaWFudF07CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzY3JpcHROYW1lKSAmJiAoIWluX2FycmF5KCR2YXJpYW50LCAkdmFyaWFudHNXaXRoU2NyaXB0KSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxhbmd1YWdlTmFtZSA9ICRzY3JpcHROYW1lIC4gJyAnIC4gJGxhbmd1YWdlTmFtZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR0ZXJyaXRvcnlOYW1lKSAmJiAoIWluX2FycmF5KCR2YXJpYW50LCAkdmFyaWFudHNXaXRoVGVycml0b3J5KSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGxhbmd1YWdlTmFtZSAuPSAnICgnIC4gJHRlcnJpdG9yeU5hbWVzWyR0ZXJyaXRvcnlJZF0gLiAnKSc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNzZXQoJGxhbmd1YWdlTmFtZSkpIHsKICAgICAgICAgICAgICAgICRhbGxHb29kID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGJhc2VMYW5ndWFnZSA9IG51bGw7CiAgICAgICAgICAgIGlmIChpc3NldCgkc2NyaXB0SWQpIHx8IGlzc2V0KCR0ZXJyaXRvcnlJZCkpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkbGFuZ3VhZ2VOYW1lc1skbGFuZ3VhZ2VJZF0pICYmICgkbGFuZ3VhZ2VOYW1lc1skbGFuZ3VhZ2VJZF0gIT09ICRsYW5ndWFnZU5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJGJhc2VMYW5ndWFnZSA9ICRsYW5ndWFnZU5hbWVzWyRsYW5ndWFnZUlkXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkcGx1cmFsID0gbnVsbDsKICAgICAgICAgICAgJHBsdXJhbHMgPSBzZWxmOjpnZXRQbHVyYWxzKCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR2YXJpYW50cyBhcyAkdmFyaWFudCkgewogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRwbHVyYWxzWyR2YXJpYW50XSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGx1cmFsID0gJHBsdXJhbHNbJHZhcmlhbnRdOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaXNzZXQoJHBsdXJhbCkpIHsKICAgICAgICAgICAgICAgICRhbGxHb29kID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHN1cGVyc2VkZWRCeSA9IG51bGw7CiAgICAgICAgICAgICRzdXBlcnNlZGVkQnlzID0gc2VsZjo6Z2V0U3VwZXJzZWRlZExhbmd1YWdlcygpOwogICAgICAgICAgICBmb3JlYWNoICgkdmFyaWFudHMgYXMgJHZhcmlhbnQpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkc3VwZXJzZWRlZEJ5c1skdmFyaWFudF0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHN1cGVyc2VkZWRCeSA9ICRzdXBlcnNlZGVkQnlzWyR2YXJpYW50XTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGFsbEdvb2QpIHsKICAgICAgICAgICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgJHJlc3VsdFsnaWQnXSA9ICRub3JtYWxpemVkSWQ7CiAgICAgICAgICAgICAgICAkcmVzdWx0WyduYW1lJ10gPSAkbGFuZ3VhZ2VOYW1lOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFsnc3VwZXJzZWRlZEJ5J10gPSAkc3VwZXJzZWRlZEJ5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRzY3JpcHRTdGFuZEFsb25lTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0WydzY3JpcHQnXSA9ICRzY3JpcHRTdGFuZEFsb25lTmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdGVycml0b3J5TmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0Wyd0ZXJyaXRvcnknXSA9ICR0ZXJyaXRvcnlOYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRiYXNlTGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFsnYmFzZUxhbmd1YWdlJ10gPSAkYmFzZUxhbmd1YWdlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlc3VsdFsnY2F0ZWdvcmllcyddID0gJHBsdXJhbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb2FkZWQgQ0xEUiBkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleSBDYW4gYmUgJ2xhbmd1YWdlcycsICd0ZXJyaXRvcmllcycsICdwbHVyYWxzJywgJ3N1cGVyc2VkZWRMYW5ndWFnZXMnLCAnc2NyaXB0cycsICdzdGFuZEFsb25lU2NyaXB0cycKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldERhdGEoJGtleSkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRkYXRhKSkgewogICAgICAgICAgICAkZml4S2V5cyA9IGZ1bmN0aW9uICgkbGlzdCwgJiRzdGFuZEFsb25lID0gbnVsbCkgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAkc3RhbmRBbG9uZSA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAkbWF0Y2ggPSBudWxsOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGxpc3QgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAkdmFyaWFudCA9ICcnOwogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXiguKyktYWx0LShzaG9ydHx2YXJpYW50fHN0YW5kLWFsb25lfGxvbmd8bWVudSkkLycsICRrZXksICRtYXRjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGtleSA9ICRtYXRjaFsxXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHZhcmlhbnQgPSAkbWF0Y2hbMl07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRrZXkgPSBzdHJfcmVwbGFjZSgnLScsICdfJywgJGtleSk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgka2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Jvb3QnOiAvLyBMYW5ndWFnZTogUm9vdAogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd1bmQnOiAvLyBMYW5ndWFnZTogVW5rbm93biBMYW5ndWFnZQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd6eHgnOiAvLyBMYW5ndWFnZTogTm8gbGluZ3Vpc3RpYyBjb250ZW50CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1paJzogLy8gVGVycml0b3J5OiBVbmtub3duIFJlZ2lvbgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdaaW5oJzogLy8gU2NyaXB0OiBJbmhlcml0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnWm10aCc6IC8vIFNjcmlwdDogTWF0aGVtYXRpY2FsIE5vdGF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1pzeW0nOiAvLyBTY3JpcHQ6IFN5bWJvbHMKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnWnh4eCc6IC8vIFNjcmlwdDogVW53cml0dGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1p5eXknOiAvLyBTY3JpcHQ6IENvbW1vbgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdaenp6JzogLy8gU2NyaXB0OiBVbmtub3duIFNjcmlwdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR2YXJpYW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RhbmQtYWxvbmUnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3RhbmRBbG9uZVska2V5XSA9ICR2YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFska2V5XSA9ICR2YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgICRkYXRhID0gYXJyYXkoKTsKICAgICAgICAgICAgJGpzb24gPSBqc29uX2RlY29kZShmaWxlX2dldF9jb250ZW50cyhfX0RJUl9fIC4gJy9jbGRyLWRhdGEvbWFpbi9lbi1VUy9sYW5ndWFnZXMuanNvbicpLCB0cnVlKTsKICAgICAgICAgICAgJGRhdGFbJ2xhbmd1YWdlcyddID0gJGZpeEtleXMoJGpzb25bJ21haW4nXVsnZW4tVVMnXVsnbG9jYWxlRGlzcGxheU5hbWVzJ11bJ2xhbmd1YWdlcyddKTsKICAgICAgICAgICAgJGpzb24gPSBqc29uX2RlY29kZShmaWxlX2dldF9jb250ZW50cyhfX0RJUl9fIC4gJy9jbGRyLWRhdGEvbWFpbi9lbi1VUy90ZXJyaXRvcmllcy5qc29uJyksIHRydWUpOwogICAgICAgICAgICAkZGF0YVsndGVycml0b3JpZXMnXSA9ICRmaXhLZXlzKCRqc29uWydtYWluJ11bJ2VuLVVTJ11bJ2xvY2FsZURpc3BsYXlOYW1lcyddWyd0ZXJyaXRvcmllcyddKTsKICAgICAgICAgICAgJGpzb24gPSBqc29uX2RlY29kZShmaWxlX2dldF9jb250ZW50cyhfX0RJUl9fIC4gJy9jbGRyLWRhdGEvc3VwcGxlbWVudGFsL3BsdXJhbHMuanNvbicpLCB0cnVlKTsKICAgICAgICAgICAgJGRhdGFbJ3BsdXJhbHMnXSA9ICRmaXhLZXlzKCRqc29uWydzdXBwbGVtZW50YWwnXVsncGx1cmFscy10eXBlLWNhcmRpbmFsJ10pOwogICAgICAgICAgICAkanNvbiA9IGpzb25fZGVjb2RlKGZpbGVfZ2V0X2NvbnRlbnRzKF9fRElSX18gLiAnL2NsZHItZGF0YS9tYWluL2VuLVVTL3NjcmlwdHMuanNvbicpLCB0cnVlKTsKICAgICAgICAgICAgJGRhdGFbJ3NjcmlwdHMnXSA9ICRmaXhLZXlzKCRqc29uWydtYWluJ11bJ2VuLVVTJ11bJ2xvY2FsZURpc3BsYXlOYW1lcyddWydzY3JpcHRzJ10sICRkYXRhWydzdGFuZEFsb25lU2NyaXB0cyddKTsKICAgICAgICAgICAgJGRhdGFbJ3N0YW5kQWxvbmVTY3JpcHRzJ10gPSBhcnJheV9tZXJnZSgkZGF0YVsnc2NyaXB0cyddLCAkZGF0YVsnc3RhbmRBbG9uZVNjcmlwdHMnXSk7CiAgICAgICAgICAgICRkYXRhWydzY3JpcHRzJ10gPSBhcnJheV9tZXJnZSgkZGF0YVsnc3RhbmRBbG9uZVNjcmlwdHMnXSwgJGRhdGFbJ3NjcmlwdHMnXSk7CiAgICAgICAgICAgICRkYXRhWydzdXBlcnNlZGVkTGFuZ3VhZ2VzJ10gPSBhcnJheSgpOwogICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGxhbmd1YWdlcyBmb3Igd2hpY2ggd2UgZG9uJ3QgaGF2ZSBwbHVyYWxzCiAgICAgICAgICAgICRtID0gbnVsbDsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cyhhcnJheV9kaWZmX2tleSgkZGF0YVsnbGFuZ3VhZ2VzJ10sICRkYXRhWydwbHVyYWxzJ10pKSBhcyAkbWlzc2luZ1BsdXJhbCkgewogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKFthLXpdezIsM30pXy8nLCAkbWlzc2luZ1BsdXJhbCwgJG0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkZGF0YVsncGx1cmFscyddWyRtWzFdXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zZXQoJGRhdGFbJ2xhbmd1YWdlcyddWyRtaXNzaW5nUGx1cmFsXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB1bnNldCgkZGF0YVsnbGFuZ3VhZ2VzJ11bJG1pc3NpbmdQbHVyYWxdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBGaXggdGhlIGxhbmd1YWdlcyBmb3Igd2hpY2ggd2UgaGF2ZSBwbHVyYWxzCiAgICAgICAgICAgICRmb3JtZXJDb2RlcyA9IGFycmF5KAogICAgICAgICAgICAgICAgJ2luJyA9PiAnaWQnLCAvLyBmb3JtZXIgSW5kb25lc2lhbgogICAgICAgICAgICAgICAgJ2l3JyA9PiAnaGUnLCAvLyBmb3JtZXIgSGVicmV3CiAgICAgICAgICAgICAgICAnamknID0+ICd5aScsIC8vIGZvcm1lciBZaWRkaXNoCiAgICAgICAgICAgICAgICAnancnID0+ICdqdicsIC8vIGZvcm1lciBKYXZhbmVzZQogICAgICAgICAgICAgICAgJ21vJyA9PiAncm9fTUQnLCAvLyBmb3JtZXIgTW9sZGF2aWFuCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRrbm93bk1pc3NpbmdMYW5ndWFnZXMgPSBhcnJheSgKICAgICAgICAgICAgICAgICdndXcnID0+ICdHdW4nLAogICAgICAgICAgICAgICAgJ25haCcgPT4gJ05haHVhdGwnLAogICAgICAgICAgICAgICAgJ3NtaScgPT4gJ1NhbWknLAogICAgICAgICAgICApOwogICAgICAgICAgICBmb3JlYWNoIChhcnJheV9rZXlzKGFycmF5X2RpZmZfa2V5KCRkYXRhWydwbHVyYWxzJ10sICRkYXRhWydsYW5ndWFnZXMnXSkpIGFzICRtaXNzaW5nTGFuZ3VhZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZm9ybWVyQ29kZXNbJG1pc3NpbmdMYW5ndWFnZV0pICYmIGlzc2V0KCRkYXRhWydsYW5ndWFnZXMnXVskZm9ybWVyQ29kZXNbJG1pc3NpbmdMYW5ndWFnZV1dKSkgewogICAgICAgICAgICAgICAgICAgICRkYXRhWydsYW5ndWFnZXMnXVskbWlzc2luZ0xhbmd1YWdlXSA9ICRkYXRhWydsYW5ndWFnZXMnXVskZm9ybWVyQ29kZXNbJG1pc3NpbmdMYW5ndWFnZV1dOwogICAgICAgICAgICAgICAgICAgICRkYXRhWydzdXBlcnNlZGVkTGFuZ3VhZ2VzJ11bJG1pc3NpbmdMYW5ndWFnZV0gPSAkZm9ybWVyQ29kZXNbJG1pc3NpbmdMYW5ndWFnZV07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgka25vd25NaXNzaW5nTGFuZ3VhZ2VzWyRtaXNzaW5nTGFuZ3VhZ2VdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZGF0YVsnbGFuZ3VhZ2VzJ11bJG1pc3NpbmdMYW5ndWFnZV0gPSAka25vd25NaXNzaW5nTGFuZ3VhZ2VzWyRtaXNzaW5nTGFuZ3VhZ2VdOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIldlIGhhdmUgdGhlIHBsdXJhbCBydWxlIGZvciB0aGUgbGFuZ3VhZ2UgJyR7bWlzc2luZ0xhbmd1YWdlfScgYnV0IHdlIGRvbid0IGhhdmUgaXRzIGxhbmd1YWdlIG5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAga3NvcnQoJGRhdGFbJ2xhbmd1YWdlcyddLCBTT1JUX1NUUklORyk7CiAgICAgICAgICAgIGtzb3J0KCRkYXRhWyd0ZXJyaXRvcmllcyddLCBTT1JUX1NUUklORyk7CiAgICAgICAgICAgIGtzb3J0KCRkYXRhWydwbHVyYWxzJ10sIFNPUlRfU1RSSU5HKTsKICAgICAgICAgICAga3NvcnQoJGRhdGFbJ3NjcmlwdHMnXSwgU09SVF9TVFJJTkcpOwogICAgICAgICAgICBrc29ydCgkZGF0YVsnc3RhbmRBbG9uZVNjcmlwdHMnXSwgU09SVF9TVFJJTkcpOwogICAgICAgICAgICBrc29ydCgkZGF0YVsnc3VwZXJzZWRlZExhbmd1YWdlcyddLCBTT1JUX1NUUklORyk7CiAgICAgICAgICAgIHNlbGY6OiRkYXRhID0gJGRhdGE7CiAgICAgICAgfQogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGRhdGFbJGtleV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkludmFsaWQgQ0xEUiBkYXRhIGtleTogJyR7a2V5fSciKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOjokZGF0YVska2V5XTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgSHRtbCBleHRlbmRzIEV4cG9ydGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgYSBIVE1MIHRhYmxlJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpidWlsZFRhYmxlKCRsYW5ndWFnZXMsIGZhbHNlKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGgoJHN0cikKICAgIHsKICAgICAgICByZXR1cm4gaHRtbHNwZWNpYWxjaGFycygkc3RyLCBFTlRfQ09NUEFULCAnVVRGLTgnKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGJ1aWxkVGFibGUoJGxhbmd1YWdlcywgJGZvckRvY3MpCiAgICB7CiAgICAgICAgJHByZWZpeCA9ICRmb3JEb2NzID8gJyAgICAgICAgICAgICcgOiAnJzsKICAgICAgICAkbGluZXMgPSBhcnJheSgpOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICc8dGFibGUnIC4gKCRmb3JEb2NzID8gJyBjbGFzcz0idGFibGUgdGFibGUtYm9yZGVyZWQgdGFibGUtY29uZGVuc2VkIHRhYmxlLXN0cmlwZWQiJyA6ICcnKSAuICc+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgIDx0aGVhZD4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgIDx0cj4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGg+TGFuZ3VhZ2UgY29kZTwvdGg+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICAgICAgPHRoPkxhbmd1YWdlIG5hbWU8L3RoPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0aD4jIHBsdXJhbHM8L3RoPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0aD5Gb3JtdWxhPC90aD4nOwogICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGg+UGx1cmFsczwvdGg+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICA8L3RyPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICA8L3RoZWFkPic7CiAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICA8dGJvZHk+JzsKICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYykgewogICAgICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICA8dHI+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gJGxjLT5pZCAuICc8L3RkPic7CiAgICAgICAgICAgICRuYW1lID0gc2VsZjo6aCgkbGMtPm5hbWUpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxjLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkbmFtZSAuPSAnPGJyIC8+PHNtYWxsPjxzcGFuPlN1cGVyc2VkZWQgYnk8L3NwYW4+ICcgLiAkbGMtPnN1cGVyc2VkZWRCeSAuICc8L3NtYWxsPic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gJG5hbWUgLiAnPC90ZD4nOwogICAgICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgICAgICAgICAgPHRkPicgLiBjb3VudCgkbGMtPmNhdGVnb3JpZXMpIC4gJzwvdGQ+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgICAgIDx0ZD4nIC4gc2VsZjo6aCgkbGMtPmZvcm11bGEpIC4gJzwvdGQ+JzsKICAgICAgICAgICAgJGNhc2VzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxjLT5jYXRlZ29yaWVzIGFzICRjKSB7CiAgICAgICAgICAgICAgICAkY2FzZXNbXSA9ICc8bGk+PHNwYW4+JyAuICRjLT5pZCAuICc8L3NwYW4+PGNvZGU+JyAuIHNlbGY6OmgoJGMtPmV4YW1wbGVzKSAuICc8L2NvZGU+PC9saT4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJHByZWZpeCAuICcgICAgICAgICAgICA8dGQ+PG9sJyAuICgkZm9yRG9jcyA/ICcgY2xhc3M9ImNhc2VzIicgOiAnJykgLiAnIHN0YXJ0PSIwIj4nIC4gaW1wbG9kZSgnJywgJGNhc2VzKSAuICc8L29sPjwvdGQ+JzsKICAgICAgICAgICAgJGxpbmVzW10gPSAkcHJlZml4IC4gJyAgICAgICAgPC90cj4nOwogICAgICAgIH0KICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnICAgIDwvdGJvZHk+JzsKICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXggLiAnPC90YWJsZT4nOwoKICAgICAgICByZXR1cm4gaW1wbG9kZSgiXG4iLCAkbGluZXMpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXI7CgpjbGFzcyBQaHAgZXh0ZW5kcyBFeHBvcnRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGEgUEhQIGFycmF5JzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgICRsaW5lcyA9IGFycmF5KCk7CiAgICAgICAgJGxpbmVzW10gPSAnPD9waHAnOwogICAgICAgICRsaW5lc1tdID0gJ3JldHVybiBhcnJheSgnOwogICAgICAgIGZvcmVhY2ggKCRsYW5ndWFnZXMgYXMgJGxjKSB7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICBcJycgLiAkbGMtPmlkIC4gJ1wnID0+IGFycmF5KCc7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCduYW1lXCcgPT4gXCcnIC4gYWRkc2xhc2hlcygkbGMtPm5hbWUpIC4gJ1wnLCc7CiAgICAgICAgICAgIGlmIChpc3NldCgkbGMtPnN1cGVyc2VkZWRCeSkpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdzdXBlcnNlZGVkQnlcJyA9PiBcJycgLiAkbGMtPnN1cGVyc2VkZWRCeSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkbGMtPnNjcmlwdCkpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdzY3JpcHRcJyA9PiBcJycgLiBhZGRzbGFzaGVzKCRsYy0+c2NyaXB0KSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkbGMtPnRlcnJpdG9yeSkpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCd0ZXJyaXRvcnlcJyA9PiBcJycgLiBhZGRzbGFzaGVzKCRsYy0+dGVycml0b3J5KSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkbGMtPmJhc2VMYW5ndWFnZSkpIHsKICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdiYXNlTGFuZ3VhZ2VcJyA9PiBcJycgLiBhZGRzbGFzaGVzKCRsYy0+YmFzZUxhbmd1YWdlKSAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdmb3JtdWxhXCcgPT4gXCcnIC4gJGxjLT5mb3JtdWxhIC4gJ1wnLCc7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdwbHVyYWxzXCcgPT4gJyAuIGNvdW50KCRsYy0+Y2F0ZWdvcmllcykgLiAnLCc7CiAgICAgICAgICAgICRjYXROYW1lcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsYy0+Y2F0ZWdvcmllcyBhcyAkYykgewogICAgICAgICAgICAgICAgJGNhdE5hbWVzW10gPSAiJ3skYy0+aWR9JyI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgICAgICBcJ2Nhc2VzXCcgPT4gYXJyYXkoJyAuIGltcGxvZGUoJywgJywgJGNhdE5hbWVzKSAuICcpLCc7CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgXCdleGFtcGxlc1wnID0+IGFycmF5KCc7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsYy0+Y2F0ZWdvcmllcyBhcyAkYykgewogICAgICAgICAgICAgICAgJGxpbmVzW10gPSAnICAgICAgICAgICAgXCcnIC4gJGMtPmlkIC4gJ1wnID0+IFwnJyAuICRjLT5leGFtcGxlcyAuICdcJywnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaW5lc1tdID0gJyAgICAgICAgKSwnOwogICAgICAgICAgICAkbGluZXNbXSA9ICcgICAgKSwnOwogICAgICAgIH0KICAgICAgICAkbGluZXNbXSA9ICcpOyc7CiAgICAgICAgJGxpbmVzW10gPSAnJzsKCiAgICAgICAgcmV0dXJuIGltcGxvZGUoIlxuIiwgJGxpbmVzKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgRG9jcyBleHRlbmRzIEh0bWwKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OmlzRm9yUHVibGljVXNlKCkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0ZvclB1YmxpY1VzZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgdGhlIHBhZ2UgaHR0cHM6Ly9waHAtZ2V0dGV4dC5naXRodWIuaW8vTGFuZ3VhZ2VzLyc7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OnRvU3RyaW5nRG8oKQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gPDw8RU9UCjwhZG9jdHlwZSBodG1sPgo8aHRtbCBsYW5nPSJlbiI+CiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4KICAgICAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEiPgogICAgICAgIDxtZXRhIG5hbWU9ImF1dGhvciIgY29udGVudD0iTWljaGVsZSBMb2NhdGkiPgogICAgICAgIDx0aXRsZT5nZXR0ZXh0IHBsdXJhbCBydWxlcyAtIGJ1aWx0IGZyb20gQ0xEUjwvdGl0bGU+CiAgICAgICAgPG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9Ikxpc3Qgb2YgYWxsIGxhbmd1YWdlIHJ1bGVzIGZvciBnZXR0ZXh0IC5wbyBmaWxlcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBmcm9tIHRoZSBVbmljb2RlIENMRFIgZGF0YSIgLz4KICAgICAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMy4yL2Nzcy9ib290c3RyYXAubWluLmNzcyI+CiAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJzdHlsZS5jc3MiPgogICAgPC9oZWFkPgogICAgPGJvZHk+CiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3BocC1nZXR0ZXh0L0xhbmd1YWdlcyIgY2xhc3M9ImhpZGRlbi14cyI+PGltZyBzdHlsZT0icG9zaXRpb246IGZpeGVkOyB0b3A6IDA7IHJpZ2h0OiAwOyBib3JkZXI6IDA7IHotaW5kZXg6IDIwMDAiIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2dpdGh1Yi9yaWJib25zL2ZvcmttZV9yaWdodF9yZWRfYWEwMDAwLnBuZyIgYWx0PSJGb3JrIG1lIG9uIEdpdEh1YiI+PC9hPgogICAgICAgIDxkaXYgY2xhc3M9ImNvbnRhaW5lci1mbHVpZCI+CgpFT1Q7CiAgICAgICAgJHJlc3VsdCAuPSBzdGF0aWM6OmJ1aWxkVGFibGUoJGxhbmd1YWdlcywgdHJ1ZSk7CiAgICAgICAgJHJlc3VsdCAuPSA8PDxFT1QKCiAgICAgICAgPC9kaXY+CiAgICAgICAgPHNjcmlwdCBzcmM9Ii8vY29kZS5qcXVlcnkuY29tL2pxdWVyeS0xLjExLjIubWluLmpzIj48L3NjcmlwdD4KICAgICAgICA8c2NyaXB0IHNyYz0ic2NyaXB0LmpzIj48L3NjcmlwdD4KICAgIDwvYm9keT4KPC9odG1sPgpFT1Q7CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXI7Cgp1c2UgRXhjZXB0aW9uOwoKY2xhc3MgUG8gZXh0ZW5kcyBFeHBvcnRlcgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGEgc3RyaW5nIHRvIGJlIHVzZWQgZm9yIGdldHRleHQgLnBvIGZpbGVzJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6dG9TdHJpbmdEbygpCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmdEbygkbGFuZ3VhZ2VzKQogICAgewogICAgICAgIGlmIChjb3VudCgkbGFuZ3VhZ2VzKSAhPT0gMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdUaGUgJyAuIGdldF9jYWxsZWRfY2xhc3MoKSAuICcgZXhwb3J0ZXIgY2FuIG9ubHkgZXhwb3J0IG9uZSBsYW5ndWFnZScpOwogICAgICAgIH0KICAgICAgICAkbGFuZ3VhZ2UgPSAkbGFuZ3VhZ2VzWzBdOwogICAgICAgICRsaW5lcyA9IGFycmF5KCk7CiAgICAgICAgJGxpbmVzW10gPSAnIkxhbmd1YWdlOiAnIC4gJGxhbmd1YWdlLT5pZCAuICdcbiInOwogICAgICAgICRsaW5lc1tdID0gJyJQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPScgLiBjb3VudCgkbGFuZ3VhZ2UtPmNhdGVnb3JpZXMpIC4gJzsgcGx1cmFsPScgLiAkbGFuZ3VhZ2UtPmZvcm11bGEgLiAnXG4iJzsKICAgICAgICAkbGluZXNbXSA9ICcnOwoKICAgICAgICByZXR1cm4gaW1wbG9kZSgiXG4iLCAkbGluZXMpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXI7Cgp1c2UgRXhjZXB0aW9uOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIGFsbCB0aGUgZXhwb3J0ZXJzLgogKi8KYWJzdHJhY3QgY2xhc3MgRXhwb3J0ZXIKewogICAgLyoqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljICRleHBvcnRlcnM7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxpc3Qgb2YgYWxsIHRoZSBhdmFpbGFibGUgZXhwb3J0ZXJzLiBLZXlzIGFyZSB0aGUgZXhwb3J0ZXIgaGFuZGxlcywgdmFsdWVzIGFyZSB0aGUgZXhwb3J0ZXIgY2xhc3MgbmFtZXMuCiAgICAgKgogICAgICogQHBhcmFtIGJvb2wgJG9ubHlGb3JQdWJsaWNVc2UgaWYgdHJ1ZSwgaW50ZXJuYWwgZXhwb3J0ZXJzIHdpbGwgYmUgb21pdHRlZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgZmluYWwgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRFeHBvcnRlcnMoJG9ubHlGb3JQdWJsaWNVc2UgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoIWlzc2V0KHNlbGY6OiRleHBvcnRlcnMpKSB7CiAgICAgICAgICAgICRleHBvcnRlcnMgPSBhcnJheSgpOwogICAgICAgICAgICAkbSA9IG51bGw7CiAgICAgICAgICAgIGZvcmVhY2ggKHNjYW5kaXIoX19ESVJfXykgYXMgJGYpIHsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXihcdyspXC5waHAkLycsICRmLCAkbSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGYgIT09IGJhc2VuYW1lKF9fRklMRV9fKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkZXhwb3J0ZXJzW3N0cnRvbG93ZXIoJG1bMV0pXSA9ICRtWzFdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmOjokZXhwb3J0ZXJzID0gJGV4cG9ydGVyczsKICAgICAgICB9CiAgICAgICAgaWYgKCRvbmx5Rm9yUHVibGljVXNlKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoIChzZWxmOjokZXhwb3J0ZXJzIGFzICRoYW5kbGUgPT4gJGNsYXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoY2FsbF91c2VyX2Z1bmMoc2VsZjo6Z2V0RXhwb3J0ZXJDbGFzc05hbWUoJGhhbmRsZSkgLiAnOjppc0ZvclB1YmxpY1VzZScpID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFskaGFuZGxlXSA9ICRjbGFzczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBzZWxmOjokZXhwb3J0ZXJzOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGRlc2NyaXB0aW9uIG9mIGEgc3BlY2lmaWMgZXhwb3J0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZXhwb3J0ZXJIYW5kbGUgdGhlIGhhbmRsZSBvZiB0aGUgZXhwb3J0ZXIKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24gdGhyb3dzIGFuIEV4Y2VwdGlvbiBpZiAkZXhwb3J0ZXJIYW5kbGUgaXMgbm90IHZhbGlkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgZmluYWwgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRFeHBvcnRlckRlc2NyaXB0aW9uKCRleHBvcnRlckhhbmRsZSkKICAgIHsKICAgICAgICAkZXhwb3J0ZXJzID0gc2VsZjo6Z2V0RXhwb3J0ZXJzKCk7CiAgICAgICAgaWYgKCFpc3NldCgkZXhwb3J0ZXJzWyRleHBvcnRlckhhbmRsZV0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkludmFsaWQgZXhwb3J0ZXIgaGFuZGxlOiAnJHtleHBvcnRlckhhbmRsZX0nIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoc2VsZjo6Z2V0RXhwb3J0ZXJDbGFzc05hbWUoJGV4cG9ydGVySGFuZGxlKSAuICc6OmdldERlc2NyaXB0aW9uJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiBhIGV4cG9ydGVyIGdpdmVuIGl0cyBoYW5kbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZXhwb3J0ZXJIYW5kbGUgdGhlIGV4cG9ydGVyIGNsYXNzIGhhbmRsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIGZpbmFsIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RXhwb3J0ZXJDbGFzc05hbWUoJGV4cG9ydGVySGFuZGxlKQogICAgewogICAgICAgIHJldHVybiBfX05BTUVTUEFDRV9fIC4gJ1xcJyAuIHVjZmlyc3Qoc3RydG9sb3dlcigkZXhwb3J0ZXJIYW5kbGUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnQgYSBsaXN0IG9mIExhbmd1YWdlIGluc3RhbmNlcyB0byBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIFxHZXR0ZXh0XExhbmd1YWdlc1xMYW5ndWFnZVtdICRsYW5ndWFnZXMgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBjb252ZXJ0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgZmluYWwgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZygkbGFuZ3VhZ2VzLCAkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zKSAmJiBpc19hcnJheSgkb3B0aW9ucykpIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyd1cy1hc2NpaSddKSAmJiAkb3B0aW9uc1sndXMtYXNjaWknXSkgewogICAgICAgICAgICAgICAgJGFzY2lpTGlzdCA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYW5ndWFnZSkgewogICAgICAgICAgICAgICAgICAgICRhc2NpaUxpc3RbXSA9ICRsYW5ndWFnZS0+Z2V0VVNBc2NpaUNsb25lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGFuZ3VhZ2VzID0gJGFzY2lpTGlzdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0YXRpYzo6dG9TdHJpbmdEbygkbGFuZ3VhZ2VzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNhdmUgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIFxHZXR0ZXh0XExhbmd1YWdlc1xMYW5ndWFnZVtdICRsYW5ndWFnZXMgdGhlIExhbmd1YWdlIGluc3RhbmNlcyB0byBjb252ZXJ0CiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIGZpbmFsIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9GaWxlKCRsYW5ndWFnZXMsICRmaWxlbmFtZSwgJG9wdGlvbnMgPSBudWxsKQogICAgewogICAgICAgICRkYXRhID0gc2VsZjo6dG9TdHJpbmcoJGxhbmd1YWdlcywgJG9wdGlvbnMpOwogICAgICAgIGlmIChAZmlsZV9wdXRfY29udGVudHMoJGZpbGVuYW1lLCAkZGF0YSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkVycm9yIHdyaXRpbmcgZGF0YSB0byAnJHtmaWxlbmFtZX0nIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSXMgdGhpcyBleHBvcnRlciBmb3IgcHVibGljIHVzZT8KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpc0ZvclB1YmxpY1VzZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBzaG9ydCBkZXNjcmlwdGlvbiBvZiB0aGUgZXhwb3J0ZXIuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihnZXRfY2FsbGVkX2NsYXNzKCkgLiAnIGRvZXMgbm90IGltcGxlbWVudCB0aGUgbWV0aG9kICcgLiBfX0ZVTkNUSU9OX18pOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydCBhIGxpc3Qgb2YgTGFuZ3VhZ2UgaW5zdGFuY2VzIHRvIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gXEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlW10gJGxhbmd1YWdlcyB0aGUgTGFuZ3VhZ2UgaW5zdGFuY2VzIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKGdldF9jYWxsZWRfY2xhc3MoKSAuICcgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBtZXRob2QgJyAuIF9fRlVOQ1RJT05fXyk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlcjsKCnVzZSBFeGNlcHRpb247CgpjbGFzcyBQcmV0dHlqc29uIGV4dGVuZHMgSnNvbgp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxFeHBvcnRlcjo6Z2V0RGVzY3JpcHRpb24oKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERlc2NyaXB0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJ0J1aWxkIGFuIHVuY29tcHJlc3NlZCBKU09OLWVuY29kZWQgZmlsZSAoUEhQIDUuNCBvciBsYXRlciBpcyBuZWVkZWQpJzsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqCiAgICAgKiBAc2VlIFxHZXR0ZXh0XExhbmd1YWdlc1xFeHBvcnRlclxKc29uOjpnZXRFbmNvZGVPcHRpb25zKCkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRFbmNvZGVPcHRpb25zKCkKICAgIHsKICAgICAgICBpZiAoIShkZWZpbmVkKCdcSlNPTl9QUkVUVFlfUFJJTlQnKSAmJiBkZWZpbmVkKCdcSlNPTl9VTkVTQ0FQRURfU0xBU0hFUycpICYmIGRlZmluZWQoJ1xKU09OX1VORVNDQVBFRF9VTklDT0RFJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ1BIUCA1LjQgb3IgbGF0ZXIgaXMgcmVxdWlyZWQgdG8gZXhwb3J0IHVuY29tcHJlc3NlZCBKU09OJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXEpTT05fUFJFVFRZX1BSSU5UIHwgXEpTT05fVU5FU0NBUEVEX1NMQVNIRVMgfCBcSlNPTl9VTkVTQ0FQRURfVU5JQ09ERTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgWG1sIGV4dGVuZHMgRXhwb3J0ZXIKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OmdldERlc2NyaXB0aW9uKCkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXREZXNjcmlwdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICdCdWlsZCBhbiBYTUwgZmlsZSAtIHNjaGVtYSBhdmFpbGFibGUgYXQgaHR0cDovL21sb2NhdGkuZ2l0aHViLmlvL2NsZHItdG8tZ2V0dGV4dC1wbHVyYWwtcnVsZXMvR2V0dGV4dExhbmd1YWdlcy54c2QnOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjp0b1N0cmluZ0RvKCkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZ0RvKCRsYW5ndWFnZXMpCiAgICB7CiAgICAgICAgJHhtbCA9IG5ldyBcRE9NRG9jdW1lbnQoJzEuMCcsICdVVEYtOCcpOwogICAgICAgICR4bWwtPmxvYWRYTUwoJzxsYW5ndWFnZXMKICAgICAgICAgICAgeG1sbnM9Imh0dHBzOi8vZ2l0aHViLmNvbS9tbG9jYXRpL2NsZHItdG8tZ2V0dGV4dC1wbHVyYWwtcnVsZXMiCiAgICAgICAgICAgIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCiAgICAgICAgICAgIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cHM6Ly9naXRodWIuY29tL21sb2NhdGkvY2xkci10by1nZXR0ZXh0LXBsdXJhbC1ydWxlcyBodHRwOi8vbWxvY2F0aS5naXRodWIuaW8vY2xkci10by1nZXR0ZXh0LXBsdXJhbC1ydWxlcy9HZXR0ZXh0TGFuZ3VhZ2VzLnhzZCIKICAgICAgICAvPicpOwogICAgICAgICR4TGFuZ3VhZ2VzID0gJHhtbC0+Zmlyc3RDaGlsZDsKICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2VzIGFzICRsYW5ndWFnZSkgewogICAgICAgICAgICAkeExhbmd1YWdlID0gJHhtbC0+Y3JlYXRlRWxlbWVudCgnbGFuZ3VhZ2UnKTsKICAgICAgICAgICAgJHhMYW5ndWFnZS0+c2V0QXR0cmlidXRlKCdpZCcsICRsYW5ndWFnZS0+aWQpOwogICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAkbGFuZ3VhZ2UtPm5hbWUpOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ3N1cGVyc2VkZWRCeScsICRsYW5ndWFnZS0+c3VwZXJzZWRlZEJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5zY3JpcHQpKSB7CiAgICAgICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ3NjcmlwdCcsICRsYW5ndWFnZS0+c2NyaXB0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT50ZXJyaXRvcnkpKSB7CiAgICAgICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ3RlcnJpdG9yeScsICRsYW5ndWFnZS0+dGVycml0b3J5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5iYXNlTGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ2Jhc2VMYW5ndWFnZScsICRsYW5ndWFnZS0+YmFzZUxhbmd1YWdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkeExhbmd1YWdlLT5zZXRBdHRyaWJ1dGUoJ2Zvcm11bGEnLCAkbGFuZ3VhZ2UtPmZvcm11bGEpOwogICAgICAgICAgICBmb3JlYWNoICgkbGFuZ3VhZ2UtPmNhdGVnb3JpZXMgYXMgJGNhdGVnb3J5KSB7CiAgICAgICAgICAgICAgICAkeENhdGVnb3J5ID0gJHhtbC0+Y3JlYXRlRWxlbWVudCgnY2F0ZWdvcnknKTsKICAgICAgICAgICAgICAgICR4Q2F0ZWdvcnktPnNldEF0dHJpYnV0ZSgnaWQnLCAkY2F0ZWdvcnktPmlkKTsKICAgICAgICAgICAgICAgICR4Q2F0ZWdvcnktPnNldEF0dHJpYnV0ZSgnZXhhbXBsZXMnLCAkY2F0ZWdvcnktPmV4YW1wbGVzKTsKICAgICAgICAgICAgICAgICR4TGFuZ3VhZ2UtPmFwcGVuZENoaWxkKCR4Q2F0ZWdvcnkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR4TGFuZ3VhZ2VzLT5hcHBlbmRDaGlsZCgkeExhbmd1YWdlKTsKICAgICAgICB9CiAgICAgICAgJHhtbC0+Zm9ybWF0T3V0cHV0ID0gdHJ1ZTsKCiAgICAgICAgcmV0dXJuICR4bWwtPnNhdmVYTUwoKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyOwoKY2xhc3MgSnNvbiBleHRlbmRzIEV4cG9ydGVyCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICoKICAgICAqIEBzZWUgXEdldHRleHRcTGFuZ3VhZ2VzXEV4cG9ydGVyXEV4cG9ydGVyOjpnZXREZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RGVzY3JpcHRpb24oKQogICAgewogICAgICAgIHJldHVybiAnQnVpbGQgYSBjb21wcmVzc2VkIEpTT04tZW5jb2RlZCBmaWxlJzsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgb3B0aW9ucyBmb3IganNvbl9lbmNvZGUuCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBnZXRFbmNvZGVPcHRpb25zKCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gMDsKICAgICAgICBpZiAoZGVmaW5lZCgnXEpTT05fVU5FU0NBUEVEX1NMQVNIRVMnKSkgewogICAgICAgICAgICAkcmVzdWx0IHw9IFxKU09OX1VORVNDQVBFRF9TTEFTSEVTOwogICAgICAgIH0KICAgICAgICBpZiAoZGVmaW5lZCgnXEpTT05fVU5FU0NBUEVEX1VOSUNPREUnKSkgewogICAgICAgICAgICAkcmVzdWx0IHw9IFxKU09OX1VORVNDQVBFRF9VTklDT0RFOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKgogICAgICogQHNlZSBcR2V0dGV4dFxMYW5ndWFnZXNcRXhwb3J0ZXJcRXhwb3J0ZXI6OnRvU3RyaW5nRG8oKQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nRG8oJGxhbmd1YWdlcykKICAgIHsKICAgICAgICAkbGlzdCA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJGxhbmd1YWdlcyBhcyAkbGFuZ3VhZ2UpIHsKICAgICAgICAgICAgJGl0ZW0gPSBhcnJheSgpOwogICAgICAgICAgICAkaXRlbVsnbmFtZSddID0gJGxhbmd1YWdlLT5uYW1lOwogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5zdXBlcnNlZGVkQnkpKSB7CiAgICAgICAgICAgICAgICAkaXRlbVsnc3VwZXJzZWRlZEJ5J10gPSAkbGFuZ3VhZ2UtPnN1cGVyc2VkZWRCeTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5zY3JpcHQpKSB7CiAgICAgICAgICAgICAgICAkaXRlbVsnc2NyaXB0J10gPSAkbGFuZ3VhZ2UtPnNjcmlwdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT50ZXJyaXRvcnkpKSB7CiAgICAgICAgICAgICAgICAkaXRlbVsndGVycml0b3J5J10gPSAkbGFuZ3VhZ2UtPnRlcnJpdG9yeTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJGxhbmd1YWdlLT5iYXNlTGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICAgICAkaXRlbVsnYmFzZUxhbmd1YWdlJ10gPSAkbGFuZ3VhZ2UtPmJhc2VMYW5ndWFnZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaXRlbVsnZm9ybXVsYSddID0gJGxhbmd1YWdlLT5mb3JtdWxhOwogICAgICAgICAgICAkaXRlbVsncGx1cmFscyddID0gY291bnQoJGxhbmd1YWdlLT5jYXRlZ29yaWVzKTsKICAgICAgICAgICAgJGl0ZW1bJ2Nhc2VzJ10gPSBhcnJheSgpOwogICAgICAgICAgICAkaXRlbVsnZXhhbXBsZXMnXSA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsYW5ndWFnZS0+Y2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgICRpdGVtWydjYXNlcyddW10gPSAkY2F0ZWdvcnktPmlkOwogICAgICAgICAgICAgICAgJGl0ZW1bJ2V4YW1wbGVzJ11bJGNhdGVnb3J5LT5pZF0gPSAkY2F0ZWdvcnktPmV4YW1wbGVzOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaXN0WyRsYW5ndWFnZS0+aWRdID0gJGl0ZW07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4ganNvbl9lbmNvZGUoJGxpc3QsIHN0YXRpYzo6Z2V0RW5jb2RlT3B0aW9ucygpKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcTGFuZ3VhZ2VzOwoKdXNlIEV4Y2VwdGlvbjsKCi8qKgogKiBBIGhlbHBlciBjbGFzcyB0aGF0IGhhbmRsZXMgYSBzaW5nbGUgY2F0ZWdvcnkgcnVsZXMgKGVnICd6ZXJvJywgJ29uZScsIC4uLikgYW5kIGl0cyBmb3JtdWxhIGFuZCBleGFtcGxlcy4KICovCmNsYXNzIENhdGVnb3J5CnsKICAgIC8qKgogICAgICogVGhlIGNhdGVnb3J5IGlkZW50aWZpZXIgKGVnICd6ZXJvJywgJ29uZScsIC4uLiwgJ290aGVyJykuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRpZDsKCiAgICAvKioKICAgICAqIFRoZSBnZXR0ZXh0IGZvcm11bGEgdGhhdCBpZGVudGlmaWVzIHRoaXMgY2F0ZWdvcnkgKG51bGwgaWYgYW5kIG9ubHkgaWYgdGhlIGNhdGVnb3J5IGlzICdvdGhlcicpLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljICRmb3JtdWxhOwoKICAgIC8qKgogICAgICogVGhlIENMRFIgcmVwcmVzZW50YXRpb24gb2Ygc29tZSBleGVtcGxhciBudW1lcmljIHJhbmdlcyB0aGF0IHNhdGlzZnkgdGhpcyBjYXRlZ29yeS4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHB1YmxpYyAkZXhhbXBsZXM7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIHRoZSBpbnN0YW5jZSBhbmQgcGFyc2UgdGhlIGZvcm11bGEuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2xkckNhdGVnb3J5SWQgdGhlIENMRFIgY2F0ZWdvcnkgaWRlbnRpZmllciAoZWcgJ3BsdXJhbFJ1bGUtY291bnQtb25lJykKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXMgdGhlIENMRFIgZm9ybXVsYSBhbmQgZXhhbXBsZXMgKGVnICdpID0gMSBhbmQgdiA9IDAgQGludGVnZXIgMScpCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY2xkckNhdGVnb3J5SWQsICRjbGRyRm9ybXVsYUFuZEV4YW1wbGVzKQogICAgewogICAgICAgICRtYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9ecGx1cmFsUnVsZS1jb3VudC0oLispJC8nLCAkY2xkckNhdGVnb3J5SWQsICRtYXRjaGVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIENMRFIgY2F0ZWdvcnk6ICcke2NsZHJDYXRlZ29yeUlkfSciKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbl9hcnJheSgkbWF0Y2hlc1sxXSwgQ2xkckRhdGE6OiRjYXRlZ29yaWVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIENMRFIgY2F0ZWdvcnk6ICcke2NsZHJDYXRlZ29yeUlkfSciKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlkID0gJG1hdGNoZXNbMV07CiAgICAgICAgJGNsZHJGb3JtdWxhQW5kRXhhbXBsZXNOb3JtYWxpemVkID0gdHJpbShwcmVnX3JlcGxhY2UoJy9ccysvJywgJyAnLCAkY2xkckZvcm11bGFBbmRFeGFtcGxlcykpOwogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL14oW15AXSopKD86QGludGVnZXIoW15AXSspKT8oPzpAZGVjaW1hbCg/OlteQF0rKSk/JC8nLCAkY2xkckZvcm11bGFBbmRFeGFtcGxlc05vcm1hbGl6ZWQsICRtYXRjaGVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIENMRFIgY2F0ZWdvcnkgcnVsZTogJHtjbGRyRm9ybXVsYUFuZEV4YW1wbGVzfSIpOwogICAgICAgIH0KICAgICAgICAkY2xkckZvcm11bGEgPSB0cmltKCRtYXRjaGVzWzFdKTsKICAgICAgICAkcyA9IGlzc2V0KCRtYXRjaGVzWzJdKSA/IHRyaW0oJG1hdGNoZXNbMl0pIDogJyc7CiAgICAgICAgJHRoaXMtPmV4YW1wbGVzID0gKCRzID09PSAnJykgPyBudWxsIDogJHM7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+aWQpIHsKICAgICAgICAgICAgY2FzZSBDbGRyRGF0YTo6T1RIRVJfQ0FURUdPUlk6CiAgICAgICAgICAgICAgICBpZiAoJGNsZHJGb3JtdWxhICE9PSAnJykgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSAnIiAuIENsZHJEYXRhOjpPVEhFUl9DQVRFR09SWSAuICInIGNhdGVnb3J5IHNob3VsZCBub3QgaGF2ZSBhbnkgZm9ybXVsYSwgYnV0IGl0IGhhcyAnJHtjbGRyRm9ybXVsYX0nIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+Zm9ybXVsYSA9IG51bGw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGlmICgkY2xkckZvcm11bGEgPT09ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVGhlICd7JHRoaXMtPmlkfScgY2F0ZWdvcnkgZG9lcyBub3QgaGF2ZSBhIGZvcm11bGEiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5mb3JtdWxhID0gRm9ybXVsYUNvbnZlcnRlcjo6Y29udmVydEZvcm11bGEoJGNsZHJGb3JtdWxhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIGxpc3Qgb2YgbnVtYmVycyBjb3JyZXNwb25kaW5nIHRvIHRoZSAkZXhhbXBsZXMgdmFsdWUuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIHRocm93cyBhbiBFeGNlcHRpb24gaWYgd2Ugd2VyZW4ndCBhYmxlIHRvIGV4cGFuZCB0aGUgZXhhbXBsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludFtdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeGFtcGxlSW50ZWdlcnMoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpleHBhbmRFeGFtcGxlcygkdGhpcy0+ZXhhbXBsZXMpOwogICAgfQoKICAgIC8qKgogICAgICogRXhwYW5kIGEgbGlzdCBvZiBleGFtcGxlcyBhcyBkZWZpbmVkIGJ5IENMRFIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZXhhbXBsZXMgQSBzdHJpbmcgbGlrZSAnMSwgMiwgNS4uLjcsIOKApicuCiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uIHRocm93cyBhbiBFeGNlcHRpb24gaWYgd2Ugd2VyZW4ndCBhYmxlIHRvIGV4cGFuZCAkZXhhbXBsZXMKICAgICAqCiAgICAgKiBAcmV0dXJuIGludFtdCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXhwYW5kRXhhbXBsZXMoJGV4YW1wbGVzKQogICAgewogICAgICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgICAgICRtID0gbnVsbDsKICAgICAgICBpZiAoc3Vic3RyKCRleGFtcGxlcywgLXN0cmxlbignLCDigKYnKSkgPT09ICcsIOKApicpIHsKICAgICAgICAgICAgJGV4YW1wbGVzID0gc3Vic3RyKCRleGFtcGxlcywgMCwgc3RybGVuKCRleGFtcGxlcykgLSBzdHJsZW4oJywg4oCmJykpOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoIChleHBsb2RlKCcsJywgc3RyX3JlcGxhY2UoJyAnLCAnJywgJGV4YW1wbGVzKSkgYXMgJHJhbmdlKSB7CiAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCcvXlxkKyQvJywgJHJhbmdlKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gKGludCkgJHJhbmdlOwogICAgICAgICAgICB9IGVsc2VpZiAocHJlZ19tYXRjaCgnL14oXGQrKX4oXGQrKSQvJywgJHJhbmdlLCAkbSkpIHsKICAgICAgICAgICAgICAgICRmcm9tID0gKGludCkgJG1bMV07CiAgICAgICAgICAgICAgICAkdG8gPSAoaW50KSAkbVsyXTsKICAgICAgICAgICAgICAgICRkZWx0YSA9ICR0byAtICRmcm9tOwogICAgICAgICAgICAgICAgJHN0ZXAgPSAoaW50KSBtYXgoMSwgJGRlbHRhIC8gMTAwKTsKICAgICAgICAgICAgICAgIGZvciAoJGkgPSAkZnJvbTsgJGkgPCAkdG87ICRpICs9ICRzdGVwKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gJGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSAkdG87CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbmhhbmRsZWQgdGVzdCByYW5nZSAnJHtyYW5nZX0nIGluICcke2V4YW1wbGVzfSciKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJHJlc3VsdCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiTm8gdGVzdCBudW1iZXJzIGZyb20gJyR7ZXhhbXBsZXN9JyIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XExhbmd1YWdlczsKCnVzZSBFeGNlcHRpb247CgovKioKICogQSBoZWxwZXIgY2xhc3MgdG8gY29udmVydCBhIENMRFIgZm9ybXVsYSB0byBhIGdldHRleHQgZm9ybXVsYS4KICovCmNsYXNzIEZvcm11bGFDb252ZXJ0ZXIKewogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIGZvcm11bGEgZnJvbSB0aGUgQ0xEUiByZXByZXNlbnRhdGlvbiB0byB0aGUgZ2V0dGV4dCByZXByZXNlbnRhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjbGRyRm9ybXVsYSB0aGUgQ0xEUiBmb3JtdWxhIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2V0dGV4dCB3aWxsIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlLCBmYWxzZSBpZiBnZXR0ZXh0IHdpbGwgYWx3YXlzIGV2YWx1YXRlIHRvIGZhbHNlLCByZXR1cm4gdGhlIGdldHRleHQgZm9ybXVsYSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0Rm9ybXVsYSgkY2xkckZvcm11bGEpCiAgICB7CiAgICAgICAgaWYgKHN0cnBicmsoJGNsZHJGb3JtdWxhLCAnKCknKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5hYmxlIHRvIGNvbnZlcnQgdGhlIGZvcm11bGEgJyR7Y2xkckZvcm11bGF9JzogcGFyZW50aGVzaXMgaGFuZGxpbmcgbm90IGltcGxlbWVudGVkIik7CiAgICAgICAgfQogICAgICAgICRvclNlcGFyYXRlZENodW5rcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnIG9yICcsICRjbGRyRm9ybXVsYSkgYXMgJGNsZHJGb3JtdWxhQ2h1bmspIHsKICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBudWxsOwogICAgICAgICAgICAkYW5kU2VwYXJhdGVkQ2h1bmtzID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoZXhwbG9kZSgnIGFuZCAnLCAkY2xkckZvcm11bGFDaHVuaykgYXMgJGNsZHJBdG9tKSB7CiAgICAgICAgICAgICAgICAkZ2V0dGV4dEF0b20gPSBzZWxmOjpjb252ZXJ0QXRvbSgkY2xkckF0b20pOwogICAgICAgICAgICAgICAgaWYgKCRnZXR0ZXh0QXRvbSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAvLyBPbmUgYXRvbSBqb2luZWQgYnkgJ2FuZCcgYWx3YXlzIGV2YWx1YXRlcyB0byBmYWxzZSA9PiB0aGUgd2hvbGUgJ2FuZCcgZ3JvdXAgaXMgYWx3YXlzIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkZ2V0dGV4dEF0b20gIT09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAkYW5kU2VwYXJhdGVkQ2h1bmtzW10gPSAkZ2V0dGV4dEF0b207CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc3NldCgkZ2V0dGV4dEZvcm11bGFDaHVuaykpIHsKICAgICAgICAgICAgICAgIGlmIChlbXB0eSgkYW5kU2VwYXJhdGVkQ2h1bmtzKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEFsbCB0aGUgYXRvbXMgam9pbmVkIGJ5ICdhbmQnIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlID0+IHRoZSB3aG9sZSAnYW5kJyBncm91cCBpcyBhbHdheXMgdHJ1ZQogICAgICAgICAgICAgICAgICAgICRnZXR0ZXh0Rm9ybXVsYUNodW5rID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSBpbXBsb2RlKCcgJiYgJywgJGFuZFNlcGFyYXRlZENodW5rcyk7CiAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlcyBzaW1wbGlmaWNhdGlvbgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJGdldHRleHRGb3JtdWxhQ2h1bmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbiA+PSAwICYmIG4gPD0gMiAmJiBuICE9IDInOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGdldHRleHRGb3JtdWxhQ2h1bmsgPSAnbiA9PSAwIHx8IG4gPT0gMSc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRnZXR0ZXh0Rm9ybXVsYUNodW5rID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAvLyBPbmUgcGFydCBvZiB0aGUgZm9ybXVsYSBqb2luZWQgd2l0aCB0aGUgb3RoZXJzIGJ5ICdvcicgYWx3YXlzIGV2YWx1YXRlcyB0byB0cnVlID0+IHRoZSB3aG9sZSBmb3JtdWxhIGFsd2F5cyBldmFsdWF0ZXMgdG8gdHJ1ZQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRnZXR0ZXh0Rm9ybXVsYUNodW5rICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJG9yU2VwYXJhdGVkQ2h1bmtzW10gPSAkZ2V0dGV4dEZvcm11bGFDaHVuazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJG9yU2VwYXJhdGVkQ2h1bmtzKSkgewogICAgICAgICAgICAvLyBBbGwgdGhlIHBhcnRzIGpvaW5lZCBieSAnb3InIGFsd2F5cyBldmFsdWF0ZSB0byBmYWxzZSA9PiB0aGUgd2hvbGUgZm9ybXVsYSBhbHdheXMgZXZhbHVhdGVzIHRvIGZhbHNlCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcgfHwgJywgJG9yU2VwYXJhdGVkQ2h1bmtzKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIGFuIGF0b21pYyBwYXJ0IG9mIHRoZSBDTERSIGZvcm11bGEgdG8gaXRzIGdldHRleHQgcmVwcmVzZW50YXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY2xkckF0b20gdGhlIENMRFIgZm9ybXVsYSBhdG9tIHRvIGNvbnZlcnQKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2V0dGV4dCB3aWxsIGFsd2F5cyBldmFsdWF0ZSB0byB0cnVlLCBmYWxzZSBpZiBnZXR0ZXh0IHdpbGwgYWx3YXlzIGV2YWx1YXRlIHRvIGZhbHNlLCByZXR1cm4gdGhlIGdldHRleHQgZm9ybXVsYSBvdGhlcndpc2UKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gY29udmVydEF0b20oJGNsZHJBdG9tKQogICAgewogICAgICAgICRtID0gbnVsbDsKICAgICAgICAkZ2V0dGV4dEF0b20gPSAkY2xkckF0b207CiAgICAgICAgJGdldHRleHRBdG9tID0gc3RyX3JlcGxhY2UoJyA9ICcsICcgPT0gJywgJGdldHRleHRBdG9tKTsKICAgICAgICAkZ2V0dGV4dEF0b20gPSBzdHJfcmVwbGFjZSgnaScsICduJywgJGdldHRleHRBdG9tKTsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL15uKCAlIFxkKyk/ICghPXw9PSkgXGQrJC8nLCAkZ2V0dGV4dEF0b20pKSB7CiAgICAgICAgICAgIHJldHVybiAkZ2V0dGV4dEF0b207CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXm4oICUgXGQrKT8gKCE9fD09KSBcZCsoLFxkK3xcLlwuXGQrKSskLycsICRnZXR0ZXh0QXRvbSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY6OmV4cGFuZEF0b20oJGdldHRleHRBdG9tKTsKICAgICAgICB9CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJy9eKD86dnx3KSg/OiAlIDEwKyk/ID09IChcZCspKD86XC5cLlxkKyk/JC8nLCAkZ2V0dGV4dEF0b20sICRtKSkgeyAvLyBGb3IgZ2V0dGV4dDogdiA9PSAwLCB3ID09IDAKICAgICAgICAgICAgcmV0dXJuIChpbnQpICRtWzFdID09PSAwID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oPzp2fHcpKD86ICUgMTArKT8gIT0gKFxkKykoPzpcLlwuXGQrKT8kLycsICRnZXR0ZXh0QXRvbSwgJG0pKSB7IC8vIEZvciBnZXR0ZXh0OiB2ID09IDAsIHcgPT0gMAogICAgICAgICAgICByZXR1cm4gKGludCkgJG1bMV0gPT09IDAgPyBmYWxzZSA6IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXig/OmZ8dCkoPzogJSAxMCspPyA9PSAoXGQrKSg/OlwuXC5cZCspPyQvJywgJGdldHRleHRBdG9tLCAkbSkpIHsgLy8gZiA9PSBlbXB0eSwgdCA9PSBlbXB0eQogICAgICAgICAgICByZXR1cm4gKGludCkgJG1bMV0gPT09IDAgPyB0cnVlIDogZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXig/OmZ8dCkoPzogJSAxMCspPyAhPSAoXGQrKSg/OlwuXC5cZCspPyQvJywgJGdldHRleHRBdG9tLCAkbSkpIHsgLy8gZiA9PSBlbXB0eSwgdCA9PSBlbXB0eQogICAgICAgICAgICByZXR1cm4gKGludCkgJG1bMV0gPT09IDAgPyBmYWxzZSA6IHRydWU7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlVuYWJsZSB0byBjb252ZXJ0IHRoZSBmb3JtdWxhIGNodW5rICcke2NsZHJBdG9tfScgZnJvbSBDTERSIHRvIGdldHRleHQiKTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4cGFuZHMgYW4gYXRvbSBjb250YWluaW5nIGEgcmFuZ2UgKGZvciBpbnN0YW5jZTogJ24gPT0gMSwzLi41JykuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYXRvbQogICAgICoKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGV4cGFuZEF0b20oJGF0b20pCiAgICB7CiAgICAgICAgJG0gPSBudWxsOwogICAgICAgIGlmIChwcmVnX21hdGNoKCcvXihuKD86ICUgXGQrKT8pICg9PXwhPSkgKFxkKyg/OlwuXC5cZCt8LFxkKykrKSQvJywgJGF0b20sICRtKSkgewogICAgICAgICAgICAkd2hhdCA9ICRtWzFdOwogICAgICAgICAgICAkb3AgPSAkbVsyXTsKICAgICAgICAgICAgJGNodW5rcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKGV4cGxvZGUoJywnLCAkbVszXSkgYXMgJHJhbmdlKSB7CiAgICAgICAgICAgICAgICAkY2h1bmsgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCghaXNzZXQoJGNodW5rKSkgJiYgcHJlZ19tYXRjaCgnL15cZCskLycsICRyYW5nZSkpIHsKICAgICAgICAgICAgICAgICAgICAkY2h1bmsgPSAiJHt3aGF0fSAke29wfSAke3JhbmdlfSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoKCFpc3NldCgkY2h1bmspKSAmJiBwcmVnX21hdGNoKCcvXihcZCspXC5cLihcZCspJC8nLCAkcmFuZ2UsICRtKSkgewogICAgICAgICAgICAgICAgICAgICRmcm9tID0gKGludCkgJG1bMV07CiAgICAgICAgICAgICAgICAgICAgJHRvID0gKGludCkgJG1bMl07CiAgICAgICAgICAgICAgICAgICAgaWYgKCgkdG8gLSAkZnJvbSkgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkb3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJz09JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2h1bmsgPSAiKCR7d2hhdH0gPT0gJHtmcm9tfSB8fCAke3doYXR9ID09ICR7dG99KSI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICchPSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNodW5rID0gIiR7d2hhdH0gIT0gJHtmcm9tfSAmJiAke3doYXR9ID09ICR7dG99IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJG9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICc9PSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNodW5rID0gIiR7d2hhdH0gPj0gJHtmcm9tfSAmJiAke3doYXR9IDw9ICR7dG99IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJyE9JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHdoYXQgPT09ICduJyAmJiAkZnJvbSA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaHVuayA9ICIke3doYXR9ID4gJHt0b30iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaHVuayA9ICIoJHt3aGF0fSA8ICR7ZnJvbX0gfHwgJHt3aGF0fSA+ICR7dG99KSI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkY2h1bmspKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5oYW5kbGVkIHJhbmdlICcke3JhbmdlfScgaW4gJyR7YXRvbX0nIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY2h1bmtzW10gPSAkY2h1bms7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50KCRjaHVua3MpID09PSAxKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGNodW5rc1swXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKCRvcCkgewogICAgICAgICAgICAgICAgY2FzZSAnPT0nOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAnKCcgLiBpbXBsb2RlKCcgfHwgJywgJGNodW5rcykgLiAnKSc7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnIT0nOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbXBsb2RlKCcgJiYgJywgJGNodW5rcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5hYmxlIHRvIGV4cGFuZCAnJHthdG9tfSciKTsKICAgIH0KfQo8P3BocAoKc3BsX2F1dG9sb2FkX3JlZ2lzdGVyKAogICAgZnVuY3Rpb24gKCRjbGFzcykgewogICAgICAgIGlmIChzdHJwb3MoJGNsYXNzLCAnR2V0dGV4dFxcTGFuZ3VhZ2VzXFwnKSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICRmaWxlID0gX19ESVJfXyAuIHN0cl9yZXBsYWNlKCdcXCcsIERJUkVDVE9SWV9TRVBBUkFUT1IsIHN1YnN0cigkY2xhc3MsIHN0cmxlbignR2V0dGV4dFxcTGFuZ3VhZ2VzJykpKSAuICcucGhwJzsKICAgICAgICBpZiAoaXNfZmlsZSgkZmlsZSkpIHsKICAgICAgICAgICAgcmVxdWlyZV9vbmNlICRmaWxlOwogICAgICAgIH0KICAgIH0KKTsKPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0OwoKLyoqCiAqIEludGVyZmFjZSB1c2VkIGJ5IGFsbCB0cmFuc2xhdG9ycy4KICovCmludGVyZmFjZSBUcmFuc2xhdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICogUmVnaXN0ZXIgdGhpcyB0cmFuc2xhdG9yIGFzIGdsb2JhbCwgdG8gdXNlIHdpdGggdGhlIGdldHRleHQgZnVuY3Rpb25zIF9fKCksIHBfXygpLCBldGMuCiAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyB0cmFuc2xhdG9yIGlmIGV4aXN0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0b3JJbnRlcmZhY2V8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoKTsKCiAgICAvKioKICAgICAqIE5vb3AsIG1hcmtzIHRoZSBzdHJpbmcgZm9yIHRyYW5zbGF0aW9uIGJ1dCByZXR1cm5zIGl0IHVuY2hhbmdlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBub29wKCRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gdXNpbmcgdGhlIG9yaWdpbmFsIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXR0ZXh0KCRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIHBsdXJhbCBmb3JtLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwbHVyYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5nZXR0ZXh0KCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKCiAgICAvKioKICAgICAqIEdldHMgYSB0cmFuc2xhdGlvbiBjaGVja2luZyB0aGUgZG9tYWluIGFuZCB0aGUgcGx1cmFsIGZvcm0uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIC8qKgogICAgICogR2V0cyBhIHRyYW5zbGF0aW9uIGNoZWNraW5nIHRoZSBjb250ZXh0IGFuZCB0aGUgcGx1cmFsIGZvcm0uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbnBnZXR0ZXh0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGdldHRleHQoJGNvbnRleHQsICRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGRvbWFpbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkb21haW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRnZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgdHJhbnNsYXRpb24gY2hlY2tpbmcgdGhlIGRvbWFpbiBhbmQgY29udGV4dC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkb21haW4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRwZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICAvKioKICAgICAqIEdldHMgYSB0cmFuc2xhdGlvbiBjaGVja2luZyB0aGUgZG9tYWluLCB0aGUgY29udGV4dCBhbmQgdGhlIHBsdXJhbCBmb3JtLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRucGdldHRleHQoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIFR3aWdfTG9hZGVyX0FycmF5Owp1c2UgVHdpZ19FbnZpcm9ubWVudDsKdXNlIFR3aWdfU291cmNlOwp1c2UgVHdpZ19FeHRlbnNpb25zX0V4dGVuc2lvbl9JMThuOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSB0d2lnIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBUd2lnIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2V4dHJhY3RDb21tZW50cycgPT4gJ25vdGVzOicsCiAgICAgICAgJ3R3aWcnID0+IG51bGwsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgJHR3aWcgPSAkb3B0aW9uc1sndHdpZyddID86IHN0YXRpYzo6Y3JlYXRlVHdpZygpOwoKICAgICAgICBQaHBDb2RlOjpmcm9tU3RyaW5nKCR0d2lnLT5jb21waWxlU291cmNlKG5ldyBUd2lnX1NvdXJjZSgkc3RyaW5nLCAnJykpLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgVHdpZyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIFR3aWdfRW52aXJvbm1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGVUd2lnKCkKICAgIHsKICAgICAgICAkdHdpZyA9IG5ldyBUd2lnX0Vudmlyb25tZW50KG5ldyBUd2lnX0xvYWRlcl9BcnJheShbJycgPT4gJyddKSk7CiAgICAgICAgJHR3aWctPmFkZEV4dGVuc2lvbihuZXcgVHdpZ19FeHRlbnNpb25zX0V4dGVuc2lvbl9JMThuKCkpOwoKICAgICAgICByZXR1cm4gc3RhdGljOjokb3B0aW9uc1sndHdpZyddID0gJHR3aWc7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgRXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEZ1bmN0aW9uc1NjYW5uZXI7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIHBocCBmaWxlcyByZXR1cm5pbmcgYXJyYXlzLgogKi8KY2xhc3MgUGhwQ29kZSBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZSwgRXh0cmFjdG9yTXVsdGlJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAvLyAtIGZhbHNlOiB0byBub3QgZXh0cmFjdCBjb21tZW50cwogICAgICAgIC8vIC0gZW1wdHkgc3RyaW5nOiB0byBleHRyYWN0IGFsbCBjb21tZW50cwogICAgICAgIC8vIC0gbm9uLWVtcHR5IHN0cmluZzogdG8gZXh0cmFjdCBjb21tZW50cyB0aGF0IHN0YXJ0IHdpdGggdGhhdCBzdHJpbmcKICAgICAgICAvLyAtIGFycmF5IHdpdGggc3RyaW5ncyB0byBleHRyYWN0IGNvbW1lbnRzIGZvcm1hdC4KICAgICAgICAnZXh0cmFjdENvbW1lbnRzJyA9PiBmYWxzZSwKCiAgICAgICAgJ2NvbnN0YW50cycgPT4gW10sCgogICAgICAgICdmdW5jdGlvbnMnID0+IFsKICAgICAgICAgICAgJ2dldHRleHQnID0+ICdnZXR0ZXh0JywKICAgICAgICAgICAgJ19fJyA9PiAnZ2V0dGV4dCcsCiAgICAgICAgICAgICduZ2V0dGV4dCcgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ25fXycgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ3BnZXR0ZXh0JyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAncF9fJyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAnZGdldHRleHQnID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkX18nID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbmdldHRleHQnID0+ICdkbmdldHRleHQnLAogICAgICAgICAgICAnZG5fXycgPT4gJ2RuZ2V0dGV4dCcsCiAgICAgICAgICAgICdkcGdldHRleHQnID0+ICdkcGdldHRleHQnLAogICAgICAgICAgICAnZHBfXycgPT4gJ2RwZ2V0dGV4dCcsCiAgICAgICAgICAgICducGdldHRleHQnID0+ICducGdldHRleHQnLAogICAgICAgICAgICAnbnBfXycgPT4gJ25wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBnZXR0ZXh0JyA9PiAnZG5wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBfXycgPT4gJ2RucGdldHRleHQnLAogICAgICAgICAgICAnbm9vcCcgPT4gJ25vb3AnLAogICAgICAgICAgICAnbm9vcF9fJyA9PiAnbm9vcCcsCiAgICAgICAgXSwKICAgIF07CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkZnVuY3Rpb25zU2Nhbm5lckNsYXNzID0gJ0dldHRleHRcVXRpbHNcUGhwRnVuY3Rpb25zU2Nhbm5lcic7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgWyR0cmFuc2xhdGlvbnNdLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICAvKiogQHZhciBGdW5jdGlvbnNTY2FubmVyICRmdW5jdGlvbnMgKi8KICAgICAgICAkZnVuY3Rpb25zID0gbmV3IHN0YXRpYzo6JGZ1bmN0aW9uc1NjYW5uZXJDbGFzcygkc3RyaW5nKTsKCiAgICAgICAgaWYgKCRvcHRpb25zWydleHRyYWN0Q29tbWVudHMnXSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgJGZ1bmN0aW9ucy0+ZW5hYmxlQ29tbWVudHNFeHRyYWN0aW9uKCRvcHRpb25zWydleHRyYWN0Q29tbWVudHMnXSk7CiAgICAgICAgfQoKICAgICAgICAkZnVuY3Rpb25zLT5zYXZlR2V0dGV4dEZ1bmN0aW9ucygkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlTXVsdGlwbGUoJGZpbGUsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjpnZXRGaWxlcygkZmlsZSkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2ZpbGUnXSA9ICRmaWxlOwogICAgICAgICAgICBzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZShzdGF0aWM6OnJlYWRGaWxlKCRmaWxlKSwgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgIH0KCgogICAgLyoqCiAgICAgKiBEZWNvZGVzIGEgVF9DT05TVEFOVF9FTkNBUFNFRF9TVFJJTkcgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0U3RyaW5nKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoc3RycG9zKCR2YWx1ZSwgJ1xcJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHZhbHVlLCAxLCAtMSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHZhbHVlWzBdID09PSAiJyIpIHsKICAgICAgICAgICAgcmV0dXJuIHN0cnRyKHN1YnN0cigkdmFsdWUsIDEsIC0xKSwgWydcXFxcJyA9PiAnXFwnLCAnXFxcJycgPT4gJ1wnJ10pOwogICAgICAgIH0KCiAgICAgICAgJHZhbHVlID0gc3Vic3RyKCR2YWx1ZSwgMSwgLTEpOwoKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAogICAgICAgICAgICAnL1xcXChufHJ8dHx2fGV8ZnxcJHwifFxcXHx4WzAtOUEtRmEtZl17MSwyfXx1e1swLTlhLWZdezEsNn19fFswLTddezEsM30pLycsCiAgICAgICAgICAgIGZ1bmN0aW9uICgkbWF0Y2gpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoJG1hdGNoWzFdWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXG4iOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3InOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxyIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICd0JzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcdCI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXHYiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2UnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxlIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICdmJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcZiI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnJCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnJCc7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnIic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnIic7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXFwnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ1xcJzsKICAgICAgICAgICAgICAgICAgICBjYXNlICd4JzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNocihoZXhkZWMoc3Vic3RyKCRtYXRjaFsxXSwgMSkpKTsKICAgICAgICAgICAgICAgICAgICBjYXNlICd1JzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRpYzo6dW5pY29kZUNoYXIoaGV4ZGVjKHN1YnN0cigkbWF0Y2hbMV0sIDEpKSk7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNocihvY3RkZWMoJG1hdGNoWzFdKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICR2YWx1ZQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gJGRlYwogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICogQHNlZSBodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uY2hyLnBocCMxMTg4MDQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB1bmljb2RlQ2hhcigkZGVjKQogICAgewogICAgICAgIGlmICgkZGVjIDwgMHg4MCkgewogICAgICAgICAgICByZXR1cm4gY2hyKCRkZWMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRkZWMgPCAweDA4MDApIHsKICAgICAgICAgICAgcmV0dXJuIGNocigweEMwICsgKCRkZWMgPj4gNikpCiAgICAgICAgICAgICAgICAuIGNocigweDgwICsgKCRkZWMgJiAweDNmKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGRlYyA8IDB4MDEwMDAwKSB7CiAgICAgICAgICAgIHJldHVybiBjaHIoMHhFMCArICgkZGVjID4+IDEyKSkKICAgICAgICAgICAgICAgIC4gY2hyKDB4ODAgKyAoKCRkZWMgPj4gNikgJiAweDNmKSkKICAgICAgICAgICAgICAgIC4gY2hyKDB4ODAgKyAoJGRlYyAmIDB4M2YpKTsKICAgICAgICB9CgogICAgICAgIGlmICgkZGVjIDwgMHgyMDAwMDApIHsKICAgICAgICAgICAgcmV0dXJuIGNocigweEYwICsgKCRkZWMgPj4gMTgpKQogICAgICAgICAgICAgICAgLiBjaHIoMHg4MCArICgoJGRlYyA+PiAxMikgJiAweDNmKSkKICAgICAgICAgICAgICAgIC4gY2hyKDB4ODAgKyAoKCRkZWMgPj4gNikgJiAweDNmKSkKICAgICAgICAgICAgICAgIC4gY2hyKDB4ODAgKyAoJGRlYyAmIDB4M2YpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbjsKdXNlIFNpbXBsZVhNTEVsZW1lbnQ7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIHhsaWZmIGZvcm1hdC4KICovCmNsYXNzIFhsaWZmIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICd1bml0aWRfYXNfaWQnID0+IGZhbHNlCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgJHhtbCA9IG5ldyBTaW1wbGVYTUxFbGVtZW50KCRzdHJpbmcsIG51bGwsIGZhbHNlKTsKCiAgICAgICAgZm9yZWFjaCAoJHhtbC0+ZmlsZSBhcyAkZmlsZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGZpbGUtPm5vdGVzKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGUtPm5vdGVzLT5ub3RlIGFzICRub3RlKSB7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+c2V0SGVhZGVyKCRub3RlWydpZCddLCAoc3RyaW5nKSAkbm90ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCRmaWxlLT51bml0IGFzICR1bml0KSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdW5pdC0+c2VnbWVudCBhcyAkc2VnbWVudCkgewogICAgICAgICAgICAgICAgICAgICR0YXJnZXRzID0gW107CgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRzZWdtZW50LT50YXJnZXQgYXMgJHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0c1tdID0gKHN0cmluZykgJHRhcmdldDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmNyZWF0ZU5ld1RyYW5zbGF0aW9uKG51bGwsIChzdHJpbmcpICRzZWdtZW50LT5zb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdW5pdFsnaWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHVuaXRJZCA9IChzdHJpbmcpICR1bml0WydpZCddOwogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZENvbW1lbnQoIlhMSUZGX1VOSVRfSUQ6ICR1bml0SWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRvcHRpb25zWyd1bml0aWRfYXNfaWQnXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRJZCgkdW5pdElkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFRyYW5zbGF0aW9uKGFycmF5X3NoaWZ0KCR0YXJnZXRzKSk7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHRhcmdldHMpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHVuaXQtPm5vdGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdW5pdC0+bm90ZXMtPm5vdGUgYXMgJG5vdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJG5vdGVbJ2NhdGVnb3J5J10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdjb250ZXh0JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5nZXRDbG9uZSgoc3RyaW5nKSAkbm90ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdleHRyYWN0ZWQtY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCgoc3RyaW5nKSAkbm90ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdmbGFnJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5hZGRGbGFnKChzdHJpbmcpICRub3RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JlZmVyZW5jZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZWYgPSBleHBsb2RlKCc6JywgKHN0cmluZykgJG5vdGUsIDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZFJlZmVyZW5jZSgkcmVmWzBdLCBpc3NldCgkcmVmWzFdKSA/ICRyZWZbMV0gOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkQ29tbWVudCgoc3RyaW5nKSAkbm90ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zW10gPSAkdHJhbnNsYXRpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBJbGx1bWluYXRlXEZpbGVzeXN0ZW1cRmlsZXN5c3RlbTsKdXNlIElsbHVtaW5hdGVcVmlld1xDb21waWxlcnNcQmxhZGVDb21waWxlcjsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gYmxhZGUucGhwIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBCbGFkZSBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGlmIChlbXB0eSgkb3B0aW9uc1snZmFjYWRlJ10pKSB7CiAgICAgICAgICAgICRjYWNoZVBhdGggPSBlbXB0eSgkb3B0aW9uc1snY2FjaGVQYXRoJ10pID8gc3lzX2dldF90ZW1wX2RpcigpIDogJG9wdGlvbnNbJ2NhY2hlUGF0aCddOwogICAgICAgICAgICAkYmxhZGVDb21waWxlciA9IG5ldyBCbGFkZUNvbXBpbGVyKG5ldyBGaWxlc3lzdGVtKCksICRjYWNoZVBhdGgpOwoKICAgICAgICAgICAgaWYgKG1ldGhvZF9leGlzdHMoJGJsYWRlQ29tcGlsZXIsICd3aXRob3V0Q29tcG9uZW50VGFncycpKSB7CiAgICAgICAgICAgICAgICAkYmxhZGVDb21waWxlci0+d2l0aG91dENvbXBvbmVudFRhZ3MoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHN0cmluZyA9ICRibGFkZUNvbXBpbGVyLT5jb21waWxlU3RyaW5nKCRzdHJpbmcpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRzdHJpbmcgPSAkb3B0aW9uc1snZmFjYWRlJ106OmNvbXBpbGVTdHJpbmcoJHN0cmluZyk7CiAgICAgICAgfQoKICAgICAgICBQaHBDb2RlOjpmcm9tU3RyaW5nKCRzdHJpbmcsICR0cmFuc2xhdGlvbnMsICRvcHRpb25zKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gcGhwIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBQbyBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgSGVhZGVyc0V4dHJhY3RvclRyYWl0OwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgLnBvIGZpbGUgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJGxpbmVzID0gZXhwbG9kZSgiXG4iLCAkc3RyaW5nKTsKICAgICAgICAkaSA9IDA7CgogICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmNyZWF0ZU5ld1RyYW5zbGF0aW9uKCcnLCAnJyk7CgogICAgICAgIGZvciAoJG4gPSBjb3VudCgkbGluZXMpOyAkaSA8ICRuOyArKyRpKSB7CiAgICAgICAgICAgICRsaW5lID0gdHJpbSgkbGluZXNbJGldKTsKICAgICAgICAgICAgJGxpbmUgPSBzdGF0aWM6OmZpeE11bHRpTGluZXMoJGxpbmUsICRsaW5lcywgJGkpOwoKICAgICAgICAgICAgaWYgKCRsaW5lID09PSAnJykgewogICAgICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aXMoJycsICcnKSkgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkdHJhbnNsYXRpb24tPmhhc09yaWdpbmFsKCkpIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zW10gPSAkdHJhbnNsYXRpb247CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9ucy0+Y3JlYXRlTmV3VHJhbnNsYXRpb24oJycsICcnKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkc3BsaXRMaW5lID0gcHJlZ19zcGxpdCgnL1xzKy8nLCAkbGluZSwgMik7CiAgICAgICAgICAgICRrZXkgPSAkc3BsaXRMaW5lWzBdOwogICAgICAgICAgICAkZGF0YSA9IGlzc2V0KCRzcGxpdExpbmVbMV0pID8gJHNwbGl0TGluZVsxXSA6ICcnOwoKICAgICAgICAgICAgaWYgKCRrZXkgPT09ICcjficpIHsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0RGlzYWJsZWQodHJ1ZSk7CgogICAgICAgICAgICAgICAgJHNwbGl0TGluZSA9IHByZWdfc3BsaXQoJy9ccysvJywgJGRhdGEsIDIpOwogICAgICAgICAgICAgICAgJGtleSA9ICRzcGxpdExpbmVbMF07CiAgICAgICAgICAgICAgICAkZGF0YSA9IGlzc2V0KCRzcGxpdExpbmVbMV0pID8gJHNwbGl0TGluZVsxXSA6ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKCRrZXkpIHsKICAgICAgICAgICAgICAgIGNhc2UgJyMnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkQ29tbWVudCgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIy4nOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkRXh0cmFjdGVkQ29tbWVudCgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIywnOgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21hcCgndHJpbScsIGV4cGxvZGUoJywnLCB0cmltKCRkYXRhKSkpIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEZsYWcoJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnIzonOgogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHByZWdfc3BsaXQoJy9ccysvJywgdHJpbSgkZGF0YSkpIGFzICR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL14oLispKDooXGQqKSk/JC9VJywgJHZhbHVlLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCRtYXRjaGVzWzFdLCBpc3NldCgkbWF0Y2hlc1szXSkgPyAkbWF0Y2hlc1szXSA6IG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21zZ2N0eHQnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbi0+Z2V0Q2xvbmUoc3RhdGljOjpjb252ZXJ0U3RyaW5nKCRkYXRhKSk7CiAgICAgICAgICAgICAgICAgICAgJGFwcGVuZCA9ICdDb250ZXh0JzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dpZCc6CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5nZXRDbG9uZShudWxsLCBzdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpKTsKICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ09yaWdpbmFsJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dpZF9wbHVyYWwnOgogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0UGx1cmFsKHN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSAnUGx1cmFsJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdtc2dzdHInOgogICAgICAgICAgICAgICAgY2FzZSAnbXNnc3RyWzBdJzoKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFRyYW5zbGF0aW9uKHN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICRhcHBlbmQgPSAnVHJhbnNsYXRpb24nOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ21zZ3N0clsxXSc6CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoW3N0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSldKTsKICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ1BsdXJhbFRyYW5zbGF0aW9uJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJGtleSwgJ21zZ3N0clsnKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkcCA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRwW10gPSBzdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHApOwogICAgICAgICAgICAgICAgICAgICAgICAkYXBwZW5kID0gJ1BsdXJhbFRyYW5zbGF0aW9uJzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGFwcGVuZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRhcHBlbmQgPT09ICdDb250ZXh0JykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uID0gJHRyYW5zbGF0aW9uLT5nZXRDbG9uZSgkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4iXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXBwZW5kID09PSAnT3JpZ2luYWwnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb24tPmdldENsb25lKG51bGwsICR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4iXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXBwZW5kID09PSAnUGx1cmFsVHJhbnNsYXRpb24nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcCA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcFtdID0gYXJyYXlfcG9wKCRwKS4iXG4iLnN0YXRpYzo6Y29udmVydFN0cmluZygkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFBsdXJhbFRyYW5zbGF0aW9ucygkcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGdldE1ldGhvZCA9ICdnZXQnLiRhcHBlbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICRzZXRNZXRob2QgPSAnc2V0Jy4kYXBwZW5kOwogICAgICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPiRzZXRNZXRob2QoJHRyYW5zbGF0aW9uLT4kZ2V0TWV0aG9kKCkuIlxuIi5zdGF0aWM6OmNvbnZlcnRTdHJpbmcoJGRhdGEpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc09yaWdpbmFsKCkgJiYgIWluX2FycmF5KCR0cmFuc2xhdGlvbiwgaXRlcmF0b3JfdG9fYXJyYXkoJHRyYW5zbGF0aW9ucykpKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnNbXSA9ICR0cmFuc2xhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIG9uZSBzdHJpbmcgZnJvbSBtdWx0aWxpbmUgc3RyaW5ncy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lCiAgICAgKiBAcGFyYW0gYXJyYXkgICRsaW5lcwogICAgICogQHBhcmFtIGludCAgICAmJGkKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZpeE11bHRpTGluZXMoJGxpbmUsIGFycmF5ICRsaW5lcywgJiRpKQogICAgewogICAgICAgIGZvciAoJGogPSAkaSwgJHQgPSBjb3VudCgkbGluZXMpOyAkaiA8ICR0OyArKyRqKSB7CiAgICAgICAgICAgIGlmIChzdWJzdHIoJGxpbmUsIC0xLCAxKSA9PSAnIicKICAgICAgICAgICAgICAgICYmIGlzc2V0KCRsaW5lc1skaiArIDFdKQogICAgICAgICAgICAgICAgJiYgc3Vic3RyKHRyaW0oJGxpbmVzWyRqICsgMV0pLCAwLCAxKSA9PSAnIicKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbGluZSA9IHN1YnN0cigkbGluZSwgMCwgLTEpLnN1YnN0cih0cmltKCRsaW5lc1skaiArIDFdKSwgMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkaSA9ICRqOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkbGluZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnQgYSBzdHJpbmcgZnJvbSBpdHMgUE8gcmVwcmVzZW50YXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbnZlcnRTdHJpbmcoJHZhbHVlKQogICAgewogICAgICAgIGlmICghJHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgIGlmICgkdmFsdWVbMF0gPT09ICciJykgewogICAgICAgICAgICAkdmFsdWUgPSBzdWJzdHIoJHZhbHVlLCAxLCAtMSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RydHIoCiAgICAgICAgICAgICR2YWx1ZSwKICAgICAgICAgICAgWwogICAgICAgICAgICAgICAgJ1xcXFwnID0+ICdcXCcsCiAgICAgICAgICAgICAgICAnXFxhJyA9PiAiXHgwNyIsCiAgICAgICAgICAgICAgICAnXFxiJyA9PiAiXHgwOCIsCiAgICAgICAgICAgICAgICAnXFx0JyA9PiAiXHQiLAogICAgICAgICAgICAgICAgJ1xcbicgPT4gIlxuIiwKICAgICAgICAgICAgICAgICdcXHYnID0+ICJceDBiIiwKICAgICAgICAgICAgICAgICdcXGYnID0+ICJceDBjIiwKICAgICAgICAgICAgICAgICdcXHInID0+ICJcciIsCiAgICAgICAgICAgICAgICAnXFwiJyA9PiAnIicsCiAgICAgICAgICAgIF0KICAgICAgICApOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKdXNlIFN5bWZvbnlcQ29tcG9uZW50XFlhbWxcWWFtbCBhcyBZYW1sUGFyc2VyOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSB5YW1sLgogKi8KY2xhc3MgWWFtbCBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBZYW1sUGFyc2VyOjpwYXJzZSgkc3RyaW5nKTsKCiAgICAgICAgaWYgKGlzX2FycmF5KCRtZXNzYWdlcykpIHsKICAgICAgICAgICAgc3RhdGljOjpmcm9tQXJyYXkoJG1lc3NhZ2VzLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgppbnRlcmZhY2UgRXh0cmFjdG9yTXVsdGlJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdHJpbmcgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKiBBbGxvd3Mgc2Nhbm5pbmcgZm9yIG11bHRpcGxlIGRvbWFpbnMgYXQgYSB0aW1lIChlYWNoIFRyYW5zbGF0aW9uIGhhcyB0byBoYXZlIGEgZGlmZmVyZW50IGRvbWFpbikKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdHJpbmcgYW5kIGFwcGVuZCB0aGUgdHJhbnNsYXRpb25zIGZvdW5kIGluIHRoZSBUcmFuc2xhdGlvbnMgaW5zdGFuY2UuCiAgICAgKiBBbGxvd3Mgc2Nhbm5pbmcgZm9yIG11bHRpcGxlIGRvbWFpbnMgYXQgYSB0aW1lIChlYWNoIFRyYW5zbGF0aW9uIGhhcyB0byBoYXZlIGEgZGlmZmVyZW50IGRvbWFpbikKICAgICAqCiAgICAgKiBAcGFyYW0gJGZpbGUKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tRmlsZU11bHRpcGxlKCRmaWxlLCBhcnJheSAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcSGVhZGVyc0V4dHJhY3RvclRyYWl0Owp1c2UgR2V0dGV4dFxVdGlsc1xDc3ZUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gY3N2LgogKi8KY2xhc3MgQ3N2RGljdGlvbmFyeSBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgSGVhZGVyc0V4dHJhY3RvclRyYWl0OwogICAgdXNlIENzdlRyYWl0OwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2RlbGltaXRlcicgPT4gIiwiLAogICAgICAgICdlbmNsb3N1cmUnID0+ICciJywKICAgICAgICAnZXNjYXBlX2NoYXInID0+ICJcXCIKICAgIF07CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwogICAgICAgICRoYW5kbGUgPSBmb3BlbigncGhwOi8vbWVtb3J5JywgJ3cnKTsKCiAgICAgICAgZnB1dHMoJGhhbmRsZSwgJHN0cmluZyk7CiAgICAgICAgcmV3aW5kKCRoYW5kbGUpOwoKICAgICAgICB3aGlsZSAoJHJvdyA9IHN0YXRpYzo6ZmdldGNzdigkaGFuZGxlLCAkb3B0aW9ucykpIHsKICAgICAgICAgICAgbGlzdCgkb3JpZ2luYWwsICR0cmFuc2xhdGlvbikgPSAkcm93ICsgWycnLCAnJ107CgogICAgICAgICAgICBpZiAoJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgc3RhdGljOjpleHRyYWN0SGVhZGVycygkdHJhbnNsYXRpb24sICR0cmFuc2xhdGlvbnMpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPmluc2VydChudWxsLCAkb3JpZ2luYWwpLT5zZXRUcmFuc2xhdGlvbigkdHJhbnNsYXRpb24pOwogICAgICAgIH0KCiAgICAgICAgZmNsb3NlKCRoYW5kbGUpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSBqc29uIGZpbGVzLgogKi8KY2xhc3MgSmVkIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgc3RhdGljOjpleHRyYWN0KGpzb25fZGVjb2RlKCRzdHJpbmcsIHRydWUpLCAkdHJhbnNsYXRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSBhbiBhcnJheSBvZiB0cmFuc2xhdGlvbnMgYW5kIGFwcGVuZCB0byB0aGUgVHJhbnNsYXRpb25zIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgJGNvbnRlbnQKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4dHJhY3QoYXJyYXkgJGNvbnRlbnQsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IGN1cnJlbnQoJGNvbnRlbnQpOwogICAgICAgICRoZWFkZXJzID0gaXNzZXQoJG1lc3NhZ2VzWycnXSkgPyAkbWVzc2FnZXNbJyddIDogbnVsbDsKICAgICAgICB1bnNldCgkbWVzc2FnZXNbJyddKTsKCiAgICAgICAgaWYgKCFlbXB0eSgkaGVhZGVyc1snZG9tYWluJ10pKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldERvbWFpbigkaGVhZGVyc1snZG9tYWluJ10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbXB0eSgkaGVhZGVyc1snbGFuZyddKSkgewogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXRMYW5ndWFnZSgkaGVhZGVyc1snbGFuZyddKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcnNbJ3BsdXJhbC1mb3JtcyddKSkgewogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoVHJhbnNsYXRpb25zOjpIRUFERVJfUExVUkFMLCAkaGVhZGVyc1sncGx1cmFsLWZvcm1zJ10pOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRleHRfZ2x1ZSA9ICdcdTAwMDQnOwoKICAgICAgICBmb3JlYWNoICgkbWVzc2FnZXMgYXMgJGtleSA9PiAkdHJhbnNsYXRpb24pIHsKICAgICAgICAgICAgJGtleSA9IGV4cGxvZGUoJGNvbnRleHRfZ2x1ZSwgJGtleSk7CiAgICAgICAgICAgICRjb250ZXh0ID0gaXNzZXQoJGtleVsxXSkgPyBhcnJheV9zaGlmdCgka2V5KSA6ICcnOwoKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KCRjb250ZXh0LCBhcnJheV9zaGlmdCgka2V5KSkKICAgICAgICAgICAgICAgIC0+c2V0VHJhbnNsYXRpb24oYXJyYXlfc2hpZnQoJHRyYW5zbGF0aW9uKSkKICAgICAgICAgICAgICAgIC0+c2V0UGx1cmFsVHJhbnNsYXRpb25zKCR0cmFuc2xhdGlvbik7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCi8qKiBAbm9pbnNwZWN0aW9uIFBocENvbXBvc2VyRXh0ZW5zaW9uU3R1YnNJbnNwZWN0aW9uICovCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIERPTUF0dHI7CnVzZSBET01Eb2N1bWVudDsKdXNlIERPTUVsZW1lbnQ7CnVzZSBET01Ob2RlOwp1c2UgRXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEZ1bmN0aW9uc1NjYW5uZXI7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIFZ1ZUpTIHRlbXBsYXRlIGZpbGVzLgogKi8KY2xhc3MgVnVlSnMgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UsIEV4dHJhY3Rvck11bHRpSW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2NvbnN0YW50cycgPT4gW10sCgogICAgICAgICdmdW5jdGlvbnMnID0+IFsKICAgICAgICAgICAgJ2dldHRleHQnID0+ICdnZXR0ZXh0JywKICAgICAgICAgICAgJ19fJyA9PiAnZ2V0dGV4dCcsCiAgICAgICAgICAgICduZ2V0dGV4dCcgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ25fXycgPT4gJ25nZXR0ZXh0JywKICAgICAgICAgICAgJ3BnZXR0ZXh0JyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAncF9fJyA9PiAncGdldHRleHQnLAogICAgICAgICAgICAnZGdldHRleHQnID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkX18nID0+ICdkZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbmdldHRleHQnID0+ICdkbmdldHRleHQnLAogICAgICAgICAgICAnZG5fXycgPT4gJ2RuZ2V0dGV4dCcsCiAgICAgICAgICAgICdkcGdldHRleHQnID0+ICdkcGdldHRleHQnLAogICAgICAgICAgICAnZHBfXycgPT4gJ2RwZ2V0dGV4dCcsCiAgICAgICAgICAgICducGdldHRleHQnID0+ICducGdldHRleHQnLAogICAgICAgICAgICAnbnBfXycgPT4gJ25wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBnZXR0ZXh0JyA9PiAnZG5wZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbnBfXycgPT4gJ2RucGdldHRleHQnLAogICAgICAgICAgICAnbm9vcCcgPT4gJ25vb3AnLAogICAgICAgICAgICAnbm9vcF9fJyA9PiAnbm9vcCcsCiAgICAgICAgXSwKICAgIF07CgogICAgcHJvdGVjdGVkIHN0YXRpYyAkZnVuY3Rpb25zU2Nhbm5lckNsYXNzID0gJ0dldHRleHRcVXRpbHNcSnNGdW5jdGlvbnNTY2FubmVyJzsKCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlTXVsdGlwbGUoJGZpbGUsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjpnZXRGaWxlcygkZmlsZSkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2ZpbGUnXSA9ICRmaWxlOwogICAgICAgICAgICBzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZShzdGF0aWM6OnJlYWRGaWxlKCRmaWxlKSwgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0ZG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHN0cmluZywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgWyR0cmFuc2xhdGlvbnNdLCAkb3B0aW9ucyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAaW5oZXJpdERvYwogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nTXVsdGlwbGUoJHN0cmluZywgYXJyYXkgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwogICAgICAgICRvcHRpb25zICs9IFsKICAgICAgICAgICAgLy8gSFRNTCBhdHRyaWJ1dGUgcHJlZml4ZXMgd2UgcGFyc2UgYXMgSlMgd2hpY2ggY291bGQgY29udGFpbiB0cmFuc2xhdGlvbnMgKGFyZSBKUyBleHByZXNzaW9ucykKICAgICAgICAgICAgJ2F0dHJpYnV0ZVByZWZpeGVzJyA9PiBbCiAgICAgICAgICAgICAgICAnOicsCiAgICAgICAgICAgICAgICAndi1iaW5kOicsCiAgICAgICAgICAgICAgICAndi1vbjonLAogICAgICAgICAgICAgICAgJ3YtdGV4dCcsCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgIC8vIEhUTUwgVGFncyB0byBwYXJzZQogICAgICAgICAgICAndGFnTmFtZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUnLAogICAgICAgICAgICBdLAogICAgICAgICAgICAvLyBIVE1MIHRhZ3MgdG8gcGFyc2Ugd2hlbiBhdHRyaWJ1dGUgZXhpc3RzCiAgICAgICAgICAgICd0YWdBdHRyaWJ1dGVzJyA9PiBbCiAgICAgICAgICAgICAgICAndi10cmFuc2xhdGUnLAogICAgICAgICAgICBdLAogICAgICAgICAgICAvLyBDb21tZW50cwogICAgICAgICAgICAnY29tbWVudEF0dHJpYnV0ZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUtY29tbWVudCcsCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICdjb250ZXh0QXR0cmlidXRlcycgPT4gWwogICAgICAgICAgICAgICAgJ3RyYW5zbGF0ZS1jb250ZXh0JywKICAgICAgICAgICAgXSwKICAgICAgICAgICAgLy8gQXR0cmlidXRlIHdpdGggcGx1cmFsIGNvbnRlbnQKICAgICAgICAgICAgJ3BsdXJhbEF0dHJpYnV0ZXMnID0+IFsKICAgICAgICAgICAgICAgICd0cmFuc2xhdGUtcGx1cmFsJywKICAgICAgICAgICAgXSwKICAgICAgICBdOwoKICAgICAgICAvLyBPaywgdGhpcyBpcyB0aGUgd2VpcmRlc3QgaGFjaywgYnV0IGxldCBtZSBleHBsYWluOgogICAgICAgIC8vIE9uIExpbnV4IChNYWMgaXMgZmluZSksIHdoZW4gY29udmVydGluZyBIVE1MIHRvIERPTSwgbmV3IGxpbmVzIGdldCB0cmltbWVkIGFmdGVyIHRoZSBmaXJzdCB0YWcuCiAgICAgICAgLy8gU28gaWYgdGhlcmUgYXJlIG5ldyBsaW5lcyBiZXR3ZWVuIDx0ZW1wbGF0ZT4gYW5kIG5leHQgZWxlbWVudCwgdGhleSBhcmUgbG9zdAogICAgICAgIC8vIFNvIHdlIGluc2VydCBhICIuIiB3aGljaCBpcyBhIHRleHQgbm9kZSwgYW5kIGl0IHdpbGwgcHJldmVudCB0aGF0IG5ld2xpbmVzIGFyZSBzdHJpcHBlZCBiZXR3ZWVuIGVsZW1lbnRzLgogICAgICAgIC8vIFNhbWUgdGhpbmcgaGFwcGVucyBiZXR3ZWVuIHRlbXBsYXRlIGFuZCBzY3JpcHQgdGFnLgogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnPHRlbXBsYXRlPicsICc8dGVtcGxhdGU+LicsICRzdHJpbmcpOwogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnPC90ZW1wbGF0ZT4nLCAnPC90ZW1wbGF0ZT4uJywgJHN0cmluZyk7CgogICAgICAgIC8vIE5vcm1hbGl6ZSBuZXdsaW5lcwogICAgICAgICRzdHJpbmcgPSBzdHJfcmVwbGFjZShbIlxyXG4iLCAiXG5cciIsICJcciJdLCAiXG4iLCAkc3RyaW5nKTsKCiAgICAgICAgLy8gVnVlSlMgZmlsZXMgYXJlIHZhbGlkIEhUTUwgZmlsZXMsIHdlIHdpbGwgb3BlcmF0ZSB3aXRoIHRoZSBET00gaGVyZQogICAgICAgICRkb20gPSBzdGF0aWM6OmNvbnZlcnRIdG1sVG9Eb20oJHN0cmluZyk7CgogICAgICAgICRzY3JpcHQgPSBzdGF0aWM6OmV4dHJhY3RTY3JpcHRUYWcoJHN0cmluZyk7CgogICAgICAgIC8vIFBhcnNlIHRoZSBzY3JpcHQgcGFydCBhcyBhIHJlZ3VsYXIgSlMgY29kZQogICAgICAgIGlmICgkc2NyaXB0KSB7CiAgICAgICAgICAgICRzY3JpcHRMaW5lTnVtYmVyID0gJGRvbS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpLT5pdGVtKDApLT5nZXRMaW5lTm8oKTsKICAgICAgICAgICAgc3RhdGljOjpnZXRTY3JpcHRUcmFuc2xhdGlvbnNGcm9tU3RyaW5nKAogICAgICAgICAgICAgICAgJHNjcmlwdCwKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbnMsCiAgICAgICAgICAgICAgICAkb3B0aW9ucywKICAgICAgICAgICAgICAgICRzY3JpcHRMaW5lTnVtYmVyIC0gMQogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgLy8gVGVtcGxhdGUgcGFydCBpcyBwYXJzZWQgc2VwYXJhdGVseSwgYWxsIHZhcmlhYmxlcyB3aWxsIGJlIGV4dHJhY3RlZAogICAgICAgIC8vIGFuZCBoYW5kbGVkIGFzIGEgcmVndWxhciBKUyBjb2RlCiAgICAgICAgJHRlbXBsYXRlID0gJGRvbS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RlbXBsYXRlJyktPml0ZW0oMCk7CiAgICAgICAgaWYgKCR0ZW1wbGF0ZSkgewogICAgICAgICAgICBzdGF0aWM6OmdldFRlbXBsYXRlVHJhbnNsYXRpb25zKAogICAgICAgICAgICAgICAgJHRlbXBsYXRlLAogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9ucywKICAgICAgICAgICAgICAgICRvcHRpb25zLAogICAgICAgICAgICAgICAgJHRlbXBsYXRlLT5nZXRMaW5lTm8oKSAtIDEKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0cyBzY3JpcHQgdGFnIGNvbnRlbnRzIHVzaW5nIHJlZ2V4IGluc3RlYWQgb2YgRE9NIG9wZXJhdGlvbnMuCiAgICAgKiBJZiB3ZSBwYXJzZSB1c2luZyBET00sIHNvbWUgY29udGVudHMgbWF5IGNoYW5nZSwgZm9yIGV4YW1wbGUsIHRhZ3Mgd2l0aGluIHN0cmluZ3Mgd2lsbCBiZSBzdHJpcHBlZAogICAgICoKICAgICAqIEBwYXJhbSAkc3RyaW5nCiAgICAgKiBAcmV0dXJuIGJvb2x8c3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZXh0cmFjdFNjcmlwdFRhZygkc3RyaW5nKQogICAgewogICAgICAgIGlmIChwcmVnX21hdGNoKCcjPFxzKj9zY3JpcHRcYltePl0qPiguKj8pPC9zY3JpcHRcYltePl0qPiNzJywgJHN0cmluZywgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkbWF0Y2hlc1sxXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAnJzsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGh0bWwKICAgICAqIEByZXR1cm4gRE9NRG9jdW1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0SHRtbFRvRG9tKCRodG1sKQogICAgewogICAgICAgICRkb20gPSBuZXcgRE9NRG9jdW1lbnQ7CgogICAgICAgIGxpYnhtbF91c2VfaW50ZXJuYWxfZXJyb3JzKHRydWUpOwoKICAgICAgICAvLyBQcmVwZW5kIHhtbCBlbmNvZGluZyBzbyBET01Eb2N1bWVudCBkb2N1bWVudCBoYW5kbGVzIFVURjggY29ycmVjdGx5LgogICAgICAgIC8vIEFzc3VtaW5nIHRoYXQgdnVlIHRlbXBsYXRlIGZpbGVzIHdpbGwgbm90IGhhdmUgYW55IHhtbCBlbmNvZGluZyB0YWdzLCBiZWNhdXNlIGR1cGxpY2F0ZSB0YWdzIG1heSBiZSBpZ25vcmVkLgogICAgICAgICRkb20tPmxvYWRIVE1MKCc8P3htbCBlbmNvZGluZz0idXRmLTgiPz4nIC4gJGh0bWwpOwoKICAgICAgICBsaWJ4bWxfY2xlYXJfZXJyb3JzKCk7CgogICAgICAgIHJldHVybiAkZG9tOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCB0cmFuc2xhdGlvbnMgZnJvbSBzY3JpcHQgcGFydAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNjcmlwdENvbnRlbnRzIE9ubHkgc2NyaXB0IHRhZyBjb250ZW50cywgbm90IHRoZSB3aG9sZSB0ZW1wbGF0ZQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zIE9uZSBvciBtdWx0aXBsZSBkb21haW4gVHJhbnNsYXRpb24gb2JqZWN0cwogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lT2Zmc2V0IE51bWJlciBvZiBsaW5lcyB0aGUgc2NyaXB0IGlzIG9mZnNldCBpbiB0aGUgdnVlIHRlbXBsYXRlIGZpbGUKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0U2NyaXB0VHJhbnNsYXRpb25zRnJvbVN0cmluZygKICAgICAgICAkc2NyaXB0Q29udGVudHMsCiAgICAgICAgJHRyYW5zbGF0aW9ucywKICAgICAgICBhcnJheSAkb3B0aW9ucyA9IFtdLAogICAgICAgICRsaW5lT2Zmc2V0ID0gMAogICAgKSB7CiAgICAgICAgLyoqIEB2YXIgRnVuY3Rpb25zU2Nhbm5lciAkZnVuY3Rpb25zICovCiAgICAgICAgJGZ1bmN0aW9ucyA9IG5ldyBzdGF0aWM6OiRmdW5jdGlvbnNTY2FubmVyQ2xhc3MoJHNjcmlwdENvbnRlbnRzKTsKICAgICAgICAkb3B0aW9uc1snbGluZU9mZnNldCddID0gJGxpbmVPZmZzZXQ7CiAgICAgICAgJGZ1bmN0aW9ucy0+c2F2ZUdldHRleHRGdW5jdGlvbnMoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2UgdGVtcGxhdGUgdG8gZXh0cmFjdCBhbGwgdHJhbnNsYXRpb25zIChlbGVtZW50IGNvbnRlbnQgYW5kIGR5bmFtaWMgZWxlbWVudCBhdHRyaWJ1dGVzKQogICAgICoKICAgICAqIEBwYXJhbSBET01Ob2RlICRkb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnN8VHJhbnNsYXRpb25zW10gJHRyYW5zbGF0aW9ucyBPbmUgb3IgbXVsdGlwbGUgZG9tYWluIFRyYW5zbGF0aW9uIG9iamVjdHMKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIGludCAkbGluZU9mZnNldCBMaW5lIG51bWJlciB3aGVyZSB0aGUgdGVtcGxhdGUgcGFydCBzdGFydHMgaW4gdGhlIHZ1ZSBmaWxlCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldFRlbXBsYXRlVHJhbnNsYXRpb25zKAogICAgICAgIERPTU5vZGUgJGRvbSwKICAgICAgICAkdHJhbnNsYXRpb25zLAogICAgICAgIGFycmF5ICRvcHRpb25zLAogICAgICAgICRsaW5lT2Zmc2V0ID0gMAogICAgKSB7CiAgICAgICAgLy8gQnVpbGQgYSBKUyBzdHJpbmcgZnJvbSBhbGwgdGVtcGxhdGUgYXR0cmlidXRlIGV4cHJlc3Npb25zCiAgICAgICAgJGZha2VBdHRyaWJ1dGVKcyA9IHN0YXRpYzo6Z2V0VGVtcGxhdGVBdHRyaWJ1dGVGYWtlSnMoJG9wdGlvbnMsICRkb20pOwoKICAgICAgICAvLyAxIGxpbmUgb2Zmc2V0IGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHBhcmVudCB0ZW1wbGF0ZSBlbGVtZW50IHdhcyBpZ25vcmVkIHdoZW4gY29udmVydGluZyB0byBET00KICAgICAgICBzdGF0aWM6OmdldFNjcmlwdFRyYW5zbGF0aW9uc0Zyb21TdHJpbmcoJGZha2VBdHRyaWJ1dGVKcywgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMsICRsaW5lT2Zmc2V0KTsKCiAgICAgICAgLy8gQnVpbGQgYSBKUyBzdHJpbmcgZnJvbSB0ZW1wbGF0ZSBlbGVtZW50IGNvbnRlbnQgZXhwcmVzc2lvbnMKICAgICAgICAkZmFrZVRlbXBsYXRlSnMgPSBzdGF0aWM6OmdldFRlbXBsYXRlRmFrZUpzKCRkb20pOwogICAgICAgIHN0YXRpYzo6Z2V0U2NyaXB0VHJhbnNsYXRpb25zRnJvbVN0cmluZygkZmFrZVRlbXBsYXRlSnMsICR0cmFuc2xhdGlvbnMsICRvcHRpb25zLCAkbGluZU9mZnNldCk7CgogICAgICAgIHN0YXRpYzo6Z2V0VGFnVHJhbnNsYXRpb25zKCRvcHRpb25zLCAkZG9tLCAkdHJhbnNsYXRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VGFnVHJhbnNsYXRpb25zKGFycmF5ICRvcHRpb25zLCBET01Ob2RlICRkb20sICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgLy8gU2luY2UgdGFnIHNjYW5uaW5nIGRvZXMgbm90IHN1cHBvcnQgZG9tYWlucywgd2UgYWx3YXlzIHVzZSB0aGUgZmlyc3QgdHJhbnNsYXRpb24gZ2l2ZW4KICAgICAgICAkdHJhbnNsYXRpb25zID0gaXNfYXJyYXkoJHRyYW5zbGF0aW9ucykgPyByZXNldCgkdHJhbnNsYXRpb25zKSA6ICR0cmFuc2xhdGlvbnM7CgogICAgICAgICRjaGlsZHJlbiA9ICRkb20tPmNoaWxkTm9kZXM7CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGNoaWxkcmVuLT5sZW5ndGg7ICRpKyspIHsKICAgICAgICAgICAgJG5vZGUgPSAkY2hpbGRyZW4tPml0ZW0oJGkpOwoKICAgICAgICAgICAgaWYgKCEoJG5vZGUgaW5zdGFuY2VvZiBET01FbGVtZW50KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmFuc2xhdGFibGUgPSBmYWxzZTsKCiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkbm9kZS0+dGFnTmFtZSwgJG9wdGlvbnNbJ3RhZ05hbWVzJ10sIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRhYmxlID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGF0dHJMaXN0ID0gJG5vZGUtPmF0dHJpYnV0ZXM7CiAgICAgICAgICAgICRjb250ZXh0ID0gbnVsbDsKICAgICAgICAgICAgJHBsdXJhbCA9ICIiOwogICAgICAgICAgICAkY29tbWVudCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkYXR0ckxpc3QtPmxlbmd0aDsgJGorKykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgRE9NQXR0ciAkZG9tQXR0ciAqLwogICAgICAgICAgICAgICAgJGRvbUF0dHIgPSAkYXR0ckxpc3QtPml0ZW0oJGopOwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGR5bmFtaWMgdnVlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1sndGFnQXR0cmlidXRlcyddKSkgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGFibGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1snY29udGV4dEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29udGV4dCA9ICRkb21BdHRyLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkZG9tQXR0ci0+bmFtZSwgJG9wdGlvbnNbJ3BsdXJhbEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkcGx1cmFsID0gJGRvbUF0dHItPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRkb21BdHRyLT5uYW1lLCAkb3B0aW9uc1snY29tbWVudEF0dHJpYnV0ZXMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkY29tbWVudCA9ICRkb21BdHRyLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGFibGUpIHsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgdHJpbSgkbm9kZS0+dGV4dENvbnRlbnQpLCAkcGx1cmFsKTsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+YWRkUmVmZXJlbmNlKCRvcHRpb25zWydmaWxlJ10sICRub2RlLT5nZXRMaW5lTm8oKSk7CiAgICAgICAgICAgICAgICBpZiAoJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoJGNvbW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG5vZGUtPmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgc3RhdGljOjpnZXRUYWdUcmFuc2xhdGlvbnMoJG9wdGlvbnMsICRub2RlLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgSlMgZXhwcmVzc2lvbnMgZnJvbSBlbGVtZW50IGF0dHJpYnV0ZSBiaW5kaW5ncyAoZXhjbHVkaW5nIHRleHQgd2l0aGluIGVsZW1lbnRzKQogICAgICogRm9yIGV4YW1wbGU6IDxzcGFuIDp0aXRsZT0iX18oJ2V4dHJhY3QgdGhpcycpIj4gc2tpcCBlbGVtZW50IGNvbnRlbnQgPC9zcGFuPgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucwogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHJldHVybiBzdHJpbmcgSlMgY29kZQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldFRlbXBsYXRlQXR0cmlidXRlRmFrZUpzKGFycmF5ICRvcHRpb25zLCBET01Ob2RlICRkb20pCiAgICB7CiAgICAgICAgJGV4cHJlc3Npb25zQnlMaW5lID0gc3RhdGljOjpnZXRWdWVBdHRyaWJ1dGVFeHByZXNzaW9ucygkb3B0aW9uc1snYXR0cmlidXRlUHJlZml4ZXMnXSwgJGRvbSk7CgogICAgICAgIGlmIChlbXB0eSgkZXhwcmVzc2lvbnNCeUxpbmUpKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CgogICAgICAgICRtYXhMaW5lcyA9IG1heChhcnJheV9rZXlzKCRleHByZXNzaW9uc0J5TGluZSkpOwogICAgICAgICRmYWtlSnMgPSAnJzsKCiAgICAgICAgZm9yICgkbGluZSA9IDE7ICRsaW5lIDw9ICRtYXhMaW5lczsgJGxpbmUrKykgewogICAgICAgICAgICBpZiAoaXNzZXQoJGV4cHJlc3Npb25zQnlMaW5lWyRsaW5lXSkpIHsKICAgICAgICAgICAgICAgICRmYWtlSnMgLj0gaW1wbG9kZSgiOyAiLCAkZXhwcmVzc2lvbnNCeUxpbmVbJGxpbmVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZmFrZUpzIC49ICJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZha2VKczsKICAgIH0KCiAgICAvKioKICAgICAqIExvb3AgRE9NIGVsZW1lbnQgcmVjdXJzaXZlbHkgYW5kIHBhcnNlIG91dCBhbGwgZHluYW1pYyB2dWUgYXR0cmlidXRlcyB3aGljaCBhcmUgYmFzaWNhbGx5IEpTIGV4cHJlc3Npb25zCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRhdHRyaWJ1dGVQcmVmaXhlcyBMaXN0IG9mIGF0dHJpYnV0ZSBwcmVmaXhlcyB3ZSBwYXJzZSBhcyBKUyAobWF5IGNvbnRhaW4gdHJhbnNsYXRpb25zKQogICAgICogQHBhcmFtIERPTU5vZGUgJGRvbQogICAgICogQHBhcmFtIGFycmF5ICRleHByZXNzaW9uQnlMaW5lIFtsaW5lTnVtYmVyID0+IFtqc0V4cHJlc3Npb24sIC4uXSwgLi5dCiAgICAgKiBAcmV0dXJuIGFycmF5IFtsaW5lTnVtYmVyID0+IFtqc0V4cHJlc3Npb24sIC4uXSwgLi5dCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VnVlQXR0cmlidXRlRXhwcmVzc2lvbnMoCiAgICAgICAgYXJyYXkgJGF0dHJpYnV0ZVByZWZpeGVzLAogICAgICAgIERPTU5vZGUgJGRvbSwKICAgICAgICBhcnJheSAmJGV4cHJlc3Npb25CeUxpbmUgPSBbXQogICAgKSB7CiAgICAgICAgJGNoaWxkcmVuID0gJGRvbS0+Y2hpbGROb2RlczsKCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGNoaWxkcmVuLT5sZW5ndGg7ICRpKyspIHsKICAgICAgICAgICAgJG5vZGUgPSAkY2hpbGRyZW4tPml0ZW0oJGkpOwoKICAgICAgICAgICAgaWYgKCEoJG5vZGUgaW5zdGFuY2VvZiBET01FbGVtZW50KSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGF0dHJMaXN0ID0gJG5vZGUtPmF0dHJpYnV0ZXM7CgogICAgICAgICAgICBmb3IgKCRqID0gMDsgJGogPCAkYXR0ckxpc3QtPmxlbmd0aDsgJGorKykgewogICAgICAgICAgICAgICAgLyoqIEB2YXIgRE9NQXR0ciAkZG9tQXR0ciAqLwogICAgICAgICAgICAgICAgJGRvbUF0dHIgPSAkYXR0ckxpc3QtPml0ZW0oJGopOwoKICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBkeW5hbWljIHZ1ZSBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgIGlmIChzdGF0aWM6OmlzQXR0cmlidXRlTWF0Y2hpbmcoJGRvbUF0dHItPm5hbWUsICRhdHRyaWJ1dGVQcmVmaXhlcykpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9ICRkb21BdHRyLT5nZXRMaW5lTm8oKTsKICAgICAgICAgICAgICAgICAgICAkZXhwcmVzc2lvbkJ5TGluZSArPSBbJGxpbmUgPT4gW11dOwogICAgICAgICAgICAgICAgICAgICRleHByZXNzaW9uQnlMaW5lWyRsaW5lXVtdID0gJGRvbUF0dHItPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJG5vZGUtPmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgJGV4cHJlc3Npb25CeUxpbmUgPSBzdGF0aWM6OmdldFZ1ZUF0dHJpYnV0ZUV4cHJlc3Npb25zKCRhdHRyaWJ1dGVQcmVmaXhlcywgJG5vZGUsICRleHByZXNzaW9uQnlMaW5lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRleHByZXNzaW9uQnlMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhpcyBhdHRyaWJ1dGUgbmFtZSBzaG91bGQgYmUgcGFyc2VkIGZvciB0cmFuc2xhdGlvbnMKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhdHRyaWJ1dGVOYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nW10gJGF0dHJpYnV0ZVByZWZpeGVzCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBpc0F0dHJpYnV0ZU1hdGNoaW5nKCRhdHRyaWJ1dGVOYW1lLCAkYXR0cmlidXRlUHJlZml4ZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJGF0dHJpYnV0ZVByZWZpeGVzIGFzICRwcmVmaXgpIHsKICAgICAgICAgICAgaWYgKHN0cnBvcygkYXR0cmlidXRlTmFtZSwgJHByZWZpeCkgPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgSlMgZXhwcmVzc2lvbnMgZnJvbSB3aXRoaW4gdGVtcGxhdGUgZWxlbWVudHMgKGV4Y2x1ZGluZyBhdHRyaWJ1dGVzKQogICAgICogRm9yIGV4YW1wbGU6IDxzcGFuIDp0aXRsZT0ic2tpcCBhdHRyaWJ1dGVzIj4ge3tfXygiZXh0cmFjdCBlbGVtZW50IGNvbnRlbnQiKX19IDwvc3Bhbj4KICAgICAqCiAgICAgKiBAcGFyYW0gRE9NTm9kZSAkZG9tCiAgICAgKiBAcmV0dXJuIHN0cmluZyBKUyBjb2RlCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0VGVtcGxhdGVGYWtlSnMoRE9NTm9kZSAkZG9tKQogICAgewogICAgICAgICRmYWtlSnMgPSAnJzsKICAgICAgICAkbGluZXMgPSBleHBsb2RlKCJcbiIsICRkb20tPnRleHRDb250ZW50KTsKCiAgICAgICAgLy8gQnVpbGQgYSBmYWtlIEpTIGZpbGUgZnJvbSB0ZW1wbGF0ZSBieSBleHRyYWN0aW5nIEpTIGV4cHJlc3Npb25zIHdpdGhpbiBlYWNoIHRlbXBsYXRlIGxpbmUKICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGxpbmUpIHsKICAgICAgICAgICAgJGV4cHJlc3Npb25NYXRjaGVkID0gc3RhdGljOjpwYXJzZU9uZVRlbXBsYXRlTGluZSgkbGluZSk7CgogICAgICAgICAgICAkZmFrZUpzIC49IGltcGxvZGUoIjsgIiwgJGV4cHJlc3Npb25NYXRjaGVkKSAuICJcbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZha2VKczsKICAgIH0KCiAgICAvKioKICAgICAqIE1hdGNoIEpTIGV4cHJlc3Npb25zIGluIGEgdGVtcGxhdGUgbGluZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxpbmUKICAgICAqIEByZXR1cm4gc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBwYXJzZU9uZVRlbXBsYXRlTGluZSgkbGluZSkKICAgIHsKICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOwoKICAgICAgICBpZiAoISRsaW5lKSB7CiAgICAgICAgICAgIHJldHVybiBbXTsKICAgICAgICB9CgogICAgICAgICRyZWdleCA9ICcjXHtceyguKj8pXH1cfSMnOwoKICAgICAgICBwcmVnX21hdGNoX2FsbCgkcmVnZXgsICRsaW5lLCAkbWF0Y2hlcyk7CgogICAgICAgICRtYXRjaGVkID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkdikgewogICAgICAgICAgICByZXR1cm4gdHJpbSgkdiwgJ1wnInt9Jyk7CiAgICAgICAgfSwgJG1hdGNoZXNbMV0pOwoKICAgICAgICByZXR1cm4gJG1hdGNoZWQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgRXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXFN0cmluZ1JlYWRlcjsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gLm1vIGZpbGVzLgogKi8KY2xhc3MgTW8gZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgY29uc3QgTUFHSUMxID0gLTE3OTQ4OTUxMzg7CiAgICBjb25zdCBNQUdJQzIgPSAtNTY5MjQ0NTIzOwogICAgY29uc3QgTUFHSUMzID0gMjUwMDA3MjE1ODsKCiAgICBwcm90ZWN0ZWQgc3RhdGljICRzdHJpbmdSZWFkZXJDbGFzcyA9ICdHZXR0ZXh0XFV0aWxzXFN0cmluZ1JlYWRlcic7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAvKiogQHZhciBTdHJpbmdSZWFkZXIgJHN0cmVhbSAqLwogICAgICAgICRzdHJlYW0gPSBuZXcgc3RhdGljOjokc3RyaW5nUmVhZGVyQ2xhc3MoJHN0cmluZyk7CiAgICAgICAgJG1hZ2ljID0gc3RhdGljOjpyZWFkSW50KCRzdHJlYW0sICdWJyk7CgogICAgICAgIGlmICgoJG1hZ2ljID09PSBzdGF0aWM6Ok1BR0lDMSkgfHwgKCRtYWdpYyA9PT0gc3RhdGljOjpNQUdJQzMpKSB7IC8vdG8gbWFrZSBzdXJlIGl0IHdvcmtzIGZvciA2NC1iaXQgcGxhdGZvcm1zCiAgICAgICAgICAgICRieXRlT3JkZXIgPSAnVic7IC8vbG93IGVuZGlhbgogICAgICAgIH0gZWxzZWlmICgkbWFnaWMgPT09IChzdGF0aWM6Ok1BR0lDMiAmIDB4RkZGRkZGRkYpKSB7CiAgICAgICAgICAgICRieXRlT3JkZXIgPSAnTic7IC8vYmlnIGVuZGlhbgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ05vdCBNTyBmaWxlJyk7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWM6OnJlYWRJbnQoJHN0cmVhbSwgJGJ5dGVPcmRlcik7CgogICAgICAgICR0b3RhbCA9IHN0YXRpYzo6cmVhZEludCgkc3RyZWFtLCAkYnl0ZU9yZGVyKTsgLy90b3RhbCBzdHJpbmcgY291bnQKICAgICAgICAkb3JpZ2luYWxzID0gc3RhdGljOjpyZWFkSW50KCRzdHJlYW0sICRieXRlT3JkZXIpOyAvL29mZnNldCBvZiBvcmlnaW5hbCB0YWJsZQogICAgICAgICR0cmFuID0gc3RhdGljOjpyZWFkSW50KCRzdHJlYW0sICRieXRlT3JkZXIpOyAvL29mZnNldCBvZiB0cmFuc2xhdGlvbiB0YWJsZQoKICAgICAgICAkc3RyZWFtLT5zZWVrdG8oJG9yaWdpbmFscyk7CiAgICAgICAgJHRhYmxlX29yaWdpbmFscyA9IHN0YXRpYzo6cmVhZEludEFycmF5KCRzdHJlYW0sICRieXRlT3JkZXIsICR0b3RhbCAqIDIpOwoKICAgICAgICAkc3RyZWFtLT5zZWVrdG8oJHRyYW4pOwogICAgICAgICR0YWJsZV90cmFuc2xhdGlvbnMgPSBzdGF0aWM6OnJlYWRJbnRBcnJheSgkc3RyZWFtLCAkYnl0ZU9yZGVyLCAkdG90YWwgKiAyKTsKCiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJHRvdGFsOyArKyRpKSB7CiAgICAgICAgICAgICRuZXh0ID0gJGkgKiAyOwoKICAgICAgICAgICAgJHN0cmVhbS0+c2Vla3RvKCR0YWJsZV9vcmlnaW5hbHNbJG5leHQgKyAyXSk7CiAgICAgICAgICAgICRvcmlnaW5hbCA9ICRzdHJlYW0tPnJlYWQoJHRhYmxlX29yaWdpbmFsc1skbmV4dCArIDFdKTsKCiAgICAgICAgICAgICRzdHJlYW0tPnNlZWt0bygkdGFibGVfdHJhbnNsYXRpb25zWyRuZXh0ICsgMl0pOwogICAgICAgICAgICAkdHJhbnNsYXRlZCA9ICRzdHJlYW0tPnJlYWQoJHRhYmxlX3RyYW5zbGF0aW9uc1skbmV4dCArIDFdKTsKCiAgICAgICAgICAgIGlmICgkb3JpZ2luYWwgPT09ICcnKSB7CiAgICAgICAgICAgICAgICAvLyBIZWFkZXJzCiAgICAgICAgICAgICAgICBmb3JlYWNoIChleHBsb2RlKCJcbiIsICR0cmFuc2xhdGVkKSBhcyAkaGVhZGVyTGluZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkaGVhZGVyTGluZSA9PT0gJycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkaGVhZGVyQ2h1bmtzID0gcHJlZ19zcGxpdCgnLzpccyovJywgJGhlYWRlckxpbmUsIDIpOwogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldEhlYWRlcigkaGVhZGVyQ2h1bmtzWzBdLCBpc3NldCgkaGVhZGVyQ2h1bmtzWzFdKSA/ICRoZWFkZXJDaHVua3NbMV0gOiAnJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjaHVua3MgPSBleHBsb2RlKCJceDA0IiwgJG9yaWdpbmFsLCAyKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkY2h1bmtzWzFdKSkgewogICAgICAgICAgICAgICAgJGNvbnRleHQgPSAkY2h1bmtzWzBdOwogICAgICAgICAgICAgICAgJG9yaWdpbmFsID0gJGNodW5rc1sxXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb250ZXh0ID0gJyc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRjaHVua3MgPSBleHBsb2RlKCJceDAwIiwgJG9yaWdpbmFsLCAyKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkY2h1bmtzWzFdKSkgewogICAgICAgICAgICAgICAgJG9yaWdpbmFsID0gJGNodW5rc1swXTsKICAgICAgICAgICAgICAgICRwbHVyYWwgPSAkY2h1bmtzWzFdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHBsdXJhbCA9ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdHJhbnNsYXRpb24gPSAkdHJhbnNsYXRpb25zLT5pbnNlcnQoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCk7CgogICAgICAgICAgICBpZiAoJHRyYW5zbGF0ZWQgPT09ICcnKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRwbHVyYWwgPT09ICcnKSB7CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPnNldFRyYW5zbGF0aW9uKCR0cmFuc2xhdGVkKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdiA9IGV4cGxvZGUoIlx4MDAiLCAkdHJhbnNsYXRlZCk7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0VHJhbnNsYXRpb24oYXJyYXlfc2hpZnQoJHYpKTsKICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHYpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBTdHJpbmdSZWFkZXIgJHN0cmVhbQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkYnl0ZU9yZGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcmVhZEludChTdHJpbmdSZWFkZXIgJHN0cmVhbSwgJGJ5dGVPcmRlcikKICAgIHsKICAgICAgICBpZiAoKCRyZWFkID0gJHN0cmVhbS0+cmVhZCg0KSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRyZWFkID0gdW5wYWNrKCRieXRlT3JkZXIsICRyZWFkKTsKCiAgICAgICAgcmV0dXJuIGFycmF5X3NoaWZ0KCRyZWFkKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBTdHJpbmdSZWFkZXIgJHN0cmVhbQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAkYnl0ZU9yZGVyCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICRjb3VudAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHJlYWRJbnRBcnJheShTdHJpbmdSZWFkZXIgJHN0cmVhbSwgJGJ5dGVPcmRlciwgJGNvdW50KQogICAgewogICAgICAgIHJldHVybiB1bnBhY2soJGJ5dGVPcmRlci4kY291bnQsICRzdHJlYW0tPnJlYWQoNCAqICRjb3VudCkpOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxFeHRyYWN0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xEaWN0aW9uYXJ5VHJhaXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxZYW1sXFlhbWwgYXMgWWFtbFBhcnNlcjsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20geWFtbC4KICovCmNsYXNzIFlhbWxEaWN0aW9uYXJ5IGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkbWVzc2FnZXMgPSBZYW1sUGFyc2VyOjpwYXJzZSgkc3RyaW5nKTsKCiAgICAgICAgaWYgKGlzX2FycmF5KCRtZXNzYWdlcykpIHsKICAgICAgICAgICAgc3RhdGljOjpmcm9tQXJyYXkoJG1lc3NhZ2VzLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgQmFkTWV0aG9kQ2FsbEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gcGhwIGZpbGVzIHJldHVybmluZyBhcnJheXMuCiAqLwpjbGFzcyBQaHBBcnJheSBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUZpbGUoJGZpbGUsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGZvcmVhY2ggKHN0YXRpYzo6Z2V0RmlsZXMoJGZpbGUpIGFzICRmaWxlKSB7CiAgICAgICAgICAgIHN0YXRpYzo6ZnJvbUFycmF5KGluY2x1ZGUoJGZpbGUpLCAkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICB0aHJvdyBuZXcgQmFkTWV0aG9kQ2FsbEV4Y2VwdGlvbignUGhwQXJyYXk6OmZyb21TdHJpbmcoKSBjYW5ub3QgYmUgY2FsbGVkLiBVc2UgUGhwQXJyYXk6OmZyb21GaWxlKCknKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcRGljdGlvbmFyeVRyYWl0OwoKLyoqCiAqIENsYXNzIHRvIGdldCBnZXR0ZXh0IHN0cmluZ3MgZnJvbSBwbGFpbiBqc29uLgogKi8KY2xhc3MgSnNvbkRpY3Rpb25hcnkgZXh0ZW5kcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgdXNlIERpY3Rpb25hcnlUcmFpdDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IGpzb25fZGVjb2RlKCRzdHJpbmcsIHRydWUpOwoKICAgICAgICBpZiAoaXNfYXJyYXkoJG1lc3NhZ2VzKSkgewogICAgICAgICAgICBzdGF0aWM6OmZyb21BcnJheSgkbWVzc2FnZXMsICR0cmFuc2xhdGlvbnMpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBFeGNlcHRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcRnVuY3Rpb25zU2Nhbm5lcjsKCi8qKgogKiBDbGFzcyB0byBnZXQgZ2V0dGV4dCBzdHJpbmdzIGZyb20gamF2YXNjcmlwdCBmaWxlcy4KICovCmNsYXNzIEpzQ29kZSBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZSwgRXh0cmFjdG9yTXVsdGlJbnRlcmZhY2UKewogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnY29uc3RhbnRzJyA9PiBbXSwKCiAgICAgICAgJ2Z1bmN0aW9ucycgPT4gWwogICAgICAgICAgICAnZ2V0dGV4dCcgPT4gJ2dldHRleHQnLAogICAgICAgICAgICAnX18nID0+ICdnZXR0ZXh0JywKICAgICAgICAgICAgJ25nZXR0ZXh0JyA9PiAnbmdldHRleHQnLAogICAgICAgICAgICAnbl9fJyA9PiAnbmdldHRleHQnLAogICAgICAgICAgICAncGdldHRleHQnID0+ICdwZ2V0dGV4dCcsCiAgICAgICAgICAgICdwX18nID0+ICdwZ2V0dGV4dCcsCiAgICAgICAgICAgICdkZ2V0dGV4dCcgPT4gJ2RnZXR0ZXh0JywKICAgICAgICAgICAgJ2RfXycgPT4gJ2RnZXR0ZXh0JywKICAgICAgICAgICAgJ2RuZ2V0dGV4dCcgPT4gJ2RuZ2V0dGV4dCcsCiAgICAgICAgICAgICdkbl9fJyA9PiAnZG5nZXR0ZXh0JywKICAgICAgICAgICAgJ2RwZ2V0dGV4dCcgPT4gJ2RwZ2V0dGV4dCcsCiAgICAgICAgICAgICdkcF9fJyA9PiAnZHBnZXR0ZXh0JywKICAgICAgICAgICAgJ25wZ2V0dGV4dCcgPT4gJ25wZ2V0dGV4dCcsCiAgICAgICAgICAgICducF9fJyA9PiAnbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ2RucGdldHRleHQnID0+ICdkbnBnZXR0ZXh0JywKICAgICAgICAgICAgJ2RucF9fJyA9PiAnZG5wZ2V0dGV4dCcsCiAgICAgICAgICAgICdub29wJyA9PiAnbm9vcCcsCiAgICAgICAgICAgICdub29wX18nID0+ICdub29wJywKICAgICAgICBdLAogICAgXTsKCiAgICBwcm90ZWN0ZWQgc3RhdGljICRmdW5jdGlvbnNTY2FubmVyQ2xhc3MgPSAnR2V0dGV4dFxVdGlsc1xKc0Z1bmN0aW9uc1NjYW5uZXInOwoKICAgIC8qKgogICAgICogQGluaGVyaXRkb2MKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICBzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZSgkc3RyaW5nLCBbJHRyYW5zbGF0aW9uc10sICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmdNdWx0aXBsZSgkc3RyaW5nLCBhcnJheSAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgIC8qKiBAdmFyIEZ1bmN0aW9uc1NjYW5uZXIgJGZ1bmN0aW9ucyAqLwogICAgICAgICRmdW5jdGlvbnMgPSBuZXcgc3RhdGljOjokZnVuY3Rpb25zU2Nhbm5lckNsYXNzKCRzdHJpbmcpOwogICAgICAgICRmdW5jdGlvbnMtPnNhdmVHZXR0ZXh0RnVuY3Rpb25zKCR0cmFuc2xhdGlvbnMsICRvcHRpb25zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBpbmhlcml0RG9jCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21GaWxlTXVsdGlwbGUoJGZpbGUsIGFycmF5ICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjpnZXRGaWxlcygkZmlsZSkgYXMgJGZpbGUpIHsKICAgICAgICAgICAgJG9wdGlvbnNbJ2ZpbGUnXSA9ICRmaWxlOwogICAgICAgICAgICBzdGF0aWM6OmZyb21TdHJpbmdNdWx0aXBsZShzdGF0aWM6OnJlYWRGaWxlKCRmaWxlKSwgJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIGpzb24uCiAqLwpjbGFzcyBKc29uIGV4dGVuZHMgRXh0cmFjdG9yIGltcGxlbWVudHMgRXh0cmFjdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBNdWx0aWRpbWVuc2lvbmFsQXJyYXlUcmFpdDsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tU3RyaW5nKCRzdHJpbmcsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IGpzb25fZGVjb2RlKCRzdHJpbmcsIHRydWUpOwoKICAgICAgICBpZiAoaXNfYXJyYXkoJG1lc3NhZ2VzKSkgewogICAgICAgICAgICBzdGF0aWM6OmZyb21BcnJheSgkbWVzc2FnZXMsICR0cmFuc2xhdGlvbnMpOwogICAgICAgIH0KICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcRXh0cmFjdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCmludGVyZmFjZSBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBFeHRyYWN0IHRoZSB0cmFuc2xhdGlvbnMgZnJvbSBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5fHN0cmluZyAkZmlsZSAgICAgICAgIEEgcGF0aCBvZiBhIGZpbGUgb3IgZmlsZXMKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucyBUaGUgdHJhbnNsYXRpb25zIGluc3RhbmNlIHRvIGFwcGVuZCB0aGUgbmV3IHRyYW5zbGF0aW9ucy4KICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tRmlsZSgkZmlsZSwgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pOwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3RyaW5nIGFuZCBhcHBlbmQgdGhlIHRyYW5zbGF0aW9ucyBmb3VuZCBpbiB0aGUgVHJhbnNsYXRpb25zIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHN0cmluZwogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSk7Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgRXhjZXB0aW9uOwp1c2UgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uOwp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgphYnN0cmFjdCBjbGFzcyBFeHRyYWN0b3IgaW1wbGVtZW50cyBFeHRyYWN0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUZpbGUoJGZpbGUsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgIGZvcmVhY2ggKHN0YXRpYzo6Z2V0RmlsZXMoJGZpbGUpIGFzICRmaWxlKSB7CiAgICAgICAgICAgICRvcHRpb25zWydmaWxlJ10gPSAkZmlsZTsKICAgICAgICAgICAgc3RhdGljOjpmcm9tU3RyaW5nKHN0YXRpYzo6cmVhZEZpbGUoJGZpbGUpLCAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGFuZCByZXR1cm5zIGFsbCBmaWxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRmaWxlIFRoZSBmaWxlL3MKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5IFRoZSBmaWxlIHBhdGhzCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2V0RmlsZXMoJGZpbGUpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRmaWxlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdUaGVyZSBpcyBub3QgYW55IGZpbGUgZGVmaW5lZCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzX3N0cmluZygkZmlsZSkpIHsKICAgICAgICAgICAgaWYgKCFpc19maWxlKCRmaWxlKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbigiJyRmaWxlJyBpcyBub3QgYSB2YWxpZCBmaWxlIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNfcmVhZGFibGUoJGZpbGUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCInJGZpbGUnIGlzIG5vdCBhIHJlYWRhYmxlIGZpbGUiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFskZmlsZV07CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNfYXJyYXkoJGZpbGUpKSB7CiAgICAgICAgICAgICRmaWxlcyA9IFtdOwoKICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGUgYXMgJGYpIHsKICAgICAgICAgICAgICAgICRmaWxlcyA9IGFycmF5X21lcmdlKCRmaWxlcywgc3RhdGljOjpnZXRGaWxlcygkZikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJGZpbGVzOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbignVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgc3RyaW5nIG9yIGFycmF5Jyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkcyBhbmQgcmV0dXJucyB0aGUgY29udGVudCBvZiBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZmlsZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcmVhZEZpbGUoJGZpbGUpCiAgICB7CiAgICAgICAgJGxlbmd0aCA9IGZpbGVzaXplKCRmaWxlKTsKCiAgICAgICAgaWYgKCEoJGZkID0gZm9wZW4oJGZpbGUsICdyYicpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW5ub3QgcmVhZCB0aGUgZmlsZSAnJGZpbGUnLCBwcm9iYWJseSBwZXJtaXNzaW9ucyIpOwogICAgICAgIH0KCiAgICAgICAgJGNvbnRlbnQgPSAkbGVuZ3RoID8gZnJlYWQoJGZkLCAkbGVuZ3RoKSA6ICcnOwogICAgICAgIGZjbG9zZSgkZmQpOwoKICAgICAgICByZXR1cm4gJGNvbnRlbnQ7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEV4dHJhY3RvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKdXNlIEdldHRleHRcVXRpbHNcQ3N2VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZ2V0IGdldHRleHQgc3RyaW5ncyBmcm9tIGNzdi4KICovCmNsYXNzIENzdiBleHRlbmRzIEV4dHJhY3RvciBpbXBsZW1lbnRzIEV4dHJhY3RvckludGVyZmFjZQp7CiAgICB1c2UgSGVhZGVyc0V4dHJhY3RvclRyYWl0OwogICAgdXNlIENzdlRyYWl0OwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2RlbGltaXRlcicgPT4gIiwiLAogICAgICAgICdlbmNsb3N1cmUnID0+ICciJywKICAgICAgICAnZXNjYXBlX2NoYXInID0+ICJcXCIKICAgIF07CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVN0cmluZygkc3RyaW5nLCBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwogICAgICAgICRoYW5kbGUgPSBmb3BlbigncGhwOi8vbWVtb3J5JywgJ3cnKTsKCiAgICAgICAgZnB1dHMoJGhhbmRsZSwgJHN0cmluZyk7CiAgICAgICAgcmV3aW5kKCRoYW5kbGUpOwoKICAgICAgICB3aGlsZSAoJHJvdyA9IHN0YXRpYzo6ZmdldGNzdigkaGFuZGxlLCAkb3B0aW9ucykpIHsKICAgICAgICAgICAgJGNvbnRleHQgPSBhcnJheV9zaGlmdCgkcm93KTsKICAgICAgICAgICAgJG9yaWdpbmFsID0gYXJyYXlfc2hpZnQoJHJvdyk7CgogICAgICAgICAgICBpZiAoJGNvbnRleHQgPT09ICcnICYmICRvcmlnaW5hbCA9PT0gJycpIHsKICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoYXJyYXlfc2hpZnQoJHJvdyksICR0cmFuc2xhdGlvbnMpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICAgICAgICAgIGlmICghZW1wdHkoJHJvdykpIHsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0VHJhbnNsYXRpb24oYXJyYXlfc2hpZnQoJHJvdykpOwogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHJvdyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZjbG9zZSgkaGFuZGxlKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7CgpjbGFzcyBHZXR0ZXh0VHJhbnNsYXRvciBleHRlbmRzIEJhc2VUcmFuc2xhdG9yIGltcGxlbWVudHMgVHJhbnNsYXRvckludGVyZmFjZQp7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLiBEZXRlY3RzIHRoZSBjdXJyZW50IGxhbmd1YWdlIHVzaW5nIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbGFuZ3VhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRsYW5ndWFnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2dldHRleHQnKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFJ1bnRpbWVFeGNlcHRpb24oJ1RoaXMgY2xhc3MgcmVxdWlyZSB0aGUgZ2V0dGV4dCBleHRlbnNpb24gZm9yIFBIUCcpOwogICAgICAgIH0KCiAgICAgICAgLy9kZXRlY3RzIHRoZSBsYW5ndWFnZSBlbnZpcm9ubWVudCByZXNwZWN0aW5nIHRoZSBwcmlvcml0eSBvcmRlcgogICAgICAgIC8vaHR0cDovL3BocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmdldHRleHQucGhwIzExNDA2MgogICAgICAgIGlmIChlbXB0eSgkbGFuZ3VhZ2UpKSB7CiAgICAgICAgICAgICRsYW5ndWFnZSA9IGdldGVudignTEFOR1VBR0UnKSA/OiBnZXRlbnYoJ0xDX0FMTCcpID86IGdldGVudignTENfTUVTU0FHRVMnKSA/OiBnZXRlbnYoJ0xBTkcnKTsKICAgICAgICB9CgogICAgICAgIGlmICghZW1wdHkoJGxhbmd1YWdlKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0TGFuZ3VhZ2UoJGxhbmd1YWdlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWZpbmUgdGhlIGN1cnJlbnQgbG9jYWxlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkbGFuZ3VhZ2UKICAgICAqIEBwYXJhbSBpbnR8bnVsbCAkY2F0ZWdvcnkKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExhbmd1YWdlKCRsYW5ndWFnZSwgJGNhdGVnb3J5ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGNhdGVnb3J5ID09PSBudWxsKSB7CiAgICAgICAgICAgICRjYXRlZ29yeSA9IGRlZmluZWQoJ0xDX01FU1NBR0VTJykgPyBMQ19NRVNTQUdFUyA6IExDX0FMTDsKICAgICAgICB9CgogICAgICAgIHNldGxvY2FsZSgkY2F0ZWdvcnksICRsYW5ndWFnZSk7CiAgICAgICAgcHV0ZW52KCdMQU5HVUFHRT0nLiRsYW5ndWFnZSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWRzIGEgZ2V0dGV4dCBkb21haW4uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoCiAgICAgKiBAcGFyYW0gYm9vbCAgICRkZWZhdWx0CiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkRG9tYWluKCRkb21haW4sICRwYXRoID0gbnVsbCwgJGRlZmF1bHQgPSB0cnVlKQogICAgewogICAgICAgIGJpbmR0ZXh0ZG9tYWluKCRkb21haW4sICRwYXRoKTsKICAgICAgICBiaW5kX3RleHRkb21haW5fY29kZXNldCgkZG9tYWluLCAnVVRGLTgnKTsKCiAgICAgICAgaWYgKCRkZWZhdWx0KSB7CiAgICAgICAgICAgIHRleHRkb21haW4oJGRvbWFpbik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXR0ZXh0KCRvcmlnaW5hbCkKICAgIHsKICAgICAgICByZXR1cm4gZ2V0dGV4dCgkb3JpZ2luYWwpOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmdldHRleHQoJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuIG5nZXR0ZXh0KCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRuZ2V0dGV4dCgkZG9tYWluLCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gZG5nZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJG1lc3NhZ2UgPSAkY29udGV4dC4iXHgwNCIuJG9yaWdpbmFsOwogICAgICAgICR0cmFuc2xhdGlvbiA9IG5nZXR0ZXh0KCRtZXNzYWdlLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgICAgICByZXR1cm4gKCR0cmFuc2xhdGlvbiA9PT0gJG1lc3NhZ2UpID8gJG9yaWdpbmFsIDogJHRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGdldHRleHQoJGNvbnRleHQsICRvcmlnaW5hbCkKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICRjb250ZXh0LiJceDA0Ii4kb3JpZ2luYWw7CiAgICAgICAgJHRyYW5zbGF0aW9uID0gZ2V0dGV4dCgkbWVzc2FnZSk7CgogICAgICAgIHJldHVybiAoJHRyYW5zbGF0aW9uID09PSAkbWVzc2FnZSkgPyAkb3JpZ2luYWwgOiAkdHJhbnNsYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZ2V0dGV4dCgkZG9tYWluLCAkb3JpZ2luYWwpCiAgICB7CiAgICAgICAgcmV0dXJuIGRnZXR0ZXh0KCRkb21haW4sICRvcmlnaW5hbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkcGdldHRleHQoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkKICAgIHsKICAgICAgICAkbWVzc2FnZSA9ICRjb250ZXh0LiJceDA0Ii4kb3JpZ2luYWw7CiAgICAgICAgJHRyYW5zbGF0aW9uID0gZGdldHRleHQoJGRvbWFpbiwgJG1lc3NhZ2UpOwoKICAgICAgICByZXR1cm4gKCR0cmFuc2xhdGlvbiA9PT0gJG1lc3NhZ2UpID8gJG9yaWdpbmFsIDogJHRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZG5wZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgJG1lc3NhZ2UgPSAkY29udGV4dC4iXHgwNCIuJG9yaWdpbmFsOwogICAgICAgICR0cmFuc2xhdGlvbiA9IGRuZ2V0dGV4dCgkZG9tYWluLCAkbWVzc2FnZSwgJHBsdXJhbCwgJHZhbHVlKTsKCiAgICAgICAgcmV0dXJuICgkdHJhbnNsYXRpb24gPT09ICRtZXNzYWdlKSA/ICRvcmlnaW5hbCA6ICR0cmFuc2xhdGlvbjsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7Cgp1c2UgR2V0dGV4dFxHZW5lcmF0b3JzXFBocEFycmF5OwoKY2xhc3MgVHJhbnNsYXRvciBleHRlbmRzIEJhc2VUcmFuc2xhdG9yIGltcGxlbWVudHMgVHJhbnNsYXRvckludGVyZmFjZQp7CiAgICBwcm90ZWN0ZWQgJGRvbWFpbjsKICAgIHByb3RlY3RlZCAkZGljdGlvbmFyeSA9IFtdOwogICAgcHJvdGVjdGVkICRwbHVyYWxzID0gW107CgogICAgLyoqCiAgICAgKiBMb2FkcyB0cmFuc2xhdGlvbiBmcm9tIGEgVHJhbnNsYXRpb25zIGluc3RhbmNlLCBhIGZpbGUgb24gYW4gYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uc3xzdHJpbmd8YXJyYXkgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBsb2FkVHJhbnNsYXRpb25zKCR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKGlzX29iamVjdCgkdHJhbnNsYXRpb25zKSAmJiAkdHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMgPSBQaHBBcnJheTo6Z2VuZXJhdGUoJHRyYW5zbGF0aW9ucywgWydpbmNsdWRlSGVhZGVycycgPT4gZmFsc2VdKTsKICAgICAgICB9IGVsc2VpZiAoaXNfc3RyaW5nKCR0cmFuc2xhdGlvbnMpICYmIGlzX2ZpbGUoJHRyYW5zbGF0aW9ucykpIHsKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucyA9IGluY2x1ZGUgJHRyYW5zbGF0aW9uczsKICAgICAgICB9IGVsc2VpZiAoIWlzX2FycmF5KCR0cmFuc2xhdGlvbnMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgJ0ludmFsaWQgVHJhbnNsYXRvcjogb25seSBhcnJheXMsIGZpbGVzIG9yIGluc3RhbmNlIG9mIFRyYW5zbGF0aW9ucyBhcmUgYWxsb3dlZCcKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5hZGRUcmFuc2xhdGlvbnMoJHRyYW5zbGF0aW9ucyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgZGVmYXVsdCBkb21haW4uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKgogICAgICogQHJldHVybiBzdGF0aWMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlZmF1bHREb21haW4oJGRvbWFpbikKICAgIHsKICAgICAgICAkdGhpcy0+ZG9tYWluID0gJGRvbWFpbjsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0dGV4dCgkb3JpZ2luYWwpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kcGdldHRleHQoJHRoaXMtPmRvbWFpbiwgbnVsbCwgJG9yaWdpbmFsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5nZXR0ZXh0KCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZG5wZ2V0dGV4dCgkdGhpcy0+ZG9tYWluLCBudWxsLCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kbnBnZXR0ZXh0KCRkb21haW4sIG51bGwsICRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgVHJhbnNsYXRvckludGVyZmFjZQogICAgICoKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kbnBnZXR0ZXh0KCR0aGlzLT5kb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZHBnZXR0ZXh0KCR0aGlzLT5kb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwpOwogICAgfQoKICAgIC8qKgogICAgICogQHNlZSBUcmFuc2xhdG9ySW50ZXJmYWNlCiAgICAgKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZHBnZXR0ZXh0KCRkb21haW4sIG51bGwsICRvcmlnaW5hbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkcGdldHRleHQoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkKICAgIHsKICAgICAgICAkdHJhbnNsYXRpb24gPSAkdGhpcy0+Z2V0VHJhbnNsYXRpb24oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCk7CgogICAgICAgIGlmIChpc3NldCgkdHJhbnNsYXRpb25bMF0pICYmICR0cmFuc2xhdGlvblswXSAhPT0gJycpIHsKICAgICAgICAgICAgcmV0dXJuICR0cmFuc2xhdGlvblswXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkb3JpZ2luYWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkbnBnZXR0ZXh0KCRkb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdHJhbnNsYXRpb24gPSAkdGhpcy0+Z2V0VHJhbnNsYXRpb24oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCk7CiAgICAgICAgJGtleSA9ICR0aGlzLT5nZXRQbHVyYWxJbmRleCgkZG9tYWluLCAkdmFsdWUsICR0cmFuc2xhdGlvbiA9PT0gZmFsc2UpOwoKICAgICAgICBpZiAoaXNzZXQoJHRyYW5zbGF0aW9uWyRrZXldKSAmJiAkdHJhbnNsYXRpb25bJGtleV0gIT09ICcnKSB7CiAgICAgICAgICAgIHJldHVybiAkdHJhbnNsYXRpb25bJGtleV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKCRrZXkgPT09IDApID8gJG9yaWdpbmFsIDogJHBsdXJhbDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBuZXcgdHJhbnNsYXRpb25zIHRvIHRoZSBkaWN0aW9uYXJ5LgogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGRUcmFuc2xhdGlvbnMoYXJyYXkgJHRyYW5zbGF0aW9ucykKICAgIHsKICAgICAgICAkZG9tYWluID0gaXNzZXQoJHRyYW5zbGF0aW9uc1snZG9tYWluJ10pID8gJHRyYW5zbGF0aW9uc1snZG9tYWluJ10gOiAnJzsKCiAgICAgICAgLy9TZXQgdGhlIGZpcnN0IGRvbWFpbiBsb2FkZWQgYXMgZGVmYXVsdCBkb21haW4KICAgICAgICBpZiAoJHRoaXMtPmRvbWFpbiA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+ZG9tYWluID0gJGRvbWFpbjsKICAgICAgICB9CgogICAgICAgIGlmIChpc3NldCgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXSkpIHsKICAgICAgICAgICAgJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl0gPSBhcnJheV9yZXBsYWNlX3JlY3Vyc2l2ZSgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXSwgJHRyYW5zbGF0aW9uc1snbWVzc2FnZXMnXSk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCR0cmFuc2xhdGlvbnNbJ3BsdXJhbC1mb3JtcyddKSkgewogICAgICAgICAgICBsaXN0KCRjb3VudCwgJGNvZGUpID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnOycsICR0cmFuc2xhdGlvbnNbJ3BsdXJhbC1mb3JtcyddLCAyKSk7CgogICAgICAgICAgICAvLyBleHRyYWN0IGp1c3QgdGhlIGV4cHJlc3Npb24gdHVybiAnbicgaW50byBhIHBocCB2YXJpYWJsZSAnJG4nLgogICAgICAgICAgICAvLyBTbGFwIG9uIGEgcmV0dXJuIGtleXdvcmQgYW5kIHNlbWljb2xvbiBhdCB0aGUgZW5kLgogICAgICAgICAgICAkdGhpcy0+cGx1cmFsc1skZG9tYWluXSA9IFsKICAgICAgICAgICAgICAgICdjb3VudCcgPT4gKGludCkgc3RyX3JlcGxhY2UoJ25wbHVyYWxzPScsICcnLCAkY291bnQpLAogICAgICAgICAgICAgICAgJ2NvZGUnID0+IHN0cl9yZXBsYWNlKCdwbHVyYWw9JywgJ3JldHVybiAnLCBzdHJfcmVwbGFjZSgnbicsICckbicsICRjb2RlKSkuJzsnLAogICAgICAgICAgICBdOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl0gPSAkdHJhbnNsYXRpb25zWydtZXNzYWdlcyddOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoIGFuZCByZXR1cm5zIGEgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGZhbHNlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbigkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZGljdGlvbmFyeVskZG9tYWluXVskY29udGV4dF1bJG9yaWdpbmFsXSkKICAgICAgICAgICAgID8gJHRoaXMtPmRpY3Rpb25hcnlbJGRvbWFpbl1bJGNvbnRleHRdWyRvcmlnaW5hbF0KICAgICAgICAgICAgIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgcGx1cmFsIGRlY2lzaW9uIGNvZGUgZ2l2ZW4gdGhlIG51bWJlciB0byBkZWNpZGUgd2hpY2gKICAgICAqIHBsdXJhbCB2ZXJzaW9uIHRvIHRha2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuCiAgICAgKiBAcGFyYW0gYm9vbCAgICRmYWxsYmFjayBzZXQgdG8gdHJ1ZSB0byBnZXQgZmFsbGJhY2sgcGx1cmFsIGluZGV4CiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldFBsdXJhbEluZGV4KCRkb21haW4sICRuLCAkZmFsbGJhY2spCiAgICB7CiAgICAgICAgLy9Ob3QgbG9hZGVkIGRvbWFpbiBvciB0cmFuc2xhdGlvbiwgdXNlIGEgZmFsbGJhY2sKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5wbHVyYWxzWyRkb21haW5dKSB8fCAkZmFsbGJhY2sgPT09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuICRuID09IDEgPyAwIDogMTsKICAgICAgICB9CgogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPnBsdXJhbHNbJGRvbWFpbl1bJ2Z1bmN0aW9uJ10pKSB7CiAgICAgICAgICAgICRjb2RlID0gc3RhdGljOjpmaXhUZXJzZUlmcygkdGhpcy0+cGx1cmFsc1skZG9tYWluXVsnY29kZSddKTsKICAgICAgICAgICAgJHRoaXMtPnBsdXJhbHNbJGRvbWFpbl1bJ2Z1bmN0aW9uJ10gPSBldmFsKCJyZXR1cm4gZnVuY3Rpb24gKFwkbikgeyAkY29kZSB9OyIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5wbHVyYWxzWyRkb21haW5dWydjb3VudCddIDw9IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGNhbGxfdXNlcl9mdW5jKCR0aGlzLT5wbHVyYWxzWyRkb21haW5dWydmdW5jdGlvbiddLCAkbikgPyAxIDogMDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuYygkdGhpcy0+cGx1cmFsc1skZG9tYWluXVsnZnVuY3Rpb24nXSwgJG4pOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiB3aWxsIHJlY3Vyc2l2ZWx5IHdyYXAgZmFpbHVyZSBzdGF0ZXMgaW4gYnJhY2tldHMgaWYgdGhleSBjb250YWluIGEgbmVzdGVkIHRlcnNlIGlmLgogICAgICoKICAgICAqIFRoaXMgYmVjYXVzZSBQSFAgY2FuIG5vdCBoYW5kbGUgbmVzdGVkIHRlcnNlIGlmJ3MgdW5sZXNzIHRoZXkgYXJlIHdyYXBwZWQgaW4gYnJhY2tldHMuCiAgICAgKgogICAgICogVGhpcyBjb2RlIHByb2JhYmx5IG9ubHkgd29ya3MgZm9yIHRoZSBnZXR0ZXh0IHBsdXJhbCBkZWNpc2lvbiBjb2Rlcy4KICAgICAqCiAgICAgKiByZXR1cm4gKCRuPT0xID8gMCA6ICRuJTEwPj0yICYmICRuJTEwPD00ICYmICgkbiUxMDA8MTAgfHwgJG4lMTAwPj0yMCkgPyAxIDogMik7CiAgICAgKiBiZWNvbWVzCiAgICAgKiByZXR1cm4gKCRuPT0xID8gMCA6ICgkbiUxMD49MiAmJiAkbiUxMDw9NCAmJiAoJG4lMTAwPDEwIHx8ICRuJTEwMD49MjApID8gMSA6IDIpKTsKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb2RlICB0aGUgdGVyc2UgaWYgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAgICRpbm5lciBJZiBpbm5lciBpcyB0cnVlIHdlIHdyYXAgaXQgaW4gYnJhY2tldHMKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBBIGZvcm1hdHRlZCB0ZXJzZSBJZiB0aGF0IFBIUCBjYW4gd29yayB3aXRoLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBmaXhUZXJzZUlmcygkY29kZSwgJGlubmVyID0gZmFsc2UpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiAoP1A8ZXhwcmVzc2lvbj5bXj9dKykgICBDYXB0dXJlIGV2ZXJ5dGhpbmcgdXAgdG8gPyBhcyAnZXhwcmVzc2lvbicKICAgICAgICAgKiBcPyAgICAgICAgICAgICAgICAgICAgICA/CiAgICAgICAgICogKD9QPHN1Y2Nlc3M+W146XSspICAgICAgQ2FwdHVyZSBldmVyeXRoaW5nIHVwIHRvIDogYXMgJ3N1Y2Nlc3MnCiAgICAgICAgICogOiAgICAgICAgICAgICAgICAgICAgICAgOgogICAgICAgICAqICg/UDxmYWlsdXJlPlteO10rKSAgICAgIENhcHR1cmUgZXZlcnl0aGluZyB1cCB0byA7IGFzICdmYWlsdXJlJwogICAgICAgICAqLwogICAgICAgIHByZWdfbWF0Y2goJy8oP1A8ZXhwcmVzc2lvbj5bXj9dKylcPyg/UDxzdWNjZXNzPlteOl0rKTooP1A8ZmFpbHVyZT5bXjtdKykvJywgJGNvZGUsICRtYXRjaGVzKTsKCiAgICAgICAgLy8gSWYgbm8gbWF0Y2ggd2FzIGZvdW5kIHRoZW4gbm8gdGVyc2UgaWYgd2FzIHByZXNlbnQKICAgICAgICBpZiAoIWlzc2V0KCRtYXRjaGVzWzBdKSkgewogICAgICAgICAgICByZXR1cm4gJGNvZGU7CiAgICAgICAgfQoKICAgICAgICAkZXhwcmVzc2lvbiA9ICRtYXRjaGVzWydleHByZXNzaW9uJ107CiAgICAgICAgJHN1Y2Nlc3MgPSAkbWF0Y2hlc1snc3VjY2VzcyddOwogICAgICAgICRmYWlsdXJlID0gJG1hdGNoZXNbJ2ZhaWx1cmUnXTsKCiAgICAgICAgLy8gR28gbG9vayBmb3IgYW5vdGhlciB0ZXJzZSBpZiBpbiB0aGUgZmFpbHVyZSBzdGF0ZS4KICAgICAgICAkZmFpbHVyZSA9IHN0YXRpYzo6Zml4VGVyc2VJZnMoJGZhaWx1cmUsIHRydWUpOwogICAgICAgICRjb2RlID0gJGV4cHJlc3Npb24uJyA/ICcuJHN1Y2Nlc3MuJyA6ICcuJGZhaWx1cmU7CgogICAgICAgIGlmICgkaW5uZXIpIHsKICAgICAgICAgICAgcmV0dXJuICIoJGNvZGUpIjsKICAgICAgICB9CgogICAgICAgIC8vIG5vdGUgdGhlIHNlbWljb2xvbi4gV2UgbmVlZCB0aGF0IGZvciBleGVjdXRpbmcgdGhlIGNvZGUuCiAgICAgICAgcmV0dXJuICIkY29kZTsiOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dDsKCi8qKgogKiBTdGF0aWMgY2xhc3Mgd2l0aCBtZXJnZSBjb250YW50cy4KICovCmZpbmFsIGNsYXNzIE1lcmdlCnsKICAgIGNvbnN0IEFERCA9IDE7CiAgICBjb25zdCBSRU1PVkUgPSAyOwoKICAgIGNvbnN0IEhFQURFUlNfQUREID0gNDsKICAgIGNvbnN0IEhFQURFUlNfUkVNT1ZFID0gODsKICAgIGNvbnN0IEhFQURFUlNfT1ZFUlJJREUgPSAxNjsKCiAgICBjb25zdCBMQU5HVUFHRV9PVkVSUklERSA9IDMyOwogICAgY29uc3QgRE9NQUlOX09WRVJSSURFID0gNjQ7CiAgICBjb25zdCBUUkFOU0xBVElPTl9PVkVSUklERSA9IDEyODsKCiAgICBjb25zdCBDT01NRU5UU19PVVJTID0gMjU2OwogICAgY29uc3QgQ09NTUVOVFNfVEhFSVJTID0gNTEyOwoKICAgIGNvbnN0IEVYVFJBQ1RFRF9DT01NRU5UU19PVVJTID0gMTAyNDsKICAgIGNvbnN0IEVYVFJBQ1RFRF9DT01NRU5UU19USEVJUlMgPSAyMDQ4OwoKICAgIGNvbnN0IEZMQUdTX09VUlMgPSA0MDk2OwogICAgY29uc3QgRkxBR1NfVEhFSVJTID0gODE5MjsKCiAgICBjb25zdCBSRUZFUkVOQ0VTX09VUlMgPSAxNjM4NDsKICAgIGNvbnN0IFJFRkVSRU5DRVNfVEhFSVJTID0gMzI3Njg7CgogICAgY29uc3QgREVGQVVMVFMgPSA1OyAvLzEgKyA0CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgZmxhZ3Mgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlRmxhZ3MoVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpGTEFHU19USEVJUlMpIHsKICAgICAgICAgICAgJHRvLT5kZWxldGVGbGFncygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEoJG9wdGlvbnMgJiBzZWxmOjpGTEFHU19PVVJTKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZnJvbS0+Z2V0RmxhZ3MoKSBhcyAkZmxhZykgewogICAgICAgICAgICAgICAgJHRvLT5hZGRGbGFnKCRmbGFnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlIHRoZSBleHRyYWN0ZWQgY29tbWVudHMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlRXh0cmFjdGVkQ29tbWVudHMoVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpFWFRSQUNURURfQ09NTUVOVFNfVEhFSVJTKSB7CiAgICAgICAgICAgICR0by0+ZGVsZXRlRXh0cmFjdGVkQ29tbWVudHMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghKCRvcHRpb25zICYgc2VsZjo6RVhUUkFDVEVEX0NPTU1FTlRTX09VUlMpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRmcm9tLT5nZXRFeHRyYWN0ZWRDb21tZW50cygpIGFzICRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAkdG8tPmFkZEV4dHJhY3RlZENvbW1lbnQoJGNvbW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2UgdGhlIGNvbW1lbnRzIG9mIHR3byB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uICRmcm9tCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJHRvCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZUNvbW1lbnRzKFRyYW5zbGF0aW9uICRmcm9tLCBUcmFuc2xhdGlvbiAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6Q09NTUVOVFNfVEhFSVJTKSB7CiAgICAgICAgICAgICR0by0+ZGVsZXRlQ29tbWVudHMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghKCRvcHRpb25zICYgc2VsZjo6Q09NTUVOVFNfT1VSUykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICR0by0+YWRkQ29tbWVudCgkY29tbWVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgcmVmZXJlbmNlcyBvZiB0d28gdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkZnJvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uICR0bwogICAgICogQHBhcmFtIGludCAgICAgICAgICRvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWVyZ2VSZWZlcmVuY2VzKFRyYW5zbGF0aW9uICRmcm9tLCBUcmFuc2xhdGlvbiAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6UkVGRVJFTkNFU19USEVJUlMpIHsKICAgICAgICAgICAgJHRvLT5kZWxldGVSZWZlcmVuY2VzKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoISgkb3B0aW9ucyAmIHNlbGY6OlJFRkVSRU5DRVNfT1VSUykpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldFJlZmVyZW5jZXMoKSBhcyAkcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICAgICAkdG8tPmFkZFJlZmVyZW5jZSgkcmVmZXJlbmNlWzBdLCAkcmVmZXJlbmNlWzFdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1lcmdlIHRoZSB0cmFuc2xhdGlvbnMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJGZyb20KICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlVHJhbnNsYXRpb24oVHJhbnNsYXRpb24gJGZyb20sIFRyYW5zbGF0aW9uICR0bywgJG9wdGlvbnMgPSBzZWxmOjpERUZBVUxUUykKICAgIHsKICAgICAgICAkb3ZlcnJpZGUgPSAoYm9vbGVhbikgKCRvcHRpb25zICYgc2VsZjo6VFJBTlNMQVRJT05fT1ZFUlJJREUpOwoKICAgICAgICBpZiAoISR0by0+aGFzVHJhbnNsYXRpb24oKSB8fCAoJGZyb20tPmhhc1RyYW5zbGF0aW9uKCkgJiYgJG92ZXJyaWRlKSkgewogICAgICAgICAgICAkdG8tPnNldFRyYW5zbGF0aW9uKCRmcm9tLT5nZXRUcmFuc2xhdGlvbigpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRvLT5oYXNQbHVyYWwoKSB8fCAoJGZyb20tPmhhc1BsdXJhbCgpICYmICRvdmVycmlkZSkpIHsKICAgICAgICAgICAgJHRvLT5zZXRQbHVyYWwoJGZyb20tPmdldFBsdXJhbCgpKTsKICAgICAgICB9CgogICAgICAgIGlmICghJHRvLT5oYXNQbHVyYWxUcmFuc2xhdGlvbnMoKSB8fCAoJGZyb20tPmhhc1BsdXJhbFRyYW5zbGF0aW9ucygpICYmICRvdmVycmlkZSkpIHsKICAgICAgICAgICAgJHRvLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJGZyb20tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgdHJhbnNsYXRpb25zIG9mIHR3byB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkZnJvbQogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdG8KICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgJG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZVRyYW5zbGF0aW9ucyhUcmFuc2xhdGlvbnMgJGZyb20sIFRyYW5zbGF0aW9ucyAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6UkVNT1ZFKSB7CiAgICAgICAgICAgICRmaWx0ZXJlZCA9IFtdOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHRvIGFzICRlbnRyeSkgewogICAgICAgICAgICAgICAgaWYgKCRmcm9tLT5maW5kKCRlbnRyeSkpIHsKICAgICAgICAgICAgICAgICAgICAkZmlsdGVyZWRbJGVudHJ5LT5nZXRJZCgpXSA9ICRlbnRyeTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRvLT5leGNoYW5nZUFycmF5KCRmaWx0ZXJlZCk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkZnJvbSBhcyAkZW50cnkpIHsKICAgICAgICAgICAgaWYgKCgkZXhpc3RpbmcgPSAkdG8tPmZpbmQoJGVudHJ5KSkpIHsKICAgICAgICAgICAgICAgICRleGlzdGluZy0+bWVyZ2VXaXRoKCRlbnRyeSwgJG9wdGlvbnMpOwogICAgICAgICAgICB9IGVsc2VpZiAoJG9wdGlvbnMgJiBzZWxmOjpBREQpIHsKICAgICAgICAgICAgICAgICR0b1tdID0gJGVudHJ5LT5nZXRDbG9uZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2UgdGhlIGhlYWRlcnMgb2YgdHdvIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICRmcm9tCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0bwogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlSGVhZGVycyhUcmFuc2xhdGlvbnMgJGZyb20sIFRyYW5zbGF0aW9ucyAkdG8sICRvcHRpb25zID0gc2VsZjo6REVGQVVMVFMpCiAgICB7CiAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6SEVBREVSU19SRU1PVkUpIHsKICAgICAgICAgICAgZm9yZWFjaCAoYXJyYXlfa2V5cygkdG8tPmdldEhlYWRlcnMoKSkgYXMgJG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmICgkZnJvbS0+Z2V0SGVhZGVyKCRuYW1lKSA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR0by0+ZGVsZXRlSGVhZGVyKCRuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJGZyb20tPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGN1cnJlbnQgPSAkdG8tPmdldEhlYWRlcigkbmFtZSk7CgogICAgICAgICAgICBpZiAoZW1wdHkoJGN1cnJlbnQpKSB7CiAgICAgICAgICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpIRUFERVJTX0FERCkgewogICAgICAgICAgICAgICAgICAgICR0by0+c2V0SGVhZGVyKCRuYW1lLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbXB0eSgkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICgkbmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSBUcmFuc2xhdGlvbnM6OkhFQURFUl9MQU5HVUFHRToKICAgICAgICAgICAgICAgIGNhc2UgVHJhbnNsYXRpb25zOjpIRUFERVJfUExVUkFMOgogICAgICAgICAgICAgICAgICAgIGlmICgkb3B0aW9ucyAmIHNlbGY6OkxBTkdVQUdFX09WRVJSSURFKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0by0+c2V0SGVhZGVyKCRuYW1lLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zbGF0aW9uczo6SEVBREVSX0RPTUFJTjoKICAgICAgICAgICAgICAgICAgICBpZiAoJG9wdGlvbnMgJiBzZWxmOjpET01BSU5fT1ZFUlJJREUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRvLT5zZXRIZWFkZXIoJG5hbWUsICR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCRvcHRpb25zICYgc2VsZjo6SEVBREVSU19PVkVSUklERSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdG8tPnNldEhlYWRlcigkbmFtZSwgJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0OwoKYWJzdHJhY3QgY2xhc3MgQmFzZVRyYW5zbGF0b3IgaW1wbGVtZW50cyBUcmFuc2xhdG9ySW50ZXJmYWNlCnsKICAgIC8qKiBAdmFyIFRyYW5zbGF0b3JJbnRlcmZhY2UgKi8KICAgIHB1YmxpYyBzdGF0aWMgJGN1cnJlbnQ7CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG5vb3AoJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAkb3JpZ2luYWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIFRyYW5zbGF0b3JJbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlZ2lzdGVyKCkKICAgIHsKICAgICAgICAkcHJldmlvdXMgPSBzdGF0aWM6OiRjdXJyZW50OwoKICAgICAgICBzdGF0aWM6OiRjdXJyZW50ID0gJHRoaXM7CgogICAgICAgIHN0YXRpYzo6aW5jbHVkZUZ1bmN0aW9ucygpOwoKICAgICAgICByZXR1cm4gJHByZXZpb3VzOwogICAgfQoKICAgIC8qKgogICAgICogSW5jbHVkZSB0aGUgZ2V0dGV4dCBmdW5jdGlvbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpbmNsdWRlRnVuY3Rpb25zKCkKICAgIHsKICAgICAgICBpbmNsdWRlX29uY2UgX19ESVJfXy4nL3RyYW5zbGF0b3JfZnVuY3Rpb25zLnBocCc7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0OwoKdXNlIEdldHRleHRcTGFuZ3VhZ2VzXExhbmd1YWdlOwp1c2UgQmFkTWV0aG9kQ2FsbEV4Y2VwdGlvbjsKdXNlIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbjsKdXNlIEFycmF5T2JqZWN0OwoKLyoqCiAqIENsYXNzIHRvIG1hbmFnZSBhIGNvbGxlY3Rpb24gb2YgdHJhbnNsYXRpb25zLgogKgogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQmxhZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21CbGFkZVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tQmxhZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUJsYWRlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2U3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Dc3ZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdlN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvQ3N2RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0NzdlN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tQ3N2RGljdGlvbmFyeUZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUNzdkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUNzdkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgYm9vbCB0b0NzdkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvQ3N2RGljdGlvbmFyeVN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSmVkRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSmVkU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21KZWRGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUplZFN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvSmVkRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0plZFN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNDb2RlRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc0NvZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUpzQ29kZVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUpzb25GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21Kc29uU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9Kc29uRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0cmluZyB0b0pzb25TdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbUpzb25EaWN0aW9uYXJ5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tSnNvbkRpY3Rpb25hcnlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbUpzb25EaWN0aW9uYXJ5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Kc29uRGljdGlvbmFyeVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvSnNvbkRpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvSnNvbkRpY3Rpb25hcnlTdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbU1vRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tTW9TdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbU1vRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21Nb1N0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvTW9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvTW9TdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVBocEFycmF5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tUGhwQXJyYXlTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVBocEFycmF5RmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBBcnJheVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBib29sIHRvUGhwQXJyYXlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvUGhwQXJyYXlTdHJpbmcoYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVBocENvZGVGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21QaHBDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBDb2RlRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21QaHBDb2RlU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tUG9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21Qb1N0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tUG9GaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVBvU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9Qb0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9Qb1N0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tVHdpZ0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVR3aWdTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVR3aWdGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVR3aWdTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21WdWVKc0ZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVZ1ZUpzU3RyaW5nKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVZ1ZUpzRmlsZShzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kICR0aGlzIGFkZEZyb21WdWVKc1N0cmluZyhzdHJpbmcgJGZpbGVuYW1lLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWGxpZmZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21YbGlmZlN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tWGxpZmZGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVhsaWZmU3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9YbGlmZkZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9YbGlmZlN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWWFtbEZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdGF0aWMgJHRoaXMgZnJvbVlhbWxTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxTdHJpbmcoc3RyaW5nICRzdHJpbmcsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgYm9vbCB0b1lhbWxGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RyaW5nIHRvWWFtbFN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIHN0YXRpYyAkdGhpcyBmcm9tWWFtbERpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2Qgc3RhdGljICR0aGlzIGZyb21ZYW1sRGljdGlvbmFyeVN0cmluZyhzdHJpbmcgJHN0cmluZywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCAkdGhpcyBhZGRGcm9tWWFtbERpY3Rpb25hcnlGaWxlKHN0cmluZyAkZmlsZW5hbWUsIGFycmF5ICRvcHRpb25zID0gW10pCiAqIEBtZXRob2QgJHRoaXMgYWRkRnJvbVlhbWxEaWN0aW9uYXJ5U3RyaW5nKHN0cmluZyAkc3RyaW5nLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogKiBAbWV0aG9kIGJvb2wgdG9ZYW1sRGljdGlvbmFyeUZpbGUoc3RyaW5nICRmaWxlbmFtZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICogQG1ldGhvZCBzdHJpbmcgdG9ZYW1sRGljdGlvbmFyeVN0cmluZyhhcnJheSAkb3B0aW9ucyA9IFtdKQogKi8KY2xhc3MgVHJhbnNsYXRpb25zIGV4dGVuZHMgQXJyYXlPYmplY3QKewogICAgY29uc3QgSEVBREVSX0xBTkdVQUdFID0gJ0xhbmd1YWdlJzsKICAgIGNvbnN0IEhFQURFUl9QTFVSQUwgPSAnUGx1cmFsLUZvcm1zJzsKICAgIGNvbnN0IEhFQURFUl9ET01BSU4gPSAnWC1Eb21haW4nOwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2RlZmF1bHRIZWFkZXJzJyA9PiBbCiAgICAgICAgICAgICdQcm9qZWN0LUlkLVZlcnNpb24nID0+ICcnLAogICAgICAgICAgICAnUmVwb3J0LU1zZ2lkLUJ1Z3MtVG8nID0+ICcnLAogICAgICAgICAgICAnTGFzdC1UcmFuc2xhdG9yJyA9PiAnJywKICAgICAgICAgICAgJ0xhbmd1YWdlLVRlYW0nID0+ICcnLAogICAgICAgICAgICAnTUlNRS1WZXJzaW9uJyA9PiAnMS4wJywKICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZScgPT4gJ3RleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgnLAogICAgICAgICAgICAnQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZycgPT4gJzhiaXQnLAogICAgICAgIF0sCiAgICAgICAgJ2hlYWRlcnNTb3J0aW5nJyA9PiBmYWxzZSwKICAgICAgICAnZGVmYXVsdERhdGVIZWFkZXJzJyA9PiBbCiAgICAgICAgICAgICdQT1QtQ3JlYXRpb24tRGF0ZScsCiAgICAgICAgICAgICdQTy1SZXZpc2lvbi1EYXRlJywKICAgICAgICBdLAogICAgXTsKCiAgICBwcm90ZWN0ZWQgJGhlYWRlcnM7CgogICAgcHJvdGVjdGVkICR0cmFuc2xhdGlvbkNsYXNzOwoKICAgIC8qKgogICAgICogQHNlZSBBcnJheU9iamVjdDo6X19jb25zdHJ1Y3QoKQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoCiAgICAgICAgJGlucHV0ID0gW10sCiAgICAgICAgJGZsYWdzID0gMCwKICAgICAgICAkaXRlcmF0b3JfY2xhc3MgPSAnQXJyYXlJdGVyYXRvcicsCiAgICAgICAgJHRyYW5zbGF0aW9uQ2xhc3MgPSAnR2V0dGV4dFxUcmFuc2xhdGlvbicKICAgICkgewogICAgICAgICR0aGlzLT5oZWFkZXJzID0gc3RhdGljOjokb3B0aW9uc1snZGVmYXVsdEhlYWRlcnMnXTsKCiAgICAgICAgZm9yZWFjaCAoc3RhdGljOjokb3B0aW9uc1snZGVmYXVsdERhdGVIZWFkZXJzJ10gYXMgJGhlYWRlcikgewogICAgICAgICAgICAkdGhpcy0+aGVhZGVyc1skaGVhZGVyXSA9IGRhdGUoJ2MnKTsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5oZWFkZXJzW3NlbGY6OkhFQURFUl9MQU5HVUFHRV0gPSAnJzsKCiAgICAgICAgJHRoaXMtPnRyYW5zbGF0aW9uQ2xhc3MgPSAkdHJhbnNsYXRpb25DbGFzczsKCiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgkaW5wdXQsICRmbGFncywgJGl0ZXJhdG9yX2NsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBjcmVhdGUgbmV3IGluc3RhbmNlcyB1c2luZyBleHRyYWN0b3JzCiAgICAgKiBGb3IgZXhhbXBsZTogVHJhbnNsYXRpb25zOjpmcm9tTW9GaWxlKCRmaWxlbmFtZSwgJG9wdGlvbnMpOy4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9ucwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIF9fY2FsbFN0YXRpYygkbmFtZSwgJGFyZ3VtZW50cykKICAgIHsKICAgICAgICBpZiAoIXByZWdfbWF0Y2goJy9eZnJvbShcdyspKEZpbGV8U3RyaW5nKSQvaScsICRuYW1lLCAkbWF0Y2hlcykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZE1ldGhvZENhbGxFeGNlcHRpb24oIlRoZSBtZXRob2QgJG5hbWUgZG9lcyBub3QgZXhpc3RzIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmNfYXJyYXkoW25ldyBzdGF0aWMoKSwgJ2FkZCcudWNmaXJzdCgkbmFtZSldLCAkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBpbXBvcnQvZXhwb3J0IHRoZSB0cmFuc2xhdGlvbnMgdG8gYSBzcGVjaWZpYyBmb3JtYXQKICAgICAqIEZvciBleGFtcGxlOiAkdHJhbnNsYXRpb25zLT50b01vRmlsZSgkZmlsZW5hbWUsICRvcHRpb25zKTsKICAgICAqIEZvciBleGFtcGxlOiAkdHJhbnNsYXRpb25zLT5hZGRGcm9tTW9GaWxlKCRmaWxlbmFtZSwgJG9wdGlvbnMpOy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGZ8Ym9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jYWxsKCRuYW1lLCAkYXJndW1lbnRzKQogICAgewogICAgICAgIGlmICghcHJlZ19tYXRjaCgnL14oYWRkRnJvbXx0bykoXHcrKShGaWxlfFN0cmluZykkL2knLCAkbmFtZSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCYWRNZXRob2RDYWxsRXhjZXB0aW9uKCJUaGUgbWV0aG9kICRuYW1lIGRvZXMgbm90IGV4aXN0cyIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRtYXRjaGVzWzFdID09PSAnYWRkRnJvbScpIHsKICAgICAgICAgICAgJGV4dHJhY3RvciA9ICdHZXR0ZXh0XFxFeHRyYWN0b3JzXFwnLiRtYXRjaGVzWzJdLic6OmZyb20nLiRtYXRjaGVzWzNdOwogICAgICAgICAgICAkc291cmNlID0gYXJyYXlfc2hpZnQoJGFyZ3VtZW50cyk7CiAgICAgICAgICAgICRvcHRpb25zID0gYXJyYXlfc2hpZnQoJGFyZ3VtZW50cykgPzogW107CgogICAgICAgICAgICBjYWxsX3VzZXJfZnVuYygkZXh0cmFjdG9yLCAkc291cmNlLCAkdGhpcywgJG9wdGlvbnMpOwoKICAgICAgICAgICAgcmV0dXJuICR0aGlzOwogICAgICAgIH0KCiAgICAgICAgJGdlbmVyYXRvciA9ICdHZXR0ZXh0XFxHZW5lcmF0b3JzXFwnLiRtYXRjaGVzWzJdLic6OnRvJy4kbWF0Y2hlc1szXTsKCiAgICAgICAgYXJyYXlfdW5zaGlmdCgkYXJndW1lbnRzLCAkdGhpcyk7CgogICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuY19hcnJheSgkZ2VuZXJhdG9yLCAkYXJndW1lbnRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hZ2ljIG1ldGhvZCB0byBjbG9uZSBlYWNoIHRyYW5zbGF0aW9uIG9uIGNsb25lIHRoZSB0cmFuc2xhdGlvbnMgb2JqZWN0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jbG9uZSgpCiAgICB7CiAgICAgICAgJGFycmF5ID0gW107CgogICAgICAgIGZvcmVhY2ggKCR0aGlzIGFzICRrZXkgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgICRhcnJheVska2V5XSA9IGNsb25lICR0cmFuc2xhdGlvbjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5leGNoYW5nZUFycmF5KCRhcnJheSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb250cm9sIHRoZSBuZXcgdHJhbnNsYXRpb25zIGFkZGVkLgogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAkaW5kZXgKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbiAkdmFsdWUKICAgICAqCiAgICAgKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEdldHRleHRcVHJhbnNsYXRpb24KICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvZmZzZXRTZXQoJGluZGV4LCAkdmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCEoJHZhbHVlIGluc3RhbmNlb2YgVHJhbnNsYXRpb24pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAnT25seSBpbnN0YW5jZXMgb2YgR2V0dGV4dFxcVHJhbnNsYXRpb24gbXVzdCBiZSBhZGRlZCB0byBhIEdldHRleHRcXFRyYW5zbGF0aW9ucycKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRpZCA9ICR2YWx1ZS0+Z2V0SWQoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5vZmZzZXRFeGlzdHMoJGlkKSkgewogICAgICAgICAgICAkdGhpc1skaWRdLT5tZXJnZVdpdGgoJHZhbHVlKTsKCiAgICAgICAgICAgIHJldHVybiAkdGhpc1skaWRdOwogICAgICAgIH0KCiAgICAgICAgcGFyZW50OjpvZmZzZXRTZXQoJGlkLCAkdmFsdWUpOwoKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBwbHVyYWwgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICAgICRjb3VudAogICAgICogQHBhcmFtIHN0cmluZyAkcnVsZQogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGx1cmFsRm9ybXMoJGNvdW50LCAkcnVsZSkKICAgIHsKICAgICAgICBpZiAocHJlZ19tYXRjaCgnL1thLXpdL2knLCBzdHJfcmVwbGFjZSgnbicsICcnLCAkcnVsZSkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKCdJbnZhbGlkIFBsdXJhbCBmb3JtOiAnIC4gJHJ1bGUpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2V0SGVhZGVyKHNlbGY6OkhFQURFUl9QTFVSQUwsICJucGx1cmFscz17JGNvdW50fTsgcGx1cmFsPXskcnVsZX07Iik7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhcnNlZCBwbHVyYWwgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbnVsbHxhcnJheSBbY291bnQsIHJ1bGVdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQbHVyYWxGb3JtcygpCiAgICB7CiAgICAgICAgJGhlYWRlciA9ICR0aGlzLT5nZXRIZWFkZXIoc2VsZjo6SEVBREVSX1BMVVJBTCk7CgogICAgICAgIGlmICghZW1wdHkoJGhlYWRlcikKICAgICAgICAgICAgJiYgcHJlZ19tYXRjaCgnL15ucGx1cmFsc1xzKj1ccyooXGQrKVxzKjtccypwbHVyYWxccyo9XHMqKFteO10rKVxzKjskLycsICRoZWFkZXIsICRtYXRjaGVzKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gW2ludHZhbCgkbWF0Y2hlc1sxXSksICRtYXRjaGVzWzJdXTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYSBuZXcgaGVhZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRIZWFkZXIoJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkbmFtZSA9IHRyaW0oJG5hbWUpOwogICAgICAgICR0aGlzLT5oZWFkZXJzWyRuYW1lXSA9IHRyaW0oJHZhbHVlKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGhlYWRlciB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKgogICAgICogQHJldHVybiBudWxsfHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGVhZGVyKCRuYW1lKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+aGVhZGVyc1skbmFtZV0pID8gJHRoaXMtPmhlYWRlcnNbJG5hbWVdIDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIGhlYWRlciBmb3IgdGhpcyB0cmFuc2xhdGlvbnMgKGluIGFscGhhYmV0aWMgb3JkZXIpLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhlYWRlcnMoKQogICAgewogICAgICAgIGlmIChzdGF0aWM6OiRvcHRpb25zWydoZWFkZXJzU29ydGluZyddKSB7CiAgICAgICAgICAgIGtzb3J0KCR0aGlzLT5oZWFkZXJzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+aGVhZGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYWxsIGhlYWRlcnMuCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBkZWxldGVIZWFkZXJzKCkKICAgIHsKICAgICAgICAkdGhpcy0+aGVhZGVycyA9IFtdOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIG9uZSBoZWFkZXIuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGVsZXRlSGVhZGVyKCRuYW1lKQogICAgewogICAgICAgIHVuc2V0KCR0aGlzLT5oZWFkZXJzWyRuYW1lXSk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxhbmd1YWdlIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nICRsYW5ndWFnZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGFuZ3VhZ2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SGVhZGVyKHNlbGY6OkhFQURFUl9MQU5HVUFHRSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsYW5ndWFnZSBhbmQgdGhlIHBsdXJhbCBmb3Jtcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsYW5ndWFnZQogICAgICoKICAgICAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsYW5ndWFnZSBoYXNuJ3QgYmVlbiByZWNvZ25pemVkCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYW5ndWFnZSgkbGFuZ3VhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnNldEhlYWRlcihzZWxmOjpIRUFERVJfTEFOR1VBR0UsIHRyaW0oJGxhbmd1YWdlKSk7CgogICAgICAgIGlmICgoJGluZm8gPSBMYW5ndWFnZTo6Z2V0QnlJZCgkbGFuZ3VhZ2UpKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnNldFBsdXJhbEZvcm1zKGNvdW50KCRpbmZvLT5jYXRlZ29yaWVzKSwgJGluZm8tPmZvcm11bGEpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKCdUaGUgbGFuZ3VhZ2UgIiVzIiBpcyBub3QgdmFsaWQnLCAkbGFuZ3VhZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBsYW5ndWFnZSBpcyBlbXB0eSBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNMYW5ndWFnZSgpCiAgICB7CiAgICAgICAgJGxhbmd1YWdlID0gJHRoaXMtPmdldExhbmd1YWdlKCk7CgogICAgICAgIHJldHVybiAoaXNfc3RyaW5nKCRsYW5ndWFnZSkgJiYgKCRsYW5ndWFnZSAhPT0gJycpKSA/IHRydWUgOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIG5ldyBkb21haW4gZm9yIHRoaXMgdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RG9tYWluKCRkb21haW4pCiAgICB7CiAgICAgICAgJHRoaXMtPnNldEhlYWRlcihzZWxmOjpIRUFERVJfRE9NQUlOLCB0cmltKCRkb21haW4pKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZG9tYWluLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREb21haW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0SGVhZGVyKHNlbGY6OkhFQURFUl9ET01BSU4pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGRvbWFpbiBpcyBlbXB0eSBvciBub3QuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNEb21haW4oKQogICAgewogICAgICAgICRkb21haW4gPSAkdGhpcy0+Z2V0RG9tYWluKCk7CgogICAgICAgIHJldHVybiAoaXNfc3RyaW5nKCRkb21haW4pICYmICgkZG9tYWluICE9PSAnJykpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogU2VhcmNoIGZvciBhIHNwZWNpZmljIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmd8VHJhbnNsYXRpb24gJGNvbnRleHQgIFRoZSBjb250ZXh0IG9mIHRoZSB0cmFuc2xhdGlvbiBvciBhIHRyYW5zbGF0aW9uIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAgICRvcmlnaW5hbCBUaGUgb3JpZ2luYWwgc3RyaW5nCiAgICAgKiBAd2FybmluZyBUcmFuc2xhdGlvbnMgd2l0aCBjdXN0b20gaWRlbnRpZmllcnMgKGUuZy4gWExJRkYgdW5pdCBJRHMpIGNhbm5vdCBiZSBmb3VuZCB1c2luZyB0aGlzIGZ1bmN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gVHJhbnNsYXRpb258ZmFsc2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmQoJGNvbnRleHQsICRvcmlnaW5hbCA9ICcnKQogICAgewogICAgICAgIGlmICgkY29udGV4dCBpbnN0YW5jZW9mIFRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgICRpZCA9ICRjb250ZXh0LT5nZXRJZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRpZCA9IFRyYW5zbGF0aW9uOjpnZW5lcmF0ZUlkKCRjb250ZXh0LCAkb3JpZ2luYWwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzLT5vZmZzZXRFeGlzdHMoJGlkKSA/ICR0aGlzWyRpZF0gOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvdW50IGFsbCBlbGVtZW50cyB0cmFuc2xhdGVkCiAgICAgKgogICAgICogQHJldHVybiBpbnRlZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudFRyYW5zbGF0ZWQoKQogICAgewogICAgICAgICRjID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcyBhcyAkdikgewogICAgICAgICAgICBpZiAoJHYtPmhhc1RyYW5zbGF0aW9uKCkpIHsKICAgICAgICAgICAgICAgICRjKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbmQgaW5zZXJ0L21lcmdlcyBhIG5ldyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgdHJhbnNsYXRpb24gY29udGV4dAogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwgVGhlIHRyYW5zbGF0aW9uIG9yaWdpbmFsIHN0cmluZwogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsICAgVGhlIHRyYW5zbGF0aW9uIG9yaWdpbmFsIHBsdXJhbCBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uIFRoZSB0cmFuc2xhdGlvbiBjcmVhdGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbnNlcnQoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b2Zmc2V0U2V0KG51bGwsICR0aGlzLT5jcmVhdGVOZXdUcmFuc2xhdGlvbigkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZXMgdGhpcyB0cmFuc2xhdGlvbnMgd2l0aCBvdGhlciB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zIFRoZSB0cmFuc2xhdGlvbnMgaW5zdGFuY2UgdG8gbWVyZ2Ugd2l0aAogICAgICogQHBhcmFtIGludCAgICAgICAgICAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbWVyZ2VXaXRoKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCAkb3B0aW9ucyA9IE1lcmdlOjpERUZBVUxUUykKICAgIHsKICAgICAgICBNZXJnZTo6bWVyZ2VIZWFkZXJzKCR0cmFuc2xhdGlvbnMsICR0aGlzLCAkb3B0aW9ucyk7CiAgICAgICAgTWVyZ2U6Om1lcmdlVHJhbnNsYXRpb25zKCR0cmFuc2xhdGlvbnMsICR0aGlzLCAkb3B0aW9ucyk7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBhIFRyYW5zbGF0aW9uIG9iamVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgY29udGV4dCBvZiB0aGUgdHJhbnNsYXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsIFRoZSBvcmlnaW5hbCBzdHJpbmcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbCAgIFRoZSBvcmlnaW5hbCBwbHVyYWwgc3RyaW5nCiAgICAgKiBAcmV0dXJuIFRyYW5zbGF0aW9uIE5ldyBUcmFuc2xhdGlvbiBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlTmV3VHJhbnNsYXRpb24oJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgICRjbGFzcyA9ICR0aGlzLT50cmFuc2xhdGlvbkNsYXNzOwogICAgICAgIHJldHVybiAkY2xhc3M6OmNyZWF0ZSgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHQ7CgovKioKICogQ2xhc3MgdG8gbWFuYWdlIGEgdHJhbnNsYXRpb24gc3RyaW5nLgogKi8KY2xhc3MgVHJhbnNsYXRpb24KewogICAgcHJvdGVjdGVkICRpZDsKICAgIHByb3RlY3RlZCAkY29udGV4dDsKICAgIHByb3RlY3RlZCAkb3JpZ2luYWw7CiAgICBwcm90ZWN0ZWQgJHRyYW5zbGF0aW9uID0gJyc7CiAgICBwcm90ZWN0ZWQgJHBsdXJhbDsKICAgIHByb3RlY3RlZCAkcGx1cmFsVHJhbnNsYXRpb24gPSBbXTsKICAgIHByb3RlY3RlZCAkcmVmZXJlbmNlcyA9IFtdOwogICAgcHJvdGVjdGVkICRjb21tZW50cyA9IFtdOwogICAgcHJvdGVjdGVkICRleHRyYWN0ZWRDb21tZW50cyA9IFtdOwogICAgcHJvdGVjdGVkICRmbGFncyA9IFtdOwogICAgcHJvdGVjdGVkICRkaXNhYmxlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogR2VuZXJhdGVzIHRoZSBpZCBvZiBhIHRyYW5zbGF0aW9uIChjb250ZXh0ICsgZ2x1ZSArIG9yaWdpbmFsKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVJZCgkY29udGV4dCwgJG9yaWdpbmFsKQogICAgewogICAgICAgIHJldHVybiAieyRjb250ZXh0fVwwMDR7JG9yaWdpbmFsfSI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBUcmFuc2xhdGlvbiBvYmplY3QuCiAgICAgKgogICAgICogVGhpcyBpcyBhIGZhY3RvcnkgbWV0aG9kIHRoYXQgd2lsbCB3b3JrIGV2ZW4gd2hlbiBUcmFuc2xhdGlvbiBpcyBleHRlbmRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0ICBUaGUgY29udGV4dCBvZiB0aGUgdHJhbnNsYXRpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsIFRoZSBvcmlnaW5hbCBzdHJpbmcKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbCAgIFRoZSBvcmlnaW5hbCBwbHVyYWwgc3RyaW5nCiAgICAgKiBAcmV0dXJuIHN0YXRpYyBOZXcgVHJhbnNsYXRpb24gaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjcmVhdGUoJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiBuZXcgc3RhdGljKCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQgIFRoZSBjb250ZXh0IG9mIHRoZSB0cmFuc2xhdGlvbgogICAgICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwgVGhlIG9yaWdpbmFsIHN0cmluZwogICAgICogQHBhcmFtIHN0cmluZyAkcGx1cmFsICAgVGhlIG9yaWdpbmFsIHBsdXJhbCBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwgPSAnJykKICAgIHsKICAgICAgICAkdGhpcy0+Y29udGV4dCA9IChzdHJpbmcpICRjb250ZXh0OwogICAgICAgICR0aGlzLT5vcmlnaW5hbCA9IChzdHJpbmcpICRvcmlnaW5hbDsKCiAgICAgICAgJHRoaXMtPnNldFBsdXJhbCgkcGx1cmFsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENsb25lcyB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkY29udGV4dCAgT3B0aW9uYWwgbmV3IGNvbnRleHQKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkb3JpZ2luYWwgT3B0aW9uYWwgbmV3IG9yaWdpbmFsCiAgICAgKgogICAgICogQHJldHVybiBUcmFuc2xhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xvbmUoJGNvbnRleHQgPSBudWxsLCAkb3JpZ2luYWwgPSBudWxsKQogICAgewogICAgICAgICRuZXcgPSBjbG9uZSAkdGhpczsKCiAgICAgICAgaWYgKCRjb250ZXh0ICE9PSBudWxsKSB7CiAgICAgICAgICAgICRuZXctPmNvbnRleHQgPSAoc3RyaW5nKSAkY29udGV4dDsKICAgICAgICB9CgogICAgICAgIGlmICgkb3JpZ2luYWwgIT09IG51bGwpIHsKICAgICAgICAgICAgJG5ldy0+b3JpZ2luYWwgPSAoc3RyaW5nKSAkb3JpZ2luYWw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJG5ldzsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGlkIG9mIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKiBAd2FybmluZyBUaGUgdXNlIG9mIHRoaXMgZnVuY3Rpb24gdG8gc2V0IGEgY3VzdG9tIElEIHdpbGwgcHJldmVudAogICAgICogIFRyYW5zbGF0aW9uczo6ZmluZCBmcm9tIG1hdGNoaW5nIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElkKCRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICB9CgoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaWQgb2YgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SWQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aWQgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHN0YXRpYzo6Z2VuZXJhdGVJZCgkdGhpcy0+Y29udGV4dCwgJHRoaXMtPm9yaWdpbmFsKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSB0cmFuc2xhdGlvbiBtYXRjaGVzIHdpdGggdGhlIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZXh0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXMoJGNvbnRleHQsICRvcmlnaW5hbCA9ICcnKQogICAgewogICAgICAgIHJldHVybiAoKCR0aGlzLT5jb250ZXh0ID09PSAkY29udGV4dCkgJiYgKCR0aGlzLT5vcmlnaW5hbCA9PT0gJG9yaWdpbmFsKSkgPyB0cnVlIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmFibGUgb3IgZGlzYWJsZSB0aGUgdHJhbnNsYXRpb24KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZGlzYWJsZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERpc2FibGVkKCRkaXNhYmxlZCkKICAgIHsKICAgICAgICAkdGhpcy0+ZGlzYWJsZWQgPSAoYm9vbCkgJGRpc2FibGVkOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHRyYW5zbGF0aW9uIGlzIGRpc2FibGVkCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0Rpc2FibGVkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRpc2FibGVkOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3JpZ2luYWwgc3RyaW5nLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcmlnaW5hbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcmlnaW5hbDsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgb3JpZ2luYWwgc3RyaW5nIGlzIGVtcHR5IG9yIG5vdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc09yaWdpbmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5vcmlnaW5hbCAhPT0gJycpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdHJhbnNsYXRpb24gc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRyYW5zbGF0aW9uCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFuc2xhdGlvbigkdHJhbnNsYXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPnRyYW5zbGF0aW9uID0gKHN0cmluZykgJHRyYW5zbGF0aW9uOwoKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0cmFuc2xhdGlvbiBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRyYW5zbGF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBzdHJpbmcgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzVHJhbnNsYXRpb24oKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPnRyYW5zbGF0aW9uICE9PSAnJykgPyB0cnVlIDogZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwbHVyYWwgdHJhbnNsYXRpb24gc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogICAgICoKICAgICAqIEByZXR1cm4gc2VsZgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGx1cmFsKCRwbHVyYWwpCiAgICB7CiAgICAgICAgJHRoaXMtPnBsdXJhbCA9IChzdHJpbmcpICRwbHVyYWw7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHBsdXJhbCB0cmFuc2xhdGlvbiBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdXJhbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wbHVyYWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIHBsdXJhbCB0cmFuc2xhdGlvbiBzdHJpbmcgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzUGx1cmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gKCR0aGlzLT5wbHVyYWwgIT09ICcnKSA/IHRydWUgOiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBhIG5ldyBwbHVyYWwgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRwbHVyYWwKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBsdXJhbFRyYW5zbGF0aW9ucyhhcnJheSAkcGx1cmFsKQogICAgewogICAgICAgICR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbiA9ICRwbHVyYWw7CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgYWxsIHBsdXJhbCB0cmFuc2xhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIGludCAkc2l6ZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBsdXJhbFRyYW5zbGF0aW9ucygkc2l6ZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRzaXplID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb247CiAgICAgICAgfQoKICAgICAgICAkY3VycmVudCA9IGNvdW50KCR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbik7CgogICAgICAgIGlmICgkc2l6ZSA+ICRjdXJyZW50KSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24gKyBhcnJheV9maWxsKDAsICRzaXplLCAnJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHNpemUgPCAkY3VycmVudCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXlfc2xpY2UoJHRoaXMtPnBsdXJhbFRyYW5zbGF0aW9uLCAwLCAkc2l6ZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHRoaXMtPnBsdXJhbFRyYW5zbGF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZXJlIGFyZSBhbnkgcGx1cmFsIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjaGVja0NvbnRlbnQKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1BsdXJhbFRyYW5zbGF0aW9ucygkY2hlY2tDb250ZW50ID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCRjaGVja0NvbnRlbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGltcGxvZGUoJycsICR0aGlzLT5wbHVyYWxUcmFuc2xhdGlvbikgIT09ICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICFlbXB0eSgkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbGwgcGx1cmFsIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZVBsdXJhbFRyYW5zbGF0aW9uKCkKICAgIHsKICAgICAgICAkdGhpcy0+cGx1cmFsVHJhbnNsYXRpb24gPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY29udGV4dCBvZiB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb250ZXh0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbnRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGNvbnRleHQgaXMgZW1wdHkgb3Igbm90LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29udGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuIChpc3NldCgkdGhpcy0+Y29udGV4dCkgJiYgKCR0aGlzLT5jb250ZXh0ICE9PSAnJykpID8gdHJ1ZSA6IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyByZWZlcmVuY2UgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAgICRmaWxlbmFtZSBUaGUgZmlsZSBwYXRoIHdoZXJlIHRoZSB0cmFuc2xhdGlvbiBoYXMgYmVlbiBmb3VuZAogICAgICogQHBhcmFtIG51bGx8aW50ICRsaW5lICAgICBUaGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIHRyYW5zbGF0aW9uIGhhcyBiZWVuIGZvdW5kCiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRSZWZlcmVuY2UoJGZpbGVuYW1lLCAkbGluZSA9IG51bGwpCiAgICB7CiAgICAgICAgJGtleSA9ICJ7JGZpbGVuYW1lfTp7JGxpbmV9IjsKICAgICAgICAkdGhpcy0+cmVmZXJlbmNlc1ska2V5XSA9IFskZmlsZW5hbWUsICRsaW5lXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBoYXMgYW55IHJlZmVyZW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc1JlZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiAhZW1wdHkoJHRoaXMtPnJlZmVyZW5jZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFsbCByZWZlcmVuY2VzIGZvciB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiBhcnJheV92YWx1ZXMoJHRoaXMtPnJlZmVyZW5jZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbGwgcmVmZXJlbmNlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZVJlZmVyZW5jZXMoKQogICAgewogICAgICAgICR0aGlzLT5yZWZlcmVuY2VzID0gW107CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSBuZXcgY29tbWVudCBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tZW50CiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDb21tZW50KCRjb21tZW50KQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJGNvbW1lbnQsICR0aGlzLT5jb21tZW50cywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzW10gPSAkY29tbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgdHJhbnNsYXRpb24gaGFzIGFueSBjb21tZW50LgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzQ29tbWVudHMoKQogICAgewogICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+Y29tbWVudHNbMF0pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgY29tbWVudHMgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tbWVudHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tbWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUNvbW1lbnRzKCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWVudHMgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBleHRyYWN0ZWQgY29tbWVudCBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb21tZW50CiAgICAgKgogICAgICogQHJldHVybiBzZWxmCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFeHRyYWN0ZWRDb21tZW50KCRjb21tZW50KQogICAgewogICAgICAgIGlmICghaW5fYXJyYXkoJGNvbW1lbnQsICR0aGlzLT5leHRyYWN0ZWRDb21tZW50cywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmV4dHJhY3RlZENvbW1lbnRzW10gPSAkY29tbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgdHJhbnNsYXRpb24gaGFzIGFueSBleHRyYWN0ZWQgY29tbWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhc0V4dHJhY3RlZENvbW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmV4dHJhY3RlZENvbW1lbnRzWzBdKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIGV4dHJhY3RlZCBjb21tZW50cyBmb3IgdGhpcyB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHRyYWN0ZWRDb21tZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHRyYWN0ZWRDb21tZW50czsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYWxsIGV4dHJhY3RlZCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUV4dHJhY3RlZENvbW1lbnRzKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXh0cmFjdGVkQ29tbWVudHMgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBmbGFnIGZvciB0aGlzIHRyYW5zbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZsYWcKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEZsYWcoJGZsYWcpCiAgICB7CiAgICAgICAgaWYgKCFpbl9hcnJheSgkZmxhZywgJHRoaXMtPmZsYWdzLCB0cnVlKSkgewogICAgICAgICAgICAkdGhpcy0+ZmxhZ3NbXSA9ICRmbGFnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSB0cmFuc2xhdGlvbiBoYXMgYW55IGZsYWcuCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYXNGbGFncygpCiAgICB7CiAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5mbGFnc1swXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBleHRyYWN0ZWQgZmxhZ3MgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmxhZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCBmbGFncy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUZsYWdzKCkKICAgIHsKICAgICAgICAkdGhpcy0+ZmxhZ3MgPSBbXTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogTWVyZ2VzIHRoaXMgdHJhbnNsYXRpb24gd2l0aCBvdGhlciB0cmFuc2xhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uIFRoZSB0cmFuc2xhdGlvbiB0byBtZXJnZSB3aXRoCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIHNlbGYKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1lcmdlV2l0aChUcmFuc2xhdGlvbiAkdHJhbnNsYXRpb24sICRvcHRpb25zID0gTWVyZ2U6OkRFRkFVTFRTKQogICAgewogICAgICAgIE1lcmdlOjptZXJnZVRyYW5zbGF0aW9uKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKICAgICAgICBNZXJnZTo6bWVyZ2VSZWZlcmVuY2VzKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKICAgICAgICBNZXJnZTo6bWVyZ2VDb21tZW50cygkdHJhbnNsYXRpb24sICR0aGlzLCAkb3B0aW9ucyk7CiAgICAgICAgTWVyZ2U6Om1lcmdlRXh0cmFjdGVkQ29tbWVudHMoJHRyYW5zbGF0aW9uLCAkdGhpcywgJG9wdGlvbnMpOwogICAgICAgIE1lcmdlOjptZXJnZUZsYWdzKCR0cmFuc2xhdGlvbiwgJHRoaXMsICRvcHRpb25zKTsKCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxHZW5lcmF0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb247CnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIERPTURvY3VtZW50OwoKY2xhc3MgWGxpZmYgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgY29uc3QgVU5JVF9JRF9SRUdFWFAgPSAnL15YTElGRl9VTklUX0lEOiAoLiopJC8nOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkb20gPSBuZXcgRE9NRG9jdW1lbnQoJzEuMCcsICd1dGYtOCcpOwogICAgICAgICRkb20tPmZvcm1hdE91dHB1dCA9IHRydWU7CiAgICAgICAgJHhsaWZmID0gJGRvbS0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlRWxlbWVudCgneGxpZmYnKSk7CiAgICAgICAgJHhsaWZmLT5zZXRBdHRyaWJ1dGUoJ3htbG5zJywgJ3VybjpvYXNpczpuYW1lczp0Yzp4bGlmZjpkb2N1bWVudDoyLjAnKTsKICAgICAgICAkeGxpZmYtPnNldEF0dHJpYnV0ZSgndmVyc2lvbicsICcyLjAnKTsKICAgICAgICAkeGxpZmYtPnNldEF0dHJpYnV0ZSgnc3JjTGFuZycsICR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkpOwogICAgICAgICR4bGlmZi0+c2V0QXR0cmlidXRlKCd0cmdMYW5nJywgJHRyYW5zbGF0aW9ucy0+Z2V0TGFuZ3VhZ2UoKSk7CiAgICAgICAgJGZpbGUgPSAkeGxpZmYtPmFwcGVuZENoaWxkKCRkb20tPmNyZWF0ZUVsZW1lbnQoJ2ZpbGUnKSk7CiAgICAgICAgJGZpbGUtPnNldEF0dHJpYnV0ZSgnaWQnLCAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKS4nLicuJHRyYW5zbGF0aW9ucy0+Z2V0TGFuZ3VhZ2UoKSk7CgogICAgICAgIC8vU2F2ZSBoZWFkZXJzIGFzIG5vdGVzCiAgICAgICAgJG5vdGVzID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnbm90ZXMnKTsKCiAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9ucy0+Z2V0SGVhZGVycygpIGFzICRuYW1lID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkbm90ZXMtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ25vdGUnLCAkdmFsdWUpKS0+c2V0QXR0cmlidXRlKCdpZCcsICRuYW1lKTsKICAgICAgICB9CgogICAgICAgIGlmICgkbm90ZXMtPmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAkZmlsZS0+YXBwZW5kQ2hpbGQoJG5vdGVzKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIC8vRmluZCBhbiBYTElGRiB1bml0IElELCBpZiBvbmUgaXMgYXZhaWxhYmxlOyBvdGhlcndpc2UgZ2VuZXJhdGUKICAgICAgICAgICAgJHVuaXRJZCA9IHN0YXRpYzo6Z2V0VW5pdElEKCR0cmFuc2xhdGlvbik/Om1kNSgkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKS4kdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCkpOwoKICAgICAgICAgICAgJHVuaXQgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCd1bml0Jyk7CiAgICAgICAgICAgICR1bml0LT5zZXRBdHRyaWJ1dGUoJ2lkJywgJHVuaXRJZCk7CgogICAgICAgICAgICAvL1NhdmUgY29tbWVudHMgYXMgbm90ZXMKICAgICAgICAgICAgJG5vdGVzID0gJGRvbS0+Y3JlYXRlRWxlbWVudCgnbm90ZXMnKTsKCiAgICAgICAgICAgICRub3Rlcy0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAnbm90ZScsICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpKSkKICAgICAgICAgICAgICAgIC0+c2V0QXR0cmlidXRlKCdjYXRlZ29yeScsICdjb250ZXh0Jyk7CgogICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgIC8vU2tpcCBYTElGRiB1bml0IElEIGNvbW1lbnRzLgogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goc3RhdGljOjpVTklUX0lEX1JFR0VYUCwgJGNvbW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG5vdGVzLT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICdub3RlJywgJGNvbW1lbnQpKQogICAgICAgICAgICAgICAgICAgIC0+c2V0QXR0cmlidXRlKCdjYXRlZ29yeScsICdjb21tZW50Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbi0+Z2V0RXh0cmFjdGVkQ29tbWVudHMoKSBhcyAkY29tbWVudCkgewogICAgICAgICAgICAgICAgJG5vdGVzLT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICdub3RlJywgJGNvbW1lbnQpKQogICAgICAgICAgICAgICAgICAgIC0+c2V0QXR0cmlidXRlKCdjYXRlZ29yeScsICdleHRyYWN0ZWQtY29tbWVudCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldEZsYWdzKCkgYXMgJGZsYWcpIHsKICAgICAgICAgICAgICAgICRub3Rlcy0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAnbm90ZScsICRmbGFnKSkKICAgICAgICAgICAgICAgICAgICAtPnNldEF0dHJpYnV0ZSgnY2F0ZWdvcnknLCAnZmxhZycpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldFJlZmVyZW5jZXMoKSBhcyAkcmVmZXJlbmNlKSB7CiAgICAgICAgICAgICAgICAkbm90ZXMtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ25vdGUnLCAkcmVmZXJlbmNlWzBdLic6Jy4kcmVmZXJlbmNlWzFdKSkKICAgICAgICAgICAgICAgICAgICAtPnNldEF0dHJpYnV0ZSgnY2F0ZWdvcnknLCAncmVmZXJlbmNlJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR1bml0LT5hcHBlbmRDaGlsZCgkbm90ZXMpOwoKICAgICAgICAgICAgJHNlZ21lbnQgPSAkdW5pdC0+YXBwZW5kQ2hpbGQoJGRvbS0+Y3JlYXRlRWxlbWVudCgnc2VnbWVudCcpKTsKICAgICAgICAgICAgJHNlZ21lbnQtPmFwcGVuZENoaWxkKHN0YXRpYzo6Y3JlYXRlVGV4dE5vZGUoJGRvbSwgJ3NvdXJjZScsICR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKSkpOwogICAgICAgICAgICAkc2VnbWVudC0+YXBwZW5kQ2hpbGQoc3RhdGljOjpjcmVhdGVUZXh0Tm9kZSgkZG9tLCAndGFyZ2V0JywgJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpKSk7CgogICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygpIGFzICRwbHVyYWwpIHsKICAgICAgICAgICAgICAgIGlmICgkcGx1cmFsICE9PSAnJykgewogICAgICAgICAgICAgICAgICAgICRzZWdtZW50LT5hcHBlbmRDaGlsZChzdGF0aWM6OmNyZWF0ZVRleHROb2RlKCRkb20sICd0YXJnZXQnLCAkcGx1cmFsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRmaWxlLT5hcHBlbmRDaGlsZCgkdW5pdCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGRvbS0+c2F2ZVhNTCgpOwogICAgfQoKICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlVGV4dE5vZGUoRE9NRG9jdW1lbnQgJGRvbSwgJG5hbWUsICRzdHJpbmcpCiAgICB7CiAgICAgICAgJG5vZGUgPSAkZG9tLT5jcmVhdGVFbGVtZW50KCRuYW1lKTsKICAgICAgICAkdGV4dCA9IChwcmVnX21hdGNoKCcvWyY8Pl0vJywgJHN0cmluZykgPT09IDEpCiAgICAgICAgICAgICA/ICRkb20tPmNyZWF0ZUNEQVRBU2VjdGlvbigkc3RyaW5nKQogICAgICAgICAgICAgOiAkZG9tLT5jcmVhdGVUZXh0Tm9kZSgkc3RyaW5nKTsKICAgICAgICAkbm9kZS0+YXBwZW5kQ2hpbGQoJHRleHQpOwoKICAgICAgICByZXR1cm4gJG5vZGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0cmFuc2xhdGlvbidzIHVuaXQgSUQsIGlmIG9uZSBpcyBhdmFpbGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9uICR0cmFuc2xhdGlvbgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRVbml0SUQoVHJhbnNsYXRpb24gJHRyYW5zbGF0aW9uKQogICAgewogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbi0+Z2V0Q29tbWVudHMoKSBhcyAkY29tbWVudCkgewogICAgICAgICAgICBpZiAocHJlZ19tYXRjaChzdGF0aWM6OlVOSVRfSURfUkVHRVhQLCAkY29tbWVudCwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJG1hdGNoZXNbMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgpjbGFzcyBQbyBleHRlbmRzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdub0xvY2F0aW9uJyA9PiBmYWxzZSwKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgJHBsdXJhbEZvcm0gPSAkdHJhbnNsYXRpb25zLT5nZXRQbHVyYWxGb3JtcygpOwogICAgICAgICRwbHVyYWxTaXplID0gaXNfYXJyYXkoJHBsdXJhbEZvcm0pID8gKCRwbHVyYWxGb3JtWzBdIC0gMSkgOiBudWxsOwogICAgICAgICRsaW5lcyA9IFsnbXNnaWQgIiInLCAnbXNnc3RyICIiJ107CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGxpbmVzW10gPSBzcHJpbnRmKCciJXM6ICVzXFxuIicsICRuYW1lLCAkdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgJGxpbmVzW10gPSAnJzsKCiAgICAgICAgLy9UcmFuc2xhdGlvbnMKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5oYXNDb21tZW50cygpKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb24tPmdldENvbW1lbnRzKCkgYXMgJGNvbW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcjICcuJGNvbW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc0V4dHJhY3RlZENvbW1lbnRzKCkpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbi0+Z2V0RXh0cmFjdGVkQ29tbWVudHMoKSBhcyAkY29tbWVudCkgewogICAgICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyMuICcuJGNvbW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJG9wdGlvbnNbJ25vTG9jYXRpb24nXSAmJiAkdHJhbnNsYXRpb24tPmhhc1JlZmVyZW5jZXMoKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRyYW5zbGF0aW9uLT5nZXRSZWZlcmVuY2VzKCkgYXMgJHJlZmVyZW5jZSkgewogICAgICAgICAgICAgICAgICAgICRsaW5lc1tdID0gJyM6ICcuJHJlZmVyZW5jZVswXS4oIWlzX251bGwoJHJlZmVyZW5jZVsxXSkgPyAnOicuJHJlZmVyZW5jZVsxXSA6IG51bGwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5oYXNGbGFncygpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICcjLCAnLmltcGxvZGUoJywnLCAkdHJhbnNsYXRpb24tPmdldEZsYWdzKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkcHJlZml4ID0gJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkgPyAnI34gJyA6ICcnOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzQ29udGV4dCgpKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICRwcmVmaXguJ21zZ2N0eHQgJy5zdGF0aWM6OmNvbnZlcnRTdHJpbmcoJHRyYW5zbGF0aW9uLT5nZXRDb250ZXh0KCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdGF0aWM6OmFkZExpbmVzKCRsaW5lcywgJHByZWZpeC4nbXNnaWQnLCAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCkpOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsKCkpIHsKICAgICAgICAgICAgICAgIHN0YXRpYzo6YWRkTGluZXMoJGxpbmVzLCAkcHJlZml4Lidtc2dpZF9wbHVyYWwnLCAkdHJhbnNsYXRpb24tPmdldFBsdXJhbCgpKTsKICAgICAgICAgICAgICAgIHN0YXRpYzo6YWRkTGluZXMoJGxpbmVzLCAkcHJlZml4Lidtc2dzdHJbMF0nLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCkpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCRwbHVyYWxTaXplKSBhcyAkayA9PiAkdikgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYzo6YWRkTGluZXMoJGxpbmVzLCAkcHJlZml4Lidtc2dzdHJbJy4oJGsgKyAxKS4nXScsICR2KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0YXRpYzo6YWRkTGluZXMoJGxpbmVzLCAkcHJlZml4Lidtc2dzdHInLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGluZXNbXSA9ICcnOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGltcGxvZGUoIlxuIiwgJGxpbmVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVzY2FwZXMgYW5kIGFkZHMgZG91YmxlIHF1b3RlcyB0byBhIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIG11bHRpbGluZVF1b3RlKCRzdHJpbmcpCiAgICB7CiAgICAgICAgJGxpbmVzID0gZXhwbG9kZSgiXG4iLCAkc3RyaW5nKTsKICAgICAgICAkbGFzdCA9IGNvdW50KCRsaW5lcykgLSAxOwoKICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGsgPT4gJGxpbmUpIHsKICAgICAgICAgICAgaWYgKCRrID09PSAkbGFzdCkgewogICAgICAgICAgICAgICAgJGxpbmVzWyRrXSA9IHN0YXRpYzo6Y29udmVydFN0cmluZygkbGluZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbGluZXNbJGtdID0gc3RhdGljOjpjb252ZXJ0U3RyaW5nKCRsaW5lLiJcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGxpbmVzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIG9uZSBvciBtb3JlIGxpbmVzIGRlcGVuZGluZyB3aGV0aGVyIHRoZSBzdHJpbmcgaXMgbXVsdGlsaW5lIG9yIG5vdC4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICYkbGluZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gYWRkTGluZXMoYXJyYXkgJiRsaW5lcywgJG5hbWUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkbmV3TGluZXMgPSBzdGF0aWM6Om11bHRpbGluZVF1b3RlKCR2YWx1ZSk7CgogICAgICAgIGlmIChjb3VudCgkbmV3TGluZXMpID09PSAxKSB7CiAgICAgICAgICAgICRsaW5lc1tdID0gJG5hbWUuJyAnLiRuZXdMaW5lc1swXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbGluZXNbXSA9ICRuYW1lLicgIiInOwoKICAgICAgICAgICAgZm9yZWFjaCAoJG5ld0xpbmVzIGFzICRsaW5lKSB7CiAgICAgICAgICAgICAgICAkbGluZXNbXSA9ICRsaW5lOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydCBhIHN0cmluZyB0byBpdHMgUE8gcmVwcmVzZW50YXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNvbnZlcnRTdHJpbmcoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAnIicuc3RydHIoCiAgICAgICAgICAgICR2YWx1ZSwKICAgICAgICAgICAgWwogICAgICAgICAgICAgICAgIlx4MDAiID0+ICcnLAogICAgICAgICAgICAgICAgJ1xcJyA9PiAnXFxcXCcsCiAgICAgICAgICAgICAgICAiXHQiID0+ICdcdCcsCiAgICAgICAgICAgICAgICAiXHIiID0+ICdccicsCiAgICAgICAgICAgICAgICAiXG4iID0+ICdcbicsCiAgICAgICAgICAgICAgICAnIicgPT4gJ1xcIicsCiAgICAgICAgICAgIF0KICAgICAgICApLiciJzsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxZYW1sXFlhbWwgYXMgWWFtbER1bXBlcjsKCmNsYXNzIFlhbWwgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgdXNlIE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0OwoKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2luY2x1ZGVIZWFkZXJzJyA9PiBmYWxzZSwKICAgICAgICAnaW5kZW50JyA9PiAyLAogICAgICAgICdpbmxpbmUnID0+IDQsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgIHJldHVybiBZYW1sRHVtcGVyOjpkdW1wKAogICAgICAgICAgICBzdGF0aWM6OnRvQXJyYXkoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnNbJ2luY2x1ZGVIZWFkZXJzJ10pLAogICAgICAgICAgICAkb3B0aW9uc1snaW5saW5lJ10sCiAgICAgICAgICAgICRvcHRpb25zWydpbmRlbnQnXQogICAgICAgICk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgphYnN0cmFjdCBjbGFzcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9GaWxlKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCAkZmlsZSwgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkY29udGVudCA9IHN0YXRpYzo6dG9TdHJpbmcoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwoKICAgICAgICBpZiAoZmlsZV9wdXRfY29udGVudHMoJGZpbGUsICRjb250ZW50KSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXERpY3Rpb25hcnlUcmFpdDsKdXNlIEdldHRleHRcVXRpbHNcQ3N2VHJhaXQ7CgpjbGFzcyBDc3ZEaWN0aW9uYXJ5IGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CiAgICB1c2UgQ3N2VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IGZhbHNlLAogICAgICAgICdkZWxpbWl0ZXInID0+ICIsIiwKICAgICAgICAnZW5jbG9zdXJlJyA9PiAnIicsCiAgICAgICAgJ2VzY2FwZV9jaGFyJyA9PiAiXFwiCiAgICBdOwoKICAgIC8qKgogICAgICoge0BwYXJlbnREb2N9LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CiAgICAgICAgJGhhbmRsZSA9IGZvcGVuKCdwaHA6Ly9tZW1vcnknLCAndycpOwoKICAgICAgICBmb3JlYWNoIChzdGF0aWM6OnRvQXJyYXkoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnNbJ2luY2x1ZGVIZWFkZXJzJ10pIGFzICRvcmlnaW5hbCA9PiAkdHJhbnNsYXRpb24pIHsKICAgICAgICAgICAgc3RhdGljOjpmcHV0Y3N2KCRoYW5kbGUsIFskb3JpZ2luYWwsICR0cmFuc2xhdGlvbl0sICRvcHRpb25zKTsKICAgICAgICB9CgogICAgICAgIHJld2luZCgkaGFuZGxlKTsKICAgICAgICAkY3N2ID0gc3RyZWFtX2dldF9jb250ZW50cygkaGFuZGxlKTsKICAgICAgICBmY2xvc2UoJGhhbmRsZSk7CgogICAgICAgIHJldHVybiAkY3N2OwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxHZW5lcmF0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKY2xhc3MgSmVkIGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHB1YmxpYyBzdGF0aWMgJG9wdGlvbnMgPSBbCiAgICAgICAgJ2pzb24nID0+IDAsCiAgICBdOwoKICAgIC8qKgogICAgICoge0BwYXJlbnREb2N9LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRkb21haW4gPSAkdHJhbnNsYXRpb25zLT5nZXREb21haW4oKSA/OiAnbWVzc2FnZXMnOwogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CgogICAgICAgIHJldHVybiBqc29uX2VuY29kZShbCiAgICAgICAgICAgICRkb21haW4gPT4gWwogICAgICAgICAgICAgICAgJycgPT4gWwogICAgICAgICAgICAgICAgICAgICdkb21haW4nID0+ICRkb21haW4sCiAgICAgICAgICAgICAgICAgICAgJ2xhbmcnID0+ICR0cmFuc2xhdGlvbnMtPmdldExhbmd1YWdlKCkgPzogJ2VuJywKICAgICAgICAgICAgICAgICAgICAncGx1cmFsLWZvcm1zJyA9PiAkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXIoJ1BsdXJhbC1Gb3JtcycpID86ICducGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7JywKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgIF0gKyBzdGF0aWM6OmJ1aWxkTWVzc2FnZXMoJHRyYW5zbGF0aW9ucyksCiAgICAgICAgXSwgJG9wdGlvbnNbJ2pzb24nXSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZXMgYW4gYXJyYXkgd2l0aCBhbGwgdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBidWlsZE1lc3NhZ2VzKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgICRwbHVyYWxGb3JtID0gJHRyYW5zbGF0aW9ucy0+Z2V0UGx1cmFsRm9ybXMoKTsKICAgICAgICAkcGx1cmFsU2l6ZSA9IGlzX2FycmF5KCRwbHVyYWxGb3JtKSA/ICgkcGx1cmFsRm9ybVswXSAtIDEpIDogbnVsbDsKICAgICAgICAkbWVzc2FnZXMgPSBbXTsKICAgICAgICAkY29udGV4dF9nbHVlID0gJ1x1MDAwNCc7CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRrZXkgPSAoJHRyYW5zbGF0aW9uLT5oYXNDb250ZXh0KCkgPyAkdHJhbnNsYXRpb24tPmdldENvbnRleHQoKS4kY29udGV4dF9nbHVlIDogJycpCiAgICAgICAgICAgICAgICAuJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsVHJhbnNsYXRpb25zKHRydWUpKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICR0cmFuc2xhdGlvbi0+Z2V0UGx1cmFsVHJhbnNsYXRpb25zKCRwbHVyYWxTaXplKTsKICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJG1lc3NhZ2UsICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IFskdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCldOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbWVzc2FnZXNbJGtleV0gPSAkbWVzc2FnZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkbWVzc2FnZXM7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKCmNsYXNzIE1vIGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBIZWFkZXJzR2VuZXJhdG9yVHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IHRydWUsCiAgICBdOwoKICAgIC8qKgogICAgICoge0BwYXJlbnREb2N9LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRvcHRpb25zICs9IHN0YXRpYzo6JG9wdGlvbnM7CiAgICAgICAgJG1lc3NhZ2VzID0gW107CgogICAgICAgIGlmICgkb3B0aW9uc1snaW5jbHVkZUhlYWRlcnMnXSkgewogICAgICAgICAgICAkbWVzc2FnZXNbJyddID0gc3RhdGljOjpnZW5lcmF0ZUhlYWRlcnMoJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoISR0cmFuc2xhdGlvbi0+aGFzVHJhbnNsYXRpb24oKSB8fCAkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc0NvbnRleHQoKSkgewogICAgICAgICAgICAgICAgJG9yaWdpbmFsU3RyaW5nID0gJHRyYW5zbGF0aW9uLT5nZXRDb250ZXh0KCkuIlx4MDQiLiR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRvcmlnaW5hbFN0cmluZyA9ICR0cmFuc2xhdGlvbi0+Z2V0T3JpZ2luYWwoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG1lc3NhZ2VzWyRvcmlnaW5hbFN0cmluZ10gPSAkdHJhbnNsYXRpb247CiAgICAgICAgfQoKICAgICAgICBrc29ydCgkbWVzc2FnZXMpOwogICAgICAgICRudW1FbnRyaWVzID0gY291bnQoJG1lc3NhZ2VzKTsKICAgICAgICAkb3JpZ2luYWxzVGFibGUgPSAnJzsKICAgICAgICAkdHJhbnNsYXRpb25zVGFibGUgPSAnJzsKICAgICAgICAkb3JpZ2luYWxzSW5kZXggPSBbXTsKICAgICAgICAkdHJhbnNsYXRpb25zSW5kZXggPSBbXTsKICAgICAgICAkcGx1cmFsRm9ybSA9ICR0cmFuc2xhdGlvbnMtPmdldFBsdXJhbEZvcm1zKCk7CiAgICAgICAgJHBsdXJhbFNpemUgPSBpc19hcnJheSgkcGx1cmFsRm9ybSkgPyAoJHBsdXJhbEZvcm1bMF0gLSAxKSA6IG51bGw7CgogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkb3JpZ2luYWxTdHJpbmcgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmIChpc19zdHJpbmcoJHRyYW5zbGF0aW9uKSkgewogICAgICAgICAgICAgICAgLy8gSGVhZGVycwogICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uU3RyaW5nID0gJHRyYW5zbGF0aW9uOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogQHZhciAkdHJhbnNsYXRpb24gXEdldHRleHRcVHJhbnNsYXRpb24gKi8KICAgICAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc1BsdXJhbCgpICYmICR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsVHJhbnNsYXRpb25zKHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJG9yaWdpbmFsU3RyaW5nIC49ICJceDAwIi4kdHJhbnNsYXRpb24tPmdldFBsdXJhbCgpOwogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvblN0cmluZyA9ICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKTsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25TdHJpbmcgLj0gIlx4MDAiLmltcGxvZGUoIlx4MDAiLCAkdHJhbnNsYXRpb24tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygkcGx1cmFsU2l6ZSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25TdHJpbmcgPSAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRvcmlnaW5hbHNJbmRleFtdID0gWwogICAgICAgICAgICAgICAgJ3JlbGF0aXZlT2Zmc2V0JyA9PiBzdHJsZW4oJG9yaWdpbmFsc1RhYmxlKSwKICAgICAgICAgICAgICAgICdsZW5ndGgnID0+IHN0cmxlbigkb3JpZ2luYWxTdHJpbmcpCiAgICAgICAgICAgIF07CiAgICAgICAgICAgICRvcmlnaW5hbHNUYWJsZSAuPSAkb3JpZ2luYWxTdHJpbmcuIlx4MDAiOwogICAgICAgICAgICAkdHJhbnNsYXRpb25zSW5kZXhbXSA9IFsKICAgICAgICAgICAgICAgICdyZWxhdGl2ZU9mZnNldCcgPT4gc3RybGVuKCR0cmFuc2xhdGlvbnNUYWJsZSksCiAgICAgICAgICAgICAgICAnbGVuZ3RoJyA9PiBzdHJsZW4oJHRyYW5zbGF0aW9uU3RyaW5nKQogICAgICAgICAgICBdOwogICAgICAgICAgICAkdHJhbnNsYXRpb25zVGFibGUgLj0gJHRyYW5zbGF0aW9uU3RyaW5nLiJceDAwIjsKICAgICAgICB9CgogICAgICAgIC8vIE9mZnNldCBvZiB0YWJsZSB3aXRoIHRoZSBvcmlnaW5hbCBzdHJpbmdzIGluZGV4OiByaWdodCBhZnRlciB0aGUgaGVhZGVyICh3aGljaCBpcyA3IHdvcmRzKQogICAgICAgICRvcmlnaW5hbHNJbmRleE9mZnNldCA9IDcgKiA0OwoKICAgICAgICAvLyBTaXplIG9mIHRhYmxlIHdpdGggdGhlIG9yaWdpbmFsIHN0cmluZ3MgaW5kZXgKICAgICAgICAkb3JpZ2luYWxzSW5kZXhTaXplID0gJG51bUVudHJpZXMgKiAoNCArIDQpOwoKICAgICAgICAvLyBPZmZzZXQgb2YgdGFibGUgd2l0aCB0aGUgdHJhbnNsYXRpb24gc3RyaW5ncyBpbmRleDogcmlnaHQgYWZ0ZXIgdGhlIG9yaWdpbmFsIHN0cmluZ3MgaW5kZXggdGFibGUKICAgICAgICAkdHJhbnNsYXRpb25zSW5kZXhPZmZzZXQgPSAkb3JpZ2luYWxzSW5kZXhPZmZzZXQgKyAkb3JpZ2luYWxzSW5kZXhTaXplOwoKICAgICAgICAvLyBTaXplIG9mIHRhYmxlIHdpdGggdGhlIHRyYW5zbGF0aW9uIHN0cmluZ3MgaW5kZXgKICAgICAgICAkdHJhbnNsYXRpb25zSW5kZXhTaXplID0gJG51bUVudHJpZXMgKiAoNCArIDQpOwoKICAgICAgICAvLyBIYXNoaW5nIHRhYmxlIHN0YXJ0cyBhZnRlciB0aGUgaGVhZGVyIGFuZCBhZnRlciB0aGUgaW5kZXggdGFibGUKICAgICAgICAkb3JpZ2luYWxzU3RyaW5nc09mZnNldCA9ICR0cmFuc2xhdGlvbnNJbmRleE9mZnNldCArICR0cmFuc2xhdGlvbnNJbmRleFNpemU7CgogICAgICAgIC8vIFRyYW5zbGF0aW9ucyBzdGFydCBhZnRlciB0aGUga2V5cwogICAgICAgICR0cmFuc2xhdGlvbnNTdHJpbmdzT2Zmc2V0ID0gJG9yaWdpbmFsc1N0cmluZ3NPZmZzZXQgKyBzdHJsZW4oJG9yaWdpbmFsc1RhYmxlKTsKCiAgICAgICAgLy8gTGV0J3MgZ2VuZXJhdGUgdGhlIC5tbyBmaWxlIGJpbmFyeSBkYXRhCiAgICAgICAgJG1vID0gJyc7CgogICAgICAgIC8vIE1hZ2ljIG51bWJlcgogICAgICAgICRtbyAuPSBwYWNrKCdMJywgMHg5NTA0MTJkZSk7CgogICAgICAgIC8vIEZpbGUgZm9ybWF0IHJldmlzaW9uCiAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAwKTsKCiAgICAgICAgLy8gTnVtYmVyIG9mIHN0cmluZ3MKICAgICAgICAkbW8gLj0gcGFjaygnTCcsICRudW1FbnRyaWVzKTsKCiAgICAgICAgLy8gT2Zmc2V0IG9mIHRhYmxlIHdpdGggb3JpZ2luYWwgc3RyaW5ncwogICAgICAgICRtbyAuPSBwYWNrKCdMJywgJG9yaWdpbmFsc0luZGV4T2Zmc2V0KTsKCiAgICAgICAgLy8gT2Zmc2V0IG9mIHRhYmxlIHdpdGggdHJhbnNsYXRpb24gc3RyaW5ncwogICAgICAgICRtbyAuPSBwYWNrKCdMJywgJHRyYW5zbGF0aW9uc0luZGV4T2Zmc2V0KTsKCiAgICAgICAgLy8gU2l6ZSBvZiBoYXNoaW5nIHRhYmxlOiB3ZSBkb24ndCB1c2UgaXQuCiAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAwKTsKCiAgICAgICAgLy8gT2Zmc2V0IG9mIGhhc2hpbmcgdGFibGU6IGl0IHdvdWxkIHN0YXJ0IHJpZ2h0IGFmdGVyIHRoZSB0cmFuc2xhdGlvbnMgaW5kZXggdGFibGUKICAgICAgICAkbW8gLj0gcGFjaygnTCcsICR0cmFuc2xhdGlvbnNJbmRleE9mZnNldCArICR0cmFuc2xhdGlvbnNJbmRleFNpemUpOwoKICAgICAgICAvLyBXcml0ZSB0aGUgbGVuZ3RocyAmIG9mZnNldHMgb2YgdGhlIG9yaWdpbmFsIHN0cmluZ3MKICAgICAgICBmb3JlYWNoICgkb3JpZ2luYWxzSW5kZXggYXMgJGluZm8pIHsKICAgICAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAkaW5mb1snbGVuZ3RoJ10pOwogICAgICAgICAgICAkbW8gLj0gcGFjaygnTCcsICRvcmlnaW5hbHNTdHJpbmdzT2Zmc2V0ICsgJGluZm9bJ3JlbGF0aXZlT2Zmc2V0J10pOwogICAgICAgIH0KCiAgICAgICAgLy8gV3JpdGUgdGhlIGxlbmd0aHMgJiBvZmZzZXRzIG9mIHRoZSB0cmFuc2xhdGVkIHN0cmluZ3MKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zSW5kZXggYXMgJGluZm8pIHsKICAgICAgICAgICAgJG1vIC49IHBhY2soJ0wnLCAkaW5mb1snbGVuZ3RoJ10pOwogICAgICAgICAgICAkbW8gLj0gcGFjaygnTCcsICR0cmFuc2xhdGlvbnNTdHJpbmdzT2Zmc2V0ICsgJGluZm9bJ3JlbGF0aXZlT2Zmc2V0J10pOwogICAgICAgIH0KCiAgICAgICAgLy8gV3JpdGUgb3JpZ2luYWwgc3RyaW5ncwogICAgICAgICRtbyAuPSAkb3JpZ2luYWxzVGFibGU7CgogICAgICAgIC8vIFdyaXRlIHRyYW5zbGF0aW9uIHN0cmluZ3MKICAgICAgICAkbW8gLj0gJHRyYW5zbGF0aW9uc1RhYmxlOwoKICAgICAgICByZXR1cm4gJG1vOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxHZW5lcmF0b3JzOwoKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwp1c2UgR2V0dGV4dFxVdGlsc1xEaWN0aW9uYXJ5VHJhaXQ7CnVzZSBTeW1mb255XENvbXBvbmVudFxZYW1sXFlhbWwgYXMgWWFtbER1bXBlcjsKCmNsYXNzIFlhbWxEaWN0aW9uYXJ5IGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IGZhbHNlLAogICAgICAgICdpbmRlbnQnID0+IDIsCiAgICAgICAgJ2lubGluZScgPT4gMywKICAgIF07CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKCiAgICAgICAgcmV0dXJuIFlhbWxEdW1wZXI6OmR1bXAoCiAgICAgICAgICAgIHN0YXRpYzo6dG9BcnJheSgkdHJhbnNsYXRpb25zLCAkb3B0aW9uc1snaW5jbHVkZUhlYWRlcnMnXSksCiAgICAgICAgICAgICRvcHRpb25zWydpbmxpbmUnXSwKICAgICAgICAgICAgJG9wdGlvbnNbJ2luZGVudCddCiAgICAgICAgKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKdXNlIEdldHRleHRcVXRpbHNcTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgpjbGFzcyBQaHBBcnJheSBleHRlbmRzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICB1c2UgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IHRydWUsCiAgICBdOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0ZG9jfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRvU3RyaW5nKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucyA9IFtdKQogICAgewogICAgICAgICRhcnJheSA9IHN0YXRpYzo6Z2VuZXJhdGUoJHRyYW5zbGF0aW9ucywgJG9wdGlvbnMpOwoKICAgICAgICByZXR1cm4gJzw/cGhwIHJldHVybiAnLnZhcl9leHBvcnQoJGFycmF5LCB0cnVlKS4nOyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZXMgYW4gYXJyYXkgd2l0aCB0aGUgdHJhbnNsYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkb3B0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZW5lcmF0ZShUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4gc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddLCB0cnVlKTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcR2VuZXJhdG9yczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCmludGVyZmFjZSBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgLyoqCiAgICAgKiBTYXZlcyB0aGUgdHJhbnNsYXRpb25zIGluIGEgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGZpbGUKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b0ZpbGUoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsICRmaWxlLCBhcnJheSAkb3B0aW9ucyA9IFtdKTsKCiAgICAvKioKICAgICAqIEdlbmVyYXRlcyBhIHN0cmluZyB3aXRoIHRoZSB0cmFuc2xhdGlvbnMgcmVhZHkgdG8gc2F2ZSBpbiBhIGZpbGUuCiAgICAgKgogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSk7Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXERpY3Rpb25hcnlUcmFpdDsKCmNsYXNzIEpzb25EaWN0aW9uYXJ5IGV4dGVuZHMgR2VuZXJhdG9yIGltcGxlbWVudHMgR2VuZXJhdG9ySW50ZXJmYWNlCnsKICAgIHVzZSBEaWN0aW9uYXJ5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnanNvbicgPT4gMCwKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IGZhbHNlLAogICAgXTsKCiAgICAvKioKICAgICAqIHtAcGFyZW50RG9jfS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4ganNvbl9lbmNvZGUoc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddKSwgJG9wdGlvbnNbJ2pzb24nXSk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXE11bHRpZGltZW5zaW9uYWxBcnJheVRyYWl0OwoKY2xhc3MgSnNvbiBleHRlbmRzIEdlbmVyYXRvciBpbXBsZW1lbnRzIEdlbmVyYXRvckludGVyZmFjZQp7CiAgICB1c2UgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQ7CgogICAgcHVibGljIHN0YXRpYyAkb3B0aW9ucyA9IFsKICAgICAgICAnanNvbicgPT4gMCwKICAgICAgICAnaW5jbHVkZUhlYWRlcnMnID0+IGZhbHNlLAogICAgXTsKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0b1N0cmluZyhUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgYXJyYXkgJG9wdGlvbnMgPSBbXSkKICAgIHsKICAgICAgICAkb3B0aW9ucyArPSBzdGF0aWM6OiRvcHRpb25zOwoKICAgICAgICByZXR1cm4ganNvbl9lbmNvZGUoc3RhdGljOjp0b0FycmF5KCR0cmFuc2xhdGlvbnMsICRvcHRpb25zWydpbmNsdWRlSGVhZGVycyddLCB0cnVlKSwgJG9wdGlvbnNbJ2pzb24nXSk7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XEdlbmVyYXRvcnM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CnVzZSBHZXR0ZXh0XFV0aWxzXEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKdXNlIEdldHRleHRcVXRpbHNcQ3N2VHJhaXQ7CgovKioKICogQ2xhc3MgdG8gZXhwb3J0IHRyYW5zbGF0aW9ucyB0byBjc3YuCiAqLwpjbGFzcyBDc3YgZXh0ZW5kcyBHZW5lcmF0b3IgaW1wbGVtZW50cyBHZW5lcmF0b3JJbnRlcmZhY2UKewogICAgdXNlIEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKICAgIHVzZSBDc3ZUcmFpdDsKCiAgICBwdWJsaWMgc3RhdGljICRvcHRpb25zID0gWwogICAgICAgICdpbmNsdWRlSGVhZGVycycgPT4gZmFsc2UsCiAgICAgICAgJ2RlbGltaXRlcicgPT4gIiwiLAogICAgICAgICdlbmNsb3N1cmUnID0+ICciJywKICAgICAgICAnZXNjYXBlX2NoYXInID0+ICJcXCIKICAgIF07CgogICAgLyoqCiAgICAgKiB7QHBhcmVudERvY30uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdG9TdHJpbmcoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsIGFycmF5ICRvcHRpb25zID0gW10pCiAgICB7CiAgICAgICAgJG9wdGlvbnMgKz0gc3RhdGljOjokb3B0aW9uczsKICAgICAgICAkaGFuZGxlID0gZm9wZW4oJ3BocDovL21lbW9yeScsICd3Jyk7CgogICAgICAgIGlmICgkb3B0aW9uc1snaW5jbHVkZUhlYWRlcnMnXSkgewogICAgICAgICAgICBzdGF0aWM6OmZwdXRjc3YoJGhhbmRsZSwgWycnLCAnJywgc3RhdGljOjpnZW5lcmF0ZUhlYWRlcnMoJHRyYW5zbGF0aW9ucyldLCAkb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGluZSA9IFskdHJhbnNsYXRpb24tPmdldENvbnRleHQoKSwgJHRyYW5zbGF0aW9uLT5nZXRPcmlnaW5hbCgpLCAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCldOwoKICAgICAgICAgICAgaWYgKCR0cmFuc2xhdGlvbi0+aGFzUGx1cmFsVHJhbnNsYXRpb25zKHRydWUpKSB7CiAgICAgICAgICAgICAgICAkbGluZSA9IGFycmF5X21lcmdlKCRsaW5lLCAkdHJhbnNsYXRpb24tPmdldFBsdXJhbFRyYW5zbGF0aW9ucygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RhdGljOjpmcHV0Y3N2KCRoYW5kbGUsICRsaW5lLCAkb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICByZXdpbmQoJGhhbmRsZSk7CiAgICAgICAgJGNzdiA9IHN0cmVhbV9nZXRfY29udGVudHMoJGhhbmRsZSk7CiAgICAgICAgZmNsb3NlKCRoYW5kbGUpOwoKICAgICAgICByZXR1cm4gJGNzdjsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7CgovKioKICogQ29tbWVudCBwYXJzZWQgYnkgUGhwRnVuY3Rpb25zU2Nhbm5lci4KICovCmNsYXNzIFBhcnNlZENvbW1lbnQKewogICAgLyoqCiAgICAgKiBUaGUgY29tbWVudCBpdHNlbGYuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21tZW50OwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgc3RhcnRzLgogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkZmlyc3RMaW5lOwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgZW5kcy4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhc3RMaW5lOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbW1lbnQgVGhlIGNvbW1lbnQgaXRzZWxmLgogICAgICogQHBhcmFtIGludCAgICAkZmlyc3RMaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqIEBwYXJhbSBpbnQgICAgJGxhc3RMaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IGVuZHMuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29tbWVudCwgJGZpcnN0TGluZSwgJGxhc3RMaW5lKQogICAgewogICAgICAgICR0aGlzLT5jb21tZW50ID0gJGNvbW1lbnQ7CiAgICAgICAgJHRoaXMtPmZpcnN0TGluZSA9ICRmaXJzdExpbmU7CiAgICAgICAgJHRoaXMtPmxhc3RMaW5lID0gJGxhc3RMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIG5ldyBvYmplY3QgZnJvbSByYXcgY29tbWVudCBkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlIFRoZSBQSFAgY29tbWVudCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gaW50ICRsaW5lIFRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0YXRpYyBUaGUgcGFyc2VkIGNvbW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlKCR2YWx1ZSwgJGxpbmUpCiAgICB7CiAgICAgICAgJGxhc3RMaW5lID0gJGxpbmUgKyBzdWJzdHJfY291bnQoJHZhbHVlLCAiXG4iKTsKCiAgICAgICAgJGxpbmVzID0gYXJyYXlfbWFwKGZ1bmN0aW9uICgkbGluZSkgewogICAgICAgICAgICBpZiAoJycgPT09IHRyaW0oJGxpbmUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGxpbmUgPSBsdHJpbSgkbGluZSwgIiMqLyBcdCIpOwogICAgICAgICAgICAkbGluZSA9IHJ0cmltKCRsaW5lLCAiIyovIFx0Iik7CgogICAgICAgICAgICByZXR1cm4gdHJpbSgkbGluZSk7CiAgICAgICAgfSwgZXhwbG9kZSgiXG4iLCAkdmFsdWUpKTsKCiAgICAgICAgLy8gUmVtb3ZlIGVtcHR5IGxpbmVzLgogICAgICAgICRsaW5lcyA9IGFycmF5X2ZpbHRlcigkbGluZXMpOwogICAgICAgICR2YWx1ZSA9IGltcGxvZGUoJyAnLCAkbGluZXMpOwoKICAgICAgICByZXR1cm4gbmV3IHN0YXRpYygkdmFsdWUsICRsaW5lLCAkbGFzdExpbmUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBsaW5lIHdoZXJlIHRoZSBjb21tZW50IHN0YXJ0cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBMaW5lIG51bWJlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZpcnN0TGluZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5maXJzdExpbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxpbmUgd2hlcmUgdGhlIGNvbW1lbnQgZW5kcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGludCBMaW5lIG51bWJlci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhc3RMaW5lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhc3RMaW5lOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBhY3R1YWwgY29tbWVudCBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGNvbW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21tZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbW1lbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRoaXMgY29tbWVudCBpcyByZWxhdGVkIHdpdGggYSBnaXZlbiBmdW5jdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gUGFyc2VkRnVuY3Rpb24gJGZ1bmN0aW9uIFRoZSBmdW5jdGlvbiB0byBjaGVjay4KICAgICAqIEByZXR1cm4gYm9vbCBXaGV0aGVyIHRoZSBjb21tZW50IGlzIHJlbGF0ZWQgb3Igbm90LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNSZWxhdGVkV2l0aChQYXJzZWRGdW5jdGlvbiAkZnVuY3Rpb24pCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRMYXN0TGluZSgpID09PSAkZnVuY3Rpb24tPmdldExpbmUoKSB8fCAkdGhpcy0+Z2V0TGFzdExpbmUoKSA9PT0gJGZ1bmN0aW9uLT5nZXRMaW5lKCkgLSAxOwogICAgfQoKICAgIC8qKgogICAgICogV2hldGhlciB0aGUgY29tbWVudCBtYXRjaGVzIHRoZSByZXF1aXJlZCBwcmVmaXhlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHByZWZpeGVzIEFuIGFycmF5IG9mIHByZWZpeGVzIHRvIGNoZWNrLgogICAgICogQHJldHVybiBib29sIFdoZXRoZXIgdGhlIGNvbW1lbnQgbWF0Y2hlcyB0aGUgcHJlZml4ZXMgb3Igbm90LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2tQcmVmaXhlcyhhcnJheSAkcHJlZml4ZXMpCiAgICB7CiAgICAgICAgaWYgKCcnID09PSAkdGhpcy0+Y29tbWVudCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW1wdHkoJHByZWZpeGVzKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCRwcmVmaXhlcyBhcyAkcHJlZml4KSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJHRoaXMtPmNvbW1lbnQsICRwcmVmaXgpID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBHZXR0ZXh0XEV4dHJhY3RvcnNcUGhwQ29kZTsKCmNsYXNzIFBocEZ1bmN0aW9uc1NjYW5uZXIgZXh0ZW5kcyBGdW5jdGlvbnNTY2FubmVyCnsKICAgIC8qKgogICAgICogUEhQIHRva2VucyBvZiB0aGUgY29kZSB0byBiZSBwYXJzZWQuCiAgICAgKgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHRva2VuczsKCiAgICAvKioKICAgICAqIElmIG5vdCBmYWxzZSwgY29tbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQuCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8ZmFsc2V8YXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRleHRyYWN0Q29tbWVudHMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEVuYWJsZSBleHRyYWN0aW5nIGNvbW1lbnRzIHRoYXQgc3RhcnQgd2l0aCBhIHRhZyAoaWYgJHRhZyBpcyBlbXB0eSBhbGwgdGhlIGNvbW1lbnRzIHdpbGwgYmUgZXh0cmFjdGVkKS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHRhZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5hYmxlQ29tbWVudHNFeHRyYWN0aW9uKCR0YWcgPSAnJykKICAgIHsKICAgICAgICAkdGhpcy0+ZXh0cmFjdENvbW1lbnRzID0gJHRhZzsKICAgIH0KCiAgICAvKioKICAgICAqIERpc2FibGUgY29tbWVudHMgZXh0cmFjdGlvbi4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRpc2FibGVDb21tZW50c0V4dHJhY3Rpb24oKQogICAgewogICAgICAgICR0aGlzLT5leHRyYWN0Q29tbWVudHMgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgVGhlIHBocCBjb2RlIHRvIHNjYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb2RlKQogICAgewogICAgICAgICR0aGlzLT50b2tlbnMgPSBhcnJheV92YWx1ZXMoCiAgICAgICAgICAgIGFycmF5X2ZpbHRlcigKICAgICAgICAgICAgICAgIHRva2VuX2dldF9hbGwoJGNvZGUpLAogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCR0b2tlbikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAhaXNfYXJyYXkoJHRva2VuKSB8fCAkdG9rZW5bMF0gIT09IFRfV0hJVEVTUEFDRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKQogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXRkb2N9CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGdW5jdGlvbnMoYXJyYXkgJGNvbnN0YW50cyA9IFtdKQogICAgewogICAgICAgICRjb3VudCA9IGNvdW50KCR0aGlzLT50b2tlbnMpOwogICAgICAgIC8qIEB2YXIgUGFyc2VkRnVuY3Rpb25bXSAkYnVmZmVyRnVuY3Rpb25zICovCiAgICAgICAgJGJ1ZmZlckZ1bmN0aW9ucyA9IFtdOwogICAgICAgIC8qIEB2YXIgUGFyc2VkQ29tbWVudFtdICRidWZmZXJDb21tZW50cyAqLwogICAgICAgICRidWZmZXJDb21tZW50cyA9IFtdOwogICAgICAgIC8qIEB2YXIgYXJyYXkgJGZ1bmN0aW9ucyAqLwogICAgICAgICRmdW5jdGlvbnMgPSBbXTsKCiAgICAgICAgZm9yICgkayA9IDA7ICRrIDwgJGNvdW50OyArKyRrKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT50b2tlbnNbJGtdOwoKICAgICAgICAgICAgaWYgKGlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJ1ZmZlckZ1bmN0aW9uc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcsJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPm5leHRBcmd1bWVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJyknOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZ1bmN0aW9uc1tdID0gYXJyYXlfc2hpZnQoJGJ1ZmZlckZ1bmN0aW9ucyktPmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPnN0b3BBcmd1bWVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAoJHZhbHVlWzBdKSB7CiAgICAgICAgICAgICAgICBjYXNlIFRfQ09OU1RBTlRfRU5DQVBTRURfU1RSSU5HOgogICAgICAgICAgICAgICAgICAgIC8vYWRkIGFuIGFyZ3VtZW50IHRvIHRoZSBjdXJyZW50IGZ1bmN0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRidWZmZXJGdW5jdGlvbnNbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsoUGhwQ29kZTo6Y29udmVydFN0cmluZygkdmFsdWVbMV0pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBUX1NUUklORzoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGJ1ZmZlckZ1bmN0aW9uc1swXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRjb25zdGFudHNbJHZhbHVlWzFdXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsoJGNvbnN0YW50c1skdmFsdWVbMV1dKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RydG9sb3dlcigkdmFsdWVbMV0pID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF0tPmFkZEFyZ3VtZW50Q2h1bmsobnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlckZ1bmN0aW9uc1swXS0+c3RvcEFyZ3VtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL25ldyBmdW5jdGlvbiBmb3VuZAogICAgICAgICAgICAgICAgICAgIGZvciAoJGogPSAkayArIDE7ICRqIDwgJGNvdW50OyArKyRqKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRuZXh0VG9rZW4gPSAkdGhpcy0+dG9rZW5zWyRqXTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkbmV4dFRva2VuKSAmJiAkbmV4dFRva2VuWzBdID09PSBUX0NPTU1FTlQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHRUb2tlbiA9PT0gJygnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbmV3RnVuY3Rpb24gPSBuZXcgUGFyc2VkRnVuY3Rpb24oJHZhbHVlWzFdLCAkdmFsdWVbMl0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBjb21tZW50IHRoYXQgd2FzIG9uIHRoZSBsaW5lIGJlZm9yZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYnVmZmVyQ29tbWVudHNbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbW1lbnQgPSAkYnVmZmVyQ29tbWVudHNbMF07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY29tbWVudC0+aXNSZWxhdGVkV2l0aCgkbmV3RnVuY3Rpb24pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRuZXdGdW5jdGlvbi0+YWRkQ29tbWVudCgkY29tbWVudC0+Z2V0Q29tbWVudCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkYnVmZmVyRnVuY3Rpb25zLCAkbmV3RnVuY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGsgPSAkajsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBUX0NPTU1FTlQ6CiAgICAgICAgICAgICAgICAgICAgJGNvbW1lbnQgPSAkdGhpcy0+cGFyc2VQaHBDb21tZW50KCR2YWx1ZVsxXSwgJHZhbHVlWzJdKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCRjb21tZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGJ1ZmZlckNvbW1lbnRzLCAkY29tbWVudCk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY29tbWVudCBpcyBpbnNpZGUgdGhlIGZ1bmN0aW9uIGNhbGwuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYnVmZmVyRnVuY3Rpb25zWzBdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlckZ1bmN0aW9uc1swXS0+YWRkQ29tbWVudCgkY29tbWVudC0+Z2V0Q29tbWVudCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkYnVmZmVyRnVuY3Rpb25zWzBdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyRnVuY3Rpb25zWzBdLT5zdG9wQXJndW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkZnVuY3Rpb25zOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCB0aGUgYWN0dWFsIHRleHQgZnJvbSBhIFBIUCBjb21tZW50LgogICAgICoKICAgICAqIElmIHNldCwgb25seSByZXR1cm5zIGNvbW1lbnRzIHRoYXQgbWF0Y2ggdGhlIHByZWZpeChlcykuCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgVGhlIFBIUCBjb21tZW50LgogICAgICogQHBhcmFtIGludCAkbGluZSBMaW5lIG51bWJlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIG51bGx8UGFyc2VkQ29tbWVudCBDb21tZW50IG9yIG51bGwgaWYgY29tbWVudCBleHRyYWN0aW9uIGlzIGRpc2FibGVkIG9yIGlmIHRoZXJlIGlzIGEgcHJlZml4IG1pc21hdGNoLgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VQaHBDb21tZW50KCR2YWx1ZSwgJGxpbmUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5leHRyYWN0Q29tbWVudHMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLy90aGlzIHJldHVybnMgYSBjb21tZW50IG9yIG51bGwKICAgICAgICAkY29tbWVudCA9IFBhcnNlZENvbW1lbnQ6OmNyZWF0ZSgkdmFsdWUsICRsaW5lKTsKCiAgICAgICAgJHByZWZpeGVzID0gYXJyYXlfZmlsdGVyKChhcnJheSkgJHRoaXMtPmV4dHJhY3RDb21tZW50cyk7CgogICAgICAgIGlmICgkY29tbWVudCAmJiAkY29tbWVudC0+Y2hlY2tQcmVmaXhlcygkcHJlZml4ZXMpKSB7CiAgICAgICAgICAgIHJldHVybiAkY29tbWVudDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCmNsYXNzIEpzRnVuY3Rpb25zU2Nhbm5lciBleHRlbmRzIEZ1bmN0aW9uc1NjYW5uZXIKewogICAgcHJvdGVjdGVkICRjb2RlOwogICAgcHJvdGVjdGVkICRzdGF0dXMgPSBbXTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgVGhlIHBocCBjb2RlIHRvIHNjYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb2RlKQogICAgewogICAgICAgIC8vIE5vcm1hbGl6ZSBuZXdsaW5lIGNoYXJhY3RlcnMKICAgICAgICAkdGhpcy0+Y29kZSA9IHN0cl9yZXBsYWNlKFsiXHJcbiIsICJcblxyIiwgIlxyIl0sICJcbiIsICRjb2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdGRvY30KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEZ1bmN0aW9ucyhhcnJheSAkY29uc3RhbnRzID0gW10pCiAgICB7CiAgICAgICAgJGxlbmd0aCA9IHN0cmxlbigkdGhpcy0+Y29kZSk7CiAgICAgICAgJGxpbmUgPSAxOwogICAgICAgICRidWZmZXIgPSAnJzsKICAgICAgICAkZnVuY3Rpb25zID0gW107CiAgICAgICAgJGJ1ZmZlckZ1bmN0aW9ucyA9IFtdOwogICAgICAgICRjaGFyID0gbnVsbDsKCiAgICAgICAgZm9yICgkcG9zID0gMDsgJHBvcyA8ICRsZW5ndGg7ICsrJHBvcykgewogICAgICAgICAgICAkcHJldiA9ICRjaGFyOwogICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jb2RlWyRwb3NdOwogICAgICAgICAgICAkbmV4dCA9IGlzc2V0KCR0aGlzLT5jb2RlWyRwb3MgKyAxXSkgPyAkdGhpcy0+Y29kZVskcG9zICsgMV0gOiBudWxsOwoKICAgICAgICAgICAgc3dpdGNoICgkY2hhcikgewogICAgICAgICAgICAgICAgY2FzZSAnXFwnOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NpbXBsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHQgIT09ICInIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RvdWJsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHQgIT09ICciJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2JhY2stdGljayc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJG5leHQgIT09ICdgJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRwcmV2ID0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkbmV4dDsKICAgICAgICAgICAgICAgICAgICAkcG9zKys7CiAgICAgICAgICAgICAgICAgICAgJG5leHQgPSBpc3NldCgkdGhpcy0+Y29kZVskcG9zXSkgPyAkdGhpcy0+Y29kZVskcG9zXSA6IG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAiXG4iOgogICAgICAgICAgICAgICAgICAgICsrJGxpbmU7CgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c3RhdHVzKCdsaW5lLWNvbW1lbnQnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBTdGF0dXMoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnLyc6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2ltcGxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZG91YmxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmFjay10aWNrJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGluZS1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmxvY2stY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHByZXYgPT09ICcqJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cFN0YXR1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRuZXh0ID09PSAnLycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZG93blN0YXR1cygnbGluZS1jb21tZW50Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJG5leHQgPT09ICcqJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5kb3duU3RhdHVzKCdibG9jay1jb21tZW50Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAiJyI6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2ltcGxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT51cFN0YXR1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdsaW5lLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdibG9jay1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZG91YmxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmFjay10aWNrJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5kb3duU3RhdHVzKCdzaW1wbGUtcXVvdGUnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkb3VibGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVwU3RhdHVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2xpbmUtY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Jsb2NrLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzaW1wbGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiYWNrLXRpY2snOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmRvd25TdGF0dXMoJ2RvdWJsZS1xdW90ZScpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2AnOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2JhY2stdGljayc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dXBTdGF0dXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGluZS1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmxvY2stY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3NpbXBsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RvdWJsZS1xdW90ZSc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZG93blN0YXR1cygnYmFjay10aWNrJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnKCc6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+c3RhdHVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2ltcGxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZG91YmxlLXF1b3RlJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmFjay10aWNrJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGluZS1jb21tZW50JzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYmxvY2stY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGJ1ZmZlciAmJiBwcmVnX21hdGNoKCcvKFx3KykkLycsICRidWZmZXIsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5kb3duU3RhdHVzKCdmdW5jdGlvbicpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQoJGJ1ZmZlckZ1bmN0aW9ucywgWyRtYXRjaGVzWzFdLCAkbGluZSwgW11dKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcpJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdmdW5jdGlvbic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCRhcmd1bWVudCA9IHN0YXRpYzo6cHJlcGFyZUFyZ3VtZW50KCRidWZmZXIpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF1bMl1bXSA9ICRhcmd1bWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRidWZmZXJGdW5jdGlvbnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZ1bmN0aW9uc1tdID0gYXJyYXlfc2hpZnQoJGJ1ZmZlckZ1bmN0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnVwU3RhdHVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcsJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdmdW5jdGlvbic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCRhcmd1bWVudCA9IHN0YXRpYzo6cHJlcGFyZUFyZ3VtZW50KCRidWZmZXIpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXJGdW5jdGlvbnNbMF1bMl1bXSA9ICRhcmd1bWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcgJzoKICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCR0aGlzLT5zdGF0dXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkb3VibGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzaW1wbGUtcXVvdGUnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiYWNrLXRpY2snOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICcnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAoJHRoaXMtPnN0YXR1cygpKSB7CiAgICAgICAgICAgICAgICBjYXNlICdsaW5lLWNvbW1lbnQnOgogICAgICAgICAgICAgICAgY2FzZSAnYmxvY2stY29tbWVudCc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJGZ1bmN0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCBjb250ZXh0IG9mIHRoZSBzY2FuLgogICAgICoKICAgICAqIEBwYXJhbSBudWxsfHN0cmluZyAkbWF0Y2ggVG8gY2hlY2sgd2hldGhlciB0aGUgY3VycmVudCBzdGF0dXMgaXMgdGhpcyB2YWx1ZQogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHN0YXR1cygkbWF0Y2ggPSBudWxsKQogICAgewogICAgICAgICRzdGF0dXMgPSBpc3NldCgkdGhpcy0+c3RhdHVzWzBdKSA/ICR0aGlzLT5zdGF0dXNbMF0gOiBudWxsOwoKICAgICAgICBpZiAoJG1hdGNoICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdHVzID09PSAkbWF0Y2g7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJHN0YXR1czsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIG5ldyBzdGF0dXMgdG8gdGhlIHN0YWNrLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0YXR1cwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZG93blN0YXR1cygkc3RhdHVzKQogICAgewogICAgICAgIGFycmF5X3Vuc2hpZnQoJHRoaXMtPnN0YXR1cywgJHN0YXR1cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFuZCByZXR1cm4gdGhlIGN1cnJlbnQgc3RhdHVzLgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHVwU3RhdHVzKCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXlfc2hpZnQoJHRoaXMtPnN0YXR1cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmVwYXJlcyB0aGUgYXJndW1lbnRzIGZvdW5kIGluIGZ1bmN0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhcmd1bWVudAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcHJlcGFyZUFyZ3VtZW50KCRhcmd1bWVudCkKICAgIHsKICAgICAgICBpZiAoJGFyZ3VtZW50ICYmIGluX2FycmF5KCRhcmd1bWVudFswXSwgWyciJywgIiciLCAnYCddLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gc3RhdGljOjpjb252ZXJ0U3RyaW5nKHN1YnN0cigkYXJndW1lbnQsIDEsIC0xKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRGVjb2RlcyBhIHN0cmluZyB3aXRoIGFuIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0U3RyaW5nKCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoc3RycG9zKCR2YWx1ZSwgJ1xcJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAkdmFsdWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKAogICAgICAgICAgICAnL1xcXChufHJ8dHx2fGV8ZnwifFxcXCkvJywKICAgICAgICAgICAgZnVuY3Rpb24gKCRtYXRjaCkgewogICAgICAgICAgICAgICAgc3dpdGNoICgkbWF0Y2hbMV1bMF0pIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICduJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcbiI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAncic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXHIiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ3QnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlx0IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICd2JzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcdiI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZSc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiXGUiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ2YnOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxmIjsKICAgICAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICciJzsKICAgICAgICAgICAgICAgICAgICBjYXNlICdcXCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnXFwnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAkdmFsdWUKICAgICAgICApOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCi8qKgogKiBGdW5jdGlvbiBwYXJzZWQgYnkgUGhwRnVuY3Rpb25zU2Nhbm5lci4KICovCmNsYXNzIFBhcnNlZEZ1bmN0aW9uCnsKICAgIC8qKgogICAgICogVGhlIGZ1bmN0aW9uIG5hbWUuCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwoKICAgIC8qKgogICAgICogVGhlIGxpbmUgd2hlcmUgdGhlIGZ1bmN0aW9uIHN0YXJ0cy4KICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxpbmU7CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5ncyBleHRyYWN0ZWQgZnJvbSB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLgogICAgICoKICAgICAqIEB2YXIgc3RyaW5nW10KICAgICAqLwogICAgcHJvdGVjdGVkICRhcmd1bWVudHM7CgogICAgLyoqCiAgICAgKiBUaGUgY3VycmVudCBpbmRleCBvZiB0aGUgZnVuY3Rpb24gKC0xIGlmIG5vIGFyZ3VtZW50cykuCiAgICAgKgogICAgICogQHZhciBpbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50SW5kZXg7CgogICAgLyoqCiAgICAgKiBTaGFsbCB3ZSBzdG9wIGFkZGluZyBzdHJpbmcgY2h1bmtzIHRvIHRoZSBjdXJyZW50IGFyZ3VtZW50PwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50U3RvcHBlZDsKCiAgICAvKioKICAgICAqIEV4dHJhY3RlZCBjb21tZW50cy4KICAgICAqCiAgICAgKiBAdmFyIHN0cmluZ1tdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21tZW50czsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBmdW5jdGlvbiBuYW1lLgogICAgICogQHBhcmFtIGludCAgICAkbGluZSBUaGUgbGluZSB3aGVyZSB0aGUgZnVuY3Rpb24gc3RhcnRzLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUsICRsaW5lKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgJHRoaXMtPmxpbmUgPSAkbGluZTsKICAgICAgICAkdGhpcy0+YXJndW1lbnRzID0gW107CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50SW5kZXggPSAtMTsKICAgICAgICAkdGhpcy0+YXJndW1lbnRTdG9wcGVkID0gZmFsc2U7CiAgICAgICAgJHRoaXMtPmNvbW1lbnRzID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFN0b3AgZXh0cmFjdGluZyBzdHJpbmdzIGZyb20gdGhlIGN1cnJlbnQgYXJndW1lbnQgKGJlY2F1c2Ugd2UgZm91bmQgc29tZXRoaW5nIHRoYXQncyBub3QgYSBzdHJpbmcpLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc3RvcEFyZ3VtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmFyZ3VtZW50SW5kZXggPT09IC0xKSB7CiAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudEluZGV4ID0gMDsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50U3RvcHBlZCA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHbyB0byB0aGUgbmV4dCBhcmd1bWVudCBiZWNhdXNlIHdlIGEgY29tbWEgd2FzIGZvdW5kLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dEFyZ3VtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmFyZ3VtZW50SW5kZXggPT09IC0xKSB7CiAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmUgb2NjdXIsIGJ1dCBsZXQncyBzdGF5IHNhZmUgLSBEdXJpbmcgdGVzdC9kZXZlbG9wbWVudCBhbiBFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KICAgICAgICAgICAgJHRoaXMtPmFyZ3VtZW50SW5kZXggPSAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICsrJHRoaXMtPmFyZ3VtZW50SW5kZXg7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5hcmd1bWVudFN0b3BwZWQgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIHN0cmluZyB0byB0aGUgY3VycmVudCBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGNodW5rCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRBcmd1bWVudENodW5rKCRjaHVuaykKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmFyZ3VtZW50U3RvcHBlZCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5hcmd1bWVudEluZGV4ID09PSAtMSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmFyZ3VtZW50SW5kZXggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc3NldCgkdGhpcy0+YXJndW1lbnRzWyR0aGlzLT5hcmd1bWVudEluZGV4XSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudHNbJHRoaXMtPmFyZ3VtZW50SW5kZXhdIC49ICRjaHVuazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hcmd1bWVudHNbJHRoaXMtPmFyZ3VtZW50SW5kZXhdID0gJGNodW5rOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgY29tbWVudCBhc3NvY2lhdGVkIHRvIHRoaXMgZnVuY3Rpb24uCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkY29tbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQ29tbWVudCgkY29tbWVudCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzID09PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21tZW50cyA9IFtdOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29tbWVudHNbXSA9ICRjb21tZW50OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBsaW5lIHRoZSBmdW5jdGlvbiBzdGFydHMuCiAgICAgKgogICAgICogQHJldHVybiBpbnQgTGluZSBudW1iZXIuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaW5lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxpbmU7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGNsb3NpbmcgcGFyZW50aGVzaXMgd2FzIGZvdW5kOiByZXR1cm4gdGhlIGZpbmFsIGRhdGEuCiAgICAgKiBUaGUgYXJyYXkgcmV0dXJuZWQgaGFzIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgogICAgICogIDAgPT4gc3RyaW5nIFRoZSBmdW5jdGlvbiBuYW1lLgogICAgICogIDEgPT4gaW50IFRoZSBsaW5lIHdoZXJlIHRoZSBmdW5jdGlvbiBzdGFydHMuCiAgICAgKiAgMiA9PiBzdHJpbmdbXSB0aGUgc3RyaW5ncyBleHRyYWN0ZWQgZnJvbSB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLgogICAgICogIDMgPT4gc3RyaW5nW10gdGhlIGNvbW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhlIGZ1bmN0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICAkYXJndW1lbnRzID0gW107CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDw9ICR0aGlzLT5hcmd1bWVudEluZGV4OyArKyRpKSB7CiAgICAgICAgICAgICRhcmd1bWVudHNbJGldID0gaXNzZXQoJHRoaXMtPmFyZ3VtZW50c1skaV0pID8gJHRoaXMtPmFyZ3VtZW50c1skaV0gOiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgJHRoaXMtPm5hbWUsCiAgICAgICAgICAgICR0aGlzLT5saW5lLAogICAgICAgICAgICAkYXJndW1lbnRzLAogICAgICAgICAgICAkdGhpcy0+Y29tbWVudHMsCiAgICAgICAgXTsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogVHJhaXQgdG8gcHJvdmlkZSB0aGUgZnVuY3Rpb25hbGl0eSBvZiBleHRyYWN0aW5nIGhlYWRlcnMuCiAqLwp0cmFpdCBIZWFkZXJzR2VuZXJhdG9yVHJhaXQKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBoZWFkZXJzIGFzIGEgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZ2VuZXJhdGVIZWFkZXJzKFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgICRoZWFkZXJzID0gJyc7CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMtPmdldEhlYWRlcnMoKSBhcyAkbmFtZSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgJGhlYWRlcnMgLj0gc3ByaW50ZigiJXM6ICVzXG4iLCAkbmFtZSwgJHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkaGVhZGVyczsKICAgIH0KfQo8P3BocAoKbmFtZXNwYWNlIEdldHRleHRcVXRpbHM7Cgp1c2UgR2V0dGV4dFxUcmFuc2xhdGlvbnM7CgovKioKICogVHJhaXQgdXNlZCBieSBhbGwgZ2VuZXJhdG9ycyB0aGF0IGV4cG9ydHMgdGhlIHRyYW5zbGF0aW9ucyB0byBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cwogKiAoY29udGV4dCA9PiBbb3JpZ2luYWwgPT4gW3RyYW5zbGF0aW9uLCBwbHVyYWwxLCBwbHVyYWxuLi4uXV0pLgogKi8KdHJhaXQgTXVsdGlkaW1lbnNpb25hbEFycmF5VHJhaXQKewogICAgdXNlIEhlYWRlcnNHZW5lcmF0b3JUcmFpdDsKICAgIHVzZSBIZWFkZXJzRXh0cmFjdG9yVHJhaXQ7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS4KICAgICAqCiAgICAgKiBAcGFyYW0gVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGluY2x1ZGVIZWFkZXJzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICRmb3JjZUFycmF5CiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHRvQXJyYXkoVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMsICRpbmNsdWRlSGVhZGVycywgJGZvcmNlQXJyYXkgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcGx1cmFsRm9ybSA9ICR0cmFuc2xhdGlvbnMtPmdldFBsdXJhbEZvcm1zKCk7CiAgICAgICAgJHBsdXJhbFNpemUgPSBpc19hcnJheSgkcGx1cmFsRm9ybSkgPyAoJHBsdXJhbEZvcm1bMF0gLSAxKSA6IG51bGw7CiAgICAgICAgJG1lc3NhZ2VzID0gW107CgogICAgICAgIGlmICgkaW5jbHVkZUhlYWRlcnMpIHsKICAgICAgICAgICAgJG1lc3NhZ2VzWycnXSA9IFsKICAgICAgICAgICAgICAgICcnID0+IFtzdGF0aWM6OmdlbmVyYXRlSGVhZGVycygkdHJhbnNsYXRpb25zKV0sCiAgICAgICAgICAgIF07CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdHJhbnNsYXRpb25zIGFzICR0cmFuc2xhdGlvbikgewogICAgICAgICAgICBpZiAoJHRyYW5zbGF0aW9uLT5pc0Rpc2FibGVkKCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29udGV4dCA9ICR0cmFuc2xhdGlvbi0+Z2V0Q29udGV4dCgpOwogICAgICAgICAgICAkb3JpZ2luYWwgPSAkdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCk7CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRtZXNzYWdlc1skY29udGV4dF0pKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZXNbJGNvbnRleHRdID0gW107CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmhhc1BsdXJhbFRyYW5zbGF0aW9ucyh0cnVlKSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzWyRjb250ZXh0XVskb3JpZ2luYWxdID0gJHRyYW5zbGF0aW9uLT5nZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHBsdXJhbFNpemUpOwogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkbWVzc2FnZXNbJGNvbnRleHRdWyRvcmlnaW5hbF0sICR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZm9yY2VBcnJheSkgewogICAgICAgICAgICAgICAgJG1lc3NhZ2VzWyRjb250ZXh0XVskb3JpZ2luYWxdID0gWyR0cmFuc2xhdGlvbi0+Z2V0VHJhbnNsYXRpb24oKV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZXNbJGNvbnRleHRdWyRvcmlnaW5hbF0gPSAkdHJhbnNsYXRpb24tPmdldFRyYW5zbGF0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdkb21haW4nID0+ICR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpLAogICAgICAgICAgICAncGx1cmFsLWZvcm1zJyA9PiAkdHJhbnNsYXRpb25zLT5nZXRIZWFkZXIoJ1BsdXJhbC1Gb3JtcycpLAogICAgICAgICAgICAnbWVzc2FnZXMnID0+ICRtZXNzYWdlcywKICAgICAgICBdOwogICAgfQoKICAgIC8qKgogICAgICogRXh0cmFjdCB0aGUgZW50cmllcyBmcm9tIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICRtZXNzYWdlcwogICAgICogQHBhcmFtIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRtZXNzYWdlcywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkbWVzc2FnZXNbJ2RvbWFpbiddKSkgewogICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXREb21haW4oJG1lc3NhZ2VzWydkb21haW4nXSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVtcHR5KCRtZXNzYWdlc1sncGx1cmFsLWZvcm1zJ10pKSB7CiAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldEhlYWRlcihUcmFuc2xhdGlvbnM6OkhFQURFUl9QTFVSQUwsICRtZXNzYWdlc1sncGx1cmFsLWZvcm1zJ10pOwogICAgICAgIH0KCiAgICAgICAgZm9yZWFjaCAoJG1lc3NhZ2VzWydtZXNzYWdlcyddIGFzICRjb250ZXh0ID0+ICRjb250ZXh0VHJhbnNsYXRpb25zKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb250ZXh0VHJhbnNsYXRpb25zIGFzICRvcmlnaW5hbCA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgkY29udGV4dCA9PT0gJycgJiYgJG9yaWdpbmFsID09PSAnJykgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYzo6ZXh0cmFjdEhlYWRlcnMoaXNfYXJyYXkoJHZhbHVlKSA/IGFycmF5X3NoaWZ0KCR2YWx1ZSkgOiAkdmFsdWUsICR0cmFuc2xhdGlvbnMpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICR0cmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbi0+c2V0VHJhbnNsYXRpb24oYXJyYXlfc2hpZnQoJHZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRQbHVyYWxUcmFuc2xhdGlvbnMoJHZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5zZXRUcmFuc2xhdGlvbigkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCi8qKgogKiBUcmFpdCB1c2VkIGJ5IGFsbCBnZW5lcmF0b3JzIHRoYXQgZXhwb3J0cyB0aGUgdHJhbnNsYXRpb25zIHRvIHBsYWluIGRpY3Rpb25hcnkgKG9yaWdpbmFsID0+IHNpbmd1bGFyLXRyYW5zbGF0aW9uKS4KICovCnRyYWl0IERpY3Rpb25hcnlUcmFpdAp7CiAgICB1c2UgSGVhZGVyc0dlbmVyYXRvclRyYWl0OwogICAgdXNlIEhlYWRlcnNFeHRyYWN0b3JUcmFpdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwbGFpbiBkaWN0aW9uYXJ5IHdpdGggdGhlIGZvcm1hdCBbb3JpZ2luYWwgPT4gdHJhbnNsYXRpb25dLgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkaW5jbHVkZUhlYWRlcnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gdG9BcnJheShUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucywgJGluY2x1ZGVIZWFkZXJzKQogICAgewogICAgICAgICRtZXNzYWdlcyA9IFtdOwoKICAgICAgICBpZiAoJGluY2x1ZGVIZWFkZXJzKSB7CiAgICAgICAgICAgICRtZXNzYWdlc1snJ10gPSBzdGF0aWM6OmdlbmVyYXRlSGVhZGVycygkdHJhbnNsYXRpb25zKTsKICAgICAgICB9CgogICAgICAgIGZvcmVhY2ggKCR0cmFuc2xhdGlvbnMgYXMgJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICgkdHJhbnNsYXRpb24tPmlzRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRtZXNzYWdlc1skdHJhbnNsYXRpb24tPmdldE9yaWdpbmFsKCldID0gJHRyYW5zbGF0aW9uLT5nZXRUcmFuc2xhdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlczsKICAgIH0KCiAgICAvKioKICAgICAqIEV4dHJhY3QgdGhlIGVudHJpZXMgZnJvbSBhIGRpY3Rpb25hcnkuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICAkbWVzc2FnZXMKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheShhcnJheSAkbWVzc2FnZXMsIFRyYW5zbGF0aW9ucyAkdHJhbnNsYXRpb25zKQogICAgewogICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkb3JpZ2luYWwgPT4gJHRyYW5zbGF0aW9uKSB7CiAgICAgICAgICAgIGlmICgkb3JpZ2luYWwgPT09ICcnKSB7CiAgICAgICAgICAgICAgICBzdGF0aWM6OmV4dHJhY3RIZWFkZXJzKCR0cmFuc2xhdGlvbiwgJHRyYW5zbGF0aW9ucyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyYW5zbGF0aW9ucy0+aW5zZXJ0KG51bGwsICRvcmlnaW5hbCktPnNldFRyYW5zbGF0aW9uKCR0cmFuc2xhdGlvbik7CiAgICAgICAgfQogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCnVzZSBHZXR0ZXh0XFRyYW5zbGF0aW9uczsKCi8qKgogKiBUcmFpdCB0byBwcm92aWRlIHRoZSBmdW5jdGlvbmFsaXR5IG9mIGV4dHJhY3RpbmcgaGVhZGVycy4KICovCnRyYWl0IEhlYWRlcnNFeHRyYWN0b3JUcmFpdAp7CiAgICAvKioKICAgICAqIEFkZCB0aGUgaGVhZGVycyBmb3VuZCB0byB0aGUgdHJhbnNsYXRpb25zIGluc3RhbmNlLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGhlYWRlcnMKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnMgJHRyYW5zbGF0aW9ucwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBleHRyYWN0SGVhZGVycygkaGVhZGVycywgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMpCiAgICB7CiAgICAgICAgJGhlYWRlcnMgPSBleHBsb2RlKCJcbiIsICRoZWFkZXJzKTsKICAgICAgICAkY3VycmVudEhlYWRlciA9IG51bGw7CgogICAgICAgIGZvcmVhY2ggKCRoZWFkZXJzIGFzICRsaW5lKSB7CiAgICAgICAgICAgICRsaW5lID0gc3RhdGljOjpjb252ZXJ0U3RyaW5nKCRsaW5lKTsKCiAgICAgICAgICAgIGlmICgkbGluZSA9PT0gJycpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3RhdGljOjppc0hlYWRlckRlZmluaXRpb24oJGxpbmUpKSB7CiAgICAgICAgICAgICAgICAkaGVhZGVyID0gYXJyYXlfbWFwKCd0cmltJywgZXhwbG9kZSgnOicsICRsaW5lLCAyKSk7CiAgICAgICAgICAgICAgICAkY3VycmVudEhlYWRlciA9ICRoZWFkZXJbMF07CiAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb25zLT5zZXRIZWFkZXIoJGN1cnJlbnRIZWFkZXIsICRoZWFkZXJbMV0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGVudHJ5ID0gJHRyYW5zbGF0aW9ucy0+Z2V0SGVhZGVyKCRjdXJyZW50SGVhZGVyKTsKICAgICAgICAgICAgICAgICR0cmFuc2xhdGlvbnMtPnNldEhlYWRlcigkY3VycmVudEhlYWRlciwgJGVudHJ5LiRsaW5lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBpdCBpcyBhIGhlYWRlciBkZWZpbml0aW9uIGxpbmUuIFVzZWZ1bCBmb3IgZGlzdGd1aXNoaW5nIGJldHdlZW4gaGVhZGVyIGRlZmluaXRpb25zCiAgICAgKiBhbmQgcG9zc2libGUgY29udGludWF0aW9ucyBvZiBhIGhlYWRlciBlbnRyeS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsaW5lIExpbmUgdG8gcGFyc2UKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBpc0hlYWRlckRlZmluaXRpb24oJGxpbmUpCiAgICB7CiAgICAgICAgcmV0dXJuIChib29sKSBwcmVnX21hdGNoKCcvXltcdy1dKzovJywgJGxpbmUpOwogICAgfQoKICAgIC8qKgogICAgICogTm9ybWFsaXplIGEgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjb252ZXJ0U3RyaW5nKCR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQp9Cjw/cGhwCgpuYW1lc3BhY2UgR2V0dGV4dFxVdGlsczsKCmNsYXNzIFN0cmluZ1JlYWRlcgp7CiAgICBwdWJsaWMgJHBvczsKICAgIHB1YmxpYyAkc3RyOwogICAgcHVibGljICRzdHJsZW47CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3Rvci4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgVGhlIHN0cmluZyB0byByZWFkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc3RyKQogICAgewogICAgICAgICR0aGlzLT5zdHIgPSAkc3RyOwogICAgICAgICR0aGlzLT5zdHJsZW4gPSBzdHJsZW4oJHRoaXMtPnN0cik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkIGFuZCByZXR1cm5zIGEgcGFydCBvZiB0aGUgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBpbnQgJGJ5dGVzIFRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkKCRieXRlcykKICAgIHsKICAgICAgICAkZGF0YSA9IHN1YnN0cigkdGhpcy0+c3RyLCAkdGhpcy0+cG9zLCAkYnl0ZXMpOwoKICAgICAgICAkdGhpcy0+c2Vla3RvKCR0aGlzLT5wb3MgKyAkYnl0ZXMpOwoKICAgICAgICByZXR1cm4gJGRhdGE7CiAgICB9CgogICAgLyoqCiAgICAgKiBNb3ZlIHRoZSBjdXJzb3IgdG8gYSBzcGVjaWZpYyBwb3NpdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRwb3MgVGhlIGFtb3VudCBvZiBieXRlcyB0byBtb3ZlCiAgICAgKgogICAgICogQHJldHVybiBpbnQgVGhlIG5ldyBwb3NpdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2Vla3RvKCRwb3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnBvcyA9ICgkdGhpcy0+c3RybGVuIDwgJHBvcykgPyAkdGhpcy0+c3RybGVuIDogJHBvczsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5wb3M7CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XFV0aWxzOwoKdXNlIEV4Y2VwdGlvbjsKdXNlIEdldHRleHRcVHJhbnNsYXRpb25zOwoKYWJzdHJhY3QgY2xhc3MgRnVuY3Rpb25zU2Nhbm5lcgp7CiAgICAvKioKICAgICAqIFNjYW4gYW5kIHJldHVybnMgdGhlIGZ1bmN0aW9ucyBhbmQgdGhlIGFyZ3VtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJGNvbnN0YW50cyBDb25zdGFudHMgdXNlZCBpbiB0aGUgY29kZSB0byByZXBsYWNlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gZ2V0RnVuY3Rpb25zKGFycmF5ICRjb25zdGFudHMgPSBbXSk7CgogICAgLyoqCiAgICAgKiBTZWFyY2ggZm9yIHNwZWNpZmljIGZ1bmN0aW9ucyBhbmQgY3JlYXRlIHRyYW5zbGF0aW9ucy4KICAgICAqCiAgICAgKiBZb3UgY2FuIHBhc3MgbXVsdGlwbGUgdHJhbnNsYXRpb24gd2l0aCBkaWZmZXJlbnQgZG9tYWlucyBhbmQgdmFsdWUgZm91bmQgd2lsbCBiZSBzb3J0ZWQgcmVzcGVjdGl2ZWx5LgogICAgICoKICAgICAqIEBwYXJhbSBUcmFuc2xhdGlvbnN8VHJhbnNsYXRpb25zW10gJHRyYW5zbGF0aW9ucyBNdWx0aXBsZSBkb21haW4gdHJhbnNsYXRpb25zIGluc3RhbmNlcyB3aGVyZSB0byBzYXZlIHRoZSB2YWx1ZXMKICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBUaGUgZXh0cmFjdG9yIG9wdGlvbnMKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzYXZlR2V0dGV4dEZ1bmN0aW9ucygkdHJhbnNsYXRpb25zLCBhcnJheSAkb3B0aW9ucykKICAgIHsKICAgICAgICAkdHJhbnNsYXRpb25zID0gaXNfYXJyYXkoJHRyYW5zbGF0aW9ucykgPyAkdHJhbnNsYXRpb25zIDogWyR0cmFuc2xhdGlvbnNdOwoKICAgICAgICAvKiogQHZhciBUcmFuc2xhdGlvbnNbXSAkdHJhbnNsYXRpb25CeURvbWFpbiBbZG9tYWluID0+IHRyYW5zbGF0aW9ucywgLi5dICovCiAgICAgICAgJHRyYW5zbGF0aW9uQnlEb21haW4gPSBhcnJheV9yZWR1Y2UoJHRyYW5zbGF0aW9ucywgZnVuY3Rpb24gKCRjYXJyeSwgVHJhbnNsYXRpb25zICR0cmFuc2xhdGlvbnMpIHsKICAgICAgICAgICAgJGNhcnJ5WyR0cmFuc2xhdGlvbnMtPmdldERvbWFpbigpXSA9ICR0cmFuc2xhdGlvbnM7CiAgICAgICAgICAgIHJldHVybiAkY2Fycnk7CiAgICAgICAgfSwgW10pOwoKICAgICAgICAkZnVuY3Rpb25zID0gJG9wdGlvbnNbJ2Z1bmN0aW9ucyddOwogICAgICAgICRmaWxlID0gJG9wdGlvbnNbJ2ZpbGUnXTsKCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmdldEZ1bmN0aW9ucygkb3B0aW9uc1snY29uc3RhbnRzJ10pIGFzICRmdW5jdGlvbikgewogICAgICAgICAgICBsaXN0KCRuYW1lLCAkbGluZSwgJGFyZ3MpID0gJGZ1bmN0aW9uOwoKICAgICAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWydsaW5lT2Zmc2V0J10pKSB7CiAgICAgICAgICAgICAgICAkbGluZSArPSAkb3B0aW9uc1snbGluZU9mZnNldCddOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWlzc2V0KCRmdW5jdGlvbnNbJG5hbWVdKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRkZWNvbnN0cnVjdGVkID0gJHRoaXMtPmRlY29uc3RydWN0QXJncygkZnVuY3Rpb25zWyRuYW1lXSwgJGFyZ3MpOwoKICAgICAgICAgICAgaWYgKCEkZGVjb25zdHJ1Y3RlZCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpc3QoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCkgPSAkZGVjb25zdHJ1Y3RlZDsKCiAgICAgICAgICAgIGlmICgoc3RyaW5nKSRvcmlnaW5hbCA9PT0gJycpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkaXNEZWZhdWx0RG9tYWluID0gJGRvbWFpbiA9PT0gbnVsbDsKCiAgICAgICAgICAgICRkb21haW5UcmFuc2xhdGlvbnMgPSBpc3NldCgkdHJhbnNsYXRpb25CeURvbWFpblskZG9tYWluXSkgPyAkdHJhbnNsYXRpb25CeURvbWFpblskZG9tYWluXSA6IGZhbHNlOwoKICAgICAgICAgICAgaWYgKCFlbXB0eSgkb3B0aW9uc1snZG9tYWluT25seSddKSAmJiAkaXNEZWZhdWx0RG9tYWluKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB3ZSB3YW50IHRvIGZpbmQgdHJhbnNsYXRpb25zIGZvciBhIHNwZWNpZmljIGRvbWFpbiwgc2tpcCBkZWZhdWx0IGRvbWFpbiBtZXNzYWdlcwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghJGRvbWFpblRyYW5zbGF0aW9ucykgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmFuc2xhdGlvbiA9ICRkb21haW5UcmFuc2xhdGlvbnMtPmluc2VydCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsKTsKICAgICAgICAgICAgJHRyYW5zbGF0aW9uLT5hZGRSZWZlcmVuY2UoJGZpbGUsICRsaW5lKTsKCiAgICAgICAgICAgIGlmIChpc3NldCgkZnVuY3Rpb25bM10pKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZnVuY3Rpb25bM10gYXMgJGV4dHJhY3RlZENvbW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkdHJhbnNsYXRpb24tPmFkZEV4dHJhY3RlZENvbW1lbnQoJGV4dHJhY3RlZENvbW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRGVjb25zdHJ1Y3QgYXJndW1lbnRzIHRvIHRyYW5zbGF0aW9uIHZhbHVlcwogICAgICoKICAgICAqIEBwYXJhbSAkZnVuY3Rpb24KICAgICAqIEBwYXJhbSAkYXJncwogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZGVjb25zdHJ1Y3RBcmdzKCRmdW5jdGlvbiwgJGFyZ3MpCiAgICB7CiAgICAgICAgJGRvbWFpbiA9IG51bGw7CiAgICAgICAgJGNvbnRleHQgPSBudWxsOwogICAgICAgICRvcmlnaW5hbCA9IG51bGw7CiAgICAgICAgJHBsdXJhbCA9IG51bGw7CgogICAgICAgIHN3aXRjaCAoJGZ1bmN0aW9uKSB7CiAgICAgICAgICAgIGNhc2UgJ25vb3AnOgogICAgICAgICAgICBjYXNlICdnZXR0ZXh0JzoKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGFyZ3NbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJG9yaWdpbmFsID0gJGFyZ3NbMF07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnbmdldHRleHQnOgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJnc1sxXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBsaXN0KCRvcmlnaW5hbCwgJHBsdXJhbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdwZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzFdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGNvbnRleHQsICRvcmlnaW5hbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzFdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGRvbWFpbiwgJG9yaWdpbmFsKSA9ICRhcmdzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2RwZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzJdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICducGdldHRleHQnOgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJnc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBsaXN0KCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwpID0gJGFyZ3M7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnZG5wZ2V0dGV4dCc6CiAgICAgICAgICAgICAgICBpZiAoIWlzc2V0KCRhcmdzWzNdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3QoJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkbmdldHRleHQnOgogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkYXJnc1syXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBsaXN0KCRkb21haW4sICRvcmlnaW5hbCwgJHBsdXJhbCkgPSAkYXJnczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihzcHJpbnRmKCdOb3QgdmFsaWQgZnVuY3Rpb24gJXMnLCAkZnVuY3Rpb24pKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBbJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCwgJHBsdXJhbF07CiAgICB9Cn0KPD9waHAKCm5hbWVzcGFjZSBHZXR0ZXh0XFV0aWxzOwoKLyoKICogVHJhaXQgdG8gcHJvdmlkZSB0aGUgZnVuY3Rpb25hbGl0eSBvZiByZWFkL3dyaXRlIGNzdi4KICovCnRyYWl0IENzdlRyYWl0CnsKICAgIHByb3RlY3RlZCBzdGF0aWMgJGNzdkVzY2FwZUNoYXI7CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIHN1cHBvcnQgdGhlIGVzY2FwZV9jaGFyIGFyZ3VtZW50IHRvIGZnZXRjc3YvZnB1dGNzdiBvciBub3QKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzdXBwb3J0c0NzdkVzY2FwZUNoYXIoKQogICAgewogICAgICAgIGlmIChzdGF0aWM6OiRjc3ZFc2NhcGVDaGFyID09PSBudWxsKSB7CiAgICAgICAgICAgIHN0YXRpYzo6JGNzdkVzY2FwZUNoYXIgPSB2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjUuNCcpID49IDA7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3RhdGljOjokY3N2RXNjYXBlQ2hhcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSByZXNvdXJjZSAkaGFuZGxlCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZmdldGNzdigkaGFuZGxlLCAkb3B0aW9ucykKICAgIHsKICAgICAgICBpZiAoc3RhdGljOjpzdXBwb3J0c0NzdkVzY2FwZUNoYXIoKSkgewogICAgICAgICAgICByZXR1cm4gZmdldGNzdigkaGFuZGxlLCAwLCAkb3B0aW9uc1snZGVsaW1pdGVyJ10sICRvcHRpb25zWydlbmNsb3N1cmUnXSwgJG9wdGlvbnNbJ2VzY2FwZV9jaGFyJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZnZXRjc3YoJGhhbmRsZSwgMCwgJG9wdGlvbnNbJ2RlbGltaXRlciddLCAkb3B0aW9uc1snZW5jbG9zdXJlJ10pOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHJlc291cmNlICRoYW5kbGUKICAgICAqIEBwYXJhbSBhcnJheSAkZmllbGRzCiAgICAgKiBAcGFyYW0gYXJyYXkgJG9wdGlvbnMKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2x8aW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gZnB1dGNzdigkaGFuZGxlLCAkZmllbGRzLCAkb3B0aW9ucykKICAgIHsKICAgICAgICBpZiAoc3RhdGljOjpzdXBwb3J0c0NzdkVzY2FwZUNoYXIoKSkgewogICAgICAgICAgICByZXR1cm4gZnB1dGNzdigkaGFuZGxlLCAkZmllbGRzLCAkb3B0aW9uc1snZGVsaW1pdGVyJ10sICRvcHRpb25zWydlbmNsb3N1cmUnXSwgJG9wdGlvbnNbJ2VzY2FwZV9jaGFyJ10pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZwdXRjc3YoJGhhbmRsZSwgJGZpZWxkcywgJG9wdGlvbnNbJ2RlbGltaXRlciddLCAkb3B0aW9uc1snZW5jbG9zdXJlJ10pOwogICAgfQp9Cjw/cGhwCgpzcGxfYXV0b2xvYWRfcmVnaXN0ZXIoZnVuY3Rpb24gKCRjbGFzcykgewogICAgaWYgKHN0cnBvcygkY2xhc3MsICdHZXR0ZXh0XFwnKSAhPT0gMCkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAkZmlsZSA9IF9fRElSX18uc3RyX3JlcGxhY2UoJ1xcJywgRElSRUNUT1JZX1NFUEFSQVRPUiwgc3Vic3RyKCRjbGFzcywgc3RybGVuKCdHZXR0ZXh0JykpKS4nLnBocCc7CgogICAgaWYgKGlzX2ZpbGUoJGZpbGUpKSB7CiAgICAgICAgcmVxdWlyZV9vbmNlICRmaWxlOwogICAgfQp9KTsKPD9waHAKCnVzZSBHZXR0ZXh0XEJhc2VUcmFuc2xhdG9yOwoKLyoqCiAqIFJldHVybnMgdGhlIHRyYW5zbGF0aW9uIG9mIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gX18oJG9yaWdpbmFsKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+Z2V0dGV4dCgkb3JpZ2luYWwpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDEpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDEpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIE5vb3AsIG1hcmtzIHRoZSBzdHJpbmcgZm9yIHRyYW5zbGF0aW9uIGJ1dCByZXR1cm5zIGl0IHVuY2hhbmdlZC4KICoKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIG5vb3BfXygkb3JpZ2luYWwpCnsKICAgIHJldHVybiAkb3JpZ2luYWw7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBzaW5ndWxhci9wbHVyYWwgdHJhbnNsYXRpb24gb2YgYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAqIEBwYXJhbSBzdHJpbmcgJHBsdXJhbAogKiBAcGFyYW0gc3RyaW5nICR2YWx1ZQogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gbl9fKCRvcmlnaW5hbCwgJHBsdXJhbCwgJHZhbHVlKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+bmdldHRleHQoJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDMpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDMpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHRyYW5zbGF0aW9uIG9mIGEgc3RyaW5nIGluIGEgc3BlY2lmaWMgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkY29udGV4dAogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKgogKiBAcmV0dXJuIHN0cmluZwogKi8KZnVuY3Rpb24gcF9fKCRjb250ZXh0LCAkb3JpZ2luYWwpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAyKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAyKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbi4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJG9yaWdpbmFsCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBkX18oJGRvbWFpbiwgJG9yaWdpbmFsKQp7CiAgICAkdGV4dCA9IEJhc2VUcmFuc2xhdG9yOjokY3VycmVudC0+ZGdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAyKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAyKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbiBhbmQgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGRwX18oJGRvbWFpbiwgJGNvbnRleHQsICRvcmlnaW5hbCkKewogICAgJHRleHQgPSBCYXNlVHJhbnNsYXRvcjo6JGN1cnJlbnQtPmRwZ2V0dGV4dCgkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsKTsKCiAgICBpZiAoZnVuY19udW1fYXJncygpID09PSAzKSB7CiAgICAgICAgcmV0dXJuICR0ZXh0OwogICAgfQoKICAgICRhcmdzID0gYXJyYXlfc2xpY2UoZnVuY19nZXRfYXJncygpLCAzKTsKCiAgICByZXR1cm4gaXNfYXJyYXkoJGFyZ3NbMF0pID8gc3RydHIoJHRleHQsICRhcmdzWzBdKSA6IHZzcHJpbnRmKCR0ZXh0LCAkYXJncyk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBzaW5ndWxhci9wbHVyYWwgdHJhbnNsYXRpb24gb2YgYSBzdHJpbmcgaW4gYSBzcGVjaWZpYyBkb21haW4uCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGRvbWFpbgogKiBAcGFyYW0gc3RyaW5nICRvcmlnaW5hbAogKiBAcGFyYW0gc3RyaW5nICRwbHVyYWwKICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICoKICogQHJldHVybiBzdHJpbmcKICovCmZ1bmN0aW9uIGRuX18oJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5kbmdldHRleHQoJGRvbWFpbiwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDQpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDQpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHNpbmd1bGFyL3BsdXJhbCB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGNvbnRleHQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBucF9fKCRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSkKewogICAgJHRleHQgPSBCYXNlVHJhbnNsYXRvcjo6JGN1cnJlbnQtPm5wZ2V0dGV4dCgkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpOwoKICAgIGlmIChmdW5jX251bV9hcmdzKCkgPT09IDQpIHsKICAgICAgICByZXR1cm4gJHRleHQ7CiAgICB9CgogICAgJGFyZ3MgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDQpOwoKICAgIHJldHVybiBpc19hcnJheSgkYXJnc1swXSkgPyBzdHJ0cigkdGV4dCwgJGFyZ3NbMF0pIDogdnNwcmludGYoJHRleHQsICRhcmdzKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHNpbmd1bGFyL3BsdXJhbCB0cmFuc2xhdGlvbiBvZiBhIHN0cmluZyBpbiBhIHNwZWNpZmljIGRvbWFpbiBhbmQgY29udGV4dC4KICoKICogQHBhcmFtIHN0cmluZyAkZG9tYWluCiAqIEBwYXJhbSBzdHJpbmcgJGNvbnRleHQKICogQHBhcmFtIHN0cmluZyAkb3JpZ2luYWwKICogQHBhcmFtIHN0cmluZyAkcGx1cmFsCiAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAqCiAqIEByZXR1cm4gc3RyaW5nCiAqLwpmdW5jdGlvbiBkbnBfXygkZG9tYWluLCAkY29udGV4dCwgJG9yaWdpbmFsLCAkcGx1cmFsLCAkdmFsdWUpCnsKICAgICR0ZXh0ID0gQmFzZVRyYW5zbGF0b3I6OiRjdXJyZW50LT5kbnBnZXR0ZXh0KCRkb21haW4sICRjb250ZXh0LCAkb3JpZ2luYWwsICRwbHVyYWwsICR2YWx1ZSk7CgogICAgaWYgKGZ1bmNfbnVtX2FyZ3MoKSA9PT0gNSkgewogICAgICAgIHJldHVybiAkdGV4dDsKICAgIH0KCiAgICAkYXJncyA9IGFycmF5X3NsaWNlKGZ1bmNfZ2V0X2FyZ3MoKSwgNSk7CgogICAgcmV0dXJuIGlzX2FycmF5KCRhcmdzWzBdKSA/IHN0cnRyKCR0ZXh0LCAkYXJnc1swXSkgOiB2c3ByaW50ZigkdGV4dCwgJGFyZ3MpOwp9Cjw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3Q7CgovKioKICogTm9kZXMgcmVuZGVyZXIgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUmVuZGVyZXIKewogICAgLyoqCiAgICAgKiBGb3JtYXR0ZXIgdG8gdXNlIGZvciB0aGUgcmVuZGVyaW5nCiAgICAgKiAKICAgICAqIEB2YXIgRm9ybWF0dGVyXEJhc2UKICAgICAqLwogICAgcHJvdGVjdGVkICRmb3JtYXR0ZXI7CiAgICAKICAgIC8qKgogICAgICogUmVuZGVyaW5nIG9wdGlvbnMgdGFrZW4gZnJvbSB0aGUgZm9ybWF0dGVyCiAgICAgKiAKICAgICAqIEB2YXIgb2JqZWN0CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVuZGVyT3B0czsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlIHR5cGVzIHRoYXQgZG9lcyBub3QgcmVxdWlyZSBzZW1pY29sb24gaW5zZXJ0aW9uCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRub1NlbWljb2xvbiA9IGFycmF5KAogICAgICAgICJDbGFzc0RlY2xhcmF0aW9uIiwKICAgICAgICAiRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uIiwKICAgICAgICAiRm9ySW5TdGF0ZW1lbnQiLAogICAgICAgICJGb3JPZlN0YXRlbWVudCIsCiAgICAgICAgIkZvclN0YXRlbWVudCIsCiAgICAgICAgIkZ1bmN0aW9uRGVjbGFyYXRpb24iLAogICAgICAgICJJZlN0YXRlbWVudCIsCiAgICAgICAgIkxhYmVsZWRTdGF0ZW1lbnQiLAogICAgICAgICJTd2l0Y2hTdGF0ZW1lbnQiLAogICAgICAgICJUcnlTdGF0ZW1lbnQiLAogICAgICAgICJXaGlsZVN0YXRlbWVudCIsCiAgICAgICAgIldpdGhTdGF0ZW1lbnQiLAogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBmb3JtYXR0ZXIgdG8gdXNlIGZvciB0aGUgcmVuZGVyaW5nCiAgICAgKiAKICAgICAqIEBwYXJhbSBGb3JtYXR0ZXJcQmFzZSAgICAkZm9ybWF0dGVyICBGb3JtYXR0ZXIKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0dGVyKEZvcm1hdHRlclxCYXNlICRmb3JtYXR0ZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdHRlciA9ICRmb3JtYXR0ZXI7CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMgPSAob2JqZWN0KSBhcnJheSgKICAgICAgICAgICAgIm5sIiA9PiAkdGhpcy0+Zm9ybWF0dGVyLT5nZXROZXdMaW5lKCksCiAgICAgICAgICAgICJpbmQiID0+ICR0aGlzLT5mb3JtYXR0ZXItPmdldEluZGVudGF0aW9uKCksCiAgICAgICAgICAgICJubGJjIiA9PiAkdGhpcy0+Zm9ybWF0dGVyLT5nZXROZXdMaW5lQmVmb3JlQ3VybHlCcmFja2V0KCksCiAgICAgICAgICAgICJzYW8iID0+ICAkdGhpcy0+Zm9ybWF0dGVyLT5nZXRTcGFjZXNBcm91bmRPcGVyYXRvcigpID8gIiAiIDogIiIsCiAgICAgICAgICAgICJzaXJiIiA9PiAkdGhpcy0+Zm9ybWF0dGVyLT5nZXRTcGFjZXNJbnNpZGVSb3VuZEJyYWNrZXRzKCkgPyAiICIgOiAiIiwKICAgICAgICAgICAgImF3YiIgPT4gJHRoaXMtPmZvcm1hdHRlci0+Z2V0QWx3YXlzV3JhcEJsb2NrcygpCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZm9ybWF0dGVyIHRvIHVzZSBmb3IgdGhlIHJlbmRlcmluZwogICAgICogCiAgICAgKiBAcmV0dXJuIEZvcm1hdHRlclxCYXNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGb3JtYXR0ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Zm9ybWF0dGVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlbmRlcnMgdGhlIGdpdmVuIG5vZGUKICAgICAqIAogICAgICogQHBhcmFtIFN5bnRheFxOb2RlXE5vZGUgICRub2RlICAgTm9kZSB0byByZW5kZXIKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIAogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcihTeW50YXhcTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgIC8vVGhyb3cgZXhjZXB0aW9uIGlmIG5vIGZvcm1hdHRlciBoYXMgYmVlbiBzcGVjaWZpZWQKICAgICAgICBpZiAoISR0aGlzLT5mb3JtYXR0ZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkZvcm1hdHRlciBub3Qgc2V0Iik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vUmVzZXQgaW5kZW50YXRpb24gbGV2ZWwKICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+aW5kTGV2ZWwgPSAwOwogICAgICAgIAogICAgICAgIC8vU3RhcnQgcmVuZGVyaW5nCiAgICAgICAgcmV0dXJuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZW5kZXJzIGEgbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlIHRvIHJlbmRlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcmVuZGVyTm9kZShTeW50YXhcTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgICRjb2RlID0gIiI7CiAgICAgICAgJHR5cGUgPSAkbm9kZS0+Z2V0VHlwZSgpOwogICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAiQXJyYXlFeHByZXNzaW9uIjoKICAgICAgICAgICAgY2FzZSAiQXJyYXlQYXR0ZXJuIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJbIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldEVsZW1lbnRzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICJdIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkFycm93RnVuY3Rpb25FeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0QXN5bmMoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJhc3luYyIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5qb2luTm9kZXMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0UGFyYW1zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICI9PiI7CiAgICAgICAgICAgICAgICAkYm9keSA9ICRub2RlLT5nZXRCb2R5KCk7CiAgICAgICAgICAgICAgICBpZiAoJGJvZHktPmdldFR5cGUoKSAhPT0gIkJsb2NrU3RhdGVtZW50IikgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLiAkdGhpcy0+cmVuZGVyTm9kZSgkYm9keSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygkYm9keSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJBd2FpdEV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImF3YWl0ICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0QXJndW1lbnQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJBc3NpZ25tZW50RXhwcmVzc2lvbiI6CiAgICAgICAgICAgIGNhc2UgIkFzc2lnbm1lbnRQYXR0ZXJuIjoKICAgICAgICAgICAgY2FzZSAiQmluYXJ5RXhwcmVzc2lvbiI6CiAgICAgICAgICAgIGNhc2UgIkxvZ2ljYWxFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRvcGVyYXRvciA9ICR0eXBlID09PSAiQXNzaWdubWVudFBhdHRlcm4iID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICI9IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0T3BlcmF0b3IoKTsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMZWZ0KCkpOwogICAgICAgICAgICAgICAgJGNvZGVSaWdodCA9ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRSaWdodCgpKTsKICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCIjXlthLXpdKyQjaSIsICRvcGVyYXRvcikpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICIgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICRvcGVyYXRvciAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAiOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvL0lmIHRoZXJlJ3Mgbm8gc3BhY2UgYXJvdW5kIHRoZSBvcGVyYXRvciwgYWRkaXRpb25hbCBjaGVja3MgbXVzdAogICAgICAgICAgICAgICAgICAgIC8vYmUgcGVyZm9ybWVkIHRvIHByZXZlbnQgZXJyb3JzIHdoZW4gcmVuZGVyaW5nIHVuYXJ5IGFuZCB1cGRhdGUKICAgICAgICAgICAgICAgICAgICAvL2V4cHJlc3Npb25zIGluc2lkZSBiaW5hcnkgZXhwcmVzc2lvbnMKICAgICAgICAgICAgICAgICAgICAkY2hlY2tTcGFjZSA9ICEkdGhpcy0+cmVuZGVyT3B0cy0+c2FvICYmICR0eXBlID09PSAiQmluYXJ5RXhwcmVzc2lvbiI7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy9UaGUgc3BhY2UgaXMgbWFuZGF0b3J5IGlmIHRoZSBsZWZ0IHBhcnQgZW5kcyB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgICAgICAgICAgLy9jaGFyYWN0ZXIgdXNlZCBhcyBvcGVyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICgkY2hlY2tTcGFjZSAmJiAkY29kZSAmJiBzdWJzdHIoJGNvZGUsIC0xKSA9PT0gJG9wZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG9wZXJhdG9yIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vVGhlIHNwYWNlIGlzIG1hbmRhdG9yeSBpZiB0aGUgcmlnaHQgcGFydCBiZWdpbnMgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICAgICAgICAgIC8vY2hhcmFjdGVyIHVzZWQgYXMgb3BlcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoJGNoZWNrU3BhY2UgJiYgJGNvZGVSaWdodCAmJiAkY29kZVJpZ2h0WzBdID09PSAkb3BlcmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICRjb2RlUmlnaHQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJCbG9ja1N0YXRlbWVudCI6CiAgICAgICAgICAgIGNhc2UgIkNsYXNzQm9keSI6CiAgICAgICAgICAgIGNhc2UgIlByb2dyYW0iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKAogICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRCb2R5KCksIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgZmFsc2UKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJCcmVha1N0YXRlbWVudCI6CiAgICAgICAgICAgIGNhc2UgIkNvbnRpbnVlU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0eXBlID09PSAiQnJlYWtTdGF0ZW1lbnQiID8gImJyZWFrIiA6ICJjb250aW51ZSI7CiAgICAgICAgICAgICAgICBpZiAoJGxhYmVsID0gJG5vZGUtPmdldExhYmVsKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbGFiZWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiQ2FsbEV4cHJlc3Npb24iOgogICAgICAgICAgICBjYXNlICJOZXdFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PT0gIk5ld0V4cHJlc3Npb24iKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIm5ldyAiOwogICAgICAgICAgICAgICAgICAgICRvcHRpb25hbCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkb3B0aW9uYWwgPSAkbm9kZS0+Z2V0T3B0aW9uYWwoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRDYWxsZWUoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgKCRvcHRpb25hbCA/ICI/LiIgOiAiIikgLgogICAgICAgICAgICAgICAgICAgICAgICAgIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5qb2luTm9kZXMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0QXJndW1lbnRzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkNhdGNoQ2xhdXNlIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJjYXRjaCI7CiAgICAgICAgICAgICAgICBpZiAoJHBhcmFtcyA9ICRub2RlLT5nZXRQYXJhbSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJHBhcmFtcykgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSwgdHJ1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJDaGFpbkV4cHJlc3Npb24iOgogICAgICAgICAgICBjYXNlICJFeHByZXNzaW9uU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRFeHByZXNzaW9uKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiQ2xhc3NFeHByZXNzaW9uIjoKICAgICAgICAgICAgY2FzZSAiQ2xhc3NEZWNsYXJhdGlvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiY2xhc3MiOwogICAgICAgICAgICAgICAgaWYgKCRpZCA9ICRub2RlLT5nZXRJZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkc3VwZXJDbGFzcyA9ICRub2RlLT5nZXRTdXBlckNsYXNzKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiIGV4dGVuZHMgIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRzdXBlckNsYXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0Qm9keSgpLCB0cnVlLCBmYWxzZSwgZmFsc2UKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJDb25kaXRpb25hbEV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFRlc3QoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiPyIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0Q29uc2VxdWVudCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICI6IiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRBbHRlcm5hdGUoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJEZWJ1Z2dlclN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiZGVidWdnZXIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiRG9XaGlsZVN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiZG8iIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRCb2R5KCksIG51bGwsIHRydWUKICAgICAgICAgICAgICAgICAgICAgICAgICkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAid2hpbGUiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgIigiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRUZXN0KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWEVtcHR5RXhwcmVzc2lvbiI6CiAgICAgICAgICAgIGNhc2UgIkVtcHR5U3RhdGVtZW50IjoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkV4cG9ydEFsbERlY2xhcmF0aW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJleHBvcnQgKiI7CiAgICAgICAgICAgICAgICAkZXhwb3J0ZWQgPSAkbm9kZS0+Z2V0RXhwb3J0ZWQoKTsKICAgICAgICAgICAgICAgIGlmICgkZXhwb3J0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiIGFzICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkZXhwb3J0ZWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIiBmcm9tICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0U291cmNlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uIjoKICAgICAgICAgICAgICAgICRkZWNsYXJhdGlvbiA9ICRub2RlLT5nZXREZWNsYXJhdGlvbigpOwogICAgICAgICAgICAgICAgJGNvZGUgLj0gImV4cG9ydCBkZWZhdWx0ICIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJGRlY2xhcmF0aW9uKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cmVxdWlyZXNTZW1pY29sb24oJGRlY2xhcmF0aW9uKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkV4cG9ydE5hbWVkRGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImV4cG9ydCI7CiAgICAgICAgICAgICAgICBpZiAoJGRlYyA9ICRub2RlLT5nZXREZWNsYXJhdGlvbigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkZGVjKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInsiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0U3BlY2lmaWVycygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn0iOwogICAgICAgICAgICAgICAgICAgIGlmICgkc291cmNlID0gJG5vZGUtPmdldFNvdXJjZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZnJvbSAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiRXhwb3J0U3BlY2lmaWVyIjoKICAgICAgICAgICAgICAgICRsb2NhbCA9ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMb2NhbCgpKTsKICAgICAgICAgICAgICAgICRyZWYgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0RXhwb3J0ZWQoKSk7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbG9jYWwgPT09ICRyZWYgPwogICAgICAgICAgICAgICAgICAgICAgICAgJGxvY2FsIDoKICAgICAgICAgICAgICAgICAgICAgICAgICRsb2NhbCAuICIgYXMgIiAuICRyZWY7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJGb3JJblN0YXRlbWVudCI6CiAgICAgICAgICAgIGNhc2UgIkZvck9mU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgIC8vRm9yY2Ugc2luZ2xlIGxpbmUgbW9kZSBmb3Igc3Vic3RhdGVtZW50cwogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSA9IHRydWU7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiZm9yIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAoJHR5cGUgPT09ICJGb3JPZlN0YXRlbWVudCIgJiYgJG5vZGUtPmdldEF3YWl0KCkgPyAiIGF3YWl0IiA6ICIiKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TGVmdCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiICIgLiAoJHR5cGUgPT09ICJGb3JJblN0YXRlbWVudCIgPyAiaW4iIDogIm9mIikgLiAiICIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFJpZ2h0KCkpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cmVuZGVyT3B0cy0+Zm9yY2VTaW5nbGVMaW5lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkZvclN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAvL0ZvcmNlIHNpbmdsZSBsaW5lIG1vZGUgZm9yIHN1YnN0YXRlbWVudHMKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5mb3JjZVNpbmdsZUxpbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgJGNvZGUgLj0gImZvciIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmI7CiAgICAgICAgICAgICAgICBpZiAoJGluaXQgPSAkbm9kZS0+Z2V0SW5pdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJGluaXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIjsiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbzsKICAgICAgICAgICAgICAgIGlmICgkdGVzdCA9ICRub2RlLT5nZXRUZXN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkdGVzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiOyIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgaWYgKCR1cGRhdGUgPSAkbm9kZS0+Z2V0VXBkYXRlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkdXBkYXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zaXJiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIpIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJvZHkoKSk7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+cmVuZGVyT3B0cy0+Zm9yY2VTaW5nbGVMaW5lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkZ1bmN0aW9uRGVjbGFyYXRpb24iOgogICAgICAgICAgICBjYXNlICJGdW5jdGlvbkV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGlkID0gJG5vZGUtPmdldElkKCk7CiAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldEFzeW5jKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiYXN5bmMgIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICJmdW5jdGlvbiI7CiAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldEdlbmVyYXRvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIioiOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRpZCkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIgIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkaWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldEdlbmVyYXRvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRpZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldFBhcmFtcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbwogICAgICAgICAgICAgICAgICAgICAgICAgKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKCRub2RlLT5nZXRCb2R5KCksIHRydWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSW1wb3J0RXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiaW1wb3J0KCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFNvdXJjZSgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hJZGVudGlmaWVyIjoKICAgICAgICAgICAgY2FzZSAiSWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbm9kZS0+Z2V0TmFtZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSWZTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImlmIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0VGVzdCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgICAgICAkY29uc2VxdWVudCA9ICRub2RlLT5nZXRDb25zZXF1ZW50KCk7CiAgICAgICAgICAgICAgICAkYWx0ZXJuYXRlID0gJG5vZGUtPmdldEFsdGVybmF0ZSgpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkZm9yY2VCcmFja2V0c0NvbnNlcXVlbnQgPSAkZm9yY2VCcmFja2V0c0FsdGVybmF0ZSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5yZW5kZXJPcHRzLT5hd2IgJiYgJGFsdGVybmF0ZSkgewogICAgICAgICAgICAgICAgICAgICRmb3JjZUJyYWNrZXRzQ29uc2VxdWVudCA9ICR0aGlzLT5jaGVja0lmUGFydHNCcmFja2V0c1JlcXVpcmVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAkY29uc2VxdWVudAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJGZvcmNlQnJhY2tldHNBbHRlcm5hdGUgPSAkdGhpcy0+Y2hlY2tJZlBhcnRzQnJhY2tldHNSZXF1aXJlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0ZQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygKICAgICAgICAgICAgICAgICAgICAkY29uc2VxdWVudCwgJGZvcmNlQnJhY2tldHNDb25zZXF1ZW50CiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCRhbHRlcm5hdGUpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZWxzZSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJTdGF0ZW1lbnRCbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZvcmNlQnJhY2tldHNBbHRlcm5hdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSW1wb3J0RGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImltcG9ydCAiOwogICAgICAgICAgICAgICAgJHNwZWNpZmllcnMgPSAkbm9kZS0+Z2V0U3BlY2lmaWVycygpOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRzcGVjaWZpZXJzKSkgewogICAgICAgICAgICAgICAgICAgICRzZXAgPSAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvOwogICAgICAgICAgICAgICAgICAgICRncm91cHMgPSAkcGFydHMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRzcGVjaWZpZXJzIGFzICRzcGVjKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzcGVjVHlwZSA9ICRzcGVjLT5nZXRUeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJGdyb3Vwc1skc3BlY1R5cGVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGdyb3Vwc1skc3BlY1R5cGVdID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkZ3JvdXBzWyRzcGVjVHlwZV1bXSA9ICRzcGVjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGdyb3Vwc1siSW1wb3J0RGVmYXVsdFNwZWNpZmllciJdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZ3JvdXBzWyJJbXBvcnREZWZhdWx0U3BlY2lmaWVyIl0gYXMgJHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJHRoaXMtPnJlbmRlck5vZGUoJHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZ3JvdXBzWyJJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIiXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJGdyb3Vwc1siSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyIl0gYXMgJHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJHRoaXMtPnJlbmRlck5vZGUoJHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZ3JvdXBzWyJJbXBvcnRTcGVjaWZpZXIiXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGltcFNwZWMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkZ3JvdXBzWyJJbXBvcnRTcGVjaWZpZXIiXSBhcyAkcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGltcFNwZWNbXSA9ICR0aGlzLT5yZW5kZXJOb2RlKCRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkcGFydHNbXSA9ICJ7IiAuIGltcGxvZGUoJHNlcCwgJGltcFNwZWMpIC4gIn0iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSBpbXBsb2RlKCRzZXAsICRwYXJ0cykgLiAiIGZyb20gIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRTb3VyY2UoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJJbXBvcnREZWZhdWx0U3BlY2lmaWVyIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMb2NhbCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkltcG9ydE5hbWVzcGFjZVNwZWNpZmllciI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiKiBhcyAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldExvY2FsKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSW1wb3J0U3BlY2lmaWVyIjoKICAgICAgICAgICAgICAgICRsb2NhbCA9ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMb2NhbCgpKTsKICAgICAgICAgICAgICAgICRyZWYgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0SW1wb3J0ZWQoKSk7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbG9jYWwgPT09ICRyZWYgPwogICAgICAgICAgICAgICAgICAgICAgICAgJGxvY2FsIDoKICAgICAgICAgICAgICAgICAgICAgICAgICRyZWYgLiAiIGFzICIgLiAkbG9jYWw7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hBdHRyaWJ1dGUiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICBpZiAoJHZhbHVlID0gJG5vZGUtPmdldFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiPSIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYQ2xvc2luZ0VsZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gIjwvIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXROYW1lKCkpIC4gIj4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYQ2xvc2luZ0ZyYWdtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICI8Lz4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYRWxlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0T3BlbmluZ0VsZW1lbnQoKSkgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2Rlcygkbm9kZS0+Z2V0Q2hpbGRyZW4oKSwgIiIpOwogICAgICAgICAgICAgICAgaWYgKCRjbG9zaW5nID0gJG5vZGUtPmdldENsb3NpbmdFbGVtZW50KCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkY2xvc2luZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hFeHByZXNzaW9uQ29udGFpbmVyIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ7IiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRFeHByZXNzaW9uKCkpIC4gIn0iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYRnJhZ21lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE9wZW5pbmdGcmFnbWVudCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKCRub2RlLT5nZXRDaGlsZHJlbigpLCAiIikgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldENsb3NpbmdGcmFnbWVudCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIkpTWE5hbWVzcGFjZWROYW1lIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXROYW1lc3BhY2UoKSkgLiAiOiIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE5hbWUoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hPcGVuaW5nRWxlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiPCIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgICRhdHRyaWJ1dGVzID0gJG5vZGUtPmdldEF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgICAgIGlmIChjb3VudCgkYXR0cmlidXRlcykpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICIgLiAkdGhpcy0+am9pbk5vZGVzKCRhdHRyaWJ1dGVzLCAiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRTZWxmQ2xvc2luZygpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIi8iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gIj4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYT3BlbmluZ0ZyYWdtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICI8PiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJKU1hTcHJlYWRBdHRyaWJ1dGUiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInsuLi4iIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEFyZ3VtZW50KCkpIC4gIn0iOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYU3ByZWFkQ2hpbGQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInsuLi4iIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEV4cHJlc3Npb24oKSkgLiAifSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJMYWJlbGVkU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRib2R5ID0gJG5vZGUtPmdldEJvZHkoKTsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRMYWJlbCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiOiIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5nZXRJbmRlbnRhdGlvbigpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRib2R5KTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cmVxdWlyZXNTZW1pY29sb24oJGJvZHkpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIjsiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYVGV4dCI6CiAgICAgICAgICAgIGNhc2UgIkxpdGVyYWwiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldFJhdygpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSlNYTWVtYmVyRXhwcmVzc2lvbiI6CiAgICAgICAgICAgIGNhc2UgIk1lbWJlckV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJHByb3BlcnR5ID0gJG5vZGUtPmdldFByb3BlcnR5KCk7CiAgICAgICAgICAgICAgICAkY29tcGlsZWRQcm9wZXJ0eSA9ICR0aGlzLT5yZW5kZXJOb2RlKCRwcm9wZXJ0eSk7CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0T2JqZWN0KCkpOwogICAgICAgICAgICAgICAgJG9wdGlvbmFsID0gZmFsc2U7CiAgICAgICAgICAgICAgICBpZiAoJHR5cGUgPT09ICJNZW1iZXJFeHByZXNzaW9uIikgewogICAgICAgICAgICAgICAgICAgICRvcHRpb25hbCA9ICRub2RlLT5nZXRPcHRpb25hbCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0eXBlID09PSAiTWVtYmVyRXhwcmVzc2lvbiIgJiYKICAgICAgICAgICAgICAgICAgICAoJG5vZGUtPmdldENvbXB1dGVkKCkgfHwgJHByb3BlcnR5LT5nZXRUeXBlKCkgIT09ICJJZGVudGlmaWVyIikpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAoJG9wdGlvbmFsID8gIj8uIiA6ICIiKSAuICJbIiAuICRjb21waWxlZFByb3BlcnR5IC4gIl0iOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAoJG9wdGlvbmFsID8gIj8uIiA6ICIuIikgLiAkY29tcGlsZWRQcm9wZXJ0eTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIk1ldGFQcm9wZXJ0eSI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkbm9kZS0+Z2V0TWV0YSgpIC4gIi4iIC4gJG5vZGUtPmdldFByb3BlcnR5KCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJNZXRob2REZWZpbml0aW9uIjoKICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0U3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAic3RhdGljICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkbm9kZS0+Z2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICRrZXkgPSAkbm9kZS0+Z2V0S2V5KCk7CiAgICAgICAgICAgICAgICAka2luZCA9ICRub2RlLT5nZXRLaW5kKCk7CiAgICAgICAgICAgICAgICBpZiAoJGtpbmQgPT09ICRub2RlOjpLSU5EX0dFVCB8fCAka2luZCA9PT0gJG5vZGU6OktJTkRfU0VUKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJGtpbmQgLiAiICI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICgkdmFsdWUtPmdldEFzeW5jKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gImFzeW5jICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkdmFsdWUtPmdldEdlbmVyYXRvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIqIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRDb21wdXRlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIlsiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgka2V5KSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl0iOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyTm9kZSgka2V5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgcHJlZ19yZXBsYWNlKCIvXlteXChdKy8iLCAiIiwgJHRoaXMtPnJlbmRlck5vZGUoJHZhbHVlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJPYmplY3RFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjdXJyZW50SW5kZW50YXRpb24gPSAkdGhpcy0+Z2V0SW5kZW50YXRpb24oKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbCsrOwogICAgICAgICAgICAgICAgJGluZGVudGF0aW9uID0gJHRoaXMtPmdldEluZGVudGF0aW9uKCk7CiAgICAgICAgICAgICAgICAvL0hhbmRsZSBzaW5nbGUgbGluZSBtb2RlCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSkpIHsKICAgICAgICAgICAgICAgICAgICAkc3RhcnQgPSAkZW5kID0gIiI7CiAgICAgICAgICAgICAgICAgICAgJHNlcGFyYXRvciA9ICIsIiAuICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRlbmQgPSAkdGhpcy0+cmVuZGVyT3B0cy0+bmwgLiAkY3VycmVudEluZGVudGF0aW9uOwogICAgICAgICAgICAgICAgICAgICRzdGFydCA9ICR0aGlzLT5yZW5kZXJPcHRzLT5ubCAuICRpbmRlbnRhdGlvbjsKICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yID0gIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4gJGluZGVudGF0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gInsiOwogICAgICAgICAgICAgICAgJHByb3BlcnRpZXMgPSAkbm9kZS0+Z2V0UHJvcGVydGllcygpOwogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRwcm9wZXJ0aWVzKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICRzdGFydCAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvcGVydGllcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICJ9IjsKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbC0tOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiT2JqZWN0UGF0dGVybiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAieyIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmpvaW5Ob2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRQcm9wZXJ0aWVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApIC4KICAgICAgICAgICAgICAgICAgICAgICAgICJ9IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0RXhwcmVzc2lvbigpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJQcm9wZXJ0eSI6CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkbm9kZS0+Z2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICRrZXkgPSAkbm9kZS0+Z2V0S2V5KCk7CiAgICAgICAgICAgICAgICAkY29tcGlsZWRLZXkgPSAkdGhpcy0+cmVuZGVyTm9kZSgka2V5KTsKICAgICAgICAgICAgICAgICRjb21waWxlZFZhbHVlID0gJHRoaXMtPnJlbmRlck5vZGUoJHZhbHVlKTsKICAgICAgICAgICAgICAgICRrZXlUeXBlID0gJGtleS0+Z2V0VHlwZSgpOwogICAgICAgICAgICAgICAgJHZhbHVlVHlwZSA9ICR2YWx1ZS0+Z2V0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKCR2YWx1ZVR5cGUgPT09ICJBc3NpZ25tZW50UGF0dGVybiIgJiYKICAgICAgICAgICAgICAgICAgICAkY29tcGlsZWRLZXkgPT09ICR0aGlzLT5yZW5kZXJOb2RlKCR2YWx1ZS0+Z2V0TGVmdCgpKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICRjb21waWxlZFZhbHVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAka2luZCA9ICRub2RlLT5nZXRLaW5kKCk7CiAgICAgICAgICAgICAgICAgICAgJGdldHRlclNldHRlciA9ICRraW5kID09PSAkbm9kZTo6S0lORF9HRVQgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGtpbmQgPT09ICRub2RlOjpLSU5EX1NFVDsKICAgICAgICAgICAgICAgICAgICBpZiAoJGdldHRlclNldHRlcikgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAka2luZCAuICIgIjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHZhbHVlLT5nZXRUeXBlKCkgPT09ICJGdW5jdGlvbkV4cHJlc3Npb24iICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWx1ZS0+Z2V0R2VuZXJhdG9yKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIioiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRDb21wdXRlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJbIiAuICRjb21waWxlZEtleSAuICJdIjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkY29tcGlsZWRLZXk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkbm9kZS0+Z2V0TWV0aG9kKCkgfHwgJGdldHRlclNldHRlcikgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZ19yZXBsYWNlKCIvXlteXChdKy8iLCAiIiwgJGNvbXBpbGVkVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgka2V5VHlwZSAhPT0gIklkZW50aWZpZXIiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2YWx1ZVR5cGUgIT09ICJJZGVudGlmaWVyIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29tcGlsZWRLZXkgIT09ICRjb21waWxlZFZhbHVlCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICgkbm9kZS0+Z2V0U2hvcnRoYW5kKCkgPyAiPSIgOiAiOiIpIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21waWxlZFZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlJlZ0V4cExpdGVyYWwiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldFJhdygpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiUmVzdEVsZW1lbnQiOgogICAgICAgICAgICBjYXNlICJTcHJlYWRFbGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICIuLi4iIC4gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEFyZ3VtZW50KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiUmV0dXJuU3RhdGVtZW50IjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJyZXR1cm4iOwogICAgICAgICAgICAgICAgaWYgKCRhcmd1bWVudCA9ICRub2RlLT5nZXRBcmd1bWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlNlcXVlbmNlRXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPmdldEV4cHJlc3Npb25zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvCiAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiU3VwZXIiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInN1cGVyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlN3aXRjaENhc2UiOgogICAgICAgICAgICAgICAgaWYgKCR0ZXN0ID0gJG5vZGUtPmdldFRlc3QoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJjYXNlICIgLiAkdGhpcy0+cmVuZGVyTm9kZSgkdGVzdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICJkZWZhdWx0IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICI6IjsKICAgICAgICAgICAgICAgIGlmIChjb3VudCgkbm9kZS0+Z2V0Q29uc2VxdWVudCgpKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5ubCAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0Q29uc2VxdWVudCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJTd2l0Y2hTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gInN3aXRjaCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldERpc2NyaW1pbmFudCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5nZXRDYXNlcygpLCB0cnVlLCBmYWxzZSwgZmFsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldFRhZygpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0UXVhc2koKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJUZW1wbGF0ZUVsZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldFJhd1ZhbHVlKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJUZW1wbGF0ZUxpdGVyYWwiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gImAiOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG5vZGUtPmdldFBhcnRzKCkgYXMgJHBhcnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJHBhcnQtPmdldFR5cGUoKSA9PT0gIlRlbXBsYXRlRWxlbWVudCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJHBhcnQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICIkIiAuICJ7IiAuICR0aGlzLT5yZW5kZXJOb2RlKCRwYXJ0KSAuICJ9IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29kZSAuPSAiYCI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJUaGlzRXhwcmVzc2lvbiI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAidGhpcyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJUaHJvd1N0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAidGhyb3cgIiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlLT5nZXRBcmd1bWVudCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIlRyeVN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAidHJ5IiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJG5vZGUtPmdldEJsb2NrKCksIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKCRoYW5kbGVyID0gJG5vZGUtPmdldEhhbmRsZXIoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJOb2RlKCRoYW5kbGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkZmluYWxpemVyID0gJG5vZGUtPmdldEZpbmFsaXplcigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpbmFsbHkiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyU3RhdGVtZW50QmxvY2soJGZpbmFsaXplciwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJVbmFyeUV4cHJlc3Npb24iOgogICAgICAgICAgICBjYXNlICJVcGRhdGVFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRwcmVmaXggPSAkbm9kZS0+Z2V0UHJlZml4KCk7CiAgICAgICAgICAgICAgICBpZiAoJHByZWZpeCkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICRub2RlLT5nZXRPcGVyYXRvcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChwcmVnX21hdGNoKCIjXlthLXpdKyQjaSIsICRub2RlLT5nZXRPcGVyYXRvcigpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldEFyZ3VtZW50KCkpOwogICAgICAgICAgICAgICAgaWYgKCEkcHJlZml4KSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gJG5vZGUtPmdldE9wZXJhdG9yKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJWYXJpYWJsZURlY2xhcmF0aW9uIjoKICAgICAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbCsrOwogICAgICAgICAgICAgICAgJGluZGVudGF0aW9uID0gJHRoaXMtPmdldEluZGVudGF0aW9uKCk7CiAgICAgICAgICAgICAgICAvL0hhbmRsZSBzaW5nbGUgbGluZSBtb2RlCiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPnJlbmRlck9wdHMtPmZvcmNlU2luZ2xlTGluZSkpIHsKICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yID0gIiwiIC4gJHRoaXMtPnJlbmRlck9wdHMtPnNhbzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHNlcGFyYXRvciA9ICIsIiAuICR0aGlzLT5yZW5kZXJPcHRzLT5ubCAuICRpbmRlbnRhdGlvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjb2RlIC49ICRub2RlLT5nZXRLaW5kKCkgLgogICAgICAgICAgICAgICAgICAgICAgICAgIiAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5qb2luTm9kZXMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+Z2V0RGVjbGFyYXRpb25zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPmluZExldmVsLS07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJWYXJpYWJsZURlY2xhcmF0b3IiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldElkKCkpOwogICAgICAgICAgICAgICAgaWYgKCRpbml0ID0gJG5vZGUtPmdldEluaXQoKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW8gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI9IiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJGluaXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiV2hpbGVTdGF0ZW1lbnQiOgogICAgICAgICAgICAgICAgJGNvZGUgLj0gIndoaWxlIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2FvIC4KICAgICAgICAgICAgICAgICAgICAgICAgICIoIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZS0+Z2V0VGVzdCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKCRub2RlLT5nZXRCb2R5KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiV2l0aFN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICAkY29kZSAuPSAid2l0aCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNhbyAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPnNpcmIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlck5vZGUoJG5vZGUtPmdldE9iamVjdCgpKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+c2lyYiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgLgogICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnJlbmRlclN0YXRlbWVudEJsb2NrKCRub2RlLT5nZXRCb2R5KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiWWllbGRFeHByZXNzaW9uIjoKICAgICAgICAgICAgICAgICRjb2RlIC49ICJ5aWVsZCI7CiAgICAgICAgICAgICAgICBpZiAoJG5vZGUtPmdldERlbGVnYXRlKCkpIHsKICAgICAgICAgICAgICAgICAgICAkY29kZSAuPSAiICoiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRhcmd1bWVudCA9ICRub2RlLT5nZXRBcmd1bWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGNvZGUgLj0gIiAiIC4gJHRoaXMtPnJlbmRlck5vZGUoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkY29kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZW5kZXJzIGEgbm9kZSBhcyBhIGJsb2NrIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZXxhcnJheSAgICAkbm9kZSAgICAgICAgICAgICAgIE5vZGUgb3IgYXJyYXkgb2YgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzIHRvIHJlbmRlcgogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAgICAgICAgICAgICAgJGZvcmNlQnJhY2tldHMgICAgICBPdmVycmlkZXMgYnJhY2tldHMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0aW5nIHJ1bGVzCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkbWFuZGF0b3J5U2VwYXJhdG9yIFRydWUgaWYgYSBzdGFydGluZwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IgaXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5CiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAgICAgICAgICAgICAgICAkYWRkU2VtaWNvbG9ucyAgICAgIFNlbWljb2xvbnMgYXJlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydGVkIGF1dG1hdGljYWxseQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0aGlzIHBhcmFtZXRlciBpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3QgZmFsc2UKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICAgICAgICAgICAgICRpbmNJbmRlbnQgICAgICAgICAgSWYgZmFsc2UgaW5kZW50YXRpb24KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwgd29uJ3QgYmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVtZW50ZWQKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHJlbmRlclN0YXRlbWVudEJsb2NrKAogICAgICAgICRub2RlLCAkZm9yY2VCcmFja2V0cyA9IG51bGwsICRtYW5kYXRvcnlTZXBhcmF0b3IgPSBmYWxzZSwKICAgICAgICAkYWRkU2VtaWNvbG9ucyA9IHRydWUsICRpbmNJbmRlbnQgPSB0cnVlCiAgICApIHsKICAgICAgICAkY29kZSA9ICIiOwogICAgICAgIAogICAgICAgIC8vU3BlY2lhbCBoYW5kbGluZyBvZiBCbG9ja1N0YXRlbWVudCBhbmQgQ2xhc3NCb2R5IG5vZGVzIGJ5IHJlbmRlcmluZwogICAgICAgIC8vdGhlaXIgY2hpbGQgbm9kZXMKICAgICAgICBpZiAoIWlzX2FycmF5KCRub2RlKSAmJgogICAgICAgICAgICBpbl9hcnJheSgkbm9kZS0+Z2V0VHlwZSgpLCBhcnJheSgiQmxvY2tTdGF0ZW1lbnQiLCAiQ2xhc3NCb2R5IikpKSB7CiAgICAgICAgICAgICRub2RlID0gJG5vZGUtPmdldEJvZHkoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JZiAkZm9yY2VCcmFja2V0cyBpcyBub3QgbnVsbCB1c2UgaXRzIHZhbHVlIHRvIG92ZXJyaWRlIGN1cmx5IGJyYWNrZXRzCiAgICAgICAgLy9pbnNlcnRpb24gcnVsZXMKICAgICAgICBpZiAoJGZvcmNlQnJhY2tldHMgIT09IG51bGwpIHsKICAgICAgICAgICAgJGhhc0JyYWNrZXRzID0gJGZvcmNlQnJhY2tldHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9JbnNlcnQgY3VybHkgYnJhY2tldHMgaWYgcmVxdWlyZWQgYnkgdGhlIGZvcm1hdHRlciBvciBpZiB0aGUKICAgICAgICAgICAgLy9udW1iZXIgb2Ygbm9kZXMgdG8gcmVuZGVyIGlzIGRpZmZlcmVudCBmcm9tIG9uZQogICAgICAgICAgICAkaGFzQnJhY2tldHMgPSAkdGhpcy0+cmVuZGVyT3B0cy0+YXdiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIChpc19hcnJheSgkbm9kZSkgJiYgY291bnQoJG5vZGUpICE9PSAxKTsKICAgICAgICB9CiAgICAgICAgJGN1cnJlbnRJbmRlbnRhdGlvbiA9ICR0aGlzLT5nZXRJbmRlbnRhdGlvbigpOwogICAgICAgIAogICAgICAgIC8vSWYgJGZvcmNlQnJhY2tldHMgaXMgbm90IHNldCB0byBmYWxzZSB0aGVuIHRoZSBub2RlIGNhbiBiZSB3cmFwcGVkIGluCiAgICAgICAgLy9jdXJseSBicmFjZXMsIHNvIGEgc2VwYXJhdG9yIGRlZmluZWQgYnkgZm9ybWF0dGVyIG11c3QgYmUgaW5zZXJ0ZWQKICAgICAgICBpZiAoJGZvcmNlQnJhY2tldHMgIT09IGZhbHNlKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVuZGVyT3B0cy0+bmxiYykgewogICAgICAgICAgICAgICAgJGNvZGUgLj0gJHRoaXMtPnJlbmRlck9wdHMtPm5sIC4gJGN1cnJlbnRJbmRlbnRhdGlvbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5zYW87CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JbnNlcnQgb3BlbiBjdXJseSBicmFja2V0IGlmIHJlcXVpcmVkCiAgICAgICAgaWYgKCRoYXNCcmFja2V0cykgewogICAgICAgICAgICAkY29kZSAuPSAieyIgLiAkdGhpcy0+cmVuZGVyT3B0cy0+bmw7CiAgICAgICAgfSBlbHNlaWYgKCRtYW5kYXRvcnlTZXBhcmF0b3IpIHsKICAgICAgICAgICAgLy9JZiBicmFja2V0IGlzIG5vdCBpbnNlcnRlZCBidXQgYSBzZXBhcmF0b3IgaXMgc3RpbGwgcmVxdWlyZWQKICAgICAgICAgICAgLy9hIHNwYWNlIGlzIGFkZGVkCiAgICAgICAgICAgICRjb2RlIC49ICIgIjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JbmNyZWFzZSBpbmRlbnRhdGlvbiBsZXZlbAogICAgICAgIGlmICgkaW5jSW5kZW50KSB7CiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbCsrOwogICAgICAgIH0KICAgICAgICAkc3ViSW5kZW50YXRpb24gPSAkdGhpcy0+Z2V0SW5kZW50YXRpb24oKTsKICAgICAgICAKICAgICAgICAvL1JlbmRlciB0aGUgbm9kZSBvciB0aGUgYXJyYXkgb2Ygbm9kZXMKICAgICAgICAkZW1wdHlCb2R5ID0gaXNfYXJyYXkoJG5vZGUpICYmICFjb3VudCgkbm9kZSk7CiAgICAgICAgaWYgKGlzX2FycmF5KCRub2RlKSkgewogICAgICAgICAgICBpZiAoISRlbXB0eUJvZHkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICRzdWJJbmRlbnRhdGlvbiAuCiAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+am9pbk5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cmVuZGVyT3B0cy0+bmwgLiAkc3ViSW5kZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYWRkU2VtaWNvbG9ucwogICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb2RlIC49ICRzdWJJbmRlbnRhdGlvbiAuICR0aGlzLT5yZW5kZXJOb2RlKCRub2RlKTsKICAgICAgICAgICAgaWYgKCRhZGRTZW1pY29sb25zICYmICR0aGlzLT5yZXF1aXJlc1NlbWljb2xvbigkbm9kZSkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1Jlc2V0IHRoZSBpbmRlbnRhdGlvbiBsZXZlbAogICAgICAgIGlmICgkaW5jSW5kZW50KSB7CiAgICAgICAgICAgICR0aGlzLT5yZW5kZXJPcHRzLT5pbmRMZXZlbC0tOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0luc2VydCBjbG9zaW5nIGN1cmx5IGJyYWNrZXQgaWYgcmVxdWlyZWQKICAgICAgICBpZiAoJGhhc0JyYWNrZXRzKSB7CiAgICAgICAgICAgIC8vQWRkIGEgbmV3IGxpbmUgaWYgc29tZXRoaW5nIHdhcyByZW5kZXJlZAogICAgICAgICAgICBpZiAoISRlbXB0eUJvZHkpIHsKICAgICAgICAgICAgICAgICRjb2RlIC49ICR0aGlzLT5yZW5kZXJPcHRzLT5ubDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkY29kZSAuPSAkY3VycmVudEluZGVudGF0aW9uIC4gIn0iOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJGNvZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSm9pbnMgYW4gYXJyYXkgb2Ygbm9kZXMgd2l0aCB0aGUgZ2l2ZW4gc2VwYXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJG5vZGVzICAgICAgICAgIE5vZGVzCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICRzZXBhcmF0b3IgICAgICBTZXBhcmF0b3IKICAgICAqIEBwYXJhbSBib29sICAgICAgJGFkZFNlbWljb2xvbnMgIFRydWUgdG8gYWRkIHNlbWljb2xvbnMgYWZ0ZXIgZWFjaCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBqb2luTm9kZXMoJG5vZGVzLCAkc2VwYXJhdG9yLCAkYWRkU2VtaWNvbG9ucz1mYWxzZSkKICAgIHsKICAgICAgICAkcGFydHMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRub2RlcyBhcyAkbm9kZSkgewogICAgICAgICAgICBpZiAoISRub2RlKSB7CiAgICAgICAgICAgICAgICAkY29kZSA9ICIiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvZGUgPSAkdGhpcy0+cmVuZGVyTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICBpZiAoJGFkZFNlbWljb2xvbnMgJiYgJHRoaXMtPnJlcXVpcmVzU2VtaWNvbG9uKCRub2RlKSkgewogICAgICAgICAgICAgICAgICAgICRjb2RlIC49ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkcGFydHNbXSA9ICRjb2RlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wbG9kZSgkc2VwYXJhdG9yLCAkcGFydHMpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiBjb25zZXF1ZW50IGFuZCBhbHRlcm5hdGUgbm9kZXMgb2YgYW4gSWZTdGF0ZW1lbnQgcmVxdWlyZSB0aGUKICAgICAqIG1hbmRhdG9yeSBpbnNlcnRpb24gb2YgYnJhY2tldHMgYXJvdW5kIHRoZW0gdG8gYXZvaWQgdGhlIHBhdHRlcm4gd2hlcmUKICAgICAqIHRoZSAiZWxzZSIgY29kZSBpcyByZW5kZXJlZCBhcyBwYXJ0IG9mIGFuIGlubmVyIElmU3RhdGVtZW50LgogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gbnVsbHxib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0lmUGFydHNCcmFja2V0c1JlcXVpcmVtZW50KCRub2RlKQogICAgewogICAgICAgICRmb3JjZUJyYWNrZXRzID0gbnVsbDsKICAgICAgICBpZiAoJG5vZGUtPmdldFR5cGUoKSA9PT0gIkJsb2NrU3RhdGVtZW50IiAmJiBjb3VudCgkbm9kZS0+Z2V0Qm9keSgpKSA+IDEpIHsKICAgICAgICAgICAgcmV0dXJuICRmb3JjZUJyYWNrZXRzOwogICAgICAgIH0KICAgICAgICAkb3B0QnJhY2tldE5vZGVzID0gYXJyYXkoCiAgICAgICAgICAgICJEb1doaWxlU3RhdGVtZW50IiwgIkZvckluU3RhdGVtZW50IiwgIkZvck9mU3RhdGVtZW50IiwKICAgICAgICAgICAgIkZvclN0YXRlbWVudCIsICJXaGlsZVN0YXRlbWVudCIsICJXaXRoU3RhdGVtZW50IgogICAgICAgICk7CiAgICAgICAgJGNoZWNrRm4gPSBmdW5jdGlvbiAoJG4pIHVzZSAoJG9wdEJyYWNrZXROb2RlcywgJiRmb3JjZUJyYWNrZXRzKSB7CiAgICAgICAgICAgICR0eXBlID0gJG4tPmdldFR5cGUoKTsKICAgICAgICAgICAgaWYgKCR0eXBlID09PSAiSWZTdGF0ZW1lbnQiKSB7CiAgICAgICAgICAgICAgICBpZiAoISRuLT5nZXRBbHRlcm5hdGUoKSkgewogICAgICAgICAgICAgICAgICAgICRmb3JjZUJyYWNrZXRzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBUcmF2ZXJzZXI6OkRPTlRfVFJBVkVSU0VfQ0hJTERfTk9ERVM7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gIkJsb2NrU3RhdGVtZW50IikgewogICAgICAgICAgICAgICAgaWYgKGNvdW50KCRuLT5nZXRCb2R5KCkpICE9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRyYXZlcnNlcjo6RE9OVF9UUkFWRVJTRV9DSElMRF9OT0RFUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCFpbl9hcnJheSgkdHlwZSwgJG9wdEJyYWNrZXROb2RlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUcmF2ZXJzZXI6OkRPTlRfVFJBVkVSU0VfQ0hJTERfTk9ERVM7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgICRub2RlLT50cmF2ZXJzZSgkY2hlY2tGbik7CiAgICAgICAgcmV0dXJuICRmb3JjZUJyYWNrZXRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSBnaXZlbiBub2RlIHJlcXVpcmVzIHNlbWljb2xvbnMgaW5zZXJ0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBTeW50YXhcTm9kZVxOb2RlICAkbm9kZSAgIE5vZGUKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiByZXF1aXJlc1NlbWljb2xvbigkbm9kZSkKICAgIHsKICAgICAgICByZXR1cm4gIWluX2FycmF5KCRub2RlLT5nZXRUeXBlKCksICR0aGlzLT5ub1NlbWljb2xvbik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBzdHJpbmcKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGdldEluZGVudGF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gc3RyX3JlcGVhdCgKICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPmluZCwKICAgICAgICAgICAgJHRoaXMtPnJlbmRlck9wdHMtPmluZExldmVsCiAgICAgICAgKTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcRm9ybWF0dGVyOwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIGZvcm1hdHRlcnMsIGFsbCB0aGUgZm9ybWF0dGVycyBtdXN0IGV4dGVuZCB0aGlzIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIEJhc2UKewogICAgLyoqCiAgICAgKiBOZXcgbGluZSBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuZXdMaW5lID0gIlxuIjsKICAgIAogICAgLyoqCiAgICAgKiBJbmRlbnRhdGlvbiBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRpbmRlbnRhdGlvbiA9ICJcdCI7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBvcGVuIGN1cmx5IGJyYWNrZXRzIGluIGNvZGUgYmxvY2tzIG11c3QgYmUKICAgICAqIG9uIGEgbmV3IGxpbmUKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmV3TGluZUJlZm9yZUN1cmx5QnJhY2tldCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgYmxvY2tzIG9mIGNvZGUgbXVzdCBiZSB3cmFwcGVkIGluIGN1cmx5CiAgICAgKiBicmFja2V0cyBhbHNvIGlmIHRoZXkgY29udGFpbiBvbmx5IG9uZSBpbnN0cnVjdGlvbgogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRhbHdheXNXcmFwQmxvY2tzID0gdHJ1ZTsKICAgIAogICAgLyoqCiAgICAgKiBCb29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIG9wZXJhdG9ycyBtdXN0IGJlIHN1cnJvdW5kZWQgYnkgc3BhY2VzCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNwYWNlc0Fyb3VuZE9wZXJhdG9ycyA9IHRydWU7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBjb250ZW50IGluc2lkZSByb3VuZCBicmFja2V0cyBtdXN0IGJlCiAgICAgKiBzdXJyb3VuZGVkIGJ5IHNwYWNlcwogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRzcGFjZXNJbnNpZGVSb3VuZEJyYWNrZXRzID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBjb21tZW50cyBtdXN0IGJlIHJlbmRlcmVkCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlbmRlckNvbW1lbnRzID0gdHJ1ZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuZXcgbGluZSBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5ld0xpbmUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmV3TGluZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbmRlbnRhdGlvbiBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluZGVudGF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluZGVudGF0aW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIG9wZW4gY3VybHkgYnJhY2tldHMgaW4gY29kZSBibG9ja3MKICAgICAqIG11c3QgYmUgb24gYSBuZXcgbGluZQogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5ld0xpbmVCZWZvcmVDdXJseUJyYWNrZXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmV3TGluZUJlZm9yZUN1cmx5QnJhY2tldDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBibG9ja3Mgb2YgY29kZSBtdXN0IGJlIHdyYXBwZWQgaW4KICAgICAqIGN1cmx5IGJyYWNrZXRzIGFsc28gaWYgdGhleSBjb250YWluIG9ubHkgb25lIGluc3RydWN0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWx3YXlzV3JhcEJsb2NrcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbHdheXNXcmFwQmxvY2tzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIG9wZXJhdG9ycyBtdXN0IGJlIHN1cnJvdW5kZWQgYnkKICAgICAqIHNwYWNlcwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNwYWNlc0Fyb3VuZE9wZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNwYWNlc0Fyb3VuZE9wZXJhdG9yczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBjb250ZW50IGluc2lkZSByb3VuZCBicmFja2V0cyBtdXN0IGJlCiAgICAgKiBzdXJyb3VuZGVkIGJ5IHNwYWNlcwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNwYWNlc0luc2lkZVJvdW5kQnJhY2tldHMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3BhY2VzSW5zaWRlUm91bmRCcmFja2V0czsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcRm9ybWF0dGVyOwoKLyoqCiAqIENvbXBhY3QgZm9ybWF0dGVyLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDb21wYWN0IGV4dGVuZHMgQmFzZQp7CiAgICAvKioKICAgICAqIE5ldyBsaW5lIGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG5ld0xpbmUgPSAiIjsKICAgIAogICAgLyoqCiAgICAgKiBJbmRlbnRhdGlvbiBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRpbmRlbnRhdGlvbiA9ICIiOwogICAgCiAgICAvKioKICAgICAqIEJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgaWYgb3BlcmF0b3JzIG11c3QgYmUgc3Vycm91bmRlZCBieSBzcGFjZXMKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc3BhY2VzQXJvdW5kT3BlcmF0b3JzID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBibG9ja3Mgb2YgY29kZSBtdXN0IGJlIHdyYXBwZWQgaW4gY3VybHkKICAgICAqIGJyYWNrZXRzIGFsc28gaWYgdGhleSBjb250YWluIG9ubHkgb25lIGluc3RydWN0aW9uCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFsd2F5c1dyYXBCbG9ja3MgPSBmYWxzZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcRm9ybWF0dGVyOwoKLyoqCiAqIFByZXR0eSBwcmludCBmb3JtYXR0ZXIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFByZXR0eVByaW50IGV4dGVuZHMgQmFzZQp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XEZvcm1hdHRlcjsKCi8qKgogKiBDb21wYWN0IGZvcm1hdHRlci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRXhwYW5kZWQgZXh0ZW5kcyBCYXNlCnsKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBvcGVuIGN1cmx5IGJyYWNrZXRzIGluIGNvZGUgYmxvY2tzIG11c3QgYmUKICAgICAqIG9uIGEgbmV3IGxpbmUKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmV3TGluZUJlZm9yZUN1cmx5QnJhY2tldCA9IHRydWU7CiAgICAKICAgIC8qKgogICAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBpZiBjb250ZW50IGluc2lkZSByb3VuZCBicmFja2V0cyBtdXN0IGJlCiAgICAgKiBzdXJyb3VuZGVkIGJ5IHNwYWNlcwogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRzcGFjZXNJbnNpZGVSb3VuZEJyYWNrZXRzID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3Q7CgovKioKICogTm9kZXMgcXVlcnkgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUXVlcnkgaW1wbGVtZW50cyBcSXRlcmF0b3JBZ2dyZWdhdGUsIFxDb3VudGFibGUKewogICAgLyoqCiAgICAgKiBDdXJyZW50IG1hdGNoZXMKICAgICAqCiAgICAgKiBAdmFyIFNlbGVjdG9yXE1hdGNoZXMKICAgICAqLwogICAgcHJvdGVjdGVkICRtYXRjaGVzOwoKICAgIC8qKgogICAgICogT3B0aW9ucyBhcnJheQogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRvcHRpb25zOwoKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IuIEF2YWlsYWJsZSBvcHRpb25zIGFyZToKICAgICAqIC0gZW5jb2Rpbmc6IHNlbGVjdG9ycyBlbmNvZGluZy4gSWYgbm90IHNwZWNpZmllZCB0aGUKICAgICAqICAgcGFyc2VyIHdpbGwgYXNzdW1lIFVURi04LgogICAgICoKICAgICAqIEBwYXJhbSBTeW50YXhcTm9kZVxQcm9ncmFtICRyb290ICAgICBSb290IG5vZGUKICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICRvcHRpb25zICBPcHRpb25zIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChTeW50YXhcTm9kZVxQcm9ncmFtICRyb290LCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSBuZXcgU2VsZWN0b3JcTWF0Y2hlcygpOwogICAgICAgICR0aGlzLT5tYXRjaGVzLT5hZGRNYXRjaCgkcm9vdCk7CiAgICAgICAgJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9uczsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmRzIG5vZGVzIG1hdGNoaW5nIHRoZSBnaXZlbiBzZWxlY3RvciBzdGFydGluZyBmcm9tIHRoZQogICAgICogY3VycmVudCBtYXRjaGVkIG5vZGVzLCBpZiBhbnksIG9yIGZyb20gdGhlIHJvb3QKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzZWxlY3RvciBTZWxlY3RvcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqCiAgICAgKiBAdGhyb3dzIFNlbGVjdG9yXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmluZCgkc2VsZWN0b3IpCiAgICB7CiAgICAgICAgJHBhcnNlciA9IG5ldyBTZWxlY3RvclxQYXJzZXIoJHNlbGVjdG9yLCAkdGhpcy0+b3B0aW9ucyk7CiAgICAgICAgJHNlbGVjdG9yID0gJHBhcnNlci0+cGFyc2UoKTsKICAgICAgICAkdGhpcy0+bWF0Y2hlcyA9ICRzZWxlY3Rvci0+ZXhlYygkdGhpcy0+bWF0Y2hlcyk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGdpdmVuIHNlbGVjdG9yIG9uIHRoZSBjdXJyZW50IG5vZGVzIGFuZCBmaWx0ZXJzCiAgICAgKiBvdXQgdGhlIG5vZGVzIHdoaWNoIGRvbid0IG1hdGNoCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkc2VsZWN0b3IgU2VsZWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKgogICAgICogQHRocm93cyBTZWxlY3RvclxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbHRlcigkc2VsZWN0b3IpCiAgICB7CiAgICAgICAgJHBhcnNlciA9IG5ldyBTZWxlY3RvclxQYXJzZXIoJHNlbGVjdG9yLCAkdGhpcy0+b3B0aW9ucyk7CiAgICAgICAgJHNlbGVjdG9yID0gJHBhcnNlci0+cGFyc2UodHJ1ZSk7CiAgICAgICAgJHRoaXMtPm1hdGNoZXMtPmZpbHRlcihmdW5jdGlvbiAoJG5vZGUsICRwYXJlbnQpIHVzZSAoJHNlbGVjdG9yKSB7CiAgICAgICAgICAgICRuZXdNYXRjaCA9IG5ldyBTZWxlY3RvclxNYXRjaGVzKCk7CiAgICAgICAgICAgICRuZXdNYXRjaC0+YWRkTWF0Y2goJG5vZGUsICRwYXJlbnQpOwogICAgICAgICAgICByZXR1cm4gJHNlbGVjdG9yLT5leGVjKCRuZXdNYXRjaCktPmdldE1hdGNoZXMoKTsKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgbWF0Y2hlZCBub2RlcwogICAgICoKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb3VudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzLT5jb3VudCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXgKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRpbmRleCBJbmRleAogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldCgkaW5kZXgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzLT5nZXQoJGluZGV4KVswXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5vZGVzIGl0ZXJhdG9yCiAgICAgKgogICAgICogQHJldHVybiBcQXJyYXlJdGVyYXRvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SXRlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiBuZXcgXEFycmF5SXRlcmF0b3IoJHRoaXMtPm1hdGNoZXMtPmdldE5vZGVzKCkpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdDsKCi8qKgogKiBNYWluIGNsYXNzIG9mIFBlYXN0IGxpYnJhcnkuCiAqIEV2ZXJ5IGZ1bmN0aW9uIG9mIHRoaXMgY2xhc3MgdGFrZXMgdHdvIGFyZ3VtZW50czoKICogLSBUaGUgc291cmNlIGNvZGUgdG8gcGFyc2UKICogLSBUaGUgb3B0aW9ucyBhcnJheSB0aGF0IGlzIGFuIGFzc29jaWF0aXZlIGFycmF5IG9mIHBhcnNlciBzZXR0aW5ncy4KICogICBBdmFpbGFibGUgb3B0aW9ucyBhcmU6CiAqICAgICAgLSAic291cmNlVHlwZSI6IG9uZSBvZiB0aGUgc291cmNlIHR5cGUgY29uc3RhbnRzIGRlY2xhcmVkIGluIHRoaXMgY2xhc3MuCiAqICAgICAgICBUaGlzIG9wdGlvbiB0ZWxscyB0aGUgcGFyc2VyIHRvIHBhcnNlIHRoZSBzb3VyY2UgaW4gc2NyaXB0IG9yIG1vZHVsZQogKiAgICAgICAgbW9kZS4gSWYgdGhpcyBvcHRpb24gaXMgbm90IHByb3ZpZGVkIHRoZSBwYXJzZXIgd2lsbCB3b3JrIGluIHNjcmlwdAogKiAgICAgICAgbW9kZS4KICogICAgICAtICJzb3VyY2VFbmNvZGluZyI6IHRoZSBlbmNvZGluZyBvZiB0aGUgc291cmNlLiBJZiBub3Qgc3BlY2lmaWVkIHRoZQogKiAgICAgICAgcGFyc2VyIHdpbGwgYXNzdW1lIFVURi04LgogKiAgICAgIC0gInN0cmljdEVuY29kaW5nIjogaWYgZmFsc2UgdGhlIHBhcnNlciB3aWxsIGhhbmRsZSBpbnZhbGlkIFVURjgKICogICAgICAgIGNoYXJhY3RlcnMgaW4gdGhlIHNvdXJjZSBjb2RlIGJ5IHJlcGxhY2luZyB0aGVtIHdpdGggdGhlIGNoYXJhY3RlcgogKiAgICAgICAgZGVmaW5lZCBpbiB0aGUgIm1ic3RyaW5nLnN1YnN0aXR1dGVfY2hhcmFjdGVyIiBpbmkgc2V0dGluZywgb3RoZXJ3aXNlCiAqICAgICAgICBpdCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi4KICogICAgICAtICJjb21tZW50cyI6IGlmIHRydWUgaXQgZW5hYmxlcyBjb21tZW50cyBwYXJzaW5nLgogKiAgICAgIC0gImpzeCI6IGlmIHRydWUgaXQgZW5hYmxlcyBwYXJzaW5nIG9mIEpTWCBzeW50YXguCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMjAxNShzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE1IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIHRoZSBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTNihzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE1IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDE2KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTYgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzcoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxNiBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMjAxNyhzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE3IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVM4KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTcgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzIwMTgoc3RyaW5nICRzb3VyY2UsIGFycmF5ICRvcHRpb25zID0gYXJyYXkoKSkKICogUmV0dXJucyBhIHBhcnNlciBpbnN0YW5jZSB3aXRoIEVTMjAxOCBmZWF0dXJlcyBmb3IgdGhlIGdpdmVuIHNvdXJjZS4gU2VlIFBlYXN0CiAqIGNsYXNzIGRvY3VtZW50YXRpb24gdG8gdW5kZXJzdGFuZCBmdW5jdGlvbiBhcmd1bWVudHMuCiAqIAogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTOShzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDE4IGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICogCiAqIEBtZXRob2Qgc3RhdGljIFN5bnRheFxQYXJzZXIgRVMyMDE5KHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTkgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzEwKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMTkgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMjAyMChzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDIwIGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICoKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzExKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMjAgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIEVTMjAyMShzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGEgcGFyc2VyIGluc3RhbmNlIHdpdGggRVMyMDIxIGZlYXR1cmVzIGZvciB0aGUgZ2l2ZW4gc291cmNlLiBTZWUgUGVhc3QKICogY2xhc3MgZG9jdW1lbnRhdGlvbiB0byB1bmRlcnN0YW5kIGZ1bmN0aW9uIGFyZ3VtZW50cy4KICoKICogQG1ldGhvZCBzdGF0aWMgU3ludGF4XFBhcnNlciBFUzEyKHN0cmluZyAkc291cmNlLCBhcnJheSAkb3B0aW9ucyA9IGFycmF5KCkpCiAqIFJldHVybnMgYSBwYXJzZXIgaW5zdGFuY2Ugd2l0aCBFUzIwMjEgZmVhdHVyZXMgZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZSBQZWFzdAogKiBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKgogKiBAbWV0aG9kIHN0YXRpYyBTeW50YXhcUGFyc2VyIGxhdGVzdChzdHJpbmcgJHNvdXJjZSwgYXJyYXkgJG9wdGlvbnMgPSBhcnJheSgpKQogKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBsYXRlc3QgcGFyc2VyIHZlcnNpb24gZm9yIHRoZSBnaXZlbiBzb3VyY2UuIFNlZQogKiBQZWFzdCBjbGFzcyBkb2N1bWVudGF0aW9uIHRvIHVuZGVyc3RhbmQgZnVuY3Rpb24gYXJndW1lbnRzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQZWFzdAp7CiAgICAvL1NvdXJjZSB0eXBlIGNvbnN0YW50cwogICAgLyoqCiAgICAgKiBUaGlzIHNvdXJjZSB0eXBlIGluZGljYXRlcyB0aGF0IHRoZSBzb3VyY2UgaXMgYSBzY3JpcHQgYW5kIGltcG9ydAogICAgICogYW5kIGV4cG9ydCBrZXl3b3JkcyBhcmUgbm90IHBhcnNlZC4KICAgICAqLwogICAgY29uc3QgU09VUkNFX1RZUEVfU0NSSVBUID0gInNjcmlwdCI7CiAgICAKICAgIC8qKgogICAgICogVGhpcyBzb3VyY2UgdHlwZSBpbmRpY2F0ZXMgdGhhdCB0aGUgc291cmNlIGlzIGEgbW9kdWxlLCB0aGlzIGVuYWJsZXMKICAgICAqIHRoZSBwYXJzaW5nIG9mIGltcG9ydCBhbmQgZXhwb3J0IGtleXdvcmRzLgogICAgICovCiAgICBjb25zdCBTT1VSQ0VfVFlQRV9NT0RVTEUgPSAibW9kdWxlIjsKICAgIAogICAgLyoqCiAgICAgKiBWYWxpZCB2ZXJzaW9ucyBhbmQgYWxpYXNlcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHN0YXRpYyBwcm90ZWN0ZWQgJHZlcnNpb25zID0gYXJyYXkoCiAgICAgICAgIkVTNiIgPT4gIkVTMjAxNSIsCiAgICAgICAgIkVTNyIgPT4gIkVTMjAxNiIsCiAgICAgICAgIkVTOCIgPT4gIkVTMjAxNyIsCiAgICAgICAgIkVTOSIgPT4gIkVTMjAxOCIsCiAgICAgICAgIkVTMTAiID0+ICJFUzIwMTkiLAogICAgICAgICJFUzExIiA9PiAiRVMyMDIwIiwKICAgICAgICAiRVMxMiIgPT4gIkVTMjAyMSIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTWFnaWMgbWV0aG9kIHRoYXQgZXhwb3NlcyBhbGwgdGhlIGZ1bmN0aW9ucyB0byBhY2Nlc3MgcGFyc2VyIHdpdGgKICAgICAqIHNwZWNpZmljIGZlYXR1cmVzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJHZlcnNpb24gICBQYXJzZXIgdmVyc2lvbgogICAgICogQHBhcmFtIGFycmF5ICAgICAkYXJncyAgICAgIFBhcnNlciBhcmd1bWVudHMKICAgICAqIAogICAgICogQHJldHVybiBTeW50YXgvUGFyc2VyCiAgICAgKiAKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIF9fY2FsbFN0YXRpYygkdmVyc2lvbiwgJGFyZ3MpCiAgICB7CiAgICAgICAgJHNvdXJjZSA9ICRhcmdzWzBdOwogICAgICAgICRvcHRpb25zID0gaXNzZXQoJGFyZ3NbMV0pID8gJGFyZ3NbMV0gOiBhcnJheSgpOwogICAgICAgIAogICAgICAgIGlmICghaW5fYXJyYXkoJHZlcnNpb24sIHNlbGY6OiR2ZXJzaW9ucykpIHsKICAgICAgICAgICAgaWYgKCR2ZXJzaW9uID09PSAibGF0ZXN0IikgewogICAgICAgICAgICAgICAgJHZlcnNpb24gPSBlbmQoc2VsZjo6JHZlcnNpb25zKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KHNlbGY6OiR2ZXJzaW9uc1skdmVyc2lvbl0pKSB7CiAgICAgICAgICAgICAgICAkdmVyc2lvbiA9IHNlbGY6OiR2ZXJzaW9uc1skdmVyc2lvbl07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCB2ZXJzaW9uICR2ZXJzaW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJGZlYXR1cmVzQ2xhc3MgPSAiXFxQZWFzdFxcU3ludGF4XFwkdmVyc2lvblxcRmVhdHVyZXMiOwogICAgICAgIHJldHVybiBuZXcgU3ludGF4XFBhcnNlcigKICAgICAgICAgICAgJHNvdXJjZSwgbmV3ICRmZWF0dXJlc0NsYXNzLCAkb3B0aW9ucwogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxFUzIwMTU7CgovKioKICogRVMyMDE1IGZlYXR1cmVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEZlYXR1cmVzIGV4dGVuZHMgXFBlYXN0XFN5bnRheFxGZWF0dXJlcwp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBBIHRva2VuIGVtaXR0ZWQgYnkgdGhlIHRva2VuaXplci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVG9rZW4gaW1wbGVtZW50cyBcSlNPTlNlcmlhbGl6YWJsZQp7CiAgICAvL1R5cGUgY29uc3RhbnRzCiAgICAvKioKICAgICAqIEJvb2xlYW4gbGl0ZXJhbAogICAgICovCiAgICBjb25zdCBUWVBFX0JPT0xFQU5fTElURVJBTCA9ICJCb29sZWFuIjsKICAgIAogICAgLyoqCiAgICAgKiBJZGVudGlmaWVyCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfSURFTlRJRklFUiA9ICJJZGVudGlmaWVyIjsKICAgIAogICAgLyoqCiAgICAgKiBLZXl3b3JkCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfS0VZV09SRCA9ICJLZXl3b3JkIjsKICAgIAogICAgLyoqCiAgICAgKiBOdWxsIGxpdGVyYWwKICAgICAqLwogICAgY29uc3QgVFlQRV9OVUxMX0xJVEVSQUwgPSAiTnVsbCI7CiAgICAKICAgIC8qKgogICAgICogTnVtZXJpYyBsaXRlcmFsCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfTlVNRVJJQ19MSVRFUkFMID0gIk51bWVyaWMiOwogICAgCiAgICAvKioKICAgICAqIEJpZ0ludCBsaXRlcmFsCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfQklHSU5UX0xJVEVSQUwgPSAiQmlnSW50IjsKICAgIAogICAgLyoqCiAgICAgKiBQdW5jdHV0YXRvcgogICAgICovCiAgICBjb25zdCBUWVBFX1BVTkNUVVRBVE9SID0gIlB1bmN0dWF0b3IiOwogICAgCiAgICAvKioKICAgICAqIFN0cmluZyBsaXRlcmFsCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfU1RSSU5HX0xJVEVSQUwgPSAiU3RyaW5nIjsKICAgIAogICAgLyoqCiAgICAgKiBSZWd1bGFyIGV4cHJlc3Npb24KICAgICAqLwogICAgY29uc3QgVFlQRV9SRUdVTEFSX0VYUFJFU1NJT04gPSAiUmVndWxhckV4cHJlc3Npb24iOwogICAgCiAgICAvKioKICAgICAqIFRlbXBsYXRlCiAgICAgKi8KICAgIGNvbnN0IFRZUEVfVEVNUExBVEUgPSAiVGVtcGxhdGUiOwogICAgCiAgICAvKioKICAgICAqIENvbW1lbnQKICAgICAqLwogICAgY29uc3QgVFlQRV9DT01NRU5UID0gIkNvbW1lbnQiOwogICAgCiAgICAvKioKICAgICAqIEpTWCB0ZXh0CiAgICAgKi8KICAgIGNvbnN0IFRZUEVfSlNYX1RFWFQgPSAiSlNYVGV4dCI7CiAgICAKICAgIC8qKgogICAgICogSlNYIGlkZW50aWZpZXIKICAgICAqLwogICAgY29uc3QgVFlQRV9KU1hfSURFTlRJRklFUiA9ICJKU1hJZGVudGlmaWVyIjsKICAgIAogICAgLyoqCiAgICAgKiBUb2tlbnMnIHR5cGUgdGhhdCBpcyBvbmUgb2YgdGhlIHR5cGUgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHR5cGU7CiAgICAKICAgIC8qKgogICAgICogVG9rZW4ncyB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICR2YWx1ZTsKICAgIAogICAgLyoqCiAgICAgKiBUb2tlbidzIGxvY2F0aW9uIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAdmFyIFNvdXJjZUxvY2F0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxvY2F0aW9uOwogICAgCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgIFRva2VuJ3MgdHlwZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgVG9rZW4ncyB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHR5cGUsICR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dHlwZSA9ICR0eXBlOwogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICAkdGhpcy0+bG9jYXRpb24gPSBuZXcgU291cmNlTG9jYXRpb24oKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0b2tlbidzIHR5cGUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFR5cGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dHlwZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0b2tlbidzIHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0b2tlbidzIGxvY2F0aW9uIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFNvdXJjZUxvY2F0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMb2NhdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sb2NhdGlvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgdG9rZW4gaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAkcG9zaXRpb24gU3RhcnQgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3RhcnRQb3NpdGlvbihQb3NpdGlvbiAkcG9zaXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2F0aW9uLT5zZXRTdGFydCgkcG9zaXRpb24pOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIHRva2VuIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIEVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbmRQb3NpdGlvbihQb3NpdGlvbiAkcG9zaXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2F0aW9uLT5zZXRFbmQoJHBvc2l0aW9uKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNlcmlhbGl6YWJsZSB2ZXJzaW9uIG9mIHRoZSBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGpzb25TZXJpYWxpemUoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgInR5cGUiID0+ICR0aGlzLT5nZXRUeXBlKCksCiAgICAgICAgICAgICJ2YWx1ZSIgPT4gJHRoaXMtPmdldFZhbHVlKCksCiAgICAgICAgICAgICJsb2NhdGlvbiIgPT4gJHRoaXMtPmdldExvY2F0aW9uKCkKICAgICAgICApOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDIwOwoKLyoqCiAqIEVTMjAyMCBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDE5XEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogRHluYW1pYyBpbXBvcnQKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRkeW5hbWljSW1wb3J0ID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEJpZ0ludCBsaXRlcmFscwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGJpZ0ludCA9IHRydWU7CgogICAgLyoqCiAgICAgKiBFeHBvcnRlZCBuYW1lIGZvciBleHBvcnQgYWxsIGRlY2xhcmF0aW9ucwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGV4cG9ydGVkTmFtZUluRXhwb3J0QWxsID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIEltcG9ydC5tZXRhCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkaW1wb3J0TWV0YSA9IHRydWU7CgogICAgLyoqCiAgICAgKiBDb2FsZXNjaW5nIG9wZXJhdG9yCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkY29hbGVzY2luZ09wZXJhdG9yID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIE9wdGlvbmFsIGNoYWluaW5nCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkb3B0aW9uYWxDaGFpbmluZyA9IHRydWU7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsb2NhdGlvbiBpbiB0aGUgc291cmNlIGNvZGUgd2l0aCBzdGFydCBhbmQgZW5kCiAqIHBvc2l0b24uCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFNvdXJjZUxvY2F0aW9uIGltcGxlbWVudHMgXEpTT05TZXJpYWxpemFibGUKewogICAgLyoqCiAgICAgKiBTdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0YXJ0OwogICAgCiAgICAvKioKICAgICAqIEVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGVuZDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGFydCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGFydDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YXJ0KFBvc2l0aW9uICRwb3NpdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+c3RhcnQgPSAkcG9zaXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIEVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbmQoUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgICR0aGlzLT5lbmQgPSAkcG9zaXRpb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXJpYWxpemFibGUgdmVyc2lvbiBvZiB0aGUgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGpzb25TZXJpYWxpemUoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgInN0YXJ0IiA9PiAkdGhpcy0+Z2V0U3RhcnQoKSwKICAgICAgICAgICAgImVuZCIgPT4gJHRoaXMtPmdldEVuZCgpCiAgICAgICAgKTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIEV2ZW50cyBlbWl0dGVyIGNsYXNzLiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIHVzZWQgYnkgUGFyc2VyIGFuZCBTY2FubmVyCiAqIHRvIGVtaXQgZXZlbnRzIGFuZCBhdHRhY2ggbGlzdGVuZXJzIHRvIHRoZW0KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRXZlbnRzRW1pdHRlcgp7CiAgICAvKioKICAgICAqIEV2ZW50cyByZWdpc3RyeSBhcnJheQogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRldmVudHNSZWdpc3RyeSA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogQXR0YWNoZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgZ2l2ZW4gZXZlbnQKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICAkZXZlbnQgICAgICBFdmVudCBuYW1lCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgICRsaXN0ZW5lciAgIExpc3RlbmVyIGZ1bmN0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZExpc3RlbmVyKCRldmVudCwgJGxpc3RlbmVyKQogICAgewogICAgICAgIGlmICghaXNzZXQoJHRoaXMtPmV2ZW50c1JlZ2lzdHJ5WyRldmVudF0pKSB7CiAgICAgICAgICAgICR0aGlzLT5ldmVudHNSZWdpc3RyeVskZXZlbnRdID0gYXJyYXkoKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmV2ZW50c1JlZ2lzdHJ5WyRldmVudF1bXSA9ICRsaXN0ZW5lcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRmlyZXMgYW4gZXZlbnQKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICAkZXZlbnQgIEV2ZW50IG5hbWUKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJGFyZ3MgICBBcmd1bWVudHMgdG8gcGFzcyB0byBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmlyZSgkZXZlbnQsICRhcmdzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmV2ZW50c1JlZ2lzdHJ5WyRldmVudF0pKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ldmVudHNSZWdpc3RyeVskZXZlbnRdIGFzICRsaXN0ZW5lcikgewogICAgICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmNfYXJyYXkoJGxpc3RlbmVyLCAkYXJncyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDE5OwoKLyoqCiAqIEVTMjAxOSBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDE4XEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogT3B0aW9uYWwgY2F0Y2ggYmluZGluZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJG9wdGlvbmFsQ2F0Y2hCaW5kaW5nID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIFBhcmFncmFwaCBhbmQgbGluZSBzZXBlYXJ0b3IgaW4gc3RyaW5ncwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHBhcmFncmFwaExpbmVTZXBJblN0cmluZ3MgPSB0cnVlOwp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDIxOwoKLyoqCiAqIEVTMjAyMSBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDIwXEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogTG9naWNhbCBhc3NpZ25tZW50IG9wZXJhdG9ycwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGxvZ2ljYWxBc3NpZ25tZW50T3BlcmF0b3JzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIE51bWVyaWMgbGl0ZXJhbCBzZXBhcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRudW1lcmljTGl0ZXJhbFNlcGFyYXRvciA9IHRydWU7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBVdGlsaXRpZXMgY2xhc3MuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFV0aWxzCnsKICAgIC8qKgogICAgICogQ29udmVydHMgYSBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgVVRGLTggY2hhcmFjdGVycwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgICAgICAgICAgICBTdHJpbmcgdG8gY29udmVydAogICAgICogQHBhcmFtIGJvb2wgICAkc3RyaWN0RW5jb2RpbmcgSWYgZmFsc2UgYW5kIHRoZSBzdHJpbmcgY29udGFpbnMgaW52YWxpZAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVRGLTggY2hhcmFjdGVycywgaXQgd2lsbCByZXBsYWNlIHRob3NlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzIHdpdGggdGhlIG9uZSBkZWZpbmVkIGluIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWJzdHJpbmcuc3Vic3RpdHV0ZV9jaGFyYWN0ZXIgc2V0dGluZwogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiAKICAgICAqIEB0aHJvd3MgRW5jb2RpbmdFeGNlcHRpb24KICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiBzdHJpbmdUb1VURjhBcnJheSgkc3RyLCAkc3RyaWN0RW5jb2RpbmcgPSB0cnVlKQogICAgewogICAgICAgIGlmICgkc3RyID09PSAiIikgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICB9CiAgICAgICAgJHJldCA9IHByZWdfc3BsaXQoJy8vdScsICRzdHIsIG51bGwsIFBSRUdfU1BMSVRfTk9fRU1QVFkpOwogICAgICAgIGlmIChwcmVnX2xhc3RfZXJyb3IoKSA9PT0gUFJFR19CQURfVVRGOF9FUlJPUikgewogICAgICAgICAgICBpZiAoISRzdHJpY3RFbmNvZGluZykgewogICAgICAgICAgICAgICAgJHN0ciA9IG1iX2NvbnZlcnRfZW5jb2RpbmcoJHN0ciwgJ1VURi04JywgJ1VURi04Jyk7CiAgICAgICAgICAgICAgICAkcmV0ID0gc2VsZjo6c3RyaW5nVG9VVEY4QXJyYXkoJHN0ciwgZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVuY29kaW5nRXhjZXB0aW9uKCJTdHJpbmcgY29udGFpbnMgaW52YWxpZCBVVEYtOCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnZlcnRzIGFuIHVuaWNvZGUgY29kZSBwb2ludCB0byBVVEYtOAogICAgICogCiAgICAgKiBAcGFyYW0gaW50ICRudW0gVW5pY29kZSBjb2RlIHBvaW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiB1bmljb2RlVG9VdGY4KCRudW0pCiAgICB7CiAgICAgICAgLy9Gcm9tOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE4MDU4MDIvcGhwLWNvbnZlcnQtdW5pY29kZS1jb2RlcG9pbnQtdG8tdXRmLTgjYW5zd2VyLTcxNTMxMzMKICAgICAgICBpZiAoJG51bSA8PSAweDdGKSB7CiAgICAgICAgICAgIHJldHVybiBjaHIoJG51bSk7CiAgICAgICAgfSBlbHNlaWYgKCRudW0gPD0gMHg3RkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiA2KSArIDE5MikgLgogICAgICAgICAgICAgICAgICAgY2hyKCgkbnVtICYgNjMpICsgMTI4KTsKICAgICAgICB9IGVsc2VpZiAoJG51bSA8PSAweEZGRkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiAxMikgKyAyMjQpIC4KICAgICAgICAgICAgICAgICAgIGNocigoKCRudW0gPj4gNikgJiA2MykgKyAxMjgpIC4KICAgICAgICAgICAgICAgICAgIGNocigoJG51bSAmIDYzKSArIDEyOCk7CiAgICAgICAgfSBlbHNlaWYgKCRudW0gPD0gMHgxRkZGRkYpIHsKICAgICAgICAgICAgcmV0dXJuIGNocigoJG51bSA+PiAxOCkgKyAyNDApIC4KICAgICAgICAgICAgICAgICAgIGNocigoKCRudW0gPj4gMTIpICYgNjMpICsgMTI4KSAuCiAgICAgICAgICAgICAgICAgICBjaHIoKCgkbnVtID4+IDYpICYgNjMpICsgMTI4KSAuCiAgICAgICAgICAgICAgICAgICBjaHIoKCRudW0gJiA2MykgKyAxMjgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJyc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGlsZWQgbGluZSB0ZXJtaW5hdG9ycyBjYWNoZQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRsaW5lVGVybWluYXRvcnNDYWNoZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxpbmUgdGVybWluYXRvcnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIGdldExpbmVUZXJtaW5hdG9ycygpCiAgICB7CiAgICAgICAgaWYgKCFzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGUpIHsKICAgICAgICAgICAgc2VsZjo6JGxpbmVUZXJtaW5hdG9yc0NhY2hlID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCAoU2Nhbm5lcjo6JGxpbmVUZXJtaW5hdG9yc0NoYXJzIGFzICRjaGFyKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGVbXSA9IGlzX2ludCgkY2hhcikgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmOjp1bmljb2RlVG9VdGY4KCRjaGFyKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaGFyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2FjaGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhIHN0cmluZyBhcyBpdCBhcHBlYXJzIGluIHRoZSBzb3VyY2UgY29kZSBhbmQgcmV0dXJucwogICAgICogYW4gdW5xdW90ZWQgdmVyc2lvbiBvZiBpdAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgVGhlIHN0cmluZyB0byB1bnF1b3RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gdW5xdW90ZUxpdGVyYWxTdHJpbmcoJHN0cikKICAgIHsKICAgICAgICAvL1JlbW92ZSBxdW90ZXMKICAgICAgICAkc3RyID0gc3Vic3RyKCRzdHIsIDEsIC0xKTsKICAgICAgICAKICAgICAgICAkbGluZVRlcm1pbmF0b3JzID0gc2VsZjo6Z2V0TGluZVRlcm1pbmF0b3JzKCk7CiAgICAgICAgCiAgICAgICAgLy9IYW5kbGUgZXNjYXBlcwogICAgICAgICRwYXR0ZXJucyA9IGFycmF5KAogICAgICAgICAgICAidVx7W2EtZkEtRjAtOV0rXH0iLAogICAgICAgICAgICAidVthLWZBLUYwLTldezR9IiwKICAgICAgICAgICAgInhbYS1mQS1GMC05XXsyfSIsCiAgICAgICAgICAgICIwWzAtN117Mn0iLAogICAgICAgICAgICAiWzEtN11bMC03XSIsCiAgICAgICAgICAgICIuIgogICAgICAgICk7CiAgICAgICAgJHJlZyA9ICIvXFxcXCgiIC4gaW1wbG9kZSgifCIsICRwYXR0ZXJucykgLiAiKS9zIjsKICAgICAgICAkc2ltcGxlU2VxdWVuY2UgPSBhcnJheSgKICAgICAgICAgICAgIm4iID0+ICJcbiIsCiAgICAgICAgICAgICJmIiA9PiAiXGYiLAogICAgICAgICAgICAiciIgPT4gIlxyIiwKICAgICAgICAgICAgInQiID0+ICJcdCIsCiAgICAgICAgICAgICJ2IiA9PiAiXHYiLAogICAgICAgICAgICAiYiIgPT4gIlx4OCIKICAgICAgICApOwogICAgICAgICRyZXBsYWNlbWVudCA9IGZ1bmN0aW9uICgkbSkgdXNlICgkc2ltcGxlU2VxdWVuY2UsICRsaW5lVGVybWluYXRvcnMpIHsKICAgICAgICAgICAgJHR5cGUgPSAkbVsxXVswXTsKICAgICAgICAgICAgaWYgKGlzc2V0KCRzaW1wbGVTZXF1ZW5jZVskdHlwZV0pKSB7CiAgICAgICAgICAgICAgICAvLyBcbiwgXHIsIFx0IC4uLgogICAgICAgICAgICAgICAgcmV0dXJuICRzaW1wbGVTZXF1ZW5jZVskdHlwZV07CiAgICAgICAgICAgIH0gZWxzZWlmICgkdHlwZSA9PT0gInUiIHx8ICR0eXBlID09PSAieCIpIHsKICAgICAgICAgICAgICAgIC8vSW52YWxpZCB1bmljb2RlIG9yIGhleGFkZWNpbWFsIHNlcXVlbmNlcwogICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkbVsxXSkgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxcJHR5cGUiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gXHVGRkZGLCBcdXtGRkZGfSwgXHhGRgogICAgICAgICAgICAgICAgJGNvZGUgPSBzdWJzdHIoJG1bMV0sIDEpOwogICAgICAgICAgICAgICAgJGNvZGUgPSBzdHJfcmVwbGFjZShhcnJheSgieyIsICJ9IiksICIiLCAkY29kZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbHM6OnVuaWNvZGVUb1V0ZjgoaGV4ZGVjKCRjb2RlKSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdHlwZSA+PSAiMCIgJiYgJHR5cGUgPD0gIjciKSB7CiAgICAgICAgICAgICAgICAvL0ludmFsaWQgb2N0YWwgc2VxdWVuY2VzCiAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRtWzFdKSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAiXFwkdHlwZSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBcMTIzCiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbHM6OnVuaWNvZGVUb1V0Zjgob2N0ZGVjKCRtWzFdKSk7CiAgICAgICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkbVsxXSwgJGxpbmVUZXJtaW5hdG9ycykpIHsKICAgICAgICAgICAgICAgIC8vIEVzY2FwZWQgbGluZSB0ZXJtaW5hdG9ycwogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gRXNjYXBlZCBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gJG1bMV07CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgICRzdHIgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHJlZywgJHJlcGxhY2VtZW50LCAkc3RyKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJHN0cjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNvbnZlcnRzIGEgc3RyaW5nIHRvIGEgcXVvdGVkIGphdmFzY3JpcHQgc3RyaW5nCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciAgIFN0cmluZyB0byBxdW90ZQogICAgICogQHBhcmFtIHN0cmluZyAkcXVvdGUgUXVvdGUgY2hhcmFjdGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgZnVuY3Rpb24gcXVvdGVMaXRlcmFsU3RyaW5nKCRzdHIsICRxdW90ZSkKICAgIHsKICAgICAgICAkZXNjYXBlID0gc2VsZjo6Z2V0TGluZVRlcm1pbmF0b3JzKCk7CiAgICAgICAgJGVzY2FwZVtdID0gJHF1b3RlOwogICAgICAgICRlc2NhcGVbXSA9ICJcXFxcIjsKICAgICAgICAkcmVnID0gIi8oIiAuIGltcGxvZGUoInwiLCAkZXNjYXBlKSAuICIpLyI7CiAgICAgICAgJHN0ciA9IHByZWdfcmVwbGFjZSgkcmVnLCAiXFxcXCQxIiwgJHN0cik7CiAgICAgICAgcmV0dXJuICRxdW90ZSAuICRzdHIgLiAkcXVvdGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydGllcyBtYXAgZm9yIHRoZSBnaXZlbiBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkbm9kZSBOb2RlIG9yIGNsYXNzIHRvIGNvbnNpZGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgc3RhdGljIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzTWFwKCRub2RlKQogICAgewogICAgICAgIHN0YXRpYyAkY2FjaGUgPSBhcnJheSgpOwogICAgICAgIAogICAgICAgIGlmICgkbm9kZSBpbnN0YW5jZW9mIFxSZWZsZWN0aW9uQ2xhc3MpIHsKICAgICAgICAgICAgJGNsYXNzTmFtZSA9ICRub2RlLT5nZXROYW1lKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNsYXNzTmFtZSA9IGdldF9jbGFzcygkbm9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICghaXNzZXQoJGNhY2hlWyRjbGFzc05hbWVdKSkgewogICAgICAgICAgICAkY2xhc3MgPSBuZXcgXFJlZmxlY3Rpb25DbGFzcygkY2xhc3NOYW1lKTsKICAgICAgICAgICAgJHBhcmVudCA9ICRjbGFzcy0+Z2V0UGFyZW50Q2xhc3MoKTsKICAgICAgICAgICAgJHByb3BzID0gJHBhcmVudCA/IHNlbGY6OmdldFByb3BlcnRpZXNNYXAoJHBhcmVudCkgOiBhcnJheSgpOwogICAgICAgICAgICAkZGVmYXVsdHMgPSAkY2xhc3MtPmdldERlZmF1bHRQcm9wZXJ0aWVzKCk7CiAgICAgICAgICAgIGlmIChpc3NldCgkZGVmYXVsdHNbInByb3BlcnRpZXNNYXAiXSkpIHsKICAgICAgICAgICAgICAgICRwcm9wcyA9IGFycmF5X21lcmdlKCRwcm9wcywgJGRlZmF1bHRzWyJwcm9wZXJ0aWVzTWFwIl0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjYWNoZVskY2xhc3NOYW1lXSA9ICRwcm9wczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjYWNoZVskY2xhc3NOYW1lXTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0aWVzIGxpc3QgZm9yIHRoZSBnaXZlbiBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgJG5vZGUgICAgICAgIE5vZGUgdG8gY29uc2lkZXIKICAgICAqIEBwYXJhbSBib29sICAgICAgJHRyYXZlcnNhYmxlIElmIHRydWUgaXQgcmV0dXJucyBvbmx5IHRyYXZlcnNhYmxlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGdldE5vZGVQcm9wZXJ0aWVzKE5vZGVcTm9kZSAkbm9kZSwgJHRyYXZlcnNhYmxlID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHByb3BzID0gc2VsZjo6Z2V0UHJvcGVydGllc01hcCgkbm9kZSk7CiAgICAgICAgcmV0dXJuIGFycmF5X21hcCgKICAgICAgICAgICAgZnVuY3Rpb24gKCRwcm9wKSB7CiAgICAgICAgICAgICAgICAkdWNQcm9wID0gdWNmaXJzdCgkcHJvcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiID0+ICRwcm9wLAogICAgICAgICAgICAgICAgICAgICJnZXR0ZXIiID0+ICJnZXQkdWNQcm9wIiwKICAgICAgICAgICAgICAgICAgICAic2V0dGVyIiA9PiAic2V0JHVjUHJvcCIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGFycmF5X2tleXMoJHRyYXZlcnNhYmxlID8gYXJyYXlfZmlsdGVyKCRwcm9wcykgOiAkcHJvcHMpCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gZXhwYW5kZWQgdmVyc2lvbiBvZiB0aGUgdHJhdmVyc2FibGUgbm9kZSBwcm9wZXJ0aWVzLgogICAgICogVGhlIHJldHVybiBvZiB0aGUgZnVuY3Rpb24gaXMgYW4gYXJyYXkgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiB2YWx1ZXMgd2l0aCBhcnJheXMgZmxhdHRlbmVkCiAgICAgKgogICAgICogQHBhcmFtIE5vZGVcTm9kZSAkbm9kZSBOb2RlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBzdGF0aWMgcHVibGljIGZ1bmN0aW9uIGdldEV4cGFuZGVkTm9kZVByb3BlcnRpZXMoTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgICRyZXQgPSBhcnJheSgpOwogICAgICAgICRwcm9wcyA9IHNlbGY6OmdldE5vZGVQcm9wZXJ0aWVzKCRub2RlLCB0cnVlKTsKICAgICAgICBmb3JlYWNoICgkcHJvcHMgYXMgJHByb3ApIHsKICAgICAgICAgICAgJHZhbCA9ICRub2RlLT57JHByb3BbImdldHRlciJdfSgpOwogICAgICAgICAgICBpZiAoaXNfYXJyYXkoJHZhbCkpIHsKICAgICAgICAgICAgICAgICRyZXQgPSBhcnJheV9tZXJnZSgkcmV0LCAkdmFsKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRyZXRbXSA9ICR2YWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWxldGUgYW4gYXJyYXkgZWxlbWVudCBieSB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gYXJyYXkgJGFycmF5IEFycmF5CiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbCAgIFZhbHVlIHRvIHJlbW92ZQogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgc3RhdGljIHB1YmxpYyBmdW5jdGlvbiByZW1vdmVBcnJheVZhbHVlKCYkYXJyYXksICR2YWwpCiAgICB7CiAgICAgICAgYXJyYXlfc3BsaWNlKCRhcnJheSwgYXJyYXlfc2VhcmNoKCR2YWwsICRhcnJheSksIDEpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXg7CgovKioKICogUGFyc2VyIGZlYXR1cmVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogRXhwb25lbnRpYXRpb24gb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRleHBvbmVudGlhdGlvbk9wZXJhdG9yID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBBc3luYy9hd2FpdAogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGFzeW5jQXdhaXQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFRyYWlsaW5nIGNvbW1hIGluIGZ1bmN0aW9uIGNhbGxzIGFuZCBkZWNsYXJhdGlvbnMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICR0cmFpbGluZ0NvbW1hRnVuY3Rpb25DYWxsRGVjbGFyYXRpb24gPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEZvci1pbiBpbml0aWFsaXplcgogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGZvckluSW5pdGlhbGl6ZXIgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEFzeW5jIGl0ZXJhdGlvbiBhbmQgZ2VuZXJhdG9ycwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGFzeW5jSXRlcmF0aW9uR2VuZXJhdG9ycyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogUmVzdC9zcHJlYWQgcHJvcGVydGllcwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHJlc3RTcHJlYWRQcm9wZXJ0aWVzID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBTa2lwIGVzY2FwZSBzZXF1ZW5jZXMgY2hlY2tzIGluIHRhZ2dlZCB0ZW1wbGF0ZQogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHNraXBFc2NhcGVTZXFDaGVja0luVGFnZ2VkVGVtcGxhdGVzID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBPcHRpb25hbCBjYXRjaCBiaW5kaW5nCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkb3B0aW9uYWxDYXRjaEJpbmRpbmcgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFBhcmFncmFwaCBhbmQgbGluZSBzZXBlYXJ0b3IgaW4gc3RyaW5ncwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHBhcmFncmFwaExpbmVTZXBJblN0cmluZ3MgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIER5bmFtaWMgaW1wb3J0CiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkZHluYW1pY0ltcG9ydCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQmlnSW50IGxpdGVyYWxzCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkYmlnSW50ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBFeHBvcnRlZCBuYW1lIGZvciBleHBvcnQgYWxsIGRlY2xhcmF0aW9ucwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGV4cG9ydGVkTmFtZUluRXhwb3J0QWxsID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBJbXBvcnQubWV0YQogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGltcG9ydE1ldGEgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIENvYWxlc2Npbmcgb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRjb2FsZXNjaW5nT3BlcmF0b3IgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIE9wdGlvbmFsIGNoYWluaW5nCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkb3B0aW9uYWxDaGFpbmluZyA9IGZhbHNlOwoKICAgIC8qKgogICAgICogTG9naWNhbCBhc3NpZ25tZW50IG9wZXJhdG9ycwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGxvZ2ljYWxBc3NpZ25tZW50T3BlcmF0b3JzID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBOdW1lcmljIGxpdGVyYWwgc2VwYXJhdG9yCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkbnVtZXJpY0xpdGVyYWxTZXBhcmF0b3IgPSBmYWxzZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIEVuY29kaW5nIGV4Y2VwdGlvbiBjbGFzcy4gRW5jb2RpbmcgZXJyb3JzIHdoaWxlIHNjYW5uaW5nIHRoZSBzb3VyY2UgYXJlCiAqIHRocm93biB1c2luZyB0aGlzIHVzaW5nIHRoaXMgZXhjZXB0aW9uIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBFbmNvZGluZ0V4Y2VwdGlvbiBleHRlbmRzIFxFeGNlcHRpb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXg7CgovKioKICogTG9uZ2VzdCBTZXF1ZW5jZSBNYXRjaGVyLiBVdGlsaXR5IGNsYXNzIHVzZWQgYnkgdGhlIHNjYW5uZXIgdG8gY29uc3VtZQogKiB0aGUgbG9uZ2VzdCBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXIgZ2l2ZW4gYSBzZXQgb2YgYWxsb3dlZCBjaGFyYWN0ZXJzIHNlcXVlbmNlcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTFNNCnsKICAgIC8qKgogICAgICogSW50ZXJuYWwgc2VxdWVuY2VzIG1hcAogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJG1hcCA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogRW5jb2RpbmcgaGFuZGxlIGZsYWcKICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGhhbmRsZUVuY29kaW5nID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gYXJyYXkgJHNlcXVlbmNlcyAgICAgIEFsbG93ZWQgY2hhcmFjdGVycyBzZXF1ZW5jZXMKICAgICAqIEBwYXJhbSBib29sICAkaGFuZGxlRW5jb2RpbmcgVHJ1ZSB0byBoYW5kbGUgZW5jb2Rpbmcgd2hlbiBtYXRjaGluZwogICAgICovCiAgICBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkc2VxdWVuY2VzLCAkaGFuZGxlRW5jb2RpbmcgPSBmYWxzZSkKICAgIHsKICAgICAgICAkdGhpcy0+aGFuZGxlRW5jb2RpbmcgPSAkaGFuZGxlRW5jb2Rpbmc7CiAgICAgICAgZm9yZWFjaCAoJHNlcXVlbmNlcyBhcyAkcykgewogICAgICAgICAgICAkdGhpcy0+YWRkKCRzKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQWRkcyBhIHNlcXVlbmNlCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNlcXVlbmNlIFNlcXVlbmNlIHRvIGFkZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGQoJHNlcXVlbmNlKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aGFuZGxlRW5jb2RpbmcpIHsKICAgICAgICAgICAgJHMgPSBVdGlsczo6c3RyaW5nVG9VVEY4QXJyYXkoJHNlcXVlbmNlKTsKICAgICAgICAgICAgJGZpcnN0ID0gJHNbMF07CiAgICAgICAgICAgICRsZW4gPSBjb3VudCgkcyk7CiAgICAgICAgfSBlbHNlIHsgICAgCiAgICAgICAgICAgICRmaXJzdCA9ICRzZXF1ZW5jZVswXTsKICAgICAgICAgICAgJGxlbiA9IHN0cmxlbigkc2VxdWVuY2UpOwogICAgICAgIH0KICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5tYXBbJGZpcnN0XSkpIHsKICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAibWF4TGVuIiA9PiAkbGVuLAogICAgICAgICAgICAgICAgIm1hcCIgPT4gYXJyYXkoJHNlcXVlbmNlKQogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5tYXBbJGZpcnN0XVsibWFwIl1bXSA9ICRzZXF1ZW5jZTsKICAgICAgICAgICAgJHRoaXMtPm1hcFskZmlyc3RdWyJtYXhMZW4iXSA9IG1heCgkdGhpcy0+bWFwWyRmaXJzdF1bIm1heExlbiJdLCAkbGVuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlbW92ZXMgYSBzZXF1ZW5jZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzZXF1ZW5jZSBTZXF1ZW5jZSB0byByZW1vdmUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVtb3ZlKCRzZXF1ZW5jZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmhhbmRsZUVuY29kaW5nKSB7CiAgICAgICAgICAgICRzID0gVXRpbHM6OnN0cmluZ1RvVVRGOEFycmF5KCRzZXF1ZW5jZSk7CiAgICAgICAgICAgICRmaXJzdCA9ICRzWzBdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmaXJzdCA9ICRzZXF1ZW5jZVswXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5tYXBbJGZpcnN0XSkpIHsKICAgICAgICAgICAgJGxlbiA9ICR0aGlzLT5oYW5kbGVFbmNvZGluZyA/IGNvdW50KCRzKSA6IHN0cmxlbigkc2VxdWVuY2UpOwogICAgICAgICAgICAkdGhpcy0+bWFwWyRmaXJzdF1bIm1hcCJdID0gYXJyYXlfZGlmZigKICAgICAgICAgICAgICAgICR0aGlzLT5tYXBbJGZpcnN0XVsibWFwIl0sIGFycmF5KCRzZXF1ZW5jZSkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCFjb3VudCgkdGhpcy0+bWFwWyRmaXJzdF1bIm1hcCJdKSkgewogICAgICAgICAgICAgICAgdW5zZXQoJHRoaXMtPm1hcFskZmlyc3RdKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5tYXBbJGZpcnN0XVsibWF4TGVuIl0gPT09ICRsZW4pIHsKICAgICAgICAgICAgICAgIC8vIFJlY2FsY3VsYXRlIHRoZSBtYXggbGVuZ3RoIGlmIG5lY2Vzc2FyeQogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm1hcFskZmlyc3RdWyJtYXAiXSBhcyAkbSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5tYXBbJGZpcnN0XVsibWF4TGVuIl0gPSBtYXgoCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5tYXBbJGZpcnN0XVsibWF4TGVuIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbigkbSkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgbWF0Y2guIEl0IHJldHVybnMgYW4gYXJyYXkgd2hlcmUgdGhlIGZpcnN0IGVsZW1lbnQgaXMgdGhlCiAgICAgKiBudW1iZXIgb2YgY29uc3VtZWQgY2hhcmFjdGVycyBhbmQgdGhlIHNlY29uZCBlbGVtZW50IGlzIHRoZSBtYXRjaC4gSWYKICAgICAqIG5vIG1hdGNoIGlzIGZvdW5kIGl0IHJldHVybnMgbnVsbC4KICAgICAqIAogICAgICogQHBhcmFtIFNjYW5uZXIgICAkc2Nhbm5lciAgICBTY2FubmVyIGluc3RhbmNlCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICRpbmRleCAgICAgIEN1cnJlbnQgaW5kZXgKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJGNoYXIgICAgICAgQ3VycmVudCBjaGFyYWN0ZXIKICAgICAqIAogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXRjaCgkc2Nhbm5lciwgJGluZGV4LCAkY2hhcikKICAgIHsKICAgICAgICAkY29uc3VtZWQgPSAxOwogICAgICAgICRiZXN0TWF0Y2ggPSBudWxsOwogICAgICAgIGlmIChpc3NldCgkdGhpcy0+bWFwWyRjaGFyXSkpIHsKICAgICAgICAgICAgLy9JZiB0aGUgY2hhcmFjdGVyIGlzIHByZXNlbnQgaW4gdGhlIG1hcCBhbmQgaXQgaGFzIGEgbWF4IGxlbmd0aCBvZgogICAgICAgICAgICAvLzEsIG1hdGNoIGltbWVkaWF0ZWx5CiAgICAgICAgICAgIGlmICgkdGhpcy0+bWFwWyRjaGFyXVsibWF4TGVuIl0gPT09IDEpIHsKICAgICAgICAgICAgICAgICRiZXN0TWF0Y2ggPSBhcnJheSgkY29uc3VtZWQsICRjaGFyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vT3RoZXJ3aXNlIGNvbnN1bWUgYSBudW1iZXIgb2YgY2hhcmFjdGVycyBlcXVhbCB0byB0aGUgbWF4CiAgICAgICAgICAgICAgICAvL2xlbmd0aCBhbmQgZmluZCB0aGUgbG9uZ2VzdCBtYXRjaAogICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICRjaGFyOwogICAgICAgICAgICAgICAgJG1hcCA9ICR0aGlzLT5tYXBbJGNoYXJdWyJtYXAiXTsKICAgICAgICAgICAgICAgICRtYXhMZW4gPSAkdGhpcy0+bWFwWyRjaGFyXVsibWF4TGVuIl07CiAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCRidWZmZXIsICRtYXApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRiZXN0TWF0Y2ggPSBhcnJheSgkY29uc3VtZWQsICRidWZmZXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbmV4dENoYXIgPSAkc2Nhbm5lci0+Y2hhckF0KCRpbmRleCArICRjb25zdW1lZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRuZXh0Q2hhciA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkbmV4dENoYXI7CiAgICAgICAgICAgICAgICAgICAgJGNvbnN1bWVkKys7CiAgICAgICAgICAgICAgICB9IHdoaWxlICgkY29uc3VtZWQgPD0gJG1heExlbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRiZXN0TWF0Y2g7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBTeW50YXggZXhjZXB0aW9uIGNsYXNzLiBTeW50YXggZXJyb3JzIGluIHRoZSBzb3VyY2UgYXJlIHRocm93biB1c2luZyB0aGlzCiAqIHVzaW5nIHRoaXMgZXhjZXB0aW9uIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBFeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKICAgIC8qKgogICAgICogRXJyb3IgcG9zaXRpb24KICAgICAqIAogICAgICogQHZhciBcUGVhc3RcU3ludGF4XFBvc2l0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcG9zaXRpb247CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgIEVycm9yIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBcUGVhc3RcU3ludGF4XFBvc2l0aW9uICRwb3NpdGlvbiBFcnJvciBwb3NpdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG1lc3NhZ2UsIFBvc2l0aW9uICRwb3NpdGlvbikKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCRtZXNzYWdlKTsKICAgICAgICAkdGhpcy0+cG9zaXRpb24gPSAkcG9zaXRpb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXJyb3IgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiBcUGVhc3RcU3ludGF4XFBvc2l0aW9uIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UG9zaXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cG9zaXRpb247CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxFUzIwMTg7CgovKioKICogRVMyMDE4IGZlYXR1cmVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEZlYXR1cmVzIGV4dGVuZHMgXFBlYXN0XFN5bnRheFxFUzIwMTdcRmVhdHVyZXMKewogICAgLyoqCiAgICAgKiBBc3luYyBpdGVyYXRpb24gYW5kIGdlbmVyYXRvcnMKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRhc3luY0l0ZXJhdGlvbkdlbmVyYXRvcnMgPSB0cnVlOwoKICAgIC8qKgogICAgICogUmVzdC9zcHJlYWQgcHJvcGVydGllcwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHJlc3RTcHJlYWRQcm9wZXJ0aWVzID0gdHJ1ZTsKCiAgICAvKioKICAgICAqIFNraXAgZXNjYXBlIHNlcXVlbmNlcyBjaGVja3MgaW4gdGFnZ2VkIHRlbXBsYXRlCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHB1YmxpYyAkc2tpcEVzY2FwZVNlcUNoZWNrSW5UYWdnZWRUZW1wbGF0ZXMgPSB0cnVlOwp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXg7CgovKioKICogUGFyc2VyIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBhcnNlciBleHRlbmRzIFBhcnNlckFic3RyYWN0CnsKICAgIHVzZSBKU1hcUGFyc2VyOwogICAgCiAgICAvL0lkZW50aWZpZXIgcGFyc2luZyBtb2RlIGNvbnN0YW50cwogICAgLyoqCiAgICAgKiBFdmVyeXRoaW5nIGlzIGFsbG93ZWQgYXMgaWRlbnRpZmllciwgaW5jbHVkaW5nIGtleXdvcmRzLCBudWxsIGFuZCBib29sZWFucwogICAgICovCiAgICBjb25zdCBJRF9BTExPV19BTEwgPSAxOwogICAgCiAgICAvKioKICAgICAqIEtleXdvcmRzLCBudWxsIGFuZCBib29sZWFucyBhcmUgbm90IGFsbG93ZWQgaW4gYW55IHNpdHVhdGlvbgogICAgICovCiAgICBjb25zdCBJRF9BTExPV19OT1RISU5HID0gMjsKICAgIAogICAgLyoqCiAgICAgKiBLZXl3b3JkcywgbnVsbCBhbmQgYm9vbGVhbnMgYXJlIG5vdCBhbGxvd2VkIGluIGFueSBzaXR1YXRpb24sIGZ1dHVyZQogICAgICogcmVzZXJ2ZWQgd29yZHMgYXJlIGFsbG93ZWQgaWYgbm90IGluIHN0cmljdCBtb2RlLiBLZXl3b3JkcyB0aGF0IGRlcGVuZCBvbgogICAgICogcGFyc2VyIGNvbnRleHQgYXJlIGV2YWx1YXRlZCBvbmx5IGlmIHRoZSBwYXJzZXIgY29udGV4dCBhbGxvd3MgdGhlbS4KICAgICAqLwogICAgY29uc3QgSURfTUlYRUQgPSAzOwogICAgCiAgICAvKioKICAgICAqIEJpbmRpbmcgaWRlbnRpZmllciBwYXJzaW5nIHJ1bGUKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgJGJpbmRpbmdJZGVudGlmaWVyID0gc2VsZjo6SURfTUlYRUQ7CiAgICAKICAgIC8qKgogICAgICogTGFiZWxsZWQgaWRlbnRpZmllciBwYXJzaW5nIHJ1bGUKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgJGxhYmVsbGVkSWRlbnRpZmllciA9IHNlbGY6OklEX01JWEVEOwogICAgCiAgICAvKioKICAgICAqIElkZW50aWZpZXIgcmVmZXJlbmNlIHBhcnNpbmcgcnVsZQogICAgICogCiAgICAgKiBAdmFyIGludCAKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyAkaWRlbnRpZmllclJlZmVyZW5jZSA9IHNlbGY6OklEX01JWEVEOwogICAgCiAgICAvKioKICAgICAqIElkZW50aWZpZXIgbmFtZSBwYXJzaW5nIHJ1bGUKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgJGlkZW50aWZpZXJOYW1lID0gc2VsZjo6SURfQUxMT1dfQUxMOwogICAgCiAgICAvKioKICAgICAqIEltcG9ydGVkIGJpbmRpbmcgcGFyc2luZyBydWxlCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgc3RhdGljICRpbXBvcnRlZEJpbmRpbmcgPSBzZWxmOjpJRF9BTExPV19OT1RISU5HOwogICAgCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3JzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXNzaWdubWVudE9wZXJhdG9ycyA9IGFycmF5KAogICAgICAgICI9IiwgIis9IiwgIi09IiwgIio9IiwgIi89IiwgIiU9IiwgIjw8PSIsICI+Pj0iLCAiPj4+PSIsICImPSIsICJePSIsCiAgICAgICAgInw9IiwgIioqPSIsICImJj0iLCAifHw9IiwgIj8/PSIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTG9naWNhbCBhbmQgYmluYXJ5IG9wZXJhdG9ycwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxvZ2ljYWxCaW5hcnlPcGVyYXRvcnMgPSBhcnJheSgKICAgICAgICAiPz8iID0+IDAsCiAgICAgICAgInx8IiA9PiAwLAogICAgICAgICImJiIgPT4gMSwKICAgICAgICAifCIgPT4gMiwKICAgICAgICAiXiIgPT4gMywKICAgICAgICAiJiIgPT4gNCwKICAgICAgICAiPT09IiA9PiA1LCAiIT09IiA9PiA1LCAiPT0iID0+IDUsICIhPSIgPT4gNSwKICAgICAgICAiPD0iID0+IDYsICI+PSIgPT4gNiwgIjwiID0+IDYsICI+IiA9PiA2LAogICAgICAgICJpbnN0YW5jZW9mIiA9PiA2LCAiaW4iID0+IDYsCiAgICAgICAgIj4+PiIgPT4gNywgIjw8IiA9PiA3LCAiPj4iID0+IDcsCiAgICAgICAgIisiID0+IDgsICItIiA9PiA4LAogICAgICAgICIqIiA9PiA5LCAiLyIgPT4gOSwgIiUiID0+IDksCiAgICAgICAgIioqIiA9PiAxMAogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBVbmFyeSBvcGVyYXRvcnMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICR1bmFyeU9wZXJhdG9ycyA9IGFycmF5KAogICAgICAgICJkZWxldGUiLCAidm9pZCIsICJ0eXBlb2YiLCAiKysiLCAiLS0iLCAiKyIsICItIiwgIn4iLCAiISIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogUG9zdGZpeCBvcGVyYXRvcnMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwb3N0Zml4T3BlcmF0b3JzID0gYXJyYXkoIi0tIiwgIisrIik7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2Yga2V5d29yZHMgdGhhdCBkZXBlbmRzIG9uIGEgY29udGV4dCBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnRleHRLZXl3b3JkcyA9IGFycmF5KAogICAgICAgICJ5aWVsZCIgPT4gImFsbG93WWllbGQiLAogICAgICAgICJhd2FpdCIgPT4gImFsbG93QXdhaXQiCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHBhcnNlciBjb250ZXh0CiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaW5pdENvbnRleHQoKQogICAgewogICAgICAgICRjb250ZXh0ID0gYXJyYXkoCiAgICAgICAgICAgICJhbGxvd1JldHVybiIgPT4gZmFsc2UsCiAgICAgICAgICAgICJhbGxvd0luIiA9PiBmYWxzZSwKICAgICAgICAgICAgImFsbG93WWllbGQiID0+IGZhbHNlLAogICAgICAgICAgICAiYWxsb3dBd2FpdCIgPT4gZmFsc2UKICAgICAgICApOwogICAgICAgIC8vSWYgYXN5bmMvYXdhaXQgaXMgbm90IGVuYWJsZWQgcmVtb3ZlIHRoZQogICAgICAgIC8vcmVsYXRpdmUgY29udGV4dCBwcm9wZXJ0aWVzCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQpIHsKICAgICAgICAgICAgdW5zZXQoJGNvbnRleHRbImFsbG93QXdhaXQiXSk7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb250ZXh0S2V5d29yZHNbImF3YWl0Il0pOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29udGV4dCA9IChvYmplY3QpICRjb250ZXh0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBvc3QgaW5pdGlhbGl6ZSBvcGVyYXRpb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcG9zdEluaXQoKQogICAgewogICAgICAgIC8vUmVtb3ZlIGV4cG9uZW50YXRpb24gb3BlcmF0b3IgaWYgdGhlIGZlYXR1cmUKICAgICAgICAvL2lzIG5vdCBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmV4cG9uZW50aWF0aW9uT3BlcmF0b3IpIHsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoCiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzaWdubWVudE9wZXJhdG9ycywKICAgICAgICAgICAgICAgICIqKj0iCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5sb2dpY2FsQmluYXJ5T3BlcmF0b3JzWyIqKiJdKTsKICAgICAgICB9CgogICAgICAgIC8vUmVtb3ZlIGNvYWxlc2Npbmcgb3BlcmF0b3IgaWYgdGhlIGZlYXR1cmUKICAgICAgICAvL2lzIG5vdCBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmNvYWxlc2NpbmdPcGVyYXRvcikgewogICAgICAgICAgICB1bnNldCgkdGhpcy0+bG9naWNhbEJpbmFyeU9wZXJhdG9yc1siPz8iXSk7CiAgICAgICAgfQoKICAgICAgICAvL1JlbW92ZSBsb2dpY2FsIGFzc2lnbm1lbnQgb3BlcmF0b3JzIGlmIHRoZQogICAgICAgIC8vZmVhdHVyZSBpcyBub3QgZW5hYmxlZAogICAgICAgIGlmICghJHRoaXMtPmZlYXR1cmVzLT5sb2dpY2FsQXNzaWdubWVudE9wZXJhdG9ycykgewogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgiJiY9IiwgInx8PSIsICI/Pz0iKSBhcyAkb3ApIHsKICAgICAgICAgICAgICAgIFV0aWxzOjpyZW1vdmVBcnJheVZhbHVlKAogICAgICAgICAgICAgICAgICAgICR0aGlzLT5hc3NpZ25tZW50T3BlcmF0b3JzLAogICAgICAgICAgICAgICAgICAgICRvcAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIHNvdXJjZQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcUHJvZ3JhbQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2UoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c291cmNlVHlwZSA9PT0gXFBlYXN0XFBlYXN0OjpTT1VSQ0VfVFlQRV9NT0RVTEUpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUodHJ1ZSk7CiAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlTW9kdWxlSXRlbUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudExpc3QodHJ1ZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICJQcm9ncmFtIiwgJGJvZHkgPyAkYm9keSA6ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpCiAgICAgICAgKTsKICAgICAgICAkbm9kZS0+c2V0U291cmNlVHlwZSgkdGhpcy0+c291cmNlVHlwZSk7CiAgICAgICAgaWYgKCRib2R5KSB7CiAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICB9CiAgICAgICAgJHByb2dyYW0gPSAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCkpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0V4ZWN1dGUgc2Nhbm5lciBlbmQgb3BlcmF0aW9ucwogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lRW5kKCk7CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBFbmRQYXJzaW5nIGV2ZW50IGFuZCBwYXNzIHRoZSByZXN1bHRpbmcgcHJvZ3JhbSBub2RlIGFzCiAgICAgICAgLy9ldmVudCBkYXRhCiAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICJFbmRQYXJzaW5nIiwgYXJyYXkoJHByb2dyYW0pCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJHByb2dyYW07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29udmVydHMgYW4gZXhwcmVzc2lvbiBub2RlIHRvIGEgcGF0dGVybiBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgJG5vZGUgVGhlIG5vZGUgdG8gY29udmVydAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhwcmVzc2lvblRvUGF0dGVybigkbm9kZSkKICAgIHsKICAgICAgICBpZiAoJG5vZGUgaW5zdGFuY2VvZiBOb2RlXEFycmF5RXhwcmVzc2lvbikgewogICAgICAgICAgICAKICAgICAgICAgICAgJGxvYyA9ICRub2RlLT5nZXRMb2NhdGlvbigpOwogICAgICAgICAgICAkZWxlbXMgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkbm9kZS0+Z2V0RWxlbWVudHMoKSBhcyAkZWxlbSkgewogICAgICAgICAgICAgICAgJGVsZW1zW10gPSAkdGhpcy0+ZXhwcmVzc2lvblRvUGF0dGVybigkZWxlbSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAkcmV0Tm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBcnJheVBhdHRlcm4iLCAkbG9jLT5nZXRTdGFydCgpKTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldEVsZW1lbnRzKCRlbGVtcyk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHJldE5vZGUsICRsb2MtPmdldEVuZCgpKTsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlaWYgKCRub2RlIGluc3RhbmNlb2YgTm9kZVxPYmplY3RFeHByZXNzaW9uKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbG9jID0gJG5vZGUtPmdldExvY2F0aW9uKCk7CiAgICAgICAgICAgICRwcm9wcyA9IGFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRub2RlLT5nZXRQcm9wZXJ0aWVzKCkgYXMgJHByb3ApIHsKICAgICAgICAgICAgICAgICRwcm9wc1tdID0gJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJHByb3ApOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgJHJldE5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiT2JqZWN0UGF0dGVybiIsICRsb2MtPmdldFN0YXJ0KCkpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0UHJvcGVydGllcygkcHJvcHMpOwogICAgICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKCRyZXROb2RlLCAkbG9jLT5nZXRFbmQoKSk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkbm9kZSBpbnN0YW5jZW9mIE5vZGVcUHJvcGVydHkpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRsb2MgPSAkbm9kZS0+Z2V0TG9jYXRpb24oKTsKICAgICAgICAgICAgJHJldE5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICJBc3NpZ25tZW50UHJvcGVydHkiLCAkbG9jLT5nZXRTdGFydCgpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIC8vIElmIGl0J3MgYSBzaG9ydGhhbmQgcHJvcGVydHkgY29udmVydCB0aGUgdmFsdWUgdG8gYW4gYXNzaWdubWVudAogICAgICAgICAgICAvLyBwYXR0ZXJuIGlmIG5lY2Vzc2FyeQogICAgICAgICAgICAkdmFsdWUgPSAkbm9kZS0+Z2V0VmFsdWUoKTsKICAgICAgICAgICAgJGtleSA9ICRub2RlLT5nZXRLZXkoKTsKICAgICAgICAgICAgaWYgKCR2YWx1ZSAmJiAkbm9kZS0+Z2V0U2hvcnRoYW5kKCkgJiYKICAgICAgICAgICAgICAgICEkdmFsdWUgaW5zdGFuY2VvZiBOb2RlXEFzc2lnbm1lbnRFeHByZXNzaW9uICYmCiAgICAgICAgICAgICAgICAoISR2YWx1ZSBpbnN0YW5jZW9mIE5vZGVcSWRlbnRpZmllciB8fCAoCiAgICAgICAgICAgICAgICAka2V5IGluc3RhbmNlb2YgTm9kZVxJZGVudGlmaWVyICYmICRrZXktPmdldE5hbWUoKSAhPT0gJHZhbHVlLT5nZXROYW1lKCkKICAgICAgICAgICAgICAgICkpKSB7CiAgICAgICAgICAgICAgICAkbG9jID0gJG5vZGUtPmdldExvY2F0aW9uKCk7CiAgICAgICAgICAgICAgICAkdmFsTm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBc3NpZ25tZW50UGF0dGVybiIsICRsb2MtPmdldFN0YXJ0KCkpOwogICAgICAgICAgICAgICAgJHZhbE5vZGUtPnNldExlZnQoJGtleSk7CiAgICAgICAgICAgICAgICAkdmFsTm9kZS0+c2V0UmlnaHQoJHZhbHVlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHZhbE5vZGUsICRsb2MtPmdldEVuZCgpKTsKICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR2YWxOb2RlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0VmFsdWUoJHZhbHVlKTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldEtleSgka2V5KTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldE1ldGhvZCgkbm9kZS0+Z2V0TWV0aG9kKCkpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0U2hvcnRoYW5kKCRub2RlLT5nZXRTaG9ydGhhbmQoKSk7CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRDb21wdXRlZCgkbm9kZS0+Z2V0Q29tcHV0ZWQoKSk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJHJldE5vZGUsICRsb2MtPmdldEVuZCgpKTsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlaWYgKCRub2RlIGluc3RhbmNlb2YgTm9kZVxTcHJlYWRFbGVtZW50KSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbG9jID0gJG5vZGUtPmdldExvY2F0aW9uKCk7CiAgICAgICAgICAgICRyZXROb2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlJlc3RFbGVtZW50IiwgJGxvYy0+Z2V0U3RhcnQoKSk7CiAgICAgICAgICAgICRyZXROb2RlLT5zZXRBcmd1bWVudCgKICAgICAgICAgICAgICAgICR0aGlzLT5leHByZXNzaW9uVG9QYXR0ZXJuKCRub2RlLT5nZXRBcmd1bWVudCgpKQogICAgICAgICAgICApOwogICAgICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKCRyZXROb2RlLCAkbG9jLT5nZXRFbmQoKSk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkbm9kZSBpbnN0YW5jZW9mIE5vZGVcQXNzaWdubWVudEV4cHJlc3Npb24pIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRsb2MgPSAkbm9kZS0+Z2V0TG9jYXRpb24oKTsKICAgICAgICAgICAgJHJldE5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXNzaWdubWVudFBhdHRlcm4iLCAkbG9jLT5nZXRTdGFydCgpKTsKICAgICAgICAgICAgJHJldE5vZGUtPnNldExlZnQoJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJG5vZGUtPmdldExlZnQoKSkpOwogICAgICAgICAgICAkcmV0Tm9kZS0+c2V0UmlnaHQoJG5vZGUtPmdldFJpZ2h0KCkpOwogICAgICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKCRyZXROb2RlLCAkbG9jLT5nZXRFbmQoKSk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXROb2RlID0gJG5vZGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0Tm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdGF0ZW1lbnQgbGlzdAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkcGFyc2VEaXJlY3RpdmVQcm9sb2d1ZXMgVHJ1ZSB0byBwYXJzZSBkaXJlY3RpdmUgcHJvbG9ndWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnRMaXN0KAogICAgICAgICRwYXJzZURpcmVjdGl2ZVByb2xvZ3VlcyA9IGZhbHNlCiAgICApIHsKICAgICAgICAkaXRlbXMgPSBhcnJheSgpOwogICAgICAgIAogICAgICAgIC8vR2V0IGRpcmVjdGl2ZSBwcm9sb2d1ZXMgYW5kIGNoZWNrIGlmIHN0cmljdCBtb2RlIGlzIHByZXNlbnQKICAgICAgICBpZiAoJHBhcnNlRGlyZWN0aXZlUHJvbG9ndWVzKSB7CiAgICAgICAgICAgICRvbGRTdHJpY3RNb2RlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKTsKICAgICAgICAgICAgaWYgKCRkaXJlY3RpdmVzID0gJHRoaXMtPnBhcnNlRGlyZWN0aXZlUHJvbG9ndWVzKCkpIHsKICAgICAgICAgICAgICAgICRpdGVtcyA9IGFycmF5X21lcmdlKCRpdGVtcywgJGRpcmVjdGl2ZXNbMF0pOwogICAgICAgICAgICAgICAgLy9JZiAidXNlIHN0cmljdCIgaXMgcHJlc2VudCBlbmFibGUgc2Nhbm5lciBzdHJpY3QgbW9kZQogICAgICAgICAgICAgICAgaWYgKGluX2FycmF5KCJ1c2Ugc3RyaWN0IiwgJGRpcmVjdGl2ZXNbMV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgd2hpbGUgKCRpdGVtID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50TGlzdEl0ZW0oKSkgewogICAgICAgICAgICAkaXRlbXNbXSA9ICRpdGVtOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0FwcGx5IHByZXZpb3VzIHN0cmljdCBtb2RlCiAgICAgICAgaWYgKCRwYXJzZURpcmVjdGl2ZVByb2xvZ3VlcykgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RyaWN0TW9kZSgkb2xkU3RyaWN0TW9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBjb3VudCgkaXRlbXMpID8gJGl0ZW1zIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzdGF0ZW1lbnQgbGlzdCBpdGVtCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxTdGF0ZW1lbnR8Tm9kZVxEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVN0YXRlbWVudExpc3RJdGVtKCkKICAgIHsKICAgICAgICBpZiAoJGRlY2xhcmF0aW9uID0gJHRoaXMtPnBhcnNlRGVjbGFyYXRpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGRlY2xhcmF0aW9uOwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VWYXJpYWJsZVN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlRW1wdHlTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUlmU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VCcmVha2FibGVTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUNvbnRpbnVlU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VCcmVha1N0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+Y29udGV4dC0+YWxsb3dSZXR1cm4gJiYgJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZVJldHVyblN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlV2l0aFN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlVGhyb3dTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZVRyeVN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlRGVidWdnZXJTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9IGVsc2VpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUxhYmVsbGVkU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0ZW1lbnQgPSAkdGhpcy0+cGFyc2VFeHByZXNzaW9uU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZURlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICBpZiAoJGRlY2xhcmF0aW9uID0gJHRoaXMtPnBhcnNlRnVuY3Rpb25PckdlbmVyYXRvckRlY2xhcmF0aW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRkZWNsYXJhdGlvbjsKICAgICAgICB9IGVsc2VpZiAoJGRlY2xhcmF0aW9uID0gJHRoaXMtPnBhcnNlQ2xhc3NEZWNsYXJhdGlvbigpKSB7CiAgICAgICAgICAgIHJldHVybiAkZGVjbGFyYXRpb247CiAgICAgICAgfSBlbHNlaWYgKAogICAgICAgICAgICAkZGVjbGFyYXRpb24gPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUxleGljYWxEZWNsYXJhdGlvbiIKICAgICAgICAgICAgKQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4gJGRlY2xhcmF0aW9uOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBicmVha2FibGUgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQnJlYWthYmxlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHN0YXRlbWVudCA9ICR0aGlzLT5wYXJzZUl0ZXJhdGlvblN0YXRlbWVudCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkc3RhdGVtZW50OwogICAgICAgIH0gZWxzZWlmICgkc3RhdGVtZW50ID0gJHRoaXMtPnBhcnNlU3dpdGNoU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRzdGF0ZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGJsb2NrIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQmxvY2tTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VCbG9jaygpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRzdGF0ZW1lbnRzID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50TGlzdCgpOwogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKSkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQmxvY2tTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgaWYgKCRzdGF0ZW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJHN0YXRlbWVudHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgbW9kdWxlIGl0ZW0gbGlzdAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZVtdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTW9kdWxlSXRlbUxpc3QoKQogICAgewogICAgICAgICRpdGVtcyA9IGFycmF5KCk7CiAgICAgICAgd2hpbGUgKCRpdGVtID0gJHRoaXMtPnBhcnNlTW9kdWxlSXRlbSgpKSB7CiAgICAgICAgICAgICRpdGVtc1tdID0gJGl0ZW07CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb3VudCgkaXRlbXMpID8gJGl0ZW1zIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gZW1wdHkgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxFbXB0eVN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUVtcHR5U3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKSkgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFbXB0eVN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgZGVidWdnZXIgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxEZWJ1Z2dlclN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZURlYnVnZ2VyU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImRlYnVnZ2VyIikpIHsKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRGVidWdnZXJTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gaWYgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxJZlN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUlmU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImlmIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJHRlc3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICAgICAoJGNvbnNlcXVlbnQgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKSkgfHwKICAgICAgICAgICAgICAgICAgICAoISR0aGlzLT5zY2FubmVyLT5nZXRTdHJpY3RNb2RlKCkgJiYKICAgICAgICAgICAgICAgICAgICAkY29uc2VxdWVudCA9ICR0aGlzLT5wYXJzZUZ1bmN0aW9uT3JHZW5lcmF0b3JEZWNsYXJhdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIklmU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb25zZXF1ZW50KCRjb25zZXF1ZW50KTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJlbHNlIikpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKCRhbHRlcm5hdGUgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKCEkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICRhbHRlcm5hdGUgPSAkdGhpcy0+cGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UKICAgICAgICAgICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEFsdGVybmF0ZSgkYWx0ZXJuYXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHRyeS1jYXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFRyeVN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVRyeVN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0cnkiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRibG9jayA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVHJ5U3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCbG9jaygkYmxvY2spOwoKICAgICAgICAgICAgICAgIGlmICgkaGFuZGxlciA9ICR0aGlzLT5wYXJzZUNhdGNoKCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SGFuZGxlcigkaGFuZGxlcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRmaW5hbGl6ZXIgPSAkdGhpcy0+cGFyc2VGaW5hbGx5KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RmluYWxpemVyKCRmaW5hbGl6ZXIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkaGFuZGxlciB8fCAkZmluYWxpemVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgY2F0Y2ggYmxvY2sgb2YgYSB0cnktY2F0Y2ggc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDYXRjaENsYXVzZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhdGNoKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImNhdGNoIikpIHsKCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkNhdGNoQ2xhdXNlIiwgJHRva2VuKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpKSB7CiAgICAgICAgICAgICAgICBpZiAoISgkcGFyYW0gPSAkdGhpcy0+cGFyc2VDYXRjaFBhcmFtZXRlcigpKSB8fAogICAgICAgICAgICAgICAgICAgICEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG5vZGUtPnNldFBhcmFtKCRwYXJhbSk7CiAgICAgICAgICAgIH0gZWxzZWlmICghJHRoaXMtPmZlYXR1cmVzLT5vcHRpb25hbENhdGNoQmluZGluZykgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoISgkYm9keSA9ICR0aGlzLT5wYXJzZUJsb2NrKCkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBjYXRjaCBwYXJhbWV0ZXIgb2YgYSBjYXRjaCBibG9jayBpbiBhIHRyeS1jYXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2F0Y2hQYXJhbWV0ZXIoKQogICAgewogICAgICAgIGlmICgkcGFyYW0gPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKSkgewogICAgICAgICAgICByZXR1cm4gJHBhcmFtOwogICAgICAgIH0gZWxzZWlmICgkcGFyYW0gPSAkdGhpcy0+cGFyc2VCaW5kaW5nUGF0dGVybigpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFyYW07CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGZpbmFsbHkgYmxvY2sgaW4gYSB0cnktY2F0Y2ggc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxCbG9ja1N0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZpbmFsbHkoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZmluYWxseSIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJGJsb2NrID0gJHRoaXMtPnBhcnNlQmxvY2soKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRibG9jazsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjb3VudGludWUgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDb250aW51ZVN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNvbnRpbnVlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImNvbnRpbnVlIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkNvbnRpbnVlU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+bm9MaW5lVGVybWluYXRvcnMoKSAmJgogICAgICAgICAgICAgICAgKCRsYWJlbCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokbGFiZWxsZWRJZGVudGlmaWVyKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGFiZWwoJGxhYmVsKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBicmVhayBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEJyZWFrU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQnJlYWtTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiYnJlYWsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQnJlYWtTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpICYmCiAgICAgICAgICAgICAgICAoJGxhYmVsID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRsYWJlbGxlZElkZW50aWZpZXIpKSkgewogICAgICAgICAgICAgICAgJG5vZGUtPnNldExhYmVsKCRsYWJlbCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI7Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcmV0dXJuIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcUmV0dXJuU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUmV0dXJuU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInJldHVybiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJSZXR1cm5TdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpKSB7CiAgICAgICAgICAgICAgICAkYXJndW1lbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkYXJndW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxhYmVsbGVkIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTGFiZWxlZFN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxhYmVsbGVkU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJGxhYmVsID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRsYWJlbGxlZElkZW50aWZpZXIsICI6IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI6Iik7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpKSB8fAogICAgICAgICAgICAgICAgKCRib2R5ID0gJHRoaXMtPnBhcnNlRnVuY3Rpb25PckdlbmVyYXRvckRlY2xhcmF0aW9uKAogICAgICAgICAgICAgICAgICAgIGZhbHNlLCBmYWxzZQogICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vTGFiZWxsZWQgZnVuY3Rpb25zIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSAKICAgICAgICAgICAgICAgIGlmICgkYm9keSBpbnN0YW5jZW9mIE5vZGVcRnVuY3Rpb25EZWNsYXJhdGlvbiAmJgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5nZXRTdHJpY3RNb2RlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAiTGFiZWxsZWQgZnVuY3Rpb25zIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkxhYmVsZWRTdGF0ZW1lbnQiLCAkbGFiZWwpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldExhYmVsKCRsYWJlbCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CgogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHRocm93IHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVGhyb3dTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VUaHJvd1N0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0aHJvdyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkgJiYKICAgICAgICAgICAgICAgICgkYXJndW1lbnQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVGhyb3dTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgd2l0aCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFdpdGhTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VXaXRoU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIndpdGgiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikgJiYKICAgICAgICAgICAgICAgICgkb2JqZWN0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIldpdGhTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldE9iamVjdCgkb2JqZWN0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzd2l0Y2ggc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxTd2l0Y2hTdGF0ZW1lbnR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTd2l0Y2hTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgic3dpdGNoIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJGRpc2NyaW1pbmFudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgKCRjYXNlcyA9ICR0aGlzLT5wYXJzZUNhc2VCbG9jaygpKSAhPT0gbnVsbAogICAgICAgICAgICApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTd2l0Y2hTdGF0ZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERpc2NyaW1pbmFudCgkZGlzY3JpbWluYW50KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDYXNlcygkY2FzZXMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgY29udGVudCBvZiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2VbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhc2VCbG9jaygpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRwYXJzZWRDYXNlc0FsbCA9IGFycmF5KAogICAgICAgICAgICAgICAgJHRoaXMtPnBhcnNlQ2FzZUNsYXVzZXMoKSwKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZURlZmF1bHRDbGF1c2UoKSwKICAgICAgICAgICAgICAgICR0aGlzLT5wYXJzZUNhc2VDbGF1c2VzKCkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAkY2FzZXMgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoJHBhcnNlZENhc2VzQWxsIGFzICRwYXJzZWRDYXNlcykgewogICAgICAgICAgICAgICAgICAgIGlmICgkcGFyc2VkQ2FzZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KCRwYXJzZWRDYXNlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYXNlcyA9IGFycmF5X21lcmdlKCRjYXNlcywgJHBhcnNlZENhc2VzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjYXNlc1tdID0gJHBhcnNlZENhc2VzOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRjYXNlczsKICAgICAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5wYXJzZURlZmF1bHRDbGF1c2UoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAiTXVsdGlwbGUgZGVmYXVsdCBjbGF1c2UgaW4gc3dpdGNoIHN0YXRlbWVudCIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGNhc2VzIGluIGEgc3dpdGNoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3dpdGNoQ2FzZVtdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2FzZUNsYXVzZXMoKQogICAgewogICAgICAgICRjYXNlcyA9IGFycmF5KCk7CiAgICAgICAgd2hpbGUgKCRjYXNlID0gJHRoaXMtPnBhcnNlQ2FzZUNsYXVzZSgpKSB7CiAgICAgICAgICAgICRjYXNlc1tdID0gJGNhc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb3VudCgkY2FzZXMpID8gJGNhc2VzIDogbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjYXNlIGluIGEgc3dpdGNoIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3dpdGNoQ2FzZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNhc2VDbGF1c2UoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiY2FzZSIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCR0ZXN0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpCiAgICAgICAgICAgICkgewoKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlN3aXRjaENhc2UiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFRlc3QoJHRlc3QpOwoKICAgICAgICAgICAgICAgIGlmICgkY29uc2VxdWVudCA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudExpc3QoKSkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb25zZXF1ZW50KCRjb25zZXF1ZW50KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGRlZmF1bHQgY2FzZSBpbiBhIHN3aXRjaCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN3aXRjaENhc2V8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEZWZhdWx0Q2xhdXNlKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImRlZmF1bHQiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI6IikpIHsKCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTd2l0Y2hDYXNlIiwgJHRva2VuKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJGNvbnNlcXVlbnQgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnRMaXN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBleHByZXNzaW9uIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcRXhwcmVzc2lvblN0YXRlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUV4cHJlc3Npb25TdGF0ZW1lbnQoKQogICAgewogICAgICAgICRsb29rYWhlYWRUb2tlbnMgPSBhcnJheSgieyIsICJmdW5jdGlvbiIsICJjbGFzcyIsIGFycmF5KCJsZXQiLCAiWyIpKTsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0KSB7CiAgICAgICAgICAgIGFycmF5X3NwbGljZSgKICAgICAgICAgICAgICAgICRsb29rYWhlYWRUb2tlbnMsIDMsIDAsCiAgICAgICAgICAgICAgICBhcnJheShhcnJheSgiYXN5bmMiLCB0cnVlKSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoJGxvb2thaGVhZFRva2VucywgdHJ1ZSkgJiYKICAgICAgICAgICAgJGV4cHJlc3Npb24gPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICkKICAgICAgICApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFeHByZXNzaW9uU3RhdGVtZW50IiwgJGV4cHJlc3Npb24pOwogICAgICAgICAgICAkbm9kZS0+c2V0RXhwcmVzc2lvbigkZXhwcmVzc2lvbik7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgZG8td2hpbGUgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxEb1doaWxlU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRG9XaGlsZVN0YXRlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJkbyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgid2hpbGUiKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCR0ZXN0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRG9XaGlsZVN0YXRlbWVudCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGVzdCgkdGVzdCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKTsKICAgICAgICAgICAgICAgIHJldHVybiAkbm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB3aGlsZSBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFdoaWxlU3RhdGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlV2hpbGVTdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgid2hpbGUiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikgJiYKICAgICAgICAgICAgICAgICgkdGVzdCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIldoaWxlU3RhdGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBmb3IodmFyIC4uLikgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBUb2tlbiAkZm9yVG9rZW4gVG9rZW4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgImZvciIga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvclZhclN0YXRlbWVudCgkZm9yVG9rZW4pCiAgICB7CiAgICAgICAgaWYgKCEoJHZhclRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInZhciIpKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwoKICAgICAgICBpZiAoKCRkZWNsID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IGZhbHNlKSwgInBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QiCiAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICgkdmFyRW5kUG9zaXRpb24gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKSkgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKQogICAgICAgICkgewoKICAgICAgICAgICAgJGluaXQgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICJWYXJpYWJsZURlY2xhcmF0aW9uIiwgJHZhclRva2VuCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRpbml0LT5zZXRLaW5kKCRpbml0OjpLSU5EX1ZBUik7CiAgICAgICAgICAgICRpbml0LT5zZXREZWNsYXJhdGlvbnMoJGRlY2wpOwogICAgICAgICAgICAkaW5pdCA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJGluaXQsICR2YXJFbmRQb3NpdGlvbik7CgogICAgICAgICAgICAkdGVzdCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CgogICAgICAgICAgICAgICAgJHVwZGF0ZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvclN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEluaXQoJGluaXQpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VXBkYXRlKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CgogICAgICAgICAgICBpZiAoJGRlY2wgPSAkdGhpcy0+cGFyc2VGb3JCaW5kaW5nKCkpIHsKCiAgICAgICAgICAgICAgICAkaW5pdCA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5mb3JJbkluaXRpYWxpemVyICYmCiAgICAgICAgICAgICAgICAgICAgJGRlY2wtPmdldElkKCktPmdldFR5cGUoKSA9PT0gIklkZW50aWZpZXIiKSB7CiAgICAgICAgICAgICAgICAgICAgJGluaXQgPSAkdGhpcy0+cGFyc2VJbml0aWFsaXplcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkaW5pdCkgewogICAgICAgICAgICAgICAgICAgICRkZWNsLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgICAgICAgICAkZGVjbC0+c2V0RW5kUG9zaXRpb24oJGluaXQtPmdldExvY2F0aW9uKCktPmdldEVuZCgpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkbGVmdCA9ICR0aGlzLT5jcmVhdGVOb2RlKCJWYXJpYWJsZURlY2xhcmF0aW9uIiwgJHZhclRva2VuKTsKICAgICAgICAgICAgICAgICRsZWZ0LT5zZXRLaW5kKCRsZWZ0OjpLSU5EX1ZBUik7CiAgICAgICAgICAgICAgICAkbGVmdC0+c2V0RGVjbGFyYXRpb25zKGFycmF5KCRkZWNsKSk7CiAgICAgICAgICAgICAgICAkbGVmdCA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJGxlZnQpOwoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiaW4iKSkgewoKICAgICAgICAgICAgICAgICAgICBpZiAoJGluaXQgJiYgJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZvci1pbiB2YXJpYWJsZSBpbml0aWFsaXplciBub3QgYWxsb3dlZCBpbiAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpY3QgbW9kZSIKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICgoJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9ySW5TdGF0ZW1lbnQiLCAkZm9yVG9rZW4KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldExlZnQoJGxlZnQpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCEkaW5pdCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgib2YiKSkgewoKICAgICAgICAgICAgICAgICAgICBpZiAoKCRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgICAgICkgewoKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGb3JPZlN0YXRlbWVudCIsICRmb3JUb2tlbgogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkbGVmdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRSaWdodCgkcmlnaHQpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBmb3IobGV0IC4uLikgb3IgZm9yKGNvbnN0IC4uLikgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBUb2tlbiAkZm9yVG9rZW4gVG9rZW4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgImZvciIga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvckxldENvbnN0U3RhdGVtZW50KCRmb3JUb2tlbikKICAgIHsKICAgICAgICAkYWZ0ZXJCcmFja2V0U3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICBpZiAoISgkaW5pdCA9ICR0aGlzLT5wYXJzZUZvckRlY2xhcmF0aW9uKCkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbiIpKSB7CiAgICAgICAgICAgIGlmICgoJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAkYm9keSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudCgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJGb3JJblN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkaW5pdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgib2YiKSkgewogICAgICAgICAgICBpZiAoKCRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikgJiYKICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvck9mU3RhdGVtZW50IiwgJGZvclRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRpbml0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRSaWdodCgkcmlnaHQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkYWZ0ZXJCcmFja2V0U3RhdGUpOwogICAgICAgICAgICBpZiAoJGluaXQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IGZhbHNlKSwgInBhcnNlTGV4aWNhbERlY2xhcmF0aW9uIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJHRlc3QgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICR1cGRhdGUgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvclN0YXRlbWVudCIsICRmb3JUb2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFRlc3QoJHRlc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VXBkYXRlKCR1cGRhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGZvciBzdGF0ZW1lbnQgdGhhdCBkb2VzIG5vdCBzdGFydCB3aXRoIHZhciwgbGV0IG9yIGNvbnN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBUb2tlbiAkZm9yVG9rZW4gVG9rZW4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgImZvciIga2V5d29yZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvck5vdFZhckxldENvbnN0U3RhdGVtZW50KCRmb3JUb2tlbikKICAgIHsKICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICAkbm90QmVmb3JlU0IgPSAhJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KGFycmF5KCJsZXQiLCAiWyIpKSwgdHJ1ZSk7CiAgICAgICAgCiAgICAgICAgaWYgKCRub3RCZWZvcmVTQiAmJgogICAgICAgICAgICAoKCRpbml0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IGZhbHNlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgKSkgfHwgdHJ1ZSkgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKQogICAgICAgICkgewogICAgICAgIAogICAgICAgICAgICAkdGVzdCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkdXBkYXRlID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRm9yU3RhdGVtZW50IiwgJGZvclRva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SW5pdCgkaW5pdCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFRlc3QoJHRlc3QpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRVcGRhdGUoJHVwZGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICAgICAgJG5vdEJlZm9yZUxldCA9ICEkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoImxldCIpKTsKICAgICAgICAgICAgJGxlZnQgPSAkdGhpcy0+cGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKCk7CgogICAgICAgICAgICBpZiAoJGxlZnQgJiYgJGxlZnQtPmdldFR5cGUoKSA9PT0gIkNoYWluRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoCiAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiBsZWZ0LWhhbmQgc2lkZSIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRsZWZ0ID0gJHRoaXMtPmV4cHJlc3Npb25Ub1BhdHRlcm4oJGxlZnQpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRub3RCZWZvcmVTQiAmJiAkbGVmdCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiaW4iKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoKCRyaWdodCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlU3RhdGVtZW50KCkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkZvckluU3RhdGVtZW50IiwgJGZvclRva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkbGVmdCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFJpZ2h0KCRyaWdodCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRub3RCZWZvcmVMZXQgJiYgJGxlZnQgJiYgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIm9mIikpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCgkcmlnaHQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAgICAgJGJvZHkgPSAkdGhpcy0+cGFyc2VTdGF0ZW1lbnQoKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRm9yT2ZTdGF0ZW1lbnQiLCAkZm9yVG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRsZWZ0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgZG8td2hpbGUsIHdoaWxlLCBmb3IsIGZvci1pbiBhbmQgZm9yLW9mIHN0YXRlbWVudHMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VJdGVyYXRpb25TdGF0ZW1lbnQoKQogICAgewogICAgICAgIGlmICgkbm9kZSA9ICR0aGlzLT5wYXJzZVdoaWxlU3RhdGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRub2RlOwogICAgICAgIH0gZWxzZWlmICgkbm9kZSA9ICR0aGlzLT5wYXJzZURvV2hpbGVTdGF0ZW1lbnQoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgfSBlbHNlaWYgKCRzdGFydEZvclRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImZvciIpKSB7CgogICAgICAgICAgICAkZm9yQXdhaXQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+YXN5bmNJdGVyYXRpb25HZW5lcmF0b3JzICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y29udGV4dC0+YWxsb3dBd2FpdCAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImF3YWl0IikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkZm9yQXdhaXQgPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJiAoCiAgICAgICAgICAgICAgICAoJG5vZGUgPSAkdGhpcy0+cGFyc2VGb3JWYXJTdGF0ZW1lbnQoJHN0YXJ0Rm9yVG9rZW4pKSB8fAogICAgICAgICAgICAgICAgKCRub2RlID0gJHRoaXMtPnBhcnNlRm9yTGV0Q29uc3RTdGF0ZW1lbnQoJHN0YXJ0Rm9yVG9rZW4pKSB8fAogICAgICAgICAgICAgICAgKCRub2RlID0gJHRoaXMtPnBhcnNlRm9yTm90VmFyTGV0Q29uc3RTdGF0ZW1lbnQoJHN0YXJ0Rm9yVG9rZW4pKSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICBpZiAoJGZvckF3YWl0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkbm9kZSBpbnN0YW5jZW9mIE5vZGVcRm9yT2ZTdGF0ZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFzeW5jIGl0ZXJhdGlvbiBpcyBhbGxvd2VkIG9ubHkgd2l0aCBmb3Itb2Ygc3RhdGVtZW50cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3RhcnRGb3JUb2tlbi0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXdhaXQodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGFuIGFzeW5jIGZ1bmN0aW9uIGNhbiBzdGFydCBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uLiBSZXR1cm5zCiAgICAgKiB0aGUgYXN5bmMgdG9rZW4gb3IgbnVsbCBpZiBub3QgZm91bmQKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkY2hlY2tGbiBJZiBmYWxzZSBpdCB3b24ndCBjaGVjayBpZiB0aGUgYXN5bmMga2V5d29yZCBpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgZm9sbG93ZWQgYnkgImZ1bmN0aW9uIgogICAgICoKICAgICAqIEByZXR1cm4gVG9rZW4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNoZWNrQXN5bmNGdW5jdGlvblN0YXJ0KCRjaGVja0ZuID0gdHJ1ZSkKICAgIHsKICAgICAgICByZXR1cm4gKCRhc3luY1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCkpICYmCiAgICAgICAgJGFzeW5jVG9rZW4tPmdldFZhbHVlKCkgPT09ICJhc3luYyIgJiYKICAgICAgICAoCiAgICAgICAgICAgICEkY2hlY2tGbiB8fAogICAgICAgICAgICAoKCRuZXh0VG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0TmV4dFRva2VuKCkpICYmCiAgICAgICAgICAgICAgICAkbmV4dFRva2VuLT5nZXRWYWx1ZSgpID09PSAiZnVuY3Rpb24iKQogICAgICAgICkgJiYKICAgICAgICAkdGhpcy0+c2Nhbm5lci0+bm9MaW5lVGVybWluYXRvcnModHJ1ZSkgPwogICAgICAgICAgICAkYXN5bmNUb2tlbiA6CiAgICAgICAgICAgIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGZ1bmN0aW9uIG9yIGdlbmVyYXRvciBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkZGVmYXVsdCAgICAgICAgRGVmYXVsdCBtb2RlCiAgICAgKiBAcGFyYW0gYm9vbCAkYWxsb3dHZW5lcmF0b3IgVHJ1ZSB0byBhbGxvdyBwYXJzaW5nIG9mIGdlbmVyYXRvcnMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEZ1bmN0aW9uRGVjbGFyYXRpb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGdW5jdGlvbk9yR2VuZXJhdG9yRGVjbGFyYXRpb24oCiAgICAgICAgJGRlZmF1bHQgPSBmYWxzZSwgJGFsbG93R2VuZXJhdG9yID0gdHJ1ZQogICAgKSB7CiAgICAgICAgJGFzeW5jID0gbnVsbDsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmCiAgICAgICAgICAgICgkYXN5bmMgPSAkdGhpcy0+Y2hlY2tBc3luY0Z1bmN0aW9uU3RhcnQoKSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+YXN5bmNJdGVyYXRpb25HZW5lcmF0b3JzKSB7CiAgICAgICAgICAgICAgICAkYWxsb3dHZW5lcmF0b3IgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImZ1bmN0aW9uIikpIHsKCiAgICAgICAgICAgICRnZW5lcmF0b3IgPSAkYWxsb3dHZW5lcmF0b3IgJiYgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIioiKTsKICAgICAgICAgICAgJGlkID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcik7CgogICAgICAgICAgICBpZiAoJGdlbmVyYXRvciB8fCAkYXN5bmMpIHsKICAgICAgICAgICAgICAgICRmbGFncyA9IGFycmF5KG51bGwpOwogICAgICAgICAgICAgICAgaWYgKCRnZW5lcmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICAkZmxhZ3NbImFsbG93WWllbGQiXSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGFzeW5jKSB7CiAgICAgICAgICAgICAgICAgICAgJGZsYWdzWyJhbGxvd0F3YWl0Il0gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGZsYWdzID0gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgkZGVmYXVsdCB8fCAkaWQpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJHBhcmFtcyA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAkZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgInBhcnNlRm9ybWFsUGFyYW1ldGVyTGlzdCIKICAgICAgICAgICAgICAgICkpICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpICYmCiAgICAgICAgICAgICAgICAoJHRva2VuQm9keVN0YXJ0ID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgJiYKICAgICAgICAgICAgICAgICgoJGJvZHkgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgInBhcnNlRnVuY3Rpb25Cb2R5IgogICAgICAgICAgICAgICAgICAgICkpIHx8IHRydWUpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpCiAgICAgICAgICAgICkgewoKICAgICAgICAgICAgICAgICRib2R5LT5zZXRTdGFydFBvc2l0aW9uKAogICAgICAgICAgICAgICAgICAgICR0b2tlbkJvZHlTdGFydC0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRib2R5LT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKSk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKAogICAgICAgICAgICAgICAgICAgICJGdW5jdGlvbkRlY2xhcmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAkYXN5bmMgPyAkYXN5bmMgOiAkdG9rZW4KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoJGlkKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldElkKCRpZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UGFyYW1zKCRwYXJhbXMpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEdlbmVyYXRvcigkZ2VuZXJhdG9yKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRBc3luYygoYm9vbCkgJGFzeW5jKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgZnVuY3Rpb24gb3IgZ2VuZXJhdG9yIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEZ1bmN0aW9uRXhwcmVzc2lvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZ1bmN0aW9uT3JHZW5lcmF0b3JFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkYWxsb3dHZW5lcmF0b3IgPSB0cnVlOwogICAgICAgICRhc3luYyA9IGZhbHNlOwogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQgJiYKICAgICAgICAgICAgKCRhc3luYyA9ICR0aGlzLT5jaGVja0FzeW5jRnVuY3Rpb25TdGFydCgpKSkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgIGlmICghJHRoaXMtPmZlYXR1cmVzLT5hc3luY0l0ZXJhdGlvbkdlbmVyYXRvcnMpIHsKICAgICAgICAgICAgICAgICRhbGxvd0dlbmVyYXRvciA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZnVuY3Rpb24iKSkgewoKICAgICAgICAgICAgJGdlbmVyYXRvciA9ICRhbGxvd0dlbmVyYXRvciAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKiIpOwoKICAgICAgICAgICAgaWYgKCRnZW5lcmF0b3IgfHwgJGFzeW5jKSB7CiAgICAgICAgICAgICAgICAkZmxhZ3MgPSBhcnJheShudWxsKTsKICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgJGZsYWdzWyJhbGxvd1lpZWxkIl0gPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRhc3luYykgewogICAgICAgICAgICAgICAgICAgICRmbGFnc1siYWxsb3dBd2FpdCJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRmbGFncyA9IG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpZCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICRmbGFncywKICAgICAgICAgICAgICAgICJwYXJzZUlkZW50aWZpZXIiLAogICAgICAgICAgICAgICAgYXJyYXkoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIpCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSAmJgogICAgICAgICAgICAgICAgKCRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgJGZsYWdzLAogICAgICAgICAgICAgICAgICAgICJwYXJzZUZvcm1hbFBhcmFtZXRlckxpc3QiCiAgICAgICAgICAgICAgICApKSAhPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgKCR0b2tlbkJvZHlTdGFydCA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpICYmCiAgICAgICAgICAgICAgICAoKCRib2R5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICAgICAkZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXJzZUZ1bmN0aW9uQm9keSIKICAgICAgICAgICAgICAgICAgICApKSB8fCB0cnVlKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKQogICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICAkYm9keS0+c2V0U3RhcnRQb3NpdGlvbigKICAgICAgICAgICAgICAgICAgICAkdG9rZW5Cb2R5U3RhcnQtPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkYm9keS0+c2V0RW5kUG9zaXRpb24oJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCkpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAiRnVuY3Rpb25FeHByZXNzaW9uIiwKICAgICAgICAgICAgICAgICAgICAkYXN5bmMgPyAkYXN5bmMgOiAkdG9rZW4KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SWQoJGlkKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRQYXJhbXMoJHBhcmFtcyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0R2VuZXJhdG9yKCRnZW5lcmF0b3IpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFzeW5jKChib29sKSAkYXN5bmMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB5aWVsZCBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFlpZWxkRXhwcmVzc2lvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVlpZWxkRXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ5aWVsZCIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJZaWVsZEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPm5vTGluZVRlcm1pbmF0b3JzKCkpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJGRlbGVnYXRlID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIioiKTsKICAgICAgICAgICAgICAgICRhcmd1bWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dZaWVsZCIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkYXJndW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RGVsZWdhdGUoJGRlbGVnYXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwYXJhbWV0ZXIgbGlzdAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZVtdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRm9ybWFsUGFyYW1ldGVyTGlzdCgpCiAgICB7CiAgICAgICAgJGhhc0NvbW1hID0gZmFsc2U7CiAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgIHdoaWxlICgKICAgICAgICAgICAgKCRwYXJhbSA9ICR0aGlzLT5wYXJzZUJpbmRpbmdSZXN0RWxlbWVudCgpKSB8fAogICAgICAgICAgICAkcGFyYW0gPSAkdGhpcy0+cGFyc2VCaW5kaW5nRWxlbWVudCgpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRoYXNDb21tYSA9IGZhbHNlOwogICAgICAgICAgICAkbGlzdFtdID0gJHBhcmFtOwogICAgICAgICAgICBpZiAoJHBhcmFtLT5nZXRUeXBlKCkgPT09ICJSZXN0RWxlbWVudCIpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIiwiKSkgewogICAgICAgICAgICAgICAgJGhhc0NvbW1hID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkaGFzQ29tbWEgJiYKICAgICAgICAgICAgISR0aGlzLT5mZWF0dXJlcy0+dHJhaWxpbmdDb21tYUZ1bmN0aW9uQ2FsbERlY2xhcmF0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRsaXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEJsb2NrU3RhdGVtZW50W118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VGdW5jdGlvbkJvZHkoKQogICAgewogICAgICAgICRib2R5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICBhcnJheSgiYWxsb3dSZXR1cm4iID0+IHRydWUpLAogICAgICAgICAgICAicGFyc2VTdGF0ZW1lbnRMaXN0IiwKICAgICAgICAgICAgYXJyYXkodHJ1ZSkKICAgICAgICApOwogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICJCbG9ja1N0YXRlbWVudCIsICRib2R5ID8gJGJvZHkgOiAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKQogICAgICAgICk7CiAgICAgICAgaWYgKCRib2R5KSB7CiAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCRib2R5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGNsYXNzIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRkZWZhdWx0IERlZmF1bHQgbW9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQ2xhc3NEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUNsYXNzRGVjbGFyYXRpb24oJGRlZmF1bHQgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImNsYXNzIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ2xhc3MgZGVjbGFyYXRpb25zIGFyZSBzdHJpY3QgbW9kZSBieSBkZWZhdWx0CiAgICAgICAgICAgICRwcmV2U3RyaWN0ID0gJHRoaXMtPnNjYW5uZXItPmdldFN0cmljdE1vZGUoKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUodHJ1ZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAkaWQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKTsKICAgICAgICAgICAgaWYgKCgkZGVmYXVsdCB8fCAkaWQpICYmCiAgICAgICAgICAgICAgICAkdGFpbCA9ICR0aGlzLT5wYXJzZUNsYXNzVGFpbCgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJDbGFzc0RlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgIGlmICgkaWQpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SWQoJGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkdGFpbFswXSkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRTdXBlckNsYXNzKCR0YWlsWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCR0YWlsWzFdKTsKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdHJpY3RNb2RlKCRwcmV2U3RyaWN0KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjbGFzcyBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDbGFzc0V4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbGFzc0V4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiY2xhc3MiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgLy9DbGFzcyBleHByZXNzaW9ucyBhcmUgc3RyaWN0IG1vZGUgYnkgZGVmYXVsdAogICAgICAgICAgICAkcHJldlN0cmljdCA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdHJpY3RNb2RlKCk7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdHJpY3RNb2RlKHRydWUpOwogICAgICAgICAgICAKICAgICAgICAgICAgJGlkID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcik7CiAgICAgICAgICAgICR0YWlsID0gJHRoaXMtPnBhcnNlQ2xhc3NUYWlsKCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkNsYXNzRXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgIGlmICgkaWQpIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRJZCgkaWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGFpbFswXSkgewogICAgICAgICAgICAgICAgJG5vZGUtPnNldFN1cGVyQ2xhc3MoJHRhaWxbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRub2RlLT5zZXRCb2R5KCR0YWlsWzFdKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0cmljdE1vZGUoJHByZXZTdHJpY3QpOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgY29kZSB0aGF0IGNvbWVzIGFmdGVyIHRoZSBjbGFzcyBrZXl3b3JkIGFuZCBjbGFzcyBuYW1lLiBUaGUKICAgICAqIHJldHVybiB2YWx1ZSBpcyBhbiBhcnJheSB3aGVyZSB0aGUgZmlyc3QgaXRlbSBpcyB0aGUgZXh0ZW5kZW5kIGNsYXNzLCBpZgogICAgICogYW55LCBhbmQgdGhlIHNlY29uZCB2YWx1ZSBpcyB0aGUgY2xhc3MgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NUYWlsKCkKICAgIHsKICAgICAgICAkaGVyaXRhZ2UgPSAkdGhpcy0+cGFyc2VDbGFzc0hlcml0YWdlKCk7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlQ2xhc3NCb2R5KCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAkYm9keS0+c2V0U3RhcnRQb3NpdGlvbigkdG9rZW4tPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCkpOwogICAgICAgICAgICAgICAgJGJvZHktPnNldEVuZFBvc2l0aW9uKCR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpKTsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkaGVyaXRhZ2UsICRib2R5KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBjbGFzcyBleHRlbmRzIHBhcnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbGFzc0hlcml0YWdlKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImV4dGVuZHMiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCRzdXBlckNsYXNzID0gJHRoaXMtPnBhcnNlTGVmdEhhbmRTaWRlRXhwcmVzc2lvbigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHN1cGVyQ2xhc3M7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBjbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxDbGFzc0JvZHl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDbGFzc0JvZHkoKQogICAgewogICAgICAgICRib2R5ID0gJHRoaXMtPnBhcnNlQ2xhc3NFbGVtZW50TGlzdCgpOwogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoCiAgICAgICAgICAgICJDbGFzc0JvZHkiLCAkYm9keSA/ICRib2R5IDogJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCkKICAgICAgICApOwogICAgICAgIGlmICgkYm9keSkgewogICAgICAgICAgICAkbm9kZS0+c2V0Qm9keSgkYm9keSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgY2xhc3MgZWxlbWVudHMgbGlzdAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTWV0aG9kRGVmaW5pdGlvbltdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NFbGVtZW50TGlzdCgpCiAgICB7CiAgICAgICAgJGl0ZW1zID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoJGl0ZW0gPSAkdGhpcy0+cGFyc2VDbGFzc0VsZW1lbnQoKSkgewogICAgICAgICAgICBpZiAoJGl0ZW0gIT09IHRydWUpIHsKICAgICAgICAgICAgICAgICRpdGVtc1tdID0gJGl0ZW07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvdW50KCRpdGVtcykgPyAkaXRlbXMgOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGNsYXNzIGVsZW1lbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxNZXRob2REZWZpbml0aW9ufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ2xhc3NFbGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjsiKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJHN0YXRpY1Rva2VuID0gbnVsbDsKICAgICAgICAvL1RoaXMgY29kZSBoYW5kbGVzIHRoZSBjYXNlIHdoZXJlICJzdGF0aWMiIGlzIHRoZSBtZXRob2QgbmFtZQogICAgICAgIGlmICghJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KGFycmF5KCJzdGF0aWMiLCAiKCIpKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgJHN0YXRpY1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInN0YXRpYyIpOwogICAgICAgIH0KICAgICAgICBpZiAoJGRlZiA9ICR0aGlzLT5wYXJzZU1ldGhvZERlZmluaXRpb24oKSkgewogICAgICAgICAgICBpZiAoJHN0YXRpY1Rva2VuKSB7CiAgICAgICAgICAgICAgICAkZGVmLT5zZXRTdGF0aWModHJ1ZSk7CiAgICAgICAgICAgICAgICAkZGVmLT5zZXRTdGFydFBvc2l0aW9uKCRzdGF0aWNUb2tlbi0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRkZWY7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0aWNUb2tlbikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxldCBvciBjb25zdCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVmFyaWFibGVEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxleGljYWxEZWNsYXJhdGlvbigpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoYXJyYXkoImxldCIsICJjb25zdCIpKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGRlY2xhcmF0aW9ucyA9ICR0aGlzLT5jaGFyU2VwYXJhdGVkTGlzdE9mKAogICAgICAgICAgICAgICAgInBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbiIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkZGVjbGFyYXRpb25zKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlZhcmlhYmxlRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEtpbmQoJHRva2VuLT5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXREZWNsYXJhdGlvbnMoJGRlY2xhcmF0aW9ucyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vICJsZXQiIGNhbiBiZSB1c2VkIGFzIHZhcmlhYmxlIG5hbWUgaW4gbm9uLXN0cmljdCBtb2RlCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpIHx8ICR0b2tlbi0+Z2V0VmFsdWUoKSAhPT0gImxldCIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5zZXRTdGF0ZSgkc3RhdGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHZhciBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVmFyaWFibGVEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVZhcmlhYmxlU3RhdGVtZW50KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInZhciIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkZGVjbGFyYXRpb25zID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uTGlzdCIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRkZWNsYXJhdGlvbnMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2luZCgkbm9kZTo6S0lORF9WQVIpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9ucygkZGVjbGFyYXRpb25zKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gdmFyaWFibGUgZGVjbGFyYXRpb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxWYXJpYWJsZURlY2xhcmF0b3JbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVZhcmlhYmxlRGVjbGFyYXRpb25MaXN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNoYXJTZXBhcmF0ZWRMaXN0T2YoCiAgICAgICAgICAgICJwYXJzZVZhcmlhYmxlRGVjbGFyYXRpb24iCiAgICAgICAgKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB2YXJpYWJsZSBkZWNsYXJhdGlvbnMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFZhcmlhYmxlRGVjbGFyYXRvcnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVZhcmlhYmxlRGVjbGFyYXRpb24oKQogICAgewogICAgICAgIGlmICgkaWQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVmFyaWFibGVEZWNsYXJhdG9yIiwgJGlkKTsKICAgICAgICAgICAgJG5vZGUtPnNldElkKCRpZCk7CiAgICAgICAgICAgIGlmICgkaW5pdCA9ICR0aGlzLT5wYXJzZUluaXRpYWxpemVyKCkpIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRJbml0KCRpbml0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIAogICAgICAgIH0gZWxzZWlmICgkaWQgPSAkdGhpcy0+cGFyc2VCaW5kaW5nUGF0dGVybigpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJGluaXQgPSAkdGhpcy0+cGFyc2VJbml0aWFsaXplcigpKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJWYXJpYWJsZURlY2xhcmF0b3IiLCAkaWQpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldElkKCRpZCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0SW5pdCgkaW5pdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxldCBvciBjb25zdCBkZWNsYXJhdGlvbiBpbiBhIGZvciBzdGF0ZW1lbnQgZGVmaW5pdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVmFyaWFibGVEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZvckRlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVPbmVPZihhcnJheSgibGV0IiwgImNvbnN0IikpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJGRlY2xhcmF0aW9uID0gJHRoaXMtPnBhcnNlRm9yQmluZGluZygpKSB7CgogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2luZCgkdG9rZW4tPmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9ucyhhcnJheSgkZGVjbGFyYXRpb24pKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gImxldCIgY2FuIGJlIHVzZWQgYXMgdmFyaWFibGUgbmFtZSBpbiBub24tc3RyaWN0IG1vZGUKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5nZXRTdHJpY3RNb2RlKCkgfHwgJHRva2VuLT5nZXRWYWx1ZSgpICE9PSAibGV0IikgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgYmluZGluZyBwYXR0ZXJuIG9yIGFuIGlkZW50aWZpZXIgdGhhdCBjb21lIGFmdGVyIGEgY29uc3Qgb3IgbGV0CiAgICAgKiBkZWNsYXJhdGlvbiBpbiBhIGZvciBzdGF0ZW1lbnQgZGVmaW5pdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcVmFyaWFibGVEZWNsYXJhdG9yfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRm9yQmluZGluZygpCiAgICB7CiAgICAgICAgaWYgKCgkaWQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKSkgfHwKICAgICAgICAgICAgKCRpZCA9ICR0aGlzLT5wYXJzZUJpbmRpbmdQYXR0ZXJuKCkpCiAgICAgICAgKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJWYXJpYWJsZURlY2xhcmF0b3IiLCAkaWQpOwogICAgICAgICAgICAkbm9kZS0+c2V0SWQoJGlkKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBtb2R1bGUgaXRlbQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU1vZHVsZUl0ZW0oKQogICAgewogICAgICAgIGlmICgkaXRlbSA9ICR0aGlzLT5wYXJzZUltcG9ydERlY2xhcmF0aW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRpdGVtOwogICAgICAgIH0gZWxzZWlmICgkaXRlbSA9ICR0aGlzLT5wYXJzZUV4cG9ydERlY2xhcmF0aW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRpdGVtOwogICAgICAgIH0gZWxzZWlmICgkaXRlbSA9ICR0aGlzLT5wYXJzZVN0YXRlbWVudExpc3RJdGVtKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRpdGVtOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIGZyb20ga2V5d29yZCBhbmQgdGhlIGZvbGxvd2luZyBzdHJpbmcgaW4gaW1wb3J0IGFuZCBleHBvcnQKICAgICAqIGRlY2xhcmF0aW9ucwogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3RyaW5nTGl0ZXJhbHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUZyb21DbGF1c2UoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZnJvbSIpKSB7CiAgICAgICAgICAgIGlmICgkc3BlYyA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRzcGVjOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGV4cG9ydCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTW9kdWxlRGVjbGFyYXRpb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFeHBvcnREZWNsYXJhdGlvbigpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJleHBvcnQiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIikpIHsKCiAgICAgICAgICAgICAgICAkZXhwb3J0ZWQgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+ZXhwb3J0ZWROYW1lSW5FeHBvcnRBbGwgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiYXMiKSkgewogICAgICAgICAgICAgICAgICAgICRleHBvcnRlZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpOwogICAgICAgICAgICAgICAgICAgIGlmICghJGV4cG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICgkc291cmNlID0gJHRoaXMtPnBhcnNlRnJvbUNsYXVzZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRXhwb3J0QWxsRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEV4cG9ydGVkKCRleHBvcnRlZCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiZGVmYXVsdCIpKSB7CiAgICAgICAgICAgICAgICAkbG9va2FoZWFkVG9rZW5zID0gYXJyYXkoImZ1bmN0aW9uIiwgImNsYXNzIik7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0KSB7CiAgICAgICAgICAgICAgICAgICAgJGxvb2thaGVhZFRva2Vuc1tdID0gYXJyYXkoImFzeW5jIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoKCRkZWNsYXJhdGlvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgInBhcnNlRnVuY3Rpb25PckdlbmVyYXRvckRlY2xhcmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkodHJ1ZSkKICAgICAgICAgICAgICAgICAgICApKSB8fAogICAgICAgICAgICAgICAgICAgICgkZGVjbGFyYXRpb24gPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXJzZUNsYXNzRGVjbGFyYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSh0cnVlKQogICAgICAgICAgICAgICAgICAgICkpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXREZWNsYXJhdGlvbigkZGVjbGFyYXRpb24pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZWlmICghJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKAogICAgICAgICAgICAgICAgICAgICAgICAkbG9va2FoZWFkVG9rZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQKICAgICAgICAgICAgICAgICAgICApICYmCiAgICAgICAgICAgICAgICAgICAgKCRkZWNsYXJhdGlvbiA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkobnVsbCwgImFsbG93SW4iID0+IHRydWUpLAogICAgICAgICAgICAgICAgICAgICAgICAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFzc2VydEVuZE9mU3RhdGVtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvbiIsICR0b2tlbgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9uKCRkZWNsYXJhdGlvbik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgoJHNwZWNpZmllcnMgPSAkdGhpcy0+cGFyc2VFeHBvcnRDbGF1c2UoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRXhwb3J0TmFtZWREZWNsYXJhdGlvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0U3BlY2lmaWVycygkc3BlY2lmaWVycyk7CiAgICAgICAgICAgICAgICBpZiAoJHNvdXJjZSA9ICR0aGlzLT5wYXJzZUZyb21DbGF1c2UoKSkgewogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKCiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgICgkZGVjID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIG51bGwsICJwYXJzZVZhcmlhYmxlU3RhdGVtZW50IgogICAgICAgICAgICAgICAgKSkgfHwKICAgICAgICAgICAgICAgICRkZWMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgbnVsbCwgInBhcnNlRGVjbGFyYXRpb24iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkgewoKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkV4cG9ydE5hbWVkRGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldERlY2xhcmF0aW9uKCRkZWMpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBleHBvcnQgY2xhdXNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxFeHBvcnRTcGVjaWZpZXJbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUV4cG9ydENsYXVzZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRsaXN0ID0gYXJyYXkoKTsKICAgICAgICAgICAgd2hpbGUgKCRzcGVjID0gJHRoaXMtPnBhcnNlRXhwb3J0U3BlY2lmaWVyKCkpIHsKICAgICAgICAgICAgICAgICRsaXN0W10gPSAkc3BlYzsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIiwiKSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRsaXN0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBleHBvcnQgc3BlY2lmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxFeHBvcnRTcGVjaWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VFeHBvcnRTcGVjaWZpZXIoKQogICAgewogICAgICAgIGlmICgkbG9jYWwgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGlkZW50aWZpZXJOYW1lKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRXhwb3J0U3BlY2lmaWVyIiwgJGxvY2FsKTsKICAgICAgICAgICAgJG5vZGUtPnNldExvY2FsKCRsb2NhbCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImFzIikpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCRleHBvcnRlZCA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEV4cG9ydGVkKCRleHBvcnRlZCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RXhwb3J0ZWQoJGxvY2FsKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gaW1wb3J0IGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxNb2R1bGVEZWNsYXJhdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUltcG9ydERlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICAvL0RlbGF5IHBhcnNpbmcgb2YgZHluYW1pYyBpbXBvcnQgc28gdGhhdCBpdCBpcyBoYW5kbGVkCiAgICAgICAgLy9ieSB0aGUgcmVsYXRpdmUgbWV0aG9kCiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+ZHluYW1pY0ltcG9ydCAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoImltcG9ydCIsICIoIikpLCB0cnVlKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgLy9EZWxheSBwYXJzaW5nIG9mIGltcG9ydC5tZXRhIHNvIHRoYXQgaXQgaXMgaGFuZGxlZAogICAgICAgIC8vYnkgdGhlIHJlbGF0aXZlIG1ldGhvZAogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmltcG9ydE1ldGEgJiYKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KGFycmF5KCJpbXBvcnQiLCAiLiIpKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiaW1wb3J0IikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkc291cmNlID0gJHRoaXMtPnBhcnNlU3RyaW5nTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiSW1wb3J0RGVjbGFyYXRpb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFNvdXJjZSgkc291cmNlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9IGVsc2VpZiAoKCRzcGVjaWZpZXJzID0gJHRoaXMtPnBhcnNlSW1wb3J0Q2xhdXNlKCkpICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAkc291cmNlID0gJHRoaXMtPnBhcnNlRnJvbUNsYXVzZSgpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkdGhpcy0+YXNzZXJ0RW5kT2ZTdGF0ZW1lbnQoKTsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydERlY2xhcmF0aW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTcGVjaWZpZXJzKCRzcGVjaWZpZXJzKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gaW1wb3J0IGNsYXVzZQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTW9kdWxlU3BlY2lmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSW1wb3J0Q2xhdXNlKCkKICAgIHsKICAgICAgICBpZiAoJHNwZWMgPSAkdGhpcy0+cGFyc2VOYW1lU3BhY2VJbXBvcnQoKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJHNwZWMpOwogICAgICAgIH0gZWxzZWlmICgoJHNwZWNzID0gJHRoaXMtPnBhcnNlTmFtZWRJbXBvcnRzKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAkc3BlY3M7CiAgICAgICAgfSBlbHNlaWYgKCRzcGVjID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpbXBvcnRlZEJpbmRpbmcpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJJbXBvcnREZWZhdWx0U3BlY2lmaWVyIiwgJHNwZWMpOwogICAgICAgICAgICAkbm9kZS0+c2V0TG9jYWwoJHNwZWMpOwogICAgICAgICAgICAkcmV0ID0gYXJyYXkoJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSkpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCRzcGVjID0gJHRoaXMtPnBhcnNlTmFtZVNwYWNlSW1wb3J0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkcmV0W10gPSAkc3BlYzsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHJldDsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgoJHNwZWNzID0gJHRoaXMtPnBhcnNlTmFtZWRJbXBvcnRzKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJHJldCA9IGFycmF5X21lcmdlKCRyZXQsICRzcGVjcyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRyZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG5hbWVzcGFjZSBpbXBvcnQKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEltcG9ydE5hbWVzcGFjZVNwZWNpZmllcnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU5hbWVTcGFjZUltcG9ydCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiYXMiKSAmJgogICAgICAgICAgICAgICAgJGxvY2FsID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpZGVudGlmaWVyUmVmZXJlbmNlKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydE5hbWVzcGFjZVNwZWNpZmllciIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TG9jYWwoJGxvY2FsKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG5hbWVkIGltcG9ydHMKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEltcG9ydFNwZWNpZmllcltdfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTmFtZWRJbXBvcnRzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHNwZWMgPSAkdGhpcy0+cGFyc2VJbXBvcnRTcGVjaWZpZXIoKSkgewogICAgICAgICAgICAgICAgJGxpc3RbXSA9ICRzcGVjOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGltcG9ydCBzcGVjaWZpZXIKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEltcG9ydFNwZWNpZmllcnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUltcG9ydFNwZWNpZmllcigpCiAgICB7CiAgICAgICAgJHJlcXVpcmVkQXMgPSBmYWxzZTsKICAgICAgICAkaW1wb3J0ZWQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGltcG9ydGVkQmluZGluZyk7CiAgICAgICAgaWYgKCEkaW1wb3J0ZWQpIHsKICAgICAgICAgICAgJGltcG9ydGVkID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpZGVudGlmaWVyTmFtZSk7CiAgICAgICAgICAgIGlmICghJGltcG9ydGVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVxdWlyZWRBcyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkltcG9ydFNwZWNpZmllciIsICRpbXBvcnRlZCk7CiAgICAgICAgJG5vZGUtPnNldEltcG9ydGVkKCRpbXBvcnRlZCk7CiAgICAgICAgCiAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJhcyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoISgkbG9jYWwgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGltcG9ydGVkQmluZGluZykpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlLT5zZXRMb2NhbCgkbG9jYWwpOwogICAgICAgICAgICAKICAgICAgICB9IGVsc2VpZiAoJHJlcXVpcmVkQXMpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRub2RlLT5zZXRMb2NhbCgkaW1wb3J0ZWQpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgYmluZGluZyBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxBcnJheVBhdHRlcm58Tm9kZVxPYmplY3RQYXR0ZXJufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQmluZGluZ1BhdHRlcm4oKQogICAgewogICAgICAgIGlmICgkcGF0dGVybiA9ICR0aGlzLT5wYXJzZU9iamVjdEJpbmRpbmdQYXR0ZXJuKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRwYXR0ZXJuOwogICAgICAgIH0gZWxzZWlmICgkcGF0dGVybiA9ICR0aGlzLT5wYXJzZUFycmF5QmluZGluZ1BhdHRlcm4oKSkgewogICAgICAgICAgICByZXR1cm4gJHBhdHRlcm47CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBlbGlzaW9ucyBzZXF1ZW5jZS4gSXQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsaXNpb25zIG9yIG51bGwKICAgICAqIGlmIG5vIGVsaXNpb24gaGFzIGJlZW4gZm91bmQKICAgICAqIAogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlRWxpc2lvbigpCiAgICB7CiAgICAgICAgJGNvdW50ID0gMDsKICAgICAgICB3aGlsZSAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIiwiKSkgewogICAgICAgICAgICAkY291bnQgKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkY291bnQgPyAkY291bnQgOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBhcnJheSBiaW5kaW5nIHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEFycmF5UGF0dGVybnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFycmF5QmluZGluZ1BhdHRlcm4oKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiWyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkZWxlbWVudHMgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgaWYgKCRlbGlzaW9uID0gJHRoaXMtPnBhcnNlRWxpc2lvbigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzID0gYXJyYXlfbWVyZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtZW50cywgYXJyYXlfZmlsbCgwLCAkZWxpc2lvbiwgbnVsbCkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRlbGVtZW50ID0gJHRoaXMtPnBhcnNlQmluZGluZ0VsZW1lbnQoKSkgewogICAgICAgICAgICAgICAgICAgICRlbGVtZW50c1tdID0gJGVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcmVzdCA9ICR0aGlzLT5wYXJzZUJpbmRpbmdSZXN0RWxlbWVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAkcmVzdDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiXSIpKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBcnJheVBhdHRlcm4iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEVsZW1lbnRzKCRlbGVtZW50cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgcmVzdCBlbGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxSZXN0RWxlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUJpbmRpbmdSZXN0RWxlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuLi4iKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkYXJndW1lbnQgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGJpbmRpbmdJZGVudGlmaWVyKSkgfHwKICAgICAgICAgICAgICAgICgkYXJndW1lbnQgPSAkdGhpcy0+cGFyc2VCaW5kaW5nUGF0dGVybigpKSkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiUmVzdEVsZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgYmluZGluZyBlbGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxBc3NpZ25tZW50UGF0dGVybnxOb2RlXElkZW50aWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VCaW5kaW5nRWxlbWVudCgpCiAgICB7CiAgICAgICAgaWYgKCRlbCA9ICR0aGlzLT5wYXJzZVNpbmdsZU5hbWVCaW5kaW5nKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRlbDsKICAgICAgICB9IGVsc2VpZiAoJGxlZnQgPSAkdGhpcy0+cGFyc2VCaW5kaW5nUGF0dGVybigpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkcmlnaHQgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUluaXRpYWxpemVyIgogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoJHJpZ2h0KSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBc3NpZ25tZW50UGF0dGVybiIsICRsZWZ0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCRsZWZ0KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRSaWdodCgkcmlnaHQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuICRsZWZ0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBzaW5nbGUgbmFtZSBiaW5kaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxBc3NpZ25tZW50UGF0dGVybnxOb2RlXElkZW50aWZpZXJ8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTaW5nbGVOYW1lQmluZGluZygpCiAgICB7CiAgICAgICAgaWYgKCRsZWZ0ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcikpIHsKICAgICAgICAgICAgJHJpZ2h0ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VJbml0aWFsaXplciIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRyaWdodCkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXNzaWdubWVudFBhdHRlcm4iLCAkbGVmdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkbGVmdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGVmdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwcm9wZXJ0eSBuYW1lLiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgYW4gYXJyYXkgd2hlcmUgdGhlcmUgZmlyc3QKICAgICAqIGVsZW1lbnQgaXMgdGhlIHByb3BlcnR5IG5hbWUgYW5kIHRoZSBzZWNvbmQgZWxlbWVudCBpcyBhIGJvb2xlYW4KICAgICAqIGluZGljYXRpbmcgaWYgaXQncyBhIGNvbXB1dGVkIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VQcm9wZXJ0eU5hbWUoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiWyIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRuYW1lID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICApKSAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIl0iKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgdHJ1ZSwgJHRva2VuKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgZmFsc2UpOwogICAgICAgIH0gZWxzZWlmICgkbmFtZSA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJG5hbWUsIGZhbHNlKTsKICAgICAgICB9IGVsc2VpZiAoJG5hbWUgPSAkdGhpcy0+cGFyc2VOdW1lcmljTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbmFtZSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBtZXRob2QgZGVmaW5pdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTWV0aG9kRGVmaW5pdGlvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU1ldGhvZERlZmluaXRpb24oKQogICAgewogICAgICAgICRzdGF0ZSA9ICR0aGlzLT5zY2FubmVyLT5nZXRTdGF0ZSgpOwogICAgICAgICRnZW5lcmF0b3IgPSAkZXJyb3IgPSAkYXN5bmMgPSBmYWxzZTsKICAgICAgICAkcG9zaXRpb24gPSBudWxsOwogICAgICAgICRraW5kID0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX01FVEhPRDsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoImdldCIpKSB7CiAgICAgICAgICAgICRwb3NpdGlvbiA9ICR0b2tlbjsKICAgICAgICAgICAgJGtpbmQgPSBOb2RlXE1ldGhvZERlZmluaXRpb246OktJTkRfR0VUOwogICAgICAgICAgICAkZXJyb3IgPSB0cnVlOwogICAgICAgIH0gZWxzZWlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgic2V0IikpIHsKICAgICAgICAgICAgJHBvc2l0aW9uID0gJHRva2VuOwogICAgICAgICAgICAka2luZCA9IE5vZGVcTWV0aG9kRGVmaW5pdGlvbjo6S0lORF9TRVQ7CiAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIqIikpIHsKICAgICAgICAgICAgJHBvc2l0aW9uID0gJHRva2VuOwogICAgICAgICAgICAkZXJyb3IgPSB0cnVlOwogICAgICAgICAgICAkZ2VuZXJhdG9yID0gdHJ1ZTsKICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmCiAgICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5jaGVja0FzeW5jRnVuY3Rpb25TdGFydChmYWxzZSkpKSB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgJHBvc2l0aW9uID0gJHRva2VuOwogICAgICAgICAgICAkZXJyb3IgPSB0cnVlOwogICAgICAgICAgICAkYXN5bmMgPSB0cnVlOwogICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0l0ZXJhdGlvbkdlbmVyYXRvcnMgJiYKICAgICAgICAgICAgICAgICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKiIpKSkgewogICAgICAgICAgICAgICAgJGdlbmVyYXRvciA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vSGFuZGxlIHRoZSBjYXNlIHdoZXJlIGdldCBhbmQgc2V0IGFyZSBtZXRob2RzIG5hbWUgYW5kIG5vdCB0aGUKICAgICAgICAvL2RlZmluaXRpb24gb2YgYSBnZXR0ZXIvc2V0dGVyCiAgICAgICAgaWYgKCRraW5kICE9PSBOb2RlXE1ldGhvZERlZmluaXRpb246OktJTkRfTUVUSE9EICYmCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikKICAgICAgICApIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgICRraW5kID0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX01FVEhPRDsKICAgICAgICAgICAgJGVycm9yID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoJHByb3AgPSAkdGhpcy0+cGFyc2VQcm9wZXJ0eU5hbWUoKSkgewoKICAgICAgICAgICAgaWYgKCEkcG9zaXRpb24pIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9IGlzc2V0KCRwcm9wWzJdKSA/ICRwcm9wWzJdIDogJHByb3BbMF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0b2tlbkZuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSkgewoKICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yIHx8ICRhc3luYykgewogICAgICAgICAgICAgICAgICAgICRmbGFncyA9IGFycmF5KG51bGwpOwogICAgICAgICAgICAgICAgICAgIGlmICgkZ2VuZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFnc1siYWxsb3dZaWVsZCJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRhc3luYykgewogICAgICAgICAgICAgICAgICAgICAgICAkZmxhZ3NbImFsbG93QXdhaXQiXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkZmxhZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICAkcGFyYW1zID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGlmICgka2luZCA9PT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX1NFVCkgewogICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsICJwYXJzZUJpbmRpbmdFbGVtZW50IgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRwYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmFtcyA9IGFycmF5KCRwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgka2luZCA9PT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX01FVEhPRCkgewogICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFncywgInBhcnNlRm9ybWFsUGFyYW1ldGVyTGlzdCIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkcGFyYW1zICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKSAmJgogICAgICAgICAgICAgICAgICAgICgkdG9rZW5Cb2R5U3RhcnQgPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgieyIpKSAmJgogICAgICAgICAgICAgICAgICAgICgoJGJvZHkgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgICAgICRmbGFncywgInBhcnNlRnVuY3Rpb25Cb2R5IgogICAgICAgICAgICAgICAgICAgICkpIHx8IHRydWUpICYmCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKQogICAgICAgICAgICAgICAgKSB7CgogICAgICAgICAgICAgICAgICAgIGlmICgkcHJvcFswXSBpbnN0YW5jZW9mIE5vZGVcSWRlbnRpZmllciAmJgogICAgICAgICAgICAgICAgICAgICAgICAkcHJvcFswXS0+Z2V0TmFtZSgpID09PSAiY29uc3RydWN0b3IiCiAgICAgICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRraW5kID0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX0NPTlNUUlVDVE9SOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJGJvZHktPnNldFN0YXJ0UG9zaXRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbkJvZHlTdGFydC0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJGJvZHktPnNldEVuZFBvc2l0aW9uKCR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpKTsKCiAgICAgICAgICAgICAgICAgICAgJG5vZGVGbiA9ICR0aGlzLT5jcmVhdGVOb2RlKCJGdW5jdGlvbkV4cHJlc3Npb24iLCAkdG9rZW5Gbik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGVGbi0+c2V0UGFyYW1zKCRwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgICRub2RlRm4tPnNldEJvZHkoJGJvZHkpOwogICAgICAgICAgICAgICAgICAgICRub2RlRm4tPnNldEdlbmVyYXRvcigkZ2VuZXJhdG9yKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZUZuLT5zZXRBc3luYygkYXN5bmMpOwoKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJNZXRob2REZWZpbml0aW9uIiwgJHBvc2l0aW9uKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRwcm9wWzBdKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZUZuKSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEtpbmQoJGtpbmQpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb21wdXRlZCgkcHJvcFsxXSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJGVycm9yKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIHBhcmFtZXRlcnMgaW4gYW4gYXJyb3cgZnVuY3Rpb24uIElmIHRoZSBwYXJhbWV0ZXJzIGFyZSB3cmFwcGVkIGluCiAgICAgKiByb3VuZCBicmFja2V0cywgdGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5IHdoZXJlIHRoZSBmaXJzdCBlbGVtZW50CiAgICAgKiBpcyB0aGUgcGFyYW1ldGVycyBsaXN0IGFuZCB0aGUgc2Vjb25kIGVsZW1lbnQgaXMgdGhlIG9wZW4gcm91bmQgYnJhY2tldHMsCiAgICAgKiB0aGlzIGlzIG5lZWRlZCB0byBrbm93IHRoZSBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcSWRlbnRpZmllcnxhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFycm93UGFyYW1ldGVycygpCiAgICB7CiAgICAgICAgaWYgKCRwYXJhbSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokYmluZGluZ0lkZW50aWZpZXIsICI9PiIpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGFyYW07CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRwYXJhbXMgPSAkdGhpcy0+cGFyc2VGb3JtYWxQYXJhbWV0ZXJMaXN0KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHBhcmFtcyAhPT0gbnVsbCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJHBhcmFtcywgJHRva2VuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgYm9keSBvZiBhbiBhcnJvdyBmdW5jdGlvbi4gVGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5CiAgICAgKiB3aGVyZSB0aGUgZmlyc3QgZWxlbWVudCBpcyB0aGUgZnVuY3Rpb24gYm9keSBhbmQgdGhlIHNlY29uZCBlbGVtZW50IGlzCiAgICAgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgYm9keSBpcyB3cmFwcGVkIGluIGN1cmx5IGJyYWNlcwogICAgICoKICAgICAqIEBwYXJhbSBib29sICAkYXN5bmMgIEFzeW5jIGJvZHkgbW9kZQogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VDb25jaXNlQm9keSgkYXN5bmMgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewoKICAgICAgICAgICAgaWYgKCgkYm9keSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAkYXN5bmMgPyBhcnJheShudWxsLCAiYWxsb3dBd2FpdCIgPT4gdHJ1ZSkgOiBudWxsLAogICAgICAgICAgICAgICAgICAgICJwYXJzZUZ1bmN0aW9uQm9keSIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJGJvZHktPnNldFN0YXJ0UG9zaXRpb24oJHRva2VuLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpKTsKICAgICAgICAgICAgICAgICRib2R5LT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJGJvZHksIGZhbHNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0gZWxzZWlmICghJHRoaXMtPnNjYW5uZXItPmlzQmVmb3JlKGFycmF5KCJ7IikpICYmCiAgICAgICAgICAgICRib2R5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ID8KICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd1lpZWxkIiA9PiBmYWxzZSwgImFsbG93QXdhaXQiID0+ICRhc3luYykgOgogICAgICAgICAgICAgICAgYXJyYXkoImFsbG93WWllbGQiID0+IGZhbHNlKSwKICAgICAgICAgICAgICAgICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICApCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkYm9keSwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBhcnJvdyBmdW5jdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcQXJyb3dGdW5jdGlvbkV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VBcnJvd0Z1bmN0aW9uKCkKICAgIHsKICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICAkYXN5bmMgPSBmYWxzZTsKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmCiAgICAgICAgICAgICgkYXN5bmMgPSAkdGhpcy0+Y2hlY2tBc3luY0Z1bmN0aW9uU3RhcnQoZmFsc2UpKSkgewogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoJHBhcmFtcyA9ICR0aGlzLT5wYXJzZUFycm93UGFyYW1ldGVycygpKSAhPT0gbnVsbCkgewoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiPT4iKQogICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICBpZiAoJGJvZHkgPSAkdGhpcy0+cGFyc2VDb25jaXNlQm9keSgoYm9vbCkgJGFzeW5jKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkcGFyYW1zKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcG9zID0gJHBhcmFtc1sxXTsKICAgICAgICAgICAgICAgICAgICAgICAgJHBhcmFtcyA9ICRwYXJhbXNbMF07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHBvcyA9ICRwYXJhbXM7CiAgICAgICAgICAgICAgICAgICAgICAgICRwYXJhbXMgPSBhcnJheSgkcGFyYW1zKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRhc3luYykgewogICAgICAgICAgICAgICAgICAgICAgICAkcG9zID0gJGFzeW5jOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbiIsICRwb3MpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRQYXJhbXMoJHBhcmFtcyk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEJvZHkoJGJvZHlbMF0pOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9uKCRib2R5WzFdKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXN5bmMoKGJvb2wpICRhc3luYyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gb2JqZWN0IGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE9iamVjdEV4cHJlc3Npb258bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VPYmplY3RMaXRlcmFsKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJHByb3BlcnRpZXMgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHByb3AgPSAkdGhpcy0+cGFyc2VQcm9wZXJ0eURlZmluaXRpb24oKSkgewogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9ICRwcm9wOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgifSIpKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk9iamVjdEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgaWYgKCRwcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnRpZXMoJHByb3BlcnRpZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHByb3BlcnR5IGluIGFuIG9iamVjdCBsaXRlcmFsCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxQcm9wZXJ0eXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVByb3BlcnR5RGVmaW5pdGlvbigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+cmVzdFNwcmVhZFByb3BlcnRpZXMgJiYKICAgICAgICAgICAgKCRwcm9wID0gJHRoaXMtPnBhcnNlU3ByZWFkRWxlbWVudCgpKSkgewogICAgICAgICAgICByZXR1cm4gJHByb3A7CiAgICAgICAgfQoKICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICBpZiAoKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZVByb3BlcnR5TmFtZSgpKSAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpCiAgICAgICAgKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICgkdmFsdWUpIHsKICAgICAgICAgICAgICAgICRzdGFydFBvcyA9IGlzc2V0KCRwcm9wZXJ0eVsyXSkgPyAkcHJvcGVydHlbMl0gOiAkcHJvcGVydHlbMF07CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJQcm9wZXJ0eSIsICRzdGFydFBvcyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRwcm9wZXJ0eVswXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHZhbHVlKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb21wdXRlZCgkcHJvcGVydHlbMV0pOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICAKICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICBpZiAoJHByb3BlcnR5ID0gJHRoaXMtPnBhcnNlTWV0aG9kRGVmaW5pdGlvbigpKSB7CgogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJQcm9wZXJ0eSIsICRwcm9wZXJ0eSk7CiAgICAgICAgICAgICRub2RlLT5zZXRLZXkoJHByb3BlcnR5LT5nZXRLZXkoKSk7CiAgICAgICAgICAgICRub2RlLT5zZXRWYWx1ZSgkcHJvcGVydHktPmdldFZhbHVlKCkpOwogICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQoJHByb3BlcnR5LT5nZXRDb21wdXRlZCgpKTsKICAgICAgICAgICAgJGtpbmQgPSAkcHJvcGVydHktPmdldEtpbmQoKTsKICAgICAgICAgICAgaWYgKCRraW5kICE9PSBOb2RlXE1ldGhvZERlZmluaXRpb246OktJTkRfR0VUICYmCiAgICAgICAgICAgICAgICAka2luZCAhPT0gTm9kZVxNZXRob2REZWZpbml0aW9uOjpLSU5EX1NFVAogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRNZXRob2QodHJ1ZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2luZChOb2RlXFByb3BlcnR5OjpLSU5EX0lOSVQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG5vZGUtPnNldEtpbmQoJGtpbmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlaWYgKCRrZXkgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGlkZW50aWZpZXJSZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJQcm9wZXJ0eSIsICRrZXkpOwogICAgICAgICAgICAkbm9kZS0+c2V0U2hvcnRoYW5kKHRydWUpOwogICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRrZXkpOwogICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUluaXRpYWxpemVyIgogICAgICAgICAgICApOwogICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHZhbHVlID8gJHZhbHVlIDogJGtleSk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBpdGxpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSW5pdGlhbGl6ZXIoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiPSIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHZhbHVlID0gJHRoaXMtPnBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gb2JqZWN0IGJpbmRpbmcgcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcT2JqZWN0UGF0dGVybnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZU9iamVjdEJpbmRpbmdQYXR0ZXJuKCkKICAgIHsKICAgICAgICAkc3RhdGUgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RhdGUoKTsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewoKICAgICAgICAgICAgJHByb3BlcnRpZXMgPSBhcnJheSgpOwogICAgICAgICAgICB3aGlsZSAoJHByb3AgPSAkdGhpcy0+cGFyc2VCaW5kaW5nUHJvcGVydHkoKSkgewogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9ICRwcm9wOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPnJlc3RTcHJlYWRQcm9wZXJ0aWVzICYmCiAgICAgICAgICAgICAgICAoJHJlc3QgPSAkdGhpcy0+cGFyc2VSZXN0UHJvcGVydHkoKSkpIHsKICAgICAgICAgICAgICAgICRwcm9wZXJ0aWVzW10gPSAkcmVzdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ9IikpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk9iamVjdFBhdHRlcm4iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgaWYgKCRwcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnRpZXMoJHByb3BlcnRpZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+c2V0U3RhdGUoJHN0YXRlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSByZXN0IHByb3BlcnR5CiAgICAgKgogICAgICogQHJldHVybiBOb2RlXFJlc3RFbGVtZW50fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUmVzdFByb3BlcnR5KCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4uLiIpKSB7CgogICAgICAgICAgICBpZiAoJGFyZ3VtZW50ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRiaW5kaW5nSWRlbnRpZmllcikpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlJlc3RFbGVtZW50IiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkYXJndW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHByb3BlcnR5IGluIGFuIG9iamVjdCBiaW5kaW5nIHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEFzc2lnbm1lbnRQcm9wZXJ0eXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUJpbmRpbmdQcm9wZXJ0eSgpCiAgICB7CiAgICAgICAgJHN0YXRlID0gJHRoaXMtPnNjYW5uZXItPmdldFN0YXRlKCk7CiAgICAgICAgaWYgKCgka2V5ID0gJHRoaXMtPnBhcnNlUHJvcGVydHlOYW1lKCkpICYmCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI6IikKICAgICAgICApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkdmFsdWUgPSAkdGhpcy0+cGFyc2VCaW5kaW5nRWxlbWVudCgpKSB7CiAgICAgICAgICAgICAgICAkc3RhcnRQb3MgPSBpc3NldCgka2V5WzJdKSA/ICRrZXlbMl0gOiAka2V5WzBdOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQXNzaWdubWVudFByb3BlcnR5IiwgJHN0YXJ0UG9zKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLZXkoJGtleVswXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQoJGtleVsxXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHZhbHVlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPnNldFN0YXRlKCRzdGF0ZSk7CiAgICAgICAgaWYgKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZVNpbmdsZU5hbWVCaW5kaW5nKCkpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFzc2lnbm1lbnRQcm9wZXJ0eSIsICRwcm9wZXJ0eSk7CiAgICAgICAgICAgICRub2RlLT5zZXRTaG9ydGhhbmQodHJ1ZSk7CiAgICAgICAgICAgIGlmICgkcHJvcGVydHkgaW5zdGFuY2VvZiBOb2RlXEFzc2lnbm1lbnRQYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0S2V5KCRwcm9wZXJ0eS0+Z2V0TGVmdCgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRLZXkoJHByb3BlcnR5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZS0+c2V0VmFsdWUoJHByb3BlcnR5KTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUV4cHJlc3Npb24oKQogICAgewogICAgICAgICRsaXN0ID0gJHRoaXMtPmNoYXJTZXBhcmF0ZWRMaXN0T2YoInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iKTsKICAgICAgICAKICAgICAgICBpZiAoISRsaXN0KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0gZWxzZWlmIChjb3VudCgkbGlzdCkgPT09IDEpIHsKICAgICAgICAgICAgcmV0dXJuICRsaXN0WzBdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlNlcXVlbmNlRXhwcmVzc2lvbiIsICRsaXN0KTsKICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb25zKCRsaXN0KTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXNzaWdubWVudCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKQogICAgewogICAgICAgIGlmICgkZXhwciA9ICR0aGlzLT5wYXJzZUFycm93RnVuY3Rpb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cHI7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5jb250ZXh0LT5hbGxvd1lpZWxkICYmICRleHByID0gJHRoaXMtPnBhcnNlWWllbGRFeHByZXNzaW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHByOwogICAgICAgIH0gZWxzZWlmICgkZXhwciA9ICR0aGlzLT5wYXJzZUNvbmRpdGlvbmFsRXhwcmVzc2lvbigpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkZXhwclR5cGVzID0gYXJyYXkoCiAgICAgICAgICAgICAgICAiQ29uZGl0aW9uYWxFeHByZXNzaW9uIiwgIkxvZ2ljYWxFeHByZXNzaW9uIiwKICAgICAgICAgICAgICAgICJCaW5hcnlFeHByZXNzaW9uIiwgIlVwZGF0ZUV4cHJlc3Npb24iLCAiVW5hcnlFeHByZXNzaW9uIgogICAgICAgICAgICApOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFpbl9hcnJheSgkZXhwci0+Z2V0VHlwZSgpLCAkZXhwclR5cGVzKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkb3BlcmF0b3JzID0gJHRoaXMtPmFzc2lnbm1lbnRPcGVyYXRvcnM7CiAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdG9yID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVPbmVPZigkb3BlcmF0b3JzKSkgewoKICAgICAgICAgICAgICAgICAgICBpZiAoJGV4cHItPmdldFR5cGUoKSA9PT0gIkNoYWluRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPcHRpb25hbCBjaGFpbiBjYW4ndCBhcHBlYXIgaW4gbGVmdC1oYW5kIHNpZGUiCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkcmlnaHQgPSAkdGhpcy0+cGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkcmlnaHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3NpZ25tZW50RXhwcmVzc2lvbiIsICRleHByCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRMZWZ0KCR0aGlzLT5leHByZXNzaW9uVG9QYXR0ZXJuKCRleHByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcGVyYXRvcigkb3BlcmF0b3ItPmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmlnaHQoJHJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRleHByOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjb25kaXRpb25hbCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQ29uZGl0aW9uYWxFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICBpZiAoJHRlc3QgPSAkdGhpcy0+cGFyc2VMb2dpY2FsQmluYXJ5RXhwcmVzc2lvbigpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIj8iKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkY29uc2VxdWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkY29uc2VxdWVudCAmJiAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpICYmCiAgICAgICAgICAgICAgICAgICAgJGFsdGVybmF0ZSA9ICR0aGlzLT5wYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ29uZGl0aW9uYWxFeHByZXNzaW9uIiwgJHRlc3QpOwogICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRUZXN0KCR0ZXN0KTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldEFsdGVybmF0ZSgkYWx0ZXJuYXRlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGVzdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsb2dpY2FsIG9yIGEgYmluYXJ5IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VMb2dpY2FsQmluYXJ5RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgJG9wZXJhdG9ycyA9ICR0aGlzLT5sb2dpY2FsQmluYXJ5T3BlcmF0b3JzOwogICAgICAgIGlmICghJHRoaXMtPmNvbnRleHQtPmFsbG93SW4pIHsKICAgICAgICAgICAgdW5zZXQoJG9wZXJhdG9yc1siaW4iXSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICghKCRleHAgPSAkdGhpcy0+cGFyc2VVbmFyeUV4cHJlc3Npb24oKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRsaXN0ID0gYXJyYXkoJGV4cCk7CiAgICAgICAgJGNvYWxlc2NpbmdGb3VuZCA9ICRhbmRPckZvdW5kID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoYXJyYXlfa2V5cygkb3BlcmF0b3JzKSkpIHsKICAgICAgICAgICAgJG9wID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICAvLyBDb2FsZXNjaW5nIGFuZCBsb2dpY2FsIGV4cHJlc3Npb25zIGNhbid0IGJlIHVzZWQgdG9nZXRoZXIKICAgICAgICAgICAgaWYgKCRvcCA9PT0gIj8/IikgewogICAgICAgICAgICAgICAgJGNvYWxlc2NpbmdGb3VuZCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZWlmICgkb3AgPT09ICImJiIgfHwgJG9wID09PSAifHwiKSB7CiAgICAgICAgICAgICAgICAkYW5kT3JGb3VuZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRjb2FsZXNjaW5nRm91bmQgJiYgJGFuZE9yRm91bmQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoCiAgICAgICAgICAgICAgICAgICAgIkxvZ2ljYWwgZXhwcmVzc2lvbnMgbXVzdCBiZSB3cmFwcGVkIGluIHBhcmVudGhlc2VzIHdoZW4gIiAuCiAgICAgICAgICAgICAgICAgICAgImluc2lkZSBjb2FsZXNjZSBleHByZXNzaW9ucyIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEoJGV4cCA9ICR0aGlzLT5wYXJzZVVuYXJ5RXhwcmVzc2lvbigpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRsaXN0W10gPSAkb3A7CiAgICAgICAgICAgICRsaXN0W10gPSAkZXhwOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbGVuID0gY291bnQoJGxpc3QpOwogICAgICAgIGlmICgkbGVuID4gMSkgewogICAgICAgICAgICAkbWF4R3JhZGUgPSBtYXgoJG9wZXJhdG9ycyk7CiAgICAgICAgICAgIGZvciAoJGdyYWRlID0gJG1heEdyYWRlOyAkZ3JhZGUgPj0gMDsgJGdyYWRlLS0pIHsKICAgICAgICAgICAgICAgICRjbGFzcyA9ICRncmFkZSA8IDIgPyAiTG9naWNhbEV4cHJlc3Npb24iIDogIkJpbmFyeUV4cHJlc3Npb24iOwogICAgICAgICAgICAgICAgJHIybCA9ICRncmFkZSA9PT0gMTA7CiAgICAgICAgICAgICAgICAvL0V4cG9uZW50YXRpb24gb3BlcmF0b3IgbXVzdCBiZSBwYXJzZWQgcmlnaHQgdG8gbGVmdAogICAgICAgICAgICAgICAgaWYgKCRyMmwpIHsKICAgICAgICAgICAgICAgICAgICAkaSA9ICRsZW4gLSAyOwogICAgICAgICAgICAgICAgICAgICRzdGVwID0gLTI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpID0gMTsKICAgICAgICAgICAgICAgICAgICAkc3RlcCA9IDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3IgKDsgKCRyMmwgJiYgJGkgPiAwKSB8fCAoISRyMmwgJiYgJGkgPCAkbGVuKTsgJGkgKz0gJHN0ZXApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJG9wZXJhdG9yc1skbGlzdFskaV1dID09PSAkZ3JhZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgkY2xhc3MsICRsaXN0WyRpIC0gMV0pOwogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TGVmdCgkbGlzdFskaSAtIDFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldE9wZXJhdG9yKCRsaXN0WyRpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRSaWdodCgkbGlzdFskaSArIDFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y29tcGxldGVOb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUsICRsaXN0WyRpICsgMV0tPmdldExvY2F0aW9uKCktPmdldEVuZCgpCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3NwbGljZSgkbGlzdCwgJGkgLSAxLCAzLCBhcnJheSgkbm9kZSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRyMmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpIC09ICRzdGVwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRsZW4gPSBjb3VudCgkbGlzdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkbGlzdFswXTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB1bmFyeSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlVW5hcnlFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkb3BlcmF0b3JzID0gJHRoaXMtPnVuYXJ5T3BlcmF0b3JzOwogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmFzeW5jQXdhaXQgJiYgJHRoaXMtPmNvbnRleHQtPmFsbG93QXdhaXQpIHsKICAgICAgICAgICAgJG9wZXJhdG9yc1tdID0gImF3YWl0IjsKICAgICAgICB9CiAgICAgICAgaWYgKCRleHByID0gJHRoaXMtPnBhcnNlUG9zdGZpeEV4cHJlc3Npb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cHI7CiAgICAgICAgfSBlbHNlaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lT25lT2YoJG9wZXJhdG9ycykpIHsKICAgICAgICAgICAgaWYgKCRhcmd1bWVudCA9ICR0aGlzLT5wYXJzZVVuYXJ5RXhwcmVzc2lvbigpKSB7CgogICAgICAgICAgICAgICAgJG9wID0gJHRva2VuLT5nZXRWYWx1ZSgpOwoKICAgICAgICAgICAgICAgIC8vRGVsZXRpbmcgYSB2YXJpYWJsZSB3aXRob3V0IGFjY2Vzc2luZyBpdHMgcHJvcGVydGllcyBpcyBhCiAgICAgICAgICAgICAgICAvL3N5bnRheCBlcnJvciBpbiBzdHJpY3QgbW9kZQogICAgICAgICAgICAgICAgaWYgKCRvcCA9PT0gImRlbGV0ZSIgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpICYmCiAgICAgICAgICAgICAgICAgICAgJGFyZ3VtZW50IGluc3RhbmNlb2YgTm9kZVxJZGVudGlmaWVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIkRlbGV0aW5nIGFuIHVucXVhbGlmaWVkIGlkZW50aWZpZXIgaXMgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGUiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0ICYmICRvcCA9PT0gImF3YWl0IikgewogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkF3YWl0RXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICgkb3AgPT09ICIrKyIgfHwgJG9wID09PSAiLS0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkYXJndW1lbnQtPmdldFR5cGUoKSA9PT0gIkNoYWluRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiBsZWZ0LWhhbmQgc2lkZSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVXBkYXRlRXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2RlLT5zZXRQcmVmaXgodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVW5hcnlFeHByZXNzaW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldE9wZXJhdG9yKCRvcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwb3N0Zml4IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgaWYgKCRhcmd1bWVudCA9ICR0aGlzLT5wYXJzZUxlZnRIYW5kU2lkZUV4cHJlc3Npb24oKSkgewoKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpICYmCiAgICAgICAgICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZU9uZU9mKCR0aGlzLT5wb3N0Zml4T3BlcmF0b3JzKQogICAgICAgICAgICApIHsKCiAgICAgICAgICAgICAgICBpZiAoJGFyZ3VtZW50LT5nZXRUeXBlKCkgPT09ICJDaGFpbkV4cHJlc3Npb24iKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiBsZWZ0LWhhbmQgc2lkZSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJVcGRhdGVFeHByZXNzaW9uIiwgJGFyZ3VtZW50KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcGVyYXRvcigkdG9rZW4tPmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkYXJndW1lbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGxlZnQgaGFuZCBzaWRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICAkb2JqZWN0ID0gbnVsbDsKICAgICAgICAkbmV3VG9rZW5zID0gYXJyYXkoKTsKICAgICAgICAKICAgICAgICAvL1BhcnNlIGFsbCBvY2N1cnJlbmNlcyBvZiAibmV3IgogICAgICAgIGlmICgkbmV3VG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoIm5ldyIpKSkgewogICAgICAgICAgICB3aGlsZSAoJG5ld1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIm5ldyIpKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4iKSkgewogICAgICAgICAgICAgICAgICAgIC8vbmV3LnRhcmdldAogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInRhcmdldCIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWV0YVByb3BlcnR5IiwgJG5ld1Rva2VuKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0TWV0YSgibmV3Iik7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnR5KCJ0YXJnZXQiKTsKICAgICAgICAgICAgICAgICAgICAkb2JqZWN0ID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbmV3VG9rZW5zW10gPSAkbmV3VG9rZW47CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJHRoaXMtPmZlYXR1cmVzLT5pbXBvcnRNZXRhICYmCiAgICAgICAgICAgICR0aGlzLT5zb3VyY2VUeXBlID09PSBcUGVhc3RcUGVhc3Q6OlNPVVJDRV9UWVBFX01PRFVMRSAmJgogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+aXNCZWZvcmUoYXJyYXkoYXJyYXkoImltcG9ydCIsICIuIikpLCB0cnVlKQogICAgICAgICkgewogICAgICAgICAgICAvL2ltcG9ydC5tZXRhCiAgICAgICAgICAgICRpbXBvcnRUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJpbXBvcnQiKTsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4iKTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgibWV0YSIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWV0YVByb3BlcnR5IiwgJGltcG9ydFRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldE1ldGEoImltcG9ydCIpOwogICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoIm1ldGEiKTsKICAgICAgICAgICAgJG9iamVjdCA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbmV3VG9rZW5zQ291bnQgPSBjb3VudCgkbmV3VG9rZW5zKTsKICAgICAgICAKICAgICAgICBpZiAoISRvYmplY3QgJiYKICAgICAgICAgICAgISgkb2JqZWN0ID0gJHRoaXMtPnBhcnNlU3VwZXJQcm9wZXJ0eU9yQ2FsbCgpKSAmJgogICAgICAgICAgICAhKCR0aGlzLT5mZWF0dXJlcy0+ZHluYW1pY0ltcG9ydCAmJgogICAgICAgICAgICAgICAgKCRvYmplY3QgPSAkdGhpcy0+cGFyc2VJbXBvcnRDYWxsKCkpCiAgICAgICAgICAgICkgJiYKICAgICAgICAgICAgISgkb2JqZWN0ID0gJHRoaXMtPnBhcnNlUHJpbWFyeUV4cHJlc3Npb24oKSkKICAgICAgICApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICgkbmV3VG9rZW5zQ291bnQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHZhbGlkID0gdHJ1ZTsKICAgICAgICAkb3B0aW9uYWxDaGFpbiA9IGZhbHNlOwogICAgICAgICRwcm9wZXJ0aWVzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAkb3B0aW9uYWwgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCRvcFRva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVPbmVPZihhcnJheSgiPy4iLCAiLiIpKSkgewogICAgICAgICAgICAgICAgJGlzT3B0Q2hhaW4gPSAkb3BUb2tlbi0+Z2V0VmFsdWUoKSA9PSAiPy4iOwogICAgICAgICAgICAgICAgaWYgKCRpc09wdENoYWluKSB7CiAgICAgICAgICAgICAgICAgICAgJG9wdGlvbmFsQ2hhaW4gPSAkb3B0aW9uYWwgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZUlkZW50aWZpZXIoc3RhdGljOjokaWRlbnRpZmllck5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkcHJvcGVydGllc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIj0+ICJpZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbmZvIiA9PiAkcHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb25hbCIgPT4gJG9wdGlvbmFsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkaXNPcHRDaGFpbikgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJbIikpIHsKICAgICAgICAgICAgICAgIGlmICgoJHByb3BlcnR5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUV4cHJlc3Npb24iCiAgICAgICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiXSIpCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICRwcm9wZXJ0aWVzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiID0+ICJjb21wdXRlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbmZvIiA9PiBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcm9wZXJ0eSwgJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCkKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbmFsIiA9PiAkb3B0aW9uYWwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKCRwcm9wZXJ0eSA9ICR0aGlzLT5wYXJzZVRlbXBsYXRlTGl0ZXJhbCh0cnVlKSkgewogICAgICAgICAgICAgICAgaWYgKCRvcHRpb25hbENoYWluKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9wdGlvbmFsIGNoYWluIGNhbid0IGFwcGVhciBpbiB0YWdnZWQgdGVtcGxhdGUgZXhwcmVzc2lvbnMiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgICAgICAgICAkcHJvcGVydGllc1tdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgInR5cGUiPT4gInRlbXBsYXRlIiwKICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gJHByb3BlcnR5LAogICAgICAgICAgICAgICAgICAgICJvcHRpb25hbCIgPT4gJG9wdGlvbmFsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2VpZiAoKCRhcmdzID0gJHRoaXMtPnBhcnNlQXJndW1lbnRzKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkdmFsaWQgPSB0cnVlOwogICAgICAgICAgICAgICAgJHByb3BlcnRpZXNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICJ0eXBlIj0+ICJhcmdzIiwKICAgICAgICAgICAgICAgICAgICAiaW5mbyIgPT4gYXJyYXkoJGFyZ3MsICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpKSwKICAgICAgICAgICAgICAgICAgICAib3B0aW9uYWwiID0+ICRvcHRpb25hbAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRwcm9wQ291bnQgPSBjb3VudCgkcHJvcGVydGllcyk7CiAgICAgICAgCiAgICAgICAgaWYgKCEkdmFsaWQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0gZWxzZWlmICghJHByb3BDb3VudCAmJiAhJG5ld1Rva2Vuc0NvdW50KSB7CiAgICAgICAgICAgIHJldHVybiAkb2JqZWN0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbm9kZSA9IG51bGw7CiAgICAgICAgJGVuZFBvcyA9ICRvYmplY3QtPmdldExvY2F0aW9uKCktPmdldEVuZCgpOwogICAgICAgICRvcHRpb25hbENoYWluU3RhcnRlZCA9IGZhbHNlOwogICAgICAgIGZvcmVhY2ggKCRwcm9wZXJ0aWVzIGFzICRpID0+ICRwcm9wZXJ0eSkgewogICAgICAgICAgICAkbGFzdE5vZGUgPSAkbm9kZSA/ICRub2RlIDogJG9iamVjdDsKICAgICAgICAgICAgaWYgKCRwcm9wZXJ0eVsib3B0aW9uYWwiXSkgewogICAgICAgICAgICAgICAgJG9wdGlvbmFsQ2hhaW5TdGFydGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHByb3BlcnR5WyJ0eXBlIl0gPT09ICJhcmdzIikgewogICAgICAgICAgICAgICAgaWYgKCRuZXdUb2tlbnNDb3VudCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkb3B0aW9uYWxDaGFpblN0YXJ0ZWQgJiYgJG5ld1Rva2Vuc0NvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3B0aW9uYWwgY2hhaW4gY2FuJ3QgYXBwZWFyIGluIG5ldyBleHByZXNzaW9ucyIKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgIk5ld0V4cHJlc3Npb24iLCBhcnJheV9wb3AoJG5ld1Rva2VucykKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRuZXdUb2tlbnNDb3VudC0tOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJDYWxsRXhwcmVzc2lvbiIsICRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgJG5vZGUtPnNldE9wdGlvbmFsKCRwcm9wZXJ0eVsib3B0aW9uYWwiXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q2FsbGVlKCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnRzKCRwcm9wZXJ0eVsiaW5mbyJdWzBdKTsKICAgICAgICAgICAgICAgICRlbmRQb3MgPSAkcHJvcGVydHlbImluZm8iXVsxXTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRwcm9wZXJ0eVsidHlwZSJdID09PSAiaWQiKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJNZW1iZXJFeHByZXNzaW9uIiwgJGxhc3ROb2RlKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRPYmplY3QoJGxhc3ROb2RlKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRPcHRpb25hbCgkcHJvcGVydHlbIm9wdGlvbmFsIl0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldFByb3BlcnR5KCRwcm9wZXJ0eVsiaW5mbyJdKTsKICAgICAgICAgICAgICAgICRlbmRQb3MgPSAkcHJvcGVydHlbImluZm8iXS0+Z2V0TG9jYXRpb24oKS0+Z2V0RW5kKCk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHlbInR5cGUiXSA9PT0gImNvbXB1dGVkIikgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiTWVtYmVyRXhwcmVzc2lvbiIsICRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5WyJpbmZvIl1bMF0pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldE9wdGlvbmFsKCRwcm9wZXJ0eVsib3B0aW9uYWwiXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q29tcHV0ZWQodHJ1ZSk7CiAgICAgICAgICAgICAgICAkZW5kUG9zID0gJHByb3BlcnR5WyJpbmZvIl1bMV07CiAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcGVydHlbInR5cGUiXSA9PT0gInRlbXBsYXRlIikgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uIiwgJG9iamVjdCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0VGFnKCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UXVhc2koJHByb3BlcnR5WyJpbmZvIl0pOwogICAgICAgICAgICAgICAgJGVuZFBvcyA9ICRwcm9wZXJ0eVsiaW5mbyJdLT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUsICRlbmRQb3MpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1dyYXAgdGhlIHJlc3VsdCBpbiBtdWx0aXBsZSBOZXdFeHByZXNzaW9uIGlmIHRoZXJlIGFyZSAibmV3IiB0b2tlbnMKICAgICAgICBpZiAoJG5ld1Rva2Vuc0NvdW50KSB7CiAgICAgICAgICAgIGZvciAoJGkgPSAkbmV3VG9rZW5zQ291bnQgLSAxOyAkaSA+PSAwOyAkaS0tKSB7CiAgICAgICAgICAgICAgICAkbGFzdE5vZGUgPSAkbm9kZSA/ICRub2RlIDogJG9iamVjdDsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk5ld0V4cHJlc3Npb24iLCAkbmV3VG9rZW5zWyRpXSk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q2FsbGVlKCRsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1dyYXAgdGhlIHJlc3VsdCBpbiBhIGNoYWluIGV4cHJlc3Npb24gaWYgcmVxdWlyZWQKICAgICAgICBpZiAoJG9wdGlvbmFsQ2hhaW4pIHsKICAgICAgICAgICAgJHByZXZOb2RlID0gJG5vZGU7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkNoYWluRXhwcmVzc2lvbiIsICRwcmV2Tm9kZSk7CiAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9uKCRwcmV2Tm9kZSk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkbm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzcHJlYWQgZWxlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcU3ByZWFkRWxlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVNwcmVhZEVsZW1lbnQoKQogICAgewogICAgICAgIGlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLi4uIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRhcmd1bWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24iCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICgkYXJndW1lbnQpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlNwcmVhZEVsZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50KCRhcmd1bWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGFuIGFycmF5IGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXEFycmF5RXhwcmVzc2lvbnxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFycmF5TGl0ZXJhbCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJbIikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICRlbGVtZW50cyA9IGFycmF5KCk7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoJGVsaXNpb24gPSAkdGhpcy0+cGFyc2VFbGlzaW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICAkZWxlbWVudHMgPSBhcnJheV9tZXJnZSgKICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzLCBhcnJheV9maWxsKDAsICRlbGlzaW9uLCBudWxsKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoKCRlbGVtZW50ID0gJHRoaXMtPnBhcnNlU3ByZWFkRWxlbWVudCgpKSB8fAogICAgICAgICAgICAgICAgICAgICgkZWxlbWVudCA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICAgICApKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnRzW10gPSAkZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIsIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJdIikpIHsKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIkFycmF5RXhwcmVzc2lvbiIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0RWxlbWVudHMoJGVsZW1lbnRzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXJndW1lbnRzIGxpc3Qgd3JhcHBlZCBpbiByb3VuZCBicmFja2V0cwogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlQXJndW1lbnRzKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIigiKSkgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkYXJncyA9ICR0aGlzLT5wYXJzZUFyZ3VtZW50TGlzdCgpKSAhPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIikiKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkYXJnczsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYW4gYXJndW1lbnRzIGxpc3QKICAgICAqIAogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUFyZ3VtZW50TGlzdCgpCiAgICB7CiAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICRoYXNDb21tYSA9IGZhbHNlOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICRzcHJlYWQgPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLi4uIik7CiAgICAgICAgICAgICRleHAgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICApOwoKICAgICAgICAgICAgaWYgKCEkZXhwKSB7CiAgICAgICAgICAgICAgICAvL0lmIHRoZXJlJ3Mgbm8gZXhwcmVzc2lvbiBhbmQgdGhlIHNwcmVhZCBkb3RzIGhhdmUgYmVlbiBmb3VuZAogICAgICAgICAgICAgICAgLy9vciB0aGVyZSBpcyBhIHRyYWlsaW5nIGNvbW1hIHRoYXQgaXMgbm90IGFsbG93ZWQsIHRocm93IGFuCiAgICAgICAgICAgICAgICAvL2Vycm9yCiAgICAgICAgICAgICAgICBpZiAoJHNwcmVhZCB8fAogICAgICAgICAgICAgICAgICAgICgkaGFzQ29tbWEgJiYKICAgICAgICAgICAgICAgICAgICAhJHRoaXMtPmZlYXR1cmVzLT50cmFpbGluZ0NvbW1hRnVuY3Rpb25DYWxsRGVjbGFyYXRpb24pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkc3ByZWFkKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJTcHJlYWRFbGVtZW50IiwgJHNwcmVhZCk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0QXJndW1lbnQoJGV4cCk7CiAgICAgICAgICAgICAgICAkbGlzdFtdID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbGlzdFtdID0gJGV4cDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLCIpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkaGFzQ29tbWEgPSB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3VwZXIgY2FsbCBvciBhIHN1cGVyIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU3VwZXJQcm9wZXJ0eU9yQ2FsbCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJzdXBlciIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkc3VwZXIgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCR0aGlzLT5jcmVhdGVOb2RlKCJTdXBlciIsICR0b2tlbikpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCgkYXJncyA9ICR0aGlzLT5wYXJzZUFyZ3VtZW50cygpKSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQ2FsbEV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAgICAgJG5vZGUtPnNldEFyZ3VtZW50cygkYXJncyk7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0Q2FsbGVlKCRzdXBlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk1lbWJlckV4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0T2JqZWN0KCRzdXBlcik7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIi4iKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJHByb3BlcnR5ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcihzdGF0aWM6OiRpZGVudGlmaWVyTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZWlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiWyIpICYmCiAgICAgICAgICAgICAgICAoJHByb3BlcnR5ID0gJHRoaXMtPmlzb2xhdGVDb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGFycmF5KCJhbGxvd0luIiA9PiB0cnVlKSwgInBhcnNlRXhwcmVzc2lvbiIKICAgICAgICAgICAgICAgICkpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiXSIpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BlcnR5KTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRDb21wdXRlZCh0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwcmltYXJ5IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VQcmltYXJ5RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ0aGlzIikpIHsKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiVGhpc0V4cHJlc3Npb24iLCAkdG9rZW4pOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VMaXRlcmFsKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VBcnJheUxpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZU9iamVjdExpdGVyYWwoKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZUZ1bmN0aW9uT3JHZW5lcmF0b3JFeHByZXNzaW9uKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VDbGFzc0V4cHJlc3Npb24oKSkgewogICAgICAgICAgICByZXR1cm4gJGV4cDsKICAgICAgICB9IGVsc2VpZiAoJGV4cCA9ICR0aGlzLT5wYXJzZVJlZ3VsYXJFeHByZXNzaW9uTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgIHJldHVybiAkZXhwOwogICAgICAgIH0gZWxzZWlmICgkZXhwID0gJHRoaXMtPnBhcnNlVGVtcGxhdGVMaXRlcmFsKCkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCRleHAgPSAkdGhpcy0+cGFyc2VJZGVudGlmaWVyKHN0YXRpYzo6JGlkZW50aWZpZXJSZWZlcmVuY2UpKSB7CiAgICAgICAgICAgIHJldHVybiAkZXhwOwogICAgICAgIH0gZWxzZWlmICgkdGhpcy0+anN4ICYmICgkZXhwID0gJHRoaXMtPnBhcnNlSlNYRnJhZ21lbnQoKSkpIHsKICAgICAgICAgICAgcmV0dXJuICRleHA7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5qc3ggJiYgKCRleHAgPSAkdGhpcy0+cGFyc2VKU1hFbGVtZW50KCkpKSB7CiAgICAgICAgICAgIHJldHVybiAkZXhwOwogICAgICAgIH0gZWxzZWlmICgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiKCIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKCRleHAgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9uKCRleHApOwogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBpbnQgICAkbW9kZSAgICAgICBQYXJzaW5nIG1vZGUsIG9uZSBvZiB0aGUgaWQgcGFyc2luZyBtb2RlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhZnRlciAgICAgSWYgYSBzdHJpbmcgaXMgcGFzc2VkIGluIHRoaXMgcGFyYW1ldGVyLCB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyIGlzIHBhcnNlZCBvbmx5IGlmIHByZWNlZWRzIHRoaXMgc3RyaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxJZGVudGlmaWVyfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSWRlbnRpZmllcigkbW9kZSwgJGFmdGVyID0gbnVsbCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoISR0b2tlbikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKCRhZnRlciAhPT0gbnVsbCkgewogICAgICAgICAgICAkbmV4dCA9ICR0aGlzLT5zY2FubmVyLT5nZXROZXh0VG9rZW4oKTsKICAgICAgICAgICAgaWYgKCEkbmV4dCB8fCAkbmV4dC0+Z2V0VmFsdWUoKSAhPT0gJGFmdGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdHlwZSA9ICR0b2tlbi0+Z2V0VHlwZSgpOwogICAgICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICAgICAgY2FzZSBUb2tlbjo6VFlQRV9CT09MRUFOX0xJVEVSQUw6CiAgICAgICAgICAgIGNhc2UgVG9rZW46OlRZUEVfTlVMTF9MSVRFUkFMOgogICAgICAgICAgICAgICAgaWYgKCRtb2RlICE9PSBzZWxmOjpJRF9BTExPV19BTEwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgVG9rZW46OlRZUEVfS0VZV09SRDoKICAgICAgICAgICAgICAgIGlmICgkbW9kZSA9PT0gc2VsZjo6SURfQUxMT1dfTk9USElORykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRtb2RlID09PSBzZWxmOjpJRF9NSVhFRCAmJgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5pc1N0cmljdE1vZGVLZXl3b3JkKCR0b2tlbikKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGlmICgkdHlwZSAhPT0gVG9rZW46OlRZUEVfSURFTlRJRklFUikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9FeGNsdWRlIGtleXdvcmRzIHRoYXQgZGVwZW5kIG9uIHBhcnNlciBjb250ZXh0CiAgICAgICAgJHZhbHVlID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgIGlmICgkbW9kZSA9PT0gc2VsZjo6SURfTUlYRUQgJiYKICAgICAgICAgICAgaXNzZXQoJHRoaXMtPmNvbnRleHRLZXl3b3Jkc1skdmFsdWVdKSAmJgogICAgICAgICAgICAkdGhpcy0+Y29udGV4dC0+eyR0aGlzLT5jb250ZXh0S2V5d29yZHNbJHZhbHVlXX0KICAgICAgICApIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJJZGVudGlmaWVyIiwgJHRva2VuKTsKICAgICAgICAkbm9kZS0+c2V0TmFtZSgkdmFsdWUpOwogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxMaXRlcmFsfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbCgpCiAgICB7CiAgICAgICAgaWYgKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpKSB7CiAgICAgICAgICAgIGlmICgkdG9rZW4tPmdldFR5cGUoKSA9PT0gVG9rZW46OlRZUEVfTlVMTF9MSVRFUkFMKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJOdWxsTGl0ZXJhbCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdG9rZW4tPmdldFR5cGUoKSA9PT0gVG9rZW46OlRZUEVfQk9PTEVBTl9MSVRFUkFMKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJCb29sZWFuTGl0ZXJhbCIsICR0b2tlbik7CiAgICAgICAgICAgICAgICAkbm9kZS0+c2V0UmF3KCR0b2tlbi0+Z2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkbGl0ZXJhbCA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRsaXRlcmFsOwogICAgICAgICAgICB9IGVsc2VpZiAoJGxpdGVyYWwgPSAkdGhpcy0+cGFyc2VOdW1lcmljTGl0ZXJhbCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJGxpdGVyYWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgc3RyaW5nIGxpdGVyYWwKICAgICAqIAogICAgICogQHJldHVybiBOb2RlXFN0cmluZ0xpdGVyYWx8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTdHJpbmdMaXRlcmFsKCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoJHRva2VuICYmICR0b2tlbi0+Z2V0VHlwZSgpID09PSBUb2tlbjo6VFlQRV9TVFJJTkdfTElURVJBTCkgewogICAgICAgICAgICAkdmFsID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tJbnZhbGlkRXNjYXBlU2VxdWVuY2VzKCR2YWwpOwogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIlN0cmluZ0xpdGVyYWwiLCAkdG9rZW4pOwogICAgICAgICAgICAkbm9kZS0+c2V0UmF3KCR2YWwpOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIG51bWVyaWMgbGl0ZXJhbAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTnVtZXJpY0xpdGVyYWx8Tm9kZVxCaWdJbnRMaXRlcmFsfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTnVtZXJpY0xpdGVyYWwoKQogICAgewogICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICgkdG9rZW4gJiYgJHRva2VuLT5nZXRUeXBlKCkgPT09IFRva2VuOjpUWVBFX05VTUVSSUNfTElURVJBTCkgewogICAgICAgICAgICAkdmFsID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tJbnZhbGlkRXNjYXBlU2VxdWVuY2VzKCR2YWwsIHRydWUpOwogICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZU5vZGUoIk51bWVyaWNMaXRlcmFsIiwgJHRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdmFsKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0gZWxzZWlmICgkdG9rZW4gJiYgJHRva2VuLT5nZXRUeXBlKCkgPT09IFRva2VuOjpUWVBFX0JJR0lOVF9MSVRFUkFMKSB7CiAgICAgICAgICAgICR2YWwgPSAkdG9rZW4tPmdldFZhbHVlKCk7CiAgICAgICAgICAgICR0aGlzLT5jaGVja0ludmFsaWRFc2NhcGVTZXF1ZW5jZXMoJHZhbCwgdHJ1ZSk7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiQmlnSW50TGl0ZXJhbCIsICR0b2tlbik7CiAgICAgICAgICAgICRub2RlLT5zZXRSYXcoJHZhbCk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEgdGVtcGxhdGUgbGl0ZXJhbAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkdGFnZ2VkIFRydWUgaWYgdGhlIHRlbXBsYXRlIGlzIHRhZ2dlZAogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTGl0ZXJhbHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZVRlbXBsYXRlTGl0ZXJhbCgkdGFnZ2VkID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgCiAgICAgICAgaWYgKCEkdG9rZW4gfHwgJHRva2VuLT5nZXRUeXBlKCkgIT09IFRva2VuOjpUWVBFX1RFTVBMQVRFKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0RvIG5vdCBwYXJzZSB0ZW1wbGF0ZXMgcGFydHMKICAgICAgICAkdmFsID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgIGlmICgkdmFsWzBdICE9PSAiYCIpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRxdWFzaXMgPSAkZXhwcmVzc2lvbnMgPSBhcnJheSgpOwogICAgICAgICR2YWxpZCA9IGZhbHNlOwogICAgICAgIGRvIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAkdmFsID0gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICAkdGhpcy0+Y2hlY2tJbnZhbGlkRXNjYXBlU2VxdWVuY2VzKCR2YWwsIGZhbHNlLCB0cnVlLCAkdGFnZ2VkKTsKICAgICAgICAgICAgJGxhc3RDaGFyID0gc3Vic3RyKCR2YWwsIC0xKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRxdWFzaSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJUZW1wbGF0ZUVsZW1lbnQiLCAkdG9rZW4pOwogICAgICAgICAgICAkcXVhc2ktPnNldFJhd1ZhbHVlKCR2YWwpOwogICAgICAgICAgICBpZiAoJGxhc3RDaGFyID09PSAiYCIpIHsKICAgICAgICAgICAgICAgICRxdWFzaS0+c2V0VGFpbCh0cnVlKTsKICAgICAgICAgICAgICAgICRxdWFzaXNbXSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJHF1YXNpKTsKICAgICAgICAgICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRxdWFzaXNbXSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJHF1YXNpKTsKICAgICAgICAgICAgICAgICRleHAgPSAkdGhpcy0+aXNvbGF0ZUNvbnRleHQoCiAgICAgICAgICAgICAgICAgICAgYXJyYXkoImFsbG93SW4iID0+IHRydWUpLCAicGFyc2VFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkZXhwKSB7CiAgICAgICAgICAgICAgICAgICAgJGV4cHJlc3Npb25zW10gPSAkZXhwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldFRva2VuKCk7CiAgICAgICAgfSB3aGlsZSAoJHRva2VuICYmICR0b2tlbi0+Z2V0VHlwZSgpID09PSBUb2tlbjo6VFlQRV9URU1QTEFURSk7CiAgICAgICAgCiAgICAgICAgaWYgKCR2YWxpZCkgewogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJUZW1wbGF0ZUxpdGVyYWwiLCAkcXVhc2lzWzBdKTsKICAgICAgICAgICAgJG5vZGUtPnNldFF1YXNpcygkcXVhc2lzKTsKICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucyk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBsaXRlcmFsCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZVxMaXRlcmFsfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlUmVndWxhckV4cHJlc3Npb25MaXRlcmFsKCkKICAgIHsKICAgICAgICBpZiAoJHRva2VuID0gJHRoaXMtPnNjYW5uZXItPnJlY29uc3VtZUN1cnJlbnRUb2tlbkFzUmVnZXhwKCkpIHsKICAgICAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJSZWdFeHBMaXRlcmFsIiwgJHRva2VuKTsKICAgICAgICAgICAgJG5vZGUtPnNldFJhdygkdG9rZW4tPmdldFZhbHVlKCkpOwogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlIGRpcmVjdGl2ZSBwcm9sb2d1ZXMuIFRoZSByZXN1bHQgaXMgYW4gYXJyYXkgd2hlcmUgdGhlIGZpcnN0IGVsZW1lbnQKICAgICAqIGlzIHRoZSBhcnJheSBvZiBwYXJzZWQgbm9kZXMgYW5kIHRoZSBzZWNvbmQgZWxlbWVudCBpcyB0aGUgYXJyYXkgb2YKICAgICAqIGRpcmVjdGl2ZSBwcm9sb2d1ZXMgdmFsdWVzCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VEaXJlY3RpdmVQcm9sb2d1ZXMoKQogICAgewogICAgICAgICRkaXJlY3RpdmVzID0gJG5vZGVzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoKCR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpKSAmJgogICAgICAgICAgICAkdG9rZW4tPmdldFR5cGUoKSA9PT0gVG9rZW46OlRZUEVfU1RSSU5HX0xJVEVSQUwKICAgICAgICApIHsKICAgICAgICAgICAgJGRpcmVjdGl2ZSA9IHN1YnN0cigkdG9rZW4tPmdldFZhbHVlKCksIDEsIC0xKTsKICAgICAgICAgICAgaWYgKCRkaXJlY3RpdmUgPT09ICJ1c2Ugc3RyaWN0IikgewogICAgICAgICAgICAgICAgJGRpcmVjdGl2ZXNbXSA9ICRkaXJlY3RpdmU7CiAgICAgICAgICAgICAgICAkZGlyZWN0aXZlTm9kZSA9ICR0aGlzLT5wYXJzZVN0cmluZ0xpdGVyYWwoKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hc3NlcnRFbmRPZlN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiRXhwcmVzc2lvblN0YXRlbWVudCIsICRkaXJlY3RpdmVOb2RlKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRFeHByZXNzaW9uKCRkaXJlY3RpdmVOb2RlKTsKICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY291bnQoJG5vZGVzKSA/IGFycmF5KCRub2RlcywgJGRpcmVjdGl2ZXMpIDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBpbXBvcnQgY2FsbAogICAgICoKICAgICAqIEByZXR1cm4gTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSW1wb3J0Q2FsbCgpCiAgICB7CiAgICAgICAgaWYgKCgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiaW1wb3J0IikpICYmCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIoIikpIHsKCiAgICAgICAgICAgIGlmICgoJHNvdXJjZSA9ICR0aGlzLT5pc29sYXRlQ29udGV4dCgKICAgICAgICAgICAgICAgICAgICBhcnJheSgiYWxsb3dJbiIgPT4gdHJ1ZSksICJwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uIgogICAgICAgICAgICAgICAgKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIpIikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVOb2RlKCJJbXBvcnRFeHByZXNzaW9uIiwgJHRva2VuKTsKICAgICAgICAgICAgICAgICRub2RlLT5zZXRTb3VyY2UoJHNvdXJjZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBsZXRlTm9kZSgkbm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBzdHJpbmcgb3IgbnVtYmVyIGNvbnRhaW5zIGludmFsaWQgZWNzYXBlIHNlcXVlbmNlcwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICAkdmFsICAgICAgICAgICAgICAgICAgICAgIFZhbHVlIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkbnVtYmVyICAgICAgICAgICAgICAgICAgIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgbnVtYmVyCiAgICAgKiBAcGFyYW0gYm9vbCAgICAkZm9yY2VMZWdhY3lPY3RhbENoZWNrICAgIFRydWUgdG8gZm9yY2UgbGVnYWN5IG9jdGFsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm0gY2hlY2sKICAgICAqIEBwYXJhbSBib29sICAgICR0YWdnZWRUZW1wbGF0ZSAgICAgICAgICAgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSB0YWdnZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjaGVja0ludmFsaWRFc2NhcGVTZXF1ZW5jZXMoCiAgICAgICAgJHZhbCwgJG51bWJlciA9IGZhbHNlLCAkZm9yY2VMZWdhY3lPY3RhbENoZWNrID0gZmFsc2UsCiAgICAgICAgJHRhZ2dlZFRlbXBsYXRlID0gZmFsc2UKICAgICkgewogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPnNraXBFc2NhcGVTZXFDaGVja0luVGFnZ2VkVGVtcGxhdGVzICYmCiAgICAgICAgICAgICR0YWdnZWRUZW1wbGF0ZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICRjaGVja0xlZ2FjeU9jdGFsID0gJGZvcmNlTGVnYWN5T2N0YWxDaGVjayB8fCAkdGhpcy0+c2Nhbm5lci0+Z2V0U3RyaWN0TW9kZSgpOwogICAgICAgIGlmICgkbnVtYmVyKSB7CiAgICAgICAgICAgIGlmICgkdmFsICYmICR2YWxbMF0gPT09ICIwIiAmJiBwcmVnX21hdGNoKCIjXjBbMC03X10rJCMiLCAkdmFsKSkgewogICAgICAgICAgICAgICAgaWYgKCRjaGVja0xlZ2FjeU9jdGFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk9jdGFsIGxpdGVyYWxzIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5mZWF0dXJlcy0+bnVtZXJpY0xpdGVyYWxTZXBhcmF0b3IgJiYKICAgICAgICAgICAgICAgICAgICBzdHJwb3MoJHZhbCwgJ18nKSAhPT0gZmFsc2UKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICJOdW1lcmljIHNlcGFyYXRvcnMgYXJlIG5vdCBhbGxvd2VkIGluIGxlZ2FjeSBvY3RhbCBudW1iZXJzIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoc3RycG9zKCR2YWwsICJcXCIpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkaGV4ID0gIjAtOWEtZkEtRiI7CiAgICAgICAgICAgICRpbnZhbGlkU3ludGF4ID0gYXJyYXkoCiAgICAgICAgICAgICAgICAieFskaGV4XT9bXiRoZXhdIiwKICAgICAgICAgICAgICAgICJ4WyRoZXhdPyQiLAogICAgICAgICAgICAgICAgInVce1x9IiwKICAgICAgICAgICAgICAgICJ1XHsoPzpbJGhleF0qW14kaGV4XH1dKykrWyRoZXhdKlx9IiwKICAgICAgICAgICAgICAgICJ1XHtbXlx9XSokIiwKICAgICAgICAgICAgICAgICJ1KD8heylbJGhleF17MCwzfVteJGhleFx7XSIsCiAgICAgICAgICAgICAgICAidVskaGV4XXswLDN9JCIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRjaGVja0xlZ2FjeU9jdGFsKSB7CiAgICAgICAgICAgICAgICAkaW52YWxpZFN5bnRheFtdID0gIlswLTddezJ9IjsKICAgICAgICAgICAgICAgICRpbnZhbGlkU3ludGF4W10gPSAiWzEtN10iOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZWcgPSAiIyhcXFxcKykoIiAuIGltcGxvZGUoInwiLCAkaW52YWxpZFN5bnRheCkgLiAiKSMiOwogICAgICAgICAgICBpZiAocHJlZ19tYXRjaF9hbGwoJHJlZywgJHZhbCwgJG1hdGNoZXMsIFBSRUdfU0VUX09SREVSKSkgewogICAgICAgICAgICAgICAgZm9yZWFjaCAoJG1hdGNoZXMgYXMgJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkbWF0Y2hbMV0pICUgMikgewogICAgICAgICAgICAgICAgICAgICAgICAkZmlyc3QgPSAkbWF0Y2hbMl1bMF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZmlyc3QgPT09ICJ1IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVyciA9ICJNYWxmb3JtZWQgdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UiOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGZpcnN0ID09PSAieCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlcnIgPSAiTWFsZm9ybWVkIGhleGFkZWNpbWFsIGVzY2FwZSBzZXF1ZW5jZSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXJyID0gIk9jdGFsIGxpdGVyYWxzIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigkZXJyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBDb21tZW50cyByZWdpc3RyeSBjbGFzcy4gSW50ZXJuYWwgY2xhc3MgdXNlZCB0byBtYW5hZ2UgY29tbWVudHMKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tbWVudHNSZWdpc3RyeQp7CiAgICAvKioKICAgICAqIE1hcCBvZiB0aGUgaW5kaWNlcyB3aGVyZSBub2RlcyBzdGFydAogICAgICogCiAgICAgKiBAdmFyIGludCAKICAgICAqLwogICAgcHJvdGVjdGVkICRub2Rlc1N0YXJ0TWFwID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBNYXAgb2YgdGhlIGluZGljZXMgd2hlcmUgbm9kZXMgZW5kCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJG5vZGVzRW5kTWFwID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyBidWZmZXIKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJGJ1ZmZlciA9IG51bGw7CiAgICAKICAgIC8qKgogICAgICogTGFzdCB0b2tlbiBpbmRleAogICAgICogCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhc3RUb2tlbkluZGV4ID0gbnVsbDsKICAgIAogICAgLyoqCiAgICAgKiBDb21tZW50cyByZWdpc3RyeQogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmVnaXN0cnkgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXJzZXIgICAgJHBhcnNlciAgICAgUGFyc2VyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChQYXJzZXIgJHBhcnNlcikKICAgIHsKICAgICAgICAkcGFyc2VyLT5nZXRFdmVudHNFbWl0dGVyKCkKICAgICAgICAgICAgICAgLT5hZGRMaXN0ZW5lcigiTm9kZUNvbXBsZXRlZCIsIGFycmF5KCR0aGlzLCAib25Ob2RlQ29tcGxldGVkIikpCiAgICAgICAgICAgICAgIC0+YWRkTGlzdGVuZXIoIkVuZFBhcnNpbmciLCBhcnJheSgkdGhpcywgIm9uRW5kUGFyc2luZyIpKTsKICAgICAgICAKICAgICAgICAkcGFyc2VyLT5nZXRTY2FubmVyKCktPmdldEV2ZW50c0VtaXR0ZXIoKQogICAgICAgICAgICAgICAtPmFkZExpc3RlbmVyKCJUb2tlbkNvbnN1bWVkIiwgYXJyYXkoJHRoaXMsICJvblRva2VuQ29uc3VtZWQiKSkKICAgICAgICAgICAgICAgLT5hZGRMaXN0ZW5lcigiRW5kUmVhY2hlZCIsIGFycmF5KCR0aGlzLCAib25Ub2tlbkNvbnN1bWVkIikpCiAgICAgICAgICAgICAgIC0+YWRkTGlzdGVuZXIoIkZyZWV6ZVN0YXRlIiwgYXJyYXkoJHRoaXMsICJvblNjYW5uZXJGcmVlemVTdGF0ZSIpKQogICAgICAgICAgICAgICAtPmFkZExpc3RlbmVyKCJSZXNldFN0YXRlIiwgYXJyYXkoJHRoaXMsICJvblNjYW5uZXJSZXNldFN0YXRlIikpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIExpc3RlbmVyIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBzY2FubmVyIGNvbXBvc2UgdGhlIGFycmF5IHRoYXQgcmVwcmVzZW50cwogICAgICogaXRzIGN1cnJlbnQgc3RhdGUKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICAgJHN0YXRlICAgU3RhdGUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvblNjYW5uZXJGcmVlemVTdGF0ZSgmJHN0YXRlKQogICAgewogICAgICAgIC8vUmVnaXN0ZXIgdGhlIGN1cnJlbnQgbGFzdCB0b2tlbiBpbmRleAogICAgICAgICRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdID0gJHRoaXMtPmxhc3RUb2tlbkluZGV4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIExpc3RlbmVyIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBzY2FubmVyIHJlc2V0IGl0cyBzdGF0ZSB1c2luZyB0aGUgZ2l2ZW4KICAgICAqIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAgICRzdGF0ZSAgIFN0YXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25TY2FubmVyUmVzZXRTdGF0ZSgmJHN0YXRlKQogICAgewogICAgICAgIC8vUmVzZXQgdGhlIGxhc3QgdG9rZW4gaW5kZXggYW5kIGRlbGV0ZSBpdCBmcm9tIHRoZSBzdGF0ZSBhcnJheQogICAgICAgICR0aGlzLT5sYXN0VG9rZW5JbmRleCA9ICRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdOwogICAgICAgIHVuc2V0KCRzdGF0ZVsiY29tbWVudHNMYXN0VG9rZW5JbmRleCJdKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBMaXN0ZW5lciBjYWxsZWQgZXZlcnkgdGltZSBhIHRva2VuIGlzIGNvbnN1bWVkIGFuZCB3aGVuIHRoZSBzY2FubmVyCiAgICAgKiByZWFjaGVzIHRoZSBlbmQgb2YgdGhlIHNvdXJjZQogICAgICogCiAgICAgKiBAcGFyYW0gVG9rZW58bnVsbCAgICR0b2tlbiAgIENvbnN1bWVkIHRva2VuIG9yIG51bGwgaWYgdGhlIGVuZCBoYXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVlbiByZWFjaGVkCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gb25Ub2tlbkNvbnN1bWVkKFRva2VuICR0b2tlbiA9IG51bGwpCiAgICB7CiAgICAgICAgLy9DaGVjayBpZiBpdCdzIGEgY29tbWVudAogICAgICAgIGlmICgkdG9rZW4gJiYgJHRva2VuLT5nZXRUeXBlKCkgPT09IFRva2VuOjpUWVBFX0NPTU1FTlQpIHsKICAgICAgICAgICAgLy9JZiB0aGVyZSBpcyBub3QgYW4gb3BlbiBjb21tZW50cyBidWZmZXIsIGNyZWF0ZSBpdAogICAgICAgICAgICBpZiAoISR0aGlzLT5idWZmZXIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXIgPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAicHJldiIgPT4gJHRoaXMtPmxhc3RUb2tlbkluZGV4LAogICAgICAgICAgICAgICAgICAgICJuZXh0IiA9PiBudWxsLAogICAgICAgICAgICAgICAgICAgICJjb21tZW50cyIgPT4gYXJyYXkoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0FkZCB0aGUgY29tbWVudCB0b2tlbiB0byB0aGUgYnVmZmVyCiAgICAgICAgICAgICR0aGlzLT5idWZmZXJbImNvbW1lbnRzIl1bXSA9ICR0b2tlbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCR0b2tlbikgewogICAgICAgICAgICAgICAgJGxvYyA9ICR0b2tlbi0+Z2V0TG9jYXRpb24oKTsKICAgICAgICAgICAgICAgIC8vU3RvcmUgdGhlIHRva2VuIGVuZCBwb3NpdGlvbgogICAgICAgICAgICAgICAgJHRoaXMtPmxhc3RUb2tlbkluZGV4ID0gJGxvYy0+Z2V0RW5kKCktPmdldEluZGV4KCk7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgIC8vRmlsbCB0aGUgIm5leHQiIGtleSBvbiB0aGUgY29tbWVudHMgYnVmZmVyIHdpdGggdGhlIHRva2VuCiAgICAgICAgICAgICAgICAgICAgLy9zdGFydCBwb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXJbIm5leHQiXSA9ICRsb2MtPmdldFN0YXJ0KCktPmdldEluZGV4KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vSWYgdGhlcmUgaXMgYW4gb3BlbiBjb21tZW50IGJ1ZmZlciwgY2xvc2UgaXQgYW5kIG1vdmUgaXQgdG8gdGhlCiAgICAgICAgICAgIC8vcmVnaXN0cnkKICAgICAgICAgICAgaWYgKCRidWZmZXIgPSAkdGhpcy0+YnVmZmVyKSB7CiAgICAgICAgICAgICAgICAvL1VzZSB0aGUgbG9jYXRpb24gYXMga2V5IHRvIGFkZCB0aGUgZ3JvdXAgb2YgY29tbWVudHMgdG8gdGhlCiAgICAgICAgICAgICAgICAvL3JlZ2lzdHJ5LCBpbiB0aGlzIHdheSBpZiBjb21tZW50cyBhcmUgcmVwcm9jZXNzZWQgdGhleSB3b24ndAogICAgICAgICAgICAgICAgLy9iZSBkdXBsaWNhdGVkCiAgICAgICAgICAgICAgICAka2V5ID0gaW1wbG9kZSgiLSIsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICRidWZmZXJbInByZXYiXSAhPT0gbnVsbCA/ICRidWZmZXJbInByZXYiXSA6ICIiLAogICAgICAgICAgICAgICAgICAgICRidWZmZXJbIm5leHQiXSAhPT0gbnVsbCA/ICRidWZmZXJbIm5leHQiXSA6ICIiCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgICAgICR0aGlzLT5yZWdpc3RyeVska2V5XSA9ICR0aGlzLT5idWZmZXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+YnVmZmVyID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogTGlzdGVuZXIgY2FsbGVkIGV2ZXJ5IHRpbWUgYSBub2RlIGlzIGNvbXBsZXRlZCBieSB0aGUgcGFyc2VyCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgICAkbm9kZSAgICAgQ29tcGxldGVkIG5vZGUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvbk5vZGVDb21wbGV0ZWQoTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgIC8vRXZlcnkgdGltZSBhIG5vZGUgaXMgY29tcGxldGVkLCByZWdpc3RlciBpdHMgc3RhcnQgYW5kIGVuZCBpbmRpY2VzCiAgICAgICAgLy9pbiB0aGUgcmVsYXRpdmUgcHJvcGVydGllcwogICAgICAgICRsb2MgPSAkbm9kZS0+Z2V0TG9jYXRpb24oKTsKICAgICAgICBmb3JlYWNoIChhcnJheSgiU3RhcnQiLCAiRW5kIikgYXMgJHBvcykgewogICAgICAgICAgICAkdmFsID0gJGxvYy0+eyJnZXQkcG9zIn0oKS0+Z2V0SW5kZXgoKTsKICAgICAgICAgICAgJG1hcCA9ICYkdGhpcy0+eyJub2Rlc3skcG9zfU1hcCJ9OwogICAgICAgICAgICBpZiAoIWlzc2V0KCRtYXBbJHZhbF0pKSB7CiAgICAgICAgICAgICAgICAkbWFwWyR2YWxdID0gYXJyYXkoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbWFwWyR2YWxdW10gPSAkbm9kZTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogTGlzdGVuZXIgY2FsbGVkIHdoZW4gcGFyc2luZyBwcm9jZXNzIGVuZHMKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBvbkVuZFBhcnNpbmcoKQogICAgewogICAgICAgIC8vUmV0dXJuIGlmIHRoZXJlIGFyZSBubyBjb21tZW50cyB0byBwcm9jZXNzCiAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RyeSkgewogICAgICAgICAgICAKICAgICAgICAgICAgLy9NYWtlIHN1cmUgbm9kZXMgc3RhcnQgaW5kaWNlcyBtYXAgaXMgc29ydGVkCiAgICAgICAgICAgIGtzb3J0KCR0aGlzLT5ub2Rlc1N0YXJ0TWFwKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vTG9vcCBhbGwgY29tbWVudCBncm91cHMgaW4gdGhlIHJlZ2lzdHJ5CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5yZWdpc3RyeSBhcyAkZ3JvdXApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5maW5kTm9kZUZvckNvbW1lbnRzR3JvdXAoJGdyb3VwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBGaW5kcyB0aGUgbm9kZSB0byBhdHRhY2ggdGhlIGdpdmVuIGNvbW1lbnRzIGdyb3VwCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheSAgICAkY29tbWVudHMgICBDb21tZW50cyBncm91cAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbmROb2RlRm9yQ29tbWVudHNHcm91cCgkZ3JvdXApCiAgICB7CiAgICAgICAgJG5leHQgPSAkZ3JvdXBbIm5leHQiXTsKICAgICAgICAkcHJldiA9ICRncm91cFsicHJldiJdOwogICAgICAgICRjb21tZW50cyA9ICRncm91cFsiY29tbWVudHMiXTsKICAgICAgICAkbGVhZGluZyA9IHRydWU7CiAgICAgICAgCiAgICAgICAgLy9JZiB0aGUgZ3JvdXAgb2YgY29tbWVudHMgaGFzIGEgbmV4dCB0b2tlbiBpbmRleCB0aGF0IGFwcGVhcnMKICAgICAgICAvL2luIHRoZSBtYXAgb2Ygc3RhcnQgbm9kZSBpbmRpY2VzLCBhZGQgdGhlIGdyb3VwIHRvIHRoZQogICAgICAgIC8vY29ycmVzcG9uZGluZyBub2RlJ3MgbGVhZGluZyBjb21tZW50cy4gVGhpcyBhc3NvY2lhdGVzCiAgICAgICAgLy9jb21tZW50cyB0aGF0IGFwcGVhciBpbW1lZGlhdGVseSBiZWZvcmUgYSBub2RlLgogICAgICAgIC8vRm9yIGV4YW1wbGU6IC8qY29tbWVudCovIGZvciAoOzspe30KICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPm5vZGVzU3RhcnRNYXBbJG5leHRdKSkgewogICAgICAgICAgICAkbm9kZXMgPSAkdGhpcy0+bm9kZXNTdGFydE1hcFskbmV4dF07CiAgICAgICAgfQogICAgICAgIC8vSWYgdGhlIGdyb3VwIG9mIGNvbW1lbnRzIGhhcyBhIHByZXZpb3VzIHRva2VuIGluZGV4IHRoYXQgYXBwZWFycwogICAgICAgIC8vaW4gdGhlIG1hcCBvZiBlbmQgbm9kZSBpbmRpY2VzLCBhZGQgdGhlIGdyb3VwIHRvIHRoZQogICAgICAgIC8vY29ycmVzcG9uZGluZyBub2RlJ3MgdHJhaWxpbmcgY29tbWVudHMuIFRoaXMgYXNzb2NpYXRlcwogICAgICAgIC8vY29tbWVudHMgdGhhdCBhcHBlYXIgaW1tZWRpYXRlbHkgYWZ0ZXIgYSBub2RlLgogICAgICAgIC8vRm9yIGV4YW1wbGU6IGZvciAoOzspe30gLypjb21tZW50Ki8gCiAgICAgICAgZWxzZWlmIChpc3NldCgkdGhpcy0+bm9kZXNFbmRNYXBbJHByZXZdKSkgewogICAgICAgICAgICAkbm9kZXMgPSAkdGhpcy0+bm9kZXNFbmRNYXBbJHByZXZdOwogICAgICAgICAgICAkbGVhZGluZyA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICAvL090aGVyd2lzZSwgZmluZCBhIG5vZGUgdGhhdCB3cmFwcyB0aGUgY29tbWVudHMgcG9zaXRpb24uCiAgICAgICAgLy9UaGlzIGFzc29jaWF0ZXMgaW5uZXIgY29tbWVudHM6CiAgICAgICAgLy9Gb3IgZXhhbXBsZTogZm9yIC8qY29tbWVudCovICg7Oyl7fQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvL0NhbGN1bGF0ZSBjb21tZW50cyBncm91cCBib3VuZGFyaWVzCiAgICAgICAgICAgICRzdGFydCA9ICRjb21tZW50c1swXS0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKS0+Z2V0SW5kZXgoKTsKICAgICAgICAgICAgJGVuZCA9ICRjb21tZW50c1tjb3VudCgkY29tbWVudHMpIC0xXS0+Z2V0TG9jYXRpb24oKS0+Z2V0RW5kKCktPmdldEluZGV4KCk7CiAgICAgICAgICAgICRub2RlcyA9IGFycmF5KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0xvb3AgYWxsIHRoZSBlbnRyaWVzIGluIHRoZSBzdGFydCBpbmRleCBtYXAKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5vZGVzU3RhcnRNYXAgYXMgJGlkeCA9PiAkbnMpIHsKICAgICAgICAgICAgICAgIC8vSWYgdGhlIGluZGV4IGlzIGhpZ2hlciB0aGFuIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgY29tbWVudHMKICAgICAgICAgICAgICAgIC8vZ3JvdXAsIHN0b3AKICAgICAgICAgICAgICAgIGlmICgkaWR4ID4gJHN0YXJ0KSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbnMgYXMgJG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoZSBjb21tZW50cyBncm91cCBpcyBpbnNpZGUgbm9kZSBpbmRpY2VzIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgaWYgKCRub2RlLT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0SW5kZXgoKSA+PSAkZW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRub2Rlc1tdID0gJG5vZGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0lmIGNvbW1lbnRzIGNhbid0IGJlIGFzc29jaWF0ZWQgd2l0aCBhbnkgbm9kZSwgYXNzb2NpYXRlIGl0IGFzCiAgICAgICAgICAgIC8vbGVhZGluZyBjb21tZW50cyBvZiB0aGUgcHJvZ3JhbSwgdGhpcyBoYXBwZW5zIHdoZW4gdGhlIHNvdXJjZSBpcwogICAgICAgICAgICAvL2VtcHR5CiAgICAgICAgICAgIGlmICghJG5vZGVzKSB7CiAgICAgICAgICAgICAgICAkZmlyc3ROb2RlID0gYXJyYXlfdmFsdWVzKCR0aGlzLT5ub2Rlc1N0YXJ0TWFwKTsKICAgICAgICAgICAgICAgICRub2RlcyA9IGFycmF5KCRmaXJzdE5vZGVbMF1bMF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vSWYgdGhlcmUgYXJlIG11bHRpcGxlIHBvc3NpYmxlIG5vZGVzIHRvIGFzc29jaWF0ZSB0aGUgY29tbWVudHMgdG8sCiAgICAgICAgLy9maW5kIHRoZSBzaG9ydGVzdCBvbmUKICAgICAgICBpZiAoY291bnQoJG5vZGVzKSA+IDEpIHsKICAgICAgICAgICAgdXNvcnQoJG5vZGVzLCBhcnJheSgkdGhpcywgImNvbXBhcmVOb2Rlc0xlbmd0aCIpKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmFzc29jaWF0ZUNvbW1lbnRzKCRub2Rlc1swXSwgJGNvbW1lbnRzLCAkbGVhZGluZyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGFyZXMgbm9kZSBsZW5ndGggCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlXE5vZGUgICRub2RlMSAgICAgRmlyc3Qgbm9kZQogICAgICogQHBhcmFtIE5vZGVcTm9kZSAgJG5vZGUyICAgICBTZWNvbmQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIGludAogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb21wYXJlTm9kZXNMZW5ndGgoJG5vZGUxLCAkbm9kZTIpCiAgICB7CiAgICAgICAgJGxvYzEgPSAkbm9kZTEtPmdldExvY2F0aW9uKCk7CiAgICAgICAgJGxlbmd0aDEgPSAkbG9jMS0+Z2V0RW5kKCktPmdldEluZGV4KCkgLSAkbG9jMS0+Z2V0U3RhcnQoKS0+Z2V0SW5kZXgoKTsKICAgICAgICAkbG9jMiA9ICRub2RlMi0+Z2V0TG9jYXRpb24oKTsKICAgICAgICAkbGVuZ3RoMiA9ICRsb2MyLT5nZXRFbmQoKS0+Z2V0SW5kZXgoKSAtICRsb2MyLT5nZXRTdGFydCgpLT5nZXRJbmRleCgpOwogICAgICAgIC8vSWYgdGhlIG5vZGVzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIG1ha2Ugc3VyZSB0byBjaG9vc2Ugbm9kZXMKICAgICAgICAvL2RpZmZlcmVudCBmcm9tIFByb2dyYW0gbm9kZXMKICAgICAgICBpZiAoJGxlbmd0aDEgPT09ICRsZW5ndGgyKSB7CiAgICAgICAgICAgIGlmICgkbm9kZTEgaW5zdGFuY2VvZiBOb2RlXFByb2dyYW0pIHsKICAgICAgICAgICAgICAgICRsZW5ndGgxICs9IDEwMDA7CiAgICAgICAgICAgIH0gZWxzZWlmICgkbm9kZTIgaW5zdGFuY2VvZiBOb2RlXFByb2dyYW0pIHsKICAgICAgICAgICAgICAgICRsZW5ndGgyICs9IDEwMDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRsZW5ndGgxIDwgJGxlbmd0aDIgPyAtMSA6IDE7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQWRkcyBjb21tZW50cyB0byB0aGUgZ2l2ZW4gbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICAgICAkbm9kZSAgICAgICBOb2RlCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgICAkY29tbWVudHMgICBBcnJheSBvZiBjb21tZW50cyB0byBhZGQKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgICRsZWFkaW5nICAgIFRydWUgdG8gYWRkIGNvbW1lbnRzIGFzIGxlYWRpbmcgY29tbWVudHMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGZhbHNlIHRvIGFkZCB0aGVtIGFzIHRyYWlsaW5nIGNvbW1lbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYXNzb2NpYXRlQ29tbWVudHMoJG5vZGUsICRjb21tZW50cywgJGxlYWRpbmcpCiAgICB7CiAgICAgICAgJGZuID0gKCRsZWFkaW5nID8gIkxlYWRpbmciIDogIlRyYWlsaW5nIikgLiAiQ29tbWVudHMiOwogICAgICAgICRjdXJyZW50Q29tbWVudHMgPSAkbm9kZS0+eyJnZXQkZm4ifSgpOwogICAgICAgIGZvcmVhY2ggKCRjb21tZW50cyBhcyAkY29tbWVudCkgewogICAgICAgICAgICAkbG9jID0gJGNvbW1lbnQtPmdldExvY2F0aW9uKCk7CiAgICAgICAgICAgICRjb21tZW50Tm9kZSA9IG5ldyBOb2RlXENvbW1lbnQ7CiAgICAgICAgICAgICRjb21tZW50Tm9kZS0+c2V0U3RhcnRQb3NpdGlvbigkbG9jLT5nZXRTdGFydCgpKQogICAgICAgICAgICAgICAgICAgICAgICAtPnNldEVuZFBvc2l0aW9uKCRsb2MtPmdldEVuZCgpKQogICAgICAgICAgICAgICAgICAgICAgICAtPnNldFJhd1RleHQoJGNvbW1lbnQtPmdldFZhbHVlKCkpOwogICAgICAgICAgICAkY3VycmVudENvbW1lbnRzW10gPSAkY29tbWVudE5vZGU7CiAgICAgICAgfQogICAgICAgICRub2RlLT57InNldCRmbiJ9KCRjdXJyZW50Q29tbWVudHMpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcRVMyMDE2OwoKLyoqCiAqIEVTMjAxNiBmZWF0dXJlcyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBGZWF0dXJlcyBleHRlbmRzIFxQZWFzdFxTeW50YXhcRVMyMDE1XEZlYXR1cmVzCnsKICAgIC8qKgogICAgICogRXhwb25lbnRpYXRpb24gb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRleHBvbmVudGlhdGlvbk9wZXJhdG9yID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyB0aGUgcG9zaXRpb24gaW4gdGhlIHNvdXJjZSBjb2RlLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQb3NpdGlvbiBpbXBsZW1lbnRzIFxKU09OU2VyaWFsaXphYmxlCnsKICAgIC8qKgogICAgICogU291cmNlIGxpbmUKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGluZTsKICAgIAogICAgLyoqCiAgICAgKiBTb3VyY2UgY29sdW1uCiAgICAgKiAKICAgICAqIEB2YXIgaW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbHVtbjsKICAgIAogICAgLyoqCiAgICAgKiBTb3VyY2UgaW5kZXgKICAgICAqIAogICAgICogQHZhciBpbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5kZXg7CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqIAogICAgICogQHBhcmFtIGludCAkbGluZSAgIFNvdXJjZSBsaW5lCiAgICAgKiBAcGFyYW0gaW50ICRjb2x1bW4gU291cmNlIGNvbHVtbgogICAgICogQHBhcmFtIGludCAkaW5kZXggIFNvdXJjZSBpbmRleAogICAgICovCiAgICBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbGluZSwgJGNvbHVtbiwgJGluZGV4KQogICAgewogICAgICAgICR0aGlzLT5saW5lID0gJGxpbmU7CiAgICAgICAgJHRoaXMtPmNvbHVtbiA9ICRjb2x1bW47CiAgICAgICAgJHRoaXMtPmluZGV4ID0gJGluZGV4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSBsaW5lCiAgICAgKiAKICAgICAqIEByZXR1cm4gaW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMaW5lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxpbmU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc291cmNlIGNvbHVtbgogICAgICogCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29sdW1uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNvbHVtbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzb3VyY2UgaW5kZXgKICAgICAqIAogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluZGV4KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmluZGV4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXJpYWxpemFibGUgdmVyc2lvbiBvZiB0aGUgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGpzb25TZXJpYWxpemUoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgImxpbmUiID0+ICR0aGlzLT5nZXRMaW5lKCksCiAgICAgICAgICAgICJjb2x1bW4iID0+ICR0aGlzLT5nZXRDb2x1bW4oKSwKICAgICAgICAgICAgImluZGV4IiA9PiAkdGhpcy0+Z2V0SW5kZXgoKQogICAgICAgICk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxFUzIwMTc7CgovKioKICogRVMyMDE3IGZlYXR1cmVzIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICovCmNsYXNzIEZlYXR1cmVzIGV4dGVuZHMgXFBlYXN0XFN5bnRheFxFUzIwMTZcRmVhdHVyZXMKewogICAgLyoqCiAgICAgKiBBc3luYy9hd2FpdAogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJGFzeW5jQXdhaXQgPSB0cnVlOwoKICAgIC8qKgogICAgICogVHJhaWxpbmcgY29tbWEgaW4gZnVuY3Rpb24gY2FsbHMgYW5kIGRlY2xhcmF0aW9ucwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwdWJsaWMgJHRyYWlsaW5nQ29tbWFGdW5jdGlvbkNhbGxEZWNsYXJhdGlvbiA9IHRydWU7CgogICAgLyoqCiAgICAgKiBGb3ItaW4gaW5pdGlhbGl6ZXIKICAgICAqCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHVibGljICRmb3JJbkluaXRpYWxpemVyID0gdHJ1ZTsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4OwoKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIHBhcnNlcnMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgUGFyc2VyQWJzdHJhY3QKewogICAgLyoqCiAgICAgKiBBc3NvY2lhdGVkIHNjYW5uZXIKICAgICAqIAogICAgICogQHZhciBTY2FubmVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNjYW5uZXI7CgogICAgLyoqCiAgICAgKiBQYXJzZXIgZmVhdHVyZXMKICAgICAqIAogICAgICogQHZhciBGZWF0dXJlcwogICAgICovCiAgICBwcm90ZWN0ZWQgJGZlYXR1cmVzOwogICAgCiAgICAvKioKICAgICAqIFBhcnNlciBjb250ZXh0CiAgICAgKiAKICAgICAqIEB2YXIgc3RkQ2xhc3MgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29udGV4dDsKICAgIAogICAgLyoqCiAgICAgKiBTb3VyY2UgdHlwZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRzb3VyY2VUeXBlOwogICAgCiAgICAvKioKICAgICAqIENvbW1lbnRzIGhhbmRsaW5nCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tbWVudHM7CiAgICAKICAgIC8qKgogICAgICogSlNYIHN5bnRheCBoYW5kbGluZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGpzeDsKICAgIAogICAgLyoqCiAgICAgKiBFdmVudHMgZW1pdHRlcgogICAgICoKICAgICAqIEB2YXIgRXZlbnRzRW1pdHRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgJGV2ZW50c0VtaXR0ZXI7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgJHNvdXJjZSAgIFNvdXJjZSBjb2RlCiAgICAgKiBAcGFyYW0gRmVhdHVyZXMgJGZlYXR1cmVzIFBhcnNlciBmZWF0dXJlcwogICAgICogQHBhcmFtIGFycmF5ICAgICRvcHRpb25zICBQYXJzaW5nIG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KAogICAgICAgICRzb3VyY2UsIEZlYXR1cmVzICRmZWF0dXJlcywgJG9wdGlvbnMgPSBhcnJheSgpCiAgICApIHsKICAgICAgICAkdGhpcy0+ZmVhdHVyZXMgPSAkZmVhdHVyZXM7CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnNvdXJjZVR5cGUgPSBpc3NldCgkb3B0aW9uc1sic291cmNlVHlwZSJdKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb3B0aW9uc1sic291cmNlVHlwZSJdIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxQZWFzdFxQZWFzdDo6U09VUkNFX1RZUEVfU0NSSVBUOwogICAgICAgIAogICAgICAgIC8vQ3JlYXRlIHRoZSBzY2FubmVyCiAgICAgICAgJHRoaXMtPnNjYW5uZXIgPSBuZXcgU2Nhbm5lcigkc291cmNlLCAkZmVhdHVyZXMsICRvcHRpb25zKTsKICAgICAgICAKICAgICAgICAvL0VuYWJsZSBtb2R1bGUgc2Nhbm5pbmcgaWYgcmVxdWlyZWQKICAgICAgICBpZiAoJHRoaXMtPnNvdXJjZVR5cGUgPT09IFxQZWFzdFxQZWFzdDo6U09VUkNFX1RZUEVfTU9EVUxFKSB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5lbmFibGVNb2R1bGVNb2RlKHRydWUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0VuYWJsZSBjb21tZW50cyBzY2FubmluZwogICAgICAgICR0aGlzLT5jb21tZW50cyA9IGlzc2V0KCRvcHRpb25zWyJjb21tZW50cyJdKSAmJiAkb3B0aW9uc1siY29tbWVudHMiXTsKICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5lbmFibGVDb21tZW50cyh0cnVlKTsKICAgICAgICAgICAgLy9DcmVhdGUgdGhlIGNvbW1lbnRzIHJlZ2lzdHJ5CiAgICAgICAgICAgIG5ldyBDb21tZW50c1JlZ2lzdHJ5KCR0aGlzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gRW5hYmxlIGpzeCBzeW50YXggaWYgcmVxdWlyZWQKICAgICAgICAkdGhpcy0+anN4ID0gaXNzZXQoJG9wdGlvbnNbImpzeCJdKSAmJiAkb3B0aW9uc1sianN4Il07CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmluaXRDb250ZXh0KCk7CiAgICAgICAgJHRoaXMtPnBvc3RJbml0KCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgcGFyc2VyIGNvbnRleHQKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIGFic3RyYWN0IHByb3RlY3RlZCBmdW5jdGlvbiBpbml0Q29udGV4dCgpOwogICAgCiAgICAvKioKICAgICAqIFBvc3QgaW5pdGlhbGl6ZSBvcGVyYXRpb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBhYnN0cmFjdCBwcm90ZWN0ZWQgZnVuY3Rpb24gcG9zdEluaXQoKTsKICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIHNvdXJjZQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZQogICAgICogCiAgICAgKiBAYWJzdHJhY3QKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHBhcnNlKCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBwYXJzZWQgdG9rZW5zIGZyb20gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW5bXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdG9rZW5pemUoKQogICAgewogICAgICAgICR0aGlzLT5zY2FubmVyLT5lbmFibGVUb2tlblJlZ2lzdHJhdGlvbigpOwogICAgICAgICR0aGlzLT5wYXJzZSgpOwogICAgICAgIHJldHVybiAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW5zKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2Nhbm5lciBhc3NvY2lhdGVkIHdpdGggdGhlIHBhcnNlcgogICAgICogCiAgICAgKiBAcmV0dXJuIFNjYW5uZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNjYW5uZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2Nhbm5lcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYXJzZXIgZmVhdHVyZXMgY2xhc3MKICAgICAqIAogICAgICogQHJldHVybiBGZWF0dXJlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmVhdHVyZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmVhdHVyZXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFyc2VyJ3MgZXZlbnRzIGVtaXR0ZXIKICAgICAqIAogICAgICogQHJldHVybiBFdmVudHNFbWl0dGVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFdmVudHNFbWl0dGVyKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5ldmVudHNFbWl0dGVyKSB7CiAgICAgICAgICAgIC8vVGhlIGV2ZW50IGVtaXR0ZXIgaXMgY3JlYXRlZCBoZXJlIHNvIHRoYXQgaXQgd29uJ3QgZXhpc3QgaWYgbm90CiAgICAgICAgICAgIC8vbmVjZXNzYXJ5CiAgICAgICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyID0gbmV3IEV2ZW50c0VtaXR0ZXI7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+ZXZlbnRzRW1pdHRlcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDYWxscyBhIG1ldGhvZCB3aXRoIGFuIGlzb2xhdGVkIHBhcnNlciBjb250ZXh0LCBhcHBseW5nIHRoZSBnaXZlbiBmbGFncywKICAgICAqIGJ1dCByZXN0b3JpbmcgdGhlaXIgdmFsdWVzIGFmdGVyIHRoZSBleGVjdXRpb24uCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICAkZmxhZ3MgIEtleS92YWx1ZSBhcnJheSBvZiBjaGFuZ2VzIHRvIGFwcGx5IHRvIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCBmbGFncy4gSWYgaXQncyBudWxsIG9yIHRoZSBmaXJzdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCBvZiB0aGUgYXJyYXkgaXMgbnVsbCB0aGUgY29udGV4dCB3aWxsCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSByZXNldCBiZWZvcmUgYXBwbHlpbmcgbmV3IHZhbHVlcy4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkZm4gICAgIE1ldGhvZCB0byBjYWxsCiAgICAgKiBAcGFyYW0gYXJyYXkgICAgICAgJGFyZ3MgICBNZXRob2QgYXJndW1lbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gbWl4ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzb2xhdGVDb250ZXh0KCRmbGFncywgJGZuLCAkYXJncyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgLy9TdG9yZSB0aGUgY3VycmVudCBjb250ZXh0CiAgICAgICAgJG9sZENvbnRleHQgPSBjbG9uZSAkdGhpcy0+Y29udGV4dDsKICAgICAgICAKICAgICAgICAvL0lmIGZsYWcgYXJndW1lbnQgaXMgbnVsbCByZXNldCB0aGUgY29udGV4dAogICAgICAgIGlmICgkZmxhZ3MgPT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPmluaXRDb250ZXh0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9BcHBseSBuZXcgdmFsdWVzIHRvIHRoZSBmbGFncwogICAgICAgICAgICBmb3JlYWNoICgkZmxhZ3MgYXMgJGsgPT4gJHYpIHsKICAgICAgICAgICAgICAgIC8vIElmIG51bGwgcmVzZXQgdGhlIGNvbnRleHQKICAgICAgICAgICAgICAgIGlmICgkdiA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbml0Q29udGV4dCgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29udGV4dC0+JGsgPSAkdjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0NhbGwgdGhlIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMKICAgICAgICAkcmV0ID0gY2FsbF91c2VyX2Z1bmNfYXJyYXkoYXJyYXkoJHRoaXMsICRmbiksICRhcmdzKTsKICAgICAgICAKICAgICAgICAvL1Jlc3RvcmUgcHJldmlvdXMgY29udGV4dAogICAgICAgICR0aGlzLT5jb250ZXh0ID0gJG9sZENvbnRleHQ7CiAgICAgICAgCiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5vZGUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkbm9kZVR5cGUgTm9kZSdzIHR5cGUKICAgICAqIEBwYXJhbSBtaXhlZCAgJHBvc2l0aW9uIE5vZGUncyBzdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZQogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjcmVhdGVOb2RlKCRub2RlVHlwZSwgJHBvc2l0aW9uKQogICAgewogICAgICAgIC8vVXNlIHRoZSByaWdodCBjbGFzcyB0byBnZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIG5vZGUKICAgICAgICAkbm9kZUNsYXNzID0gIlxcUGVhc3RcXFN5bnRheFxcTm9kZVxcIiAuICRub2RlVHlwZTsKICAgICAgICAkbm9kZSA9IG5ldyAkbm9kZUNsYXNzOwogICAgICAgIAogICAgICAgIC8vQWRkIHRoZSBub2RlIHN0YXJ0IHBvc2l0aW9uCiAgICAgICAgaWYgKCRwb3NpdGlvbiBpbnN0YW5jZW9mIE5vZGVcTm9kZSB8fCAkcG9zaXRpb24gaW5zdGFuY2VvZiBUb2tlbikgewogICAgICAgICAgICAkcG9zaXRpb24gPSAkcG9zaXRpb24tPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCk7CiAgICAgICAgfSBlbHNlaWYgKGlzX2FycmF5KCRwb3NpdGlvbikpIHsKICAgICAgICAgICAgaWYgKGNvdW50KCRwb3NpdGlvbikpIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9ICRwb3NpdGlvblswXS0+Z2V0TG9jYXRpb24oKS0+Z2V0U3RhcnQoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRwb3NpdGlvbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRub2RlLT5zZXRTdGFydFBvc2l0aW9uKCRwb3NpdGlvbik7CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBOb2RlQ3JlYXRlZCBldmVudCBmb3IgdGhlIG5vZGUKICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIk5vZGVDcmVhdGVkIiwgYXJyYXkoJG5vZGUpCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gJG5vZGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGxldGVzIGEgbm9kZSBieSBhZGRpbmcgdGhlIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gTm9kZVxOb2RlICAgJG5vZGUgICAgIE5vZGUgdG8gY29tcGxldGUKICAgICAqIEBwYXJhbSBQb3NpdGlvbiAgICAkcG9zaXRpb24gTm9kZSdzIGVuZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVcTm9kZQogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb21wbGV0ZU5vZGUoTm9kZVxOb2RlICRub2RlLCAkcG9zaXRpb24gPSBudWxsKQogICAgewogICAgICAgIC8vQWRkIHRoZSBub2RlIGVuZCBwb3NpdGlvbgogICAgICAgICRub2RlLT5zZXRFbmRQb3NpdGlvbigKICAgICAgICAgICAgJHBvc2l0aW9uID8gJHBvc2l0aW9uIDogJHRoaXMtPnNjYW5uZXItPmdldFBvc2l0aW9uKCkKICAgICAgICApOwogICAgICAgIAogICAgICAgIC8vRW1pdCB0aGUgTm9kZUNvbXBsZXRlZCBldmVudCBmb3IgdGhlIG5vZGUKICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIk5vZGVDb21wbGV0ZWQiLCBhcnJheSgkbm9kZSkKICAgICAgICApOwogICAgICAgIAogICAgICAgIHJldHVybiAkbm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUaHJvd3MgYSBzeW50YXggZXJyb3IKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAgICRtZXNzYWdlICBFcnJvciBtZXNzYWdlCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uIEVycm9yIHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXJyb3IoJG1lc3NhZ2UgPSAiIiwgJHBvc2l0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoISRtZXNzYWdlKSB7CiAgICAgICAgICAgICR0b2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgICAgICBpZiAoJHRva2VuID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICJVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dCI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcG9zaXRpb24gPSAkdG9rZW4tPmdldExvY2F0aW9uKCktPmdldFN0YXJ0KCk7CiAgICAgICAgICAgICAgICAkbWVzc2FnZSA9ICJVbmV4cGVjdGVkOiAiIC4gJHRva2VuLT5nZXRWYWx1ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghJHBvc2l0aW9uKSB7CiAgICAgICAgICAgICRwb3NpdGlvbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRQb3NpdGlvbigpOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCRtZXNzYWdlLCAkcG9zaXRpb24pOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEFzc2VydHMgdGhhdCBhIHZhbGlkIGVuZCBvZiBzdGF0ZW1lbnQgZm9sbG93cyB0aGUgY3VycmVudCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqIAogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFzc2VydEVuZE9mU3RhdGVtZW50KCkKICAgIHsKICAgICAgICAvL1RoZSBlbmQgb2Ygc3RhdGVtZW50IGlzIHJlYWNoZWQgd2hlbiBpdCBpcyBmb2xsb3dlZCBieSBsaW5lCiAgICAgICAgLy90ZXJtaW5hdG9ycywgZW5kIG9mIHNvdXJjZSwgIn0iIG9yICI7Ii4gSW4gdGhlIGxhc3QgY2FzZSB0aGUgdG9rZW4KICAgICAgICAvL211c3QgYmUgY29uc3VtZWQKICAgICAgICBpZiAoISR0aGlzLT5zY2FubmVyLT5ub0xpbmVUZXJtaW5hdG9ycygpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOyIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICAgICAgaWYgKCEkdG9rZW4gfHwgJHRva2VuLT5nZXRWYWx1ZSgpID09PSAifSIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBjaGFyYWN0ZXIgc2VwYXJhdGVkIGxpc3Qgb2YgaW5zdHJ1Y3Rpb25zIG9yIG51bGwgaWYgdGhlCiAgICAgKiBzZXF1ZW5jZSBpcyBub3QgdmFsaWQKICAgICAqIAogICAgICogQHBhcmFtIGNhbGxhYmxlICRmbiAgIFBhcnNpbmcgaW5zdHJ1Y3Rpb24gZnVuY3Rpb24KICAgICAqIEBwYXJhbSBhcnJheSAgICAkYXJncyBBcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24KICAgICAqIEBwYXJhbSBzdHJpbmcgICAkY2hhciBTZXBhcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICogCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY2hhclNlcGFyYXRlZExpc3RPZigkZm4sICRhcmdzID0gYXJyYXkoKSwgJGNoYXIgPSAiLCIpCiAgICB7CiAgICAgICAgJGxpc3QgPSBhcnJheSgpOwogICAgICAgICR2YWxpZCA9IHRydWU7CiAgICAgICAgd2hpbGUgKCRwYXJhbSA9IGNhbGxfdXNlcl9mdW5jX2FycmF5KGFycmF5KCR0aGlzLCAkZm4pLCAkYXJncykpIHsKICAgICAgICAgICAgJGxpc3RbXSA9ICRwYXJhbTsKICAgICAgICAgICAgJHZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgkY2hhcikpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCEkdmFsaWQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGxpc3Q7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheDsKCi8qKgogKiBCYXNlIGNsYXNzIGZvciBzY2FubmVycy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU2Nhbm5lcgp7CiAgICB1c2UgSlNYXFNjYW5uZXI7CgogICAgLyoqCiAgICAgKiBTY2FubmVyIGZlYXR1cmVzCiAgICAgKiAKICAgICAqIEB2YXIgRmVhdHVyZXMKICAgICAqLwogICAgcHJvdGVjdGVkICRmZWF0dXJlczsKCiAgICAvKioKICAgICAqIEN1cnJlbnQgY29sdW1uCiAgICAgKiAKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29sdW1uID0gMDsKICAgIAogICAgLyoqCiAgICAgKiBDdXJyZW50IGxpbmUKICAgICAqIAogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRsaW5lID0gMTsKICAgIAogICAgLyoqCiAgICAgKiBDdXJyZW50IGluZGV4CiAgICAgKiAKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5kZXggPSAwOwogICAgCiAgICAvKioKICAgICAqIFNvdXJjZSBsZW5ndGgKICAgICAqIAogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRsZW5ndGg7CiAgICAKICAgIC8qKgogICAgICogU291cmNlIGNoYXJhY3RlcnMKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZTsKICAgIAogICAgLyoqCiAgICAgKiBDb25zdW1lZCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAdmFyIFBvc2l0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcG9zaXRpb247CiAgICAKICAgIC8qKgogICAgICogQ3VycmVudCB0b2tlbgogICAgICogCiAgICAgKiBAdmFyIFRva2VuIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGN1cnJlbnRUb2tlbjsKICAgIAogICAgLyoqCiAgICAgKiBOZXh0IHRva2VuCiAgICAgKiAKICAgICAqIEB2YXIgVG9rZW4gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmV4dFRva2VuOwogICAgCiAgICAvKioKICAgICAqIFN0cmljdCBtb2RlIGZsYWcKICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0cmljdE1vZGUgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBUcnVlIHRvIHJlZ2lzdGVyIHRva2VucyBpbiB0aGUgdG9rZW5zIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRyZWdpc3RlclRva2VucyA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIE1vZHVsZSBtb2RlCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRpc01vZHVsZSA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIENvbW1lbnRzIGhhbmRsaW5nCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21tZW50cyA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIEludGVybmFsIEpTWCBzY2FuIGZsYWcKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkanN4ID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogUmVnaXN0ZXJlZCB0b2tlbnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICR0b2tlbnMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENvbW1lbnRzIHRvIHRva2VucyBtYXAKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21tZW50c01hcCA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogRXZlbnRzIGVtaXR0ZXIKICAgICAqCiAgICAgKiBAdmFyIEV2ZW50c0VtaXR0ZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRldmVudHNFbWl0dGVyOwogICAgCiAgICAvKioKICAgICAqIFJlZ2V4IHRvIG1hdGNoIGlkZW50aWZpZXJzIHN0YXJ0cwogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRpZFN0YXJ0UmVnZXggPSAiL1tccHtMdX1ccHtMbH1ccHtMdH1ccHtMbX1ccHtMb31ccHtObH1ceHsyMTE4fVx4ezIxMkV9XHh7MzA5Qn1ceHszMDlDfV0vdSI7CiAgICAKICAgIC8qKgogICAgICogUmVnZXggdG8gbWF0Y2ggaWRlbnRpZmllcnMgcGFydHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaWRQYXJ0UmVnZXggPSAiL1tccHtMdX1ccHtMbH1ccHtMdH1ccHtMbX1ccHtMb31ccHtObH1ceHsyMTE4fVx4ezIxMkV9XHh7MzA5Qn1ceHszMDlDfVxwe01ufVxwe01jfVxwe05kfVxwe1BjfVx4ezAwQjd9XHh7MDM4N31ceHsxMzY5fVx4ezEzNkF9XHh7MTM2Qn1ceHsxMzZDfVx4ezEzNkR9XHh7MTM2RX1ceHsxMzZGfVx4ezEzNzB9XHh7MTM3MX1ceHsxOURBfVx4ezIwMEN9XHh7MjAwRH1dL3UiOwogICAgCiAgICAvKioKICAgICAqIEtleXdvcmRzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2V5d29yZHMgPSBhcnJheSgKICAgICAgICAiYnJlYWsiLCAiZG8iLCAiaW4iLCAidHlwZW9mIiwgImNhc2UiLCAiZWxzZSIsICJpbnN0YW5jZW9mIiwgInZhciIsCiAgICAgICAgImNhdGNoIiwgImV4cG9ydCIsICJuZXciLCAidm9pZCIsICJjbGFzcyIsICJleHRlbmRzIiwgInJldHVybiIsICJ3aGlsZSIsCiAgICAgICAgImNvbnN0IiwgImZpbmFsbHkiLCAic3VwZXIiLCAid2l0aCIsICJjb250aW51ZSIsICJmb3IiLCAic3dpdGNoIiwKICAgICAgICAiZGVidWdnZXIiLCAiZnVuY3Rpb24iLCAidGhpcyIsICJkZWZhdWx0IiwgImlmIiwgInRocm93IiwKICAgICAgICAiZGVsZXRlIiwgImltcG9ydCIsICJ0cnkiLCAiZW51bSIsICJhd2FpdCIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2Ygd29yZHMgdGhhdCBhcmUga2V5d29yZHMgb25seSBpbiBzdHJpY3QgbW9kZQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0cmljdE1vZGVLZXl3b3JkcyA9IGFycmF5KAogICAgICAgICJpbXBsZW1lbnRzIiwgImludGVyZmFjZSIsICJwYWNrYWdlIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInB1YmxpYyIsCiAgICAgICAgInN0YXRpYyIsICJsZXQiLCAieWllbGQiCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFB1bmN0dXRhdG9ycyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHB1bmN0dXRhdG9ycyA9IGFycmF5KAogICAgICAgICIuIiwgIjsiLCAiLCIsICI8IiwgIj4iLCAiPD0iLCAiPj0iLCAiPT0iLCAiIT0iLCAiPT09IiwgIiE9PSIsICIrIiwKICAgICAgICAiLSIsICIqIiwgIiUiLCAiKysiLCAiLS0iLCAiPDwiLCAiPj4iLCAiPj4+IiwgIiYiLCAifCIsICJeIiwgIiEiLCAifiIsCiAgICAgICAgIiYmIiwgInx8IiwgIj8iLCAiOiIsICI9IiwgIis9IiwgIi09IiwgIio9IiwgIiU9IiwgIjw8PSIsICI+Pj0iLCAiPj4+PSIsCiAgICAgICAgIiY9IiwgInw9IiwgIl49IiwgIj0+IiwgIi4uLiIsICIvIiwgIi89IiwgIioqIiwgIioqPSIsICI/PyIsICI/LiIsCiAgICAgICAgIiYmPSIsICJ8fD0iLCAiPz89IgogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBQdW5jdHV0YXRvcnMgTFNNCiAgICAgKiAKICAgICAqIEB2YXIgTFNNIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHB1bmN0dXRhdG9yc0xTTTsKICAgIAogICAgLyoqCiAgICAgKiBTdHJpbmdzIHN0b3BzIExTTQogICAgICogCiAgICAgKiBAdmFyIExTTSAKICAgICAqLwogICAgcHJvdGVjdGVkICRzdHJpbmdzU3RvcHNMU007CiAgICAKICAgIC8qKgogICAgICogQnJhY2tldHMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRicmFja2V0cyA9IGFycmF5KAogICAgICAgICIoIiA9PiAiIiwgIlsiID0+ICIiLCAieyIgPT4gIiIsICIpIiA9PiAiKCIsICJdIiA9PiAiWyIsICJ9IiA9PiAieyIKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3BlbiBicmFja2V0cyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZW5CcmFja2V0cyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogT3BlbiB0ZW1wbGF0ZXMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVuVGVtcGxhdGVzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBXaGl0ZXNwYWNlcyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHdoaXRlc3BhY2VzID0gYXJyYXkoCiAgICAgICAgIiAiLCAiXHQiLCAiXG4iLCAiXHIiLCAiXGYiLCAiXHYiLCAweDAwQTAsIDB4RkVGRiwgMHgwMEEwLAogICAgICAgIDB4MTY4MCwgMHgyMDAwLCAweDIwMDEsIDB4MjAwMiwgMHgyMDAzLCAweDIwMDQsIDB4MjAwNSwgMHgyMDA2LAogICAgICAgIDB4MjAwNywgMHgyMDA4LCAweDIwMDksIDB4MjAwQSwgMHgyMDJGLCAweDIwNUYsIDB4MzAwMCwgMHgyMDI4LAogICAgICAgIDB4MjAyOQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBMaW5lIHRlcm1pbmF0b3JzIGNoYXJhY3RlcnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqIAogICAgICogQHN0YXRpYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljICRsaW5lVGVybWluYXRvcnNDaGFycyA9IGFycmF5KCJcbiIsICJcciIsIDB4MjAyOCwgMHgyMDI5KTsKICAgIAogICAgLyoqCiAgICAgKiBMaW5lIHRlcm1pbmF0b3JzIHNlcXVlbmNlcyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKiAKICAgICAqIEBzdGF0aWMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyAkbGluZVRlcm1pbmF0b3JzU2VxdWVuY2VzID0gYXJyYXkoIlxyXG4iKTsKICAgIAogICAgLyoqCiAgICAgKiBSZWdleCB0byBzcGxpdCB0ZXh0cyB1c2luZyB2YWxpZCBFUyBsaW5lIHRlcm1pbmF0b3JzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGluZXNTcGxpdHRlcjsKICAgIAogICAgLyoqCiAgICAgKiBDb25jYXRlbmF0aW9uIG9mIGxpbmUgdGVybWluYXRvcnMgY2hhcmFjdGVycyBhbmQgbGluZSB0ZXJtaW5hdG9ycwogICAgICogc2VxdWVuY2VzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbGluZVRlcm1pbmF0b3JzOwogICAgCiAgICAvKioKICAgICAqIFByb3BlcnRpZXMgdG8gY29weSB3aGVuIGdldHRpbmcgdGhlIHNjYW5uZXIgc3RhdGUKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0YXRlUHJvcHMgPSBhcnJheSgicG9zaXRpb24iLCAiaW5kZXgiLCAiY29sdW1uIiwgImxpbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImN1cnJlbnRUb2tlbiIsICJuZXh0VG9rZW4iLCAic3RyaWN0TW9kZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3BlbkJyYWNrZXRzIiwgIm9wZW5UZW1wbGF0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbW1lbnRzTWFwIik7CiAgICAKICAgIC8qKgogICAgICogRGVjaW1hbCBudW1iZXJzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRudW1iZXJzID0gYXJyYXkoIjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1IiwgIjYiLCAiNyIsICI4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI5Iik7CiAgICAKICAgIC8qKgogICAgICogSGV4YWRlY2ltYWwgbnVtYmVycwogICAgICogCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkeG51bWJlcnMgPSBhcnJheSgiMCIsICIxIiwgIjIiLCAiMyIsICI0IiwgIjUiLCAiNiIsICI3IiwgIjgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI5IiwgImEiLCAiYiIsICJjIiwgImQiLCAiZSIsICJmIiwgIkEiLCAiQiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkMiLCAiRCIsICJFIiwgIkYiKTsKCiAgICAvKioKICAgICAqIE9jdGFsIG51bWJlcnMKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb251bWJlcnMgPSBhcnJheSgiMCIsICIxIiwgIjIiLCAiMyIsICI0IiwgIjUiLCAiNiIsICI3Iik7CgogICAgLyoqCiAgICAgKiBCaW5hcnkgbnVtYmVycwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRibnVtYmVycyA9IGFycmF5KCIwIiwgIjEiKTsKCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgICAkc291cmNlICAgU291cmNlIGNvZGUKICAgICAqIEBwYXJhbSBGZWF0dXJlcyAkZmVhdHVyZXMgU2Nhbm5lciBmZWF0dXJlcwogICAgICogQHBhcmFtIGFycmF5ICAgICRvcHRpb25zICBQYXJzaW5nIG9wdGlvbnMKICAgICAqLwogICAgZnVuY3Rpb24gX19jb25zdHJ1Y3QoCiAgICAgICAgJHNvdXJjZSwgRmVhdHVyZXMgJGZlYXR1cmVzLCAkb3B0aW9ucwogICAgKSB7CiAgICAgICAgJHRoaXMtPmZlYXR1cmVzID0gJGZlYXR1cmVzOwoKICAgICAgICAkZW5jb2RpbmcgPSBpc3NldCgkb3B0aW9uc1sic291cmNlRW5jb2RpbmciXSkgPwogICAgICAgICAgICAgICAgICAgICRvcHRpb25zWyJzb3VyY2VFbmNvZGluZyJdIDoKICAgICAgICAgICAgICAgICAgICBudWxsOwogICAgICAgIAogICAgICAgIC8vU3RyaXAgQk9NIGNoYXJhY3RlcnMgZnJvbSB0aGUgc291cmNlCiAgICAgICAgJHRoaXMtPnN0cmlwQk9NKCRzb3VyY2UsICRlbmNvZGluZyk7CiAgICAgICAgCiAgICAgICAgLy9Db252ZXJ0IHRvIFVURjggaWYgbmVlZGVkCiAgICAgICAgaWYgKCRlbmNvZGluZyAmJiAhcHJlZ19tYXRjaCgiL1VURi0/OC9pIiwgJGVuY29kaW5nKSkgewogICAgICAgICAgICAkc291cmNlID0gbWJfY29udmVydF9lbmNvZGluZygkc291cmNlLCAiVVRGLTgiLCAkZW5jb2RpbmcpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0luc3RlYWQgb2YgdXNpbmcgbWJfc3Vic3RyIGZvciBlYWNoIGNoYXJhY3Rlciwgc3BsaXQgdGhlIHNvdXJjZQogICAgICAgIC8vaW50byBhbiBhcnJheSBvZiBVVEY4IGNoYXJhY3RlcnMgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMKICAgICAgICAkdGhpcy0+c291cmNlID0gVXRpbHM6OnN0cmluZ1RvVVRGOEFycmF5KAogICAgICAgICAgICAkc291cmNlLAogICAgICAgICAgICAhaXNzZXQoJG9wdGlvbnNbInN0cmljdEVuY29kaW5nIl0pIHx8ICRvcHRpb25zWyJzdHJpY3RFbmNvZGluZyJdCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+bGVuZ3RoID0gY291bnQoJHRoaXMtPnNvdXJjZSk7CiAgICAgICAgCiAgICAgICAgLy9Db252ZXJ0IGNoYXJhY3RlciBjb2RlcyB0byBVVEY4IGNoYXJhY3RlcnMgaW4gd2hpdGVzcGFjZXMgYW5kIGxpbmUKICAgICAgICAvL3Rlcm1pbmF0b3JzCiAgICAgICAgJHRoaXMtPmxpbmVUZXJtaW5hdG9ycyA9IGFycmF5X21lcmdlKAogICAgICAgICAgICBzZWxmOjokbGluZVRlcm1pbmF0b3JzU2VxdWVuY2VzLCBzZWxmOjokbGluZVRlcm1pbmF0b3JzQ2hhcnMKICAgICAgICApOwogICAgICAgIGZvcmVhY2ggKGFycmF5KCJ3aGl0ZXNwYWNlcyIsICJsaW5lVGVybWluYXRvcnMiKSBhcyAka2V5KSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT4ka2V5IGFzICRpID0+ICRjaGFyKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNfaW50KCRjaGFyKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT57JGtleX1bJGldID0gVXRpbHM6OnVuaWNvZGVUb1V0ZjgoJGNoYXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1JlbW92ZSBleHBvbmVudGF0aW9uIG9wZXJhdG9yIGlmIHRoZSBmZWF0dXJlCiAgICAgICAgLy9pcyBub3QgZW5hYmxlZAogICAgICAgIGlmICghJHRoaXMtPmZlYXR1cmVzLT5leHBvbmVudGlhdGlvbk9wZXJhdG9yKSB7CiAgICAgICAgICAgIFV0aWxzOjpyZW1vdmVBcnJheVZhbHVlKCR0aGlzLT5wdW5jdHV0YXRvcnMsICIqKiIpOwogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgkdGhpcy0+cHVuY3R1dGF0b3JzLCAiKio9Iik7CiAgICAgICAgfQoKICAgICAgICBpZiAoISR0aGlzLT5mZWF0dXJlcy0+b3B0aW9uYWxDaGFpbmluZykgewogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgkdGhpcy0+cHVuY3R1dGF0b3JzLCAiPy4iKTsKICAgICAgICB9CgogICAgICAgIC8vUmVtb3ZlIGxvZ2ljYWwgYXNzaWdubWVudCBvcGVyYXRvcnMgaWYgdGhlIGZlYXR1cmUKICAgICAgICAvL2lzIG5vdCBlbmFibGVkCiAgICAgICAgaWYgKCEkdGhpcy0+ZmVhdHVyZXMtPmxvZ2ljYWxBc3NpZ25tZW50T3BlcmF0b3JzKSB7CiAgICAgICAgICAgIFV0aWxzOjpyZW1vdmVBcnJheVZhbHVlKCR0aGlzLT5wdW5jdHV0YXRvcnMsICImJj0iKTsKICAgICAgICAgICAgVXRpbHM6OnJlbW92ZUFycmF5VmFsdWUoJHRoaXMtPnB1bmN0dXRhdG9ycywgInx8PSIpOwogICAgICAgICAgICBVdGlsczo6cmVtb3ZlQXJyYXlWYWx1ZSgkdGhpcy0+cHVuY3R1dGF0b3JzLCAiPz89Iik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vQ3JlYXRlIGEgTFNNIGZvciBwdW5jdHV0YXRvcnMgYXJyYXkKICAgICAgICAkdGhpcy0+cHVuY3R1dGF0b3JzTFNNID0gbmV3IExTTSgkdGhpcy0+cHVuY3R1dGF0b3JzKTsKICAgICAgICAKICAgICAgICAvL0NyZWF0ZSBhIExTTSBmb3Igc3RyaW5ncyBzdG9wcwogICAgICAgICR0aGlzLT5zdHJpbmdzU3RvcHNMU00gPSBuZXcgTFNNKCR0aGlzLT5saW5lVGVybWluYXRvcnMsIHRydWUpOwogICAgICAgIAogICAgICAgIC8vQWxsb3cgcGFyYWdyYXBoIGFuZCBsaW5lIHNlcGFyYXRvcnMgaW4gc3RyaW5ncwogICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPnBhcmFncmFwaExpbmVTZXBJblN0cmluZ3MpIHsKICAgICAgICAgICAgJHRoaXMtPnN0cmluZ3NTdG9wc0xTTS0+cmVtb3ZlKFV0aWxzOjp1bmljb2RlVG9VdGY4KDB4MjAyOCkpOwogICAgICAgICAgICAkdGhpcy0+c3RyaW5nc1N0b3BzTFNNLT5yZW1vdmUoVXRpbHM6OnVuaWNvZGVUb1V0ZjgoMHgyMDI5KSk7CiAgICAgICAgfQoKICAgICAgICAvL1JlbW92ZSBhd2FpdCBhcyBrZXl3b3JkIGlmIGFzeW5jL2F3YWl0IGlzIGVuYWJsZWQKICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5hc3luY0F3YWl0KSB7CiAgICAgICAgICAgIFV0aWxzOjpyZW1vdmVBcnJheVZhbHVlKCR0aGlzLT5rZXl3b3JkcywgImF3YWl0Iik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICR0aGlzLT5saW5lc1NwbGl0dGVyID0gIi8iIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcGxvZGUoInwiLCAkdGhpcy0+bGluZVRlcm1pbmF0b3JzKSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiL3UiOwogICAgICAgICR0aGlzLT5wb3NpdGlvbiA9IG5ldyBQb3NpdGlvbigwLCAwLCAwKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdHJpcHMgQk9NIGNoYXJhY3RlcnMgZnJvbSB0aGUgc291cmNlIGFuZCBkZXRlY3RzIHNvdXJjZSBlbmNvZGluZyBpZiBub3QKICAgICAqIGdpdmVuIGJ5IHRoZSB1c2VyCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZSAgIFNvdXJjZQogICAgICogQHBhcmFtIHN0cmluZyAkZW5jb2RpbmcgVXNlciBzcGVjaWZpZWQgZW5jb2RpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHN0cmlwQk9NKCYkc291cmNlLCAmJGVuY29kaW5nKQogICAgewogICAgICAgICRib21zID0gYXJyYXkoCiAgICAgICAgICAgICJceEVGIiA9PiBhcnJheShhcnJheSgiXHhCQiIsICJceEJGIiksICJVVEYtOCIpLAogICAgICAgICAgICAiXHhGRSIgPT4gYXJyYXkoYXJyYXkoIlx4RkYiKSwgIlVURi0xNkJFIiksCiAgICAgICAgICAgICJceEZGIiA9PiBhcnJheShhcnJheSgiXHhGRSIpLCAiVVRGLTE2TEUiKSwKICAgICAgICApOwogICAgICAgIGlmICghaXNzZXQoJHNvdXJjZVswXSkgfHwgIWlzc2V0KCRib21zWyRzb3VyY2VbMF1dKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICRib20gPSAkYm9tc1skc291cmNlWzBdXTsKICAgICAgICAkbCA9IGNvdW50KCRib21bMF0pOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRsOyAkaSsrKSB7CiAgICAgICAgICAgIGlmICghaXNzZXQoJHNvdXJjZVskaSArIDFdKSB8fCAkc291cmNlWyRpICsgMV0gIT09ICRib21bMF1bJGldKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHNvdXJjZSA9IHN1YnN0cigkc291cmNlLCAkbCArIDEpOwogICAgICAgIGlmICghJGVuY29kaW5nKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9ICRib21bMV07CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgbW9kdWxlIHNjYW5uaW5nIG1vZGUKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGVuYWJsZSBUcnVlIHRvIGVuYWJsZSBtb2R1bGUgc2Nhbm5pbmcgbW9kZSwgZmFsc2UgdG8gZGlzYWJsZSBpdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVNb2R1bGVNb2RlKCRlbmFibGUgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5pc01vZHVsZSA9ICRlbmFibGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgY29tbWVudHMgaGFuZGxpbmcKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGVuYWJsZSBUcnVlIHRvIGVuYWJsZSBjb21tZW50cyBoYW5kbGluZywgZmFsc2UgdG8gZGlzYWJsZSBpdAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmFibGVDb21tZW50cygkZW5hYmxlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tbWVudHMgPSAkZW5hYmxlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIHRva2VucyByZWdpc3RyYXRpb24gaW4gdGhlIHRva2VuIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRlbmFibGUgVHJ1ZSB0byBlbmFibGUgdG9rZW4gcmVnaXN0cmF0aW9uLCBmYWxzZSB0byBkaXNhYmxlIGl0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuYWJsZVRva2VuUmVnaXN0cmF0aW9uKCRlbmFibGUgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5yZWdpc3RlclRva2VucyA9ICRlbmFibGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiByZWdpc3RlcmVkIHRva2VucwogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb2tlbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dG9rZW5zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNjYW5uZXIncyBldmVudCBlbWl0dGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXZlbnRzRW1pdHRlcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXZlbnRzRW1pdHRlcigpCiAgICB7CiAgICAgICAgaWYgKCEkdGhpcy0+ZXZlbnRzRW1pdHRlcikgewogICAgICAgICAgICAvL1RoZSBldmVudCBlbWl0dGVyIGlzIGNyZWF0ZWQgaGVyZSBzbyB0aGF0IGl0IHdvbid0IGV4aXN0IGlmIG5vdAogICAgICAgICAgICAvL25lY2Vzc2FyeQogICAgICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciA9IG5ldyBFdmVudHNFbWl0dGVyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmV2ZW50c0VtaXR0ZXI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyBzdHJpY3QgbW9kZQogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc3RyaWN0TW9kZSBTdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdHJpY3RNb2RlKCRzdHJpY3RNb2RlKQogICAgewogICAgICAgICR0aGlzLT5zdHJpY3RNb2RlID0gJHN0cmljdE1vZGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiBzdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0cmljdE1vZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RyaWN0TW9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIHRva2VuIGlzIGEga2V5d29yZCBpbiB0aGUgY3VycmVudCBzdHJpY3QgbW9kZSBzdGF0ZQogICAgICogCiAgICAgKiBAcGFyYW0gVG9rZW4gJHRva2VuIFRva2VuIHRvIGNoZWNrcwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU3RyaWN0TW9kZUtleXdvcmQoJHRva2VuKQogICAgewogICAgICAgIHJldHVybiAkdG9rZW4tPmdldFR5cGUoKSA9PT0gVG9rZW46OlRZUEVfS0VZV09SRCAmJgogICAgICAgICAgICAgICAoaW5fYXJyYXkoJHRva2VuLT5nZXRWYWx1ZSgpLCAkdGhpcy0+a2V5d29yZHMpIHx8ICgKICAgICAgICAgICAgICAgICR0aGlzLT5zdHJpY3RNb2RlICYmCiAgICAgICAgICAgICAgICBpbl9hcnJheSgkdG9rZW4tPmdldFZhbHVlKCksICR0aGlzLT5zdHJpY3RNb2RlS2V5d29yZHMpKSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzY2FubmVyIHN0YXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXRlKCkKICAgIHsKICAgICAgICAvL0NvbnN1bWUgY3VycmVudCBhbmQgbmV4dCB0b2tlbnMgc28gdGhhdCB0aGV5IHdvbnQnIGJlIHBhcnNlZCBhZ2FpbgogICAgICAgIC8vaWYgdGhlIHN0YXRlIGlzIHJlc3RvcmVkCiAgICAgICAgJHRoaXMtPmdldE5leHRUb2tlbigpOwogICAgICAgICRzdGF0ZSA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnN0YXRlUHJvcHMgYXMgJHByb3ApIHsKICAgICAgICAgICAgJHN0YXRlWyRwcm9wXSA9ICR0aGlzLT4kcHJvcDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RlclRva2VucykgewogICAgICAgICAgICAkc3RhdGVbInRva2Vuc051bSJdID0gY291bnQoJHRoaXMtPnRva2Vucyk7CiAgICAgICAgfQogICAgICAgIC8vRW1pdCB0aGUgRnJlZXplU3RhdGUgZXZlbnQgYW5kIHBhc3MgdGhlIGdpdmVuIHN0YXRlIHNvIHRoYXQgbGlzdGVuZXJzCiAgICAgICAgLy9hdHRhY2hlZCB0byB0aGlzIGV2ZW50IGNhbiBhZGQgZGF0YQogICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyICYmICR0aGlzLT5ldmVudHNFbWl0dGVyLT5maXJlKAogICAgICAgICAgICAiRnJlZXplU3RhdGUiLCBhcnJheSgmJHN0YXRlKQogICAgICAgICk7CiAgICAgICAgcmV0dXJuICRzdGF0ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHNjYW5uZXIgc3RhdGUKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRzdGF0ZSBTdGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGF0ZSgkc3RhdGUpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5yZWdpc3RlclRva2VucykgewogICAgICAgICAgICAkdGhpcy0+dG9rZW5zID0gYXJyYXlfc2xpY2UoJHRoaXMtPnRva2VucywgMCwgJHN0YXRlWyJ0b2tlbnNOdW0iXSk7CiAgICAgICAgICAgIHVuc2V0KCRzdGF0ZVsidG9rZW5zTnVtIl0pOwogICAgICAgIH0KICAgICAgICAvL0VtaXQgdGhlIFJlc2V0U3RhdGUgZXZlbnQgYW5kIHBhc3MgdGhlIGdpdmVuIHN0YXRlCiAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICJSZXNldFN0YXRlIiwgYXJyYXkoJiRzdGF0ZSkKICAgICAgICApOwogICAgICAgIGZvcmVhY2ggKCRzdGF0ZSBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICAgICAkdGhpcy0+JGtleSA9ICR2YWx1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgY3VycmVudCBzY2FubmVyIHN0YXRlCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRzY2FuUG9zaXRpb24gQnkgZGVmYXVsdCB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBzY2FubmVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN1bWVkIHBvc2l0aW9uLCBpZiB0aGlzIHBhcmFtZXRlciBpcyB0cnVlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBzY2FubmVkIHBvc2l0aW9uIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqIAogICAgICogQHJldHVybiBQb3NpdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UG9zaXRpb24oJHNjYW5Qb3NpdGlvbiA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkc2NhblBvc2l0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUG9zaXRpb24oJHRoaXMtPmxpbmUsICR0aGlzLT5jb2x1bW4sICR0aGlzLT5pbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3NpdGlvbjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY3VycmVudCBzY2FuIHBvc2l0aW9uIGF0IHRoZSBnaXZlbiBvbmUKICAgICAqIAogICAgICogQHBhcmFtIFBvc2l0aW9uICRwb3NpdGlvbiBQb3NpdGlvbiBhdCB3aGljaCB0aGUgc2NhbiBwb3NpdGlvbiB3aWxsIGJlIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTY2FuUG9zaXRpb24oUG9zaXRpb24gJHBvc2l0aW9uID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+bGluZSA9ICRwb3NpdGlvbi0+Z2V0TGluZSgpOwogICAgICAgICR0aGlzLT5jb2x1bW4gPSAkcG9zaXRpb24tPmdldENvbHVtbigpOwogICAgICAgICR0aGlzLT5pbmRleCA9ICRwb3NpdGlvbi0+Z2V0SW5kZXgoKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIGdpdmVuIGluZGV4IGluIHRoZSBzb3VyY2UgY29kZSBvciBudWxsIGlmIHRoZQogICAgICogZW5kIGlzIHJlYWNoZWQuCiAgICAgKiAKICAgICAqIEBwYXJhbSBpbnQgJGluZGV4IEluZGV4LCBpZiBub3QgZ2l2ZW4gaXQgd2lsbCB1c2UgdGhlIGN1cnJlbnQgaW5kZXgKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hhckF0KCRpbmRleCA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCRpbmRleCA9PT0gbnVsbCkgewogICAgICAgICAgICAkaW5kZXggPSAkdGhpcy0+aW5kZXg7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+aXNFT0YoJGluZGV4KSA/IG51bGwgOiAkdGhpcy0+c291cmNlWyRpbmRleF07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBpbmRleCBpcyBhdCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcGFyYW0gaW50ICRpbmRleCBJbmRleCwgaWYgbm90IGdpdmVuIGl0IHdpbGwgdXNlIHRoZSBjdXJyZW50IGluZGV4CiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNFT0YoJGluZGV4ID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJGluZGV4ID09PSBudWxsKSB7CiAgICAgICAgICAgICRpbmRleCA9ICR0aGlzLT5pbmRleDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRpbmRleCA+PSAkdGhpcy0+bGVuZ3RoOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRocm93cyBhIHN5bnRheCBlcnJvcgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIEVycm9yIG1lc3NhZ2UKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKiAKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBlcnJvcigkbWVzc2FnZSA9IG51bGwpCiAgICB7CiAgICAgICAgaWYgKCEkbWVzc2FnZSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICJVbmV4cGVjdGVkICIgLiAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJG1lc3NhZ2UsICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29uc3VtZXMgdGhlIGN1cnJlbnQgdG9rZW4KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29uc3VtZVRva2VuKCkKICAgIHsKICAgICAgICAvL01vdmUgdGhlIHNjYW5uZXIgcG9zaXRpb24gdG8gdGhlIGVuZCBvZiB0aGUgY3VycmVudCBwb3NpdGlvbgogICAgICAgICR0aGlzLT5wb3NpdGlvbiA9ICR0aGlzLT5jdXJyZW50VG9rZW4tPmdldExvY2F0aW9uKCktPmdldEVuZCgpOwogICAgICAgIAogICAgICAgIC8vQmVmb3JlIGNvbnN1bWUgdGhlIHRva2VuLCBjb25zdW1lIGNvbW1lbnRzIGFzc29jaWF0ZWQgd2l0aCBpdAogICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVDb21tZW50c0ZvckN1cnJlbnRUb2tlbigpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL1JlZ2lzdGVyIHRoZSB0b2tlbiBpZiByZXF1aXJlZAogICAgICAgIGlmICgkdGhpcy0+cmVnaXN0ZXJUb2tlbnMpIHsKICAgICAgICAgICAgJHRoaXMtPnRva2Vuc1tdID0gJHRoaXMtPmN1cnJlbnRUb2tlbjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBUb2tlbkNvbnN1bWVkIGV2ZW50IGZvciB0aGUgY29uc3VtZWQgdG9rZW4KICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgIlRva2VuQ29uc3VtZWQiLCBhcnJheSgkdGhpcy0+Y3VycmVudFRva2VuKQogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbiA9ICR0aGlzLT5uZXh0VG9rZW4gPyAkdGhpcy0+bmV4dFRva2VuIDogbnVsbDsKICAgICAgICAkdGhpcy0+bmV4dFRva2VuID0gbnVsbDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBzdHJpbmcgaXMgbWF0Y2hlZCwgaWYgc28gaXQgY29uc3VtZXMgdGhlIHRva2VuCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGV4cGVjdGVkIFN0cmluZyB0byBjaGVjawogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvbnN1bWUoJGV4cGVjdGVkKQogICAgewogICAgICAgICR0b2tlbiA9ICR0aGlzLT5nZXRUb2tlbigpOwogICAgICAgIGlmICgkdG9rZW4gJiYgJHRva2VuLT5nZXRWYWx1ZSgpID09PSAkZXhwZWN0ZWQpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVUb2tlbigpOwogICAgICAgICAgICByZXR1cm4gJHRva2VuOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgb25lIG9mIHRoZSBnaXZlbiBzdHJpbmdzIGlzIG1hdGNoZWQsIGlmIHNvIGl0IGNvbnN1bWVzIHRoZQogICAgICogdG9rZW4KICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRleHBlY3RlZCBTdHJpbmdzIHRvIGNoZWNrCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29uc3VtZU9uZU9mKCRleHBlY3RlZCkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoJHRva2VuICYmIGluX2FycmF5KCR0b2tlbi0+Z2V0VmFsdWUoKSwgJGV4cGVjdGVkKSkgewogICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiAkdG9rZW47CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyB0aGF0IHRoZXJlIGFyZSBub3QgbGluZSB0ZXJtaW5hdG9ycyBmb2xsb3dpbmcgdGhlIGN1cnJlbnQgc2NhbgogICAgICogcG9zaXRpb24gYmVmb3JlIG5leHQgdG9rZW4KICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJG5leHRUb2tlbiBCeSBkZWZhdWx0IGl0IGNoZWNrcyB0aGUgY3VycmVudCB0b2tlbiBwb3NpdGlvbgogICAgICogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiwgaWYgdGhpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgaXMgdHJ1ZSB0aGUgY2hlY2sgd2lsbCBiZSBkb25lIHJlbGF0aXZlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIHRoZSBuZXh0IHRva2VuCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbm9MaW5lVGVybWluYXRvcnMoJG5leHRUb2tlbiA9IGZhbHNlKQogICAgewogICAgICAgIGlmICgkbmV4dFRva2VuKSB7CiAgICAgICAgICAgICRuZXh0VG9rZW4gPSAkdGhpcy0+Z2V0TmV4dFRva2VuKCk7CiAgICAgICAgICAgICRyZWZMaW5lID0gISRuZXh0VG9rZW4gPyBudWxsIDoKICAgICAgICAgICAgICAgICAgICAgICAgJG5leHRUb2tlbi0+Z2V0TG9jYXRpb24oKS0+Z2V0RW5kKCktPmdldExpbmUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcmVmTGluZSA9ICR0aGlzLT5nZXRQb3NpdGlvbigpLT5nZXRMaW5lKCk7CiAgICAgICAgfQogICAgICAgICR0b2tlbiA9ICR0aGlzLT5nZXRUb2tlbigpOwogICAgICAgIHJldHVybiAkdG9rZW4gJiYKICAgICAgICAgICAgICAgJHRva2VuLT5nZXRMb2NhdGlvbigpLT5nZXRFbmQoKS0+Z2V0TGluZSgpID09PSAkcmVmTGluZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgb25lIG9mIHRoZSBnaXZlbiBzdHJpbmdzIGZvbGxvd3MgdGhlIGN1cnJlbnQgc2NhbiBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICRleHBlY3RlZCAgU3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJG5leHRUb2tlbiBUaGlzIHBhcmFtZXRlciBtdXN0IGJlIHRydWUgaWYgdGhlIGZpcnN0CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGlzIGFuIGFycmF5IHNvIHRoYXQgaXQgd2lsbAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrIGFsc28gbmV4dCB0b2tlbnMKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0JlZm9yZSgkZXhwZWN0ZWQsICRuZXh0VG9rZW4gPSBmYWxzZSkKICAgIHsKICAgICAgICAkdG9rZW4gPSAkdGhpcy0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoISR0b2tlbikgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlaWYgKGluX2FycmF5KCR0b2tlbi0+Z2V0VmFsdWUoKSwgJGV4cGVjdGVkKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2VpZiAoISRuZXh0VG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoISR0aGlzLT5nZXROZXh0VG9rZW4oKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRleHBlY3RlZCBhcyAkdmFsKSB7CiAgICAgICAgICAgIGlmICghaXNfYXJyYXkoJHZhbCkgfHwgJHZhbFswXSAhPT0gJHRva2VuLT5nZXRWYWx1ZSgpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0lmIHRoZSBzZWNvbmQgdmFsdWUgaW4gdGhlIGFycmF5IGlzIHRydWUgY2hlY2sgdGhhdCB0aGUgY3VycmVudAogICAgICAgICAgICAvL3Rva2VuIGlzIG5vdCBmb2xsb3dlZCBieSBsaW5lIHRlcm1pbmF0b3JzLCBvdGhlcndpc2UgY29tcGFyZSBpdHMKICAgICAgICAgICAgLy92YWx1ZSB0byB0aGUgbmV4dCB0b2tlbgogICAgICAgICAgICBpZiAoKCR2YWxbMV0gPT09IHRydWUgJiYgJHRoaXMtPm5vTGluZVRlcm1pbmF0b3JzKHRydWUpKSB8fAogICAgICAgICAgICAgICAgKCR2YWxbMV0gIT09IHRydWUgJiYgJHZhbFsxXSA9PT0gJHRoaXMtPm5leHRUb2tlbi0+Z2V0VmFsdWUoKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmV4dFRva2VuKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5uZXh0VG9rZW4pIHsKICAgICAgICAgICAgJHRva2VuID0gJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBudWxsOwogICAgICAgICAgICAkdGhpcy0+bmV4dFRva2VuID0gJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSAkdG9rZW47CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+bmV4dFRva2VuOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdG9rZW4gCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VG9rZW4oKQogICAgewogICAgICAgIC8vVGhlIGN1cnJlbnQgdG9rZW4gaXMgcmV0dXJuZWQgdW50aWwgY29uc3VtZWQKICAgICAgICBpZiAoJHRoaXMtPmN1cnJlbnRUb2tlbikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmN1cnJlbnRUb2tlbjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJGNvbW1lbnRzID0gJHRoaXMtPnNraXBXaGl0ZXNwYWNlc0FuZENvbW1lbnRzKCk7CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBUb2tlbkNyZWF0ZWQgZXZlbnQgZm9yIGFsbCB0aGUgY29tbWVudHMgZm91bmQKICAgICAgICBpZiAoJGNvbW1lbnRzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb21tZW50cyBhcyAkY29tbWVudCkgewogICAgICAgICAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICAgICAgICAgIlRva2VuQ3JlYXRlZCIsIGFycmF5KCRjb21tZW50KQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoJHRoaXMtPmlzRU9GKCkpIHsKICAgICAgICAgICAgLy9XaGVuIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBpcyByZWFjaGVkCiAgICAgICAgICAgIC8vQ2hlY2sgaWYgdGhlcmUgYXJlIG9wZW4gYnJhY2tldHMKICAgICAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm9wZW5CcmFja2V0cyBhcyAkYnJhY2tldCA9PiAkbnVtKSB7CiAgICAgICAgICAgICAgICBpZiAoJG51bSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoIlVuY2xvc2VkICRicmFja2V0Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ2hlY2sgaWYgdGhlcmUgYXJlIG9wZW4gdGVtcGxhdGVzCiAgICAgICAgICAgIGlmIChjb3VudCgkdGhpcy0+b3BlblRlbXBsYXRlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoIlVudGVybWluYXRlZCB0ZW1wbGF0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvL1JlZ2lzdGVyIGNvbW1lbnRzIGFuZCBjb25zdW1lIHRoZW0KICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cyAmJiAkY29tbWVudHMpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb21tZW50c0ZvckN1cnJlbnRUb2tlbigkY29tbWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0VtaXQgdGhlIEVuZFJlYWNoZWQgZXZlbnQgd2hlbiBhdCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UKICAgICAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICAgICAiRW5kUmVhY2hlZCIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkc3RhcnRQb3NpdGlvbiA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAkb3JpZ0V4Y2VwdGlvbiA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vVHJ5IHRvIG1hdGNoIGEgdG9rZW4KICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgKCR0aGlzLT5qc3ggJiYgKCR0b2tlbiA9ICR0aGlzLT5zY2FuSlNYU3RyaW5nKCkpKSB8fAogICAgICAgICAgICAgICAgKCR0aGlzLT5qc3ggJiYgKCR0b2tlbiA9ICR0aGlzLT5zY2FuSlNYSWRlbnRpZmllcigpKSkgfHwKICAgICAgICAgICAgICAgICgkdG9rZW4gPSAkdGhpcy0+c2NhblN0cmluZygpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuVGVtcGxhdGUoKSkgfHwKICAgICAgICAgICAgICAgICgkdG9rZW4gPSAkdGhpcy0+c2Nhbk51bWJlcigpKSB8fAogICAgICAgICAgICAgICAgKCR0aGlzLT5qc3ggJiYgKCR0b2tlbiA9ICR0aGlzLT5zY2FuSlNYUHVuY3R1dGF0b3IoKSkpIHx8CiAgICAgICAgICAgICAgICAoJHRva2VuID0gJHRoaXMtPnNjYW5QdW5jdHV0YXRvcigpKSB8fAogICAgICAgICAgICAgICAgKCR0b2tlbiA9ICR0aGlzLT5zY2FuS2V5d29yZE9ySWRlbnRpZmllcigpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIC8vU2V0IHRoZSB0b2tlbiBzdGFyZCBhbmQgZW5kIHBvc2l0aW9ucwogICAgICAgICAgICAgICAgJHRva2VuLT5zZXRTdGFydFBvc2l0aW9uKCRzdGFydFBvc2l0aW9uKQogICAgICAgICAgICAgICAgICAgICAgLT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpOwogICAgICAgICAgICAgICAgJHRoaXMtPmN1cnJlbnRUb2tlbiA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vUmVnaXN0ZXIgY29tbWVudHMgaWYgcmVxdWlyZWQKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMgJiYgJGNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCRjb21tZW50cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vRW1pdCB0aGUgVG9rZW5DcmVhdGVkIGV2ZW50IGZvciB0aGUgdG9rZW4ganVzdCBjcmVhdGVkCiAgICAgICAgICAgICAgICAkdGhpcy0+ZXZlbnRzRW1pdHRlciAmJiAkdGhpcy0+ZXZlbnRzRW1pdHRlci0+ZmlyZSgKICAgICAgICAgICAgICAgICAgICAiVG9rZW5DcmVhdGVkIiwgYXJyYXkoJHRoaXMtPmN1cnJlbnRUb2tlbikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y3VycmVudFRva2VuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkb3JpZ0V4Y2VwdGlvbiA9ICRlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0lmIGxhc3QgdG9rZW4gd2FzICIvIiBkbyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHRva2VuIGhhcyBub3QgYmUKICAgICAgICAvL3JlY29nbml6ZWQgc2luY2UgaXQgY2FuIGJlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gYSByZWdleHAgYW5kIGl0IHdpbGwKICAgICAgICAvL2JlIGNvbnN1bWVkIHdoZW4gdGhlIGN1cnJlbnQgdG9rZW4gd2lsbCBiZSByZWNvbnN1bWVkIGFzIGEgcmVnZXhwCiAgICAgICAgaWYgKCR0aGlzLT5pc0FmdGVyU2xhc2goJHN0YXJ0UG9zaXRpb24pKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRTY2FuUG9zaXRpb24oJHN0YXJ0UG9zaXRpb24pOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9ObyB2YWxpZCB0b2tlbiBmb3VuZC4gSWYgdGhlcmUgd2FzIGEgc2NhbiBlcnJvciwgdGhyb3cgdGhlIHNhbWUKICAgICAgICAvL2V4Y2VwdGlvbiBhZ2Fpbiwgb3RoZXJ3aXNlIHRocm93IGEgbmV3IGVycm9yCiAgICAgICAgaWYgKCRvcmlnRXhjZXB0aW9uKSB7CiAgICAgICAgICAgIHRocm93ICRvcmlnRXhjZXB0aW9uOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIG9wZXJhdGlvbnMgdG8gaGFuZGxlIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzY2FubmluZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjb25zdW1lRW5kKCkKICAgIHsKICAgICAgICAvL0NvbnN1bWUgZmluYWwgY29tbWVudHMKICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICR0aGlzLT5jb25zdW1lQ29tbWVudHNGb3JDdXJyZW50VG9rZW4oKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9FbWl0IHRoZSBFbmRSZWFjaGVkIGV2ZW50IHdoZW4gYXQgdGhlIGVuZCBvZiB0aGUgc291cmNlCiAgICAgICAgJHRoaXMtPmV2ZW50c0VtaXR0ZXIgJiYgJHRoaXMtPmV2ZW50c0VtaXR0ZXItPmZpcmUoCiAgICAgICAgICAgICJFbmRSZWFjaGVkIgogICAgICAgICk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEdldHMgb3Igc2V0cyBjb21tZW50cyBmb3IgdGhlIGN1cnJlbnQgdG9rZW4uIElmIHRoZSBwYXJhbWV0ZXIgaXMgYW4KICAgICAqIGFycmF5IGl0IGFzc29jaWF0ZXMgdGhlIGdpdmVuIGNvbW1lbnRzIGFycmF5IHRvIHRoZSBjdXJyZW50IG5vZGUsCiAgICAgKiBvdGhlcndpc2UgY29tbWVudHMgZm9yIHRoZSBjdXJyZW50IHRva2VuIGFyZSByZXR1cm5lZAogICAgICogCiAgICAgKiBAcGFyYW0gYXJyYXkgJGNvbW1lbnRzICBDb21tZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb21tZW50c0ZvckN1cnJlbnRUb2tlbigkY29tbWVudHMgPSBudWxsKQogICAgewogICAgICAgICRpZCA9ICR0aGlzLT5jdXJyZW50VG9rZW4gPyBzcGxfb2JqZWN0X2hhc2goJHRoaXMtPmN1cnJlbnRUb2tlbikgOiAiIjsKICAgICAgICBpZiAoJGNvbW1lbnRzICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21tZW50c01hcFskaWRdID0gJGNvbW1lbnRzOwogICAgICAgIH0gZWxzZWlmIChpc3NldCgkdGhpcy0+Y29tbWVudHNNYXBbJGlkXSkpIHsKICAgICAgICAgICAgJGNvbW1lbnRzID0gJHRoaXMtPmNvbW1lbnRzTWFwWyRpZF07CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5jb21tZW50c01hcFskaWRdKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjb21tZW50czsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb25zdW1lcyBjb21tZW50IHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgdG9rZW4KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uc3VtZUNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCkKICAgIHsKICAgICAgICAkY29tbWVudHMgPSAkdGhpcy0+Y29tbWVudHNGb3JDdXJyZW50VG9rZW4oKTsKICAgICAgICBpZiAoJGNvbW1lbnRzICYmICgkdGhpcy0+cmVnaXN0ZXJUb2tlbnMgfHwgJHRoaXMtPmV2ZW50c0VtaXR0ZXIpKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRjb21tZW50cyBhcyAkY29tbWVudCkgewogICAgICAgICAgICAgICAgLy9SZWdpc3RlciB0aGUgdG9rZW4gaWYgcmVxdWlyZWQKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cmVnaXN0ZXJUb2tlbnMpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dG9rZW5zW10gPSAkY29tbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vRW1pdCB0aGUgVG9rZW5Db25zdW1lZCBldmVudCBmb3IgdGhlIGNvbW1lbnQKICAgICAgICAgICAgICAgICR0aGlzLT5ldmVudHNFbWl0dGVyICYmICR0aGlzLT5ldmVudHNFbWl0dGVyLT5maXJlKAogICAgICAgICAgICAgICAgICAgICJUb2tlbkNvbnN1bWVkIiwgYXJyYXkoJGNvbW1lbnQpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGNvbnN1bWVkIG9yIHRoZSBzY2FubmVkIHBvc2l0aW9uIGZvbGxvdyBhIHNsYXNoLgogICAgICogCiAgICAgKiBAcGFyYW0gUG9zaXRpb24gJHBvc2l0aW9uICBBZGRpdGlvbmFsIHBvc2l0aW9uIHRvIGNoZWNrCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gaXNBZnRlclNsYXNoKCRwb3NpdGlvbiA9IG51bGwpCiAgICB7CiAgICAgICAgJGNvbnN1bWVkSW5kZXggPSAkdGhpcy0+Z2V0UG9zaXRpb24oKS0+Z2V0SW5kZXgoKTsKICAgICAgICAkY2hlY2tJbmRpY2VzID0gYXJyYXkoJGNvbnN1bWVkSW5kZXgsICRjb25zdW1lZEluZGV4ICsgMSk7CiAgICAgICAgaWYgKCRwb3NpdGlvbikgewogICAgICAgICAgICAkY2hlY2tJbmRpY2VzW10gPSAkcG9zaXRpb24tPmdldEluZGV4KCkgLSAxOwogICAgICAgIH0KICAgICAgICBmb3JlYWNoICgkY2hlY2tJbmRpY2VzIGFzICRpKSB7CiAgICAgICAgICAgIGlmICgkaSA+PSAwICYmICR0aGlzLT5jaGFyQXQoJGkpID09PSAiLyIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUcmllcyB0byByZWNvbnN1bWUgdGhlIGN1cnJlbnQgdG9rZW4gYXMgYSByZWdleHAgaWYgcG9zc2libGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWNvbnN1bWVDdXJyZW50VG9rZW5Bc1JlZ2V4cCgpCiAgICB7CiAgICAgICAgJHRva2VuID0gJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgJHZhbHVlID0gJHRva2VuID8gJHRva2VuLT5nZXRWYWx1ZSgpIDogbnVsbDsKICAgICAgICAKICAgICAgICAvL0NoZWNrIGlmIHRoZSB0b2tlbiBzdGFydHMgd2l0aCAiLyIKICAgICAgICBpZiAoISR2YWx1ZSB8fCAkdmFsdWVbMF0gIT09ICIvIikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9SZXNldCB0aGUgc2Nhbm5lciBwb3NpdGlvbiB0byB0aGUgdG9rZW4ncyBzdGFydCBwb3NpdGlvbgogICAgICAgICRzdGFydFBvc2l0aW9uID0gJHRva2VuLT5nZXRMb2NhdGlvbigpLT5nZXRTdGFydCgpOwogICAgICAgICR0aGlzLT5zZXRTY2FuUG9zaXRpb24oJHN0YXJ0UG9zaXRpb24pOwogICAgICAgIAogICAgICAgICRidWZmZXIgPSAiLyI7CiAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICRpbkNsYXNzID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgLy9JbiBhIGNoYXJhY3RlcnMgY2xhc3MgdGhlIGRlbG1pdGVyICIvIiBpcyBhbGxvd2VkIHdpdGhvdXQgZXNjYXBlLAogICAgICAgICAgICAvL3NvIHRoZSBjaGFyYWN0ZXJzIGNsYXNzIG11c3QgYmUgY2xvc2VkIGJlZm9yZSBjbG9zaW5nIHRoZSByZWdleHAKICAgICAgICAgICAgJHN0b3BzID0gJGluQ2xhc3MgPyBhcnJheSgiXSIpIDogYXJyYXkoIi8iLCAiWyIpOwogICAgICAgICAgICAkdGVtcEJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lVW50aWwoJHN0b3BzKTsKICAgICAgICAgICAgaWYgKCR0ZW1wQnVmZmVyID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoJGluQ2xhc3MpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgICAgICAgICAiVW50ZXJtaW5hdGVkIGNoYXJhY3RlciBjbGFzcyBpbiByZWdleHAiCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigiVW50ZXJtaW5hdGVkIHJlZ2V4cCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXJbMF07CiAgICAgICAgICAgIGlmICgkdGVtcEJ1ZmZlclsxXSA9PT0gIi8iKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpbkNsYXNzID0gJHRlbXBCdWZmZXJbMV0gPT09ICJbIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL0ZsYWdzCiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5jaGFyQXQoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgJGxvd2VyID0gc3RydG9sb3dlcigkY2hhcik7CiAgICAgICAgICAgIGlmICgkbG93ZXIgPj0gImEiICYmICRsb3dlciA8PSAieiIpIHsKICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vSWYgbmV4dCB0b2tlbiBoYXMgYWxyZWFkeSBiZWVuIHBhcnNlZCBhbmQgaXQncyBhIGJyYWNrZXQgZXhjbHVkZSBpdAogICAgICAgIC8vZnJvbSB0aGUgY291bnQgb2Ygb3BlbiBicmFja2V0cwogICAgICAgIGlmICgkdGhpcy0+bmV4dFRva2VuKSB7CiAgICAgICAgICAgICRuZXh0VmFsID0gJHRoaXMtPm5leHRUb2tlbi0+Z2V0VmFsdWUoKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5icmFja2V0c1skbmV4dFZhbF0pICYmCiAgICAgICAgICAgICAgICBpc3NldCgkdGhpcy0+b3BlbkJyYWNrZXRzWyRuZXh0VmFsXSkKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmJyYWNrZXRzWyRuZXh0VmFsXSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuQnJhY2tldHNbJG5leHRWYWxdKys7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuQnJhY2tldHNbJG5leHRWYWxdLS07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPm5leHRUb2tlbiA9IG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vSWYgY29tbWVudHMgaGFuZGxpbmcgaXMgZW5hYmxlZCwgZ2V0IHRoZSBjb21tZW50cyBhc3NvY2lhdGVkIHdpdGggdGhlCiAgICAgICAgLy9jdXJyZW50IHRva2VuCiAgICAgICAgJGNvbW1lbnRzID0gJHRoaXMtPmNvbW1lbnRzID8gJHRoaXMtPmNvbW1lbnRzRm9yQ3VycmVudFRva2VuKCkgOiBudWxsOwogICAgICAgICAgICAKICAgICAgICAvL1JlcGxhY2UgdGhlIGN1cnJlbnQgdG9rZW4gd2l0aCBhIHJlZ2V4cCB0b2tlbgogICAgICAgICR0b2tlbiA9IG5ldyBUb2tlbihUb2tlbjo6VFlQRV9SRUdVTEFSX0VYUFJFU1NJT04sICRidWZmZXIpOwogICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSAkdG9rZW4tPnNldFN0YXJ0UG9zaXRpb24oJHN0YXJ0UG9zaXRpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+c2V0RW5kUG9zaXRpb24oJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgaWYgKCRjb21tZW50cykgewogICAgICAgICAgICAvL0F0dGFjaCB0aGUgY29tbWVudHMgdG8gdGhlIG5ldyBjdXJyZW50IHRva2VuCiAgICAgICAgICAgICR0aGlzLT5jb21tZW50c0ZvckN1cnJlbnRUb2tlbigkY29tbWVudHMpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJHRoaXMtPmN1cnJlbnRUb2tlbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTa2lwcyB3aGl0ZXNwYWNlcyBhbmQgY29tbWVudHMgZnJvbSB0aGUgY3VycmVudCBzY2FuIHBvc2l0aW9uLiBJZgogICAgICogY29tbWVudHMgaGFuZGxpbmcgaXMgZW5hYmxlZCwgdGhlIGFycmF5IG9mIHBhcnNlZCBjb21tZW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBza2lwV2hpdGVzcGFjZXNBbmRDb21tZW50cygpCiAgICB7CiAgICAgICAgJGNvbW1lbnRzID0gW107CiAgICAgICAgJGNvbnRlbnQgPSAiIjsKICAgICAgICAkc2VjU3RhcnRJZHggPSAkdGhpcy0+aW5kZXg7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5jaGFyQXQoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgLy9XaGl0ZXNwYWNlCiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY2hhciwgJHRoaXMtPndoaXRlc3BhY2VzKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgkY2hhciA9PT0gIi8iKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vQ29tbWVudAogICAgICAgICAgICAgICAgJG5leHRDaGFyID0gJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAxKTsKICAgICAgICAgICAgICAgIGlmICgkbmV4dENoYXIgPT09ICIvIiB8fCAkbmV4dENoYXIgPT09ICIqIikgewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vSWYgY29tbWVudHMgbXVzdCBiZSBoYW5kbGVkLCBlbXB0eSB0aGUgY3VycmVudCBjb250ZW50IHRvbwogICAgICAgICAgICAgICAgICAgIC8vYW5kIGdldCB0aGUgY29tbWVudCBzdGFydCBwb3NpdGlvbgogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb250ZW50ICE9PSAiIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmFkanVzdENvbHVtbkFuZExpbmUoJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkc3RhcnQgPSAkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICRpbmxpbmUgPSAkbmV4dENoYXIgPT09ICIvIjsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gMjsKICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhciAuICRuZXh0Q2hhcjsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY2hhciA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkaW5saW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgaGFzIGJlZW4gcmVhY2hlZCBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2EgbXVsdGlsaW5lIGNvbW1lbnQgaXMgc3RpbGwgb3BlbiwgaXQncyBhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCJVbnRlcm1pbmF0ZWQgY29tbWVudCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlzRW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50IC49ICRjaGFyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaXNFbmQgPSAkaW5saW5lID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSW5saW5lIGNvbW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluX2FycmF5KCRjaGFyLCAkdGhpcy0+bGluZVRlcm1pbmF0b3JzKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL011bHRpbGluZSBjb21tZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2hhciA9PT0gIioiICYmICR0aGlzLT5jaGFyQXQoKSA9PT0gIi8iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlzRW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISRpbmxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAiLyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9Gb3IgaW5saW5lIGNvbW1lbnRzIHRoZSBjbG9zaW5nIGxpbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Rlcm1pbmF0b3IgbXVzdCBiZSBleGNsdWRlZCBmcm9tIGNvbW1lbnQgdGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaW5saW5lICYmICRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleC0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9IHN1YnN0cigkY29udGVudCwgMCwgLXN0cmxlbigkY2hhcikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRqdXN0Q29sdW1uQW5kTGluZSgkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRva2VuID0gbmV3IFRva2VuKFRva2VuOjpUWVBFX0NPTU1FTlQsICRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW4tPnNldFN0YXJ0UG9zaXRpb24oJHN0YXJ0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+c2V0RW5kUG9zaXRpb24oJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29tbWVudHNbXSA9ICR0b2tlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0ZvciBpbmxpbmUgY29tbWVudHMgdGhlIG5ldyBjb250ZW50IGNvbnRhaW5zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGUgY2xvc2luZyBsaW5lIHRlcm1pbmF0b3Igc2luY2UgdGhlIGNoYXIgaGFzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hbHJlYWR5IGJlZW4gcHJvY2Vzc2VkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlubGluZSAmJiAkY2hhciAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICRjaGFyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+aXNNb2R1bGUgJiYgJGNoYXIgPT09ICI8IiAmJgogICAgICAgICAgICAgICAgJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAxKSA9PT0gIiEiICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArIDIpID09PSAiLSIgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5jaGFyQXQoJHRoaXMtPmluZGV4ICsgMykgPT09ICItIgogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy9JZiBjb21tZW50cyBtdXN0IGJlIGhhbmRsZWQsIGVtcHR5IHRoZSBjdXJyZW50IGNvbnRlbnQgdG9vCiAgICAgICAgICAgICAgICAvL2FuZCBnZXQgdGhlIGNvbW1lbnQgc3RhcnQgcG9zaXRpb24KICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+Y29tbWVudHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRlbnQgIT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHN0YXJ0ID0gJHRoaXMtPmdldFBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvL09wZW4gaHRtbCBjb21tZW50CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXggKz0gNDsKICAgICAgICAgICAgICAgICRjb250ZW50IC49ICI8IS0tIjsKICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRpc0VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAkaXNFbmQgPSBpbl9hcnJheSgkY2hhciwgJHRoaXMtPmxpbmVUZXJtaW5hdG9ycyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkaXNFbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgdGhlIGNsb3NpbmcgbGluZSB0ZXJtaW5hdG9yIGZyb20gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NvbW1lbnQgdGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4LS07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSBzdWJzdHIoJGNvbnRlbnQsIDAsIC1zdHJsZW4oJGNoYXIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbiA9IG5ldyBUb2tlbihUb2tlbjo6VFlQRV9DT01NRU5ULCAkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW4tPnNldFN0YXJ0UG9zaXRpb24oJHN0YXJ0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbW1lbnRzW10gPSAkdG9rZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfSBlbHNlaWYgKCEkdGhpcy0+aXNNb2R1bGUgJiYgJGNoYXIgPT09ICItIiAmJgogICAgICAgICAgICAgICAgJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAxKSA9PT0gIi0iICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArIDIpID09PSAiPiIKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vQ2xvc2UgaHRtbCBjb21tZW50CiAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIGl0IGlzIG9uIGl0J3Mgb3duIGxpbmUKICAgICAgICAgICAgICAgICRhbGxvdyA9IGZhbHNlOwogICAgICAgICAgICAgICAgaWYgKCEkc2VjU3RhcnRJZHgpIHsKICAgICAgICAgICAgICAgICAgICAkYWxsb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKCRpbmRleCA9ICR0aGlzLT5pbmRleCAtIDE7ICRpbmRleCA+PSAkc2VjU3RhcnRJZHg7ICRpbmRleC0tKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkdGhpcy0+Y2hhckF0KCRpbmRleCksICR0aGlzLT5saW5lVGVybWluYXRvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYWxsb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJGFsbG93KSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy9JZiBjb21tZW50cyBtdXN0IGJlIGhhbmRsZWQsIGVtcHR5IHRoZSBjdXJyZW50IGNvbnRlbnQgdG9vCiAgICAgICAgICAgICAgICAgICAgLy9hbmQgZ2V0IHRoZSBjb21tZW50IHN0YXJ0IHBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb21tZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRlbnQgIT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+YWRqdXN0Q29sdW1uQW5kTGluZSgkY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICRzdGFydCA9ICR0aGlzLT5nZXRQb3NpdGlvbih0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDM7CiAgICAgICAgICAgICAgICAgICAgJGNvbnRlbnQgLj0gIi0tPiI7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpc0VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudCAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlzRW5kID0gaW5fYXJyYXkoJGNoYXIsICR0aGlzLT5saW5lVGVybWluYXRvcnMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGlzRW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmNvbW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgdGhlIGNsb3NpbmcgbGluZSB0ZXJtaW5hdG9yIGZyb20gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jb21tZW50IHRleHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNoYXIgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4LS07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50ID0gc3Vic3RyKCRjb250ZW50LCAwLCAtc3RybGVuKCRjaGFyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdG9rZW4gPSBuZXcgVG9rZW4oVG9rZW46OlRZUEVfQ09NTUVOVCwgJGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0b2tlbi0+c2V0U3RhcnRQb3NpdGlvbigkc3RhcnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21tZW50c1tdID0gJHRva2VuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50ID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGFyICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250ZW50ID0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKCRjb250ZW50ICE9PSAiIikgewogICAgICAgICAgICAkdGhpcy0+YWRqdXN0Q29sdW1uQW5kTGluZSgkY29udGVudCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkY29tbWVudHM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU3RyaW5nIHNjYW5uaW5nIG1ldGhvZAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkaGFuZGxlRXNjYXBlIFRydWUgdG8gaGFuZGxlIGVzY2FwaW5nCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2NhblN0cmluZygkaGFuZGxlRXNjYXBlID0gdHJ1ZSkKICAgIHsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICBpZiAoJGNoYXIgPT09ICInIiB8fCAkY2hhciA9PT0gJyInKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgIC8vQWRkIHRoZSBxdW90ZSB0byB0aGUgTFNNIGFuZCB0aGVuIHJlbW92ZSBpdCBhZnRlciBjb25zdW1pbmcKICAgICAgICAgICAgJHRoaXMtPnN0cmluZ3NTdG9wc0xTTS0+YWRkKCRjaGFyKTsKICAgICAgICAgICAgJGJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lVW50aWwoJHRoaXMtPnN0cmluZ3NTdG9wc0xTTSwgJGhhbmRsZUVzY2FwZSk7CiAgICAgICAgICAgICR0aGlzLT5zdHJpbmdzU3RvcHNMU00tPnJlbW92ZSgkY2hhcik7CiAgICAgICAgICAgIGlmICgkYnVmZmVyID09PSBudWxsIHx8ICRidWZmZXJbMV0gIT09ICRjaGFyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCJVbnRlcm1pbmF0ZWQgc3RyaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBUb2tlbihUb2tlbjo6VFlQRV9TVFJJTkdfTElURVJBTCwgJGNoYXIgLiAkYnVmZmVyWzBdKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGVtcGxhdGUgc2Nhbm5pbmcgbWV0aG9kCiAgICAgKiAKICAgICAqIEByZXR1cm4gVG9rZW58bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2NhblRlbXBsYXRlKCkKICAgIHsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAKICAgICAgICAvL0dldCB0aGUgY3VycmVudCBudW1iZXIgb2Ygb3BlbiBjdXJseSBicmFja2V0cwogICAgICAgICRvcGVuQ3VybHkgPSBpc3NldCgkdGhpcy0+b3BlbkJyYWNrZXRzWyJ7Il0pID8KICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZW5CcmFja2V0c1sieyJdIDoKICAgICAgICAgICAgICAgICAgICAgMDsKICAgICAgICAKICAgICAgICAvL0lmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjdXJseSBicmFja2V0IGNoZWNrIGFuZCB0aGUgbnVtYmVyIG9mIG9wZW4KICAgICAgICAvL2N1cmx5IGJyYWNrZXRzIG1hdGNoZXMgdGhlIGxhc3QgbnVtYmVyIGluIHRoZSBvcGVuIHRlbXBsYXRlcyBzdGFjaywKICAgICAgICAvL3RoZW4gdGhlIGJyYWNrZXQgY2xvc2VzIHRoZSBvcGVuIHRlbXBsYXRlIGV4cHJlc3Npb24KICAgICAgICAkZW5kRXhwcmVzc2lvbiA9IGZhbHNlOwogICAgICAgIGlmICgkY2hhciA9PT0gIn0iKSB7CiAgICAgICAgICAgICRsZW4gPSBjb3VudCgkdGhpcy0+b3BlblRlbXBsYXRlcyk7CiAgICAgICAgICAgIGlmICgkbGVuICYmICR0aGlzLT5vcGVuVGVtcGxhdGVzWyRsZW4gLSAxXSA9PT0gJG9wZW5DdXJseSkgewogICAgICAgICAgICAgICAgJGVuZEV4cHJlc3Npb24gPSB0cnVlOwogICAgICAgICAgICAgICAgYXJyYXlfcG9wKCR0aGlzLT5vcGVuVGVtcGxhdGVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoJGNoYXIgPT09ICJgIiB8fCAkZW5kRXhwcmVzc2lvbikgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyID0gJGNoYXI7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAkdGVtcEJ1ZmZlciA9ICR0aGlzLT5jb25zdW1lVW50aWwoYXJyYXkoImAiLCAiJCIpKTsKICAgICAgICAgICAgICAgIGlmICghJHRlbXBCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCJVbnRlcm1pbmF0ZWQgdGVtcGxhdGUiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXJbMF07CiAgICAgICAgICAgICAgICBpZiAoJHRlbXBCdWZmZXJbMV0gIT09ICIkIiB8fCAkdGhpcy0+Y2hhckF0KCkgPT09ICJ7IikgewogICAgICAgICAgICAgICAgICAgIC8vSWYgIiR7IiBpcyBmb3VuZCBpdCdzIGEgbmV3IHRlbXBsYXRlIGV4cHJlc3Npb24sIHJlZ2lzdGVyCiAgICAgICAgICAgICAgICAgICAgLy90aGUgY3VycmVudCBudW1iZXIgb2Ygb3BlbiBjdXJseSBicmFja2V0cyBpbiB0aGUgb3BlbgogICAgICAgICAgICAgICAgICAgIC8vdGVtcGxhdGVzIHN0YWNrCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0ZW1wQnVmZmVyWzFdID09PSAiJCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAieyI7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuVGVtcGxhdGVzW10gPSAkb3BlbkN1cmx5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuKFRva2VuOjpUWVBFX1RFTVBMQVRFLCAkYnVmZmVyKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogTnVtYmVyIHNjYW5uaW5nIG1ldGhvZAogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNjYW5OdW1iZXIoKQogICAgewogICAgICAgIC8vTnVtYmVycyBjYW4gc3RhcnQgd2l0aCBhIGRlY2ltYWwgbnVtYmVyIG9yIHdpdGggYSBkb3QgKC41KQogICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIGlmICghKCgkY2hhciA+PSAiMCIgJiYgJGNoYXIgPD0gIjkiKSB8fCAkY2hhciA9PT0gIi4iKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkYWxsb3dlZEV4cCA9IHRydWU7CiAgICAgICAgCiAgICAgICAgLy9QYXJzZSB0aGUgaW50ZWdlciBwYXJ0CiAgICAgICAgaWYgKCRjaGFyICE9PSAiLiIpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29uc3VtZSBhbGwgZGVjaW1hbCBudW1iZXJzCiAgICAgICAgICAgICRidWZmZXIgPSAkdGhpcy0+Y29uc3VtZU51bWJlcnMoKTsKICAgICAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoJHRoaXMtPmZlYXR1cmVzLT5iaWdJbnQgJiYgJGNoYXIgPT09ICJuIikgewogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuKFRva2VuOjpUWVBFX0JJR0lOVF9MSVRFUkFMLCAkYnVmZmVyIC4gJGNoYXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAkbG93ZXIgPSAkY2hhciAhPT0gbnVsbCA/IHN0cnRvbG93ZXIoJGNoYXIpIDogbnVsbDsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vSGFuZGxlIGhleGFkZWNpbWFsICgweCksIG9jdGFsICgwbykgYW5kIGJpbmFyeSAoMGIpIGZvcm1zCiAgICAgICAgICAgIGlmICgkYnVmZmVyID09PSAiMCIgJiYgJGxvd2VyICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICBpc3NldCgkdGhpcy0+eyRsb3dlciAuICJudW1iZXJzIn0pCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCRsb3dlcik7CiAgICAgICAgICAgICAgICBpZiAoJHRlbXBCdWZmZXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCJNaXNzaW5nIG51bWJlcnMgYWZ0ZXIgMCRjaGFyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyIC4gJHRlbXBCdWZmZXI7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vQ2hlY2sgdGhhdCB0aGVyZSBhcmUgbm90IG51bWJlcnMgbGVmdAogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5jb25zdW1lTnVtYmVycygpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZmVhdHVyZXMtPmJpZ0ludCAmJiAkdGhpcy0+Y2hhckF0KCkgPT09ICJuIikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuKFRva2VuOjpUWVBFX0JJR0lOVF9MSVRFUkFMLCAkYnVmZmVyIC4gJGNoYXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuKFRva2VuOjpUWVBFX05VTUVSSUNfTElURVJBTCwgJGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29uc3VtZSBleHBvbmVudCBwYXJ0IGlmIHByZXNlbnQKICAgICAgICAgICAgaWYgKCR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVFeHBvbmVudFBhcnQoKSkgewogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkdGVtcEJ1ZmZlcjsKICAgICAgICAgICAgICAgICRhbGxvd2VkRXhwID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9QYXJzZSB0aGUgZGVjaW1hbCBwYXJ0CiAgICAgICAgaWYgKCR0aGlzLT5jaGFyQXQoKSA9PT0gIi4iKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0NvbnN1bWUgdGhlIGRvdAogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyIC49ICIuIjsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29uc3VtZSBhbGwgZGVjaW1hbCBudW1iZXJzCiAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCk7CiAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXI7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0lmIHRoZSBidWZmZXIgY29udGFpbnMgb25seSB0aGUgZG90IGl0IHNob3VsZCBiZSBwYXJzZWQgYXMKICAgICAgICAgICAgLy9wdW5jdHV0YXRvcgogICAgICAgICAgICBpZiAoJGJ1ZmZlciA9PT0gIi4iKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgtLTsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4tLTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0NvbnN1bWUgZXhwb25lbnQgcGFydCBpZiBwcmVzZW50CiAgICAgICAgICAgIGlmICgoJHRlbXBCdWZmZXIgPSAkdGhpcy0+Y29uc3VtZUV4cG9uZW50UGFydCgpKSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKCEkYWxsb3dlZEV4cCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoIkludmFsaWQgZXhwb25lbnRpYWwgbm90YXRpb24iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG5ldyBUb2tlbihUb2tlbjo6VFlQRV9OVU1FUklDX0xJVEVSQUwsICRidWZmZXIpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBkaWdpdHMKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkdHlwZSBEaWdpdHMgdHlwZSAoZGVjaW1hbCwgaGV4YWRlY2ltYWwsIGV0Yy4uLikKICAgICAqIEBwYXJhbSBpbnQgICAgJG1heCAgTWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIHRvIG1hdGNoCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVOdW1iZXJzKCR0eXBlID0gIiIsICRtYXggPSBudWxsKQogICAgewogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAkY291bnQgPSAwOwogICAgICAgICRleHRyYSA9ICR0aGlzLT5mZWF0dXJlcy0+bnVtZXJpY0xpdGVyYWxTZXBhcmF0b3IgPyAiXyIgOiAiIjsKICAgICAgICB3aGlsZSAoCiAgICAgICAgICAgIGluX2FycmF5KCRjaGFyLCAkdGhpcy0+eyR0eXBlIC4gIm51bWJlcnMifSkgfHwKICAgICAgICAgICAgKCRjb3VudCAmJiAkY2hhciA9PT0gJGV4dHJhKQogICAgICAgICkgewogICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkY291bnQgKys7CiAgICAgICAgICAgIGlmICgkY291bnQgPT09ICRtYXgpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIH0KICAgICAgICBpZiAoJGNvdW50ICYmIHN1YnN0cigkYnVmZmVyLCAtMSkgPT09ICJfIikgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKAogICAgICAgICAgICAgICAgIk51bWVyaWMgc2VwYXJhdG9ycyBhcmUgbm90IGFsbG93ZWQgYXQgdGhlIGVuZCBvZiBhIG51bWJlciIKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRjb3VudCA/ICRidWZmZXIgOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBleHBvbmVudCBwYXJ0IG9mIGEgbnVtYmVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVFeHBvbmVudFBhcnQoKQogICAgewogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICBpZiAoc3RydG9sb3dlcigkY2hhcikgPT09ICJlIikgewogICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbisrOwogICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAgICAgaWYgKCRjaGFyID09PSAiKyIgfHwgJGNoYXIgPT09ICItIikgewogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0ZW1wQnVmZmVyID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCk7CiAgICAgICAgICAgIGlmICgkdGVtcEJ1ZmZlciA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigiTWlzc2luZyBleHBvbmVudCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRidWZmZXIgLj0gJHRlbXBCdWZmZXI7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFB1bmN0dXRhdG9yIHNjYW5uaW5nIG1ldGhvZAogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNjYW5QdW5jdHV0YXRvcigpCiAgICB7CiAgICAgICAgJHRva2VuID0gbnVsbDsKICAgICAgICAkY2hhciA9ICR0aGlzLT5jaGFyQXQoKTsKICAgICAgICAKICAgICAgICAvL0NoZWNrIGlmIHRoZSBuZXh0IGNoYXIgaXMgYSBicmFja2V0CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5icmFja2V0c1skY2hhcl0pKSB7CiAgICAgICAgICAgIC8vQ2hlY2sgaWYgaXQgaXMgYSBjbG9zaW5nIGJyYWNrZXQKICAgICAgICAgICAgaWYgKCR0aGlzLT5icmFja2V0c1skY2hhcl0pIHsKICAgICAgICAgICAgICAgICRvcGVuQnJhY2tldCA9ICR0aGlzLT5icmFja2V0c1skY2hhcl07CiAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBvcGVuIGJyYWNrZXQKICAgICAgICAgICAgICAgIGlmICghaXNzZXQoJHRoaXMtPm9wZW5CcmFja2V0c1skb3BlbkJyYWNrZXRdKSB8fAogICAgICAgICAgICAgICAgICAgICEkdGhpcy0+b3BlbkJyYWNrZXRzWyRvcGVuQnJhY2tldF0KICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlzQWZ0ZXJTbGFzaCgkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5vcGVuQnJhY2tldHNbJG9wZW5CcmFja2V0XS0tOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+b3BlbkJyYWNrZXRzWyRjaGFyXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3BlbkJyYWNrZXRzWyRjaGFyXSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+b3BlbkJyYWNrZXRzWyRjaGFyXSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICR0b2tlbiA9IG5ldyBUb2tlbihUb2tlbjo6VFlQRV9QVU5DVFVUQVRPUiwgJGNoYXIpOwogICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgLy9UcnkgdG8gbWF0Y2ggdGhlIGxvbmdlc3QgcHVuY3V0YXRvcgogICAgICAgICAgICAkbWF0Y2ggPSAkdGhpcy0+cHVuY3R1dGF0b3JzTFNNLT5tYXRjaCgkdGhpcywgJHRoaXMtPmluZGV4LCAkY2hhcikKICAgICAgICApIHsKICAgICAgICAgICAgLy9PcHRpb25hbCBjaGFpbmluZyBwdW5jdHV0YXRvciBjYW5ub3QgYXBwZWFyIGJlZm9yZSBhIG51bWJlciwgaW4gdGhpcwogICAgICAgICAgICAvL2Nhc2Ugb25seSB0aGUgcXVlc3Rpb24gbWFyayBtdXN0IGJlIGNvbnN1bWVkCiAgICAgICAgICAgIGlmICgkbWF0Y2hbMV0gPT09ICI/LiIgJiYKICAgICAgICAgICAgICAgICgkbmV4dENoYXIgPSAkdGhpcy0+Y2hhckF0KCR0aGlzLT5pbmRleCArICRtYXRjaFswXSkpICYmCiAgICAgICAgICAgICAgICAkbmV4dENoYXIgPj0gIjAiICYmICRuZXh0Q2hhciA8PSAiOSIKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkbWF0Y2ggPSBhcnJheSgxLCAiPyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAkbWF0Y2hbMF07CiAgICAgICAgICAgICR0aGlzLT5jb2x1bW4gKz0gJG1hdGNoWzBdOwogICAgICAgICAgICAkdG9rZW4gPSBuZXcgVG9rZW4oVG9rZW46OlRZUEVfUFVOQ1RVVEFUT1IsICRtYXRjaFsxXSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdG9rZW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogS2V5d29yZHMgYW5kIGlkZW50aWZpZXJzIHNjYW5uaW5nIG1ldGhvZAogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNjYW5LZXl3b3JkT3JJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICAvL0NvbnN1bWUgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgdW5pY29kZSBlc2NhcGUKICAgICAgICAvL3NlcXVlbmNlcyBvciB2YWxpZCBpZGVudGlmaWVyIHN0YXJ0cyAob25seSB0aGUgZmlyc3QgY2hhcmFjdGVyKSBvcgogICAgICAgIC8vcGFydHMKICAgICAgICAkYnVmZmVyID0gIiI7CiAgICAgICAgJGZuID0gImlzSWRlbnRpZmllclN0YXJ0IjsKICAgICAgICB3aGlsZSAoKCRjaGFyID0gJHRoaXMtPmNoYXJBdCgpKSAhPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoJHRoaXMtPiRmbigkY2hhcikpIHsKICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRzZXEgPSAkdGhpcy0+Y29uc3VtZVVuaWNvZGVFc2NhcGVTZXF1ZW5jZSgpKSB7CiAgICAgICAgICAgICAgICAvL1ZlcmlmeSB0aGF0IGlzIGEgdmFsaWQgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT4kZm4oJHNlcSkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJHNlcTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRmbiA9ICJpc0lkZW50aWZpZXJQYXJ0IjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9JZGVudGlmeSB0b2tlbiB0eXBlCiAgICAgICAgaWYgKCRidWZmZXIgPT09ICIiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0gZWxzZWlmICgkYnVmZmVyID09PSAibnVsbCIpIHsKICAgICAgICAgICAgJHR5cGUgPSBUb2tlbjo6VFlQRV9OVUxMX0xJVEVSQUw7CiAgICAgICAgfSBlbHNlaWYgKCRidWZmZXIgPT09ICJ0cnVlIiB8fCAkYnVmZmVyID09PSAiZmFsc2UiKSB7CiAgICAgICAgICAgICR0eXBlID0gVG9rZW46OlRZUEVfQk9PTEVBTl9MSVRFUkFMOwogICAgICAgIH0gZWxzZWlmIChpbl9hcnJheSgkYnVmZmVyLCAkdGhpcy0+a2V5d29yZHMpIHx8CiAgICAgICAgICAgIGluX2FycmF5KCRidWZmZXIsICR0aGlzLT5zdHJpY3RNb2RlS2V5d29yZHMpCiAgICAgICAgKSB7CiAgICAgICAgICAgICR0eXBlID0gVG9rZW46OlRZUEVfS0VZV09SRDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdHlwZSA9IFRva2VuOjpUWVBFX0lERU5USUZJRVI7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBuZXcgVG9rZW4oJHR5cGUsICRidWZmZXIpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIGFuIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVVbmljb2RlRXNjYXBlU2VxdWVuY2UoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+Y2hhckF0KCkgIT09ICJcXCIgfHwKICAgICAgICAgICAgJHRoaXMtPmNoYXJBdCgkdGhpcy0+aW5kZXggKyAxKSAhPT0gInUiCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkc3RhcnRJbmRleCA9ICR0aGlzLT5pbmRleDsKICAgICAgICAkc3RhcnRDb2x1bW4gPSAkdGhpcy0+Y29sdW1uOwogICAgICAgICR0aGlzLT5pbmRleCArPSAyOwogICAgICAgICR0aGlzLT5jb2x1bW4gKz0gMjsKICAgICAgICBpZiAoJHRoaXMtPmNoYXJBdCgpID09PSAieyIpIHsKICAgICAgICAgICAgLy9cdXtGRkZ9CiAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgICRjb2RlID0gJHRoaXMtPmNvbnN1bWVOdW1iZXJzKCJ4Iik7CiAgICAgICAgICAgIGlmICgkY29kZSAmJiAkdGhpcy0+Y2hhckF0KCkgIT09ICJ9IikgewogICAgICAgICAgICAgICAgJGNvZGUgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL1x1RkZGRgogICAgICAgICAgICAkY29kZSA9ICR0aGlzLT5jb25zdW1lTnVtYmVycygieCIsIDQpOwogICAgICAgICAgICBpZiAoJGNvZGUgJiYgc3RybGVuKCRjb2RlKSAhPT0gNCkgewogICAgICAgICAgICAgICAgJGNvZGUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vVW5jb25zdW1lIGV2ZXJ5dGhpbmcgaWYgdGhlIGZvcm1hdCBpcyBpbnZhbGlkCiAgICAgICAgaWYgKCRjb2RlID09PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCA9ICRzdGFydEluZGV4OwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uID0gJHN0YXJ0Q29sdW1uOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9SZXR1cm4gdGhlIGRlY29kZWQgY2hhcmFjdGVyCiAgICAgICAgcmV0dXJuIFV0aWxzOjp1bmljb2RlVG9VdGY4KGhleGRlYygkY29kZSkpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIGEgdmFsaWQgaWRlbnRpZmllciBzdGFydAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyIENoYXJhY3RlciB0byBjaGVjawogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzSWRlbnRpZmllclN0YXJ0KCRjaGFyKQogICAgewogICAgICAgIHJldHVybiAoJGNoYXIgPj0gImEiICYmICRjaGFyIDw9ICJ6IikgfHwKICAgICAgICAgICAgICAgKCRjaGFyID49ICJBIiAmJiAkY2hhciA8PSAiWiIpIHx8CiAgICAgICAgICAgICAgICRjaGFyID09PSAiXyIgfHwgJGNoYXIgPT09ICIkIiB8fAogICAgICAgICAgICAgICBwcmVnX21hdGNoKCR0aGlzLT5pZFN0YXJ0UmVnZXgsICRjaGFyKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyBhIHZhbGlkIGlkZW50aWZpZXIgcGFydAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyIENoYXJhY3RlciB0byBjaGVjawogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzSWRlbnRpZmllclBhcnQoJGNoYXIpCiAgICB7CiAgICAgICAgcmV0dXJuICgkY2hhciA+PSAiYSIgJiYgJGNoYXIgPD0gInoiKSB8fAogICAgICAgICAgICAgICAoJGNoYXIgPj0gIkEiICYmICRjaGFyIDw9ICJaIikgfHwKICAgICAgICAgICAgICAgKCRjaGFyID49ICIwIiAmJiAkY2hhciA8PSAiOSIpIHx8CiAgICAgICAgICAgICAgICRjaGFyID09PSAiXyIgfHwgJGNoYXIgPT09ICIkIiB8fAogICAgICAgICAgICAgICBwcmVnX21hdGNoKCR0aGlzLT5pZFBhcnRSZWdleCwgJGNoYXIpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEluY3JlYXNlcyBjb2x1bW5zIGFuZCBsaW5lcyBjb3VudCBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHN0cmluZwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRidWZmZXIgU3RyaW5nIHRvIGFuYWx5emUKICAgICAqIAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhZGp1c3RDb2x1bW5BbmRMaW5lKCRidWZmZXIpCiAgICB7CiAgICAgICAgJGxpbmVzID0gcHJlZ19zcGxpdCgkdGhpcy0+bGluZXNTcGxpdHRlciwgJGJ1ZmZlcik7CiAgICAgICAgJGxpbmVzQ291bnQgPSBjb3VudCgkbGluZXMpIC0gMTsKICAgICAgICAkdGhpcy0+bGluZSArPSAkbGluZXNDb3VudDsKICAgICAgICAkY29sdW1ucyA9IG1iX3N0cmxlbigkbGluZXNbJGxpbmVzQ291bnRdLCAiVVRGLTgiKTsKICAgICAgICBpZiAoJGxpbmVzQ291bnQpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbHVtbiA9ICRjb2x1bW5zOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5jb2x1bW4gKz0gJGNvbHVtbnM7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN1bWVzIGNoYXJhY3RlcnMgdW50aWwgb25lIG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXJzIGlzIGZvdW5kCiAgICAgKiAKICAgICAqIEBwYXJhbSBhcnJheXxMU00gJHN0b3BzICAgICAgICAgIENoYXJhY3RlcnMgdG8gc2VhcmNoCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICRoYW5kbGVFc2NhcGUgICBUcnVlIHRvIGhhbmRsZSBlc2NhcGluZwogICAgICogQHBhcmFtIGJvb2wgICAgICAkY29sbGVjdFN0b3AgICAgVHJ1ZSB0byBpbmNsdWRlIHRoZSBzdG9wIGNoYXJhY3RlcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lVW50aWwoCiAgICAgICAgJHN0b3BzLCAkaGFuZGxlRXNjYXBlID0gdHJ1ZSwgJGNvbGxlY3RTdG9wID0gdHJ1ZQogICAgKSB7CiAgICAgICAgJGlzTFNNID0gJHN0b3BzIGluc3RhbmNlb2YgTFNNOwogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICAkZXNjYXBlZCA9IGZhbHNlOwogICAgICAgIHdoaWxlICgoJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICRpbmNySW5kZXggPSAxOwogICAgICAgICAgICAkaXNTdG9wID0gZmFsc2U7CiAgICAgICAgICAgIGlmICgkaXNMU00pIHsKICAgICAgICAgICAgICAgICRtID0gJHN0b3BzLT5tYXRjaCgkdGhpcywgJHRoaXMtPmluZGV4LCAkY2hhcik7CiAgICAgICAgICAgICAgICBpZiAoJG0pIHsKICAgICAgICAgICAgICAgICAgICAkaXNTdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAkaW5jckluZGV4ID0gJG1bMF07CiAgICAgICAgICAgICAgICAgICAgJGNoYXIgPSAkbVsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRpc1N0b3AgPSBpbl9hcnJheSgkY2hhciwgJHN0b3BzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdmFsaWRTdG9wID0gJGlzU3RvcCAmJiAhJGVzY2FwZWQ7CiAgICAgICAgICAgIGlmICghJHZhbGlkU3RvcCB8fCAkY29sbGVjdFN0b3ApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAkaW5jckluZGV4OwogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHZhbGlkU3RvcCkgewogICAgICAgICAgICAgICAgaWYgKCEkY29sbGVjdFN0b3AgJiYgJGJ1ZmZlciA9PT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5hZGp1c3RDb2x1bW5BbmRMaW5lKCRidWZmZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRidWZmZXIsICRjaGFyKTsKICAgICAgICAgICAgfSBlbHNlaWYgKCEkZXNjYXBlZCAmJiAkY2hhciA9PT0gIlxcIiAmJiAkaGFuZGxlRXNjYXBlKSB7CiAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCnVzZSBQZWFzdFxRdWVyeTsKdXNlIFBlYXN0XFNlbGVjdG9yOwoKLyoqCiAqIFJvb3Qgbm9kZSBmb3Igc2NyaXB0cyBhbmQgbW9kdWxlcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHJvZ3JhbSBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJib2R5IiA9PiB0cnVlLAogICAgICAgICJzb3VyY2VUeXBlIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBTb3VyY2UgdHlwZSB0aGF0IGlzIG9uZSBvZiB0aGUgc291cmNlIHR5cGUgY29uc3RhbnRzIGluIHRoZSBQZWFzdCBjbGFzcwogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRzb3VyY2VUeXBlID0gXFBlYXN0XFBlYXN0OjpTT1VSQ0VfVFlQRV9TQ1JJUFQ7CiAgICAKICAgIC8qKgogICAgICogUHJvZ3JhbSdzIGJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnRbXXxNb2R1bGVEZWNsYXJhdGlvbltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keSA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc291cmNlIHR5cGUgdGhhdCBpcyBvbmUgb2YgdGhlIHNvdXJjZSB0eXBlIGNvbnN0YW50cyBpbiB0aGUKICAgICAqIFBlYXN0IGNsYXNzCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2VUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNvdXJjZVR5cGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc291cmNlIHR5cGUgdGhhdCBpcyBvbmUgb2YgdGhlIHNvdXJjZSB0eXBlIGNvbnN0YW50cyBpbiB0aGUKICAgICAqIFBlYXN0IGNsYXNzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHNvdXJjZVR5cGUgU291cmNlIHR5cGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlVHlwZSgkc291cmNlVHlwZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlVHlwZSA9ICRzb3VyY2VUeXBlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9ncmFtJ3MgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIFN0YXRlbWVudFtdfE1vZHVsZURlY2xhcmF0aW9uW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9ncmFtJ3MgYm9keQogICAgICogCiAgICAgKiBAcGFyYW0gU3RhdGVtZW50W118TW9kdWxlRGVjbGFyYXRpb25bXSAkYm9keSBQcm9ncmFtJ3MgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KCRib2R5KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRib2R5LCBhcnJheSgiU3RhdGVtZW50IiwgIk1vZHVsZURlY2xhcmF0aW9uIikpOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRmluZHMgbm9kZXMgbWF0Y2hpbmcgdGhlIGdpdmVuIHNlbGVjdG9yLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgJHNlbGVjdG9yICAgU2VsZWN0b3IKICAgICAqIEBwYXJhbSBhcnJheSAgICAgJG9wdGlvbnMgICAgT3B0aW9ucyBhcnJheS4gU2VlIFF1ZXJ5IGNsYXNzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50YXRpb24gZm9yIGF2YWlsYWJsZSBvcHRpb25zCiAgICAgKgogICAgICogQHJldHVybiBRdWVyeQogICAgICoKICAgICAqIEB0aHJvd3MgU2VsZWN0b3JcRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeSgkc2VsZWN0b3IsICRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkcXVlcnkgPSBuZXcgUXVlcnkoJHRoaXMsICRvcHRpb25zKTsKICAgICAgICByZXR1cm4gJHF1ZXJ5LT5maW5kKCRzZWxlY3Rvcik7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjbGFzcyBib2R5LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDbGFzc0JvZHkgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBDbGFzcyBtZXRob2RzCiAgICAgKiAKICAgICAqIEB2YXIgTWV0aG9kRGVmaW5pdGlvbltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keSA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBjbGFzcyBtZXRob2RzCiAgICAgKiAKICAgICAqIEByZXR1cm4gTWV0aG9kRGVmaW5pdGlvbltdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBjbGFzcyBtZXRob2RzCiAgICAgKiAKICAgICAqIEBwYXJhbSBNZXRob2REZWZpbml0aW9uW10gJGJvZHkgQ2xhc3MgbWV0aG9kcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KCRib2R5KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRib2R5LCAiTWV0aG9kRGVmaW5pdGlvbiIpOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBJbnRlcmZhY2UgdGhhdCBldmVyeSBleHByZXNzaW9uIG5vZGUgbXVzdCBpbXBsZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmludGVyZmFjZSBFeHByZXNzaW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgY2F0Y2ggY2xhdXNlIGluIGEgdHJ5LWNhdGNoIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ2F0Y2hDbGF1c2UgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAicGFyYW0iID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGNhdGNoIGNsYXVzZSBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJuIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHBhcmFtOwogICAgCiAgICAvKioKICAgICAqIFRoZSBib2R5IG9mIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHZhciBCbG9ja1N0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNhdGNoIGNsYXVzZSBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJhbSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wYXJhbTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjYXRjaCBjbGF1c2UgcGFyYW1ldGVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuICRwYXJhbSBDYXRjaCBjbGF1c2UgcGFyYW1ldGVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcmFtKCRwYXJhbSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkcGFyYW0sICJQYXR0ZXJuIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnBhcmFtID0gJHBhcmFtOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib2R5IG9mIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiBCbG9ja1N0YXRlbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGJvZHkgb2YgdGhlIGNhdGNoIGNsYXVzZQogICAgICogCiAgICAgKiBAcGFyYW0gQmxvY2tTdGF0ZW1lbnQgJGJvZHkgVGhlIGJsb2NrIG9mIGNvZGUgaW5zaWRlIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keShCbG9ja1N0YXRlbWVudCAkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogSW50ZXJmYWNlIHRoYXQgZXZlcnkgZGVjbGFyYXRpb24gbm9kZSBtdXN0IGltcGxlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIERlY2xhcmF0aW9uIGV4dGVuZHMgU3RhdGVtZW50CnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGNhc2UgaW4gYSBzd2l0Y2ggc3RhdGVtZW50LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBTd2l0Y2hDYXNlIGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInRlc3QiID0+IHRydWUsCiAgICAgICAgImNvbnNlcXVlbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGVzdCBleHByZXNzaW9uIHRoYXQgaXMgbnVsbCBpbiB0aGUgImRlZmF1bHQiIGNhc2UKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRlc3Q7CiAgICAKICAgIC8qKgogICAgICogQ29uc2VxdWVudCBzdGF0ZW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50W10gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uc2VxdWVudCA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGVzdCBleHByZXNzaW9uIHRoYXQgaXMgbnVsbCBpbiB0aGUgImRlZmF1bHQiIGNhc2UKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUZXN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRlc3Q7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgdGVzdCBleHByZXNzaW9uIHRoYXQgaXMgbnVsbCBpbiB0aGUgImRlZmF1bHQiIGNhc2UKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHRlc3QgVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlc3QoJHRlc3QpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHRlc3QsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnRlc3QgPSAkdGVzdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29uc2VxdWVudCBzdGF0ZW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50W10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnNlcXVlbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uc2VxdWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb25zZXF1ZW50IHN0YXRlbWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXSAkY29uc2VxdWVudCBDb25zZXF1ZW50IHN0YXRlbWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkY29uc2VxdWVudCwgIlN0YXRlbWVudCIpOwogICAgICAgICR0aGlzLT5jb25zZXF1ZW50ID0gJGNvbnNlcXVlbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGluIGltcG9ydCBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGltcG9ydCBhIGZyb20gIm1vZCIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSW1wb3J0RGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgTW9kdWxlRGVjbGFyYXRpb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJzcGVjaWZpZXJzIiA9PiB0cnVlLAogICAgICAgICJzb3VyY2UiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogSW1wb3J0IHNwZWNpZmllcnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHNwZWNpZmllcnMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIEltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHZhciBMaXRlcmFsIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNvdXJjZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbXBvcnQgc3BlY2lmaWVycyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTcGVjaWZpZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNwZWNpZmllcnM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0IHNwZWNpZmllcnMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5ICRzcGVjaWZpZXJzIEltcG9ydCBzcGVjaWZpZXJzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNwZWNpZmllcnMoJHNwZWNpZmllcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoCiAgICAgICAgICAgICRzcGVjaWZpZXJzLAogICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICJJbXBvcnRTcGVjaWZpZXIiLAogICAgICAgICAgICAgICAgIkltcG9ydERlZmF1bHRTcGVjaWZpZXIiLAogICAgICAgICAgICAgICAgIkltcG9ydE5hbWVzcGFjZVNwZWNpZmllciIKICAgICAgICAgICAgKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPnNwZWNpZmllcnMgPSAkc3BlY2lmaWVyczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcmV0dXJuIExpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2U7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcGFyYW0gTGl0ZXJhbCAkc291cmNlIEltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlKExpdGVyYWwgJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gJHNvdXJjZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBkZWNsYXJhdGlvbiBpbiBhIFZhcmlhYmxlRGVjbGFyYXRpb24gbm9kZS4KICogRm9yIGV4YW1wbGUgImE9MSIgaW46IHZhciBhID0gMQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBWYXJpYWJsZURlY2xhcmF0b3IgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiaWQiID0+IHRydWUsCiAgICAgICAgImluaXQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRGVjbGFyYXRpb24gaWRlbnRpZmllciBvciBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEB2YXIgUGF0dGVybiAKICAgICAqLwogICAgcHJvdGVjdGVkICRpZDsKICAgIAogICAgLyoqCiAgICAgKiBPcHRpb25hbCBpbml0aWFsaXplcgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5pdDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJhdGlvbiBpZGVudGlmaWVyIG9yIHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBkZWNsYXJhdGlvbiBpZGVudGlmaWVyIG9yIHBhdHRlcm4KICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm4gJGlkIERlY2xhcmF0aW9uIGlkZW50aWZpZXIgb3IgcGF0dGVybgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZChQYXR0ZXJuICRpZCkKICAgIHsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW5pdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pbml0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRpbml0IEluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluaXQoJGluaXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGluaXQsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmluaXQgPSAkaW5pdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEFic3RyYWN0IGNsYXNzIGZvciBmdW5jdGlvbnMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIEZ1bmN0aW9uXyBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJpZCIgPT4gdHJ1ZSwKICAgICAgICAicGFyYW1zIiA9PiB0cnVlLAogICAgICAgICJib2R5IiA9PiB0cnVlLAogICAgICAgICJnZW5lcmF0b3IiID0+IGZhbHNlLAogICAgICAgICJhc3luYyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRnVuY3Rpb24gbmFtZQogICAgICogCiAgICAgKiBAdmFyIElkZW50aWZpZXIgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaWQ7CiAgICAKICAgIC8qKgogICAgICogRnVuY3Rpb24gcGFyYW1ldGVycyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIFBhdHRlcm5bXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwYXJhbXMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIEZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHZhciBCbG9ja1N0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIEdlbmVyYXRvciBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBmdW5jdGlvbiBpcyBhIGdlbmVyYXRvcgogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZ2VuZXJhdG9yID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogQXN5bmMgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiBpdCBpcyBhbiBhc3luYyBmdW5jdGlvbgogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXN5bmMgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGZ1bmN0aW9uIG5hbWUKICAgICAqIAogICAgICogQHJldHVybiBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGZ1bmN0aW9uIG5hbWUKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGlkIEZ1bmN0aW9uIG5hbWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SWQoJGlkKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRpZCwgIklkZW50aWZpZXIiLCB0cnVlKTsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgZnVuY3Rpb24gcGFyYW1ldGVycyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFBhdHRlcm5bXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UGFyYW1zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhcmFtczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGZ1bmN0aW9uIHBhcmFtZXRlcnMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm5bXSAkcGFyYW1zIEZ1bmN0aW9uIHBhcmFtZXRlcnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UGFyYW1zKCRwYXJhbXMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJHBhcmFtcywgIlBhdHRlcm4iKTsKICAgICAgICAkdGhpcy0+cGFyYW1zID0gJHBhcmFtczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBmdW5jdGlvbiBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gQmxvY2tTdGF0ZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIEJsb2NrU3RhdGVtZW50ICRib2R5IEZ1bmN0aW9uIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keSgkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkYm9keSwgIkJsb2NrU3RhdGVtZW50Iik7CiAgICAgICAgJHRoaXMtPmJvZHkgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZ2VuZXJhdG9yIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGEgZ2VuZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0R2VuZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdlbmVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBnZW5lcmF0b3IgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgZnVuY3Rpb24gaXMgYSBnZW5lcmF0b3IKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGdlbmVyYXRvciBHZW5lcmF0b3IgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRHZW5lcmF0b3IoJGdlbmVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+Z2VuZXJhdG9yID0gKGJvb2wpICRnZW5lcmF0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFzeW5jIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gaXQgaXMgYW4gYXN5bmMgZnVuY3Rpb24KICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBc3luYygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hc3luYzsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhc3luYyBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIGl0IGlzIGFuIGFzeW5jIGZ1bmN0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRhc3luYyBBc3luYyBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFzeW5jKCRhc3luYykKICAgIHsKICAgICAgICAkdGhpcy0+YXN5bmMgPSAoYm9vbCkgJGFzeW5jOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhICJ2YXIiLCAiY29uc3QiIG9yICJsZXQiIGRlY2xhcmF0aW9uLgogKiBGb3IgZXhhbXBsZTogdmFyIGEgPSAxCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFZhcmlhYmxlRGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRGVjbGFyYXRpb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJkZWNsYXJhdGlvbnMiID0+IHRydWUsCiAgICAgICAgImtpbmQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvL0tpbmQgY29uc3RhbnRzCiAgICAvKioKICAgICAqICJ2YXIiIGtpbmQKICAgICAqLwogICAgY29uc3QgS0lORF9WQVIgPSAidmFyIjsKICAgIAogICAgLyoqCiAgICAgKiAibGV0IiBraW5kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfTEVUID0gImxldCI7CiAgICAKICAgIC8qKgogICAgICogImNvbnN0IiBraW5kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfQ09OU1QgPSAiY29uc3QiOwogICAgCiAgICAvKioKICAgICAqIERlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAdmFyIFZhcmlhYmxlRGVjbGFyYXRvcltdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGRlY2xhcmF0aW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogRGVjbGFyYXRpb24ga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2luZCA9IHNlbGY6OktJTkRfVkFSOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFZhcmlhYmxlRGVjbGFyYXRvcltdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWNsYXJhdGlvbnMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVjbGFyYXRpb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlY2xhcmF0aW9ucyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdG9yW10gJGRlY2xhcmF0aW9ucyBEZWNsYXJhdGlvbnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjbGFyYXRpb25zKCRkZWNsYXJhdGlvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGRlY2xhcmF0aW9ucywgIlZhcmlhYmxlRGVjbGFyYXRvciIpOwogICAgICAgICR0aGlzLT5kZWNsYXJhdGlvbnMgPSAkZGVjbGFyYXRpb25zOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJhdGlvbiBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlY2xhcmF0aW9uIGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgRGVjbGFyYXRpb24ga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgQmlnSW50IGxpdGVyYWwuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJpZ0ludExpdGVyYWwgZXh0ZW5kcyBMaXRlcmFsCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYmlnaW50IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGJpZ2ludDsKICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gZmxvYXQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAvL1ZhbHVlLCBSYXcgYW5kIEJpZ2ludCBhcmUgYWx3YXlzIHRoZSBzYW1lIHZhbHVlCiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHRoaXMtPnJhdyA9ICR0aGlzLT5iaWdpbnQgPSAkdmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJpZ2ludCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5iaWdpbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkYmlnaW50IFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJpZ2ludCgkYmlnaW50KQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2V0VmFsdWUoJGJpZ2ludCk7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzcGVjaWZpZXIgaW4gYW4gaW1wb3J0IGRlY2xhcmF0aW9uLgogKiBGb3IgZXhhbXBsZSAie2F9IiBpbjogaW1wb3J0IHthfSBmcm9tICJ0ZXN0IgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBJbXBvcnRTcGVjaWZpZXIgZXh0ZW5kcyBNb2R1bGVTcGVjaWZpZXIKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJpbXBvcnRlZCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBJbXBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRpbXBvcnRlZDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbXBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SW1wb3J0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW1wb3J0ZWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkaW1wb3J0ZWQgSW1wb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJbXBvcnRlZChJZGVudGlmaWVyICRpbXBvcnRlZCkKICAgIHsKICAgICAgICAkdGhpcy0+aW1wb3J0ZWQgPSAkaW1wb3J0ZWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBJbnRlcmZhY2UgdGhhdCBldmVyeSBzdGF0ZW1lbnQgbm9kZSBtdXN0IGltcGxlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KaW50ZXJmYWNlIFN0YXRlbWVudAp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBib29sZWFuIGxpdGVyYWwuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJvb2xlYW5MaXRlcmFsIGV4dGVuZHMgTGl0ZXJhbAp7CiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgIGlmICgkdmFsdWUgPT09ICJ0cnVlIikgewogICAgICAgICAgICAkdGhpcy0+dmFsdWUgPSB0cnVlOwogICAgICAgIH0gZWxzZWlmICgkdmFsdWUgPT09ICJmYWxzZSIpIHsKICAgICAgICAgICAgJHRoaXMtPnZhbHVlID0gZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnZhbHVlID0gKGJvb2wpICR2YWx1ZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnJhdyA9ICR0aGlzLT52YWx1ZSA/ICJ0cnVlIiA6ICJmYWxzZSI7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFzc2lnbm1lbnQgaW4gYSBiaW5kaW5nIGNvbnRleHQuCiAqIEZvciBleGFtcGxlICJhID0gYiIgaW46IHZhciB7YSA9IGJ9ID0gYwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBc3NpZ25tZW50UGF0dGVybiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBQYXR0ZXJuCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAicmlnaHQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAdmFyIFBhdHRlcm4KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJHJpZ2h0OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIFBhdHRlcm4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExlZnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGVmdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsZWZ0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm4gJGxlZnQgTGVmdCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoUGF0dGVybiAkbGVmdCkKICAgIHsKICAgICAgICAkdGhpcy0+bGVmdCA9ICRsZWZ0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgUmlnaHQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSaWdodChFeHByZXNzaW9uICRyaWdodCkKICAgIHsKICAgICAgICAkdGhpcy0+cmlnaHQgPSAkcmlnaHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdW5hcnkgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6ICFhCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFVuYXJ5RXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUsCiAgICAgICAgIm9wZXJhdG9yIiA9PiBmYWxzZSwKICAgICAgICAicHJlZml4IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3Mgb3BlcmF0b3IKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRvcGVyYXRvcjsKICAgIAogICAgLyoqCiAgICAgKiBQcmVmaXggZmxhZyB0aGF0IGlzIGFsd2F5cyB0cnVlIHNpbmNlIHRoZSBvcGVyYXRvciBwcmVjZWVkcyB0aGUgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJlZml4ID0gdHJ1ZTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBvcGVyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0b3I7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wZXJhdG9yKCRvcGVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSAkb3BlcmF0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByZWZpeCBmbGFnIHRoYXQgaXMgYWx3YXlzIHRydWUgc2luY2UgdGhlIG9wZXJhdG9yIHByZWNlZWRzCiAgICAgKiB0aGUgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcmVmaXgoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJlZml4OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBzaW5jZSB0aGUgcHJlZml4IGZsYWcgaXMgYWx3YXlzIHRydWUgZm9yCiAgICAgKiB1bmFyeSBleHByZXNzaW9ucwogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkcHJlZml4IFByZWZpeCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJlZml4KCRwcmVmaXgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgQXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoRXhwcmVzc2lvbiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHByb3BlcnR5IGluIGFuIG9iamVjdCBsaXRlcmFsLgogKiBGb3IgZXhhbXBsZSAiYiIgaW46IGEgPSB7YjogMX0KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHJvcGVydHkgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAia2V5IiA9PiB0cnVlLAogICAgICAgICJ2YWx1ZSIgPT4gdHJ1ZSwKICAgICAgICAia2luZCIgPT4gZmFsc2UsCiAgICAgICAgIm1ldGhvZCIgPT4gZmFsc2UsCiAgICAgICAgInNob3J0aGFuZCIgPT4gZmFsc2UsCiAgICAgICAgImNvbXB1dGVkIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLy9LaW5kIGNvbnN0YW50cwogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCBraW5kIGZvciBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfSU5JVCA9ICJpbml0IjsKICAgIAogICAgLyoqCiAgICAgKiBHZXR0ZXIgcHJvcGVydHkKICAgICAqLwogICAgY29uc3QgS0lORF9HRVQgPSAiZ2V0IjsKICAgIAogICAgLyoqCiAgICAgKiBTZXR0ZXIgcHJvcGVydHkKICAgICAqLwogICAgY29uc3QgS0lORF9TRVQgPSAic2V0IjsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSBrZXkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGtleTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdmFsdWU7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHZhciB0eXBlIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGtpbmQgPSBzZWxmOjpLSU5EX0lOSVQ7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkgbWV0aG9kIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5IGlzIGEgbWV0aG9kCiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRtZXRob2QgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eSBzaG9ydGhhbmQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgZGVjbGFyZWQKICAgICAqIHVzaW5nIGFuIGlkZW50aWZpZXIgYW5kIHdpdGhvdXQgYSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2hvcnRoYW5kID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogUHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMgZGVjbGFyZWQgdXNpbmcKICAgICAqIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21wdXRlZCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IGtleQogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5rZXk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkga2V5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRrZXkgUHJvcGVydHkga2V5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtleShFeHByZXNzaW9uICRrZXkpCiAgICB7CiAgICAgICAgJHRoaXMtPmtleSA9ICRrZXk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHZhbHVlIFByb3BlcnR5IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkdmFsdWUsICJFeHByZXNzaW9uIik7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IGtpbmQgdGhhdCBpcyBvbmUgb2YgdGhlIGtpbmQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtpbmQgUHJvcGVydHkga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByb3BlcnR5IG1ldGhvZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhCiAgICAgKiBtZXRob2QKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNZXRob2QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bWV0aG9kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHByb3BlcnR5IG1ldGhvZCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhIG1ldGhvZAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkbWV0aG9kIE1ldGhvZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE1ldGhvZCgkbWV0aG9kKQogICAgewogICAgICAgICR0aGlzLT5tZXRob2QgPSAoYm9vbCkgJG1ldGhvZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgc2hvcnRoYW5kIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5CiAgICAgKiBpcyBkZWNsYXJlZCB1c2luZyBhbiBpZGVudGlmaWVyIGFuZCB3aXRob3V0IGEgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBib29sIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2hvcnRoYW5kKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNob3J0aGFuZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0eSBzaG9ydGhhbmQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkKICAgICAqIGlzIGRlY2xhcmVkIHVzaW5nIGFuIGlkZW50aWZpZXIgYW5kIHdpdGhvdXQgYSB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc2hvcnRoYW5kIFByb3BlcnR5IHNob3J0aGFuZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNob3J0aGFuZCgkc2hvcnRoYW5kKQogICAgewogICAgICAgICR0aGlzLT5zaG9ydGhhbmQgPSAoYm9vbCkgJHNob3J0aGFuZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMKICAgICAqIGRlY2xhcmVkIHVzaW5nIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcHV0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcHV0ZWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgcHJvcGVydHkgaXMKICAgICAqIGRlY2xhcmVkIHVzaW5nIHRoZSBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRjb21wdXRlZCBQcm9wZXJ0eSBjb21wdXRlZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbXB1dGVkKCRjb21wdXRlZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcHV0ZWQgPSAoYm9vbCkgJGNvbXB1dGVkOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGNoYWluIGVsZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIENoYWluRWxlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJvcHRpb25hbCIgPT4gZmFsc2UKICAgICk7CgogICAgLyoqCiAgICAgKiBPcHRpb25hbCBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgbm9kZSBpcyBpbiB0aGUgb3B0aW9uYWwKICAgICAqIHBhcnQgb2YgYSBjaGFpbiBleHByZXNzaW9uCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3B0aW9uYWwgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbmFsIGZsYWcgdGhhdCBpcyB0cnVlIGlmIHRoZSBub2RlIGlzIGluCiAgICAgKiB0aGUgb3B0aW9uYWwgcGFydCBvZiBhIGNoYWluIGV4cHJlc3Npb24KICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbmFsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wdGlvbmFsOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3B0aW9uYWwgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIG5vZGUgaXMgaW4KICAgICAqIHRoZSBvcHRpb25hbCBwYXJ0IG9mIGEgY2hhaW4gZXhwcmVzc2lvbgogICAgICoKICAgICAqIEBwYXJhbSBib29sICRvcHRpb25hbCBPcHRpb25hbCBmbGFnCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uYWwoJG9wdGlvbmFsKQogICAgewogICAgICAgICR0aGlzLT5vcHRpb25hbCA9IChib29sKSAkb3B0aW9uYWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSAiY29udGludWUiIHN0YXRlbWVudCBpbnNpZGUgbG9vcHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENvbnRpbnVlU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImxhYmVsIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBvcHRpb25hbCBsYWJlbCBvZiB0aGUgY29udGludWUgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRsYWJlbDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBub2RlJ3MgbGFiZWwKICAgICAqIAogICAgICogQHJldHVybiBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMYWJlbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sYWJlbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBub2RlJ3MgbGFiZWwKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGxhYmVsIE5vZGUncyBsYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYWJlbCgkbGFiZWwpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGxhYmVsLCAiSWRlbnRpZmllciIsIHRydWUpOwogICAgICAgICR0aGlzLT5sYWJlbCA9ICRsYWJlbDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjaGFpbiBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogdGVzdD8udGVzdD8uKCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ2hhaW5FeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZXhwcmVzc2lvbjsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHByZXNzaW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIENvbW1vbiBpbnRlcmZhY2UgZm9yIGZ1bmN0aW9uIGltcG9ydCBhbmQgZXhwb3J0IG5vZGVzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgTW9kdWxlRGVjbGFyYXRpb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIG9iamVjdCBsaXRlcmFsLgogKiBGb3IgZXhhbXBsZToge2E6IDEsIGI6IDIsIGM6IDN9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIE9iamVjdEV4cHJlc3Npb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInByb3BlcnRpZXMiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBQcm9wZXJ0eVtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgb2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiBQcm9wZXJ0eVtdIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydGllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9wZXJ0aWVzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgb2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHBhcmFtIFByb3BlcnR5W10gJHByb3BlcnRpZXMgT2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvcGVydGllcygkcHJvcGVydGllcykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcHJvcGVydGllcywgYXJyYXkoIlByb3BlcnR5IiwgIlNwcmVhZEVsZW1lbnQiKSk7CiAgICAgICAgJHRoaXMtPnByb3BlcnRpZXMgPSAkcHJvcGVydGllczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gYXdhaXQgZXhwcmVzc2lvbi4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQXdhaXRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFyZ3VtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb24ncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgQXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoRXhwcmVzc2lvbiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHByb3BlcnR5IGluIGFuIG9iamVjdCBiaW5kaW5nIHBhdHRlcm4uCiAqIEZvciBleGFtcGxlICJhIiBpbjogdmFyIHthfSA9IGIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQXNzaWdubWVudFByb3BlcnR5IGV4dGVuZHMgUHJvcGVydHkKewogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB0eXBlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkKICAgIHsKICAgICAgICByZXR1cm4gIlByb3BlcnR5IjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcm9wZXJ5IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuICR2YWx1ZSBQcm9wZXJ0eSB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHZhbHVlLCAiUGF0dGVybiIpOwogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAka2luZCBQcm9wZXJ0eSBraW5kCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0S2luZCgka2luZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkgbWV0aG9kIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHByb3BlcnR5IGlzIGEgbWV0aG9kCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRtZXRob2QgTWV0aG9kIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRNZXRob2QoJG1ldGhvZCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlIHJldHVybiBzdGF0ZW1lbnQgaW5zaWRlIGZ1bmN0aW9ucy4KICogRm9yIGV4YW1wbGU6IHJldHVybiBhICsgMQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBSZXR1cm5TdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3B0aW9uYWwgZXhwcmVzc2lvbiBhZnRlciB0aGUgcmV0dXJuIGtleXdvcmQKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gYWZ0ZXIgdGhlIHJldHVybiBrZXl3b3JkCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbiBhZnRlciB0aGUgcmV0dXJuIGtleXdvcmQKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGFyZ3VtZW50IFRoZSBleHByZXNzaW9uIHRvIHJldHVybgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudCgkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGFyZ3VtZW50LCAiRXhwcmVzc2lvbiIsIHRydWUpOwogICAgICAgICR0aGlzLT5hcmd1bWVudCA9ICRhcmd1bWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBtZXRob2QgZGVjbGFyYXRpb24gaW4gY2xhc3NlcyBhbmQgb2JqZWN0IGxpdGVyYWxzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBNZXRob2REZWZpbml0aW9uIGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImtleSIgPT4gdHJ1ZSwKICAgICAgICAidmFsdWUiID0+IHRydWUsCiAgICAgICAgImtpbmQiID0+IGZhbHNlLAogICAgICAgICJjb21wdXRlZCIgPT4gZmFsc2UsCiAgICAgICAgInN0YXRpYyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8vS2luZCBjb25zdGFudHMKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgbWV0aG9kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfQ09OU1RSVUNUT1IgPSAiY29uc3RydWN0b3IiOwogICAgCiAgICAvKioKICAgICAqIFN0YW5kYXJkIG1ldGhvZAogICAgICovCiAgICBjb25zdCBLSU5EX01FVEhPRCA9ICJtZXRob2QiOwogICAgCiAgICAvKioKICAgICAqIEdldHRlciBtZXRob2QKICAgICAqLwogICAgY29uc3QgS0lORF9HRVQgPSAiZ2V0IjsKICAgIAogICAgLyoqCiAgICAgKiBTZXR0ZXIgbWV0aG9kCiAgICAgKi8KICAgIGNvbnN0IEtJTkRfU0VUID0gInNldCI7CiAgICAKICAgIC8qKgogICAgICogTWV0aG9kJ3Mga2V5CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRrZXk7CiAgICAKICAgIC8qKgogICAgICogTWV0aG9kJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBGdW5jdGlvbkV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdmFsdWU7CiAgICAKICAgIC8qKgogICAgICogTWV0aG9kJ3Mga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAka2luZCA9IHNlbGY6OktJTkRfTUVUSE9EOwogICAgCiAgICAvKioKICAgICAqIENvbXB1dGVkIGZsYWcgdGhhdCBpcyB0cnVlIGlmIG1ldGhvZCdzIGtleSBpcyBkZWNsYXJlZCB1c2luZyBzcXVhcmUKICAgICAqIGJyYWNrZXRzIHN5bnRheAogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tcHV0ZWQgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBTdGF0aWMgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIG1ldGhvZCBpcyBzdGF0aWMKICAgICAqIAogICAgICogQHZhciBib29sIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN0YXRpYyA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCdzIGtleQogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEtleSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5rZXk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWV0aG9kJ3Mga2V5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRrZXkgTWV0aG9kJ3Mga2V5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEtleShFeHByZXNzaW9uICRrZXkpCiAgICB7CiAgICAgICAgJHRoaXMtPmtleSA9ICRrZXk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCdzIHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gRnVuY3Rpb25FeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBtZXRob2QncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gRnVuY3Rpb25FeHByZXNzaW9uICR2YWx1ZSBNZXRob2QncyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZShGdW5jdGlvbkV4cHJlc3Npb24gJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT52YWx1ZSA9ICR2YWx1ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWV0aG9kJ3Mga2luZCB0aGF0IGlzIG9uZSBvZiB0aGUga2luZCBjb25zdGFudHMKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEtpbmQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+a2luZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBtZXRob2QncyBraW5kIHRoYXQgaXMgb25lIG9mIHRoZSBraW5kIGNvbnN0YW50cwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRraW5kIE1ldGhvZCdzIGtpbmQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0S2luZCgka2luZCkKICAgIHsKICAgICAgICAkdGhpcy0+a2luZCA9ICRraW5kOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiBtZXRob2QncyBrZXkgaXMgZGVjbGFyZWQgdXNpbmcKICAgICAqIHNxdWFyZSBicmFja2V0cyBzeW50YXgKICAgICAqIAogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb21wdXRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wdXRlZDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb21wdXRlZCBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiBtZXRob2QncyBrZXkgaXMgZGVjbGFyZWQgdXNpbmcKICAgICAqIHNxdWFyZSBicmFja2V0cyBzeW50YXgKICAgICAqIAogICAgICogQHBhcmFtIHR5cGUgJGNvbXB1dGVkIENvbXB1dGVkIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29tcHV0ZWQoJGNvbXB1dGVkKQogICAgewogICAgICAgICR0aGlzLT5jb21wdXRlZCA9IChib29sKSAkY29tcHV0ZWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRpYyBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgbWV0aG9kIGlzIHN0YXRpYwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN0YXRpYygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT57InN0YXRpYyJ9OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0YXRpYyBmbGFnIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgbWV0aG9kIGlzIHN0YXRpYwogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkc3RhdGljIFN0YXRpYyBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN0YXRpYygkc3RhdGljKQogICAgewogICAgICAgICR0aGlzLT57InN0YXRpYyJ9ID0gKGJvb2wpICRzdGF0aWM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgIm5ldyIgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IG5ldyB0ZXN0KCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTmV3RXhwcmVzc2lvbiBleHRlbmRzIENhbGxFeHByZXNzaW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQWJzdHJhY3QgY2xhc3MgdGhhdCBleHBvcnQgYW5kIGltcG9ydCBzcGVjaWZpZXJzIG5vZGVzIG11c3QgZXh0ZW5kLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIE1vZHVsZVNwZWNpZmllciBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJsb2NhbCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBMb2NhbCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRsb2NhbDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYWwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9jYWw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9jYWwgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkbG9jYWwgTG9jYWwgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMb2NhbChJZGVudGlmaWVyICRsb2NhbCkKICAgIHsKICAgICAgICAkdGhpcy0+bG9jYWwgPSAkbG9jYWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSByZXN0IGVsZW1lbnQgaW4gYXJyYXkgYmluZGluZyBwYXRlcm5zIG9yIGZ1bmN0aW9uCiAqIHBhcmFtZXRlcnMuCiAqIEZvciBleGFtcGxlICIuLi5yZXN0IiBpbjogW2EsIC4uLnJlc3RdID0gYgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBSZXN0RWxlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBQYXR0ZXJuCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIG5vZGUncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIHR5cGUgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gUGF0dGVybgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEBwYXJhbSBQYXR0ZXJuICRhcmd1bWVudCBOb2RlJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoUGF0dGVybiAkYXJndW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFyZ3VtZW50ID0gJGFyZ3VtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHdpdGggc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogd2l0aCAodGVzdCkge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgV2l0aFN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJvYmplY3QiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIHN0YXRlbWVudCBzdWJqZWN0CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRvYmplY3Q7CiAgICAKICAgIC8qKgogICAgICogVGhlIHN0YXRlbWVudCBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgdHlwZSAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCBzdWJqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T2JqZWN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9iamVjdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGF0ZW1lbnQgc3ViamVjdAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkb2JqZWN0IFN0YXRlbWVudCBzdWJqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9iamVjdChFeHByZXNzaW9uICRvYmplY3QpCiAgICB7CiAgICAgICAgJHRoaXMtPm9iamVjdCA9ICRvYmplY3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0YXRlbWVudCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgU3RhdGVtZW50IGJvZHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keShTdGF0ZW1lbnQgJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmJvZHkgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gb2JqZWN0IGJpbmRpbmcgcGF0dGVybi4KICogRm9yIGV4YW1wbGU6IHZhciB7YSwgYiwgY30gPSBkCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIE9iamVjdFBhdHRlcm4gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInByb3BlcnRpZXMiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBQcm9wZXJ0eVtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgb2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiBQcm9wZXJ0eVtdIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydGllcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9wZXJ0aWVzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgb2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHBhcmFtIFByb3BlcnR5W10gJHByb3BlcnRpZXMgT2JqZWN0IHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvcGVydGllcygkcHJvcGVydGllcykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcHJvcGVydGllcywgYXJyYXkoIkFzc2lnbm1lbnRQcm9wZXJ0eSIsICJSZXN0RWxlbWVudCIpKTsKICAgICAgICAkdGhpcy0+cHJvcGVydGllcyA9ICRwcm9wZXJ0aWVzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHdoaWxlIGxvb3AuCiAqIEZvciBleGFtcGxlOiB3aGlsZSAodGVzdCkge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgV2hpbGVTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidGVzdCIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbG9vcCBjb25kaXRpb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRlc3Q7CiAgICAKICAgIC8qKgogICAgICogVGhlIGxvb3AgYm9keQogICAgICogCiAgICAgKiBAdmFyIFN0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR0ZXN0IExvb3AKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvb3AgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuIFN0YXRlbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxvb3AgYm9keQogICAgICogCiAgICAgKiBAcGFyYW0gU3RhdGVtZW50ICRib2R5IExvb3AgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KFN0YXRlbWVudCAkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGZ1bmN0aW9uIGV4cHJlc3Npb24KICogRm9yIGV4YW1wbGU6IHZhciB0ZXN0ID0gZnVuY3Rpb24gKCkge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRnVuY3Rpb25FeHByZXNzaW9uIGV4dGVuZHMgRnVuY3Rpb25fIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBjb25kaXRpb25hbCBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogdGVzdCgpID8gb2soKSA6IGZhaWwoKQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDb25kaXRpb25hbEV4cHJlc3Npb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInRlc3QiID0+IHRydWUsCiAgICAgICAgImNvbnNlcXVlbnQiID0+IHRydWUsCiAgICAgICAgImFsdGVybmF0ZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgdGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR0ZXN0OwogICAgCiAgICAvKioKICAgICAqIFRoZSBjb25zZXF1ZW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNvbnNlcXVlbnQ7CiAgICAKICAgIC8qKgogICAgICogVGhlIGFsdGVybmF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRhbHRlcm5hdGU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkdGVzdCBUZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnNlcXVlbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbnNlcXVlbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29uc2VxdWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb25zZXF1ZW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGNvbnNlcXVlbnQgQ29uc2VxdWVudCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbnNlcXVlbnQoRXhwcmVzc2lvbiAkY29uc2VxdWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29uc2VxdWVudCA9ICRjb25zZXF1ZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhbHRlcm5hdGUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsdGVybmF0ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hbHRlcm5hdGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgYWx0ZXJuYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGFsdGVybmF0ZSBBbHRlcm5hdGUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBbHRlcm5hdGUoRXhwcmVzc2lvbiAkYWx0ZXJuYXRlKQogICAgewogICAgICAgICR0aGlzLT5hbHRlcm5hdGUgPSAkYWx0ZXJuYXRlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgc3ByZWFkIGVsZW1lbnQgaW4gYXJyYXkgbGl0ZXJhbHMgb3IgZnVuY3Rpb24KICogY2FsbHMuCiAqIEZvciBleGFtcGxlICIuLi5wYXJhbXMiIGluOiB0ZXN0KC4uLnBhcmFtcykKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU3ByZWFkRWxlbWVudCBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhcmd1bWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbm9kZSdzIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEB2YXIgdHlwZSAKICAgICAqLwogICAgcHJvdGVjdGVkICRhcmd1bWVudDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBub2RlJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hcmd1bWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBub2RlJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGFyZ3VtZW50IE5vZGUncyBhcmd1bWVudAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBcmd1bWVudChFeHByZXNzaW9uICRhcmd1bWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXJndW1lbnQgPSAkYXJndW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFycmF5IGxpdGVyYWwuCiAqIEZvciBleGFtcGxlOiBbYSwgYiwgY10KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQXJyYXlFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJlbGVtZW50cyIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBBcnJheSBlbGVtZW50cwogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10KICAgICAqLwogICAgcHJvdGVjdGVkICRlbGVtZW50cyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhcnJheSBlbGVtZW50cwogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVsZW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVsZW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10gJGVsZW1lbnRzIEFycmF5IGVsZW1lbnRzIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFbGVtZW50cygkZWxlbWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoCiAgICAgICAgICAgICRlbGVtZW50cywKICAgICAgICAgICAgYXJyYXkoIkV4cHJlc3Npb24iLCAiU3ByZWFkRWxlbWVudCIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZWxlbWVudHMgPSAkZWxlbWVudHM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbWV0YSBwcm9wZXJ0eS4KICogRm9yIGV4YW1wbGU6IG5ldy50YXJnZXQKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTWV0YVByb3BlcnR5IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJtZXRhIiA9PiBmYWxzZSwKICAgICAgICAicHJvcGVydHkiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFN1YmplY3QKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbWV0YTsKICAgIAogICAgLyoqCiAgICAgKiBQcm9wZXJ0eQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0eTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdWJqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNZXRhKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm1ldGE7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3ViamVjdAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXRhIFN1YmplY3QKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TWV0YSgkbWV0YSkKICAgIHsKICAgICAgICAkdGhpcy0+bWV0YSA9ICRtZXRhOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcHJvcGVydHkKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkcHJvcGVydHkgUHJvcGVydHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UHJvcGVydHkoJHByb3BlcnR5KQogICAgewogICAgICAgICR0aGlzLT5wcm9wZXJ0eSA9ICRwcm9wZXJ0eTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBkZWJ1Z2dlciBzdGF0ZW1lbnQuCiAqIEZvciBleGFtcGxlOiBkZWJ1Z2dlcjsKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRGVidWdnZXJTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGNvbW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENvbW1lbnQgZXh0ZW5kcyBOb2RlCnsKICAgIC8vQ29tbWVudCBraW5kIGNvbnN0YW50cwogICAgLyoqCiAgICAgKiBJbmxpbmUgY29tbWVudAogICAgICovCiAgICBjb25zdCBLSU5EX0lOTElORSA9ICJpbmxpbmUiOwogICAgCiAgICAvKioKICAgICAqIE11bHRpbGluZSBjb21tZW50CiAgICAgKi8KICAgIGNvbnN0IEtJTkRfTVVMVElMSU5FID0gIm11bHRpbGluZSI7CiAgICAKICAgIC8qKgogICAgICogSHRtbCBvcGVuIGNvbW1lbnQKICAgICAqLwogICAgY29uc3QgS0lORF9IVE1MX09QRU4gPSAiaHRtbC1vcGVuIjsKICAgIAogICAgLyoqCiAgICAgKiBIdG1sIGNsb3NlIGNvbW1lbnQKICAgICAqLwogICAgY29uc3QgS0lORF9IVE1MX0NMT1NFID0gImh0bWwtY2xvc2UiOwogICAgCiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImtpbmQiID0+IGZhbHNlLAogICAgICAgICJ0ZXh0IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgY29tbWVudCBraW5kCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGtpbmQ7CiAgICAKICAgIC8qKgogICAgICogVGhlIGNvbW1lbnQgdGV4dAogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICR0ZXh0OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1lbnQga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0S2luZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5raW5kOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbW1lbnQga2luZAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRraW5kIENvbW1lbnQga2luZAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRLaW5kKCRraW5kKQogICAgewogICAgICAgICR0aGlzLT5raW5kID0gJGtpbmQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1lbnQgdGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXh0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbW1lbnQgdGV4dAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0IENvbW1lbnQgdGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUZXh0KCR0ZXh0KQogICAgewogICAgICAgICR0aGlzLT50ZXh0ID0gJHRleHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbW1lbnQgcmF3IHRleHQKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhd1RleHQoKQogICAgewogICAgICAgICR0ZXh0ID0gJHRoaXMtPmdldFRleHQoKTsKICAgICAgICAka2luZCA9ICR0aGlzLT5nZXRLaW5kKCk7CiAgICAgICAgCiAgICAgICAgaWYgKCRraW5kID09PSBzZWxmOjpLSU5EX0lOTElORSkgewogICAgICAgICAgICByZXR1cm4gIi8vIiAuICR0ZXh0OwogICAgICAgIH0gZWxzZWlmICgka2luZCA9PT0gc2VsZjo6S0lORF9IVE1MX09QRU4pIHsKICAgICAgICAgICAgcmV0dXJuICI8IS0tIiAuICR0ZXh0OwogICAgICAgIH0gZWxzZWlmICgka2luZCA9PT0gc2VsZjo6S0lORF9IVE1MX0NMT1NFKSB7CiAgICAgICAgICAgIHJldHVybiAiLS0+IiAuICR0ZXh0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiLyoiIC4gJHRleHQgLiAiKi8iOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb21tZW50IHJhdyB0ZXh0CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJhd1RleHQgQ29tbWVudCByYXcgdGV4dAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSYXdUZXh0KCRyYXdUZXh0KQogICAgewogICAgICAgICRzdGFydCA9IHN1YnN0cigkcmF3VGV4dCwgMCwgMik7CiAgICAgICAgaWYgKCRzdGFydCA9PT0gIi8vIikgewogICAgICAgICAgICAka2luZCA9IHNlbGY6OktJTkRfSU5MSU5FOwogICAgICAgICAgICAkdGV4dCA9IHN1YnN0cigkcmF3VGV4dCwgMik7CiAgICAgICAgfSBlbHNlaWYgKCRzdGFydCA9PT0gIi8qIiAmJiBzdWJzdHIoJHJhd1RleHQsIC0yKSA9PT0gIiovIikgewogICAgICAgICAgICAka2luZCA9IHNlbGY6OktJTkRfTVVMVElMSU5FOwogICAgICAgICAgICAkdGV4dCA9IHN1YnN0cigkcmF3VGV4dCwgMiwgLTIpOwogICAgICAgIH0gZWxzZWlmICgkc3RhcnQgPT09ICI8ISIgJiYgc3Vic3RyKCRyYXdUZXh0LCAyLCAyKSA9PT0gIi0tIikgewogICAgICAgICAgICAka2luZCA9IHNlbGY6OktJTkRfSFRNTF9PUEVOOwogICAgICAgICAgICAkdGV4dCA9IHN1YnN0cigkcmF3VGV4dCwgNCk7CiAgICAgICAgfSBlbHNlaWYgKCRzdGFydCA9PT0gIi0tIiAmJiBzdWJzdHIoJHJhd1RleHQsIDIsIDEpID09PSAiPiIpIHsKICAgICAgICAgICAgJGtpbmQgPSBzZWxmOjpLSU5EX0hUTUxfQ0xPU0U7CiAgICAgICAgICAgICR0ZXh0ID0gc3Vic3RyKCRyYXdUZXh0LCAzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBjb21tZW50Iik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+c2V0S2luZCgka2luZCktPnNldFRleHQoJHRleHQpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbGVhZGluZyBjb21tZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gQ29tbWVudHNbXSAkY29tbWVudHMgQ29tbWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGVhZGluZ0NvbW1lbnRzKCRjb21tZW50cykKICAgIHsKICAgICAgICAvL0NvbW1lbnRzIGNhbm5vdCBiZSBhdHRhY2hlZCB0byBvdGhlciBjb21tZW50cwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRyYWlsaW5nIGNvbW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBDb21tZW50c1tdICRjb21tZW50cyBDb21tZW50cyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUcmFpbGluZ0NvbW1lbnRzKCRjb21tZW50cykKICAgIHsKICAgICAgICAvL0NvbW1lbnRzIGNhbm5vdCBiZSBhdHRhY2hlZCB0byBvdGhlciBjb21tZW50cwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2VyaWFsaXphYmxlIHZlcnNpb24gb2YgdGhlIG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24ganNvblNlcmlhbGl6ZSgpCiAgICB7CiAgICAgICAgJHJldCA9IHBhcmVudDo6anNvblNlcmlhbGl6ZSgpOwogICAgICAgIHVuc2V0KCRyZXRbImxlYWRpbmdDb21tZW50cyJdKTsKICAgICAgICB1bnNldCgkcmV0WyJ0cmFpbGluZ0NvbW1lbnRzIl0pOwogICAgICAgIHJldHVybiAkcmV0OwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGlkZW50aWZpZXIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIElkZW50aWZpZXIgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbiwgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm5hbWUiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBpZGVudGlmaWVyJ3MgbmFtZQogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaWRlbnRpZmllcidzIG5hbWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpZGVudGlmaWVyJ3MgbmFtZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBuYW1lIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXROYW1lKCRuYW1lKQogICAgewogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdGVtcGxhdGUgbGl0ZXJhbC4KICogRm9yIGV4YW1wbGU6IGB0aGlzIGlzIGEgJHt0ZXN0KCl9IHRlbXBsYXRlYAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBUZW1wbGF0ZUxpdGVyYWwgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInBhcnRzIiA9PiB0cnVlLAogICAgICAgICJxdWFzaXMiID0+IGZhbHNlLAogICAgICAgICJleHByZXNzaW9ucyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2YgcXVhc2lzIHRoYXQgYXJlIHRoZSBsaXRlcmFsIHBhcnRzIG9mIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAdmFyIFRlbXBsYXRlRWxlbWVudFtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHF1YXNpcyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2YgZXhwcmVzc2lvbnMgaW5zaWRlIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb25bXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgcXVhc2lzIHRoYXQgYXJlIHRoZSBsaXRlcmFsIHBhcnRzIG9mIHRoZSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRlbXBsYXRlRWxlbWVudFtdIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UXVhc2lzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnF1YXNpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBxdWFzaXMgdGhhdCBhcmUgdGhlIGxpdGVyYWwgcGFydHMgb2YgdGhlIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEBwYXJhbSBUZW1wbGF0ZUVsZW1lbnRbXSAkcXVhc2lzIFF1YXNpcwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRRdWFzaXMoJHF1YXNpcykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcXVhc2lzLCAiVGVtcGxhdGVFbGVtZW50Iik7CiAgICAgICAgJHRoaXMtPnF1YXNpcyA9ICRxdWFzaXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIGV4cHJlc3Npb25zIGluc2lkZSB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4cHJlc3Npb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFycmF5IG9mIGV4cHJlc3Npb25zIGluc2lkZSB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXSAkZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwcmVzc2lvbnMoJGV4cHJlc3Npb25zKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRleHByZXNzaW9ucywgIkV4cHJlc3Npb24iKTsKICAgICAgICAkdGhpcy0+ZXhwcmVzc2lvbnMgPSAkZXhwcmVzc2lvbnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHRlbXBsYXRlIHBhcnRzIChxdWFzaXMgYW5kIGV4cHJlc3Npb25zKQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXJ0cygpCiAgICB7CiAgICAgICAgLy8gSXQgbXVzdCBiZSBhIGxpc3Qgb2YgcXVhc2lzIGFuZCBleHByZXNzaW9ucyBhbHRlcm5hdGVkCiAgICAgICAgJHBhcnRzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+cXVhc2lzIGFzICRrID0+ICR2YWwpIHsKICAgICAgICAgICAgJHBhcnRzW10gPSAkdmFsOwogICAgICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmV4cHJlc3Npb25zWyRrXSkpIHsKICAgICAgICAgICAgICAgICRwYXJ0c1tdID0gJHRoaXMtPmV4cHJlc3Npb25zWyRrXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFycmF5IG9mIHRoZSB0ZW1wbGF0ZSBwYXJ0cyAocXVhc2lzIGFuZCBleHByZXNzaW9ucykKICAgICAqIAogICAgICogQHBhcmFtIGFycmF5IFRlbXBsYXRlIHBhcnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhcnRzKCRwYXJ0cykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkcGFydHMsIGFycmF5KCJFeHByZXNzaW9uIiwgIlRlbXBsYXRlRWxlbWVudCIpKTsKICAgICAgICAkcXVhc2lzID0gJGV4cHJlc3Npb25zID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkcGFydHMgYXMgJHBhcnQpIHsKICAgICAgICAgICAgaWYgKCRwYXJ0IGluc3RhbmNlb2YgVGVtcGxhdGVFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAkcXVhc2lzW10gPSAkcGFydDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRleHByZXNzaW9uc1tdID0gJHBhcnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRRdWFzaXMoJHF1YXNpcyktPnNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNlcmlhbGl6YWJsZSB2ZXJzaW9uIG9mIHRoZSBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGpzb25TZXJpYWxpemUoKQogICAgewogICAgICAgICRyZXQgPSBwYXJlbnQ6Ompzb25TZXJpYWxpemUoKTsKICAgICAgICB1bnNldCgkcmV0WyJwYXJ0cyJdKTsKICAgICAgICByZXR1cm4gJHJldDsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogSW50ZXJmYWNlIHRoYXQgZXZlcnkgcGF0dGVybiBub2RlIG11c3QgaW1wbGVtZW50LgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwppbnRlcmZhY2UgUGF0dGVybgp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEFic3RyYWN0IGNsYXNzIGZvciBjbGFzc2VzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwphYnN0cmFjdCBjbGFzcyBDbGFzc18gZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiaWQiID0+IHRydWUsCiAgICAgICAgInN1cGVyQ2xhc3MiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgbmFtZQogICAgICogCiAgICAgKiBAdmFyIElkZW50aWZpZXIgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaWQ7CiAgICAKICAgIC8qKgogICAgICogRXh0ZW5kZWQgY2xhc3MKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHN1cGVyQ2xhc3M7CiAgICAKICAgIC8qKgogICAgICogQ2xhc3MgYm9keQogICAgICogCiAgICAgKiBAdmFyIENsYXNzQm9keSAKICAgICAqLwogICAgcHJvdGVjdGVkICRib2R5OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgY2xhc3MgbmFtZQogICAgICogCiAgICAgKiBAcmV0dXJuIElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldElkKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmlkOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgY2xhc3MgbmFtZQogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkaWQgQ2xhc3MgbmFtZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRJZCgkaWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGlkLCAiSWRlbnRpZmllciIsIHRydWUpOwogICAgICAgICR0aGlzLT5pZCA9ICRpZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBleHRlbmRlZCBjbGFzcwogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFN1cGVyQ2xhc3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3VwZXJDbGFzczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGV4dGVuZGVkIGNsYXNzCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRzdXBlckNsYXNzIEV4dGVuZGVkIGNsYXNzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFN1cGVyQ2xhc3MoJHN1cGVyQ2xhc3MpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHN1cGVyQ2xhc3MsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnN1cGVyQ2xhc3MgPSAkc3VwZXJDbGFzczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBjbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gQ2xhc3NCb2R5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBjbGFzcyBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBDbGFzc0JvZHkgJGJvZHkgQ2xhc3MgYm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KCRib2R5KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRib2R5LCAiQ2xhc3NCb2R5Iik7CiAgICAgICAgJHRoaXMtPmJvZHkgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzcGVjaWZpZXIgaW4gYW4gZXhwb3J0IGRlY2xhcmF0aW9uLgogKiBGb3IgZXhhbXBsZSAie2F9IiBpbjogZXhwb3J0IHthfQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBFeHBvcnRTcGVjaWZpZXIgZXh0ZW5kcyBNb2R1bGVTcGVjaWZpZXIKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHBvcnRlZCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEB2YXIgSWRlbnRpZmllciAKICAgICAqLwogICAgcHJvdGVjdGVkICRleHBvcnRlZDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHBvcnRlZCBpZGVudGlmaWVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwb3J0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhwb3J0ZWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkZXhwb3J0ZWQgRXhwb3J0ZWQgaWRlbnRpZmllcgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHBvcnRlZChJZGVudGlmaWVyICRleHBvcnRlZCkKICAgIHsKICAgICAgICAkdGhpcy0+ZXhwb3J0ZWQgPSAkZXhwb3J0ZWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSAiZm9yLi4ub2YiIHN0YXRlbWVudC4KICogRm9yIGV4YW1wbGU6IGZvciAodmFyIGEgb2YgYikge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRm9yT2ZTdGF0ZW1lbnQgZXh0ZW5kcyBGb3JJblN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImxlZnQiID0+IHRydWUsCiAgICAgICAgInJpZ2h0IiA9PiB0cnVlLAogICAgICAgICJib2R5IiA9PiB0cnVlLAogICAgICAgICJhd2FpdCIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQXN5bmMgaXRlcmF0aW9uIGZsYWcKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXdhaXQgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhc3luYyBpdGVyYXRpb24gZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF3YWl0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmF3YWl0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFzeW5jIGl0ZXJhdGlvbiBmbGFnCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRhd2FpdCBBc3luYyBpdGVyYXRpb24gZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBd2FpdCgkYXdhaXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmF3YWl0ID0gKGJvb2wpICRhd2FpdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSB5aWVsZCBzdGF0ZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFlpZWxkRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiYXJndW1lbnQiID0+IHRydWUsCiAgICAgICAgImRlbGVnYXRlIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBZaWVsZCBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogRGVsZWdhdGUgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgeWllbGQga2V5d29yZCBpcyBwcmVjZWVkZWQgYnkgKgogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZGVsZWdhdGUgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHlpZWxkIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXJndW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB5aWVsZCBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgQXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnQoJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRhcmd1bWVudCwgIkV4cHJlc3Npb24iLCB0cnVlKTsKICAgICAgICAkdGhpcy0+YXJndW1lbnQgPSAkYXJndW1lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlbGVnYXRlIGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIHlpZWxkIGtleXdvcmQgaXMKICAgICAqIHByZWNlZWRlZCBieSAqCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RGVsZWdhdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZGVsZWdhdGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVsZWdhdGUgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgeWllbGQga2V5d29yZCBpcwogICAgICogcHJlY2VlZGVkIGJ5ICoKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGRlbGVnYXRlIERlbGVnYXRlIGZsYWcKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVsZWdhdGUoJGRlbGVnYXRlKQogICAgewogICAgICAgICR0aGlzLT5kZWxlZ2F0ZSA9IChib29sKSAkZGVsZWdhdGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50IGFuZCB3cmFwcyBhbm90aGVyIGV4cHJlc3Npb24uCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV4cHJlc3Npb25TdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZXhwcmVzc2lvbiIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBXcmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4cHJlc3Npb247CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkZXhwcmVzc2lvbiBXcmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uICRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5leHByZXNzaW9uID0gJGV4cHJlc3Npb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgdHJ5LWNhdGNoIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVHJ5U3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImJsb2NrIiA9PiB0cnVlLAogICAgICAgICJoYW5kbGVyIiA9PiB0cnVlLAogICAgICAgICJmaW5hbGl6ZXIiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogV3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAdmFyIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkYmxvY2s7CiAgICAKICAgIC8qKgogICAgICogQ2F0Y2ggY2xhdXNlCiAgICAgKiAKICAgICAqIEB2YXIgQ2F0Y2hDbGF1c2UgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkaGFuZGxlcjsKICAgIAogICAgLyoqCiAgICAgKiAiZmluYWxseSIgYmxvY2sKICAgICAqIAogICAgICogQHZhciBCbG9ja1N0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRmaW5hbGl6ZXI7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCbG9jaygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ibG9jazsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB3cmFwcGVkIGJsb2NrCiAgICAgKiAKICAgICAqIEBwYXJhbSBCbG9ja1N0YXRlbWVudCAkYmxvY2sgV3JhcHBlZCBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCbG9jayhCbG9ja1N0YXRlbWVudCAkYmxvY2spCiAgICB7CiAgICAgICAgJHRoaXMtPmJsb2NrID0gJGJsb2NrOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIAogICAgICogQHJldHVybiBDYXRjaENsYXVzZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SGFuZGxlcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5oYW5kbGVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNhdGNoIGNsYXVzZQogICAgICogCiAgICAgKiBAcGFyYW0gQ2F0Y2hDbGF1c2UgJGhhbmRsZXIgQ2F0Y2ggY2xhdXNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEhhbmRsZXIoJGhhbmRsZXIpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGhhbmRsZXIsICJDYXRjaENsYXVzZSIsIHRydWUpOwogICAgICAgICR0aGlzLT5oYW5kbGVyID0gJGhhbmRsZXI7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlICJmaW5hbGx5IiBibG9jawogICAgICogCiAgICAgKiBAcmV0dXJuIEJsb2NrU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRGaW5hbGl6ZXIoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmluYWxpemVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlICJmaW5hbGx5IiBibG9jawogICAgICogCiAgICAgKiBAcGFyYW0gQmxvY2tTdGF0ZW1lbnQgJGZpbmFsaXplciBUaGUgImZpbmFsbHkiIGJsb2NrCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZpbmFsaXplcigkZmluYWxpemVyKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRmaW5hbGl6ZXIsICJCbG9ja1N0YXRlbWVudCIsIHRydWUpOwogICAgICAgICR0aGlzLT5maW5hbGl6ZXIgPSAkZmluYWxpemVyOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfQo8P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlICJzdXBlciIga2V5d29yZC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU3VwZXIgZXh0ZW5kcyBOb2RlCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHRhZ2dldCB0ZW1wbGF0ZSBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogZm5gdGVtcGxhdGVgCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidGFnIiA9PiB0cnVlLAogICAgICAgICJxdWFzaSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUYWcgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdGFnOwogICAgCiAgICAvKioKICAgICAqIFRlbXBsYXRlCiAgICAgKiAKICAgICAqIEB2YXIgVGVtcGxhdGVMaXRlcmFsIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHF1YXNpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRhZyBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFnKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRhZzsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0YWcgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkdGFnIFRhZyBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRhZyhFeHByZXNzaW9uICR0YWcpCiAgICB7CiAgICAgICAgJHRoaXMtPnRhZyA9ICR0YWc7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gVGVtcGxhdGVMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRRdWFzaSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5xdWFzaTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0aGUgdGVtcGxhdGUKICAgICAqIAogICAgICogQHBhcmFtIFRlbXBsYXRlTGl0ZXJhbCAkcXVhc2kgVGVtcGxhdGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UXVhc2koVGVtcGxhdGVMaXRlcmFsICRxdWFzaSkKICAgIHsKICAgICAgICAkdGhpcy0+cXVhc2kgPSAkcXVhc2k7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFycm93IGZ1bmN0aW9uLgogKiBGb3IgZXhhbXBsZTogdmFyIGZuID0gKGEsIGIpID0+IGNvbnNvbGUubG9nKGEsIGIpCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEFycm93RnVuY3Rpb25FeHByZXNzaW9uIGV4dGVuZHMgRnVuY3Rpb25fIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImV4cHJlc3Npb24iID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoaXMgZmxhZyBpcyB0cnVlIHdoZW4gZnVuY3Rpb24gYm9keSBpcyB3cmFwcGVkIGluIGN1cmx5IGJyYWNlcwogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9uID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZnVuY3Rpb24gYm9keQogICAgICogCiAgICAgKiBAcGFyYW0gQmxvY2tTdGF0ZW1lbnR8RXhwcmVzc2lvbiAkYm9keSBGdW5jdGlvbiBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGJvZHksIGFycmF5KCJCbG9ja1N0YXRlbWVudCIsICJFeHByZXNzaW9uIikpOwogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4cHJlc3Npb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXhwcmVzc2lvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uIGZsYWcKICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGV4cHJlc3Npb24gRXhwcmVzc2lvbiBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEV4cHJlc3Npb24oJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAoYm9vbCkgJGV4cHJlc3Npb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGltcG9ydCBleHByZXNzaW9uIChkeW5hbWljIGltcG9ydCkuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEltcG9ydEV4cHJlc3Npb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInNvdXJjZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgY2F0Y2ggY2xhdXNlIHBhcmFtZXRlcgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRzb3VyY2U7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2U7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaW1wb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkc291cmNlIEltcG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlKEV4cHJlc3Npb24gJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gJHNvdXJjZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzd2l0Y2ggc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogc3dpdGNoICh0ZXN0KSB7fQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBTd2l0Y2hTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZGlzY3JpbWluYW50IiA9PiB0cnVlLAogICAgICAgICJjYXNlcyIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBEaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZGlzY3JpbWluYW50OwogICAgCiAgICAvKioKICAgICAqIENhc2VzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgU3dpdGNoQ2FzZVtdIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNhc2VzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERpc2NyaW1pbmFudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kaXNjcmltaW5hbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGlzY3JpbWluYW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGRpc2NyaW1pbmFudCBEaXNjcmltaW5hbnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXREaXNjcmltaW5hbnQoRXhwcmVzc2lvbiAkZGlzY3JpbWluYW50KQogICAgewogICAgICAgICR0aGlzLT5kaXNjcmltaW5hbnQgPSAkZGlzY3JpbWluYW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYXNlcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIFN3aXRjaENhc2VbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2FzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2FzZXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2FzZXMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIFN3aXRjaENhc2VbXSAkY2FzZXMgQ2FzZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2FzZXMoJGNhc2VzKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjYXNlcywgIlN3aXRjaENhc2UiKTsKICAgICAgICAkdGhpcy0+Y2FzZXMgPSAkY2FzZXM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZm9yIHN0YXRlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRm9yU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImluaXQiID0+IHRydWUsCiAgICAgICAgInRlc3QiID0+IHRydWUsCiAgICAgICAgInVwZGF0ZSIgPT4gdHJ1ZSwKICAgICAgICAiYm9keSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcgogICAgICogCiAgICAgKiBAdmFyIFZhcmlhYmxlRGVjbGFyYXRpb258RXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGluaXQ7CiAgICAKICAgIC8qKgogICAgICogVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR0ZXN0OwogICAgCiAgICAvKioKICAgICAqIFVwZGF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICR1cGRhdGU7CiAgICAKICAgIC8qKgogICAgICogTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50IAogICAgICovCiAgICBwcm90ZWN0ZWQgJGJvZHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5pdGlhbGl6ZXIKICAgICAqIAogICAgICogQHJldHVybiBWYXJpYWJsZURlY2xhcmF0aW9ufEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEluaXQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+aW5pdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbml0aWFsaXplcgogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9uICRpbml0IEluaXRpYWxpemVyCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEluaXQoJGluaXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRpbml0LAogICAgICAgICAgICBhcnJheSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICJFeHByZXNzaW9uIiksCiAgICAgICAgICAgIHRydWUKICAgICAgICApOwogICAgICAgICR0aGlzLT5pbml0ID0gJGluaXQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFRlc3QoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dGVzdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0ZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHRlc3QgVGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFRlc3QoJHRlc3QpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHRlc3QsICJFeHByZXNzaW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnRlc3QgPSAkdGVzdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdXBkYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRVcGRhdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dXBkYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHVwZGF0ZSBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR1cGRhdGUgVXBkYXRlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VXBkYXRlKCR1cGRhdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJHVwZGF0ZSwgIkV4cHJlc3Npb24iLCB0cnVlKTsKICAgICAgICAkdGhpcy0+dXBkYXRlID0gJHVwZGF0ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIHVwZGF0ZSBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogYSsrCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFVwZGF0ZUV4cHJlc3Npb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImFyZ3VtZW50IiA9PiB0cnVlLAogICAgICAgICJvcGVyYXRvciIgPT4gZmFsc2UsCiAgICAgICAgInByZWZpeCIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRXhwcmVzc2lvbidzIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3I7CiAgICAKICAgIC8qKgogICAgICogUHJlZml4IGZsYWcgdGhhdCBpcyB0cnVlIHdoZW4gdGhlIG9wZXJhdG9yIHByZWNlZWRzIHRoZSBhcmd1bWVudAogICAgICogCiAgICAgKiBAdmFyIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmVmaXggPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGFyZ3VtZW50OwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBvcGVyYXRvcgogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlcmF0b3IoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlcmF0b3I7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wZXJhdG9yKCRvcGVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSAkb3BlcmF0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHByZWZpeCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBvcGVyYXRvciBwcmVjZWVkcyB0aGUKICAgICAqIGFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJlZml4KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByZWZpeDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBwcmVmaXggZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgb3BlcmF0b3IgcHJlY2VlZHMgdGhlCiAgICAgKiBhcmd1bWVudAogICAgICogCiAgICAgKiBAcGFyYW0gYm9vbCAkcHJlZml4IFByZWZpeCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByZWZpeCgkcHJlZml4KQogICAgewogICAgICAgICR0aGlzLT5wcmVmaXggPSAkcHJlZml4OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hcmd1bWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3MgYXJndW1lbnQKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGFyZ3VtZW50IEFyZ3VtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50KEV4cHJlc3Npb24gJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudCA9ICRhcmd1bWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBzZXF1ZW5jZSBvZiBleHByZXNzaW9ucy4KICogRm9yIGV4YW1wbGU6IGEsIGIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgU2VxdWVuY2VFeHByZXNzaW9uICBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZXhwcmVzc2lvbnMiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogRXhwcmVzc2lvbnMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9ucyA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbnMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEV4cHJlc3Npb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmV4cHJlc3Npb25zOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cHJlc3Npb25zIGFycmF5CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uW10gJGV4cHJlc3Npb25zIEV4cHJlc3Npb25zIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEV4cHJlc3Npb25zKCRleHByZXNzaW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkZXhwcmVzc2lvbnMsICJFeHByZXNzaW9uIik7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb25zID0gJGV4cHJlc3Npb25zOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGZ1bmN0aW9uIGRlY2xhcmF0aW9uCiAqIEZvciBleGFtcGxlOiBmdW5jdGlvbiB0ZXN0ICgpIHt9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEZ1bmN0aW9uRGVjbGFyYXRpb24gZXh0ZW5kcyBGdW5jdGlvbl8gaW1wbGVtZW50cyBEZWNsYXJhdGlvbgp7CiAgICAvKioKICAgICAqIFNldHMgdGhlIGZ1bmN0aW9uIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGlkIEZ1bmN0aW9uIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SWQoJGlkKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRpZCwgIklkZW50aWZpZXIiKTsKICAgICAgICByZXR1cm4gJHRoaXMtPmlkID0gJGlkOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbWVtYmVyIGV4cHJlc3Npb24uCiAqIEZvciBleGFtcGxlOiBmb28uYmFyCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIE1lbWJlckV4cHJlc3Npb24gZXh0ZW5kcyBDaGFpbkVsZW1lbnQgaW1wbGVtZW50cyBQYXR0ZXJuCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAib2JqZWN0IiA9PiB0cnVlLAogICAgICAgICJwcm9wZXJ0eSIgPT4gdHJ1ZSwKICAgICAgICAiY29tcHV0ZWQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEV4cHJlc3Npb24ncyBvYmplY3QKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9ufFN1cGVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9iamVjdDsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgcHJvcGVydHkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydHk7CiAgICAKICAgIC8qKgogICAgICogQ29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIGRlY2xhcmVkIHVzaW5nIHNxdWFyZQogICAgICogYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEB2YXIgYm9vbCAKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21wdXRlZCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24ncyBvYmplY3QKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9ufFN1cGVyIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T2JqZWN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9iamVjdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9ufFN1cGVyICRvYmplY3QgT2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9iamVjdCgkb2JqZWN0KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRvYmplY3QsIGFycmF5KCJFeHByZXNzaW9uIiwgIlN1cGVyIikpOwogICAgICAgICR0aGlzLT5vYmplY3QgPSAkb2JqZWN0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uJ3MgcHJvcGVydHkKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQcm9wZXJ0eSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5wcm9wZXJ0eTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3MgcHJvcGVydHkKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJHByb3BlcnR5IFByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFByb3BlcnR5KEV4cHJlc3Npb24gJHByb3BlcnR5KQogICAgewogICAgICAgICR0aGlzLT5wcm9wZXJ0eSA9ICRwcm9wZXJ0eTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIGRlY2xhcmVkCiAgICAgKiB1c2luZyBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29tcHV0ZWQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcHV0ZWQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29tcHV0ZWQgZmxhZyB0aGF0IGlzIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIGRlY2xhcmVkCiAgICAgKiB1c2luZyBzcXVhcmUgYnJhY2tldHMgc3ludGF4CiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRjb21wdXRlZCBDb21wdXRlZCBmbGFnCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENvbXB1dGVkKCRjb21wdXRlZCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29tcHV0ZWQgPSAoYm9vbCkgJGNvbXB1dGVkOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBleHBvcnQgbmFtZWQgZGVjbGFyYXRpb24uCiAqIEZvciBleGFtcGxlOiBleHBvcnQge2Zvb30gZnJvbSAiYmFyIgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBFeHBvcnROYW1lZERlY2xhcmF0aW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIE1vZHVsZURlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZGVjbGFyYXRpb24iID0+IHRydWUsCiAgICAgICAgInNwZWNpZmllcnMiID0+IHRydWUsCiAgICAgICAgInNvdXJjZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHBvcnRlZCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAdmFyIERlY2xhcmF0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGRlY2xhcmF0aW9uOwogICAgCiAgICAvKioKICAgICAqIEV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHZhciBFeHBvcnRTcGVjaWZpZXJbXSAKICAgICAqLwogICAgcHJvdGVjdGVkICRzcGVjaWZpZXJzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgZXhwb3J0IHNvdXJjZQogICAgICogCiAgICAgKiBAdmFyIExpdGVyYWwgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRGVjbGFyYXRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldERlY2xhcmF0aW9uKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmRlY2xhcmF0aW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBEZWNsYXJhdGlvbiAkZGVjbGFyYXRpb24gRXhwb3J0ZWQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RGVjbGFyYXRpb24oJGRlY2xhcmF0aW9uKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRkZWNsYXJhdGlvbiwgIkRlY2xhcmF0aW9uIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmRlY2xhcmF0aW9uID0gJGRlY2xhcmF0aW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHJldHVybiBFeHBvcnRTcGVjaWZpZXJbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U3BlY2lmaWVycygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zcGVjaWZpZXJzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHBhcmFtIEV4cG9ydFNwZWNpZmllcltdICRzcGVjaWZpZXJzIEV4cG9ydGVkIHNwZWNpZmllcnMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U3BlY2lmaWVycygkc3BlY2lmaWVycykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkc3BlY2lmaWVycywgIkV4cG9ydFNwZWNpZmllciIpOwogICAgICAgICR0aGlzLT5zcGVjaWZpZXJzID0gJHNwZWNpZmllcnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHJldHVybiBMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb3VyY2UoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c291cmNlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqIAogICAgICogQHBhcmFtIExpdGVyYWwgJHNvdXJjZSBFeHBvcnQgc291cmNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFNvdXJjZSgkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRzb3VyY2UsICJMaXRlcmFsIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPnNvdXJjZSA9ICRzb3VyY2U7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbnVsbCBsaXRlcmFsLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBOdWxsTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlID0gbnVsbDsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmF3ID0gIm51bGwiOwogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBleHByZXNzaW9uIHdyYXBwZWQgaW4gcm91bmQgYnJhY2tldHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4cHJlc3Npb247CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkZXhwcmVzc2lvbiBXcmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uICRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5leHByZXNzaW9uID0gJGV4cHJlc3Npb247CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuICJleHBvcnQgYWxsIiBkZWNsYXJhdGlvbi4KICogRm9yIGV4YW1wbGU6IGV4cG9ydCAqIGZyb20gInRlc3QiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEV4cG9ydEFsbERlY2xhcmF0aW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIE1vZHVsZURlY2xhcmF0aW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAic291cmNlIiA9PiB0cnVlLAogICAgICAgICJleHBvcnRlZCIgPT4gdHJ1ZQogICAgKTsKCiAgICAvKioKICAgICAqIFRoZSBleHBvcnQgc291cmNlCiAgICAgKgogICAgICogQHZhciBMaXRlcmFsCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc291cmNlOwoKICAgIC8qKgogICAgICogVGhlIGV4cG9ydGVkIG5hbWUKICAgICAqCiAgICAgKiBAdmFyIElkZW50aWZpZXIKICAgICAqLwogICAgcHJvdGVjdGVkICRleHBvcnRlZDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cG9ydCBzb3VyY2UKICAgICAqCiAgICAgKiBAcmV0dXJuIExpdGVyYWwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFNvdXJjZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zb3VyY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHBvcnQgc291cmNlCiAgICAgKgogICAgICogQHBhcmFtIExpdGVyYWwgJHNvdXJjZSBFeHBvcnQgc291cmNlCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U291cmNlKExpdGVyYWwgJHNvdXJjZSkKICAgIHsKICAgICAgICAkdGhpcy0+c291cmNlID0gJHNvdXJjZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHBvcnRlZCBuYW1lCiAgICAgKgogICAgICogQHJldHVybiBJZGVudGlmaWVyCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFeHBvcnRlZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHBvcnRlZDsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGV4cG9ydGVkIG5hbWUKICAgICAqVwogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGV4cG9ydGVkIEV4cG9ydGVkIG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHBvcnRlZCgkZXhwb3J0ZWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJGV4cG9ydGVkLCAiSWRlbnRpZmllciIsIHRydWUpOwogICAgICAgICR0aGlzLT5leHBvcnRlZCA9ICRleHBvcnRlZDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlIGV4cG9ydCBkZWZhdWx0IGRlY2xhcmF0aW9uLgogKiBGb3IgZXhhbXBsZTogZXhwb3J0IGRlZmF1bHQgYQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgTW9kdWxlRGVjbGFyYXRpb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJkZWNsYXJhdGlvbiIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgZXhwb3J0ZWQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHZhciBEZWNsYXJhdGlvbnxFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZGVjbGFyYXRpb247CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwb3J0ZWQgZGVjbGFyYXRpb24KICAgICAqIAogICAgICogQHJldHVybiBEZWNsYXJhdGlvbnxFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXREZWNsYXJhdGlvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kZWNsYXJhdGlvbjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHBvcnRlZCBkZWNsYXJhdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gdHlwZSAkZGVjbGFyYXRpb24gVGhlIGV4cG9ydGVkIGRlY2xhcmF0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldERlY2xhcmF0aW9uKCRkZWNsYXJhdGlvbikKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkZGVjbGFyYXRpb24sIGFycmF5KCJEZWNsYXJhdGlvbiIsICJFeHByZXNzaW9uIikpOwogICAgICAgICR0aGlzLT5kZWNsYXJhdGlvbiA9ICRkZWNsYXJhdGlvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gYXJyYXkgYmluZGluZyBwYXR0ZXJuLgogKiBGb3IgZXhhbXBsZTogW2EsIGIsIGNdID0gZAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBcnJheVBhdHRlcm4gZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgUGF0dGVybgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImVsZW1lbnRzIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEFycmF5IGVsZW1lbnRzCiAgICAgKiAKICAgICAqIEB2YXIgUGF0dGVybltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZWxlbWVudHMgPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHJldHVybiBQYXR0ZXJuW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEVsZW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVsZW1lbnRzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYXJyYXkgZWxlbWVudHMKICAgICAqIAogICAgICogQHBhcmFtIFBhdHRlcm5bXSAkZWxlbWVudHMgQXJyYXkgZWxlbWVudHMgdG8gc2V0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEVsZW1lbnRzKCRlbGVtZW50cykKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0QXJyYXlPZigkZWxlbWVudHMsICJQYXR0ZXJuIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmVsZW1lbnRzID0gJGVsZW1lbnRzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgInRoaXMiIGtleXdvcmQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFRoaXNFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY2xhc3MgZXhwcmVzc2lvbgogKiBGb3IgZXhhbXBsZTogdGVzdCA9IGNsYXNzIHt9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENsYXNzRXhwcmVzc2lvbiBleHRlbmRzIENsYXNzXyBpbXBsZW1lbnRzIEV4cHJlc3Npb24Kewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbGFiZWxlZCBzdGF0ZW1lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIExhYmVsZWRTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGFiZWwiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTGFiZWwKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhYmVsOwogICAgCiAgICAvKioKICAgICAqIEJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuIElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhYmVsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhYmVsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxhYmVsCiAgICAgKiAKICAgICAqIEBwYXJhbSBJZGVudGlmaWVyICRsYWJlbCBMYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMYWJlbChJZGVudGlmaWVyICRsYWJlbCkKICAgIHsKICAgICAgICAkdGhpcy0+bGFiZWwgPSAkbGFiZWw7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgQm9keQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRCb2R5KFN0YXRlbWVudCAkYm9keSkKICAgIHsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGJpbmFyeSBleHByZXNzaW9uLgogKiBGb3IgZXhhbXBsZTogYSArIGIKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQmluYXJ5RXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAib3BlcmF0b3IiID0+IGZhbHNlLAogICAgICAgICJyaWdodCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBPcGVyYXRvcgogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwogICAgCiAgICAvKioKICAgICAqIExlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFJpZ2h0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmlnaHQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdG9yOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wZXJhdG9yKCRvcGVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSAkb3BlcmF0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExlZnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGVmdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsZWZ0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGxlZnQgTGVmdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoRXhwcmVzc2lvbiAkbGVmdCkKICAgIHsKICAgICAgICAkdGhpcy0+bGVmdCA9ICRsZWZ0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgUmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSaWdodChFeHByZXNzaW9uICRyaWdodCkKICAgIHsKICAgICAgICAkdGhpcy0+cmlnaHQgPSAkcmlnaHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgY2xhc3MgZGVjbGFyYXRpb24uCiAqIEZvciBleGFtcGxlOiBjbGFzcyB0ZXN0IHt9CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIENsYXNzRGVjbGFyYXRpb24gZXh0ZW5kcyBDbGFzc18gaW1wbGVtZW50cyBEZWNsYXJhdGlvbgp7CiAgICAvKioKICAgICAqIFNldHMgdGhlIGNsYXNzIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHBhcmFtIElkZW50aWZpZXIgJGlkIENsYXNzIGlkZW50aWZpZXIKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SWQoJGlkKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRpZCwgIklkZW50aWZpZXIiKTsKICAgICAgICAkdGhpcy0+aWQgPSAkaWQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZGVmYXVsdCBpbXBvcnQgc3BlY2lmaWVyLgogKiBGb3IgZXhhbXBsZSAidGVzdCIgaW46IGltcG9ydCB0ZXN0IGZyb20gInRlc3QuanMiLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIgZXh0ZW5kcyBNb2R1bGVTcGVjaWZpZXIKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCnVzZSBQZWFzdFxTeW50YXhcVXRpbHM7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHRlbXBsYXRlIGVsZW1lbnQuCiAqIEZvciBleGFtcGxlIGBmb29gIGFuZCBgYmFyYCBpbjogYGZvbyR7ZXhwfWJhcmAKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgVGVtcGxhdGVFbGVtZW50IGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInZhbHVlIiA9PiBmYWxzZSwKICAgICAgICAidGFpbCIgPT4gZmFsc2UsCiAgICAgICAgInJhd1ZhbHVlIiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdmFsdWU7CiAgICAKICAgIC8qKgogICAgICogVGFpbCBmbGFnIHRoYXQgaXMgdHJ1ZSB3aGVuIHRoZSBlbGVtZW50IGlzIHRoZSB0YWlsIGVsZW1lbnQgaW4gYSB0ZW1wbGF0ZQogICAgICogCiAgICAgKiBAdmFyIGJvb2wgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdGFpbCA9IGZhbHNlOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRyYXdWYWx1ZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gbm9kZSdzIHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSkKICAgIHsKICAgICAgICAkdGhpcy0+dmFsdWUgPSAkdmFsdWU7CiAgICAgICAgJHRoaXMtPnJhd1ZhbHVlID0gVXRpbHM6OnF1b3RlTGl0ZXJhbFN0cmluZygkdmFsdWUsICJgIik7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRhaWwgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgZWxlbWVudCBpcyB0aGUgdGFpbCBlbGVtZW50CiAgICAgKiBpbiBhIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGFpbCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50YWlsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRhaWwgZmxhZyB0aGF0IGlzIHRydWUgd2hlbiB0aGUgZWxlbWVudCBpcyB0aGUgdGFpbCBlbGVtZW50CiAgICAgKiBpbiBhIHRlbXBsYXRlCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICR0YWlsIFRhaWwgZmxhZwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUYWlsKCR0YWlsKQogICAgewogICAgICAgICR0aGlzLT50YWlsID0gKGJvb2wpICR0YWlsOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhd1ZhbHVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJhd1ZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHJhdyB2YWx1ZSB0aGF0IG11c3QgYmUgd3JhcHBlZCBpbiB0ZW1wbGF0ZXMgcXVvdGVzLgogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyYXdWYWx1ZSBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3VmFsdWUoJHJhd1ZhbHVlKQogICAgewogICAgICAgICRyYXdWYWx1ZSA9IHByZWdfcmVwbGFjZSgiI15bYH1dfCg/OmB8XFxcJFx7KSQjIiwgIiIsICRyYXdWYWx1ZSk7CiAgICAgICAgJHRoaXMtPnNldFZhbHVlKFV0aWxzOjp1bnF1b3RlTGl0ZXJhbFN0cmluZygiYCRyYXdWYWx1ZWAiKSk7CiAgICAgICAgJHRoaXMtPnJhd1ZhbHVlID0gJHJhd1ZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhbiBlbXB0eSBzdGF0ZW1lbnQgKDspLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBFbXB0eVN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGFzc2lnbm1lbnQgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IGEgPSBiCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEFzc2lnbm1lbnRFeHByZXNzaW9uIGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJsZWZ0IiA9PiB0cnVlLAogICAgICAgICJvcGVyYXRvciIgPT4gZmFsc2UsCiAgICAgICAgInJpZ2h0IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwogICAgCiAgICAvKioKICAgICAqIFRoZSBsZWZ0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHZhciBQYXR0ZXJufEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFRoZSByaWdodCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbiAKICAgICAqLwogICAgcHJvdGVjdGVkICRyaWdodDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRPcGVyYXRvcigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVyYXRvcjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGVmdCBub2RlIG9mIHRoZSBhc3NpZ25tZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gUGF0dGVybnxFeHByZXNzaW9uIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGVmdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWZ0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxlZnQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gUGF0dGVybnxFeHByZXNzaW9uICRsZWZ0IFRoZSBub2RlIHRvIHNldAogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZWZ0KCRsZWZ0KQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKCRsZWZ0LCBhcnJheSgiUGF0dGVybiIsICJFeHByZXNzaW9uIikpOwogICAgICAgICR0aGlzLT5sZWZ0ID0gJGxlZnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJpZ2h0IG5vZGUgb2YgdGhlIGFzc2lnbm1lbnQKICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uIAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgbm9kZSBvZiB0aGUgYXNzaWdubWVudAogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgVGhlIG5vZGUgdG8gc2V0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJpZ2h0KEV4cHJlc3Npb24gJHJpZ2h0KQogICAgewogICAgICAgICR0aGlzLT5yaWdodCA9ICRyaWdodDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlICJicmVhayIgc3RhdGVtZW50IGluc2lkZSBsb29wcy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQnJlYWtTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGFiZWwiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogVGhlIG9wdGlvbmFsIGxhYmVsIG9mIHRoZSBicmVhayBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHZhciBJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhYmVsOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5vZGUncyBsYWJlbAogICAgICogCiAgICAgKiBAcmV0dXJuIElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExhYmVsKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhYmVsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG5vZGUncyBsYWJlbAogICAgICogCiAgICAgKiBAcGFyYW0gSWRlbnRpZmllciAkbGFiZWwgTm9kZSdzIGxhYmVsCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExhYmVsKCRsYWJlbCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkbGFiZWwsICJJZGVudGlmaWVyIiwgdHJ1ZSk7CiAgICAgICAgJHRoaXMtPmxhYmVsID0gJGxhYmVsOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGxvZ2ljYWwgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IGEgJiYgYgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBMb2dpY2FsRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAib3BlcmF0b3IiID0+IGZhbHNlLAogICAgICAgICJyaWdodCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBPcGVyYXRvcgogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwogICAgCiAgICAvKioKICAgICAqIExlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIFJpZ2h0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcmlnaHQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3BlcmF0b3IKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZXJhdG9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9wZXJhdG9yOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIG9wZXJhdG9yCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9wZXJhdG9yKCRvcGVyYXRvcikKICAgIHsKICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPSAkb3BlcmF0b3I7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlZnQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExlZnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bGVmdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsZWZ0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb24gJGxlZnQgTGVmdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoRXhwcmVzc2lvbiAkbGVmdCkKICAgIHsKICAgICAgICAkdGhpcy0+bGVmdCA9ICRsZWZ0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkcmlnaHQgUmlnaHQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSaWdodChFeHByZXNzaW9uICRyaWdodCkKICAgIHsKICAgICAgICAkdGhpcy0+cmlnaHQgPSAkcmlnaHQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgbnVtZXJpYyBsaXRlcmFsLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBOdW1lcmljTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJmb3JtYXQiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvL0Zvcm1hdCBjb25zdGFudHMKICAgIC8qKgogICAgICogRGVjaW1hbCBudW1iZXIgZm9ybWF0CiAgICAgKi8KICAgIGNvbnN0IERFQ0lNQUwgPSAiZGVjaW1hbCI7CiAgICAKICAgIC8qKgogICAgICogSGV4YWRlY2ltYWwgbnVtYmVyIGZvcm1hdAogICAgICovCiAgICBjb25zdCBIRVhBREVDSU1BTCA9ICJoZXhhZGVjaW1hbCI7CiAgICAKICAgIC8qKgogICAgICogT2N0YWwgbnVtYmVyIGZvcm1hdAogICAgICovCiAgICBjb25zdCBPQ1RBTCA9ICJvY3RhbCI7CiAgICAKICAgIC8qKgogICAgICogQmluYXJ5IG51bWJlciBmb3JtYXQKICAgICAqLwogICAgY29uc3QgQklOQVJZID0gImJpbmFyeSI7CiAgICAKICAgIC8qKgogICAgICogTm9kZSdzIG51bWVyaWMgZm9ybWF0CiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkZm9ybWF0ID0gc2VsZjo6REVDSU1BTDsKICAgIAogICAgLyoqCiAgICAgKiBOdW1lcmljIGZvcm1zIGNvbnZlcnNpb24gcnVsZXMKICAgICAqIAogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJGZvcm1zID0gYXJyYXkoCiAgICAgICAgImIiID0+IGFycmF5KAogICAgICAgICAgICAiY2hlY2siID0+ICIvXjBiWzAxXStbMDFfXSokL2kiLAogICAgICAgICAgICAiY29udiIgPT4gImJpbmRlYyIsCiAgICAgICAgICAgICJmb3JtYXQiID0+IHNlbGY6OkJJTkFSWQogICAgICAgICksCiAgICAgICAgIm8iID0+IGFycmF5KAogICAgICAgICAgICAiY2hlY2siID0+ICIvXjBvWzAtN10rWzAtN19dKiQvaSIsCiAgICAgICAgICAgICJjb252IiA9PiAib2N0ZGVjIiwKICAgICAgICAgICAgImZvcm1hdCIgPT4gc2VsZjo6T0NUQUwKICAgICAgICApLAogICAgICAgICJ4IiA9PiBhcnJheSgKICAgICAgICAgICAgImNoZWNrIiA9PiAiL14weFswLTlhLWZdK1swLTlhLWZfXSokL2kiLAogICAgICAgICAgICAiY29udiIgPT4gImhleGRlYyIsCiAgICAgICAgICAgICJmb3JtYXQiID0+IHNlbGY6OkhFWEFERUNJTUFMCiAgICAgICAgKSwKICAgICk7CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIGZsb2F0ICR2YWx1ZSBWYWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHZhbHVlID0gKGZsb2F0KSAkdmFsdWU7CiAgICAgICAgJGludFZhbHVlID0gKGludCkgJHZhbHVlOwogICAgICAgIGlmICgkdmFsdWUgPT0gJGludFZhbHVlKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICRpbnRWYWx1ZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIC8vRm9yY2UgcmVjYWxjdWxhdGlvbiBvZiB0aGUgcmF3IHZhbHVlCiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRGb3JtYXQoJHRoaXMtPmZvcm1hdCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkcmF3IFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKiAKICAgICAqIEB0aHJvd3MgXEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3KCRyYXcpCiAgICB7CiAgICAgICAgJHZhbHVlID0gJHJhdzsKICAgICAgICAkZm9ybWF0ID0gc2VsZjo6REVDSU1BTDsKICAgICAgICBpZiAoaXNfc3RyaW5nKCR2YWx1ZSkgJiYgJHZhbHVlICE9PSAiIikgewogICAgICAgICAgICAvL0hleGFkZWNpbWFsLCBiaW5hcnkgb3Igb2N0YWwKICAgICAgICAgICAgJHN0YXJ0WmVybyA9ICR2YWx1ZVswXSA9PT0gIjAiOwogICAgICAgICAgICAkZm9ybSA9ICRzdGFydFplcm8gJiYgaXNzZXQoJHZhbHVlWzFdKSA/IHN0cnRvbG93ZXIoJHZhbHVlWzFdKSA6IG51bGw7CiAgICAgICAgICAgIC8vTnVtZXJpYyBzZXBhcmF0b3IgY2Fubm90IGFwcGVhciBhdCB0aGUgYmVnaW5uaW5nIG9yIGF0IHRoZSBlbmQgb2YgdGhlIG51bWJlcgogICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgiL15ffF8kLyIsICR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJJbnZhbGlkIG51bWVyaWMgdmFsdWUiKTsKICAgICAgICAgICAgfSBlbHNlaWYgKGlzc2V0KCR0aGlzLT5mb3Jtc1skZm9ybV0pKSB7CiAgICAgICAgICAgICAgICAkZm9ybURlZiA9ICR0aGlzLT5mb3Jtc1skZm9ybV07CiAgICAgICAgICAgICAgICBpZiAoIXByZWdfbWF0Y2goJGZvcm1EZWZbImNoZWNrIl0sICR2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCAiIC4gJGZvcm1EZWZbImZvcm1hdCJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR2YWx1ZSA9IHN0cl9yZXBsYWNlKCJfIiwgIiIsICR2YWx1ZSk7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkZm9ybURlZlsiY29udiJdKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAkZm9ybWF0ID0gJGZvcm1EZWZbImZvcm1hdCJdOwogICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0WmVybyAmJiBwcmVnX21hdGNoKCIvXjBbMC03X10rJC8iLCAkdmFsdWUpKSB7CiAgICAgICAgICAgICAgICAvL0xlZ2FjeSBvY3RhbCBmb3JtCiAgICAgICAgICAgICAgICAkdmFsdWUgPSBzdHJfcmVwbGFjZSgiXyIsICIiLCAkdmFsdWUpOwogICAgICAgICAgICAgICAgJHZhbHVlID0gb2N0ZGVjKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAkZm9ybWF0ID0gc2VsZjo6T0NUQUw7CiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgIHByZWdfbWF0Y2goIi9eKFtcZF9dKlwuP1tcZF9dKikoPzplWytcLV0/W1xkX10rKT8kL2kiLCAkdmFsdWUsICRtYXRjaCkgJiYKICAgICAgICAgICAgICAgICRtYXRjaFsxXSAhPT0gIiIgJiYKICAgICAgICAgICAgICAgICRtYXRjaFsxXSAhPT0gIi4iICYmCiAgICAgICAgICAgICAgICAhcHJlZ19tYXRjaCgiL19lfGVbKy1dP198XyQvIiwgJHZhbHVlKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICR2YWx1ZSA9IHN0cl9yZXBsYWNlKCJfIiwgIiIsICR2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgXEV4Y2VwdGlvbigiSW52YWxpZCBudW1lcmljIHZhbHVlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoIWlzX2ludCgkdmFsdWUpICYmICFpc19mbG9hdCgkdmFsdWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJJbnZhbGlkIG51bWVyaWMgdmFsdWUiKTsKICAgICAgICB9CiAgICAgICAgJHZhbHVlID0gKGZsb2F0KSAkdmFsdWU7CiAgICAgICAgJGludFZhbHVlID0gKGludCkgJHZhbHVlOwogICAgICAgIGlmICgkdmFsdWUgPT0gJGludFZhbHVlKSB7CiAgICAgICAgICAgICR2YWx1ZSA9ICRpbnRWYWx1ZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmZvcm1hdCA9ICRmb3JtYXQ7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgICR0aGlzLT5yYXcgPSAkcmF3OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyBudW1lcmljIGZvcm1hdAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Rm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZvcm1hdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyBudW1lcmljIGZvcm1hdAogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmb3JtYXQgRm9ybWF0LCBvbmUgb2YgdGhlIGZvcm1hdCBjb25zdGFudHMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Rm9ybWF0KCRmb3JtYXQpCiAgICB7CiAgICAgICAgJHRoaXMtPmZvcm1hdCA9ICRmb3JtYXQ7CiAgICAgICAgc3dpdGNoICgkZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6QklOQVJZOgogICAgICAgICAgICAgICAgJHRoaXMtPnJhdyA9ICIwYiIgLiBkZWNiaW4oJHRoaXMtPnZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugc2VsZjo6T0NUQUw6CiAgICAgICAgICAgICAgICAkdGhpcy0+cmF3ID0gIjBvIiAuIGRlY29jdCgkdGhpcy0+dmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBzZWxmOjpIRVhBREVDSU1BTDoKICAgICAgICAgICAgICAgICR0aGlzLT5yYXcgPSAiMHgiIC4gZGVjaGV4KCR0aGlzLT52YWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJHRoaXMtPnJhdyA9IChzdHJpbmcpICR0aGlzLT52YWx1ZTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGNhbGwgZXhwcmVzc2lvbi4KICogRm9yIGV4YW1wbGU6IHRlc3QoKQogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBDYWxsRXhwcmVzc2lvbiBleHRlbmRzIENoYWluRWxlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImNhbGxlZSIgPT4gdHJ1ZSwKICAgICAgICAiYXJndW1lbnRzIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBjYWxsZWUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb258U3VwZXIgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2FsbGVlOwogICAgCiAgICAvKioKICAgICAqIFRoZSBhcmd1bWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uW118U3ByZWFkRWxlbWVudFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnRzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjYWxsZWUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIEV4cHJlc3Npb258U3VwZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENhbGxlZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jYWxsZWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2FsbGVlIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb258U3VwZXIgJGNhbGxlZSBDYWxsZWUgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDYWxsZWUoJGNhbGxlZSkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkY2FsbGVlLCBhcnJheSgiRXhwcmVzc2lvbiIsICJTdXBlciIpKTsKICAgICAgICAkdGhpcy0+Y2FsbGVlID0gJGNhbGxlZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJndW1lbnRzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbltdfFNwcmVhZEVsZW1lbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QXJndW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFyZ3VtZW50czsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhcmd1bWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIEV4cHJlc3Npb25bXXxTcHJlYWRFbGVtZW50W10gJGFyZ3VtZW50cyBBcmd1bWVudHMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QXJndW1lbnRzKCRhcmd1bWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGFyZ3VtZW50cywgYXJyYXkoIkV4cHJlc3Npb24iLCAiU3ByZWFkRWxlbWVudCIpKTsKICAgICAgICAkdGhpcy0+YXJndW1lbnRzID0gJGFyZ3VtZW50czsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBuYW1lc3BhY2UgaW1wb3J0IHNwZWNpZmllci4KICogRm9yIGV4YW1wbGUgIiogYXMgdGVzdCIgaW46IGltcG9ydCAqIGFzIHRlc3QgZnJvbSAidGVzdC5qcyIuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEltcG9ydERlZmF1bHRTcGVjaWZpZXIgZXh0ZW5kcyBNb2R1bGVTcGVjaWZpZXIKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgZm9yLWluIHN0YXRlbWVudC4KICogRm9yIGV4YW1wbGU6IGZvciAodmFyIGEgaW4gYikge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRm9ySW5TdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAibGVmdCIgPT4gdHJ1ZSwKICAgICAgICAicmlnaHQiID0+IHRydWUsCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogSXRlcmF0aW9uIHZhcmlhYmxlCiAgICAgKiAKICAgICAqIEB2YXIgVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9ufFBhdHRlcm4KICAgICAqLwogICAgcHJvdGVjdGVkICRsZWZ0OwogICAgCiAgICAvKioKICAgICAqIEl0ZXJhdGVkIG9iamVjdAogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRyaWdodDsKICAgIAogICAgLyoqCiAgICAgKiBMb29wIGJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpdGVyYXRpb24gdmFyaWFibGUKICAgICAqIAogICAgICogQHJldHVybiBWYXJpYWJsZURlY2xhcmF0aW9ufEV4cHJlc3Npb258UGF0dGVybgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TGVmdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWZ0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGl0ZXJhdGlvbiB2YXJpYWJsZQogICAgICogCiAgICAgKiBAcGFyYW0gVmFyaWFibGVEZWNsYXJhdGlvbnxFeHByZXNzaW9ufFBhdHRlcm4gJGxlZnQgSXRlcmF0aW9uIHZhcmlhYmxlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldExlZnQoJGxlZnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRsZWZ0LCBhcnJheSgiVmFyaWFibGVEZWNsYXJhdGlvbiIsICJFeHByZXNzaW9uIiwgIlBhdHRlcm4iKQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmxlZnQgPSAkbGVmdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaXRlcmF0ZWQgb2JqZWN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmlnaHQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmlnaHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgaXRlcmF0ZWQgb2JqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICRyaWdodCBJdGVyYXRlZCBvYmplY3QKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmlnaHQoRXhwcmVzc2lvbiAkcmlnaHQpCiAgICB7CiAgICAgICAgJHRoaXMtPnJpZ2h0ID0gJHJpZ2h0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEJvZHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Ym9keTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudCAkYm9keSBMb29wIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Qm9keShTdGF0ZW1lbnQgJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmJvZHkgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgc3RyaW5nIGxpdGVyYWwuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFN0cmluZ0xpdGVyYWwgZXh0ZW5kcyBMaXRlcmFsCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZm9ybWF0IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLy9Gb3JtYXQgY29uc3RhbnRzCiAgICAvKioKICAgICAqIERvdWJsZSBxdW90ZWQgc3RyaW5nCiAgICAgKi8KICAgIGNvbnN0IERPVUJMRV9RVU9URUQgPSAiZG91YmxlIjsKICAgIAogICAgLyoqCiAgICAgKiBTaW5nbGUgcXVvdGVkIHN0cmluZwogICAgICovCiAgICBjb25zdCBTSU5HTEVfUVVPVEVEID0gInNpbmdsZSI7CiAgICAKICAgIC8qKgogICAgICogU3RyaW5nIGZvcm1hdAogICAgICogCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgJGZvcm1hdCA9IHNlbGY6OkRPVUJMRV9RVU9URUQ7CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgVmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VmFsdWUoJHZhbHVlKQogICAgewogICAgICAgICR0aGlzLT52YWx1ZSA9IChzdHJpbmcpICR2YWx1ZTsKICAgICAgICAvL0ZvcmNlIHJlY2FsY3VsYXRpb24gb2YgdGhlIHJhdyB2YWx1ZQogICAgICAgIHJldHVybiAkdGhpcy0+c2V0Rm9ybWF0KCR0aGlzLT5mb3JtYXQpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHJhdyBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICogCiAgICAgKiBAdGhyb3dzIFxFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFJhdygkcmF3KQogICAgewogICAgICAgIGlmICghaXNfc3RyaW5nKCRyYXcpIHx8IHN0cmxlbigkcmF3KSA8IDIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFxFeGNlcHRpb24oIkludmFsaWQgc3RyaW5nIik7CiAgICAgICAgfQogICAgICAgICRzdGFydFF1b3RlID0gJHJhd1swXTsKICAgICAgICAkZW5kUXVvdGUgPSBzdWJzdHIoJHJhdywgLTEpOwogICAgICAgIGlmICgoJHN0YXJ0UXVvdGUgIT09ICInIiAmJiAkc3RhcnRRdW90ZSAhPT0gJyInKSB8fAogICAgICAgICAgICAkc3RhcnRRdW90ZSAhPT0gJGVuZFF1b3RlCiAgICAgICAgKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJJbnZhbGlkIHN0cmluZyIpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+dmFsdWUgPSBVdGlsczo6dW5xdW90ZUxpdGVyYWxTdHJpbmcoJHJhdyk7CiAgICAgICAgJHRoaXMtPnNldEZvcm1hdCgkcmF3WzBdID09PSAiJyIgPwogICAgICAgICAgICBzZWxmOjpTSU5HTEVfUVVPVEVEIDoKICAgICAgICAgICAgc2VsZjo6RE9VQkxFX1FVT1RFRAogICAgICAgICk7CiAgICAgICAgJHRoaXMtPnJhdyA9ICRyYXc7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgc3RyaW5nIGZvcm1hdAogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Rm9ybWF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmZvcm1hdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHN0cmluZyBmb3JtYXQKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkZm9ybWF0IEZvcm1hdCwgb25lIG9mIHRoZSBmb3JtYXQgY29uc3RhbnRzCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEZvcm1hdCgkZm9ybWF0KQogICAgewogICAgICAgICR0aGlzLT5mb3JtYXQgPSAkZm9ybWF0OwogICAgICAgICRxdW90ZSA9ICRmb3JtYXQgPT09IHNlbGY6OlNJTkdMRV9RVU9URUQgPyAiJyIgOiAnIic7CiAgICAgICAgJHRoaXMtPnJhdyA9IFV0aWxzOjpxdW90ZUxpdGVyYWxTdHJpbmcoJHRoaXMtPnZhbHVlLCAkcXVvdGUpOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgdGhyb3cgc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogdGhyb3cgZXJyCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFRocm93U3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImFyZ3VtZW50IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB0aHJvd24gZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAdmFyIEV4cHJlc3Npb24gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXJndW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGhyb3duIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiBFeHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBcmd1bWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hcmd1bWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB0aHJvd24gZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkYXJndW1lbnQgVGhlIG5vZGUgdG8gc2V0CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEFyZ3VtZW50KEV4cHJlc3Npb24gJGFyZ3VtZW50KQogICAgewogICAgICAgICR0aGlzLT5hcmd1bWVudCA9ICRhcmd1bWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYW4gaWYgc3RhdGVtZW50LgogKiBGb3IgZXhhbXBsZTogaWYgKHRlc3QpIHt9IGVsc2Uge30KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSWZTdGF0ZW1lbnQgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgU3RhdGVtZW50CnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidGVzdCIgPT4gdHJ1ZSwKICAgICAgICAiY29uc2VxdWVudCIgPT4gdHJ1ZSwKICAgICAgICAiYWx0ZXJuYXRlIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB0ZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRlc3Q7CiAgICAKICAgIC8qKgogICAgICogVGhlIHN0YXRlbWVudCB0aGF0IGlzIGFjdGl2YXRlZCBpZiB0aGUgdGVzdCBleHByZXNzaW9uIGlzIHRydWUKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29uc2VxdWVudDsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgImVsc2UiIHN0YXRlbWVudAogICAgICogCiAgICAgKiBAdmFyIFN0YXRlbWVudCAKICAgICAqLwogICAgcHJvdGVjdGVkICRhbHRlcm5hdGU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGVzdCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHRlc3QgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkdGVzdCBUZXN0IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCB0aGF0IGlzIGFjdGl2YXRlZCBpZiB0aGUgdGVzdCBleHByZXNzaW9uIGlzIHRydWUKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnR8RnVuY3Rpb25EZWNsYXJhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29uc2VxdWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25zZXF1ZW50OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0YXRlbWVudCB0aGF0IGlzIGFjdGl2YXRlZCBpZiB0aGUgdGVzdCBleHByZXNzaW9uIGlzIHRydWUKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudHxGdW5jdGlvbkRlY2xhcmF0aW9uICRjb25zZXF1ZW50IFRoZSBjb25zZXF1ZW50IGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q29uc2VxdWVudCgkY29uc2VxdWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgKICAgICAgICAgICAgJGNvbnNlcXVlbnQsCiAgICAgICAgICAgIGFycmF5KCJTdGF0ZW1lbnQiLCAiRnVuY3Rpb25EZWNsYXJhdGlvbiIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Y29uc2VxdWVudCA9ICRjb25zZXF1ZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSAiZWxzZSIgc3RhdGVtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbHRlcm5hdGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWx0ZXJuYXRlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlICJlbHNlIiBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHBhcmFtIFN0YXRlbWVudHxGdW5jdGlvbkRlY2xhcmF0aW9uICRhbHRlcm5hdGUgVGhlICJlbHNlIiBzdGF0ZW1lbnQKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0QWx0ZXJuYXRlKCRhbHRlcm5hdGUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRhbHRlcm5hdGUsCiAgICAgICAgICAgIGFycmF5KCJTdGF0ZW1lbnQiLCAiRnVuY3Rpb25EZWNsYXJhdGlvbiIpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+YWx0ZXJuYXRlID0gJGFsdGVybmF0ZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSByZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUmVnRXhwTGl0ZXJhbCBleHRlbmRzIExpdGVyYWwKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJmbGFncyIgPT4gZmFsc2UsCiAgICAgICAgInBhdHRlcm4iID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFJlZ2V4IGZsYWdzCiAgICAgKiAKICAgICAqIEB2YXIgc3RyaW5nIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGZsYWdzID0gIiI7CiAgICAKICAgIC8qKgogICAgICogUmVnZXggcGF0dGVybgogICAgICogCiAgICAgKiBAdmFyIHN0cmluZyAKICAgICAqLwogICAgcHJvdGVjdGVkICRwYXR0ZXJuID0gIiI7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICJSZWdFeHBMaXRlcmFsIjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHJlZ2V4IHBhdHRlcm4KICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFBhdHRlcm4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cGF0dGVybjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHJlZ2V4IHBhdHRlcm4KICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkcGF0dGVybiBSZWdleCBwYXR0ZXJuCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldFBhdHRlcm4oJHBhdHRlcm4pCiAgICB7CiAgICAgICAgJHRoaXMtPnBhdHRlcm4gPSAkcGF0dGVybjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyByZWdleCBmbGFncwogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RmxhZ3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZmxhZ3M7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyByZWdleCBmbGFncwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmbGFncyBSZWdleCBmbGFncwogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRGbGFncygkZmxhZ3MpCiAgICB7CiAgICAgICAgJHRoaXMtPmZsYWdzID0gJGZsYWdzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhdygpCiAgICB7CiAgICAgICAgcmV0dXJuICIvIiAuICR0aGlzLT5nZXRQYXR0ZXJuKCkgLiAiLyIgLiAkdGhpcy0+Z2V0RmxhZ3MoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyByYXcgdmFsdWUgdGhhdCBtdXN0IGluY2x1ZGUgZGVsaW1pdGVycwogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyYXdWYWx1ZSBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3KCRyYXdWYWx1ZSkKICAgIHsKICAgICAgICAKICAgICAgICAkcGFydHMgPSBleHBsb2RlKCIvIiwgc3Vic3RyKCRyYXdWYWx1ZSwgMSkpOwogICAgICAgICRmbGFncyA9IGFycmF5X3BvcCgkcGFydHMpOwogICAgICAgICR0aGlzLT5zZXRQYXR0ZXJuKGltcGxvZGUoIi8iLCAkcGFydHMpKTsKICAgICAgICAkdGhpcy0+c2V0RmxhZ3MoJGZsYWdzKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UmF3KCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBWYWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRSYXcoJHZhbHVlKTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGJsb2NrIG9mIGNvZGUgd3JhcHBlZCBpbiBjdXJseSBicmFjZXMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEJsb2NrU3RhdGVtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIFN0YXRlbWVudAp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgImJvZHkiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQmxvY2sncyBib2R5CiAgICAgKiAKICAgICAqIEB2YXIgU3RhdGVtZW50W10gCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keSA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBibG9jaydzIGJvZHkKICAgICAqIAogICAgICogQHJldHVybiBTdGF0ZW1lbnRbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9keSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5ib2R5OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgYmxvY2sncyBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnRbXSAkYm9keSBBcnJheSBvZiBTdGF0ZW1lbnRzIHRoYXQgYXJlIHRoZSBib2R5IG9mIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGJvZHksICJTdGF0ZW1lbnQiKTsKICAgICAgICAkdGhpcy0+Ym9keSA9ICRib2R5OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIGRvLXdoaWxlIGxvb3AuCiAqIEZvciBleGFtcGxlOiBkbyB7fSB3aGlsZSAodGVzdCkKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgRG9XaGlsZVN0YXRlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBTdGF0ZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJib2R5IiA9PiB0cnVlLAogICAgICAgICJ0ZXN0IiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSBsb29wIGJvZHkKICAgICAqIAogICAgICogQHZhciBTdGF0ZW1lbnQgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm9keTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgbG9vcCBjb25kaXRpb24KICAgICAqIAogICAgICogQHZhciBFeHByZXNzaW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJHRlc3Q7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gU3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCb2R5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmJvZHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbG9vcCBib2R5CiAgICAgKiAKICAgICAqIEBwYXJhbSBTdGF0ZW1lbnQgJGJvZHkgTG9vcCBib2R5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEJvZHkoU3RhdGVtZW50ICRib2R5KQogICAgewogICAgICAgICR0aGlzLT5ib2R5ID0gJGJvZHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VGVzdCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXN0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxvb3AgY29uZGl0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBFeHByZXNzaW9uICR0ZXN0IExvb3AKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VGVzdChFeHByZXNzaW9uICR0ZXN0KQogICAgewogICAgICAgICR0aGlzLT50ZXN0ID0gJHRlc3Q7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGVtcHR5IGV4cHJlc3Npb24uCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEVtcHR5RXhwcmVzc2lvbiBleHRlbmRzIE5vZGUKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBtZW1iZXIgZXhwcmVzc2lvbi4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYTWVtYmVyRXhwcmVzc2lvbiBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAib2JqZWN0IiA9PiB0cnVlLAogICAgICAgICJwcm9wZXJ0eSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEB2YXIgSlNYTWVtYmVyRXhwcmVzc2lvbnxKU1hJZGVudGlmaWVyIAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9iamVjdDsKICAgIAogICAgLyoqCiAgICAgKiBFeHByZXNzaW9uJ3MgcHJvcGVydHkKICAgICAqIAogICAgICogQHZhciBKU1hJZGVudGlmaWVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydHk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIG9iamVjdAogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWE1lbWJlckV4cHJlc3Npb258SlNYSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T2JqZWN0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm9iamVjdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBleHByZXNzaW9uJ3Mgb2JqZWN0CiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hNZW1iZXJFeHByZXNzaW9ufEpTWElkZW50aWZpZXIgJG9iamVjdCBPYmplY3QKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T2JqZWN0KCRvYmplY3QpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJG9iamVjdCwgYXJyYXkoIkpTWE1lbWJlckV4cHJlc3Npb24iLCAiSlNYSWRlbnRpZmllciIpKTsKICAgICAgICAkdGhpcy0+b2JqZWN0ID0gJG9iamVjdDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbidzIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UHJvcGVydHkoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cHJvcGVydHk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZXhwcmVzc2lvbidzIHByb3BlcnR5CiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyICRwcm9wZXJ0eSBQcm9wZXJ0eQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRQcm9wZXJ0eShKU1hJZGVudGlmaWVyICRwcm9wZXJ0eSkKICAgIHsKICAgICAgICAkdGhpcy0+cHJvcGVydHkgPSAkcHJvcGVydHk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcU3ByZWFkRWxlbWVudDsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIHNwcmVhZCBhdHRyaWJ1dGUuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWFNwcmVhZEF0dHJpYnV0ZSBleHRlbmRzIFNwcmVhZEVsZW1lbnQKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBjbG9zaW5nIGVsZW1lbnQgdGFnLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hDbG9zaW5nRWxlbWVudCBleHRlbmRzIEpTWEJvdW5kYXJ5RWxlbWVudAp7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxJZGVudGlmaWVyOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggaWRlbnRpZmllci4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYSWRlbnRpZmllciBleHRlbmRzIElkZW50aWZpZXIKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGNsb3NpbmcgZnJhZ21lbnQgdGFnLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hUZXh0IGV4dGVuZHMgTm9kZQp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInZhbHVlIiA9PiBmYWxzZSwKICAgICAgICAicmF3IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRyYXc7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBtaXhlZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBWYWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgICR0aGlzLT5yYXcgPSAkdmFsdWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSYXcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+cmF3OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbm9kZSdzIHJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHJhdyBSYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmF3KCRyYXcpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXRWYWx1ZSgkcmF3KTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9uOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggZWxlbWVudC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYRWxlbWVudCBleHRlbmRzIE5vZGUgaW1wbGVtZW50cyBFeHByZXNzaW9uCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAib3BlbmluZ0VsZW1lbnQiID0+IHRydWUsCiAgICAgICAgImNoaWxkcmVuIiA9PiB0cnVlLAogICAgICAgICJjbG9zaW5nRWxlbWVudCIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBPcGVuaW5nIGVsZW1lbnQgbm9kZQogICAgICogCiAgICAgKiBAdmFyIEpTWE9wZW5pbmdFbGVtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlbmluZ0VsZW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogQ2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBOb2RlW10KICAgICAqLwogICAgcHJvdGVjdGVkICRjaGlsZHJlbiA9IGFycmF5KCk7CiAgICAKICAgIC8qKgogICAgICogQ2xvc2luZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHZhciBKU1hDbG9zaW5nRWxlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2xvc2luZ0VsZW1lbnQ7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgb3BlbmluZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBKU1hPcGVuaW5nRWxlbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0T3BlbmluZ0VsZW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+b3BlbmluZ0VsZW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlbmluZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHBhcmFtIEpTWE9wZW5pbmdFbGVtZW50ICRvcGVuaW5nRWxlbWVudCBPcGVuaW5nIGVsZW1lbnQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRPcGVuaW5nRWxlbWVudChKU1hPcGVuaW5nRWxlbWVudCAkb3BlbmluZ0VsZW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPm9wZW5pbmdFbGVtZW50ID0gJG9wZW5pbmdFbGVtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZHJlbiBub2RlcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hpbGRyZW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hpbGRyZW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIE5vZGVbXSAkY2hpbGRyZW4gQ2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2hpbGRyZW4oJGNoaWxkcmVuKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjaGlsZHJlbiwgYXJyYXkoCiAgICAgICAgICAgICJKU1hUZXh0IiwgIkpTWEV4cHJlc3Npb25Db250YWluZXIiLCAiSlNYU3ByZWFkQ2hpbGQiLCAiSlNYRWxlbWVudCIsCiAgICAgICAgICAgICJKU1hGcmFnbWVudCIKICAgICAgICApKTsKICAgICAgICAkdGhpcy0+Y2hpbGRyZW4gPSAkY2hpbGRyZW47CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNsb3NpbmcgZWxlbWVudCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYQ2xvc2luZ0VsZW1lbnR8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xvc2luZ0VsZW1lbnQoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2xvc2luZ0VsZW1lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2xvc2luZyBlbGVtZW50IG5vZGUKICAgICAqIAogICAgICogQHBhcmFtIEpTWENsb3NpbmdFbGVtZW50fG51bGwgJGNsb3NpbmdFbGVtZW50IENsb3NpbmcgZWxlbWVudCBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENsb3NpbmdFbGVtZW50KCRjbG9zaW5nRWxlbWVudCkKICAgIHsKICAgICAgICAkdGhpcy0+YXNzZXJ0VHlwZSgkY2xvc2luZ0VsZW1lbnQsICJKU1hDbG9zaW5nRWxlbWVudCIsIHRydWUpOwogICAgICAgICR0aGlzLT5jbG9zaW5nRWxlbWVudCA9ICRjbG9zaW5nRWxlbWVudDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcRXhwcmVzc2lvbjsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIG5hbWVzcGFjZWQgbmFtZS4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYTmFtZXNwYWNlZE5hbWUgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgIm5hbWVzcGFjZSIgPT4gZmFsc2UsCiAgICAgICAgIm5hbWUiID0+IGZhbHNlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyBuYW1lc3BhY2UKICAgICAqIAogICAgICogQHZhciBKU1hJZGVudGlmaWVyCiAgICAgKi8KICAgIHByb3RlY3RlZCAkbmFtZXNwYWNlOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyBuYW1lCiAgICAgKiAKICAgICAqIEB2YXIgSlNYSWRlbnRpZmllcgogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgbmFtZXNwYWNlCiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYSWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZXNwYWNlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWVzcGFjZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyBuYW1lc3BhY2UKICAgICAqIAogICAgICogQHBhcmFtIEpTWElkZW50aWZpZXIgJG5hbWVzcGFjZSBOYW1lc3BhY2UKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TmFtZXNwYWNlKCRuYW1lc3BhY2UpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWVzcGFjZSA9ICRuYW1lc3BhY2U7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiBub2RlJ3MgbmFtZQogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWElkZW50aWZpZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bmFtZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyICRuYW1lIE5hbWUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TmFtZSgkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9uOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggZnJhZ21lbnQuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEZyYWdtZW50IGV4dGVuZHMgTm9kZSBpbXBsZW1lbnRzIEV4cHJlc3Npb24KewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJvcGVuaW5nRnJhZ21lbnQiID0+IHRydWUsCiAgICAgICAgImNoaWxkcmVuIiA9PiB0cnVlLAogICAgICAgICJjbG9zaW5nRnJhZ21lbnQiID0+IHRydWUKICAgICk7CiAgICAKICAgIC8qKgogICAgICogT3BlbmluZyBmcmFnbWVudCBub2RlCiAgICAgKiAKICAgICAqIEB2YXIgSlNYT3BlbmluZ0ZyYWdtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlbmluZ0ZyYWdtZW50OwogICAgCiAgICAvKioKICAgICAqIENoaWxkcmVuIG5vZGVzIGFycmF5CiAgICAgKiAKICAgICAqIEB2YXIgTm9kZVtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY2hpbGRyZW4gPSBhcnJheSgpOwogICAgCiAgICAvKioKICAgICAqIENsb3NpbmcgZnJhZ21lbnQgbm9kZQogICAgICogCiAgICAgKiBAdmFyIEpTWENsb3NpbmdGcmFnbWVudAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNsb3NpbmdGcmFnbWVudDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvcGVuaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBKU1hPcGVuaW5nRnJhZ21lbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE9wZW5pbmdGcmFnbWVudCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5vcGVuaW5nRnJhZ21lbnQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlbmluZyBmcmFnbWVudCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hPcGVuaW5nRnJhZ21lbnQgJG9wZW5pbmdGcmFnbWVudCBPcGVuaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlbmluZ0ZyYWdtZW50KEpTWE9wZW5pbmdGcmFnbWVudCAkb3BlbmluZ0ZyYWdtZW50KQogICAgewogICAgICAgICR0aGlzLT5vcGVuaW5nRnJhZ21lbnQgPSAkb3BlbmluZ0ZyYWdtZW50OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZHJlbiBub2RlcyBhcnJheQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGVbXQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2hpbGRyZW4oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2hpbGRyZW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHBhcmFtIE5vZGVbXSAkY2hpbGRyZW4gQ2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2hpbGRyZW4oJGNoaWxkcmVuKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjaGlsZHJlbiwgYXJyYXkoCiAgICAgICAgICAgICJKU1hUZXh0IiwgIkpTWEV4cHJlc3Npb25Db250YWluZXIiLCAiSlNYU3ByZWFkQ2hpbGQiLCAiSlNYRWxlbWVudCIsCiAgICAgICAgICAgICJKU1hGcmFnbWVudCIKICAgICAgICApKTsKICAgICAgICAkdGhpcy0+Y2hpbGRyZW4gPSAkY2hpbGRyZW47CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNsb3NpbmcgZnJhZ21lbnQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIEpTWENsb3NpbmdGcmFnbWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2xvc2luZ0ZyYWdtZW50KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmNsb3NpbmdGcmFnbWVudDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjbG9zaW5nIGZyYWdtZW50IG5vZGUKICAgICAqIAogICAgICogQHBhcmFtIEpTWENsb3NpbmdGcmFnbWVudCAkY2xvc2luZ0ZyYWdtZW50IENsb3NpbmcgZnJhZ21lbnQgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRDbG9zaW5nRnJhZ21lbnQoSlNYQ2xvc2luZ0ZyYWdtZW50ICRjbG9zaW5nRnJhZ21lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPmNsb3NpbmdGcmFnbWVudCA9ICRjbG9zaW5nRnJhZ21lbnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIHNwcmVhZCBjaGlsZCBleHByZXNzaW9uIGluIEpTWC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYU3ByZWFkQ2hpbGQgZXh0ZW5kcyBOb2RlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAiZXhwcmVzc2lvbiIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBUaGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEB2YXIgRXhwcmVzc2lvbgogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4cHJlc3Npb247CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBleHByZXNzaW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gRXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gRXhwcmVzc2lvbiAkZXhwcmVzc2lvbiBXcmFwcGVkZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gJGV4cHJlc3Npb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmV4cHJlc3Npb24gPSAkZXhwcmVzc2lvbjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFN5bnRheFxOb2RlXEpTWDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggb3BlbmluZyBmcmFnbWVudCB0YWcuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWE9wZW5pbmdGcmFnbWVudCBleHRlbmRzIE5vZGUKewp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGEgSlNYIGNsb3NpbmcgZnJhZ21lbnQgdGFnLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBKU1hDbG9zaW5nRnJhZ21lbnQgZXh0ZW5kcyBOb2RlCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CgovKioKICogQSBub2RlIHRoYXQgcmVwcmVzZW50cyBhIEpTWCBhdHRyaWJ1dGUuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIEpTWEF0dHJpYnV0ZSBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJuYW1lIiA9PiB0cnVlLAogICAgICAgICJ2YWx1ZSIgPT4gdHJ1ZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgbmFtZQogICAgICogCiAgICAgKiBAdmFyIEpTWElkZW50aWZpZXJ8SlNYTmFtZXNwYWNlZE5hbWUKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwogICAgCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSB2YWx1ZQogICAgICogCiAgICAgKiBAdmFyIE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gTm9kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TmFtZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyfEpTWE5hbWVzcGFjZWROYW1lICRuYW1lIEF0dHJpYnV0ZSBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoJG5hbWUsIGFycmF5KCJKU1hJZGVudGlmaWVyIiwgIkpTWE5hbWVzcGFjZWROYW1lIikpOwogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIE5vZGV8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VmFsdWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+dmFsdWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXR0cmlidXRlIHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBOb2RlfG51bGwgJHZhbHVlIEF0dHJpYnV0ZSB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICR2YWx1ZSwKICAgICAgICAgICAgYXJyYXkoCiAgICAgICAgICAgICAgICAiXFBlYXN0XFN5bnRheFxOb2RlXExpdGVyYWwiLCAiSlNYRXhwcmVzc2lvbkNvbnRhaW5lciIsCiAgICAgICAgICAgICAgICAiSlNYRWxlbWVudCIsICJKU1hGcmFnbWVudCIKICAgICAgICAgICAgKSwKICAgICAgICAgICAgdHJ1ZQogICAgICAgICk7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGVcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9uOwoKLyoqCiAqIEEgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBKU1ggb3BlbmluZyBlbGVtZW50IHRhZy4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYT3BlbmluZ0VsZW1lbnQgZXh0ZW5kcyBKU1hCb3VuZGFyeUVsZW1lbnQKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJhdHRyaWJ1dGVzIiA9PiB0cnVlLAogICAgICAgICJzZWxmQ2xvc2luZyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogQ2hpbGRyZW4gbm9kZXMgYXJyYXkKICAgICAqIAogICAgICogQHZhciBKU1hBdHRyaWJ1dGVbXXxKU1hTcHJlYWRBdHRyaWJ1dGVbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGF0dHJyaWJ1dGVzID0gYXJyYXkoKTsKICAgIAogICAgLyoqCiAgICAgKiBTZWxmIGNsb3NpbmcgdGFnIG1vZGUKICAgICAqIAogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2VsZkNsb3NpbmcgPSBmYWxzZTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZHJlbiBhdHRyaWJ1dGVzIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYQXR0cmlidXRlW118SlNYU3ByZWFkQXR0cmlidXRlW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEF0dHJpYnV0ZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YXR0cnJpYnV0ZXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgYXR0cmlidXRlcyBub2RlcyBhcnJheQogICAgICogCiAgICAgKiBAcGFyYW0gSlNYQXR0cmlidXRlW118SlNYU3ByZWFkQXR0cmlidXRlW10gJGF0dHJyaWJ1dGVzIEF0dHJyaWJ1dGVzIG5vZGVzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5CiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldEF0dHJpYnV0ZXMoJGF0dHJyaWJ1dGVzKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRhdHRycmlidXRlcywgYXJyYXkoCiAgICAgICAgICAgICJKU1hBdHRyaWJ1dGUiLCAiSlNYU3ByZWFkQXR0cmlidXRlIgogICAgICAgICkpOwogICAgICAgICR0aGlzLT5hdHRycmlidXRlcyA9ICRhdHRycmlidXRlczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2VsZiBjbG9zaW5nIHRhZyBtb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2VsZkNsb3NpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2VsZkNsb3Npbmc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc2VsZiBjbG9zaW5nIHRhZyBtb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBib29sICRzZWxmQ2xvc2luZyBTZWxmIGNsb3NpbmcgdGFnIG1vZGUKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0U2VsZkNsb3NpbmcoJHNlbGZDbG9zaW5nKQogICAgewogICAgICAgICR0aGlzLT5zZWxmQ2xvc2luZyA9IChib29sKSAkc2VsZkNsb3Npbmc7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIGJhc2UgY2xhc3MgZm9yIGJvdW5kYXJ5IGVsZW1lbnRzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIEpTWEJvdW5kYXJ5RWxlbWVudCBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJuYW1lIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIEVsZW1lbnQgbmFtZQogICAgICogCiAgICAgKiBAdmFyIEpTWElkZW50aWZpZXJ8SlNYTWVtYmVyRXhwcmVzc2lvbnxKU1hOYW1lc3BhY2VkTmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgJG5hbWU7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gSlNYSWRlbnRpZmllcnxKU1hNZW1iZXJFeHByZXNzaW9ufEpTWE5hbWVzcGFjZWROYW1lCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPm5hbWU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZWxlbWVudCBuYW1lCiAgICAgKiAKICAgICAqIEBwYXJhbSBKU1hJZGVudGlmaWVyfEpTWE1lbWJlckV4cHJlc3Npb258SlNYTmFtZXNwYWNlZE5hbWUgJG5hbWUgRWxlbWVudAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydFR5cGUoCiAgICAgICAgICAgICRuYW1lLAogICAgICAgICAgICBhcnJheSgiSlNYSWRlbnRpZmllciIsICJKU1hNZW1iZXJFeHByZXNzaW9uIiwgIkpTWE5hbWVzcGFjZWROYW1lIikKICAgICAgICApOwogICAgICAgICR0aGlzLT5uYW1lID0gJG5hbWU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZVxKU1g7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKCi8qKgogKiBBIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIGV4cHJlc3Npb24gY29udGFpbmVyIGluIEpTWC4KICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgSlNYRXhwcmVzc2lvbkNvbnRhaW5lciBleHRlbmRzIE5vZGUKewogICAgLyoqCiAgICAgKiBNYXAgb2Ygbm9kZSBwcm9wZXJ0aWVzCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkgCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJvcGVydGllc01hcCA9IGFycmF5KAogICAgICAgICJleHByZXNzaW9uIiA9PiB0cnVlCiAgICApOwogICAgCiAgICAvKioKICAgICAqIFRoZSB3cmFwcGVkIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHZhciBcUGVhc3RcU3ludGF4XE5vZGVcRXhwcmVzc2lvbnxKU1hFbXB0eUV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkICRleHByZXNzaW9uOwogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9ufEpTWEVtcHR5RXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5leHByZXNzaW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHdyYXBwZWQgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcGFyYW0gXFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb258SlNYRW1wdHlFeHByZXNzaW9uICRleHByZXNzaW9uIFdyYXBwZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRFeHByZXNzaW9uKCRleHByZXNzaW9uKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRUeXBlKAogICAgICAgICAgICAkZXhwcmVzc2lvbiwKICAgICAgICAgICAgYXJyYXkoIlxQZWFzdFxTeW50YXhcTm9kZVxFeHByZXNzaW9uIiwgIkpTWEVtcHR5RXhwcmVzc2lvbiIpCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+ZXhwcmVzc2lvbiA9ICRleHByZXNzaW9uOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU3ludGF4XE5vZGU7CgovKioKICogQmFzZSBjbGFzcyBmb3IgYWxsIHRoZSBub2RlcyBnZW5lcmF0ZWQgYnkgUGVhc3QuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICogCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgTm9kZSBpbXBsZW1lbnRzIFxKU09OU2VyaWFsaXphYmxlCnsKICAgIC8qKgogICAgICogTWFwIG9mIG5vZGUgcHJvcGVydGllcwogICAgICogCiAgICAgKiBAdmFyIGFycmF5IAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByb3BlcnRpZXNNYXAgPSBhcnJheSgKICAgICAgICAidHlwZSIgPT4gZmFsc2UsCiAgICAgICAgImxvY2F0aW9uIiA9PiBmYWxzZSwKICAgICAgICAibGVhZGluZ0NvbW1lbnRzIiA9PiBmYWxzZSwKICAgICAgICAidHJhaWxpbmdDb21tZW50cyIgPT4gZmFsc2UKICAgICk7CiAgICAKICAgIC8qKgogICAgICogTm9kZSBsb2NhdGlvbiBpbiB0aGUgc291cmNlIGNvZGUKICAgICAqIAogICAgICogQHZhciBcUGVhc3RcU3ludGF4XFNvdXJjZUxvY2F0aW9uIAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxvY2F0aW9uOwogICAgCiAgICAvKioKICAgICAqIExlYWRpbmcgY29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAdmFyIENvbW1lbnRbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGxlYWRpbmdDb21tZW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBUcmFpbGluZyBjb21tZW50cyBhcnJheQogICAgICoKICAgICAqIEB2YXIgQ29tbWVudFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdHJhaWxpbmdDb21tZW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoKQogICAgewogICAgICAgICR0aGlzLT5sb2NhdGlvbiA9IG5ldyBcUGVhc3RcU3ludGF4XFNvdXJjZUxvY2F0aW9uOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgbm9kZSB0eXBlCiAgICAgKiAKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUeXBlKCkKICAgIHsKICAgICAgICAkY2xhc3MgPSBleHBsb2RlKCJcXCIsIGdldF9jbGFzcygkdGhpcykpOwogICAgICAgIHJldHVybiBhcnJheV9wb3AoJGNsYXNzKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIGxlYWRpbmcgY29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAcGFyYW0gQ29tbWVudHNbXSAkY29tbWVudHMgQ29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRMZWFkaW5nQ29tbWVudHMoJGNvbW1lbnRzKQogICAgewogICAgICAgICR0aGlzLT5hc3NlcnRBcnJheU9mKCRjb21tZW50cywgIlxQZWFzdFxTeW50YXhcTm9kZVxDb21tZW50Iik7CiAgICAgICAgJHRoaXMtPmxlYWRpbmdDb21tZW50cyA9ICRjb21tZW50czsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGxlYWRpbmcgY29tbWVudHMgYXJyYXkKICAgICAqCiAgICAgKiBAcmV0dXJuIENvbW1lbnRzW10KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldExlYWRpbmdDb21tZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5sZWFkaW5nQ29tbWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRyYWlsaW5nIGNvbW1lbnRzIGFycmF5CiAgICAgKgogICAgICogQHBhcmFtIENvbW1lbnRzW10gJGNvbW1lbnRzIENvbW1lbnRzIGFycmF5CiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0VHJhaWxpbmdDb21tZW50cygkY29tbWVudHMpCiAgICB7CiAgICAgICAgJHRoaXMtPmFzc2VydEFycmF5T2YoJGNvbW1lbnRzLCAiXFBlYXN0XFN5bnRheFxOb2RlXENvbW1lbnQiKTsKICAgICAgICAkdGhpcy0+dHJhaWxpbmdDb21tZW50cyA9ICRjb21tZW50czsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRyYWlsaW5nIGNvbW1lbnRzIGFycmF5CiAgICAgKgogICAgICogQHJldHVybiBDb21tZW50c1tdCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUcmFpbGluZ0NvbW1lbnRzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnRyYWlsaW5nQ29tbWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUgbG9jYXRpb24gaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxTb3VyY2VMb2NhdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TG9jYXRpb24oKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+bG9jYXRpb247CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSBjb2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBcUGVhc3RcU3ludGF4XFBvc2l0aW9uICRwb3NpdGlvbiBTdGFydCBwb3NpdGlvbgogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGFydFBvc2l0aW9uKFxQZWFzdFxTeW50YXhcUG9zaXRpb24gJHBvc2l0aW9uKQogICAgewogICAgICAgICR0aGlzLT5sb2NhdGlvbi0+c2V0U3RhcnQoJHBvc2l0aW9uKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZW5kIHBvc2l0aW9uIG9mIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgY29kZQogICAgICogCiAgICAgKiBAcGFyYW0gXFBlYXN0XFN5bnRheFxQb3NpdGlvbiAkcG9zaXRpb24gU3RhcnQgcG9zaXRpb24KICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RW5kUG9zaXRpb24oXFBlYXN0XFN5bnRheFxQb3NpdGlvbiAkcG9zaXRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmxvY2F0aW9uLT5zZXRFbmQoJHBvc2l0aW9uKTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVHJhdmVyc2VzIHRoZSBjdXJyZW50IG5vZGUgYW5kIGFsbCBpdHMgY2hpbGQgbm9kZXMgdXNpbmcgdGhlIGdpdmVuCiAgICAgKiBmdW5jdGlvbgogICAgICogCiAgICAgKiBAcGFyYW0gY2FsbGFibGUgJGZuICAgICAgRnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCBvbiBlYWNoIG5vZGUKICAgICAqIEBwYXJhbSBhcnJheSAgICAkb3B0aW9ucyBPcHRpb25zIGFycmF5LiBTZWUgVHJhdmVyc2VyIGNsYXNzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvbiBmb3IgYXZhaWxhYmxlIG9wdGlvbnMKICAgICAqIAogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdHJhdmVyc2UoY2FsbGFibGUgJGZuLCAkb3B0aW9ucyA9IGFycmF5KCkpCiAgICB7CiAgICAgICAgJHRyYXZlcnNlciA9IG5ldyBcUGVhc3RcVHJhdmVyc2VyKCRvcHRpb25zKTsKICAgICAgICAkdHJhdmVyc2VyLT5hZGRGdW5jdGlvbigkZm4pLT50cmF2ZXJzZSgkdGhpcyk7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXJpYWxpemFibGUgdmVyc2lvbiBvZiB0aGUgbm9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBqc29uU2VyaWFsaXplKCkKICAgIHsKICAgICAgICAkcmV0ID0gYXJyYXkoKTsKICAgICAgICAkcHJvcHMgPSBcUGVhc3RcU3ludGF4XFV0aWxzOjpnZXROb2RlUHJvcGVydGllcygkdGhpcyk7CiAgICAgICAgZm9yZWFjaCAoJHByb3BzIGFzICRwcm9wKSB7CiAgICAgICAgICAgICRyZXRbJHByb3BbIm5hbWUiXV0gPSAkdGhpcy0+eyRwcm9wWyJnZXR0ZXIiXX0oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRyZXQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVuZGVycyB0aGUgY3VycmVudCBub2RlCiAgICAgKiAKICAgICAqIEBwYXJhbSBcUGVhc3RcRm9ybWF0dGVyXEJhc2UgJGZvcm1hdHRlciBGb3JtYXR0ZXIgdG8gdXNlIGZvciB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJpbmcKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlbmRlcihcUGVhc3RcRm9ybWF0dGVyXEJhc2UgJGZvcm1hdHRlcikKICAgIHsKICAgICAgICAkcmVuZGVyZXIgPSBuZXcgXFBlYXN0XFJlbmRlcmVyKCk7CiAgICAgICAgcmV0dXJuICRyZW5kZXJlci0+c2V0Rm9ybWF0dGVyKCRmb3JtYXR0ZXIpLT5yZW5kZXIoJHRoaXMpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgaXMgYW4gYXJyYXkgb2YgZGVmaW5lZCB0eXBlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAgICAgICAgJHBhcmFtcyAgICBWYWx1ZSB0byBjaGVjawogICAgICogQHBhcmFtIHN0cmluZ3xhcnJheSAkY2xhc3NlcyAgIENsYXNzIG9yIGFycmF5IG9mIGNsYXNzZXMgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHBhcmFtIGJvb2wgICAgICAgICAkYWxsb3dOdWxsIElmIHRydWUsIG51bGwgdmFsdWVzIGFyZSBhbGxvd2VkCiAgICAgKiAKICAgICAqIEByZXR1cm4gdm9pZAogICAgICogCiAgICAgKiBAY29kZUNvdmVyYWdlSWdub3JlCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBhc3NlcnRBcnJheU9mKCRwYXJhbXMsICRjbGFzc2VzLCAkYWxsb3dOdWxsID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkY2xhc3NlcykpIHsKICAgICAgICAgICAgJGNsYXNzZXMgPSBhcnJheSgkY2xhc3Nlcyk7CiAgICAgICAgfQogICAgICAgIGlmICghaXNfYXJyYXkoJHBhcmFtcykpIHsKICAgICAgICAgICAgJHRoaXMtPnR5cGVFcnJvcigkcGFyYW1zLCAkY2xhc3NlcywgJGFsbG93TnVsbCwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhcmFtcyBhcyAkcGFyYW0pIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjbGFzc2VzIGFzICRjbGFzcykgewogICAgICAgICAgICAgICAgICAgIGlmICgkcGFyYW0gPT09IG51bGwgJiYgJGFsbG93TnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjID0gJHRoaXMtPmFkZE5hbWVzcGFjZSgkY2xhc3MpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHBhcmFtIGluc3RhbmNlb2YgJGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+dHlwZUVycm9yKCRwYXJhbSwgJGNsYXNzZXMsICRhbGxvd051bGwsIHRydWUsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgcmVzcGVjdHMgdGhlIGRlZmluZWQgdHlwZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgICAgICAgICRwYXJhbSAgICAgVmFsdWUgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBzdHJpbmd8YXJyYXkgJGNsYXNzZXMgICBDbGFzcyBvciBhcnJheSBvZiBjbGFzc2VzIHRvIGNoZWNrIGFnYWluc3QKICAgICAqIEBwYXJhbSBib29sICAgICAgICAgJGFsbG93TnVsbCBJZiB0cnVlLCBudWxsIHZhbHVlcyBhcmUgYWxsb3dlZAogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIAogICAgICogQGNvZGVDb3ZlcmFnZUlnbm9yZQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXNzZXJ0VHlwZSgkcGFyYW0sICRjbGFzc2VzLCAkYWxsb3dOdWxsID0gZmFsc2UpCiAgICB7CiAgICAgICAgaWYgKCFpc19hcnJheSgkY2xhc3NlcykpIHsKICAgICAgICAgICAgJGNsYXNzZXMgPSBhcnJheSgkY2xhc3Nlcyk7CiAgICAgICAgfQogICAgICAgIGlmICgkcGFyYW0gPT09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCEkYWxsb3dOdWxsKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+dHlwZUVycm9yKCRwYXJhbSwgJGNsYXNzZXMsICRhbGxvd051bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yZWFjaCAoJGNsYXNzZXMgYXMgJGNsYXNzKSB7CiAgICAgICAgICAgICAgICAkYyA9ICR0aGlzLT5hZGROYW1lc3BhY2UoJGNsYXNzKTsKICAgICAgICAgICAgICAgIGlmICgkcGFyYW0gaW5zdGFuY2VvZiAkYykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+dHlwZUVycm9yKCRwYXJhbSwgJGNsYXNzZXMsICRhbGxvd051bGwpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBBZGRzIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGN1cnJlbnQgY2xhc3MgdG8gdGhlIGdpdmVuIGNsYXNzIG5hbWUKICAgICAqIAogICAgICogQHBhcmFtIHN0cmluZyAkY2xhc3MgQ2xhc3MgbmFtZSB0byBuYW1lc3BhY2UKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZE5hbWVzcGFjZSgkY2xhc3MpCiAgICB7CiAgICAgICAgaWYgKCRjbGFzc1swXSA9PT0gIlxcIikgewogICAgICAgICAgICByZXR1cm4gJGNsYXNzOwogICAgICAgIH0KICAgICAgICAkcGFydHMgPSBleHBsb2RlKCJcXCIsIGdldF9jbGFzcygkdGhpcykpOwogICAgICAgICRwYXJ0c1tjb3VudCgkcGFydHMpIC0xXSA9ICRjbGFzczsKICAgICAgICByZXR1cm4gaW1wbG9kZSgiXFwiLCAkcGFydHMpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRocm93cyBhbiBlcnJvciBpZiB0aGUgZGVmaW5lZCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgYgogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHBhcmFtICAgICAgICBUaGUgdmFsdWUgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBtaXhlZCAkYWxsb3dlZFR5cGVzIENsYXNzIG9yIGFycmF5IG9mIGNsYXNzZXMgdG8gY2hlY2sgYWdhaW5zdAogICAgICogQHBhcmFtIGJvb2wgICRhbGxvd051bGwgICAgSWYgdHJ1ZSwgbnVsbCB2YWx1ZXMgYXJlIGFsbG93ZWQKICAgICAqIEBwYXJhbSBib29sICAkYXJyYXkgICAgICAgIElmIHRydWUsIHRoZSB2YWx1ZSBtdXN0IGJlIGFuIGFycmF5CiAgICAgKiBAcGFyYW0gYm9vbCAgJGluQXJyYXkgICAgICBJZiB0cnVlLCB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgYnV0IHRoZSBjb250ZW50CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2VzIG5vdCByZXNwZWN0cyB0aGUgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqIAogICAgICogQHRocm93cyBcVHlwZUVycm9yCiAgICAgKiAKICAgICAqIEBjb2RlQ292ZXJhZ2VJZ25vcmUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHR5cGVFcnJvcigKICAgICAgICAkcGFyYW0sICRhbGxvd2VkVHlwZXMsICRhbGxvd051bGwgPSBmYWxzZSwgJGFycmF5ID0gZmFsc2UsCiAgICAgICAgJGluQXJyYXkgPSBmYWxzZQogICAgKSB7CiAgICAgICAgJGJhY2t0cmFjZSA9IGRlYnVnX2JhY2t0cmFjZShERUJVR19CQUNLVFJBQ0VfSUdOT1JFX0FSR1MpOwogICAgICAgICRtZXRob2QgPSAkYmFja3RyYWNlWzJdWyJjbGFzcyJdIC4gIjo6IiAuICRiYWNrdHJhY2VbMl1bImZ1bmN0aW9uIl07CiAgICAgICAgJG1zZyA9ICJBcmd1bWVudCAwIHBhc3NlZCB0byAkbWV0aG9kIG11c3QgYmUgIjsKICAgICAgICBpZiAoJGFycmF5KSB7CiAgICAgICAgICAgICRtc2cgLj0gImFuIGFycmF5IG9mICI7CiAgICAgICAgfQogICAgICAgICRtc2cgLj0gaW1wbG9kZSgiIG9yICIsICRhbGxvd2VkVHlwZXMpOwogICAgICAgIGlmICgkYWxsb3dOdWxsKSB7CiAgICAgICAgICAgICRtc2cgLj0gIiBvciBudWxsIjsKICAgICAgICB9CiAgICAgICAgaWYgKGlzX29iamVjdCgkcGFyYW0pKSB7CiAgICAgICAgICAgICRwYXJ0cyA9IGV4cGxvZGUoIlxcIiwgZ2V0X2NsYXNzKCRwYXJhbSkpOwogICAgICAgICAgICAkdHlwZSA9IGFycmF5X3BvcCgkcGFydHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0eXBlID0gZ2V0dHlwZSgkcGFyYW0pOwogICAgICAgIH0KICAgICAgICBpZiAoJGluQXJyYXkpIHsKICAgICAgICAgICAgJHR5cGUgPSAiYXJyYXkgb2YgJHR5cGUiOwogICAgICAgIH0KICAgICAgICAkbXNnIC49ICIsICR0eXBlIGdpdmVuIjsKICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwgJzcnLCAnPj0nKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgXFR5cGVFcnJvcigkbXNnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCRtc2csIEVfVVNFUl9FUlJPUik7CiAgICAgICAgfQogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcTm9kZTsKCi8qKgogKiBBYnN0cmFjdCBjbGFzcyBmb3IgbGl0ZXJhbHMuCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmFic3RyYWN0IGNsYXNzIExpdGVyYWwgZXh0ZW5kcyBOb2RlIGltcGxlbWVudHMgRXhwcmVzc2lvbgp7CiAgICAvKioKICAgICAqIE1hcCBvZiBub2RlIHByb3BlcnRpZXMKICAgICAqIAogICAgICogQHZhciBhcnJheSAKICAgICAqLwogICAgcHJvdGVjdGVkICRwcm9wZXJ0aWVzTWFwID0gYXJyYXkoCiAgICAgICAgInZhbHVlIiA9PiBmYWxzZSwKICAgICAgICAicmF3IiA9PiBmYWxzZQogICAgKTsKICAgIAogICAgLyoqCiAgICAgKiBOb2RlJ3MgdmFsdWUKICAgICAqIAogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlOwogICAgCiAgICAvKioKICAgICAqIE5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRyYXc7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBub2RlJ3MgdHlwZQogICAgICogCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHlwZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICJMaXRlcmFsIjsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuIG1peGVkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRWYWx1ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT52YWx1ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG5vZGUncyB2YWx1ZQogICAgICogCiAgICAgKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFZhbHVlCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIHNldFZhbHVlKCR2YWx1ZSk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIG5vZGUncyByYXcgdmFsdWUKICAgICAqIAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJhdygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5yYXc7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyBub2RlJ3MgcmF3IHZhbHVlCiAgICAgKiAKICAgICAqIEBwYXJhbSBtaXhlZCAkcmF3IFJhdyB2YWx1ZQogICAgICogCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRSYXcoJHJhdykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNldFZhbHVlKCRyYXcpOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxUb2tlbjsKCi8qKgogKiBKU1ggcGFyc2VyIHRyYWl0CiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCnRyYWl0IFBhcnNlcgp7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBKU1ggbm9kZQogICAgICogCiAgICAgKiBAcGFyYW0gc3RyaW5nICRub2RlVHlwZSBOb2RlJ3MgdHlwZQogICAgICogQHBhcmFtIG1peGVkICAkcG9zaXRpb24gTm9kZSdzIHN0YXJ0IHBvc2l0aW9uCiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXE5vZGUKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNyZWF0ZUpTWE5vZGUoJG5vZGVUeXBlLCAkcG9zaXRpb24pCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jcmVhdGVOb2RlKCJKU1hcXCRub2RlVHlwZSIsICRwb3NpdGlvbik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEganN4IGZyYWdtZW50CiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXEpTWFxKU1hGcmFnbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUpTWEZyYWdtZW50KCkKICAgIHsKICAgICAgICAkc3RhcnRPcGVuaW5nVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+Z2V0VG9rZW4oKTsKICAgICAgICBpZiAoISRzdGFydE9wZW5pbmdUb2tlbiB8fCAkc3RhcnRPcGVuaW5nVG9rZW4tPmdldFZhbHVlKCkgIT09ICI8IikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJGVuZE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXROZXh0VG9rZW4oKTsKICAgICAgICBpZiAoISRlbmRPcGVuaW5nVG9rZW4gfHwgJGVuZE9wZW5pbmdUb2tlbi0+Z2V0VmFsdWUoKSAhPT0gIj4iKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgICRjaGlsZHJlbiA9ICR0aGlzLT5wYXJzZUpTWENoaWxkcmVuKCk7CiAgICAgICAgCiAgICAgICAgaWYgKCEoJHN0YXJ0Q2xvc2luZ1Rva2VuID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIjwiKSkgfHwKICAgICAgICAgICAgISR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIvIikgfHwKICAgICAgICAgICAgISR0aGlzLT5zY2FubmVyLT5yZWNvbnN1bWVDdXJyZW50VG9rZW5JbkpTWE1vZGUoKSB8fAogICAgICAgICAgICAkZW5kT3BlbmluZ1Rva2VuLT5nZXRWYWx1ZSgpICE9PSAiPiIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgCiAgICAgICAgLy9PcGVuaW5nIHRhZwogICAgICAgICRvcGVuaW5nTm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKAogICAgICAgICAgICAiSlNYT3BlbmluZ0ZyYWdtZW50IiwKICAgICAgICAgICAgJHN0YXJ0T3BlbmluZ1Rva2VuCiAgICAgICAgKTsKICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKAogICAgICAgICAgICAkb3BlbmluZ05vZGUsCiAgICAgICAgICAgICRlbmRPcGVuaW5nVG9rZW4tPmdldExvY2F0aW9uKCktPmdldEVuZCgpCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICAvL0Nsb3NpbmcgdGFnCiAgICAgICAgJGNsb3NpbmdOb2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoCiAgICAgICAgICAgICJKU1hDbG9zaW5nRnJhZ21lbnQiLAogICAgICAgICAgICAkc3RhcnRDbG9zaW5nVG9rZW4KICAgICAgICApOwogICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJGNsb3NpbmdOb2RlKTsKICAgICAgICAKICAgICAgICAvL0ZyYWdtZW50CiAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYRnJhZ21lbnQiLCAkc3RhcnRPcGVuaW5nVG9rZW4pOwogICAgICAgICRub2RlLT5zZXRPcGVuaW5nRnJhZ21lbnQoJG9wZW5pbmdOb2RlKTsKICAgICAgICAkbm9kZS0+c2V0Q2xvc2luZ0ZyYWdtZW50KCRjbG9zaW5nTm9kZSk7CiAgICAgICAgaWYgKCRjaGlsZHJlbikgewogICAgICAgICAgICAkbm9kZS0+c2V0Q2hpbGRyZW4oJGNoaWxkcmVuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdyb3VwIG9mIGpzeCBjaGlsZHJlbgogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlW118bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hDaGlsZHJlbigpCiAgICB7CiAgICAgICAgJGNoaWxkcmVuID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoJGNoaWxkID0gJHRoaXMtPnBhcnNlSlNYQ2hpbGQoKSkgewogICAgICAgICAgICAkY2hpbGRyZW5bXSA9ICRjaGlsZDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvdW50KCRjaGlsZHJlbikgPyAkY2hpbGRyZW4gOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBjaGlsZAogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYQ2hpbGQoKQogICAgewogICAgICAgIGlmICgkbm9kZSA9ICR0aGlzLT5wYXJzZUpTWFRleHQoKSkgewogICAgICAgICAgICByZXR1cm4gJG5vZGU7CiAgICAgICAgfSBlbHNlaWYoJG5vZGUgPSAkdGhpcy0+cGFyc2VKU1hFbGVtZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuICRub2RlOwogICAgICAgIH0gZWxzZWlmICgkc3RhcnRUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpIHsKICAgICAgICAgICAgJHNwcmVhZCA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuLi4iKTsKICAgICAgICAgICAgJGV4cCA9ICR0aGlzLT5wYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICRtaWRQb3MgPSAkdGhpcy0+c2Nhbm5lci0+Z2V0UG9zaXRpb24oKTsKICAgICAgICAgICAgaWYgKCgkc3ByZWFkICYmICEkZXhwKSB8fCAhJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIn0iKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoCiAgICAgICAgICAgICAgICAkc3ByZWFkID8gIkpTWFNwcmVhZENoaWxkIiA6ICJKU1hFeHByZXNzaW9uQ29udGFpbmVyIiwKICAgICAgICAgICAgICAgICRzdGFydFRva2VuCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICghJGV4cCkgewogICAgICAgICAgICAgICAgJGV4cCA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hFbXB0eUV4cHJlc3Npb24iLCAkbWlkUG9zKTsKICAgICAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJGV4cCwgJG1pZFBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG5vZGUtPnNldEV4cHJlc3Npb24oJGV4cCk7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEganN4IHRleHQKICAgICAqIAogICAgICogQHJldHVybiBcUGVhc3RcU3ludGF4XE5vZGVcSlNYXEpTWFRleHR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hUZXh0KCkKICAgIHsKICAgICAgICBpZiAoISgkdG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuQXNKU1hUZXh0KCkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYVGV4dCIsICR0b2tlbik7CiAgICAgICAgJG5vZGUtPnNldFJhdygkdG9rZW4tPmdldFZhbHVlKCkpOwogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlLCAkdG9rZW4tPmdldExvY2F0aW9uKCktPmdldEVuZCgpKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggZWxlbWVudAogICAgICogCiAgICAgKiBAcmV0dXJuIFxQZWFzdFxTeW50YXhcTm9kZVxKU1hcSlNYRWxlbWVudHxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUpTWEVsZW1lbnQoKQogICAgewogICAgICAgICRzdGFydE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5nZXRUb2tlbigpOwogICAgICAgIGlmICghJHN0YXJ0T3BlbmluZ1Rva2VuIHx8ICRzdGFydE9wZW5pbmdUb2tlbi0+Z2V0VmFsdWUoKSAhPT0gIjwiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbmV4dFRva2VuID0gJHRoaXMtPnNjYW5uZXItPmdldE5leHRUb2tlbigpOwogICAgICAgIGlmICgkbmV4dFRva2VuICYmICRuZXh0VG9rZW4tPmdldFZhbHVlKCkgPT09ICIvIikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgIGlmICghKCRuYW1lID0gJHRoaXMtPnBhcnNlSlNYSWRlbnRpZmllck9yTWVtYmVyRXhwcmVzc2lvbigpKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgICRhdHRyaWJ1dGVzID0gJHRoaXMtPnBhcnNlSlNYQXR0cmlidXRlcygpOwogICAgICAgIAogICAgICAgICRzZWxmQ2xvc2luZyA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIvIik7CiAgICAgICAgCiAgICAgICAgJGVuZE9wZW5pbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5yZWNvbnN1bWVDdXJyZW50VG9rZW5JbkpTWE1vZGUoKTsKICAgICAgICBpZiAoISRlbmRPcGVuaW5nVG9rZW4gfHwgJGVuZE9wZW5pbmdUb2tlbi0+Z2V0VmFsdWUoKSAhPT0gIj4iKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgIGlmICghJHNlbGZDbG9zaW5nKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkY2hpbGRyZW4gPSAkdGhpcy0+cGFyc2VKU1hDaGlsZHJlbigpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgKCRzdGFydENsb3NpbmdUb2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCI8IikpICYmCiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiLyIpICYmCiAgICAgICAgICAgICAgICAoJGNsb3NpbmdOYW1lID0gJHRoaXMtPnBhcnNlSlNYSWRlbnRpZmllck9yTWVtYmVyRXhwcmVzc2lvbigpKSAmJgogICAgICAgICAgICAgICAgKCRlbmRDbG9zaW5nVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCkpICYmCiAgICAgICAgICAgICAgICAoJGVuZENsb3NpbmdUb2tlbi0+Z2V0VmFsdWUoKSA9PT0gIj4iKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPmlzU2FtZUpTWEVsZW1lbnROYW1lKCRuYW1lLCAkY2xvc2luZ05hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigiQ2xvc2luZyB0YWcgZG9lcyBub3QgbWF0Y2ggb3BlbmluZyB0YWciKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9PcGVuaW5nIHRhZwogICAgICAgICRvcGVuaW5nTm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKAogICAgICAgICAgICAiSlNYT3BlbmluZ0VsZW1lbnQiLAogICAgICAgICAgICAkc3RhcnRPcGVuaW5nVG9rZW4KICAgICAgICApOwogICAgICAgICRvcGVuaW5nTm9kZS0+c2V0TmFtZSgkbmFtZSk7CiAgICAgICAgJG9wZW5pbmdOb2RlLT5zZXRTZWxmQ2xvc2luZygkc2VsZkNsb3NpbmcpOwogICAgICAgIGlmICgkYXR0cmlidXRlcykgewogICAgICAgICAgICAkb3BlbmluZ05vZGUtPnNldEF0dHJpYnV0ZXMoJGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29tcGxldGVOb2RlKAogICAgICAgICAgICAkb3BlbmluZ05vZGUsCiAgICAgICAgICAgICRlbmRPcGVuaW5nVG9rZW4tPmdldExvY2F0aW9uKCktPmdldEVuZCgpCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICAvL0Nsb3NpbmcgdGFnCiAgICAgICAgJGNsb3NpbmdOb2RlID0gbnVsbDsKICAgICAgICBpZiAoISRzZWxmQ2xvc2luZykgewogICAgICAgICAgICAkY2xvc2luZ05vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgKICAgICAgICAgICAgICAgICJKU1hDbG9zaW5nRWxlbWVudCIsCiAgICAgICAgICAgICAgICAkc3RhcnRDbG9zaW5nVG9rZW4KICAgICAgICAgICAgKTsKICAgICAgICAgICAgJGNsb3NpbmdOb2RlLT5zZXROYW1lKCRjbG9zaW5nTmFtZSk7CiAgICAgICAgICAgICR0aGlzLT5jb21wbGV0ZU5vZGUoJGNsb3NpbmdOb2RlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9FbGVtZW50CiAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYRWxlbWVudCIsICRzdGFydE9wZW5pbmdUb2tlbik7CiAgICAgICAgJG5vZGUtPnNldE9wZW5pbmdFbGVtZW50KCRvcGVuaW5nTm9kZSk7CiAgICAgICAgaWYgKCRjbG9zaW5nTm9kZSkgewogICAgICAgICAgICAkbm9kZS0+c2V0Q2xvc2luZ0VsZW1lbnQoJGNsb3NpbmdOb2RlKTsKICAgICAgICAgICAgaWYgKCRjaGlsZHJlbikgewogICAgICAgICAgICAgICAgJG5vZGUtPnNldENoaWxkcmVuKCRjaGlsZHJlbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBpZGVudGlmaWVyLCBuYW1lc3BhY2VkIGlkZW50aWZpZXIgb3IgbWVtYmVyIGV4cHJlc3Npb24KICAgICAqIAogICAgICogQHBhcmFtIGJvb2wgJGFsbG93TWVtYmVyIFRydWUgdG8gYWxsb3cgbWVtYmVyIGV4cHJlc3Npb25zCiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXE5vZGV8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VKU1hJZGVudGlmaWVyT3JNZW1iZXJFeHByZXNzaW9uKCRhbGxvd01lbWJlciA9IHRydWUpCiAgICB7CiAgICAgICAgJGlkVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCk7CiAgICAgICAgaWYgKCEkaWRUb2tlbiB8fCAkaWRUb2tlbi0+Z2V0VHlwZSgpICE9PSBUb2tlbjo6VFlQRV9KU1hfSURFTlRJRklFUikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnNjYW5uZXItPmNvbnN1bWVUb2tlbigpOwogICAgICAgIAogICAgICAgICRpZE5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYSWRlbnRpZmllciIsICRpZFRva2VuKTsKICAgICAgICAkaWROb2RlLT5zZXROYW1lKCRpZFRva2VuLT5nZXRWYWx1ZSgpKTsKICAgICAgICAkaWROb2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkaWROb2RlKTsKICAgICAgICAKICAgICAgICAvL05hbWVzcGFjZWQgaWRlbnRpZmllcgogICAgICAgIGlmICgkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZSgiOiIpKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAkaWRUb2tlbjIgPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCk7CiAgICAgICAgICAgIGlmICghJGlkVG9rZW4yIHx8ICRpZFRva2VuMi0+Z2V0VHlwZSgpICE9PSBUb2tlbjo6VFlQRV9KU1hfSURFTlRJRklFUikgewogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRpZE5vZGUyID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWElkZW50aWZpZXIiLCAkaWRUb2tlbjIpOwogICAgICAgICAgICAkaWROb2RlMi0+c2V0TmFtZSgkaWRUb2tlbjItPmdldFZhbHVlKCkpOwogICAgICAgICAgICAkaWROb2RlMiA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJGlkTm9kZTIpOwogICAgICAgICAgICAKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYTmFtZXNwYWNlZE5hbWUiLCAkaWRUb2tlbik7CiAgICAgICAgICAgICRub2RlLT5zZXROYW1lc3BhY2UoJGlkTm9kZSk7CiAgICAgICAgICAgICRub2RlLT5zZXROYW1lKCRpZE5vZGUyKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9HZXQgZm9sbG93aW5nIGlkZW50aWZpZXJzCiAgICAgICAgJG5leHRJZHMgPSBhcnJheSgpOwogICAgICAgIGlmICgkYWxsb3dNZW1iZXIpIHsKICAgICAgICAgICAgd2hpbGUgKCR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuIikpIHsKICAgICAgICAgICAgICAgICRuZXh0SWQgPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCk7CiAgICAgICAgICAgICAgICBpZiAoISRuZXh0SWQgfHwgJG5leHRJZC0+Z2V0VHlwZSgpICE9PSBUb2tlbjo6VFlQRV9KU1hfSURFTlRJRklFUikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lVG9rZW4oKTsKICAgICAgICAgICAgICAgICRuZXh0SWRzW10gPSAkbmV4dElkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vQ3JlYXRlIHRoZSBtZW1iZXIgZXhwcmVzc2lvbiBpZiByZXF1aXJlZAogICAgICAgICRvYmplY3ROb2RlID0gJGlkTm9kZTsKICAgICAgICBmb3JlYWNoICgkbmV4dElkcyBhcyAkbmlkKSB7CiAgICAgICAgICAgICRwcm9wRW5kID0gJG5pZC0+Z2V0TG9jYXRpb24oKS0+Z2V0RW5kKCk7CiAgICAgICAgICAgICRwcm9wTm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hJZGVudGlmaWVyIiwgJG5pZCk7CiAgICAgICAgICAgICRwcm9wTm9kZS0+c2V0TmFtZSgkbmlkLT5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgJHByb3BOb2RlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkcHJvcE5vZGUsICRwcm9wRW5kKTsKICAgICAgICAgICAgCiAgICAgICAgICAgICRub2RlID0gJHRoaXMtPmNyZWF0ZUpTWE5vZGUoIkpTWE1lbWJlckV4cHJlc3Npb24iLCAkb2JqZWN0Tm9kZSk7CiAgICAgICAgICAgICRub2RlLT5zZXRPYmplY3QoJG9iamVjdE5vZGUpOwogICAgICAgICAgICAkbm9kZS0+c2V0UHJvcGVydHkoJHByb3BOb2RlKTsKICAgICAgICAgICAgJG9iamVjdE5vZGUgPSAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlLCAkcHJvcEVuZCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkb2JqZWN0Tm9kZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBqc3ggYXR0cmlidXRlcyBsaXN0CiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXE5vZGVbXXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUpTWEF0dHJpYnV0ZXMoKQogICAgewogICAgICAgICRhdHRyaWJ1dGVzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoCiAgICAgICAgICAgICgkYXR0ciA9ICR0aGlzLT5wYXJzZUpTWFNwcmVhZEF0dHJpYnV0ZSgpKSB8fAogICAgICAgICAgICAoJGF0dHIgPSAkdGhpcy0+cGFyc2VKU1hBdHRyaWJ1dGUoKSkKICAgICAgICApIHsKICAgICAgICAgICAgJGF0dHJpYnV0ZXNbXSA9ICRhdHRyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY291bnQoJGF0dHJpYnV0ZXMpID8gJGF0dHJpYnV0ZXMgOiBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGpzeCBzcHJlYWQgYXR0cmlidXRlCiAgICAgKiAKICAgICAqIEByZXR1cm4gXFBlYXN0XFN5bnRheFxOb2RlXEpTWFNwcmVhZEF0dHJpYnV0ZXxudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUpTWFNwcmVhZEF0dHJpYnV0ZSgpCiAgICB7CiAgICAgICAgaWYgKCEoJG9wZW5Ub2tlbiA9ICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ7IikpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCIuLi4iKSAmJgogICAgICAgICAgICAoJGV4cCA9ICR0aGlzLT5wYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCkpICYmCiAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ9IikKICAgICAgICApIHsKICAgICAgICAgICAgJG5vZGUgPSAkdGhpcy0+Y3JlYXRlSlNYTm9kZSgiSlNYU3ByZWFkQXR0cmlidXRlIiwgJG9wZW5Ub2tlbik7CiAgICAgICAgICAgICRub2RlLT5zZXRBcmd1bWVudCgkZXhwKTsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wbGV0ZU5vZGUoJG5vZGUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUGFyc2VzIGEganN4IHNwcmVhZCBhdHRyaWJ1dGUKICAgICAqIAogICAgICogQHJldHVybiBcUGVhc3RcU3ludGF4XE5vZGVcSlNYU3ByZWFkQXR0cmlidXRlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlSlNYQXR0cmlidXRlKCkKICAgIHsKICAgICAgICBpZiAoISgkbmFtZSA9ICR0aGlzLT5wYXJzZUpTWElkZW50aWZpZXJPck1lbWJlckV4cHJlc3Npb24oZmFsc2UpKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgJHZhbHVlID0gbnVsbDsKICAgICAgICBpZiAoJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoIj0iKSkgewogICAgICAgICAgICAkc3RyVG9rZW4gPSAkdGhpcy0+c2Nhbm5lci0+cmVjb25zdW1lQ3VycmVudFRva2VuSW5KU1hNb2RlKCk7CiAgICAgICAgICAgIGlmICgkc3RyVG9rZW4gJiYgJHN0clRva2VuLT5nZXRUeXBlKCkgPT09IFRva2VuOjpUWVBFX1NUUklOR19MSVRFUkFMKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2Nhbm5lci0+Y29uc3VtZVRva2VuKCk7CiAgICAgICAgICAgICAgICAkdmFsdWUgPSAkdGhpcy0+Y3JlYXRlTm9kZSgiU3RyaW5nTGl0ZXJhbCIsICRzdHJUb2tlbik7CiAgICAgICAgICAgICAgICAkdmFsdWUtPnNldFJhdygkc3RyVG9rZW4tPmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgJHZhbHVlID0gJHRoaXMtPmNvbXBsZXRlTm9kZSgkdmFsdWUpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXJ0RXhwID0gJHRoaXMtPnNjYW5uZXItPmNvbnN1bWUoInsiKSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKCRleHAgPSAkdGhpcy0+cGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpKSAmJgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5zY2FubmVyLT5jb25zdW1lKCJ9IikKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAiSlNYRXhwcmVzc2lvbkNvbnRhaW5lciIsCiAgICAgICAgICAgICAgICAgICAgICAgICRzdGFydEV4cAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlLT5zZXRFeHByZXNzaW9uKCRleHApOwogICAgICAgICAgICAgICAgICAgICR2YWx1ZSA9ICR0aGlzLT5jb21wbGV0ZU5vZGUoJHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5lcnJvcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0gZWxzZWlmICgKICAgICAgICAgICAgICAgICEoJHZhbHVlID0gJHRoaXMtPnBhcnNlSlNYRnJhZ21lbnQoKSkgJiYKICAgICAgICAgICAgICAgICEoJHZhbHVlID0gJHRoaXMtPnBhcnNlSlNYRWxlbWVudCgpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAkbm9kZSA9ICR0aGlzLT5jcmVhdGVKU1hOb2RlKCJKU1hBdHRyaWJ1dGUiLCAkbmFtZSk7CiAgICAgICAgJG5vZGUtPnNldE5hbWUoJG5hbWUpOwogICAgICAgIGlmICgkdmFsdWUpIHsKICAgICAgICAgICAgJG5vZGUtPnNldFZhbHVlKCR2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+Y29tcGxldGVOb2RlKCRub2RlKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVja3MgdGhhdCAyIHRhZyBuYW1lcyBhcmUgZXF1YWwKICAgICAqIAogICAgICogQHBhcmFtIFxQZWFzdFxTeW50YXhcTm9kZVxOb2RlICAgJG4xIEZpcnN0IG5hbWUKICAgICAqIEBwYXJhbSBcUGVhc3RcU3ludGF4XE5vZGVcTm9kZSAgICRuMSBTZWNvbmQgbmFtZQogICAgICogCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGlzU2FtZUpTWEVsZW1lbnROYW1lKCRuMSwgJG4yKQogICAgewogICAgICAgICR0eXBlID0gJG4xLT5nZXRUeXBlKCk7CiAgICAgICAgaWYgKCR0eXBlICE9PSAkbjItPmdldFR5cGUoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAiSlNYTmFtZXNwYWNlZE5hbWUiKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aXNTYW1lSlNYRWxlbWVudE5hbWUoCiAgICAgICAgICAgICAgICAkbjEtPmdldE5hbWVzcGFjZSgpLCAkbjItPmdldE5hbWVzcGFjZSgpCiAgICAgICAgICAgICkgJiYgJHRoaXMtPmlzU2FtZUpTWEVsZW1lbnROYW1lKAogICAgICAgICAgICAgICAgJG4xLT5nZXROYW1lKCksICRuMi0+Z2V0TmFtZSgpCiAgICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09PSAiSlNYTWVtYmVyRXhwcmVzc2lvbiIpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pc1NhbWVKU1hFbGVtZW50TmFtZSgKICAgICAgICAgICAgICAgICRuMS0+Z2V0T2JqZWN0KCksICRuMi0+Z2V0T2JqZWN0KCkKICAgICAgICAgICAgKSAmJiAkdGhpcy0+aXNTYW1lSlNYRWxlbWVudE5hbWUoCiAgICAgICAgICAgICAgICAkbjEtPmdldFByb3BlcnR5KCksICRuMi0+Z2V0UHJvcGVydHkoKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHR5cGUgPT09ICJKU1hJZGVudGlmaWVyIiAmJiAkbjEtPmdldE5hbWUoKSA9PT0gJG4yLT5nZXROYW1lKCk7CiAgICB9Cn0KPD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTeW50YXhcSlNYOwoKdXNlIFBlYXN0XFN5bnRheFxUb2tlbjsKCi8qKgogKiBKU1ggc2Nhbm5lciB0cmFpdAogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwp0cmFpdCBTY2FubmVyCnsKICAgIC8qKgogICAgICogVHJpZXMgdG8gcmVjb25zdW1lIHRoZSBjdXJyZW50IHRva2VuIGFzIGEganN4IHRleHQgaWYgcG9zc2libGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWNvbnN1bWVDdXJyZW50VG9rZW5Bc0pTWFRleHQoKQogICAgewogICAgICAgICR0aGlzLT5uZXh0VG9rZW4gPSBudWxsOwogICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBudWxsOwogICAgICAgICRzdGFydFBvc2l0aW9uID0gJHRoaXMtPmdldFBvc2l0aW9uKCk7CiAgICAgICAgJHRoaXMtPnNldFNjYW5Qb3NpdGlvbigkc3RhcnRQb3NpdGlvbik7CiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5jb25zdW1lVW50aWwoYXJyYXkoInsiLCAiPCIpLCBmYWxzZSwgZmFsc2UpOwogICAgICAgIGlmICgkcmVzdWx0KSB7CiAgICAgICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBuZXcgVG9rZW4oVG9rZW46OlRZUEVfSlNYX1RFWFQsICRyZXN1bHRbMF0pOwogICAgICAgICAgICAkdGhpcy0+Y3VycmVudFRva2VuLT5zZXRTdGFydFBvc2l0aW9uKCRzdGFydFBvc2l0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5zZXRFbmRQb3NpdGlvbigkdGhpcy0+Z2V0UG9zaXRpb24odHJ1ZSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPmN1cnJlbnRUb2tlbjsKICAgIH0KICAgIAogICAgCiAgICAvKioKICAgICAqIFJlY29uc3VtZXMgdGhlIGN1cnJlbnQgdG9rZW4gaW4ganN4IG1vZGUKICAgICAqIAogICAgICogQHJldHVybiBUb2tlbnxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWNvbnN1bWVDdXJyZW50VG9rZW5JbkpTWE1vZGUoKQogICAgewogICAgICAgICR0aGlzLT5qc3ggPSB0cnVlOwogICAgICAgICR0aGlzLT5uZXh0VG9rZW4gPSBudWxsOwogICAgICAgICR0aGlzLT5jdXJyZW50VG9rZW4gPSBudWxsOwogICAgICAgICRzdGFydFBvc2l0aW9uID0gJHRoaXMtPmdldFBvc2l0aW9uKCk7CiAgICAgICAgJHRoaXMtPnNldFNjYW5Qb3NpdGlvbigkc3RhcnRQb3NpdGlvbik7CiAgICAgICAgJHRva2VuID0gJHRoaXMtPmdldFRva2VuKCk7CiAgICAgICAgJHRoaXMtPmpzeCA9IGZhbHNlOwogICAgICAgIHJldHVybiAkdG9rZW47CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU3RyaW5nIHNjYW5uaW5nIG1ldGhvZCBpbiBqc3ggbW9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW5KU1hTdHJpbmcoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2NhblN0cmluZyhmYWxzZSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU3RyaW5nIHB1bmN0dXRhdG9yIG1ldGhvZCBpbiBqc3ggbW9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW5KU1hQdW5jdHV0YXRvcigpCiAgICB7CiAgICAgICAgLy9UaGUgIj4iIGNoYXJhY3RlciBpbiBqc3ggbW9kZSBtdXN0IGJlIGVtaXR0ZWQgaW4gaXRzIG93biB0b2tlbgogICAgICAgIC8vd2l0aG91dCBtYXRjaGluZyBsb25nZXIgc2VxdWVuY2VzIGxpa2UgIj4+IgogICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgIGlmICgkY2hhciA9PT0gIj4iKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAkdGhpcy0+Y29sdW1uKys7CiAgICAgICAgICAgIHJldHVybiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfUFVOQ1RVVEFUT1IsICRjaGFyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5zY2FuUHVuY3R1dGF0b3IoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJZGVudGlmaWVyIHNjYW5uaW5nIG1ldGhvZCBpbiBqc3ggbW9kZQogICAgICogCiAgICAgKiBAcmV0dXJuIFRva2VufG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW5KU1hJZGVudGlmaWVyKCkKICAgIHsKICAgICAgICAkYnVmZmVyID0gIiI7CiAgICAgICAgJGNoYXIgPSAkdGhpcy0+Y2hhckF0KCk7CiAgICAgICAgaWYgKCRjaGFyICE9PSBudWxsICYmICR0aGlzLT5pc0lkZW50aWZpZXJTdGFydCgkY2hhcikpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAkdGhpcy0+aW5kZXgrKzsKICAgICAgICAgICAgICAgICR0aGlzLT5jb2x1bW4rKzsKICAgICAgICAgICAgICAgICRjaGFyID0gJHRoaXMtPmNoYXJBdCgpOwogICAgICAgICAgICB9IHdoaWxlICgKICAgICAgICAgICAgICAgICRjaGFyICE9PSBudWxsICYmCiAgICAgICAgICAgICAgICAoJHRoaXMtPmlzSWRlbnRpZmllclBhcnQoJGNoYXIpIHx8ICRjaGFyID09PSAiLSIpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiAkYnVmZmVyID09PSAiIiA/IG51bGwgOiBuZXcgVG9rZW4oVG9rZW46OlRZUEVfSlNYX0lERU5USUZJRVIsICRidWZmZXIpOwogICAgfQp9Cjw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3Q7CgovKioKICogTm9kZXMgdHJhdmVyc2VyIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFRyYXZlcnNlcgp7CiAgICAvKioKICAgICAqIElmIGEgZnVuY3Rpb24gcmV0dXJuIHRoaXMgdmFsdWUsIHRoZSBjdXJyZW50IG5vZGUgd2lsbCBiZSByZW1vdmVkCiAgICAgKi8KICAgIGNvbnN0IFJFTU9WRV9OT0RFID0gMTsKICAgIAogICAgLyoqCiAgICAgKiBJZiBhIGZ1bmN0aW9uIHJldHVybiB0aGlzIHZhbHVlLCB0aGUgY3VycmVudCBub2RlJ3MgY2hpbGRyZW4gd29uJ3QgYmUKICAgICAqIHRyYXZlcnNlZAogICAgICovCiAgICBjb25zdCBET05UX1RSQVZFUlNFX0NISUxEX05PREVTID0gMjsKICAgIAogICAgLyoqCiAgICAgKiBJZiBhIGZ1bmN0aW9uIHJldHVybiB0aGlzIHZhbHVlLCB0aGUgdHJhdmVyc2VyIHdpbGwgc3RvcCBydW5uaW5nCiAgICAgKi8KICAgIGNvbnN0IFNUT1BfVFJBVkVSU0lORyA9IDQ7CiAgICAKICAgIC8qKgogICAgICogQXJyYXkgb2YgZnVuY3Rpb25zIHRvIGNhbGwgb24gZWFjaCBub2RlCiAgICAgKiAKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRmdW5jdGlvbnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogUGFzcyBwYXJlbnQgbm9kZSBmbGFnCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFzc1BhcmVudE5vZGUgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFNraXAgc3RhcnRpbmcgbm9kZSBmbGFnCiAgICAgKgogICAgICogQHZhciBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2tpcFN0YXJ0aW5nTm9kZSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IuIEF2YWlsYWJsZSBvcHRpb25zIGFyZToKICAgICAqIC0gc2tpcFN0YXJ0aW5nTm9kZTogaWYgdHJ1ZSB0aGUgc3RhcnRpbmcgbm9kZSB3aWxsIGJlIHNraXBwZWQKICAgICAqIC0gcGFzc1BhcmVudE5vZGU6IGlmIHRydWUgdGhlIHBhcmVudCBub2RlIG9mIGVhY2ggbm9kZSB3aWxsIGJlCiAgICAgKiAgIHBhc3NlZCBhcyBzZWNvbmQgYXJndW1lbnQgd2hlbiB0aGUgZnVuY3Rpb25zIGFyZSBjYWxsZWQuIE5vdGUKICAgICAqICAgdGhhdCB0aGUgcGFyZW50IG5vZGUgaXMgY2FsY3VsYXRlZCBkdXJpbmcgdHJhdmVyc2luZywgc28gZm9yCiAgICAgKiAgIHRoZSBzdGFydGluZyBub2RlIGl0IHdpbGwgYWx3YXlzIGJlIG51bGwuCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRvcHRpb25zIE9wdGlvbnMgYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoaXNzZXQoJG9wdGlvbnNbInBhc3NQYXJlbnROb2RlIl0pKSB7CiAgICAgICAgICAgICR0aGlzLT5wYXNzUGFyZW50Tm9kZSA9IChib29sKSAkb3B0aW9uc1sicGFzc1BhcmVudE5vZGUiXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRvcHRpb25zWyJza2lwU3RhcnRpbmdOb2RlIl0pKSB7CiAgICAgICAgICAgICR0aGlzLT5za2lwU3RhcnRpbmdOb2RlID0gKGJvb2wpICRvcHRpb25zWyJza2lwU3RhcnRpbmdOb2RlIl07CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEFkZHMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIGZvciBlYWNoIG5vZGUgaW4gdGhlIHRyZWUuIFRoZQogICAgICogZnVuY3Rpb24gd2lsbCByZWNlaXZlIHRoZSBjdXJyZW50IG5vZGUgYXMgYXJndW1lbnQuIFRoZSBhY3Rpb24gdGhhdCB3aWxsCiAgICAgKiBiZSBleGVjdXRlZCBvbiB0aGUgbm9kZSBieSB0aGUgdHJhdmVyc2VyIGRlcGVuZHMgb24gdGhlIHJldHVybmVkIHZhbHVlCiAgICAgKiBvZiB0aGUgZnVuY3Rpb246CiAgICAgKiAtIGEgbm9kZTogaXQgd2lsbCByZXBsYWNlIHRoZSBub2RlIHdpdGggdGhlIHJldHVybmVkIG9uZQogICAgICogLSBhIG51bWVyaWMgdmFsdWUgdGhhdCBpcyBhIGNvbWJpbmF0aW9uIG9mIHRoZSBjb25zdGFudHMgZGVmaW5lZCBpbiB0aGlzCiAgICAgKiAgIGNsYXNzOiBpdCB3aWxsIGV4ZWN1dGUgdGhlIGZ1bmN0aW9uIHJlbGF0ZWQgdG8gZWFjaCBjb25zdGFudAogICAgICogLSBhbiBhcnJheSB3aGVyZSB0aGUgZmlyc3QgZWxlbWVudCBpcyBhIG5vZGUgYW5kIHRoZSBzZWNvbmQgZWxlbWVudCBpcyBhCiAgICAgKiAgIG51bWVyaWMgdmFsdWUgdGhhdCBpcyBhIGNvbWJpbmF0aW9uIG9mIHRoZSBjb25zdGFudHMgZGVmaW5lZCBpbiB0aGlzCiAgICAgKiAgIGNsYXNzOiBpdCB3aWxsIHJlcGxhY2UgdGhlIG5vZGUgd2l0aCB0aGUgcmV0dXJuZWQgb25lIGFuZCAgaXQgd2lsbAogICAgICogICBleGVjdXRlIHRoZSBmdW5jdGlvbiByZWxhdGVkIHRvIGVhY2ggY29uc3RhbnQgKFJFTU9WRV9OT0RFIHdpbGwgYmUKICAgICAqICAgaWdub3JlZCBzaW5jZSBpdCBkb2VzIG5vdCBtYWtlIGFueSBzZW5zZSBpbiB0aGlzIGNhc2UpCiAgICAgKiAtIG90aGVyOiBub3RoaW5nCiAgICAgKiAKICAgICAqIEBwYXJhbSBjYWxsYWJsZSAkZm4gRnVuY3Rpb24gdG8gYWRkCiAgICAgKiAKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEZ1bmN0aW9uKGNhbGxhYmxlICRmbikKICAgIHsKICAgICAgICAkdGhpcy0+ZnVuY3Rpb25zW10gPSAkZm47CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFN0YXJ0cyB0aGUgdHJhdmVyc2luZwogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBTdGFydGluZyBub2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gU3ludGF4XE5vZGVcTm9kZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdHJhdmVyc2UoU3ludGF4XE5vZGVcTm9kZSAkbm9kZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnNraXBTdGFydGluZ05vZGUpIHsKICAgICAgICAgICAgJHRoaXMtPnRyYXZlcnNlQ2hpbGRyZW4oJG5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5leGVjRnVuY3Rpb25zKCRub2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRub2RlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIGFsbCBmdW5jdGlvbnMgb24gdGhlIGdpdmVuIG5vZGUgYW5kLCBpZiByZXF1aXJlZCwgc3RhcnRzCiAgICAgKiB0cmF2ZXJzaW5nIGl0cyBjaGlsZHJlbi4gVGhlIHJldHVybmVkIHZhbHVlIGlzIGFuIGFycmF5IHdoZXJlIHRoZSBmaXJzdAogICAgICogdmFsdWUgaXMgdGhlIG5vZGUgb3IgbnVsbCBpZiBpdCBoYXMgYmVlbiByZW1vdmVkIGFuZCB0aGUgc2Vjb25kIHZhbHVlIGlzCiAgICAgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgdHJhdmVyc2VyIG11c3QgY29udGludWUgdGhlIHRyYXZlcnNpbmcgb3Igbm90CiAgICAgKiAKICAgICAqIEBwYXJhbSBTeW50YXhcTm9kZVxOb2RlICAgICAgICRub2RlICAgICBOb2RlCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZXxudWxsICAkcGFyZW50ICAgUGFyZW50IG5vZGUKICAgICAqIAogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZXhlY0Z1bmN0aW9ucygkbm9kZSwgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRyYXZlcnNlQ2hpbGRyZW4gPSB0cnVlOwogICAgICAgICRjb250aW51ZVRyYXZlcnNpbmcgPSB0cnVlOwogICAgICAgIAogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5mdW5jdGlvbnMgYXMgJGZuKSB7CiAgICAgICAgICAgICRyZXQgPSAkdGhpcy0+cGFzc1BhcmVudE5vZGUgPyAkZm4oJG5vZGUsICRwYXJlbnQpIDogJGZuKCRub2RlKTsKICAgICAgICAgICAgaWYgKCRyZXQpIHsKICAgICAgICAgICAgICAgIGlmIChpc19hcnJheSgkcmV0KSAmJiAkcmV0WzBdIGluc3RhbmNlb2YgU3ludGF4XE5vZGVcTm9kZSkgewogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHJldFswXTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHJldFsxXSkgJiYgaXNfbnVtZXJpYygkcmV0WzFdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHJldFsxXSAmIHNlbGY6OkRPTlRfVFJBVkVSU0VfQ0hJTERfTk9ERVMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0cmF2ZXJzZUNoaWxkcmVuID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXRbMV0gJiBzZWxmOjpTVE9QX1RSQVZFUlNJTkcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250aW51ZVRyYXZlcnNpbmcgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcmV0IGluc3RhbmNlb2YgU3ludGF4XE5vZGVcTm9kZSkgewogICAgICAgICAgICAgICAgICAgICRub2RlID0gJHJldDsKICAgICAgICAgICAgICAgIH0gZWxzZWlmIChpc19udW1lcmljKCRyZXQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXQgJiBzZWxmOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0cmF2ZXJzZUNoaWxkcmVuID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgkcmV0ICYgc2VsZjo6U1RPUF9UUkFWRVJTSU5HKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb250aW51ZVRyYXZlcnNpbmcgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRyZXQgJiBzZWxmOjpSRU1PVkVfTk9ERSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbm9kZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICR0cmF2ZXJzZUNoaWxkcmVuID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoJHRyYXZlcnNlQ2hpbGRyZW4gJiYgJGNvbnRpbnVlVHJhdmVyc2luZykgewogICAgICAgICAgICAkY29udGludWVUcmF2ZXJzaW5nID0gJHRoaXMtPnRyYXZlcnNlQ2hpbGRyZW4oJG5vZGUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gYXJyYXkoJG5vZGUsICRjb250aW51ZVRyYXZlcnNpbmcpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRyYXZlcnNlcyBub2RlIGNoaWxkcmVuLiBJdCByZXR1cm5zIGEgYm9vbGVuYSBpbmRpY2F0aW5nIGlmIHRoZQogICAgICogdHJhdmVyc2luZyBtdXN0IGNvbnRpbnVlIG9yIG5vdAogICAgICogCiAgICAgKiBAcGFyYW0gU3ludGF4XE5vZGVcTm9kZSAgJG5vZGUgICBOb2RlCiAgICAgKiAKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gdHJhdmVyc2VDaGlsZHJlbihTeW50YXhcTm9kZVxOb2RlICRub2RlKQogICAgewogICAgICAgICRjb250aW51ZSA9IHRydWU7CiAgICAgICAgCiAgICAgICAgZm9yZWFjaCAoU3ludGF4XFV0aWxzOjpnZXROb2RlUHJvcGVydGllcygkbm9kZSwgdHJ1ZSkgYXMgJHByb3ApIHsKICAgICAgICAgICAgJGdldHRlciA9ICRwcm9wWyJnZXR0ZXIiXTsKICAgICAgICAgICAgJHNldHRlciA9ICRwcm9wWyJzZXR0ZXIiXTsKICAgICAgICAgICAgJGNoaWxkID0gJG5vZGUtPiRnZXR0ZXIoKTsKICAgICAgICAgICAgaWYgKCEkY2hpbGQpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9IGVsc2VpZiAoaXNfYXJyYXkoJGNoaWxkKSkgewogICAgICAgICAgICAgICAgJG5ld0NoaWxkcmVuID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRjaGlsZCBhcyAkYykgewogICAgICAgICAgICAgICAgICAgIGlmICghJGMgfHwgISRjb250aW51ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbmV3Q2hpbGRyZW5bXSA9ICRjOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoJGMsICRjb250aW51ZSkgPSAkdGhpcy0+ZXhlY0Z1bmN0aW9ucygkYywgJG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRuZXdDaGlsZHJlbltdID0gJGM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbm9kZS0+JHNldHRlcigkbmV3Q2hpbGRyZW4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGlzdCgkY2hpbGQsICRjb250aW51ZSkgPSAkdGhpcy0+ZXhlY0Z1bmN0aW9ucygkY2hpbGQsICRub2RlKTsKICAgICAgICAgICAgICAgICRub2RlLT4kc2V0dGVyKCRjaGlsZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICghJGNvbnRpbnVlKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gJGNvbnRpbnVlOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvcjsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIFNlbGVjdG9yIG1hdGNoZXMgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgTWF0Y2hlcwp7CiAgICAvKioKICAgICAqIE1hdGNoZXMgYXJyYXkKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkbWF0Y2hlczsKCiAgICAvKioKICAgICAqIENsYXNzIGNvbnN0cnVjdG9yCiAgICAgKgogICAgICogQHBhcmFtIGFycmF5ICRtYXRjaGVzIE1hdGNoZXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRtYXRjaGVzID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+bWF0Y2hlcyA9ICRtYXRjaGVzOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBtYXRjaAogICAgICoKICAgICAqIEBwYXJhbSBOb2RlICRub2RlCiAgICAgKiBAcGFyYW0gTm9kZXxudWxsICRwYXJlbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE1hdGNoKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPm1hdGNoZXNbXSA9IGFycmF5KCRub2RlLCAkcGFyZW50KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcmV0dXJucyBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TWF0Y2hlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5tYXRjaGVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWF0Y2hlZCBub2RlcwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE5vZGVzKCkgewogICAgICAgIHJldHVybiBhcnJheV9tYXAoZnVuY3Rpb24gKCRtKSB7CiAgICAgICAgICAgIHJldHVybiAkbVswXTsKICAgICAgICB9LCAkdGhpcy0+bWF0Y2hlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGaWx0ZXJzIHRoZSBtYXRjaGVzIHVzaW5nIHRoZSBnaXZlbiBmdW5jdGlvbiwgaWYgaXQgcmV0dXJucwogICAgICogYSBmYWxzZSB2YWx1ZSB0aGUgbWF0Y2ggd2lsbCBiZSByZW1vdmVkLiBUaGUgZnVuY3Rpb24gd2lsbAogICAgICogcmVjZWl2ZSB0aGUgbm9kZSBhbmQgaXRzIHBhcmVudCBhcyBhcmd1bWVudHMuCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRmbiBGaWx0ZXIgZnVuY3Rpb24KICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbHRlcihjYWxsYWJsZSAkZm4pCiAgICB7CiAgICAgICAgJG5ld01hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5tYXRjaGVzIGFzICRtYXRjaCkgewogICAgICAgICAgICBpZiAoJGZuKCRtYXRjaFswXSwgJG1hdGNoWzFdKSkgewogICAgICAgICAgICAgICAgJG5ld01hdGNoZXNbXSA9ICRtYXRjaDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+bWF0Y2hlcyA9ICRuZXdNYXRjaGVzOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcGxhY2VzIGFsbCB0aGUgbWF0Y2hlcyB3aXRoIHRoZSByZXN1bHQgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uLgogICAgICogVGhlIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgbm9kZSBhbmQgaXRzIHBhcmVudCBhcyBhcmd1bWVudHMKICAgICAqIGFuZCBtdXN0IHJldHVybiBhbiBhcnJheSBvZiBtYXRjaGVzCiAgICAgKgogICAgICogQHBhcmFtIGNhbGxhYmxlICRmbiBNYXAgZnVuY3Rpb24KICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBtYXAoY2FsbGFibGUgJGZuKQogICAgewogICAgICAgICRuZXdNYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+bWF0Y2hlcyBhcyAkbWF0Y2gpIHsKICAgICAgICAgICAgJHJlcyA9ICRmbigkbWF0Y2hbMF0sICRtYXRjaFsxXSk7CiAgICAgICAgICAgIGlmICgkcmVzKSB7CiAgICAgICAgICAgICAgICAkbmV3TWF0Y2hlcyA9IGFycmF5X21lcmdlKCRuZXdNYXRjaGVzLCAkcmVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+bWF0Y2hlcyA9ICRuZXdNYXRjaGVzOwogICAgICAgIHJldHVybiAkdGhpcy0+dW5pcXVlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZXMgdGhlIGN1cnJlbnQgb2JqZWN0IHdpdGggdGhlIG90aGVyIGdpdmVuIE1hdGNoZXMgb2JqZWN0cwogICAgICoKICAgICAqIEBwYXJhbSBNYXRjaGVzW10gJG1hdGNoZXNBcnIgQXJyYXkgb2YgTWF0Y2hlcyB0byBtZXJnZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1lcmdlKCRtYXRjaGVzQXJyKQogICAgewogICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzQXJyIGFzICRtYXRjaGVzKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRtYXRjaGVzLT5nZXRNYXRjaGVzKCkgYXMgJG1hdGNoKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+YWRkTWF0Y2goJG1hdGNoWzBdLCAkbWF0Y2hbMV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+dW5pcXVlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYWxsIGR1cGxpY2F0ZWQgbWF0Y2hlcwogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHVuaXF1ZSgpCiAgICB7CiAgICAgICAgJG5ld01hdGNoZXMgPSBhcnJheSgpOwogICAgICAgICRuZXdOb2RlcyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm1hdGNoZXMgYXMgJG1hdGNoKSB7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJG1hdGNoWzBdLCAkbmV3Tm9kZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAkbmV3TWF0Y2hlc1tdID0gJG1hdGNoOwogICAgICAgICAgICAgICAgJG5ld05vZGVzW10gPSAkbWF0Y2hbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJHRoaXMtPm1hdGNoZXMgPSAkbmV3TWF0Y2hlczsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhlIGN1cnJlbnQgb2JqZWN0CiAgICAgKgogICAgICogQHJldHVybiBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjcmVhdGVDbG9uZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBzZWxmKCR0aGlzLT5tYXRjaGVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBtYXRjaGVzCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNvdW50KCkKICAgIHsKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPm1hdGNoZXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWF0Y2ggYXQgdGhlIGdpdmVuIGluZGV4CiAgICAgKgogICAgICogQHBhcmFtIGludCAkaW5kZXggSW5kZXgKICAgICAqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKgogICAgICogQHRocm93cyBcRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXQoJGluZGV4KQogICAgewogICAgICAgICRpbmRleCA9IChpbnQpICRpbmRleDsKICAgICAgICBpZiAoIWlzc2V0KCR0aGlzLT5tYXRjaGVzWyRpbmRleF0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBcRXhjZXB0aW9uKCJJbnZhbGlkIGluZGV4ICRpbmRleCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPm1hdGNoZXNbJGluZGV4XTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3I7CgovKioKICogU2VsZWN0b3IgZXhjZXB0aW9uIGNsYXNzLiBTeW50YXggZXJyb3JzIGluIHNlbGVjdG9ycyBhcmUgdGhyb3duCiAqIHVzaW5nIHRoaXMgZXhjZXB0aW9uIGNsYXNzLgogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqIAogKiBAY29kZUNvdmVyYWdlSWdub3JlCiAqLwpjbGFzcyBFeGNlcHRpb24gZXh0ZW5kcyBcRXhjZXB0aW9uCnsKfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3I7CgovKioKICogU2VsZWN0b3IgcGFyc2VyIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFBhcnNlcgp7CiAgICAvKioKICAgICAqIFNlbGVjdG9yIHN0cmluZwogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2VsZWN0b3I7CgogICAgLyoqCiAgICAgKiBDdXJyZW50IHBhcnNlciBpbmRleAogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkaW5kZXggPSAwOwoKICAgIC8qKgogICAgICogU2VsZWN0b3IgbGVuZ3RoCiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRsZW5ndGg7CgogICAgLyoqCiAgICAgKiBXaGl0ZXNwYWNlcwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICR3aGl0ZXNwYWNlcyA9IGFycmF5KCIgIiwgIlx0IiwgIlxuIiwgIlxyIiwgIlxmIik7CgogICAgLyoqCiAgICAgKiBDb21iaW5hdG9ycwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRjb21iaW5hdG9ycyA9IGFycmF5KCI+IiwgIisiLCAifiIpOwoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHNlbGVjdG9yIG9wZXJhdG9yIGNoYXJhY3RlcnMKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXR0ck9wZXJhdG9yQ2hhcnMgPSBhcnJheSgiPSIsICI8IiwgIj4iLCAiXiIsICIkIiwgIioiKTsKCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSBzZWxlY3RvciBvcGVyYXRvcnMKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkYXR0ck9wZXJhdG9ycyA9IGFycmF5KCI9IiwgIjwiLCAiPiIsICI8PSIsICI+PSIsICJePSIsICIkPSIsICIqPSIpOwoKICAgIC8qKgogICAgICogVmFsaWQgcHNldWRvIHNlbGVjdG9ycy4gVGhlIHZhbHVlIGluZGljYXRlcyB0aGUgYXJndW1lbnQgdHlwZToKICAgICAqIC0gMDogbm8gYXJndW1lbnRzCiAgICAgKiAtIDE6IGluZGV4IGZvcm11bGEgKEFuK0Igc3ludGF4KQogICAgICogLSAyOiBzZWxlY3RvcgogICAgICogQHZhciBhcnJheQogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbGlkUHNldWRvID0gYXJyYXkoCiAgICAgICAgInBhdHRlcm4iID0+IDAsICJzdGF0ZW1lbnQiID0+IDAsICJleHByZXNzaW9uIiA9PiAwLCAiZGVjbGFyYXRpb24iID0+IDAsCiAgICAgICAgImZpcnN0LWNoaWxkIiA9PiAwLCAibGFzdC1jaGlsZCIgPT4gMCwKICAgICAgICAibnRoLWNoaWxkIiA9PiAxLCAibnRoLWxhc3QtY2hpbGQiID0+IDEsCiAgICAgICAgImhhcyIgPT4gMiwgImlzIiA9PiAyLCAibm90IiA9PiAyCiAgICApOwoKICAgIC8qKgogICAgICogQ2xhc3MgY29uc3RydWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzZWxlY3RvciAgU2VsZWN0b3Igc3RyaW5nCiAgICAgKiBAcGFyYW0gYXJyYXkgICRvcHRpb25zICAgT3B0aW9ucyBhcnJheS4gU2VlIFF1ZXJ5IGNsYXNzCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvbiBmb3IgYXZhaWxhYmxlIG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzZWxlY3RvciwgJG9wdGlvbnMgPSBhcnJheSgpKQogICAgewogICAgICAgICRlbmNvZGluZyA9IGlzc2V0KCRvcHRpb25zWyJlbmNvZGluZyJdKSA/ICRvcHRpb25zWyJlbmNvZGluZyJdIDogbnVsbDsKICAgICAgICBpZiAoJGVuY29kaW5nICYmICFwcmVnX21hdGNoKCIvVVRGLT84L2kiLCAkZW5jb2RpbmcpKSB7CiAgICAgICAgICAgICRzZWxlY3RvciA9IG1iX2NvbnZlcnRfZW5jb2RpbmcoJHNlbGVjdG9yLCAiVVRGLTgiLCAkZW5jb2RpbmcpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+c2VsZWN0b3IgPSAkc2VsZWN0b3I7CiAgICAgICAgJHRoaXMtPmxlbmd0aCA9IHN0cmxlbigkc2VsZWN0b3IpOwogICAgfQoKICAgIC8qKgogICAgICogU3RhcnRzIHRoZSBwYXJzaW5nIGFuZCByZXR1cm5zIHRoZSBwYXJzZWQgc2VsZWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZmlsdGVyIFRydWUgaWYgdGhlIHNlbGVjdG9yIG11c3QgYmUgdXNlZCBmb3IgYSBmaWx0ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcU2VsZWN0b3IKICAgICAqCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2UoJGZpbHRlciA9IGZhbHNlKQogICAgewogICAgICAgICRzZWxlY3RvciA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yKCRmaWx0ZXIpOwogICAgICAgIC8vVGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBlbmQgaGFzIG5vdCBiZWVuIHJlYWNoZWQKICAgICAgICBpZiAoKCRjaGFyID0gJHRoaXMtPmdldENoYXIoKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBzeW50YXggJyRjaGFyJyIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHNlbGVjdG9yOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgc2VsZWN0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbCAkZmlsdGVyIFRydWUgaWYgdGhlIHNlbGVjdG9yIG11c3QgYmUgdXNlZCBmb3IgYSBmaWx0ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcU2VsZWN0b3IKICAgICAqCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcGFyc2VTZWxlY3RvcigkZmlsdGVyID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHNlbGVjdG9yID0gbmV3IE5vZGVcU2VsZWN0b3I7CiAgICAgICAgZG8gewogICAgICAgICAgICAkZmlyc3QgPSB0cnVlOwogICAgICAgICAgICAkZ3JvdXAgPSBuZXcgTm9kZVxHcm91cDsKICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICRjb21iaW5hdG9yID0gJHRoaXMtPmNvbnN1bWVDb21iaW5hdG9yKCk7CiAgICAgICAgICAgICAgICBpZiAoISRmaXJzdCAmJiAhJGNvbWJpbmF0b3IpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYXJ0cyA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yUGFydHMoKTsKICAgICAgICAgICAgICAgIGlmICghY291bnQoJHBhcnRzKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIk1pc3Npbmcgc2VsZWN0b3IgYWZ0ZXIgY29tYmluYXRvciIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAkc2VsQ29tYmluYXRvciA9IG5ldyBOb2RlXENvbWJpbmF0b3I7CiAgICAgICAgICAgICAgICAkc2VsQ29tYmluYXRvci0+c2V0T3BlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgJGNvbWJpbmF0b3IgPyAkY29tYmluYXRvciA6ICgkZmlsdGVyID8gbnVsbCA6ICIgIikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkcGFydHMgYXMgJHBhcnQpIHsKICAgICAgICAgICAgICAgICAgICAkc2VsQ29tYmluYXRvci0+YWRkUGFydCgkcGFydCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZ3JvdXAtPmFkZENvbWJpbmF0b3IoJHNlbENvbWJpbmF0b3IpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRzZWxlY3Rvci0+YWRkR3JvdXAoJGdyb3VwKTsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgIH0gd2hpbGUgKCR0aGlzLT5jb25zdW1lKCIsIikpOwogICAgICAgIHJldHVybiAkc2VsZWN0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBzZXQgb2Ygc2VsZWN0b3IgcGF0cwogICAgICoKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VTZWxlY3RvclBhcnRzKCkKICAgIHsKICAgICAgICAkcGFydHMgPSBhcnJheSgpOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICgkcGFydCA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yUGFydFR5cGUoKSkgfHwKICAgICAgICAgICAgICAgICgkcGFydCA9ICR0aGlzLT5wYXJzZVNlbGVjdG9yUGFydEF0dHJpYnV0ZSgpKSB8fAogICAgICAgICAgICAgICAgKCRwYXJ0ID0gJHRoaXMtPnBhcnNlU2VsZWN0b3JQYXJ0UHNldWRvKCkpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJHBhcnRzW10gPSAkcGFydDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcGFydHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSB0eXBlIHNlbGVjdG9yIHBhcnQKICAgICAqCiAgICAgKiBAcmV0dXJuIE5vZGVcUGFydFxUeXBlfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU2VsZWN0b3JQYXJ0VHlwZSgpCiAgICB7CiAgICAgICAgJHR5cGUgPSAkdGhpcy0+Y29uc3VtZVdvcmQoKTsKICAgICAgICBpZiAoJHR5cGUpIHsKICAgICAgICAgICAgJHBhcnQgPSBuZXcgTm9kZVxQYXJ0XFR5cGU7CiAgICAgICAgICAgICRwYXJ0LT5zZXRUeXBlKCR0eXBlKTsKICAgICAgICAgICAgcmV0dXJuICRwYXJ0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlcyBhbiBhdHRyaWJ1dGUgc2VsZWN0b3IgcGFydAogICAgICoKICAgICAqIEByZXR1cm4gTm9kZVxQYXJ0XEF0dHJpYnV0ZXxudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU2VsZWN0b3JQYXJ0QXR0cmlidXRlKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5jb25zdW1lKCJbIikpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICAkcGFydCA9IG5ldyBOb2RlXFBhcnRcQXR0cmlidXRlOwogICAgICAgIGlmICghKCRuYW1lID0gJHRoaXMtPmNvbnN1bWVXb3JkKCkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIk1pc3NpbmcgYXR0cmlidXRlIG5hbWUiKTsKICAgICAgICB9CiAgICAgICAgJHBhcnQtPmFkZE5hbWUoJG5hbWUpOwogICAgICAgIHdoaWxlICgkdGhpcy0+Y29uc3VtZSgiLiIpKSB7CiAgICAgICAgICAgIGlmICghKCRuYW1lID0gJHRoaXMtPmNvbnN1bWVXb3JkKCkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJNaXNzaW5nIGF0dHJpYnV0ZSBuYW1lIGFmdGVyIGRvdCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYXJ0LT5hZGROYW1lKCRuYW1lKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgICRvcGVyYXRvciA9ICR0aGlzLT5jb25zdW1lQW55KCR0aGlzLT5hdHRyT3BlcmF0b3JDaGFycyk7CiAgICAgICAgaWYgKCRvcGVyYXRvcikgewogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRvcGVyYXRvciwgJHRoaXMtPmF0dHJPcGVyYXRvcnMpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJJbnZhbGlkIGF0dHJpYnV0ZSBvcGVyYXRvciAnJG9wZXJhdG9yJyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRwYXJ0LT5zZXRPcGVyYXRvcigkb3BlcmF0b3IpOwogICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgICAgIGlmICghKCR2YWx1ZSA9ICR0aGlzLT5wYXJzZUxpdGVyYWwoKSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIk1pc3NpbmcgYXR0cmlidXRlIHZhbHVlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBhcnQtPnNldFZhbHVlKCR2YWx1ZVswXSk7CiAgICAgICAgICAgIGlmICgkdmFsdWVbMV0pIHsKICAgICAgICAgICAgICAgIGlmICgkb3BlcmF0b3IgIT0gIj0iKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIk9ubHkgJz0nIG9wZXJhdG9yIGlzIHZhbGlkIGZvciBhdHRyaWJ1dGUgcmVnZXggbWF0Y2giCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRSZWdleCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdGhpcy0+Y29uc3VtZVdoaXRlc3BhY2VzKCk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+Y29uc3VtZSgiaSIpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzX3N0cmluZygkdmFsdWVbMF0pIHx8ICR2YWx1ZVsxXSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJDYXNlIGluc2Vuc2l0aXZlIGZsYWcgY2FuIGJlIHVzZWQgb25seSBmb3Igc3RyaW5nIHZhbHVlcyIKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHBhcnQtPnNldENhc2VJbnNlbnNpdGl2ZSh0cnVlKTsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoISR0aGlzLT5jb25zdW1lKCJdIikpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIGF0dHJpYnV0ZSBzZWxlY3RvciIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBwc2V1ZG8gc2VsZWN0b3IgcGFydAogICAgICoKICAgICAqIEByZXR1cm4gTm9kZVxQYXJ0XFBzZXVkb3xudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlU2VsZWN0b3JQYXJ0UHNldWRvKCkKICAgIHsKICAgICAgICBpZiAoISR0aGlzLT5jb25zdW1lKCI6IikpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgICRuYW1lID0gJHRoaXMtPmNvbnN1bWVXb3JkKCItIik7CiAgICAgICAgaWYgKCFpc3NldCgkdGhpcy0+dmFsaWRQc2V1ZG9bJG5hbWVdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBwc2V1ZG8gc2VsZWN0b3IgJyRuYW1lJyIpOwogICAgICAgIH0KICAgICAgICAkYXJnc1R5cGUgPSAkdGhpcy0+dmFsaWRQc2V1ZG9bJG5hbWVdOwogICAgICAgICRlcnJvciA9IGZhbHNlOwogICAgICAgIGlmICgkYXJnc1R5cGUgPT09IDEpIHsKICAgICAgICAgICAgJHBhcnQgPSBuZXcgTm9kZVxQYXJ0XFBzZXVkb0luZGV4OwogICAgICAgICAgICBpZiAoISR0aGlzLT5jb25zdW1lKCIoIikpIHsKICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCEkZXJyb3IpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICAgICAgICAgIGlmICgkaW5kaWNlcyA9ICR0aGlzLT5jb25zdW1lUmVnZXgoIi0/XGQqbig/OlwrXGQrKT98XGQrIikpIHsKICAgICAgICAgICAgICAgICAgICAkaW5kaWNlcyA9IGV4cGxvZGUoIm4iLCAkaW5kaWNlcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50KCRpbmRpY2VzKSA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFydC0+c2V0T2Zmc2V0KChpbnQpICRpbmRpY2VzWzBdKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCRpbmRpY2VzWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICIiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0LT5zZXRTdGVwKDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICItIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFydC0+c2V0U3RlcCgtMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldFN0ZXAoKGludCkgJGluZGljZXNbMF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRpbmRpY2VzWzFdICE9PSAiIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldE9mZnNldCgoaW50KSAkaW5kaWNlc1sxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoCiAgICAgICAgICAgICAgICAgICAgKCR3b3JkID0gJHRoaXMtPmNvbnN1bWVXb3JkKCkpICYmCiAgICAgICAgICAgICAgICAgICAgKCR3b3JkID09PSAiZXZlbiIgfHwgJHdvcmQgPT09ICJvZGQiKQogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhcnQtPnNldFN0ZXAoMik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR3b3JkID09PSAib2RkIikgewogICAgICAgICAgICAgICAgICAgICAgICAkcGFydC0+c2V0T2Zmc2V0KDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5jb25zdW1lV2hpdGVzcGFjZXMoKTsKICAgICAgICAgICAgICAgIGlmICghJGVycm9yICYmICEkdGhpcy0+Y29uc3VtZSgiKSIpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkYXJnc1R5cGUgPT09IDIpIHsKICAgICAgICAgICAgJHBhcnQgPSBuZXcgTm9kZVxQYXJ0XFBzZXVkb1NlbGVjdG9yOwogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAkdGhpcy0+Y29uc3VtZSgiKCIpICYmCiAgICAgICAgICAgICAgICAoJHNlbGVjdG9yID0gJHRoaXMtPnBhcnNlU2VsZWN0b3IoJG5hbWUgIT09ICJoYXMiKSkgJiYKICAgICAgICAgICAgICAgICR0aGlzLT5jb25zdW1lKCIpIikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkcGFydC0+c2V0U2VsZWN0b3IoJHNlbGVjdG9yKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRlcnJvciA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFydCA9IG5ldyBOb2RlXFBhcnRcUHNldWRvU2ltcGxlOwogICAgICAgIH0KICAgICAgICBpZiAoJGVycm9yKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBhcmd1bWVudCBmb3IgcHNldWRvIHNlbGVjdG9yICckbmFtZSciCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgICRwYXJ0LT5zZXROYW1lKCRuYW1lKTsKICAgICAgICByZXR1cm4gJHBhcnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsIHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbCgpCiAgICB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAoJGxpdGVyYWwgPSAkdGhpcy0+cGFyc2VMaXRlcmFsQm9vbE51bGwoKSkgIT09IDAgfHwKICAgICAgICAgICAgKCRsaXRlcmFsID0gJHRoaXMtPnBhcnNlTGl0ZXJhbFN0cmluZygpKSAhPT0gbnVsbCB8fAogICAgICAgICAgICAoJGxpdGVyYWwgPSAkdGhpcy0+cGFyc2VMaXRlcmFsTnVtYmVyKCkpICE9PSBudWxsCiAgICAgICAgKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbGl0ZXJhbCwgZmFsc2UpOwogICAgICAgIH0gZWxzZWlmICgkbGl0ZXJhbCA9ICR0aGlzLT5wYXJzZUxpdGVyYWxSZWdleCgpKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkbGl0ZXJhbCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGl0ZXJhbCBib29sZWFuIG9yIG51bGwgdmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbEJvb2xOdWxsKCkKICAgIHsKICAgICAgICAkd29yZCA9ICR0aGlzLT5jb25zdW1lV29yZCgpOwogICAgICAgIGlmICghJHdvcmQpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlaWYgKCR3b3JkID09PSAidHJ1ZSIpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlaWYgKCR3b3JkID09PSAiZmFsc2UiKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2VpZiAoJHdvcmQgPT09ICJudWxsIikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW52YWxpZCBhdHRyaWJ1dGUgdmFsdWUgJyR3b3JkJyIpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGl0ZXJhbCBzdHJpbmcKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKgogICAgICogQHRocm93cyBFeGNlcHRpb24KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbFN0cmluZygpCiAgICB7CiAgICAgICAgaWYgKCEoJHF1b3RlID0gJHRoaXMtPmNvbnN1bWVBbnkoYXJyYXkoIiciLCAnIicpLCB0cnVlKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGlmICgoJHN0ciA9ICR0aGlzLT5jb25zdW1lVW50aWwoJHF1b3RlKSkgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHN0cmluZyBpbiBhdHRyaWJ1dGUgdmFsdWUiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRzdHI7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsIG51bWJlcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbE51bWJlcigpCiAgICB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAkdGhpcy0+Z2V0Q2hhcigpID09PSAiMCIgJiYKICAgICAgICAgICAgKCR2YWwgPSAkdGhpcy0+Y29uc3VtZVJlZ2V4KCIwW3hYXVthLWZBLUZdK3wwW2JCXVswMV0rfDBbb09dWzAtN10rIikpCiAgICAgICAgKSB7CiAgICAgICAgICAgICRmb3JtID0gc3RydG9sb3dlcigkdmFsWzFdKTsKICAgICAgICAgICAgJHZhbCA9IHN1YnN0cigkdmFsLCAyKTsKICAgICAgICAgICAgaWYgKCRmb3JtID09PSAieCIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoZXhkZWMoJHZhbCk7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZm9ybSA9PT0gIm8iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2N0ZGVjKCR2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBiaW5kZWMoJHZhbCk7CiAgICAgICAgfQogICAgICAgICRyZWcgPSAiLT9cZCsoPzpcLlxkKyk/KD86W2VFXVsrLV0/XGQrKT98LT9cLlxkKyg/OltlRV1bKy1dP1xkKyk/IjsKICAgICAgICBpZiAoISgkdmFsID0gJHRoaXMtPmNvbnN1bWVSZWdleCgkcmVnKSkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoZmxvYXQpICR2YWw7CiAgICB9CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBsaXRlcmFsIHJlZ2V4CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBwYXJzZUxpdGVyYWxSZWdleCgpCiAgICB7CiAgICAgICAgaWYgKCEoJHNlcCA9ICR0aGlzLT5jb25zdW1lKCIvIikpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAoKCRyZWcgPSAkdGhpcy0+Y29uc3VtZVVudGlsKCRzZXAsIGZhbHNlLCB0cnVlKSkgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHJlZ2V4IGluIGF0dHJpYnV0ZSB2YWx1ZSIpOwogICAgICAgIH0KICAgICAgICAkbW9kaWZpZXJzID0gJHRoaXMtPmNvbnN1bWVXb3JkKCk7CiAgICAgICAgcmV0dXJuICRzZXAgLiAkcmVnIC4gKCRtb2RpZmllcnMgPyAkbW9kaWZpZXJzIDogIiIpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgdGhlIGdpdmVuIHJlZ2V4CiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkcmVnZXggUmVnZXggdG8gY29uc3VtZQogICAgICoKICAgICAqIEByZXR1cm4gbWl4ZWR8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uc3VtZVJlZ2V4KCRyZWdleCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdldENoYXIoKSA9PT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCIjXigkcmVnZXgpIyIsIHN1YnN0cigkdGhpcy0+c2VsZWN0b3IsICR0aGlzLT5pbmRleCksICRtYXRjaGVzKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmluZGV4ICs9IHN0cmxlbigkbWF0Y2hlc1sxXSk7CiAgICAgICAgcmV0dXJuICRtYXRjaGVzWzFdOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgYWxsIHRoZSBjaGFyYWN0ZXJzIHVudGlsIHRoZSBnaXZlbiBvbmUgaXMgcmVhY2hlZAogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0b3AgICAgICAgICAgU3RvcCBjaGFyYWN0ZXIKICAgICAqIEBwYXJhbSBib29sICAgJHJlbW92ZUVzY2FwZXMgSWYgZmFsc2UgZXNjYXBlIGNoYXJhY3RlcnMgd29uJ3QgYmUgcmVtb3ZlZAogICAgICogQHBhcmFtIGZhbHNlICAkaW5jbHVkZVN0b3AgICBJZiB0cnVlIHN0b3AgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xudWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb25zdW1lVW50aWwoJHN0b3AsICRyZW1vdmVFc2NhcGVzID0gdHJ1ZSwgJGluY2x1ZGVTdG9wID0gZmFsc2UpCiAgICB7CiAgICAgICAgJGJ1ZmZlciA9ICIiOwogICAgICAgICRlc2NhcGVkID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5nZXRDaGFyKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICR0aGlzLT5pbmRleCArPSAxOwogICAgICAgICAgICBpZiAoISRlc2NhcGVkKSB7CiAgICAgICAgICAgICAgICBpZiAoJGNoYXIgPT09ICJcXCIpIHsKICAgICAgICAgICAgICAgICAgICAkZXNjYXBlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkcmVtb3ZlRXNjYXBlcykgewogICAgICAgICAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkY2hhciA9PT0gJHN0b3ApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJGluY2x1ZGVTdG9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRidWZmZXIgLj0gJGNoYXI7CiAgICAgICAgICAgICRlc2NhcGVkID0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3VtZXMgYSB3b3JkIGNvbXBvc2VkIGJ5IGNoYXJhY3RlcnMgYS16CiAgICAgKgogICAgICogQHBhcmFtIG51bGx8c3RyaW5nICRleHRyYUNoYXIgRXh0cmEgY2hhcmFjdGVyIHRvIG1hdGNoCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVXb3JkKCRleHRyYUNoYXIgPSBudWxsKQogICAgewogICAgICAgICRidWZmZXIgPSAiIjsKICAgICAgICB3aGlsZSAoJGNoYXIgPSAkdGhpcy0+Z2V0Q2hhcigpKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICgkY2hhciA+PSAiYSIgJiYgJGNoYXIgPD0gInoiKSB8fAogICAgICAgICAgICAgICAgKCRjaGFyID49ICJBIiAmJiAkY2hhciA8PSAiWiIpIHx8CiAgICAgICAgICAgICAgICAoJGV4dHJhQ2hhciAhPT0gbnVsbCAmJiAkY2hhciA9PT0gJGV4dHJhQ2hhcikKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAkYnVmZmVyIC49ICRjaGFyOwogICAgICAgICAgICAgICAgJHRoaXMtPmluZGV4ICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGJ1ZmZlcjsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgY29tYmluYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVDb21iaW5hdG9yKCkKICAgIHsKICAgICAgICAvL0luaXRpYWwgd3MgY2FuIGJlIHRyaW1tZWQgaWYgZm9sbG93ZWQgYnkgYW5vdGhlciBjb21iaW5hdG9yCiAgICAgICAgJHdzID0gJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgIGlmICgkY29tYmluYXRvciA9ICR0aGlzLT5jb25zdW1lQW55KCR0aGlzLT5jb21iaW5hdG9ycywgdHJ1ZSkpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbnN1bWVXaGl0ZXNwYWNlcygpOwogICAgICAgIH0gZWxzZWlmICgkd3MpIHsKICAgICAgICAgICAgLy9JZiB0aGVyZSdzIG5vIG90aGVyIGNvbWJpbmF0b3JzIHVzZSB0aGUgc3BhY2UKICAgICAgICAgICAgJGNvbWJpbmF0b3IgPSAiICI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNvbWJpbmF0b3IgPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGNvbWJpbmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhcyBtdWNoIHdoaXRlc3BhY2VzIGFzIHBvc3NpYmxlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVXaGl0ZXNwYWNlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jb25zdW1lQW55KCR0aGlzLT53aGl0ZXNwYWNlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyB0aGUgZ2l2ZW4gY2hhcmFjdGVycwogICAgICoKICAgICAqIEBwYXJhbSBhcnJheSAkY2hhcnMgICAgICAgQ2hhcmFjdGVycyB0byBjb25zdW1lCiAgICAgKiBAcGFyYW0gZmFsc2UgJHN0b3BBdEZpcnN0IElmIHRydWUgb25seSB0aGUgZmlyc3QgbWF0Y2hpbmcgY2hhcmFjdGVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGNvbnN1bWVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGNvbnN1bWVBbnkoJGNoYXJzLCAkc3RvcEF0Rmlyc3QgPSBmYWxzZSkKICAgIHsKICAgICAgICAkYnVmZmVyID0gIiI7CiAgICAgICAgd2hpbGUgKCgkY2hhciA9ICR0aGlzLT5nZXRDaGFyKCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgIGlmIChpbl9hcnJheSgkY2hhciwgJGNoYXJzKSkgewogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkY2hhcjsKICAgICAgICAgICAgICAgICR0aGlzLT5pbmRleCsrOwogICAgICAgICAgICAgICAgaWYgKCRzdG9wQXRGaXJzdCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRidWZmZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdW1lcyB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaWYgaXQgaXMgZXF1YWwgdG8gdGhlCiAgICAgKiBnaXZlbiBvbmUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyIENoYXJhY3RlciB0byBjb21wYXJlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gY29uc3VtZSgkY2hhcikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmdldENoYXIoKSA9PT0gJGNoYXIpIHsKICAgICAgICAgICAgJHRoaXMtPmluZGV4Kys7CiAgICAgICAgICAgIHJldHVybiAkY2hhcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGNoYXJhY3RlciBvciBudWxsIGlmIHRoZSBlbmQKICAgICAqIGhhdmUgYmVlbiByZWFjaGVkCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0Q2hhcigpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5pbmRleCA8ICR0aGlzLT5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zZWxlY3RvclskdGhpcy0+aW5kZXhdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3JcTm9kZVxQYXJ0OwoKLyoqCiAqIFNlbGVjdG9yIHBzZXVkbyBwYXJ0IGJhc2UgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBAYWJzdHJhY3QKICovCmFic3RyYWN0IGNsYXNzIFBzZXVkbyBleHRlbmRzIFBhcnQKewogICAgLyoqCiAgICAgKiBTZWxlY3RvciBuYW1lCiAgICAgKgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbmFtZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWUgPSAkbmFtZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwp1c2UgUGVhc3RcU3ludGF4XE5vZGVcUGF0dGVybjsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXFN0YXRlbWVudDsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXEV4cHJlc3Npb247CnVzZSBQZWFzdFxTeW50YXhcTm9kZVxEZWNsYXJhdGlvbjsKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IHNpbXBsZSBwc2V1ZG8gY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHNldWRvU2ltcGxlIGV4dGVuZHMgUHNldWRvCnsKICAgIC8qKgogICAgICogUHJpb3JpdHkKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByaW9yaXR5ID0gMzsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VsZWN0b3IgcGFydCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHBhcmFtIE5vZGUgJG5vZGUgICAgTm9kZQogICAgICogQHBhcmFtIE5vZGUgJHBhcmVudCAgUGFyZW50IG5vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+bmFtZSkgewogICAgICAgICAgICBjYXNlICJwYXR0ZXJuIjoKICAgICAgICAgICAgICAgIHJldHVybiAkbm9kZSBpbnN0YW5jZW9mIFBhdHRlcm47CiAgICAgICAgICAgIGNhc2UgInN0YXRlbWVudCI6CiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGUgaW5zdGFuY2VvZiBTdGF0ZW1lbnQ7CiAgICAgICAgICAgIGNhc2UgImV4cHJlc3Npb24iOgogICAgICAgICAgICAgICAgcmV0dXJuICRub2RlIGluc3RhbmNlb2YgRXhwcmVzc2lvbjsKICAgICAgICAgICAgY2FzZSAiZGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgcmV0dXJuICRub2RlIGluc3RhbmNlb2YgRGVjbGFyYXRpb247CiAgICAgICAgICAgIGNhc2UgImxhc3QtY2hpbGQiOgogICAgICAgICAgICBjYXNlICJmaXJzdC1jaGlsZCI6CiAgICAgICAgICAgICAgICAkZmlyc3QgPSAkdGhpcy0+bmFtZSA9PT0gImZpcnN0LWNoaWxkIjsKICAgICAgICAgICAgICAgICRwcm9wcyA9IFV0aWxzOjpnZXRFeHBhbmRlZE5vZGVQcm9wZXJ0aWVzKCRwYXJlbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50KCRwcm9wcykgPiAwICYmICgKICAgICAgICAgICAgICAgICAgICAkZmlyc3QgPyAkcHJvcHNbMF0gPT09ICRub2RlIDogYXJyYXlfcG9wKCRwcm9wcykgPT09ICRub2RlCiAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3JcTm9kZVxQYXJ0OwoKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CgovKioKICogU2VsZWN0b3IgcGFydCB0eXBlIGNsYXNzCiAqIAogKiBAYXV0aG9yIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICovCmNsYXNzIFR5cGUgZXh0ZW5kcyBQYXJ0CnsKICAgIC8qKgogICAgICogU2VsZWN0b3IgdHlwZQogICAgICoKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdHlwZTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHNlbGVjdG9yIHR5cGUKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIFR5cGUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRUeXBlKCR0eXBlKQogICAgewogICAgICAgICR0aGlzLT50eXBlID0gJHR5cGU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZWxlY3RvciBwYXJ0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUsCiAgICAgKiBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZSAgICBOb2RlCiAgICAgKiBAcGFyYW0gTm9kZSAkcGFyZW50ICBQYXJlbnQgbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soTm9kZSAkbm9kZSwgTm9kZSAkcGFyZW50ID0gbnVsbCkKICAgIHsKICAgICAgICByZXR1cm4gJG5vZGUtPmdldFR5cGUoKSA9PT0gJHRoaXMtPnR5cGU7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTZWxlY3RvclxNYXRjaGVzOwp1c2UgUGVhc3RcU2VsZWN0b3JcTm9kZVxTZWxlY3RvcjsKdXNlIFBlYXN0XFN5bnRheFxOb2RlXE5vZGU7CgovKioKICogU2VsZWN0b3IgcGFydCBzZWxlY3RvciBwc2V1ZG8gY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgUHNldWRvU2VsZWN0b3IgZXh0ZW5kcyBQc2V1ZG8KewogICAgLyoqCiAgICAgKiBQcmlvcml0eQogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkcHJpb3JpdHkgPSAxOwoKICAgIC8qKgogICAgICogU2VsZWN0b3IKICAgICAqCiAgICAgKiBAdmFyIFNlbGVjdG9yCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2VsZWN0b3I7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzZWxlY3RvcgogICAgICoKICAgICAqIEBwYXJhbSBTZWxlY3RvciAkc2VsZWN0b3IgU2VsZWN0b3IKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTZWxlY3RvcihTZWxlY3RvciAkc2VsZWN0b3IpCiAgICB7CiAgICAgICAgJHRoaXMtPnNlbGVjdG9yID0gJHNlbGVjdG9yOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VsZWN0b3IgcGFydCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHBhcmFtIE5vZGUgJG5vZGUgICAgTm9kZQogICAgICogQHBhcmFtIE5vZGUgJHBhcmVudCAgUGFyZW50IG5vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgJG1hdGNoID0gbmV3IE1hdGNoZXMoKTsKICAgICAgICAkbWF0Y2gtPmFkZE1hdGNoKCRub2RlLCAkcGFyZW50KTsKICAgICAgICAkcmVzID0gJHRoaXMtPnNlbGVjdG9yLT5leGVjKCRtYXRjaCktPmNvdW50KCk7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lID09PSAibm90IiA/ICRyZXMgPT09IDAgOiAkcmVzICE9PSAwOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvclxOb2RlXFBhcnQ7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IGluZGV4IHBzZXVkbyBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBQc2V1ZG9JbmRleCBleHRlbmRzIFBzZXVkbwp7CiAgICAvKioKICAgICAqIFByaW9yaXR5CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmlvcml0eSA9IDI7CgogICAgLyoqCiAgICAgKiBTdGVwCiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRzdGVwID0gMDsKCiAgICAvKioKICAgICAqIE9mZnNldAogICAgICoKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb2Zmc2V0ID0gMDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0ZXAKICAgICAqCiAgICAgKiBAcGFyYW0gaW50ICRzdGVwIFN0ZXAKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRTdGVwKCRzdGVwKQogICAgewogICAgICAgICR0aGlzLT5zdGVwID0gJHN0ZXA7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgb2Zmc2V0CiAgICAgKgogICAgICogQHBhcmFtIGludCAkb2Zmc2V0IE9mZnNldAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldE9mZnNldCgkb2Zmc2V0KQogICAgewogICAgICAgICR0aGlzLT5vZmZzZXQgPSAkb2Zmc2V0OwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VsZWN0b3IgcGFydCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKgogICAgICogQHBhcmFtIE5vZGUgJG5vZGUgICAgTm9kZQogICAgICogQHBhcmFtIE5vZGUgJHBhcmVudCAgUGFyZW50IG5vZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNoZWNrKE5vZGUgJG5vZGUsIE5vZGUgJHBhcmVudCA9IG51bGwpCiAgICB7CiAgICAgICAgJHByb3BzID0gVXRpbHM6OmdldEV4cGFuZGVkTm9kZVByb3BlcnRpZXMoJHBhcmVudCk7CiAgICAgICAgJGNvdW50ID0gY291bnQoJHByb3BzKTsKICAgICAgICAkcmV2ZXJzZSA9ICR0aGlzLT5uYW1lID09PSAibnRoLWxhc3QtY2hpbGQiOwogICAgICAgIGlmICgkcmV2ZXJzZSkgewogICAgICAgICAgICAkc3RhcnQgPSAkY291bnQgLSAxIC0gKCR0aGlzLT5vZmZzZXQgLSAxKTsKICAgICAgICAgICAgJHN0ZXAgPSAkdGhpcy0+c3RlcCAqIC0xOwogICAgICAgICAgICBpZiAoJHN0ZXAgPiAwKSB7CiAgICAgICAgICAgICAgICAkcmV2ZXJzZSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHN0YXJ0ID0gJHRoaXMtPm9mZnNldCAtIDE7CiAgICAgICAgICAgICRzdGVwID0gJHRoaXMtPnN0ZXA7CiAgICAgICAgICAgIGlmICgkc3RlcCA8IDApIHsKICAgICAgICAgICAgICAgICRyZXZlcnNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL1N0ZXAgMCB3aWxsIGNhdXNlIGFuIGluZmluaXRlIGxvb3AsIHNvIGl0IG11c3QgYmUgc2V0IHRvIHRoZQogICAgICAgIC8vbnVtYmVyIG9mIHByb3BzIHNvIHRoYXQgaXQgd2lsbCBleGVjdXRlIG9ubHkgb25lIGl0ZXJhdGlvbgogICAgICAgIGlmICghJHN0ZXApIHsKICAgICAgICAgICAgJHN0ZXAgPSAkcmV2ZXJzZSA/IC0kY291bnQgOiAkY291bnQ7CiAgICAgICAgfQogICAgICAgIGZvciAoJGkgPSAkc3RhcnQ7ICgkcmV2ZXJzZSAmJiAkaSA+PSAwKSAgfHwgKCEkcmV2ZXJzZSAmJiAkaSA8ICRjb3VudCk7ICRpICs9ICRzdGVwKSB7CiAgICAgICAgICAgIGlmIChpc3NldCgkcHJvcHNbJGldKSAmJiAkcHJvcHNbJGldID09PSAkbm9kZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvclxOb2RlXFBhcnQ7Cgp1c2UgUGVhc3RcU3ludGF4XE5vZGVcTm9kZTsKdXNlIFBlYXN0XFN5bnRheFxVdGlsczsKCi8qKgogKiBTZWxlY3RvciBwYXJ0IGF0dHJpYnV0ZSBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBBdHRyaWJ1dGUgZXh0ZW5kcyBQYXJ0CnsKICAgIC8qKgogICAgICogUHJpb3JpdHkKICAgICAqCiAgICAgKiBAdmFyIGludAogICAgICovCiAgICBwcm90ZWN0ZWQgJHByaW9yaXR5ID0gNDsKCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSBuYW1lcwogICAgICoKICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHJvdGVjdGVkICRuYW1lcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgbWF0Y2ggb3BlcmF0b3IKICAgICAqCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKi8KICAgIHByb3RlY3RlZCAkb3BlcmF0b3IgPSBudWxsOwoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHZhbHVlCiAgICAgKgogICAgICogQHZhciBtaXhlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHZhbHVlID0gbnVsbDsKCiAgICAvKioKICAgICAqIENhc2UgaW5zZW5zaXRpdmUgZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlOwoKICAgIC8qKgogICAgICogUmVnZXggZmxhZwogICAgICoKICAgICAqIEB2YXIgYm9vbAogICAgICovCiAgICBwcm90ZWN0ZWQgJHJlZ2V4ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmFtZQogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgTmFtZQogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZE5hbWUoJG5hbWUpCiAgICB7CiAgICAgICAgJHRoaXMtPm5hbWVzW10gPSAkbmFtZTsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvcGVyYXRvcgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJG9wZXJhdG9yIE9wZXJhdG9yCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB2YWx1ZQogICAgICoKICAgICAqIEBwYXJhbSBtaXhlZCAkdmFsdWUgVmFsdWUKICAgICAqCiAgICAgKiBAcmV0dXJuICR0aGlzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRWYWx1ZSgkdmFsdWUpCiAgICB7CiAgICAgICAgJHRoaXMtPnZhbHVlID0gJHZhbHVlOwogICAgICAgIHJldHVybiAkdGhpczsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNhc2UgaW5zZW5zaXRpdmUgZmxhZwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRjYXNlSW5zZW5zaXRpdmUgQ2FzZSBpbnNlbnNpdGl2ZSBmbGFnCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0Q2FzZUluc2Vuc2l0aXZlKCRjYXNlSW5zZW5zaXRpdmUpCiAgICB7CiAgICAgICAgJHRoaXMtPmNhc2VJbnNlbnNpdGl2ZSA9ICRjYXNlSW5zZW5zaXRpdmU7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgcmVnZXggZmxhZwogICAgICoKICAgICAqIEBwYXJhbSBib29sICRyZWdleCBSZWdleCBmbGFnCiAgICAgKgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVnZXgoJHJlZ2V4KQogICAgewogICAgICAgICR0aGlzLT5yZWdleCA9ICRyZWdleDsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNlbGVjdG9yIHBhcnQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbm9kZSwKICAgICAqIGZhbHNlIG90aGVyd2lzZQogICAgICoKICAgICAqIEBwYXJhbSBOb2RlICRub2RlICAgIE5vZGUKICAgICAqIEBwYXJhbSBOb2RlICRwYXJlbnQgIFBhcmVudCBub2RlCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjaGVjayhOb2RlICRub2RlLCBOb2RlICRwYXJlbnQgPSBudWxsKQogICAgewogICAgICAgICRhdHRyID0gJG5vZGU7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPm5hbWVzIGFzICRuYW1lKSB7CiAgICAgICAgICAgICRhdHRyRm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKCRhdHRyIGluc3RhbmNlb2YgTm9kZSkgewogICAgICAgICAgICAgICAgJHByb3BzID0gVXRpbHM6OmdldE5vZGVQcm9wZXJ0aWVzKCRhdHRyKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRwcm9wcyBhcyAkcHJvcCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkcHJvcFsibmFtZSJdID09PSAkbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYXR0ckZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJGF0dHIgPSAkYXR0ci0+eyRwcm9wWyJnZXR0ZXIiXX0oKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghJGF0dHJGb3VuZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRib3RoU3RyaW5ncyA9IGlzX3N0cmluZygkYXR0cikgJiYgaXNfc3RyaW5nKCR0aGlzLT52YWx1ZSk7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+b3BlcmF0b3IpIHsKICAgICAgICAgICAgY2FzZSAiPSI6CiAgICAgICAgICAgICAgICBpZiAoJGJvdGhTdHJpbmdzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5yZWdleCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJlZ19tYXRjaCgkdGhpcy0+dmFsdWUsICRhdHRyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5jb21wYXJlU3RyKAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+dmFsdWUsICRhdHRyLCAkdGhpcy0+Y2FzZUluc2Vuc2l0aXZlLCB0cnVlLCB0cnVlCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc19pbnQoJGF0dHIpICYmIGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZsb2F0KSAkYXR0ciA9PT0gJHRoaXMtPnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyID09PSAkdGhpcy0+dmFsdWU7CiAgICAgICAgICAgIGNhc2UgIjwiOgogICAgICAgICAgICAgICAgaWYgKGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkgJiYgIWlzX2Zsb2F0KCRhdHRyKSAmJiAhaXNfaW50KCRhdHRyKSAmJiAhaXNfc3RyaW5nKCRhdHRyKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAkYXR0ciA8ICR0aGlzLT52YWx1ZTsKICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHRoaXMtPnZhbHVlKSAmJiAhaXNfZmxvYXQoJGF0dHIpICYmICFpc19pbnQoJGF0dHIpICYmICFpc19zdHJpbmcoJGF0dHIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyID4gJHRoaXMtPnZhbHVlOwogICAgICAgICAgICBjYXNlICI8PSI6CiAgICAgICAgICAgICAgICBpZiAoaXNfZmxvYXQoJHRoaXMtPnZhbHVlKSAmJiAhaXNfZmxvYXQoJGF0dHIpICYmICFpc19pbnQoJGF0dHIpICYmICFpc19zdHJpbmcoJGF0dHIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICRhdHRyIDw9ICR0aGlzLT52YWx1ZTsKICAgICAgICAgICAgY2FzZSAiPj0iOgogICAgICAgICAgICAgICAgaWYgKGlzX2Zsb2F0KCR0aGlzLT52YWx1ZSkgJiYgIWlzX2Zsb2F0KCRhdHRyKSAmJiAhaXNfaW50KCRhdHRyKSAmJiAhaXNfc3RyaW5nKCRhdHRyKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAkYXR0ciA+PSAkdGhpcy0+dmFsdWU7CiAgICAgICAgICAgIGNhc2UgIl49IjoKICAgICAgICAgICAgY2FzZSAiJD0iOgogICAgICAgICAgICBjYXNlICIqPSI6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvbXBhcmVTdHIoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnZhbHVlLCAkYXR0ciwgJHRoaXMtPmNhc2VJbnNlbnNpdGl2ZSwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3BlcmF0b3IgPT09ICJePSIsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPm9wZXJhdG9yID09PSAiJD0iCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR2MSAgICAgICAgICAgICAgICBTZWFyY2ggdmFsdWUKICAgICAqIEBwYXJhbSBzdHJpbmcgJHYyICAgICAgICAgICAgICAgIENvbXBhcmUgdmFsdWUKICAgICAqIEBwYXJhbSBib29sICAgJGNhc2VJbnNlbnNpdGl2ZSAgIFRydWUgaWYgdGhlIHNlYXJjaCBtdXN0IGJlIGNhc2UgaW5zZW5zaXRpdmUKICAgICAqIEBwYXJhbSBib29sICAgJG1hdGNoU3RhcnQgICAgICAgIFRydWUgaWYgdGhlIHNlYXJjaCBtdXN0IGJlIGV4ZWN1dGVkIGZyb20gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZwogICAgICogQHBhcmFtIGJvb2wgICAkbWF0Y2hFbmQgICAgICAgICAgVHJ1ZSBpZiB0aGUgc2VhcmNoIG11c3QgYmUgZXhlY3V0ZWQgZnJvbSB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCBvZiB0aGUgc3RyaW5nCiAgICAgKgogICAgICogQHJldHVybiBib29sCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBjb21wYXJlU3RyKCR2MSwgJHYyLCAkY2FzZUluc2Vuc2l0aXZlLCAkbWF0Y2hTdGFydCwgJG1hdGNoRW5kKQogICAgewogICAgICAgICRyZWdleCA9ICIjIiAuCiAgICAgICAgICAgICAgICAgKCRtYXRjaFN0YXJ0ID8gIl4iIDogIiIpIC4KICAgICAgICAgICAgICAgICBwcmVnX3F1b3RlKCR2MSkgLgogICAgICAgICAgICAgICAgICgkbWF0Y2hFbmQgPyAiJCIgOiAiIikgLgogICAgICAgICAgICAgICAgICIjdSIgLgogICAgICAgICAgICAgICAgICgkY2FzZUluc2Vuc2l0aXZlID8gImkiIDogIiIpOwogICAgICAgIHJldHVybiAoYm9vbCkgcHJlZ19tYXRjaCgkcmVnZXgsICR2Mik7CiAgICB9Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGVcUGFydDsKCnVzZSBQZWFzdFxTeW50YXhcTm9kZVxOb2RlOwoKLyoqCiAqIFNlbGVjdG9yIHBhcnQgYmFzZSBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEBhYnN0cmFjdAogKi8KYWJzdHJhY3QgY2xhc3MgUGFydAp7CiAgICAvKioKICAgICAqIFByaW9yaXR5CiAgICAgKgogICAgICogQHZhciBpbnQKICAgICAqLwogICAgcHJvdGVjdGVkICRwcmlvcml0eSA9IDU7CgogICAgcHVibGljIGZ1bmN0aW9uIGdldFByaW9yaXR5KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnByaW9yaXR5OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZWxlY3RvciBwYXJ0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUsCiAgICAgKiBmYWxzZSBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gTm9kZSAkbm9kZSAgICBOb2RlCiAgICAgKiBAcGFyYW0gTm9kZSAkcGFyZW50ICBQYXJlbnQgbm9kZQogICAgICoKICAgICAqIEByZXR1cm4gYm9vbAogICAgICoKICAgICAqIEBhYnN0cmFjdAogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgZnVuY3Rpb24gY2hlY2soTm9kZSAkbm9kZSwgTm9kZSAkcGFyZW50ID0gbnVsbCk7Cn08P3BocAovKioKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIFBlYXN0IHBhY2thZ2UKICoKICogKGMpIE1hcmNvIE1hcmNoacOyIDxtYXJjby5tbTg5QGdtYWlsLmNvbT4KICoKICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiByZWZlciB0byB0aGUgTElDRU5TRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZQogKi8KbmFtZXNwYWNlIFBlYXN0XFNlbGVjdG9yXE5vZGU7Cgp1c2UgUGVhc3RcU2VsZWN0b3JcTWF0Y2hlczsKCi8qKgogKiBTZWxlY3RvciBjbGFzcwogKiAKICogQGF1dGhvciBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqLwpjbGFzcyBTZWxlY3Rvcgp7CiAgICAvKioKICAgICAqIFNlbGVjdG9yIGdyb3VwcwogICAgICoKICAgICAqIEB2YXIgR3JvdXBbXQogICAgICovCiAgICBwcm90ZWN0ZWQgJGdyb3VwcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmV3IGdyb3VwCiAgICAgKgogICAgICogQHBhcmFtIEdyb3VwICRncm91cCBHcm91cAogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEdyb3VwKEdyb3VwICRncm91cCkKICAgIHsKICAgICAgICAkdGhpcy0+Z3JvdXBzW10gPSAkZ3JvdXA7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgc2VsZWN0b3Igb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKgogICAgICogQHJldHVybiBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJHJldE1hdGNoZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5ncm91cHMgYXMgJGdyb3VwKSB7CiAgICAgICAgICAgICRjbG9uZWRNYXRjaGVzID0gJG1hdGNoZXMtPmNyZWF0ZUNsb25lKCk7CiAgICAgICAgICAgICRncm91cC0+ZXhlYygkY2xvbmVkTWF0Y2hlcyk7CiAgICAgICAgICAgICRyZXRNYXRjaGVzW10gPSAkY2xvbmVkTWF0Y2hlczsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50KCRyZXRNYXRjaGVzKSA+IDEpIHsKICAgICAgICAgICAgJHJldE1hdGNoZXNbMF0tPm1lcmdlKGFycmF5X3NsaWNlKCRyZXRNYXRjaGVzLCAxKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0TWF0Y2hlc1swXTsKICAgIH0KfTw/cGhwCi8qKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgUGVhc3QgcGFja2FnZQogKgogKiAoYykgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKgogKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uIHJlZmVyIHRvIHRoZSBMSUNFTlNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlCiAqLwpuYW1lc3BhY2UgUGVhc3RcU2VsZWN0b3JcTm9kZTsKCnVzZSBQZWFzdFxTZWxlY3RvclxNYXRjaGVzOwp1c2UgUGVhc3RcU3ludGF4XFV0aWxzOwp1c2UgUGVhc3RcVHJhdmVyc2VyOwoKLyoqCiAqIFNlbGVjdG9yIGNvbWJpbmF0b3IgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgQ29tYmluYXRvcgp7CiAgICAvKioKICAgICAqIE9wZXJhdG9yCiAgICAgKgogICAgICogQHZhciBzdHJpbmd8bnVsbAogICAgICovCiAgICBwcm90ZWN0ZWQgJG9wZXJhdG9yOwoKICAgIC8qKgogICAgICogU2VsZWN0b3IgcGFydHMKICAgICAqCiAgICAgKiBAdmFyIFBhcnRcUGFydFtdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkcGFydHMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgb3BlcmF0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRvcGVyYXRvciBPcGVyYXRvcgogICAgICogQHJldHVybiAkdGhpcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0T3BlcmF0b3IoJG9wZXJhdG9yKQogICAgewogICAgICAgICR0aGlzLT5vcGVyYXRvciA9ICRvcGVyYXRvcjsKICAgICAgICByZXR1cm4gJHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgbmV3IHNlbGVjdG9yIHBhcnQKICAgICAqCiAgICAgKiBAcGFyYW0gUGFydFxQYXJ0ICRwYXJ0IFBhcnQKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFBhcnQoUGFydFxQYXJ0ICRwYXJ0KQogICAgewogICAgICAgICR0aGlzLT5wYXJ0c1tdID0gJHBhcnQ7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgZ3JvdXAgb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgJHBhcnRzID0gJHRoaXMtPnBhcnRzOwogICAgICAgIC8vU29ydCB0aGUgcGFydHMgYnkgcHJpb3JpdHkgdG8gZXhlY3V0ZSBmYXN0ZXIgY2hlY2tzIGZpcnN0CiAgICAgICAgdXNvcnQoJHBhcnRzLCBmdW5jdGlvbiAoJHAxLCAkcDIpIHsKICAgICAgICAgICAgJHByMSA9ICRwMS0+Z2V0UHJpb3JpdHkoKTsKICAgICAgICAgICAgJHByMiA9ICRwMi0+Z2V0UHJpb3JpdHkoKTsKICAgICAgICAgICAgaWYgKCRwcjEgPT09ICRwcjIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9IGVsc2VpZiAoJHByMSA8ICRwcjIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgJGZpbHRlciA9IGZ1bmN0aW9uICgkbm9kZSwgJHBhcmVudCkgdXNlICgkcGFydHMpIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHBhcnRzIGFzICRwYXJ0KSB7CiAgICAgICAgICAgICAgICBpZiAoISRwYXJ0LT5jaGVjaygkbm9kZSwgJHBhcmVudCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKICAgICAgICBzd2l0Y2ggKCR0aGlzLT5vcGVyYXRvcikgewogICAgICAgICAgICBjYXNlICIgIjoKICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSAkdGhpcy0+b3BlcmF0b3IgPT09ICI+IjsKICAgICAgICAgICAgICAgICRtYXRjaGVzLT5tYXAoZnVuY3Rpb24gKCRjdXJOb2RlKSB1c2UgKCRmaWx0ZXIsICRjaGlsZHJlbikgewogICAgICAgICAgICAgICAgICAgICRyZXQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICRjdXJOb2RlLT50cmF2ZXJzZSgKICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCRub2RlLCAkcGFyZW50KSB1c2UgKCRmaWx0ZXIsICRjaGlsZHJlbiwgJiRyZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZmlsdGVyKCRub2RlLCAkcGFyZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXRbXSA9IGFycmF5KCRub2RlLCAkcGFyZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJhdmVyc2VyOjpET05UX1RSQVZFUlNFX0NISUxEX05PREVTOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJza2lwU3RhcnRpbmdOb2RlIiA9PiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhc3NQYXJlbnROb2RlIiA9PiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ+IjoKICAgICAgICAgICAgY2FzZSAiKyI6CiAgICAgICAgICAgICAgICAkYWRqYWNlbnQgPSAkdGhpcy0+b3BlcmF0b3IgPT09ICIrIjsKICAgICAgICAgICAgICAgICRtYXRjaGVzLT5tYXAoZnVuY3Rpb24gKCRub2RlLCAkcGFyZW50KSB1c2UgKCRmaWx0ZXIsICRhZGphY2VudCkgewogICAgICAgICAgICAgICAgICAgICRyZXQgPSBhcnJheSgpOwogICAgICAgICAgICAgICAgICAgICRldmFsdWF0ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICRwcm9wcyA9ICRwYXJlbnQgPyBVdGlsczo6Z2V0RXhwYW5kZWROb2RlUHJvcGVydGllcygkcGFyZW50KSA6IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHByb3BzIGFzICRwcm9wTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGV2YWx1YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHByb3BOb2RlICYmICRmaWx0ZXIoJHByb3BOb2RlLCAkcGFyZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXRbXSA9IGFycmF5KCRwcm9wTm9kZSwgJHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGFkamFjZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcHJvcE5vZGUgPT09ICRub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXZhbHVhdGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkcmV0OwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJG1hdGNoZXMtPmZpbHRlcigkZmlsdGVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9PD9waHAKLyoqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBQZWFzdCBwYWNrYWdlCiAqCiAqIChjKSBNYXJjbyBNYXJjaGnDsiA8bWFyY28ubW04OUBnbWFpbC5jb20+CiAqCiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIExJQ0VOU0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUKICovCm5hbWVzcGFjZSBQZWFzdFxTZWxlY3RvclxOb2RlOwoKdXNlIFBlYXN0XFNlbGVjdG9yXE1hdGNoZXM7CgovKioKICogU2VsZWN0b3IgZ3JvdXAgY2xhc3MKICogCiAqIEBhdXRob3IgTWFyY28gTWFyY2hpw7IgPG1hcmNvLm1tODlAZ21haWwuY29tPgogKi8KY2xhc3MgR3JvdXAKewogICAgLyoqCiAgICAgKiBTZWxlY3RvciBjb21iaW5hdG9ycwogICAgICoKICAgICAqIEB2YXIgQ29tYmluYXRvcltdCiAgICAgKi8KICAgIHByb3RlY3RlZCAkY29tYmluYXRvcnMgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQWRkcyBhIGNvbWJpbmF0b3IKICAgICAqCiAgICAgKiBAcGFyYW0gQ29tYmluYXRvciAkY29tYmluYXRvcnMgQ29tYmluYXRvcgogICAgICoKICAgICAqIEByZXR1cm4gJHRoaXMKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoQ29tYmluYXRvciAkY29tYmluYXRvcnMpCiAgICB7CiAgICAgICAgJHRoaXMtPmNvbWJpbmF0b3JzW10gPSAkY29tYmluYXRvcnM7CiAgICAgICAgcmV0dXJuICR0aGlzOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZXMgdGhlIGN1cnJlbnQgZ3JvdXAgb24gdGhlIGdpdmVuIG1hdGNoZXMKICAgICAqCiAgICAgKiBAcGFyYW0gTWF0Y2hlcyAkbWF0Y2hlcyBNYXRjaGVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjKE1hdGNoZXMgJG1hdGNoZXMpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmNvbWJpbmF0b3JzIGFzICRjb21iaW5hdG9yKSB7CiAgICAgICAgICAgICRjb21iaW5hdG9yLT5leGVjKCRtYXRjaGVzKTsKICAgICAgICB9CiAgICB9Cn17eyNpc19zdWJjb21tYW5kfX0KCgp7ey9pc19zdWJjb21tYW5kfX0Ke3sjaGFzX3N1YmNvbW1hbmRzfX0KCgp7ey9oYXNfc3ViY29tbWFuZHN9fQp7eyNoYXNfcGFyYW1ldGVyc319CiMjIEdMT0JBTCBQQVJBTUVURVJTCgp7eyNwYXJhbWV0ZXJzfX0KICB7e3N5bm9wc2lzfX0KICAgICAge3tkZXNjfX0KCnt7L3BhcmFtZXRlcnN9fQp7ey9oYXNfcGFyYW1ldGVyc319Cnt7I3Jvb3RfY29tbWFuZH19CiAgUnVuICd3cCBoZWxwIDxjb21tYW5kPicgdG8gZ2V0IG1vcmUgaW5mb3JtYXRpb24gb24gYSBzcGVjaWZpYyBjb21tYW5kLgoKe3svcm9vdF9jb21tYW5kfX0KIyMgTkFNRQoKCXt7bmFtZX19Cgp7eyNzaG9ydGRlc2N9fQojIyBERVNDUklQVElPTgoKCXt7c2hvcnRkZXNjfX0KCnt7L3Nob3J0ZGVzY319CiMjIFNZTk9QU0lTCgoJe3tzeW5vcHNpc319Cgp7eyNhbGlhc319CiMjIEFMSUFTCgoJe3thbGlhc319Cgp7ey9hbGlhc319Cnt7I2hhcy1zdWJjb21tYW5kc319CiMjIFNVQkNPTU1BTkRTCgp7eyNzdWJjb21tYW5kc319Cgl7ey59fQp7ey9zdWJjb21tYW5kc319Cgp7ey9oYXMtc3ViY29tbWFuZHN9fQo8P3BocAovKioKICogVGhlIGJhc2UgY29uZmlndXJhdGlvbiBmb3IgV29yZFByZXNzCiAqCiAqIFRoZSB3cC1jb25maWcucGhwIGNyZWF0aW9uIHNjcmlwdCB1c2VzIHRoaXMgZmlsZSBkdXJpbmcgdGhlCiAqIGluc3RhbGxhdGlvbi4gWW91IGRvbid0IGhhdmUgdG8gdXNlIHRoZSB3ZWIgc2l0ZSwgeW91IGNhbgogKiBjb3B5IHRoaXMgZmlsZSB0byAid3AtY29uZmlnLnBocCIgYW5kIGZpbGwgaW4gdGhlIHZhbHVlcy4KICoKICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgY29uZmlndXJhdGlvbnM6CiAqCiAqICogTXlTUUwgc2V0dGluZ3MKICogKiBTZWNyZXQga2V5cwogKiAqIERhdGFiYXNlIHRhYmxlIHByZWZpeAogKiAqIEFCU1BBVEgKICoKICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL3N1cHBvcnQvYXJ0aWNsZS9lZGl0aW5nLXdwLWNvbmZpZy1waHAvCiAqCiAqIEBwYWNrYWdlIFdvcmRQcmVzcwogKi8KCi8vICoqIE15U1FMIHNldHRpbmdzIC0gWW91IGNhbiBnZXQgdGhpcyBpbmZvIGZyb20geW91ciB3ZWIgaG9zdCAqKiAvLwovKiogVGhlIG5hbWUgb2YgdGhlIGRhdGFiYXNlIGZvciBXb3JkUHJlc3MgKi8KZGVmaW5lKCAnREJfTkFNRScsICd7e2RibmFtZX19JyApOwoKLyoqIE15U1FMIGRhdGFiYXNlIHVzZXJuYW1lICovCmRlZmluZSggJ0RCX1VTRVInLCAne3tkYnVzZXJ9fScgKTsKCi8qKiBNeVNRTCBkYXRhYmFzZSBwYXNzd29yZCAqLwpkZWZpbmUoICdEQl9QQVNTV09SRCcsICd7e2RicGFzc319JyApOwoKLyoqIE15U1FMIGhvc3RuYW1lICovCmRlZmluZSggJ0RCX0hPU1QnLCAne3tkYmhvc3R9fScgKTsKCi8qKiBEYXRhYmFzZSBDaGFyc2V0IHRvIHVzZSBpbiBjcmVhdGluZyBkYXRhYmFzZSB0YWJsZXMuICovCmRlZmluZSggJ0RCX0NIQVJTRVQnLCAne3tkYmNoYXJzZXR9fScgKTsKCi8qKiBUaGUgRGF0YWJhc2UgQ29sbGF0ZSB0eXBlLiBEb24ndCBjaGFuZ2UgdGhpcyBpZiBpbiBkb3VidC4gKi8KZGVmaW5lKCAnREJfQ09MTEFURScsICd7e2RiY29sbGF0ZX19JyApOwoKLyoqCiAqIEF1dGhlbnRpY2F0aW9uIFVuaXF1ZSBLZXlzIGFuZCBTYWx0cy4KICoKICogQ2hhbmdlIHRoZXNlIHRvIGRpZmZlcmVudCB1bmlxdWUgcGhyYXNlcyEKICogWW91IGNhbiBnZW5lcmF0ZSB0aGVzZSB1c2luZyB0aGUge0BsaW5rIGh0dHBzOi8vYXBpLndvcmRwcmVzcy5vcmcvc2VjcmV0LWtleS8xLjEvc2FsdC8gV29yZFByZXNzLm9yZyBzZWNyZXQta2V5IHNlcnZpY2V9CiAqIFlvdSBjYW4gY2hhbmdlIHRoZXNlIGF0IGFueSBwb2ludCBpbiB0aW1lIHRvIGludmFsaWRhdGUgYWxsIGV4aXN0aW5nIGNvb2tpZXMuIFRoaXMgd2lsbCBmb3JjZSBhbGwgdXNlcnMgdG8gaGF2ZSB0byBsb2cgaW4gYWdhaW4uCiAqCiAqIEBzaW5jZSAyLjYuMAogKi8Ke3sja2V5cy1hbmQtc2FsdHN9fQpkZWZpbmUoICdBVVRIX0tFWScsICAgICAgICAgICd7e2F1dGgta2V5fX0nICk7CmRlZmluZSggJ1NFQ1VSRV9BVVRIX0tFWScsICAgJ3t7c2VjdXJlLWF1dGgta2V5fX0nICk7CmRlZmluZSggJ0xPR0dFRF9JTl9LRVknLCAgICAgJ3t7bG9nZ2VkLWluLWtleX19JyApOwpkZWZpbmUoICdOT05DRV9LRVknLCAgICAgICAgICd7e25vbmNlLWtleX19JyApOwpkZWZpbmUoICdBVVRIX1NBTFQnLCAgICAgICAgICd7e2F1dGgtc2FsdH19JyApOwpkZWZpbmUoICdTRUNVUkVfQVVUSF9TQUxUJywgICd7e3NlY3VyZS1hdXRoLXNhbHR9fScgKTsKZGVmaW5lKCAnTE9HR0VEX0lOX1NBTFQnLCAgICAne3tsb2dnZWQtaW4tc2FsdH19JyApOwpkZWZpbmUoICdOT05DRV9TQUxUJywgICAgICAgICd7e25vbmNlLXNhbHR9fScgKTsKZGVmaW5lKCAnV1BfQ0FDSEVfS0VZX1NBTFQnLCAne3t3cC1jYWNoZS1rZXktc2FsdH19JyApOwp7ey9rZXlzLWFuZC1zYWx0c319Cnt7a2V5cy1hbmQtc2FsdHMtYWx0fX0KLyoqCiAqIFdvcmRQcmVzcyBEYXRhYmFzZSBUYWJsZSBwcmVmaXguCiAqCiAqIFlvdSBjYW4gaGF2ZSBtdWx0aXBsZSBpbnN0YWxsYXRpb25zIGluIG9uZSBkYXRhYmFzZSBpZiB5b3UgZ2l2ZSBlYWNoCiAqIGEgdW5pcXVlIHByZWZpeC4gT25seSBudW1iZXJzLCBsZXR0ZXJzLCBhbmQgdW5kZXJzY29yZXMgcGxlYXNlIQogKi8KJHRhYmxlX3ByZWZpeCA9ICd7e2RicHJlZml4fX0nOwoKe3sjYWRkLXdwbGFuZ319CmRlZmluZSggJ1dQTEFORycsICd7e2xvY2FsZX19JyApOwp7ey9hZGQtd3BsYW5nfX0KCnt7ZXh0cmEtcGhwfX0KCi8qIFRoYXQncyBhbGwsIHN0b3AgZWRpdGluZyEgSGFwcHkgcHVibGlzaGluZy4gKi8KCi8qKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBXb3JkUHJlc3MgZGlyZWN0b3J5LiAqLwppZiAoICEgZGVmaW5lZCggJ0FCU1BBVEgnICkgKSB7CglkZWZpbmUoICdBQlNQQVRIJywgZGlybmFtZSggX19GSUxFX18gKSAuICcvJyApOwp9CgovKiogU2V0cyB1cCBXb3JkUHJlc3MgdmFycyBhbmQgaW5jbHVkZWQgZmlsZXMuICovCnJlcXVpcmVfb25jZSBBQlNQQVRIIC4gJ3dwLXNldHRpbmdzLnBocCc7CldvcmRQcmVzcyB2ZXJzaW9uOiB7e3dwLXZlcnNpb259fQpEYXRhYmFzZSByZXZpc2lvbjoge3tkYi12ZXJzaW9ufX0KVGlueU1DRSB2ZXJzaW9uOiAgIHt7bWNlLXZlcnNpb259fQpQYWNrYWdlIGxhbmd1YWdlOiAge3tsb2NhbC1wYWNrYWdlfX0KUGx1Z2luICU5e3tzbHVnfX0lbiBkZXRhaWxzOgogICAgTmFtZToge3tuYW1lfX0KICAgIFN0YXR1czoge3tzdGF0dXN9fSVuCiAgICBWZXJzaW9uOiB7e3ZlcnNpb259fQogICAgQXV0aG9yOiB7e2F1dGhvcn19CiAgICBEZXNjcmlwdGlvbjoge3tkZXNjcmlwdGlvbn19ClRoZW1lICU5e3tzbHVnfX0lbiBkZXRhaWxzOgogICAgTmFtZToge3tuYW1lfX0KICAgIFN0YXR1czoge3tzdGF0dXN9fSVuCiAgICBWZXJzaW9uOiB7e3ZlcnNpb259fQogICAgQXV0aG9yOiB7e2F1dGhvcn19Cjw/cGhwCi8qKgogKiBQSFBVbml0IGJvb3RzdHJhcCBmaWxlLgogKgogKiBAcGFja2FnZSB7e3BsdWdpbl9wYWNrYWdlfX0KICovCgppZiAoIFBIUF9NQUpPUl9WRVJTSU9OID49IDggKSB7CgllY2hvICJUaGUgc2NhZmZvbGRlZCB0ZXN0cyBjYW5ub3QgY3VycmVudGx5IGJlIHJ1biBvbiBQSFAgOC4wKy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93cC1jbGkvc2NhZmZvbGQtY29tbWFuZC9pc3N1ZXMvMjg1IiAuIFBIUF9FT0w7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuU2VjdXJpdHkuRXNjYXBlT3V0cHV0Lk91dHB1dE5vdEVzY2FwZWQKCWV4aXQoIDEgKTsKfQoKJF90ZXN0c19kaXIgPSBnZXRlbnYoICdXUF9URVNUU19ESVInICk7CgppZiAoICEgJF90ZXN0c19kaXIgKSB7CgkkX3Rlc3RzX2RpciA9IHJ0cmltKCBzeXNfZ2V0X3RlbXBfZGlyKCksICcvXFwnICkgLiAnL3dvcmRwcmVzcy10ZXN0cy1saWInOwp9CgppZiAoICEgZmlsZV9leGlzdHMoICJ7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAiICkgKSB7CgllY2hvICJDb3VsZCBub3QgZmluZCB7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAsIGhhdmUgeW91IHJ1biBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCA/IiAuIFBIUF9FT0w7IC8vIHBocGNzOmlnbm9yZSBXb3JkUHJlc3MuU2VjdXJpdHkuRXNjYXBlT3V0cHV0Lk91dHB1dE5vdEVzY2FwZWQKCWV4aXQoIDEgKTsKfQoKLy8gR2l2ZSBhY2Nlc3MgdG8gdGVzdHNfYWRkX2ZpbHRlcigpIGZ1bmN0aW9uLgpyZXF1aXJlX29uY2UgInskX3Rlc3RzX2Rpcn0vaW5jbHVkZXMvZnVuY3Rpb25zLnBocCI7CgovKioKICogTWFudWFsbHkgbG9hZCB0aGUgcGx1Z2luIGJlaW5nIHRlc3RlZC4KICovCmZ1bmN0aW9uIF9tYW51YWxseV9sb2FkX3BsdWdpbigpIHsKCXJlcXVpcmUgZGlybmFtZSggZGlybmFtZSggX19GSUxFX18gKSApIC4gJy97e3BsdWdpbl9zbHVnfX0ucGhwJzsKfQoKdGVzdHNfYWRkX2ZpbHRlciggJ211cGx1Z2luc19sb2FkZWQnLCAnX21hbnVhbGx5X2xvYWRfcGx1Z2luJyApOwoKLy8gU3RhcnQgdXAgdGhlIFdQIHRlc3RpbmcgZW52aXJvbm1lbnQuCnJlcXVpcmUgInskX3Rlc3RzX2Rpcn0vaW5jbHVkZXMvYm9vdHN0cmFwLnBocCI7Cm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oIGdydW50ICkgewoKCSd1c2Ugc3RyaWN0JzsKCgkvLyBQcm9qZWN0IGNvbmZpZ3VyYXRpb24KCWdydW50LmluaXRDb25maWcoIHsKCgkJcGtnOiBncnVudC5maWxlLnJlYWRKU09OKCAncGFja2FnZS5qc29uJyApLAoKCQlhZGR0ZXh0ZG9tYWluOiB7CgkJCW9wdGlvbnM6IHsKCQkJCXRleHRkb21haW46ICd7e3RleHRkb21haW59fScsCgkJCX0sCgkJCXVwZGF0ZV9hbGxfZG9tYWluczogewoJCQkJb3B0aW9uczogewoJCQkJCXVwZGF0ZURvbWFpbnM6IHRydWUKCQkJCX0sCgkJCQlzcmM6IFsgJyoucGhwJywgJyoqLyoucGhwJywgJyFcLmdpdC8qKi8qJywgJyFiaW4vKiovKicsICchbm9kZV9tb2R1bGVzLyoqLyonLCAnIXRlc3RzLyoqLyonIF0KCQkJfQoJCX0sCgoJCXdwX3JlYWRtZV90b19tYXJrZG93bjogewoJCQl5b3VyX3RhcmdldDogewoJCQkJZmlsZXM6IHsKCQkJCQknUkVBRE1FLm1kJzogJ3JlYWRtZS50eHQnCgkJCQl9CgkJCX0sCgkJfSwKCgkJbWFrZXBvdDogewoJCQl0YXJnZXQ6IHsKCQkJCW9wdGlvbnM6IHsKCQkJCQlkb21haW5QYXRoOiAnL2xhbmd1YWdlcycsCgkJCQkJZXhjbHVkZTogWyAnXC5naXQvKicsICdiaW4vKicsICdub2RlX21vZHVsZXMvKicsICd0ZXN0cy8qJyBdLAoJCQkJCW1haW5GaWxlOiAne3twbHVnaW5fc2x1Z319LnBocCcsCgkJCQkJcG90RmlsZW5hbWU6ICd7e3BsdWdpbl9zbHVnfX0ucG90JywKCQkJCQlwb3RIZWFkZXJzOiB7CgkJCQkJCXBvZWRpdDogdHJ1ZSwKCQkJCQkJJ3gtcG9lZGl0LWtleXdvcmRzbGlzdCc6IHRydWUKCQkJCQl9LAoJCQkJCXR5cGU6ICd3cC1wbHVnaW4nLAoJCQkJCXVwZGF0ZVRpbWVzdGFtcDogdHJ1ZQoJCQkJfQoJCQl9CgkJfSwKCX0gKTsKCglncnVudC5sb2FkTnBtVGFza3MoICdncnVudC13cC1pMThuJyApOwoJZ3J1bnQubG9hZE5wbVRhc2tzKCAnZ3J1bnQtd3AtcmVhZG1lLXRvLW1hcmtkb3duJyApOwoJZ3J1bnQucmVnaXN0ZXJUYXNrKCAnZGVmYXVsdCcsIFsgJ2kxOG4nLCdyZWFkbWUnIF0gKTsKCWdydW50LnJlZ2lzdGVyVGFzayggJ2kxOG4nLCBbJ2FkZHRleHRkb21haW4nLCAnbWFrZXBvdCddICk7CglncnVudC5yZWdpc3RlclRhc2soICdyZWFkbWUnLCBbJ3dwX3JlYWRtZV90b19tYXJrZG93biddICk7CgoJZ3J1bnQudXRpbC5saW5lZmVlZCA9ICdcbic7Cgp9Owo8P3BocAoKLyoqCiAqIFJlZ2lzdGVycyB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHBvc3QgdHlwZS4KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1faW5pdCgpIHsKe3tvdXRwdXR9fQp9CgphZGRfYWN0aW9uKCAnaW5pdCcsICd7e21hY2hpbmVfbmFtZX19X2luaXQnICk7CgovKioKICogU2V0cyB0aGUgcG9zdCB1cGRhdGVkIG1lc3NhZ2VzIGZvciB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHBvc3QgdHlwZS4KICoKICogQHBhcmFtICBhcnJheSAkbWVzc2FnZXMgUG9zdCB1cGRhdGVkIG1lc3NhZ2VzLgogKiBAcmV0dXJuIGFycmF5IE1lc3NhZ2VzIGZvciB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHBvc3QgdHlwZS4KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1fdXBkYXRlZF9tZXNzYWdlcyggJG1lc3NhZ2VzICkgewoJZ2xvYmFsICRwb3N0OwoKCSRwZXJtYWxpbmsgPSBnZXRfcGVybWFsaW5rKCAkcG9zdCApOwoKCSRtZXNzYWdlc1sne3tzbHVnfX0nXSA9IFsKCQkwICA9PiAnJywgLy8gVW51c2VkLiBNZXNzYWdlcyBzdGFydCBhdCBpbmRleCAxLgoJCS8qIHRyYW5zbGF0b3JzOiAlczogcG9zdCBwZXJtYWxpbmsgKi8KCQkxICA9PiBzcHJpbnRmKCBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHVwZGF0ZWQuIDxhIHRhcmdldD0iX2JsYW5rIiBocmVmPSIlcyI+VmlldyB7e2xhYmVsfX08L2E+JywgJ3t7dGV4dGRvbWFpbn19JyApLCBlc2NfdXJsKCAkcGVybWFsaW5rICkgKSwKCQkyICA9PiBfXyggJ0N1c3RvbSBmaWVsZCB1cGRhdGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQkzICA9PiBfXyggJ0N1c3RvbSBmaWVsZCBkZWxldGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQk0ICA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHVwZGF0ZWQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCS8qIHRyYW5zbGF0b3JzOiAlczogZGF0ZSBhbmQgdGltZSBvZiB0aGUgcmV2aXNpb24gKi8KCQk1ICA9PiBpc3NldCggJF9HRVRbJ3JldmlzaW9uJ10gKSA/IHNwcmludGYoIF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gcmVzdG9yZWQgdG8gcmV2aXNpb24gZnJvbSAlcycsICd7e3RleHRkb21haW59fScgKSwgd3BfcG9zdF9yZXZpc2lvbl90aXRsZSggKGludCkgJF9HRVRbJ3JldmlzaW9uJ10sIGZhbHNlICkgKSA6IGZhbHNlLCAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlNlY3VyaXR5Lk5vbmNlVmVyaWZpY2F0aW9uLlJlY29tbWVuZGVkCgkJLyogdHJhbnNsYXRvcnM6ICVzOiBwb3N0IHBlcm1hbGluayAqLwoJCTYgID0+IHNwcmludGYoIF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gcHVibGlzaGVkLiA8YSBocmVmPSIlcyI+VmlldyB7e2xhYmVsfX08L2E+JywgJ3t7dGV4dGRvbWFpbn19JyApLCBlc2NfdXJsKCAkcGVybWFsaW5rICkgKSwKCQk3ICA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHNhdmVkLicsICd7e3RleHRkb21haW59fScgKSwKCQkvKiB0cmFuc2xhdG9yczogJXM6IHBvc3QgcGVybWFsaW5rICovCgkJOCAgPT4gc3ByaW50ZiggX18oICd7e2xhYmVsX3VjZmlyc3R9fSBzdWJtaXR0ZWQuIDxhIHRhcmdldD0iX2JsYW5rIiBocmVmPSIlcyI+UHJldmlldyB7e2xhYmVsfX08L2E+JywgJ3t7dGV4dGRvbWFpbn19JyApLCBlc2NfdXJsKCBhZGRfcXVlcnlfYXJnKCAncHJldmlldycsICd0cnVlJywgJHBlcm1hbGluayApICkgKSwKCQkvKiB0cmFuc2xhdG9yczogMTogUHVibGlzaCBib3ggZGF0ZSBmb3JtYXQsIHNlZSBodHRwczovL3NlY3VyZS5waHAubmV0L2RhdGUgMjogUG9zdCBwZXJtYWxpbmsgKi8KCQk5ICA9PiBzcHJpbnRmKCBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IHNjaGVkdWxlZCBmb3I6IDxzdHJvbmc+JTEkczwvc3Ryb25nPi4gPGEgdGFyZ2V0PSJfYmxhbmsiIGhyZWY9IiUyJHMiPlByZXZpZXcge3tsYWJlbH19PC9hPicsICd7e3RleHRkb21haW59fScgKSwgZGF0ZV9pMThuKCBfXyggJ00gaiwgWSBAIEc6aScsICd7e3RleHRkb21haW59fScgKSwgc3RydG90aW1lKCAkcG9zdC0+cG9zdF9kYXRlICkgKSwgZXNjX3VybCggJHBlcm1hbGluayApICksCgkJLyogdHJhbnNsYXRvcnM6ICVzOiBwb3N0IHBlcm1hbGluayAqLwoJCTEwID0+IHNwcmludGYoIF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gZHJhZnQgdXBkYXRlZC4gPGEgdGFyZ2V0PSJfYmxhbmsiIGhyZWY9IiVzIj5QcmV2aWV3IHt7bGFiZWx9fTwvYT4nLCAne3t0ZXh0ZG9tYWlufX0nICksIGVzY191cmwoIGFkZF9xdWVyeV9hcmcoICdwcmV2aWV3JywgJ3RydWUnLCAkcGVybWFsaW5rICkgKSApLAoJXTsKCglyZXR1cm4gJG1lc3NhZ2VzOwp9CgphZGRfZmlsdGVyKCAncG9zdF91cGRhdGVkX21lc3NhZ2VzJywgJ3t7bWFjaGluZV9uYW1lfX1fdXBkYXRlZF9tZXNzYWdlcycgKTsKCi8qKgogKiBTZXRzIHRoZSBidWxrIHBvc3QgdXBkYXRlZCBtZXNzYWdlcyBmb3IgdGhlIGB7e21hY2hpbmVfbmFtZX19YCBwb3N0IHR5cGUuCiAqCiAqIEBwYXJhbSAgYXJyYXkgJGJ1bGtfbWVzc2FnZXMgQXJyYXlzIG9mIG1lc3NhZ2VzLCBlYWNoIGtleWVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIHBvc3QgdHlwZS4gTWVzc2FnZXMgYXJlCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5ZWQgd2l0aCAndXBkYXRlZCcsICdsb2NrZWQnLCAnZGVsZXRlZCcsICd0cmFzaGVkJywgYW5kICd1bnRyYXNoZWQnLgogKiBAcGFyYW0gIGludFtdICRidWxrX2NvdW50cyAgIEFycmF5IG9mIGl0ZW0gY291bnRzIGZvciBlYWNoIG1lc3NhZ2UsIHVzZWQgdG8gYnVpbGQgaW50ZXJuYXRpb25hbGl6ZWQgc3RyaW5ncy4KICogQHJldHVybiBhcnJheSBCdWxrIG1lc3NhZ2VzIGZvciB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHBvc3QgdHlwZS4KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1fYnVsa191cGRhdGVkX21lc3NhZ2VzKCAkYnVsa19tZXNzYWdlcywgJGJ1bGtfY291bnRzICkgewoJZ2xvYmFsICRwb3N0OwoKCSRidWxrX21lc3NhZ2VzWyd7e3NsdWd9fSddID0gWwoJCS8qIHRyYW5zbGF0b3JzOiAlczogTnVtYmVyIG9mIHt7bGFiZWxfcGx1cmFsfX0uICovCgkJJ3VwZGF0ZWQnICAgPT4gX24oICclcyB7e2xhYmVsfX0gdXBkYXRlZC4nLCAnJXMge3tsYWJlbF9wbHVyYWx9fSB1cGRhdGVkLicsICRidWxrX2NvdW50c1sndXBkYXRlZCddLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJJ2xvY2tlZCcgICAgPT4gKCAxID09PSAkYnVsa19jb3VudHNbJ2xvY2tlZCddICkgPyBfXyggJzEge3tsYWJlbH19IG5vdCB1cGRhdGVkLCBzb21lYm9keSBpcyBlZGl0aW5nIGl0LicsICd7e3RleHRkb21haW59fScgKSA6CgkJCQkJCS8qIHRyYW5zbGF0b3JzOiAlczogTnVtYmVyIG9mIHt7bGFiZWxfcGx1cmFsfX0uICovCgkJCQkJCV9uKCAnJXMge3tsYWJlbH19IG5vdCB1cGRhdGVkLCBzb21lYm9keSBpcyBlZGl0aW5nIGl0LicsICclcyB7e2xhYmVsX3BsdXJhbH19IG5vdCB1cGRhdGVkLCBzb21lYm9keSBpcyBlZGl0aW5nIHRoZW0uJywgJGJ1bGtfY291bnRzWydsb2NrZWQnXSwgJ3t7dGV4dGRvbWFpbn19JyApLAoJCS8qIHRyYW5zbGF0b3JzOiAlczogTnVtYmVyIG9mIHt7bGFiZWxfcGx1cmFsfX0uICovCgkJJ2RlbGV0ZWQnICAgPT4gX24oICclcyB7e2xhYmVsfX0gcGVybWFuZW50bHkgZGVsZXRlZC4nLCAnJXMge3tsYWJlbF9wbHVyYWx9fSBwZXJtYW5lbnRseSBkZWxldGVkLicsICRidWxrX2NvdW50c1snZGVsZXRlZCddLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJLyogdHJhbnNsYXRvcnM6ICVzOiBOdW1iZXIgb2Yge3tsYWJlbF9wbHVyYWx9fS4gKi8KCQkndHJhc2hlZCcgICA9PiBfbiggJyVzIHt7bGFiZWx9fSBtb3ZlZCB0byB0aGUgVHJhc2guJywgJyVzIHt7bGFiZWxfcGx1cmFsfX0gbW92ZWQgdG8gdGhlIFRyYXNoLicsICRidWxrX2NvdW50c1sndHJhc2hlZCddLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJLyogdHJhbnNsYXRvcnM6ICVzOiBOdW1iZXIgb2Yge3tsYWJlbF9wbHVyYWx9fS4gKi8KCQkndW50cmFzaGVkJyA9PiBfbiggJyVzIHt7bGFiZWx9fSByZXN0b3JlZCBmcm9tIHRoZSBUcmFzaC4nLCAnJXMge3tsYWJlbF9wbHVyYWx9fSByZXN0b3JlZCBmcm9tIHRoZSBUcmFzaC4nLCAkYnVsa19jb3VudHNbJ3VudHJhc2hlZCddLCAne3t0ZXh0ZG9tYWlufX0nICksCgldOwoKCXJldHVybiAkYnVsa19tZXNzYWdlczsKfQoKYWRkX2ZpbHRlciggJ2J1bGtfcG9zdF91cGRhdGVkX21lc3NhZ2VzJywgJ3t7bWFjaGluZV9uYW1lfX1fYnVsa191cGRhdGVkX21lc3NhZ2VzJywgMTAsIDIgKTsKIyEvdXNyL2Jpbi9lbnYgYmFzaAoKaWYgWyAkIyAtbHQgMyBdOyB0aGVuCgllY2hvICJ1c2FnZTogJDAgPGRiLW5hbWU+IDxkYi11c2VyPiA8ZGItcGFzcz4gW2RiLWhvc3RdIFt3cC12ZXJzaW9uXSBbc2tpcC1kYXRhYmFzZS1jcmVhdGlvbl0iCglleGl0IDEKZmkKCkRCX05BTUU9JDEKREJfVVNFUj0kMgpEQl9QQVNTPSQzCkRCX0hPU1Q9JHs0LWxvY2FsaG9zdH0KV1BfVkVSU0lPTj0kezUtbGF0ZXN0fQpTS0lQX0RCX0NSRUFURT0kezYtZmFsc2V9CgpUTVBESVI9JHtUTVBESVItL3RtcH0KVE1QRElSPSQoZWNobyAkVE1QRElSIHwgc2VkIC1lICJzL1wvJC8vIikKV1BfVEVTVFNfRElSPSR7V1BfVEVTVFNfRElSLSRUTVBESVIvd29yZHByZXNzLXRlc3RzLWxpYn0KV1BfQ09SRV9ESVI9JHtXUF9DT1JFX0RJUi0kVE1QRElSL3dvcmRwcmVzc30KCmRvd25sb2FkKCkgewogICAgaWYgWyBgd2hpY2ggY3VybGAgXTsgdGhlbgogICAgICAgIGN1cmwgLXMgIiQxIiA+ICIkMiI7CiAgICBlbGlmIFsgYHdoaWNoIHdnZXRgIF07IHRoZW4KICAgICAgICB3Z2V0IC1udiAtTyAiJDIiICIkMSIKICAgIGZpCn0KCmlmIFtbICRXUF9WRVJTSU9OID1+IF5bMC05XStcLlswLTldK1wtKGJldGF8UkMpWzAtOV0rJCBdXTsgdGhlbgoJV1BfQlJBTkNIPSR7V1BfVkVSU0lPTiVcLSp9CglXUF9URVNUU19UQUc9ImJyYW5jaGVzLyRXUF9CUkFOQ0giCgplbGlmIFtbICRXUF9WRVJTSU9OID1+IF5bMC05XStcLlswLTldKyQgXV07IHRoZW4KCVdQX1RFU1RTX1RBRz0iYnJhbmNoZXMvJFdQX1ZFUlNJT04iCmVsaWYgW1sgJFdQX1ZFUlNJT04gPX4gWzAtOV0rXC5bMC05XStcLlswLTldKyBdXTsgdGhlbgoJaWYgW1sgJFdQX1ZFUlNJT04gPX4gWzAtOV0rXC5bMC05XStcLlswXSBdXTsgdGhlbgoJCSMgdmVyc2lvbiB4LnguMCBtZWFucyB0aGUgZmlyc3QgcmVsZWFzZSBvZiB0aGUgbWFqb3IgdmVyc2lvbiwgc28gc3RyaXAgb2ZmIHRoZSAuMCBhbmQgZG93bmxvYWQgdmVyc2lvbiB4LngKCQlXUF9URVNUU19UQUc9InRhZ3MvJHtXUF9WRVJTSU9OJT8/fSIKCWVsc2UKCQlXUF9URVNUU19UQUc9InRhZ3MvJFdQX1ZFUlNJT04iCglmaQplbGlmIFtbICRXUF9WRVJTSU9OID09ICduaWdodGx5JyB8fCAkV1BfVkVSU0lPTiA9PSAndHJ1bmsnIF1dOyB0aGVuCglXUF9URVNUU19UQUc9InRydW5rIgplbHNlCgkjIGh0dHAgc2VydmVzIGEgc2luZ2xlIG9mZmVyLCB3aGVyZWFzIGh0dHBzIHNlcnZlcyBtdWx0aXBsZS4gd2Ugb25seSB3YW50IG9uZQoJZG93bmxvYWQgaHR0cDovL2FwaS53b3JkcHJlc3Mub3JnL2NvcmUvdmVyc2lvbi1jaGVjay8xLjcvIC90bXAvd3AtbGF0ZXN0Lmpzb24KCWdyZXAgJ1swLTldK1wuWzAtOV0rKFwuWzAtOV0rKT8nIC90bXAvd3AtbGF0ZXN0Lmpzb24KCUxBVEVTVF9WRVJTSU9OPSQoZ3JlcCAtbyAnInZlcnNpb24iOiJbXiJdKicgL3RtcC93cC1sYXRlc3QuanNvbiB8IHNlZCAncy8idmVyc2lvbiI6Ii8vJykKCWlmIFtbIC16ICIkTEFURVNUX1ZFUlNJT04iIF1dOyB0aGVuCgkJZWNobyAiTGF0ZXN0IFdvcmRQcmVzcyB2ZXJzaW9uIGNvdWxkIG5vdCBiZSBmb3VuZCIKCQlleGl0IDEKCWZpCglXUF9URVNUU19UQUc9InRhZ3MvJExBVEVTVF9WRVJTSU9OIgpmaQpzZXQgLWV4CgppbnN0YWxsX3dwKCkgewoKCWlmIFsgLWQgJFdQX0NPUkVfRElSIF07IHRoZW4KCQlyZXR1cm47CglmaQoKCW1rZGlyIC1wICRXUF9DT1JFX0RJUgoKCWlmIFtbICRXUF9WRVJTSU9OID09ICduaWdodGx5JyB8fCAkV1BfVkVSU0lPTiA9PSAndHJ1bmsnIF1dOyB0aGVuCgkJbWtkaXIgLXAgJFRNUERJUi93b3JkcHJlc3MtdHJ1bmsKCQlybSAtcmYgJFRNUERJUi93b3JkcHJlc3MtdHJ1bmsvKgoJCXN2biBleHBvcnQgLS1xdWlldCBodHRwczovL2NvcmUuc3ZuLndvcmRwcmVzcy5vcmcvdHJ1bmsgJFRNUERJUi93b3JkcHJlc3MtdHJ1bmsvd29yZHByZXNzCgkJbXYgJFRNUERJUi93b3JkcHJlc3MtdHJ1bmsvd29yZHByZXNzLyogJFdQX0NPUkVfRElSCgllbHNlCgkJaWYgWyAkV1BfVkVSU0lPTiA9PSAnbGF0ZXN0JyBdOyB0aGVuCgkJCWxvY2FsIEFSQ0hJVkVfTkFNRT0nbGF0ZXN0JwoJCWVsaWYgW1sgJFdQX1ZFUlNJT04gPX4gWzAtOV0rXC5bMC05XSsgXV07IHRoZW4KCQkJIyBodHRwcyBzZXJ2ZXMgbXVsdGlwbGUgb2ZmZXJzLCB3aGVyZWFzIGh0dHAgc2VydmVzIHNpbmdsZS4KCQkJZG93bmxvYWQgaHR0cHM6Ly9hcGkud29yZHByZXNzLm9yZy9jb3JlL3ZlcnNpb24tY2hlY2svMS43LyAkVE1QRElSL3dwLWxhdGVzdC5qc29uCgkJCWlmIFtbICRXUF9WRVJTSU9OID1+IFswLTldK1wuWzAtOV0rXC5bMF0gXV07IHRoZW4KCQkJCSMgdmVyc2lvbiB4LnguMCBtZWFucyB0aGUgZmlyc3QgcmVsZWFzZSBvZiB0aGUgbWFqb3IgdmVyc2lvbiwgc28gc3RyaXAgb2ZmIHRoZSAuMCBhbmQgZG93bmxvYWQgdmVyc2lvbiB4LngKCQkJCUxBVEVTVF9WRVJTSU9OPSR7V1BfVkVSU0lPTiU/P30KCQkJZWxzZQoJCQkJIyBvdGhlcndpc2UsIHNjYW4gdGhlIHJlbGVhc2VzIGFuZCBnZXQgdGhlIG1vc3QgdXAgdG8gZGF0ZSBtaW5vciB2ZXJzaW9uIG9mIHRoZSBtYWpvciByZWxlYXNlCgkJCQlsb2NhbCBWRVJTSU9OX0VTQ0FQRUQ9YGVjaG8gJFdQX1ZFUlNJT04gfCBzZWQgJ3MvXC4vXFxcXC4vZydgCgkJCQlMQVRFU1RfVkVSU0lPTj0kKGdyZXAgLW8gJyJ2ZXJzaW9uIjoiJyRWRVJTSU9OX0VTQ0FQRUQnW14iXSonICRUTVBESVIvd3AtbGF0ZXN0Lmpzb24gfCBzZWQgJ3MvInZlcnNpb24iOiIvLycgfCBoZWFkIC0xKQoJCQlmaQoJCQlpZiBbWyAteiAiJExBVEVTVF9WRVJTSU9OIiBdXTsgdGhlbgoJCQkJbG9jYWwgQVJDSElWRV9OQU1FPSJ3b3JkcHJlc3MtJFdQX1ZFUlNJT04iCgkJCWVsc2UKCQkJCWxvY2FsIEFSQ0hJVkVfTkFNRT0id29yZHByZXNzLSRMQVRFU1RfVkVSU0lPTiIKCQkJZmkKCQllbHNlCgkJCWxvY2FsIEFSQ0hJVkVfTkFNRT0id29yZHByZXNzLSRXUF9WRVJTSU9OIgoJCWZpCgkJZG93bmxvYWQgaHR0cHM6Ly93b3JkcHJlc3Mub3JnLyR7QVJDSElWRV9OQU1FfS50YXIuZ3ogICRUTVBESVIvd29yZHByZXNzLnRhci5negoJCXRhciAtLXN0cmlwLWNvbXBvbmVudHM9MSAtenhtZiAkVE1QRElSL3dvcmRwcmVzcy50YXIuZ3ogLUMgJFdQX0NPUkVfRElSCglmaQoKCWRvd25sb2FkIGh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vbWFya29oZWlqbmVuL3dwLW15c3FsaS9tYXN0ZXIvZGIucGhwICRXUF9DT1JFX0RJUi93cC1jb250ZW50L2RiLnBocAp9CgppbnN0YWxsX3Rlc3Rfc3VpdGUoKSB7CgkjIHBvcnRhYmxlIGluLXBsYWNlIGFyZ3VtZW50IGZvciBib3RoIEdOVSBzZWQgYW5kIE1hYyBPU1ggc2VkCglpZiBbWyAkKHVuYW1lIC1zKSA9PSAnRGFyd2luJyBdXTsgdGhlbgoJCWxvY2FsIGlvcHRpb249Jy1pLmJhaycKCWVsc2UKCQlsb2NhbCBpb3B0aW9uPSctaScKCWZpCgoJIyBzZXQgdXAgdGVzdGluZyBzdWl0ZSBpZiBpdCBkb2Vzbid0IHlldCBleGlzdAoJaWYgWyAhIC1kICRXUF9URVNUU19ESVIgXTsgdGhlbgoJCSMgc2V0IHVwIHRlc3Rpbmcgc3VpdGUKCQlta2RpciAtcCAkV1BfVEVTVFNfRElSCgkJcm0gLXJmICRXUF9URVNUU19ESVIve2luY2x1ZGVzLGRhdGF9CgkJc3ZuIGV4cG9ydCAtLXF1aWV0IC0taWdub3JlLWV4dGVybmFscyBodHRwczovL2RldmVsb3Auc3ZuLndvcmRwcmVzcy5vcmcvJHtXUF9URVNUU19UQUd9L3Rlc3RzL3BocHVuaXQvaW5jbHVkZXMvICRXUF9URVNUU19ESVIvaW5jbHVkZXMKCQlzdm4gZXhwb3J0IC0tcXVpZXQgLS1pZ25vcmUtZXh0ZXJuYWxzIGh0dHBzOi8vZGV2ZWxvcC5zdm4ud29yZHByZXNzLm9yZy8ke1dQX1RFU1RTX1RBR30vdGVzdHMvcGhwdW5pdC9kYXRhLyAkV1BfVEVTVFNfRElSL2RhdGEKCWZpCgoJaWYgWyAhIC1mIHdwLXRlc3RzLWNvbmZpZy5waHAgXTsgdGhlbgoJCWRvd25sb2FkIGh0dHBzOi8vZGV2ZWxvcC5zdm4ud29yZHByZXNzLm9yZy8ke1dQX1RFU1RTX1RBR30vd3AtdGVzdHMtY29uZmlnLXNhbXBsZS5waHAgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCQkjIHJlbW92ZSBhbGwgZm9yd2FyZCBzbGFzaGVzIGluIHRoZSBlbmQKCQlXUF9DT1JFX0RJUj0kKGVjaG8gJFdQX0NPUkVfRElSIHwgc2VkICJzOi9cKyQ6OiIpCgkJc2VkICRpb3B0aW9uICJzOmRpcm5hbWUoIF9fRklMRV9fICkgLiAnL3NyYy8nOickV1BfQ09SRV9ESVIvJzoiICIkV1BfVEVTVFNfRElSIi93cC10ZXN0cy1jb25maWcucGhwCgkJc2VkICRpb3B0aW9uICJzOl9fRElSX18gLiAnL3NyYy8nOickV1BfQ09SRV9ESVIvJzoiICIkV1BfVEVTVFNfRElSIi93cC10ZXN0cy1jb25maWcucGhwCgkJc2VkICRpb3B0aW9uICJzL3lvdXJlbXB0eXRlc3RkYm5hbWVoZXJlLyREQl9OQU1FLyIgIiRXUF9URVNUU19ESVIiL3dwLXRlc3RzLWNvbmZpZy5waHAKCQlzZWQgJGlvcHRpb24gInMveW91cnVzZXJuYW1laGVyZS8kREJfVVNFUi8iICIkV1BfVEVTVFNfRElSIi93cC10ZXN0cy1jb25maWcucGhwCgkJc2VkICRpb3B0aW9uICJzL3lvdXJwYXNzd29yZGhlcmUvJERCX1BBU1MvIiAiJFdQX1RFU1RTX0RJUiIvd3AtdGVzdHMtY29uZmlnLnBocAoJCXNlZCAkaW9wdGlvbiAic3xsb2NhbGhvc3R8JHtEQl9IT1NUfXwiICIkV1BfVEVTVFNfRElSIi93cC10ZXN0cy1jb25maWcucGhwCglmaQoKfQoKcmVjcmVhdGVfZGIoKSB7CglzaG9wdCAtcyBub2Nhc2VtYXRjaAoJaWYgW1sgJDEgPX4gXih5fHllcykkIF1dCgl0aGVuCgkJbXlzcWxhZG1pbiBkcm9wICREQl9OQU1FIC1mIC0tdXNlcj0iJERCX1VTRVIiIC0tcGFzc3dvcmQ9IiREQl9QQVNTIiRFWFRSQQoJCWNyZWF0ZV9kYgoJCWVjaG8gIlJlY3JlYXRlZCB0aGUgZGF0YWJhc2UgKCREQl9OQU1FKS4iCgllbHNlCgkJZWNobyAiTGVhdmluZyB0aGUgZXhpc3RpbmcgZGF0YWJhc2UgKCREQl9OQU1FKSBpbiBwbGFjZS4iCglmaQoJc2hvcHQgLXUgbm9jYXNlbWF0Y2gKfQoKY3JlYXRlX2RiKCkgewoJbXlzcWxhZG1pbiBjcmVhdGUgJERCX05BTUUgLS11c2VyPSIkREJfVVNFUiIgLS1wYXNzd29yZD0iJERCX1BBU1MiJEVYVFJBCn0KCmluc3RhbGxfZGIoKSB7CgoJaWYgWyAke1NLSVBfREJfQ1JFQVRFfSA9ICJ0cnVlIiBdOyB0aGVuCgkJcmV0dXJuIDAKCWZpCgoJIyBwYXJzZSBEQl9IT1NUIGZvciBwb3J0IG9yIHNvY2tldCByZWZlcmVuY2VzCglsb2NhbCBQQVJUUz0oJHtEQl9IT1NULy9cOi8gfSkKCWxvY2FsIERCX0hPU1ROQU1FPSR7UEFSVFNbMF19OwoJbG9jYWwgREJfU09DS19PUl9QT1JUPSR7UEFSVFNbMV19OwoJbG9jYWwgRVhUUkE9IiIKCglpZiAhIFsgLXogJERCX0hPU1ROQU1FIF0gOyB0aGVuCgkJaWYgWyAkKGVjaG8gJERCX1NPQ0tfT1JfUE9SVCB8IGdyZXAgLWUgJ15bMC05XVx7MSxcfSQnKSBdOyB0aGVuCgkJCUVYVFJBPSIgLS1ob3N0PSREQl9IT1NUTkFNRSAtLXBvcnQ9JERCX1NPQ0tfT1JfUE9SVCAtLXByb3RvY29sPXRjcCIKCQllbGlmICEgWyAteiAkREJfU09DS19PUl9QT1JUIF0gOyB0aGVuCgkJCUVYVFJBPSIgLS1zb2NrZXQ9JERCX1NPQ0tfT1JfUE9SVCIKCQllbGlmICEgWyAteiAkREJfSE9TVE5BTUUgXSA7IHRoZW4KCQkJRVhUUkE9IiAtLWhvc3Q9JERCX0hPU1ROQU1FIC0tcHJvdG9jb2w9dGNwIgoJCWZpCglmaQoKCSMgY3JlYXRlIGRhdGFiYXNlCglpZiBbICQobXlzcWwgLS11c2VyPSIkREJfVVNFUiIgLS1wYXNzd29yZD0iJERCX1BBU1MiJEVYVFJBIC0tZXhlY3V0ZT0nc2hvdyBkYXRhYmFzZXM7JyB8IGdyZXAgXiREQl9OQU1FJCkgXQoJdGhlbgoJCWVjaG8gIlJlaW5zdGFsbGluZyB3aWxsIGRlbGV0ZSB0aGUgZXhpc3RpbmcgdGVzdCBkYXRhYmFzZSAoJERCX05BTUUpIgoJCXJlYWQgLXAgJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBwcm9jZWVkPyBbeS9OXTogJyBERUxFVEVfRVhJU1RJTkdfREIKCQlyZWNyZWF0ZV9kYiAkREVMRVRFX0VYSVNUSU5HX0RCCgllbHNlCgkJY3JlYXRlX2RiCglmaQp9CgppbnN0YWxsX3dwCmluc3RhbGxfdGVzdF9zdWl0ZQppbnN0YWxsX2RiCjw/eG1sIHZlcnNpb249IjEuMCI/Pgo8cnVsZXNldCBuYW1lPSJXb3JkUHJlc3MgQ29kaW5nIFN0YW5kYXJkcyBiYXNlZCBjdXN0b20gcnVsZXNldCBmb3IgeW91ciBwbHVnaW4iPgoJPGRlc2NyaXB0aW9uPkdlbmVyYWxseS1hcHBsaWNhYmxlIHNuaWZmcyBmb3IgV29yZFByZXNzIHBsdWdpbnMuPC9kZXNjcmlwdGlvbj4KCgk8IS0tIFdoYXQgdG8gc2NhbiAtLT4KCTxmaWxlPi48L2ZpbGU+Cgk8ZXhjbHVkZS1wYXR0ZXJuPi92ZW5kb3IvPC9leGNsdWRlLXBhdHRlcm4+Cgk8ZXhjbHVkZS1wYXR0ZXJuPi9ub2RlX21vZHVsZXMvPC9leGNsdWRlLXBhdHRlcm4+CgoJPCEtLSBIb3cgdG8gc2NhbiAtLT4KCTwhLS0gVXNhZ2UgaW5zdHJ1Y3Rpb25zOiBodHRwczovL2dpdGh1Yi5jb20vc3F1aXpsYWJzL1BIUF9Db2RlU25pZmZlci93aWtpL1VzYWdlIC0tPgoJPCEtLSBBbm5vdGF0ZWQgcnVsZXNldDogaHR0cHM6Ly9naXRodWIuY29tL3NxdWl6bGFicy9QSFBfQ29kZVNuaWZmZXIvd2lraS9Bbm5vdGF0ZWQtcnVsZXNldC54bWwgLS0+Cgk8YXJnIHZhbHVlPSJzcCIvPiA8IS0tIFNob3cgc25pZmYgYW5kIHByb2dyZXNzIC0tPgoJPGFyZyBuYW1lPSJiYXNlcGF0aCIgdmFsdWU9Ii4vIi8+PCEtLSBTdHJpcCB0aGUgZmlsZSBwYXRocyBkb3duIHRvIHRoZSByZWxldmFudCBiaXQgLS0+Cgk8YXJnIG5hbWU9ImNvbG9ycyIvPgoJPGFyZyBuYW1lPSJleHRlbnNpb25zIiB2YWx1ZT0icGhwIi8+Cgk8YXJnIG5hbWU9InBhcmFsbGVsIiB2YWx1ZT0iOCIvPjwhLS0gRW5hYmxlcyBwYXJhbGxlbCBwcm9jZXNzaW5nIHdoZW4gYXZhaWxhYmxlIGZvciBmYXN0ZXIgcmVzdWx0cy4gLS0+CgoJPCEtLSBSdWxlczogQ2hlY2sgUEhQIHZlcnNpb24gY29tcGF0aWJpbGl0eSAtLT4KCTwhLS0gaHR0cHM6Ly9naXRodWIuY29tL1BIUENvbXBhdGliaWxpdHkvUEhQQ29tcGF0aWJpbGl0eSNzbmlmZmluZy15b3VyLWNvZGUtZm9yLWNvbXBhdGliaWxpdHktd2l0aC1zcGVjaWZpYy1waHAtdmVyc2lvbnMgLS0+Cgk8Y29uZmlnIG5hbWU9InRlc3RWZXJzaW9uIiB2YWx1ZT0iNS42LSIvPgoJPCEtLSBodHRwczovL2dpdGh1Yi5jb20vUEhQQ29tcGF0aWJpbGl0eS9QSFBDb21wYXRpYmlsaXR5V1AgLS0+Cgk8cnVsZSByZWY9IlBIUENvbXBhdGliaWxpdHlXUCIvPgoKCTwhLS0gUnVsZXM6IFdvcmRQcmVzcyBDb2RpbmcgU3RhbmRhcmRzIC0tPgoJPCEtLSBodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMgLS0+Cgk8IS0tIGh0dHBzOi8vZ2l0aHViLmNvbS9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy93aWtpL0N1c3RvbWl6YWJsZS1zbmlmZi1wcm9wZXJ0aWVzIC0tPgoJPGNvbmZpZyBuYW1lPSJtaW5pbXVtX3N1cHBvcnRlZF93cF92ZXJzaW9uIiB2YWx1ZT0iNC42Ii8+Cgk8cnVsZSByZWY9IldvcmRQcmVzcyIvPgoJPHJ1bGUgcmVmPSJXb3JkUHJlc3MuTmFtaW5nQ29udmVudGlvbnMuUHJlZml4QWxsR2xvYmFscyI+CgkJPHByb3BlcnRpZXM+CgkJCTwhLS0gVmFsdWU6IHJlcGxhY2UgdGhlIGZ1bmN0aW9uLCBjbGFzcywgYW5kIHZhcmlhYmxlIHByZWZpeGVzIHVzZWQuIFNlcGFyYXRlIG11bHRpcGxlIHByZWZpeGVzIHdpdGggYSBjb21tYS4gLS0+CgkJCTxwcm9wZXJ0eSBuYW1lPSJwcmVmaXhlcyIgdHlwZT0iYXJyYXkiIHZhbHVlPSJteS1wbHVnaW4iLz4KCQk8L3Byb3BlcnRpZXM+Cgk8L3J1bGU+Cgk8cnVsZSByZWY9IldvcmRQcmVzcy5XUC5JMThuIj4KCQk8cHJvcGVydGllcz4KCQkJPCEtLSBWYWx1ZTogcmVwbGFjZSB0aGUgdGV4dCBkb21haW4gdXNlZC4gLS0+CgkJCTxwcm9wZXJ0eSBuYW1lPSJ0ZXh0X2RvbWFpbiIgdHlwZT0iYXJyYXkiIHZhbHVlPSJteS1wbHVnaW4iLz4KCQk8L3Byb3BlcnRpZXM+Cgk8L3J1bGU+Cgk8cnVsZSByZWY9IldvcmRQcmVzcy5XaGl0ZVNwYWNlLkNvbnRyb2xTdHJ1Y3R1cmVTcGFjaW5nIj4KCQk8cHJvcGVydGllcz4KCQkJPHByb3BlcnR5IG5hbWU9ImJsYW5rX2xpbmVfY2hlY2siIHZhbHVlPSJ0cnVlIi8+CgkJPC9wcm9wZXJ0aWVzPgoJPC9ydWxlPgo8L3J1bGVzZXQ+Cjw/cGhwCi8qKgogKiBQSFBVbml0IGJvb3RzdHJhcCBmaWxlLgogKgogKiBAcGFja2FnZSB7e3RoZW1lX3BhY2thZ2V9fQogKi8KCmlmICggUEhQX01BSk9SX1ZFUlNJT04gPj0gOCApIHsKCWVjaG8gIlRoZSBzY2FmZm9sZGVkIHRlc3RzIGNhbm5vdCBjdXJyZW50bHkgYmUgcnVuIG9uIFBIUCA4LjArLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3dwLWNsaS9zY2FmZm9sZC1jb21tYW5kL2lzc3Vlcy8yODUiIC4gUEhQX0VPTDsgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5TZWN1cml0eS5Fc2NhcGVPdXRwdXQuT3V0cHV0Tm90RXNjYXBlZAoJZXhpdCggMSApOwp9CgokX3Rlc3RzX2RpciA9IGdldGVudiggJ1dQX1RFU1RTX0RJUicgKTsKCmlmICggISAkX3Rlc3RzX2RpciApIHsKCSRfdGVzdHNfZGlyID0gcnRyaW0oIHN5c19nZXRfdGVtcF9kaXIoKSwgJy9cXCcgKSAuICcvd29yZHByZXNzLXRlc3RzLWxpYic7Cn0KCmlmICggISBmaWxlX2V4aXN0cyggJF90ZXN0c19kaXIgLiAnL2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAnICkgKSB7CgllY2hvICJDb3VsZCBub3QgZmluZCB7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAsIGhhdmUgeW91IHJ1biBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCA/IiAuIFBIUF9FT0w7CglleGl0KCAxICk7Cn0KCi8vIEdpdmUgYWNjZXNzIHRvIHRlc3RzX2FkZF9maWx0ZXIoKSBmdW5jdGlvbi4KcmVxdWlyZV9vbmNlICJ7JF90ZXN0c19kaXJ9L2luY2x1ZGVzL2Z1bmN0aW9ucy5waHAiOwoKLyoqCiAqIFJlZ2lzdGVycyB0aGVtZS4KICovCmZ1bmN0aW9uIF9yZWdpc3Rlcl90aGVtZSgpIHsKCgkkdGhlbWVfZGlyICAgICA9IGRpcm5hbWUoIF9fRElSX18gKTsKCSRjdXJyZW50X3RoZW1lID0gYmFzZW5hbWUoICR0aGVtZV9kaXIgKTsKCSR0aGVtZV9yb290ICAgID0gZGlybmFtZSggJHRoZW1lX2RpciApOwoKCWFkZF9maWx0ZXIoICd0aGVtZV9yb290JywgZnVuY3Rpb24gKCkgdXNlICggJHRoZW1lX3Jvb3QgKSB7CgkJcmV0dXJuICR0aGVtZV9yb290OwoJfSApOwoKCXJlZ2lzdGVyX3RoZW1lX2RpcmVjdG9yeSggJHRoZW1lX3Jvb3QgKTsKCglhZGRfZmlsdGVyKCAncHJlX29wdGlvbl90ZW1wbGF0ZScsIGZ1bmN0aW9uICgpIHVzZSAoICRjdXJyZW50X3RoZW1lICkgewoJCXJldHVybiAkY3VycmVudF90aGVtZTsKCX0gKTsKCglhZGRfZmlsdGVyKCAncHJlX29wdGlvbl9zdHlsZXNoZWV0JywgZnVuY3Rpb24gKCkgdXNlICggJGN1cnJlbnRfdGhlbWUgKSB7CgkJcmV0dXJuICRjdXJyZW50X3RoZW1lOwoJfSApOwp9Cgp0ZXN0c19hZGRfZmlsdGVyKCAnbXVwbHVnaW5zX2xvYWRlZCcsICdfcmVnaXN0ZXJfdGhlbWUnICk7CgovLyBTdGFydCB1cCB0aGUgV1AgdGVzdGluZyBlbnZpcm9ubWVudC4KcmVxdWlyZSAieyRfdGVzdHNfZGlyfS9pbmNsdWRlcy9ib290c3RyYXAucGhwIjsKPD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwaHB1bml0Cglib290c3RyYXA9InRlc3RzL2Jvb3RzdHJhcC5waHAiCgliYWNrdXBHbG9iYWxzPSJmYWxzZSIKCWNvbG9ycz0idHJ1ZSIKCWNvbnZlcnRFcnJvcnNUb0V4Y2VwdGlvbnM9InRydWUiCgljb252ZXJ0Tm90aWNlc1RvRXhjZXB0aW9ucz0idHJ1ZSIKCWNvbnZlcnRXYXJuaW5nc1RvRXhjZXB0aW9ucz0idHJ1ZSIKCT4KCTx0ZXN0c3VpdGVzPgoJCTx0ZXN0c3VpdGU+CgkJCTxkaXJlY3RvcnkgcHJlZml4PSJ0ZXN0LSIgc3VmZml4PSIucGhwIj4uL3Rlc3RzLzwvZGlyZWN0b3J5PgoJCQk8ZXhjbHVkZT4uL3Rlc3RzL3Rlc3Qtc2FtcGxlLnBocDwvZXhjbHVkZT4KCQk8L3Rlc3RzdWl0ZT4KCTwvdGVzdHN1aXRlcz4KPC9waHB1bml0Pgp2YXJpYWJsZXM6CiAgIyBDb25maWd1cmUgbXlzcWwgc2VydmljZSAoaHR0cHM6Ly9odWIuZG9ja2VyLmNvbS9fL215c3FsLykKICBNWVNRTF9EQVRBQkFTRTogd29yZHByZXNzX3Rlc3RzCiAgTVlTUUxfUk9PVF9QQVNTV09SRDogbXlzcWwKCmJlZm9yZV9zY3JpcHQ6CiAgIyBJbnN0YWxsIGRlcGVuZGVuY2llcwogIAogICMgdXBkYXRlIHRoZSBkb2NrZXIKICAtIGFwdC1nZXQgY2xlYW4KICAtIGFwdC1nZXQgLXlxcSB1cGRhdGUKCiAgIyBpbnN0bGwgdGhlIHJlcXVpcmVkIHBhY2thZ2VzIGZvciB0aGUgcnVubmluZyBDSSB0ZXN0cwogIC0gYXB0LWdldCAteXFxZiBpbnN0YWxsIHppcCB1bnppcCBzdWJ2ZXJzaW9uIG15c3FsLWNsaWVudCBsaWJteXNxbGNsaWVudC1kZXYgLS1maXgtbWlzc2luZwoKICAjIFBIUCBleHRlbnNpb25zCiAgLSBkb2NrZXItcGhwLWV4dC1lbmFibGUgbWJzdHJpbmcgbWNyeXB0IG15c3FsaSBwZG9fbXlzcWwgaW50bCBnZCB6aXAgYnoyCgogICMgU2V0IHVwIFdvcmRQcmVzcyB0ZXN0cwogIC0gYmFzaCBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCB3b3JkcHJlc3NfdGVzdHMgcm9vdCBteXNxbCBteXNxbCBsYXRlc3QgdHJ1ZQoKICAjIEluc3RhbGwgUEhQQ1MgYW5kIFdQQ1MKICAtIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlICJzcXVpemxhYnMvcGhwX2NvZGVzbmlmZmVyPSoiCiAgLSBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSAid3AtY29kaW5nLXN0YW5kYXJkcy93cGNzIgogIC0gcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3dwLWNvZGluZy1zdGFuZGFyZHMvd3BjcwoKUEhQdW5pdDpQSFA1LjM6TXlTUUw6CiAgaW1hZ2U6IHRldHJhd2ViL3BocDo1LjMKICBzZXJ2aWNlczoKICAgIC0gbXlzcWw6NS42CiAgc2NyaXB0OgogIC0gcGhwY3MKICAtIHBocHVuaXQKClBIUHVuaXQ6UEhQNS42Ok15U1FMOgogIGltYWdlOiB0ZXRyYXdlYi9waHA6NS42CiAgc2VydmljZXM6CiAgICAtIG15c3FsOjUuNgogIHNjcmlwdDoKICAtIHBocGNzCiAgLSBwaHB1bml0CiAgClBIUHVuaXQ6UEhQNy4wOk15U1FMOgogIGltYWdlOiB0ZXRyYXdlYi9waHA6Ny4wCiAgc2VydmljZXM6CiAgICAtIG15c3FsOjUuNgogIHNjcmlwdDoKICAtIHBocGNzCiAgLSBwaHB1bml0CgpQSFB1bml0OlBIUDcuMTpNeVNRTDoKICBpbWFnZTogdGV0cmF3ZWIvcGhwOjcuMQogIHNlcnZpY2VzOgogICAgLSBteXNxbDo1LjYKICBzY3JpcHQ6CiAgLSBwaHBjcwogIC0gcGhwdW5pdAoKUEhQdW5pdDpQSFA3LjI6TXlTUUw6CiAgaW1hZ2U6IHRldHJhd2ViL3BocDo3LjIKICBzZXJ2aWNlczoKICAgIC0gbXlzcWw6NS42CiAgc2NyaXB0OgogIC0gcGhwY3MKICAtIHBocHVuaXQKPT09IHt7cGx1Z2luX25hbWV9fSA9PT0KQ29udHJpYnV0b3JzOiAodGhpcyBzaG91bGQgYmUgYSBsaXN0IG9mIHdvcmRwcmVzcy5vcmcgdXNlcmlkJ3MpCkRvbmF0ZSBsaW5rOiBodHRwczovL2V4YW1wbGUuY29tLwpUYWdzOiBjb21tZW50cywgc3BhbQpSZXF1aXJlcyBhdCBsZWFzdDogNC41ClRlc3RlZCB1cCB0bzoge3twbHVnaW5fdGVzdGVkX3VwX3RvfX0KUmVxdWlyZXMgUEhQOiA1LjYKU3RhYmxlIHRhZzogMC4xLjAKTGljZW5zZTogR1BMdjIgb3IgbGF0ZXIKTGljZW5zZSBVUkk6IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC5odG1sCgpIZXJlIGlzIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIHBsdWdpbi4gIFRoaXMgc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiAxNTAgY2hhcmFjdGVycy4gIE5vIG1hcmt1cCBoZXJlLgoKPT0gRGVzY3JpcHRpb24gPT0KClRoaXMgaXMgdGhlIGxvbmcgZGVzY3JpcHRpb24uICBObyBsaW1pdCwgYW5kIHlvdSBjYW4gdXNlIE1hcmtkb3duIChhcyB3ZWxsIGFzIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMpLgoKRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBpZiB0aGlzIHNlY3Rpb24gaXMgbWlzc2luZywgdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzaG9ydCBkZXNjcmlwdGlvbiB3aWxsIGJlIHVzZWQsIGFuZApNYXJrZG93biBwYXJzZWQuCgpBIGZldyBub3RlcyBhYm91dCB0aGUgc2VjdGlvbnMgYWJvdmU6CgoqICAgIkNvbnRyaWJ1dG9ycyIgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB3cC5vcmcvd3AtcGx1Z2lucy5vcmcgdXNlcm5hbWVzCiogICAiVGFncyIgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB0YWdzIHRoYXQgYXBwbHkgdG8gdGhlIHBsdWdpbgoqICAgIlJlcXVpcmVzIGF0IGxlYXN0IiBpcyB0aGUgbG93ZXN0IHZlcnNpb24gdGhhdCB0aGUgcGx1Z2luIHdpbGwgd29yayBvbgoqICAgIlRlc3RlZCB1cCB0byIgaXMgdGhlIGhpZ2hlc3QgdmVyc2lvbiB0aGF0IHlvdSd2ZSAqc3VjY2Vzc2Z1bGx5IHVzZWQgdG8gdGVzdCB0aGUgcGx1Z2luKi4gTm90ZSB0aGF0IGl0IG1pZ2h0IHdvcmsgb24KaGlnaGVyIHZlcnNpb25zLi4uIHRoaXMgaXMganVzdCB0aGUgaGlnaGVzdCBvbmUgeW91J3ZlIHZlcmlmaWVkLgoqICAgU3RhYmxlIHRhZyBzaG91bGQgaW5kaWNhdGUgdGhlIFN1YnZlcnNpb24gInRhZyIgb2YgdGhlIGxhdGVzdCBzdGFibGUgdmVyc2lvbiwgb3IgInRydW5rLCIgaWYgeW91IHVzZSBgL3RydW5rL2AgZm9yCnN0YWJsZS4KCiAgICBOb3RlIHRoYXQgdGhlIGByZWFkbWUudHh0YCBvZiB0aGUgc3RhYmxlIHRhZyBpcyB0aGUgb25lIHRoYXQgaXMgY29uc2lkZXJlZCB0aGUgZGVmaW5pbmcgb25lIGZvciB0aGUgcGx1Z2luLCBzbwppZiB0aGUgYC90cnVuay9yZWFkbWUudHh0YCBmaWxlIHNheXMgdGhhdCB0aGUgc3RhYmxlIHRhZyBpcyBgNC4zYCwgdGhlbiBpdCBpcyBgL3RhZ3MvNC4zL3JlYWRtZS50eHRgIHRoYXQnbGwgYmUgdXNlZApmb3IgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGx1Z2luLiAgSW4gdGhpcyBzaXR1YXRpb24sIHRoZSBvbmx5IHRoaW5nIGNvbnNpZGVyZWQgZnJvbSB0aGUgdHJ1bmsgYHJlYWRtZS50eHRgCmlzIHRoZSBzdGFibGUgdGFnIHBvaW50ZXIuICBUaHVzLCBpZiB5b3UgZGV2ZWxvcCBpbiB0cnVuaywgeW91IGNhbiB1cGRhdGUgdGhlIHRydW5rIGByZWFkbWUudHh0YCB0byByZWZsZWN0IGNoYW5nZXMgaW4KeW91ciBpbi1kZXZlbG9wbWVudCB2ZXJzaW9uLCB3aXRob3V0IGhhdmluZyB0aGF0IGluZm9ybWF0aW9uIGluY29ycmVjdGx5IGRpc2Nsb3NlZCBhYm91dCB0aGUgY3VycmVudCBzdGFibGUgdmVyc2lvbgp0aGF0IGxhY2tzIHRob3NlIGNoYW5nZXMgLS0gYXMgbG9uZyBhcyB0aGUgdHJ1bmsncyBgcmVhZG1lLnR4dGAgcG9pbnRzIHRvIHRoZSBjb3JyZWN0IHN0YWJsZSB0YWcuCgogICAgSWYgbm8gc3RhYmxlIHRhZyBpcyBwcm92aWRlZCwgaXQgaXMgYXNzdW1lZCB0aGF0IHRydW5rIGlzIHN0YWJsZSwgYnV0IHlvdSBzaG91bGQgc3BlY2lmeSAidHJ1bmsiIGlmIHRoYXQncyB3aGVyZQp5b3UgcHV0IHRoZSBzdGFibGUgdmVyc2lvbiwgaW4gb3JkZXIgdG8gZWxpbWluYXRlIGFueSBkb3VidC4KCj09IEluc3RhbGxhdGlvbiA9PQoKVGhpcyBzZWN0aW9uIGRlc2NyaWJlcyBob3cgdG8gaW5zdGFsbCB0aGUgcGx1Z2luIGFuZCBnZXQgaXQgd29ya2luZy4KCmUuZy4KCjEuIFVwbG9hZCBgcGx1Z2luLW5hbWUucGhwYCB0byB0aGUgYC93cC1jb250ZW50L3BsdWdpbnMvYCBkaXJlY3RvcnkKMS4gQWN0aXZhdGUgdGhlIHBsdWdpbiB0aHJvdWdoIHRoZSAnUGx1Z2lucycgbWVudSBpbiBXb3JkUHJlc3MKMS4gUGxhY2UgYDw/cGhwIGRvX2FjdGlvbigncGx1Z2luX25hbWVfaG9vaycpOyA/PmAgaW4geW91ciB0ZW1wbGF0ZXMKCj09IEZyZXF1ZW50bHkgQXNrZWQgUXVlc3Rpb25zID09Cgo9IEEgcXVlc3Rpb24gdGhhdCBzb21lb25lIG1pZ2h0IGhhdmUgPQoKQW4gYW5zd2VyIHRvIHRoYXQgcXVlc3Rpb24uCgo9IFdoYXQgYWJvdXQgZm9vIGJhcj8gPQoKQW5zd2VyIHRvIGZvbyBiYXIgZGlsZW1tYS4KCj09IFNjcmVlbnNob3RzID09CgoxLiBUaGlzIHNjcmVlbiBzaG90IGRlc2NyaXB0aW9uIGNvcnJlc3BvbmRzIHRvIHNjcmVlbnNob3QtMS4ocG5nfGpwZ3xqcGVnfGdpZikuIE5vdGUgdGhhdCB0aGUgc2NyZWVuc2hvdCBpcyB0YWtlbiBmcm9tCnRoZSAvYXNzZXRzIGRpcmVjdG9yeSBvciB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIHN0YWJsZSByZWFkbWUudHh0ICh0YWdzIG9yIHRydW5rKS4gU2NyZWVuc2hvdHMgaW4gdGhlIC9hc3NldHMKZGlyZWN0b3J5IHRha2UgcHJlY2VkZW5jZS4gRm9yIGV4YW1wbGUsIGAvYXNzZXRzL3NjcmVlbnNob3QtMS5wbmdgIHdvdWxkIHdpbiBvdmVyIGAvdGFncy80LjMvc2NyZWVuc2hvdC0xLnBuZ2AKKG9yIGpwZywganBlZywgZ2lmKS4KMi4gVGhpcyBpcyB0aGUgc2Vjb25kIHNjcmVlbiBzaG90Cgo9PSBDaGFuZ2Vsb2cgPT0KCj0gMS4wID0KKiBBIGNoYW5nZSBzaW5jZSB0aGUgcHJldmlvdXMgdmVyc2lvbi4KKiBBbm90aGVyIGNoYW5nZS4KCj0gMC41ID0KKiBMaXN0IHZlcnNpb25zIGZyb20gbW9zdCByZWNlbnQgYXQgdG9wIHRvIG9sZGVzdCBhdCBib3R0b20uCgo9PSBVcGdyYWRlIE5vdGljZSA9PQoKPSAxLjAgPQpVcGdyYWRlIG5vdGljZXMgZGVzY3JpYmUgdGhlIHJlYXNvbiBhIHVzZXIgc2hvdWxkIHVwZ3JhZGUuICBObyBtb3JlIHRoYW4gMzAwIGNoYXJhY3RlcnMuCgo9IDAuNSA9ClRoaXMgdmVyc2lvbiBmaXhlcyBhIHNlY3VyaXR5IHJlbGF0ZWQgYnVnLiAgVXBncmFkZSBpbW1lZGlhdGVseS4KCj09IEFyYml0cmFyeSBzZWN0aW9uID09CgpZb3UgbWF5IHByb3ZpZGUgYXJiaXRyYXJ5IHNlY3Rpb25zLCBpbiB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG9uZXMgYWJvdmUuICBUaGlzIG1heSBiZSBvZiB1c2UgZm9yIGV4dHJlbWVseSBjb21wbGljYXRlZApwbHVnaW5zIHdoZXJlIG1vcmUgaW5mb3JtYXRpb24gbmVlZHMgdG8gYmUgY29udmV5ZWQgdGhhdCBkb2Vzbid0IGZpdCBpbnRvIHRoZSBjYXRlZ29yaWVzIG9mICJkZXNjcmlwdGlvbiIgb3IKImluc3RhbGxhdGlvbi4iICBBcmJpdHJhcnkgc2VjdGlvbnMgd2lsbCBiZSBzaG93biBiZWxvdyB0aGUgYnVpbHQtaW4gc2VjdGlvbnMgb3V0bGluZWQgYWJvdmUuCgo9PSBBIGJyaWVmIE1hcmtkb3duIEV4YW1wbGUgPT0KCk9yZGVyZWQgbGlzdDoKCjEuIFNvbWUgZmVhdHVyZQoxLiBBbm90aGVyIGZlYXR1cmUKMS4gU29tZXRoaW5nIGVsc2UgYWJvdXQgdGhlIHBsdWdpbgoKVW5vcmRlcmVkIGxpc3Q6CgoqIHNvbWV0aGluZwoqIHNvbWV0aGluZyBlbHNlCiogdGhpcmQgdGhpbmcKCkhlcmUncyBhIGxpbmsgdG8gW1dvcmRQcmVzc10oaHR0cHM6Ly93b3JkcHJlc3Mub3JnLyAiWW91ciBmYXZvcml0ZSBzb2Z0d2FyZSIpIGFuZCBvbmUgdG8gW01hcmtkb3duJ3MgU3ludGF4IERvY3VtZW50YXRpb25dW21hcmtkb3duIHN5bnRheF0uClRpdGxlcyBhcmUgb3B0aW9uYWwsIG5hdHVyYWxseS4KClttYXJrZG93biBzeW50YXhdOiBodHRwczovL2RhcmluZ2ZpcmViYWxsLm5ldC9wcm9qZWN0cy9tYXJrZG93bi9zeW50YXgKICAgICAgICAgICAgIk1hcmtkb3duIGlzIHdoYXQgdGhlIHBhcnNlciB1c2VzIHRvIHByb2Nlc3MgbXVjaCBvZiB0aGUgcmVhZG1lIGZpbGUiCgpNYXJrZG93biB1c2VzIGVtYWlsIHN0eWxlIG5vdGF0aW9uIGZvciBibG9ja3F1b3RlcyBhbmQgSSd2ZSBiZWVuIHRvbGQ6Cj4gQXN0ZXJpc2tzIGZvciAqZW1waGFzaXMqLiBEb3VibGUgaXQgdXAgIGZvciAqKnN0cm9uZyoqLgoKYDw/cGhwIGNvZGUoKTsgLy8gZ29lcyBpbiBiYWNrdGlja3MgPz5gCi8qKgogKiBUaGUgZm9sbG93aW5nIHN0eWxlcyBnZXQgYXBwbGllZCBib3RoIG9uIHRoZSBmcm9udCBvZiB5b3VyIHNpdGUgYW5kIGluIHRoZSBlZGl0b3IuCiAqCiAqIFJlcGxhY2UgdGhlbSB3aXRoIHlvdXIgb3duIHN0eWxlcyBvciByZW1vdmUgdGhlIGZpbGUgY29tcGxldGVseS4KICovCgoud3AtYmxvY2ste3tuYW1lc3BhY2V9fS17e3NsdWd9fSB7CgliYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwoJY29sb3I6ICNmZmY7CglwYWRkaW5nOiAycHg7Cn0KCXJlZ2lzdGVyX3Bvc3RfdHlwZSgKCQkne3tzbHVnfX0nLAoJCVsKCQkJJ2xhYmVscycgICAgICAgICAgICAgICAgPT4gWwoJCQkJJ25hbWUnICAgICAgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknc2luZ3VsYXJfbmFtZScgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ2FsbF9pdGVtcycgICAgICAgICAgICAgPT4gX18oICdBbGwge3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ2FyY2hpdmVzJyAgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSBBcmNoaXZlcycsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdhdHRyaWJ1dGVzJyAgICAgICAgICAgID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gQXR0cmlidXRlcycsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdpbnNlcnRfaW50b19pdGVtJyAgICAgID0+IF9fKCAnSW5zZXJ0IGludG8ge3tsYWJlbH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ3VwbG9hZGVkX3RvX3RoaXNfaXRlbScgPT4gX18oICdVcGxvYWRlZCB0byB0aGlzIHt7bGFiZWx9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdmZWF0dXJlZF9pbWFnZScgICAgICAgID0+IF94KCAnRmVhdHVyZWQgSW1hZ2UnLCAne3tzbHVnfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknc2V0X2ZlYXR1cmVkX2ltYWdlJyAgICA9PiBfeCggJ1NldCBmZWF0dXJlZCBpbWFnZScsICd7e3NsdWd9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdyZW1vdmVfZmVhdHVyZWRfaW1hZ2UnID0+IF94KCAnUmVtb3ZlIGZlYXR1cmVkIGltYWdlJywgJ3t7c2x1Z319JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ3VzZV9mZWF0dXJlZF9pbWFnZScgICAgPT4gX3goICdVc2UgYXMgZmVhdHVyZWQgaW1hZ2UnLCAne3tzbHVnfX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknZmlsdGVyX2l0ZW1zX2xpc3QnICAgICA9PiBfXyggJ0ZpbHRlciB7e2xhYmVsX3BsdXJhbH19IGxpc3QnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknaXRlbXNfbGlzdF9uYXZpZ2F0aW9uJyA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fSBsaXN0IG5hdmlnYXRpb24nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknaXRlbXNfbGlzdCcgICAgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fSBsaXN0JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ25ld19pdGVtJyAgICAgICAgICAgICAgPT4gX18oICdOZXcge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknYWRkX25ldycgICAgICAgICAgICAgICA9PiBfXyggJ0FkZCBOZXcnLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknYWRkX25ld19pdGVtJyAgICAgICAgICA9PiBfXyggJ0FkZCBOZXcge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQknZWRpdF9pdGVtJyAgICAgICAgICAgICA9PiBfXyggJ0VkaXQge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQkndmlld19pdGVtJyAgICAgICAgICAgICA9PiBfXyggJ1ZpZXcge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCQkndmlld19pdGVtcycgICAgICAgICAgICA9PiBfXyggJ1ZpZXcge3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQkJJ3NlYXJjaF9pdGVtcycgICAgICAgICAgPT4gX18oICdTZWFyY2gge3tsYWJlbF9wbHVyYWx9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdub3RfZm91bmQnICAgICAgICAgICAgID0+IF9fKCAnTm8ge3tsYWJlbF9wbHVyYWx9fSBmb3VuZCcsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdub3RfZm91bmRfaW5fdHJhc2gnICAgID0+IF9fKCAnTm8ge3tsYWJlbF9wbHVyYWx9fSBmb3VuZCBpbiB0cmFzaCcsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdwYXJlbnRfaXRlbV9jb2xvbicgICAgID0+IF9fKCAnUGFyZW50IHt7bGFiZWxfdWNmaXJzdH19OicsICd7e3RleHRkb21haW59fScgKSwKCQkJCSdtZW51X25hbWUnICAgICAgICAgICAgID0+IF9fKCAne3tsYWJlbF9wbHVyYWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQldLAoJCQkncHVibGljJyAgICAgICAgICAgICAgICA9PiB0cnVlLAoJCQknaGllcmFyY2hpY2FsJyAgICAgICAgICA9PiBmYWxzZSwKCQkJJ3Nob3dfdWknICAgICAgICAgICAgICAgPT4gdHJ1ZSwKCQkJJ3Nob3dfaW5fbmF2X21lbnVzJyAgICAgPT4gdHJ1ZSwKCQkJJ3N1cHBvcnRzJyAgICAgICAgICAgICAgPT4gWyAndGl0bGUnLCAnZWRpdG9yJyBdLAoJCQknaGFzX2FyY2hpdmUnICAgICAgICAgICA9PiB0cnVlLAoJCQkncmV3cml0ZScgICAgICAgICAgICAgICA9PiB0cnVlLAoJCQkncXVlcnlfdmFyJyAgICAgICAgICAgICA9PiB0cnVlLAoJCQknbWVudV9wb3NpdGlvbicgICAgICAgICA9PiBudWxsLAoJCQknbWVudV9pY29uJyAgICAgICAgICAgICA9PiAnZGFzaGljb25zLXt7ZGFzaGljb259fScsCgkJCSdzaG93X2luX3Jlc3QnICAgICAgICAgID0+IHRydWUsCgkJCSdyZXN0X2Jhc2UnICAgICAgICAgICAgID0+ICd7e3NsdWd9fScsCgkJCSdyZXN0X2NvbnRyb2xsZXJfY2xhc3MnID0+ICdXUF9SRVNUX1Bvc3RzX0NvbnRyb2xsZXInLAoJCV0KCSk7Cjw/cGhwCi8qKgogKiBDbGFzcyBTYW1wbGVUZXN0CiAqCiAqIEBwYWNrYWdlIHt7cGx1Z2luX3BhY2thZ2V9fQogKi8KCi8qKgogKiBTYW1wbGUgdGVzdCBjYXNlLgogKi8KY2xhc3MgU2FtcGxlVGVzdCBleHRlbmRzIFdQX1VuaXRUZXN0Q2FzZSB7CgoJLyoqCgkgKiBBIHNpbmdsZSBleGFtcGxlIHRlc3QuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0ZXN0X3NhbXBsZSgpIHsKCQkvLyBSZXBsYWNlIHRoaXMgd2l0aCBzb21lIGFjdHVhbCB0ZXN0aW5nIGNvZGUuCgkJJHRoaXMtPmFzc2VydFRydWUoIHRydWUgKTsKCX0KfQo8P3BocAovKioKICoge3t0aGVtZV9uYW1lfX0gVGhlbWUgZnVuY3Rpb25zIGFuZCBkZWZpbml0aW9ucy4KICoKICogQGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIud29yZHByZXNzLm9yZy90aGVtZXMvYmFzaWNzL3RoZW1lLWZ1bmN0aW9ucy8KICoKICogQHBhY2thZ2Uge3tzbHVnfX0KICovCgphZGRfYWN0aW9uKCAnd3BfZW5xdWV1ZV9zY3JpcHRzJywgJ3t7cGFyZW50X3RoZW1lX2Z1bmN0aW9uX3NhZmV9fV9wYXJlbnRfdGhlbWVfZW5xdWV1ZV9zdHlsZXMnICk7CgovKioKICogRW5xdWV1ZSBzY3JpcHRzIGFuZCBzdHlsZXMuCiAqLwpmdW5jdGlvbiB7e3BhcmVudF90aGVtZV9mdW5jdGlvbl9zYWZlfX1fcGFyZW50X3RoZW1lX2VucXVldWVfc3R5bGVzKCkgewoJd3BfZW5xdWV1ZV9zdHlsZSggJ3t7cGFyZW50X3RoZW1lfX0tc3R5bGUnLCBnZXRfdGVtcGxhdGVfZGlyZWN0b3J5X3VyaSgpIC4gJy9zdHlsZS5jc3MnICk7Cgl3cF9lbnF1ZXVlX3N0eWxlKCAne3tzbHVnfX0tc3R5bGUnLAoJCWdldF9zdHlsZXNoZWV0X2RpcmVjdG9yeV91cmkoKSAuICcvc3R5bGUuY3NzJywKCQlbICd7e3BhcmVudF90aGVtZX19LXN0eWxlJyBdCgkpOwp9CiMgQSBzZXQgb2YgZmlsZXMgeW91IHByb2JhYmx5IGRvbid0IHdhbnQgaW4geW91ciBXb3JkUHJlc3Mub3JnIGRpc3RyaWJ1dGlvbgouYmFiZWxyYwouZGVwbG95aWdub3JlCi5kaXN0aWdub3JlCi5lZGl0b3Jjb25maWcKLmVzbGludGlnbm9yZQouZXNsaW50cmMKLmdpdAouZ2l0aWdub3JlCi5naXRodWIKLmdpdGxhYi1jaS55bWwKLnRyYXZpcy55bWwKLkRTX1N0b3JlClRodW1icy5kYgpiZWhhdC55bWwKYml0YnVja2V0LXBpcGVsaW5lcy55bWwKYmluCi5jaXJjbGVjaS9jb25maWcueW1sCmNvbXBvc2VyLmpzb24KY29tcG9zZXIubG9jawpkZXBlbmRlbmNpZXMueW1sCkdydW50ZmlsZS5qcwpwYWNrYWdlLmpzb24KcGFja2FnZS1sb2NrLmpzb24KcGhwdW5pdC54bWwKcGhwdW5pdC54bWwuZGlzdAptdWx0aXNpdGUueG1sCm11bHRpc2l0ZS54bWwuZGlzdAoucGhwY3MueG1sCnBocGNzLnhtbAoucGhwY3MueG1sLmRpc3QKcGhwY3MueG1sLmRpc3QKUkVBRE1FLm1kCndlYnBhY2suY29uZmlnLmpzCndwLWNsaS5sb2NhbC55bWwKeWFybi5sb2NrCnRlc3RzCnZlbmRvcgpub2RlX21vZHVsZXMKKi5zcWwKKi50YXIuZ3oKKi56aXAKPD9waHAKLyoqCiAqIFBsdWdpbiBOYW1lOiAgICAge3twbHVnaW5fbmFtZX19CiAqIFBsdWdpbiBVUkk6ICAgICAge3twbHVnaW5fdXJpfX0KICogRGVzY3JpcHRpb246ICAgICB7e3BsdWdpbl9kZXNjcmlwdGlvbn19CiAqIEF1dGhvcjogICAgICAgICAge3twbHVnaW5fYXV0aG9yfX0KICogQXV0aG9yIFVSSTogICAgICB7e3BsdWdpbl9hdXRob3JfdXJpfX0KICogVGV4dCBEb21haW46ICAgICB7e3RleHRkb21haW59fQogKiBEb21haW4gUGF0aDogICAgIC9sYW5ndWFnZXMKICogVmVyc2lvbjogICAgICAgICAwLjEuMAogKgogKiBAcGFja2FnZSAgICAgICAgIHt7cGx1Z2luX3BhY2thZ2V9fQogKi8KCi8vIFlvdXIgY29kZSBzdGFydHMgaGVyZS4KCnsKICAibmFtZSI6ICJ7e3BsdWdpbl9zbHVnfX0iLAogICJ2ZXJzaW9uIjogIjAuMS4wIiwKICAibWFpbiI6ICJHcnVudGZpbGUuanMiLAogICJhdXRob3IiOiAie3twbHVnaW5fYXV0aG9yfX0iLAogICJzY3JpcHRzIiA6IHsKICAgICJzdGFydCIgOiAiZ3J1bnQgZGVmYXVsdCIgLAogICAgInJlYWRtZSIgOiAiZ3J1bnQgcmVhZG1lIiwKICAgICJpMThuIiA6ICJncnVudCBpMThuIgogIH0sCiAgImRldkRlcGVuZGVuY2llcyI6IHsKICAgICJncnVudCI6ICJ+MC40LjUiLAogICAgImdydW50LXdwLWkxOG4iOiAifjAuNS4wIiwKICAgICJncnVudC13cC1yZWFkbWUtdG8tbWFya2Rvd24iOiAifjEuMC4wIgogIH0KfQo8P3BocAovKioKICogQ2xhc3MgU2FtcGxlVGVzdAogKgogKiBAcGFja2FnZSB7e3RoZW1lX3BhY2thZ2V9fQogKi8KCi8qKgogKiBTYW1wbGUgdGVzdCBjYXNlLgogKi8KY2xhc3MgU2FtcGxlVGVzdCBleHRlbmRzIFdQX1VuaXRUZXN0Q2FzZSB7CgoJLyoqCgkgKiBBIHNpbmdsZSBleGFtcGxlIHRlc3QuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiB0ZXN0X3NhbXBsZSgpIHsKCQkvLyBSZXBsYWNlIHRoaXMgd2l0aCBzb21lIGFjdHVhbCB0ZXN0aW5nIGNvZGUuCgkJJHRoaXMtPmFzc2VydFRydWUoIHRydWUgKTsKCX0KfQouRFNfU3RvcmUKcGhwY3MueG1sCnBocHVuaXQueG1sClRodW1icy5kYgp3cC1jbGkubG9jYWwueW1sCm5vZGVfbW9kdWxlcy8KKi5zcWwKKi50YXIuZ3oKKi56aXAKIyBUaGlzIGZpbGUgaXMgZm9yIHVuaWZ5aW5nIHRoZSBjb2Rpbmcgc3R5bGUgZm9yIGRpZmZlcmVudCBlZGl0b3JzIGFuZCBJREVzCiMgZWRpdG9yY29uZmlnLm9yZwoKIyBXb3JkUHJlc3MgQ29kaW5nIFN0YW5kYXJkcwojIGh0dHBzOi8vbWFrZS53b3JkcHJlc3Mub3JnL2NvcmUvaGFuZGJvb2svY29kaW5nLXN0YW5kYXJkcy8KCnJvb3QgPSB0cnVlCgpbKl0KY2hhcnNldCA9IHV0Zi04CmVuZF9vZl9saW5lID0gbGYKaW5zZXJ0X2ZpbmFsX25ld2xpbmUgPSB0cnVlCnRyaW1fdHJhaWxpbmdfd2hpdGVzcGFjZSA9IHRydWUKaW5kZW50X3N0eWxlID0gdGFiCmluZGVudF9zaXplID0gNAoKW3suanNoaW50cmMsKi5qc29uLCoueW1sfV0KaW5kZW50X3N0eWxlID0gc3BhY2UKaW5kZW50X3NpemUgPSAyCgpbeyoudHh0LHdwLWNvbmZpZy1zYW1wbGUucGhwfV0KZW5kX29mX2xpbmUgPSBjcmxmClRoZW1lICU5e3tzbHVnfX0lbiBkZXRhaWxzOgogICAgTmFtZToge3tuYW1lfX0KICAgIFN0YXR1czoge3tzdGF0dXN9fSVuCiAgICBWZXJzaW9uOiB7e3ZlcnNpb259fQogICAgQXV0aG9yOiB7e2F1dGhvcn19CndvcmtmbG93czoKICB2ZXJzaW9uOiAyCiAgbWFpbjoKICAgIGpvYnM6CiAgICAgIC0gcGhwNTYtYnVpbGQKICAgICAgLSBwaHA3MC1idWlsZAogICAgICAtIHBocDcxLWJ1aWxkCiAgICAgIC0gcGhwNzItYnVpbGQKICAgICAgLSBwaHA3My1idWlsZAogICAgICAtIHBocDc0LWJ1aWxkCgp2ZXJzaW9uOiAyCgpqb2ItcmVmZXJlbmNlczoKICBteXNxbF9pbWFnZTogJm15c3FsX2ltYWdlCiAgICBjaXJjbGVjaS9teXNxbDo1LjYKCiAgc2V0dXBfZW52aXJvbm1lbnQ6ICZzZXR1cF9lbnZpcm9ubWVudAogICAgbmFtZTogIlNldHVwIEVudmlyb25tZW50IFZhcmlhYmxlcyIKICAgIGNvbW1hbmQ6IHwKICAgICAgZWNobyAiZXhwb3J0IFBBVEg9JEhPTUUvLmNvbXBvc2VyL3ZlbmRvci9iaW46JFBBVEgiID4+ICRCQVNIX0VOVgogICAgICBzb3VyY2UgL2hvbWUvY2lyY2xlY2kvLmJhc2hyYwoKICBpbnN0YWxsX2RlcGVuZGVuY2llczogJmluc3RhbGxfZGVwZW5kZW5jaWVzCiAgICBuYW1lOiAiSW5zdGFsbCBEZXBlbmRlbmNpZXMiCiAgICBjb21tYW5kOiB8CiAgICAgIHN1ZG8gYXB0LWdldCB1cGRhdGUgJiYgc3VkbyBhcHQtZ2V0IGluc3RhbGwgc3VidmVyc2lvbgogICAgICBzdWRvIC1FIGRvY2tlci1waHAtZXh0LWluc3RhbGwgbXlzcWxpCiAgICAgIHN1ZG8gc2ggLWMgInByaW50ZiAnXG5kZWIgaHR0cDovL2Z0cC51cy5kZWJpYW4ub3JnL2RlYmlhbiBzaWQgbWFpblxuJyA+PiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QiCiAgICAgIHN1ZG8gYXB0LWdldCB1cGRhdGUgJiYgc3VkbyBhcHQtZ2V0IGluc3RhbGwgbXlzcWwtY2xpZW50LTUuNwoKICBwaHBfam9iOiAmcGhwX2pvYgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gV1BfVEVTVFNfRElSOiAiL3RtcC93b3JkcHJlc3MtdGVzdHMtbGliIgogICAgICAtIFdQX0NPUkVfRElSOiAiL3RtcC93b3JkcHJlc3MvIgogICAgc3RlcHM6CiAgICAgIC0gY2hlY2tvdXQKICAgICAgLSBydW46ICpzZXR1cF9lbnZpcm9ubWVudAogICAgICAtIHJ1bjogKmluc3RhbGxfZGVwZW5kZW5jaWVzCiAgICAgIC0gcnVuOgogICAgICAgICAgbmFtZTogIlJ1biBUZXN0cyIKICAgICAgICAgIGNvbW1hbmQ6IHwKICAgICAgICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgInBocHVuaXQvcGhwdW5pdD01LjcuKiIKICAgICAgICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgd3AtY29kaW5nLXN0YW5kYXJkcy93cGNzCiAgICAgICAgICAgIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci93cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MKICAgICAgICAgICAgcGhwY3MKICAgICAgICAgICAgcm0gLXJmICRXUF9URVNUU19ESVIgJFdQX0NPUkVfRElSCiAgICAgICAgICAgIGJhc2ggYmluL2luc3RhbGwtd3AtdGVzdHMuc2ggd29yZHByZXNzX3Rlc3Qgcm9vdCAnJyAxMjcuMC4wLjEgbGF0ZXN0CiAgICAgICAgICAgIHBocHVuaXQKICAgICAgICAgICAgV1BfTVVMVElTSVRFPTEgcGhwdW5pdAoKam9iczoKICBwaHA1Ni1idWlsZDoKICAgIDw8OiAqcGhwX2pvYgogICAgZG9ja2VyOgogICAgICAtIGltYWdlOiBjaXJjbGVjaS9waHA6NS42CiAgICAgIC0gaW1hZ2U6ICpteXNxbF9pbWFnZQogICAgc3RlcHM6CiAgICAgIC0gY2hlY2tvdXQKICAgICAgLSBydW46ICpzZXR1cF9lbnZpcm9ubWVudAogICAgICAtIHJ1bjogKmluc3RhbGxfZGVwZW5kZW5jaWVzCiAgICAgIC0gcnVuOgogICAgICAgICAgbmFtZTogIlJ1biBUZXN0cyIKICAgICAgICAgIGNvbW1hbmQ6IHwKICAgICAgICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgInBocHVuaXQvcGhwdW5pdD01LjcuKiIKICAgICAgICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgd3AtY29kaW5nLXN0YW5kYXJkcy93cGNzCiAgICAgICAgICAgIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci93cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MKICAgICAgICAgICAgcGhwY3MKICAgICAgICAgICAgU0tJUF9EQl9DUkVBVEU9ZmFsc2UKICAgICAgICAgICAge3sjd3BfdmVyc2lvbnNfdG9fdGVzdH19CiAgICAgICAgICAgIHJtIC1yZiAkV1BfVEVTVFNfRElSICRXUF9DT1JFX0RJUgogICAgICAgICAgICBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0IHJvb3QgJycgMTI3LjAuMC4xIHt7Ln19ICRTS0lQX0RCX0NSRUFURQogICAgICAgICAgICBwaHB1bml0CiAgICAgICAgICAgIFdQX01VTFRJU0lURT0xIHBocHVuaXQKICAgICAgICAgICAgU0tJUF9EQl9DUkVBVEU9dHJ1ZQogICAgICAgICAgICB7ey93cF92ZXJzaW9uc190b190ZXN0fX0KCiAgcGhwNzAtYnVpbGQ6CiAgICA8PDogKnBocF9qb2IKICAgIGRvY2tlcjoKICAgICAgLSBpbWFnZTogY2lyY2xlY2kvcGhwOjcuMAogICAgICAtIGltYWdlOiAqbXlzcWxfaW1hZ2UKCiAgcGhwNzEtYnVpbGQ6CiAgICA8PDogKnBocF9qb2IKICAgIGRvY2tlcjoKICAgICAgLSBpbWFnZTogY2lyY2xlY2kvcGhwOjcuMQogICAgICAtIGltYWdlOiAqbXlzcWxfaW1hZ2UKCiAgcGhwNzItYnVpbGQ6CiAgICA8PDogKnBocF9qb2IKICAgIGRvY2tlcjoKICAgICAgLSBpbWFnZTogY2lyY2xlY2kvcGhwOjcuMgogICAgICAtIGltYWdlOiAqbXlzcWxfaW1hZ2UKCiAgcGhwNzMtYnVpbGQ6CiAgICA8PDogKnBocF9qb2IKICAgIGRvY2tlcjoKICAgICAgLSBpbWFnZTogY2lyY2xlY2kvcGhwOjcuMwogICAgICAtIGltYWdlOiAqbXlzcWxfaW1hZ2UKCiAgcGhwNzQtYnVpbGQ6CiAgICA8PDogKnBocF9qb2IKICAgIGRvY2tlcjoKICAgICAgLSBpbWFnZTogY2lyY2xlY2kvcGhwOjcuNAogICAgICAtIGltYWdlOiAqbXlzcWxfaW1hZ2UKcGlwZWxpbmVzOgogIGRlZmF1bHQ6CiAgICAtIHN0ZXA6CiAgICAgICAgaW1hZ2U6IHBocDo1LjYKICAgICAgICBuYW1lOiAiUEhQIDUuNiIKICAgICAgICBzY3JpcHQ6CiAgICAgICAgICAjIEluc3RhbGwgRGVwZW5kZW5jaWVzCiAgICAgICAgICAtIGRvY2tlci1waHAtZXh0LWluc3RhbGwgbXlzcWxpCiAgICAgICAgICAtIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBzdWJ2ZXJzaW9uIC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUENTCiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwY3MgLWZTTCBodHRwczovL3NxdWl6bGFicy5naXRodWIuaW8vUEhQX0NvZGVTbmlmZmVyL3BocGNzLnBoYXIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwY3MKICAgICAgICAgIC0gcGhwY3MgLS12ZXJzaW9uCgogICAgICAgICAgIyBJbnN0YWxsIFdvcmRQcmVzcyBDb2RpbmcgU3RhbmRhcmRzCiAgICAgICAgICAtIFdQQ1NfVkVSU0lPTj0wLjE0LjEKICAgICAgICAgIC0gY3VybCAtbyB3cGNzLnRhci5neiAtZlNMICJodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvYXJjaGl2ZS8ke1dQQ1NfVkVSU0lPTn0udGFyLmd6IgogICAgICAgICAgLSBta2RpciAtcCAvdmFyL3dwY3MgJiYgdGFyIC14emYgd3Bjcy50YXIuZ3ogLS1kaXJlY3RvcnkgL3Zhci93cGNzIC0tc3RyaXAtY29tcG9uZW50cyAxICYmIHJtIHdwY3MudGFyLmd6CiAgICAgICAgICAtIHBocGNzIC0tY29uZmlnLXNldCBzaG93X3Byb2dyZXNzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGNvbG9ycyAxICYmIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgL3Zhci93cGNzCgogICAgICAgICAgIyMgUnVuIFBIUENTCiAgICAgICAgICAtIHBocGNzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUFVuaXQKICAgICAgICAgIC0gUEhQVU5JVF9WRVJTSU9OPTUuNy4yNwogICAgICAgICAgLSBjdXJsIC1vIC91c3IvbG9jYWwvYmluL3BocHVuaXQgImh0dHBzOi8vcGhhci5waHB1bml0LmRlL3BocHVuaXQtJHtQSFBVTklUX1ZFUlNJT059LnBoYXIiICYmIGNobW9kICt4IC91c3IvbG9jYWwvYmluL3BocHVuaXQKICAgICAgICAgIC0gcGhwdW5pdCAtLXZlcnNpb24KCiAgICAgICAgICAjIyBSdW4gUEhQVW5pdAogICAgICAgICAgLSBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0cyByb290IHJvb3QgMTI3LjAuMC4xIGxhdGVzdCB0cnVlCiAgICAgICAgICAtIHBocHVuaXQKICAgICAgICBzZXJ2aWNlczoKICAgICAgICAgIC0gZGF0YWJhc2UKCiAgICAtIHN0ZXA6CiAgICAgICAgaW1hZ2U6IHBocDo3LjAKICAgICAgICBuYW1lOiAiUEhQIDcuMCIKICAgICAgICBzY3JpcHQ6CiAgICAgICAgICAjIEluc3RhbGwgRGVwZW5kZW5jaWVzCiAgICAgICAgICAtIGRvY2tlci1waHAtZXh0LWluc3RhbGwgbXlzcWxpCiAgICAgICAgICAtIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBzdWJ2ZXJzaW9uIC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUENTCiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwY3MgLWZTTCBodHRwczovL3NxdWl6bGFicy5naXRodWIuaW8vUEhQX0NvZGVTbmlmZmVyL3BocGNzLnBoYXIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwY3MKICAgICAgICAgIC0gcGhwY3MgLS12ZXJzaW9uCgogICAgICAgICAgIyBJbnN0YWxsIFdvcmRQcmVzcyBDb2RpbmcgU3RhbmRhcmRzCiAgICAgICAgICAtIFdQQ1NfVkVSU0lPTj0wLjE0LjEKICAgICAgICAgIC0gY3VybCAtbyB3cGNzLnRhci5neiAtZlNMICJodHRwczovL2dpdGh1Yi5jb20vV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvV29yZFByZXNzLUNvZGluZy1TdGFuZGFyZHMvYXJjaGl2ZS8ke1dQQ1NfVkVSU0lPTn0udGFyLmd6IgogICAgICAgICAgLSBta2RpciAtcCAvdmFyL3dwY3MgJiYgdGFyIC14emYgd3Bjcy50YXIuZ3ogLS1kaXJlY3RvcnkgL3Zhci93cGNzIC0tc3RyaXAtY29tcG9uZW50cyAxICYmIHJtIHdwY3MudGFyLmd6CiAgICAgICAgICAtIHBocGNzIC0tY29uZmlnLXNldCBzaG93X3Byb2dyZXNzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGNvbG9ycyAxICYmIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgL3Zhci93cGNzCgogICAgICAgICAgIyMgUnVuIFBIUENTCiAgICAgICAgICAtIHBocGNzCgogICAgICAgICAgIyBJbnN0YWxsIFBIUFVuaXQKICAgICAgICAgIC0gUEhQVU5JVF9WRVJTSU9OPTYuNS42CiAgICAgICAgICAtIGN1cmwgLW8gL3Vzci9sb2NhbC9iaW4vcGhwdW5pdCAiaHR0cHM6Ly9waGFyLnBocHVuaXQuZGUvcGhwdW5pdC0ke1BIUFVOSVRfVkVSU0lPTn0ucGhhciIgJiYgY2htb2QgK3ggL3Vzci9sb2NhbC9iaW4vcGhwdW5pdAogICAgICAgICAgLSBwaHB1bml0IC0tdmVyc2lvbgoKICAgICAgICAgICMjIFJ1biBQSFBVbml0CiAgICAgICAgICAtIGJhc2ggYmluL2luc3RhbGwtd3AtdGVzdHMuc2ggd29yZHByZXNzX3Rlc3RzIHJvb3Qgcm9vdCAxMjcuMC4wLjEgbGF0ZXN0IHRydWUKICAgICAgICAgIC0gcGhwdW5pdAogICAgICAgIHNlcnZpY2VzOgogICAgICAgICAgLSBkYXRhYmFzZQoKICAgIC0gc3RlcDoKICAgICAgICBpbWFnZTogcGhwOjcuMQogICAgICAgIG5hbWU6ICJQSFAgNy4xIgogICAgICAgIHNjcmlwdDoKICAgICAgICAgICMgSW5zdGFsbCBEZXBlbmRlbmNpZXMKICAgICAgICAgIC0gZG9ja2VyLXBocC1leHQtaW5zdGFsbCBteXNxbGkKICAgICAgICAgIC0gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IHN1YnZlcnNpb24gLS1uby1pbnN0YWxsLXJlY29tbWVuZHMKCiAgICAgICAgICAjIEluc3RhbGwgUEhQQ1MKICAgICAgICAgIC0gY3VybCAtbyAvdXNyL2xvY2FsL2Jpbi9waHBjcyAtZlNMIGh0dHBzOi8vc3F1aXpsYWJzLmdpdGh1Yi5pby9QSFBfQ29kZVNuaWZmZXIvcGhwY3MucGhhciAmJiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9waHBjcwogICAgICAgICAgLSBwaHBjcyAtLXZlcnNpb24KCiAgICAgICAgICAjIEluc3RhbGwgV29yZFByZXNzIENvZGluZyBTdGFuZGFyZHMKICAgICAgICAgIC0gV1BDU19WRVJTSU9OPTAuMTQuMQogICAgICAgICAgLSBjdXJsIC1vIHdwY3MudGFyLmd6IC1mU0wgImh0dHBzOi8vZ2l0aHViLmNvbS9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9Xb3JkUHJlc3MtQ29kaW5nLVN0YW5kYXJkcy9hcmNoaXZlLyR7V1BDU19WRVJTSU9OfS50YXIuZ3oiCiAgICAgICAgICAtIG1rZGlyIC1wIC92YXIvd3BjcyAmJiB0YXIgLXh6ZiB3cGNzLnRhci5neiAtLWRpcmVjdG9yeSAvdmFyL3dwY3MgLS1zdHJpcC1jb21wb25lbnRzIDEgJiYgcm0gd3Bjcy50YXIuZ3oKICAgICAgICAgIC0gcGhwY3MgLS1jb25maWctc2V0IHNob3dfcHJvZ3Jlc3MgMSAmJiBwaHBjcyAtLWNvbmZpZy1zZXQgY29sb3JzIDEgJiYgcGhwY3MgLS1jb25maWctc2V0IGluc3RhbGxlZF9wYXRocyAvdmFyL3dwY3MKCiAgICAgICAgICAjIyBSdW4gUEhQQ1MKICAgICAgICAgIC0gcGhwY3MKCiAgICAgICAgICAjIEluc3RhbGwgUEhQVW5pdAogICAgICAgICAgLSBQSFBVTklUX1ZFUlNJT049Ni41LjYKICAgICAgICAgIC0gY3VybCAtbyAvdXNyL2xvY2FsL2Jpbi9waHB1bml0ICJodHRwczovL3BoYXIucGhwdW5pdC5kZS9waHB1bml0LSR7UEhQVU5JVF9WRVJTSU9OfS5waGFyIiAmJiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9waHB1bml0CiAgICAgICAgICAtIHBocHVuaXQgLS12ZXJzaW9uCgogICAgICAgICAgIyMgUnVuIFBIUFVuaXQKICAgICAgICAgIC0gYmFzaCBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCB3b3JkcHJlc3NfdGVzdHMgcm9vdCByb290IDEyNy4wLjAuMSBsYXRlc3QgdHJ1ZQogICAgICAgICAgLSBwaHB1bml0CiAgICAgICAgc2VydmljZXM6CiAgICAgICAgICAtIGRhdGFiYXNlCgogICAgLSBzdGVwOgogICAgICAgIGltYWdlOiBwaHA6Ny4yCiAgICAgICAgbmFtZTogIlBIUCA3LjIiCiAgICAgICAgc2NyaXB0OgogICAgICAgICAgIyBJbnN0YWxsIERlcGVuZGVuY2llcwogICAgICAgICAgLSBkb2NrZXItcGhwLWV4dC1pbnN0YWxsIG15c3FsaQogICAgICAgICAgLSBhcHQtZ2V0IHVwZGF0ZSAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgc3VidmVyc2lvbiAtLW5vLWluc3RhbGwtcmVjb21tZW5kcwoKICAgICAgICAgICMgSW5zdGFsbCBQSFBDUwogICAgICAgICAgLSBjdXJsIC1vIC91c3IvbG9jYWwvYmluL3BocGNzIC1mU0wgaHR0cHM6Ly9zcXVpemxhYnMuZ2l0aHViLmlvL1BIUF9Db2RlU25pZmZlci9waHBjcy5waGFyICYmIGNobW9kICt4IC91c3IvbG9jYWwvYmluL3BocGNzCiAgICAgICAgICAtIHBocGNzIC0tdmVyc2lvbgoKICAgICAgICAgICMgSW5zdGFsbCBXb3JkUHJlc3MgQ29kaW5nIFN0YW5kYXJkcwogICAgICAgICAgLSBXUENTX1ZFUlNJT049MC4xNC4xCiAgICAgICAgICAtIGN1cmwgLW8gd3Bjcy50YXIuZ3ogLWZTTCAiaHR0cHM6Ly9naXRodWIuY29tL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzL1dvcmRQcmVzcy1Db2RpbmctU3RhbmRhcmRzL2FyY2hpdmUvJHtXUENTX1ZFUlNJT059LnRhci5neiIKICAgICAgICAgIC0gbWtkaXIgLXAgL3Zhci93cGNzICYmIHRhciAteHpmIHdwY3MudGFyLmd6IC0tZGlyZWN0b3J5IC92YXIvd3BjcyAtLXN0cmlwLWNvbXBvbmVudHMgMSAmJiBybSB3cGNzLnRhci5negogICAgICAgICAgLSBwaHBjcyAtLWNvbmZpZy1zZXQgc2hvd19wcm9ncmVzcyAxICYmIHBocGNzIC0tY29uZmlnLXNldCBjb2xvcnMgMSAmJiBwaHBjcyAtLWNvbmZpZy1zZXQgaW5zdGFsbGVkX3BhdGhzIC92YXIvd3BjcwoKICAgICAgICAgICMjIFJ1biBQSFBDUwogICAgICAgICAgLSBwaHBjcwoKICAgICAgICAgICMgSW5zdGFsbCBQSFBVbml0CiAgICAgICAgICAtIFBIUFVOSVRfVkVSU0lPTj02LjUuNgogICAgICAgICAgLSBjdXJsIC1vIC91c3IvbG9jYWwvYmluL3BocHVuaXQgImh0dHBzOi8vcGhhci5waHB1bml0LmRlL3BocHVuaXQtJHtQSFBVTklUX1ZFUlNJT059LnBoYXIiICYmIGNobW9kICt4IC91c3IvbG9jYWwvYmluL3BocHVuaXQKICAgICAgICAgIC0gcGhwdW5pdCAtLXZlcnNpb24KCiAgICAgICAgICAjIyBSdW4gUEhQVW5pdAogICAgICAgICAgLSBiYXNoIGJpbi9pbnN0YWxsLXdwLXRlc3RzLnNoIHdvcmRwcmVzc190ZXN0cyByb290IHJvb3QgMTI3LjAuMC4xIGxhdGVzdCB0cnVlCiAgICAgICAgICAtIHBocHVuaXQKICAgICAgICBzZXJ2aWNlczoKICAgICAgICAgIC0gZGF0YWJhc2UKCmRlZmluaXRpb25zOgogIHNlcnZpY2VzOgogICAgZGF0YWJhc2U6CiAgICAgIGltYWdlOiBteXNxbDpsYXRlc3QKICAgICAgZW52aXJvbm1lbnQ6CiAgICAgICAgTVlTUUxfREFUQUJBU0U6ICd3b3JkcHJlc3NfdGVzdHMnCiAgICAgICAgTVlTUUxfUk9PVF9QQVNTV09SRDogJ3Jvb3QnCnN1ZG86IGZhbHNlCmRpc3Q6IHRydXN0eQoKbGFuZ3VhZ2U6IHBocAoKbm90aWZpY2F0aW9uczoKICBlbWFpbDoKICAgIG9uX3N1Y2Nlc3M6IG5ldmVyCiAgICBvbl9mYWlsdXJlOiBjaGFuZ2UKCmJyYW5jaGVzOgogIG9ubHk6CiAgICAtIG1hc3RlcgoKY2FjaGU6CiAgZGlyZWN0b3JpZXM6CiAgICAtICRIT01FLy5jb21wb3Nlci9jYWNoZQoKbWF0cml4OgogIGluY2x1ZGU6CiAgICAtIHBocDogNy40CiAgICAgIGVudjogV1BfVkVSU0lPTj1sYXRlc3QKICAgIC0gcGhwOiA3LjMKICAgICAgZW52OiBXUF9WRVJTSU9OPWxhdGVzdAogICAgLSBwaHA6IDcuMgogICAgICBlbnY6IFdQX1ZFUlNJT049bGF0ZXN0CiAgICAtIHBocDogNy4xCiAgICAgIGVudjogV1BfVkVSU0lPTj1sYXRlc3QKICAgIC0gcGhwOiA3LjAKICAgICAgZW52OiBXUF9WRVJTSU9OPWxhdGVzdAogICAge3sjd3BfdmVyc2lvbnNfdG9fdGVzdH19CiAgICAtIHBocDogNS42CiAgICAgIGVudjogV1BfVkVSU0lPTj17ey59fQogICAge3svd3BfdmVyc2lvbnNfdG9fdGVzdH19CiAgICAtIHBocDogNS42CiAgICAgIGVudjogV1BfVFJBVklTQ0k9cGhwY3MKCmJlZm9yZV9zY3JpcHQ6CiAgLSBleHBvcnQgUEFUSD0iJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci9iaW46JFBBVEgiCiAgLSB8CiAgICBpZiBbIC1mIH4vLnBocGVudi92ZXJzaW9ucy8kKHBocGVudiB2ZXJzaW9uLW5hbWUpL2V0Yy9jb25mLmQveGRlYnVnLmluaSBdOyB0aGVuCiAgICAgIHBocGVudiBjb25maWctcm0geGRlYnVnLmluaQogICAgZWxzZQogICAgICBlY2hvICJ4ZGVidWcuaW5pIGRvZXMgbm90IGV4aXN0IgogICAgZmkKICAtIHwKICAgIGlmIFtbICEgLXogIiRXUF9WRVJTSU9OIiBdXSA7IHRoZW4KICAgICAgYmFzaCBiaW4vaW5zdGFsbC13cC10ZXN0cy5zaCB3b3JkcHJlc3NfdGVzdCByb290ICcnIGxvY2FsaG9zdCAkV1BfVkVSU0lPTgogICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSAicGhwdW5pdC9waHB1bml0PTQuOC4qfDUuNy4qIgogICAgZmkKICAtIHwKICAgIGlmIFtbICIkV1BfVFJBVklTQ0kiID09ICJwaHBjcyIgXV0gOyB0aGVuCiAgICAgIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlIHdwLWNvZGluZy1zdGFuZGFyZHMvd3BjcwogICAgICBjb21wb3NlciBnbG9iYWwgcmVxdWlyZSBwaHBjb21wYXRpYmlsaXR5L3BocC1jb21wYXRpYmlsaXR5CiAgICAgIGNvbXBvc2VyIGdsb2JhbCByZXF1aXJlIHBocGNvbXBhdGliaWxpdHkvcGhwY29tcGF0aWJpbGl0eS1wYXJhZ29uaWUKICAgICAgY29tcG9zZXIgZ2xvYmFsIHJlcXVpcmUgcGhwY29tcGF0aWJpbGl0eS9waHBjb21wYXRpYmlsaXR5LXdwCiAgICAgIHBocGNzIC0tY29uZmlnLXNldCBpbnN0YWxsZWRfcGF0aHMgJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci93cC1jb2Rpbmctc3RhbmRhcmRzL3dwY3MsJEhPTUUvLmNvbXBvc2VyL3ZlbmRvci9waHBjb21wYXRpYmlsaXR5L3BocC1jb21wYXRpYmlsaXR5LCRIT01FLy5jb21wb3Nlci92ZW5kb3IvcGhwY29tcGF0aWJpbGl0eS9waHBjb21wYXRpYmlsaXR5LXBhcmFnb25pZSwkSE9NRS8uY29tcG9zZXIvdmVuZG9yL3BocGNvbXBhdGliaWxpdHkvcGhwY29tcGF0aWJpbGl0eS13cAogICAgZmkKCnNjcmlwdDoKICAtIHwKICAgIGlmIFtbICEgLXogIiRXUF9WRVJTSU9OIiBdXSA7IHRoZW4KICAgICAgcGhwdW5pdAogICAgICBXUF9NVUxUSVNJVEU9MSBwaHB1bml0CiAgICBmaQogIC0gfAogICAgaWYgW1sgIiRXUF9UUkFWSVNDSSIgPT0gInBocGNzIiBdXSA7IHRoZW4KICAgICAgcGhwY3MKICAgIGZpCiggZnVuY3Rpb24oIHdwICkgewoJLyoqCgkgKiBSZWdpc3RlcnMgYSBuZXcgYmxvY2sgcHJvdmlkZWQgYSB1bmlxdWUgbmFtZSBhbmQgYW4gb2JqZWN0IGRlZmluaW5nIGl0cyBiZWhhdmlvci4KCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL2Jsb2NrLWFwaS8jcmVnaXN0ZXJpbmctYS1ibG9jawoJICovCgl2YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7CgkvKioKCSAqIFJldHVybnMgYSBuZXcgZWxlbWVudCBvZiBnaXZlbiB0eXBlLiBFbGVtZW50IGlzIGFuIGFic3RyYWN0aW9uIGxheWVyIGF0b3AgUmVhY3QuCgkgKiBAc2VlIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svZGVzaWduZXJzLWRldmVsb3BlcnMvZGV2ZWxvcGVycy9wYWNrYWdlcy9wYWNrYWdlcy1lbGVtZW50LwoJICovCgl2YXIgZWwgPSB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQ7CgkvKioKCSAqIFJldHJpZXZlcyB0aGUgdHJhbnNsYXRpb24gb2YgdGV4dC4KCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL3BhY2thZ2VzL3BhY2thZ2VzLWkxOG4vCgkgKi8KCXZhciBfXyA9IHdwLmkxOG4uX187CgoJLyoqCgkgKiBFdmVyeSBibG9jayBzdGFydHMgYnkgcmVnaXN0ZXJpbmcgYSBuZXcgYmxvY2sgdHlwZSBkZWZpbml0aW9uLgoJICogQHNlZSBodHRwczovL3dvcmRwcmVzcy5vcmcvZ3V0ZW5iZXJnL2hhbmRib29rL2Rlc2lnbmVycy1kZXZlbG9wZXJzL2RldmVsb3BlcnMvYmxvY2stYXBpLyNyZWdpc3RlcmluZy1hLWJsb2NrCgkgKi8KCXJlZ2lzdGVyQmxvY2tUeXBlKCAne3tuYW1lc3BhY2V9fS97e3NsdWd9fScsIHsKCQkvKioKCQkgKiBUaGlzIGlzIHRoZSBkaXNwbGF5IHRpdGxlIGZvciB5b3VyIGJsb2NrLCB3aGljaCBjYW4gYmUgdHJhbnNsYXRlZCB3aXRoIGBpMThuYCBmdW5jdGlvbnMuCgkJICogVGhlIGJsb2NrIGluc2VydGVyIHdpbGwgc2hvdyB0aGlzIG5hbWUuCgkJICovCgkJdGl0bGU6IF9fKCAne3t0aXRsZV91Y2ZpcnN0X2pzfX0nLCAne3tuYW1lc3BhY2V9fScgKSwKCgkJe3sjZGFzaGljb259fQoJCS8qKgoJCSAqIEFuIGljb24gcHJvcGVydHkgc2hvdWxkIGJlIHNwZWNpZmllZCB0byBtYWtlIGl0IGVhc2llciB0byBpZGVudGlmeSBhIGJsb2NrLgoJCSAqIFRoZXNlIGNhbiBiZSBhbnkgb2YgV29yZFByZXNz4oCZIERhc2hpY29ucywgb3IgYSBjdXN0b20gc3ZnIGVsZW1lbnQuCgkJICovCgkJaWNvbjogJ3t7ZGFzaGljb259fScsCgoJCXt7L2Rhc2hpY29ufX0KCQkvKioKCQkgKiBCbG9ja3MgYXJlIGdyb3VwZWQgaW50byBjYXRlZ29yaWVzIHRvIGhlbHAgdXNlcnMgYnJvd3NlIGFuZCBkaXNjb3ZlciB0aGVtLgoJCSAqIFRoZSBjYXRlZ29yaWVzIHByb3ZpZGVkIGJ5IGNvcmUgYXJlIGBjb21tb25gLCBgZW1iZWRgLCBgZm9ybWF0dGluZ2AsIGBsYXlvdXRgIGFuZCBgd2lkZ2V0c2AuCgkJICovCgkJY2F0ZWdvcnk6ICd7e2NhdGVnb3J5fX0nLAoKCQkvKioKCQkgKiBPcHRpb25hbCBibG9jayBleHRlbmRlZCBzdXBwb3J0IGZlYXR1cmVzLgoJCSAqLwoJCXN1cHBvcnRzOiB7CgkJCS8vIFJlbW92ZXMgc3VwcG9ydCBmb3IgYW4gSFRNTCBtb2RlLgoJCQlodG1sOiBmYWxzZSwKCQl9LAoKCQkvKioKCQkgKiBUaGUgZWRpdCBmdW5jdGlvbiBkZXNjcmliZXMgdGhlIHN0cnVjdHVyZSBvZiB5b3VyIGJsb2NrIGluIHRoZSBjb250ZXh0IG9mIHRoZSBlZGl0b3IuCgkJICogVGhpcyByZXByZXNlbnRzIHdoYXQgdGhlIGVkaXRvciB3aWxsIHJlbmRlciB3aGVuIHRoZSBibG9jayBpcyB1c2VkLgoJCSAqIEBzZWUgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9kZXNpZ25lcnMtZGV2ZWxvcGVycy9kZXZlbG9wZXJzL2Jsb2NrLWFwaS9ibG9jay1lZGl0LXNhdmUvI2VkaXQKCQkgKgoJCSAqIEBwYXJhbSB7T2JqZWN0fSBbcHJvcHNdIFByb3BlcnRpZXMgcGFzc2VkIGZyb20gdGhlIGVkaXRvci4KCQkgKiBAcmV0dXJuIHtFbGVtZW50fSAgICAgICBFbGVtZW50IHRvIHJlbmRlci4KCQkgKi8KCQllZGl0OiBmdW5jdGlvbiggcHJvcHMgKSB7CgkJCXJldHVybiBlbCgKCQkJCSdwJywKCQkJCXsgY2xhc3NOYW1lOiBwcm9wcy5jbGFzc05hbWUgfSwKCQkJCV9fKCAnSGVsbG8gZnJvbSB0aGUgZWRpdG9yIScsICd7e25hbWVzcGFjZX19JyApCgkJCSk7CgkJfSwKCgkJLyoqCgkJICogVGhlIHNhdmUgZnVuY3Rpb24gZGVmaW5lcyB0aGUgd2F5IGluIHdoaWNoIHRoZSBkaWZmZXJlbnQgYXR0cmlidXRlcyBzaG91bGQgYmUgY29tYmluZWQKCQkgKiBpbnRvIHRoZSBmaW5hbCBtYXJrdXAsIHdoaWNoIGlzIHRoZW4gc2VyaWFsaXplZCBieSBHdXRlbmJlcmcgaW50byBgcG9zdF9jb250ZW50YC4KCQkgKiBAc2VlIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svZGVzaWduZXJzLWRldmVsb3BlcnMvZGV2ZWxvcGVycy9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlLyNzYXZlCgkJICoKCQkgKiBAcmV0dXJuIHtFbGVtZW50fSAgICAgICBFbGVtZW50IHRvIHJlbmRlci4KCQkgKi8KCQlzYXZlOiBmdW5jdGlvbigpIHsKCQkJcmV0dXJuIGVsKAoJCQkJJ3AnLAoJCQkJe30sCgkJCQlfXyggJ0hlbGxvIGZyb20gdGhlIHNhdmVkIGNvbnRlbnQhJywgJ3t7bmFtZXNwYWNlfX0nICkKCQkJKTsKCQl9Cgl9ICk7Cn0gKSgKCXdpbmRvdy53cAopOwoJcmVnaXN0ZXJfdGF4b25vbXkoICd7e3NsdWd9fScsIFsge3twb3N0X3R5cGVzfX0gXSwgWwoJCSdoaWVyYXJjaGljYWwnICAgICAgICAgID0+IGZhbHNlLAoJCSdwdWJsaWMnICAgICAgICAgICAgICAgID0+IHRydWUsCgkJJ3Nob3dfaW5fbmF2X21lbnVzJyAgICAgPT4gdHJ1ZSwKCQknc2hvd191aScgICAgICAgICAgICAgICA9PiB0cnVlLAoJCSdzaG93X2FkbWluX2NvbHVtbicgICAgID0+IGZhbHNlLAoJCSdxdWVyeV92YXInICAgICAgICAgICAgID0+IHRydWUsCgkJJ3Jld3JpdGUnICAgICAgICAgICAgICAgPT4gdHJ1ZSwKCQknY2FwYWJpbGl0aWVzJyAgICAgICAgICA9PiBbCgkJCSdtYW5hZ2VfdGVybXMnID0+ICdlZGl0X3Bvc3RzJywKCQkJJ2VkaXRfdGVybXMnICAgPT4gJ2VkaXRfcG9zdHMnLAoJCQknZGVsZXRlX3Rlcm1zJyA9PiAnZWRpdF9wb3N0cycsCgkJCSdhc3NpZ25fdGVybXMnID0+ICdlZGl0X3Bvc3RzJywKCQldLAoJCSdsYWJlbHMnICAgICAgICAgICAgICAgID0+IFsKCQkJJ25hbWUnICAgICAgICAgICAgICAgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ3Npbmd1bGFyX25hbWUnICAgICAgICAgICAgICA9PiBfeCggJ3t7bGFiZWxfdWNmaXJzdH19JywgJ3RheG9ub215IGdlbmVyYWwgbmFtZScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ3NlYXJjaF9pdGVtcycgICAgICAgICAgICAgICA9PiBfXyggJ1NlYXJjaCB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdwb3B1bGFyX2l0ZW1zJyAgICAgICAgICAgICAgPT4gX18oICdQb3B1bGFyIHt7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2FsbF9pdGVtcycgICAgICAgICAgICAgICAgICA9PiBfXyggJ0FsbCB7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdwYXJlbnRfaXRlbScgICAgICAgICAgICAgICAgPT4gX18oICdQYXJlbnQge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdwYXJlbnRfaXRlbV9jb2xvbicgICAgICAgICAgPT4gX18oICdQYXJlbnQge3tsYWJlbF91Y2ZpcnN0fX06JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknZWRpdF9pdGVtJyAgICAgICAgICAgICAgICAgID0+IF9fKCAnRWRpdCB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ3VwZGF0ZV9pdGVtJyAgICAgICAgICAgICAgICA9PiBfXyggJ1VwZGF0ZSB7e2xhYmVsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ3ZpZXdfaXRlbScgICAgICAgICAgICAgICAgICA9PiBfXyggJ1ZpZXcge3tsYWJlbF91Y2ZpcnN0fX0nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdhZGRfbmV3X2l0ZW0nICAgICAgICAgICAgICAgPT4gX18oICdBZGQgTmV3IHt7bGFiZWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknbmV3X2l0ZW1fbmFtZScgICAgICAgICAgICAgID0+IF9fKCAnTmV3IHt7bGFiZWxfdWNmaXJzdH19JywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknc2VwYXJhdGVfaXRlbXNfd2l0aF9jb21tYXMnID0+IF9fKCAnU2VwYXJhdGUge3tsYWJlbF9wbHVyYWx9fSB3aXRoIGNvbW1hcycsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2FkZF9vcl9yZW1vdmVfaXRlbXMnICAgICAgICA9PiBfXyggJ0FkZCBvciByZW1vdmUge3tsYWJlbF9wbHVyYWx9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2Nob29zZV9mcm9tX21vc3RfdXNlZCcgICAgICA9PiBfXyggJ0Nob29zZSBmcm9tIHRoZSBtb3N0IHVzZWQge3tsYWJlbF9wbHVyYWx9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ25vdF9mb3VuZCcgICAgICAgICAgICAgICAgICA9PiBfXyggJ05vIHt7bGFiZWxfcGx1cmFsfX0gZm91bmQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCQknbm9fdGVybXMnICAgICAgICAgICAgICAgICAgID0+IF9fKCAnTm8ge3tsYWJlbF9wbHVyYWx9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ21lbnVfbmFtZScgICAgICAgICAgICAgICAgICA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2l0ZW1zX2xpc3RfbmF2aWdhdGlvbicgICAgICA9PiBfXyggJ3t7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fSBsaXN0IG5hdmlnYXRpb24nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJCSdpdGVtc19saXN0JyAgICAgICAgICAgICAgICAgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0gbGlzdCcsICd7e3RleHRkb21haW59fScgKSwKCQkJJ21vc3RfdXNlZCcgICAgICAgICAgICAgICAgICA9PiBfeCggJ01vc3QgVXNlZCcsICd7e3NsdWd9fScsICd7e3RleHRkb21haW59fScgKSwKCQkJJ2JhY2tfdG9faXRlbXMnICAgICAgICAgICAgICA9PiBfXyggJyZsYXJyOyBCYWNrIHRvIHt7bGFiZWxfcGx1cmFsX3VjZmlyc3R9fScsICd7e3RleHRkb21haW59fScgKSwKCQldLAoJCSdzaG93X2luX3Jlc3QnICAgICAgICAgID0+IHRydWUsCgkJJ3Jlc3RfYmFzZScgICAgICAgICAgICAgPT4gJ3t7c2x1Z319JywKCQkncmVzdF9jb250cm9sbGVyX2NsYXNzJyA9PiAnV1BfUkVTVF9UZXJtc19Db250cm9sbGVyJywKCV0gKTsKLyoKVGhlbWUgTmFtZTogICAgIHt7dGhlbWVfbmFtZX19ClRoZW1lIFVSSTogICAgICB7e3RoZW1lX3VyaX19CkRlc2NyaXB0aW9uOiAgICB7e2Rlc2NyaXB0aW9ufX0KQXV0aG9yOiAgICAgICAgIHt7YXV0aG9yfX0KQXV0aG9yIFVSSTogICAgIHt7YXV0aG9yX3VyaX19ClRlbXBsYXRlOiAgICAgICB7e3BhcmVudF90aGVtZX19ClZlcnNpb246ICAgICAgICAwLjEuMAoqLwovKioKICogVGhlIGZvbGxvd2luZyBzdHlsZXMgZ2V0IGFwcGxpZWQgaW5zaWRlIHRoZSBlZGl0b3Igb25seS4KICoKICogUmVwbGFjZSB0aGVtIHdpdGggeW91ciBvd24gc3R5bGVzIG9yIHJlbW92ZSB0aGUgZmlsZSBjb21wbGV0ZWx5LgogKi8KCi53cC1ibG9jay17e25hbWVzcGFjZX19LXt7c2x1Z319IHsKCWJvcmRlcjogMXB4IGRvdHRlZCAjZjAwOwp9Cjw/cGhwCgovKioKICogUmVnaXN0ZXJzIHRoZSBge3ttYWNoaW5lX25hbWV9fWAgdGF4b25vbXksCiAqIGZvciB1c2Ugd2l0aCB7e3Bvc3RfdHlwZXN9fS4KICovCmZ1bmN0aW9uIHt7bWFjaGluZV9uYW1lfX1faW5pdCgpIHsKe3tvdXRwdXR9fQp9CgphZGRfYWN0aW9uKCAnaW5pdCcsICd7e21hY2hpbmVfbmFtZX19X2luaXQnICk7CgovKioKICogU2V0cyB0aGUgcG9zdCB1cGRhdGVkIG1lc3NhZ2VzIGZvciB0aGUgYHt7bWFjaGluZV9uYW1lfX1gIHRheG9ub215LgogKgogKiBAcGFyYW0gIGFycmF5ICRtZXNzYWdlcyBQb3N0IHVwZGF0ZWQgbWVzc2FnZXMuCiAqIEByZXR1cm4gYXJyYXkgTWVzc2FnZXMgZm9yIHRoZSBge3ttYWNoaW5lX25hbWV9fWAgdGF4b25vbXkuCiAqLwpmdW5jdGlvbiB7e21hY2hpbmVfbmFtZX19X3VwZGF0ZWRfbWVzc2FnZXMoICRtZXNzYWdlcyApIHsKCgkkbWVzc2FnZXNbJ3t7c2x1Z319J10gPSBbCgkJMCA9PiAnJywgLy8gVW51c2VkLiBNZXNzYWdlcyBzdGFydCBhdCBpbmRleCAxLgoJCTEgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSBhZGRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgkJMiA9PiBfXyggJ3t7bGFiZWxfdWNmaXJzdH19IGRlbGV0ZWQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCTMgPT4gX18oICd7e2xhYmVsX3VjZmlyc3R9fSB1cGRhdGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQk0ID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gbm90IGFkZGVkLicsICd7e3RleHRkb21haW59fScgKSwKCQk1ID0+IF9fKCAne3tsYWJlbF91Y2ZpcnN0fX0gbm90IHVwZGF0ZWQuJywgJ3t7dGV4dGRvbWFpbn19JyApLAoJCTYgPT4gX18oICd7e2xhYmVsX3BsdXJhbF91Y2ZpcnN0fX0gZGVsZXRlZC4nLCAne3t0ZXh0ZG9tYWlufX0nICksCgldOwoKCXJldHVybiAkbWVzc2FnZXM7Cn0KCmFkZF9maWx0ZXIoICd0ZXJtX3VwZGF0ZWRfbWVzc2FnZXMnLCAne3ttYWNoaW5lX25hbWV9fV91cGRhdGVkX21lc3NhZ2VzJyApOwo8P3BocAoKLy8gYXV0b2xvYWQucGhwIEBnZW5lcmF0ZWQgYnkgQ29tcG9zZXIKCnJlcXVpcmVfb25jZSBfX0RJUl9fIC4gJy9jb21wb3Nlci9hdXRvbG9hZF9yZWFsLnBocCc7CgpyZXR1cm4gQ29tcG9zZXJBdXRvbG9hZGVySW5pdGJmMTA5ZTA5MWQyOTE2NmUwNDk0NjExZTIyZTdkYmQ4OjpnZXRMb2FkZXIoKTsKQ29weXJpZ2h0IChjKSBOaWxzIEFkZXJtYW5uLCBKb3JkaSBCb2dnaWFubwoKUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQpvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAppbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCnRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZAp0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgpUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KClRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLApGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgpMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLApPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOClRIRSBTT0ZUV0FSRS4KewogICAgIiRzY2hlbWEiOiAiaHR0cHM6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIyIsCiAgICAibmFtZSI6ICJQYWNrYWdlIiwKICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiBmYWxzZSwKICAgICJyZXF1aXJlZCI6IFsgIm5hbWUiLCAiZGVzY3JpcHRpb24iIF0sCiAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAibmFtZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgbmFtZSwgaW5jbHVkaW5nICd2ZW5kb3ItbmFtZS8nIHByZWZpeC4iLAogICAgICAgICAgICAicGF0dGVybiI6ICJeW2EtejAtOV0oW18uLV0/W2EtejAtOV0rKSovW2EtejAtOV0oKFtfLl0/fC17MCwyfSlbYS16MC05XSspKiQiCiAgICAgICAgfSwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgdHlwZSwgZWl0aGVyICdsaWJyYXJ5JyBmb3IgY29tbW9uIHBhY2thZ2VzLCAnY29tcG9zZXItcGx1Z2luJyBmb3IgcGx1Z2lucywgJ21ldGFwYWNrYWdlJyBmb3IgZW1wdHkgcGFja2FnZXMsIG9yIGEgY3VzdG9tIHR5cGUgKFthLXowLTktXSspIGRlZmluZWQgYnkgd2hhdGV2ZXIgcHJvamVjdCB0aGlzIHBhY2thZ2UgYXBwbGllcyB0by4iLAogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAicGF0dGVybiI6ICJeW2EtejAtOS1dKyQiCiAgICAgICAgfSwKICAgICAgICAidGFyZ2V0LWRpciI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRFUFJFQ0FURUQ6IEZvcmNlcyB0aGUgcGFja2FnZSB0byBiZSBpbnN0YWxsZWQgaW50byB0aGUgZ2l2ZW4gc3ViZGlyZWN0b3J5IHBhdGguIFRoaXMgaXMgdXNlZCBmb3IgYXV0b2xvYWRpbmcgUFNSLTAgcGFja2FnZXMgdGhhdCBkbyBub3QgY29udGFpbiB0aGVpciBmdWxsIHBhdGguIFVzZSBmb3J3YXJkIHNsYXNoZXMgZm9yIGNyb3NzLXBsYXRmb3JtIGNvbXBhdGliaWxpdHkuIiwKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiU2hvcnQgcGFja2FnZSBkZXNjcmlwdGlvbi4iCiAgICAgICAgfSwKICAgICAgICAia2V5d29yZHMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHRhZy9rZXl3b3JkIHRoYXQgdGhpcyBwYWNrYWdlIHJlbGF0ZXMgdG8uIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiaG9tZXBhZ2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJIb21lcGFnZSBVUkwgZm9yIHRoZSBwcm9qZWN0LiIsCiAgICAgICAgICAgICJmb3JtYXQiOiAidXJpIgogICAgICAgIH0sCiAgICAgICAgInJlYWRtZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlJlbGF0aXZlIHBhdGggdG8gdGhlIHJlYWRtZSBkb2N1bWVudC4iCiAgICAgICAgfSwKICAgICAgICAidmVyc2lvbiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhY2thZ2UgdmVyc2lvbiwgc2VlIGh0dHBzOi8vZ2V0Y29tcG9zZXIub3JnL2RvYy8wNC1zY2hlbWEubWQjdmVyc2lvbiBmb3IgbW9yZSBpbmZvIG9uIHZhbGlkIHNjaGVtZXMuIiwKICAgICAgICAgICAgInBhdHRlcm4iOiAiXnY/XFxkKygoKFxcLlxcZCspP1xcLlxcZCspP1xcLlxcZCspP3xeZGV2LSIKICAgICAgICB9LAogICAgICAgICJ0aW1lIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGFja2FnZSByZWxlYXNlIGRhdGUsIGluICdZWVlZLU1NLUREJywgJ1lZWVktTU0tREQgSEg6TU06U1MnIG9yICdZWVlZLU1NLUREVEhIOk1NOlNTWicgZm9ybWF0LiIKICAgICAgICB9LAogICAgICAgICJsaWNlbnNlIjogewogICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJMaWNlbnNlIG5hbWUuIE9yIGFuIGFycmF5IG9mIGxpY2Vuc2UgbmFtZXMuIgogICAgICAgIH0sCiAgICAgICAgImF1dGhvcnMiOiB7CiAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvYXV0aG9ycyIKICAgICAgICB9LAogICAgICAgICJyZXF1aXJlIjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhIGhhc2ggb2YgcGFja2FnZSBuYW1lIChrZXlzKSBhbmQgdmVyc2lvbiBjb25zdHJhaW50cyAodmFsdWVzKSB0aGF0IGFyZSByZXF1aXJlZCB0byBydW4gdGhpcyBwYWNrYWdlLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInJlcGxhY2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGEgaGFzaCBvZiBwYWNrYWdlIG5hbWUgKGtleXMpIGFuZCB2ZXJzaW9uIGNvbnN0cmFpbnRzICh2YWx1ZXMpIHRoYXQgY2FuIGJlIHJlcGxhY2VkIGJ5IHRoaXMgcGFja2FnZS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjb25mbGljdCI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYSBoYXNoIG9mIHBhY2thZ2UgbmFtZSAoa2V5cykgYW5kIHZlcnNpb24gY29uc3RyYWludHMgKHZhbHVlcykgdGhhdCBjb25mbGljdCB3aXRoIHRoaXMgcGFja2FnZS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJwcm92aWRlIjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhIGhhc2ggb2YgcGFja2FnZSBuYW1lIChrZXlzKSBhbmQgdmVyc2lvbiBjb25zdHJhaW50cyAodmFsdWVzKSB0aGF0IHRoaXMgcGFja2FnZSBwcm92aWRlcyBpbiBhZGRpdGlvbiB0byB0aGlzIHBhY2thZ2UncyBuYW1lLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInJlcXVpcmUtZGV2IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhIGhhc2ggb2YgcGFja2FnZSBuYW1lIChrZXlzKSBhbmQgdmVyc2lvbiBjb25zdHJhaW50cyAodmFsdWVzKSB0aGF0IHRoaXMgcGFja2FnZSByZXF1aXJlcyBmb3IgZGV2ZWxvcGluZyBpdCAodGVzdGluZyB0b29scyBhbmQgc3VjaCkuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic3VnZ2VzdCI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYSBoYXNoIG9mIHBhY2thZ2UgbmFtZSAoa2V5cykgYW5kIGRlc2NyaXB0aW9ucyAodmFsdWVzKSB0aGF0IHRoaXMgcGFja2FnZSBzdWdnZXN0cyB3b3JrIHdlbGwgd2l0aCBpdCAodGhpcyB3aWxsIGJlIHN1Z2dlc3RlZCB0byB0aGUgdXNlciBkdXJpbmcgaW5zdGFsbGF0aW9uKS4iLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJDb21wb3NlciBvcHRpb25zLiIsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInByb2Nlc3MtdGltZW91dCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJpbnRlZ2VyIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIHRpbWVvdXQgaW4gc2Vjb25kcyBmb3IgcHJvY2VzcyBleGVjdXRpb25zLCBkZWZhdWx0cyB0byAzMDAgKDVtaW5zKS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInVzZS1pbmNsdWRlLXBhdGgiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHRydWUsIHRoZSBDb21wb3NlciBhdXRvbG9hZGVyIHdpbGwgYWxzbyBsb29rIGZvciBjbGFzc2VzIGluIHRoZSBQSFAgaW5jbHVkZSBwYXRoLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlZmVycmVkLWluc3RhbGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJvYmplY3QiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGluc3RhbGwgbWV0aG9kIENvbXBvc2VyIHdpbGwgcHJlZmVyIHRvIHVzZSwgZGVmYXVsdHMgdG8gYXV0byBhbmQgY2FuIGJlIGFueSBvZiBzb3VyY2UsIGRpc3QsIGF1dG8sIG9yIGEgaGFzaCBvZiB7XCJwYXR0ZXJuXCI6IFwicHJlZmVyZW5jZVwifS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm5vdGlmeS1vbi1pbnN0YWxsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJDb21wb3NlciBhbGxvd3MgcmVwb3NpdG9yaWVzIHRvIGRlZmluZSBhIG5vdGlmaWNhdGlvbiBVUkwsIHNvIHRoYXQgdGhleSBnZXQgbm90aWZpZWQgd2hlbmV2ZXIgYSBwYWNrYWdlIGZyb20gdGhhdCByZXBvc2l0b3J5IGlzIGluc3RhbGxlZC4gVGhpcyBvcHRpb24gYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoYXQgYmVoYXZpb3VyLCBkZWZhdWx0cyB0byB0cnVlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0aHViLXByb3RvY29scyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgbGlzdCBvZiBwcm90b2NvbHMgdG8gdXNlIGZvciBnaXRodWIuY29tIGNsb25lcywgaW4gcHJpb3JpdHkgb3JkZXIsIGRlZmF1bHRzIHRvIFtcImdpdFwiLCBcImh0dHBzXCIsIFwiaHR0cFwiXS4iLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0aHViLW9hdXRoIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgaGFzaCBvZiBkb21haW4gbmFtZSA9PiBnaXRodWIgQVBJIG9hdXRoIHRva2VucywgdHlwaWNhbGx5IHtcImdpdGh1Yi5jb21cIjpcIjx0b2tlbj5cIn0uIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImdpdGxhYi1vYXV0aCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGhhc2ggb2YgZG9tYWluIG5hbWUgPT4gZ2l0bGFiIEFQSSBvYXV0aCB0b2tlbnMsIHR5cGljYWxseSB7XCJnaXRsYWIuY29tXCI6XCI8dG9rZW4+XCJ9LiIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJnaXRsYWItdG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBoYXNoIG9mIGRvbWFpbiBuYW1lID0+IGdpdGxhYiBwcml2YXRlIHRva2VucywgdHlwaWNhbGx5IHtcImdpdGxhYi5jb21cIjpcIjx0b2tlbj5cIn0uIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImJlYXJlciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGhhc2ggb2YgZG9tYWluIG5hbWUgPT4gYmVhcmVyIGF1dGhlbnRpY2F0aW9uIHRva2VuLCBmb3IgZXhhbXBsZSB7XCJleGFtcGxlLmNvbVwiOlwiPHRva2VuPlwifS4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlzYWJsZS10bHMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIGBmYWxzZWAuIElmIHNldCB0byB0cnVlIGFsbCBIVFRQUyBVUkxzIHdpbGwgYmUgdHJpZWQgd2l0aCBIVFRQIGluc3RlYWQgYW5kIG5vIG5ldHdvcmsgbGV2ZWwgZW5jcnlwdGlvbiBpcyBwZXJmb3JtZWQuIEVuYWJsaW5nIHRoaXMgaXMgYSBzZWN1cml0eSByaXNrIGFuZCBpcyBOT1QgcmVjb21tZW5kZWQuIFRoZSBiZXR0ZXIgd2F5IGlzIHRvIGVuYWJsZSB0aGUgcGhwX29wZW5zc2wgZXh0ZW5zaW9uIGluIHBocC5pbmkuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzZWN1cmUtaHR0cCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGVmYXVsdHMgdG8gYHRydWVgLiBJZiBzZXQgdG8gdHJ1ZSBvbmx5IEhUVFBTIFVSTHMgYXJlIGFsbG93ZWQgdG8gYmUgZG93bmxvYWRlZCB2aWEgQ29tcG9zZXIuIElmIHlvdSByZWFsbHkgYWJzb2x1dGVseSBuZWVkIEhUVFAgYWNjZXNzIHRvIHNvbWV0aGluZyB0aGVuIHlvdSBjYW4gZGlzYWJsZSBpdCwgYnV0IHVzaW5nIFwiTGV0J3MgRW5jcnlwdFwiIHRvIGdldCBhIGZyZWUgU1NMIGNlcnRpZmljYXRlIGlzIGdlbmVyYWxseSBhIGJldHRlciBhbHRlcm5hdGl2ZS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhZmlsZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHdheSB0byBzZXQgdGhlIHBhdGggdG8gdGhlIG9wZW5zc2wgQ0EgZmlsZS4gSW4gUEhQIDUuNisgeW91IHNob3VsZCByYXRoZXIgc2V0IHRoaXMgdmlhIG9wZW5zc2wuY2FmaWxlIGluIHBocC5pbmksIGFsdGhvdWdoIFBIUCA1LjYrIHNob3VsZCBiZSBhYmxlIHRvIGRldGVjdCB5b3VyIHN5c3RlbSBDQSBmaWxlIGF1dG9tYXRpY2FsbHkuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYXBhdGgiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSWYgY2FmaWxlIGlzIG5vdCBzcGVjaWZpZWQgb3IgaWYgdGhlIGNlcnRpZmljYXRlIGlzIG5vdCBmb3VuZCB0aGVyZSwgdGhlIGRpcmVjdG9yeSBwb2ludGVkIHRvIGJ5IGNhcGF0aCBpcyBzZWFyY2hlZCBmb3IgYSBzdWl0YWJsZSBjZXJ0aWZpY2F0ZS4gY2FwYXRoIG11c3QgYmUgYSBjb3JyZWN0bHkgaGFzaGVkIGNlcnRpZmljYXRlIGRpcmVjdG9yeS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImh0dHAtYmFzaWMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQSBoYXNoIG9mIGRvbWFpbiBuYW1lID0+IHtcInVzZXJuYW1lXCI6IFwiLi4uXCIsIFwicGFzc3dvcmRcIjogXCIuLi5cIn0uIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidXNlcm5hbWUiLCAicGFzc3dvcmQiXSwKICAgICAgICAgICAgICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidXNlcm5hbWUiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIHVzZXJuYW1lIHVzZWQgZm9yIEhUVFAgQmFzaWMgYXV0aGVudGljYXRpb24iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhc3N3b3JkIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBwYXNzd29yZCB1c2VkIGZvciBIVFRQIEJhc2ljIGF1dGhlbnRpY2F0aW9uIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzdG9yZS1hdXRocyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImJvb2xlYW4iXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2hhdCB0byBkbyBhZnRlciBwcm9tcHRpbmcgZm9yIGF1dGhlbnRpY2F0aW9uLCBvbmUgb2Y6IHRydWUgKHN0b3JlKSwgZmFsc2UgKGRvIG5vdCBzdG9yZSkgb3IgXCJwcm9tcHRcIiAoYXNrIGV2ZXJ5IHRpbWUpLCBkZWZhdWx0cyB0byBwcm9tcHQuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwbGF0Zm9ybSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGEgaGFzaCBvZiBwYWNrYWdlIG5hbWUgKGtleXMpIGFuZCB2ZXJzaW9uICh2YWx1ZXMpIHRoYXQgd2lsbCBiZSB1c2VkIHRvIG1vY2sgdGhlIHBsYXRmb3JtIHBhY2thZ2VzIG9uIHRoaXMgbWFjaGluZS4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAidmVuZG9yLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgYWxsIHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQsIGRlZmF1bHRzIHRvIFwidmVuZG9yXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJiaW4tZGlyIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBsb2NhdGlvbiB3aGVyZSBhbGwgYmluYXJpZXMgYXJlIGxpbmtlZCwgZGVmYXVsdHMgdG8gXCJ2ZW5kb3IvYmluXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkYXRhLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgb2xkIHBoYXIgZmlsZXMgYXJlIHN0b3JlZCwgZGVmYXVsdHMgdG8gXCIkaG9tZVwiIGV4Y2VwdCBvbiBYREcgQmFzZSBEaXJlY3RvcnkgY29tcGxpYW50IHVuaXhlcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhY2hlLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgYWxsIGNhY2hlcyBhcmUgbG9jYXRlZCwgZGVmYXVsdHMgdG8gXCJ+Ly5jb21wb3Nlci9jYWNoZVwiIG9uICpuaXggYW5kIFwiJUxPQ0FMQVBQREFUQSVcXENvbXBvc2VyXCIgb24gd2luZG93cy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhY2hlLWZpbGVzLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgZmlsZXMgKHppcCBkb3dubG9hZHMpIGFyZSBjYWNoZWQsIGRlZmF1bHRzIHRvIFwieyRjYWNoZS1kaXJ9L2ZpbGVzXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1yZXBvLWRpciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbG9jYXRpb24gd2hlcmUgcmVwbyAoZ2l0L2hnIHJlcG8gY2xvbmVzKSBhcmUgY2FjaGVkLCBkZWZhdWx0cyB0byBcInskY2FjaGUtZGlyfS9yZXBvXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS12Y3MtZGlyIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBsb2NhdGlvbiB3aGVyZSB2Y3MgaW5mb3MgKGdpdCBjbG9uZXMsIGdpdGh1YiBhcGkgY2FsbHMsIGV0Yy4gd2hlbiByZWFkaW5nIHZjcyByZXBvcykgYXJlIGNhY2hlZCwgZGVmYXVsdHMgdG8gXCJ7JGNhY2hlLWRpcn0vdmNzXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS10dGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBkZWZhdWx0IGNhY2hlIHRpbWUtdG8tbGl2ZSwgZGVmYXVsdHMgdG8gMTU1NTIwMDAgKDYgbW9udGhzKS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhY2hlLWZpbGVzLXR0bCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJpbnRlZ2VyIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGNhY2hlIHRpbWUtdG8tbGl2ZSBmb3IgZmlsZXMsIGRlZmF1bHRzIHRvIHRoZSB2YWx1ZSBvZiBjYWNoZS10dGwuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjYWNoZS1maWxlcy1tYXhzaXplIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiaW50ZWdlciJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgY2FjaGUgbWF4IHNpemUgZm9yIHRoZSBmaWxlcyBjYWNoZSwgZGVmYXVsdHMgdG8gXCIzMDBNaUJcIi4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNhY2hlLXJlYWQtb25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYm9vbGVhbiJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJXaGV0aGVyIHRvIHVzZSB0aGUgQ29tcG9zZXIgY2FjaGUgaW4gcmVhZC1vbmx5IG1vZGUuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJiaW4tY29tcGF0IjogewogICAgICAgICAgICAgICAgICAgICJlbnVtIjogWyJhdXRvIiwgImZ1bGwiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGNvbXBhdGliaWxpdHkgb2YgdGhlIGJpbmFyaWVzLCBkZWZhdWx0cyB0byBcImF1dG9cIiAoYXV0b21hdGljYWxseSBndWVzc2VkKSBhbmQgY2FuIGJlIFwiZnVsbFwiIChjb21wYXRpYmxlIHdpdGggYm90aCBXaW5kb3dzIGFuZCBVbml4LWJhc2VkIHN5c3RlbXMpLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlzY2FyZC1jaGFuZ2VzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYm9vbGVhbiJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgZGVmYXVsdCBzdHlsZSBvZiBoYW5kbGluZyBkaXJ0eSB1cGRhdGVzLCBkZWZhdWx0cyB0byBmYWxzZSBhbmQgY2FuIGJlIGFueSBvZiB0cnVlLCBmYWxzZSBvciBcInN0YXNoXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJhdXRvbG9hZGVyLXN1ZmZpeCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPcHRpb25hbCBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIHN1ZmZpeCBmb3IgdGhlIGdlbmVyYXRlZCBDb21wb3NlciBhdXRvbG9hZGVyLiBXaGVuIG51bGwgYSByYW5kb20gb25lIHdpbGwgYmUgZ2VuZXJhdGVkLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAib3B0aW1pemUtYXV0b2xvYWRlciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQWx3YXlzIG9wdGltaXplIHdoZW4gZHVtcGluZyB0aGUgYXV0b2xvYWRlci4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInByZXBlbmQtYXV0b2xvYWRlciI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSWYgZmFsc2UsIHRoZSBjb21wb3NlciBhdXRvbG9hZGVyIHdpbGwgbm90IGJlIHByZXBlbmRlZCB0byBleGlzdGluZyBhdXRvbG9hZGVycywgZGVmYXVsdHMgdG8gdHJ1ZS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNsYXNzbWFwLWF1dGhvcml0YXRpdmUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHRydWUsIHRoZSBjb21wb3NlciBhdXRvbG9hZGVyIHdpbGwgbm90IHNjYW4gdGhlIGZpbGVzeXN0ZW0gZm9yIGNsYXNzZXMgdGhhdCBhcmUgbm90IGZvdW5kIGluIHRoZSBjbGFzcyBtYXAsIGRlZmF1bHRzIHRvIGZhbHNlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXBjdS1hdXRvbG9hZGVyIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiB0cnVlLCB0aGUgQ29tcG9zZXIgYXV0b2xvYWRlciB3aWxsIGNoZWNrIGZvciBBUEN1IGFuZCB1c2UgaXQgdG8gY2FjaGUgZm91bmQvbm90LWZvdW5kIGNsYXNzZXMgd2hlbiB0aGUgZXh0ZW5zaW9uIGlzIGVuYWJsZWQsIGRlZmF1bHRzIHRvIGZhbHNlLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0aHViLWRvbWFpbnMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGxpc3Qgb2YgZG9tYWlucyB0byB1c2UgaW4gZ2l0aHViIG1vZGUuIFRoaXMgaXMgdXNlZCBmb3IgR2l0SHViIEVudGVycHJpc2Ugc2V0dXBzLCBkZWZhdWx0cyB0byBbXCJnaXRodWIuY29tXCJdLiIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJnaXRodWItZXhwb3NlLWhvc3RuYW1lIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZWZhdWx0cyB0byB0cnVlLiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBPQXV0aCB0b2tlbnMgY3JlYXRlZCB0byBhY2Nlc3MgdGhlIGdpdGh1YiBBUEkgd2lsbCBoYXZlIGEgZGF0ZSBpbnN0ZWFkIG9mIHRoZSBtYWNoaW5lIGhvc3RuYW1lLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZ2l0bGFiLWRvbWFpbnMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGxpc3Qgb2YgZG9tYWlucyB0byB1c2UgaW4gZ2l0bGFiIG1vZGUuIFRoaXMgaXMgdXNlZCBmb3IgY3VzdG9tIEdpdExhYiBzZXR1cHMsIGRlZmF1bHRzIHRvIFtcImdpdGxhYi5jb21cIl0uIiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInVzZS1naXRodWItYXBpIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZWZhdWx0cyB0byB0cnVlLiAgSWYgc2V0IHRvIGZhbHNlLCBnbG9iYWxseSBkaXNhYmxlcyB0aGUgdXNlIG9mIHRoZSBHaXRIdWIgQVBJIGZvciBhbGwgR2l0SHViIHJlcG9zaXRvcmllcyBhbmQgY2xvbmVzIHRoZSByZXBvc2l0b3J5IGFzIGl0IHdvdWxkIGZvciBhbnkgb3RoZXIgcmVwb3NpdG9yeS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImFyY2hpdmUtZm9ybWF0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBkZWZhdWx0IGFyY2hpdmluZyBmb3JtYXQgd2hlbiBub3QgcHJvdmlkZWQgb24gY2xpLCBkZWZhdWx0cyB0byBcInRhclwiLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXJjaGl2ZS1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGRlZmF1bHQgYXJjaGl2ZSBwYXRoIHdoZW4gbm90IHByb3ZpZGVkIG9uIGNsaSwgZGVmYXVsdHMgdG8gXCIuXCIuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJodGFjY2Vzcy1wcm90ZWN0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZWZhdWx0cyB0byB0cnVlLiBJZiBzZXQgdG8gZmFsc2UsIENvbXBvc2VyIHdpbGwgbm90IGNyZWF0ZSAuaHRhY2Nlc3MgZmlsZXMgaW4gdGhlIGNvbXBvc2VyIGhvbWUsIGNhY2hlLCBhbmQgZGF0YSBkaXJlY3Rvcmllcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInNvcnQtcGFja2FnZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRlZmF1bHRzIHRvIGZhbHNlLiBJZiBzZXQgdG8gdHJ1ZSwgQ29tcG9zZXIgd2lsbCBzb3J0IHBhY2thZ2VzIHdoZW4gYWRkaW5nL3VwZGF0aW5nIGEgbmV3IGRlcGVuZGVuY3kuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJsb2NrIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZWZhdWx0cyB0byB0cnVlLiBJZiBzZXQgdG8gZmFsc2UsIENvbXBvc2VyIHdpbGwgbm90IGNyZWF0ZSBhIGNvbXBvc2VyLmxvY2sgZmlsZS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBsYXRmb3JtLWNoZWNrIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJib29sZWFuIiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZWZhdWx0cyB0byBcInBocC1vbmx5XCIgd2hpY2ggY2hlY2tzIG9ubHkgdGhlIFBIUCB2ZXJzaW9uLiBTZXR0aW5nIHRvIHRydWUgd2lsbCBhbHNvIGNoZWNrIHRoZSBwcmVzZW5jZSBvZiByZXF1aXJlZCBQSFAgZXh0ZW5zaW9ucy4gSWYgc2V0IHRvIGZhbHNlLCBDb21wb3NlciB3aWxsIG5vdCBjcmVhdGUgYW5kIHJlcXVpcmUgYSBwbGF0Zm9ybV9jaGVjay5waHAgZmlsZSBhcyBwYXJ0IG9mIHRoZSBhdXRvbG9hZGVyIGJvb3RzdHJhcC4iCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJleHRyYSI6IHsKICAgICAgICAgICAgInR5cGUiOiBbIm9iamVjdCIsICJhcnJheSJdLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQXJiaXRyYXJ5IGV4dHJhIGRhdGEgdGhhdCBjYW4gYmUgdXNlZCBieSBwbHVnaW5zLCBmb3IgZXhhbXBsZSwgcGFja2FnZSBvZiB0eXBlIGNvbXBvc2VyLXBsdWdpbiBtYXkgaGF2ZSBhICdjbGFzcycga2V5IGRlZmluaW5nIGFuIGluc3RhbGxlciBjbGFzcyBuYW1lLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHRydWUKICAgICAgICB9LAogICAgICAgICJhdXRvbG9hZCI6IHsKICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9hdXRvbG9hZCIKICAgICAgICB9LAogICAgICAgICJhdXRvbG9hZC1kZXYiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZXNjcmlwdGlvbiBvZiBhZGRpdGlvbmFsIGF1dG9sb2FkIHJ1bGVzIGZvciBkZXZlbG9wbWVudCBwdXJwb3NlIChlZy4gYSB0ZXN0IHN1aXRlKS4iLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJwc3ItMCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGEgaGFzaCBvZiBuYW1lc3BhY2VzIChrZXlzKSBhbmQgdGhlIGRpcmVjdG9yaWVzIHRoZXkgY2FuIGJlIGZvdW5kIGludG8gKHZhbHVlcywgY2FuIGJlIGFycmF5cyBvZiBwYXRocykgYnkgdGhlIGF1dG9sb2FkZXIuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwc3ItNCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGEgaGFzaCBvZiBuYW1lc3BhY2VzIChrZXlzKSBhbmQgdGhlIFBTUi00IGRpcmVjdG9yaWVzIHRoZXkgY2FuIG1hcCB0byAodmFsdWVzLCBjYW4gYmUgYXJyYXlzIG9mIHBhdGhzKSBieSB0aGUgYXV0b2xvYWRlci4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJhcnJheSJdLAogICAgICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNsYXNzbWFwIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBhcnJheSBvZiBwYXRocyB0aGF0IGNvbnRhaW4gY2xhc3NlcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgY2xhc3MtbWFwIGdlbmVyYXRpb24gcHJvY2Vzcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZpbGVzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBhcnJheSBvZiBmaWxlcyB0aGF0IGFyZSBhbHdheXMgcmVxdWlyZWQgb24gZXZlcnkgcmVxdWVzdC4iCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJhcmNoaXZlIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPcHRpb25zIGZvciBjcmVhdGluZyBwYWNrYWdlIGFyY2hpdmVzIGZvciBkaXN0cmlidXRpb24uIiwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAibmFtZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGJhc2UgbmFtZSBmb3IgYXJjaGl2ZS4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImV4Y2x1ZGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGxpc3Qgb2YgcGF0dGVybnMgZm9yIHBhdGhzIHRvIGV4Y2x1ZGUgb3IgaW5jbHVkZSBpZiBwcmVmaXhlZCB3aXRoIGFuIGV4Y2xhbWF0aW9uIG1hcmsuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVwb3NpdG9yaWVzIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0IiwgImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHNldCBvZiBhZGRpdGlvbmFsIHJlcG9zaXRvcmllcyB3aGVyZSBwYWNrYWdlcyBjYW4gYmUgZm91bmQuIiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIsICJlbnVtIjogW2ZhbHNlXSB9CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvcmVwb3NpdG9yeSIgfSwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsgInR5cGUiOiAiYm9vbGVhbiIsICJlbnVtIjogW2ZhbHNlXSB9LAogICAgICAgICAgICAgICAgICAgICAgICAibWluUHJvcGVydGllcyI6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICJtYXhQcm9wZXJ0aWVzIjogMQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm1pbmltdW0tc3RhYmlsaXR5IjogewogICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIl0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgbWluaW11bSBzdGFiaWxpdHkgdGhlIHBhY2thZ2VzIG11c3QgaGF2ZSB0byBiZSBpbnN0YWxsLWFibGUuIFBvc3NpYmxlIHZhbHVlcyBhcmU6IGRldiwgYWxwaGEsIGJldGEsIFJDLCBzdGFibGUuIiwKICAgICAgICAgICAgInBhdHRlcm4iOiAiXmRldnxhbHBoYXxiZXRhfHJjfFJDfHN0YWJsZSQiCiAgICAgICAgfSwKICAgICAgICAicHJlZmVyLXN0YWJsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHNldCB0byB0cnVlLCBzdGFibGUgcGFja2FnZXMgd2lsbCBiZSBwcmVmZXJyZWQgdG8gZGV2IHBhY2thZ2VzIHdoZW4gcG9zc2libGUsIGV2ZW4gaWYgdGhlIG1pbmltdW0tc3RhYmlsaXR5IGFsbG93cyB1bnN0YWJsZSBwYWNrYWdlcy4iCiAgICAgICAgfSwKICAgICAgICAiYmluIjogewogICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHNldCBvZiBmaWxlcywgb3IgYSBzaW5nbGUgZmlsZSwgdGhhdCBzaG91bGQgYmUgdHJlYXRlZCBhcyBiaW5hcmllcyBhbmQgc3ltbGlua2VkIGludG8gYmluLWRpciAoZnJvbSBjb25maWcpLiIsCiAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImluY2x1ZGUtcGF0aCI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJERVBSRUNBVEVEOiBBIGxpc3Qgb2YgZGlyZWN0b3JpZXMgd2hpY2ggc2hvdWxkIGdldCBhZGRlZCB0byBQSFAncyBpbmNsdWRlIHBhdGguIFRoaXMgaXMgb25seSBwcmVzZW50IHRvIHN1cHBvcnQgbGVnYWN5IHByb2plY3RzLCBhbmQgYWxsIG5ldyBjb2RlIHNob3VsZCBwcmVmZXJhYmx5IHVzZSBhdXRvbG9hZGluZy4iLAogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzY3JpcHRzIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJTY3JpcHQgbGlzdGVuZXJzIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBiZWZvcmUvYWZ0ZXIgc29tZSBldmVudHMuIiwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAicHJlLWluc3RhbGwtY21kIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSIsICJzdHJpbmciXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2NjdXJzIGJlZm9yZSB0aGUgaW5zdGFsbCBjb21tYW5kIGlzIGV4ZWN1dGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3QtaW5zdGFsbC1jbWQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgdGhlIGluc3RhbGwgY29tbWFuZCBpcyBleGVjdXRlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmUtdXBkYXRlLWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBiZWZvcmUgdGhlIHVwZGF0ZSBjb21tYW5kIGlzIGV4ZWN1dGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3QtdXBkYXRlLWNtZCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciB0aGUgdXBkYXRlIGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlLXN0YXR1cy1jbWQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIHRoZSBzdGF0dXMgY29tbWFuZCBpcyBleGVjdXRlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwb3N0LXN0YXR1cy1jbWQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgdGhlIHN0YXR1cyBjb21tYW5kIGlzIGV4ZWN1dGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInByZS1wYWNrYWdlLWluc3RhbGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIGEgcGFja2FnZSBpcyBpbnN0YWxsZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1wYWNrYWdlLWluc3RhbGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgYSBwYWNrYWdlIGlzIGluc3RhbGxlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcmUtcGFja2FnZS11cGRhdGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIGEgcGFja2FnZSBpcyB1cGRhdGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3QtcGFja2FnZS11cGRhdGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgYSBwYWNrYWdlIGlzIHVwZGF0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlLXBhY2thZ2UtdW5pbnN0YWxsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJhcnJheSIsICJzdHJpbmciXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2NjdXJzIGJlZm9yZSBhIHBhY2thZ2UgaGFzIGJlZW4gdW5pbnN0YWxsZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1wYWNrYWdlLXVuaW5zdGFsbCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9jY3VycyBhZnRlciBhIHBhY2thZ2UgaGFzIGJlZW4gdW5pbnN0YWxsZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicHJlLWF1dG9sb2FkLWR1bXAiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYmVmb3JlIHRoZSBhdXRvbG9hZGVyIGlzIGR1bXBlZCwgY29udGFpbnMgb25lIG9yIG1vcmUgQ2xhc3M6Om1ldGhvZCBjYWxsYWJsZXMgb3Igc2hlbGwgY29tbWFuZHMuIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwb3N0LWF1dG9sb2FkLWR1bXAiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgdGhlIGF1dG9sb2FkZXIgaXMgZHVtcGVkLCBjb250YWlucyBvbmUgb3IgbW9yZSBDbGFzczo6bWV0aG9kIGNhbGxhYmxlcyBvciBzaGVsbCBjb21tYW5kcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBvc3Qtcm9vdC1wYWNrYWdlLWluc3RhbGwiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgdGhlIHJvb3QtcGFja2FnZSBpcyBpbnN0YWxsZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicG9zdC1jcmVhdGUtcHJvamVjdC1jbWQiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbImFycmF5IiwgInN0cmluZyJdLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPY2N1cnMgYWZ0ZXIgdGhlIGNyZWF0ZS1wcm9qZWN0IGNvbW1hbmQgaXMgZXhlY3V0ZWQsIGNvbnRhaW5zIG9uZSBvciBtb3JlIENsYXNzOjptZXRob2QgY2FsbGFibGVzIG9yIHNoZWxsIGNvbW1hbmRzLiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInNjcmlwdHMtZGVzY3JpcHRpb25zIjogewogICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZXNjcmlwdGlvbnMgZm9yIGN1c3RvbSBjb21tYW5kcywgc2hvd24gaW4gY29uc29sZSBoZWxwLiIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInN1cHBvcnQiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgImVtYWlsIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkVtYWlsIGFkZHJlc3MgZm9yIHN1cHBvcnQuIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogImVtYWlsIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJpc3N1ZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIHRoZSBpc3N1ZSB0cmFja2VyLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZvcnVtIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVSTCB0byB0aGUgZm9ydW0uIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAid2lraSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gdGhlIHdpa2kuIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiaXJjIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIklSQyBjaGFubmVsIGZvciBzdXBwb3J0LCBhcyBpcmM6Ly9zZXJ2ZXIvY2hhbm5lbC4iLAogICAgICAgICAgICAgICAgICAgICJmb3JtYXQiOiAidXJpIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJjaGF0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVSTCB0byB0aGUgc3VwcG9ydCBjaGF0LiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInNvdXJjZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gYnJvd3NlIG9yIGRvd25sb2FkIHRoZSBzb3VyY2VzLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImRvY3MiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIHRoZSBkb2N1bWVudGF0aW9uLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInJzcyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVUkwgdG8gdGhlIFJTUyBmZWVkLiIsCiAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJmdW5kaW5nIjogewogICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGxpc3Qgb2Ygb3B0aW9ucyB0byBmdW5kIHRoZSBkZXZlbG9wbWVudCBhbmQgbWFpbnRlbmFuY2Ugb2YgdGhlIHBhY2thZ2UuIiwKICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVHlwZSBvZiBmdW5kaW5nIG9yIHBsYXRmb3JtIHRocm91Z2ggd2hpY2ggZnVuZGluZyBpcyBwb3NzaWJsZS4iCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAidXJsIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVVJMIHRvIGEgd2Vic2l0ZSB3aXRoIGRldGFpbHMgb24gZnVuZGluZyBhbmQgYSB3YXkgdG8gZnVuZCB0aGUgcGFja2FnZS4iLAogICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJub24tZmVhdHVyZS1icmFuY2hlcyI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImFycmF5Il0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIHNldCBvZiBzdHJpbmcgb3IgcmVnZXggcGF0dGVybnMgZm9yIG5vbi1udW1lcmljIGJyYW5jaCBuYW1lcyB0aGF0IHdpbGwgbm90IGJlIGhhbmRsZWQgYXMgZmVhdHVyZSBicmFuY2hlcy4iLAogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJkZWZhdWx0LWJyYW5jaCI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iXSwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkludGVybmFsIHVzZSBvbmx5LCBkbyBub3Qgc3BlY2lmeSB0aGlzIGluIGNvbXBvc2VyLmpzb24uIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgdmVyc2lvbiBpcyB0aGUgZGVmYXVsdCBicmFuY2ggb2YgdGhlIGxpbmtlZCBWQ1MgcmVwb3NpdG9yeS4gRGVmYXVsdHMgdG8gZmFsc2UuIgogICAgICAgIH0sCiAgICAgICAgImFiYW5kb25lZCI6IHsKICAgICAgICAgICAgInR5cGUiOiBbImJvb2xlYW4iLCAic3RyaW5nIl0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHBhY2thZ2UgaGFzIGJlZW4gYWJhbmRvbmVkLCBpdCBjYW4gYmUgYm9vbGVhbiBvciBhIHBhY2thZ2UgbmFtZS9VUkwgcG9pbnRpbmcgdG8gYSByZWNvbW1lbmRlZCBhbHRlcm5hdGl2ZS4gRGVmYXVsdHMgdG8gZmFsc2UuIgogICAgICAgIH0sCiAgICAgICAgIl9jb21tZW50IjogewogICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiLCAic3RyaW5nIl0sCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIGtleSB0byBzdG9yZSBjb21tZW50cyBpbiIKICAgICAgICB9CiAgICB9LAogICAgImRlZmluaXRpb25zIjogewogICAgICAgICJhdXRob3JzIjogewogICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJMaXN0IG9mIGF1dGhvcnMgdGhhdCBjb250cmlidXRlZCB0byB0aGUgcGFja2FnZS4gVGhpcyBpcyB0eXBpY2FsbHkgdGhlIG1haW4gbWFpbnRhaW5lcnMsIG5vdCB0aGUgZnVsbCBsaXN0LiIsCiAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiBmYWxzZSwKICAgICAgICAgICAgICAgICJyZXF1aXJlZCI6IFsgIm5hbWUiXSwKICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRnVsbCBuYW1lIG9mIHRoZSBhdXRob3IuIgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgImVtYWlsIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRW1haWwgYWRkcmVzcyBvZiB0aGUgYXV0aG9yLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJmb3JtYXQiOiAiZW1haWwiCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiaG9tZXBhZ2UiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJIb21lcGFnZSBVUkwgZm9yIHRoZSBhdXRob3IuIiwKICAgICAgICAgICAgICAgICAgICAgICAgImZvcm1hdCI6ICJ1cmkiCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAicm9sZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkF1dGhvcidzIHJvbGUgaW4gdGhlIHByb2plY3QuIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImF1dG9sb2FkIjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGVzY3JpcHRpb24gb2YgaG93IHRoZSBwYWNrYWdlIGNhbiBiZSBhdXRvbG9hZGVkLiIsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInBzci0wIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYSBoYXNoIG9mIG5hbWVzcGFjZXMgKGtleXMpIGFuZCB0aGUgZGlyZWN0b3JpZXMgdGhleSBjYW4gYmUgZm91bmQgaW4gKHZhbHVlcywgY2FuIGJlIGFycmF5cyBvZiBwYXRocykgYnkgdGhlIGF1dG9sb2FkZXIuIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWyJzdHJpbmciLCAiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwc3ItNCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGlzIGlzIGEgaGFzaCBvZiBuYW1lc3BhY2VzIChrZXlzKSBhbmQgdGhlIFBTUi00IGRpcmVjdG9yaWVzIHRoZXkgY2FuIG1hcCB0byAodmFsdWVzLCBjYW4gYmUgYXJyYXlzIG9mIHBhdGhzKSBieSB0aGUgYXV0b2xvYWRlci4iLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbInN0cmluZyIsICJhcnJheSJdLAogICAgICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNsYXNzbWFwIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBhcnJheSBvZiBwYXRocyB0aGF0IGNvbnRhaW4gY2xhc3NlcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgY2xhc3MtbWFwIGdlbmVyYXRpb24gcHJvY2Vzcy4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZpbGVzIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyBhbiBhcnJheSBvZiBmaWxlcyB0aGF0IGFyZSBhbHdheXMgcmVxdWlyZWQgb24gZXZlcnkgcmVxdWVzdC4iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImV4Y2x1ZGUtZnJvbS1jbGFzc21hcCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYW4gYXJyYXkgb2YgcGF0dGVybnMgdG8gZXhjbHVkZSBmcm9tIGF1dG9sb2FkIGNsYXNzbWFwIGdlbmVyYXRpb24uIChlLmcuIFwiZXhjbHVkZS1mcm9tLWNsYXNzbWFwXCI6IFtcIi90ZXN0L1wiLCBcIi90ZXN0cy9cIiwgXCIvVGVzdHMvXCJdIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVwb3NpdG9yeSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL2NvbXBvc2VyLXJlcG9zaXRvcnkiIH0sCiAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvdmNzLXJlcG9zaXRvcnkiIH0sCiAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvcGF0aC1yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL2FydGlmYWN0LXJlcG9zaXRvcnkiIH0sCiAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvcGVhci1yZXBvc2l0b3J5IiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3BhY2thZ2UtcmVwb3NpdG9yeSIgfQogICAgICAgICAgICBdCiAgICAgICAgfSwKICAgICAgICAiY29tcG9zZXItcmVwb3NpdG9yeSI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ0eXBlIiwgInVybCJdLAogICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZW51bSI6IFsiY29tcG9zZXIiXSB9LAogICAgICAgICAgICAgICAgInVybCI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgImNhbm9uaWNhbCI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfSwKICAgICAgICAgICAgICAgICJvbmx5IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImV4Y2x1ZGUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAib3B0aW9ucyI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHRydWUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYWxsb3dfc3NsX2Rvd25ncmFkZSI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfSwKICAgICAgICAgICAgICAgICJmb3JjZS1sYXp5LXByb3ZpZGVycyI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAidmNzLXJlcG9zaXRvcnkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidHlwZSIsICJ1cmwiXSwKICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAidHlwZSI6IHsgInR5cGUiOiAic3RyaW5nIiwgImVudW0iOiBbInZjcyIsICJnaXRodWIiLCAiZ2l0IiwgImdpdGxhYiIsICJnaXQtYml0YnVja2V0IiwgImhnIiwgImhnLWJpdGJ1Y2tldCIsICJmb3NzaWwiLCAicGVyZm9yY2UiLCAic3ZuIl0gfSwKICAgICAgICAgICAgICAgICJ1cmwiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJjYW5vbmljYWwiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAib25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm5vLWFwaSI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfSwKICAgICAgICAgICAgICAgICJzZWN1cmUtaHR0cCI6IHsgInR5cGUiOiAiYm9vbGVhbiIgfSwKICAgICAgICAgICAgICAgICJzdm4tY2FjaGUtY3JlZGVudGlhbHMiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAidHJ1bmstcGF0aCI6IHsgInR5cGUiOiBbInN0cmluZyIsICJib29sZWFuIl0gfSwKICAgICAgICAgICAgICAgICJicmFuY2hlcy1wYXRoIjogeyAidHlwZSI6IFsic3RyaW5nIiwgImJvb2xlYW4iXSB9LAogICAgICAgICAgICAgICAgInRhZ3MtcGF0aCI6IHsgInR5cGUiOiBbInN0cmluZyIsICJib29sZWFuIl0gfSwKICAgICAgICAgICAgICAgICJwYWNrYWdlLXBhdGgiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJkZXBvdCI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgImJyYW5jaCI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgInVuaXF1ZV9wZXJmb3JjZV9jbGllbnRfbmFtZSI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgInA0dXNlciI6IHsgInR5cGUiOiAic3RyaW5nIiB9LAogICAgICAgICAgICAgICAgInA0cGFzc3dvcmQiOiB7ICJ0eXBlIjogInN0cmluZyIgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicGF0aC1yZXBvc2l0b3J5IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAidXJsIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJlbnVtIjogWyJwYXRoIl0gfSwKICAgICAgICAgICAgICAgICJ1cmwiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJjYW5vbmljYWwiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAib25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInN5bWxpbmsiOiB7ICJ0eXBlIjogWyJib29sZWFuIiwgIm51bGwiXSB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB0cnVlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJhcnRpZmFjdC1yZXBvc2l0b3J5IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAidXJsIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJlbnVtIjogWyJhcnRpZmFjdCJdIH0sCiAgICAgICAgICAgICAgICAidXJsIjogeyAidHlwZSI6ICJzdHJpbmciIH0sCiAgICAgICAgICAgICAgICAiY2Fub25pY2FsIjogeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgIm9ubHkiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXhjbHVkZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicGVhci1yZXBvc2l0b3J5IjogewogICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAicmVxdWlyZWQiOiBbInR5cGUiLCAidXJsIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJlbnVtIjogWyJwZWFyIl0gfSwKICAgICAgICAgICAgICAgICJ1cmwiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgICAgICJjYW5vbmljYWwiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAib25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInZlbmRvci1hbGlhcyI6IHsgInR5cGUiOiAic3RyaW5nIiB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJwYWNrYWdlLXJlcG9zaXRvcnkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidHlwZSIsICJwYWNrYWdlIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgInR5cGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJlbnVtIjogWyJwYWNrYWdlIl0gfSwKICAgICAgICAgICAgICAgICJjYW5vbmljYWwiOiB7ICJ0eXBlIjogImJvb2xlYW4iIH0sCiAgICAgICAgICAgICAgICAib25seSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBhY2thZ2UiOiB7CiAgICAgICAgICAgICAgICAgICAgIm9uZU9mIjogWwogICAgICAgICAgICAgICAgICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvaW5saW5lLXBhY2thZ2UiIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9pbmxpbmUtcGFja2FnZSIgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiaW5saW5lLXBhY2thZ2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IFsibmFtZSIsICJ2ZXJzaW9uIl0sCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgIm5hbWUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGFja2FnZSBuYW1lLCBpbmNsdWRpbmcgJ3ZlbmRvci1uYW1lLycgcHJlZml4LiIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInRhcmdldC1kaXIiOiB7CiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRFUFJFQ0FURUQ6IEZvcmNlcyB0aGUgcGFja2FnZSB0byBiZSBpbnN0YWxsZWQgaW50byB0aGUgZ2l2ZW4gc3ViZGlyZWN0b3J5IHBhdGguIFRoaXMgaXMgdXNlZCBmb3IgYXV0b2xvYWRpbmcgUFNSLTAgcGFja2FnZXMgdGhhdCBkbyBub3QgY29udGFpbiB0aGVpciBmdWxsIHBhdGguIFVzZSBmb3J3YXJkIHNsYXNoZXMgZm9yIGNyb3NzLXBsYXRmb3JtIGNvbXBhdGliaWxpdHkuIiwKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAia2V5d29yZHMiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiaG9tZXBhZ2UiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAidmVyc2lvbiI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInRpbWUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJsaWNlbnNlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogWwogICAgICAgICAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgImFycmF5IgogICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXV0aG9ycyI6IHsKICAgICAgICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL2F1dGhvcnMiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInJlcXVpcmUiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInJlcGxhY2UiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImNvbmZsaWN0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJwcm92aWRlIjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJyZXF1aXJlLWRldiI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAic3VnZ2VzdCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXh0cmEiOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBbIm9iamVjdCIsICJhcnJheSJdLAogICAgICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IHRydWUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXV0b2xvYWQiOiB7CiAgICAgICAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9hdXRvbG9hZCIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYXJjaGl2ZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsib2JqZWN0Il0sCiAgICAgICAgICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJleGNsdWRlIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImJpbiI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsic3RyaW5nIiwgImFycmF5Il0sCiAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkEgc2V0IG9mIGZpbGVzLCBvciBhIHNpbmdsZSBmaWxlLCB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIGFzIGJpbmFyaWVzIGFuZCBzeW1saW5rZWQgaW50byBiaW4tZGlyIChmcm9tIGNvbmZpZykuIiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImluY2x1ZGUtcGF0aCI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFsiYXJyYXkiXSwKICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiREVQUkVDQVRFRDogQSBsaXN0IG9mIGRpcmVjdG9yaWVzIHdoaWNoIHNob3VsZCBnZXQgYWRkZWQgdG8gUEhQJ3MgaW5jbHVkZSBwYXRoLiBUaGlzIGlzIG9ubHkgcHJlc2VudCB0byBzdXBwb3J0IGxlZ2FjeSBwcm9qZWN0cywgYW5kIGFsbCBuZXcgY29kZSBzaG91bGQgcHJlZmVyYWJseSB1c2UgYXV0b2xvYWRpbmcuIiwKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInNvdXJjZSI6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICJyZXF1aXJlZCI6IFsidHlwZSIsICJ1cmwiLCAicmVmZXJlbmNlIl0sCiAgICAgICAgICAgICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAidXJsIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAicmVmZXJlbmNlIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAibWlycm9ycyI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkaXN0IjogewogICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgInJlcXVpcmVkIjogWyJ0eXBlIiwgInVybCJdLAogICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgInVybCI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgInJlZmVyZW5jZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgInNoYXN1bSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgIm1pcnJvcnMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogdHJ1ZQogICAgICAgIH0KICAgIH0KfQojIwojIyBCdW5kbGUgb2YgQ0EgUm9vdCBDZXJ0aWZpY2F0ZXMKIyMKIyMgQ2VydGlmaWNhdGUgZGF0YSBmcm9tIE1vemlsbGEgYXMgb2Y6IFR1ZSBKYW4gMTkgMDQ6MTI6MDQgMjAyMSBHTVQKIyMKIyMgVGhpcyBpcyBhIGJ1bmRsZSBvZiBYLjUwOSBjZXJ0aWZpY2F0ZXMgb2YgcHVibGljIENlcnRpZmljYXRlIEF1dGhvcml0aWVzCiMjIChDQSkuIFRoZXNlIHdlcmUgYXV0b21hdGljYWxseSBleHRyYWN0ZWQgZnJvbSBNb3ppbGxhJ3Mgcm9vdCBjZXJ0aWZpY2F0ZXMKIyMgZmlsZSAoY2VydGRhdGEudHh0KS4gIFRoaXMgZmlsZSBjYW4gYmUgZm91bmQgaW4gdGhlIG1vemlsbGEgc291cmNlIHRyZWU6CiMjIGh0dHBzOi8vaGcubW96aWxsYS5vcmcvcmVsZWFzZXMvbW96aWxsYS1yZWxlYXNlL3Jhdy1maWxlL2RlZmF1bHQvc2VjdXJpdHkvbnNzL2xpYi9ja2Z3L2J1aWx0aW5zL2NlcnRkYXRhLnR4dAojIwojIyBJdCBjb250YWlucyB0aGUgY2VydGlmaWNhdGVzIGluIFBFTSBmb3JtYXQgYW5kIHRoZXJlZm9yZQojIyBjYW4gYmUgZGlyZWN0bHkgdXNlZCB3aXRoIGN1cmwgLyBsaWJjdXJsIC8gcGhwX2N1cmwsIG9yIHdpdGgKIyMgYW4gQXBhY2hlK21vZF9zc2wgd2Vic2VydmVyIGZvciBTU0wgY2xpZW50IGF1dGhlbnRpY2F0aW9uLgojIyBKdXN0IGNvbmZpZ3VyZSB0aGlzIGZpbGUgYXMgdGhlIFNTTENBQ2VydGlmaWNhdGVGaWxlLgojIwojIyBDb252ZXJzaW9uIGRvbmUgd2l0aCBtay1jYS1idW5kbGUucGwgdmVyc2lvbiAxLjI4LgojIyBTSEEyNTY6IDNiZGM2M2QxZGUyNzA1OGZlYzk0M2E5OTlhMmE4YTAxZmNjNjgwNmE2MTFiMTkyMjFhNzcyN2QzZDliYmJkZmQKIyMKCgpHbG9iYWxTaWduIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEZFRDQ0FsMmdBd0lCQWdJTEJBQUFBQUFCRlV0YXc1UXdEUVlKS29aSWh2Y05BUUVGQlFBd1Z6RUxNQWtHQTFVRUJoTUNRa1V4CkdUQVhCZ05WQkFvVEVFZHNiMkpoYkZOcFoyNGdibll0YzJFeEVEQU9CZ05WQkFzVEIxSnZiM1FnUTBFeEd6QVpCZ05WQkFNVEVrZHMKYjJKaGJGTnBaMjRnVW05dmRDQkRRVEFlRncwNU9EQTVNREV4TWpBd01EQmFGdzB5T0RBeE1qZ3hNakF3TURCYU1GY3hDekFKQmdOVgpCQVlUQWtKRk1Sa3dGd1lEVlFRS0V4QkhiRzlpWVd4VGFXZHVJRzUyTFhOaE1SQXdEZ1lEVlFRTEV3ZFNiMjkwSUVOQk1Sc3dHUVlEClZRUURFeEpIYkc5aVlXeFRhV2R1SUZKdmIzUWdRMEV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGEKRHVhWmpjNmo0MCtLZnZ2eGk0TWxhK3BJSC9FcXNMbVZFUVM5OEdQUjRtZG16eHpkenh0SUsrNk5pWTZhcnltQVphdnB4eTBTeTZzYwpUSEFIb1QwS01NMFZqVS80M2RTTVVCVWM3MUR1eEM3My9PbFM4cEY5NEczVk5UQ09Ya056OGtIcDFXcmpzb2s2VmprNGJ3WThpR2xiCktrM0ZwMVM0YkluTW0vazh5dVg5aWZVU1BKSjRsdGJjZEc2VFJHSFJqY2RHc25VT2h1Z1ppdFZ0Yk5WNEZwV2k2Y2dLT092eUpCTlAKYzFTVEU0VTZHN3dlTkxXTEJZeTVkNHV4Mng4Z2thc0pVMjZRem5zM2RMbHdSNUVpVVdNV2VhNnhya0VtQ01nWks5Rkdxa2pXWkNyWApnelQvTENyQmJCbERTZ2VGNTlOODlpRm83K3J5VXA5L2s1RFBBZ01CQUFHalFqQkFNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WCkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJnZTJZYVJRMlh5b2xRTDMwRXpUU28vL3o5U3pBTkJna3Foa2lHOXcwQkFRVUYKQUFPQ0FRRUExblBuZkU5MjBJMi83THFpdmpURktESzFmUHhzbkN3cnZRbWVVNzlyWHFvUlNMYmxDS096eWoxaFRkTkdDYk0rdzZEagpZMVViOHJydnJUbmhRN2s0bytZdmlpWTc3NkJRVnZuR0N2MDR6Y1FMY0ZHVWw1Z0UzOE5mbE5VVnlSUkJuTVJkZFdRVkRmOVZNT3lHCmovOE43eXk1WTBiMnF2emZ2R245TGhKSVpKcmdsZkNtN3ltUEFiRVZ0UXdkcGY1cExHa2tlQjZ6cHh4eFl1N0t5SmVzRjEyS3d2aEgKaG00cXhGWXhsZEJuaVlVcitXeW1YVWFkREtxQzVKbFIzWEMzMjFZOVllUnE0VnpXOXY0OTNrSE1CNjVqVXI5VFUvUXI2Y2Y5dHZlQwpYNFhTUVJqYmdiTUVITVVmcElCdkZTREozZ3lJQ2gzV1psWGkvRWpKS1NacDRBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR2xvYmFsU2lnbiBSb290IENBIC0gUjIKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR1akNDQXFLZ0F3SUJBZ0lMQkFBQUFBQUJENFltNWcwd0RRWUpLb1pJaHZjTkFRRUZCUUF3VERFZ01CNEdBMVVFQ3hNWFIyeHYKWW1Gc1UybG5iaUJTYjI5MElFTkJJQzBnVWpJeEV6QVJCZ05WQkFvVENrZHNiMkpoYkZOcFoyNHhFekFSQmdOVkJBTVRDa2RzYjJKaApiRk5wWjI0d0hoY05NRFl4TWpFMU1EZ3dNREF3V2hjTk1qRXhNakUxTURnd01EQXdXakJNTVNBd0hnWURWUVFMRXhkSGJHOWlZV3hUCmFXZHVJRkp2YjNRZ1EwRWdMU0JTTWpFVE1CRUdBMVVFQ2hNS1IyeHZZbUZzVTJsbmJqRVRNQkVHQTFVRUF4TUtSMnh2WW1Gc1UybG4KYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS2JQSkE2K0xtOG9tVVZDeEtzK0lWU2JDOU4vaEhENgpFclBMdjRkZnhuK0cwN0l3WE5iOXJmRjczT1g0WUpZSmtoRDEwRlBlKzN0K2M0aXNVb2g3U3FiS1NhWmVxS2VNV2hHOGVvTHJ2b3pwCnM2eVdKUWVYU3BrcUJ5KzBIbmUvaWcrMUFud2JscmpGdVRvc3ZOWVN1ZXRaZmVMUUJvWmZYa2xxdFRsZWlEVHN2SGdNQ0ppRWJLak4KUzdTZ2ZReDVUZkM0TGNzaHl0VnNXMzNob0NtRW9mblRsRW5MSkdLUklMemRDOVhaelBucUp3b3JjNUhHblJ1c3lNdm80S0QwTDVDTApUZnV3Tmh2MkdYcUY0RzN5WVJPSVhKL2drd3BSbDRwYXpxK3IxZmVxQ2FwZ3ZkelpYOTl5cVdBVFhnQUJ5VXI2UDZUcUJ3TWhBbzZDCnlnUENtNDhDQXdFQUFhT0JuRENCbVRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEUKRmdRVW0rSUhWMmNjSHNCcUJ0NVp0Sm90Mzl3WmhpNHdOZ1lEVlIwZkJDOHdMVEFyb0NtZ0o0WWxhSFIwY0RvdkwyTnliQzVuYkc5aQpZV3h6YVdkdUxtNWxkQzl5YjI5MExYSXlMbU55YkRBZkJnTlZIU01FR0RBV2dCU2I0Z2RYWnh3ZXdHb0czbG0wbWkzZjNCbUdMakFOCkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQW1ZRlRoeHhvbDRhUjdPQkt1RVFMcTRHc0owL1d3YmdjUTNpekRKcjg2aXc4Ym1FYlRVc3AKOVo4RkhTYkJ1T21EQUdKRnRxa0lrN21wTTBzWW1zTDRoNGhPMjkxeE5CckJWTnBHUCtEVEtxdHRWQ0wxT21MTklHKzZLWW5YM1pIdQowMXlpUHFGYlFmWGY1V1JETGVuVk9hdlNvdCszaTlEQWdCa2NSY0F0ak9qNExhUjBWa25GQmJWUEZkNXVSSGc1aDZoK3UvTjVHSkc3CjlHK2R3ZkNNTll4ZEFmdkRiYm52UkcxNVJqRitDdjZwZ3NILzc2dHVJTVJReVYrZFRac1hqQXpsQWNtZ1FXcHpVL3FsVUxSdUpRLzcKVEJqMC9WTFpqbW14NkJFUDNvalkreDFKOTZyZWxjOGdlTUpnRXRzbFFJeHEvSDVDT0VCa0V2ZWVnZUdUTGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpFbnRydXN0Lm5ldCBQcmVtaXVtIDIwNDggU2VjdXJlIFNlcnZlciBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRUtqQ0NBeEtnQXdJQkFnSUVPR1BlK0RBTkJna3Foa2lHOXcwQkFRVUZBRENCdERFVU1CSUdBMVVFQ2hNTFJXNTBjblZ6ZEM1dQpaWFF4UURBK0JnTlZCQXNVTjNkM2R5NWxiblJ5ZFhOMExtNWxkQzlEVUZOZk1qQTBPQ0JwYm1OdmNuQXVJR0o1SUhKbFppNGdLR3hwCmJXbDBjeUJzYVdGaUxpa3hKVEFqQmdOVkJBc1RIQ2hqS1NBeE9UazVJRVZ1ZEhKMWMzUXVibVYwSUV4cGJXbDBaV1F4TXpBeEJnTlYKQkFNVEtrVnVkSEoxYzNRdWJtVjBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlDZ3lNRFE0S1RBZUZ3MDVPVEV5TWpReApOelV3TlRGYUZ3MHlPVEEzTWpReE5ERTFNVEphTUlHME1SUXdFZ1lEVlFRS0V3dEZiblJ5ZFhOMExtNWxkREZBTUQ0R0ExVUVDeFEzCmQzZDNMbVZ1ZEhKMWMzUXVibVYwTDBOUVUxOHlNRFE0SUdsdVkyOXljQzRnWW5rZ2NtVm1MaUFvYkdsdGFYUnpJR3hwWVdJdUtURWwKTUNNR0ExVUVDeE1jS0dNcElERTVPVGtnUlc1MGNuVnpkQzV1WlhRZ1RHbHRhWFJsWkRFek1ERUdBMVVFQXhNcVJXNTBjblZ6ZEM1dQpaWFFnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dLREl3TkRncE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQXJVMUxxUktHc3VxaklBY1ZGbVFxSzB2UnZ3dEtUWTd0Z0hhbFo3ZDRRTUJ6UXNob3dOdFRLOTFldUhhWU5aT0wKR3AxOEV6b09IMXUzSHMvbEpCUWVzWUdwalgyNHpHdExBL0VDRE55cnBVQWtBSDkwbEtHZENDbXppQXYxaDNlZFZjM2t3MzdYYW1TcgpoUlNHbFZ1WE1sQnZQY2k2Wmd6ai9MMjRTY0YyaVVrWi9jQ292WW1qWnkvR243eHhHV0M0TGVrc3laQjJabnVVNHE5NDFtVlRYVHpXCm5MTFBLUVA1TDZSUXN0Ukl6Z1V5VllyOXNtUk1EdVNZQjNYYmY5KzVDRlZnaFRBcCtYdElwR21HNHpVL0hvWmRlbm9WdmU4QWpoVWkKVkJjQWtDYVR2QTVKYUpHLytFZlRuWlZDd1E1TjMyOG16OE1ZSVdKbVEzRFcxY0FINFFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVVZlU0IwUkdBdnRpSnVRaWpNZm1oSkFrV3VYQXdEUVlKCktvWklodmNOQVFFRkJRQURnZ0VCQUR1YmoxYWJNT2RUbVh4NmVhZE5sOWNabFpEN0JoL0tNM3hHWTQrV1ppVDZRQnNoSjhybWNuUHkKVC80eG1mM0lERXhvVThhQWdoT1krcmF0MmwwOThjNXU5aFVSbElJTTdqK1ZyeEdyRDljdjNoOERqMWNzSHNtN21ocEVsZXNZVDZZZgp6WDFYRUMrYkJBbGFoTFZ1MkIwNjRkYWUwV3g1WG5rY0ZNWGowRXlUTzJVODdkODl2cWJsbFJyRHRSbkR2VjVidS84ajcyZ1p5eEtUCkoxd0RMVzh3MEI2MkdxemVXdmZScXFnbnB2NTVnY1I1bVROWHVoS3dxZUJDYkpQS1Z0NytiWVFMQ0l0K2plclhtQ0hHOCtjOGVTOWUKbk5GTUZZM2g3Q0kzekpwREM1ZmNnSkNOczJlYmIwZ0lGVmJQdi9FcmZGNmFkdWxaa01WOGd6VVJaVkU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3QKPT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGR6Q0NBbCtnQXdJQkFnSUVBZ0FBdVRBTkJna3Foa2lHOXcwQkFRVUZBREJhTVFzd0NRWURWUVFHRXdKSlJURVNNQkFHQTFVRQpDaE1KUW1Gc2RHbHRiM0psTVJNd0VRWURWUVFMRXdwRGVXSmxjbFJ5ZFhOME1TSXdJQVlEVlFRREV4bENZV3gwYVcxdmNtVWdRM2xpClpYSlVjblZ6ZENCU2IyOTBNQjRYRFRBd01EVXhNakU0TkRZd01Gb1hEVEkxTURVeE1qSXpOVGt3TUZvd1dqRUxNQWtHQTFVRUJoTUMKU1VVeEVqQVFCZ05WQkFvVENVSmhiSFJwYlc5eVpURVRNQkVHQTFVRUN4TUtRM2xpWlhKVWNuVnpkREVpTUNBR0ExVUVBeE1aUW1GcwpkR2x0YjNKbElFTjVZbVZ5VkhKMWMzUWdVbTl2ZERDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS01FCnV5S3JtRDFYNkNaeW1yVjUxQ25pNGVpVmdMR3c0MXVPS3ltYVpOK2hYZTJ3Q1FWdDJ5Z3V6bUtpWXY2MGlOb1M2empySVozQVFTc0IKVW51SWQ5TWNqOGU2dVlpMWFnbm5jK2dSUUtmUnpNcGlqUzNsand1bVVOS29VTU1vNnZXckpZZUttcFljcVdlNFB3elY5L2xTRXkvQwpHOVZ3Y1BDUHdCTEtCc3VhNGRuS00zcDMxdmpzdWZGb1JFSklFOUxBd3FTdVhtRCt0cVlGL0xUZEIxa0MxRmtZbUdQMXBXUGdrQXg5ClhiSUdldk9GNnV2VUE2NWVoRDVmL3hYdGFiejVPVFp5ZGM5M1VrM3p5WkFzdVQzbHlTTlRQeDhrbUNGY0I1a3B2Y1k2N09kdWhqcHIKbDNSak03MW9HREh3ZUkxMnYveWVqbDBxaHFkTmtOd25HamtDQXdFQUFhTkZNRU13SFFZRFZSME9CQllFRk9XZFdUQ0NSMWpNclBvSQpWRGFHZXpxMUJFM3dNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUU13RGdZRFZSMFBBUUgvQkFRREFnRUdNQTBHQ1NxR1NJYjNEUUVCCkJRVUFBNElCQVFDRkRGMk81RzlSYUVJRm9OMjdUeWNsaEFPOTkyVDlMZGN3NDZRUUYrdmFLU20yZVQ5Mjloa1RJN2dRQ3ZsWXBOUmgKY0wwRVlXb1NpaGZWQ3IzRnZEQjgxdWtNSlkyR1FFL3N6S04rT01ZM0VVL3QzV2d4amt6U3N3RjA3cjUxWGdkSUduOXcveFpjaE1CNQpoYmdGL1grK1pSR2pEOEFDdFBoU056a0UxYWt4ZWhpL29DcjBFcG4zbzBXQzR6eGU5WjJldGNpZWZDN0lwSjVPQ0JSTGJmMXdiV3NhClk3MWs1aCszenZEeW55NjdHN2Z5VUloemtzTGk0eGFObWpJQ3E0NFkzZWtRRWU1K05hdVFyejR3bEhyUU16Mm5aUS8xL0k2ZVlzOUgKUkN3Qlhic2R0VExTUjlJNEx0RCtnZHd5YWg2MTdqelYvT2VCSFJuREpFTHFZem1wCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVrVENDQTNtZ0F3SUJBZ0lFUld0UVZEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnNERUxNQWtHQTFVRUJoTUNWVk14RmpBVUJnTlYKQkFvVERVVnVkSEoxYzNRc0lFbHVZeTR4T1RBM0JnTlZCQXNUTUhkM2R5NWxiblJ5ZFhOMExtNWxkQzlEVUZNZ2FYTWdhVzVqYjNKdwpiM0poZEdWa0lHSjVJSEpsWm1WeVpXNWpaVEVmTUIwR0ExVUVDeE1XS0dNcElESXdNRFlnUlc1MGNuVnpkQ3dnU1c1akxqRXRNQ3NHCkExVUVBeE1rUlc1MGNuVnpkQ0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUI0WERUQTJNVEV5TnpJd01qTTAKTWxvWERUSTJNVEV5TnpJd05UTTBNbG93Z2JBeEN6QUpCZ05WQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFGYm5SeWRYTjBMQ0JKYm1NdQpNVGt3TndZRFZRUUxFekIzZDNjdVpXNTBjblZ6ZEM1dVpYUXZRMUJUSUdseklHbHVZMjl5Y0c5eVlYUmxaQ0JpZVNCeVpXWmxjbVZ1ClkyVXhIekFkQmdOVkJBc1RGaWhqS1NBeU1EQTJJRVZ1ZEhKMWMzUXNJRWx1WXk0eExUQXJCZ05WQkFNVEpFVnVkSEoxYzNRZ1VtOXYKZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQgpBTGFWdGtOQytzWnRLbTlJMzVSTU9WY0Y3c041RVVGb051M3MvcG9CajZFNEtQejNFRVptTGswZUdyRWFUc2JSd0pXSXNNbi9NWXN6CkE5dTNnM3MrSUlSZTdiSldLS2Y0NExsQWNUZkZ5MGNPbHlwb3dDS1ZZaFhiUjluMTBDdi9na3ZKclQ3ZVROdVFnRkEvQ1lxRUFPd3cKQ2owWXpmdjlLbG1hSTVVWExFV2VIMjVEZVcwTVhKaitTS2ZGSTBkY1h2MXU1eDYwOW1oRjBZYURXNktLamJIaktZRCtKWEdJcmI2OApqNnhTbGt1cVVZM2tFekVaNkU1Tm45dXNzMnJWdkRsVWNjcDZlbitRM1gwZGdObUJ1MWttd2hIKzVwUGk5NERrWmZzME53NHBnSEJOCnJ6aUdMcDUvVjYrZUY2N3JITXNvSVYrMkhOam5vZ1FpK2RQYTJNc0NBd0VBQWFPQnNEQ0JyVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXcKRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFyQmdOVkhSQUVKREFpZ0E4eU1EQTJNVEV5TnpJd01qTTBNbHFCRHpJd01qWXhNVEkzTWpBMQpNelF5V2pBZkJnTlZIU01FR0RBV2dCUm9rT1JucEtaVGdNZUdacVR4OTB0RCs0UzliVEFkQmdOVkhRNEVGZ1FVYUpEa1o2U21VNERICmhtYWs4ZmRMUS91RXZXMHdIUVlKS29aSWh2WjlCMEVBQkJBd0Roc0lWamN1TVRvMExqQURBZ1NRTUEwR0NTcUdTSWIzRFFFQkJRVUEKQTRJQkFRQ1QxREN3MXdNZ0t0RDVZK2lSREFVZ3FWOFp5bnR5VHRTeDI5Q1crMVJhR1N3TUNQZXl2SVdvblg5dE8xS3pLdHZuMUlTTQpZL1lQeXlZQmtWQnM5RjhVNHBOMHdCT2VNRHBRNDdSZ3hSendJa1NOY1Vlc3lCcko2WnVhQUdBVC8zQitYeEZOU1J1ekZWSjd5VlRhCnY1MlZyMnVhMko3cDhlUkRqZUlSUkRxL3I3MkRRbk5TaTZxN3B5blA5V1FjQ2szUnZLcXNueXJRLzM5LzJuM3FzZTB3SmNHRTJqVFMKVzNpRFZ1eWNOc01tNGhIMlowa2RrcXVNKyt2L2V1NkZTcWRRZ1BDblhFcVVMbDhGbVR4U1FlRE50R1BQQVVPNm5JUGNqMkE3ODFxMAp0SHV1Mmd1UU9IWHZnUjFtMHZkWGNEYXp2L3dvcjNFbGhWc1QvaDUvV3JROAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDb21vZG8gQUFBIFNlcnZpY2VzIHJvb3QKPT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFTWpDQ0F4cWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCN01Rc3dDUVlEVlFRR0V3SkhRakViTUJrR0ExVUVDQXdTClIzSmxZWFJsY2lCTllXNWphR1Z6ZEdWeU1SQXdEZ1lEVlFRSERBZFRZV3htYjNKa01Sb3dHQVlEVlFRS0RCRkRiMjF2Wkc4Z1EwRWcKVEdsdGFYUmxaREVoTUI4R0ExVUVBd3dZUVVGQklFTmxjblJwWm1sallYUmxJRk5sY25acFkyVnpNQjRYRFRBME1ERXdNVEF3TURBdwpNRm9YRFRJNE1USXpNVEl6TlRrMU9Wb3dlekVMTUFrR0ExVUVCaE1DUjBJeEd6QVpCZ05WQkFnTUVrZHlaV0YwWlhJZ1RXRnVZMmhsCmMzUmxjakVRTUE0R0ExVUVCd3dIVTJGc1ptOXlaREVhTUJnR0ExVUVDZ3dSUTI5dGIyUnZJRU5CSUV4cGJXbDBaV1F4SVRBZkJnTlYKQkFNTUdFRkJRU0JEWlhKMGFXWnBZMkYwWlNCVFpYSjJhV05sY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUw1QW5mUnU0ZXAyaHh4TlJVU092a2JJZ3dhZHdTcitHQitPNUFMNjg2dGRVSW9XTVF1YUJ0REZjQ0xOU1MxVVk4eTJibWhHCkMxUHF5MHdrd0x4eVR1cnhGYTcwVkpvU0NzTjZzak5nNHRxSlZmTWlXUFBlM00vdmc0YWlqSlJQbjJqeW1KQkdoQ2ZIZHIvanpEVXMKaTE0SFpHV0N3RWl3cUpINVlaOTJJRkNva2NkbXRldDRZZ05XOElvYUUrb3hveDZnbWYwNDl2WW5NbGh2Qi9WcnVQc1VLNiszcXN6VwpZMTl6ak5vRm1hZzRxTXNYZURaUnJPbWU5SGc2amM4UDJVTGltQXlyTDU4T0FkN3ZuNWxKOFMzZnJIUk5HNWkxUjhYbEtkSDVrQmpICllweStnOGNtZXo2S0pjZkEzWjNtTldnUUlKMlAyTjdTdzRTY0RWN29MOGtDQXdFQUFhT0J3RENCdlRBZEJnTlZIUTRFRmdRVW9CRUsKSXo2VzhRZnM0cThwNzRLbGY5QXdwTFF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdld1lEVlIwZgpCSFF3Y2pBNG9EYWdOSVl5YUhSMGNEb3ZMMk55YkM1amIyMXZaRzlqWVM1amIyMHZRVUZCUTJWeWRHbG1hV05oZEdWVFpYSjJhV05sCmN5NWpjbXd3TnFBMG9ES0dNR2gwZEhBNkx5OWpjbXd1WTI5dGIyUnZMbTVsZEM5QlFVRkRaWEowYVdacFkyRjBaVk5sY25acFkyVnoKTG1OeWJEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFDRmI4QXZDYjZQK2srdFo3eGtTQXprL0V4ZllBV015bXRyd1VTV2dFZHVqbQo3bDNzQWc5ZzFvMVFHRThtVGdIajVyQ2w3cis4ZEZSQnYvMzhFcmpIVDFyMGlXQUZmMkMzQlVyejl2SEN2OFM1ZElhMkxYMXJ6Tkx6ClJ0MHZ4dUJxdzhNMEF5eDlsdDFhd2c2bkNwbkJCWXVyREMvelhEclBiRGRWQ1lmZVUwQnNXTy84dHF0bGJnVDJHOXc4NEZvVnhwN1oKOFZsSU1DRmxBMnpzNlNGejdKc0RvZUEzcmFBVkdJLzZ1Z0xPcHl5cEVCTXMxT1VJSnFzaWwyRDRrRjUwMUtLYVU3M3lxV2pnb203QwoxMnl4b3crZXYrdG81MWJ5cnZMakt6ZzZDWUcxYTRYWHZpM3RQeHEzc21QaTlXSXNndFJxQUVGUThUbURuNVhwTnBhWWJnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKUXVvVmFkaXMgUm9vdCBDQQo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGMERDQ0JMaWdBd0lCQWdJRU9yWlFpekFOQmdrcWhraUc5dzBCQVFVRkFEQi9NUXN3Q1FZRFZRUUdFd0pDVFRFWk1CY0dBMVVFCkNoTVFVWFZ2Vm1Ga2FYTWdUR2x0YVhSbFpERWxNQ01HQTFVRUN4TWNVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDAKZVRFdU1Dd0dBMVVFQXhNbFVYVnZWbUZrYVhNZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzB3TVRBegpNVGt4T0RNek16TmFGdzB5TVRBek1UY3hPRE16TXpOYU1IOHhDekFKQmdOVkJBWVRBa0pOTVJrd0Z3WURWUVFLRXhCUmRXOVdZV1JwCmN5Qk1hVzFwZEdWa01TVXdJd1lEVlFRTEV4eFNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUzR3TEFZRFZRUUQKRXlWUmRXOVdZV1JwY3lCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQXYyRzFsVk82Vi96NjhtY0xPaHJmRVlCa2xiVFJ2TTE2ei9ZcGxpNGtWRUFrT1BjYWhkeFlUTXVrCkowS1gwSitEaXNQa0JnTmJBS1ZSSG5BRWRPTEIxRHFyMTYwN0J4Z0ZqdjJEck9wbTJSZ2JhSXIxVnhxWXV2WHRkajE4MmQ2VWFqdEwKRjhIVmo3MWxPRHFWMEQxVk5rN2ZlVmN4S2g3WVdXVkpXQ0NZZnF0ZmZwL3AxazNzZzNTcHgyelk3aWxLaFNvR0ZQbFU1dFBhWlFlTApZemNTMTlEc3czc2dRVVNqN2N1Z0YrRnhaYzRkWmpIM2RnRVp5SDBEV0xhVlNSMm1FaWJveGd4MjRPTm15K3BkcGlidTVjeGZ2V2VuCkFTY09vc3BVeGJGNmxSMXhIa29waWdQY2FrWEJwQmxlYnpiTnc2S3d0LzVjT09KU3ZQaEVRK2FRdXdJREFRQUJvNElDVWpDQ0FrNHcKUFFZSUt3WUJCUVVIQVFFRU1UQXZNQzBHQ0NzR0FRVUZCekFCaGlGb2RIUndjem92TDI5amMzQXVjWFZ2ZG1Ga2FYTnZabVp6YUc5eQpaUzVqYjIwd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pDQ0FSb0dBMVVkSUFTQ0FSRXdnZ0VOTUlJQkNRWUpLd1lCQkFHK1dBQUJNSUg3Ck1JSFVCZ2dyQmdFRkJRY0NBakNCeHhxQnhGSmxiR2xoYm1ObElHOXVJSFJvWlNCUmRXOVdZV1JwY3lCU2IyOTBJRU5sY25ScFptbGoKWVhSbElHSjVJR0Z1ZVNCd1lYSjBlU0JoYzNOMWJXVnpJR0ZqWTJWd2RHRnVZMlVnYjJZZ2RHaGxJSFJvWlc0Z1lYQndiR2xqWVdKcwpaU0J6ZEdGdVpHRnlaQ0IwWlhKdGN5QmhibVFnWTI5dVpHbDBhVzl1Y3lCdlppQjFjMlVzSUdObGNuUnBabWxqWVhScGIyNGdjSEpoClkzUnBZMlZ6TENCaGJtUWdkR2hsSUZGMWIxWmhaR2x6SUVObGNuUnBabWxqWVhSbElGQnZiR2xqZVM0d0lnWUlLd1lCQlFVSEFnRVcKRm1oMGRIQTZMeTkzZDNjdWNYVnZkbUZrYVhNdVltMHdIUVlEVlIwT0JCWUVGSXRMYmUzVEtia0dHZXc1T2Fud2w0UnF5Ky9mTUlHdQpCZ05WSFNNRWdhWXdnYU9BRkl0TGJlM1RLYmtHR2V3NU9hbndsNFJxeSsvZm9ZR0VwSUdCTUg4eEN6QUpCZ05WQkFZVEFrSk5NUmt3CkZ3WURWUVFLRXhCUmRXOVdZV1JwY3lCTWFXMXBkR1ZrTVNVd0l3WURWUVFMRXh4U2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjAKYUc5eWFYUjVNUzR3TEFZRFZRUURFeVZSZFc5V1lXUnBjeUJTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1Z2dRNgp0bENMTUE0R0ExVWREd0VCL3dRRUF3SUJCakFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBaXRRVXRmNzBtcEtuR2RTa2ZuSVlqOWxvCmZGSWszV2R2T1hyRXFsNDk0bGl3VFhDWWhHSG9HK05wR0E3TyswZFFvRTcvOENRZnZiTE85U2Y4N0M5VHFuTjdBejEwYnVZV251dWwKTHNTL1ZpZFFLMks2dmtzY1BGVmNRUjBrdm9JZ1IxM1ZSSDU2Rm1qZmZVMVJjSGhYSFRNZS9RS1puQXpOQ2dWUHg3dU9wSFg2U20yeApnSTRKVnJtY0dtRCtYY0hYZXR3UmVORFdYY0czMWEweW1RTTZpc3hVSlRreGdYc1RJbEc2Um15aHU1NzZCR3hKSm5TUDBuUHJ6RENpCjV1cFpJb2Y0bC9VTy9lck1rcVFXeEZJWTZpSE9zZkhtaElIbHVxbUdLUEpEV2wwU25hd2UyYWpsQ21xbmY2Q0hLYy95aVUzVTdNWGkKNW5yUU5pT0tTblEyK1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpRdW9WYWRpcyBSb290IENBIDIKPT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGdHpDQ0E1K2dBd0lCQWdJQ0JRa3dEUVlKS29aSWh2Y05BUUVGQlFBd1JURUxNQWtHQTFVRUJoTUNRazB4R1RBWEJnTlZCQW9UCkVGRjFiMVpoWkdseklFeHBiV2wwWldReEd6QVpCZ05WQkFNVEVsRjFiMVpoWkdseklGSnZiM1FnUTBFZ01qQWVGdzB3TmpFeE1qUXgKT0RJM01EQmFGdzB6TVRFeE1qUXhPREl6TXpOYU1FVXhDekFKQmdOVkJBWVRBa0pOTVJrd0Z3WURWUVFLRXhCUmRXOVdZV1JwY3lCTQphVzFwZEdWa01Sc3dHUVlEVlFRREV4SlJkVzlXWVdScGN5QlNiMjkwSUVOQklESXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDCkR3QXdnZ0lLQW9JQ0FRQ2FHTXBMbEEwQUxhOERLWXJ3RDRISXJrd1poUjBJbjZzcFJJWHpMNEd0TWg2UVJyK2poaVlhSHY1K0hCZzYKWEp4Z0Z5bzZkSU16TUgxaFZCSEw3YXZnNXRLaWZ2VnJieGkzQ2dzdC9lays3d3JHc3hEcDNNSkdGL2hkL2FUYS81NUpXcHptTStZawpsdmMvdWxzckhIbzF3dFpuL3F0bVVJdHRLR0FyNzlkZ3c4ZVR2STAya2ZOLytOc1JFOFNjZDNiQnJyY0Nhb0Y2cVVXRDRnWG11VmJCCmxEZVBTSEZqSXV3WFpRZVZpa3ZmajhaYUN1V3c0MTllYXhHckRQbUY2MFRwK0FSejh1bitYSmlNOVhPdmE3Uit6ZFJjQWl0TU9lR3kKbFpVdFFvZlgxYk9RUTdkc0UvSGUzZmJFK0lrLzBYWDFrc09SMVlxSTBKRHMzRzNlaWNKbGNaYUxEUVA5bkw5YkZxeVMyK3IrZVh5dAo2Ni8zRnN2YnpTVXI1Ui83bXAvaVVjdzZVd3hJNWc2OXliUjJCbExtRVJPRmNtTURCT0FFTmlzZ0dRTG9kS2NmdHNsV1p2QjFKZHhuCndRNWhZSWl6UHRHby9LUGFIYkRSc1NOVTMwUjJiZTFCMk1HeUlyWlRITjgxSGR5aGR5b3g1QzMxNWVYYnlPRC81WURYQzJPZy96T2gKRDdvc0ZSWHFsN1BTb3JXKzhveVdIaHFQSFd5a1lUZTVobk16MTVlV25pTjlncVJNZ2VLaDBicG5YNVVIb3ljUjdoWVFlN3hGU2t5eQpCTktyNzlYOURGSE9VR29JTWZtUjJneVBaRndEd3pxTElEOXVqV2M5T3RiK2ZWdUl5Vjc3ekdIY2l6TjMwMFF5TlFsaUJKSVdFTmllCkowZjdPeUhqK09zZFd3SURBUUFCbzRHd01JR3RNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdDd1lEVlIwUEJBUURBZ0VHTUIwR0ExVWQKRGdRV0JCUWFoR0s4U0V3ekpRVFU3dEQyQThRWlJ0R1VhekJ1QmdOVkhTTUVaekJsZ0JRYWhHSzhTRXd6SlFUVTd0RDJBOFFaUnRHVQphNkZKcEVjd1JURUxNQWtHQTFVRUJoTUNRazB4R1RBWEJnTlZCQW9URUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4R3pBWkJnTlZCQU1UCkVsRjFiMVpoWkdseklGSnZiM1FnUTBFZ01vSUNCUWt3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUQ0S0ZrMmZCbHVvcm5GZEx3VXYKWitZVFJZUEVOdmJ6d0NZTURiVkhaRjM0dEhMSlJxVURHQ2RWaVhoOWR1cVdOSUFYSU56bmcvaU4vQWU0Mmw5TkxtZXloUDNaUlB4MwpVSUhtZkxUSkRRdHlVL2gyQndkQlI1WU0rK0NDSnBOVmpQNGlIMkJsZkYvbkpyUDNNcENZVU5RM2NWWDJraUY0OTVWNSt2Z3RKb2RtClZqQjNwamQ0TTFJUVdLNC9ZWTd5YXJIdkdINUtXV1BLamFKVzFhY3Z2RllmenpuQjR2c0txQlVzZlUxNlk4WnNsMFE4MG0vRFNoY0sKK0pEU1Y2SVpVYVV0bDBIYUIwK3BVTnFRalpSRzRUN3dsUDBRQURqMU8raEE0YlJ1VmhvZ3pHOVlqZTB1UlkvVzZaTS81N0VzM3pyVwpJb3pjaExzaWI5RDQ1TVk1NlFTSVBNTzY2MVY2YllDWkpQVnNBZnY0bDdDVVcrdjkwbS94ZDJnTk5XUWpyTGhWb1FQUlRVSVozUGgxCldWYWorYWhKZWZpdkRya1JvSHkzYXUwMDBMWW1ZamdhaHd6NDZQMHUwNUIvQjVFcUhkWitYSVdEbWJBNENEL3BYdmsxQitUSlltNVgKZjZkUWxmZTZ5SnZtanFJQnhkWm12M2xoOHp3YzRibUNYRjJndytuWVNMMFpvaEVVR1c2eWhodG9Qa2czR29pM1haWmVuTWZ2SjJJSQo0cEVaWE5MeElkMjZGMEtDbDNHQlV6R3BuL1o5WXI5eTRhT1RIY3lLSmxvSk9ORE8xdzJBRnJSNHBUcUhUSTJLcGRWR2wvSXNFTG04ClZDTEFBVkJwUTU3MHN1OXQrT3phOGVPeDc5K1JqMVFxQ3lYQkpobkVVaEFGWmRXQ0VPckNNYzB1Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClF1b1ZhZGlzIFJvb3QgQ0EgMwo9PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUduVENDQklXZ0F3SUJBZ0lDQmNZd0RRWUpLb1pJaHZjTkFRRUZCUUF3UlRFTE1Ba0dBMVVFQmhNQ1FrMHhHVEFYQmdOVkJBb1QKRUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4R3pBWkJnTlZCQU1URWxGMWIxWmhaR2x6SUZKdmIzUWdRMEVnTXpBZUZ3MHdOakV4TWpReApPVEV4TWpOYUZ3MHpNVEV4TWpReE9UQTJORFJhTUVVeEN6QUpCZ05WQkFZVEFrSk5NUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNCmFXMXBkR1ZrTVJzd0dRWURWUVFERXhKUmRXOVdZV1JwY3lCU2IyOTBJRU5CSURNd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUMKRHdBd2dnSUtBb0lDQVFETVYwSVdWSnptbU5QVFRlNys3Y2VmUXpsS1piUG9Gb2cwMncxWmtYVFBrcmdFUUswQ1N6R3J2STJSYU5nZwpEaG9CNGhwN1RoZGQ0b3EzUDVrYXpldGhxOEpscGgrM3Q3MjNqL3o5Y0k4TG9HZStBYUpaejNIbUR5bDIvN0ZXZVVVckg1NTZWT2lqCktUVm9wQUZQRDZRdU4rOGJ2K09QRUtoeXExaFg1MVNHeU1uelc5b3MybDJPYmp5alB0cjdndVhkOGx5eUJUTnZpamJPMEJOTy83OUsKRERSTXBzTWh2VkFFVmV1eHU1MzdSUjVrRmQ1VkFZd0NkclhMb1Q5Q2Fid3Z2V2hERmxhSktqZGhrZjJtcms3QXl4UmxsRGRMa2didgpCTkRJbklqYkMzdUJyN0U5S3NSbE9uaTI3dHlBc2RMVG1adzY3bXRhYTdPTnQ5WE9uTUsrcFVzdkZyR2VhRHNHYjY1OW4vamU3TXdwCnA1aWpKVU12Ny9GZkp1R0lUZmhlYnRmWkZHNFpNMm1uTzRTSms4UlRWUk9oVVhoQStMakpvdTU3dWxKQ2c1NFU3UVZTV2xsV3A1ZjgKblQ4S0tkamNUNUVPRTd6ZWxhVGZpNW0rckpzemlPKzFnYThieGlKVHlQYkg3cGNVc01WOGVGTEk4TTV1ZDJDRXB1a3FkaUR0V0FFWApNSlBwR292Z2MyUFphcEtVU1U2MHJVcUZ4S01pTVB3SjdXZ2ljNmFJREZVaFdNWGhPcDhxM2NyaGtPRFpjNnRzZ0xqb0MyU1RvSnlNCkdmK3owZ3pza1NhSGlyT2k0WENQTEFybHpXMW9VZXZhUHdWL2l6TG1FMXhyL2w5QTRpTEl0TFJrVDlhNmZVZytxR2tNMTd1R2NjbHoKdUQ4N25TVkwydjlBNndJREFRQUJvNElCbFRDQ0FaRXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96Q0I0UVlEVlIwZ0JJSFpNSUhXTUlIVApCZ2tyQmdFRUFiNVlBQU13Z2NVd2daTUdDQ3NHQVFVRkJ3SUNNSUdHR29HRFFXNTVJSFZ6WlNCdlppQjBhR2x6SUVObGNuUnBabWxqCllYUmxJR052Ym5OMGFYUjFkR1Z6SUdGalkyVndkR0Z1WTJVZ2IyWWdkR2hsSUZGMWIxWmhaR2x6SUZKdmIzUWdRMEVnTXlCRFpYSjAKYVdacFkyRjBaU0JRYjJ4cFkza2dMeUJEWlhKMGFXWnBZMkYwYVc5dUlGQnlZV04wYVdObElGTjBZWFJsYldWdWRDNHdMUVlJS3dZQgpCUVVIQWdFV0lXaDBkSEE2THk5M2QzY3VjWFZ2ZG1Ga2FYTm5iRzlpWVd3dVkyOXRMMk53Y3pBTEJnTlZIUThFQkFNQ0FRWXdIUVlEClZSME9CQllFRlBMQUUrQ0NRejc3N2k5bk1wWTFYTnU0eXdMUU1HNEdBMVVkSXdSbk1HV0FGUExBRStDQ1F6Nzc3aTluTXBZMVhOdTQKeXdMUW9VbWtSekJGTVFzd0NRWURWUVFHRXdKQ1RURVpNQmNHQTFVRUNoTVFVWFZ2Vm1Ga2FYTWdUR2x0YVhSbFpERWJNQmtHQTFVRQpBeE1TVVhWdlZtRmthWE1nVW05dmRDQkRRU0F6Z2dJRnhqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFUNjJnTEV6NndQSnY5MlpWCnF5TTA3dWNwMnNOYnRyQ0QyZERRNGlINzgyQ25PMTFnVXllaW0vWUlJaXJudjZCeTVad2thakd4a0hvbjI0UVJpU2VtZDFvNDE3K3MKaHZ6dVhZTzhCc2JSZDJzUGJTUXZTM3BzcHdlV3l1T0VuNjJJaXgyckZvMWJaaGZaRnZTTGdOTGQrTEoydy93NEU2b00za0pwSzI3egpQT3VBSjl2MXBrUU5uMXBWV1F2VkRWSkl4YTZmOGkrQXhlb3lVRFVTbHk3QjRmL3hJNGhST0oveVpsWjI1dzlSbDZWU0RFMUpVWlUyClBiK2lTd3dRSFlhWlRLcnpjaEdUNU9yMm05cW9YYWROdDU0Q3JuTUF5Tm9qQStqNTZobDBZZ0NVeXlJZ3ZwU25XYldDYXI2WmVYcXAKOGtva1V2ZDAvYnBPNXFnZEFtNnhEWUJFd2E3VEl6ZGZ1NFY4SzVJdTZINmxpOTJaNGI4bmJ5MWRxbnVIL2dyZFMveU85U2JrYm5CQwpialBzTVo1N2s4SGt5V2thUGNCclRpSnQ3cXRZVGNiUVFjRXI2azhTaDE3clJkaHM5WmdDMDZEWVZZb0dtUm1pb0hmUk1KNnN6SFh1CmcvV3dZam5QYkZmaVROS1JDdzUxS0J1YXYvMGFRL0hLZC9zN2oyRzRhU2dXUWdSZWNDb2NJZGlQNGIwald5MTBRSkxaWXhrTmM5MXAKdkdKSHZPQjBLN0xyZmI1Qkc3WEFSc1doSXN0ZlRzRW9rdDRZdXRVcUtMc1JpeGVUbUpsZ2xGd2p6MW9ubDE0TEJRYVROeDQ3YVRicgpxWjVoSFk4eTJvNE0xblErZXdrazJnRjNSOFE3elRTTW1mWEs0U1ZoTTdKWkcrSnUxemRYdGcycEV0bz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFdqQ0NBa0tnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFVRkFEQlFNUXN3Q1FZRFZRUUdFd0pLVURFWU1CWUdBMVVFQ2hNUApVMFZEVDAwZ1ZISjFjM1F1Ym1WME1TY3dKUVlEVlFRTEV4NVRaV04xY21sMGVTQkRiMjF0ZFc1cFkyRjBhVzl1SUZKdmIzUkRRVEV3CkhoY05NRE13T1RNd01EUXlNRFE1V2hjTk1qTXdPVE13TURReU1EUTVXakJRTVFzd0NRWURWUVFHRXdKS1VERVlNQllHQTFVRUNoTVAKVTBWRFQwMGdWSEoxYzNRdWJtVjBNU2N3SlFZRFZRUUxFeDVUWldOMWNtbDBlU0JEYjIxdGRXNXBZMkYwYVc5dUlGSnZiM1JEUVRFdwpnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDenMvNS8wMjJ4N3haOFY2VU1iWGFLTDB1L1pQdE03b3J3Cjh5bDg5Zi91S3VEcDZicGJaQ0thbW04c09pWnBVUVdaSnR6VkhHcHh4cHA5SHAzZGZHekdqR2RuU2o3NGNiQVpKNmtKREthVnYwdU0KRFBwVm1Edlk2Q0toUzNFNGVheVhrbW16aVg3cUlXZ0dtQlNXaDlKaE5yeHRKMWFlVis3QXdGYjlNcytrMlk3Q0k5ZU5xUFBZSmF5WAo1SEE0OUxZNnRKMDdseVpEbzZHOFNWbHlUQ013aHdGWTlrNitIR2hXWnEvTlFWM0lzMDBxVlVhckg5b2U0a0E5MjgxOXVaS0FuRGZkCkRKWmtuZHdpOTJTTDMySGVGWlJTRmFCOVVzbExxQ0hKeHJIdHk4T1ZZTkVQOEt0dytOL0xUWDdzMXZxcjJiMS9WUEtsNlhuNjJkWjIKSkNoekFnTUJBQUdqUHpBOU1CMEdBMVVkRGdRV0JCU2djMG1aYU55RlcyWGpteWd2VjUrOU03d0hTREFMQmdOVkhROEVCQU1DQVFZdwpEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFhRUNwcUx2a1QxMTVzd1cxRjdOZ0UrdkdrbDNnCjBkTnEvdnUrbTIyL3h3VnRXU0RFSFBDMzJvUllBbVA2U0JidlQ2VUw5MHFZOGorZUc2MUhhMlBPQ0VmclVqOTRuSzlOcnZqVlQ4K2EKbUNvUVFUbFN4TjNabXc3dmt3R3VzaTdLYUVJa1FteXdzem8remVuYVNNUVZ5K241QncrU1VFbUszVEdYWDhucE42bzdXV1dYbERMSgpzNTgrT21KWXhVbXRZZzV4cFRLcUw4YUpka05BRXhOblBhSlVKUkRMOFRyeTJmcmJTVmE3cHY2blFUWEQ0SWhoeVlqSDN6WVFJcGhaCjZyQksrMVlXYzI2c1RmY2lvVSt0SFhvdFJTZmxNTUZlOHRvVHl5VkNVWlZIQTR4c0ljeDBRdTFUL3pPTGp3OVhBUll2ejZidXlYQWkKRkwzOXZtd0xBdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNvbmVyYSBDbGFzcyAyIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRElEQ0NBZ2lnQXdJQkFnSUJIVEFOQmdrcWhraUc5dzBCQVFVRkFEQTVNUXN3Q1FZRFZRUUdFd0pHU1RFUE1BMEdBMVVFQ2hNRwpVMjl1WlhKaE1Sa3dGd1lEVlFRREV4QlRiMjVsY21FZ1EyeGhjM015SUVOQk1CNFhEVEF4TURRd05qQTNNamswTUZvWERUSXhNRFF3Ck5qQTNNamswTUZvd09URUxNQWtHQTFVRUJoTUNSa2t4RHpBTkJnTlZCQW9UQmxOdmJtVnlZVEVaTUJjR0ExVUVBeE1RVTI5dVpYSmgKSUVOc1lYTnpNaUJEUVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSkFYU2pXZHl2QU5sc2RFK2hZMwovRWk5dlgrQUxUVTc0VytvWjZtL0F4eE5qRzh5UjlWQmFLUVRCTUUxREpxRVEveGNIZitKcytnWEdNMlJYL3VKNCtxL1RsMThHeWJUCmRYbnQ1b1RqVitXdEtjVDBPaWpucFh1RU5tbXovVjUydmFNdG1kT1FUaU1vZlJoajhWUTdKcDEyVzVkQ3N2K3U4RTdzM1RtVlRvTUcKZitkSlFNakZBYkpVV21ZZFBmejU2VHdLbm9HNGNQQUJpK1FqVkh6SXJ2aVFIZ0NXY3RSVXoyRWp2T3I3blFLVjBiYTVjVHBwQ0Q4UAp0T0ZDeDRqMVA1aW9wN29jNEhGeDcxaFhnVkI2WEd0MFJnNkRBNWpEanFodThuWXliaWVEd25QejNCam90SlBxZFVSckJHQWdjVmVICm5mTytvSkFqUFlvazRkb2gyOE1DQXdFQUFhTXpNREV3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFSQmdOVkhRNEVDZ1FJU3FDcVdJVFQKWGp3d0N3WURWUjBQQkFRREFnRUdNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJhem9mNUZuSVZWMHNkMlp2bm9pWXc3Sk5uMzlZdAowalN2OXppbHpxc1d1YXN2ZkRYTHJOQVB0RXdyL0lEdmE0eVJYeloyOTl1ekd4bnE5TElSL1dGeFJMOG9zem9kdjdORDZKKy8zREVJCmNiQ2RqZFkwUnpLUXhtVWs5NkJLZkFSemp6bHZGNHh5dGIxTHlIcjRlNFBES0U2Y0NlcG5QN0puQkJ2REZOcjQ1MGtra2RBZGF2cGgKT2U5cjV5RjFCZ2ZZRXJRaElIQkNjWUhhUEpvMnZxWmJEV3BzbWgrUmUvbjU3MEs2VGs2ZXpBeU5sTnpaUlp4ZTdFSlFZNjcwWGNTeApFdHpLTzZndW5SUmFCWFczN05kajRybzF0Z1FJa2VqYW5aejJaclVZckFxbVZDWTBNOUlid2RSL0dqcU9DNm95YnR2OFR5V2YyVExICmxscHdyTjlNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClhSYW1wIEdsb2JhbCBDQSBSb290Cj09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFTURDQ0F4aWdBd0lCQWdJUVVKUnM3QmpxMVp4TjFaZnZkWStnclRBTkJna3Foa2lHOXcwQkFRVUZBRENCZ2pFTE1Ba0dBMVVFCkJoTUNWVk14SGpBY0JnTlZCQXNURlhkM2R5NTRjbUZ0Y0hObFkzVnlhWFI1TG1OdmJURWtNQ0lHQTFVRUNoTWJXRkpoYlhBZ1UyVmoKZFhKcGRIa2dVMlZ5ZG1salpYTWdTVzVqTVMwd0t3WURWUVFERXlSWVVtRnRjQ0JIYkc5aVlXd2dRMlZ5ZEdsbWFXTmhkR2x2YmlCQgpkWFJvYjNKcGRIa3dIaGNOTURReE1UQXhNVGN4TkRBMFdoY05NelV3TVRBeE1EVXpOekU1V2pDQmdqRUxNQWtHQTFVRUJoTUNWVk14CkhqQWNCZ05WQkFzVEZYZDNkeTU0Y21GdGNITmxZM1Z5YVhSNUxtTnZiVEVrTUNJR0ExVUVDaE1iV0ZKaGJYQWdVMlZqZFhKcGRIa2cKVTJWeWRtbGpaWE1nU1c1ak1TMHdLd1lEVlFRREV5UllVbUZ0Y0NCSGJHOWlZV3dnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcApkSGt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ1lKQjY5RmJTNjM4ZU1wU2UyT0F0cDg3Wk9xQ3d1CklSMWNSTjhoWFg0amRQNWVmclJLdDZhdEg2N2dCaGJpbTF2WlozUnJYWUNQS1oyR0c5bWNEWmh0ZGhBb1dPUmxzSDlLbUhtZjRNTXgKZm9BcnRZekFRRHNSaHRETG9vWTJZS1RWTUlKdDJXN1FEeElFTTVkZlQyRmE4T1Q1a2F2bkhUdTg2TS8wYXkwMGZPSklZUnlPODJGRQp6RytnU3FtVXNFM2E1NmswZW5JNHFFSE1QSlFSZmV2SXBveTNoc3ZLTXp2WlBUZUwrM28raGl6bmM5Y0tWNnhrbXhucjlBOEVDSXFzCkF4Y1paUFJhSlNLTk5DeXk5bWdkRW0zVGloNFUyc1NQcHVJamhkVjZEYjFxNE9uczdCZTdRaHRucWlYdFJZTWgvTUhKZk5WaVB2cnkKeFMzVC9kUmxBZ01CQUFHamdaOHdnWnd3RXdZSkt3WUJCQUdDTnhRQ0JBWWVCQUJEQUVFd0N3WURWUjBQQkFRREFnR0dNQThHQTFVZApFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRk1aUG9qMEdZNFFKbk01aTVBU3NqVnkxNmJZYk1EWUdBMVVkSHdRdk1DMHdLNkFwCm9DZUdKV2gwZEhBNkx5OWpjbXd1ZUhKaGJYQnpaV04xY21sMGVTNWpiMjB2V0VkRFFTNWpjbXd3RUFZSkt3WUJCQUdDTnhVQkJBTUMKQVFFd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFKRVZPUU1CRzJmN1NoejVDbUJib2RwTmwyTDVKRk1uMTRKa1RwQXV3MGtiSzVyYwovS2g0WnpYeEhmQVJ2YmRJNHhEMkRkOC8wc20ycWxXa1NMb0MyOTVaTGhWYk81MFdmVWZYTitwZlRYWVNOcnNmMTZHQkJFWWdveXh0CnFaNEJmajhwemdDVDMvM0prbk9KaVdTZTV5dmtISkVzMHJuT2ZjNXZNWm5UNXI3U0hwRHdDUlI1WENPclRkTGFJUjlObVhtZDRjOG4KbnhDYkhJZ05zSXBrUVRHNERteVFKS1NiWEhHUHVydCtIQnZiYW9BUElienAyNmEzUVBTeWk2bXg1TythR3RBOWFabnVxQ2lqNFR5ego4TElSbk05OFFPYmQ1ME45b3RnNnRhbU44alNaeE5RUTRRYjlDWVFRTys3RVRQVHNKM3hDd25SOGdvb0p5YlFESmJ3PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbyBEYWRkeSBDbGFzcyAyIENBCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVBRENDQXVpZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJqTVFzd0NRWURWUVFHRXdKVlV6RWhNQjhHQTFVRUNoTVkKVkdobElFZHZJRVJoWkdSNUlFZHliM1Z3TENCSmJtTXVNVEV3THdZRFZRUUxFeWhIYnlCRVlXUmtlU0JEYkdGemN5QXlJRU5sY25ScApabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNQjRYRFRBME1EWXlPVEUzTURZeU1Gb1hEVE0wTURZeU9URTNNRFl5TUZvd1l6RUxNQWtHCkExVUVCaE1DVlZNeElUQWZCZ05WQkFvVEdGUm9aU0JIYnlCRVlXUmtlU0JIY205MWNDd2dTVzVqTGpFeE1DOEdBMVVFQ3hNb1IyOGcKUkdGa1pIa2dRMnhoYzNNZ01pQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRDQ0FTQXdEUVlKS29aSWh2Y05BUUVCQlFBRApnZ0VOQURDQ0FRZ0NnZ0VCQU42ZDErcFhHRW1oVyt2WFgwaUc2cjdkLytUdlp4ejBaV2l6VjNHZ1huZTc3WnRKNlhDQVBWWVlZd2h2CjJ2TE0wRDkvQWxRaVZCRFlzb0hVd0hVOVMzL0hkOE0rZUtzYUE3VWdheTlxSzdIRmlIN0V1eDZ3d2RoRkoyK3FOMWozaHliWDJDMzIKcVJlM0gzSTJUcVlYUDJXWWt0c3FibDJpL29qZ0M5NS81WTBWNGV2TE90WGlFcUlUTGRpT3IxOFNQYUFJQlFpMlhLVmxPQVJGbVI2agpZR0IweFVHbGNtSWJZc1VmYjE4YVFyNENVV1dvcmlNWWF2eDRBNmxOZjRERCtxdGEvS0ZBcE1vWkZ2Nnl5TzllY3czdWQ3MmE5bm1ZCnZMRUhaNklWRGQyZ1dNWkVld28rWWloZnVrRUhVMWpQRVg0NGRNWDQvN1Zwa0krRWRPcVhHNjhDQVFPamdjQXdnYjB3SFFZRFZSME8KQkJZRUZOTEVzTktSMUV3UmNiTmh5ejJoL3Qyb2F0VGpNSUdOQmdOVkhTTUVnWVV3Z1lLQUZOTEVzTktSMUV3UmNiTmh5ejJoL3QybwphdFRqb1dla1pUQmpNUXN3Q1FZRFZRUUdFd0pWVXpFaE1COEdBMVVFQ2hNWVZHaGxJRWR2SUVSaFpHUjVJRWR5YjNWd0xDQkpibU11Ck1URXdMd1lEVlFRTEV5aEhieUJFWVdSa2VTQkRiR0Z6Y3lBeUlFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1Z2dFQU1Bd0cKQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFESkw4N0xLUHBIOEVzYWhCNHlPZDZBekJoUmNrQjRZOXdpbQpQUW9aK1llQUVXNXA1SllYTVA4MGtXTnlPTzdNSEFHakhaUW9wREgyZXNSVTEvYmxNVmdEb3N6T1l0dVVSWE8xdjBYSkpMWFZnZ0t0CkkzbHBqYmkyVGM3UFRNb3pJK2djaUtxZGkwRnVGc2tnNVltZXpUdmFjUGQrbVNZZ0ZGUWxxMjV6aGVhYklaMEtiSUlPcVBqQ0RQb1EKSG15Vzc0Y054QTloaTYzdWd5dVYrSTZTaEhJNTZ5RHFnKzJEelpkdUNMenJUaWEyY3l2azAvWk0vaVp4NG1FUmRFci9WeHFIRDNWSQpMczlSYVJlZ0FoSmhsZFhSUUxJUVRPN0VyQkJEcHFXZUN0V1ZZcG9OejRpQ3hUSU01Q3VmUmVZTm55aWNzYmtxV2xldE53K3ZIWC9iCnZaOD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU3RhcmZpZWxkIENsYXNzIDIgQ0EKPT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVEekNDQXZlZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJvTVFzd0NRWURWUVFHRXdKVlV6RWxNQ01HQTFVRUNoTWMKVTNSaGNtWnBaV3hrSUZSbFkyaHViMnh2WjJsbGN5d2dTVzVqTGpFeU1EQUdBMVVFQ3hNcFUzUmhjbVpwWld4a0lFTnNZWE56SURJZwpRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrd0hoY05NRFF3TmpJNU1UY3pPVEUyV2hjTk16UXdOakk1TVRjek9URTJXakJvCk1Rc3dDUVlEVlFRR0V3SlZVekVsTUNNR0ExVUVDaE1jVTNSaGNtWnBaV3hrSUZSbFkyaHViMnh2WjJsbGN5d2dTVzVqTGpFeU1EQUcKQTFVRUN4TXBVM1JoY21acFpXeGtJRU5zWVhOeklESWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrd2dnRWdNQTBHQ1NxRwpTSWIzRFFFQkFRVUFBNElCRFFBd2dnRUlBb0lCQVFDM01zais2WEdtQklXdERCRmszODVONzhnREdJYy9vYXY3UEthZjhNT2gydFRZCmJpdFRrUHNrcEQ2RThKN29YK3psSjBUMUtLWS9lOTdnS3ZESXIxTXZuc29GQVpNZWoyWWNPYWROK2xxMmN3UWxadXQzZitkWnhrcVoKSlJSVTZ5Ykg4MzhaMVRCd2o2K3dSaXIvcmVzcDdkZWZxZ1NIbzlUNWlhVTBYOXREa1lJMjJXWThzYmk1Z3YyY09qNFF5RHZ2Qm1WbQplcHNaR0QzL2NWRThNQzVmdmoxM2M3SmRCbXpESTFhYUs0VW1raHluQXJQa1B3MnZDSG1DdURZOTZwelROYk84YWNyMXpKM28vV1NOCkY0QXpibDVLWFpuSkhvZTBuUnJBMVc0VE5TTmUzNXRmUGUvVzkzYkM2ajY3ZUEwY1FtZHJCTmo0MXRwdmkvSkVvQUdyQWdFRG80SEYKTUlIQ01CMEdBMVVkRGdRV0JCUy9YN2ZSenQwZmh2UmJWYXpjMXhEQ0RxbUk1ekNCa2dZRFZSMGpCSUdLTUlHSGdCUy9YN2ZSenQwZgpodlJiVmF6YzF4RENEcW1JNTZGc3BHb3dhREVMTUFrR0ExVUVCaE1DVlZNeEpUQWpCZ05WQkFvVEhGTjBZWEptYVdWc1pDQlVaV05vCmJtOXNiMmRwWlhNc0lFbHVZeTR4TWpBd0JnTlZCQXNUS1ZOMFlYSm1hV1ZzWkNCRGJHRnpjeUF5SUVObGNuUnBabWxqWVhScGIyNGcKUVhWMGFHOXlhWFI1Z2dFQU1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUFXZFA0aWQwY2thVmFHcwphZlB6V2RxYkFZY2FUMWVwb1hrSkt0djNMN0llek1kZWF0aURoNkdYNzBrMVBuY0dRVmhpdjQ1WXVBcG5QK3l6M1NGbUg4bFUrbkxNClBVeEEySUd2ZDU2RGVydWl4L1UwRjQ3WkVVRDAvQ3dxVFJWL3AySmRMaVhUQUFzZ0doMW8rUmU0OUwyTDdTaFozVTBXaXhlRHlMSmwKeHkxNnBhcThVNFp0M1Zla3l2Z2dRUXRvOFBUN2RMNVdYWHA1OWZrZGhlTXRsYjcxY1pCRHpJMGZtZ0FLaHlucFZTSllBQ1BxNHhKRApLVnRIQ04yTVFXcGxCcWpsSWFwQnRKVWhsYmw5MFRTckU5YXR2TnppUFRuTnZUNTFjS0VZV1FQSklyU1BuTlZlS3RlbHR0UUtiZmkzClFCRkdtaDk1RG1LL0Q1ZnM0QzhmRjVRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdHpDQ0FwK2dBd0lCQWdJUURPZmc1UmZZUnY2UDVXRDhHL0F3T1RBTkJna3Foa2lHOXcwQkFRVUZBREJsTVFzd0NRWURWUVFHCkV3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXcKSWdZRFZRUURFeHRFYVdkcFEyVnlkQ0JCYzNOMWNtVmtJRWxFSUZKdmIzUWdRMEV3SGhjTk1EWXhNVEV3TURBd01EQXdXaGNOTXpFeApNVEV3TURBd01EQXdXakJsTVFzd0NRWURWUVFHRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMCkV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TUXdJZ1lEVlFRREV4dEVhV2RwUTJWeWRDQkJjM04xY21Wa0lFbEVJRkp2YjNRZ1EwRXcKZ2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3REaFhPNUVPQVhMR0g4N2RnK1hFU3BhN2NKcFNJcXZUTwo5U0E1S0ZoZ0RQaUEycWtWbFRKaFBMV3hLSVNLaXR5ZkNneURGM3FQa0t5SzUzbFRYREdFS3ZZUG1ESTJkc3plM1R5b291OXEreUh5ClVtSGZueURYSCtLeDJmNFlaTklTVzEvNVdCZzF2RWZOb1RiNWEzL1VzRGcrd1J2RGpEUFoyQzhZL2lnUHM2ZUQxc051Uk1CaE5aWVcKL2xtY2kzWnQxL0dpU3cwci93dHkycDVnMEk2UU5jWjRWWWNnb2MvbGJRcklTWHd4bUROc0l1bUgwREphb3JvVGdoSHRPUmVkbVRweQpvZWI2cE5uVkZ6RjFyb1Y5SXE0L0FVYUc5aWg1eUxIYTVGY1h4SDRjRHJDMGtxWldzNzJ5bCsycXAvQzN4YWcvbFJiUS82R1c2d2hmCkdIZFBBZ01CQUFHall6QmhNQTRHQTFVZER3RUIvd1FFQXdJQmhqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUkYKNjZLdjlKTExnakV0VVl1bnB5R2Q4MjNJRHpBZkJnTlZIU01FR0RBV2dCUkY2Nkt2OUpMTGdqRXRVWXVucHlHZDgyM0lEekFOQmdrcQpoa2lHOXcwQkFRVUZBQU9DQVFFQW9nNjgzK0x0OE9OeWMzcGtsTC8zY21iWU11UkNkV0t1aCt2eTFkbmVWck9mek00VUtMa05sMkJjCkVreFk1Tk05ZzBsRldKYzFhUnFvUitwV3hubXJFdGhuZ1lUZmZ3azhsT2E0Sml3Z3ZUMnpLSW4zWC84aTRwZUVIK2xsNzRmZzM4Rm4KU2JOZDY3SUpLdXNtN1hpK2ZUOHI4N2NtTlcxZmlRRzJTVnVmQVFXYnF6MGx3Y3kyZjhMeGI0YkcrbVJvNjRFdGxPdEN0L3FNSHQxaQo4YjVRWjdkc3ZmUHhIMnNNTmdjV2Z6ZDhxVnR0ZXZFU1JtQ0QxeWNFdmt2T2w3N0RaeXBvRWQrQTV3d3pacjhURFJSdTgzOGZZeEFlCitvMGJKVzFzajZXM1lRR3gwcU1tb1JCeG5hM2l3L25EbVZHM0t3Y0l6aTdtVUxLbitncEZMNkx3OGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRHJ6Q0NBcGVnQXdJQkFnSVFDRHZnVnBCQ1JyR2hkV3JKV1pISFNqQU5CZ2txaGtpRzl3MEJBUVVGQURCaE1Rc3dDUVlEVlFRRwpFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU0F3CkhnWURWUVFERXhkRWFXZHBRMlZ5ZENCSGJHOWlZV3dnVW05dmRDQkRRVEFlRncwd05qRXhNVEF3TURBd01EQmFGdzB6TVRFeE1UQXcKTURBd01EQmFNR0V4Q3pBSkJnTlZCQVlUQWxWVE1SVXdFd1lEVlFRS0V3eEVhV2RwUTJWeWRDQkpibU14R1RBWEJnTlZCQXNURUhkMwpkeTVrYVdkcFkyVnlkQzVqYjIweElEQWVCZ05WQkFNVEYwUnBaMmxEWlhKMElFZHNiMkpoYkNCU2IyOTBJRU5CTUlJQklqQU5CZ2txCmhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNGp2aEVYTGVxS1RUbzFlcVVLS1BDM2VReWFLbDdoTE9sbHNCQ1NETUFaT24KVGpDM1UvZER4R2tBVjUzaWpTTGRod1pBQUlFSnpzNGJnNy9melR0eFJ1TFdac2NGczNZbkZvOTduaDZWZmU2M1NLTUkydGF2ZWd3NQpCbVYvU2wwZnZCZjRxNzd1S05kMGYzcDRtVm1GYUc1Y0l6Skx2MDdBNkZwdDQzQy9keEMvL0FIMmhkbW9SQkJZTXFsMUdOWFJvcjVICjRpZHE5Sm96K0VrSVlJdlVYN1E2aEwraHFrcE1mVDdQVDE5c2RsNmdTemVSbnR3aTVtM09GQnFPYXN2K3piTVVaQmZIV3ltZU1yL3kKN3ZyVEMwTFVxN2RCTXRvTTFPLzRnZFc3alZnL3RSdm9TU2lpY05veEJOMzNzaGJ5VEFwT0I2anRTajFldFgramtNT3ZKd0lEQVFBQgpvMk13WVRBT0JnTlZIUThCQWY4RUJBTUNBWVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVQTk1UU5WYlJUTHRtCjhLUGlHeHZEbDdJOTBWVXdId1lEVlIwakJCZ3dGb0FVQTk1UU5WYlJUTHRtOEtQaUd4dkRsN0k5MFZVd0RRWUpLb1pJaHZjTkFRRUYKQlFBRGdnRUJBTXVjTjZwSUV4SUsrdDFFbkU5U3NQVGZyZ1QxZVhrSW95UVkvRXNyaE1BdHVkWEgvdlRCSDFqTHVHMmNlblRubUNtcgpFYlhqY0tDaHpVeUltWk9Na1hEaXF3OGN2cE9wLzJQVjVBZGcwNk8vblZzSjhkV080MVAwam1QNlA2ZmJ0R2JmWW1iVzBXNUJqZkl0CnRlcDNTcCtkV09JcldjQkFJKzB0S0lKRlBubFVraWFZNElCSXFEZnY4Tlo1WUJiZXJPZ096VzZzUkJjNEwwbmE0VVUrS3JrMlU4ODYKVUFiM0x1akVWMGxzWVNFWTFRU3RlRHdzT29CcnArdXZGUlRwMkluQnVUaHM0cEZzaXY5a3VYY2xWekRBR3lTajRkenAzMGQ4dGJRawpDQVV3N0MyOUM3OUZ2MUM1cWZQcm1BRVNyY2lJeHBnMFg0MEtQTWJwMVpXVmJkND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEeFRDQ0FxMmdBd0lCQWdJUUFxeGNKbW9MUUp1UEMzbnlya1lsZHpBTkJna3Foa2lHOXcwQkFRVUZBREJzTVFzd0NRWURWUVFHCkV3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1Tc3cKS1FZRFZRUURFeUpFYVdkcFEyVnlkQ0JJYVdkb0lFRnpjM1Z5WVc1alpTQkZWaUJTYjI5MElFTkJNQjRYRFRBMk1URXhNREF3TURBdwpNRm9YRFRNeE1URXhNREF3TURBd01Gb3diREVMTUFrR0ExVUVCaE1DVlZNeEZUQVRCZ05WQkFvVERFUnBaMmxEWlhKMElFbHVZekVaCk1CY0dBMVVFQ3hNUWQzZDNMbVJwWjJsalpYSjBMbU52YlRFck1Da0dBMVVFQXhNaVJHbG5hVU5sY25RZ1NHbG5hQ0JCYzNOMWNtRnUKWTJVZ1JWWWdVbTl2ZENCRFFUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1iTTVYUG0rOVM3NVMwdApNcWJmNVlFL3ljMGxTYlp4S3NQVmxEUm5vZ29jc0Y5cHBrQ3h4TGV5ajlDWXBLbEJXVHJUM0pUV1BOdDBPS1JLekUwbGd2ZEtwVk1TCk9PN3pTVzF4a1g1anRxdW1YOE9raFBoUFlsRysrTVhzMnppUzR3YmxDSkVNeENoQlZmdkxXb2tWZm5Ib05iOU5jZ2s5dmpvNFVGdDMKTVJ1TnM4Y2tSWnFuckcwQUZGb0V0N29UNjFFS21FRkJJazVsWVllQlFWQ21lVnlKM2hsS1Y5VXU1bDBjVXl4K21NMGFCaGFrYUhQUQpOQVFUWEtGeDAxcDhWZHRlWk9FM2h6QldCT1VSdENtQUV2RjVPWWlpQWhGOEoyYTNpTGQ0OHNvS3FEaXJDbVRDdjJaZGxZVEJvU1VlCmgxMGFVQXNnRXN4QnUyNExVVGk0UzhzQ0F3RUFBYU5qTUdFd0RnWURWUjBQQVFIL0JBUURBZ0dHTUE4R0ExVWRFd0VCL3dRRk1BTUIKQWY4d0hRWURWUjBPQkJZRUZMRSt3MmtEK0w5SEFkU1lKaG9JQXU5alpDdkRNQjhHQTFVZEl3UVlNQmFBRkxFK3cya0QrTDlIQWRTWQpKaG9JQXU5alpDdkRNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUFjR2dhWDNOZWNuenlJWmdZSVZ5SGJJVWY0S21lcXZ4Z3lka0FRClY4R0s4M3JaRVdXT05mcWUvRVcxbnRsTU1VdTRrZWhETEk2emVNN2I0MU41Y2RibElaUUIybFdIbWlSazlvcG16TjZjTjgyb05MRnAKbXlQSW5uZ2lLM0JENDFWSE1XRVo3MWpGaFM5T01QYWdNUllqeU9maVpSWXp5NzhhRzZBOStNcGVpekdMWUFpSkxRd0dYRkszeFBrSwptTkVWWDU4U3ZudzJZemk5UktSLzVDWXJDc1NYYVEzcGpPTEFFRmU0eUhZU2tWWHlTR25ZdkNvQ1d3OUUxQ0F4Mi9TNmNDWmRrR0NlCnZFc1hDUysweXg1RGFNa0hKOEhTWFBmcUlibG9FcHc4bkwrZS9JQmNtMlBON0VlcUpTZG5vRGZ6QUlKOVZOZXArT2t1RTZOMzZCOUsKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRFNUIFJvb3QgQ0EgWDMKPT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURTakNDQWpLZ0F3SUJBZ0lRUksrd2dOYWpKN3FKTURtR0x2aEFhekFOQmdrcWhraUc5dzBCQVFVRkFEQS9NU1F3SWdZRFZRUUsKRXh0RWFXZHBkR0ZzSUZOcFoyNWhkSFZ5WlNCVWNuVnpkQ0JEYnk0eEZ6QVZCZ05WQkFNVERrUlRWQ0JTYjI5MElFTkJJRmd6TUI0WApEVEF3TURrek1ESXhNVEl4T1ZvWERUSXhNRGt6TURFME1ERXhOVm93UHpFa01DSUdBMVVFQ2hNYlJHbG5hWFJoYkNCVGFXZHVZWFIxCmNtVWdWSEoxYzNRZ1EyOHVNUmN3RlFZRFZRUURFdzVFVTFRZ1VtOXZkQ0JEUVNCWU16Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQUQKZ2dFUEFEQ0NBUW9DZ2dFQkFOK3Y2WmRRQ0lOWHRNeGlaZmFRZ3V6SDB5eHJNTXBiN05uRGZjZEF3UmdVaStEb00zWkpLdU0vSVVtVApyRTRPcno1SXkyWHUvTk1oRDJYU0t0a3lqNHpsOTNld0VudTFsY0NKbzZtNjdYTXVlZ3dHTW9PaWZvb1VNTTBSb09FcU9MbDVDakg5ClVMMkFaZCszVVdPRHlPS0lZZXBMWVlIc1VtdTVvdUpMR2lpZlNLT2VETm9Kamo0WExoN2RJTjlieGlxS3F5NjljSzNGQ3hvbGtIUnkKeFh0cXF6VFdNSW4vNVdnVGUxUUx5TmF1N0ZxY2toNDlaTE9NeHQrL3lVRnc3Qlp5MVNic09GVTVROUQ4L1JoY1FQR1g2OVdhbTQwZAp1dG9sdWNiWTM4RVZBanFyMm03eFBpNzFYQWljUE5hRGFlUVFteGtxdGlsWDQrVTltNS93QWwwQ0F3RUFBYU5DTUVBd0R3WURWUjBUCkFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZNU25zYVI3TEhINjIrRkxrSFgveEJWZ2hZa1EKTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFDakdpeWJGd0JjcVI3dUtHWTNPcitEeHo5THd3bWdsU0JkNDlsWlJOSStEVDY5aWt1ZwpkQi9PRUlLY2RCb2RmcGdhM2NzVFM3TWdST1NSNmN6OGZhWGJhdVgrNXYzZ1R0MjNBRHExY0Vtdjh1WHJBdkhSQW9zWnk1UTZYa2pFCkdCNVlHVjhlQWxyd0RQR3hyYW5jV1lhTGJ1bVI5WWJLK3JsbU02cFpXODdpcHhaelI4c3J6Sm13TjBqUDQxWkw5YzhQREhJeWg4YncKUkx0VGNtMUQ5U1pJbWxKbnQxaXIvbWQyY1hqYkRhSldGQk01SkRHRm9xZ0NXakJINGQxUUI3d0NDWkFBNjJSallKc1d2SWpKRXViUwpmWkdMK1QweWpXVzA2WHl4VjNicXhiWW9PYjhWWlJ6STluZVdhZ3FOZHd2WWtRc0VqZ2ZiS2JZSzdwMkNOVFVRCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN3aXNzU2lnbiBHb2xkIENBIC0gRzIKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRnVqQ0NBNktnQXdJQkFnSUpBTHRBSEVQMVhrK3dNQTBHQ1NxR1NJYjNEUUVCQlFVQU1FVXhDekFKQmdOVkJBWVRBa05JTVJVdwpFd1lEVlFRS0V3eFRkMmx6YzFOcFoyNGdRVWN4SHpBZEJnTlZCQU1URmxOM2FYTnpVMmxuYmlCSGIyeGtJRU5CSUMwZ1J6SXdIaGNOCk1EWXhNREkxTURnek1ETTFXaGNOTXpZeE1ESTFNRGd6TURNMVdqQkZNUXN3Q1FZRFZRUUdFd0pEU0RFVk1CTUdBMVVFQ2hNTVUzZHAKYzNOVGFXZHVJRUZITVI4d0hRWURWUVFERXhaVGQybHpjMU5wWjI0Z1IyOXNaQ0JEUVNBdElFY3lNSUlDSWpBTkJna3Foa2lHOXcwQgpBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFyK1R1Zm9za0RoSnVxVkF0RmtRN2twSmN5cmhkaEpKQ0V5cThaVmVDUUQ1WEpNMVFpeVVxCnQyLzg3NkxRd0I4Q0pFb1RsbzhqRStZb1dBQ2pSOGNHcDRRaks3dTlsaXQvVmN5THdWY2ZEbUpsRDkwOVZvcHoycTUrYmJxQkhINUMKakNBMTJVTk5oUHFFMjFJczh3NG5kd3RydnhFdmNuaWZMdGcrNWhnM1dpcHkrZHBpa0pLVnloK2M2Yk04Szh2ekFSTy9Xcy9CdFFwZwp2ZDIxbVdSVHVLQ1dzMi9pSm5lUmpPQmlFQUtmTkErazFaSXpVZDYramJxRWVtQThhdHVmSyt6ZTNnRS9iazNsVUliTHRLL3RSRURGCnlscU0ydElyZktqdXZxYmxDcW9PcGQ4RlVyZFZ4eUpkTW1xWGwyTVQyOG5iZVRaN2hUcEt4VktKK1NUbm5YZXBndjlWSEtWeGFTdlIKQWlUeXN5YlVhOW9FVmVYQkNzZHRNRGVRS3VTZUZETmVGaGRWeFZ1MXl6U0prdkdkSm8raEI5VEdzbmhRMnd3TUMzd0xqRUhYdWVuZApqSWozbzAyeU1zellGOXJOdDg1bW5kVDlYdis5bHo0cGRlZCtwMkpZcnlVMHBVSEhQYndOVU1vREF3OElXaCtWYzNoaXY2OXlGR2tPCnBlVUREbmlPSmloQzhBY0xZaUFRWnpsRytxa0R6QVE0ZW1idklJTzFqRXBXanBFQS9JNWNndDZJb01QaWFHNTlqZTg4M1dYMFhheFIKN3lTQXJxcFdsMi81clgzYVlUK1lkenlsa2JZY2pDYmFaYUlKYmNIaVZPTzV5a3hNZ0k5M2UyQ2FIdCsyOGtnZURycE9WRzJZNE9HaQpHcUozVU0vRVk1THNSeG1kNitacnpzRUNBd0VBQWFPQnJEQ0JxVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3CkF3RUIvekFkQmdOVkhRNEVGZ1FVV3lWN2xxUmxVWDY0T2ZQQWVHWmU2RHJuOE80d0h3WURWUjBqQkJnd0ZvQVVXeVY3bHFSbFVYNjQKT2ZQQWVHWmU2RHJuOE80d1JnWURWUjBnQkQ4d1BUQTdCZ2xnaFhRQldRRUNBUUV3TGpBc0JnZ3JCZ0VGQlFjQ0FSWWdhSFIwY0RvdgpMM0psY0c5emFYUnZjbmt1YzNkcGMzTnphV2R1TG1OdmJTOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnSUJBQ2U2NDVSODhhN0EzaGZtCjVkalY5VlN3Zy9TN3pWNEZlMCtmZFdhdlBPaFdmdnh5ZURnRDJTdGlHd0M1K09sZ3pjek9VWXJIVURGdTRVcCtHQzlwV2JZOVpJRXIKNDRPRTVpS0hqbjNnN2dLWlliZ2U5TGdyaUJJV2hNSXhremlXTWFhNU8xTS93eVNUVmx0cGt1ekZ3YnM0QU9Qc0Y2bTQzTWQ4QVlPZgpNa2U2VWlJMEhUSjZDVmFuZkNVMnFUMUwyc0NDYndxN0VzaUhTeWNSK1I0dHg1TS9udHRmSm10UzJTNks4UlRHUkkwVnFiZS92ZDZtCkd1NnVMZnRJZHhmK3UreXZHUFVxVWZBNWhKZVZiRzRid3l2RWRHQjVKYkFLSjkvZlh0STV6MFY5UWt2ZnN5d2V4Y1pkeWxVNm9KeHAKbW8vYTc3S3dQSitIYkJJclpYQVZVakVhSk05dk1TTlFINHhQanlQRGRFRmpIRldvRk4wKzRGRlF6L0ViTUZZT2tyQ0NoZGlEeXlKawp2QzI0SmRWVW9yZ0c2cTJTcENTZ3dZYTFTaE5xUjg4dUMxYVZWTXZPbXR0cXRLYXkyMEVJaGlkMzkycWdRbXdMT003WGRWQXlrc0xmCkt6QWlTTkRWUVRnbFhhVHBYWi9HbEhYUVJmMHdsME9Qa0tzS3g0WnpZRXBwTGQ2bGVOY0cybXFlU3o1M09pQVRJZ0hRdjJpZVkyQnIKTlUwTGJicWhQY0NUNEg4anMxV3RjaVZPUnZuU0Z1K3daTUVCbnVuS29HcVlEcy9ZWVBJdlNiamtRdUU0TlJiMHlHNVA5NEZXNkxxagp2aU92cnYxdkErQUNPekIyK2h0dFFjOEJzZW00eVdiMDJ5YnpPcVIwOGtra1c4bXcwRmZCK2o1NjRaZkoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyCj09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRnZUQ0NBNldnQXdJQkFnSUlUeHZVTDFTN0wwc3dEUVlKS29aSWh2Y05BUUVGQlFBd1J6RUxNQWtHQTFVRUJoTUNRMGd4RlRBVApCZ05WQkFvVERGTjNhWE56VTJsbmJpQkJSekVoTUI4R0ExVUVBeE1ZVTNkcGMzTlRhV2R1SUZOcGJIWmxjaUJEUVNBdElFY3lNQjRYCkRUQTJNVEF5TlRBNE16STBObG9YRFRNMk1UQXlOVEE0TXpJME5sb3dSekVMTUFrR0ExVUVCaE1DUTBneEZUQVRCZ05WQkFvVERGTjMKYVhOelUybG5iaUJCUnpFaE1COEdBMVVFQXhNWVUzZHBjM05UYVdkdUlGTnBiSFpsY2lCRFFTQXRJRWN5TUlJQ0lqQU5CZ2txaGtpRwo5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBeFBHSGY5TjRNZmM0eWZqRG1VTzh4L2U4TitkT2NicExqNlZ6SFZ4dW1LNERWNjQ0Ck4wTXZGejBmeU01b0VNRjRyaGtES3hENkxIbUQ5dWk1YUxsVjhnUkVwem41L0FTTEh2R2lUU2Y1WVh1NnQrV2lFN2JyWVQ3UWJOSG0KKy9wZTdSMjBucUExVzZHU3kvQkprdjZGQ2dVKzV0a0w0ays3M0pVMy9KSHBNalVpMFI4NlRpZUZuYkFWbERMYVlRMUhUV0JDcnBKSAo2SU5hVUZqcGlvdTVYYUhjM1psS0h6Wm51MGprZzdZMzYwZzZydzluanhjSDZBVEs3Mm94aDlUQXR2bVVjWHRuWkxpMmtVcENlMlV1Ck1Hb005WkR1bGVieXpZTHMyYUZLN1BheVMrVkZoZVp0ZUpNRUxweUNiVGFweERGa0g0YURDeXIwTlFwNHlWWFBRYkJINlRDZm1iNWgKcUFhRXVTaDZYempaRzZrNHNJTi9jOEhETzBncWdnOGhtN2pNcURYRGhCdURzejYrcEpWcEFUcUpBSGdFMmNuMG1SbXJWbjViaTRZNQpGWkdrRUN3Sk1vQmdzNVBBS3JZWUM1MStqVW55RUVwLytkVkdMeG1TbzVtbkpxeTdqRHptRHJ4SEI5eHpVZkZ3WkM4SStiUkhIVEJzClJPb3BONFdTYUdhOGd6aitlemt1MDFEd0gvdGVZTGFwcHZvblFmR2JHSEx5OVlSMFNzbG54RlN1U0dUZmpORnVzQjNoQjQ4SUhwbWMKY2VsTTJLWDNSeElmZE5GUm5vYnp3cUlqUUF0ejIwdW01M01Hak1HZzZjRlpyRWI2NWkvNHozR2NSbTI1eEJXTk9Ia0RSVWp2eEYzWApDTzZIT1NLR3NnMFBXRVAzY2FsSUx2M3ExaDhDQXdFQUFhT0JyRENCcVRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvCkJBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUY2RE53ZVJCdGpwYk84dEZuYjBjd3BqNmhsZ3dId1lEVlIwakJCZ3dGb0FVRjZETndlUkIKdGpwYk84dEZuYjBjd3BqNmhsZ3dSZ1lEVlIwZ0JEOHdQVEE3QmdsZ2hYUUJXUUVEQVFFd0xqQXNCZ2dyQmdFRkJRY0NBUllnYUhSMApjRG92TDNKbGNHOXphWFJ2Y25rdWMzZHBjM056YVdkdUxtTnZiUzh3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUhQR2dlQW4waTBQCjRKVXc0cHBCZjFBc1gxOWlZYW1HYW1rWURIUkoxbDJFNmtGU0dHOVlyVkJXSUdyR3ZTaHBXSkhja1JFMXFUb2R2QnFsWUo3WUgzOUYKa1duWmZydDRjc0VHRHlyT2o0VndZYXlnelF1NE9TbFdoREpPaHJzOXhDcloxeDl5N3Y1Um9TSkJzWEVDWXhxQ3NHS3JYbGNTSDkvTAozWFdnd0YxNWtJd2I0RkRtM2pIK21IdHdYNldRMkszNEFyWnYwMkRkUUVzaXhUMnRPbnFmR2hwSGtYa3p1b0xjTW1rRGxtNGZTL0J4Ci91Tm5jcUN4djF5TDVQcVpJc2VFdVJ1Tkk1Yy83U1hnejJXNzlXRUU3OTBlc2xwQklscWhuMTBzNkZ2SmJha01ESGlxWU1aV2p3RmEKREdpOGFSbDV4QjkrbHdXL3hla2tVVjdVMVV0VDdka2pXallEWmFQQkE2MUJNUE5HRzRXUXIyVzExYkhrRmx0NGRSMlhlbTFacVNxUAplOTdEaDRrUW1VbHplTWc5dlZFMWRDclY4WDVwR3lxN083MGx1SnBhUFhKaGtHYUg3Z3pXVGRRUmRBdHEvZ3NEL0tOVlY0bitTc3V1Cld4Y0Z5UEtOSXpGVE9OSXRhaitDdVkwSWF2ZGVRWFJ1d3hGK0I2d3BZSkUvT01wWEVBMjlNQy9IcGVaQm9OcXVCWWVhb0tSbGJFd0oKREltNnVOTzV3Sk9LTVBxTjVacHJGUUZPWjZyYVlsWStoQWhtMHNRMmZhYytFUHlJNE5TQTVRQzlxdk5PQnFONmF2bGljdU1KVCt1YgpEZ0VqOForN2ZOemNiQkdYSmJMeXRHTVUwZ1lxWjR5RDljN3FCOWlhYWg3czVBcTdLa3pyQ1dBNXpzcGkyQzV1Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNlY3VyZVRydXN0IENBCj09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEdURDQ0FxQ2dBd0lCQWdJUURQQ09YQWdXcGExQ2YvRHJKeGhaMERBTkJna3Foa2lHOXcwQkFRVUZBREJJTVFzd0NRWURWUVFHCkV3SlZVekVnTUI0R0ExVUVDaE1YVTJWamRYSmxWSEoxYzNRZ1EyOXljRzl5WVhScGIyNHhGekFWQmdOVkJBTVREbE5sWTNWeVpWUnkKZFhOMElFTkJNQjRYRFRBMk1URXdOekU1TXpFeE9Gb1hEVEk1TVRJek1URTVOREExTlZvd1NERUxNQWtHQTFVRUJoTUNWVk14SURBZQpCZ05WQkFvVEYxTmxZM1Z5WlZSeWRYTjBJRU52Y25CdmNtRjBhVzl1TVJjd0ZRWURWUVFERXc1VFpXTjFjbVZVY25WemRDQkRRVENDCkFTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS3VrZ2VXVnpmWDJGSTdDVDhyVTRuaVZXSnhCNFEyWlFDUVgKT1pFelp1bSs0WU92WWx5SjBmd2tXMkd6NEJFUlFSd2RidkM0dS9qZXA0RzZwa2pHbngyOXZvNnBRVDY0bE8wcEd0U08wZ01kQSs5dApEV2NjVjljR3Jjckk5ZjRPcjJZbFNBU1dDMTJqdWhiRENFL1JSdmdVWFBMSVhnR1piZjJJeklhb3dXOHhRbXhTUG1qTDh4azAzN3VICkdGYUFKc1RRM01CdjM5Nmd3cEVXb0dRUlMwUzhIdmJuK21QZVpxeDJwSEdqN0RhVWFIcDNwTEhuRGkrQmV1SzFjb2J2b211TDhBL2IKMDFrL3VuSzhSQ1NjNDNPejk2OVhMMEltbmFsMHVnQlM4a3ZOVTN4SEN6YUZEbWFwQ0pjV05GZkJadmVBNCsxd1ZNZVQ0QzRvRlZtSAp1cnNDQXdFQUFhT0JuVENCbWpBVEJna3JCZ0VFQVlJM0ZBSUVCaDRFQUVNQVFUQUxCZ05WSFE4RUJBTUNBWVl3RHdZRFZSMFRBUUgvCkJBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVVFqSzJGdm9FL2Y1ZFMzckQvZmRNUUIxYVE2OHdOQVlEVlIwZkJDMHdLekFwb0NlZ0pZWWoKYUhSMGNEb3ZMMk55YkM1elpXTjFjbVYwY25WemRDNWpiMjB2VTFSRFFTNWpjbXd3RUFZSkt3WUJCQUdDTnhVQkJBTUNBUUF3RFFZSgpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFERHRUMHJoV0RwU2NsdTFwcU5sR0thN1VUdDM2WjNxMDU5YzRFVmxldzNLVytKd1VMS1VCUlN1ClNjZU5RUWNTYzVSK0RDTWgvYndRZjJBUVduTDFtQTZzN0xsLzNYcHZYZE1jOVArSUJXbENxUVZ4eUxlc0p1Z3V0SXhxLzNIY3VMSGYKbWJ4OElWUXI1RmlpdTFjcHJwNnBveGttRDVrdUNMRHYvV25QbVJvSmplT25ueXZKTmpSN0pMTjRUSlVYcEFZbUhyWmtValpmWUdmWgpuTVVGZEF2blp5UFNDUHlJNmE2TGYrRXc5RGQrL2NZeTJpMmVSREF3Yk80SDN0STAvTkwvUVBaTDlHWkdCbFNtOGpJS1l5WXdhNXZSCjNJdEh1dUc1MVdMUW9xRDBad1Y0S1dNYWJ3VFcrTVpNbzVxeE43U041U2hMSFo0c3dyaG92TzBDN2pFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTZWN1cmUgR2xvYmFsIENBCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2RENDQXFTZ0F3SUJBZ0lRQjFZaXBPalVpb2xOOUJQSThQanFwVEFOQmdrcWhraUc5dzBCQVFVRkFEQktNUXN3Q1FZRFZRUUcKRXdKVlV6RWdNQjRHQTFVRUNoTVhVMlZqZFhKbFZISjFjM1FnUTI5eWNHOXlZWFJwYjI0eEdUQVhCZ05WQkFNVEVGTmxZM1Z5WlNCSApiRzlpWVd3Z1EwRXdIaGNOTURZeE1UQTNNVGswTWpJNFdoY05Namt4TWpNeE1UazFNakEyV2pCS01Rc3dDUVlEVlFRR0V3SlZVekVnCk1CNEdBMVVFQ2hNWFUyVmpkWEpsVkhKMWMzUWdRMjl5Y0c5eVlYUnBiMjR4R1RBWEJnTlZCQU1URUZObFkzVnlaU0JIYkc5aVlXd2cKUTBFd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN2TlM3WXJHeFZhUVp4NVJOb0pMTlAyTXdoUi9qeApZRGlKaVFQcHZlcGVSbE1KM0Z6MVd1ajNSU29DNnpGaDF5a3pUTTdIZkFvM2ZnKzZNcGpoSFpldmo4ZmN5VGlXODlzYS9GSHRhTWJRCmJxUjhKTkd1UXNpV1VHTXU0UDUxL3Bpblgwa3VsZU01TTJTT0hxUmZrTkpuUExMWi9rRzVWYWNKam5JRkhvdmRSSVdDUXRCSndCMWcKOE5FWExKWHI5cVhCa3FQRndxY0lZQTFnQkJDV2VaNFdOT2FwdHZvbFJUbklIbVg1ay9XcThWTGNtWmc5cFlZYUREVXora3VsQkFZVgpIREdBNzZvWWE4SjcxOXJPK1RNZzFmVzlhak10Z1FUN3NGelVuS1BpWEIzanFVSjFYbnZVZCs4NVZMckpDaGdiRXBsSkw0aEwvVkJpCjBYUG5qM3BEQWdNQkFBR2pnWjB3Z1pvd0V3WUpLd1lCQkFHQ054UUNCQVllQkFCREFFRXdDd1lEVlIwUEJBUURBZ0dHTUE4R0ExVWQKRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZLOUVCTUpCZmtpRDIwNDVBdXpzaEhybXpzbWtNRFFHQTFVZEh3UXRNQ3N3S2FBbgpvQ1dHSTJoMGRIQTZMeTlqY213dWMyVmpkWEpsZEhKMWMzUXVZMjl0TDFOSFEwRXVZM0pzTUJBR0NTc0dBUVFCZ2pjVkFRUURBZ0VBCk1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQmpHZ2hBZmFSZVV3MTMySHF1SHcwTFVSWUQ3eGg4eU9PdmFsaVRGR0NSc29UY2lFNisKT1lvNjgrYUNpVjBCTjdPckpLUVZEcEkxV2twRVhrNVgrblhPSDBqT1p2UThRQ2FTbUd3YjdpUkdEQmV6VXFYYnBaR1J6emZUYitjbgpDRHBPR1I4NnAxaGNGODk1UDR2a3A5TW1JNTBtRDFocC9FZCtzdENOaTVPL0tVOURhWFIyWjB2UEI0em1BdmUxNGJSRHRVc3RGSi81CjNDWU52NlpIZEFiWWlORTZLVENFenRJNWdHSWJxTWRYU2J4cVZWRm5GVXErTlFmazFYV1lOM2t3Rk5zcG5XekZhY3hIVmFJdzk4eGMKZjhMRG1CeHJUaGFBNjNwNFpVV2lBQnF2REExVlpEUkl1Sks1OGJSUUtmSlBJeC9hYkt3ZlJPSGRJM2hSVzhjVwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDT01PRE8gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFSFRDQ0F3V2dBd0lCQWdJUVRvRXRpb0psNEFzQzdqNDFBa2JsUFRBTkJna3Foa2lHOXcwQkFRVUZBRENCZ1RFTE1Ba0dBMVVFCkJoTUNSMEl4R3pBWkJnTlZCQWdURWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEdBMVVFQnhNSFUyRnNabTl5WkRFYU1CZ0cKQTFVRUNoTVJRMDlOVDBSUElFTkJJRXhwYldsMFpXUXhKekFsQmdOVkJBTVRIa05QVFU5RVR5QkRaWEowYVdacFkyRjBhVzl1SUVGMQpkR2h2Y21sMGVUQWVGdzB3TmpFeU1ERXdNREF3TURCYUZ3MHlPVEV5TXpFeU16VTVOVGxhTUlHQk1Rc3dDUVlEVlFRR0V3SkhRakViCk1Ca0dBMVVFQ0JNU1IzSmxZWFJsY2lCTllXNWphR1Z6ZEdWeU1SQXdEZ1lEVlFRSEV3ZFRZV3htYjNKa01Sb3dHQVlEVlFRS0V4RkQKVDAxUFJFOGdRMEVnVEdsdGFYUmxaREVuTUNVR0ExVUVBeE1lUTA5TlQwUlBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNQpNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTBFQ0xpM0xqa1J2M1VjRWJWQVNZMDZtL3dlYUtYVHVICis3dUl6ZzNqTHo4R2x2Q2lLVkNacnRzN29WZXdkRkZ4emUxQ2tVMUIvcW5JMkdxR2QwUzdXV2FYVUY2MDFDeHdSTS9hTjVWQ2FUd3cKeEhHelV2QWhUYUhZdWpsOEhKNmpKSjN5Z3hhWXFoWjhRNXNWVzdldU5KSCsxR0ltR0VhYVArdkIrZkdRVit1c2VnMkwyM0l3YW1iVgo0RWFqY054bzJmOEVTSWwzM3JYcCsyZHRRZW04T2IweTJXSUM4YkdvUFc0M25PSXY0dE9pSm92R3VGVkRpT0VqUHFYU0pEbHFSNnNBCjFLR3pxU1grRFQrbkhiclRVY0VMcE5xc09POVZVQ1FGWlVhVE5FOHRqYTNHMUNFWjBvN0tCV0Z4QjNOSDVZb1pFcjBFVGM1T25LVkkKckxzbTl3SURBUUFCbzRHT01JR0xNQjBHQTFVZERnUVdCQlFMV09XTHhrd1ZONlJBcVRDcEliNUhObHBXL3pBT0JnTlZIUThCQWY4RQpCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pCSkJnTlZIUjhFUWpCQU1ENmdQS0E2aGpob2RIUndPaTh2WTNKc0xtTnZiVzlrCmIyTmhMbU52YlM5RFQwMVBSRTlEWlhKMGFXWnBZMkYwYVc5dVFYVjBhRzl5YVhSNUxtTnliREFOQmdrcWhraUc5dzBCQVFVRkFBT0MKQVFFQVBwaWVtL1liNmRjNXQzaXVIWElZU2RPSDVFT0M2ei9KcXZXb3RlOVZmQ0ZTWmZuVkRlRnM5RDZNazNPUkxnTEVUZ2R4YjhDUApPR0VJcUI2QkNzQXZJQzlCaTVIY1NFVzg4Y2JldW5ack04Z0FMVEZHVE8zbm5jK0lsUDh6d0Zib0pJWW11Tmc0T044cWE5MFN6TWMvClJ4ZE1vc0lHbGduVzIvNC9QRVpCMzFqaVZnODhPOEVja3pYWk9GS3M3c2pzTGpCT2xEVzBKQjlMZUduYThnSTR6SlZTay9Cd0pWbWMKSUdmRTd2bUxWMkgwa25aOVA0U05WYmZvNWF6VjhmVVpWcVphKzVBY3I1UHI1UnpVWjVkZEJBNitDNE9tRjRPNU1CS2d4VE1WQmJrTgorOGNGZHVQWVNvMzhOQmVqeGlFb3ZqQkZNUjdIZUw1WVlUaXNPK0lCWlE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlENWpDQ0FzNmdBd0lCQWdJUVY4c3piOEpjRnVaSEZoZmprREZvNERBTkJna3Foa2lHOXcwQkFRVUZBREJpTVFzd0NRWURWUVFHCkV3SlZVekVoTUI4R0ExVUVDaE1ZVG1WMGQyOXlheUJUYjJ4MWRHbHZibk1nVEM1TUxrTXVNVEF3TGdZRFZRUURFeWRPWlhSM2IzSnIKSUZOdmJIVjBhVzl1Y3lCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcGRIa3dIaGNOTURZeE1qQXhNREF3TURBd1doY05Namt4TWpNeApNak0xT1RVNVdqQmlNUXN3Q1FZRFZRUUdFd0pWVXpFaE1COEdBMVVFQ2hNWVRtVjBkMjl5YXlCVGIyeDFkR2x2Ym5NZ1RDNU1Ma011Ck1UQXdMZ1lEVlFRREV5ZE9aWFIzYjNKcklGTnZiSFYwYVc5dWN5QkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt3Z2dFaU1BMEcKQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURrdkg2U01HM0cySTRyQzd4R3p1QW5sdDdlK2ZvUzB6d3pjN01FTDd4eApqT1dmdGlKZ1BsOWR6Z24vZ2d3Ym1sRlFHaWFKM2RWaFhSbmNFZzh0Q3FKRFhSZlFOSklnNm5QUE9Dd0dKZ2w2Y3ZmNlVETDR3cFBUCmFhSWp6a0d4ek9UVkh6YlJpanI0akdQaUZGbHA3UTNUZjJ2b3VBUGxUMnJsbUdOcFNBVytMdjh6dHVtWFdXbjRaeG11azJHV1JCWFQKY3JBL3ZHcDk3RWgvamNPcnFuRXJVMmxCVXpTMXNMbkZCZ3JFc0VYMVFWMXVpVVY3UFRzbWpIVEM1ZExSZmJJUjFQdFlNaUthZ01uYwovUXpwZjE0RGw4NDdBQlNISjNBNHFZNXVzeWQybUZIZ0JlTWhxeHJWaFNJOEtiV2FGc1dBcVBTN2F6Q1BMMFlDb3JFTUl1RFRBZ01CCkFBR2pnWmN3Z1pRd0hRWURWUjBPQkJZRUZDRXd5ZnNBMTA2WTJvZXFLdENuTHJGQU1hZE1NQTRHQTFVZER3RUIvd1FFQXdJQkJqQVAKQmdOVkhSTUJBZjhFQlRBREFRSC9NRklHQTFVZEh3UkxNRWt3UjZCRm9FT0dRV2gwZEhBNkx5OWpjbXd1Ym1WMGMyOXNjM05zTG1OdgpiUzlPWlhSM2IzSnJVMjlzZFhScGIyNXpRMlZ5ZEdsbWFXTmhkR1ZCZFhSb2IzSnBkSGt1WTNKc01BMEdDU3FHU0liM0RRRUJCUVVBCkE0SUJBUUM3cmt2bnQxZnJmNm90dDNOSGhXckI1S1VkNU9jODZmUlpaWGUxZWx0YWpTVTI0SHFYTGpqQVYyQ0RtQWFEbjdsMmVtNVEKNExxSUxQeEZ6Qml3bVpWUkR1d2R1SWovaDFBY2dzTGo0REtBdjZBTFI4akRNZStaWnpLQVR4Y2hlUXhwWE41ZU5LNEN0U2JxVU45LwpHR1VzeWZKajRha0gvbnh4SDJzekpHb2VCZmNGYU1CcUVzc3VYbUhMcmlqVGZzSzBacEVtWHp3dUpGL0xXQS9yS095dkVaYnozSHR2CndLZUk4bE4zczJCZXJxNG8yalVzYnpSRjB5YmgzdXhiVHlkckZueTlSQVFZZ3JPSmVSY1FjVDE2b2haTzlRSE5wR3hsYUtGSmRseEQKeWRpOE5tZHNwWlMxMU15NXZXbzFWaUhlMk1Qcis4dWtZRXl3VmFDZ2UxZXkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ09NT0RPIEVDQyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDaVRDQ0FnK2dBd0lCQWdJUUgwZXZxbUlBY0ZCVVRBR2VtMk9aS2pBS0JnZ3Foa2pPUFFRREF6Q0JoVEVMTUFrR0ExVUVCaE1DClIwSXhHekFaQmdOVkJBZ1RFa2R5WldGMFpYSWdUV0Z1WTJobGMzUmxjakVRTUE0R0ExVUVCeE1IVTJGc1ptOXlaREVhTUJnR0ExVUUKQ2hNUlEwOU5UMFJQSUVOQklFeHBiV2wwWldReEt6QXBCZ05WQkFNVElrTlBUVTlFVHlCRlEwTWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQgpkWFJvYjNKcGRIa3dIaGNOTURnd016QTJNREF3TURBd1doY05Nemd3TVRFNE1qTTFPVFU1V2pDQmhURUxNQWtHQTFVRUJoTUNSMEl4Ckd6QVpCZ05WQkFnVEVrZHlaV0YwWlhJZ1RXRnVZMmhsYzNSbGNqRVFNQTRHQTFVRUJ4TUhVMkZzWm05eVpERWFNQmdHQTFVRUNoTVIKUTA5TlQwUlBJRU5CSUV4cGJXbDBaV1F4S3pBcEJnTlZCQU1USWtOUFRVOUVUeUJGUTBNZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSbwpiM0pwZEhrd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFEUjNzdmRjbUNGWVg3ZGVTUkZ0U3JZcG4xUGxJTEJzNUJBSCtYCjRRb2tQQjBCQk80OTBvMEpsd3pnZGVUNiszZUtLdlVEWUVzMml4WWpGcTBKY2ZSSzlDaFF0UDZJSEc0L2JDOHZDVmxicFZzTE01bmkKd3oySitXb3M3N0xUQnVtalFqQkFNQjBHQTFVZERnUVdCQlIxY2FjWlNCbThuWjNxUVVmZmxNUklkNW5UZVRBT0JnTlZIUThCQWY4RQpCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpFQTd3TmJlcXkzZUFweXQ0amYvN1ZHCkZBa0srcURtZlFqR0dvZTlHS2h6dlNiS1lBeWR6cG1mejF3UE1PRytGREhxQWpBVTlKTThTYWN6ZXBCR1I3TmpmUk9iVHJkdkdEZUEKVS83ZElPQTFtamJSeHdHNTV0emQ4LzhkTERvV1Y5bVNPZFk9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNlcnRpZ25hCj09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEcURDQ0FwQ2dBd0lCQWdJSkFQN2M0d0VQeVVqL01BMEdDU3FHU0liM0RRRUJCUVVBTURReEN6QUpCZ05WQkFZVEFrWlNNUkl3CkVBWURWUVFLREFsRWFHbHRlVzkwYVhNeEVUQVBCZ05WQkFNTUNFTmxjblJwWjI1aE1CNFhEVEEzTURZeU9URTFNVE13TlZvWERUSTMKTURZeU9URTFNVE13TlZvd05ERUxNQWtHQTFVRUJoTUNSbEl4RWpBUUJnTlZCQW9NQ1VSb2FXMTViM1JwY3pFUk1BOEdBMVVFQXd3SQpRMlZ5ZEdsbmJtRXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFESWFQSEoxdGF6TkhVbWdoN3N0TDdxClhPRW03UkZIWWVHaWZCWjRRQ0hrWUo1YXlHUGh4TEdXa3Y4WWJXa2o0U3RpOTkzaU5pK1JCN2xJenc3c2ViWXM1elJMY0FnbG96eUgKR3hueWdRY1BPSkFaMHhIK2hyVHkwVjRlSHBiTmdHek9PekdUdHZLZzBLbVZFbjJsbXN4cnlJUldpak9wNXlJVlV4Ynd6QmZzVjEvcApvZ3FZQ2Q3alg1eHYzRWpqaFFzVldxYTZuNnhJNHdteTkvUXkzbDQwdmh4NFhVSmJ6ZzRpajAyUTEzMHlHTE1MTEdxL2pqOFVFWWtnCkRuY1V0VDJVQ0lmM0pSN1ZzbUFBN0c4cUtDVnVLajRZWXhjbFB6NUVJQmIySnNnbHJnVkt0T2RqTFBPTUZsTitYUHNSR2dqQlJtS2YKSXJqeHdvMXAzUG82V0FiZkFnTUJBQUdqZ2J3d2dia3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVHdTMrUVRtUQp0Q1JadmdIeVV0VkY5bG81M0JFd1pBWURWUjBqQkYwd1c0QVVHdTMrUVRtUXRDUlp2Z0h5VXRWRjlsbzUzQkdoT0tRMk1EUXhDekFKCkJnTlZCQVlUQWtaU01SSXdFQVlEVlFRS0RBbEVhR2x0ZVc5MGFYTXhFVEFQQmdOVkJBTU1DRU5sY25ScFoyNWhnZ2tBL3R6akFRL0oKU1A4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJFR0NXQ0dTQUdHK0VJQkFRUUVBd0lBQnpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQQpoUU1la25IMlFxL2hvMkdlNi9QQUQvS2wxTnFWNXRhK2FEWTlmbTRmVElydjBROGhiVjZsVW1QT0V2anZLdHB2NnpmK0V3TEh5enMrCkltdmFZUzUvMUhJOTNURGhIa3hBR1l3UDE1elJnekI3bUZuY2ZjYTVEQ2xNb1RPaTYyYzZaWVRUbHVMdGRrVndqN1VyM3ZrajFrbHUKUEJTMXhwODFIbERRd1k5cWNFUUNZc3V1SFdoQnA2cFg2Rk9xQjlJRzl0VVVCZ3VSQTNVc2JISzFZWldhRFl1NURlZjEzMVROM3ViWQoxZ2tJbDJQbHdTNnd0MFFtd0NiQXIxVXduanZWTmlvWkJQUmNIdi9QTExmLzBQMkhRQkhWRVNPN1NNQWhxYVFvTGYwVitMQk9LL1F3Cld5SDhFWkUwdmtIdmU1MlhkZitYbGNDV1dDL3F1MGJYdStUWkxnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ3liZXJ0cnVzdCBHbG9iYWwgUm9vdAo9PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEb1RDQ0FvbWdBd0lCQWdJTEJBQUFBQUFCRDRXcUxVZ3dEUVlKS29aSWh2Y05BUUVGQlFBd096RVlNQllHQTFVRUNoTVBRM2xpClpYSjBjblZ6ZEN3Z1NXNWpNUjh3SFFZRFZRUURFeFpEZVdKbGNuUnlkWE4wSUVkc2IySmhiQ0JTYjI5ME1CNFhEVEEyTVRJeE5UQTQKTURBd01Gb1hEVEl4TVRJeE5UQTRNREF3TUZvd096RVlNQllHQTFVRUNoTVBRM2xpWlhKMGNuVnpkQ3dnU1c1ak1SOHdIUVlEVlFRRApFeFpEZVdKbGNuUnlkWE4wSUVkc2IySmhiQ0JTYjI5ME1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCitNaTh2UlJRWmhQLzhOTjU3Q1B5dHhySGpvWHhFbk9tR2FvUTI1eWlaWFJhZHo1UmZWYjIzQ08yMU8xZldMRTNUZFZKRG03MWFvZlcKMG96U0o4YmkvemFmbUdXZ0UwN0dLbVNiMVpBU3p4UUc5RHZqMUNpKzZBNzRxMDVJbEcyT2xURVFYTzJpTGIzVk9tMnlITHRnd0VaTApBZlZKcm41R2l0QjBqYUVNQXM3dS9PZVB1R3RtODM5RUFMOW1KUlFyM1JBd0hRZVdQMDMyYTdpUHQzc01wVGpyM2tmYjFWMDUvSWluCjg5Y3FkUEhvV3FJN24xQzZwb3hGTmNKUVpaWGNZNEx2M2I5M1RaeGl5V056RnRBcEQwbXBTUEN6cXJkc3hhY3dPVUJkcnNUaVhTWlQKOE00Y0l3aGhxSlFadWdSaVFPd2ZPSEIzRWdaeHB6QVlYU1VucFFJREFRQUJvNEdsTUlHaU1BNEdBMVVkRHdFQi93UUVBd0lCQmpBUApCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUzJDSHNOZXN5c0lFeUdWakplejZ0dWhTMXdWekEvQmdOVkhSOEVPREEyCk1EU2dNcUF3aGk1b2RIUndPaTh2ZDNkM01pNXdkV0pzYVdNdGRISjFjM1F1WTI5dEwyTnliQzlqZEM5amRISnZiM1F1WTNKc01COEcKQTFVZEl3UVlNQmFBRkxZSWV3MTZ6S3dnVElaV01sN1BxMjZGTFhCWE1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQlc3d29qb0ZSTwpsWmZKK0luYVJjSFVvd0FsOUI4VHE3ZWpoVmhwd2pDdDJCV0tMZVBKellGYStITWpXcWQ4QmZQOUlqc08wUWJFMnpaTWN3U081YkFpCjVNWHpMcVhaSStPNFRrb2dwMjRDSko4aVlHZDdpeDF5Q2NVeFhPbDVuNEJIUGEyaEN3Y1VQVWYvQTJrYURBdEU1Mk1scDMreXliaDIKaE8wajluMEhxMFYrMDkrenYrbUt0czJvb21jclV0VzNaZkE1VEdPZ2tYbVRVZzlVM1lPN245R1BwMU56dzh2L01PeDhCTGpZUkIrVApYM0VKSXJkdVB1b2NBMDZkR2lCaCs0RTM3Rjc4Q2tXcjErY1hWZENnNm1DYnB2YmpqRnNwd2daZ0ZKMHRsMHlwa3hXZFljUUJYMGpXCldMMVdNUkpPRWNnaDRMTVJrV1hidEthSU9NNVYKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRnNEQ0NBNWlnQXdJQkFnSVFGY2k5WlVkY3I3aVhBRjdrQnRLOG5UQU5CZ2txaGtpRzl3MEJBUVVGQURCZU1Rc3dDUVlEVlFRRwpFd0pVVnpFak1DRUdBMVVFQ2d3YVEyaDFibWRvZDJFZ1ZHVnNaV052YlNCRGJ5NHNJRXgwWkM0eEtqQW9CZ05WQkFzTUlXVlFTMGtnClVtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzB3TkRFeU1qQXdNak14TWpkYUZ3MHpOREV5TWpBd01qTXgKTWpkYU1GNHhDekFKQmdOVkJBWVRBbFJYTVNNd0lRWURWUVFLREJwRGFIVnVaMmgzWVNCVVpXeGxZMjl0SUVOdkxpd2dUSFJrTGpFcQpNQ2dHQTFVRUN3d2haVkJMU1NCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1JSUNJakFOQmdrcWhraUc5dzBCCkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQTRTVVA3bzNiaUROMVo4MnRIMzA2VG0yZDB5OFU4Mk4weXdFaGFqZnFoRkFIU3laYkNVTnMKSVo1cXlOVUQ5V0Jwajh6d0l1UWY1L2RxSWpHM0xCWHk0UDRBYWtQL2gyWEd0UnJCcDB4dEluQWhpakh5bDNTSkNSSW1ISjdLMlJLaQpsVHphNldlL0NLQms0OVpDdDBYdmwvVDI5ZGUxU2hVQ1dIMllXRXRndk0zWERab1RNMVBSWWZsNjFkZDRzNW96OXdDR3poMU5sRGl2CnFPeDRVWENLWEJDRFVTSDNFVDAwaGw3bFNNMlhnWUkxVEJuc1pmWnJ4UVdoN2tjVDFyTWhKNVFRQ3Rra083cStSQk5HTUQrWFBOalgKMTJydU96ampLOVNYRHJrYjV3ZEpmemNxK1hkNHoxVHRXMGFkbzRBT2tVUEIxbHRmRkxxZnBvMGtSMEJadjNJNHNqWnNOLytaMFYwTwpXUXFyYWZmQXNnUkZlbFFBcnI1VDlyWG40Zmc4b3pIU3FmNGhVbVRGcG1md2RRY0dsQlNCVmNZbjVBR1BGOEZxY2RlK1MvdVVXSDErCkVUT3hRdmRpYkJqV3p3bG9QbjlzOWg2UFlxMmxZOXNKcHg4aVFrRWViNW1LUHRmNVAwQjZlYkNsQVpMU25UMElGYVVRQVMyek1uYW8KbFEyemVwcjdCeEI0RVcvaGo4ZTZEeVVhZENybEhKaEJtZDhoaCtpVkJtb0tzMnBIZG1YMk9zK1BZaGNaZXdvb3pSclNneDRoeHl5Lwp2djloYUxkbkc3dDRUWTNPWitYa3dZNjNJMmJpblpCMU5KaXBOaXVLbXBTNW5lek1pckg0SllsY1dyWXZqQjl0ZVNTblVtakRoRFhpClpvMWpEaVZOMVJteTVuazNweUtkVkRFQ0F3RUFBYU5xTUdnd0hRWURWUjBPQkJZRUZCNE05N1puOHVHU0pnbEZ3RlU1TG5jL1FrcWkKTUF3R0ExVWRFd1FGTUFNQkFmOHdPUVlFWnlvSEFBUXhNQzh3TFFJQkFEQUpCZ1VyRGdNQ0dnVUFNQWNHQldjcUF3QUFCQlJGc01MSApDbFo4N2x0NERKWDVHRlBCcGh6WUVEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFDYk9EVTFrQlBwVkp1ZkdCdXZsMklDTzFKMkIwCjFHcVpORjVzQUZQWm4vS21zU1FIUkdvcXhxV09lQkxvUjlsWUd4TXFYbm1ibndvcVo2WWxQd1pwVm5QRGltWkkreW1CVjNRR3lwenEKS09nNFp5WXI4ZFcxUDJXVCtEWmRqbzJOUUNDSEdlcnZKOEE5dERrUEpYdG9VSFJWbkF4WmZWbzlRWlFsVWdqZ1J5d1ZNUm5WdndkVgp4cnNTdFpmMFg0T0Z1bkhCMld5QkVYWUtDckMvZ3BmMzZqMzYrdXd0cVNpVU8xYmQwbEV1cnNDOUNCV01kMUkwbHRhYnJOTWRqbUVQCk5YdWJyamxwQzJKZ1FDQTJqNi83TnU0dENFb2R1TCtiWFBqcXBSdWdjNmJZK0c3Z013UmZhS29uaCszWndaQ2M3YjNqYWpXdlk5K3IKR05tNjV1bEs2bENLRDJHVEh1SXRHZUl3bERXU1hRNjJCNjhaZ0k5SGtGRkxMazNkaGVMU0NsSUtGNXI4R3JCUUF1VUJvMk0zSVV4RQp4SnRSbVJFT2M1d0dqMVF1cHloZVJEbUhWaTAzdllWRWxPRU1TeXljdzVLRk5HSExEN2liU2tOUy9qUTZmYmpwS2R4MnFjZ3crQlJ4CmdNWWVOa2gwSWtGY2g0TG9HSEdMUVlsRTUzNVlXNmk0alJQcHAyekRSKzJ6R3AxaXJvMkM2cFNlM1ZrUXc2M2Q0azNqTWRYSDdPankKc1A2U0hoWUtHdnpaOC9nbnRzbStIYlJzWkpCLzlPVEVXOWMzcmtJTzNhUWFiM3lJVk1VV2J1RjZhQzc0T3I4TnBEeUpPM2luVG1PRApCQ0VJWjQzeWdrblFXLzJ4elErRGhOUStJSVgzU2owcm5QMHFDZ2xONm9INEVadz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKY2VydFNJR04gUk9PVCBDQQo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlET0RDQ0FpQ2dBd0lCQWdJR0lBWUZGbkFDTUEwR0NTcUdTSWIzRFFFQkJRVUFNRHN4Q3pBSkJnTlZCQVlUQWxKUE1SRXdEd1lEClZRUUtFd2hqWlhKMFUwbEhUakVaTUJjR0ExVUVDeE1RWTJWeWRGTkpSMDRnVWs5UFZDQkRRVEFlRncwd05qQTNNRFF4TnpJd01EUmEKRncwek1UQTNNRFF4TnpJd01EUmFNRHN4Q3pBSkJnTlZCQVlUQWxKUE1SRXdEd1lEVlFRS0V3aGpaWEowVTBsSFRqRVpNQmNHQTFVRQpDeE1RWTJWeWRGTkpSMDRnVWs5UFZDQkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMY3p1WDdJCkpVcU90ZHUwS0J1cVY1RG8wU0xUWkxyVGsralVySVpoUUdwZ1YyaFVoRTI4YWxRQ0JmL2ZtNW9xcmwwSGowckRLSC92K3l2NmVmSEgKcmZBUVV5U1FpMmJKcUlpcnIxcWpBT20rdWtidVczTjdMQmVDZ1Y1aUxLRUNaYk85eFNzQWZzVDhBek5YRGUzaStzNWRSZFk0elRXMgpzc0hRbklGS3F1U3lBVndkajErWnhMR3QyNGdoNjVBSWdvRHpNS05ENXBDQ3JsVW9TZTFiMTZrUU9BNytqMHhibTBicVFmV3dDSFRECjBJZ3p0bnpYZE4vY2hORkREblU1b1NWQUtPcDR5dzRzTGptZGpJdHVGaHd2Sm9JUTR1TmxsQW9Fd0Y3M1hWdjRFT0xRdW5wTCs5NDMKQUFBYVd5amowcHh6UGpLSG1LSEpVUy9YM3F3enMwOENBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QgpBZjhFQkFNQ0FjWXdIUVlEVlIwT0JCWUVGT0NNbTlzbFNiUHhmSWJXc2tLSEM5QnJvTm5rTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCCkFRQSswaHlKTGpYOCtIWGQ1bjlsaVBSeVRNa3MxekpPODkwWmVVZTlqanRia3c5UVNTUVRheFFHY3U4SjA2R2g0MENFeWVjWU1uUTgKU0c0UG4wdlU5eDdUazRaa1ZKZGpjbERWVmMvNklKTUNvcHZESTVOT0ZsVjJvSEI1YmMwaEg4OHZMYndaNDRneCtGa2FnUW5JbDZaMAp4MkRFVzh4WGpySjEvUnNDQ2R0WmIzS1RhZmN4UWRhSU9MK0hzcjBXZWZtcTVMNklKZDFoSnlNY3RURUhCRGEwR3BDOW9IUnhVSWx0CnZCVGpENGF1OGFzK3g2QUp6S05JMGVEYlpPZVN0Yyt2Y2tOd2kvbkRoRHdUcW42U20xZFRrL3B3d3BFT01mbWJaMTNwbGpoZVg3TnoKVG9nVlo5NmVkaEJpSUw1VmFaVkRBRGxOOXU2d1drNUpSRlJZWDBLRAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDcmpDQ0FqV2dBd0lCQWdJUVBMTDBTQW9BNHY3ckpEdGVZRDdEYXpBS0JnZ3Foa2pPUFFRREF6Q0JtREVMTUFrR0ExVUVCaE1DClZWTXhGakFVQmdOVkJBb1REVWRsYjFSeWRYTjBJRWx1WXk0eE9UQTNCZ05WQkFzVE1DaGpLU0F5TURBM0lFZGxiMVJ5ZFhOMElFbHUKWXk0Z0xTQkdiM0lnWVhWMGFHOXlhWHBsWkNCMWMyVWdiMjVzZVRFMk1EUUdBMVVFQXhNdFIyVnZWSEoxYzNRZ1VISnBiV0Z5ZVNCRApaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNBdElFY3lNQjRYRFRBM01URXdOVEF3TURBd01Gb1hEVE00TURFeE9ESXpOVGsxCk9Wb3dnWmd4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRS0V3MUhaVzlVY25WemRDQkpibU11TVRrd053WURWUVFMRXpBb1l5a2cKTWpBd055QkhaVzlVY25WemRDQkpibU11SUMwZ1JtOXlJR0YxZEdodmNtbDZaV1FnZFhObElHOXViSGt4TmpBMEJnTlZCQU1UTFVkbApiMVJ5ZFhOMElGQnlhVzFoY25rZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGtnTFNCSE1qQjJNQkFHQnlxR1NNNDlBZ0VHCkJTdUJCQUFpQTJJQUJCV3g2UDBERlVQbHJPdUhOeEZpNzlLRE5sSjlSVmNMU28xN1ZEczZibDhWQXNCUXBzOGxMMzNLU0xqSFVHTWMKS2lFSWZKbzIyQXYrMFNiRldERXdLQ1h6WFYyanVMYWx0Skx0YkN5ZjY5MURpYUk4UzBpUkhWRHNKdC9XWUM2OUlhTkNNRUF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFRkJWZk5WZFJWZnNsc3EwRGFmd0JvL3ErCkVWWFZNQW9HQ0NxR1NNNDlCQU1EQTJjQU1HUUNNR1NXV2Fib0NkNkx1dnBhaUlqd0g1SFRScWp5U2t3Q1kvdHNYempiTGtHVHFRN20KbmR3eEhMS2dweGdjZWVISE5nSXdPbGF2bW5Sczl2dUQ0RFBUQ0YraG5NSmJuMGJXdHN1UkJtT2lCdWN6ckQ2b2dSTFF5N3JRa2d1MgpucGFxQkErSwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpWZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRXVUQ0NBNkdnQXdJQkFnSVFRQnJFWkNHekV5RUREcnZrRWhyRkhUQU5CZ2txaGtpRzl3MEJBUXNGQURDQnZURUxNQWtHQTFVRQpCaE1DVlZNeEZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVI4d0hRWURWUVFMRXhaV1pYSnBVMmxuYmlCVWNuVnpkQ0JPClpYUjNiM0pyTVRvd09BWURWUVFMRXpFb1l5a2dNakF3T0NCV1pYSnBVMmxuYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmsKSUhWelpTQnZibXg1TVRnd05nWURWUVFERXk5V1pYSnBVMmxuYmlCVmJtbDJaWEp6WVd3Z1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dQpJRUYxZEdodmNtbDBlVEFlRncwd09EQTBNREl3TURBd01EQmFGdzB6TnpFeU1ERXlNelU1TlRsYU1JRzlNUXN3Q1FZRFZRUUdFd0pWClV6RVhNQlVHQTFVRUNoTU9WbVZ5YVZOcFoyNHNJRWx1WXk0eEh6QWRCZ05WQkFzVEZsWmxjbWxUYVdkdUlGUnlkWE4wSUU1bGRIZHYKY21zeE9qQTRCZ05WQkFzVE1TaGpLU0F5TURBNElGWmxjbWxUYVdkdUxDQkpibU11SUMwZ1JtOXlJR0YxZEdodmNtbDZaV1FnZFhObApJRzl1YkhreE9EQTJCZ05WQkFNVEwxWmxjbWxUYVdkdUlGVnVhWFpsY25OaGJDQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwCmFHOXlhWFI1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4MkUzWHJFQk5OdGkxeFdiLzFoYWpDTWoKMW1DT2tkZVFtSU42NWxnWk9JekY5dVZraGJTaWNmdnR2Ym5helUwQXRNZ3RjNlhIYVhHVkh6azhza1FIbk9nTytrMUt4Q0hmS1dHUApNaUpoZ3NXSEgyNk1mRjhXSUZGRTBYQlBWK3JqSE9QTWVlNVkyQTdDczBXVHdDem5taGNyZXdBM2VrRXplT0V6NHZNUUduK0hMTDcyCjlmZEM0dVcvaDJLSlh3QkwzOFhkNUhWRU1rRTZIbkZ1YWNzTGRVWUkwY3JTSzVYUXovdTVRR3RrakZkTi9CTVJlWVR0WGxUMk5KOEkKQWZNUUpRWVhTdHJ4SFhwbWE1aGdacVRaNzlJdWd2SHc3d25xUk1rVmF1SURialBUcko5VkFNZjJDR3FVdVYvYzREUHhoR0Q1V3ljUgp0UHdXOHJ0V2FvQWxqUUlEQVFBQm80R3lNSUd2TUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNRzBHCkNDc0dBUVVGQndFTUJHRXdYNkZkb0Zzd1dUQlhNRlVXQ1dsdFlXZGxMMmRwWmpBaE1COHdCd1lGS3c0REFob0VGSS9sMHhxR3JJMk8KYThQUGdHclVTQmdzZXhrdU1DVVdJMmgwZEhBNkx5OXNiMmR2TG5abGNtbHphV2R1TG1OdmJTOTJjMnh2WjI4dVoybG1NQjBHQTFVZApEZ1FXQkJTMmQvcHBTRWVmVXhMVnd1b0hNbllIMFpjSEdUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFTdmo0c0FQbUxHZDc1SlIzClk4eHVUUGw5RGczY3lMazF1WEJQWS9vaytteURqRWVkTzJQem12bDJNcFdSc1hlOHJKcStzZVF4SWNhQmxWWmFEckhDMUxHbVdhengKWTh1NFRCMVprRXJ2a0JZb0gxcXVFUHVCVURnTWJNenhQY1AxWStPejR5SEpKRG5wL1JWbVJ2UWJFZEJOYzZOOVJ2azk3YWhmWXRUeApQL2pnZEZjckdKMkJ0TVFvMnBTWHBYRHJyQjIrQnhIdzFkdmQ1WXp3MVRLd2crWlg0bysvdnFHcXZ6MGR0ZFE0NnRld1hEcFBhaitQCndHWnNZNnJwMmFRVzlJSFJsUlFPZmMyVk5OblNqM0J6Z1h1Y2ZyMllZZGhGaDVpUXhldUdNTVkxdi9EL3cxV0lnMHZ2QlpJR2NmSzQKbUpPMzdNMkNZZkU0NWsrWG1DcGFqUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCk5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVGVENDQXYyZ0F3SUJBZ0lHU1VFczVBQVFNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR25NUXN3Q1FZRFZRUUdFd0pJVlRFUk1BOEcKQTFVRUJ3d0lRblZrWVhCbGMzUXhGVEFUQmdOVkJBb01ERTVsZEV4dlkyc2dTMlowTGpFM01EVUdBMVVFQ3d3dVZHRnV3N3B6dzYxMApkc09oYm5scmFXRmt3N05ySUNoRFpYSjBhV1pwWTJGMGFXOXVJRk5sY25acFkyVnpLVEUxTURNR0ExVUVBd3dzVG1WMFRHOWpheUJCCmNtRnVlU0FvUTJ4aGMzTWdSMjlzWkNrZ1JzV1JkR0Z1dzdwenc2MTBkc09oYm5rd0hoY05NRGd4TWpFeE1UVXdPREl4V2hjTk1qZ3gKTWpBMk1UVXdPREl4V2pDQnB6RUxNQWtHQTFVRUJoTUNTRlV4RVRBUEJnTlZCQWNNQ0VKMVpHRndaWE4wTVJVd0V3WURWUVFLREF4TwpaWFJNYjJOcklFdG1kQzR4TnpBMUJnTlZCQXNNTGxSaGJzTzZjOE90ZEhiRG9XNTVhMmxoWk1PemF5QW9RMlZ5ZEdsbWFXTmhkR2x2CmJpQlRaWEoyYVdObGN5a3hOVEF6QmdOVkJBTU1MRTVsZEV4dlkyc2dRWEpoYm5rZ0tFTnNZWE56SUVkdmJHUXBJRWJGa1hSaGJzTzYKYzhPdGRIYkRvVzU1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4Q1JlYzc1TGJSVERvZlRqbDVCdQowakJGSGp6dVo5bGs0QnFLZjhvd3lvUGpJTUhqOURyVGxGOGFmRnR0dnpCUGhDZjJueDlKdk1hWkNwRHlEL1YvUTRRM1kxR0xlcVZ3Ci9IcFl6WTZiN2NOR2JJUndYZHJ6QVpBai9FNHdxWDdoSjJQbjdXUThvTGpKTTJQK0ZwRC9zTGo5MTZqQXdKUkRDN2JWV2FhZVZ0QWsKSDNCNXI5czVWQTFsZGRrVlFaUUJyMTdzOW8zeC82MWsvaUNhMTF6ci9xWWZDR1NqaTNaVnJSNDdLR0F1aHlYb3FxOGZ4bVJHSUxkdwpmenplU051V1U3YzVkK1FhNHNjV2hIYVhXeSs3R1JXRitHbUY5Wm1ucWZJMHA2bTJwZ1A4YjRZOVZIeDJCSnRyK1VCZEFEVEhMcGwxCm5lV0lBNnBOK0FQU1FuYkFHd0lEQUtpTG8wVXdRekFTQmdOVkhSTUJBZjhFQ0RBR0FRSC9BZ0VFTUE0R0ExVWREd0VCL3dRRUF3SUIKQmpBZEJnTlZIUTRFRmdRVXpQcG5rL0MydU5DbHdCN3pVLzJNVTkrRDE1WXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS3QvN2h3VwpxWnc4VVFDZ3dCRUlCYWVaNW04QmlGUmhidkc1R0sxS3JmNkJRQ09VTC90MWZDOG9TMklrZ1lJTDlXSHhIRzY0WVRqcmdmcGlvVHRhCll0T1VaY1RoNW0yQytDOGxjTEloSnNGeVVSK01MTU9Fa01OYWo3clA5S2RscGV1WTBmc0Zza1oxRlNOcWI0VmpNSUR3MVo0ZktSekMKYkxCUVdWMlFXenVvRFREUHYzMS96dkdkZzczSlJtNGdwdmxoVWJvaEwzdStwUlZqb2RTVmgvR2V1Zk9KOHoyRnVMamJ2clc1S2ZuYQpOd1VBU1pRRGhFVG52ME14ejNXTEpkSDBwbVQxa3ZhckJlczk2YVVMTm1MYXpBWmZOb3UyWGpHNEt2dGU5bkhmUkNhZXhPWU5rYlF1CmRaV0FVV3BMTUthd1lxR1Q4WnZZenNSamRUOVpSN0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkhvbmdrb25nIFBvc3QgUm9vdCBDQSAxCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlETURDQ0FoaWdBd0lCQWdJQ0ErZ3dEUVlKS29aSWh2Y05BUUVGQlFBd1J6RUxNQWtHQTFVRUJoTUNTRXN4RmpBVUJnTlZCQW9UCkRVaHZibWRyYjI1bklGQnZjM1F4SURBZUJnTlZCQU1URjBodmJtZHJiMjVuSUZCdmMzUWdVbTl2ZENCRFFTQXhNQjRYRFRBek1EVXgKTlRBMU1UTXhORm9YRFRJek1EVXhOVEEwTlRJeU9Wb3dSekVMTUFrR0ExVUVCaE1DU0VzeEZqQVVCZ05WQkFvVERVaHZibWRyYjI1bgpJRkJ2YzNReElEQWVCZ05WQkFNVEYwaHZibWRyYjI1bklGQnZjM1FnVW05dmRDQkRRU0F4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBclA4NHR1bG1Ba25qb3JUaGtQbEFqM241NHIxNS9nSzk3aVNTSFNMMjJvVnlhZjdYUHduVTNaRzEKQXB6UWpWcmhWY05RaHJrcEpzTGoyYUR4YVFNb0lJQkZJaTFXcHp0VWxWWWlXUjhvM3g4Z1BXMmlOcjRqb0xGdXRiRW5QemxUQ2VxcgphdWgwc3NKbFhJNi9mTU40aE0yZUZ2ejFMazhnS2dpZmQvUEZIc1NhVW1ZZVNGN2pFQWFQSXBqaFpZNGJYU05tTzdpbE1sSElocXFoCnFaNS9kcFRDcG15M1FmRFZ5QVk0NXRRTTR2TTdURzFRak1TREo4RVRoRms5bm5WMHR0Z0NYanFRZXNCQ05uTHNhazNjNzhRQTN4TVkKVjE4bWVNaldDbmwzdi9ldnQzYTVwUXVFRjEwUTZtL2hxNVVSWDIwOG8xeE5nMXZ5c3htS2dJc0xod0lEQVFBQm95WXdKREFTQmdOVgpIUk1CQWY4RUNEQUdBUUgvQWdFRE1BNEdBMVVkRHdFQi93UUVBd0lCeGpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQURrYlZQSzdpCmg5bGVnWXNDbUVFSWpFeTgydHZ1Snh1QzUycEY3QmFMVDRXZzg3Snd2VnFXdXNwdWJlNUdpMjduS2k2V3N4a3o2N1NmcUxJMzdwaW8KbDdZdXRtY24xS1pKL1J5VFpYYWVRaS9jSW15YVQvSmFGVG14Y2RjclVlaHRISmpBMlNyMG9ZSjcxY2xCb2lNQmREaFZpdys1TG1laQpJQVEzMnB3TDB4Y2g0SStYZVRSdmhFZ0NJRE1iNWpSRW41Rnc5SUJlaEVQQ0tkSnNFaFRrWVkyc0VKQ2VoRkM3OEpadlJaK0s4OHBzClQvb1JPaFVWUnNQTkg0TmJMVUVTN1ZCblFSTTlJYXVVaXFwT2ZNR3grNmZXdFNjdmw2dHU0QjNpMFJ3c0gwVGkvTDZSb1p6NzFpbFQKYzRhZlU5aEREbDNXWTRKeEhZQjB5dmJpQW12WldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU2VjdXJlU2lnbiBSb290Q0ExMQo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEYlRDQ0FsV2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCWU1Rc3dDUVlEVlFRR0V3SktVREVyTUNrR0ExVUVDaE1pClNtRndZVzRnUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObGN5d2dTVzVqTGpFY01Cb0dBMVVFQXhNVFUyVmpkWEpsVTJsbmJpQlMKYjI5MFEwRXhNVEFlRncwd09UQTBNRGd3TkRVMk5EZGFGdzB5T1RBME1EZ3dORFUyTkRkYU1GZ3hDekFKQmdOVkJBWVRBa3BRTVNzdwpLUVlEVlFRS0V5SktZWEJoYmlCRFpYSjBhV1pwWTJGMGFXOXVJRk5sY25acFkyVnpMQ0JKYm1NdU1Sd3dHZ1lEVlFRREV4TlRaV04xCmNtVlRhV2R1SUZKdmIzUkRRVEV4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEvWGVxcFJ5UUJUdkwKVEpzemkxb1VSYVRua0JiUjMxZlNJUkNrRi8zZnJOWWZwK1RiZlBmczM3Z0QycFJZL1YxeWZJdy9Yd0ZuZEJXVzR3SThoOXV1eXdHTwp3dk5teG9WRjlBTEdPclZpc3EvNm5MK2s1dFNBTUpqekRiYVRqNm5VMkRieXNQeUt5aXloRlRPVk1kckFHL0x1WXBtR1l6Ky8zWk1xCmc2aDJ1Uk1mdDg1T1FvV1BJdWN1R3ZLVkNiSUZ0VVJPZDZFZ3ZhbnlUZ3A5VUszMUJRMUZUMFp4L1NnK1Uvc0UyQzNYWlIxS0cvclAKTzdBeG1qVnV5SXNHMHdDUjhwUUlaVXl4TkFZQWVvbmk4TWNEV2MvVjF1aW5NclBtbUVDR3hjMG5Fb3ZNZTg2M0VUeGlZQWNqUGl0QQpicFNBQ1cyMnMyOTNielVJVVBzQ2g4VStpUUlEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVVy9oTlQ3S2xodFE2MHZGam1xQytDZlpYCnQ5NHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFLQ2gKT0JabUxxZFdIeUdjQnZvZDdia2l4VGdtMkU1UDdLTi9lZDVHSWFHSGQ0OEhDSnF5cE1XdkR6S1lDM3htS2JhYmZTVlNTVU9yVEM0cgpibnB3cnhZTzR3SnMrMExtR0oxRjJGWEk2RHZkNStIMExnc2NORnhzV0VyN2pJaFFYNVVjdisycklyVmxzNFc2bmcrNHJlVjZHNHBRCk9oMjlEYng3VkZBTHVVS3ZWYUFZZ2ExbG1lKys1SnkveElXclFiSlViOXdsemUxNDRvNE1qUWxKM1dON1dtbVdBaUdvdlZKWjZYMDEKeThoU3luK0IvdGxyMC9jUjdTWGYrT2Y1cFBweWw0UlREYVhRTWhoUmRsa1ViQS9yN0YrQWpIVkRnOE9GbVA5TW5pME41SGVEazA2MQpsZ2VMS0JPYmpCbU5RU2RKUU83ZTVpTkVPZHloSXRhNkEvST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQSAyMDA5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRUNqQ0NBdktnQXdJQkFnSUpBTUorUXdST1J6OFpNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR0NNUXN3Q1FZRFZRUUdFd0pJVlRFUgpNQThHQTFVRUJ3d0lRblZrWVhCbGMzUXhGakFVQmdOVkJBb01EVTFwWTNKdmMyVmpJRXgwWkM0eEp6QWxCZ05WQkFNTUhrMXBZM0p2CmMyVmpJR1V0VTNwcFoyNXZJRkp2YjNRZ1EwRWdNakF3T1RFZk1CMEdDU3FHU0liM0RRRUpBUllRYVc1bWIwQmxMWE42YVdkdWJ5NW8KZFRBZUZ3MHdPVEEyTVRZeE1UTXdNVGhhRncweU9URXlNekF4TVRNd01UaGFNSUdDTVFzd0NRWURWUVFHRXdKSVZURVJNQThHQTFVRQpCd3dJUW5Wa1lYQmxjM1F4RmpBVUJnTlZCQW9NRFUxcFkzSnZjMlZqSUV4MFpDNHhKekFsQmdOVkJBTU1IazFwWTNKdmMyVmpJR1V0ClUzcHBaMjV2SUZKdmIzUWdRMEVnTWpBd09URWZNQjBHQ1NxR1NJYjNEUUVKQVJZUWFXNW1iMEJsTFhONmFXZHVieTVvZFRDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU9uNGovTmpyZHFHMktmZ1F2dlBrZDZtSnZpWnBXTndyWnV1eWpOQQpmVzJXYnFFT1JPN2hFNTJVUWxLYXZYV0ZkQ3lvRGgyVHRoaTNqQ3lvei90Y2NibmE3UDdvZm8va0x4MnlxSFdIMkxlaDVUdlBtVXBHCjBJTVpmY0NoRWh5VmJVcjAyTWVsVFRNdWhUbEFkWDRVZklBU21GREhRV2U0b0lCaFZLWnNUaC9nblE0SDZjbTZNK2Yrd0ZVb0xBS0EKcHhuMW50eFZVd09YZXdkSS81bjdONG9reEZuTVVCQmpqcXFwR3JDRUdvYjVYN3V4VUc2azBRck0xWEYrSDZjYmZQVlRiaUpmeXl2bQoxSHhkcnRiQ3hremxCUUhaN1ZmOHdTTjUvUHJJSklPVjg3VnFVUUhRZDlicEVxSDVHb1A3Z2h1NXNKZjBkZ1l6UTBtZy93dTErclVDCkF3RUFBYU9CZ0RCK01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJUTEQ4YmYKUWtQTVBjdTFTQ09oR25xbUtyczBhREFmQmdOVkhTTUVHREFXZ0JUTEQ4YmZRa1BNUGN1MVNDT2hHbnFtS3JzMGFEQWJCZ05WSFJFRQpGREFTZ1JCcGJtWnZRR1V0YzNwcFoyNXZMbWgxTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFESjBRNWVMdFhNczN3K3kvdzkvdzBvCmxaTUV5TC9helhtNFE1RHdwTDd2OHU4aG1MelUxRjBHOXU1QzdEQnNvS3FweXZHdml2by9DM05xUHVvdVFINGZybFJoZWVzdUNEZlgKSS9PTW43NGRzZUdrZGR1ZzRsUVVzYm9jS2FRWTloSzZvaFFVNHpFMXlFRC90K0FGZGxmQkhGbnkrTC9rN1NWaVhJVHdmbjRmczc3NQp0eUVSekFNQlZuQ25FSkllR3pTQkhxMmNHc01FUE8wQ1lkWWVCdk5mT29meUsvRkZoK1U5ck5ISFY0UzlhNjdjMlBtMkcySndDejAyCnlVTHlNdGQ2WWViUzJ6M1B5S25KbTl6YldFVFhieml2ZjNqVG82MGFkYm9jd1RaOGp4NXRITU4xUnE0MUJhYjJYRDBoN2xid3lZSWkKTFhwVXEzRERmU0psZ25DVwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMwo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFh6Q0NBa2VnQXdJQkFnSUxCQUFBQUFBQklWaFRDS0l3RFFZSktvWklodmNOQVFFTEJRQXdUREVnTUI0R0ExVUVDeE1YUjJ4dgpZbUZzVTJsbmJpQlNiMjkwSUVOQklDMGdVak14RXpBUkJnTlZCQW9UQ2tkc2IySmhiRk5wWjI0eEV6QVJCZ05WQkFNVENrZHNiMkpoCmJGTnBaMjR3SGhjTk1Ea3dNekU0TVRBd01EQXdXaGNOTWprd016RTRNVEF3TURBd1dqQk1NU0F3SGdZRFZRUUxFeGRIYkc5aVlXeFQKYVdkdUlGSnZiM1FnUTBFZ0xTQlNNekVUTUJFR0ExVUVDaE1LUjJ4dlltRnNVMmxuYmpFVE1CRUdBMVVFQXhNS1IyeHZZbUZzVTJsbgpiakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNd2xkcEI1Qm5naUZ2WEFnN2FFeWlpZS9RVjJFY1d0CmlITDhSZ0pEeDdLS25RUmZKTXN1UytGZ2drYmhVcXNNZ1Vkd2JOMWswZXYxTEtNUGdqME1LNjZYMTdZVWhoQjV1enNUZ0hlTUNPRkoKMG1waUx4OWUrcFpvMzRrbmxUaWZCdGMreWNzbVdRMXozckRJNlNZT2d4WEc3MXVMMGdSZ3lrbW1LUFpwTy9iTHlDaVI1WjJLWVZjMwpySFFVM0hUZ091NXlMeTZjKzlDN3YvVTlBT0VHTStpQ0s2NVRwam9XYzR6ZFFRNGdPc0MwcDZIcHNrK1FMakpnNlZmTHVRU1NhR2psCk9DWmdkYktmZC8rUkZPK3VJRW44clVBVlNORUNNV0VaWHJpWDc2MTN0MlNhZXI5ZndSUHZtMkw3RFd6Z1ZHa1dxUVBhYnVtRGszRjIKeG1tRmdoY0NBd0VBQWFOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRQpGSS93UzMrb0xrVWtyazFRK21PYWk5N2kzUnU4TUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCTFFOdkFVS3IreUF6djk1WlVSVW03CmxnQUpRYXl6RTRhR0tBY3p5bXZtZExtNkFDMnVwQXJUOWZIeEQ0cS9jMmRLZzhkRWUzamdyMjVzYndNcGpqTTVSY09PNUxsWGJLcjgKRXBic1U4WXQ1Q1JzdVpSais5eFRhR2RXUG9PNHp6VWh3OGxvL3M3YXdsT3F6SkNLNmZCZFJveVYzWHBZS0JvdkhkN05BRGRCaisxRQpiZGRUS0pkKzgyY0VIaFhYaXBhMDA5NU1KNlJNRzNOemR2UVhtY0lmZWc3akxRaXRDaHdzL3p5clZRNFBrWDQyNjhOWFNiN2hMaTE4CllJdkRRVkVUSTUzTzl6SnJsQUdvbWVjc014ODZPeVhTaGtET095eUdlTWxoTHhTNjd0dFZiOStFN2dVSlRiMG8ySExPMDJKUVpSN3IKa3BlRE1kbXp0Y3BIV0Q5ZgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHRkRDQ0EveWdBd0lCQWdJSVUrdzc3dnV5U0Y4d0RRWUpLb1pJaHZjTkFRRUZCUUF3VVRFTE1Ba0dBMVVFQmhNQ1JWTXhRakJBCkJnTlZCQU1NT1VGMWRHOXlhV1JoWkNCa1pTQkRaWEowYVdacFkyRmphVzl1SUVacGNtMWhjSEp2Wm1WemFXOXVZV3dnUTBsR0lFRTIKTWpZek5EQTJPREFlRncwd09UQTFNakF3T0RNNE1UVmFGdzB6TURFeU16RXdPRE00TVRWYU1GRXhDekFKQmdOVkJBWVRBa1ZUTVVJdwpRQVlEVlFRREREbEJkWFJ2Y21sa1lXUWdaR1VnUTJWeWRHbG1hV05oWTJsdmJpQkdhWEp0WVhCeWIyWmxjMmx2Ym1Gc0lFTkpSaUJCCk5qSTJNelF3Tmpnd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUURLbG11TzZ2ajc4YUkxNEg5TTJ1REQKVXRkOXRoRElBbDZ6UXlyRVQycXl5aHhkS0pwNEVScHBXVmV2dFNCQzVJc1A1dDlicGdPU0wvVVI1R0xYTW5FNDJRUU1jYXM5VVg0UApCOTlqQlZ6cHY1UnZ3U21Dd0xUYVViREJQTHV0TjBwY3l2RkxOZzRrcTcvRGhIZjlxRkQwc2VmR0w5SXRXWTE2Q2s2V2FWSUNxamFZCjdQejZGSU1NTngvSmtqZC8xNEV0NWNTNTRENDAvbWYwUG1iUjAvUkF6MTVpTkE5d0JqNGdHRnJPOTNJYkpXeVRkQlNUbzNPeERxcUgKRUNOWlh5QUZHVWZ0YUk2U0VzcGQvTllyc3BJOElNL2hYNjhndnFCMmYzYmw3QnFHWVRNKzUzdTBQNkFQanFLNWFtKzVoeVp2UVd5SQpwbEQ5YW1NTDlaTVdHeG1Qc3UyYm04bVE5UUVNM3hrOUR6NDRJOGt2and6UkF2NGJWZFpPMEkwOHIwK2s4LzZ2S3RNRm5Ya0lvY3RYCk1iU2N5SkN5Wi9RWUZwTTYvRWZZMFhpV01SKzZLd3hmWFptdFk0bGFKQ0IyMk4vOXEwNm1JcXFkWHVZbmluMW9LYVBuaXJqYUVic1gKTFptZEV5Ukc5OFhpMkorT2Y4ZVBkRzFhc3VoeTlhenVKQkN0THhUYS95MmFSbkZIdmtMZnV3SGI5SC9US0k4eFdWdlR5UUttdEZMSwpicGY3UThVSUptK0s5THY5bnlpcURkVkY4eE02SGRqQWVJOUJaendlbEdTdWV3dkY2TmtCaURrYWw0WmtRZFU3aHd4dStnL0d2VWdVCnZ6bE4xSjVCdG8rV0hXT1drOW1WQm5neGFKNDNCanVBaVVWaE9TUEhHMFNqRmVVYytKSXd1d0lEQVFBQm80SHZNSUhzTUJJR0ExVWQKRXdFQi93UUlNQVlCQWY4Q0FRRXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCUmx6ZXVyTlI0QVBuN1ZkTUFjdEhOSApEaHBrTHpDQnBnWURWUjBnQklHZU1JR2JNSUdZQmdSVkhTQUFNSUdQTUM4R0NDc0dBUVVGQndJQkZpTm9kSFJ3T2k4dmQzZDNMbVpwCmNtMWhjSEp2Wm1WemFXOXVZV3d1WTI5dEwyTndjekJjQmdnckJnRUZCUWNDQWpCUUhrNEFVQUJoQUhNQVpRQnZBQ0FBWkFCbEFDQUEKYkFCaEFDQUFRZ0J2QUc0QVlRQnVBRzhBZGdCaEFDQUFOQUEzQUNBQVFnQmhBSElBWXdCbEFHd0Fid0J1QUdFQUlBQXdBRGdBTUFBeApBRGN3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUJkOW9QbTAzY1hGNjYxTEpMV2hBcXZkcFloS3NnOVZTeXRYakR2bE1kMyt4REx4CjUxdGtsall5R095bE1uZlg0MFMyd0JFcWdMazlhbTU4bTlPdC9NUFdvK1prS1h6UjRUZ2VnaXYvSjJXdit4WVZ4QzV4aE9XMS8vcWsKUjcxa01ydjJKWVNpSjBMMUlMRENFeEFSelJBVnVrS1FLdEpFNFpZbTZ6RklFdjBxMnNrR3ozUWVxVXZWaHlqNWVUU1NQaTVFNlBhUApUNDgxUHlXek9keGpLcEJySUYvRVVoSk9seXdxckoyWDNranlvMmJid3RLRGxhWm1wNTRsRCtrTE01RmxDbHJEMlZRUzNhL0RUZzRmCkpsNE4zTE9ON05XQmNON1NUeVFGODJ4TzlVeEpabzNSLzlJTEpVRkkvbEdFeGtLdmdBVFAwSDVrU2VUeTM2THNzVXpBS2gzbnRMRmwKb3NTODhaajBxbkFIWTdTNDJqdE0ra0FpTUZzUnB2QUZEc1lDQTBpcmhwdUYzZHZkNnFKMmdITjk5WndFeEVXTjU3a2NpNTdxMTNYUgpjckhlZFVUblFuM2lWMnQ5M0ptOFBZTW82b0NUamNWTVpjRndnYmc0L0VNeHN2WURORWV5clBzaUJzc2UzUmRISEY5bXVkTWFvdG9SCnNhUzhJOG5rdm9mL3VaUzIrRjBnU3RSZjU3MW9lMlh5RlI3U09xa3Q2ZGhySkt5WFdFUkhyVmtZOFNGbGNON09OR0NvUVBIelBLVEQKS0NPTS9pY3pRMENnRnp6cjZqdXdjcWFqdVVwTFhoWkk5TEs4eUl5U3haMmZySEkydkRTQU5HdXBpNUxBdUJmdDdIWlQ5U1FCakxNaQo2RXQ4VmNhZCtxTVV1MldGYm01UEVuNEtQSjJWCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkl6ZW5wZS5jb20KPT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjhUQ0NBOW1nQXdJQkFnSVFBTEMzV2haSVg3L2h5L1dMMXhubWZUQU5CZ2txaGtpRzl3MEJBUXNGQURBNE1Rc3dDUVlEVlFRRwpFd0pGVXpFVU1CSUdBMVVFQ2d3TFNWcEZUbEJGSUZNdVFTNHhFekFSQmdOVkJBTU1Da2w2Wlc1d1pTNWpiMjB3SGhjTk1EY3hNakV6Ck1UTXdPREk0V2hjTk16Y3hNakV6TURneU56STFXakE0TVFzd0NRWURWUVFHRXdKRlV6RVVNQklHQTFVRUNnd0xTVnBGVGxCRklGTXUKUVM0eEV6QVJCZ05WQkFNTUNrbDZaVzV3WlM1amIyMHdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFESgowM3JLRHg2c3A0Ym9GbVZxc2NJYlJUSnhsZG4rRUZ2TXIrZWxlUUdQaWNQSzhsVng5M2UrZDVUemNxUXNSTmlla3BzVU9xSG5KSkFLCkNsYU94ZGdtbE9IWlNPRXRQdG9LY3Qyam1SWGFnYUtIOUh0dUpuZUpXSzNXNnd5eVFYcHpibTNiZW5oQjZRaUlFbjZITG1ZUlkyeFUKK3p5ZGNzQzhMdi9DdDkwTmR1TTYxL2UwYUw2aTllT0Jic0ZHYjEyTjRFM0dWRldKR2pNeENyRlh1YU9LbU1Qc096VEZsVUZwZm5YQwpQQ0RGWWJwUlI2QWdrSk9oa0V2elRueUZSVlNhMFFVbVFiQzFUUjB6dnNRRHlDVjh3WERiTy9RSkxWUW5TS3d2NGNTc1Bzakxra3hUCk9UY2o3Tk1CK2VBSlJFMU5aTURoRFZxSElyeXRHNlArSnJVVjg2ZjhoQm5wN0tHSXRFUnBoSVB6aWRGMEJxbk1DOWJDM2llRlVDYksKRjdqSmVvZFdMQm9CSG15K0U2MFFyTFVrOVRpUm9kWkwydkc3MHQ1SHRmRzhnZlpaYTg4WlUrbU5GY3RLeTZsdlJPVWJRYy9oaHFmSwowR3FmdkV5TkJqTmFvb1hsa0RXZ1lsd1dUdkRqb3ZvREdyUXNjYk5ZTE41N0M5c2FEK3ZlSVI4R2R3WURzTW52bWZ6QXVVOExoaWorCjBybnE0OXFsdzBkcEV1RGI4UFlaaSsxN2NOY0MxdTJIR0Nnc0JDUk1kK1JJaWhyR081clVEOHI2ZGRJQlFGcU5lYitMejB2UHFoYkIKbGVTdFRJbytGNUhVc1dMbGd1V0FCS1FEZm8yLzJuK2lENWRQRE5NTis5ZlI1WEorSE1oMy8xdWFEN2V1QlVibDhhZ1c3RWVrRndJRApBUUFCbzRIMk1JSHpNSUd3QmdOVkhSRUVnYWd3Z2FXQkQybHVabTlBYVhwbGJuQmxMbU52YmFTQmtUQ0JqakZITUVVR0ExVUVDZ3crClNWcEZUbEJGSUZNdVFTNGdMU0JEU1VZZ1FUQXhNek0zTWpZd0xWSk5aWEpqTGxacGRHOXlhV0V0UjJGemRHVnBlaUJVTVRBMU5TQkcKTmpJZ1V6Z3hRekJCQmdOVkJBa01Pa0YyWkdFZ1pHVnNJRTFsWkdsMFpYSnlZVzVsYnlCRmRHOXlZbWxrWldFZ01UUWdMU0F3TVRBeApNQ0JXYVhSdmNtbGhMVWRoYzNSbGFYb3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPCkJCWUVGQjBjWlE2bzhpVjd0SkhQNUxHeDVyMVZkR3dGTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElDQVFCNHBnd1dTcDlNaURyQXl3NmwKRm4yZnVVaGZHSThOWWpiMnpSbHJyS3ZWOXBGOXJuSHpQN01PZUlXYmxhUW5JVWRDU254SU92VkZmTE1NamxGNHJKVVQzc2I5ZmJnYQprRXlya2dQSDdVSUJ6Zy9Zc2ZxaWt1RmdiYTU2YXdtcXhpbnVhRWxuTUlBa2VqRVdPVnQrOFJ3dTNXd0pyZkl4d1lKT3VidjV2cjhxCmhUL0FRS002V2Z4WlN6d29KTnUwRlhXdURZaTZMblBBdlZpSDVVTHk2MTd1SGpBaW1jczMwY1FoYklIc3ZtMG01aHprUWlDZVI3Q3MKZzFsd0xEWFdyelkwdE0wNytES283K040aWZ1TlJTemFuTGgrUUJ4aDV6NmlraXhMOHMzNm1MWXAvL1B5ZTZrZkxxQ1RWeXZlaFFQNQphVGZMbm5ocUJiVEZNWGlKN0hxbmhlRzVlenpldmg1NWhNNmZjQTVad2pVdWtDb3gyZVJGZWtHa0xoT2JOQTVtZTBtclpKZlFSc041Cm5YSlFZNmFZV3dhOVNHM1lPWU53NkRYd0JkR3F2T1BieUFMcWZQMkMyc0piVWpXdW1EcXR1aldUSTZjZlNOMDFScGl5RUdqa3BUSEMKQ2xndUdZRVF5VkIxL09wYUZzNFIxKzd2VUlndFlmOC9Rbk1GbEVQVmpqeE9BVG9acFI5R1RuZlFYZVdCSWlHSC9wUjloTmlUcmRabwpRMGl5Mit0ekpPZVJmMVNrdG9BK25hTThUSExDVjhTZzFNdzRKODdWQnA2aVNObnBuODZDY0RhVG1qdmZsaUhqV2JjTTJwRTM4UDFaCldyT1p5R2xzUXlZQk5XTmdWWWtET25YWXVrclpWUC91M29EWUxkRTQxVjR0QzVoOVBtemIvQ2FJeHc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDaGFtYmVycyBvZiBDb21tZXJjZSBSb290IC0gMjAwOAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJSFR6Q0NCVGVnQXdJQkFnSUpBS1BhUW42a3NhN2FNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR3VNUXN3Q1FZRFZRUUdFd0pGVlRGRApNRUVHQTFVRUJ4TTZUV0ZrY21sa0lDaHpaV1VnWTNWeWNtVnVkQ0JoWkdSeVpYTnpJR0YwSUhkM2R5NWpZVzFsY21acGNtMWhMbU52CmJTOWhaR1J5WlhOektURVNNQkFHQTFVRUJSTUpRVGd5TnpRek1qZzNNUnN3R1FZRFZRUUtFeEpCUXlCRFlXMWxjbVpwY20xaElGTXUKUVM0eEtUQW5CZ05WQkFNVElFTm9ZVzFpWlhKeklHOW1JRU52YlcxbGNtTmxJRkp2YjNRZ0xTQXlNREE0TUI0WERUQTRNRGd3TVRFeQpNamsxTUZvWERUTTRNRGN6TVRFeU1qazFNRm93Z2E0eEN6QUpCZ05WQkFZVEFrVlZNVU13UVFZRFZRUUhFenBOWVdSeWFXUWdLSE5sClpTQmpkWEp5Wlc1MElHRmtaSEpsYzNNZ1lYUWdkM2QzTG1OaGJXVnlabWx5YldFdVkyOXRMMkZrWkhKbGMzTXBNUkl3RUFZRFZRUUYKRXdsQk9ESTNORE15T0RjeEd6QVpCZ05WQkFvVEVrRkRJRU5oYldWeVptbHliV0VnVXk1QkxqRXBNQ2NHQTFVRUF4TWdRMmhoYldKbApjbk1nYjJZZ1EyOXRiV1Z5WTJVZ1VtOXZkQ0F0SURJd01EZ3dnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDCkFRQ3ZBTXR3Tnl1QVdrbzZiSGlVZmFOL0doLzJOZFc5MjhzTlJISStKcktRVXJwak95aFliNld6YlpTbTg5MWtERlgyOXVmeUlpS0EKWHVGaXhyWXA0WUZzOHIvbGZUSnFWS0F5R1ZuK0g0dlhQV0NHaFNSdjR4R3pkejRnbGpVaGE3TUkyWEF1WlBlRWtsUFdEckNRaW9yagpoNDBHMDcyUUR1S1pvUnVHRHRxYUNyc0xZVkFHVXZHZWYzYnN5dy9RSGczUG1UQTlITVJGRUZpczF0UG8xK1hxeFFFSGQ5WlI1Z04vCmlraWxUV2gxdWVtOG5rNFpjZlV5UzV4dFlCa0wrOHlkZGR5L0pzMlBrM2c1ZVhOZUpRN0tYT3QzRWdmTFpFRkhjcE9yVU1QckNYWmsKTk5JNXQzWVJDUTEyUmNTcHJqMXFyN1Y5WlMrVVdCRHNYSHl2ZnVLMkdOblFtMDVhU2QrcFpndk1QTVo0ZktlY0hlUE9qbE8rQmQ1ZwpEMnZsR3RzLzQrRWh5U25COGVzSG5GSWJBVVJSUEhzbDE4VGxVbFJkSlFmS0ZpQzRyZVJCN25vSS9wbHZnNmFSQXJCc05sVnE1MzMxCmx1YktnZGFYOFpTRDZlMndzV3NTYVI2cysxMnB4WmpwdEZ0WWVyNDlva1E2WTFuVUN5WGVHMCs5NVFHZXpkSXAxWjhYR1FwdnZ3eVEKMHdsZjJlT0tOY3g1V2swWk41SzN4TUd0ci9SNUpKcXlBUXV4cjF5Vzg0QXkrMXc5bVBHZ1AwcmV2cStVTHRsVm1oZHVZSjFqYkxoagp5YTZCWEJnMTRKQzd2anhQTnlLNWZ1dlBubmNocGowNGdmdEkyakU5SytPSjlkQzF2WDdnVU1RU2liTWptaEF4aGR1dWIrODRNeGgyCkVRSURBUUFCbzRJQmJEQ0NBV2d3RWdZRFZSMFRBUUgvQkFnd0JnRUIvd0lCRERBZEJnTlZIUTRFRmdRVStTU3NEN0sxK0huQSttQ0kKRzhUWlRRS2VGeGt3Z2VNR0ExVWRJd1NCMnpDQjJJQVUrU1NzRDdLMStIbkErbUNJRzhUWlRRS2VGeG1oZ2JTa2diRXdnYTR4Q3pBSgpCZ05WQkFZVEFrVlZNVU13UVFZRFZRUUhFenBOWVdSeWFXUWdLSE5sWlNCamRYSnlaVzUwSUdGa1pISmxjM01nWVhRZ2QzZDNMbU5oCmJXVnlabWx5YldFdVkyOXRMMkZrWkhKbGMzTXBNUkl3RUFZRFZRUUZFd2xCT0RJM05ETXlPRGN4R3pBWkJnTlZCQW9URWtGRElFTmgKYldWeVptbHliV0VnVXk1QkxqRXBNQ2NHQTFVRUF4TWdRMmhoYldKbGNuTWdiMllnUTI5dGJXVnlZMlVnVW05dmRDQXRJREl3TURpQwpDUUNqMmtKK3BMR3UyakFPQmdOVkhROEJBZjhFQkFNQ0FRWXdQUVlEVlIwZ0JEWXdOREF5QmdSVkhTQUFNQ293S0FZSUt3WUJCUVVICkFnRVdIR2gwZEhBNkx5OXdiMnhwWTNrdVkyRnRaWEptYVhKdFlTNWpiMjB3RFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUpBU3J5STEKd3FNNThDN2U2YlhwZUh4SXZqOTlSWkplNmRxeEdmd1dQSiswVzJhZWF1ZkR1VjJJNkErdHp5TVAzaVU2WHN4UHBjRzFMYXdrMGxnSAozcUxQYVlSZ00rZ1FEUk9wSTlDRjVZNTdwcDQ5Y2hOeU0vV3FmY1pqSHdqMC9nRi9KTThyTEZRSjN1SXJiWkxHT1U4VzZqeCtla2JVClJXcEdxT3QxZ2xhbnE2QjhhQk16OXAwdzhHOG5PU1FqS3BEOWtDazE4cFBmTktYRzkvanZqQTlpU255dTAvVlUrSTIybWxhSEZvSTYKTTZ0YUlnajNncnJxTHVCSG1yUzFSYU1GTzluY0xrVkFPK3JjZitnNzY5SHNKdGcxcERERk9xeFhuck4ycFNCNytSNUtCV0lCcGloMQpZSmVTRFc0K1RUZEREWklWbkJnaXpWR1pvQ2thUEYrS01qTmJNTWVKTDBlWUQ2TUR4dmJ4ck44eThObUJHdVNjdmZhQUZQRFJMTG1GCjlkaWpzY2lsSWVVY0U1ZnVEcjNmS2Fudk5GTmIwK1JxRTRRR3RqSUN4Rkt1SXRMY3NpRkNHdHBBOENuSjdBb01YT0xRdXN4STB6Y0sKekJJS2lubXdQUU4vYVV2ME5DQjlzelRxamt0azlUNzlzeU5uRlEwRXVQQXR3UWxSUExKc0ZmQ2xJOWVEZE9UbExzbittQ2RDeHF2RwpuckRRV3ppbG0xRGVmaGlZdFVVNzlubTA2UGNhZXdhRCs5Q0wycnZIdlJpckNHODhnR3RBUHhrWnVtV0s1cjdWWE5NMjErOUFVaVJnCk9HY0VNZXlQODRMRzNybFY4enN4a1ZyY3RRZ1ZyWFlsQ2cxN0xvZmlES1lHdkNZUWJUZWQ3TjE0akh5QXhmRFpkMGpRCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUhTVENDQlRHZ0F3SUJBZ0lKQU1uTjArblZmU1BPTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdzTVFzd0NRWURWUVFHRXdKRlZURkQKTUVFR0ExVUVCeE02VFdGa2NtbGtJQ2h6WldVZ1kzVnljbVZ1ZENCaFpHUnlaWE56SUdGMElIZDNkeTVqWVcxbGNtWnBjbTFoTG1OdgpiUzloWkdSeVpYTnpLVEVTTUJBR0ExVUVCUk1KUVRneU56UXpNamczTVJzd0dRWURWUVFLRXhKQlF5QkRZVzFsY21acGNtMWhJRk11ClFTNHhKekFsQmdOVkJBTVRIa2RzYjJKaGJDQkRhR0Z0WW1WeWMybG5iaUJTYjI5MElDMGdNakF3T0RBZUZ3MHdPREE0TURFeE1qTXgKTkRCYUZ3MHpPREEzTXpFeE1qTXhOREJhTUlHc01Rc3dDUVlEVlFRR0V3SkZWVEZETUVFR0ExVUVCeE02VFdGa2NtbGtJQ2h6WldVZwpZM1Z5Y21WdWRDQmhaR1J5WlhOeklHRjBJSGQzZHk1allXMWxjbVpwY20xaExtTnZiUzloWkdSeVpYTnpLVEVTTUJBR0ExVUVCUk1KClFUZ3lOelF6TWpnM01Sc3dHUVlEVlFRS0V4SkJReUJEWVcxbGNtWnBjbTFoSUZNdVFTNHhKekFsQmdOVkJBTVRIa2RzYjJKaGJDQkQKYUdGdFltVnljMmxuYmlCU2IyOTBJQzBnTWpBd09EQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU1EZgpWdFBrT3B0MlJiUVQyLy9CdGhtTE4wRVlsVkpINnhlZEtZaU9OV3dHTWk1SFl2TkpCTDk5UkRheGNjeTlXZ2x6MWRtRlJQK1JWeVhmClhqYU9jTkZjY1VNZDJkcnZYTkw3RzcwNnRjdXRvOHhFcHcydUlSVS91WHBia25YWXBCSTRpUm1LdDREUzRqSnZWcHlSMW9nUUM3TjAKWkpKMFlQUDJ6eGhQWUxJajBNYzd6bUZMbVkvQ0ROQkFzcGpjRGFoT283a0tybUNnclVWU1k3cG12V2pnK2I0YXFJRzdIa0Y0ZGRQQgovZ0JWc0lkVTZDZVFOUjFNTTYyWC9KY3VtSVMvTE1tanY5R1lFUlR0WS9qS21JaFlGNW50UlFPWGZqeUdIb2lNdnZLUmhJOWxOTmdBClRIMjNNUmRhS1hvS0dDUXdvemUxZXFrQmZTYlcrUTZPV2ZIOUd6TzFLVHNYTzBHMklkM1V3RDJsbjU4ZlExREp1N3hzZXBlWTdzMk0KSC91Y1VhNkxjTDBubjNIQWE2eDlrR2JvMTEwNkRiRFZ3bzNWeUoyZHdXM1EwTDlSNU9QNHd6ZzJydGFuZGVhdmhFTmRrNUlNYWdmZQpPeDJZSXRhc3dUWGJvNkFsLzNLMWRoM2ViZWtzWml4U2hOQkZrczRjNWVVekhkd0hVMVNqcW9JN21qY3YzTjJnWk9ubTNiMnUvR1NGCkhUeW55UWJlaFA5cjZHc2FQTVdpczBMN2l3aytYd2hTeDJMRTFBVnh2OFJrNVBpaGcrZytFcHVvSHRRMlRTOXg5bzBvOW9PcEU5SmgKd1pHN1NNQTBqMEdNUzB6YmFSTC9VSlNjSUlOWmMrMThvZkx4L2QzM1NkTkRXS0JXWThvOVBlVTFWbG5wRHNvZ3pDdExreWtQQWdNQgpBQUdqZ2dGcU1JSUJaakFTQmdOVkhSTUJBZjhFQ0RBR0FRSC9BZ0VNTUIwR0ExVWREZ1FXQkJTNUNjcWNIdHZUYkRwcnJ1MVU4VnVUCkJqVXVYakNCNFFZRFZSMGpCSUhaTUlIV2dCUzVDY3FjSHR2VGJEcHJydTFVOFZ1VEJqVXVYcUdCc3FTQnJ6Q0JyREVMTUFrR0ExVUUKQmhNQ1JWVXhRekJCQmdOVkJBY1RPazFoWkhKcFpDQW9jMlZsSUdOMWNuSmxiblFnWVdSa2NtVnpjeUJoZENCM2QzY3VZMkZ0WlhKbQphWEp0WVM1amIyMHZZV1JrY21WemN5a3hFakFRQmdOVkJBVVRDVUU0TWpjME16STROekViTUJrR0ExVUVDaE1TUVVNZ1EyRnRaWEptCmFYSnRZU0JUTGtFdU1TY3dKUVlEVlFRREV4NUhiRzlpWVd3Z1EyaGhiV0psY25OcFoyNGdVbTl2ZENBdElESXdNRGlDQ1FESnpkUHAKMVgwanpqQU9CZ05WSFE4QkFmOEVCQU1DQVFZd1BRWURWUjBnQkRZd05EQXlCZ1JWSFNBQU1Db3dLQVlJS3dZQkJRVUhBZ0VXSEdoMApkSEE2THk5d2IyeHBZM2t1WTJGdFpYSm1hWEp0WVM1amIyMHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnSUJBSUNJZjNEZWtpalpCWlJHCi81QlhxZkV2M3hvTmEvcDhEaHhKSkhrbjJFYXFieWxaVW9od0V1cmRQZldiVTFSdjRXQ2lxQW01N090WmZNWTE4ZHdZNmZGbjVhKzYKUmVBSjNzcEVEOElYRG5lUlJYb3pYMStXTEdpTHdVZVBtSnM5d096TDlkV0Nrb1ExMGI0Mk9GWnlNVnRITGFvWHBHTlI2d29CclgvcwpkWjdMb1IveGZ4S3h1ZVJrZjJmV0l5cjB1RGxkbU9naHArRzlQVUlhZEpwd3IyaHNVRjFKei8vN0RsM21MRWZYZ1RwWkFMVnphMk1nCjlqRkZDRGtPOUhCK1FIQmFQOUJyUXFsMFBTZ3ZBbTExY3BVSmpVaGp4c1lqVjVLVFhqWEJqZmtLOXl5ZFloejJyWHpkcGpFZXRySEgKZm9VbStxUnF0ZHBqTU5Idmt6ZXlaaTk5QmZmbnQwdVlsRFhBMlRvcHdaMnlVRE1kU3FsYXBza0Q3KzMwNTZodWlyUlhoT3VrUDlEdQpxcXFIVzJQb2srSnJxTlM0Y25ockcrMDU1RjNMbTZxSDFVOU9BUDdaYXA4OE1ROG9BZ0Y5bU9pbnNLSmtubm40U1BJVnFjem15RVRyClAzaVo4bnR4UGp6eG1LZkZHQkkvNXJzb00wTHBSUXA4YmZLR2VTL0ZnaGw5Q1lsOHNsUjJpSzdld2ZQTTRXN2JNZGFUcnBtZzd5VnEKYzVpSld6b3VFNGdldjhDU2xEUWI0eWUzaXg1dlF2L242VGViVUIwdG92a0M3c3RZV0RweHZHampxc0d2SENnZm90d2paVCtCNnE2WgowOWd3enhNTlR4WEpoTHluU0MzNE1DTjMyRVpMZVczMmpPMDZmMkFSZVBUcG02N1ZWTUIwZ05FTFFwL0IKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEeFRDQ0FxMmdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURDQmd6RUxNQWtHQTFVRUJoTUNWVk14RURBT0JnTlZCQWdUCkIwRnlhWHB2Ym1FeEV6QVJCZ05WQkFjVENsTmpiM1IwYzJSaGJHVXhHakFZQmdOVkJBb1RFVWR2UkdGa1pIa3VZMjl0TENCSmJtTXUKTVRFd0x3WURWUVFERXloSGJ5QkVZV1JrZVNCU2IyOTBJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZjbWwwZVNBdElFY3lNQjRYRFRBNQpNRGt3TVRBd01EQXdNRm9YRFRNM01USXpNVEl6TlRrMU9Wb3dnWU14Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lEVlFRSUV3ZEJjbWw2CmIyNWhNUk13RVFZRFZRUUhFd3BUWTI5MGRITmtZV3hsTVJvd0dBWURWUVFLRXhGSGIwUmhaR1I1TG1OdmJTd2dTVzVqTGpFeE1DOEcKQTFVRUF4TW9SMjhnUkdGa1pIa2dVbTl2ZENCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcGRIa2dMU0JITWpDQ0FTSXdEUVlKS29aSQpodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUw5eFlnangrbGswOXh2SkdLUDNnRWxZNlNLREU2YkZJRU1CTzRUeDVvVkpueWZxCjlvUWJUcUMwMjNDWXh6SUJzUVUrQjA3dTlQcFBMMWt3SXVlckdWWnI0b0FIL1BNV2RZQTVVWHZsK1RXMmRFNnBqWUlUNUxZL3FRT0QKK3FLK2loVnFmOTRMdzdZWkZBWEs2c09vQkpRN1Jud3lEZk1BWmlMSWpXbHROb3dSR0xmVHNoeGd0RGo2QW96TzA5MUdCOTRLUHV0ZApmTWg4KzdBclU2U1NZbWxSSlFWaEdrU0JqQ3lwUTVZajM2dzZnWm9PS2NVY3FlbGRIcmFlbmpBS09jN3hpSUQ3UzEzTU11eUZZa01sCk5BSldKd0dSdER0d0tqOXVzZWljaUFGOW45VDUyMU50WUoyL0xPZFlxN2hmUnZ6T3hCc0RQQW5yU1RGY2FVYXo0RWNDQXdFQUFhTkMKTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFRkRxYWhRY1FaeWkyNy9hOQpCVUZ1SU1HVTJnL2VNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNaMjExNTFmbVhXV2NEWWZGK093WXhkUzJoSUk1UFpZZTA5NmFjCnZOanBMOURiV3U3UGRJeHp0RGhDMmdWNytBSjF1UDJsc2RldTl0ZmVFOHRURUg2S1J0R1grcmN1S3hHcmtMQW5nUG5vbjFycE41K3IKNU45c3M0VVhuVDNaSkU5NWtUWFdYd1RyZ0lPcm1nSXR0UkQwMkpESEJITkE3WElsb0ttZjdKNnJhQktaVjhhUEVqb0pwTDFFL1FZVgpOOEdiNURLajdUam8yR1R6TEg0VS9BTHFuODMvQjJnWDJ5S1FPQzE2amRGVThXbmpYelBLZWoxN0N1UEtmMTg1NWVKMXVzVjJHRFBPCkxQQXZUSzMzc2VmT1Q2akVtMHBVQnNWL2ZkVUlEK0ljL240WHVLeGU5dFFXc2tNSkRFMzJwMnUwbVlSbHlucUk0dUpFdmx6MzZoejEKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU3RhcmZpZWxkIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQzVENDQXNXZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBRENCanpFTE1Ba0dBMVVFQmhNQ1ZWTXhFREFPQmdOVkJBZ1QKQjBGeWFYcHZibUV4RXpBUkJnTlZCQWNUQ2xOamIzUjBjMlJoYkdVeEpUQWpCZ05WQkFvVEhGTjBZWEptYVdWc1pDQlVaV05vYm05cwpiMmRwWlhNc0lFbHVZeTR4TWpBd0JnTlZCQU1US1ZOMFlYSm1hV1ZzWkNCU2IyOTBJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZjbWwwCmVTQXRJRWN5TUI0WERUQTVNRGt3TVRBd01EQXdNRm9YRFRNM01USXpNVEl6TlRrMU9Wb3dnWTh4Q3pBSkJnTlZCQVlUQWxWVE1SQXcKRGdZRFZRUUlFd2RCY21sNmIyNWhNUk13RVFZRFZRUUhFd3BUWTI5MGRITmtZV3hsTVNVd0l3WURWUVFLRXh4VGRHRnlabWxsYkdRZwpWR1ZqYUc1dmJHOW5hV1Z6TENCSmJtTXVNVEl3TUFZRFZRUURFeWxUZEdGeVptbGxiR1FnVW05dmRDQkRaWEowYVdacFkyRjBaU0JCCmRYUm9iM0pwZEhrZ0xTQkhNakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMM3R3UVA4OW8vOEFyRnYKVzU5STJaMTU0cUszQTJGV0dNTkh0dGZLUFRVdWlVUDNvV21iM29vYS9STWduTFJKZHpJcFZ2MjU3SXpkSXZweTNDZGhsKzcyV29UcwpiaG01aVN6Y2hGdlZkUHRyWDhXSnBSQlNpVVpWOUxoMUhPWi81RlN1Uy9oVmNsY0NHZmdYY1ZuckhpZ0hkTVdkU0w1c3RQU2tzUE5rCk4zbVN3T3hHWG4vaGJWTk1ZcS9OSHd0anV6cWQrL3g1QUpoaGRNOG1na0JqODdKeWFoa05tY3JVRG5YTU4vdUxpY0ZaOFdKL1g3TmYKWlRENHA3ZE5kbG9lZGw0MHdPaVdWcG1Lcy9CL3BNMjkzREl4ZkpIUDRGOFIrR3VxU1Z6Um1aVFJvdU5qV3dsMnRWWmk0VXQwSFpiVQpKdFFJQkZuUW1BNE81dDc4dyt3ZmtQRUNBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DCkFRWXdIUVlEVlIwT0JCWUVGSHdNTWgrbjJUQi94SDFvbzJLb29jNnJCMXNuTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBUldmb2wKVHdOdmxKazdtaCtDaFRuVWRnV1VYdUVvazIxaVhRbkNvS2pVc0hVNDhUUnFuZVNmaW9ZbVVlWXMwY1l0YnBVZ1NwSUI3TGlLWjNzeAo0bWN1akpVREppNURuVW94OWc2MURMdTM0amQvSXJvQW93NTdVdnRydXp2RTAzbFJUczJROUdjSEdjZzhSbm9OQVgzRldPZHQ1b1V3CkY1b2t4QkRnQlBmZzhuL1VxZ3IvUWgwMzdaVGxaRmtTSUhjNDB6SStPSUYxbG5QNmFJK3h5ODRmeGV6Nm5IN1Bmckh4QnkyMi9ML0sKcEwvUWx3Vkt2T29ZS0FLUXZWUjRDU0Z4MDlGOUhka1dzS2xoUGRBS0FDTDh4M3ZMQ1dSRkN6dEFnZmQ5ZkRMMW1NcFlqbjBxN3BCWgpjMlQ1Tm5SZUphSDFaZ1V1ZnprVnFTcjdVSXVPaFduMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTdGFyZmllbGQgU2VydmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRDd6Q0NBdGVnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFzRkFEQ0JtREVMTUFrR0ExVUVCaE1DVlZNeEVEQU9CZ05WQkFnVApCMEZ5YVhwdmJtRXhFekFSQmdOVkJBY1RDbE5qYjNSMGMyUmhiR1V4SlRBakJnTlZCQW9USEZOMFlYSm1hV1ZzWkNCVVpXTm9ibTlzCmIyZHBaWE1zSUVsdVl5NHhPekE1QmdOVkJBTVRNbE4wWVhKbWFXVnNaQ0JUWlhKMmFXTmxjeUJTYjI5MElFTmxjblJwWm1sallYUmwKSUVGMWRHaHZjbWwwZVNBdElFY3lNQjRYRFRBNU1Ea3dNVEF3TURBd01Gb1hEVE0zTVRJek1USXpOVGsxT1Zvd2daZ3hDekFKQmdOVgpCQVlUQWxWVE1SQXdEZ1lEVlFRSUV3ZEJjbWw2YjI1aE1STXdFUVlEVlFRSEV3cFRZMjkwZEhOa1lXeGxNU1V3SXdZRFZRUUtFeHhUCmRHRnlabWxsYkdRZ1ZHVmphRzV2Ykc5bmFXVnpMQ0JKYm1NdU1Uc3dPUVlEVlFRREV6SlRkR0Z5Wm1sbGJHUWdVMlZ5ZG1salpYTWcKVW05dmRDQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGtnTFNCSE1qQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQwpBUW9DZ2dFQkFOVU1Pc1FxK1U3aTliNFpsMStPaUZPeEh6L0x6NThnRTIwcE9zZ1BmVHozYTNZNFk5azJZS2liWGx3QWdMSXZXWC8yCmgva2xRNGJuYVJ0U21wRGhjZVBZTFExT2IvYklTZG0yOHhwV3JpdTJkQlRyei9zbTR4cTZIWll1YWp0WWxJbEhWdjhsb0pOd1U0UGEKaEhRVXcyZWVCR2c2MzQ1QVdoMUtUczlEa1R2blZ0WUFjTXRTN250OXJqcm52REg1UmZiQ1lNOFRXUUlyZ013MFI5KzUzcEJsYlFMUApMSkdtcHVmZWhSaEpmR1pPb3pwdHFiWHVOQzY2RFFPNE05OUg2N0ZyalNYWm04NkIwVVZHTXBad2g5NENEa2xEaGJac2M3dGs2bUZCCnJNblVWTitITDhjaXNpYk1uMWxVYUovOHZpb3Z4RlVjZFVCZ0Y0VUNWVG1MZndVQ0F3RUFBYU5DTUVBd0R3WURWUjBUQVFIL0JBVXcKQXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKeGZBTitxQWRjd0t6aUlvcmh0U3B6eUVaR0RNQTBHQ1NxRwpTSWIzRFFFQkN3VUFBNElCQVFCTE5xYUVkMm5kT3htZlp5TUlidzVoeWYyRTNGL1lOb0hOMkJ0QkxaOWczY2NhYU5uUmJvYmhpQ1BQCkU5NUR6K0kwc3dTZEh5blZ2L2hleU5YQnZlNlNiekowOHBHQ0w3MkNRbnF0S3JjZ2ZVMjhlbFVTd2hYcXZmZHFsUzVzZEovUEhMVHkKeFFHamhkQnlQcTF6cXd1YmRReHRSYmVPbEt5V043V2cwSThWUnc3ajZJUGRqLzN2UVFGM3pDZXBZb1V6OGpjSTczSFBkd2JleUJrZAppRURQZlVZZC94N0g0YzcvSTl2RytvMVZUcWtDNTBjUlJqNzAvYjE3S1NhN3FXRmlOeWkyTFNyMkVJWmt5WENuMHEyM0tYQjU2anphCll5V2YvV2kzTU94dyszV0t0MjFnWjdJZXlMbnAyS2h2QW90bkRVMG1WM0hhSVB6QlNsQ05zU2k2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFmZmlybVRydXN0IENvbW1lcmNpYWwKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFREQ0NBalNnQXdJQkFnSUlkM2NHSnlhcHNYd3dEUVlKS29aSWh2Y05BUUVMQlFBd1JERUxNQWtHQTFVRUJoTUNWVk14RkRBUwpCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNUjh3SFFZRFZRUUREQlpCWm1acGNtMVVjblZ6ZENCRGIyMXRaWEpqYVdGc01CNFhEVEV3Ck1ERXlPVEUwTURZd05sb1hEVE13TVRJek1URTBNRFl3Tmxvd1JERUxNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHkKYlZSeWRYTjBNUjh3SFFZRFZRUUREQlpCWm1acGNtMVVjblZ6ZENCRGIyMXRaWEpqYVdGc01JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTlodFBad2Nyb1JYMUJpTExId0d5NDNORkJrUkpMTHRKSlJUV3pzTzNxeXhQeGtFeWxGZjZFcWRiCkR1S1BIeDZHR2FlcXRTMjVYdzJLd3ErRk5Ya3lMYnNjWWpmeXNWdEtQY3JOY1YvcFFyNlU2TWplK1NKSVpNYmxxOFlyYmEwRjhQclYKQzgrYTVmQlFwSXM3UjZValczcDYrRE0vdU8rWmwrTWd3ZFlvaWMrVSs3bEY3ZU5BRnhIVWRQQUxNZUlySm1xYlRGZXVyQ0ErdWtWNgpCZk85bTJrVnJuMU9JR1BFTlhZNkJ3TEpOLzNIUis3bzhYWWRjeFh5bDZTMXlIcDUyVUtxSzM5Yy9zNG1UNk5tZ1RXdlJMcFVIaHd3Ck1tV2Q1anlUWGxCT2V1TTYxRzdNR3Z2NTBqZXVKQ3FyVndNaUtBMUpkWCszS05wMXY0N2ozQTU1TVFJREFRQUJvMEl3UURBZEJnTlYKSFE0RUZnUVVuWlBHVTR0ZXlxOC9ueDRQNVptVnZDVDJsSTh3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQwpBUVl3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUZpczlBUU96Y0FOL3dyOTFMb1dYeW05ZTJpWldFblN0QjAzVFg4bmZVWUdYVVBHCmhpNCtjN0ltZlUrVHFiYkVLcHFySVpjVXNkNk0wNnVKRmRockpOVHhGcTdZcEZ6VWYxR083UmdCc1pOanZiejRZWUNhbnJIT1FuRGkKcVgwR0pYMG5vZjV2N0xNZUpOcmpTMVVhQURzMXREdloxMTB3L1lFVGlmTENCaXZ0WjhTT3lVT3lYR3NWaVFLOFl2eE84clV6cXJKdgowd3FpVU9QMk8rZ3VSTUxiWmppcE0xWkk4VzBiTTQwTmpEOWdONTNUeW0xK05INE5uM0oyaXh1ZmN2MVNOVUZGQXBZdkhMS2FjMGtoCnNVbEhSVWUwNzJvMEVjbE5tc3hadDlZQ25scE9aYldVcmh2ZktiQVc4YjhBbmdjNkYyUzFCTFVqSVprS2xUdVhmTzg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFmZmlybVRydXN0IE5ldHdvcmtpbmcKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFREQ0NBalNnQXdJQkFnSUlmRThFT1J6VW1TMHdEUVlKS29aSWh2Y05BUUVGQlFBd1JERUxNQWtHQTFVRUJoTUNWVk14RkRBUwpCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNUjh3SFFZRFZRUUREQlpCWm1acGNtMVVjblZ6ZENCT1pYUjNiM0pyYVc1bk1CNFhEVEV3Ck1ERXlPVEUwTURneU5Gb1hEVE13TVRJek1URTBNRGd5TkZvd1JERUxNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHkKYlZSeWRYTjBNUjh3SFFZRFZRUUREQlpCWm1acGNtMVVjblZ6ZENCT1pYUjNiM0pyYVc1bk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQXRJVE1NeGN1YTVSc2EyRlNvT3VqejNtVVRPV1VnSm5MVldSRVpZOW5aT0lHNDF3M1NmWXZtNFNFCkhpM3lZSjB3VHN5RWhlSXN6eDZlL2phck0zYzFSTmcxbGhvOU51aDZEdGpWUjZGcWFZdlovTHM2cm5sYTFmVFdjYnVha0NOcm1yZUkKZEljTUhsKzVuaTM2cTFNcjNMdDJQcE5NQ0FpTUhxSWpITlJxclNLNm1RRXViV1hMdmlSbVZTUkxRRVN4RzlmaHdvWEEzaEEvUGUyNAovUEh4STFQY3YyV1hiOW41UUhHTmZiMlYxTTYrb0Y0bkk5NzlwdEFtRGdBcDZ6eEc4RDFndno5UTB0d21RVkdlRkRkQ0JLTndWNmdiCmgrMHQrbnZ1akFyanFXYUpHY3RCK2QxRU5tSFA0bmRHeUgzMjlKS0JOdjNiTlBGeWZ2TU1GcjIwRlFJREFRQUJvMEl3UURBZEJnTlYKSFE0RUZnUVVCeC9TNTV6YXdtNmlRTFN3ZWxBUVVIVEV5TDB3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQwpBUVl3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUlsWHNoWjZxTUw5MXRtYm16VENuTFF5RkUybnBOL3N2cWUrK0VQYmtUZk90REl1ClVGVWFOVTUyUTNFZzc1TjNUaFZ3TG9mRHdSMXQzTXUxSjlRc1Z0RlNVenBFMG5QSXhCc0ZaVnBpa3B6dVFZMHgyK2MwNmxraDFRRjYKMTJTNFpEbk55ZTJ2N1VzRFNLZWdtUUdBM0dXak5xNWxXVWhQZ2t2SVpmRlhIZVZaTGdvL2JOalI5ZVVKdEd4VUFBcmdGVTJIZFcyMwpXSlphM1czU0FLRDBtMGkrd3pla3VqYmdmSWVGbHhvVm90NHVvbHU5cnhqNWtGRE5jRm40SjJkSHk4ZWdCenA5MFN4ZGJCazZaclY5Ci9aRnZnckcrQ0pQYkZFZnhvamZIUlo0OHgzZXZaS2lUMy9acGc0Smc4a2xDTk8xYUFGU0ZIQlkya2d4YytxYXR2OXM9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFmZmlybVRydXN0IFByZW1pdW0KPT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRlJqQ0NBeTZnQXdJQkFnSUliWXdVUnJHbUN1NHdEUVlKS29aSWh2Y05BUUVNQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RkRBUwpCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNUnd3R2dZRFZRUUREQk5CWm1acGNtMVVjblZ6ZENCUWNtVnRhWFZ0TUI0WERURXdNREV5Ck9URTBNVEF6TmxvWERUUXdNVEl6TVRFME1UQXpObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhGREFTQmdOVkJBb01DMEZtWm1seWJWUnkKZFhOME1Sd3dHZ1lEVlFRRERCTkJabVpwY20xVWNuVnpkQ0JRY21WdGFYVnRNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUF4QkxmcVYvK1FkM2Q5WitLNC9hczRUeDRtcnpZOEg5Nm9ETXEzSTBnVzY0dGIrZVQyVFp3YW1qUGpsR2poVnRuCkJLQVFKRzlkS0lMQmwxZllTQ2tUdHVHK2tVM2ZoUXhUR0pvZUpLSlBqL0NpaFF2TDlDbC8wcVJZN2laTnlhcW9lNXJaK2pqZVJGY1YKNWZpTXlObEk0ZzBXSngwZXlJT0ZKYmU2cWxWQnpBTWlTeTJSall2bWlhOW14K24vSytrOHJOclNzOFBoYUp5SitIb0FWdDcwVlpWcworN3BrM1dLTDN3dDNNdXRpekNhYW03dXFZb05NdEFaNk1NZ3B2KzBHVFplNUhNUXhLOVZmdkZNU0Y1eVpWeWxtZDJFaE1RY3VKVW1kCkdQTHU4eXR4akxXNk9RZEpkL3p2THBLUUJZMHRMM2Q3NzBPL05idWEyUGx6cHl6eTBGZnVLRTRtWDQrUWFBa3Z1UGpjQnVrdW1qNVIKcDlFaXhBcW5PRWhzcy9uL2ZhdUdWK082MW9WNGQ3cEQ2a2gvOXRpK0kyMGV2OUUyYkZoYzhlNmtHVlFhOVFQU2R1YmhqTDA4czlOSQpTK0xJK0grU3FIWkduRUpsUHFRZXdRY0RXa1l0dUpmenQ5V3lWU0h2dXR4TUFKZjdGSlVuTTcvb1EwZEcwZ2laRm1BN21uN1M1dTA0CjZ1d0JIanhJVmtrSngwdzNBSjZJRHNCejRXOW02WEpITUQ0UTVRc0R5WnBDQUd6RmxINWh4SXJmZjRJYUMxbkVXVEozczd4Z2FWWTUKL2JRR2V5eldaRGJadlVqdGhCOStwU0tQS3JoQzlJSzMxRk9RZUU0dEd2MkJiMFRYT3dGMGxrTGdBT0l1YStyRjduS3N1Ny8rNnFxbworTnoyc25tS3RtY0NBd0VBQWFOQ01FQXdIUVlEVlIwT0JCWUVGSjNBWjZZTUl0a205VVdycG1WU0VTZllSYXhqTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQkRBVUFBNElDQVFDelYwMFFZazQ2NUt6cXVCeXYKTWlQSXMwbGFVWngyS0kxNXFsZEdGOVgxVXZhM1JPZ0lSTDhZaE5JTGdNM0ZFdjBBVlFWaGgwSGN0U1NlUE1UWXlQdHduaTk0bG9NZwpOdDU4RDJrVGlLVjFOcGdJcHNiZnJNN2pXTmEzUHQ2NjgrczBRTmlpZ2ZWNFB5L1ZwZnpab3RSZUJBNFhyZjVCOE9XeWN2cEVnak5DCjZDMVk5MWFNWWorNlFyQ2NERngrTG1VbVhGTlBBTEo0ZnFFTm1TMk51QjJPb3NTdy9XRFFNS1NPeUFSaXFjVHROZDU2bCswT09GNlMKTDVOd3BhbWNiNmQ5RXgxK3hnaElzVjVuNjFFSUplbm1KV3RTS1pHYzBqbHpDRmZlbVFhMFc1MFFCdUhDQUtpNEhFb0NDaFRRd1VISworNHcxSVgyQ09QS3BWSkVaTlpPVWJXbzZ4YkxRdTRtR2sraWJ5UTg2cDNxNG9mQjRSdnI4TnkvbGlvVHozLzRFMmFGb29DOGs0Z21WCkJ0V1Z5dUVrbHV0ODlwTUZ1KzF6NlMzUmRUblg1eVRiMkU1ZlE0K2UwQlE1djFWd1NKbFhNYlNjN2txWUE1WXdIMkFHN2hzai9vRmcKSXhwSFlvV2x6QmswZ0crenJCcmpuL0I3U0szVkFkbG50cWx5aytvdFpyV3l1T1E5UExMdlRJenE2d2UvcXpXYVZZYThHS2ExcUY2MApnMnhyYVVEVG45enh3MmxydWVGdENmVHhxbEIyQ25wOWVoZWhWWlpDbVRFSjNXQVJqUVV3ZnVhT1J0R2RGTnJIRitRRmxvekVKTFViCnp4UUhza0Q0bzU1Qmhyd0UwR3VXeUNxQU5QMi83d2FqM1ZqRmhUMCtqLzZlS2VDMnVBbG9HUndZUXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQwo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQi9qQ0NBWVdnQXdJQkFnSUlkSmNsaXNjL2VsUXdDZ1lJS29aSXpqMEVBd013UlRFTE1Ba0dBMVVFQmhNQ1ZWTXhGREFTQmdOVgpCQW9NQzBGbVptbHliVlJ5ZFhOME1TQXdIZ1lEVlFRRERCZEJabVpwY20xVWNuVnpkQ0JRY21WdGFYVnRJRVZEUXpBZUZ3MHhNREF4Ck1qa3hOREl3TWpSYUZ3MDBNREV5TXpFeE5ESXdNalJhTUVVeEN6QUpCZ05WQkFZVEFsVlRNUlF3RWdZRFZRUUtEQXRCWm1acGNtMVUKY25WemRERWdNQjRHQTFVRUF3d1hRV1ptYVhKdFZISjFjM1FnVUhKbGJXbDFiU0JGUTBNd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQQpJZ05pQUFRTk1GNGJGWjBEMEtGNU5iYzZQSko2eWhVY3pXTHpuQ1pjQnozbFZQcWoxc3dTNnZRVVgraU9HYXN2TGtqbXJCaERlS3pRCk44TzlzczBzNWtmaUd1Wmp1RDB1TDNqRVQ5djBENlJvVEZWeWE1VWRUaGhDbFhqTU56eVI0cHRsS3ltalFqQkFNQjBHQTFVZERnUVcKQkJTYXJ5bDZ3QkUxTlNaUk1BRERhdjVBMWE3V1BEQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCQmpBSwpCZ2dxaGtqT1BRUURBd05uQURCa0FqQVhDZk9IaUZCYXI4akFRcjlIWC9Wc2FvYmd4Q2QwNURoVDF3Vi9HelRqeGkrenlnazhONTNYCjU3aEc4ZjJoNG5FQ01FSlpoMFBVVWQrNjB3a3lXczZJZmxjOW5GOUNhL1VITGJYd2dwUDVXVyt1WlBwWTVZc2U0Mk8rdFlITmJ3S00KZVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBCj09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR1ekNDQXFPZ0F3SUJBZ0lEQkVUQU1BMEdDU3FHU0liM0RRRUJCUVVBTUg0eEN6QUpCZ05WQkFZVEFsQk1NU0l3SUFZRFZRUUsKRXhsVmJtbDZaWFJ2SUZSbFkyaHViMnh2WjJsbGN5QlRMa0V1TVNjd0pRWURWUVFMRXg1RFpYSjBkVzBnUTJWeWRHbG1hV05oZEdsdgpiaUJCZFhSb2IzSnBkSGt4SWpBZ0JnTlZCQU1UR1VObGNuUjFiU0JVY25WemRHVmtJRTVsZEhkdmNtc2dRMEV3SGhjTk1EZ3hNREl5Ck1USXdOek0zV2hjTk1qa3hNak14TVRJd056TTNXakIrTVFzd0NRWURWUVFHRXdKUVRERWlNQ0FHQTFVRUNoTVpWVzVwZW1WMGJ5QlUKWldOb2JtOXNiMmRwWlhNZ1V5NUJMakVuTUNVR0ExVUVDeE1lUTJWeWRIVnRJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNQpNU0l3SUFZRFZRUURFeGxEWlhKMGRXMGdWSEoxYzNSbFpDQk9aWFIzYjNKcklFTkJNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DCkFROEFNSUlCQ2dLQ0FRRUE0L3Q5bzNLNnd2REpGSWYxYXdGTzRXNUFCN3B0SjExLzkxc3RzMXJIVVYrcnBES21ZWWUyYmcrRzBqQUMKbC9qWGFWZWhHRGxkYW1SNXhnRlpyRHd4U2poODBnVFNTeWpvSUY4N0I2TE1UWFBiODY1UHgxYlZXcWVXaWZyenEyalVJNFpaSjg4SgpKN3lzYm5LREhEQnkzK0NpNmRMaGRIVVp2U3FlZXhWVUJCdlhRem10VlNqRjRocTc5TURrcmpoSk04eDJoWjg1UmRLa252SVNqRkg0CmZPUXRmL1dzWCtzV243RXQwYnJNa1VKM1RDWEprRGh2Mi9ETSs0NGVsMWsrMVdCTzVnVW83VWw1RTB1NlNOc3YrWExUT2NyK0g5ZzAKY3ZXMFFNOHhBY1BzM2hFdEYxMGZ1RkRSWGhtbmFkNEhNeWpLVUpYNXAxVExWSVpRUmFuNVNRSURBUUFCbzBJd1FEQVBCZ05WSFJNQgpBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFJZHMzTEIvOGs5c1hON2J1UXZPS0VOMFoxOXpBT0JnTlZIUThCQWY4RUJBTUNBUVl3CkRRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFLYW9yU0xPQVQybW8vOWkwRWlkaTE1eXNIaEU0OXdjcnduOUkwajZ2U3JFdVZVRXRSQ2oKalNmZUM0SmowTzdlRERkNVFWc2lzckNhUVZ5bWNPRFUwSGZMSTlNQTRHeFdMK0ZwRFEzWnFyOGhnVkRaQnFXby81VTMwS3IrNHJQMQptUzFGaElybFFnblhkQUl2OTRuWW1lbThKOVJIamJvTlJoeDN6eFNrSExta01jU2NLSFFETlA4ekdTYWw2UTEwdHo2WHhuYm9KNWFqClp0M2hydkpCVzhxWVZvTnpjT1NHR3RJeFFib3Z2aTBUV25adlR1aE9nUTQvV3dNaW9CSytabGdSU3NzRHhMUXFLaTJXRitBNVZMeEkKMDNZbm5ab3RCcWJKN0RuU3E5dWZtZ3NuQWpVcHNVQ1Y1L25vbkZXSUdVYld0elQxZnM0NW10azQ4VkgzVHl3PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUV0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEZXpDQ0FtT2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCZk1Rc3dDUVlEVlFRR0V3SlVWekVTTUJBR0ExVUVDZ3dKClZFRkpWMEZPTFVOQk1SQXdEZ1lEVlFRTERBZFNiMjkwSUVOQk1Tb3dLQVlEVlFRRERDRlVWME5CSUZKdmIzUWdRMlZ5ZEdsbWFXTmgKZEdsdmJpQkJkWFJvYjNKcGRIa3dIaGNOTURnd09ESTRNRGN5TkRNeldoY05NekF4TWpNeE1UVTFPVFU1V2pCZk1Rc3dDUVlEVlFRRwpFd0pVVnpFU01CQUdBMVVFQ2d3SlZFRkpWMEZPTFVOQk1SQXdEZ1lEVlFRTERBZFNiMjkwSUVOQk1Tb3dLQVlEVlFRRERDRlVWME5CCklGSnZiM1FnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3dnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUsKQW9JQkFRQ3dmbks0cEFPVTVxZmVDVGlSU2hGQWg2ZDhXV1FVZTdVUkVOMyt2OVhBdTFiaWhTWDBOWElQK0ZQUVFlRkVBY0swSE1NeApRaFpIaFRNaWRySUtidy9sSlZCUGhZYSt2NWd1RUdjZXZoRUZoZ1dReEZuUWZIZ1FzSUJjdCtISEszWExmSit1dGRHZEl6ZGpwOXhDCm9pMlNCQnRRd1h1NFBodkpWZ1NMTDFLYnJhbFc2Y0gvcmFsWWh6QzJnZmVYUmZ3WlZ6c3JiK1JIOUpsRi9oM3grSmVqaUIwM0hGeVAKNEhZbG1sRDRvRlQvUkpCMkk5SXl4c09yQnIvOCs3L3pyWDJTWWdKYktkTTFvNU9hUTJSZ1hiTDZNdjg3Qks5TlFHcjV4K1B2SS8xcgp5K1VQaXpnTjdncjgvZytZbnpBeDNXeFNaZm1MZ2I0aTRSeFlBN3FSRzRrSEFnTUJBQUdqUWpCQU1BNEdBMVVkRHdFQi93UUVBd0lCCkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUnFPRnNtamQ2TFd2SlBlbFNER1JqakNEV211akFOQmdrcWhraUcKOXcwQkFRVUZBQU9DQVFFQVBOVjNQZHJmaWJxSERBaFVhaUJRa3I2d1FUMjVKbVNEQ2kvb1FNQ1hLQ2VDTUVySmsvOXE1NllBZjRsQwptdFlSNVZQT0w4enkyZ1hFL3VKUXhEcUdmY3phZmhBSk81STFLbE95L3VzckJkbHNYZWJRNzlOcVpwNFZLSVY2NklJQXJCNm5DV2xXClF0Tm9VUmkrVkpxL1JFRzZTYjRndW1sYzdyaDN6YzVzSDYyRGxoaDlEclVVT1lUeEtPa3RvNTU3SG5weVdvT3plVy92dFB6UUNxVlkKVDBiZisyMTVXZktFSWxLdUQ4ejdmRHZuYXNwSFljTjYrTk9TQkIrNElJVGhObFFXeDBEZU80cHozTi9HQ1V6ZjdOci8xRk5Db2NueQpZaDBpZ3p5WHhma1pZaWVzWlNMWDB6ekc1WTZ5VTh4Snpyd3cvbnNPTTVENzdkSVVrUjhIcnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEZHpDQ0FsK2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURCZE1Rc3dDUVlEVlFRR0V3SktVREVsTUNNR0ExVUVDaE1jClUwVkRUMDBnVkhKMWMzUWdVM2x6ZEdWdGN5QkRUeTRzVEZSRUxqRW5NQ1VHQTFVRUN4TWVVMlZqZFhKcGRIa2dRMjl0YlhWdWFXTmgKZEdsdmJpQlNiMjkwUTBFeU1CNFhEVEE1TURVeU9UQTFNREF6T1ZvWERUSTVNRFV5T1RBMU1EQXpPVm93WFRFTE1Ba0dBMVVFQmhNQwpTbEF4SlRBakJnTlZCQW9USEZORlEwOU5JRlJ5ZFhOMElGTjVjM1JsYlhNZ1EwOHVMRXhVUkM0eEp6QWxCZ05WQkFzVEhsTmxZM1Z5CmFYUjVJRU52YlcxMWJtbGpZWFJwYjI0Z1VtOXZkRU5CTWpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUIKQU5BVk9WS3hVck82eFZtQ3hGMVNyanBEWllCTHgvS1d2TnMybDlhbVpJeW9YdkRqQ2h6MzM1YzlTNjcyWGV3aHRVR3J6YmwrZHArKworVDQyTktBN3dmWXhFVVYwa3oxWGdNWDVpWm5LNWF0cTFMWGFRWkFRd2RiV1FvbkN2L1E0RXBWTVZBWDNOdVJGZzNzVVpkYmNERTNSCjNuNE1xenZFRmI0NlZxWmFiM1pwVXFsNnVjanJhcHBkVXRBdENtczFGZ2tRaE5CcXlqb0dBRGRINUg1WFR6K0w2MmU0aUtyRnZsTlYKc3BIRWZibXdoUmtHZUM3YllScjZoZlZLa2FIbkZ0V09vam5mbExod0h5Zy9pL3hBWG1PRFBJTXFHcGxyejk1WmFqdjhieGJYSC8xSwpFT3RPZ2hZNnJDY01VL0d0MVNTd2F3TlF3UzA4RnQxRU5DY2FkZnNDQXdFQUFhTkNNRUF3SFFZRFZSME9CQllFRkFxRnFYZGxCWmg4ClFJSDRENWNzT1BFSzdEelBNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUIKQ3dVQUE0SUJBUUJNT3FORXJMbEZzY2VUZnNnTENrTGZaT29jN2xsc0NMcUpYMnJLU3BXZWVvOEh4ZHBGY29KeERqclN6RytudEtFagp1L1lrbjhzWC9veW16c0xTMjh5Ti9ISDhBeW5CYkYwelgyUzJaVHVKYnhoMmVQWGNva2dmR1QrT2srdngraGZ1elU3akJCSlYxdVhrCjNmcytCWHppSFY3R3A3eVhUMmc2OWVrdUNrTzJyMWRjWW1oOHQvMmppb1NnckdLK0t3bUhOUEJxQWJ1YktWWTgvZ0EzenlOczhVNnEKdG5SR0VteVI3alRWN0pxUjUwUytrREZ5MVVrQzlnTGw5Qi9yZk5tV1Zhbi83SXI1bVVmL05Wb0NxZ1RMaWx1SGNTbVJ2YVMwZWcyOQptdlZYSXdBSElSYy9Tam5SQlVrTHA3WTNnYVZkaktvelhvRW9mS2Q5SitzQXJvMDMKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRUMtQUNDCj09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRlZqQ0NCRDZnQXdJQkFnSVE3aXM5NjlRaDNoU29ZcXdFODkzRUFUQU5CZ2txaGtpRzl3MEJBUVVGQURDQjh6RUxNQWtHQTFVRQpCaE1DUlZNeE96QTVCZ05WQkFvVE1rRm5aVzVqYVdFZ1EyRjBZV3hoYm1FZ1pHVWdRMlZ5ZEdsbWFXTmhZMmx2SUNoT1NVWWdVUzB3Ck9EQXhNVGMyTFVrcE1TZ3dKZ1lEVlFRTEV4OVRaWEoyWldseklGQjFZbXhwWTNNZ1pHVWdRMlZ5ZEdsbWFXTmhZMmx2TVRVd013WUQKVlFRTEV5eFdaV2RsZFNCb2RIUndjem92TDNkM2R5NWpZWFJqWlhKMExtNWxkQzkyWlhKaGNuSmxiQ0FvWXlrd016RTFNRE1HQTFVRQpDeE1zU21WeVlYSnhkV2xoSUVWdWRHbDBZWFJ6SUdSbElFTmxjblJwWm1sallXTnBieUJEWVhSaGJHRnVaWE14RHpBTkJnTlZCQU1UCkJrVkRMVUZEUXpBZUZ3MHdNekF4TURjeU16QXdNREJhRncwek1UQXhNRGN5TWpVNU5UbGFNSUh6TVFzd0NRWURWUVFHRXdKRlV6RTcKTURrR0ExVUVDaE15UVdkbGJtTnBZU0JEWVhSaGJHRnVZU0JrWlNCRFpYSjBhV1pwWTJGamFXOGdLRTVKUmlCUkxUQTRNREV4TnpZdApTU2t4S0RBbUJnTlZCQXNUSDFObGNuWmxhWE1nVUhWaWJHbGpjeUJrWlNCRFpYSjBhV1pwWTJGamFXOHhOVEF6QmdOVkJBc1RMRlpsCloyVjFJR2gwZEhCek9pOHZkM2QzTG1OaGRHTmxjblF1Ym1WMEwzWmxjbUZ5Y21Wc0lDaGpLVEF6TVRVd013WURWUVFMRXl4S1pYSmgKY25GMWFXRWdSVzUwYVhSaGRITWdaR1VnUTJWeWRHbG1hV05oWTJsdklFTmhkR0ZzWVc1bGN6RVBNQTBHQTFVRUF4TUdSVU10UVVORApNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXN5TEhUK0tYUXBXSVI0TkE5aDBYODROekpCNVI4NWlLCnc1SzQvMENRQlhDSFlNa0FxYldVWlJraUZSZkNRMnhtUkpvTkJENDViNlZMZXFwanQ0cEVuZGxqa1lSbTRDZ1B1a0xqYm83M0ZDZVQKYWU2UkRxTmZEckhyWnFKeVR4SVRobVY2UHR0UEIvU25DV0RhT2tLWng3Si9zeGFWSE1mNU5MV1VoZFdaWHFCSW9IN25GMlc0b25XNApIdlBsUW4ydjdmT0tTR1JkZ2hTVDJNRGsvN05RY3ZKMjlyTmRRbEI1MEpRK2F3d0F2dGhyRGs0cTdEN1N6SUtpR0dVekUzZWVtbDBhCkU5akQyejNJbDNydWNPMm41bnpiY2M4dGxHTGZiZGIxT0w0L3BZVUtHYmlvMkFsMVFuREU2dS9MRHNnMHFCSWltQXk0RTVTMlMrencKMEpEbkp3SURBUUFCbzRIak1JSGdNQjBHQTFVZEVRUVdNQlNCRW1WalgyRmpZMEJqWVhSalpYSjBMbTVsZERBUEJnTlZIUk1CQWY4RQpCVEFEQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVW9NT0xSS28zcFVXL2w0QmEwZkY0b3B2cFhZMHdmd1lEClZSMGdCSGd3ZGpCMEJnc3JCZ0VFQWZWNEFRTUJDakJsTUN3R0NDc0dBUVVGQndJQkZpQm9kSFJ3Y3pvdkwzZDNkeTVqWVhSalpYSjAKTG01bGRDOTJaWEpoY25KbGJEQTFCZ2dyQmdFRkJRY0NBakFwR2lkV1pXZGxkU0JvZEhSd2N6b3ZMM2QzZHk1allYUmpaWEowTG01bApkQzkyWlhKaGNuSmxiQ0F3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUtCSVc0SUI5azFJdURsVk5aeUFlbE9aMVZyL3NYRTd6RGtKCmxGN1cydSsrQVZ0ZDB4N1kvWDFQemFCQjREU1R2OHZpaHB3M2twQldITnpyS1FYbHhKN0hOZCtLRE0zRklVUHBxb2psTmNBWlFtTmEKQWw2a1NCZzZoVy9jbmJ3L25aekJoN2g2WVFqcGR3dC9jS3Q2M2RtWExHUWVoYis4ZEphaHczb1M3QXdhYm9NTVBPaHlScC83U05WZQpsK2F4b2ZqazcwWWxsSnlKMjJrNHZ1eGNEbGJIWlZIbFVJaUl2MExWS3ozbCticWVMclBLOUhPU0FndStUR2JySVA2NXk3V1pmK2EyCkUvcktTMDNaN2xOR0JqdkdUcTJUV29GK2JDcExhZ1ZGalBJaHBER1FoMnhsbkoybFlKVTZVbi8xMGFzSWJ2UHVXL21JUFg2NGIyNEQKNUVJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVNVENDQXhtZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBRENCbFRFTE1Ba0dBMVVFQmhNQ1IxSXhSREJDQmdOVkJBb1QKTzBobGJHeGxibWxqSUVGallXUmxiV2xqSUdGdVpDQlNaWE5sWVhKamFDQkpibk4wYVhSMWRHbHZibk1nUTJWeWRDNGdRWFYwYUc5eQphWFI1TVVBd1BnWURWUVFERXpkSVpXeHNaVzVwWXlCQlkyRmtaVzFwWXlCaGJtUWdVbVZ6WldGeVkyZ2dTVzV6ZEdsMGRYUnBiMjV6CklGSnZiM1JEUVNBeU1ERXhNQjRYRFRFeE1USXdOakV6TkRrMU1sb1hEVE14TVRJd01URXpORGsxTWxvd2daVXhDekFKQmdOVkJBWVQKQWtkU01VUXdRZ1lEVlFRS0V6dElaV3hzWlc1cFl5QkJZMkZrWlcxcFl5QmhibVFnVW1WelpXRnlZMmdnU1c1emRHbDBkWFJwYjI1egpJRU5sY25RdUlFRjFkR2h2Y21sMGVURkFNRDRHQTFVRUF4TTNTR1ZzYkdWdWFXTWdRV05oWkdWdGFXTWdZVzVrSUZKbGMyVmhjbU5vCklFbHVjM1JwZEhWMGFXOXVjeUJTYjI5MFEwRWdNakF4TVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUIKQUtsVEFPTXVwdmFPK21EWUxaVSsrQ3dxVkU3TnVZUmhsRmhQanoyTDVFUHpkWW1OVWVURE45S0tpRTE1SHJjUzNVTjRTb3FTNXRkSQoxUStrT2lsRU5iZ0g5bWdkVmMwNFVmQ01KREdGcjRQSmZlbDNyKzBhZTUwWCtiT2RPRkFQcGxwNWtZQ3ZONjZtMHpIN3RTWUpuVHhhCjcxSEZLOStXWGVzeUhnTGFjRW5zYmd6SW1qZU45L0UyWUVzbUxJS2UwSGp6RFE5anBGRXc0ZmtySnhJSDJPcTlHR0tZc0ZrM2ZiN3UKOHlCUlFscUQ3NU82YVJYeFlwMmZtVG1Db2JkMExvdlV4UXQ3TC9ESUN0bzllUXFha3h5bEtISnprVU9hcDlGTmhZUzVxWFNQRkVESAozTjZzUVdSc3RCbWJBbU50SkdTUFJMSWw2czVkZEF4ak1seU5oK1VDQXdFQUFhT0JpVENCaGpBUEJnTlZIUk1CQWY4RUJUQURBUUgvCk1Bc0dBMVVkRHdRRUF3SUJCakFkQmdOVkhRNEVGZ1FVcHBGQy9STmhTaU9lQ0tRcDVkZ1RCQ1B1UVNVd1J3WURWUjBlQkVBd1BxQTgKTUFXQ0F5NW5jakFGZ2dNdVpYVXdCb0lFTG1Wa2RUQUdnZ1F1YjNKbk1BV0JBeTVuY2pBRmdRTXVaWFV3Qm9FRUxtVmtkVEFHZ1FRdQpiM0puTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFBZjczbEI0WHR1UDdLTWhqZENTazRjTng2Tlpyb2tnY2xQRWc4aHdBT1hoaVZ0ClhkTWlLYWhzb2cycDZ6MEdXNWs2eDh6RG1qUi9xdzdJVGh6aCt1VGN6UTIrdnlUK2JPZHJ3ZzNJQnA1T2pXRW9wbXI5NWZaaTZoZzgKVHFCVG5iSTZuT3VsbkpFV3RrMkM0QXdGU0tsczljejR5NTFKdFBBQ3BmMXdBKzJLSWFXdUU0Wkp3ek56dm9jN2RJc1hSU1pNRnBHRAovbWQ5elUxalovcnpBeEtXZUFhTnNXZnRqaisrbjA4QzliTUpML05NaDk4cXk1VjhBY3lzTm5xL29uTjY5NC9CdFpxaEZMS1BNNThOCjd5TGNabnVFdlVVWEJqMDh5cmwzTkkvSzZzOC9NVDdqaU9PQVNTWElsN1dkbXBsTnNEejRTZ0NiWk4yZk9VdlJKOWU0Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFjdGFsaXMgQXV0aGVudGljYXRpb24gUm9vdCBDQQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ1ekNDQTZPZ0F3SUJBZ0lJVndvUmwwTEU0OHd3RFFZSktvWklodmNOQVFFTEJRQXdhekVMTUFrR0ExVUVCaE1DU1ZReERqQU0KQmdOVkJBY01CVTFwYkdGdU1TTXdJUVlEVlFRS0RCcEJZM1JoYkdseklGTXVjQzVCTGk4d016TTFPRFV5TURrMk56RW5NQ1VHQTFVRQpBd3dlUVdOMFlXeHBjeUJCZFhSb1pXNTBhV05oZEdsdmJpQlNiMjkwSUVOQk1CNFhEVEV4TURreU1qRXhNakl3TWxvWERUTXdNRGt5Ck1qRXhNakl3TWxvd2F6RUxNQWtHQTFVRUJoTUNTVlF4RGpBTUJnTlZCQWNNQlUxcGJHRnVNU013SVFZRFZRUUtEQnBCWTNSaGJHbHoKSUZNdWNDNUJMaTh3TXpNMU9EVXlNRGsyTnpFbk1DVUdBMVVFQXd3ZVFXTjBZV3hwY3lCQmRYUm9aVzUwYVdOaGRHbHZiaUJTYjI5MApJRU5CTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFwOGJFcFNta0xPL2xHTVd3VUtOdlVUdWZDbHJKCndrZzRDc0ljb0JoL2tiV0h1VUEvM1Ixb0h3aUQxUzBlaUtENGoxYVBiWmtDa3BBVzFWOEliSW5YNGF5OElNS3g0SU5SaW1sTkFKWmEKYnkvQVJINmpEdVNSelZqdTNQdkhIa1ZIM1NlNUNBR2ZwaUVkOVVFdEwwejlLSzNnaXEwaXRGWmxqb1pVajVOREtkNDVSbmlqTUNPNgp6ZkI5RTFmQVhkS0RhMGhNeEt1ZmdGcGJPcjNKcHlJL2dDY3pXdzYzaWd4ZEJ6Y0l5MnpTZWtjaVJEWEZ6TXd1anQwcTdiZDlaZzFmCllWRWlWUnZqUnVQalBkQTFZcHJicnhUSVc2SE1pUnZoTUNiOG9Kc2ZnYWRISHdUcm96bVNCcCtaMDcvVDZrOVFuQm4rbG9jZVBHWDIKb3hna2c0WVE1MVErcURwMkpFK0JJY1hqRHdMNGs1UkhJTHYrMUE3VGFMbmR4SHFFZ3VOVFZIbmQyNXpTOGdlYkxyYThQdTJGYmU4bApFZktYR2tKaDkwcVg2SXV4RUFmNlpZR3lvam5QOXp6L0dQdkc4VnFMV2VJQ3JIdVMwRTRVVDFsRjlneGVLRit3NkQ5Rno4K3ZtMi83CmhOTjNXcFZ2ckpTRW51Njh3RXFQU3BQNFJDSGlNVVZoVUU0UTJPTTFmRXdadE40RnY2TUduOGkxemVRZjF4Y0dEWHFWZEZVTmFCcjgKRUJ0aVpKMXQ0SldndzVRSFZ3MFU1cjBGKzdpZjV0K0w0c2JuZnBiMlU4V0FORkFvV1BBU1VIRVhNTHJtZUdPODlMS3RteXV5L3VFNQpqRjY2Q3lDVTNudUR1UC9qVm8yM0VlazdqUEt4d1YyZHBBdE1LOW15R1BXMW4wc0NBd0VBQWFOak1HRXdIUVlEVlIwT0JCWUVGRkxZCmlEckluM2htN1luemV6aHdsTWtDQWpiUU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0h3WURWUjBqQkJnd0ZvQVVVdGlJT3NpZmVHYnQKaWZON09IQ1V5UUlDTnRBd0RnWURWUjBQQVFIL0JBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElDQVFBTGUzS0h3R0NtU1V5SQpXT1lkaVBjVVpFaW0yRmdLRGs4VE5kODFIZFR0QmpISWdUNXExZDA3R2pMdWtEMFIwaTcwanNOakxpTm1zR2UrYjdiQUV6bGdxcUkwCkpaTjFVdDZubmEwT2g0bFNjV29XUEJrZGcvaWFLV1crOUQrYTJmRHpXb2NoY1lCTnkrQTRteis3K3VBd1RjK0cwMlVRR1JqUmx3S3gKSzNKQ2FLeWd2VTVhMmhpL2E1aUIwUDJhdmw0VlNNMFJGYm5BS1Z5MDZJajNQamF1dDJMOUhtTGVjSGdRSEVoYjJyeWtPTHBuN1ZVKwpYbGZmMUFOQVRJR2swazlqcHdsQ0NSVDhBS25DZ0hOUExzQkEyUkY3U09wNkFzRFQ2eWdCSmxoMHdjQnpJbTJUbGYwNWZic3E0L2FDCjR5eVhYMDRma1pUNi9peWoySFlhdUUyeU9FK2IraDFJWUhrbTR2UDlxZENhNkhDUFNYclc1YjBLRHRzdDg0Mi82K09rZmN2SGxYSG8KMnFOOHhjTDRkSklFRzRhc3BDSlRRTGFzL2t4MnovdVVNc0ExbjNZL2J1V1FicUNtSnFLNExMN1JLNFg5cDJqSXVnRXJzV3gwSGJoegpsZWZ1dDhjbDhBQk1BTEordGd1TEhQUEFVSjRsdWVBSTNqWm0vemVsMGJ0VVpDekpKN1ZMa241bC85TXQ0YmxPdkgra1FTR1FRWGVtCk9SL3FudU9mMEdadkJleXFkbjYvYXhhZzY3WEgvSkpVTHlzUkp5VTNlRXhSYXJEenpGaGRGUEZxU0JYL3dnZTJzWTBQamx4UVJyTTkKdndHWVQ3SlpWRWMrTkh0NGJWYVRMblBxWmloNHpSMFV2NkNQTHk2NExvN3lGSXJNNmJWOCsyeWRES1hobGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUcnVzdGlzIEZQUyBSb290IENBCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaekNDQWsrZ0F3SUJBZ0lRR3grdHRpRDVKTk0yYS9mSDhZeWdXVEFOQmdrcWhraUc5dzBCQVFVRkFEQkZNUXN3Q1FZRFZRUUcKRXdKSFFqRVlNQllHQTFVRUNoTVBWSEoxYzNScGN5Qk1hVzFwZEdWa01Sd3dHZ1lEVlFRTEV4TlVjblZ6ZEdseklFWlFVeUJTYjI5MApJRU5CTUI0WERUQXpNVEl5TXpFeU1UUXdObG9YRFRJME1ERXlNVEV4TXpZMU5Gb3dSVEVMTUFrR0ExVUVCaE1DUjBJeEdEQVdCZ05WCkJBb1REMVJ5ZFhOMGFYTWdUR2x0YVhSbFpERWNNQm9HQTFVRUN4TVRWSEoxYzNScGN5QkdVRk1nVW05dmRDQkRRVENDQVNJd0RRWUoKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTVZRZTU0N05kRGZ4SXpOanB2dG84QTJtZlJDNnFjK2dJTVBwcWRaaDhtUQpSVU4rQU9xR2VTb0R2VDAzbVlsbXQrV0tWb2FUbkdoTGFBU01rNU1DUGpEU056b2lZWWtjaFU1OWo5V3ZlelgyZmloSGlUSGNEbmxrCkg1blNXN3IrZjJDL3Jldm5QRGdwYWkvbGtRdFYvK3h2V05VdHlkNU1abkdQRE5jRTJnZm1IaGpqdlNrQ3FQb2M0VnU1ZzZoQlNMd2EKY1kzbll1VXRzdXZmZk0vYnExcktNZkZNSXZNRkUvZUMrWE41REw3WFN4ekEwUlU4azBGazBlYStJeGNpQUlsZUgydWxyRzZuUzR6dApvM0xtcjJOTkw0WFNGRFdhTGs2TTZqS1lLSWFoa1FsQk9yVGg0L0w2OE1rS29rSGRxZU1EeDRnVk94elVHcFRYbjJSWkVtMENBd0VBCkFhTlRNRkV3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFmQmdOVkhTTUVHREFXZ0JTNituRWxlWXRYUVNVaGhndHg2N0prRG9zaFp6QWQKQmdOVkhRNEVGZ1FVdXZweEpYbUxWMEVsSVlZTGNldXlaQTZMSVdjd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFINVkvLzAxR1gyYwpHRStlc0N1OGpvd1UveXlnMmtkYncrK0JMYThGNm5SSVcvTStUZ2ZIYmNXems4OGlOVnkyUDNVblh3bVd6YUQrdmtBTVhCSlYrSk9DCnlpbnBYajlXVjRzNE52ZEZHa3dvelo1QnVPMVdUSVNrUU1pNHNLVXJhWEFFYXNQNDFCSXkrUTdEc2R3eWhFUXNiOHRHRCtwbVFROVAKOFZpbHBnME5EMkhlcFo1ZGZXV2hQQmZucUZWTzc2REg3Y1pFZjFUMW8rQ1A4SHhWSW84cHRvR2o0VzFPTEJ1QVoreXRJSjhNWW1IVgpsLzlEN1MzQjJsMHBLb1UvckdYdWhnOEZqWkJmMys2ZjlML3VIZnVZNUgrUUs0UjRFQTVzU1ZQdkZWdGxSa3BkcjdyN09uSWR6ZllsCmlCNlh6Q0djS1FFTlpldFgyZk5YbHJ0SXpZRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQnV5cGFzcyBDbGFzcyAyIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZXVENDQTBHZ0F3SUJBZ0lCQWpBTkJna3Foa2lHOXcwQkFRc0ZBREJPTVFzd0NRWURWUVFHRXdKT1R6RWRNQnNHQTFVRUNnd1UKUW5WNWNHRnpjeUJCVXkwNU9ETXhOak16TWpjeElEQWVCZ05WQkFNTUYwSjFlWEJoYzNNZ1EyeGhjM01nTWlCU2IyOTBJRU5CTUI0WApEVEV3TVRBeU5qQTRNemd3TTFvWERUUXdNVEF5TmpBNE16Z3dNMW93VGpFTE1Ba0dBMVVFQmhNQ1RrOHhIVEFiQmdOVkJBb01GRUoxCmVYQmhjM01nUVZNdE9UZ3pNVFl6TXpJM01TQXdIZ1lEVlFRRERCZENkWGx3WVhOeklFTnNZWE56SURJZ1VtOXZkQ0JEUVRDQ0FpSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU5mSFh2ZkJCOVIzKzBNaDlQVDFhZVR1TWdIYm80WWY1RmtOdXVkMQpnMUxyNmh4aEZVaTdIUWZLaks2dzNKYWQ2c05na29hQ0tIT2NWZ2IvUzJUd0RDbzNTYlhsend4ODd2Rkt1M013WmZQVkw0TzJmdVBuCjlaNnJZUG5UOFoyU2RJcmtISmFzVzREcHRmUXhoNk5SL01kK29XK09VM2ZVbDhGVk01SStHQzkxMUsyR1NjdVZyMVFHYk5nR0U0MWIKLytFbUdWbkFKTHFCY1htUVJGQm9KSlJmdUxNUjhTbEJZYU5CeXlNMjFjSHhNbEFRVG4vMGhwUHNoTk9PdkV1L1hBRk9CejNjRklxVQpDcVRxYy9zTFVlZ1RCeGo2RHZFcjBWUVZmVHpoOTdRWlFtZGlYbmZnb2xYc3R0bHBGOVU2cjBUdFNzV2U1SG9uZk9WMTE2ckxKZWZmCmF3cmJEMDJUVHFpZ3pYc3U4bGtCYXJjTnVBZUJmb3M0R3pqbUNsZVpQZTRoNktQMURCYmRpK3cwanB3cUhBQVZGNDFvZzlKd254Z0kKelJGbzFjbHJVczNFUm8vY3RmUFlWM01lNlpRNUJML1QzampldEZQc2FSeWlmc1NQNUJ0d3JmS2krZnYzRm1SbWFaOUpVYUxpRlJobgpCa3AvMVd5MVRiTXo0R0hyWGI3cG1BOHkxeDFMUEM1YUFWS1JDZkxmNm8zWUJrQmpxaEhrL3NNM25oUlNQL1RpelBKaGs5SDlaMnZYClVxNi9hS3RBUTZCWE5WTjQ4RlA0WVVJSFpNYlhiNXRNT0ExanJHS3ZOb3VpY3dvTjlTRzlkS3BONm5JRFNkdkhYeDFpWThmOTNaSHMKTSs3MWJiUnVNR2pleU5ZbXNIVmVlN1FISUppaGRqSzRUV3hQQWdNQkFBR2pRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRApWUjBPQkJZRUZNbUFkK0Jpa29MMVJwenp1dmRNdzk2NG82MDVNQTRHQTFVZER3RUIvd1FFQXdJQkJqQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBZ0VBVTE4aDlicXdPbEk1TEpLd2JBREo3ODRnN3dieWxwN3BwSFIvZWhiOHQvVzIreFViUDZ1bXdISmRFTEZ4N3J4UDQ2MnMKQTIwdWNTNnZ4T090bzcwTUVhZTAvMHF5ZXhBUUg2ZFhRYkxBcnZRc1dkWkhFSWp6SVZFcE1NcGdocTlHcXgzdE9sdXdsTjVFNDBFSQpvc0hzSGRiOVQ3YldSOUFVQzhybXlyVjdkMzVCSDE2RHg3YU1PWmF3UDVhQlFXOWdrT0xvK2ZzaWNkbDlzejFHdjdTRXI1QWNENDhTCmFxL3Y3aDU2cmdKS2loY3JkdjZzVklra0xFOC90cktuVG95b2taZjdLY1o3WEMyNXkyYTJ0NmhiRWxHRnRRbCtZbmh3L3FscVlMWWQKRG5rTS9jcnFKSUJ5dzVjLzhuZXJReUlLeCt1MkRJU0NMSUJyUVlvSXdPdWxhOStaRXN1SzFWNkFESkhnSmdnMlNNWDZPQkUxL3lXRApMZko2djlyOWp2Nmx5MFVzSDhTSVU2NTNEdG1hZHNXT0xCMmp1dFhzTXE3QXFxejMwWHBONjlRSDRrajNJbzZ3cEo5cXpvNnlzbUQwCm95TFFJK3VVV25wcDNRKy9RRmVzYTFsUTJhT1o0VzcralFGNUp5TVYzcEtkZXdsTld1ZExTREJhR09ZS2JlYVA0Tks3NXQ5OGJpR0MKd1dnNVRiU1lXR1ppekVxUVhzUDZKd1N4ZVJWMG1jeStyU0RlSm1BYzYxWlJwcVBxNUtNL3AvOWgzUEZhVFd3eUkwUHVyS2p1N2tvUwpDVHhkY2NLK2VmckNoMmdkQy8xY2Fjd0cwSnA5VkprcXlUa2FHYTlMS2tQelkxMWFXT0l2NHgza3FkYlFDdENldjllQkNmSEp4eVlOCnJKZ1dWcUE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkJ1eXBhc3MgQ2xhc3MgMyBSb290IENBCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGV1RDQ0EwR2dBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUXNGQURCT01Rc3dDUVlEVlFRR0V3Sk9UekVkTUJzR0ExVUVDZ3dVClFuVjVjR0Z6Y3lCQlV5MDVPRE14TmpNek1qY3hJREFlQmdOVkJBTU1GMEoxZVhCaGMzTWdRMnhoYzNNZ015QlNiMjkwSUVOQk1CNFgKRFRFd01UQXlOakE0TWpnMU9Gb1hEVFF3TVRBeU5qQTRNamcxT0Zvd1RqRUxNQWtHQTFVRUJoTUNUazh4SFRBYkJnTlZCQW9NRkVKMQplWEJoYzNNZ1FWTXRPVGd6TVRZek16STNNU0F3SGdZRFZRUUREQmRDZFhsd1lYTnpJRU5zWVhOeklETWdVbTl2ZENCRFFUQ0NBaUl3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLWGFDcFVXVU9PVjhsNmRkakVHTW5xYjhSQjJ1QUNhdFZJMnpTUkgKc0o4WVpMeWE5dnJWZWRpUVlrd2lMOTQ0UGRiZ3FPa2NMTnQ0RWVtT2FGRVZjc2Z6TTRma29GMExYT0JYQnlvdzljM0VOM2NvVFJpUgo1ci9WVXYxeExYQSs1OGJFaXVQd0tBdjBkcGloaTRkVnNqb1QvTGMrSnplT0l1T29UeXJ2WUxzOXR6bkREZ0ZIbVYwU1Q5dEQrbGVoCjdmbWR2aEZISmxzVG1LdGRGb3F3Tnh4WG5VWC9pSlkydjd2S0IzdHZoMlBYMERKcTFsMXNEUEd6YmpuaWF6RXVPUUFuRk40NHdPd1oKWm9ZUzZKMXlGaE5rVXNlcE54ejlnakR0aEJnZDlLNWMvM0FUQU91eDlUTjZTOVpWK0FXTlMybXc5Yk1vTmx3VXhGRnpUV3NMOFRRSAoyeGM1MTl3b2UydjFuL011d1U4WEtoRHp6TXJvNi8xcnF5NmFueTJDYmdUVVVnR1RMVDJHL0g3ODMrOUNIYVpyNzdrZ3h2ZTlvS2VWCi9hZm1pU1RZekl3MGJPSWpMOWtTR2lHNVZaRnZDNUY1R1F5dFFJZ0xjT0o2MGc3WWFFaTdnaE01RUZqcDJDb0h4aExiV052U08xVVEKUndVVloySitHR09tUmo4SkRsUXlYcjhOWW5vbjc0RG8yOWxMQmxvM1dpWFFDQkozMUc4SlVKYzl5QjNEMzR4Rk1GYkcwMlNyWnZQQQpYcGFjdzhUdnczeHJpenA1ZjdOSnp6M2lpWitnTUV1RnVaeVVKSG1QZld1cFJXZ1BLOUR4Mmh6TGFiaktTV0p0eU5Call0MWdEMWlxCmo2RzhCYVZtb3M4YmRyS0VaTEZNT1ZMQU1McndqRXNDc0xhM0FnTUJBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGRWU0emYvbGIrNzRzdXd2VGc3NUpiQ09QR3ZETUE0R0ExVWREd0VCL3dRRUF3SUJCakFOQmdrcWhraUc5dzBCQVFzRgpBQU9DQWdFQUFDQWpRVFVFa01KQVltRHY0alZNMXorczRqU1F1S0Z2ZHZvV0ZxUklOeXpwa01MeVBQZ0tuOWlCNWJ0YjJpVXNwS2RWCmNTUXk5c2dMOHJ4cStKT3NzZ2ZDWDUvYnpNaUtxcjVxYitGSkVNd3gxNEM3dThqWW9nNWtWK3FpOWNLcE1SWFNJR3JzL0NJQktNK0cKdUlBZXFjd1JwVHp5RnJOSG5melNnQ0hFeTlCSGNFR2h5b01aQ0N4dDhsMTNuSW9VRTlRMkhKTHc1UVkzM0tibWtKczRqMXhyRzBhRwpRMEpmUGdFSFUxUmRaWDMzaW5PaG1sUmFIeWxERkNmQ2hRKzFpSHNhTzVTM0hXQ250WnpuS1dsWFdwdVRla013R3dQWFlzaEFwcXI4ClpPUksxNUZUQWFnZ2lHNmNYMFM1eTJDQk5PeHYwMzNhU0YvcnRKQzhMYWtjQzZ3YzFhSm9JSUFFMXZ5eGp5KzdTakVOU29ZYzYrSTIKS1NiMTJ0akU4blZoejM2dWRtTktla0JsazRmNEhvQ01odVdHMW84Ty9GTXNZT2dXWVJxaVBrTjd6VGxnVkdyMThva21BV2lEU0tJego2TWtFa2JJUk5CRSs2dEJER1I4RGs1QU0vMUU5Vi9SQmJ1SExvTDdyeVdQTmJjemsrRGFxYUozdHZWMlhjRVFOdGc0MTNPRU1YYnVnClVaVExmaGJyRVMramtrWElUSEhadk1tWlVsZEdMMURQdlRWcDlEMFZ6Z2FsTEE4KzlvRzZsTHZEdTc5bGVOS0dlZjlKT3hxRERQRGUKZU96SThrMU1HdDZDS2ZqQld0cnQ3dVluWHVoRjBKMGNVYWhvcTBUajBJdHE0L2c3dTl4TjEyVHlVYjdtcXF0YTZUSHVCcnh6dnhOaQpDcC9IdVpjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpULVRlbGVTZWMgR2xvYmFsUm9vdCBDbGFzcyAzCj09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR3ekNDQXF1Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCZ2pFTE1Ba0dBMVVFQmhNQ1JFVXhLekFwQmdOVkJBb00KSWxRdFUzbHpkR1Z0Y3lCRmJuUmxjbkJ5YVhObElGTmxjblpwWTJWeklFZHRZa2d4SHpBZEJnTlZCQXNNRmxRdFUzbHpkR1Z0Y3lCVQpjblZ6ZENCRFpXNTBaWEl4SlRBakJnTlZCQU1NSEZRdFZHVnNaVk5sWXlCSGJHOWlZV3hTYjI5MElFTnNZWE56SURNd0hoY05NRGd4Ck1EQXhNVEF5T1RVMldoY05Nek14TURBeE1qTTFPVFU1V2pDQmdqRUxNQWtHQTFVRUJoTUNSRVV4S3pBcEJnTlZCQW9NSWxRdFUzbHoKZEdWdGN5QkZiblJsY25CeWFYTmxJRk5sY25acFkyVnpJRWR0WWtneEh6QWRCZ05WQkFzTUZsUXRVM2x6ZEdWdGN5QlVjblZ6ZENCRApaVzUwWlhJeEpUQWpCZ05WQkFNTUhGUXRWR1ZzWlZObFl5QkhiRzlpWVd4U2IyOTBJRU5zWVhOeklETXdnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzlkWlB3WWlKdkpLN2dlbmFzZmIzWkpOVzR0L3pOOEVMZzYzaUlWbDZibWxRZFRReUsKOXRQUGNQUlN0ZGlUQk9OR2huRkJTaXZ3S2l4VkE5Wkl3K0E1T08zeVhEdy9STHlUUFdHclRzME52dkFnSjFnT1JIOEVHb2VsMTVZVQpOcERRU1h1aGRmc2FhM094K002cENTenlVOVhERkVTNGhxWDJpeXM1MnFNelZObjZjaHIzSWhVY2lKRnJmMmJsdzJxQXNDVHozNFpGCmlQMFpmM1dISHgreEd3cHpKRnU1WmVBc1ZNaGcwMllYUCtITVZETnprUUk2cG45N2RqbWlINWEyT0s2MXlKTjBIWjY1dE9WZ25TOVcKMGVEclhsdE1FbkFNYkVRZ3F4SFk5Qm4yMHB4U04rZjZ0c0l4TzByVUZKbXR4eHIxWFYvNkI3aDhEUi9XZ3g2ekFnTUJBQUdqUWpCQQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCUzFBL2QyTzJHQ2FoS3FHRlByCkF5R1V2LzdPeWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVZqM3ZsTlc5Mm5PeVdMNnVrSzJZSjVmK0FiR3dVZ0M0VGVRYklYUWIKZnNEdVhta3FKYTljMWgzYTBubko4NWNwNElhSDNnUlpEL0ZaMUdTRlM1bXZKUVFleVVhcGw5NkNzaHR3bjV6MnIzRXgzWHNGcFN6VAp1Y3BIOXNyeTl1ZXR1VWcvdkJhM3dXMzA2Z212N1BPMTV3V2VwaDZLVTFIV2s0SE1kSlAydWRxbUpRVjBlVnArUUQ2Q1N5WVJNRzdoClAwSEhSd0ExMWZYVDkxUStnVDNhU1dxYXMrOFFQZWJyYjlISUlrZkx6TThCTVpMWkdPTWl2Z2tlR2o1YXN1UnJERlI2ZlVOT3VJbWwKZTllaVBaYUd6UEltTkMxcWtwMmFHdEF3NGwxT0JMQmZpeUIrZDhFOWxZTFJScG83UEhpNGI2SFFEV1NpZUI0cFRwUERwRlFVV3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpELVRSVVNUIFJvb3QgQ2xhc3MgMyBDQSAyIDIwMDkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFTXpDQ0F4dWdBd0lCQWdJRENZUHpNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1FMHhDekFKQmdOVkJBWVRBa1JGTVJVd0V3WURWUVFLCkRBeEVMVlJ5ZFhOMElFZHRZa2d4SnpBbEJnTlZCQU1NSGtRdFZGSlZVMVFnVW05dmRDQkRiR0Z6Y3lBeklFTkJJRElnTWpBd09UQWUKRncwd09URXhNRFV3T0RNMU5UaGFGdzB5T1RFeE1EVXdPRE0xTlRoYU1FMHhDekFKQmdOVkJBWVRBa1JGTVJVd0V3WURWUVFLREF4RQpMVlJ5ZFhOMElFZHRZa2d4SnpBbEJnTlZCQU1NSGtRdFZGSlZVMVFnVW05dmRDQkRiR0Z6Y3lBeklFTkJJRElnTWpBd09UQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOT3lTczk2Uis5MW15UDZPaS9XVUVXSk5UckdhOXYrMndCb3FPQUQKRVIwM1VBaWZUVXBvbERXelU5R1VZNmNnVnEvZVVYanNLajN6U0VoUVBncmZSbFdMSjIzREVFME5rVkpEMklmZ1hVNDJ0U0hLWHpsQQpCRjliZnN5anhpdXBRQjdaTm9UV1NQT1NIalJHSUNUQnBGR09TaHJ2VUQ5cFhSbC9SY1BIQVk5UnlTUG9jcTYwdkZZSmZ4TExITEd2CktaQUt5VlhNRDlPMEd1MUhOVnBLN1p4ekJDSFFxcjBNRTdVQXlpWnN4R3NNbEZxVmxOcFFtdkgvcFN0bU1hVEpPS0RmSFIrNENTN3oKcCtoblVxdVZIK0JHUHRpa3c4cGF4VEdBNkVpYW41UnAvaG5kMkhOOGdjcVczbzd0c3pJRlpZUTA1dWI5VnhDMVgzYS9MN0FRRGNVQwpBd0VBQWFPQ0FSb3dnZ0VXTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRlAzYUZNU2ZNTjRodlI1Q09meXJZeU5KCjRQR0VNQTRHQTFVZER3RUIvd1FFQXdJQkJqQ0Iwd1lEVlIwZkJJSExNSUhJTUlHQW9INmdmSVo2YkdSaGNEb3ZMMlJwY21WamRHOXkKZVM1a0xYUnlkWE4wTG01bGRDOURUajFFTFZSU1ZWTlVKVEl3VW05dmRDVXlNRU5zWVhOekpUSXdNeVV5TUVOQkpUSXdNaVV5TURJdwpNRGtzVHoxRUxWUnlkWE4wSlRJd1IyMWlTQ3hEUFVSRlAyTmxjblJwWm1sallYUmxjbVYyYjJOaGRHbHZibXhwYzNRd1E2QkJvRCtHClBXaDBkSEE2THk5M2QzY3VaQzEwY25WemRDNXVaWFF2WTNKc0wyUXRkSEoxYzNSZmNtOXZkRjlqYkdGemMxOHpYMk5oWHpKZk1qQXcKT1M1amNtd3dEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSCtYMnpESTM2U2NmU0Y2Z0hET0ZCSnBpQlNWWUVRQnJMTHBNRStiVU1KbQoySDZOTUxWd01lbmlhY2Z6Y05zZ0ZZYlFEZkMrckFGMWhNNStuMDIvdDJBN25QUEtIZUplYU5pam5aZmxRR0RTTmlIKzBMUzRGOXAwCm8zL1UzN0NZQXF4dmEyc3NKU1J5b1dYdUpWcmw1akxuOHQrclNmcnprR2tqMndUWjUxeFkvR1hVbDc3TS9DNEt6Q1VxTlFUNFlKRVYKZFQxQi95TWZHY2hzNjRKVEJLYmtUQ0pOall5NnpsdHo3R1JVVUczUm5GWDdhY00ydzR5OFBJV21hd29tRGVDVG1HQ3Vmc1lrbDRwaApYNUdPWnBJSmh6Yk5pNXN0UHZaUjFGRFVXU2k5Zy9MTUtIdFRobTNZSm9odzErcVJ6VDY1eXNDUWJsckdYblJsMTF6K28rST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRC1UUlVTVCBSb290IENsYXNzIDMgQ0EgMiBFViAyMDA5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRVF6Q0NBeXVnQXdJQkFnSURDWVAwTUEwR0NTcUdTSWIzRFFFQkN3VUFNRkF4Q3pBSkJnTlZCQVlUQWtSRk1SVXdFd1lEVlFRSwpEQXhFTFZSeWRYTjBJRWR0WWtneEtqQW9CZ05WQkFNTUlVUXRWRkpWVTFRZ1VtOXZkQ0JEYkdGemN5QXpJRU5CSURJZ1JWWWdNakF3Ck9UQWVGdzB3T1RFeE1EVXdPRFV3TkRaYUZ3MHlPVEV4TURVd09EVXdORFphTUZBeEN6QUpCZ05WQkFZVEFrUkZNUlV3RXdZRFZRUUsKREF4RUxWUnlkWE4wSUVkdFlrZ3hLakFvQmdOVkJBTU1JVVF0VkZKVlUxUWdVbTl2ZENCRGJHRnpjeUF6SUVOQklESWdSVllnTWpBdwpPVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbnhoRFJ3dWkrM01LQ092WHdFejc1aXZKbjlncGZTCmVncG5samdKOWhCT2xTSnptWTNhRlMzbkJmd1pjeUszanBnQXZEdzlyS0ZzKzlaNUpVdXQ4TXhrMm9nK0tiZ1BDZE0wM1RQMVl0SGgKelJucDdoaFBURml1NGg3V0RGc1ZXdGc2dU1RWVpCN2pNN0sxaVhkT0RML1psR3NUbDI4U28vNlpxUVRNRmV4Z2FEYnRDSHUzOWIrVAo3V1l4ZzR6R2NUU0hUaGZxcjR1UmpSeFdRYTRpTjE0MzhoM1owUzBOTDJsUnA3NW1wb282S3IzSEdySGhGUEMrT2gyNXoxdXhhdjYwCnNVWWdvdnNlTzNEdms1aDlqSE9XOHNYdmhYQ3RLU2I4SGdRK0hLRFlEOHRTZzJKODdvdFRsWkNwVjZMcVlRWFkrVTNFSi9wdXJlMzUKMTFIM2E2VUNBd0VBQWFPQ0FTUXdnZ0VnTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRk5PVWlreGlFeW9aTHN5dgpjb3A5TnRlYUhOeG5NQTRHQTFVZER3RUIvd1FFQXdJQkJqQ0IzUVlEVlIwZkJJSFZNSUhTTUlHSG9JR0VvSUdCaG45c1pHRndPaTh2ClpHbHlaV04wYjNKNUxtUXRkSEoxYzNRdWJtVjBMME5PUFVRdFZGSlZVMVFsTWpCU2IyOTBKVEl3UTJ4aGMzTWxNakF6SlRJd1EwRWwKTWpBeUpUSXdSVllsTWpBeU1EQTVMRTg5UkMxVWNuVnpkQ1V5TUVkdFlrZ3NRejFFUlQ5alpYSjBhV1pwWTJGMFpYSmxkbTlqWVhScApiMjVzYVhOME1FYWdSS0JDaGtCb2RIUndPaTh2ZDNkM0xtUXRkSEoxYzNRdWJtVjBMMk55YkM5a0xYUnlkWE4wWDNKdmIzUmZZMnhoCmMzTmZNMTlqWVY4eVgyVjJYekl3TURrdVkzSnNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEwN1h0YVBLU1VpTzhhRVhVSEw3UCsKUFBvZVVTYnJoL1lwM3VEeDFNWWtDZW5CejFVYnRERFp6aHIrQmxHbUZhUXQ3N0pMdnlBb0pVblJwalozTk9oazMxS3hFY2R6ZXMwNQpuc0t0akhFaDhscHJyOTg4VGxXdnNvUmxGSW01ZDhzcU1iN1BvMjNQYjBpVU1rWnY1M0dNb0thRUdUY0g4Z05GQ1N1R2RYemZYMmxYCkFOdHUyS1p5SWt0UTFIV1lWdCszR1A5RFExQ3Vla1I3OEhsUjEwTTlwOU9CMC9ESlQ3bmF4cGVHMElMRDVFSnQvckRpWkU0T0p1ZEEKTkNhMUNJblhDR05qT0NkMUhqUHFicWpkbjVsUGRFMkJpWUJMM1pxWEtWd3Z2b0ZCdVl6LzZuMWdCcDdOMXozVExxTVZ2S2ptSnVWdgp3OXk0QXlIcW54YnhMRlMxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkNBIERpc2lnIFJvb3QgUjIKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmFUQ0NBMUdnQXdJQkFnSUpBSks0aU51d2lzRmpNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1GSXhDekFKQmdOVkJBWVRBbE5MTVJNdwpFUVlEVlFRSEV3cENjbUYwYVhOc1lYWmhNUk13RVFZRFZRUUtFd3BFYVhOcFp5QmhMbk11TVJrd0Z3WURWUVFERXhCRFFTQkVhWE5wClp5QlNiMjkwSUZJeU1CNFhEVEV5TURjeE9UQTVNVFV6TUZvWERUUXlNRGN4T1RBNU1UVXpNRm93VWpFTE1Ba0dBMVVFQmhNQ1Uwc3gKRXpBUkJnTlZCQWNUQ2tKeVlYUnBjMnhoZG1FeEV6QVJCZ05WQkFvVENrUnBjMmxuSUdFdWN5NHhHVEFYQmdOVkJBTVRFRU5CSUVScApjMmxuSUZKdmIzUWdVakl3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ2lvOFFBQ2RhRlhTMXRGUGJDCnczT2VOY0p4Vlg2Qis2dEdVT0RCZkVsNDVxdDVXRHphLzN3Y245aVhBbmcrYTBFRTZVRzl2Z01zUmZZdlpOU3JYYU5IUFdTYjZXaWEKeHN3YlA3cStzb3MwQWk2WVZSbjhqRytxWDlwTXprMERJYVBZMGpTVFZwYkxUQXdBRmp4ZkdzM0l4MnltcmRNeHA3em81ZUZtMXRMNwpBN1JCWmNrUXJnNEZZOGFBYW1rdy9kTHVrTzhOSjkrZmxYUDA0U1hhYkJiZVFUZzA2b3Y4MGVnRUZHRXRRWDZzeDNkT3kxRlUrMTZTCkdCc0VXbWpHeWNUNnR4T2dtTGNSSzdmV1Y4eDhuaGZSeXlYK2hrNGtMbFlNZUUyZUFSS21LNmNCWlc1OFloMkVoTi9xd0d1MXBTcVYKZzhOVEVReHpIUXV5UnBEUlFqck9RRzZWcmYvR2xLMXVsNFNPZlcrZWlvQU5TVzF6NG51U0hzUHp3ZlByTGdWdjJSdlBOM1lFeUxSYQo1QmVueTkxMkg5QVpkdWdzQmJQV25EVFlsdHhoaDVFRjVFUUlNOEhhdVFobDFLNnlOZzNydWppNkRPV2JudXVOWnQyWno5YUpRZllFCmtvb3BLVzFyT2h6bmRYMENjUTd6d09lOXl4bmRuV0N5d21aZ3RyRUU3c25taHJtYVprQ281eEh0Z1VVRGkvWm5XZWpCQmhHOTNjK0EKQWs5bFFIaGNSMURJbStZZmdYdmtSS2hiaFpyaTNsclZ4L2s2UkdaTDVESlVmT1JzbkxNT1BSZWlzalFTMW42eXFFbTcwWG9vUUw2aQpGaC9mNURjZkVYUDdrQXBsUTZJTmZQZ0dBVlV6ZmJBTnVQVDFycVZDVjN3MkVZeDdYc1FEbll4NW5RSURBUUFCbzBJd1FEQVBCZ05WCkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVV0Wm40cjdDVTllTWcxZ3F0ems1V3BDNXUKUXUwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFDWUdYbkRuWlRQSWdtN1puQmM2RzNwbXNnSDJlRHRwWGkvcS8wNzVLTU9ZS21GTQp0Q1FTaW4xdEVSVDNuTFhLNXJ5ZUo0NU1HY2lwdlhyQTF6WU9iWVZ5YnFqR29tMzIrbk5qZjd4dWVRZ2NuWXFmR29wVHB0aTcyVFZWCnNSSEZxUU96Vmp1NWhKTWlYbjdCOWhKU2krb3NaN3orTmt6MXVNL1JzMG1TTzlNcERwa2JsdmRodUR2RUs3WjRiTFFqYi9EOTA3SmUKZFIrWmxhaXM5dHJoeFRGNys5RkdzOUs4WjdSaVZMb0o5Mk93azZLYStlbFNMb3RnRXF2ODlXQlc3eEJjaThRYVF0eURXMlFPeTdXOAoxay9CZkR4dWpSTnQrM3ZyTU5EY1RhL0YxYmFsVEZ0eHllZ3h2dWc0QmtpaEd1THEwdDRTT1ZnYS80QU9nblhtdDhrSGJBN3Yvemp4Cm1ISEV0MzhPRmRBbGFiMGluU3Z0QmZaR1I2enR3UERVTytMczdwWmJrQk5PSGxZNjY3RHZscnVXSXhHNjhrT0dkR1NWeUNoMTN4MDEKdXRJM2d6aFRPRFk3ejJ6cCtXc08wUHNFNkU5MzEyVUJlSVlNZWo0aFl2Ri9ZM0VNeVo5RTI2Z25vblcrYm9FKzE4RHJHNWdQY0Z3MApzb3JNd0lVWTYyNTZzL2Rhb1FlL3FVS1M4MkFpbCtRVW9RZWJUbmJBam4zOXBDWEhSKzMvSDNPc3pNT2w2VzhLanB0bHdsQ0Z0YU9nClV4TE1WWWRoODRHdUVFWmh2VVFodU1JOWRNOStKRFg2SEFjT216MGl5dTh4TDR5c0VyM3ZRQ2o4S1dlZnNoTlBaaVRFVXhucEhpa1YKNytadHNIOHRaLzN6YkJ0MVJxUGxTaGZwcE5jTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBQ0NWUkFJWjEKPT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlIMHpDQ0JidWdBd0lCQWdJSVhzTzNwa04vcE9Bd0RRWUpLb1pJaHZjTkFRRUZCUUF3UWpFU01CQUdBMVVFQXd3SlFVTkRWbEpCClNWb3hNUkF3RGdZRFZRUUxEQWRRUzBsQlEwTldNUTB3Q3dZRFZRUUtEQVJCUTBOV01Rc3dDUVlEVlFRR0V3SkZVekFlRncweE1UQTEKTURVd09UTTNNemRhRncwek1ERXlNekV3T1RNM016ZGFNRUl4RWpBUUJnTlZCQU1NQ1VGRFExWlNRVWxhTVRFUU1BNEdBMVVFQ3d3SApVRXRKUVVORFZqRU5NQXNHQTFVRUNnd0VRVU5EVmpFTE1Ba0dBMVVFQmhNQ1JWTXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDCkR3QXdnZ0lLQW9JQ0FRQ2JxYXUvWVVxWHJ5K1hacHAwWDlEWmx2M1A0dVJtN3g4ZlJ6UENSS1BmbXQ0ZnRWVGRGWHhwTlJGdnU4Z00Kam1vWUh0aVAyUmE4RUVnMlhQQmpzNUJhWENRMzE2UFd5d2x4dWZFQmNvU3dmZHROZ00zODAyL0orTnEyRG9MU1JZV29HMmlvUGVqMApSR3k5b2NMTEE3Nk1QaE1BaE45S1NNRGpJZ3JvNlRlbkdFeXhDUTBqVm44RVRka1hoQmlseU5wQWxIUHJ6ZzVYUEFPQk9wMEtvVmRECmFheFhiWG1RZU9XMXREdll2RXlOS0tHbm82ZTZBazRsMFNxdTdhNERJcmhySUE4d0tGU1ZmK0R1emdwbW5kRkFMVzRpcjUwYXdRVVoKMG0vQThwLzRlN01DUXZ0UXFSMHRrdzhqcThiQkQ1TC8wS0lWOVZNSmNSei9SUk9FNWlaZStPQ0lIQXI4RnJhb2N3YTQ4R09FQXFERwpXdXpuZE45d3JxT0RKZXJXeDVlSGs2Zkdpb296bDJBM0VENlhQbTRwRmRhaEQ5R0lMQktmYjZxa3hrTHJRYUxqbFVQVEFZVnRqcnM3Cjh5TTJ4LzQ3NEtFbEIwaXJ5WWwwL3dpUGdML0FsbVh6N3V4TGFMMmRpTU14czBEeDZNLzJPTHVjNU5GLzFPVlltM3o2MVBNT20zV1IKNUxwU0xobCswZlhOV2huOHVnYjIrMUtvUzVrRTNmajV0SXRRbzA1aWlmQ0hKUHFEUXNHSCt0VXRLU3BhY1hwa2F0Y25ZR01OMjg1Sgo5WTBma0lreUYvaHpRN2pTV3BPR1lkYmhkUXJxZVdaMmlFOXg2d1FsMWdwYWVwUGx1VXNYUUEreHRybjEzay9jNExPc094RndZSVJLClEyNlpJTUFwY1FyQVpRSURBUUFCbzRJQ3l6Q0NBc2N3ZlFZSUt3WUJCUVVIQVFFRWNUQnZNRXdHQ0NzR0FRVUZCekFDaGtCb2RIUncKT2k4dmQzZDNMbUZqWTNZdVpYTXZabWxzWldGa2JXbHVMMEZ5WTJocGRtOXpMMk5sY25ScFptbGpZV1J2Y3k5eVlXbDZZV05qZGpFdQpZM0owTUI4R0NDc0dBUVVGQnpBQmhoTm9kSFJ3T2k4dmIyTnpjQzVoWTJOMkxtVnpNQjBHQTFVZERnUVdCQlRTaDdUajN6Y25rMVgyClZ1cUI1VGJNakI0L3ZUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01COEdBMVVkSXdRWU1CYUFGTktIdE9QZk55ZVRWZlpXNm9IbE5zeU0KSGorOU1JSUJjd1lEVlIwZ0JJSUJhakNDQVdZd2dnRmlCZ1JWSFNBQU1JSUJXRENDQVNJR0NDc0dBUVVGQndJQ01JSUJGQjZDQVJBQQpRUUIxQUhRQWJ3QnlBR2tBWkFCaEFHUUFJQUJrQUdVQUlBQkRBR1VBY2dCMEFHa0FaZ0JwQUdNQVlRQmpBR2tBOHdCdUFDQUFVZ0JoCkFPMEFlZ0FnQUdRQVpRQWdBR3dBWVFBZ0FFRUFRd0JEQUZZQUlBQW9BRUVBWndCbEFHNEFZd0JwQUdFQUlBQmtBR1VBSUFCVUFHVUEKWXdCdUFHOEFiQUJ2QUdjQTdRQmhBQ0FBZVFBZ0FFTUFaUUJ5QUhRQWFRQm1BR2tBWXdCaEFHTUFhUUR6QUc0QUlBQkZBR3dBWlFCagpBSFFBY2dEekFHNEFhUUJqQUdFQUxBQWdBRU1BU1FCR0FDQUFVUUEwQURZQU1BQXhBREVBTlFBMkFFVUFLUUF1QUNBQVF3QlFBRk1BCklBQmxBRzRBSUFCb0FIUUFkQUJ3QURvQUx3QXZBSGNBZHdCM0FDNEFZUUJqQUdNQWRnQXVBR1VBY3pBd0JnZ3JCZ0VGQlFjQ0FSWWsKYUhSMGNEb3ZMM2QzZHk1aFkyTjJMbVZ6TDJ4bFoybHpiR0ZqYVc5dVgyTXVhSFJ0TUZVR0ExVWRId1JPTUV3d1NxQklvRWFHUkdoMApkSEE2THk5M2QzY3VZV05qZGk1bGN5OW1hV3hsWVdSdGFXNHZRWEpqYUdsMmIzTXZZMlZ5ZEdsbWFXTmhaRzl6TDNKaGFYcGhZMk4yCk1WOWtaWEl1WTNKc01BNEdBMVVkRHdFQi93UUVBd0lCQmpBWEJnTlZIUkVFRURBT2dReGhZMk4yUUdGalkzWXVaWE13RFFZSktvWkkKaHZjTkFRRUZCUUFEZ2dJQkFKY3hBcC9uL1VOblNFUVU1Q21IN1V3b1p0Q1BOZHBOWWJkS2wwMjEyNURnQlM0T3hublE4cGRwRDcwRQpSOW0rMjdVcDJwdlpycW1aMWRNOE1KUDFqYUdvL0FhTlJQVEtGcFY4TTl4aWk2ZzMrQ2ZZQ1MwYjc4Z1VKeUNwWkVUL0x0WjFxbXhOCllFQVpTVU5VWTlyaXpMcG01VTlFZWx2WmFvRXJRTlYvK1FFbldDekk3VWlSZkQrbUFNL0VLWE1STnQ2R0dUNmQ3aG1LRzlXdzdZNDkKbkNyQURkZzladU04RGIzVmxGemk0cWMxR3dRQTlqOWFqZXBEdlYrSkhhbkJzTXlaNGswQUN0ckpKMXZuRTVCYzVQVXpvbFZ0M09BSgpUUyt4SmxzbmRRQUp4R0ozS1FoZm5sbXN0bjZ0bjFRd0lnUEJIbkZrL3ZrNENwWVkzUUlVckNQTEJod2VwSDJORGQ0blFlaXQyaFczCnNDUGRLNmpUMmlXSDdlaFZSRTJJOURaK2hKcDRyUGNPVmtrTzFqTWwxb1JRUW13Z0VoMHExYjY4OG5DQnBIQmd2Z1cxbTU0RVJMNWgKSTZ6cHBTU01FWUNVV3FLaXVVblN3ZHpScCsweEVTeWVHYWJ1NFZYaHdPclBEWVRrRjdlaWZLWGVWU1VHN3N6QWgxeEEyc3lWUDFYZwpOY2U0aEw2MFhjMTZnd0Z5N29mbVh4MnV0WVhHSnQvbXdacnBIZ0pIbnlxb2JhbGJ6K3hGZDMrWUo1b3lYU3JqaE83Rm1HWXZsaUFkCjNkakRKOWV3K2Y3WmZjM1FuNDhMRkZoUm55K0x3emd0M3VpUDFvMkhwUFZXUXhhWkxQU2tWclEwdUdFM3ljSllnQnVnbDZIOFdZM3AKRWZiUkQwdFZORVlxaTRZNwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUV0NBIEdsb2JhbCBSb290IENBCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZRVENDQXltZ0F3SUJBZ0lDREw0d0RRWUpLb1pJaHZjTkFRRUxCUUF3VVRFTE1Ba0dBMVVFQmhNQ1ZGY3hFakFRQmdOVkJBb1QKQ1ZSQlNWZEJUaTFEUVRFUU1BNEdBMVVFQ3hNSFVtOXZkQ0JEUVRFY01Cb0dBMVVFQXhNVFZGZERRU0JIYkc5aVlXd2dVbTl2ZENCRApRVEFlRncweE1qQTJNamN3TmpJNE16TmFGdzB6TURFeU16RXhOVFU1TlRsYU1GRXhDekFKQmdOVkJBWVRBbFJYTVJJd0VBWURWUVFLCkV3bFVRVWxYUVU0dFEwRXhFREFPQmdOVkJBc1RCMUp2YjNRZ1EwRXhIREFhQmdOVkJBTVRFMVJYUTBFZ1IyeHZZbUZzSUZKdmIzUWcKUTBFd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUN3QmR2STY0ekVib29oNzQ1Tm5IRUtIMUp3N1cyQwpuSmZGMTB4T1JVbkxRRUsxRWpSc0djSjBwREZmaFFLWDdFTXpDbFBTbkl5T3Q3aDUyeXZWYXZLT1pzVHVLd0VIa3RTejBBTGZVUFpWCnIyWU95K0JIWUM4ck1qazFVam9vZy9oN0ZzWVl1R0xXUnlXUnp2QVpFazJ0WS9YVFAzVmZLZkNoTUJ3cW9KaW1GYjN1L1JrMjhPS1IKUTQvNnl0WVFKMGxNNzkzQjhZVndtOHJxcUZwRC9HMkdiM1BwTjBXcDhEYkh6SWgxSHJ0c0J2K2JhejRYN0dHcWNYekdIYUwzU2VrVgp0VHpXb1dIMUVmY0ZieDM5RWI3UU1BZkNLYkFKVGliYzQ2S29rV29md3BGRmlGemxtTGh4cFJVWnlYeDFFY3h3ZEU4dG14MlJSUDFXCktLRCt1NFpxeVBwY0MxamN4a3QyeUtzaTJYTVBwZlJhQW9rL1Q1NGlndTZpZEZNcVBWTW5hUjFzampJc1pBQW1ZMkUyVHFOR3R6OTkKc3kyc2JaQ2lsYUxPejlxQzV3YzBHWmJwdUNHcUtYNm1PTDZPS1VvaFpua2ZzOE8xQ1dmZTF0UUhSdk1xMnVZaU4yRExnYllQb0EvcAp5SlYvdjFXUkJYclBQUlhBYjk0SmxBR0QxelFiekVDbDhMaWJaOVdZa1R1bmhIaVZKcVJhQ1BncmRMUUFCRHpmdUJTTzZOK3BqV3huCmtqTWR3TGZTN0pMSXZnbS9MQ2tGYndKcm51Kzh2eXE4VzhCUWowRndjWWV5VGJjRXFZU2pNcSt1N21zWGk3S3gvbXpoa0l5SXFKZEkKenNoTnkvTUd6MTlxQ2tLeEhoNTNMNDZnNXBJT0J2d0ZJdEltNFRGUmZUTGNEd0lEQVFBQm95TXdJVEFPQmdOVkhROEJBZjhFQkFNQwpBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBWHpTQmR1K1dIZFhsdGRrQ1k0UVd3YTZnCmNGR245MHhITmNnTDF5ZzlpWEhacWpOQjZoUWJiQ0VBd0d4Q0dYNmZhVnNnUXQraTB0ckVmSmRMamJEb3JNanVwV2tFbVFxU3Bxc24KTGhwTmdiK0UxSEFlclVmKy9VcWRNK0R5dWNSRkNDRUsybWxwYzNJTnZqVCtsSXV0d3g0MTE2S0Q3K1U0eDZXRkg2dlBOT3cvS1A0TQo4VmVHVHNsVjl4elUyS1Y5Qm5wdjFkOFEzNEZPSVdXeHR1RVhlWlZGQnM1ZnpOeEdpV05vUkkyVDlHUndvRDJkS0FYRE9YQzRZbnNnCi9lVGI2UWlodUo0OUNjZFAreXo0azNaQjNsTGc0VmZTblFPOGQ1NytuaWxlOThGUllCL2UyZ3V5TFhXM1EwaVQ1L1o1eG9SZGdGbGcKbFB4NG1JODhrMUh0UUpBSDMyUmpKTXRPY1FXaDE1UWFpREx4SW5RaXJxV20yQkpwVEdDakF1NHI3TlJqa2d0ZXZpOTJhNk8ySnJ5UApBOWdLOGt4a1JyMDVZdVdXNnpSakVTak1sZkd0NysvY2dGaEk2VXU0Nm1XczZmeUF0YlhJUmZtc3daL1p1ZXBpaUk3RThVdURFcTNtCmk0VFduc0xyZ3hpZmFyc2JKR0F6Y016czl6THpYTmw1ZmUrZXBQN0pJOE1rN2hXU3NUMlJUeWFHdldaekpCUHFwSzVqd2ExOWhBTTgKRUhpR0czbmp4UFB5QkpVZ3JpT0N4TE02QUdLLzVqWWs0VmU2eHg2UWRkVmZQNVZoSzhFN3plV3phR0hRUmlhcElWSnBMZXN1eCt0Mwp6cVk2dFFNelQzYlI1MXhVQVYzTGVQVEpETC9QRW80WExTTm9sT2VyL3FteUt3YlFCTTA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRlbGlhU29uZXJhIFJvb3QgQ0EgdjEKPT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRk9EQ0NBeUNnQXdJQkFnSVJBSlcrRnFEM0xrYnhlem1DY3ZxTHpaWXdEUVlKS29aSWh2Y05BUUVGQlFBd056RVVNQklHQTFVRQpDZ3dMVkdWc2FXRlRiMjVsY21FeEh6QWRCZ05WQkFNTUZsUmxiR2xoVTI5dVpYSmhJRkp2YjNRZ1EwRWdkakV3SGhjTk1EY3hNREU0Ck1USXdNRFV3V2hjTk16SXhNREU0TVRJd01EVXdXakEzTVJRd0VnWURWUVFLREF0VVpXeHBZVk52Ym1WeVlURWZNQjBHQTFVRUF3d1cKVkdWc2FXRlRiMjVsY21FZ1VtOXZkQ0JEUVNCMk1UQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU1LKwo2eWZ3SWFQemFTWlZmcDNGVlJhUlhQM3ZJYjlUZ0hvdDBwR01Zekh3N0NUd3c2WFNjbndRYmZRM3QrWG1mSG5xakxXQ2k2NUl0cXdBCjNHVjE3Q3BOWDhHSDlTQmxLNEdvUno2Skk1VXdGcEIvNkZjSFNPY1pycjlGWjdFM0d3WXEvdDc1ckgyRCsxNjY1SStYWjc1TGpvMWsKQjFjNFZXazBOajBUU085UDR0Tm1IcVRQR3JkZU5qUFV0QWE5R0FIOWQ0UlFBRVgxakYzb0k3eCsvalhoN1ZCN3FUQ05HZE1Kam1obgpYYjg4bHhoVHV5bGl4Y3BlY3NISGx0VGJMYUMwSDJrRDdPcmlVUEVNUFBDczgxTXQ4QnoxN1d3NU9YT0FGc2hTc0NQTjREN2MzVHhICm9MczFpdUtZYUl1KzViOXk3dEw2cGUwUzdmeVlHS2ttZHR3b1N4QWdITk4vRm5jdDdXK0E5MG03VXdXN1hXakgxTWgxRmorSldvdjMKRjBmVVRQSFNpWGsrVFQyWXFHSGVPaDdTK0Y0RDRNSEpISXpUalUzVGxUYXpOMTlqWTVzekZQQXRKbXRUZkltTU1zSnU3RDBoQURuSgpvV2ppVUlNdXNEb3I4emFnckMva2IySENVUWs1UG90VHVidG4ydHhUdVhaWk5wMUQ1U0RnUFRKZ2hTSlJ0OGN6dTkwVkw2UjRwZ2Q3CmdVWTJCSWJkZVRYSGxTdzdzS01YTmVWekg3UmNXZS9hNmhCbGUzclFmNSt6dENvM08zQ0xtMXU1Szdmc3NsRVNsMU1wV3RUd0VoRGMKVHdLN0VwSXZZdFEvYVVOOERkYjhXSFVCaUoxWUZrdmV1cEQvUndHSkJtcjJYN0tRYXJNQ3BnS0l2N05IZmlyWjFmcG9lRFZOQWdNQgpBQUdqUHpBOU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0N3WURWUjBQQkFRREFnRUdNQjBHQTFVZERnUVdCQlR3ajFrNEFMUDFqNXFXCkROWHIrbnVxRitnVEVqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUF2dVJjWWs0azlBd0kvL0RUREdqa2swa2lQMFFuYjd0dDNvTm0KenFqTURmejFtZ2JsZHhTUjY1MUJlNWtxaE9YLy9DSEJYZkRrSDFlM2RhbWhYd0ltLzlmSDkwN2VUL2ozSEViQWVrOUFMQ0kxOEJteAowR3RuTExDbzRNQkFOelgyaEZ4YzQ2OUNlUDZueVExUTZnMkVkdlpSNzROVHhuci9EbFpKTG85NjFnem1KMVRqVFFwZ2NtTE5rUWZXCnBiL0ltV3Z0eEJubXEwd1JPTVZ2TWVKdVNjZy9kb0FtQXlZcDREYjI5aUJUNHhkd05CZWRZMmdlYSt6RFRZYTRFekF2WFVZTlIwUFYKRzZwWkRybGNqUVpJclhTSFg4ZjhNVlJCRStMSElRNmU0QjRONGNCN1E0V1F4WXBZeG1VS2VGZnl4aU1QQWRrZ1M5NFArNUtGZFNwYwpjNDF0ZXlXUnl1NUZyZ1pMQU16VHNWbFEyanFJT3lsRFJsNlhLMVRPVTIrTlN1ZVcrcjl4RGtLTGZQMG9vTkJJeXRyRWdVeTdvbk9UCkpzanJETlltaUxiQUpNKzd2VnZyZFgzcENJNkdNeXg1ZHdscHBZbjhzM0NRaDNhUDB5SzdRczY5Y3dzZ0ppclFtejF3SGlSc3pZZDIKcVJlV3Q4OE5rdnVPR0ttWVNkR2UvbUJFY2lHNUdlM0M5VEh4T1VpSWtDUjFWQmF0enZUNGFSUmtPZnVqdUxwd1FNY25ITC9FVmxQNgpZMlhROHh3T0Z2VnJobGhOR05Ua0RZNmxuVnVSM0hZa1VEL0dLdnZadDV5MTF1YlEyZWdaaXhWeFNLMjM2dGhaaU5TUXZ4YXoyZW1zCldXRlV5Qnk2eXNISzRia2dUSTg2azRtbG9NeS8wL1oxcEhXV2JWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRS1UdWdyYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHU3pDQ0JET2dBd0lCQWdJSWFtZytuRkdieTFNd0RRWUpLb1pJaHZjTkFRRUxCUUF3Z2JJeEN6QUpCZ05WQkFZVEFsUlNNUTh3CkRRWURWUVFIREFaQmJtdGhjbUV4UURBK0JnTlZCQW9NTjBVdFZIWEVuM0poSUVWQ1J5QkNhV3hweFo5cGJTQlVaV3R1YjJ4dmFtbHMKWlhKcElIWmxJRWhwZW0xbGRHeGxjbWtnUVM3Rm5pNHhKakFrQmdOVkJBc01IVVV0VkhWbmNtRWdVMlZ5ZEdsbWFXdGhjM2x2YmlCTgpaWEpyWlhwcE1TZ3dKZ1lEVlFRRERCOUZMVlIxWjNKaElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUI0WERURXpNRE13Ck5URXlNRGswT0ZvWERUSXpNRE13TXpFeU1EazBPRm93Z2JJeEN6QUpCZ05WQkFZVEFsUlNNUTh3RFFZRFZRUUhEQVpCYm10aGNtRXgKUURBK0JnTlZCQW9NTjBVdFZIWEVuM0poSUVWQ1J5QkNhV3hweFo5cGJTQlVaV3R1YjJ4dmFtbHNaWEpwSUhabElFaHBlbTFsZEd4bApjbWtnUVM3Rm5pNHhKakFrQmdOVkJBc01IVVV0VkhWbmNtRWdVMlZ5ZEdsbWFXdGhjM2x2YmlCTlpYSnJaWHBwTVNnd0pnWURWUVFECkRCOUZMVlIxWjNKaElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEEKTUlJQ0NnS0NBZ0VBNHZVL2t3VlJIb1ZpVkY1NkMvVVlCNE91ZnE5ODk5U0thNlZqUXptNVMvZkR4bVNKUFpRdVZJQlNPVGtIUzB2ZApoUWQyaDh5L0w1Vk16SDJuUGJ4SEQ1aHcrSXlGSG5TT2ttMGJRTkdaRGJ0MWJzaXBhNXJBaERHdnlrUEw2eXMwNkkrWGF3R2IxUTVLCkNLcGJrblNGUTlPQXJxR0lXNjZ6Nmw3TEZwcDNSTWloOWxSb3p0NlBseXU2VzBBQ0RHUVh3TFdUemVIeEUyYk9ESG52MFpFb3ExK2cKRWxJd2N4bU9qK0dNQjZMRHUwcnc2aDhWcU80bHpLUkcrQnNpNzdNT1E3b3NKTGpGTEZ6VUhQaGRaTDNEazE0b3B6OG44WTRlMHlwUQpCYU5WMmN2bk9WUEFtSjZNVkdLTEpyRDNmWTE4NU1hZVprSlZna2Zuc2xpTlp2Y0hmQzQyNWxBY1A5dERKTVcvaGtkNXMza2M5MXIwCkUreHMrRC9pV1IrVjdrSSt1YTJvTW9WSmwwYitTekdQV3N1dGRFY2Y2WkczM3lnRUlxRFVEMTNpZVUvcWJJV0d2YWltenVUNncrR3oKcnQ0OFVlN0xFM3dCZjRRT1hWR1VuaE1NdGk2bFRQazVjRFp2bHNvdURFUlZ4Y3I2WFFLajM5WmtqRnF6QVFxcHRRcEhGLy92a1VBcQpqcUZHT2pHWTVSSDh6THRKVm9yOHVkQmhtbTlsYk9iRHl6NTFTZjZQcCtLSnhXZlhuVVlUVGpGMk95U3puaEZsaHF0Lzd4M1UrTHpuCnJGcGN0MXBIWEZYT1ZiUWljVnRiQy9EUDNLQmhaT3FwMTJnS1k2ZmdEVCtncjlPcTBuN3ZVYURtVVN0VmtoVVhVOHUzWmc1bVRQajUKZFV5UTV4Snd4MFVDQXdFQUFhTmpNR0V3SFFZRFZSME9CQllFRkM3ajI3SkowSnhVZVZ6Nkp5cit6RTdTNkU1VU1BOEdBMVVkRXdFQgovd1FGTUFNQkFmOHdId1lEVlIwakJCZ3dGb0FVTHVQYnNrblFuRlI1WFBvbkt2N01UdExvVGxRd0RnWURWUjBQQVFIL0JBUURBZ0VHCk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQUZOenIwVGJkRjRrVjFKSSsyZDFMb0hOZ1FrMlh6OGxrR3BENGVLZXhkMGRDcmZPQUsKa0VoNDdVNllBNW4rS0dDUkhUQWR1R044cU9ZMXRmclRZWGJtMWdkTHltbWFzb1I2ZDVORkZ4V2ZKTkNZRXhML3U2QXUvVTVNaC9qTwpYS3FZR3dYZ0FFWktnb0NsTTRzbzNPMDQwOS9sUHVuKysxbmRZWVJQMGxTV0UyRVRQbytBYWI2VFI3VTFROUphdXoxYzc3TkNSODA3ClZSTUdzQW5iL1dQMk9vZ0ttVzkrNGM0YlUycEVaaU5SQ0h1OFcxS2kvUVkzT0VCaGowcVd1SkEzK0diSGVKQUFGUzZMclZFMVV3ZW8KYTJpdStVNDhCeWJOQ0FWd3pEay9kcjJsMDJjbUFZYW1VOUpnTzN4RGYxV0t2SlVhd1NnNVRCOUQwcEgwY2xtS3VWYjhQN1NkMm5DYwpkbHFNUTFEdWpqQnlUZC8vU2ZmR3FXZlpiYXdDRWVJNkZpV25XQWpMYjFOQm5FZzRSMmd6MGRmSGo5UjBJZFREQlpCNi84NldpTEVWCktWMGpxOUJnb1JKUDN2UVh6VExseWIvSVE2MzlMbzd4citMMG1Qb1NIeURZd0tjTWhjV1E5RHN0bGlheExMNU1xK3V4MG9ySjIzZ1QKRHg0Sm5XMlBBSjhDMnNINkgzcDZDY1JLNW9ncWw1K0ppLzAzWDE4NnpqaFpoa3V2Y1F1MDJQSndUNTh5RStPd3AxZmwydHBEeTRRMAo4aWpFNm0zMEt1L0JhM2JhKzM2N2hUelNVOEpOdm5IaFJkSDlJMmNORTNYN3oyVm5JcDJ1c0FuUkNmOGROTC8rSTVjMzBqbjZQUTBHCkM3VGJPNk9yYjF3ZHRuN29zNEkwN1FaY0pBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVC1UZWxlU2VjIEdsb2JhbFJvb3QgQ2xhc3MgMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEd3pDQ0FxdWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUXNGQURDQmdqRUxNQWtHQTFVRUJoTUNSRVV4S3pBcEJnTlZCQW9NCklsUXRVM2x6ZEdWdGN5QkZiblJsY25CeWFYTmxJRk5sY25acFkyVnpJRWR0WWtneEh6QWRCZ05WQkFzTUZsUXRVM2x6ZEdWdGN5QlUKY25WemRDQkRaVzUwWlhJeEpUQWpCZ05WQkFNTUhGUXRWR1ZzWlZObFl5QkhiRzlpWVd4U2IyOTBJRU5zWVhOeklESXdIaGNOTURneApNREF4TVRBME1ERTBXaGNOTXpNeE1EQXhNak0xT1RVNVdqQ0JnakVMTUFrR0ExVUVCaE1DUkVVeEt6QXBCZ05WQkFvTUlsUXRVM2x6CmRHVnRjeUJGYm5SbGNuQnlhWE5sSUZObGNuWnBZMlZ6SUVkdFlrZ3hIekFkQmdOVkJBc01GbFF0VTNsemRHVnRjeUJVY25WemRDQkQKWlc1MFpYSXhKVEFqQmdOVkJBTU1IRlF0VkdWc1pWTmxZeUJIYkc5aVlXeFNiMjkwSUVOc1lYTnpJREl3Z2dFaU1BMEdDU3FHU0liMwpEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNxWDlvYlgraHprZVhhWFBTaTVrZmw4MmhWWUFVZEFxU3ptMW56SG9xdk5LMzhEY0xaClNCbnVhWS9KSVB3aHFnY1o3YkJjckdYSFgrMENmSHQ4TFJ2V3VybUF3aGlDRm9UNlpyQUl4bFFqZ2VUTnVVay85azl1TjBnb09BL0YKdnVkb2NQMDVsMDNTeDVpUlVLckVSTE1qZlRsSDZWSmkxaEtUWHJjeGxrSUYrM2FuSHFQMXd2enBlc1ZzcVhGUDZzdDR2R0N2eDk3MAoyY3UrZmpPbGJwU0Q4RFQ2SWF2cWpuS2dQNlRlTUZ2dmhrMXFsVnREUktnUUZSemxBVmZGbVBIbUJpaVJxaURGdDFNbVVVT3lDeEdWCldPSEFEM2Jad0kxOGdmTnljSjV2L2hxTzJWODF4ckp2Tkh5K1NFL2lXam5YMkoxNG5wK0dQZ05lR1l0RW90WEhBZ01CQUFHalFqQkEKTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlMvV1NBMkFIbWdvQ0pyak5YeQpZZEs0TE11Q1NqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNUU9pWVFzZmRPaHlOc1p0K1UyZStpS280WUZXejgyN24rcXJrUms0CnI2cDhGVTN6dHFPTnBmU085a1NwcCtnaGxhMCtBR0lXaVBBQ3V2eGhJK1l6bXpCNmF6WmllNjBFSTRSWVplTGJLNHJuSlZNM1lsTmYKdk5vQllpbWlwaWR4NWpvaWZzRnZIWlZ3SUVvSE5OL3EveFdBNWJyWGV0aGJkWHdGZWlsSGZrQ29NUk4zelVBN3RGRkhlaTRSNDBjUgozcDFtMEl2VlZHYjZnMVhxZk1JcGlSdnBiN1BPNGdXRXlTOCtlSVZpYnNsZndYaGpkRmpBU0JnTW1UbnJwTXdhdFhsYWpSV2MyQlFOCjlub0hWOGNpZ3dVdFBKc2xKajBZczZsRGZNaklxMlNQRHFPL25CdWRNTnZhMEJrdXFqengrek9BZHVUTnJSbFBCU2VPRTZGdXdnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQXRvcyBUcnVzdGVkUm9vdCAyMDExCj09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGR6Q0NBbCtnQXdJQkFnSUlYRFBMWWl4ZnN6SXdEUVlKS29aSWh2Y05BUUVMQlFBd1BERWVNQndHQTFVRUF3d1ZRWFJ2Y3lCVQpjblZ6ZEdWa1VtOXZkQ0F5TURFeE1RMHdDd1lEVlFRS0RBUkJkRzl6TVFzd0NRWURWUVFHRXdKRVJUQWVGdzB4TVRBM01EY3hORFU0Ck16QmFGdzB6TURFeU16RXlNelU1TlRsYU1Ed3hIakFjQmdOVkJBTU1GVUYwYjNNZ1ZISjFjM1JsWkZKdmIzUWdNakF4TVRFTk1Bc0cKQTFVRUNnd0VRWFJ2Y3pFTE1Ba0dBMVVFQmhNQ1JFVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDVgpoVHVYYnlvN0xqdlBwdk1wTmI3UEdLdytxdG40VGFBK0drZTV2SnJmOHY3TVBrZm9lcGJDSkk0MTlLa00vSUw5YmNGeVlpZTk2bXZyCjU0ck1WRDZRVU0rQTFKWDc2TFdDMUJURnRxbFZKVmZic1ZEMnNHQmtXWHBwendPM2J3Mit5ajV2ZEhMcXFqQXFjMksrU1pGaHlCSCsKRGdNcTkyb2czQUlWRFY0VmF2empnc0cxeFoxa0NXeWpXWmdISjhjYmxpdGhkSEZzUS9IM05Za1E0SjdzVmFFM0lxS0hCQVVzUjMyMApITGxpS1dZb3lyZmhrL1drbEFPWnVYQ0Z0ZVpJNm8xUS9ObmV6RzhIRHQwTGNwMkFNQllIbFQ4b0R2M0ZkVTlUMW5TYXRDUXVqZ0tSCnozYkZteDVWZEp4NEliSHdMZkVMbjhMVmxoZ2Y4RlFpZW93SEFnTUJBQUdqZlRCN01CMEdBMVVkRGdRV0JCU25wUWF4TEtZSllPN1IKbCtsd3JydzdHV3piSVRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUI4R0ExVWRJd1FZTUJhQUZLZWxCckVzcGdsZzd0R1g2WEN1dkRzWgpiTnNoTUJnR0ExVWRJQVFSTUE4d0RRWUxLd1lCQkFHd0xRTUVBUUV3RGdZRFZSMFBBUUgvQkFRREFnR0dNQTBHQ1NxR1NJYjNEUUVCCkN3VUFBNElCQVFBbWR6VGJsRWlHS2tHZExENEdrR0RFakt3TFZMZ2Z1WHZUQnpuaytqNTdzajFPN1o4anZaZnphMXp2N3YxQXB0K2gKazZFS2hxenZJTkI1QWIxNDl4bllKREUwQkFHbXVoV2F3eWZjMkU4UHpCaGovNWtQRHBGcmRSYmhJZnpZSnNkSHQ2YlBXSEp4ZnJyaApUWlZITzhtdmJhRzB3ZXlKOXJRUE9MWGlaTndsejZiYjY1cGNtYUhGQ043OTV0clYxbHBGRE1TM3dyVVU3N1FSL3c0VnRmWDEyOGE5CjYxcW44RllpcVR4bFZNWVZxTDJHbnMyRGxtaDZjWUdKNFF2aDZoRWJhQWpNYVo3c25rR2VSREltZXVLSENuRTk2K1JhcE5MYnhjM0cKM21CL3VmTlBSSkx2S3JjWVBxY1oyUXQ5c1RkQlFyQzZZQjN5L2drUnNQQ0hlNmVkCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClF1b1ZhZGlzIFJvb3QgQ0EgMSBHMwo9PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZZRENDQTBpZ0F3SUJBZ0lVZUZoZkxxMHNHVXZqTndjMU5CTW90WmJVWlpNd0RRWUpLb1pJaHZjTkFRRUxCUUF3U0RFTE1Ba0cKQTFVRUJoTUNRazB4R1RBWEJnTlZCQW9URUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4SGpBY0JnTlZCQU1URlZGMWIxWmhaR2x6SUZKdgpiM1FnUTBFZ01TQkhNekFlRncweE1qQXhNVEl4TnpJM05EUmFGdzAwTWpBeE1USXhOekkzTkRSYU1FZ3hDekFKQmdOVkJBWVRBa0pOCk1Sa3dGd1lEVlFRS0V4QlJkVzlXWVdScGN5Qk1hVzFwZEdWa01SNHdIQVlEVlFRREV4VlJkVzlXWVdScGN5QlNiMjkwSUVOQklERWcKUnpNd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUNndmxBUWp1bnliRUMwQkp5RnVUSEszQzNrRWFrRQpQQnRWd2VkWU1CMGt0TVB2aGQ2TUxPSEJQZCtDNWsrdFI0ZHM3RnRKd1VyVnU0L3NoNngvZ3BxRzdEMERtVklCMGpXZXJOcndVOGxtClBOU3NBZ0hhSk5NN3FBSkdyNlFjNC9oeldIYTM5ZzZRRGJYd3o4ejYrY1pNNWNPR01BcU5GMzQxNjhYZnV3NmN3STJINDRnNGhXZjYKUHNlcjRCT2NCUmlZejVQMXNaSzAvQ1BUejlYRUowbmduanliQ0tPTFhTb2g0UHc1cWxQYWZYN1BHZ2xUdkYwRkJNK2hTbytMZG9JTgpvZmpTeHhSM1c1QTJCNEdiUGdiNlVsNWp4YVlBL3FYcFVodFN0Wkk1Y2dNSllyMndZQlp1cHQwbHdnTm0zZk1FMFVEaVRvdUc5Ry9sCmc2QW5oRjRFd2ZXUXZUQTl4TytvYWJ3NG02U2tsdEZpMm1uQUFaYXV5OFJSTk9vTXF2OGhqbG1QU2x6a1lacW4wdWtxZUkxUlBUb1YKN3FKWmpxbGMzc1g1a0NMbGlFVngzWkdaYkhxZlBUMllmRjcydmhab29GNnVDeVA4V2crcUluWXR5YUVRSGVUVFJDT1FpSi9HS3ViWAo5WnF6V0I0dk1Ja0lHMVNpdFpnajdBaDNISlZkWWRITGlaeGZva3FSbXU4aHFra1dDS2k5WVNneHlYU3RoZmJaeGJHTDBlVVFNazFmCml5QTZQRWtmTTRWWkRkdkxDWFZEYVhQN2EzRjk4Ti9FVEgzR295N0lsWG5MYzZLT1RrMGsrMTdrQkw1eUc2WW5MVWxhbVhyWFhBa2cKdDMrVXVVL3hEUnhlaUVJYkViZm5rZHVlYlBScTM0d0dtQU90ekNqdnBVZnpVd0lEQVFBQm8wSXdRREFQQmdOVkhSTUJBZjhFQlRBRApBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJCakFkQmdOVkhRNEVGZ1FVbzVmVzgxNmlFT0dyUlo4OEYyUTg3Z0Z3bk13d0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnSUJBQmo2VzNYOFBuckhYM2ZIeXQvUFg4TVN4RUJkMURLcXVHclgxUlVWUnBnanBlYVFXeGlaVE9PdFFxT0MKTVRhSXplbjd4QVNXU0lzQng0MEJ6MXN6QnBaR1puUWRUKzNCdHJtMERXSE1ZMzdYTG5lTWxod3FJMmhyaFZkMmNETVQvdUZQcGlOMwpHUG9hak9pOVpjblBQL1RKRjl6cng3ekFCQzR0Umk5cFpzTWJqLzdzUHRQS2xMOTJDaVVOcVhzQ0hLblFPMThMd0lFNlBXVGh2NmN0ClRyMU54TmdweGlJWTBNV3NjZ0tDUDZvNm9qb2lsekhkQ0dQRGRSUzVZQ2d0VzJqZ0ZxbG1naU5SOWV0VDJER2JlK20zblV2cmlCYlAKK1YwNGlra3dqKzN4NnhuMGR4b3hHRTFuVkd3dmIyWDUyejNzSWV4ZTlQU0x5bUJsVk5GeFpQVDVwcU9CTXpZemNmQ2tlRjlPcllNaAozalJKamVoWnJKM3lkbG8yOGhQMHIrQUp4MkVxYlBmZ25hNjdoa29vYnk3dXRIbk5rRFBEczNiNjlmQnNuUUdRK3A2UTlweHl6MGZhCnd4L2tOU0JUOGxUUjMyR0RwZ0xpSlRqZWhUSXRYbk9RVWwxQ3hNNDlTK0g1R1lRZDFhSlF6RUg3UVJURHZkYkpXcU5qWmdLQXZRVTYKTzBlYzdBQW1UUFdJVWIrb0kzOFlCN0FMN1lzbW9XVFRZVXJyWEovZXM2OW5BN01mM1cxZGFXaHBxMTQ2N0h4cHZNYzdoVTZlRmJtMApGVS9EbFhwWTE4bHM2V3k1OHlsalhyUXM4QzA5N1ZwbDRLbGJRTUpJbVlGdG5oOEdLandTdElzUG02SWs4S2FOMW5yZ1M3WmtsbU9WCmhNSkt6Und1SkljellPWEQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKUXVvVmFkaXMgUm9vdCBDQSAyIEczCj09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRllEQ0NBMGlnQXdJQkFnSVVSRmMwSkZ1QmlaczE4czY0S3p0YnB5YndkU2d3RFFZSktvWklodmNOQVFFTEJRQXdTREVMTUFrRwpBMVVFQmhNQ1FrMHhHVEFYQmdOVkJBb1RFRkYxYjFaaFpHbHpJRXhwYldsMFpXUXhIakFjQmdOVkJBTVRGVkYxYjFaaFpHbHpJRkp2CmIzUWdRMEVnTWlCSE16QWVGdzB4TWpBeE1USXhPRFU1TXpKYUZ3MDBNakF4TVRJeE9EVTVNekphTUVneEN6QUpCZ05WQkFZVEFrSk4KTVJrd0Z3WURWUVFLRXhCUmRXOVdZV1JwY3lCTWFXMXBkR1ZrTVI0d0hBWURWUVFERXhWUmRXOVdZV1JwY3lCU2IyOTBJRU5CSURJZwpSek13Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ2hyaVd5QVJqY1Y0Zy9SdXY1citMckkzSGltdEZoClppRmZxcThuVWVWdUd4YlVMWDFRc0ZOM3ZYZzZZT0prQXB0OGhwdldHbzZ0L3g4VmY5V1ZIaExMNWhTRUJNSGZOck1XbjRyanlkdVkKTk03WU14Y29SdnlueWZEU3ROVk5DWEpKK2ZLSDQ2bmFmYUY5YTdJNkphbHRVa1NzK0w1dSs5eW1jNUdRWWFZREZDRHk1NGVqaUsydApvSXovcGdzbFVpWG5GZ0hWeTdnMWdReWpPL0RoNGZ4YVhjNkFjVzM0U2FzK083cTQxNEFCKzZYclc3UEZYbUFxTWFDdk4rZ2dPcCtvCk1pd016QWtkMDU2T1hieE1tTzdGR21oNzdGT202UlExbzkvTmdKOE1TUHNjOVBHL1NyajYxWXh4U3NjZnJmNUJtck9EWGZLRVZ1K2wKVjBQT0thMk1xMVcveFB0YkFkMGpJYUZZQUk3RDBHb1Q3UlBqRWl1QTNHZm1sYkxOSGlKdUt2aEIxUExLRkFlTmlsVVN4bW4xdUlabwpMMU5lc05LcUljR1k1akRqWjFYSG0yNnNHYWhWcGtVRzBDTTYyK3RsWFNvUkVmQTdUOHB0OURURWNlVC9BRnIyWEs0allJVno4ZVFRCnNTV3UxWks3RThFTTREbmF0RGxYdGFzMXFuSWhPNE0xNXpIZmVpRnV1RElJZlIweWtSVktZbkxQNDNlaHZOVVJHM1lCWndqZ1FRdkQKNnhWdStLUVoyYUtycitJblVsWXJBb29zRkNUNXYwSUN2eWJJeG8vZ2JqaDlVeTNsN1ppemxXTm9mL2sxOU4rSXhXQTFrc0I4YVJ4aApsUmJRNjk0THJ6NEVFRVZsV0ZBNHIwanlXYllXOGp3TmtBTEdjQzRCclR3VjF3SURBUUFCbzBJd1FEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVU3ZWR2ZGxxL1lPeEpXOGFsZDd0eUZuR2J4RDB3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dJQkFKSGZnRDlEQ1g1eHd2ZnJzNGlQNFZHeXZEMTErU2hkeUx5Wm0zdGRxdVhLNFFyMzZMTFRuOTFuTVg2NgpBYXJIYWtFN2tOUUlYTEpnYXBEd3lNNERZdm1MN2Z0dUt0d0dUVHdwRDRrV2lsaE1TQS9vaEdIcVBIS21kK1JDcm9palExaDVmcTdLCnBWTU5xVDF3dlNBWllhUnNPUHhETXVIQlIvLzQ3UEVSSWpLV25NTDJXMm1XZXlBTVEwR2FXL1paR1lqZVZZZzNVUXQ0WEFvZW8wTDkKeDUySUQ4RHllQUlrVkpPdmlZZUl5VXFBSGVyUWJqNWhMamE3TlE0bmx2MW1ORHRoY25QeEZseEhCbFJKQUhwWUVyQUs3NFg5c2JnegpkV3FUSEJMbVlGNXZIWC9KSHlQTGhHR2ZIb0pFK1YrdFlsVWttbEtZN1ZIbm9YNlhPdVl2SHhIYVU0QXNoWjZyTlJEYklsOXF4VjZYClUvSXlBZ2t3bzFqd0RRSFZjc2F4ZkdsN3cvVTJSY3hoYmw1TWxNVmVydWdPWG91Lzk4M2c3YUVPR3pQdVZCaitENzd2Zm9SclErTncKbU50ZGRiSU5XUWVGRlNNNTF2SGZxU1lQMWtqSHM2WWk5VE0zV3BWSG4zdTZHQlZ2LzlZVVpJTkowZ3BuSWRzUE5XTmdLQ0xqc1pXRAp6WVdtM1M4UDUyZFNicnN2aFh6MVNuUG54VDdBdlNFU0JULzh0d05KQWx2SUplYmlWRGoxZVllTUhWT3lUb1Y3QmpqSExQajRzSEtOCkplVjNVdlFESEVpbVVGK0lJREJ1OG9KRHF6MlhoT2RUK3lIQlR3OGltb2E0V1NyMlJ6MFppQzNvaGVHZTdJVUlhckZzTk1rZDdFZ3IKTzNqdFpzU09lV21EM24rTQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpRdW9WYWRpcyBSb290IENBIDMgRzMKPT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGWURDQ0EwaWdBd0lCQWdJVUx2V2JBaWluMjNyLzFhT3A3cjBEb004U2FoMHdEUVlKS29aSWh2Y05BUUVMQlFBd1NERUxNQWtHCkExVUVCaE1DUWsweEdUQVhCZ05WQkFvVEVGRjFiMVpoWkdseklFeHBiV2wwWldReEhqQWNCZ05WQkFNVEZWRjFiMVpoWkdseklGSnYKYjNRZ1EwRWdNeUJITXpBZUZ3MHhNakF4TVRJeU1ESTJNekphRncwME1qQXhNVEl5TURJMk16SmFNRWd4Q3pBSkJnTlZCQVlUQWtKTgpNUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNYVcxcGRHVmtNUjR3SEFZRFZRUURFeFZSZFc5V1lXUnBjeUJTYjI5MElFTkJJRE1nClJ6TXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDenl3NFFaNDdxRkplbk1pb0tWalovYUV6SHMyODYKSXhTUi94bC9wY3FzN3JOMm5YcnBpeHVyYXpIYitndFRUSy9GcFJwNVBJcE0vNnpmSmQ1TzJZSXlDMFRleXR1TXJLTnVGb003cG1STApNb243RmhZNGZ1dEQ0dE4wU3NKaUNuTUszVW16VjlLd0NvV2RjVHplbzh2QU12TUJPU0JER3pYUlU3T3g3c1dUYVlJK0ZyVW9ScUhlCjZva0o3VU80QlVhS2h2VlpSNzRiYndFaEVMbjlxZElveWhBNUNjb1ROcytjcmExQWRIa3JBajgwLy9vZ2FYM1Q3bUgxdXJQbk1OQTMKSTRaeVlVVXBTRmxvYjNlbUxvRytCMDF2cjg3RVJST1JGSEFHangrZitJZHBzUTd2dzRrWjYrb2NZZng2YklyYzFnTUxuaWE2RXQzVQpWRG1ySnFNejZuV0IyaTNORDAva0E5SHZGWmNiYTVERkFwQ1RaZ0loc1VmZWk1cEtnTGxWajdXaUw4RFdNMmZhZnNTbnRBUkU2MGY3CjVsaTU5d3p3ZXl1eHdIQXB3MEJpTFR0SWFkd2pQRWpyZXdsNXFXM2FxRENZejRCeUE0aW1XMGF1Y25sOENBTWhaYTYzNFJ5bHNTcWkKTWQ1bUJQZkFkT2h4M3Y4OVdjeVdKaEtMaFpWWEdxdHJkUXRFUFJFb1BIdGh0K0tQWjAvbDdEeE1ZSUJwVnpnZUFWdU5WZWpIMzhETQpkeU0wU1hWODlwZ1I2eTNlN1VFdUZBVUNmK0QrSU9zMTV4R3NJczVYUGQ3Sk1HMFFBNFhOOGYrTUZyWEJzajZJYkdCL2tFK1Y5L1l0CnJRRTVCd1Q2ZFlCOXYwbFE3ZS9KeEh3YzY0QisyN2JRM1JQK3lkT2MxN0tYcVFJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQUQKQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVXhoZlF2S2pxQWtQeUd3YVpYU3VRSUxuWG5PUXdEUVlKS29aSQpodmNOQVFFTEJRQURnZ0lCQURSaDJWYTFFb2RWVGQyak5URkd1NlFIY3J4ZllXTG9wZnNMTjdFOHRyUDZLWjEvQXZXa3lhaVR0M3B4CktHbVBjK0ZTa05yVnZqcmx0M1pxVm9BaDMxM202VHFlNVQ3Mm9tbkhLZ3F3R0VmY0lIQjlVcU0rV1h6QnVzbklGVUJoeW5MV2NLelMKdC9BYzVJWXA4TTd2YUdQUXRTQ0tGV0dhZm9hWXRNbkNkdnZNdWpBV3pLTmh4blFUNVd2dm94WHFBLzRUaTJUazA4SFM2SVQ3U2RFUQpUWGxtNjZyOTlJMHhIbkFVcmR6ZVp4Tk1nUlZodkxmWmtYZHhHWUZndS9CWXBiV2NDL2VQSWxVbndFc0JiVHVaRGRRZG0yTm5MOUR1CkRjcG12SlJQcHEzdC9PNWpyRmMvWlNYUHNvYVAwQWovdUhZVWJ0N2xKK3lyZUxWVHViWS82Q0Q1MHFpK1lVYktoNHlFOC9ueG9HaWIKSWg2Qkpwc1FCSkZ4d0FZZjNLRFR1VmFuNDVndGY0T2QzNHdybkRLT01wVHdBVHdpS3A5RHdpN0RtRGtIT0h2OFhnQkNIL015Sm5tRApoUGJsOE1GUkVzQUxIZ1FqREZTbFRDOUp4VXJSdG01Z0RXdjhhNHVGSkdTM2lRNnJKVWRiUE05K1NiM0g2UXJHMnZkK0RoY0kwMGlYCjBIR1M4QTg1UGpScUhIM1k4aUt1dTJuME03U21TRlhSRHc0bTZPeTJDeTJuaFRYTi9WbkluOUhOUGxvcE5MazloTTZ4WmRSWmtaRlcKZFNIQmQ1NzVldUZnbmRPdEJCajBmT3RlazQ5VFNpSXArRWdyUGsyR3JGdC95d2FaV1dEWVdHV1ZqVVRSOTM5K0ozOTlyb0QxQjB5MgpQcHh4VkprRVMvMVkrWmowCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkRpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBHMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsakNDQW42Z0F3SUJBZ0lRQzVNY090WTVaK3BuSTcvRHI1cjBTekFOQmdrcWhraUc5dzBCQVFzRkFEQmxNUXN3Q1FZRFZRUUcKRXdKVlV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNRdwpJZ1lEVlFRREV4dEVhV2RwUTJWeWRDQkJjM04xY21Wa0lFbEVJRkp2YjNRZ1J6SXdIaGNOTVRNd09EQXhNVEl3TURBd1doY05Nemd3Ck1URTFNVEl3TURBd1dqQmxNUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUwKRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNRd0lnWURWUVFERXh0RWFXZHBRMlZ5ZENCQmMzTjFjbVZrSUVsRUlGSnZiM1FnUnpJdwpnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEWjV5Z3ZVajgyY2ttSWt6VHorR29lTVZTQW42MVVRYlZICjM1YW8xSytBTGJrS3ozWDlpYVY5SlByaklnd3J2SlVYQ3pPL0dVMUJCcEFBdlF4TkVQNEh0ZWNjYmlKVk1XV1h2ZE1YMGg1aTg5dnEKYkZDTVA0UU1scyszeXdQZ3ltMmhGRXdiaWQzdEFMQlNmSytSYkxFNEU5SHBFZ2pBQUxBY0t4SGFkM0EybTY3T2VZZmNnbkRtQ1hSdwpWV212bzJpZnY5MjJlYlB5blhBcFZmU3IvNVZoODhsQWJ4M1J2cE83MDRncXU1Mi9jbHBXY1RzLzFQUFJDdjRvNzZQdTJabXZBOU9QCllMZnlrcUd4dlltSkh6RE53Nll1WWpPdUZnSjNSRnJuZ1FvOHAwUXVlYmcvQkx4Y29JZmhHNjlSanMzc0xQcjQvbTN3T255cWkrUm4KbFRHTkFnTUJBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0dHTUIwR0ExVWREZ1FXQkJUTwp3MHE1bVZYeXVOdGd2NmwrdlZhMWx6YW4xakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBeXFWVmpPUElRVzVwSjZkMUVlODhoalp2CjBwM0dlRGdkYVphaWtta3VPR3liZlFUVWlhV3hNVGVLeVNITXEyek5peHlhMXI5STBqSm13WXJBOHk4Njc4RGoxSkdHMFZEakE5dHoKZDI5S09WUHQzaWJIdFgydkswTFJkV0xqU2lzQ3gxQkw0R25pbG13T1JHWVFSSSt0QmV2NGVheW1HK2czTkoxVHlXR3FvbEt2U25BVwpoc0k2eUxFVGNEYll6KzcwQ2pUVlcwejlCNXlpdXRrQmNsenpUY0hkRHJFY0RjUmp2cTMwRlB1SjdLSkJEa3pNeUZkQTBHNERxczBNCmpvbVptV3p3UERDdk9OOXZ2S08rS1NBbnEzVC9FeUo0M3BkU1ZSNkR0VlFnQSs2dXdFOVczamZNdzMrcUJDZTcwM2U0WXRzWGZKd28KSWhOemJNOG05WW9wNXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMKPT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDUmpDQ0FjMmdBd0lCQWdJUUM2RmEraDNmb0xWSlJLL05KS0JzN0RBS0JnZ3Foa2pPUFFRREF6QmxNUXN3Q1FZRFZRUUdFd0pWClV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNRd0lnWUQKVlFRREV4dEVhV2RwUTJWeWRDQkJjM04xY21Wa0lFbEVJRkp2YjNRZ1J6TXdIaGNOTVRNd09EQXhNVEl3TURBd1doY05Nemd3TVRFMQpNVEl3TURBd1dqQmxNUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzCmQzY3VaR2xuYVdObGNuUXVZMjl0TVNRd0lnWURWUVFERXh0RWFXZHBRMlZ5ZENCQmMzTjFjbVZrSUVsRUlGSnZiM1FnUnpNd2RqQVEKQmdjcWhrak9QUUlCQmdVcmdRUUFJZ05pQUFRWjU3eXNSR1h0emJnL1dQdU5zVmVwUkMwRkZmTHZDLzhRZEorMVlsSmZabjRmNWR3YgpSWGtMek1aVENwMk5YUUxacVZuZUFscjJsU29PalRoS2lrbkd2TVlET0FkZlZkcCtDVzdpZjE3UVJTQVBXWFlRMXFBazhDM2VOdkpzCktUbWpRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnR0dNQjBHQTFVZERnUVdCQlRMMEwycDRaZ0YKVWFGTk42S0RlYzZOSFNya2hEQUtCZ2dxaGtqT1BRUURBd05uQURCa0FqQWxwSUZGQW1zU1MzVjBUOGdqNDNEeWRYTGVmSW53ejVGeQpZWjVlRUpKWlZybUR4eERuT09sWUpqWjkxZVEwaGprQ01IdzJVL0F3NVdKak9wbml0cU03bXpUNkh0b1FrbkZla1JPbjNhUnVrc3d5CjF2VWhac2N2NnBaamFtVkZrcFVCdEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMgo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGpqQ0NBbmFnQXdJQkFnSVFBenJ4NXFjUnFhQzdLR1N4SFFuNjVUQU5CZ2txaGtpRzl3MEJBUXNGQURCaE1Rc3dDUVlEVlFRRwpFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzZDNjdVpHbG5hV05sY25RdVkyOXRNU0F3CkhnWURWUVFERXhkRWFXZHBRMlZ5ZENCSGJHOWlZV3dnVW05dmRDQkhNakFlRncweE16QTRNREV4TWpBd01EQmFGdzB6T0RBeE1UVXgKTWpBd01EQmFNR0V4Q3pBSkJnTlZCQVlUQWxWVE1SVXdFd1lEVlFRS0V3eEVhV2RwUTJWeWRDQkpibU14R1RBWEJnTlZCQXNURUhkMwpkeTVrYVdkcFkyVnlkQzVqYjIweElEQWVCZ05WQkFNVEYwUnBaMmxEWlhKMElFZHNiMkpoYkNCU2IyOTBJRWN5TUlJQklqQU5CZ2txCmhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdXpmTk5OeDdhOG15YUpDdFNuWC9Scm9oQ2dpTjlSbFV5ZnVJMi9PdThqcUoKa1R4NjVxc0dHbXZQckMzb1hna2tSTHBpbW43V282aCs0RlIxSUFXc1VMZWNZeHBzTU56YUh4bXgxeDdlL2RmZ3k1U0RONjdzSDBOTwozWHNzMHIwdXBTL2txYml0T3RTWnBMWWw2WnRyQUdDU1lQOVBJVWtZOTJlUXEyRUduSS95dXVtMDZaSXlhN1h6VitoZEc4Mk1IYXVWCkJKVko4elV0bHVOSmJkMTM0L3RKUzdTc1ZRZXBqNVd6dENPN1RHMUY4UGFwc3BVd3RQMU1WWXduU2xjVWZJS2R6WE9TMHhaS0JneU0KVU5HUEhnbStGNkhtSWNyOWcrVVF2SU9sQ3NSbktQWnpGQlE5Um5iRGh4U0pJVFJOcnc5RkRLWkpvYnE3bk1XeE00TXBoUUlEQVFBQgpvMEl3UURBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJoakFkQmdOVkhRNEVGZ1FVVGlKVUlCaVY1dU51CjVnLzYrcmtTN1FZWGp6a3dEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBR0JuS0pSdkRraGo2ekhkNm1jWTFZbDlQTVdMU24vcHZ0c3IKRjkrd1gzTjNLaklUT1lGblFvUWo4a1ZuTmV5SXYvaVBzR0VNTktTdUlFeUV4dHY0TmVGMjJkK21RcnZIUkFpR2Z6WjBKRnJhYkEwVQpXVFc5OGtuZHRoL0pzdzFIS2oyWkw3dGN1N1hVSU9HWlgxTkdGZHRvbS9Eek1OVStNZUtOaEo3aml0cmFsajQxRTZWZjhQbHdVSEJIClFSRlhHVTdBajY0R3hKVVRGeThiSlo5MThyR09tYUZ2RTdGQmNmNklLc2hQRUNCVjEvTVVSZVhnUlBUcWg1VXlrdzcrVTBiNkxKMy8KaXlLNVM5a0pSYVRlcExpYVdOMGJmVktmamxsRGlJR2tuaWJWYjYzZERjWTNmZTBEa2h2bGQxOTI3anlOeEYxV1c2TFpabTZ6TlRmbApNclk9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkRpZ2lDZXJ0IEdsb2JhbCBSb290IEczCj09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDUHpDQ0FjV2dBd0lCQWdJUUJWVld2UEplcERVMXc2UVAxYXRGY2pBS0JnZ3Foa2pPUFFRREF6QmhNUXN3Q1FZRFZRUUdFd0pWClV6RVZNQk1HQTFVRUNoTU1SR2xuYVVObGNuUWdTVzVqTVJrd0Z3WURWUVFMRXhCM2QzY3VaR2xuYVdObGNuUXVZMjl0TVNBd0hnWUQKVlFRREV4ZEVhV2RwUTJWeWRDQkhiRzlpWVd3Z1VtOXZkQ0JITXpBZUZ3MHhNekE0TURFeE1qQXdNREJhRncwek9EQXhNVFV4TWpBdwpNREJhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUlV3RXdZRFZRUUtFd3hFYVdkcFEyVnlkQ0JKYm1NeEdUQVhCZ05WQkFzVEVIZDNkeTVrCmFXZHBZMlZ5ZEM1amIyMHhJREFlQmdOVkJBTVRGMFJwWjJsRFpYSjBJRWRzYjJKaGJDQlNiMjkwSUVjek1IWXdFQVlIS29aSXpqMEMKQVFZRks0RUVBQ0lEWWdBRTNhZlp1NHE0Qy9zTGZ5SFM4TDYrYy9NelhScThOT3JleHB1ODBKWDI4TXpRQzdwaFcxRkdmcDR0bis2TwpZd3dYN0FkdzljK0VMa0NEbk9nL1FXMDdyZE9rRkZrMmVKMERRKzRRRTJ4eTNxNklwNkZydFVQT1o5d2ovd01jbytJK28wSXdRREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJoakFkQmdOVkhRNEVGZ1FVczl0SXBQbWh4ZGl1TmtITUVXTnAKWWltOFM4WXdDZ1lJS29aSXpqMEVBd01EYUFBd1pRSXhBSzI4OG13L0VrclJMVG5EQ2dtWGMvU0lOb3lJSjd2bWlJMVFoYWRqK1o0eQozbWFURC9ITXNRbVAzV3lyK210L29BSXdPV1pid21TTnVKNVEzS2pWU2FMdHg5elJTWDhYQWJqSWhvOU9qSWdycUpxcGlzWFJBTDM0ClZPS2E1VnQ4c3ljWAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQKPT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGa0RDQ0EzaWdBd0lCQWdJUUJac2JWNTZPSVRMaU9RZTlwM2QxWERBTkJna3Foa2lHOXcwQkFRd0ZBREJpTVFzd0NRWURWUVFHCkV3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmxjblF1WTI5dE1TRXcKSHdZRFZRUURFeGhFYVdkcFEyVnlkQ0JVY25WemRHVmtJRkp2YjNRZ1J6UXdIaGNOTVRNd09EQXhNVEl3TURBd1doY05Nemd3TVRFMQpNVEl3TURBd1dqQmlNUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzCmQzY3VaR2xuYVdObGNuUXVZMjl0TVNFd0h3WURWUVFERXhoRWFXZHBRMlZ5ZENCVWNuVnpkR1ZrSUZKdmIzUWdSelF3Z2dJaU1BMEcKQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUMvNXBCemFONjc1RjFLUERBaU1Ha3o3TUtuSlM3SklUM3lpdGhad3VFcApwejFZcTNhYXphNTdHNFFOeERBZjh4dWtPQmJyVnNhWGJSMnJzbm55eWhIUzVGL1dCVHhTRDFJZnhwNFZwWDYrbjZsWEZsbFZjcTlvCmszRENzcnAxbVdwek1wVFJFRVFRTHQrQzh3ZUU1blE3YlhIaUxRd2I3aURWeVNBZFl5a3R6dXhlVHNpVCtDRmhtelRyQmNaZTdGc2EKdk92Sno4MnNORUJmc1hwbTduZklTS2htVjFlZlZGaU9EQ3UzVDZjdzJWYnV5bnRkNDYzSlQxN2xOZWN4eTlxVFh0eU9qNERhdHBHWQpRSkI1dzNqSHRySEV0V29ZT0FNUWpkalVONlF1QlgySTlZSStFSkZ3cTFXQ1FUTFgyd1J6S202UkFYd2hUTlM4cmhzRGRWMTRadGs2Ck1VU2FNMEMvQ05kYVNhVEM1cW1nWjkya0o3eWhUem0xRVZnWDl5UmNSbzlrOThGcGlIYVlkajFaWFVKMmg0bVhhWHBJOE9DaUVodG0KbW5USzNrc2U1dzVqcnViVTc1S1NPcDQ5M0FEa1JTV0p0cHBFR1N0K3dKUzAwbUZ0NnpQWnhkOUxCQURNZlJ5Vnc0LzNJYkt5RWJlNwpmL0xWakhBc1FXQ3FzV01ZUkpVYWRtSis5b0N3Kytoa3BqUFJpUWZodmJmbVE2UVl1S1ozQWVFUGxBd2hIYkpVS1NXSmJPVU9VbEZICmRMNG1yTFpCZGQ1NnJGK05QOG04MDBFUkVsdmxFRkRyTWNYS2NoWWlDZDk4VEhVL1krd2hYOFFnVVd0dnNhdUdpMC9DMWtWZm5TRDgKb1I3RndJK2lzWDRLSnBuMTVHa3ZtQjB0OWRtcHNoM2xHd0lEQVFBQm8wSXdRREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZApEd0VCL3dRRUF3SUJoakFkQmdOVkhRNEVGZ1FVN05mamd0SnhYV1JNM3k1blArZTZtSzRjRDA4d0RRWUpLb1pJaHZjTkFRRU1CUUFECmdnSUJBTHRoMlgycGJMNFh4SkVidzZHaUFJM2paR2dQVnM5M3JuRDUvWnBLbWJuSmVGd01ERi9rNWhRcFZnczJTVjFFWStDdG5KWVkKWmhzakRUMTU2VzFyMWxUNDBqekJRMEN1SFZEMVV2eVFPN3VZbVdscng4R25xR2lrSjl5ZCtTZXVNSVc1OW1kTk9qNlBXVGtpVTBUcgp5RjBEeXUxUWVuMWlJUXFBeUhObTBhQUZZRi9vcGJTbnI2ajNiVFdjZkZxSzFxSTRtZk40aS9STjBpQUwzZ1R1akp0SGdYSU53QlF5Cjd6QlpMcTdnY2ZKVzVHcVhiNUpRYlphTmFIcWFzallVZWdieUpMa0pFVkRYQ0xHNGlYcUVJMkZDS2VXanphSWdRZGZSbkdUWjZpYWgKaXhUWFRCbXlVRUZ4UFQ5TmNDT0dERXJjZ2RMTU1wU0VEUWdKbHh4UHdPNXJJSFF3MHVBNU5CQ0ZJUlVCQ09oVk10NXhTZGtvRjFCTgo1cjVOMFhXczBNcjdRYmhEcGFyVHd3VkVUeXcybStMNjRrVzRJMU5zQm05blZYOUd0VXcvYmloYWVTYlNwS2hpbDlJZTR1MUtpN3diCi9VZEtEZDluWm42eVcwSFFPK1QwTy9RRVkrbnZ3bFFBVWFDS0tzbk9lTXpWNm9jRUdMUE9yMG1Jci9PU21iYXo1bUVQMG9VQTUxQWEKNUJ1Vm5SbWh1Wnl4bTdFQUh1L1FEMDlDYk1rS3ZPNUQranB4cGNoTkpxVTEvWWxkdklWaUhUTFNvQ3RVN1pwWHdkdjZFTThadDR0SwpHNDhCdGllVlUraTJpVzFidkdqVUkraUxVYUpXK2ZDbWdLRFdIck84RHc5VGRTbXE2aE4zNU42TWdTR3RCeEJIRWEySFBRZlJkYnpQCjgyWisKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ09NT0RPIFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGMkRDQ0E4Q2dBd0lCQWdJUVRLcjV5dHRqYitBZjkwN1lXd09HblRBTkJna3Foa2lHOXcwQkFRd0ZBRENCaFRFTE1Ba0dBMVVFCkJoTUNSMEl4R3pBWkJnTlZCQWdURWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEdBMVVFQnhNSFUyRnNabTl5WkRFYU1CZ0cKQTFVRUNoTVJRMDlOVDBSUElFTkJJRXhwYldsMFpXUXhLekFwQmdOVkJBTVRJa05QVFU5RVR5QlNVMEVnUTJWeWRHbG1hV05oZEdsdgpiaUJCZFhSb2IzSnBkSGt3SGhjTk1UQXdNVEU1TURBd01EQXdXaGNOTXpnd01URTRNak0xT1RVNVdqQ0JoVEVMTUFrR0ExVUVCaE1DClIwSXhHekFaQmdOVkJBZ1RFa2R5WldGMFpYSWdUV0Z1WTJobGMzUmxjakVRTUE0R0ExVUVCeE1IVTJGc1ptOXlaREVhTUJnR0ExVUUKQ2hNUlEwOU5UMFJQSUVOQklFeHBiV2wwWldReEt6QXBCZ05WQkFNVElrTlBUVTlFVHlCU1UwRWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQgpkWFJvYjNKcGRIa3dnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDUjZGU1MwZ3BXc2F3TkpOM0Z6MFJuCmRKa3JONk45STNBQWNieFQzOFQ2S2hLUFMzOFFWcjJmY0hLM1lYL0pTdzhYcHozanNBUmg3djhSbDhmMGhqNEsrajVjK1pQbU5IcloKRkd2bm5MT0ZvSUo2ZHE5eGtOZnMvUTM2bkd6NjM3Q0M5QlIrK2I3RXBpOVBmNWwvdGZ4blEzSzlEQURXaWV0ckxOUHRqNWdjRkt0Kwo1ZU51L05pbzVKSWsya05yWXJoVi9lckJ2R3kyaS9NT2pacmttMnhwbWZoNFNEQkYxYTNoRFR4RllQd3lsbEVudkdmRHlpNjJhK3BHCng4Y2dvTEVmWmQ1SUNMcWtUcW55ZzBZM2hPdm96SUZJUTJkT2NpcWJYTDFNR3lpS1hDSjd0S3VZMmU3Z1VZUERDVVpPYlQ2WitwVVgKMm53elYwRThqVkh0QzdaY3J5eGpHdDlYeUQrODZWM0VtNjlGbWVLaldpUzB1cWxXUGM5dnF2OUpXTDd3cVAvMHVLM3BOL3U2dVBRTApPdm5vUTBJZWlkaUV5eFB4MmJ2aGlXQzRqQ2hXckJRZG5Bcm5jZXZQRHQwOXFaYWhTTDA4OTYrMURTSk13QkdCN0ZZNzl0T2k0bHUzCnNnUWlVcFdBazJub2preGw4WkVETFhCMEF1cUxaeFVwYVZJQ3U5ZmZVR3BWUnIrZ295aGhmM0RRdzZLcUxDR3FSODRvbkFaRmRyK0MKR0NlMDFhNjB5MURtYS9STWhuRXc2YWJmRm9iZzJQOUEzZnZRUW9oL296TTZMbHdlUVJHQlk4NFljV3NyN0thS3R6RmNPbXBINE1ONQpXZFlnR3EveWFwaXFjcnhYU3RKTG5ic1EvTEJNUWVYdEhUMWVLSjJjekwrelVkcW5SK1dFVXdJREFRQUJvMEl3UURBZEJnTlZIUTRFCkZnUVV1NjkrQWozNnB2RThoSTZ0N2ppWTdOa3lNdFF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHcKRFFZSktvWklodmNOQVFFTUJRQURnZ0lCQUFyeDFVYUV0NjVSdTJ5eVRVRVVBSk5Nbk12bHdGVFBvQ1dPQXZuOXNLSU45U0NZUEJNdApyRmFpc05aK0VaTHBMcnFlTHBweXNiMFpSR3hoTmFLYXRCWVNhVnFNNGRjK3BCcm9Md1Awcm1FZEVCc3FwSXQ2eGY0RnB1SEExc2orCm5xNlBLN285bWZqWWN3bFlSbTZtblBUWEo5T1YyamVEY2h6VGMrQ2lSNWtET0YzVlNYa0FLUnpIN0pzZ0hBY2thVmQ0c2puOE9vU2cKdFp4OGpiOHVrMkludHpuYUZ4aXV2VHdKYVArRW16elYxZ3NENDFlZUZQZlI2MC9JdlljanQ3WkpRM21GWExycmtndWh4dWhvcUV3VwpzUnFaQ3VoVExKSzdvUWtZZFF4bHFIdkxJN2Nhd2lpRnd4di8wQ3RpNzZSN0NaR1laNHdVQWMxb0JtcGpJWFVEZ0lpS2JvSEdoZktwCnBDM245S1VrRUVlRHlzMzBqWGxZc1FhYjV4b3EyWjBCMTVSOTdRTkt5dkRiNktrQlB2VldtY2tlamtrOXUrVUp1ZUJQU1pJOUZvSkEKek14Wnh1WTY3Ukl1YVR4c2xiSDlxaDE3ZjRhK0hnNHlSdnY3RTQ5MWYweUxTMFpqL2dBMFFIREJ3N21oM2FadzRnU3pRYnpwZ0pIcQpaSng2NFNJRHFaeHVidzVsVDJ5SGgxN3picUQ1ZGFXYlFPaFRzaWVkU3JuQWR5R04vNGZ5M3J5TTd4ZmZ0MGtMMGZKdU1Bc2FEazUyCjdSSDg5ZWxXc24yL3gyMEtrNHlsME1DMkhiNDZUcFNpMTI1c0M4S0tmUG9nODhUazVjME5xTXVSa3JGOGhleTFGR2xtRG9MbnpjN0kKTGFaUmZ5SEJOVk9GQmtwZG42MjdHMTkwCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjNqQ0NBOGFnQXdJQkFnSVFBZjF0TVB5anlsR29HN3hrRGpVRExUQU5CZ2txaGtpRzl3MEJBUXdGQURDQmlERUxNQWtHQTFVRQpCaE1DVlZNeEV6QVJCZ05WQkFnVENrNWxkeUJLWlhKelpYa3hGREFTQmdOVkJBY1RDMHBsY25ObGVTQkRhWFI1TVI0d0hBWURWUVFLCkV4VlVhR1VnVlZORlVsUlNWVk5VSUU1bGRIZHZjbXN4TGpBc0JnTlZCQU1USlZWVFJWSlVjblZ6ZENCU1UwRWdRMlZ5ZEdsbWFXTmgKZEdsdmJpQkJkWFJvYjNKcGRIa3dIaGNOTVRBd01qQXhNREF3TURBd1doY05Nemd3TVRFNE1qTTFPVFU1V2pDQmlERUxNQWtHQTFVRQpCaE1DVlZNeEV6QVJCZ05WQkFnVENrNWxkeUJLWlhKelpYa3hGREFTQmdOVkJBY1RDMHBsY25ObGVTQkRhWFI1TVI0d0hBWURWUVFLCkV4VlVhR1VnVlZORlVsUlNWVk5VSUU1bGRIZHZjbXN4TGpBc0JnTlZCQU1USlZWVFJWSlVjblZ6ZENCU1UwRWdRMlZ5ZEdsbWFXTmgKZEdsdmJpQkJkWFJvYjNKcGRIa3dnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDQUVtVVhOZzdEMndpegowS3hYRFhidHpTZlRUSzFRZzJIaXFpQk5DUzFrQ2R6T2laL01QYW5zOXMvQjNQSFRzZFo3TnlnUkswZmFPY2E4T2htMFg2YTlmWjJqClkwSzJkdktwT3l1UitPSnYwT3dXSUpBSlB1TG9kTWtZdEpIVVltVGJmNk1HOFlnWWFwQWlQTHorRS9DSEZIdjI1QitPMU9SUnhoRm4KUmdoUnk0WVVWRCs4TS81K2JKei9GcDBZdlZHT05hYW5ac2h5WjlzaFpySFVtM2dEd0ZBNjZNenczTHllVFA2dkJaWTFIMWRhdC8vTworVDIzTExiMlZOM0k1eEk2VGE1TWlyZGNtclMzSUQzS2Z5STBybjQ3YUdZQlJPY0JUa1pUbXpOZzk1UytVemVRYzBQek1zTlQ3OXVxCi9uUk9hY2RyakdDVDNzVEhETi9oTXE3TWt6dFJlSlZuaSs0OVZ2NE0wR2tQR3cvekpTWnJNMjMzYmtmNmMwUGxmZzZsWnJFcGZES0UKWTFXSnhBM0JrMVF3R1JPczAzMDNwK3RkT213MVhOdEIxeExhcVVrTDM5aUFpZ21UWW82MVpzOGxpTTJFdUxFL3BEa1AyUUtlNnhKTQpsWHp6YXdXcFhoYUR6TGhuNHVnVG5jeGJndE5NcysxYi85N2xjNndqT3kwQXZ6VlZkQWxKMkVsWUduK1NOdVpSa2c3ekpuMGNUUmU4CnlleERKdEMvUVY5QXFVUkU5Sm5uVjRlZVVCOVhWS2crL1hSakw3RlFaUW5tV0VJdVF4cE10UEFsUjFuNkJCNlQxQ1pHU2xDQnN0NisKZUxmOFp4WGh5VmVFSGc5ajF1bGl1dFpmVlM3cVhNWW9DQVFsT2JnT0s2bnlUSmNjQno4TlV2WHQ3eStDRHdJREFRQUJvMEl3UURBZApCZ05WSFE0RUZnUVVVM20vV3FvclNzOVVnT0hZbThDZDhySURac3N3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGCk1BTUJBZjh3RFFZSktvWklodmNOQVFFTUJRQURnZ0lCQUZ6VWZBM1A5d0Y5UVpsbERIUEZVcC9MK00rWkJuOGIya01WbjU0Q1ZWZVcKRlBGU1BDZUhsQ2p0SHpvQk42SjIvRk5Rd0lTYnhtdE91b3doVDZLT1ZXS1I4MmtWMkx5STQ4U3FDLzN2cU9sTFZTb0dJRzFWZUNrWgo3bDh3WEVza0VWWC9KSnB1WGlvcjdndE5uMy8zQVRpVUZKVkRCd243WUtudUhLc1NqS0NhWHFlWWFsbHRpejhJKzhqUlJhOFlGV1NRCkVnOXpLQzdGNGlSTy9GanM4UFJGL2lLejZ5K08wdGxGWVFYQmwyK29kbktQaTR3MnI3OE5CYzV4amVhbWJ4OXNwbkZpeGRqUWczSU0KOFdjUmlReWNFMHh5Tk4rODFYSGZxbkhkNGJsc2pEd1NYV1hhdlZjU3RrTnIvK1hlVFdZUlVjK1pydXdYdHVoeGtZemVTZjdkTlhHaQpGU2VVSE05aDR5YTdiNk5uSlNGZDV0MGRDeTVvR3p1Q3IreURaNFhVbUZGMHNibVpnSW4vZjNnWlhIbEtZQzZTUUs1TU55b3N5Y2RpCnlBNWQ5elpieXVBbEpRRzAzUm9IbkhjQVA5RGMxZXc5MVBxN1A4eUYxbTkvcVMzZnVRTDM5WmVhdFRYYXcyZXdoMHFwS0o0amp2OWMKSjJ2aHNFL3pCKzRBTHRSWmg4dFNRWlhxOUVmWDdtUkJWWHlOV1FLVjNXS2R3cm51V2loMGhLV2J0NURIREFmZjlZazJkRExXS01HdwpzQXZnbkV6REhOYjg0Mm0xUjBhQkw2S0NxOU5qUkhERWpmOHRNN3F0ajN1MWNJaXVQaG5QUUNqWS9NaVF1MTJaSXZWUzVsakZINGd4ClErNklIZGZHamp4RGFoMm5HTjU5UFJieFl2bktrS2o5Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ2p6Q0NBaFdnQXdJQkFnSVFYSXVaeFZxVXhkSnhWdDdOaVlETUpqQUtCZ2dxaGtqT1BRUURBekNCaURFTE1Ba0dBMVVFQmhNQwpWVk14RXpBUkJnTlZCQWdUQ2s1bGR5QktaWEp6WlhreEZEQVNCZ05WQkFjVEMwcGxjbk5sZVNCRGFYUjVNUjR3SEFZRFZRUUtFeFZVCmFHVWdWVk5GVWxSU1ZWTlVJRTVsZEhkdmNtc3hMakFzQmdOVkJBTVRKVlZUUlZKVWNuVnpkQ0JGUTBNZ1EyVnlkR2xtYVdOaGRHbHYKYmlCQmRYUm9iM0pwZEhrd0hoY05NVEF3TWpBeE1EQXdNREF3V2hjTk16Z3dNVEU0TWpNMU9UVTVXakNCaURFTE1Ba0dBMVVFQmhNQwpWVk14RXpBUkJnTlZCQWdUQ2s1bGR5QktaWEp6WlhreEZEQVNCZ05WQkFjVEMwcGxjbk5sZVNCRGFYUjVNUjR3SEFZRFZRUUtFeFZVCmFHVWdWVk5GVWxSU1ZWTlVJRTVsZEhkdmNtc3hMakFzQmdOVkJBTVRKVlZUUlZKVWNuVnpkQ0JGUTBNZ1EyVnlkR2xtYVdOaGRHbHYKYmlCQmRYUm9iM0pwZEhrd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFhckZSYXFmbG9JK2Q2MVNSdlU4WmEyRXVyeHRXMgowZVp6Y2E3ZG5OWU1ZZjNib0lrRHVBVVU3RmZPN2wwLzRpR3p6dmZVaW5uZ280TitMWmZRWWNUeG1kd2xrV09yZnpDanRIRGl4NkV6Cm5QTy9MbHhUc1YremZUSi9palRqZVhtalFqQkFNQjBHQTFVZERnUVdCQlE2NFFtRzFNOFp3cFoyZEVsMjNPQTF4bU5qbWpBT0JnTlYKSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpBMlo2RVdDTnprbHdCQgpIVTYrNFdNQnp6dXFRaEZrb0oyVU9RSVJlVng3SGZwa3VlNFdRck8vaXNJSnhPemtzVTBDTVFEcEttRkhqRkpLUzA0WWNQYldSTlp1CjlZTzZiVmk5Sk5sV1NPcnZ4S0pHZ1locU9rYlJxWnROeVdIYTBWMVhhaGc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNAo9PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUI0VENDQVllZ0F3SUJBZ0lSS2ppa0hKWUtCTjVDc2lpbEMrZzBtQUl3Q2dZSUtvWkl6ajBFQXdJd1VERWtNQ0lHQTFVRUN4TWIKUjJ4dlltRnNVMmxuYmlCRlEwTWdVbTl2ZENCRFFTQXRJRkkwTVJNd0VRWURWUVFLRXdwSGJHOWlZV3hUYVdkdU1STXdFUVlEVlFRRApFd3BIYkc5aVlXeFRhV2R1TUI0WERURXlNVEV4TXpBd01EQXdNRm9YRFRNNE1ERXhPVEF6TVRRd04xb3dVREVrTUNJR0ExVUVDeE1iClIyeHZZbUZzVTJsbmJpQkZRME1nVW05dmRDQkRRU0F0SUZJME1STXdFUVlEVlFRS0V3cEhiRzlpWVd4VGFXZHVNUk13RVFZRFZRUUQKRXdwSGJHOWlZV3hUYVdkdU1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRXVNWjUwNDlzSlE2Zkxqa1pIQU9rcnBybApPUWNKRnNwanNibUcrSXBYd1ZmT1F2cHpvZmRsUXY4ZXdRQ3libk1PLzhjaDVSaWtxdGx4UDZqVXVjNk1IYU5DTUVBd0RnWURWUjBQCkFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZGU3dlNjFGdU9KQWYvc0tidnUrTThrOG80VFYKTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFEY2txR2dFNmJQQTdEbXhDR1hrUG9VVnkwRDdPNDgwMjdLcUd4MnZLTGV1d0lnSjZpRgpKeldiVnNhajhrZlN0MjRiQWdBWHFtZW1GWkhlK3BUc2V3djRuNFE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNQo9PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNIakNDQWFTZ0F3SUJBZ0lSWUZsSjRDWXV1MVg1Q25lS2NmbEsyR3d3Q2dZSUtvWkl6ajBFQXdNd1VERWtNQ0lHQTFVRUN4TWIKUjJ4dlltRnNVMmxuYmlCRlEwTWdVbTl2ZENCRFFTQXRJRkkxTVJNd0VRWURWUVFLRXdwSGJHOWlZV3hUYVdkdU1STXdFUVlEVlFRRApFd3BIYkc5aVlXeFRhV2R1TUI0WERURXlNVEV4TXpBd01EQXdNRm9YRFRNNE1ERXhPVEF6TVRRd04xb3dVREVrTUNJR0ExVUVDeE1iClIyeHZZbUZzVTJsbmJpQkZRME1nVW05dmRDQkRRU0F0SUZJMU1STXdFUVlEVlFRS0V3cEhiRzlpWVd4VGFXZHVNUk13RVFZRFZRUUQKRXdwSGJHOWlZV3hUYVdkdU1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFUjBVT2x2dDlYYi9wT2RFaCtKOEx0dFY3SHBJNgpTRmtjOEdJeExjQjZLUDRhcDF5enRzeVg1MFhVV1ByUmQyMURvc0NIWlRRS0gzcmQ2end6b2NXZFRhUnZRWlU0ZjhrZWhPdlJua21TCmg1U0hERHFGU21hZm5WbVRUWmRoQm9aS28wSXdRREFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWQKQmdOVkhRNEVGZ1FVUGVZcFNKdnFCOG9oUkVvbTNtN2Uwb1BRbjFrd0NnWUlLb1pJemowRUF3TURhQUF3WlFJeEFPVnBFc2x1MjhZeAp1Z2xCNFpmNCsvMmE0bjBTeWUxOFpOUExCU1dMVnRtZzUxNWRUZ3VEbkZ0MkthQUpKaUZxWWdJd2NkSzFqMXpxTytGNENZV29kWkk3CnlGejlTTzhOZENLb0NPSnV4VW5PeHd5OHAyRnA4ZmM3NFNyTCtTdnpacEEzCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzMKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmREQ0NBMXlnQXdJQkFnSUVBSmlpT1RBTkJna3Foa2lHOXcwQkFRc0ZBREJhTVFzd0NRWURWUVFHRXdKT1RERWVNQndHQTFVRQpDZ3dWVTNSaFlYUWdaR1Z5SUU1bFpHVnliR0Z1WkdWdU1Tc3dLUVlEVlFRRERDSlRkR0ZoZENCa1pYSWdUbVZrWlhKc1lXNWtaVzRnClVtOXZkQ0JEUVNBdElFY3pNQjRYRFRFek1URXhOREV4TWpnME1sb1hEVEk0TVRFeE16SXpNREF3TUZvd1dqRUxNQWtHQTFVRUJoTUMKVGt3eEhqQWNCZ05WQkFvTUZWTjBZV0YwSUdSbGNpQk9aV1JsY214aGJtUmxiakVyTUNrR0ExVUVBd3dpVTNSaFlYUWdaR1Z5SUU1bApaR1Z5YkdGdVpHVnVJRkp2YjNRZ1EwRWdMU0JITXpDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBTDR5Cm9sUVBjUHNzWEZucmJNU2tVZWlGS3JQTVNqVHlzRi96RHNjY1BWTWVpQWhvMkc4OXJjS2V6SUpuQnllSGFIRTZuM1dXSWtZRnNPMnQKeDF1ZUt0NmMvRHJHbGFmMUYyY1k1eTlKQ0F4Y3orYk1OTzE0KzFDeDNHc3k4S0wrdGp6azdGcVh4ejhlY0Fnd29OekZzMjF2MElKeQpFYXZTZ1doWmdoZTNlSkpnK3N6ZVA0VHJqVGd6a0FweUkvbzF6Q1p4TWRGeUtKTFpXeU50WnJWdEIwTHJwalBPa3R2QTlteGplTTNLClRqMjE1VktiOGI0NzVsUmdzR1llQ2FzSC9sU0pFVUxSOXlTNllIZ2FtUGZKRWYwV3dUVWFWSFh2UTlQbHJrN081M3ZEeGs1aFVVdXIKbWtWTG9SOUJ2VWhURlhGa0M0YXo1UzYrenFRYndTbUVvclhMQ0NOMlF5SWtIeGNFMUc2Y3h2eC9LMllhN0lybDFzOU45V01KdHhVNQoxbnVzNitOODZVNzhkVUxJN1ZpVkRBWkNvcHozNUhDejMzSnZXamRBaWRpRnBOZnhDOTVER2RSS1dDeU1pam1ldjRTSDhSWTdOZ3pwCjA3VEtiQmxCVWdtaEhiQnF2NEx2Y0ZFaE10d0Zkb3pMOTJUa0ExQ3ZqSkZucThYeTdsalkzcjczNXpIUGJNazdjY0hWaUxWbHZNRG8KRnhjSEVyVmMwcXNnazdUbWdvTndOc1hObzQydGkreWp3VU9INWtQaU5MNlZpelh0QnpuYXFCMTZuemFlRXJBTVpSS1FGV0RaSmtCRQo0MVpncFJEVWFqejlRZHdPV2tlMjc1ZGhkVS9aL3NleUhkVHRYVW16cVdyTFpvUVQxVnlnM045dWR3YlJjWFhJVjIrdkQzZGJBZ01CCkFBR2pRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlJVcmZySGtsZXUKeWpXY0xoTDc1THBkSU55VVZ6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFNSm1kQlRMSVhnNDdtQUU2aXFUbkIvZDYrT2VhMzFCRApVNWNxUGNvOFI1Z3U0UlY3OFpMellkcVFKUlpsd0o5VVhRNERPMXQzQXB5RXRnMllYelRkTzJQQ3d5aUJ3cHdwTGluaXlNTUI4alBxCktxck1DUWozWldmR3pkL1R0aXVudmN6UkRuQmZ1Q1BSeTVGT0N2VElldVhaWXpiQjFOLzhJcGYzWUYzcUtTOVlzcjFZdlkyV1R4QjEKdjBoN1BWR0hvVHgwSXNMOEIzK0EzTVNzL21yQmNEQ3c2WTVwNGl4cGdaUUp1dDMrVGNDRGpKUll3RVlncjV3ZkF2ZzFWVWt2UnRUQQo4S0NXQWc4enhYSHpuaU45bExmOU90TUpnd1loL1dBOXJqTEEwdTZOcHZEbnRJSjhDc3h3eVhtQStQNU05eldFR1lveCt3cloxMytiCjhLS2FhOE1GU3UxQllCUXcwYW9SUW03VEl3SUVDOFpsM2QxU2Q5cUJhN0tvK2dFNHVaYnFLbXhubDRtVW5yemhWTlhrYW5qdlNyMHIKbWoxQWZzYkFkZEp1KzJndzdPeUxuZmxKTlpvYUxObXpsVG5WSHBMM3BybGxMK1U5YlRwSVRBamM1Q2dTS0w1OU5WenE0QlorRXh0cQoxejdYbnZ3dGRiTEJGTlVqQTl0YmJ3cytlQzhOM2pPTkZyZEk1NE9hZ1E5N3dVTk5WUVFYT0VwUjFWbWlpWFRUbjc0ZVM5ZkdiYmVJCkpHOWdrYVNDaFZ0V1FielFSS3RxRTc3UkxGaTNFak5Zc2pkajNCUDFsQjAvUUZIMVQvVTY3Y2pGNjhJZUhSYVZlc2QrUW5HVGJrc1YKdHpEZnF1MVhoVWlzSFdyZE9Xbms0WGw0dnM0RnY2RU05NEI3SVdjbk1Gaz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU3RhYXQgZGVyIE5lZGVybGFuZGVuIEVWIFJvb3QgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjRENDQTFpZ0F3SUJBZ0lFQUppV2pUQU5CZ2txaGtpRzl3MEJBUXNGQURCWU1Rc3dDUVlEVlFRR0V3Sk9UREVlTUJ3R0ExVUUKQ2d3VlUzUmhZWFFnWkdWeUlFNWxaR1Z5YkdGdVpHVnVNU2t3SndZRFZRUUREQ0JUZEdGaGRDQmtaWElnVG1Wa1pYSnNZVzVrWlc0ZwpSVllnVW05dmRDQkRRVEFlRncweE1ERXlNRGd4TVRFNU1qbGFGdzB5TWpFeU1EZ3hNVEV3TWpoYU1GZ3hDekFKQmdOVkJBWVRBazVNCk1SNHdIQVlEVlFRS0RCVlRkR0ZoZENCa1pYSWdUbVZrWlhKc1lXNWtaVzR4S1RBbkJnTlZCQU1NSUZOMFlXRjBJR1JsY2lCT1pXUmwKY214aGJtUmxiaUJGVmlCU2IyOTBJRU5CTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE0OGQraWZrawpTenJTTTRNMUxHbnMzQW1rNDFHb0pTdDV1QWc5NEpHNmhJWEdoYVRLNXNrdVU2VEpKQjc5VldaeFhTekZZR2dFdDluQ1VpWTRpS1RXCk8wQ213czAvelppVHMxUVVXSlpWMVZEK2hxMmtZMzljaC9hTzVpZVNaeGVTQWdNczNOWm1kTzNkWi8vQllZMWpUdytiYlJjd0p1K3IKMGg4UW9QbkZmeFpwZ1FOSDdSNW9qWEtoVGJJbXhycHNYMjNXcjlHeEU0NnByZk5lYVhVbUdENUJLeUYvN290ZEJ3YWRROFFwQ2l2OApLajZHeXp5RE92bkpEZHJGbWVLOGVFRXpkdUcvTDEzbHBKaFFEQlhkNFBxY2Z6aG8wTEttZXFmUk1iMStpbGduUTdPNk01SFRwNWdWClhKcm0wdzkxMmZ4Qm1KYytxaVhiajVJdXNIc01YL0ZqcVRmNW0zVnBUQ2dtSmRyVjhoSndSVlhqMzNOZU4vVWhiSkNPTlZySjB5UHIKMDhDK2VLeENLRmhtcFVadGNBTFhFUGxMVlB4ZGhrcUh6My9LUmF3UldyVWdVWTB2aUVlWE9jRFB1c0JDQVVDWlNDRUxhNmZTL1piVgowYjVHblVuZ0M2YWdJazQ0ME1FOE1MeHdqeXgxek5ERmpGRTdQWlFJWkNaaGZibkRaWThVbkNIUXF2MFhjZ09Qdlp1TTVsNVRucm1kCjc0Szc0YnppY2tGYklaVFRSVGVVMGQ4Sk9WM25JNnFhSGNwdHFBcUdoWXFDdmtJSDF2STRnblBhaDF2bFBOT2VQcWM3bnZRRHMvbngKZlJOMEF2KzdvZVg2QUhrY3BtWkJpRnhnVjZZdUNjUzYvWnJQcHg5QXc3dk1XZ3BWU3pzNGRsRzRZNHVFbEJibVZ2TUNBd0VBQWFOQwpNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGUDZyQUpDWW5pVDhxY3dhCml2c251TDh3YnFnN01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRRFBkeXh1VnI1T3M3YUVBSlNyUjhrTjBuYkhocDhkQjlPMnRMc0kKZUs5cDBndEozalBGckszQ2lBSjlCcmMxQXNGZ3liL0U2SlRlMU5PcEV5VmEvbTZpcm4wRjNIM3piUEIrcG8zdTJkZk9XQmZvcVNtdQpjMGlINTV2S2JpbWhaRjhaRS9ldUJoRC9VY2FiVFZVbFQ1T1pFQUZUZGZFVHpzZW1RVUhTdjRpbGYwWDhyTGlsdFRNTWdzVDdCL1pxCjVTV0VYd2JLd1lZNUVkdFl6WGM3TE1KTUQxNmE0L0NyUG1FYlVDVEN3UFR4R2ZBUktiYWxHQUtiMTJOTWNJeEhvd05EWExsZFJxQU4KYi85WmpyN2RuM0xEV3l2ZmpGdk81UXhHYkpLeUNxTk1WRUlZRlJJWXZkcjh1blJ1LzhHMm9HVFlxVjlWcnA5Y2FuYVcySE5uaC90TgpmMXp1YWNwekVQdUtxZjJldlRZNFNVbUg5QTRVOE9tSHVEK25UM3Bham5uVWsrUzdhRktFckd6cDg1aHdWWEl5K1RTckswbTF6U0JpCjVEcDZaMk9ybHR4dHJwZnMvSjkyVm9ndVpzOWJ0c21rc05jRnV1RW5MNU83SmlxaWs3QWI4NDYrSFVDanVUYVBQb0lhR2w2STZsRDQKV2VLRFJpa0w0MFJjNFpXMmFaQ2FGRytYcm9IUGFPK1ptcjYxNStGLytQb1RSeFpNekcwSVFPZUxlRzlRZ2tSUVAyWUdpcXREaEZaSwpEeUF0aGc3MTB0dlNlb3BMemFYb1R2RmVKaVVCV1NPZ2Z0TDJmaUZYMXllOEZWZE1wRWJCNElNZURFeE5IMDhHR2VMNXFQUTZncUd5CmVVTjUxcTF2ZWllUUE2VHFKSWMvMmIzWjZmSmZVRWtjN3V6WExnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSWRlblRydXN0IENvbW1lcmNpYWwgUm9vdCBDQSAxCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRllEQ0NBMGlnQXdJQkFnSVFDZ0ZDZ0FBQUFVVWp5RVMxQUFBQUFqQU5CZ2txaGtpRzl3MEJBUXNGQURCS01Rc3dDUVlEVlFRRwpFd0pWVXpFU01CQUdBMVVFQ2hNSlNXUmxibFJ5ZFhOME1TY3dKUVlEVlFRREV4NUpaR1Z1VkhKMWMzUWdRMjl0YldWeVkybGhiQ0JTCmIyOTBJRU5CSURFd0hoY05NVFF3TVRFMk1UZ3hNakl6V2hjTk16UXdNVEUyTVRneE1qSXpXakJLTVFzd0NRWURWUVFHRXdKVlV6RVMKTUJBR0ExVUVDaE1KU1dSbGJsUnlkWE4wTVNjd0pRWURWUVFERXg1SlpHVnVWSEoxYzNRZ1EyOXRiV1Z5WTJsaGJDQlNiMjkwSUVOQgpJREV3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ25VQm5lUDVrOTFETkc4VzlSWVlLeXFVK1BaNGxkCmhObFQzUXdvMmRmdy82NlZRM0taK2JWZGZJckJRdUV4VUhUUmdRMTh6WnNocTBQaXJLMWVobTd6Q1lvZldqSzlvdXVVK2VoY0N1ei8KbU5LdmNiTzBVNTlPaCsrU3ZMM3NUekl3aUVzWFhsZkVVOEwyQXBlTjJXSXJ2eVFmWW8zZnc3Z3BTMGw0UEpOZ2lDTDhtZG8yeU1LaQoxQ3hVQUdjMWJuTy9BbGp3cE4zbHNLSW1lc3JnTnFVWkZ2WDl0Kyt1UDBEMWJWb0UvYzQweWlUY2RDTWJYVE1URWwzRUFTWDJNTjBDClhaL2cxVWU5dE9zYm9idEpTZGlmV3dMeml1UWtrT1JpVDAvQnI0c09kQmVvMFhLSWFub0JTY3kwUm5uR0Y3SGFtQjRIV2ZwMUlZVmwKM1pCV3p2dXJwV0NkeEozNVVyQ0x2WWY1anlzakNpTjJPL2N6NGNrQTgybjVTNkxnVHJ4K2t6bUVCL2RFY0g3K0IxcmxzYXpSR016eQpOZVZKU1FqS1ZzazkrdzhZZllzN3dSUENUWS9KVHc0MzZSK2hEbXJmWWk3TE5RWlJlU3pJSlRqMCtrdW5pVnljMHVNTk9ZWktkSHpWCldZZkNQMDRNWEZMMFBmZFNndkhxbzZ6OVNUUWFLUE5CaURvVDd1amUvNWtkWDdyTDZCN3l1VkJnd0RIVGMrWHZ2cUR0TXd0MHZpQWcKeEdkczhBZ0RlbFdBZjBaT2xxZjBIajdoOXRnSjRUTmtLMlBYTWw2ZitjQjdEM2h2bDd5VG12bWNFcEI0ZW9DSEZkZHlkSnhWZEhpeAp1dUZ1Y0FTNlQ2QzZhTU43L3pId2N6MDlsQ3F4QzBFT29QNU5pR1ZyZVRPMDF3SURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DCkFRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVU3VVFad05Qd0JvdnVwSHUrUXVjbVZNaU9Obll3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dJQkFBMnVrREwycGt0OFJIWVpZUjRuS00xZVZPOGx2T01Ja1BrcDE2NW9DT0dVQUZqdkxpNStVMUtNdGx3SAo2b2k2bVl0UWxOZUNnTjloQ1FDVHJRMFU1czdCOGplVWVMQmZuTE9pYzdpUEJaTTR6WTArc0xqN3dNK3g4dXd0TFJ2TTdLcWFzNnBnCmdoc3RPOE9FUFZlS2xoNmNkYmpUTU0xZ0NJT1EwNDVVOFUxbXdGMTBBMENqN29WK3doOTNuQWJvd2FjWVhWS1Y3Y25kSlo1dCtxbnQKb3pvMDBGbDcydTFROHpXLzdlc1VUVEhIWVBUYThZZWM0a2ppeHNVMyt3WVErblZaWmpGSEtkcDJtaHpwZ3E3dm1ybFI5NGdqbW1tVgpZanpsVllBMjExUUMvL0c1WGM3VUkyL1lSWVJLVzJYdmlRemRGS2NneXhpbEpiUU4rUUh3b3RMMEFNaDBqcUVxU0k1bDJ4UEU0aVVYCmZldStoMXNYSUZSUmswcFRBd3ZzWGNvejdXTDlSY2N2Vzl4WW9JQTU1dnJYL2hNVXB1MDlsRXBDZE5URGQxbHp6WTlHdmxVNDcvcm8Ka1RMcWwxZ0VJdDQ0dzh5OGJja3pPbW9LYVQrZ3lPcHlqNHhqaGlPOWJUeVducFhnU1V5cW9ya3FHNXcyZ1hqdHcraEc0aVpaUkhVZQoyWFdKVWMwUWhKMWhZTXRkK1pjaVRZNlk1dU4vOWx1N3JzM0tTb0ZyWGd2elVlRjBLK2wrSjZmWm1VbE8rS1dBMnlVUEhHTmlpc2t6CloyczhFSVBHcmQ2b3pSYU9qZkFITjNHZjhxdjhRZlhCaSt3QU4xMEo1VTZBNy9xeFhEZ0dwUnRLNGR3NExUemNxeCtRR3RWS25PN1IKY0d6TTd2UlgrQmk2aEc2SAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGWmpDQ0EwNmdBd0lCQWdJUUNnRkNnQUFBQVVVanowWjhBQUFBQWpBTkJna3Foa2lHOXcwQkFRc0ZBREJOTVFzd0NRWURWUVFHCkV3SlZVekVTTUJBR0ExVUVDaE1KU1dSbGJsUnlkWE4wTVNvd0tBWURWUVFERXlGSlpHVnVWSEoxYzNRZ1VIVmliR2xqSUZObFkzUnYKY2lCU2IyOTBJRU5CSURFd0hoY05NVFF3TVRFMk1UYzFNek15V2hjTk16UXdNVEUyTVRjMU16TXlXakJOTVFzd0NRWURWUVFHRXdKVgpVekVTTUJBR0ExVUVDaE1KU1dSbGJsUnlkWE4wTVNvd0tBWURWUVFERXlGSlpHVnVWSEoxYzNRZ1VIVmliR2xqSUZObFkzUnZjaUJTCmIyOTBJRU5CSURFd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUMySXBUOHBFaXY2RWRyQ3ZzbmR1VHkKUDRvN2Vrb3NNU3FNamJDcHd6RnJxSGQyaENhMnJJRkNEUWpyVlZpN2V2aThaWDN5b0cyTHFFZnBZblllRWU0SUZOR3lSQmIwNnRENgpIaTllMjh0elFhNjhBTEJLSzBDeXJPRTdTOEl0bmVTaG0rd2FPaDd3Q0xQUTVDUTFCNStjdE1sU2Jkc0h5bysxVy9DRDgwL0hMYVhJCnJjdVZJS1F4S0ZkWVd1U05HNXFybmcwTThnb3pPU0k1Q3BjdTgxTjN1VVJGL1lUTE5pQ0JXUzJhYjIxSVNHSEtUTjlUMGE5U3ZFU2YKcXk5cmczTHZkWURhQmpNYlhjamFZOFpOemF4bU1jM1IzajZIRURiaHVhUjY3MkJRc3N2S3BsYmdONityTkJNNUplZzVadVNZZXFvUwptSnhaWm9ZK3JmR3d5ajRHRDN2d0VVczNvRVJ0ZTh1b2pISDAxYldSTnN6d0ZjWXIzbEVYc1pkTVVEMnhsVmw4QlgwdElkVUF2d0ZuCm9sNTdwbHp5OXlMeGtBMlQyNnBFVVdiTWZYWUQ2MnFvS2pnWmwzWU5hNHBoK2J6MjduYjljQ3ZkS1R6NENoNWJRaHlMVmk5Vkd4eWgKTHJYSEZ1YjRxanlTam1tMkFjRzFocDJKRHdzNGxGVG82dHllUFNXOFV5YnQxYXM1cXNWQVRGU3JzclRaMmZqWGN0c2N2RzI5WlYvdgppRFVxWmkvdTlyTmw4RE9OZkpoQmFVWVBReHhwK3B1MTBHRnF6Y3BMMlV5UVJxc1ZXYUZIVkNrdWd5aGZITUtpcTNJWEFBYU9SZXlMCjRqTTlmOW9aUk9SaWNzUGZJc2J5VnRUZFg1Vnk3VzFmOTBnRFcvM0ZLcUQyY3lPRUVCc0I1d0lEQVFBQm8wSXdRREFPQmdOVkhROEIKQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVNDNIZ250aW5RdG5iY1pGcmxKUHJ3NlBSRktNdwpEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBRWY2M1Fxd0VaRTRyVTFkOStVT2wxUVpna2lIVkl5cVpKbllXdjZJQWNWWXBabXhJMVFqCnQyb2RJRmZsQVdKQkY5TUoyM1hMYmxTUWRmNGFuNEVLd3QzWDl3blFXM0lWNUI0SmFqMHo4eUdhNWhWK3JWSFZEUkR0ZlVMQWorN0EKbWdqVlFkWmNEaUZwYm9CaERoWEF1TS9GU1JKU3pMNDZ6TlF1T0FYZU5mMGZiN2lBYUpnOVRhREtRR1hTYzN6MWk5a0tsVC9ZUHlOdApHdEVxSkJuWmhiTVg3M2h1cVZqUkk5UEhFKzF5Slg5ZHNYTncwSDhHbHdtRUtZQmhIZnBlLzNPc29PT0p1Qnh4RmNiZU1YOFMzT0Z0Cm02L242SjkxZUV5clJqdWF6cjhGR0YxTkZUd1dtaGxRQkpxeW1tOWxpMUpmUEZnRUtDWEFabUV4ZnJuZ2Ria2FxSUhXY2hlenhRTXgKTlJGNGVLTGc2VENNZjREZldOODh1aWVXNG9BMGJlT1kwMlFuckVoK0tIZGN4aVZoSmZpRkRHWDZ4REl2cFpnRjVQZ0xaeFlXeG9LNApNaG41K2JsNTNCL042NityRHQwYjIwWGtldWNDNHBWZC9HbndVMmxobFhWNUMxNVY1amdjbEtsWk01N0ljWFI1ZjFHSnRzaHF1RERJCmFqakRicDdoTnhicUJXSk1XeEpIN2FlMHMxaFd4MG56ZnhKb0NURng4RzM0VGtmNzFvWHV4VmhBR2FRZHAvbExRemZjYUZwUHordkMKWkhUZXRCWFo5RlJVR2k4YzE1ZHhWSkNPMlNDZFV5dC9xNC9pNmpDOFVEZnY4VWUxZlh3c0JPeG9uYlJKUkJEMGNrc2NaT2Y4NW11UQozV2w5YWYwQVZxVzNyTGF0dDhvK0FlK2MKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVQakNDQXlhZ0F3SUJBZ0lFU2xPTUtEQU5CZ2txaGtpRzl3MEJBUXNGQURDQnZqRUxNQWtHQTFVRUJoTUNWVk14RmpBVUJnTlYKQkFvVERVVnVkSEoxYzNRc0lFbHVZeTR4S0RBbUJnTlZCQXNUSDFObFpTQjNkM2N1Wlc1MGNuVnpkQzV1WlhRdmJHVm5ZV3d0ZEdWeQpiWE14T1RBM0JnTlZCQXNUTUNoaktTQXlNREE1SUVWdWRISjFjM1FzSUVsdVl5NGdMU0JtYjNJZ1lYVjBhRzl5YVhwbFpDQjFjMlVnCmIyNXNlVEV5TURBR0ExVUVBeE1wUlc1MGNuVnpkQ0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1SUMwZ1J6SXcKSGhjTk1Ea3dOekEzTVRjeU5UVTBXaGNOTXpBeE1qQTNNVGMxTlRVMFdqQ0J2akVMTUFrR0ExVUVCaE1DVlZNeEZqQVVCZ05WQkFvVApEVVZ1ZEhKMWMzUXNJRWx1WXk0eEtEQW1CZ05WQkFzVEgxTmxaU0IzZDNjdVpXNTBjblZ6ZEM1dVpYUXZiR1ZuWVd3dGRHVnliWE14Ck9UQTNCZ05WQkFzVE1DaGpLU0F5TURBNUlFVnVkSEoxYzNRc0lFbHVZeTRnTFNCbWIzSWdZWFYwYUc5eWFYcGxaQ0IxYzJVZ2IyNXMKZVRFeU1EQUdBMVVFQXhNcFJXNTBjblZ6ZENCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlDMGdSekl3Z2dFaQpNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUM2aExaeTI1NE1hK0taNlRBQnAzYnFNcmlWUVJySjJtRk9XSExQCi92YUNlYjl6WVFZS3BTZllzMS9UUlU0Y2N0Wk9Ndkp5aWcvM2d4blFhb0NBQUVVZXNNZm5tcjhTVnljY28yZ3ZDb2U5YW1zT1htWHoKSEhmVjFJV05jQ0cwc3pMbmk2TFZoamtDc2JqU1I4N2t5VW5FTzZmZSsxUjlWNzd3Nkc3Q2ViSTZDMVhpVUpnV01oTmNMM2hXd2NLVQpzL0phNUNlYW55VFh4dXpRbXlXQzQ4ekN4RVhGakpkNkJtc3FFWitwQ201SU8yL2IxQkVaUXZlUEI3LzFVMStjUHZRWExPWnByRTR5ClRHSjM2cmZvNWJzMHZCbUxycHhSNTdkK3RWT3hNeUxsYmM5d1BCcjY0cHRudG9QMGphV3ZZa3hONEZpc1pEUVNBL2kyalpSakpLUngKQWdNQkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJxY2laNgowQjd2ZmVjN2FWSFViSTJma0JKbXF6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFlWjhkbHNhMmVUOGlqWWZUaHdNRVlHcHJtaTVaCmlYTVJyRVBSOVJQL2pUa3J3UEs5VDNDTXFTL3FGOFFMVko3VUc1YVlNenlvcldLaUFIYXJXV2x1QmgxK3hMbEVqWml2RXRSaDJ3b1oKUmtmejYvZGp3VUFGUUtYU3QvUzFtamEvcVloMmlBUlZCQ3VjaDM4YU56eCtMYVVhMk5TSlhzcTlyRDFzMkcydjFmTjJEODA3aURnaQpuV3lUbXNROXY0SWJaVCttRDEycS9PV3lGY3ExcmNhOFBkQ0U2T29HY3JCTk9USjR2ejRSbkF1a25ab2g4L0NiQ3pCNDI4SGNoMFArCnZHT2F5c1hDSE1uSGpmODdFbGdJNXJZOTdIb3NUdnVEbHM0TVBHbUhWSE9rYzhLVC8xRVFyQlZVQWRqOEJiR0pvWDkwZzVwSjE5eE8KZTRwSWI0dEY5Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrVENDQW9DZ0F3SUJBZ0lOQUthTGVTa0FBQUFBVU5DUitUQUtCZ2dxaGtqT1BRUURBekNCdnpFTE1Ba0dBMVVFQmhNQ1ZWTXgKRmpBVUJnTlZCQW9URFVWdWRISjFjM1FzSUVsdVl5NHhLREFtQmdOVkJBc1RIMU5sWlNCM2QzY3VaVzUwY25WemRDNXVaWFF2YkdWbgpZV3d0ZEdWeWJYTXhPVEEzQmdOVkJBc1RNQ2hqS1NBeU1ERXlJRVZ1ZEhKMWMzUXNJRWx1WXk0Z0xTQm1iM0lnWVhWMGFHOXlhWHBsClpDQjFjMlVnYjI1c2VURXpNREVHQTFVRUF4TXFSVzUwY25WemRDQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjUKSUMwZ1JVTXhNQjRYRFRFeU1USXhPREUxTWpVek5sb1hEVE0zTVRJeE9ERTFOVFV6Tmxvd2diOHhDekFKQmdOVkJBWVRBbFZUTVJZdwpGQVlEVlFRS0V3MUZiblJ5ZFhOMExDQkpibU11TVNnd0pnWURWUVFMRXg5VFpXVWdkM2QzTG1WdWRISjFjM1F1Ym1WMEwyeGxaMkZzCkxYUmxjbTF6TVRrd053WURWUVFMRXpBb1l5a2dNakF4TWlCRmJuUnlkWE4wTENCSmJtTXVJQzBnWm05eUlHRjFkR2h2Y21sNlpXUWcKZFhObElHOXViSGt4TXpBeEJnTlZCQU1US2tWdWRISjFjM1FnVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNBdApJRVZETVRCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaUEySUFCSVFUeWRDNmJVRjc0bXpRNjFWZlpnSWFKUFJiaVdsSDQ3akNmZkh5CkFzV2ZvUFpiMVlzR0dZWlBVeEJ0QnlRbm9hRDQxVWNaWVV4OXlwTW42blFNNzIrV0NmNWo3SEJkTnExbmQ2N0puWHhWUkRxaVkxRWYKOWVOaTFLbEhCejdNSUtOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRQpGTGRqNXhyZGpla0lwbFdEcE9CcVVFRmxFVUpKTUFvR0NDcUdTTTQ5QkFNREEyY0FNR1FDTUdGNTJPVkNSOThjcmxPWkY3WnZISDNoCnZ4R1UwUU9JZGVTTmlhU0tkMGJlYldIdkF2WDd0ZC9NL2s3Ly9xbm1wd0l3VzVuWGhUY0d0WHNJL2VzbmkwcVUrZUg2cDQ0bUNPaDgKa21odGM5aHZKcXdoQXJpWnR5WkJXeVZncnRCSUd1NEcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ0ZDQSBFViBST09UCj09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmpUQ0NBM1dnQXdJQkFnSUVHRXJNMWpBTkJna3Foa2lHOXcwQkFRc0ZBREJXTVFzd0NRWURWUVFHRXdKRFRqRXdNQzRHQTFVRQpDZ3duUTJocGJtRWdSbWx1WVc1amFXRnNJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1SVXdFd1lEVlFRRERBeERSa05CCklFVldJRkpQVDFRd0hoY05NVEl3T0RBNE1ETXdOekF4V2hjTk1qa3hNak14TURNd056QXhXakJXTVFzd0NRWURWUVFHRXdKRFRqRXcKTUM0R0ExVUVDZ3duUTJocGJtRWdSbWx1WVc1amFXRnNJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1SVXdFd1lEVlFRRApEQXhEUmtOQklFVldJRkpQVDFRd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUURYWFd2TkVEOGZCVm5WCkJVMDNzUTdzbUN1T0ZSMzZrMHNYZ2lGeEVGTFhVV1J3RnNKVmFVMk9GVzJmdnd3Ynd1Q2paOVlNck04aXJxOTNWQ3BMVElwVFVuckQKN2k3ZXMzRWx3ZWxkUGU2aEw2UDNLanpKSXgxcXF4MmhwL0h6N0tEVlJNOFZ6M0l2SFdPWDZKbjUvWk9rVklCTVV0UlNxeTVKMzVETgp1RisrUDk2aHlrMGcxQ1hvaENsVHQ3R0lILy82MnBDZkNxa3RRVCt4OFJncDdoWlpMRFJKR3FnRzE2aUkwZ055ZWpMaTZtaE5iaXlXClpYdktXZnJ5NHQzdU1Dejd6RWFzeEdQcmIzODJLelJ6RXBSLzM4d21udkZ5WFZCbFdZOXBzNGRlTW0vREdJcTFsWSt3ZWpmZVdrVTcKeHpiaDcyZlJPZE9YVzNOaUdVZ3RoeHdHKzNTWUlFbHo4QVhTRzdHZ283Y2JjTk9JYWJsYTFqajBZdHdsaTNpLytPaCt1RnpKbFU5ZgpweTI1SUd2UGE5MzFEZlNDdC9TeVppNFFLUGFYV251V0ZvOEJHUzFzYm44NVdBWmtnd0dEZzhOTmt0MHl4b2VrTitrV3pxb3RhSzhLCmdXVTZjTUdiclUxdFZNb3FMVXVGRzdPQTVuQkZEV3RlTmZCL083aWM1QVJ3aVJJbGs5b0ttU0pnYW1OZ1RuWUdtRTY5ZzYwZFdJb2wKaGRMSFpSNHRqc2JmdHNiaGY0b0VJUlVwZFBBK25KQ2REQzd4aWo1YXFnd0pIc2ZWUEtQdGw4TWVOUG80K1FnTzQ4QmRLNFBSVm1ySgp0cWhVVXk1NE1tYzlnbjkwMFB2aHRnVmd1WERiamd2NUUxaHZjV0FRVWhDNXdVRUo3M0lmWnpGNC81WUZqUUlEQVFBQm8yTXdZVEFmCkJnTlZIU01FR0RBV2dCVGovaTM5S05BTHRicTJvc1MvQnFvRmpKUDdMekFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZER3RUIKL3dRRUF3SUJCakFkQmdOVkhRNEVGZ1FVNC80dC9TalFDN1c2dHFMRXZ3YXFCWXlUK3k4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQgpBQ1hHdW12cmg4dmVnam1XUGZCRXAydUVjd1BlblN0UHVpQi92SGl5ejVld0c1enoxM2t1OVVpMjB2c1hpT2JUZWovdFV4UFE0aTlxCmVjc0FJeWptSGpkWE5ZbUV3blpQTkRhdFo4UE9RUWFJeGZmdTJCcTQxZ3QvVVArVHFoZExqT3p0VW1DeXBBYnFUdXYwYXhuOTYvVWEKNENVcW10ekhRVGIzeUhRRmhEbVZPZFlMTzZRbitnallYQjc0QkdCU0VTZ29BLy92VTJZQXBVbzBGbVo4L1Fta3JwNW5HbTlCQzJzRwpFNXVQaG5FRnRDK05pV1l6S1haVW1oSDRKL3F5UDVIZ3pnMGI4ekFhcmI4aVhSdlR2eVVGVGVHU0duK1puenhFazhyVVFFbHNnSWZYCkJEckRNbEkxRGxiNHBkMTl4SXNORVI5VHl4NnlGN1pvZDFyZzFNdklCNjcxT2k2T043ZlFBVXRES1hlTU9aZVBnbHI0VWVXSm9Cam4KYUg5ZENpNzdvMGNPUGFZamVzWUJ4NC9JWHI5dGdGYStpaVM2TStxZjRUSVJudkhTVDREMkcwQ3ZPSjRSVUhsekVoTE41bXlkTEloeQpQRENCQnBFaTZsbXQyaGt1SXNLTnVZeUg0R2E4Y3lOZklXUmpnRWoxb0R3WVBaVElTRUVkUUxwZS92NVdPYUhJejE2ZUdXUkdFTm9YCmtiY0ZnS3lMbVpKOTU2TFlCd3MySitkSWVXQ0t3OWNUWFBoeVFOOUt5OCtaQUFvQUN4R1YybFpGQTRnS24yZlExWG14cUkxQWJRM0MKZWtENjgxOWtSNUxMVTdtN1djNVAvZEFWVXdIWTMrdlo1bmJ2MENPN082bDVzOVVDS2MySm81WVBTalhuVGtMQWRjMEh6K1lzNjNzdQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpPSVNURSBXSVNlS2V5IEdsb2JhbCBSb290IEdCIENBCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR0VENDQXAyZ0F3SUJBZ0lRZHJFZ1VuVHdoWWRHcy9nakd2YkN3REFOQmdrcWhraUc5dzBCQVFzRkFEQnRNUXN3Q1FZRFZRUUcKRXdKRFNERVFNQTRHQTFVRUNoTUhWMGxUWlV0bGVURWlNQ0FHQTFVRUN4TVpUMGxUVkVVZ1JtOTFibVJoZEdsdmJpQkZibVJ2Y25ObApaREVvTUNZR0ExVUVBeE1mVDBsVFZFVWdWMGxUWlV0bGVTQkhiRzlpWVd3Z1VtOXZkQ0JIUWlCRFFUQWVGdzB4TkRFeU1ERXhOVEF3Ck16SmFGdzB6T1RFeU1ERXhOVEV3TXpGYU1HMHhDekFKQmdOVkJBWVRBa05JTVJBd0RnWURWUVFLRXdkWFNWTmxTMlY1TVNJd0lBWUQKVlFRTEV4bFBTVk5VUlNCR2IzVnVaR0YwYVc5dUlFVnVaRzl5YzJWa01TZ3dKZ1lEVlFRREV4OVBTVk5VUlNCWFNWTmxTMlY1SUVkcwpiMkpoYkNCU2IyOTBJRWRDSUVOQk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMkJlM0hFb2tLdGFYCnNjcmlIdnQ5T08rWTliSTVtRTRudUJGZGU5SWxsSWlDRlNacUd6RzdxRnNoSVN2WUQwNmZXdkd4V3VSNTFqSWpLK0ZUekpsRlhIdFAKcmJ5L2gwb0xTNWRhcVBaSTdIMTdEYzBoQnQrZUZmMUJpa2kzSVBTaGVodFgxRjFRLzdwbjJDT1pIOGcvNDk3L2IxdDNzV3R1dU1sawo5K0hLUVVZT0tYSFF1U1A4eVlGZlR2ZHYzNytFclhOa3U3ZENqbW4yMUhZZGZwMm51RmVLVVdkeTE5U291SlZVUUhNRDl1cjA2LzRvClFuYy9uU01ic3JZOWdCUUhUQzVQOTlVS0ZnMjlaa00zZmlORGVjTkFodlZNS2RxT21xME5wUVNIaUI2RjQrbFQxWnZJaXdOamVPdmcKR1VwdXV5OXJNMlJZazYxcHY0OGI3NEpJeHdJREFRQUJvMUV3VHpBTEJnTlZIUThFQkFNQ0FZWXdEd1lEVlIwVEFRSC9CQVV3QXdFQgovekFkQmdOVkhRNEVGZ1FVTlEvSU5tTmU0cVBzK1R0bUZjNVJVdU9SbWowd0VBWUpLd1lCQkFHQ054VUJCQU1DQVFBd0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnRUJBRUJNKzRleW1ZR1FmcDNGc0xBbXpZaDdLektOYnJnaGNWaVhmYTQzRks4KzUvZWE0bjMyY1ppWkJLcEQKZEhpajQwbGhQbk9NVFpUZytYSEV0aFlPVTNnZjFxS0hMd0k1Z1NrOHJ4V1lJVEQrS0pBQWpOSGh5L3BleVAzNEVFWTdvbmhDa1JkMApWUXJlVUdkTlp0R24vLzNad0xXb280ck9adlVQUTgybksxZDdZMFpxcWk1UzJQVHQ0VzJ0S1pCNFNMcmhJNnFqaWV5MXE1YkF0RXVpCkhaZWVldkp1UUhIZmFQRmxUYzU4QmQ5VFphbWw4TEdYQkhBVlJnT1kxTksvVkxTZ1dIMVNiOXBXSm1MVTJOdUpNVzhjOENMQzAySWMKTmMxTWFSVlVHcENZM3VzZVg4cDN4OHVPUFVOcG5KcFkwQ1E3M3h0QWxuNDFyWUhIVG5HNmlCTT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU1pBRklSIFJPT1QgQ0EyCj09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGNqQ0NBbHFnQXdJQkFnSVVQb3BkQit4VjBqTFZ0K08yWHdIckxkemsxdVF3RFFZSktvWklodmNOQVFFTEJRQXdVVEVMTUFrRwpBMVVFQmhNQ1VFd3hLREFtQmdOVkJBb01IMHR5WVdwdmQyRWdTWHBpWVNCU2IzcHNhV042Wlc1cGIzZGhJRk11UVM0eEdEQVdCZ05WCkJBTU1EMU5hUVVaSlVpQlNUMDlVSUVOQk1qQWVGdzB4TlRFd01Ua3dOelF6TXpCYUZ3MHpOVEV3TVRrd056UXpNekJhTUZFeEN6QUoKQmdOVkJBWVRBbEJNTVNnd0pnWURWUVFLREI5TGNtRnFiM2RoSUVsNlltRWdVbTk2YkdsamVtVnVhVzkzWVNCVExrRXVNUmd3RmdZRApWUVFEREE5VFdrRkdTVklnVWs5UFZDQkRRVEl3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzN2RDVRCnFFdk5RTFhPWWVlV3lyU2gyZ3dpc1BxMWUzWUFkNHdMejMyb2hzd21VZVFnUFlVTTFsamo1L1FxR0ozYTBhNG03dXRUM1BTUTFoTksKREpBOHcvVGEwbzROa2pyY3NiSC9PTjdEdWkxZmdMa0N2VXFkR3crMHc4TEJad1BkM0J1Y1BiT3czZ0FlcURSSHU1cnIvZ3NVdlRhRQoyZzBndi9wYnk2a1dJSzA1WU80dmRiYm5sNXo1UHYxK1RXOU5MKytJRFdyNjNmRTliaUNsb0JLMFRYQzV6dGR5TzRtVHA0Q0VIQ2RKCmNrbTEvenVWbnNITXlBSHM2QTZLQ3BibnM2YUg1ZGI1QlNzTmwwQndQTHFzZFZxYzFVMmRBZ3JTUzV0bVMwWUhGMld0bjJ5SUFOd2kKaWVEaFpOUm52REY1WVR5N3lrSE5YR29BeUR3NGpsaXZBZ01CQUFHalFqQkFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUApBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlF1RnFsS0dMWEx6UFZ2VVBNalgvaGQ1Nnp3eURBTkJna3Foa2lHOXcwQkFRc0ZBQU9DCkFRRUF0WFA0QTl4Wld4MTI2YU1xZTVBb3NrM0FNMCtxbXJIVXVPUW4vNm1XbWM1RzRHMThUS0k0cEFadzhQUkJFZXcvUjQwL2NvZjUKTy8ya2J5dFRBT0QvT2JscUJ3N3JIUnoyb25LUXk0STlFWUtMMHJ1ZktxOGg1bU9HblhrWjcvZTdERFdRdzRydFR3LzF6QkxacEQ2NwpvUHdnbFY5UEppOFJJNE5PZFFjUHY1dlJ0QjNwRUFUK3ltQ1Bva3k0cmMvaGtBL05yZ3JIWFh1M1VOTFVZZnJWRmR2WG40ZFJWT3VsCjQrdkpoYUFsSURmN2pzNE1OSVRoUElHeWQwNURwWWhmaG1laFBlYTBYR0cyUHR2K3R5akZvZ2V1dGNyS2pTb1M3NWZ0d2pDa3lTcDYKKy9OTkl4dVpNelNnTHZXcEN6L1VYZUhQaEovaUdjSmZpdFlnSHVOenR3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyCj09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjBqQ0NBN3FnQXdJQkFnSVFJZGJRU2s4bEQ4a3lOL3lxWGhLTjZUQU5CZ2txaGtpRzl3MEJBUTBGQURDQmdERUxNQWtHQTFVRQpCaE1DVUV3eElqQWdCZ05WQkFvVEdWVnVhWHBsZEc4Z1ZHVmphRzV2Ykc5bmFXVnpJRk11UVM0eEp6QWxCZ05WQkFzVEhrTmxjblIxCmJTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRFa01DSUdBMVVFQXhNYlEyVnlkSFZ0SUZSeWRYTjBaV1FnVG1WMGQyOXkKYXlCRFFTQXlNQ0lZRHpJd01URXhNREEyTURnek9UVTJXaGdQTWpBME5qRXdNRFl3T0RNNU5UWmFNSUdBTVFzd0NRWURWUVFHRXdKUQpUREVpTUNBR0ExVUVDaE1aVlc1cGVtVjBieUJVWldOb2JtOXNiMmRwWlhNZ1V5NUJMakVuTUNVR0ExVUVDeE1lUTJWeWRIVnRJRU5sCmNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNU1F3SWdZRFZRUURFeHREWlhKMGRXMGdWSEoxYzNSbFpDQk9aWFIzYjNKcklFTkIKSURJd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUM5K1hqNDV0V0FER1NkaGh1V1pHYy9Jam9lZFFGOQo3L3RjWjR6SnpGeHJxWkhtdVVMbElFdWIycHQ3dVpsZDJadUFTOWVFUUNzbjAraTZNTHMrQ1JxblNaWHZLMEFrd3BmSHArNmJKZStvCkNnQ1hoVnFxbmR3cHllSTFCK3R3VFVyV3diTld1S0ZCT0p2Uit6Ri9qK0JmNGJFL0Q0NFdTV0RYQm8wWSthb21FS3NxMDlEUlo0MGIKUnI1SE1OVXVjdEhGWTlyblkzbEVma3RqSkltR0xqUS9LVXhTaXlxbndPS1JLSW01d0Z2NUhkbm5KNjMvbWdLWHdjWlFrcHNDTEwycAp1VFJaQ3IrRVN2L2Yvck9mNjltZTRKZ2o3S1pyZHhZcTI4eXRPeHlraDl4R2MxNFpZbWhGVitTUWdrSzdRdGJ3WWVEQm96MW1vMTMwCkdPNkl5WTBYUlNtWk1uVUNNZTRwSnNockF1YTFZa1YvTnhWYUkyaUoxRDdlVGlldzhFQU12RTBYeTAyaXN4N1FCbHJkOXBQUFYzV1oKOWZxR0dtZDRzNytXL2pUY3ZlZFNWdVd6NVhWNzEwR1JCZHhkYWVPVkRVTzUvSU9XT1pWN2JJQmFUeE55eHRkOUtYcEV1bEtrS3RWQgpSZ2tnL2lLZ3Rsc3dqYnlKRE5YWGNQaUhVdjNhNzZ4UkxnZXpUdjdRQ2Rwdzc1ajZWdVp0MjdWWFM5emxMQ1VWeUo0dWVFNzQycHllCmhpektWL01hNWNpU2l4cUNsbnJEdkZBU2FkZ09Xa2FMT3VzbStpUEp0ckNCdmtJQXBQalcvakF1eDlKRzl1V09kZjN5ekxuUWgxdk0KQmhCZ3U0TTF0MTVuM2tmc21VanhwS0VWL3EyTVlvNDVWVTg1RnJteFk1My90d0lEQVFBQm8wSXdRREFQQmdOVkhSTUJBZjhFQlRBRApBUUgvTUIwR0ExVWREZ1FXQkJTMm9WUTVBc09nUDQ2S3ZQclUrQnltMFRvTy9UQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0RRWUpLb1pJCmh2Y05BUUVOQlFBRGdnSUJBSEdsRHM3azZiOC9PTldKV3NRQ1lmdE14UlFYTFl0UFUyc1FGL3hsaE1jUVNaRGUyOGNtazRnbWIzRFcKQWw0NW9QZVBxNWExcFJOY2dSUnREb0dDRVJ1S1RzWlBwZDFpSGtUZkNWbjBXM2NMTittTElNYjRDazR1V0J6ck05RFBobURKMnZ1QQpMNTVNWUlSNFBTRmsxdnRCSHhnUDU4bDFjYjI5WE40MGh6NUJzQTcydWRZL0NST1dGQy9lbWgxYXVWYk9OVHF3WDNCTlh1TXA4U01vCmNsbTJxOEtNWmlZY2R5d21kaldMS0tkcG9Qazc5U1BkaFJCMHlaQURWcEhucjdwSDFCS1hFU0xqb2ttVWJPZTNsRXU2TGFUYU00dE0KcGtUL1dqekdIV1RZdFRIa3BqeDZxRmNMMisxaEdzdnh6bk4zWTZTSGIweFJPTmJrWDhlZnRvRXE1SVZJZVZoZU8vamJBb0pud1RuYgp3M1JMUFRZZStTbVRpR2hicUVRWklmQ242SUVOTE9pVE5yUTNzc3F3R3laNm1pVWZtcHFBbmtzcVAvdWptdjV6TW5IQ25zWnk0WXBvCkovSGtEN1RFVEtWaGsvaVhFQWNxTUNXcHVjaHh1TzlvekMxKzllQitENEtvYjdhNmJJTkRkODJLa2hlaG5sdDRGajFGNGpOeTNlRm0KeXBuVHljVW0vUTFvQkVhdXR0bWJqTDRadnJIRzhobmpYQUxLTE5odlNnZlp5VFhhUUhYeXhLY1piNTVDRUpoMTVwV0xZTHp0eFJMWAppczdWbUZ4V2xnUEY3bmNHTmYvUDVPNC9FMkh1MjlvdGhmRE5ycDJ5R0FsRnc1S2hjaGY4UjdhZ0N5enh4TjVEYUFocVh6dndkbVA3CnpBWXNwc2JpRHJXNXZpU1AKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxNQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlHQ3pDQ0EvT2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURDQnBqRUxNQWtHQTFVRUJoTUNSMUl4RHpBTkJnTlZCQWNUCkJrRjBhR1Z1Y3pGRU1FSUdBMVVFQ2hNN1NHVnNiR1Z1YVdNZ1FXTmhaR1Z0YVdNZ1lXNWtJRkpsYzJWaGNtTm9JRWx1YzNScGRIVjAKYVc5dWN5QkRaWEowTGlCQmRYUm9iM0pwZEhreFFEQStCZ05WQkFNVE4waGxiR3hsYm1saklFRmpZV1JsYldsaklHRnVaQ0JTWlhObApZWEpqYUNCSmJuTjBhWFIxZEdsdmJuTWdVbTl2ZEVOQklESXdNVFV3SGhjTk1UVXdOekEzTVRBeE1USXhXaGNOTkRBd05qTXdNVEF4Ck1USXhXakNCcGpFTE1Ba0dBMVVFQmhNQ1IxSXhEekFOQmdOVkJBY1RCa0YwYUdWdWN6RkVNRUlHQTFVRUNoTTdTR1ZzYkdWdWFXTWcKUVdOaFpHVnRhV01nWVc1a0lGSmxjMlZoY21Ob0lFbHVjM1JwZEhWMGFXOXVjeUJEWlhKMExpQkJkWFJvYjNKcGRIa3hRREErQmdOVgpCQU1UTjBobGJHeGxibWxqSUVGallXUmxiV2xqSUdGdVpDQlNaWE5sWVhKamFDQkpibk4wYVhSMWRHbHZibk1nVW05dmRFTkJJREl3Ck1UVXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFEQytLay9HNG44UER3RVhUMlFOckNST25rOFpscnYKYlRrQlNScTB0ODkvVFNOVHQ1QUE0eE1xS0tZeDhaRUE0eWpzcmlGQnpoL2EvWDBTV3dHREQ3bXdYNW5oOGhLRGdFMEdQdCtzcitlaAppR3N4ci9DTDBCZ3p1TnRGYWpUMEFvQWtLQW9DRlpWZWRpb05tVG9VVy9iTHkxTzhFMDBCaURlVUpSdEN2Q0xZanFPV1hqclpNdHMrCjZQQVFaZTEwNFMrbmZLOG5OTHNwZlp1Mnp3bkk1ZE1LL0lobFpYUUszSE1jWE0xQXNSelV0b1NNVEZEUGFJNm9XYTdDSjA2Q29qWGQKRlBRZi83SjMxWWN2cW01OUpDZm54c3NtNXVYK1p3ZGoyRVVOM1RwWlpUbFllcEtaY2oyY2hGNklJYmpWOUN6ODJYQlNUM2k0dlR3cgppNVdZOWJQUmFNOGdGSDVNWEYvbmkrWDFOWUVaTjljUkNMZG12dE5Lem9OWEFEckRnZmdYeTVJMlhkR2oySFViNFlzbjZucElRZjFGCkdRYXRKNWxPd1hCSDNiV2ZnVk1TNWJHTVNGMHhReGZqak1aNlk1WkxLVEJPaEU1aUdWNDh6cGVRcFg4QjY1M2crSXVKM1NXWVBaSzIKZnUvWjhWRlJmUzBteUdsWlllQ3NhcmdxTmhFRWVsQzlNb1MrTDl4eTFkY2RGa2ZrUjJZZ1AvU1d4YStPQVhxbEQzcGs5UTBZaDltdQppTlg2aE1FNndHa29MZklOYUZHcTQ2VjN4cVNRRHFFM2l6RWpSOEVKQ090dTkzaWIxNEw4aENDWlNSbTJFa2F4KzBWVkZxbWpaYXljCkJ3L3FhOXdmTGdaeTdJYUlFdVF0MjE4RkwrVHdBOU1tTStlQXdzMUNvUmMwQ3dJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQUQKQVFIL01BNEdBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVWNSVm55TWpKdlhWZGN0QTRHR3FkODNFa1ZBc3dEUVlKS29aSQpodmNOQVFFTEJRQURnZ0lCQUhXN2JWUkxxaEJZUmpUeVl0Y1dObDBJWHRWc3lJZTl0QzVHOGpINGZPcEN0Wk1XVmR5aERCS2cybUYrCkQxaFljMlJ5eCtoRmp0eXA4aVkveG5tTXNWTUlNNEd3VmhPKzVsRmMySnNLVDB1Y1ZsTUM2VS8yRFdEcVRVSlY2SHdiSVNIVEd6ck0KZC9LNGtQRm94L2xhL3ZvdDlML0o5VVViempnUUtqZUtlYU8wNHdsc2hZYVQvNG1XSjNpQmoyZmpSblJVanRrTmFlSks5RTEwQS8reQpkKzJWWjVma3NjV3J2Mm9qNk5TVTRrUW9Zc1JMNHZEWTRpbHJHbkIrSkdHVGUwOERNaVVOUlNRcmxyUkdhcjlLQy9lYWo4R3NHc1ZuCjgyODAwdnB6WTR6dkZyQ29wRVlxK09zUzdISzA3L2dyZm94U3dJdUVWUGt2UHVOVnFOeG1zZG5oWDlpempGazBXYVNyVDJ5N0h4amIKZGF2WXk1TE5sRGhoRGdjR0gwdEdFUEVWdm8yRlhEdEtLNEY1RDdScG4wbFFsMDMzRGxaZHdKVnF3amJERzJqSjlTcmNSNXErc3M3RgpKZWo2QTduYStSWnVrWVQxSENqSS9DYk0xeHlRVnFkZmJ6b0V2TTE0aVF1T0R5K2pxaytpR3hJOUZnaEFEL0ZHVE5lcWV3akJDdlZ0Cko5NENqOHJEdFN2SzZldklJVk00cGN3NzJIYzNNS0pQMlcvUjhrQ3RRWG9YeGRaS05ZbTNRZFY4aG45VlRZTktwWE1nd0RxdmtQR2EKSkk3WmpuSEtlN2lHMnJLUG1UNGRFdzBTRWU3VXEvRHBGWFlDNU9EZnFpQWVXMkdGWkVDcGtKY05yVlBTV2gySGFnQ1haV0swdm05cQpwL1VzUXUweXJiWWhucjY4Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDd3pDQ0FrcWdBd0lCQWdJQkFEQUtCZ2dxaGtqT1BRUURBakNCcWpFTE1Ba0dBMVVFQmhNQ1IxSXhEekFOQmdOVkJBY1RCa0YwCmFHVnVjekZFTUVJR0ExVUVDaE03U0dWc2JHVnVhV01nUVdOaFpHVnRhV01nWVc1a0lGSmxjMlZoY21Ob0lFbHVjM1JwZEhWMGFXOXUKY3lCRFpYSjBMaUJCZFhSb2IzSnBkSGt4UkRCQ0JnTlZCQU1UTzBobGJHeGxibWxqSUVGallXUmxiV2xqSUdGdVpDQlNaWE5sWVhKagphQ0JKYm5OMGFYUjFkR2x2Ym5NZ1JVTkRJRkp2YjNSRFFTQXlNREUxTUI0WERURTFNRGN3TnpFd016Y3hNbG9YRFRRd01EWXpNREV3Ck16Y3hNbG93Z2FveEN6QUpCZ05WQkFZVEFrZFNNUTh3RFFZRFZRUUhFd1pCZEdobGJuTXhSREJDQmdOVkJBb1RPMGhsYkd4bGJtbGoKSUVGallXUmxiV2xqSUdGdVpDQlNaWE5sWVhKamFDQkpibk4wYVhSMWRHbHZibk1nUTJWeWRDNGdRWFYwYUc5eWFYUjVNVVF3UWdZRApWUVFERXp0SVpXeHNaVzVwWXlCQlkyRmtaVzFwWXlCaGJtUWdVbVZ6WldGeVkyZ2dTVzV6ZEdsMGRYUnBiMjV6SUVWRFF5QlNiMjkwClEwRWdNakF4TlRCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaUEySUFCSktnUWVoTGdvUmM0dmd4RVptR1pFNEpKUytkUVM4S3JqVlAKZEpXeVVXUnJqV3ZtUDNDVjhBVkVSNlp5T0ZCMmxRSmFqcTRvbnZrdFRwbnZMRWh2VENVcDZORnhXOThkd1hVM3ROZjZlM3BDbkdvSwpWbHA4YVF1cWdBa2tiSDdCUnFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPCkJCWUVGTFFpQzRLWkpBRU9uTHZrRHYyLys1Y2drNWtxTUFvR0NDcUdTTTQ5QkFNQ0EyY0FNR1FDTUdmT0ZtSTRvcXhpUmFlcGxTVEEKR2llY01qdkF3Tlc2cWVmNEJFTlRoZTVTSWQ2ZDlTV0RQcDVZU3kvWFp4TU9JUUl3QmVGMUFkNW83U29mVFV3SkNBM3NTNjFrRnlqbgpkYzVGWlhJaEY4c2lRUTZNRTVnNG1sUnRtOHJpZk9vQ1dDS1IKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKSVNSRyBSb290IFgxCj09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmF6Q0NBMU9nQXdJQkFnSVJBSUlRejdEU1FPTlpSR1BndTJPQ2l3QXdEUVlKS29aSWh2Y05BUUVMQlFBd1R6RUxNQWtHQTFVRQpCaE1DVlZNeEtUQW5CZ05WQkFvVElFbHVkR1Z5Ym1WMElGTmxZM1Z5YVhSNUlGSmxjMlZoY21Ob0lFZHliM1Z3TVJVd0V3WURWUVFECkV3eEpVMUpISUZKdmIzUWdXREV3SGhjTk1UVXdOakEwTVRFd05ETTRXaGNOTXpVd05qQTBNVEV3TkRNNFdqQlBNUXN3Q1FZRFZRUUcKRXdKVlV6RXBNQ2NHQTFVRUNoTWdTVzUwWlhKdVpYUWdVMlZqZFhKcGRIa2dVbVZ6WldGeVkyZ2dSM0p2ZFhBeEZUQVRCZ05WQkFNVApERWxUVWtjZ1VtOXZkQ0JZTVRDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBSzNvSkhQMEZEZnptNTRyClZ5Z2NoNzdjdDk4NGtJeHVQT1pYb0hqM2RjS2kvdlZxYnZZQVR5amIzbWlHYkVTVHRyRmovUlFTYTc4ZjB1b3hteUYrMFRNOHVrajEKM1huZnM3ai9FdkVobWt2QmlvWnhhVXBtWm15UGZqeHd2NjBwSWdiejVNRG1nSzdpUzQrM21YNlVBNS9UUjVkOG1VZ2pVK2c0cms4SwpiNE11MFVsWGpJQjB0dG92MERpTmV3TndJUnQxOGpBOCtvK3UzZHBqcStzV1Q4S09FVXQrend2by83VjNMdlN5ZTByZ1RCSWxESENOCkF5bWc0Vk1rN0JQWjdobS9FTE5LakQrSm8yRlIzcXlIQjVUMFkzSHNMdUp2VzVpQjRZbGNOSGxzZHU4N2tHSjU1dHVrbWk4bXhkQVEKNFE3ZTJSQ09GdnUzOTZqM3grVUNCNWlQTmdpVjUrSTNsZzAyZFo3N0RuS3hIWnU4QS9sSkJkaUIzUVcwS3RaQjZhd0JkcFVLRDlqZgoxYjBTSHpVdktCZHMwcGpCcUFsa2QyNUhON3JPckZsZWFKMS9jdGFKeFFaQktUNVpQdDBtOVNUSkVhZGFvMHhBSDBhaG1iV25PbEZ1CmhqdWVmWEtuRWdWNFdlMCtVWGdWQ3dPUGpkQXZCYkkrZTBvY1MzTUZFdnpHNnVCUUUzeERrM1N6eW5UbmpoOEJDTkF3MUZ0eE5yUUgKdXNFd01GeEl0NEk3bUtaOVlJcWlveW1DekxxOWd3UWJvb01EUWFIV0JmRWJ3cmJ3cUh5R08wYW9TQ3FJM0hhYWRyOGZhcVU5R1kvcgpPUE5rM3NnckRRb28vL2ZiNGhWQzFDTFFKMTNoZWY0WTUzQ0lyVTdtMllzNnh0MG5VVzcvdkdUMU0wTlBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlI1dEZubWU3Ymw1QUZ6Z0FpSXlCcFkKOXVtYmJqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFWUjlZcWJ5eXFGRFFETEhZR21rZ0p5a0lyR0YxWElwdStJTGxhUy9WOWxaTAp1Ymh6RUZuVElaZCs1MHh4KzdMU1lLMDVxQXZxRnlGV2hmRlFEbG5yenVCWjZickpGZStHblkrRWdQYms2WkdRM0JlYllodEY4R2FWCjBueHZ3dW83N3gvUHk5YXVKL0dwc01pdS9YMSttdm9pQk92LzJYL3FrU3Npc1JjT2ovS0tORnRZMlB3QnlWUzV1Q2JNaW9nemlVd3QKaER5QzMrNldWd1c2TEx2M3hMZkhUanVDdmpISUluTnprdEhDZ0tRNU9SQXpJNEpNUEorR3NsV1lIYjRwaG93aW01N2lhenRYT29KdwpUZHdKeDRuTENnZE5iT2hkanNudnpxdkh1N1VyVGtYV1N0QW16T1Z5eWdocXBaWGpGYUgzcE8zSkxGK2wrLytzS0FJdXZ0ZDd1K054CmU1QVcwd2RlUmxOOE53ZENqTlBFbHB6Vm1iVXE0SlVhZ0VpdVREa0h6c3hIcEZLVks3cTQrNjNTTTFOOTVSMU5iZFdoc2NkQ2IrWkEKSnpWY295aTNCNDNualRPUTV5T2YrMUNjZVd4RzFiUVZzNVp1ZnBzTWxqcTRVaTAvMWx2aCt3akNoUDRrcUtPSjJxeHE0Umdxc2FoRApZVnZUSDl3N2pYYnlMZWlOZGQ4WE0ydzlVL3Q3eTBGZi85eWkwR0U0NFphNHJGMkxOOWQxMVRQQW1SR3VuVUhCY25XRXZnSkJRbDluCkpFaVUwWnNudmdjL3ViaFBnWFJSNFhxMzdaMGo0cjdnMVNnRUV6d3hBNTdkZW15UHhnY1l4bi9lUjQ0L0tKNEVCcytsVkRSM3ZleUoKbStrWFE5OWIyMS8ramg1WG9zMUFuWDVpSXRyZUdDYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQUMgUkFJWiBGTk1ULVJDTQo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGZ3pDQ0EydWdBd0lCQWdJUFhaT05NR2MyeUFZZEdzZFVoR2tITUEwR0NTcUdTSWIzRFFFQkN3VUFNRHN4Q3pBSkJnTlZCQVlUCkFrVlRNUkV3RHdZRFZRUUtEQWhHVGsxVUxWSkRUVEVaTUJjR0ExVUVDd3dRUVVNZ1VrRkpXaUJHVGsxVUxWSkRUVEFlRncwd09ERXcKTWpreE5UVTVOVFphRncwek1EQXhNREV3TURBd01EQmFNRHN4Q3pBSkJnTlZCQVlUQWtWVE1SRXdEd1lEVlFRS0RBaEdUazFVTFZKRApUVEVaTUJjR0ExVUVDd3dRUVVNZ1VrRkpXaUJHVGsxVUxWSkRUVENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DCmdnSUJBTHB4Z0hwTWhtNS95Qk50d01aOUhBQ1hqeXdNSTdzUW1rQ3BHcmVIaVBpYlZtcjc1bnVPaTVLT3B5VmRXUkhiTmk2M1VSY2YKcVFnZkJCY2tXS28zU2hqZjVUblVWLzNYd1N5UkFaSGlJdFFEd0ZqOGQwZnNqejUwUTdxc05JMU5PSFpuanJESWJ6QXpXSEZjdFBWcgpidFFCVUxnVGZteEtvMG5SSUJudXZNQXBHR1duM3Y3djNRcVFJZWNhWjVKQ0VKaGZUekM4UGh4RnRCRFhhRUFVd0VENjUzY1hldVlMCmoyVmJQTm1hVXR1MXZaNUd6ejNya1FVQ3dKYXlka3hORUpZN2t2cWNmdytaMzc0ak5VVWVBbHordGFpYm1TWGFYdk1pd3puMTVDb3UKMDhZZnhHeXF4UnhxQVFWS0w5TEZ3YWcwSmwxbXBkSUNJZmtZdHdiMVRwbHZxS3RNVWVqUFVCakZkOGc1Q1N4SmtqS1pxTHNYRjNtdwpXc1htbzhSWlpVYzFnMTZwNkRVTG1idmt6U0RHbTBvR09iVm8vQ0s2N2xXTUswN3E4N0hqL0xhWm10VkMrbkZOQ00rSEhtcHhmZm5UCnRPbWxjWUY3d2s1SGxxWDJkb1dqS0kvcGdHNkJVNlZ0WDdoSStjTDVOcVl1U2YrNGxzS01CN09iaUZqODZ4c2MzaTF3NHBlU01LR0oKNDd4VnFDZldTKzJRcll2Nll5VlpMYWcxM2NxWE03emx6Y2VkMGV6dlhnNUtrQVltWTYyNTJUVXRCN3AyWlN5c1Y0OTk5QWVVMTRFQwpsbDJqQjBuVmV0QlgrUnZuVTBaMXFyQjVRc3RvY1FqcFlMMDVhYzcwcjhOV1FNZXRVcUlKNUcrR1I0b2Y2eWduWFlNZ3J3VEpiRmFhCmkwYjFBZ01CQUFHamdZTXdnWUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUUKRlBkOXhmM0U2Sm9iZDJTbjlSMmd6TCtIWUpwdE1ENEdBMVVkSUFRM01EVXdNd1lFVlIwZ0FEQXJNQ2tHQ0NzR0FRVUZCd0lCRmgxbwpkSFJ3T2k4dmQzZDNMbU5sY25RdVptNXRkQzVsY3k5a2NHTnpMekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBQjVCSzMvTWpUdkRECm5GRmxtNXdpb29vTWhmTnpLV3ROL2dIaXFReGpBYjhFWjZXZG1GLzlBUlA2N0pwaTZZYit0bUxTYmt5VSs4QjFSWHhsRFBpeU44K3MKRDgrTmIva1o5NC9zSHZKd252REt1TyszLzNZM2RsdjJib2p6cjJJeUlwTU5PbXFPRkdZTUxWTjBWMlVlMWJMZEk0RTdwV1lqSjJjSgpqK0YzcWtQTlpWRUk3VkZZL3VZNStjdEhoS1FWOFhhN3BPNmtPOFJmNzdJemxoRVl0OGxsdmhqaG82VGMraGo1MDd3VG16bDZOTHJUClFmdjZNb29xdHl1R0MybURPTDdOaWk0TGNLMk5KcEx1SHZVQkt3cloxcGViYnVDb0dSdzZJWXNNSGtDdEErZmRabjcxdVNBTkEraVcKK1lKRjFEbmdvQUJkMTVqbWZaNW5jOE9hS3Zlcmk2RTZGTzgwdkZJT2laaWFCRUNFSFg1RmFaTlh6dXZPK0ZCOFR4eHVCRU9iK2RZNwpJeGpwNm83UlRVYU44VHZrYXNxNit5TzNtL3FaQVNsYVdGb3Q0L25VYlE0bXJjRnVOTHd5K0F3RittV2oyenMzZ3lMcDF0eHlNLzFkCjhpQzlkandqMmlqMytSdnJXV1RWM0Y5eWZpRDh6WW0xa0dkTlluby9UcTBkd3puK2V2UW9GdDlCOWtpQUJkY1BVWG1zRUt2VTdBTm0KNW1xd3VqR1NRa0JxdmpyVGN1RnFOMVc4ckIyVnQybGg4a09SZE9hZzB3b2tScUVJcjliYVJSbVcxRk1kVzRSNThNRDNSKytMajhVRwpycDFNWXAzL1JnVDQwOG0yRUNWQWRmNFdxc2xLWUlZdnV1OHdkK1JVNHJpRW1WaUFxaE9MVVRwUFNQYUx0ck09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFtYXpvbiBSb290IENBIDEKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFFUQ0NBaW1nQXdJQkFnSVRCbXlmejVtL2pBbzU0dkI0aWtQbWxqWmJ5akFOQmdrcWhraUc5dzBCQVFzRkFEQTVNUXN3Q1FZRApWUVFHRXdKVlV6RVBNQTBHQTFVRUNoTUdRVzFoZW05dU1Sa3dGd1lEVlFRREV4QkJiV0Y2YjI0Z1VtOXZkQ0JEUVNBeE1CNFhEVEUxCk1EVXlOakF3TURBd01Gb1hEVE00TURFeE56QXdNREF3TUZvd09URUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQW9UQmtGdFlYcHYKYmpFWk1CY0dBMVVFQXhNUVFXMWhlbTl1SUZKdmIzUWdRMEVnTVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUxKNGdISEtlTlhqY2E5SGdGQjBmVzdZMTRoMjlKbG85MWdoWVBsMGhBRXZyQUl0aHRPZ1EzcE9zcVRRTnJvQnZvM2JTTWdICkZ6Wk05TzZJSThjKzZ6ZjF0Um40U1dpdzN0ZTVkamdkWVo2ay9vSTJwZVZLVnVSRjRmbjl0QmI2ZE5xY216VTVML3F3SUZBR2JIclEKZ0xLbSthL3NSeG1QVURnSDNLS0hPVmo0dXRXcCtVaG5NSmJ1bEhoZWI0bWpVY0F3aG1haFJXYTZWT3VqdzVINVNOei8wZWd3TFgwdApkSEExMTRnazk1N0VXVzY3YzRjWDhqSkdLTGhEK3JjZHFzcTA4cDhrRGkxTDkzRmNYbW4vNnBVQ3l6aUtybEE0Yjl2N0xXSWJ4Y2NlClZPRjM0R2ZJRDV5SEk5WS9RQ0IvSUlERWdFdytPeVFtamdTdWJKcklxZzBDQXdFQUFhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBT0JnTlZIUThCQWY4RUJBTUNBWVl3SFFZRFZSME9CQllFRklRWXpJVTA3THdNbEpRdUNGbWN4N0lRVGdvSU1BMEdDU3FHU0liMwpEUUVCQ3dVQUE0SUJBUUNZOGpkYVFaQ2hHc1YyVVNnZ05pTU9ydVlvdTZyNGxLNUlwREIvRy93a2pVdTB5S0dYOXJieGVuRElVNVBNCkNDamptQ1hQSTZUNTNpSFRmSVVKclU2YWRUckNDMnFKZUhaRVJ4aGxiSTFCamp0L21zdjB0YWRRMXdVc04rZ0RTNjNwWWFBQ2J2WHkKOE1XeTdWdTMzUHFVWEhlZUU2Vi9VcTJWOHZpVE85NkxYRnZLV2xKYllLOFU5MHZ2by91ZlFKVnRNVlQ4UXRQSFJoOGpyZGtQU0hDYQoyWFY0Y2RGeVF6UjFibGRad2dKY0ptQXB6eU1aRm82SVE2WFU1TXNJK3lNUlEraERLWEppb2FsZFhnalVrSzY0Mk00VXd0QlY4b2IyCnhKTkRkMlpod0xub1FkZVhlR0FEYmtweXJxWFJmYm9Rbm9ac0c0cTVXVFA0NjhTUXZ2RzUKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQW1hem9uIFJvb3QgQ0EgMgo9PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGUVRDQ0F5bWdBd0lCQWdJVEJteWYwcFkxaHA4S0QrV0dlUGhiSnJ1S056QU5CZ2txaGtpRzl3MEJBUXdGQURBNU1Rc3dDUVlEClZRUUdFd0pWVXpFUE1BMEdBMVVFQ2hNR1FXMWhlbTl1TVJrd0Z3WURWUVFERXhCQmJXRjZiMjRnVW05dmRDQkRRU0F5TUI0WERURTEKTURVeU5qQXdNREF3TUZvWERUUXdNRFV5TmpBd01EQXdNRm93T1RFTE1Ba0dBMVVFQmhNQ1ZWTXhEekFOQmdOVkJBb1RCa0Z0WVhwdgpiakVaTUJjR0ExVUVBeE1RUVcxaGVtOXVJRkp2YjNRZ1EwRWdNakNDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DCmdnSUJBSzJXbnkyY1NreEtnWGxSbWV5S3kydGdVUk84VFcwRy9MQUlqZDBaRUdySEpndzEyTUJ2SUlUcGxMR2JoUVBEVzl0SzZNajQKa0hiWlcwL2pUT2dHTmszTW1xdzlESkFya3RRR0dXQ3NOMFI1aFlHQ3JWbzM0QTNNbmFaTVVuYnFRNTIzQk5GUTlsWGcxZEttU1lYcApOK25LZnE1Y2xVMUltait1SUZwdGlKWFpOTGhTR2tPUXNMOXNCYm0yZUxmcTBPUTZQQkpUWXY5SzhudStOUVdwRWpUajgyUjBZaXc5CkFFbGFLUDR5Ukx1SDNXVW5BbkU3MmtyM0g5ck45eUZWa0U4UDdLNkM0WjlyMlVYVHUvQmZoKzA4TERtRzJqL2U3SEpWNjNtanJkdmQKZkxDNkhNNzgzazgxZHM4UCtIZ2ZhalpSUmlkaFcrbWV6L0NpVlgxOEpZcHZMN1RGejRRdUsvME5VUkJzKzE4YnZCdCt4YTQ3bUFFeAprdjhMVi9TYXNybFg2YXZ2RFhiUjhPNzB6b2FuNEc3cHRHbWgzMm4yTThacExwY1RucVdIc0ZjUWdUZkpVN083Zi9hUzBaelFHUFNTCmJ0cURUNlpqbVV5bCsxN3ZJV1I2SUY5c1pJVVZ5emZwWWd3TEtoYmNBUzR5Mmo1TDlaNDY5aGRBbE8rZWtRaUcrcjVqcUZvejdNdDAKUTVYNWJHbFNOc2NwYi94VkExd2YrNSs5Uit2blNVZVZDMDZKSWdsSjRQVmhIdkcvTG9weWJvQlovMWM2K1hVeW8wNWY3TzBvWXRsTgpjL0xNZ1JkZzdjM3IzTnVueXNWK0FyM3lWQWhVL2JRdENTd1hWRXFZMFZUaFVXY0kwdTF1Zm04LzBpMkJXU2xteTVBNWxSRWVkQ2YrCjNldXZBZ01CQUFHalFqQkFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01CMEdBMVVkRGdRV0JCU3cKRFBCTU1QUUZXQUpJL1RQbFVxOUxoT05tVWpBTkJna3Foa2lHOXcwQkFRd0ZBQU9DQWdFQXFxaUFqdzU0bytDaTFNM205Wmg2TytvQQpBN0NYRHBPOFdxajJMSXh5aDZteC9IOXovV054ZUtXSFdjOHc0UTBRc2hOYWJZTDFhdWFBbjZBRkMyamtSMnZIYXQrMi9YY3ljdVVZCitnbjBvSk1zWGRLTWRZVjJaWkFNQTNtM01TTmpyWGlEQ1lab2hNci8rYzhtbXBKNTU4MUx4ZWRocHhmTDg2a1NrNU5ycCtndlU1TEUKWUZpd3pBSlJHRnVGaldKWlk3YXR0TjZhK3liM0FDZkFYVlUzZEpuSlVIL2pXUzVFNHl3bDd1eE1NbmUwbnhycFMxMGd4ZHI5SEljVwp4a1BvMUxzbW1rVndYcWtMTjFQaVJuc24vZUJHOG9tM3pFSzJ5eWdtYnRtbHlUcklRUk5nOTFDTUZhNnliUm9WR2xkNDVwSXEyV1dRCmdqOXNBcSt1RWpvbmxqWUUxeDJpZ0dPcG0vSGx1clI4RkxCT3liRWZkRjg0OWxIcW0vb3NvaEhVcVMwbkdrV3hyN0pPY1EzQVdFYlcKYVFiTFU4dXovbXRCelVGK2ZVd1BmSEo1ZWxuTlhrb09ySnVwbUhONWZMVDB6TG00Qnd5eWRGeTR4MitJb1pDbjlLcjV2MmM2OUJvVgpZaDYzbjc0OXNTbXZaNkVTOGxnUUdWTURNQnU0R29uMm5MMlhBNDZqQ2ZNZGl5SHh0Ti9rSE5HZlpRSUc2bHpXRTdPRTc2S2xYSXgzCkthZG93R3V1UU5Lb3RPck44STFMT0p3Wm1oc29WTGlKa08vS2RZRStIdkprSk1jWXIwNy9SNTRIOWpWbHBOTUtWdi8xRjJSczc2Z2kKSlVtVHR0OEFGOXBZZmwzdXhSdXcwZEZmSVJESCtmTzZBZ29uQjhYeDFzZlQ0UHNKWUd3PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpBbWF6b24gUm9vdCBDQSAzCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ0akNDQVZ1Z0F3SUJBZ0lUQm15ZjFYU1hObVkvT3d1YTJlaWVkZ1B5U2pBS0JnZ3Foa2pPUFFRREFqQTVNUXN3Q1FZRFZRUUcKRXdKVlV6RVBNQTBHQTFVRUNoTUdRVzFoZW05dU1Sa3dGd1lEVlFRREV4QkJiV0Y2YjI0Z1VtOXZkQ0JEUVNBek1CNFhEVEUxTURVeQpOakF3TURBd01Gb1hEVFF3TURVeU5qQXdNREF3TUZvd09URUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQW9UQmtGdFlYcHZiakVaCk1CY0dBMVVFQXhNUVFXMWhlbTl1SUZKdmIzUWdRMEVnTXpCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkNtWHA4WkIKZjhBTm0rZ0JHMWJHOGxLbHVpMnlFdWpTTHRmNnljWFlxbTBmYzRFN081aHJPWHd6cGNWT2hvNkFGMmhpUlZkOVJGZ2RzemZsWndqcgpadDZqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0dHTUIwR0ExVWREZ1FXQkJTcnR0dlhCcDQzCnJEQ0dCNUZ3eDV6RUdiRjR3REFLQmdncWhrak9QUVFEQWdOSkFEQkdBaUVBNElXU294ZTNqZmtyQnFXVHJCcVlhR0Z5K3VHaDBQc2MKZUdDbVE1bkZ1TVFDSVFDY0F1L3hsSnl6bHZucnhpcjR0aXorT3BBVUZ0ZU1ZeVJJSE44d2ZkVm9Pdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkFtYXpvbiBSb290IENBIDQKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQjhqQ0NBWGlnQXdJQkFnSVRCbXlmMThHN0VFd3BRK1Z4ZTNzc3lCckJEakFLQmdncWhrak9QUVFEQXpBNU1Rc3dDUVlEVlFRRwpFd0pWVXpFUE1BMEdBMVVFQ2hNR1FXMWhlbTl1TVJrd0Z3WURWUVFERXhCQmJXRjZiMjRnVW05dmRDQkRRU0EwTUI0WERURTFNRFV5Ck5qQXdNREF3TUZvWERUUXdNRFV5TmpBd01EQXdNRm93T1RFTE1Ba0dBMVVFQmhNQ1ZWTXhEekFOQmdOVkJBb1RCa0Z0WVhwdmJqRVoKTUJjR0ExVUVBeE1RUVcxaGVtOXVJRkp2YjNRZ1EwRWdOREIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQUJOS3JpamRQbzFNTgovc0dLZTB1b2UwWkxZN0JpOWkwYjJ3aHhJZElBNkdPOW1pZjc4RGx1WGVvOXBjbUJxcU5iSUpoRlhSYmIvZWdRYmVPYzRPTzlYNFJpCjgzQmtNNkRMSkM5d3VvaWhLcUIxK0lHdVlnYkVnZHM1Ymltd0h2b3VYS05DTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlYKSFE4QkFmOEVCQU1DQVlZd0hRWURWUjBPQkJZRUZOUHN4enBsYnN6aDJuYWFWdnVjODRadFYrV0JNQW9HQ0NxR1NNNDlCQU1EQTJnQQpNR1VDTURxTElmRzlmaEd0ME85WWxpL1c2NTEra0kwcnoyWlZ3eXpqS0tsd0NrY084RGRaRXY4dG1aUW9UaXBQTlUweldnSXhBT3AxCkFFNDd4RHFVRXBISldFYWRJUk55cDRpY2l1Uk1TdHVXMUt5TGEydEpFbE16cmRma3ZpVDh0UXAyMUtXOEVBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRVl6Q0NBMHVnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFzRkFEQ0IwakVMTUFrR0ExVUVCaE1DVkZJeEdEQVdCZ05WQkFjVApEMGRsWW5wbElDMGdTMjlqWVdWc2FURkNNRUFHQTFVRUNoTTVWSFZ5YTJsNVpTQkNhV3hwYlhObGJDQjJaU0JVWld0dWIyeHZhbWxyCklFRnlZWE4wYVhKdFlTQkxkWEoxYlhVZ0xTQlVWVUpKVkVGTE1TMHdLd1lEVlFRTEV5UkxZVzExSUZObGNuUnBabWxyWVhONWIyNGcKVFdWeWEyVjZhU0F0SUV0aGJYVWdVMDB4TmpBMEJnTlZCQU1UTFZSVlFrbFVRVXNnUzJGdGRTQlRUU0JUVTB3Z1MyOXJJRk5sY25ScApabWxyWVhOcElDMGdVM1Z5ZFcwZ01UQWVGdzB4TXpFeE1qVXdPREkxTlRWYUZ3MDBNekV3TWpVd09ESTFOVFZhTUlIU01Rc3dDUVlEClZRUUdFd0pVVWpFWU1CWUdBMVVFQnhNUFIyVmllbVVnTFNCTGIyTmhaV3hwTVVJd1FBWURWUVFLRXpsVWRYSnJhWGxsSUVKcGJHbHQKYzJWc0lIWmxJRlJsYTI1dmJHOXFhV3NnUVhKaGMzUnBjbTFoSUV0MWNuVnRkU0F0SUZSVlFrbFVRVXN4TFRBckJnTlZCQXNUSkV0aApiWFVnVTJWeWRHbG1hV3RoYzNsdmJpQk5aWEpyWlhwcElDMGdTMkZ0ZFNCVFRURTJNRFFHQTFVRUF4TXRWRlZDU1ZSQlN5QkxZVzExCklGTk5JRk5UVENCTGIyc2dVMlZ5ZEdsbWFXdGhjMmtnTFNCVGRYSjFiU0F4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEEKTUlJQkNnS0NBUUVBcjNVd002cTdhOU9aTEJJM2hObU5lNWVBMDI3bi81dFFsVDZRbFZaQzF4bDhKb1NOa3ZvQkhUb1A0bVE0dDR5OAo2SWo1aXlTckxxUDFOK1JBamhnbGVZTjFIenYvYktqRnhsYjR0TzJLUktPcmJFejhIZERjNzJpOXorU3F6dkJWOTZJMDFJTnJOM3djCnd2NjFBK3hYenJ5MHRjWHRBQTlUTnlwTjlFOE1nL3VHejh2K2pFNjloL21uaXlGWG5IcmZBMmVKTEoyWFlhY1F1RldRZnc0dEp6aDAKMytmOTJrNFM0MDBWSWdMSTRPRDhENjJLMThsVVVNdzdEOG9XZ0lUUVVWYkRqbFovaVNJekwrYUZDcjJscUJzMjN0UGNMRzA3eHhPOQpXU01zNXVXazk5Z0w3ZXFRUUVTb2xidVQxZENBTkxaR2VBNGZBSk5HNGU3cCtleFBGd0lEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVClpUL0hpb2JHUE4wOFZGdzErRHJ0VWd4SFY4Z3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUoKS29aSWh2Y05BUUVMQlFBRGdnRUJBQ28vNGZFeWpxN2htRnhMWHM5ckhtb0owaUtwRXNkZVYzMXpWbVNBaEhxVDVBbTVFTTJmS2lmaApBSGUrU01nMXFJR2Y1TGdzeVg4T3NOSkxOMTNxdWRVTFhqUzk5SE1wdyswbUZaeCtDRk9LV0kzUVN5amZ3YlBmSVBQNTQrTTYzOHljCmxOaE9UOE5yRjdmM2N1aXRaak8xSlZPcjRQaE1xWjM5OGcyNnJyblpxc1pyK1pPN3JxdTRsendER3JwRHhwYTVSWEk0czZlaGxqMlIKZTM3QUlWTk1oKzN5QzFTVlVaUFZJcVVOaXZHVERqNVVEckRZeVU3YzhqRXlWdXBrK2VxMW5SWm1Rbkx6ZjlPeE1VUDhwSTRYOFcwagpxNVJtK0szN0R3aHVKaTEvRndjSnNvejdVTUNmbG8zUHR2MEFuVm9VbXI4Q1JQWEJ3cDhpWHFJUG9lTT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR0RDQSBUcnVzdEFVVEggUjUgUk9PVAo9PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGaURDQ0EzQ2dBd0lCQWdJSWZRbVgvdkJINm5vd0RRWUpLb1pJaHZjTkFRRUxCUUF3WWpFTE1Ba0dBMVVFQmhNQ1EwNHhNakF3CkJnTlZCQW9NS1VkVlFVNUhJRVJQVGtjZ1EwVlNWRWxHU1VOQlZFVWdRVlZVU0U5U1NWUlpJRU5QTGl4TVZFUXVNUjh3SFFZRFZRUUQKREJaSFJFTkJJRlJ5ZFhOMFFWVlVTQ0JTTlNCU1QwOVVNQjRYRFRFME1URXlOakExTVRNeE5Wb1hEVFF3TVRJek1URTFOVGsxT1ZvdwpZakVMTUFrR0ExVUVCaE1DUTA0eE1qQXdCZ05WQkFvTUtVZFZRVTVISUVSUFRrY2dRMFZTVkVsR1NVTkJWRVVnUVZWVVNFOVNTVlJaCklFTlBMaXhNVkVRdU1SOHdIUVlEVlFRRERCWkhSRU5CSUZSeWRYTjBRVlZVU0NCU05TQlNUMDlVTUlJQ0lqQU5CZ2txaGtpRzl3MEIKQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBMmFNVzhNaDBkSGViN3pNTk93WitWZnkxWUk5MmhoSkNmVlptUG9pQzdYSmpEcDZMM1RRcwpBbEZSd3huOVdWU0V5ZkZyczB5dzZlaEdYVGpHb3FjdUVWZTZnaFdpbkk5dHNKbEtDdkxyaVhCalRubkV0MXU5b2wyeDhrRUNLNjJwCk9xUHNlUXJzWHpyai9lK0FQSzAwbXhxcmlDWjdWcUtDaGgvck5ZbURmMSt1S1U0OXRtN3Nyc0h3SjV1dTQvVHM3NjUvOTRZOWNucnIKcGZ0WlRxZnJsWXdpT1huaExRaVB6THlSdUVIM0ZNRWpxY090bWtWRXM3TFhMTTNHS2VKUUVLNWN5NEtPRnhnMmZaZm1pSnF3VFRRSgo5Q3k1V21ZcXNCZWJuaDUyblVwbU1VSGZQL3ZGQnU4YnRuNGFSamIzWkdNNzR6a1lJK2RuZFJUVmRWZVNONzIrYWhzbVVQSTJKZ2FRCnhYQUJaRzEyWnVHUjIyNEh3R0dBTHJJdUw0eHdwOUU3UExPUjVHNjJ4RHR3OG15U2x3bk5SMzBZd1BPN25nL1dpNjRIdGxvUHpnc00KUjZmbFByaTlmY2ViTmFCaGx6cEJkUmZNSzVaM0twSWhIdG1WZGlCbmFNOE52ZC9XSHdscW11TE1jM0drTDMwU2dMZFRNRVplUzFTWgpEMmZKcGNqeUlNR0M3SjBSMzhJQyt4bzcwZTBnbXU5bFpKSVFEU3JpM25EeEdHZUNqR0hldUx6Ukw1ejdEOUFyN1J0MnVlUTVWZmo0Cm9SMjRxb0FBVElMbnNuOEp1THd3b0M4TjlWS2VqdmVTc3dvQUhRQlVsd2Jnc1FmWnh3OWNaWDA4YlZsWDVPMmxqZWxBVTU4VlM2QngKOWhvaDQ5cHdCaUZZRkllRmQzbXFnbmtDQXdFQUFhTkNNRUF3SFFZRFZSME9CQllFRk9MSlFKOU56dWlhb1h6UERqOWx4U21JYWhsUgpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRRFJTVmZnCnA4eG9XTG9CRHlzWnpZMndZVVdzRWUxalVHbjRIMysrRm8vOW5lc0xxakpIZHRKbkpPMjlmRE15bHlySEJZWm1EUmQ5RkJVYjFPdjkKSDVyMlhwZHB0eG9scEFxemtUOWZOcXlMN0Zlb1B1ZUJpaGhYT1lWMEdrTEg2VnNUWDQvNUNPbVNkSTMxUjlLck85YjdlR1pPTm4zNQo2WkxwQk43OVNXUDhiZnNVY1pObkwwZEt0N24vSGlwemNFWXd2MXJ5TDNtbDRZME0yZm15WXplTU4yV0ZjR3BjV3dseXVhMWpQTEhkCitQd3l2emVHNUx1T21DZCt1aDhXNFhBUjhnUGZKV0l5SnlZWU1vU2Yvd0E2RTdxYVRmUlB1QlJ3SXJIS0s1RE9LY0Z3OUMrZGYvS1EKSHRaYTM3ZEcvT2FHK3N2Z0lIWjZ1cWJMOVh6ZVlxV3hpKzdlZ21hS1Rqb3dIeitBeTYwbnVneGUxOUN4VnNwM2NiSzFkYUZRcVVCRApGOElvMmM5U2kxdklZOVJDUHFBemVrWXU5d29nUmxSK2FrOHg4WUYrUW5RNFpYTW43c1o4dUk3WHBUclhtS0djakJCVjA5dEw3RUNRCjhzMXVWOUppRG54WGs3R25iYzJkZzdzcTUrVzJPM0ZZcmYzUlJieGFrZTVURlcvVFJRbDFicnFRWFI0RXp6ZmZIcWhtc1l6bUlHcnYKL0VoT2RKaENyeWx2TG1ySCszM1JaakVpeklZQWZtYURERUwwdlRTU3d4cnFUOHArY2swTGNJeW1TTHVtb1JUMisxaEVtUlN1cWd1VAphYUFwSlVxbHl5dmRpbVlIRm5nVlYzRWI3UFZIaFBPZU1UZDYxWDhrcmVTOC9mM01ib1BvREtpM1FXd0gzYjA4aHBjdjBnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMQo9PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlFTURDQ0F4aWdBd0lCQWdJSkFOcWI3SEh6QTdBWk1BMEdDU3FHU0liM0RRRUJDd1VBTUlHa01Rc3dDUVlEVlFRR0V3SlFRVEVQCk1BMEdBMVVFQ0F3R1VHRnVZVzFoTVJRd0VnWURWUVFIREF0UVlXNWhiV0VnUTJsMGVURWtNQ0lHQTFVRUNnd2JWSEoxYzNSRGIzSWcKVTNsemRHVnRjeUJUTGlCa1pTQlNMa3d1TVNjd0pRWURWUVFMREI1VWNuVnpkRU52Y2lCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcApkSGt4SHpBZEJnTlZCQU1NRmxSeWRYTjBRMjl5SUZKdmIzUkRaWEowSUVOQkxURXdIaGNOTVRZd01qQTBNVEl6TWpFMldoY05Namt4Ck1qTXhNVGN5TXpFMldqQ0JwREVMTUFrR0ExVUVCaE1DVUVFeER6QU5CZ05WQkFnTUJsQmhibUZ0WVRFVU1CSUdBMVVFQnd3TFVHRnUKWVcxaElFTnBkSGt4SkRBaUJnTlZCQW9NRzFSeWRYTjBRMjl5SUZONWMzUmxiWE1nVXk0Z1pHVWdVaTVNTGpFbk1DVUdBMVVFQ3d3ZQpWSEoxYzNSRGIzSWdRMlZ5ZEdsbWFXTmhkR1VnUVhWMGFHOXlhWFI1TVI4d0hRWURWUVFEREJaVWNuVnpkRU52Y2lCU2IyOTBRMlZ5CmRDQkRRUzB4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2NDYzbGVMQ0poSnJNeG5IUUZnS3ExbXEKalFDai9JREhVSHVPMUNBbXVqSVMyQ05VU1NVUUlwaWRSdExCeVo1T0d5NHNEamp6R2lWb0hLWmFCZVllaTBpL21KWjBQbW5LNmJWNApwUWE4MVFCZUNRcnlKM3BTL0MzVnNlcTBpV0VrOHhvVDI2blBVdTBNSkxxNW51eCtBSFQ2azYxc0taS3VVYlM3MDFlL3MvT29qWnowCkpFc3ExcG1lOUo3K3dINUNPdWNMbFZQYXQyZ09rRXo3Y0QrUFNpeVU4eWJkWTJtcGxOZ1FUc1ZIQ0pDWkd4ZE51V3h1NzJDVkVZNGgKZ0xXOW9IUFkwTEozeEVYcVdpYjdabloyK0FZZllXMFBWY1dEdHhCV2NnWUhwZk94R2dNRlpBNmRXb3JXaG5BYkpONytLSW9yMEdxdwovSHFpM0xKNURvdGxEd0lEQVFBQm8yTXdZVEFkQmdOVkhRNEVGZ1FVN210SlBIby9EZU94Q2JlS3lLc1puM016VU9jd0h3WURWUjBqCkJCZ3dGb0FVN210SlBIby9EZU94Q2JlS3lLc1puM016VU9jd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUMKQVlZd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDVVkxSkdQRSs2UEhoMFJVOW90UkNrWm9CNXJNWjVORHA2dFBWeEJiNVVySktGNQptRG80TnZ1N1pwNUkvNUNRN3ozVXVKdTBoM1UvSUp2T2NzK2hWY0ZOWktJWkJxRUhNd3dMS2VYeDZxdWo3TFVLZEpESGZYTHkxMXlmCmtlK1JpN2ZjN1dhaXo0NW1PN3lmT2dMZ0o5MFdtTUNWMUFxazVJR2FkWlExbkpCZmlEY0dyVm1WQ3JEUlo5TVp5b25uTWxvMkhENkMKcUZxVHZzYlFaSkcyejltMkdNL2JmdEpsbzZiRWpoY3h3ZnQrZHR2VGhlTllzbmQ2ZGp0c0wxQWM1OXYyWjNrZjlZS1ZtZ2VuRksrUAozQ2doWnduUzFrMWFIQmtjam5kY3c1UWtQVEpyUzM3VWVKU0R2amROemwvSEhrNDg0SWt6bFFzUHBUTFdQRnA1TEJrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUcnVzdENvciBSb290Q2VydCBDQS0yCj09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdMekNDQkJlZ0F3SUJBZ0lJSmFIZnlqUExXUUl3RFFZSktvWklodmNOQVFFTEJRQXdnYVF4Q3pBSkJnTlZCQVlUQWxCQk1ROHcKRFFZRFZRUUlEQVpRWVc1aGJXRXhGREFTQmdOVkJBY01DMUJoYm1GdFlTQkRhWFI1TVNRd0lnWURWUVFLREJ0VWNuVnpkRU52Y2lCVAplWE4wWlcxeklGTXVJR1JsSUZJdVRDNHhKekFsQmdOVkJBc01IbFJ5ZFhOMFEyOXlJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZjbWwwCmVURWZNQjBHQTFVRUF3d1dWSEoxYzNSRGIzSWdVbTl2ZEVObGNuUWdRMEV0TWpBZUZ3MHhOakF5TURReE1qTXlNak5hRncwek5ERXkKTXpFeE56STJNemxhTUlHa01Rc3dDUVlEVlFRR0V3SlFRVEVQTUEwR0ExVUVDQXdHVUdGdVlXMWhNUlF3RWdZRFZRUUhEQXRRWVc1aApiV0VnUTJsMGVURWtNQ0lHQTFVRUNnd2JWSEoxYzNSRGIzSWdVM2x6ZEdWdGN5QlRMaUJrWlNCU0xrd3VNU2N3SlFZRFZRUUxEQjVVCmNuVnpkRU52Y2lCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcGRIa3hIekFkQmdOVkJBTU1GbFJ5ZFhOMFEyOXlJRkp2YjNSRFpYSjAKSUVOQkxUSXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDbklHN0NLcUppSkpXUWRzZzRmb0RTcThHYgpaUVdVOU1FS0VOVUNyTzJmazhlSHlMQW5LMElNUFFvK1FWcWVkZDJOeXVDYjdHZ3lwR21TYUl3TGdRNVdvRDRhM1N3bEZJSXZsOU5rClJ2UlVxZHc2VkMweEs1bUM4dGtxMSs5eEFMZ3hwTDU2SkFmRFFpRHlpdFNTQkJ0bFZreHMxUHUyWVZwSEk3VFlhYlMzT3RCMFBBeDEKb1l4T2RxSHAyeXFsTy9yT3NQOSthaWo5Snh6SXNla3A4VmR1WkxUUXdSVnREcjR1RGtiSVh2UlIvdThPWXpvN2NiclBiMW5LRE9PYgpYVW00VE9KWHNaaUtRbGVjZHUvdnZkRm9xTkwwQ2J0M05iNGxnZ2pFRml4RUlGYXBSQkYzNzEyMEhhcGVhejZMTXZZSEwxY0Vrc3IxCi9wM0M2ZWl6amt4TEFqSFo1RHhJZ2lmM0dJSjJTRHB4c1JPaE9kVXV4VFRDSFdLRjN3UCtUZlN2UGQ5Y1c0MzZjT0dsZmlmSGhpNXEKanhMR2hGNURVVkNjR1p0NDV2ejI3VWQrZXoxbTd4TVRpRjg4b1dQNytheUhOWi96Z3A2a1B3cWNNV21MbWFTSVNvNXVaazN2RnNRUAplU2doWUEyRkZuM1hWRGp4a2xiOXRUTk1nOXpYRUo5TC9jYjRRcjI2ZkhNQzRQOTl6VnZoMUt4aGUxZlZTbnRiMUlWWUoxMi8rQ3RnCnJLQW1yaFFoSjhaM21qT0FQRjVHUC9mRHNhT0dNOGJvWGcyNU5TeXFSc0dGQW5XQW9Pc2sreFdxNUdkL2JuYy85QVNLTDN4NzR4ZGgKOE4wSnFTREl2Z21rMEg1RXc3SXdTamlxcWV3WW1nZUNLOXU0bkJpdDJ1QkdGNnpQWFFJREFRQUJvMk13WVRBZEJnTlZIUTRFRmdRVQoyZjRoUUc2VW5yeWJQWng5bUNBWjVZd3dZckl3SHdZRFZSMGpCQmd3Rm9BVTJmNGhRRzZVbnJ5YlBaeDltQ0FaNVl3d1lySXdEd1lEClZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FZWXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBSjVGbmd3N3R1L2gKT3NoODBRQTl6K0xxQnJXeU9yc0dTMmg2MENPWGRLY3M4QWpZZVZyWFdvU0syQkthRzlsOVhFMXd4YVg1cStXamlZbmRBZnJzM2ZucAprcGZic0VaQzg5TmlxcFgrTVdjVWFWaVFDcW9MN2pjangxQlJ0UFYrbnVONzkrVE1Rakl0U1F6TC8wa01teDQwL1c1dWxvcDVBN1p2CjJ3bkwvVjlsRkRmaE9QWHpZUlpZNUxWdERRc0VHejlRTFgrengzb2FGb0JnK0lvZjZSc3F4dm02QVJwcHY5Sll4MVJYQ0kvaE9XQjMKUzZ4WmhCcUk4ZDNMVDNqWDUrRXpMZnp1UWZvZ3NMN0w5emlVd09IUWhRKzc3U3h6cSszK2tuWWFaSDliRFRNSkJ6TjdCajhScEZ4dwpQSVhBeitPUXFJTjMrdHZteFl4b1p4Qm5wVkl0OE1TWmozKy8wV3ZpdFVmVzJkQ0ZtVTJVbXc5TGplNEFXa2NkRVFPc1FSaXZoN2R2CkREcVB5cy9jQThHaUNjamwvWUJleUdCQ0FSc2FVMXE3TjZhM3ZMcUU2UjVzR3RSazJ0UkQvcE9MUy9Jc2VSWVExSk1MaUkraDJJWVUKUnBGSG15Z2s3MWRTVGx4Q25LcjNTZXduNkVBZXM2YUpJbktjOVEwenRGaWpNRHZkMUdwVWs3NGFUZk9UbFBmOGhBcy9oQ0JjTkFORQp4ZHF0dkFyQkFzOGU1WlRaODQ1YjJFenduZXhoRjdzVU1sUU1BaW1USHBLRzluL3Y1NUlGRGxuZG1RZ3VMdnFjQUZMVHhXWXA1S2VYClJLUU9LSUVUTmNYMmIyVG1RY1RWTDh3MFJTWFBRUUNXUFVvdXdwYVlUMDVLbkplMzJ4K1NNc2ovRDFGdTF1d0oKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3RDb3IgRUNBLTEKPT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJRENDQXdpZ0F3SUJBZ0lKQUlTQ0xGOGNZdEJBTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdjTVFzd0NRWURWUVFHRXdKUVFURVAKTUEwR0ExVUVDQXdHVUdGdVlXMWhNUlF3RWdZRFZRUUhEQXRRWVc1aGJXRWdRMmwwZVRFa01DSUdBMVVFQ2d3YlZISjFjM1JEYjNJZwpVM2x6ZEdWdGN5QlRMaUJrWlNCU0xrd3VNU2N3SlFZRFZRUUxEQjVVY25WemRFTnZjaUJEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwCmRIa3hGekFWQmdOVkJBTU1EbFJ5ZFhOMFEyOXlJRVZEUVMweE1CNFhEVEUyTURJd05ERXlNekl6TTFvWERUSTVNVEl6TVRFM01qZ3cKTjFvd2dad3hDekFKQmdOVkJBWVRBbEJCTVE4d0RRWURWUVFJREFaUVlXNWhiV0V4RkRBU0JnTlZCQWNNQzFCaGJtRnRZU0JEYVhSNQpNU1F3SWdZRFZRUUtEQnRVY25WemRFTnZjaUJUZVhOMFpXMXpJRk11SUdSbElGSXVUQzR4SnpBbEJnTlZCQXNNSGxSeWRYTjBRMjl5CklFTmxjblJwWm1sallYUmxJRUYxZEdodmNtbDBlVEVYTUJVR0ExVUVBd3dPVkhKMWMzUkRiM0lnUlVOQkxURXdnZ0VpTUEwR0NTcUcKU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFBqK0FSdForb2RuYmIzdzlVNzNOaktZS3RSOGFqYSszK1h6UDRRMUhwR2pPUgpNUmVnZE1UVXB3SG1zcEkrYXAzdER2bDBtRURUUHdPQUJvSkE2TEhpcDFHbkhZTW1hNnZlK2hlUks5akdyQjZ4bmhrQjFaZW02ZzIzCnhGVWZKM3pTQ05WMkh5a1ZoMEE1M1RoRkVYWFFtcWMwNEwvTnlGSWR1VWQrRGJpN3hnejJjMWNXV241RGtSOVZPc1p0UkFTcW5LbWMKcDB5SkY0T3Vvd1JlVW9DTEhoSWxFUm5YREgxOU1VUkI2dHV2c0J6dmdkQXN4Wm9obXozdFFqdFFKdkxzem5GaEJtSWhWRTUvd1owKwpmeUNNZ01zcTJKZGl5SU16a1gyd29sb1BWK2c3elBJbHN0UjhMK3hOeHFFNkZYcm50bDAxOWZaSVNqWkZadFM2bUZqQkFnTUJBQUdqCll6QmhNQjBHQTFVZERnUVdCQlJFbmtqMXpHMUkxS0JMZi81WkpDK0RsNW1haGpBZkJnTlZIU01FR0RBV2dCUkVua2oxekcxSTFLQkwKZi81WkpDK0RsNW1haGpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJoakFOQmdrcWhraUc5dzBCQVFzRgpBQU9DQVFFQUJUNDFYQlZ3bThuSGMyRnZjaXZVd28veVExMEN6c1NVdVpRUmcyZGQ0bWRzZFhhL3V3eXFOc2F0UjVOajNCNSsxdDR1Ci91a1pNamdEZnhUMkFITXNXYkVoQnVIN3JCaVZES1AvbVpiM0t5ZWIxU1RNSGQzQk91Q1lSTERFNUQ1M3NYT3BaQ3oySEFGOFAxMUYKaGNDRjV5V1BsZHdYOHp5ZkdtNnd5dU1kS3VsTVkvb2tZV0xXMm42MkhHejFBaDNVS3QxVmtPc3FFVWM4TGw1MHNvSWlwWDFUSDBYcwpKNUY5NXlJVzZNQm9OdGpHOFUrQVJETDU0ZEhSSGFyZXFLdWNCSyt0SUE1a21FMmxhOEJJV0pacFRkd0hqRkdUb3QrZkR6MkxZTFNDCmphb0lUbUpGNFBrTDB1RGdQRnZlWEhFbkpjTG1BNEdMRUZQangxV2l0Si9YNWc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTU0wuY29tIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYzVENDQThXZ0F3SUJBZ0lJZXl5YjB4YUFNcGt3RFFZSktvWklodmNOQVFFTEJRQXdmREVMTUFrR0ExVUVCaE1DVlZNeERqQU0KQmdOVkJBZ01CVlJsZUdGek1SQXdEZ1lEVlFRSERBZEliM1Z6ZEc5dU1SZ3dGZ1lEVlFRS0RBOVRVMHdnUTI5eWNHOXlZWFJwYjI0eApNVEF2QmdOVkJBTU1LRk5UVEM1amIyMGdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0JTVTBFd0hoY05NVFl3Ck1qRXlNVGN6T1RNNVdoY05OREV3TWpFeU1UY3pPVE01V2pCOE1Rc3dDUVlEVlFRR0V3SlZVekVPTUF3R0ExVUVDQXdGVkdWNFlYTXgKRURBT0JnTlZCQWNNQjBodmRYTjBiMjR4R0RBV0JnTlZCQW9NRDFOVFRDQkRiM0p3YjNKaGRHbHZiakV4TUM4R0ExVUVBd3dvVTFOTQpMbU52YlNCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlGSlRRVENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnSVBBRENDQWdvQ2dnSUJBUGtQM2FNcmZjdlFLdjdzWjRXbTV5NGJ1bmZoNC9XdnBPejZTbDJSeEZkSGF4aDNhM2J5L1pQa1BRL0MKRnA0TFpzTldsSjRYZzRYT1Z1L3lGdjBBWXZVaUNWVG9aUmRPUWJuZ1QwYVhxaHZJdUc1aVhtbXhYOXNxQW43OGJNcnpRZGp0ME9qOApQMkZJN2JBREZCMFFEa3NaNEx0TzdJWmwvemJ6WG1jQ0M1MkdWV0g5ZWpqdC91SVpBTGR2b1ZCaWRYUThvUHJJSlpLMGJub2l4L2dlCm9lT3kzWkV4cXlzZEJQK2xTZ1EzNllXa015djk0dFpWTkh3WnBFcG94N0tvMDdmS29aT0k2OEdYdkl6NUhka2loQ1IweHdROWFxa3AKazh6cnVGdmgvbDhscWpSWXlNRWpWSjBibUJIRE9KeCtQWVpzcFE5QWhud0M5RndDVHlqTHJuR2ZEenJJTS80UkpUWHEvTHJGWUQzWgpmQmpWc3FuVGRYZ0RjaUxLT3NNZjd5emxMcW42bml5MlVVYjlyd1BXNm1CbzZvVVdObXVGNlI3QXM5M0VKTnlBS29GQmJaUSt5T0RKCmdVRUFubDYvZjhVSW1LSVlMRUpBcy9sdk9DZExUb0QwUFlGSDRJaDg2aHpPdFhWY1VTNGNLMzhhY2lqbkFMWFJkTWJYNUordEI1TzIKVXpVMS9EZmt3L1pkRnI0aGM5NlNDdmlnWTJxOGxwSnFQdmk4WlZXYjN2VU5pU1lFL0NVYXBpVnB5OEp0eW56aVdWK1hyT3Z2THNpOAoxeHRaUEN2TThobklrMnNuWXhuUC9Pa20rTXB4bTMrVC9qUm5oRTZaNi95emVBa3pjTHBtcG5idEczUHJHcVVOeENJVElKUldDazRzCmJFNngvYytjQ2JxaU0rMkhBZ01CQUFHall6QmhNQjBHQTFVZERnUVdCQlRkQkFrSG92VjZmVkpURXBLVjdqaUFKUTJtV1RBUEJnTlYKSFJNQkFmOEVCVEFEQVFIL01COEdBMVVkSXdRWU1CYUFGTjBFQ1FlaTlYcDlVbE1Ta3BYdU9JQWxEYVpaTUE0R0ExVWREd0VCL3dRRQpBd0lCaGpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQUlCZ1JsQ243SnAwY0hoNXdZZkdWY3BOeEpLMW9rMWlPTXE4YnMzQUQvQ1VyCmRJV1FQWGhxOUxtTHBaYzd0UmlSdXg2bitVQmJrZmxWbWE4ZUVkQmNIYWRtNDdHVUJ3d3lPYWJxRzdCNTJCMmNjRVRqaXQzRStaVWYKaWpoRFB3R0ZwVWVuUFVheXZPVWlhUGQ3bk5nc1Bnb2h5QzB6ckwvRmdaa3hkTUYxY2NXK3NmQWpSZlNkYS93Wlk1Mmp2QVRHR0FzbAp1MU9KRDdPQVVONUY3a1IvcTVSNFpKalQ5aWpkaDlod1pYVDdEcmtUNjZjUFlha3lsc3pldSsxalRCaTdxVUQzb0ZSdUlJaHhkUmpxCmVyUTBjdUFqSjNkY3RwRHFoaVZBcSs4ekQ4dWZncjZpSVB2MnRTMGE1c0tGc1hRUCs4aGxBcVJTQVVmZFNTTEJ2OWpyYTZ4KzN1eGoKTXhXM0l3aVB4ZytOUVZyZGpzVzVqK1ZGUDNqYnV0SWJRTEgrY1UwLzRJR2l1bDYwN0JYZ2s5MElIMzdoVlprTElkNlRuZ3I3NXFOSgp2VFl3L3VkM3NxQjFsN1V0Z1lnWFpTRDMycEFBbjhsU3pETEtOWHoxUFEvWUs5ZjFKbXpKQmpTV0Z1cHdXUm95ZVhrTHRvaC9EMUpJClBiOXMyS0pFTHRGT3QzSlkwNGtUbGY1RXEvalhpeHR1bkx3c29GdlZhZ0N2WHpmaDFmb1FDNWljaHVjbWo4N3c3RzZLVnd1QTQwNnkKd0tCallaQzZWV2czZEdxMmt0dWZvWVlpdG1VbkR1eTJuMEpnNUdmQ3RkcEJDOFRUaTJFYnZQb2ZrU3ZYUkFkZXVpbXMyY1hwNzFOSQpXdXVBOFNoWUljMndCbFg3Sno5VGtIQ3BCQjVYSjdrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpTU0wuY29tIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRUNDCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqVENDQWhTZ0F3SUJBZ0lJZGViZnk4Rm9XNmd3Q2dZSUtvWkl6ajBFQXdJd2ZERUxNQWtHQTFVRUJoTUNWVk14RGpBTUJnTlYKQkFnTUJWUmxlR0Z6TVJBd0RnWURWUVFIREFkSWIzVnpkRzl1TVJnd0ZnWURWUVFLREE5VFUwd2dRMjl5Y0c5eVlYUnBiMjR4TVRBdgpCZ05WQkFNTUtGTlRUQzVqYjIwZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQkZRME13SGhjTk1UWXdNakV5Ck1UZ3hOREF6V2hjTk5ERXdNakV5TVRneE5EQXpXakI4TVFzd0NRWURWUVFHRXdKVlV6RU9NQXdHQTFVRUNBd0ZWR1Y0WVhNeEVEQU8KQmdOVkJBY01CMGh2ZFhOMGIyNHhHREFXQmdOVkJBb01EMU5UVENCRGIzSndiM0poZEdsdmJqRXhNQzhHQTFVRUF3d29VMU5NTG1OdgpiU0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1SUVWRFF6QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBCkJFVnVxVkRFcGlNMm5sOG9qUmZMbGlKa1A5eDZqaDNNQ0xPaWNTUzZqa201QkJ0SGxsaXJMWlhJN1o0SU5jZ242NG1NVTFqcllvcisKOEZzUGF6RlNZMEU3aWMzczdMYU5HZE0wQjl5N3hnWi93a1dWN010L3FDUGdDZW1CK3ZOSDA2TmpNR0V3SFFZRFZSME9CQllFRklMUgpoWE13NXpVRTA0NENrdnZscE5IRUllak5NQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdId1lEVlIwakJCZ3dGb0FVZ3RHRmN6RG5OUVRUCmpnS1MrK1drMGNRaDZNMHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01Bb0dDQ3FHU000OUJBTUNBMmNBTUdRQ01HL242MWtScEdEUFliQ1cKZSswRitTOFRrZHp0NWZ4UWF4RkdSck1jSVFCaXU3N0Q1K2pOQjVuNURRdGRjajdFcWdJd0g3eTZDK0l3SlB0OGJZQlZDcGsrZ0Ewego1V2FqczZPN3BkV0xqd2tzcGwxKzR2QUhDR2h0MG54cGJsL2Y1V3BsCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClNTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EgUjIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRjZ6Q0NBOU9nQXdJQkFnSUlWcllwelRTOGVQWXdEUVlKS29aSWh2Y05BUUVMQlFBd2dZSXhDekFKQmdOVkJBWVRBbFZUTVE0dwpEQVlEVlFRSURBVlVaWGhoY3pFUU1BNEdBMVVFQnd3SFNHOTFjM1J2YmpFWU1CWUdBMVVFQ2d3UFUxTk1JRU52Y25CdmNtRjBhVzl1Ck1UY3dOUVlEVlFRRERDNVRVMHd1WTI5dElFVldJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGtnVWxOQklGSXkKTUI0WERURTNNRFV6TVRFNE1UUXpOMW9YRFRReU1EVXpNREU0TVRRek4xb3dnWUl4Q3pBSkJnTlZCQVlUQWxWVE1RNHdEQVlEVlFRSQpEQVZVWlhoaGN6RVFNQTRHQTFVRUJ3d0hTRzkxYzNSdmJqRVlNQllHQTFVRUNnd1BVMU5NSUVOdmNuQnZjbUYwYVc5dU1UY3dOUVlEClZRUUREQzVUVTB3dVkyOXRJRVZXSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrZ1VsTkJJRkl5TUlJQ0lqQU4KQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBanpabFFPSFdUY0RYdE9sRzJtdnFNMGZOVFBsOWZiNjlMVDN3MjNqaApocVhadWdsWGFPMVhQcURRQ0VHRDV5aEJKQi9qY2hYUUFScjdYbkFqc3N1Zk9lUFB4VTdHa20wbXhudTdzOW9ublFxRzZZRTNCZjd3CmNYSHN3eHpwWTZJWEZKM3ZHMmZUaFZVQ0F0Wkp5Y3hhNGJIM2J6S2Z5ZFE3aUVHb25MM0xxOXR0ZXdrZm9reHlrTm9yQ1B6UFBGVE8KWncrb3oxMldHUXZFNDNMcnJkRjlIU2Z2a3VzUXYxdnJPNi9QZ04zQjBwWUVXM3ArcEtrOE9IYWtZbzZnT1Y3cWQ4OWRBRm1QWml3KwpCNktqQlNZUmFaZnFoYmNQbGd0THlFRGhVTG91aXN2M0Q1b2k1MythTnhQTjhrMFRheUhSd013aThxRkc5a1Jwbk1waE5RY0FiOVpoCkNCSHF1cmoyNmJOZzVVMjU3SjhVWnNsWFdOdk5oMm40aW9ZU0EwZS9aaE4yckhkOU5DU0ZnODNYcXB5UUdwOGhMSDk0dDJTNDJPaW0KOUhpelZjdUUwakxFZUs2amoySGR6Z2hUcmV5SS9CWGttZzNtbnhwM3preVB1QlFWUFdLY2hqZ0dBR1lTNUZsMldsUEFBcGlpRUN0bwpSSHVPZWM0elNuYXFXNEVXRzdXSzJOQUFlMTVpdEFuV2htTU9wZ1dWU2Jvb2k0aVRzalFjMktSVmJyY2MwTjZaVlRzajlDTGcrU2xtCkp1d2dVSGZiU2d1UHZ1VUNZSEJCWHRTdVVEa2lGQ2JMc2p0emRGVkhCM21CT2Fnd0UwVGxCSXF1bGhNbFFnKzVVOFNiL00za0hONDgKK3F2V0Jrb2ZaNmFZTUJ6ZExOdmNHSlZYWnNiL1hJdFc5WGNDQXdFQUFhTmpNR0V3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFmQmdOVgpIU01FR0RBV2dCVDVZTHZVNDlVMDlyajFCb0FscDNQYlJtbW9uakFkQmdOVkhRNEVGZ1FVK1dDNzFPUFZOUGE0OVFhQUphZHoyMFpwCnFKNHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQldzNDdMQ3AxSmpyK2t4Skc3WmhjRlVaaDEKKytWUUxIcWU4UlQ2cTlPS1B2K1JLWTlqaTlpMHFWUUJEYjZUaGkvNVNtM0hYdlZYK2NwVkhCSytSdzgyeGQ5cXQ5dDF3a2NsZjdueApZL2hvTFZVRTBmS05zS1RQdkR4ZUgzam5wYUFnY0xBRXhiZjNjcWZlSWcyOU15VkdqR1NTSnVNK0xtT1cycHVNUGZnWUNkY0R6SDJHCmd1REtCQWRSVU5mL2t0VU03OXFHbjVuWDY3ZXZhT0k1SnBTNmFMZS9nOVBxZW1jOVltZXVKZVZ5Nk9MazdLNFM5a3NyUEovcHNFRHoKT0ZTei9iZG95TnJHajFFOHN2dVIzQnpubTUzaHR3MXlqK0treEtsNCtlc1VyTVpEQmNKbE9TZ1lBc09Dc3AwRnZtWHRsbDlsZER6NwpDVFV1ZTV3VC9Sc1BYY2R0Z1RwV0Q4dzc0YThDTHlLc1JzcEdQS0FjVE5aRXRGNHVYQlZtQ2VFbUtmN0dVbUc2c1hQL3d3eWM1V3hxCmxEOFV5a0FXbFlUeldhbXNYMHhoazIzUk84eWlsUXdpcG1kblJDNjUyZEtLUWJObUMxcjdmU09sOGhxdy85NmJnNVF1MFQvZmtyZVIKcndVN1pjZWdiTEhOWWhMRGtCdmpKYzQwdkc5M2RyRVF3L2NGR3NEV3IzUmlTQmQza21tUVlSemVsWUIwVkk4WUhNUHpBOUMvcEVOMQpobE1ZZWdvdUNSdzJuNUg5Z29vaVM5RU9VQ1hkeXdNTUY4bURBQWhPTlUyS2krM3dBcFJtTEVSL3k1VW5saGV0Q1RDc3RuRVhib3NYCjlod0oxQzA3bUtWeDAxUVQyV0R6OVV0bVQvcng3aUFTamJTc1Y3RkZZNkdzZHFuQyt3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKU1NMLmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDbERDQ0FocWdBd0lCQWdJSUxDbWNXeGJ0QlpVd0NnWUlLb1pJemowRUF3SXdmekVMTUFrR0ExVUVCaE1DVlZNeERqQU1CZ05WCkJBZ01CVlJsZUdGek1SQXdEZ1lEVlFRSERBZEliM1Z6ZEc5dU1SZ3dGZ1lEVlFRS0RBOVRVMHdnUTI5eWNHOXlZWFJwYjI0eE5EQXkKQmdOVkJBTU1LMU5UVEM1amIyMGdSVllnVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNCRlEwTXdIaGNOTVRZdwpNakV5TVRneE5USXpXaGNOTkRFd01qRXlNVGd4TlRJeldqQi9NUXN3Q1FZRFZRUUdFd0pWVXpFT01Bd0dBMVVFQ0F3RlZHVjRZWE14CkVEQU9CZ05WQkFjTUIwaHZkWE4wYjI0eEdEQVdCZ05WQkFvTUQxTlRUQ0JEYjNKd2IzSmhkR2x2YmpFME1ESUdBMVVFQXd3clUxTk0KTG1OdmJTQkZWaUJTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1SUVWRFF6QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QgpCQUFpQTJJQUJLb1NSNUNZRy92dncwQUhneUJPOFRDQ29nYlI4cEtHWWZMMklXaktBTVRINmtNQVZJYmMvUi9mQUxoQllsemNjQll5CjNoK1oxTXpGQjhnSUgyRVdCMUU5ZlZ3SFUrTTFPSXpmelovWkxnMUt0aGt1V25CYUJ1Mis4S0d3eXRBSkthTmpNR0V3SFFZRFZSME8KQkJZRUZGdktYdVhlMG9HcXphZ3RaRkcyMlhLYmwrWlBNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdId1lEVlIwakJCZ3dGb0FVVzhwZQo1ZDdTZ2FyTnFDMWtVYmJaY3B1WDVrOHdEZ1lEVlIwUEFRSC9CQVFEQWdHR01Bb0dDQ3FHU000OUJBTUNBMmdBTUdVQ01RQ0s1a0NKCk4rdnAxUlBaeXRSckpQT3dQWWRHV0Jyc3NkOXYrMWE2Y0d2SE9Nem9zWXhQRC9meFozWU9nOUFlVVk4Q01EMzJJeWdtVE1aZ2g1TW0KbTdJMUhyclc5enpSSE03NkpUeW1Hb0VWVy9NU0QyenVaWXJKaDZqNUIrQmltb3hjU2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNgo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRmd6Q0NBMnVnQXdJQkFnSU9SZWE3QTRNenc0VmxTT2IvUlZFd0RRWUpLb1pJaHZjTkFRRU1CUUF3VERFZ01CNEdBMVVFQ3hNWApSMnh2WW1Gc1UybG5iaUJTYjI5MElFTkJJQzBnVWpZeEV6QVJCZ05WQkFvVENrZHNiMkpoYkZOcFoyNHhFekFSQmdOVkJBTVRDa2RzCmIySmhiRk5wWjI0d0hoY05NVFF4TWpFd01EQXdNREF3V2hjTk16UXhNakV3TURBd01EQXdXakJNTVNBd0hnWURWUVFMRXhkSGJHOWkKWVd4VGFXZHVJRkp2YjNRZ1EwRWdMU0JTTmpFVE1CRUdBMVVFQ2hNS1IyeHZZbUZzVTJsbmJqRVRNQkVHQTFVRUF4TUtSMnh2WW1GcwpVMmxuYmpDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBSlVINkhQS1p2bnNGTXA3UFBjTkNQRzBSUXNzCmdyUkl4dXRiUEs2RHVFR1NNeFNrYjMvcEtzekdzSWhyeGJhSjBjYXkveFRPVVJRaDdFcmRHMXJHMW9mdVRUb1ZCdTFrWmd1U2dNcEUKM25PVVR2T25pWDlQZUdNSXlCSlFiVUptTDAyNWVTaE5VaHFLR29DM0dZRU9mc1NLdkdSTUlSeERhTmM5UElyRnNtYlZrSnEzTVFiRgp2dUp0TWdhbUh2bTU2NnFqdUwrK2dtTlEwUEFZaWQva0QzbjE2cUlmS3RKd0xudm52Sk83YlZQaVNIeU1FQWM0LzJheWQyRis0T3FNClBLcTBwUGJ6bFVvU0IyMzlqTEtKejlDZ1lYZklXSFN3MUNNNjkxMDZ5cUxiblFuZVhVUXRrUEdCelZlUytuNjhVQVJqTk45cmt4aSsKYXpheU9lU3NKRGEzOE8rMkhCTlhrN2Jlc3ZqaWhiZHpvcmcxcWtYeTRKMDJvVzlVaXZGeVZtNHVpTVZSUWtRVmxPNmp4VGlXbTA1TwpXZ3RIOHdZMlNYY3d2SEUzNWFic0lRaDEvT1poRmo5MzFkbVJsNFFLYk5RQ1RYVEFGTzM5T2Z1RDhsNFVvUVN3QytuKzdvL2hiZ3V5CkNMTmhaZ2xxc1FZNlpaWlp3UEExL2NuYUtJMGFFWWR3Z1Fxb21uVWRuanFHQlFDZTI0RFdKZm5jQlo0bldVeDJPVnZxK2FXaDJJTVAKMGYvZk1CSDVoYzh6U1BYS2JXUVVMSHBZVDlOTENFbkZsV1FhWXc1NVBmV3pqTXBZclp4Q1JYbHVEb2NaWEZTeFpiYS9qSnZjRStrTgpiN2d1M0dkdXlZc1J0WVFVaWdBWmNJTjVrWmVSMUJvbnZ6Y2VNZ2ZZRkdNOEtFeXZBZ01CQUFHall6QmhNQTRHQTFVZER3RUIvd1FFCkF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlN1YkFXamt4UGlvdWZpMXh6V3gvQi95R2RUb0RBZkJnTlYKSFNNRUdEQVdnQlN1YkFXamt4UGlvdWZpMXh6V3gvQi95R2RUb0RBTkJna3Foa2lHOXcwQkFRd0ZBQU9DQWdFQWd5WHQ2Tkg5bFZMTgpuc0FFb0pGcDVselFoTjdjcmFKUDZFZDQxbVdZcVZ1b1BJZDhBb3JSYnJjV2MrWmZ3RlNZMVhTK3djM2lFWkd0SXhnOTNlRnlSSmEwCmxWN0FlNDZaZUJaREUxWlhzNkt6TzdWMzNFQnlyS1BybXpVK3NRZ2hvZWZFUXpkNU1yNjE1NXdzVEx4REtabU9NTk9zSWVEakhmclkKQnpOMlZBQWlLcmxOSUM1d2FOcmxVL3lEWE5PZDh2OUVERVJtOHRManZVWUFHbTBDdWlWZGphRXhVZDFVUmh4TjI1bVc3eG9jQkZ5bQpGZTk0NEhuK1hkcytxa3hWL1pvVnFXL2hwdnZmY0REcHcrNUNSdTNDa3dXSituMWplei9RY1lGOEFPaVlyZzU0Tk1NbCs2OEtueUJyCjNUc1RqeEtNNGtFYVNIcHpvSGRweDdaY2Y0TElIdjVZR3lncnFHeXRYbTNBQmRKN3QrdUEvaVUzL2dLYmFLeENYY1B1OWN6YzhGQjEKMGpacG5PWjdCTjl1Qm1tMjNnb0pTRm1INjNzVVlIcGtxbWxENzVISFRPd1kzV3p2VXkyTW1lRmU4bkkrejFUSXZXZnNwQTlNUmYvVAp1VEFqQjB5UEVMK0dsdG1aV3JTWlZ4eWt6THNWaVZPNkxBVVA1TVNlR2JFWU5OVk1uYnJ0OXgrdkpKVUVlS2dEdSs2QjVkcGZmSXRLCm9aQjBKYWV6UGt2SUxGYTl4OGp2T09KY2t2QjU5NXlFdW5RdFlRRWdmbjdSOGs4SFdWK0xMVU5TNjBZTWxPSDFaa2Q1ZDlWVVd4K3QKSkRmTFJWcE9vRVJJeU5pd21jVVZoQW4yMWtsSndHVzQ1aHB4YnFDbzhZTG9SVDVzMWdMWENtZURCVnJKcEJBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpPSVNURSBXSVNlS2V5IEdsb2JhbCBSb290IEdDIENBCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNhVENDQWUrZ0F3SUJBZ0lRSVNwV0RLN2FES3RBUmI4cm9pMDY2akFLQmdncWhrak9QUVFEQXpCdE1Rc3dDUVlEVlFRR0V3SkQKU0RFUU1BNEdBMVVFQ2hNSFYwbFRaVXRsZVRFaU1DQUdBMVVFQ3hNWlQwbFRWRVVnUm05MWJtUmhkR2x2YmlCRmJtUnZjbk5sWkRFbwpNQ1lHQTFVRUF4TWZUMGxUVkVVZ1YwbFRaVXRsZVNCSGJHOWlZV3dnVW05dmRDQkhReUJEUVRBZUZ3MHhOekExTURrd09UUTRNelJhCkZ3MDBNakExTURrd09UVTRNek5hTUcweEN6QUpCZ05WQkFZVEFrTklNUkF3RGdZRFZRUUtFd2RYU1ZObFMyVjVNU0l3SUFZRFZRUUwKRXhsUFNWTlVSU0JHYjNWdVpHRjBhVzl1SUVWdVpHOXljMlZrTVNnd0pnWURWUVFERXg5UFNWTlVSU0JYU1ZObFMyVjVJRWRzYjJKaApiQ0JTYjI5MElFZERJRU5CTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVUT2xRd01ZUGNoaTgyUEc2czRuaWVVcWpGcWRyClZDVGJVZi9xOUFra3d3c2luOHRxSjRLQkRkTEFyekhrZElKdXlpWFpqSFdkOGR2UW1xSkxJWDRXcDJPUTBqblVzWWQ0WHhpV0QxQWIKTlRjUGFzYmMyUk5OcEk2UU4rYTlXekdSbzFRd1VqQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZApCZ05WSFE0RUZnUVVTSWNVck9QRG5wQmdPdGZLaWU3VHJZeTBVR1l3RUFZSkt3WUJCQUdDTnhVQkJBTUNBUUF3Q2dZSUtvWkl6ajBFCkF3TURhQUF3WlFJd0pzZHBXOXpWNTdMbnlBeU1qTVBkZVl3Ylk5WEpVcFJPVFlKS2N4NnlnSVNwSmNCTVdtMUpLV0I0RStKK1NPdGsKQWpFQTJ6UWdNZ2ovbWtrQ3RvamVGSzlkYkpseGpSby9pOWZnb2phR0hBZUNPblpUL2NLaTdlOTdzSUJQV0E5TFV6bTkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR1RTIFJvb3QgUjEKPT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZXakNDQTBLZ0F3SUJBZ0lRYmtlcHhVdEhEQTNzTTlDSnVSejA0VEFOQmdrcWhraUc5dzBCQVF3RkFEQkhNUXN3Q1FZRFZRUUcKRXdKVlV6RWlNQ0FHQTFVRUNoTVpSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6SUV4TVF6RVVNQklHQTFVRUF4TUxSMVJUSUZKdgpiM1FnVWpFd0hoY05NVFl3TmpJeU1EQXdNREF3V2hjTk16WXdOakl5TURBd01EQXdXakJITVFzd0NRWURWUVFHRXdKVlV6RWlNQ0FHCkExVUVDaE1aUjI5dloyeGxJRlJ5ZFhOMElGTmxjblpwWTJWeklFeE1RekVVTUJJR0ExVUVBeE1MUjFSVElGSnZiM1FnVWpFd2dnSWkKTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDMkVRS0xIdU9oZDVzNzNMK1VQcmVWcDBBOG9mMkMrWDB5Qm9KeAo5dmFNZi92bzI3eHFMcGVYbzR4TCtTdjJzZm5PaEIyeCtjV1gzdSs1OHFQcHZCS0pYcWVxVXF2NEl5ZkxwTEdjWTl2WG1YN3dDbDdyCmFLYjB4bHBIRFUwUU0rTk9zUk9qeUJoc1MrejhDWkRmbldRcEpTTUhvYlRTUFM1ZzRNL1NDWWU3elVqd1RjTENlb2lLdTdyUFdSblcKcjQrd0I3Q2VNZkdDd2NEZkxxWnRiQmtPdGRoK0pocEZBejJ3ZWFTVUtLMFBmeWJscUFqK2x1ZzhhSlJUN29NNmlDc1ZsZ215NEhxTQpMblhXbk91blZtU1BsazlvcmoyWHdvU1B3THhBd0F0Y3ZmYUhzelZzckJoUWY0VGdUTTJTMHlEcE03eFNtYTh5dFNtekpTcTBTUGx5CjRjcGs5K2FDRUkzb25jS0tpUG80Wm9yOFkva0IrWGo5ZTF4MytuYUgrdXpmc1E1NWxWZTB2U2J2MWdIUjZ4WUt1NDRMdGNYRmlsV3IKMDZ6cWtVc3B6Qm1rTWlWT0t2RmxSTkFDenFyT1NiVHFuM3lEc0VCNzUwT3JwMnlqajMySmdmcE1wZi9WanNQT1MrQzEyTE9PUmM5Mgp3TzFBSy8xVEQ3Q24xVHNOc1lxaUE5NHhyY3gzNm05N1B0YmZrU0lTNXI3NjJETDhFR01VVVhMZVhkWVdrNzBwYURQdk9tYnNCNG9tCjN4UFhWMlY0Sjk1ZVNSUUFvZ0IvbXFnaHRxbXhsYkNsdVEwV0VkckhiRWc4UU9CK0RWck5WanpSbHdXNXkwdnRPVXVjeEQvU1ZSTnUKSkxEV2NmcjB3YnJNN1J2MS9vRkIyQUNZUFRySXJucVlOeGdGbFFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTVLOHJKbkVhSzBnbmhTOVNaaXp2OElrVGNUNHdEUVlKS29aSWh2Y05BUUVNCkJRQURnZ0lCQURpV0N1NDl0SlllWCsrZG5Bc3pueXZneXYzU2pnb2ZRWFNsZktxRTFPWHlIdVkzVWpLY0M5RmhIYjhvd2JaRUtUVjEKZDVpeWZObTlkS3lLYU9PcE1Ra3BBV0J6NDBkOFU2aVFTaWZ2UzllZmsrZUNOczZhYUF5QzU4L1VFQlp2WHc2WlhQWWZjWDN2NzNzdgpmdW8yMXBkd0N4WHUxMXhXYWpPbDQwazRETGg5KzQyRnBMRlpYdlJxNGQyaDltUkVydVpSZ3lGbXhoRSs4ODVIN3B3b0h5WGEvNnhtCmxkMDFEMXp2SUN4aS9aRzZxY3o4V3B5VGdZTXBsMHA4V25LME9kQzNkOHQ1L1drNmtqZnRiamhsUm43cFlMMTVpSmRmT0JMMDdxOWIKZ3NpRzFlR1piWXdFOG5hNlNmWnU2VzBlWDZEdko0SjJRUGltMDFoY0R5eEMya0xHZTRnMHg4SFlSWnZCUHNWaEhkbGpVRW4yTklWcQo0QmpGYmtlclFVSXBtL1pnRGRJeDAyT1lJNU5hQUlGSXRPL05pczNKejVudTJaNnFOdUZvUzNGSkZEWW9PajBkenBxUEplYUFjV0VyCnRYdk0rU1VXZ2VFeFg2R2pmaGFrbkJacWx4aTlkbktsQzU0ZE51WXZvUysrY0pFUHFPYmErTVNTUUd3bGZudXpDZHl5RjYyQVJQQm8KcFkrVWRmOTBXdWlvQW53TUNlS3BTd3VnaFF0aXVlK2hNWkw3Ny9aUkJJbHM2S2wwb2JzWHM3WDlTUTk4UE95REdDQkRUdFdUdXJRMApzUjhXTmg4TTVtUTVGa3pjNFA0ZHlLbGlQVURxeXNVMEFyU3VpWWd6TmR3c0UzUFlKL0hRY3U1MU95TGVtR2htVy9IR1kwZFZITHFsCkNGRjFwa2dsCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCkdUUyBSb290IFIyCj09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGV2pDQ0EwS2dBd0lCQWdJUWJrZXB4bHF6NXlERk1Kby9hRkx5YnpBTkJna3Foa2lHOXcwQkFRd0ZBREJITVFzd0NRWURWUVFHCkV3SlZVekVpTUNBR0ExVUVDaE1aUjI5dloyeGxJRlJ5ZFhOMElGTmxjblpwWTJWeklFeE1RekVVTUJJR0ExVUVBeE1MUjFSVElGSnYKYjNRZ1VqSXdIaGNOTVRZd05qSXlNREF3TURBd1doY05Nell3TmpJeU1EQXdNREF3V2pCSE1Rc3dDUVlEVlFRR0V3SlZVekVpTUNBRwpBMVVFQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2YjNRZ1VqSXdnZ0lpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRRE8zdjJtKyt6c0ZEUThCd1phYkZuM0dUWGQ5OEdkVmFyVHpUdWsKazNMdkN2cHRuZmJ3aFlCYm9VaFNuem5GdCs0b3JPL0xkbWdVdWQrdEFXeVpIOFFpSFovK2NuZmdMRnV2NUFTL1QzS2dHalNZNkRsbwo3SlVsZTNhaDVtbTVoUm05aVl6K3JlMDI2bk84LzRQaXkzM0IwczVLczQwRm5vdEprOS9CVzlCdVh2QXVNQzZDL1BxOHRCY0tTT1dJCm04V2JhOTZ3eXJRRDhOcjBrTGhsWlBkY1RLM29mbVplbWRlNHdqN0kwQk9kcmU3a1JYdUpWZmVLSDJKU2hCS3p3a0NYNDRvZlI1R20KZEZyUytMRmpLQkM0c3dtNFZuZEFvaWFZZWNiKzN5WHVQdVdnZjlSaEQxRkxQRCtNMnVGd2ROakNhS0g1d1F6cG9lSi91MVU4ZGdidQphazdNa29nd1RacTlUd3RJbW9TMW1LUFYrM1BCVjJIZEtGWjFFNjZIanVjTVVRa1FkWWhNdkkzNWV6elVJa2dmS3R6cmE3dEVzY3N6CmNUSkdyNjFLOFl6b2REcXM1eG9pYzREU01QY2xRc2NpT3pzU3JaWXV4c04yQjZvZ3R6VkpWK21TU2VoMkZuSXhaeXVXZm9xang1UlcKSXI5cVMzNEJJYklqTXQva21rUnRXVnRkOVFDZ0hKdkdlSmVOa1ArYnlLcTByeEZST1Y3WisyZXQxVnNSblRLYUc3M1Z1bHVseWNzbAphVk5WSjF6Z3lqYkxpR0g3SHJmUXkrNFcrOU9tVE42U3BkVGkzL1VHVk40dW5VdTBrekNxZ2M3ZEd0eFJjdzFQY09ubHRoWWhHWG15CjVva0xkV1RLMWF1OENjRVlvZi9VVktHRlBQMFVKQU95aDlPa3R3SURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVV1Ly9LamlPZlQ1bksyK0pvcHFVVkp4Y2UyUTR3RFFZSktvWklodmNOQVFFTQpCUUFEZ2dJQkFMWnA4S1ozL3A3dUM0R3Q0Y0NweC9rMUhVQ0NxK1lFdE4vTDl4MFBnL0IrRTAyTmpPN2pNeUxET2Z4QTMyNUJTMEpUCnZoYUk4ZEk0WHNSb21SeVlVcE9NNTJqdEcycHplZ1ZBVFg5bE85Wlk4YzZEUjJEai81ZXBuR0IzR0ZXMWZnaVR6OUQyUEdjREZXRUoKK1lGNTlleFRwSi9KandHTGM4UjNkdHlEb3ZVTVNScW9kdDZTbTJUNHN5ekZKOU1Id0FpQXBKaVM0d0dXQXFvQzdvODd4ZEZ0Q2pNdwpjM2k1VDFRV3Z3c0hvYVJjNXN2SlhJU1BEK0FWZHl4K0puN2F4RXZicHhaM0I3RE5kZWh5UXRhVmhKMkdnL0xra00wSlI5U0xBM0RhCldzWURRdlR0TjZMd0cxQlVTdzdZaE40WktKbUJSNjRKR3o5STBjTnY0ckJnRi9YdUl3S2wyZ0JiYlpDcjdxTHBHenZweDBRblJZNXIKbi9Xa2hMeDMrV3VYckQ1UlJhSVJwc3lGN2dwbzhqNVFPSG9rWWg0WElEZHRhazIzQ1p2Si9LUlk5YmI3bkU0WXU1VUM1Nkd0bXdmdQpObXNrMGptR3daT0RVTktCUnFoZllsY3N1MnhraUFodTd4TlVYOTB0eEdkajA4K0pONytkSVBUN2VvT2JvQjZCQUZEQzVBd2lXVklRCjdVTldod0Q0RkZLbkhZdVRqS0pOUm44bnhuR2JKTjdrMm9hTERYNXJJTUhBbnVGbDJHcWpwdWlGaXpvSENCeTY5WTlWbWhoMWZ1WHMKZ1diUklYT2hOVVFMZ0QxYm5GNXZLaGVXMFlNamlHWnQ1b2JpY0RJdlVpTG55T2QveEN4Z1hTL0RyNTVGQmNPRUFyZjlMQWhTVDRMZApvL0RVaGdrQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpHVFMgUm9vdCBSMwo9PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ0REQ0NBWkdnQXdJQkFnSVFia2VweDJ5cGN5UkFpUThEVmQyTkhUQUtCZ2dxaGtqT1BRUURBekJITVFzd0NRWURWUVFHRXdKVgpVekVpTUNBR0ExVUVDaE1aUjI5dloyeGxJRlJ5ZFhOMElGTmxjblpwWTJWeklFeE1RekVVTUJJR0ExVUVBeE1MUjFSVElGSnZiM1FnClVqTXdIaGNOTVRZd05qSXlNREF3TURBd1doY05Nell3TmpJeU1EQXdNREF3V2pCSE1Rc3dDUVlEVlFRR0V3SlZVekVpTUNBR0ExVUUKQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2YjNRZ1VqTXdkakFRQmdjcQpoa2pPUFFJQkJnVXJnUVFBSWdOaUFBUWZUek9ITXltS29ZVGV5OGNoV0VHSjZsYWRLMHVGeGgxTUo3eC9KbEZ5YitLZjFxUEt6RVVVClJvdXQ3MzZHak95eGZpLy9xWEdkR0lSRkJFRlZiaXZxSm4rN2tBSGpTeG02NUZTV1JRbXgxV3lSUksyRUU0NmFqQTJBRERMMjRDZWoKUWpCQU1BNEdBMVVkRHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJUQjhTYTZvQzJ1aFlIUAowL0VxRXIyNENtZjl2REFLQmdncWhrak9QUVFEQXdOcEFEQm1BakVBZ0Z1a2ZDUEFsYVVzM0w2SmJ5TzVvOTFsQUZKZWthekluWEowCmdsTUxmYWxBdldoZ3hlRzRWRHZCTmhjbDJNRzlBakVBbmpXU2RJVWxVZlVrN0dSU0pGQ2xIOXZveThsMjdPeUNidldGR0ZQb3VPT2EKS2FxVzA0TWp5YVI3WWJQTUF1aGQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKR1RTIFJvb3QgUjQKPT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNDakNDQVpHZ0F3SUJBZ0lRYmtlcHlJdVV0dWk3T3lyWW9yTEJtVEFLQmdncWhrak9QUVFEQXpCSE1Rc3dDUVlEVlFRR0V3SlYKVXpFaU1DQUdBMVVFQ2hNWlIyOXZaMnhsSUZSeWRYTjBJRk5sY25acFkyVnpJRXhNUXpFVU1CSUdBMVVFQXhNTFIxUlRJRkp2YjNRZwpValF3SGhjTk1UWXdOakl5TURBd01EQXdXaGNOTXpZd05qSXlNREF3TURBd1dqQkhNUXN3Q1FZRFZRUUdFd0pWVXpFaU1DQUdBMVVFCkNoTVpSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6SUV4TVF6RVVNQklHQTFVRUF4TUxSMVJUSUZKdmIzUWdValF3ZGpBUUJnY3EKaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVR6ZEhPbmFJdGdya080TmNXQk1IdExTWjM3d1dITzV0NUd2V3ZWWVJnMXJrRGRjL2VKa1RCYQo2enp1aFh5aVFIWTdxY2E0UjlncTU1S1JhblBwc1hJNW55bWZvcGpUWDE1WWhtVVBvWVJsQnRIY2k4bkhjOGlNYWkvbHhLdlJIWXFqClFqQkFNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCU0FUTmJyZFA5Sk5xUFYKMlB5MVBzVnE4SlFkakRBS0JnZ3Foa2pPUFFRREF3Tm5BREJrQWpCcVVGSjBDTVJ3M0o1UWRDSG9qWG9odzArV2JoWFJJalZoTGZvSQpOKzRaYmEzYnNzeDlCelQxWUJrc3RUVFpieUFDTUFOeHNicWpZQXVHN1pvSWFwVm9uK0t6NFpOa2ZGNlRwdDk1TFkyRjQ1VFBJMTF4CnpQS3dUZGIrbWNpVXFYV2k0dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClVDQSBHbG9iYWwgRzIgUm9vdAo9PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZSakNDQXk2Z0F3SUJBZ0lRWGQreDJscWo3VjIrV21VZ1pRT1E3ekFOQmdrcWhraUc5dzBCQVFzRkFEQTlNUXN3Q1FZRFZRUUcKRXdKRFRqRVJNQThHQTFVRUNnd0lWVzVwVkhKMWMzUXhHekFaQmdOVkJBTU1FbFZEUVNCSGJHOWlZV3dnUnpJZ1VtOXZkREFlRncweApOakF6TVRFd01EQXdNREJhRncwME1ERXlNekV3TURBd01EQmFNRDB4Q3pBSkJnTlZCQVlUQWtOT01SRXdEd1lEVlFRS0RBaFZibWxVCmNuVnpkREViTUJrR0ExVUVBd3dTVlVOQklFZHNiMkpoYkNCSE1pQlNiMjkwTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEEKTUlJQ0NnS0NBZ0VBeGVZcmIzenZKZ1VubzRFazJtL0xBZm1abXFreXdpS0hZVUdSTzh2RGFCc0d4VXlwSzhGbkZ5SWRLKzM1S1ltVApvbmk5a211Z293Mmlmc3FUczZiUmpEWFZkZmtYOXM5RnhlVjY3SGVUb0k4anJnNGFBMysrMU5EdExudXJSaU5iL3l6bVZIcVV3Q29WCjhNbU5zSG83Sk9IWGFPSXhQQVl6UnJaVUVhYWxMeUpVS2xnTkFRTHgraFZSWjJ6QSt0ZTJHMy9SVm9ndkdqcU5PN3VDRWVCSEFOQlMKaDZ2N2huNFBKR3RBblRSbnZJM0hMWVp2ZVQ2T3FUd1hTMyt3bWVPd2NXRGNDL1Zrdzg1RHZHMXh1ZExlSjF1SzZOakdydUZaZmM4bwpMVFc0bFZZYThiSllTN2NTTjhoOHMrMUxnT0dOK2pJanRtKzNTSlVJc1VST2hZdzZBbFFnTDkrL1YwODdPcEFoMThFbU5WUWc3TWMvClIrenZXcjlMZXNHdE94ZFFYR0xZRDB0SzNDdjZicnh6a3Mzc3gxRG9RWmJYcVg1dDJPa2RqNHExdVZpU3VrcVNLd3hXL1lEckNQQmUKS1c0YkhBeXZqNU9KcmR1OW81NGh5b2taN04rMXd4cnJGdjU0Tmt6V2J0QStGeHlRRjJzbXV2dDZMNzhSSEJnT0xYTURqNkRsTmFCYQo0a3gxSFhIaE9UaFRlRURNZzVQWENwNmRXNCtLNU9YZ1NPUklza2ZOVGlwMUtudnlJdmJKdmdtUmxsZDZpSWlzN25Dcytkd3A0d3djCk94Sk9STmFuVHJBbXlQUFpHcGVSYU9ydmpVWUcwbFpGV0pvOERBK0R1QVVsd3puUE82UTBpYmQ1RWk5SHhlZXBsMm44cG5kbnRkOTcKOFhwbEZlUmhWbVVDQXdFQUFhTkNNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwTwpCQllFRklIRWpNejE1REQvcFF3SVg0d1ZaeUYwQWQvZk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQVRaU0wxaml1dFJPVEwvN2xvCjVzT0FTRDBFZS9vakwzcnROdHF5em0zMjVwN2xYMWlQeXpjeW9jaGx0cTQ0UFRVYlBydzd0Z1RRdlBsSjladjNoY1UydHN1OCtNZzUKMWVSZkI3MFZWSmQweXNydFQ3cTZaSGFmZ2JpRVJVbE1qVytpNjdITTBjT1Uya1RDNXVMcUdPaWlIeWNGdXRmbDFxbk4zZTkybUkwQQpEczBiK2dPM2pvQllEaWMvVXZ1VW9zcGVaY25XaE5xNU5YSHpKc0JQZCthQko5SjNPNW9VYjNuMDl0RGgwNVM2MEZkUnZTY0ZEY0g5CnlCSXc3bStORVNzSW5kVFV2NEJGRkpxSVJOb3c2clNuNCs3dlc0TFZQdGF0ZUpMYlhEenoySzM2dUd0L3hEWW90Z0lWaWxRc25MQVgKYzQ3UU42TVVQSmlWQUF3cEJWdWVTVW14WDhmank4OG5aWTQxRjdkWHlERFpRVnU1Rkxib3dnK1VNYWVVbU14cTY3WGhKL1VRcUFIbwpqaEppNklqTXRYOUdsOENiRUdZNEdqWkdYeUpvUGQvSnhoTW5xMU1HcktJOGhnWmxiN0Yrc1NsRW1xTzZTV2tvYVkvWDVWK3RCSVprCmJ4cWdETVVJWXM2QW85RHo3R2pldmpQSEYxdC9nTVJNVExHbWhJckRPN2dKelJTQnVoampWRmMyL3RzdmZFZWhPalBJK1ZnN1JFK3gKeWdLSkJKWW9hTVZMdUNhSnU5WXpMMURWL3BxSnVoZ3lrbFRHVytDZCtWN2xEU0tiOXRyaXlDR3lZaUdxaGtDeUxtVFRYOGpqZmhGbgpSUjhGL3VPaTc3T29zL045ai9nTUh5SWZMWEMwdUFFMGRqQUE1U040cDFiWFVCK0srd2Ixd2hudzBBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVUNBIEV4dGVuZGVkIFZhbGlkYXRpb24gUm9vdAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGV2pDQ0EwS2dBd0lCQWdJUVQ5SXJqL1ZreURPZVR6UllaaU53WURBTkJna3Foa2lHOXcwQkFRc0ZBREJITVFzd0NRWURWUVFHCkV3SkRUakVSTUE4R0ExVUVDZ3dJVlc1cFZISjFjM1F4SlRBakJnTlZCQU1NSEZWRFFTQkZlSFJsYm1SbFpDQldZV3hwWkdGMGFXOXUKSUZKdmIzUXdIaGNOTVRVd016RXpNREF3TURBd1doY05Nemd4TWpNeE1EQXdNREF3V2pCSE1Rc3dDUVlEVlFRR0V3SkRUakVSTUE4RwpBMVVFQ2d3SVZXNXBWSEoxYzNReEpUQWpCZ05WQkFNTUhGVkRRU0JGZUhSbGJtUmxaQ0JXWVd4cFpHRjBhVzl1SUZKdmIzUXdnZ0lpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ3BDUWNvRXdLd21lQmtxaDVERm5wenNaR2dkVDZvK3VNNEFIcnMKaVdvZ0Q0dkZzSnN6QTFxR3hsaUcxY0dGdTAvR25FQk55cjd1YVphNHJZRXdtbnlTQmVzRks1cEkwTGgyUHBiSUlMdlNzUEdQMkt4RgpSditxWjJDMGQzNXFIendhVW5vRVBRYzhoUTJFMEI5MkN2ZHFGTjl5NHpSOFYwNVdBVDU1OGFvcE8yejYrSTl0VGNnMTM2N3IzQ1R1CmVVV25oYllGaU42SVhTVjhsMlJuQ2RtL1doVUZodk1KSHV4WU1qTVI4M2Rrc0hZZjVCQTFGeHZ5RHJGc3BDcWpjL3dKSHg0eUdWTVIKNTltekxDNTJMcUdqM241cWlBbm84Z2VLK0xMTkVPZmljMENUdXdqUlArSDhDNVN6SmU5OHB0ZlJyNS8vbHByMWtYdVlDM2ZVZnVnSAowbUsxbFRuajgvRnREdzVsaElwalZNV0F0dUNlUzMxSEpxY0JDRjNSaUo3WHd6SkUrb0pLQ21oVWZ6aFRBOHlrQUROa1VWa0xvNEtSCmVsN3NGc0x6S3VaaTJpcmJXV0lRSlVvcWdRdEhCME1HY0lmUytwTVJLWHBJVGV1VXgzQk5yMmZWVWJHQUlBRUJ0SG9JcHBCL1R1RHYKQjBHSHIycWxYb3Y3ejFDeW1sU3Z3NG02V0MzMU1KaXhObkk1ZmtrRS9TbW5USG5rQlZmYmxMa1dVNDFHc3gyVllWZFdmNi93Rmx0aApXRzgyVUJFTDJLd3JsUllhRGg4SXpUWTBaUkJpWnRXQVh4UWdYeTBNb0hnS2FOWXMxK2x2SzlKS0JaUDhubTlyWi8rSThVNmxhVXBTCk53WHF4aGFOMHNTWjBZSXJPN28xZGZkUlVWanp5QWZkNUxRRGZ3SURBUUFCbzBJd1FEQWRCZ05WSFE0RUZnUVUyWFE2NURBOURmY1MKM0g1YUJaOGVOSnIzNFJRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBWVl3RFFZSktvWklodmNOQVFFTApCUUFEZ2dJQkFEYU5sOHhDRldRcE41c21MTmI3cmhWcExHc2FHdmRmdHZrSFRGbnE4OG5JdWE3TXVpNTYzTUQxc0MzQU82K2ZjQVVSCmFwOGxUd0VwY09QbERPSHFXbnpjU2J2QkhpcUI5UlpMY3BISW9qRzVxdHI4blIvelhVQUNFL3hPSEFiS3N4U1FWQmNaRWhyeEg5Y00KYVZyMmNYajBsSDJSQzQ3c2tGU092RytoVEt2OGRHVDljWnI0UVFlaHpaSGtQSnJnbXpJNWM2c3ExV25JZUpFbU1YM2l4ekR4L0JSNApkeElPRS9UZEZwUy9TMmQ3Y0ZPRnlyQzc4emhOTEpBNXdBM0NYV3ZwNHVYVmlJM1dMTCtyRzc2MUtJY1NGM1J1L0gzOGo5Q0hKckFiCis3bHNxK0tlUFJYQk95NW5BbGlSbisvNFFoOHN0MmoxZGEzUHRmYi9FWDNDOENTbHJkUDZvRHlwK2wzY3BhRHZSS1MrMXVqbDVCT1cKRjNzR1BqTHR4N2RDdkhhajJHVTRLemcxVVNFT0RtOHVOQk5BNFN0bkRHMUtRVEFZSTFveVZabkpGK0E4M3Zic2VhMHJXQm1pclN3aQpHcFdPdnBhUVhVSlh4UGtVQXpVckhDMVJWd2luT3Q0LzVNaTBBM1BDd1NhQXV3dENINjBOcnlaeTJzeStzNk9EV0EyQ3hSOUdVZU9jCkdNeU5tNDNzU2V0MVVOV01LRm5LZERUYWpBc2hxeDdxRytYSC9SVSt3QmVxK3lOdUprYkwrdm14Y210cHp5S0VDMklQck5rWkFKU2kKZGp6VUxacnRCSjR0Qm1JUU4xSWNoWEliSitYTXhqSHNOK3hqV1pzTEhYYk1makthaUpVSU5sSzczblpmZGtsSnJYKzlaU0N5eWNFcgpkaGgybjFheAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpDZXJ0aWduYSBSb290IENBCj09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdXekNDQkVPZ0F3SUJBZ0lSQU1ycEc0bnhWUU1ObytaQmJjVGpwdUV3RFFZSktvWklodmNOQVFFTEJRQXdXakVMTUFrR0ExVUUKQmhNQ1JsSXhFakFRQmdOVkJBb01DVVJvYVcxNWIzUnBjekVjTUJvR0ExVUVDd3dUTURBd01pQTBPREUwTmpNd09ERXdNREF6TmpFWgpNQmNHQTFVRUF3d1FRMlZ5ZEdsbmJtRWdVbTl2ZENCRFFUQWVGdzB4TXpFd01ERXdPRE15TWpkYUZ3MHpNekV3TURFd09ETXlNamRhCk1Gb3hDekFKQmdOVkJBWVRBa1pTTVJJd0VBWURWUVFLREFsRWFHbHRlVzkwYVhNeEhEQWFCZ05WQkFzTUV6QXdNRElnTkRneE5EWXoKTURneE1EQXdNell4R1RBWEJnTlZCQU1NRUVObGNuUnBaMjVoSUZKdmIzUWdRMEV3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQwpEd0F3Z2dJS0FvSUNBUUROR0RsbEdsbXg2bVFXRG95VUpKVjhnOVBGT1NiY0RPOFdWNDNYMkt5alFuK0N5dTNOVzlzT3R5M3RSUWdYCnN0bXp5OVlYVW5JbzI0NU9ub3EyQy9tZWhKcE5kdDRpS1Z6U3M5SUdQakE1cVhTamtsWWNvVzlNQ2lCdG55TjZ0TWJhTE9RZExOeXoKS05BVDhreE9Ba21oVkVDZTV1VUZvQzJFeVArWWJORHJpaHFFQ0I2M2FDUHVJOVZ3em0xUmFSRHVvWHJDMFNJeHdvS0YwdkpWZGxCOApKWHJKaEZ3THJOMUNUaXZuZ3FJa2ljdVFzdER1STdwbVRMdGlwUGxUV21SN2ZKajZvMGllRDVXdXB4ajBhdXd1QTBXdjhIVDRLczE2ClhkRytSQ1l5S2ZIeDlXek1mZ0loQzU5dnBEKytuVlBpejMycExIeFlHcGZoUFRjM0dHWW8wa0RGVVlxTXd5M09VNGdrV0dRd0ZzV3EKNE5ZS3BrRGZlUGIxQkh4cEU0UzgwZEduQnM4QjkyakFxRmU3T21HdEJJeVQ0NjM4OE50RWJWbmNTVm11ckpxWk5qQkJlM1l6SW9lagp3cEtHYnZsdzdxNkhoNVVieEhxOU1mUFUwdVdaLzc1STdIWDFlQllkcG5EQmZ6d2JvWkw3ejhnODFzV1RDby8xVlRwMmxjNVptSW9KCmxYY3ltb082TEFRNmw3M1VMNzdYYkp1aXluMXRKc2xWMWMvRGVWSUlDWmtISkMxa0pXdW1JV21iYXQxMFRXdVhla0c5cXhmNWtCZEkKanpiNUxkWEYyKzZxaFVWQitzMDZSYkZvNWpaTW01Qlg3Q081aHdqQ3hBbnhsNFlxS0UzaWRNRGF4SXpiMytLaEYxbk9KRmwwTWRwLwovVEJ0MmR6aGF1SDhYd0lEQVFBQm80SUJHakNDQVJZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3CkhRWURWUjBPQkJZRUZCaUhWdUJ1ZCs0a05UeE9jNW9mMXVIaWVYNHJNQjhHQTFVZEl3UVlNQmFBRkJpSFZ1QnVkKzRrTlR4T2M1b2YKMXVIaWVYNHJNRVFHQTFVZElBUTlNRHN3T1FZRVZSMGdBREF4TUM4R0NDc0dBUVVGQndJQkZpTm9kSFJ3Y3pvdkwzZDNkM2N1WTJWeQpkR2xuYm1FdVpuSXZZWFYwYjNKcGRHVnpMekJ0QmdOVkhSOEVaakJrTUMrZ0xhQXJoaWxvZEhSd09pOHZZM0pzTG1ObGNuUnBaMjVoCkxtWnlMMk5sY25ScFoyNWhjbTl2ZEdOaExtTnliREF4b0MrZ0xZWXJhSFIwY0RvdkwyTnliQzVrYUdsdGVXOTBhWE11WTI5dEwyTmwKY25ScFoyNWhjbTl2ZEdOaExtTnliREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBbExpZVQvRGpsUWdpNTgxb1FmY2NWZFY4QU9JdApPb2xkYURndlVTSUxTbzNMNmJ0ZFBydGNQYkVvL3VSVFZSUFBvWkFiQWgxZlprWUpNeWpoRFNTWGNOTVFIK3BrVjVhN1hkcm54SXhQClRHUkdIVnlINDFuZVF0R2JxSDZtaWQyUEhNa3dndTA3bk0zQTZSbmdhdGdDZFRlcjl6UW9LSkh5QkFwUE5lTmdKZ0g2MEJHTStSRnEKN3E4OXcxRFRqMTh6ZVR5R3FITkZrSXdndG5KekZ5TytCMlhsZUpJTnVnSEE2NHdjWnIrc2huY0JsQTJjNXVrNWpSK21VWXlaRERsMwo0YlNiK2h4blYyOXFhbzZwSzB4WGVYcFhJcy9OWDJOR2pWeFpPb2I0TWtkaW8yY05HSkhjKzZacjlVaGhjeU5aamdLbnZFVHE5RW1kCjhWUlkrV0N2Mmhpa0x5aEYzSHFnaUlaZDh6dm4veWsxZ1B4a1E1VG00eHh2dnEwT0ttT1pLOGwraGZaeDZBWURsZjdlajBnY1d0U1MKNkN2dTV6SGJ1Z1JxaDVqbnhWL3ZmYWNpOXdIWVRmbUowQTZhQlZta25walpieXZLY0w1a3dsV2o5T212dzVJcDNJZ1dKSms4alNhWQp0bHUzek02M053ZjlKdG1ZaFNUL1dTTURtdTJkbmFqa1hqak8xMUlOYjlJL2JiRUZhMG5PaXBGR2MvVDJML0NvYzNjT1pheWhqV1pTCmFYNUxhQXpISGpjbmc2V014d0xrRk0xSkFiQnpzLzNHa0RwdjBtenRPKzdza2I2aVExMkxBRXBtSlVSdzNrQVArSHdWOTZMT1BOZGUKRTR5QkZ4Z1gwYjN4ZHhBNjFHVTV3U2VzVnl3bFZQK2kyaytLWVRsZXJqMUtqTDA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmVtU2lnbiBSb290IENBIC0gRzEKPT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGxEQ0NBbnlnQXdJQkFnSUtNZlhrWWd4c1dPM1cyREFOQmdrcWhraUc5dzBCQVFzRkFEQm5NUXN3Q1FZRFZRUUdFd0pKVGpFVApNQkVHQTFVRUN4TUtaVzFUYVdkdUlGQkxTVEVsTUNNR0ExVUVDaE1jWlUxMVpHaHlZU0JVWldOb2JtOXNiMmRwWlhNZ1RHbHRhWFJsClpERWNNQm9HQTFVRUF4TVRaVzFUYVdkdUlGSnZiM1FnUTBFZ0xTQkhNVEFlRncweE9EQXlNVGd4T0RNd01EQmFGdzAwTXpBeU1UZ3gKT0RNd01EQmFNR2N4Q3pBSkJnTlZCQVlUQWtsT01STXdFUVlEVlFRTEV3cGxiVk5wWjI0Z1VFdEpNU1V3SXdZRFZRUUtFeHhsVFhWawphSEpoSUZSbFkyaHViMnh2WjJsbGN5Qk1hVzFwZEdWa01Sd3dHZ1lEVlFRREV4TmxiVk5wWjI0Z1VtOXZkQ0JEUVNBdElFY3hNSUlCCklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFrMHU3NldhSzdwMWIxVFNUMEJzZXcrZWV1R1F6ZjJONGFMVE4KTG5GMTE1c2d4azBwdkxab1lJcjNJWnBXTlZyemRyM1l6WnIvazFaTHBWa0dvWk0wS2QwV05IVk84b0cweDVaT3JSa1ZVa3IrUEhCMQpjTTJ2SzZzVm1qTThxck9McXMxRC9mWHFjUC90enhFN2xNNU9NaGJUSTBBcWQ3T3ZQQUVzYk8yWkxJdlpUbW1Zc3ZlUFFiQXllR0hXCkRWL0QrcUpBa2gxY0YrWndQalhub3JmQ1l1S3JwRGhNdFRrMWIrb0RhZm82VkdpRmJkYnlMME5WSHBFTkR0alZhcVNXMFJNOExIaFEKNkRxUzBoZFc1VFVhUUJ3K2pTenRPZDlDNElOQmROK2p6Y0tHWUVobzQya0xWQUNMNUhacElRMTVUalFJWGhUQ3pMRzNyZGQ4Y0lySApoUUlEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVKys4TmhwNnc0OTJwdWZFaEYzOCsvUEIzS3hvd0RnWURWUjBQQVFIL0JBUURBZ0VHCk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFGbi84b3oxaDMxeFBhT2ZHMXZSMnZqVG5HczIKdlp1cFlldmVGaXgwUFo3bWRkclh1cWU4UWhmblBaSHI1WDNkUHB6eHo1S3NiRWpNd2lJL2FUdkZ0aFV2b3pYR2FDb2NWNjg1NzQzUQpOY01ZREhzQVZoek5peGwwM3I0UEV1RFFxcUUvQWpTeGNNNmRHTllJQXdsRzdtRGdmcmJFU1FSUmZYQmd2S3F5LzNseWVxWWRQVjhxCitNcmkvVG0zUjducmZ0OEVJNi82bkFZSDZmdGprNEJBdGNac0NqRW96Z3lmejdNak5ZQkJqV3pFTjN1Qkw0Q2hRRUtGNmRrNGplaWgKVTgwQnYybm9XZ2J5UlF1UStxN2h2NTN5cmxjOHBhNnlWdlNMWlVEcC9UR0JMUFE1Q2RqdWE2ZTBwaDBWcFpqM0FZSFloWDN6VVZ4eAppTjY2ekIrQWZrbz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKZW1TaWduIEVDQyBSb290IENBIC0gRzMKPT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNUakNDQWRPZ0F3SUJBZ0lLUFBZSHFXaHdEdHFMaERBS0JnZ3Foa2pPUFFRREF6QnJNUXN3Q1FZRFZRUUdFd0pKVGpFVE1CRUcKQTFVRUN4TUtaVzFUYVdkdUlGQkxTVEVsTUNNR0ExVUVDaE1jWlUxMVpHaHlZU0JVWldOb2JtOXNiMmRwWlhNZ1RHbHRhWFJsWkRFZwpNQjRHQTFVRUF4TVhaVzFUYVdkdUlFVkRReUJTYjI5MElFTkJJQzBnUnpNd0hoY05NVGd3TWpFNE1UZ3pNREF3V2hjTk5ETXdNakU0Ck1UZ3pNREF3V2pCck1Rc3dDUVlEVlFRR0V3SkpUakVUTUJFR0ExVUVDeE1LWlcxVGFXZHVJRkJMU1RFbE1DTUdBMVVFQ2hNY1pVMTEKWkdoeVlTQlVaV05vYm05c2IyZHBaWE1nVEdsdGFYUmxaREVnTUI0R0ExVUVBeE1YWlcxVGFXZHVJRVZEUXlCU2IyOTBJRU5CSUMwZwpSek13ZGpBUUJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBUWpwUXk0TFJMMUtQT3hzdDNpQWhLQW5qbGZTVTJmeVNVMFdYVHN1d1ljCjU4QnlyK2l1TCtGQlZJY1VxRXF5Nkh5QzVsdHF0ZHl6ZGM2TEJ0Q0dJNzlHMVk0UFB3VDAxeHlTZnZhbFk4TDFYNDR1VDZFWUdRSXIKTWdxQ1pIMFdrOUdqUWpCQU1CMEdBMVVkRGdRV0JCUjhYUUtFRTlUTWlwdUJ6aGNjTGlrZW5FaGpRakFPQmdOVkhROEJBZjhFQkFNQwpBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFLQmdncWhrak9QUVFEQXdOcEFEQm1BakVBdnZOaHp3SVFIV1NWQjdnWWJvaUZCUytECkNCZVF5aCtLVE9nTkczcXhyZFdCQ1Vmdk82d0lCSHhjbWJIdFJ3ZlNBakVBbmJwVi9LbEs2TzN0NW5ZQlFudkkrR0RaalZHTFZUdjcKakh2clpRbkQrSmJOUjZpQzhoWlZkeVIrRWhDVkJDeWoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKZW1TaWduIFJvb3QgQ0EgLSBDMQo9PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEY3pDQ0FsdWdBd0lCQWdJTEFLN1BBTHJFenpMNFE3SXdEUVlKS29aSWh2Y05BUUVMQlFBd1ZqRUxNQWtHQTFVRUJoTUNWVk14CkV6QVJCZ05WQkFzVENtVnRVMmxuYmlCUVMwa3hGREFTQmdOVkJBb1RDMlZOZFdSb2NtRWdTVzVqTVJ3d0dnWURWUVFERXhObGJWTnAKWjI0Z1VtOXZkQ0JEUVNBdElFTXhNQjRYRFRFNE1ESXhPREU0TXpBd01Gb1hEVFF6TURJeE9ERTRNekF3TUZvd1ZqRUxNQWtHQTFVRQpCaE1DVlZNeEV6QVJCZ05WQkFzVENtVnRVMmxuYmlCUVMwa3hGREFTQmdOVkJBb1RDMlZOZFdSb2NtRWdTVzVqTVJ3d0dnWURWUVFECkV4TmxiVk5wWjI0Z1VtOXZkQ0JEUVNBdElFTXhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXordXAKdWZHWkJjellLQ0ZLODNNMFVZUldFUFdnVHl3UzQvb1RtaWZRei9sNUduUmZIWGs1L0Z2NGNJN2drbEwzNUNYNVZJUFpIZFBJV29VLwpYc2UyQis0K3dNNmFyNnhXUWlvNUpYRFd2N1Y3TnEyczluUGN6ZGNkaW9PbCt5dVFGVGRySENaSDNEc3BWcE5xczhGcU9wMDk5Y0dYCk9GZ0ZpeHdSNCtTMHVGMkZIWVArZUY4TFJXZ1lTS1ZHY3pRNy9nL0lkcnZIR1BNRjBZYnpoZTNudWRreXJWV0l6cWEya2JCUHJINFYKSTViMlAvQWdOQmJlQ3NiRUJFVjVmNmY5dnRLcHBhK2N4U01xOXp3aGJMMnZqMDdGT3JMek5CTDgzNEFhU2FUVXFaWDNub2xlb29tcwpsTXVvYUp1dmltVW56WW51M1l5MWF5bHdRNkJwQytTNUR3SURBUUFCbzBJd1FEQWRCZ05WSFE0RUZnUVUvcUhnY0I0cUF6bFNXa0srClhKR0ZlaGlxVGJVd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFNSktWdm9WSVhzb291bmxIZnY0TGNRNWxrRk1PeWNzeEd3WUZZREdySzlIV1M4bUMrTTJzTzg3L2tPWFNUS1pFaFZiM3hFcAovNnRUK0x2QmVBK3NuRk92Vjcxb2pEMXBNL0Nqb0NOak8yUm5Ja1N0MVhITFZpcDRrcU5QRWpFMk51TGUvZ0RFbzJBUEo2MmdzSXExCk5ucFNvYjBuOUNBbll1aE5sQ1FUNUFvRTZUeXJMc2hEQ1VyR1lRVGxTVFIrMDhUSTlRL0FxdW02VkY3ell5dFBUMURVL3JsN21ZdzkKd0M2OEFpdlR4RURraWdjeEhwdk9KcGtUK3hIcW1pSU1FUm5IWGh1QlVERElsaEp1NTh0QmY1RTdva2UzVklBYjNBRE1tcERxdzhOUQpCbUlNTU1BVlNLZW9XWHpocmlLaTRncDZEL3BpcTFKTTRmSGZ5cjZERFVJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgplbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMwo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ0t6Q0NBYkdnQXdJQkFnSUtlM0cyZ2xhNEVueWNxREFLQmdncWhrak9QUVFEQXpCYU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFRwpBMVVFQ3hNS1pXMVRhV2R1SUZCTFNURVVNQklHQTFVRUNoTUxaVTExWkdoeVlTQkpibU14SURBZUJnTlZCQU1URjJWdFUybG5iaUJGClEwTWdVbTl2ZENCRFFTQXRJRU16TUI0WERURTRNREl4T0RFNE16QXdNRm9YRFRRek1ESXhPREU0TXpBd01Gb3dXakVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBc1RDbVZ0VTJsbmJpQlFTMGt4RkRBU0JnTlZCQW9UQzJWTmRXUm9jbUVnU1c1ak1TQXdIZ1lEVlFRRApFeGRsYlZOcFoyNGdSVU5ESUZKdmIzUWdRMEVnTFNCRE16QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQlAybFlhNTdKaEFkCjZiY2lNSzRHOUlHenNVSnhsVG04MDFManI2LzU4cGMxa2paR0RvZVZqYms1V3VtNzM5RCt5QWRCUEx0VmI0T2phdnRpc0lHSkFuQjkKU01WSzQra2lWQ0pOazd0Q0RLOTNuQ09tZmRkaEVjNWx4L2gvL3ZYeXFhTkNNRUF3SFFZRFZSME9CQllFRlB0YVNOQ0FJRUR5cU9rQQpCMmtaZDZmbXcvVFBNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Bb0dDQ3FHU000OUJBTURBMmdBCk1HVUNNUUMwMkM4Q2lmMjJUR0s2UTA0VGhISzFydDBjM3RhMTNGYVBXRUJhTGQ0Z1RDS0R5cE9vZnU0U1FNZldoMC80MzRVQ01Cd1UKWk9SOGxvTVJuTERSV21GTHBnOUowd0Q4b2Z6a3BmOS9yZGN3ME1kM2Y3NkJCMVV3VUNBVTlWYzRDcWd4VVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpIb25na29uZyBQb3N0IFJvb3QgQ0EgMwo9PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRnp6Q0NBN2VnQXdJQkFnSVVDQlpmaWt5bDdBREprMERmeE1hdUk3Z2NXcVF3RFFZSktvWklodmNOQVFFTEJRQXdiekVMTUFrRwpBMVVFQmhNQ1NFc3hFakFRQmdOVkJBZ1RDVWh2Ym1jZ1MyOXVaekVTTUJBR0ExVUVCeE1KU0c5dVp5QkxiMjVuTVJZd0ZBWURWUVFLCkV3MUliMjVuYTI5dVp5QlFiM04wTVNBd0hnWURWUVFERXhkSWIyNW5hMjl1WnlCUWIzTjBJRkp2YjNRZ1EwRWdNekFlRncweE56QTIKTURNd01qSTVORFphRncwME1qQTJNRE13TWpJNU5EWmFNRzh4Q3pBSkJnTlZCQVlUQWtoTE1SSXdFQVlEVlFRSUV3bEliMjVuSUV0dgpibWN4RWpBUUJnTlZCQWNUQ1VodmJtY2dTMjl1WnpFV01CUUdBMVVFQ2hNTlNHOXVaMnR2Ym1jZ1VHOXpkREVnTUI0R0ExVUVBeE1YClNHOXVaMnR2Ym1jZ1VHOXpkQ0JTYjI5MElFTkJJRE13Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ3oKaU5mcXpnOGdUcjdtMWdOdDdsbjh3bGZmS1dpaGd3NCthTWRvV0p3Y1lFdUpRd3k1MUJXeTdzRk9kZW0xcCsvbDZUV1o1TXdjNTB0ZgpqVE13SUROVDJhYTcxVDRUanVrZmgwbXRVQzFReWhpK0FWaWlFM0NXdTRtSVZvQmMrTDBzUE9GTVY0aTcwN21WNzh2SDl0b3hkQ2ltCjVsU0o5VUV4eXVVbUdzMkM0SERhT3ltNzFRUDFtYnBWOVdUUllBNnppVW00aWk4RjBvUkZLSHlQYUZBU2VQd0x0VlBMd3BnY2hLT2UKc0w0anBOcmN5Q3NlMm01RkhvbVkydmtBTGdicEREdHcxVkFsaUpuTHpYTmc5OVgvTldmRm9ieGVxODFLdUVYcnlHZ2VEUTBVUmhMagowbVJpaWtLWXZMVEdDQWo0L2FoTVpKeDJBYjB2cVd3ekQ5Zy9LTGc4YVFGQ2huNXB3Y2tHeXVWNlJtWHB3dFpRUVM0L3QrVHRiTmUvCkpnRVJvaFlwU21zMEJwRHNFOUsyKzJwMjBqenQ4Tll0M2VFVjdLT2JMeXpKUGl2a2FUdi9jaVd4Tm9aYngzOXJpMVViU3NVZ1lUMnUKeTFEaENEcStzSTlqUVZNd0NGazhtQjEzdW1PUmVzb1FVR0MvOE5lOGxZZVBsOFgrbDJvQmxLTjhXNFVkS2prNjBGU2gwVGx4bmYwaAorYlY3OE9MZ0FvOXVsaVFsTEtBZUxLakVpYWZ2N1prR0w3WUtURS9ib3N3M0dxOUhoUzJLWDhRME5Fd0EvUmlUWnhQUk4rWkl0SXNHCnhWZDdHWVlLZWNzQXlWS3ZRdjgzaitHakhubzlVS3RqQnVjVnRUKzJSVGVVTjdGKzhrakRmOFYxL3BlTlJZOGFweHB5S0JwQUR3SUQKQVFBQm8yTXdZVEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWZCZ05WSFNNRUdEQVdnQlFYbmMwZQppOVk1SzNEVFhOU2d1Qit3QVB6RllUQWRCZ05WSFE0RUZnUVVGNTNOSG92V09TdHcwMXpVb0xnZnNBRDh4V0V3RFFZSktvWklodmNOCkFRRUxCUUFEZ2dJQkFGYlZlMjdtSWdIU1Fwc1kxUTdYWmlOYzQvNmd4NUxTNlpTdFM2TEc3Qko4ZE5WSTBsa1VtY0RydWRIcjlFZ3cKVzYyblYzT1pxZFBsdDlFdVdTUlkzR2d1TG1MWWF1UndDeTBnVUNDa01wWFJBSmk3MC8zM012Skpyc1o2NEVlK2JzN0xvM0k2TFdsZAp5OGpvUlRuVStrTEJFVXgzWFpMN2F2OVlST1hyZ1o2dm9KbXR2cWtCWnNzNEhUemZReC8wVFc2MHVoZEcvSDM5aDRGNWFnMHpEL292CitCUzVnTE5kVGFxWDRmbmtHTVg0MVRpTUpqejk4aWppN2xwSmlDemZlVDJPbnBBOHZVRktPdDFiOXBxMHpqOGxNSDh5ZmFJRGxORGMKZXFGUzNtNlRqUmdtL1ZXc3ZZK2Iwcyt2NTRZc3l4OEpiNk52cVlUVWM3OU5vWFFiVGlOZzhzd09xbitrbkV3bHFMSm1PemovMlpRdwo5bktFdm1oVkVBL0djeXdXYVpNSC9yRkY3YnVpVldxdzJyVktBaVVuaGRlM3Q0WkVGb2xzZ0NzK2w2bWMxWDVWVE1iZVJSQWM2dWs3Cm53TlQ3dTU2QVFJV2VOVG93cjVHZG9nVFB5SzdTQklkVWdDMEFuNGhHaDZjSmZUelBWNGUwaHo1c3kyMjl6ZGN4c3NoVHJEM21VY1kKaGNFcnVsV3VCdXJRQjdMY3E5Q0NsblhPMGxEK21lZlBMNS9uZHRGaEt2c2h1ekhRcXA5SHBMSWl5aFk2VUZmRVcwTm54V1ZpQTBrQgo2MFBaMlBpZXJjK3hZdzVGOUtCYUxKc3R4YWJBcmFoSDlDZE1PQTB1RzBrN1V2VG9pSU1yVkNqVThqVlN0REtEWW1sa0RKR2NuNWZxCmRCYjlIeEVHbXB2MAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJR1N6Q0NCRE9nQXdJQkFnSVJBTm0xUTMrdnFUa1BBQUFBQUZWbHJWZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2diNHhDekFKQmdOVgpCQVlUQWxWVE1SWXdGQVlEVlFRS0V3MUZiblJ5ZFhOMExDQkpibU11TVNnd0pnWURWUVFMRXg5VFpXVWdkM2QzTG1WdWRISjFjM1F1CmJtVjBMMnhsWjJGc0xYUmxjbTF6TVRrd053WURWUVFMRXpBb1l5a2dNakF4TlNCRmJuUnlkWE4wTENCSmJtTXVJQzBnWm05eUlHRjEKZEdodmNtbDZaV1FnZFhObElHOXViSGt4TWpBd0JnTlZCQU1US1VWdWRISjFjM1FnVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMQpkR2h2Y21sMGVTQXRJRWMwTUI0WERURTFNRFV5TnpFeE1URXhObG9YRFRNM01USXlOekV4TkRFeE5sb3dnYjR4Q3pBSkJnTlZCQVlUCkFsVlRNUll3RkFZRFZRUUtFdzFGYm5SeWRYTjBMQ0JKYm1NdU1TZ3dKZ1lEVlFRTEV4OVRaV1VnZDNkM0xtVnVkSEoxYzNRdWJtVjAKTDJ4bFoyRnNMWFJsY20xek1Ua3dOd1lEVlFRTEV6QW9ZeWtnTWpBeE5TQkZiblJ5ZFhOMExDQkpibU11SUMwZ1ptOXlJR0YxZEdodgpjbWw2WldRZ2RYTmxJRzl1YkhreE1qQXdCZ05WQkFNVEtVVnVkSEoxYzNRZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2CmNtbDBlU0F0SUVjME1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBc2V3c1F1N2kwVEQvcFpKSDRpM0QKdW1TWGJjcjNEYlZad2JQTHFHZ1oySytFYlRCd1hYN3pMdEpUbWVIK0gxN1pTSzlkRTQzYi8yTXpUZE1BQXJ6RStORUdDSlI1V0lvVgozaW16L2YzRVQraXE0cUE3ZWMyL2EwTXkzZGwwRUxuMzlHalV1OUNIMWFwTGlpcHZLZ1Mxc3FiSG9Icm1TS3ZTMFZuTTFuNGo1cGRzCjhFTGwzRkZMRlVIdFNVckozaENYMW5iQjc2VzFOaFNYTmRoNElqVlM3ME85MnlmYllWYUNOTnpMaUdBTUMxcmxMQUhHVksvWHFzRVEKZTlJRldyaEFub2FudzVDR0FsWlNDWHFjMGllQ1UwcGxVbXIxUE9lbzhweXZpNzNURHRUVVhtNkhubW85UlIzUlhSdjA2UXFzWUpuNwppYlQvbUN6UGZCM3BBcW9FbWg2NDNJaHVKYk5zWnZjOGtQTlh3Yk12OVczeSs4cWgrQ21kUm91emF2Ym1ad2UrTEdjS0toOWFzajVYCnhOTWhJV05sVXBFYnNabU9lWDdtNjQwQTJWcXE2blBvcElJQ1I1YitXNDVVWWFQckwwc3dzSXNqZFhKOElUekk5dkYwMUJ4N293VlYKN3J0Tk96SyttbmRtbnF4cGtDSUhIMkU2bHI3bG1rL01CVHdvV2RQQkRGU29XV0c5eUhKTTZOeWZoMys5bkVnMlhwV2pEcms0SkZYOApkV2JyQXVNSU5DbEt4dU1yTHpPZzJxT0dwUktYL1lBcjJoUkM0NUs5UHZKZFhtZDBMaHlJUnlrMFgrSXlxSndsTjR5Nm1BQ1hpMG1XCkh2MGxpcXpjMnRoZGRHNW1zUDlFMzZFWXhyNUlMemVVZVBpVlNqOS9FMTVkV2YxMGhrTmpjMGtDQXdFQUFhTkNNRUF3RHdZRFZSMFQKQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFRko4NHhGWWp3em5vb0hGczZGUk01T2c2c2I5bgpNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUFTNVVLbWU0c1BET1JHcGJaZ1FJZU1KWDZ0dUdndVc4WkFkandEK01sWjlQT3JZczRRCmpiUmFaSXhvd0xCeVF6VFNHd3YyTEZQU3lwQkxobWI4cW9NaTlJc2FieVpJckhaM0NML0ZtRnowSm9tZWU4TzVaRElCZjlQRDNWaHQKN0xHcmhGVjBkNFFFSjFKcmhrek8zYmxsLzliR1hwK2FFSmxMZFdyK2F1bVhJT1RrZG5yRzBDU3FrTTBna0xwSFpQdC9CN05UZUxVSwpZdkp6UTg1Qks0RnFMb1VXbEZQVWExOXlJcXRSTFVMVkFKeVp2OTY3bER0WC9acjFoc3RXTzF1SUFlVjhLRXNEK1VtRGZMSi9mT1B0CmpxRi9ZRk9PVloxUU5CSVB0NWQ3YklkS1JPZjFiZXlBTi9CWUdXNUthSGJ3SDVMazZyV1MwMkZSRUF1dHA5bGZ4MS9jSDZOY2pLRisKbTdlZTAxWnZabDRIbGlEdEMzVDdaazZMRVJYcGdVbCtiN0RVVUg4aTExOWxBZzJtOUlVZTJLNEdTMHFuMGpGbXd2ak81UWltcEFLVwpSR2hYeE5Venp4a3ZGTVNVSEh1azJmQ2ZEckdBNHRHZUVXU3BpQkU2ZG9MbFlzS0EyS1NEN1pQdmZDK1FzREpNbGhWb1NGTFVtUWpBCkpPZ2M0N09sSVE2U3dKQWZ6eUJmeWpzNHg3ZHRPdlBtUkxnT01XdUlqbkRybkJkU3FFR1VMb2UyNTZZU3hYWGZXOEFLYm51azVGNkcKK1RhVTMzZkQ2UTNBT2ZGNXUwYU9xME5aSjdjZ3V5UHBWa0FoN0RFOVphcEQ4ajNmY0VUaHVrMG1FRHVZbi9QSWpoczRWaUZxVVpQVAprY3BHMm9tM1BWT0RMQWdmaTQ5VDNmK3NIdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCk1pY3Jvc29mdCBFQ0MgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxNwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXVENDQWQrZ0F3SUJBZ0lRWnZJOXI0ZmVpN0ZLNmd4WE1RSEM3REFLQmdncWhrak9QUVFEQXpCbE1Rc3dDUVlEVlFRR0V3SlYKVXpFZU1Cd0dBMVVFQ2hNVlRXbGpjbTl6YjJaMElFTnZjbkJ2Y21GMGFXOXVNVFl3TkFZRFZRUURFeTFOYVdOeWIzTnZablFnUlVORApJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVJREl3TVRjd0hoY05NVGt4TWpFNE1qTXdOalExV2hjTk5ESXdOekU0Ck1qTXhOakEwV2pCbE1Rc3dDUVlEVlFRR0V3SlZVekVlTUJ3R0ExVUVDaE1WVFdsamNtOXpiMlowSUVOdmNuQnZjbUYwYVc5dU1UWXcKTkFZRFZRUURFeTFOYVdOeWIzTnZablFnUlVORElGSnZiM1FnUTJWeWRHbG1hV05oZEdVZ1FYVjBhRzl5YVhSNUlESXdNVGN3ZGpBUQpCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVRVdkQwQ1FuVkJFeVBOZ0FTR0FsRXZhcWlCWWd0bHpQYktuUjV2U21aUm9nUFpuWkg2CnRoYXhqRzdlZk0zYmVhWXZ6cnZPY1MvbHBhc283R01FWnBuNCt2S1RFQVhoZ1NoQzQ4Wm85T1liaEdCS2lhL3RlUTg3enZIMlJQVUIKZU1DalZEQlNNQTRHQTFVZER3RUIvd1FFQXdJQmhqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCVEl5NWx5Y0ZJTQorT2Erc2dSWEtTclBRaER0TlRBUUJna3JCZ0VFQVlJM0ZRRUVBd0lCQURBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpCWThrM3FEUGxmClh1NWdLY3M2OHR2V01vUVpQM3pWTDhLeHpKT3VVTHNKTXNiRzdYN0pOcFFTNUdpRkJxSWIwQzhDTVFDWjZSYTBEdnBXU05Ta01CYVIKZU50VWpHVUJpdWRRWnNJeHR6bTZ1Qm9pQjA3OGExUVdJUDhydGVkTURFMm1UM009Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCk1pY3Jvc29mdCBSU0EgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxNwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZxRENDQTVDZ0F3SUJBZ0lRSHRPWENWL1l0TE5IY0I2cXZuOUZzekFOQmdrcWhraUc5dzBCQVF3RkFEQmxNUXN3Q1FZRFZRUUcKRXdKVlV6RWVNQndHQTFVRUNoTVZUV2xqY205emIyWjBJRU52Y25CdmNtRjBhVzl1TVRZd05BWURWUVFERXkxTmFXTnliM052Wm5RZwpVbE5CSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR1VnUVhWMGFHOXlhWFI1SURJd01UY3dIaGNOTVRreE1qRTRNakkxTVRJeVdoY05OREl3Ck56RTRNak13TURJeldqQmxNUXN3Q1FZRFZRUUdFd0pWVXpFZU1Cd0dBMVVFQ2hNVlRXbGpjbTl6YjJaMElFTnZjbkJ2Y21GMGFXOXUKTVRZd05BWURWUVFERXkxTmFXTnliM052Wm5RZ1VsTkJJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVJREl3TVRjdwpnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFES1c3NlVNNHdwbFpFV0NwVzlSMkxCaWZPWk50OUdrTW1sCjdYaHFiMGVSYVBnbloxQXpIYUdtKytEbFE2T0VBbGNCWFp4SVFJSlRFTHkveHp0b2tMYUNMZVgwWmRETWJSbk1sZmw3ckVxVXJRN2UKUzBNZGh3ZVNFNUNBZzJRMU9RVDg1ZWxzczdZZlVKUTRaVkJjRjBhNXRvVzFITFVYNk5aRm5kaXlKckRLeEhCS3JtQ2szYlBaN1B3NwoxVmR5dkQvSXliTGVTMnY0STJ3RHdBVzlsY2ZOY3p0bWdHVGpHcXd1K1VjRjhnYTJtM1AxZUROYng2SDdKeXFodEpxUmpKSFRPb0krCmRrQzB6VkpoVVhBb1A4WEZXdkxKakVtN0ZGdE55UDluVFV3U2xxMzEvbmlvbDRmWC9WNGdnTnloU3lMNzFJbXR1czVIbDBkVmU0OUYKeUdjb2hKVWNhRER2NzBuZ05YdGs1NWl3bE5wTmhUcytWY1FvcjFmem5oUGJSaWVmSHFKZVJJT2twY3JWRTdOTFA4VGp3dWFHWWFSUwpNTGw2SUU5dkR6aFR5ek1NRXl1UDFwcTlLc2d0c1J4OVMxSEtSOUZJSjNKZGgrdlZSZVpJWloydlVwQzZXNklZWlZjU24yaTUxQlZyCmxNUnBJcGowTStEdCtWR09RVkRKTkU5MmtLejhPTUhZNFh1NTQrT1U0VVpweXc0S1VHc1R1cXdQTjFxM0VyV1FnUjVXcmxjaWh0bkoKMHRIWFVlT3JPOFpWL1I0TzAzUUswZHFxNm1tNGx5aVBTTVFIK0ZKRE92VEtWVFVzc0tacXdKejU4b0hoRW1yQVJkbG5zODcvSTZLSgpDbFRVRkxrcXFOZnMrYXZOSlZneWVZK1FXNWc1eEFnR3dheC9EajBBcFFJREFRQUJvMVF3VWpBT0JnTlZIUThCQWY4RUJBTUNBWVl3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUNjdFpmNGF5Y0k4YXd6bmp3Tm5wdjd0TnNpTXdFQVlKS3dZQkJBR0MKTnhVQkJBTUNBUUF3RFFZSktvWklodmNOQVFFTUJRQURnZ0lCQUt5dlBsM0NFWmFKanFQbmt0YVhGYmdUb3FaQ0xnTE5GZ1ZaSjhvZwo2THE0NkJyc1RhaVhWcTVsUTdHUEFKdFN6VlhOVXpsdFlreUxEVnQ4TGtTL2d4Q1A4MU9DZ01OUE9zZHVFVC9tNHhhUmhQdHRoSDgwCmRLMkpwODY1MTllZmhHU1N2cFdoclFsVE05M3VDdXBLVVk1dlZhdTZ0WlJHcm94LzJLSlFKV1ZnZ0ViYk13U3ViTFdZZEZRbDNKUGsKK09OVkZUMjRiY01LcEJMQmFZVnUzMlR4VTVuaFNuVWduWlVQNU5iY0EvRlpHT2hIaWJKWFdwUzJxZGdYS3hkSjVYYkx3VmFaT2pleAovMmtza1pHVDRkOU1vemQyVGFHZitHMGVIZFA2N1B2MFJSMFRiYy8zV2VVaUozSXJodk5YdXpEdEpFM2NmVmE3bzdQNE5IbUp3ZUR5CkFtSDNwdndQdXh3WEM2NUIyWHk5SjZQOUxqclJrNVN4Y3gwa2k2OWJJSW10dDJkbWVmVTZ4cWFXTS81VGtzaEdzUkdSeHBsL2o4blcKWmpFZ1FSQ0hMUXpXd2E4MG1NcGtnL3NUVjlIQjhEeDZqS1hCL1pVaG9ISEJrMmR4RXVxUGlBcHBHV1NaSTFiN3JDb3VjTDVteEF5RQo3K1dMODVNQitHcVFrMmRMc21panRXS1A2VCtNZWp0ZUQrZU11TVo4N3pmOWRPTElUek55NFpRNWJiMFNyNzRNVG5COEcyK05zektUCmMwUVdiZWowOStDVmdJK1dYVGlrOUt2ZUNqQ0hrOWhOQUhGaVJTZExPa0tFVzM5bHQyYzBVaTJjRm11cXFOaDdvMEpNY2NjTXlqNkQKNUtidnR3RXdYbEdqZWZWd2FhWkJSQStHc0N5UnhqM3FyZytFCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCmUtU3ppZ25vIFJvb3QgQ0EgMjAxNwo9PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNRRENDQWVXZ0F3SUJBZ0lNQVZSSTd5SDlsMWtOOVFRS01Bb0dDQ3FHU000OUJBTUNNSEV4Q3pBSkJnTlZCQVlUQWtoVk1SRXcKRHdZRFZRUUhEQWhDZFdSaGNHVnpkREVXTUJRR0ExVUVDZ3dOVFdsamNtOXpaV01nVEhSa0xqRVhNQlVHQTFVRVlRd09Wa0ZVU0ZVdApNak0xT0RRME9UY3hIakFjQmdOVkJBTU1GV1V0VTNwcFoyNXZJRkp2YjNRZ1EwRWdNakF4TnpBZUZ3MHhOekE0TWpJeE1qQTNNRFphCkZ3MDBNakE0TWpJeE1qQTNNRFphTUhFeEN6QUpCZ05WQkFZVEFraFZNUkV3RHdZRFZRUUhEQWhDZFdSaGNHVnpkREVXTUJRR0ExVUUKQ2d3TlRXbGpjbTl6WldNZ1RIUmtMakVYTUJVR0ExVUVZUXdPVmtGVVNGVXRNak0xT0RRME9UY3hIakFjQmdOVkJBTU1GV1V0VTNwcApaMjV2SUZKdmIzUWdRMEVnTWpBeE56QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJKYmNQWXJZc0h0dnhpZStSSkN4CnMxWVZlNDVESkgwYWhGbnVZMml5eGw2SDBCVklIcWlRcmIxVG90cmVPcENtWUY5b01yV0dRZCtIV3l4N3hmNThldHFqWXpCaE1BOEcKQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCU0hFUlVJMGFyQmVBeXhyODdHeVpEdgp2ekFFd0RBZkJnTlZIU01FR0RBV2dCU0hFUlVJMGFyQmVBeXhyODdHeVpEdnZ6QUV3REFLQmdncWhrak9QUVFEQWdOSkFEQkdBaUVBCnRWZmQxNHBWQ3piaGhrVDYxTmxvamJqY0k0cUtEZFF2ZmVwejdMOU5iS2dDSVFETHBiUVMrdWUxNk05K2svenpOWTl2VGxwOHRMeE8Kc3Z4eXFsdForZWZjTVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpjZXJ0U0lHTiBSb290IENBIEcyCj09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZSekNDQXkrZ0F3SUJBZ0lKRVFBMHRrN0dOaTAyTUEwR0NTcUdTSWIzRFFFQkN3VUFNRUV4Q3pBSkJnTlZCQVlUQWxKUE1SUXcKRWdZRFZRUUtFd3REUlZKVVUwbEhUaUJUUVRFY01Cb0dBMVVFQ3hNVFkyVnlkRk5KUjA0Z1VrOVBWQ0JEUVNCSE1qQWVGdzB4TnpBeQpNRFl3T1RJM016VmFGdzAwTWpBeU1EWXdPVEkzTXpWYU1FRXhDekFKQmdOVkJBWVRBbEpQTVJRd0VnWURWUVFLRXd0RFJWSlVVMGxIClRpQlRRVEVjTUJvR0ExVUVDeE1UWTJWeWRGTkpSMDRnVWs5UFZDQkRRU0JITWpDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVAKQURDQ0Fnb0NnZ0lCQU1ERmRSbVJmVVIwZElmK0RqdVczTmdCRnN6dVk1SG5DMi9PT3dwcEduekM0NitDam9iWFhvOVg2OU1oV2YwNQpOMEl3dmxEcXRnK3BpTmd1TFdraDU5RTNHRTU5a2RVV1gydGJBTUk1UXcwMmhWSzVVMlVQSFVMbGo4OEYwKzdjREJyWnVJdDRJbWZrCmFiQm94VHprYkZwRzU4M0grdS9FN0V1OWFxU3MvY3dvVWUrU3RDbXJxeldhVE9URUNNWW16UGhwbitTYzhDblRYUG5HRmlXZUk4TWcKd1QwUFB6aEFzUDZDUkRpcVdocUthMk5ZT0xRVjA3WVJhWHNlVk82TUdpS3NjcGMvSTFtYnlTS0V3UWRQekgvaVY4b1NjTHVtWmZOcApkV085bGZzYmw4M2txSy8yMFU2bzJZcHhKTTAyUGJ5V3hQRnNxYTdsencxdUtBMndEclhLVVh0NEZNTWdMMy83RkZYaEVabjkxUXFoCm5nTGpZbC9yTlVzc3VITG9QajFQckN5N0xvYmlvM2FQNVpNcXo2V3J5RnlOU3diL0VrYXNlTXNVQnpYZ3FkK0w2YThWVHhhSlc3MzIKamNaWnJvaUZEc0dKNng5bnhVV08vMjAzTml0NFpvT1JVU3M5LzFGM2RtS2g3R2MrUG9HRDRGYXBVQjhmZXBtclk3K0VGM2Z4RFR2Zgo5NXhoc3pXWWlqcXk3RHdhTno5K2o1TFAyUklVWk5vUUFoVkIvMC9FNnh5anlmcVo5MGJwNFJqWnNiZ3lMY3NVREZEWWcyV0Q3cmxjCno4c0ZXa3o2R1pkcjFsMFQwOEpjVkx3eWM2QjQ5ZkZ0SHN1ZnBhYWZJdHpSVVo2Q2VXUmdLUk0rby8xUGNtcXI0dFRsdUNSVkxFUkwKaW9oRW5NcUUweW83QWdNQkFBR2pRakJBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZApEZ1FXQkJTQ0lTMW14dGVnNEJYcnprd0pkOFJnbmxSdUF6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFZTjRhdU9meVlJTFZBek9CCnl3YUs4U0pKNmVqcWtYL0dNMTVvR1FPR08wTUJ6d2R3NUFnZVpZV1I1aEVpdC9VQ0k0NnV1UjU5SDM1czVyMGwxWlVhOGdXbXI0VUMKYjY3NDFqSC9KY2xLeU1lS3FkbWZTMG1iRVZlWmtrTVIzcll6cE16WGpXUjkxTTA4S0N5MG1wYnFUZlhFUk1RbHFpQ0EyQ2xWOStCQgovQVltLzdrMjlVTVVBMlo0NFJHeDJpQmZSZ0I0QUNHbEhnQW9ZWGh2cUFFQmo1MDBtdi8wT0pEN3VOR3pjZ2JKY2VhQnhYbnRDNlo1CjhoTUxuUGRkRG5za2s3UkkyNFpmM2xDR2VPZEE1akdva0had1lhK2NOeXdSdFlLM3FxNGtORnR5REdrTnpWbWY5bkd2bkF2UkNqajUKQmlLRFV5VU0vRkhFNXI3aU9aVUxKSzJ2MFpYa2x0ZDBaR3R4VGdJOHFvWHpJS05ET1haYmJGRCttcHdVSG1VVWloVzlvNEpGV2tsVwphdEtjc1dNeTVXSGdVeUlPcHdwSjZzdCtINmppWW9EMkVFVlNtQVlZM3FYTkwzK3ExT2srQ0hMc0l3TUNQS2FxMkx4bmREMFVGL3RVClN4ZmowM2s5Yld0SnlTZ09MblJRdnd6WlJqb1Foc21uUCttZzdIL3JwWGRZYVhIbWd3bzM4b1pKYXI1NUNKRDJBaFprUHVYYVRINE0KTk1uNVg3YXpLRkducHl1cVNmcU5aU2xPNDJzVHA1U2pMVkZ0ZUF4RXk5L2VDRy9PbzJTcjA1V0UxTGxTVkhKN2xpWE12R25qU0c0TgowTWVkSjVxcStCT1MzUjdmWTU4MXFSWTI3SXk0Zy9ROWlZL050QmRlMTdNWFFSQmRKM05naFZkSklnYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGMmpDQ0E4S2dBd0lCQWdJTUJmY09odHBKODBZMUxycXlNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR0lNUXN3Q1FZRFZRUUdFd0pWClV6RVJNQThHQTFVRUNBd0lTV3hzYVc1dmFYTXhFREFPQmdOVkJBY01CME5vYVdOaFoyOHhJVEFmQmdOVkJBb01HRlJ5ZFhOMGQyRjIKWlNCSWIyeGthVzVuY3l3Z1NXNWpMakV4TUM4R0ExVUVBd3dvVkhKMWMzUjNZWFpsSUVkc2IySmhiQ0JEWlhKMGFXWnBZMkYwYVc5dQpJRUYxZEdodmNtbDBlVEFlRncweE56QTRNak14T1RNME1USmFGdzAwTWpBNE1qTXhPVE0wTVRKYU1JR0lNUXN3Q1FZRFZRUUdFd0pWClV6RVJNQThHQTFVRUNBd0lTV3hzYVc1dmFYTXhFREFPQmdOVkJBY01CME5vYVdOaFoyOHhJVEFmQmdOVkJBb01HRlJ5ZFhOMGQyRjIKWlNCSWIyeGthVzVuY3l3Z1NXNWpMakV4TUM4R0ExVUVBd3dvVkhKMWMzUjNZWFpsSUVkc2IySmhiQ0JEWlhKMGFXWnBZMkYwYVc5dQpJRUYxZEdodmNtbDBlVENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMbGRVU2hMUERlUzBZTE92UjI5CnpkMjRxODhLUHVGZDVkeXFDYmxYQWo3bVkySGY4ZytDWTY2ajk2eHowWHpuc3d1dkNBQUpXWC9OS1NxSWs0Y1hHSUR0aUxLMHRoQWYKTGRaZlZhSVRYZEhHNndaV2lZaityREtkL1Z6REJjZHU3b2FKdW9nRG5YSWhocEN1andPbDNKK0lLTXVqa2trUDdOQVA0bTFFVDRCcQpzdFRub0FwVEFicU9sNUYyYnJ6ODFXczI1a0NJMW5zdlh3WG9MRzBSOCtleXZwSkVUTktYcFA3U2NvRkRCNXpwRVQ3MWl4cFpmUjlvCldOMEVBQ3lXODBPemZwZ1pkTm1jYzlrWXZrSEhOSG5aOUdMQ1E3bXpKN0FpeS9rOVVzY3dSN1BKUHJocTR1Zm9nWEJlUW90UEpxWCsKT3NJZ2JydjRGbzdOREttMEcyeDJFT0ZZZVVZK1ZNNkFxRmNKTnlrYm1ST1BETWpXTEJ6N0JlZ0lsVDFsUnR6dXpXbmlUWStIS0U0MApDejdQRk5tNzNiWlFtcTEzMUJuVzJocUl5RTRiSjNYWXNnanhyb013dVJFT3pZZndoSTBWY255aDc4enlpR0c2OUdtN0RJd0xkVmNFCnVFNHFGQzQ5RHh3ZU1xWmlOdTVtNGlLNEJVQmpFQ0x6TXgxMGNvb3M5VGtwb05Qbkc0Q0VMY1U5NDAyeC9ScHZ1bVVITzFqc1FrVW0KKzlqYUpYTEU5Z0N4SW5tOTQzeFpZa3FjQlc4OXp1YldSMk9aeGlSdmNoTElySCtRdEF1UmNPaTM1aFlRY1JmTzNnWlBTRUY5TlVxagppZkxKUzN0QkVXMW50d2lZVE9VUkdhNUNnTno3a0FYVStGREt2dVN0eDhLVTF4YWQ1aGVQcnpiN0FnTUJBQUdqUWpCQU1BOEdBMVVkCkV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGSm5nR1djTll0dDJzOW85dUZ2by9VTFNNUTZITUE0R0ExVWREd0VCL3dRRUF3SUIKQmpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQW1ITnc0ckRUN1Ruc1RHRFpxUktHRng2VzBPaFVLRHRrTFNHbStKMVdFMnBJUFUvSApQaW5iYlZpRFZEMkhmU01GMU9RYzNPZzRaWWJGZGFkYTJ6VUZ2WGZldXlrM1FBVUh3NVJTbjhwazNmRWJLOXhHQ2hBQ01mMUthQTBIClpKRG1IdlVxb2FpN1BGMzVvd2dMRVF6eFB5MFFsRy8rNGpTSGc5YlA1UnMxYmRJRDRiQU5xS0NxUmllQ05xY1Z0Z2ltUWxSWHRwbGEKNGd0NWtOZFhFbEUxR1loQmFDWFVOeGVFRmZzQmN0eVYzbEltSUpnbTRuYjFKMi82QUR0S1lka055MUdUS3YwV0JwYW5JNW9qU1A1Ugp2YmJFc0xGVXp0NXNRYTBXWjM3Yi9Uak51VGhPc3NGZ3k1MFgzMWllZW1LeUpvOTBsWnZrV3gzU0Q5MllISnRadVNQVE1hQ20vempkCnp5QlA2VmhXT21mRDBmYVptWjI2TnJhQUw0aEhUNGEvUkRxQTVEY2NwcnJxbDVnUjBJUmlSMlFlcXU1QXZ6U3huSTlPNGZLU1R4K08KODU2WDN2T21lV3FKY1U5TEp4ZEkvdXowVUE5UFNYM01SZU85ZWtERlFkeGhWaWNHYWVWeVFZSFR0Z0dKb0M4NmNubitPakMvUWV6SApZajZSUzhmWk1YWkMrZmM4WSt3bWpITU1mUm9kNnFoOGg2akNKM3poTTBFUHo4LzhBS0FpZ0o1S3AyOEFzRUZGdHlMS2FFakZRcUt1CjNSM3k0RzVPQlZpeHdKQVdLcVE5RUVDK2oySmpnNm1jZ24wdEF1bURNSHpMSjhuOUhtWUFzQzdUSVMrT014WnNtTzBRcUFmV3pKUFAKMjlGcEhPVEt5ZUMybk9uT2NYSGViRDhXcEhrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUcnVzdHdhdmUgR2xvYmFsIEVDQyBQMjU2IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZRENDQWdlZ0F3SUJBZ0lNRFdwZkNEOG9YRDVSbGQ5ZE1Bb0dDQ3FHU000OUJBTUNNSUdSTVFzd0NRWURWUVFHRXdKVlV6RVIKTUE4R0ExVUVDQk1JU1d4c2FXNXZhWE14RURBT0JnTlZCQWNUQjBOb2FXTmhaMjh4SVRBZkJnTlZCQW9UR0ZSeWRYTjBkMkYyWlNCSQpiMnhrYVc1bmN5d2dTVzVqTGpFNk1EZ0dBMVVFQXhNeFZISjFjM1IzWVhabElFZHNiMkpoYkNCRlEwTWdVREkxTmlCRFpYSjBhV1pwClkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MHhOekE0TWpNeE9UTTFNVEJhRncwME1qQTRNak14T1RNMU1UQmFNSUdSTVFzd0NRWUQKVlFRR0V3SlZVekVSTUE4R0ExVUVDQk1JU1d4c2FXNXZhWE14RURBT0JnTlZCQWNUQjBOb2FXTmhaMjh4SVRBZkJnTlZCQW9UR0ZSeQpkWE4wZDJGMlpTQkliMnhrYVc1bmN5d2dTVzVqTGpFNk1EZ0dBMVVFQXhNeFZISjFjM1IzWVhabElFZHNiMkpoYkNCRlEwTWdVREkxCk5pQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkg3N2JPWWoKNDNNeUNNcGc1bE9jdW5TTkdMQjRrRktBM1RqQVNoM1JxTXlUcEpjR09Nb05GV0xHamdFcVpaMnEzelNSTG9IQjVET1NNY1Q5Q1RxbQpQNjJqUXpCQk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0R3WURWUjBQQVFIL0JBVURBd2NHQURBZEJnTlZIUTRFRmdRVW8wRUdySkJ0CjBVcnJkYVZLRUptenNhR0xTdmN3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnQitaVTJnNmdXckt1RVorSHhiYi9hZDRsdnZpZ3R3anoKUk00cTN3Z2hERGNDSUMwbUE2QUZ2V3ZSOWx6NFpjeUdiYk9jTkVoamhBbkZqWGNhNHN5YzRYUjcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDblRDQ0FpU2dBd0lCQWdJTUNMMkZsMnlaSjZTQWFFYzdNQW9HQ0NxR1NNNDlCQU1ETUlHUk1Rc3dDUVlEVlFRR0V3SlZVekVSCk1BOEdBMVVFQ0JNSVNXeHNhVzV2YVhNeEVEQU9CZ05WQkFjVEIwTm9hV05oWjI4eElUQWZCZ05WQkFvVEdGUnlkWE4wZDJGMlpTQkkKYjJ4a2FXNW5jeXdnU1c1akxqRTZNRGdHQTFVRUF4TXhWSEoxYzNSM1lYWmxJRWRzYjJKaGJDQkZRME1nVURNNE5DQkRaWEowYVdacApZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzB4TnpBNE1qTXhPVE0yTkROYUZ3MDBNakE0TWpNeE9UTTJORE5hTUlHUk1Rc3dDUVlEClZRUUdFd0pWVXpFUk1BOEdBMVVFQ0JNSVNXeHNhVzV2YVhNeEVEQU9CZ05WQkFjVEIwTm9hV05oWjI4eElUQWZCZ05WQkFvVEdGUnkKZFhOMGQyRjJaU0JJYjJ4a2FXNW5jeXdnU1c1akxqRTZNRGdHQTFVRUF4TXhWSEoxYzNSM1lYWmxJRWRzYjJKaGJDQkZRME1nVURNNApOQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkd2YURYVTFDREZICkJhNUZtVlh4RVJNdVN2Z1FNU09qZm9QVGZ5Z0lPaVlhT3MrWGdoK0F0eWNKajlHT01NUUttdzZzV0FTcjl6WjlsQ09rbXdxS2k2dnIKL1RrbFp2RmUvb3l1alVGNW5RbGd6aWlwMDRwdDg5WkYxUEtZaERobG9LTkRNRUV3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFQQmdOVgpIUThCQWY4RUJRTURCd1lBTUIwR0ExVWREZ1FXQkJSVnFZU0owc0V5dlJqTGJLWUhUc2pubmI2Q2tEQUtCZ2dxaGtqT1BRUURBd05uCkFEQmtBakEzQVpLWFJSSitvUE0rclJrNmN0MzBVSk1ERXI1RTBrOUJwSXljblIrajlzS1M1MGdVL2s2YnBaRlhyc1kzY3JzQ01HY2wKQ3JFTVh1NnBZNUp2NVpBTC9tWWl5a2Y5aWpIM2cvNTZ2eEMrR0NzZWovWXBIcFJaNzQ0aE44dFJtS1Z1U3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRm9qQ0NBNHFnQXdJQkFnSVVBWlF3SHFJTDNmWEZNeXF4UTBSeCtOWlFUUTB3RFFZSktvWklodmNOQVFFTUJRQXdhVEVMTUFrRwpBMVVFQmhNQ1MxSXhKakFrQmdOVkJBb01IVTVCVmtWU0lFSlZVMGxPUlZOVElGQk1RVlJHVDFKTklFTnZjbkF1TVRJd01BWURWUVFECkRDbE9RVlpGVWlCSGJHOWlZV3dnVW05dmRDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MHhOekE0TVRnd09EVTQKTkRKYUZ3MHpOekE0TVRneU16VTVOVGxhTUdreEN6QUpCZ05WQkFZVEFrdFNNU1l3SkFZRFZRUUtEQjFPUVZaRlVpQkNWVk5KVGtWVApVeUJRVEVGVVJrOVNUU0JEYjNKd0xqRXlNREFHQTFVRUF3d3BUa0ZXUlZJZ1IyeHZZbUZzSUZKdmIzUWdRMlZ5ZEdsbWFXTmhkR2x2CmJpQkJkWFJvYjNKcGRIa3dnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDMjFQR1RYTFZBaVFxckRaQmIKVUdPdWtKUjBGMFZ5MW50bFdpbExwMWFnUzdndlFuWHAyWHNrV2pGbHF4Y1gwVE02MlJIY1FEYUgzOGRxNlNaZVdZcDM0K2hJbkRFVworajZSc2NySm8rS2Z6aUZUb3dJMk1NdFNBdVhhTWwzRHhlYjU3aEhIaThsRUhvU1RHRXEwbitVU1pHblFKb1ZpQWJiSkFoMitnMUc3ClhOcjRyUlZxbWZlU1ZQYzBXK20vNmltQkV0UlRrWmF6a1ZyZC9wQnpLUHN3UnJYS0NBZkhjWExKWnRNMGwvYU05QmhLNGRBOVdrVzIKYWFjcCt5UE9pTmdTbkFCSXFLWVBzenVTalhFT2RNV0x5RXo1OUp1T3VEeHA3Vzg3VUM5WTdjU3cwQndiYWd6aXZFU3EyTTBVWFpSNApZYjhPYnRvcXZDOE1DM0dtc3hZL25PYjV6SjlUTmVJRG9LQVl2N3Z4dnZUV2pJY05RdmNHdWZGdDdRU1VxUDYyMHdiR1FHSGZuWjN6ClZIYk9Vem9CcHBKQjdBU2pqdzJpMVFuSzFzdWE4ZTlEWGNDcnBVSFBYRk53Y01tSXBpM1VhMkZ6VUNhR1lRNWZHOElyNG96VnU1M0IKQTBLNmxOcGZxYkRLekUwSzcwZHBBeThpKy9Fb3pyOWRVR1dva0cyemRMQUl4NnlvMGVzK25QeGRHb011Szh1MTgwU2RPcWNYWVphaQpjZE53bGhWTnQweHo3aGxjeFZzK1FmNnNkV0E3RzJQT0FOM2FDSkJpdE9VdDdraW5heGVaVkw2SFN1T3BYZ1JNNnhCdFZOYnY4ZWp5ClloYkxnR3Z0UGUzMUh6Q2xya3ZKRSsyS0FRSEp1RkZZd0dZNnNXWkx4TlV4QW1McGRJUU0yMDFHTFFJREFRQUJvMEl3UURBZEJnTlYKSFE0RUZnUVUwcCtJMzZITkxMM3M5VHNCQVpNeko3THJZRXN3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQgpBZjh3RFFZSktvWklodmNOQVFFTUJRQURnZ0lCQURMS2dMT2RQVlFHM2RMU0x2Q2tBU0VMWjBqS2JZN2d5S29OcW8waFY0L0dQbnJLCjIxSFVVclBVbG9TbFdHQi81UXVPSC9YY0NoV0I1VHUydHlJdkNad1RGckZzRERVSWJhdGpjdTNjdnV6SFYrWXdJSEhXMXhEQkUxVUIKakNwRDVFSHh6enA2VTVMT29nTUZEVGpmQXJzUUx0azcwcHQ2d0tHbStMVXg1dlIxeWJsVG1YVkhJbG9VRmNkNEc3YWQ2UXo0RzNieApoWVRlb2RvUzc2VGlFSmQ2ZU40TVVaZW9JVUNMaHIwTjhGNU9TemE3T3lBZmlrSlc0UXNhdjN2UUlrTXNSSXo3NVNxMGJCd2N1cFRnCkUzNGg1cHJDeThWQ1pMUWVsSHNJSmNoeHpJZEZWNFhUbnlsaUlvTlJsd0FZbDNkcW1KTEpmR0JzMzJ4OVN1UndUTUtldUIzMzBEVEgKRDh6N3AvOER2cTF3a05vTDNjaHRsMSthZndreVFmM05vc3hhYlV6eXFrbitadmpwMkRYckRpZ2U3a2d2T3RCNUNUaDhwaUtDazVYUQpBNzYrQXFBRjNTQWk0MjhkaURSZ3h1WUt1UWwxQy9BSDZHbVdOY2Y3STRHT09EbTRSU3REZUtMUkxCVC9EU2h5Y3BXYlhnbmJpVVNZCnFxRkp1M0ZTOHIvMi95ZWhOcSs0dG5lSTNUcWtiWnMwa053VVhUQy90K3NYNUllM2NkQ2gxM2NWMUVMWDh2TXhtVjJiM1JadFArb0cKSS9oR29pTHRrL2JkbXVZcWg3R1lWUEVpOTJ0RjQrS09kaDJhamNRR2pUYTNGUE9kVkdtM2pqelZwRzJUZ2JldDlyMWtlOExKYURtZwprcHpOTklhUmtQcGtVWjMrL3V1bDlYWGVpZmR5Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClRoYXd0ZSBTZXJ2ZXIgQ0EKPT09PT09PT09PT09PT09PQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJREV6Q0NBbnlnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFRRkFEQ0J4REVMTUFrR0ExVUVCaE1DV2tFeEZUQVRCZ05WQkFnVApERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlEyRndaU0JVYjNkdU1SMHdHd1lEVlFRS0V4UlVhR0YzZEdVZ1EyOXVjM1ZzCmRHbHVaeUJqWXpFb01DWUdBMVVFQ3hNZlEyVnlkR2xtYVdOaGRHbHZiaUJUWlhKMmFXTmxjeUJFYVhacGMybHZiakVaTUJjR0ExVUUKQXhNUVZHaGhkM1JsSUZObGNuWmxjaUJEUVRFbU1DUUdDU3FHU0liM0RRRUpBUllYYzJWeWRtVnlMV05sY25SelFIUm9ZWGQwWlM1agpiMjB3SGhjTk9UWXdPREF4TURBd01EQXdXaGNOTWpBeE1qTXhNak0xT1RVNVdqQ0J4REVMTUFrR0ExVUVCaE1DV2tFeEZUQVRCZ05WCkJBZ1RERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlEyRndaU0JVYjNkdU1SMHdHd1lEVlFRS0V4UlVhR0YzZEdVZ1EyOXUKYzNWc2RHbHVaeUJqWXpFb01DWUdBMVVFQ3hNZlEyVnlkR2xtYVdOaGRHbHZiaUJUWlhKMmFXTmxjeUJFYVhacGMybHZiakVaTUJjRwpBMVVFQXhNUVZHaGhkM1JsSUZObGNuWmxjaUJEUVRFbU1DUUdDU3FHU0liM0RRRUpBUllYYzJWeWRtVnlMV05sY25SelFIUm9ZWGQwClpTNWpiMjB3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ1kwQU1JR0pBb0dCQU5Pa1VHN0kvMVpyNXM5ZHR1b01hSFZIb3FyQzJvUWwKL0tqMFIxSGFoYlVnZEpTR0hnOTF5ZWtJWWZVR2JUQnVGUmtDNlZMQVl0dE5tWjdpYWd4RU9NMyt2dU5rQ1hERi9yRnJLYll2U2NnNwoxQ2NFSlJDWEwrZVFiY0FvUXBuWFRFUGV3L1VoYlZTZlhjTlk0Y0RrMlZ1d3VOeTBlOTgyT3NLMVppSVMxb2NOQWdNQkFBR2pFekFSCk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUVCUUFEZ1lFQUIvcE1hVno3bGN4RzdvV0RUU0V3anNyWnFHOUoKR3ViYVVlTmdjR3lFWVJHaEdzaElQbGxEZlUrVlBhR0x0d3RpbUhwMWl0MklUazZlUU51b3pESjB1VzhOeHVPelJBdlppbSthS1p1WgpHQ2c3MGVOQUtKcGFQTlcxNXlBYmk4cWtxNDNwVWRuaVRDeFpxZHE1c25VYjlrTHk3OGZ5R1BtSnZLUC9paU11Y0VjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgpUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIgQ0EKPT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlESnpDQ0FwQ2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVFGQURDQnpqRUxNQWtHQTFVRUJoTUNXa0V4RlRBVEJnTlZCQWdUCkRGZGxjM1JsY200Z1EyRndaVEVTTUJBR0ExVUVCeE1KUTJGd1pTQlViM2R1TVIwd0d3WURWUVFLRXhSVWFHRjNkR1VnUTI5dWMzVnMKZEdsdVp5QmpZekVvTUNZR0ExVUVDeE1mUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObGN5QkVhWFpwYzJsdmJqRWhNQjhHQTFVRQpBeE1ZVkdoaGQzUmxJRkJ5WlcxcGRXMGdVMlZ5ZG1WeUlFTkJNU2d3SmdZSktvWklodmNOQVFrQkZobHdjbVZ0YVhWdExYTmxjblpsCmNrQjBhR0YzZEdVdVkyOXRNQjRYRFRrMk1EZ3dNVEF3TURBd01Gb1hEVEl3TVRJek1USXpOVGsxT1Zvd2djNHhDekFKQmdOVkJBWVQKQWxwQk1SVXdFd1lEVlFRSUV3eFhaWE4wWlhKdUlFTmhjR1V4RWpBUUJnTlZCQWNUQ1VOaGNHVWdWRzkzYmpFZE1Cc0dBMVVFQ2hNVQpWR2hoZDNSbElFTnZibk4xYkhScGJtY2dZMk14S0RBbUJnTlZCQXNUSDBObGNuUnBabWxqWVhScGIyNGdVMlZ5ZG1salpYTWdSR2wyCmFYTnBiMjR4SVRBZkJnTlZCQU1UR0ZSb1lYZDBaU0JRY21WdGFYVnRJRk5sY25abGNpQkRRVEVvTUNZR0NTcUdTSWIzRFFFSkFSWVoKY0hKbGJXbDFiUzF6WlhKMlpYSkFkR2hoZDNSbExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMGpZMgphb3ZYd2x1ZTJvRkJZbzg0N2trRVZkYlE3eHdibFJaSDd4aElOVHBTOUN0cUJvODdMK3BXNDYrR2paNFg5NTYwWlhVQ1RlL0xDYUloClVkaWIwR2ZRdWcyU0JoUnoxSlBMbHlvQW5GeE9ETHo2RlZMODhrUnUyaEZLYmdpZkx5M2orYW82aG5PMlJsTll5SWtGdllNUnVITS8KcWdlTjlFSk41MENkSERjQ0F3RUFBYU1UTUJFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHOXcwQkFRUUZBQU9CZ1FBbQpTQ3dXd2xqNjZCWjBES3FxWDFRLzh0ZkplR0JlWG00M1l5SjNObjZ5RjhRMHVmVUloZnpKQVRqL1RiN3lGa0pENTd0YVJ2dkJ4aEVmCjhVcXdLRWJKdzhSQ2ZiejZxMWx1MWJkUmlCSGpwSVVaYTRKTXBBd1NyZW1rcmoveHcwbGxtb3pGeUQ0bHQ1U1p1NUl5Y1Fmd2hsN3QKVUNlbURhWWorYnZMcGdjVVFnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKVmVyaXNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDUERDQ0FhVUNFSEM2NUIwUTJTazB0ampLZXdQTXVyOHdEUVlKS29aSWh2Y05BUUVDQlFBd1h6RUxNQWtHQTFVRUJoTUNWVk14CkZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVRjd05RWURWUVFMRXk1RGJHRnpjeUF6SUZCMVlteHBZeUJRY21sdFlYSjUKSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNQjRYRFRrMk1ERXlPVEF3TURBd01Gb1hEVEk0TURnd01USXpOVGsxT1ZvdwpYekVMTUFrR0ExVUVCaE1DVlZNeEZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVRjd05RWURWUVFMRXk1RGJHRnpjeUF6CklGQjFZbXhwWXlCUWNtbHRZWEo1SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUEKQTRHTkFEQ0JpUUtCZ1FESlhGbWU4aHVLQVJTMEVOOEVRTnZqVjY5cVJVQ1BoQXdMMFRQWjJSSFA3Z0pZSHlYM0txaEVCYXJzQXg5NApmNTZUdVpvQXFpTjkxcXlGb21ORngzSW56UFJNeG5WeDBqbnZUMEx3ZGQ4S2tNYU9JRytZRC9pc0kxOXdLVGFreVlibnNab2d5MU9sCmhlYzl2bjJhL2lSRk05eDJGZTBQb25Ga1RHVXVnV2hGcHdJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQWdVQUE0R0JBTHRNRWl2UExDWUEKVHhRVDNhYjcvQW9SaEl6ektCeG5raTk4dHNYNjMvRG9sYndkajJ3c3FGSE1jOWlrd0ZQd1R0WW13SFlCVjRHU1hpSHgwYkgvNTlBaApXTTFwRitORUhKd1pSRG1KWE55Y0FBOVdqUUtaN2FLUVJVemt1eENrUGZBeUF3N3h6dmpveVZHTTVtS2Y1cC9BZmJkeW5NazJPbXVmClRxai9aQTFrCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KClZlcmlzaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBakNDQW1zQ0VIM1ovZ2ZQcUI2M0VIbG4rNmVKTk1Zd0RRWUpLb1pJaHZjTkFRRUZCUUF3Z2NFeEN6QUpCZ05WQkFZVEFsVlQKTVJjd0ZRWURWUVFLRXc1V1pYSnBVMmxuYml3Z1NXNWpMakU4TURvR0ExVUVDeE16UTJ4aGMzTWdNeUJRZFdKc2FXTWdVSEpwYldGeQplU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXRJRWN5TVRvd09BWURWUVFMRXpFb1l5a2dNVGs1T0NCV1pYSnBVMmxuCmJpd2dTVzVqTGlBdElFWnZjaUJoZFhSb2IzSnBlbVZrSUhWelpTQnZibXg1TVI4d0hRWURWUVFMRXhaV1pYSnBVMmxuYmlCVWNuVnoKZENCT1pYUjNiM0pyTUI0WERUazRNRFV4T0RBd01EQXdNRm9YRFRJNE1EZ3dNVEl6TlRrMU9Wb3dnY0V4Q3pBSkJnTlZCQVlUQWxWVApNUmN3RlFZRFZRUUtFdzVXWlhKcFUybG5iaXdnU1c1akxqRThNRG9HQTFVRUN4TXpRMnhoYzNNZ015QlFkV0pzYVdNZ1VISnBiV0Z5CmVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNBdElFY3lNVG93T0FZRFZRUUxFekVvWXlrZ01UazVPQ0JXWlhKcFUybG4KYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNUjh3SFFZRFZRUUxFeFpXWlhKcFUybG5iaUJVY25WegpkQ0JPWlhSM2IzSnJNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUURNWHRFUlhWeHAwS3ZUdVdwTW1SOVptRENPCkZvVWdSbTFIUDlTRklJVGhiYlA0cE8wTThSY1BPL21uK1NYWHdjK0VZL0o4WTgraVIvTEdXek9PWkVBRWFNR0F1V1FjUlhmSDJHNzEKbFNrOFVPZzAxM2dmcUxwdFE1R1ZqMFZYWG43Ris4cWtCT3ZxbHpkVU1HKzdBVWN5TTgzY1Y1dGthV0g0bXgwY2lVOWNad0lEQVFBQgpNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0R0JBRkZOemI1Y3k1Z1puQld5QVRsNExrMFBaM0J3bWNZUVdwU2tVMDFVYlN1dkRWMUFpMlRUCjErN2VWbUdTWDZiRUhSQmhOdE1zSnp6b0tRbTVFV1IwekxWem54eElxYnhoQWU3aUY2WU00MEFJT3c3bjYwUnpLcHJ4YVpMdmNSVEQKT2F4eHA1RUpiK1J4QnJPNldWY21lUUQyK0EyaU16QW8xS3BZb0oyZGFaSDkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQp3cC1jbGkvd3AtY2xpIDIuNS4wIDIwMjEtMDUtMTRUMTY6MTc6MjIrMDA6MDAKY29tcG9zZXIvY2EtYnVuZGxlIDEuMi45IDc4YTBlMjg4ZmRjZWJmOTJhYTIzMThhOGQzNjU2MTY4ZGE2YWMxYTUKY29tcG9zZXIvY29tcG9zZXIgMi4wLjEzIDk4NmU4Yjg2YjdiNTcwNjMyYWQwYTkwNWMzNzI2YzMzZGQ0YzBlZmIKY29tcG9zZXIvbWV0YWRhdGEtbWluaWZpZXIgMS4wLjAgYzU0OWQyMzgyOTUzNmYwZDBlOTg0YWFhYmJmMDJhZjkxZjQ0MzIwNwpjb21wb3Nlci9zZW12ZXIgMy4yLjQgYTAyZmRmOTMwYTNjMWMzZWQzYTQ5YjVmNjM4NTljMGMyMGUxMDQ2NApjb21wb3Nlci9zcGR4LWxpY2Vuc2VzIDEuNS41IGRlMzAzMjhhN2FmODY4MGVmZGMwM2UzOTZhYWQyNGJlZmQ1MTMyMDAKY29tcG9zZXIveGRlYnVnLWhhbmRsZXIgMS40LjYgZjI3ZTA2Y2Q5Njc1ODAxZGY0NDFiMzY1NjU2OWIzMjhlMDRhYTM3YwpnZXR0ZXh0L2dldHRleHQgdjQuOC40IDU4YmMwZjdmMzdlNzhlZmIwZjk3NThmOTNkNGEwZjY2OWYwZjg0YTEKZ2V0dGV4dC9sYW5ndWFnZXMgMi42LjAgMzhlYTA0ODJmNjQ5ZTA4MDJlNDc1ZjBlZDE5ZmE5OTNiY2I3YTYxOApqdXN0aW5yYWluYm93L2pzb24tc2NoZW1hIDUuMi4xMCAyYmE5YzhjODYyZWNkNTUxMGVkMTZjNjM0MGFhOWY2ZWFkYjRmMzFiCm1jazg5L3BlYXN0IHYxLjEyLjAgODMzYmU3YTI5NDYyN2E4YzViMWM0ODJjYmY0ODlmNzNiZjliODA4NgptdXN0YWNoZS9tdXN0YWNoZSB2Mi4xMy4wIGU5NWM1YTAwOGMyM2QzMTUxZDU5ZWE3MjQ4NGQ0ZjcyMDQ5YWI3ZjQKbmIvb3h5bWVsIHYwLjEuMCBjYmU2MjZlZjU1ZDVjNGNjOWI1ZTZlMzkwNGIzOTU4NjFlYTc2ZTNjCnBzci9sb2cgMS4xLjQgZDQ5Njk1YjkwOWMzYjc2MjhiNjI4OWRiNTQ3OWExYzIwNDYwMWYxMQpyZWFjdC9wcm9taXNlIHYyLjguMCBmM2NmZjk2YTE5NzM2NzE0NTI0Y2EwZGQxZDQxMzBkZTczZGJiYmM0CnJtY2N1ZS9yZXF1ZXN0cyB2MS44LjAgYWZiZTQ3OTBlNGRlZjAzNTgxYzRhMDk2M2ExZThhYTAxZjYwMzBmMQpzZWxkL2pzb25saW50IDEuOC4zIDlhZDZjZTc5YzM0MmZiZDQ0ZGYxMGVhOTU1MTFhMWIyNGRlZTViNTcKc2VsZC9waGFyLXV0aWxzIDEuMS4xIDg2NzRiMWQ4NGZmYjQ3Y2M1OWExMDFmNWQ1YTNiNjFlODdkMjM3OTYKc3ltZm9ueS9jb25zb2xlIHYzLjQuNDcgYTEwYjFkYTZmYzkzMDgwYzE4MGJiYTcyMTliNWZmNWI3NTE4ZmU4MQpzeW1mb255L2RlYnVnIHYzLjQuNDcgYWI0Mjg4OWRlNTdmZGZjZmNjMDc1OWFiMTAyZTJmZDRlYTcyZGNhZQpzeW1mb255L2ZpbGVzeXN0ZW0gdjMuNC40NyBlNThkNzg0MWNkZGZlZDZlODQ2ODI5MDQwZGNhMmNjYTBlYmJiYmIzCnN5bWZvbnkvZmluZGVyIHYzLjQuNDcgYjZiNmFkM2RiM2VkYjFiNGIxYzE4OTZiMTk3NWZiNjg0OTk0ZGU2ZQpzeW1mb255L3BvbHlmaWxsLWN0eXBlIHYxLjE5LjAgYWVkNTk2OTEzYjcwZmFlNTdiZTUzZDg2ZmFhMmU5ZWY4NWEyMjk3YgpzeW1mb255L3BvbHlmaWxsLW1ic3RyaW5nIHYxLjE5LjAgYjVmN2I5MzJlZTZmYTgwMmZjNzkyZWFiZDc3YzRjODgwODQ1MTdjZQpzeW1mb255L3Byb2Nlc3MgdjMuNC40NyBiODY0OGNmMWQ1YWYxMmE0NGE1MWQwN2VmOWJmOTgwOTIxZjE1ZmNhCndwLWNsaS9jYWNoZS1jb21tYW5kIHYyLjAuNyBiZjVkM2QzMzVkZTVmOWQ5MzE4MDY4MmYxMDdjMjM4YTgzYzRiMDJjCndwLWNsaS9jaGVja3N1bS1jb21tYW5kIHYyLjEuMCAwZjU4YWY5MTRhNGFmMzAxOGNlODM0NDk4NjkzMDBkNjVkZjlmNjEzCndwLWNsaS9jb25maWctY29tbWFuZCB2Mi4xLjAgNDZiMDk2ZWFlMmMxMTZiZWQzMGM4ZDY0OWY2ZTJhMWQ0ZGIwMzVjMQp3cC1jbGkvY29yZS1jb21tYW5kIHYyLjEuMCBiN2Y0NGYwM2EzYTM1MTQ3OThjZGEyMWI2MWE0MThmMDhhZWNlMzI0CndwLWNsaS9jcm9uLWNvbW1hbmQgdjIuMC44IGYwZDQ5M2ZmNGQ0ZjIwZWU2ZDZmZDU0OTVkYTFiYzE3NjBmOWRhMTUKd3AtY2xpL2RiLWNvbW1hbmQgdjIuMC4xMyAyNjliZjI2YTY2OTE1ZDY1MjZiMTAxNWY3Yzc1OWZmZTA0Mzg2YmY3CndwLWNsaS9lbWJlZC1jb21tYW5kIHYyLjAuOSBlYzc0ZjNmMzRjYjljMDI4ZmQzOWViZjhjY2EzYTE1MDRmZDU5OWJhCndwLWNsaS9lbnRpdHktY29tbWFuZCB2Mi4xLjAgOWIzYzAzMGQ1YjA1NmYzZjdiODgzNWUxMTcxMzlmOTI3OTkzNDBhOQp3cC1jbGkvZXZhbC1jb21tYW5kIHYyLjEuMCBkY2RhMDIxOTRiZDBjYTc3M2NlMDNkZWM2MDkzYWMwZDI3MWY4OTc2CndwLWNsaS9leHBvcnQtY29tbWFuZCB2Mi4wLjggZTk0ZjVmOWU4NDc2ODkxOWFhNmNkMjE5M2ViMGM4Yjk5NGU3ZjRjOQp3cC1jbGkvZXh0ZW5zaW9uLWNvbW1hbmQgdjIuMS4wIDdhZDRmOWMwYzkzYTFlZTczNzUyMWY4MjVmMTYxZDRiNzlhNDY5NDUKd3AtY2xpL2kxOG4tY29tbWFuZCB2Mi4yLjggOGJjMjM0NjE3ZWRjNTMzNTkwYWMwZjQxMDgwMTY0YThkODVlYzljZQp3cC1jbGkvaW1wb3J0LWNvbW1hbmQgdjIuMC43IDc1ZTZkNDI3M2I0YTlkYmY1MTBkNjlhNDRmOTM3MWVlZTBkMDEyOTQKd3AtY2xpL2xhbmd1YWdlLWNvbW1hbmQgdjIuMC4xMCA0YzAyZWY0MzFlMjgyNWVhYzdiMDJlNWNmNDgwNGM0NzE2N2I2YmFmCndwLWNsaS9tYWludGVuYW5jZS1tb2RlLWNvbW1hbmQgdjIuMC42IDI2YzFjMGE3OWVkMTE5NGM4NjNjYjk1ZmEzNjRiNGRiNzkyOWQ3Y2MKd3AtY2xpL21lZGlhLWNvbW1hbmQgdjIuMC4xMSAxNjVhNDYyZTIzNGU1NWRiMjE3NGY5ZjBmNmZhYjcyMDQwZTljNTEwCndwLWNsaS9tdXN0YW5nb3N0YW5nLXNweWMgMC42LjMgNmFhMGI0ZGE2OWNlOWU5YTJjODQwMmRhYjhkNDNjZjMyYzU4MWNjNwp3cC1jbGkvcGFja2FnZS1jb21tYW5kIHYyLjEuMSAyZTM0NWRmNmM2N2Q0ZjliNGJmNDJjZTEyYTdmYTA3YjJiNDQzOTlkCndwLWNsaS9waHAtY2xpLXRvb2xzIHYwLjExLjEyIGU0NzJlMDg0ODlmNzUwNGQ5ZThjNWM1YTA1N2UxNDE5Y2QxYjJiM2UKd3AtY2xpL3Jld3JpdGUtY29tbWFuZCB2Mi4wLjggNDY4MzU4ZTA3OTQzYTdhOGJlNzBjOTVlMjBkNDU0MTJkODI4OTlhYwp3cC1jbGkvcm9sZS1jb21tYW5kIHYyLjAuNyA3NDYwNTY2ZmViZTgyYjE0YzM0YjEwNWM0YzYzMjZkM2UyM2Y5Mjk1CndwLWNsaS9zY2FmZm9sZC1jb21tYW5kIHYyLjAuMTQgY2RlNDQ1MjRmZDA0OTljMDM2NGE1YWUzYTZkYzQ5Mjc5NmU4MGUwYQp3cC1jbGkvc2VhcmNoLXJlcGxhY2UtY29tbWFuZCB2Mi4wLjEyIDdkOTNhYmJkZmQwYzMyMzkwMmFjMjFmYzM0MTg2MDQxYmU3NDNmZDAKd3AtY2xpL3NlcnZlci1jb21tYW5kIHYyLjAuOCAyOTk3NmFlZjVjMmJkZjE1OWI4NzAwZWFiMjZiYWZjOTQzZjBiZTBjCndwLWNsaS9zaGVsbC1jb21tYW5kIHYyLjAuOSBmMjdiMzRhODdiNTE1ZGE2NDZkMmU3MDE4YThhYmMxMjU0NDE2ZmVjCndwLWNsaS9zdXBlci1hZG1pbi1jb21tYW5kIHYyLjAuNyBhZDRiZDRlNmI2YTUzYWZhNGJhODY2NGE2ZGQ2OTViZTZmZWI2OTJlCndwLWNsaS93aWRnZXQtY29tbWFuZCB2Mi4xLjQgNWM3YjRlMTQ3Yjc3ZTNkNzY4YTlhMDM0NjkzZWJjN2JhMTk4MDcwNwp3cC1jbGkvd3AtY2xpIGRldi1tYXN0ZXIgMGJjZjBjNTRmNGQzNTY4NTIxMWQ0MzVlMjUyMTljYzdhY2JlNmQ0OAp3cC1jbGkvd3AtY29uZmlnLXRyYW5zZm9ybWVyIHYxLjIuOCAwYmIyYjkxNjJjMzhjYTcyMzcwMzgwYWVhMTFkYzA2ZTQzMWUxM2E1Mi41LjDrK2dPuQpk7U8f+7Wucbon32qfGQIAAABHQk1C
Base64 mode: content will be decoded on save.
Save
Close
Exit & Reset
Directory Contents
Dirs: 0 × Files: 5
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
imunify-security.svg
1.58 KB
lrwxr-xr-x
2026-01-23 14:05:13
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
imunify-security.version
6 B
lrwxr-xr-x
2026-01-23 14:05:13
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
imunify-security.zip
4.41 MB
lrwxr-xr-x
2026-01-23 14:05:13
Edit
Download
Rename
Chmod
Change Date
Unzip here
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
wp-cli
5.81 MB
lrwxr-xr-x
2026-01-23 14:05:13
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
wp-cli-wrapper
3.81 KB
lrwxr-xr-x
2026-01-23 14:05:13
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).